300 lines
8.5 KiB
C++
300 lines
8.5 KiB
C++
//
|
|
// 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_PIXEL_HPP
|
|
#define BOOST_GIL_CONCEPTS_PIXEL_HPP
|
|
|
|
#include <boost/gil/concepts/basic.hpp>
|
|
#include <boost/gil/concepts/channel.hpp>
|
|
#include <boost/gil/concepts/color.hpp>
|
|
#include <boost/gil/concepts/color_base.hpp>
|
|
#include <boost/gil/concepts/concept_check.hpp>
|
|
#include <boost/gil/concepts/fwd.hpp>
|
|
#include <boost/gil/concepts/pixel_based.hpp>
|
|
#include <boost/gil/concepts/detail/type_traits.hpp>
|
|
#include <boost/gil/detail/mp11.hpp>
|
|
|
|
#include <cstddef>
|
|
#include <type_traits>
|
|
|
|
#if defined(BOOST_CLANG)
|
|
#pragma clang diagnostic push
|
|
#pragma clang diagnostic ignored "-Wunknown-pragmas"
|
|
#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 {
|
|
|
|
/// \brief Pixel concept - A color base whose elements are channels
|
|
/// \ingroup PixelConcept
|
|
/// \code
|
|
/// concept PixelConcept<typename P> : ColorBaseConcept<P>, PixelBasedConcept<P>
|
|
/// {
|
|
/// where is_pixel<P>::value == true;
|
|
/// // where for each K [0..size<P>::value - 1]:
|
|
/// // ChannelConcept<kth_element_type<P, K>>;
|
|
///
|
|
/// typename P::value_type;
|
|
/// where PixelValueConcept<value_type>;
|
|
/// typename P::reference;
|
|
/// where PixelConcept<reference>;
|
|
/// typename P::const_reference;
|
|
/// where PixelConcept<const_reference>;
|
|
/// static const bool P::is_mutable;
|
|
///
|
|
/// template <PixelConcept P2> where { PixelConcept<P, P2> }
|
|
/// P::P(P2);
|
|
/// template <PixelConcept P2> where { PixelConcept<P, P2> }
|
|
/// bool operator==(const P&, const P2&);
|
|
/// template <PixelConcept P2> where { PixelConcept<P, P2> }
|
|
/// bool operator!=(const P&, const P2&);
|
|
/// };
|
|
/// \endcode
|
|
template <typename P>
|
|
struct PixelConcept
|
|
{
|
|
void constraints()
|
|
{
|
|
gil_function_requires<ColorBaseConcept<P>>();
|
|
gil_function_requires<PixelBasedConcept<P>>();
|
|
|
|
static_assert(is_pixel<P>::value, "");
|
|
static const bool is_mutable = P::is_mutable;
|
|
ignore_unused_variable_warning(is_mutable);
|
|
|
|
using value_type = typename P::value_type;
|
|
// TODO: Is the cyclic dependency intentional? --mloskot
|
|
// gil_function_requires<PixelValueConcept<value_type>>();
|
|
|
|
using reference = typename P::reference;
|
|
gil_function_requires<PixelConcept
|
|
<
|
|
typename detail::remove_const_and_reference<reference>::type
|
|
>>();
|
|
|
|
using const_reference = typename P::const_reference;
|
|
gil_function_requires<PixelConcept
|
|
<
|
|
typename detail::remove_const_and_reference<const_reference>::type
|
|
>>();
|
|
}
|
|
};
|
|
|
|
/// \brief Pixel concept that allows for changing its channels
|
|
/// \ingroup PixelConcept
|
|
/// \code
|
|
/// concept MutablePixelConcept<PixelConcept P> : MutableColorBaseConcept<P>
|
|
/// {
|
|
/// where is_mutable==true;
|
|
/// };
|
|
/// \endcode
|
|
template <typename P>
|
|
struct MutablePixelConcept
|
|
{
|
|
void constraints()
|
|
{
|
|
gil_function_requires<PixelConcept<P>>();
|
|
static_assert(P::is_mutable, "");
|
|
}
|
|
};
|
|
|
|
/// \brief Homogeneous pixel concept
|
|
/// \ingroup PixelConcept
|
|
/// \code
|
|
/// concept HomogeneousPixelConcept<PixelConcept P>
|
|
/// : HomogeneousColorBaseConcept<P>, HomogeneousPixelBasedConcept<P>
|
|
/// {
|
|
/// P::template element_const_reference_type<P>::type operator[](P p, std::size_t i) const
|
|
/// {
|
|
/// return dynamic_at_c(p,i);
|
|
/// }
|
|
/// };
|
|
/// \endcode
|
|
template <typename P>
|
|
struct HomogeneousPixelConcept
|
|
{
|
|
void constraints()
|
|
{
|
|
gil_function_requires<PixelConcept<P>>();
|
|
gil_function_requires<HomogeneousColorBaseConcept<P>>();
|
|
gil_function_requires<HomogeneousPixelBasedConcept<P>>();
|
|
p[0];
|
|
}
|
|
P p;
|
|
};
|
|
|
|
/// \brief Homogeneous pixel concept that allows for changing its channels
|
|
/// \ingroup PixelConcept
|
|
/// \code
|
|
/// concept MutableHomogeneousPixelConcept<HomogeneousPixelConcept P>
|
|
/// : MutableHomogeneousColorBaseConcept<P>
|
|
/// {
|
|
/// P::template element_reference_type<P>::type operator[](P p, std::size_t i)
|
|
/// {
|
|
/// return dynamic_at_c(p, i);
|
|
/// }
|
|
/// };
|
|
/// \endcode
|
|
template <typename P>
|
|
struct MutableHomogeneousPixelConcept
|
|
{
|
|
void constraints()
|
|
{
|
|
gil_function_requires<HomogeneousPixelConcept<P>>();
|
|
gil_function_requires<MutableHomogeneousColorBaseConcept<P>>();
|
|
p[0] = v;
|
|
v = p[0];
|
|
}
|
|
typename P::template element_type<P>::type v;
|
|
P p;
|
|
};
|
|
|
|
/// \brief Pixel concept that is a Regular type
|
|
/// \ingroup PixelConcept
|
|
/// \code
|
|
/// concept PixelValueConcept<PixelConcept P> : Regular<P>
|
|
/// {
|
|
/// where SameType<value_type,P>;
|
|
/// };
|
|
/// \endcode
|
|
template <typename P>
|
|
struct PixelValueConcept
|
|
{
|
|
void constraints()
|
|
{
|
|
gil_function_requires<PixelConcept<P>>();
|
|
gil_function_requires<Regular<P>>();
|
|
}
|
|
};
|
|
|
|
/// \brief Homogeneous pixel concept that is a Regular type
|
|
/// \ingroup PixelConcept
|
|
/// \code
|
|
/// concept HomogeneousPixelValueConcept<HomogeneousPixelConcept P> : Regular<P>
|
|
/// {
|
|
/// where SameType<value_type,P>;
|
|
/// };
|
|
/// \endcode
|
|
template <typename P>
|
|
struct HomogeneousPixelValueConcept
|
|
{
|
|
void constraints()
|
|
{
|
|
gil_function_requires<HomogeneousPixelConcept<P>>();
|
|
gil_function_requires<Regular<P>>();
|
|
static_assert(std::is_same<P, typename P::value_type>::value, "");
|
|
}
|
|
};
|
|
|
|
namespace detail {
|
|
|
|
template <typename P1, typename P2, int K>
|
|
struct channels_are_pairwise_compatible
|
|
: mp11::mp_and
|
|
<
|
|
channels_are_pairwise_compatible<P1, P2, K - 1>,
|
|
channels_are_compatible
|
|
<
|
|
typename kth_semantic_element_reference_type<P1, K>::type,
|
|
typename kth_semantic_element_reference_type<P2, K>::type
|
|
>
|
|
>
|
|
{
|
|
};
|
|
|
|
template <typename P1, typename P2>
|
|
struct channels_are_pairwise_compatible<P1, P2, -1> : std::true_type {};
|
|
|
|
} // namespace detail
|
|
|
|
/// \ingroup PixelAlgorithm
|
|
/// \brief Returns whether two pixels are compatible
|
|
/// Pixels are compatible if their channels and color space types are compatible.
|
|
/// Compatible pixels can be assigned and copy constructed from one another.
|
|
/// \tparam P1 Models PixelConcept
|
|
/// \tparam P2 Models PixelConcept
|
|
template <typename P1, typename P2>
|
|
struct pixels_are_compatible
|
|
: mp11::mp_and
|
|
<
|
|
typename color_spaces_are_compatible
|
|
<
|
|
typename color_space_type<P1>::type,
|
|
typename color_space_type<P2>::type
|
|
>::type,
|
|
detail::channels_are_pairwise_compatible
|
|
<
|
|
P1, P2, num_channels<P1>::value - 1
|
|
>
|
|
>
|
|
{
|
|
};
|
|
|
|
/// \ingroup PixelConcept
|
|
/// \brief Concept for pixel compatibility
|
|
/// Pixels are compatible if their channels and color space types are compatible.
|
|
/// Compatible pixels can be assigned and copy constructed from one another.
|
|
/// \tparam P1 Models PixelConcept
|
|
/// \tparam P2 Models PixelConcept
|
|
/// \code
|
|
/// concept PixelsCompatibleConcept<PixelConcept P1, PixelConcept P2>
|
|
/// : ColorBasesCompatibleConcept<P1,P2> {
|
|
/// // where for each K [0..size<P1>::value):
|
|
/// // ChannelsCompatibleConcept<kth_semantic_element_type<P1,K>::type, kth_semantic_element_type<P2,K>::type>;
|
|
/// };
|
|
/// \endcode
|
|
template <typename P1, typename P2>
|
|
struct PixelsCompatibleConcept
|
|
{
|
|
void constraints()
|
|
{
|
|
static_assert(pixels_are_compatible<P1, P2>::value, "");
|
|
}
|
|
};
|
|
|
|
/// \ingroup PixelConcept
|
|
/// \brief Pixel convertible concept
|
|
/// Convertibility is non-symmetric and implies that one pixel
|
|
/// can be converted to another, approximating the color.
|
|
/// Conversion is explicit and sometimes lossy.
|
|
/// \code
|
|
/// template <PixelConcept SrcPixel, MutablePixelConcept DstPixel>
|
|
/// concept PixelConvertibleConcept
|
|
/// {
|
|
/// void color_convert(const SrcPixel&, DstPixel&);
|
|
/// };
|
|
/// \endcode
|
|
template <typename SrcP, typename DstP>
|
|
struct PixelConvertibleConcept
|
|
{
|
|
void constraints()
|
|
{
|
|
gil_function_requires<PixelConcept<SrcP>>();
|
|
gil_function_requires<MutablePixelConcept<DstP>>();
|
|
color_convert(src, dst);
|
|
}
|
|
SrcP src;
|
|
DstP 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
|