milena r1518: Subdirectory border ready for rereading

URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena ChangeLog: 2007-11-22 Guillaume Duhamel <guillaume.duhamel@lrde.epita.fr> Subdirectory border ready for rereading. * mln/border/all.hh: Update with all headers. * mln/border/mirror.hh: Add 2d version. * mln/border/adjust.hh, * mln/border/duplicate.hh, * mln/border/equalize.hh, * mln/border/fill.hh, * mln/border/find.hh, * mln/border/resize.hh, * mln/border/get.hh: Check typo and tracing. Tests * tests/border/equalize.cc, * tests/border/mirror.cc: New test for these algorithms. * tests/border/Makefile.am: Add previous tests. --- mln/border/adjust.hh | 3 - mln/border/all.hh | 13 ++++-- mln/border/duplicate.hh | 23 ++++++---- mln/border/equalize.hh | 40 ++++++++++++++---- mln/border/fill.hh | 13 +++++- mln/border/find.hh | 10 ++++ mln/border/get.hh | 10 ++++ mln/border/mirror.hh | 101 +++++++++++++++++++++++++++++++++++++++++++++-- mln/border/resize.hh | 2 tests/border/Makefile.am | 4 + tests/border/equalize.cc | 46 +++++++++++++++++++++ tests/border/mirror.cc | 90 +++++++++++++++++++++++++++++++++++++++++ 12 files changed, 328 insertions(+), 27 deletions(-) Index: trunk/milena/tests/border/equalize.cc =================================================================== --- trunk/milena/tests/border/equalize.cc (revision 0) +++ trunk/milena/tests/border/equalize.cc (revision 1518) @@ -0,0 +1,46 @@ +// 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. + +/*! \file tests/border/equalize.cc + * + * \brief Tests on mln::border::equalize. + */ + +#include <mln/core/image2d.hh> +#include <mln/border/get.hh> +#include <mln/border/equalize.hh> + +int main() +{ + using namespace mln; + + image2d<int> ima1(3,3, 36); + image2d<int> ima2(3,3, 42); + border::equalize(ima1, ima2, 51); + mln_assertion(border::get(ima1) == 51); + mln_assertion(border::get(ima2) == 51); +} Index: trunk/milena/tests/border/Makefile.am =================================================================== --- trunk/milena/tests/border/Makefile.am (revision 1517) +++ trunk/milena/tests/border/Makefile.am (revision 1518) @@ -5,16 +5,20 @@ check_PROGRAMS = \ adjust \ duplicate \ + equalize \ fill \ find \ get \ + mirror \ resize adjust_SOURCES = adjust.cc duplicate_SOURCES = duplicate.cc +equalize_SOURCES = equalize.cc fill_SOURCES = fill.cc find_SOURCES = find.cc get_SOURCES = get.cc +mirror_SOURCES = mirror.cc resize_SOURCES = resize.cc TESTS = $(check_PROGRAMS) Index: trunk/milena/tests/border/mirror.cc =================================================================== --- trunk/milena/tests/border/mirror.cc (revision 0) +++ trunk/milena/tests/border/mirror.cc (revision 1518) @@ -0,0 +1,90 @@ +// 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. + +/*! \file tests/border_duplicate/test_border_duplicate_image2d_1.cc + * + * \brief Tests on mln::border::duplicate. + */ + +#include <mln/core/image2d.hh> +#include <mln/debug/iota.hh> +#include <mln/border/mirror.hh> + +using namespace mln; + +int +main (void) +{ + image2d<int> ima(2, 3, 2); + + debug::iota(ima); + border::mirror(ima); + + mln_assertion(ima[ 0] == 1); + mln_assertion(ima[ 1] == 1); + mln_assertion(ima[ 2] == 4); + mln_assertion(ima[ 3] == 5); + mln_assertion(ima[ 4] == 6); + mln_assertion(ima[ 5] == 3); + mln_assertion(ima[ 6] == 3); + mln_assertion(ima[ 7] == 1); + mln_assertion(ima[ 8] == 1); + mln_assertion(ima[ 9] == 1); + mln_assertion(ima[10] == 2); + mln_assertion(ima[11] == 3); + mln_assertion(ima[12] == 3); + mln_assertion(ima[13] == 3); + mln_assertion(ima[14] == 2); + mln_assertion(ima[15] == 1); + mln_assertion(ima[16] == 1); + mln_assertion(ima[17] == 2); + mln_assertion(ima[18] == 3); + mln_assertion(ima[19] == 3); + mln_assertion(ima[20] == 2); + mln_assertion(ima[21] == 5); + mln_assertion(ima[22] == 4); + mln_assertion(ima[23] == 4); + mln_assertion(ima[24] == 5); + mln_assertion(ima[25] == 6); + mln_assertion(ima[26] == 6); + mln_assertion(ima[27] == 5); + mln_assertion(ima[28] == 4); + mln_assertion(ima[29] == 4); + mln_assertion(ima[30] == 4); + mln_assertion(ima[31] == 5); + mln_assertion(ima[32] == 6); + mln_assertion(ima[33] == 6); + mln_assertion(ima[34] == 6); + mln_assertion(ima[35] == 4); + mln_assertion(ima[36] == 4); + mln_assertion(ima[37] == 1); + mln_assertion(ima[38] == 2); + mln_assertion(ima[39] == 3); + mln_assertion(ima[40] == 6); + mln_assertion(ima[41] == 6); +} + Index: trunk/milena/mln/border/resize.hh =================================================================== --- trunk/milena/mln/border/resize.hh (revision 1517) +++ trunk/milena/mln/border/resize.hh (revision 1518) @@ -95,6 +95,7 @@ void resize(const Image<I>& ima_, unsigned thickness) { trace::entering("border::resize"); + mlc_is(mln_trait_image_border(I), trait::image::border::some)::check(); const I& ima = exact(ima_); mln_precondition(ima.has_data()); @@ -106,6 +107,7 @@ ima, thickness); mln_postcondition(border::get(ima) == thickness); + trace::exiting("border::resize"); } Index: trunk/milena/mln/border/fill.hh =================================================================== --- trunk/milena/mln/border/fill.hh (revision 1517) +++ trunk/milena/mln/border/fill.hh (revision 1518) @@ -50,7 +50,7 @@ * * \pre \p ima has to be initialized. * - * \todo Implement it + optimize with memset if possible. + * \todo Optimize with memset if possible. */ template <typename I> void fill(const Image<I>& ima, const mln_value(I)& v); @@ -63,6 +63,8 @@ template <typename I> void fill_size_1_(const I& ima, const mln_value(I)& v) { + trace::entering("border::impl::fill_size_1_"); + typedef mln_point(I) P; typedef mln_point(I) P; typename I::line_piter pl(ima.domain()); @@ -80,11 +82,15 @@ std::memset((void*)&ima[st], *(const int*)(&v), ima.ncells () - st); + + trace::exiting("border::impl::fill_size_1_"); } template <typename I> void fill_size_n_(const I& ima, const mln_value(I)& v) { + trace::entering("border::impl::fill_size_n_"); + typedef mln_point(I) P; typename I::line_piter pl(ima.domain()); std::size_t len_r = ima.bbox().len(P::dim - 1); @@ -99,15 +105,19 @@ } for (std::size_t i = st; i < ima.ncells (); ++i) const_cast<I&>(ima)[i] = v; + + trace::exiting("border::impl::fill_size_n_"); } } + // Facade. template <typename I> void fill(const Image<I>& ima_, const mln_value(I)& v) { trace::entering("border::fill"); + typedef mln_point(I) P; const I& ima = exact(ima_); @@ -119,6 +129,7 @@ impl::fill_size_1_(ima, v); else impl::fill_size_n_(ima, v); + trace::exiting("border::fill"); } Index: trunk/milena/mln/border/all.hh =================================================================== --- trunk/milena/mln/border/all.hh (revision 1517) +++ trunk/milena/mln/border/all.hh (revision 1518) @@ -41,18 +41,25 @@ namespace border { /// Implementation namespace of border namespace. - namespace impl {} + namespace impl { + + /// Generic implementation namespace of border namespace. + namespace generic {} + } } +} +# include <mln/border/adjust.hh> # include <mln/border/duplicate.hh> +# include <mln/border/equalize.hh> # include <mln/border/fill.hh> +# include <mln/border/find.hh> +# include <mln/border/get.hh> # include <mln/border/mirror.hh> # include <mln/border/resize.hh> -# include <mln/border/adjust.hh> -# include <mln/border/equalize.hh> # include <mln/border/thickness.hh> Index: trunk/milena/mln/border/duplicate.hh =================================================================== --- trunk/milena/mln/border/duplicate.hh (revision 1517) +++ trunk/milena/mln/border/duplicate.hh (revision 1518) @@ -52,7 +52,7 @@ * * \pre \p ima has to be initialized. * - * \todo Implement it + optimize with memcpy if possible. + * \todo Optimize with memcpy if possible. */ template <typename I> void duplicate(const Image<I>& ima); @@ -66,7 +66,7 @@ template <typename I> void duplicate_1d_(const I& ima) { - mln_precondition(ima.has_data()); + trace::entering("border::impl::duplicate_1d_"); typedef mln_point(I) P; typename I::line_piter pl(ima.domain()); @@ -79,12 +79,14 @@ std::size_t st = border + len_c - 1; for (std::size_t i = st + 1; i < ima.ncells (); ++i) const_cast<I&>(ima)[i] = ima[st]; + + trace::exiting("border::impl::duplicate_1d_"); } template <typename I> void duplicate_2d_(const I& ima) { - mln_precondition(ima.has_data()); + trace::entering("border::impl::duplicate_2d_"); typedef mln_point(I) P; typename I::line_piter pl(ima.domain()); @@ -117,11 +119,15 @@ for (std::size_t k = 1; k <= border; ++k) for (std::size_t i = st; i < st + real_len_c; ++i) const_cast<I&>(ima)[k * real_len_c + i] = ima[i]; + + trace::exiting("border::impl::duplicate_2d_"); } template <typename I> void duplicate_3d_(const Image<I>& ima_) { + trace::entering("border::impl::duplicate_3d_"); + const I& ima = exact(ima_); mln_precondition(ima.has_data()); @@ -178,9 +184,9 @@ for (std::size_t k = 1; k <= border; ++k) for (std::size_t i = 0; i < face; ++i) const_cast<I&>(ima)[st + k * face + i] = ima[st + i]; - } - + trace::exiting("border::impl::duplicate_3d_"); + } } // end of namespace mln::border::impl @@ -190,13 +196,14 @@ template <typename I> void duplicate(const Image<I>& ima_) { - mlc_is(mln_trait_image_speed(I), trait::image::speed::fastest)::check(); - const I& ima = exact(ima_); - typedef mln_point(I) P; trace::entering("border::duplicate"); mln_precondition(ima.has_data()); + mlc_is(mln_trait_image_speed(I), trait::image::speed::fastest)::check(); + const I& ima = exact(ima_); + typedef mln_point(I) P; + if (!ima.border ()) return; Index: trunk/milena/mln/border/mirror.hh =================================================================== --- trunk/milena/mln/border/mirror.hh (revision 1517) +++ trunk/milena/mln/border/mirror.hh (revision 1518) @@ -51,7 +51,7 @@ * * \pre \p ima has to be initialized. * - * \todo Implement it + optimize with memset if possible. + * \todo Implement 1d and 3d version + optimize with memset if possible. */ template <typename I> void mirror(const Image<I>& ima); @@ -59,15 +59,110 @@ # ifndef MLN_INCLUDE_ONLY + namespace impl + { + + template <typename I> + void mirror_1d_(const I& ima) + { + mln::internal::fixme(); + } + + template <typename I> + void mirror_2d_(const I& ima) + { + trace::entering("border::impl::mirror_2d_"); + + std::size_t border = ima.border (); + std::size_t nbrows = geom::max_row(ima) - geom::min_row(ima); + std::size_t nbcols = geom::max_col(ima) - geom::min_col(ima); + std::size_t real_nbcols = (nbcols + 1) + 2 * border; + std::size_t start = real_nbcols * border + border; + std::size_t s = start; + + // duplicate top left corner + for (std::size_t i = 0; i < border; ++i) + for (std::size_t j = 0; j < border; ++j) + const_cast<I&>(ima)[i * ((nbcols + 1) + 2 * border) + j] = ima[s]; + + // duplicate top left corner + s = start + nbcols; + for (std::size_t i = 0; i < border; ++i) + for (std::size_t j = 1; j <= border; ++j) + const_cast<I&>(ima)[i * ((nbcols + 1) + 2 * border) + (nbcols + border + j)] = ima[s]; + + // duplicate bottom left corner + s = start + (nbrows * real_nbcols); + for (std::size_t i = 1; i <= border; ++i) + for (std::size_t j = 1; j <= border; ++j) + const_cast<I&>(ima)[s - i + (j * (real_nbcols))] = ima[s]; + + // duplicate bottom right corner + s = start + (nbrows * real_nbcols) + nbcols; + for (std::size_t i = 1; i <= border; ++i) + for (std::size_t j = 1; j <= border; ++j) + const_cast<I&>(ima)[s + i + (j * real_nbcols)] = ima[s]; + + // mirror top border + s = start; + for (std::size_t i = 0; i <= nbcols; ++i) + for (std::size_t j = 1; j <= border; ++j) + const_cast<I&>(ima)[s + i - (j * real_nbcols)] = ima[s + i + ((j - 1)* real_nbcols)]; + + // mirror left border + s = start; + for (std::size_t i = 0; i <= nbrows; ++i) + for (std::size_t j = 1; j <= border; ++j) + const_cast<I&>(ima)[s + (i * real_nbcols) - j] = ima[s + (i * real_nbcols) + (j - 1)]; + + // mirror right border + s = start; + for (std::size_t i = 0; i <= nbrows; ++i) + for (std::size_t j = 1; j <= border; ++j) + const_cast<I&>(ima)[s + (i * real_nbcols + nbcols) + j] = ima[s + (i * real_nbcols + nbcols) - (j - 1)]; + + // mirror bottom border + s = start + (nbrows * real_nbcols); + for (std::size_t i = 0; i <= nbcols; ++i) + for (std::size_t j = 1; j <= border; ++j) + const_cast<I&>(ima)[s + i + (j * real_nbcols)] = ima[s + i - ((j - 1)* real_nbcols)]; + + trace::exiting("border::impl::mirror_2d_"); + } + + template <typename I> + void mirror_3d_(const I& ima) + { + mln::internal::fixme(); + } + + + } // end of namespace mln::border::mirror + + template <typename I> void mirror(const Image<I>& ima_) { + trace::entering("border::mirror"); + const I& ima = exact(ima_); + mln_precondition(ima.has_data()); mlc_is(mln_trait_image_speed(I), trait::image::speed::fastest)::check(); - mln_precondition(ima.has_data()); - mln::internal::fixme(); + typedef mln_point(I) P; + + if (!ima.border ()) + return; + + if (P::dim == 1) + impl::mirror_1d_(ima); + if (P::dim == 2) + impl::mirror_2d_(ima); + if (P::dim == 3) + impl::mirror_3d_(ima); + + trace::exiting("border::mirror"); } # endif // ! MLN_INCLUDE_ONLY Index: trunk/milena/mln/border/adjust.hh =================================================================== --- trunk/milena/mln/border/adjust.hh (revision 1517) +++ trunk/milena/mln/border/adjust.hh (revision 1518) @@ -58,13 +58,13 @@ void adjust(const Image<I>& ima, unsigned min_thickness); - # ifndef MLN_INCLUDE_ONLY template <typename I> void adjust(const Image<I>& ima_, unsigned min_thickness) { trace::entering("border::adjust"); + mlc_is(mln_trait_image_border(I), trait::image::border::some)::check(); const I& ima = exact(ima_); mln_precondition(ima.has_data()); @@ -73,6 +73,7 @@ border::resize(ima, min_thickness); mln_postcondition(border::get(ima) >= min_thickness); + trace::exiting("border::adjust"); } Index: trunk/milena/mln/border/equalize.hh =================================================================== --- trunk/milena/mln/border/equalize.hh (revision 1517) +++ trunk/milena/mln/border/equalize.hh (revision 1518) @@ -50,7 +50,8 @@ * \param[in,out] ima2 The second image whose border is to be equalizeed. * \param[in] min_thickness The expected border minimum thickness of both images. * - * \pre \p ima has to be initialized. + * \pre \p ima1 has to be initialized. + * \pre \p ima2 has to be initialized. * * \warning If both image borders already have the same thickness * and if this thickness is larger than \p min_thickness, this @@ -64,18 +65,16 @@ # ifndef MLN_INCLUDE_ONLY + namespace impl + { + template <typename I, typename J> - void equalize(const Image<I>& ima1_, const Image<J>& ima2_, - unsigned min_thickness) + void equalize_(const I& ima1, const J& ima2, unsigned min_thickness) { - trace::entering("border::equalize"); - mlc_is(mln_trait_image_border(I), trait::image::border::some)::check(); - mlc_is(mln_trait_image_border(J), trait::image::border::some)::check(); - const I& ima1 = exact(ima1_); - const J& ima2 = exact(ima2_); - mln_precondition(ima1.has_data() && ima2.has_data()); + trace::entering("border::impl::equalize_"); unsigned b1 = border::get(ima1), b2 = border::get(ima2); + if (! (b1 == b2 && b2 >= min_thickness)) // Something has to be done. { @@ -101,9 +100,32 @@ } } + trace::exiting("border::impl::equalize_"); + } + + } // end of namespace mln::border::impl + + + // Facade + + template <typename I, typename J> + void equalize(const Image<I>& ima1_, const Image<J>& ima2_, + unsigned min_thickness) + { + trace::entering("border::equalize"); + + mlc_is(mln_trait_image_border(I), trait::image::border::some)::check(); + mlc_is(mln_trait_image_border(J), trait::image::border::some)::check(); + const I& ima1 = exact(ima1_); + const J& ima2 = exact(ima2_); + mln_precondition(ima1.has_data() && ima2.has_data()); + + impl::equalize_(ima1, ima2, min_thickness); + mln_postcondition(border::get(ima1) == border::get(ima2) && border::get(ima1) >= min_thickness && border::get(ima2) >= min_thickness); + trace::exiting("border::equalize"); } Index: trunk/milena/mln/border/get.hh =================================================================== --- trunk/milena/mln/border/get.hh (revision 1517) +++ trunk/milena/mln/border/get.hh (revision 1518) @@ -46,6 +46,9 @@ * * \param[in] ima The image. * \result The border thickness (0 if there is no border). + * + * \pre \p ima has to be initialized. + * */ template <typename I> unsigned get(const Image<I>& ima); @@ -86,9 +89,14 @@ template <typename I> unsigned get(const Image<I>& ima) { + trace::entering("border::get"); + mln_precondition(exact(ima).has_data()); - return border::impl::get_(mln_trait_image_border(I)(), mln_trait_image_category(I)(), + unsigned res = border::impl::get_(mln_trait_image_border(I)(), mln_trait_image_category(I)(), exact(ima)); + + trace::exiting("border::get"); + return res; } # endif // ! MLN_INCLUDE_ONLY Index: trunk/milena/mln/border/find.hh =================================================================== --- trunk/milena/mln/border/find.hh (revision 1517) +++ trunk/milena/mln/border/find.hh (revision 1518) @@ -46,6 +46,9 @@ * * \param[in] ima The image. * \result The border thickness (0 if there is no border). + * + * \pre \p ima has to be initialized. + * */ template <typename I> unsigned find(const Image<I>& ima); @@ -88,8 +91,13 @@ template <typename I> unsigned find(const Image<I>& ima) { + trace::entering("border::find"); + mln_precondition(exact(ima).has_data()); - return border::impl::find_(mln_trait_image_speed(I)(), exact(ima)); + unsigned res = border::impl::find_(mln_trait_image_speed(I)(), exact(ima)); + + trace::exiting("border::find"); + return res; } # endif // ! MLN_INCLUDE_ONLY
participants (1)
-
Guillaume Duhamel