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

rgb.hh

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

Generated on Fri Sep 16 2011 16:34:00 for Milena (Olena) by  doxygen 1.7.1