Re: [Boost-users] Boost-users Digest, Vol 2650, Issue 4

Sorry for the slow response. I simply defined the following:
typedef boost::gil::pixel
gray_float_pixel_t; typedef boost::gil::image gray_float_image_t; typedef gray_float_image_t::view_t gray_float_view_t; typedef gray_float_image_t::const_view_t gray_float_const_view_t; As Dr. Bourdev advised, I do not use with these typedefs any of the color conversion operations offered by GIL. Apparently those rely on the scaling properties of the float wrapper type.
So far, all I have done with these typedefs is ...
1. construct views using interleaved_view and pixel data pointed to by [const] float*, as illustrated near the beginning of the GIL tutorial 2. create x- and y- iterators for the views to apply row- and column-oriented algorithms?
Sorry for _my_ slow response (I was in Japan). I don't care about colour conversions, but I think that these types will convert to integral types with scaling unless you add more boilerplate. I added the following -- but it may not all have been needed; this was quite a while ago and I was new to gil. I also have some remaining conversion problems where I have to rewrite expressions to make them compile, but this may be something else. Anyway, I'd really like to see native gil support for a complete set of NON-scaling types.
namespace boost { namespace gil {
/*
* Define a type that's a pure float, without scaling into [0, 1]
*/
typedef float bits32f_noscale;
GIL_DEFINE_BASE_TYPEDEFS(32f_noscale, gray)
GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(32f_noscale, dev2n, devicen_t<2>, devicen_layout_t<2>)
template<> struct channel_multiplier

On Mar 07, 2011, at 07:44 AM, Robert Lupton the Good
Sorry for the slow response. I simply defined the following:
typedef boost::gil::pixel
gray_float_pixel_t; typedef boost::gil::image gray_float_image_t; typedef gray_float_image_t::view_t gray_float_view_t; typedef gray_float_image_t::const_view_t gray_float_const_view_t; As Dr. Bourdev advised, I do not use with these typedefs any of the color conversion operations offered by GIL. Apparently those rely on the scaling properties of the float wrapper type.
So far, all I have done with these typedefs is ...
1. construct views using interleaved_view and pixel data pointed to by [const] float*, as illustrated near the beginning of the GIL tutorial 2. create x- and y- iterators for the views to apply row- and column-oriented algorithms
Sorry for _my_ slow response (I was in Japan). I don't care about colour conversions, but I think that these types will convert to integral types with scaling unless you add more boilerplate. I added the following -- but it may not all have been needed; this was quite a while ago and I was new to gil. I also have some remaining conversion problems where I have to rewrite expressions to make them compile, but this may be something else. Anyway, I'd really like to see native gil support for a complete set of NON-scaling types.
namespace boost { namespace gil { /* * Define a type that's a pure float, without scaling into [0, 1] */ typedef float bits32f_noscale;
GIL_DEFINE_BASE_TYPEDEFS(32f_noscale, gray) GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(32f_noscale, dev2n, devicen_t<2>, devicen_layout_t<2>)
template<> struct channel_multiplier
: public std::binary_function { bits32f_noscale operator()(bits32f_noscale a, bits32f_noscale b) const { return a*b; } }; template <typename DstChannelV> struct channel_converter
: public std::unary_function { DstChannelV operator()(bits32f_noscale x) const { return DstChannelV(x + 0.5f); } }; template <typename SrcChannelV> struct channel_converter
: public std::unary_function { bits32f_noscale operator()(SrcChannelV x) const { return bits32f_noscale(x); } }; // // Totally specialised templates to resolve ambiguities // #define CONVERT_NOOP(T1, T2) \ template <> \ struct channel_converter
: public std::unary_function { \ T2 operator()(T1 x) const { return static_cast<T2>(x); } \ }; \ \ template <> \ struct channel_converter : public std::unary_function { \ T1 operator()(T2 x) const { return static_cast<T1>(x); } \ } CONVERT_NOOP(unsigned char, short); CONVERT_NOOP(unsigned char, unsigned short); CONVERT_NOOP(unsigned char, int); CONVERT_NOOP(unsigned short, short); CONVERT_NOOP(unsigned short, int); CONVERT_NOOP(short, int);
#undef CONVERT_NOOP
Using only the four typedefs that I provided earlier, I don't see any sign that the GIL classes that I'm using are scaling the floats behind the curtain. I haven't been able to follow the details of the metaprogramming inside GIL, but I have observed two key facts that suggest that no scaling is occuring:
1. The end result has the scale I expect (without scaling).
2. std::less

Hi Curtis and Robert,
On Fri, Apr 22, 2011 at 1:06 PM, Curtis Gehman
Sorry for _my_ slow response (I was in Japan). I don't care about colour conversions, but I think that these types will convert to integral types with scaling unless you add more boilerplate. I added the following -- but it may not all have been needed; this was quite a while ago and I was new to gil. I also have some remaining conversion problems where I have to rewrite expressions to make them compile, but this may be something else. Anyway, I'd really like to see native gil support for a complete set of NON-scaling types.
<snip partial specializations of channel_multiplier and channel_converter>
Using only the four typedefs that I provided earlier, I don't see any sign that the GIL classes that I'm using are scaling the floats behind the curtain. I haven't been able to follow the details of the metaprogramming inside GIL, but I have observed two key facts that suggest that no scaling is occuring:
The end result has the scale I expect (without scaling). std::less
works with InIter = gray_float_const_view_t::x_iterator (or y_iterator).
I'm neither Christian nor Lubomir, but I've spent a fair amount of time with the channel conversion code. GIL generally doesn't verify that pixel values are in gamut (too expensive), so it doesn't really modify anything under the hood. Robert has identified two places where there's the potential for strange conversions -- channel_multiply and channel_convert. Channel multiply is used inside GIL to convert from one colorspace to another, and the problem occurs when normalizing the result by the maximum channel value (in this case, std::numeric_limits<float>::max()). channel_convert is similar. So avoiding the conversion code should be all that's necessary to prevent unwanted scaling. I'll admit that I'm suspicious of the correctness of Robert's color_convert overloads -- if you don't want color conversion to happen perhaps you could add a static assert to verify they're not instantiated? HTH, Nate
participants (3)
-
Curtis Gehman
-
Nathan Crookston
-
Robert Lupton the Good