
https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Make the tricky morpho example fully work. * mln/core/site_set/p_centered.hh: New. * mln/core/site_set/all.hh: Update. * mln/core/image/extended.hh: New. * mln/core/image/extension_fun.hh, * mln/core/image/extension_ima.hh, * mln/core/image/extension_val.hh (ch_value): New. The extension is propagated to a concrete type iff it can work. (todo): New. * mln/core/image/image1d.hh, * mln/core/image/image3d.hh (line_piter): De-activate cause it does not work yet. * mln/core/point.hh (point): Add explicit to the 1D ctor. * mln/level/sort_psites.hh: Update. * mln/border/fill.hh, * mln/border/mirror.hh: Update. * mln/fun/i2v/array.hh: New. * mln/win/all.hh: Update. * mln/win/multiple.hh (i_): Fix warning. * doc/examples/tuto_bis.cc: Update. doc/examples/tuto_bis.cc | 224 +++++++++++++++++------------ mln/border/fill.hh | 4 mln/border/mirror.hh | 30 ++-- mln/core/image/extended.hh | 226 ++++++++++++++++++++++++++++++ mln/core/image/extension_fun.hh | 11 + mln/core/image/extension_ima.hh | 11 + mln/core/image/extension_val.hh | 11 + mln/core/image/image1d.hh | 1 mln/core/image/image3d.hh | 4 mln/core/point.hh | 2 mln/core/site_set/all.hh | 14 + mln/core/site_set/p_centered.hh | 300 ++++++++++++++++++++++++++++++++++++++++ mln/fun/i2v/array.hh | 147 +++++++++++++++++++ mln/level/sort_psites.hh | 13 + mln/win/all.hh | 4 mln/win/multiple.hh | 2 16 files changed, 877 insertions(+), 127 deletions(-) Index: doc/examples/tuto_bis.cc --- doc/examples/tuto_bis.cc (revision 2280) +++ doc/examples/tuto_bis.cc (working copy) @@ -2,37 +2,28 @@ # include <mln/core/image/image2d.hh> # include <mln/core/image/image_if.hh> +# include <mln/core/image/extended.hh> # include <mln/core/routine/extend.hh> # include <mln/core/alias/window2d.hh> +# include <mln/core/alias/neighb2d.hh> # include <mln/make/dual_neighb2d.hh> +# include <mln/core/site_set/p_centered.hh> +# include <mln/literal/origin.hh> -# include <mln/debug/println.hh> +# include <mln/accu/min_max.hh> +# include <mln/accu/mean.hh> + +# include <mln/fun/i2v/array.hh> # include <mln/fun/p2v/iota.hh> # include <mln/level/paste.hh> # include <mln/level/fill.hh> +# include <mln/level/transform.hh> -# include <mln/accu/min_max.hh> -# include <mln/morpho/meyer_wst.hh> - - -/* -# include <vector> - -# include <mln/core/image/sub_image.hh> - -# include <mln/core/alias/neighb2d.hh> -# include <mln/core/alias/window2d.hh> -# include <mln/convert/to_window.hh> - -# include <mln/morpho/dilation.hh> # include <mln/morpho/meyer_wst.hh> -# include <mln/level/transform.hh> -# include <mln/accu/mean.hh> - -*/ +# include <mln/debug/println.hh> /* @@ -63,18 +54,49 @@ } // mln::level + +} // mln + +*/ + + +namespace mln +{ + + namespace border + { + + template <typename I> + void + fill(I& ima, const mln_value(I)& v) + { + const int nrows = ima.nrows(); + const int ncols = ima.ncols(); + for (int r = -1; r <= nrows; ++r) + { + ima.at(r, -1) = v; + ima.at(r, ncols) = v; + } + for (int c = -1; c <= ncols; ++c) + { + ima.at(-1, c) = v; + ima.at(nrows, c) = v; + } + } + + } // mln::border + namespace accu { - template <typename A_, typename I, typename L, typename R> + template <typename A_, typename I, typename L, typename V> inline void compute(const Image<I>& input_, const Image<L>& label_, - std::vector<R>& v) + V& v) { mlc_is_a(A_, Meta_Accumulator)::check(); - trace::entering("accu::compute"); const I& input = exact(input_); @@ -89,51 +111,13 @@ a[label(p)].take(input(p)); for (unsigned l = 1; l < n; ++l) - v[l] = a[l].to_result(); + v(l) = a[l]; trace::exiting("accu::compute"); } } // mln::accu -} // mln - - -*/ - - -namespace mln -{ - - template <typename W, typename S> - void convert_to_site_set(const Window<W>& win, - const mln_psite(W)& p, - Site_Set<S>& s_) - { - std::cout << "win -> pset" << std::endl; - - S& s = exact(s_); - s.clear(); - - mln_qiter(W) q(exact(win), p); - for_all(q) - exact(s).insert(q); - } - - template <typename N, typename S> - void convert_to_site_set(const Neighborhood<N>& nbh, - const mln_psite(N)& p, - Site_Set<S>& s_) - { - S& s = exact(s_); - s.clear(); - - mln_niter(N) n(exact(nbh), p); - for_all(n) - exact(s).insert(n); - } - - namespace morpho { @@ -157,42 +141,75 @@ return output; } + template <typename I, typename N> + mln_concrete(I) + dilation(const I& input, const N& nbh) + { + typedef mln_value(I) V; + // extension::fill(input, mln_min(V)); - } // mln::morpho + mln_concrete(I) output; + initialize(output, input); + accu::max_<V> m; + mln_piter(I) p(input.domain()); + mln_niter(N) n(nbh, p); + for_all(p) + { + m.init(); + for_all(n) if (input.has(n)) + m.take(input(n)); + output(p) = m; + } + return output; + } + + } // mln::morpho } // mln + // Functions +inline bool is_row_odd(const mln::point2d& p) { return p.row() % 2; } +inline bool is_cell(const mln::point2d& p) { return p.row() % 2 == 0 && p.col() % 2 == 0; } +inline bool is_edge(const mln::point2d& p) { return p.row() % 2 + p.col() % 2 == 1; } +inline bool is_point(const mln::point2d& p) { return p.row() % 2 && p.col() % 2; } +inline +bool is_not_edge(const mln::point2d& p) +{ + return ! is_edge(p); +} + int main() { using namespace mln; + // e2c bool e2c_h[] = { 0, 1, 0, @@ -221,6 +238,16 @@ +// { +// p_centered<e2e_t::window> wc(e2e.to_window(), literal::origin); +// std::cout << wc << std::endl; + +// p_set<point2d> s; +// s += wc; +// std::cout << s << std::endl; +// } + + image2d<int> ima(3, 5); @@ -244,29 +271,26 @@ // 1 1 - unsigned nbasins; - mln_VAR(wst, morpho::meyer_wst(edge, e2e, nbasins)); - // ^^^ - // edge -> neighboring edges - debug::println(wst); - // 2 2 - // 0 0 0 - // 1 1 - - std::cout << nbasins << " bassins" << std::endl; - // 2 bassins - - + image2d<unsigned> label(ima.bbox(), 1); + border::fill(label, 0); + level::fill(label, 9); + debug::println(label); + // 9 9 9 9 9 + // 9 9 9 9 9 + // 9 9 9 9 9 - /* - window2d c4 = convert::to_window(mln::c4()); + mln_VAR(wst, label | is_edge); + debug::println(wst); + // 9 9 + // 9 9 9 + // 9 9 unsigned nbasins; - mln_VAR(wst, morpho::meyer_wst(edge, nbh_e2e, nbasins)); - // ^^^^^^^ - // edge -> neighbooring edges + level::fill(wst, morpho::meyer_wst(edge, e2e, nbasins)); + // ^^^ + // edge -> neighboring edges debug::println(wst); // 2 2 // 0 0 0 @@ -276,11 +300,15 @@ // 2 bassins + + // '0' IS THE TAG VALUE FOR THE WATERSHED LINE // THE OTHER VALUES ARE THE REGION LABELS - std::cout << "the watershed line = " << (wst | 0).domain() << std::endl; + mln_VAR(wst_line, wst | (pw::value(wst) == pw::cst(0u))); // FIXME: wst | 0 + std::cout << "the watershed line = " << wst_line.domain() << std::endl + << std::endl; // the watershed line = {(1,0)(1,2)(1,4)} // ^^^^^ // meaning (row = 1, col = 0) @@ -298,22 +326,31 @@ // row - // YET THOSE VALUES ARE ON EDGES, NOT ON CELLS... + // YET THOSE VALUES ARE ON EDGES, NOT ON CELLS... - mln_VAR(label, wst.full()); debug::println(label); - // 0 2 0 2 0 - // 0 0 0 0 0 - // 0 1 0 1 0 + // 9 2 9 2 9 + // 0 9 0 9 0 + // 9 1 9 1 9 - level::paste(morpho::dilation(label | is_cell, c4), label); + + mln_VAR(lab, label | is_cell); + debug::println(lab); + // 9 9 9 + // + // 9 9 9 + + level::paste(morpho::dilation(extend(lab, pw::value(label)), + c4()), + label); debug::println(label); // 2 2 2 2 2 - // 0 0 0 0 0 + // 0 9 0 9 0 // 1 1 1 1 1 - debug::println(label | is_cell); + + debug::println(lab); // 2 2 2 // // 1 1 1 @@ -332,18 +369,17 @@ // NOW WE WANT TO MODIFY THE INPUT IMAGE TO FLATTEN REGIONS... - std::vector<int> m(nbasins + 1); + fun::i2v::array<int> m(nbasins + 1); accu::compute<accu::mean>(cell, label, m); for (unsigned i = 1; i <= nbasins; ++i) - std::cout << "mean value of basin " << i << " is " << m[i] << std::endl; + std::cout << "mean value of basin #" << i << " is " << m(i) << std::endl; - level::fill(cell, level::transform(label, m)); + level::fill(cell, level::transform(lab, m)); debug::println(cell); // 2 2 2 // // 5 5 5 - // DONE! - */ + // DONE! } Index: mln/core/site_set/all.hh --- mln/core/site_set/all.hh (revision 2280) +++ mln/core/site_set/all.hh (working copy) @@ -31,18 +31,24 @@ /*! \file mln/core/site_set/all.hh * * \brief File that includes all site_set types. - * - * \todo Make it effective after having moved image-defining files. */ -// # include <mln/core/site_set/p_array_of.hh> // FIXME: Uncomment. +# include <mln/core/site_set/box.hh> +# include <mln/core/site_set/line2d.hh> +# include <mln/core/site_set/p_array.hh> +# include <mln/core/site_set/p_centered.hh> +# include <mln/core/site_set/p_if.hh> # include <mln/core/site_set/p_image.hh> # include <mln/core/site_set/p_key.hh> # include <mln/core/site_set/p_mutable_array_of.hh> +# include <mln/core/site_set/p_priority.hh> +# include <mln/core/site_set/p_queue.hh> +# include <mln/core/site_set/p_queue_fast.hh> +# include <mln/core/site_set/p_run.hh> +# include <mln/core/site_set/p_set.hh> # include <mln/core/site_set/p_set_of.hh> # include <mln/core/site_set/p_vaccess.hh> -// FIXME: Complete... #endif // ! MLN_CORE_SITE_SET_ALL_HH Index: mln/core/site_set/p_centered.hh --- mln/core/site_set/p_centered.hh (revision 0) +++ mln/core/site_set/p_centered.hh (revision 0) @@ -0,0 +1,300 @@ +// 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 +// 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_SITE_SET_P_CENTERED_HH +# define MLN_CORE_SITE_SET_P_CENTERED_HH + +/*! \file mln/core/site_set/p_centered.hh + * + * \brief This file defines the site set corresponding to a window + * centered on a site. + * + * \todo Add the bkd iter. + * \todo Code is_valid() and change_target() for the site set. + */ + +# include <mln/core/internal/site_set_base.hh> + + +namespace mln +{ + + // Fwd decls. + template <typename W> class p_centered; + template <typename W> class p_centered_piter; + + + namespace trait + { + + template <typename W> + struct site_set_< p_centered<W> > + { + typedef trait::site_set::nsites::unknown nsites; + typedef trait::site_set::bbox::unknown bbox; + typedef trait::site_set::contents::fixed contents; + typedef trait::site_set::arity::unique arity; + }; + +// template <typename W> +// struct set_precise_unary_< op::ord, p_centered<W> > +// { +// typedef set_precise_unary_< op::ord, p_centered<W> > ret; // Itself. +// bool strict(const p_centered<W>& lhs, const p_centered<W>& rhs) const; +// }; + + } // end of namespace mln::trait + + + template <typename W> + class p_centered : public internal::site_set_base_< mln_psite(W), p_centered<W> >, + private mlc_is_a(W, Window)::check_t + { + public: + + /// Psite associated type. + typedef mln_psite(W) psite; + + /// Site associated type. + typedef mln_site(W) site; + + + /// Element associated type. + typedef psite element; + + + /// Forward Site_Iterator associated type. + typedef p_centered_piter<W> fwd_piter; + + /// Backward Site_Iterator associated type. + typedef p_centered_piter<W> bkd_piter; // FIXME + + /// Site_Iterator associated type. + typedef fwd_piter piter; + + + /// Constructor without argument. + p_centered(); + + /// Constructor from a window \p win and a center \p c. + p_centered(const W& win, const mln_psite(W)& c); + + + /// Test if \p p belongs to the box. + template <typename P> + bool has(const P& p) const; + + /// Test if this site set is initialized. + bool is_valid() const; + + /// Return the size of this site set in memory. + std::size_t memory_size() const; + + /// Give the center of this site set. + const mln_psite(W)& center() const; + + /// Give the window this site set is defined upon. + const W& window() const; + + protected: + + W win_; + mln_psite(W) c_; + }; + + + template <typename W> + class p_centered_piter : public internal::site_set_iterator_base< p_centered<W>, + p_centered_piter<W> > + { + typedef p_centered_piter<W> self_; + typedef internal::site_set_iterator_base< p_centered<W>, self_ > super_; + public: + + /// Constructor without argument. + p_centered_piter(); + + /// Constructor. + p_centered_piter(const p_centered<W>& s); + + /// 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: + using super_::p_; + using super_::s_; + + mln_fwd_qiter(W) q_; + }; + + + +# ifndef MLN_INCLUDE_ONLY + + // p_centered<W> + + template <typename W> + inline + bool + p_centered<W>::is_valid() const + { + return true; // FIXME + } + + template <typename W> + inline + p_centered<W>::p_centered() + { + } + + template <typename W> + inline + p_centered<W>::p_centered(const W& win, const mln_psite(W)& c) + : win_(win), + c_(c) + { + mln_precondition(is_valid()); + } + + template <typename W> + template <typename P> + inline + bool + p_centered<W>::has(const P&) const + { + mln_precondition(is_valid()); + return true; // FIXME + } + + template <typename W> + inline + std::size_t + p_centered<W>::memory_size() const + { + return sizeof(*this); + } + + template <typename W> + inline + const mln_psite(W)& + p_centered<W>::center() const + { + return c_; + } + + template <typename W> + inline + const W& + p_centered<W>::window() const + { + return win_; + } + +// namespace trait +// { + +// template <typename W> +// inline +// bool +// set_precise_unary_< op::ord, p_centered<W> >::strict(const p_centered<W>& lhs, const p_centered<W>& rhs) const +// { +// // Lexicographical over "pmin then pmax". +// return util::ord_lexi_strict(lhs.pmin(), lhs.pmax(), +// rhs.pmin(), rhs.pmax()); +// } + +// } // end of namespace mln::trait + + + // p_centered_piter<W> + + template <typename W> + inline + p_centered_piter<W>::p_centered_piter() + { + } + + template <typename W> + inline + p_centered_piter<W>::p_centered_piter(const p_centered<W>& s) + { + this->change_target(s); + q_.center_at(s.center()); + q_.change_target(s.window()); + } + + template <typename W> + inline + bool + p_centered_piter<W>::is_valid_() const + { + return q_.is_valid(); + } + + template <typename W> + inline + void + p_centered_piter<W>::invalidate_() + { + q_.invalidate(); + } + + template <typename W> + inline + void + p_centered_piter<W>::start_() + { + q_.start(); + if (is_valid_()) + p_ = q_; + } + + template <typename W> + inline + void + p_centered_piter<W>::next_() + { + q_.next(); + if (is_valid_()) + p_ = q_; + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + + +#endif // ! MLN_CORE_SITE_SET_P_CENTERED_HH Index: mln/core/image/extension_fun.hh --- mln/core/image/extension_fun.hh (revision 2280) +++ mln/core/image/extension_fun.hh (working copy) @@ -35,10 +35,10 @@ * with a function. * * \todo Deal with two-ways functions... + * \todo Use an envelop as lvalue to test extension writing. */ # include <mln/core/internal/image_identity.hh> -# include <mln/metal/converts_to.hh> @@ -81,6 +81,15 @@ typedef trait::image::ext_io::read_only ext_io; }; + template <typename I, typename F, typename V> + struct ch_value< extension_fun<I, F>, V > + { + typedef mlc_converts_to(mln_result(F), V) keep_ext; + typedef mln_ch_value(I, V) Iv; + typedef extension_fun<Iv, F> Iv_ext; + typedef mlc_if(keep_ext, Iv_ext, Iv) ret; + }; + } // end of namespace mln::trait Index: mln/core/image/extended.hh --- mln/core/image/extended.hh (revision 0) +++ mln/core/image/extended.hh (revision 0) @@ -0,0 +1,226 @@ +// Copyright (C) 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 +// 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_IMAGE_EXTENDED_HH +# define MLN_CORE_IMAGE_EXTENDED_HH + +/*! + * \file mln/core/image/extended.hh + * + * \brief Definition of morpher that makes an image become restricted + * given by a point set. + * + * \todo Add a special case for "ima | box"; think about some other + * special cases... + */ + +# include <mln/core/internal/image_domain_morpher.hh> +# include <mln/core/site_set/box.hh> + + +namespace mln +{ + + + // Forward declaration. + template <typename I> class extended; + + + namespace internal + { + + /// Data structure for \c mln::extended<I>. + template <typename I> + struct data< extended<I> > + { + data(I& ima, const box<mln_site(I)>& b_); + + I ima_; + box<mln_site(I)> b_; + }; + + } // end of namespace mln::internal + + + + namespace trait + { + + template <typename I> + struct image_< extended<I> > : default_image_morpher< I, + mln_value(I), + extended<I> > + { + typedef trait::image::category::domain_morpher category; + + typedef trait::image::ext_domain::none ext_domain; + typedef trait::image::ext_value::irrelevant ext_value; + typedef trait::image::ext_io::irrelevant ext_io; + + typedef trait::image::value_storage::disrupted value_storage; + }; + + } // end of namespace mln::trait + + + + // FIXME: Doc! + + template <typename I> + struct extended : public internal::image_domain_morpher< I, + box<mln_site(I)>, + extended<I> >, + private mlc_not_equal(mln_trait_image_ext_domain(I), + trait::image::ext_domain::none)::check_t + { + /// Skeleton. + typedef tag::image_<I> skeleton; // This property is lost! + + /// Constructor without argument. + extended(); + + /// Constructor. + extended(I& ima, const box<mln_site(I)>& ); + + /// Initialization. + void init_(I& ima, const box<mln_site(I)>& b); + + /// Give the definition domain. + const box<mln_site(I)>& domain() const; + }; + + + + template <typename I, typename J> + void init_(tag::image_t, extended<I>& target, const J& model); + + + template <typename I, typename B> + extended<const I> + extended_to(const Image<I>& ima, const Box<B>& b); + + template <typename I, typename B> + extended<I> + extended_to(Image<I>& ima, const Box<B>& b); + + + +# ifndef MLN_INCLUDE_ONLY + + // init_ + + template <typename I, typename J> + inline + void init_(tag::image_t, extended<I>& target, const J& model) + { + I ima; + init_(tag::image, ima, model); + box<mln_site(I)> b; + init_(tag::bbox, b, model); + target.init_(ima, b); + } + + + // internal::data< extended<I> > + + namespace internal + { + + template <typename I> + inline + data< extended<I> >::data(I& ima, const box<mln_site(I)>& b) + : ima_(ima), + b_(b) + { + } + + } // end of namespace mln::internal + + + // extended<I> + + template <typename I> + inline + extended<I>::extended() + { + } + + template <typename I> + inline + extended<I>::extended(I& ima, const box<mln_site(I)>& b) + { + init_(ima, b); + } + + template <typename I> + inline + void + extended<I>::init_(I& ima, const box<mln_site(I)>& b) + { + mln_precondition(! this->has_data()); + this->data_ = new internal::data< extended<I> >(ima, b); + } + + template <typename I> + inline + const box<mln_site(I)>& + extended<I>::domain() const + { + return this->data_->b_; + } + + + // extended_to + + template <typename I, typename B> + extended<const I> + extended_to(const Image<I>& ima, const Box<B>& b) + { + mlc_not_equal(mln_trait_image_ext_domain(I), + trait::image::ext_domain::none)::check(); + mln_precondition(exact(ima).has_data()); + extended<const I> tmp(exact(ima), exact(b)); + return tmp; + } + + template <typename I, typename B> + extended<I> + extended_to(Image<I>& ima, const Box<B>& b) + { + mlc_not_equal(mln_trait_image_ext_domain(I), + trait::image::ext_domain::none)::check(); + mln_precondition(exact(ima).has_data()); + extended<I> tmp(exact(ima), exact(b)); + return tmp; + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + + +#endif // ! MLN_CORE_IMAGE_EXTENDED_HH Index: mln/core/image/extension_ima.hh --- mln/core/image/extension_ima.hh (revision 2280) +++ mln/core/image/extension_ima.hh (working copy) @@ -35,10 +35,10 @@ * with a function. * * \todo Use the 'instant' mechanism. + * \todo Use an envelop as lvalue to test extension writing. */ # include <mln/core/internal/image_identity.hh> -# include <mln/metal/converts_to.hh> @@ -81,6 +81,15 @@ typedef mln_trait_image_value_io(J) ext_io; }; + template <typename I, typename J, typename V> + struct ch_value< extension_ima<I, J>, V > + { + typedef mlc_converts_to(mln_result(J), V) keep_ext; + typedef mln_ch_value(I, V) Iv; + typedef extension_ima<Iv, J> Iv_ext; + typedef mlc_if(keep_ext, Iv_ext, Iv) ret; + }; + } // end of namespace mln::trait Index: mln/core/image/image1d.hh --- mln/core/image/image1d.hh (revision 2280) +++ mln/core/image/image1d.hh (working copy) @@ -39,7 +39,6 @@ # include <mln/value/set.hh> # include <mln/fun/i2v/all_to.hh> -# include <mln/core/line_piter.hh> // FIXME: Index: mln/core/image/image3d.hh --- mln/core/image/image3d.hh (revision 2280) +++ mln/core/image/image3d.hh (working copy) @@ -40,7 +40,7 @@ # include <mln/value/set.hh> # include <mln/fun/i2v/all_to.hh> -# include <mln/core/line_piter.hh> +// # include <mln/core/line_piter.hh> // FIXME: @@ -131,7 +131,7 @@ typedef dpoint3d dpoint; typedef mln_fwd_piter(box3d) fwd_piter; typedef mln_bkd_piter(box3d) bkd_piter; - typedef line_piter_<point> line_piter; +// typedef line_piter_<point> line_piter; // End of warning. Index: mln/core/image/extension_val.hh --- mln/core/image/extension_val.hh (revision 2280) +++ mln/core/image/extension_val.hh (working copy) @@ -34,10 +34,10 @@ * \brief Definition of a morpher that extends the domain of an image. * * \todo Use the 'instant' mechanism. + * \todo Use an envelop as lvalue to test extension writing. */ # include <mln/core/internal/image_identity.hh> -# include <mln/metal/converts_to.hh> @@ -80,6 +80,15 @@ typedef trait::image::ext_io::read_write ext_io; }; + template <typename I, typename V> + struct ch_value< extension_val<I>, V > + { + typedef mlc_converts_to(mln_value(I), V) keep_ext; + typedef mln_ch_value(I, V) Iv; + typedef extension_val<Iv> Iv_ext; + typedef mlc_if(keep_ext, Iv_ext, Iv) ret; + }; + } // end of namespace mln::trait Index: mln/core/point.hh --- mln/core/point.hh (revision 2280) +++ mln/core/point.hh (working copy) @@ -140,7 +140,7 @@ /// \{ Constructors with different numbers of arguments /// (coordinates) w.r.t. the dimension. - point(C ind); + explicit point(C ind); point(C row, C col); point(C sli, C row, C col); /// \} Index: mln/level/sort_psites.hh --- mln/level/sort_psites.hh (revision 2280) +++ mln/level/sort_psites.hh (working copy) @@ -38,6 +38,7 @@ # include <mln/core/concept/image.hh> # include <mln/convert/to_p_array.hh> # include <mln/histo/compute.hh> +# include <mln/util/ord.hh> namespace mln @@ -89,8 +90,10 @@ bool operator()(const mln_psite(I)& lhs, const mln_psite(I)& rhs) const { - return ima_(lhs) < ima_(rhs) || (ima_(lhs) == ima_(rhs) - && lhs < rhs); + return util::ord_strict(ima_(lhs), ima_(rhs)) + || (ima_(lhs) == ima_(rhs) + && + util::ord_strict(lhs, rhs)); } }; @@ -109,8 +112,10 @@ bool operator()(const mln_psite(I)& lhs, const mln_psite(I)& rhs) const { - return ima_(lhs) > ima_(rhs) || (ima_(lhs) == ima_(rhs) - && lhs > rhs); + return util::ord_strict(ima_(rhs), ima_(lhs)) + || (ima_(lhs) == ima_(rhs) + && + util::ord_strict(rhs, lhs)); } }; Index: mln/border/fill.hh --- mln/border/fill.hh (revision 2280) +++ mln/border/fill.hh (working copy) @@ -77,12 +77,12 @@ for_all (pl) { std::size_t end = ima.index_of_point (pl); - std::memset((void*)&ima[st], + std::memset((void*)&ima.element(st), *(const int*)(&v), end - st); st = end + len_r; } - std::memset((void*)&ima[st], + std::memset((void*)&ima.element(st), *(const int*)(&v), ima.nelements () - st); Index: mln/border/mirror.hh --- mln/border/mirror.hh (revision 2280) +++ mln/border/mirror.hh (working copy) @@ -73,9 +73,10 @@ template <typename I> inline - void mirror_(const box1d&, const I& ima) + void mirror_(const box1d&, const I& ima_) { trace::entering("border::impl::mirror_"); + I& ima = const_cast<I&>(ima_); std::size_t border = ima.border (); std::size_t nbinds = geom::ninds(ima); @@ -90,10 +91,10 @@ { std::size_t i = 0; for (; i < min; ++i) - const_cast<I&>(ima)[border - 1 - i] = ima(point1d(i)); + ima.element(border - 1 - i) = ima(point1d(i)); for (; i < border; ++i) - const_cast<I&>(ima)[border - 1 - i] = ima(point1d(min - 1)); + ima.element(border - 1 - i) = ima(point1d(min - 1)); } /// right border @@ -103,21 +104,22 @@ for (; i < min; ++i, --j) - const_cast<I&>(ima)[border + nbinds + i] = ima(point1d(j)); + ima.element(border + nbinds + i) = ima(point1d(j)); ++j; for (; i < border; ++i) - const_cast<I&>(ima)[border + nbinds + i] = ima(point1d(j)); + ima.element(border + nbinds + i) = ima(point1d(j)); } trace::exiting("border::impl::mirror_"); } template <typename I> inline - void mirror_(const box2d&, const I& ima) + void mirror_(const box2d&, const I& ima_) { trace::entering("border::impl::mirror_"); + I& ima = const_cast<I&>(ima_); std::size_t border = ima.border (); std::size_t nbrows = geom::max_row(ima) - geom::min_row(ima); @@ -129,49 +131,49 @@ // mirror top left corner for (std::size_t i = 0; i < border; ++i) for (std::size_t j = 0; j < border; ++j) - const_cast<I&>(ima)[i * ((nbcols + 1) + 2 * border) + j] = ima[s]; + ima.element(i * ((nbcols + 1) + 2 * border) + j) = ima.element(s); // mirror top left corner s = start + nbcols; for (std::size_t i = 0; i < border; ++i) for (std::size_t j = 1; j <= border; ++j) - const_cast<I&>(ima)[i * ((nbcols + 1) + 2 * border) + (nbcols + border + j)] = ima[s]; + ima.element(i * ((nbcols + 1) + 2 * border) + (nbcols + border + j)) = ima.element(s); // mirror bottom left corner s = start + (nbrows * real_nbcols); for (std::size_t i = 1; i <= border; ++i) for (std::size_t j = 1; j <= border; ++j) - const_cast<I&>(ima)[s - i + (j * (real_nbcols))] = ima[s]; + ima.element(s - i + (j * (real_nbcols))) = ima.element(s); // mirror bottom right corner s = start + (nbrows * real_nbcols) + nbcols; for (std::size_t i = 1; i <= border; ++i) for (std::size_t j = 1; j <= border; ++j) - const_cast<I&>(ima)[s + i + (j * real_nbcols)] = ima[s]; + ima.element(s + i + (j * real_nbcols)) = ima.element(s); // mirror top border s = start; for (std::size_t i = 0; i <= nbcols; ++i) for (std::size_t j = 1; j <= border; ++j) - const_cast<I&>(ima)[s + i - (j * real_nbcols)] = ima[s + i + ((j - 1)* real_nbcols)]; + ima.element(s + i - (j * real_nbcols)) = ima.element(s + i + ((j - 1)* real_nbcols)); // mirror left border s = start; for (std::size_t i = 0; i <= nbrows; ++i) for (std::size_t j = 1; j <= border; ++j) - const_cast<I&>(ima)[s + (i * real_nbcols) - j] = ima[s + (i * real_nbcols) + (j - 1)]; + ima.element(s + (i * real_nbcols) - j) = ima.element(s + (i * real_nbcols) + (j - 1)); // mirror right border s = start; for (std::size_t i = 0; i <= nbrows; ++i) for (std::size_t j = 1; j <= border; ++j) - const_cast<I&>(ima)[s + (i * real_nbcols + nbcols) + j] = ima[s + (i * real_nbcols + nbcols) - (j - 1)]; + ima.element(s + (i * real_nbcols + nbcols) + j) = ima.element(s + (i * real_nbcols + nbcols) - (j - 1)); // mirror bottom border s = start + (nbrows * real_nbcols); for (std::size_t i = 0; i <= nbcols; ++i) for (std::size_t j = 1; j <= border; ++j) - const_cast<I&>(ima)[s + i + (j * real_nbcols)] = ima[s + i - ((j - 1)* real_nbcols)]; + ima.element(s + i + (j * real_nbcols)) = ima.element(s + i - ((j - 1)* real_nbcols)); trace::exiting("border::impl::mirror_"); } Index: mln/fun/i2v/array.hh --- mln/fun/i2v/array.hh (revision 0) +++ mln/fun/i2v/array.hh (revision 0) @@ -0,0 +1,147 @@ +// Copyright (C) 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 +// 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_FUN_I2V_ARRAY_HH +# define MLN_FUN_I2V_ARRAY_HH + +/*! \file mln/fun/i2v/array.hh + * + * \brief FIXME. + */ + +# include <vector> +# include <algorithm> +# include <mln/core/concept/function.hh> + + +namespace mln +{ + + namespace fun + { + + namespace i2v + { + + template <typename T> + class array : public Function_i2v< array<T> > + { + public: + + typedef T result; + + array(); + array(unsigned n); + + void resize(unsigned n); + unsigned size() const; + + T operator()(unsigned i) const; + T& operator()(unsigned i); + + private: + std::vector<T> v_; + }; + + } // end of namespace mln::fun::i2v + + } // end of namespace mln::fun + + +# ifndef MLN_INCLUDE_ONLY + + namespace fun + { + + namespace i2v + { + + template <typename T> + inline + array<T>::array() + { + } + + template <typename T> + inline + array<T>::array(unsigned n) + { + resize(n); + } + + template <typename T> + inline + void + array<T>::resize(unsigned n) + { + v_.resize(n); + } + + template <typename T> + inline + unsigned + array<T>::size() const + { + return v_.size(); + } + + template <typename T> + inline + T + array<T>::operator()(unsigned i) const + { + mln_precondition(i < v_.size()); + return v_[i]; + } + + template <typename T> + inline + T& + array<T>::operator()(unsigned i) + { + mln_precondition(i < v_.size()); + return v_[i]; + } + + } // end of namespace mln::fun::i2v + + } // end of namespace mln::fun + + template <typename T> + inline + fun::i2v::array<T> array(T t) + { + fun::i2v::array<T> tmp(t); + return tmp; + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + + +#endif // ! MLN_FUN_I2V_ARRAY_HH Index: mln/win/all.hh --- mln/win/all.hh (revision 2280) +++ mln/win/all.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 @@ -44,10 +44,12 @@ # include <mln/win/backdiag2d.hh> # include <mln/win/cube3d.hh> +# include <mln/win/cuboid3d.hh> # include <mln/win/diag2d.hh> # include <mln/win/disk2d.hh> # include <mln/win/hline2d.hh> # include <mln/win/line.hh> +# include <mln/win/multiple.hh> # include <mln/win/octagon2d.hh> # include <mln/win/rectangle2d.hh> # include <mln/win/segment1d.hh> Index: mln/win/multiple.hh --- mln/win/multiple.hh (revision 2280) +++ mln/win/multiple.hh (working copy) @@ -119,7 +119,7 @@ mln_psite(W) compute_p_() const; private: - int i_; + unsigned i_; unsigned n_() const; };