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