Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
gray_f.hh
1 // Copyright (C) 2006, 2007, 2008, 2009, 2011 EPITA Research and
2 // Development 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_VALUE_INTERNAL_GRAY_F_HH
28 # define MLN_VALUE_INTERNAL_GRAY_F_HH
29 
33 
34 
35 # include <iostream>
36 
37 # include <mln/value/ops.hh>
38 
39 # include <mln/core/contract.hh>
40 # include <mln/metal/math/pow.hh>
41 # include <mln/metal/bexpr.hh>
42 # include <mln/literal/ops.hh>
43 
44 # include <mln/value/float01_f.hh>
45 # include <mln/trait/value_.hh>
46 
47 # include <mln/value/graylevel_f.hh>
48 
49 namespace mln
50 {
51 
52  namespace literal
53  {
55  struct black_t;
56  struct medium_gray_t;
57  struct white_t;
59  }
60  namespace value
61  {
63  namespace internal
64  {
65  template <unsigned n> class gray_;
66  struct gray_f;
67  }
68 
69  struct float01_f;
71  }
72 
73 
74 
75  namespace trait
76  {
77 
78 
79  template < template <class, class> class Name>
80  struct set_precise_binary_< Name, mln::value::internal::gray_f, mln::value::internal::gray_f >
81  {
82  typedef mln::value::internal::gray_f ret;
83  };
84 
85  template <>
86  struct set_precise_binary_< op::greater, mln::value::internal::gray_f, mln::value::internal::gray_f >
87  {
88  typedef bool ret;
89  };
90 
91  template <>
92  struct set_precise_binary_< op::eq, mln::value::internal::gray_f, mln::value::internal::gray_f >
93  {
94  typedef bool ret;
95  };
96 
97  // Necessary??
98 // template <typename F>
99 // struct set_binary_< op::eq,
100 // mln::value::Floating, mln::value::internal::gray_f,
101 // mln::value::Floating, F >
102 // {
103 // typedef bool ret;
104 // };
105 
107  template <typename T> struct value_;
108 
109  // 'gray_f' as a value.
110  template <>
111  struct value_<mln::value::internal::gray_f>
112  {
113  private:
114  typedef mln::value::internal::gray_f self_;
115  typedef float equiv_;
116 
117  public:
118 
119  enum {
120  nbits = mln_nbits(equiv_),
121  card = 0
122  };
123 
124  typedef trait::value::nature::floating nature;
125  typedef trait::value::kind::gray kind;
126  typedef mln_trait_value_quant_(equiv_) quant;
127 
128  static equiv_ min() { return 0; }
129  static equiv_ max() { return 1; }
130  static equiv_ epsilon() { return mln_epsilon(equiv_); }
131 
132  typedef float sum;
133  };
134 
135  } // end of namespace mln::trait
136 
137 
138 
139  namespace value
140  {
141 
142  namespace internal
143  {
144 
146  struct gray_f
147  :
148  public Floating< gray_f >,
149 
150  public internal::value_like_< float, // Equivalent.
151  float, // Encoding.
152  gray_f, // Interoperation.
153  gray_f > // Exact.
154  {
156  gray_f();
157 
159  gray_f(const gray_f& rhs);
160  gray_f& operator=(const gray_f& rhs);
162 
164  template <unsigned n>
165  gray_f(const gray_<n>& rhs);
166  template <unsigned n>
167  gray_f& operator=(const gray_<n>& rhs);
169 
171  gray_f(float val);
172  gray_f& operator=(float val);
174 
176  gray_f(const graylevel_f& val);
177  gray_f& operator=(const graylevel_f& val);
179 
181  template <unsigned m>
182  operator graylevel<m>() const;
183 
185  template <unsigned m>
186  operator gray_<m>() const;
187 
189  operator graylevel_f() const;
190 
192  float value() const;
193  };
194 
195  // Operators.
196 
198  std::ostream& operator<<(std::ostream& ostr, const gray_f& g);
199 
200  } // end of namespace mln::value::internal
201 
202  } // end of namespace mln::value
203 
204 } // end of namespace mln
205 
206 
207 # include <mln/value/internal/gray_.hh>
208 
209 
210 namespace mln
211 {
212 
213  namespace value
214  {
215 
216  namespace internal
217  {
218 
219 # ifndef MLN_INCLUDE_ONLY
220 
221  // gray_f.
222 
223  inline
224  gray_f::gray_f()
225  {
226  }
227 
228  inline
229  gray_f::gray_f(const gray_f& g)
230  : Floating<gray_f>()
231  {
232  this->v_ = g.v_;
233  }
234 
235  inline
236  gray_f&
237  gray_f::operator=(const gray_f& g)
238  {
239  this->v_ = g.v_;
240  return *this;
241  }
242 
243  template <unsigned n>
244  gray_f::gray_f(const gray_<n>& rhs)
245  {
246  static const float denom = float(metal::math::pow_int<2, n>::value) - 1.f;
247  this->v_ = float(rhs.value()) / denom;
248  }
249 
250  template <unsigned n>
251  gray_f&
252  gray_f::operator=(const gray_<n>& rhs)
253  {
254  static const float denom = float(metal::math::pow_int<2, n>::value) - 1.f;
255  this->v_ = float(rhs.value()) / denom;
256  return *this;
257  }
258 
259  inline
260  gray_f::gray_f(float val)
261  {
262  this->v_ = val;
263  }
264 
265  inline
266  gray_f&
267  gray_f::operator=(float val)
268  {
269  this->v_ = val;
270  return *this;
271  }
272 
273  inline
274  gray_f::gray_f(const graylevel_f& rhs)
275  {
276  this->v_ = rhs.value();
277  }
278 
279  inline
280  gray_f&
281  gray_f::operator=(const graylevel_f& rhs)
282  {
283  this->v_ = rhs.value();
284  return *this;
285  }
286 
287  template <unsigned m>
288  inline
289  gray_f::operator graylevel<m>() const
290  {
291  return graylevel<m>(int(round(this->v_ * (mlc_pow_int(2, m) - 1))));
292  }
293 
294 
295  template <unsigned m>
296  inline
297  gray_f::operator gray_<m>() const
298  {
299  return gray_<m>(int(round(this->v_ * (mlc_pow_int(2, m) - 1))));
300  }
301 
302  inline
303  gray_f::operator graylevel_f() const
304  {
305  return graylevel_f(this->v_);
306  }
307 
308  inline
309  float
310  gray_f::value() const
311  {
312  return this->v_;
313  }
314 
315  // Operators.
316 
317  inline
318  std::ostream& operator<<(std::ostream& ostr, const gray_f& g)
319  {
320  return ostr << g.value() << "/gl_f"; // FIXME: Be more explicit!
321  }
322 
323 # endif // ! MLN_INCLUDE_ONLY
324 
325  } // end of namespace mln::value::internal
326 
327 
328  // Graylevel_F operators.
329 
330  // Op glf == Int
331 
332  template <typename I>
333  inline
334  bool
335  operator==(const Integer<I>& lhs, const graylevel_f& rhs)
336  {
337  return rhs.value() == exact(lhs);
338  }
339 
340  // Op glf == glf
341  inline
342  bool
343  operator==(const graylevel_f& lhs, const graylevel_f& rhs)
344  {
345  return rhs.value() == lhs.value();
346  }
347 
348  // Op glf + glf
349  inline
350  mln_trait_op_plus_(graylevel_f, graylevel_f)
351  operator+(const graylevel_f& lhs, const graylevel_f& rhs)
352  {
353  return lhs.value() + rhs.value();
354  }
355 
356  // Op glf + gl<n>
357  template <unsigned n>
358  inline
359  mln_trait_op_plus(graylevel_f, graylevel<n>)
360  operator+(const graylevel_f& lhs, const graylevel<n>& rhs)
361  {
362  return lhs.value() + graylevel_f(rhs).value();
363  }
364 
365  // Op gl<n> + glf
366  template <unsigned n>
367  inline
368  mln_trait_op_plus(graylevel_f, graylevel<n>)
369  operator+(const graylevel<n>& lhs, const graylevel_f& rhs)
370  {
371  return rhs.value() + graylevel_f(lhs).value();
372  }
373 
374 
375  // Op glf + Another type
376  template <typename I>
377  inline
378  void
379  operator+(const graylevel_f& lhs, const I& i)
380  {
381  (void) lhs;
382  (void) i;
383  typename Object<I>::wrong_use_of_graylevel_f___Please_use_the__to_enc__method a;
384  }
385 
386 
387  // Op Another type + glf
388  template <typename I>
389  inline
390  void
391  operator+(const I& i, const graylevel_f& rhs)
392  {
393  (void) i;
394  (void) rhs;
395  typename Object<I>::wrong_use_of_graylevel_f___Please_use_the__to_enc__method a;
396  }
397 
398 
399  // Op glf - Another type
400  template <typename I>
401  inline
402  void
403  operator-(const graylevel_f& lhs, const I& i)
404  {
405  (void) lhs;
406  (void) i;
407  typename Object<I>::wrong_use_of_graylevel_f___Please_use_the__to_enc__method a;
408  }
409 
410 
411  // Op Another type - glf
412  template <typename I>
413  inline
414  void
415  operator-(const I& i, const graylevel_f& rhs)
416  {
417  (void) i;
418  (void) rhs;
419  typename Object<I>::wrong_use_of_graylevel_f___Please_use_the__to_enc__method a;
420  }
421 
422  // Op glf - glf
423 
424  inline
425  mln_trait_op_minus_(graylevel_f, graylevel_f)
426  operator-(const graylevel_f& lhs, const graylevel_f& rhs)
427  {
428  return lhs.value() - rhs.value();
429  }
430 
431  // Op glf * glf
432  inline
433  mln_trait_op_times_(graylevel_f, graylevel_f)
434  operator*(const graylevel_f& lhs, const graylevel_f& rhs)
435  {
436  return lhs.value() * rhs.value();
437  }
438 
439  // Op symm glf * Int
440 
441  template <typename I>
442  inline
443  mln_trait_op_times(graylevel_f, I)
444  operator*(const graylevel_f& lhs, const Integer<I>& rhs)
445  {
446  return lhs.value() * int(exact(rhs));
447  }
448 
449  template <typename I>
450  inline
451  mln_trait_op_times(I, graylevel_f)
452  operator*(const Integer<I>& lhs, const graylevel_f& rhs)
453  {
454  return rhs.value() * int(exact(lhs));
455  }
456 
457  // Op symm glf * Float
458 
459  template <typename F>
460  inline
461  mln_trait_op_times(graylevel_f, F)
462  operator*(const graylevel_f& lhs, const Floating<F>& rhs)
463  {
464  return lhs.value() * exact(rhs);
465  }
466 
467  template <typename F>
468  inline
469  mln_trait_op_times(F, graylevel_f)
470  operator*(const Floating<F>& lhs, const graylevel_f& rhs)
471  {
472  return rhs.value() * exact(lhs);
473  }
474 
475 
476 
477  // Op * scalar
478  template <typename S>
479  inline
480  mln_trait_op_times(graylevel_f, S)
481  operator*(const graylevel_f& lhs, const scalar_<S>& rhs)
482  {
483  return lhs.value() * rhs.to_equiv();
484  }
485 
486  // Op / scalar
487  template <typename S>
488  inline
489  mln_trait_op_div(graylevel_f, S)
490  operator/(const graylevel_f& lhs, const scalar_<S>& rhs)
491  {
492  mln_precondition(rhs.to_equiv() != S(0));
493  return lhs.value() / rhs.to_equiv();
494  }
495 
496  } // end of namespace mln::value
497 
498 } // end of namespace mln
499 
500 #endif // ! MLN_VALUE_INTERNAL_GRAY_F_HH