• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List

rgb32.hh

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       /*---------------.
00373       | Construction.  |
00374       `---------------*/
00375 
00376 
00377       inline
00378       rgb32::rgb32()
00379       {
00380       }
00381 
00382 
00383       inline
00384       rgb32::rgb32(const algebra::vec<3, int>& v)
00385       {
00386         this->v_[0] = v[2];
00387         this->v_[1] = v[1];
00388         this->v_[2] = v[0];
00389       }
00390 
00391 
00392       inline
00393       rgb32::rgb32(const algebra::vec<3, unsigned>& v)
00394       {
00395         this->v_[0] = v[2];
00396         this->v_[1] = v[1];
00397         this->v_[2] = v[0];
00398       }
00399 
00400 
00401       inline
00402       rgb32::rgb32(const algebra::vec<3, int_u<8> >& v)
00403       {
00404         this->v_[0] = v[2];
00405         this->v_[1] = v[1];
00406         this->v_[2] = v[0];
00407       }
00408 
00409 
00410       inline
00411       rgb32::rgb32(const algebra::vec<3, float>& v)
00412       {
00413         this->v_[0] = unsigned(v[2]);
00414         this->v_[1] = unsigned(v[1]);
00415         this->v_[2] = unsigned(v[0]);
00416       }
00417 
00418 
00419       inline
00420       rgb32::rgb32(int r, int g, int b)
00421       {
00422         mln_precondition(r >= 0);
00423         mln_precondition(g >= 0);
00424         mln_precondition(b >= 0);
00425         mln_precondition(unsigned(r) <= mln_max(int_u<8>));
00426         mln_precondition(unsigned(g) <= mln_max(int_u<8>));
00427         mln_precondition(unsigned(b) <= mln_max(int_u<8>));
00428         this->v_[0] = b;
00429         this->v_[1] = g;
00430         this->v_[2] = r;
00431       }
00432 
00433 
00434       inline
00435       rgb32::rgb32(const mln::literal::zero_t&)
00436       {
00437         this->v_[0] = 0;
00438         this->v_[1] = 0;
00439         this->v_[2] = 0;
00440       }
00441 
00442 
00443       inline
00444       rgb32::rgb32(const mln::literal::white_t&)
00445       {
00446         this->v_[0] = mln_max(int_u<8>);
00447         this->v_[1] = mln_max(int_u<8>);
00448         this->v_[2] = mln_max(int_u<8>);
00449       }
00450 
00451 
00452       inline
00453       rgb32::rgb32(const mln::literal::black_t&)
00454       {
00455         this->v_[0] = 0;
00456         this->v_[1] = 0;
00457         this->v_[2] = 0;
00458       }
00459 
00460 
00461       inline
00462       rgb32::rgb32(const mln::literal::light_gray_t&)
00463       {
00464         this->v_[0] = unsigned(mln_max(int_u<8>) * 0.75);
00465         this->v_[1] = unsigned(mln_max(int_u<8>) * 0.75);
00466         this->v_[2] = unsigned(mln_max(int_u<8>) * 0.75);
00467       }
00468 
00469 
00470       inline
00471       rgb32::rgb32(const mln::literal::medium_gray_t&)
00472       {
00473         this->v_[0] = unsigned(mln_max(int_u<8>) * 0.50);
00474         this->v_[1] = unsigned(mln_max(int_u<8>) * 0.50);
00475         this->v_[2] = unsigned(mln_max(int_u<8>) * 0.50);
00476       }
00477 
00478 
00479       inline
00480       rgb32::rgb32(const mln::literal::dark_gray_t&)
00481       {
00482         this->v_[0] = unsigned(mln_max(int_u<8>) * 0.25);
00483         this->v_[1] = unsigned(mln_max(int_u<8>) * 0.25);
00484         this->v_[2] = unsigned(mln_max(int_u<8>) * 0.25);
00485       }
00486 
00487 
00488       inline
00489       rgb32::rgb32(const mln::literal::red_t&)
00490       {
00491         this->v_[0] = 0;
00492         this->v_[1] = 0;
00493         this->v_[2] = mln_max(int_u<8>);
00494       }
00495 
00496 
00497       inline
00498       rgb32::rgb32(const mln::literal::green_t&)
00499       {
00500         this->v_[0] = 0;
00501         this->v_[1] = mln_max(int_u<8>);
00502         this->v_[2] = 0;
00503       }
00504 
00505 
00506       inline
00507       rgb32::rgb32(const mln::literal::blue_t&)
00508       {
00509         this->v_[0] = mln_max(int_u<8>);
00510         this->v_[1] = 0;
00511         this->v_[2] = 0;
00512       }
00513 
00514 
00515       inline
00516       rgb32::rgb32(const mln::literal::brown_t&)
00517       {
00518         this->v_[0] = unsigned(mln_max(int_u<8>) * 0.25);
00519         this->v_[1] = unsigned(mln_max(int_u<8>) * 0.50);
00520         this->v_[2] = unsigned(mln_max(int_u<8>) * 0.75);
00521       }
00522 
00523 
00524       inline
00525       rgb32::rgb32(const mln::literal::lime_t&)
00526       {
00527         this->v_[0] = 0;
00528         this->v_[1] = mln_max(int_u<8>);
00529         this->v_[2] = unsigned(mln_max(int_u<8>) * 0.75);
00530       }
00531 
00532 
00533       inline
00534       rgb32::rgb32(const mln::literal::orange_t&)
00535       {
00536         this->v_[0] = 0;
00537         this->v_[1] = unsigned(mln_max(int_u<8>) * 0.50);
00538         this->v_[2] = mln_max(int_u<8>);
00539       }
00540 
00541 
00542       inline
00543       rgb32::rgb32(const mln::literal::pink_t&)
00544       {
00545         this->v_[0] = unsigned(mln_max(int_u<8>) * 0.75);
00546         this->v_[1] = unsigned(mln_max(int_u<8>) * 0.75);
00547         this->v_[2] = mln_max(int_u<8>);
00548       }
00549 
00550 
00551       inline
00552       rgb32::rgb32(const mln::literal::purple_t&)
00553       {
00554         this->v_[0] = unsigned(mln_max(int_u<8>) * 0.25);
00555         this->v_[1] = 0;
00556         this->v_[2] = unsigned(mln_max(int_u<8>) * 0.75);
00557       }
00558 
00559 
00560       inline
00561       rgb32::rgb32(const mln::literal::teal_t&)
00562       {
00563         this->v_[0] = unsigned(mln_max(int_u<8>) * 0.50);
00564         this->v_[1] = unsigned(mln_max(int_u<8>) * 0.50);
00565         this->v_[2] = 0;
00566       }
00567 
00568 
00569       inline
00570       rgb32::rgb32(const mln::literal::violet_t&)
00571       {
00572         this->v_[0] = unsigned(mln_max(int_u<8>) * 0.50);
00573         this->v_[1] = 0;
00574         this->v_[2] = unsigned(mln_max(int_u<8>) * 0.50);
00575       }
00576 
00577 
00578       inline
00579       rgb32::rgb32(const mln::literal::cyan_t&)
00580       {
00581         this->v_[0] = mln_max(int_u<8>);
00582         this->v_[1] = mln_max(int_u<8>);
00583         this->v_[2] = 0;
00584       }
00585 
00586 
00587       inline
00588       rgb32::rgb32(const mln::literal::magenta_t&)
00589       {
00590         this->v_[0] = mln_max(int_u<8>);
00591         this->v_[1] = 0;
00592         this->v_[2] = mln_max(int_u<8>);
00593       }
00594 
00595 
00596       inline
00597       rgb32::rgb32(const mln::literal::yellow_t&)
00598       {
00599         this->v_[0] = 0;
00600         this->v_[1] = mln_max(int_u<8>);
00601         this->v_[2] = mln_max(int_u<8>);
00602       }
00603 
00604 
00605       inline
00606       rgb32::rgb32(const mln::literal::olive_t&)
00607       {
00608         this->v_[0] = 0;
00609         this->v_[1] = unsigned(mln_max(int_u<8>) * 0.50);
00610         this->v_[2] = unsigned(mln_max(int_u<8>) * 0.50);
00611       }
00612 
00613 
00614       inline
00615       rgb32&
00616       rgb32::operator=(const rgb32& rhs)
00617       {
00618         if (& rhs == this)
00619           return *this;
00620         this->v_ = rhs.v_;
00621         return *this;
00622       }
00623 
00624 
00625       inline
00626       rgb32::operator algebra::vec<3, int>() const
00627       {
00628         algebra::vec<3, int> out;
00629         out[0] = this->v_[2];
00630         out[1] = this->v_[1];
00631         out[2] = this->v_[0];
00632         return out;
00633       }
00634 
00635       inline
00636       rgb32::operator algebra::vec<3, float>() const
00637       {
00638         algebra::vec<3, float> out;
00639         out[0] = this->v_[2];
00640         out[1] = this->v_[1];
00641         out[2] = this->v_[0];
00642         return out;
00643       }
00644 
00645 
00646       /*------------.
00647       | Operators.  |
00648       `------------*/
00649 
00650 
00651       inline
00652       rgb32::interop
00653       operator+(const rgb32& lhs, const rgb32& rhs)
00654       {
00655         rgb32::interop tmp(lhs.to_interop() + rhs.to_interop());
00656         return tmp;
00657       }
00658 
00659 
00660       inline
00661       rgb32::interop
00662       operator+(const rgb32& lhs, const rgb32::interop& rhs)
00663       {
00664         rgb32::interop tmp(lhs.to_interop() + rhs);
00665         return tmp;
00666       }
00667 
00668 
00669       inline
00670       rgb32::interop
00671       operator+(const rgb32::interop& lhs, const rgb32& rhs)
00672       {
00673         rgb32::interop tmp(lhs + rhs.to_interop());
00674         return tmp;
00675       }
00676 
00677 
00678       inline
00679       rgb32::interop
00680       operator-(const rgb32& lhs, const rgb32& rhs)
00681       {
00682         rgb32::interop tmp(lhs.to_interop() - rhs.to_interop());
00683         return tmp;
00684       }
00685 
00686 
00687       inline
00688       rgb32::interop
00689       operator-(const rgb32& lhs, const rgb32::interop& rhs)
00690       {
00691         rgb32::interop tmp(lhs.to_interop() - rhs);
00692         return tmp;
00693       }
00694 
00695 
00696       inline
00697       rgb32::interop
00698       operator-(const rgb32::interop& lhs, const rgb32& rhs)
00699       {
00700         rgb32::interop tmp(lhs - rhs.to_interop());
00701         return tmp;
00702       }
00703 
00704       template <typename S>
00705       inline
00706       rgb32::interop
00707       operator*(const rgb32& lhs, const mln::value::scalar_<S>& s)
00708       {
00709         rgb32::interop tmp(lhs.to_interop() * s.to_equiv());
00710         return tmp;
00711       }
00712 
00713       template <typename S>
00714       inline
00715       rgb32::interop
00716       operator*(const mln::value::scalar_<S>& s, const rgb32& lhs)
00717       {
00718         rgb32::interop tmp(s.to_equiv() * lhs.to_interop());
00719         return tmp;
00720       }
00721 
00722       template <typename S>
00723       inline
00724       rgb32::interop
00725       operator/(const rgb32& lhs, const mln::value::scalar_<S>& s)
00726       {
00727         rgb32::interop tmp(lhs.to_interop() / s.to_equiv());
00728         return tmp;
00729       }
00730 
00731 
00732       inline
00733       std::ostream& operator<<(std::ostream& ostr, const rgb32& v)
00734       {
00735         return ostr << '(' << debug::format(v.red())
00736                     << ',' << debug::format(v.green())
00737                     << ',' << debug::format(v.blue())
00738                     << ')';
00739       }
00740 
00741 
00742       inline
00743       std::istream& operator>>(std::istream& istr, rgb32& c)
00744       {
00745         return istr >> c.red() >> c.green() >> c.blue();
00746       }
00747 
00748     } // end of namespace mln::value::qt
00749 
00750   } // end of namespace mln::value
00751 
00752 
00753   namespace convert
00754   {
00755 
00756     namespace over_load
00757     {
00758 
00759       template <unsigned m>
00760       void
00761       from_to_(const value::int_u<m>& from, value::qt::rgb32& to)
00762       {
00763         mlc_bool(m <= 8)::check();
00764         to = value::qt::rgb32(from, from, from);
00765       }
00766 
00767 
00768       // hsl -> rgb8.
00769       template <typename H, typename S, typename L>
00770       void from_to_(const value::hsl_<H,S,L>& from, value::qt::rgb32& to)
00771       {
00772         value::rgb8 v = fun::v2v::f_hsl_to_rgb_3x8(from);
00773         to = v.to_equiv();
00774       }
00775 
00776 
00777       inline
00778       void from_to_(const value::qt::rgb32& from, bool& to)
00779       {
00780         to = ((from == literal::black) ? false : true);
00781       }
00782 
00783 
00784       inline
00785       void from_to_(const bool& from, value::qt::rgb32& to)
00786       {
00787         if (from)
00788           to = literal::white;
00789         else
00790           to = literal::black;
00791       }
00792 
00793 
00794     } // end of namespace mln::convert::over_load
00795 
00796   } // end of namespace mln::convert
00797 
00798 } // end of namespace mln
00799 
00800 # endif // ! MLN_INCLUDE_ONLY
00801 
00802 
00803 #endif // ! MLN_VALUE_QT_RGB32_HH

Generated on Fri Oct 19 2012 04:16:20 for Milena (Olena) by  doxygen 1.7.1