Index: channel.hpp =================================================================== --- channel.hpp (revision 66245) +++ channel.hpp (working copy) @@ -27,6 +27,7 @@ #include #include #include +#include #include "gil_config.hpp" #include "utilities.hpp" @@ -669,4 +670,30 @@ } +// \brief Determines the fundamental type which may be used, e.g., to cast from larger to smaller channel types. +namespace boost { namespace gil { +template +struct base_channel_type_impl { typedef T type; }; + +template +struct base_channel_type_impl > +{ typedef typename packed_channel_value::integer_t type; }; + +template +struct base_channel_type_impl > +{ typedef typename packed_channel_reference::integer_t type; }; + +template +struct base_channel_type_impl > +{ typedef typename packed_dynamic_channel_reference::integer_t type; }; + +template +struct base_channel_type_impl > +{ typedef ChannelValue type; }; + +template +struct base_channel_type : base_channel_type_impl::type > {}; + +} } //namespace boost::gil + #endif Index: channel_algorithm.hpp =================================================================== --- channel_algorithm.hpp (revision 66245) +++ channel_algorithm.hpp (working copy) @@ -227,7 +227,9 @@ struct channel_converter_unsigned_integral_nondivisible { DstChannelV operator()(SrcChannelV src) const { typedef typename detail::min_fast_uint::value+unsigned_integral_num_bits::value>::type integer_t; - return DstChannelV(integer_t(src * unsigned_integral_max_value::value) / unsigned_integral_max_value::value); + typedef typename base_channel_type::type dest_t; + return DstChannelV(static_cast( + (src * integer_t(unsigned_integral_max_value::value)) / unsigned_integral_max_value::value)); } }; @@ -239,7 +241,7 @@ struct channel_converter_unsigned_integral_nondivisible { DstChannelV operator()(SrcChannelV src) const { static const double mul = unsigned_integral_max_value::value / double(unsigned_integral_max_value::value); - return DstChannelV(src * mul); + return DstChannelV(static_cast::type>(src * mul)); } }; @@ -250,8 +252,8 @@ struct channel_converter_unsigned_integral_nondivisible { DstChannelV operator()(SrcChannelV src) const { - typedef typename detail::unsigned_integral_max_value< SrcChannelV >::value_type src_integer_t; - typedef typename detail::unsigned_integral_max_value< DstChannelV >::value_type dst_integer_t; + typedef typename base_channel_type< SrcChannelV >::type src_integer_t; + typedef typename base_channel_type< DstChannelV >::type dst_integer_t; static const double div = unsigned_integral_max_value::value / static_cast< double >( unsigned_integral_max_value::value ); @@ -410,7 +412,7 @@ template struct channel_multiplier_unsigned : public std::binary_function { ChannelValue operator()(ChannelValue a, ChannelValue b) const { - return ChannelValue(a / double(channel_traits::max_value()) * b); + return ChannelValue(static_cast::type>(a / double(channel_traits::max_value()) * b)); } };