// // 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_CHANNEL_HPP #define BOOST_GIL_CONCEPTS_CHANNEL_HPP #include #include #include #include #include // std::swap #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 template struct channel_traits; template auto channel_convert(SrcT const& val) -> typename channel_traits::value_type; /// \ingroup ChannelConcept /// \brief A channel is the building block of a color. /// Color is defined as a mixture of primary colors and a channel defines /// the degree to which each primary color is used in the mixture. /// /// For example, in the RGB color space, using 8-bit unsigned channels, /// the color red is defined as [255 0 0], which means maximum of Red, /// and no Green and Blue. /// /// Built-in scalar types, such as \p int and \p float, are valid GIL channels. /// In more complex scenarios, channels may be represented as bit ranges or /// even individual bits. /// In such cases special classes are needed to represent the value and /// reference to a channel. /// /// Channels have a traits class, \p channel_traits, which defines their /// associated types as well as their operating ranges. /// /// \code /// concept ChannelConcept : EqualityComparable /// { /// typename value_type = T; // use channel_traits::value_type to access it /// typename reference = T&; // use channel_traits::reference to access it /// typename pointer = T*; // use channel_traits::pointer to access it /// typename const_reference = const T&; // use channel_traits::const_reference to access it /// typename const_pointer = const T*; // use channel_traits::const_pointer to access it /// static const bool is_mutable; // use channel_traits::is_mutable to access it /// /// static T min_value(); // use channel_traits::min_value to access it /// static T max_value(); // use channel_traits::min_value to access it /// }; /// \endcode template struct ChannelConcept { void constraints() { gil_function_requires>(); using v = typename channel_traits::value_type; using r = typename channel_traits::reference; using p = typename channel_traits::pointer; using cr = typename channel_traits::const_reference; using cp = typename channel_traits::const_pointer; channel_traits::min_value(); channel_traits::max_value(); } T c; }; namespace detail { /// \tparam T models ChannelConcept template struct ChannelIsMutableConcept { void constraints() { c1 = c2; using std::swap; swap(c1, c2); } T c1; T c2; }; } // namespace detail /// \brief A channel that allows for modifying its value /// \code /// concept MutableChannelConcept : Assignable, Swappable {}; /// \endcode /// \ingroup ChannelConcept template struct MutableChannelConcept { void constraints() { gil_function_requires>(); gil_function_requires>(); } }; /// \brief A channel that supports default construction. /// \code /// concept ChannelValueConcept : Regular {}; /// \endcode /// \ingroup ChannelConcept template struct ChannelValueConcept { void constraints() { gil_function_requires>(); gil_function_requires>(); } }; /// \brief Predicate metafunction returning whether two channels are compatible /// /// Channels are considered compatible if their value types /// (ignoring constness and references) are the same. /// /// Example: /// /// \code /// static_assert(channels_are_compatible::value, ""); /// \endcode /// \ingroup ChannelAlgorithm template // Models GIL Pixel struct channels_are_compatible : std::is_same < typename channel_traits::value_type, typename channel_traits::value_type > { }; /// \brief Channels are compatible if their associated value types (ignoring constness and references) are the same /// /// \code /// concept ChannelsCompatibleConcept /// { /// where SameType; /// }; /// \endcode /// \ingroup ChannelConcept template struct ChannelsCompatibleConcept { void constraints() { static_assert(channels_are_compatible::value, ""); } }; /// \brief A channel is convertible to another one if the \p channel_convert algorithm is defined for the two channels. /// /// Convertibility is non-symmetric and implies that one channel can be /// converted to another. Conversion is explicit and often lossy operation. /// /// concept ChannelConvertibleConcept /// { /// DstChannel channel_convert(const SrcChannel&); /// }; /// \endcode /// \ingroup ChannelConcept template struct ChannelConvertibleConcept { void constraints() { gil_function_requires>(); gil_function_requires>(); dst = channel_convert(src); ignore_unused_variable_warning(dst); } SrcChannel src; DstChannel dst; }; }} // 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