1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #ifndef INCLUDED_BASEBMP_TRUECOLORMASKACCESSOR_HXX 25 #define INCLUDED_BASEBMP_TRUECOLORMASKACCESSOR_HXX 26 27 #include <basebmp/colortraits.hxx> 28 #include <basebmp/accessortraits.hxx> 29 #include <basebmp/metafunctions.hxx> 30 #include <basebmp/endian.hxx> 31 32 #include <vigra/numerictraits.hxx> 33 #include <vigra/metaprogramming.hxx> 34 35 namespace basebmp 36 { 37 38 namespace 39 { 40 /// Shift left for positive shift value, and right otherwise shiftLeft(T v,int shift)41 template< typename T > inline T shiftLeft( T v, int shift ) 42 { 43 return shift > 0 ? v << shift : v >> (-shift); 44 } 45 46 /// Shift right for positive shift value, and left otherwise shiftRight(T v,int shift)47 template< typename T > inline T shiftRight( T v, int shift ) 48 { 49 return shift > 0 ? v >> shift : v << (-shift); 50 } 51 } 52 53 /** Access true color data, which is pixel-packed into a POD. 54 55 @tpl Accessor 56 Wrapped accessor, used to access the actual pixel values 57 58 @tpl ColorType 59 Underlying color type, to convert the pixel values into 60 61 @tpl RedMask 62 Bitmask, to access the red bits in the data type 63 64 @tpl GreenMask 65 Bitmask, to access the green bits in the data type 66 67 @tpl BlueMask 68 Bitmask, to access the blue bits in the data type 69 70 @tpl SwapBytes 71 When true, the final pixel values will be byte-swapped before 72 passed to/from the iterator. 73 */ 74 template< class Accessor, 75 typename ColorType, 76 int RedMask, 77 int GreenMask, 78 int BlueMask, 79 bool SwapBytes > class TrueColorMaskAccessor 80 { 81 public: 82 typedef typename Accessor::value_type data_type; 83 typedef ColorType value_type; 84 typedef typename make_unsigned<data_type>::type unsigned_data_type; 85 typedef typename ColorTraits<ColorType>::component_type component_type; 86 87 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS 88 // making all members public, if no member template friends 89 private: 90 template<class A, typename C, int R, int G, int B, bool S> friend class TrueColorMaskAccessor; 91 #endif 92 93 Accessor maAccessor; 94 95 public: 96 // calc corrective shifts for all three channels in advance 97 enum { 98 red_shift = numberOfTrailingZeros<RedMask>::value, 99 green_shift = numberOfTrailingZeros<GreenMask>::value, 100 blue_shift = numberOfTrailingZeros<BlueMask>::value, 101 102 red_bits = bitcount<RedMask>::value, 103 green_bits = bitcount<GreenMask>::value, 104 blue_bits = bitcount<BlueMask>::value 105 }; 106 107 // ------------------------------------------------------- 108 TrueColorMaskAccessor()109 TrueColorMaskAccessor() : 110 maAccessor() 111 {} 112 113 template< class A > explicit TrueColorMaskAccessor(TrueColorMaskAccessor<A,ColorType,RedMask,GreenMask,BlueMask,SwapBytes> const & rSrc)114 TrueColorMaskAccessor( TrueColorMaskAccessor< A, 115 ColorType, 116 RedMask, 117 GreenMask, 118 BlueMask, 119 SwapBytes > const& rSrc ) : 120 maAccessor( rSrc.maAccessor ) 121 {} 122 TrueColorMaskAccessor(T accessor)123 template< class T > explicit TrueColorMaskAccessor( T accessor ) : 124 maAccessor(accessor) 125 {} 126 127 // ------------------------------------------------------- 128 getWrappedAccessor() const129 Accessor const& getWrappedAccessor() const { return maAccessor; } getWrappedAccessor()130 Accessor& getWrappedAccessor() { return maAccessor; } 131 132 // ------------------------------------------------------- 133 toValue(unsigned_data_type v) const134 value_type toValue( unsigned_data_type v ) const 135 { 136 v = SwapBytes ? byteSwap(v) : v; 137 138 const unsigned_data_type red (v & RedMask); 139 const unsigned_data_type green(v & GreenMask); 140 const unsigned_data_type blue (v & BlueMask); 141 142 value_type res( (shiftRight(red, 143 red_shift-8*sizeof(component_type)+red_bits)) | 144 (shiftRight(red, 145 red_shift-8*sizeof(component_type)+2*red_bits)), 146 147 (shiftRight(green, 148 green_shift-8*sizeof(component_type)+green_bits)) | 149 (shiftRight(green, 150 green_shift-8*sizeof(component_type)+2*green_bits)), 151 152 (shiftRight(blue, 153 blue_shift-8*sizeof(component_type)+blue_bits)) | 154 (shiftRight(blue, 155 blue_shift-8*sizeof(component_type)+2*blue_bits)) ); 156 return res; 157 } 158 toPacked(value_type v) const159 data_type toPacked( value_type v ) const 160 { 161 const unsigned_data_type red (v.getRed()); 162 const unsigned_data_type green(v.getGreen()); 163 const unsigned_data_type blue (v.getBlue()); 164 165 unsigned_data_type res( 166 (shiftLeft(red, 167 red_shift-8*sizeof(component_type)+red_bits) & RedMask) | 168 (shiftLeft(green, 169 green_shift-8*sizeof(component_type)+green_bits) & GreenMask) | 170 (shiftLeft(blue, 171 blue_shift-8*sizeof(component_type)+blue_bits) & BlueMask) ); 172 173 return SwapBytes ? byteSwap(res) : res; 174 } 175 176 // ------------------------------------------------------- 177 178 template< class Iterator > operator ()(Iterator const & i) const179 value_type operator()(Iterator const& i) const 180 { 181 return toValue( 182 unsigned_cast<data_type>( maAccessor(i)) ); 183 } 184 185 template< class Iterator, class Difference > operator ()(Iterator const & i,Difference const & diff) const186 value_type operator()(Iterator const& i, Difference const& diff) const 187 { 188 return toValue( 189 unsigned_cast<data_type>( maAccessor(i,diff)) ); 190 } 191 192 // ------------------------------------------------------- 193 194 template< typename V, class Iterator > set(V const & value,Iterator const & i) const195 void set(V const& value, Iterator const& i) const 196 { 197 maAccessor.set( 198 toPacked( 199 vigra::detail::RequiresExplicitCast<value_type>::cast( 200 value) ), 201 i); 202 } 203 204 template< typename V, class Iterator, class Difference > set(V const & value,Iterator const & i,Difference const & diff) const205 void set(V const& value, Iterator const& i, Difference const& diff) const 206 { 207 maAccessor.set( 208 toPacked( 209 vigra::detail::RequiresExplicitCast<value_type>::cast( 210 value)), 211 i, 212 diff ); 213 } 214 }; 215 216 //----------------------------------------------------------------------------- 217 218 /** Convert Color to packed true color value for TrueColorMaskAccessor 219 */ 220 template< class Accessor > struct ColorConvert 221 { operator ()basebmp::ColorConvert222 typename Accessor::data_type operator()( const Accessor& acc, 223 typename Accessor::value_type v ) 224 { 225 return acc.toPacked(v); 226 } 227 }; 228 229 //----------------------------------------------------------------------------- 230 231 // partial specialization for TrueColorMaskAccessor 232 template< class Accessor, 233 typename ColorType, 234 int RedMask, 235 int GreenMask, 236 int BlueMask, 237 bool SwapBytes > struct AccessorTraits< 238 TrueColorMaskAccessor< Accessor, 239 ColorType, 240 RedMask, 241 GreenMask, 242 BlueMask, 243 SwapBytes > > 244 { 245 /// value type of described accessor 246 typedef typename TrueColorMaskAccessor< Accessor, 247 ColorType, 248 RedMask, 249 GreenMask, 250 BlueMask, 251 SwapBytes >::value_type value_type; 252 253 /// Retrieve stand-alone color lookup function for given Accessor type 254 typedef ColorConvert< TrueColorMaskAccessor< Accessor, 255 ColorType, 256 RedMask, 257 GreenMask, 258 BlueMask, 259 SwapBytes > > color_lookup; 260 261 /// Retrieve raw pixel data accessor for given Accessor type 262 typedef Accessor raw_accessor; 263 264 /** accessor for XOR setter access is disabled, since the results 265 * are usually completely unintended - you'll usually want to 266 * wrap an xor_accessor with a TrueColorMaskAccessor, not the 267 * other way around. 268 */ 269 typedef vigra::VigraFalseType xor_accessor; 270 271 /** accessor for masked setter access is disabled, since the 272 * results are usually completely unintended - you'll usually 273 * want to wrap a masked_accessor with a TrueColorMaskAccessor, 274 * not the other way around. 275 */ 276 template< class MaskAccessor, 277 class Iterator, 278 class MaskIterator > struct masked_accessor 279 { 280 typedef vigra::VigraFalseType type; 281 }; 282 }; 283 284 } // namespace basebmp 285 286 #endif /* INCLUDED_BASEBMP_TRUECOLORMASKACCESSOR_HXX */ 287