Boost logo

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