Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2006, 2007, 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_GRAYLEVEL_HH 00027 # define MLN_VALUE_GRAYLEVEL_HH 00028 00032 00033 # include <iostream> 00034 00035 # include <mln/value/ops.hh> 00036 00037 # include <mln/core/contract.hh> 00038 # include <mln/metal/math/pow.hh> 00039 # include <mln/metal/math/max.hh> 00040 # include <mln/metal/bexpr.hh> 00041 # include <mln/literal/ops.hh> 00042 00043 # include <mln/value/graylevel_f.hh> 00044 # include <mln/value/int_u.hh> 00045 # include <mln/trait/value_.hh> 00046 00047 00048 namespace mln 00049 { 00050 00051 namespace literal 00052 { 00054 struct black_t; 00055 struct medium_gray_t; 00056 struct white_t; 00058 } 00059 namespace value 00060 { 00061 00063 namespace internal 00064 { 00065 template <unsigned n> class gray_; 00066 struct gray_f; 00067 template <unsigned n_src, unsigned n_dest> 00068 long convert(int val); 00069 } 00070 template <unsigned n> struct graylevel; 00071 struct float01_f; 00073 } 00074 00075 00076 00077 namespace trait 00078 { 00079 00080 template < unsigned n, unsigned m > 00081 struct set_precise_binary_< op::plus, mln::value::graylevel<n>, mln::value::graylevel<m> > 00082 { 00083 typedef mln::value::internal::gray_< mlc_max_int(n, m) > ret; 00084 }; 00085 00086 template < unsigned n, unsigned m > 00087 struct set_precise_binary_< op::minus, mln::value::graylevel<n>, mln::value::graylevel<m> > 00088 { 00089 typedef mln::value::internal::gray_< mlc_max_int(m, n) > ret; 00090 }; 00091 00092 template < unsigned n, unsigned m > 00093 struct set_precise_binary_< op::times, mln::value::graylevel<n>, mln::value::graylevel<m> > 00094 { 00095 typedef mln::value::internal::gray_<mlc_max_int(m, n)> ret; 00096 }; 00097 00098 template < unsigned n, unsigned m > 00099 struct set_precise_binary_< op::div, mln::value::graylevel<n>, mln::value::graylevel<m> > 00100 { 00101 typedef mln::value::internal::gray_f ret; 00102 }; 00103 00104 template < unsigned n, typename I > 00105 struct set_binary_< op::times, 00106 mln::value::Integer, mln::value::graylevel<n>, 00107 mln::value::Integer, I > 00108 { 00109 typedef mln::value::internal::gray_<n> ret; 00110 }; 00111 00112 template < typename I, unsigned n > 00113 struct set_binary_< op::times, 00114 mln::value::Integer, I, 00115 mln::value::Integer, mln::value::graylevel<n> > 00116 { 00117 typedef mln::value::internal::gray_<n> ret; 00118 }; 00119 00120 00121 template < unsigned n, typename F > 00122 struct set_binary_< op::times, 00123 mln::value::Integer, mln::value::graylevel<n>, 00124 mln::value::Floating, F > 00125 { 00126 typedef mln::value::internal::gray_f ret; 00127 }; 00128 00129 template < typename F, unsigned n > 00130 struct set_binary_< op::times, 00131 mln::value::Floating, F, 00132 mln::value::Integer, mln::value::graylevel<n> > 00133 { 00134 typedef mln::value::internal::gray_f ret; 00135 }; 00136 00137 00138 template < unsigned n, typename S > 00139 struct set_precise_binary_< op::times, mln::value::graylevel<n>, mln::value::scalar_<S> > 00140 { 00141 typedef mln_value_equiv(S) E; 00142 typedef mln::metal::or_< mlc_equal(E, float), mlc_equal(E, double) > is_float; 00143 typedef mlc_if(is_float, mln::value::internal::gray_f, mln::value::internal::gray_<n>) ret; 00144 }; 00145 00146 template < unsigned n, typename S > 00147 struct set_precise_binary_< op::div, mln::value::graylevel<n>, mln::value::scalar_<S> > 00148 { 00149 typedef mln::value::internal::gray_f ret; 00150 }; 00151 00152 // 'graylevel<n>' as a value. 00153 00154 template <unsigned n> 00155 struct value_< mln::value::graylevel<n> > 00156 { 00157 private: 00158 typedef mln::value::graylevel<n> self_; 00159 public: 00160 00161 enum { 00162 dim = 1, 00163 nbits = n, 00164 card = mln_value_card_from_(n) 00165 }; 00166 00167 typedef trait::value::nature::integer nature; // FIXME: Or scalar?. 00168 typedef trait::value::kind::gray kind; 00169 typedef mln_value_quant_from_(card) quant; 00170 00171 static const self_ min() { return 0; } 00172 static const self_ max() { return card - 1; } 00173 static const self_ epsilon() { return 0; } 00174 00175 typedef mln::value::int_u<n> comp; 00176 00177 typedef float sum; 00178 }; 00179 00180 } // end of namespace mln::trait 00181 00182 00183 00184 namespace value 00185 { 00186 00188 00189 // Return types of the operators +-*/. 00190 00191 // Operators + - return the interoperability type to allow 00192 // operations like (gl8(255) + gl8(255)) / 2. + - with int and 00193 // float are not allowed. 00194 00195 // If you really need to act with the value 00196 // of the gray_<n> (the encoding). use the to_enc() method. 00197 // 00198 00199 // |--------------------------------------------| 00200 // | + || gl | glf |gray_n | int | float | 00201 // |============================================| 00202 // |gl ||gray_n|gray_f |gray_n | X | X | 00203 // |--------------------------------------------| 00204 // |glf || |gray_f |gray_f | X | X | 00205 // |--------------------------------------------| 00206 // |gray|| |gray_n | X | X | 00207 // |--------------------------------------------| 00208 00209 // |--------------------------------------------| 00210 // | - || gl | glf |gray_n | int | float | 00211 // |============================================| 00212 // |gl ||gray_n|gray_f |gray_n | X | X | 00213 // |--------------------------------------------| 00214 // |glf || |gray_f |gray_f | X | X | 00215 // |--------------------------------------------| 00216 // |gray|| |gray_n | X | X | 00217 // |--------------------------------------------| 00218 00219 // |--------------------------------------------| 00220 // | * || gl | glf |gray_n | int | float | 00221 // |============================================| 00222 // |gl ||gray_n|gray_f |gray_n |gray_n |gray_f | 00223 // |--------------------------------------------| 00224 // |glf || |gray_f |gray_f |gray_f |gray_f | 00225 // |--------------------------------------------| 00226 // |gray|| |gray_n |gray_n |gray_f | 00227 // |--------------------------------------------| 00228 00229 // |--------------------------------------------| 00230 // | / || gl | glf |gray_n | int | float | 00231 // |============================================| 00232 // |gl ||gray_f|gray_f |gray_n |gray_f |gray_f | 00233 // |--------------------------------------------| 00234 // |glf || |gray_f |gray_f |gray_f |gray_f | 00235 // |--------------------------------------------| 00236 // |gray|| |gray_f |gray_f |gray_f | 00237 // |--------------------------------------------| 00238 00239 // Valid Conversions are : 00240 00241 // gray_f -> gray_<n> 00242 // gray_f -> graylevel<n> 00243 // gray_f -> graylevel_f 00244 00245 // gray_<n> -> gray_f 00246 // gray_<n> -> graylevel<n> 00247 // gray_<n> -> graylevel_f 00248 00249 // graylevel_f -> gray_f 00250 // graylevel_f -> graylevel<n> 00251 00252 // graylevel_<n> -> gray_<n> 00253 // graylevel_<n> -> graylevel_f<n> 00254 00255 00256 template <unsigned n> 00257 struct graylevel 00258 : 00259 public Integer< graylevel<n> >, 00260 00261 public internal::value_like_< int_u<n>, // Equivalent. 00262 mln_enc(int_u<n>), // Encoding. 00263 internal::gray_<n>,// Interoperation. 00264 graylevel<n> > // Exact. 00265 { 00266 00268 graylevel(); 00270 graylevel(const graylevel<n>& rhs); 00272 graylevel<n>& operator=(const graylevel<n>& rhs); 00273 00275 graylevel(int val); 00277 graylevel<n>& operator=(int val); 00278 00280 template <unsigned m> 00281 graylevel(const graylevel<m>& rhs); 00283 template <unsigned m> 00284 graylevel<n>& operator=(const graylevel<m>& rhs); 00285 00288 graylevel(const mln::literal::black_t&); 00289 graylevel(const mln::literal::medium_gray_t&); 00290 graylevel(const mln::literal::white_t&); 00292 00293 00296 graylevel<n>& operator=(const mln::literal::black_t&); 00297 graylevel<n>& operator=(const mln::literal::medium_gray_t&); 00298 graylevel<n>& operator=(const mln::literal::white_t&); 00300 00301 00303 unsigned value() const; 00304 00306 float to_float() const; 00307 }; 00308 00309 00310 00311 namespace internal 00312 { 00313 // Fwd decl; 00314 template <typename T> struct convert_; 00315 00316 // convert for graylevel. 00317 template <unsigned n> 00318 struct convert_< graylevel<n> > 00319 { 00320 static graylevel<n> value_at_index(unsigned i); 00321 static unsigned index_of_value(graylevel<n> v); 00322 }; 00323 00324 } // end of namespace mln::value::internal 00325 00326 00328 template <unsigned n> 00329 std::ostream& operator<<(std::ostream& ostr, const graylevel<n>& g); 00330 00331 // graylevel<n> + graylevel<m>. 00332 template <unsigned n, unsigned m> 00333 mln_trait_op_plus(graylevel<n>, graylevel<m>) 00334 operator+(const graylevel<n>& lhs, const graylevel<m>& rhs); 00335 00336 // graylevel<n> + Another type (doesn't compile). 00337 template <unsigned n, typename I> 00338 void 00339 operator+(const graylevel<n>& lhs, const I& i); 00340 00341 // graylevel<n> + Another type (doesn't compile). 00342 template <unsigned n, typename I> 00343 void 00344 operator+(const I& i, const graylevel<n>& rhs); 00345 00346 // graylevel<n> - graylevel<m>. 00347 template <unsigned n, unsigned m> 00348 mln_trait_op_minus(graylevel<n>, graylevel<m>) 00349 operator-(const graylevel<n>& lhs, const graylevel<m>& rhs); 00350 00351 // graylevel<n> - Another type (doesn't compile). 00352 template <unsigned n, typename I> 00353 void 00354 operator-(const graylevel<n>& lhs, const I& i); 00355 00356 // graylevel<n> - Another type (doesn't compile). 00357 template <unsigned n, typename I> 00358 void 00359 operator-(const I& i, const graylevel<n>& rhs); 00360 00361 // graylevel<n> * graylevel<m>. 00362 template <unsigned n, unsigned m> 00363 mln_trait_op_times(graylevel<n>, graylevel<m>) 00364 operator*(const graylevel<n>& lhs, const graylevel<m>& rhs); 00365 00366 // With Builtins. 00367 00368 // graylevel<n> * T. 00369 template <unsigned n, typename T> 00370 mln_trait_op_times(graylevel<n>, T) 00371 operator*(const graylevel<n>& lhs, const T& rhs); 00372 00373 // T * graylevel<n>. 00374 template <unsigned n, typename T> 00375 mln_trait_op_times(graylevel<n>, T) 00376 operator*(const T& lhs, const graylevel<n>& rhs); 00377 00378 // graylevel<n> / T. 00379 template <unsigned n, typename T> 00380 internal::gray_f 00381 //mln_trait_op_div(graylevel<n>, T). 00382 operator/(const graylevel<n>& lhs, const T& rhs); 00383 00384 // With Integer. 00385 00386 // graylevel<n> * Integer<I>. 00387 template <unsigned n, typename I> 00388 mln_trait_op_times(graylevel<n>, I) 00389 operator*(const graylevel<n>& lhs, const Integer<I>& rhs); 00390 00391 // Integer<I> * graylevel<n>. 00392 template <typename I, unsigned n> 00393 mln_trait_op_times(I, graylevel<n>) 00394 operator*(const Integer<I>& lhs, const graylevel<n>& rhs); 00395 00396 // graylevel<n> / Integer<I>. 00397 template <unsigned n, typename I> 00398 mln_trait_op_div(graylevel<n>, I) 00399 operator/(const graylevel<n>& lhs, const Integer<I>& rhs); 00400 00401 // Integer<I> / graylevel<n>. 00402 template <typename I, unsigned n> 00403 mln_trait_op_div(I, graylevel<n>) 00404 operator/(const Integer<I>& lhs, const graylevel<n>& rhs); 00405 00406 // With Floating. 00407 00408 // graylevel<n> * Floating<F>. 00409 template <unsigned n, typename F> 00410 mln_trait_op_times(graylevel<n>, F) 00411 operator*(const graylevel<n>& lhs, const Floating<F>& rhs); 00412 00413 // Floating<F>, graylevel<n>. 00414 template <typename F, unsigned n> 00415 mln_trait_op_times(F, graylevel<n>) 00416 operator*(const Floating<F>& lhs, const graylevel<n>& rhs); 00417 00418 00419 // graylevel<n> / Floating<F>. 00420 template <unsigned n, typename F> 00421 mln_trait_op_div(graylevel<n>, F) 00422 operator/(const graylevel<n>& lhs, const Floating<F>& rhs); 00423 00424 // Floating<F> / graylevel<n>. 00425 template <typename F, unsigned n> 00426 mln_trait_op_div(F, graylevel<n>) 00427 operator/(const Floating<F>& lhs, const graylevel<n>& rhs); 00428 00429 # ifndef MLN_INCLUDE_ONLY 00430 00431 // Graylevel<n>. 00432 00433 00434 template <unsigned n> 00435 inline 00436 graylevel<n>::graylevel() 00437 { 00438 } 00439 00440 00441 template <unsigned n> 00442 inline 00443 graylevel<n>::graylevel(int val) 00444 { 00445 mln_precondition(val >= 0); 00446 mln_precondition(unsigned(val) <= mln_max(mln_enc(int_u<n>))); 00447 this->v_ = val; 00448 } 00449 00450 template <unsigned n> 00451 inline 00452 graylevel<n>& 00453 graylevel<n>::operator=(int val) 00454 { 00455 mln_precondition(val >= 0); 00456 mln_precondition(unsigned(val) <= mln_max(mln_enc(int_u<n>))); 00457 this->v_ = val; 00458 return *this; 00459 } 00460 00461 template <unsigned n> 00462 inline 00463 graylevel<n>::graylevel(const graylevel<n>& rhs) : 00464 Integer< graylevel<n> >() 00465 { 00466 this->v_ = rhs.v_; 00467 } 00468 00469 template <unsigned n> 00470 inline 00471 graylevel<n>& 00472 graylevel<n>::operator=(const graylevel<n>& rhs) 00473 { 00474 this->v_ = rhs.v_; 00475 return *this; 00476 } 00477 00478 template <unsigned n> 00479 template <unsigned m> 00480 inline 00481 graylevel<n>::graylevel(const graylevel<m>& rhs) 00482 { 00483 this->v_ = internal::convert<m, n>(rhs.value()); 00484 } 00485 00486 template <unsigned n> 00487 template <unsigned m> 00488 inline 00489 graylevel<n>& 00490 graylevel<n>::operator=(const graylevel<m>& rhs) 00491 { 00492 this->v_ = internal::convert<m, n>(rhs.value()); 00493 return *this; 00494 } 00495 00496 00497 template <unsigned n> 00498 inline 00499 graylevel<n>::graylevel(const mln::literal::black_t&) 00500 { 00501 this->v_ = 0; 00502 } 00503 00504 template <unsigned n> 00505 inline 00506 graylevel<n>& 00507 graylevel<n>::operator=(const mln::literal::black_t&) 00508 { 00509 this->v_ = 0; 00510 return *this; 00511 } 00512 00513 template <unsigned n> 00514 inline 00515 graylevel<n>::graylevel(const mln::literal::medium_gray_t&) 00516 { 00517 this->v_ = metal::math::pow_int<2, n - 1>::value; 00518 } 00519 00520 template <unsigned n> 00521 inline 00522 graylevel<n>& 00523 graylevel<n>::operator=(const mln::literal::medium_gray_t&) 00524 { 00525 this->v_ = metal::math::pow_int<2, n - 1>::value; 00526 return *this; 00527 } 00528 00529 00530 template <unsigned n> 00531 inline 00532 graylevel<n>::graylevel(const mln::literal::white_t&) 00533 { 00534 this->v_ = mln_max(mln_enc(int_u<n>)); 00535 } 00536 00537 template <unsigned n> 00538 inline 00539 graylevel<n>& 00540 graylevel<n>::operator=(const mln::literal::white_t&) 00541 { 00542 this->v_ = mln_max(mln_enc(int_u<n>)); 00543 return *this; 00544 } 00545 00546 template <unsigned n> 00547 inline 00548 unsigned 00549 graylevel<n>::value() const 00550 { 00551 return this->v_; 00552 } 00553 00554 template <unsigned n> 00555 inline 00556 float 00557 graylevel<n>::to_float() const 00558 { 00559 static const float denom = float(metal::math::pow_int<2, n>::value) - 1.f; 00560 return float(this->v_) / denom; 00561 } 00562 00563 00564 00565 namespace internal 00566 { 00567 00568 template <unsigned n> 00569 inline 00570 graylevel<n> 00571 convert_< graylevel<n> >::value_at_index(unsigned i) 00572 { 00573 mln_assertion(i <= mln_max(mln_equiv(graylevel<n>))); 00574 return graylevel<n>(i); 00575 } 00576 00577 template <unsigned n> 00578 inline 00579 unsigned 00580 convert_< graylevel<n> >::index_of_value(graylevel<n> v) 00581 { 00582 return v.value(); 00583 } 00584 00585 } // end of namespace mln::value::internal 00586 00587 // Operators. 00588 00589 template <unsigned n> 00590 inline 00591 std::ostream& operator<<(std::ostream& ostr, const graylevel<n>& g) 00592 { 00593 return ostr << g.value() << "/gl" << n; // FIXME: Be more explicit! 00594 } 00595 00596 // The remaining operators are in mln/value/internal/gray_.hh. 00597 00598 # endif // ! MLN_INCLUDE_ONLY 00599 00600 } // end of namespace mln::value 00601 00602 } // end of namespace mln 00603 00604 00605 #include <mln/value/internal/gray_f.hh> 00606 #include <mln/value/internal/gray_.hh> 00607 00608 #endif // ! MLN_VALUE_GRAYLEVEL_HH