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
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
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
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
00095
00096
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
00120
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 mln_value_quant_from_(card) 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
00279
00280 operator algebra::vec<3, int>() const { return this->v_; }
00281
00282 operator algebra::vec<3, float>() const { return this->v_; }
00283
00285 rgb<n>(const mln::literal::white_t&);
00286 rgb<n>(const mln::literal::black_t&);
00287
00288 rgb<n>(const mln::literal::light_gray_t&);
00289 rgb<n>(const mln::literal::medium_gray_t&);
00290 rgb<n>(const mln::literal::dark_gray_t&);
00291
00292 rgb<n>(const mln::literal::red_t&);
00293 rgb<n>(const mln::literal::blue_t&);
00294 rgb<n>(const mln::literal::green_t&);
00295 rgb<n>(const mln::literal::brown_t&);
00296 rgb<n>(const mln::literal::lime_t&);
00297 rgb<n>(const mln::literal::orange_t&);
00298 rgb<n>(const mln::literal::pink_t&);
00299 rgb<n>(const mln::literal::purple_t&);
00300 rgb<n>(const mln::literal::teal_t&);
00301 rgb<n>(const mln::literal::violet_t&);
00302 rgb<n>(const mln::literal::cyan_t&);
00303 rgb<n>(const mln::literal::magenta_t&);
00304 rgb<n>(const mln::literal::yellow_t&);
00305 rgb<n>(const mln::literal::olive_t&);
00307
00309 rgb<n>& operator=(const rgb<n>& rhs);
00310
00312 static const rgb<n> zero;
00313 };
00314
00315
00316
00323 template <unsigned n>
00324 std::ostream& operator<<(std::ostream& ostr, const rgb<n>& c);
00325
00326 template <unsigned n>
00327 std::istream& operator>>(std::istream& istr, rgb<n>& c);
00328
00329
00330
00331
00332
00333
00334
00335
00336
00339 template <unsigned n>
00340 typename rgb<n>::interop
00341 operator+(const rgb<n>& lhs, const rgb<n>& rhs);
00342
00343 template <unsigned n>
00344 typename rgb<n>::interop
00345 operator+(const typename rgb<n>::interop& lhs, const rgb<n>& rhs);
00346
00347 template <unsigned n>
00348 typename rgb<n>::interop
00349 operator+(const rgb<n>& lhs, const typename rgb<n>::interop& rhs);
00351
00354 template <unsigned n>
00355 typename rgb<n>::interop
00356 operator-(const rgb<n>& lhs, const rgb<n>& rhs);
00357
00358 template <unsigned n>
00359 typename rgb<n>::interop
00360 operator-(const typename rgb<n>::interop& lhs, const rgb<n>& rhs);
00361
00362 template <unsigned n>
00363 typename rgb<n>::interop
00364 operator-(const rgb<n>& lhs, const typename rgb<n>::interop& rhs);
00366
00369 template <unsigned n, typename S>
00370 inline
00371 typename rgb<n>::interop
00372 operator*(const rgb<n>& lhs, const mln::value::scalar_<S>& s);
00373
00374 template <unsigned n, typename S>
00375 inline
00376 typename rgb<n>::interop
00377 operator*(const mln::value::scalar_<S>& s, const rgb<n>& lhs);
00379
00382 template <unsigned n, typename S>
00383 inline
00384 typename rgb<n>::interop
00385 operator/(const rgb<n>& lhs, const mln::value::scalar_<S>& s);
00387
00388
00389 }
00390
00391 }
00392
00393
00394
00395
00396
00397
00398 # ifndef MLN_INCLUDE_ONLY
00399
00400 namespace mln
00401 {
00402
00403 namespace value
00404 {
00405
00406
00407
00408
00409
00410 template <unsigned n>
00411 inline
00412 rgb<n>::rgb()
00413 {
00414 }
00415
00416 template <unsigned n>
00417 inline
00418 rgb<n>::rgb(const algebra::vec<3, int>& v)
00419 {
00420 this->v_ = v;
00421 }
00422
00423 template <unsigned n>
00424 inline
00425 rgb<n>::rgb(const algebra::vec<3, unsigned>& v)
00426 {
00427 this->v_ = v;
00428 }
00429
00430 template <unsigned n>
00431 inline
00432 rgb<n>::rgb(const algebra::vec<3, int_u<n> >& v)
00433 {
00434 this->v_ = v;
00435 }
00436
00437 template <unsigned n>
00438 inline
00439 rgb<n>::rgb(int r, int g, int b)
00440 {
00441 mln_precondition(r >= 0);
00442 mln_precondition(g >= 0);
00443 mln_precondition(b >= 0);
00444 mln_precondition(unsigned(r) <= mln_max(int_u<n>));
00445 mln_precondition(unsigned(g) <= mln_max(int_u<n>));
00446 mln_precondition(unsigned(b) <= mln_max(int_u<n>));
00447 this->v_[0] = r;
00448 this->v_[1] = g;
00449 this->v_[2] = b;
00450 }
00451
00452 template <unsigned n>
00453 inline
00454 rgb<n>::rgb(const mln::literal::white_t&)
00455 {
00456 this->v_[0] = mln_max(int_u<n>);
00457 this->v_[1] = mln_max(int_u<n>);
00458 this->v_[2] = mln_max(int_u<n>);
00459 }
00460
00461 template <unsigned n>
00462 inline
00463 rgb<n>::rgb(const mln::literal::black_t&)
00464 {
00465 this->v_[0] = 0;
00466 this->v_[1] = 0;
00467 this->v_[2] = 0;
00468 }
00469
00470 template <unsigned n>
00471 inline
00472 rgb<n>::rgb(const mln::literal::light_gray_t&)
00473 {
00474 this->v_[0] = mln_max(int_u<n>) * 0.75;
00475 this->v_[1] = mln_max(int_u<n>) * 0.75;
00476 this->v_[2] = mln_max(int_u<n>) * 0.75;
00477 }
00478
00479 template <unsigned n>
00480 inline
00481 rgb<n>::rgb(const mln::literal::medium_gray_t&)
00482 {
00483 this->v_[0] = mln_max(int_u<n>) * 0.50;
00484 this->v_[1] = mln_max(int_u<n>) * 0.50;
00485 this->v_[2] = mln_max(int_u<n>) * 0.50;
00486 }
00487
00488 template <unsigned n>
00489 inline
00490 rgb<n>::rgb(const mln::literal::dark_gray_t&)
00491 {
00492 this->v_[0] = mln_max(int_u<n>) * 0.25;
00493 this->v_[1] = mln_max(int_u<n>) * 0.25;
00494 this->v_[2] = mln_max(int_u<n>) * 0.25;
00495 }
00496
00497 template <unsigned n>
00498 inline
00499 rgb<n>::rgb(const mln::literal::red_t&)
00500 {
00501 this->v_[0] = mln_max(int_u<n>);
00502 this->v_[1] = 0;
00503 this->v_[2] = 0;
00504 }
00505
00506 template <unsigned n>
00507 inline
00508 rgb<n>::rgb(const mln::literal::green_t&)
00509 {
00510 this->v_[0] = 0;
00511 this->v_[1] = mln_max(int_u<n>);
00512 this->v_[2] = 0;
00513 }
00514
00515 template <unsigned n>
00516 inline
00517 rgb<n>::rgb(const mln::literal::blue_t&)
00518 {
00519 this->v_[0] = 0;
00520 this->v_[1] = 0;
00521 this->v_[2] = mln_max(int_u<n>);
00522 }
00523
00524 template <unsigned n>
00525 inline
00526 rgb<n>::rgb(const mln::literal::brown_t&)
00527 {
00528 this->v_[0] = mln_max(int_u<n>) * 0.75;
00529 this->v_[1] = mln_max(int_u<n>) * 0.50;
00530 this->v_[2] = mln_max(int_u<n>) * 0.25;
00531 }
00532
00533 template <unsigned n>
00534 inline
00535 rgb<n>::rgb(const mln::literal::lime_t&)
00536 {
00537 this->v_[0] = mln_max(int_u<n>) * 0.75;
00538 this->v_[1] = mln_max(int_u<n>);
00539 this->v_[2] = 0;
00540 }
00541
00542 template <unsigned n>
00543 inline
00544 rgb<n>::rgb(const mln::literal::orange_t&)
00545 {
00546 this->v_[0] = mln_max(int_u<n>);
00547 this->v_[1] = mln_max(int_u<n>) * 0.50;
00548 this->v_[2] = 0;
00549 }
00550
00551 template <unsigned n>
00552 inline
00553 rgb<n>::rgb(const mln::literal::pink_t&)
00554 {
00555 this->v_[0] = mln_max(int_u<n>);
00556 this->v_[1] = mln_max(int_u<n>) * 0.75;
00557 this->v_[2] = mln_max(int_u<n>) * 0.75;
00558 }
00559
00560 template <unsigned n>
00561 inline
00562 rgb<n>::rgb(const mln::literal::purple_t&)
00563 {
00564 this->v_[0] = mln_max(int_u<n>) * 0.75;
00565 this->v_[1] = 0;
00566 this->v_[2] = mln_max(int_u<n>) * 0.25;
00567 }
00568
00569 template <unsigned n>
00570 inline
00571 rgb<n>::rgb(const mln::literal::teal_t&)
00572 {
00573 this->v_[0] = 0;
00574 this->v_[1] = mln_max(int_u<n>) * 0.50;
00575 this->v_[2] = mln_max(int_u<n>) * 0.50;
00576 }
00577
00578 template <unsigned n>
00579 inline
00580 rgb<n>::rgb(const mln::literal::violet_t&)
00581 {
00582 this->v_[0] = mln_max(int_u<n>) * 0.50;
00583 this->v_[1] = 0;
00584 this->v_[2] = mln_max(int_u<n>) * 0.50;
00585 }
00586
00587 template <unsigned n>
00588 inline
00589 rgb<n>::rgb(const mln::literal::cyan_t&)
00590 {
00591 this->v_[0] = 0;
00592 this->v_[1] = mln_max(int_u<n>);
00593 this->v_[2] = mln_max(int_u<n>);
00594 }
00595
00596 template <unsigned n>
00597 inline
00598 rgb<n>::rgb(const mln::literal::magenta_t&)
00599 {
00600 this->v_[0] = mln_max(int_u<n>);
00601 this->v_[1] = 0;
00602 this->v_[2] = mln_max(int_u<n>);
00603 }
00604
00605 template <unsigned n>
00606 inline
00607 rgb<n>::rgb(const mln::literal::yellow_t&)
00608 {
00609 this->v_[0] = mln_max(int_u<n>);
00610 this->v_[1] = mln_max(int_u<n>);
00611 this->v_[2] = 0;
00612 }
00613
00614 template <unsigned n>
00615 inline
00616 rgb<n>::rgb(const mln::literal::olive_t&)
00617 {
00618 this->v_[0] = mln_max(int_u<n>) * 0.50;
00619 this->v_[1] = mln_max(int_u<n>) * 0.50;
00620 this->v_[2] = 0;
00621 }
00622
00623 template <unsigned n>
00624 inline
00625 rgb<n>&
00626 rgb<n>::operator=(const rgb<n>& rhs)
00627 {
00628 if (& rhs == this)
00629 return *this;
00630 this->v_ = rhs.v_;
00631 return *this;
00632 }
00633
00634 template <unsigned n>
00635 const rgb<n> rgb<n>::zero(0,0,0);
00636
00637
00638
00639
00640
00641 template <unsigned n>
00642 inline
00643 typename rgb<n>::interop
00644 operator+(const rgb<n>& lhs, const rgb<n>& rhs)
00645 {
00646 typename rgb<n>::interop tmp(lhs.to_interop() + rhs.to_interop());
00647 return tmp;
00648 }
00649
00650 template <unsigned n>
00651 inline
00652 typename rgb<n>::interop
00653 operator+(const rgb<n>& lhs, const typename rgb<n>::interop& rhs)
00654 {
00655 typename rgb<n>::interop tmp(lhs.to_interop() + rhs);
00656 return tmp;
00657 }
00658
00659 template <unsigned n>
00660 inline
00661 typename rgb<n>::interop
00662 operator+(const typename rgb<n>::interop& lhs, const rgb<n>& rhs)
00663 {
00664 typename rgb<n>::interop tmp(lhs + rhs.to_interop());
00665 return tmp;
00666 }
00667
00668 template <unsigned n>
00669 inline
00670 typename rgb<n>::interop
00671 operator-(const rgb<n>& lhs, const rgb<n>& rhs)
00672 {
00673 typename rgb<n>::interop tmp(lhs.to_interop() - rhs.to_interop());
00674 return tmp;
00675 }
00676
00677 template <unsigned n>
00678 inline
00679 typename rgb<n>::interop
00680 operator-(const rgb<n>& lhs, const typename rgb<n>::interop& rhs)
00681 {
00682 typename rgb<n>::interop tmp(lhs.to_interop() - rhs);
00683 return tmp;
00684 }
00685
00686 template <unsigned n>
00687 inline
00688 typename rgb<n>::interop
00689 operator-(const typename rgb<n>::interop& lhs, const rgb<n>& rhs)
00690 {
00691 typename rgb<n>::interop tmp(lhs - rhs.to_interop());
00692 return tmp;
00693 }
00694
00695 template <unsigned n, typename S>
00696 inline
00697 typename rgb<n>::interop
00698 operator*(const rgb<n>& lhs, const mln::value::scalar_<S>& s)
00699 {
00700 typename rgb<n>::interop tmp(lhs.to_interop() * s.to_equiv());
00701 return tmp;
00702 }
00703
00704 template <unsigned n, typename S>
00705 inline
00706 typename rgb<n>::interop
00707 operator*(const mln::value::scalar_<S>& s, const rgb<n>& lhs)
00708 {
00709 typename rgb<n>::interop tmp(s.to_equiv() * lhs.to_interop());
00710 return tmp;
00711 }
00712
00713 template <unsigned n, typename S>
00714 inline
00715 typename rgb<n>::interop
00716 operator/(const rgb<n>& lhs, const mln::value::scalar_<S>& s)
00717 {
00718 typename rgb<n>::interop tmp(lhs.to_interop() / s.to_equiv());
00719 return tmp;
00720 }
00721
00722 template <unsigned n>
00723 inline
00724 std::ostream& operator<<(std::ostream& ostr, const rgb<n>& v)
00725 {
00726 return ostr << '(' << debug::format(v.red())
00727 << ',' << debug::format(v.green())
00728 << ',' << debug::format(v.blue())
00729 << ')';
00730 }
00731
00732 template <unsigned n>
00733 inline
00734 std::istream& operator>>(std::istream& istr, rgb<n>& c)
00735 {
00736 return istr >> c.red() >> c.green() >> c.blue();
00737 }
00738
00739 }
00740
00741
00742 namespace convert
00743 {
00744
00745 namespace over_load
00746 {
00747
00748
00749 template <typename T, unsigned m>
00750 inline
00751 void
00752 from_to_(const algebra::vec<3,T>& from, value::rgb<m>& to)
00753 {
00754 algebra::vec<3, unsigned> tmp;
00755 for (unsigned i = 0; i < 3; ++i)
00756 tmp[i] = static_cast<unsigned>(from[i]);
00757
00758 to = value::rgb<m>(tmp);
00759 }
00760
00761
00762 template <unsigned m>
00763 void
00764 from_to_(bool from, value::rgb<m>& to)
00765 {
00766 static literal::white_t* white_ = 0;
00767 static literal::black_t* black_ = 0;
00768
00769
00770
00771 if (from)
00772 to = *white_;
00773 else
00774 to = *black_;
00775 }
00776
00777 template <unsigned m>
00778 void
00779 from_to_(const value::int_u<m>& from, value::rgb<m>& to)
00780 {
00781 to = value::rgb<m>(from, from, from);
00782 }
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798 template <unsigned m>
00799 void
00800 from_to_(const value::rgb<m>& from, bool& to)
00801 {
00802 to = (from.red() != 0 && from.green() != 0 && from.blue() != 0);
00803 }
00804
00805 }
00806
00807 }
00808
00809 }
00810
00811 # endif // ! MLN_INCLUDE_ONLY
00812
00813
00814 #endif // ! MLN_VALUE_RGB_HH