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