TuttleOFX  1
packed_pixel.hpp
Go to the documentation of this file.
00001 /*
00002     Copyright 2005-2007 Adobe Systems Incorporated
00003 
00004     Use, modification and distribution are subject to the Boost Software License,
00005     Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
00006     http://www.boost.org/LICENSE_1_0.txt).
00007 
00008     See http://opensource.adobe.com/gil for most recent version including documentation.
00009  */
00010 
00011 /*************************************************************************************************/
00012 
00013 #ifndef GIL_PACKED_PIXEL_H
00014 #define GIL_PACKED_PIXEL_H
00015 
00016 ////////////////////////////////////////////////////////////////////////////////////////
00017 /// \file
00018 /// \brief A model of a heterogeneous pixel whose channels are bit ranges. For example 16-bit RGB in '565' format
00019 /// \author Lubomir Bourdev and Hailin Jin \n
00020 ///         Adobe Systems Incorporated
00021 /// \date   2005-2007 \n Last updated on September 28, 2006
00022 ///
00023 ////////////////////////////////////////////////////////////////////////////////////////
00024 
00025 #include <functional>
00026 #include <boost/utility/enable_if.hpp>
00027 #include <boost/mpl/bool.hpp>
00028 #include <boost/mpl/front.hpp>
00029 #include "gil_config.hpp"
00030 #include "pixel.hpp"
00031 
00032 namespace boost {
00033 namespace gil {
00034 
00035 /// \defgroup ColorBaseModelPackedPixel packed_pixel
00036 /// \ingroup ColorBaseModel
00037 /// \brief A heterogeneous color base whose elements are reference proxies to channels in a pixel. Models ColorBaseValueConcept. This class is used to model packed pixels, such as 16-bit packed RGB.
00038 
00039 /**
00040    \defgroup PixelModelPackedPixel packed_pixel
00041    \ingroup PixelModel
00042    \brief A heterogeneous pixel used to represent packed pixels with non-byte-aligned channels. Models PixelValueConcept
00043 
00044    Example:
00045    \code
00046    typedef packed_pixel_type<uint16_t, mpl::vector3_c<unsigned,5,6,5>, rgb_layout_t>::type rgb565_pixel_t;
00047    BOOST_STATIC_ASSERT((sizeof(rgb565_pixel_t)==2));
00048 
00049    rgb565_pixel_t r565;
00050    get_color(r565,red_t())   = 31;
00051    get_color(r565,green_t()) = 63;
00052    get_color(r565,blue_t())  = 31;
00053    assert(r565 == rgb565_pixel_t((uint16_t)0xFFFF));
00054    \endcode
00055  */
00056 
00057 /// \ingroup ColorBaseModelPackedPixel PixelModelPackedPixel PixelBasedModel
00058 /// \brief Heterogeneous pixel value whose channel references can be constructed from the pixel bitfield and their index. Models ColorBaseValueConcept, PixelValueConcept, PixelBasedConcept
00059 /// Typical use for this is a model of a packed pixel (like 565 RGB)
00060 template <typename BitField,      // A type that holds the bits of the pixel. Typically an integral type, like boost::uint16_t
00061           typename ChannelRefVec, // An MPL vector whose elements are packed channels. They must be constructible from BitField. GIL uses packed_channel_reference
00062           typename Layout>
00063 // Layout defining the color space and ordering of the channels. Example value: rgb_layout_t
00064 struct packed_pixel
00065 {
00066         BitField _bitfield;
00067 
00068         typedef Layout layout_t;
00069         typedef packed_pixel value_type;
00070         typedef value_type&           reference;
00071         typedef const value_type&     const_reference;
00072 
00073         BOOST_STATIC_CONSTANT( bool, is_mutable = channel_traits<typename mpl::front<ChannelRefVec>::type>::is_mutable );
00074 
00075         packed_pixel() {}
00076         explicit packed_pixel( const BitField& bitfield ) : _bitfield( bitfield ) {}
00077 
00078         // Construct from another compatible pixel type
00079         packed_pixel( const packed_pixel& p ) : _bitfield( p._bitfield ) {}
00080         template <typename P>
00081         packed_pixel( const P& p, typename enable_if_c<is_pixel<P>::value>::type* d = 0 )            { check_compatible<P>(); static_copy( p, *this ); }
00082         packed_pixel( int chan0, int chan1 ) : _bitfield( 0 )
00083         {
00084                 BOOST_STATIC_ASSERT( ( num_channels<packed_pixel>::value == 2 ) );
00085                 at_c<0>( *this ) = chan0; at_c<1>( *this ) = chan1;
00086         }
00087 
00088         packed_pixel( int chan0, int chan1, int chan2 ) : _bitfield( 0 )
00089         {
00090                 BOOST_STATIC_ASSERT( ( num_channels<packed_pixel>::value == 3 ) );
00091                 at_c<0>( *this ) = chan0; at_c<1>( *this ) = chan1; at_c<2>( *this ) = chan2;
00092         }
00093 
00094         packed_pixel( int chan0, int chan1, int chan2, int chan3 ) : _bitfield( 0 )
00095         {
00096                 BOOST_STATIC_ASSERT( ( num_channels<packed_pixel>::value == 4 ) );
00097                 at_c<0>( *this ) = chan0; at_c<1>( *this ) = chan1; at_c<2>( *this ) = chan2; at_c<3>( *this ) = chan3;
00098         }
00099 
00100         packed_pixel( int chan0, int chan1, int chan2, int chan3, int chan4 ) : _bitfield( 0 )
00101         {
00102                 BOOST_STATIC_ASSERT( ( num_channels<packed_pixel>::value == 5 ) );
00103                 at_c<0>( *this ) = chan0; at_c<1>( *this ) = chan1; at_c<2>( *this ) = chan2; at_c<3>( *this ) = chan3;  at_c<4>( *this ) = chan4;
00104         }
00105 
00106         packed_pixel& operator=( const packed_pixel& p ) { _bitfield = p._bitfield; return *this; }
00107 
00108         template <typename P>
00109         packed_pixel& operator=( const P& p ) { assign( p, mpl::bool_<is_pixel<P>::value>() ); return *this; }
00110         template <typename P>
00111         bool operator==( const P& p ) const { return equal( p, mpl::bool_<is_pixel<P>::value>() ); }
00112 
00113         template <typename P>
00114         bool operator!=( const P& p ) const { return !( *this == p ); }
00115 
00116         private:
00117                 template <typename Pixel>
00118                 static void check_compatible() { gil_function_requires<PixelsCompatibleConcept<Pixel, packed_pixel> >(); }
00119                 template <typename Pixel>
00120                 void assign( const Pixel& p, mpl::true_ ) { check_compatible<Pixel>(); static_copy( p, *this ); }
00121                 template <typename Pixel>
00122                 bool equal( const Pixel& p, mpl::true_ ) const { check_compatible<Pixel>(); return static_equal( *this, p ); }
00123 
00124                 // Support for assignment/equality comparison of a channel with a grayscale pixel
00125                 static void check_gray() {  BOOST_STATIC_ASSERT( ( is_same<typename Layout::color_space_t, gray_t>::value ) ); }
00126                 template <typename Channel>
00127                 void assign( const Channel& chan, mpl::false_ ) { check_gray(); at_c<0>( *this ) = chan; }
00128                 template <typename Channel>
00129                 bool equal( const Channel& chan, mpl::false_ ) const { check_gray(); return at_c<0>( *this ) == chan; }
00130 
00131         public:
00132                 packed_pixel&  operator=( int chan )        { check_gray(); at_c<0>( *this ) = chan; return *this; }
00133                 bool operator          ==( int chan ) const { check_gray(); return at_c<0>( *this ) == chan; }
00134 };
00135 
00136 /////////////////////////////
00137 //  ColorBasedConcept
00138 /////////////////////////////
00139 
00140 template <typename BitField, typename ChannelRefVec, typename Layout, int K>
00141 struct kth_element_type<packed_pixel<BitField, ChannelRefVec, Layout>, K> : public mpl::at_c<ChannelRefVec, K> {};
00142 
00143 template <typename BitField, typename ChannelRefVec, typename Layout, int K>
00144 struct kth_element_reference_type<packed_pixel<BitField, ChannelRefVec, Layout>, K> : public mpl::at_c<ChannelRefVec, K> {};
00145 
00146 template <typename BitField, typename ChannelRefVec, typename Layout, int K>
00147 struct kth_element_const_reference_type<packed_pixel<BitField, ChannelRefVec, Layout>, K>
00148 {
00149         typedef typename channel_traits<typename mpl::at_c<ChannelRefVec, K>::type>::const_reference type;
00150 };
00151 
00152 template <int K, typename P, typename C, typename L>
00153 inline
00154 typename kth_element_reference_type<packed_pixel<P, C, L>, K>::type at_c( packed_pixel<P, C, L>& p )
00155 {
00156         return typename kth_element_reference_type<packed_pixel<P, C, L>, K>::type( &p._bitfield );
00157 }
00158 
00159 template <int K, typename P, typename C, typename L>
00160 inline
00161 typename kth_element_const_reference_type<packed_pixel<P, C, L>, K>::type at_c( const packed_pixel<P, C, L>& p )
00162 {
00163         return typename kth_element_const_reference_type<packed_pixel<P, C, L>, K>::type( &p._bitfield );
00164 }
00165 
00166 /////////////////////////////
00167 //  PixelConcept
00168 /////////////////////////////
00169 
00170 // Metafunction predicate that flags packed_pixel as a model of PixelConcept. Required by PixelConcept
00171 template <typename BitField, typename ChannelRefVec, typename Layout>
00172 struct is_pixel<packed_pixel<BitField, ChannelRefVec, Layout> > : public mpl::true_ {};
00173 
00174 /////////////////////////////
00175 //  PixelBasedConcept
00176 /////////////////////////////
00177 
00178 template <typename P, typename C, typename Layout>
00179 struct color_space_type<packed_pixel<P, C, Layout> >
00180 {
00181         typedef typename Layout::color_space_t type;
00182 };
00183 
00184 template <typename P, typename C, typename Layout>
00185 struct channel_mapping_type<packed_pixel<P, C, Layout> >
00186 {
00187         typedef typename Layout::channel_mapping_t type;
00188 };
00189 
00190 template <typename P, typename C, typename Layout>
00191 struct is_planar<packed_pixel<P, C, Layout> > : mpl::false_ {};
00192 
00193 ////////////////////////////////////////////////////////////////////////////////
00194 ///
00195 /// Support for interleaved iterators over packed pixel
00196 ///
00197 ////////////////////////////////////////////////////////////////////////////////
00198 
00199 /// \defgroup PixelIteratorModelPackedInterleavedPtr Pointer to packed_pixel<P,CR,Layout>
00200 /// \ingroup PixelIteratorModel
00201 /// \brief Iterators over interleaved pixels.
00202 /// The pointer packed_pixel<P,CR,Layout>* is used as an iterator over interleaved pixels of packed format. Models PixelIteratorConcept, HasDynamicXStepTypeConcept, MemoryBasedIteratorConcept
00203 
00204 template <typename P, typename C, typename L>
00205 struct iterator_is_mutable<packed_pixel<P, C, L>*> : public mpl::bool_<packed_pixel<P, C, L>::is_mutable> {};
00206 template <typename P, typename C, typename L>
00207 struct iterator_is_mutable<const packed_pixel<P, C, L>*> : public mpl::false_ {};
00208 
00209 }
00210 }    // namespace boost::gil
00211 
00212 namespace boost {
00213 template <typename P, typename C, typename L>
00214 struct has_trivial_constructor<gil::packed_pixel<P, C, L> > : public has_trivial_constructor<P> {};
00215 }
00216 #endif