https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Revamp linear sobel and cleanup level transform.
* mln/linear/ch_convolve.hh (mln_ch_convolve_grad): New.
* mln/linear/sobel_2d.hh: New.
* mln/linear/sobel.hh: Remove; obsolete.
* tests/linear/sobel.cc: Remove; obsolete.
* tests/linear/sobel_2d.cc: New.
* tests/linear/Makefile.am: Update.
* mln/fun/x2v/l1_norm.hh: New.
* mln/fun/vv2v/vec.hh: New.
* mln/fun/vv2v/all.hh: Update.
* mln/level/transform.spe.hh: Cleanup.
* mln/level/transform.hh: Cleanup.
* mln/level/transform_inplace.hh: New.
* tests/level/transform_inplace.cc: New.
* tests/level/Makefile.am: Update.
* mln/make/image2d.hh: Relax check; it was too strong.
* mln/core/concept/image.hh: Likewise.
* tests/make/image2d.cc: Augment.
mln/core/concept/image.hh | 6 -
mln/fun/vv2v/all.hh | 13 +-
mln/fun/vv2v/vec.hh | 80 +++++++++++++
mln/fun/x2v/l1_norm.hh | 81 +++++++++++++
mln/level/transform.hh | 139 +++++++++--------------
mln/level/transform.spe.hh | 94 +++++++---------
mln/level/transform_inplace.hh | 226 ++++++++++++++++++++++++++++++++++++++
mln/linear/ch_convolve.hh | 6 +
mln/linear/sobel_2d.hh | 229 +++++++++++----------------------------
mln/make/image2d.hh | 4
tests/level/Makefile.am | 2
tests/level/transform_inplace.cc | 56 +++++++++
tests/linear/Makefile.am | 4
tests/linear/sobel_2d.cc | 34 +----
tests/make/image2d.cc | 15 +-
15 files changed, 653 insertions(+), 336 deletions(-)
Index: tests/level/transform_inplace.cc
--- tests/level/transform_inplace.cc (revision 0)
+++ tests/level/transform_inplace.cc (revision 0)
@@ -0,0 +1,56 @@
+// 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.
+
+/// \file tests/level/transform_inplace.cc
+///
+/// Tests on mln::level::transform_inplace
+
+#include <mln/core/image/image2d.hh>
+#include <mln/core/routine/clone.hh>
+#include <mln/fun/v2v/inc.hh>
+#include <mln/fun/v2v/dec.hh>
+#include <mln/debug/iota.hh>
+
+#include <mln/level/transform_inplace.hh>
+#include <mln/level/compare.hh>
+
+
+
+int main()
+{
+ using namespace mln;
+ const unsigned size = 50;
+
+ image2d<int> ref(3, 3);
+ debug::iota(ref);
+
+ image2d<int> ima = clone(ref);
+ level::transform_inplace(ima, fun::v2v::inc<int>());
+ level::transform_inplace(ima, fun::v2v::dec<int>());
+
+ mln_assertion(ima == ref);
+}
Index: tests/level/Makefile.am
--- tests/level/Makefile.am (revision 2825)
+++ tests/level/Makefile.am (working copy)
@@ -28,6 +28,7 @@
sort_psites_full \
stretch \
transform \
+ transform_inplace \
update
abs_SOURCES = abs.cc
@@ -52,6 +53,7 @@
sort_psites_SOURCES = sort_psites.cc
stretch_SOURCES = stretch.cc
transform_SOURCES = transform.cc
+transform_inplace_SOURCES = transform_inplace.cc
update_SOURCES = update.cc
# Lengthy tests.
Index: tests/linear/Makefile.am
--- tests/linear/Makefile.am (revision 2825)
+++ tests/linear/Makefile.am (working copy)
@@ -11,7 +11,7 @@
gaussian \
lap \
log \
- sobel
+ sobel_2d
convolve_SOURCES = convolve.cc
gaussian_SOURCES = gaussian.cc
@@ -19,6 +19,6 @@
convolve_directional_SOURCES = convolve_directional.cc
convolve_2x1d_SOURCES = convolve_2x1d.cc
log_SOURCES = log.cc
-sobel_SOURCES = sobel.cc
+sobel_2d_SOURCES = sobel_2d.cc
TESTS = $(check_PROGRAMS)
Index: tests/linear/sobel_2d.cc
--- tests/linear/sobel_2d.cc (revision 2821)
+++ tests/linear/sobel_2d.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
@@ -25,22 +26,20 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-/*! \file tests/linear/sobel.cc
- *
- * \brief Tests on mln::linear::sobel.
- */
+/// \file tests/linear/sobel_2d.cc
+///
+/// Tests on mln::linear::sobel_2d.
+
#include <mln/core/image/image2d.hh>
+#include <mln/core/var.hh>
#include <mln/value/int_u8.hh>
-#include <mln/level/saturate.hh>
#include <mln/level/stretch.hh>
#include <mln/io/pgm/load.hh>
#include <mln/io/pgm/save.hh>
-#include <mln/border/thickness.hh>
-#include <mln/linear/sobel.hh>
-
+#include <mln/linear/sobel_2d.hh>
#include <mln/debug/println.hh>
#include "tests/data.hh"
@@ -56,19 +55,6 @@
image2d<int_u8> input;
io::pgm::load(input, MLN_IMG_DIR "/tiny.pgm");
- // Create unused objects, for test purpose.
- linear::sobel_h(input);
- linear::sobel_v(input);
- linear::sobel(input);
-
- linear::sobel_norm(input);
-
- image2d<float> result = linear::sobel_norm(input);
- image2d<int_u8> output (result.domain());
- level::stretch (result, output);
- debug::println (output);
-
- image2d<int_u8> output_sat (output.domain());
- level::saturate(output, output_sat);
- io::pgm::save(output_sat, "out.pgm");
+ image2d<float> output = linear::sobel_2d_l1_norm(input);
+ io::pgm::save(level::stretch(int_u8(), output), "out.pgm");
}
Property changes on: tests/linear/sobel_2d.cc
___________________________________________________________________
Added: svn:mergeinfo
Index: tests/make/image2d.cc
--- tests/make/image2d.cc (revision 2825)
+++ tests/make/image2d.cc (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2008 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,10 +25,9 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-/*! \file tests/make/image2d.cc
- *
- * \brief Tests on mln::make::image2d.
- */
+/// \file tests/make/image2d.cc
+///
+/// Tests on mln::make::image2d.
#include <mln/make/image2d.hh>
@@ -44,4 +43,10 @@
0, 1, 0, 0, 0 };
image2d<bool> ima = make::image2d(vals);
mln_assertion(ima.domain() == box2d(5,5));
+
+ bool vs[] = { 1, 0,
+ 1, 1 };
+ image2d<bool> tiny = make::image2d(vs);
+ mln_assertion(tiny.domain() == box2d(2,2));
+
}
Index: mln/core/concept/image.hh
--- mln/core/concept/image.hh (revision 2825)
+++ mln/core/concept/image.hh (working copy)
@@ -251,13 +251,13 @@
mlc_converts_to(V, mln_value(I))::check();
typedef mln_site(I) P;
enum { d = P::dim,
- s = mlc_root(d,S)::value / 2 };
- metal::bool_<(mlc_pow_int(2 * s + 1, d) == S)>::check();
+ s = mlc_root(d, S)::value };
+ metal::bool_<(mlc_pow_int(s, d) == S)>::check();
I& to = exact(to_);
mln_precondition(! to.has_data());
- box<P> b(all_to(0), all_to(2 * s));
+ box<P> b(all_to(0), all_to(s - 1));
to.init_(b);
mln_fwd_piter(box<P>) p(b);
unsigned i = 0;
Index: mln/level/transform.spe.hh
--- mln/level/transform.spe.hh (revision 2825)
+++ mln/level/transform.spe.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,11 +29,9 @@
#ifndef MLN_LEVEL_TRANSFORM_SPE_HH
# define MLN_LEVEL_TRANSFORM_SPE_HH
-/*! \file mln/level/transform.spe.hh
- *
- * \brief Specializations for mln::level::transform.
- *
- */
+/// \file mln/level/transform.spe.hh
+///
+/// Specializations for mln::level::transform.
# ifndef MLN_LEVEL_TRANSFORM_HH
# error "Forbidden inclusion of *.spe.hh"
@@ -58,11 +57,17 @@
namespace internal
{
- template <typename I, typename F, typename O>
+
+ template <typename I, typename F>
inline
void transform_tests(const Image<I>& input,
- const Function_v2v<F>& f,
- Image<O>& output);
+ const Function_v2v<F>& f);
+
+ template <typename I1, typename I2, typename F>
+ inline
+ void transform_tests(const Image<I1>& input1, const Image<I2>&
input2,
+ const Function_v2v<F>& f);
+
}
@@ -88,17 +93,16 @@
{
trace::entering("level::impl::transform_lowq");
+ mlc_is(mln_trait_image_pw_io(mln_ch_value(I, mln_result(F))),
+ trait::image::pw_io::read_write)::check();
+
const I& input = exact(input_);
const F& f = exact(f_);
+ level::internal::transform_tests(input, f);
- mln_precondition(exact(input).has_data());
mln_ch_value(I, mln_result(F)) output;
initialize(output, input);
- level::internal::transform_tests(input, f, output);
- mlc_is(mln_trait_image_pw_io(mln_ch_value(I, mln_result(F))),
- trait::image::pw_io::read_write)::check();
-
value::lut_vec<mln_vset(I), mln_result(F)>
lut(input.values_eligible(), f);
@@ -118,17 +122,16 @@
{
trace::entering("level::impl::transform_taken");
+ mlc_is(mln_trait_image_pw_io(mln_ch_value(I, mln_result(F))),
+ trait::image::pw_io::read_write)::check();
+
const I& input = exact(input_);
const F& f = exact(f_);
+ level::internal::transform_tests(input, f);
- mln_precondition(exact(input).has_data());
mln_ch_value(I, mln_result(F)) output;
initialize(output, input);
- level::internal::transform_tests(input, f, output);
- mlc_is(mln_trait_image_pw_io(mln_ch_value(I, mln_result(F))),
- trait::image::pw_io::read_write)::check();
-
value::lut_vec<mln_vset(I), mln_result(F)>
lut(input.taken_values(), f);
@@ -151,13 +154,11 @@
const I& input = exact(input_);
const F& f = exact(f_);
+ level::internal::transform_tests(input, f);
- mln_precondition(exact(input).has_data());
mln_ch_value(I, mln_result(F)) output;
initialize(output, input);
- level::internal::transform_tests(input_, f_, output);
-
mln_result(F) val = f(input.val());
fill_with_value(output, val);
@@ -173,18 +174,15 @@
{
trace::entering("level::impl::transform_fast");
- typedef mln_ch_value(I, mln_result(F)) O;
const I& input = exact(input_);
const F& f = exact(f_);
+ level::internal::transform_tests(input, f);
- mln_precondition(exact(input).has_data());
- mln_ch_value(I, mln_result(F)) output;
+ typedef mln_ch_value(I, mln_result(F)) O;
+ O output;
initialize(output, input);
-
- level::internal::transform_tests(input, f, output);
-
mln_pixter(const I) pi(input);
mln_pixter(O) po(output);
po.start();
@@ -207,17 +205,15 @@
const Function_v2v<F>& f_)
{
trace::entering("level::impl::transform_fast_lowq");
- typedef mln_ch_value(I, mln_result(F)) O;
const I& input = exact(input_);
const F& f = exact(f_);
+ level::internal::transform_tests(input, f);
- mln_precondition(exact(input).has_data());
- mln_ch_value(I, mln_result(F)) output;
+ typedef mln_ch_value(I, mln_result(F)) O;
+ O output;
initialize(output, input);
- level::internal::transform_tests(input, f, output);
-
value::lut_vec<mln_vset(I), mln_result(F)>
lut(input.values_eligible(), f);
@@ -247,7 +243,7 @@
template <typename I, typename F>
inline
mln_ch_value(I, mln_result(F))
- transform_dispatch_(mln::trait::undef,
+ transform_dispatch(mln::trait::undef,
mln::trait::image::quant::any,
const Image<I>& input,
const Function_v2v<F>& f)
@@ -258,7 +254,7 @@
template <typename I, typename F>
inline
mln_ch_value(I, mln_result(F))
- transform_dispatch_(mln::trait::image::vw_set::any,
+ transform_dispatch(mln::trait::image::vw_set::any,
mln::trait::image::quant::any,
const Image<I>& input,
const Function_v2v<F>& f)
@@ -269,7 +265,7 @@
template <typename I, typename F>
inline
mln_ch_value(I, mln_result(F))
- transform_dispatch_(mln::trait::image::vw_set::uni,
+ transform_dispatch(mln::trait::image::vw_set::uni,
mln::trait::image::quant::any,
const Image<I>& input,
const Function_v2v<F>& f)
@@ -281,7 +277,7 @@
template <typename I, typename F>
inline
mln_ch_value(I, mln_result(F))
- transform_dispatch_(mln::trait::image::vw_set::any,
+ transform_dispatch(mln::trait::image::vw_set::any,
mln::trait::image::quant::low,
const Image<I>& input,
const Function_v2v<F>& f)
@@ -294,7 +290,7 @@
template <typename I, typename F>
inline
mln_ch_value(I, mln_result(F))
- transform_dispatch_(mln::trait::image::quant::any,
+ transform_dispatch(mln::trait::image::quant::any,
mln::trait::image::value_access::direct,
const Image<I>& input,
const Function_v2v<F>& f)
@@ -306,7 +302,7 @@
template <typename I, typename F>
inline
mln_ch_value(I, mln_result(F))
- transform_dispatch_(mln::trait::image::quant::low,
+ transform_dispatch(mln::trait::image::quant::low,
mln::trait::image::value_access::direct,
const Image<I>& input,
const Function_v2v<F>& f)
@@ -319,12 +315,12 @@
template <typename I, typename F>
inline
mln_ch_value(I, mln_result(F))
- transform_dispatch_(mln::trait::image::quant::any,
+ transform_dispatch(mln::trait::image::quant::any,
mln::trait::image::value_access::any,
const Image<I>& input,
const Function_v2v<F>& f)
{
- return transform_dispatch_(mln_trait_image_vw_set(I)(),
+ return transform_dispatch(mln_trait_image_vw_set(I)(),
mln_trait_image_quant(I)(),
input, f);
}
@@ -333,11 +329,11 @@
template <typename I, typename F>
inline
mln_ch_value(I, mln_result(F))
- transform_dispatch_(mln::trait::image::value_storage::any,
+ transform_dispatch(mln::trait::image::value_storage::any,
const Image<I>& input,
const Function_v2v<F>& f)
{
- return transform_dispatch_(mln_trait_image_vw_set(I)(),
+ return transform_dispatch(mln_trait_image_vw_set(I)(),
mln_trait_image_quant(I)(),
input, f);
}
@@ -345,7 +341,7 @@
template <typename I, typename F>
inline
mln_ch_value(I, mln_result(F))
- transform_dispatch_(mln::trait::image::value_storage::singleton,
+ transform_dispatch(mln::trait::image::value_storage::singleton,
const Image<I>& input,
const Function_v2v<F>& f)
{
@@ -355,7 +351,7 @@
template <typename I, typename F>
inline
mln_ch_value(I, mln_result(F))
- transform_dispatch_(mln::trait::image::value_storage::one_block,
+ transform_dispatch(mln::trait::image::value_storage::one_block,
const Image<I>& input_,
const Function_v2v<F>& f_)
{
@@ -364,11 +360,11 @@
/// Check alignement property
if (mlc_is(mln_trait_image_value_alignement(I),
trait::image::value_alignement::with_grid)::value)
- return transform_dispatch_(mln_trait_image_quant(I)(),
+ return transform_dispatch(mln_trait_image_quant(I)(),
mln_trait_image_value_access(I)(),
input, f_);
else
- return transform_dispatch_(mln_trait_image_vw_set(I)(),
+ return transform_dispatch(mln_trait_image_vw_set(I)(),
mln_trait_image_quant(I)(),
input, f_);
}
@@ -377,10 +373,10 @@
template <typename I, typename F>
mln_ch_value(I, mln_result(F))
- transform_dispatch_(const Image<I>& input,
+ transform_dispatch(const Image<I>& input,
const Function_v2v<F>& f)
{
- return transform_dispatch_(mln_trait_image_value_storage(I)(),
+ return transform_dispatch(mln_trait_image_value_storage(I)(),
input, f);
}
Index: mln/level/transform.hh
--- mln/level/transform.hh (revision 2825)
+++ mln/level/transform.hh (working copy)
@@ -1,4 +1,5 @@
// 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
@@ -39,10 +40,8 @@
# include <mln/core/concept/image.hh>
# include <mln/core/concept/function.hh>
-
# include <mln/value/set.hh>
-
// Specializations are in:
# include <mln/level/transform.spe.hh>
@@ -53,7 +52,7 @@
namespace level
{
- /*! Transform the image \p input through a function \p f
+ /*! Transform the image \p input through a function \p f.
*
* \param[in] input The input image.
* \param[in] f The function.
@@ -67,95 +66,74 @@
transform(const Image<I>& input, const Function_v2v<F>& f);
- /*! Transform two images \p ima1 \p ima2 through a function \p f
+ /*! Transform two images \p input1 \p input2 through a function \p f.
*
- * \param[in] input The input image.
+ * \param[in] input1 The 1st input image.
+ * \param[in] input2 The 2nd input image.
* \param[in] f The function.
*
* This routine runs: \n
- * for all p of \p input, \p output(p) = \p f( \p input(p) ).
- *
+ * for all p of \p input, \p output(p) = \p f( \p input1(p), \p input2(p) ).
*/
- template <typename I, typename J, typename F>
- mln_ch_value(I, mln_result(F))
- transform(const Image<I>& ima1,
- const Image<J>& ima2,
+ template <typename I1, typename I2, typename F>
+ mln_ch_value(I1, mln_result(F))
+ transform(const Image<I1>& input1,
+ const Image<I2>& input2,
const Function_vv2v<F>& f);
+
# ifndef MLN_INCLUDE_ONLY
namespace internal
{
- template <typename I, typename F, typename O>
+
+ template <typename I, typename F>
inline
void transform_tests(const Image<I>& input,
- const Function_v2v<F>& f,
- Image<O>& output)
+ const Function_v2v<F>& f)
{
+ // Dynamic test.
+ mln_precondition(exact(input).has_data());
+
// Avoid a warning about an undefined variable when NDEBUG
// is not defined.
(void) input;
(void) f;
- (void) output;
-
- // Properties check
- mln_precondition((mlc_is(mln_trait_image_pw_io(O),
- trait::image::pw_io::read_write)::value ||
- mlc_is(mln_trait_image_vw_io(O),
- trait::image::vw_io::read_write)::value));
-
- // FIXME Convert test
- mlc_converts_to(mln_result(F), mln_value(O))::check();
-
-
- // Dynamic tests
- mln_precondition(exact(input).has_data());
- mln_precondition(exact(output).domain() >= exact(input).domain());
}
- template <typename I, typename J, typename F, typename O>
+ template <typename I1, typename I2, typename F>
inline
- void transform_tests(const Image<I>& ima1,
- const Image<J>& ima2,
- const Function_v2v<F>& f,
- Image<O>& output)
+ void transform_tests(const Image<I1>& input1,
+ const Image<I2>& input2,
+ const Function_vv2v<F>& f)
{
+ // Dynamic tests.
+ mln_precondition(exact(input1).has_data());
+ mln_precondition(exact(input2).has_data());
+ mln_precondition(exact(input2).domain() == exact(input1).domain());
+
// Avoid a warning about an undefined variable when NDEBUG
// is not defined.
- (void) ima1;
- (void) ima2;
+ (void) input1;
+ (void) input2;
(void) f;
- (void) output;
-
- // Properties check
- mln_precondition((mlc_is(mln_trait_image_pw_io(O),
- trait::image::pw_io::read_write)::value ||
- mlc_is(mln_trait_image_vw_io(O),
- trait::image::vw_io::read_write)::value));
-
- // FIXME Convert test
- mlc_converts_to(mln_result(F), mln_value(O))::check();
-
-
- // Dynamic tests
- mln_precondition(exact(ima1).has_data());
- mln_precondition(exact(ima2).has_data());
- mln_precondition(exact(ima1).domain() == exact(ima2).domain());
- mln_precondition(exact(output).domain() >= exact(ima1).domain());
}
} // end of namespace mln::level::internal
+
namespace impl
{
+ // Generic implementations.
+
+
namespace generic
{
- // Generic implementation.
template <typename I, typename F>
inline
mln_ch_value(I, mln_result(F))
@@ -166,11 +144,11 @@
const I& input = exact(input_);
const F& f = exact(f_);
- mln_precondition(exact(input).has_data());
+ level::internal::transform_tests(input, f);
+
mln_ch_value(I, mln_result(F)) output;
initialize(output, input);
- level::internal::transform_tests(input, f, output);
mlc_is(mln_trait_image_pw_io(mln_ch_value(I, mln_result(F))),
trait::image::pw_io::read_write)::check();
@@ -179,36 +157,33 @@
output(p) = f(input(p));
trace::exiting("level::impl::generic::transform");
-
return output;
}
- // Generic implementation.
- template <typename I, typename J, typename F>
+ template <typename I1, typename I2, typename F>
inline
- mln_ch_value(I, mln_result(F))
- transform(const Image<I>& ima1_,
- const Image<J>& ima2_,
+ mln_ch_value(I1, mln_result(F))
+ transform(const Image<I1>& input1_,
+ const Image<I2>& input2_,
const Function_vv2v<F>& f_)
{
trace::entering("level::impl::generic::transform");
- const I& ima1 = exact(ima1_);
- const I& ima2 = exact(ima2_);
+ const I1& input1 = exact(input1_);
+ const I2& input2 = exact(input2_);
const F& f = exact(f_);
- mln_ch_value(I, mln_result(F)) output;
- initialize(output, ima1);
+ level::internal::transform_tests(input1, input2, f);
-// level::internal::transform_tests(ima1, ima2, f, output);
+ mln_ch_value(I1, mln_result(F)) output;
+ initialize(output, input1);
- mln_piter(I) p(ima1.domain());
+ mln_piter(I1) p(input1.domain());
for_all(p)
- output(p) = f(ima1(p), ima2(p));
+ output(p) = f(input1(p), input2(p));
trace::exiting("level::impl::generic::transform");
-
return output;
}
@@ -217,7 +192,8 @@
} // end of namespace mln::level::impl
- // Facade.
+
+ // Facades.
template <typename I, typename F>
inline
@@ -226,30 +202,31 @@
{
trace::entering("level::transform");
+ internal::transform_tests(input, f);
+
mln_ch_value(I, mln_result(F)) output;
- output = impl::internal::transform_dispatch_(exact(input), exact(f));
+ output = impl::internal::transform_dispatch(exact(input), exact(f));
trace::exiting("level::transform");
-
return output;
}
- template <typename I, typename J, typename F>
+ template <typename I1, typename I2, typename F>
inline
- mln_ch_value(I, mln_result(F))
- transform(const Image<I>& ima1,
- const Image<J>& ima2,
+ mln_ch_value(I1, mln_result(F))
+ transform(const Image<I1>& input1,
+ const Image<I2>& input2,
const Function_vv2v<F>& f)
{
trace::entering("level::transform");
- mln_ch_value(I, mln_result(F)) output;
- output = impl::generic::transform(exact(ima1), exact(ima2), exact(f));
+ internal::transform_tests(input1, input2, f);
- trace::exiting("level::transform");
+ mln_ch_value(I1, mln_result(F)) output;
+ output = impl::generic::transform(input1, input2, f);
+ trace::exiting("level::transform");
return output;
-
}
Index: mln/level/transform_inplace.hh
--- mln/level/transform_inplace.hh (revision 0)
+++ mln/level/transform_inplace.hh (revision 0)
@@ -0,0 +1,226 @@
+// 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_LEVEL_TRANSFORM_INPLACE_HH
+# define MLN_LEVEL_TRANSFORM_INPLACE_HH
+
+/// \file mln/level/transform_inplace.hh
+///
+/// Transform inplace the contents of an image through a function.
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/function.hh>
+
+
+namespace mln
+{
+
+ namespace level
+ {
+
+ /*! Transform inplace the image \p ima through a function \p f.
+ *
+ * \param[in,out] ima The image to be transformed.
+ * \param[in] f The function.
+ *
+ * This routine runs: \n
+ * for all p of \p ima, \p ima(p) = \p f( \p ima(p) ).
+ *
+ */
+ template <typename I, typename F>
+ void
+ transform_inplace(Image<I>& ima, const Function_v2v<F>& f);
+
+
+ /*! Transform inplace the image \p ima with the image \p aux
+ through a function \p f.
+ *
+ * \param[in] ima1 The image to be transformed.
+ * \param[in] aux The auxiliary image.
+ * \param[in] f The function.
+ *
+ * This routine runs: \n
+ * for all p of \p ima, \p ima(p) = \p f( \p ima(p), \p aux(p) ).
+ */
+ template <typename I1, typename I2, typename F>
+ void
+ transform_inplace(Image<I1>& ima, const Image<I2>& aux,
+ const Function_vv2v<F>& f);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+
+ template <typename I, typename F>
+ inline
+ void transform_inplace_tests(const Image<I>& ima,
+ const Function_v2v<F>& f)
+ {
+ // Properties checks.
+ mlc_or(mlc_is(mln_trait_image_pw_io(I),
+ trait::image::pw_io::read_write),
+ mlc_is(mln_trait_image_vw_io(I),
+ trait::image::vw_io::read_write))::check();
+ mlc_converts_to(mln_result(F), mln_value(I))::check();
+
+ // Dynamic test.
+ mln_precondition(exact(ima).has_data());
+
+ // Avoid a warning.
+ (void) ima;
+ (void) f;
+ }
+
+ template <typename I1, typename I2, typename F>
+ inline
+ void transform_tests(const Image<I1>& ima,
+ const Image<I2>& aux,
+ const Function_v2v<F>& f)
+ {
+ // Properties checks.
+ mlc_or(mlc_is(mln_trait_image_pw_io(I1),
+ trait::image::pw_io::read_write),
+ mlc_is(mln_trait_image_vw_io(I1),
+ trait::image::vw_io::read_write))::check();
+ mlc_converts_to(mln_result(F), mln_value(I1))::check();
+
+ // Dynamic test.
+ mln_precondition(exact(ima).has_data());
+ mln_precondition(exact(aux).has_data());
+ mln_precondition(exact(aux).domain() == exact(ima).domain());
+
+ // Avoid a warning.
+ (void) ima;
+ (void) aux;
+ (void) f;
+ }
+
+ } // end of namespace mln::level::internal
+
+
+ namespace impl
+ {
+
+
+ namespace generic
+ {
+
+ // Generic implementation.
+ template <typename I, typename F>
+ inline
+ void
+ transform_inplace(Image<I>& ima_, const Function_v2v<F>& f_)
+ {
+ trace::entering("level::impl::generic::transform_inplace");
+
+ mlc_is(mln_trait_image_pw_io(I),
+ trait::image::pw_io::read_write)::check();
+
+ I& ima = exact(ima_);
+ const F& f = exact(f_);
+
+ level::internal::transform_inplace_tests(ima, f);
+
+ mln_piter(I) p(ima.domain());
+ for_all(p)
+ ima(p) = f(ima(p));
+
+ trace::exiting("level::impl::generic::transform_inplace");
+ }
+
+
+ // Generic implementation.
+ template <typename I1, typename I2, typename F>
+ inline
+ void
+ transform_inplace(Image<I1>& ima_, const Image<I2>& aux_,
+ const Function_vv2v<F>& f_)
+ {
+ trace::entering("level::impl::generic::transform_inplace");
+
+ mlc_is(mln_trait_image_pw_io(I1),
+ trait::image::pw_io::read_write)::check();
+
+ I1& ima = exact(ima_);
+ const I2& aux = exact(aux_);
+ const F& f = exact(f_);
+
+ level::internal::transform_inplace_tests(ima, aux, f);
+
+ mln_piter(I1) p(ima.domain());
+ for_all(p)
+ ima(p) = f(ima(p), aux(p));
+
+ trace::exiting("level::impl::generic::transform_inplace");
+ }
+
+ } // end of namespace mln::level::impl::generic
+
+
+ } // end of namespace mln::level::impl
+
+
+ // Facades.
+
+ template <typename I, typename F>
+ inline
+ void
+ transform_inplace(Image<I>& ima, const Function_v2v<F>& f)
+ {
+ trace::entering("level::transform_inplace");
+
+ level::internal::transform_inplace_tests(ima, f);
+ impl::generic::transform_inplace(ima, f);
+
+ trace::exiting("level::transform_inplace");
+ }
+
+ template <typename I1, typename I2, typename F>
+ void
+ transform_inplace(Image<I1>& ima, const Image<I2>& aux,
+ const Function_vv2v<F>& f)
+ {
+ trace::entering("level::transform_inplace");
+
+ level::internal::transform_inplace_tests(ima, aux, f);
+ impl::generic::transform_inplace(ima, aux, f);
+
+ trace::exiting("level::transform_inplace");
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::level
+
+} // end of namespace mln
+
+
+#endif // ! MLN_LEVEL_TRANSFORM_INPLACE_HH
Index: mln/linear/ch_convolve.hh
--- mln/linear/ch_convolve.hh (revision 2825)
+++ mln/linear/ch_convolve.hh (working copy)
@@ -38,12 +38,18 @@
# include <mln/trait/ch_value.hh>
# include <mln/value/ops.hh>
+# include <mln/algebra/vec.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
+# define mln_ch_convolve_grad(I, W) \
+ typename mln::trait::ch_value< I, algebra::vec< I::site::dim, typename
mln::linear::ch_convolve<I,W>::ret::value > >::ret
+
+
namespace mln
{
Index: mln/linear/sobel_2d.hh
--- mln/linear/sobel_2d.hh (revision 2821)
+++ mln/linear/sobel_2d.hh (working copy)
@@ -26,12 +26,12 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_LINEAR_SOBEL_HH
-# define MLN_LINEAR_SOBEL_HH
+#ifndef MLN_LINEAR_SOBEL_2D_HH
+# define MLN_LINEAR_SOBEL_2D_HH
-/// \file mln/linear/sobel.hh
+/// \file mln/linear/sobel_2d.hh
///
-/// Sobel filter.
+/// Sobel_2d filter.
/// \todo Extends to the case of other dimensions (only the 2-d case
/// is handled here).
@@ -42,24 +42,10 @@
# include <mln/arith/plus.hh>
# include <mln/level/abs.hh>
-# include <mln/fun/v2v/norm.hh>
-# include <mln/level/transform.hh>
-# include <mln/linear/line_x2_convolve.hh>
+# include <mln/fun/x2v/l1_norm.hh>
+# include <mln/fun/vv2v/vec.hh>
+# include <mln/linear/convolve_2x1d.hh>
-# include <mln/value/stack.hh>
-
-// FIXME: We might want to move these macros to another file, like
-// mln/core/gradient.hh.
-
-
-/// \brief Get the gradient component image type associated to image \a I.
-#define mln_gradient_component(I) \
- /* FIXME: Use mln_sum_x (or mln_sum_product) instead of mln_sum. */ \
- mln_ch_value(I, mln_sum(mln_value(I)))
-
-/// \brief Get the gradient image type associated to image \a I.
-#define mln_gradient(I) \
- mln::value::stack_image<I::point::dim, mln_gradient_component(I)>
namespace mln
@@ -68,194 +54,109 @@
namespace linear
{
- /// Sobel gradient components.
+ /// Sobel_2d gradient components.
/// \{
- /// Compute the vertical component of the Sobel gradient.
+ /// Compute the horizontal component of the 2D Sobel gradient.
template <typename I>
- mln_gradient_component(I) sobel_h(const Image<I>& input);
+ mln_ch_convolve(I, int)
+ sobel_2d_h(const Image<I>& input);
- /// Compute the horizontal component of the Sobel gradient.
+ /// Compute the vertical component of the 2D Sobel gradient.
template <typename I>
- mln_gradient_component(I) sobel_v(const Image<I>& input);
+ mln_ch_convolve(I, int)
+ sobel_2d_v(const Image<I>& input);
/// \}
- /// Compute the Sobel gradient of an image.
- ///
- /// \param[in] input A vectorial output image.
- /// \{
+ /// Compute the vertical component of the 2D Sobel gradient.
template <typename I>
- mln_gradient(I) sobel(const Image<I>& input);
- /// \}
-
- /// Compute the norm of the Sobel gradient of an image.
- ///
- /// \param input a vectorial input image
- /// \param norm a norm functor (\see mln/fun/v2v/norm.hh),
- /// defaulting to the L1-norm (mln::fun::v2v::l1_norm).
- /// \return the norm-image of the Sobel gradient of the input image
- /// FIXME: Add constraints on N (mln::Function_v2v<N>).
- /// \{
- template <typename I, typename N>
- mln_ch_value(I, mln_result(N)) sobel_norm(const Image<I>& input, N norm);
+ mln_ch_convolve_grad(I, int)
+ sobel_2d(const Image<I>& input);
/// \}
-
- /// \brief Compute the L-1 norm of the Sobel gradient of an image.
- ///
- /// This function is a shortcut for the general
- /// mln::linear::sobel_norm function.
- /// \{
+ /// Compute the L1 norm of the 2D Sobel gradient.
template <typename I>
- mln_ch_value(I, mln_sum(mln_value(I))) sobel_norm(const Image<I>& input);
+ mln_ch_convolve(I, int)
+ sobel_2d_l1_norm(const Image<I>& input);
/// \}
# ifndef MLN_INCLUDE_ONLY
-/// \brief Ensure type \p V is a scalar value.
-///
-/// For internal use only (#undef'd before the end of this file). (We
-/// might want to export this macro to the user interface; if so,
-/// rename it and move it elsewhere.)
-///
-/// FIXME: At the moment (rev. 1645), we cannot use mlc_is_a to check
-/// whether V derives from trait::value::nature::scalar like this
-///
-/// mlc_is_a(trait::value_<V>::nature, trait::value::nature::scalar)::check()
-///
-/// since `mlc_is_a' doesn't work on non template classes (yet). Hence
-/// the ugly workaround based on comprehensive checks.
-/// \{
-# define mlc_internal_ensure_is_scalar(V) \
- mlc_or(mlc_equal(typename mln::trait::value_<V>::nature, \
- mln::trait::value::nature::scalar), \
- mlc_or(mlc_equal(typename mln::trait::value_<V>::nature, \
- mln::trait::value::nature::integer), \
- mlc_equal(typename mln::trait::value_<V>::nature, \
- mln::trait::value::nature::floating)))::check()
-/// \}
- namespace impl
- {
+ // Facades.
template <typename I>
inline
- mln_gradient_component(I)
- sobel_h_(const Image<I>& input)
+ mln_ch_convolve(I, int)
+ sobel_2d_h(const Image<I>& input)
{
- // We don't use const ints here, since it would confuse the
- // STL allocators used within the windows used in the
- // convolutions.
- int wrow[] = { -1, 0, 1 };
- int wcol[] = { 1,
+ trace::entering("linear::sobel_2d_h");
+ mln_precondition(exact(input).has_data());
+
+ int wh[] = { -1, 0, 1 };
+ int wv[] = { 1,
2,
1 };
- // FIXME: It'd probably be nicer to have a "functional" version
- // of linear::line_x2_convolve.
- mln_gradient_component(I) output(exact(input).domain());
- linear::line_x2_convolve(input, wrow, wcol, output);
+ mln_ch_convolve(I, int) output = convolve_2x1d(input, wh, wv);
+
+ trace::exiting("linear::sobel_2d_h");
return output;
}
+
template <typename I>
inline
- mln_gradient_component(I)
- sobel_v_(const Image<I>& input)
+ mln_ch_convolve(I, int)
+ sobel_2d_v(const Image<I>& input)
{
- // We don't use const ints here, since it would confuse the
- // STL allocators used within the windows used in the
- // convolutions.
- int wrow[] = { 1, 2, 1 };
- int wcol[] = { -1,
+ trace::entering("linear::sobel_2d_v");
+ mln_precondition(exact(input).has_data());
+
+ int wh[] = { 1, 2, 1 };
+ int wv[] = { -1,
0,
+1 };
- // FIXME: It'd probably be nicer to have a "functional" version
- // of linear::line_x2_convolve.
- mln_gradient_component(I) output(exact(input).domain());
- linear::line_x2_convolve(input, wrow, wcol, output);
+ mln_ch_convolve(I, int) output = convolve_2x1d(input, wh, wv);
+
+ trace::exiting("linear::sobel_2d_v");
return output;
}
- template <typename I>
- inline
- mln_gradient(I)
- sobel_(const Image<I>& input)
- {
- /* FIXME: Not generic w.r.t. the dimension (only works on 2-D
- images here). Anyway, we'd need a n-dimensional definition
- of the Sobel gradient to.
-
- Stick with a very simple static assertion for the momemt,
- and improve later. */
- mlc_equal(metal::int_<I::point::dim>, metal::int_<2>)::check();
-
- mln_gradient_component(I) component_h = linear::sobel_h(input);
- mln_gradient_component(I) component_v = linear::sobel_v(input);
- return value::stack(component_h, component_v);
- }
- /* FIXME: Add constraints on N (mln::Function_v2v<N>). */
- template <typename I, typename N>
- mln_ch_value(I, mln_result(N))
- sobel_norm_(const Image<I>& input, N norm)
+ template <typename I>
+ mln_ch_convolve_grad(I, int)
+ sobel_2d(const Image<I>& input)
{
- mln_gradient(I) gradient = mln::linear::sobel (input);
- return level::transform (gradient, norm);
- }
-
- } // end of namespace mln::linear::impl
+ trace::entering("linear::sobel_2d");
+ mln_precondition(exact(input).has_data());
+ typedef mln_ch_convolve(I, int) J;
+ J h = sobel_2d_h(input),
+ v = sobel_2d_v(input);
+ fun::vv2v::vec<mln_value(J)> f;
+ mln_ch_convolve_grad(I, int) output = level::transform(h, v, f);
- // Facades.
-
- template <typename I>
- inline
- mln_gradient_component(I) sobel_h(const Image<I>& input)
- {
- mlc_internal_ensure_is_scalar(mln_value(I));
- return impl::sobel_h_(exact(input));
+ trace::exiting("linear::sobel_2d");
+ return output;
}
- template <typename I>
- inline
- mln_gradient_component(I) sobel_v(const Image<I>& input)
- {
- mlc_internal_ensure_is_scalar(mln_value(I));
- return impl::sobel_v_(exact(input));
- }
template <typename I>
- inline
- mln_gradient(I) sobel(const Image<I>& input)
+ mln_ch_convolve(I, int)
+ sobel_2d_l1_norm(const Image<I>& input)
{
- mlc_internal_ensure_is_scalar(mln_value(I));
- return impl::sobel_(exact(input));
- }
+ trace::entering("linear::sobel_2d_norm_l1");
+ mln_precondition(exact(input).has_data());
- template <typename I, typename N>
- inline
- mln_ch_value(I, mln_result(N))
- sobel_norm(const Image<I>& input, N norm)
- {
- mlc_internal_ensure_is_scalar(mln_value(I));
- return impl::sobel_norm_(exact(input), norm);
- }
+ typedef mln_ch_convolve_grad(I, int) G;
+ G grad = sobel_2d(input);
+ fun::x2v::l1_norm<mln_value(G)> f;
+ mln_ch_convolve(I, int) output = level::transform(grad, f);
- template <typename I>
- inline
- mln_ch_value(I, mln_sum(mln_value(I)))
- sobel_norm(const Image<I>& input)
- {
- // The type of a component of a vector from the gradient.
- typedef mln_sum(mln_value(I)) gradient_val_t;
- // The type of a vector from the gradient.
- typedef mln::algebra::vec<I::point::dim, gradient_val_t> gradient_vec_t;
- return sobel_norm(input,
- fun::v2v::l1_norm<gradient_vec_t, gradient_val_t>());
+ trace::exiting("linear::sobel_2d");
+ return output;
}
-# undef mlc_internal_ensure_is_scalar
-
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::linear
@@ -263,4 +164,4 @@
} // end of namespace mln
-#endif // ! MLN_LINEAR_SOBEL_HH
+#endif // ! MLN_LINEAR_SOBEL_2D_HH
Property changes on: mln/linear/sobel_2d.hh
___________________________________________________________________
Added: svn:mergeinfo
Index: mln/make/image2d.hh
--- mln/make/image2d.hh (revision 2825)
+++ mln/make/image2d.hh (working copy)
@@ -60,8 +60,8 @@
image2d(V (&values)[S])
{
mlc_bool(S != 0)::check();
- enum { s = mlc_sqrt_int(S) / 2 };
- metal::bool_<((2 * s + 1) * (2 * s + 1) == S)>::check();
+ enum { s = mlc_sqrt_int(S) };
+ metal::bool_<(s * s == S)>::check();
mln::image2d<V> tmp;
convert::from_to(values, tmp);
return tmp;
Index: mln/fun/x2v/l1_norm.hh
--- mln/fun/x2v/l1_norm.hh (revision 0)
+++ mln/fun/x2v/l1_norm.hh (revision 0)
@@ -0,0 +1,81 @@
+// 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_FUN_X2V_L1_NORM_HH
+# define MLN_FUN_X2V_L1_NORM_HH
+
+/// \file mln/fun/x2v/l1_norm.hh
+///
+/// Define the L1-norm of an algebraic vector.
+
+# include <mln/core/concept/function.hh>
+# include <mln/algebra/vec.hh>
+# include <mln/math/abs.hh>
+
+
+namespace mln
+{
+
+ namespace fun
+ {
+
+ namespace x2v
+ {
+
+ template <typename V>
+ struct l1_norm : public Function_v2v< l1_norm<V> >
+ {
+ typedef mln_coord(V) C;
+ typedef mln_sum(C) result;
+
+ result operator()(const V& v) const;
+ };
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename V>
+ inline
+ typename l1_norm<V>::result
+ l1_norm<V>::operator()(const V& v) const
+ {
+ result res = 0;
+ for (unsigned i = 0; i < V::dim; ++i)
+ res += mln::math::abs(v[i]);
+ return res;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::fun::x2v
+
+ } // end of namespace mln::fun
+
+} // end of namespace mln
+
+
+#endif // ! MLN_FUN_X2V_L1_NORM_HH
Index: mln/fun/vv2v/all.hh
--- mln/fun/vv2v/all.hh (revision 2825)
+++ mln/fun/vv2v/all.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2008 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
@@ -28,10 +28,9 @@
#ifndef MLN_FUN_VV2V_ALL_HH
# define MLN_FUN_VV2V_ALL_HH
-/*! \file mln/fun/vv2v/all.hh
- *
- * \brief File that includes all functions from point to value.
- */
+/// \file mln/fun/vv2v/all.hh
+///
+/// File that includes all functions from point to value.
namespace mln
@@ -40,7 +39,7 @@
namespace fun
{
- /// Namespace of functions from point to value.
+ /// Namespace of functions from a couple of values to a value.
namespace vv2v
{
}
@@ -51,5 +50,7 @@
# include <mln/fun/vv2v/max.hh>
# include <mln/fun/vv2v/min.hh>
+# include <mln/fun/vv2v/vec.hh>
+
#endif // ! MLN_FUN_VV2V_ALL_HH
Index: mln/fun/vv2v/vec.hh
--- mln/fun/vv2v/vec.hh (revision 0)
+++ mln/fun/vv2v/vec.hh (revision 0)
@@ -0,0 +1,80 @@
+// 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_FUN_VV2V_VEC_HH
+# define MLN_FUN_VV2V_VEC_HH
+
+/// \file mln/fun/vv2v/vec.hh
+///
+/// computing the vecimum of two values using a functor.
+
+# include <mln/core/concept/function.hh>
+# include <mln/algebra/vec.hh>
+
+
+namespace mln
+{
+
+ namespace fun
+ {
+
+ namespace vv2v
+ {
+
+ // FIXME: Doc.
+
+ /// \brief A functor computing the vecimum of two values.
+ template <typename V>
+ struct vec : public Function_vv2v< vec<V> >
+ {
+ typedef algebra::vec<2,V> result;
+ algebra::vec<2,V> operator()(const V& v1, const V& v2) const;
+ };
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename V>
+ inline
+ algebra::vec<2,V>
+ vec<V>::operator()(const V& v1, const V& v2) const
+ {
+ algebra::vec<2,V> tmp;
+ tmp.set(v1, v2);
+ return tmp;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::fun::vv2v
+
+ } // end of namespace mln::fun
+
+} // end of namespace mln
+
+
+#endif // ! MLN_FUN_VV2V_VEC_HH