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