Olena-patches
  Threads by month 
                
            - ----- 2025 -----
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2024 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2023 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2022 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2021 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2020 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2019 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2018 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2017 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2016 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2015 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2014 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2013 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2012 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2011 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2010 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2009 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2008 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2007 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2006 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2005 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2004 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 
March 2009
- 9 participants
 - 202 discussions
 
                    
                        https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from  Thierry Geraud  <thierry.geraud(a)lrde.epita.fr>
	Fix missing trace in mln::test routines.
	* mln/level/compare.hh,
	* mln/test/positive.hh,
	* mln/test/predicate.hh: Add trace.
	Upgrade doc style.
	* tests/level/compare.cc: Upgrade doc style.
 mln/level/compare.hh   |   88 +++++++++++++++++++++++++++++--------------------
 mln/test/positive.hh   |   17 ++++++---
 mln/test/predicate.hh  |   37 +++++++++++++++++---
 tests/level/compare.cc |   10 ++---
 4 files changed, 101 insertions(+), 51 deletions(-)
Index: mln/level/compare.hh
--- mln/level/compare.hh	(revision 3524)
+++ mln/level/compare.hh	(working copy)
@@ -1,4 +1,5 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2009 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
@@ -28,10 +29,9 @@
 #ifndef MLN_LEVEL_COMPARE_HH
 # define MLN_LEVEL_COMPARE_HH
 
-/*! \file mln/level/compare.hh
- *
- * \brief Comparison operators between the pixel values of images.
- */
+/// \file mln/level/compare.hh
+///
+/// Comparison operators between the pixel values of images.
 
 # include <mln/core/concept/image.hh>
 # include <mln/fun/vv2b/eq.hh>
@@ -43,38 +43,38 @@
 namespace mln
 {
 
-  /*! Point-wise test if the pixel values of \p lhs are equal to the
-   *  pixel values of \p rhs.
-   *
-   * \param[in] lhs A first image.
-   * \param[in] rhs A second image.
-   *
-   * \pre lhs.domain == rhs.domain
-   */
+  /// Point-wise test if the pixel values of \p lhs are equal to the
+  /// pixel values of \p rhs.
+  ///
+  /// \param[in] lhs A first image.
+  /// \param[in] rhs A second image.
+  ///
+  /// \pre lhs.domain == rhs.domain
+  //
   template <typename L, typename R>
   bool operator == (const Image<L>& lhs, const Image<R>& rhs);
 
 
-  /*! Point-wise test if the pixel values of \p lhs are point-wise
-   *  less than the pixel values of \p rhs.
-   *
-   * \param[in] lhs A first image.
-   * \param[in] rhs A second image.
-   *
-   * \pre lhs.domain == rhs.domain
-   */
+  /// Point-wise test if the pixel values of \p lhs are point-wise
+  /// less than the pixel values of \p rhs.
+  ///
+  /// \param[in] lhs A first image.
+  /// \param[in] rhs A second image.
+  ///
+  /// \pre lhs.domain == rhs.domain
+  //
   template <typename L, typename R>
   bool operator < (const Image<L>& lhs, const Image<R>& rhs);
 
 
-  /*! Point-wise test if the pixel values of \p lhs are point-wise
-   *  less than or equal to the pixel values of \p rhs.
-   *
-   * \param[in] lhs A first image.
-   * \param[in] rhs A second image.
-   *
-   * \pre lhs.domain == rhs.domain
-   */
+  /// Point-wise test if the pixel values of \p lhs are point-wise
+  /// less than or equal to the pixel values of \p rhs.
+  ///
+  /// \param[in] lhs A first image.
+  /// \param[in] rhs A second image.
+  ///
+  /// \pre lhs.domain == rhs.domain
+  //
   template <typename L, typename R> // required!
   bool operator <= (const Image<L>& lhs, const Image<R>& rhs);
 
@@ -82,45 +82,63 @@
 
 # ifndef MLN_INCLUDE_ONLY
 
+
   template <typename L, typename R>
   inline
   bool operator == (const Image<L>& lhs_, const Image<R>& rhs_)
   {
-    typedef fun::vv2b::eq<mln_value(L), mln_value(R)> F;
+    trace::entering("level::compare (==)");
 
     const L& lhs = exact(lhs_);
     const R& rhs = exact(rhs_);
+
     mln_precondition(lhs.is_valid());
     mln_precondition(rhs.is_valid());
     mln_precondition(lhs.domain() == rhs.domain());
 
-    return test::predicate(lhs_, rhs_, F());
+    typedef fun::vv2b::eq<mln_value(L), mln_value(R)> F;
+    bool res = test::predicate(lhs_, rhs_, F());
+
+    trace::exiting("level::compare (==)");
+    return res;
   }
 
+
   template <typename L, typename R>
   inline
   bool operator < (const Image<L>& lhs_, const Image<R>& rhs_)
   {
-    typedef fun::vv2b::lt<mln_value(L), mln_value(R)> F;
+    trace::entering("level::compare (<)");
 
     const L& lhs = exact(lhs_);
     const R& rhs = exact(rhs_);
+
     mln_precondition(lhs.domain() == rhs.domain());
 
-    return test::predicate(lhs_, rhs_, F());
+    typedef fun::vv2b::lt<mln_value(L), mln_value(R)> F;
+    bool res = test::predicate(lhs_, rhs_, F());
+
+    trace::exiting("level::compare (<)");
+    return res;
   }
 
+
   template <typename L, typename R> // required!
   inline
   bool operator <= (const Image<L>& lhs_, const Image<R>& rhs_)
   {
-    typedef fun::vv2b::le<mln_value(L), mln_value(R)> F;
+    trace::entering("level::compare (<=)");
 
     const L& lhs = exact(lhs_);
     const R& rhs = exact(rhs_);
+
     mln_precondition(lhs.domain() == rhs.domain());
 
-    return test::predicate(lhs_, rhs_, F());
+    typedef fun::vv2b::le<mln_value(L), mln_value(R)> F;
+    bool res = test::predicate(lhs_, rhs_, F());
+
+    trace::exiting("level::compare (<=)");
+    return res;
   }
 
 # endif // ! MLN_INCLUDE_ONLY
Index: mln/test/positive.hh
--- mln/test/positive.hh	(revision 3524)
+++ mln/test/positive.hh	(working copy)
@@ -1,4 +1,5 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2009 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
@@ -28,10 +29,9 @@
 #ifndef MLN_TEST_POSITIVE_HH
 # define MLN_TEST_POSITIVE_HH
 
-/*! \file mln/test/positive.hh
- *
- * \brief Test if an image only contains positive values.
- */
+/// \file mln/test/positive.hh
+///
+/// Test if an image only contains positive values.
 
 # include <mln/test/predicate.hh>
 # include <mln/pw/all.hh>
@@ -56,17 +56,22 @@
     inline
     bool positive(const Image<I>& input_)
     {
+      trace::entering("test::positive");
+
       const I& input = exact(input_);
       mln_precondition(input.is_valid());
       // FIXME: Below the '>=' op should properly work with signed/unsigned without
       // FIXME: warnings; so we really need to overload ops for functions when literals
       // FIXME: are involved.
       mln_value(I) zero_ = literal::zero;
-      return test::predicate(input.domain(),
+      bool res = test::predicate(input.domain(),
 			     pw::value(input) >= pw::cst(zero_));
       // FIXME: test the version below.
 //       return test::predicate(input,
 // 			     fun::v2v::id<mln_value(I)>() >= pw::cst(0));
+
+      trace::exiting("test::positive");
+      return res;
     }
 
 # endif // ! MLN_INCLUDE_ONLY
Index: mln/test/predicate.hh
--- mln/test/predicate.hh	(revision 3524)
+++ mln/test/predicate.hh	(working copy)
@@ -1,5 +1,5 @@
-// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2007, 2008, 2009 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
@@ -49,6 +49,7 @@
     ///
     /// \param[in] ima The image.
     /// \param[in] f The predicate.
+    //
     template <typename I, typename F>
     bool predicate(const Image<I>& ima, const Function_v2b<F>& f);
 
@@ -59,6 +60,7 @@
     /// \param[in] lhs The image.
     /// \param[in] rhs The image.
     /// \param[in] f The predicate.
+    //
     template <typename I, typename J, typename F>
     bool predicate(const Image<I>& lhs, const Image<J>& rhs, const Function_vv2b<F>& f);
 
@@ -67,12 +69,16 @@
     ///
     /// \param[in] pset The point set.
     /// \param[in] f The predicate.
+    //
     template <typename S, typename F>
     bool predicate(const Site_Set<S>& pset, const Function_p2b<F>& f);
 
 
 # ifndef MLN_INCLUDE_ONLY
 
+
+    // Tests.
+
     namespace internal
     {
 
@@ -115,6 +121,9 @@
 
     } // end of namespace mln::test::internal
 
+
+    // Implementations.
+
     namespace impl
     {
 
@@ -191,15 +200,22 @@
     } // end of namespace mln::test::impl
 
 
+
     // Facades.
 
+
     template <typename I, typename F>
     inline
     bool predicate(const Image<I>& ima, const Function_v2b<F>& f)
     {
+      trace::entering("test::predicate");
+
       internal::predicate_tests(ima, f);
-      return impl::predicate_(mln_trait_image_speed(I)(), exact(ima),
+      bool res = impl::predicate_(mln_trait_image_speed(I)(), exact(ima),
 			      exact(f));
+
+      trace::exiting("test::predicate");
+      return res;
     }
 
 
@@ -207,23 +223,34 @@
     inline
     bool predicate(const Image<I>& lhs_, const Image<J>& rhs_, const Function_vv2b<F>& f)
     {
+      trace::entering("test::predicate");
+
       const I& lhs = exact(lhs_);
       const J& rhs = exact(rhs_);
 
       internal::predicate_tests(lhs_, rhs_, f);
 
-      return impl::predicate_(mln_trait_image_speed(I)(),
+      bool res = impl::predicate_(mln_trait_image_speed(I)(),
 			      mln_trait_image_speed(J)(),
 			      lhs, rhs,
 			      exact(f));
+
+      trace::exiting("test::predicate");
+      return res;
     }
 
     template <typename S, typename F>
     inline
     bool predicate(const Site_Set<S>& pset, const Function_p2b<F>& f)
     {
+      trace::entering("test::predicate");
+
       internal::predicate_tests(pset, f);
-      return impl::predicate_(exact(pset), exact(f));
+
+      bool res = impl::predicate_(exact(pset), exact(f));
+
+      trace::exiting("test::predicate");
+      return res;
     }
 
 # endif // ! MLN_INCLUDE_ONLY
Index: tests/level/compare.cc
--- tests/level/compare.cc	(revision 3524)
+++ tests/level/compare.cc	(working copy)
@@ -1,4 +1,5 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2009 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
@@ -25,10 +26,9 @@
 // reasons why the executable file might be covered by the GNU General
 // Public License.
 
-/*! \file tests/level/compare.cc
- *
- * \brief Tests on mln::level::compare.
- */
+/// \file tests/level/compare.cc
+///
+/// Tests on mln::level::compare.
 
 #include <mln/core/image/image2d.hh>
 #include <mln/level/compare.hh>
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                          URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
ChangeLog:
2009-03-13  Etienne FOLIO  <folio(a)lrde.epita.fr>
	Sandbox reorganization.
	Moved again many old things...
	* folio/dt/canvas_dt.hh: Remove.
	* folio/dt/chamfer.hh: Remove.
	* folio/dt/cp.hh: Remove.
	* folio/dt/dmap.hh: Remove.
	* folio/dt/path.hh: Remove.
	* folio/dt/raw_cp_fast.hh: Remove.
	* folio/dt/raw_cp_slow.hh: Remove.
	* folio/dt/raw_dmap_fast.hh: Remove.
	* folio/dt/raw_dmap_slow.hh: Remove.
	* folio/dt/raw_path_fast.hh: Remove.
	* folio/dt/raw_path_slow.hh: Remove.
	* folio/dt: Remove.
	* folio/dt_old/canevas_dt.hh: Remove.
	* folio/dt_old/chamfer.cc: Remove.
	* folio/dt_old/distance_front.cc: Remove.
	* folio/dt_old/distance_front_new.hh: Remove.
	* folio/dt_old/dt.cc: Remove.
	* folio/dt_old/dt.hh: Remove.
	* folio/dt_old/dt.spe.hh: Remove.
	* folio/dt_old/naive.cc: Remove.
	* folio/dt_old/psn.cc: Remove.
	* folio/dt_old/psn_log.cc: Remove.
	* folio/dt_old: Remove.
	* folio/mln/dt/dt_old: New.
	* folio/mln/dt: New.
---
 canvas_dt.hh                 |  178 ++++++++++++++++++
 chamfer.hh                   |  156 +++++++++++++++
 cp.hh                        |  121 ++++++++++++
 dmap.hh                      |  119 ++++++++++++
 dt_old/canevas_dt.hh         |  231 +++++++++++++++++++++++
 dt_old/chamfer.cc            |  206 +++++++++++++++++++++
 dt_old/distance_front.cc     |   88 +++++++++
 dt_old/distance_front_new.hh |  420 +++++++++++++++++++++++++++++++++++++++++++
 dt_old/dt.cc                 |   59 ++++++
 dt_old/dt.hh                 |  101 ++++++++++
 dt_old/dt.spe.hh             |  123 ++++++++++++
 dt_old/naive.cc              |  142 ++++++++++++++
 dt_old/psn.cc                |  203 ++++++++++++++++++++
 dt_old/psn_log.cc            |  290 +++++++++++++++++++++++++++++
 path.hh                      |  121 ++++++++++++
 raw_cp_fast.hh               |  173 +++++++++++++++++
 raw_cp_slow.hh               |  155 +++++++++++++++
 raw_dmap_fast.hh             |  164 ++++++++++++++++
 raw_dmap_slow.hh             |  149 +++++++++++++++
 raw_path_fast.hh             |  173 +++++++++++++++++
 raw_path_slow.hh             |  155 +++++++++++++++
 21 files changed, 3527 insertions(+)
Index: trunk/milena/sandbox/folio/mln/dt/dmap.hh
===================================================================
--- trunk/milena/sandbox/folio/mln/dt/dmap.hh	(revision 0)
+++ trunk/milena/sandbox/folio/mln/dt/dmap.hh	(revision 3524)
@@ -0,0 +1,119 @@
+// 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_DT_DMAP_HH
+# define MLN_DT_DMAP_HH
+
+# include "canvas_dt.hh"
+
+namespace mln
+{
+
+  namespace dt
+  {
+
+    /*! Propagation using a single neighborhood (PSN).
+     *
+     * \param[in]  input_   The input image.
+     * \param[in]  nbh      The chamfer window to use for distance calcul.
+     * \param[in]  max      Max value of the output image.
+     * \return              A distance map.
+     *
+     * \pre \p img has to be initialized.
+     */
+    template<typename I, typename N>
+    mln_ch_value(I, unsigned)
+    dmap(const Image<I>& input_, const N& nbh, unsigned max);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+    namespace impl
+    {
+
+      // Generic functor.
+
+      template <typename I_, typename N_>
+      struct dmap_functor
+      {
+	typedef I_ I;
+	typedef N_ N;
+
+	const I& input;
+	const N& nbh;
+	unsigned max;
+
+	dmap_functor(const I& input, const N& nbh, unsigned max)
+	  : input(input),
+	    nbh(nbh),
+	    max(max)
+	{}
+
+	void init()
+	{
+	}
+
+	void init_in_for(const mln_point(I)& p)
+	{
+	  (void) p;
+	}
+
+	void run_in_for(const mln_point(I)& p, const mln_point(I)& n)
+	{
+	  (void) p;
+	  (void) n;
+	}
+      };
+
+    } // end of namespace mln::dt::impl
+
+
+    // Facade.
+
+    template<typename I, typename N>
+    inline
+    mln_ch_value(I, unsigned)
+    dmap(const Image<I>& input, const N& nbh, unsigned max)
+    {
+      trace::entering("dt::dmap");
+      mln_precondition(exact(input).is_valid());
+
+      typedef impl::dmap_functor<I, N> F;
+      F f(exact(input), nbh, max);
+      mln::canvas::dt<F> call(f);
+
+      trace::exiting("dt::dmap");
+      return call.distance;
+    }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace mln::dt
+
+} // end of namespace mln
+
+#endif // ! MLN_DT_DMAP_HH
Index: trunk/milena/sandbox/folio/mln/dt/canvas_dt.hh
===================================================================
--- trunk/milena/sandbox/folio/mln/dt/canvas_dt.hh	(revision 0)
+++ trunk/milena/sandbox/folio/mln/dt/canvas_dt.hh	(revision 3524)
@@ -0,0 +1,178 @@
+// 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_DT_CANVAS_HH
+# define MLN_DT_CANVAS_HH
+
+# include <vector>
+
+namespace mln
+{
+
+  namespace canvas
+  {
+
+    // General version.
+
+    template <typename F>
+    class dt
+    {
+    public:
+
+      // Ctor.
+      dt(F& f);
+
+      typedef typename F::I I;
+      typedef typename F::N N;
+      typedef mln_point(I) point;
+
+      mln_ch_value(I, unsigned) distance;
+
+    private:
+
+      // Functor.
+      F& f;
+
+      void init();
+      void run();
+
+      std::vector< std::vector<point> > bucket;
+      unsigned bucket_size;
+      unsigned mod;
+    };
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+    /*-------------.
+    | canvas::dt.  |
+    `-------------*/
+
+    template <typename F>
+    dt<F>::dt(F& f)
+      : f(f),
+	bucket_size(0)
+    {
+      trace::entering("canvas::dt");
+
+      this->init();
+      this->run();
+
+      trace::exiting("canvas::dt");
+    }
+
+    template <typename F>
+    void
+    dt<F>::init()
+    {
+      // Preconditions.
+      mln_precondition(f.input.is_valid());
+
+      f.init(); //< f call.
+
+      initialize(distance, f.input);
+
+      // Mod determination.
+      mln::accu::max<unsigned> accu;
+      mln_fwd_piter(I) p(f.input.domain());
+      mln_qiter(N) n(f.nbh, p);
+      for_all(n)
+	accu.take(n.w());
+      mod = accu.to_result() + 1;
+
+      bucket.resize(mod);
+
+      // Initialization
+      for_all(p)
+      {
+	f.init_in_for(p); //< f call.
+	if (f.input(p))
+	{
+	  distance(p) = literal::zero;
+	  for_all(n)
+	    if (f.input.has(n) && ! f.input(n))
+	    {
+	      bucket[0].push_back(p);
+	      ++bucket_size;
+	      break;
+	    }
+	}
+	else
+	  distance(p) = f.max;
+      }
+    }
+
+    template <typename F>
+    void
+    dt<F>::run()
+    {
+      point p;
+      mln_qiter(N) n(f.nbh, p);
+
+      for (unsigned d = 0; bucket_size != 0; ++d)
+      {
+	std::vector<point>& bucket_d = bucket[d % mod];
+	for (unsigned i = 0; i < bucket_d.size(); ++i)
+	{
+	  p = bucket_d[i];
+
+	  /* |00|    |00|    insert "a" in bucket 1    |00|
+	     |ab| -> |12| -> insert "b" in bucket 1 -> |11| -> then in bucket 2.
+	     when d = 2, "b" has already been processed when d = 1. */
+	  if (distance(p) < d)
+	    continue;
+
+	  for_all(n)
+	    if (distance.has(n) && distance(n) > d)
+	    {
+	      unsigned newDist = d + n.w();
+
+	      if (newDist < distance(n))
+	      {
+		f.run_in_for(p, n); //< f call.
+		distance(n) = newDist;
+		bucket[newDist % mod].push_back(n);
+		++bucket_size;
+	      }
+	    }
+	}
+	bucket_size -= bucket_d.size();
+	bucket_d.clear();
+      }
+
+    } // end of method dt::run()
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+
+  } // end of namespace mln::canvas
+
+} // end of namespace mln
+
+
+#endif // ! MLN_DT_CANVAS_HH
Index: trunk/milena/sandbox/folio/mln/dt/cp.hh
===================================================================
--- trunk/milena/sandbox/folio/mln/dt/cp.hh	(revision 0)
+++ trunk/milena/sandbox/folio/mln/dt/cp.hh	(revision 3524)
@@ -0,0 +1,121 @@
+// 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_DT_CP_HH
+# define MLN_DT_CP_HH
+
+# include "canvas_dt.hh"
+
+namespace mln
+{
+
+  namespace dt
+  {
+
+    /*! Propagation using a single neighborhood (PSN).
+     *
+     * \param[in]  input_   The input image.
+     * \param[in]  nbh      The chamfer window to use for distance calcul.
+     * \param[in]  max      Max value of the output image.
+     * \return              A distance map.
+     *
+     * \pre \p img has to be initialized.
+     */
+    template<typename I, typename N>
+    mln_ch_value(I, mln_point(I))
+    cp(const Image<I>& input_, const N& nbh, unsigned max);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+    namespace impl
+    {
+
+      // Generic functor.
+
+      template <typename I_, typename N_>
+      struct cp_functor
+      {
+	typedef I_ I;
+	typedef N_ N;
+
+	const I& input;
+	const N& nbh;
+	unsigned max;
+
+	cp_functor(const I& input, const N& nbh, unsigned max)
+	  : input(input),
+	    nbh(nbh),
+	    max(max)
+	{}
+
+	mln_ch_value(I, mln_point(I)) output;
+
+	void init()
+	{
+	  initialize(output, input);
+	}
+
+	void init_in_for(const mln_point(I)& p)
+	{
+	  output(p) = p;
+	}
+
+	void run_in_for(const mln_point(I)& p, const mln_point(I)& n)
+	{
+	  output(n) = p;
+	}
+      };
+
+    } // end of namespace mln::dt::impl
+
+
+    // Facade.
+
+    template<typename I, typename N>
+    inline
+    mln_ch_value(I, mln_point(I))
+    cp(const Image<I>& input, const N& nbh, unsigned max)
+    {
+      trace::entering("dt::cp");
+      mln_precondition(exact(input).is_valid());
+
+      typedef impl::cp_functor<I, N> F;
+      F f(exact(input), nbh, max);
+      mln::canvas::dt<F> call(f);
+
+      trace::exiting("dt::cp");
+      return f.output;
+    }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace mln::dt
+
+} // end of namespace mln
+
+#endif // ! MLN_DT_CP_HH
Index: trunk/milena/sandbox/folio/mln/dt/raw_path_fast.hh
===================================================================
--- trunk/milena/sandbox/folio/mln/dt/raw_path_fast.hh	(revision 0)
+++ trunk/milena/sandbox/folio/mln/dt/raw_path_fast.hh	(revision 3524)
@@ -0,0 +1,173 @@
+// 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_DT_RAW_PATH_FAST_HH
+# define MLN_DT_RAW_PATH_FAST_HH
+
+# include <queue>
+# include <map>
+# include <cmath>
+
+# include <mln/core/concept/image.hh>
+# include <mln/make/w_window.hh>
+# include <mln/core/concept/neighborhood.hh>
+# include <mln/literal/zero.hh>
+# include <mln/accu/max.hh>
+
+# include <iostream>
+
+namespace mln
+{
+
+  namespace dt
+  {
+
+    /*! Propagation using a single neighborhood (PSN).
+     *
+     * \param[in]  input_   The input image.
+     * \param[in]  nbh      The chamfer window to use for distance calcul.
+     * \param[in]  max      Max value of the output image.
+     * \return              A distance map.
+     *
+     * \pre \p img has to be initialized.
+     */
+    template<typename I, typename N>
+    mln_ch_value(I, mln_point(I))
+    raw_path_fast(const Image<I>& input_, const N& nbh, unsigned max);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+    namespace impl
+    {
+    } // end of namespace mln::dt::impl
+
+
+
+    // Facade.
+
+    template<typename I, typename N>
+    inline
+    mln_ch_value(I, mln_point(I))
+    raw_path_fast(const Image<I>& input_, const N& nbh, unsigned max)
+    {
+      // Preconditions.
+      const I& input = exact(input_);
+      mln_precondition(input.is_valid());
+
+      // Types.
+      typedef mln_point(I) point;
+
+      // Initialization of distance.
+      mln_ch_value(I, unsigned) distance;
+      initialize(distance, input);
+
+      // Initialization of output.
+      mln_ch_value(I, mln_point(I)) output;
+      initialize(output, input);
+
+      // Mod determination.
+      mln_accu_with_(accu::max, unsigned) accu;
+      mln_fwd_piter(I) p(input.domain());
+      mln_qiter(N) n(nbh, p);
+      for_all(n)
+	accu.take(n.w());
+      unsigned mod = accu.to_result() + 1;
+
+      // Aux data.
+      std::vector< std::vector<point> > bucket(mod);
+      unsigned bucket_size = 0;
+
+      // Initialization.
+      {
+	for_all(p)
+	{
+	  output(p) = p;
+	  if (input(p))
+	  {
+	    distance(p) = literal::zero;
+	    for_all(n)
+	      if (input.has(n) && ! input(n))
+	      {
+		bucket[0].push_back(p);
+		++bucket_size;
+		break;
+	      }
+	  }
+	  else
+	    distance(p) = max;
+	}
+      }
+
+      // Propagation.
+      {
+	point p;
+	mln_qiter(N) n(nbh, p);
+
+	for (unsigned d = 0; bucket_size != 0; ++d)
+	{
+	  std::vector<point>& bucket_d = bucket[d % mod];
+	  for (unsigned i = 0; i < bucket_d.size(); ++i)
+	  {
+	    p = bucket_d[i];
+
+	    // FIXME: Draw...
+	    if (distance(p) < d)
+	      // p has already been processed, having a distance less than d.
+	      continue;
+
+	    for_all(n)
+	      if (distance.has(n) && distance(n) > d)
+	      {
+		unsigned newDist = d + n.w();
+
+		if (newDist < distance(n))
+		{
+		  output(n) = output(p);
+		  distance(n) = newDist;
+		  bucket[newDist % mod].push_back(n);
+		  ++bucket_size;
+		}
+	      }
+	  }
+	  bucket_size -= bucket_d.size();
+	  bucket_d.clear();
+	}
+
+      } // end of propagation.
+
+      return output;
+    }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace mln::dt
+
+} // end of namespace mln
+
+#endif // ! MLN_DT_RAW_PATH_FAST_HH
Index: trunk/milena/sandbox/folio/mln/dt/chamfer.hh
===================================================================
--- trunk/milena/sandbox/folio/mln/dt/chamfer.hh	(revision 0)
+++ trunk/milena/sandbox/folio/mln/dt/chamfer.hh	(revision 3524)
@@ -0,0 +1,156 @@
+// 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_DT_CHAMFER_HH
+# define MLN_DT_CHAMFER_HH
+
+# include <mln/core/concept/image.hh>
+# include <mln/make/w_window.hh>
+
+namespace mln
+{
+
+  namespace dt
+  {
+
+    /*! Distance tranform by chamfer application.
+     *
+     * \param[in]  input_   The input image.
+     * \param[in]  chamfer  The chamfer window to use for distance calcul.
+     * \return              A pair (distance map, nearest point map).
+     *
+     * \pre \p img has to be initialized.
+     */
+    template<typename I, typename T>
+    std::pair<mln_ch_value(I, T), mln_ch_value(I, mln_point(I))>
+    chamfer(const Image<I>& input_,
+	    w_window<mln_dpoint(I), T> chamfer);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+    namespace impl
+    {
+
+      /*! Computes a pass of the chamfer DT algorithm.
+       *
+       * \param[in]  p              Iterator on the input image to use.
+       * \param[in]  chamfer        The chamfer window to use for distance calcul.
+       * \param[in]  input          The input image.
+       * \param[out] outputDistance The distance map updated.
+       * \param[out] outputnearest  The nearest points map updated.
+       */
+      template<typename Q, typename I, typename T>
+      inline
+      void
+      chamfer_pass(const w_window<mln_dpoint(I), T> chamfer,
+		   const I& input,
+		   mln_ch_value(I, T)& outputDistance,
+		   mln_ch_value(I, mln_point(I))& outputNearest)
+      {
+	typedef w_window<mln_dpoint(I), T> W;
+
+	Q p(input.domain());
+	mln_qiter(W) q(chamfer, p);
+	for_all(p)
+	{
+	  std::pair<T, mln_point(I)> min(mln_max(T), p);
+
+	  for_all(q)
+	    if (input.has(q) && outputDistance(q) != mln_max(T))
+	    {
+	      T v = outputDistance(q) + q.w();
+
+	      if (v < min.first)
+	      {
+		min.first = v;
+		min.second = outputNearest(q);
+	      }
+	    }
+
+	  if (min.first < outputDistance(p))
+	  {
+	    outputDistance(p) = min.first;
+	    outputNearest(p) = min.second;
+	  }
+	}
+      }
+
+    } // end of namespace mln::dt::impl
+
+
+
+    // Facade.
+
+    template<typename I, typename T>
+    inline
+    std::pair<mln_ch_value(I, T), mln_ch_value(I, mln_point(I))>
+    chamfer(const Image<I>& input_,
+	    w_window<mln_dpoint(I), T> chamfer)
+    {
+      typedef w_window<mln_dpoint(I), T> W;
+
+      const I& input = exact(input_);
+      mln_precondition(input.is_valid());
+
+      mln_ch_value(I, T) outputDistance;
+      initialize(outputDistance, input);
+
+      mln_ch_value(I, mln_point(I)) outputNearest;
+      initialize(outputNearest, input);
+
+      // Initialization.
+      {
+	mln_fwd_piter(I) p(input.domain());
+	for_all(p)
+	{
+	  outputDistance(p) = input(p) ? literal::zero : mln_max(T);
+	  outputNearest(p) = p;
+	}
+      }
+
+      // First pass.
+      impl::chamfer_pass<mln_fwd_piter(I)>
+	(chamfer, input, outputDistance, outputNearest);
+
+      chamfer.sym();
+
+      // Second pass.
+      impl::chamfer_pass<mln_bkd_piter(I)>
+	(chamfer, input, outputDistance, outputNearest);
+
+      return std::pair<mln_ch_value(I, T), mln_ch_value(I, mln_point(I))>
+	(outputDistance, outputNearest);
+    }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace mln::dt
+
+} // end of namespace mln
+
+#endif // ! MLN_DT_CHAMFER_HH
Index: trunk/milena/sandbox/folio/mln/dt/dt_old/psn.cc
===================================================================
--- trunk/milena/sandbox/folio/mln/dt/dt_old/psn.cc	(revision 0)
+++ trunk/milena/sandbox/folio/mln/dt/dt_old/psn.cc	(revision 3524)
@@ -0,0 +1,203 @@
+// 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_DT_CHAMFER_HH
+# define MLN_DT_CHAMFER_HH
+
+# include <queue>
+# include <map>
+# include <cmath>
+
+# include <mln/core/concept/image.hh>
+# include <mln/make/w_window.hh>
+# include <mln/core/concept/neighborhood.hh>
+# include <mln/literal/zero.hh>
+
+# include <iostream>
+
+namespace mln
+{
+
+  namespace dt
+  {
+
+    /*! Propagation using a single neighborhood (PSN).
+     *
+     * \param[in]  input_   The input image.
+     * \param[in]  nbh      The chamfer window to use for distance calcul.
+     * \param[in]  max      Max value of the output image.
+     * \return              A distance map.
+     *
+     * \pre \p img has to be initialized.
+     */
+    template<typename I, typename N>
+    mln_ch_value(I, unsigned)
+    psn(const Image<I>& input_, const N& nbh, unsigned max);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+    namespace impl
+    {
+    } // end of namespace mln::dt::impl
+
+
+
+    // Facade.
+
+    template<typename I, typename N>
+    inline
+    mln_ch_value(I, unsigned)
+    psn(const Image<I>& input_, const N& nbh, unsigned max)
+    {
+      // Preconditions.
+      const I& input = exact(input_);
+      mln_precondition(input.is_valid());
+
+      // Types.
+      typedef mln_point(I) point;
+
+      // Initialization of output.
+      mln_ch_value(I, unsigned) output;
+      initialize(output, input);
+
+      // Initialization.
+      // {
+
+      std::map<unsigned, std::queue<point> > bucket;
+      unsigned bucket_size = 0;
+
+      mln_fwd_piter(I) p(input.domain());
+      for_all(p)
+	if (input(p))
+	{
+	  output(p) = literal::zero;
+	  bucket[0].push(p);
+	  ++bucket_size;
+	}
+	else
+	  output(p) = max;
+
+      unsigned d = 0;
+
+      // }
+
+      while (bucket_size != 0)
+      {
+	std::queue<point> bucket_d = bucket[d];
+	while (! bucket_d.empty())
+	{
+	  point p = bucket_d.front();
+	  bucket_d.pop();
+	  --bucket_size;
+
+	  if (output(p) == d)
+	  {
+	    mln_qiter(N) n(nbh, p);
+
+	    for_all(n)
+	      if (output.has(n))
+	      {
+		unsigned newOut = output(p) + n.w();
+
+		if (newOut < output(n))
+		{
+		  output(n) = newOut;
+		  bucket[newOut].push(n);
+		  ++bucket_size;
+		}
+	      }
+	  }
+	}
+	bucket.erase(d);
+	++d;
+      }
+
+      return output;
+    }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace mln::dt
+
+} // end of namespace mln
+
+#endif // ! MLN_DT_CHAMFER_HH
+
+#include <iostream>
+#include <mln/core/image/image2d.hh>
+#include <mln/debug/println.hh>
+#include <mln/make/win_chamfer.hh>
+#include <mln/data/fill.hh>
+#include <mln/core/alias/neighb2d.hh>
+
+#include <mln/io/pbm/load.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/level/stretch.hh>
+#include <mln/value/int_u8.hh>
+
+#include <mln/core/image/sub_image.hh>
+#include <mln/core/image/image_if.hh>
+#include <mln/pw/value.hh>
+
+int main()
+{
+  using namespace mln;
+
+  image2d<bool> ima(5,5);
+  bool vals[] = { 1, 0, 0, 1, 1,
+		  0, 0, 0, 0, 0,
+		  0, 0, 0, 0, 0,
+		  0, 0, 0, 1, 0,
+		  0, 0, 0, 0, 0};
+  data::fill(ima, vals);
+
+  image2d<bool> msk(5,5);
+  bool rest[] = { 1, 0, 1, 1, 1,
+		  1, 0, 1, 1, 1,
+		  1, 1, 0, 0, 0,
+		  1, 1, 0, 1, 1,
+		  1, 1, 1, 1, 1};
+  data::fill(msk, rest);
+
+  int ws[] = { 2, 1, 2,
+	       1, 0, 1,
+	       2, 1, 2 };
+  image2d<unsigned> out;
+  out = dt::psn(ima | pw::value(msk), make::w_window2d(ws), 50);
+
+  debug::println(ima | pw::value(msk));
+  debug::println(out);
+
+//  image2d<bool> ima = io::pbm::load("../../img/c01.pbm");
+
+//  image2d<value::int_u8> out2(out.domain());
+//  level::stretch(out, out2);
+
+//  io::pgm::save(out2, "out.pgm");
+}
Index: trunk/milena/sandbox/folio/mln/dt/dt_old/canevas_dt.hh
===================================================================
--- trunk/milena/sandbox/folio/mln/dt/dt_old/canevas_dt.hh	(revision 0)
+++ trunk/milena/sandbox/folio/mln/dt/dt_old/canevas_dt.hh	(revision 3524)
@@ -0,0 +1,231 @@
+/*!
+ * \file   canevas_dt.hh
+ * \author ornthalas <ornthalas(a)gmail.com>
+ */
+
+#ifndef CANEVAS_DT_HH
+# define CANEVAS_DT_HH
+
+# include <queue>
+# include <map>
+# include <mln/core/concept/image.hh>
+# include <mln/make/w_window.hh>
+# include <mln/literal/zero.hh>
+
+# include <mln/core/concept/neighborhood.hh>
+
+namespace mln
+{
+
+  namespace canvas
+  {
+
+    // General version.
+
+    template <typename F>
+    struct dt
+    {
+      // Functor.
+      F& f;
+
+      typedef typename F::I I;
+      typedef typename F::N N;
+      typedef typename F::L L;
+      typedef mln_psite(I) point;
+
+      mln_ch_value(I, L) output;
+
+      // Ctor.
+      dt(F& f);
+
+      void init();
+      void run();
+
+      std::map<unsigned, std::queue<point> > bucket;
+      unsigned bucket_size;
+
+      unsigned current_distance;
+    };
+
+    template <typename F>
+    struct dt_fastest
+    {
+      // Functor.
+      F& f;
+
+      typedef typename F::I I;
+      typedef typename F::N N;
+      typedef typename F::L L;
+      typedef mln_psite(I) point;
+
+      mln_ch_value(I, L) output;
+
+      // Ctor.
+      dt_fastest(F& f);
+
+      void init();
+      void run();
+
+      std::map<unsigned, std::queue<point> > bucket;
+      unsigned bucket_size;
+
+      unsigned current_distance;
+    };
+
+# ifndef MLN_INCLUDE_ONLY
+
+    /*-------------.
+    | canvas::dt.  |
+    `-------------*/
+
+    template <typename F>
+    dt<F>::dt(F& f)
+      : f(f),
+	bucket_size(0),
+	current_distance(0)
+    {
+      trace::entering("canvas::dt");
+
+      this->init();
+      this->run();
+
+      trace::exiting("canvas::dt");
+    }
+
+    template <typename F>
+    void
+    dt<F>::init()
+    {
+      this->f.init();
+      initialize(this->output, this->f.input);
+
+      mln_fwd_piter(I) p(this->f.input.domain());
+      for_all(p)
+	if (this->f.input(p))
+	{
+	  this->output(p) = literal::zero;
+	  this->bucket[0].push(p);
+	  ++this->bucket_size;
+	}
+	else
+	  this->output(p) = this->max;
+    }
+
+    template <typename F>
+    void
+    dt<F>::run()
+    {
+      while (this->bucket_size != 0)
+      {
+	std::queue<point> bucket_d = this->bucket[this->current_distance];
+	while (! bucket_d.empty())
+	{
+	  point p = bucket_d.front();
+	  bucket_d.pop();
+	  --bucket_size;
+
+	  if (this->output(p) == this->current_distance)
+	  {
+	    mln_qiter(N) n(this->nbh, p);
+
+	    for_all(n)
+	      if (this->output.has(n))
+	      {
+		unsigned new_out = this->output(p) + n.w();
+
+		if (new_out < this->output(n))
+		{
+		  this->output(n) = new_out;
+		  this->bucket[new_out].push(n);
+		  ++this->bucket_size;
+		}
+	      }
+	  }
+	}
+	this->bucket.erase(this->current_distance);
+	++this->current_distance;
+      }
+    }
+
+    /*---------------------.
+    | canvas::dt_fastest.  |
+    `---------------------*/
+    template <typename F>
+    dt_fastest<F>::dt_fastest(F& f)
+      : f(f),
+	bucket_size(0),
+	current_distance(0)
+    {
+      trace::entering("canvas::dt");
+
+      this->init();
+      this->run();
+
+      trace::exiting("canvas::dt");
+    }
+
+    template <typename F>
+    void
+    dt_fastest<F>::init()
+    {
+      this->f.init();
+      initialize(this->output, this->f.input);
+
+      mln_fwd_piter(I) p(this->f.input.domain());
+      for_all(p)
+	if (this->f.input(p))
+	{
+	  this->output(p) = literal::zero;
+	  this->bucket[0].push(p);
+	  ++this->bucket_size;
+	}
+	else
+	  this->output(p) = this->max;
+    }
+
+    template <typename F>
+    void
+    dt_fastest<F>::run()
+    {
+      while (this->bucket_size != 0)
+      {
+	std::queue<point> bucket_d = this->bucket[this->current_distance];
+	while (! bucket_d.empty())
+	{
+	  point p = bucket_d.front();
+	  bucket_d.pop();
+	  --bucket_size;
+
+	  if (this->output(p) == this->current_distance)
+	  {
+	    mln_qiter(N) n(this->nbh, p);
+
+	    for_all(n)
+	      if (this->output.has(n))
+	      {
+		unsigned new_out = this->output(p) + n.w();
+
+		if (new_out < this->output(n))
+		{
+		  this->output(n) = new_out;
+		  this->bucket[new_out].push(n);
+		  ++this->bucket_size;
+		}
+	      }
+	  }
+	}
+	this->bucket.erase(this->current_distance);
+	++this->current_distance;
+      }
+    }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+
+  } // end of namespace mln::canvas
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CANVAS_DT_HH
Index: trunk/milena/sandbox/folio/mln/dt/dt_old/dt.hh
===================================================================
--- trunk/milena/sandbox/folio/mln/dt/dt_old/dt.hh	(revision 0)
+++ trunk/milena/sandbox/folio/mln/dt/dt_old/dt.hh	(revision 3524)
@@ -0,0 +1,101 @@
+/*!
+ * \file   psn.cc
+ * \author ornthalas <ornthalas(a)gmail.com>
+ */
+
+#ifndef DT_HH
+# define DT_HH
+
+// The 'fastest' specialization is in:
+# include "dt.spe.hh"
+
+namespace mln
+{
+
+  namespace dt
+  {
+
+    template<typename I, typename N, typename L>
+    inline
+    mln_ch_value(I, L)
+    dt(const Image<I>& input_, const N& nbh, unsigned max);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+    namespace impl
+    {
+
+      // Generic functor.
+
+      template <typename I_, typename N_, typename L_>
+      struct dt_functor
+      {
+	typedef I_ I;
+	typedef N_ N;
+	typedef L_ L;
+
+	const I& input;
+	const N& nbh;
+	unsigned max;
+
+	dt_functor(const I_& input, const N_& nbh, const unsigned max)
+	  : input(input),
+	    nbh(nbh),
+	    max(max)
+	{}
+
+	void init() {}
+      };
+
+
+      // Generic implementation.
+
+      namespace generic
+      {
+
+	template<typename I, typename N, typename L>
+	inline
+	mln_ch_value(I, L)
+	dt_(const Image<I>& input, const N& nbh, unsigned max)
+	{
+	  trace::entering("dt::impl::generic::dt_");
+
+	  typedef dt_functor<I, N, L> F;
+	  F f(input, nbh, max);
+	  canvas::dt<F> run(f);
+
+	  trace::exiting("dt::impl::generic::dt_");
+	  return run.output;
+	}
+
+      } // end of namespace mln::dt::impl::generic
+
+    } // end of namespace mln::dt::impl
+
+
+    // Facade.
+
+    template<typename I, typename N, typename L>
+    inline
+    mln_ch_value(I, L)
+    dt(const Image<I>& input, const N& nbh, unsigned max)
+    {
+      trace::entering("dt::dt");
+      mln_precondition(exact(input).is_valid());
+
+      mln_ch_value(I, L) output =
+	impl::dt_(mln_trait_image_speed(I)(),
+		  exact(input), nbh, max);
+
+      trace::exiting("dt::dt");
+      return output;
+    }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace mln::dt
+
+} // end of namespace mln
+
+#endif // !DT_HH
Index: trunk/milena/sandbox/folio/mln/dt/dt_old/psn_log.cc
===================================================================
--- trunk/milena/sandbox/folio/mln/dt/dt_old/psn_log.cc	(revision 0)
+++ trunk/milena/sandbox/folio/mln/dt/dt_old/psn_log.cc	(revision 3524)
@@ -0,0 +1,290 @@
+
+// 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_DT_CHAMFER_HH
+# define MLN_DT_CHAMFER_HH
+
+# include <vector>
+# include <queue>
+# include <map>
+# include <cmath>
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/neighborhood.hh>
+# include <mln/literal/zero.hh>
+
+#include <mln/core/image/image2d.hh>
+# include <mln/debug/println.hh>
+
+namespace mln
+{
+
+  namespace dt
+  {
+
+    /*! Propagation using a single neighborhood (PSN).
+     *
+     * \param[in]  input_   The input image.
+     * \param[in]  chamfer  The chamfer window to use for distance calcul.
+     * \return              A pair <distance map, closest point map>.
+     *
+     * \pre \p img has to be initialized.
+     */
+    template<typename I, typename N>
+    mln_ch_value(I, unsigned)
+    psn(const Image<I>& input_, const N& nbh);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+    namespace impl
+    {
+
+      template <typename BP>
+      class compare
+      {
+      public:
+	bool
+	operator()(const BP& lhs, const BP& rhs) const
+	{
+	  return lhs.second > rhs.second;
+	}
+      };
+
+      template <typename D>
+      unsigned
+      sq(const D& dp)
+      {
+	unsigned res = 0;
+
+	for (unsigned i = 0; i < D::dim; ++i)
+	  res += std::abs(dp[i]); // FIXME: dp[i] * dp[i];
+
+	return res;
+      }
+
+      template <typename BP>
+      unsigned
+      size(const std::map<unsigned, std::queue<BP> >& bucket,
+	   int d)
+      {
+	unsigned s = 0;
+	typename std::map<unsigned, std::queue<BP> >::const_iterator i;
+	for (i = bucket.begin(); i != bucket.end(); ++i)
+	  if (i->first >= d)
+	    s += i->second.size();
+	return s;
+      }
+
+      template <typename BP>
+      unsigned
+      size(const std::map<unsigned, std::queue<BP> >& bucket)
+      {
+	unsigned s = 0;
+	typename std::map<unsigned, std::queue<BP> >::const_iterator i;
+	for (i = bucket.begin(); i != bucket.end(); ++i)
+	  s += i->second.size();
+	return s;
+      }
+
+      template <typename BP>
+      void
+      print(const std::map<unsigned, std::queue<BP> >& bucket)
+      {
+	typename std::map<unsigned, std::queue<BP> >::const_iterator i;
+	int d = -1;
+	for (i = bucket.begin(); i != bucket.end(); ++i)
+	  {
+	    if (i->first != d)
+	      {
+		d = i->first;
+		std::cout << std::endl << d << ": ";
+	      }
+	    std::queue<BP> qu = i->second; // copy
+	    std::vector<BP> v;
+	    v.push_back(qu.front()); qu.pop();
+	    typename std::vector<BP>::const_iterator j;
+	    for (j = v.begin(); j != v.end(); ++j)
+	      std::cout << j->first << " "; // point
+	  }
+	std::cout << std::endl;
+      }
+
+    } // end of namespace mln::dt::impl
+
+
+
+    // Facade.
+
+    template<typename I, typename N>
+    inline
+    mln_ch_value(I, unsigned)
+    psn(const Image<I>& input_, const N& nbh)
+    {
+      const I& input = exact(input_);
+      mln_precondition(input.is_valid());
+
+      mln_ch_value(I, unsigned) D;
+      initialize(D, input);
+
+      static const unsigned M = 666; // FIXME
+
+      // Initialization.
+      typedef mln_point(I) point;
+      typedef mln_dpoint(I) dpoint;
+      typedef std::pair<point, dpoint> BP;
+
+      std::map<unsigned, std::queue<BP> > bucket;
+      unsigned bucket_size = 0;
+
+      mln_fwd_piter(I) p(input.domain());
+      for_all(p)
+	if (input(p))
+	{
+	  D(p) = literal::zero;
+	  bucket[0].push(BP(p, literal::zero));
+	  ++bucket_size;
+	}
+	else
+	  D(p) = M;
+
+      debug::println(input);
+      debug::println(D);
+      impl::print(bucket);
+
+      unsigned d = 0;
+
+      while (impl::size(bucket, d) != 0)
+      {
+
+	mln_invariant(impl::size(bucket) == bucket_size);
+
+	std::cout << "PROCESSING  d = " << d << std::endl;
+	  
+	std::queue<BP>& bucket_d = bucket[d];
+
+	while (! bucket_d.empty())
+	{
+	  point p = bucket_d.front().first;
+	  dpoint dp = bucket_d.front().second;
+
+	  bucket_d.pop();
+	  --bucket_size;
+
+	  std::cout << "pop " << p << " at D=" << D(p) << std::endl;
+
+	  if (D(p) == d)
+	  {
+	    mln_niter(N) n_(nbh, p);
+
+	    for_all(n_)
+	      if (D.has(n_))
+	      {
+		dpoint n = n_ - p;
+		unsigned newD = impl::sq(dp + n);
+
+		std::cout << "  n=" << n_ << " at D=" << D(n_)
+			  << " and newD=" << newD
+			  << (newD < D(p + n) ? "   push" : "")
+			  << std::endl;
+
+		if (newD < D(p + n)) // p + n = p + n_ - p = n_
+		{
+		  D(n_) = newD;
+		  bucket[newD].push(BP(p + n, dp + n));
+		  ++bucket_size;
+		}
+	      }
+	  }
+	}
+	++d;
+      }
+
+      return D;
+    }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace mln::dt
+
+} // end of namespace mln
+
+#endif // ! MLN_DT_CHAMFER_HH
+
+#include <iostream>
+#include <mln/debug/println.hh>
+#include <mln/make/win_chamfer.hh>
+#include <mln/data/fill.hh>
+#include <mln/core/alias/neighb2d.hh>
+
+#include <mln/io/pbm/load.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/level/stretch.hh>
+#include <mln/value/int_u8.hh>
+
+#include <mln/core/image/sub_image.hh>
+#include <mln/core/image/image_if.hh>
+#include <mln/pw/value.hh>
+
+int main()
+{
+  using namespace mln;
+
+//   image2d<bool> ima(5,5);
+//   bool vals[] = { 1, 1, 1, 0, 0,
+// 		  0, 0, 1, 0, 0,
+// 		  0, 0, 1, 0, 0,
+// 		  0, 0, 0, 0, 0,
+// 		  0, 0, 0, 0, 0 };
+
+  image2d<bool> ima(3,3);
+  bool vals[] = { 1, 0, 0,
+		  0, 0, 0,
+		  0, 0, 0};
+  data::fill(ima, vals);
+
+  image2d<bool> msk(3,3);
+  bool rest[] = { 1, 0, 1,
+		  1, 0, 1,
+		  1, 1, 1};
+  data::fill(msk, rest);
+
+  image2d<unsigned> out;
+  out = dt::psn(ima | pw::value(msk), c4());
+
+  debug::println(ima | pw::value(msk));
+  debug::println(out);
+
+//  image2d<bool> ima = io::pbm::load("../../img/c01.pbm");
+
+//  image2d<value::int_u8> out2(out.domain());
+//  level::stretch(out, out2);
+
+//  io::pgm::save(out2, "out.pgm");
+}
Index: trunk/milena/sandbox/folio/mln/dt/dt_old/distance_front.cc
===================================================================
--- trunk/milena/sandbox/folio/mln/dt/dt_old/distance_front.cc	(revision 0)
+++ trunk/milena/sandbox/folio/mln/dt/dt_old/distance_front.cc	(revision 3524)
@@ -0,0 +1,88 @@
+// Copyright (C) 2008, 2009 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.
+
+/// \file tests/transform/distance_front.cc
+///
+/// Test on mln::transform::distance_front.
+
+#include <mln/core/var.hh>
+#include <mln/core/image/image2d.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/make/w_window2d_int.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/data/fill.hh>
+#include <mln/debug/println.hh>
+#include <mln/opt/at.hh>
+#include <mln/level/compare.hh>
+
+#include <mln/transform/internal/distance_functor.hh>
+#include "distance_front_new.hh"
+
+
+int main()
+{
+  using namespace mln;
+  using value::int_u8;
+
+  typedef image2d<bool> I;
+
+  I input(9, 9);
+  data::fill(input, false);
+  opt::at(input, 4, 4) = true;
+
+
+  int_u8 dmax = 18;
+  mln_VAR(nbh, c4());
+
+  int ws[] = { 0, 9, 0, 9, 0,
+	       9, 6, 4, 6, 9,
+	       0, 4, 0, 4, 0,
+	       9, 6, 4, 6, 9,
+	       0, 9, 0, 9, 0 };
+  mln_VAR(w_win, make::w_window2d_int(ws));
+
+
+  transform::internal::distance_functor<I> f;
+  image2d<int_u8> ref, output;
+
+  ref = canvas::impl::generic::distance_front(input,
+					      nbh,
+					      w_win,
+					      dmax,
+					      f);
+  // debug::println("ref", ref);
+
+  output = canvas::impl::distance_front_fastest(input,
+						nbh,
+						w_win,
+						dmax,
+						f);
+  // debug::println("output", output);
+
+  mln_invariant(output == ref);
+}
Property changes on: trunk/milena/sandbox/folio/mln/dt/dt_old/distance_front.cc
___________________________________________________________________
Name: svn:mergeinfo
   + 
Index: trunk/milena/sandbox/folio/mln/dt/dt_old/naive.cc
===================================================================
--- trunk/milena/sandbox/folio/mln/dt/dt_old/naive.cc	(revision 0)
+++ trunk/milena/sandbox/folio/mln/dt/dt_old/naive.cc	(revision 3524)
@@ -0,0 +1,142 @@
+// Copyright (C) 2007, 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.
+
+/*! \file TODO
+ *
+ * \brief Defines a function that creates a distance map corresponding to a
+ * given image.
+ */
+
+#ifndef MLN_DT_NAIVE_HH
+# define MLN_DT_NAIVE_HH
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/function.hh>
+# include <mln/literal/zero.hh>
+# include <mln/accu/min.hh>
+
+namespace mln
+{
+
+  namespace dt
+  {
+
+    /*! Calculates the distance map corresponding to a given image
+     *
+     * \param[in] input_ The binary reference image.
+     * \param[in] fun_   The function used for distance aclculus.
+     * \return           New distance map image.
+     *
+     * \pre \p input_ has to be initialized.
+     *
+     * \fixme Use instead of R the result type of F::operator().
+     */
+    template <typename I, typename F>
+    inline
+    mln_ch_value(I, mln_result(F))
+    naive(const Image<I>& input_, const Function_v2v<F>& fun_);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+    // Facade.
+
+    template <typename I, typename F>
+    inline
+    mln_ch_value(I, mln_result(F))
+    naive(const Image<I>& input_, const Function_v2v<F>& fun_)
+    {
+      const I& input = exact(input_);
+      const F& fun   = exact(fun_);
+      mln_precondition(input.is_valid());
+
+      mln_ch_value(I, mln_result(F)) output;
+      initialize(output, input);
+
+      mln_piter(I) p(input.domain());
+      for_all(p)
+      {
+	if (input(p))
+	  output(p) = literal::zero;
+	else
+	{
+	  // p is in the background so the distance has to be computed.
+	  accu::min_<mln_result(F)> min;
+          min.init();
+
+          mln_piter(I) q(input.domain());
+          for_all(q)
+            if (input(q))
+              {
+		// q is in the object.
+//                 metal::vec<2, int> vp = p.to_point(), vq = q.to_point();
+//                 min.take(fun_(vp, vq));
+		min.take(fun(p - q));
+              }
+          output(p) = min;
+	}
+      }
+
+      return output;
+    }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace mln::dt
+
+} // end of namespace mln
+
+#endif // ! MLN_DT_NAIVE_HH
+
+#include <iostream>
+#include <mln/debug/println.hh>
+#include <mln/core/image/image2d.hh>
+#include <mln/data/fill.hh>
+#include <mln/fun/v2v/norm.hh>
+
+int main()
+{
+  using namespace mln;
+
+  {
+    image2d<bool> ima(5,5);
+    bool vals[] = { 1, 1, 1, 0, 0,
+		    0, 0, 1, 0, 0,
+		    0, 0, 1, 0, 0,
+		    0, 0, 0, 0, 0,
+		    0, 0, 0, 0, 0 };
+
+    data::fill(ima, vals);
+    debug::println(ima);
+
+    typedef fun::v2v::l2_norm< algebra::vec<2,float>, float > L2;
+    image2d<float> out = dt::naive(ima, L2());
+
+    std::cerr << "Distance:" << std::endl;
+    debug::println(out);
+  }
+}
Index: trunk/milena/sandbox/folio/mln/dt/dt_old/chamfer.cc
===================================================================
--- trunk/milena/sandbox/folio/mln/dt/dt_old/chamfer.cc	(revision 0)
+++ trunk/milena/sandbox/folio/mln/dt/dt_old/chamfer.cc	(revision 3524)
@@ -0,0 +1,206 @@
+// 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_DT_CHAMFER_HH
+# define MLN_DT_CHAMFER_HH
+
+# include <mln/core/concept/image.hh>
+# include <mln/make/w_window.hh>
+
+namespace mln
+{
+
+  namespace dt
+  {
+
+    /*! Distance tranform by chamfer application.
+     *
+     * \param[in]  input_   The input image.
+     * \param[in]  chamfer  The chamfer window to use for distance calcul.
+     * \return              A pair (distance map, nearest point map).
+     *
+     * \pre \p img has to be initialized.
+     */
+    template<typename I, typename T>
+    std::pair<mln_ch_value(I, T), mln_ch_value(I, mln_point(I))>
+    chamfer(const Image<I>& input_,
+	    w_window<mln_dpoint(I), T> chamfer);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+    namespace impl
+    {
+
+      /*! Computes a pass of the chamfer DT algorithm.
+       *
+       * \param[in]  p              Iterator on the input image to use.
+       * \param[in]  chamfer        The chamfer window to use for distance calcul.
+       * \param[in]  input          The input image.
+       * \param[out] outputDistance The distance map updated.
+       * \param[out] outputnearest  The nearest points map updated.
+       */
+      template<typename Q, typename I, typename T>
+      inline
+      void
+      chamfer_pass(const w_window<mln_dpoint(I), T> chamfer,
+		   const I& input,
+		   mln_ch_value(I, T)& outputDistance,
+		   mln_ch_value(I, mln_point(I))& outputNearest)
+      {
+	typedef w_window<mln_dpoint(I), T> W;
+
+	Q p(input.domain());
+	mln_qiter(W) q(chamfer, p);
+	for_all(p)
+	{
+	  std::pair<T, mln_point(I)> min(mln_max(T), p);
+
+	  for_all(q)
+	    if (input.has(q) && outputDistance(q) != mln_max(T))
+	    {
+	      T v = outputDistance(q) + q.w();
+
+	      if (v < min.first)
+	      {
+		min.first = v;
+		min.second = outputNearest(q);
+	      }
+	    }
+
+	  if (min.first < outputDistance(p))
+	  {
+	    outputDistance(p) = min.first;
+	    outputNearest(p) = min.second;
+	  }
+	}
+      }
+
+    } // end of namespace mln::dt::impl
+
+
+
+    // Facade.
+
+    template<typename I, typename T>
+    inline
+    std::pair<mln_ch_value(I, T), mln_ch_value(I, mln_point(I))>
+    chamfer(const Image<I>& input_,
+	    w_window<mln_dpoint(I), T> chamfer)
+    {
+      typedef w_window<mln_dpoint(I), T> W;
+
+      const I& input = exact(input_);
+      mln_precondition(input.is_valid());
+
+      mln_ch_value(I, T) outputDistance;
+      initialize(outputDistance, input);
+
+      mln_ch_value(I, mln_point(I)) outputNearest;
+      initialize(outputNearest, input);
+
+      // Initialization.
+      {
+	mln_fwd_piter(I) p(input.domain());
+	for_all(p)
+	{
+	  outputDistance(p) = input(p) ? literal::zero : mln_max(T);
+	  outputNearest(p) = p;
+	}
+      }
+
+      // First pass.
+      impl::chamfer_pass<mln_fwd_piter(I)>
+	(chamfer, input, outputDistance, outputNearest);
+
+      chamfer.sym();
+
+      // Second pass.
+      impl::chamfer_pass<mln_bkd_piter(I)>
+	(chamfer, input, outputDistance, outputNearest);
+
+      return std::pair<mln_ch_value(I, T), mln_ch_value(I, mln_point(I))>
+	(outputDistance, outputNearest);
+    }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace mln::dt
+
+} // end of namespace mln
+
+#endif // ! MLN_DT_CHAMFER_HH
+
+#include <iostream>
+#include <mln/core/image/image2d.hh>
+#include <mln/debug/println.hh>
+#include <mln/make/win_chamfer.hh>
+#include <mln/data/fill.hh>
+
+#include <mln/io/pbm/load.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/level/stretch.hh>
+#include <mln/value/int_u8.hh>
+
+int main()
+{
+  using namespace mln;
+
+  w_window2d_int chamfer = make::mk_chamfer_3x3_int<1, 2>();
+
+  {
+//     image2d<bool> ima(5,5);
+//     bool vals[] = { 1, 1, 1, 0, 0,
+// 		    0, 0, 1, 0, 0,
+// 		    0, 0, 1, 0, 0,
+// 		    0, 0, 0, 0, 0,
+// 		    0, 0, 0, 0, 0 };
+
+//     data::fill(ima, vals);
+//     debug::println(ima);
+
+//     std::pair<image2d<int>, image2d<mln_point_(image2d<bool>)> > out;
+//     for (int i = 0; i < 999; ++i)
+//       out = dt::chamfer(ima, chamfer);
+
+//     std::cerr << "Distance:" << std::endl;
+//     debug::println(out.first);
+//     std::cerr << "PPP:" << std::endl;
+//     debug::println(out.second);
+
+  image2d<bool> ima = io::pbm::load("../../img/c01.pbm");
+
+  std::pair<image2d<int>, image2d<mln_point_(image2d<bool>)> > out;
+  out = dt::chamfer(ima, chamfer);
+
+  image2d<value::int_u8> out2(out.first.domain());
+  level::stretch(out.first, out2);
+
+  io::pgm::save(out2, "out.pgm");
+
+  }
+}
Index: trunk/milena/sandbox/folio/mln/dt/dt_old/distance_front_new.hh
===================================================================
--- trunk/milena/sandbox/folio/mln/dt/dt_old/distance_front_new.hh	(revision 0)
+++ trunk/milena/sandbox/folio/mln/dt/dt_old/distance_front_new.hh	(revision 3524)
@@ -0,0 +1,420 @@
+// 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_CANVAS_DISTANCE_FRONT_HH
+# define MLN_CANVAS_DISTANCE_FRONT_HH
+
+/// \file mln/canvas/distance_front.hh
+///
+/// Discrete distance canvas by front propagation.
+
+# include <vector>
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/neighborhood.hh>
+# include <mln/core/concept/weighted_window.hh>
+# include <mln/data/fill.hh>
+# include <mln/accu/max.hh>
+# include <mln/extension/adjust_fill.hh>
+
+
+namespace mln
+{
+
+  namespace canvas
+  {
+
+    /// Discrete front distance canvas.
+    template <typename I,
+	      typename N, typename W, typename D,
+	      typename F>
+    mln_ch_value(I, D)
+      distance_front(const Image<I>& input,
+		     const Neighborhood<N>& nbh, const Weighted_Window<W>& w_win, D max,
+		     F& functor);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+    // Tests.
+
+    namespace internal
+    {
+
+      template <typename I,
+		typename N, typename W, typename D,
+		typename F>
+      void
+      distance_front_tests(const Image<I>& input_,
+			   const Neighborhood<N>& nbh_,
+			   const Weighted_Window<W>& w_win_,
+			   D max,
+			   F& functor)
+      {
+	const I& input = exact(input_);
+	const N& nbh   = exact(nbh_);
+	const W& w_win = exact(w_win_);
+
+	mln_precondition(input.is_valid());
+	mln_precondition(nbh.is_valid());
+
+	(void) input;
+	(void) nbh;
+	(void) max;
+	(void) functor;
+      }
+
+
+    } // of namespace mln::canvas::internal
+
+
+
+    // Implementations.
+
+    namespace impl
+    {
+
+      namespace generic
+      {
+
+	template <typename I,
+		  typename N, typename W, typename D,
+		  typename F>
+	mln_ch_value(I, D)
+	  distance_front(const Image<I>& input_,
+			 const Neighborhood<N>& nbh_,
+			 const Weighted_Window<W>& w_win_,
+			 D max,
+			 F& functor)
+	{
+	  trace::entering("canvas::impl::generic::distance_front");
+
+	  const I& input = exact(input_);
+	  const N& nbh   = exact(nbh_);
+	  const W& w_win = exact(w_win_);
+
+	  mln_precondition(input.is_valid());
+	  mln_precondition(w_win.is_valid());
+
+	  typedef mln_site(I) P;
+	  typedef std::vector<P> bucket_t;
+
+	  // Distance map.
+	  mln_ch_value(I, D) dmap;
+	  initialize(dmap, input);
+	  data::fill(dmap, max);
+
+	  // Mod determination.
+	  unsigned mod;
+	  {
+	    accu::max<unsigned> m;
+	    for (unsigned i = 0; i < w_win.size(); ++i)
+	      m.take(w_win.w(i));
+	    mod = unsigned(m) + 1;
+	  }
+
+	  // Aux data.
+	  std::vector<bucket_t> bucket(mod);
+	  unsigned bucket_size = 0;
+
+	  // Initialization.
+	  {
+	    functor.init(input); // <-- init
+	    mln_piter(I) p(input.domain());
+	    mln_niter(N) n(nbh, p);
+	    for_all(p)
+	      if (functor.inqueue_p_wrt_input_p(input(p))) // <-- inqueue_p_wrt_input_p
+		{
+		  dmap(p) = 0;
+		  for_all(n)
+		    if (input.domain().has(n) &&
+			functor.inqueue_p_wrt_input_n(input(n))) // <-- inqueue_p_wrt_input_n
+		      {
+			bucket[0].push_back(p);
+			++bucket_size;
+			break;
+		      }
+		}
+	  } // end of Initialization.
+
+	  // Propagation.
+	  {
+	    P p;
+	    mln_qiter(W) q(w_win, p);
+	    for (unsigned d = 0; bucket_size != 0; ++d)
+	      {
+		bucket_t& bucket_d = bucket[d % mod];
+		for (unsigned i = 0; i < bucket_d.size(); ++i)
+		  {
+		    p = bucket_d[i];
+
+		    if (dmap(p) == max)
+		      {
+			// Saturation so stop.
+			bucket_size = bucket_d.size(); // So at end bucket_size == 0.
+			break;
+		      }
+
+		    if (dmap(p) < d)
+		      // p has already been processed, having a distance less than d.
+		      continue;
+
+		    for_all(q)
+		      if (dmap.domain().has(q) && dmap(q) > d)
+			{
+			  unsigned d_ = d + q.w();
+			  if (d_ < dmap(q))
+			    {
+			      dmap(q) = d_;
+			      functor.process(p, q); // <- process
+			      bucket[d_ % mod].push_back(q);
+			      ++bucket_size;
+			    }
+			}
+		  }
+		bucket_size -= bucket_d.size();
+		bucket_d.clear();
+	      }
+	  } // end of Propagation.
+	  
+	  trace::exiting("canvas::impl::generic::distance_front");
+	  return dmap;
+	}
+
+      } // of namespace mln::canvas::impl::generic
+
+
+
+      // Fastest version.
+
+      template <typename I,
+		typename N, typename W, typename D,
+		typename F>
+      mln_ch_value(I, D)
+	distance_front_fastest(const Image<I>& input_,
+			       const Neighborhood<N>& nbh_,
+			       const Weighted_Window<W>& w_win_,
+			       D max, F& functor)
+      {
+	trace::entering("canvas::impl::distance_front_fastest");
+
+	const I& input = exact(input_);
+	const N& nbh   = exact(nbh_);
+	const W& w_win = exact(w_win_);
+
+	mln_precondition(input.is_valid());
+	mln_precondition(w_win.is_valid());
+
+	// Handling w_win.
+	extension::adjust(input, w_win);
+	const unsigned n_ws = w_win.size();
+	util::array<int> dp = offsets_wrt(input, w_win.win());
+	mln_invariant(dp.nelements() == n_ws);
+
+	// Distance map.
+	mln_ch_value(I, D) dmap;
+	initialize(dmap, input);
+	data::fill(dmap, max);
+
+	// Mod determination.
+	unsigned mod;
+	{
+	  accu::max<unsigned> m;
+	  for (unsigned i = 0; i < w_win.size(); ++i)
+	    m.take(w_win.w(i));
+	  mod = unsigned(m) + 1;
+	}
+
+	// Aux data.
+	typedef std::vector<unsigned> bucket_t;
+	std::vector<bucket_t> bucket(mod);
+	unsigned bucket_size = 0;
+
+	// Initialization.
+	{
+	  functor.init_(input); // <-- init
+
+	  // For the extension to be ignored:
+	  extension::fill(input, true);
+	  extension::fill(dmap, D(0));
+
+	  mln_pixter(const I)    p(input);
+	  mln_nixter(const I, N) n(p, nbh);
+	  for_all(p)
+	    if (functor.inqueue_p_wrt_input_p_(p.val())) // <-- inqueue_p_wrt_input_p
+	      {
+		dmap.element(p.offset()) = 0;
+		for_all(n)
+		  if (functor.inqueue_p_wrt_input_n_(n.val())) // <-- inqueue_p_wrt_input_n
+		    {
+		      bucket[0].push_back(p.offset());
+		      ++bucket_size;
+		      break;
+		    }
+	      }
+	} // end of Initialization.
+
+	// Propagation.
+	{
+	  unsigned p;
+
+	  for (unsigned d = 0; bucket_size != 0; ++d)
+	    {
+	      bucket_t& bucket_d = bucket[d % mod];
+	      for (unsigned i = 0; i < bucket_d.size(); ++i)
+		{
+		  p = bucket_d[i];
+
+		  if (dmap.element(p) == max)
+		    {
+		      // Saturation so stop.
+		      bucket_size = bucket_d.size(); // So at end bucket_size == 0.
+		      break;
+		    }
+
+		  if (dmap.element(p) < d)
+		    // p has already been processed, having a distance less than d.
+		    continue;
+
+		  for (unsigned i = 0; i < n_ws; ++i)
+		  {
+		    unsigned q = p + dp[i];
+		    if (dmap.element(q) > d)
+		      {
+			unsigned d_ = d + w_win.w(i);
+			if (d_ < dmap.element(q))
+			  {
+			    dmap.element(q) = d_;
+			    functor.process_(p, q); // <- process
+			    bucket[d_ % mod].push_back(q);
+			    ++bucket_size;
+			  }
+		      }
+		  }
+		}
+	      bucket_size -= bucket_d.size();
+	      bucket_d.clear();
+	    }
+	} // end of Propagation.
+
+	trace::exiting("canvas::impl::distance_front_fastest");
+	return dmap;
+      }
+
+
+    } // of namespace mln::canvas::impl
+
+
+
+    // Dispatch.
+
+    namespace internal
+    {
+
+      template <typename I,
+		typename N, typename W, typename D,
+		typename F>
+      inline
+      mln_ch_value(I, D)
+	distance_front_dispatch(metal::false_,
+				const Image<I>& input,
+				const Neighborhood<N>& nbh, const Weighted_Window<W>& w_win,
+				D max, F& functor)
+      {
+	return impl::generic::distance_front(input, nbh, max, w_win, functor);
+      }
+
+      template <typename I,
+		typename N, typename W, typename D,
+		typename F>
+      inline
+      mln_ch_value(I, D)
+	distance_front_dispatch(metal::true_,
+				const Image<I>& input,
+				const Neighborhood<N>& nbh, const Weighted_Window<W>& w_win,
+				D max, F& functor)
+      {
+  	return impl::distance_front_fastest(input, nbh, w_win, max, functor);
+	// 	return impl::generic::distance_front(input, nbh, w_win, max, functor);
+      }
+
+      template <typename I,
+		typename N, typename W, typename D,
+		typename F>
+      inline
+      mln_ch_value(I, D)
+	distance_front_dispatch(const Image<I>& input,
+				const Neighborhood<N>& nbh, const Weighted_Window<W>& w_win,
+				D max, F& functor)
+      {
+	enum {
+	  test = mlc_equal(mln_trait_image_speed(I),
+			   trait::image::speed::fastest)::value
+	  &&
+	  mln_is_simple_neighborhood(N)::value
+	};
+	return distance_front_dispatch(metal::bool_<test>(),
+				       input, nbh, w_win, max, functor);
+      }
+
+
+    } // of namespace mln::canvas::internal
+
+
+
+    // Facade.
+
+    template <typename I,
+	      typename N, typename W, typename D,
+	      typename F>
+    inline
+    mln_ch_value(I, D)
+      distance_front(const Image<I>& input,
+		     const Neighborhood<N>& nbh, const Weighted_Window<W>& w_win,
+		     D max, F& functor)
+    {
+      trace::entering("canvas::distance_front");
+
+      internal::distance_front_tests(input, nbh, w_win, max, functor);
+
+      mln_ch_value(I,D) output;
+      output = internal::distance_front_dispatch(input, nbh, w_win, max, functor);
+
+      trace::exiting("canvas::distance_front");
+      return output;
+    }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace mln::canvas
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CANVAS_DISTANCE_FRONT_HH
Index: trunk/milena/sandbox/folio/mln/dt/dt_old/dt.cc
===================================================================
--- trunk/milena/sandbox/folio/mln/dt/dt_old/dt.cc	(revision 0)
+++ trunk/milena/sandbox/folio/mln/dt/dt_old/dt.cc	(revision 3524)
@@ -0,0 +1,59 @@
+/*!
+ * \file   dt.cc
+ * \author ornthalas <ornthalas(a)gmail.com>
+ */
+
+#include <iostream>
+#include <mln/core/image/image2d.hh>
+#include <mln/debug/println.hh>
+#include <mln/make/win_chamfer.hh>
+#include <mln/data/fill.hh>
+#include <mln/core/alias/neighb2d.hh>
+
+#include <mln/io/pbm/load.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/level/stretch.hh>
+#include <mln/value/int_u8.hh>
+
+#include <mln/core/image/sub_image.hh>
+#include <mln/core/image/image_if.hh>
+#include <mln/pw/value.hh>
+
+#include "dt.hh"
+
+int main()
+{
+  using namespace mln;
+
+  image2d<bool> ima(5,5);
+  bool vals[] = { 1, 0, 0, 1, 1,
+		  0, 0, 0, 0, 0,
+		  0, 0, 0, 0, 0,
+		  0, 0, 0, 1, 0,
+		  0, 0, 0, 0, 0};
+  data::fill(ima, vals);
+
+  image2d<bool> msk(5,5);
+  bool rest[] = { 1, 0, 1, 1, 1,
+		  1, 0, 1, 1, 1,
+		  1, 1, 0, 0, 0,
+		  1, 1, 0, 1, 1,
+		  1, 1, 1, 1, 1};
+  data::fill(msk, rest);
+
+  int ws[] = { 2, 1, 2,
+	       1, 0, 1,
+	       2, 1, 2 };
+  image2d<unsigned> out;
+  out = dt::dt(ima | pw::value(msk), make::w_window2d(ws), 50);
+
+  debug::println(ima | pw::value(msk));
+  debug::println(out);
+
+//  image2d<bool> ima = io::pbm::load("../../img/c01.pbm");
+
+//  image2d<value::int_u8> out2(out.domain());
+//  level::stretch(out, out2);
+
+//  io::pgm::save(out2, "out.pgm");
+}
Index: trunk/milena/sandbox/folio/mln/dt/dt_old/dt.spe.hh
===================================================================
--- trunk/milena/sandbox/folio/mln/dt/dt_old/dt.spe.hh	(revision 0)
+++ trunk/milena/sandbox/folio/mln/dt/dt_old/dt.spe.hh	(revision 3524)
@@ -0,0 +1,123 @@
+/*!
+ * \file   test_psn.spe.hh
+ * \author ornthalas <ornthalas(a)gmail.com>
+ */
+
+#ifndef DT_SPE_HH
+# define DT_SPE_HH
+
+# ifndef DT_HH
+#  error "Forbidden inclusion of *.spe.hh"
+# endif // ! DT_HH
+
+# include "canevas_dt.hh"
+
+namespace mln
+{
+
+  namespace dt
+  {
+
+    template<typename I, typename N, typename L>
+    inline
+    mln_ch_value(I, L)
+    dt(const Image<I>& input_, const N& nbh, unsigned max);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+    namespace impl
+    {
+
+
+      // Fwd decl of the Generic version.
+
+      namespace generic
+      {
+
+	template<typename I, typename N, typename L>
+	inline
+	mln_ch_value(I, L)
+	dt_(const Image<I>& input_, const N& nbh, unsigned max);
+
+      } // end of namespace mln::dt::impl::generic
+
+
+      // Fastest functor.
+
+      template <typename I_, typename N_, typename L_>
+      struct dt_fasfunctor
+      {
+	typedef I_ I;
+	typedef N_ N;
+	typedef L_ L;
+
+	const I& input;
+	const N& nbh;
+	unsigned max;
+
+	dt_fasfunctor(const I_& input, const N_& nbh, const unsigned max)
+	  : input(input),
+	    nbh(nbh),
+	    max(max)
+	{}
+
+	void init() {}
+      };
+
+
+      // Fastest implementation.
+
+      namespace fastest
+      {
+
+	template<typename I, typename N, typename L>
+	inline
+	mln_ch_value(I, L)
+        dt_(const I& input, const N& nbh, unsigned max)
+	{
+	  trace::entering("dt::impl::dt_fas");
+
+	  typedef dt_fasfunctor<I,N,L> F;
+	  F f(input, nbh, max);
+	  canvas::dt_fastest<F> run(f);
+
+	  trace::exiting("dt::impl::dt_fas");
+	  return run.output;
+	}
+
+      } // end of namespace mln::dt::impl::fastest
+
+
+      // Disjunction between "fastest" and "not fastest".
+
+      template<typename I, typename N, typename L>
+      inline
+      mln_ch_value(I, L)
+      dt_(trait::image::speed::any,
+	  const I& input, const N& nbh, unsigned max)
+      {
+	return generic::dt_(input, nbh, max);
+      }
+
+      template<typename I, typename N, typename L>
+      inline
+      mln_ch_value(I, L)
+      dt_(trait::image::speed::fastest,
+	  const I& input, const N& nbh, unsigned max)
+      {
+	return fastest::dt_(input, nbh, max);
+      }
+
+
+    } // end of namespace mln::dt::impl
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace mln::dt
+
+} // end of namespace mln
+
+
+#endif // !DT_SPE_HH
Index: trunk/milena/sandbox/folio/mln/dt/raw_dmap_fast.hh
===================================================================
--- trunk/milena/sandbox/folio/mln/dt/raw_dmap_fast.hh	(revision 0)
+++ trunk/milena/sandbox/folio/mln/dt/raw_dmap_fast.hh	(revision 3524)
@@ -0,0 +1,164 @@
+// 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_DT_RAW_DMAP_FAST_HH
+# define MLN_DT_RAW_DMAP_FAST_HH
+
+# include <queue>
+# include <map>
+# include <cmath>
+
+# include <mln/core/concept/image.hh>
+# include <mln/make/w_window.hh>
+# include <mln/core/concept/neighborhood.hh>
+# include <mln/literal/zero.hh>
+
+# include <iostream>
+
+namespace mln
+{
+
+  namespace dt
+  {
+
+    /*! Propagation using a single neighborhood (PSN).
+     *
+     * \param[in]  input_   The input image.
+     * \param[in]  nbh      The chamfer window to use for distance calcul.
+     * \param[in]  max      Max value of the distance image.
+     * \return              A distance map.
+     *
+     * \pre \p img has to be initialized.
+     */
+    template<typename I, typename N>
+    mln_ch_value(I, unsigned)
+    raw_dmap_fast(const Image<I>& input_, const N& nbh, unsigned max);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+    namespace impl
+    {
+    } // end of namespace mln::dt::impl
+
+
+
+    // Facade.
+
+    template<typename I, typename N>
+    inline
+    mln_ch_value(I, unsigned)
+    raw_dmap_fast(const Image<I>& input_, const N& nbh, unsigned max)
+    {
+      // Preconditions.
+      const I& input = exact(input_);
+      mln_precondition(input.is_valid());
+
+      // Types.
+      typedef mln_point(I) point;
+
+      // Initialization of distance.
+      mln_ch_value(I, unsigned) distance;
+      initialize(distance, input);
+
+      // Mod determination.
+      mln_accu_with_(accu::max, unsigned) accu;
+      mln_fwd_piter(I) p(input.domain());
+      mln_qiter(N) n(nbh, p);
+      for_all(n)
+	accu.take(n.w());
+      unsigned mod = accu.to_result() + 1;
+
+      // Aux data.
+      std::vector< std::vector<point> > bucket(mod);
+      unsigned bucket_size = 0;
+
+      // Initialization.
+      {
+	for_all(p)
+	  if (input(p))
+	  {
+	    distance(p) = literal::zero;
+	    for_all(n)
+	      if (input.has(n) && ! input(n))
+	      {
+		bucket[0].push_back(p);
+		++bucket_size;
+		break;
+	      }
+	  }
+	  else
+	    distance(p) = max;
+      }
+
+      // Propagation.
+      {
+	point p;
+	mln_qiter(N) n(nbh, p);
+
+	for (unsigned d = 0; bucket_size != 0; ++d)
+	{
+	  std::vector<point>& bucket_d = bucket[d % mod];
+	  for (unsigned i = 0; i < bucket_d.size(); ++i)
+	  {
+	    p = bucket_d[i];
+
+	    // FIXME: Draw...
+	    if (distance(p) < d)
+	      // p has already been processed, having a distance less than d.
+	      continue;
+
+	    for_all(n)
+	      if (distance.has(n) && distance(n) > d)
+	      {
+		unsigned newDist = d + n.w();
+
+		if (newDist < distance(n))
+		{
+		  distance(n) = newDist;
+		  bucket[newDist % mod].push_back(n);
+		  ++bucket_size;
+		}
+	      }
+	  }
+	  bucket_size -= bucket_d.size();
+	  bucket_d.clear();
+	}
+
+      } // end of propagation.
+
+      return distance;
+    }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace mln::dt
+
+} // end of namespace mln
+
+#endif // ! MLN_DT_RAW_DMAP_FAST_HH
Index: trunk/milena/sandbox/folio/mln/dt/raw_cp_fast.hh
===================================================================
--- trunk/milena/sandbox/folio/mln/dt/raw_cp_fast.hh	(revision 0)
+++ trunk/milena/sandbox/folio/mln/dt/raw_cp_fast.hh	(revision 3524)
@@ -0,0 +1,173 @@
+// 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_DT_RAW_CP_FAST_HH
+# define MLN_DT_RAW_CP_FAST_HH
+
+# include <queue>
+# include <map>
+# include <cmath>
+
+# include <mln/core/concept/image.hh>
+# include <mln/make/w_window.hh>
+# include <mln/core/concept/neighborhood.hh>
+# include <mln/literal/zero.hh>
+# include <mln/accu/max.hh>
+
+# include <iostream>
+
+namespace mln
+{
+
+  namespace dt
+  {
+
+    /*! Propagation using a single neighborhood (PSN).
+     *
+     * \param[in]  input_   The input image.
+     * \param[in]  nbh      The chamfer window to use for distance calcul.
+     * \param[in]  max      Max value of the output image.
+     * \return              A distance map.
+     *
+     * \pre \p img has to be initialcped.
+     */
+    template<typename I, typename N>
+    mln_ch_value(I, mln_point(I))
+    raw_cp_fast(const Image<I>& input_, const N& nbh, unsigned max);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+    namespace impl
+    {
+    } // end of namespace mln::dt::impl
+
+
+
+    // Facade.
+
+    template<typename I, typename N>
+    inline
+    mln_ch_value(I, mln_point(I))
+    raw_cp_fast(const Image<I>& input_, const N& nbh, unsigned max)
+    {
+      // Preconditions.
+      const I& input = exact(input_);
+      mln_precondition(input.is_valid());
+
+      // Types.
+      typedef mln_point(I) point;
+
+      // Initialcpation of distance.
+      mln_ch_value(I, unsigned) distance;
+      initialize(distance, input);
+
+      // Initialcpation of output.
+      mln_ch_value(I, mln_point(I)) output;
+      initialize(output, input);
+
+      // Mod determination.
+      mln_accu_with_(accu::max, unsigned) accu;
+      mln_fwd_piter(I) p(input.domain());
+      mln_qiter(N) n(nbh, p);
+      for_all(n)
+	accu.take(n.w());
+      unsigned mod = accu.to_result() + 1;
+
+      // Aux data.
+      std::vector< std::vector<point> > bucket(mod);
+      unsigned bucket_size = 0;
+
+      // Initialcpation.
+      {
+	for_all(p)
+	{
+	  output(p) = p;
+	  if (input(p))
+	  {
+	    distance(p) = literal::zero;
+	    for_all(n)
+	      if (input.has(n) && ! input(n))
+	      {
+		bucket[0].push_back(p);
+		++bucket_size;
+		break;
+	      }
+	  }
+	  else
+	    distance(p) = max;
+	}
+      }
+
+      // Propagation.
+      {
+	point p;
+	mln_qiter(N) n(nbh, p);
+
+	for (unsigned d = 0; bucket_size != 0; ++d)
+	{
+	  std::vector<point>& bucket_d = bucket[d % mod];
+	  for (unsigned i = 0; i < bucket_d.size(); ++i)
+	  {
+	    p = bucket_d[i];
+
+	    // FIXME: Draw...
+	    if (distance(p) < d)
+	      // p has already been processed, having a distance less than d.
+	      continue;
+
+	    for_all(n)
+	      if (distance.has(n) && distance(n) > d)
+	      {
+		unsigned newDist = d + n.w();
+
+		if (newDist < distance(n))
+		{
+		  output(n) = p;
+		  distance(n) = newDist;
+		  bucket[newDist % mod].push_back(n);
+		  ++bucket_size;
+		}
+	      }
+	  }
+	  bucket_size -= bucket_d.size();
+	  bucket_d.clear();
+	}
+
+      } // end of propagation.
+
+      return output;
+    }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace mln::dt
+
+} // end of namespace mln
+
+#endif // ! MLN_DT_RAW_CP_FAST_HH
Index: trunk/milena/sandbox/folio/mln/dt/raw_path_slow.hh
===================================================================
--- trunk/milena/sandbox/folio/mln/dt/raw_path_slow.hh	(revision 0)
+++ trunk/milena/sandbox/folio/mln/dt/raw_path_slow.hh	(revision 3524)
@@ -0,0 +1,155 @@
+// Copyright (C) 2007 EPITA Research and Development unsignedaboratory
+//
+// This file is part of the Olena unsignedibrary.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public unsignedicense 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 unsignedicense for more details.
+//
+// You should have received a copy of the GNU General Public unsignedicense
+// 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
+// unsignedicense.  This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public unsignedicense.
+
+#ifndef MLN_DT_RAW_PATH_SLOW_HH
+# define MLN_DT_RAW_PATH_SLOW_HH
+
+# include <queue>
+# include <map>
+# include <cmath>
+
+# include <mln/core/concept/image.hh>
+# include <mln/make/w_window.hh>
+# include <mln/core/concept/neighborhood.hh>
+# include <mln/literal/zero.hh>
+
+# include <iostream>
+
+namespace mln
+{
+
+  namespace dt
+  {
+
+    /*! Propagation using a single neighborhood (PSN).
+     *
+     * \param[in]  input_   The input image.
+     * \param[in]  nbh      The chamfer window to use for distance calcul.
+     * \param[in]  max      Max value of the output image.
+     * \return              A distance map.
+     *
+     * \pre \p img has to be initialized.
+     */
+    template<typename I, typename N>
+    mln_ch_value(I, mln_point(I))
+    raw_path_slow(const Image<I>& input_, const N& nbh, unsigned max);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+    namespace impl
+    {
+    } // end of namespace mln::dt::impl
+
+
+
+    // Facade.
+
+    template<typename I, typename N>
+    inline
+    mln_ch_value(I, mln_point(I))
+    raw_path_slow(const Image<I>& input_, const N& nbh, unsigned max)
+    {
+      // Preconditions.
+      const I& input = exact(input_);
+      mln_precondition(input.is_valid());
+
+      // Types.
+      typedef mln_point(I) point;
+
+      // Initialization of distance.
+      mln_ch_value(I, unsigned) distance;
+      initialize(distance, input);
+
+      // Initialization of output.
+      mln_ch_value(I, mln_point(I)) output;
+      initialize(output, input);
+
+      // Initialization.
+      // {
+
+      std::map< unsigned, std::queue<point> > bucket;
+      unsigned bucket_size = 0;
+
+      mln_fwd_piter(I) p(input.domain());
+      for_all(p)
+      {
+	output(p) = p;
+	if (input(p))
+	{
+	  distance(p) = literal::zero;
+	  bucket[0].push(p);
+	  ++bucket_size;
+	}
+	else
+	  distance(p) = max;
+      }
+
+      // }
+
+      for (unsigned d = 0; bucket_size != 0; ++d)
+      {
+	std::queue<point> bucket_d = bucket[d];
+	while (! bucket_d.empty())
+	{
+	  point p = bucket_d.front();
+	  bucket_d.pop();
+	  --bucket_size;
+
+	  if (distance(p) == d)
+	  {
+	    mln_qiter(N) n(nbh, p);
+
+	    for_all(n)
+	      if (distance.has(n))
+	      {
+		unsigned newDist = d + n.w();
+
+		if (newDist < distance(n))
+		{
+		  distance(n) = newDist;
+		  output(n) = output(p);
+		  bucket[newDist].push(n);
+		  ++bucket_size;
+		}
+	      }
+	  }
+	}
+	bucket.erase(d);
+      }
+
+      return output;
+    }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace mln::dt
+
+} // end of namespace mln
+
+#endif // ! MLN_DT_RAW_PATH_SLOW_HH
Index: trunk/milena/sandbox/folio/mln/dt/path.hh
===================================================================
--- trunk/milena/sandbox/folio/mln/dt/path.hh	(revision 0)
+++ trunk/milena/sandbox/folio/mln/dt/path.hh	(revision 3524)
@@ -0,0 +1,121 @@
+// 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_DT_PATH_HH
+# define MLN_DT_PATH_HH
+
+# include "canvas_dt.hh"
+
+namespace mln
+{
+
+  namespace dt
+  {
+
+    /*! Propagation using a single neighborhood (PSN).
+     *
+     * \param[in]  input_   The input image.
+     * \param[in]  nbh      The chamfer window to use for distance calcul.
+     * \param[in]  max      Max value of the output image.
+     * \return              A distance map.
+     *
+     * \pre \p img has to be initialized.
+     */
+    template<typename I, typename N>
+    mln_ch_value(I, mln_point(I))
+    path(const Image<I>& input_, const N& nbh, unsigned max);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+    namespace impl
+    {
+
+      // Generic functor.
+
+      template <typename I_, typename N_>
+      struct path_functor
+      {
+	typedef I_ I;
+	typedef N_ N;
+
+	const I& input;
+	const N& nbh;
+	unsigned max;
+
+	path_functor(const I& input, const N& nbh, unsigned max)
+	  : input(input),
+	    nbh(nbh),
+	    max(max)
+	{}
+
+	mln_ch_value(I, mln_point(I)) output;
+
+	void init()
+	{
+	  initialize(output, input);
+	}
+
+	void init_in_for(const mln_point(I)& p)
+	{
+	  output(p) = p;
+	}
+
+	void run_in_for(const mln_point(I)& p, const mln_point(I)& n)
+	{
+	  output(n) = output(p);
+	}
+      };
+
+    } // end of namespace mln::dt::impl
+
+
+    // Facade.
+
+    template<typename I, typename N>
+    inline
+    mln_ch_value(I, mln_point(I))
+    path(const Image<I>& input, const N& nbh, unsigned max)
+    {
+      trace::entering("dt::path");
+      mln_precondition(exact(input).is_valid());
+
+      typedef impl::path_functor<I, N> F;
+      F f(exact(input), nbh, max);
+      mln::canvas::dt<F> call(f);
+
+      trace::exiting("dt::path");
+      return f.output;
+    }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace mln::dt
+
+} // end of namespace mln
+
+#endif // ! MLN_DT_PATH_HH
Index: trunk/milena/sandbox/folio/mln/dt/raw_dmap_slow.hh
===================================================================
--- trunk/milena/sandbox/folio/mln/dt/raw_dmap_slow.hh	(revision 0)
+++ trunk/milena/sandbox/folio/mln/dt/raw_dmap_slow.hh	(revision 3524)
@@ -0,0 +1,149 @@
+// Copyright (C) 2007 EPITA Research and Development unsignedaboratory
+//
+// This file is part of the Olena unsignedibrary.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public unsignedicense 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 unsignedicense for more details.
+//
+// You should have received a copy of the GNU General Public unsignedicense
+// 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
+// unsignedicense.  This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public unsignedicense.
+
+#ifndef MLN_DT_RAW_DMAP_SLOW_HH
+# define MLN_DT_RAW_DMAP_SLOW_HH
+
+# include <queue>
+# include <map>
+# include <cmath>
+
+# include <mln/core/concept/image.hh>
+# include <mln/make/w_window.hh>
+# include <mln/core/concept/neighborhood.hh>
+# include <mln/literal/zero.hh>
+
+# include <iostream>
+
+namespace mln
+{
+
+  namespace dt
+  {
+
+    /*! Propagation using a single neighborhood (PSN).
+     *
+     * \param[in]  input_   The input image.
+     * \param[in]  nbh      The chamfer window to use for distance calcul.
+     * \param[in]  max      Max value of the output image.
+     * \return              A distance map.
+     *
+     * \pre \p img has to be initialized.
+     */
+    template<typename I, typename N>
+    mln_ch_value(I, unsigned)
+    raw_dmap_slow(const Image<I>& input_, const N& nbh, unsigned max);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+    namespace impl
+    {
+    } // end of namespace mln::dt::impl
+
+
+
+    // Facade.
+
+    template<typename I, typename N>
+    inline
+    mln_ch_value(I, unsigned)
+    raw_dmap_slow(const Image<I>& input_, const N& nbh, unsigned max)
+    {
+      // Preconditions.
+      const I& input = exact(input_);
+      mln_precondition(input.is_valid());
+
+      // Types.
+      typedef mln_point(I) point;
+
+      // Initialization of distance.
+      mln_ch_value(I, unsigned) distance;
+      initialize(distance, input);
+
+      // Initialization.
+      // {
+
+      std::map< unsigned, std::queue<point> > bucket;
+      unsigned bucket_size = 0;
+
+      mln_fwd_piter(I) p(input.domain());
+      for_all(p)
+      {
+	if (input(p))
+	{
+	  distance(p) = literal::zero;
+	  bucket[0].push(p);
+	  ++bucket_size;
+	}
+	else
+	  distance(p) = max;
+      }
+
+      // }
+
+      for (unsigned d = 0; bucket_size != 0; ++d)
+      {
+	std::queue<point> bucket_d = bucket[d];
+	while (! bucket_d.empty())
+	{
+	  point p = bucket_d.front();
+	  bucket_d.pop();
+	  --bucket_size;
+
+	  if (distance(p) == d)
+	  {
+	    mln_qiter(N) n(nbh, p);
+
+	    for_all(n)
+	      if (distance.has(n))
+	      {
+		unsigned newDist = d + n.w();
+
+		if (newDist < distance(n))
+		{
+		  distance(n) = newDist;
+		  bucket[newDist].push(n);
+		  ++bucket_size;
+		}
+	      }
+	  }
+	}
+	bucket.erase(d);
+      }
+
+      return distance;
+    }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace mln::dt
+
+} // end of namespace mln
+
+#endif // ! MLN_DT_RAW_DMAP_SLOW_HH
Index: trunk/milena/sandbox/folio/mln/dt/raw_cp_slow.hh
===================================================================
--- trunk/milena/sandbox/folio/mln/dt/raw_cp_slow.hh	(revision 0)
+++ trunk/milena/sandbox/folio/mln/dt/raw_cp_slow.hh	(revision 3524)
@@ -0,0 +1,155 @@
+// Copyright (C) 2007 EPITA Research and Development unsignedaboratory
+//
+// This file is part of the Olena unsignedibrary.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public unsignedicense 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 unsignedicense for more details.
+//
+// You should have received a copy of the GNU General Public unsignedicense
+// 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
+// unsignedicense.  This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public unsignedicense.
+
+#ifndef MLN_DT_RAW_CP_SLOW_HH
+# define MLN_DT_RAW_CP_SLOW_HH
+
+# include <queue>
+# include <map>
+# include <cmath>
+
+# include <mln/core/concept/image.hh>
+# include <mln/make/w_window.hh>
+# include <mln/core/concept/neighborhood.hh>
+# include <mln/literal/zero.hh>
+
+# include <iostream>
+
+namespace mln
+{
+
+  namespace dt
+  {
+
+    /*! Propagation using a single neighborhood (PSN).
+     *
+     * \param[in]  input_   The input image.
+     * \param[in]  nbh      The chamfer window to use for distance calcul.
+     * \param[in]  max      Max value of the output image.
+     * \return              A distance map.
+     *
+     * \pre \p img has to be initialcped.
+     */
+    template<typename I, typename N>
+    mln_ch_value(I, mln_point(I))
+    raw_cp_slow(const Image<I>& input_, const N& nbh, unsigned max);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+    namespace impl
+    {
+    } // end of namespace mln::dt::impl
+
+
+
+    // Facade.
+
+    template<typename I, typename N>
+    inline
+    mln_ch_value(I, mln_point(I))
+    raw_cp_slow(const Image<I>& input_, const N& nbh, unsigned max)
+    {
+      // Preconditions.
+      const I& input = exact(input_);
+      mln_precondition(input.is_valid());
+
+      // Types.
+      typedef mln_point(I) point;
+
+      // Initialcpation of distance.
+      mln_ch_value(I, unsigned) distance;
+      initialize(distance, input);
+
+      // Initialcpation of output.
+      mln_ch_value(I, mln_point(I)) output;
+      initialize(output, input);
+
+      // Initialcpation.
+      // {
+
+      std::map< unsigned, std::queue<point> > bucket;
+      unsigned bucket_size = 0;
+
+      mln_fwd_piter(I) p(input.domain());
+      for_all(p)
+      {
+	output(p) = p;
+	if (input(p))
+	{
+	  distance(p) = literal::zero;
+	  bucket[0].push(p);
+	  ++bucket_size;
+	}
+	else
+	  distance(p) = max;
+      }
+
+      // }
+
+      for (unsigned d = 0; bucket_size != 0; ++d)
+      {
+	std::queue<point> bucket_d = bucket[d];
+	while (! bucket_d.empty())
+	{
+	  point p = bucket_d.front();
+	  bucket_d.pop();
+	  --bucket_size;
+
+	  if (distance(p) == d)
+	  {
+	    mln_qiter(N) n(nbh, p);
+
+	    for_all(n)
+	      if (distance.has(n))
+	      {
+		unsigned newDist = d + n.w();
+
+		if (newDist < distance(n))
+		{
+		  distance(n) = newDist;
+		  output(n) = p;
+		  bucket[newDist].push(n);
+		  ++bucket_size;
+		}
+	      }
+	  }
+	}
+	bucket.erase(d);
+      }
+
+      return output;
+    }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace mln::dt
+
+} // end of namespace mln
+
+#endif // ! MLN_DT_RAW_CP_SLOW_HH
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                        https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from  Thierry Geraud  <thierry.geraud(a)lrde.epita.fr>
	Add an identity site iterator adaptor.
	* mln/core/internal/piter_identity.hh: New.
	* mln/core/internal/site_iterator_base.hh (todo): Remove; done.
	* mln/core/internal/site_set_iterator_base.hh (pset): New.
	Upgrade file doc style.
 piter_identity.hh         |   88 ++++++++++++++++++++++++++++++++++++++++++++++
 site_iterator_base.hh     |    8 +---
 site_set_iterator_base.hh |   29 ++++++++-------
 3 files changed, 106 insertions(+), 19 deletions(-)
Index: mln/core/internal/piter_identity.hh
--- mln/core/internal/piter_identity.hh	(revision 0)
+++ mln/core/internal/piter_identity.hh	(revision 0)
@@ -0,0 +1,88 @@
+// Copyright (C) 2009 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_CORE_INTERNAL_PITER_IDENTITY_HH
+# define MLN_CORE_INTERNAL_PITER_IDENTITY_HH
+
+/// \file mln/core/internal/piter_identity.hh
+///
+/// \brief Definition of site iterator identity adaptors.
+
+# include <mln/core/internal/piter_adaptor.hh>
+
+
+namespace mln
+{
+
+  namespace internal
+  {
+
+    /// A base class for site iterator identity adaptors.
+    ///
+    /// Parameter \c Pi is the type of the site iterator adaptee;
+    /// parameter E is the exact type.
+    ///
+    template <typename Pi, typename E>
+    class piter_identity_ : public piter_adaptor_< Pi,            // Adaptee.
+						   mln_pset(Pi),  // Site set.
+						   E >            // Exact type.
+    {
+      typedef piter_adaptor_< Pi, mln_pset(Pi), E > super_;
+
+    protected:
+
+      /// Constructor without argument.
+      piter_identity_();
+
+      /// Constructor from a point iterator \p piter.
+      piter_identity_(const Pi& piter);
+    };
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+    template <typename Pi, typename E>
+    inline
+    piter_identity_<Pi,E>::piter_identity_()
+    {
+    }
+
+    template <typename Pi, typename E>
+    inline
+    piter_identity_<Pi,E>::piter_identity_(const Pi& pi)
+      : super_(pi)
+    {
+    }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace mln::internal
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CORE_INTERNAL_PITER_IDENTITY_HH
Index: mln/core/internal/site_iterator_base.hh
--- mln/core/internal/site_iterator_base.hh	(revision 3521)
+++ mln/core/internal/site_iterator_base.hh	(working copy)
@@ -1,4 +1,5 @@
-// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2008, 2009 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
@@ -31,17 +32,12 @@
 /// \file mln/core/internal/site_iterator_base.hh
 ///
 /// Base class to factor code for site iterator classes.
-///
-/// \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.
 
 
-// FIXME: See todo.
-
-
 
 namespace mln
 {
Index: mln/core/internal/site_set_iterator_base.hh
--- mln/core/internal/site_set_iterator_base.hh	(revision 3521)
+++ mln/core/internal/site_set_iterator_base.hh	(working copy)
@@ -1,4 +1,5 @@
-// Copyright (C) 2008 EPITA Research and Development Laboratory
+// Copyright (C) 2008, 2009 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
@@ -28,11 +29,10 @@
 #ifndef MLN_CORE_INTERNAL_SITE_SET_ITERATOR_BASE_HH
 # define MLN_CORE_INTERNAL_SITE_SET_ITERATOR_BASE_HH
 
-/*! \file mln/core/internal/site_set_iterator_base.hh
- *
- * \brief Base class to factor code for iterator classes directly
- * working on site sets.
- */
+/// \file mln/core/internal/site_set_iterator_base.hh
+///
+/// \brief Base class to factor code for iterator classes directly
+/// working on site sets.
 
 # include <mln/core/internal/site_iterator_base.hh>
 
@@ -43,18 +43,21 @@
   namespace internal
   {
 
-    /*! A base class for site iterators.
-     *
-     * Parameter \c S is the targeted site set type.
-     *
-     * IMPORTANT: Sub-classes have to define start_, next_,
-     * is_valid_ and invalidate_.
-     */
+    /// A base class for iterators on site sets.
+    ///
+    /// Parameter \c S is the targeted site set type.
+    ///
+    /// IMPORTANT: Sub-classes have to define start_, next_,
+    /// is_valid_ and invalidate_.
+    //
     template <typename S, typename E>
     class site_set_iterator_base : public site_iterator_base<S, E>
     {
     public:
 
+      /// The associated site set type.
+      typedef S pset;
+
       /// Give the site set that this iterator browses.
       const S& site_set() const;
 
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                          URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
ChangeLog:
2009-03-13  Etienne FOLIO  <folio(a)lrde.epita.fr>
	Reorganization of the sandbox.
	Moved a lot of things...
	* folio/canevas_dt.hh: Remove.
	* folio/chamfer.cc: Remove.
	* folio/distance_front.cc: Remove.
	* folio/distance_front_new.hh: Remove.
	* folio/dt.cc: Remove.
	* folio/dt.hh: Remove.
	* folio/dt.spe.hh: Remove.
	* folio/dt_old/canevas_dt.hh: New.
	* folio/dt_old/chamfer.cc: New.
	* folio/dt_old/distance_front.cc: New.
	* folio/dt_old/distance_front_new.hh: New.
	* folio/dt_old/dt.cc: New.
	* folio/dt_old/dt.hh: New.
	* folio/dt_old/dt.spe.hh: New.
	* folio/dt_old/naive.cc: New.
	* folio/dt_old/psn.cc: New.
	* folio/dt_old/psn_log.cc: New.
	* folio/dt_old: New.
	* folio/histo/compute_histo_rgb.hh: Remove.
	* folio/histo: Remove.
	* folio/mln/histo: New.
	* folio/mln/value: New.
	* folio/mln: New.
	* folio/naive.cc: Remove.
	* folio/psn.cc: Remove.
	* folio/psn_log.cc: Remove.
	* folio/test/canvas/dt.hh: Remove.
	* folio/test/canvas/dt.spe.hh: Remove.
	* folio/test/canvas: Remove.
	* folio/test/chamfer.cc: Remove.
	* folio/test/dt.cc: Remove.
	* folio/test/dt/canvas: New.
	* folio/test/dt/chamfer.cc: New.
	* folio/test/dt/dt.cc: New.
	* folio/test/dt/dt_bench.cc: New.
	* folio/test/dt/dt_maze.cc: New.
	* folio/test/dt/naive.cc: New.
	* folio/test/dt/psn.cc: New.
	* folio/test/dt/psn_log.cc: New.
	* folio/test/dt/tmp.ppm: New.
	* folio/test/dt: New.
	* folio/test/dt_bench.cc: Remove.
	* folio/test/dt_maze.cc: Remove.
	* folio/test/naive.cc: Remove.
	* folio/test/psn.cc: Remove.
	* folio/test/psn_log.cc: Remove.
	* folio/test/tmp.ppm: Remove.
	* folio/value/pipo.hh: Remove.
	* folio/value: Remove.
---
 dt_old/canevas_dt.hh           |  231 ++++++++++++++++++++++
 dt_old/chamfer.cc              |  206 ++++++++++++++++++++
 dt_old/distance_front.cc       |   88 ++++++++
 dt_old/distance_front_new.hh   |  420 +++++++++++++++++++++++++++++++++++++++++
 dt_old/dt.cc                   |   59 +++++
 dt_old/dt.hh                   |  101 +++++++++
 dt_old/dt.spe.hh               |  123 ++++++++++++
 dt_old/naive.cc                |  142 +++++++++++++
 dt_old/psn.cc                  |  203 +++++++++++++++++++
 dt_old/psn_log.cc              |  290 ++++++++++++++++++++++++++++
 mln/histo/compute_histo_rgb.hh |   36 +++
 mln/value/pipo.hh              |  107 ++++++++++
 test/dt/canvas/dt.hh           |  101 +++++++++
 test/dt/canvas/dt.spe.hh       |  123 ++++++++++++
 test/dt/chamfer.cc             |   52 +++++
 test/dt/dt.cc                  |   66 ++++++
 test/dt/dt_bench.cc            |   53 +++++
 test/dt/dt_maze.cc             |  124 ++++++++++++
 test/dt/naive.cc               |  142 +++++++++++++
 test/dt/psn.cc                 |  203 +++++++++++++++++++
 test/dt/psn_log.cc             |  290 ++++++++++++++++++++++++++++
 21 files changed, 3160 insertions(+)
Index: trunk/milena/sandbox/folio/psn.cc (deleted)
===================================================================
Index: trunk/milena/sandbox/folio/psn_log.cc (deleted)
===================================================================
Index: trunk/milena/sandbox/folio/distance_front.cc (deleted)
===================================================================
Index: trunk/milena/sandbox/folio/naive.cc (deleted)
===================================================================
Index: trunk/milena/sandbox/folio/chamfer.cc (deleted)
===================================================================
Index: trunk/milena/sandbox/folio/dt.cc (deleted)
===================================================================
Index: trunk/milena/sandbox/folio/dt.spe.hh (deleted)
===================================================================
Index: trunk/milena/sandbox/folio/canevas_dt.hh (deleted)
===================================================================
Index: trunk/milena/sandbox/folio/dt.hh (deleted)
===================================================================
Index: trunk/milena/sandbox/folio/distance_front_new.hh (deleted)
===================================================================
Index: trunk/milena/sandbox/folio/test/psn.cc (deleted)
===================================================================
Index: trunk/milena/sandbox/folio/test/psn_log.cc (deleted)
===================================================================
Index: trunk/milena/sandbox/folio/test/naive.cc (deleted)
===================================================================
Index: trunk/milena/sandbox/folio/test/dt_maze.cc (deleted)
===================================================================
Index: trunk/milena/sandbox/folio/test/chamfer.cc (deleted)
===================================================================
Index: trunk/milena/sandbox/folio/test/dt_bench.cc (deleted)
===================================================================
Index: trunk/milena/sandbox/folio/test/dt.cc (deleted)
===================================================================
Index: trunk/milena/sandbox/folio/test/tmp.ppm (deleted)
===================================================================
Index: trunk/milena/sandbox/folio/test/dt/psn.cc
===================================================================
--- trunk/milena/sandbox/folio/test/dt/psn.cc	(revision 0)
+++ trunk/milena/sandbox/folio/test/dt/psn.cc	(revision 3522)
@@ -0,0 +1,203 @@
+// 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_DT_CHAMFER_HH
+# define MLN_DT_CHAMFER_HH
+
+# include <queue>
+# include <map>
+# include <cmath>
+
+# include <mln/core/concept/image.hh>
+# include <mln/make/w_window.hh>
+# include <mln/core/concept/neighborhood.hh>
+# include <mln/literal/zero.hh>
+
+# include <iostream>
+
+namespace mln
+{
+
+  namespace dt
+  {
+
+    /*! Propagation using a single neighborhood (PSN).
+     *
+     * \param[in]  input_   The input image.
+     * \param[in]  nbh      The chamfer window to use for distance calcul.
+     * \param[in]  max      Max value of the output image.
+     * \return              A distance map.
+     *
+     * \pre \p img has to be initialized.
+     */
+    template<typename I, typename N>
+    mln_ch_value(I, unsigned)
+    psn(const Image<I>& input_, const N& nbh, unsigned max);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+    namespace impl
+    {
+    } // end of namespace mln::dt::impl
+
+
+
+    // Facade.
+
+    template<typename I, typename N>
+    inline
+    mln_ch_value(I, unsigned)
+    psn(const Image<I>& input_, const N& nbh, unsigned max)
+    {
+      // Preconditions.
+      const I& input = exact(input_);
+      mln_precondition(input.is_valid());
+
+      // Types.
+      typedef mln_point(I) point;
+
+      // Initialization of output.
+      mln_ch_value(I, unsigned) output;
+      initialize(output, input);
+
+      // Initialization.
+      // {
+
+      std::map<unsigned, std::queue<point> > bucket;
+      unsigned bucket_size = 0;
+
+      mln_fwd_piter(I) p(input.domain());
+      for_all(p)
+	if (input(p))
+	{
+	  output(p) = literal::zero;
+	  bucket[0].push(p);
+	  ++bucket_size;
+	}
+	else
+	  output(p) = max;
+
+      unsigned d = 0;
+
+      // }
+
+      while (bucket_size != 0)
+      {
+	std::queue<point> bucket_d = bucket[d];
+	while (! bucket_d.empty())
+	{
+	  point p = bucket_d.front();
+	  bucket_d.pop();
+	  --bucket_size;
+
+	  if (output(p) == d)
+	  {
+	    mln_qiter(N) n(nbh, p);
+
+	    for_all(n)
+	      if (output.has(n))
+	      {
+		unsigned newOut = output(p) + n.w();
+
+		if (newOut < output(n))
+		{
+		  output(n) = newOut;
+		  bucket[newOut].push(n);
+		  ++bucket_size;
+		}
+	      }
+	  }
+	}
+	bucket.erase(d);
+	++d;
+      }
+
+      return output;
+    }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace mln::dt
+
+} // end of namespace mln
+
+#endif // ! MLN_DT_CHAMFER_HH
+
+#include <iostream>
+#include <mln/core/image/image2d.hh>
+#include <mln/debug/println.hh>
+#include <mln/make/win_chamfer.hh>
+#include <mln/data/fill.hh>
+#include <mln/core/alias/neighb2d.hh>
+
+#include <mln/io/pbm/load.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/level/stretch.hh>
+#include <mln/value/int_u8.hh>
+
+#include <mln/core/image/sub_image.hh>
+#include <mln/core/image/image_if.hh>
+#include <mln/pw/value.hh>
+
+int main()
+{
+  using namespace mln;
+
+  image2d<bool> ima(5,5);
+  bool vals[] = { 1, 0, 0, 1, 1,
+		  0, 0, 0, 0, 0,
+		  0, 0, 0, 0, 0,
+		  0, 0, 0, 1, 0,
+		  0, 0, 0, 0, 0};
+  data::fill(ima, vals);
+
+  image2d<bool> msk(5,5);
+  bool rest[] = { 1, 0, 1, 1, 1,
+		  1, 0, 1, 1, 1,
+		  1, 1, 0, 0, 0,
+		  1, 1, 0, 1, 1,
+		  1, 1, 1, 1, 1};
+  data::fill(msk, rest);
+
+  int ws[] = { 2, 1, 2,
+	       1, 0, 1,
+	       2, 1, 2 };
+  image2d<unsigned> out;
+  out = dt::psn(ima | pw::value(msk), make::w_window2d(ws), 50);
+
+  debug::println(ima | pw::value(msk));
+  debug::println(out);
+
+//  image2d<bool> ima = io::pbm::load("../../img/c01.pbm");
+
+//  image2d<value::int_u8> out2(out.domain());
+//  level::stretch(out, out2);
+
+//  io::pgm::save(out2, "out.pgm");
+}
Index: trunk/milena/sandbox/folio/test/dt/psn_log.cc
===================================================================
--- trunk/milena/sandbox/folio/test/dt/psn_log.cc	(revision 0)
+++ trunk/milena/sandbox/folio/test/dt/psn_log.cc	(revision 3522)
@@ -0,0 +1,290 @@
+
+// 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_DT_CHAMFER_HH
+# define MLN_DT_CHAMFER_HH
+
+# include <vector>
+# include <queue>
+# include <map>
+# include <cmath>
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/neighborhood.hh>
+# include <mln/literal/zero.hh>
+
+#include <mln/core/image/image2d.hh>
+# include <mln/debug/println.hh>
+
+namespace mln
+{
+
+  namespace dt
+  {
+
+    /*! Propagation using a single neighborhood (PSN).
+     *
+     * \param[in]  input_   The input image.
+     * \param[in]  chamfer  The chamfer window to use for distance calcul.
+     * \return              A pair <distance map, closest point map>.
+     *
+     * \pre \p img has to be initialized.
+     */
+    template<typename I, typename N>
+    mln_ch_value(I, unsigned)
+    psn(const Image<I>& input_, const N& nbh);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+    namespace impl
+    {
+
+      template <typename BP>
+      class compare
+      {
+      public:
+	bool
+	operator()(const BP& lhs, const BP& rhs) const
+	{
+	  return lhs.second > rhs.second;
+	}
+      };
+
+      template <typename D>
+      unsigned
+      sq(const D& dp)
+      {
+	unsigned res = 0;
+
+	for (unsigned i = 0; i < D::dim; ++i)
+	  res += std::abs(dp[i]); // FIXME: dp[i] * dp[i];
+
+	return res;
+      }
+
+      template <typename BP>
+      unsigned
+      size(const std::map<unsigned, std::queue<BP> >& bucket,
+	   int d)
+      {
+	unsigned s = 0;
+	typename std::map<unsigned, std::queue<BP> >::const_iterator i;
+	for (i = bucket.begin(); i != bucket.end(); ++i)
+	  if (i->first >= d)
+	    s += i->second.size();
+	return s;
+      }
+
+      template <typename BP>
+      unsigned
+      size(const std::map<unsigned, std::queue<BP> >& bucket)
+      {
+	unsigned s = 0;
+	typename std::map<unsigned, std::queue<BP> >::const_iterator i;
+	for (i = bucket.begin(); i != bucket.end(); ++i)
+	  s += i->second.size();
+	return s;
+      }
+
+      template <typename BP>
+      void
+      print(const std::map<unsigned, std::queue<BP> >& bucket)
+      {
+	typename std::map<unsigned, std::queue<BP> >::const_iterator i;
+	int d = -1;
+	for (i = bucket.begin(); i != bucket.end(); ++i)
+	  {
+	    if (i->first != d)
+	      {
+		d = i->first;
+		std::cout << std::endl << d << ": ";
+	      }
+	    std::queue<BP> qu = i->second; // copy
+	    std::vector<BP> v;
+	    v.push_back(qu.front()); qu.pop();
+	    typename std::vector<BP>::const_iterator j;
+	    for (j = v.begin(); j != v.end(); ++j)
+	      std::cout << j->first << " "; // point
+	  }
+	std::cout << std::endl;
+      }
+
+    } // end of namespace mln::dt::impl
+
+
+
+    // Facade.
+
+    template<typename I, typename N>
+    inline
+    mln_ch_value(I, unsigned)
+    psn(const Image<I>& input_, const N& nbh)
+    {
+      const I& input = exact(input_);
+      mln_precondition(input.is_valid());
+
+      mln_ch_value(I, unsigned) D;
+      initialize(D, input);
+
+      static const unsigned M = 666; // FIXME
+
+      // Initialization.
+      typedef mln_point(I) point;
+      typedef mln_dpoint(I) dpoint;
+      typedef std::pair<point, dpoint> BP;
+
+      std::map<unsigned, std::queue<BP> > bucket;
+      unsigned bucket_size = 0;
+
+      mln_fwd_piter(I) p(input.domain());
+      for_all(p)
+	if (input(p))
+	{
+	  D(p) = literal::zero;
+	  bucket[0].push(BP(p, literal::zero));
+	  ++bucket_size;
+	}
+	else
+	  D(p) = M;
+
+      debug::println(input);
+      debug::println(D);
+      impl::print(bucket);
+
+      unsigned d = 0;
+
+      while (impl::size(bucket, d) != 0)
+      {
+
+	mln_invariant(impl::size(bucket) == bucket_size);
+
+	std::cout << "PROCESSING  d = " << d << std::endl;
+	  
+	std::queue<BP>& bucket_d = bucket[d];
+
+	while (! bucket_d.empty())
+	{
+	  point p = bucket_d.front().first;
+	  dpoint dp = bucket_d.front().second;
+
+	  bucket_d.pop();
+	  --bucket_size;
+
+	  std::cout << "pop " << p << " at D=" << D(p) << std::endl;
+
+	  if (D(p) == d)
+	  {
+	    mln_niter(N) n_(nbh, p);
+
+	    for_all(n_)
+	      if (D.has(n_))
+	      {
+		dpoint n = n_ - p;
+		unsigned newD = impl::sq(dp + n);
+
+		std::cout << "  n=" << n_ << " at D=" << D(n_)
+			  << " and newD=" << newD
+			  << (newD < D(p + n) ? "   push" : "")
+			  << std::endl;
+
+		if (newD < D(p + n)) // p + n = p + n_ - p = n_
+		{
+		  D(n_) = newD;
+		  bucket[newD].push(BP(p + n, dp + n));
+		  ++bucket_size;
+		}
+	      }
+	  }
+	}
+	++d;
+      }
+
+      return D;
+    }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace mln::dt
+
+} // end of namespace mln
+
+#endif // ! MLN_DT_CHAMFER_HH
+
+#include <iostream>
+#include <mln/debug/println.hh>
+#include <mln/make/win_chamfer.hh>
+#include <mln/data/fill.hh>
+#include <mln/core/alias/neighb2d.hh>
+
+#include <mln/io/pbm/load.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/level/stretch.hh>
+#include <mln/value/int_u8.hh>
+
+#include <mln/core/image/sub_image.hh>
+#include <mln/core/image/image_if.hh>
+#include <mln/pw/value.hh>
+
+int main()
+{
+  using namespace mln;
+
+//   image2d<bool> ima(5,5);
+//   bool vals[] = { 1, 1, 1, 0, 0,
+// 		  0, 0, 1, 0, 0,
+// 		  0, 0, 1, 0, 0,
+// 		  0, 0, 0, 0, 0,
+// 		  0, 0, 0, 0, 0 };
+
+  image2d<bool> ima(3,3);
+  bool vals[] = { 1, 0, 0,
+		  0, 0, 0,
+		  0, 0, 0};
+  data::fill(ima, vals);
+
+  image2d<bool> msk(3,3);
+  bool rest[] = { 1, 0, 1,
+		  1, 0, 1,
+		  1, 1, 1};
+  data::fill(msk, rest);
+
+  image2d<unsigned> out;
+  out = dt::psn(ima | pw::value(msk), c4());
+
+  debug::println(ima | pw::value(msk));
+  debug::println(out);
+
+//  image2d<bool> ima = io::pbm::load("../../img/c01.pbm");
+
+//  image2d<value::int_u8> out2(out.domain());
+//  level::stretch(out, out2);
+
+//  io::pgm::save(out2, "out.pgm");
+}
Index: trunk/milena/sandbox/folio/test/dt/naive.cc
===================================================================
--- trunk/milena/sandbox/folio/test/dt/naive.cc	(revision 0)
+++ trunk/milena/sandbox/folio/test/dt/naive.cc	(revision 3522)
@@ -0,0 +1,142 @@
+// Copyright (C) 2007, 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.
+
+/*! \file TODO
+ *
+ * \brief Defines a function that creates a distance map corresponding to a
+ * given image.
+ */
+
+#ifndef MLN_DT_NAIVE_HH
+# define MLN_DT_NAIVE_HH
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/function.hh>
+# include <mln/literal/zero.hh>
+# include <mln/accu/min.hh>
+
+namespace mln
+{
+
+  namespace dt
+  {
+
+    /*! Calculates the distance map corresponding to a given image
+     *
+     * \param[in] input_ The binary reference image.
+     * \param[in] fun_   The function used for distance aclculus.
+     * \return           New distance map image.
+     *
+     * \pre \p input_ has to be initialized.
+     *
+     * \fixme Use instead of R the result type of F::operator().
+     */
+    template <typename I, typename F>
+    inline
+    mln_ch_value(I, mln_result(F))
+    naive(const Image<I>& input_, const Function_v2v<F>& fun_);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+    // Facade.
+
+    template <typename I, typename F>
+    inline
+    mln_ch_value(I, mln_result(F))
+    naive(const Image<I>& input_, const Function_v2v<F>& fun_)
+    {
+      const I& input = exact(input_);
+      const F& fun   = exact(fun_);
+      mln_precondition(input.is_valid());
+
+      mln_ch_value(I, mln_result(F)) output;
+      initialize(output, input);
+
+      mln_piter(I) p(input.domain());
+      for_all(p)
+      {
+	if (input(p))
+	  output(p) = literal::zero;
+	else
+	{
+	  // p is in the background so the distance has to be computed.
+	  accu::min_<mln_result(F)> min;
+          min.init();
+
+          mln_piter(I) q(input.domain());
+          for_all(q)
+            if (input(q))
+              {
+		// q is in the object.
+//                 metal::vec<2, int> vp = p.to_point(), vq = q.to_point();
+//                 min.take(fun_(vp, vq));
+		min.take(fun(p - q));
+              }
+          output(p) = min;
+	}
+      }
+
+      return output;
+    }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace mln::dt
+
+} // end of namespace mln
+
+#endif // ! MLN_DT_NAIVE_HH
+
+#include <iostream>
+#include <mln/debug/println.hh>
+#include <mln/core/image/image2d.hh>
+#include <mln/data/fill.hh>
+#include <mln/fun/v2v/norm.hh>
+
+int main()
+{
+  using namespace mln;
+
+  {
+    image2d<bool> ima(5,5);
+    bool vals[] = { 1, 1, 1, 0, 0,
+		    0, 0, 1, 0, 0,
+		    0, 0, 1, 0, 0,
+		    0, 0, 0, 0, 0,
+		    0, 0, 0, 0, 0 };
+
+    data::fill(ima, vals);
+    debug::println(ima);
+
+    typedef fun::v2v::l2_norm< algebra::vec<2,float>, float > L2;
+    image2d<float> out = dt::naive(ima, L2());
+
+    std::cerr << "Distance:" << std::endl;
+    debug::println(out);
+  }
+}
Index: trunk/milena/sandbox/folio/test/dt/dt_maze.cc
===================================================================
--- trunk/milena/sandbox/folio/test/dt/dt_maze.cc	(revision 0)
+++ trunk/milena/sandbox/folio/test/dt/dt_maze.cc	(revision 3522)
@@ -0,0 +1,124 @@
+/*!
+ * \file   dt.cc
+ * \author ornthalas <ornthalas(a)gmail.com>
+ */
+
+#include <iostream>
+#include <mln/core/image/image2d.hh>
+#include <mln/debug/println.hh>
+#include <mln/make/win_chamfer.hh>
+#include <mln/data/fill.hh>
+#include <mln/core/alias/neighb2d.hh>
+
+#include <mln/io/ppm/load.hh>
+#include <mln/io/ppm/save.hh>
+#include <mln/io/pbm/save.hh>
+#include <mln/level/stretch.hh>
+#include <mln/data/paste.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/value/rgb8.hh>
+
+#include <mln/core/image/sub_image.hh>
+#include <mln/core/image/image_if.hh>
+#include <mln/pw/all.hh>
+
+#include "../dt/path.hh"
+// #include "../dt/raw_path_fast.hh"
+// #include "../dt/raw_path_slow.hh"
+
+int main()
+{
+  using namespace mln;
+
+  typedef image2d<value::rgb8> I;
+  typedef mln_point_(I) point;
+  point start;
+  point end;
+
+  I ima = io::ppm::load<value::rgb8>("tmp.ppm"); // "../img/monkeys_april.ppm");
+  mln_fwd_piter_(I) p(ima.domain());
+  mln_bkd_piter_(I) pp(ima.domain());
+
+  // Create window
+  int ws[] = { 3, 2, 3,
+	       2, 0, 2,
+	       3, 2, 3 };
+
+  // Search green point
+  std::cout << "search green point..." << std::endl;
+  for_all(p)
+    if (ima(p) == value::rgb8(0, 255, 0))
+    {
+      start = p;
+      break;
+    }
+  std::cout << "  => green point is " << start << std::endl << std::endl;
+
+  // Search red point
+  std::cout << "search red point..." << std::endl;
+  for_all(pp)
+    if (ima(pp) == value::rgb8(255, 0, 0))
+    {
+      end = pp;
+      break;
+    }
+  std::cout << "  => red point is " << end << std::endl << std::endl;
+
+  // Create mask
+  std::cout << "create mask..." << std::endl;
+  mln_ch_value_(I, bool) mask;
+  initialize(mask, ima);
+
+  for_all(p)
+    mask(p) = (ima(p) != value::rgb8(0, 0, 0));
+  std::cout << "  => saving mask.pbm..." << std::endl;
+  io::pbm::save(mask, "mask.pbm");
+  std::cout << "  => saved !" << std::endl << std::endl;
+
+  // Create input
+  std::cout << "create input..." << std::endl;
+  mln_ch_value_(I, bool) input;
+  initialize(input, ima);
+
+  for_all(p)
+    input(p) = (p == end);
+  std::cout << "  => saving input.pbm..." << std::endl;
+  io::pbm::save(input, "input.pbm");
+  std::cout << "  => saved !" << std::endl << std::endl;
+
+  // Create return image
+  std::cout << "create output..." << std::endl;
+  image2d<point> out;
+  std::cout << "  => done !" << std::endl << std::endl;
+
+  std::cout << "call path algorithm..." << std::endl;
+  out = dt::path(input | (pw::value(mask) == pw::cst(true)),
+		 make::w_window2d(ws), mln_max(unsigned));
+  std::cout << "  => done !" << std::endl << std::endl;
+
+  // Create output
+  std::cout << "create return image" << std::endl;
+  I ret;
+  initialize(ret, ima);
+  point c = start;
+
+  // Copy inut into ret
+  std::cout << "copy original image into return image..." << std::endl;
+  for_all(p)
+    ret(p) = ima(p);
+  std::cout << "  => done !" << std::endl << std::endl;
+
+  // Create path into ret
+  std::cout << "create path into return image..." << std::endl;
+  while (c != end)
+  {
+    ret(c) = value::rgb8(255, 0, 0);
+    c = out(c);
+  }
+  std::cout << "  => done !" << std::endl << std::endl;
+
+  // save
+  std::cout << "  => saving ret.ppm..." << std::endl;
+  io::ppm::save(ret, "ret.ppm");
+  std::cout << "  => saved !" << std::endl << std::endl;
+}
Index: trunk/milena/sandbox/folio/test/dt/chamfer.cc
===================================================================
--- trunk/milena/sandbox/folio/test/dt/chamfer.cc	(revision 0)
+++ trunk/milena/sandbox/folio/test/dt/chamfer.cc	(revision 3522)
@@ -0,0 +1,52 @@
+
+#include <iostream>
+#include <mln/core/image/image2d.hh>
+#include <mln/debug/println.hh>
+#include <mln/make/win_chamfer.hh>
+#include <mln/data/fill.hh>
+
+#include <mln/io/pbm/load.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/level/stretch.hh>
+#include <mln/value/int_u8.hh>
+
+#include "../dt/chamfer.hh"
+
+int main()
+{
+  using namespace mln;
+
+  w_window2d_int chamfer = make::mk_chamfer_3x3_int<1, 2>();
+
+  {
+//     image2d<bool> ima(5,5);
+//     bool vals[] = { 1, 1, 1, 0, 0,
+// 		    0, 0, 1, 0, 0,
+// 		    0, 0, 1, 0, 0,
+// 		    0, 0, 0, 0, 0,
+// 		    0, 0, 0, 0, 0 };
+
+//     data::fill(ima, vals);
+//     debug::println(ima);
+
+//     std::pair<image2d<int>, image2d<mln_point_(image2d<bool>)> > out;
+//     for (int i = 0; i < 999; ++i)
+//       out = dt::chamfer(ima, chamfer);
+
+//     std::cerr << "Distance:" << std::endl;
+//     debug::println(out.first);
+//     std::cerr << "PPP:" << std::endl;
+//     debug::println(out.second);
+
+  image2d<bool> ima = io::pbm::load("../../img/lena.pbm");
+
+  std::pair<image2d<int>, image2d<mln_point_(image2d<bool>)> > out;
+  out = dt::chamfer(ima, chamfer);
+
+  image2d<value::int_u8> out2(out.first.domain());
+  level::stretch(out.first, out2);
+
+  io::pgm::save(out2, "out.pgm");
+
+  }
+}
Index: trunk/milena/sandbox/folio/test/dt/dt_bench.cc
===================================================================
--- trunk/milena/sandbox/folio/test/dt/dt_bench.cc	(revision 0)
+++ trunk/milena/sandbox/folio/test/dt/dt_bench.cc	(revision 3522)
@@ -0,0 +1,53 @@
+/*!
+ * \file   dt.cc
+ * \author ornthalas <ornthalas(a)gmail.com>
+ */
+
+#include <iostream>
+#include <mln/core/image/image2d.hh>
+#include <mln/debug/println.hh>
+#include <mln/make/win_chamfer.hh>
+#include <mln/data/fill.hh>
+#include <mln/core/alias/neighb2d.hh>
+
+#include <mln/io/pbm/load.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/level/stretch.hh>
+#include <mln/data/paste.hh>
+#include <mln/value/int_u8.hh>
+
+#include <mln/core/image/sub_image.hh>
+#include <mln/core/image/image_if.hh>
+#include <mln/pw/value.hh>
+
+// #include "../dt/dmap.hh"
+#include "../dt/raw_dmap_fast.hh"
+#include "../dt/raw_dmap_slow.hh"
+
+// #include "../dt/iz.hh"
+// #include "../dt/raw_iz_fast.hh"
+// #include "../dt/raw_iz_slow.hh"
+
+// #include "../dt/cp.hh"
+// #include "../dt/raw_cp_fast.hh"
+// #include "../dt/raw_cp_slow.hh"
+
+int main()
+{
+  using namespace mln;
+
+  image2d<bool> ima = io::pbm::load("lena.pbm");
+
+  int ws[] = { 3, 2, 3,
+	       2, 0, 2,
+	       3, 2, 3 };
+  image2d<unsigned> out;
+//  for (int i = 0; i < 20; ++i)
+  out = dt::raw_dmap_fast(ima, make::w_window2d(ws), 666666);
+
+  image2d<value::int_u8> out2(out.domain());
+  level::stretch(out, out2);
+
+  io::pgm::save(out2, "out.pgm");
+}
+
Index: trunk/milena/sandbox/folio/test/dt/canvas/dt.hh
===================================================================
--- trunk/milena/sandbox/folio/test/dt/canvas/dt.hh	(revision 0)
+++ trunk/milena/sandbox/folio/test/dt/canvas/dt.hh	(revision 3522)
@@ -0,0 +1,101 @@
+/*!
+ * \file   psn.cc
+ * \author ornthalas <ornthalas(a)gmail.com>
+ */
+
+#ifndef DT_HH
+# define DT_HH
+
+// The 'fastest' specialization is in:
+# include "dt.spe.hh"
+
+namespace mln
+{
+
+  namespace dt
+  {
+
+    template<typename I, typename N, typename L>
+    inline
+    mln_ch_value(I, L)
+    dt(const Image<I>& input_, const N& nbh, const unsigned max);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+    namespace impl
+    {
+
+      // Generic functor.
+
+      template <typename I_, typename N_, typename L_>
+      struct dt_functor
+      {
+	typedef I_ I;
+	typedef N_ N;
+	typedef L_ L;
+
+	const I& input;
+	const N& nbh;
+	unsigned max;
+
+	dt_functor(const I_& input, const N_& nbh, const unsigned max)
+	  : input(input),
+	    nbh(nbh),
+	    max(max)
+	{}
+
+	void init() {}
+      };
+
+
+      // Generic implementation.
+
+      namespace generic
+      {
+
+	template<typename I, typename N, typename L>
+	inline
+	mln_ch_value(I, L)
+	dt_(const Image<I>& input, const N& nbh, const unsigned max)
+	{
+	  trace::entering("dt::impl::generic::dt_");
+
+	  typedef dt_functor<I, N, L> F;
+	  F f(input, nbh, max);
+	  canvas::dt<F> run(f);
+
+	  trace::exiting("dt::impl::generic::dt_");
+	  return run.output;
+	}
+
+      } // end of namespace mln::dt::impl::generic
+
+    } // end of namespace mln::dt::impl
+
+
+    // Facade.
+
+    template<typename I, typename N, typename L>
+    inline
+    mln_ch_value(I, L)
+    dt(const Image<I>& input, const N& nbh, const unsigned max)
+    {
+      trace::entering("dt::dt");
+      mln_precondition(exact(input).is_valid());
+
+      mln_ch_value(I, L) output =
+	impl::dt_(mln_trait_image_speed(I)(),
+		  exact(input), nbh, max);
+
+      trace::exiting("dt::dt");
+      return output;
+    }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace mln::dt
+
+} // end of namespace mln
+
+#endif // !DT_HH
Index: trunk/milena/sandbox/folio/test/dt/canvas/dt.spe.hh
===================================================================
--- trunk/milena/sandbox/folio/test/dt/canvas/dt.spe.hh	(revision 0)
+++ trunk/milena/sandbox/folio/test/dt/canvas/dt.spe.hh	(revision 3522)
@@ -0,0 +1,123 @@
+/*!
+ * \file   test_psn.spe.hh
+ * \author ornthalas <ornthalas(a)gmail.com>
+ */
+
+#ifndef DT_SPE_HH
+# define DT_SPE_HH
+
+# ifndef DT_HH
+#  error "Forbidden inclusion of *.spe.hh"
+# endif // ! DT_HH
+
+# include "canevas_dt.hh"
+
+namespace mln
+{
+
+  namespace dt
+  {
+
+    template<typename I, typename N, typename L>
+    inline
+    mln_ch_value(I, L)
+    dt(const Image<I>& input_, const N& nbh, const unsigned max);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+    namespace impl
+    {
+
+
+      // Fwd decl of the Generic version.
+
+      namespace generic
+      {
+
+	template<typename I, typename N, typename L>
+	inline
+	mln_ch_value(I, L)
+	dt_(const Image<I>& input_, const N& nbh, const unsigned max);
+
+      } // end of namespace mln::dt::impl::generic
+
+
+      // Fastest functor.
+
+      template <typename I_, typename N_, typename L_>
+      struct dt_fasfunctor
+      {
+	typedef I_ I;
+	typedef N_ N;
+	typedef L_ L;
+
+	const I& input;
+	const N& nbh;
+	unsigned max;
+
+	dt_fasfunctor(const I_& input, const N_& nbh, const unsigned max)
+	  : input(input),
+	    nbh(nbh),
+	    max(max)
+	{}
+
+	void init() {}
+      };
+
+
+      // Fastest implementation.
+
+      namespace fastest
+      {
+
+	template<typename I, typename N, typename L>
+	inline
+	mln_ch_value(I, L)
+        dt_(const I& input, const N& nbh, const unsigned max)
+	{
+	  trace::entering("dt::impl::dt_fas");
+
+	  typedef dt_fasfunctor<I,N,L> F;
+	  F f(input, nbh, max);
+	  canvas::dt_fastest<F> run(f);
+b
+	  trace::exiting("dt::impl::dt_fas");
+	  return run.output;
+	}
+
+      } // end of namespace mln::dt::impl::fastest
+
+
+      // Disjunction between "fastest" and "not fastest".
+
+      template<typename I, typename N, typename L>
+      inline
+      mln_ch_value(I, L)
+      dt_(trait::image::speed::any,
+	  const I& input, const N& nbh, const unsigned max)
+      {
+	return generic::dt_(input, nbh, max);
+      }
+
+      template<typename I, typename N, typename L>
+      inline
+      mln_ch_value(I, L)
+      dt_(trait::image::speed::fastest,
+	  const I& input, const N& nbh, const unsigned max)
+      {
+	return fastest::dt_(input, nbh, max);
+      }
+
+
+    } // end of namespace mln::dt::impl
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace mln::dt
+
+} // end of namespace mln
+
+
+#endif // !DT_SPE_HH
Index: trunk/milena/sandbox/folio/test/dt/dt.cc
===================================================================
--- trunk/milena/sandbox/folio/test/dt/dt.cc	(revision 0)
+++ trunk/milena/sandbox/folio/test/dt/dt.cc	(revision 3522)
@@ -0,0 +1,66 @@
+/*!
+ * \file   dt.cc
+ * \author ornthalas <ornthalas(a)gmail.com>
+ */
+
+#include <iostream>
+#include <mln/core/image/image2d.hh>
+#include <mln/debug/println.hh>
+#include <mln/make/win_chamfer.hh>
+#include <mln/data/fill.hh>
+#include <mln/core/alias/neighb2d.hh>
+
+#include <mln/io/pbm/load.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/level/stretch.hh>
+#include <mln/data/paste.hh>
+#include <mln/value/int_u8.hh>
+
+#include <mln/core/image/sub_image.hh>
+#include <mln/core/image/image_if.hh>
+#include <mln/pw/value.hh>
+
+#include "../dt/dmap.hh"
+// #include "../dt/raw_dmap_fast.hh"
+// #include "../dt/raw_dmap_slow.hh"
+
+// #include "../dt/path.hh"
+// #include "../dt/raw_path_fast.hh"
+// #include "../dt/raw_path_slow.hh"
+
+// #include "../dt/cp.hh"
+// #include "../dt/raw_cp_fast.hh"
+// #include "../dt/raw_cp_slow.hh"
+
+int main()
+{
+  using namespace mln;
+
+  image2d<bool> ima(5,5);
+  bool vals[] = { 1, 0, 0, 1, 1,
+		  0, 0, 0, 0, 0,
+		  0, 0, 0, 0, 0,
+		  0, 0, 0, 1, 0,
+		  0, 0, 0, 0, 0};
+  data::fill(ima, vals);
+
+  image2d<bool> msk(5,5);
+  bool rest[] = { 1, 0, 1, 1, 1,
+		  1, 0, 1, 1, 1,
+		  1, 1, 0, 0, 0,
+		  1, 1, 0, 1, 1,
+		  1, 1, 1, 1, 1};
+  data::fill(msk, rest);
+
+  int ws[] = { 3, 2, 3,
+	       2, 0, 2,
+	       3, 2, 3 };
+
+//  image2d<mln_point_(image2d<bool>)> out;
+  image2d<unsigned> out;
+  out = dt::dmap(ima | pw::value(msk), make::w_window2d(ws), 50);
+
+//  debug::println(ima);
+  debug::println(ima | pw::value(msk));
+  debug::println(out);
+}
Index: trunk/milena/sandbox/folio/test/dt/tmp.ppm
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: trunk/milena/sandbox/folio/test/dt/tmp.ppm
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream
Index: trunk/milena/sandbox/folio/dt_old/psn.cc
===================================================================
--- trunk/milena/sandbox/folio/dt_old/psn.cc	(revision 0)
+++ trunk/milena/sandbox/folio/dt_old/psn.cc	(revision 3522)
@@ -0,0 +1,203 @@
+// 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_DT_CHAMFER_HH
+# define MLN_DT_CHAMFER_HH
+
+# include <queue>
+# include <map>
+# include <cmath>
+
+# include <mln/core/concept/image.hh>
+# include <mln/make/w_window.hh>
+# include <mln/core/concept/neighborhood.hh>
+# include <mln/literal/zero.hh>
+
+# include <iostream>
+
+namespace mln
+{
+
+  namespace dt
+  {
+
+    /*! Propagation using a single neighborhood (PSN).
+     *
+     * \param[in]  input_   The input image.
+     * \param[in]  nbh      The chamfer window to use for distance calcul.
+     * \param[in]  max      Max value of the output image.
+     * \return              A distance map.
+     *
+     * \pre \p img has to be initialized.
+     */
+    template<typename I, typename N>
+    mln_ch_value(I, unsigned)
+    psn(const Image<I>& input_, const N& nbh, unsigned max);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+    namespace impl
+    {
+    } // end of namespace mln::dt::impl
+
+
+
+    // Facade.
+
+    template<typename I, typename N>
+    inline
+    mln_ch_value(I, unsigned)
+    psn(const Image<I>& input_, const N& nbh, unsigned max)
+    {
+      // Preconditions.
+      const I& input = exact(input_);
+      mln_precondition(input.is_valid());
+
+      // Types.
+      typedef mln_point(I) point;
+
+      // Initialization of output.
+      mln_ch_value(I, unsigned) output;
+      initialize(output, input);
+
+      // Initialization.
+      // {
+
+      std::map<unsigned, std::queue<point> > bucket;
+      unsigned bucket_size = 0;
+
+      mln_fwd_piter(I) p(input.domain());
+      for_all(p)
+	if (input(p))
+	{
+	  output(p) = literal::zero;
+	  bucket[0].push(p);
+	  ++bucket_size;
+	}
+	else
+	  output(p) = max;
+
+      unsigned d = 0;
+
+      // }
+
+      while (bucket_size != 0)
+      {
+	std::queue<point> bucket_d = bucket[d];
+	while (! bucket_d.empty())
+	{
+	  point p = bucket_d.front();
+	  bucket_d.pop();
+	  --bucket_size;
+
+	  if (output(p) == d)
+	  {
+	    mln_qiter(N) n(nbh, p);
+
+	    for_all(n)
+	      if (output.has(n))
+	      {
+		unsigned newOut = output(p) + n.w();
+
+		if (newOut < output(n))
+		{
+		  output(n) = newOut;
+		  bucket[newOut].push(n);
+		  ++bucket_size;
+		}
+	      }
+	  }
+	}
+	bucket.erase(d);
+	++d;
+      }
+
+      return output;
+    }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace mln::dt
+
+} // end of namespace mln
+
+#endif // ! MLN_DT_CHAMFER_HH
+
+#include <iostream>
+#include <mln/core/image/image2d.hh>
+#include <mln/debug/println.hh>
+#include <mln/make/win_chamfer.hh>
+#include <mln/data/fill.hh>
+#include <mln/core/alias/neighb2d.hh>
+
+#include <mln/io/pbm/load.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/level/stretch.hh>
+#include <mln/value/int_u8.hh>
+
+#include <mln/core/image/sub_image.hh>
+#include <mln/core/image/image_if.hh>
+#include <mln/pw/value.hh>
+
+int main()
+{
+  using namespace mln;
+
+  image2d<bool> ima(5,5);
+  bool vals[] = { 1, 0, 0, 1, 1,
+		  0, 0, 0, 0, 0,
+		  0, 0, 0, 0, 0,
+		  0, 0, 0, 1, 0,
+		  0, 0, 0, 0, 0};
+  data::fill(ima, vals);
+
+  image2d<bool> msk(5,5);
+  bool rest[] = { 1, 0, 1, 1, 1,
+		  1, 0, 1, 1, 1,
+		  1, 1, 0, 0, 0,
+		  1, 1, 0, 1, 1,
+		  1, 1, 1, 1, 1};
+  data::fill(msk, rest);
+
+  int ws[] = { 2, 1, 2,
+	       1, 0, 1,
+	       2, 1, 2 };
+  image2d<unsigned> out;
+  out = dt::psn(ima | pw::value(msk), make::w_window2d(ws), 50);
+
+  debug::println(ima | pw::value(msk));
+  debug::println(out);
+
+//  image2d<bool> ima = io::pbm::load("../../img/c01.pbm");
+
+//  image2d<value::int_u8> out2(out.domain());
+//  level::stretch(out, out2);
+
+//  io::pgm::save(out2, "out.pgm");
+}
Index: trunk/milena/sandbox/folio/dt_old/canevas_dt.hh
===================================================================
--- trunk/milena/sandbox/folio/dt_old/canevas_dt.hh	(revision 0)
+++ trunk/milena/sandbox/folio/dt_old/canevas_dt.hh	(revision 3522)
@@ -0,0 +1,231 @@
+/*!
+ * \file   canevas_dt.hh
+ * \author ornthalas <ornthalas(a)gmail.com>
+ */
+
+#ifndef CANEVAS_DT_HH
+# define CANEVAS_DT_HH
+
+# include <queue>
+# include <map>
+# include <mln/core/concept/image.hh>
+# include <mln/make/w_window.hh>
+# include <mln/literal/zero.hh>
+
+# include <mln/core/concept/neighborhood.hh>
+
+namespace mln
+{
+
+  namespace canvas
+  {
+
+    // General version.
+
+    template <typename F>
+    struct dt
+    {
+      // Functor.
+      F& f;
+
+      typedef typename F::I I;
+      typedef typename F::N N;
+      typedef typename F::L L;
+      typedef mln_psite(I) point;
+
+      mln_ch_value(I, L) output;
+
+      // Ctor.
+      dt(F& f);
+
+      void init();
+      void run();
+
+      std::map<unsigned, std::queue<point> > bucket;
+      unsigned bucket_size;
+
+      unsigned current_distance;
+    };
+
+    template <typename F>
+    struct dt_fastest
+    {
+      // Functor.
+      F& f;
+
+      typedef typename F::I I;
+      typedef typename F::N N;
+      typedef typename F::L L;
+      typedef mln_psite(I) point;
+
+      mln_ch_value(I, L) output;
+
+      // Ctor.
+      dt_fastest(F& f);
+
+      void init();
+      void run();
+
+      std::map<unsigned, std::queue<point> > bucket;
+      unsigned bucket_size;
+
+      unsigned current_distance;
+    };
+
+# ifndef MLN_INCLUDE_ONLY
+
+    /*-------------.
+    | canvas::dt.  |
+    `-------------*/
+
+    template <typename F>
+    dt<F>::dt(F& f)
+      : f(f),
+	bucket_size(0),
+	current_distance(0)
+    {
+      trace::entering("canvas::dt");
+
+      this->init();
+      this->run();
+
+      trace::exiting("canvas::dt");
+    }
+
+    template <typename F>
+    void
+    dt<F>::init()
+    {
+      this->f.init();
+      initialize(this->output, this->f.input);
+
+      mln_fwd_piter(I) p(this->f.input.domain());
+      for_all(p)
+	if (this->f.input(p))
+	{
+	  this->output(p) = literal::zero;
+	  this->bucket[0].push(p);
+	  ++this->bucket_size;
+	}
+	else
+	  this->output(p) = this->max;
+    }
+
+    template <typename F>
+    void
+    dt<F>::run()
+    {
+      while (this->bucket_size != 0)
+      {
+	std::queue<point> bucket_d = this->bucket[this->current_distance];
+	while (! bucket_d.empty())
+	{
+	  point p = bucket_d.front();
+	  bucket_d.pop();
+	  --bucket_size;
+
+	  if (this->output(p) == this->current_distance)
+	  {
+	    mln_qiter(N) n(this->nbh, p);
+
+	    for_all(n)
+	      if (this->output.has(n))
+	      {
+		unsigned new_out = this->output(p) + n.w();
+
+		if (new_out < this->output(n))
+		{
+		  this->output(n) = new_out;
+		  this->bucket[new_out].push(n);
+		  ++this->bucket_size;
+		}
+	      }
+	  }
+	}
+	this->bucket.erase(this->current_distance);
+	++this->current_distance;
+      }
+    }
+
+    /*---------------------.
+    | canvas::dt_fastest.  |
+    `---------------------*/
+    template <typename F>
+    dt_fastest<F>::dt_fastest(F& f)
+      : f(f),
+	bucket_size(0),
+	current_distance(0)
+    {
+      trace::entering("canvas::dt");
+
+      this->init();
+      this->run();
+
+      trace::exiting("canvas::dt");
+    }
+
+    template <typename F>
+    void
+    dt_fastest<F>::init()
+    {
+      this->f.init();
+      initialize(this->output, this->f.input);
+
+      mln_fwd_piter(I) p(this->f.input.domain());
+      for_all(p)
+	if (this->f.input(p))
+	{
+	  this->output(p) = literal::zero;
+	  this->bucket[0].push(p);
+	  ++this->bucket_size;
+	}
+	else
+	  this->output(p) = this->max;
+    }
+
+    template <typename F>
+    void
+    dt_fastest<F>::run()
+    {
+      while (this->bucket_size != 0)
+      {
+	std::queue<point> bucket_d = this->bucket[this->current_distance];
+	while (! bucket_d.empty())
+	{
+	  point p = bucket_d.front();
+	  bucket_d.pop();
+	  --bucket_size;
+
+	  if (this->output(p) == this->current_distance)
+	  {
+	    mln_qiter(N) n(this->nbh, p);
+
+	    for_all(n)
+	      if (this->output.has(n))
+	      {
+		unsigned new_out = this->output(p) + n.w();
+
+		if (new_out < this->output(n))
+		{
+		  this->output(n) = new_out;
+		  this->bucket[new_out].push(n);
+		  ++this->bucket_size;
+		}
+	      }
+	  }
+	}
+	this->bucket.erase(this->current_distance);
+	++this->current_distance;
+      }
+    }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+
+  } // end of namespace mln::canvas
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CANVAS_DT_HH
Index: trunk/milena/sandbox/folio/dt_old/dt.hh
===================================================================
--- trunk/milena/sandbox/folio/dt_old/dt.hh	(revision 0)
+++ trunk/milena/sandbox/folio/dt_old/dt.hh	(revision 3522)
@@ -0,0 +1,101 @@
+/*!
+ * \file   psn.cc
+ * \author ornthalas <ornthalas(a)gmail.com>
+ */
+
+#ifndef DT_HH
+# define DT_HH
+
+// The 'fastest' specialization is in:
+# include "dt.spe.hh"
+
+namespace mln
+{
+
+  namespace dt
+  {
+
+    template<typename I, typename N, typename L>
+    inline
+    mln_ch_value(I, L)
+    dt(const Image<I>& input_, const N& nbh, unsigned max);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+    namespace impl
+    {
+
+      // Generic functor.
+
+      template <typename I_, typename N_, typename L_>
+      struct dt_functor
+      {
+	typedef I_ I;
+	typedef N_ N;
+	typedef L_ L;
+
+	const I& input;
+	const N& nbh;
+	unsigned max;
+
+	dt_functor(const I_& input, const N_& nbh, const unsigned max)
+	  : input(input),
+	    nbh(nbh),
+	    max(max)
+	{}
+
+	void init() {}
+      };
+
+
+      // Generic implementation.
+
+      namespace generic
+      {
+
+	template<typename I, typename N, typename L>
+	inline
+	mln_ch_value(I, L)
+	dt_(const Image<I>& input, const N& nbh, unsigned max)
+	{
+	  trace::entering("dt::impl::generic::dt_");
+
+	  typedef dt_functor<I, N, L> F;
+	  F f(input, nbh, max);
+	  canvas::dt<F> run(f);
+
+	  trace::exiting("dt::impl::generic::dt_");
+	  return run.output;
+	}
+
+      } // end of namespace mln::dt::impl::generic
+
+    } // end of namespace mln::dt::impl
+
+
+    // Facade.
+
+    template<typename I, typename N, typename L>
+    inline
+    mln_ch_value(I, L)
+    dt(const Image<I>& input, const N& nbh, unsigned max)
+    {
+      trace::entering("dt::dt");
+      mln_precondition(exact(input).is_valid());
+
+      mln_ch_value(I, L) output =
+	impl::dt_(mln_trait_image_speed(I)(),
+		  exact(input), nbh, max);
+
+      trace::exiting("dt::dt");
+      return output;
+    }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace mln::dt
+
+} // end of namespace mln
+
+#endif // !DT_HH
Index: trunk/milena/sandbox/folio/dt_old/psn_log.cc
===================================================================
--- trunk/milena/sandbox/folio/dt_old/psn_log.cc	(revision 0)
+++ trunk/milena/sandbox/folio/dt_old/psn_log.cc	(revision 3522)
@@ -0,0 +1,290 @@
+
+// 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_DT_CHAMFER_HH
+# define MLN_DT_CHAMFER_HH
+
+# include <vector>
+# include <queue>
+# include <map>
+# include <cmath>
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/neighborhood.hh>
+# include <mln/literal/zero.hh>
+
+#include <mln/core/image/image2d.hh>
+# include <mln/debug/println.hh>
+
+namespace mln
+{
+
+  namespace dt
+  {
+
+    /*! Propagation using a single neighborhood (PSN).
+     *
+     * \param[in]  input_   The input image.
+     * \param[in]  chamfer  The chamfer window to use for distance calcul.
+     * \return              A pair <distance map, closest point map>.
+     *
+     * \pre \p img has to be initialized.
+     */
+    template<typename I, typename N>
+    mln_ch_value(I, unsigned)
+    psn(const Image<I>& input_, const N& nbh);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+    namespace impl
+    {
+
+      template <typename BP>
+      class compare
+      {
+      public:
+	bool
+	operator()(const BP& lhs, const BP& rhs) const
+	{
+	  return lhs.second > rhs.second;
+	}
+      };
+
+      template <typename D>
+      unsigned
+      sq(const D& dp)
+      {
+	unsigned res = 0;
+
+	for (unsigned i = 0; i < D::dim; ++i)
+	  res += std::abs(dp[i]); // FIXME: dp[i] * dp[i];
+
+	return res;
+      }
+
+      template <typename BP>
+      unsigned
+      size(const std::map<unsigned, std::queue<BP> >& bucket,
+	   int d)
+      {
+	unsigned s = 0;
+	typename std::map<unsigned, std::queue<BP> >::const_iterator i;
+	for (i = bucket.begin(); i != bucket.end(); ++i)
+	  if (i->first >= d)
+	    s += i->second.size();
+	return s;
+      }
+
+      template <typename BP>
+      unsigned
+      size(const std::map<unsigned, std::queue<BP> >& bucket)
+      {
+	unsigned s = 0;
+	typename std::map<unsigned, std::queue<BP> >::const_iterator i;
+	for (i = bucket.begin(); i != bucket.end(); ++i)
+	  s += i->second.size();
+	return s;
+      }
+
+      template <typename BP>
+      void
+      print(const std::map<unsigned, std::queue<BP> >& bucket)
+      {
+	typename std::map<unsigned, std::queue<BP> >::const_iterator i;
+	int d = -1;
+	for (i = bucket.begin(); i != bucket.end(); ++i)
+	  {
+	    if (i->first != d)
+	      {
+		d = i->first;
+		std::cout << std::endl << d << ": ";
+	      }
+	    std::queue<BP> qu = i->second; // copy
+	    std::vector<BP> v;
+	    v.push_back(qu.front()); qu.pop();
+	    typename std::vector<BP>::const_iterator j;
+	    for (j = v.begin(); j != v.end(); ++j)
+	      std::cout << j->first << " "; // point
+	  }
+	std::cout << std::endl;
+      }
+
+    } // end of namespace mln::dt::impl
+
+
+
+    // Facade.
+
+    template<typename I, typename N>
+    inline
+    mln_ch_value(I, unsigned)
+    psn(const Image<I>& input_, const N& nbh)
+    {
+      const I& input = exact(input_);
+      mln_precondition(input.is_valid());
+
+      mln_ch_value(I, unsigned) D;
+      initialize(D, input);
+
+      static const unsigned M = 666; // FIXME
+
+      // Initialization.
+      typedef mln_point(I) point;
+      typedef mln_dpoint(I) dpoint;
+      typedef std::pair<point, dpoint> BP;
+
+      std::map<unsigned, std::queue<BP> > bucket;
+      unsigned bucket_size = 0;
+
+      mln_fwd_piter(I) p(input.domain());
+      for_all(p)
+	if (input(p))
+	{
+	  D(p) = literal::zero;
+	  bucket[0].push(BP(p, literal::zero));
+	  ++bucket_size;
+	}
+	else
+	  D(p) = M;
+
+      debug::println(input);
+      debug::println(D);
+      impl::print(bucket);
+
+      unsigned d = 0;
+
+      while (impl::size(bucket, d) != 0)
+      {
+
+	mln_invariant(impl::size(bucket) == bucket_size);
+
+	std::cout << "PROCESSING  d = " << d << std::endl;
+	  
+	std::queue<BP>& bucket_d = bucket[d];
+
+	while (! bucket_d.empty())
+	{
+	  point p = bucket_d.front().first;
+	  dpoint dp = bucket_d.front().second;
+
+	  bucket_d.pop();
+	  --bucket_size;
+
+	  std::cout << "pop " << p << " at D=" << D(p) << std::endl;
+
+	  if (D(p) == d)
+	  {
+	    mln_niter(N) n_(nbh, p);
+
+	    for_all(n_)
+	      if (D.has(n_))
+	      {
+		dpoint n = n_ - p;
+		unsigned newD = impl::sq(dp + n);
+
+		std::cout << "  n=" << n_ << " at D=" << D(n_)
+			  << " and newD=" << newD
+			  << (newD < D(p + n) ? "   push" : "")
+			  << std::endl;
+
+		if (newD < D(p + n)) // p + n = p + n_ - p = n_
+		{
+		  D(n_) = newD;
+		  bucket[newD].push(BP(p + n, dp + n));
+		  ++bucket_size;
+		}
+	      }
+	  }
+	}
+	++d;
+      }
+
+      return D;
+    }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace mln::dt
+
+} // end of namespace mln
+
+#endif // ! MLN_DT_CHAMFER_HH
+
+#include <iostream>
+#include <mln/debug/println.hh>
+#include <mln/make/win_chamfer.hh>
+#include <mln/data/fill.hh>
+#include <mln/core/alias/neighb2d.hh>
+
+#include <mln/io/pbm/load.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/level/stretch.hh>
+#include <mln/value/int_u8.hh>
+
+#include <mln/core/image/sub_image.hh>
+#include <mln/core/image/image_if.hh>
+#include <mln/pw/value.hh>
+
+int main()
+{
+  using namespace mln;
+
+//   image2d<bool> ima(5,5);
+//   bool vals[] = { 1, 1, 1, 0, 0,
+// 		  0, 0, 1, 0, 0,
+// 		  0, 0, 1, 0, 0,
+// 		  0, 0, 0, 0, 0,
+// 		  0, 0, 0, 0, 0 };
+
+  image2d<bool> ima(3,3);
+  bool vals[] = { 1, 0, 0,
+		  0, 0, 0,
+		  0, 0, 0};
+  data::fill(ima, vals);
+
+  image2d<bool> msk(3,3);
+  bool rest[] = { 1, 0, 1,
+		  1, 0, 1,
+		  1, 1, 1};
+  data::fill(msk, rest);
+
+  image2d<unsigned> out;
+  out = dt::psn(ima | pw::value(msk), c4());
+
+  debug::println(ima | pw::value(msk));
+  debug::println(out);
+
+//  image2d<bool> ima = io::pbm::load("../../img/c01.pbm");
+
+//  image2d<value::int_u8> out2(out.domain());
+//  level::stretch(out, out2);
+
+//  io::pgm::save(out2, "out.pgm");
+}
Index: trunk/milena/sandbox/folio/dt_old/distance_front.cc
===================================================================
--- trunk/milena/sandbox/folio/dt_old/distance_front.cc	(revision 0)
+++ trunk/milena/sandbox/folio/dt_old/distance_front.cc	(revision 3522)
@@ -0,0 +1,88 @@
+// Copyright (C) 2008, 2009 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.
+
+/// \file tests/transform/distance_front.cc
+///
+/// Test on mln::transform::distance_front.
+
+#include <mln/core/var.hh>
+#include <mln/core/image/image2d.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/make/w_window2d_int.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/data/fill.hh>
+#include <mln/debug/println.hh>
+#include <mln/opt/at.hh>
+#include <mln/level/compare.hh>
+
+#include <mln/transform/internal/distance_functor.hh>
+#include "distance_front_new.hh"
+
+
+int main()
+{
+  using namespace mln;
+  using value::int_u8;
+
+  typedef image2d<bool> I;
+
+  I input(9, 9);
+  data::fill(input, false);
+  opt::at(input, 4, 4) = true;
+
+
+  int_u8 dmax = 18;
+  mln_VAR(nbh, c4());
+
+  int ws[] = { 0, 9, 0, 9, 0,
+	       9, 6, 4, 6, 9,
+	       0, 4, 0, 4, 0,
+	       9, 6, 4, 6, 9,
+	       0, 9, 0, 9, 0 };
+  mln_VAR(w_win, make::w_window2d_int(ws));
+
+
+  transform::internal::distance_functor<I> f;
+  image2d<int_u8> ref, output;
+
+  ref = canvas::impl::generic::distance_front(input,
+					      nbh,
+					      w_win,
+					      dmax,
+					      f);
+  // debug::println("ref", ref);
+
+  output = canvas::impl::distance_front_fastest(input,
+						nbh,
+						w_win,
+						dmax,
+						f);
+  // debug::println("output", output);
+
+  mln_invariant(output == ref);
+}
Property changes on: trunk/milena/sandbox/folio/dt_old/distance_front.cc
___________________________________________________________________
Name: svn:mergeinfo
   + 
Index: trunk/milena/sandbox/folio/dt_old/naive.cc
===================================================================
--- trunk/milena/sandbox/folio/dt_old/naive.cc	(revision 0)
+++ trunk/milena/sandbox/folio/dt_old/naive.cc	(revision 3522)
@@ -0,0 +1,142 @@
+// Copyright (C) 2007, 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.
+
+/*! \file TODO
+ *
+ * \brief Defines a function that creates a distance map corresponding to a
+ * given image.
+ */
+
+#ifndef MLN_DT_NAIVE_HH
+# define MLN_DT_NAIVE_HH
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/function.hh>
+# include <mln/literal/zero.hh>
+# include <mln/accu/min.hh>
+
+namespace mln
+{
+
+  namespace dt
+  {
+
+    /*! Calculates the distance map corresponding to a given image
+     *
+     * \param[in] input_ The binary reference image.
+     * \param[in] fun_   The function used for distance aclculus.
+     * \return           New distance map image.
+     *
+     * \pre \p input_ has to be initialized.
+     *
+     * \fixme Use instead of R the result type of F::operator().
+     */
+    template <typename I, typename F>
+    inline
+    mln_ch_value(I, mln_result(F))
+    naive(const Image<I>& input_, const Function_v2v<F>& fun_);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+    // Facade.
+
+    template <typename I, typename F>
+    inline
+    mln_ch_value(I, mln_result(F))
+    naive(const Image<I>& input_, const Function_v2v<F>& fun_)
+    {
+      const I& input = exact(input_);
+      const F& fun   = exact(fun_);
+      mln_precondition(input.is_valid());
+
+      mln_ch_value(I, mln_result(F)) output;
+      initialize(output, input);
+
+      mln_piter(I) p(input.domain());
+      for_all(p)
+      {
+	if (input(p))
+	  output(p) = literal::zero;
+	else
+	{
+	  // p is in the background so the distance has to be computed.
+	  accu::min_<mln_result(F)> min;
+          min.init();
+
+          mln_piter(I) q(input.domain());
+          for_all(q)
+            if (input(q))
+              {
+		// q is in the object.
+//                 metal::vec<2, int> vp = p.to_point(), vq = q.to_point();
+//                 min.take(fun_(vp, vq));
+		min.take(fun(p - q));
+              }
+          output(p) = min;
+	}
+      }
+
+      return output;
+    }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace mln::dt
+
+} // end of namespace mln
+
+#endif // ! MLN_DT_NAIVE_HH
+
+#include <iostream>
+#include <mln/debug/println.hh>
+#include <mln/core/image/image2d.hh>
+#include <mln/data/fill.hh>
+#include <mln/fun/v2v/norm.hh>
+
+int main()
+{
+  using namespace mln;
+
+  {
+    image2d<bool> ima(5,5);
+    bool vals[] = { 1, 1, 1, 0, 0,
+		    0, 0, 1, 0, 0,
+		    0, 0, 1, 0, 0,
+		    0, 0, 0, 0, 0,
+		    0, 0, 0, 0, 0 };
+
+    data::fill(ima, vals);
+    debug::println(ima);
+
+    typedef fun::v2v::l2_norm< algebra::vec<2,float>, float > L2;
+    image2d<float> out = dt::naive(ima, L2());
+
+    std::cerr << "Distance:" << std::endl;
+    debug::println(out);
+  }
+}
Index: trunk/milena/sandbox/folio/dt_old/chamfer.cc
===================================================================
--- trunk/milena/sandbox/folio/dt_old/chamfer.cc	(revision 0)
+++ trunk/milena/sandbox/folio/dt_old/chamfer.cc	(revision 3522)
@@ -0,0 +1,206 @@
+// 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_DT_CHAMFER_HH
+# define MLN_DT_CHAMFER_HH
+
+# include <mln/core/concept/image.hh>
+# include <mln/make/w_window.hh>
+
+namespace mln
+{
+
+  namespace dt
+  {
+
+    /*! Distance tranform by chamfer application.
+     *
+     * \param[in]  input_   The input image.
+     * \param[in]  chamfer  The chamfer window to use for distance calcul.
+     * \return              A pair (distance map, nearest point map).
+     *
+     * \pre \p img has to be initialized.
+     */
+    template<typename I, typename T>
+    std::pair<mln_ch_value(I, T), mln_ch_value(I, mln_point(I))>
+    chamfer(const Image<I>& input_,
+	    w_window<mln_dpoint(I), T> chamfer);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+    namespace impl
+    {
+
+      /*! Computes a pass of the chamfer DT algorithm.
+       *
+       * \param[in]  p              Iterator on the input image to use.
+       * \param[in]  chamfer        The chamfer window to use for distance calcul.
+       * \param[in]  input          The input image.
+       * \param[out] outputDistance The distance map updated.
+       * \param[out] outputnearest  The nearest points map updated.
+       */
+      template<typename Q, typename I, typename T>
+      inline
+      void
+      chamfer_pass(const w_window<mln_dpoint(I), T> chamfer,
+		   const I& input,
+		   mln_ch_value(I, T)& outputDistance,
+		   mln_ch_value(I, mln_point(I))& outputNearest)
+      {
+	typedef w_window<mln_dpoint(I), T> W;
+
+	Q p(input.domain());
+	mln_qiter(W) q(chamfer, p);
+	for_all(p)
+	{
+	  std::pair<T, mln_point(I)> min(mln_max(T), p);
+
+	  for_all(q)
+	    if (input.has(q) && outputDistance(q) != mln_max(T))
+	    {
+	      T v = outputDistance(q) + q.w();
+
+	      if (v < min.first)
+	      {
+		min.first = v;
+		min.second = outputNearest(q);
+	      }
+	    }
+
+	  if (min.first < outputDistance(p))
+	  {
+	    outputDistance(p) = min.first;
+	    outputNearest(p) = min.second;
+	  }
+	}
+      }
+
+    } // end of namespace mln::dt::impl
+
+
+
+    // Facade.
+
+    template<typename I, typename T>
+    inline
+    std::pair<mln_ch_value(I, T), mln_ch_value(I, mln_point(I))>
+    chamfer(const Image<I>& input_,
+	    w_window<mln_dpoint(I), T> chamfer)
+    {
+      typedef w_window<mln_dpoint(I), T> W;
+
+      const I& input = exact(input_);
+      mln_precondition(input.is_valid());
+
+      mln_ch_value(I, T) outputDistance;
+      initialize(outputDistance, input);
+
+      mln_ch_value(I, mln_point(I)) outputNearest;
+      initialize(outputNearest, input);
+
+      // Initialization.
+      {
+	mln_fwd_piter(I) p(input.domain());
+	for_all(p)
+	{
+	  outputDistance(p) = input(p) ? literal::zero : mln_max(T);
+	  outputNearest(p) = p;
+	}
+      }
+
+      // First pass.
+      impl::chamfer_pass<mln_fwd_piter(I)>
+	(chamfer, input, outputDistance, outputNearest);
+
+      chamfer.sym();
+
+      // Second pass.
+      impl::chamfer_pass<mln_bkd_piter(I)>
+	(chamfer, input, outputDistance, outputNearest);
+
+      return std::pair<mln_ch_value(I, T), mln_ch_value(I, mln_point(I))>
+	(outputDistance, outputNearest);
+    }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace mln::dt
+
+} // end of namespace mln
+
+#endif // ! MLN_DT_CHAMFER_HH
+
+#include <iostream>
+#include <mln/core/image/image2d.hh>
+#include <mln/debug/println.hh>
+#include <mln/make/win_chamfer.hh>
+#include <mln/data/fill.hh>
+
+#include <mln/io/pbm/load.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/level/stretch.hh>
+#include <mln/value/int_u8.hh>
+
+int main()
+{
+  using namespace mln;
+
+  w_window2d_int chamfer = make::mk_chamfer_3x3_int<1, 2>();
+
+  {
+//     image2d<bool> ima(5,5);
+//     bool vals[] = { 1, 1, 1, 0, 0,
+// 		    0, 0, 1, 0, 0,
+// 		    0, 0, 1, 0, 0,
+// 		    0, 0, 0, 0, 0,
+// 		    0, 0, 0, 0, 0 };
+
+//     data::fill(ima, vals);
+//     debug::println(ima);
+
+//     std::pair<image2d<int>, image2d<mln_point_(image2d<bool>)> > out;
+//     for (int i = 0; i < 999; ++i)
+//       out = dt::chamfer(ima, chamfer);
+
+//     std::cerr << "Distance:" << std::endl;
+//     debug::println(out.first);
+//     std::cerr << "PPP:" << std::endl;
+//     debug::println(out.second);
+
+  image2d<bool> ima = io::pbm::load("../../img/c01.pbm");
+
+  std::pair<image2d<int>, image2d<mln_point_(image2d<bool>)> > out;
+  out = dt::chamfer(ima, chamfer);
+
+  image2d<value::int_u8> out2(out.first.domain());
+  level::stretch(out.first, out2);
+
+  io::pgm::save(out2, "out.pgm");
+
+  }
+}
Index: trunk/milena/sandbox/folio/dt_old/distance_front_new.hh
===================================================================
--- trunk/milena/sandbox/folio/dt_old/distance_front_new.hh	(revision 0)
+++ trunk/milena/sandbox/folio/dt_old/distance_front_new.hh	(revision 3522)
@@ -0,0 +1,420 @@
+// 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_CANVAS_DISTANCE_FRONT_HH
+# define MLN_CANVAS_DISTANCE_FRONT_HH
+
+/// \file mln/canvas/distance_front.hh
+///
+/// Discrete distance canvas by front propagation.
+
+# include <vector>
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/neighborhood.hh>
+# include <mln/core/concept/weighted_window.hh>
+# include <mln/data/fill.hh>
+# include <mln/accu/max.hh>
+# include <mln/extension/adjust_fill.hh>
+
+
+namespace mln
+{
+
+  namespace canvas
+  {
+
+    /// Discrete front distance canvas.
+    template <typename I,
+	      typename N, typename W, typename D,
+	      typename F>
+    mln_ch_value(I, D)
+      distance_front(const Image<I>& input,
+		     const Neighborhood<N>& nbh, const Weighted_Window<W>& w_win, D max,
+		     F& functor);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+    // Tests.
+
+    namespace internal
+    {
+
+      template <typename I,
+		typename N, typename W, typename D,
+		typename F>
+      void
+      distance_front_tests(const Image<I>& input_,
+			   const Neighborhood<N>& nbh_,
+			   const Weighted_Window<W>& w_win_,
+			   D max,
+			   F& functor)
+      {
+	const I& input = exact(input_);
+	const N& nbh   = exact(nbh_);
+	const W& w_win = exact(w_win_);
+
+	mln_precondition(input.is_valid());
+	mln_precondition(nbh.is_valid());
+
+	(void) input;
+	(void) nbh;
+	(void) max;
+	(void) functor;
+      }
+
+
+    } // of namespace mln::canvas::internal
+
+
+
+    // Implementations.
+
+    namespace impl
+    {
+
+      namespace generic
+      {
+
+	template <typename I,
+		  typename N, typename W, typename D,
+		  typename F>
+	mln_ch_value(I, D)
+	  distance_front(const Image<I>& input_,
+			 const Neighborhood<N>& nbh_,
+			 const Weighted_Window<W>& w_win_,
+			 D max,
+			 F& functor)
+	{
+	  trace::entering("canvas::impl::generic::distance_front");
+
+	  const I& input = exact(input_);
+	  const N& nbh   = exact(nbh_);
+	  const W& w_win = exact(w_win_);
+
+	  mln_precondition(input.is_valid());
+	  mln_precondition(w_win.is_valid());
+
+	  typedef mln_site(I) P;
+	  typedef std::vector<P> bucket_t;
+
+	  // Distance map.
+	  mln_ch_value(I, D) dmap;
+	  initialize(dmap, input);
+	  data::fill(dmap, max);
+
+	  // Mod determination.
+	  unsigned mod;
+	  {
+	    accu::max<unsigned> m;
+	    for (unsigned i = 0; i < w_win.size(); ++i)
+	      m.take(w_win.w(i));
+	    mod = unsigned(m) + 1;
+	  }
+
+	  // Aux data.
+	  std::vector<bucket_t> bucket(mod);
+	  unsigned bucket_size = 0;
+
+	  // Initialization.
+	  {
+	    functor.init(input); // <-- init
+	    mln_piter(I) p(input.domain());
+	    mln_niter(N) n(nbh, p);
+	    for_all(p)
+	      if (functor.inqueue_p_wrt_input_p(input(p))) // <-- inqueue_p_wrt_input_p
+		{
+		  dmap(p) = 0;
+		  for_all(n)
+		    if (input.domain().has(n) &&
+			functor.inqueue_p_wrt_input_n(input(n))) // <-- inqueue_p_wrt_input_n
+		      {
+			bucket[0].push_back(p);
+			++bucket_size;
+			break;
+		      }
+		}
+	  } // end of Initialization.
+
+	  // Propagation.
+	  {
+	    P p;
+	    mln_qiter(W) q(w_win, p);
+	    for (unsigned d = 0; bucket_size != 0; ++d)
+	      {
+		bucket_t& bucket_d = bucket[d % mod];
+		for (unsigned i = 0; i < bucket_d.size(); ++i)
+		  {
+		    p = bucket_d[i];
+
+		    if (dmap(p) == max)
+		      {
+			// Saturation so stop.
+			bucket_size = bucket_d.size(); // So at end bucket_size == 0.
+			break;
+		      }
+
+		    if (dmap(p) < d)
+		      // p has already been processed, having a distance less than d.
+		      continue;
+
+		    for_all(q)
+		      if (dmap.domain().has(q) && dmap(q) > d)
+			{
+			  unsigned d_ = d + q.w();
+			  if (d_ < dmap(q))
+			    {
+			      dmap(q) = d_;
+			      functor.process(p, q); // <- process
+			      bucket[d_ % mod].push_back(q);
+			      ++bucket_size;
+			    }
+			}
+		  }
+		bucket_size -= bucket_d.size();
+		bucket_d.clear();
+	      }
+	  } // end of Propagation.
+	  
+	  trace::exiting("canvas::impl::generic::distance_front");
+	  return dmap;
+	}
+
+      } // of namespace mln::canvas::impl::generic
+
+
+
+      // Fastest version.
+
+      template <typename I,
+		typename N, typename W, typename D,
+		typename F>
+      mln_ch_value(I, D)
+	distance_front_fastest(const Image<I>& input_,
+			       const Neighborhood<N>& nbh_,
+			       const Weighted_Window<W>& w_win_,
+			       D max, F& functor)
+      {
+	trace::entering("canvas::impl::distance_front_fastest");
+
+	const I& input = exact(input_);
+	const N& nbh   = exact(nbh_);
+	const W& w_win = exact(w_win_);
+
+	mln_precondition(input.is_valid());
+	mln_precondition(w_win.is_valid());
+
+	// Handling w_win.
+	extension::adjust(input, w_win);
+	const unsigned n_ws = w_win.size();
+	util::array<int> dp = offsets_wrt(input, w_win.win());
+	mln_invariant(dp.nelements() == n_ws);
+
+	// Distance map.
+	mln_ch_value(I, D) dmap;
+	initialize(dmap, input);
+	data::fill(dmap, max);
+
+	// Mod determination.
+	unsigned mod;
+	{
+	  accu::max<unsigned> m;
+	  for (unsigned i = 0; i < w_win.size(); ++i)
+	    m.take(w_win.w(i));
+	  mod = unsigned(m) + 1;
+	}
+
+	// Aux data.
+	typedef std::vector<unsigned> bucket_t;
+	std::vector<bucket_t> bucket(mod);
+	unsigned bucket_size = 0;
+
+	// Initialization.
+	{
+	  functor.init_(input); // <-- init
+
+	  // For the extension to be ignored:
+	  extension::fill(input, true);
+	  extension::fill(dmap, D(0));
+
+	  mln_pixter(const I)    p(input);
+	  mln_nixter(const I, N) n(p, nbh);
+	  for_all(p)
+	    if (functor.inqueue_p_wrt_input_p_(p.val())) // <-- inqueue_p_wrt_input_p
+	      {
+		dmap.element(p.offset()) = 0;
+		for_all(n)
+		  if (functor.inqueue_p_wrt_input_n_(n.val())) // <-- inqueue_p_wrt_input_n
+		    {
+		      bucket[0].push_back(p.offset());
+		      ++bucket_size;
+		      break;
+		    }
+	      }
+	} // end of Initialization.
+
+	// Propagation.
+	{
+	  unsigned p;
+
+	  for (unsigned d = 0; bucket_size != 0; ++d)
+	    {
+	      bucket_t& bucket_d = bucket[d % mod];
+	      for (unsigned i = 0; i < bucket_d.size(); ++i)
+		{
+		  p = bucket_d[i];
+
+		  if (dmap.element(p) == max)
+		    {
+		      // Saturation so stop.
+		      bucket_size = bucket_d.size(); // So at end bucket_size == 0.
+		      break;
+		    }
+
+		  if (dmap.element(p) < d)
+		    // p has already been processed, having a distance less than d.
+		    continue;
+
+		  for (unsigned i = 0; i < n_ws; ++i)
+		  {
+		    unsigned q = p + dp[i];
+		    if (dmap.element(q) > d)
+		      {
+			unsigned d_ = d + w_win.w(i);
+			if (d_ < dmap.element(q))
+			  {
+			    dmap.element(q) = d_;
+			    functor.process_(p, q); // <- process
+			    bucket[d_ % mod].push_back(q);
+			    ++bucket_size;
+			  }
+		      }
+		  }
+		}
+	      bucket_size -= bucket_d.size();
+	      bucket_d.clear();
+	    }
+	} // end of Propagation.
+
+	trace::exiting("canvas::impl::distance_front_fastest");
+	return dmap;
+      }
+
+
+    } // of namespace mln::canvas::impl
+
+
+
+    // Dispatch.
+
+    namespace internal
+    {
+
+      template <typename I,
+		typename N, typename W, typename D,
+		typename F>
+      inline
+      mln_ch_value(I, D)
+	distance_front_dispatch(metal::false_,
+				const Image<I>& input,
+				const Neighborhood<N>& nbh, const Weighted_Window<W>& w_win,
+				D max, F& functor)
+      {
+	return impl::generic::distance_front(input, nbh, max, w_win, functor);
+      }
+
+      template <typename I,
+		typename N, typename W, typename D,
+		typename F>
+      inline
+      mln_ch_value(I, D)
+	distance_front_dispatch(metal::true_,
+				const Image<I>& input,
+				const Neighborhood<N>& nbh, const Weighted_Window<W>& w_win,
+				D max, F& functor)
+      {
+  	return impl::distance_front_fastest(input, nbh, w_win, max, functor);
+	// 	return impl::generic::distance_front(input, nbh, w_win, max, functor);
+      }
+
+      template <typename I,
+		typename N, typename W, typename D,
+		typename F>
+      inline
+      mln_ch_value(I, D)
+	distance_front_dispatch(const Image<I>& input,
+				const Neighborhood<N>& nbh, const Weighted_Window<W>& w_win,
+				D max, F& functor)
+      {
+	enum {
+	  test = mlc_equal(mln_trait_image_speed(I),
+			   trait::image::speed::fastest)::value
+	  &&
+	  mln_is_simple_neighborhood(N)::value
+	};
+	return distance_front_dispatch(metal::bool_<test>(),
+				       input, nbh, w_win, max, functor);
+      }
+
+
+    } // of namespace mln::canvas::internal
+
+
+
+    // Facade.
+
+    template <typename I,
+	      typename N, typename W, typename D,
+	      typename F>
+    inline
+    mln_ch_value(I, D)
+      distance_front(const Image<I>& input,
+		     const Neighborhood<N>& nbh, const Weighted_Window<W>& w_win,
+		     D max, F& functor)
+    {
+      trace::entering("canvas::distance_front");
+
+      internal::distance_front_tests(input, nbh, w_win, max, functor);
+
+      mln_ch_value(I,D) output;
+      output = internal::distance_front_dispatch(input, nbh, w_win, max, functor);
+
+      trace::exiting("canvas::distance_front");
+      return output;
+    }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace mln::canvas
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CANVAS_DISTANCE_FRONT_HH
Index: trunk/milena/sandbox/folio/dt_old/dt.cc
===================================================================
--- trunk/milena/sandbox/folio/dt_old/dt.cc	(revision 0)
+++ trunk/milena/sandbox/folio/dt_old/dt.cc	(revision 3522)
@@ -0,0 +1,59 @@
+/*!
+ * \file   dt.cc
+ * \author ornthalas <ornthalas(a)gmail.com>
+ */
+
+#include <iostream>
+#include <mln/core/image/image2d.hh>
+#include <mln/debug/println.hh>
+#include <mln/make/win_chamfer.hh>
+#include <mln/data/fill.hh>
+#include <mln/core/alias/neighb2d.hh>
+
+#include <mln/io/pbm/load.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/level/stretch.hh>
+#include <mln/value/int_u8.hh>
+
+#include <mln/core/image/sub_image.hh>
+#include <mln/core/image/image_if.hh>
+#include <mln/pw/value.hh>
+
+#include "dt.hh"
+
+int main()
+{
+  using namespace mln;
+
+  image2d<bool> ima(5,5);
+  bool vals[] = { 1, 0, 0, 1, 1,
+		  0, 0, 0, 0, 0,
+		  0, 0, 0, 0, 0,
+		  0, 0, 0, 1, 0,
+		  0, 0, 0, 0, 0};
+  data::fill(ima, vals);
+
+  image2d<bool> msk(5,5);
+  bool rest[] = { 1, 0, 1, 1, 1,
+		  1, 0, 1, 1, 1,
+		  1, 1, 0, 0, 0,
+		  1, 1, 0, 1, 1,
+		  1, 1, 1, 1, 1};
+  data::fill(msk, rest);
+
+  int ws[] = { 2, 1, 2,
+	       1, 0, 1,
+	       2, 1, 2 };
+  image2d<unsigned> out;
+  out = dt::dt(ima | pw::value(msk), make::w_window2d(ws), 50);
+
+  debug::println(ima | pw::value(msk));
+  debug::println(out);
+
+//  image2d<bool> ima = io::pbm::load("../../img/c01.pbm");
+
+//  image2d<value::int_u8> out2(out.domain());
+//  level::stretch(out, out2);
+
+//  io::pgm::save(out2, "out.pgm");
+}
Index: trunk/milena/sandbox/folio/dt_old/dt.spe.hh
===================================================================
--- trunk/milena/sandbox/folio/dt_old/dt.spe.hh	(revision 0)
+++ trunk/milena/sandbox/folio/dt_old/dt.spe.hh	(revision 3522)
@@ -0,0 +1,123 @@
+/*!
+ * \file   test_psn.spe.hh
+ * \author ornthalas <ornthalas(a)gmail.com>
+ */
+
+#ifndef DT_SPE_HH
+# define DT_SPE_HH
+
+# ifndef DT_HH
+#  error "Forbidden inclusion of *.spe.hh"
+# endif // ! DT_HH
+
+# include "canevas_dt.hh"
+
+namespace mln
+{
+
+  namespace dt
+  {
+
+    template<typename I, typename N, typename L>
+    inline
+    mln_ch_value(I, L)
+    dt(const Image<I>& input_, const N& nbh, unsigned max);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+    namespace impl
+    {
+
+
+      // Fwd decl of the Generic version.
+
+      namespace generic
+      {
+
+	template<typename I, typename N, typename L>
+	inline
+	mln_ch_value(I, L)
+	dt_(const Image<I>& input_, const N& nbh, unsigned max);
+
+      } // end of namespace mln::dt::impl::generic
+
+
+      // Fastest functor.
+
+      template <typename I_, typename N_, typename L_>
+      struct dt_fasfunctor
+      {
+	typedef I_ I;
+	typedef N_ N;
+	typedef L_ L;
+
+	const I& input;
+	const N& nbh;
+	unsigned max;
+
+	dt_fasfunctor(const I_& input, const N_& nbh, const unsigned max)
+	  : input(input),
+	    nbh(nbh),
+	    max(max)
+	{}
+
+	void init() {}
+      };
+
+
+      // Fastest implementation.
+
+      namespace fastest
+      {
+
+	template<typename I, typename N, typename L>
+	inline
+	mln_ch_value(I, L)
+        dt_(const I& input, const N& nbh, unsigned max)
+	{
+	  trace::entering("dt::impl::dt_fas");
+
+	  typedef dt_fasfunctor<I,N,L> F;
+	  F f(input, nbh, max);
+	  canvas::dt_fastest<F> run(f);
+
+	  trace::exiting("dt::impl::dt_fas");
+	  return run.output;
+	}
+
+      } // end of namespace mln::dt::impl::fastest
+
+
+      // Disjunction between "fastest" and "not fastest".
+
+      template<typename I, typename N, typename L>
+      inline
+      mln_ch_value(I, L)
+      dt_(trait::image::speed::any,
+	  const I& input, const N& nbh, unsigned max)
+      {
+	return generic::dt_(input, nbh, max);
+      }
+
+      template<typename I, typename N, typename L>
+      inline
+      mln_ch_value(I, L)
+      dt_(trait::image::speed::fastest,
+	  const I& input, const N& nbh, unsigned max)
+      {
+	return fastest::dt_(input, nbh, max);
+      }
+
+
+    } // end of namespace mln::dt::impl
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace mln::dt
+
+} // end of namespace mln
+
+
+#endif // !DT_SPE_HH
Index: trunk/milena/sandbox/folio/mln/histo/compute_histo_rgb.hh
===================================================================
--- trunk/milena/sandbox/folio/mln/histo/compute_histo_rgb.hh	(revision 0)
+++ trunk/milena/sandbox/folio/mln/histo/compute_histo_rgb.hh	(revision 3522)
@@ -0,0 +1,36 @@
+/*!
+ * \file   compute_histo_rgb.cc
+ * \author etiennefolio <ornthalas(a)gmail.com>
+ */
+
+#include <mln/core/image/image2d.hh>
+#include <mln/core/image/image3d.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/value/rgb8.hh>
+#include <iostream>
+namespace mln
+{
+  namespace histo
+  {
+
+    template <typename C, typename T>
+    image3d<C> compute_histo_rgb(image2d<T> ima)
+    {
+      // out
+      typedef value::int_u8::enc enc;
+      image3d<C> out(mln_max(enc) + abs(mln_min(enc)) + 1,
+		     mln_max(enc) + abs(mln_min(enc)) + 1,
+		     mln_max(enc) + abs(mln_min(enc)) + 1);
+      data::fill(out, mln_min(C));
+
+      // count
+      mln_fwd_piter(image2d<T>) p(ima.domain());
+      for_all(p)
+	++out(point3d(ima(p).red(), ima(p).green(), ima(p).blue()));
+
+      // return
+      return out;
+    }
+
+  }
+}
Index: trunk/milena/sandbox/folio/mln/value/pipo.hh
===================================================================
--- trunk/milena/sandbox/folio/mln/value/pipo.hh	(revision 0)
+++ trunk/milena/sandbox/folio/mln/value/pipo.hh	(revision 3522)
@@ -0,0 +1,107 @@
+/*!
+ * \file   pipo.hh
+ * \author etiennefolio <ornthalas(a)gmail.com>
+ */
+
+#ifndef PIPO_HH_
+# define PIPO_HH_
+
+# include <mln/value/int_s.hh>
+# include <mln/value/int_u.hh>
+# include <mln/value/float01.hh>
+
+namespace mln
+{
+
+  namespace value { class pipo; }
+
+  namespace trait
+  {
+
+    template <>
+    struct value_< mln::value::pipo >
+    {
+      enum {
+	dim = 3
+      };
+
+      typedef mln::value::int_s<3>	comp_0;
+      typedef mln::value::float01_<8>	comp_1;
+      typedef mln::value::int_u<7>	comp_2;
+    };
+
+  } // end of namespace trait
+
+  namespace value
+  {
+    class pipo
+    {
+    public:
+
+      int_s<3>   c0;
+      float01_<8> c1;
+      int_u<7>   c2;
+
+      pipo();
+      pipo(int_s<3> _c0,
+	   float01_<8> _c1,
+	   int_u<7> _c2);
+
+      pipo& operator=(const pipo& rhs);
+    };
+
+# ifndef MLN_INCLUDE_ONLY
+
+    inline
+    pipo::pipo()
+      : c0(mln_min(int_s<3>)),
+	c1(mln_min(float01_<8>)),
+	c2(mln_min(int_u<7>))
+    {
+    }
+
+    inline
+    pipo::pipo(int_s<3> _c0,
+	       float01_<8> _c1,
+	       int_u<7> _c2)
+      : c0(_c0),
+	c1(_c1),
+	c2(_c2)
+    {
+    }
+
+    inline
+    pipo&
+    pipo::operator=(const pipo& rhs)
+    {
+      if (& rhs == this)
+	return *this;
+      this->c0 = rhs.c0;
+      this->c1 = rhs.c1;
+      this->c2 = rhs.c2;
+      return *this;
+    }
+
+    inline
+    std::ostream& operator<<(std::ostream& ostr, const pipo& v)
+    {
+      return ostr << '(' << debug::format(v.c0)
+		  << ',' << debug::format(v.c1)
+		  << ',' << debug::format(v.c2)
+		  << ')';
+    }
+
+// dunno why this doesn't compile... *_*"
+
+//     inline
+//     std::istream& operator>>(std::istream& istr, pipo& c)
+//     {
+//       return istr >> c.c0 >> c.c1 >> c.c2;
+//     }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace value
+}
+
+#endif /* !PIPO_HH_ */
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                          URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
ChangeLog:
2009-03-13  Etienne FOLIO  <folio(a)lrde.epita.fr>
	Add traits in pipo value type.
	* folio/value/pipo.hh: Add dimension and components types in the
	pipo type's traits.
---
 pipo.hh |   23 +++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)
Index: trunk/milena/sandbox/folio/value/pipo.hh
===================================================================
--- trunk/milena/sandbox/folio/value/pipo.hh	(revision 3520)
+++ trunk/milena/sandbox/folio/value/pipo.hh	(revision 3521)
@@ -12,6 +12,26 @@
 
 namespace mln
 {
+
+  namespace value { class pipo; }
+
+  namespace trait
+  {
+
+    template <>
+    struct value_< mln::value::pipo >
+    {
+      enum {
+	dim = 3
+      };
+
+      typedef mln::value::int_s<3>	comp_0;
+      typedef mln::value::float01_<8>	comp_1;
+      typedef mln::value::int_u<7>	comp_2;
+    };
+
+  } // end of namespace trait
+
   namespace value
   {
     class pipo
@@ -28,7 +48,6 @@
 	   int_u<7> _c2);
 
       pipo& operator=(const pipo& rhs);
-
     };
 
 # ifndef MLN_INCLUDE_ONLY
@@ -82,7 +101,7 @@
 
 # endif // ! MLN_INCLUDE_ONLY
 
-  }
+  } // end of namespace value
 }
 
 #endif /* !PIPO_HH_ */
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                          URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
ChangeLog:
2009-03-13  Etienne FOLIO  <folio(a)lrde.epita.fr>
	HistoRGB out image size correction.
	* folio/histo/compute_histo_rgb.hh: Computes now the right
	dimensions of the histogram.
---
 compute_histo_rgb.hh |    9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)
Index: trunk/milena/sandbox/folio/histo/compute_histo_rgb.hh
===================================================================
--- trunk/milena/sandbox/folio/histo/compute_histo_rgb.hh	(revision 3519)
+++ trunk/milena/sandbox/folio/histo/compute_histo_rgb.hh	(revision 3520)
@@ -7,7 +7,7 @@
 #include <mln/core/image/image3d.hh>
 #include <mln/value/int_u8.hh>
 #include <mln/value/rgb8.hh>
-
+#include <iostream>
 namespace mln
 {
   namespace histo
@@ -17,9 +17,10 @@
     image3d<C> compute_histo_rgb(image2d<T> ima)
     {
       // out
-      image3d<C> out(mln_max(C),
-		     mln_max(C),
-		     mln_max(C));
+      typedef value::int_u8::enc enc;
+      image3d<C> out(mln_max(enc) + abs(mln_min(enc)) + 1,
+		     mln_max(enc) + abs(mln_min(enc)) + 1,
+		     mln_max(enc) + abs(mln_min(enc)) + 1);
       data::fill(out, mln_min(C));
 
       // count
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                          URL: https://svn.lrde.epita.fr/svn/oln/trunk
ChangeLog:
2009-03-13  Frederic Bour  <bour(a)lrde.epita.fr>
	fun update: add unary & binary composition.
	
	* milena/sandbox/fred/fun/cos.hh,
	* milena/sandbox/fred/fun/abs.hh:
	  WIP, switching from solve to nsolve.
	* milena/sandbox/fred/fun/assignability.hh: New.
	  Traits to check function properties using sfinae (should be renamed).
	* milena/sandbox/fred/fun/binary.hh: New. Binary function
	* milena/sandbox/fred/fun/compose.hh: New. Compose function.
	* milena/sandbox/fred/fun/composition.hh: New.
	  Composition result objects definition.
	* milena/sandbox/fred/fun/cos.cc: New. Test for composition.
	* milena/sandbox/fred/fun/fun.cc: WIP.
	* milena/sandbox/fred/fun/meta_function.hh:
          Added Meta_Function_v2v and Meta_Function_vv2v categories.
	* milena/sandbox/fred/fun/nsolve.hh,
	* milena/sandbox/fred/fun/nsolve_binary.hh,
	* milena/sandbox/fred/fun/nsolve_unary.hh: New.
	  Original trait solver modification now based
	  on typename flag instead of template <class> class
	* milena/sandbox/fred/fun/thru_morpher.hh: WIP.
	* milena/sandbox/fred/fun/unary.hh: Update & redesign,
	  especially for composition.
---
 abs.hh           |    1 
 assignability.hh |  103 ++++++++++++++++++
 binary.hh        |  137 ++++++++++++++++++++++++
 compose.hh       |   71 ++++++++++++
 composition.hh   |  210 ++++++++++++++++++++++++++++++++++++++
 cos.cc           |   34 ++++++
 cos.hh           |   12 +-
 fun.cc           |    5 
 meta_function.hh |   71 ++++++++++++
 nsolve.hh        |  152 +++++++++++++++++++++++++++
 nsolve_binary.hh |  302 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 nsolve_unary.hh  |  171 +++++++++++++++++++++++++++++++
 thru_morpher.hh  |    1 
 unary.hh         |  299 +++++++++++++++++++++++++++++++++++++++++++++++-------
 14 files changed, 1526 insertions(+), 43 deletions(-)
Index: trunk/milena/sandbox/fred/fun/binary.hh
===================================================================
--- trunk/milena/sandbox/fred/fun/binary.hh	(revision 0)
+++ trunk/milena/sandbox/fred/fun/binary.hh	(revision 3519)
@@ -0,0 +1,137 @@
+#ifndef BINARY_HH
+# define BINARY_HH
+
+# include <mln/fun/essential.hh>
+# include "meta_function.hh"
+# include "nsolve.hh"
+# include "assignability.hh"
+
+namespace mln
+{
+
+  namespace fun
+  {
+
+    namespace spe
+    {
+
+      // Forward declaration
+      template <typename Fun, typename T1, typename T2>
+      struct binary;
+
+      namespace impl
+      {
+
+	template <typename Fun, typename T1, typename T2>
+	struct binary_impl : mln::Function_v2v< binary<Fun, T1, T2> >
+	{
+	  typedef mln_trait_nbinary(Fun, T1, T2) impl;
+
+	  typedef typename impl::argument1 argument1;
+	  typedef typename impl::argument2 argument2;
+	  typedef typename impl::result    result;
+
+	  binary_impl()
+	  : impl_()
+	  {
+	  }
+
+	  binary_impl(const impl& f)
+	  : impl_(f)
+	  {
+	  }
+
+	  result operator () (const argument1& a, const argument2& b) const
+	  {
+	    return this->impl_.read(a, b);
+	  }
+
+	protected:
+	  impl impl_;
+	};
+
+      } // end of namespace mln::fun::spe::impl
+
+      template <typename Fun, typename T1, typename T2>
+      struct binary
+      : impl::binary_impl<Fun, T1, T2>
+      {
+	typedef impl::binary_impl<Fun, T1, T2> super;
+
+	binary()
+	: super()
+	{
+	}
+
+	binary(const typename super::impl& f)
+	: super(f)
+	{
+	}
+
+	using super::operator();
+      };
+
+    } // end of namespace mln::fun::spe
+
+    template <typename F>
+    struct binary : mln::Meta_Function_vv2v< binary<F> >
+    {
+
+      template <typename T1, typename T2>
+      struct with
+      {
+	typedef spe::binary<F, T1, T2> ret;
+      };
+
+      template <typename T1, typename T2>
+      typename with<T1, T2>::ret::result operator()(const T1& a, const T2& b) const
+      {
+	typename with<T1, T2>::ret tmp;
+	return tmp(a, b);
+      }
+
+    };
+
+    template <typename F, typename P>
+    struct binary_param: binary<F>
+    {
+      typedef P param;
+
+      binary_param() {};
+      binary_param(const param& p) : p_(p) {};
+
+      void init(const param& p)
+      {
+	p_ = p;
+      }
+
+      param& parameter()
+      {
+	return p_;
+      }
+
+      protected:
+	param p_;
+    };
+
+    template <typename F>
+    struct binary_param<F, F>: binary<F>
+    {
+      typedef F param;
+
+      void init(const param& p)
+      {
+	exact(*this) = p;
+      }
+
+      param& parameter()
+      {
+	return exact(*this);
+      }
+    };
+
+  } // end of namespace mln::fun
+
+} // end of namespace mln
+
+#endif /* ! BINARY_HH */
Index: trunk/milena/sandbox/fred/fun/cos.hh
===================================================================
--- trunk/milena/sandbox/fred/fun/cos.hh	(revision 3518)
+++ trunk/milena/sandbox/fred/fun/cos.hh	(revision 3519)
@@ -11,12 +11,15 @@
   // COS, bijective
   namespace fun
   {
-    template <typename T>
-    struct cos : unary<cos, T> {};
+    struct cos : unary<cos> {};
   }
 
   namespace trait
   {
+
+    namespace next
+    {
+
     template <typename T>
     struct set_unary_<mln::fun::cos, mln::value::Floating, T>
     {
@@ -35,12 +38,11 @@
 	l = math::acos(x);
       }
     };
+
   }
 
-  namespace meta
-  {
-    typedef unary<mln::fun::cos> cos;
   }
+
 }
 
 #endif /* ! COS_HH */
\ No newline at end of file
Index: trunk/milena/sandbox/fred/fun/nsolve_unary.hh
===================================================================
--- trunk/milena/sandbox/fred/fun/nsolve_unary.hh	(revision 0)
+++ trunk/milena/sandbox/fred/fun/nsolve_unary.hh	(revision 3519)
@@ -0,0 +1,171 @@
+// Copyright (C) 2006, 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_TRAIT_NSOLVE_UNARY_HH
+# define MLN_TRAIT_NSOLVE_UNARY_HH
+
+/*!
+ * \file   mln/trait/solve_unary.hh
+ *
+ * \brief  FIXME
+ *
+ *
+ */
+
+# include <mln/core/category.hh>
+# include <mln/core/routine/exact.hh>
+# include <mln/metal/equal.hh>
+# include <mln/metal/if.hh>
+# include <mln/metal/ret.hh>
+# include "nsolve.hh"
+
+
+// FIXME: Just for the record (use it...)
+
+#  ifndef MLN_DEBUG_TRAITS
+#  endif // ! MLN_DEBUG_TRAITS
+
+
+
+namespace mln
+{
+
+  namespace trait
+  {
+
+    namespace next
+    {
+
+      namespace internal
+      {
+
+
+	template < typename Name,
+		   typename Category,
+		   typename T >
+	struct trait_set_unary_;
+
+	template < typename Name,
+		   template <class> class Category, typename _,
+		   typename T >
+	struct trait_set_unary_< Name, Category<_>, T >
+	{
+	  typedef typename mln::trait::next::set_unary_<Name, Category, T>::ret ret;
+	};
+
+
+	// Fwd decls.
+	template < typename Name,
+		   typename Category, typename T >
+	struct get_unary_;
+
+
+	template < typename user_ret, /* != not_found and != undefined */
+		   typename Name,
+		   typename Category, typename T >
+	struct helper_get_unary_
+	{
+	  typedef user_ret ret;  // The user has defined 'ret' so we return it.
+	};
+
+
+	template < typename Name,
+		   typename Category, typename T >
+	struct helper_get_unary_< /* user_ret == */ not_found,
+				  Name, Category, T >
+	{
+	  typedef not_found ret;  // End of search due to a blocker; 'ret' is not found.
+	};
+
+
+	template < typename Name,
+		   typename Category, typename T >
+	struct helper_get_unary_< /* user_ret == */ undefined,
+				  Name, Category, T >
+	{
+	  typedef typename mln::internal::super_category_< Category, T >::ret Super_Category;
+	  typedef typename get_unary_<Name, Super_Category, T>::ret ret;   // No user ret definition => Recursion.
+	};
+
+
+	template < typename Name,
+		   typename Category, typename T >
+	struct get_unary_
+	{
+	  typedef typename trait_set_unary_<Name, Category, T>::ret user_ret;  // First get 'user_ret'
+	  typedef helper_get_unary_<user_ret, Name, Category, T> helper;       // Set the helper to make a decision.
+	  typedef mlc_ret(helper) ret;                                         // Return.
+	};
+
+
+	template < typename precise_ret,
+		   typename Name,
+		   typename Category, typename T >
+	struct helper_choose_unary_wrt_ /* precise_ret != undefined */
+	{
+	  typedef precise_ret ret;                                 // -> A precise ret has been defined so it is it.
+	};
+
+	template < typename Name,
+		   typename Category, typename T >
+	struct helper_choose_unary_wrt_< /* precise_ret == */ undefined,
+					Name, Category, T >
+	{
+	  typedef typename get_unary_<Name, Category, T>::ret ret; // -> Go up into the category inheritance
+								  //    to fetch a ret from 'set_unary_'s.
+	};
+
+	template < typename Name,
+		   typename Category, typename T >
+	struct helper_solve_unary_
+	{
+	  typedef typename set_precise_unary_<Name, T>::ret precise_ret;
+	  typedef helper_choose_unary_wrt_< precise_ret, /* undefined or not (?) */
+					    Name, Category, T> helper;
+	  typedef mlc_ret(helper) ret;
+	};
+
+      } // end of namespace mln::trait::next::internal
+
+
+      template < typename Name,
+		typename T_ >
+      struct solve_unary
+      {
+	typedef mln_exact(T_) T;
+	typedef typename mln::category<T>::ret Category;
+	typedef internal::helper_solve_unary_< Name, Category, T > meta_code;
+	typedef typename meta_code::ret ret;
+      };
+
+    } // end of namespace mln::trait::next
+
+  } // end of namespace mln::trait
+
+} // end of namespace mln
+
+
+#endif // ! MLN_TRAIT_NSOLVE_UNARY_HH
Index: trunk/milena/sandbox/fred/fun/meta_function.hh
===================================================================
--- trunk/milena/sandbox/fred/fun/meta_function.hh	(revision 3518)
+++ trunk/milena/sandbox/fred/fun/meta_function.hh	(revision 3519)
@@ -57,6 +57,8 @@
 
   // Fwd decl.
   template <typename E> struct Meta_Function;
+  template <typename E> struct Meta_Function_v2v;
+  template <typename E> struct Meta_Function_vv2v;
 
   // Meta_Function category flag type.
   template <>
@@ -81,6 +83,49 @@
     Meta_Function();
   };
 
+  /*----------------------.
+  | Unary meta function.  |
+  `----------------------*/
+
+  template <>
+  struct Meta_Function_v2v<void> { typedef Meta_Function<void> super; };
+
+  /// Base class for implementation of function-objects from
+  /// value to value.
+  ///
+  /// The parameter \a E is the exact type.
+  ///
+  template <typename E>
+  struct Meta_Function_v2v : public Meta_Function<E>
+  {
+    typedef Meta_Function_v2v<void> category;
+
+    protected:
+      Meta_Function_v2v();
+      Meta_Function_v2v(const Meta_Function_v2v&);
+  };
+
+  /*-----------------------.
+  | Binary meta function.  |
+  `-----------------------*/
+
+  template <>
+  struct Meta_Function_vv2v<void> { typedef Meta_Function<void> super; };
+
+  /// Base class for implementation of function-objects from
+  /// value to value.
+  ///
+  /// The parameter \a E is the exact type.
+  ///
+  template <typename E>
+  struct Meta_Function_vv2v : public Meta_Function<E>
+  {
+    typedef Meta_Function_vv2v<void> category;
+
+    protected:
+      Meta_Function_vv2v();
+      Meta_Function_vv2v(const Meta_Function_vv2v&);
+  };
 
   namespace fun
   {
@@ -109,6 +154,32 @@
     // FIXME: Check "with" on E.
   }
 
+  template <typename E>
+  inline
+  Meta_Function_v2v<E>::Meta_Function_v2v()
+  {
+  }
+
+  template <typename E>
+  inline
+  Meta_Function_v2v<E>::Meta_Function_v2v(const Meta_Function_v2v<E>& rhs)
+  : Meta_Function<E>(rhs)
+  {
+  }
+
+  template <typename E>
+  inline
+  Meta_Function_vv2v<E>::Meta_Function_vv2v()
+  {
+  }
+
+  template <typename E>
+  inline
+  Meta_Function_vv2v<E>::Meta_Function_vv2v(const Meta_Function_vv2v<E>& rhs)
+  : Meta_Function<E>(rhs)
+  {
+  }
+
   namespace fun
   {
 
Index: trunk/milena/sandbox/fred/fun/unary.hh
===================================================================
--- trunk/milena/sandbox/fred/fun/unary.hh	(revision 3518)
+++ trunk/milena/sandbox/fred/fun/unary.hh	(revision 3519)
@@ -1,18 +1,23 @@
 #ifndef UNARY_HH
 # define UNARY_HH
 
-# include <mln/trait/solve.hh>
 # include <mln/fun/essential.hh>
-# include <mln/fun/internal/resolve.hh>
 # include "meta_function.hh"
+# include "nsolve.hh"
+# include "assignability.hh"
 
 namespace mln
 {
-  // UNARY
+
   namespace fun
   {
+
+    // Forward declaration, for composition with unary::operator()(Fun)
+    struct compose;
+
     namespace internal
     {
+
       template <typename Impl>
       struct unary_modifier
       {
@@ -22,14 +27,14 @@
 	typedef unary_modifier          lresult;
 	
 	// FIXME: argument or lvalue? ~~~
-	unary_modifier(argument& x)
-	: x_(&x)
+	unary_modifier(const Impl& impl, argument& x)
+	: x_(&x), impl_(&impl)
 	{
 	}
 	
 	result to_result() const
 	{
-	  return Impl::read(*x_);
+	  return impl_->read(*x_);
 	};
 	
 	operator result() const
@@ -39,89 +44,307 @@
 
 	const result& operator = (const result& r) const
 	{
-	  Impl::write(*x_, r);
+	  impl_->write(*x_, r);
 	  return r;
 	}
 	
       private:
 	argument *x_;
+	const Impl *impl_;
       };
-    }
 
-    template <template <class> class Fun, typename T>
-    struct unary : mln::Function_v2v< Fun<T> >
+    } // end of namespace mln::fun::internal
+
+    namespace spe
+    {
+
+      // Forward declaration
+      template <typename Fun, typename T>
+      struct unary;
+
+      namespace impl
     {
-      // FIXME: mln_fun_internal_resolve? Fun<T> is not defined at this point...
-      //	so mln_is_a(Fun<T>, Function) won't work.
-      typedef typename mln::trait::solve_unary< Fun, T >::ret impl;
       
+	template <bool set, typename Fun, typename T>
+	struct unary_impl_set;
+
+	template <typename Fun, typename T>
+	struct unary_impl_set<false, Fun, T> : mln::Function_v2v< unary<Fun, T> >
+	{
+	  typedef mln_trait_nunary(Fun, T) impl;
+
+	  typedef typename impl::argument argument;
       typedef typename impl::result          result;
+	  typedef mln_trait_fun_param(impl) param_;
+	  typedef mlc_if(mlc_equal(param_, void), impl, param_) init_param;
+
+	  unary_impl_set() {}
+
+	  unary_impl_set(const init_param& p) : impl_(p) {}
+
+	  result operator () (const argument& value) const
+	  {
+	    return this->impl_.read(value);
+	  }
+
+	protected:
+	  impl impl_;
+	};
+
+	template <typename Fun, typename T>
+	struct unary_impl_set<true, Fun, T> : unary_impl_set<false, Fun, T>
+	{
+	  typedef unary_impl_set<false, Fun, T> super;
+	  typedef typename super::impl      impl;
+
       typedef typename impl::argument        argument;
+	  typedef typename impl::result          result;
       typedef typename impl::lvalue          lvalue;
       typedef internal::unary_modifier<impl> lresult;
       
-      result operator () (const argument& value) const
+	  unary_impl_set() {}
+	  unary_impl_set(const typename super::init_param& p) : super(p) {}
+
+	  void set(lvalue l, const result& r) const
       {
-	return impl::read(value);
+	    this->impl_.write(l, r);
       }
       
       lresult operator () (argument& value) const
       {
-	return lresult(value);
+	    return lresult(this->impl_, value);
       }
       
-      void set(lvalue l, const result& r) const
+	  using super::operator();
+	};
+
+	template <bool set, typename Fun, typename T>
+	struct unary_impl_param;
+
+	template <typename Fun, typename T>
+	struct unary_impl_param<false, Fun, T>
+	: impl::unary_impl_set<mln_trait_fun_is_assignable_(mln_trait_nunary(Fun, T))::value, Fun, T>
       {
-	impl::write(l, r);
-      }
+	  typedef impl::unary_impl_set<mln_trait_fun_is_assignable_(mln_trait_nunary(Fun, T))::value, Fun, T> super;
+
+	  unary_impl_param() {}
+	  unary_impl_param(const typename super::init_param& p) : super(p) {}
     };
-  }
 
-  namespace trait
+	template <typename Fun, typename T>
+	struct unary_impl_param<true, Fun, T>
+	: unary_impl_param<false, Fun, T>
   {
+	  typedef unary_impl_param<false, Fun, T> super;
     
-    namespace fun
+	  unary_impl_param() {}
+	  unary_impl_param(const typename super::init_param& p) : super(p) {}
+
+	  typedef typename super::param_ param;
+
+	  void init(const param& p)
+	  {
+	    this->impl_.init(p);
+	  }
+	};
+
+      } // end of namespace mln::fun::spe::impl
+
+      template <typename Fun, typename T>
+      struct unary
+      : impl::unary_impl_param<mln_trait_fun_is_parametrable_(mln_trait_nunary(Fun, T))::value, Fun, T>
     {
+	typedef impl::unary_impl_param<mln_trait_fun_is_parametrable_(mln_trait_nunary(Fun, T))::value, Fun, T>
+		super;
+
+	unary() {}
+	unary(const typename super::init_param& p) : super(p) {}
+
+	using super::operator();
+      };
+
+    } // end of namespace mln::fun::spe
 
-      /// Find correct implementation
       template <typename F>
-      struct is_assignable
+    struct unary;
+
+    namespace internal
+    {
+      template <typename T>
+      struct unary_with {};
+
+      template <bool has_param, typename M, typename T>
+      struct unary_with_param_helper;
+
+      template <typename M, typename T>
+      struct unary_with_param_helper<false, M, T>
+      {
+	typedef mln::fun::spe::unary<M, T> function;
+
+	static function inst(const M&)
+	{
+	  return function();
+	};
+
+      };
+
+      template <typename M, typename T>
+      struct unary_with_param_helper<true, M, T>
       {
-	typedef metal::true_ ret;
+	typedef mln::fun::spe::unary<M, T> function;
+
+	static function inst(const M& m)
+	{
+	  return function(m.parameter());
+	};
+
       };
       
+      template <typename M, typename T>
+      struct unary_with_helper : unary_with_param_helper<mln_trait_fun_is_parametrable_(M)::value, M, T>
+      {
+	typedef unary_with_param_helper<mln_trait_fun_is_parametrable_(M)::value, M, T> super;
+	typedef typename super::function function;
+
+	static typename function::result call(const M& m, const T& x)
+	{
+	  function f(super::inst(m));
+	  return f(x);
     }
     
+	static typename function::lresult lcall(const M& m, T& x)
+	{
+	  function f(super::inst(m));
+	  return f(x);
   }
   
-  namespace meta
+	static void set(const M& m, typename function::lvalue v, const T& x)
   {
-    template <template <class> class F>
-    struct unary : mln::Meta_Function< unary<F> >
+	  function f(super::inst(m));
+	  f.set(v, x);
+	}
+
+      };
+
+    }
+
+    template <typename F>
+    struct unary: mln::Meta_Function_v2v< F >
     {
+
+      template <typename T>
+      struct with {
+	typedef mln_trait_nunary(internal::unary_with<F>, T) impl;
+	typedef typename impl::function ret;
+      };
+
       template <typename T>
-      typename F<T>::result operator()(const T& v) const
+      typename with<T>::ret::result operator()(const T& v) const
       {
-	F<T> tmp;
-	return tmp(v);
+	return with<T>::impl::call(exact(*this), v);
       }
       
       template <typename T>
-      typename F<T>::lresult operator()(T& v) const
+      typename with<T>::ret::lresult operator()(T& v) const
       {
-	F<T> tmp;
-	return tmp(v);
+	return with<T>::impl::lcall(exact(*this), v);
       }
       
-      template <typename T>
-      struct with
+      template <typename T, typename R>
+      void set(T& v, const R& r) const
       {
-	typedef F<T> ret;
+	with<T>::impl::set(exact(*this), v, r);
+      }
+
       };
+
+    template <typename F, typename P>
+    struct unary_param: unary<F>
+    {
+      typedef P param;
+
+      unary_param() {};
+      unary_param(const param& p) : p_(p) {};
+
+      void init(const param& p)
+      {
+	p_ = p;
+      }
+
+      param& parameter()
+      {
+	return p_;
+      }
+
+      const param& parameter() const
+      {
+	return p_;
+      }
+
+    protected:
+      param p_;
     };    
+
+    template <typename F>
+    struct unary_param<F, F>: unary<F>
+    {
+      typedef F param;
+
+      void init(const param& p)
+      {
+	exact(*this) = p;
+      }
+
+      param& parameter()
+      {
+	return exact(*this);
+      }
+
+      const param& parameter() const
+      {
+	return exact(*this);
+      }
+
+    };
+
+  } // end of namespace mln::fun
+
+  namespace trait
+  {
+
+    namespace next
+    {
+
+      // Any type
+      template <typename F, typename T>
+      struct set_unary_< mln::fun::internal::unary_with<F>, mln::Object, T>
+      {
+	typedef mln::fun::internal::unary_with_helper<F, T> ret;
+      };
+
+      // Meta Function
+      template <typename F, typename G>
+      struct set_unary_< mln::fun::internal::unary_with<F>, mln::Meta_Function, G>
+      {
+	// FIXME: Workaround for cyclic references (unary -> unary_with -> compose -> unary)
+	template <typename T>
+	struct identity
+	{
+	  typedef T ret;
+	};
+
+	typedef set_unary_ ret;
+	typedef typename identity<mln::fun::compose>::ret::template with<F, G>::ret function;
+
+	static typename function::result call(const F& f, const G& g)
+	{
+	  function tmp;
+	  return tmp(f, g);
   }
+      };
   
 }
+  }
 
 template <typename Impl>
 std::ostream& operator << (std::ostream& o, const mln::fun::internal::unary_modifier<Impl>& m)
@@ -129,4 +352,6 @@
   return o << m.to_result();
 }
 
+} // end of namespace mln
+
 #endif /* ! UNARY_HH */
Index: trunk/milena/sandbox/fred/fun/assignability.hh
===================================================================
--- trunk/milena/sandbox/fred/fun/assignability.hh	(revision 0)
+++ trunk/milena/sandbox/fred/fun/assignability.hh	(revision 3519)
@@ -0,0 +1,103 @@
+#ifndef ASSIGNABILITY_HH
+# define ASSIGNABILITY_HH
+
+# include <mln/metal/bexpr.hh>
+# include <mln/metal/if.hh>
+
+#define mln_trait_fun_is_assignable(Fun) typename mln::trait::fun::is_assignable< Fun >::ret
+#define mln_trait_fun_is_assignable_(Fun) mln::trait::fun::is_assignable< Fun >::ret
+#define mln_trait_fun_is_assignable__1comma(A, B) mln_trait_fun_is_assignable(A, B)
+#define mln_trait_fun_is_assignable__1comma_(A, B) mln_trait_fun_is_assignable_(A, B)
+
+#define mln_trait_fun_is_parametrable(Fun) typename mln::trait::fun::is_parametrable< Fun >::ret
+#define mln_trait_fun_is_parametrable_(Fun) mln::trait::fun::is_parametrable< Fun >::ret
+
+#define mln_trait_fun_lvalue(Fun) typename mln::trait::fun::get_lvalue< Fun >::ret
+#define mln_trait_fun_param(Fun) typename mln::trait::fun::get_param< Fun >::ret
+namespace mln
+{
+
+  namespace trait
+  {
+
+    namespace fun
+    {
+
+      namespace internal
+      {
+
+	namespace introspect
+	{
+
+	  template <typename T>
+	  struct except_void_t
+	  {
+	    typedef void ret;
+	  };
+
+	  template <>
+	  struct except_void_t<void>;
+
+	  template <typename T, typename V>
+	  struct has_lvalue_t
+	  {
+	    typedef metal::false_ ret;
+	    typedef void type;
+	  };
+
+	  template <typename T>
+	  struct has_lvalue_t<T, typename except_void_t<typename T::lvalue>::ret>
+	  {
+	    typedef metal::true_ ret;
+	    typedef typename T::lvalue type;
+	  };
+
+	  template <typename T, typename V>
+	  struct has_param_t
+	  {
+	    typedef metal::false_ ret;
+	    typedef void type;
+	  };
+
+	  template <typename T>
+	  struct has_param_t<T, typename except_void_t<typename T::param>::ret>
+	  {
+	    typedef metal::true_ ret;
+	    typedef typename T::param type;
+	  };
+
+	}
+
+      } // end of namespace mln::trait::fun::internal
+
+      template <typename F>
+      struct is_assignable
+      {
+	typedef typename internal::introspect::has_lvalue_t<F, void>::ret ret;
+      };
+
+      template <typename F>
+      struct is_parametrable
+      {
+	typedef typename internal::introspect::has_param_t<F, void>::ret ret;
+      };
+
+      template <typename F>
+      struct get_lvalue
+      {
+	typedef typename internal::introspect::has_lvalue_t<F, void>::type ret;
+      };
+
+      template <typename F>
+      struct get_param
+      {
+	typedef typename internal::introspect::has_param_t<F, void>::type ret;
+      };
+
+    } // end of namespace mln::trait::fun
+
+  } // end of namespace mln::trait
+
+} // end of namespace mln
+
+#endif // ! ASSIGNABILITY_HH
\ No newline at end of file
Index: trunk/milena/sandbox/fred/fun/composition.hh
===================================================================
--- trunk/milena/sandbox/fred/fun/composition.hh	(revision 0)
+++ trunk/milena/sandbox/fred/fun/composition.hh	(revision 3519)
@@ -0,0 +1,210 @@
+#ifndef COMPOSITION_HH
+# define COMPOSITION_HH
+
+# include "unary.hh"
+# include "binary.hh"
+
+namespace mln
+{
+  // Composition
+  namespace fun
+  {
+
+    namespace internal
+    {
+
+      // Compositions may take this has initialization parameter
+      template <typename F, typename G>
+      struct composition_param
+      {
+	composition_param(const F& f, const G& g) : f_(f), g_(g) {}
+	composition_param() {}
+
+	F f_;
+	G g_;
+      };
+
+      // Composition types...
+      template <template <class> class CatF,  typename F,
+		template <class> class CatG, typename G>
+      struct composition;
+
+      // Meta
+      template <typename F, typename G>
+      struct composition<mln::Meta_Function_v2v, F, mln::Meta_Function_v2v, G>
+      : mln::fun::unary_param< composition<mln::Meta_Function_v2v, F, mln::Meta_Function_v2v, G>, composition_param<F, G> >
+      {
+	typedef mln::fun::unary_param< composition<mln::Meta_Function_v2v, F, mln::Meta_Function_v2v, G>, composition_param<F, G> > super;
+
+	composition() {};
+	composition(const typename super::param& p) : super(p) {};
+
+	typedef composition exact_type;
+      };
+
+      template <typename F, typename G>
+      struct composition<mln::Meta_Function_v2v, F, mln::Meta_Function_vv2v, G>
+      : mln::fun::binary_param< composition<mln::Meta_Function_v2v, F, mln::Meta_Function_vv2v, G>, composition_param<F, G> >
+      {
+	typedef mln::fun::binary_param< composition<mln::Meta_Function_v2v, F, mln::Meta_Function_vv2v, G>, composition_param<F, G> > super;
+
+	composition() {};
+	composition(const typename super::param& p) : super(p) {};
+
+	typedef composition exact_type;
+      };
+
+      // Concrete
+      template <typename F, typename G>
+      struct composition<mln::Meta_Function_v2v, F, mln::Function_v2v, G>
+      {
+	typedef mln::fun::spe::unary< composition<mln::Meta_Function_v2v, F, mln::Function_vv2v, G>, typename G::argument> exact_type;
+      };
+
+      template <typename F, typename G>
+      struct composition<mln::Meta_Function_v2v, F, mln::Function_vv2v, G>
+      {
+	typedef mln::fun::spe::binary< composition<mln::Meta_Function_v2v, F, mln::Function_vv2v, G>,
+				       typename G::argument1, typename G::argument2> exact_type;
+      };
+
+      // Unary compositions implementation inherit from composition_unary_impl...
+      template <bool has_lvalue, typename F, typename F_spe, typename G, typename G_spe>
+      struct composition_unary_impl_helper;
+
+      template <typename F, typename F_spe, typename G, typename G_spe>
+      struct composition_unary_impl_helper<false, F, F_spe, G, G_spe>
+      {
+	typedef typename G_spe::argument argument;
+	typedef typename F_spe::result   result;
+	typedef composition_param<F, G> param;
+
+	composition_unary_impl_helper() {}
+	composition_unary_impl_helper(const param& p) : f_(p.f_), g_(p.g_) {}
+
+	void init(const param& p)
+	{
+	  f_ = p.f_;
+	  g_ = p.g_;
+	}
+
+	result read(const argument& x) const
+	{
+	  return this->f_(this->g_(x));
+	}
+
+      protected:
+	F f_;
+	G g_;
+      };
+
+      template <typename F, typename F_spe, typename G, typename G_spe>
+      struct composition_unary_impl_helper<true, F, F_spe, G, G_spe>
+      : composition_unary_impl_helper<false, F, F_spe, G, G_spe>
+      {
+	typedef composition_unary_impl_helper<false, F, F_spe, G, G_spe> super;
+	typedef typename G_spe::lvalue   lvalue;
+
+	composition_unary_impl_helper() {}
+	composition_unary_impl_helper(const typename super::param& p) : super(p) {}
+
+	void write(lvalue l, const typename super::result& x) const
+	{
+	  typename G_spe::result r(this->g_(l));
+
+	  this->f_.set(r, x);
+	  this->g_.set(l, r);
+	}
+      };
+
+      template <typename F, typename F_spe, typename G, typename G_spe>
+      struct composition_unary_impl
+      : composition_unary_impl_helper<mln_trait_fun_is_assignable_(G_spe)::value, F, F_spe, G, G_spe>
+      {
+	typedef composition_unary_impl_helper<mln_trait_fun_is_assignable_(G_spe)::value, F, F_spe, G, G_spe> super;
+
+	composition_unary_impl() {}
+	composition_unary_impl(const typename super::param& p) : super(p) {}
+      };
+
+      // Binary compositions implementation inherit from composition_binary_inherit...
+      template <typename F, typename F_spe, typename G, typename G_spe>
+      struct composition_binary_impl
+      {
+	typedef typename G_spe::argument1 argument1;
+	typedef typename G_spe::argument2 argument2;
+	typedef typename F_spe::result   result;
+	typedef composition_param<F, G> param;
+
+	composition_binary_impl() {}
+	composition_binary_impl(const param& p) : f_(p.f_), g_(p.g_) {}
+
+	void init(const param& p)
+	{
+	  f_ = p.f_;
+	  g_ = p.g_;
+	}
+
+	result read(const argument1& a, const argument2& b) const
+	{
+	  return this->f_(this->g_(a, b));
+	}
+
+      protected:
+	F f_;
+	G g_;
+      };
+
+    }
+
+  }
+
+  namespace trait
+  {
+
+    namespace next
+    {
+
+      template <typename F, typename G, typename T>
+      struct set_precise_unary_<mln::fun::internal::composition<mln::Meta_Function_v2v, F, mln::Meta_Function_v2v, G>, T>
+      {
+	typedef typename G::template with<T>::ret G_fun;
+	typedef typename F::template with<typename G_fun::result>::ret F_fun;
+
+	typedef mln::fun::internal::composition_unary_impl<F, F_fun, G, G_fun> ret;
+      };
+
+      template <typename F, typename G, typename T1, typename T2>
+      struct set_precise_binary_<mln::fun::internal::composition<mln::Meta_Function_v2v, F, mln::Meta_Function_vv2v, G>, T1, T2>
+      {
+	typedef typename G::template with<T1, T2>::ret G_fun;
+	typedef typename F::template with<typename G_fun::result>::ret F_fun;
+
+	typedef mln::fun::internal::composition_binary_impl<F, F_fun, G, G_fun> ret;
+      };
+
+      template <typename F, typename G>
+      struct set_precise_unary_<mln::fun::internal::composition<mln::Meta_Function_v2v, F, mln::Function_v2v, G>,
+				typename G::argument>
+      {
+	typedef typename F::template with<typename G::result>::ret F_fun;
+
+	typedef mln::fun::internal::composition_unary_impl<F, F_fun, G, G> ret;
+      };
+
+      template <typename F, typename G>
+      struct set_precise_binary_<mln::fun::internal::composition<mln::Meta_Function_v2v, F, mln::Meta_Function_vv2v, G>,
+				 typename G::argument1, typename G::argument2>
+      {
+	typedef typename F::template with<typename G::result>::ret F_fun;
+
+	typedef mln::fun::internal::composition_binary_impl<F, F_fun, G, G> ret;
+      };
+
+    }
+
+  }
+
+}
+
+#endif /* ! COMPOSITION_HH */
\ No newline at end of file
Index: trunk/milena/sandbox/fred/fun/abs.hh
===================================================================
--- trunk/milena/sandbox/fred/fun/abs.hh	(revision 3518)
+++ trunk/milena/sandbox/fred/fun/abs.hh	(revision 3519)
@@ -22,7 +22,6 @@
       typedef set_unary_ ret;
       typedef T result;
       typedef T argument;
-      typedef T& lvalue;
       
       static result read(const argument& x)
       {
Index: trunk/milena/sandbox/fred/fun/compose.hh
===================================================================
--- trunk/milena/sandbox/fred/fun/compose.hh	(revision 0)
+++ trunk/milena/sandbox/fred/fun/compose.hh	(revision 3519)
@@ -0,0 +1,71 @@
+#ifndef COMPOSE_HH
+# define COMPOSE_HH
+
+# include "composition.hh"
+
+namespace mln
+{
+  // Composition
+  namespace fun
+  {
+    struct compose : binary<compose> {};
+
+    namespace internal
+    {
+
+      template <template <class> class CatF, typename F, template <class> class CatG, typename G>
+      struct compose_helper
+      {
+	typedef F argument1;
+	typedef G argument2;
+
+	typedef typename composition<CatF, F, CatG, G>::exact_type result;
+	typedef typename result::param param;
+
+	static result read(const F& f, const G& g)
+	{
+	  return result(param(f, g));
+	}
+      };
+
+    }
+  }
+
+  namespace trait
+  {
+
+    namespace next
+    {
+
+      // All kinds of supported compositions (meta : unary) with (meta or not : unary or binary)
+      template <typename F, typename G>
+      struct set_binary_< mln::fun::compose, mln::Meta_Function_v2v, F, mln::Meta_Function_v2v, G>
+      {
+	typedef mln::fun::internal::compose_helper<mln::Meta_Function_v2v, F, mln::Meta_Function_v2v, G> ret;
+      };
+
+      template <typename F, typename G>
+      struct set_binary_< mln::fun::compose, mln::Meta_Function_v2v, F, mln::Meta_Function_vv2v, G>
+      {
+	typedef mln::fun::internal::compose_helper<mln::Meta_Function_v2v, F, mln::Meta_Function_vv2v, G> ret;
+      };
+
+      template <typename F, typename G>
+      struct set_binary_< mln::fun::compose, mln::Meta_Function_v2v, F, mln::Function_v2v, G>
+      {
+	typedef mln::fun::internal::compose_helper<mln::Meta_Function_v2v, F, mln::Function_v2v, G> ret;
+      };
+
+      template <typename F, typename G>
+      struct set_binary_< mln::fun::compose, mln::Meta_Function_v2v, F, mln::Function_vv2v, G>
+      {
+	typedef mln::fun::internal::compose_helper<mln::Meta_Function_v2v, F, mln::Function_vv2v, G> ret;
+      };
+
+    }
+
+  }
+
+}
+
+#endif /* ! COMPOSE_HH */
\ No newline at end of file
Index: trunk/milena/sandbox/fred/fun/nsolve.hh
===================================================================
--- trunk/milena/sandbox/fred/fun/nsolve.hh	(revision 0)
+++ trunk/milena/sandbox/fred/fun/nsolve.hh	(revision 3519)
@@ -0,0 +1,152 @@
+// Copyright (C) 2006, 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_TRAIT_NSOLVE_HH
+# define MLN_TRAIT_NSOLVE_HH
+
+/*!
+ * \file   mln/trait/nsolve.hh
+ *
+ * \brief  FIXME
+ *
+ *
+ */
+
+# include <mln/core/category.hh>
+# include <mln/metal/equal.hh>
+# include <mln/metal/if.hh>
+# include <mln/metal/ret.hh>
+# include <mln/trait/solve.hh>
+
+
+// FIXME: Just for the record (use it...)
+
+#  ifndef MLN_DEBUG_TRAITS
+#  endif // ! MLN_DEBUG_TRAITS
+
+
+# define mln_trait_nunary(Name, T)  typename mln::trait::next::solve_unary< Name, T >::ret
+# define mln_trait_nunary_(Name, T)          mln::trait::next::solve_unary< Name, T >::ret
+
+# define mln_trait_nbinary(Name, T1, T2)  typename mln::trait::next::solve_binary< Name, T1, T2 >::ret
+# define mln_trait_nbinary_(Name, T1, T2)          mln::trait::next::solve_binary< Name, T1, T2 >::ret
+
+
+
+namespace mln
+{
+
+  namespace trait
+  {
+
+    namespace next
+    {
+
+      // Unary case.
+
+
+      template < typename Name,
+		 typename T >
+      struct set_precise_unary_
+      {
+	typedef undefined ret;
+      };
+
+
+      template < typename Name,
+		 template <class> class Category_T, typename T >
+      struct set_unary_
+      {
+	typedef undefined ret;
+      };
+
+      template < typename Name,
+		 typename T >
+      struct set_unary_< Name, Unknown, T > // Blocker; top of inheritance.
+      {
+	typedef not_found ret;
+      };
+
+
+
+
+      // Binary case.
+
+
+      template < typename Name,
+		 typename L,
+		 typename R >
+      struct set_precise_binary_
+      {
+	typedef undefined ret;
+      };
+
+
+      template < typename Name,
+		 template <class> class Category_L, typename L,
+		 template <class> class Category_R, typename R >
+      struct set_binary_
+      {
+	typedef undefined ret;
+      };
+
+      template < typename Name,
+		 typename L,
+		 template <class> class Category_R, typename R >
+      struct set_binary_< Name, Unknown, L, Category_R, R > // Left blocker.
+      {
+	typedef not_found ret;
+      };
+
+      template < typename Name,
+		 template <class> class Category_L, typename L,
+		 typename R >
+      struct set_binary_< Name, Category_L, L, Unknown, R > // Right blocker.
+      {
+	typedef not_found ret;
+      };
+
+      template < typename Name,
+		 typename L,
+		 typename R >
+      struct set_binary_< Name, Unknown, L, Unknown, R > // Blocker.
+      {
+	typedef not_found ret;
+      };
+
+    } // end of namespace mln::trait::next
+
+  } // end of namespace mln::trait
+
+} // end of namespace mln
+
+
+# include "nsolve_unary.hh"
+# include "nsolve_binary.hh"
+
+
+#endif // ! MLN_TRAIT_NSOLVE_HH
Index: trunk/milena/sandbox/fred/fun/cos.cc
===================================================================
--- trunk/milena/sandbox/fred/fun/cos.cc	(revision 0)
+++ trunk/milena/sandbox/fred/fun/cos.cc	(revision 3519)
@@ -0,0 +1,34 @@
+// Meta functions test
+#include "cos.hh"
+#include "compose.hh"
+
+#include <iostream>
+
+#define dbg_print(val) std::cout << #val << "\n\t -> \t" << (val) << std::endl
+int main()
+{
+  mln::fun::cos cos;
+  mln::fun::compose compose;
+
+  double x;
+  dbg_print(cos(compose)(cos,cos)(x) = 0.857553);
+  dbg_print(x);
+  dbg_print(cos(compose)(cos,cos)(0.));
+
+  // COS
+  {
+    mln_invariant(cos(0.) == 1.);
+    dbg_print(cos(0.));
+    dbg_print(cos(mln::math::acos(0.5)));
+  }
+
+  // COS
+  {
+    double x;
+    dbg_print(cos(x) = 1.);
+    mln_invariant(cos(x) == 1.);
+    dbg_print(x);
+  }
+
+  std::cout << "Ok." << std::endl;
+}
\ No newline at end of file
Index: trunk/milena/sandbox/fred/fun/nsolve_binary.hh
===================================================================
--- trunk/milena/sandbox/fred/fun/nsolve_binary.hh	(revision 0)
+++ trunk/milena/sandbox/fred/fun/nsolve_binary.hh	(revision 3519)
@@ -0,0 +1,302 @@
+// Copyright (C) 2006, 2008, 2009 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_TRAIT_NSOLVE_BINARY_HH
+# define MLN_TRAIT_NSOLVE_BINARY_HH
+
+/// \file   mln/trait/solve_binary.hh
+///
+///  FIXME
+
+# include <mln/core/category.hh>
+# include <mln/core/routine/exact.hh>
+# include <mln/metal/equal.hh>
+# include <mln/metal/if.hh>
+# include <mln/metal/ret.hh>
+# include "nsolve.hh"
+
+
+// FIXME: Just for the record (use it...)
+
+#  ifndef MLN_DEBUG_TRAITS
+#  endif // ! MLN_DEBUG_TRAITS
+
+
+
+namespace mln
+{
+
+  namespace trait
+  {
+
+    namespace next
+    {
+
+      namespace internal
+      {
+
+
+	template < typename Name,
+		  typename Category_L, typename L,
+		  typename Category_R, typename R >
+	struct trait_set_binary_;
+
+	template < typename Name,
+		  template <class> class Category_L, typename _l, typename L,
+		  template <class> class Category_R, typename _r, typename R >
+	struct trait_set_binary_< Name,
+				Category_L<_l>, L,
+				Category_R<_r>, R >
+	{
+	  typedef typename mln::trait::next::set_binary_<Name,
+							 Category_L, L,
+							 Category_R, R>::ret ret;
+	};
+
+
+	// triplet_ret_
+
+	template < unsigned i_L_, unsigned i_R_, typename ret_ >
+	struct triplet_
+	{
+	  typedef ret_ ret;
+	};
+
+
+	// merge_triplets_
+
+	template < typename L_trp, typename R_trp >
+	struct merge_triplets_;
+
+	template < unsigned L_i_L, unsigned L_i_R, typename L_ret,
+		  unsigned R_i_L, unsigned R_i_R, typename R_ret >
+	struct merge_triplets_< triplet_<L_i_L, L_i_R, L_ret>,
+				triplet_<R_i_L, R_i_R, R_ret> >
+	{
+	  typedef metal::bool_<(L_i_L <= R_i_L && L_i_R <= R_i_R)> take_L;
+	  typedef metal::bool_<(R_i_L <= L_i_L && R_i_R <= L_i_R)> take_R;
+	  typedef metal::or_<take_L, take_R> ok;
+	  typedef typename metal::if_< metal::and_<ok, take_L>,
+				      triplet_<L_i_L, L_i_R, L_ret>,
+				      typename metal::if_< metal::and_<ok, take_R>,
+							    triplet_<R_i_L, R_i_R, R_ret>,
+							    triplet_<0,0, not_found> >::ret >::ret ret;
+	};
+
+	template < unsigned i_L, unsigned i_R, typename LR_ret >
+	struct merge_triplets_< triplet_<i_L, i_R, LR_ret>,
+				triplet_<i_L, i_R, LR_ret> >
+	{
+	  typedef triplet_<i_L, i_R, LR_ret> ret;
+	};
+
+
+	template < unsigned L_i_L, unsigned L_i_R, unsigned L_i_max,
+		  unsigned R_i_L, unsigned R_i_R, unsigned R_i_max >
+	// L_i_max and R_i_max differ
+	struct helper_merge_triplets_same_ret_
+	{
+	  // The winning couple between L_* and R_* is the one which
+	  // maximum index is the smallest; for instance, with:
+	  //   left  branch giving L_i_L = 5 and L_i_R = 1 so L_i_max = 5
+	  //   right branch giving L_i_L = 3 and L_i_R = 4 so R_i_max = 4
+	  // the right branch wins.
+	  enum { i_L = (L_i_max < R_i_max ? L_i_L : R_i_L),
+		i_R = (L_i_max < R_i_max ? L_i_R : R_i_R) };
+	};
+
+	template < unsigned L_i_L, unsigned L_i_R, unsigned i_max,
+		  unsigned R_i_L, unsigned R_i_R >
+	// L_i_max is equal to R_i_max
+	struct helper_merge_triplets_same_ret_< L_i_L, L_i_R, i_max,
+						R_i_L, R_i_R, i_max >
+	{
+	  // The winning couple is the one with the minimum index.
+	  enum { L_i_min = (L_i_L < L_i_R ? L_i_L : L_i_R),
+		R_i_min = (R_i_L < R_i_R ? R_i_L : R_i_R),
+		i_L = (L_i_min < R_i_min ? L_i_L : R_i_L),
+		i_R = (L_i_min < R_i_min ? L_i_R : R_i_R) };
+	};
+
+
+	template < unsigned L_i_L, unsigned L_i_R, typename LR_ret,
+		  unsigned R_i_L, unsigned R_i_R >
+	struct merge_triplets_< triplet_<L_i_L, L_i_R, LR_ret>,
+				triplet_<R_i_L, R_i_R, LR_ret> >
+	{
+	  typedef helper_merge_triplets_same_ret_< L_i_L, L_i_R, (L_i_L > L_i_R ? L_i_L : L_i_R),
+						  R_i_L, R_i_R, (R_i_L > R_i_R ? R_i_L : R_i_R) > helper;
+	  typedef triplet_<helper::i_L, helper::i_R, LR_ret> ret;
+	};
+
+	template < unsigned L_i_L, unsigned L_i_R, typename L_ret >
+	struct merge_triplets_< triplet_<L_i_L, L_i_R, L_ret>,
+				triplet_<  0,     0,   not_found> >
+	{
+	  typedef triplet_<L_i_L, L_i_R, L_ret> ret;
+	};
+
+	template < unsigned R_i_L, unsigned R_i_R, typename R_ret >
+	struct merge_triplets_< triplet_<  0,     0,   not_found>,
+				triplet_<R_i_L, R_i_R, R_ret> >
+	{
+	  typedef triplet_<R_i_L, R_i_R, R_ret> ret;
+	};
+
+	template <> // To disambiguate.
+	struct merge_triplets_< triplet_<0, 0, not_found>,
+				triplet_<0, 0, not_found> >
+	{
+	  typedef triplet_<0u,0u, not_found> ret;
+	};
+
+
+
+	// Fwd decl.
+	template < typename Name,
+		  unsigned i_L, typename Category_L, typename L,
+		  unsigned i_R, typename Category_R, typename R >
+	struct get_binary_;
+
+
+	template < typename user_ret, /* != not_found and != undefined */
+		  typename Name,
+		  unsigned i_L, typename Category_L, typename L,
+		  unsigned i_R, typename Category_R, typename R >
+	struct helper_get_binary_
+	{
+	  typedef triplet_< i_L, i_R, user_ret > ret; // The user has defined 'ret' so we return it.
+	};
+
+	template < typename Name,
+		  unsigned i_L, typename Category_L, typename L,
+		  unsigned i_R, typename Category_R, typename R >
+	struct helper_get_binary_< /* user_ret == */ not_found,
+				  Name,  i_L, Category_L, L,  i_R, Category_R, R >
+	{
+	  typedef triplet_< 0, 0, not_found > ret; // End of search due to a blocker; 'ret' is not found.
+	};
+
+
+	template < typename Name,
+		  unsigned i_L, typename Category_L, typename L,
+		  unsigned i_R, typename Category_R, typename R >
+	struct helper_get_binary_< /* user_ret == */ undefined,
+				  Name, i_L,Category_L, L, i_R,Category_R, R >
+	{
+	  // No user definition for 'ret' so treillis construction in a static recursive way.
+
+	  // FIXME: We *do* need to handle this search with a priority!
+	  // FIXME: for a result can be found in both branches...
+
+	  typedef typename mln::internal::super_category_< Category_L, L >::ret Super_Category_L;
+	  typedef typename mln::internal::super_category_< Category_R, R >::ret Super_Category_R;
+
+	  typedef get_binary_< Name,
+			      i_L + 1, Super_Category_L, L,
+			      i_R,     Category_R,       R > L_branch;
+	  typedef mlc_ret(L_branch) L_trp;
+
+	  typedef get_binary_< Name,
+			      i_L,     Category_L,       L,
+			      i_R + 1, Super_Category_R, R > R_branch;
+	  typedef mlc_ret(R_branch) R_trp;
+
+	  typedef typename merge_triplets_< L_trp, R_trp >::ret ret;
+	};
+
+
+	template < typename Name,
+		  unsigned i_L, typename Category_L, typename L,
+		  unsigned i_R, typename Category_R, typename R >
+	struct get_binary_
+	{
+	  typedef typename trait_set_binary_<Name, Category_L,L,
+					    Category_R,R>::ret user_ret;  // First get 'user_ret'
+	  typedef helper_get_binary_<user_ret, Name, i_L,Category_L,L,
+						    i_R,Category_R,R> helper;        // Set the helper to make a decision.
+	  typedef mlc_ret(helper) ret;                                                // Return a triplet.
+	};
+
+
+	template < typename precise_ret,
+		  typename Name,
+		  typename Category_L, typename L,
+		  typename Category_R, typename R >
+	struct helper_choose_binary_wrt_ /* precise_ret != undefined */
+	{
+	  typedef precise_ret ret;                                                 // -> A precise ret has been defined so it is it.
+	};
+
+	template < typename Name,
+		  typename Category_L, typename L,
+		  typename Category_R, typename R >
+	struct helper_choose_binary_wrt_< /* precise_ret == */ undefined,
+					  Name, Category_L, L, Category_R, R >
+	{
+	  typedef typename get_binary_< Name,
+					0, Category_L, L,
+					0, Category_R, R >::ret triplet;           // Browse upwards the category inheritance
+	  typedef mlc_ret(triplet) ret;                                            // to fetch ret from 'get_binary_'s.
+	};
+
+
+	template < typename Name,
+		  typename Category_L, typename L,
+		  typename Category_R, typename R >
+	struct helper_solve_binary_
+	{
+	  typedef typename set_precise_binary_<Name, L, R>::ret precise_ret; /* undefined or not (?) */
+	  typedef helper_choose_binary_wrt_<precise_ret, Name, Category_L,L, Category_R,R> helper;
+	  typedef mlc_ret(helper) ret;
+	};
+
+      } // end of namespace mln::trait::internal
+
+
+      // FIXME: Postfix solve_binary with a '-'(?)
+      template < typename Name,
+		typename L_,
+		typename R_ >
+      struct solve_binary
+      {
+	typedef mln_exact(L_) L;
+	typedef mln_exact(R_) R;
+	typedef typename mln::category<L>::ret Category_L;
+	typedef typename mln::category<R>::ret Category_R;
+	typedef internal::helper_solve_binary_< Name, Category_L, L, Category_R, R > meta_code;
+	typedef typename meta_code::ret ret;
+      };
+
+    } // end of namespace mln::trait::next
+
+  } // end of namespace mln::trait
+
+} // end of namespace mln
+
+
+#endif // ! MLN_TRAIT_NSOLVE_BINARY_HH
Index: trunk/milena/sandbox/fred/fun/fun.cc
===================================================================
--- trunk/milena/sandbox/fred/fun/fun.cc	(revision 3518)
+++ trunk/milena/sandbox/fred/fun/fun.cc	(revision 3519)
@@ -27,6 +27,10 @@
   dbg_print(abs(-1));
   dbg_print(abs(-3.1415926535));
 
+  int x = 1;
+  abs(x) = 2;
+  abs.set(x, 2);
+
   // INC
   mln_invariant(inc(-1) == 0);
   dbg_print(inc(-1));
@@ -48,6 +52,7 @@
   v[2] = 0;
   dbg_print(v);
   dbg_print(l1(v));
+//   dbg_print(cos(l1)(v));
   dbg_print(l2(v));
   dbg_print(linfty(v));
 
Index: trunk/milena/sandbox/fred/fun/thru_morpher.hh
===================================================================
--- trunk/milena/sandbox/fred/fun/thru_morpher.hh	(revision 3518)
+++ trunk/milena/sandbox/fred/fun/thru_morpher.hh	(revision 3519)
@@ -135,6 +135,7 @@
       public:
 
 	/// Type returned by the read-write pixel value operator.
+// 	typedef typename F::template lresult<typename F::argument>::ret lvalue;
 	typedef typename F::lresult lvalue;
 	
 	using thru_image_read<I,F>::operator();
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                          URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
ChangeLog:
2009-03-12  Edwin Carlinet  <carlinet(a)lrde.epita.fr>
	Clean and fix bugs on component trees propagation.
	* edwin/tree/accumulator/max.hh: Special max accumulator for iterator.
	* edwin/tree/accumulator: New.
	* edwin/tree/propagate.hh,
	* edwin/tree/propagate_leaf.hh,
	* edwin/tree/propagate_node.hh,
	* edwin/tree/propagate_value.hh: Improve propagation methods
	and make them cleaner.
	* edwin/tree/propagation.cc: Test file.
	* edwin/tree/routines.hh: Add methods for tree traversal.
---
 Makefile           |    7 -
 accumulator/max.hh |  154 ++++++++++++++++++++++++++++++++
 propagate.hh       |    7 +
 propagate_leaf.hh  |   63 +++++++++++++
 propagate_node.hh  |  253 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 propagate_value.hh |  231 ++++++++++++++++++++++++++++++++++++++++++++++++
 propagation.cc     |  118 ++++++++++++++++++++++++
 routines.hh        |   19 +++
 8 files changed, 847 insertions(+), 5 deletions(-)
Index: trunk/milena/sandbox/edwin/tree/accumulator/max.hh
===================================================================
--- trunk/milena/sandbox/edwin/tree/accumulator/max.hh	(revision 0)
+++ trunk/milena/sandbox/edwin/tree/accumulator/max.hh	(revision 3518)
@@ -0,0 +1,154 @@
+// Copyright (C) 2007, 2008, 2009 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_TREE_ACCUMULATOR_MAX_HH_
+# define MLN_MORPHO_TREE_ACCUMULATOR_MAX_HH_
+
+/// \file mln/morpho/tree/accumulator/max.hh
+///
+/// Define an accumulator that returns iterator matching the max node value.
+
+
+# include <mln/core/concept/image.hh>
+# include <mln/accu/internal/base.hh>
+
+namespace mln {
+  namespace morpho {
+    namespace tree{
+      namespace accumulator {
+
+	template <typename T, typename I>
+	class max : public mln::accu::internal::base< mln_bkd_piter(T::nodes_t), max<T, I> >
+	{
+	  typedef mln::accu::internal::base< unsigned, max<T, I> > super_;
+
+	public:
+	  typedef mln_bkd_piter(T::nodes_t) argument;
+
+	  /// Constructor
+	  max(const Image<I>& f);
+
+	  /// Manipulators.
+	  /// \{
+	  void init();
+
+	  void take(const argument& it);
+	  void take(const max<T, I>& other);
+
+	  void take_as_init(const argument& it);
+	  /// \}
+
+	  /// Get the value of the accumulator.
+	  mln_bkd_piter(T::nodes_t) to_result() const;
+
+	  /// Check whether the accumulator is able to give a result.
+	  bool is_valid() const;
+
+	private:
+	  const I& f_;
+	  mln_bkd_piter(T::nodes_t) max_;
+	};
+
+# ifndef MLN_INCLUDE_ONLY
+
+	template <typename T, typename I>
+	inline
+	max<T, I>::max(const Image<I>& f) :
+	  f_ (exact(f))
+	{
+	}
+
+	template <typename T, typename I>
+	inline
+	void
+	max<T, I>::init()
+	{
+	}
+
+	template <typename T, typename I>
+	inline
+	void
+	max<T, I>::take(const argument& it)
+	{
+	  mln_invariant(it.is_valid());
+
+	  if (!is_valid())
+	    {
+	      take_as_init(it);
+	      return;
+	    }
+
+	  if (f_(it) > f_(max_))
+	    max_ = it;
+	}
+
+ 	template <typename T, typename I>
+	inline
+	void
+	max<T, I>::take(const max<T, I>& other)
+	{
+	  mln_invariant(other.is_valid());
+
+	  if (f_(other.max_) > f_(max_))
+	    max_ = other.max_;
+	}
+
+    	template <typename T, typename I>
+	inline
+	void
+	max<T, I>::take_as_init(const argument& it)
+	{
+	  mln_invariant(it.is_valid());
+	  max_ = it;
+	}
+
+	template <typename T, typename I>
+	inline
+	mln_bkd_piter(T::nodes_t)
+	max<T, I>::to_result() const
+	{
+	  return max_;
+	}
+
+	template <typename T, typename I>
+	inline
+	bool
+	max<T, I>::is_valid() const
+	{
+	  return max_.is_valid();
+	}
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+      }  // end of namespace mln::morpho::tree::accumulator
+    }  // end of namespace mln::morpho::tree
+  }  // end of namespace mln::morpho
+} // end of namespace mln
+
+#endif /* ! MLN_MORPHO_TREE_ACCUMULATOR_MAX_HH_ */
Index: trunk/milena/sandbox/edwin/tree/propagate.hh
===================================================================
--- trunk/milena/sandbox/edwin/tree/propagate.hh	(revision 3517)
+++ trunk/milena/sandbox/edwin/tree/propagate.hh	(revision 3518)
@@ -1,4 +1,4 @@
-// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2008, 2009 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
@@ -55,8 +55,11 @@
 	    }
       }
 
-      namespace binary {
 
+
+
+
+      /// Dans le cas des images binaires...
       /// Propagate a tagged node's value to its subbranches.
       template <typename T, typename A>
       void
Index: trunk/milena/sandbox/edwin/tree/propagate_node.hh
===================================================================
--- trunk/milena/sandbox/edwin/tree/propagate_node.hh	(revision 0)
+++ trunk/milena/sandbox/edwin/tree/propagate_node.hh	(revision 3518)
@@ -0,0 +1,253 @@
+// Copyright (C) 2007, 2008, 2009 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_TREE_PROPAGATE_NODE_HH_
+# define MLN_MORPHO_TREE_PROPAGATE_NODE_HH_
+
+#include <mln/morpho/tree/data.hh>
+#include <mln/core/site_set/p_array.hh>
+
+/// \file mln/morpho/tree/propagate_node.hh
+///
+/// Functions to propagate node in the tree.
+
+namespace mln {
+  namespace morpho {
+    namespace tree {
+
+
+      /**
+      ** Propagate a value to a node and its descendants.
+      **
+      ** @param n Forward iterator related to the node.
+      ** @param t Reference to components tree.
+      ** @param a_ Reference to image.
+      ** @param v Value to propagate. Default is a_(n).
+      */
+      template <typename T, typename A>
+      void
+      propagate_node_to_descendants(mln_bkd_piter(T::nodes_t)& n,
+				    const T& t,
+				    Image<A>& a_,
+				    mln_value(A) v);
+
+      /**
+      ** Propagate the value of a node to its descendants.
+      **
+      ** @param n Forward iterator related to the node.
+      ** @param t Reference to components tree.
+      ** @param a_ Reference to image.
+      */
+      template <typename T, typename A>
+      void
+      propagate_node_to_descendants(mln_bkd_piter(T::nodes_t)& n,
+				    const T& t,
+				    Image<A>& a_);
+
+
+      /**
+      ** Propagate a value to a node and its descendants.
+      **
+      ** @param n The root of subtree which value propagates in.
+      ** @param t The reference to components tree.
+      ** @param a_ The reference to image.
+      ** @param v The value to propagate. Default is a_(n).
+      */
+      template <typename T, typename A>
+      void
+      propagate_node_to_descendants(mln_psite(A) n,
+				    const T& t,
+				    Image<A>& a_,
+				    mln_value(A) v);
+
+      /**
+      ** Propagate the node's value to its descendants.
+      **
+      ** @param n The root of subtree which value propagates in.
+      ** @param t The reference to components tree.
+      ** @param a_ The reference to image.
+      */
+      template <typename T, typename A>
+      void
+      propagate_node_to_descendants(mln_psite(A)& n,
+				    const T& t,
+				    Image<A>& a_);
+
+      /**
+      ** Propagate a value from a node to its ancestors.
+      **
+      ** @param n Forward iterator related to the node.
+      ** @param t Reference to components tree.
+      ** @param a_ Reference to image.
+      ** @param v Value to propagate.
+      */
+      template <typename T, typename A>
+      void
+      propagate_node_to_ancestors(mln_psite(A) n,
+				  const T& t,
+				  Image<A>& a_,
+				  mln_value(A) v);
+
+      /**
+      ** Propagate the node's value to its ancestors.
+      **
+      ** @param n Forward iterator related to the node.
+      ** @param t Reference to components tree.
+      ** @param a_ Reference to image.
+      */
+      template <typename T, typename A>
+      void
+      propagate_node_to_ancestors(mln_psite(A) n,
+				  const T& t,
+				  Image<A>& a_);
+
+
+
+
+
+
+      /* Descendants propagation */
+
+      template <typename T, typename A>
+      void
+      propagate_node_to_descendants(mln_bkd_piter(T::nodes_t)& n,
+				    const T& t,
+				    Image<A>& a_,
+				    mln_value(A) v)
+      {
+	A& a = exact(a_);
+	mln_precondition(a.is_valid());
+	mln_precondition(a.domain() == t.f().domain());
+	mln_precondition(n.is_valid());
+	mln_precondition(t.is_a_node(n));
+
+	mln_ch_value(A, bool) ancestors;
+	initialize(ancestors, a);
+	data::fill(ancestors, false);
+	ancestors(n) = true;
+
+	mln_bkd_piter(T::nodes_t) it(n);
+	for (it.next(); it.is_valid(); it.next())
+	  {
+	    if (ancestors(t.parent(it)))
+	      {
+		ancestors(it) = true;
+		a(it) = v;
+	      }
+	  }
+      }
+
+      template <typename T, typename A>
+      inline
+      void
+      propagate_node_to_descendants(mln_bkd_piter(T::nodes_t)& n,
+				    const T& t,
+				    Image<A>& a_)
+      {
+	A& a = exact(a_);
+	propagate_node_to_descendants(n, t, a, a(n));
+      }
+
+      template <typename T, typename A>
+      void
+      propagate_node_to_descendants(mln_psite(A) n,
+				    const T& t,
+				    Image<A>& a_,
+				    mln_value(A) v)
+      {
+	A& a = exact(a_);
+	mln_precondition(a.is_valid());
+	mln_precondition(a.domain() == t.f().domain());
+	mln_precondition(a.domain().has(n));
+
+
+	if (!t.is_a_node(n)) // Get the representant.
+	  n = t.parent(n);
+
+	mln_bkd_piter(T::nodes_t) it = find_bkd(t.nodes(), n);
+	propagate_node_to_descendants(it, t, a, v);
+      }
+
+      template <typename T, typename A>
+      inline
+      void
+      propagate_node_to_descendants(mln_psite(A) n,
+				    const T& t,
+				    Image<A>& a_)
+
+      {
+	A& a = exact(a_);
+	propagate_node_to_descendants(n, t, a, a(n));
+      }
+
+
+      /* Ancestors propagation */
+
+      template <typename T, typename A>
+      void
+      propagate_node_to_ancestors(mln_psite(A) n,
+				  const T& t,
+				  Image<A>& a_,
+				  mln_value(A) v)
+      {
+	A& a = exact(a_);
+	mln_precondition(a.is_valid());
+	mln_precondition(a.domain() == t.f().domain());
+	mln_precondition(a.domain().has(n));
+
+	if (!t.is_a_node(n))
+	  n = t.parent(n);
+	mln_assertion(t.is_a_node(n));
+
+	if (t.is_root(n))
+	  return;
+
+	do {
+	  n = t.parent(n);
+	  a(n) = v;
+	} while (!t.is_root(n));
+
+      }
+
+      template <typename T, typename A>
+      inline
+      void
+      propagate_node_to_ancestors(mln_psite(A) n,
+				  const T& t,
+				  Image<A>& a_)
+      {
+	A& a = exact(a_);
+	propagate_node_to_ancestors(n, t, a, a(n));
+      }
+
+
+    } // end of namespace mln::morpho::tree
+  } // end of namespace mln::morpho
+} // end of namespace mln
+
+#endif /* !MLN_MORPHO_TREE_PROPAGATE_NODE_HH_ */
Index: trunk/milena/sandbox/edwin/tree/routines.hh
===================================================================
--- trunk/milena/sandbox/edwin/tree/routines.hh	(revision 3517)
+++ trunk/milena/sandbox/edwin/tree/routines.hh	(revision 3518)
@@ -37,6 +37,22 @@
   namespace morpho {
     namespace tree {
 
+
+      template <typename T, 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
       // FIXME: it bugs; need a stack/queue
       template <typename I, typename T>
       util::array< mln_psite(I) >
@@ -65,6 +81,9 @@
 	return fnodes;
       }
 
+      template <typename T, 
+
+
     }
   }
 }
Index: trunk/milena/sandbox/edwin/tree/propagate_leaf.hh
===================================================================
--- trunk/milena/sandbox/edwin/tree/propagate_leaf.hh	(revision 0)
+++ trunk/milena/sandbox/edwin/tree/propagate_leaf.hh	(revision 3518)
@@ -0,0 +1,63 @@
+// Copyright (C) 2007, 2008, 2009 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_TREE_PROPAGATE_LEAF_HH_
+# define MLN_MORPHO_TREE_PROPAGATE_LEAF_HH_
+
+
+/// \file mln/morpho/tree/propagate_leaf.hh
+///
+/// Functions to propagate the leaf value in the tree.
+
+namespace mln {
+  namespace morpho {
+    namespace tree {
+
+      template <typename T, typename A>
+      void
+      propagate_leaf_to_ancestors(mln_value(A) v,
+				  const T& t,
+				  Image<A>& a_)
+      {
+	A& a = exact(a_);
+
+	mln_fwd_piter(T::leaves_t) l(t.leaves());
+	for_all(l)
+	  a(t.parent(l)) = 0;
+
+	mln_fwd_piter(T::nodes_t) n(t.nodes());
+	for_all(n)
+	{
+	  mln_assertion(t.is_a_node(t.parent(n)));
+	  a(t.parent(n)) = a(t.parent(n)) || a(n);
+	}
+      }
+    } // end of namespace mln::morpho::tree
+  } // end of namespace mln::morpho
+} // end of namespace mln
+#endif /* !MLN_MORPHO_TREE_PROPAGATE_LEAF_HH_ */
Index: trunk/milena/sandbox/edwin/tree/propagation.cc
===================================================================
--- trunk/milena/sandbox/edwin/tree/propagation.cc	(revision 0)
+++ trunk/milena/sandbox/edwin/tree/propagation.cc	(revision 3518)
@@ -0,0 +1,118 @@
+#include <iostream>
+
+#include <mln/core/image/image2d.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/core/alias/point2d.hh>
+#include <mln/core/routine/duplicate.hh>
+
+#include <mln/value/int_u8.hh>
+#include <mln/io/pgm/load.hh>
+
+
+#include <mln/level/sort_psites.hh>
+#include <mln/morpho/tree/data.hh>
+
+
+#include <../../theo/color/change_attributes.hh>
+#include "propagate_node.hh"
+#include "propagate_value.hh"
+#include "run.hh"
+#include "accumulator/max.hh"
+
+void usage(char** argv)
+{
+  std::cerr << "usage: " << argv[0] << " input" << std::endl;
+  abort();
+}
+
+void dsp(const char* str)
+{
+  std::cout << "*********************" << std::endl
+	    << "** " << str << std::endl
+	    << "*********************" << std::endl;
+}
+
+int main(int argc, char* argv[])
+{
+  using namespace mln;
+  using value::int_u8;
+
+  if (argc < 2)
+    usage(argv);
+
+
+  typedef image2d<int_u8> I;
+  I input, dup;
+
+
+  io::pgm::load(input, argv[1]);
+
+
+  typedef p_array< mln_site_(I) > S;
+  typedef morpho::tree::data<I,S> tree_t;
+  S sorted_sites = level::sort_psites_decreasing(input);
+  tree_t tree(input, sorted_sites, c4());
+
+  dsp("Input:");
+  display_tree_attributes(tree, input);
+
+  dup = duplicate(input);
+  morpho::tree::propagate_node_to_ancestors(point2d(1, 4), tree, dup, 0);
+  dsp("Propagate node to ancestors  : (point2d(1, 4), tree, dup, 0)");
+  display_tree_attributes(tree, dup);
+
+  dup = duplicate(input);
+  morpho::tree::propagate_node_to_ancestors(point2d(1, 4), tree, dup);
+  dsp("Propagate node to ancestors  : (point2d(1, 4), tree, dup)");
+  display_tree_attributes(tree, dup);
+
+  dup = duplicate(input);
+  morpho::tree::propagate_node_to_descendants(point2d(0, 2), tree, dup, 0);
+  dsp("Propagate node to descendants  : (point2d(0, 2), tree, dup, 0)");
+  display_tree_attributes(tree, dup);
+
+  dup = duplicate(input);
+  morpho::tree::propagate_node_to_descendants(point2d(0, 2), tree, dup);
+  dsp("Propagate node to descendants  : (point2d(0, 2), tree, dup)");
+  display_tree_attributes(tree, dup);
+
+  dup = duplicate(input);
+  morpho::tree::propagate_value_to_ancestors(117, tree, dup, 0);
+  dsp("Propagate value to ancestors  : (117, tree, dup, 0)");
+  display_tree_attributes(tree, dup);
+
+  dup = duplicate(input);
+  morpho::tree::propagate_value_to_ancestors(117, tree, dup);
+  dsp("Propagate value to ancestors  : (117, tree, dup)");
+  display_tree_attributes(tree, dup);
+
+  dup = duplicate(input);
+  morpho::tree::propagate_value_to_descendants(117, tree, dup, 0);
+  dsp("Propagate value to descendants  : (117, tree, dup, 0)");
+  display_tree_attributes(tree, dup);
+
+  dup = duplicate(input);
+  morpho::tree::propagate_value_to_descendants(117, tree, dup);
+  dsp("Propagate value to descendants  : (117, tree, dup)");
+  display_tree_attributes(tree, dup);
+
+
+
+  dup = duplicate(input);
+
+  typedef morpho::tree::accumulator::max<tree_t, I> A;
+  A accu(dup);
+  morpho::tree::run_bkd(tree, accu);
+
+  mln_bkd_piter_(tree_t::nodes_t) it_max = accu.to_result();
+  morpho::tree::propagate_node_to_descendants(it_max, tree, dup, 69);
+  dsp("Propagate value to descendants  : (it_max, tree, dup, 69)");
+  display_tree_attributes(tree, dup);
+
+
+
+
+}
+
+
+
Index: trunk/milena/sandbox/edwin/tree/propagate_value.hh
===================================================================
--- trunk/milena/sandbox/edwin/tree/propagate_value.hh	(revision 0)
+++ trunk/milena/sandbox/edwin/tree/propagate_value.hh	(revision 3518)
@@ -0,0 +1,231 @@
+// Copyright (C) 2007, 2008, 2009 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_TREE_PROPAGATE_VALUE_HH_
+# define MLN_MORPHO_TREE_PROPAGATE_VALUE_HH_
+
+
+/// \file mln/morpho/tree/propagate_value.hh
+///
+/// Functions to propagate a value in the tree.
+
+namespace mln {
+  namespace morpho {
+    namespace tree {
+
+     /**
+      ** Propagate the value \p v2 from node \p n having the value \p v
+      ** to its ancestors.
+      **
+      ** @param v Value that node must have to be propagated.
+      ** @param t Reference to components tree.
+      ** @param a_ Reference to image.
+      ** @param v2 Value to propagate (\p v by default).
+      */
+      template <typename T, typename A>
+      void
+      propagate_value_to_ancestors(mln_value(A) v,
+				   const T& t,
+				   Image<A>& a_,
+				   mln_value(A) v2);
+
+      /**
+      ** Propagate the value \p v2 from node \p n having the value \p v
+      ** to its descendants.
+      **
+      ** @param v Value that node must have to be propagated.
+      ** @param t Reference to components tree.
+      ** @param a_ Reference to image.
+      ** @param v2 Value to propagate (\p v by default).
+      */
+      template <typename T, typename A>
+      void
+      propagate_value_to_descendants(mln_value(A) v,
+				     const T& t,
+				     Image<A>& a_,
+				     mln_value(A) v2);
+
+
+
+
+
+
+
+
+
+      namespace internal
+      {
+	template <typename T, typename A>
+	bool check_propagate_ancestors(const T& t, const A& a, mln_value(A) v)
+	{
+	  mln_fwd_piter(T::nodes_t) n(t.nodes());
+	  for_all(n)
+	    if (a(n) == v && a(t.parent(n)) != v)
+	      return false;
+	  return true;
+	}
+
+	template <typename T, typename A>
+	bool check_propagate_descendants(const T& t, const A& a, mln_value(A) v)
+	{
+	  mln_fwd_piter(T::nodes_t) n(t.nodes());
+	  for_all(n)
+	    if (a(n) != v && a(t.parent(n)) == v)
+	      return false;
+	  return true;
+	}
+
+      } // end of namespace mln::morpho::tree::internal
+
+      template <typename T, typename A>
+      void
+      propagate_value_to_ancestors(mln_value(A) v,
+				   const T& t,
+				   Image<A>& a_,
+				   mln_value(A) v2)
+      {
+	if (v == v2)
+	  {
+	    propagate_value_to_ancestors(v, t, a_);
+	    return;
+	  }
+
+	A& a = exact(a_);
+	mln_precondition(a.is_valid());
+	mln_precondition(a.domain() == t.f().domain());
+
+	mln_ch_value(A, bool) deja_vu;
+	initialize(deja_vu, a);
+	data::fill(deja_vu, false);
+
+	mln_fwd_piter(T::nodes_t) n(t.nodes());
+	for_all(n)
+	{
+	  if (a(n) == v || deja_vu(n))
+	    {
+	      mln_assertion(t.is_a_node(t.parent(n)));
+	      a(t.parent(n)) = v2;
+	      deja_vu(t.parent(n)) = true;
+	    }
+	}
+
+	mln_postcondition(internal::check_propagate_ancestors(t, a, v2));
+      }
+
+
+      template <typename T, typename A>
+      void
+      propagate_value_to_ancestors(mln_value(A) v,
+				   const T& t,
+				   Image<A>& a_)
+      {
+	A& a = exact(a_);
+	mln_precondition(a.is_valid());
+	mln_precondition(a.domain() == t.f().domain());
+
+	mln_fwd_piter(T::nodes_t) n(t.nodes());
+	for_all(n)
+	{
+	  if (a(n) == v)
+	    {
+	      mln_assertion(t.is_a_node(t.parent(n)));
+	      a(t.parent(n)) = v;
+	    }
+	}
+
+	mln_postcondition(internal::check_propagate_ancestors(t, a, v));
+      }
+
+
+      template <typename T, typename A>
+      void
+      propagate_value_to_descendants(mln_value(A) v,
+				     const T& t,
+				     Image<A>& a_,
+				     mln_value(A) v2)
+      {
+	if (v == v2)
+	  {
+	    propagate_value_to_descendants(v, t, a_);
+	    return;
+	  }
+
+	A& a = exact(a_);
+	mln_precondition(a.is_valid());
+	mln_precondition(a.domain() == t.f().domain());
+
+	mln_ch_value(A, bool) deja_vu;
+	initialize(deja_vu, a);
+	data::fill(deja_vu, false);
+
+	mln_bkd_piter(T::nodes_t) n(t.nodes());
+	for_all(n)
+	{
+	  if (a(n) == v)
+	    {
+	      mln_assertion(t.is_a_node(t.parent(n)));
+	      deja_vu(n) = true;
+	    }
+	  else if (deja_vu(t.parent(n)))
+	    {
+	      mln_assertion(t.is_a_node(t.parent(n)));
+	      a(n) = v2;
+	      deja_vu(n) = true;
+	    }
+	}
+	mln_postcondition(internal::check_propagate_descendants(t, a, v2));
+      }
+
+      template <typename T, typename A>
+      void
+      propagate_value_to_descendants(mln_value(A) v,
+				     const T& t,
+				     Image<A>& a_)
+      {
+     	A& a = exact(a_);
+	mln_precondition(a.is_valid());
+	mln_precondition(a.domain() == t.f().domain());
+
+	mln_bkd_piter(T::nodes_t) n(t.nodes());
+	for_all(n)
+	{
+	  if (a(t.parent(n)) == v)
+	    {
+	      mln_assertion(t.is_a_node(t.parent(n)));
+	      a(n) = v;
+	    }
+	}
+	mln_postcondition(internal::check_propagate_descendants(t, a, v));
+      }
+
+
+    } // end of namespace mln::morpho::tree
+  } // end of namespace mln::morpho
+} // end of namespace mln
+
+#endif /* !MLN_MORPHO_TREE_PROPAGATE_VALUE_HH_ */
Index: trunk/milena/sandbox/edwin/tree/Makefile
===================================================================
--- trunk/milena/sandbox/edwin/tree/Makefile	(revision 3517)
+++ trunk/milena/sandbox/edwin/tree/Makefile	(revision 3518)
@@ -1,5 +1,5 @@
-TARGET=tree
-SRC=tree.cc
+TARGET=propagation
+SRC=propagation.cc
 OBJS=${SRC:.cc=.o}
 
 OLENADIR=$(MLN_DIR)/..
@@ -7,7 +7,8 @@
 
 CXXFLAGS=-I$(MILENADIR) -I./
 
-CXXFLAGS += -DNDEBUG -O1
+CXXFLAGS += -g -ggdb
+#CXXFLAGS += -DNDEBUG -O1
 
 CXX=g++
 LD=g++
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                          URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
ChangeLog:
2009-03-12  Fabien Freling  <fabien.freling(a)lrde.epita.fr>
	Create workflow based on small tools.
	* fabien/bin/dumpl32_to_colorize.cc: New.
	* fabien/igr/Makefile: Update.
	* fabien/igr/check.sh: New script shell for testing.
	* fabien/igr/clo_vol.cc: Implement closing volume.
	* fabien/igr/grad.cc: Implement gradient.
	* fabien/igr/graph.cc: Implement graph.
	* fabien/igr/wst.cc: Implement watershed.
---
 TODO                       |    6 
 bin/dumpl32_to_colorize.cc |   61 ++++++++
 igr/Makefile               |   40 +++--
 igr/check.sh               |   32 ++++
 igr/clo_vol.cc             |   63 ++++++++
 igr/grad.cc                |   63 ++++++++
 igr/graph.cc               |  329 +++++++++++++++++++++++++++++++++++++++++++++
 igr/wst.cc                 |   71 +++++++++
 8 files changed, 650 insertions(+), 15 deletions(-)
Index: trunk/milena/sandbox/fabien/igr/clo_vol.cc
===================================================================
--- trunk/milena/sandbox/fabien/igr/clo_vol.cc	(revision 0)
+++ trunk/milena/sandbox/fabien/igr/clo_vol.cc	(revision 3517)
@@ -0,0 +1,63 @@
+#include <iostream>
+#include <mln/core/image/image2d.hh>
+#include <mln/core/image/image3d.hh>
+
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/core/alias/window2d.hh>
+#include <mln/core/alias/neighb3d.hh>
+#include <mln/core/alias/window3d.hh>
+
+#include <mln/io/dump/all.hh>
+
+#include <mln/value/int_u8.hh>
+#include <mln/value/int_u12.hh>
+
+#include <mln/morpho/closing/volume.hh>
+
+
+
+///////////////////
+//               //
+// Main Function //
+//               //
+///////////////////
+
+
+int main(int argc, char *argv[])
+{
+  using namespace mln;
+  using value::int_u8;
+  using value::int_u12;
+
+  if (argc != 4)
+  {
+    std::cout << "Usage: " << argv[0] << " <input.dump> <dimensions> <closure_lambda>"
+	      << std::endl;
+    return 1;
+  }
+
+  unsigned closure_lambda = atoi(argv[3]);
+  unsigned dim = atoi(argv[2]);
+  if (dim != 2 && dim != 3)
+  {
+    std::cout << "<dimensions> invalid" << std::endl;
+    return 1;
+  }
+
+  if (dim == 2)
+  {
+    image2d<int_u12> input;
+    io::dump::load(input, argv[1]);
+    image2d<int_u12> clo = morpho::closing::volume(input, c4(), closure_lambda);
+    io::dump::save(clo, "clo_vol.dump");
+  }
+  else
+  {
+    image3d<int_u12> input;
+    io::dump::load(input, argv[1]);
+    image3d<int_u12> clo = morpho::closing::volume(input, c6(), closure_lambda);
+    io::dump::save(clo, "clo_vol.dump");
+  }
+
+  return 0;
+}
Index: trunk/milena/sandbox/fabien/igr/graph.cc
===================================================================
--- trunk/milena/sandbox/fabien/igr/graph.cc	(revision 0)
+++ trunk/milena/sandbox/fabien/igr/graph.cc	(revision 3517)
@@ -0,0 +1,329 @@
+#include <iostream>
+#include <mln/core/image/image2d.hh>
+#include <mln/core/image/image3d.hh>
+#include <mln/core/image/image_if.hh>
+
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/core/alias/window2d.hh>
+#include <mln/core/alias/neighb3d.hh>
+#include <mln/core/alias/window3d.hh>
+
+#include <mln/io/dump/all.hh>
+#include <mln/io/dicom/load.hh>
+#include <mln/io/pgm/save.hh>
+
+#include <mln/value/int_u8.hh>
+#include <mln/value/int_u12.hh>
+#include <mln/value/label_16.hh>
+#include <mln/value/label_32.hh>
+
+#include <mln/morpho/watershed/flooding.hh>
+
+#include <mln/math/diff_abs.hh>
+
+#include <mln/labeling/mean_values.hh>
+
+#include <mln/convert/to_fun.hh>
+
+#include <mln/make/graph.hh>
+#include <mln/util/graph.hh>
+
+#include <mln/fun/l2l/wrap.hh>
+
+#include <mln/core/var.hh>
+#include <mln/morpho/elementary/dilation.hh>
+
+#include <mln/core/routine/extend.hh>
+
+#include <mln/core/alias/vec3d.hh>
+#include <mln/debug/draw_graph.hh>
+#include <mln/accu/center.hh>
+#include <mln/io/dump/all.hh>
+#include <mln/value/label_8.hh>
+#include <mln/value/rgb16.hh>
+#include <mln/accu/compute.hh>
+#include <mln/core/alias/dpoint2d.hh>
+#include <mln/draw/box.hh>
+#include <mln/level/stretch.hh>
+#include <mln/fun/v2v/id.hh>
+#include <mln/fun/l2l/wrap.hh>
+#include <mln/core/image/line_graph_elt_neighborhood.hh>
+#include <mln/labeling/mean_values.hh>
+#include <mln/extension/adjust_fill.hh>
+#include <mln/extract/all.hh>
+#include <mln/make/region_adjacency_graph.hh>
+
+
+
+
+// Given a color image and a wshed image, computes the component graph.
+// Vertex values are computed thanks to a RGB image.
+
+namespace mln
+{
+
+  template <typename V>
+  value::int_u8 dist(const V& c1, const V& c2)
+  {
+    unsigned d = math::diff_abs(c1.red(), c2.red());
+    unsigned d_;
+    d_ = math::diff_abs(c1.green(), c2.green());
+
+    if (d_ > d)
+      d = d_;
+
+    d_ = math::diff_abs(c1.blue(), c2.blue());
+
+    if (d_ > d)
+      d = d_;
+    return d;
+  }
+
+
+  // ima_v, image on graph vertices; value = mean color per vertex (watershed basin)
+  template <typename I>
+  inline
+  pw::image<fun::i2v::array<value::int_u8>,
+	    p_edges<util::graph, fun::i2v::array<mln_site(I)> > >
+  make_edge_graph_image(const I& ima_v, const util::graph& g)
+  {
+    // edge sites.
+    typedef fun::i2v::array<mln_site(I)> edge_site_t;
+    edge_site_t edge_site(g.e_nmax(), literal::origin);
+    typedef p_edges<util::graph, edge_site_t > pe_t;
+    pe_t pe(g, edge_site);
+
+    // edge values
+    typedef fun::i2v::array<value::int_u8> edge_values_t;
+    edge_values_t edge_values(g.e_nmax());
+
+    // image on graph edges
+    typedef pw::image<edge_values_t, pe_t> ima_e_t;
+    ima_e_t ima_e = (edge_values | pe);
+
+    mln_piter(ima_e_t) e(ima_e.domain());
+    for_all(e) // in ima_e
+      ima_e(e) = math::diff_abs(ima_v.function()(e.element().v1()), ima_v.function()(e.element().v2()));
+
+    return ima_e;
+  }
+
+
+  template <typename I, typename J>
+  inline
+  util::array<mln_value(I)>
+  mean_color_values(const I& input, const J& w, mln_value(J) nbasins)
+  {
+    // Cf. sandbox/theo/color/segment_rgb_pixels.cc
+
+    util::array<float> m_3f = labeling::compute(accu::mean<mln_value(I)>(),
+						input, // input color image
+						w, // watershed labeling
+						nbasins);
+    m_3f[0] = literal::zero;
+
+    util::array<mln_value(I)> m;
+    convert::from_to(m_3f, m);
+    m[0] = 150u;
+
+    /*io::ppm::save(level::transform(w,
+	  convert::to< fun::i2v::array<mln_value(I)> >(m)),
+	"wst_rag_wshd_color.ppm");*/
+
+    return m;
+  }
+
+
+  template <typename I, typename J>
+  pw::image<fun::i2v::array<mln_value(I)>, p_vertices<util::graph, fun::i2v::array<mln_site(I)> > >
+  make_vertex_graph_image(const util::graph& g, const I&input, const J& w, const mln_value(J)& nbasins)
+  {
+    typedef util::array<mln_site(I)> vertex_sites_t;
+    vertex_sites_t site_values;
+    convert::from_to(labeling::compute(accu::center<mln_site(I)>(), w, nbasins),
+				       site_values);
+
+    typedef fun::i2v::array<mln_site(J)> f_sites_t;
+    f_sites_t sites;
+    convert::from_to(site_values, sites);
+
+    // p_vertices
+    typedef p_vertices<util::graph, f_sites_t> S;
+    S pv(g, sites);
+
+
+    typedef fun::i2v::array<mln_value(I)> vertex_values_t;
+    vertex_values_t vertex_values;
+    convert::from_to(mean_color_values(input, w, nbasins), vertex_values);
+
+    mln_VAR(ima_v, (vertex_values | pv));
+
+    return ima_v;
+  }
+
+
+  template <typename I, typename V>
+  struct edge_to_color : Function_p2v< edge_to_color<I,V> >
+  {
+    typedef V result;
+
+    edge_to_color(const I& ima)
+      : ima_(ima)
+    {
+    }
+
+    V
+    operator()(const unsigned& e) const
+    {
+      return convert::to<V>(ima_.function()(e));
+    }
+
+    const I& ima_;
+  };
+
+  template <typename V>
+  inline
+  unsigned
+  find_root(util::array<V>& parent, const unsigned& x)
+  {
+    if (parent[x] == x)
+      return x;
+    else
+      return parent[x] = find_root(parent, parent[x]);
+  }
+
+
+  template <typename I, typename V, typename E>
+  inline
+  image2d<mln_value(I)>
+  make_debug_graph_image(const I& input,
+			 const V& ima_v, const E& ima_e,
+			 unsigned box_size, const value::int_u12& bg)
+  {
+    image2d<mln_value(I)> ima;
+    initialize(ima, input);
+
+    data::fill(ima, bg);
+    debug::draw_graph(ima, ima_v.domain(),
+		      pw::cst(150u),
+		      edge_to_color<E, mln_value(I)>(ima_e));
+
+    dpoint2d tl(-box_size,-box_size);
+    dpoint2d br(box_size,box_size);
+    mln_piter(V) p(ima_v.domain());
+    for_all(p)
+    {
+      box2d b(p + tl, p + br);
+      b.crop_wrt(ima.domain());
+      data::fill((ima | b).rw(), convert::to<mln_value(I)>(ima_v(p)));
+    }
+
+    return ima;
+  }
+
+}
+
+
+
+
+
+///////////////////
+//               //
+// Main Function //
+//               //
+///////////////////
+
+
+int main(int argc, char *argv[])
+{
+  using namespace mln;
+  using value::int_u8;
+  using value::int_u12;
+  using value::label_16;
+  using value::label_32;
+  typedef label_32 L;
+
+  if (argc != 6)
+  {
+    std::cout << "Usage: " << argv[0] << " <wst.dump> <dimensions> <ima.dcm> <dist_max> <nbasins>"
+	      << std::endl;
+    return 1;
+  }
+
+  unsigned dim = atoi(argv[2]);
+  unsigned dist_max = atoi(argv[4]);
+  if (dim != 2 && dim != 3)
+  {
+    std::cout << "<dimensions> invalid" << std::endl;
+    return 1;
+  }
+
+  L nbasins = atoi(argv[5]);
+  unsigned nbasins2 = 0;
+
+  if (dim == 2)
+  {
+    image2d<L> wshed;
+    io::dump::load(wshed, argv[1]);
+    image2d<int_u12> dcm;
+    io::dicom::load(dcm, argv[3]);
+
+    /// Build graph
+    util::graph g = make::graph(wshed, c4(), nbasins);
+    // Build graph images and compute distance values with a RGB image.
+    mln_VAR(ima_v, make_vertex_graph_image(g, dcm, wshed, nbasins));
+    mln_VAR(ima_e, make_edge_graph_image(ima_v, g));
+
+    /// Try to merge vertices.
+    mln_piter_(ima_e_t) e(ima_e.domain());
+    util::array<label_16> parent(g.v_nmax());
+    for (unsigned i = 0; i < parent.nelements(); ++i)
+      parent[i] = i;
+
+    for_all(e)
+    {
+      unsigned v1 = e.element().v1();
+      unsigned v2 = e.element().v2();
+      if (ima_e(e) <= dist_max && find_root(parent, v1) != find_root(parent, v2))
+	parent[find_root(parent, v1)] = find_root(parent, v2);
+    }
+
+    fun::i2v::array<label_16> f(parent.nelements());
+    std::vector<unsigned> new_label(parent.nelements(), 0);
+    for (unsigned i = 0; i < parent.nelements(); ++i)
+    {
+      unsigned p = find_root(parent, i);
+      mln_assertion(parent[p] == find_root(parent, i));
+      if (new_label[p] == 0)
+	new_label[p] = nbasins2++;
+      f(i) = new_label[p];
+    }
+    mln_invariant(f(0) == 0u);
+    --nbasins2; // nbasins2 does not count the basin with label 0.
+    image2d<label_16> wsd2 = level::transform(wshed, f);
+
+    /// Reconstruct a graph from the simplified image.
+    util::graph g2 = make::graph(wsd2, c4(), nbasins2);
+
+    // Compute distance values with a RGB image.
+    mln_VAR(ima_v2, make_vertex_graph_image(g2, dcm, wsd2, nbasins2));
+    mln_VAR(ima_e2, make_edge_graph_image(ima_v2, g2));
+
+    mln_VAR(wsd_, morpho::elementary::dilation(extend(wshed | (pw::value(wshed) == 0u), wshed), c8()));
+    data::fill((wshed | (pw::value(wshed) == 0u)).rw(), wsd_);
+
+    mln_VAR(wsd2_, morpho::elementary::dilation(extend(wsd2 | (pw::value(wsd2) == 0u), wsd2), c8()));
+    data::fill((wsd2 | (pw::value(wsd2) == 0u)).rw(), wsd2_);
+
+    io::pgm::save(level::stretch(int_u8(), labeling::mean_values(dcm, wshed, nbasins)), "wsd_original.pgm");
+    io::pgm::save(level::stretch(int_u8(), labeling::mean_values(dcm, wsd2, nbasins2)), "wsd_mean_colors.pgm");
+  }
+  else
+  {
+    // FIXME
+  }
+
+  std::cout << nbasins2 << std::endl;
+
+  return 0;
+}
Index: trunk/milena/sandbox/fabien/igr/check.sh
===================================================================
--- trunk/milena/sandbox/fabien/igr/check.sh	(revision 0)
+++ trunk/milena/sandbox/fabien/igr/check.sh	(revision 3517)
@@ -0,0 +1,32 @@
+#!/bin/zsh
+
+process_file ()
+{
+  echo "Processing $3..."
+  dist_max=10
+
+  ./grad $1 $2
+  for lambda_closing in 10 50 100 500 1000 5000 10000 50000; do
+    echo "  for lambda_closing = ${lambda_closing}";
+    ./clo_vol grad.dump $2 ${lambda_closing}
+    nbasins=`./wst clo_vol.dump $2`
+    ../bin/dumpl32_to_colorize wst.dump $2 $nbasins results/colorize_${3}_${lambda_closing}.ppm
+
+    if [ ${lambda_closing} -eq 100 ]; then
+      for lambda_dist in 10 50 100; do
+	nbasins_after=`./graph wst.dump $2 $1 $lambda_dist $nbasins`
+	mv wsd_original.pgm results/graph_${3}_${lambda_closing}_${lambda_dist}_01.pgm
+	mv wsd_mean_colors.pgm results/graph_${3}_${lambda_closing}_${lambda_dist}_02.pgm
+	echo "nbasins was" $nbasins "and now is" $nbasins_after "( diff =" $(($nbasins - $nbasins_after)) ")"
+      done
+    fi
+  done
+#  rm *.dump
+}
+
+process_file "/Users/HiSoKa/Work/IGR/souris18/irm/IM_0049.dcm" 2 "49"
+#process_file "/Users/HiSoKa/Work/IGR/souris18/irm/IM_0052.dcm" 3 "52"
+process_file "/Users/HiSoKa/Work/IGR/souris18/irm/IM_0055.dcm" 2 "55"
+process_file "/Users/HiSoKa/Work/IGR/souris18/irm/IM_0058.dcm" 2 "58"
+#process_file "/Users/HiSoKa/Work/IGR/souris18/irm/IM_0061.dcm" 3 "61"
+#process_file "/Users/HiSoKa/Work/IGR/souris18/irm/IM_0064.dcm" 3 "64"
Property changes on: trunk/milena/sandbox/fabien/igr/check.sh
___________________________________________________________________
Name: svn:executable
   + *
Index: trunk/milena/sandbox/fabien/igr/wst.cc
===================================================================
--- trunk/milena/sandbox/fabien/igr/wst.cc	(revision 0)
+++ trunk/milena/sandbox/fabien/igr/wst.cc	(revision 3517)
@@ -0,0 +1,71 @@
+#include <iostream>
+#include <mln/core/image/image2d.hh>
+#include <mln/core/image/image3d.hh>
+
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/core/alias/window2d.hh>
+#include <mln/core/alias/neighb3d.hh>
+#include <mln/core/alias/window3d.hh>
+
+#include <mln/io/dump/all.hh>
+
+#include <mln/value/int_u8.hh>
+#include <mln/value/int_u12.hh>
+#include <mln/value/label_16.hh>
+#include <mln/value/label_32.hh>
+
+#include <mln/morpho/watershed/flooding.hh>
+
+
+
+///////////////////
+//               //
+// Main Function //
+//               //
+///////////////////
+
+
+int main(int argc, char *argv[])
+{
+  using namespace mln;
+  using value::int_u8;
+  using value::int_u12;
+  using value::label_16;
+  using value::label_32;
+  typedef label_32 L;
+
+  if (argc != 3)
+  {
+    std::cout << "Usage: " << argv[0] << " <ima.dcm> <dimensions>"
+	      << std::endl;
+    return 1;
+  }
+
+  unsigned dim = atoi(argv[2]);
+  if (dim != 2 && dim != 3)
+  {
+    std::cout << "<dimensions> invalid" << std::endl;
+    return 1;
+  }
+
+  L nbasins;
+
+  if (dim == 2)
+  {
+    image2d<int_u12> input;
+    io::dump::load(input, argv[1]);
+    image2d<L> wshed = morpho::watershed::flooding(input, c4(), nbasins);
+    io::dump::save(wshed, "wst.dump");
+  }
+  else
+  {
+    image3d<int_u12> input;
+    io::dump::load(input, argv[1]);
+    image3d<L> wshed = morpho::watershed::flooding(input, c6(), nbasins);
+    io::dump::save(wshed, "wst.dump");
+  }
+
+  std::cout << nbasins << std::endl;
+
+  return 0;
+}
Index: trunk/milena/sandbox/fabien/igr/grad.cc
===================================================================
--- trunk/milena/sandbox/fabien/igr/grad.cc	(revision 0)
+++ trunk/milena/sandbox/fabien/igr/grad.cc	(revision 3517)
@@ -0,0 +1,63 @@
+#include <iostream>
+#include <mln/core/image/image2d.hh>
+#include <mln/core/image/image3d.hh>
+
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/core/alias/window2d.hh>
+#include <mln/core/alias/neighb3d.hh>
+#include <mln/core/alias/window3d.hh>
+
+#include <mln/io/dicom/load.hh>
+#include <mln/io/dump/save.hh>
+
+#include <mln/value/int_u8.hh>
+#include <mln/value/int_u12.hh>
+
+#include <mln/morpho/elementary/gradient.hh>
+
+
+
+///////////////////
+//               //
+// Main Function //
+//               //
+///////////////////
+
+
+int main(int argc, char *argv[])
+{
+  using namespace mln;
+  using value::int_u8;
+  using value::int_u12;
+
+  if (argc != 3)
+  {
+    std::cout << "Usage: " << argv[0] << " <ima.dcm> <dimensions>"
+	      << std::endl;
+    return 1;
+  }
+
+  unsigned dim = atoi(argv[2]);
+  if (dim != 2 && dim != 3)
+  {
+    std::cout << "<dimensions> invalid" << std::endl;
+    return 1;
+  }
+
+  if (dim == 2)
+  {
+    image2d<int_u12> dcm2;
+    io::dicom::load(dcm2, argv[1]);
+    image2d<int_u12> grad2 = morpho::elementary::gradient(dcm2, c4());
+    io::dump::save(grad2, "grad.dump");
+  }
+  else
+  {
+    image3d<int_u12> dcm3;
+    io::dicom::load(dcm3, argv[1]);
+    image3d<int_u12> grad3 = morpho::elementary::gradient(dcm3, c6());
+    io::dump::save(grad3, "grad.dump");
+  }
+
+  return 0;
+}
Index: trunk/milena/sandbox/fabien/igr/Makefile
===================================================================
--- trunk/milena/sandbox/fabien/igr/Makefile	(revision 3516)
+++ trunk/milena/sandbox/fabien/igr/Makefile	(revision 3517)
@@ -1,32 +1,46 @@
-DICOM_INC = -I/Users/HiSoKa/Downloads/gdcm-2.0.10/Source/Common/ \
-	    -I/Users/HiSoKa/Downloads/gdcmbin/Source/Common/ \
-	    -I/Users/HiSoKa/Downloads/gdcm-2.0.10/Source/DataDictionary/ \
-	    -I/Users/HiSoKa/Downloads/gdcm-2.0.10/Source/MediaStorageAndFileFormat/ \
-	    -I/Users/HiSoKa/Downloads/gdcm-2.0.10/Source/DataStructureAndEncodingDefinition/
-DICOM_LIB = -L/Users/HiSoKa/Downloads/gdcmbin/bin \
+DCM_SRC=/Users/HiSoKa/Downloads/gdcm-2.0.10
+DCM_BIN=/Users/HiSoKa/Downloads/gdcmbin
+DICOM_INC = -I${DCM_SRC}/Source/Common/ \
+	    -I${DCM_BIN}/Source/Common/ \
+	    -I${DCM_SRC}/Source/DataDictionary/ \
+	    -I${DCM_SRC}/Source/MediaStorageAndFileFormat/ \
+	    -I${DCM_SRC}/Source/DataStructureAndEncodingDefinition/
+DICOM_LIBS = -L${DCM_BIN}/bin \
 	    -lgdcmCommon -lgdcmDICT -lgdcmDSED -lgdcmIOD -lgdcmMSFF -lgdcmexpat -lgdcmjpeg12 -lgdcmjpeg16 -lgdcmjpeg8 -lgdcmopenjpeg -lgdcmuuid -lgdcmzlib \
 	    -framework CoreFoundation
 CXXFLAGS = -DNDEBUG -O1
 
-all: 2d 3d wsd2d wsd3d
+all: 2d 3d wsd2d wsd3d grad
 
 2d: seg_vol_irm.hh seg2d.cc
-	g++ -I../../../ ${DICOM_INC} ${DICOM_LIB} ${CXXFLAGS} seg2d.cc -o seg2d
+	g++ -I../../../ ${DICOM_INC} ${DICOM_LIBS} ${CXXFLAGS} seg2d.cc -o seg2d
 
 3d: seg_vol_irm.hh seg3d.cc
-	g++ -I../../../ ${DICOM_INC} ${DICOM_LIB} ${CXXFLAGS} seg3d.cc -o seg3d
+	g++ -I../../../ ${DICOM_INC} ${DICOM_LIBS} ${CXXFLAGS} seg3d.cc -o seg3d
 
 wsd2d: watershed.hh watershed2d.cc
-	g++ -I../../../ ${DICOM_INC} ${DICOM_LIB} ${CXXFLAGS} $^ -o wsd2d
+	g++ -I../../../ ${DICOM_INC} ${DICOM_LIBS} ${CXXFLAGS} $^ -o wsd2d
 
 wsd3d: watershed.hh watershed3d.cc
-	g++ -I../../../ ${DICOM_INC} ${DICOM_LIB} ${CXXFLAGS} $^ -o wsd3d
+	g++ -I../../../ ${DICOM_INC} ${DICOM_LIBS} ${CXXFLAGS} $^ -o wsd3d
 
 wsd3dg: watershed.hh watershed3d.cc
-	g++ -I../../../ ${DICOM_INC} ${DICOM_LIB} -g $^ -o wsd3dg
+	g++ -I../../../ ${DICOM_INC} ${DICOM_LIBS} -g $^ -o wsd3dg
 
 nbasins: nbasins_finder.cc
-	g++ -I../../../ ${DICOM_INC} ${DICOM_LIB} ${CXXFLAGS} $^ -o nbasins_finder
+	g++ -I../../../ ${DICOM_INC} ${DICOM_LIBS} ${CXXFLAGS} $^ -o nbasins_finder
+	
+grad: grad.cc
+	g++ -I../../../ ${DICOM_INC} ${DICOM_LIBS} ${CXXFLAGS} $^ -o grad
+	
+clo_vol: clo_vol.cc
+	g++ -I../../../ ${CXXFLAGS} $^ -o clo_vol
+
+wst: wst.cc
+	g++ -I../../../ ${CXXFLAGS} $^ -o wst
+	
+graph: graph.cc
+	g++ -I../../../ ${DICOM_INC} ${DICOM_LIBS} ${CXXFLAGS} $^ -o graph
 	
 clean:
 	rm -rf *.dump *.p?m *.plot *.log *.csv
Index: trunk/milena/sandbox/fabien/TODO
===================================================================
--- trunk/milena/sandbox/fabien/TODO	(revision 3516)
+++ trunk/milena/sandbox/fabien/TODO	(revision 3517)
@@ -26,5 +26,7 @@
 [X] Create 3D US morpho with 2D stack
 [ ] Create macro for_all_slice
 [X] Batch process watershed with 2D, 3D and any combination of parameters
-[ ] Cut into small tools
-[ ] Test 3D workflow on 2D images
+[X] Cut into small tools
+[X] Test 3D workflow on 2D images
+[ ] Create colorized colors for graph
+[ ] Diff with %
Index: trunk/milena/sandbox/fabien/bin/dumpl32_to_colorize.cc
===================================================================
--- trunk/milena/sandbox/fabien/bin/dumpl32_to_colorize.cc	(revision 0)
+++ trunk/milena/sandbox/fabien/bin/dumpl32_to_colorize.cc	(revision 3517)
@@ -0,0 +1,61 @@
+#include <mln/core/image/image2d.hh>
+#include <mln/make/image3d.hh>
+#include <mln/debug/slices_2d.hh>
+#include <mln/debug/colorize.hh>
+
+#include <mln/value/int_u8.hh>
+#include <mln/value/int_u12.hh>
+#include <mln/value/label_32.hh>
+#include <mln/value/rgb8.hh>
+#include <mln/core/concept/literal.hh>
+
+#include <mln/io/dump/load.hh>
+#include <mln/io/ppm/save.hh>
+
+
+int usage(char* argv[])
+{
+  std::cerr << "usage: " << argv[0] << " input.dump dim nbasins output.ppm" << std::endl;
+  return 1;
+}
+
+
+
+int main(int argc, char* argv[])
+{
+  using namespace mln;
+  using value::int_u8;
+  using value::int_u12;
+  using value::label_32;
+  using value::rgb8;
+
+  if (argc != 5)
+    return usage(argv);
+
+  unsigned dim = atoi(argv[2]);
+  unsigned nbasins = atoi(argv[3]);
+  if (dim != 2 && dim != 3)
+  {
+    std::cout << "<dimensions> invalid" << std::endl;
+    return 1;
+  }
+
+  if (dim == 2)
+  {
+    image2d<label_32> ima2d;
+    io::dump::load(ima2d, argv[1]);
+    image2d<rgb8> ima_rgb = debug::colorize(rgb8(), ima2d, nbasins);
+    io::ppm::save(ima_rgb, argv[4]);
+  }
+  else
+  {
+    image3d<label_32> ima3d;
+    io::dump::load(ima3d, argv[1]);
+    image3d<rgb8> ima_rgb = debug::colorize(rgb8(), ima3d, nbasins);
+
+    image2d<rgb8> ima_result = debug::slices_2d(ima_rgb, 1.f, literal::black);
+    io::ppm::save(ima_result, argv[4]);
+  }
+
+  return 0;
+}
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                        	* Makefile.am: add new rule "tools".
	* doc/examples/Makefile.am,
	* doc/Makefile.am: rename rule data to examples.
	* doc/ref_guide/ref_guide.tex: remove useless chapters.
	* doc/tutorial/tutorial.tex: write two new chapters.
---
 milena/ChangeLog                   |   13 +
 milena/Makefile.am                 |   15 +-
 milena/doc/Makefile.am             |   12 +-
 milena/doc/examples/Makefile.am    |    2 +-
 milena/doc/ref_guide/ref_guide.tex |   18 +-
 milena/doc/tutorial/tutorial.tex   |  718 ++++++++++++++++++++++++++++++++++--
 6 files changed, 728 insertions(+), 50 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 8f4a879..db4cab5 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,16 @@
+2009-03-12  Guillaume Lazzara  <lazzara(a)lrde.epita.fr>
+
+	Improve tutorial and documentation.
+
+	* Makefile.am: add new rule "tools".
+
+	* doc/examples/Makefile.am,
+	* doc/Makefile.am: rename rule data to examples.
+
+	* doc/ref_guide/ref_guide.tex: remove useless chapters.
+
+	* doc/tutorial/tutorial.tex: write two new chapters.
+
 2009-03-11  Thierry Geraud  <thierry.geraud(a)lrde.epita.fr>
 
 	Fix missing update in labeling extrema.
diff --git a/milena/Makefile.am b/milena/Makefile.am
index 593fbf9..b394cf2 100644
--- a/milena/Makefile.am
+++ b/milena/Makefile.am
@@ -4,17 +4,20 @@
 SUBDIRS = 	\
   doc 		\
   mesh 	 	\
-  tests		\
-  tools
+  tests
 #  apps
 
-.PHONY: doc tutorial
+.PHONY: doc tutorial tools
+
 doc:
 	$(MAKE) -C doc doc
 
 tutorial:
 	$(MAKE) -C doc tutorial
 
+tools:
+	$(MAKE) -C tools all
+
 .PHONY: regen-dist
 regen-dist: $(srcdir)/headers.mk
 # FIXME: Change generate_dist_headers.sh so that the action looks like this:
@@ -54,4 +57,8 @@ img/tiny.ppm 		\
 img/toto.pbm
 
 EXTRA_DIST += 		\
-generate_dist_headers.sh
+generate_dist_headers.sh\
+tools 			\
+tools/area_flooding.cc 	\
+tools/seed2tiling.cc
+
diff --git a/milena/doc/Makefile.am b/milena/doc/Makefile.am
index ad25545..14da88f 100644
--- a/milena/doc/Makefile.am
+++ b/milena/doc/Makefile.am
@@ -6,9 +6,9 @@ SUBDIRS = tutorial white_paper
 
 DOXYGEN = doxygen
 
-.PHONY: doc user-doc complete-doc html-complete html-user tutorial white-paper regen-dist
+.PHONY: doc user-doc complete-doc html-complete html-user tutorial white-paper regen-dist examples
 
-doc: user-doc
+doc: user-doc tutorial white_paper ref-guide
 
 complete-doc: html-complete
 
@@ -20,10 +20,10 @@ html-complete: Doxyfile tuto-html ref-guide-html
 html-user: Doxyfile tuto-html ref-guide-html
 	$(DOXYGEN) Doxyfile_user
 
-tuto-html: data fig-convert
+tuto-html: examples fig-convert
 	$(MAKE) -C tutorial tuto-html
 
-tutorial: data fig-convert
+tutorial: examples fig-convert
 	$(MAKE) -C tutorial tutorial
 
 white-paper:
@@ -36,8 +36,8 @@ ref-guide-html:
 	$(MAKE) -C ref_guide ref-guide-html
 
 
-data:
-	make -C examples data
+examples:
+	make -C examples examples
 
 fix-refdata:
 	make -C examples fix-refdata
diff --git a/milena/doc/examples/Makefile.am b/milena/doc/examples/Makefile.am
index 74f68f1..c343312 100644
--- a/milena/doc/examples/Makefile.am
+++ b/milena/doc/examples/Makefile.am
@@ -108,7 +108,7 @@ run-samples: all
 	done
 
 
-data: run-samples diff-data split-samples split-outputs 
+examples: run-samples diff-data split-samples split-outputs 
 
 
 diff-data:
diff --git a/milena/doc/ref_guide/ref_guide.tex b/milena/doc/ref_guide/ref_guide.tex
index 4df8efa..28bc543 100644
--- a/milena/doc/ref_guide/ref_guide.tex
+++ b/milena/doc/ref_guide/ref_guide.tex
@@ -1119,9 +1119,9 @@ Voir les vset => attendre que ca soit ameliore?
 \clearpage
 \newpage
 %Ugly workaround to avoid missing chapter references in doxygen.
-\begin{htmlonly}
-\doxychapter{1}{}
-\end{htmlonly}
+%\begin{htmlonly}
+%\doxychapter{1}{}
+%\end{htmlonly}
 \doxychapter{winneigh}{Structural elements: Window and neighborhood}
 
 In Olena, there are both the window and neighborhood concept. A window can be
@@ -1923,9 +1923,9 @@ site set.
 \newpage
 \clearpage
 %Ugly workaround to avoid missing chapter references in doxygen.
-\begin{htmlonly}
-\doxychapter{2}{}
-\end{htmlonly}
+%\begin{htmlonly}
+%\doxychapter{2}{}
+%\end{htmlonly}
 \doxychapter{graphandima}{Graphes and images}
 
 FIXME: REWRITE
@@ -2186,9 +2186,9 @@ mln\_edge\_nbh\_edge\_iter(G)	  & G : graph type & Iterator on the edges adjacen
 \newpage
 \clearpage
 %Ugly workaround to avoid missing chapter references in doxygen.
-\begin{htmlonly}
-\doxychapter{2}{}
-\end{htmlonly}
+%\begin{htmlonly}
+%\doxychapter{2}{}
+%\end{htmlonly}
 \doxychapter{debugtools}{Debugging tools}
 
 FIXME write it
diff --git a/milena/doc/tutorial/tutorial.tex b/milena/doc/tutorial/tutorial.tex
index 87949d9..903ac14 100644
--- a/milena/doc/tutorial/tutorial.tex
+++ b/milena/doc/tutorial/tutorial.tex
@@ -305,6 +305,15 @@ $$
 \end{latexonly}
 }
 
+\newcommand{\path}[1]{
+\textit{#1}
+}
+
+\newcommand{\dir}[1]{
+\textbf{\textit{#1}}
+}
+
+
 \begin{document}
 
 % Doxygen use only - Generate the left menu.
@@ -344,21 +353,684 @@ A copy of the license is provided in the file COPYING.DOC.
 
 %\begin{htmlonly}
 %====================================
-\doxychapter{tuto0}{Step 0: Foreword}
+\doxychapter{tuto1}{Welcome}
 
-- image2d
-- typical use case
+Welcome to Milena's tutorial.
 
-\begin{htmlonly}
-  \begin{center}%
-    \hspace{1cm} Go to \doxyref{tuto1}~ \longrightarrow%
-  \end{center}%
-\end{htmlonly}
 
 
 
+
+%**************************
+\doxysection{tuto1howotlearn}{How to learn Milena}
+
+Milena is only a subpart of Olena but tends to be a large system too.
+Therefore it is not possible to present all the functionalities in a
+tutorial. 
+
+
+Milena targets several audiences: \textit{end users}, \textit{designers} and
+\textit{providers}. \textit{End users} want to apply and assemble algorithms
+to solve image processing, pattern recognition or computer vision problems,
+\textit{designers} build new algorithms and \textit{providers} are interested
+in developping their own data structures and extend an existing library.
+
+
+Whatever the kind of user you are, the key to learning how to use Milena is to
+become familiar with its palette of objects and the way of combining them.
+
+As an \textit{end user}, you may start with this simple tutorial and the Quick
+tour (FIXME: ref). They describe and illustrate the key features of the library.
+\textit{End users} getting familiar with Milena and \textit{designers}, should
+take a look at the  Quick Reference Guide (FIXME: ref!).
+It is a more detailed explanations of the library's features.
+
+\textit{end users} and \textit{designers} may be also interested by all the
+examples provided with the documentation and the tutorial. The source code is
+available in \path{milena/doc/examples} (FIXME: ref) and is usually pointed
+out and commented by the documentation.
+
+Taking a look at the test suite is also a good idea. The tests usually focus on
+a single functionality and handle several use cases which may overlap your needs.
+The test suite is located at \path{milena/tests} (FIXME: ref?).
+
+Still not enough information? More information about all the functions is
+available in the User HTML documentation (FIXME:ref).
+It mainly targets \textit{designers} and \texit{providers}.
+The latter may also be interested by the Developer HTML documentation
+(FIXME:ref).
+
+
+
+%**************************
+\doxysection{tuto1obtainingthelib}{Obtaining the library}
+
+There are two ways of getting Milena on the web:
+\begin{itemize}
+  \item Download a tarball/package from the website,
+  \item Checkout the SVN repository.
+\end{itemize}
+
+Downloading a package or a tarball is the best choice for a new user. Except
+for nightly builds which are packages generated every night from the SVN repository, 
+packages and tarballs contain only a released version of Milena. It guaranties a 
+certain quality: no building issues, no bugs (ok, maybe some...), \ldots
+
+This tutorial is based on the latest released version of Milena. Therefore,
+if you decide to use the SVN version, you may notice different behaviors or results
+compared to what it is described in this document. 
+
+Using the SVN version implies some drawbacks: the code might crash, not
+compile or produce incorrect results.
+Besides, The SVN version is always up to date and you may find new functionalities,
+bug fixes and new syntax improvements.
+This version targets users familiar with build systems and compilation issues.
+We strongly advise you to not use it for production use.
+
+
+
+%**************************
+\doxysection{tuto1downloading}{Downloading the library}
+
+
+
+%download page.
+
+%--------------------------
+\subdoxysection{tuto1downloadingsvn}{Downloading from SVN}
+
+First, be sure that SVN is already installed on your system.
+Open a terminal and type:
+
+\begin{verbatim}
+\$ svn --version --quiet
+1.4.6
+\end{verbatim}
+
+You should see your version of SVN installed. If you read 'Command not found'
+then you need to install SVN.
+
+Usually, systems providing packages reference SVN's package as 'subversion'.
+
+Once you have SVN installed, go to the directory where you woudl like to 
+download Olena and create a new directory.
+
+\begin{verbatim}
+\$ cd $HOME
+\$ mkdir olena
+\$ cd olena
+\end{verbatim}
+     
+Then 'checkout' (download) the repository with the following command.
+
+\begin{verbatim}
+\$ svn co https://svn.lrde.epita.fr/svn/oln/trunk
+\end{verbatim}
+
+Enter the 'trunk' directory.
+
+\begin{verbatim}
+\$ cd trunk
+\end{verbatim}
+
+You are now ready to configure the directory and install Milena as described 
+in section \ref{tuto2}.
+We invite you to take a look at the description of the directory structure
+(\ref{tuto1dirstruct}.
+If you encounter any issues in the installation process or if you have any
+question, do not forget to join the mailing lists (\ref{tuto1mailinglists}
+and/or use the other documentations ressources (\ref{tuto1ressources}).
+
+
+
+
+
+%--------------------------
+\subdoxysection{tuto1downloadingpackages}{Downloading packaged releases}
+
+%details.
+
+Milena's packages can be downloaded from:
+
+\begin{centerize}
+\begin{verbatim}
+http://www.lrde.epita.fr/Olena/Download
+\end{verbatim}
+\end{centerize}
+
+On this page you will find the latest and past releases.
+Currently, we provide only '.tar.gz' and 'tar.bz2' archives.
+
+Once download, you just need to uncompress the archive.
+
+For the '.tar.gz' archive:
+\begin{verbatim}
+$ tar zxvf olena-1.0.tar.gz
+\end{verbatim}
+
+For the '.tar.bz2' archive:
+\begin{verbatim}
+$ tar jxvf olena-1.0.tar.bz2
+\end{verbatim}
+
+Then, enter the new created directory:
+\begin{verbatim}
+$ cd olena-1.0
+\end{verbatim}
+
+
+You are now ready to configure the directory and install Milena as described 
+in section \ref{tuto2}.
+We invite you to take a look at the description of the directory structure
+(\ref{tuto1dirstruct}.
+If you encounter any issues in the installation process or if you have any
+question, do not forget to join the mailing lists (\ref{tuto1mailinglists}
+and/or use the other documentations ressources (\ref{tuto1ressources}).
+
+
+
+%**************************
+\doxysection{tuto1mailinglists}{Join the mailing lists}
+
+Regardless your use of Olena, we strongly advise you to join our mailing lists.
+This is the best way to keep up to date about new releases, bug
+notifications/fixes and future updates.
+This is also a good opportunity to tell us what you would like to find in
+Milena and what could be improved.
+
+Currently four mailing-lists are available:
+
+\begin{tabular}{l l}
+\textbf{Olena}		& Discussion about the project Olena  \\ 
+\textbf{Olena-bugs}	& Bugs from Olena projects	      \\
+\textbf{Olena-core}	& Internal list for the Olena project \\
+\textbf{Olena-patches}	& patches for the Olena project	      \\
+\end{tabular}
+
+You can subscribe to these mailing lists at the following adress:
+
+\begin{center}
+\begin{verbatim}
+https://www.lrde.epita.fr/mailman/listinfo/
+\end{verbatim}
+\end{center}
+
+Just click on the name of the mailing list you want to subscribe to and fill
+out the form.
+
+
+
+%**************************
+\doxysection{tuto1dirstruct}{Directory structure}
+
+Milena's directory is composed of several subdirectories. In order to help
+you finding what you need, you will find a description of all these
+subdirectories.
+
+
+List of \path{milena}'s subdirectories:
+\begin{itemize}
+
+\dir{apps} --- A full example of a 3D mesh visualization tool. It
+  uses milena.
+
+\dir{doc} --- THE directory you must know. Contains all the 
+  documentation material.
+
+\dir{img} --- A set of common test images. They are used in the
+  test suite. Feel free to use it in your programs.
+
+\dir{mesh} --- A set of 3D meshes. They can be used with the full
+  example located in \path{milena/apps}.
+
+\dir{mln} --- The core of the libray. Contains all the library headers.
+
+\dir{tests} --- The test suite. Is it subdivided in sub directories.
+  The directory hierarchy respects \path{milena/mln}'s. 
+
+\dir{tools} --- Small tools written with milena. They can be used as examples.
+
+\end{itemize}
+
+
+
+List of \path{mln}'s subdirectories:
+\begin{itemize}
+  \item \dir{accu} --- Set of Accumulators.
+  \item \dir{algebra} --- Algebraic structures like vectors or matrices.
+  \item \dir{arith} --- Arithmetical operators.
+  \item \dir{binarization} --- Routines to binarize an image.
+  \item \dir{border} --- Image border related routines.
+  \item \dir{canvas} --- Generic canvas. They define generic ways of browsing
+  an image, compute data, \dots.
+  \item \dir{convert} --- Automatic conversion mechanism.
+  \item \dir{core} --- Core of the library. Here you can find the image types,
+  the site set types and basic concepts.
+  \item \dir{data} --- Routine that modify image data.
+  \item \dir{debug} --- Debug related routines.
+  \item \dir{display} --- Display images on the screen.
+  \item \dir{draw} --- Draw geometric objects in an image.
+  \item \dir{essential} --- Set of essential headers for 1,2,3-D manipulations.
+  \item \dir{estim} --- Compute data on image values.
+  \item \dir{extension} --- Image extension manipulation.
+  \item \dir{extract} --- FIXME: extract will be removed and replaced by thru().
+  \item \dir{fun} --- Set of functions applying on sites, values, \ldots
+  \item \dir{geom} --- Functions related to image geometry.
+  \item \dir{graph} --- Graph related routines.
+  \item \dir{histo} --- Histogram related functions.
+  \item \dir{io} --- I/O related routines.
+  \item \dir{labeling} --- Labeling related routines.
+  \item \dir{level} --- Point-wise operators on levels.
+  \item \dir{linear} --- Linear operators.
+  \item \dir{literal} --- Generic image values such as zero, black, white \ldots
+  \item \dir{logical} --- Logical operators.
+  \item \dir{make} --- Small routines to construct images, windows, \ldots
+  \item \dir{math} --- Mathematical functions.
+  \item \dir{metal} --- Metalic macros/structures. Static library helping
+  developing doing static tests.
+  \item \dir{morpho} --- Mathematical morphology.
+  \item \dir{norm} --- Norm computation
+  \item \dir{opt} --- Optional routines. Routines which may work on a
+  specific image type only.
+  \item \dir{pw} --- Point-wise image related routines.
+  \item \dir{registration} -- Registration related routine.
+  \item \dir{set} --- Set related routines.
+  \item \dir{subsampling} --- Subsampling related algorithms.
+  \item \dir{tag} --- Tag traits.
+  \item \dir{test} --- Definition of predicates.
+  \item \dir{topo} --- Complex related structures.
+  \item \dir{trace} --- Debug trace mechanism.
+  \item \dir{trait} --- Internal traits mechanism.
+  \item \dir{transform} --- Algorithms based on the level::transform.
+  \item \dir{util} --- Various utilitarian classes.
+  \item \dir{value} --- Set of value types which can be used in an image.
+  \item \dir{win} --- Set of various window kinds.
+\end{itemize}}
+
+
+The source code and the material of the documentation is available in \path{
+milena/doc}.
+List of \path{doc}'s subdirectories:
+\begin{itemize}
+\item \dir{examples} --- All the source code of the documentation examples.
+\item \dir{benchmark} --- Some benchmarks.
+\item \dir{tools} --- Small tools used for generating documentation /
+  building examples.
+
+\item \dir{tutorial} --- Tutorial sources.
+\item \dir{white\_paper} --- White paper sources.
+\item \dir{technical} --- Technical documentation. (DEPRECATED)
+\item \dir{ref\_guide} --- Reference guide sources.
+\item \dir{figures} --- Reference figures for documentation generation.
+\item \dir{outputs} --- Reference outputs for documentation examples.
+
+\end{itemize}
+
+
+
+
+%**************************
+\doxysection{tuto1ressources}{Documentation}
+
+This tutorial is not the only documentation of Milena. Other documents are available:
+
+\begin{itemize}
+  \item \dir{White paper} --- a small document of few pages presenting the key
+  features of the library. It intents to give a big picture of the library.
+
+  \item \dir{Quick tour} --- it aims giving an overview of Milena's possibilities.
+  It does not only give the concepts but illustrate them with small sample
+  codes.
+
+  \item \dir{Quick reference guide} --- Present in details all the main
+  functionalities of Milena.
+  Hints and full examples are also provided. The sample codes are commented
+  and each concept in the library is detailed. This is the reference document for any 
+  \textit{end user} and \textit{algorithm designer}.
+
+  \item \dir{HTML user doc} --- The full documentation of the library. The full
+  API is described in details. Each part of the library is classified by
+  categories and the source code is directly accessible from the documentation.
+  This is the reference document for any \textit{algorithm designer} and/or 
+  \textit{provider of data structures}.
+
+  \item \dir{Header files} --- Every object or algorithm is declared in a '.hh' file.
+  The documentation is provided as comments in these file. 
+\end{itemize}
+
+
+%**************************
+\doxysection{tuto1ressources}{Community and Support}
+
+Even though Milena is currently developped by the LRDE in EPITA, we are open
+for new contributors.
+
+\begin{itemize}
+  \item If you are a user, please send us feedback about the library.
+  Did you find what you wanted? Do you miss something?
+
+  \item Please report bugs and defect in the API. Mailing lists are the best
+  way for reporting that.
+
+  \item Developers, if you write cool open source programs or algorithms with Milena,
+  send them to us. We may ship your code with Olena and/or add it to
+  our download page.
+
+  \item Educators, if you use Olena for your courses and you are ready to
+  share your materials, you can send it to us through our mailing-lists.
+
+  \item We are also interested in partnership or commercial use of Milena.
+  If you are interested, contact us directly (\ref{tuto1contacts}).
+
+\end{itemize}
+
+
+%**************************
+\doxysection{tuto1projectstatus}{Project status}
+
+If you want to stay tuned to Milena's development, the best way is probably
+the mailing-lists (\ref{tuto1mailinglists}).
+
+There are other ways to get to know what is the status of the project.
+
+\begin{itemize}
+\item Olena's trac --- \href{https://trac.lrde.org/olena} --- Here is the 
+roadmap, the current open tickets/bugs/improvements which are taken in
+consideration. A source browser is also available.
+
+\item Olena's Buildfarm --- https://buildfarm.lrde.org/buildfarm/oln/ --- The
+official buildfarm. Every night and after each commit, tests are compiled and run.
+The buildfarm can show you whether it is safe to update your svn copy of Milena or not\ldots
+
+\item Test failures --- http://www.lrde.epita.fr/dload/olena/test-failures-daily.html
+--- Through this page, you can see exactly which tests do not compile or pass.
+This page is updated every night.
+
+
+
+%**************************
+\doxysection{tuto1ressources}{A brief history of Milena}
+
+The Olena project aims at building a scientific computation platform oriented
+towards image processing, image recognition, and artificial vision. 
+This environment is composed of a high performance generic library (Milena),
+a set of tools for shell scripts, together with, in the more distant future,
+an interpreter (a la Octave, MatLab etc.) and a visual programming environment. 
+
+The Olena project started in 2000 from a small prototype on 2-D images.
+From November 2001 to April 2004, this prototype evolved from version 0.1 to 0.10.
+More image types were supported and the level of genericity expected from the
+library was partially obtained. During these three years, the prototype was used
+to experiment with genericity and to try to meet our objectives.
+In February 2007, Olena 0.11 was released to conform modern C++ compilers.
+At that time, the code was not enough readable though and the compilation time
+was too long.
+
+Since June 2007 up to now, The library of the Olena platform is called Milena
+and the library has been rewritten. The programming  paradigm has been
+simplified: the code is more readable and the compilation time is acceptable.
+The level of genericity still meets our objectives though. 
+
+Milena is now getting ready for being considered as stable and distributable.
+The core of the library is getting frozen and we aim at enriching the library,
+its documentation and the related tools.
+
+
+%**************************
+\doxysection{tuto1contacts}{Contacts}
+
+If you want to reach us directly, you can contact one of the following people:
+
+\begin{itemize}
+  \item Thierry Geraud - Project Manager - thierry.geraud(a)lrde.epita.fr
+\end{itemize}
+
+
+
+
+
+
+%\begin{htmlonly}
 %====================================
-\doxychapter{tuto1}{Step 1: Load and save images}
+\doxychapter{tuto2}{Installation}
+
+%pre-requis/compatibility
+This section describes the installation process of Milena.
+Do not forget that Milena is a library, not a program. Therefore, no program
+will be installed. 
+
+Milena's examples and tests are compiled on the following platforms:
+\begin{itemize}
+  \item Apple Tiger Darwin 8, PowerPC, GCC 4.0.1
+  \item Apple Leopard Darwin 10.5, X86-64, GCC 4.0.1, 4.2
+  \item Linux, i486, GCC 3.3, 4.1, 4.2, 4.3
+  \item Linux, x86-64, GCC 4.1
+\end{itemize}
+
+We guaranty that Milena compiles on these platforms, e.g. Linux and Unix
+platforms. It may compiles on other platforms though but we have not tested.
+If you did, and you succeeded, please let us know in order to update this
+section.
+
+Milena is known NOT to work with GCC-2.95.
+
+
+Milena is actively developed under Unix systems. As a result, the build system
+is based on the Autotools.
+Autotools make sure that every dependencies are resolved before compiling
+or installing a program.
+
+Milena is different from usual libraries in a way that nothing needs to be
+compiled to use it. The library itself is composed of headers which must be
+included when you need them.
+Then, your application will be compiled with the parts of the library used in
+that program. That's all.
+
+So, why do we have a build system? It is useful for installing the library on
+your system, generating the doc and compiling the test suite and the examples.
+
+
+
+%**************************
+\doxysection{tuto2bootstrap}{Bootstrap (SVN Sources)}
+
+If you got the sources from a package/tarball, you can skip this section. Go
+to section \ref{tuto2configure}.
+
+If you downloaded the sources from the SVN repository, you must launch a
+script before configuring the build directory. 
+
+Run the following:
+\begin{verbatim}
+$ cd /my/path/to/olena-1.0
+$ ./bootstrap
+\end{verbatim}
+
+Running 'bootstrap' can take a while. Some files are generated during this
+process.
+When it's done, you are ready to configure the build directory.
+
+
+
+%**************************
+\doxysection{tuto2configure}{Configure}
+
+First, make sure you are at the root directory of the milena source:
+
+\begin{verbatim}
+$ cd /my/path/to/olena-1.0
+\end{verbatim}
+
+First, create and enter a build directory:
+\begin{verbatim}
+$ mkdir build
+$ cd build
+\end{verbatim}
+
+We are now about to configure the build directory. This process will create
+the necessary files to compile documentation, examples and tools and prepare the
+installation.
+
+\textbf{Important Note}: the Install path prefix must be chosen at this step.
+By default, Milena will be installed in /usr/local but you may like to install
+it elsewhere. To do so, pass the option \textit{--prefix=/installation/path/prefix}
+to the configure script (see below). Replace '/installation/path/prefix' with the
+wanted installation path prefix.
+  
+now, you can run:
+\begin{verbatim}
+$ ../configure
+\end{verbatim}
+OR
+\begin{verbatim}
+$ ../configure --prefix=/installation/path/prefix
+\end{verbatim}
+
+The configure script will perform various tests. If there is no dependency
+issues, the last lines shown before the prompt are:
+
+\begin{verbatim}
+config.status: creating config.h
+config.status: executing depfiles commands
+$
+\end{verbatim}
+
+The build directory is now configured, the library can be installed.
+
+
+
+%**************************
+\doxysection{tuto2install}{Install}
+
+First, be sure to be in the build directory. If you followed the previous
+steps, the build directory should be in the Milena sources root directory. 
+
+\begin{verbatim}
+$ cd /my/path/to/olena-1.0/build
+\end{verbatim}
+
+If you did not change the default install path prefix, set to 
+\path{/usr/local}, you will need to have administrator privileges to
+perform the installation. Then, you may type:
+\begin{verbatim}
+$ sudo make install
+\end{verbatim}
+
+Otherwise, if you set the install path prefix to a directory own by your
+user, simply type:
+\begin{verbatim}
+$ make install
+\end{verbatim}
+
+When the installation is finished, you are done. Milena is installed on your
+system. But maybe you would like to build the examples? This is described
+in the next section \ref{tuto2optionalcomp}.
+
+A description of the installation content is also available in section
+\ref{tuto2installcontent}.
+
+
+
+%**************************
+\doxysection{tuto2optionalcomp}{Optional compilation}
+
+The library itself does not need to be compiled, therefore installing
+Milena does not require compilation.
+
+Though, some examples and tools are provided with the library and must be 
+compiled if you want to use them.
+
+\doxysubsection{tuto2examples}{Examples}
+
+Examples are part of the documentation. The sources are located in
+\path{milena/doc/examples}. 
+
+To compile the examples simply run:
+\begin{verbatim}
+$ cd /my/path/to/olena-1.0/build/milena/doc/examples
+$ make
+\end{verbatim}
+
+These examples can produce outputs and images. May be you would like
+to run all the examples and take a look at the outputs? To do so, run:
+\begin{verbatim}
+$ cd /my/path/to/olena-1.0/build/milena/doc/examples
+$ make examples
+\end{verbatim}
+
+Text and image outputs will be respectively stored in
+\path{build/milena/doc/outputs} and \path{build/milena/doc/figures}.
+
+
+
+\doxysubsection{tuto2examples}{Tools}
+
+Few tools are provided with Milena. They can be considered as full program
+examples.
+
+Currently two tools are available:
+\begin{tabular}{l l}
+area\_flooding.cc & FIXME:description \\
+\hline
+seed2tiling.cc & FIXME:description \\
+\end{itemize}
+
+To build these tools, run:
+\begin{verbatim}
+$ cd /my/path/to/olena-1.0/build/milena/tools
+$ make
+\end{verbatim}
+
+
+\doxysubsection{tuto2examples}{Tests}
+
+The test suite used for Milena's development is shipped with the library.
+
+In order to build and run it, just do the following:
+\begin{verbatim}
+$ cd /my/path/to/olena-1.0/build/milena/tests
+$ make check
+\end{verbatim}
+
+Running the test suite is memory and CPU consumming and will take a while.
+
+
+%**************************
+\doxysection{tuto2installcontent}{Installation content}
+
+Once installed, Milena's files are located in the installed path prefix
+you passed to the configure script or in the default path /usr/local.
+
+In the installed path prefix, Milena's files are located in:
+
+\begin{itemize}
+  \item include/mln/ --- The library. All the headers are located here.
+  \item share/olena/images --- Mesh sample files which may be used with
+  example programs.
+\end{itemize}
+
+
+
+%\begin{htmlonly}
+%====================================
+\doxychapter{tuto3}{Getting started with Milena}
+
+** intent
+
+A very simple processing chain; the target is the end-user!
+
+OR (?)
+this chain plus a sample tiny generic algorithm
+
+** misc
+/!\ step by step...
+compilation time w.r.t compilation options (O1, DNDEBUG).
+
+
+
+
+%====================================
+\doxychapter{tuto4}{Step 4: Load and save images}
 
 After this step you shoud know how to:
 \begin{itemize}
@@ -392,12 +1064,12 @@ The supported file formats and their associated image value types are listed
 in section \doxyref{imaio}.
 
 \vspace{2cm}
-\tutotoc{tuto0}{tuto2}
+\tutotoc{tuto3}{tuto5}
 
 
 
 %====================================
-\doxychapter{tuto2}{Step 2: Create your first image}
+\doxychapter{tuto5}{Step 5: Create your first image}
 
 After this step you should know how to:
   \begin{itemize}
@@ -440,12 +1112,12 @@ though. A more detailed description can be found in section
 
 \vspace{2cm}
 \begin{center}
-  \tutotoc{tuto1}{tuto3}
+  \tutotoc{tuto4}{tuto6}
 \end{center}
 
 
 %====================================
-\doxychapter{tuto3}{Step 3: Read and write images}
+\doxychapter{tuto6}{Step 6: Read and write images}
 
 After this step you should know how to:
   \begin{itemize}
@@ -495,12 +1167,12 @@ the reference guide.
 
 \vspace{2cm}
 \begin{center}
-  \tutotoc{tuto2}{tuto4}
+  \tutotoc{tuto5}{tuto7}
 \end{center}
 
 
 %====================================
-\doxychapter{tuto4}{Step 4: Regions of interest}
+\doxychapter{tuto7}{Step 7: Regions of interest}
 
 After this step you should know how to:
   \begin{itemize}
@@ -711,23 +1383,9 @@ value in \var{label} is equal to 16'.
 
 \vspace{2cm}
 \begin{center}
-  \tutotoc{tuto3}{tuto5}
+  \tutotoc{tuto6}{tuto8}
 \end{center}
 
-%====================================%
-%%Ugly workaround to avoid missing chapter references in doxygen.
-%\begin{htmlonly}
-%  \doxychapter{1}{}
-%  \doxychapter{tuto5}{Step 5: Conversion between image values}
-%\end{htmlonly}
-
-
-%====================================
-\doxychapter{tuto6}{Step 6: Using structural elements with algorithms}
-
-
-%====================================
-\doxychapter{tuto7}{Step 7: Handle graphes with an image}
 
 %\end{htmlonly}
 
-- 
1.5.6.5
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0