URL:
https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2007-10-01 Matthieu Garrigues <garrigues(a)lrde.epita.fr>
Add gray values.
* mln/value/gray.hh: General gray-level class where n bits is not know
at compile-time. This class is used for exchange between gray-level
types purpose.
* mln/value/graylevel.hh: Graylevel class on n bits.
* tests/value_gray.cc: Some tests.
---
diffstat not available
Index: trunk/milena/tests/value_gray.cc
===================================================================
--- trunk/milena/tests/value_gray.cc (revision 0)
+++ trunk/milena/tests/value_gray.cc (revision 1203)
@@ -0,0 +1,44 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#include <mln/value/graylevel.hh>
+
+int main()
+{
+ using namespace mln::value;
+
+ gl8 a = white;
+ gl16 b = white;
+ assert((a == b) == true);
+ gl8 c = (a + b) / 2;
+ assert(c == white);
+ c = a;
+ assert(c == white);
+
+ c = (a * 2) / 2;
+ assert(c == white);
+}
Index: trunk/milena/mln/value/graylevel.hh
===================================================================
--- trunk/milena/mln/value/graylevel.hh (revision 0)
+++ trunk/milena/mln/value/graylevel.hh (revision 1203)
@@ -0,0 +1,208 @@
+// Copyright (C) 2006, 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_CORE_VALUE_GRAYLEVEL_HH
+# define MLN_CORE_VALUE_GRAYLEVEL_HH
+
+# include <iostream>
+# include <mln/core/contract.hh>
+# include <mln/metal/math.hh>
+# include <mln/metal/bexpr.hh>
+# include <mln/value/internal/value_like.hh>
+# include <mln/value/internal/encoding.hh>
+# include <mln/value/gray.hh>
+# include <mln/value/props.hh>
+
+namespace mln
+{
+
+ namespace value
+ {
+
+ /// Fwd decl.
+ class gray;
+
+
+ /// General gray-level class on n bits.
+ template <unsigned n>
+ class graylevel
+ : public internal::value_like_< typename
internal::encoding_unsigned_<n>::ret,
+ graylevel<n> >
+ {
+ protected:
+ typedef internal::value_like_< typename
internal::encoding_unsigned_<n>::ret,
+ graylevel<n> > super;
+
+ public:
+
+ /// Encoding associated type.
+ typedef typename super::enc enc;
+
+ /// Ctor.
+ graylevel();
+
+ /// Ctor.
+ explicit graylevel(const int val);
+
+ /// Access to std type.
+ enc value() const;
+
+ /// Op encoding_t.
+ operator enc() const;
+
+ /// Op graylevel.
+ operator graylevel() const;
+
+ /// Op<.
+ bool operator<(const graylevel<n>& rhs) const;
+
+ graylevel<n>& operator=(const int val);
+ /// Op==.
+ // bool operator==(const graylevel<n>& rhs) const;
+
+ protected:
+ enc val_;
+ };
+
+
+ template <unsigned n>
+ struct props< graylevel<n> >
+ {
+ static const std::size_t card_ = metal::pow<2, n>::value;
+ static const graylevel<n> min() { return 0; }
+ static const graylevel<n> max() { return card_ - 1; }
+ static const unsigned nbits = n;
+ typedef data_kind kind;
+ typedef float sum;
+ typedef int interop;
+ };
+
+
+ /// Op<<.
+ template <unsigned n>
+ std::ostream& operator<<(std::ostream& ostr, const
graylevel<n>& g);
+
+
+ /// Aliases.
+ typedef graylevel<8> gl8;
+ typedef graylevel<16> gl16;
+ typedef graylevel<32> gl32;
+
+
+ template <unsigned n, unsigned m>
+ bool operator==(const graylevel<n>& lhs, const graylevel<m>&
rhs);
+
+ template <unsigned n, unsigned m>
+ gray operator+(const graylevel<n>& lhs, const graylevel<m>&
rhs);
+
+ template <unsigned n, unsigned m>
+ gray operator-(const graylevel<n>& lhs, const graylevel<m>&
rhs);
+
+ template <unsigned n>
+ gray operator*(int s, const graylevel<n>& rhs);
+
+ template <unsigned n>
+ gray operator*(const graylevel<n>& lhs, int s);
+
+ template <unsigned n>
+ gray operator/(const graylevel<n>& lhs, int s);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ // Graylevel<n>.
+
+ template <unsigned n>
+ graylevel<n>::graylevel()
+ {
+ }
+
+ template <unsigned n>
+ graylevel<n>::graylevel(const int val)
+ : val_(val)
+ {
+ mln_precondition(val >= 0);
+ mln_precondition(unsigned(val) <= mln_max(enc));
+ }
+
+ template <unsigned n>
+ typename graylevel<n>::enc
+ graylevel<n>::value() const
+ {
+ return val_;
+ }
+
+ template <unsigned n>
+ graylevel<n>&
+ graylevel<n>::operator=(const int val)
+ {
+ mln_precondition(val >= 0);
+ mln_precondition(unsigned(val) <= mln_max(enc));
+ this->val_ = val;
+ return *this;
+ }
+
+ template <unsigned n>
+ graylevel<n>::operator graylevel() const
+ {
+ gray tmp(n, val_);
+ return tmp;
+ }
+
+ template <unsigned n>
+ graylevel<n>::operator typename graylevel<n>::enc() const
+ {
+ return val_;
+ }
+
+ template <unsigned n>
+ bool graylevel<n>::operator<(const graylevel<n>& rhs) const
+ {
+ return val_ < rhs.val_;
+ }
+
+ template <unsigned n>
+ std::ostream& operator<<(std::ostream& ostr, const
graylevel<n>& g)
+ {
+ return ostr << g.value();
+ }
+
+ template <unsigned n, unsigned m>
+ bool operator==(const graylevel<n>& lhs, const graylevel<m>&
rhs)
+ {
+ return gray(lhs) == gray(rhs);
+ }
+
+# endif
+
+
+ } // end of namespace mln::value
+
+} // end of namespace mln
+
+#endif // ! MLN_CORE_VALUE_GRAYLEVEL_HH
Index: trunk/milena/mln/value/gray.hh
===================================================================
--- trunk/milena/mln/value/gray.hh (revision 0)
+++ trunk/milena/mln/value/gray.hh (revision 1203)
@@ -0,0 +1,350 @@
+// Copyright (C) 2006, 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_VALUE_GRAY_HH
+# define MLN_VALUE_GRAY_HH
+
+# include <iostream>
+# include <mln/value/graylevel.hh>
+
+
+
+namespace mln
+{
+
+ // Fwd decls.
+ namespace value
+ {
+ template <unsigned N> class graylevel;
+ class gray;
+
+ /// General gray-level class where n bits is not know at compile-time.
+ /// This class is used for exchange between gray-level types purpose.
+
+ class gray // FIXME do we need a super class?
+ //: public mln::internal::graylevel_value_< gray >
+ {
+ public:
+
+ /// Ctor.
+ gray();
+
+ /// Ctor.
+ template <unsigned N>
+ gray(const graylevel<N>& val);
+
+ /// Ctor.
+ gray(unsigned nbits, unsigned long val);
+
+ /// Access to std type.
+ unsigned long value() const;
+
+ unsigned nbits() const;
+
+ void set_nbits(unsigned nbits);
+
+ gray to_nbits(unsigned nbits) const;
+
+ template <unsigned N>
+ operator graylevel<N>() const;
+
+ protected:
+ unsigned nbits_;
+ unsigned long val_;
+ };
+
+ /// White.
+ extern const gray white;
+
+ /// Black.
+ extern const gray black;
+
+ std::ostream& operator<<(std::ostream& ostr, const gray& g);
+
+ bool operator==(const gray& lhs, const gray& rhs);
+ bool operator<(const gray& lhs, const gray& rhs);
+
+ gray operator+(const gray& lhs, const gray& rhs);
+ gray operator-(const gray& lhs, const gray& rhs);
+
+ gray operator*(int s, const gray& rhs);
+ gray operator*(const gray& lhs, int s);
+
+ gray operator/(const gray& lhs, int s);
+
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ const gray white = gray(1, 1);
+ const gray black = gray(1, 0);
+
+ template <unsigned N, unsigned M>
+ gray operator+(const graylevel<N>& lhs, const graylevel<M>& rhs)
+ {
+ return gray(lhs) + gray(rhs);
+ }
+
+ template <unsigned N, unsigned M>
+ gray operator-(const graylevel<N>& lhs, const graylevel<M>& rhs)
+ {
+ return gray(lhs) - gray(rhs);
+ }
+
+ template <unsigned N>
+ gray operator*(int s, const graylevel<N>& rhs)
+ {
+ mln_precondition(s >= 0);
+ gray tmp(N, s * rhs.value());
+ return tmp;
+ }
+
+ template <unsigned N>
+ gray operator*(const graylevel<N>& lhs, int s)
+ {
+ mln_precondition(s >= 0);
+ gray tmp(N, lhs.value() * s);
+ return tmp;
+ }
+
+ template <unsigned N>
+ gray operator/(const graylevel<N>& lhs, int s)
+ {
+ mln_precondition(s > 0);
+ gray tmp(N, lhs.value() / s);
+ return tmp;
+ }
+
+
+
+ // Gray.
+
+ gray::gray()
+ : nbits_(0)
+ {
+ }
+
+ template <unsigned n>
+ gray::gray(const graylevel<n>& g)
+ : nbits_(n),
+ val_(g.value())
+ {
+ }
+
+ gray::gray(unsigned nbits, unsigned long val)
+ : nbits_(nbits),
+ val_(val)
+ {
+ }
+
+ unsigned long gray::value() const
+ {
+ mln_invariant(nbits_ != 0);
+ return val_;
+ }
+
+ unsigned gray::nbits() const
+ {
+ return nbits_;
+ }
+
+ namespace internal
+ {
+
+ unsigned long two_pow_(unsigned n)
+ {
+ if (n == 0)
+ return 1;
+ else
+ return 2 * two_pow_(n - 1);
+ }
+
+ unsigned long two_pow_n_minus_1(unsigned n)
+ {
+ return two_pow_(n) - 1;
+ }
+
+ template <unsigned n_dest>
+ unsigned long convert(unsigned n_src, unsigned long val)
+ {
+ if (n_dest == n_src)
+ return val;
+ else
+ if (n_dest > n_src)
+ return val * two_pow_n_minus_1(n_dest) / two_pow_n_minus_1(n_src);
+ else
+ return val / two_pow_(n_src - n_dest);
+ }
+
+ } // end of mln::value::internal
+
+
+ void gray::set_nbits(unsigned nbits)
+ {
+ mln_precondition(nbits != 0);
+ mln_invariant(nbits_ != 0);
+ if (nbits == nbits_)
+ return;
+ if (nbits > nbits_)
+ {
+ val_ *= internal::two_pow_n_minus_1(nbits);
+ val_ /= internal::two_pow_n_minus_1(nbits_);
+ }
+ else // nbits < nbits_
+ {
+ val_ /= internal::two_pow_(nbits_ - nbits);
+ }
+ nbits_ = nbits;
+ }
+
+
+ gray gray::to_nbits(unsigned nbits) const
+ {
+ mln_precondition(nbits != 0);
+ mln_invariant(nbits_ != 0);
+ gray tmp(*this);
+ tmp.set_nbits(nbits);
+ return tmp;
+ }
+
+
+ template <unsigned n>
+ gray::operator graylevel<n>() const
+ {
+ mln_precondition(nbits_ != 0);
+ graylevel<n> tmp(internal::convert<n>(nbits_, val_));
+
+ mln_assertion(tmp.value() < internal::two_pow_(n));
+ return tmp;
+ }
+
+ // operators
+
+ std::ostream& operator<<(std::ostream& ostr, const gray& g)
+ {
+ return ostr << g.value() << '/' << g.nbits() <<
"nbits";
+ }
+
+ bool operator==(const gray& lhs, const gray& rhs)
+ {
+ mln_precondition(lhs.nbits() != 0 and rhs.nbits() != 0);
+ if (rhs.nbits() == lhs.nbits())
+ return lhs.value() == rhs.value();
+ if (lhs.nbits() > rhs.nbits())
+ return lhs.value() == rhs.to_nbits(lhs.nbits()).value();
+ else
+ return lhs.to_nbits(rhs.nbits()).value() == rhs.value();
+ }
+
+ bool operator<(const gray& lhs, const gray& rhs)
+ {
+ mln_precondition(lhs.nbits() != 0 and rhs.nbits() != 0);
+ if (rhs.nbits() == lhs.nbits())
+ return lhs.value() < rhs.value();
+ if (lhs.nbits() > rhs.nbits())
+ return lhs.value() < rhs.to_nbits(lhs.nbits()).value();
+ else
+ return lhs.to_nbits(rhs.nbits()).value() < rhs.value();
+ }
+
+ gray operator+(const gray& lhs, const gray& rhs)
+ {
+ mln_precondition(lhs.nbits() != 0 and rhs.nbits() != 0);
+ if (lhs.nbits() > rhs.nbits())
+ {
+ gray tmp(lhs.nbits(),
+ lhs.value() + rhs.to_nbits(lhs.nbits()).value());
+ return tmp;
+ }
+ else
+ {
+ gray tmp(rhs.nbits(),
+ lhs.to_nbits(rhs.nbits()).value() + rhs.value());
+ return tmp;
+ }
+ }
+
+ gray operator-(const gray& lhs, const gray& rhs)
+ {
+ mln_precondition(lhs.nbits() != 0 and rhs.nbits() != 0);
+ if (lhs.nbits() > rhs.nbits())
+ {
+ unsigned long l = rhs.to_nbits(lhs.nbits()).value();
+ assert(lhs.value() >= l);
+ gray tmp(lhs.nbits(),
+ lhs.value() - l);
+ return tmp;
+ }
+ else
+ {
+ unsigned long l = lhs.to_nbits(rhs.nbits()).value();
+ assert(l >= rhs.value());
+ gray tmp(rhs.nbits(),
+ l - rhs.value());
+ return tmp;
+ }
+ }
+
+ gray operator*(int s, const gray& rhs)
+ {
+ mln_precondition(s >= 0);
+ gray tmp(rhs.nbits(), rhs.value() * s);
+ return tmp;
+ }
+
+ gray operator*(const gray& lhs, int s)
+ {
+ mln_precondition(s >= 0);
+ gray tmp(lhs.nbits(), lhs.value() * s);
+ return tmp;
+ }
+
+ gray operator/(const gray& lhs, int s)
+ {
+ mln_precondition(s > 0);
+ gray tmp(lhs.nbits(), lhs.value() / s);
+ return tmp;
+ }
+
+// template <unsigned N>
+// graylevel<N>&
+// graylevel<N>::operator=(const gray& g)
+// {
+// mln_precondition(g.nbits() == N);
+// assert(g.value() < internal::two_pow_(N));
+// this->val = g.value(); // FIXME: Add static_cast.
+// }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::value
+
+} // end of namespace mln
+
+
+#endif // ! MLN_VALUE_GRAY_HH