
"Timothy M. Shead" <tshead@k-3d.com> wrote in message news:1161054851.13317.27.camel@joe.k-3d.com...
I am trying to use GIL with the OpenEXR library, which uses half-precision floating-point channels:
typedef image_type<half, rgb_t>::type rgb16f_image_t; typedef pixel<half, rgb_t> rgb16f_pixel_t;
... which works fine. However, I also need to convert to 8bpp integer images for use with a UI toolkit:
rgb16f_image_t a(100, 100); rgb8_image_t b(100, 100); copy_pixels(const_view(a), view(b));
After providing a specialization for PixelsCompatibleConcept the code compiles fine, but I would like to provide my own code for converting channels of type "half" to type "bits8" (e.g: to convert values in the range [0, 1] to [0, 255]).
Any thoughts?
Tim Shead
I'm not sure if the following fits the bill , but it might provide some ideas. (quan arithmetic_promote header is : http://quan.cvs.sourceforge.net/quan/quan-trunk/quan/meta/arithmetic_promote... which has no dependencies afaics. Alternatively try Boost.Typeof) have fun... regards Andy Little ------------------ #include <boost/numeric/conversion/converter.hpp> #include <quan/meta/arithmetic_promote.hpp> // rgb_value includes N as its normalisation to 1 value //where normalised = value/N template< typename T, unsigned N
struct rgb_value{ typedef T value_type; static const unsigned max_rgb_value = N; T value; explicit rgb_value(T const & in) : value(in){} rgb_value() : value(T(0)){} }; template < typename T, template <typename , typename > class Policy,// intermediate calc policy typename S
T rgb_conv(S const & from) { typedef Policy<typename T::value_type,typename S::value_type>::type Inter; Inter inter = (static_cast<Inter>(from.value) * T::max_rgb_value )/ S::max_rgb_value; // Boost.Numeric.Converter set up with nearest neighbour rounding typedef typename boost::numeric::converter< typename T::value_type, Inter, boost::numeric::conversion_traits<typename T::value_type,Inter>, boost::numeric::def_overflow_handler, // boost::numeric::Trunc<Inter> boost::numeric::RoundEven<Inter> > converter; typename T::value_type result_value = converter()(inter); T result(result_value); return result; } // intermediate calc policy template <typename T1, typename T2> struct double_policy{ typedef double type; }; #include <iostream> int main() { typedef rgb_value<double,1> rgb_double; typedef rgb_value<float,1> rgb_float; typedef rgb_value<unsigned char,0xFF> rgb_int8; typedef rgb_value<unsigned int,0xFFFF> rgb_int16; typedef rgb_value<unsigned int,0xFFFFFFFF> rgb_int32; using quan::meta::arithmetic_promote; rgb_double v1(.3); std::cout << "rgb_double value = " << v1.value <<'\n'; rgb_float v1a = rgb_conv<rgb_float,arithmetic_promote>(v1); std::cout << "rgb_double value as float = " << v1a.value <<'\n'; rgb_int8 v2 = rgb_conv<rgb_int8,arithmetic_promote>(v1); std::cout << "rgb_double as rgb8 value = "<< std::hex << (unsigned int) v2.value <<'\n'; rgb_int16 v3 = rgb_conv<rgb_int16,arithmetic_promote>(v1); std::cout << "rgb_double as rgb16 value = " << std::hex << v3.value <<'\n'; rgb_int32 v4 = rgb_conv<rgb_int32,arithmetic_promote>(v1); std::cout << "rgb_double as rgb32 value = "<< std::hex << v4.value <<'\n'; v1 = rgb_conv<rgb_double,arithmetic_promote>(v2); v4 = rgb_conv<rgb_int32,double_policy>(v2); std::cout << "rgb_int8 as rgb32 value = "<< std::hex << v4.value <<'\n'; v2 = rgb_conv<rgb_int8,double_policy>(v4); std::cout << "rgb_int32 as rgb8 value = "<< std::hex << (unsigned int) v2.value <<'\n'; v1 = rgb_conv<rgb_double,arithmetic_promote>(v2); std::cout << "rgb_int8 back to rgb double " << v1.value <<'\n'; };