Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
rgb32.hh
1 // Copyright (C) 2010 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_QT_RGB32_HH
27 # define MLN_VALUE_QT_RGB32_HH
28 
29 # include <cstring>
30 
31 # include <mln/value/ops.hh>
32 
33 # include <mln/value/concept/vectorial.hh>
34 # include <mln/value/int_u.hh>
35 # include <mln/algebra/vec.hh>
36 
37 # include <mln/value/rgb8.hh>
38 
39 # include <mln/literal/zero.hh>
40 # include <mln/literal/black.hh>
41 # include <mln/literal/white.hh>
42 
43 namespace mln
44 {
45 
46  // Forward declaration.
47  namespace value { namespace qt { struct rgb32; } }
48 
49 
50 
51  namespace literal
52  {
54  struct black_t;
55  struct white_t;
56 
57  struct light_gray_t;
58  struct medium_gray_t;
59  struct dark_gray_t;
60 
61  struct red_t;
62  struct green_t;
63  struct blue_t;
64  struct brown_t;
65  struct lime_t;
66  struct orange_t;
67  struct pink_t;
68  struct purple_t;
69  struct teal_t;
70  struct violet_t;
71  struct cyan_t;
72  struct magenta_t;
73  struct yellow_t;
74  struct olive_t;
76  }
77 
78 
79  namespace convert
80  {
81 
82  namespace over_load
83  {
84 
85  // int_u -> rgb.
86  template <unsigned m>
87  void from_to_(const value::int_u<m>& from, value::qt::rgb32& to);
88 
89  // hsl -> rgb32.
90  template <typename H, typename S, typename L>
91  void from_to_(const value::hsl_<H,S,L>&, value::qt::rgb32& to);
92 
93  // rgb32 -> bool.
94  void from_to_(const value::qt::rgb32& from, bool& to);
95 
96 
97  // bool -> rgb32.
98  void from_to_(const bool& from, value::qt::rgb32& to);
99 
100 
101  } // end of namespace mln::convert::over_load
102 
103  } // end of namespace mln::convert
104 
105 
106  namespace trait
107  {
108  template <>
109  struct set_precise_binary_< op::plus, mln::value::qt::rgb32, mln::value::qt::rgb32 >
110  {
111  typedef mln::value::qt::rgb32 ret;
112  };
113 
114  template <>
115  struct set_precise_binary_< op::minus, mln::value::qt::rgb32, mln::value::qt::rgb32 >
116  {
117  typedef mln::value::qt::rgb32 ret;
118  };
119 
120  template < typename S >
121  struct set_precise_binary_< op::times, mln::value::qt::rgb32, mln::value::scalar_<S> >
122  {
123  typedef mln::value::qt::rgb32 ret;
124  };
125 
126  template < typename S >
127  struct set_precise_binary_< op::div, mln::value::qt::rgb32, mln::value::scalar_<S> >
128  {
129  typedef mln::value::qt::rgb32 ret;
130  };
131 
132 
133  // FIXME : Is there any way more generic? a way to factor
134  // set_precise_binary_< op::div, mln::value::qt::rgb32, mln::value::scalar_<S> >
135  // and
136  // set_precise_binary_< op::div, mln::value::qt::rgb32, mln::value::int_u<m> >
137  // as for op::times.
138 
139  template < unsigned m >
140  struct set_precise_binary_< op::times, mln::value::qt::rgb32, mln::value::int_u<m> >
141  {
142  typedef mln::value::qt::rgb32 ret;
143  };
144 
145  template < unsigned m >
146  struct set_precise_binary_< op::div, mln::value::qt::rgb32, mln::value::int_u<m> >
147  {
148  typedef mln::value::qt::rgb32 ret;
149  };
150 
151 
152  template <>
153  struct value_< mln::value::qt::rgb32 >
154  {
155  enum {
156  dim = 3,
157  nbits = 32,
158  card = mln_value_card_from_(nbits)
159  };
160 
161  typedef trait::value::nature::vectorial nature;
162  typedef trait::value::kind::color kind;
163  typedef trait::value::quant::high /*mln_value_quant_from_(card)*/ quant;
164 
165  typedef void comp;
166  typedef mln::value::int_u<8> comp_0;
167  typedef mln::value::int_u<8> comp_1;
168  typedef mln::value::int_u<8> comp_2;
169 
170  template <typename V> static comp_0 get_comp_0(const V& v) { return v.red(); }
171  template <typename V> static comp_1 get_comp_1(const V& v) { return v.green(); }
172  template <typename V> static comp_2 get_comp_2(const V& v) { return v.blue(); }
173 
174  typedef algebra::vec<dim, float> sum;
175 
176  static const char* name()
177  {
178  static std::string s = "qt_rgb32";
179  return s.c_str();
180  }
181 
182  };
183 
184  } // end of namespace trait
185 
186 
187 
188  namespace value
189  {
190 
191  namespace qt
192  {
193 
196 
197  struct rgb32
198  :
199  public Vectorial< rgb32 >,
200  public internal::value_like_< algebra::vec< 3, int_u<8> >, // Equivalent.
201  algebra::vec< 3, int_u<8> >, // Encoding.
202  algebra::vec< 3, int >, // Interoperation.
203  rgb32 > // Exact.
204  {
205  public:
206 
207  typedef int_u<8> red_t;
208  typedef int_u<8> green_t;
209  typedef int_u<8> blue_t;
210 
212  int_u<8> red() const { return this->v_[2]; }
213  int_u<8>& red() { return this->v_[2]; }
214 
215  int_u<8> green() const { return this->v_[1]; }
216  int_u<8>& green() { return this->v_[1]; }
217 
218  int_u<8> blue() const { return this->v_[0]; }
219  int_u<8>& blue() { return this->v_[0]; }
220 
221  int_u<8> comp(unsigned k) const { return this->v_[k]; }
222  int_u<8>& comp(unsigned k) { return this->v_[k]; }
224 
226  rgb32();
227 
229  rgb32(int r, int g, int b);
230 
232  rgb32(const algebra::vec<3, int>& rhs);
233  rgb32(const algebra::vec<3, unsigned>& rhs);
234  rgb32(const algebra::vec<3, int_u<8> >& rhs);
235  rgb32(const algebra::vec<3, float>& rhs);
236 
237  // Conversion to the interoperation type.
238  operator algebra::vec<3, int>() const;
239  // Conversion to the sum type.
240  operator algebra::vec<3, float>() const;
241 
243  rgb32(const mln::literal::zero_t&);
244 
247 
249  rgb32(const mln::literal::medium_gray_t&);
250  rgb32(const mln::literal::dark_gray_t&);
251 
252  rgb32(const mln::literal::red_t&);
253  rgb32(const mln::literal::blue_t&);
256  rgb32(const mln::literal::lime_t&);
258  rgb32(const mln::literal::pink_t&);
260  rgb32(const mln::literal::teal_t&);
262  rgb32(const mln::literal::cyan_t&);
267 
269  rgb32& operator=(const rgb32& rhs);
270 
272  static const rgb32 zero;
273 
274 
276  int_u<8> alpha_;
277  };
278 
279 
280 
287 
288  std::ostream& operator<<(std::ostream& ostr, const rgb32& c);
289 
290 
291  std::istream& operator>>(std::istream& istr, rgb32& c);
292 
293 
294  /* FIXME: We should not need to define these operators, thanks to
295  Milena's global operator resolution mechanism based on
296  mln::Object. See what prevent us to use this mechanism. */
297 
298  /* FIXME: Cannot work for i negative; add traits! (2008-02-16,
299  Roland: What does this comment mean?) */
300 
303 
304  rgb32::interop
305  operator+(const rgb32& lhs, const rgb32& rhs);
306 
307 
308  rgb32::interop
309  operator+(const rgb32::interop& lhs, const rgb32& rhs);
310 
311 
312  rgb32::interop
313  operator+(const rgb32& lhs, const rgb32::interop& rhs);
315 
318 
319  rgb32::interop
320  operator-(const rgb32& lhs, const rgb32& rhs);
321 
322 
323  rgb32::interop
324  operator-(const rgb32::interop& lhs, const rgb32& rhs);
325 
326 
327  rgb32::interop
328  operator-(const rgb32& lhs, const rgb32::interop& rhs);
330 
333  template <typename S>
334  inline
335  rgb32::interop
336  operator*(const rgb32& lhs, const mln::value::scalar_<S>& s);
337 
338  template <typename S>
339  inline
340  rgb32::interop
341  operator*(const mln::value::scalar_<S>& s, const rgb32& lhs);
343 
346  template <typename S>
347  inline
348  rgb32::interop
349  operator/(const rgb32& lhs, const mln::value::scalar_<S>& s);
351 
352 
353  } // end of namespace mln::value::qt
354 
355  } // end of namespace mln::value
356 
357 } // end of namespace mln
358 
359 
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
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>) * 0.75);
472  this->v_[1] = unsigned(mln_max(int_u<8>) * 0.75);
473  this->v_[2] = unsigned(mln_max(int_u<8>) * 0.75);
474  }
475 
476 
477  inline
478  rgb32::rgb32(const mln::literal::medium_gray_t&)
479  {
480  this->v_[0] = unsigned(mln_max(int_u<8>) * 0.50);
481  this->v_[1] = unsigned(mln_max(int_u<8>) * 0.50);
482  this->v_[2] = unsigned(mln_max(int_u<8>) * 0.50);
483  }
484 
485 
486  inline
487  rgb32::rgb32(const mln::literal::dark_gray_t&)
488  {
489  this->v_[0] = unsigned(mln_max(int_u<8>) * 0.25);
490  this->v_[1] = unsigned(mln_max(int_u<8>) * 0.25);
491  this->v_[2] = unsigned(mln_max(int_u<8>) * 0.25);
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>) * 0.25);
526  this->v_[1] = unsigned(mln_max(int_u<8>) * 0.50);
527  this->v_[2] = unsigned(mln_max(int_u<8>) * 0.75);
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>) * 0.75);
537  }
538 
539 
540  inline
542  {
543  this->v_[0] = 0;
544  this->v_[1] = unsigned(mln_max(int_u<8>) * 0.50);
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>) * 0.75);
553  this->v_[1] = unsigned(mln_max(int_u<8>) * 0.75);
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>) * 0.25);
562  this->v_[1] = 0;
563  this->v_[2] = unsigned(mln_max(int_u<8>) * 0.75);
564  }
565 
566 
567  inline
569  {
570  this->v_[0] = unsigned(mln_max(int_u<8>) * 0.50);
571  this->v_[1] = unsigned(mln_max(int_u<8>) * 0.50);
572  this->v_[2] = 0;
573  }
574 
575 
576  inline
578  {
579  this->v_[0] = unsigned(mln_max(int_u<8>) * 0.50);
580  this->v_[1] = 0;
581  this->v_[2] = unsigned(mln_max(int_u<8>) * 0.50);
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>) * 0.50);
617  this->v_[2] = unsigned(mln_max(int_u<8>) * 0.50);
618  }
619 
620 
621  inline
622  rgb32&
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
659  rgb32::interop
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
668  rgb32::interop
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
677  rgb32::interop
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
686  rgb32::interop
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
695  rgb32::interop
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
704  rgb32::interop
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
713  rgb32::interop
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
722  rgb32::interop
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
731  rgb32::interop
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  } // end of namespace mln::value::qt
756 
757  } // end of namespace mln::value
758 
759 
760  namespace convert
761  {
762 
763  namespace over_load
764  {
765 
766  // int_u -> qt::rgb32
767  template <unsigned m>
768  void
769  from_to_(const value::int_u<m>& from, value::qt::rgb32& to)
770  {
771  mlc_bool(m <= 8)::check();
772  to = value::qt::rgb32(from, from, from);
773  }
774 
775 
776  // hsl -> rgb8.
777  template <typename H, typename S, typename L>
778  void from_to_(const value::hsl_<H,S,L>& from, value::qt::rgb32& to)
779  {
781  to = v.to_equiv();
782  }
783 
784 
785  // qt::rgb32 -> bool
786  inline
787  void from_to_(const value::qt::rgb32& from, bool& to)
788  {
789  to = ((from == literal::black) ? false : true);
790  }
791 
792 
793  // bool -> qt::rgb32
794  inline
795  void from_to_(const bool& from, value::qt::rgb32& to)
796  {
797  if (from)
798  to = literal::white;
799  else
800  to = literal::black;
801  }
802 
803 
804  } // end of namespace mln::convert::over_load
805 
806  } // end of namespace mln::convert
807 
808 } // end of namespace mln
809 
810 # endif // ! MLN_INCLUDE_ONLY
811 
812 
813 #endif // ! MLN_VALUE_QT_RGB32_HH