$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
rgb_to_hsl.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_RGB_TO_HSL_HH
28 # define MLN_FUN_V2V_RGB_TO_HSL_HH
29 
30 # include <cmath>
31 
32 # include <mln/math/round.hh>
33 # include <mln/math/max.hh>
34 # include <mln/math/min.hh>
35 
36 # include <mln/trait/value_.hh>
37 
38 namespace mln
39 {
40 
41  // Forward declaration
42  namespace value
43  {
44  template <typename H, typename S, typename L> class hsl_;
46  }
47 
48  namespace fun
49  {
50 
51  namespace v2v
52  {
53 
54  template <typename T_hsl>
55  struct f_rgb_to_hsl_ : public Function_v2v< f_rgb_to_hsl_<T_hsl> >
56  {
57  typedef T_hsl result;
58 
59  f_rgb_to_hsl_();
60 
61  template <typename T_rgb>
62  T_hsl operator()(const T_rgb& rgb) const;
63 
64  };
65 
67 
69 
70 
71 # ifndef MLN_INCLUDE_ONLY
72 
73 # ifndef MLN_WO_GLOBAL_VARS
74 
79 
80 # endif // ! MLN_WO_GLOBAL_VARS
81 
82  template <typename T_hsl>
84  {
85  }
86 
87  template <typename T_hsl>
88  template <typename T_rgb>
89  inline
90  T_hsl
91  f_rgb_to_hsl_<T_hsl>::operator()(const T_rgb& rgb) const
92  {
93  // Locals.
94  T_hsl hsl;
95 
96  typename T_rgb::red_t rmax = math::max(rgb.red(), math::max(rgb.green(), rgb.blue()));
97  typename T_rgb::red_t rmin = math::min(rgb.red(), math::min(rgb.green(), rgb.blue()));
98 
99  if (rmin == rmax)
100  hsl.hue() = 0;
101  else
102  if (rmax == rgb.red())
103  {
104  hsl.hue() = (60. * (rgb.green() - rgb.blue()) / (rmax - rmin));
105  if (hsl.hue() < 0)
106  hsl.hue() += 360.;
107  }
108  else
109  if (rmax == rgb.green())
110  hsl.hue() = (60. * (rgb.blue() - rgb.red()) / (rmax - rmin)) + 120.;
111  else
112  hsl.hue() = (60. * (rgb.red() - rgb.green()) / (rmax - rmin)) + 240;
113 
114  // We want min and max between 0 and 1
115  rmax -= mln_min(typename T_rgb::red_t);
116  rmin -= mln_min(typename T_rgb::red_t);
117  double nmax = (double) rmax / (mln_max(typename T_rgb::red_t) - mln_min(typename T_rgb::red_t));
118  double nmin = (double) rmin / (mln_max(typename T_rgb::red_t) - mln_min(typename T_rgb::red_t));
119 
120  hsl.lum() = (nmax + nmin) / 2;
121 
122  if (rmin == rmax)
123  hsl.sat() = 0;
124  else
125  if (hsl.lum() <= 0.5)
126  hsl.sat() = (nmax - nmin) / (nmax + nmin);
127  else
128  hsl.sat() = (nmax - nmin) / (2 - nmax - nmin);
129 
130  return hsl;
131  }
132 
133 
134 # endif // !MLN_INCLUDE_ONLY
135 
136  } // end of namespace fun::v2v
137 
138  } // end of namespace fun
139 
140 } // end of namespace mln
141 
142 #endif // ! MLN_FUN_V2V_RGB_TO_HSL_HH