1Color Base
2==========
3
4.. contents::
5   :local:
6   :depth: 2
7
8Overview
9--------
10
11A color base is a container of color elements. The most common use of color
12base is in the implementation of a pixel, in which case the color elements are
13channel values. The color base concept, however, can be used in other
14scenarios. For example, a planar pixel has channels that are not contiguous in
15memory. Its reference is a proxy class that uses a color base whose elements
16are channel references. Its iterator uses a color base whose elements are
17channel iterators.
18
19Color 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
90A color base must have an associated layout (which consists of a color space,
91as well as an ordering of the channels). There are two ways to index the
92elements of a color base: A physical index corresponds to the way they are
93ordered in memory, and a semantic index corresponds to the way the elements
94are ordered in their color space. For example, in the RGB color space the
95elements are ordered as ``{red_t, green_t, blue_t}``. For a color base with
96a BGR layout, the first element in physical ordering is the blue element,
97whereas the first semantic element is the red one.  Models of
98``ColorBaseConcept`` are required to provide the ``at_c<K>(ColorBase)``
99function, which allows for accessing the elements based on their physical
100order. GIL provides a ``semantic_at_c<K>(ColorBase)`` function (described
101later) which can operate on any model of ColorBaseConcept and returns the
102corresponding semantic element.
103
104Two color bases are *compatible* if they have the same color space and their
105elements (paired semantically) are convertible to each other.
106
107Models
108------
109
110GIL provides a model for a homogeneous color base (a color base whose elements
111all 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
121It is used in the implementation of GIL's pixel, planar pixel reference and
122planar pixel iterator. Another model of ``ColorBaseConcept`` is
123``packed_pixel`` - it is a pixel whose channels are bit ranges.
124
125See the :doc:`pixel` section for more.
126
127Algorithms
128----------
129
130GIL provides the following functions and metafunctions operating on color
131bases:
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
163GIL also provides the following algorithms which operate on color bases.
164Note 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
207These algorithms are designed after the corresponding STL algorithms, except
208that instead of ranges they take color bases and operate on their elements.
209In addition, they are implemented with a compile-time recursion (thus the
210prefix "static\_"). Finally, they pair the elements semantically instead of
211based on their physical order in memory.
212
213For 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
242This algorithm is used when invoking ``operator==`` on two pixels, for
243example. By using semantic accessors we are properly comparing an RGB pixel to
244a BGR pixel. Notice also that all of the above algorithms taking more than one
245color base require that they all have the same color space.
246