color_base.rst 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. Color Base
  2. ==========
  3. .. contents::
  4. :local:
  5. :depth: 2
  6. Overview
  7. --------
  8. A color base is a container of color elements. The most common use of color
  9. base is in the implementation of a pixel, in which case the color elements are
  10. channel values. The color base concept, however, can be used in other
  11. scenarios. For example, a planar pixel has channels that are not contiguous in
  12. memory. Its reference is a proxy class that uses a color base whose elements
  13. are channel references. Its iterator uses a color base whose elements are
  14. channel iterators.
  15. Color base models must satisfy the following concepts:
  16. .. code-block:: cpp
  17. concept ColorBaseConcept<typename T>
  18. : CopyConstructible<T>, EqualityComparable<T>
  19. {
  20. // a GIL layout (the color space and element permutation)
  21. typename layout_t;
  22. // The type of K-th element
  23. template <int K> struct kth_element_type;
  24. where Metafunction<kth_element_type>;
  25. // The result of at_c
  26. template <int K> struct kth_element_const_reference_type;
  27. where Metafunction<kth_element_const_reference_type>;
  28. template <int K> kth_element_const_reference_type<T,K>::type at_c(T);
  29. template <ColorBaseConcept T2> where { ColorBasesCompatibleConcept<T,T2> }
  30. T::T(T2);
  31. template <ColorBaseConcept T2> where { ColorBasesCompatibleConcept<T,T2> }
  32. bool operator==(const T&, const T2&);
  33. template <ColorBaseConcept T2> where { ColorBasesCompatibleConcept<T,T2> }
  34. bool operator!=(const T&, const T2&);
  35. };
  36. concept MutableColorBaseConcept<ColorBaseConcept T>
  37. : Assignable<T>, Swappable<T>
  38. {
  39. template <int K> struct kth_element_reference_type;
  40. where Metafunction<kth_element_reference_type>;
  41. template <int K> kth_element_reference_type<T,K>::type at_c(T);
  42. template <ColorBaseConcept T2> where { ColorBasesCompatibleConcept<T,T2> }
  43. T& operator=(T&, const T2&);
  44. };
  45. concept ColorBaseValueConcept<typename T> : MutableColorBaseConcept<T>, Regular<T>
  46. {
  47. };
  48. concept HomogeneousColorBaseConcept<ColorBaseConcept CB>
  49. {
  50. // For all K in [0 ... size<C1>::value-1):
  51. // where SameType<kth_element_type<K>::type, kth_element_type<K+1>::type>;
  52. kth_element_const_reference_type<0>::type dynamic_at_c(const CB&, std::size_t n) const;
  53. };
  54. concept MutableHomogeneousColorBaseConcept<MutableColorBaseConcept CB>
  55. : HomogeneousColorBaseConcept<CB>
  56. {
  57. kth_element_reference_type<0>::type dynamic_at_c(const CB&, std::size_t n);
  58. };
  59. concept HomogeneousColorBaseValueConcept<typename T>
  60. : MutableHomogeneousColorBaseConcept<T>, Regular<T>
  61. {
  62. };
  63. concept ColorBasesCompatibleConcept<ColorBaseConcept C1, ColorBaseConcept C2>
  64. {
  65. where SameType<C1::layout_t::color_space_t, C2::layout_t::color_space_t>;
  66. // also, for all K in [0 ... size<C1>::value):
  67. // where Convertible<kth_semantic_element_type<C1,K>::type, kth_semantic_element_type<C2,K>::type>;
  68. // where Convertible<kth_semantic_element_type<C2,K>::type, kth_semantic_element_type<C1,K>::type>;
  69. };
  70. A color base must have an associated layout (which consists of a color space,
  71. as well as an ordering of the channels). There are two ways to index the
  72. elements of a color base: A physical index corresponds to the way they are
  73. ordered in memory, and a semantic index corresponds to the way the elements
  74. are ordered in their color space. For example, in the RGB color space the
  75. elements are ordered as ``{red_t, green_t, blue_t}``. For a color base with
  76. a BGR layout, the first element in physical ordering is the blue element,
  77. whereas the first semantic element is the red one. Models of
  78. ``ColorBaseConcept`` are required to provide the ``at_c<K>(ColorBase)``
  79. function, which allows for accessing the elements based on their physical
  80. order. GIL provides a ``semantic_at_c<K>(ColorBase)`` function (described
  81. later) which can operate on any model of ColorBaseConcept and returns the
  82. corresponding semantic element.
  83. Two color bases are *compatible* if they have the same color space and their
  84. elements (paired semantically) are convertible to each other.
  85. Models
  86. ------
  87. GIL provides a model for a homogeneous color base (a color base whose elements
  88. all have the same type).
  89. .. code-block:: cpp
  90. namespace detail
  91. {
  92. template <typename Element, typename Layout, int K>
  93. struct homogeneous_color_base;
  94. }
  95. It is used in the implementation of GIL's pixel, planar pixel reference and
  96. planar pixel iterator. Another model of ``ColorBaseConcept`` is
  97. ``packed_pixel`` - it is a pixel whose channels are bit ranges.
  98. See the :doc:`pixel` section for more.
  99. Algorithms
  100. ----------
  101. GIL provides the following functions and metafunctions operating on color
  102. bases:
  103. .. code-block:: cpp
  104. // Metafunction returning an mpl::int_ equal to the number of elements in the color base
  105. template <class ColorBase> struct size;
  106. // Returns the type of the return value of semantic_at_c<K>(color_base)
  107. template <class ColorBase, int K> struct kth_semantic_element_reference_type;
  108. template <class ColorBase, int K> struct kth_semantic_element_const_reference_type;
  109. // Returns a reference to the element with K-th semantic index.
  110. template <class ColorBase, int K>
  111. typename kth_semantic_element_reference_type<ColorBase,K>::type semantic_at_c(ColorBase& p)
  112. template <class ColorBase, int K>
  113. typename kth_semantic_element_const_reference_type<ColorBase,K>::type semantic_at_c(const ColorBase& p)
  114. // Returns the type of the return value of get_color<Color>(color_base)
  115. template <typename Color, typename ColorBase> struct color_reference_t;
  116. template <typename Color, typename ColorBase> struct color_const_reference_t;
  117. // Returns a reference to the element corresponding to the given color
  118. template <typename ColorBase, typename Color>
  119. typename color_reference_t<Color,ColorBase>::type get_color(ColorBase& cb, Color=Color());
  120. template <typename ColorBase, typename Color>
  121. typename color_const_reference_t<Color,ColorBase>::type get_color(const ColorBase& cb, Color=Color());
  122. // Returns the element type of the color base. Defined for homogeneous color bases only
  123. template <typename ColorBase> struct element_type;
  124. template <typename ColorBase> struct element_reference_type;
  125. template <typename ColorBase> struct element_const_reference_type;
  126. GIL also provides the following algorithms which operate on color bases.
  127. Note that they all pair the elements semantically:
  128. .. code-block:: cpp
  129. // Equivalents to std::equal, std::copy, std::fill, std::generate
  130. template <typename CB1,typename CB2> bool static_equal(const CB1& p1, const CB2& p2);
  131. template <typename Src,typename Dst> void static_copy(const Src& src, Dst& dst);
  132. template <typename CB, typename Op> void static_generate(CB& dst,Op op);
  133. // Equivalents to std::transform
  134. template <typename CB , typename Dst,typename Op> Op static_transform( CB&,Dst&,Op);
  135. template <typename CB , typename Dst,typename Op> Op static_transform(const CB&,Dst&,Op);
  136. template <typename CB1,typename CB2,typename Dst,typename Op> Op static_transform( CB1&, CB2&,Dst&,Op);
  137. template <typename CB1,typename CB2,typename Dst,typename Op> Op static_transform(const CB1&, CB2&,Dst&,Op);
  138. template <typename CB1,typename CB2,typename Dst,typename Op> Op static_transform( CB1&,const CB2&,Dst&,Op);
  139. template <typename CB1,typename CB2,typename Dst,typename Op> Op static_transform(const CB1&,const CB2&,Dst&,Op);
  140. // Equivalents to std::for_each
  141. template <typename CB1, typename Op> Op static_for_each( CB1&,Op);
  142. template <typename CB1, typename Op> Op static_for_each(const CB1&,Op);
  143. template <typename CB1,typename CB2, typename Op> Op static_for_each( CB1&, CB2&,Op);
  144. template <typename CB1,typename CB2, typename Op> Op static_for_each( CB1&,const CB2&,Op);
  145. template <typename CB1,typename CB2, typename Op> Op static_for_each(const CB1&, CB2&,Op);
  146. template <typename CB1,typename CB2, typename Op> Op static_for_each(const CB1&,const CB2&,Op);
  147. template <typename CB1,typename CB2,typename CB3,typename Op> Op static_for_each( CB1&, CB2&, CB3&,Op);
  148. template <typename CB1,typename CB2,typename CB3,typename Op> Op static_for_each( CB1&, CB2&,const CB3&,Op);
  149. template <typename CB1,typename CB2,typename CB3,typename Op> Op static_for_each( CB1&,const CB2&, CB3&,Op);
  150. template <typename CB1,typename CB2,typename CB3,typename Op> Op static_for_each( CB1&,const CB2&,const CB3&,Op);
  151. template <typename CB1,typename CB2,typename CB3,typename Op> Op static_for_each(const CB1&, CB2&, CB3&,Op);
  152. template <typename CB1,typename CB2,typename CB3,typename Op> Op static_for_each(const CB1&, CB2&,const CB3&,Op);
  153. template <typename CB1,typename CB2,typename CB3,typename Op> Op static_for_each(const CB1&,const CB2&, CB3&,Op);
  154. template <typename CB1,typename CB2,typename CB3,typename Op> Op static_for_each(const CB1&,const CB2&,const CB3&,Op);
  155. // The following algorithms are only defined for homogeneous color bases:
  156. // Equivalent to std::fill
  157. template <typename HCB, typename Element> void static_fill(HCB& p, const Element& v);
  158. // Equivalents to std::min_element and std::max_element
  159. template <typename HCB> typename element_const_reference_type<HCB>::type static_min(const HCB&);
  160. template <typename HCB> typename element_reference_type<HCB>::type static_min( HCB&);
  161. template <typename HCB> typename element_const_reference_type<HCB>::type static_max(const HCB&);
  162. template <typename HCB> typename element_reference_type<HCB>::type static_max( HCB&);
  163. These algorithms are designed after the corresponding STL algorithms, except
  164. that instead of ranges they take color bases and operate on their elements.
  165. In addition, they are implemented with a compile-time recursion (thus the
  166. prefix "static\_"). Finally, they pair the elements semantically instead of
  167. based on their physical order in memory.
  168. For example, here is the implementation of ``static_equal``:
  169. .. code-block:: cpp
  170. namespace detail
  171. {
  172. template <int K> struct element_recursion
  173. {
  174. template <typename P1,typename P2>
  175. static bool static_equal(const P1& p1, const P2& p2)
  176. {
  177. return element_recursion<K-1>::static_equal(p1,p2) &&
  178. semantic_at_c<K-1>(p1)==semantic_at_c<N-1>(p2);
  179. }
  180. };
  181. template <> struct element_recursion<0>
  182. {
  183. template <typename P1,typename P2>
  184. static bool static_equal(const P1&, const P2&) { return true; }
  185. };
  186. }
  187. template <typename P1,typename P2>
  188. bool static_equal(const P1& p1, const P2& p2)
  189. {
  190. gil_function_requires<ColorSpacesCompatibleConcept<P1::layout_t::color_space_t,P2::layout_t::color_space_t> >();
  191. return detail::element_recursion<size<P1>::value>::static_equal(p1,p2);
  192. }
  193. This algorithm is used when invoking ``operator==`` on two pixels, for
  194. example. By using semantic accessors we are properly comparing an RGB pixel to
  195. a BGR pixel. Notice also that all of the above algorithms taking more than one
  196. color base require that they all have the same color space.