$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
graylevel.hh
1 // Copyright (C) 2006, 2007, 2008, 2009, 2013 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_GRAYLEVEL_HH
28 # define MLN_VALUE_GRAYLEVEL_HH
29 
33 
34 # include <iostream>
35 
36 # include <mln/value/ops.hh>
37 
38 # include <mln/core/contract.hh>
39 # include <mln/metal/math/pow.hh>
40 # include <mln/metal/math/max.hh>
41 # include <mln/metal/bexpr.hh>
42 # include <mln/literal/ops.hh>
43 
44 # include <mln/value/graylevel_f.hh>
45 # include <mln/value/int_u.hh>
46 # include <mln/trait/value_.hh>
47 
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  {
62 
64  namespace internal
65  {
66  template <unsigned n> class gray_;
67  struct gray_f;
68  template <unsigned n_src, unsigned n_dest>
69  long convert(int val);
70  }
71  template <unsigned n> struct graylevel;
72  struct float01_f;
74  }
75 
76 
77 
78  namespace trait
79  {
80 
81  template < unsigned n, unsigned m >
82  struct set_precise_binary_< op::plus, mln::value::graylevel<n>, mln::value::graylevel<m> >
83  {
85  };
86 
87  template < unsigned n, unsigned m >
88  struct set_precise_binary_< op::minus, mln::value::graylevel<n>, mln::value::graylevel<m> >
89  {
91  };
92 
93  template < unsigned n, unsigned m >
94  struct set_precise_binary_< op::times, mln::value::graylevel<n>, mln::value::graylevel<m> >
95  {
97  };
98 
99  template < unsigned n, unsigned m >
100  struct set_precise_binary_< op::div, mln::value::graylevel<n>, mln::value::graylevel<m> >
101  {
103  };
104 
105  template < unsigned n, typename I >
106  struct set_binary_< op::times,
109  {
111  };
112 
113  template < typename I, unsigned n >
114  struct set_binary_< op::times,
117  {
119  };
120 
121 
122  template < unsigned n, typename F >
123  struct set_binary_< op::times,
126  {
128  };
129 
130  template < typename F, unsigned n >
131  struct set_binary_< op::times,
134  {
136  };
137 
138 
139  template < unsigned n, typename S >
140  struct set_precise_binary_< op::times, mln::value::graylevel<n>, mln::value::scalar_<S> >
141  {
142  typedef mln_value_equiv(S) E;
143  typedef mln::metal::or_< mlc_equal(E, float), mlc_equal(E, double) > is_float;
144  typedef mlc_if(is_float, mln::value::internal::gray_f, mln::value::internal::gray_<n>) ret;
145  };
146 
147  template < unsigned n, typename S >
148  struct set_precise_binary_< op::div, mln::value::graylevel<n>, mln::value::scalar_<S> >
149  {
150  typedef mln::value::internal::gray_f ret;
151  };
152 
153  // 'graylevel<n>' as a value.
154 
155  template <unsigned n>
156  struct value_< mln::value::graylevel<n> >
157  {
158  private:
159  typedef mln::value::graylevel<n> self_;
160  public:
161 
162  enum {
163  dim = 1,
164  nbits = n,
165  card = mln_value_card_from_(n)
166  };
167 
168  typedef trait::value::nature::integer nature; // FIXME: Or scalar?.
169  typedef trait::value::kind::gray kind;
170  typedef mln_value_quant_from_(card) quant;
171 
172  static const self_ min() { return 0; }
173  static const self_ max() { return card - 1; }
174  static const self_ epsilon() { return 0; }
175 
176  typedef mln::value::int_u<n> comp;
177 
178  typedef float sum;
179  };
180 
181  } // end of namespace mln::trait
182 
183 
184 
185  namespace value
186  {
187 
189 
190  // Return types of the operators +-*/.
191 
192  // Operators + - return the interoperability type to allow
193  // operations like (gl8(255) + gl8(255)) / 2. + - with int and
194  // float are not allowed.
195 
196  // If you really need to act with the value
197  // of the gray_<n> (the encoding). use the to_enc() method.
198  //
199 
200  // |--------------------------------------------|
201  // | + || gl | glf |gray_n | int | float |
202  // |============================================|
203  // |gl ||gray_n|gray_f |gray_n | X | X |
204  // |--------------------------------------------|
205  // |glf || |gray_f |gray_f | X | X |
206  // |--------------------------------------------|
207  // |gray|| |gray_n | X | X |
208  // |--------------------------------------------|
209 
210  // |--------------------------------------------|
211  // | - || gl | glf |gray_n | int | float |
212  // |============================================|
213  // |gl ||gray_n|gray_f |gray_n | X | X |
214  // |--------------------------------------------|
215  // |glf || |gray_f |gray_f | X | X |
216  // |--------------------------------------------|
217  // |gray|| |gray_n | X | X |
218  // |--------------------------------------------|
219 
220  // |--------------------------------------------|
221  // | * || gl | glf |gray_n | int | float |
222  // |============================================|
223  // |gl ||gray_n|gray_f |gray_n |gray_n |gray_f |
224  // |--------------------------------------------|
225  // |glf || |gray_f |gray_f |gray_f |gray_f |
226  // |--------------------------------------------|
227  // |gray|| |gray_n |gray_n |gray_f |
228  // |--------------------------------------------|
229 
230  // |--------------------------------------------|
231  // | / || gl | glf |gray_n | int | float |
232  // |============================================|
233  // |gl ||gray_f|gray_f |gray_n |gray_f |gray_f |
234  // |--------------------------------------------|
235  // |glf || |gray_f |gray_f |gray_f |gray_f |
236  // |--------------------------------------------|
237  // |gray|| |gray_f |gray_f |gray_f |
238  // |--------------------------------------------|
239 
240  // Valid Conversions are :
241 
242  // gray_f -> gray_<n>
243  // gray_f -> graylevel<n>
244  // gray_f -> graylevel_f
245 
246  // gray_<n> -> gray_f
247  // gray_<n> -> graylevel<n>
248  // gray_<n> -> graylevel_f
249 
250  // graylevel_f -> gray_f
251  // graylevel_f -> graylevel<n>
252 
253  // graylevel<n> -> gray_<n>
254  // graylevel<n> -> graylevel_f
255 
256 
257  template <unsigned n>
258  struct graylevel
259  :
260  public Integer< graylevel<n> >,
261 
262  public internal::value_like_< int_u<n>, // Equivalent.
263  mln_enc(int_u<n>), // Encoding.
264  internal::gray_<n>,// Interoperation.
265  graylevel<n> > // Exact.
266  {
267 
269  graylevel();
271  graylevel(const graylevel<n>& rhs);
273  graylevel<n>& operator=(const graylevel<n>& rhs);
274 
276  graylevel(int val);
278  graylevel<n>& operator=(int val);
279 
281  template <unsigned m>
282  graylevel(const graylevel<m>& rhs);
284  template <unsigned m>
285  graylevel<n>& operator=(const graylevel<m>& rhs);
286 
289  graylevel(const mln::literal::black_t&);
290  graylevel(const mln::literal::medium_gray_t&);
291  graylevel(const mln::literal::white_t&);
293 
294 
297  graylevel<n>& operator=(const mln::literal::black_t&);
298  graylevel<n>& operator=(const mln::literal::medium_gray_t&);
299  graylevel<n>& operator=(const mln::literal::white_t&);
301 
302 
304  unsigned value() const;
305 
307  float to_float() const;
308  };
309 
310 
311 
312  namespace internal
313  {
314  // Fwd decl;
315  template <typename T> struct convert_;
316 
317  // convert for graylevel.
318  template <unsigned n>
319  struct convert_< graylevel<n> >
320  {
321  static graylevel<n> value_at_index(unsigned i);
322  static unsigned index_of_value(graylevel<n> v);
323  };
324 
325  } // end of namespace mln::value::internal
326 
327 
329  template <unsigned n>
330  std::ostream& operator<<(std::ostream& ostr, const graylevel<n>& g);
331 
332  // graylevel<n> + graylevel<m>.
333  template <unsigned n, unsigned m>
334  mln_trait_op_plus(graylevel<n>, graylevel<m>)
335  operator+(const graylevel<n>& lhs, const graylevel<m>& rhs);
336 
337  // graylevel<n> + Another type (doesn't compile).
338  template <unsigned n, typename I>
339  void
340  operator+(const graylevel<n>& lhs, const I& i);
341 
342  // graylevel<n> + Another type (doesn't compile).
343  template <unsigned n, typename I>
344  void
345  operator+(const I& i, const graylevel<n>& rhs);
346 
347  // graylevel<n> - graylevel<m>.
348  template <unsigned n, unsigned m>
349  mln_trait_op_minus(graylevel<n>, graylevel<m>)
350  operator-(const graylevel<n>& lhs, const graylevel<m>& rhs);
351 
352  // graylevel<n> - Another type (doesn't compile).
353  template <unsigned n, typename I>
354  void
355  operator-(const graylevel<n>& lhs, const I& i);
356 
357  // graylevel<n> - Another type (doesn't compile).
358  template <unsigned n, typename I>
359  void
360  operator-(const I& i, const graylevel<n>& rhs);
361 
362  // graylevel<n> * graylevel<m>.
363  template <unsigned n, unsigned m>
364  mln_trait_op_times(graylevel<n>, graylevel<m>)
365  operator*(const graylevel<n>& lhs, const graylevel<m>& rhs);
366 
367  // With Builtins.
368 
369  // graylevel<n> * T.
370  template <unsigned n, typename T>
371  mln_trait_op_times(graylevel<n>, T)
372  operator*(const graylevel<n>& lhs, const T& rhs);
373 
374  // T * graylevel<n>.
375  template <unsigned n, typename T>
376  mln_trait_op_times(graylevel<n>, T)
377  operator*(const T& lhs, const graylevel<n>& rhs);
378 
379  // graylevel<n> / T.
380  template <unsigned n, typename T>
381  internal::gray_f
382  //mln_trait_op_div(graylevel<n>, T).
383  operator/(const graylevel<n>& lhs, const T& rhs);
384 
385  // With Integer.
386 
387  // graylevel<n> * Integer<I>.
388  template <unsigned n, typename I>
389  mln_trait_op_times(graylevel<n>, I)
390  operator*(const graylevel<n>& lhs, const Integer<I>& rhs);
391 
392  // Integer<I> * graylevel<n>.
393  template <typename I, unsigned n>
394  mln_trait_op_times(I, graylevel<n>)
395  operator*(const Integer<I>& lhs, const graylevel<n>& rhs);
396 
397  // graylevel<n> / Integer<I>.
398  template <unsigned n, typename I>
399  mln_trait_op_div(graylevel<n>, I)
400  operator/(const graylevel<n>& lhs, const Integer<I>& rhs);
401 
402  // Integer<I> / graylevel<n>.
403  template <typename I, unsigned n>
404  mln_trait_op_div(I, graylevel<n>)
405  operator/(const Integer<I>& lhs, const graylevel<n>& rhs);
406 
407  // With Floating.
408 
409  // graylevel<n> * Floating<F>.
410  template <unsigned n, typename F>
411  mln_trait_op_times(graylevel<n>, F)
412  operator*(const graylevel<n>& lhs, const Floating<F>& rhs);
413 
414  // Floating<F>, graylevel<n>.
415  template <typename F, unsigned n>
416  mln_trait_op_times(F, graylevel<n>)
417  operator*(const Floating<F>& lhs, const graylevel<n>& rhs);
418 
419 
420  // graylevel<n> / Floating<F>.
421  template <unsigned n, typename F>
422  mln_trait_op_div(graylevel<n>, F)
423  operator/(const graylevel<n>& lhs, const Floating<F>& rhs);
424 
425  // Floating<F> / graylevel<n>.
426  template <typename F, unsigned n>
427  mln_trait_op_div(F, graylevel<n>)
428  operator/(const Floating<F>& lhs, const graylevel<n>& rhs);
429 
430 # ifndef MLN_INCLUDE_ONLY
431 
432  // Graylevel<n>.
433 
434 
435  template <unsigned n>
436  inline
438  {
439  }
440 
441 
442  template <unsigned n>
443  inline
444  graylevel<n>::graylevel(int val)
445  {
446  mln_precondition(val >= 0);
447  mln_precondition(unsigned(val) <= mln_max(mln_enc(int_u<n>)));
448  this->v_ = val;
449  }
450 
451  template <unsigned n>
452  inline
453  graylevel<n>&
454  graylevel<n>::operator=(int val)
455  {
456  mln_precondition(val >= 0);
457  mln_precondition(unsigned(val) <= mln_max(mln_enc(int_u<n>)));
458  this->v_ = val;
459  return *this;
460  }
461 
462  template <unsigned n>
463  inline
464  graylevel<n>::graylevel(const graylevel<n>& rhs) :
465  Integer< graylevel<n> >()
466  {
467  this->v_ = rhs.v_;
468  }
469 
470  template <unsigned n>
471  inline
472  graylevel<n>&
473  graylevel<n>::operator=(const graylevel<n>& rhs)
474  {
475  this->v_ = rhs.v_;
476  return *this;
477  }
478 
479  template <unsigned n>
480  template <unsigned m>
481  inline
482  graylevel<n>::graylevel(const graylevel<m>& rhs)
483  {
484  this->v_ = internal::convert<m, n>(rhs.value());
485  }
486 
487  template <unsigned n>
488  template <unsigned m>
489  inline
490  graylevel<n>&
491  graylevel<n>::operator=(const graylevel<m>& rhs)
492  {
493  this->v_ = internal::convert<m, n>(rhs.value());
494  return *this;
495  }
496 
497 
498  template <unsigned n>
499  inline
500  graylevel<n>::graylevel(const mln::literal::black_t&)
501  {
502  this->v_ = 0;
503  }
504 
505  template <unsigned n>
506  inline
507  graylevel<n>&
508  graylevel<n>::operator=(const mln::literal::black_t&)
509  {
510  this->v_ = 0;
511  return *this;
512  }
513 
514  template <unsigned n>
515  inline
516  graylevel<n>::graylevel(const mln::literal::medium_gray_t&)
517  {
518  this->v_ = metal::math::pow_int<2, n - 1>::value;
519  }
520 
521  template <unsigned n>
522  inline
523  graylevel<n>&
524  graylevel<n>::operator=(const mln::literal::medium_gray_t&)
525  {
526  this->v_ = metal::math::pow_int<2, n - 1>::value;
527  return *this;
528  }
529 
530 
531  template <unsigned n>
532  inline
533  graylevel<n>::graylevel(const mln::literal::white_t&)
534  {
535  this->v_ = mln_max(mln_enc(int_u<n>));
536  }
537 
538  template <unsigned n>
539  inline
540  graylevel<n>&
541  graylevel<n>::operator=(const mln::literal::white_t&)
542  {
543  this->v_ = mln_max(mln_enc(int_u<n>));
544  return *this;
545  }
546 
547  template <unsigned n>
548  inline
549  unsigned
550  graylevel<n>::value() const
551  {
552  return this->v_;
553  }
554 
555  template <unsigned n>
556  inline
557  float
558  graylevel<n>::to_float() const
559  {
560  static const float denom = float(metal::math::pow_int<2, n>::value) - 1.f;
561  return float(this->v_) / denom;
562  }
563 
564 
565 
566  namespace internal
567  {
568 
569  template <unsigned n>
570  inline
571  graylevel<n>
572  convert_< graylevel<n> >::value_at_index(unsigned i)
573  {
574  mln_assertion(i <= mln_max(mln_equiv(graylevel<n>)));
575  return graylevel<n>(i);
576  }
577 
578  template <unsigned n>
579  inline
580  unsigned
581  convert_< graylevel<n> >::index_of_value(graylevel<n> v)
582  {
583  return v.value();
584  }
585 
586  } // end of namespace mln::value::internal
587 
588  // Operators.
589 
590  template <unsigned n>
591  inline
592  std::ostream& operator<<(std::ostream& ostr, const graylevel<n>& g)
593  {
594  return ostr << g.value() << "/gl" << n; // FIXME: Be more explicit!
595  }
596 
597  // The remaining operators are in mln/value/internal/gray_.hh.
598 
599 # endif // ! MLN_INCLUDE_ONLY
600 
601  } // end of namespace mln::value
602 
603 } // end of namespace mln
604 
605 
606 #include <mln/value/internal/gray_f.hh>
607 #include <mln/value/internal/gray_.hh>
608 
609 #endif // ! MLN_VALUE_GRAYLEVEL_HH