|
Boost : |
From: Andy Little (andy_at_[hidden])
Date: 2006-10-18 07:29:19
"Timothy M. Shead" <tshead_at_[hidden]> wrote in message
news:1161054851.13317.27.camel_at_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.hpp?view=markup
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';
};
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk