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