// // Copyright 2005-2007 Adobe Systems Incorporated // // Distributed under the Boost Software License, Version 1.0 // See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt // #ifndef BOOST_GIL_CONCEPTS_COLOR_BASE_HPP #define BOOST_GIL_CONCEPTS_COLOR_BASE_HPP #include #include #include #include #include #include #if defined(BOOST_CLANG) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-local-typedefs" #endif #if defined(BOOST_GCC) && (BOOST_GCC >= 40900) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-local-typedefs" #endif namespace boost { namespace gil { // Forward declarations of at_c namespace detail { template struct homogeneous_color_base; } // namespace detail template auto at_c(detail::homogeneous_color_base& p) -> typename std::add_lvalue_reference::type; template auto at_c(detail::homogeneous_color_base const& p) -> typename std::add_lvalue_reference::type>::type; template struct packed_pixel; template auto at_c(packed_pixel& p) -> typename kth_element_reference_type, K>::type; template auto at_c(packed_pixel const& p) -> typename kth_element_const_reference_type, K>::type; template struct bit_aligned_pixel_reference; template inline auto at_c(bit_aligned_pixel_reference const& p) -> typename kth_element_reference_type < bit_aligned_pixel_reference, K >::type; // Forward declarations of semantic_at_c template auto semantic_at_c(ColorBase& p) -> typename std::enable_if < !std::is_const::value, typename kth_semantic_element_reference_type::type >::type; template auto semantic_at_c(ColorBase const& p) -> typename kth_semantic_element_const_reference_type::type; /// \ingroup ColorBaseConcept /// \brief A color base is a container of color elements (such as channels, channel references or channel pointers). /// /// 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. /// /// 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 \p ColorBaseConcept are required to provide the \p at_c(ColorBase) /// function, which allows for accessing the elements based on their physical order. /// GIL provides a \p semantic_at_c(ColorBase) function (described later) /// which can operate on any model of ColorBaseConcept and returns the corresponding /// semantic element. /// /// \code /// 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); /// /// // Copy-constructible and equality comparable with other compatible color bases /// template where { ColorBasesCompatibleConcept } /// T::T(T2); /// template where { ColorBasesCompatibleConcept } /// bool operator==(const T&, const T2&); /// template where { ColorBasesCompatibleConcept } /// bool operator!=(const T&, const T2&); /// }; /// \endcode template struct ColorBaseConcept { void constraints() { gil_function_requires>(); gil_function_requires>(); using color_space_t = typename ColorBase::layout_t::color_space_t; gil_function_requires>(); using channel_mapping_t = typename ColorBase::layout_t::channel_mapping_t; // TODO: channel_mapping_t must be an Boost.MP11-compatible random access sequence static const int num_elements = size::value; using TN = typename kth_element_type::type; using RN = typename kth_element_const_reference_type::type; RN r = gil::at_c(cb); boost::ignore_unused(r); // functions that work for every pixel (no need to require them) semantic_at_c<0>(cb); semantic_at_c(cb); // also static_max(cb), static_min(cb), static_fill(cb,value), // and all variations of static_for_each(), static_generate(), static_transform() } ColorBase cb; }; /// \ingroup ColorBaseConcept /// \brief Color base which allows for modifying its elements /// \code /// concept MutableColorBaseConcept : Assignable, Swappable /// { /// template /// struct kth_element_reference_type; where Metafunction; /// /// template /// kth_element_reference_type::type>::type at_c(T); /// /// template where { ColorBasesCompatibleConcept } /// T& operator=(T&, const T2&); /// }; /// \endcode template struct MutableColorBaseConcept { void constraints() { gil_function_requires>(); gil_function_requires>(); gil_function_requires>(); using R0 = typename kth_element_reference_type::type; R0 r = gil::at_c<0>(cb); gil::at_c<0>(cb) = r; } ColorBase cb; }; /// \ingroup ColorBaseConcept /// \brief Color base that also has a default-constructor. Refines Regular /// \code /// concept ColorBaseValueConcept : MutableColorBaseConcept, Regular /// { /// }; /// \endcode template struct ColorBaseValueConcept { void constraints() { gil_function_requires>(); gil_function_requires>(); } }; /// \ingroup ColorBaseConcept /// \brief Color base whose elements all have the same type /// \code /// concept HomogeneousColorBaseConcept /// { /// // For all K in [0 ... size::value-1): /// // where SameType::type, kth_element_type::type>; /// kth_element_const_reference_type::type dynamic_at_c(CB const&, std::size_t n) const; /// }; /// \endcode template struct HomogeneousColorBaseConcept { void constraints() { gil_function_requires>(); static const int num_elements = size::value; using T0 = typename kth_element_type::type; using TN = typename kth_element_type::type; static_assert(std::is_same::value, ""); // better than nothing using R0 = typename kth_element_const_reference_type::type; R0 r = dynamic_at_c(cb, 0); boost::ignore_unused(r); } ColorBase cb; }; /// \ingroup ColorBaseConcept /// \brief Homogeneous color base that allows for modifying its elements /// \code /// concept MutableHomogeneousColorBaseConcept /// : HomogeneousColorBaseConcept /// { /// kth_element_reference_type::type dynamic_at_c(CB&, std::size_t n); /// }; /// \endcode template struct MutableHomogeneousColorBaseConcept { void constraints() { gil_function_requires>(); gil_function_requires>(); using R0 = typename kth_element_reference_type::type; R0 r = dynamic_at_c(cb, 0); boost::ignore_unused(r); dynamic_at_c(cb, 0) = dynamic_at_c(cb, 0); } ColorBase cb; }; /// \ingroup ColorBaseConcept /// \brief Homogeneous color base that also has a default constructor. /// Refines Regular. /// /// \code /// concept HomogeneousColorBaseValueConcept /// : MutableHomogeneousColorBaseConcept, Regular /// { /// }; /// \endcode template struct HomogeneousColorBaseValueConcept { void constraints() { gil_function_requires>(); gil_function_requires>(); } }; /// \ingroup ColorBaseConcept /// \brief Two color bases are compatible if they have the same color space and their elements are compatible, semantic-pairwise. /// \code /// 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>; /// }; /// \endcode template struct ColorBasesCompatibleConcept { void constraints() { static_assert(std::is_same < typename ColorBase1::layout_t::color_space_t, typename ColorBase2::layout_t::color_space_t >::value, ""); // using e1 = typename kth_semantic_element_type::type; // using e2 = typename kth_semantic_element_type::type; // "e1 is convertible to e2" } }; }} // namespace boost::gil #if defined(BOOST_CLANG) #pragma clang diagnostic pop #endif #if defined(BOOST_GCC) && (BOOST_GCC >= 40900) #pragma GCC diagnostic pop #endif #endif