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 #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 class 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
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;
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 }
00181
00182
00183
00184 namespace value
00185 {
00186
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256 template <unsigned n>
00257 struct graylevel
00258 :
00259 public Integer< graylevel<n> >,
00260
00261 public internal::value_like_< int_u<n>,
00262 mln_enc(int_u<n>),
00263 internal::gray_<n>,
00264 graylevel<n> >
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
00314 template <typename T> struct convert_;
00315
00316
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 }
00325
00326
00328 template <unsigned n>
00329 std::ostream& operator<<(std::ostream& ostr, const graylevel<n>& g);
00330
00331
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
00337 template <unsigned n, typename I>
00338 void
00339 operator+(const graylevel<n>& lhs, const I& i);
00340
00341
00342 template <unsigned n, typename I>
00343 void
00344 operator+(const I& i, const graylevel<n>& rhs);
00345
00346
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
00352 template <unsigned n, typename I>
00353 void
00354 operator-(const graylevel<n>& lhs, const I& i);
00355
00356
00357 template <unsigned n, typename I>
00358 void
00359 operator-(const I& i, const graylevel<n>& rhs);
00360
00361
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
00367
00368
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
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
00379 template <unsigned n, typename T>
00380 internal::gray_f
00381
00382 operator/(const graylevel<n>& lhs, const T& rhs);
00383
00384
00385
00386
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
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
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
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
00407
00408
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
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
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
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
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 }
00586
00587
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;
00594 }
00595
00596
00597
00598 # endif // ! MLN_INCLUDE_ONLY
00599
00600 }
00601
00602 }
00603
00604
00605 #include <mln/value/internal/gray_f.hh>
00606 #include <mln/value/internal/gray_.hh>
00607
00608 #endif // ! MLN_VALUE_GRAYLEVEL_HH