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