Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
hsi_to_rgb.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_HSI_TO_RGB_HH
28 # define MLN_FUN_V2V_HSI_TO_RGB_HH
29 
33 
34 #include <cmath>
35 
36 #include <mln/value/rgb8.hh>
37 #include <mln/math/round.hh>
38 
39 #include <mln/value/hsi.hh>
40 
41 
42 namespace mln
43 {
44 
45 
46  namespace fun
47  {
48 
49  namespace v2v
50  {
51 
55  //
56  template <typename T_rgb>
57  struct f_hsi_to_rgb_ : public Function_v2v< f_hsi_to_rgb_<T_rgb> >
58  {
59  typedef T_rgb result;
60 
61  f_hsi_to_rgb_();
62 
63  template <typename T_hsi>
64  T_rgb operator()(const T_hsi& hsi) const;
65 
66  };
67 
68  typedef f_hsi_to_rgb_<value::rgb8> f_hsi_to_rgb_3x8_t;
69 
70  extern f_hsi_to_rgb_3x8_t f_hsi_to_rgb_3x8;
71 
72 
73 # ifndef MLN_INCLUDE_ONLY
74 
75 # ifndef MLN_WO_GLOBAL_VARS
76 
79  f_hsi_to_rgb_3x8_t f_hsi_to_rgb_3x8;
81 
82 # endif // ! MLN_WO_GLOBAL_VARS
83 
84  template <typename T_rgb>
85  f_hsi_to_rgb_<T_rgb>::f_hsi_to_rgb_()
86  {
87  }
88 
89 
90  template <typename T_rgb>
91  template <typename T_hsi>
92  inline
93  T_rgb
94  f_hsi_to_rgb_<T_rgb>::operator()(const T_hsi& hsi) const
95  {
96  typedef typename T_rgb::red_t red_t;
97  typedef typename T_rgb::green_t green_t;
98  typedef typename T_rgb::blue_t blue_t;
99 
100  static math::round<red_t> to_r;
101  static math::round<green_t> to_g;
102  static math::round<blue_t> to_b;
103 
104  static const float
105  sqrt3_3 = std::sqrt(3) / 3,
106  inv_sqrt6 = 1 / std::sqrt(6),
107  inv_sqrt2 = 1 / std::sqrt(2);
108 
109  float
110  h = hsi.hue() / 180.0 * 3.1415,
111  alpha = hsi.sat() * std::cos(h),
112  beta = hsi.sat() * std::sin(h);
113 
114 
115  red_t r = to_r(sqrt3_3 * hsi.inty() + 2 * inv_sqrt6 * beta);
116  green_t g =
117  to_g(sqrt3_3 * hsi.inty() + inv_sqrt2 * alpha - inv_sqrt6 * beta);
118  blue_t b =
119  to_b(sqrt3_3 * hsi.inty() - inv_sqrt2 * alpha - inv_sqrt6 * beta);
120 
121  T_rgb rgb(r, g, b);
122 
123  return rgb;
124  }
125 
126 # endif // !MLN_INCLUDE_ONLY
127 
128  } // end of namespace fun::v2v
129 
130  } // end of namespace fun
131 
132 } // end of namespace mln
133 
134 #endif // ! MLN_FUN_V2V_HSI_TO_RGB_HH