2 // Copyright 2005-2007 Adobe Systems Incorporated
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
8 #ifndef BOOST_GIL_CONCEPTS_PIXEL_HPP
9 #define BOOST_GIL_CONCEPTS_PIXEL_HPP
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>
22 #include <type_traits>
24 #if defined(BOOST_CLANG)
25 #pragma clang diagnostic push
26 #pragma clang diagnostic ignored "-Wunused-local-typedefs"
29 #if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
30 #pragma GCC diagnostic push
31 #pragma GCC diagnostic ignored "-Wunused-local-typedefs"
34 namespace boost { namespace gil {
36 /// \brief Pixel concept - A color base whose elements are channels
37 /// \ingroup PixelConcept
39 /// concept PixelConcept<typename P> : ColorBaseConcept<P>, PixelBasedConcept<P>
41 /// where is_pixel<P>::value == true;
42 /// // where for each K [0..size<P>::value - 1]:
43 /// // ChannelConcept<kth_element_type<P, K>>;
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;
53 /// template <PixelConcept P2> where { PixelConcept<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&);
66 gil_function_requires<ColorBaseConcept<P>>();
67 gil_function_requires<PixelBasedConcept<P>>();
69 static_assert(is_pixel<P>::value, "");
70 static const bool is_mutable = P::is_mutable;
71 ignore_unused_variable_warning(is_mutable);
73 using value_type = typename P::value_type;
74 // TODO: Is the cyclic dependency intentional? --mloskot
75 // gil_function_requires<PixelValueConcept<value_type>>();
77 using reference = typename P::reference;
78 gil_function_requires<PixelConcept
80 typename detail::remove_const_and_reference<reference>::type
83 using const_reference = typename P::const_reference;
84 gil_function_requires<PixelConcept
86 typename detail::remove_const_and_reference<const_reference>::type
91 /// \brief Pixel concept that allows for changing its channels
92 /// \ingroup PixelConcept
94 /// concept MutablePixelConcept<PixelConcept P> : MutableColorBaseConcept<P>
96 /// where is_mutable==true;
100 struct MutablePixelConcept
104 gil_function_requires<PixelConcept<P>>();
105 static_assert(P::is_mutable, "");
109 /// \brief Homogeneous pixel concept
110 /// \ingroup PixelConcept
112 /// concept HomogeneousPixelConcept<PixelConcept P>
113 /// : HomogeneousColorBaseConcept<P>, HomogeneousPixelBasedConcept<P>
115 /// P::template element_const_reference_type<P>::type operator[](P p, std::size_t i) const
117 /// return dynamic_at_c(p,i);
121 template <typename P>
122 struct HomogeneousPixelConcept
126 gil_function_requires<PixelConcept<P>>();
127 gil_function_requires<HomogeneousColorBaseConcept<P>>();
128 gil_function_requires<HomogeneousPixelBasedConcept<P>>();
134 /// \brief Homogeneous pixel concept that allows for changing its channels
135 /// \ingroup PixelConcept
137 /// concept MutableHomogeneousPixelConcept<HomogeneousPixelConcept P>
138 /// : MutableHomogeneousColorBaseConcept<P>
140 /// P::template element_reference_type<P>::type operator[](P p, std::size_t i)
142 /// return dynamic_at_c(p, i);
146 template <typename P>
147 struct MutableHomogeneousPixelConcept
151 gil_function_requires<HomogeneousPixelConcept<P>>();
152 gil_function_requires<MutableHomogeneousColorBaseConcept<P>>();
156 typename P::template element_type<P>::type v;
160 /// \brief Pixel concept that is a Regular type
161 /// \ingroup PixelConcept
163 /// concept PixelValueConcept<PixelConcept P> : Regular<P>
165 /// where SameType<value_type,P>;
168 template <typename P>
169 struct PixelValueConcept
173 gil_function_requires<PixelConcept<P>>();
174 gil_function_requires<Regular<P>>();
178 /// \brief Homogeneous pixel concept that is a Regular type
179 /// \ingroup PixelConcept
181 /// concept HomogeneousPixelValueConcept<HomogeneousPixelConcept P> : Regular<P>
183 /// where SameType<value_type,P>;
186 template <typename P>
187 struct HomogeneousPixelValueConcept
191 gil_function_requires<HomogeneousPixelConcept<P>>();
192 gil_function_requires<Regular<P>>();
193 static_assert(std::is_same<P, typename P::value_type>::value, "");
199 template <typename P1, typename P2, int K>
200 struct channels_are_pairwise_compatible
203 channels_are_pairwise_compatible<P1, P2, K - 1>,
204 channels_are_compatible
206 typename kth_semantic_element_reference_type<P1, K>::type,
207 typename kth_semantic_element_reference_type<P2, K>::type
213 template <typename P1, typename P2>
214 struct channels_are_pairwise_compatible<P1, P2, -1> : std::true_type {};
216 } // namespace detail
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
228 typename color_spaces_are_compatible
230 typename color_space_type<P1>::type,
231 typename color_space_type<P2>::type
233 detail::channels_are_pairwise_compatible
235 P1, P2, num_channels<P1>::value - 1
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
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>;
254 template <typename P1, typename P2>
255 struct PixelsCompatibleConcept
259 static_assert(pixels_are_compatible<P1, P2>::value, "");
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.
269 /// template <PixelConcept SrcPixel, MutablePixelConcept DstPixel>
270 /// concept PixelConvertibleConcept
272 /// void color_convert(const SrcPixel&, DstPixel&);
275 template <typename SrcP, typename DstP>
276 struct PixelConvertibleConcept
280 gil_function_requires<PixelConcept<SrcP>>();
281 gil_function_requires<MutablePixelConcept<DstP>>();
282 color_convert(src, dst);
288 }} // namespace boost::gil
290 #if defined(BOOST_CLANG)
291 #pragma clang diagnostic pop
294 #if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
295 #pragma GCC diagnostic pop