2006-10-16 Thierry GERAUD <theo(a)tegucigalpa.lrde.epita.fr>
Add grey-level types.
* tests/grey.cc: New.
* tests/Makefile.am: Update.
* oln/value/default.hh: New.
* oln/value/greylevel.hh: New.
* oln/Makefile.am: Update.
* oln/core/abstract/value.hh (value): Remove inheritance
so that a value type is not a regular oln type.
Index: tests/grey.cc
===================================================================
--- tests/grey.cc (revision 0)
+++ tests/grey.cc (revision 0)
@@ -0,0 +1,42 @@
+// Copyright (C) 2006 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.
+
+/// Test oln::grey.
+#include <oln/value/greylevel.hh>
+#include <oln/value/default.hh>
+
+
+int main()
+{
+ using namespace oln::value;
+
+ gl8 a = white;
+ gl16 b = white;
+ assert((a == b) == true);
+ gl8 c = (a + b) / 2;
+ assert(c == white);
+}
Index: tests/Makefile.am
===================================================================
--- tests/Makefile.am (revision 643)
+++ tests/Makefile.am (working copy)
@@ -35,6 +35,7 @@
\
at \
\
+ grey \
io_pnm \
\
identity_morpher \
@@ -60,6 +61,9 @@
# I/O.
io_pnm_SOURCES = io_pnm.cc
+# Value.
+grey_SOURCES = grey.cc
+
# Morphers.
identity_morpher_SOURCES = identity_morpher.cc
add_neighborhood_morpher_SOURCES = add_neighborhood_morpher.cc
Index: oln/core/abstract/value.hh
===================================================================
--- oln/core/abstract/value.hh (revision 643)
+++ oln/core/abstract/value.hh (working copy)
@@ -35,7 +35,9 @@
namespace abstract {
- struct value : public oln::type
+ // A value is not an oln::type. As a consequence,
+ // traits are basically defined.
+ struct value
{
protected:
value();
Index: oln/Makefile.am
===================================================================
--- oln/Makefile.am (revision 643)
+++ oln/Makefile.am (working copy)
@@ -152,6 +152,9 @@
morpher/tags.hh \
morpher/thru_fun.hh \
\
+ value/default.hh \
+ value/greylevel.hh \
+ \
basics1d.hh \
basics2d.hh \
basics3d.hh
Index: oln/value/default.hh
===================================================================
--- oln/value/default.hh (revision 0)
+++ oln/value/default.hh (revision 0)
@@ -0,0 +1,59 @@
+// Copyright (C) 2006 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 OLN_VALUE_DEFAULT_HH
+# define OLN_VALUE_DEFAULT_HH
+
+# include <oln/value/greylevel.hh>
+
+
+namespace oln
+{
+
+ namespace value
+ {
+
+ /// White.
+ extern const greylevel white;
+
+ /// Black.
+ extern const greylevel black;
+
+
+# ifndef OLN_INCLUDE_ONLY
+
+ const greylevel white = greylevel(1, 1);
+ const greylevel black = greylevel(1, 0);
+
+# endif
+
+ } // end of namespace oln::value
+
+} // end of namespace oln
+
+
+#endif // ! OLN_VALUE_DEFAULT_HH
Index: oln/value/greylevel.hh
===================================================================
--- oln/value/greylevel.hh (revision 0)
+++ oln/value/greylevel.hh (revision 0)
@@ -0,0 +1,494 @@
+// Copyright (C) 2006 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 OLN_CORE_VALUE_GREYLEVEL_HH
+# define OLN_CORE_VALUE_GREYLEVEL_HH
+
+# include <iostream>
+# include <mlc/contract.hh>
+# include <xtd/optraits.hh>
+# include <oln/core/abstract/value.hh>
+
+
+namespace oln
+{
+
+ namespace value
+ {
+
+
+ namespace internal
+ {
+
+ template <unsigned nbits>
+ struct encoding;
+
+ template <> struct encoding <1> { typedef bool ret; };
+ template <> struct encoding <8> { typedef unsigned char ret; };
+ template <> struct encoding <16> { typedef unsigned short ret; };
+ template <> struct encoding <32> { typedef unsigned long ret; };
+
+ } // end of oln::value::internal
+
+
+ /// Fwd decl.
+ class greylevel;
+
+
+ /// General grey-level class on n bits.
+ template <unsigned nbits>
+ class greylevel_ : public oln::abstract::value
+ {
+ typedef typename internal::encoding<nbits>::ret encoding_t;
+
+ public:
+
+ /// Ctor.
+ greylevel_();
+
+ /// Ctor.
+ explicit greylevel_(typename internal::encoding<nbits>::ret val);
+
+ /// Access to std type.
+ typename internal::encoding<nbits>::ret value() const;
+
+ /// Op greylevel.
+ operator greylevel() const;
+
+ /// Op<.
+ bool operator<(const greylevel_<nbits>& rhs) const;
+
+ /// Op==.
+ bool operator==(const greylevel_<nbits>& rhs) const;
+
+ protected:
+ encoding_t val_;
+ };
+
+
+ /// Op<<.
+ template <unsigned nbits>
+ std::ostream& operator<<(std::ostream& ostr, const
greylevel_<nbits>& g);
+
+
+ /// Aliases.
+ typedef greylevel_<1> gl1;
+ typedef greylevel_<8> gl8;
+ typedef greylevel_<16> gl16;
+ typedef greylevel_<32> gl32;
+
+
+ template <unsigned nbits, unsigned mbits>
+ bool operator==(const greylevel_<nbits>& lhs, const
greylevel_<mbits>& rhs);
+
+ template <unsigned nbits, unsigned mbits>
+ greylevel operator+(const greylevel_<nbits>& lhs, const
greylevel_<mbits>& rhs);
+
+ template <unsigned nbits, unsigned mbits>
+ greylevel operator-(const greylevel_<nbits>& lhs, const
greylevel_<mbits>& rhs);
+
+ template <unsigned nbits>
+ greylevel operator*(int s, const greylevel_<nbits>& rhs);
+
+ template <unsigned nbits>
+ greylevel operator*(const greylevel_<nbits>& lhs, int s);
+
+ template <unsigned nbits>
+ greylevel operator/(const greylevel_<nbits>& lhs, int s);
+
+
+
+ /// General grey-level class where n bits is not know at compile-time.
+ /// This class is used for exchange between grey-level types purpose.
+ class greylevel : public oln::abstract::value
+ {
+ public:
+
+ /// Ctor.
+ greylevel();
+
+ /// Ctor.
+ template <unsigned n>
+ greylevel(const greylevel_<n>& val);
+
+ /// Ctor.
+ greylevel(unsigned nbits, unsigned long val);
+
+ /// Access to std type.
+ unsigned long value() const;
+
+ unsigned nbits() const;
+
+ void set_nbits(unsigned nbits);
+
+ greylevel to_nbits(unsigned nbits) const;
+
+ template <unsigned n>
+ operator greylevel_<n>() const;
+
+ bool operator<(const greylevel& rhs) const;
+
+ bool operator==(const greylevel& rhs) const;
+
+ protected:
+ unsigned nbits_;
+ unsigned long val_;
+ };
+
+
+ std::ostream& operator<<(std::ostream& ostr, const greylevel& g);
+
+
+ greylevel operator+(const greylevel& lhs, const greylevel& rhs);
+ greylevel operator-(const greylevel& lhs, const greylevel& rhs);
+
+ greylevel operator*(int s, const greylevel& rhs);
+ greylevel operator*(const greylevel& lhs, int s);
+
+ greylevel operator/(const greylevel& lhs, int s);
+
+
+
+# ifndef OLN_INCLUDE_ONLY
+
+ // Greylevel_<nbits>.
+
+ template <unsigned nbits>
+ greylevel_<nbits>::greylevel_()
+ {
+ }
+
+ template <unsigned nbits>
+ greylevel_<nbits>::greylevel_(typename internal::encoding<nbits>::ret
val)
+ : val_(val)
+ {
+ }
+
+ template <unsigned nbits>
+ typename internal::encoding<nbits>::ret
+ greylevel_<nbits>::value() const
+ {
+ return val_;
+ }
+
+ template <unsigned nbits>
+ greylevel_<nbits>::operator greylevel() const
+ {
+ greylevel tmp(nbits, val_);
+ return tmp;
+ }
+
+ template <unsigned nbits>
+ bool greylevel_<nbits>::operator<(const greylevel_<nbits>& rhs)
const
+ {
+ return val_ < rhs.val_;
+ }
+
+ template <unsigned nbits>
+ bool greylevel_<nbits>::operator==(const greylevel_<nbits>& rhs)
const
+ {
+ return val_ == rhs.val_;
+ }
+
+ template <unsigned nbits>
+ std::ostream& operator<<(std::ostream& ostr, const
greylevel_<nbits>& g)
+ {
+ return ostr << g.value();
+ }
+
+
+ template <unsigned nbits, unsigned mbits>
+ bool operator==(const greylevel_<nbits>& lhs, const
greylevel_<mbits>& rhs)
+ {
+ return greylevel(lhs) == greylevel(rhs);
+ }
+
+ template <unsigned nbits, unsigned mbits>
+ greylevel operator+(const greylevel_<nbits>& lhs, const
greylevel_<mbits>& rhs)
+ {
+ return greylevel(lhs) + greylevel(rhs);
+ }
+
+ template <unsigned nbits, unsigned mbits>
+ greylevel operator-(const greylevel_<nbits>& lhs, const
greylevel_<mbits>& rhs)
+ {
+ return greylevel(lhs) - greylevel(rhs);
+ }
+
+ template <unsigned nbits>
+ greylevel operator*(int s, const greylevel_<nbits>& rhs)
+ {
+ precondition(s >= 0);
+ greylevel tmp(nbits, s * rhs.value());
+ return tmp;
+ }
+
+ template <unsigned nbits>
+ greylevel operator*(const greylevel_<nbits>& lhs, int s)
+ {
+ precondition(s >= 0);
+ greylevel tmp(nbits, lhs.value() * s);
+ return tmp;
+ }
+
+ template <unsigned nbits>
+ greylevel operator/(const greylevel_<nbits>& lhs, int s)
+ {
+ precondition(s > 0);
+ greylevel tmp(nbits, lhs.value() / s);
+ return tmp;
+ }
+
+
+
+ // Greylevel.
+
+ greylevel::greylevel()
+ : nbits_(0)
+ {
+ }
+
+ template <unsigned n>
+ greylevel::greylevel(const greylevel_<n>& g)
+ : nbits_(n),
+ val_(g.value())
+ {
+ }
+
+ greylevel::greylevel(unsigned nbits, unsigned long val)
+ : nbits_(nbits),
+ val_(val)
+ {
+ }
+
+ unsigned long greylevel::value() const
+ {
+ invariant(nbits_ != 0);
+ return val_;
+ }
+
+ unsigned greylevel::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 oln::value::internal
+
+
+ void greylevel::set_nbits(unsigned nbits)
+ {
+ precondition(nbits != 0);
+ 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;
+ }
+
+
+ greylevel greylevel::to_nbits(unsigned nbits) const
+ {
+ precondition(nbits != 0);
+ invariant(nbits_ != 0);
+ greylevel tmp(*this);
+ tmp.set_nbits(nbits);
+ return tmp;
+ }
+
+
+ template <unsigned n>
+ greylevel::operator greylevel_<n>() const
+ {
+ precondition(nbits_ != 0);
+ greylevel_<n> tmp(internal::convert<n>(nbits_, val_));
+ assert(tmp.value() < internal::two_pow_(n));
+ return tmp;
+ }
+
+ bool greylevel::operator<(const greylevel& rhs) const
+ {
+ precondition(nbits_ != 0 and rhs.nbits() != 0);
+ if (rhs.nbits() == nbits_)
+ return rhs.value() < val_;
+ if (nbits_ > rhs.nbits())
+ return val_ < rhs.to_nbits(nbits_).value();
+ else
+ return this->to_nbits(rhs.nbits()).value() < rhs.value();
+ }
+
+ bool greylevel::operator==(const greylevel& rhs) const
+ {
+ precondition(nbits_ != 0 and rhs.nbits() != 0);
+ if (rhs.nbits() == nbits_)
+ return rhs.value() == val_;
+ if (nbits_ > rhs.nbits())
+ return val_ == rhs.to_nbits(nbits_).value();
+ else
+ return this->to_nbits(rhs.nbits()).value() == rhs.value();
+ }
+
+ std::ostream& operator<<(std::ostream& ostr, const greylevel& g)
+ {
+ return ostr << g.value() << '/' << g.nbits() <<
"nbits";
+ }
+
+ greylevel operator+(const greylevel& lhs, const greylevel& rhs)
+ {
+ precondition(lhs.nbits() != 0 and rhs.nbits() != 0);
+ if (lhs.nbits() > rhs.nbits())
+ {
+ greylevel tmp(lhs.nbits(),
+ lhs.value() + rhs.to_nbits(lhs.nbits()).value());
+ return tmp;
+ }
+ else
+ {
+ greylevel tmp(rhs.nbits(),
+ lhs.to_nbits(rhs.nbits()).value() + rhs.value());
+ return tmp;
+ }
+ }
+
+ greylevel operator-(const greylevel& lhs, const greylevel& rhs)
+ {
+ 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);
+ greylevel tmp(lhs.nbits(),
+ lhs.value() - l);
+ return tmp;
+ }
+ else
+ {
+ unsigned long l = lhs.to_nbits(rhs.nbits()).value();
+ assert(l >= rhs.value());
+ greylevel tmp(rhs.nbits(),
+ l - rhs.value());
+ return tmp;
+ }
+ }
+
+ greylevel operator*(int s, const greylevel& rhs)
+ {
+ precondition(s >= 0);
+ greylevel tmp(rhs.nbits(), rhs.value() * s);
+ return tmp;
+ }
+
+ greylevel operator*(const greylevel& lhs, int s)
+ {
+ precondition(s >= 0);
+ greylevel tmp(lhs.nbits(), lhs.value() * s);
+ return tmp;
+ }
+
+ greylevel operator/(const greylevel& lhs, int s)
+ {
+ precondition(s > 0);
+ greylevel tmp(lhs.nbits(), lhs.value() / s);
+ return tmp;
+ }
+
+# endif
+
+
+ } // end of namespace oln::value
+
+} // end of namespace oln
+
+
+
+namespace xtd
+{
+
+ using oln::value::greylevel;
+
+ template <> struct set_trait_<op_plus, greylevel, greylevel> { typedef
greylevel ret; };
+ template <> struct set_trait_<op_minus, greylevel, greylevel> { typedef
greylevel ret; };
+ template <> struct set_trait_<op_mult, int, greylevel> { typedef
greylevel ret; };
+ template <> struct set_trait_<op_mult, greylevel, int > { typedef
greylevel ret; };
+ template <> struct set_trait_<op_div, greylevel, int > { typedef
greylevel ret; };
+
+ using oln::value::greylevel_;
+
+ template <unsigned nbits, unsigned mbits>
+ struct set_trait_< op_plus, greylevel_<nbits>, greylevel_<mbits> > {
typedef greylevel ret; };
+
+ template <unsigned nbits, unsigned mbits>
+ struct set_trait_< op_minus, greylevel_<nbits>, greylevel_<mbits> > {
typedef greylevel ret; };
+
+ template <unsigned nbits>
+ struct set_trait_< op_mult, int, greylevel_<nbits> > { typedef greylevel
ret; };
+
+ template <unsigned nbits>
+ struct set_trait_< op_mult, greylevel_<nbits>, int > { typedef greylevel
ret; };
+
+ template <unsigned nbits>
+ struct set_trait_< op_div, greylevel_<nbits>, int > { typedef greylevel
ret; };
+
+} // end of namespace xtd
+
+
+#endif // ! OLN_CORE_VALUE_GREYLEVEL_HH