| 106 | #endif |
| 107 | |
| 108 | void channelsToWrite( const ImagePrimitive *image, const ImageOutput *out, const CompoundObject *operands, std::vector<std::string> &channels ) |
| 109 | { |
| 110 | channels.clear(); |
| 111 | |
| 112 | const bool supportsNChannels = (bool)out->supports( "nchannels" ); |
| 113 | const bool supportsAlpha = (bool)out->supports( "alpha" ); |
| 114 | |
| 115 | const std::vector<std::string> &requestedChannels = operands->member<const StringVectorData>( "channels" )->readable(); |
| 116 | |
| 117 | std::vector<std::string> existingChannels; |
| 118 | image->channelNames( existingChannels ); |
| 119 | |
| 120 | // some formats require RGB listed in order, so lets find them first |
| 121 | auto rIt = find( existingChannels.begin(), existingChannels.end(), "R" ); |
| 122 | if( rIt != existingChannels.end() && rIt != existingChannels.begin() ) |
| 123 | { |
| 124 | std::iter_swap( existingChannels.begin(), rIt ); |
| 125 | } |
| 126 | auto gIt = find( existingChannels.begin(), existingChannels.end(), "G" ); |
| 127 | if( gIt != existingChannels.end() && gIt != existingChannels.begin() + 1 ) |
| 128 | { |
| 129 | std::iter_swap( existingChannels.begin() + 1, gIt ); |
| 130 | } |
| 131 | auto bIt = find( existingChannels.begin(), existingChannels.end(), "B" ); |
| 132 | if( bIt != existingChannels.end() && bIt != existingChannels.begin() + 2 ) |
| 133 | { |
| 134 | std::iter_swap( existingChannels.begin() + 2, bIt ); |
| 135 | } |
| 136 | |
| 137 | for( const auto &channel : existingChannels ) |
| 138 | { |
| 139 | if ( |
| 140 | // channel was requested |
| 141 | ( |
| 142 | requestedChannels.empty() || |
| 143 | find( requestedChannels.begin(), requestedChannels.end(), channel ) != requestedChannels.end() |
| 144 | ) && |
| 145 | // channel hasn't been added yet |
| 146 | find( channels.begin(), channels.end(), channel ) == channels.end() && |
| 147 | // only allow arbitrary channels if the format supports it |
| 148 | ( supportsNChannels || channel == "R" || channel == "G" || channel == "B" || channel == "A" || channel == "Y" ) && |
| 149 | // only allow alpha if the format supports it |
| 150 | ( supportsAlpha || channel != "A" ) |
| 151 | ) |
| 152 | { |
| 153 | channels.push_back( channel ); |
| 154 | } |
| 155 | } |
| 156 | } |
| 157 | |
| 158 | void metadataToImageSpecAttributes( const CompoundData *metadata, ImageSpec *spec, const std::string &prefix = "" ) |
| 159 | { |