***SPAM*** L3 cleanup-2008 2068: Update iterator base classes and make image_if fully work.

https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Update iterator base classes and make image_if fully work. * doc/tutorial/examples/image_if.cc (change_target): Test it. * doc/tutorial/examples/window.cc: New. * mln/core/window.hh (window): New ctor from util::set. * mln/core/internal/basic_window_impl.hh (dps_): Move from private to protected. (basic_window_impl): New ctor from util::set. * mln/core/dpsites_piter.hh (update): Move... * mln/core/internal/site_relative_iterator_base.hh: ...here so it is factored. (p_, p_hook_, change_target): New. * mln/core/internal/site_iterator_base.hh (todo): Update. (p): Remove. (current_p_, p_): Remove as is; those entities are now defined in sub-classes as respectively p_hook_ and p_ (if needed). * mln/core/internal/site_set_iterator_base.hh (site_set_iterator_base): Change from struct to class. (p_, p_hook_, change_target): New. * mln/core/internal/piter_adaptor.hh (todo): Update. (piter_adaptor_): Fix inheritance. (S): New parameter. (p_hook_, change_target): New. (piter_): Rename as... (pi_): ...this. * mln/core/concept/neighborhood.hh (window, to_window): New. * mln/core/neighb.hh: Likewise. * mln/core/box_piter.hh (super_): Fix type definition. * mln/core/pset_if_piter.hh (pset_if_piter_): Inherit from piter_adaptor_. (is_valid_, invalidate_): Remove; now factored in super class. (pi_set_from_): New method required for adapters. (start_, next_): Update. * mln/core/p_array_piter.hh: Layout. * mln/morpho/dilation_elementary.hh: New. doc/tutorial/examples/image_if.cc | 11 +++ doc/tutorial/examples/window.cc | 80 +++++++++++++++++++++ mln/core/box_piter.hh | 40 +++++----- mln/core/concept/neighborhood.hh | 11 ++- mln/core/dpsites_piter.hh | 26 ------- mln/core/internal/basic_window_impl.hh | 23 +++++- mln/core/internal/piter_adaptor.hh | 84 ++++++++++++++++------- mln/core/internal/site_iterator_base.hh | 41 +---------- mln/core/internal/site_relative_iterator_base.hh | 55 +++++++++++++-- mln/core/internal/site_set_iterator_base.hh | 35 +++++++++ mln/core/neighb.hh | 13 +++ mln/core/p_array_piter.hh | 2 mln/core/pset_if_piter.hh | 62 +++++----------- mln/core/window.hh | 4 + mln/morpho/dilation_elementary.hh | 80 +++++++++++++++++++++ 15 files changed, 407 insertions(+), 160 deletions(-) Index: doc/tutorial/examples/image_if.cc --- doc/tutorial/examples/image_if.cc (revision 2067) +++ doc/tutorial/examples/image_if.cc (working copy) @@ -7,6 +7,12 @@ # include <mln/fun/p2b/chess.hh> +template <typename It, typename S> +void ch_target(It it, const S& s) +{ + it.change_target(s); +} + int main() { @@ -20,4 +26,9 @@ debug::println(ima | fun::p2b::chess); trait::image::print(ima | fun::p2b::chess); + + typedef pset_if<box2d, fun::p2b::chess_t> S; + + ch_target(mln_fwd_piter_(S)(), + (ima | fun::p2b::chess).domain()); } Index: doc/tutorial/examples/window.cc --- doc/tutorial/examples/window.cc (revision 0) +++ doc/tutorial/examples/window.cc (revision 0) @@ -0,0 +1,80 @@ +# include <mln/core/image2d.hh> +# include <mln/core/window2d.hh> +# include <mln/core/p_array.hh> + +# include <mln/debug/iota.hh> +# include <mln/debug/println.hh> + +# include <mln/core/neighb2d.hh> + + +template <typename I, typename W, typename P> +void picture(const I& ima, const W& win, const P& p) +{ + std::cout << ima(p) << ": "; + mln_qiter(W) q(win, p); + for_all(q) + if (ima.has(q)) + std::cout << ima(q) << ' '; + else + std::cout << "- "; + std::cout << std::endl; +} + + +template <typename I, typename W> +void fill_null(I& ima, const W& win) +{ + mln_piter(I) p(ima.domain()); + mln_qiter(W) q(win, p); + for_all(p) + for_all(q) + if (ima.has(q)) + ima(q) = 0; +} + + + +int main() +{ + using namespace mln; + + typedef image2d<unsigned> I; + I ima(2, 3, 0); // no border + debug::iota(ima); + debug::println(ima); + mln_invariant(ima.nsites() == 6); + + window2d win; + win + .insert(-1, 0) + .insert(0, -1) + .insert(-1,-1); + std::cout << win << std::endl; + + { + mln_fwd_piter_(I) p(ima.domain()); + for_all(p) + picture(ima, win, p); + } + + { + typedef p_array<point2d> A; + A arr; + arr.insert_all(ima.domain()); + mln_fwd_piter_(A) p(arr); + for_all(p) + picture(ima, win, p); + + // FIXME: Move this new test in a separate file. + mln_psite_(A) c(arr, 0); + window2d it; it.insert(0,0); + mln_qiter_(window2d) q(it, c); + q.start(); + q.to_site() == c.to_site(); + c.inc_index(); + mln_assertion(q.update().to_site() == c.to_site()); + } + + fill_null(ima, win); +} Index: mln/core/window.hh --- mln/core/window.hh (revision 2067) +++ mln/core/window.hh (working copy) @@ -64,6 +64,10 @@ */ window(); + window(const util::set<D>& s) + { + this->dps_ = s; + } /*! \brief Test if the window is centered. * Index: mln/core/internal/basic_window_impl.hh --- mln/core/internal/basic_window_impl.hh (revision 2067) +++ mln/core/internal/basic_window_impl.hh (working copy) @@ -55,8 +55,6 @@ template <typename D, typename E> class basic_window_impl { - util::set<D> dps_; - public: @@ -119,8 +117,14 @@ protected: + util::set<D> dps_; + + /// Constructor without argument. basic_window_impl(); + /// Constructor from an util::set. + basic_window_impl(const util::set<D>& s); + void insert_(const D& dp); // The only routine to effectively insert a dp. // This is a default implementation. This routine can be // overidden in sub-classes. @@ -137,6 +141,21 @@ template <typename D, typename E> inline + basic_window_impl<D,E>::basic_window_impl(const util::set<D>& s) + { + bool is_sym = true; + for (unsigned i = 0; s.nelements(); ++i) + if (! s.has(-s[i])) + { + is_sym = false; + break; + } + mln_precondition(is_sym); + dps_ = s; + } + + template <typename D, typename E> + inline bool basic_window_impl<D,E>::is_empty() const { return dps_.is_empty(); Index: mln/core/internal/site_relative_iterator_base.hh --- mln/core/internal/site_relative_iterator_base.hh (revision 2067) +++ mln/core/internal/site_relative_iterator_base.hh (working copy) @@ -86,9 +86,24 @@ /// changed. const mln_psite(S)& unproxy() const; + /// Hook to the current location. + const mln_psite(S)& p_hook_() const; + + /// Change the site set targeted by this iterator. + void change_target(const S& s); + + /// FIXME: import doc from home. + E& update(); + protected: + /// A pointer to the center psite. const mln_psite(S)* c_; + + private: + + /// The psite designated by this iterator. + mln_psite(S) p_; }; @@ -125,7 +140,7 @@ { exact(this)->do_start_(); if (this->is_valid()) - this->p_ = exact(this)->compute_p_(); + p_ = exact(this)->compute_p_(); } template <typename S, typename E> @@ -135,7 +150,7 @@ { exact(this)->do_next_(); if (this->is_valid()) - this->p_ = exact(this)->compute_p_(); + p_ = exact(this)->compute_p_(); } template <typename S, typename E> @@ -153,8 +168,40 @@ site_relative_iterator_base<S,E>::unproxy() const { mln_psite(S) p_now = exact(this)->compute_p_(); - mln_assertion(p_now == this->p_); - return this->p_; + mln_assertion(p_now == p_); + return p_; + } + + template <typename S, typename E> + inline + const mln_psite(S)& + site_relative_iterator_base<S,E>::p_hook_() const + { + return p_; + } + + template <typename S, typename E> + inline + void + site_relative_iterator_base<S,E>::change_target(const S& s) + { + this->s_ = & s; + // p might be also updated since it can hold a pointer towards + // the set it designates, so: + if_possible::change_target(p_, s); + // Last: + this->invalidate(); + } + + template <typename S, typename E> + inline + E& + site_relative_iterator_base<S,E>::update() + { + mln_precondition(this->s_ && c_); + p_ = exact(this)->compute_p_(); + mln_postcondition(this->is_valid()); + return exact(*this); } # endif // ! MLN_INCLUDE_ONLY Index: mln/core/internal/site_iterator_base.hh --- mln/core/internal/site_iterator_base.hh (revision 2067) +++ mln/core/internal/site_iterator_base.hh (working copy) @@ -32,20 +32,14 @@ * * \brief Base class to factor code for site iterator classes. * - * \todo Make p_ private and add a p() method that can be overridden - * so that a subclass can use some other info than this attribute. - * See for instance start_ and next_ in pset_if_piter.hh: we have - * both pi_ and p_ to designate the current site. + * \todo Import tech doc from home. */ # include <mln/core/concept/site_iterator.hh> # include <mln/core/concept/pseudo_site.hh> // Use of if_possible::change_target. -// site_iterator_base<S> where S is a Site_Set -// { -// s_ : const S* -// } +// FIXME: See todo. @@ -100,26 +94,12 @@ /// Give the target address. It might be 0. const S*& target_(); - /// Change the iterator target. - void change_target(const S& s); - - mln_psite(S)& p() { return exact(this)->current_p_(); } - const mln_psite(S)& p() const { return exact(this)->current_p_(); } - - mln_psite(S)& current_p_() { return p_; } - const mln_psite(S)& current_p_() const { return p_; } - protected: site_iterator_base(); /// The target. const S* s_; - - private: - - /// The psite designated by this iterator. - mln_psite(S) p_; }; @@ -146,7 +126,7 @@ site_iterator_base<S, E>::to_site() const { mln_precondition(exact(*this).is_valid()); // FIXME: OK? - return internal::to_site( p() ); + return internal::to_site( exact(this)->p_hook_() ); } template <typename S, typename E> @@ -154,7 +134,7 @@ const mln_psite(S)& site_iterator_base<S, E>::unproxy() const { - return p(); + return exact(this)->p_hook_(); } template <typename S, typename E> @@ -165,19 +145,6 @@ return s_; } - template <typename S, typename E> - inline - void - site_iterator_base<S, E>::change_target(const S& s) - { - s_ = & s; - // p might be also updated since it can hold a pointer towards - // the set it designates, so: - if_possible::change_target(p(), s); - // Last: - this->invalidate(); - } - #endif // ! MLN_INCLUDE_ONLY } // end of namespace internal Index: mln/core/internal/site_set_iterator_base.hh --- mln/core/internal/site_set_iterator_base.hh (revision 2067) +++ mln/core/internal/site_set_iterator_base.hh (working copy) @@ -48,13 +48,25 @@ * Parameter \c S is the targeted site set type. */ template <typename S, typename E> - struct site_set_iterator_base : site_iterator_base<S, E> + class site_set_iterator_base : public site_iterator_base<S, E> { + public: + /// Give the site set that this iterator browses. const S& site_set() const; + /// Hook to the current location. + const mln_psite(S)& p_hook_() const; + + /// Change the site set targeted by this iterator. + void change_target(const S& s); + protected: + /// The psite designated by this iterator. + mln_psite(S) p_; + + /// Constructor without argument. site_set_iterator_base(); }; @@ -76,6 +88,27 @@ return *this->s_; } + template <typename S, typename E> + inline + void + site_set_iterator_base<S, E>::change_target(const S& s) + { + this->s_ = & s; + // p might be also updated since it can hold a pointer towards + // the set it designates, so: + if_possible::change_target(p_, s); + // Last: + this->invalidate(); + } + + template <typename S, typename E> + inline + const mln_psite(S)& + site_set_iterator_base<S, E>::p_hook_() const + { + return p_; + } + #endif // ! MLN_INCLUDE_ONLY } // end of namespace internal Index: mln/core/internal/piter_adaptor.hh --- mln/core/internal/piter_adaptor.hh (revision 2067) +++ mln/core/internal/piter_adaptor.hh (working copy) @@ -31,10 +31,14 @@ /*! \file mln/core/internal/piter_adaptor.hh * * \brief Definition of iterators on points of boxes. + * + * \todo Rename as site_iterator_adaptor_base. + * + * \todo Distinguish between adaptors of site_set_iterator, + * site_relative_iterator, etc. (?) */ -# include <mln/core/internal/site_set_iterator_base.hh> -# include <mln/core/concept/box.hh> +# include <mln/core/internal/site_iterator_base.hh> namespace mln @@ -44,14 +48,18 @@ { /*! \internal A base class for point iterator adaptors. + * * Parameter \c Pi is the type of the point iterator adaptee; * parameter E is the exact type. */ - template <typename Pi, typename E> - class piter_adaptor_ : public internal::site_set_iterator_base< mln_pset(Pi), E > + template <typename Pi, typename S, typename E> + class piter_adaptor_ : public internal::site_iterator_base< S, E > { public: + /// Constructor without argument. + piter_adaptor_(); + /// Constructor from a point iterator \p piter. piter_adaptor_(const Pi& piter); @@ -67,54 +75,86 @@ /// Go to the next point. void next_(); - protected: + /// Hook to the current location. + const mln_psite(S)& p_hook_() const; - Pi piter_; // own copy - }; + /// Change the site set targeted by this iterator. + void change_target(const S& s); + protected: + /// The adaptee site iterator. + Pi pi_; // own copy + }; # ifndef MLN_INCLUDE_ONLY - template <typename Pi, typename E> + template <typename Pi, typename S, typename E> inline - piter_adaptor_<Pi,E>::piter_adaptor_(const Pi& piter) - : piter_(piter) + piter_adaptor_<Pi,S,E>::piter_adaptor_() + { + } + + template <typename Pi, typename S, typename E> + inline + piter_adaptor_<Pi,S,E>::piter_adaptor_(const Pi& pi) + : pi_(pi) { invalidate_(); } - template <typename Pi, typename E> + template <typename Pi, typename S, typename E> inline bool - piter_adaptor_<Pi,E>::is_valid_() const + piter_adaptor_<Pi,S,E>::is_valid_() const + { + return pi_.is_valid(); + } + + template <typename Pi, typename S, typename E> + inline + void + piter_adaptor_<Pi,S,E>::invalidate_() { - return piter_.is_valid(); + pi_.invalidate(); } - template <typename Pi, typename E> + template <typename Pi, typename S, typename E> inline void - piter_adaptor_<Pi,E>::invalidate_() + piter_adaptor_<Pi,S,E>::start_() { - piter_.invalidate(); + pi_.start(); } - template <typename Pi, typename E> + template <typename Pi, typename S, typename E> inline void - piter_adaptor_<Pi,E>::start_() + piter_adaptor_<Pi,S,E>::next_() + { + pi_.next(); + } + + template <typename Pi, typename S, typename E> + inline + const mln_psite(S)& + piter_adaptor_<Pi,S,E>::p_hook_() const { - piter_.start(); + return pi_.p_hook_(); } - template <typename Pi, typename E> + template <typename Pi, typename S, typename E> inline void - piter_adaptor_<Pi,E>::next_() + piter_adaptor_<Pi,S,E>::change_target(const S& s) { - piter_.next(); + this->s_ = & s; + // p might be also updated since it can hold a pointer towards + // the set it designates, so: + pi_.change_target( exact(this)->pi_set_from_(s) ); + // Last: + this->invalidate(); } # endif // ! MLN_INCLUDE_ONLY Index: mln/core/neighb.hh --- mln/core/neighb.hh (revision 2067) +++ mln/core/neighb.hh (working copy) @@ -37,6 +37,9 @@ # include <mln/core/internal/basic_window_impl.hh> # include <mln/core/internal/neighborhood_impl_mixin.hh> +# include <mln/core/window.hh> +# include <mln/literal/zero.hh> + namespace mln { @@ -62,6 +65,16 @@ // Overridden from internal::basic_window_impl so that it also // inserts \a -dp. neighb<D>& insert_(const D& dp); + + typedef mln::window<D> window; + + window to_window() const + { + window tmp(this->dps_); + D zero = literal::zero; + tmp.insert(zero); + return tmp; + } }; Index: mln/core/box_piter.hh --- mln/core/box_piter.hh (revision 2067) +++ mln/core/box_piter.hh (working copy) @@ -51,7 +51,7 @@ box_fwd_piter_<P> > { typedef box_fwd_piter_<P> self_; - typedef internal::site_iterator_base< box<P>, self_ > super_; + typedef internal::site_set_iterator_base< box<P>, self_ > super_; public: @@ -79,9 +79,8 @@ /// Go to the next point. void next_(); - using super_::p; - protected: + using super_::p_; using super_::s_; }; @@ -94,11 +93,11 @@ * \see mln::box_ */ template <typename P> - class box_bkd_piter_ : public internal::site_iterator_base< box<P>, + class box_bkd_piter_ : public internal::site_set_iterator_base< box<P>, box_bkd_piter_<P> > { typedef box_bkd_piter_<P> self_; - typedef internal::site_iterator_base< box<P>, self_ > super_; + typedef internal::site_set_iterator_base< box<P>, self_ > super_; public: @@ -126,9 +125,8 @@ /// Go to the next point. void next_(); - using super_::p; - protected: + using super_::p_; using super_::s_; }; @@ -158,7 +156,7 @@ bool box_fwd_piter_<P>::is_valid_() const { - return p()[0] != s_->pmax()[0] + 1; + return p_[0] != s_->pmax()[0] + 1; } template <typename P> @@ -166,7 +164,7 @@ void box_fwd_piter_<P>::invalidate_() { - p()[0] = s_->pmax()[0] + 1; + p_[0] = s_->pmax()[0] + 1; } template <typename P> @@ -174,7 +172,7 @@ void box_fwd_piter_<P>::start_() { - p() = s_->pmin(); + p_ = s_->pmin(); } template <typename P> @@ -183,14 +181,14 @@ box_fwd_piter_<P>::next_() { for (int i = dim - 1; i >= 0; --i) - if (p()[i] == s_->pmax()[i]) - p()[i] = s_->pmin()[i]; + if (p_[i] == s_->pmax()[i]) + p_[i] = s_->pmin()[i]; else { - ++p()[i]; + ++p_[i]; break; } - if (p() == s_->pmin()) + if (p_ == s_->pmin()) invalidate_(); } @@ -215,7 +213,7 @@ bool box_bkd_piter_<P>::is_valid_() const { - return p()[0] != s_->pmin()[0] - 1; + return p_[0] != s_->pmin()[0] - 1; } template <typename P> @@ -223,7 +221,7 @@ void box_bkd_piter_<P>::invalidate_() { - p()[0] = s_->pmin()[0] - 1; + p_[0] = s_->pmin()[0] - 1; } template <typename P> @@ -231,7 +229,7 @@ void box_bkd_piter_<P>::start_() { - p() = s_->pmax(); + p_ = s_->pmax(); } template <typename P> @@ -240,14 +238,14 @@ box_bkd_piter_<P>::next_() { for (int i = dim - 1; i >= 0; --i) - if (p()[i] == s_->pmin()[i]) - p()[i] = s_->pmax()[i]; + if (p_[i] == s_->pmin()[i]) + p_[i] = s_->pmax()[i]; else { - --p()[i]; + --p_[i]; break; } - if (p() == s_->pmax()) + if (p_ == s_->pmax()) invalidate_(); } Index: mln/core/pset_if_piter.hh --- mln/core/pset_if_piter.hh (revision 2067) +++ mln/core/pset_if_piter.hh (working copy) @@ -32,16 +32,17 @@ * * \brief Definition of iterators on pset_if<S,F>. * - * \todo See todo in site_iterator_base.hh + * \todo pset_if_bkd_piter_. */ -# include <mln/core/internal/site_set_iterator_base.hh> +# include <mln/core/internal/piter_adaptor.hh> # include <mln/core/pset_if.hh> namespace mln { + /*! \brief A generic forward iterator on points of subsets. * * Parameter \c S is a point set type; parameter F is a function @@ -51,8 +52,9 @@ */ template <typename S, typename F> class pset_if_fwd_piter_ - : public internal::site_set_iterator_base< pset_if<S,F>, - pset_if_fwd_piter_<S,F> > + : public internal::piter_adaptor_< mln_fwd_piter(S), // Adaptee. + pset_if<S,F>, // Site_Set. + pset_if_fwd_piter_<S,F> > // Exact. { public: @@ -62,26 +64,14 @@ /// Constructor from a site set. pset_if_fwd_piter_(const pset_if<S,F>& s); - /// Test if the iterator is valid. - bool is_valid_() const; - - /// Invalidate the iterator. - void invalidate_(); - /// Start an iteration. void start_(); /// Go to the next point. void next_(); - mln_fwd_piter(S)& hook_pi_() { return pi_; } - - mln_psite(S)& current_p_() { return pi_.p(); } - const mln_psite(S)& current_p_() const { return pi_.p(); } - - private: - - mln_fwd_piter(S) pi_; + /// The set site targeted by pi_. + const S& pi_set_from_(const pset_if<S,F>& s) const; }; @@ -109,51 +99,37 @@ inline pset_if_fwd_piter_<S,F>::pset_if_fwd_piter_(const pset_if<S,F>& s) { - pi_.change_target(s.overset()); this->change_target(s); } template <typename S, typename F> inline - bool - pset_if_fwd_piter_<S,F>::is_valid_() const - { - return pi_.is_valid(); - } - - template <typename S, typename F> - inline void - pset_if_fwd_piter_<S,F>::invalidate_() + pset_if_fwd_piter_<S,F>::start_() { - pi_.invalidate(); + this->pi_.start(); + while (this->pi_.is_valid() && ! this->s_->pred(this->pi_)) + this->pi_.next(); } template <typename S, typename F> inline void - pset_if_fwd_piter_<S,F>::start_() + pset_if_fwd_piter_<S,F>::next_() { - pi_.start(); - while (pi_.is_valid() && ! this->s_->pred(pi_)) - pi_.next(); -// if (is_valid_()) -// this->p_ = pi_; + do + this->pi_.next(); + while (this->pi_.is_valid() && ! this->s_->pred(this->pi_)); } template <typename S, typename F> inline - void - pset_if_fwd_piter_<S,F>::next_() + const S& + pset_if_fwd_piter_<S,F>::pi_set_from_(const pset_if<S,F>& s) const { - do - pi_.next(); - while (pi_.is_valid() && ! this->s_->pred(pi_)); -// if (is_valid_()) -// this->p_ = pi_; + return s.overset(); } - // FIXME: pset_if_bkd_piter_<S,F> Index: mln/core/p_array_piter.hh --- mln/core/p_array_piter.hh (revision 2067) +++ mln/core/p_array_piter.hh (working copy) @@ -72,7 +72,6 @@ int index() const; protected: - using super::p_; using super::s_; }; @@ -117,7 +116,6 @@ int index() const; protected: - using super::p_; using super::s_; }; Index: mln/core/dpsites_piter.hh --- mln/core/dpsites_piter.hh (revision 2067) +++ mln/core/dpsites_piter.hh (working copy) @@ -76,8 +76,6 @@ /// Compute the current psite. mln_psite(V) compute_p_() const; - dpsites_fwd_piter<V>& update(); - protected: unsigned i_; @@ -119,8 +117,6 @@ /// Compute the current psite. mln_psite(V) compute_p_() const; - dpsites_fwd_piter<V>& update(); - protected: int i_; @@ -183,17 +179,6 @@ return *this->c_ + this->s_->std_vector()[i_]; } - template <typename V> - inline - dpsites_fwd_piter<V>& - dpsites_fwd_piter<V>::update() - { - mln_precondition(this->s_ && this->c_); - this->p_ = compute_p_(); - mln_postcondition(this->is_valid()); - return *this; - } - // Backward. @@ -247,17 +232,6 @@ return *this->c_ + this->s_->std_vector()[i_]; } - template <typename V> - inline - dpsites_fwd_piter<V>& - dpsites_bkd_piter<V>::update() - { - mln_precondition(this->s_ && this->c_); - this->p_ = compute_p_(); - mln_postcondition(this->is_valid()); - return *this; - } - # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln Index: mln/core/concept/neighborhood.hh --- mln/core/concept/neighborhood.hh (revision 2067) +++ mln/core/concept/neighborhood.hh (working copy) @@ -32,7 +32,7 @@ * \brief Definition of the concept of mln::Neighborhood. */ -# include <mln/core/concept/window.hh> +# include <mln/core/concept/object.hh> namespace mln @@ -55,7 +55,7 @@ * class contents. */ template <typename E> - struct Neighborhood : public Window<E> + struct Neighborhood : public Object<E> { typedef Neighborhood<void> category; @@ -63,6 +63,9 @@ typedef niter; typedef fwd_niter; typedef bkd_niter; + + typedef window; + window to_window() const; */ protected: @@ -79,6 +82,10 @@ typedef mln_niter(E) niter; typedef mln_fwd_niter(E) fwd_niter; typedef mln_bkd_niter(E) bkd_niter; + + typedef mln_window(E) window; + window (E::*m)() const = & E::to_window; + m = 0; } # endif // ! MLN_INCLUDE_ONLY Index: mln/morpho/dilation_elementary.hh --- mln/morpho/dilation_elementary.hh (revision 0) +++ mln/morpho/dilation_elementary.hh (revision 0) @@ -0,0 +1,80 @@ +// Copyright (C) 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 +// 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_MORPHO_DILATION_ELEMENTARY_HH +# define MLN_MORPHO_DILATION_ELEMENTARY_HH + +/// \file mln/morpho/dilation_elementary.hh +/// \brief Morphological elementary dilation. + +# include <mln/morpho/dilation.hh> + + +namespace mln +{ + + namespace morpho + { + + /// Morphological elementary dilation. + /// + /// \param[in] input The image to be dilated. + /// \param[in] nbh The neighborhood to consider. + /// + /// The structuring element is the neighborhood + the center site. + /// + /// \{ + template <typename I, typename N> + mln_concrete(I) + dilation_elementary(const Image<I>& input, const Neighborhood<N>& nbh); + /// \} + + +# ifndef MLN_INCLUDE_ONLY + + template <typename I, typename N> + mln_concrete(I) + dilation_elementary(const Image<I>& input, const Neighborhood<N>& nbh) + { + trace::entering("morpho::dilation_elementary"); + mln_precondition(exact(input).has_data()); + // FIXME: mln_precondition(! exact(nbh).is_empty()); + + mln_concrete(I) output = dilation(input, nbh.to_window()); + + trace::exiting("morpho::dilation_elementary"); + return output; + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::morpho + +} // end of namespace mln + + +#endif // ! MLN_MORPHO_DILATION_ELEMENTARY_HH
participants (1)
-
Thierry Geraud