1013: Add subimage in milena.

https://svn.lrde.epita.fr/svn/oln/trunk/milena Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Add subimage in milena. * tests/subimage.cc: New. * mln/core/subimage.hh: New. * mln/debug/println.hh: Handle "not has" cases. * mln/core/concept/box.hh (operator=, operator<, operator<=): New. * mln/core/concept/point_set.hh: Likewise. * mln/core/internal/image_adaptor.hh: Add default parameter. * mln/core/internal/piter_adaptor.hh: . * mln/accu/histo.hh, * mln/accu/median.hh, * mln/accu/median_alt.hh, * mln/value/viter.hh, * mln/value/set.hh, * mln/make/dpoint2d.hh, * mln/make/point2d.hh: Fix doc. mln/accu/histo.hh | 2 mln/accu/median.hh | 2 mln/accu/median_alt.hh | 4 - mln/core/concept/box.hh | 76 +++++++++++++++++++++++ mln/core/concept/point_set.hh | 98 ++++++++++++++++++++++++++++++ mln/core/internal/image_adaptor.hh | 44 +++++++------ mln/core/internal/piter_adaptor.hh | 6 - mln/core/subimage.hh | 118 +++++++++++++++++++++++++++++++++++++ mln/debug/println.hh | 7 +- mln/make/dpoint2d.hh | 2 mln/make/point2d.hh | 2 mln/value/set.hh | 2 mln/value/viter.hh | 4 - tests/subimage.cc | 47 ++++++++++++++ 14 files changed, 379 insertions(+), 35 deletions(-) Index: tests/subimage.cc --- tests/subimage.cc (revision 0) +++ tests/subimage.cc (revision 0) @@ -0,0 +1,47 @@ +// 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/subimage.cc + * + * \brief Tests on mln::subimage. + */ + +#include <mln/core/image2d_b.hh> +#include <mln/core/subimage.hh> +#include <mln/fun/chess.hh> +#include <mln/debug/println.hh> + + +int main() +{ + using namespace mln; + + image2d_b<int> ima(8, 8); + debug::println(ima | fun::chess); + + // mln_assertion((box_8x8 | fun::chess).npoints() = 32); +} Index: mln/debug/println.hh --- mln/debug/println.hh (revision 1012) +++ mln/debug/println.hh (working copy) @@ -67,7 +67,7 @@ std::cout << std::endl; } - // "domain = box2d" version + // 2D version template <typename I> void println(const box2d& b, const I& input) { @@ -79,7 +79,10 @@ for (row = b.min_row(); row <= max_row; ++row) { for (col = b.min_col(); col <= max_col; ++col) + if (input.has(p)) std::cout << format( input(p) ) << ' '; + else + std::cout << " "; std::cout << std::endl; } std::cout << std::endl; @@ -94,7 +97,7 @@ template <typename I> void println(const Image<I>& input) { - impl::println(exact(input).domain(), exact(input)); + impl::println(exact(input).bbox(), exact(input)); } # endif // ! MLN_INCLUDE_ONLY Index: mln/core/subimage.hh --- mln/core/subimage.hh (revision 0) +++ mln/core/subimage.hh (revision 0) @@ -0,0 +1,118 @@ +// 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_SUBIMAGE_HH +# define MLN_CORE_SUBIMAGE_HH + +/*! \file mln/core/subimage.hh + * + * \brief Definition of a base class for image adaptors. + */ + +# include <mln/core/internal/image_adaptor.hh> +# include <mln/core/psubset.hh> + + +namespace mln +{ + + /*! \brief A base class for image adaptors. + * + */ + template <typename I, typename F> + struct subimage : public internal::image_adaptor_< I, + subimage<I,F>, + psubset<mln_pset(I),F> > + { + /// Point_Set associated type. + typedef psubset<mln_pset(I), F> pset; + + /// Constructor from an \p adaptee image. + subimage(I& adaptee, const F& f); + + /// Test if a pixel value is accessible at \p p. + bool owns_(const mln_psite(I)& p) const; + + /// Give the definition domain. + const pset& domain() const; + + template <typename T> + struct change_value + { + typedef subimage<mln_ch_value(I,T), F> ret; + }; + + protected: + + pset pset_; + F f_; + + typedef subimage<I,F> self_; + typedef internal::image_adaptor_< I, self_, pset > super_; + }; + + + + template <typename I, typename F> + subimage<I, F> + operator | (Image<I>& ima, const Function_p2b<F>& f) + { + subimage<I, F> tmp(exact(ima), exact(f)); + return tmp; + } + + +# ifndef MLN_INCLUDE_ONLY + + template <typename I, typename F> + subimage<I,F>::subimage(I& adaptee, const F& f) + : super_(adaptee), + pset_(adaptee.domain() | f), + f_(f) + { + } + + template <typename I, typename F> + bool + subimage<I,F>::owns_(const mln_psite(I)& p) const + { + return pset_.has(p); + } + + template <typename I, typename F> + const psubset<mln_pset(I), F>& + subimage<I,F>::domain() const + { + return pset_; + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + + +#endif // ! MLN_CORE_SUBIMAGE_HH Index: mln/core/concept/box.hh --- mln/core/concept/box.hh (revision 1012) +++ mln/core/concept/box.hh (working copy) @@ -85,8 +85,47 @@ }; + + /*! \brief Equality test between boxes \p lhs and \p rhs. + * + * \param[in] lhs A box. + * \param[in] rhs Another box. + * + * \relates mln::Box + */ + template <typename Bl, typename Br> + bool operator=(const Box<Bl>& lhs, const Box<Br>& rhs); + + + + /*! \brief Inclusion test between boxes \p lhs and \p rhs. + * + * \param[in] lhs A box (included?). + * \param[in] rhs Another box (includor?). + * + * \relates mln::Box + */ + template <typename Bl, typename Br> + bool operator<=(const Box<Bl>& lhs, const Box<Br>& rhs); + + + /*! \brief Strict inclusion test between boxes \p lhs and \p rhs. + * + * \param[in] lhs A box (strictly included?). + * \param[in] rhs Another box (includor?). + * + * \relates mln::Box + */ + template <typename Bl, typename Br> + bool operator<(const Box<Bl>& lhs, const Box<Br>& rhs); + + + + # ifndef MLN_INCLUDE_ONLY + // Box<E> + template <typename E> const E& Box<E>::bbox() const { @@ -114,12 +153,47 @@ Box<E>::npoints() const { std::size_t count = 1; - typedef typename E::point P; // helps g++-3.3.5 + typedef mln_point(E) P; // helps g++-3.3.5 for (unsigned i = 0; i < P::dim; ++i) count *= exact(this)->len(i); return count; } + + // operators + + template <typename Bl, typename Br> + bool operator=(const Box<Bl>& lhs_, const Box<Br>& rhs_) + { + // FIXME: Same grid! + const Bl& lhs = exact(lhs_); + const Br& rhs = exact(rhs_); + return lhs.pmin() = rhs.pmin() && lhs.pmax() = rhs.pmax(); + } + + template <typename Bl, typename Br> + bool operator<=(const Box<Bl>& lhs_, const Box<Br>& rhs_) + { + // FIXME: Same grid! + const Bl& lhs = exact(lhs_); + const Br& rhs = exact(rhs_); + typedef mln_point(Bl) P; + for (unsigned i = 0; i < P::dim; ++i) + if (lhs.pmin()[i] < rhs.pmin()[i] || + lhs.pmax()[i] > rhs.pmax()[i]) + return false; + return true; + } + + template <typename Bl, typename Br> + bool operator<(const Box<Bl>& lhs_, const Box<Br>& rhs_) + { + // FIXME: Same grid! + const Bl& lhs = exact(lhs_); + const Br& rhs = exact(rhs_); + return lhs <= rhs && ! lhs = rhs; + } + # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln Index: mln/core/concept/point_set.hh --- mln/core/concept/point_set.hh (revision 1012) +++ mln/core/concept/point_set.hh (working copy) @@ -64,6 +64,43 @@ }; + /*! \brief Equality test between point sets \p lhs and \p rhs. + * + * \param[in] lhs A point set. + * \param[in] rhs Another point set. + * + * \relates mln::Point_Set + */ + template <typename Sl, typename Sr> + bool operator=(const Point_Set<Sl>& lhs, const Point_Set<Sr>& rhs); + + + + /*! \brief Inclusion test between point sets \p lhs and \p rhs. + * + * \param[in] lhs A point set (included?). + * \param[in] rhs Another point set (includer?). + * + * \relates mln::Point_Set + */ + template <typename Sl, typename Sr> + bool operator<=(const Point_Set<Sl>& lhs, const Point_Set<Sr>& rhs); + + + + /*! \brief Strict inclusion test between point sets \p lhs and \p + * rhs. + * + * \param[in] lhs A point set (strictly included?). + * \param[in] rhs Another point set (includer?). + * + * \relates mln::Point_Set + */ + template <typename Sl, typename Sr> + bool operator<(const Point_Set<Sl>& lhs, const Point_Set<Sr>& rhs); + + + /*! \brief Print a point set \p pset into the output stream \p * ostr. * @@ -78,6 +115,7 @@ std::ostream& operator<<(std::ostream& ostr, const Point_Set<S>& pset); + # ifndef MLN_INCLUDE_ONLY // fwd decl @@ -102,6 +140,66 @@ } + // operators + + + template <typename Sl, typename Sr> + bool operator=(const Point_Set<Sl>& lhs_, const Point_Set<Sr>& rhs_) + { + // FIXME: Same grid! + const Sl& lhs = exact(lhs_); + const Sr& rhs = exact(rhs_); + + // easy test: + if (lhs.npoints() != rhs.npoints()) + return false; + + // exhaustive test: + mln_fwd_piter(Sl) pl(lhs); + mln_fwd_piter(Sr) pr(rhs); + for (pl.start(), pr.start(); + pl.is_valid() && pr.is_valid(); + pl.next(), pr.next()) + if (pl != pr) + return false; // difference found + + // both sets are equal only if both browsings are completed + // at the same time: + return ! pl.is_valid() && ! pr.is_valid(); + } + + + template <typename Sl, typename Sr> + bool operator<=(const Point_Set<Sl>& lhs_, const Point_Set<Sr>& rhs_) + { + // FIXME: Same grid! + const Sl& lhs = exact(lhs_); + const Sr& rhs = exact(rhs_); + + // easy test: + if (lhs.npoints() > rhs.npoints()) + return false; + + // exhaustive test: + mln_piter(Sl) pl(lhs); + for_all(pl) + if (! rhs.has(pl)) + return false; + + return true; + } + + + template <typename Sl, typename Sr> + bool operator<(const Point_Set<Sl>& lhs_, const Point_Set<Sr>& rhs_) + { + // FIXME: Same grid! + const Sl& lhs = exact(lhs_); + const Sr& rhs = exact(rhs_); + return lhs <= rhs && lhs.npoints() != rhs.npoints(); + } + + template <typename S> std::ostream& operator<<(std::ostream& ostr, const Point_Set<S>& pset_) { Index: mln/core/internal/image_adaptor.hh --- mln/core/internal/image_adaptor.hh (revision 1012) +++ mln/core/internal/image_adaptor.hh (working copy) @@ -46,14 +46,16 @@ * * \internal */ - template <typename I, typename E> - struct image_adaptor_ : public internal::image_base_< mln_pset(I), E > + template < typename I, + typename E, + typename S = mln_pset(I) > + struct image_adaptor_ : public internal::image_base_< S, E > { /// Psite associated type. - typedef mln_psite(I) psite; + typedef mln_psite(S) psite; /// Point_Set associated type. - typedef mln_pset(I) pset; + typedef S pset; /// Value associated type. typedef mln_value(I) value; @@ -71,7 +73,7 @@ bool owns_(const psite& p) const; /// Give the definition domain. - const pset& domain() const; + const S& domain() const; /// Read-only access of pixel value at point site \p p. rvalue operator()(const psite& p) const; @@ -92,41 +94,43 @@ # ifndef MLN_INCLUDE_ONLY - template <typename I, typename E> - bool image_adaptor_<I,E>::has_data() const + template <typename I, typename E, typename S> + bool image_adaptor_<I,E,S>::has_data() const { return adaptee_.has_data(); } - template <typename I, typename E> - bool image_adaptor_<I,E>::owns_(const psite& p) const + template <typename I, typename E, typename S> + bool image_adaptor_<I,E,S>::owns_(const psite& p) const { return adaptee_.owns_(p); } - template <typename I, typename E> - const typename image_adaptor_<I,E>::pset& - image_adaptor_<I,E>::domain() const + template <typename I, typename E, typename S> + const S& + image_adaptor_<I,E,S>::domain() const { return adaptee_.domain(); } - template <typename I, typename E> - typename image_adaptor_<I,E>::rvalue - image_adaptor_<I,E>::operator()(const psite& p) const + template <typename I, typename E, typename S> + typename image_adaptor_<I,E,S>::rvalue + image_adaptor_<I,E,S>::operator()(const psite& p) const { + mln_precondition(exact(this)->owns_(p)); return adaptee_(p); } - template <typename I, typename E> - typename image_adaptor_<I,E>::lvalue - image_adaptor_<I,E>::operator()(const psite& p) + template <typename I, typename E, typename S> + typename image_adaptor_<I,E,S>::lvalue + image_adaptor_<I,E,S>::operator()(const psite& p) { + mln_precondition(exact(this)->owns_(p)); return adaptee_(p); } - template <typename I, typename E> - image_adaptor_<I,E>::image_adaptor_(Image<I>& adaptee) + template <typename I, typename E, typename S> + image_adaptor_<I,E,S>::image_adaptor_(Image<I>& adaptee) : adaptee_(exact(adaptee)) { } Index: mln/core/internal/piter_adaptor.hh --- mln/core/internal/piter_adaptor.hh (revision 1012) +++ mln/core/internal/piter_adaptor.hh (working copy) @@ -28,7 +28,7 @@ #ifndef MLN_CORE_INTERNAL_PITER_ADAPTOR_HH # define MLN_CORE_INTERNAL_PITER_ADAPTOR_HH -/*! \file mln/core/internal/piter_adaptor_.hh +/*! \file mln/core/internal/piter_adaptor.hh * * \brief Definition of iterators on points of boxes. */ @@ -69,12 +69,12 @@ typedef mln_coord(Pi) coord; - /// Constructor from a point iterator \p \piter. + /// Constructor from a point iterator \p piter. piter_adaptor_(const Pi& piter); /// Convertion to point. - operator point() const; + operator mln_point(Pi) () const; /// Address of the point. const point* pointer() const; Index: mln/accu/histo.hh --- mln/accu/histo.hh (revision 1012) +++ mln/accu/histo.hh (working copy) @@ -28,7 +28,7 @@ #ifndef MLN_ACCU_HISTO_HH # define MLN_ACCU_HISTO_HH -/*! \file mln/value/histo.hh +/*! \file mln/accu/histo.hh * * \brief Define a couple of generic histogram classes. */ Index: mln/accu/median.hh --- mln/accu/median.hh (revision 1012) +++ mln/accu/median.hh (working copy) @@ -59,7 +59,7 @@ unsigned card() const { return h_.sum(); } - operator value() const; + operator mln_value(S) () const; value to_value() const; const histo_on_set<S>& histo() const; Index: mln/accu/median_alt.hh --- mln/accu/median_alt.hh (revision 1012) +++ mln/accu/median_alt.hh (working copy) @@ -57,7 +57,7 @@ void untake(const value& v); void init(); - operator value() const; + operator mln_value(S) () const; value to_value() const; // FIXME: remove @@ -249,7 +249,7 @@ } template <typename S> - median_alt<S>::operator typename median_alt<S>::value () const + median_alt<S>::operator mln_value(S) () const { return v_; } Index: mln/value/viter.hh --- mln/value/viter.hh (revision 1012) +++ mln/value/viter.hh (working copy) @@ -58,7 +58,7 @@ fwd_viter_(const Value_Set<S>& s); /// Convertion into a value. - operator value() const; + operator mln_value(S) () const; /// Test if the iterator is valid. bool is_valid() const; @@ -95,7 +95,7 @@ bkd_viter_(const Value_Set<S>& s); /// Convertion into a value. - operator value() const; + operator mln_value(S) () const; /// Test if the iterator is valid. bool is_valid() const; Index: mln/value/set.hh --- mln/value/set.hh (revision 1012) +++ mln/value/set.hh (working copy) @@ -28,7 +28,7 @@ #ifndef MLN_VALUE_SET_HH # define MLN_VALUE_SET_HH -/*! \file mln/value/vset.hh +/*! \file mln/value/set.hh * * \brief Define some basic sets of values from value types. */ Index: mln/make/dpoint2d.hh --- mln/make/dpoint2d.hh (revision 1012) +++ mln/make/dpoint2d.hh (working copy) @@ -45,7 +45,7 @@ /*! \brief Create an mln::dpoint2d. * * \param[in] row Row coordinate. - * \param[in] Col Column coordinate. + * \param[in] col Column coordinate. * * \return A 2D dpoint. */ Index: mln/make/point2d.hh --- mln/make/point2d.hh (revision 1012) +++ mln/make/point2d.hh (working copy) @@ -45,7 +45,7 @@ /*! \brief Create an mln::point2d. * * \param[in] row Row coordinate. - * \param[in] Col Column coordinate. + * \param[in] col Column coordinate. * * \return A 2D point. */
participants (1)
-
Thierry Geraud