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