color_base.hpp 11 KB

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