
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena ChangeLog: 2008-04-07 Matthieu Garrigues <garrigues@lrde.epita.fr> Add pixter for p_image2d. * mln/core/p_image2d_pixter.hh: New, a pixter to optimize iteration on p_image2d. * mln/core/p_image2d.hh: Update, optimize clear and the number of update of bb_. * tests/core/p_image2d.cc: More tests on the clean method. --- mln/core/p_image2d.hh | 53 +++++++++- mln/core/p_image2d_pixter.hh | 208 +++++++++++++++++++++++++++++++++++++++++++ tests/core/p_image2d.cc | 14 ++ 3 files changed, 270 insertions(+), 5 deletions(-) Index: trunk/milena/tests/core/p_image2d.cc =================================================================== --- trunk/milena/tests/core/p_image2d.cc (revision 1845) +++ trunk/milena/tests/core/p_image2d.cc (revision 1846) @@ -36,6 +36,7 @@ { using namespace mln; + trace::quiet = false; p_image2d<point2d> ps(20,20); ps .insert(make::point2d(6, 9)) @@ -53,4 +54,17 @@ mln_assertion(ps.npoints() == 0); mln_assertion(ps.is_empty()); + std::cout << ps << std::endl; + + mln_fwd_piter_(box2d) p(inplace(make::box2d(13,13,19,15))); + for_all(p) + { + ps.insert(p); + } + ps.clear(); + for_all(p) + { + mln_assertion(!ps.has(p)); + } + } Index: trunk/milena/mln/core/p_image2d_pixter.hh =================================================================== --- trunk/milena/mln/core/p_image2d_pixter.hh (revision 0) +++ trunk/milena/mln/core/p_image2d_pixter.hh (revision 1846) @@ -0,0 +1,208 @@ +// 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_CORE_P_IMAGE2D_PIXTER_HH +# define MLN_CORE_P_IMAGE2D_PIXTER_HH + +/*! \file mln/core/p_image2d_pixter.hh + * + * \brief Pixel iterator class on a image 2d with border. + */ + +# include <mln/core/internal/pixel_iterator_base.hh> +# include <mln/core/point2d.hh> +# include <mln/geom/size2d.hh> + + + +namespace mln +{ + + template <typename P> + class p_image2d_fwd_pixter : public internal::pixel_iterator_base_< typename p_image2d<P>::image_type, p_image2d_fwd_pixter<P> > + { + typedef internal::pixel_iterator_base_< typename p_image2d<P>::image_type, p_image2d_fwd_pixter<P> > super_; + + public: + + /// Image type. + typedef typename p_image2d<P>::image_type image; + + /// Point type. + typedef point2d point; + + /*! \brief Constructor. + * + * \param[in] image Image to iterate over its pixels. + */ + p_image2d_fwd_pixter(p_image2d<P>& s); + + /// Reference of the corresponding point. + const point to_point() const; + + /// Go to the next pixel. + void next_(); + + void start(); + + private: + + /// Row offset. + unsigned row_offset_; + /// End of the current row. + mln_qlf_value(image)* eor_; + }; + + + + template <typename P> + class p_image2d_bkd_pixter : public internal::pixel_iterator_base_< typename image2d<P>::image_type, p_image2d_bkd_pixter<P> > + { + typedef internal::pixel_iterator_base_< typename image2d<P>::image_type, p_image2d_bkd_pixter<P> > super_; + + public: + + /// Image type. + typedef typename p_image2d<P>::image_type image; + + /// Point type. + typedef point2d point; + + /*! \brief Constructor. + * + * \param[in] image Image to iterate over its pixels. + */ + p_image2d_bkd_pixter(p_image2d<P>& s); + + /// Go to the next pixel. + void next_(); + + void start(); + + /// Reference of the corresponding point. + const point to_point() const; + + private: + + /// Row offset. + unsigned row_offset_; + + /// Beginning of the current row. + mln_qlf_value(image)* bor_; + }; + + + + +#ifndef MLN_INCLUDE_ONLY + + // Fwd. + + template <typename P> + inline + p_image2d_fwd_pixter<P>::p_image2d_fwd_pixter(p_image2d<P>& s) : + super_(s.image_non_const()) + { + mln_precondition(this->image_.has_data()); + row_offset_ = geom::max_col(this->image_) - geom::min_col(this->image_) + 1; + eor_ = & this->image_.at(geom::min_row(this->image_), geom::max_col(this->image_)) + 1; + } + + template <typename P> + inline + const typename p_image2d_fwd_pixter<P>::point + p_image2d_fwd_pixter<P>::to_point() const + { + return this->image_.point_at_offset(*this); + } + + template <typename P> + inline + void + p_image2d_fwd_pixter<P>::next_() + { + ++this->value_ptr_; + while(this->is_valid() && !(*this->value_ptr_)) + ++this->value_ptr_; + } + + + template <typename P> + inline + void + p_image2d_fwd_pixter<P>::start() + { + this->value_ptr_ = this->boi_ + 1; + while(this->is_valid() && !(*this->value_ptr_)) + ++this->value_ptr_; + } + + // Bkd. + + template <typename P> + inline + p_image2d_bkd_pixter<P>::p_image2d_bkd_pixter(p_image2d<P>& s) : + super_(s.image_non_const()) + { + mln_precondition(this->image_.has_data()); + row_offset_ = geom::max_col(this->image_) - geom::min_col(this->image_) + 1; + bor_ = & this->image_.at(geom::max_row(this->image_), geom::min_col(this->image_)) - 1; + } + + template <typename P> + inline + const typename p_image2d_bkd_pixter<P>::point + p_image2d_bkd_pixter<P>::to_point() const + { + return this->image_.point_at_offset(*this); + } + + template <typename P> + inline + void + p_image2d_bkd_pixter<P>::next_() + { + --this->value_ptr_; + while(this->is_valid() && !(*this->value_ptr_)) + --this->value_ptr_; + } + + template <typename P> + inline + void + p_image2d_bkd_pixter<P>::start() + { + this->value_ptr_ = this->eoi_ - 1; + while(this->is_valid() && !(*this->value_ptr_)) + --this->value_ptr_; + } + +#endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + +#endif // ! MLN_CORE_P_IMAGE2D_PIXTER_HH Index: trunk/milena/mln/core/p_image2d.hh =================================================================== --- trunk/milena/mln/core/p_image2d.hh (revision 1845) +++ trunk/milena/mln/core/p_image2d.hh (revision 1846) @@ -37,8 +37,14 @@ # include <mln/core/internal/point_set_base.hh> # include <mln/core/box2d.hh> # include <mln/core/image2d.hh> +# include <mln/core/sub_image.hh> + +# include <mln/accu/bbox.hh> +# include <mln/geom/ncols.hh> +# include <mln/accu/bbox.hh> # include <mln/level/fill.hh> +# include <mln/level/memset_.hh> namespace mln { @@ -53,6 +59,8 @@ { public: + typedef image2d<bool> image_type; + /// Forward Point_Iterator associated type. typedef p_image2d_fwd_piter_<P> fwd_piter; @@ -90,6 +98,7 @@ /// Hook to the image2d const image2d<bool>& image() const; + image2d<bool>& image_non_const(); private: image2d<bool> points_; unsigned npoints_; @@ -102,11 +111,10 @@ template <typename P> p_image2d<P>::p_image2d(int nrows, int ncols) - : points_(nrows, ncols), + : points_(nrows, ncols, 0), npoints_(0), bb_need_update_(false) { - level::fill(points_, false); } @@ -153,8 +161,16 @@ if (points_(p) == true) { points_(p) = false; - bb_need_update_ = true; npoints_--; + + if (npoints_ == 0) + { + bb_.init(); + bb_need_update_ = false; + } + else + bb_need_update_ = true; + } return *this; } @@ -171,6 +187,7 @@ for_all(p) if (this->points_.has(p)) this->remove(p); + return *this; } @@ -205,7 +222,6 @@ if (bb_need_update_) { bb_.init(); - mln_fwd_piter(p_image2d<P>) p(*this); for_all(p) bb_.take(p); @@ -215,11 +231,30 @@ return bb_.to_result(); } + template <typename P> void p_image2d<P>::clear() { - level::fill(points_, false); + if (npoints_ == 0) + return; + + unsigned bb_nrows = geom::nrows(bb_.to_result()); + unsigned ima_nrows = geom::nrows(points_); + + if (bb_nrows * 3 < ima_nrows * 2) + { + unsigned bb_ncols = geom::ncols(bb_.to_result()); + mln_line_piter_(image2d<bool>) p(bb_.to_result()); + for_all(p) + { + level::memset_(points_, p, false, bb_ncols); + } + } + else + level::fill(inplace(points_), false); + + npoints_ = 0; bb_.init(); bb_need_update_ = false; } @@ -231,12 +266,20 @@ return points_; } + template <typename P> + image2d<bool>& + p_image2d<P>::image_non_const() + { + return points_; + } + # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln # include <mln/core/p_image2d_piter.hh> +# include <mln/core/p_image2d_pixter.hh> #endif // ! MLN_CORE_P_IMAGE2D_HH