$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
rgb32.hh
1 // Copyright (C) 2010, 2012, 2013 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_VALUE_QT_RGB32_HH
28 # define MLN_VALUE_QT_RGB32_HH
29 
34 
35 # include <mln/value/ops.hh>
36 
37 # include <mln/value/concept/vectorial.hh>
38 # include <mln/algebra/vec.hh>
39 
40 # include <mln/literal/zero.hh>
41 # include <mln/literal/black.hh>
42 # include <mln/literal/white.hh>
43 # include <mln/literal/grays.hh>
44 # include <mln/literal/colors.hh>
45 
46 /* Because of mutual dependencies between the implementations of
47  mln::value::int_u and mln::value::qt::rgb32, we have to ensure that
48  only the interfaces of the required classes are included here.
49  Implementations are included later, at the bottom of this file. */
50 
51 # ifdef MLN_INCLUDE_ONLY
52 # include <mln/value/int_u.hh>
53 # else
54 # define MLN_INCLUDE_ONLY
55 # include <mln/value/int_u.hh>
56 # undef MLN_INCLUDE_ONLY
57 # endif
58 
59 
60 namespace mln
61 {
62 
63  // Forward declaration.
64  namespace value { namespace qt { struct rgb32; } }
65 
66 
67 
68  namespace literal
69  {
71  struct black_t;
72  struct white_t;
73 
74  struct light_gray_t;
75  struct medium_gray_t;
76  struct dark_gray_t;
77 
78  struct red_t;
79  struct green_t;
80  struct blue_t;
81  struct brown_t;
82  struct lime_t;
83  struct orange_t;
84  struct pink_t;
85  struct purple_t;
86  struct teal_t;
87  struct violet_t;
88  struct cyan_t;
89  struct magenta_t;
90  struct yellow_t;
91  struct olive_t;
93  }
94 
95  namespace trait
96  {
97  template <>
98  struct set_precise_binary_< op::plus, mln::value::qt::rgb32, mln::value::qt::rgb32 >
99  {
100  typedef mln::value::qt::rgb32 ret;
101  };
102 
103  template <>
104  struct set_precise_binary_< op::minus, mln::value::qt::rgb32, mln::value::qt::rgb32 >
105  {
106  typedef mln::value::qt::rgb32 ret;
107  };
108 
109  template < typename S >
110  struct set_precise_binary_< op::times, mln::value::qt::rgb32, mln::value::scalar_<S> >
111  {
112  typedef mln::value::qt::rgb32 ret;
113  };
114 
115  template < typename S >
116  struct set_precise_binary_< op::div, mln::value::qt::rgb32, mln::value::scalar_<S> >
117  {
118  typedef mln::value::qt::rgb32 ret;
119  };
120 
121 
122  // FIXME : Is there any way more generic? a way to factor
123  // set_precise_binary_< op::div, mln::value::qt::rgb32, mln::value::scalar_<S> >
124  // and
125  // set_precise_binary_< op::div, mln::value::qt::rgb32, mln::value::int_u<m> >
126  // as for op::times.
127 
128  template < unsigned m >
129  struct set_precise_binary_< op::times, mln::value::qt::rgb32, mln::value::int_u<m> >
130  {
131  typedef mln::value::qt::rgb32 ret;
132  };
133 
134  template < unsigned m >
135  struct set_precise_binary_< op::div, mln::value::qt::rgb32, mln::value::int_u<m> >
136  {
137  typedef mln::value::qt::rgb32 ret;
138  };
139 
140 
141  template <>
142  struct value_< mln::value::qt::rgb32 >
143  {
144  enum {
145  dim = 3,
146  nbits = 32,
147  card = mln_value_card_from_(nbits)
148  };
149 
150  typedef trait::value::nature::vectorial nature;
151  typedef trait::value::kind::color kind;
152  typedef trait::value::quant::high /*mln_value_quant_from_(card)*/ quant;
153 
154  typedef void comp;
155  typedef mln::value::int_u<8> comp_0;
156  typedef mln::value::int_u<8> comp_1;
157  typedef mln::value::int_u<8> comp_2;
158 
159  template <typename V> static comp_0 get_comp_0(const V& v) { return v.red(); }
160  template <typename V> static comp_1 get_comp_1(const V& v) { return v.green(); }
161  template <typename V> static comp_2 get_comp_2(const V& v) { return v.blue(); }
162 
163  typedef algebra::vec<dim, float> sum;
164 
165  static const char* name()
166  {
167  static std::string s = "qt_rgb32";
168  return s.c_str();
169  }
170 
171  };
172 
173  } // end of namespace trait
174 
175 
176 
177  namespace value
178  {
179 
180  namespace qt
181  {
182 
193  struct rgb32
194  :
195  public Vectorial< rgb32 >,
196  public internal::value_like_< algebra::vec< 3, int_u<8> >, // Equivalent.
197  algebra::vec< 3, int_u<8> >, // Encoding.
198  algebra::vec< 3, int >, // Interoperation.
199  rgb32 > // Exact.
200  {
201  public:
202 
203  typedef int_u<8> red_t;
204  typedef int_u<8> green_t;
205  typedef int_u<8> blue_t;
206 
208  int_u<8> red() const { return this->v_[2]; }
209  int_u<8>& red() { return this->v_[2]; }
210 
211  int_u<8> green() const { return this->v_[1]; }
212  int_u<8>& green() { return this->v_[1]; }
213 
214  int_u<8> blue() const { return this->v_[0]; }
215  int_u<8>& blue() { return this->v_[0]; }
216 
217  int_u<8> comp(unsigned k) const { return this->v_[k]; }
218  int_u<8>& comp(unsigned k) { return this->v_[k]; }
220 
222  rgb32();
223 
225  rgb32(int r, int g, int b);
226 
230  rgb32(const algebra::vec<3, int_u<8> >& rhs);
232 
233  // Conversion to the interoperation type.
234  operator algebra::vec<3, int>() const;
235  // Conversion to the sum type.
236  operator algebra::vec<3, float>() const;
237 
239  rgb32(const mln::literal::zero_t&);
240 
243 
247 
248  rgb32(const mln::literal::red_t&);
249  rgb32(const mln::literal::blue_t&);
252  rgb32(const mln::literal::lime_t&);
254  rgb32(const mln::literal::pink_t&);
256  rgb32(const mln::literal::teal_t&);
258  rgb32(const mln::literal::cyan_t&);
263 
265  rgb32& operator=(const rgb32& rhs);
266 
268  static const rgb32 zero;
269 
270 
273  };
274 
275 
276 
283 
284  std::ostream& operator<<(std::ostream& ostr, const rgb32& c);
285 
286 
287  std::istream& operator>>(std::istream& istr, rgb32& c);
288 
289 
290  /* FIXME: We should not need to define these operators, thanks to
291  Milena's global operator resolution mechanism based on
292  mln::Object. See what prevent us to use this mechanism. */
293 
294  /* FIXME: Cannot work for i negative; add traits! (2008-02-16,
295  Roland: What does this comment mean?) */
296 
299 
301  operator+(const rgb32& lhs, const rgb32& rhs);
302 
303 
305  operator+(const rgb32::interop& lhs, const rgb32& rhs);
306 
307 
309  operator+(const rgb32& lhs, const rgb32::interop& rhs);
311 
314 
316  operator-(const rgb32& lhs, const rgb32& rhs);
317 
318 
320  operator-(const rgb32::interop& lhs, const rgb32& rhs);
321 
322 
324  operator-(const rgb32& lhs, const rgb32::interop& rhs);
326 
329  template <typename S>
330  inline
332  operator*(const rgb32& lhs, const mln::value::scalar_<S>& s);
333 
334  template <typename S>
335  inline
337  operator*(const mln::value::scalar_<S>& s, const rgb32& lhs);
339 
342  template <typename S>
343  inline
345  operator/(const rgb32& lhs, const mln::value::scalar_<S>& s);
347 
348 
350  void from_to_(const rgb32& from, bool& to);
351 
353  void from_to_(const bool& from, value::qt::rgb32& to);
354 
355  } // end of namespace mln::value::qt
356 
357  } // end of namespace mln::value
358 
359 } // end of namespace mln
360 
361 # ifndef MLN_INCLUDE_ONLY
362 
363 namespace mln
364 {
365 
366  namespace value
367  {
368 
369  namespace qt
370  {
371 
372 # ifndef MLN_WO_GLOBAL_VARS
373 
374  const rgb32 rgb32::zero(0,0,0);
375 
376 # endif // !MLN_WO_GLOBAL_VARS
377 
378 
379  /*---------------.
380  | Construction. |
381  `---------------*/
382 
383 
384  inline
385  rgb32::rgb32()
386  {
387  }
388 
389 
390  inline
391  rgb32::rgb32(const algebra::vec<3, int>& v)
392  {
393  this->v_[0] = v[2];
394  this->v_[1] = v[1];
395  this->v_[2] = v[0];
396  }
397 
398 
399  inline
400  rgb32::rgb32(const algebra::vec<3, unsigned>& v)
401  {
402  this->v_[0] = v[2];
403  this->v_[1] = v[1];
404  this->v_[2] = v[0];
405  }
406 
407 
408  inline
409  rgb32::rgb32(const algebra::vec<3, int_u<8> >& v)
410  {
411  this->v_[0] = v[2];
412  this->v_[1] = v[1];
413  this->v_[2] = v[0];
414  }
415 
416 
417  inline
418  rgb32::rgb32(const algebra::vec<3, float>& v)
419  {
420  this->v_[0] = unsigned(v[2]);
421  this->v_[1] = unsigned(v[1]);
422  this->v_[2] = unsigned(v[0]);
423  }
424 
425 
426  inline
427  rgb32::rgb32(int r, int g, int b)
428  {
429  mln_precondition(r >= 0);
430  mln_precondition(g >= 0);
431  mln_precondition(b >= 0);
432  mln_precondition(unsigned(r) <= mln_max(int_u<8>));
433  mln_precondition(unsigned(g) <= mln_max(int_u<8>));
434  mln_precondition(unsigned(b) <= mln_max(int_u<8>));
435  this->v_[0] = b;
436  this->v_[1] = g;
437  this->v_[2] = r;
438  }
439 
440 
441  inline
443  {
444  this->v_[0] = 0;
445  this->v_[1] = 0;
446  this->v_[2] = 0;
447  }
448 
449 
450  inline
452  {
453  this->v_[0] = mln_max(int_u<8>);
454  this->v_[1] = mln_max(int_u<8>);
455  this->v_[2] = mln_max(int_u<8>);
456  }
457 
458 
459  inline
461  {
462  this->v_[0] = 0;
463  this->v_[1] = 0;
464  this->v_[2] = 0;
465  }
466 
467 
468  inline
470  {
471  this->v_[0] = unsigned(mln_max(int_u<8>)) * 3 / 4;
472  this->v_[1] = unsigned(mln_max(int_u<8>)) * 3 / 4;
473  this->v_[2] = unsigned(mln_max(int_u<8>)) * 3 / 4;
474  }
475 
476 
477  inline
479  {
480  this->v_[0] = unsigned(mln_max(int_u<8>)) / 2;
481  this->v_[1] = unsigned(mln_max(int_u<8>)) / 2;
482  this->v_[2] = unsigned(mln_max(int_u<8>)) / 2;
483  }
484 
485 
486  inline
488  {
489  this->v_[0] = unsigned(mln_max(int_u<8>)) / 4;
490  this->v_[1] = unsigned(mln_max(int_u<8>)) / 4;
491  this->v_[2] = unsigned(mln_max(int_u<8>)) / 4;
492  }
493 
494 
495  inline
497  {
498  this->v_[0] = 0;
499  this->v_[1] = 0;
500  this->v_[2] = mln_max(int_u<8>);
501  }
502 
503 
504  inline
506  {
507  this->v_[0] = 0;
508  this->v_[1] = mln_max(int_u<8>);
509  this->v_[2] = 0;
510  }
511 
512 
513  inline
515  {
516  this->v_[0] = mln_max(int_u<8>);
517  this->v_[1] = 0;
518  this->v_[2] = 0;
519  }
520 
521 
522  inline
524  {
525  this->v_[0] = unsigned(mln_max(int_u<8>)) / 4;
526  this->v_[1] = unsigned(mln_max(int_u<8>)) / 2;
527  this->v_[2] = unsigned(mln_max(int_u<8>)) * 3 / 4;
528  }
529 
530 
531  inline
533  {
534  this->v_[0] = 0;
535  this->v_[1] = mln_max(int_u<8>);
536  this->v_[2] = unsigned(mln_max(int_u<8>)) * 3 / 4;
537  }
538 
539 
540  inline
542  {
543  this->v_[0] = 0;
544  this->v_[1] = unsigned(mln_max(int_u<8>)) / 2;
545  this->v_[2] = mln_max(int_u<8>);
546  }
547 
548 
549  inline
551  {
552  this->v_[0] = unsigned(mln_max(int_u<8>)) * 3 / 4;
553  this->v_[1] = unsigned(mln_max(int_u<8>)) * 3 / 4;
554  this->v_[2] = mln_max(int_u<8>);
555  }
556 
557 
558  inline
560  {
561  this->v_[0] = unsigned(mln_max(int_u<8>)) / 4;
562  this->v_[1] = 0;
563  this->v_[2] = unsigned(mln_max(int_u<8>)) * 3 / 4;
564  }
565 
566 
567  inline
569  {
570  this->v_[0] = unsigned(mln_max(int_u<8>)) / 2;
571  this->v_[1] = unsigned(mln_max(int_u<8>)) / 2;
572  this->v_[2] = 0;
573  }
574 
575 
576  inline
578  {
579  this->v_[0] = unsigned(mln_max(int_u<8>)) / 2;
580  this->v_[1] = 0;
581  this->v_[2] = unsigned(mln_max(int_u<8>)) / 2;
582  }
583 
584 
585  inline
587  {
588  this->v_[0] = mln_max(int_u<8>);
589  this->v_[1] = mln_max(int_u<8>);
590  this->v_[2] = 0;
591  }
592 
593 
594  inline
596  {
597  this->v_[0] = mln_max(int_u<8>);
598  this->v_[1] = 0;
599  this->v_[2] = mln_max(int_u<8>);
600  }
601 
602 
603  inline
605  {
606  this->v_[0] = 0;
607  this->v_[1] = mln_max(int_u<8>);
608  this->v_[2] = mln_max(int_u<8>);
609  }
610 
611 
612  inline
614  {
615  this->v_[0] = 0;
616  this->v_[1] = unsigned(mln_max(int_u<8>)) / 2;
617  this->v_[2] = unsigned(mln_max(int_u<8>)) / 2;
618  }
619 
620 
621  inline
622  rgb32&
623  rgb32::operator=(const rgb32& rhs)
624  {
625  if (& rhs == this)
626  return *this;
627  this->v_ = rhs.v_;
628  return *this;
629  }
630 
631 
632  inline
633  rgb32::operator algebra::vec<3, int>() const
634  {
635  algebra::vec<3, int> out;
636  out[0] = this->v_[2];
637  out[1] = this->v_[1];
638  out[2] = this->v_[0];
639  return out;
640  }
641 
642  inline
643  rgb32::operator algebra::vec<3, float>() const
644  {
645  algebra::vec<3, float> out;
646  out[0] = this->v_[2];
647  out[1] = this->v_[1];
648  out[2] = this->v_[0];
649  return out;
650  }
651 
652 
653  /*------------.
654  | Operators. |
655  `------------*/
656 
657 
658  inline
660  operator+(const rgb32& lhs, const rgb32& rhs)
661  {
662  rgb32::interop tmp(lhs.to_interop() + rhs.to_interop());
663  return tmp;
664  }
665 
666 
667  inline
669  operator+(const rgb32& lhs, const rgb32::interop& rhs)
670  {
671  rgb32::interop tmp(lhs.to_interop() + rhs);
672  return tmp;
673  }
674 
675 
676  inline
678  operator+(const rgb32::interop& lhs, const rgb32& rhs)
679  {
680  rgb32::interop tmp(lhs + rhs.to_interop());
681  return tmp;
682  }
683 
684 
685  inline
687  operator-(const rgb32& lhs, const rgb32& rhs)
688  {
689  rgb32::interop tmp(lhs.to_interop() - rhs.to_interop());
690  return tmp;
691  }
692 
693 
694  inline
696  operator-(const rgb32& lhs, const rgb32::interop& rhs)
697  {
698  rgb32::interop tmp(lhs.to_interop() - rhs);
699  return tmp;
700  }
701 
702 
703  inline
705  operator-(const rgb32::interop& lhs, const rgb32& rhs)
706  {
707  rgb32::interop tmp(lhs - rhs.to_interop());
708  return tmp;
709  }
710 
711  template <typename S>
712  inline
714  operator*(const rgb32& lhs, const mln::value::scalar_<S>& s)
715  {
716  rgb32::interop tmp(lhs.to_interop() * s.to_equiv());
717  return tmp;
718  }
719 
720  template <typename S>
721  inline
723  operator*(const mln::value::scalar_<S>& s, const rgb32& lhs)
724  {
725  rgb32::interop tmp(s.to_equiv() * lhs.to_interop());
726  return tmp;
727  }
728 
729  template <typename S>
730  inline
732  operator/(const rgb32& lhs, const mln::value::scalar_<S>& s)
733  {
734  rgb32::interop tmp(lhs.to_interop() / s.to_equiv());
735  return tmp;
736  }
737 
738 
739  inline
740  std::ostream& operator<<(std::ostream& ostr, const rgb32& v)
741  {
742  return ostr << '(' << debug::format(v.red())
743  << ',' << debug::format(v.green())
744  << ',' << debug::format(v.blue())
745  << ')';
746  }
747 
748 
749  inline
750  std::istream& operator>>(std::istream& istr, rgb32& c)
751  {
752  return istr >> c.red() >> c.green() >> c.blue();
753  }
754 
755 
756  // Conversions
757 
758  inline
759  void from_to_(const rgb32& from, bool& to)
760  {
761  to = ((from == literal::black) ? false : true);
762  }
763 
764  inline
765  void from_to_(const bool& from, value::qt::rgb32& to)
766  {
767  if (from)
768  to = literal::white;
769  else
770  to = literal::black;
771  }
772 
773  } // end of namespace mln::value::qt
774 
775  } // end of namespace mln::value
776 
777 } // end of namespace mln
778 
779 # endif // ! MLN_INCLUDE_ONLY
780 
781 
782 // Delayed inclusion of mln::value::int_u_'s implementation.
783 # ifndef MLN_INCLUDE_ONLY
784 # include <mln/value/int_u.hxx>
785 # endif // ! MLN_INCLUDE_ONLY
786 
787 
788 #endif // ! MLN_VALUE_QT_RGB32_HH