packed_pixel.hpp 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. /*
  2. Copyright 2005-2007 Adobe Systems Incorporated
  3. Use, modification and distribution are subject to the Boost Software License,
  4. Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  5. http://www.boost.org/LICENSE_1_0.txt).
  6. See http://opensource.adobe.com/gil for most recent version including documentation.
  7. */
  8. /*************************************************************************************************/
  9. #ifndef GIL_PACKED_PIXEL_H
  10. #define GIL_PACKED_PIXEL_H
  11. ////////////////////////////////////////////////////////////////////////////////////////
  12. /// \file
  13. /// \brief A model of a heterogeneous pixel whose channels are bit ranges. For example 16-bit RGB in '565' format
  14. /// \author Lubomir Bourdev and Hailin Jin \n
  15. /// Adobe Systems Incorporated
  16. /// \date 2005-2009 \n Last updated on February 20, 2009
  17. ///
  18. ////////////////////////////////////////////////////////////////////////////////////////
  19. #include <functional>
  20. #include <boost/core/ignore_unused.hpp>
  21. #include <boost/utility/enable_if.hpp>
  22. #include <boost/mpl/bool.hpp>
  23. #include <boost/mpl/front.hpp>
  24. #include "gil_config.hpp"
  25. #include "pixel.hpp"
  26. namespace boost { namespace gil {
  27. /// \defgroup ColorBaseModelPackedPixel packed_pixel
  28. /// \ingroup ColorBaseModel
  29. /// \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.
  30. /**
  31. \defgroup PixelModelPackedPixel packed_pixel
  32. \ingroup PixelModel
  33. \brief A heterogeneous pixel used to represent packed pixels with non-byte-aligned channels. Models PixelValueConcept
  34. Example:
  35. \code
  36. typedef packed_pixel_type<uint16_t, mpl::vector3_c<unsigned,5,6,5>, rgb_layout_t>::type rgb565_pixel_t;
  37. BOOST_STATIC_ASSERT((sizeof(rgb565_pixel_t)==2));
  38. rgb565_pixel_t r565;
  39. get_color(r565,red_t()) = 31;
  40. get_color(r565,green_t()) = 63;
  41. get_color(r565,blue_t()) = 31;
  42. assert(r565 == rgb565_pixel_t((uint16_t)0xFFFF));
  43. \endcode
  44. */
  45. /// \ingroup ColorBaseModelPackedPixel PixelModelPackedPixel PixelBasedModel
  46. /// \brief Heterogeneous pixel value whose channel references can be constructed from the pixel bitfield and their index. Models ColorBaseValueConcept, PixelValueConcept, PixelBasedConcept
  47. /// Typical use for this is a model of a packed pixel (like 565 RGB)
  48. template <typename BitField, // A type that holds the bits of the pixel. Typically an integral type, like std::uint16_t
  49. typename ChannelRefVec, // An MPL vector whose elements are packed channels. They must be constructible from BitField. GIL uses packed_channel_reference
  50. typename Layout> // Layout defining the color space and ordering of the channels. Example value: rgb_layout_t
  51. struct packed_pixel {
  52. BitField _bitfield;
  53. typedef Layout layout_t;
  54. typedef packed_pixel value_type;
  55. typedef value_type& reference;
  56. typedef const value_type& const_reference;
  57. BOOST_STATIC_CONSTANT(bool, is_mutable = channel_traits<typename mpl::front<ChannelRefVec>::type>::is_mutable);
  58. packed_pixel(){}
  59. explicit packed_pixel(const BitField& bitfield) : _bitfield(bitfield) {}
  60. // Construct from another compatible pixel type
  61. packed_pixel(const packed_pixel& p) : _bitfield(p._bitfield) {}
  62. template <typename P> packed_pixel(const P& p, typename enable_if_c<is_pixel<P>::value>::type* d=0) {
  63. check_compatible<P>(); static_copy(p,*this);
  64. boost::ignore_unused(d);
  65. }
  66. packed_pixel(int chan0, int chan1) : _bitfield(0) {
  67. BOOST_STATIC_ASSERT((num_channels<packed_pixel>::value==2));
  68. gil::at_c<0>(*this)=chan0; gil::at_c<1>(*this)=chan1;
  69. }
  70. packed_pixel(int chan0, int chan1, int chan2) : _bitfield(0) {
  71. BOOST_STATIC_ASSERT((num_channels<packed_pixel>::value==3));
  72. gil::at_c<0>(*this) = chan0;
  73. gil::at_c<1>(*this) = chan1;
  74. gil::at_c<2>(*this) = chan2;
  75. }
  76. packed_pixel(int chan0, int chan1, int chan2, int chan3) : _bitfield(0) {
  77. BOOST_STATIC_ASSERT((num_channels<packed_pixel>::value==4));
  78. gil::at_c<0>(*this)=chan0; gil::at_c<1>(*this)=chan1; gil::at_c<2>(*this)=chan2; gil::at_c<3>(*this)=chan3;
  79. }
  80. packed_pixel(int chan0, int chan1, int chan2, int chan3, int chan4) : _bitfield(0) {
  81. BOOST_STATIC_ASSERT((num_channels<packed_pixel>::value==5));
  82. gil::at_c<0>(*this)=chan0; gil::at_c<1>(*this)=chan1; gil::at_c<2>(*this)=chan2; gil::at_c<3>(*this)=chan3; gil::at_c<4>(*this)=chan4;
  83. }
  84. packed_pixel& operator=(const packed_pixel& p) { _bitfield=p._bitfield; return *this; }
  85. template <typename P> packed_pixel& operator=(const P& p) { assign(p, mpl::bool_<is_pixel<P>::value>()); return *this; }
  86. template <typename P> bool operator==(const P& p) const { return equal(p, mpl::bool_<is_pixel<P>::value>()); }
  87. template <typename P> bool operator!=(const P& p) const { return !(*this==p); }
  88. private:
  89. template <typename Pixel> static void check_compatible() { gil_function_requires<PixelsCompatibleConcept<Pixel,packed_pixel> >(); }
  90. template <typename Pixel> void assign(const Pixel& p, mpl::true_) { check_compatible<Pixel>(); static_copy(p,*this); }
  91. template <typename Pixel> bool equal(const Pixel& p, mpl::true_) const { check_compatible<Pixel>(); return static_equal(*this,p); }
  92. // Support for assignment/equality comparison of a channel with a grayscale pixel
  93. static void check_gray() { BOOST_STATIC_ASSERT((is_same<typename Layout::color_space_t, gray_t>::value)); }
  94. template <typename Channel> void assign(const Channel& chan, mpl::false_) { check_gray(); gil::at_c<0>(*this)=chan; }
  95. template <typename Channel> bool equal (const Channel& chan, mpl::false_) const { check_gray(); return gil::at_c<0>(*this)==chan; }
  96. public:
  97. packed_pixel& operator= (int chan) { check_gray(); gil::at_c<0>(*this)=chan; return *this; }
  98. bool operator==(int chan) const { check_gray(); return gil::at_c<0>(*this)==chan; }
  99. };
  100. /////////////////////////////
  101. // ColorBasedConcept
  102. /////////////////////////////
  103. template <typename BitField, typename ChannelRefVec, typename Layout, int K>
  104. struct kth_element_type<packed_pixel<BitField,ChannelRefVec,Layout>,K> : public mpl::at_c<ChannelRefVec,K> {};
  105. template <typename BitField, typename ChannelRefVec, typename Layout, int K>
  106. struct kth_element_reference_type<packed_pixel<BitField,ChannelRefVec,Layout>,K> : public mpl::at_c<ChannelRefVec,K> {};
  107. template <typename BitField, typename ChannelRefVec, typename Layout, int K>
  108. struct kth_element_const_reference_type<packed_pixel<BitField,ChannelRefVec,Layout>,K> {
  109. typedef typename channel_traits<typename mpl::at_c<ChannelRefVec,K>::type>::const_reference type;
  110. };
  111. template <int K, typename P, typename C, typename L> inline
  112. typename kth_element_reference_type<packed_pixel<P,C,L>, K>::type
  113. at_c(packed_pixel<P,C,L>& p) {
  114. return typename kth_element_reference_type<packed_pixel<P,C,L>, K>::type(&p._bitfield);
  115. }
  116. template <int K, typename P, typename C, typename L> inline
  117. typename kth_element_const_reference_type<packed_pixel<P,C,L>, K>::type
  118. at_c(const packed_pixel<P,C,L>& p) {
  119. return typename kth_element_const_reference_type<packed_pixel<P,C,L>, K>::type(&p._bitfield);
  120. }
  121. /////////////////////////////
  122. // PixelConcept
  123. /////////////////////////////
  124. // Metafunction predicate that flags packed_pixel as a model of PixelConcept. Required by PixelConcept
  125. template <typename BitField, typename ChannelRefVec, typename Layout>
  126. struct is_pixel<packed_pixel<BitField,ChannelRefVec,Layout> > : public mpl::true_{};
  127. /////////////////////////////
  128. // PixelBasedConcept
  129. /////////////////////////////
  130. template <typename P, typename C, typename Layout>
  131. struct color_space_type<packed_pixel<P,C,Layout> > {
  132. typedef typename Layout::color_space_t type;
  133. };
  134. template <typename P, typename C, typename Layout>
  135. struct channel_mapping_type<packed_pixel<P,C,Layout> > {
  136. typedef typename Layout::channel_mapping_t type;
  137. };
  138. template <typename P, typename C, typename Layout>
  139. struct is_planar<packed_pixel<P,C,Layout> > : mpl::false_ {};
  140. ////////////////////////////////////////////////////////////////////////////////
  141. ///
  142. /// Support for interleaved iterators over packed pixel
  143. ///
  144. ////////////////////////////////////////////////////////////////////////////////
  145. /// \defgroup PixelIteratorModelPackedInterleavedPtr Pointer to packed_pixel<P,CR,Layout>
  146. /// \ingroup PixelIteratorModel
  147. /// \brief Iterators over interleaved pixels.
  148. /// The pointer packed_pixel<P,CR,Layout>* is used as an iterator over interleaved pixels of packed format. Models PixelIteratorConcept, HasDynamicXStepTypeConcept, MemoryBasedIteratorConcept
  149. template <typename P, typename C, typename L>
  150. struct iterator_is_mutable<packed_pixel<P,C,L>*> : public mpl::bool_<packed_pixel<P,C,L>::is_mutable> {};
  151. template <typename P, typename C, typename L>
  152. struct iterator_is_mutable<const packed_pixel<P,C,L>*> : public mpl::false_ {};
  153. } } // namespace boost::gil
  154. namespace boost {
  155. template <typename P, typename C, typename L>
  156. struct has_trivial_constructor<gil::packed_pixel<P,C,L> > : public has_trivial_constructor<P> {};
  157. }
  158. #endif