00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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
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;
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;
00116 };
00117
00118 }
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,
00136 int,
00137 gray_<n>,
00138 gray_<n> >
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
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 }
00210
00211 }
00212
00213 }
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
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
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 }
00453
00454
00455
00456
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }
00674
00675
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
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 }
00697
00698
00699
00700 namespace trait
00701 {
00702
00703
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);
00727 }
00728
00729 }
00730
00731
00732 # endif // ! MLN_INCLUDE_ONLY
00733
00734 }
00735
00736 #endif // ! MLN_VALUE_INTERNAL_GRAY__HH