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_RGBMASKPIXELFORMATS_HXX 25cdf0e10cSrcweir #define INCLUDED_BASEBMP_RGBMASKPIXELFORMATS_HXX 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include <basebmp/color.hxx> 28cdf0e10cSrcweir #include <basebmp/colortraits.hxx> 29cdf0e10cSrcweir #include <basebmp/accessor.hxx> 30cdf0e10cSrcweir #include <basebmp/pixeliterator.hxx> 31cdf0e10cSrcweir #include <basebmp/pixelformatadapters.hxx> 32cdf0e10cSrcweir #include <basebmp/metafunctions.hxx> 33cdf0e10cSrcweir #include <basebmp/endian.hxx> 34cdf0e10cSrcweir 35cdf0e10cSrcweir #include <vigra/numerictraits.hxx> 36cdf0e10cSrcweir #include <vigra/metaprogramming.hxx> 37cdf0e10cSrcweir 38cdf0e10cSrcweir #include <functional> 39cdf0e10cSrcweir 40cdf0e10cSrcweir namespace basebmp 41cdf0e10cSrcweir { 42cdf0e10cSrcweir 43cdf0e10cSrcweir /** Base class operating on RGB truecolor mask pixel 44cdf0e10cSrcweir 45cdf0e10cSrcweir Use this template, if you have an (integer) pixel type, and three 46cdf0e10cSrcweir bitmasks denoting where the channel bits are. 47cdf0e10cSrcweir 48cdf0e10cSrcweir @tpl PixelType 49cdf0e10cSrcweir Input pixel type to operate on 50cdf0e10cSrcweir 51cdf0e10cSrcweir @tpl ColorType 52cdf0e10cSrcweir Underlying color type, to convert the pixel values into 53cdf0e10cSrcweir 54cdf0e10cSrcweir @tpl RedMask 55cdf0e10cSrcweir Bitmask, to access the red bits in the data type 56cdf0e10cSrcweir 57cdf0e10cSrcweir @tpl GreenMask 58cdf0e10cSrcweir Bitmask, to access the green bits in the data type 59cdf0e10cSrcweir 60cdf0e10cSrcweir @tpl BlueMask 61cdf0e10cSrcweir Bitmask, to access the blue bits in the data type 62cdf0e10cSrcweir 63cdf0e10cSrcweir @tpl SwapBytes 64cdf0e10cSrcweir When true, the final pixel values will be byte-swapped before 65cdf0e10cSrcweir passed on. 66cdf0e10cSrcweir */ 67cdf0e10cSrcweir template< typename PixelType, 68cdf0e10cSrcweir typename ColorType, 69cdf0e10cSrcweir unsigned int RedMask, 70cdf0e10cSrcweir unsigned int GreenMask, 71cdf0e10cSrcweir unsigned int BlueMask, 72cdf0e10cSrcweir bool SwapBytes > struct RGBMaskFunctorBase 73cdf0e10cSrcweir { 74cdf0e10cSrcweir typedef PixelType pixel_type; 75cdf0e10cSrcweir typedef ColorType color_type; 76cdf0e10cSrcweir typedef typename make_unsigned<pixel_type>::type unsigned_pixel_type; 77cdf0e10cSrcweir typedef typename ColorTraits<ColorType>::component_type component_type; 78cdf0e10cSrcweir 79cdf0e10cSrcweir // calc corrective shifts for all three channels in advance 80cdf0e10cSrcweir enum { 81cdf0e10cSrcweir red_shift = numberOfTrailingZeros<RedMask>::value, 82cdf0e10cSrcweir green_shift = numberOfTrailingZeros<GreenMask>::value, 83cdf0e10cSrcweir blue_shift = numberOfTrailingZeros<BlueMask>::value, 84cdf0e10cSrcweir 85cdf0e10cSrcweir red_bits = bitcount<RedMask>::value, 86cdf0e10cSrcweir green_bits = bitcount<GreenMask>::value, 87cdf0e10cSrcweir blue_bits = bitcount<BlueMask>::value 88cdf0e10cSrcweir }; 89cdf0e10cSrcweir }; 90cdf0e10cSrcweir 91cdf0e10cSrcweir template< typename PixelType, 92cdf0e10cSrcweir typename ColorType, 93cdf0e10cSrcweir unsigned int RedMask, 94cdf0e10cSrcweir unsigned int GreenMask, 95cdf0e10cSrcweir unsigned int BlueMask, 96cdf0e10cSrcweir bool SwapBytes > struct RGBMaskGetter : 97cdf0e10cSrcweir public RGBMaskFunctorBase<PixelType, 98cdf0e10cSrcweir ColorType, 99cdf0e10cSrcweir RedMask, 100cdf0e10cSrcweir GreenMask, 101cdf0e10cSrcweir BlueMask, 102cdf0e10cSrcweir SwapBytes>, 103cdf0e10cSrcweir public std::unary_function<PixelType, ColorType> 104cdf0e10cSrcweir { 105cdf0e10cSrcweir typedef RGBMaskFunctorBase<PixelType, 106cdf0e10cSrcweir ColorType, 107cdf0e10cSrcweir RedMask, 108cdf0e10cSrcweir GreenMask, 109cdf0e10cSrcweir BlueMask, 110cdf0e10cSrcweir SwapBytes> base_type; 111cdf0e10cSrcweir operator ()basebmp::RGBMaskGetter112cdf0e10cSrcweir ColorType operator()( PixelType v ) const 113cdf0e10cSrcweir { 114cdf0e10cSrcweir v = SwapBytes ? byteSwap(v) : v; 115cdf0e10cSrcweir 116cdf0e10cSrcweir const typename base_type::unsigned_pixel_type red (v & RedMask); 117cdf0e10cSrcweir const typename base_type::unsigned_pixel_type green(v & GreenMask); 118cdf0e10cSrcweir const typename base_type::unsigned_pixel_type blue (v & BlueMask); 119cdf0e10cSrcweir 120cdf0e10cSrcweir // shift color nibbles to right-aligend position. ORing it 121cdf0e10cSrcweir // channel value shifted twice the number of channel bits, to 122cdf0e10cSrcweir // spread the value into the component_type range 123cdf0e10cSrcweir ColorType res( (shiftRight(red, 124cdf0e10cSrcweir base_type::red_shift-8* 125cdf0e10cSrcweir (signed)sizeof(typename base_type::component_type)+ 126cdf0e10cSrcweir base_type::red_bits)) | 127cdf0e10cSrcweir (shiftRight(red, 128cdf0e10cSrcweir base_type::red_shift-8* 129cdf0e10cSrcweir (signed)sizeof(typename base_type::component_type)+ 130cdf0e10cSrcweir 2*base_type::red_bits)), 131cdf0e10cSrcweir 132cdf0e10cSrcweir (shiftRight(green, 133cdf0e10cSrcweir base_type::green_shift-8* 134cdf0e10cSrcweir (signed)sizeof(typename base_type::component_type)+ 135cdf0e10cSrcweir base_type::green_bits)) | 136cdf0e10cSrcweir (shiftRight(green, 137cdf0e10cSrcweir base_type::green_shift-8* 138cdf0e10cSrcweir (signed)sizeof(typename base_type::component_type)+ 139cdf0e10cSrcweir 2*base_type::green_bits)), 140cdf0e10cSrcweir 141cdf0e10cSrcweir (shiftRight(blue, 142cdf0e10cSrcweir base_type::blue_shift-8* 143cdf0e10cSrcweir (signed)sizeof(typename base_type::component_type)+ 144cdf0e10cSrcweir base_type::blue_bits)) | 145cdf0e10cSrcweir (shiftRight(blue, 146cdf0e10cSrcweir base_type::blue_shift-8* 147cdf0e10cSrcweir (signed)sizeof(typename base_type::component_type)+ 148cdf0e10cSrcweir 2*base_type::blue_bits)) ); 149cdf0e10cSrcweir return res; 150cdf0e10cSrcweir } 151cdf0e10cSrcweir }; 152cdf0e10cSrcweir 153cdf0e10cSrcweir template< typename PixelType, 154cdf0e10cSrcweir typename ColorType, 155cdf0e10cSrcweir unsigned int RedMask, 156cdf0e10cSrcweir unsigned int GreenMask, 157cdf0e10cSrcweir unsigned int BlueMask, 158cdf0e10cSrcweir bool SwapBytes > struct RGBMaskSetter : 159cdf0e10cSrcweir public RGBMaskFunctorBase<PixelType, 160cdf0e10cSrcweir ColorType, 161cdf0e10cSrcweir RedMask, 162cdf0e10cSrcweir GreenMask, 163cdf0e10cSrcweir BlueMask, 164cdf0e10cSrcweir SwapBytes>, 165cdf0e10cSrcweir public std::unary_function<ColorType, PixelType> 166cdf0e10cSrcweir { 167cdf0e10cSrcweir typedef RGBMaskFunctorBase<PixelType, 168cdf0e10cSrcweir ColorType, 169cdf0e10cSrcweir RedMask, 170cdf0e10cSrcweir GreenMask, 171cdf0e10cSrcweir BlueMask, 172cdf0e10cSrcweir SwapBytes> base_type; 173cdf0e10cSrcweir operator ()basebmp::RGBMaskSetter174cdf0e10cSrcweir PixelType operator()( ColorType const& c ) const 175cdf0e10cSrcweir { 176cdf0e10cSrcweir const typename base_type::unsigned_pixel_type red (c.getRed()); 177cdf0e10cSrcweir const typename base_type::unsigned_pixel_type green(c.getGreen()); 178cdf0e10cSrcweir const typename base_type::unsigned_pixel_type blue (c.getBlue()); 179cdf0e10cSrcweir 180cdf0e10cSrcweir typename base_type::unsigned_pixel_type res( 181cdf0e10cSrcweir (shiftLeft(red, 182cdf0e10cSrcweir base_type::red_shift-8* 183cdf0e10cSrcweir (signed)sizeof(typename base_type::component_type)+ 184cdf0e10cSrcweir base_type::red_bits) & RedMask) | 185cdf0e10cSrcweir (shiftLeft(green, 186cdf0e10cSrcweir base_type::green_shift-8* 187cdf0e10cSrcweir (signed)sizeof(typename base_type::component_type)+ 188cdf0e10cSrcweir base_type::green_bits) & GreenMask) | 189cdf0e10cSrcweir (shiftLeft(blue, 190cdf0e10cSrcweir base_type::blue_shift-8* 191cdf0e10cSrcweir (signed)sizeof(typename base_type::component_type)+ 192cdf0e10cSrcweir base_type::blue_bits) & BlueMask) ); 193cdf0e10cSrcweir 194cdf0e10cSrcweir return SwapBytes ? byteSwap(res) : res; 195cdf0e10cSrcweir } 196cdf0e10cSrcweir }; 197cdf0e10cSrcweir 198cdf0e10cSrcweir //----------------------------------------------------------------------------- 199cdf0e10cSrcweir 200cdf0e10cSrcweir template< typename PixelType, 201cdf0e10cSrcweir unsigned int RedMask, 202cdf0e10cSrcweir unsigned int GreenMask, 203cdf0e10cSrcweir unsigned int BlueMask, 204cdf0e10cSrcweir bool SwapBytes > struct PixelFormatTraitsTemplate_RGBMask 205cdf0e10cSrcweir { 206cdf0e10cSrcweir typedef PixelType pixel_type; 207cdf0e10cSrcweir 208cdf0e10cSrcweir typedef RGBMaskGetter<pixel_type, 209cdf0e10cSrcweir Color, 210cdf0e10cSrcweir RedMask, 211cdf0e10cSrcweir GreenMask, 212cdf0e10cSrcweir BlueMask, 213cdf0e10cSrcweir SwapBytes> getter_type; 214cdf0e10cSrcweir typedef RGBMaskSetter<pixel_type, 215cdf0e10cSrcweir Color, 216cdf0e10cSrcweir RedMask, 217cdf0e10cSrcweir GreenMask, 218cdf0e10cSrcweir BlueMask, 219cdf0e10cSrcweir SwapBytes> setter_type; 220cdf0e10cSrcweir 221cdf0e10cSrcweir typedef PixelIterator<pixel_type> iterator_type; 222cdf0e10cSrcweir typedef StandardAccessor<pixel_type> raw_accessor_type; 223cdf0e10cSrcweir typedef AccessorSelector< 224cdf0e10cSrcweir getter_type, setter_type> accessor_selector; 225cdf0e10cSrcweir }; 226cdf0e10cSrcweir 227cdf0e10cSrcweir //----------------------------------------------------------------------------- 228cdf0e10cSrcweir 229cdf0e10cSrcweir #ifdef OSL_LITENDIAN 230cdf0e10cSrcweir # define BASEBMP_TRUECOLORMASK_LSB_SWAP false 231cdf0e10cSrcweir # define BASEBMP_TRUECOLORMASK_MSB_SWAP true 232cdf0e10cSrcweir #else 233cdf0e10cSrcweir # ifdef OSL_BIGENDIAN 234cdf0e10cSrcweir # define BASEBMP_TRUECOLORMASK_LSB_SWAP true 235cdf0e10cSrcweir # define BASEBMP_TRUECOLORMASK_MSB_SWAP false 236cdf0e10cSrcweir # else 237cdf0e10cSrcweir # error Undetermined endianness! 238cdf0e10cSrcweir # endif 239cdf0e10cSrcweir #endif 240cdf0e10cSrcweir 241cdf0e10cSrcweir //----------------------------------------------------------------------------- 242cdf0e10cSrcweir 243cdf0e10cSrcweir // 16bpp MSB RGB 244cdf0e10cSrcweir typedef PixelFormatTraitsTemplate_RGBMask< 245cdf0e10cSrcweir sal_uInt16, 246cdf0e10cSrcweir 0xF800, 247cdf0e10cSrcweir 0x07E0, 248cdf0e10cSrcweir 0x001F, 249cdf0e10cSrcweir BASEBMP_TRUECOLORMASK_MSB_SWAP > PixelFormatTraits_RGB16_565_MSB; 250cdf0e10cSrcweir BASEBMP_SPECIALIZE_ACCESSORTRAITS(PixelFormatTraits_RGB16_565_MSB::getter_type, 251cdf0e10cSrcweir PixelFormatTraits_RGB16_565_MSB::setter_type); 252cdf0e10cSrcweir 253cdf0e10cSrcweir // 16bpp LSB RGB 254cdf0e10cSrcweir typedef PixelFormatTraitsTemplate_RGBMask< 255cdf0e10cSrcweir sal_uInt16, 256cdf0e10cSrcweir 0xF800, 257cdf0e10cSrcweir 0x07E0, 258cdf0e10cSrcweir 0x001F, 259cdf0e10cSrcweir BASEBMP_TRUECOLORMASK_LSB_SWAP > PixelFormatTraits_RGB16_565_LSB; 260cdf0e10cSrcweir BASEBMP_SPECIALIZE_ACCESSORTRAITS(PixelFormatTraits_RGB16_565_LSB::getter_type, 261cdf0e10cSrcweir PixelFormatTraits_RGB16_565_LSB::setter_type); 262cdf0e10cSrcweir 263cdf0e10cSrcweir // 32bpp endian-sensitive RGB 264cdf0e10cSrcweir typedef PixelFormatTraitsTemplate_RGBMask< 265cdf0e10cSrcweir sal_uInt32, 266cdf0e10cSrcweir 0xFF0000, 267cdf0e10cSrcweir 0x00FF00, 268cdf0e10cSrcweir 0x0000FF, 269cdf0e10cSrcweir BASEBMP_TRUECOLORMASK_LSB_SWAP > PixelFormatTraits_RGB32_888; 270cdf0e10cSrcweir BASEBMP_SPECIALIZE_ACCESSORTRAITS(PixelFormatTraits_RGB32_888::getter_type, 271cdf0e10cSrcweir PixelFormatTraits_RGB32_888::setter_type); 272cdf0e10cSrcweir 273cdf0e10cSrcweir // 32bpp endian-sensitive BGR 274cdf0e10cSrcweir typedef PixelFormatTraitsTemplate_RGBMask< 275cdf0e10cSrcweir sal_uInt32, 276cdf0e10cSrcweir 0xFF0000, 277cdf0e10cSrcweir 0x00FF00, 278cdf0e10cSrcweir 0x0000FF, 279cdf0e10cSrcweir BASEBMP_TRUECOLORMASK_MSB_SWAP > PixelFormatTraits_BGR32_888; 280cdf0e10cSrcweir BASEBMP_SPECIALIZE_ACCESSORTRAITS(PixelFormatTraits_BGR32_888::getter_type, 281cdf0e10cSrcweir PixelFormatTraits_BGR32_888::setter_type); 282cdf0e10cSrcweir 283cdf0e10cSrcweir } // namespace basebmp 284cdf0e10cSrcweir 285cdf0e10cSrcweir #endif /* INCLUDED_BASEBMP_RGBMASKPIXELFORMATS_HXX */ 286