Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2007, 2008, 2009, 2010 EPITA Research and Development 00002 // Laboratory (LRDE) 00003 // 00004 // This file is part of Olena. 00005 // 00006 // Olena is free software: you can redistribute it and/or modify it under 00007 // the terms of the GNU General Public License as published by the Free 00008 // Software Foundation, version 2 of the License. 00009 // 00010 // Olena is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 // General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with Olena. If not, see <http://www.gnu.org/licenses/>. 00017 // 00018 // As a special exception, you may use this file as part of a free 00019 // software project without restriction. Specifically, if other files 00020 // instantiate templates or use macros or inline functions from this 00021 // file, or you compile this file and link it with other files to produce 00022 // an executable, this file does not by itself cause the resulting 00023 // executable to be covered by the GNU General Public License. This 00024 // exception does not however invalidate any other reasons why the 00025 // executable file might be covered by the GNU General Public License. 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 // FIXME: should we consider that mln_min may be negative? => wrong 00043 // color formulae. 00044 00045 namespace mln 00046 { 00047 00048 // Forward declaration. 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 // typedef f_hsl_to_rgb_< value::rgb<16> > f_hsl_to_rgb_3x16_t; 00064 00065 extern f_hsl_to_rgb_3x8_t f_hsl_to_rgb_3x8; 00066 // extern f_hsl_to_rgb_3x16_t f_hsl_to_rgb_3x16; 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 // Forward declaration. 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 // algebra::vec -> rgb. 00115 template <typename T, unsigned m> 00116 void from_to_(const algebra::vec<3,T>& from, value::rgb<m>& to_); 00117 00118 // bool -> rgb. 00119 template <unsigned m> 00120 void from_to_(bool from, value::rgb<m>& to); 00121 00122 // int_u -> rgb. 00123 template <unsigned m> 00124 void from_to_(const value::int_u<m>& from, value::rgb<m>& to); 00125 00126 // hsl -> rgb8. 00127 template <typename H, typename S, typename L> 00128 void from_to_(const value::hsl_<H,S,L>&, value::rgb<8>& to); 00129 00130 // // hsl -> rgb16. 00131 // template <typename H, typename S, typename L> 00132 // void from_to_(const value::hsl_<H,S,L>&, value::rgb<16>& to); 00133 00134 // rgb -> bool. 00135 template <unsigned m> 00136 void from_to_(const value::rgb<m>& from, bool& to); 00137 00138 } // end of namespace mln::convert::over_load 00139 00140 } // end of namespace mln::convert 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 // FIXME : Is there any way more generic? a way to factor 00171 // set_precise_binary_< op::div, mln::value::rgb<n>, mln::value::scalar_<S> > 00172 // and 00173 // set_precise_binary_< op::div, mln::value::rgb<n>, mln::value::int_u<m> > 00174 // as for op::times. 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 // template < unsigned n, typename I > 00190 // struct set_binary_< op::times, 00191 // mln::value::Vectorial, mln::value::rgb<n>, 00192 // mln::value::Integer, I > 00193 // { 00194 // typedef mln::value::rgb<n> ret; 00195 // }; 00196 00197 // template < unsigned n, typename S > 00198 // struct set_binary_< op::times, 00199 // mln::value::Scalar, S, 00200 // mln::value::Vectorial, mln::value::rgb<n> > 00201 // { 00202 // typedef mln::value::rgb<n> ret; 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 /*mln_value_quant_from_(card)*/ 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 } // end of namespace trait 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> >, // Equivalent. 00253 algebra::vec< 3, int_u<n> >, // Encoding. 00254 algebra::vec< 3, int >, // Interoperation. 00255 rgb<n> > // Exact. 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 // Conversion to the interoperation type. 00290 operator algebra::vec<3, int>() const { return this->v_; } 00291 // Conversion to the sum type. 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 /* FIXME: We should not need to define these operators, thanks to 00341 Milena's global operator resolution mechanism based on 00342 mln::Object. See what prevent us to use this mechanism. */ 00343 00344 /* FIXME: Cannot work for i negative; add traits! (2008-02-16, 00345 Roland: What does this comment mean?) */ 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 } // end of namespace mln::value 00400 00401 } // end of namespace mln 00402 00403 00404 // // Needed by from_to_. 00405 // # include <mln/fun/v2v/rgb_to_hsl.hh> 00406 00407 00408 # ifndef MLN_INCLUDE_ONLY 00409 00410 namespace mln 00411 { 00412 00413 namespace value 00414 { 00415 00416 /*---------------. 00417 | Construction. | 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 | Operators. | 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 } // end of namespace mln::value 00759 00760 00761 namespace convert 00762 { 00763 00764 namespace over_load 00765 { 00766 00767 // algebra::vec -> rgb. 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]); // FIXME: Use from_to_ instead of cast. 00776 00777 to = value::rgb<m>(tmp); 00778 } 00779 00780 // bool -> rgb. 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 // We do not use literal::white (the object) so that we 00788 // do not introduce any coupling with the file where 00789 // literals are defined. 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 // template <typename H, typename S, typename L> 00811 // void 00812 // from_to_(const value::hsl_<H,S,L>& from, value::rgb<16>& to) 00813 // { 00814 // to = fun::v2v::f_hsl_to_rgb_3x16(from); 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 } // end of namespace mln::convert::over_load 00825 00826 } // end of namespace mln::convert 00827 00828 } // end of namespace mln 00829 00830 # endif // ! MLN_INCLUDE_ONLY 00831 00832 00833 #endif // ! MLN_VALUE_RGB_HH