blob: fa3d4bb55f4d08da639b1cdd1c86544999e9d893 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
#ifndef INCLUDED_BASEBMP_RGBMASKPIXELFORMATS_HXX
#define INCLUDED_BASEBMP_RGBMASKPIXELFORMATS_HXX
#include <basebmp/color.hxx>
#include <basebmp/colortraits.hxx>
#include <basebmp/accessor.hxx>
#include <basebmp/pixeliterator.hxx>
#include <basebmp/pixelformatadapters.hxx>
#include <basebmp/metafunctions.hxx>
#include <basebmp/endian.hxx>
#include <vigra/numerictraits.hxx>
#include <vigra/metaprogramming.hxx>
#include <functional>
namespace basebmp
{
/** Base class operating on RGB truecolor mask pixel
Use this template, if you have an (integer) pixel type, and three
bitmasks denoting where the channel bits are.
@tpl PixelType
Input pixel type to operate on
@tpl ColorType
Underlying color type, to convert the pixel values into
@tpl RedMask
Bitmask, to access the red bits in the data type
@tpl GreenMask
Bitmask, to access the green bits in the data type
@tpl BlueMask
Bitmask, to access the blue bits in the data type
@tpl SwapBytes
When true, the final pixel values will be byte-swapped before
passed on.
*/
template< typename PixelType,
typename ColorType,
unsigned int RedMask,
unsigned int GreenMask,
unsigned int BlueMask,
bool SwapBytes > struct RGBMaskFunctorBase
{
typedef PixelType pixel_type;
typedef ColorType color_type;
typedef typename make_unsigned<pixel_type>::type unsigned_pixel_type;
typedef typename ColorTraits<ColorType>::component_type component_type;
// calc corrective shifts for all three channels in advance
enum {
red_shift = numberOfTrailingZeros<RedMask>::value,
green_shift = numberOfTrailingZeros<GreenMask>::value,
blue_shift = numberOfTrailingZeros<BlueMask>::value,
red_bits = bitcount<RedMask>::value,
green_bits = bitcount<GreenMask>::value,
blue_bits = bitcount<BlueMask>::value
};
};
template< typename PixelType,
typename ColorType,
unsigned int RedMask,
unsigned int GreenMask,
unsigned int BlueMask,
bool SwapBytes > struct RGBMaskGetter :
public RGBMaskFunctorBase<PixelType,
ColorType,
RedMask,
GreenMask,
BlueMask,
SwapBytes>,
public std::unary_function<PixelType, ColorType>
{
typedef RGBMaskFunctorBase<PixelType,
ColorType,
RedMask,
GreenMask,
BlueMask,
SwapBytes> base_type;
ColorType operator()( PixelType v ) const
{
v = SwapBytes ? byteSwap(v) : v;
const typename base_type::unsigned_pixel_type red (v & RedMask);
const typename base_type::unsigned_pixel_type green(v & GreenMask);
const typename base_type::unsigned_pixel_type blue (v & BlueMask);
// shift color nibbles to right-aligend position. ORing it
// channel value shifted twice the number of channel bits, to
// spread the value into the component_type range
ColorType res( (shiftRight(red,
base_type::red_shift-8*
(signed)sizeof(typename base_type::component_type)+
base_type::red_bits)) |
(shiftRight(red,
base_type::red_shift-8*
(signed)sizeof(typename base_type::component_type)+
2*base_type::red_bits)),
(shiftRight(green,
base_type::green_shift-8*
(signed)sizeof(typename base_type::component_type)+
base_type::green_bits)) |
(shiftRight(green,
base_type::green_shift-8*
(signed)sizeof(typename base_type::component_type)+
2*base_type::green_bits)),
(shiftRight(blue,
base_type::blue_shift-8*
(signed)sizeof(typename base_type::component_type)+
base_type::blue_bits)) |
(shiftRight(blue,
base_type::blue_shift-8*
(signed)sizeof(typename base_type::component_type)+
2*base_type::blue_bits)) );
return res;
}
};
template< typename PixelType,
typename ColorType,
unsigned int RedMask,
unsigned int GreenMask,
unsigned int BlueMask,
bool SwapBytes > struct RGBMaskSetter :
public RGBMaskFunctorBase<PixelType,
ColorType,
RedMask,
GreenMask,
BlueMask,
SwapBytes>,
public std::unary_function<ColorType, PixelType>
{
typedef RGBMaskFunctorBase<PixelType,
ColorType,
RedMask,
GreenMask,
BlueMask,
SwapBytes> base_type;
PixelType operator()( ColorType const& c ) const
{
const typename base_type::unsigned_pixel_type red (c.getRed());
const typename base_type::unsigned_pixel_type green(c.getGreen());
const typename base_type::unsigned_pixel_type blue (c.getBlue());
typename base_type::unsigned_pixel_type res(
(shiftLeft(red,
base_type::red_shift-8*
(signed)sizeof(typename base_type::component_type)+
base_type::red_bits) & RedMask) |
(shiftLeft(green,
base_type::green_shift-8*
(signed)sizeof(typename base_type::component_type)+
base_type::green_bits) & GreenMask) |
(shiftLeft(blue,
base_type::blue_shift-8*
(signed)sizeof(typename base_type::component_type)+
base_type::blue_bits) & BlueMask) );
return SwapBytes ? byteSwap(res) : res;
}
};
//-----------------------------------------------------------------------------
template< typename PixelType,
unsigned int RedMask,
unsigned int GreenMask,
unsigned int BlueMask,
bool SwapBytes > struct PixelFormatTraitsTemplate_RGBMask
{
typedef PixelType pixel_type;
typedef RGBMaskGetter<pixel_type,
Color,
RedMask,
GreenMask,
BlueMask,
SwapBytes> getter_type;
typedef RGBMaskSetter<pixel_type,
Color,
RedMask,
GreenMask,
BlueMask,
SwapBytes> setter_type;
typedef PixelIterator<pixel_type> iterator_type;
typedef StandardAccessor<pixel_type> raw_accessor_type;
typedef AccessorSelector<
getter_type, setter_type> accessor_selector;
};
//-----------------------------------------------------------------------------
#ifdef OSL_LITENDIAN
# define BASEBMP_TRUECOLORMASK_LSB_SWAP false
# define BASEBMP_TRUECOLORMASK_MSB_SWAP true
#else
# ifdef OSL_BIGENDIAN
# define BASEBMP_TRUECOLORMASK_LSB_SWAP true
# define BASEBMP_TRUECOLORMASK_MSB_SWAP false
# else
# error Undetermined endianness!
# endif
#endif
//-----------------------------------------------------------------------------
// 16bpp MSB RGB
typedef PixelFormatTraitsTemplate_RGBMask<
sal_uInt16,
0xF800,
0x07E0,
0x001F,
BASEBMP_TRUECOLORMASK_MSB_SWAP > PixelFormatTraits_RGB16_565_MSB;
BASEBMP_SPECIALIZE_ACCESSORTRAITS(PixelFormatTraits_RGB16_565_MSB::getter_type,
PixelFormatTraits_RGB16_565_MSB::setter_type);
// 16bpp LSB RGB
typedef PixelFormatTraitsTemplate_RGBMask<
sal_uInt16,
0xF800,
0x07E0,
0x001F,
BASEBMP_TRUECOLORMASK_LSB_SWAP > PixelFormatTraits_RGB16_565_LSB;
BASEBMP_SPECIALIZE_ACCESSORTRAITS(PixelFormatTraits_RGB16_565_LSB::getter_type,
PixelFormatTraits_RGB16_565_LSB::setter_type);
// 32bpp endian-sensitive RGB
typedef PixelFormatTraitsTemplate_RGBMask<
sal_uInt32,
0xFF0000,
0x00FF00,
0x0000FF,
BASEBMP_TRUECOLORMASK_LSB_SWAP > PixelFormatTraits_RGB32_888;
BASEBMP_SPECIALIZE_ACCESSORTRAITS(PixelFormatTraits_RGB32_888::getter_type,
PixelFormatTraits_RGB32_888::setter_type);
// 32bpp endian-sensitive BGR
typedef PixelFormatTraitsTemplate_RGBMask<
sal_uInt32,
0xFF0000,
0x00FF00,
0x0000FF,
BASEBMP_TRUECOLORMASK_MSB_SWAP > PixelFormatTraits_BGR32_888;
BASEBMP_SPECIALIZE_ACCESSORTRAITS(PixelFormatTraits_BGR32_888::getter_type,
PixelFormatTraits_BGR32_888::setter_type);
} // namespace basebmp
#endif /* INCLUDED_BASEBMP_RGBMASKPIXELFORMATS_HXX */