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