###  | #  |

packed_pixel.hpp
1//
2// Copyright 2005-2007 Adobe Systems Incorporated
3//
4// Distributed under the Boost Software License, Version 1.0
5// See accompanying file LICENSE_1_0.txt or copy at
6// http://www.boost.org/LICENSE_1_0.txt
7//
8#ifndef BOOST_GIL_PACKED_PIXEL_HPP
9#define BOOST_GIL_PACKED_PIXEL_HPP
10
11#include <boost/gil/pixel.hpp>
12#include <boost/gil/detail/mp11.hpp>
13
14#include <functional>
15#include <type_traits>
16
17 namespace boost { namespace gil {
18
21
25
41
48 template <typename BitField, typename ChannelRefs, typename Layout>
49 struct packed_pixel
50{
51 BitField _bitfield{0}; // TODO: Make private
52
53 using layout_t = Layout;
54 using value_type = packed_pixel<BitField, ChannelRefs, Layout>;
55 using reference = value_type&;
56 using const_reference = value_type const&;
57
58 static constexpr bool is_mutable =
59 channel_traits<mp11::mp_front<ChannelRefs>>::is_mutable;
60
61 packed_pixel() = default;
62 explicit packed_pixel(const BitField& bitfield) : _bitfield(bitfield) {}
63
64 template <typename Pixel>
65 packed_pixel(Pixel const& p,
66 typename std::enable_if<is_pixel<Pixel>::value>::type* /*dummy*/ = nullptr)
67 {
68 check_compatible<Pixel>();
69 static_copy(p, *this);
70 }
71
72 packed_pixel(int chan0, int chan1)
73 : _bitfield(0)
74 {
75 static_assert(num_channels<packed_pixel>::value == 2, "");
76 gil::at_c<0>(*this) = chan0;
77 gil::at_c<1>(*this) = chan1;
78 }
79
80 packed_pixel(int chan0, int chan1, int chan2)
81 : _bitfield(0)
82 {
83 static_assert(num_channels<packed_pixel>::value == 3, "");
84 gil::at_c<0>(*this) = chan0;
85 gil::at_c<1>(*this) = chan1;
86 gil::at_c<2>(*this) = chan2;
87 }
88
89 packed_pixel(int chan0, int chan1, int chan2, int chan3)
90 : _bitfield(0)
91 {
92 static_assert(num_channels<packed_pixel>::value == 4, "");
93 gil::at_c<0>(*this) = chan0;
94 gil::at_c<1>(*this) = chan1;
95 gil::at_c<2>(*this) = chan2;
96 gil::at_c<3>(*this) = chan3;
97 }
98
99 packed_pixel(int chan0, int chan1, int chan2, int chan3, int chan4)
100 : _bitfield(0)
101 {
102 static_assert(num_channels<packed_pixel>::value == 5, "");
103 gil::at_c<0>(*this) = chan0;
104 gil::at_c<1>(*this) = chan1;
105 gil::at_c<2>(*this) = chan2;
106 gil::at_c<3>(*this) = chan3;
107 gil::at_c<4>(*this) = chan4;
108 }
109
110 template <typename Pixel>
111 auto operator=(Pixel const& p) -> packed_pixel&
112 {
113 assign(p, is_pixel<Pixel>());
114 return *this;
115 }
116
117 template <typename Pixel>
118 bool operator==(Pixel const& p) const
119 {
120 return equal(p, is_pixel<Pixel>());
121 }
122
123 template <typename Pixel>
124 bool operator!=(Pixel const& p) const { return !(*this==p); }
125
126 private:
127 template <typename Pixel>
128 static void check_compatible()
129 {
130 gil_function_requires<PixelsCompatibleConcept<Pixel, packed_pixel>>();
131 }
132
133 template <typename Pixel>
134 void assign(Pixel const& p, std::true_type)
135 {
136 check_compatible<Pixel>();
137 static_copy(p, *this);
138 }
139
140 template <typename Pixel>
141 bool equal(Pixel const& p, std::true_type) const
142 {
143 check_compatible<Pixel>();
144 return static_equal(*this, p);
145 }
146
147 // Support for assignment/equality comparison of a channel with a grayscale pixel
148 static void check_gray()
149 {
150 static_assert(std::is_same<typename Layout::color_space_t, gray_t>::value, "");
151 }
152
153 template <typename Channel>
154 void assign(Channel const& channel, std::false_type)
155 {
156 check_gray();
157 gil::at_c<0>(*this) = channel;
158 }
159
160 template <typename Channel>
161 bool equal (Channel const& channel, std::false_type) const
162 {
163 check_gray();
164 return gil::at_c<0>(*this) == channel;
165 }
166
167 public:
168 auto operator=(int channel) -> packed_pixel&
169 {
170 check_gray();
171 gil::at_c<0>(*this) = channel;
172 return *this;
173 }
174
175 bool operator==(int channel) const
176 {
177 check_gray();
178 return gil::at_c<0>(*this) == channel;
179 }
180};
181
183// ColorBasedConcept
185
186 template <typename BitField, typename ChannelRefs, typename Layout, int K>
187 struct kth_element_type<packed_pixel<BitField, ChannelRefs, Layout>, K>
188{
189 using type = typename channel_traits<mp11::mp_at_c<ChannelRefs, K>>::value_type;
190};
191
192 template <typename BitField, typename ChannelRefs, typename Layout, int K>
193 struct kth_element_reference_type<packed_pixel<BitField, ChannelRefs, Layout>, K>
194{
195 using type = typename channel_traits<mp11::mp_at_c<ChannelRefs, K>>::reference;
196};
197
198 template <typename BitField, typename ChannelRefs, typename Layout, int K>
199 struct kth_element_const_reference_type<packed_pixel<BitField, ChannelRefs, Layout>, K>
200{
201 using type = typename channel_traits<mp11::mp_at_c<ChannelRefs, K>>::const_reference;
202};
203
204 template <int K, typename P, typename C, typename L>
205 inline
206 auto at_c(packed_pixel<P, C, L>& p)
207 -> typename kth_element_reference_type<packed_pixel<P, C, L>, K>::type
208{
209 return typename kth_element_reference_type
210 <
211 packed_pixel<P, C, L>,
212 K
213 >::type{&p._bitfield};
214}
215
216 template <int K, typename P, typename C, typename L>
217 inline
218 auto at_c(const packed_pixel<P, C, L>& p)
219 -> typename kth_element_const_reference_type<packed_pixel<P, C, L>, K>::type
220{
221 return typename kth_element_const_reference_type
222 <
223 packed_pixel<P, C, L>,
224 K>::type{&p._bitfield};
225}
226
228// PixelConcept
230
231// Metafunction predicate that flags packed_pixel as a model of PixelConcept.
232// Required by PixelConcept
233 template <typename BitField, typename ChannelRefs, typename Layout>
234 struct is_pixel<packed_pixel<BitField, ChannelRefs, Layout>> : std::true_type {};
235
237// PixelBasedConcept
239
240 template <typename P, typename C, typename Layout>
241 struct color_space_type<packed_pixel<P, C, Layout>>
242{
243 using type = typename Layout::color_space_t;
244};
245
246 template <typename P, typename C, typename Layout>
247 struct channel_mapping_type<packed_pixel<P, C, Layout>>
248{
249 using type = typename Layout::channel_mapping_t;
250};
251
252 template <typename P, typename C, typename Layout>
253 struct is_planar<packed_pixel<P, C, Layout>> : std::false_type {};
254
258
265
266 template <typename P, typename C, typename L>
267 struct iterator_is_mutable<packed_pixel<P, C, L>*>
268 : std::integral_constant<bool, packed_pixel<P, C, L>::is_mutable>
269{};
270
271 template <typename P, typename C, typename L>
272 struct iterator_is_mutable<const packed_pixel<P, C, L>*> : std::false_type {};
273
274}} // namespace boost::gil
275
276#endif
boost
defined(BOOST_NO_CXX17_HDR_MEMORY_RESOURCE)
Definition: algorithm.hpp:36
boost::gil::num_channels
Returns the number of channels of a pixel-based GIL construct.
Definition: pixel.hpp:54
boost::gil::packed_pixel
Heterogeneous pixel value whose channel references can be constructed from the pixel bitfield and the...
Definition: packed_pixel.hpp:50