Boost logo

Boost Users :

Subject: Re: [Boost-users] [GIL] Adding base_channel_type metafunction
From: Christian Henning (chhenning_at_[hidden])
Date: 2010-11-07 16:57:31


Hi Nathan,

>
> Output with trunk:
> Value: 12632255
> Should be: 1073741823

There was already a bug in the code before I patched it. Basically the
static_cast to integer_t should have been applied to src only.

Please review my patch. The function is more verbose now but I thing
it's more clear.

Index: channel_algorithm.hpp
===================================================================
--- channel_algorithm.hpp (revision 66416)
+++ channel_algorithm.hpp (working copy)
@@ -226,8 +226,20 @@
 template <typename SrcChannelV, typename DstChannelV>
 struct channel_converter_unsigned_integral_nondivisible<SrcChannelV,DstChannelV,true,false>
{
     DstChannelV operator()(SrcChannelV src) const {
- typedef typename base_channel_type<DstChannelV>::type dest_t;
- return DstChannelV(static_cast<dest_t>( src *
unsigned_integral_max_value<DstChannelV>::value) /
unsigned_integral_max_value<SrcChannelV>::value);
+
+ // make sure the operation below doesn't overflow dst's
integeral data type.
+ // e.g. dst is 30bit and src is 8 bit can result in 38bit value
+ typedef typename detail::min_fast_uint<
unsigned_integral_num_bits< SrcChannelV >::value
+ +
unsigned_integral_num_bits< DstChannelV >::value
+ >::type integer_t;
+
+ typedef typename base_channel_type< DstChannelV >::type dest_t;
+
+ integer_t src_ = static_cast< integer_t >( src );
+ integer_t dst_max = unsigned_integral_max_value<DstChannelV>::value;
+ integer_t src_max = unsigned_integral_max_value<SrcChannelV>::value;
+
+ return static_cast< dest_t >( src_ * dst_max / src_max );
     }
 };

Regards,
Christian


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net