$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
hsl_to_rgb.hh
1 // Copyright (C) 2008, 2009, 2011, 2012 EPITA Research and Development
2 // Laboratory (LRDE)
3 //
4 // This file is part of Olena.
5 //
6 // Olena is free software: you can redistribute it and/or modify it under
7 // the terms of the GNU General Public License as published by the Free
8 // Software Foundation, version 2 of the License.
9 //
10 // Olena is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
17 //
18 // As a special exception, you may use this file as part of a free
19 // software project without restriction. Specifically, if other files
20 // instantiate templates or use macros or inline functions from this
21 // file, or you compile this file and link it with other files to produce
22 // an executable, this file does not by itself cause the resulting
23 // executable to be covered by the GNU General Public License. This
24 // exception does not however invalidate any other reasons why the
25 // executable file might be covered by the GNU General Public License.
26 
27 #ifndef MLN_FUN_V2V_HSL_TO_RGB_HH
28 # define MLN_FUN_V2V_HSL_TO_RGB_HH
29 
35 
36 # include <cmath>
37 
38 # include <mln/math/round.hh>
39 # include <mln/math/max.hh>
40 # include <mln/math/min.hh>
41 
42 # include <mln/trait/value_.hh>
43 
44 # include <mln/value/rgb.hh>
45 
46 
47 
48 namespace mln
49 {
50 
51  namespace fun
52  {
53 
54  namespace v2v
55  {
56 
60  //
61  template <typename T_rgb>
62  struct f_hsl_to_rgb_ : public Function_v2v< f_hsl_to_rgb_<T_rgb> >
63  {
64  typedef T_rgb result;
65 
66 
67  f_hsl_to_rgb_();
68 
69  template <typename T_hsl>
70  T_rgb operator()(const T_hsl& hsl) const;
71 
72  };
73 
76 
79 
80 
81 # ifndef MLN_INCLUDE_ONLY
82 
83 # ifndef MLN_WO_GLOBAL_VARS
84 
90 # endif // !MLN_WO_GLOBAL_VARS
91 
92  template <typename T_rgb>
94  {
95  }
96 
100  template <typename T_rgb>
101  template <typename T_hsl>
102  inline
103  T_rgb
104  f_hsl_to_rgb_<T_rgb>::operator()(const T_hsl& hsl) const
105  {
106  typedef typename T_rgb::red_t red_t;
107  typedef typename T_rgb::green_t green_t;
108  typedef typename T_rgb::blue_t blue_t;
109 
110  const float q = (hsl.lum() < 0.5) ? hsl.lum() * (1.0 + hsl.sat()) :
111  hsl.lum() + hsl.sat() - (hsl.lum() * hsl.sat());
112  const float p = 2.0 * hsl.lum() - q;
113  const float hk = hsl.hue() / 360.0; // hk = normalized hue
114  float tr = hk + (1.0 / 3.0);
115  float tg = hk;
116  float tb = hk - (1.0 / 3.0);
117 
118  if (tr < 0.0)
119  tr += 1.0;
120  if (tr > 1.0)
121  tr -= 1.0;
122 
123  if (tg < 0.0)
124  tg += 1.0;
125  if (tg > 1.0)
126  tg -= 1.0;
127 
128  if (tb < 0.0)
129  tb += 1.0;
130  if (tb > 1.0)
131  tb -= 1.0;
132 
133  // Red.
134  float red;
135  if (tr < (1.0 / 6.0))
136  red = p + ((q - p) * 6 * tr);
137  else if (tr < (1.0 / 2.0))
138  red = q;
139  else if (tr < (2.0 / 3.0))
140  red = p + ((q - p) * 6 * ((2.0 / 3.0) - tr));
141  else
142  red = p;
143 
144  // Green.
145  float green;
146  if (tg < (1.0 / 6.0))
147  green = p + ((q - p) * 6 * tg);
148  else if (tg < (1.0 / 2.0))
149  green = q;
150  else if (tg < (2.0 / 3.0))
151  green = p + ((q - p) * 6 * ((2.0 / 3.0) - tg));
152  else
153  green = p;
154 
155  // Blue.
156  float blue;
157  if (tb < (1.0 / 6.0))
158  blue = p + ((q - p) * 6 * tb);
159  else if (tb < (1.0 / 2.0))
160  blue = q;
161  else if (tb < (2.0 / 3.0))
162  blue = p + ((q - p) * 6 * ((2.0 / 3.0) - tb));
163  else
164  blue = p;
165 
166  // Each component is in [0, 1].
167  red_t r = math::round<red_t>(red * 255);
168  green_t g = math::round<green_t>(green * 255);
169  blue_t b = math::round<blue_t>(blue * 255);
170 
171  T_rgb rgb_result(r, g, b);
172 
173  return rgb_result;
174  }
175 
176 # endif // !MLN_INCLUDE_ONLY
177 
178  } // end of namespace fun::v2v
179 
180  } // end of namespace fun
181 
182 } // end of namespace mln
183 
184 
185 #endif // ! MLN_FUN_V2V_HSL_TO_RGB_HH