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