Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2006, 2007, 2008, 2009, 2011 EPITA Research and 00002 // Development 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_INTERNAL_GRAY__HH 00028 # define MLN_VALUE_INTERNAL_GRAY__HH 00029 00033 00034 # include <iostream> 00035 # include <cmath> 00036 00037 # include <mln/metal/math/max.hh> 00038 # include <mln/metal/math/pow.hh> 00039 00040 # include <mln/value/concept/integer.hh> 00041 # include <mln/value/internal/value_like.hh> 00042 00043 # include <mln/value/graylevel_f.hh> 00044 00045 namespace mln 00046 { 00047 00048 namespace literal 00049 { 00051 struct black_t; 00052 struct white_t; 00054 } 00055 00056 namespace value 00057 { 00059 template <unsigned n> 00060 struct graylevel; 00061 template <unsigned N> struct graylevel; 00062 struct graylevel_f; 00063 namespace internal 00064 { 00065 template <unsigned n> class gray_; 00066 struct gray_f; 00067 } 00069 } 00070 00071 00072 namespace trait 00073 { 00074 00075 template < template <class, class> class Name, unsigned n, unsigned m> 00076 struct set_precise_binary_< Name, mln::value::internal::gray_<n>, mln::value::internal::gray_<m> > 00077 { 00078 typedef mln::value::internal::gray_< mlc_max_int(n, m) > ret; 00079 }; 00080 00081 template <unsigned n, unsigned m> 00082 struct set_precise_binary_< op::greater, mln::value::internal::gray_<n>, mln::value::internal::gray_<m> > 00083 { 00084 typedef bool ret; 00085 }; 00086 00087 template <unsigned n, unsigned m> 00088 struct set_precise_binary_< op::eq, mln::value::internal::gray_<n>, mln::value::internal::gray_<m> > 00089 { 00090 typedef bool ret; 00091 }; 00092 00093 // 'gray_' as a value. 00094 00095 template <unsigned n> 00096 struct value_< mln::value::internal::gray_<n> > 00097 { 00098 private: 00099 typedef mln::value::internal::gray_<n> self_; 00100 public: 00101 00102 enum { 00103 nbits = 8 * (sizeof(unsigned) + sizeof(long)), 00104 card = 0 00105 }; 00106 00107 typedef trait::value::nature::integer nature; // FIXME: Or scalar?. 00108 typedef trait::value::kind::gray kind; 00109 typedef trait::value::quant::high quant; 00110 00111 static self_ min(); 00112 static self_ max(); 00113 static self_ epsilon(); 00114 00115 typedef self_ sum; // FIXME: OK?. 00116 }; 00117 00118 } // end of namespace mln::trait 00119 00120 00121 00122 namespace value 00123 { 00124 00125 namespace internal 00126 { 00127 00130 template <unsigned n> 00131 class gray_ 00132 : 00133 public Integer< gray_<n> >, 00134 00135 public internal::value_like_< int, // Equivalent. 00136 int, // Encoding. 00137 gray_<n>, // Interoperation. 00138 gray_<n> > // Exact. 00139 00140 { 00141 public: 00142 00144 typedef int enc; 00145 00147 typedef int equiv; 00148 00150 gray_(); 00152 gray_(int val); 00153 00155 explicit gray_(const literal::white_t&); 00156 explicit gray_(const literal::black_t&); 00158 00159 00161 template <unsigned m> 00162 gray_(const graylevel<m>& val); 00163 template <unsigned m> 00164 gray_<n>& operator=(const graylevel<m>& val); 00166 00168 int value() const; 00169 00171 template <unsigned m> 00172 operator gray_<m>() const; 00173 00175 template <unsigned m> 00176 operator graylevel<m>() const; 00177 00179 operator graylevel_f() const; 00180 00181 }; 00182 00183 00184 // Operators. 00185 00186 template <unsigned n> 00187 std::ostream& operator<<(std::ostream& ostr, const gray_<n>& g); 00188 00189 template <unsigned n, unsigned m> 00190 bool operator==(const gray_<n>& lhs, const gray_<m>& rhs); 00191 template <unsigned n, unsigned m> 00192 bool operator<(const gray_<n>& lhs, const gray_<m>& rhs); 00193 00194 template <unsigned n, unsigned m> 00195 mln_trait_op_plus(gray_<n>, gray_<m>) 00196 operator+(const gray_<n>& lhs, const gray_<m>& rhs); 00197 00198 template <unsigned n, unsigned m> 00199 mln_trait_op_minus(gray_<n>, gray_<m>) 00200 operator-(const gray_<n>& lhs, const gray_<m>& rhs); 00201 00202 template <unsigned n> 00203 gray_<n> operator*(int s, const gray_<n>& rhs); 00204 template <unsigned n> 00205 gray_<n> operator*(const gray_<n>& lhs, int s); 00206 template <unsigned n> 00207 gray_<n> operator/(const gray_<n>& lhs, int s); 00208 00209 } // end of namespace mln::value::internal 00210 00211 } // end of namespace mln::value 00212 00213 } // end of namespace mln 00214 00215 00216 # include <mln/value/internal/gray_f.hh> 00217 00218 00219 namespace mln 00220 { 00221 00222 # ifndef MLN_INCLUDE_ONLY 00223 00224 namespace value 00225 { 00226 namespace internal 00227 { 00228 00229 template <unsigned n_src, unsigned n_dest> 00230 inline 00231 long convert(int val) 00232 { 00233 using mln::metal::int_; 00234 typedef mlc_max(int_<n_dest - n_src> , int_<n_src - n_dest>) m; 00235 00236 if (n_dest == n_src) 00237 return val; 00238 else 00239 if (n_dest > n_src) 00240 return val * mlc_pow_int(2, m::value); 00241 else 00242 return val / mlc_pow_int(2, m::value); 00243 } 00244 00245 // Gray_<N>. 00246 00247 template <unsigned n> 00248 inline 00249 gray_<n>::gray_() 00250 { 00251 } 00252 00253 template <unsigned n> 00254 template <unsigned m> 00255 gray_<n>::gray_(const graylevel<m>& g) 00256 { 00257 this->v_ = convert<m, n>(g.value()); 00258 } 00259 00260 template <unsigned n> 00261 template <unsigned m> 00262 inline 00263 gray_<n>& 00264 gray_<n>::operator=(const graylevel<m>& g) 00265 { 00266 this->v_ = convert<m, n>(g.value()); 00267 return *this; 00268 } 00269 00270 template <unsigned n> 00271 inline 00272 gray_<n>::gray_(const literal::white_t&) 00273 { 00274 this->v_ = mlc_pow_int(2, n) - 1; 00275 } 00276 00277 template <unsigned n> 00278 inline 00279 gray_<n>::gray_(const literal::black_t&) 00280 { 00281 this->v_ = 0; 00282 } 00283 00284 template <unsigned n> 00285 inline 00286 gray_<n>::gray_(int val) 00287 { 00288 this->v_ = val; 00289 } 00290 00291 template <unsigned n> 00292 inline 00293 int 00294 gray_<n>::value() const 00295 { 00296 return this->v_; 00297 } 00298 00299 template <unsigned n> 00300 template <unsigned m> 00301 inline 00302 gray_<n>::operator gray_<m>() const 00303 { 00304 return gray_<m>(convert<n, m>(this->v_)); 00305 } 00306 00307 00308 template <unsigned n> 00309 template <unsigned m> 00310 inline 00311 gray_<n>::operator graylevel<m>() const 00312 { 00313 graylevel<m> tmp(convert<n, m>(this->v_)); 00314 mln_assertion(tmp.value() < std::pow(2.f, int(m))); 00315 return tmp; 00316 } 00317 00318 00319 template <unsigned n> 00320 inline 00321 gray_<n>::operator graylevel_f() const 00322 { 00323 static const float denom = float(metal::math::pow_int<2, n>::value) - 1.f; 00324 return graylevel_f(float(this->v_) / denom); 00325 } 00326 00327 // Operators. 00328 00329 template <unsigned n> 00330 inline 00331 std::ostream& operator<<(std::ostream& ostr, const gray_<n>& g) 00332 { 00333 return ostr << g.value() << "g/" << n << "bits"; 00334 } 00335 00336 template <unsigned n, unsigned m> 00337 inline 00338 bool operator==(const gray_<n>& lhs, const gray_<m>& rhs) 00339 { 00340 if (n == m) 00341 return internal::gray_<mlc_max_int(n, m)>(lhs).value() == 00342 internal::gray_<mlc_max_int(n, m)>(rhs).value(); 00343 if (n > m) 00344 { 00345 gray_<n> down = rhs; 00346 gray_<n> up(down.value() + 00347 mlc_pow_int(2, m)); 00348 return (lhs.value() >= down.value() && lhs.value() < up.value()); 00349 } 00350 else 00351 { 00352 gray_<m> down = lhs; 00353 gray_<m> up(down.value() + 00354 mlc_pow_int(2, n)); 00355 return (rhs.value() >= down.value() && rhs.value() < up.value()); 00356 } 00357 } 00358 00359 template <unsigned n, unsigned m> 00360 inline 00361 bool operator<(const gray_<n>& lhs, const gray_<m>& rhs) 00362 { 00363 if (m == n) 00364 return lhs.value() < rhs.value(); 00365 if (n > m) 00366 return lhs.value() < gray_<n>(rhs).value(); 00367 else 00368 return gray_<m>(lhs).value() < rhs.value(); 00369 } 00370 00371 template <unsigned n, unsigned m> 00372 inline 00373 mln_trait_op_plus(gray_<n>, gray_<m>) 00374 operator+(const gray_<n>& lhs, const gray_<m>& rhs) 00375 { 00376 typedef mln_trait_op_plus(gray_<n>, gray_<m>) ret; 00377 if (n > m) 00378 { 00379 ret tmp(ret(lhs).value() + ret(rhs).value()); 00380 return tmp; 00381 } 00382 else 00383 { 00384 ret tmp(ret(lhs).value() + ret(rhs).value()); 00385 return tmp; 00386 } 00387 } 00388 00389 template <unsigned n, unsigned m> 00390 inline 00391 mln_trait_op_minus(gray_<n>, gray_<m>) 00392 operator-(const gray_<n>& lhs, const gray_<m>& rhs) 00393 { 00394 typedef mln_trait_op_minus(gray_<n>, gray_<m>) ret; 00395 00396 00397 if (lhs == rhs) 00398 return ret(0); 00399 if (n == m) 00400 return ret(lhs.value() - rhs.value()); 00401 if (n > m) 00402 { 00403 ret l = rhs; 00404 mln_assertion(lhs.value() >= l.value()); 00405 ret tmp(lhs.value() - l.value()); 00406 return tmp; 00407 } 00408 else 00409 { 00410 ret l = lhs; 00411 mln_assertion(l.value() >= rhs.value()); 00412 ret tmp(l.value() - rhs.value()); 00413 return tmp; 00414 } 00415 } 00416 00417 template <unsigned n, unsigned m> 00418 inline 00419 mln_trait_op_times(gray_<n>, gray_<m>) 00420 operator*(const gray_<n>& lhs, const gray_<m>& rhs) 00421 { 00422 typedef mln_trait_op_times(gray_<n>, gray_<m>) ret; 00423 00424 return ret(ret(lhs).value() * ret(rhs).value()); 00425 } 00426 00427 template <unsigned n> 00428 inline 00429 gray_<n> operator*(int s, const gray_<n>& rhs) 00430 { 00431 gray_<n> tmp(rhs.value() * s); 00432 return tmp; 00433 } 00434 00435 template <unsigned n> 00436 inline 00437 gray_<n> operator*(const gray_<n>& lhs, int s) 00438 { 00439 gray_<n> tmp(lhs.value() * s); 00440 return tmp; 00441 } 00442 00443 template <unsigned n> 00444 inline 00445 gray_<n> operator/(const gray_<n>& lhs, int s) 00446 { 00447 mln_precondition(s != 0); 00448 gray_<n> tmp(lhs.value() / s); 00449 return tmp; 00450 } 00451 00452 } // end of namespace mln::value::internal 00453 00454 // Graylevel operators. 00455 00456 // Op gl == Int. 00457 00458 template <typename I, unsigned n> 00459 inline 00460 bool 00461 operator==(const Integer<I>& lhs, const graylevel<n>& rhs) 00462 { 00463 return rhs.value() == exact(lhs); 00464 } 00465 00466 // Op gl == gl. 00467 00468 template <unsigned n, unsigned m> 00469 inline 00470 bool 00471 operator==(const graylevel<n>& lhs, const graylevel<m>& rhs) 00472 { 00473 return internal::gray_<n>(rhs) == internal::gray_<m>(lhs); 00474 } 00475 00476 // Op gl + gl. 00477 00478 template <unsigned n, unsigned m> 00479 inline 00480 mln_trait_op_plus(graylevel<n>, graylevel<m>) 00481 operator+(const graylevel<n>& lhs, const graylevel<m>& rhs) 00482 { 00483 return internal::gray_<n>(lhs) + internal::gray_<m>(rhs); 00484 } 00485 00486 // Op gl + Another type. 00487 template <unsigned n, typename I> 00488 inline 00489 void 00490 operator+(const graylevel<n>& lhs, const I& i) 00491 { 00492 (void) lhs; 00493 (void) i; 00494 typename graylevel<n>::wrong_use_of_graylevel___Please_use_the__to_enc__method a; 00495 } 00496 00497 00498 // Op Another type + gl. 00499 template <unsigned n, typename I> 00500 inline 00501 void 00502 operator+(const I& i, const graylevel<n>& rhs) 00503 { 00504 (void) i; 00505 (void) rhs; 00506 typename graylevel<n>::wrong_use_of_graylevel___Please_use_the__to_enc__method a; 00507 } 00508 00509 // Op gl - gl. 00510 template <unsigned n, unsigned m> 00511 inline 00512 mln_trait_op_minus(graylevel<n>, graylevel<m>) 00513 operator-(const graylevel<n>& lhs, const graylevel<m>& rhs) 00514 { 00515 return internal::gray_<n>(lhs) - internal::gray_<m>(rhs); 00516 } 00517 00518 // Op gl - Another type. 00519 template <unsigned n, typename I> 00520 inline 00521 void 00522 operator-(const graylevel<n>& lhs, const I& i) 00523 { 00524 (void) lhs; 00525 (void) i; 00526 typename graylevel<n>::wrong_use_of_graylevel___Please_use_the__to_enc__method a; 00527 } 00528 00529 00530 // Op Another type - gl. 00531 template <unsigned n, typename I> 00532 inline 00533 void 00534 operator-(const I& i, const graylevel<n>& rhs) 00535 { 00536 (void) i; 00537 (void) rhs; 00538 typename graylevel<n>::wrong_use_of_graylevel___Please_use_the__to_enc__method a; 00539 } 00540 00541 // Op gl * gl. 00542 template <unsigned n, unsigned m> 00543 inline 00544 mln_trait_op_times(graylevel<n>, graylevel<m>) 00545 operator*(const graylevel<n>& lhs, const graylevel<m>& rhs) 00546 { 00547 return internal::gray_<n>(lhs) * internal::gray_<m>(rhs); 00548 } 00549 00550 // Op symm gl * Integer. 00551 template <unsigned n, typename I> 00552 inline 00553 internal::gray_<n> 00554 operator*(const graylevel<n>& lhs, const Integer<I>& rhs) 00555 { 00556 return internal::gray_<n>(lhs) * int(exact(rhs)); 00557 } 00558 00559 template <typename I, unsigned n> 00560 inline 00561 mln_trait_op_times(I, graylevel<n>) 00562 operator*(const Integer<I>& lhs, const graylevel<n>& rhs) 00563 { 00564 return internal::gray_<n>(rhs) * int(exact(lhs)); 00565 } 00566 00567 // Op symm gl * Floating. 00568 template <unsigned n, typename F> 00569 inline 00570 mln_trait_op_times(graylevel<n>, F) 00571 operator*(const graylevel<n>& lhs, const Floating<F>& rhs) 00572 { 00573 return lhs.to_float() * float(exact(rhs)); 00574 } 00575 00576 template <typename F, unsigned n> 00577 inline 00578 mln_trait_op_times(F, graylevel<n>) 00579 operator*(const Floating<F>& lhs, const graylevel<n>& rhs) 00580 { 00581 return rhs.to_float() * float(exact(lhs)); 00582 } 00583 00584 // Op * Builtin. 00585 template <unsigned n, typename T> 00586 mln_trait_op_times(graylevel<n>, T) 00587 operator*(const graylevel<n>& lhs, const T& rhs) 00588 { 00589 return lhs * scalar_<T>(rhs); 00590 } 00591 00592 template <unsigned n, typename T> 00593 mln_trait_op_times(graylevel<n>, T) 00594 operator*(const T& lhs, const graylevel<n>& rhs) 00595 { 00596 return rhs * scalar_<T>(lhs); 00597 } 00598 00599 00600 // Op / Builtin. 00602 namespace internal 00603 { 00604 struct gray_f; 00605 } 00607 00608 template <unsigned n, typename T> 00609 mln::value::internal::gray_f 00610 operator/(const graylevel<n>& lhs, const T& rhs) 00611 { 00612 return lhs / scalar_<T>(rhs); 00613 } 00614 00615 00616 // Op * scalar. 00617 namespace internal 00618 { 00619 00620 template <typename ret> 00621 struct helper_gray__op_; 00622 00623 template <unsigned n> 00624 struct helper_gray__op_< gray_<n> > 00625 { 00626 template <unsigned m, typename S> 00627 inline static 00628 mln_trait_op_times(graylevel<m>, scalar_<S>) 00629 times(const graylevel<m>& lhs, const scalar_<S>& rhs) 00630 { 00631 typedef mln_trait_op_times(graylevel<m>, scalar_<S>) ret; 00632 ret tmp(typename ret::equiv 00633 (lhs.value() * typename ret::equiv(rhs.to_equiv()))); 00634 return tmp; 00635 } 00636 00637 template <unsigned m, typename S> 00638 inline static 00639 mln_trait_op_times(graylevel<m>, scalar_<S>) 00640 div(const graylevel<m>& lhs, const scalar_<S>& rhs) 00641 { 00642 typedef mln_trait_op_times(graylevel<m>, scalar_<S>) ret; 00643 ret tmp(typename ret::equiv 00644 (lhs.value() / typename ret::equiv(rhs.to_equiv()))); 00645 return tmp; 00646 } 00647 }; 00648 00649 template <> 00650 struct helper_gray__op_< gray_f > 00651 { 00652 template <unsigned n, typename S> 00653 inline static 00654 mln_trait_op_times(graylevel<n>, scalar_<S>) 00655 times(const graylevel<n>& lhs, const scalar_<S>& rhs) 00656 { 00657 typedef mln_trait_op_times(graylevel<n>, scalar_<S>) ret; 00658 ret tmp(lhs.to_float() * typename ret::equiv(rhs.to_equiv())); 00659 return tmp; 00660 } 00661 template <unsigned n, typename S> 00662 inline static 00663 mln_trait_op_div(graylevel<n>, scalar_<S>) 00664 div(const graylevel<n>& lhs, const scalar_<S>& rhs) 00665 { 00666 typedef mln_trait_op_div(graylevel<n>, scalar_<S>) ret; 00667 ret tmp(typename ret::equiv 00668 (lhs.to_float() / typename ret::equiv(rhs.to_equiv()))); 00669 return tmp; 00670 } 00671 }; 00672 00673 } // end of namespace mln::value::internal 00674 00675 // Op graylevel<n> * scalar_<S>. 00676 template <unsigned n, typename S> 00677 inline 00678 mln_trait_op_times(graylevel<n>, scalar_<S>) 00679 operator*(const graylevel<n>& lhs, const scalar_<S>& rhs) 00680 { 00681 typedef mln_trait_op_times(graylevel<n>, scalar_<S>) ret; 00682 return internal::helper_gray__op_<ret>::times(lhs, rhs); 00683 } 00684 00685 // Op graylevel<n> / scalar_<S>. 00686 template <unsigned n, typename S> 00687 inline 00688 mln_trait_op_div(graylevel<n>, scalar_<S>) 00689 operator/(const graylevel<n>& lhs, const scalar_<S>& rhs) 00690 { 00691 mln_precondition(rhs.to_equiv() != S(0)); 00692 typedef mln_trait_op_div(graylevel<n>, scalar_<S>) ret; 00693 return internal::helper_gray__op_<ret>::div(lhs, rhs); 00694 } 00695 00696 } //end of namespace mln::value 00697 00698 00699 00700 namespace trait 00701 { 00702 00703 // 'gray_<n>' as a value. 00704 00705 template <unsigned n> 00706 inline 00707 mln::value::internal::gray_<n> 00708 value_< mln::value::internal::gray_<n> >::min() 00709 { 00710 return mln::value::internal::gray_<n>(1, 0); 00711 } 00712 00713 template <unsigned n> 00714 inline 00715 mln::value::internal::gray_<n> 00716 value_< mln::value::internal::gray_<n> >::max() 00717 { 00718 return mln::value::internal::gray_<n>(1, 1); 00719 } 00720 00721 template <unsigned n> 00722 inline 00723 mln::value::internal::gray_<n> 00724 value_< mln::value::internal::gray_<n> >::epsilon() 00725 { 00726 return mln::value::internal::gray_<n>(1, 0); // Means '0'. 00727 } 00728 00729 } // end of namespace mln::trait 00730 00731 00732 # endif // ! MLN_INCLUDE_ONLY 00733 00734 } // end of namespace mln 00735 00736 #endif // ! MLN_VALUE_INTERNAL_GRAY__HH