
https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Rename the methods of fastest images. * mln/core/internal/check/image_fastest.hh (offset_at, offset, point_at_offset: Rename as... (index_of_point, delta_index, point_at_index): ...these. (operator[], ncells): Rename as... (element, nelements): ...these. (size_t): Replace by... (unsigned): ...this to handle indices. * mln/core/image2d.hh: Likewise. (super_): New. (nrows, ncols): New. Layout. * mln/level/paste.spe.hh: Update with new properties. * mln/level/paste.hh: Likewise. * mln/border/get.hh: Likewise. * mln/border/resize.hh: Revamp. * tests/core/image2d.cc: Update. Make tests silent. mln/border/get.hh | 9 + mln/border/resize.hh | 78 +++++++++++++--- mln/core/image2d.hh | 151 ++++++++++++++++++++----------- mln/core/internal/check/image_fastest.hh | 24 ++-- mln/level/paste.hh | 6 - mln/level/paste.spe.hh | 12 +- tests/core/image2d.cc | 18 ++- 7 files changed, 202 insertions(+), 96 deletions(-) Index: tests/core/image2d.cc --- tests/core/image2d.cc (revision 2086) +++ tests/core/image2d.cc (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 @@ -45,18 +45,22 @@ const unsigned nrows = 1; const unsigned ncols = 66; const unsigned border = 4; + const unsigned new_border = 3; image2d<int> f(nrows, ncols, border); + mln_assertion(f.nrows() == nrows); + mln_assertion(f.ncols() == ncols); + { - std::cout << f.id_() << std::endl; + const void* f_id = f.id_(); image2d<int> g; - std::cout << g.id_() << std::endl; + mln_assertion(g.id_() == 0); g = f; - // border::resize (g, 2); - std::cout << g.id_() << std::endl; + border::resize(g, new_border); + mln_assertion(g.id_() == f_id); } - mln_assertion(f.npoints() == geom::nrows(f) * geom::ncols(f)); - mln_assertion(f.ncells() == (nrows + 2 * border) * (ncols + 2 * border)); + mln_assertion(f.nsites() == geom::nrows(f) * geom::ncols(f)); + mln_assertion(f.nelements() == (nrows + 2 * new_border) * (ncols + 2 * new_border)); } Index: mln/core/internal/check/image_fastest.hh --- mln/core/internal/check/image_fastest.hh (revision 2086) +++ mln/core/internal/check/image_fastest.hh (working copy) @@ -64,8 +64,8 @@ * \post p == point_at_offset(result) */ template <typename P> - std::size_t - offset_at(const P& p) const; + unsigned + index_of_point(const P& p) const; protected: image_fastest_(); @@ -93,9 +93,9 @@ typedef mln_fwd_pixter(E) fwd_pixter; typedef mln_bkd_pixter(E) bkd_pixter; - int (E::*m1)(const dpsite&) const = & E::offset; + int (E::*m1)(const dpsite&) const = & E::delta_index; m1 = 0; - site (E::*m2)(unsigned) const = & E::point_at_offset; + site (E::*m2)(unsigned) const = & E::point_at_index; m2 = 0; unsigned (E::*m3)() const = & E::border; m3 = 0; @@ -110,12 +110,12 @@ typedef mln_rvalue(E) rvalue; typedef mln_lvalue(E) lvalue; - rvalue (E::*m6)(unsigned) const = & E::operator[]; + rvalue (E::*m6)(unsigned) const = & E::element; m6 = 0; - lvalue (E::*m7)(unsigned) = & E::operator[]; + lvalue (E::*m7)(unsigned) = & E::element; m7 = 0; - std::size_t (E::*m8)() const = & E::ncells; + unsigned (E::*m8)() const = & E::nelements; m8 = 0; // FIXME: how to check that qixter are defined when W is unknown! @@ -124,16 +124,16 @@ template <typename E, typename B> template <typename P> inline - std::size_t - image_fastest_<E,B>::offset_at(const P& p) const + unsigned + image_fastest_<E,B>::index_of_point(const P& p) const { const E* this_ = & internal::force_exact<E>(*this); mln_precondition(this_->has_data()); mln_precondition(this_->has(p)); - unsigned o = & this_->operator()(p) - this_->buffer(); - mln_postcondition(p == this_->point_at_offset(o)); - return o; + unsigned i = & this_->operator()(p) - this_->buffer(); + mln_postcondition(p == this_->point_at_index(i)); + return i; } # endif // ! MLN_INCLUDE_ONLY Index: mln/core/image2d.hh --- mln/core/image2d.hh (revision 2086) +++ mln/core/image2d.hh (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 @@ -120,8 +121,11 @@ * thickness around data. */ template <typename T> - struct image2d : public internal::image_primary< box2d, image2d<T> > + class image2d : public internal::image_primary< box2d, image2d<T> > { + typedef internal::image_primary< box2d, image2d<T> > super_; + public: + /// Coordinate associated type. typedef int coord; @@ -171,23 +175,15 @@ /// Give the bounding box domain. const box2d& bbox() const; - /// Give the border thickness. - unsigned border() const; - - /// Give the number of cells (points including border ones). - std::size_t ncells() const; - /// Read-only access to the image value located at point \p p. const T& operator()(const point2d& p) const; /// Read-write access to the image value located at point \p p. T& operator()(const point2d& p); - /// Read-only access to the image value located at offset \p o. - const T& operator[](unsigned o) const; - /// Read-write access to the image value located at offset \p o. - T& operator[](unsigned o); + // Specific methods: + // ----------------- /// Read-only access to the image value located at (\p row, \p col). const T& at(int row, int col) const; @@ -195,14 +191,36 @@ /// Read-write access to the image value located at (\p row, \p col). T& at(int row, int col); + /// Give the number of rows. + unsigned nrows() const; + + /// Give the number of columns. + unsigned ncols() const; + + + // As a fastest image: + // ------------------- + + // Give the index of a point. + using super_::index_of_point; + + /// Give the border thickness. + unsigned border() const; + + /// Give the number of elements (points including border ones). + unsigned nelements() const; - /// Fast Image method + /// Read-only access to the image value located at index \p i. + const T& element(unsigned i) const; - /// Give the offset corresponding to the delta-point \p dp. - int offset(const dpoint2d& dp) const; + /// Read-write access to the image value located at index \p i. + T& element(unsigned i); - /// Give the point corresponding to the offset \p o. - point2d point_at_offset(unsigned o) const; + /// Give the delta-index corresponding to the delta-point \p dp. + int delta_index(const dpoint2d& dp) const; + + /// Give the point corresponding to the index \p i. + point2d point_at_index(unsigned i) const; /// Give a hook to the value buffer. const T* buffer() const; @@ -403,24 +421,6 @@ template <typename T> inline - unsigned - image2d<T>::border() const - { - mln_precondition(this->has_data()); - return this->data_->bdr_; - } - - template <typename T> - inline - std::size_t - image2d<T>::ncells() const - { - mln_precondition(this->has_data()); - return this->data_->vb_.nsites(); - } - - template <typename T> - inline bool image2d<T>::has(const point2d& p) const { @@ -446,40 +446,82 @@ return this->data_->array_[p.row()][p.col()]; } + + // Specific methods: + template <typename T> inline const T& - image2d<T>::operator[](unsigned o) const + image2d<T>::at(int row, int col) const { - mln_precondition(o < ncells()); - return *(this->data_->buffer_ + o); + mln_precondition(this->has(make::point2d(row, col))); + return this->data_->array_[row][col]; } template <typename T> inline T& - image2d<T>::operator[](unsigned o) + image2d<T>::at(int row, int col) { - mln_precondition(o < ncells()); - return *(this->data_->buffer_ + o); + mln_precondition(this->has(make::point2d(row, col))); + return this->data_->array_[row][col]; + } + + template <typename T> + inline + unsigned + image2d<T>::nrows() const + { + mln_precondition(this->has_data()); + return this->data_->b_.len(0); + } + + template <typename T> + inline + unsigned + image2d<T>::ncols() const + { + mln_precondition(this->has_data()); + return this->data_->b_.len(1); + } + + + // As a fastest image: + + template <typename T> + inline + unsigned + image2d<T>::border() const + { + mln_precondition(this->has_data()); + return this->data_->bdr_; + } + + template <typename T> + inline + unsigned + image2d<T>::nelements() const + { + mln_precondition(this->has_data()); + return this->data_->vb_.nsites(); } template <typename T> inline const T& - image2d<T>::at(int row, int col) const + image2d<T>::element(unsigned i) const { - mln_precondition(this->has(make::point2d(row, col))); - return this->data_->array_[row][col]; + mln_precondition(i < nelements()); + return *(this->data_->buffer_ + i); } template <typename T> inline T& - image2d<T>::at(int row, int col) + image2d<T>::element(unsigned i) { - mln_precondition(this->has(make::point2d(row, col))); - return this->data_->array_[row][col]; + mln_precondition(i < nelements()); + return *(this->data_->buffer_ + i); } template <typename T> @@ -503,7 +545,7 @@ template <typename T> inline int - image2d<T>::offset(const dpoint2d& dp) const + image2d<T>::delta_index(const dpoint2d& dp) const { mln_precondition(this->has_data()); int o = dp[0] * this->data_->vb_.len(1) + dp[1]; @@ -513,20 +555,23 @@ template <typename T> inline point2d - image2d<T>::point_at_offset(unsigned o) const + image2d<T>::point_at_index(unsigned i) const { - mln_precondition(o < ncells()); - point2d p = make::point2d(o / this->data_->vb_.len(1) + this->data_->vb_.min_row(), - o % this->data_->vb_.len(1) + this->data_->vb_.min_col()); - mln_postcondition(& this->operator()(p) == this->data_->buffer_ + o); + mln_precondition(i < nelements()); + point2d p = make::point2d(i / this->data_->vb_.len(1) + this->data_->vb_.min_row(), + i % this->data_->vb_.len(1) + this->data_->vb_.min_col()); + mln_postcondition(& this->operator()(p) == this->data_->buffer_ + i); return p; } + // Extra. + template <typename T> inline void image2d<T>::resize_(unsigned new_border) { + mln_precondition(this->has_data()); this->data_->reallocate_(new_border); } Index: mln/level/paste.spe.hh --- mln/level/paste.spe.hh (revision 2086) +++ mln/level/paste.spe.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 @@ -31,6 +31,8 @@ /*! \file mln/level/paste.spe.hh * * \brief Specializations for mln::level::paste. + * + * \todo Rewrite the dispatch!!! */ # ifndef MLN_LEVEL_PASTE_HH @@ -84,16 +86,16 @@ template <typename I, typename J> inline - void paste_(trait::image::data::any, const I& data, - trait::image::data::any, J& destination) + void paste_(trait::image::value_storage::any, const I& data, + trait::image::value_storage::any, J& destination) { generic::paste_(data, destination); } template <typename I, typename J> inline - void paste_(trait::image::data::raw, const I& data, - trait::image::data::raw, J& destination) + void paste_(trait::image::value_storage::one_block, const I& data, + trait::image::value_storage::one_block, J& destination) { if (sizeof(mln_value(I)) == sizeof(mln_value(J))) paste_lines_(data, destination); Index: mln/level/paste.hh --- mln/level/paste.hh (revision 2086) +++ mln/level/paste.hh (working copy) @@ -108,12 +108,12 @@ const I& data = exact(data_); J& destination = exact(destination_); - mlc_is(mln_trait_image_io(J), trait::image::io::write)::check(); + mlc_is(mln_trait_image_value_io(J), trait::image::value_io::read_write)::check(); mlc_converts_to(mln_value(I), mln_value(J))::check(); mln_precondition(data.domain() <= destination.domain()); - impl::paste_(mln_trait_image_data(I)(), data, - mln_trait_image_data(J)(), destination); + impl::paste_(mln_trait_image_value_storage(I)(), data, + mln_trait_image_value_storage(J)(), destination); trace::exiting("level::paste"); } Index: mln/border/resize.hh --- mln/border/resize.hh (revision 2086) +++ mln/border/resize.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 @@ -32,13 +32,15 @@ * * \brief Define a function that resizes the virtual border of an * image. + * + * \todo Use level::fill!!! */ # include <mln/core/concept/image.hh> # include <mln/core/clone.hh> -# include <mln/level/fill.hh> -# include <mln/metal/is.hh> # include <mln/border/get.hh> +// # include <mln/level/fill.hh> +// # include <mln/level/paste.hh> namespace mln @@ -68,12 +70,14 @@ namespace impl { + // Effective resizing. + template <typename I> inline void resize_(trait::image::category::morpher, - const I& ima_, unsigned thickness) + const I& ima, unsigned thickness) { - return resize(*ima_.delegatee_(), thickness); + return resize(*ima.delegatee_(), thickness); } template <typename I> @@ -85,7 +89,62 @@ mln_concrete(I) memo = clone(ima); ima.resize_(thickness); - level::fill(ima, memo); + // level::fill(ima, memo); + // level::paste(memo, ima); + mln_piter(I) p(ima.domain()); + for_all(p) + ima(p) = memo(p); + } + +// ext_domain: /any/ +// | +// + -- none +// | +// + -- /some/ +// | +// + -- fixed +// | | +// | + -- infinite +// | +// + -- extendable + + template <typename I> + inline + void resize_(trait::image::ext_domain::none, + const I& ima, unsigned thickness) + { + // No-op. + } + + template <typename I> + inline + void resize_(trait::image::ext_domain::fixed, + const I& ima, unsigned thickness) + { + // No-op. + } + + template <typename I> + inline + void resize_(trait::image::ext_domain::extendable, + const I& ima, unsigned thickness) + { + if (border::get(ima) == thickness) + return; // No-op. + resize_(mln_trait_image_category(I)(), + ima, thickness); + mln_postcondition(border::get(ima) == thickness); + } + + + // Selector. + + template <typename I> + inline + void resize_(const I& ima, unsigned thickness) + { + resize_(mln_trait_image_ext_domain(I)(), + ima, thickness); } } // end of namespace mln::border::resize @@ -99,15 +158,10 @@ { 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()); - if (border::get(ima) == thickness) - return; // No-op. - // Otherwise: do-it. - impl::resize_(mln_trait_image_category(I)(), - ima, thickness); + impl::resize_(ima, thickness); mln_postcondition(border::get(ima) == thickness); Index: mln/border/get.hh --- mln/border/get.hh (revision 2086) +++ mln/border/get.hh (working copy) @@ -60,7 +60,7 @@ template <typename I> inline - unsigned get_(trait::image::border::some, trait::image::category::primary, + unsigned get_(trait::image::ext_domain::some, trait::image::category::primary, const I& ima) { return ima.border(); @@ -68,7 +68,7 @@ template <typename I> inline - unsigned get_(trait::image::border::some, trait::image::category::morpher, + unsigned get_(trait::image::ext_domain::some, trait::image::category::morpher, const I& ima) { return border::get( *ima.delegatee_() ); @@ -77,7 +77,7 @@ template <typename I> inline - unsigned get_(trait::image::border::none, trait::image::category::any, + unsigned get_(trait::image::ext_domain::none, trait::image::category::any, const I&) { return 0; @@ -95,7 +95,8 @@ trace::entering("border::get"); mln_precondition(exact(ima).has_data()); - unsigned res = border::impl::get_(mln_trait_image_border(I)(), mln_trait_image_category(I)(), + unsigned res = border::impl::get_(mln_trait_image_ext_domain(I)(), + mln_trait_image_category(I)(), exact(ima)); trace::exiting("border::get");