Index: channel.hpp
===================================================================
--- channel.hpp	(revision 66245)
+++ channel.hpp	(working copy)
@@ -27,6 +27,7 @@
 #include <limits>
 #include <cassert>
 #include <boost/cstdint.hpp>
+#include <boost/type_traits/remove_cv.hpp>
 #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 <typename T>
+struct base_channel_type_impl { typedef T type; };
+
+template <int N>
+struct base_channel_type_impl<packed_channel_value<N> >
+{ typedef typename packed_channel_value<N>::integer_t type; };
+
+template <typename B, int F, int N, bool M>
+struct base_channel_type_impl<packed_channel_reference<B, F, N, M> >
+{ typedef typename packed_channel_reference<B,F,N,M>::integer_t type; };
+
+template <typename B, int N, bool M>
+struct base_channel_type_impl<packed_dynamic_channel_reference<B, N, M> >
+{ typedef typename packed_dynamic_channel_reference<B,N,M>::integer_t type; };
+
+template <typename ChannelValue, typename MinV, typename MaxV>
+struct base_channel_type_impl<scoped_channel_value<ChannelValue, MinV, MaxV> >
+{ typedef ChannelValue type; };
+
+template <typename T>
+struct base_channel_type : base_channel_type_impl<typename remove_cv<T>::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<SrcChannelV,DstChannelV,true,false> {
     DstChannelV operator()(SrcChannelV src) const {
         typedef typename detail::min_fast_uint<unsigned_integral_num_bits<SrcChannelV>::value+unsigned_integral_num_bits<DstChannelV>::value>::type integer_t;
-        return DstChannelV(integer_t(src * unsigned_integral_max_value<DstChannelV>::value) / unsigned_integral_max_value<SrcChannelV>::value);
+        typedef typename base_channel_type<DstChannelV>::type dest_t;
+        return DstChannelV(static_cast<dest_t>(
+          integer_t(src * unsigned_integral_max_value<DstChannelV>::value) / unsigned_integral_max_value<SrcChannelV>::value));
     }
 };
 
@@ -250,8 +252,8 @@
 struct channel_converter_unsigned_integral_nondivisible<SrcChannelV,DstChannelV,false,CannotFit> {
     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<SrcChannelV>::value 
                                 / static_cast< double >( unsigned_integral_max_value<DstChannelV>::value );
@@ -410,7 +412,7 @@
 template <typename ChannelValue>
 struct channel_multiplier_unsigned : public std::binary_function<ChannelValue,ChannelValue,ChannelValue> {
     ChannelValue operator()(ChannelValue a, ChannelValue b) const {
-        return ChannelValue(a / double(channel_traits<ChannelValue>::max_value()) * b);
+        return ChannelValue(static_cast<typename base_channel_type<ChannelValue>::type>(a / double(channel_traits<ChannelValue>::max_value()) * b));
     }
 };
 
