Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE) 00002 // 00003 // This file is part of Olena. 00004 // 00005 // Olena is free software: you can redistribute it and/or modify it under 00006 // the terms of the GNU General Public License as published by the Free 00007 // Software Foundation, version 2 of the License. 00008 // 00009 // Olena is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 // General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with Olena. If not, see <http://www.gnu.org/licenses/>. 00016 // 00017 // As a special exception, you may use this file as part of a free 00018 // software project without restriction. Specifically, if other files 00019 // instantiate templates or use macros or inline functions from this 00020 // file, or you compile this file and link it with other files to produce 00021 // an executable, this file does not by itself cause the resulting 00022 // executable to be covered by the GNU General Public License. This 00023 // exception does not however invalidate any other reasons why the 00024 // executable file might be covered by the GNU General Public License. 00025 00026 #ifndef MLN_VALUE_QT_RGB32_HH 00027 # define MLN_VALUE_QT_RGB32_HH 00028 00029 # include <cstring> 00030 00031 # include <mln/value/ops.hh> 00032 00033 # include <mln/value/concept/vectorial.hh> 00034 # include <mln/value/int_u.hh> 00035 # include <mln/algebra/vec.hh> 00036 00037 # include <mln/value/rgb8.hh> 00038 00039 # include <mln/literal/zero.hh> 00040 # include <mln/literal/black.hh> 00041 # include <mln/literal/white.hh> 00042 00043 namespace mln 00044 { 00045 00046 // Forward declaration. 00047 namespace value { namespace qt { struct rgb32; } } 00048 00049 00050 00051 namespace literal 00052 { 00054 struct black_t; 00055 struct white_t; 00056 00057 struct light_gray_t; 00058 struct medium_gray_t; 00059 struct dark_gray_t; 00060 00061 struct red_t; 00062 struct green_t; 00063 struct blue_t; 00064 struct brown_t; 00065 struct lime_t; 00066 struct orange_t; 00067 struct pink_t; 00068 struct purple_t; 00069 struct teal_t; 00070 struct violet_t; 00071 struct cyan_t; 00072 struct magenta_t; 00073 struct yellow_t; 00074 struct olive_t; 00076 } 00077 00078 00079 namespace convert 00080 { 00081 00082 namespace over_load 00083 { 00084 00085 // int_u -> rgb. 00086 template <unsigned m> 00087 void from_to_(const value::int_u<m>& from, value::qt::rgb32& to); 00088 00089 // hsl -> rgb32. 00090 template <typename H, typename S, typename L> 00091 void from_to_(const value::hsl_<H,S,L>&, value::qt::rgb32& to); 00092 00093 // rgb32 -> bool. 00094 void from_to_(const value::qt::rgb32& from, bool& to); 00095 00096 00097 // bool -> rgb32. 00098 void from_to_(const bool& from, value::qt::rgb32& to); 00099 00100 00101 } // end of namespace mln::convert::over_load 00102 00103 } // end of namespace mln::convert 00104 00105 00106 namespace trait 00107 { 00108 template <> 00109 struct set_precise_binary_< op::plus, mln::value::qt::rgb32, mln::value::qt::rgb32 > 00110 { 00111 typedef mln::value::qt::rgb32 ret; 00112 }; 00113 00114 template <> 00115 struct set_precise_binary_< op::minus, mln::value::qt::rgb32, mln::value::qt::rgb32 > 00116 { 00117 typedef mln::value::qt::rgb32 ret; 00118 }; 00119 00120 template < typename S > 00121 struct set_precise_binary_< op::times, mln::value::qt::rgb32, mln::value::scalar_<S> > 00122 { 00123 typedef mln::value::qt::rgb32 ret; 00124 }; 00125 00126 template < typename S > 00127 struct set_precise_binary_< op::div, mln::value::qt::rgb32, mln::value::scalar_<S> > 00128 { 00129 typedef mln::value::qt::rgb32 ret; 00130 }; 00131 00132 00133 // FIXME : Is there any way more generic? a way to factor 00134 // set_precise_binary_< op::div, mln::value::qt::rgb32, mln::value::scalar_<S> > 00135 // and 00136 // set_precise_binary_< op::div, mln::value::qt::rgb32, mln::value::int_u<m> > 00137 // as for op::times. 00138 00139 template < unsigned m > 00140 struct set_precise_binary_< op::times, mln::value::qt::rgb32, mln::value::int_u<m> > 00141 { 00142 typedef mln::value::qt::rgb32 ret; 00143 }; 00144 00145 template < unsigned m > 00146 struct set_precise_binary_< op::div, mln::value::qt::rgb32, mln::value::int_u<m> > 00147 { 00148 typedef mln::value::qt::rgb32 ret; 00149 }; 00150 00151 00152 template <> 00153 struct value_< mln::value::qt::rgb32 > 00154 { 00155 enum { 00156 dim = 3, 00157 nbits = 32, 00158 card = mln_value_card_from_(nbits) 00159 }; 00160 00161 typedef trait::value::nature::vectorial nature; 00162 typedef trait::value::kind::color kind; 00163 typedef trait::value::quant::high /*mln_value_quant_from_(card)*/ quant; 00164 00165 typedef void comp; 00166 typedef mln::value::int_u<8> comp_0; 00167 typedef mln::value::int_u<8> comp_1; 00168 typedef mln::value::int_u<8> comp_2; 00169 00170 template <typename V> static comp_0 get_comp_0(const V& v) { return v.red(); } 00171 template <typename V> static comp_1 get_comp_1(const V& v) { return v.green(); } 00172 template <typename V> static comp_2 get_comp_2(const V& v) { return v.blue(); } 00173 00174 typedef algebra::vec<dim, float> sum; 00175 00176 static const char* name() 00177 { 00178 static std::string s = "qt_rgb32"; 00179 return s.c_str(); 00180 } 00181 00182 }; 00183 00184 } // end of namespace trait 00185 00186 00187 00188 namespace value 00189 { 00190 00191 namespace qt 00192 { 00193 00196 00197 struct rgb32 00198 : 00199 public Vectorial< rgb32 >, 00200 public internal::value_like_< algebra::vec< 3, int_u<8> >, // Equivalent. 00201 algebra::vec< 3, int_u<8> >, // Encoding. 00202 algebra::vec< 3, int >, // Interoperation. 00203 rgb32 > // Exact. 00204 { 00205 public: 00206 00207 typedef int_u<8> red_t; 00208 typedef int_u<8> green_t; 00209 typedef int_u<8> blue_t; 00210 00212 int_u<8> red() const { return this->v_[2]; } 00213 int_u<8>& red() { return this->v_[2]; } 00214 00215 int_u<8> green() const { return this->v_[1]; } 00216 int_u<8>& green() { return this->v_[1]; } 00217 00218 int_u<8> blue() const { return this->v_[0]; } 00219 int_u<8>& blue() { return this->v_[0]; } 00220 00221 int_u<8> comp(unsigned k) const { return this->v_[k]; } 00222 int_u<8>& comp(unsigned k) { return this->v_[k]; } 00224 00226 rgb32(); 00227 00229 rgb32(int r, int g, int b); 00230 00232 rgb32(const algebra::vec<3, int>& rhs); 00233 rgb32(const algebra::vec<3, unsigned>& rhs); 00234 rgb32(const algebra::vec<3, int_u<8> >& rhs); 00235 rgb32(const algebra::vec<3, float>& rhs); 00236 00237 // Conversion to the interoperation type. 00238 operator algebra::vec<3, int>() const; 00239 // Conversion to the sum type. 00240 operator algebra::vec<3, float>() const; 00241 00243 rgb32(const mln::literal::zero_t&); 00244 00245 rgb32(const mln::literal::white_t&); 00246 rgb32(const mln::literal::black_t&); 00247 00248 rgb32(const mln::literal::light_gray_t&); 00249 rgb32(const mln::literal::medium_gray_t&); 00250 rgb32(const mln::literal::dark_gray_t&); 00251 00252 rgb32(const mln::literal::red_t&); 00253 rgb32(const mln::literal::blue_t&); 00254 rgb32(const mln::literal::green_t&); 00255 rgb32(const mln::literal::brown_t&); 00256 rgb32(const mln::literal::lime_t&); 00257 rgb32(const mln::literal::orange_t&); 00258 rgb32(const mln::literal::pink_t&); 00259 rgb32(const mln::literal::purple_t&); 00260 rgb32(const mln::literal::teal_t&); 00261 rgb32(const mln::literal::violet_t&); 00262 rgb32(const mln::literal::cyan_t&); 00263 rgb32(const mln::literal::magenta_t&); 00264 rgb32(const mln::literal::yellow_t&); 00265 rgb32(const mln::literal::olive_t&); 00267 00269 rgb32& operator=(const rgb32& rhs); 00270 00272 static const rgb32 zero; 00273 00274 00276 int_u<8> alpha_; 00277 }; 00278 00279 00280 00287 00288 std::ostream& operator<<(std::ostream& ostr, const rgb32& c); 00289 00290 00291 std::istream& operator>>(std::istream& istr, rgb32& c); 00292 00293 00294 /* FIXME: We should not need to define these operators, thanks to 00295 Milena's global operator resolution mechanism based on 00296 mln::Object. See what prevent us to use this mechanism. */ 00297 00298 /* FIXME: Cannot work for i negative; add traits! (2008-02-16, 00299 Roland: What does this comment mean?) */ 00300 00303 00304 rgb32::interop 00305 operator+(const rgb32& lhs, const rgb32& rhs); 00306 00307 00308 rgb32::interop 00309 operator+(const rgb32::interop& lhs, const rgb32& rhs); 00310 00311 00312 rgb32::interop 00313 operator+(const rgb32& lhs, const rgb32::interop& rhs); 00315 00318 00319 rgb32::interop 00320 operator-(const rgb32& lhs, const rgb32& rhs); 00321 00322 00323 rgb32::interop 00324 operator-(const rgb32::interop& lhs, const rgb32& rhs); 00325 00326 00327 rgb32::interop 00328 operator-(const rgb32& lhs, const rgb32::interop& rhs); 00330 00333 template <typename S> 00334 inline 00335 rgb32::interop 00336 operator*(const rgb32& lhs, const mln::value::scalar_<S>& s); 00337 00338 template <typename S> 00339 inline 00340 rgb32::interop 00341 operator*(const mln::value::scalar_<S>& s, const rgb32& lhs); 00343 00346 template <typename S> 00347 inline 00348 rgb32::interop 00349 operator/(const rgb32& lhs, const mln::value::scalar_<S>& s); 00351 00352 00353 } // end of namespace mln::value::qt 00354 00355 } // end of namespace mln::value 00356 00357 } // end of namespace mln 00358 00359 00360 00361 # ifndef MLN_INCLUDE_ONLY 00362 00363 namespace mln 00364 { 00365 00366 namespace value 00367 { 00368 00369 namespace qt 00370 { 00371 00372 # ifndef MLN_WO_GLOBAL_VARS 00373 00374 const rgb32 rgb32::zero(0,0,0); 00375 00376 # endif // !MLN_WO_GLOBAL_VARS 00377 00378 00379 /*---------------. 00380 | Construction. | 00381 `---------------*/ 00382 00383 00384 inline 00385 rgb32::rgb32() 00386 { 00387 } 00388 00389 00390 inline 00391 rgb32::rgb32(const algebra::vec<3, int>& v) 00392 { 00393 this->v_[0] = v[2]; 00394 this->v_[1] = v[1]; 00395 this->v_[2] = v[0]; 00396 } 00397 00398 00399 inline 00400 rgb32::rgb32(const algebra::vec<3, unsigned>& v) 00401 { 00402 this->v_[0] = v[2]; 00403 this->v_[1] = v[1]; 00404 this->v_[2] = v[0]; 00405 } 00406 00407 00408 inline 00409 rgb32::rgb32(const algebra::vec<3, int_u<8> >& v) 00410 { 00411 this->v_[0] = v[2]; 00412 this->v_[1] = v[1]; 00413 this->v_[2] = v[0]; 00414 } 00415 00416 00417 inline 00418 rgb32::rgb32(const algebra::vec<3, float>& v) 00419 { 00420 this->v_[0] = unsigned(v[2]); 00421 this->v_[1] = unsigned(v[1]); 00422 this->v_[2] = unsigned(v[0]); 00423 } 00424 00425 00426 inline 00427 rgb32::rgb32(int r, int g, int b) 00428 { 00429 mln_precondition(r >= 0); 00430 mln_precondition(g >= 0); 00431 mln_precondition(b >= 0); 00432 mln_precondition(unsigned(r) <= mln_max(int_u<8>)); 00433 mln_precondition(unsigned(g) <= mln_max(int_u<8>)); 00434 mln_precondition(unsigned(b) <= mln_max(int_u<8>)); 00435 this->v_[0] = b; 00436 this->v_[1] = g; 00437 this->v_[2] = r; 00438 } 00439 00440 00441 inline 00442 rgb32::rgb32(const mln::literal::zero_t&) 00443 { 00444 this->v_[0] = 0; 00445 this->v_[1] = 0; 00446 this->v_[2] = 0; 00447 } 00448 00449 00450 inline 00451 rgb32::rgb32(const mln::literal::white_t&) 00452 { 00453 this->v_[0] = mln_max(int_u<8>); 00454 this->v_[1] = mln_max(int_u<8>); 00455 this->v_[2] = mln_max(int_u<8>); 00456 } 00457 00458 00459 inline 00460 rgb32::rgb32(const mln::literal::black_t&) 00461 { 00462 this->v_[0] = 0; 00463 this->v_[1] = 0; 00464 this->v_[2] = 0; 00465 } 00466 00467 00468 inline 00469 rgb32::rgb32(const mln::literal::light_gray_t&) 00470 { 00471 this->v_[0] = unsigned(mln_max(int_u<8>) * 0.75); 00472 this->v_[1] = unsigned(mln_max(int_u<8>) * 0.75); 00473 this->v_[2] = unsigned(mln_max(int_u<8>) * 0.75); 00474 } 00475 00476 00477 inline 00478 rgb32::rgb32(const mln::literal::medium_gray_t&) 00479 { 00480 this->v_[0] = unsigned(mln_max(int_u<8>) * 0.50); 00481 this->v_[1] = unsigned(mln_max(int_u<8>) * 0.50); 00482 this->v_[2] = unsigned(mln_max(int_u<8>) * 0.50); 00483 } 00484 00485 00486 inline 00487 rgb32::rgb32(const mln::literal::dark_gray_t&) 00488 { 00489 this->v_[0] = unsigned(mln_max(int_u<8>) * 0.25); 00490 this->v_[1] = unsigned(mln_max(int_u<8>) * 0.25); 00491 this->v_[2] = unsigned(mln_max(int_u<8>) * 0.25); 00492 } 00493 00494 00495 inline 00496 rgb32::rgb32(const mln::literal::red_t&) 00497 { 00498 this->v_[0] = 0; 00499 this->v_[1] = 0; 00500 this->v_[2] = mln_max(int_u<8>); 00501 } 00502 00503 00504 inline 00505 rgb32::rgb32(const mln::literal::green_t&) 00506 { 00507 this->v_[0] = 0; 00508 this->v_[1] = mln_max(int_u<8>); 00509 this->v_[2] = 0; 00510 } 00511 00512 00513 inline 00514 rgb32::rgb32(const mln::literal::blue_t&) 00515 { 00516 this->v_[0] = mln_max(int_u<8>); 00517 this->v_[1] = 0; 00518 this->v_[2] = 0; 00519 } 00520 00521 00522 inline 00523 rgb32::rgb32(const mln::literal::brown_t&) 00524 { 00525 this->v_[0] = unsigned(mln_max(int_u<8>) * 0.25); 00526 this->v_[1] = unsigned(mln_max(int_u<8>) * 0.50); 00527 this->v_[2] = unsigned(mln_max(int_u<8>) * 0.75); 00528 } 00529 00530 00531 inline 00532 rgb32::rgb32(const mln::literal::lime_t&) 00533 { 00534 this->v_[0] = 0; 00535 this->v_[1] = mln_max(int_u<8>); 00536 this->v_[2] = unsigned(mln_max(int_u<8>) * 0.75); 00537 } 00538 00539 00540 inline 00541 rgb32::rgb32(const mln::literal::orange_t&) 00542 { 00543 this->v_[0] = 0; 00544 this->v_[1] = unsigned(mln_max(int_u<8>) * 0.50); 00545 this->v_[2] = mln_max(int_u<8>); 00546 } 00547 00548 00549 inline 00550 rgb32::rgb32(const mln::literal::pink_t&) 00551 { 00552 this->v_[0] = unsigned(mln_max(int_u<8>) * 0.75); 00553 this->v_[1] = unsigned(mln_max(int_u<8>) * 0.75); 00554 this->v_[2] = mln_max(int_u<8>); 00555 } 00556 00557 00558 inline 00559 rgb32::rgb32(const mln::literal::purple_t&) 00560 { 00561 this->v_[0] = unsigned(mln_max(int_u<8>) * 0.25); 00562 this->v_[1] = 0; 00563 this->v_[2] = unsigned(mln_max(int_u<8>) * 0.75); 00564 } 00565 00566 00567 inline 00568 rgb32::rgb32(const mln::literal::teal_t&) 00569 { 00570 this->v_[0] = unsigned(mln_max(int_u<8>) * 0.50); 00571 this->v_[1] = unsigned(mln_max(int_u<8>) * 0.50); 00572 this->v_[2] = 0; 00573 } 00574 00575 00576 inline 00577 rgb32::rgb32(const mln::literal::violet_t&) 00578 { 00579 this->v_[0] = unsigned(mln_max(int_u<8>) * 0.50); 00580 this->v_[1] = 0; 00581 this->v_[2] = unsigned(mln_max(int_u<8>) * 0.50); 00582 } 00583 00584 00585 inline 00586 rgb32::rgb32(const mln::literal::cyan_t&) 00587 { 00588 this->v_[0] = mln_max(int_u<8>); 00589 this->v_[1] = mln_max(int_u<8>); 00590 this->v_[2] = 0; 00591 } 00592 00593 00594 inline 00595 rgb32::rgb32(const mln::literal::magenta_t&) 00596 { 00597 this->v_[0] = mln_max(int_u<8>); 00598 this->v_[1] = 0; 00599 this->v_[2] = mln_max(int_u<8>); 00600 } 00601 00602 00603 inline 00604 rgb32::rgb32(const mln::literal::yellow_t&) 00605 { 00606 this->v_[0] = 0; 00607 this->v_[1] = mln_max(int_u<8>); 00608 this->v_[2] = mln_max(int_u<8>); 00609 } 00610 00611 00612 inline 00613 rgb32::rgb32(const mln::literal::olive_t&) 00614 { 00615 this->v_[0] = 0; 00616 this->v_[1] = unsigned(mln_max(int_u<8>) * 0.50); 00617 this->v_[2] = unsigned(mln_max(int_u<8>) * 0.50); 00618 } 00619 00620 00621 inline 00622 rgb32& 00623 rgb32::operator=(const rgb32& rhs) 00624 { 00625 if (& rhs == this) 00626 return *this; 00627 this->v_ = rhs.v_; 00628 return *this; 00629 } 00630 00631 00632 inline 00633 rgb32::operator algebra::vec<3, int>() const 00634 { 00635 algebra::vec<3, int> out; 00636 out[0] = this->v_[2]; 00637 out[1] = this->v_[1]; 00638 out[2] = this->v_[0]; 00639 return out; 00640 } 00641 00642 inline 00643 rgb32::operator algebra::vec<3, float>() const 00644 { 00645 algebra::vec<3, float> out; 00646 out[0] = this->v_[2]; 00647 out[1] = this->v_[1]; 00648 out[2] = this->v_[0]; 00649 return out; 00650 } 00651 00652 00653 /*------------. 00654 | Operators. | 00655 `------------*/ 00656 00657 00658 inline 00659 rgb32::interop 00660 operator+(const rgb32& lhs, const rgb32& rhs) 00661 { 00662 rgb32::interop tmp(lhs.to_interop() + rhs.to_interop()); 00663 return tmp; 00664 } 00665 00666 00667 inline 00668 rgb32::interop 00669 operator+(const rgb32& lhs, const rgb32::interop& rhs) 00670 { 00671 rgb32::interop tmp(lhs.to_interop() + rhs); 00672 return tmp; 00673 } 00674 00675 00676 inline 00677 rgb32::interop 00678 operator+(const rgb32::interop& lhs, const rgb32& rhs) 00679 { 00680 rgb32::interop tmp(lhs + rhs.to_interop()); 00681 return tmp; 00682 } 00683 00684 00685 inline 00686 rgb32::interop 00687 operator-(const rgb32& lhs, const rgb32& rhs) 00688 { 00689 rgb32::interop tmp(lhs.to_interop() - rhs.to_interop()); 00690 return tmp; 00691 } 00692 00693 00694 inline 00695 rgb32::interop 00696 operator-(const rgb32& lhs, const rgb32::interop& rhs) 00697 { 00698 rgb32::interop tmp(lhs.to_interop() - rhs); 00699 return tmp; 00700 } 00701 00702 00703 inline 00704 rgb32::interop 00705 operator-(const rgb32::interop& lhs, const rgb32& rhs) 00706 { 00707 rgb32::interop tmp(lhs - rhs.to_interop()); 00708 return tmp; 00709 } 00710 00711 template <typename S> 00712 inline 00713 rgb32::interop 00714 operator*(const rgb32& lhs, const mln::value::scalar_<S>& s) 00715 { 00716 rgb32::interop tmp(lhs.to_interop() * s.to_equiv()); 00717 return tmp; 00718 } 00719 00720 template <typename S> 00721 inline 00722 rgb32::interop 00723 operator*(const mln::value::scalar_<S>& s, const rgb32& lhs) 00724 { 00725 rgb32::interop tmp(s.to_equiv() * lhs.to_interop()); 00726 return tmp; 00727 } 00728 00729 template <typename S> 00730 inline 00731 rgb32::interop 00732 operator/(const rgb32& lhs, const mln::value::scalar_<S>& s) 00733 { 00734 rgb32::interop tmp(lhs.to_interop() / s.to_equiv()); 00735 return tmp; 00736 } 00737 00738 00739 inline 00740 std::ostream& operator<<(std::ostream& ostr, const rgb32& v) 00741 { 00742 return ostr << '(' << debug::format(v.red()) 00743 << ',' << debug::format(v.green()) 00744 << ',' << debug::format(v.blue()) 00745 << ')'; 00746 } 00747 00748 00749 inline 00750 std::istream& operator>>(std::istream& istr, rgb32& c) 00751 { 00752 return istr >> c.red() >> c.green() >> c.blue(); 00753 } 00754 00755 } // end of namespace mln::value::qt 00756 00757 } // end of namespace mln::value 00758 00759 00760 namespace convert 00761 { 00762 00763 namespace over_load 00764 { 00765 00766 // int_u -> qt::rgb32 00767 template <unsigned m> 00768 void 00769 from_to_(const value::int_u<m>& from, value::qt::rgb32& to) 00770 { 00771 mlc_bool(m <= 8)::check(); 00772 to = value::qt::rgb32(from, from, from); 00773 } 00774 00775 00776 // hsl -> rgb8. 00777 template <typename H, typename S, typename L> 00778 void from_to_(const value::hsl_<H,S,L>& from, value::qt::rgb32& to) 00779 { 00780 value::rgb8 v = fun::v2v::f_hsl_to_rgb_3x8(from); 00781 to = v.to_equiv(); 00782 } 00783 00784 00785 // qt::rgb32 -> bool 00786 inline 00787 void from_to_(const value::qt::rgb32& from, bool& to) 00788 { 00789 to = ((from == literal::black) ? false : true); 00790 } 00791 00792 00793 // bool -> qt::rgb32 00794 inline 00795 void from_to_(const bool& from, value::qt::rgb32& to) 00796 { 00797 if (from) 00798 to = literal::white; 00799 else 00800 to = literal::black; 00801 } 00802 00803 00804 } // end of namespace mln::convert::over_load 00805 00806 } // end of namespace mln::convert 00807 00808 } // end of namespace mln 00809 00810 # endif // ! MLN_INCLUDE_ONLY 00811 00812 00813 #endif // ! MLN_VALUE_QT_RGB32_HH