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