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_COLOR_BASE_HPP 9 #define BOOST_GIL_CONCEPTS_COLOR_BASE_HPP 10 11 #include <boost/gil/concepts/basic.hpp> 12 #include <boost/gil/concepts/color.hpp> 13 #include <boost/gil/concepts/concept_check.hpp> 14 #include <boost/gil/concepts/fwd.hpp> 15 16 #include <boost/core/ignore_unused.hpp> 17 #include <type_traits> 18 19 #if defined(BOOST_CLANG) 20 #pragma clang diagnostic push 21 #pragma clang diagnostic ignored "-Wunused-local-typedefs" 22 #endif 23 24 #if defined(BOOST_GCC) && (BOOST_GCC >= 40900) 25 #pragma GCC diagnostic push 26 #pragma GCC diagnostic ignored "-Wunused-local-typedefs" 27 #endif 28 29 namespace boost { namespace gil { 30 31 // Forward declarations of at_c 32 namespace detail { 33 34 template <typename Element, typename Layout, int K> 35 struct homogeneous_color_base; 36 37 } // namespace detail 38 39 template <int K, typename E, typename L, int N> 40 auto at_c(detail::homogeneous_color_base<E, L, N>& p) 41 -> typename std::add_lvalue_reference<E>::type; 42 43 template <int K, typename E, typename L, int N> 44 auto at_c(detail::homogeneous_color_base<E, L, N> const& p) 45 -> typename std::add_lvalue_reference<typename std::add_const<E>::type>::type; 46 47 template <typename P, typename C, typename L> 48 struct packed_pixel; 49 50 template <int K, typename P, typename C, typename L> 51 auto at_c(packed_pixel<P, C, L>& p) 52 -> typename kth_element_reference_type<packed_pixel<P, C, L>, K>::type; 53 54 template <int K, typename P, typename C, typename L> 55 auto at_c(packed_pixel<P, C, L> const& p) 56 -> typename kth_element_const_reference_type<packed_pixel<P, C, L>, K>::type; 57 58 template <typename B, typename C, typename L, bool M> 59 struct bit_aligned_pixel_reference; 60 61 template <int K, typename B, typename C, typename L, bool M> 62 inline auto at_c(bit_aligned_pixel_reference<B, C, L, M> const& p) 63 -> typename kth_element_reference_type 64 < 65 bit_aligned_pixel_reference<B, C, L, M>, 66 K 67 >::type; 68 69 // Forward declarations of semantic_at_c 70 template <int K, typename ColorBase> 71 auto semantic_at_c(ColorBase& p) 72 -> typename std::enable_if 73 < 74 !std::is_const<ColorBase>::value, 75 typename kth_semantic_element_reference_type<ColorBase, K>::type 76 >::type; 77 78 template <int K, typename ColorBase> 79 auto semantic_at_c(ColorBase const& p) 80 -> typename kth_semantic_element_const_reference_type<ColorBase, K>::type; 81 82 /// \ingroup ColorBaseConcept 83 /// \brief A color base is a container of color elements (such as channels, channel references or channel pointers). 84 /// 85 /// The most common use of color base is in the implementation of a pixel, 86 /// in which case the color elements are channel values. The color base concept, 87 /// however, can be used in other scenarios. For example, a planar pixel has 88 /// channels that are not contiguous in memory. Its reference is a proxy class 89 /// that uses a color base whose elements are channel references. Its iterator 90 /// uses a color base whose elements are channel iterators. 91 /// 92 /// A color base must have an associated layout (which consists of a color space, 93 /// as well as an ordering of the channels). 94 /// There are two ways to index the elements of a color base: A physical index 95 /// corresponds to the way they are ordered in memory, and a semantic index 96 /// corresponds to the way the elements are ordered in their color space. 97 /// For example, in the RGB color space the elements are ordered as 98 /// {red_t, green_t, blue_t}. For a color base with a BGR layout, the first element 99 /// in physical ordering is the blue element, whereas the first semantic element 100 /// is the red one. 101 /// Models of \p ColorBaseConcept are required to provide the \p at_c<K>(ColorBase) 102 /// function, which allows for accessing the elements based on their physical order. 103 /// GIL provides a \p semantic_at_c<K>(ColorBase) function (described later) 104 /// which can operate on any model of ColorBaseConcept and returns the corresponding 105 /// semantic element. 106 /// 107 /// \code 108 /// concept ColorBaseConcept<typename T> : CopyConstructible<T>, EqualityComparable<T> 109 /// { 110 /// // a GIL layout (the color space and element permutation) 111 /// typename layout_t; 112 /// 113 /// // The type of K-th element 114 /// template <int K> 115 /// struct kth_element_type; 116 /// where Metafunction<kth_element_type>; 117 /// 118 /// // The result of at_c 119 /// template <int K> 120 /// struct kth_element_const_reference_type; 121 /// where Metafunction<kth_element_const_reference_type>; 122 /// 123 /// template <int K> 124 /// kth_element_const_reference_type<T,K>::type at_c(T); 125 /// 126 /// // Copy-constructible and equality comparable with other compatible color bases 127 /// template <ColorBaseConcept T2> where { ColorBasesCompatibleConcept<T,T2> } 128 /// T::T(T2); 129 /// template <ColorBaseConcept T2> where { ColorBasesCompatibleConcept<T,T2> } 130 /// bool operator==(const T&, const T2&); 131 /// template <ColorBaseConcept T2> where { ColorBasesCompatibleConcept<T,T2> } 132 /// bool operator!=(const T&, const T2&); 133 /// }; 134 /// \endcode 135 template <typename ColorBase> 136 struct ColorBaseConcept 137 { constraintsboost::gil::ColorBaseConcept138 void constraints() 139 { 140 gil_function_requires<CopyConstructible<ColorBase>>(); 141 gil_function_requires<EqualityComparable<ColorBase>>(); 142 143 using color_space_t = typename ColorBase::layout_t::color_space_t; 144 gil_function_requires<ColorSpaceConcept<color_space_t>>(); 145 146 using channel_mapping_t = typename ColorBase::layout_t::channel_mapping_t; 147 // TODO: channel_mapping_t must be an Boost.MP11-compatible random access sequence 148 149 static const int num_elements = size<ColorBase>::value; 150 151 using TN = typename kth_element_type<ColorBase, num_elements - 1>::type; 152 using RN = typename kth_element_const_reference_type<ColorBase, num_elements - 1>::type; 153 154 RN r = gil::at_c<num_elements - 1>(cb); 155 boost::ignore_unused(r); 156 157 // functions that work for every pixel (no need to require them) 158 semantic_at_c<0>(cb); 159 semantic_at_c<num_elements-1>(cb); 160 // also static_max(cb), static_min(cb), static_fill(cb,value), 161 // and all variations of static_for_each(), static_generate(), static_transform() 162 } 163 ColorBase cb; 164 }; 165 166 /// \ingroup ColorBaseConcept 167 /// \brief Color base which allows for modifying its elements 168 /// \code 169 /// concept MutableColorBaseConcept<ColorBaseConcept T> : Assignable<T>, Swappable<T> 170 /// { 171 /// template <int K> 172 /// struct kth_element_reference_type; where Metafunction<kth_element_reference_type>; 173 /// 174 /// template <int K> 175 /// kth_element_reference_type<kth_element_type<T,K>::type>::type at_c(T); 176 /// 177 /// template <ColorBaseConcept T2> where { ColorBasesCompatibleConcept<T,T2> } 178 /// T& operator=(T&, const T2&); 179 /// }; 180 /// \endcode 181 template <typename ColorBase> 182 struct MutableColorBaseConcept 183 { constraintsboost::gil::MutableColorBaseConcept184 void constraints() 185 { 186 gil_function_requires<ColorBaseConcept<ColorBase>>(); 187 gil_function_requires<Assignable<ColorBase>>(); 188 gil_function_requires<Swappable<ColorBase>>(); 189 190 using R0 = typename kth_element_reference_type<ColorBase, 0>::type; 191 192 R0 r = gil::at_c<0>(cb); 193 gil::at_c<0>(cb) = r; 194 } 195 ColorBase cb; 196 }; 197 198 /// \ingroup ColorBaseConcept 199 /// \brief Color base that also has a default-constructor. Refines Regular 200 /// \code 201 /// concept ColorBaseValueConcept<typename T> : MutableColorBaseConcept<T>, Regular<T> 202 /// { 203 /// }; 204 /// \endcode 205 template <typename ColorBase> 206 struct ColorBaseValueConcept 207 { constraintsboost::gil::ColorBaseValueConcept208 void constraints() 209 { 210 gil_function_requires<MutableColorBaseConcept<ColorBase>>(); 211 gil_function_requires<Regular<ColorBase>>(); 212 } 213 }; 214 215 /// \ingroup ColorBaseConcept 216 /// \brief Color base whose elements all have the same type 217 /// \code 218 /// concept HomogeneousColorBaseConcept<ColorBaseConcept CB> 219 /// { 220 /// // For all K in [0 ... size<C1>::value-1): 221 /// // where SameType<kth_element_type<CB,K>::type, kth_element_type<CB,K+1>::type>; 222 /// kth_element_const_reference_type<CB,0>::type dynamic_at_c(CB const&, std::size_t n) const; 223 /// }; 224 /// \endcode 225 template <typename ColorBase> 226 struct HomogeneousColorBaseConcept 227 { constraintsboost::gil::HomogeneousColorBaseConcept228 void constraints() 229 { 230 gil_function_requires<ColorBaseConcept<ColorBase>>(); 231 232 static const int num_elements = size<ColorBase>::value; 233 234 using T0 = typename kth_element_type<ColorBase, 0>::type; 235 using TN = typename kth_element_type<ColorBase, num_elements - 1>::type; 236 237 static_assert(std::is_same<T0, TN>::value, ""); // better than nothing 238 239 using R0 = typename kth_element_const_reference_type<ColorBase, 0>::type; 240 R0 r = dynamic_at_c(cb, 0); 241 boost::ignore_unused(r); 242 } 243 ColorBase cb; 244 }; 245 246 /// \ingroup ColorBaseConcept 247 /// \brief Homogeneous color base that allows for modifying its elements 248 /// \code 249 /// concept MutableHomogeneousColorBaseConcept<ColorBaseConcept CB> 250 /// : HomogeneousColorBaseConcept<CB> 251 /// { 252 /// kth_element_reference_type<CB, 0>::type dynamic_at_c(CB&, std::size_t n); 253 /// }; 254 /// \endcode 255 template <typename ColorBase> 256 struct MutableHomogeneousColorBaseConcept 257 { constraintsboost::gil::MutableHomogeneousColorBaseConcept258 void constraints() 259 { 260 gil_function_requires<ColorBaseConcept<ColorBase>>(); 261 gil_function_requires<HomogeneousColorBaseConcept<ColorBase>>(); 262 using R0 = typename kth_element_reference_type<ColorBase, 0>::type; 263 R0 r = dynamic_at_c(cb, 0); 264 boost::ignore_unused(r); 265 dynamic_at_c(cb, 0) = dynamic_at_c(cb, 0); 266 } 267 ColorBase cb; 268 }; 269 270 /// \ingroup ColorBaseConcept 271 /// \brief Homogeneous color base that also has a default constructor. 272 /// Refines Regular. 273 /// 274 /// \code 275 /// concept HomogeneousColorBaseValueConcept<typename T> 276 /// : MutableHomogeneousColorBaseConcept<T>, Regular<T> 277 /// { 278 /// }; 279 /// \endcode 280 template <typename ColorBase> 281 struct HomogeneousColorBaseValueConcept 282 { constraintsboost::gil::HomogeneousColorBaseValueConcept283 void constraints() 284 { 285 gil_function_requires<MutableHomogeneousColorBaseConcept<ColorBase>>(); 286 gil_function_requires<Regular<ColorBase>>(); 287 } 288 }; 289 290 /// \ingroup ColorBaseConcept 291 /// \brief Two color bases are compatible if they have the same color space and their elements are compatible, semantic-pairwise. 292 /// \code 293 /// concept ColorBasesCompatibleConcept<ColorBaseConcept C1, ColorBaseConcept C2> 294 /// { 295 /// where SameType<C1::layout_t::color_space_t, C2::layout_t::color_space_t>; 296 /// // also, for all K in [0 ... size<C1>::value): 297 /// // where Convertible<kth_semantic_element_type<C1,K>::type, kth_semantic_element_type<C2,K>::type>; 298 /// // where Convertible<kth_semantic_element_type<C2,K>::type, kth_semantic_element_type<C1,K>::type>; 299 /// }; 300 /// \endcode 301 template <typename ColorBase1, typename ColorBase2> 302 struct ColorBasesCompatibleConcept 303 { constraintsboost::gil::ColorBasesCompatibleConcept304 void constraints() 305 { 306 static_assert(std::is_same 307 < 308 typename ColorBase1::layout_t::color_space_t, 309 typename ColorBase2::layout_t::color_space_t 310 >::value, ""); 311 312 // using e1 = typename kth_semantic_element_type<ColorBase1,0>::type; 313 // using e2 = typename kth_semantic_element_type<ColorBase2,0>::type; 314 // "e1 is convertible to e2" 315 } 316 }; 317 318 }} // namespace boost::gil 319 320 #if defined(BOOST_CLANG) 321 #pragma clang diagnostic pop 322 #endif 323 324 #if defined(BOOST_GCC) && (BOOST_GCC >= 40900) 325 #pragma GCC diagnostic pop 326 #endif 327 328 #endif 329