Color Base ========== .. contents:: :local: :depth: 2 Overview -------- A color base is a container of color elements. The most common use of color base is in the implementation of a pixel, in which case the color elements are channel values. The color base concept, however, can be used in other scenarios. For example, a planar pixel has channels that are not contiguous in memory. Its reference is a proxy class that uses a color base whose elements are channel references. Its iterator uses a color base whose elements are channel iterators. Color base models must satisfy the following concepts: .. code-block:: cpp concept ColorBaseConcept : CopyConstructible, EqualityComparable { // a GIL layout (the color space and element permutation) typename layout_t; // The type of K-th element template struct kth_element_type; where Metafunction; // The result of at_c template struct kth_element_const_reference_type; where Metafunction; template kth_element_const_reference_type::type at_c(T); template where { ColorBasesCompatibleConcept } T::T(T2); template where { ColorBasesCompatibleConcept } bool operator==(const T&, const T2&); template where { ColorBasesCompatibleConcept } bool operator!=(const T&, const T2&); }; concept MutableColorBaseConcept : Assignable, Swappable { template struct kth_element_reference_type; where Metafunction; template kth_element_reference_type::type at_c(T); template where { ColorBasesCompatibleConcept } T& operator=(T&, const T2&); }; concept ColorBaseValueConcept : MutableColorBaseConcept, Regular { }; concept HomogeneousColorBaseConcept { // For all K in [0 ... size::value-1): // where SameType::type, kth_element_type::type>; kth_element_const_reference_type<0>::type dynamic_at_c(const CB&, std::size_t n) const; }; concept MutableHomogeneousColorBaseConcept : HomogeneousColorBaseConcept { kth_element_reference_type<0>::type dynamic_at_c(const CB&, std::size_t n); }; concept HomogeneousColorBaseValueConcept : MutableHomogeneousColorBaseConcept, Regular { }; concept ColorBasesCompatibleConcept { where SameType; // also, for all K in [0 ... size::value): // where Convertible::type, kth_semantic_element_type::type>; // where Convertible::type, kth_semantic_element_type::type>; }; A color base must have an associated layout (which consists of a color space, as well as an ordering of the channels). There are two ways to index the elements of a color base: A physical index corresponds to the way they are ordered in memory, and a semantic index corresponds to the way the elements are ordered in their color space. For example, in the RGB color space the elements are ordered as ``{red_t, green_t, blue_t}``. For a color base with a BGR layout, the first element in physical ordering is the blue element, whereas the first semantic element is the red one. Models of ``ColorBaseConcept`` are required to provide the ``at_c(ColorBase)`` function, which allows for accessing the elements based on their physical order. GIL provides a ``semantic_at_c(ColorBase)`` function (described later) which can operate on any model of ColorBaseConcept and returns the corresponding semantic element. Two color bases are *compatible* if they have the same color space and their elements (paired semantically) are convertible to each other. Models ------ GIL provides a model for a homogeneous color base (a color base whose elements all have the same type). .. code-block:: cpp namespace detail { template struct homogeneous_color_base; } It is used in the implementation of GIL's pixel, planar pixel reference and planar pixel iterator. Another model of ``ColorBaseConcept`` is ``packed_pixel`` - it is a pixel whose channels are bit ranges. See the :doc:`pixel` section for more. Algorithms ---------- GIL provides the following functions and metafunctions operating on color bases: .. code-block:: cpp // Metafunction returning an mpl::int_ equal to the number of elements in the color base template struct size; // Returns the type of the return value of semantic_at_c(color_base) template struct kth_semantic_element_reference_type; template struct kth_semantic_element_const_reference_type; // Returns a reference to the element with K-th semantic index. template typename kth_semantic_element_reference_type::type semantic_at_c(ColorBase& p) template typename kth_semantic_element_const_reference_type::type semantic_at_c(const ColorBase& p) // Returns the type of the return value of get_color(color_base) template struct color_reference_t; template struct color_const_reference_t; // Returns a reference to the element corresponding to the given color template typename color_reference_t::type get_color(ColorBase& cb, Color=Color()); template typename color_const_reference_t::type get_color(const ColorBase& cb, Color=Color()); // Returns the element type of the color base. Defined for homogeneous color bases only template struct element_type; template struct element_reference_type; template struct element_const_reference_type; GIL also provides the following algorithms which operate on color bases. Note that they all pair the elements semantically: .. code-block:: cpp // Equivalents to std::equal, std::copy, std::fill, std::generate template bool static_equal(const CB1& p1, const CB2& p2); template void static_copy(const Src& src, Dst& dst); template void static_generate(CB& dst,Op op); // Equivalents to std::transform template Op static_transform( CB&,Dst&,Op); template Op static_transform(const CB&,Dst&,Op); template Op static_transform( CB1&, CB2&,Dst&,Op); template Op static_transform(const CB1&, CB2&,Dst&,Op); template Op static_transform( CB1&,const CB2&,Dst&,Op); template Op static_transform(const CB1&,const CB2&,Dst&,Op); // Equivalents to std::for_each template Op static_for_each( CB1&,Op); template Op static_for_each(const CB1&,Op); template Op static_for_each( CB1&, CB2&,Op); template Op static_for_each( CB1&,const CB2&,Op); template Op static_for_each(const CB1&, CB2&,Op); template Op static_for_each(const CB1&,const CB2&,Op); template Op static_for_each( CB1&, CB2&, CB3&,Op); template Op static_for_each( CB1&, CB2&,const CB3&,Op); template Op static_for_each( CB1&,const CB2&, CB3&,Op); template Op static_for_each( CB1&,const CB2&,const CB3&,Op); template Op static_for_each(const CB1&, CB2&, CB3&,Op); template Op static_for_each(const CB1&, CB2&,const CB3&,Op); template Op static_for_each(const CB1&,const CB2&, CB3&,Op); template Op static_for_each(const CB1&,const CB2&,const CB3&,Op); // The following algorithms are only defined for homogeneous color bases: // Equivalent to std::fill template void static_fill(HCB& p, const Element& v); // Equivalents to std::min_element and std::max_element template typename element_const_reference_type::type static_min(const HCB&); template typename element_reference_type::type static_min( HCB&); template typename element_const_reference_type::type static_max(const HCB&); template typename element_reference_type::type static_max( HCB&); These algorithms are designed after the corresponding STL algorithms, except that instead of ranges they take color bases and operate on their elements. In addition, they are implemented with a compile-time recursion (thus the prefix "static\_"). Finally, they pair the elements semantically instead of based on their physical order in memory. For example, here is the implementation of ``static_equal``: .. code-block:: cpp namespace detail { template struct element_recursion { template static bool static_equal(const P1& p1, const P2& p2) { return element_recursion::static_equal(p1,p2) && semantic_at_c(p1)==semantic_at_c(p2); } }; template <> struct element_recursion<0> { template static bool static_equal(const P1&, const P2&) { return true; } }; } template bool static_equal(const P1& p1, const P2& p2) { gil_function_requires >(); return detail::element_recursion::value>::static_equal(p1,p2); } This algorithm is used when invoking ``operator==`` on two pixels, for example. By using semantic accessors we are properly comparing an RGB pixel to a BGR pixel. Notice also that all of the above algorithms taking more than one color base require that they all have the same color space.