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