1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #ifndef INCLUDED_BASEBMP_RGBMASKPIXELFORMATS_HXX
21 #define INCLUDED_BASEBMP_RGBMASKPIXELFORMATS_HXX
23 #include <basebmp/color.hxx>
24 #include <basebmp/colortraits.hxx>
25 #include <basebmp/accessor.hxx>
26 #include <basebmp/pixeliterator.hxx>
27 #include <basebmp/pixelformatadapters.hxx>
28 #include <basebmp/metafunctions.hxx>
29 #include <basebmp/endian.hxx>
31 #include <vigra/numerictraits.hxx>
32 #include <vigra/metaprogramming.hxx>
39 /** Base class operating on RGB truecolor mask pixel
41 Use this template, if you have an (integer) pixel type, and three
42 bitmasks denoting where the channel bits are.
45 Input pixel type to operate on
48 Underlying color type, to convert the pixel values into
51 Bitmask, to access the red bits in the data type
54 Bitmask, to access the green bits in the data type
57 Bitmask, to access the blue bits in the data type
60 When true, the final pixel values will be byte-swapped before
63 template< typename PixelType
,
66 unsigned int GreenMask
,
67 unsigned int BlueMask
,
68 bool SwapBytes
> struct RGBMaskFunctorBase
70 typedef PixelType pixel_type
;
71 typedef ColorType color_type
;
72 typedef typename make_unsigned
<pixel_type
>::type unsigned_pixel_type
;
73 typedef typename ColorTraits
<ColorType
>::component_type component_type
;
75 // calc corrective shifts for all three channels in advance
77 red_shift
= numberOfTrailingZeros
<RedMask
>::value
,
78 green_shift
= numberOfTrailingZeros
<GreenMask
>::value
,
79 blue_shift
= numberOfTrailingZeros
<BlueMask
>::value
,
81 red_bits
= bitcount
<RedMask
>::value
,
82 green_bits
= bitcount
<GreenMask
>::value
,
83 blue_bits
= bitcount
<BlueMask
>::value
87 template< typename PixelType
,
90 unsigned int GreenMask
,
91 unsigned int BlueMask
,
92 bool SwapBytes
> struct RGBMaskGetter
:
93 public RGBMaskFunctorBase
<PixelType
,
99 public std::unary_function
<PixelType
, ColorType
>
101 typedef RGBMaskFunctorBase
<PixelType
,
106 SwapBytes
> base_type
;
108 ColorType
operator()( PixelType v
) const
110 v
= SwapBytes
? byteSwap(v
) : v
;
112 const typename
base_type::unsigned_pixel_type
red (v
& RedMask
);
113 const typename
base_type::unsigned_pixel_type
green(v
& GreenMask
);
114 const typename
base_type::unsigned_pixel_type
blue (v
& BlueMask
);
116 // shift color nibbles to right-aligend position. ORing it
117 // channel value shifted twice the number of channel bits, to
118 // spread the value into the component_type range
119 ColorType
res( (shiftRight(red
,
120 base_type::red_shift
-8*
121 (signed)sizeof(typename
base_type::component_type
)+
122 base_type::red_bits
)) |
124 base_type::red_shift
-8*
125 (signed)sizeof(typename
base_type::component_type
)+
126 2*base_type::red_bits
)),
129 base_type::green_shift
-8*
130 (signed)sizeof(typename
base_type::component_type
)+
131 base_type::green_bits
)) |
133 base_type::green_shift
-8*
134 (signed)sizeof(typename
base_type::component_type
)+
135 2*base_type::green_bits
)),
138 base_type::blue_shift
-8*
139 (signed)sizeof(typename
base_type::component_type
)+
140 base_type::blue_bits
)) |
142 base_type::blue_shift
-8*
143 (signed)sizeof(typename
base_type::component_type
)+
144 2*base_type::blue_bits
)) );
149 template< typename PixelType
,
151 unsigned int RedMask
,
152 unsigned int GreenMask
,
153 unsigned int BlueMask
,
154 bool SwapBytes
> struct RGBMaskSetter
:
155 public RGBMaskFunctorBase
<PixelType
,
161 public std::unary_function
<ColorType
, PixelType
>
163 typedef RGBMaskFunctorBase
<PixelType
,
168 SwapBytes
> base_type
;
170 PixelType
operator()( ColorType
const& c
) const
172 const typename
base_type::unsigned_pixel_type
red (c
.getRed());
173 const typename
base_type::unsigned_pixel_type
green(c
.getGreen());
174 const typename
base_type::unsigned_pixel_type
blue (c
.getBlue());
176 typename
base_type::unsigned_pixel_type
res(
178 base_type::red_shift
-8*
179 (signed)sizeof(typename
base_type::component_type
)+
180 base_type::red_bits
) & RedMask
) |
182 base_type::green_shift
-8*
183 (signed)sizeof(typename
base_type::component_type
)+
184 base_type::green_bits
) & GreenMask
) |
186 base_type::blue_shift
-8*
187 (signed)sizeof(typename
base_type::component_type
)+
188 base_type::blue_bits
) & BlueMask
) );
190 return SwapBytes
? byteSwap(res
) : res
;
194 //-----------------------------------------------------------------------------
196 template< typename PixelType
,
197 unsigned int RedMask
,
198 unsigned int GreenMask
,
199 unsigned int BlueMask
,
200 bool SwapBytes
> struct PixelFormatTraitsTemplate_RGBMask
202 typedef PixelType pixel_type
;
204 typedef RGBMaskGetter
<pixel_type
,
209 SwapBytes
> getter_type
;
210 typedef RGBMaskSetter
<pixel_type
,
215 SwapBytes
> setter_type
;
217 typedef PixelIterator
<pixel_type
> iterator_type
;
218 typedef StandardAccessor
<pixel_type
> raw_accessor_type
;
219 typedef AccessorSelector
<
220 getter_type
, setter_type
> accessor_selector
;
223 //-----------------------------------------------------------------------------
225 // Hopefully this is an understandable plaintext explanation that matches
228 // BASEBMP_TRUECOLORMASK_LSB_SWAP means that on a big-endian platform, a pixel
229 // value when viewed as an integer (16 or 32 bits) has to be byte-swapped for
230 // the channels to match the masks. Or equivalently (I think), on a big-endian
231 // platform, the masks need to be byte-swapped to be correct.
233 // I.e. on a litte-endian platform the masks work as such.
235 // BASEBMP_TRUECOLORMASK_MSB_SWAP means the opposite. The masks work as such
236 // on big-endian platforms, on little-endian platforms the pixel needs to be
237 // byte-swapped for the masks to work.
239 // So in a sense these two names are "backward". It sounds to me as if
240 // BASEBMP_TRUECOLORMASK_LSB_SWAP would mean "when on LSB, swap" ;)
243 # define BASEBMP_TRUECOLORMASK_LSB_SWAP false
244 # define BASEBMP_TRUECOLORMASK_MSB_SWAP true
246 # ifdef OSL_BIGENDIAN
247 # define BASEBMP_TRUECOLORMASK_LSB_SWAP true
248 # define BASEBMP_TRUECOLORMASK_MSB_SWAP false
250 # error Undetermined endianness!
254 //-----------------------------------------------------------------------------
257 typedef PixelFormatTraitsTemplate_RGBMask
<
262 BASEBMP_TRUECOLORMASK_MSB_SWAP
> PixelFormatTraits_RGB16_565_MSB
;
263 BASEBMP_SPECIALIZE_ACCESSORTRAITS(PixelFormatTraits_RGB16_565_MSB::getter_type
,
264 PixelFormatTraits_RGB16_565_MSB::setter_type
);
267 typedef PixelFormatTraitsTemplate_RGBMask
<
272 BASEBMP_TRUECOLORMASK_LSB_SWAP
> PixelFormatTraits_RGB16_565_LSB
;
273 BASEBMP_SPECIALIZE_ACCESSORTRAITS(PixelFormatTraits_RGB16_565_LSB::getter_type
,
274 PixelFormatTraits_RGB16_565_LSB::setter_type
);
279 // The intent is that the order of channel names in the names of the 32bpp
280 // format typedefs below correspond to the order of the channel bytes in
281 // memory, if I understand correctly.... I think the point with the below
282 // formats is that the channel byte order in memory is the same regardless of
283 // platform byte order.
285 // This one used to be called PixelFormatTraits_RGB32_888.
287 typedef PixelFormatTraitsTemplate_RGBMask
<
292 BASEBMP_TRUECOLORMASK_LSB_SWAP
> PixelFormatTraits_BGRX32_8888
;
293 BASEBMP_SPECIALIZE_ACCESSORTRAITS(PixelFormatTraits_BGRX32_8888::getter_type
,
294 PixelFormatTraits_BGRX32_8888::setter_type
);
296 // This one used to be called PixelFormatTraits_BGR32_888.
298 typedef PixelFormatTraitsTemplate_RGBMask
<
303 BASEBMP_TRUECOLORMASK_MSB_SWAP
> PixelFormatTraits_XRGB32_8888
;
304 BASEBMP_SPECIALIZE_ACCESSORTRAITS(PixelFormatTraits_XRGB32_8888::getter_type
,
305 PixelFormatTraits_XRGB32_8888::setter_type
);
307 // The following two ones were added for Android needs and for completeness
309 typedef PixelFormatTraitsTemplate_RGBMask
<
314 BASEBMP_TRUECOLORMASK_LSB_SWAP
> PixelFormatTraits_XBGR32_8888
;
315 BASEBMP_SPECIALIZE_ACCESSORTRAITS(PixelFormatTraits_XBGR32_8888::getter_type
,
316 PixelFormatTraits_XBGR32_8888::setter_type
);
318 typedef PixelFormatTraitsTemplate_RGBMask
<
323 BASEBMP_TRUECOLORMASK_MSB_SWAP
> PixelFormatTraits_RGBX32_8888
;
324 BASEBMP_SPECIALIZE_ACCESSORTRAITS(PixelFormatTraits_RGBX32_8888::getter_type
,
325 PixelFormatTraits_RGBX32_8888::setter_type
);
327 } // namespace basebmp
329 #endif /* INCLUDED_BASEBMP_RGBMASKPIXELFORMATS_HXX */
331 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */