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 bits12;
namespace detail
{
template <>
struct unsigned_integral_max_value<bits12>
: public mpl::integral_c {};
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 bits14;
namespace detail
{
template <>
struct unsigned_integral_max_value<bits14>
: public mpl::integral_c {};
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(view(img14))(1,0);
gray32f_image_t img32f(2,2);
color_converted_view(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:
:operator ()(SrcChannelV) const'
with
[
BaseChannelValue=boost::uint16_t,
MinVal=boost::gil::bits12_min,
MaxVal=boost::gil::bits12_max,
SrcChannelV=boost::gil::scoped_channel_value,
DstChannelV=boost::gil::scoped_channel_value,
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::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,
DstChannelV=boost::gil::scoped_channel_value
]
<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
+struct base_channel >
+: public base_channel<BaseChannelValue> {};
+
+template <int NumBits>
+struct base_channel
+{ 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(div/2);
+ return static_cast((src + div2) / div);
}
};
@@ -265,7 +276,8 @@
/////////////////////////////////////////////////////
template <typename DstChannelV> struct
channel_converter_unsigned : public
std::unary_function {
- DstChannelV operator()(bits32f x) const { return
DstChannelV(x*channel_traits<DstChannelV>::max_value()+0.5f); }
+ DstChannelV operator()(bits32f x) const { return
+ static_cast(x*channel_traits<DstChannelV>::max_value()+0.5f);
}
};
template <typename SrcChannelV> struct
channel_converter_unsigned : public
std::unary_function {
//////// END patch ////////////////
Thanks,
Nate