https://svn.lrde.epita.fr/svn/oln/trunk/milena Index: ChangeLog from Nicolas Ballas <ballas@lrde.epita.fr> Add RLE and Sparse image to milena. * tests/sparse_image.cc, * tests/run_pset.cc, * tests/rle_image.cc: test. * mln/core/sparse_encode.hh: Encode an image into a sparse image. * mln/core/internal/run_image.hh: New, factorisation class. * mln/core/internal/run_psite.hh: New, run psite class. * mln/core/internal/run_pset.hh: New, point set of run image. * mln/core/rle_image.hh: New, rle_image class. * mln/core/rle_encode.hh: Encode an image into an rle image. * mln/core/sparse_image.hh: New, sparse_image class. mln/core/internal/run_image.hh | 97 +++++++++ mln/core/internal/run_pset.hh | 413 +++++++++++++++++++++++++++++++++++++++++ mln/core/internal/run_psite.hh | 146 ++++++++++++++ mln/core/rle_encode.hh | 110 ++++++++++ mln/core/rle_image.hh | 143 ++++++++++++++ mln/core/sparse_encode.hh | 104 ++++++++++ mln/core/sparse_image.hh | 147 ++++++++++++++ tests/rle_image.cc | 59 +++++ tests/run_pset.cc | 58 +++++ tests/sparse_image.cc | 81 ++++++++ 10 files changed, 1358 insertions(+) Index: tests/sparse_image.cc --- tests/sparse_image.cc (revision 0) +++ tests/sparse_image.cc (revision 0) @@ -0,0 +1,81 @@ +#include <mln/core/image2d_b.hh> +#include <mln/core/sparse_image.hh> +#include <mln/core/sparse_encode.hh> +#include <vector> + +using namespace mln; + + +template <typename Pset> +void test(const Pset& my_set) +{ + typename Pset::fwd_piter run (my_set); + for (run.start(); run.is_valid(); run.next()) + ; + //std::cout << run << std::endl; + + // std::cout << "Reverse" << std::endl; + typename Pset::bkd_piter run2 (my_set); + + //std::cout << "Reverse\n"; + + for (run2.start(); run2.is_valid(); run2.next()) + ; + // std::cout << run2 << std::endl; +} + +template <typename I> +void test2(I& ima) +{ + typename I::fwd_piter run (ima.domain()); + for_all(run) + ++ima(run); + + typename I::bkd_piter run2 (ima.domain()); + for_all(run2) + assert(ima(run2) == 1); +} + +int +main() +{ + mln::point2d p, q, r; + p = mln::make::point2d(0, 1); + q = mln::make::point2d(3, 0); + r = mln::make::point2d(2, 2); + mln::internal::run_pset_<mln::point2d> my_set; + mln::sparse_image<mln::point2d, int> sparse; + mln::sparse_image<mln::point2d, int> sparse2; + + + my_set.insert(p, 5); + my_set.insert(q, 8); + test(my_set); + + std::vector<int> values; + int a = 0; + values.push_back(a); + a = 0; + values.push_back(a); + a = 0; + values.push_back(a); + sparse.insert(q, 3, values); + + test(sparse.domain()); + test2(sparse); + + mln::image2d_b<int> ima2d (1, 5); + + ima2d(mln::make::point2d(0, 4)) = 5; + ima2d(mln::make::point2d(0, 3)) = 2; + +// oln::debug::print(ima2d); + + sparse2 = sparse_encode(ima2d); + + +// oln::debug::print(sparse2); +// std::cout << std::endl; + + return 0; +} Index: tests/run_pset.cc --- tests/run_pset.cc (revision 0) +++ tests/run_pset.cc (revision 0) @@ -0,0 +1,58 @@ +#include <mln/core/internal/run_pset.hh> +#include <mln/core/image2d_b.hh> +#include <iostream> + +using namespace mln; + +template <typename Pset> +void +parc(const Pset& pset) +{ + typename Pset::fwd_piter it_(pset); + + for_all(it_) + { + std::cout << (typename Pset::point) it_ << std::endl; + } + + typename Pset::bkd_piter rit_(pset); + + for_all(rit_) + { + std::cout << (typename Pset::point) rit_ << std::endl; + } +} + + +int +main() +{ + point2d p, q, r; + p = make::point2d(2, 4); + q = make::point2d(18, 42); + r = make::point2d(50, 76); + + // Psite declaration + run_psite<point2d> site(p, 5, 0); + run_psite<point2d> site2(r, 40, 0); + + // Pset test + internal::run_pset_<point2d> ps; + + ps.insert(p, 7); + assert(ps.npoints() == 7); + + ps.insert(q, 42); + assert(ps.npoints() == 49); + + assert(ps.has(site)); + assert(!ps.has(site2)); + + ps.insert(r, 14); + assert(!ps.has(site2)); + + // FIXME bbox test + + parc(ps); + return 0; +} Index: tests/rle_image.cc --- tests/rle_image.cc (revision 0) +++ tests/rle_image.cc (revision 0) @@ -0,0 +1,59 @@ +#include <mln/core/image2d_b.hh> +#include <mln/core/rle_image.hh> +#include <mln/core/rle_encode.hh> + +using namespace mln; + +template <typename Pset> +void test(const Pset& my_set) +{ + typename Pset::fwd_piter run (my_set); + for (run.start(); run.is_valid(); run.next()) + /*std::cout << run << std::endl*/; + + // std::cout << "Reverse" << std::endl; + + typename Pset::bkd_piter run2 (my_set); + for (run2.start(); run2.is_valid(); run2.next()) + /*std::cout << run2 << std::endl*/; +} + +int +main() +{ + mln::point2d p, q, r; + r = make::point2d(0, 1); + q = make::point2d(2, 2); + r = make::point2d(3, 0); + mln::internal::run_pset_<mln::point2d> my_set; + mln::rle_image<mln::point2d, int> rle; + mln::rle_image<mln::point2d, int> rle2; + + my_set.insert(p, 5); + my_set.insert(q, 8); + test(my_set); + + rle.insert(p, 5, 4); + rle.insert(q, 8, 9); + +// mln::debug::print(rle); +// std::cout << std::endl; + + mln::image2d_b<int> ima2d (1, 5); + ima2d(make::point2d(0, 4)) = 5; + +// mln::debug::print(ima2d); + + rle2 = rle_encode(ima2d); + + mln::rle_image<mln::point2d, int>::fwd_piter p1(rle2.domain()); + for_all(p1) + { + assert(ima2d(p1) == rle2(p1)); + } + +// mln::debug::print(rle2); +// std::cout << std::endl; + + return 0; +} Index: mln/core/sparse_encode.hh --- mln/core/sparse_encode.hh (revision 0) +++ mln/core/sparse_encode.hh (revision 0) @@ -0,0 +1,104 @@ +// 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_SPARSE_ENCODE_HH +# define MLN_CORE_SPARSE_ENCODE_HH + +/*! \file mln/core/sparse_image.hh + * + * \brief FIXME + */ + +# include <mln/core/sparse_image.hh> +# include <vector> + +namespace mln +{ + + /*! + ** encode a generic image to a sparse image format + ** + ** @param input an Image + ** + ** @return a sparse image + */ + template <typename I> + sparse_image<mln_point(I), mln_value(I)> + sparse_encode(const Image<I>& input); + +# ifndef MLN_INCLUDE_ONLY + + template <typename I> + sparse_image<mln_point(I), mln_value(I)> + sparse_encode(const Image<I>& input) + { + sparse_image<mln_point(I), mln_value(I)> output; + mln_piter(I) p(exact(input).domain()); + unsigned len = 1; + // old point first dim coordinate + typename I::coord old = 1; + // range pointstart + mln_point(I) rstart; + // range value + std::vector<mln_value(I)> values; + + p.start(); + if (not p.is_valid()) + return output; + + rstart = p; + + old = p[0]; + values.push_back(exact(input)(p)); + p.next_(); + while (p.is_valid()) + { + if (p[0] - 1 == old) + { + ++len; + values.push_back(exact(input)(p)); + } + else + { + output.insert(rstart, len, values); + rstart = p; + len = 1; + values.clear(); + values.push_back(exact(input)(p)); + } + old = p[0]; + p.next_(); + } + output.insert(rstart, len, values); + return output; + } + +#endif // ! MLN_INCLUDE_ONLY + +} + +#endif // ! MLN_CORE_SPARSE_ENCODE_HH Index: mln/core/internal/run_image.hh --- mln/core/internal/run_image.hh (revision 0) +++ mln/core/internal/run_image.hh (revision 0) @@ -0,0 +1,97 @@ +// 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_INTERNAL_RUN_IMAGE_HH +# define MLN_CORE_INTERNAL_RUN_IMAGE_HH + +/*! \file mln/core/internal/run_image.hh + * + * \brief Definition of mln::internal::run_image_ class for internal use only + */ + +# include <mln/core/internal/image_base.hh> +# include <mln/core/internal/run_pset.hh> +# include <mln/core/internal/run_psite.hh> +# include <mln/value/set.hh> + +namespace mln +{ + + namespace internal + { + + /*! \brief Factorization class for run_image. + * + * Parameter \c P is the type of the image point. + * Parameter \c E is the Exact type of the image. + */ + template <typename P, typename E> + class run_image_ : public image_base_<run_pset_<P>, E> + { + public: + typedef run_pset_<P> pset; + typedef mln_psite(pset) psite; + + /// Give the definition domain. + const pset& domain() const; + /// Test if \p p is valid. + bool owns_(const psite& site) const; + protected: + /// domain of the image + pset domain_; + + run_image_(); + }; + +# ifndef MLN_INCLUDE_ONLY + + template <typename P, typename E> + run_image_<P, E>::run_image_() + { + } + + template <typename P, typename E> + const typename run_image_<P, E>::pset& + run_image_<P, E>::domain() const + { + return domain_; + } + + template <typename P, typename E> + bool + run_image_<P, E>::owns_(const typename run_image_<P, E>::psite& site) const + { + return domain_.has(site); + } +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace internal + +} // end of namespace mln + + +#endif // ! MLN_CORE_INTERNAL_RUN_IMAGE_HH Index: mln/core/internal/run_psite.hh --- mln/core/internal/run_psite.hh (revision 0) +++ mln/core/internal/run_psite.hh (revision 0) @@ -0,0 +1,146 @@ +// 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_INTERNAL_RUN_PSITE_HH +# define MLN_CORE_INTERNAL_RUN_PSITE_HH + +/*! \file mln/core/internal/run_psite.hh + * + * \brief Definition of class mln::internal::run_psite_ for internal use only + */ + +namespace mln +{ + + namespace internal + { + + /*! \brief Psite class used in run_image_. + * + * Parameter \c P is the type of the image point. + */ + template <typename P> + class run_psite + { + public: + run_psite(); + run_psite(P point, unsigned index, unsigned pset_pos); + + operator P () const; + /// Return the point at the start of the current run. + P& range_start_(); + /// Return the point at the start of the current run. + const P& range_start_() const; + /// Return the position of this psite in the point set. + unsigned pset_pos_() const; + /// Return the position of this psite in the point set. + unsigned& pset_pos_(); + /// Return the position of this psite in the current range. + unsigned index_() const; + /// Return the position of this psite in the current range. + unsigned& index_(); + + protected: + /// Start of the psite range. + P point_; + /// Position in the psite range. + unsigned range_index_; + /// Position of the psite in the point set. + unsigned pset_position_; + }; + +# ifndef MLN_INCLUDE_ONLY + template <typename P> + run_psite<P>::run_psite() + { + } + + template <typename P> + run_psite<P>::run_psite(P point, unsigned index, unsigned pset_pos) : + point_(point), + range_index_(index), + pset_position_(pset_pos) + { + } + + template <typename P> + run_psite<P>::operator P() const + { + P tmp = point_; + tmp[0] += range_index_; + return tmp; + } + + template <typename P> + const P& + run_psite<P>::range_start_() const + { + return point_; + } + + template <typename P> + P& + run_psite<P>::range_start_() + { + return point_; + } + + template <typename P> + unsigned + run_psite<P>::pset_pos_() const + { + return pset_position_; + } + + template <typename P> + unsigned& + run_psite<P>::pset_pos_() + { + return pset_position_; + } + + template <typename P> + unsigned + run_psite<P>::index_() const + { + return range_index_; + } + + template <typename P> + unsigned& + run_psite<P>::index_() + { + return range_index_; + } +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace internal + +} // end of namespace mln + + +#endif // ! MLN_CORE_INTERNAL_RUN_PSITE_HH Index: mln/core/internal/run_pset.hh --- mln/core/internal/run_pset.hh (revision 0) +++ mln/core/internal/run_pset.hh (revision 0) @@ -0,0 +1,413 @@ +// 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_INTERNAL_RUN_PSET_HH +# define MLN_CORE_INTERNAL_RUN_PSET_HH + +/*! \file mln/core/internal/run_pset.hh + * + * \brief Definition of mln::internal::run_pset_ class and its iterators + * (for internal use only). + */ + +# include <mln/core/concept/point_set.hh> +# include <mln/core/concept/point_iterator.hh> +# include <mln/core/internal/run_psite.hh> +# include <mln/accu/bbox.hh> + +# include <vector> +# include <utility> + + + +namespace mln +{ + + namespace internal + { + // Forward declaration + template <typename P> struct run_fwd_piter_; + template <typename P> struct run_bkd_piter_; + + + /*! \brief run_pset_ class represent a point set used in run_image_ class. + * + * Parameter \c P is the type of the image point. + */ + template <typename P> + class run_pset_ : public Point_Set<run_pset_<P> > + { + public: + typedef P point; + typedef internal::run_psite<point> psite; + typedef std::vector<std::pair<point, unsigned> > std_container; + typedef run_fwd_piter_<P> fwd_piter; + typedef run_bkd_piter_<P> bkd_piter; + + + run_pset_(); + /// Test is \p p belongs to this point set. + bool has(const psite& p) const; + /// Give the exact bounding box. + const box_<P>& bbox() const; + /// Give the number of points. + typename std::size_t npoints() const; + + /// Insert a range, start at point \p p wit len \p len. + void insert(const P& p, unsigned len); + /// Return the len of the range starting at point \p p. + unsigned range_len_(const P& p) const; + + /// Return the container of the pset (internal use only). + const std_container& con() const; + + protected: + /// Number of points. + typename std::size_t npoints_; + /// Points container + std_container con_; + /// Exact bounding box. + accu::bbox<P> fb_; + }; + +# ifndef MLN_INCLUDE_ONLY + + template <typename P> + run_pset_<P>::run_pset_() : + npoints_(0) + { + } + + template <typename P> + bool + run_pset_<P>::has(const typename run_pset_<P>::psite& p) const + { + for (unsigned i = 0; i < con_.size(); ++i) + { + if (con_[i].first == p.range_start_() && con_[i].second > p.index_()) + return true; + } + return false; + } + + template <typename P> + const box_<P>& + run_pset_<P>::bbox() const + { + return fb_.to_value(); + } + + template <typename P> + typename std::size_t + run_pset_<P>::npoints() const + { + return npoints_; + } + + template <typename P> + void + run_pset_<P>::insert(const P& p, unsigned len) + { + point run_pend; + typename std_container::value_type elt (p, len); + con_.push_back(elt); + + // update box + fb_.take(p); + run_pend = p; + run_pend[0] += len - 1; + fb_.take(run_pend); + // update size + npoints_ += len; + } + + template <typename P> + unsigned + run_pset_<P>::range_len_(const P& p) const + { + unsigned i; + for (i = 0; i < con_.size(); ++i) + { + if (con_[i].first == p) + return con_[i].second; + } + mln_assertion(i < con.size()); + + //Hack + return (con_[i].second); + } + + template <typename P> + const typename run_pset_<P>::std_container& + run_pset_<P>::con() const + { + return con_; + } + +# endif // ! MLN_INCLUDE_ONLY + + /*! \brief Factorization class for run_pset_iterator_. + * + * Parameter \c P is the type of the point used in the point set. + * Parameter \c E is the exact type of the iterator + */ + template <typename P, typename E> + class run_piter_ : public Point_Iterator<E> + { + public: + typedef typename run_pset_<P>::std_container std_container; + typedef P point; + typedef mln_dpoint(P) dpoint; + typedef mln_coord(P) coord; + typedef internal::run_psite<P> psite; + + enum { dim = P::dim }; + + /// Convertion into a point-site. + operator psite () const; + /// Convertion into a point. + operator P () const; + /// Return a pointer of the current point. + const P* pointer_() const; + /// Access to the current point coordinates. + coord operator[](unsigned i) const; + + protected: + /// Current point. + P p_; + /// Current site. + psite site_; + /// Point set container. + const std_container& con_; + + run_piter_(const run_pset_<P>& pset); + }; + + +# ifndef MLN_INCLUDE_ONLY + + template <typename P, typename E> + run_piter_<P, E>::run_piter_(const run_pset_<P>& pset) : + con_(pset.con()) + { + } + + template <typename P, typename E> + run_piter_<P, E>::operator typename run_piter_<P, E>::psite () const + { + return site_; + } + + template <typename P, typename E> + run_piter_<P, E>::operator P () const + { + return p_; + } + + template <typename P, typename E> + const P* + run_piter_<P, E>::pointer_() const + { + mln_precondition(exact(this)->is_valid()); + return &p_; + } + + template <typename P, typename E> + typename run_piter_<P, E>::coord + run_piter_<P, E>::operator[] (unsigned i) const + { + mln_precondition(exact(this)->is_valid()); + return p_[i]; + } +# endif // ! MLN_INCLUDE_ONLY + + + /*! \brief Forward iterator on run_pset_ point set. + * + * Parameter \c P is the type of the point used in the point set. + */ + template <typename P> + class run_fwd_piter_ : public run_piter_<P, run_fwd_piter_<P> > + { + typedef run_piter_<P, run_fwd_piter_<P> > super; + public: + + run_fwd_piter_(const run_pset_<P>& pset); + + /// Test the iterator validity. + bool is_valid() const; + /// Invalidate the iterator. + void invalidate(); + /// Start an iteration. + void start(); + /// Go to the next point. + void next_(); + protected: + typename super::std_container::const_iterator it_; + }; + +# ifndef MLN_INCLUDE_ONLY + template <typename P> + run_fwd_piter_<P>::run_fwd_piter_(const run_pset_<P>& pset) : + super(pset) + { + it_ = this->con_.end(); + this->site_.pset_pos_() = this->con_.size(); + } + + template <typename P> + bool + run_fwd_piter_<P>::is_valid() const + { + return it_ != this->con_.end(); + } + + template <typename P> + void + run_fwd_piter_<P>::invalidate() + { + it_ = this->con_.end(); + this->site_.pset_pos_() = this->con_.size(); + } + + template <typename P> + void + run_fwd_piter_<P>::start() + { + it_ = this->con_.begin(); + this->site_.range_start_() = it_->first; + this->site_.index_() = 0; + this->site_.pset_pos_() = 0; + this->p_ = it_->first; + } + + template <typename P> + void + run_fwd_piter_<P>::next_() + { + mln_precondition(this->is_valid()); + ++(this->site_.index_()); + + if (this->site_.index_() >= it_->second) + { + ++it_; + ++this->site_.pset_pos_(); + this->site_.range_start_() = it_->first; + this->site_.index_() = 0; + } + this->p_ = this->site_.range_start_(); + this->p_[0] += this->site_.index_(); + } + +# endif // ! MLN_INCLUDE_ONLY + + /*! \brief Backward iterator on run_pset_ point set. + * + * Parameter \c P is the type of the point used in the point set. + */ + template <typename P> + class run_bkd_piter_ : public run_piter_<P, run_bkd_piter_<P> > + { + typedef run_piter_<P, run_bkd_piter_<P> > super; + public: + + run_bkd_piter_(const run_pset_<P>& pset); + + /// Test the iterator validity. + bool is_valid() const; + /// Invalidate the iterator. + void invalidate(); + /// Start an iteration. + void start(); + /// Go to the next point. + void next_(); + protected: + typename super::std_container::const_reverse_iterator it_; + }; + +# ifndef MLN_INCLUDE_ONLY + template <typename P> + run_bkd_piter_<P>::run_bkd_piter_(const run_pset_<P>& pset) : + super(pset) + { + it_ = this->con_.rend(); + this->site_.pset_pos_() = this->con_.size(); + } + + template <typename P> + bool + run_bkd_piter_<P>::is_valid() const + { + return it_ != this->con_.rend(); + } + + template <typename P> + void + run_bkd_piter_<P>::invalidate() + { + it_ = this->con_.rend(); + this->site_.pset_pos_() = this->con_.size(); + } + + template <typename P> + void + run_bkd_piter_<P>::start() + { + it_ = this->con_.rbegin(); + this->site_.range_start_() = it_->first; + this->site_.index_() = it_->second - 1; + this->site_.pset_pos_() = this->con_.size() - 1; + this->p_ = this->site_.range_start_(); + this->p_[0] += this->site_.index_(); + } + + template <typename P> + void + run_bkd_piter_<P>::next_() + { + mln_precondition(this->is_valid()); + --(this->site_.index_()); + + if (this->site_.index_() + 1 == 0) + { + ++it_; + --this->site_.pset_pos_(); + this->site_.range_start_() = it_->first; + this->site_.index_() = this->it_->second - 1; + } + this->p_ = this->site_.range_start_(); + this->p_[0] += this->site_.index_(); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace internal + +} // end of namespace mln + + +#endif // ! MLN_CORE_INTERNAL_RUN_PSET_HH Index: mln/core/rle_image.hh --- mln/core/rle_image.hh (revision 0) +++ mln/core/rle_image.hh (revision 0) @@ -0,0 +1,143 @@ +// 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_RLE_IMAGE_HH +# define MLN_CORE_RLE_IMAGE_HH + +/*! \file mln/core/rle_image.hh + * + * \brief Definition of mln::rle_image + */ + +# include <mln/core/internal/run_image.hh> +# include <mln/core/internal/run_psite.hh> +# include <mln/value/set.hh> +# include <vector> + +namespace mln +{ + + /*! \brief RLE image. + * + * + * Parameter \c P is the type of the image points. + * Parameter \c T is the type of the pixel values. + * This image is not point wise accessible. + */ + template <typename P, typename T> + class rle_image : public internal::run_image_< P, rle_image<P, T> > + { + public: + typedef T value; + typedef T& lvalue; + typedef const T rvalue; + typedef internal::run_psite<P> psite; + typedef mln::value::set<T> vset; + + rle_image(); + + /// Add a new range to the image. + void insert(const P& p, unsigned len, T value); + + /// Read-only access to the image value located at point \p p. + rvalue operator() (const psite& site) const; + + /// Read-write access to the image value located at point \p p. + lvalue operator() (const psite& site); + + /// Test if this image has been initialized. + bool has_data() const; + + /// Give the set of values of the image. + const vset& values() const; + + /// Change value type. + template <typename U> + struct change_value + { + typedef rle_image<P, U> ret; + }; + protected: + /// Image values. + std::vector<T> values_; + }; + + +# ifndef MLN_INCLUDE_ONLY + + template <typename P, typename T> + rle_image<P, T>::rle_image() + { + } + + template <typename P, typename T> + bool + rle_image<P, T>::has_data() const + { + return values_.size() != 0; + } + + template <typename P, typename T> + const typename rle_image<P, T>::vset& + rle_image<P, T>::values() const + { + return vset::the(); + } + + template <typename P, typename T> + void + rle_image<P, T>::insert(const P& p, unsigned len, T value) + { + this->domain_.insert(p, len); + values_.push_back(value); + } + + template <typename P, typename T> + typename rle_image<P, T>::rvalue + rle_image<P, T>::operator() (const typename rle_image<P, T>::psite& site) + const + { + mln_precondition(this->has_data() && + site.pset_pos_() < values_.size()); + return values_[site.pset_pos_()]; + } + + template <typename P, typename T> + typename rle_image<P, T>::lvalue + rle_image<P, T>::operator() (const typename rle_image<P, T>::psite& site) + { + mln_precondition(this->has_data() && + site.pset_pos_() < values_.size()); + return values_[site.pset_pos_()]; + } +# endif // ! MLN_INCLUDE_ONLY + + +} // end of namespace mln + + +#endif // ! MLN_CORE_RLE_IMAGE_HH Index: mln/core/rle_encode.hh --- mln/core/rle_encode.hh (revision 0) +++ mln/core/rle_encode.hh (revision 0) @@ -0,0 +1,110 @@ +// 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_RLE_ENCODE_HH +# define MLN_CORE_RLE_ENCODE_HH + +/*! \file mln/core/sparse_image.hh + * + * \brief FIXME + */ + +# include <mln/core/sparse_image.hh> +# include <vector> + +namespace mln +{ + + /*! + ** encode an image class to a rle_image + ** + ** @param input has to respect the Image concept + ** + ** @return rle_image + */ + template <typename I> + rle_image<mln_point(I), mln_value(I)> + rle_encode(const Image<I>& input); + +# ifndef MLN_INCLUDE_ONLY + /*! + ** test if Point p1 and p2 are on the same line + */ + template <typename P> + bool + on_the_same_line(const P& p1, const P& p2) + { + unsigned dim = P::dim; + bool same_line = true; + + for (int n = dim - 1; same_line and n > 0; --n) + same_line = (p1[n] == p2[n]); + return same_line; + } + + template <typename I> + rle_image<mln_point(I), mln_value(I)> + rle_encode(const Image<I>& input) + { + rle_image<mln_point(I), mln_value(I)> output; + mln_piter(I) p (exact(input).domain()); + unsigned len = 1; + /// range point start + mln_point(I) rstart; + /// range value + mln_value(I) rvalue; + + p.start(); + if (!p.is_valid()) + return output; + + rstart = p; + rvalue = exact(input)(p); + p.next_(); + while (p.is_valid()) + { + if (rvalue == exact(input)(p) and + on_the_same_line(rstart, mln_point(I)(p))) + ++len; + else + { + output.insert(rstart, len, rvalue); + len = 1; + rstart = p; + rvalue = exact(input)(p); + } + p.next_(); + } + output.insert(rstart, len, rvalue); + return output; + } + +#endif // ! MLN_INCLUDE_ONLY + +} + +#endif // ! MLN_CORE_RLE_ENCODE_HH Index: mln/core/sparse_image.hh --- mln/core/sparse_image.hh (revision 0) +++ mln/core/sparse_image.hh (revision 0) @@ -0,0 +1,147 @@ +// 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_SPARSE_IMAGE_HH +# define MLN_CORE_SPARSE_IMAGE_HH + +/*! \file mln/core/sparse_image.hh + * + * \brief Definition of mln::sparse_image + */ + +# include <mln/core/internal/run_image.hh> +# include <mln/core/internal/run_psite.hh> +# include <mln/value/set.hh> +# include <vector> + +namespace mln +{ + + /*! \brief Sparse image. + * + * + * Parameter \c P is the type of the image points. + * Parameter \c T is the type of the pixel values. + * This image is not point wise accessible. + */ + template <typename P, typename T> + class sparse_image : public internal::run_image_< P, sparse_image<P, T> > + { + public: + typedef T value; + typedef T& lvalue; + typedef const T rvalue; + typedef internal::run_psite<P> psite; + typedef mln::value::set<T> vset; + + sparse_image(); + + /// Add a new range to the image. + void insert(const P& p, unsigned len, const std::vector<T>& value); + + /// Read-only access to the image value located at point \p p. + rvalue operator() (const psite& p) const; + + /// Read-write access to the image value located at point \p p. + lvalue operator() (const psite& p); + + /// Test if this image has been initialized. + bool has_data() const; + + /// Give the set of values of the image. + const vset& values() const; + + /// Change value type. + template <typename U> + struct change_value + { + typedef sparse_image<P, U> ret; + }; + protected: + /// Image values. + std::vector< std::vector<value> > values_; + }; + +# ifndef MLN_INCLUDE_ONLY + + template <typename P, typename T> + sparse_image<P, T>::sparse_image() + { + } + + template <typename P, typename T> + bool + sparse_image<P, T>::has_data() const + { + return values_.size() != 0; + } + + template <typename P, typename T> + const typename sparse_image<P, T>::vset& + sparse_image<P, T>::values() const + { + return vset::the(); + } + + template <typename P, typename T> + void + sparse_image<P, T>::insert(const P& p, unsigned len, + const std::vector<T>& value) + { + this->domain_.insert(p, len); + values_.push_back(value); + } + + template <typename P, typename T> + typename sparse_image<P, T>::rvalue + sparse_image<P, T>::operator() + (const typename sparse_image<P, T>::psite& site) const + { + mln_precondition(this->has_data() && + site.pset_pos_() < values_.size() && + site.index_() < values_[site.pset_pos_()].size()); + return values_[site.pset_pos_()][site.index_()]; + } + + template <typename P, typename T> + typename sparse_image<P, T>::lvalue + sparse_image<P, T>::operator() + (const typename sparse_image<P,T>::psite& site) + { + mln_precondition(this->has_data() && + site.pset_pos_() < values_.size() && + site.index_() < values_[site.pset_pos_()].size()); + return values_[site.pset_pos_()][site.index_()]; + } + +# endif // ! MLN_INCLUDE_ONLY + + +} // end of namespace mln + + +#endif // ! MLN_CORE_SPARSE_IMAGE_HH