cleanup-2008 2780: Make convolution return the straightforward type.

https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Make convolution return the straightforward type. * mln/core/concept/object.hh: Add metal include. * mln/metal/is_not_a.hh: New. * mln/metal/all.hh: Update. * mln/metal/is_a.hh (U): Rename as... (M): ...this; more appropriate. * mln/linear/ch_convolve.hh: New. * mln/linear/convolve.hh: Fix return type. * mln/linear/lap.hh: Update. * mln/accu/convolve.hh: Add check. * tests/linear/convolve.cc: Update. * tests/linear/lap.cc: Update. mln/accu/convolve.hh | 3 - mln/core/concept/object.hh | 1 mln/linear/ch_convolve.hh | 92 +++++++++++++++++++++++++++++++++++++++++++++ mln/linear/convolve.hh | 33 +++++++--------- mln/linear/lap.hh | 77 +++++++++++++++++++++++-------------- mln/metal/all.hh | 13 +++--- mln/metal/is_a.hh | 26 ++++++------ mln/metal/is_not_a.hh | 28 +++++-------- tests/linear/convolve.cc | 12 ++--- tests/linear/lap.cc | 11 +++-- 10 files changed, 204 insertions(+), 92 deletions(-) Index: tests/linear/convolve.cc --- tests/linear/convolve.cc (revision 2779) +++ tests/linear/convolve.cc (working copy) @@ -1,4 +1,5 @@ -// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory (LRDE) +// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory +// (LRDE) // // This file is part of the Olena Library. This library is free // software; you can redistribute it and/or modify it under the terms @@ -61,11 +62,8 @@ .04, .04, .04, .04, .04, .04, .04, .04, .04, .04 }; w_window2d_float w = make::w_window2d(ws); + image2d<float> tmp = linear::convolve(lena, w); -// image2d<float> tmp = linear::convolve(lena, w); -// image2d<int_u8> out = level::transform(tmp, math::round<int_u8>()); - - image2d<int_u8> out = linear::convolve(lena, w); - - io::pgm::save(out, "out.pgm"); + io::pgm::save(level::transform(tmp, math::round<int_u8>()), + "out.pgm"); } Index: tests/linear/lap.cc --- tests/linear/lap.cc (revision 2779) +++ tests/linear/lap.cc (working copy) @@ -1,4 +1,5 @@ -// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory (LRDE) +// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory +// (LRDE) // // This file is part of the Olena Library. This library is free // software; you can redistribute it and/or modify it under the terms @@ -33,9 +34,11 @@ #include <mln/core/image/image2d.hh> #include <mln/value/int_u8.hh> #include <mln/io/pgm/load.hh> +#include <mln/io/pgm/save.hh> #include <mln/border/thickness.hh> #include <mln/linear/lap.hh> +#include <mln/level/stretch.hh> #include "tests/data.hh" @@ -47,8 +50,8 @@ border::thickness = 1; - image2d<int_u8> lena; + image2d<int_u8> lena, out; io::pgm::load(lena, MLN_IMG_DIR "/lena.pgm"); - image2d<int> tmp(lena.domain()); - linear::lap_4(lena, tmp); + level::stretch(linear::lap_4(lena), out); + io::pgm::save(out, "out.pgm"); } Index: mln/core/concept/object.hh --- mln/core/concept/object.hh (revision 2779) +++ mln/core/concept/object.hh (working copy) @@ -45,6 +45,7 @@ // metal # include <mln/metal/is_a.hh> +# include <mln/metal/is_not_a.hh> # include <mln/metal/is.hh> # include <mln/metal/is_not.hh> # include <mln/metal/equal.hh> Index: mln/metal/is_not_a.hh --- mln/metal/is_not_a.hh (revision 2778) +++ mln/metal/is_not_a.hh (working copy) @@ -1,4 +1,4 @@ -// Copyright (C) 2007 EPITA Research and Development Laboratory +// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE) // // This file is part of the Olena Library. This library is free // software; you can redistribute it and/or modify it under the terms @@ -25,18 +25,17 @@ // reasons why the executable file might be covered by the GNU General // Public License. -#ifndef MLN_METAL_IS_NOT_HH -# define MLN_METAL_IS_NOT_HH +#ifndef MLN_METAL_IS_NOT_A_HH +# define MLN_METAL_IS_NOT_A_HH -/*! \file mln/metal/is_not.hh - * - * \brief Definition of a type that means "is not". - */ +/// \file mln/metal/is_not_a.hh +/// +/// Definition of a type that means "is not a". -# include <mln/metal/is.hh> +# include <mln/metal/is_a.hh> -# define mlc_is_not(T, U) mln::metal::is_not< T, U > +# define mlc_is_not_a(T, M) mln::metal::is_not_a< T, M > @@ -46,12 +45,9 @@ namespace metal { - /*! \brief "is_not" check. - * - * FIXME: Doc! - */ - template <typename T, typename U> - struct is_not : not_< is<T, U> >::eval + /// "is_not_a" static Boolean expression. + template <typename T, template <class> class M> + struct is_not_a : not_< is_a<T, M> >::eval { }; @@ -60,4 +56,4 @@ } // end of namespace mln -#endif // ! MLN_METAL_IS_NOT_HH +#endif // ! MLN_METAL_IS_NOT_A_HH Property changes on: mln/metal/is_not_a.hh ___________________________________________________________________ Added: svn:mergeinfo Index: mln/metal/all.hh --- mln/metal/all.hh (revision 2779) +++ mln/metal/all.hh (working copy) @@ -1,4 +1,5 @@ -// Copyright (C) 2007 EPITA Research and Development Laboratory +// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory +// (LRDE) // // This file is part of the Olena Library. This library is free // software; you can redistribute it and/or modify it under the terms @@ -28,10 +29,10 @@ #ifndef MLN_METAL_ALL_HH # define MLN_METAL_ALL_HH -/*! \file mln/metal/all.hh - * - * \brief File that includes all meta-programming tools. - */ +/// \file mln/metal/all.hh +/// +/// File that includes all meta-programming tools. + namespace mln { @@ -61,7 +62,9 @@ # include <mln/metal/converts_to.hh> # include <mln/metal/is.hh> +# include <mln/metal/is_not.hh> # include <mln/metal/is_a.hh> +# include <mln/metal/is_not_a.hh> # include <mln/metal/goes_to.hh> # include <mln/metal/const.hh> Index: mln/metal/is_a.hh --- mln/metal/is_a.hh (revision 2779) +++ mln/metal/is_a.hh (working copy) @@ -37,14 +37,14 @@ /// \brief Expand to a "metalic" boolean expression stating whether \a -/// T is a subclass of \a U or not. +/// T is a subclass of \a M or not. /// -/// In the current implementation, \a U must be template class with +/// In the current implementation, \a M must be template class with /// exactly one, non template parameter. /// /// This macro is the recommended user interface of the "is_a" /// facility. -# define mlc_is_a(T, U) mln::metal::is_a<T, U> +# define mlc_is_a(T, M) mln::metal::is_a<T, M> @@ -72,12 +72,12 @@ static T* ptr(); }; - template <typename T, template <class> class U> + template <typename T, template <class> class M> struct helper_is_a_ { template<class V> - static yes_ selector(U<V>*); + static yes_ selector(M<V>*); static no_ selector(...); }; @@ -89,22 +89,22 @@ * * FIXME: Doc! */ - template <typename T, template <class> class U> - struct is_a : bool_<( sizeof( internal::helper_is_a_< T, U >::selector(internal::make_< T >::ptr()) ) + template <typename T, template <class> class M> + struct is_a : bool_<( sizeof( internal::helper_is_a_< T, M >::selector(internal::make_< T >::ptr()) ) == sizeof( internal::yes_ ) )> {}; - template <typename T, template <class> class U> - struct is_a< const T, U > : is_a< T, U >::eval + template <typename T, template <class> class M> + struct is_a< const T, M > : is_a< T, M >::eval {}; - template <typename T, template <class> class U> - struct is_a< T&, U > : is_a< T, U >::eval + template <typename T, template <class> class M> + struct is_a< T&, M > : is_a< T, M >::eval {}; - template <typename T, template <class> class U> - struct is_a< const T&, U > : is_a< T, U >::eval + template <typename T, template <class> class M> + struct is_a< const T&, M > : is_a< T, M >::eval {}; Index: mln/linear/ch_convolve.hh --- mln/linear/ch_convolve.hh (revision 0) +++ mln/linear/ch_convolve.hh (revision 0) @@ -0,0 +1,92 @@ +// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE) +// +// 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_LINEAR_CH_CONVOLVE_HH +# define MLN_LINEAR_CH_CONVOLVE_HH + +/// \file mln/linear/ch_convolve.hh +/// +/// Define convolution return type. + +# include <mln/core/concept/image.hh> +# include <mln/core/concept/window.hh> +# include <mln/core/concept/weighted_window.hh> +# include <mln/trait/ch_value.hh> +# include <mln/value/ops.hh> + + +/// Define the result of the convolution of an image with type \p I +/// with a weighted window of type \p W or weights of type \p W. +# define mln_ch_convolve(I, W) \ + typename mln::linear::ch_convolve<I, W>::ret + + +namespace mln +{ + + namespace linear + { + + namespace internal + { + + template <bool b, /* = true, i.e., W is a Weighted_Window */ + typename I, typename W> + struct ch_convolve_helper + { + typedef mln_sum_x(mln_value(I), mln_weight(W)) V; + typedef mln_ch_value(I, V) ret; + }; + + template <typename I, typename W> + struct ch_convolve_helper<false, I, W> + { + typedef mln_sum_x(mln_value(I), W) V; + typedef mln_ch_value(I, V) ret; + }; + + } // end of namespace mln::linear::internal + + + template <typename I, typename W> + struct ch_convolve + : private mlc_and( mlc_is_a(I, Image), + mlc_is_not_a(W, Window) )::check_t + { + protected: + enum { is_w_win = mlc_is_a(W, Weighted_Window)::value }; + typedef internal::ch_convolve_helper<is_w_win, I, W> helper; + public: + typedef mlc_ret(helper) ret; + }; + + } // end of namespace mln::linear + +} // end of namespace mln + + +#endif // ! MLN_LINEAR_CH_CONVOLVE_HH Index: mln/linear/convolve.hh --- mln/linear/convolve.hh (revision 2779) +++ mln/linear/convolve.hh (working copy) @@ -29,18 +29,15 @@ #ifndef MLN_LINEAR_CONVOLVE_HH # define MLN_LINEAR_CONVOLVE_HH -/*! \file mln/linear/convolve.hh - * - * \brief Convolution. - * - * \todo Introduce an accumulator. - */ +/// \file mln/linear/convolve.hh +/// +/// Convolution. # include <mln/core/concept/image.hh> # include <mln/core/concept/weighted_window.hh> -# include <mln/extension/adjust_duplicate.hh> +# include <mln/linear/ch_convolve.hh> # include <mln/accu/convolve.hh> - +# include <mln/extension/adjust_duplicate.hh> namespace mln @@ -60,7 +57,7 @@ * \pre output.domain = input.domain */ template <typename I, typename W> - mln_concrete(I) + mln_ch_convolve(I, W) convolve(const Image<I>& input, const Weighted_Window<W>& w_win); @@ -95,7 +92,7 @@ { template <typename I, typename W> - mln_concrete(I) + mln_ch_convolve(I, W) convolve(const Image<I>& input_, const Weighted_Window<W>& w_win_) { @@ -107,7 +104,7 @@ extension::adjust_duplicate(input, w_win); - typedef mln_concrete(I) O; + typedef mln_ch_convolve(I, W) O; O output; initialize(output, input); @@ -132,7 +129,7 @@ template <typename I, typename W> - mln_concrete(I) + mln_ch_convolve(I, W) convolve_fastest(const Image<I>& input_, const Weighted_Window<W>& w_win_) { @@ -144,7 +141,7 @@ extension::adjust_duplicate(input, w_win); - typedef mln_concrete(I) O; + typedef mln_ch_convolve(I, W) O; O output; initialize(output, input); mln_pixter(O) p_out(output); @@ -176,7 +173,7 @@ { template <typename I, typename W> - mln_concrete(I) + mln_ch_convolve(I, W) convolve_dispatch(trait::image::speed::any, const Image<I>& input, const Weighted_Window<W>& w_win) @@ -185,7 +182,7 @@ } template <typename I, typename W> - mln_concrete(I) + mln_ch_convolve(I, W) convolve_dispatch(trait::image::speed::fastest, const Image<I>& input, const Weighted_Window<W>& w_win) @@ -194,7 +191,7 @@ } template <typename I, typename W> - mln_concrete(I) + mln_ch_convolve(I, W) convolve_dispatch(const Image<I>& input, const Weighted_Window<W>& w_win) { @@ -208,14 +205,14 @@ // Facade. template <typename I, typename W> - mln_concrete(I) + mln_ch_convolve(I, W) convolve(const Image<I>& input, const Weighted_Window<W>& w_win) { trace::entering("linear::convolve"); internal::convolve_tests(input, w_win); - mln_concrete(I) output; + mln_ch_convolve(I, W) output; output = internal::convolve_dispatch(mln_trait_image_speed(I)(), input, w_win); Index: mln/linear/lap.hh --- mln/linear/lap.hh (revision 2779) +++ mln/linear/lap.hh (working copy) @@ -1,4 +1,5 @@ -// Copyright (C) 2007 EPITA Research and Development Laboratory +// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory +// (LRDE) // // This file is part of the Olena Library. This library is free // software; you can redistribute it and/or modify it under the terms @@ -46,65 +47,85 @@ // FIXME: Doc! - template <typename I, typename O> - void lap_4(const Image<I>& input, Image<O>& output); - - template <typename I, typename O> - void lap_8(const Image<I>& input, Image<O>& output); - - template <typename I, typename O> - void lap_x(const Image<I>& input, Image<O>& output); - - template <typename I, typename O> - void lap_o(const Image<I>& input, Image<O>& output); + template <typename I> + mln_ch_convolve(I, int) + lap_4(const Image<I>& input); + + template <typename I> + mln_ch_convolve(I, int) + lap_8(const Image<I>& input); + + template <typename I> + mln_ch_convolve(I, int) + lap_x(const Image<I>& input); + + template <typename I> + mln_ch_convolve(I, int) + lap_o(const Image<I>& input); # ifndef MLN_INCLUDE_ONLY // Laplacian operators (Cf. Sonka et al., p. 81) - template <typename I, typename O> + template <typename I> inline - void lap_4(const Image<I>& input, Image<O>& output) + mln_ch_convolve(I, int) + lap_4(const Image<I>& input) { - mln_precondition(exact(output).domain() == exact(input).domain()); + trace::entering("linear::lap_4"); + mln_precondition(exact(input).has_data()); int ws[] = { 0, 1, 0, 1, -4, 1, 0, 1, 0 }; - convolve(input, make::w_window2d(ws), output); + mln_ch_convolve(I, int) output = convolve(input, make::w_window2d(ws)); + trace::exiting("linear::lap_4"); + return output; } - template <typename I, typename O> + template <typename I> inline - void lap_8(const Image<I>& input, Image<O>& output) + mln_ch_convolve(I, int) + lap_8(const Image<I>& input) { - mln_precondition(exact(output).domain() == exact(input).domain()); + trace::entering("linear::lap_8"); + mln_precondition(exact(input).has_data()); int ws[] = { 1, 1, 1, 1, -8, 1, 1, 1, 1 }; - convolve(input, make::w_window2d(ws), output); + mln_ch_convolve(I, int) output = convolve(input, make::w_window2d(ws)); + trace::exiting("linear::lap_8"); + return output; } - template <typename I, typename O> + template <typename I> inline - void lap_x(const Image<I>& input, Image<O>& output) + mln_ch_convolve(I, int) + lap_x(const Image<I>& input) { - mln_precondition(exact(output).domain() == exact(input).domain()); + trace::entering("linear::lap_x"); + mln_precondition(exact(input).has_data()); int ws[] = { +2, -1, +2, -1, -4, -1, +2, -1, +2 }; - convolve(input, make::w_window2d(ws), output); + mln_ch_convolve(I, int) output = convolve(input, make::w_window2d(ws)); + trace::exiting("linear::lap_x"); + return output; } - template <typename I, typename O> + template <typename I> inline - void lap_o(const Image<I>& input, Image<O>& output) + mln_ch_convolve(I, int) + lap_o(const Image<I>& input) { - mln_precondition(exact(output).domain() == exact(input).domain()); + trace::entering("linear::lap_o"); + mln_precondition(exact(input).has_data()); int ws[] = { -1, +2, -1, +2, -4, +2, -1, +2, -1 }; - convolve(input, make::w_window2d(ws), output); + mln_ch_convolve(I, int) output = convolve(input, make::w_window2d(ws)); + trace::exiting("linear::lap_o"); + return output; } # endif // ! MLN_INCLUDE_ONLY Index: mln/accu/convolve.hh --- mln/accu/convolve.hh (revision 2779) +++ mln/accu/convolve.hh (working copy) @@ -52,7 +52,8 @@ */ template <typename T1, typename T2, typename R = mln_sum_x(T1, T2)> - struct convolve : public mln::accu::internal::base< R, convolve<T1,T2,R> > + struct convolve : public mln::accu::internal::base< R, convolve<T1,T2,R> >, + private metal::converts_to< mln_sum_x(T1, T2), R >::check_t { typedef std::pair<T1,T2> argument;
participants (1)
-
Thierry Geraud