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