
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena ChangeLog: 2007-12-19 Matthieu Garrigues <garrigues@lrde.epita.fr> Rewrite graylevel types. * mln/value/gray.hh: Rename as... * mln/value/internal/gray_.hh: ...this. Gray_<n> is a graylevel encoded on n bits. It can represent value greater than pow(2, n). * mln/value/internal/gray_f.hh: New, gray_f is a graylevel encoded on a float. It can represent value greater than 1. * mln/value/glf.hh: New, alias to graylevel_f. * mln/value/graylevel.hh: graylevel<n> is a graylevel encoded on n bits. its interoperability type is gray_<n>. * mln/value/graylevel_f.hh: New. graylevel_f is a graylevel encoded on a float01_f. * tests/value/graylevel.cc: Unit tests on graylevel. * tests/value/graylevel_f.cc: Unit tests on graylevel_f. * tests/value/graylevel_f_full.cc: Full tests on graylevel_f. * tests/value/graylevel_full.cc: Full tests on graylevel. Misc. * mln/trait/value_.hh: (mln_trait_value_nature_) New, (mln_trait_value_quant_) new, (mln_trait_value_kind_) new. * mln/metal/math/max.hh: (mlc_max) New, (mlc_max_int) new. * tests/arith/revert_full.cc: Add a test on int_u8. * mln/accu/count.hh: Add a fixme to add an take without argument. * mln/core/fi_adaptor.hh: Disable a precondition because it doesn't work on rgb values. --- mln/accu/count.hh | 1 mln/core/fi_adaptor.hh | 2 mln/metal/math/max.hh | 2 mln/trait/value_.hh | 3 mln/value/glf.hh | 55 +++ mln/value/graylevel.hh | 178 ++++++----- mln/value/graylevel_f.hh | 299 ++++++++++++++++++ mln/value/internal/gray_.hh | 633 ++++++++++++++++++++++++++++++++++++++++ mln/value/internal/gray_f.hh | 273 +++++++++++++++++ tests/arith/revert_full.cc | 2 tests/value/graylevel.cc | 87 +++++ tests/value/graylevel_f.cc | 61 +++ tests/value/graylevel_f_full.cc | 102 ++++++ tests/value/graylevel_full.cc | 102 ++---- 14 files changed, 1666 insertions(+), 134 deletions(-) Index: trunk/milena/tests/arith/revert_full.cc =================================================================== --- trunk/milena/tests/arith/revert_full.cc (revision 1619) +++ trunk/milena/tests/arith/revert_full.cc (revision 1620) @@ -266,6 +266,8 @@ chk<value::int_s8>(); std::cerr << "on int_s16:" << std::endl; chk<value::int_s16>(); + std::cerr << "on int_u8:" << std::endl; + chk<value::int_u8>(); std::cerr << "on unsigned:" << std::endl; chk<unsigned>(); } Index: trunk/milena/tests/value/graylevel_f.cc =================================================================== --- trunk/milena/tests/value/graylevel_f.cc (revision 0) +++ trunk/milena/tests/value/graylevel_f.cc (revision 1620) @@ -0,0 +1,61 @@ +// 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. + +/*! \file tests/value/graylevel_f.cc + * + * \brief Tests on mln::value::graylevel_f. + */ + +#include <mln/value/graylevel.hh> +#include <mln/value/glf.hh> +#include <mln/literal/all.hh> + + +int main() +{ + using namespace mln; + using value::glf; + + using literal::black; + using literal::medium_gray; + using literal::white; + + + // Literals. + { + glf a = medium_gray; + glf b = medium_gray; + //a == 0.5f; + mln_assertion(0.5f == a.to_enc()); + //a == b; + mln_assertion(b == a); + + a *= 2; + mln_assertion(a == white); + mln_assertion(a.to_enc() == 1.f); + } +} Index: trunk/milena/tests/value/graylevel_full.cc =================================================================== --- trunk/milena/tests/value/graylevel_full.cc (revision 1619) +++ trunk/milena/tests/value/graylevel_full.cc (revision 1620) @@ -32,7 +32,8 @@ * */ -#include <mln/value/graylevel2.hh> +#include <mln/value/gl8.hh> +#include <mln/value/gl16.hh> #include <mln/value/int_u8.hh> #include <mln/literal/black.hh> @@ -68,11 +69,9 @@ gl16 c = d; mln_assertion(c == d); - gl8 e = gray(white); - std::cout << e << std::endl; - std::cout << gray(white) << std::endl; + gl8 e = white; - mln_assertion(gray(e) == gray(white)); + mln_assertion(e == white); gl8 f = 12; gl8 g = f; @@ -87,6 +86,9 @@ gl8 a(white); gl16 b(white); + a = white; + b = white; + mln_assertion(a == b); mln_assertion(a.value() == float(255)); mln_assertion(b.value() == float(65535)); @@ -125,7 +127,7 @@ mln_assertion(b.value() == float(2)); a = b; - mln_assertion(a.value() == float(2 / 257)); + mln_assertion(a.value() == float(2 / 256)); signed char c = 51; a = c; @@ -167,14 +169,18 @@ a = 42; b = 16969; b += a; - std::cout << "b = " << b << std::endl; - std::cout << "res = " << float(42 * 256 + 128 + 16969) << std::endl; - mln_assertion(b.value() == float((42 * 256 + 128 + 16969) )); + mln_assertion(b.value() == float((42 * 256 + 16969) )); + + a = 42; + b = 16969; + b = b + a; + + mln_assertion(b.value() == float((42 * 256 + 16969) )); a = 42; b = 16969; b = a + b; - mln_assertion(b.value() == float((42 * 256 + 128 + 16969) )); + mln_assertion(b.value() == float((42 * 256 + 16969) )); // misc a = 255; @@ -184,10 +190,7 @@ a = 0; b = 65535; - //FIXME for tomorow: this doesn't work. a = a + b; - std::cout << "a = " << a << std::endl; - std::cout << "a + b = " << a + b << std::endl; mln_assertion(a.value() == float(255)); } @@ -211,26 +214,23 @@ b = 5969; a = b; - std::cout << "a.value() = " << int(a.value()) << std::endl; - std::cout << "should be " << (b.value() / 256) << std::endl; { a = 42; - gl8 t; + gl16 t; + t = a - b; t = t + b; - std::cout << t << " == " << a << std::endl; mln_assertion(a == t); } a = 42; a = a - b; - std::cout << int(a.value()) << ":" << floor(42 - b.value() / 256.0) << std::endl; - mln_assertion(a.value() == float((42 - b.value() / 256) )); + mln_assertion(a.value() == (42 * 256 - b.value()) / 256 ); a = 42; b = 9969; a -= b; - mln_assertion(a.value() == float((42 - round(float(b.value()) / 256)) )); + mln_assertion(a.value() == (42 * 256 - b.value()) / 256 ); // gl16 <- gl8 - gl16 @@ -250,6 +250,8 @@ a = a - b; mln_assertion(a.value() == float(255)); + gl8(255) - gl16(65535); + mln_assertion( gl8(255) == gl16(65535) ); a = 255; b = 65535; a = a - b; @@ -257,33 +259,16 @@ // ... { - graylevel<2> a = 2; + graylevel<2> a = 1; graylevel<3> b = 5; graylevel<2> c; graylevel<3> d; - c = a - b; - d = a - b; + c = b - a; + d = b - a; mln_assertion(c == d); } - { - - // ... - gl8 a = 42; - gl16 b = 5969; - gl8 p; - p = b; - gl8 q; - gl8 r; - - q = a - p; - r = a - b; - std::cout << int(q.value()) << " " << int(r.value()) << std::endl; - mln_assertion(q == r); - - } - } // Multiplication @@ -294,35 +279,36 @@ // gl8 <- gl8 * gl8 a = 8; a *= a; - std::cout << a << std::endl; - mln_assertion(a.value() == 42); + mln_assertion(a.value() == 64); - a = 21; + a = 7; a = a * a; - mln_assertion(a.value() == 42); + mln_assertion(a.value() == 49); // gl8 <- gl8 * gl16 a = 10; - b = 5969; + b = 20; a = a * b; - mln_assertion(a.value() == float((10 * b.value() / 256) )); + mln_assertion(a.value() == float((10 * 256* b.value())/256)); a = 10; - b = 16969; + b = 16; a *= b; - mln_assertion(a.value() == float((10 * b.value() / 256) )); + mln_assertion(a.value() == float((10 * 256* b.value())/256)); + + mln_assertion((gl8(12) * gl16(12345)).to_enc() == float((12 * 256* 12345))); // gl16 <- gl8 * gl16 a = 10; - b = 5969; + b = 24; b *= a; - mln_assertion(b.value() == float((10 * 256 * 5969) )); + mln_assertion(b.value() == float((10 * 256 * 24) )); a = 10; - b = 5969; + b = 24; b = a * b; - mln_assertion(b.value() == float((10 * 256 * 5969) )); + mln_assertion(b.value() == float((10 * 256 * 24) )); // misc a = 255; @@ -337,8 +323,8 @@ // ... { - graylevel<2> a = 2; - graylevel<3> b = 5; + graylevel<2> a = 1; + graylevel<3> b = 2; graylevel<2> c; graylevel<3> d; @@ -351,7 +337,7 @@ // ... gl8 a = 7; - gl16 b = 5969; + gl16 b = 596; gl8 p; p = b; @@ -360,11 +346,9 @@ gl8 r; q = a * p; - r = a * b; - std::cout << int(q.value()) << " " << int(r.value()) << std::endl; - mln_assertion(q == r); - + r = a * b / 256; } } + // FIXME : division } Index: trunk/milena/tests/value/graylevel_f_full.cc =================================================================== --- trunk/milena/tests/value/graylevel_f_full.cc (revision 0) +++ trunk/milena/tests/value/graylevel_f_full.cc (revision 1620) @@ -0,0 +1,102 @@ +// 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. + +/*! \file tests/value/graylevel_f_full.cc + * + * \brief Full tests on mln::value::graylevel_f. + */ + +#include <mln/value/graylevel.hh> +#include <mln/value/glf.hh> +#include <mln/value/gl8.hh> +#include <mln/value/gl16.hh> +#include <mln/literal/all.hh> + + +int main() +{ + using namespace mln; + using value::glf; + using value::gl8; + using value::gl16; + using value::graylevel; + + using literal::black; + using literal::medium_gray; + using literal::white; + + // Constructions + { + glf a; + + glf b = 0.42; + mln_assertion(b.value() == 0.42f); + + glf c = 0.42; + mln_assertion(c.value() == 0.42f); + + glf d = c; + mln_assertion(d.value() == 0.42f); + + glf e = 0; + mln_assertion(e.value() == 0.f); + + graylevel<24> f = mlc_pow_int(2, 24) - 1; + glf g = f; + mln_assertion(g.value() == 1.f); + + graylevel<24> h = 0; + glf i = h; + mln_assertion(i.value() == 0.f); + } + + // Literals + { + glf a(white); + mln_assertion(a == white); + mln_assertion(a.value() == 1.f); + glf d = white; + mln_assertion(d == white); + mln_assertion(d.value() == 1.f); + + glf b(black); + mln_assertion(b == black); + mln_assertion(b.value() == 0.f); + glf e = black; + mln_assertion(e == black); + mln_assertion(e.value() == 0.f); + + glf c(medium_gray); + mln_assertion(c == medium_gray); + mln_assertion(c.value() == 0.5f); + glf f = medium_gray; + mln_assertion(f == medium_gray); + mln_assertion(f.value() == 0.5f); + } + + // FIXME : addition, multiplication, division. +} Index: trunk/milena/tests/value/graylevel.cc =================================================================== --- trunk/milena/tests/value/graylevel.cc (revision 0) +++ trunk/milena/tests/value/graylevel.cc (revision 1620) @@ -0,0 +1,87 @@ +// 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. + +/*! \file tests/value/graylevel.cc + * + * \brief Tests on mln::value::graylevel. Tests operations between + * graylevel of different encodings. + * + */ + +#include <mln/value/gl8.hh> +#include <mln/value/gl16.hh> +#include <mln/value/int_u8.hh> + +#include <mln/literal/black.hh> +#include <mln/literal/white.hh> + + + +int main() +{ + using namespace mln::value; + + using mln::literal::white; + using mln::literal::black; + + gl8 a(white); + gl8 b(white); + + a = b; + mln_assertion(a == b); + + { + gl8 a(10); + gl8 b(10); + + gl8 c = a + b; + } + { + gl8 a(white); + gl8 b(white); + gl8 c; + c = (a + b) / 2; + + mln_assertion(c == white); + mln_assertion(c.value() == 255); + + c = a; + mln_assertion(c == white); + + c = (a * 2) / 2; + mln_assertion(c == white); + + c = c / 6; + } + + { + gl8 c = white; + mln_assertion(c == white); + mln_assertion(c.value() == float(255)); + } + +} Index: trunk/milena/mln/trait/value_.hh =================================================================== --- trunk/milena/mln/trait/value_.hh (revision 1619) +++ trunk/milena/mln/trait/value_.hh (revision 1620) @@ -45,8 +45,11 @@ # define mln_trait_value_nature(V) typename mln::trait::value_< V >::nature +# define mln_trait_value_nature_(V) mln::trait::value_< V >::nature # define mln_trait_value_kind(V) typename mln::trait::value_< V >::kind +# define mln_trait_value_kind_(V) mln::trait::value_< V >::kind # define mln_trait_value_quant(V) typename mln::trait::value_< V >::quant +# define mln_trait_value_quant_(V) mln::trait::value_< V >::quant # define mln_nbits(V) mln::trait::value_< V >::nbits Index: trunk/milena/mln/core/fi_adaptor.hh =================================================================== --- trunk/milena/mln/core/fi_adaptor.hh (revision 1619) +++ trunk/milena/mln/core/fi_adaptor.hh (revision 1620) @@ -244,7 +244,7 @@ data_< fi_adaptor<I> >::sync_with_adaptee_() { mln_precondition(fi_ima_.isValid()); - mln_precondition(fi_ima_.getBitsPerPixel() == 8 * sizeof(mln_value(I))); + //FIXME: doesnt work for rgb: mln_precondition(fi_ima_.getBitsPerPixel() == 8 * sizeof(mln_value(I))); deallocate_(); b_ = make::box2d(fi_ima_.getHeight(), Index: trunk/milena/mln/metal/math/max.hh =================================================================== --- trunk/milena/mln/metal/math/max.hh (revision 1619) +++ trunk/milena/mln/metal/math/max.hh (revision 1620) @@ -36,6 +36,8 @@ # include <mln/metal/bool.hh> # include <mln/metal/int.hh> +# define mlc_max(X, Y) typename mln::metal::math::max< X, Y >::ret +# define mlc_max_int(x, y) mln::metal::math::max_int< x, y >::value namespace mln { Index: trunk/milena/mln/accu/count.hh =================================================================== --- trunk/milena/mln/accu/count.hh (revision 1619) +++ trunk/milena/mln/accu/count.hh (revision 1620) @@ -58,6 +58,7 @@ count_(); void init(); + // FIXME : should we add a take() without argument? void take(const argument&); void take(const count_<T>& other); Index: trunk/milena/mln/value/gray.hh (deleted) =================================================================== Index: trunk/milena/mln/value/graylevel.hh =================================================================== --- trunk/milena/mln/value/graylevel.hh (revision 1619) +++ trunk/milena/mln/value/graylevel.hh (revision 1620) @@ -39,11 +39,12 @@ # include <mln/core/contract.hh> # include <mln/metal/math/pow.hh> +# include <mln/metal/math/max.hh> # include <mln/metal/bexpr.hh> # include <mln/literal/ops.hh> # include <mln/value/int_u.hh> -# include <mln/value/gray.hh> +# include <mln/value/internal/gray_.hh> # include <mln/trait/value_.hh> @@ -60,8 +61,9 @@ } namespace value { + /// \{ Fwd decls. - class gray; + class gray_; template <unsigned n> struct graylevel; struct float01_f; /// \} @@ -71,36 +73,38 @@ namespace trait { - // FIXME: Change into - // - for op::plus: mln::value::graylevel<1 + (n > m ? n : m)> - // - for op::times: mln::value::graylevel<n + m> - // - ... template < unsigned n, unsigned m > struct set_precise_binary_< op::plus, mln::value::graylevel<n>, mln::value::graylevel<m> > { - typedef mln::value::gray ret; + typedef mln::value::internal::gray_< mlc_max_int(n, m) > ret; }; template < unsigned n, unsigned m > struct set_precise_binary_< op::minus, mln::value::graylevel<n>, mln::value::graylevel<m> > { - typedef mln::value::gray ret; + typedef mln::value::internal::gray_< mlc_max_int(m, n) > ret; }; template < unsigned n, unsigned m > struct set_precise_binary_< op::times, mln::value::graylevel<n>, mln::value::graylevel<m> > { - typedef mln::value::gray ret; + typedef mln::value::internal::gray_<mlc_max_int(m, n)> ret; }; + template < unsigned n, unsigned m > + struct set_precise_binary_< op::div, mln::value::graylevel<n>, mln::value::graylevel<m> > + { + // FIXME : correct? + typedef mln::value::internal::gray_< mlc_max_int(m, n) > ret; + }; template < unsigned n, typename I > struct set_binary_< op::times, mln::value::Integer, mln::value::graylevel<n>, mln::value::Integer, I > { - typedef mln::value::gray ret; + typedef mln::value::internal::gray_<n> ret; }; template < typename I, unsigned n > @@ -108,7 +112,7 @@ mln::value::Integer, I, mln::value::Integer, mln::value::graylevel<n> > { - typedef mln::value::gray ret; + typedef mln::value::internal::gray_<n> ret; }; @@ -117,7 +121,7 @@ mln::value::Integer, mln::value::graylevel<n>, mln::value::Floating, F > { - typedef float ret; + typedef mln::value::internal::gray_f ret; }; template < typename F, unsigned n > @@ -125,7 +129,7 @@ mln::value::Floating, F, mln::value::Integer, mln::value::graylevel<n> > { - typedef float ret; + typedef mln::value::internal::gray_f ret; }; @@ -134,7 +138,7 @@ { typedef mln_value_equiv(S) E; typedef mlc_equal(E, float) is_float; // FIXME: Or double... - typedef mlc_if(is_float, float, mln::value::gray) ret; + typedef mlc_if(is_float, float, mln::value::internal::gray_<n>) ret; }; template < unsigned n, typename S > @@ -144,7 +148,6 @@ mln::value::scalar_<S>) ret; }; - // 'graylevel<n>' as a value. template <unsigned n> @@ -178,6 +181,62 @@ { /// General gray-level class on n bits. + + // Return types of the operators +-*/. + + // Operators + - return the interoperability type to allow + // operations like (gl8(255) + gl8(255)) / 2. + - with int and + // float are not allowed. + + // If you really need to act with the value + // of the gray_<n> (the encoding). use the to_enc() method. + // + + // |--------------------------------------------| + // | + || gl | glf |gray_i | int | float | + // |============================================| + // |gl ||gray_i|gray_f |gray_i | X | X | + // |--------------------------------------------| + // |glf || |gray_f |gray_f | X | X | + // |--------------------------------------------| + // |gray|| |gray_i | X | X | + // |--------------------------------------------| + + // |--------------------------------------------| + // | - || gl | glf |gray_i | int | float | + // |============================================| + // |gl ||gray_i|gray_f |gray_i | X | X | + // |--------------------------------------------| + // |glf || |gray_f |gray_f | X | X | + // |--------------------------------------------| + // |gray|| |gray_i | X | X | + // |--------------------------------------------| + + // |--------------------------------------------| + // | * || gl | glf |gray_i | int | float | + // |============================================| + // |gl ||gray_i|gray_f |gray_i |gray_i |gray_f | + // |--------------------------------------------| + // |glf || |gray_f |gray_f |gray_f |gray_f | + // |--------------------------------------------| + // |gray|| |gray_i |gray_i |gray_f | + // |--------------------------------------------| + + // |--------------------------------------------| + // | / || gl | glf |gray_i | int | float | + // |============================================| + // |gl ||gray_i|gray_f |gray_i |gray_i |gray_i | + // |--------------------------------------------| + // |glf || |gray_f |gray_f |gray_f |gray_f | + // |--------------------------------------------| + // |gray|| |gray_i |gray_i |gray_f | + // |--------------------------------------------| + + /// Valid convertions : + // glf -> gl (round) + // gl -> gray_i + // gray_i-> gl + template <unsigned n> struct graylevel : @@ -185,38 +244,30 @@ public internal::value_like_< int_u<n>, // Equivalent. mln_enc(int_u<n>), // Encoding. - gray, // Interoperation. + internal::gray_<n>,// Interoperation. graylevel<n> > // Exact. { /// Constructor without argument. graylevel(); - + /// Copy constructor. + graylevel(const graylevel<n>& rhs); + /// Assigment. + graylevel<n>& operator=(const graylevel<n>& rhs); /// Constructor from int. graylevel(int val); - /// Assigment with int. graylevel<n>& operator=(int val); - - /// Constructor from gray. - graylevel(const gray& rhs); - - /// Assigment with gray. - graylevel<n>& operator=(const gray& rhs); - - - /// Copy constructor. - graylevel(const graylevel<n>& rhs); - - /// Assigment. - graylevel<n>& operator=(const graylevel<n>& rhs); + /// Constructor from graylevel_f. + graylevel(const graylevel_f& rhs); + /// Assigment with graylevel_f. + graylevel<n>& operator=(const graylevel_f& rhs); /// Constructor from any graylevel. template <unsigned m> graylevel(const graylevel<m>& rhs); - /// Assigment with any graylevel. template <unsigned m> graylevel<n>& operator=(const graylevel<m>& rhs); @@ -229,11 +280,12 @@ graylevel(const literal::white_t&); /// \} + /// Assigment with literals. /// \{ - graylevel<n>& operator=(const literal::white_t&); - graylevel<n>& operator=(const literal::medium_gray_t&); graylevel<n>& operator=(const literal::black_t&); + graylevel<n>& operator=(const literal::medium_gray_t&); + graylevel<n>& operator=(const literal::white_t&); /// \} @@ -266,49 +318,46 @@ 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; - - - + // graylevel<n> + graylevel<m> template <unsigned n, unsigned m> - gray + mln_trait_op_plus(graylevel<n>, graylevel<m>) operator+(const graylevel<n>& lhs, const graylevel<m>& rhs); + // graylevel<n> - graylevel<m> template <unsigned n, unsigned m> - gray + mln_trait_op_minus(graylevel<n>, graylevel<m>) operator-(const graylevel<n>& lhs, const graylevel<m>& rhs); + // graylevel<n> * graylevel<m> template <unsigned n, unsigned m> - gray + mln_trait_op_times(graylevel<n>, graylevel<m>) operator*(const graylevel<n>& lhs, const graylevel<m>& rhs); // With Integer. + // graylevel<n> * Integer<I> template <unsigned n, typename I> - gray + mln_trait_op_times(graylevel<n>, Integer<I>) operator*(const graylevel<n>& lhs, const Integer<I>& rhs); + // Integer<I> * graylevel<n> template <typename I, unsigned n> - gray + mln_trait_op_times(Integer<I>, graylevel<n>) operator*(const Integer<I>& lhs, const graylevel<n>& rhs); // With Floating. + // graylevel<n> * Floating<F> template <unsigned n, typename F> - float + mln_trait_op_times(graylevel<n>, Floating<F>) operator*(const graylevel<n>& lhs, const Floating<F>& rhs); + // Floating<F>, graylevel<n> template <typename F, unsigned n> - float + mln_trait_op_times(Floating<F>, graylevel<n>) operator*(const Floating<F>& lhs, const graylevel<n>& rhs); - - # ifndef MLN_INCLUDE_ONLY // Graylevel<n>. @@ -341,25 +390,6 @@ return *this; } - - template <unsigned n> - inline - graylevel<n>::graylevel(const gray& g) - { - gray tmp = g.to_nbits(n); - this->v_ = tmp.value(); - } - - template <unsigned n> - inline - graylevel<n>& - graylevel<n>::operator=(const gray& g) - { - gray tmp = g.to_nbits(n); - this->v_ = tmp.value(); - return *this; - } - template <unsigned n> inline graylevel<n>::graylevel(const graylevel<n>& rhs) @@ -381,7 +411,7 @@ inline graylevel<n>::graylevel(const graylevel<m>& rhs) { - *this = gray(rhs).to_nbits(n); + *this = internal::gray_<m>(rhs); } template <unsigned n> @@ -390,7 +420,7 @@ graylevel<n>& graylevel<n>::operator=(const graylevel<m>& rhs) { - *this = gray(rhs).to_nbits(n); + *this = internal::gray_<m>(rhs); return *this; } @@ -427,6 +457,7 @@ return *this; } + template <unsigned n> inline graylevel<n>::graylevel(const literal::white_t&) @@ -443,7 +474,6 @@ return *this; } - template <unsigned n> inline unsigned @@ -494,7 +524,7 @@ return ostr << g.value() << "/gl" << n; // FIXME: Be more explicit! } - // The remaining operators are in mln/value/gray.hh. + // The remaining operators are in mln/value/internal/gray_.hh. # endif // ! MLN_INCLUDE_ONLY Index: trunk/milena/mln/value/graylevel_f.hh =================================================================== --- trunk/milena/mln/value/graylevel_f.hh (revision 0) +++ trunk/milena/mln/value/graylevel_f.hh (revision 1620) @@ -0,0 +1,299 @@ +// 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_GRAYLEVEL_F_HH +# define MLN_VALUE_GRAYLEVEL_F_HH + +/*! \file mln/value/graylevel_f.hh + * + * \brief Definition of the mln::value::graylevel_f class. + */ + +# include <iostream> + +# include <mln/value/ops.hh> + +# include <mln/core/contract.hh> +# include <mln/metal/math/pow.hh> +# include <mln/metal/bexpr.hh> +# include <mln/literal/ops.hh> + +# include <mln/value/float01_f.hh> +# include <mln/value/internal/gray_.hh> +# include <mln/trait/value_.hh> + + +namespace mln +{ + + namespace literal + { + /// \{ Fwd decls. + struct black_t; + struct medium_gray_t; + struct white_t; + /// \} + } + namespace value + { + /// \{ Fwd decls. + namespace internal {class gray_f; } + struct graylevel_f; + template <unsigned n> struct graylevel; + struct float01_f; + /// \} + } + + + + namespace trait + { + + + template < template <class, class> class Name> + struct set_precise_binary_< Name, mln::value::graylevel_f, mln::value::graylevel_f > + { + typedef mln::value::internal::gray_f ret; + }; + + template <> + struct set_precise_binary_< op::greater, mln::value::graylevel_f, mln::value::graylevel_f > + { + typedef bool ret; + }; + + template <> + struct set_precise_binary_< op::eq, mln::value::graylevel_f, mln::value::graylevel_f > + { + typedef bool ret; + }; + + /// Forward declaration. + template <typename T> struct value_; + + // 'graylevel_f' as a value. + template <> + struct value_<mln::value::graylevel_f> + { + private: + typedef mln::value::graylevel_f self_; + typedef mln::value::float01_f equiv_; + + public: + + enum { + nbits = mln_nbits(equiv_), + card = 0 + }; + + typedef trait::value::nature::floating nature; + typedef trait::value::kind::gray kind; + typedef mln_trait_value_quant_(equiv_) quant; + + static const equiv_ min() { return 0; } + static const equiv_ max() { return 1; } + static const equiv_ epsilon() { return mln_epsilon(equiv_); } + + typedef float sum; + }; + + } // end of namespace mln::trait + + + + namespace value + { + + /// General gray-level class on n bits. + struct graylevel_f + : + public Floating< graylevel_f >, + + public internal::value_like_< float01_f, // Equivalent. + mln_enc_(float01_f),// Encoding. + internal::gray_f, // Interoperation. + graylevel_f > // Exact. + { + /// Constructor without argument. + graylevel_f(); + /// Copy constructor. + graylevel_f(const graylevel_f& rhs); + /// Assigment. + graylevel_f& operator=(const graylevel_f& rhs); + + + /// Constructor from float. + graylevel_f(float val); + /// Assigment with float. + graylevel_f& operator=(float val); + + /// Constructor from graylevel. + template <unsigned n> + graylevel_f(const graylevel<n>& rhs); + /// Assigment with graylevel. + template <unsigned n> + graylevel_f& operator=(const graylevel<n>& rhs); + + /// Ctors with literals. + /// \{ + graylevel_f(const literal::black_t&); + graylevel_f(const literal::medium_gray_t&); + graylevel_f(const literal::white_t&); + /// \} + + /// Assigment with literals. + /// \{ + graylevel_f& operator=(const literal::black_t&); + graylevel_f& operator=(const literal::medium_gray_t&); + graylevel_f& operator=(const literal::white_t&); + /// \} + + /// Access to std type. + float value() const; + }; + + + // Operators. + + /// Op<<. + std::ostream& operator<<(std::ostream& ostr, const graylevel_f& g); + +# ifndef MLN_INCLUDE_ONLY + + // graylevel_f. + + inline + graylevel_f::graylevel_f() + { + } + + + inline + graylevel_f::graylevel_f(float val) + { + this->v_ = val; + } + + inline + graylevel_f& + graylevel_f::operator=(float val) + { + this->v_ = val; + return *this; + } + + template <unsigned n> + graylevel_f::graylevel_f(const graylevel<n>& rhs) + { + this->v_ = rhs.to_float(); + } + + template <unsigned n> + graylevel_f& + graylevel_f::operator=(const graylevel<n>& rhs) + { + this->v_ = rhs.to_float(); + } + + inline + graylevel_f::graylevel_f(const graylevel_f& rhs) + { + this->v_ = rhs.v_; + } + + inline + graylevel_f& + graylevel_f::operator=(const graylevel_f& rhs) + { + this->v_ = rhs.v_; + return *this; + } + + inline + graylevel_f::graylevel_f(const literal::black_t&) + { + this->v_ = 0.0f; + } + + inline + graylevel_f& + graylevel_f::operator=(const literal::black_t&) + { + this->v_ = 0.0f; + return *this; + } + + inline + graylevel_f::graylevel_f(const literal::medium_gray_t&) + { + this->v_ = 0.5f; + } + + inline + graylevel_f& + graylevel_f::operator=(const literal::medium_gray_t&) + { + this->v_ = 0.5f; + return *this; + } + + inline + graylevel_f::graylevel_f(const literal::white_t&) + { + this->v_ = 1.0f; + } + + inline + graylevel_f& + graylevel_f::operator=(const literal::white_t&) + { + this->v_ = 1.0f; + return *this; + } + + inline + float + graylevel_f::value() const + { + return this->v_; + } + + // Operators. + + inline + std::ostream& operator<<(std::ostream& ostr, const graylevel_f& g) + { + return ostr << g.value() << "/gl_f"; // FIXME: Be more explicit! + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln::value + + } // end of namespace mln + +#endif // ! MLN_VALUE_GRAYLEVEL_F_HH Index: trunk/milena/mln/value/glf.hh =================================================================== --- trunk/milena/mln/value/glf.hh (revision 0) +++ trunk/milena/mln/value/glf.hh (revision 1620) @@ -0,0 +1,55 @@ +// 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. + +#ifndef MLN_VALUE_GLF_HH +# define MLN_VALUE_GLF_HH + +/*! \file mln/value/glf.hh + * + * \brief Define the alias value::glf. + */ + +# include <mln/value/graylevel_f.hh> + + +namespace mln +{ + + namespace value + { + + + /// Alias for 8 bit graylevel. + typedef graylevel_f glf; + + + } // end of namespace mln::value + +} // end of namespace mln + + +#endif // ! MLN_VALUE_GLF_HH Index: trunk/milena/mln/value/internal/gray_.hh =================================================================== --- trunk/milena/mln/value/internal/gray_.hh (revision 0) +++ trunk/milena/mln/value/internal/gray_.hh (revision 1620) @@ -0,0 +1,633 @@ +// 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_INTERNAL_GRAY__HH +# define MLN_VALUE_INTERNAL_GRAY__HH + +/*! \file mln/value/internal/gray_.hh + * + * \brief FIXME. + * + */ + +# include <iostream> +# include <cmath> + +# include <mln/metal/math/max.hh> +# include <mln/metal/math/pow.hh> + +# include <mln/value/graylevel.hh> +# include <mln/value/graylevel_f.hh> +# include <mln/value/concept/integer.hh> + + +namespace mln +{ + + namespace literal + { + /// \{ Fwd decls. + struct black_t; + struct white_t; + /// \} + } + + namespace value + { + /// \{ Fwd decls. + template <unsigned N> class graylevel; + class graylevel_f; + namespace internal { template <unsigned n> class gray_; } + /// \} + } + + + namespace trait + { + + template < template <class, class> class Name, unsigned n, unsigned m> + struct set_precise_binary_< Name, mln::value::internal::gray_<n>, mln::value::internal::gray_<m> > + { + typedef mln::value::internal::gray_< mlc_max_int(n, m) > ret; + }; + + template <unsigned n, unsigned m> + struct set_precise_binary_< op::greater, mln::value::internal::gray_<n>, mln::value::internal::gray_<m> > + { + typedef bool ret; + }; + + template <unsigned n, unsigned m> + struct set_precise_binary_< op::eq, mln::value::internal::gray_<n>, mln::value::internal::gray_<m> > + { + typedef bool ret; + }; + + // 'gray_' as a value. + + template <unsigned n> + struct value_< mln::value::internal::gray_<n> > + { + private: + typedef mln::value::internal::gray_<n> self_; + public: + + enum { + nbits = 8 * (sizeof(unsigned) + sizeof(long)), + card = 0 + }; + + typedef trait::value::nature::integer nature; // FIXME: Or scalar? + typedef trait::value::kind::gray kind; + typedef trait::value::quant::high quant; + + static const self_ min(); + static const self_ max(); + static const self_ epsilon(); + + typedef self_ sum; // FIXME: OK? + }; + + } // end of namespace mln::trait + + + + namespace value + { + + namespace internal + { + + /// \internal General gray-level class where n bits is not know at compile-time. + /// This class is used for exchange between gray-level types purpose. + template <unsigned n> + class gray_ + : + public Integer< gray_<n> >, + + public internal::value_like_< int, // Equivalent. + int, // Encoding. + gray_<n>, // Interoperation. + gray_<n> > // Exact. + + { + public: + + /// Encoding associated type. + typedef int enc; + + /// Equivalent associated type. + typedef int equiv; + + /// Constructor without argument. + gray_(); + /// Constructor with int. + gray_(int val); + + /// \{ Constructors/assignments with literals. + explicit gray_(const literal::white_t&); + explicit gray_(const literal::black_t&); + /// \} + + + /// \{ Constructors/assigments with graylevel. + template <unsigned m> + gray_(const graylevel<m>& val); + template <unsigned m> + gray_<n>& operator=(const graylevel<m>& val); + /// \} + + /// Access to std type. + int value() const; + + /// Return an equivalent gray_ encoded on \p nbits bits. + template <unsigned m> + operator gray_<m>() const; + + /// Convertion to graylevel. + template <unsigned m> + operator graylevel<m>() const; + + /// Convertion to graylevel_f. +// operator graylevel_f() const; + }; + + + // Operators. + + template <unsigned n> + std::ostream& operator<<(std::ostream& ostr, const gray_<n>& g); + + template <unsigned n, unsigned m> + bool operator==(const gray_<n>& lhs, const gray_<m>& rhs); + template <unsigned n, unsigned m> + bool operator<(const gray_<n>& lhs, const gray_<m>& rhs); + + template <unsigned n, unsigned m> + mln_trait_op_plus(gray_<n>, gray_<m>) + operator+(const gray_<n>& lhs, const gray_<m>& rhs); + + template <unsigned n, unsigned m> + mln_trait_op_minus(gray_<n>, gray_<m>) + operator-(const gray_<n>& lhs, const gray_<m>& rhs); + + template <unsigned n> + gray_<n> operator*(int s, const gray_<n>& rhs); + template <unsigned n> + gray_<n> operator*(const gray_<n>& lhs, int s); + template <unsigned n> + gray_<n> operator/(const gray_<n>& lhs, int s); + + } // end of namespace mln::value::internal + +} // end of namespace mln::value + + + +# ifndef MLN_INCLUDE_ONLY + + namespace value + { + namespace internal + { + + template <unsigned n_src, unsigned n_dest> + inline + long convert(int val) + { + using typename mln::metal::int_; + typedef mlc_max(int_<n_dest - n_src> , int_<n_src - n_dest>) m; + + if (n_dest == n_src) + return val; + else + if (n_dest > n_src) + return val * mlc_pow_int(2, m::value); + else + return val / mlc_pow_int(2, m::value); + } + + // Gray_<N>. + + template <unsigned n> + inline + gray_<n>::gray_() + { + } + + template <unsigned n> + template <unsigned m> + gray_<n>::gray_(const graylevel<m>& g) + { + this->v_ = convert<m, n>(g.value()); + } + + template <unsigned n> + template <unsigned m> + inline + gray_<n>& + gray_<n>::operator=(const graylevel<m>& g) + { + this->v_ = convert<m, n>(g.value()); + return *this; + } + + template <unsigned n> + inline + gray_<n>::gray_(const literal::white_t&) + { + this->v_ = mlc_pow_int(2, n) - 1; + } + + template <unsigned n> + inline + gray_<n>::gray_(const literal::black_t&) + { + this->v_ = 0; + } + + template <unsigned n> + inline + gray_<n>::gray_(int val) + { + this->v_ = val; + } + + template <unsigned n> + inline + int + gray_<n>::value() const + { + return this->v_; + } + + template <unsigned n> + template <unsigned m> + inline + gray_<n>::operator gray_<m>() const + { + return gray_<m>(convert<n, m>(this->v_)); + } + + + template <unsigned n> + template <unsigned m> + inline + gray_<n>::operator graylevel<m>() const + { + graylevel<m> tmp(convert<n, m>(this->v_)); + mln_assertion(tmp.value() < std::pow(2.f, int(m))); + return tmp; + } + + + // Operators. + + template <unsigned n> + inline + std::ostream& operator<<(std::ostream& ostr, const gray_<n>& g) + { + return ostr << g.value() << "g/" << n << "bits"; + } + + template <unsigned n, unsigned m> + inline + bool operator==(const gray_<n>& lhs, const gray_<m>& rhs) + { + if (n == m) + return internal::gray_<mlc_max_int(n, m)>(lhs).value() == + internal::gray_<mlc_max_int(n, m)>(rhs).value(); + if (n > m) + { + gray_<n> down = rhs; + gray_<n> up(down.value() + + mlc_pow_int(2, m)); + return (lhs.value() >= down.value() && lhs.value() < up.value()); + } + else + { + gray_<m> down = lhs; + gray_<m> up(down.value() + + mlc_pow_int(2, n)); + return (rhs.value() >= down.value() && rhs.value() < up.value()); + } + } + + template <unsigned n, unsigned m> + inline + bool operator<(const gray_<n>& lhs, const gray_<m>& rhs) + { + if (m == n) + return lhs.value() < rhs.value(); + if (n > m) + return lhs.value() < gray_<n>(rhs).value(); + else + return gray_<m>(lhs).value() < rhs.value(); + } + + template <unsigned n, unsigned m> + inline + mln_trait_op_plus(gray_<n>, gray_<m>) + operator+(const gray_<n>& lhs, const gray_<m>& rhs) + { + typedef mln_trait_op_plus(gray_<n>, gray_<m>) ret; + if (n > m) + { + ret tmp(ret(lhs).value() + ret(rhs).value()); + return tmp; + } + else + { + ret tmp(ret(lhs).value() + ret(rhs).value()); + return tmp; + } + } + + template <unsigned n, unsigned m> + inline + mln_trait_op_minus(gray_<n>, gray_<m>) + operator-(const gray_<n>& lhs, const gray_<m>& rhs) + { + typedef mln_trait_op_minus(gray_<n>, gray_<m>) ret; + + + if (lhs == rhs) + return ret(0); + if (n == m) + return ret(lhs.value() - rhs.value()); + if (n > m) + { + ret l = rhs; + mln_assertion(lhs.value() >= l.value()); + ret tmp(lhs.value() - l.value()); + return tmp; + } + else + { + ret l = lhs; + mln_assertion(l.value() >= rhs.value()); + ret tmp(l.value() - rhs.value()); + return tmp; + } + } + + template <unsigned n, unsigned m> + inline + mln_trait_op_times(gray_<n>, gray_<m>) + operator*(const gray_<n>& lhs, const gray_<m>& rhs) + { + typedef mln_trait_op_times(gray_<n>, gray_<m>) ret; + + return ret(ret(lhs).value() * ret(rhs).value()); + } + + template <unsigned n> + inline + gray_<n> operator*(int s, const gray_<n>& rhs) + { + gray_<n> tmp(rhs.value() * s); + return tmp; + } + + template <unsigned n> + inline + gray_<n> operator*(const gray_<n>& lhs, int s) + { + gray_<n> tmp(lhs.value() * s); + return tmp; + } + + template <unsigned n> + inline + gray_<n> operator/(const gray_<n>& lhs, int s) + { + mln_precondition(s != 0); + gray_<n> tmp(lhs.value() / s); + return tmp; + } + + } // end of namespace mln::value::internal + + // Graylevel operators. + + // Op gl == Int + + template <typename I, unsigned n> + inline + bool + operator==(const Integer<I>& lhs, const graylevel<n>& rhs) + { + return rhs.value() == exact(lhs); + } + + // Op gl == gl + + template <unsigned n, unsigned m> + inline + bool + operator==(const graylevel<n>& lhs, const graylevel<m>& rhs) + { + return internal::gray_<n>(rhs) == internal::gray_<m>(lhs); + } + + // Op gl + gl + + template <unsigned n, unsigned m> + inline + mln_trait_op_plus(graylevel<n>, graylevel<m>) + operator+(const graylevel<n>& lhs, const graylevel<m>& rhs) + { + return internal::gray_<n>(lhs) + internal::gray_<m>(rhs); + } + + // Op gl - gl + + template <unsigned n, unsigned m> + inline + mln_trait_op_minus(graylevel<n>, graylevel<m>) + operator-(const graylevel<n>& lhs, const graylevel<m>& rhs) + { + return internal::gray_<n>(lhs) - internal::gray_<m>(rhs); + } + + // Op gl * gl + + template <unsigned n, unsigned m> + inline + mln_trait_op_times(graylevel<n>, graylevel<m>) + operator*(const graylevel<n>& lhs, const graylevel<m>& rhs) + { + return internal::gray_<n>(lhs) * internal::gray_<m>(rhs); + } + + // Op symm gl * Int + + template <unsigned n, typename I> + inline + mln_trait_op_times(graylevel<n>, Integer<I>) + operator*(const graylevel<n>& lhs, const Integer<I>& rhs) + { + return internal::gray_<n>(lhs) * int(exact(rhs)); + } + + template <typename I, unsigned n> + inline + mln_trait_op_times(Integer<I>, graylevel<n>) + operator*(const Integer<I>& lhs, const graylevel<n>& rhs) + { + return internal::gray_<n>(rhs) * int(exact(lhs)); + } + + // Op symm gl * Float + + template <unsigned n, typename F> + inline + mln_trait_op_times(graylevel<n>, Floating<F>) + operator*(const graylevel<n>& lhs, const Floating<F>& rhs) + { + return lhs.to_float() * exact(rhs); + } + + template <typename F, unsigned n> + inline + mln_trait_op_times(Floating<F>, graylevel<n>) + operator*(const Floating<F>& lhs, const graylevel<n>& rhs) + { + return rhs.to_float() * exact(lhs); + } + + + + // Op * scalar + + namespace internal + { + + template <typename ret> + struct helper_gray__op_; + + template <unsigned n> + struct helper_gray__op_< gray_<n> > + { + template <unsigned m, typename S> + inline + static gray_<n> times(const graylevel<m>& lhs, const scalar_<S>& rhs) + { + gray_<n> tmp(lhs.value() * rhs.to_equiv()); + return tmp; + } + template <unsigned m, typename S> + inline + static gray_<n> div(const graylevel<m>& lhs, const scalar_<S>& rhs) + { + gray_<n> tmp(lhs.value() / rhs.to_equiv()); + return tmp; + } + }; + + template <> + struct helper_gray__op_< float > + { + template <unsigned n, typename S> + inline + static float times(const graylevel<n>& lhs, const scalar_<S>& rhs) + { + float tmp(lhs.to_float() * float(rhs.to_equiv())); + return tmp; + } + template <unsigned n, typename S> + inline + static float div(const graylevel<n>& lhs, const scalar_<S>& rhs) + { + float tmp(lhs.to_float() / float(rhs.to_equiv())); + return tmp; + } + }; + + } // end of namespace mln::value::internal + + template <unsigned n, typename S> + inline + mln_trait_op_times(graylevel<n>, scalar_<S>) + operator*(const graylevel<n>& lhs, const scalar_<S>& rhs) + { + typedef mln_trait_op_times(graylevel<n>, scalar_<S>) ret; + return internal::helper_gray__op_<ret>::times(lhs, rhs); + } + + template <unsigned n, typename S> + inline + mln_trait_op_div(graylevel<n>, scalar_<S>) + operator/(const graylevel<n>& lhs, const scalar_<S>& rhs) + { + mln_precondition(rhs.to_equiv() != 0); + typedef mln_trait_op_div(graylevel<n>, scalar_<S>) ret; + return internal::helper_gray__op_<ret>::div(lhs, rhs); + } + + } // end of namespace mln::value + + + +namespace trait +{ + + // 'gray_<n>' as a value. + + template <unsigned n> + inline + const mln::value::internal::gray_<n> + value_< mln::value::internal::gray_<n> >::min() + { + return mln::value::internal::gray_<n>(1, 0); + } + + template <unsigned n> + inline + const mln::value::internal::gray_<n> + value_< mln::value::internal::gray_<n> >::max() + { + return mln::value::internal::gray_<n>(1, 1); + } + + template <unsigned n> + inline + const mln::value::internal::gray_<n> + value_< mln::value::internal::gray_<n> >::epsilon() + { + return mln::value::internal::gray_<n>(1, 0); // Means '0'. + } + +} // end of namespace mln::trait + + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + + +#endif // ! MLN_INTERNAL_VALUE_GRAY__HH Index: trunk/milena/mln/value/internal/gray_f.hh =================================================================== --- trunk/milena/mln/value/internal/gray_f.hh (revision 0) +++ trunk/milena/mln/value/internal/gray_f.hh (revision 1620) @@ -0,0 +1,273 @@ +// 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_INTERNAL_GRAY_F_HH +# define MLN_VALUE_INTERNAL_GRAY_F_HH + +/*! \file mln/value/internal/gray_f.hh + * + * \brief Definition of the mln::value::gray_f class. + */ + +# include <iostream> + +# include <mln/value/ops.hh> + +# include <mln/core/contract.hh> +# include <mln/metal/math/pow.hh> +# include <mln/math/two_pow.hh> +# include <mln/metal/bexpr.hh> +# include <mln/literal/ops.hh> + +# include <mln/value/float01_f.hh> +# include <mln/value/gray.hh> +# include <mln/trait/value_.hh> + + +namespace mln +{ + + namespace literal + { + /// \{ Fwd decls. + struct black_t; + struct medium_gray_t; + struct white_t; + /// \} + } + namespace value + { + /// \{ Fwd decls. + class gray; + struct gray_f; + struct float01_f; + /// \} + } + + + + namespace trait + { + + + template < template <class, class> class Name> + struct set_precise_binary_< Name, mln::value::gray_f, mln::value::gray_f > + { + typedef mln::value::gray_f ret; + }; + + struct set_precise_binary_< op::greater, mln::value::gray_f, mln::value::gray_f > + { + typedef bool ret; + }; + + struct set_precise_binary_< op::eq, mln::value::gray_f, mln::value::gray_f > + { + typedef bool ret; + }; + + // Nessecary?? +// template <typename F> +// struct set_binary_< op::eq, +// mln::value::Floating, mln::value::gray_f, +// mln::value::Floating, F > +// { +// typedef bool ret; +// }; + + /// Forward declaration. + template <typename T> struct value_; + + // 'gray_f' as a value. + template <> + struct value_<mln::value::gray_f> + { + private: + typedef mln::value::gray_f self_; + typedef float equiv_; + + public: + + enum { + nbits = mln_nbits(equiv_), + card = 0 + }; + + typedef trait::value::nature::floating nature; + typedef trait::value::kind::gray kind; + typedef mln_trait_value_quant_(equiv_) quant; + + static const equiv_ min() { return 0; } + static const equiv_ max() { return 1; } + static const equiv_ epsilon() { return mln_epsilon(equiv_); } + + typedef float sum; + }; + + } // end of namespace mln::trait + + + + namespace value + { + + namespace internal + { + + /// \internal General gray-level class on n bits. + struct gray_f + : + public Floating< gray_f >, + + public internal::value_like_< float, // Equivalent. + float, // Encoding. + gray_f, // Interoperation. + gray_f > // Exact. + { + /// Constructor without argument. + gray_f(); + + /// \{ Constructors/assigments with gray_f. + gray_f(const gray_f& rhs); + gray_f& operator=(const gray_f& rhs); + /// \} + + /// \{ Constructors/assigments with float. + gray_f(float val); + gray_f& operator=(float val); + /// \} + + /// \{ Constructors/assigments with graylevel_f. + gray_f(const graylevel_f& val); + gray_f& operator=(const graylevel_f& val); + /// \} + + /// Convertion to graylevel<n> + template <unsigned m> + operator graylevel<m>() const; + + /// Convertion to graylevel_f + operator graylevel_f() const; + + /// Access to std type. + float value() const; + }; + + // Operators. + + /// \internal Op<<. + std::ostream& operator<<(std::ostream& ostr, const gray_f& g); + +# ifndef MLN_INCLUDE_ONLY + + // gray_f. + + inline + gray_f::gray_f() + { + } + + inline + gray_f::gray_f(const gray_f& g) + : v_(g.v_) + { + } + + inline + gray_f& + gray_f::operator=(const gray_f& g) + { + this->v_ = g.v_; + return *this; + } + + inline + gray_f::gray_f(float val) + { + this->v_ = val; + } + + inline + gray_f& + gray_f::operator=(float val) + { + this->v_ = val; + return *this; + } + + inline + gray_f& + gray_f::gray_f(const graylevel_f& rhs) + : v_(rhs.v_) + { + } + + inline + gray_f& + gray_f::gray_f& operator=(const graylevel_f& rhs) + { + this->v_ = rhs.v_; + return *this; + } + + template <unsigned m> + inline + gray_f::operator graylevel<m>() const + { + return graylevel<m>(round(this->v_ * (mlc_pow_int(2, m) - 1))); + } + + inline + gray_f::operator graylevel_f() const + { + return graylevel_f(this->v_); + } + + inline + float + gray_f::value() const + { + return this->v_; + } + + // Operators. + + inline + std::ostream& operator<<(std::ostream& ostr, const gray_f& g) + { + return ostr << g.value() << "/gl_f"; // FIXME: Be more explicit! + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::value::internal + + } // end of namespace mln::value + +} // end of namespace mln + +#endif // ! MLN_VALUE_GRAY_F_HH