
https://svn.lrde.epita.fr/svn/oln/trunk/olena Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Add plus and minus with explicit cast. * TODO: Extend. * oln/core/gen/pw_value.hh (image): New method. * oln/core/gen/value_cast.hh: New. * oln/arith/plus.hh (plus): New. * oln/arith/minus.hh (minus): New. * oln/morpho/elementary_gradient.hh, * oln/morpho/elementary_gradient_external.hh, * oln/morpho/elementary_laplace.hh, * oln/morpho/gradient_internal.hh, * oln/morpho/top_hat_black.hh, * oln/morpho/gradient.hh, * oln/morpho/top_hat_white.hh, * oln/morpho/closing.hh, * oln/morpho/opening.hh, * oln/morpho/gradient_external.hh, * oln/morpho/laplace.hh, * oln/morpho/elementary_gradient_internal.hh: Update. * oln/level/compare.hh: Add FIXME. TODO | 2 oln/arith/minus.hh | 32 +++++++++ oln/arith/plus.hh | 37 ++++++++++- oln/core/gen/pw_value.hh | 12 +++ oln/core/gen/value_cast.hh | 96 +++++++++++++++++++++++++++++ oln/level/compare.hh | 3 oln/morpho/elementary_gradient.hh | 2 oln/morpho/elementary_gradient_external.hh | 2 oln/morpho/elementary_gradient_internal.hh | 2 oln/morpho/elementary_laplace.hh | 10 +-- oln/morpho/gradient.hh | 2 oln/morpho/gradient_external.hh | 2 oln/morpho/gradient_internal.hh | 2 oln/morpho/laplace.hh | 7 +- oln/morpho/top_hat_black.hh | 2 oln/morpho/top_hat_white.hh | 3 16 files changed, 195 insertions(+), 21 deletions(-) Index: TODO --- TODO (revision 925) +++ TODO (working copy) @@ -30,6 +30,8 @@ meta-window type; for instance, ball, segment, etc. +provide "- win" for morpho::opening and morpho::closing. + const promotions for op_<L,O,R> types + result is Mutable only if the underlying type is not 'const' Index: oln/core/gen/pw_value.hh --- oln/core/gen/pw_value.hh (revision 925) +++ oln/core/gen/pw_value.hh (working copy) @@ -33,6 +33,7 @@ # include <oln/core/gen/fun_ops.hh> + namespace oln { @@ -43,6 +44,7 @@ } // end of namespace oln::ERROR + template <typename I> class pw_value_ : public Function_p2v< pw_value_<I> >, private mlc::assert_< mlc_is_a(I, Image), @@ -55,6 +57,8 @@ pw_value_(const Image<I>& ima); oln_value(I) operator()(const oln_point(I)& p) const; + const I& image() const; + protected: const I& ima_; }; @@ -64,6 +68,7 @@ pw_value_<I> pw_value(const Image<I>& ima); + # ifndef OLN_INCLUDE_ONLY template <typename I> @@ -83,6 +88,13 @@ } template <typename I> + const I& + pw_value_<I>::image() const + { + return this->ima_; + } + + template <typename I> pw_value_<I> pw_value(const Image<I>& ima) { Index: oln/core/gen/value_cast.hh --- oln/core/gen/value_cast.hh (revision 0) +++ oln/core/gen/value_cast.hh (revision 0) @@ -0,0 +1,96 @@ +// 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 OLN_CORE_GEN_VALUE_CAST_HH +# define OLN_CORE_GEN_VALUE_CAST_HH + +# include <oln/core/gen/fun.hh> + + +// FIXME: Separate defs and decls. + + + +namespace oln +{ + + + // ----------------------------- casted_fp2v_<F, V> + + + // Fwd decl. + template <typename F, typename V> struct casted_fp2v_; + + // Category. + namespace internal + { + template <typename F, typename V> + struct set_category_of_< casted_fp2v_<F, V> > + { + typedef stc::is< Function_p2v > ret; + }; + } + + + // Class. + template <typename F, typename V> + struct casted_fp2v_ : public Function_p2v< casted_fp2v_<F, V> > + { + typedef oln_arg_of_(F) argument; + typedef oln_res_of_(F) f_result; + typedef V result; + + casted_fp2v_(const F& f) : f_(f) {} + + result operator()(argument arg) const + { + return static_cast<V>(this->f_(arg)); + } + + private: + F f_; + }; + + + // value_cast + + template <typename V, typename F> + casted_fp2v_<F, V> value_cast(const Function_p2v<F>& f) + { + // FIXME: Check that the cast "F::result -> V" is OK. + casted_fp2v_<F, V> tmp(exact(f)); + return tmp; + } + + + // FIXME: Add casted_fv2v_<F,V>? + + +} // end of namespace oln + + +#endif // ! OLN_CORE_GEN_VALUE_CAST_HH Index: oln/morpho/elementary_gradient.hh --- oln/morpho/elementary_gradient.hh (revision 925) +++ oln/morpho/elementary_gradient.hh (working copy) @@ -59,7 +59,7 @@ { oln_plain(I) dil = elementary_dilation(input); oln_plain(I) ero = elementary_erosion(input); - return dil - ero; + return arith::minus<oln_value(I)>(dil, ero); } Index: oln/morpho/elementary_gradient_external.hh --- oln/morpho/elementary_gradient_external.hh (revision 925) +++ oln/morpho/elementary_gradient_external.hh (working copy) @@ -57,7 +57,7 @@ elementary_gradient_external_(const Image_with_Nbh<I>& input) { oln_plain(I) dil = elementary_dilation(input); - return dil - input; + return arith::minus<oln_value(I)>(dil, input); } Index: oln/morpho/elementary_laplace.hh --- oln/morpho/elementary_laplace.hh (revision 925) +++ oln/morpho/elementary_laplace.hh (working copy) @@ -41,7 +41,7 @@ // Fwd decl. template <typename I> - oln_plain(I) + oln_minus_trait(I, I) elementary_laplace(const Image_with_Nbh<I>& input); @@ -53,7 +53,7 @@ // Generic version. template <typename I> - oln_plain(I) + oln_minus_trait(I, I) elementary_laplace_(const Image_with_Nbh<I>& input) { oln_plain(I) g_ext = elementary_gradient_external(input); @@ -61,18 +61,16 @@ return g_ext - g_int; } - - // FIXME: Add a fast version. - } // end of namespace oln::morpho::impl // Facade. template <typename I> - oln_plain(I) + oln_minus_trait(I, I) elementary_laplace(const Image_with_Nbh<I>& input) { + // FIXME: Add postcondition. return impl::elementary_laplace_(exact(input)); } Index: oln/morpho/gradient_internal.hh --- oln/morpho/gradient_internal.hh (revision 925) +++ oln/morpho/gradient_internal.hh (working copy) @@ -57,7 +57,7 @@ gradient_internal_(const Image<I>& input, const Window<W>& win) { oln_plain(I) ero = erosion(input, win); - return input - ero; + return arith::minus<oln_value(I)>(input, ero); } Index: oln/morpho/top_hat_black.hh --- oln/morpho/top_hat_black.hh (revision 925) +++ oln/morpho/top_hat_black.hh (working copy) @@ -58,7 +58,7 @@ top_hat_black_(const Image<I>& input, const Window<W>& win) { oln_plain(I) clo = closing(input, win); - return clo - input; + return arith::minus<oln_value(I)>(clo, input); } Index: oln/morpho/gradient.hh --- oln/morpho/gradient.hh (revision 925) +++ oln/morpho/gradient.hh (working copy) @@ -59,7 +59,7 @@ { oln_plain(I) dil = dilation(input, win); oln_plain(I) ero = erosion(input, win); - return dil - ero; + return arith::minus<oln_value(I)>(dil, ero); } Index: oln/morpho/top_hat_white.hh --- oln/morpho/top_hat_white.hh (revision 925) +++ oln/morpho/top_hat_white.hh (working copy) @@ -58,10 +58,9 @@ top_hat_white_(const Image<I>& input, const Window<W>& win) { oln_plain(I) ope = opening(input, win) - return input - ope; + return arith::minus<oln_value(I)>(input, ope); } - // FIXME: Add a fast version. } // end of namespace oln::morpho::impl Index: oln/morpho/closing.hh Index: oln/morpho/opening.hh Index: oln/morpho/gradient_external.hh --- oln/morpho/gradient_external.hh (revision 925) +++ oln/morpho/gradient_external.hh (working copy) @@ -57,7 +57,7 @@ gradient_external_(const Image<I>& input, const Window<W>& win) { oln_plain(I) dil = dilation(input, win); - return dil - input; + return arith::minus<oln_value(I)>(dil, input); } Index: oln/morpho/laplace.hh --- oln/morpho/laplace.hh (revision 925) +++ oln/morpho/laplace.hh (working copy) @@ -41,7 +41,7 @@ // Fwd decl. template <typename I, typename W> - oln_plain(I) + oln_minus_trait(I, I) laplace(const Image<I>& input, const Window<W>& win); @@ -53,7 +53,7 @@ // Generic version. template <typename I, typename W> - oln_plain(I) + oln_minus_trait(I, I) laplace_(const Image<I>& input, const Window<W>& win) { oln_plain(I) g_ext = gradient_external(input, win); @@ -70,9 +70,10 @@ // Facade. template <typename I, typename W> - oln_plain(I) + oln_minus_trait(I, I) laplace(const Image<I>& input, const Window<W>& win) { + // FIXME: Add postcondition. return impl::laplace_(exact(input), exact(win)); } Index: oln/morpho/elementary_gradient_internal.hh --- oln/morpho/elementary_gradient_internal.hh (revision 925) +++ oln/morpho/elementary_gradient_internal.hh (working copy) @@ -57,7 +57,7 @@ elementary_gradient_internal_(const Image_with_Nbh<I>& input) { oln_plain(I) ero = elementary_erosion(input) - return input - ero; + return arith::minus<oln_value(I)>(input, ero); } Index: oln/level/compare.hh --- oln/level/compare.hh (revision 925) +++ oln/level/compare.hh (working copy) @@ -60,6 +60,9 @@ bool operator <= (const Image<I>& lhs, const literal_<oln_value(I)>& val); + // FIXME: is-it a good idea to have "ima = lit"? + // FIXME: should we rather have "ima = f:p->v"? + # ifndef OLN_LNCLUDE_ONLY Index: oln/arith/plus.hh --- oln/arith/plus.hh (revision 925) +++ oln/arith/plus.hh (working copy) @@ -29,8 +29,14 @@ # define OLN_ARITH_PLUS_HH # include <oln/core/concept/image.hh> -// # include <oln/core/internal/f_ch_value.hh> # include <oln/core/gen/traits.hh> +# include <oln/core/gen/pw_value.hh> +# include <oln/core/gen/value_cast.hh> +# include <oln/level/fill.hh> +# include <oln/core/internal/f_ch_value.hh> + + +// FIXME: what about "ima + literal"? namespace oln @@ -46,12 +52,22 @@ typedef oln_plain_value(I, V) ret; }; - // Fwd decl. + + // Fwd decls. template <typename I, typename J> oln_plus_trait(I, J) operator + (const Image<I>& lhs, const Image<J>& rhs); + namespace arith + { + + template <typename V, typename I, typename J> + oln_plain_value(I, V) + plus(const Image<I>& lhs, const Image<J>& rhs); + + } // end of namespace oln::arith + # ifndef OLN_INCLUDE_ONLY @@ -68,6 +84,23 @@ return output; } + namespace arith + { + + template <typename V, typename I, typename J> + oln_plain_value(I, V) + plus(const Image<I>& lhs, const Image<J>& rhs) + { + precondition(lhs.points() = rhs.points()); + oln_plain_value(I, V) output; + prepare(output, with, lhs); + level::fill(output, + value_cast<V>(pw_value(lhs) + pw_value(rhs))); + return output; + } + + } // end of namespace oln::arith + # endif // ! OLN_INCLUDE_ONLY } // end of namespace oln Index: oln/arith/minus.hh --- oln/arith/minus.hh (revision 925) +++ oln/arith/minus.hh (working copy) @@ -30,6 +30,10 @@ # include <oln/core/concept/image.hh> # include <oln/core/gen/traits.hh> +# include <oln/core/gen/pw_value.hh> +# include <oln/core/gen/value_cast.hh> +# include <oln/level/fill.hh> +# include <oln/core/internal/f_ch_value.hh> namespace oln @@ -45,12 +49,21 @@ }; - // Fwd decl. + // Fwd decls. template <typename I, typename J> oln_minus_trait(I, J) operator - (const Image<I>& lhs, const Image<J>& rhs); + namespace arith + { + + template <typename V, typename I, typename J> + oln_plain_value(I, V) + minus(const Image<I>& lhs, const Image<J>& rhs); + + } // end of namespace oln::arith + # ifndef OLN_INCLUDE_ONLY @@ -67,6 +80,23 @@ return output; } + namespace arith + { + + template <typename V, typename I, typename J> + oln_plain_value(I, V) + minus(const Image<I>& lhs, const Image<J>& rhs) + { + precondition(lhs.points() = rhs.points()); + oln_plain_value(I, V) output; + prepare(output, with, lhs); + level::fill(output, + value_cast<V>(pw_value(lhs) - pw_value(rhs))); + return output; + } + + } // end of namespace oln::arith + # endif // ! OLN_INCLUDE_ONLY } // end of namespace oln