update boost
This commit is contained in:
@@ -11,56 +11,81 @@
|
||||
#include <boost/gil/channel.hpp>
|
||||
#include <boost/gil/promote_integral.hpp>
|
||||
#include <boost/gil/typedefs.hpp>
|
||||
|
||||
#include <boost/mpl/less.hpp>
|
||||
#include <boost/mpl/integral_c.hpp>
|
||||
#include <boost/mpl/greater.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
#include <boost/gil/detail/is_channel_integral.hpp>
|
||||
#include <boost/gil/detail/mp11.hpp>
|
||||
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
namespace detail {
|
||||
|
||||
// some forward declarations
|
||||
template <typename SrcChannelV, typename DstChannelV, bool SrcIsIntegral, bool DstIsIntegral> struct channel_converter_unsigned_impl;
|
||||
template <typename SrcChannelV, typename DstChannelV, bool SrcIsGreater> struct channel_converter_unsigned_integral;
|
||||
template <typename SrcChannelV, typename DstChannelV, bool SrcLessThanDst, bool SrcDivisible> struct channel_converter_unsigned_integral_impl;
|
||||
template <typename SrcChannelV, typename DstChannelV, bool SrcLessThanDst, bool CannotFitInInteger> struct channel_converter_unsigned_integral_nondivisible;
|
||||
template <typename SrcChannelV, typename DstChannelV, bool SrcIsIntegral, bool DstIsIntegral>
|
||||
struct channel_converter_unsigned_impl;
|
||||
|
||||
template <typename SrcChannelV, typename DstChannelV, bool SrcIsGreater>
|
||||
struct channel_converter_unsigned_integral;
|
||||
|
||||
template <typename SrcChannelV, typename DstChannelV, bool SrcLessThanDst, bool SrcDivisible>
|
||||
struct channel_converter_unsigned_integral_impl;
|
||||
|
||||
template <typename SrcChannelV, typename DstChannelV, bool SrcLessThanDst, bool CannotFitInInteger>
|
||||
struct channel_converter_unsigned_integral_nondivisible;
|
||||
|
||||
//////////////////////////////////////
|
||||
//// unsigned_integral_max_value - given an unsigned integral channel type, returns its maximum value as an MPL integral constant
|
||||
//////////////////////////////////////
|
||||
|
||||
|
||||
template <typename UnsignedIntegralChannel>
|
||||
struct unsigned_integral_max_value : public mpl::integral_c<UnsignedIntegralChannel,std::numeric_limits<UnsignedIntegralChannel>::max()> {};
|
||||
|
||||
template <>
|
||||
struct unsigned_integral_max_value<uint8_t> : public mpl::integral_c<uint32_t,0xFF> {};
|
||||
template <>
|
||||
struct unsigned_integral_max_value<uint16_t> : public mpl::integral_c<uint32_t,0xFFFF> {};
|
||||
template <>
|
||||
struct unsigned_integral_max_value<uint32_t> : public mpl::integral_c<uintmax_t,0xFFFFFFFF> {};
|
||||
|
||||
|
||||
template <int K>
|
||||
struct unsigned_integral_max_value<packed_channel_value<K> >
|
||||
: public mpl::integral_c<typename packed_channel_value<K>::integer_t, (uint64_t(1)<<K)-1> {};
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////
|
||||
//// unsigned_integral_num_bits - given an unsigned integral channel type, returns the minimum number of bits needed to represent it
|
||||
//// unsigned_integral_max_value - given an unsigned integral channel type,
|
||||
//// returns its maximum value as an integral constant
|
||||
//////////////////////////////////////
|
||||
|
||||
template <typename UnsignedIntegralChannel>
|
||||
struct unsigned_integral_num_bits : public mpl::int_<sizeof(UnsignedIntegralChannel)*8> {};
|
||||
struct unsigned_integral_max_value
|
||||
: std::integral_constant
|
||||
<
|
||||
UnsignedIntegralChannel,
|
||||
(std::numeric_limits<UnsignedIntegralChannel>::max)()
|
||||
>
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct unsigned_integral_max_value<uint8_t>
|
||||
: std::integral_constant<uint32_t, 0xFF>
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct unsigned_integral_max_value<uint16_t>
|
||||
: std::integral_constant<uint32_t, 0xFFFF>
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct unsigned_integral_max_value<uint32_t>
|
||||
: std::integral_constant<uintmax_t, 0xFFFFFFFF>
|
||||
{};
|
||||
|
||||
template <int K>
|
||||
struct unsigned_integral_num_bits<packed_channel_value<K> >
|
||||
: public mpl::int_<K> {};
|
||||
struct unsigned_integral_max_value<packed_channel_value<K>>
|
||||
: std::integral_constant
|
||||
<
|
||||
typename packed_channel_value<K>::integer_t,
|
||||
(uint64_t(1)<<K)-1
|
||||
>
|
||||
{};
|
||||
|
||||
//////////////////////////////////////
|
||||
//// unsigned_integral_num_bits - given an unsigned integral channel type,
|
||||
//// returns the minimum number of bits needed to represent it
|
||||
//////////////////////////////////////
|
||||
|
||||
template <typename UnsignedIntegralChannel>
|
||||
struct unsigned_integral_num_bits
|
||||
: std::integral_constant<int, static_cast<int>(sizeof(UnsignedIntegralChannel) * 8)>
|
||||
{};
|
||||
|
||||
template <int K>
|
||||
struct unsigned_integral_num_bits<packed_channel_value<K>>
|
||||
: std::integral_constant<int, K>
|
||||
{};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
@@ -88,13 +113,11 @@ struct unsigned_integral_num_bits<packed_channel_value<K> >
|
||||
/// assert(dst_channel == 255); // max value goes to max value
|
||||
/// \endcode
|
||||
|
||||
|
||||
/**
|
||||
\defgroup ChannelConvertUnsignedAlgorithm channel_converter_unsigned
|
||||
\ingroup ChannelConvertAlgorithm
|
||||
\brief Convert one unsigned/floating point channel to another. Converts both the channel type and range
|
||||
@{
|
||||
*/
|
||||
///
|
||||
/// \defgroup ChannelConvertUnsignedAlgorithm channel_converter_unsigned
|
||||
/// \ingroup ChannelConvertAlgorithm
|
||||
/// \brief Convert one unsigned/floating point channel to another. Converts both the channel type and range
|
||||
/// @{
|
||||
|
||||
//////////////////////////////////////
|
||||
//// channel_converter_unsigned
|
||||
@@ -102,13 +125,18 @@ struct unsigned_integral_num_bits<packed_channel_value<K> >
|
||||
|
||||
template <typename SrcChannelV, typename DstChannelV> // Model ChannelValueConcept
|
||||
struct channel_converter_unsigned
|
||||
: public detail::channel_converter_unsigned_impl<SrcChannelV,DstChannelV,is_integral<SrcChannelV>::value,is_integral<DstChannelV>::value> {};
|
||||
|
||||
: detail::channel_converter_unsigned_impl
|
||||
<
|
||||
SrcChannelV,
|
||||
DstChannelV,
|
||||
detail::is_channel_integral<SrcChannelV>::value,
|
||||
detail::is_channel_integral<DstChannelV>::value
|
||||
>
|
||||
{};
|
||||
|
||||
/// \brief Converting a channel to itself - identity operation
|
||||
template <typename T> struct channel_converter_unsigned<T,T> : public detail::identity<T> {};
|
||||
|
||||
|
||||
namespace detail {
|
||||
|
||||
//////////////////////////////////////
|
||||
@@ -120,23 +148,34 @@ template <typename SrcChannelV, typename DstChannelV, bool SrcIsIntegral, bool D
|
||||
struct channel_converter_unsigned_impl {
|
||||
using argument_type = SrcChannelV;
|
||||
using result_type = DstChannelV;
|
||||
DstChannelV operator()(SrcChannelV src) const {
|
||||
auto operator()(SrcChannelV src) const -> DstChannelV
|
||||
{
|
||||
return DstChannelV(channel_traits<DstChannelV>::min_value() +
|
||||
(src - channel_traits<SrcChannelV>::min_value()) / channel_range<SrcChannelV>() * channel_range<DstChannelV>());
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename C>
|
||||
static double channel_range() {
|
||||
static auto channel_range() -> double
|
||||
{
|
||||
return double(channel_traits<C>::max_value()) - double(channel_traits<C>::min_value());
|
||||
}
|
||||
};
|
||||
|
||||
// When both the source and the destination are integral channels, perform a faster conversion
|
||||
template <typename SrcChannelV, typename DstChannelV>
|
||||
struct channel_converter_unsigned_impl<SrcChannelV,DstChannelV,true,true>
|
||||
: public channel_converter_unsigned_integral<SrcChannelV,DstChannelV,
|
||||
mpl::less<unsigned_integral_max_value<SrcChannelV>,unsigned_integral_max_value<DstChannelV> >::value > {};
|
||||
|
||||
struct channel_converter_unsigned_impl<SrcChannelV, DstChannelV, true, true>
|
||||
: channel_converter_unsigned_integral
|
||||
<
|
||||
SrcChannelV,
|
||||
DstChannelV,
|
||||
mp11::mp_less
|
||||
<
|
||||
unsigned_integral_max_value<SrcChannelV>,
|
||||
unsigned_integral_max_value<DstChannelV>
|
||||
>::value
|
||||
>
|
||||
{};
|
||||
|
||||
//////////////////////////////////////
|
||||
//// channel_converter_unsigned_integral
|
||||
@@ -162,7 +201,8 @@ struct channel_converter_unsigned_integral<SrcChannelV,DstChannelV,false>
|
||||
// and the dst max value is divisible by the src max value
|
||||
template <typename SrcChannelV, typename DstChannelV>
|
||||
struct channel_converter_unsigned_integral_impl<SrcChannelV,DstChannelV,true,true> {
|
||||
DstChannelV operator()(SrcChannelV src) const {
|
||||
auto operator()(SrcChannelV src) const -> DstChannelV
|
||||
{
|
||||
using integer_t = typename unsigned_integral_max_value<DstChannelV>::value_type;
|
||||
static const integer_t mul = unsigned_integral_max_value<DstChannelV>::value / unsigned_integral_max_value<SrcChannelV>::value;
|
||||
return DstChannelV(src * mul);
|
||||
@@ -174,7 +214,8 @@ struct channel_converter_unsigned_integral_impl<SrcChannelV,DstChannelV,true,tru
|
||||
// and the src max value is divisible by the dst max value
|
||||
template <typename SrcChannelV, typename DstChannelV>
|
||||
struct channel_converter_unsigned_integral_impl<SrcChannelV,DstChannelV,false,true> {
|
||||
DstChannelV operator()(SrcChannelV src) const {
|
||||
auto operator()(SrcChannelV src) const -> DstChannelV
|
||||
{
|
||||
using integer_t = typename unsigned_integral_max_value<SrcChannelV>::value_type;
|
||||
static const integer_t div = unsigned_integral_max_value<SrcChannelV>::value / unsigned_integral_max_value<DstChannelV>::value;
|
||||
static const integer_t div2 = div/2;
|
||||
@@ -185,7 +226,8 @@ struct channel_converter_unsigned_integral_impl<SrcChannelV,DstChannelV,false,tr
|
||||
// Prevent overflow for the largest integral type
|
||||
template <typename DstChannelV>
|
||||
struct channel_converter_unsigned_integral_impl<uintmax_t,DstChannelV,false,true> {
|
||||
DstChannelV operator()(uintmax_t src) const {
|
||||
auto operator()(uintmax_t src) const -> DstChannelV
|
||||
{
|
||||
static const uintmax_t div = unsigned_integral_max_value<uint32_t>::value / unsigned_integral_max_value<DstChannelV>::value;
|
||||
static const uintmax_t div2 = div/2;
|
||||
if (src > unsigned_integral_max_value<uintmax_t>::value - div2)
|
||||
@@ -198,23 +240,37 @@ struct channel_converter_unsigned_integral_impl<uintmax_t,DstChannelV,false,true
|
||||
// and the dst max value is not divisible by the src max value
|
||||
// See if you can represent the expression (src * dst_max) / src_max in integral form
|
||||
template <typename SrcChannelV, typename DstChannelV, bool SrcLessThanDst>
|
||||
struct channel_converter_unsigned_integral_impl<SrcChannelV,DstChannelV,SrcLessThanDst,false>
|
||||
: public channel_converter_unsigned_integral_nondivisible<SrcChannelV,DstChannelV,SrcLessThanDst,
|
||||
mpl::greater<
|
||||
mpl::plus<unsigned_integral_num_bits<SrcChannelV>,unsigned_integral_num_bits<DstChannelV> >,
|
||||
unsigned_integral_num_bits<uintmax_t>
|
||||
>::value> {};
|
||||
|
||||
struct channel_converter_unsigned_integral_impl<SrcChannelV, DstChannelV, SrcLessThanDst, false>
|
||||
: channel_converter_unsigned_integral_nondivisible
|
||||
<
|
||||
SrcChannelV,
|
||||
DstChannelV,
|
||||
SrcLessThanDst,
|
||||
mp11::mp_less
|
||||
<
|
||||
unsigned_integral_num_bits<uintmax_t>,
|
||||
mp11::mp_plus
|
||||
<
|
||||
unsigned_integral_num_bits<SrcChannelV>,
|
||||
unsigned_integral_num_bits<DstChannelV>
|
||||
>
|
||||
>::value
|
||||
>
|
||||
{};
|
||||
|
||||
// Both source and destination are unsigned integral channels,
|
||||
// the src max value is less than the dst max value,
|
||||
// and the dst max value is not divisible by the src max value
|
||||
// The expression (src * dst_max) / src_max fits in an integer
|
||||
template <typename SrcChannelV, typename DstChannelV>
|
||||
struct channel_converter_unsigned_integral_nondivisible<SrcChannelV,DstChannelV,true,false> {
|
||||
DstChannelV operator()(SrcChannelV src) const {
|
||||
struct channel_converter_unsigned_integral_nondivisible<SrcChannelV, DstChannelV, true, false>
|
||||
{
|
||||
auto operator()(SrcChannelV src) const -> DstChannelV
|
||||
{
|
||||
using dest_t = typename base_channel_type<DstChannelV>::type;
|
||||
return DstChannelV(static_cast<dest_t>( src * unsigned_integral_max_value<DstChannelV>::value) / unsigned_integral_max_value<SrcChannelV>::value);
|
||||
return DstChannelV(
|
||||
static_cast<dest_t>(src * unsigned_integral_max_value<DstChannelV>::value)
|
||||
/ unsigned_integral_max_value<SrcChannelV>::value);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -223,9 +279,13 @@ struct channel_converter_unsigned_integral_nondivisible<SrcChannelV,DstChannelV,
|
||||
// and the dst max value is not divisible by the src max value
|
||||
// The expression (src * dst_max) / src_max cannot fit in an integer (overflows). Use a double
|
||||
template <typename SrcChannelV, typename DstChannelV>
|
||||
struct channel_converter_unsigned_integral_nondivisible<SrcChannelV,DstChannelV,true,true> {
|
||||
DstChannelV operator()(SrcChannelV src) const {
|
||||
static const double mul = unsigned_integral_max_value<DstChannelV>::value / double(unsigned_integral_max_value<SrcChannelV>::value);
|
||||
struct channel_converter_unsigned_integral_nondivisible<SrcChannelV, DstChannelV, true, true>
|
||||
{
|
||||
auto operator()(SrcChannelV src) const -> DstChannelV
|
||||
{
|
||||
static const double mul
|
||||
= unsigned_integral_max_value<DstChannelV>::value
|
||||
/ double(unsigned_integral_max_value<SrcChannelV>::value);
|
||||
return DstChannelV(src * mul);
|
||||
}
|
||||
};
|
||||
@@ -234,9 +294,10 @@ struct channel_converter_unsigned_integral_nondivisible<SrcChannelV,DstChannelV,
|
||||
// the dst max value is less than (or equal to) the src max value,
|
||||
// and the src max value is not divisible by the dst max value
|
||||
template <typename SrcChannelV, typename DstChannelV, bool CannotFit>
|
||||
struct channel_converter_unsigned_integral_nondivisible<SrcChannelV,DstChannelV,false,CannotFit> {
|
||||
DstChannelV operator()(SrcChannelV src) const {
|
||||
|
||||
struct channel_converter_unsigned_integral_nondivisible<SrcChannelV,DstChannelV,false,CannotFit>
|
||||
{
|
||||
auto operator()(SrcChannelV src) const -> DstChannelV
|
||||
{
|
||||
using src_integer_t = typename detail::unsigned_integral_max_value<SrcChannelV>::value_type;
|
||||
using dst_integer_t = typename detail::unsigned_integral_max_value<DstChannelV>::value_type;
|
||||
|
||||
@@ -258,7 +319,7 @@ struct channel_converter_unsigned_integral_nondivisible<SrcChannelV,DstChannelV,
|
||||
template <typename DstChannelV> struct channel_converter_unsigned<float32_t,DstChannelV> {
|
||||
using argument_type = float32_t;
|
||||
using result_type = DstChannelV;
|
||||
DstChannelV operator()(float32_t x) const
|
||||
auto operator()(float32_t x) const -> DstChannelV
|
||||
{
|
||||
using dst_integer_t = typename detail::unsigned_integral_max_value<DstChannelV>::value_type;
|
||||
return DstChannelV( static_cast< dst_integer_t >(x*channel_traits<DstChannelV>::max_value()+0.5f ));
|
||||
@@ -268,13 +329,13 @@ template <typename DstChannelV> struct channel_converter_unsigned<float32_t,DstC
|
||||
template <typename SrcChannelV> struct channel_converter_unsigned<SrcChannelV,float32_t> {
|
||||
using argument_type = float32_t;
|
||||
using result_type = SrcChannelV;
|
||||
float32_t operator()(SrcChannelV x) const { return float32_t(x/float(channel_traits<SrcChannelV>::max_value())); }
|
||||
auto operator()(SrcChannelV x) const -> float32_t { return float32_t(x/float(channel_traits<SrcChannelV>::max_value())); }
|
||||
};
|
||||
|
||||
template <> struct channel_converter_unsigned<float32_t,float32_t> {
|
||||
using argument_type = float32_t;
|
||||
using result_type = float32_t;
|
||||
float32_t operator()(float32_t x) const { return x; }
|
||||
auto operator()(float32_t x) const -> float32_t { return x; }
|
||||
};
|
||||
|
||||
|
||||
@@ -282,7 +343,8 @@ template <> struct channel_converter_unsigned<float32_t,float32_t> {
|
||||
template <> struct channel_converter_unsigned<uint32_t,float32_t> {
|
||||
using argument_type = uint32_t;
|
||||
using result_type = float32_t;
|
||||
float32_t operator()(uint32_t x) const {
|
||||
auto operator()(uint32_t x) const -> float32_t
|
||||
{
|
||||
// unfortunately without an explicit check it is possible to get a round-off error. We must ensure that max_value of uint32_t matches max_value of float32_t
|
||||
if (x>=channel_traits<uint32_t>::max_value()) return channel_traits<float32_t>::max_value();
|
||||
return float(x) / float(channel_traits<uint32_t>::max_value());
|
||||
@@ -292,7 +354,8 @@ template <> struct channel_converter_unsigned<uint32_t,float32_t> {
|
||||
template <> struct channel_converter_unsigned<float32_t,uint32_t> {
|
||||
using argument_type = float32_t;
|
||||
using result_type = uint32_t;
|
||||
uint32_t operator()(float32_t x) const {
|
||||
auto operator()(float32_t x) const -> uint32_t
|
||||
{
|
||||
// unfortunately without an explicit check it is possible to get a round-off error. We must ensure that max_value of uint32_t matches max_value of float32_t
|
||||
if (x>=channel_traits<float32_t>::max_value())
|
||||
return channel_traits<uint32_t>::max_value();
|
||||
@@ -352,7 +415,7 @@ template <> struct channel_convert_from_unsigned<int8_t> {
|
||||
using argument_type = uint8_t;
|
||||
using result_type = int8_t;
|
||||
using type = int8_t;
|
||||
type operator()(uint8_t val) const {
|
||||
type operator()(uint8_t val) const {
|
||||
return static_cast<int8_t>(static_cast<int32_t>(val) - 128);
|
||||
}
|
||||
};
|
||||
@@ -383,7 +446,8 @@ template <typename SrcChannelV, typename DstChannelV> // Model ChannelValueConce
|
||||
struct channel_converter {
|
||||
using argument_type = SrcChannelV;
|
||||
using result_type = DstChannelV;
|
||||
DstChannelV operator()(const SrcChannelV& src) const {
|
||||
auto operator()(SrcChannelV const& src) const -> DstChannelV
|
||||
{
|
||||
using to_unsigned = detail::channel_convert_to_unsigned<SrcChannelV>;
|
||||
using from_unsigned = detail::channel_convert_from_unsigned<DstChannelV>;
|
||||
using converter_unsigned = channel_converter_unsigned<typename to_unsigned::result_type, typename from_unsigned::argument_type>;
|
||||
@@ -394,7 +458,8 @@ struct channel_converter {
|
||||
/// \ingroup ChannelConvertAlgorithm
|
||||
/// \brief Converting from one channel type to another.
|
||||
template <typename DstChannel, typename SrcChannel> // Model ChannelConcept (could be channel references)
|
||||
inline typename channel_traits<DstChannel>::value_type channel_convert(const SrcChannel& src) {
|
||||
inline auto channel_convert(SrcChannel const& src) -> typename channel_traits<DstChannel>::value_type
|
||||
{
|
||||
return channel_converter<typename channel_traits<SrcChannel>::value_type,
|
||||
typename channel_traits<DstChannel>::value_type>()(src);
|
||||
}
|
||||
@@ -405,17 +470,26 @@ inline typename channel_traits<DstChannel>::value_type channel_convert(const Src
|
||||
/// on heterogeneous pixels.
|
||||
struct default_channel_converter {
|
||||
template <typename Ch1, typename Ch2>
|
||||
void operator()(const Ch1& src, Ch2& dst) const {
|
||||
void operator()(Ch1 const& src, Ch2& dst) const
|
||||
{
|
||||
dst=channel_convert<Ch2>(src);
|
||||
}
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
namespace detail
|
||||
{
|
||||
// fast integer division by 255
|
||||
inline uint32_t div255(uint32_t in) { uint32_t tmp=in+128; return (tmp + (tmp>>8))>>8; }
|
||||
inline auto div255(uint32_t in) -> uint32_t
|
||||
{
|
||||
uint32_t tmp = in + 128;
|
||||
return (tmp + (tmp >> 8)) >> 8;
|
||||
}
|
||||
|
||||
// fast integer divison by 32768
|
||||
inline uint32_t div32768(uint32_t in) { return (in+16384)>>15; }
|
||||
inline auto div32768(uint32_t in) -> uint32_t
|
||||
{
|
||||
return (in + 16384) >> 15;
|
||||
}
|
||||
}
|
||||
|
||||
/// \defgroup ChannelMultiplyAlgorithm channel_multiply
|
||||
@@ -437,7 +511,8 @@ struct channel_multiplier_unsigned {
|
||||
using first_argument_type = ChannelValue;
|
||||
using second_argument_type = ChannelValue;
|
||||
using result_type = ChannelValue;
|
||||
ChannelValue operator()(ChannelValue a, ChannelValue b) const {
|
||||
auto operator()(ChannelValue a, ChannelValue b) const -> ChannelValue
|
||||
{
|
||||
return ChannelValue(static_cast<typename base_channel_type<ChannelValue>::type>(a / double(channel_traits<ChannelValue>::max_value()) * b));
|
||||
}
|
||||
};
|
||||
@@ -447,7 +522,7 @@ template<> struct channel_multiplier_unsigned<uint8_t> {
|
||||
using first_argument_type = uint8_t;
|
||||
using second_argument_type = uint8_t;
|
||||
using result_type = uint8_t;
|
||||
uint8_t operator()(uint8_t a, uint8_t b) const { return uint8_t(detail::div255(uint32_t(a) * uint32_t(b))); }
|
||||
auto operator()(uint8_t a, uint8_t b) const -> uint8_t { return uint8_t(detail::div255(uint32_t(a) * uint32_t(b))); }
|
||||
};
|
||||
|
||||
/// \brief Specialization of channel_multiply for 16-bit unsigned channels
|
||||
@@ -455,7 +530,7 @@ template<> struct channel_multiplier_unsigned<uint16_t> {
|
||||
using first_argument_type = uint16_t;
|
||||
using second_argument_type = uint16_t;
|
||||
using result_type = uint16_t;
|
||||
uint16_t operator()(uint16_t a, uint16_t b) const { return uint16_t((uint32_t(a) * uint32_t(b))/65535); }
|
||||
auto operator()(uint16_t a, uint16_t b) const -> uint16_t { return uint16_t((uint32_t(a) * uint32_t(b))/65535); }
|
||||
};
|
||||
|
||||
/// \brief Specialization of channel_multiply for float 0..1 channels
|
||||
@@ -463,7 +538,7 @@ template<> struct channel_multiplier_unsigned<float32_t> {
|
||||
using first_argument_type = float32_t;
|
||||
using second_argument_type = float32_t;
|
||||
using result_type = float32_t;
|
||||
float32_t operator()(float32_t a, float32_t b) const { return a*b; }
|
||||
auto operator()(float32_t a, float32_t b) const -> float32_t { return a*b; }
|
||||
};
|
||||
|
||||
/// \brief A function object to multiply two channels. result = a * b / max_value
|
||||
@@ -472,7 +547,8 @@ struct channel_multiplier {
|
||||
using first_argument_type = ChannelValue;
|
||||
using second_argument_type = ChannelValue;
|
||||
using result_type = ChannelValue;
|
||||
ChannelValue operator()(ChannelValue a, ChannelValue b) const {
|
||||
auto operator()(ChannelValue a, ChannelValue b) const -> ChannelValue
|
||||
{
|
||||
using to_unsigned = detail::channel_convert_to_unsigned<ChannelValue>;
|
||||
using from_unsigned = detail::channel_convert_from_unsigned<ChannelValue>;
|
||||
using multiplier_unsigned = channel_multiplier_unsigned<typename to_unsigned::result_type>;
|
||||
@@ -482,7 +558,8 @@ struct channel_multiplier {
|
||||
|
||||
/// \brief A function multiplying two channels. result = a * b / max_value
|
||||
template <typename Channel> // Models ChannelConcept (could be a channel reference)
|
||||
inline typename channel_traits<Channel>::value_type channel_multiply(Channel a, Channel b) {
|
||||
inline auto channel_multiply(Channel a, Channel b) -> typename channel_traits<Channel>::value_type
|
||||
{
|
||||
return channel_multiplier<typename channel_traits<Channel>::value_type>()(a,b);
|
||||
}
|
||||
/// @}
|
||||
@@ -502,8 +579,8 @@ inline typename channel_traits<Channel>::value_type channel_multiply(Channel a,
|
||||
/// \brief Default implementation. Provide overloads for performance
|
||||
/// \ingroup ChannelInvertAlgorithm channel_invert
|
||||
template <typename Channel> // Models ChannelConcept (could be a channel reference)
|
||||
inline typename channel_traits<Channel>::value_type channel_invert(Channel x) {
|
||||
|
||||
inline auto channel_invert(Channel x) -> typename channel_traits<Channel>::value_type
|
||||
{
|
||||
using base_t = typename base_channel_type<Channel>::type;
|
||||
using promoted_t = typename promote_integral<base_t>::type;
|
||||
promoted_t const promoted_x = x;
|
||||
@@ -514,6 +591,6 @@ inline typename channel_traits<Channel>::value_type channel_invert(Channel x) {
|
||||
return inverted_x;
|
||||
}
|
||||
|
||||
} } // namespace boost::gil
|
||||
}} // namespace boost::gil
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user