Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
hsl.hh
1 // Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
2 //
3 // This file is part of Olena.
4 //
5 // Olena is free software: you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free
7 // Software Foundation, version 2 of the License.
8 //
9 // Olena is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
16 //
17 // As a special exception, you may use this file as part of a free
18 // software project without restriction. Specifically, if other files
19 // instantiate templates or use macros or inline functions from this
20 // file, or you compile this file and link it with other files to produce
21 // an executable, this file does not by itself cause the resulting
22 // executable to be covered by the GNU General Public License. This
23 // exception does not however invalidate any other reasons why the
24 // executable file might be covered by the GNU General Public License.
25 
26 #ifndef MLN_VALUE_HSL_HH
27 # define MLN_VALUE_HSL_HH
28 
29 #include <mln/value/ops.hh>
30 
31 #include <mln/value/concept/vectorial.hh>
32 #include <mln/value/int_u.hh>
33 #include <mln/algebra/vec.hh>
34 
35 // Used in from_to
36 #include <mln/fun/v2v/rgb_to_hsl.hh>
37 
38 
39 namespace mln
40 {
41 
42  // Forward declarations.
43  namespace value
44  {
45 
46  template <typename H, typename S, typename L>
47  class hsl_;
48 
49  }
50 
51 
52 
53  namespace convert
54  {
55 
56  namespace over_load
57  {
58 
59  // rgb to hsl_
60  void
61  from_to_(const value::rgb<16>& from, value::hsl_<float,float,float>& to);
62 
63  // rgb to hsl_
64  void
65  from_to_(const value::rgb<8>& from, value::hsl_<float,float,float>& to);
66 
67  } // end of namespace mln::convert::over_load
68 
69  } // end of namespace mln::convert
70 
71 
72 
73  namespace trait
74  {
75 
76  template <typename H, typename S, typename L>
77  struct set_precise_binary_< op::plus, mln::value::hsl_<H,S,L>, mln::value::hsl_<H,S,L> >
78  {
79  typedef mln::value::hsl_<H,S,L> ret;
80  };
81 
82  template <typename H, typename S, typename L>
83  struct set_precise_binary_< op::minus, mln::value::hsl_<H,S,L>, mln::value::hsl_<H,S,L> >
84  {
85  typedef mln::value::hsl_<H,S,L> ret;
86  };
87 
88  template <typename H, typename S, typename L, typename S2>
89  struct set_precise_binary_< op::times, mln::value::hsl_<H,S,L>, mln::value::scalar_<S2> >
90  {
91  typedef mln::value::hsl_<H,S,L> ret;
92  };
93 
94  template <typename H, typename S, typename L, typename S2>
95  struct set_precise_binary_< op::div, mln::value::hsl_<H,S,L>, mln::value::scalar_<S2> >
96  {
97  typedef mln::value::hsl_<H,S,L> ret;
98  };
99 
100 
101  // FIXME : Is there any way more generic? a way to factor
102  // set_precise_binary_< op::div, mln::value::hsl_<H,S,L>, mln::value::scalar_<S> >
103  // and
104  // set_precise_binary_< op::div, mln::value::hsl_<H,S,L>, mln::value::int_u<m> >
105  // as for op::times.
106 
107  template <typename H, typename S, typename L, unsigned m>
108  struct set_precise_binary_< op::times, mln::value::hsl_<H,S,L>, mln::value::int_u<m> >
109  {
110  typedef mln::value::hsl_<H,S,L> ret;
111  };
112 
113  template <typename H, typename S, typename L, unsigned m>
114  struct set_precise_binary_< op::div, mln::value::hsl_<H,S,L>, mln::value::int_u<m> >
115  {
116  typedef mln::value::hsl_<H,S,L> ret;
117  };
118 
119  template <typename H, typename S, typename L>
120  struct value_< mln::value::hsl_<H,S,L> >
121  {
122  enum {
123  dim = 3,
124  nbits = (sizeof (H) + sizeof (S) + sizeof (L)) * 8,
125  card = mln_value_card_from_(nbits)
126  };
127 
128  typedef trait::value::nature::vectorial nature;
129  typedef trait::value::kind::color kind;
130  typedef mln_value_quant_from_(card) quant;
131 
132  typedef void comp;
133  typedef H comp_0;
134  typedef S comp_1;
135  typedef L comp_2;
136 
137  template <typename V> static comp_0 get_comp_0(const V& v) { return v.hue(); }
138  template <typename V> static comp_1 get_comp_1(const V& v) { return v.sat(); }
139  template <typename V> static comp_2 get_comp_2(const V& v) { return v.lum(); }
140 
141 // typedef algebra::vec<3, float> sum;
142  typedef mln::value::hsl_<H,S,L> sum;
143  };
144 
145  } // end of namespace trait
146 
147 
148  namespace value
149  {
150 
151  template <typename E>
152  struct HSL : Object<E>
153  {
154  };
155 
156  template <typename H, typename S, typename L>
157  class hsl_ : public HSL< hsl_<H,S,L> >
158  {
159  public:
160 
161  typedef H h_type;
162  typedef S s_type;
163  typedef L l_type;
164 
166  hsl_()
167  {
168  }
169 
170  hsl_(const literal::zero_t&)
171  : hue_(0),
172  sat_(0),
173  lum_(0)
174  {
175  }
176 
178  hsl_(const H& hue, const S& sat, const L& lum)
179  : hue_(hue),
180  sat_(sat),
181  lum_(lum)
182  {
183  }
184 
186  const H& hue() const;
187  const S& sat() const;
188  const L& lum() const;
189 
191  H& hue();
192  S& sat();
193  L& lum();
194 
195  private:
196  //FIXME: Don't we want to store these values in a vector?
197  H hue_;
198  S sat_;
199  L lum_;
200  };
201 
202 
203  // FIXME: Use float01_8/float01_16 ?
204  typedef hsl_<float, float, float> hsl_f;
205 
206  typedef hsl_<double, double, double> hsl_d;
207 
208 
215  template <typename H, typename S, typename L>
216  std::ostream& operator<<(std::ostream& ostr, const hsl_<H,S,L>& c);
217 
218 
221  template <typename H, typename S, typename L>
222  hsl_<H,S,L>
223  operator+(const hsl_<H,S,L>& lhs, const hsl_<H,S,L>& rhs);
225 
228  template <typename H, typename S, typename L>
229  hsl_<H,S,L>
230  operator-(const hsl_<H,S,L>& lhs, const hsl_<H,S,L>& rhs);
232 
235  template <typename H, typename S, typename L, typename S2>
236  hsl_<H,S,L>
237  operator*(const hsl_<H,S,L>& lhs, const mln::value::scalar_<S2>& s);
239 
242  template <typename H, typename S, typename L, typename S2>
243  hsl_<H,S,L>
244  operator/(const hsl_<H,S,L>& lhs, const mln::value::scalar_<S2>& s);
246 
249  template <typename H, typename S, typename L>
250  bool
251  operator==(const hsl_<H,S,L>& lhs, const hsl_<H,S,L>& rhs);
253 
254  } // end of namespace mln::value
255 
256 
257 
258  // More forward declarations
259  namespace fun
260  {
261  namespace v2v
262  {
263 
264  template <typename T_hsl>
265  struct f_rgb_to_hsl_;
266 
267  typedef f_rgb_to_hsl_<value::hsl_f> f_rgb_to_hsl_f_t;
268 
269  extern f_rgb_to_hsl_f_t f_rgb_to_hsl_f;
270 
271  }
272 
273  }
274 
275 # ifndef MLN_INCLUDE_ONLY
276 
277 
278  namespace value
279  {
280 
281  template <typename H, typename S, typename L>
282  const H&
283  hsl_<H,S,L>::hue() const
284  {
285  return this->hue_;
286  }
287 
288  template <typename H, typename S, typename L>
289  const S&
290  hsl_<H,S,L>::sat() const
291  {
292  return this->sat_;
293  }
294 
295  template <typename H, typename S, typename L>
296  const L&
297  hsl_<H,S,L>::lum() const
298  {
299  return this->lum_;
300  }
301 
302  template <typename H, typename S, typename L>
303  H&
304  hsl_<H,S,L>::hue()
305  {
306  return this->hue_;
307  }
308 
309  template <typename H, typename S, typename L>
310  S&
311  hsl_<H,S,L>::sat()
312  {
313  return this->sat_;
314  }
315 
316  template <typename H, typename S, typename L>
317  L&
318  hsl_<H,S,L>::lum()
319  {
320  return this->lum_;
321  }
322 
323 
324  template <typename H, typename S, typename L>
325  inline
326  std::ostream& operator<<(std::ostream& ostr, const hsl_<H,S,L>& v)
327  {
328  return ostr << '(' << debug::format(v.hue())
329  << ',' << debug::format(v.sat())
330  << ',' << debug::format(v.lum())
331  << ')';
332  }
333 
334 
335  template <typename H, typename S, typename L>
336  hsl_<H,S,L>
337  operator+(const hsl_<H,S,L>& lhs, const hsl_<H,S,L>& rhs)
338  {
339  return hsl_<H,S,L>(lhs.hue() + rhs.hue(),
340  lhs.sat() + rhs.sat(),
341  lhs.lum() + rhs.lum());
342  }
343 
344 
345  template <typename H, typename S, typename L>
346  hsl_<H,S,L>
347  operator-(const hsl_<H,S,L>& lhs, const hsl_<H,S,L>& rhs)
348  {
349  return hsl_<H,S,L>(lhs.hue() - rhs.hue(),
350  lhs.sat() - rhs.sat(),
351  lhs.lum() - rhs.lum());
352  }
353 
354 
355  template <typename H, typename S, typename L, typename S2>
356  hsl_<H,S,L>
357  operator*(const hsl_<H,S,L>& lhs, const mln::value::scalar_<S2>& s)
358  {
359  return hsl_<H,S,L>(lhs.hue() * s,
360  lhs.sat() * s,
361  lhs.lum() * s);
362  }
363 
364 
365  template <typename H, typename S, typename L, typename S2>
366  hsl_<H,S,L>
367  operator/(const hsl_<H,S,L>& lhs, const mln::value::scalar_<S2>& s)
368  {
369  return hsl_<H,S,L>(lhs.hue() / s,
370  lhs.sat() / s,
371  lhs.lum() / s);
372  }
373 
374  template <typename H, typename S, typename L>
375  bool
376  operator==(const hsl_<H,S,L>& lhs, const hsl_<H,S,L>& rhs)
377  {
378  return lhs.hue() == rhs.hue()
379  && lhs.sat() == rhs.sat()
380  && lhs.lum() == rhs.lum();
381  }
382 
383  } // end of namespace mln::value
384 
385 
386  namespace convert
387  {
388 
389  namespace over_load
390  {
391 
392  inline
393  void
394  from_to_(const value::rgb<16>& from, value::hsl_<float,float,float>& to)
395  {
396  to = fun::v2v::f_rgb_to_hsl_f(from);
397  }
398 
399  inline
400  void
401  from_to_(const value::rgb<8>& from, value::hsl_<float,float,float>& to)
402  {
403  to = fun::v2v::f_rgb_to_hsl_f(from);
404  }
405 
406  } // end of namespace mln::convert::over_load
407 
408  } // end of namespace mln::convert
409 
410 
411 # endif // ! MLN_INCLUDE_ONLY
412 
413 
414 } // end of namespace mln
415 
416 #endif // ! MLN_VALUE_HSL_HH