• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List

graylevel.hh

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       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     // '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

Generated on Tue Oct 4 2011 15:23:55 for Milena (Olena) by  doxygen 1.7.1