https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Revamp extension fill and fix dependant morpho operators.
* tests/core/routine/extend.cc: New.
* tests/core/routine/Makefile.am: Update.
* sandbox/geraud/cs2d/dbl_neighb.cc: Rename as...
* doc/examples/tuto_one.cc: ...this.
Update.
* mln/core/image/extension_ima.hh (change_extension): New.
* mln/core/routine/extend.hh (todo): New.
* mln/core/internal/image_morpher.hh (unmorph_): New.
* mln/border/fill.hh: Revamp.
* mln/morpho/closing_area.hh (closing_area): New up-to-date sig.
* mln/morpho/erosion.spe.hh: Update.
De-activate some parts because of multiple windows.
(FIXME): New couple.
* mln/morpho/erosion.hh (has): Replace by...
(domain.has): ...this.
* mln/morpho/dilation.hh: Likewise.
* mln/morpho/meyer_wst.hh: Likewise.
* mln/canvas/morpho/algebraic_union_find.hh: Likewise.
* mln/canvas/labeling.hh: Likewise.
* mln/morpho/includes.hh: New include.
* mln/extension/fill.hh: Revamp.
doc/examples/tuto_one.cc | 33 +++----
mln/border/fill.hh | 105 ++++++++++++++++++----
mln/canvas/labeling.hh | 4
mln/canvas/morpho/algebraic_union_find.hh | 2
mln/core/image/extension_ima.hh | 13 ++
mln/core/internal/image_morpher.hh | 15 +++
mln/core/routine/extend.hh | 1
mln/extension/fill.hh | 140 +++++++++++++++++++++++-------
mln/morpho/closing_area.hh | 14 +++
mln/morpho/dilation.hh | 4
mln/morpho/erosion.hh | 4
mln/morpho/erosion.spe.hh | 59 +++++++-----
mln/morpho/includes.hh | 2
mln/morpho/meyer_wst.hh | 6 -
tests/core/routine/Makefile.am | 2
tests/core/routine/extend.cc | 72 +++++++++++++++
16 files changed, 374 insertions(+), 102 deletions(-)
Index: tests/core/routine/Makefile.am
--- tests/core/routine/Makefile.am (revision 2408)
+++ tests/core/routine/Makefile.am (working copy)
@@ -5,10 +5,12 @@
check_PROGRAMS = \
clone \
exact \
+ extend \
initialize
clone_SOURCES = clone.cc
exact_SOURCES = exact.cc
+extend_SOURCES = extend.cc
initialize_SOURCES = initialize.cc
TESTS = $(check_PROGRAMS)
Index: tests/core/routine/extend.cc
--- tests/core/routine/extend.cc (revision 0)
+++ tests/core/routine/extend.cc (revision 0)
@@ -0,0 +1,72 @@
+// Copyright (C) 2008 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/core/routine/extend.cc
+ *
+ * \brief Tests on mln::extend.
+ */
+
+#include <mln/core/var.hh>
+
+#include <mln/core/image/image2d.hh>
+#include <mln/core/image/sub_image.hh>
+
+#include <mln/core/image/extended.hh>
+#include <mln/core/routine/extend.hh>
+
+#include <mln/debug/iota.hh>
+#include <mln/debug/println.hh>
+
+#include <mln/extension/fill.hh>
+
+
+
+int main()
+{
+ using namespace mln;
+
+ image2d<int> ima(3, 3, 1);
+ debug::iota(ima);
+
+ box2d bb = ima.domain().to_larger(1);
+ box2d BB = ima.domain().to_larger(2);
+
+ debug::println(ima);
+ debug::println(extended_to(ima, bb));
+
+ mln_VAR(ima_, extend(ima | make::box2d(2,2), 7));
+ debug::println(ima_);
+
+ debug::println(extended_to(ima_, BB));
+
+ extension::fill(ima_, 8);
+
+ debug::println(ima_);
+ debug::println(extended_to(ima_, BB));
+
+ debug::println(ima_);
+}
Index: doc/examples/tuto_one.cc
--- doc/examples/tuto_one.cc (revision 2406)
+++ doc/examples/tuto_one.cc (working copy)
@@ -3,6 +3,7 @@
# include <mln/value/int_u8.hh>
# include <mln/value/rgb8.hh>
+# include <mln/core/var.hh>
# include <mln/core/image/image2d.hh>
# include <mln/core/alias/neighb2d.hh>
# include <mln/core/alias/window2d.hh>
@@ -11,7 +12,7 @@
# include <mln/convert/to_image.hh>
# include <mln/debug/println.hh>
-# include "dbl_neighb.hh"
+# include <mln/make/double_neighb2d.hh>
# include <mln/io/pgm/load.hh>
# include <mln/io/pgm/save.hh>
@@ -29,14 +30,6 @@
-struct is_chess_t
-{
- bool operator()(const mln::point2d& p) const
- {
- return p.col() % 2 == p.row() % 2;
- }
-};
-
struct colorize : mln::Function_v2v< colorize >
{
@@ -58,6 +51,12 @@
};
+ bool is_chess(const mln::point2d& p)
+ {
+ return p.col() % 2 == p.row() % 2;
+ }
+
+
void usage(char* argv[])
{
std::cerr << "usage: " << argv[0] << " input.pgm
lambda output.ppm" << std::endl;
@@ -70,6 +69,7 @@
using namespace mln;
using value::int_u8;
+
if (argc != 4)
usage(argv);
@@ -84,26 +84,27 @@
1, 0, 1,
1, 1, 0 };
- dbl_neighb_<dpoint2d, is_chess_t> nbh;
- nbh
- .when_true (make::neighb2d(vert))
- .when_false(make::neighb2d(hori));
+ mln_VAR( nbh, make::double_neighb2d(is_chess, vert, hori) );
+// mln_VAR(nbh, c4());
+// mln_VAR(nbh, c8());
- image2d<int_u8> clo, grad = morpho::gradient(lena, nbh);
- // io::pgm::save(grad, "grad.pgm");
+ image2d<int_u8> clo, grad = morpho::gradient(lena, nbh.win());
+ // io::pgm::save(grad, "tmp_grad.pgm");
int lambda = atoi(argv[2]);
if (lambda > 1)
{
clo = morpho::closing_area(grad, nbh, lambda);
- // io::pgm::save(clo, "clo.pgm");
+ io::pgm::save(clo, "tmp_clo.pgm");
}
else
clo = grad;
unsigned l;
image2d<unsigned> wst = morpho::meyer_wst(clo, nbh, l);
+
std::cout << "l = " << l << std::endl;
+ debug::println(wst);
io::ppm::save(level::transform(wst, colorize(l)), argv[3]);
Index: mln/core/image/extension_ima.hh
--- mln/core/image/extension_ima.hh (revision 2408)
+++ mln/core/image/extension_ima.hh (working copy)
@@ -39,6 +39,7 @@
*/
# include <mln/core/internal/image_identity.hh>
+# include <mln/level/fill_with_value.hh>
@@ -142,6 +143,9 @@
/// Mutable access to the extension domain (image). This domain
/// can be modified if J a read-write image type.
J& extension();
+
+ /// Change the value in the extension domain (image).
+ void change_extension(const mln_value(I)& v);
};
@@ -266,6 +270,15 @@
return this->data_->ext_;
}
+ template <typename I, typename J>
+ inline
+ void
+ extension_ima<I, J>::change_extension(const mln_value(I)& v)
+ {
+ mlc_equal(mln_trait_image_value_io(J),
+ trait::image::value_io::read_write)::check();
+ level::fill_with_value(v);
+ }
// init_
Index: mln/core/routine/extend.hh
--- mln/core/routine/extend.hh (revision 2408)
+++ mln/core/routine/extend.hh (working copy)
@@ -35,6 +35,7 @@
*
* \todo Use the 'instant' mechanism.
* \todo Deal with ambiguities.
+ * \todo Check that there is no extension yet (except "extendable").
*/
# include <mln/core/image/extension_ima.hh>
Index: mln/core/internal/image_morpher.hh
--- mln/core/internal/image_morpher.hh (revision 2408)
+++ mln/core/internal/image_morpher.hh (working copy)
@@ -61,6 +61,11 @@
/// Return the delegatee_ pointer (non-const version); default code.
I* delegatee_();
+
+ /// Give the morphed image.
+ I& unmorph_();
+
+
/* \brief Test if this image has been initialized; default impl.
*
* This default impl is stronger than the one inherited from
@@ -130,6 +135,16 @@
template <typename I, typename T, typename S, typename E>
inline
+ I&
+ image_morpher<I, T, S, E>::unmorph_()
+ {
+ I* ptr = delegatee_();
+ mln_assertion(ptr != 0);
+ return *ptr;
+ }
+
+ template <typename I, typename T, typename S, typename E>
+ inline
image_morpher<I, T, S, E>::operator I() const
{
mln_precondition(exact(this)->has_data());
Index: mln/border/fill.hh
--- mln/border/fill.hh (revision 2408)
+++ mln/border/fill.hh (working copy)
@@ -58,16 +58,34 @@
template <typename I>
void fill(const Image<I>& ima, const mln_value(I)& v);
+
# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+
+ template <typename I>
+ inline
+ void fill_tests(const Image<I>& ima, const mln_value(I)& v)
+ {
+ mln_precondition(exact(ima).has_data());
+ }
+
+ } // end of namespace mln::border::internal
+
+
namespace impl
{
template <typename I>
inline
- void fill_size_1_(const I& ima, const mln_value(I)& v)
+ void fill_size_1(const Image<I>& ima_, const mln_value(I)& v)
{
- trace::entering("border::impl::fill_size_1_");
+ trace::entering("border::impl::fill_size_1");
+
+ const I& ima = exact(ima_);
+ internal::fill_tests(ima, v);
typedef mln_psite(I) P;
typedef mln_psite(I) P;
@@ -88,14 +106,18 @@
*(const int*)(&v),
ima.nelements () - st);
- trace::exiting("border::impl::fill_size_1_");
+ trace::exiting("border::impl::fill_size_1");
}
+
template <typename I>
inline
- void fill_size_n_(const I& ima, const mln_value(I)& v)
+ void fill_size_n(const I& ima_, const mln_value(I)& v)
{
- trace::entering("border::impl::fill_size_n_");
+ trace::entering("border::impl::fill_size_n");
+
+ const I& ima = exact(ima_);
+ internal::fill_tests(ima, v);
typedef mln_psite(I) P;
mln_box_runstart_piter(I) pl(ima.domain());
@@ -112,34 +134,81 @@
for (std::size_t i = st; i < ima.nelements (); ++i)
const_cast<I&>(ima).element(i) = v;
- trace::exiting("border::impl::fill_size_n_");
+ trace::exiting("border::impl::fill_size_n");
+ }
+
+
+ } // end of namespace mln::border::impl
+
+
+ namespace internal
+ {
+
+ // Dispatch.
+
+ template <typename I>
+ inline
+ void fill_dispatch(const Image<I>& ima, const mln_value(I)& v);
+
+ template <typename I>
+ inline
+ void fill_dispatch(mln::trait::image::category::primary,
+ mln::trait::image::speed::fastest,
+ I& ima, const mln_value(I)& v)
+ {
+ if (sizeof(mln_value(I)) == 1)
+ impl::fill_size_1(ima, v);
+ else
+ impl::fill_size_n(ima, v);
+ }
+
+ template <typename I>
+ inline
+ void fill_dispatch(mln::trait::image::category::primary,
+ mln::trait::image::speed::any,
+ I& ima, const mln_value(I)& v)
+ {
+ // No border so no-op.
}
+ template <typename I>
+ inline
+ void fill_dispatch(mln::trait::image::category::morpher,
+ mln::trait::image::speed::any,
+ I& ima, const mln_value(I)& v)
+ {
+ fill_dispatch(ima.unmorph_(), v);
}
+ template <typename I>
+ inline
+ void fill_dispatch(const Image<I>& ima_, const mln_value(I)& v)
+ {
+ I& ima = const_cast<I&>(exact(ima_));
+ fill_dispatch(mln_trait_image_category(I)(),
+ mln_trait_image_speed(I)(),
+ ima, v);
+ }
+
+ } // end of namespace mln::border::internal
+
+
+
// Facade.
template <typename I>
inline
- void fill(const Image<I>& ima_, const mln_value(I)& v)
+ void fill(const Image<I>& ima, const mln_value(I)& v)
{
trace::entering("border::fill");
- typedef mln_psite(I) P;
- const I& ima = exact(ima_);
-
- mlc_is(mln_trait_image_speed(I), trait::image::speed::fastest)::check();
- mln_precondition(ima.has_data());
- if (!ima.border ())
- return;
- if (sizeof(mln_value(I)) == 1)
- impl::fill_size_1_(ima, v);
- else
- impl::fill_size_n_(ima, v);
+ internal::fill_tests(ima, v);
+ internal::fill_dispatch(ima, v);
trace::exiting("border::fill");
}
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::border
Index: mln/morpho/closing_area.hh
--- mln/morpho/closing_area.hh (revision 2408)
+++ mln/morpho/closing_area.hh (working copy)
@@ -48,6 +48,10 @@
void closing_area(const Image<I>& input, const Neighborhood<N>&
nbh,
std::size_t lambda, Image<O>& output);
+ template <typename I, typename N>
+ mln_concrete(I) closing_area(const Image<I>& input, const
Neighborhood<N>& nbh,
+ std::size_t lambda);
+
# ifndef MLN_INCLUDE_ONLY
@@ -62,6 +66,16 @@
closing_attribute< accu::count_<pix_t> >(input, nbh, lambda, output);
}
+ template <typename I, typename N>
+ mln_concrete(I) closing_area(const Image<I>& input, const
Neighborhood<N>& nbh,
+ std::size_t lambda)
+ {
+ mln_concrete(I) output;
+ initialize(output, input);
+ closing_area(input, nbh, lambda, output);
+ return output;
+ }
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::morpho
Index: mln/morpho/erosion.spe.hh
--- mln/morpho/erosion.spe.hh (revision 2408)
+++ mln/morpho/erosion.spe.hh (working copy)
@@ -93,7 +93,7 @@
O output;
initialize(output, input);
-// border::fill(input, mln_max(mln_value(I)));
+ extension::fill(input, mln_max(mln_value(I)));
mln_pixter(const I) p(input);
mln_pixter(O) o(output);
@@ -124,7 +124,7 @@
O output;
initialize(output, input);
-// border::fill(input, true);
+ extension::fill(input, true);
mln_pixter(const I) p(input);
mln_pixter(O) p_out(output);
@@ -154,7 +154,7 @@
const W& win = exact(win_);
O output;
-// border::fill(input, true);
+ extension::fill(input, true);
output = clone(input);
mln_piter(I) p(input.domain());
@@ -183,7 +183,7 @@
const W& win = exact(win_);
O output;
-// border::fill(input, true);
+ extension::fill(input, true);
output = clone(input);
mln_pixter(const I) p(input);
@@ -439,26 +439,29 @@
// dispatch for the generic version
- template <typename I, typename W>
- mln_concrete(I)
- erosion_dispatch_for_generic(trait::image::kind::logic, // On sets.
- trait::image::speed::fastest,
- const I& input, const W& win)
- {
- if (win.is_centered())
- return impl::erosion_on_set_centered_fastest(input, win);
- else
- return impl::erosion_on_set_fastest(input, win);
- }
+ // FIXME: De-activate because when the window is multiple, the access
+ // win.dp(i), used in dpoints_pixter, is impossible.
- template <typename I, typename W>
- mln_concrete(I)
- erosion_dispatch_for_generic(trait::image::kind::any, // On functions.
- trait::image::speed::fastest,
- const I& input, const W& win)
- {
- return impl::erosion_on_function_fastest(input, win);
- }
+// template <typename I, typename W>
+// mln_concrete(I)
+// erosion_dispatch_for_generic(trait::image::kind::logic, // On sets.
+// trait::image::speed::fastest,
+// const I& input, const W& win)
+// {
+// if (win.is_centered())
+// return impl::erosion_on_set_centered_fastest(input, win);
+// else
+// return impl::erosion_on_set_fastest(input, win);
+// }
+
+// template <typename I, typename W>
+// mln_concrete(I)
+// erosion_dispatch_for_generic(trait::image::kind::any, // On functions.
+// trait::image::speed::fastest,
+// const I& input, const W& win)
+// {
+// return impl::erosion_on_function_fastest(input, win);
+// }
template <typename I, typename W>
mln_concrete(I)
@@ -543,9 +546,13 @@
mln_concrete(I)
erosion_dispatch_wrt_win(const I& input, const W& win)
{
- if (erosion_chooses_arbitrary(input, win))
- return erosion_dispatch_for_arbitrary(input, win);
- else
+ // FIXME: De-activate because, when win is multiple,
+ // geom::shift does not work. We have to introduce
+ // props from windows, then re-write geom::shift.
+
+// if (erosion_chooses_arbitrary(input, win))
+// return erosion_dispatch_for_arbitrary(input, win);
+// else
return erosion_dispatch_for_generic(input, win);
}
Index: mln/morpho/erosion.hh
--- mln/morpho/erosion.hh (revision 2408)
+++ mln/morpho/erosion.hh (working copy)
@@ -79,7 +79,7 @@
for_all(p)
{
min.init();
- for_all(q) if (input.has(q))
+ for_all(q) if (input.domain().has(q))
min.take(input(q));
output(p) = min;
}
@@ -107,7 +107,7 @@
mln_qiter(W) q(win, p);
for_all(p)
{
- for_all(q) if (input.has(q))
+ for_all(q) if (input.domain().has(q))
if (input(q) == false)
break;
output(p) = ! q.is_valid();
Index: mln/morpho/dilation.hh
--- mln/morpho/dilation.hh (revision 2408)
+++ mln/morpho/dilation.hh (working copy)
@@ -99,7 +99,7 @@
for_all(p)
{
max.init();
- for_all(q) if (input.has(q))
+ for_all(q) if (input.domain().has(q))
max.take(input(q));
output(p) = max.to_result();
}
@@ -122,7 +122,7 @@
mln_qiter(W) q(win, p);
for_all(p)
if (!input(p))
- for_all(q) if (input.has(q))
+ for_all(q) if (input.domain().has(q))
if (input(q))
{
output(p) = true;
Index: mln/morpho/includes.hh
--- mln/morpho/includes.hh (revision 2408)
+++ mln/morpho/includes.hh (working copy)
@@ -54,7 +54,9 @@
# include <mln/level/fill.hh>
# include <mln/test/positive.hh>
+
// # include <mln/border/all.hh>
+# include <mln/extension/fill.hh>
# include <mln/geom/sym.hh>
# include <mln/set/inter.hh>
Index: mln/morpho/meyer_wst.hh
--- mln/morpho/meyer_wst.hh (revision 2408)
+++ mln/morpho/meyer_wst.hh (working copy)
@@ -138,7 +138,7 @@
for_all (p)
if (output(p) == unmarked)
for_all(n)
- if (output.has(n) && output(n) != unmarked)
+ if (output.domain().has(n) && output(n) != unmarked)
{
queue.push(p);
break;
@@ -157,7 +157,7 @@
bool single_adjacent_marker_p = true;
mln_niter(N) n(nbh, p);
for_all(n)
- if (output.has(n) && output(n) != unmarked)
+ if (output.domain().has(n) && output(n) != unmarked)
{
if (adjacent_marker == unmarked)
{
@@ -179,7 +179,7 @@
{
output(p) = adjacent_marker;
for_all(n)
- if (output.has(n) && output(n) == unmarked)
+ if (output.domain().has(n) && output(n) == unmarked)
queue.push(n);
}
}
Index: mln/canvas/morpho/algebraic_union_find.hh
--- mln/canvas/morpho/algebraic_union_find.hh (revision 2408)
+++ mln/canvas/morpho/algebraic_union_find.hh (working copy)
@@ -92,7 +92,7 @@
{
make_set(p);
for_all(n)
- if (f.input.has(n) && deja_vu(n))
+ if (f.input.domain().has(n) && deja_vu(n))
do_union(n, p);
deja_vu(p) = true;
}
Index: mln/canvas/labeling.hh
--- mln/canvas/labeling.hh (revision 2408)
+++ mln/canvas/labeling.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 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
@@ -173,7 +173,7 @@
{
make_set(p);
for_all(n)
- if (f.input.has(n) && deja_vu(n))
+ if (f.input.domain().has(n) && deja_vu(n))
{
if (f.equiv(n, p))
do_union(n, p);
Index: mln/extension/fill.hh
--- mln/extension/fill.hh (revision 2408)
+++ mln/extension/fill.hh (working copy)
@@ -25,7 +25,6 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-
#ifndef MLN_CORE_EXTENSION_FILL_HH
# define MLN_CORE_EXTENSION_FILL_HH
@@ -33,6 +32,9 @@
*
* \brief Define function that fills domain extension.
*
+ *
+ * \todo Test the compatibility between val and mln_value(I) because,
+ * while unmorphing, this type can change...
*/
# include <mln/core/concept/image.hh>
@@ -40,6 +42,7 @@
# include <mln/border/fill.hh>
# include <mln/level/fill_with_value.hh>
+
namespace mln
{
@@ -50,63 +53,136 @@
* single value \p v.
*
* \param[in,out] ima The image whose domain extension is to be filled.
- * \param[in] v The value to assign.
+ * \param[in] val The value to assign.
*
* \pre \p ima has to be initialized.
*
* \todo Optimize with memset if possible.
*/
template <typename I>
- void fill(const Image<I>& ima, const mln_value(I)& v);
+ void fill(const Image<I>& ima, const mln_value(I)& val);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
- namespace impl
+ namespace internal
{
+
+ // Do it.
+
+ template <typename I>
+ void do_fill(I& ima, const mln_value(I)& val); // Entry point.
+
template <typename I>
- void fill_fixed_extension(const Image<I>& ima, const mln_value(I)&
v);
+ void do_fill(mln::trait::image::ext_domain::some,
+ mln::trait::image::ext_value::single,
+ mln::trait::image::ext_domain::none,
+ I& ima, const mln_value(I)& val)
+ {
+ ima.change_extension(val);
}
-# ifndef MLN_INCLUDE_ONLY
+ template <typename I>
+ void do_fill(mln::trait::image::ext_domain::some,
+ mln::trait::image::ext_value::multiple,
+ mln::trait::image::ext_domain::none,
+ I& ima, const mln_value(I)& val)
+ {
+ border::fill(ima, val);
+ ima.change_extension(val);
+ }
template <typename I>
- void fill(const Image<I>& ima, const mln_value(I)& v)
+ void do_fill(mln::trait::image::ext_domain::some,
+ mln::trait::image::ext_value::any,
+ mln::trait::image::ext_domain::some,
+ I& ima, const mln_value(I)& val)
{
- // Case of ext_io::read_only.
- if (mlc_equal(mln_trait_image_ext_io(I),
- mln::trait::image::ext_io::read_only)::value == true)
- return; // No-op.
+ mln::extension::fill(ima.unmorph_(), val);
+ }
- // Case of ext_domain::none.
- if (mlc_equal(mln_trait_image_ext_domain(I),
- mln::trait::image::ext_domain::none)::value == true)
- return; // No-op.
+ template <typename I>
+ void do_fill(mln::trait::image::ext_domain::none,
+ mln::trait::image::ext_value::any,
+ mln::trait::image::ext_domain::any,
+ I& ima, const mln_value(I)& val)
+ {
+ // Oops...
+ }
+
+ template <typename I>
+ void do_fill(I& ima, const mln_value(I)& val)
+ {
+ typedef typename I::delegatee D;
+ do_fill(mln_trait_image_ext_domain(I)(),
+ mln_trait_image_ext_value(I)(),
+ mln_trait_image_ext_domain(D)(),
+ ima, val);
+ }
- // Case of ext_domain::extendable.
- if (mlc_equal(mln_trait_image_ext_domain(I),
- mln::trait::image::ext_domain::extendable)::value == true)
- return mln::border::fill(ima, v);
- // Case of ext_domain::fixed.
- if (mlc_equal(mln_trait_image_ext_domain(I),
- mln::trait::image::ext_domain::fixed)::value == true)
+ // Dispatch.
- // Case of ext_value::single.
- if (mlc_equal(mln_trait_image_ext_value(I),
- mln::trait::image::ext_value::single)::value == true)
- return impl::fill_fixed_extension(const_cast<I&>(exact(ima)), v);
- else
- return mln::level::fill_with_value(const_cast<I&>(exact(ima)), v);
+ template <typename I>
+ void fill_dispatch(mln::trait::image::ext_domain::none,
+ mln::trait::image::ext_io::any,
+ I& ima, const mln_value(I)& val)
+ {
+ // No-op cause no extension domain, no border.
+ }
+ template <typename I>
+ void fill_dispatch(mln::trait::image::ext_domain::some,
+ mln::trait::image::ext_io::read_only,
+ I& ima, const mln_value(I)& val)
+ {
+ // No-op for the extension domain, yet:
+ border::fill(ima, val);
+ }
+
+ template <typename I>
+ void fill_dispatch(mln::trait::image::ext_domain::extendable,
+ mln::trait::image::ext_io::read_write,
+ I& ima, const mln_value(I)& val)
+ {
+ // Just fill the border.
+ border::fill(ima, val);
}
- namespace impl
+ template <typename I>
+ void fill_dispatch(mln::trait::image::ext_domain::some,
+ mln::trait::image::ext_io::read_write,
+ I& ima, const mln_value(I)& val)
{
+ do_fill(ima, val);
+ }
+
template <typename I>
- void fill_fixed_extension(Image<I>& ima_, const mln_value(I)& v)
+ void fill_dispatch(const Image<I>& ima_, const mln_value(I)& val)
{
- I& ima = exact(ima_);
- ima.extension() = v;
+ I& ima = const_cast<I&>(exact(ima_));
+ fill_dispatch(mln_trait_image_ext_domain(I)(),
+ mln_trait_image_ext_io(I)(),
+ ima, val);
}
+
+ } // end of namespace mln::extension::internal
+
+
+ // Facade.
+
+ template <typename I>
+ void fill(const Image<I>& ima, const mln_value(I)& val)
+ {
+ trace::entering("extension::fill");
+
+ mln_precondition(exact(ima).has_data());
+ internal::fill_dispatch(ima, val);
+
+ trace::exiting("extension::fill");
}
# endif // ! MLN_INCLUDE_ONLY