Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2008, 2009 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_HSL_HH 00027 # define MLN_VALUE_HSL_HH 00028 00029 #include <mln/value/ops.hh> 00030 00031 #include <mln/value/concept/vectorial.hh> 00032 #include <mln/value/int_u.hh> 00033 #include <mln/algebra/vec.hh> 00034 00035 // Used in from_to 00036 #include <mln/fun/v2v/rgb_to_hsl.hh> 00037 00038 00039 namespace mln 00040 { 00041 00042 // Forward declarations. 00043 namespace value 00044 { 00045 00046 template <typename H, typename S, typename L> 00047 class hsl_; 00048 00049 } 00050 00051 00052 00053 namespace convert 00054 { 00055 00056 namespace over_load 00057 { 00058 00059 // rgb to hsl_ 00060 void 00061 from_to_(const value::rgb<16>& from, value::hsl_<float,float,float>& to); 00062 00063 // rgb to hsl_ 00064 void 00065 from_to_(const value::rgb<8>& from, value::hsl_<float,float,float>& to); 00066 00067 } // end of namespace mln::convert::over_load 00068 00069 } // end of namespace mln::convert 00070 00071 00072 00073 namespace trait 00074 { 00075 00076 template <typename H, typename S, typename L> 00077 struct set_precise_binary_< op::plus, mln::value::hsl_<H,S,L>, mln::value::hsl_<H,S,L> > 00078 { 00079 typedef mln::value::hsl_<H,S,L> ret; 00080 }; 00081 00082 template <typename H, typename S, typename L> 00083 struct set_precise_binary_< op::minus, mln::value::hsl_<H,S,L>, mln::value::hsl_<H,S,L> > 00084 { 00085 typedef mln::value::hsl_<H,S,L> ret; 00086 }; 00087 00088 template <typename H, typename S, typename L, typename S2> 00089 struct set_precise_binary_< op::times, mln::value::hsl_<H,S,L>, mln::value::scalar_<S2> > 00090 { 00091 typedef mln::value::hsl_<H,S,L> ret; 00092 }; 00093 00094 template <typename H, typename S, typename L, typename S2> 00095 struct set_precise_binary_< op::div, mln::value::hsl_<H,S,L>, mln::value::scalar_<S2> > 00096 { 00097 typedef mln::value::hsl_<H,S,L> ret; 00098 }; 00099 00100 00101 // FIXME : Is there any way more generic? a way to factor 00102 // set_precise_binary_< op::div, mln::value::hsl_<H,S,L>, mln::value::scalar_<S> > 00103 // and 00104 // set_precise_binary_< op::div, mln::value::hsl_<H,S,L>, mln::value::int_u<m> > 00105 // as for op::times. 00106 00107 template <typename H, typename S, typename L, unsigned m> 00108 struct set_precise_binary_< op::times, mln::value::hsl_<H,S,L>, mln::value::int_u<m> > 00109 { 00110 typedef mln::value::hsl_<H,S,L> ret; 00111 }; 00112 00113 template <typename H, typename S, typename L, unsigned m> 00114 struct set_precise_binary_< op::div, mln::value::hsl_<H,S,L>, mln::value::int_u<m> > 00115 { 00116 typedef mln::value::hsl_<H,S,L> ret; 00117 }; 00118 00119 template <typename H, typename S, typename L> 00120 struct value_< mln::value::hsl_<H,S,L> > 00121 { 00122 enum { 00123 dim = 3, 00124 nbits = (sizeof (H) + sizeof (S) + sizeof (L)) * 8, 00125 card = mln_value_card_from_(nbits) 00126 }; 00127 00128 typedef trait::value::nature::vectorial nature; 00129 typedef trait::value::kind::color kind; 00130 typedef mln_value_quant_from_(card) quant; 00131 00132 typedef void comp; 00133 typedef H comp_0; 00134 typedef S comp_1; 00135 typedef L comp_2; 00136 00137 template <typename V> static comp_0 get_comp_0(const V& v) { return v.hue(); } 00138 template <typename V> static comp_1 get_comp_1(const V& v) { return v.sat(); } 00139 template <typename V> static comp_2 get_comp_2(const V& v) { return v.lum(); } 00140 00141 // typedef algebra::vec<3, float> sum; 00142 typedef mln::value::hsl_<H,S,L> sum; 00143 }; 00144 00145 } // end of namespace trait 00146 00147 00148 namespace value 00149 { 00150 00151 template <typename E> 00152 struct HSL : Object<E> 00153 { 00154 }; 00155 00156 template <typename H, typename S, typename L> 00157 class hsl_ : public HSL< hsl_<H,S,L> > 00158 { 00159 public: 00160 00161 typedef H h_type; 00162 typedef S s_type; 00163 typedef L l_type; 00164 00166 hsl_() 00167 { 00168 } 00169 00170 hsl_(const literal::zero_t&) 00171 : hue_(0), 00172 sat_(0), 00173 lum_(0) 00174 { 00175 } 00176 00178 hsl_(const H& hue, const S& sat, const L& lum) 00179 : hue_(hue), 00180 sat_(sat), 00181 lum_(lum) 00182 { 00183 } 00184 00186 const H& hue() const; 00187 const S& sat() const; 00188 const L& lum() const; 00189 00191 H& hue(); 00192 S& sat(); 00193 L& lum(); 00194 00195 private: 00196 //FIXME: Don't we want to store these values in a vector? 00197 H hue_; 00198 S sat_; 00199 L lum_; 00200 }; 00201 00202 00203 // FIXME: Use float01_8/float01_16 ? 00204 typedef hsl_<float, float, float> hsl_f; 00205 00206 typedef hsl_<double, double, double> hsl_d; 00207 00208 00215 template <typename H, typename S, typename L> 00216 std::ostream& operator<<(std::ostream& ostr, const hsl_<H,S,L>& c); 00217 00218 00221 template <typename H, typename S, typename L> 00222 hsl_<H,S,L> 00223 operator+(const hsl_<H,S,L>& lhs, const hsl_<H,S,L>& rhs); 00225 00228 template <typename H, typename S, typename L> 00229 hsl_<H,S,L> 00230 operator-(const hsl_<H,S,L>& lhs, const hsl_<H,S,L>& rhs); 00232 00235 template <typename H, typename S, typename L, typename S2> 00236 hsl_<H,S,L> 00237 operator*(const hsl_<H,S,L>& lhs, const mln::value::scalar_<S2>& s); 00239 00242 template <typename H, typename S, typename L, typename S2> 00243 hsl_<H,S,L> 00244 operator/(const hsl_<H,S,L>& lhs, const mln::value::scalar_<S2>& s); 00246 00249 template <typename H, typename S, typename L> 00250 bool 00251 operator==(const hsl_<H,S,L>& lhs, const hsl_<H,S,L>& rhs); 00253 00254 } // end of namespace mln::value 00255 00256 00257 00258 // More forward declarations 00259 namespace fun 00260 { 00261 namespace v2v 00262 { 00263 00264 template <typename T_hsl> 00265 struct f_rgb_to_hsl_; 00266 00267 typedef f_rgb_to_hsl_<value::hsl_f> f_rgb_to_hsl_f_t; 00268 00269 extern f_rgb_to_hsl_f_t f_rgb_to_hsl_f; 00270 00271 } 00272 00273 } 00274 00275 # ifndef MLN_INCLUDE_ONLY 00276 00277 00278 namespace value 00279 { 00280 00281 template <typename H, typename S, typename L> 00282 const H& 00283 hsl_<H,S,L>::hue() const 00284 { 00285 return this->hue_; 00286 } 00287 00288 template <typename H, typename S, typename L> 00289 const S& 00290 hsl_<H,S,L>::sat() const 00291 { 00292 return this->sat_; 00293 } 00294 00295 template <typename H, typename S, typename L> 00296 const L& 00297 hsl_<H,S,L>::lum() const 00298 { 00299 return this->lum_; 00300 } 00301 00302 template <typename H, typename S, typename L> 00303 H& 00304 hsl_<H,S,L>::hue() 00305 { 00306 return this->hue_; 00307 } 00308 00309 template <typename H, typename S, typename L> 00310 S& 00311 hsl_<H,S,L>::sat() 00312 { 00313 return this->sat_; 00314 } 00315 00316 template <typename H, typename S, typename L> 00317 L& 00318 hsl_<H,S,L>::lum() 00319 { 00320 return this->lum_; 00321 } 00322 00323 00324 template <typename H, typename S, typename L> 00325 inline 00326 std::ostream& operator<<(std::ostream& ostr, const hsl_<H,S,L>& v) 00327 { 00328 return ostr << '(' << debug::format(v.hue()) 00329 << ',' << debug::format(v.sat()) 00330 << ',' << debug::format(v.lum()) 00331 << ')'; 00332 } 00333 00334 00335 template <typename H, typename S, typename L> 00336 hsl_<H,S,L> 00337 operator+(const hsl_<H,S,L>& lhs, const hsl_<H,S,L>& rhs) 00338 { 00339 return hsl_<H,S,L>(lhs.hue() + rhs.hue(), 00340 lhs.sat() + rhs.sat(), 00341 lhs.lum() + rhs.lum()); 00342 } 00343 00344 00345 template <typename H, typename S, typename L> 00346 hsl_<H,S,L> 00347 operator-(const hsl_<H,S,L>& lhs, const hsl_<H,S,L>& rhs) 00348 { 00349 return hsl_<H,S,L>(lhs.hue() - rhs.hue(), 00350 lhs.sat() - rhs.sat(), 00351 lhs.lum() - rhs.lum()); 00352 } 00353 00354 00355 template <typename H, typename S, typename L, typename S2> 00356 hsl_<H,S,L> 00357 operator*(const hsl_<H,S,L>& lhs, const mln::value::scalar_<S2>& s) 00358 { 00359 return hsl_<H,S,L>(lhs.hue() * s, 00360 lhs.sat() * s, 00361 lhs.lum() * s); 00362 } 00363 00364 00365 template <typename H, typename S, typename L, typename S2> 00366 hsl_<H,S,L> 00367 operator/(const hsl_<H,S,L>& lhs, const mln::value::scalar_<S2>& s) 00368 { 00369 return hsl_<H,S,L>(lhs.hue() / s, 00370 lhs.sat() / s, 00371 lhs.lum() / s); 00372 } 00373 00374 template <typename H, typename S, typename L> 00375 bool 00376 operator==(const hsl_<H,S,L>& lhs, const hsl_<H,S,L>& rhs) 00377 { 00378 return lhs.hue() == rhs.hue() 00379 && lhs.sat() == rhs.sat() 00380 && lhs.lum() == rhs.lum(); 00381 } 00382 00383 } // end of namespace mln::value 00384 00385 00386 namespace convert 00387 { 00388 00389 namespace over_load 00390 { 00391 00392 inline 00393 void 00394 from_to_(const value::rgb<16>& from, value::hsl_<float,float,float>& to) 00395 { 00396 to = fun::v2v::f_rgb_to_hsl_f(from); 00397 } 00398 00399 inline 00400 void 00401 from_to_(const value::rgb<8>& from, value::hsl_<float,float,float>& to) 00402 { 00403 to = fun::v2v::f_rgb_to_hsl_f(from); 00404 } 00405 00406 } // end of namespace mln::convert::over_load 00407 00408 } // end of namespace mln::convert 00409 00410 00411 # endif // ! MLN_INCLUDE_ONLY 00412 00413 00414 } // end of namespace mln 00415 00416 #endif // ! MLN_VALUE_HSL_HH