|
Boost : |
Subject: [boost] [GIL] color_convert
From: fabien.castan_at_[hidden]
Date: 2010-07-28 05:49:56
Hi,
I use the GIL extension: HSL.
I need to make conversions from hsl to other colorspaces.
So I define generic default conversion using intermediate rgb colorspace.
I define 2 templates:
* default_color_convert<C1,hsl_t>
* default_color_convert<hsl_t,C2>
But it creates an ambiguity with rgba_t, because it defines the same thing for rgba_t:
* default_color_convert<C1,rgba_t>
* default_color_convert<rgba_t,C2>
So default_color_convert<hsl_t,rgba_t> is ambiguous.
The only solution I see is:
* to remove default_color_convert<C1,rgba_t>
* to define gray_t->rgba_t, rgb_t->rgba_t
* to remove default_color_convert<C1,hsl_t>
* to define default_color_convert<cmyk_t,C2>
So all colorspaces have to:
* define a generic conversion to another colorspace using an intermediate rgb colorspace conversion
* redefine the conversion for colorspaces we want to make a direct conversion
Best regards,
Fabien Castan
/// \ingroup ColorConvert
/// \brief Converting CMYK to any pixel type. Note: Supports homogeneous pixels only.
///
/// Done by an intermediate RGB conversion
template <typename C2>
struct default_color_converter_impl<cmyk_t,C2>
{
template <typename P1, typename P2>
void operator()(const P1& src, P2& dst) const
{
typedef cmyk_t C1;
typedef typename channel_type<P1>::type T1;
typedef typename channel_type<P2>::type T2;
pixel<T2,rgb_layout_t> tmp;
default_color_converter_impl<C1,rgb_t>()(src, tmp);
default_color_converter_impl<rgb_t,C2>()(tmp, dst);
}
};
/*
/// \ingroup ColorConvert
/// \brief Converting any pixel type to RGBA. Note: Supports homogeneous pixels only.
template <typename C1>
struct default_color_converter_impl<C1,rgba_t> {
template <typename P1, typename P2>
void operator()(const P1& src, P2& dst) const {
typedef typename channel_type<P2>::type T2;
pixel<T2,rgb_layout_t> tmp;
default_color_converter_impl<C1,rgb_t>()(src,tmp);
get_color(dst,red_t()) = get_color(tmp,red_t());
get_color(dst,green_t())= get_color(tmp,green_t());
get_color(dst,blue_t()) = get_color(tmp,blue_t());
get_color(dst,alpha_t())= channel_convert<T2>(alpha_or_max(src));
}
};
*/
/// \ingroup ColorConvert
/// \brief Converting grayscale pixel type to RGBA. Note: Supports homogeneous pixels only.
template <>
struct default_color_converter_impl<gray_t,rgba_t> {
template <typename P1, typename P2>
void operator()(const P1& src, P2& dst) const
{
typedef gray_t C1;
typedef typename channel_type<P2>::type T2;
get_color(dst,red_t()) = get_color(src,gray_color_t());
get_color(dst,green_t())= get_color(src,gray_color_t());
get_color(dst,blue_t()) = get_color(src,gray_color_t());
get_color(dst,alpha_t())= channel_convert<T2>(alpha_or_max(src));
}
};
/// \ingroup ColorConvert
/// \brief Converting grayscale pixel type to RGBA. Note: Supports homogeneous pixels only.
template <>
struct default_color_converter_impl<rgb_t,rgba_t> {
template <typename P1, typename P2>
void operator()(const P1& src, P2& dst) const
{
typedef rgb_t C1;
typedef typename channel_type<P2>::type T2;
get_color(dst,red_t()) = get_color(src,red_t());
get_color(dst,green_t())= get_color(src,green_t());
get_color(dst,blue_t()) = get_color(src,blue_t());
get_color(dst,alpha_t())= channel_convert<T2>(alpha_or_max(src));
}
};
/// \ingroup ColorConvert
/// \brief Converting RGBA to any pixel type. Note: Supports homogeneous pixels only.
///
/// Done by multiplying the alpha to get to RGB, then converting the RGB to the target pixel type
/// Note: This may be slower if the compiler doesn't optimize out constructing/destructing a temporary RGB pixel.
/// Consider rewriting if performance is an issue
template <typename C2>
struct default_color_converter_impl<rgba_t,C2> {
template <typename P1, typename P2>
void operator()(const P1& src, P2& dst) const {
typedef typename channel_type<P1>::type T1;
default_color_converter_impl<rgb_t,C2>()(
pixel<T1,rgb_layout_t>(channel_multiply(get_color(src,red_t()), get_color(src,alpha_t())),
channel_multiply(get_color(src,green_t()),get_color(src,alpha_t())),
channel_multiply(get_color(src,blue_t()), get_color(src,alpha_t())))
,dst);
}
};
/// \ingroup ColorConvert
/// \brief Converting HSL to any pixel type. Note: Supports homogeneous pixels only.
///
/// Done by an intermediate RGB conversion
template <typename C2>
struct default_color_converter_impl<hsl_t,C2>
{
template <typename P1, typename P2>
void operator()(const P1& src, P2& dst) const
{
typedef hsl_t C1;
typedef typename channel_type<P1>::type T1;
typedef typename channel_type<P2>::type T2;
pixel<T2,rgb_layout_t> tmp;
default_color_converter_impl<C1,rgb_t>()(src, tmp);
default_color_converter_impl<rgb_t,C2>()(tmp, dst);
}
};
/// \ingroup ColorConvert
/// \brief Unfortunately HSL to HSL must be explicitly provided - otherwise we get ambiguous specialization error.
template <>
struct default_color_converter_impl<hsl_t,hsl_t>
{
template <typename P1, typename P2>
void operator()(const P1& src, P2& dst) const
{
static_for_each(src,dst,default_channel_converter());
}
};
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk