
URL: https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena ChangeLog: 2008-10-21 Matthieu Garrigues <garrigues@lrde.epita.fr> Add diagonal2d browsings. * mln/canvas/browsing/backdiagonal2d.hh: New. * mln/canvas/browsing/diagonal2d.hh: New. * tests/canvas/browsing/backdiagonal2d.cc: New. * tests/canvas/browsing/diagonal2d.cc: New. Use it in erosion. * mln/morpho/erosion.spe.hh: Add diagonal versions of erosion: (erosion_diagonal) New, (erosion_diagonal_fastest) New, (erosion_backdiagonal) New, (erosion_backdiagonal_fastest) New. * tests/morpho/erosion.cc: Some tests on erosion with win::diag2d and win::backdiag2d. --- mln/canvas/browsing/backdiagonal2d.hh | 174 +++++++++++ mln/canvas/browsing/diagonal2d.hh | 172 +++++++++++ mln/morpho/erosion.spe.hh | 482 +++++++++++++++++++++++++++++++- tests/canvas/browsing/backdiagonal2d.cc | 97 ++++++ tests/canvas/browsing/diagonal2d.cc | 97 ++++++ tests/morpho/erosion.cc | 88 +++++ 6 files changed, 1103 insertions(+), 7 deletions(-) Index: branches/cleanup-2008/milena/tests/morpho/erosion.cc =================================================================== --- branches/cleanup-2008/milena/tests/morpho/erosion.cc (revision 2614) +++ branches/cleanup-2008/milena/tests/morpho/erosion.cc (revision 2615) @@ -31,8 +31,7 @@ */ #include <mln/core/image/image2d.hh> -#include <mln/win/rectangle2d.hh> -#include <mln/win/octagon2d.hh> +#include <mln/win/all.hh> #include <mln/debug/iota.hh> @@ -51,9 +50,9 @@ using namespace mln; using value::int_u8; - unsigned - l_oct = 11, L_oct = 6 * l_oct + 1, - l_rec = 29, L_rec = 2 * l_rec + 1; +// unsigned +// l_oct = 11, L_oct = 6 * l_oct + 1, +// l_rec = 29, L_rec = 2 * l_rec + 1; // l_ // oct rec err @@ -75,7 +74,9 @@ win::rectangle2d rec(21, 21); win::hline2d hline(31); win::vline2d vline(31); - win::octagon2d oct(19); + win::diag2d diag2d(31); + win::backdiag2d backdiag2d(31); + win::octagon2d oct(6 * 3 + 1); image2d<int_u8> out; image2d<int_u8> ref; // trace::quiet = false; @@ -194,6 +195,81 @@ std::cout << " " << (test ? "OK" : "KO!!!") << std::endl; } + + //Diag2d + std::cout << "-------------------------- Diag2d: "<< std::endl; + { + t.start(); + ref = morpho::impl::generic::erosion_on_function(lena, diag2d); + std::cout << "generic on diag2d: " << t << std::endl; + } + + { + t.start(); + out = morpho::erosion(lena, diag2d); + std::cout << "dispach on diag2d : " << t << std::endl; + bool test = out == ref; + mln_assertion(test); + std::cout << " " << (test ? "OK" : "KO!!!") << std::endl; + } + + + { + t.start(); + out = morpho::impl::erosion_arbitrary_2d_fastest(lena, diag2d); + std::cout << "erosion_arbitrary_2d_fastest on diag2d: " << t << std::endl; + bool test = out == ref; + mln_assertion(test); + std::cout << " " << (test ? "OK" : "KO!!!") << std::endl; + } + + + { + t.start(); + out = morpho::impl::erosion_arbitrary_2d(lena, diag2d); + std::cout << "erosion_arbitrary_2d on diag2d: " << t << std::endl; + bool test = out == ref; + mln_assertion(test); + std::cout << " " << (test ? "OK" : "KO!!!") << std::endl; + } + + //Backdiag2d + std::cout << "-------------------------- Backdiag2d: "<< std::endl; + { + t.start(); + ref = morpho::impl::generic::erosion_on_function(lena, backdiag2d); + std::cout << "generic on backdiag2d: " << t << std::endl; + } + + { + t.start(); + out = morpho::erosion(lena, backdiag2d); + std::cout << "dispach on backdiag2d : " << t << std::endl; + bool test = out == ref; + mln_assertion(test); + std::cout << " " << (test ? "OK" : "KO!!!") << std::endl; + } + + + { + t.start(); + out = morpho::impl::erosion_arbitrary_2d_fastest(lena, backdiag2d); + std::cout << "erosion_arbitrary_2d_fastest on backdiag2d: " << t << std::endl; + bool test = out == ref; + mln_assertion(test); + std::cout << " " << (test ? "OK" : "KO!!!") << std::endl; + } + + + { + t.start(); + out = morpho::impl::erosion_arbitrary_2d(lena, backdiag2d); + std::cout << "erosion_arbitrary_2d on backdiag2d: " << t << std::endl; + bool test = out == ref; + mln_assertion(test); + std::cout << " " << (test ? "OK" : "KO!!!") << std::endl; + } + std::cout << "-------------------------- Octagon: " << std::endl; // Octagon Index: branches/cleanup-2008/milena/tests/canvas/browsing/diagonal2d.cc =================================================================== --- branches/cleanup-2008/milena/tests/canvas/browsing/diagonal2d.cc (revision 0) +++ branches/cleanup-2008/milena/tests/canvas/browsing/diagonal2d.cc (revision 2615) @@ -0,0 +1,97 @@ +// 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 +// 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/canvas/browsing/diagonal2d.cc + * + * \brief Tests on mln::canvas::browsing::diagonal2d. + */ + +#include <mln/core/image/image2d.hh> +#include <mln/canvas/browsing/diagonal2d.hh> +#include <mln/fun/p2v/iota.hh> +#include <mln/debug/println.hh> + +template <typename I_, typename F> +struct assign_browsing_functor +{ + typedef I_ I; + enum { dim = I::site::dim }; + + typedef assign_browsing_functor<I, F> self; + typedef mln_deduce(I, psite, delta) dpsite; + typedef void (assign_browsing_functor<I,F>::*move_fun)(); + + I input; + F f; + + assign_browsing_functor(I& input, F f = F()) + : input(input), + f(f) + { + } + + mln_psite(I) p; + + void init() { std::cout << "init" << std::endl; } + void final() { std::cout << "final" << std::endl; } + + void next_() + { + input(p) = f(p); + } + void next() { std::cout << "next : " << p << std::endl; next_(); } + void init_diag() { std::cout << "init_diag: " << p << std::endl; } +}; + +namespace mln +{ + + template <typename I, typename F, typename B> + void my_test(Image<I>& ima_, + const Function_p2v<F>& f_, + const Browsing<B>& browse_) + { + I& ima = exact(ima_); + const F& f = exact(f_); + const B& browse = exact(browse_); + + assign_browsing_functor<I, F> fun(ima, f); + browse(fun); + } + +} + + +int main() +{ + using namespace mln; + image2d<unsigned> ima2(10, 10); + + std::cout << ima2.bbox() << std::endl; + my_test(ima2, fun::p2v::iota, canvas::browsing::diagonal2d); + debug::println(ima2); +} Index: branches/cleanup-2008/milena/tests/canvas/browsing/backdiagonal2d.cc =================================================================== --- branches/cleanup-2008/milena/tests/canvas/browsing/backdiagonal2d.cc (revision 0) +++ branches/cleanup-2008/milena/tests/canvas/browsing/backdiagonal2d.cc (revision 2615) @@ -0,0 +1,97 @@ +// 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 +// 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/canvas/browsing/backdiagonal2d.cc + * + * \brief Tests on mln::canvas::browsing::backdiagonal2d. + */ + +#include <mln/core/image/image2d.hh> +#include <mln/canvas/browsing/backdiagonal2d.hh> +#include <mln/fun/p2v/iota.hh> +#include <mln/debug/println.hh> + +template <typename I_, typename F> +struct assign_browsing_functor +{ + typedef I_ I; + enum { dim = I::site::dim }; + + typedef assign_browsing_functor<I, F> self; + typedef mln_deduce(I, psite, delta) dpsite; + typedef void (assign_browsing_functor<I,F>::*move_fun)(); + + I input; + F f; + + assign_browsing_functor(I& input, F f = F()) + : input(input), + f(f) + { + } + + mln_psite(I) p; + + void init() { std::cout << "init" << std::endl; } + void final() { std::cout << "final" << std::endl; } + + void next_() + { + input(p) = f(p); + } + void next() { std::cout << "next : " << p << std::endl; next_(); } + void init_diag() { std::cout << "init_diag: " << p << std::endl; } +}; + +namespace mln +{ + + template <typename I, typename F, typename B> + void my_test(Image<I>& ima_, + const Function_p2v<F>& f_, + const Browsing<B>& browse_) + { + I& ima = exact(ima_); + const F& f = exact(f_); + const B& browse = exact(browse_); + + assign_browsing_functor<I, F> fun(ima, f); + browse(fun); + } + +} + + +int main() +{ + using namespace mln; + image2d<unsigned> ima2(10, 10); + + std::cout << ima2.bbox() << std::endl; + my_test(ima2, fun::p2v::iota, canvas::browsing::backdiagonal2d); + debug::println(ima2); +} Index: branches/cleanup-2008/milena/mln/morpho/erosion.spe.hh =================================================================== --- branches/cleanup-2008/milena/mln/morpho/erosion.spe.hh (revision 2614) +++ branches/cleanup-2008/milena/mln/morpho/erosion.spe.hh (revision 2615) @@ -47,6 +47,8 @@ # include <mln/canvas/browsing/snake_fwd.hh> # include <mln/canvas/browsing/snake_generic.hh> # include <mln/canvas/browsing/directional.hh> +# include <mln/canvas/browsing/diagonal2d.hh> +# include <mln/canvas/browsing/backdiagonal2d.hh> /*! \file mln/morpho/erosion.spe.hh @@ -783,6 +785,7 @@ }; + template <typename I, typename W> inline mln_concrete(I) @@ -799,6 +802,337 @@ return f.output; } + + // Diagonal2d non fastest. + template <typename I_, typename W> + struct erosion_diagonal2d_functor + { + typedef I_ I; + typedef mln_deduce(I, psite, delta) dpsite; + + const I& input; + const W& win; + mln_concrete(I) output; + accu::min_h<mln_value(I)> min; + + mln_psite(I) p; + enum { dim = I::site::dim }; + unsigned dir; + + window2d win_left, win_right; + + mln_qiter(window2d) q_l, q_r; + + erosion_diagonal2d_functor(const I& input, const W& win) + : input(input), + win(win), + min(), + dir(dir), + win_left(win::shift(win, dpsite(1, -1)) - win), + win_right(win - win::shift(win, dpsite(1, -1))), + q_l(win_left, p), + q_r(win_right, p) + { + } + + void init() + { + // FIXME: border::adjust(input, win.delta()); + extension::fill(input, mln_max(mln_value(I))); + initialize(output, input); + } + + void next() + { + for_all(q_l) + min.untake(input(q_l)); + for_all(q_r) + min.take(input(q_r)); + output(p) = min; + } + + + void init_diag() + { + min.init(); + p = p - dpsite(-1, 1); + mln_qiter(W) q(win, p); + for_all(q) + min.take(input(q)); + p = p + dpsite(-1, 1); + } + + void final() + { + } + + }; + + // Backdiagonal2d non fastest. + template <typename I, typename W> + inline + mln_concrete(I) + erosion_diagonal2d(const Image<I>& input, const Window<W>& win) + { + trace::entering("morpho::impl:erosion_diagonal2d"); + + typedef erosion_diagonal2d_functor<I, W> F; + F f(exact(input), exact(win)); + canvas::browsing::diagonal2d(f); + + trace::exiting("morpho::impl:erosion_diagonal2d"); + + return f.output; + } + + + + template <typename I_, typename W> + struct erosion_backdiagonal2d_functor + { + typedef I_ I; + typedef mln_deduce(I, psite, delta) dpsite; + + const I& input; + const W& win; + mln_concrete(I) output; + accu::min_h<mln_value(I)> min; + + mln_psite(I) p; + enum { dim = I::site::dim }; + unsigned dir; + + window2d win_left, win_right; + + mln_qiter(window2d) q_l, q_r; + + erosion_backdiagonal2d_functor(const I& input, const W& win) + : input(input), + win(win), + min(), + dir(dir), + win_left(win::shift(win, dpsite(-1, -1)) - win), + win_right(win - win::shift(win, dpsite(-1, -1))), + q_l(win_left, p), + q_r(win_right, p) + { + } + + void init() + { + // FIXME: border::adjust(input, win.delta()); + extension::fill(input, mln_max(mln_value(I))); + initialize(output, input); + } + + void next() + { + for_all(q_l) + min.untake(input(q_l)); + for_all(q_r) + min.take(input(q_r)); + output(p) = min; + } + + + void init_diag() + { + min.init(); + p = p - dpsite(1, 1); + mln_qiter(W) q(win, p); + for_all(q) + min.take(input(q)); + p = p + dpsite(1, 1); + } + + void final() + { + } + + }; + + template <typename I, typename W> + inline + mln_concrete(I) + erosion_backdiagonal2d(const Image<I>& input, const Window<W>& win) + { + trace::entering("morpho::impl:erosion_backdiagonal2d"); + + typedef erosion_backdiagonal2d_functor<I, W> F; + F f(exact(input), exact(win)); + canvas::browsing::backdiagonal2d(f); + + trace::exiting("morpho::impl:erosion_backdiagonal2d"); + + return f.output; + } + + + + // Diagonal2d fastest. + template <typename I_, typename W> + struct erosion_diagonal2d_fastest_functor + { + typedef I_ I; + typedef mln_deduce(I, psite, delta) dpsite; + + const I& input; + const W& win; + mln_concrete(I) output; + accu::min_h<mln_value(I)> min; + + mln_psite(I) p; + enum { dim = I::site::dim }; + unsigned dir; + + window2d win_left, win_right; + + mln_qixter(const I, window2d) q_l, q_r; + + erosion_diagonal2d_fastest_functor(const I& input, const W& win) + : input(input), + win(win), + min(), + dir(dir), + win_left(win::shift(win, dpsite(1, -1)) - win), + win_right(win - win::shift(win, dpsite(1, -1))), + q_l(input, win_left, p), + q_r(input, win_right, p) + { + } + + void init() + { + // FIXME: border::adjust(input, win.delta()); + extension::fill(input, mln_max(mln_value(I))); + initialize(output, input); + } + + void next() + { + for_all(q_l) + min.untake(q_l.val()); + for_all(q_r) + min.take(q_r.val()); + output(p) = min; + } + + + void init_diag() + { + min.init(); + p = p - dpsite(-1, 1); + mln_qixter(const I, W) q(input, win, p); + for_all(q) + min.take(q.val()); + p = p + dpsite(-1, 1); + } + + void final() + { + } + + }; + + template <typename I, typename W> + inline + mln_concrete(I) + erosion_diagonal2d_fastest(const Image<I>& input, const Window<W>& win) + { + trace::entering("morpho::impl:erosion_diagonal2d_fastest"); + + typedef erosion_diagonal2d_fastest_functor<I, W> F; + F f(exact(input), exact(win)); + canvas::browsing::diagonal2d(f); + + trace::exiting("morpho::impl:erosion_diagonal2d_fastest"); + + return f.output; + } + + + + // Backdiagonal2d fastest. + template <typename I_, typename W> + struct erosion_backdiagonal2d_fastest_functor + { + typedef I_ I; + typedef mln_deduce(I, psite, delta) dpsite; + + const I& input; + const W& win; + mln_concrete(I) output; + accu::min_h<mln_value(I)> min; + + mln_psite(I) p; + enum { dim = I::site::dim }; + unsigned dir; + + window2d win_left, win_right; + + mln_qixter(const I, window2d) q_l, q_r; + + erosion_backdiagonal2d_fastest_functor(const I& input, const W& win) + : input(input), + win(win), + min(), + dir(dir), + win_left(win::shift(win, dpsite(-1, -1)) - win), + win_right(win - win::shift(win, dpsite(-1, -1))), + q_l(input, win_left, p), + q_r(input, win_right, p) + { + } + + void init() + { + // FIXME: border::adjust(input, win.delta()); + extension::fill(input, mln_max(mln_value(I))); + initialize(output, input); + } + + void next() + { + for_all(q_l) + min.untake(q_l.val()); + for_all(q_r) + min.take(q_r.val()); + output(p) = min; + } + + + void init_diag() + { + min.init(); + p = p - dpsite(1, 1); + mln_qixter(const I, W) q(input, win, p); + for_all(q) + min.take(q.val()); + p = p + dpsite(1, 1); + } + + void final() + { + } + + }; + + template <typename I, typename W> + inline + mln_concrete(I) + erosion_backdiagonal2d_fastest(const Image<I>& input, const Window<W>& win) + { + trace::entering("morpho::impl:erosion_backdiagonal2d_fastest"); + + typedef erosion_backdiagonal2d_fastest_functor<I, W> F; + F f(exact(input), exact(win)); + canvas::browsing::backdiagonal2d(f); + + trace::exiting("morpho::impl:erosion_backdiagonal2d_fastest"); + + return f.output; + } + } // end of namespace mln::morpho::impl @@ -868,7 +1202,7 @@ template <typename I, typename W> bool - erosion_chooses_arbitrary(const I& input, const W& win) + erosion_chooses_arbitrary(const I&, const W& win) { return win.size() >= 10 // size is not too small @@ -942,6 +1276,64 @@ trace::exiting("morpho::erosion_dispatch_for_directional"); } + + // dispatch for diagonal2d w.r.t. speed + + template <typename I, typename W> + mln_concrete(I) + erosion_dispatch_for_diagonal2d(trait::image::speed::fastest, + const I& input, const W& win) + { + return impl::erosion_diagonal2d_fastest(input, win); + } + + template <typename I, typename W> + mln_concrete(I) + erosion_dispatch_for_diagonal2d(trait::image::speed::any, + const I& input, const W& win) + { + return impl::erosion_diagonal2d(input, win); + } + + template <typename I, typename W> + mln_concrete(I) + erosion_dispatch_for_diagonal2d(const I& input, const W& win) + { + trace::entering("morpho::erosion_dispatch_for_diagonal2d"); + return erosion_dispatch_for_diagonal2d(mln_trait_image_speed(I)(), + input, win); + trace::exiting("morpho::erosion_dispatch_for_diagonal2d"); + } + + + // dispatch for backdiagonal2d w.r.t. speed + + template <typename I, typename W> + mln_concrete(I) + erosion_dispatch_for_backdiagonal2d(trait::image::speed::fastest, + const I& input, const W& win) + { + return impl::erosion_backdiagonal2d_fastest(input, win); + } + + template <typename I, typename W> + mln_concrete(I) + erosion_dispatch_for_backdiagonal2d(trait::image::speed::any, + const I& input, const W& win) + { + return impl::erosion_backdiagonal2d(input, win); + } + + template <typename I, typename W> + mln_concrete(I) + erosion_dispatch_for_backdiagonal2d(const I& input, const W& win) + { + trace::entering("morpho::erosion_dispatch_for_backdiagonal2d"); + return erosion_dispatch_for_backdiagonal2d(mln_trait_image_speed(I)(), + input, win); + trace::exiting("morpho::erosion_dispatch_for_backdiagonal2d"); + } + // dispatch w.r.t. win template <typename I, typename W> @@ -1068,6 +1460,94 @@ /// \} + /// Handling win::diag2d. + /// \{ + + template <typename I> + mln_concrete(I) + erosion_dispatch_wrt_win(metal::true_, + const I& input, const win::diag2d& win) + { + return erosion_dispatch_for_diagonal2d(input, win); + } + + template <typename I> + mln_concrete(I) + erosion_dispatch_wrt_win(metal::false_, + const I& input, const win::diag2d& win) + { + return erosion_dispatch_for_generic(input, win); + } + + template <typename I> + mln_concrete(I) + erosion_dispatch_wrt_win(const I& input, const win::diag2d& win) + { + if (win.size() == 1) + return clone(input); + else if (win.size() == 3) + return erosion_dispatch_for_generic(input, win); + else + { + typedef mlc_is_not(mln_trait_image_kind(I), + mln::trait::image::kind::logic) test_not_logic; + typedef mlc_is_a(mln_pset(I), Box) test_box; + typedef mlc_equal(mln_trait_image_quant(I), + mln::trait::image::quant::low) test_lowq; + typedef mlc_and(test_not_logic, test_box) temp; + typedef mlc_and(temp, test_lowq) tests; + return erosion_dispatch_wrt_win(typename tests::eval (), + input, win); + } + } + + /// \} + + + /// Handling win::backdiag2d. + /// \{ + + template <typename I> + mln_concrete(I) + erosion_dispatch_wrt_win(metal::true_, + const I& input, const win::backdiag2d& win) + { + return erosion_dispatch_for_backdiagonal2d(input, win); + } + + template <typename I> + mln_concrete(I) + erosion_dispatch_wrt_win(metal::false_, + const I& input, const win::backdiag2d& win) + { + return erosion_dispatch_for_generic(input, win); + } + + template <typename I> + mln_concrete(I) + erosion_dispatch_wrt_win(const I& input, const win::backdiag2d& win) + { + if (win.size() == 1) + return clone(input); + else if (win.size() == 3) + return erosion_dispatch_for_generic(input, win); + else + { + typedef mlc_is_not(mln_trait_image_kind(I), + mln::trait::image::kind::logic) test_not_logic; + typedef mlc_is_a(mln_pset(I), Box) test_box; + typedef mlc_equal(mln_trait_image_quant(I), + mln::trait::image::quant::low) test_lowq; + typedef mlc_and(test_not_logic, test_box) temp; + typedef mlc_and(temp, test_lowq) tests; + return erosion_dispatch_wrt_win(typename tests::eval (), + input, win); + } + } + + /// \} + + // The dispatch entry point. template <typename I, typename W> Index: branches/cleanup-2008/milena/mln/canvas/browsing/diagonal2d.hh =================================================================== --- branches/cleanup-2008/milena/mln/canvas/browsing/diagonal2d.hh (revision 0) +++ branches/cleanup-2008/milena/mln/canvas/browsing/diagonal2d.hh (revision 2615) @@ -0,0 +1,172 @@ +// Copyright (C) 2007 EPITA Research and Development Laboratory +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +#ifndef MLN_CANVAS_BROWSING_DIAGONAL2D_HH +# define MLN_CANVAS_BROWSING_DIAGONAL2D_HH + +/*! \file mln/canvas/browsing/diagonal2d.hh + * + * \brief Diagonal2d browsing of an image. + */ + +# include <mln/core/concept/browsing.hh> +# include <mln/core/concept/image.hh> + +namespace mln +{ + + namespace canvas + { + + namespace browsing + { + + /*! + * \brief Browsing in a certain direction. + * + * This canvas browse all the point of an image 'input' of type + * 'I' and of dimension 'dim' in the direction 'dir'. + * + * The functor should provide (In addition to 'input', 'I', + * 'dim' and 'dir') three methods : + * + * - init() : Will be called at the beginning. + * - next() : Will be called at each point 'p' (also provided by + * the fonctor). + * - final(): Will be called at the end. + * + * F shall features : \n + * { \n + * --- as types: \n + * I; \n + * --- as attributes: \n + * dim; \n + * dir; // and test dir < dim \n + * input; \n + * p; \n + * --- as methods: \n + * void init(); \n + * void next(); \n + * void final(); \n + * } \n + * + * Example : \n + * + * | 1 3 6 + * | 2 5 8 + * | 4 7 9 + * L------> + * + */ + struct diagonal2d_t : public Browsing< diagonal2d_t > + { + template <typename F> + void operator()(F& f) const; + } + + diagonal2d; + +# ifndef MLN_INCLUDE_ONLY + + template <typename F> + inline + void + diagonal2d_t::operator()(F& f) const + { + trace::entering("canvas::browsing::diagonal2d"); + + typedef typename F::I I; + typedef mln_deduce(I, psite, delta) dpsite; + typedef mln_psite(I) psite; + + // Directions + dpsite dp_first(1, 0); + dpsite dp_second(0, 1); + dpsite dp_diag(-1, 1); + + mln_deduce(I, psite, delta) diag; + + psite + pmin = f.input.domain().pmin(), + pmax = f.input.domain().pmax(); + + f.p = pmin; + + trace::entering("canvas::browsing::diagonal2d::init"); + f.init(); + trace::exiting("canvas::browsing::diagonal2d::init"); + + + while (f.input.domain().has(f.p)) + { + psite start_diag = f.p; + // Browse one diag. + f.init_diag(); + while (f.input.domain().has(f.p)) + { + f.next(); + f.p = f.p + dp_diag; + } + + // Goto next diag start. + f.p = start_diag + dp_first; + } + f.p = f.p - dp_first; + + f.p = f.p + dp_second; + while (f.input.domain().has(f.p)) + { + psite start_diag = f.p; + + // Browse one diag. + f.init_diag(); + while (f.input.domain().has(f.p)) + { + f.next(); + f.p = f.p + dp_diag; + } + f.p = f.p - dp_diag; + + // Goto next diag start. + f.p = start_diag + dp_second; + } + + trace::entering("canvas::browsing::diagonal2d::final"); + f.final(); + trace::exiting("canvas::browsing::diagonal2d::final"); + trace::exiting("canvas::browsing::diagonal2d"); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::canvas::browsing + + } // end of namespace mln::canvas + +} // end of namespace mln + +#endif // ! MLN_CANVAS_BROWSING_DIAGONAL2D_HH Index: branches/cleanup-2008/milena/mln/canvas/browsing/backdiagonal2d.hh =================================================================== --- branches/cleanup-2008/milena/mln/canvas/browsing/backdiagonal2d.hh (revision 0) +++ branches/cleanup-2008/milena/mln/canvas/browsing/backdiagonal2d.hh (revision 2615) @@ -0,0 +1,174 @@ +// Copyright (C) 2007 EPITA Research and Development Laboratory +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +#ifndef MLN_CANVAS_BROWSING_BACKDIAGONAL2D_HH +# define MLN_CANVAS_BROWSING_BACKDIAGONAL2D_HH + +/*! \file mln/canvas/browsing/backdiagonal2d.hh + * + * \brief Backdiagonal2d browsing of an image. + */ + +# include <mln/core/concept/browsing.hh> +# include <mln/core/concept/image.hh> + +namespace mln +{ + + namespace canvas + { + + namespace browsing + { + + /*! + * \brief Browsing in a certain direction. + * + * This canvas browse all the point of an image 'input' of type + * 'I' and of dimension 'dim' in the direction 'dir'. + * + * The functor should provide (In addition to 'input', 'I', + * 'dim' and 'dir') three methods : + * + * - init() : Will be called at the beginning. + * - next() : Will be called at each point 'p' (also provided by + * the fonctor). + * - final(): Will be called at the end. + * + * F shall features : \n + * { \n + * --- as types: \n + * I; \n + * --- as attributes: \n + * dim; \n + * dir; // and test dir < dim \n + * input; \n + * p; \n + * --- as methods: \n + * void init(); \n + * void next(); \n + * void final(); \n + * } \n + * + * Example : \n + * + * -------> + * | 4 7 9 + * | 2 5 8 + * | 1 3 6 + * + */ + struct backdiagonal2d_t : public Browsing< backdiagonal2d_t > + { + template <typename F> + void operator()(F& f) const; + } + + backdiagonal2d; + +# ifndef MLN_INCLUDE_ONLY + + template <typename F> + inline + void + backdiagonal2d_t::operator()(F& f) const + { + trace::entering("canvas::browsing::backdiagonal2d"); + + typedef typename F::I I; + typedef mln_deduce(I, psite, delta) dpsite; + typedef mln_psite(I) psite; + + // Directions + dpsite dp_first(-1, 0); + dpsite dp_second(0, 1); + dpsite dp_diag(1, 1); + + mln_deduce(I, psite, delta) diag; + + psite + pmin = f.input.domain().pmin(), + pmax = f.input.domain().pmax(); + + // Start at the bottom left corner. + f.p[0] = pmax[0]; + f.p[1] = pmin[1]; + + trace::entering("canvas::browsing::backdiagonal2d::init"); + f.init(); + trace::exiting("canvas::browsing::backdiagonal2d::init"); + + + while (f.input.domain().has(f.p)) + { + psite start_diag = f.p; + // Browse one diag. + f.init_diag(); + while (f.input.domain().has(f.p)) + { + f.next(); + f.p = f.p + dp_diag; + } + + // Goto next diag start. + f.p = start_diag + dp_first; + } + f.p = f.p - dp_first; + + f.p = f.p + dp_second; + while (f.input.domain().has(f.p)) + { + psite start_diag = f.p; + + // Browse one diag. + f.init_diag(); + while (f.input.domain().has(f.p)) + { + f.next(); + f.p = f.p + dp_diag; + } + f.p = f.p - dp_diag; + + // Goto next diag start. + f.p = start_diag + dp_second; + } + + trace::entering("canvas::browsing::backdiagonal2d::final"); + f.final(); + trace::exiting("canvas::browsing::backdiagonal2d::final"); + trace::exiting("canvas::browsing::backdiagonal2d"); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::canvas::browsing + + } // end of namespace mln::canvas + +} // end of namespace mln + +#endif // ! MLN_CANVAS_BROWSING_BACKDIAGONAL2D_HH