
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()); } };

Hi there, I'm in Cuda school this week. Please allow me some time to have a look at this over the weekend. Regards, Christian On Wed, Jul 28, 2010 at 5:49 AM, <fabien.castan@free.fr> wrote:
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()); } };
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Hi there,
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.
I cannot recreate your problem. Here is a little test app that works fine on my machine ( VC10 ): #include <boost\gil\gil_all.hpp> #include <boost\gil\extension\toolbox\hsl.hpp> namespace boost { namespace gil { template <> struct default_color_converter_impl< rgba_t, hsl_t > { template <typename P1, typename P2> void operator()( const P1& src, P2& dst ) const { using namespace hsl_color_space; int i = 9; // call default_color_converter_impl< rgb_t, hsl_t > eventually } }; template <> struct default_color_converter_impl<hsl_t,rgba_t> { template <typename P1, typename P2> void operator()( const P1& src, P2& dst) const { using namespace hsl_color_space; int i = 9; // call default_color_converter_impl< hsl_t, rgb_t > eventually } }; } // namespace gil } // namespace boost using namespace std; using namespace boost; using namespace gil; int _tmain(int argc, _TCHAR* argv[]) { rgba8_pixel_t p( 128, 0, 128, 255 ); hsl32f_pixel_t h; color_convert( p, h ); color_convert( h, p ); return 0; } You don't even need to specify the total specification. The current implementation would multiply the alpha factor to all rgb channels and then call rgb -> hsl converter. Do you have a different algorithm to create a hsl pixel? I haven't tried cmyk. Regards, Christian
participants (2)
-
Christian Henning
-
fabien.castan@free.fr