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