2 // Copyright 2012 Chung-Lin Wen
4 // Distributed under the Boost Software License, Version 1.0
5 // See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt
8 #ifndef BOOST_GIL_EXTENSION_TOOLBOX_COLOR_SPACES_LAB_HPP
9 #define BOOST_GIL_EXTENSION_TOOLBOX_COLOR_SPACES_LAB_HPP
11 #include <boost/gil/extension/toolbox/color_spaces/xyz.hpp>
13 #include <boost/gil/color_convert.hpp>
14 #include <boost/gil.hpp> // FIXME: Include what you use, not everything, even in extensions!
15 #include <boost/gil/detail/mp11.hpp>
17 namespace boost{ namespace gil {
19 /// \addtogroup ColorNameModel
21 namespace lab_color_space
24 struct luminance_t {};
25 /// \brief a Color Component
26 struct a_color_opponent_t {};
27 /// \brief b Color Component
28 struct b_color_opponent_t {};
32 /// \ingroup ColorSpaceModel
33 using lab_t = mp11::mp_list
35 lab_color_space::luminance_t,
36 lab_color_space::a_color_opponent_t,
37 lab_color_space::b_color_opponent_t
40 /// \ingroup LayoutModel
41 using lab_layout_t = layout<lab_t>;
43 GIL_DEFINE_ALL_TYPEDEFS(32f, float32_t, lab)
45 /// \ingroup ColorConvert
48 struct default_color_converter_impl< lab_t, xyz_t >
50 template <typename P1, typename P2>
51 void operator()( const P1& src, P2& dst ) const
53 using namespace lab_color_space;
54 using namespace xyz_color_space;
56 float32_t p = ((get_color(src, luminance_t()) + 16.f)/116.f);
58 get_color(dst, y_t()) =
61 get_color(dst, x_t()) =
63 (get_color(src, a_color_opponent_t())/500.f)
65 get_color(dst, z_t()) =
67 (get_color(src, b_color_opponent_t())/200.f)
72 /// \ingroup ColorConvert
74 /// \note I assume \c xyz_t
76 struct default_color_converter_impl< xyz_t, lab_t >
79 /// \ref http://www.brucelindbloom.com/index.html?Eqn_XYZ_to_Lab.html
81 float32_t forward_companding(float32_t value) const
83 if (value > 216.f/24389.f)
85 return powf(value, 1.f/3.f);
89 return ((24389.f/27.f * value + 16.f)/116.f);
94 template <typename P1, typename P2>
95 void operator()( const P1& src, P2& dst ) const
97 using namespace lab_color_space;
101 channel_convert<float32_t>(
102 get_color(src, xyz_color_space::y_t())
109 channel_convert<float32_t>(
110 get_color(src, xyz_color_space::x_t())
112 * (1.f / 0.95047f) // if the compiler is smart, it should
113 // precalculate this, no?
118 channel_convert<float32_t>(
119 get_color(src, xyz_color_space::z_t())
121 * (1.f / 1.08883f) // if the compiler is smart, it should
122 // precalculate this, no?
125 get_color(dst, luminance_t()) =
128 get_color(dst, a_color_opponent_t()) =
131 get_color(dst, b_color_opponent_t()) =
137 /// \ingroup ColorConvert
138 /// \brief RGB to LAB
140 struct default_color_converter_impl< rgb_t, lab_t >
142 template <typename P1, typename P2>
143 void operator()( const P1& src, P2& dst ) const
145 using namespace lab_color_space;
147 xyz32f_pixel_t xyz32f_temp_pixel;
148 default_color_converter_impl<rgb_t, xyz_t>()(src, xyz32f_temp_pixel);
149 default_color_converter_impl<xyz_t, lab_t>()(xyz32f_temp_pixel, dst);
153 /// \ingroup ColorConvert
154 /// \brief LAB to RGB
156 struct default_color_converter_impl<lab_t,rgb_t>
158 template <typename P1, typename P2>
159 void operator()( const P1& src, P2& dst) const
161 using namespace lab_color_space;
163 xyz32f_pixel_t xyz32f_temp_pixel;
164 default_color_converter_impl<lab_t, xyz_t>()(src, xyz32f_temp_pixel);
165 default_color_converter_impl<xyz_t, rgb_t>()(xyz32f_temp_pixel, dst);