• 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_CHANNEL_HPP
9 #define BOOST_GIL_CONCEPTS_CHANNEL_HPP
10 
11 #include <boost/gil/concepts/basic.hpp>
12 #include <boost/gil/concepts/concept_check.hpp>
13 #include <boost/gil/concepts/fwd.hpp>
14 
15 #include <boost/concept_check.hpp>
16 
17 #include <utility> // std::swap
18 #include <type_traits>
19 
20 #if defined(BOOST_CLANG)
21 #pragma clang diagnostic push
22 #pragma clang diagnostic ignored "-Wunknown-pragmas"
23 #pragma clang diagnostic ignored "-Wunused-local-typedefs"
24 #endif
25 
26 #if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
27 #pragma GCC diagnostic push
28 #pragma GCC diagnostic ignored "-Wunused-local-typedefs"
29 #endif
30 
31 namespace boost { namespace gil {
32 
33 // Forward declarations
34 template <typename T>
35 struct channel_traits;
36 
37 template <typename DstT, typename SrcT>
38 auto channel_convert(SrcT const& val)
39     -> typename channel_traits<DstT>::value_type;
40 
41 /// \ingroup ChannelConcept
42 /// \brief A channel is the building block of a color.
43 /// Color is defined as a mixture of primary colors and a channel defines
44 /// the degree to which each primary color is used in the mixture.
45 ///
46 /// For example, in the RGB color space, using 8-bit unsigned channels,
47 /// the color red is defined as [255 0 0], which means maximum of Red,
48 /// and no Green and Blue.
49 ///
50 /// Built-in scalar types, such as \p int and \p float, are valid GIL channels.
51 /// In more complex scenarios, channels may be represented as bit ranges or
52 /// even individual bits.
53 /// In such cases special classes are needed to represent the value and
54 /// reference to a channel.
55 ///
56 /// Channels have a traits class, \p channel_traits, which defines their
57 /// associated types as well as their operating ranges.
58 ///
59 /// \code
60 /// concept ChannelConcept<typename T> : EqualityComparable<T>
61 /// {
62 ///     typename value_type      = T;        // use channel_traits<T>::value_type to access it
63 ///     typename reference       = T&;       // use channel_traits<T>::reference to access it
64 ///     typename pointer         = T*;       // use channel_traits<T>::pointer to access it
65 ///     typename const_reference = const T&; // use channel_traits<T>::const_reference to access it
66 ///     typename const_pointer   = const T*; // use channel_traits<T>::const_pointer to access it
67 ///     static const bool is_mutable;        // use channel_traits<T>::is_mutable to access it
68 ///
69 ///     static T min_value();                // use channel_traits<T>::min_value to access it
70 ///     static T max_value();                // use channel_traits<T>::max_value to access it
71 /// };
72 /// \endcode
73 template <typename T>
74 struct ChannelConcept
75 {
constraintsboost::gil::ChannelConcept76     void constraints()
77     {
78         gil_function_requires<boost::EqualityComparableConcept<T>>();
79 
80         using v = typename channel_traits<T>::value_type;
81         using r = typename channel_traits<T>::reference;
82         using p = typename channel_traits<T>::pointer;
83         using cr = typename channel_traits<T>::const_reference;
84         using cp = typename channel_traits<T>::const_pointer;
85 
86         channel_traits<T>::min_value();
87         channel_traits<T>::max_value();
88     }
89 
90      T c;
91 };
92 
93 namespace detail
94 {
95 
96 /// \tparam T models ChannelConcept
97 template <typename T>
98 struct ChannelIsMutableConcept
99 {
constraintsboost::gil::detail::ChannelIsMutableConcept100     void constraints()
101     {
102         c1 = c2;
103         using std::swap;
104         swap(c1, c2);
105     }
106     T c1;
107     T c2;
108 };
109 
110 } // namespace detail
111 
112 /// \brief A channel that allows for modifying its value
113 /// \code
114 /// concept MutableChannelConcept<ChannelConcept T> : Assignable<T>, Swappable<T> {};
115 /// \endcode
116 /// \ingroup ChannelConcept
117 template <typename T>
118 struct MutableChannelConcept
119 {
constraintsboost::gil::MutableChannelConcept120     void constraints()
121     {
122         gil_function_requires<ChannelConcept<T>>();
123         gil_function_requires<detail::ChannelIsMutableConcept<T>>();
124     }
125 };
126 
127 /// \brief A channel that supports default construction.
128 /// \code
129 /// concept ChannelValueConcept<ChannelConcept T> : Regular<T> {};
130 /// \endcode
131 /// \ingroup ChannelConcept
132 template <typename T>
133 struct ChannelValueConcept
134 {
constraintsboost::gil::ChannelValueConcept135     void constraints()
136     {
137         gil_function_requires<ChannelConcept<T>>();
138         gil_function_requires<Regular<T>>();
139     }
140 };
141 
142 /// \brief Predicate metafunction returning whether two channels are compatible
143 ///
144 /// Channels are considered compatible if their value types
145 /// (ignoring constness and references) are the same.
146 ///
147 /// Example:
148 ///
149 /// \code
150 /// static_assert(channels_are_compatible<uint8_t, const uint8_t&>::value, "");
151 /// \endcode
152 /// \ingroup ChannelAlgorithm
153 template <typename T1, typename T2>  // Models GIL Pixel
154 struct channels_are_compatible
155     : std::is_same
156         <
157             typename channel_traits<T1>::value_type,
158             typename channel_traits<T2>::value_type
159         >
160 {
161 };
162 
163 /// \brief Channels are compatible if their associated value types (ignoring constness and references) are the same
164 ///
165 /// \code
166 /// concept ChannelsCompatibleConcept<ChannelConcept T1, ChannelConcept T2>
167 /// {
168 ///     where SameType<T1::value_type, T2::value_type>;
169 /// };
170 /// \endcode
171 /// \ingroup ChannelConcept
172 template <typename Channel1, typename Channel2>
173 struct ChannelsCompatibleConcept
174 {
constraintsboost::gil::ChannelsCompatibleConcept175     void constraints()
176     {
177         static_assert(channels_are_compatible<Channel1, Channel2>::value, "");
178     }
179 };
180 
181 /// \brief A channel is convertible to another one if the \p channel_convert algorithm is defined for the two channels.
182 ///
183 /// Convertibility is non-symmetric and implies that one channel can be
184 /// converted to another. Conversion is explicit and often lossy operation.
185 ///
186 /// concept ChannelConvertibleConcept<ChannelConcept SrcChannel, ChannelValueConcept DstChannel>
187 /// {
188 ///     DstChannel channel_convert(const SrcChannel&);
189 /// };
190 /// \endcode
191 /// \ingroup ChannelConcept
192 template <typename SrcChannel, typename DstChannel>
193 struct ChannelConvertibleConcept
194 {
constraintsboost::gil::ChannelConvertibleConcept195     void constraints()
196     {
197         gil_function_requires<ChannelConcept<SrcChannel>>();
198         gil_function_requires<MutableChannelConcept<DstChannel>>();
199         dst = channel_convert<DstChannel, SrcChannel>(src);
200         ignore_unused_variable_warning(dst);
201     }
202     SrcChannel src;
203     DstChannel dst;
204 };
205 
206 }} // namespace boost::gil
207 
208 #if defined(BOOST_CLANG)
209 #pragma clang diagnostic pop
210 #endif
211 
212 #if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
213 #pragma GCC diagnostic pop
214 #endif
215 
216 #endif
217