00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef MLN_VALUE_RGB_HH
00028 # define MLN_VALUE_RGB_HH
00029
00030
00031 # include <mln/value/ops.hh>
00032
00033 # include <mln/fun/v2v/hsl_to_rgb.hh>
00034 # include <mln/value/concept/vectorial.hh>
00035 # include <mln/value/int_u.hh>
00036 # include <mln/algebra/vec.hh>
00037
00038 # include <mln/value/internal/make_generic_name.hh>
00039
00040 # include <mln/convert/from_to.hh>
00041
00042
00043
00044
00045 namespace mln
00046 {
00047
00048
00049 namespace value { template <unsigned n> struct rgb; }
00050
00051
00052
00053 namespace fun
00054 {
00055
00056 namespace v2v
00057 {
00058
00059 template <typename T_rgb>
00060 struct f_hsl_to_rgb_;
00061
00062 typedef f_hsl_to_rgb_< value::rgb<8> > f_hsl_to_rgb_3x8_t;
00063
00064
00065 extern f_hsl_to_rgb_3x8_t f_hsl_to_rgb_3x8;
00066
00067
00068 }
00069
00070 }
00071
00072
00073 namespace literal
00074 {
00076 struct black_t;
00077 struct white_t;
00078
00079 struct light_gray_t;
00080 struct medium_gray_t;
00081 struct dark_gray_t;
00082
00083 struct red_t;
00084 struct green_t;
00085 struct blue_t;
00086 struct brown_t;
00087 struct lime_t;
00088 struct orange_t;
00089 struct pink_t;
00090 struct purple_t;
00091 struct teal_t;
00092 struct violet_t;
00093 struct cyan_t;
00094 struct magenta_t;
00095 struct yellow_t;
00096 struct olive_t;
00098 }
00099
00100
00101
00102 namespace value
00103 {
00104 template <typename H, typename S, typename L> class hsl_;
00105 }
00106
00107
00108 namespace convert
00109 {
00110
00111 namespace over_load
00112 {
00113
00114
00115 template <typename T, unsigned m>
00116 void from_to_(const algebra::vec<3,T>& from, value::rgb<m>& to_);
00117
00118
00119 template <unsigned m>
00120 void from_to_(bool from, value::rgb<m>& to);
00121
00122
00123 template <unsigned m>
00124 void from_to_(const value::int_u<m>& from, value::rgb<m>& to);
00125
00126
00127 template <typename H, typename S, typename L>
00128 void from_to_(const value::hsl_<H,S,L>&, value::rgb<8>& to);
00129
00130
00131
00132
00133
00134
00135 template <unsigned m>
00136 void from_to_(const value::rgb<m>& from, bool& to);
00137
00138 }
00139
00140 }
00141
00142
00143 namespace trait
00144 {
00145 template < unsigned n >
00146 struct set_precise_binary_< op::plus, mln::value::rgb<n>, mln::value::rgb<n> >
00147 {
00148 typedef mln::value::rgb<n> ret;
00149 };
00150
00151 template < unsigned n >
00152 struct set_precise_binary_< op::minus, mln::value::rgb<n>, mln::value::rgb<n> >
00153 {
00154 typedef mln::value::rgb<n> ret;
00155 };
00156
00157 template < unsigned n, typename S >
00158 struct set_precise_binary_< op::times, mln::value::rgb<n>, mln::value::scalar_<S> >
00159 {
00160 typedef mln::value::rgb<n> ret;
00161 };
00162
00163 template < unsigned n, typename S >
00164 struct set_precise_binary_< op::div, mln::value::rgb<n>, mln::value::scalar_<S> >
00165 {
00166 typedef mln::value::rgb<n> ret;
00167 };
00168
00169
00170
00171
00172
00173
00174
00175
00176 template < unsigned n, unsigned m >
00177 struct set_precise_binary_< op::times, mln::value::rgb<n>, mln::value::int_u<m> >
00178 {
00179 typedef mln::value::rgb<n> ret;
00180 };
00181
00182 template < unsigned n, unsigned m >
00183 struct set_precise_binary_< op::div, mln::value::rgb<n>, mln::value::int_u<m> >
00184 {
00185 typedef mln::value::rgb<n> ret;
00186 };
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205 template <unsigned n>
00206 struct value_< mln::value::rgb<n> >
00207 {
00208 enum {
00209 dim = 3,
00210 nbits = dim * n,
00211 card = mln_value_card_from_(nbits)
00212 };
00213
00214 typedef trait::value::nature::vectorial nature;
00215 typedef trait::value::kind::color kind;
00216 typedef trait::value::quant::high quant;
00217
00218 typedef void comp;
00219 typedef mln::value::int_u<n> comp_0;
00220 typedef mln::value::int_u<n> comp_1;
00221 typedef mln::value::int_u<n> comp_2;
00222
00223 template <typename V> static comp_0 get_comp_0(const V& v) { return v.red(); }
00224 template <typename V> static comp_1 get_comp_1(const V& v) { return v.green(); }
00225 template <typename V> static comp_2 get_comp_2(const V& v) { return v.blue(); }
00226
00227 typedef algebra::vec<dim, float> sum;
00228
00229 static const char* name()
00230 {
00231 static std::string
00232 s = mln::value::internal::make_generic_name("rgb", n);
00233 return s.c_str();
00234 }
00235
00236 };
00237
00238 }
00239
00240
00241
00242 namespace value
00243 {
00244
00247 template <unsigned n>
00248 struct rgb
00249 :
00250 public Vectorial< rgb<n> >
00251 ,
00252 public internal::value_like_< algebra::vec< 3, int_u<n> >,
00253 algebra::vec< 3, int_u<n> >,
00254 algebra::vec< 3, int >,
00255 rgb<n> >
00256 {
00257 public:
00258
00259 typedef int_u<n> red_t;
00260 typedef int_u<n> green_t;
00261 typedef int_u<n> blue_t;
00262
00264 int_u<n> red() const { return this->v_[0]; }
00265 int_u<n>& red() { return this->v_[0]; }
00266
00267 int_u<n> green() const { return this->v_[1]; }
00268 int_u<n>& green() { return this->v_[1]; }
00269
00270 int_u<n> blue() const { return this->v_[2]; }
00271 int_u<n>& blue() { return this->v_[2]; }
00272
00273 int_u<n> comp(unsigned k) const { return this->v_[k]; }
00274 int_u<n>& comp(unsigned k) { return this->v_[k]; }
00276
00278 rgb<n>();
00279
00281 rgb<n>(int r, int g, int b);
00282
00284 rgb<n>(const algebra::vec<3, int>& rhs);
00285 rgb<n>(const algebra::vec<3, unsigned>& rhs);
00286 rgb<n>(const algebra::vec<3, int_u<n> >& rhs);
00287 rgb<n>(const algebra::vec<3, float>& rhs);
00288
00289
00290 operator algebra::vec<3, int>() const { return this->v_; }
00291
00292 operator algebra::vec<3, float>() const { return this->v_; }
00293
00295 rgb<n>(const mln::literal::white_t&);
00296 rgb<n>(const mln::literal::black_t&);
00297
00298 rgb<n>(const mln::literal::light_gray_t&);
00299 rgb<n>(const mln::literal::medium_gray_t&);
00300 rgb<n>(const mln::literal::dark_gray_t&);
00301
00302 rgb<n>(const mln::literal::red_t&);
00303 rgb<n>(const mln::literal::blue_t&);
00304 rgb<n>(const mln::literal::green_t&);
00305 rgb<n>(const mln::literal::brown_t&);
00306 rgb<n>(const mln::literal::lime_t&);
00307 rgb<n>(const mln::literal::orange_t&);
00308 rgb<n>(const mln::literal::pink_t&);
00309 rgb<n>(const mln::literal::purple_t&);
00310 rgb<n>(const mln::literal::teal_t&);
00311 rgb<n>(const mln::literal::violet_t&);
00312 rgb<n>(const mln::literal::cyan_t&);
00313 rgb<n>(const mln::literal::magenta_t&);
00314 rgb<n>(const mln::literal::yellow_t&);
00315 rgb<n>(const mln::literal::olive_t&);
00317
00319 rgb<n>& operator=(const rgb<n>& rhs);
00320
00322 static const rgb<n> zero;
00323 };
00324
00325
00326
00333 template <unsigned n>
00334 std::ostream& operator<<(std::ostream& ostr, const rgb<n>& c);
00335
00336 template <unsigned n>
00337 std::istream& operator>>(std::istream& istr, rgb<n>& c);
00338
00339
00340
00341
00342
00343
00344
00345
00346
00349 template <unsigned n>
00350 typename rgb<n>::interop
00351 operator+(const rgb<n>& lhs, const rgb<n>& rhs);
00352
00353 template <unsigned n>
00354 typename rgb<n>::interop
00355 operator+(const typename rgb<n>::interop& lhs, const rgb<n>& rhs);
00356
00357 template <unsigned n>
00358 typename rgb<n>::interop
00359 operator+(const rgb<n>& lhs, const typename rgb<n>::interop& rhs);
00361
00364 template <unsigned n>
00365 typename rgb<n>::interop
00366 operator-(const rgb<n>& lhs, const rgb<n>& rhs);
00367
00368 template <unsigned n>
00369 typename rgb<n>::interop
00370 operator-(const typename rgb<n>::interop& lhs, const rgb<n>& rhs);
00371
00372 template <unsigned n>
00373 typename rgb<n>::interop
00374 operator-(const rgb<n>& lhs, const typename rgb<n>::interop& rhs);
00376
00379 template <unsigned n, typename S>
00380 inline
00381 typename rgb<n>::interop
00382 operator*(const rgb<n>& lhs, const mln::value::scalar_<S>& s);
00383
00384 template <unsigned n, typename S>
00385 inline
00386 typename rgb<n>::interop
00387 operator*(const mln::value::scalar_<S>& s, const rgb<n>& lhs);
00389
00392 template <unsigned n, typename S>
00393 inline
00394 typename rgb<n>::interop
00395 operator/(const rgb<n>& lhs, const mln::value::scalar_<S>& s);
00397
00398
00399 }
00400
00401 }
00402
00403
00404
00405
00406
00407
00408 # ifndef MLN_INCLUDE_ONLY
00409
00410 namespace mln
00411 {
00412
00413 namespace value
00414 {
00415
00416
00417
00418
00419
00420 template <unsigned n>
00421 inline
00422 rgb<n>::rgb()
00423 {
00424 }
00425
00426 template <unsigned n>
00427 inline
00428 rgb<n>::rgb(const algebra::vec<3, int>& v)
00429 {
00430 this->v_ = v;
00431 }
00432
00433 template <unsigned n>
00434 inline
00435 rgb<n>::rgb(const algebra::vec<3, unsigned>& v)
00436 {
00437 this->v_ = v;
00438 }
00439
00440 template <unsigned n>
00441 inline
00442 rgb<n>::rgb(const algebra::vec<3, int_u<n> >& v)
00443 {
00444 this->v_ = v;
00445 }
00446
00447 template <unsigned n>
00448 inline
00449 rgb<n>::rgb(const algebra::vec<3, float>& v)
00450 {
00451 convert::from_to(v[0], this->v_[0]);
00452 convert::from_to(v[1], this->v_[1]);
00453 convert::from_to(v[2], this->v_[2]);
00454 }
00455
00456 template <unsigned n>
00457 inline
00458 rgb<n>::rgb(int r, int g, int b)
00459 {
00460 mln_precondition(r >= 0);
00461 mln_precondition(g >= 0);
00462 mln_precondition(b >= 0);
00463 mln_precondition(unsigned(r) <= mln_max(int_u<n>));
00464 mln_precondition(unsigned(g) <= mln_max(int_u<n>));
00465 mln_precondition(unsigned(b) <= mln_max(int_u<n>));
00466 this->v_[0] = r;
00467 this->v_[1] = g;
00468 this->v_[2] = b;
00469 }
00470
00471 template <unsigned n>
00472 inline
00473 rgb<n>::rgb(const mln::literal::white_t&)
00474 {
00475 this->v_[0] = mln_max(int_u<n>);
00476 this->v_[1] = mln_max(int_u<n>);
00477 this->v_[2] = mln_max(int_u<n>);
00478 }
00479
00480 template <unsigned n>
00481 inline
00482 rgb<n>::rgb(const mln::literal::black_t&)
00483 {
00484 this->v_[0] = 0;
00485 this->v_[1] = 0;
00486 this->v_[2] = 0;
00487 }
00488
00489 template <unsigned n>
00490 inline
00491 rgb<n>::rgb(const mln::literal::light_gray_t&)
00492 {
00493 convert::from_to(mln_max(int_u<n>) * 0.75, this->v_[0]);
00494 convert::from_to(mln_max(int_u<n>) * 0.75, this->v_[1]);
00495 convert::from_to(mln_max(int_u<n>) * 0.75, this->v_[2]);
00496 }
00497
00498 template <unsigned n>
00499 inline
00500 rgb<n>::rgb(const mln::literal::medium_gray_t&)
00501 {
00502 convert::from_to(mln_max(int_u<n>) * 0.50, this->v_[0]);
00503 convert::from_to(mln_max(int_u<n>) * 0.50, this->v_[1]);
00504 convert::from_to(mln_max(int_u<n>) * 0.50, this->v_[2]);
00505 }
00506
00507 template <unsigned n>
00508 inline
00509 rgb<n>::rgb(const mln::literal::dark_gray_t&)
00510 {
00511 convert::from_to(mln_max(int_u<n>) * 0.25, this->v_[0]);
00512 convert::from_to(mln_max(int_u<n>) * 0.25, this->v_[1]);
00513 convert::from_to(mln_max(int_u<n>) * 0.25, this->v_[2]);
00514 }
00515
00516 template <unsigned n>
00517 inline
00518 rgb<n>::rgb(const mln::literal::red_t&)
00519 {
00520 this->v_[0] = mln_max(int_u<n>);
00521 this->v_[1] = 0;
00522 this->v_[2] = 0;
00523 }
00524
00525 template <unsigned n>
00526 inline
00527 rgb<n>::rgb(const mln::literal::green_t&)
00528 {
00529 this->v_[0] = 0;
00530 this->v_[1] = mln_max(int_u<n>);
00531 this->v_[2] = 0;
00532 }
00533
00534 template <unsigned n>
00535 inline
00536 rgb<n>::rgb(const mln::literal::blue_t&)
00537 {
00538 this->v_[0] = 0;
00539 this->v_[1] = 0;
00540 this->v_[2] = mln_max(int_u<n>);
00541 }
00542
00543 template <unsigned n>
00544 inline
00545 rgb<n>::rgb(const mln::literal::brown_t&)
00546 {
00547 convert::from_to(mln_max(int_u<n>) * 0.75, this->v_[0]);
00548 convert::from_to(mln_max(int_u<n>) * 0.50, this->v_[1]);
00549 convert::from_to(mln_max(int_u<n>) * 0.25, this->v_[2]);
00550 }
00551
00552 template <unsigned n>
00553 inline
00554 rgb<n>::rgb(const mln::literal::lime_t&)
00555 {
00556 convert::from_to(mln_max(int_u<n>) * 0.75, this->v_[0]);
00557 this->v_[1] = mln_max(int_u<n>);
00558 this->v_[2] = 0;
00559 }
00560
00561 template <unsigned n>
00562 inline
00563 rgb<n>::rgb(const mln::literal::orange_t&)
00564 {
00565 this->v_[0] = mln_max(int_u<n>);
00566 convert::from_to(mln_max(int_u<n>) * 0.50, this->v_[1]);
00567 this->v_[2] = 0;
00568 }
00569
00570 template <unsigned n>
00571 inline
00572 rgb<n>::rgb(const mln::literal::pink_t&)
00573 {
00574 this->v_[0] = mln_max(int_u<n>);
00575 convert::from_to(mln_max(int_u<n>) * 0.75, this->v_[1]);
00576 convert::from_to(mln_max(int_u<n>) * 0.75, this->v_[2]);
00577 }
00578
00579 template <unsigned n>
00580 inline
00581 rgb<n>::rgb(const mln::literal::purple_t&)
00582 {
00583 convert::from_to(mln_max(int_u<n>) * 0.75, this->v_[0]);
00584 this->v_[1] = 0;
00585 convert::from_to(mln_max(int_u<n>) * 0.25, this->v_[2]);
00586 }
00587
00588 template <unsigned n>
00589 inline
00590 rgb<n>::rgb(const mln::literal::teal_t&)
00591 {
00592 this->v_[0] = 0;
00593 convert::from_to(mln_max(int_u<n>) * 0.50, this->v_[1]);
00594 convert::from_to(mln_max(int_u<n>) * 0.50, this->v_[2]);
00595 }
00596
00597 template <unsigned n>
00598 inline
00599 rgb<n>::rgb(const mln::literal::violet_t&)
00600 {
00601 convert::from_to(mln_max(int_u<n>) * 0.50, this->v_[0]);
00602 this->v_[1] = 0;
00603 convert::from_to(mln_max(int_u<n>) * 0.50, this->v_[2]);
00604 }
00605
00606 template <unsigned n>
00607 inline
00608 rgb<n>::rgb(const mln::literal::cyan_t&)
00609 {
00610 this->v_[0] = 0;
00611 this->v_[1] = mln_max(int_u<n>);
00612 this->v_[2] = mln_max(int_u<n>);
00613 }
00614
00615 template <unsigned n>
00616 inline
00617 rgb<n>::rgb(const mln::literal::magenta_t&)
00618 {
00619 this->v_[0] = mln_max(int_u<n>);
00620 this->v_[1] = 0;
00621 this->v_[2] = mln_max(int_u<n>);
00622 }
00623
00624 template <unsigned n>
00625 inline
00626 rgb<n>::rgb(const mln::literal::yellow_t&)
00627 {
00628 this->v_[0] = mln_max(int_u<n>);
00629 this->v_[1] = mln_max(int_u<n>);
00630 this->v_[2] = 0;
00631 }
00632
00633 template <unsigned n>
00634 inline
00635 rgb<n>::rgb(const mln::literal::olive_t&)
00636 {
00637 convert::from_to(mln_max(int_u<n>) * 0.50, this->v_[0]);
00638 convert::from_to(mln_max(int_u<n>) * 0.50, this->v_[1]);
00639 this->v_[2] = 0;
00640 }
00641
00642 template <unsigned n>
00643 inline
00644 rgb<n>&
00645 rgb<n>::operator=(const rgb<n>& rhs)
00646 {
00647 if (& rhs == this)
00648 return *this;
00649 this->v_ = rhs.v_;
00650 return *this;
00651 }
00652
00653 template <unsigned n>
00654 const rgb<n> rgb<n>::zero(0,0,0);
00655
00656
00657
00658
00659
00660 template <unsigned n>
00661 inline
00662 typename rgb<n>::interop
00663 operator+(const rgb<n>& lhs, const rgb<n>& rhs)
00664 {
00665 typename rgb<n>::interop tmp(lhs.to_interop() + rhs.to_interop());
00666 return tmp;
00667 }
00668
00669 template <unsigned n>
00670 inline
00671 typename rgb<n>::interop
00672 operator+(const rgb<n>& lhs, const typename rgb<n>::interop& rhs)
00673 {
00674 typename rgb<n>::interop tmp(lhs.to_interop() + rhs);
00675 return tmp;
00676 }
00677
00678 template <unsigned n>
00679 inline
00680 typename rgb<n>::interop
00681 operator+(const typename rgb<n>::interop& lhs, const rgb<n>& rhs)
00682 {
00683 typename rgb<n>::interop tmp(lhs + rhs.to_interop());
00684 return tmp;
00685 }
00686
00687 template <unsigned n>
00688 inline
00689 typename rgb<n>::interop
00690 operator-(const rgb<n>& lhs, const rgb<n>& rhs)
00691 {
00692 typename rgb<n>::interop tmp(lhs.to_interop() - rhs.to_interop());
00693 return tmp;
00694 }
00695
00696 template <unsigned n>
00697 inline
00698 typename rgb<n>::interop
00699 operator-(const rgb<n>& lhs, const typename rgb<n>::interop& rhs)
00700 {
00701 typename rgb<n>::interop tmp(lhs.to_interop() - rhs);
00702 return tmp;
00703 }
00704
00705 template <unsigned n>
00706 inline
00707 typename rgb<n>::interop
00708 operator-(const typename rgb<n>::interop& lhs, const rgb<n>& rhs)
00709 {
00710 typename rgb<n>::interop tmp(lhs - rhs.to_interop());
00711 return tmp;
00712 }
00713
00714 template <unsigned n, typename S>
00715 inline
00716 typename rgb<n>::interop
00717 operator*(const rgb<n>& lhs, const mln::value::scalar_<S>& s)
00718 {
00719 typename rgb<n>::interop tmp(lhs.to_interop() * s.to_equiv());
00720 return tmp;
00721 }
00722
00723 template <unsigned n, typename S>
00724 inline
00725 typename rgb<n>::interop
00726 operator*(const mln::value::scalar_<S>& s, const rgb<n>& lhs)
00727 {
00728 typename rgb<n>::interop tmp(s.to_equiv() * lhs.to_interop());
00729 return tmp;
00730 }
00731
00732 template <unsigned n, typename S>
00733 inline
00734 typename rgb<n>::interop
00735 operator/(const rgb<n>& lhs, const mln::value::scalar_<S>& s)
00736 {
00737 typename rgb<n>::interop tmp(lhs.to_interop() / s.to_equiv());
00738 return tmp;
00739 }
00740
00741 template <unsigned n>
00742 inline
00743 std::ostream& operator<<(std::ostream& ostr, const rgb<n>& v)
00744 {
00745 return ostr << '(' << debug::format(v.red())
00746 << ',' << debug::format(v.green())
00747 << ',' << debug::format(v.blue())
00748 << ')';
00749 }
00750
00751 template <unsigned n>
00752 inline
00753 std::istream& operator>>(std::istream& istr, rgb<n>& c)
00754 {
00755 return istr >> c.red() >> c.green() >> c.blue();
00756 }
00757
00758 }
00759
00760
00761 namespace convert
00762 {
00763
00764 namespace over_load
00765 {
00766
00767
00768 template <typename T, unsigned m>
00769 inline
00770 void
00771 from_to_(const algebra::vec<3,T>& from, value::rgb<m>& to)
00772 {
00773 algebra::vec<3, unsigned> tmp;
00774 for (unsigned i = 0; i < 3; ++i)
00775 tmp[i] = static_cast<unsigned>(from[i]);
00776
00777 to = value::rgb<m>(tmp);
00778 }
00779
00780
00781 template <unsigned m>
00782 void
00783 from_to_(bool from, value::rgb<m>& to)
00784 {
00785 static literal::white_t* white_ = 0;
00786 static literal::black_t* black_ = 0;
00787
00788
00789
00790 if (from)
00791 to = *white_;
00792 else
00793 to = *black_;
00794 }
00795
00796 template <unsigned m>
00797 void
00798 from_to_(const value::int_u<m>& from, value::rgb<m>& to)
00799 {
00800 to = value::rgb<m>(from, from, from);
00801 }
00802
00803 template <typename H, typename S, typename L>
00804 void
00805 from_to_(const value::hsl_<H,S,L>& from, value::rgb<8>& to)
00806 {
00807 to = fun::v2v::f_hsl_to_rgb_3x8(from);
00808 }
00809
00810
00811
00812
00813
00814
00815
00816
00817 template <unsigned m>
00818 void
00819 from_to_(const value::rgb<m>& from, bool& to)
00820 {
00821 to = (from.red() != 0 && from.green() != 0 && from.blue() != 0);
00822 }
00823
00824 }
00825
00826 }
00827
00828 }
00829
00830 # endif // ! MLN_INCLUDE_ONLY
00831
00832
00833 #endif // ! MLN_VALUE_RGB_HH