Imported Upstream version 1.72.0
[platform/upstream/boost.git] / boost / gil / concepts / 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_CONCEPTS_PIXEL_HPP
9 #define BOOST_GIL_CONCEPTS_PIXEL_HPP
10
11 #include <boost/gil/concepts/basic.hpp>
12 #include <boost/gil/concepts/channel.hpp>
13 #include <boost/gil/concepts/color.hpp>
14 #include <boost/gil/concepts/color_base.hpp>
15 #include <boost/gil/concepts/concept_check.hpp>
16 #include <boost/gil/concepts/fwd.hpp>
17 #include <boost/gil/concepts/pixel_based.hpp>
18 #include <boost/gil/concepts/detail/type_traits.hpp>
19 #include <boost/gil/detail/mp11.hpp>
20
21 #include <cstddef>
22 #include <type_traits>
23
24 #if defined(BOOST_CLANG)
25 #pragma clang diagnostic push
26 #pragma clang diagnostic ignored "-Wunused-local-typedefs"
27 #endif
28
29 #if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
30 #pragma GCC diagnostic push
31 #pragma GCC diagnostic ignored "-Wunused-local-typedefs"
32 #endif
33
34 namespace boost { namespace gil {
35
36 /// \brief Pixel concept - A color base whose elements are channels
37 /// \ingroup PixelConcept
38 /// \code
39 /// concept PixelConcept<typename P> : ColorBaseConcept<P>, PixelBasedConcept<P>
40 /// {
41 ///     where is_pixel<P>::value == true;
42 ///     // where for each K [0..size<P>::value - 1]:
43 ///     //      ChannelConcept<kth_element_type<P, K>>;
44 ///
45 ///     typename P::value_type;
46 ///         where PixelValueConcept<value_type>;
47 ///     typename P::reference;
48 ///         where PixelConcept<reference>;
49 ///     typename P::const_reference;
50 ///         where PixelConcept<const_reference>;
51 ///     static const bool P::is_mutable;
52 ///
53 ///     template <PixelConcept P2> where { PixelConcept<P, P2> }
54 ///         P::P(P2);
55 ///     template <PixelConcept P2> where { PixelConcept<P, P2> }
56 ///         bool operator==(const P&, const P2&);
57 ///     template <PixelConcept P2> where { PixelConcept<P, P2> }
58 ///         bool operator!=(const P&, const P2&);
59 /// };
60 /// \endcode
61 template <typename P>
62 struct PixelConcept
63 {
64     void constraints()
65     {
66         gil_function_requires<ColorBaseConcept<P>>();
67         gil_function_requires<PixelBasedConcept<P>>();
68
69         static_assert(is_pixel<P>::value, "");
70         static const bool is_mutable = P::is_mutable;
71         ignore_unused_variable_warning(is_mutable);
72
73         using value_type = typename P::value_type;
74         // TODO: Is the cyclic dependency intentional? --mloskot
75         // gil_function_requires<PixelValueConcept<value_type>>();
76
77         using reference = typename P::reference;
78         gil_function_requires<PixelConcept
79             <
80                 typename detail::remove_const_and_reference<reference>::type
81             >>();
82
83         using const_reference = typename P::const_reference;
84         gil_function_requires<PixelConcept
85             <
86                 typename detail::remove_const_and_reference<const_reference>::type
87             >>();
88     }
89 };
90
91 /// \brief Pixel concept that allows for changing its channels
92 /// \ingroup PixelConcept
93 /// \code
94 /// concept MutablePixelConcept<PixelConcept P> : MutableColorBaseConcept<P>
95 /// {
96 ///     where is_mutable==true;
97 /// };
98 /// \endcode
99 template <typename P>
100 struct MutablePixelConcept
101 {
102     void constraints()
103     {
104         gil_function_requires<PixelConcept<P>>();
105         static_assert(P::is_mutable, "");
106     }
107 };
108
109 /// \brief Homogeneous pixel concept
110 /// \ingroup PixelConcept
111 /// \code
112 /// concept HomogeneousPixelConcept<PixelConcept P>
113 ///     : HomogeneousColorBaseConcept<P>, HomogeneousPixelBasedConcept<P>
114 /// {
115 ///     P::template element_const_reference_type<P>::type operator[](P p, std::size_t i) const
116 ///     {
117 ///         return dynamic_at_c(p,i);
118 /// }
119 /// };
120 /// \endcode
121 template <typename P>
122 struct HomogeneousPixelConcept
123 {
124     void constraints()
125     {
126         gil_function_requires<PixelConcept<P>>();
127         gil_function_requires<HomogeneousColorBaseConcept<P>>();
128         gil_function_requires<HomogeneousPixelBasedConcept<P>>();
129         p[0];
130     }
131     P p;
132 };
133
134 /// \brief Homogeneous pixel concept that allows for changing its channels
135 /// \ingroup PixelConcept
136 /// \code
137 /// concept MutableHomogeneousPixelConcept<HomogeneousPixelConcept P>
138 ///     : MutableHomogeneousColorBaseConcept<P>
139 /// {
140 ///     P::template element_reference_type<P>::type operator[](P p, std::size_t i)
141 ///     {
142 ///         return dynamic_at_c(p, i);
143 ///     }
144 /// };
145 /// \endcode
146 template <typename P>
147 struct MutableHomogeneousPixelConcept
148 {
149     void constraints()
150     {
151         gil_function_requires<HomogeneousPixelConcept<P>>();
152         gil_function_requires<MutableHomogeneousColorBaseConcept<P>>();
153         p[0] = v;
154         v = p[0];
155     }
156     typename P::template element_type<P>::type v;
157     P p;
158 };
159
160 /// \brief Pixel concept that is a Regular type
161 /// \ingroup PixelConcept
162 /// \code
163 /// concept PixelValueConcept<PixelConcept P> : Regular<P>
164 /// {
165 ///     where SameType<value_type,P>;
166 /// };
167 /// \endcode
168 template <typename P>
169 struct PixelValueConcept
170 {
171     void constraints()
172     {
173         gil_function_requires<PixelConcept<P>>();
174         gil_function_requires<Regular<P>>();
175     }
176 };
177
178 /// \brief Homogeneous pixel concept that is a Regular type
179 /// \ingroup PixelConcept
180 /// \code
181 /// concept HomogeneousPixelValueConcept<HomogeneousPixelConcept P> : Regular<P>
182 /// {
183 ///     where SameType<value_type,P>;
184 /// };
185 /// \endcode
186 template <typename P>
187 struct HomogeneousPixelValueConcept
188 {
189     void constraints()
190     {
191         gil_function_requires<HomogeneousPixelConcept<P>>();
192         gil_function_requires<Regular<P>>();
193         static_assert(std::is_same<P, typename P::value_type>::value, "");
194     }
195 };
196
197 namespace detail {
198
199 template <typename P1, typename P2, int K>
200 struct channels_are_pairwise_compatible
201     : mp11::mp_and
202     <
203         channels_are_pairwise_compatible<P1, P2, K - 1>,
204         channels_are_compatible
205         <
206             typename kth_semantic_element_reference_type<P1, K>::type,
207             typename kth_semantic_element_reference_type<P2, K>::type
208         >
209     >
210 {
211 };
212
213 template <typename P1, typename P2>
214 struct channels_are_pairwise_compatible<P1, P2, -1> : std::true_type {};
215
216 } // namespace detail
217
218 /// \ingroup PixelAlgorithm
219 /// \brief Returns whether two pixels are compatible
220 /// Pixels are compatible if their channels and color space types are compatible.
221 /// Compatible pixels can be assigned and copy constructed from one another.
222 /// \tparam P1 Models PixelConcept
223 /// \tparam P2 Models PixelConcept
224 template <typename P1, typename P2>
225 struct pixels_are_compatible
226     : mp11::mp_and
227         <
228             typename color_spaces_are_compatible
229             <
230                 typename color_space_type<P1>::type,
231                 typename color_space_type<P2>::type
232             >::type,
233             detail::channels_are_pairwise_compatible
234             <
235                 P1, P2, num_channels<P1>::value - 1
236             >
237         >
238 {
239 };
240
241 /// \ingroup PixelConcept
242 /// \brief  Concept for pixel compatibility
243 /// Pixels are compatible if their channels and color space types are compatible.
244 /// Compatible pixels can be assigned and copy constructed from one another.
245 /// \tparam P1 Models PixelConcept
246 /// \tparam P2 Models PixelConcept
247 /// \code
248 /// concept PixelsCompatibleConcept<PixelConcept P1, PixelConcept P2>
249 ///     : ColorBasesCompatibleConcept<P1,P2> {
250 ///     // where for each K [0..size<P1>::value):
251 ///     //    ChannelsCompatibleConcept<kth_semantic_element_type<P1,K>::type, kth_semantic_element_type<P2,K>::type>;
252 /// };
253 /// \endcode
254 template <typename P1, typename P2>
255 struct PixelsCompatibleConcept
256 {
257     void constraints()
258     {
259         static_assert(pixels_are_compatible<P1, P2>::value, "");
260     }
261 };
262
263 /// \ingroup PixelConcept
264 /// \brief Pixel convertible concept
265 /// Convertibility is non-symmetric and implies that one pixel
266 /// can be converted to another, approximating the color.
267 /// Conversion is explicit and sometimes lossy.
268 /// \code
269 /// template <PixelConcept SrcPixel, MutablePixelConcept DstPixel>
270 /// concept PixelConvertibleConcept
271 /// {
272 ///     void color_convert(const SrcPixel&, DstPixel&);
273 /// };
274 /// \endcode
275 template <typename SrcP, typename DstP>
276 struct PixelConvertibleConcept
277 {
278     void constraints()
279     {
280         gil_function_requires<PixelConcept<SrcP>>();
281         gil_function_requires<MutablePixelConcept<DstP>>();
282         color_convert(src, dst);
283     }
284     SrcP src;
285     DstP dst;
286 };
287
288 }} // namespace boost::gil
289
290 #if defined(BOOST_CLANG)
291 #pragma clang diagnostic pop
292 #endif
293
294 #if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
295 #pragma GCC diagnostic pop
296 #endif
297
298 #endif