Boost logo

Boost Users :

Subject: Re: [Boost-users] [GIL] Warnings when compiling items in channel_algorithms.hpp
From: Christian Henning (chhenning_at_[hidden])
Date: 2010-06-18 20:30:37


Hi Nathan, I'll have a look.

Thanks for submitting,
Christian

On Fri, Jun 18, 2010 at 1:34 PM, Nathan Crookston
<nathan.crookston_at_[hidden]> wrote:
> All,
>
> While writing some image conversion code using scoped_channel_value I
> encountered several compiler warnings.  The following minimal code
> demonstrates:
>
> Compiled with VC8, command line: "cl simple.cpp /Iboost /W3 /EHsc"
>
>
> ////// BEGIN CODE /////////////////////////////
>
> #include "boost/gil/gil_all.hpp"
>
> namespace boost { namespace gil {
>
> const boost::uint16_t bits12_max_val = 0xFFF;
> struct bits12_min { static boost::uint16_t apply() { return 0; } };
> struct bits12_max { static boost::uint16_t apply() { return bits12_max_val; } };
>
> typedef boost::gil::scoped_channel_value<boost::uint16_t,
>                                                 bits12_min, bits12_max> bits12;
>
> namespace detail
> {
>  template <>
>    struct unsigned_integral_max_value<bits12>
>      : public mpl::integral_c<uint32_t,bits12_max_val> {};
>
>  template <>
>    struct unsigned_integral_num_bits<bits12> : public mpl::int_<12> {};
>
> }//end detail
>
> GIL_DEFINE_BASE_TYPEDEFS(12, gray)
>
> const boost::uint16_t bits14_max_val = 0x3FFF;
> struct bits14_min { static boost::uint16_t apply() { return 0; } };
> struct bits14_max { static boost::uint16_t apply() { return bits14_max_val; } };
>
> typedef boost::gil::scoped_channel_value<boost::uint16_t,
>                                                 bits14_min, bits14_max> bits14;
>
> namespace detail
> {
>  template <>
>    struct unsigned_integral_max_value<bits14>
>      : public mpl::integral_c<uint32_t,bits14_max_val> {};
>
>  template <>
>    struct unsigned_integral_num_bits<bits14> : public mpl::int_<14> {};
>
> }//end detail
>
> GIL_DEFINE_BASE_TYPEDEFS(14, gray)
> } } //end gil, boost
>
> using namespace boost::gil;
>
> int main()
> {
>  gray14_image_t img14(2,2);
>  color_converted_view<gray12_pixel_t>(view(img14))(1,0);
>
>  gray32f_image_t img32f(2,2);
>  color_converted_view<gray12_pixel_t>(view(img32f))(1,0);
>
>  return 0;
> }
>
> ////// END CODE ///////////////////////////////
>
> It produces the following warnings, trimmed to only those I thought relevant:
>
> ///////////////// BEGIN Relevant Warnings //////////////////////////////////////
> c:\cygwin\home\ncrookston\boost\boost\gil\channel_algorithm.hpp(257) : warning C
> 4244: 'argument' : conversion from 'const double' to 'boost::uint16_t', possible
>  loss of data
>        c:\cygwin\home\ncrookston\boost\boost\gil\channel_algorithm.hpp(252) : w
> hile compiling class template member function 'boost::gil::scoped_channel_value<
> BaseChannelValue,MinVal,MaxVal> boost::gil::detail::channel_converter_unsigned_i
> ntegral_nondivisible<SrcChannelV,DstChannelV,SrcLessThanDst,CannotFitInInteger>:
> :operator ()(SrcChannelV) const'
>        with
>        [
>            BaseChannelValue=boost::uint16_t,
>            MinVal=boost::gil::bits12_min,
>            MaxVal=boost::gil::bits12_max,
>            SrcChannelV=boost::gil::scoped_channel_value<boost::uint16_t,boost::
> gil::bits14_min,boost::gil::bits14_max>,
>            DstChannelV=boost::gil::scoped_channel_value<boost::uint16_t,boost::
> gil::bits12_min,boost::gil::bits12_max>,
>            SrcLessThanDst=false,
>            CannotFitInInteger=false
>        ]
>
> <snip lots of instantiation backtrace>
>
> c:\cygwin\home\ncrookston\boost\boost\gil\channel_algorithm.hpp(268) : warning C
> 4244: 'argument' : conversion from 'float' to 'boost::uint16_t', possible loss o
> f data
>        c:\cygwin\home\ncrookston\boost\boost\gil\channel_algorithm.hpp(268) : w
> hile compiling class template member function 'boost::gil::scoped_channel_value<
> BaseChannelValue,MinVal,MaxVal> boost::gil::channel_converter_unsigned<SrcChanne
> lV,DstChannelV>::operator ()(boost::gil::bits32f) const'
>        with
>        [
>            BaseChannelValue=boost::uint16_t,
>            MinVal=boost::gil::bits12_min,
>            MaxVal=boost::gil::bits12_max,
>            SrcChannelV=boost::gil::scoped_channel_value<float,boost::gil::float
> _zero,boost::gil::float_one>,
>            DstChannelV=boost::gil::scoped_channel_value<boost::uint16_t,boost::
> gil::bits12_min,boost::gil::bits12_max>
>        ]
>
> <snip lots more instantiation backtrace>
>
> /////////////////////// END Relevant Warnings
> //////////////////////////////////////////////////
>
> Interestingly, g++ doesn't have an issue with the code.
>
> The following patch corrects the problem.  I'd be happy to create a
> trac ticket, write some tests, etc.  Please advise.
>
> ////////////// BEGIN Patch //////////////////////////////////////
> Index: channel_algorithm.hpp
> ===================================================================
> --- channel_algorithm.hpp (revision 63088)
> +++ channel_algorithm.hpp (working copy)
> @@ -243,7 +243,18 @@
>     }
>  };
>
> +// Determines the base type of the channel.
> +template <typename Channel>
> +struct base_channel { typedef Channel type; };
>
> +template <typename BaseChannelValue, typename MinVal, typename MaxVal>
> +struct base_channel<scoped_channel_value<BaseChannelValue,MinVal,MaxVal> >
> +: public base_channel<BaseChannelValue> {};
> +
> +template <int NumBits>
> +struct base_channel<packed_channel_value<NumBits> >
> +{ typedef typename packed_channel_value<NumBits>::integer_t type; };
> +
>  // Both source and destination are unsigned integral channels,
>  // 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
> @@ -253,8 +264,8 @@
>         typedef typename
> unsigned_integral_max_value<SrcChannelV>::value_type integer_t;
>
>         static const double div =
> unsigned_integral_max_value<SrcChannelV>::value /
> double(unsigned_integral_max_value<DstChannelV>::value);
> -        static const integer_t div2 = integer_t(div/2);
> -        return DstChannelV((src + div2) / div);
> +        static const integer_t div2 = static_cast<integer_t>(div/2);
> +        return static_cast<typename
> base_channel<DstChannelV>::type>((src + div2) / div);
>     }
>  };
>
> @@ -265,7 +276,8 @@
>  /////////////////////////////////////////////////////
>
>  template <typename DstChannelV> struct
> channel_converter_unsigned<bits32f,DstChannelV> : public
> std::unary_function<bits32f,DstChannelV> {
> -    DstChannelV   operator()(bits32f x) const { return
> DstChannelV(x*channel_traits<DstChannelV>::max_value()+0.5f); }
> +    DstChannelV   operator()(bits32f x) const { return
> +      static_cast<typename
> detail::base_channel<DstChannelV>::type>(x*channel_traits<DstChannelV>::max_value()+0.5f);
> }
>  };
>
>  template <typename SrcChannelV> struct
> channel_converter_unsigned<SrcChannelV,bits32f> : public
> std::unary_function<SrcChannelV,bits32f> {
>
> //////// END patch ////////////////
>
>
> Thanks,
> Nate
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users
>


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