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
 
July 2007
- 6 participants
 - 59 discussions
 
                    
                        https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from  Thierry Geraud  <thierry.geraud(a)lrde.epita.fr>
	Clean-up and update pixel related material.
	* tests/README: New.
	* mln/core/trait: New.
	* mln/core/trait/pixter.hh: New.
	* mln/core/internal/pixel_impl.hh: New.
	* mln/core/internal/fixme.hh: New.
	* mln/core/concept/fast_image.hh: New.
	* mln/core/concept/doc/fast_iterator.hh: Rename as...
	* mln/core/concept/doc/pixel_iterator.hh: ...this new file.
	Update.
	* mln/core/concept/doc/fast_image.hh: New.
	* mln/core/concept/doc/genpixel.hh: New.
	* mln/core/tags.hh: New.
	* mln/metal: New.
	* mln/metal/none.hh: New.
	* mln/core/internal/lineary_pixel_iterator_base.hh: Remove.
	* mln/core/dpoints_piter.hh,
	* mln/core/box_piter.hh,
	* mln/core/internal/image_base.hh,
	* mln/core/internal/piter_adaptor.hh,
	* mln/core/concept/genpoint.hh,
	* mln/core/concept/psite.hh,
	* mln/core/concept/point.hh,
	* mln/core/concept/doc/genpoint.hh (pointer): Rename as...
	(pointer_): ...this.
	* tests/window2d.cc: Cosmetic change.
	* TODO: Update.
	* mln/core/macros.hh (mln_ima): Remove.
	(*ixter): Update.
	(mln_piter, mln_qiter, mln_niter): Update.
	* mln/core/psubset.hh (bkd_piter): Use fixme.
	(npoints): Update.
	* mln/core/box.hh (piter): Remove.
	* mln/core/rectangle2d.hh (bkd_piter): Use fixme.
	* mln/core/pixter2d_b.hh: Clean-up and update.
	* mln/core/window.hh (bkd_piter): Use fixme.
	* mln/core/dpoints_pixter.hh: Clean-up and update.
	* mln/core/internal/pixel_iterator_base.hh: Clean-up and update.
	* mln/core/internal/box_impl.hh: Touch doc.
	* mln/core/internal/image_base.hh (dpoint, coord): New.
	(pointer): Update.
	* mln/core/pixel.hh: Clean-up and update.
	* mln/core/hline2d.hh (bkd_piter): Use fixme.
	* mln/core/concept/image.hh (piter): Remove.
	(dpoint, coord): New.
	* mln/core/concept/pixel_iterator.hh: Update.
	* mln/core/concept/point_set.hh (piter): Remove.
	* mln/core/concept/object.hh: New include.
	* mln/core/concept/doc/image.hh: Update.
	* mln/core/concept/doc/point_set.hh: Update.
	* mln/core/concept/genpixel.hh: Clean-up and update.
	* mln/core/vline2d.hh (bkd_piter): Use fixme.
	* mln/core/image2d_b.hh: Clean-up and update.
	(buffer): New.
	(offset, point_at_offset): Fix.
	* mln/level/fast_median.hh: Update.
	* mln/level/median.hh: Prefer mln_coord to int.
	* mln/canvas/sbrowsing.hh: Update doc.
	* tests/fast_median.cc,
	* tests/pixter_point2d.cc,
	* tests/pixter_dpoint2d.cc,
	* tests/pixel.cc: Update.
 TODO                                     |   55 +++++++--
 mln/canvas/sbrowsing.hh                  |   18 ++-
 mln/core/box.hh                          |    4 
 mln/core/box_piter.hh                    |    8 -
 mln/core/concept/doc/fast_image.hh       |   92 ++++++++++++++++
 mln/core/concept/doc/genpixel.hh         |   78 +++++++++++++
 mln/core/concept/doc/genpoint.hh         |    2 
 mln/core/concept/doc/image.hh            |   17 +--
 mln/core/concept/doc/pixel_iterator.hh   |   24 ++--
 mln/core/concept/doc/point_set.hh        |    4 
 mln/core/concept/fast_image.hh           |   96 +++++++++++++++++
 mln/core/concept/genpixel.hh             |   62 +----------
 mln/core/concept/genpoint.hh             |    7 -
 mln/core/concept/image.hh                |    8 +
 mln/core/concept/object.hh               |    1 
 mln/core/concept/pixel_iterator.hh       |   32 ++---
 mln/core/concept/point.hh                |    4 
 mln/core/concept/point_set.hh            |    4 
 mln/core/concept/psite.hh                |    2 
 mln/core/dpoints_piter.hh                |    8 -
 mln/core/dpoints_pixter.hh               |  104 +++++++++++-------
 mln/core/hline2d.hh                      |    2 
 mln/core/image2d_b.hh                    |  128 +++++++++++++++++-----
 mln/core/internal/box_impl.hh            |    2 
 mln/core/internal/fixme.hh               |   55 +++++++++
 mln/core/internal/image_base.hh          |   10 +
 mln/core/internal/piter_adaptor.hh       |    6 -
 mln/core/internal/pixel_impl.hh          |  174 ++++++++++++++++++-------------
 mln/core/internal/pixel_iterator_base.hh |  135 ++++++------------------
 mln/core/macros.hh                       |   50 +++++---
 mln/core/pixel.hh                        |  104 +++++-------------
 mln/core/pixter2d_b.hh                   |   75 ++++++-------
 mln/core/psubset.hh                      |    7 -
 mln/core/rectangle2d.hh                  |    2 
 mln/core/tags.hh                         |   50 ++++++++
 mln/core/trait/pixter.hh                 |  111 +++++++++++++++++++
 mln/core/vline2d.hh                      |    2 
 mln/core/window.hh                       |    2 
 mln/level/fast_median.hh                 |   19 +--
 mln/level/median.hh                      |   11 +
 mln/metal/none.hh                        |   57 ++++++++++
 tests/README                             |    1 
 tests/fast_median.cc                     |    4 
 tests/pixel.cc                           |    7 -
 tests/pixter_dpoint2d.cc                 |   84 ++++++++++----
 tests/pixter_point2d.cc                  |   28 ++--
 tests/window2d.cc                        |    3 
 47 files changed, 1177 insertions(+), 582 deletions(-)
Index: tests/window2d.cc
--- tests/window2d.cc	(revision 1024)
+++ tests/window2d.cc	(working copy)
@@ -42,12 +42,15 @@
   using namespace mln;
 
   window2d w;
+
   mln_assertion(w.is_centered() = false);
   mln_assertion(w.is_symmetric() = true);
 
   w.insert(make::dpoint2d(-1,-1));
   w.insert(make::dpoint2d( 1, 1));
+
   image2d_b<bool> ima = convert::to_image(w);
   debug::println(ima);
+
   mln_assertion(w.delta() = 1);
 }
Index: tests/README
--- tests/README	(revision 0)
+++ tests/README	(revision 0)
@@ -0,0 +1 @@
+g++-4.1 -I.. -ansi -pedantic -W -Wall -Wextra -Wconversion sample.cc
Index: tests/fast_median.cc
--- tests/fast_median.cc	(revision 1024)
+++ tests/fast_median.cc	(working copy)
@@ -55,7 +55,7 @@
     p.row() = p.col() = 1;
 
     {
-      mln_qixter(I) qix(win, p, input);
+      mln_qixter(I, W) qix(input, win, p);
       for_all(qix)
 	std::cout << *qix << ' ';
       std::cout << " :  " << qix.center_value() << std::endl;
@@ -63,7 +63,7 @@
 
     {
       pixel<I> pix(input, p);
-      mln_qixter(I) qix(win, pix, input);
+      mln_qixter(I, W) qix(input, win, pix);
       for_all(qix)
 	std::cout << *qix << ' ';
       std::cout << " :  " << qix.center_value() << std::endl;
Index: tests/pixter_point2d.cc
--- tests/pixter_point2d.cc	(revision 1024)
+++ tests/pixter_point2d.cc	(working copy)
@@ -34,31 +34,29 @@
 {
   using namespace mln;
 
-  image2d_b<int> ima(20, 20);
+  typedef image2d_b<int> I;
+  I ima(20, 20);
 
-  image2d_b<int>::piter p(ima.domain());
-  image2d_b<int>::pixter f(ima);
+  mln_piter_(I) p(ima.domain());
+
+  mln_pixter_(I) pix(ima);
   int i = 0;
 
   for_all(p)
-    {
       ima(p) = i++;
-    }
   i = 0;
 
-  for_all(f)
+  for_all(pix)
     {
-      assert(*f = i ++);
-      *f = 5;
+      mln_assertion(*pix = i ++);
+      *pix = 5;
     }
 
   for_all(p)
-    {
-      assert(ima(p) = 5);
-    }
+    mln_assertion(ima(p) = 5);
 
-  f.start();
-  assert(f.is_valid());
-  f.invalidate();
-  assert(!f.is_valid());
+  pix.start();
+  mln_assertion(pix.is_valid());
+  pix.invalidate();
+  mln_assertion(! pix.is_valid());
 }
Index: tests/pixter_dpoint2d.cc
--- tests/pixter_dpoint2d.cc	(revision 1024)
+++ tests/pixter_dpoint2d.cc	(working copy)
@@ -1,37 +1,73 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction.  Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License.  This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+/*! \file tests/pixter_dpoint2d.cc
+ *
+ * \brief Test on mln::dpoints_fwd_pixter.
+ */
+
 #include <cassert>
 #include <iostream>
+
 #include <mln/core/image2d_b.hh>
 #include <mln/core/window.hh>
-#include <mln/level/fill.hh>
 #include <mln/core/dpoints_pixter.hh>
 
-int
-main()
+#include <mln/level/fill.hh>
+
+
+int main()
 {
   using namespace mln;
-  typedef image2d_b<int> I;
 
+  typedef image2d_b<int> I;
+  typedef I::dpoint      D;
+  typedef window_<D>     W;
 
-  I ima(20, 20);
-  level::fill(ima, 5);
-  I::piter f(ima.domain());
-  window_<I::dpoint> set;
-
-  set.insert(make::dpoint2d(0, -1));
-  set.insert(make::dpoint2d(0, -1));
-  set.insert(make::dpoint2d(1, 0));
-  set.insert(make::dpoint2d(1, 0));
+  typedef dpoints_fwd_pixter<I> qixter;
 
-  for_all(f)
-  {
-    if (f[0] > 0 && f[1] > 0 && f[0] < 19 && f[1] < 19)
-    {
-      I::qixter dit(set, f, ima);
+  const unsigned size = 20;
+  I ima(size, size);
 
-      for_all(dit)
-      {
-      	assert(*dit = 5);
-      }
-    }
-  }
+  const int value = 51;
+  level::fill(ima, value);
+
+  W win;
+  win
+    .insert(make::dpoint2d(0, -1))
+    .insert(make::dpoint2d(0, -1))
+    .insert(make::dpoint2d(1, 0))
+    .insert(make::dpoint2d(1, 0));
+
+  mln_piter_(I) p(ima.domain());
+  qixter        qix(ima, win, p);
+
+  for_all(p)
+    if (p[0] > 0 && p[1] > 0 && p[0] < size - 1 && p[1] < size - 1)
+      for_all(qix)
+      	mln_assertion(*qix = value);
 }
Index: tests/pixel.cc
--- tests/pixel.cc	(revision 1024)
+++ tests/pixel.cc	(working copy)
@@ -42,15 +42,13 @@
   I ima(3, 3);
 
   {
-    pixel<I> pxl(ima);
-    pxl.site() = make::point2d(1, 1);
+    pixel<I> pxl(ima, make::point2d(1, 1));
     *pxl = 51;
     mln_assertion(ima.at(1,1) = 51);
   }
 
   {
-    pixel<const I> pxl(ima);
-    pxl.site() = make::point2d(1, 1);
+    pixel<const I> pxl(ima, make::point2d(1, 1));
     ima.at(1,1) = 51;
     mln_assertion(*pxl = 51);
 
@@ -58,4 +56,5 @@
     // *pxl = 0;
     // assignment of read-only location
   }
+
 }
Index: TODO
--- TODO	(revision 1024)
+++ TODO	(working copy)
@@ -1,25 +1,54 @@
 	-*- outline -*-
 
 
-* compilation
+* large changes
 
-g++-4.1 -I.. int_u8.cc -Wall -Wextra -Wconversion
+introduce grids
 
 
-* value
+* adds-on
 
-Value_Set
-props { ... }
-notion of lowq
-+ values() : vset dans Image ?
+** abstractions
 
+Function_i2i
+Weighted_Window
 
-* function
+** types
 
-Function_p2v
-Function_p2b
-Function_v2w
+value::proxy to dispatch read/write + the corresponding image type
+a mean_value object { sum; count } and operator+
+value_cast<T>(image)
+t_image to "transpose" the 0 and the i-th coordinates
+image defined by f/pset
 
-F apply(I, F)
-O transform(I, F)
+** extensions
 
+in Fast_Image: memcpy and memset-like methods (?)
+.offset() into GenPixel
+notion of low-quantization
+vset and .values() in Image
+built-in op objects -> reverse lhs/rhs
+
+
+* renaming
+
+GenPixel, GenPoint, Psite, Piter: longer name (?)
+mlc into metal
+point-wise material: pw::value_of, pw::constant, and pw::variable
+kind-related: mln_value_kind(I) and mln_kind(V)
+
+
+* clean-up
+
+accu::histo and median: remove inheritance
+
+
+* processing routines
+
+reconstructions + their canvases
+fast versions of level::fill and level::paste
+histogram class
+sorting points w.r.t. their value (array of offsets, psites, points)
+border::* and no-op versions if not fast image
+arith::inplace_plus et al.
+linear:: for convolutions
Index: mln/core/dpoints_piter.hh
--- mln/core/dpoints_piter.hh	(revision 1024)
+++ mln/core/dpoints_piter.hh	(working copy)
@@ -78,7 +78,7 @@
     operator mln_point(D) () const;
 
     /// Address of the point this iterator designates.
-    const point* pointer() const;
+    const point* pointer_() const;
 
     /// Test the iterator validity.
     bool is_valid() const;
@@ -108,7 +108,7 @@
 
     unsigned i_;
     point p_; // location of this iterator; p_ makes this iterator be
-	      // itself a potential center point (Cf. the pointer() method).
+	      // itself a potential center point (Cf. the pointer_() method).
   };
 
 
@@ -119,7 +119,7 @@
   dpoints_fwd_piter<D>::dpoints_fwd_piter(const Dps& dps,
 					  const GenPoint<Pref>& p_ref)
     : dps_(exact(dps).vec()),
-      p_ref_(* internal::force_exact<Pref>(p_ref).pointer())
+      p_ref_(* internal::force_exact<Pref>(p_ref).pointer_())
   {
     invalidate();
   }
@@ -133,7 +133,7 @@
 
   template <typename D>
   const mln_point(D)*
-  dpoints_fwd_piter<D>::pointer() const
+  dpoints_fwd_piter<D>::pointer_() const
   {
     return & p_;
   }
Index: mln/core/macros.hh
--- mln/core/macros.hh	(revision 1024)
+++ mln/core/macros.hh	(working copy)
@@ -81,29 +81,20 @@
 /// Shortcut to access the fwd_piter type associated to T.
 # define mln_fwd_piter(T)  typename T::fwd_piter
 
-/// Shortcut to access the fwd_pixter type associated to T.
-# define mln_fwd_pixter(T)  typename T::fwd_pixter
-
 /// Shortcut to access the bkd_piter type associated to T.
 # define mln_bkd_piter(T)  typename T::bkd_piter
 
 /// Shortcut to access the fwd_qiter type associated to T.
 # define mln_fwd_qiter(T)  typename T::fwd_qiter
 
-/// Shortcut to access the fwd_qixter type associated to T.
-# define mln_fwd_qixter(T)  typename T::fwd_qixter
-
 /// Shortcut to access the fwd_viter type associated to T.
 # define mln_fwd_viter(T)  typename T::fwd_viter
 
 // i
 
-/// Shortcut to access the fwd_viter type associated to T.
+/// Shortcut to access the image type associated to T.
 # define mln_image(T)      typename T::image
 
-/// Shortcut to access the fwd_viter type associated to T.
-# define mln_ima(T)        typename T::ima
-
 
 // l
 
@@ -115,10 +106,8 @@
 // p
 
 /// Shortcut to access the piter type associated to T.
-# define mln_piter(T)      typename T::piter
-
-/// Shortcut to access the pixter type associated to T.
-# define mln_pixter(T)     typename T::pixter
+# define mln_piter(T)      typename T::fwd_piter
+# define mln_piter_(T)              T::fwd_piter
 
 /// Shortcut to access the pset type associated to T.
 # define mln_pset(T)       typename T::pset
@@ -133,16 +122,13 @@
 // q
 
 /// Shortcut to access the qiter type associated to T.
-# define mln_qiter(T)      typename T::qiter
-
-// Shortcut to access to the qixter type associated to T
-# define mln_qixter(T)      typename T::qixter
+# define mln_qiter(T)      typename T::fwd_qiter
 
 
 // n
 
 /// Shortcut to access the niter type associated to T.
-# define mln_niter(T)      typename T::niter
+# define mln_niter(T)      typename T::fwd_niter
 
 
 // r
@@ -160,7 +146,9 @@
 # define mln_value(T)      typename T::value
 
 /// Shortcut to access the viter type associated to T.
-# define mln_viter(T)      typename T::viter
+# define mln_viter(T)      typename T::fwd_viter
+
+
 
 
 
@@ -172,4 +160,26 @@
 # define mln_ch_value(I, T) typename I::template change_value<T>::ret
 
 
+
+// FIXME: Doc!
+
+# define mln_fwd_pixter(I)  typename mln::trait::fwd_pixter<I>::ret
+# define mln_fwd_pixter_(I)          mln::trait::fwd_pixter<I>::ret
+
+# define mln_bkd_pixter(I) typename mln::trait::bkd_pixter<I>::ret
+# define mln_pixter(I)  mln_fwd_pixter(I)
+# define mln_pixter_(I) mln_fwd_pixter_(I)
+
+
+# define mln_fwd_qixter(I, W) typename mln::trait::fwd_qixter<I, W>::ret
+# define mln_bkd_qixter(I, W) typename mln::trait::bkd_qixter<I, W>::ret
+# define mln_qixter(I, W) mln_fwd_qixter(I, W)
+
+
+# define mln_fwd_nixter(I, N) typename mln::trait::fwd_nixter<I, N>::ret
+# define mln_bkd_nixter(I, N) typename mln::trait::bkd_nixter<I, N>::ret
+# define mln_nixter(I, N) mln_fwd_nixter(I, N)
+
+
+
 #endif // ! MLN_CORE_MACROS_HH
Index: mln/core/trait/pixter.hh
--- mln/core/trait/pixter.hh	(revision 0)
+++ mln/core/trait/pixter.hh	(revision 0)
@@ -0,0 +1,111 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction.  Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License.  This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_CORE_TRAIT_PIXTER_HH
+# define MLN_CORE_TRAIT_PIXTER_HH
+
+/*! \file mln/core/trait/pixter.hh
+ *
+ * \brief Definition of some traits over image types.
+ */
+
+# include <mln/metal/none.hh>
+
+
+namespace mln
+{
+
+  namespace trait
+  {
+
+
+    // pixter
+
+    template <typename I>
+    struct fwd_pixter
+    {
+      typedef metal::none ret;
+    };
+
+    template <typename I>
+    struct bkd_pixter
+    {
+      typedef metal::none ret;
+    };
+
+    template <typename I>
+    struct pixter : fwd_pixter<I>
+    {
+    };
+
+
+    // qixter
+
+    template <typename I, typename W>
+    struct fwd_qixter
+    {
+      typedef metal::none ret;
+    };
+
+    template <typename I, typename W>
+    struct bkd_qixter
+    {
+      typedef metal::none ret;
+    };
+
+    template <typename I, typename W>
+    struct qixter : fwd_qixter<I, W>
+    {
+    };
+
+
+    // nixter
+
+    template <typename I, typename N>
+    struct fwd_nixter
+    {
+      typedef metal::none ret;
+    };
+
+    template <typename I, typename N>
+    struct bkd_nixter
+    {
+      typedef metal::none ret;
+    };
+
+    template <typename I, typename N>
+    struct nixter : fwd_nixter<I, N>
+    {
+    };
+
+
+  } // end of namespace mln::trait
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CORE_TRAIT_PIXTER_HH
Index: mln/core/psubset.hh
--- mln/core/psubset.hh	(revision 1024)
+++ mln/core/psubset.hh	(working copy)
@@ -78,10 +78,7 @@
     typedef psubset_fwd_piter_<S,F> fwd_piter;
 
     /// Backward Piter associated type.
-    typedef psubset_fwd_piter_<S,F> bkd_piter; // FIXME: bkd!!!
-
-    /// Piter associated type.
-    typedef fwd_piter piter;
+    typedef internal::fixme bkd_piter;
 
 
     /// Constructor without argument.
@@ -180,7 +177,7 @@
   psubset<S,F>::npoints() const
   {
     std::size_t n = 0;
-    piter p(*this);
+    fwd_piter p(*this);
     for_all(p)
       ++n;
     return n;
Index: mln/core/box.hh
--- mln/core/box.hh	(revision 1024)
+++ mln/core/box.hh	(working copy)
@@ -70,10 +70,6 @@
      */
     typedef box_bkd_piter_<P> bkd_piter;
 
-    /*! \brief Piter associated type.
-     */
-    typedef fwd_piter piter;
-
     /*! \brief Minimum point.
      */
     P  pmin() const;
Index: mln/core/rectangle2d.hh
--- mln/core/rectangle2d.hh	(revision 1024)
+++ mln/core/rectangle2d.hh	(working copy)
@@ -70,7 +70,7 @@
     /*! \brief Piter type to browse a rectangle such as: "for each row
      * (decreasing), for each column (decreasing)."
      */
-    typedef dpoints_fwd_piter<dpoint2d> bkd_qiter; // FIXME: bkd!!!
+    typedef internal::fixme bkd_qiter;
 
     /*! \brief Same as fwd_qiter.
      */
Index: mln/core/box_piter.hh
--- mln/core/box_piter.hh	(revision 1024)
+++ mln/core/box_piter.hh	(working copy)
@@ -76,7 +76,7 @@
     operator P() const;
 
     /// Address of the point.
-    const P* pointer() const;
+    const P* pointer_() const;
 
     /// Give the i-th coordinate.
     coord operator[](unsigned i) const;
@@ -136,7 +136,7 @@
     operator P() const;
 
     /// Address of the point.
-    const P* pointer() const;
+    const P* pointer_() const;
 
     /// Give the i-th coordinate.
     coord operator[](unsigned i) const;
@@ -183,7 +183,7 @@
 
   template <typename P>
   const P*
-  box_fwd_piter_<P>::pointer() const
+  box_fwd_piter_<P>::pointer_() const
   {
     return & p_;
   }
@@ -254,7 +254,7 @@
 
   template <typename P>
   const P*
-  box_bkd_piter_<P>::pointer() const
+  box_bkd_piter_<P>::pointer_() const
   {
     return & p_;
   }
Index: mln/core/pixter2d_b.hh
--- mln/core/pixter2d_b.hh	(revision 1024)
+++ mln/core/pixter2d_b.hh	(working copy)
@@ -28,80 +28,77 @@
 #ifndef MLN_CORE_PIXTER2D_B_HH
 # define MLN_CORE_PIXTER2D_B_HH
 
-# include <mln/core/internal/lineary_pixel_iterator_base.hh>
-# include <mln/core/point2d.hh>
-# include <iostream>
-
-
-//FIXME comment
 /*! \file mln/core/pixter2d_b.hh
  *
  * \brief Pixel iterator class on a image 2d with border.
  */
 
+# include <mln/core/internal/pixel_iterator_base.hh>
+# include <mln/core/point2d.hh>
+
 
 
 namespace mln
 {
 
-  // Forward declaration
-  template <typename T> class image2d_b;
-
-  template <typename T>
-  class fwd_pixter2d_b :
-    public internal::lineary_pixel_iterator_base_<image2d_b<T>, fwd_pixter2d_b<T> >
+  template <typename I>
+  class fwd_pixter2d_b : public internal::pixel_iterator_base_< I, fwd_pixter2d_b<I> >
   {
-    typedef internal::lineary_pixel_iterator_base_<image2d_b<T>, fwd_pixter2d_b<T> > super;
+    typedef internal::pixel_iterator_base_< I, fwd_pixter2d_b<I> > super_;
+    typedef mln_value(super_) value_;
   public:
-    /// Image pixel value type.
-    typedef mln_value(image2d_b<T>) value;
 
     /*! \brief Constructor.
      *
-     * \param[in] ima   Image to iterate.
+     * \param[in] image Image to iterate over its pixels.
      */
-    fwd_pixter2d_b(image2d_b<T>& image);
-    /// Move the iterator on the next element.
+    fwd_pixter2d_b(I& image);
+
+    /// Go to the next pixel.
     void next_();
 
   private:
-    /// Size of the image border.
-    unsigned border_size_;
+
+    /// Twice the size of the image border.
+    unsigned border_x2_;
+
     /// Row offset.
     unsigned row_offset_;
-    /// End of a row.
-    value *eor_;
+
+    /// End of the current row.
+    value_* eor_;
   };
 
+
+  // FIXME: bkd_pixter2d_b
+
+
 #ifndef MLN_INCLUDE_ONLY
 
-  template <typename T>
-  fwd_pixter2d_b<T>::fwd_pixter2d_b(image2d_b<T>& image) :
-    super(image),
-    border_size_(image.border()),
-    row_offset_((image.domain().pmax()[1] - image.domain().pmin()[1])
-		+ 2 * border_size_ + 1)
+  template <typename I>
+  fwd_pixter2d_b<I>::fwd_pixter2d_b(I& image) :
+    super_(image)
   {
-    this->start_ = &image(image.domain().pmin());
-    this->eor_ = &image(make::point2d(image.domain().pmin()[0], image.domain().pmax()[1])) + 1;
-    this->eoi_ = &image(image.domain().pmax()) + 1;
+    mln_precondition(image.has_data());
+    border_x2_ = 2 * image.border();
+    row_offset_ = image.max_col() - image.min_col() + 1 + border_x2_;
+    eor_ = & image.at(image.min_row(), image.max_col()) + 1;
   }
 
-  template <typename T>
-  void fwd_pixter2d_b<T>::next_()
+  template <typename I>
+  void
+  fwd_pixter2d_b<I>::next_()
   {
-    ++(this->value_ptr_);
-
-    if (this->value_ptr_ = this->eor_ && this->value_ptr_ != this->eoi_)
+    ++this->value_ptr_;
+    if (this->value_ptr_ = eor_ && this->value_ptr_ != this->eoi_)
     {
-      this->value_ptr_ += 2 * this->border_size_;
-      this->eor_ += this->row_offset_;
+      this->value_ptr_ += border_x2_;
+      eor_ += row_offset_;
     }
   }
 
 #endif // ! MLN_INCLUDE_ONLY
 
-
 } // end of namespace mln
 
 #endif // ! MLN_CORE_PIXTER2D_B_HH
Index: mln/core/window.hh
--- mln/core/window.hh	(revision 1024)
+++ mln/core/window.hh	(working copy)
@@ -75,7 +75,7 @@
     /*! \brief Piter type to browse the points of a generic window
      * w.r.t. the reverse ordering of delta-points.
      */
-    typedef dpoints_bkd_piter<D> bkd_qiter;
+    typedef internal::fixme bkd_qiter;
 
     /*! \brief Same as fwd_qiter.
      */
Index: mln/core/dpoints_pixter.hh
--- mln/core/dpoints_pixter.hh	(revision 1024)
+++ mln/core/dpoints_pixter.hh	(working copy)
@@ -28,47 +28,60 @@
 #ifndef MLN_CORE_DPOINTS_PIXTER_HH
 # define MLN_CORE_DPOINTS_PIXTER_HH
 
+/*! \file mln/core/dpoints_pixter.hh
+ *
+ * \brief Definition of mln::dpoints_fwd_pixter and
+ * mln::dpoints_bkd_pixter.
+ */
+
 # include <cassert>
 # include <vector>
-# include <mln/core/internal/pixel_iterator_base.hh>
+
+# include <mln/core/concept/pixel_iterator.hh>
+# include <mln/core/concept/genpixel.hh>
+# include <mln/core/internal/pixel_impl.hh>
+
 
 
 namespace mln
 {
 
-  /*! \brief A generic forward iterator on image pixel of a windows and of
+  /*! \brief A generic forward iterator on pixels of windows and of
    *  neighborhoods.
    *
    * The parameter \c I is the image type.
    */
   template <typename I>
-  class dpoints_pixter : public internal::pixel_iterator_base_< I, dpoints_pixter<I> >
+  class dpoints_fwd_pixter : public Pixel_Iterator< dpoints_fwd_pixter<I> >,
+			     public internal::pixel_impl_< I, dpoints_fwd_pixter<I> >
   {
-    typedef typename internal::pixel_iterator_base_< I, dpoints_pixter<I> > super;
+    typedef typename internal::pixel_impl_< I, dpoints_fwd_pixter<I> > super;
   public:
 
-    /// Image pixel value
-    typedef mln_value(I) value;
-    /// Image pixel rvalue
-    typedef mln_rvalue(I) rvalue;
-    /// Image pixel lvalue
-    typedef mln_lvalue(I) lvalue;
+    /// Using super value type.
+    typedef mln_value(super) value;
 
     /*! \brief Constructor.
      *
-     * \param[in] dps   Object that can provide an array of delta-points.
-     * \param[in] p_ref Center point to iterate around.
-     * \param[in] ima   Image to iterate.
+     * \param[in] image Image subject to iteration.
+     * \param[in] dps   Object that can provide a set of delta-points.
+     * \param[in] p_ref Center (generalized) point to iterate around.
      */
     template <typename Dps, typename Pref>
-    dpoints_pixter(const Dps& dps,
-		   const GenPoint<Pref>& p_ref,
-		   I& image);
+    dpoints_fwd_pixter(I& image,
+		       const Dps& dps,
+		       const GenPoint<Pref>& p_ref);
 
+    /*! \brief Constructor.
+     *
+     * \param[in] image Image subject to iteration.
+     * \param[in] dps   Object that can provide a set of delta-points.
+     * \param[in] p_ref Center (generalized) pixel to iterate around.
+     */
     template <typename Dps, typename Pref>
-    dpoints_pixter(const Dps& dps,
-		   const GenPixel<Pref>& p_ref,
-		   I& image);
+    dpoints_fwd_pixter(I& image,
+		       const Dps& dps,
+		       const GenPixel<Pref>& p_ref);
 
     /// Start an iteration.
     void start();
@@ -87,7 +100,7 @@
     void update();
 
     /// The value around which this iterator moves.
-    const value& center_value() const;
+    const mln_value(I)& center_value() const;
 
   private:
 
@@ -95,7 +108,7 @@
     std::vector<int> offset_;
 
     /// current offset
-    int i_;
+    unsigned i_;
 
     /// reference pixel / point in the image
     value** value_ref_;
@@ -108,16 +121,24 @@
   };
 
 
+  // FIXME: dpoints_bkd_pixter<I>
+
+
+
 #ifndef MLN_INCLUDE_ONLY
 
+
+  // dpoints_fwd_pixter<I>
+
   template <typename I>
   template <typename Dps, typename Pref>
-  dpoints_pixter<I>::dpoints_pixter(const Dps& dps,
-				    const GenPoint<Pref>& p_ref,
-				    I& image)
+  dpoints_fwd_pixter<I>::dpoints_fwd_pixter(I& image,
+					    const Dps& dps,
+					    const GenPoint<Pref>& p_ref)
     : super(image)
   {
-    p_ref_ = internal::force_exact<Pref>(p_ref).pointer();
+    mln_precondition(image.has_data());
+    p_ref_ = internal::force_exact<Pref>(p_ref).pointer_();
     value_ref_ = 0;
     init_(dps);
   }
@@ -125,19 +146,20 @@
 
   template <typename I>
   template <typename Dps, typename Pref>
-  dpoints_pixter<I>::dpoints_pixter(const Dps& dps,
-				    const GenPixel<Pref>& p_ref,
-				    I& image)
+  dpoints_fwd_pixter<I>::dpoints_fwd_pixter(I& image,
+					    const Dps& dps,
+					    const GenPixel<Pref>& p_ref)
     : super(image)
   {
+    mln_precondition(image.has_data());
     p_ref_ = 0;
-    value_ref_ = internal::force_exact<Pref>(p_ref).address();
+    value_ref_ = internal::force_exact<Pref>(p_ref).address_();
     init_(dps);
   }
 
   template <typename I>
   const mln_value(I)&
-  dpoints_pixter<I>::center_value() const
+  dpoints_fwd_pixter<I>::center_value() const
   {
     mln_invariant(value_ref_ != 0 || p_ref_ != 0);
     if (p_ref_)
@@ -149,21 +171,21 @@
   template <typename I>
   template <typename Dps>
   void
-  dpoints_pixter<I>::init_(const Dps& dps)
+  dpoints_fwd_pixter<I>::init_(const Dps& dps)
   {
     for (unsigned i = 0; i < dps.nelements(); ++i)
       offset_.push_back(this->image_.offset(dps.element(i)));
-
+    // offset_[0] is absolute
+    // other offsets are relative: 
     if (dps.nelements() > 1)
       for (unsigned i = dps.nelements() - 1; i > 0; --i)
 	offset_[i] -= offset_[i - 1];
-
-    // offset_[0] is absolute; other offsets are relative.
     invalidate();
   }
 
   template <typename I>
-  void dpoints_pixter<I>::update()
+  void
+  dpoints_fwd_pixter<I>::update()
   {
     if (is_valid())
       {
@@ -175,27 +197,31 @@
   }
 
   template <typename I>
-  void dpoints_pixter<I>::start()
+  void
+  dpoints_fwd_pixter<I>::start()
   {
     i_ = 0;
     update();
   }
 
   template <typename I>
-  void dpoints_pixter<I>::next_()
+  void
+  dpoints_fwd_pixter<I>::next_()
   {
     ++i_;
     this->value_ptr_ += offset_[i_];    
   }
 
   template <typename I>
-  bool dpoints_pixter<I>::is_valid() const
+  bool
+  dpoints_fwd_pixter<I>::is_valid() const
   {
     return i_ != offset_.size();
   }
 
   template <typename I>
-  void dpoints_pixter<I>::invalidate()
+  void
+  dpoints_fwd_pixter<I>::invalidate()
   {
     i_ = offset_.size();
   }
Index: mln/core/internal/pixel_impl.hh
--- mln/core/internal/pixel_impl.hh	(revision 1024)
+++ mln/core/internal/pixel_impl.hh	(working copy)
@@ -25,15 +25,16 @@
 // reasons why the executable file might be covered by the GNU General
 // Public License.
 
-#ifndef MLN_CORE_INTERNAL_PIXEL_ITERATOR_BASE_HH
-# define MLN_CORE_INTERNAL_PIXEL_ITERATOR_BASE_HH
+#ifndef MLN_CORE_INTERNAL_PIXEL_IMPL_HH
+# define MLN_CORE_INTERNAL_PIXEL_IMPL_HH
 
-/*! \file mln/core/internal/pixel_iterator_base.hh
+/*! \file mln/core/internal/pixel_impl.hh
  *
- * \brief Base class for Pixel_Iterator concept implementation classes.
+ * \brief Define a couple of implementation classes to provide methods
+ * to classes of generalized pixels.
  */
 
-# include <mln/core/concept/pixel_iterator.hh>
+# include <mln/core/internal/force_exact.hh>
 
 
 namespace mln
@@ -42,11 +43,13 @@
   namespace internal
   {
 
-    /*! \brief pixel_iterator_base_ class
+    /*! \brief Implementation class to equip generalized pixel
+     *  classes based on mutable images.
      *
+     * \internal
      */
     template <typename I, typename E>
-    class pixel_iterator_base_ : public Pixel_Iterator<E>
+    class pixel_impl_
     {
     public:
 
@@ -68,111 +71,138 @@
 
 
       /// Address of the current iterator value/pixel.
-      value** address() const;
+      value** address_() const;
 
+    protected:
 
-      // FIXME: Inactivated:
+      /// Image associated to the iterator
+      I& image_;
 
-//       /// I type.
-//       typedef I ima;
+      /// Current pixel / value
+      value* value_ptr_;
 
-//       /// Image psite type.
-//       typedef mln_psite(I) psite;
+      /// Constructor
+      pixel_impl_(I& image);
 
-//       /// Get the image associated to the current pixel iterator.
-//       const ima& image() const;
+    private:
+      bool is_valid_() const;
+    };
 
-//       /// psite associated to the iterator.
-//       const psite& site() const;
 
-//       /// psite associated to the iterator.
-//       psite& site();
+    /*! \brief Implementation class to equip generalized pixel
+     *  classes based on constant images.
+     *
+     * \internal
+     */
+    template <typename I, typename E>
+    class pixel_impl_< const I, E >
+    {
+    public:
 
-//       /// Address of the current iterator value/pixel.
-//       value* address();
+      /// Image value type.
+      typedef mln_value(I) value;
+
+      /// Image rvalue type.
+      typedef mln_rvalue(I) rvalue;
+
+
+      /// Get the pixel iterator value.
+      rvalue operator*() const;
+
+
+      /// Address of the current iterator value/pixel.
+      value** address_() const;
 
     protected:
 
       /// Image associated to the iterator
-      I& image_;
+      const I& image_;
 
       /// Current pixel / value
-      value* value_ptr_;
-
-      // FIXME: Inactivated:
+      const value* value_ptr_;
 
-//       /// Psite of the pixel
-//       psite  p_;
+      /// Constructor
+      pixel_impl_(const I& image);
 
-      pixel_iterator_base_(I& image);
+    private:
+      bool is_valid_() const;
     };
 
+
 #ifndef MLN_INCLUDE_ONLY
 
+    // pixel_impl_<I, E>
+
     template <typename I, typename E>
-    pixel_iterator_base_<I, E>::pixel_iterator_base_(I& image) :
+    bool
+    pixel_impl_<I, E>::is_valid_() const
+    {
+      return value_ptr_ != 0 && internal::force_exact<E>(*this).is_valid();
+    }
+
+    template <typename I, typename E>
+    pixel_impl_<I, E>::pixel_impl_(I& image) :
       image_(image),
       value_ptr_(0)
     {
     }
 
-//     template <typename I, typename E>
-//     const typename pixel_iterator_base_<I, E>::ima&
-//     pixel_iterator_base_<I, E>::image() const
-//     {
-//       return ima_;
-//     }
-
     template <typename I, typename E>
     mln_lvalue(I)
-    pixel_iterator_base_<I, E>::operator* ()
+    pixel_impl_<I, E>::operator*()
+    {
+      mln_precondition(is_valid_());
+      return *value_ptr_;
+    }
+
+    template <typename I, typename E>
+    mln_rvalue(I)
+    pixel_impl_<I, E>::operator*() const
     {
-      mln_precondition(exact(this)->is_valid());
-      mln_precondition(value_ptr_ != 0);
+      mln_precondition(is_valid_());
       return *value_ptr_;
     }
 
     template <typename I, typename E>
+    mln_value(I) **
+    pixel_impl_<I, E>::address_() const
+    {
+      mln_precondition(is_valid_());
+      return (value**)(& this->value_ptr_);
+    }
+
+
+    // pixel_impl_<const I, E>
+
+    template <typename I, typename E>
+    bool
+    pixel_impl_<const I, E>::is_valid_() const
+    {
+      return value_ptr_ != 0 && internal::force_exact<E>(*this).is_valid();
+    }
+
+    template <typename I, typename E>
+    pixel_impl_<const I, E>::pixel_impl_(const I& image) :
+      image_(image),
+      value_ptr_(0)
+    {
+    }
+
+    template <typename I, typename E>
     mln_rvalue(I)
-    pixel_iterator_base_<I, E>::operator* () const
+    pixel_impl_<const I, E>::operator*() const
     {
-      mln_precondition(exact(this)->is_valid());
-      mln_precondition(value_ptr_ != 0);
+      mln_precondition(is_valid_());
       return *value_ptr_;
     }
 
     template <typename I, typename E>
     mln_value(I) **
-    pixel_iterator_base_<I, E>::address() const
+    pixel_impl_<const I, E>::address_() const
     {
-      mln_precondition(exact(this)->is_valid());
-      mln_precondition(value_ptr_ != 0);
-      return & (mln_value(I)*)(value_ptr_);
-    }
-
-//     template <typename I, typename E>
-//     mln_value(I)*
-//     pixel_iterator_base_<I, E>::address()
-//     {
-//       mln_precondition(exact(this)->is_valid());
-//       return value_ptr_;
-//     }
-
-//     template <typename I, typename E>
-//     const typename pixel_iterator_base_<I, E>::psite&
-//     pixel_iterator_base_<I, E>::site() const
-//     {
-//       //FIXME: update psite
-//       return p_;
-//     }
-
-//     template <typename I, typename E>
-//     typename pixel_iterator_base_<I, E>::psite&
-//     pixel_iterator_base_<I, E>::site()
-//     {
-//       //FIXME: update psite
-//       return p_;
-//     }
+      mln_precondition(is_valid_());
+      return (value**)(& this->value_ptr_);
+    }
 
 #endif // ! MLN_INCLUDE_ONLY
 
@@ -181,4 +211,4 @@
 } // end of namespace mln
 
 
-#endif // ! MLN_CORE_INTERNAL_PIXEL_ITERATOR_BASE_HH
+#endif // ! MLN_CORE_INTERNAL_PIXEL_IMPL_HH
Index: mln/core/internal/pixel_iterator_base.hh
--- mln/core/internal/pixel_iterator_base.hh	(revision 1024)
+++ mln/core/internal/pixel_iterator_base.hh	(working copy)
@@ -30,10 +30,11 @@
 
 /*! \file mln/core/internal/pixel_iterator_base.hh
  *
- * \brief Base class for Pixel_Iterator concept implementation classes.
+ * \brief Base class to factor code for pixel iterator classes.
  */
 
 # include <mln/core/concept/pixel_iterator.hh>
+# include <mln/core/internal/pixel_impl.hh>
 
 
 namespace mln
@@ -42,138 +43,74 @@
   namespace internal
   {
 
-    /*! \brief pixel_iterator_base_ class
+    /*! \brief A base class for pixel iterators. 
      *
      */
     template <typename I, typename E>
-    class pixel_iterator_base_ : public Pixel_Iterator<E>
+    class pixel_iterator_base_ : public Pixel_Iterator<E>,
+				 public internal::pixel_impl_<I, E>
     {
-    public:
-
-      /// Image value type.
-      typedef mln_value(I) value;
-
-      /// Image lvalue type.
-      typedef mln_lvalue(I) lvalue;
-
-      /// Image rvalue type.
-      typedef mln_rvalue(I) rvalue;
-
-
-      /// pixel iterator value.
-      lvalue operator* ();
-
-      /// Get the pixel iterator value.
-      rvalue operator* () const;
-
-
-      /// Address of the current iterator value/pixel.
-      value** address() const;
-
+      typedef internal::pixel_impl_<I, E> super_;
+      typedef mln_value(super_) value_;
 
-      // FIXME: Inactivated:
-
-//       /// I type.
-//       typedef I ima;
-
-//       /// Image psite type.
-//       typedef mln_psite(I) psite;
-
-//       /// Get the image associated to the current pixel iterator.
-//       const ima& image() const;
+    public:
 
-//       /// psite associated to the iterator.
-//       const psite& site() const;
+      /// Start an iteration.
+      void start();
 
-//       /// psite associated to the iterator.
-//       psite& site();
+      /// Invalidate the iterator.
+      void invalidate();
 
-//       /// Address of the current iterator value/pixel.
-//       value* address();
+      /// Test if the iterator is valid.
+      bool is_valid() const;
 
     protected:
 
-      /// Image associated to the iterator
-      I& image_;
-
-      /// Current pixel / value
-      value* value_ptr_;
+      /// Beginning of the image.
+      value_* boi_;
 
-      // FIXME: Inactivated:
-
-//       /// Psite of the pixel
-//       psite  p_;
+      /// End of the image (past-the-end).
+      value_* eoi_;
 
+      /// Constructor.
       pixel_iterator_base_(I& image);
     };
 
+
 #ifndef MLN_INCLUDE_ONLY
 
     template <typename I, typename E>
-    pixel_iterator_base_<I, E>::pixel_iterator_base_(I& image) :
-      image_(image),
-      value_ptr_(0)
+    pixel_iterator_base_<I, E>::pixel_iterator_base_(I& image)
+      : super_(image)
     {
+      mln_precondition(image.has_data());
+      I& ima = this->image_;
+      boi_ = & ima( ima.domain().pmin() );
+      eoi_ = & ima( ima.domain().pmax() ) + 1;
+      invalidate();
     }
 
-//     template <typename I, typename E>
-//     const typename pixel_iterator_base_<I, E>::ima&
-//     pixel_iterator_base_<I, E>::image() const
-//     {
-//       return ima_;
-//     }
-
     template <typename I, typename E>
-    mln_lvalue(I)
-    pixel_iterator_base_<I, E>::operator* ()
+    void
+    pixel_iterator_base_<I, E>::start()
     {
-      mln_precondition(exact(this)->is_valid());
-      mln_precondition(value_ptr_ != 0);
-      return *value_ptr_;
+      this->value_ptr_ = boi_;
     }
 
     template <typename I, typename E>
-    mln_rvalue(I)
-    pixel_iterator_base_<I, E>::operator* () const
+    void
+    pixel_iterator_base_<I, E>::invalidate()
     {
-      mln_precondition(exact(this)->is_valid());
-      mln_precondition(value_ptr_ != 0);
-      return *value_ptr_;
+      this->value_ptr_ = eoi_;
     }
 
     template <typename I, typename E>
-    mln_value(I) **
-    pixel_iterator_base_<I, E>::address() const
+    bool
+    pixel_iterator_base_<I, E>::is_valid() const
     {
-      mln_precondition(exact(this)->is_valid());
-      mln_precondition(value_ptr_ != 0);
-      return & (mln_value(I)*)(value_ptr_);
+      return this->value_ptr_ != eoi_;
     }
 
-//     template <typename I, typename E>
-//     mln_value(I)*
-//     pixel_iterator_base_<I, E>::address()
-//     {
-//       mln_precondition(exact(this)->is_valid());
-//       return value_ptr_;
-//     }
-
-//     template <typename I, typename E>
-//     const typename pixel_iterator_base_<I, E>::psite&
-//     pixel_iterator_base_<I, E>::site() const
-//     {
-//       //FIXME: update psite
-//       return p_;
-//     }
-
-//     template <typename I, typename E>
-//     typename pixel_iterator_base_<I, E>::psite&
-//     pixel_iterator_base_<I, E>::site()
-//     {
-//       //FIXME: update psite
-//       return p_;
-//     }
-
 #endif // ! MLN_INCLUDE_ONLY
 
   } // end of namespace internal
Index: mln/core/internal/fixme.hh
--- mln/core/internal/fixme.hh	(revision 0)
+++ mln/core/internal/fixme.hh	(revision 0)
@@ -0,0 +1,55 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction.  Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License.  This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_CORE_INTERNAL_FIXME_HH
+# define MLN_CORE_INTERNAL_FIXME_HH
+
+/*! \file mln/core/internal/fixme.hh
+ *
+ * \brief Definition of mln::fixme for internal use only.
+ */
+
+
+namespace mln
+{
+
+  namespace internal
+  {
+
+    /*! \brief A FIXME class to make explicit in code that a type is
+     *  not yet implemented.
+     *
+     * \internal
+     */
+    struct fixme;
+
+  } // end of namespace mln::internal
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CORE_INTERNAL_FIXME_HH
Index: mln/core/internal/box_impl.hh
--- mln/core/internal/box_impl.hh	(revision 1024)
+++ mln/core/internal/box_impl.hh	(working copy)
@@ -48,7 +48,7 @@
     // box_impl
 
     /*! \brief Implementation class to equip objects having a bounding
-     * box with methods.
+     * box.
      *
      * \internal
      */
Index: mln/core/internal/image_base.hh
--- mln/core/internal/image_base.hh	(revision 1024)
+++ mln/core/internal/image_base.hh	(working copy)
@@ -58,14 +58,20 @@
       /// Point associated type.
       typedef mln_point(S) point;
 
+
+      /// Dpoint associated type.
+      typedef mln_dpoint(point) dpoint;
+
+      /// Coordinate associated type.
+      typedef mln_coord(point) coord;
+
+
       /// Forward Piter associated type.
       typedef mln_fwd_piter(S) fwd_piter;
 
       /// Backward Piter associated type.
       typedef mln_bkd_piter(S) bkd_piter;
 
-      /// Piter associated type.
-      typedef fwd_piter piter;
 
       /// Test if \p p belongs to the image domain.
       bool has(const psite& p) const;
Index: mln/core/internal/piter_adaptor.hh
--- mln/core/internal/piter_adaptor.hh	(revision 1024)
+++ mln/core/internal/piter_adaptor.hh	(working copy)
@@ -77,7 +77,7 @@
       operator mln_point(Pi) () const;
 
       /// Address of the point.
-      const point* pointer() const;
+      const point* pointer_() const;
 
       /// Give the i-th coordinate.
       coord operator[](unsigned i) const;
@@ -120,9 +120,9 @@
 
     template <typename Pi, typename E>
     const mln_point(Pi)*
-    piter_adaptor_<Pi,E>::pointer() const
+    piter_adaptor_<Pi,E>::pointer_() const
     {
-      return piter_.pointer();
+      return piter_.pointer_();
     }
 
     template <typename Pi, typename E>
Index: mln/core/pixel.hh
--- mln/core/pixel.hh	(revision 1024)
+++ mln/core/pixel.hh	(working copy)
@@ -34,57 +34,36 @@
  */
 
 # include <mln/core/concept/genpixel.hh>
+# include <mln/core/internal/pixel_impl.hh>
 
 
 namespace mln
 {
 
 
-  template <typename I>
-  struct pixel_lvalue
-  {
-    typedef mln_lvalue(I) ret;
-  };
-
-  template <typename I>
-  struct pixel_lvalue< const I >
-  {
-    typedef mln_rvalue(I) ret;
-  };
-
-
-
   /*! \brief Generic pixel class.
    *
    * The parameter is \c I the type of the image it belongs to.
    */
   template <typename I>
   struct pixel : public Object< pixel<I> >,
-		 public GenPixel< pixel<I> >
+		 public GenPixel< pixel<I> >,
+		 internal::pixel_impl_< I, pixel<I> >
   {
-    typedef mln_psite(I) psite;
-    typedef mln_value(I) value;
-    typedef mln_rvalue(I) rvalue;
-    typedef I ima;
-
-    pixel(I& ima);
-    pixel(I& ima, const psite& p);
-
-    const I& image() const;
+    /// Constructor.
+    pixel(I& image);
 
-    const psite& site() const;
-    psite& site();
+    /// Constructor.
+    pixel(I& image, const mln_point(I)& p);
 
-    mln_rvalue(I) operator*() const;
-    mln_lvalue(I) operator*();
+    /// Change the pixel to the one at point \p p.
+    void change_to(const mln_point(I)& p);
 
-    value** address() const;
+    /// Test if this pixel is valid.
+    bool is_valid() const;
 
-  protected:
-
-    I& ima_;
-    psite p_;
-    value* value_ptr_;
+  private:
+    typedef internal::pixel_impl_<I, pixel<I> > super;
   };
 
 
@@ -92,58 +71,37 @@
 
   template <typename I>
   pixel<I>::pixel(I& image)
-    : ima_(image)
-  {
-  }
-
-  template <typename I>
-  pixel<I>::pixel(I& image, const psite& p)
-    : ima_(image),
-      p_(p)
-  {
-    value_ptr_ = & ima_(p);
-  }
-
-  template <typename I>
-  const I&
-  pixel<I>::image() const
-  {
-    return ima_;
-  }
-
-  template <typename I>
-  const mln_psite(I)&
-  pixel<I>::site() const
-  {
-    return p_;
-  }
-
-  template <typename I>
-  mln_psite(I)&
-  pixel<I>::site()
+    : super(image)
   {
-    return p_;
+    this->value_ptr_ = 0;
   }
 
   template <typename I>
-  mln_rvalue(I)
-  pixel<I>::operator*() const
+  pixel<I>::pixel(I& image, const mln_point(I)& p)
+    : super(image)
   {
-    return ima_(p_);
+    mln_precondition(this->image_.owns_(p));
+    change_to(p);
   }
 
   template <typename I>
-  mln_lvalue(I)
-  pixel<I>::operator*()
+  void
+  pixel<I>::change_to(const mln_point(I)& p)
   {
-    return ima_(p_);
+    mln_precondition(this->image_.owns_(p));
+    this->value_ptr_ = & this->image_(p);
   }
 
   template <typename I>
-  mln_value(I)**
-  pixel<I>::address() const
+  bool
+  pixel<I>::is_valid() const
   {
-    return (mln_value(I)**)(& this->value_ptr_);
+    I& ima = this->image_;
+    if (this->value_ptr_ = 0 || ! ima.has_data())
+      return false;
+    int o = this->value_ptr_ - ima.buffer();
+    mln_point(I) p = ima.point_at_offset(o);
+    return ima.owns_(p);
   }
 
 # endif // ! MLN_INCLUDE_ONLY
Index: mln/core/hline2d.hh
--- mln/core/hline2d.hh	(revision 1024)
+++ mln/core/hline2d.hh	(working copy)
@@ -68,7 +68,7 @@
     /*! \brief Piter type to browse a hline such as: "for each row
      * (decreasing), for each column (decreasing)."
      */
-    typedef dpoints_fwd_piter<dpoint2d> bkd_qiter; // FIXME: bkd!!!
+    typedef internal::fixme bkd_qiter;
 
     /*! \brief Same as fwd_qiter.
      */
Index: mln/core/concept/image.hh
--- mln/core/concept/image.hh	(revision 1024)
+++ mln/core/concept/image.hh	(working copy)
@@ -74,7 +74,9 @@
       typedef point;
       typedef psite;
 
-      typedef piter;
+      typedef coord;
+      typedef dpoint;
+
       typedef fwd_piter;
       typedef bkd_piter;
 
@@ -99,7 +101,9 @@
     typedef mln_point(E) point;
     typedef mln_psite(E) psite;
 
-    typedef mln_piter(E)     piter;
+    typedef mln_coord(E)  coord;
+    typedef mln_dpoint(E) dpoint;
+
     typedef mln_fwd_piter(E) fwd_piter;
     typedef mln_bkd_piter(E) bkd_piter;
 
Index: mln/core/concept/genpoint.hh
--- mln/core/concept/genpoint.hh	(revision 1024)
+++ mln/core/concept/genpoint.hh	(working copy)
@@ -36,9 +36,6 @@
 # include <mlc/same_coord.hh>
 
 # include <mln/core/concept/object.hh>
-
-# include <mln/core/macros.hh>
-# include <mln/core/contract.hh>
 # include <mln/core/internal/force_exact.hh>
 
 
@@ -73,7 +70,7 @@
       either Point
       or operator point() const;
 
-      const point* pointer() const;
+      const point* pointer_() const;
       coord operator[](unsigned i) const;
     */
 
@@ -218,7 +215,7 @@
     typedef  mln_point(E)  point;
     typedef mln_dpoint(E) dpoint;
     typedef mln_coord(E)  coord;
-    const point* (E::*m1)() const = & E::pointer;
+    const point* (E::*m1)() const = & E::pointer_;
     m1 = 0;
     coord (E::*m2)(unsigned i) const = & E::operator[];
     m2 = 0;
Index: mln/core/concept/psite.hh
--- mln/core/concept/psite.hh	(revision 1024)
+++ mln/core/concept/psite.hh	(working copy)
@@ -65,7 +65,7 @@
 		 public GenPoint<E>
   {
     /*
-    const point* pointer() const
+    const point* pointer_() const
     {
       return & (exact(this)->operator point());
     }
Index: mln/core/concept/point.hh
--- mln/core/concept/point.hh	(revision 1024)
+++ mln/core/concept/point.hh	(working copy)
@@ -55,7 +55,7 @@
 
     /*! \brief The pointer is this point address.
      */
-    const P* pointer() const;
+    const P* pointer_() const;
 
   protected:
     Point();
@@ -105,7 +105,7 @@
   }
 
   template <typename P>
-  const P* Point<P>::pointer() const
+  const P* Point<P>::pointer_() const
   {
     return exact(this);
   }
Index: mln/core/concept/pixel_iterator.hh
--- mln/core/concept/pixel_iterator.hh	(revision 1024)
+++ mln/core/concept/pixel_iterator.hh	(working copy)
@@ -28,53 +28,53 @@
 #ifndef MLN_CORE_CONCEPT_PIXEL_ITERATOR_HH
 # define MLN_CORE_CONCEPT_PIXEL_ITERATOR_HH
 
-/*! \file mln/core/concept/fast_iterator.hh
+/*! \file mln/core/concept/pixel_iterator.hh
+ *
  * \brief Definition of the concept of mln::Pixel_Iterator.
  */
 
 # include <mln/core/concept/iterator.hh>
 # include <mln/core/concept/genpixel.hh>
 
+
 namespace mln
 {
 
-  /*! \brief Pixel Iterator concept class.
+  /*! \brief Base class for the implementation of pixel iterator
+   *  classes.
    *
-   * \see FIXME
+   * An iterator on pixels is an iterator that is bound to a
+   * particular image and that browses over a set of image pixels.
+   *
+   * \see mln::doc::Pixel_Iterator for a complete documentation of
+   * this class contents.
    */
   template <typename E>
-  struct Pixel_Iterator :
-    public Iterator<E>,
+  struct Pixel_Iterator : public Iterator<E>,
     public GenPixel<E>
   {
     /*
-      typedef rvalue
-      typedef lvalue
+      typedef lvalue;
+
       lvalue operator* ();
-      rvalue operator* () const;
     */
   protected:
     Pixel_Iterator();
   };
 
+
 #ifndef MLN_INCLUDE_ONLY
 
   template <typename E>
   Pixel_Iterator<E>::Pixel_Iterator()
   {
-    typedef mln_value(E) value;
-    typedef mln_rvalue(E) rvalue;
     typedef mln_lvalue(E) lvalue;
-
-    lvalue (E::*m1)() = & E::operator*;
-    m1 = 0;
-    rvalue (E::*m2)() const = & E::operator*;
-    m2 = 0;
+    lvalue (E::*m)() = & E::operator*;
+    m = 0;
   }
 
 #endif // ! MLN_INCLUDE_ONLY
 
-
 } // end of namespace mln
 
 
Index: mln/core/concept/fast_image.hh
--- mln/core/concept/fast_image.hh	(revision 0)
+++ mln/core/concept/fast_image.hh	(revision 0)
@@ -0,0 +1,96 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction.  Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License.  This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_CORE_CONCEPT_FAST_IMAGE_HH
+# define MLN_CORE_CONCEPT_FAST_IMAGE_HH
+
+/*! \file mln/core/concept/fast_image.hh
+ * \brief Definition of the concept of mln::Fast_Image.
+ */
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/trait/pixter.hh>
+
+
+namespace mln
+{
+
+  /*! \brief Base class for implementation of fast image classes.
+   *
+   * \see mln::doc::Fast_Image for a complete documentation of this
+   * class contents.
+   */
+  template <typename E>
+  struct Fast_Image : public Image<E>
+  {
+    /*
+      unsigned border();
+
+      int offset(const dpoint& dp);
+      unsigned offset(const point& p);
+      point point_at_offset(unsigned o) const;
+
+      const value* buffer() const;
+     */
+
+  protected:
+    Fast_Image();
+  };
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+  template <typename E>
+  Fast_Image<E>::Fast_Image()
+  {
+    typedef mln_point(E)   point;
+    typedef mln_dpoint(E) dpoint;
+    typedef mln_value(E)   value;
+
+    typedef mln_fwd_pixter(E) fwd_pixter;
+    typedef mln_bkd_pixter(E) bkd_pixter;
+
+    int (E::*m1)(const dpoint&) = & E::offset;
+    m1 = 0;
+    unsigned (E::*m2)(const point&) = & E::offset;
+    m2 = 0;
+    point (E::*m3)(unsigned) const = & E::point_at_offset;
+    m3 = 0;
+    const value* (E::*m4)() const = & E::buffer;
+    m4 = 0;
+    unsigned (E::*m5)() const = & E::border;
+    m5 = 0;
+
+    // FIXME: how to check that qixter are defined when W is unknown!
+  }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CORE_CONCEPT_FAST_IMAGE_HH
Index: mln/core/concept/point_set.hh
--- mln/core/concept/point_set.hh	(revision 1024)
+++ mln/core/concept/point_set.hh	(working copy)
@@ -29,6 +29,7 @@
 # define MLN_CORE_CONCEPT_POINT_SET_HH
 
 /*! \file mln/core/concept/point_set.hh
+ *
  * \brief Definition of the concept of mln::Point_Set.
  */
 
@@ -50,7 +51,7 @@
     /*
       typedef point;
       typedef psite;
-      typedef piter;
+
       typedef fwd_piter;
       typedef bkd_piter;
 
@@ -127,7 +128,6 @@
     typedef mln_point(E) point;
     typedef mln_psite(E) psite;
 
-    typedef mln_piter(E)         piter;
     typedef mln_fwd_piter(E) fwd_piter;
     typedef mln_bkd_piter(E) bkd_piter;
     
Index: mln/core/concept/object.hh
--- mln/core/concept/object.hh	(revision 1024)
+++ mln/core/concept/object.hh	(working copy)
@@ -38,6 +38,7 @@
 
 # include <mln/core/macros.hh>
 # include <mln/core/contract.hh>
+# include <mln/core/internal/fixme.hh>
 
 
 /*! \namespace mln
Index: mln/core/concept/doc/image.hh
--- mln/core/concept/doc/image.hh	(revision 1024)
+++ mln/core/concept/doc/image.hh	(working copy)
@@ -121,10 +121,16 @@
        */
       typedef void psite;
 
-      /*! \brief Piter associated type.
-       * \invariant This type has to derive from mln::Piter.
+
+      /*! \brief Coordinate associated type.
+       */
+      typedef void coord;
+
+      /*! \brief Dpoint associated type.
+       * \invariant This type has to derive from mln::Dpoint.
        */
-      typedef void piter;
+      typedef void dpoint;
+
 
       /*! \brief Forward point iterator associated type.
        * \invariant This type has to derive from mln::Piter.
@@ -136,6 +142,7 @@
        */
       typedef void bkd_piter;
 
+
       /*! \brief Test if \p p belongs to the image domain. 
        *
        * \param[in] p A point site.
@@ -162,10 +169,6 @@
       std::size_t npoints() const;
     };
 
-    template <typename E>
-    struct Fast_Image : public Image<E>
-    {
-    };
 
   } // end of namespace mln::doc
 
Index: mln/core/concept/doc/genpoint.hh
--- mln/core/concept/doc/genpoint.hh	(revision 1024)
+++ mln/core/concept/doc/genpoint.hh	(working copy)
@@ -79,7 +79,7 @@
        *
        * \return A point address.
        */
-      const point* pointer() const;
+      const point* pointer_() const;
 
       /*! \brief Read-only access to the \p i-th coordinate value.
        *
Index: mln/core/concept/doc/pixel_iterator.hh
--- mln/core/concept/doc/pixel_iterator.hh	(revision 1024)
+++ mln/core/concept/doc/pixel_iterator.hh	(working copy)
@@ -25,8 +25,9 @@
 // reasons why the executable file might be covered by the GNU General
 // Public License.
 
-/*! \file mln/core/concept/doc/fast_iterator.hh
- * \brief This file documents the concept of mln::Fast_Iterator.
+/*! \file mln/core/concept/doc/pixel_iterator.hh
+ *
+ * \brief This file documents the concept of mln::Pixel_Iterator.
  */
 
 namespace mln
@@ -34,24 +35,29 @@
 
   namespace doc
   {
+
     /*! \brief Documentation class for mln::Iterator.
-     * \see mln::Fast_Iterator
+     * \see mln::Pixel_Iterator
      */
     template <typename E>
-    struct Fast_Iterator : public Iterator<E>
+    struct Pixel_Iterator : public Iterator<E>,
+			    public GenPixel<E>
     {
-      /*! \brief Dereference operator.
-       * return the current pixel
+      /*! \brief Type returned by the read-write dereference operator.
        */
-      rvalue operator* ();
+      typedef void lvalue;
 
       /*! \brief Dereference operator.
-       * return the current pixel
+       *
+       * \return The current pixel value; this value cannot be
+       * modified.
        */
       lvalue operator* () const;
+
     protected:
-      Fast_Iterator();
+      Pixel_Iterator();
     };
+
   } // end of namespace doc
 
 } // end of namespace mln
Index: mln/core/concept/doc/fast_image.hh
--- mln/core/concept/doc/fast_image.hh	(revision 0)
+++ mln/core/concept/doc/fast_image.hh	(revision 0)
@@ -0,0 +1,92 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction.  Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License.  This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+/*! \file mln/core/concept/doc/fast_image.hh
+ * \brief This file documents the concept of mln::Fast_Image.
+ */
+
+namespace mln
+{
+
+  namespace doc
+  {
+
+    /*! \brief Documentation class for mln::Fast_Image.
+     * \see mln::Fast_Image
+     */
+    template <typename E>
+    struct Fast_Image : public Image<E>
+    {
+
+      /*! \brief Give the border thickness.
+       *
+       * \pre The image has to be initialized.
+       */
+      unsigned border();
+
+      /*! \brief Give the offset corresponding to the delta-point \p
+       *  dp.
+       *
+       * \param[in] p A delta-point.
+       *
+       * \pre The image has to be initialized.
+       */
+      int offset(const dpoint& dp);
+
+
+      /*! \brief Give the offset of the point \p p.
+       *
+       * \param[in] p A point.
+       *
+       * \pre The image has to own the point \p p.
+       */
+      unsigned offset(const point& p);
+
+
+      /*! \brief Give the point at offset \p o.
+       *
+       * \param[in] p An offset.
+       *
+       * \pre The image has to be initialized.
+       * \pre o < ncells()
+       */
+      point point_at_offset(unsigned o) const;
+
+
+      /*! \brief Give a hook to the value buffer.
+       *
+       * \internal
+       *
+       * \pre The image has to be initialized.
+       */
+      const value* buffer() const;
+
+    };
+
+  } // end of namespace mln::doc
+
+} // end of namespace mln
Index: mln/core/concept/doc/point_set.hh
--- mln/core/concept/doc/point_set.hh	(revision 1024)
+++ mln/core/concept/doc/point_set.hh	(working copy)
@@ -50,10 +50,6 @@
        */
       typedef void psite;
 
-      /*! \brief Piter associated type.
-       */
-      typedef void piter;
-
       /*! \brief Forward Piter associated type.
        */
       typedef void fwd_piter;
Index: mln/core/concept/doc/genpixel.hh
--- mln/core/concept/doc/genpixel.hh	(revision 0)
+++ mln/core/concept/doc/genpixel.hh	(revision 0)
@@ -0,0 +1,78 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction.  Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License.  This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_CORE_CONCEPT_DOC_GENPIXEL_HH
+# define MLN_CORE_CONCEPT_DOC_GENPIXEL_HH
+
+/*! \file mln/core/concept/doc/genpixel.hh
+ * \brief This file documents the concept of mln::GenPixel.
+ */
+
+
+namespace mln
+{
+
+  namespace doc
+  {
+
+    /*! \brief Documentation class for mln::GenPixel.
+     *
+     * \see mln::GenPixel
+     */
+    template <typename E>
+    struct GenPixel
+    {
+
+      /// Value associated type.
+      typedef void value;
+
+      /// Read-only value associated type.
+      typedef void rvalue;
+
+
+      /*! \brief Give the value of this generalized pixel.
+       *
+       * \return A read-only value.
+       */
+      rvalue operator*() const;
+
+      /*! \brief Give a hook to the value address.
+       *
+       * This method allows for iterators to refer to a generalized
+       * pixel.
+       *
+       * \return A pointer to the value address.
+       */
+      value** address_() const;
+
+    protected:
+      GenPixel();
+    };
+
+  } // end of namespace mln::doc
+
+} // end of namespace mln
Index: mln/core/concept/genpixel.hh
--- mln/core/concept/genpixel.hh	(revision 1024)
+++ mln/core/concept/genpixel.hh	(working copy)
@@ -29,13 +29,11 @@
 # define MLN_CORE_CONCEPT_GENPIXEL_HH
 
 /*! \file mln/core/concept/genpixel.hh
+ *
  * \brief Definition of the concept of mln::Genpixel.
  */
 
 # include <mln/core/concept/object.hh>
-
-# include <mln/core/macros.hh>
-# include <mln/core/contract.hh>
 # include <mln/core/internal/force_exact.hh>
 
 
@@ -58,75 +56,29 @@
   template <typename E>
   struct GenPixel
   {
-
     /*
-      typedef rvalue;
       typedef value;
-      // FIXME: lvalue?
-
-
-      // FIXME: Inactivated:
-      //  typedef ima; // not const!
-      //  typedef psite;
-      //  const ima& image() const;
-      //  const psite& site() const; // FIXME ou cpy
-      //  value* address();
+      typedef rvalue;
 
       rvalue operator*() const;
-      lvalue operator*();
-
-      const value*& address() const;
+      value** address_() const;
     */
-
   protected:
     GenPixel();
-
   };
 
-  /*! \brief Print a generalized pixel \p p into the output stream \p
-   *  ostr.
-   *
-   * \param[in,out] ostr An output stream.
-   * \param[in] p A generalized pixel.
-   *
-   * \return The modified output stream \p ostr.
-   *
-   * \relates mln::GenPixel
-   */
-  template <typename P>
-  std::ostream& operator<<(std::ostream& ostr, const GenPixel<P>& pxl);
-
-
 
 # ifndef MLN_INCLUDE_ONLY
 
-
   template <typename E>
   GenPixel<E>::GenPixel()
   {
     typedef mln_value(E) value;
     typedef mln_rvalue(E) rvalue;
-
-    // FIXME: Inactivated:
-
-//     typedef mln_ima(E) ima;
-//     typedef mln_psite(E) psite;
-//     const ima& (E::*m1)() const = & E::image;
-//     m1 = 0;
-//     const psite& (E::*m2)() const = & E::site;
-//     m2 = 0;
-
-    rvalue (E::*m3)() const = & E::operator*;
-    m3 = 0;
-//     const value *const & (E::*m4)() const = & E::address;
-//     m4 = 0;
-  }
-
-
-  template <typename P>
-  std::ostream& operator<<(std::ostream& ostr, const GenPixel<P>& pxl)
-  {
-    return ostr << pxl.psite() << '@' << & pxl.image();
+    rvalue (E::*m1)() const = & E::operator*;
+    m1 = 0;
+    value** (E::*m2)() const = & E::address_;
+    m2 = 0;
   }
 
 # endif // ! MLN_INCLUDE_ONLY
Index: mln/core/tags.hh
--- mln/core/tags.hh	(revision 0)
+++ mln/core/tags.hh	(revision 0)
@@ -0,0 +1,50 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction.  Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License.  This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_CORE_TAGS_HH
+# define MLN_CORE_TAGS_HH
+
+/*! \file mln/core/tags.hh
+ *
+ * \brief Define a set of tags for images types.
+ */
+
+
+namespace mln
+{
+
+  namespace tag
+  {
+
+    // FIXME: ...
+
+  } // end of namespace mln::core
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CORE_TAGS_HH
Index: mln/core/vline2d.hh
--- mln/core/vline2d.hh	(revision 1024)
+++ mln/core/vline2d.hh	(working copy)
@@ -70,7 +70,7 @@
     /*! \brief Piter type to browse a vline such as: "for each row
      * (decreasing), for each column (decreasing)."
      */
-    typedef dpoints_fwd_piter<dpoint2d> bkd_qiter; // FIXME: bkd!!!
+    typedef internal::fixme bkd_qiter;
 
     /*! \brief Same as fwd_qiter.
      */
Index: mln/core/image2d_b.hh
--- mln/core/image2d_b.hh	(revision 1024)
+++ mln/core/image2d_b.hh	(working copy)
@@ -39,8 +39,12 @@
 
 # include <mln/border/thickness.hh>
 # include <mln/fun/all.hh>
-# include <mln/core/pixter2d_b.hh>
-# include <mln/core/dpoints_pixter.hh>
+
+
+// FIXME:
+
+// # include <mln/core/pixter2d_b.hh>
+// # include <mln/core/dpoints_pixter.hh>
 
 
 namespace mln
@@ -64,18 +68,19 @@
     typedef dpoint2d dpoint;
     typedef mln_fwd_piter(box2d) fwd_piter;
     typedef mln_bkd_piter(box2d) bkd_piter;
-    typedef fwd_piter piter;
     // end of warning
 
-    /// Forward pixel iterator associated to image2d
-    typedef fwd_pixter2d_b<T> fwd_pixter;
 
-    /// Foward pixel iterator on dpoints assoicated to image 2d
-    typedef dpoints_pixter< image2d_b<T> > fwd_qixter;
+    // FIXME:
 
+//     /// Forward pixel iterator associated to image2d
+//     typedef fwd_pixter2d_b<T> fwd_pixter;
 
-    typedef fwd_pixter pixter;
-    typedef fwd_qixter qixter;
+//     /// Foward pixel iterator on dpoints assoicated to image 2d
+//     typedef dpoints_pixter< image2d_b<T> > fwd_qixter;
+
+//     typedef fwd_pixter pixter;
+//     typedef fwd_qixter qixter;
 
 
     /// Value associated type.
@@ -153,14 +158,17 @@
 
     /// Fast Image method
 
-    /// Return the offset corresponding to the dpoint \p dp.
+    /// Give the offset corresponding to the delta-point \p dp.
     int offset(const dpoint2d& dp);
 
-    /// Return the offset corresponding to the dpoint \p p.
-    int offset(const point2d& p);
+    /// Give the offset corresponding to the point \p p.
+    unsigned offset(const point2d& p);
+
+    /// Give the point corresponding to the offset \p o.
+    point2d point_at_offset(unsigned o) const;
 
-    /// Return the point corresponding to the offset \p offset.
-    point2d point_at_offset(int offset);
+    /// Give a hook to the value buffer.
+    const T* buffer() const;
 
 
   private:
@@ -340,6 +348,46 @@
     deallocate_();
   }
 
+  template <typename T>
+  const T*
+  image2d_b<T>::buffer() const
+  {
+    mln_precondition(this->has_data());
+    return buffer_;
+  }
+
+  template <typename T>
+  int
+  image2d_b<T>::offset(const dpoint2d& dp)
+  {
+    mln_precondition(this->has_data());
+    int o = dp[0] * vb_.len(1) + dp[1];
+    return o;
+  }
+
+  template <typename T>
+  unsigned
+  image2d_b<T>::offset(const point2d& p)
+  {
+    mln_precondition(this->owns_(p));
+    unsigned o = & this->operator()(p) - this->buffer_;
+    mln_postcondition(p = point_at_offset(o));
+    return o;
+  }
+
+  template <typename T>
+  point2d
+  image2d_b<T>::point_at_offset(unsigned o) const
+  {
+    mln_precondition(o < ncells());
+    mln_precondition(this->has_data());
+    point2d p = make::point2d(o / vb_.len(1) + vb_.min_row(),
+			      o % vb_.len(1) + vb_.min_col());
+    mln_postcondition(& this->operator()(p) = this->buffer_ + o);
+    return p;
+  }
+
+
   // private
 
   template <typename T>
@@ -388,28 +436,52 @@
       }
   }
 
-  template <typename T>
-  int
-  image2d_b<T>::offset(const dpoint2d& dp)
+# endif // ! MLN_INCLUDE_ONLY
+
+} // end of namespace mln
+
+
+
+# include <mln/core/trait/pixter.hh>
+# include <mln/core/dpoints_pixter.hh>
+# include <mln/core/pixter2d_b.hh>
+
+
+namespace mln
+{
+
+  namespace trait
   {
-    return dp[0] * vb_.len(1) + dp[1];
-  }
+
+    // pixter
 
   template <typename T>
-  int
-  image2d_b<T>::offset(const point2d& p)
+    struct fwd_pixter< image2d_b<T> >
   {
-    return p[0] * vb_.len(1) + p[1];
-  }
+      typedef fwd_pixter2d_b< image2d_b<T> > ret;
+    };
 
   template <typename T>
-  point2d
-  image2d_b<T>::point_at_offset(int offset)
+    struct bkd_pixter< image2d_b<T> >
   {
-    return point2d(offset / (vb_.len(1) + 1), offset % (vb_.len(1) + 1));
-  }
+      typedef internal::fixme ret;
+    };
 
-# endif // ! MLN_INCLUDE_ONLY
+    // qixter
+
+    template <typename T, typename W>
+    struct fwd_qixter< image2d_b<T>, W >
+    {
+      typedef dpoints_fwd_pixter< image2d_b<T> > ret;
+    };
+
+    template <typename T, typename W>
+    struct bkd_qixter< image2d_b<T>, W >
+    {
+      typedef internal::fixme ret;
+    };
+
+  } // end of namespace mln::trait
 
 } // end of namespace mln
 
Index: mln/metal/none.hh
--- mln/metal/none.hh	(revision 0)
+++ mln/metal/none.hh	(revision 0)
@@ -0,0 +1,57 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction.  Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License.  This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_CORE_METAL_NONE_HH
+# define MLN_CORE_METAL_NONE_HH
+
+/*! \file mln/core/metal/none.hh
+ *
+ * \brief Definition of a type that means "none".
+ */
+
+
+namespace mln
+{
+
+  namespace metal
+  {
+
+
+    /*! \brief Type meaning "none".
+     *
+     * This type is for use when a type is required and none can be
+     * provided.
+     */
+    struct none;
+    
+
+  } // end of namespace mln::metal
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CORE_METAL_NONE_HH
Index: mln/level/fast_median.hh
--- mln/level/fast_median.hh	(revision 1024)
+++ mln/level/fast_median.hh	(working copy)
@@ -36,7 +36,6 @@
 # include <mln/core/concept/image.hh>
 # include <mln/core/window2d.hh>
 # include <mln/accu/median.hh>
-# include <ostream>
 
 
 namespace mln
@@ -85,24 +84,20 @@
 	  win_bot  = win - (win + up),
 	  win_top = (win + up) - win;
 
-
-
-	//Fixme bug
-	point2d p;
-
 	accu::median_on<mln_value(I)> med;
 
 	// initialization
 
-	p = input.domain().pmin() + up;
-	mln_qixter(I)
-	  q_fp(win_fwd_plus, p, input), q_fm(win_fwd_minus, p, input),
-	  q_bp(win_bkd_plus, p, input), q_bm(win_bkd_minus, p, input),
-	  q_top(win_top, p, input), q_bot(win_bot, p, input);
+	point2d p = input.domain().pmin() + up;
+
+	mln_qixter(I, window2d)
+	  q_fp(input, win_fwd_plus, p), q_fm(input, win_fwd_minus, p),
+	  q_bp(input, win_bkd_plus, p), q_bm(input, win_bkd_minus, p),
+	  q_top(input, win_top, p), q_bot(input, win_bot, p);
 
 	med.init();
 	{
-	  mln_qixter(I) q(win, p, input);
+	  mln_qixter(I, W) q(input, win, p);
 	  for_all(q)
 	    med.take(*q);
 	}
Index: mln/level/median.hh
--- mln/level/median.hh	(revision 1024)
+++ mln/level/median.hh	(working copy)
@@ -160,21 +160,22 @@
       template <typename I, typename O>
       void median(const I& input, const hline2d& win, O& output)
       {
-	const int
+	typedef mln_coord(I) coord;
+	const coord
 	  max_row = input.max_row(),
 	  min_col = input.min_col(),
 	  max_col = input.max_col();
-	const unsigned half = win.length() / 2;
+	const coord half = win.length() / 2;
 
 	point2d p;
-	int& row = p.row();
-	int& col = p.col();
+	coord& row = p.row();
+	coord& col = p.col();
 
 	accu::median_on<mln_value(I)> med;
 
 	for (row = input.min_row(); row <= max_row; ++row)
 	  {
-	    int ct, cu;
+	    coord ct, cu;
 
 	    // initialization (before first point of the row)
 	    med.init();
Index: mln/canvas/sbrowsing.hh
--- mln/canvas/sbrowsing.hh	(revision 1024)
+++ mln/canvas/sbrowsing.hh	(working copy)
@@ -45,12 +45,18 @@
     /*! FIXME: Doc!
      *
      *
-     * F should be
-     * {
-     *   input;  p;  --- attributes
-     *   void init();
-     *   void down(); void fwd(); void bkd(); --- methods
-     * }
+     * F shall feature: \n
+     * { \n
+     *   --- as attributes: \n
+     *   input; \n
+     *   p; \n
+     *   --- as methods: \n
+     *   void init(); \n
+     *   void down(); \n
+     *   void fwd(); \n
+     *   void bkd(); \n
+     * } \n
+     *
      */
     template <typename F>
     void sbrowsing(F& f);
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                        https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from  Nicolas Ballas  <ballas(a)lrde.epita.fr>
	Repair lineary pixel iterator.
	* mln/core/pixter2d_b.hh: Adapt pixter2d_b to the new pixel iterator hierachy.
	* mln/core/internal/pixel_iterator_base.hh: Fix dead code.
	* mln/core/internal/lineary_pixel_iterator_base.hh: New factorization class.
 internal/lineary_pixel_iterator_base.hh |  109 ++++++++++++++++++++++++++++++++
 internal/pixel_iterator_base.hh         |  101 +----------------------------
 pixter2d_b.hh                           |   31 +++++----
 3 files changed, 131 insertions(+), 110 deletions(-)
Index: mln/core/pixter2d_b.hh
--- mln/core/pixter2d_b.hh	(revision 1023)
+++ mln/core/pixter2d_b.hh	(working copy)
@@ -28,7 +28,7 @@
 #ifndef MLN_CORE_PIXTER2D_B_HH
 # define MLN_CORE_PIXTER2D_B_HH
 
-# include <mln/core/internal/pixel_iterator_base.hh>
+# include <mln/core/internal/lineary_pixel_iterator_base.hh>
 # include <mln/core/point2d.hh>
 # include <iostream>
 
@@ -49,8 +49,9 @@
 
   template <typename T>
   class fwd_pixter2d_b :
-    public internal::pixel_iterator_base_< fwd_pixter2d_b<T>, image2d_b<T> >
+    public internal::lineary_pixel_iterator_base_<image2d_b<T>, fwd_pixter2d_b<T> >
   {
+    typedef internal::lineary_pixel_iterator_base_<image2d_b<T>, fwd_pixter2d_b<T> > super;
   public:
     /// Image pixel value type.
     typedef mln_value(image2d_b<T>) value;
@@ -59,37 +60,41 @@
      *
      * \param[in] ima   Image to iterate.
      */
-    fwd_pixter2d_b(image2d_b<T>& ima);
-    /// Move the iterator to the next elements
+    fwd_pixter2d_b(image2d_b<T>& image);
+    /// Move the iterator on the next element.
     void next_();
 
   private:
+    /// Size of the image border.
     unsigned border_size_;
+    /// Row offset.
     unsigned row_offset_;
+    /// End of a row.
     value *eor_;
   };
 
 #ifndef MLN_INCLUDE_ONLY
 
   template <typename T>
-  fwd_pixter2d_b<T>::fwd_pixter2d_b(image2d_b<T>& ima) :
-    border_size_(ima.border()),
-    row_offset_((ima.domain().pmax()[1] - ima.domain().pmin()[1])
+  fwd_pixter2d_b<T>::fwd_pixter2d_b(image2d_b<T>& image) :
+    super(image),
+    border_size_(image.border()),
+    row_offset_((image.domain().pmax()[1] - image.domain().pmin()[1])
 		+ 2 * border_size_ + 1)
   {
-    this->start_ = &ima(ima.domain().pmin());
-    this->eor_ = &ima(make::point2d(ima.domain().pmin()[0], ima.domain().pmax()[1])) + 1;
-    this->eoi_ = &ima(ima.domain().pmax()) + 1;
+    this->start_ = &image(image.domain().pmin());
+    this->eor_ = &image(make::point2d(image.domain().pmin()[0], image.domain().pmax()[1])) + 1;
+    this->eoi_ = &image(image.domain().pmax()) + 1;
   }
 
   template <typename T>
   void fwd_pixter2d_b<T>::next_()
   {
-    ++(this->current_);
+    ++(this->value_ptr_);
 
-    if (this->current_ == this->eor_ && this->current_ != this->eoi_)
+    if (this->value_ptr_ == this->eor_ && this->value_ptr_ != this->eoi_)
     {
-      this->current_ += 2 * this->border_size_;
+      this->value_ptr_ += 2 * this->border_size_;
       this->eor_ += this->row_offset_;
     }
   }
Index: mln/core/internal/pixel_iterator_base.hh
--- mln/core/internal/pixel_iterator_base.hh	(revision 1023)
+++ mln/core/internal/pixel_iterator_base.hh	(working copy)
@@ -93,12 +93,12 @@
 
     protected:
 
-      /// Current pixel / value
-      value* value_ptr_;
-
       /// Image associated to the iterator
       I& image_;
 
+      /// Current pixel / value
+      value* value_ptr_;
+
       // FIXME: Inactivated:
 
 //       /// Psite of the pixel
@@ -174,101 +174,8 @@
 //       return p_;
 //     }
 
-
-
-
-
-// FIXME: Dead code
-// #################
-
-
-
-//     /*! \brief pixel_iterator_base_ class
-//      */
-//     template <typename E, typename I>
-//     class pixel_iterator_base_ : public Pixel_Iterator<E>
-//     {
-//     public:
-//       /// I pixel value type.
-//       typedef mln_value(I) value;
-//       /// I pixel rvalue type.
-//       typedef mln_value(I)& rvalue;
-//       /// I pixel lvalue type
-//       typedef mln_value(I) lvalue;
-
-//       // Go to the beginning of the image.
-//       void start();
-//       // Go on the next element.
-//       void next_();
-//       // Invalidate the iterator.
-//       void invalidate();
-//       // Is the iterator referencing a correct position in the image?
-//       bool is_valid() const;
-
-
-//       // Return the current pixel.
-//       rvalue operator* ();
-//       lvalue operator* () const;
-
-//     protected:
-//       // beginning of the image
-//       value* start_;
-//       // end of the image
-//       value* eoi_;
-//       // current position in the image
-//       value* current_;
-//       // End of Factoriasable
-
-//       pixel_iterator_base_();
-//     };
-
-// #ifndef MLN_INCLUDE_ONLY
-
-//     template <typename E, typename I>
-//     pixel_iterator_base_<E,I>::pixel_iterator_base_()
-//     {
-//     }
-
-//     template <typename E, typename I>
-//     void pixel_iterator_base_<E,I>::start()
-//     {
-//       current_ = start_;
-//     }
-
-//     template <typename E, typename I>
-//     void pixel_iterator_base_<E,I>::next_()
-//     {
-//       ++current_;
-//     }
-
-//     template <typename E, typename I>
-//     void pixel_iterator_base_<E,I>::invalidate()
-//     {
-//       current_ = eoi_;
-//     }
-
-//     template <typename E, typename I>
-//     bool pixel_iterator_base_<E,I>::is_valid() const
-//     {
-//       return (current_ != eoi_);
-//     }
-
-//     template <typename E, typename I>
-//     typename pixel_iterator_base_<E,I>::rvalue
-//     pixel_iterator_base_<E,I>::operator*()
-//     {
-//       return *current_;
-//     }
-
-
-//     template <typename E, typename I>
-//     typename pixel_iterator_base_<E,I>::lvalue
-//     pixel_iterator_base_<E,I>::operator*() const
-//     {
-//       return *current_;
-//     }
-
 #endif // ! MLN_INCLUDE_ONLY
+
   } // end of namespace internal
 
 } // end of namespace mln
Index: mln/core/internal/lineary_pixel_iterator_base.hh
--- mln/core/internal/lineary_pixel_iterator_base.hh	(revision 0)
+++ mln/core/internal/lineary_pixel_iterator_base.hh	(revision 0)
@@ -0,0 +1,109 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction.  Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License.  This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_CORE_INTERNAL_LINEARY_PIXEL_ITERATOR_BASE_HH
+# define MLN_CORE_INTERNAL_LINEARY_PIXEL_ITERATOR_BASE_HH
+
+/*! \file mln/core/internal/lineary_pixel_iterator_base.hh
+ *
+ * \brief Code factorization for lineary pixel iterator classes.
+ */
+
+# include <mln/core/internal/pixel_iterator_base.hh>
+
+namespace mln
+{
+
+  namespace internal
+  {
+
+    /*! \brief lineary_pixel_iterator_base_ class
+     *
+     */
+    template <typename I, typename E>
+    class  lineary_pixel_iterator_base_ : public pixel_iterator_base_<I, E>
+    {
+      typedef pixel_iterator_base_<I, E> super;
+    public:
+      /// Image pixel value type.
+      typedef mln_value(I) value;
+
+      /// Go to the beginning of the image.
+      void start();
+      /// Invalidate the iterator.
+      void invalidate();
+      /// Is the iterator referencing a correct position in the image?
+      bool is_valid() const;
+
+
+    protected:
+      /// beginning of the image
+      value* start_;
+      /// end of the image
+      value* eoi_;
+
+      /// Constructor
+      lineary_pixel_iterator_base_(I& image);
+    };
+
+#ifndef MLN_INCLUDE_ONLY
+
+    template <typename I, typename E>
+    lineary_pixel_iterator_base_<I, E>::lineary_pixel_iterator_base_(I& image)
+       : super(image)
+    {
+    }
+
+    template <typename I, typename E>
+    void
+    lineary_pixel_iterator_base_<I, E>::start()
+    {
+      this->value_ptr_ = start_;
+    }
+
+    template <typename I, typename E>
+    void
+    lineary_pixel_iterator_base_<I, E>::invalidate()
+    {
+      this->value_ptr_ = eoi_;
+    }
+
+    template <typename I, typename E>
+    bool
+    lineary_pixel_iterator_base_<I, E>::is_valid() const
+    {
+      return (this->value_ptr_ != eoi_);
+    }
+
+#endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace internal
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CORE_INTERNAL_LINEARY_PIXEL_ITERATOR_BASE_HH
                    
                  
                  
                          
                            
                            2
                            
                          
                          
                            
                            1
                            
                          
                          
                            
    
                          
                        
                    
                    
                        https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from  Thierry Geraud  <thierry.geraud(a)lrde.epita.fr>
	Fix pixel iterators on sets of dpoints.
	* tests/fast_median.cc (test): New.
	* tests/naive_median.cc: Update.
	* mln/debug/iota.hh: New.
	* mln/core/pixel.hh (value_ptr_): New.
	* mln/core/dpoints_piter.hh (center_point): New.
	(update_p_): Rename as...
	(update): ...this.
	* mln/core/concept/genpixel.hh: Inactivate some code.
	* mln/core/dpoints_pixter.hh: Update.
	* mln/core/internal/pixel_iterator_base.hh: Clean-up.
	* mln/level/was.hmedian.hh (hmedian): Move...
	* mln/level/was.median.hh: ...here.
	* mln/level/was.hmedian.hh: Remove.
	* mln/level/fast_median.hh: Clean-up.
	Contents
 mln/core/concept/genpixel.hh             |   36 +++--
 mln/core/dpoints_piter.hh                |   40 ++++-
 mln/core/dpoints_pixter.hh               |  120 +++++++++++++---
 mln/core/internal/pixel_iterator_base.hh |  223 +++++++++++++++++--------------
 mln/core/pixel.hh                        |   20 --
 mln/debug/iota.hh                        |   69 +++++++++
 mln/level/fast_median.hh                 |   15 --
 mln/level/was.median.hh                  |   61 ++++++++
 tests/fast_median.cc                     |   47 ++++++
 tests/naive_median.cc                    |    4 
 10 files changed, 468 insertions(+), 167 deletions(-)
Index: tests/fast_median.cc
--- tests/fast_median.cc	(revision 1022)
+++ tests/fast_median.cc	(working copy)
@@ -37,9 +37,40 @@
 #include <mln/io/save_pgm.hh>
 
 #include <mln/value/int_u.hh>
+#include <mln/debug/iota.hh>
+#include <mln/debug/println.hh>
 #include <mln/level/fast_median.hh>
-#include <mln/level/approx/median.hh>
 
+#include <mln/core/dpoints_pixter.hh>
+#include <mln/core/pixel.hh>
+
+
+namespace mln
+{
+
+  template <typename I, typename W>
+  void test(I& input, const W& win)
+  {
+    mln_point(I) p;
+    p.row() = p.col() = 1;
+
+    {
+      mln_qixter(I) qix(win, p, input);
+      for_all(qix)
+	std::cout << *qix << ' ';
+      std::cout << " :  " << qix.center_value() << std::endl;
+    }
+
+    {
+      pixel<I> pix(input, p);
+      mln_qixter(I) qix(win, pix, input);
+      for_all(qix)
+	std::cout << *qix << ' ';
+      std::cout << " :  " << qix.center_value() << std::endl;
+    }
+  }
+
+}
 
 
 
@@ -48,6 +79,17 @@
   using namespace mln;
   using value::int_u8;
 
+//   {
+//     rectangle2d rect(3, 3);
+//     border::thickness = 4;
+//     image2d_b<int_u8> ima(3, 3);
+//     debug::iota(ima);
+//     debug::println(ima);
+//     test(ima, rect);
+//   }
+
+
+  {
   rectangle2d rect(51, 51);
   border::thickness = 52;
 
@@ -57,7 +99,6 @@
 
   level::fast_median(lena, rect, out);
   io::save_pgm(out, "out.pgm");
+  }
 
-//   level::approx::median(lena, rec, out);
-//   io::save_pgm(out, "outa.pgm");
 }
Index: tests/naive_median.cc
--- tests/naive_median.cc	(revision 1022)
+++ tests/naive_median.cc	(working copy)
@@ -46,8 +46,8 @@
 
 int main()
 {
-  rectangle2d rec(8, 8);
-  border::thickness = 9;
+  rectangle2d rec(51, 51);
+  border::thickness = 52;
 
   image2d_b<int_u8>
     lena = io::load_pgm("../img/lena.pgm"),
Index: mln/debug/iota.hh
--- mln/debug/iota.hh	(revision 0)
+++ mln/debug/iota.hh	(revision 0)
@@ -0,0 +1,69 @@
+// 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_DEBUG_IOTA_HH
+# define MLN_DEBUG_IOTA_HH
+
+/*! \file mln/debug/iota.hh
+ *
+ * \brief FIXME
+ */
+
+# include <mln/core/concept/image.hh>
+
+
+namespace mln
+{
+
+  namespace debug
+  {
+
+    /// FIXME
+    template <typename I>
+    void iota(Image<I>& input);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+    template <typename I>
+    void iota(Image<I>& input_)
+    {
+      unsigned i = 0;
+      I& input = exact(input_);
+      mln_piter(I) p(input.domain());
+      for_all(p)
+	input(p) = ++i;
+      }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace mln::debug
+
+} // end of namespace mln
+
+
+#endif // ! MLN_DEBUG_IOTA_HH
Index: mln/core/pixel.hh
--- mln/core/pixel.hh	(revision 1022)
+++ mln/core/pixel.hh	(working copy)
@@ -76,15 +76,15 @@
     psite& site();
 
     mln_rvalue(I) operator*() const;
-    typename pixel_lvalue<I>::ret operator*();
+    mln_lvalue(I) operator*();
 
-    const value* address() const;
-    value* address();
+    value** address() const;
 
   protected:
 
     I& ima_;
     psite p_;
+    value* value_ptr_;
   };
 
 
@@ -101,6 +101,7 @@
     : ima_(image),
       p_(p)
   {
+    value_ptr_ = & ima_(p);
   }
 
   template <typename I>
@@ -132,24 +133,17 @@
   }
 
   template <typename I>
-  typename pixel_lvalue<I>::ret
+  mln_lvalue(I)
   pixel<I>::operator*()
   {
     return ima_(p_);
   }
 
   template <typename I>
-  const mln_value(I)*
+  mln_value(I)**
   pixel<I>::address() const
   {
-    return & ima_(p_);
-  }
-
-  template <typename I>
-  mln_value(I)*
-  pixel<I>::address()
-  {
-    return & ima_(p_);
+    return (mln_value(I)**)(& this->value_ptr_);
   }
 
 # endif // ! MLN_INCLUDE_ONLY
Index: mln/core/dpoints_piter.hh
--- mln/core/dpoints_piter.hh	(revision 1022)
+++ mln/core/dpoints_piter.hh	(working copy)
@@ -71,13 +71,13 @@
      * \param[in] p_ref Center point to iterate around.
      */
     template <typename Dps, typename Pref>
-    dpoints_fwd_piter(const Dps& dps,
+    dpoints_fwd_piter(const Dps& dps, // FIXME: explicitly set_of_<D>?
 		      const GenPoint<Pref>& p_ref);
 
     /// Convertion to point.
     operator mln_point(D) () const;
 
-    /// Address of the point.
+    /// Address of the point this iterator designates.
     const point* pointer() const;
 
     /// Test the iterator validity.
@@ -95,13 +95,20 @@
     /// Give the i-th coordinate.
     coord operator[](unsigned i) const;
 
+    /// The point around which this iterator moves.
+    const point& center_point() const;
+
+    /// Force this iterator to update its location to take into
+    /// account that its center point may have moved. 
+    void update();
+
   private:
     const std::vector<D>& dps_;
-    const point& p_ref_;
+    const point& p_ref_; // reference point (or "center point")
 
     unsigned i_;
-    point p_;
-    void update_p_();
+    point p_; // location of this iterator; p_ makes this iterator be
+	      // itself a potential center point (Cf. the pointer() method).
   };
 
 
@@ -120,7 +127,7 @@
   template <typename D>
   dpoints_fwd_piter<D>::operator mln_point(D) () const
   {
-    assert(is_valid());
+    mln_precondition(is_valid());
     return p_;
   }
 
@@ -150,7 +157,7 @@
   dpoints_fwd_piter<D>::start()
   {
     i_ = 0;
-    update_p_();
+    update();
   }
 
   template <typename D>
@@ -158,12 +165,19 @@
   dpoints_fwd_piter<D>::next_()
   {
     ++i_;
-    update_p_();
+    update();
+  }
+
+  template <typename D>
+  const mln_point(D)&
+  dpoints_fwd_piter<D>::center_point() const
+  {
+    return p_ref_;
   }
 
   template <typename D>
   void
-  dpoints_fwd_piter<D>::update_p_()
+  dpoints_fwd_piter<D>::update()
   {
     if (is_valid())
       p_ = p_ref_ + dps_[i_];
@@ -173,6 +187,14 @@
   mln_coord(D)
   dpoints_fwd_piter<D>::operator[](unsigned i) const
   {
+    mln_precondition(is_valid());
+
+    // below we test that no update is required
+    // meaning that p_ref_ has not moved or that
+    // the user has explicitly called update()
+    mln_precondition(p_ref_ + dps_[i_] = p_);
+    // FIXME: Explain this issue in the class documentation...
+
     return p_[i];
   }
 
Index: mln/core/concept/genpixel.hh
--- mln/core/concept/genpixel.hh	(revision 1022)
+++ mln/core/concept/genpixel.hh	(working copy)
@@ -60,17 +60,22 @@
   {
 
     /*
-      typedef ima; // not const!
-      typede  psite;
       typedef rvalue;
       typedef value;
+      // FIXME: lvalue?
 
-      const ima& image() const;
-      const psite& site() const; // FIXME ou cpy
+
+      // FIXME: Inactivated:
+      //  typedef ima; // not const!
+      //  typedef psite;
+      //  const ima& image() const;
+      //  const psite& site() const; // FIXME ou cpy
+      //  value* address();
 
       rvalue operator*() const;
+      lvalue operator*();
 
-      const value* address() const;
+      const value*& address() const;
     */
 
   protected:
@@ -89,7 +94,7 @@
    * \relates mln::GenPixel
    */
   template <typename P>
-  std::ostream& operator<<(std::ostream& ostr, const GenPixel<P>& p);
+  std::ostream& operator<<(std::ostream& ostr, const GenPixel<P>& pxl);
 
 
 
@@ -101,17 +106,20 @@
   {
     typedef mln_value(E) value;
     typedef mln_rvalue(E) rvalue;
-    typedef mln_ima(E) ima;
-    typedef mln_psite(E) psite;
 
-    const ima& (E::*m1)() const = & E::image;
-    m1 = 0;
-    const psite& (E::*m2)() const = & E::site;
-    m2 = 0;
+    // FIXME: Inactivated:
+
+//     typedef mln_ima(E) ima;
+//     typedef mln_psite(E) psite;
+//     const ima& (E::*m1)() const = & E::image;
+//     m1 = 0;
+//     const psite& (E::*m2)() const = & E::site;
+//     m2 = 0;
+
     rvalue (E::*m3)() const = & E::operator*;
     m3 = 0;
-    const value* (E::*m4)() const = & E::address;
-    m4 = 0;
+//     const value *const & (E::*m4)() const = & E::address;
+//     m4 = 0;
   }
 
 
Index: mln/core/dpoints_pixter.hh
--- mln/core/dpoints_pixter.hh	(revision 1022)
+++ mln/core/dpoints_pixter.hh	(working copy)
@@ -35,6 +35,7 @@
 
 namespace mln
 {
+
   /*! \brief A generic forward iterator on image pixel of a windows and of
    *  neighborhoods.
    *
@@ -45,6 +46,7 @@
   {
     typedef typename internal::pixel_iterator_base_< I, dpoints_pixter<I> > super;
   public:
+
     /// Image pixel value
     typedef mln_value(I) value;
     /// Image pixel rvalue
@@ -58,73 +60,149 @@
      * \param[in] p_ref Center point to iterate around.
      * \param[in] ima   Image to iterate.
      */
-    template <typename Dps>
-    dpoints_pixter(const Dps& dps, const typename I::psite& p_ref,I& ima);
+    template <typename Dps, typename Pref>
+    dpoints_pixter(const Dps& dps,
+		   const GenPoint<Pref>& p_ref,
+		   I& image);
+
+    template <typename Dps, typename Pref>
+    dpoints_pixter(const Dps& dps,
+		   const GenPixel<Pref>& p_ref,
+		   I& image);
 
-    /// Set the iterator at the start.
+    /// Start an iteration.
     void start();
+
     /// Go to the next pixel.
     void next_();
+
     /// Invalidate the iterator.
     void invalidate();
-    ///  Is the iterator valid?
+
+    /// Test the iterator validity.
     bool is_valid() const;
 
+    /// Force this iterator to update its location to take into
+    /// account that its center point may have moved. 
+    void update();
+
+    /// The value around which this iterator moves.
+    const value& center_value() const;
+
   private:
+
     /// offset of each dpoints
     std::vector<int> offset_;
+
     /// current offset
-    std::vector<int>::iterator i_;
-    /// reference pixel in the image
-    value* pixref_;
+    int i_;
+
+    /// reference pixel / point in the image
+    value** value_ref_;
+    //    or:
+    const mln_point(I)* p_ref_;
+
+
+    template <typename Dps>
+    void init_(const Dps& dps);
   };
 
 
 #ifndef MLN_INCLUDE_ONLY
 
   template <typename I>
+  template <typename Dps, typename Pref>
+  dpoints_pixter<I>::dpoints_pixter(const Dps& dps,
+				    const GenPoint<Pref>& p_ref,
+				    I& image)
+    : super(image)
+  {
+    p_ref_ = internal::force_exact<Pref>(p_ref).pointer();
+    value_ref_ = 0;
+    init_(dps);
+  }
+
+
+  template <typename I>
+  template <typename Dps, typename Pref>
+  dpoints_pixter<I>::dpoints_pixter(const Dps& dps,
+				    const GenPixel<Pref>& p_ref,
+				    I& image)
+    : super(image)
+  {
+    p_ref_ = 0;
+    value_ref_ = internal::force_exact<Pref>(p_ref).address();
+    init_(dps);
+  }
+
+  template <typename I>
+  const mln_value(I)&
+  dpoints_pixter<I>::center_value() const
+  {
+    mln_invariant(value_ref_ != 0 || p_ref_ != 0);
+    if (p_ref_)
+      return image_(*p_ref_);
+    else
+      return ** value_ref_;
+  }
+
+  template <typename I>
   template <typename Dps>
-  dpoints_pixter<I>::dpoints_pixter(const Dps& dps, const typename I::psite& ref, I& ima) : super(ima)
+  void
+  dpoints_pixter<I>::init_(const Dps& dps)
   {
-    this->p_ = ref;
-    pixref_ = &ima(ref);
-    for (typename std::vector<typename I::dpoint>::const_iterator it = dps.vec().begin();
-	 it != dps.vec().end();
-	 ++it)
-      offset_.push_back(ima.offset(*it));
+    for (unsigned i = 0; i < dps.nelements(); ++i)
+      offset_.push_back(this->image_.offset(dps.element(i)));
+
+    if (dps.nelements() > 1)
+      for (unsigned i = dps.nelements() - 1; i > 0; --i)
+	offset_[i] -= offset_[i - 1];
+
+    // offset_[0] is absolute; other offsets are relative.
+    invalidate();
   }
 
+  template <typename I>
+  void dpoints_pixter<I>::update()
+  {
+    if (is_valid())
+      {
+	if (p_ref_)
+	  this->value_ptr_ = & image_(*p_ref_) + offset_[i_];
+	else
+	  this->value_ptr_ = * value_ref_ + offset_[i_];
+      }
+  }
 
   template <typename I>
   void dpoints_pixter<I>::start()
   {
-    pixref_ = &ima_(this->p_);
-    i_ = offset_.begin();
-    this->current_value_ = pixref_ + *i_;
+    i_ = 0;
+    update();
   }
 
   template <typename I>
   void dpoints_pixter<I>::next_()
   {
     ++i_;
-    this->current_value_ = pixref_ + *i_;
+    this->value_ptr_ += offset_[i_];    
   }
 
   template <typename I>
   bool dpoints_pixter<I>::is_valid() const
   {
-    return i_ != offset_.end();
+    return i_ != offset_.size();
   }
 
   template <typename I>
   void dpoints_pixter<I>::invalidate()
   {
-    i_ = offset_.end();
+    i_ = offset_.size();
   }
 
 #endif // ! MLN_INCLUDE_ONLY
 
-}
+} // end of namespace mln
 
 
 #endif // MLN_CORE_DPOINTS_PIXTER_HH
Index: mln/core/internal/pixel_iterator_base.hh
--- mln/core/internal/pixel_iterator_base.hh	(revision 1022)
+++ mln/core/internal/pixel_iterator_base.hh	(working copy)
@@ -28,10 +28,9 @@
 #ifndef MLN_CORE_INTERNAL_PIXEL_ITERATOR_BASE_HH
 # define MLN_CORE_INTERNAL_PIXEL_ITERATOR_BASE_HH
 
-/*! \file mln/core/internal/fast_iterator_base.hh
+/*! \file mln/core/internal/pixel_iterator_base.hh
  *
- * \brief Base class for Fast_Iterator concept implementation.
- *        Usefull for code factorisation
+ * \brief Base class for Pixel_Iterator concept implementation classes.
  */
 
 # include <mln/core/concept/pixel_iterator.hh>
@@ -44,126 +43,158 @@
   {
 
     /*! \brief pixel_iterator_base_ class
+     *
      */
-    template <typename Image, typename Exact>
-    class pixel_iterator_base_ : public Pixel_Iterator<Exact>
+    template <typename I, typename E>
+    class pixel_iterator_base_ : public Pixel_Iterator<E>
     {
     public:
-      /// Image type.
-      typedef Image ima;
+
       /// Image value type.
-      typedef mln_value(Image) value;
+      typedef mln_value(I) value;
+
       /// Image lvalue type.
-      typedef mln_lvalue(Image) lvalue;
+      typedef mln_lvalue(I) lvalue;
+
       /// Image rvalue type.
-      typedef mln_rvalue(Image) rvalue;
-      /// Image psite type.
-      typedef mln_psite(Image) psite;
+      typedef mln_rvalue(I) rvalue;
+
 
-      /// Get the image associated to the current pixel iterator.
-      const ima& image() const;
       /// pixel iterator value.
       lvalue operator* ();
+
       /// Get the pixel iterator value.
       rvalue operator* () const;
+
+
       /// Address of the current iterator value/pixel.
-      const value* address() const;
-      /// Address of the current iterator value/pixel.
-      value* address();
+      value** address() const;
+
+
+      // FIXME: Inactivated:
 
-      /// psite associated to the iterator.
-      const psite& site() const;
-      /// psite associated to the iterator.
-      psite& site();
+//       /// I type.
+//       typedef I ima;
+
+//       /// Image psite type.
+//       typedef mln_psite(I) psite;
+
+//       /// Get the image associated to the current pixel iterator.
+//       const ima& image() const;
+
+//       /// psite associated to the iterator.
+//       const psite& site() const;
+
+//       /// psite associated to the iterator.
+//       psite& site();
+
+//       /// Address of the current iterator value/pixel.
+//       value* address();
 
     protected:
-      /// Current pixel value
-      value* current_value_;
+
+      /// Current pixel / value
+      value* value_ptr_;
+
       /// Image associated to the iterator
-      ima&   ima_;
-      /// Psite of the pixel
-      psite  p_;
+      I& image_;
+
+      // FIXME: Inactivated:
 
-      pixel_iterator_base_(ima& source);
+//       /// Psite of the pixel
+//       psite  p_;
+
+      pixel_iterator_base_(I& image);
     };
 
 #ifndef MLN_INCLUDE_ONLY
 
-    template <typename Image, typename Exact>
-    pixel_iterator_base_<Image, Exact>::pixel_iterator_base_(ima& source) :
-      ima_(source)
+    template <typename I, typename E>
+    pixel_iterator_base_<I, E>::pixel_iterator_base_(I& image) :
+      image_(image),
+      value_ptr_(0)
     {
     }
 
-    template <typename Image, typename Exact>
-    const typename pixel_iterator_base_<Image, Exact>::ima&
-    pixel_iterator_base_<Image, Exact>::image() const
-    {
-      return ima_;
-    }
+//     template <typename I, typename E>
+//     const typename pixel_iterator_base_<I, E>::ima&
+//     pixel_iterator_base_<I, E>::image() const
+//     {
+//       return ima_;
+//     }
 
-    template <typename Image, typename Exact>
-    typename pixel_iterator_base_<Image, Exact>::lvalue
-    pixel_iterator_base_<Image, Exact>::operator* ()
+    template <typename I, typename E>
+    mln_lvalue(I)
+    pixel_iterator_base_<I, E>::operator* ()
     {
-      assert(exact(this)->is_valid());
-      return *current_value_;
+      mln_precondition(exact(this)->is_valid());
+      mln_precondition(value_ptr_ != 0);
+      return *value_ptr_;
     }
 
-    template <typename Image, typename Exact>
-    typename pixel_iterator_base_<Image, Exact>::rvalue
-    pixel_iterator_base_<Image, Exact>::operator* () const
+    template <typename I, typename E>
+    mln_rvalue(I)
+    pixel_iterator_base_<I, E>::operator* () const
     {
-      assert(exact(this)->is_valid());
-      return *current_value_;
+      mln_precondition(exact(this)->is_valid());
+      mln_precondition(value_ptr_ != 0);
+      return *value_ptr_;
     }
 
-    template <typename Image, typename Exact>
-    const typename pixel_iterator_base_<Image, Exact>::value*
-    pixel_iterator_base_<Image, Exact>::address() const
+    template <typename I, typename E>
+    mln_value(I) **
+    pixel_iterator_base_<I, E>::address() const
     {
-      assert(exact(this)->is_valid());
-      return current_value_;
+      mln_precondition(exact(this)->is_valid());
+      mln_precondition(value_ptr_ != 0);
+      return & (mln_value(I)*)(value_ptr_);
     }
 
-    template <typename Image, typename Exact>
-    typename pixel_iterator_base_<Image, Exact>::value*
-    pixel_iterator_base_<Image, Exact>::address()
-    {
-      assert(exact(this)->is_valid());
-      return current_value_;
-    }
+//     template <typename I, typename E>
+//     mln_value(I)*
+//     pixel_iterator_base_<I, E>::address()
+//     {
+//       mln_precondition(exact(this)->is_valid());
+//       return value_ptr_;
+//     }
+
+//     template <typename I, typename E>
+//     const typename pixel_iterator_base_<I, E>::psite&
+//     pixel_iterator_base_<I, E>::site() const
+//     {
+//       //FIXME: update psite
+//       return p_;
+//     }
+
+//     template <typename I, typename E>
+//     typename pixel_iterator_base_<I, E>::psite&
+//     pixel_iterator_base_<I, E>::site()
+//     {
+//       //FIXME: update psite
+//       return p_;
+//     }
+
 
-    template <typename Image, typename Exact>
-    const typename pixel_iterator_base_<Image, Exact>::psite&
-    pixel_iterator_base_<Image, Exact>::site() const
-    {
-      //FIXME: update psite
-      return p_;
-    }
 
-    template <typename Image, typename Exact>
-    typename pixel_iterator_base_<Image, Exact>::psite&
-    pixel_iterator_base_<Image, Exact>::site()
-    {
-      //FIXME: update psite
-      return p_;
-    }
 
 
 // FIXME: Dead code
+// #################
+
+
+
 //     /*! \brief pixel_iterator_base_ class
 //      */
-//     template <typename Exact, typename Image>
-//     class pixel_iterator_base_ : public Pixel_Iterator<Exact>
+//     template <typename E, typename I>
+//     class pixel_iterator_base_ : public Pixel_Iterator<E>
 //     {
 //     public:
-//       /// Image pixel value type.
-//       typedef mln_value(Image) value;
-//       /// Image pixel rvalue type.
-//       typedef mln_value(Image)& rvalue;
-//       /// Image pixel lvalue type
-//       typedef mln_value(Image) lvalue;
+//       /// I pixel value type.
+//       typedef mln_value(I) value;
+//       /// I pixel rvalue type.
+//       typedef mln_value(I)& rvalue;
+//       /// I pixel lvalue type
+//       typedef mln_value(I) lvalue;
 
 //       // Go to the beginning of the image.
 //       void start();
@@ -193,46 +224,46 @@
 
 // #ifndef MLN_INCLUDE_ONLY
 
-//     template <typename Exact, typename Image>
-//     pixel_iterator_base_<Exact, Image>::pixel_iterator_base_()
+//     template <typename E, typename I>
+//     pixel_iterator_base_<E,I>::pixel_iterator_base_()
 //     {
 //     }
 
-//     template <typename Exact, typename Image>
-//     void pixel_iterator_base_<Exact, Image>::start()
+//     template <typename E, typename I>
+//     void pixel_iterator_base_<E,I>::start()
 //     {
 //       current_ = start_;
 //     }
 
-//     template <typename Exact, typename Image>
-//     void pixel_iterator_base_<Exact, Image>::next_()
+//     template <typename E, typename I>
+//     void pixel_iterator_base_<E,I>::next_()
 //     {
 //       ++current_;
 //     }
 
-//     template <typename Exact, typename Image>
-//     void pixel_iterator_base_<Exact, Image>::invalidate()
+//     template <typename E, typename I>
+//     void pixel_iterator_base_<E,I>::invalidate()
 //     {
 //       current_ = eoi_;
 //     }
 
-//     template <typename Exact, typename Image>
-//     bool pixel_iterator_base_<Exact, Image>::is_valid() const
+//     template <typename E, typename I>
+//     bool pixel_iterator_base_<E,I>::is_valid() const
 //     {
 //       return (current_ != eoi_);
 //     }
 
-//     template <typename Exact, typename Image>
-//     typename pixel_iterator_base_<Exact, Image>::rvalue
-//     pixel_iterator_base_<Exact, Image>::operator*()
+//     template <typename E, typename I>
+//     typename pixel_iterator_base_<E,I>::rvalue
+//     pixel_iterator_base_<E,I>::operator*()
 //     {
 //       return *current_;
 //     }
 
 
-//     template <typename Exact, typename Image>
-//     typename pixel_iterator_base_<Exact, Image>::lvalue
-//     pixel_iterator_base_<Exact, Image>::operator*() const
+//     template <typename E, typename I>
+//     typename pixel_iterator_base_<E,I>::lvalue
+//     pixel_iterator_base_<E,I>::operator*() const
 //     {
 //       return *current_;
 //     }
Index: mln/level/was.median.hh
--- mln/level/was.median.hh	(revision 1022)
+++ mln/level/was.median.hh	(working copy)
@@ -30,7 +30,7 @@
 
 /*! \file mln/level/was.median.hh
  *
- * \brief Obsolete routine for the median filter.
+ * \brief Obsolete routines for median filtering.
  */
 
 
@@ -43,6 +43,9 @@
     namespace impl
     {
 
+
+      // prefer using a canvas
+
       template <typename I, typename W, typename O>
       void median_as_procedure(const I& input,
 			       const W& win,
@@ -126,6 +129,62 @@
       }
 
 
+
+      // horizontal median
+
+      template <typename I, typename O>
+      void hmedian(const I& input, const hline2d& win, O& output)
+      {
+
+	const int
+	  max_row = input.max_row(),
+	  min_col = input.min_col(),
+	  max_col = input.max_col();
+	const unsigned half = win.length() / 2;
+
+	point2d p;
+	int& row = p.row();
+	int& col = p.col();
+
+	accu::median_on<mln_value(I)> med;
+
+	for (row = input.min_row(); row <= max_row; ++row)
+	  {
+	    int ct, cu;
+
+	    // initialization (before first point of the row)
+	    med.init();
+	    for (ct = min_col; ct < min_col + half; ++ct)
+	      med.take(input.at(row, ct));
+
+	    // left columns (just take new points)
+	    for (col = min_col; col <= min_col + half; ++col, ++ct)
+	      {
+		med.take(input.at(row, ct));
+		output(p) = med;
+	      }
+	    
+	    // middle columns (both take and untake)
+	    cu = min_col;
+	    for (; col <= max_col - half; ++cu, ++col, ++ct)
+	      {
+		med.take(input.at(row, ct));
+		med.untake(input.at(row, cu));
+		output(p) = med;
+	      }
+
+	    // right columns (now just untake old points)
+	    for (; col <= max_col; ++cu, ++col)
+	      {
+		med.untake(input.at(row, cu));
+		output(p) = med;
+	      }
+	  }
+
+      } // end of hmedian
+
+
+
     } // end of namespace mln::level::impl
 
   } // end of namespace mln::level
Index: mln/level/fast_median.hh
--- mln/level/fast_median.hh	(revision 1022)
+++ mln/level/fast_median.hh	(working copy)
@@ -103,7 +103,7 @@
 	med.init();
 	{
 	  mln_qixter(I) q(win, p, input);
-	  for_all(q) //if (input.has(q))
+	  for_all(q)
 	    med.take(*q);
 	}
 
@@ -118,10 +118,10 @@
 	  {
 
 	    // "go down"
-	    for_all(q_top) //if (input.has(q_top))
+	    for_all(q_top)
 	      med.untake(*q_top);
 
-	    for_all(q_bot) //if (input.has(q_bot))
+	    for_all(q_bot)
 	      med.take(*q_bot);
 
 	    output(p) = med;
@@ -130,11 +130,10 @@
 	      // browse line fwd
 	      while (col < max_col)
 		{
-		  std::cout << "debug: psite" << q_fm.psite() << "\n";
 		  ++col;
-		  for_all(q_fm) //if (input.has(q_fm))
+		  for_all(q_fm)
 		    med.untake(*q_fm);
-		  for_all(q_fp) //if (input.has(q_fp))
+		  for_all(q_fp)
 		    med.take(*q_fp);
 		  output(p) = med;
 		}
@@ -143,9 +142,9 @@
 	      while (col > min_col)
 		{
 		  --col;
-		  for_all(q_bm) //if (input.has(q_bm))
+		  for_all(q_bm)
 		    med.untake(*q_bm);
-		  for_all(q_bp) //if (input.has(q_bp))
+		  for_all(q_bp)
 		    med.take(*q_bp);
 		  output(p) = med;
 		}
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                        https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from  Nicolas Ballas  <ballas(a)lrde.epita.fr>
	Change fast_iterator hierarchy.
	* tests/fast_median.cc: New test.
	* tests/pixter_point2d.cc: Update test.
	* mln/core/pixel.hh: Add typedefs in the class pixel_.
	* mln/core/macros.hh: Add new macros.
	* mln/core/concept/pixel_iterator.hh: New, rename Fast_Iterator concep as Pixel Iterator.
	* mln/core/concept/fast_iterator.hh: Remove.
	* mln/core/concept/genpixel.hh: Constructor fixed.
	* mln/core/pixter2d_b.hh: Broken!.
	* mln/core/image2d_b.hh: Add new method point_at_offset.
	* mln/core/dpoints_pixter.hh: Adapt dpoint_pixter to the new hierarchy.
	* mln/core/internal/pixel_iterator_base.hh: New, rename fast_iterator_base_ as pixel_iterator_base_.
	* mln/core/internal/fast_iterator_base.hh: Remove.
	* mln/level/fast_median.hh: New median using qixter.
 mln/core/concept/genpixel.hh             |   33 ++--
 mln/core/concept/pixel_iterator.hh       |   81 ++++++++++
 mln/core/dpoints_pixter.hh               |   35 +---
 mln/core/image2d_b.hh                    |   22 ++
 mln/core/internal/pixel_iterator_base.hh |  246 +++++++++++++++++++++++++++++++
 mln/core/macros.hh                       |    9 +
 mln/core/pixel.hh                        |    2 
 mln/core/pixter2d_b.hh                   |    5 
 mln/level/fast_median.hh                 |  176 ++++++++++++++++++++++
 tests/fast_median.cc                     |   63 +++++++
 tests/pixter_point2d.cc                  |    4 
 11 files changed, 630 insertions(+), 46 deletions(-)
Index: tests/fast_median.cc
--- tests/fast_median.cc	(revision 0)
+++ tests/fast_median.cc	(revision 0)
@@ -0,0 +1,63 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction.  Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License.  This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+/*! \file tests/fast_median.cc
+ *
+ * \brief Test on mln::level::fast_median.
+ */
+
+#include <mln/core/image2d_b.hh>
+#include <mln/core/rectangle2d.hh>
+
+#include <mln/io/load_pgm.hh>
+#include <mln/io/save_pgm.hh>
+
+#include <mln/value/int_u.hh>
+#include <mln/level/fast_median.hh>
+#include <mln/level/approx/median.hh>
+
+
+
+
+int main()
+{
+  using namespace mln;
+  using value::int_u8;
+
+  rectangle2d rect(51, 51);
+  border::thickness = 52;
+
+  image2d_b<int_u8>
+    lena = io::load_pgm("../img/lena.pgm"),
+    out(lena.domain());
+
+  level::fast_median(lena, rect, out);
+  io::save_pgm(out, "out.pgm");
+
+//   level::approx::median(lena, rec, out);
+//   io::save_pgm(out, "outa.pgm");
+}
Index: tests/pixter_point2d.cc
--- tests/pixter_point2d.cc	(revision 1021)
+++ tests/pixter_point2d.cc	(working copy)
@@ -27,7 +27,6 @@
 
 #include <cassert>
 #include <mln/core/image2d_b.hh>
-#include <iostream>
 
 
 int
@@ -35,7 +34,7 @@
 {
   using namespace mln;
 
-  image2d_b<int> ima(2, 2);
+  image2d_b<int> ima(20, 20);
 
   image2d_b<int>::piter p(ima.domain());
   image2d_b<int>::pixter f(ima);
@@ -49,7 +48,6 @@
 
   for_all(f)
     {
-      std::cout << *f << std::endl;
       assert(*f == i ++);
       *f = 5;
     }
Index: mln/core/pixel.hh
--- mln/core/pixel.hh	(revision 1021)
+++ mln/core/pixel.hh	(working copy)
@@ -64,6 +64,8 @@
   {
     typedef mln_psite(I) psite;
     typedef mln_value(I) value;
+    typedef mln_rvalue(I) rvalue;
+    typedef I ima;
 
     pixel(I& ima);
     pixel(I& ima, const psite& p);
Index: mln/core/macros.hh
--- mln/core/macros.hh	(revision 1021)
+++ mln/core/macros.hh	(working copy)
@@ -96,6 +96,15 @@
 /// Shortcut to access the fwd_viter type associated to T.
 # define mln_fwd_viter(T)  typename T::fwd_viter
 
+// i
+
+/// Shortcut to access the fwd_viter type associated to T.
+# define mln_image(T)      typename T::image
+
+/// Shortcut to access the fwd_viter type associated to T.
+# define mln_ima(T)        typename T::ima
+
+
 // l
 
 
Index: mln/core/concept/pixel_iterator.hh
--- mln/core/concept/pixel_iterator.hh	(revision 0)
+++ mln/core/concept/pixel_iterator.hh	(revision 0)
@@ -0,0 +1,81 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction.  Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License.  This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_CORE_CONCEPT_PIXEL_ITERATOR_HH
+# define MLN_CORE_CONCEPT_PIXEL_ITERATOR_HH
+
+/*! \file mln/core/concept/fast_iterator.hh
+ * \brief Definition of the concept of mln::Pixel_Iterator.
+ */
+
+# include <mln/core/concept/iterator.hh>
+# include <mln/core/concept/genpixel.hh>
+
+namespace mln
+{
+
+  /*! \brief Pixel Iterator concept class.
+   *
+   * \see FIXME
+   */
+  template <typename E>
+  struct Pixel_Iterator :
+    public Iterator<E>,
+    public GenPixel<E>
+  {
+    /*
+      typedef rvalue
+      typedef lvalue
+      lvalue operator* ();
+      rvalue operator* () const;
+    */
+  protected:
+    Pixel_Iterator();
+  };
+
+#ifndef MLN_INCLUDE_ONLY
+
+  template <typename E>
+  Pixel_Iterator<E>::Pixel_Iterator()
+  {
+    typedef mln_value(E) value;
+    typedef mln_rvalue(E) rvalue;
+    typedef mln_lvalue(E) lvalue;
+
+    lvalue (E::*m1)() = & E::operator*;
+    m1 = 0;
+    rvalue (E::*m2)() const = & E::operator*;
+    m2 = 0;
+  }
+
+#endif // ! MLN_INCLUDE_ONLY
+
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CORE_CONCEPT_PIXEL_ITERATOR_HH
Index: mln/core/concept/genpixel.hh
--- mln/core/concept/genpixel.hh	(revision 1021)
+++ mln/core/concept/genpixel.hh	(working copy)
@@ -60,12 +60,13 @@
   {
 
     /*
-      typedef image; // not const!
-      typedef psite;
+      typedef ima; // not const!
+      typede  psite;
       typedef rvalue;
+      typedef value;
 
-      const image& image() const;
-      const psite& psite() const; // FIXME ou cpy
+      const ima& image() const;
+      const psite& site() const; // FIXME ou cpy
 
       rvalue operator*() const;
 
@@ -98,17 +99,19 @@
   template <typename E>
   GenPixel<E>::GenPixel()
   {
-    // FIXME
-//     int dim = E::dim;
-//     mln_invariant(dim > 0);
-//     dim = 0;
-//     typedef  mln_point(E)  point;
-//     typedef mln_dpoint(E) dpoint;
-//     typedef mln_coord(E)  coord;
-//     const point* (E::*m1)() const = & E::pointer;
-//     m1 = 0;
-//     coord (E::*m2)(unsigned i) const = & E::operator[];
-//     m2 = 0;
+    typedef mln_value(E) value;
+    typedef mln_rvalue(E) rvalue;
+    typedef mln_ima(E) ima;
+    typedef mln_psite(E) psite;
+
+    const ima& (E::*m1)() const = & E::image;
+    m1 = 0;
+    const psite& (E::*m2)() const = & E::site;
+    m2 = 0;
+    rvalue (E::*m3)() const = & E::operator*;
+    m3 = 0;
+    const value* (E::*m4)() const = & E::address;
+    m4 = 0;
   }
 
 
Index: mln/core/pixter2d_b.hh
--- mln/core/pixter2d_b.hh	(revision 1021)
+++ mln/core/pixter2d_b.hh	(working copy)
@@ -28,7 +28,7 @@
 #ifndef MLN_CORE_PIXTER2D_B_HH
 # define MLN_CORE_PIXTER2D_B_HH
 
-# include <mln/core/internal/fast_iterator_base.hh>
+# include <mln/core/internal/pixel_iterator_base.hh>
 # include <mln/core/point2d.hh>
 # include <iostream>
 
@@ -39,7 +39,6 @@
  * \brief Pixel iterator class on a image 2d with border.
  */
 
-# include <mln/core/concept/fast_iterator.hh>
 
 
 namespace mln
@@ -50,7 +49,7 @@
 
   template <typename T>
   class fwd_pixter2d_b :
-    public internal::fast_iterator_base_< fwd_pixter2d_b<T>, image2d_b<T> >
+    public internal::pixel_iterator_base_< fwd_pixter2d_b<T>, image2d_b<T> >
   {
   public:
     /// Image pixel value type.
Index: mln/core/image2d_b.hh
--- mln/core/image2d_b.hh	(revision 1021)
+++ mln/core/image2d_b.hh	(working copy)
@@ -151,9 +151,17 @@
     T& at(int row, int col);
 
 
+    /// Fast Image method
+
     /// Return the offset corresponding to the dpoint \p dp.
     int offset(const dpoint2d& dp);
 
+    /// Return the offset corresponding to the dpoint \p p.
+    int offset(const point2d& p);
+
+    /// Return the point corresponding to the offset \p offset.
+    point2d point_at_offset(int offset);
+
 
   private:
 
@@ -387,6 +395,20 @@
     return dp[0] * vb_.len(1) + dp[1];
   }
 
+  template <typename T>
+  int
+  image2d_b<T>::offset(const point2d& p)
+  {
+    return p[0] * vb_.len(1) + p[1];
+  }
+
+  template <typename T>
+  point2d
+  image2d_b<T>::point_at_offset(int offset)
+  {
+    return point2d(offset / (vb_.len(1) + 1), offset % (vb_.len(1) + 1));
+  }
+
 # endif // ! MLN_INCLUDE_ONLY
 
 } // end of namespace mln
Index: mln/core/dpoints_pixter.hh
--- mln/core/dpoints_pixter.hh	(revision 1021)
+++ mln/core/dpoints_pixter.hh	(working copy)
@@ -30,7 +30,7 @@
 
 # include <cassert>
 # include <vector>
-# include <mln/core/concept/fast_iterator.hh>
+# include <mln/core/internal/pixel_iterator_base.hh>
 
 
 namespace mln
@@ -41,8 +41,9 @@
    * The parameter \c I is the image type.
    */
   template <typename I>
-  class dpoints_pixter : public Fast_Iterator< dpoints_pixter<I> >
+  class dpoints_pixter : public internal::pixel_iterator_base_< I, dpoints_pixter<I> >
   {
+    typedef typename internal::pixel_iterator_base_< I, dpoints_pixter<I> > super;
   public:
     /// Image pixel value
     typedef mln_value(I) value;
@@ -51,14 +52,14 @@
     /// Image pixel lvalue
     typedef mln_lvalue(I) lvalue;
 
-    /*! \brief Constructo.
+    /*! \brief Constructor.
      *
      * \param[in] dps   Object that can provide an array of delta-points.
      * \param[in] p_ref Center point to iterate around.
      * \param[in] ima   Image to iterate.
      */
     template <typename Dps>
-    dpoints_pixter(const Dps& dps, const typename I::point& p_ref,I& ima);
+    dpoints_pixter(const Dps& dps, const typename I::psite& p_ref,I& ima);
 
     /// Set the iterator at the start.
     void start();
@@ -69,10 +70,6 @@
     ///  Is the iterator valid?
     bool is_valid() const;
 
-    /// Get the iterator value
-    rvalue operator* ();
-    lvalue operator* () const;
-
   private:
     /// offset of each dpoints
     std::vector<int> offset_;
@@ -87,8 +84,9 @@
 
   template <typename I>
   template <typename Dps>
-  dpoints_pixter<I>::dpoints_pixter(const Dps& dps, const typename I::point& ref, I& ima)
+  dpoints_pixter<I>::dpoints_pixter(const Dps& dps, const typename I::psite& ref, I& ima) : super(ima)
   {
+    this->p_ = ref;
     pixref_ = &ima(ref);
     for (typename std::vector<typename I::dpoint>::const_iterator it = dps.vec().begin();
 	 it != dps.vec().end();
@@ -100,13 +98,16 @@
   template <typename I>
   void dpoints_pixter<I>::start()
   {
+    pixref_ = &ima_(this->p_);
     i_ = offset_.begin();
+    this->current_value_ = pixref_ + *i_;
   }
 
   template <typename I>
   void dpoints_pixter<I>::next_()
   {
     ++i_;
+    this->current_value_ = pixref_ + *i_;
   }
 
   template <typename I>
@@ -121,22 +122,6 @@
     i_ = offset_.end();
   }
 
-  template <typename I>
-  typename dpoints_pixter<I>::rvalue
-  dpoints_pixter<I>::operator* ()
-  {
-    assert(this->is_valid());
-    return *(pixref_ + *i_);
-  }
-
-  template <typename I>
-  typename dpoints_pixter<I>::lvalue
-  dpoints_pixter<I>::operator* () const
-  {
-    assert(this->is_valid());
-    return *(pixref_ + *i_);
-  }
-
 #endif // ! MLN_INCLUDE_ONLY
 
 }
Index: mln/core/internal/pixel_iterator_base.hh
--- mln/core/internal/pixel_iterator_base.hh	(revision 0)
+++ mln/core/internal/pixel_iterator_base.hh	(revision 0)
@@ -0,0 +1,246 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction.  Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License.  This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_CORE_INTERNAL_PIXEL_ITERATOR_BASE_HH
+# define MLN_CORE_INTERNAL_PIXEL_ITERATOR_BASE_HH
+
+/*! \file mln/core/internal/fast_iterator_base.hh
+ *
+ * \brief Base class for Fast_Iterator concept implementation.
+ *        Usefull for code factorisation
+ */
+
+# include <mln/core/concept/pixel_iterator.hh>
+
+
+namespace mln
+{
+
+  namespace internal
+  {
+
+    /*! \brief pixel_iterator_base_ class
+     */
+    template <typename Image, typename Exact>
+    class pixel_iterator_base_ : public Pixel_Iterator<Exact>
+    {
+    public:
+      /// Image type.
+      typedef Image ima;
+      /// Image value type.
+      typedef mln_value(Image) value;
+      /// Image lvalue type.
+      typedef mln_lvalue(Image) lvalue;
+      /// Image rvalue type.
+      typedef mln_rvalue(Image) rvalue;
+      /// Image psite type.
+      typedef mln_psite(Image) psite;
+
+      /// Get the image associated to the current pixel iterator.
+      const ima& image() const;
+      /// pixel iterator value.
+      lvalue operator* ();
+      /// Get the pixel iterator value.
+      rvalue operator* () const;
+      /// Address of the current iterator value/pixel.
+      const value* address() const;
+      /// Address of the current iterator value/pixel.
+      value* address();
+
+      /// psite associated to the iterator.
+      const psite& site() const;
+      /// psite associated to the iterator.
+      psite& site();
+
+    protected:
+      /// Current pixel value
+      value* current_value_;
+      /// Image associated to the iterator
+      ima&   ima_;
+      /// Psite of the pixel
+      psite  p_;
+
+      pixel_iterator_base_(ima& source);
+    };
+
+#ifndef MLN_INCLUDE_ONLY
+
+    template <typename Image, typename Exact>
+    pixel_iterator_base_<Image, Exact>::pixel_iterator_base_(ima& source) :
+      ima_(source)
+    {
+    }
+
+    template <typename Image, typename Exact>
+    const typename pixel_iterator_base_<Image, Exact>::ima&
+    pixel_iterator_base_<Image, Exact>::image() const
+    {
+      return ima_;
+    }
+
+    template <typename Image, typename Exact>
+    typename pixel_iterator_base_<Image, Exact>::lvalue
+    pixel_iterator_base_<Image, Exact>::operator* ()
+    {
+      assert(exact(this)->is_valid());
+      return *current_value_;
+    }
+
+    template <typename Image, typename Exact>
+    typename pixel_iterator_base_<Image, Exact>::rvalue
+    pixel_iterator_base_<Image, Exact>::operator* () const
+    {
+      assert(exact(this)->is_valid());
+      return *current_value_;
+    }
+
+    template <typename Image, typename Exact>
+    const typename pixel_iterator_base_<Image, Exact>::value*
+    pixel_iterator_base_<Image, Exact>::address() const
+    {
+      assert(exact(this)->is_valid());
+      return current_value_;
+    }
+
+    template <typename Image, typename Exact>
+    typename pixel_iterator_base_<Image, Exact>::value*
+    pixel_iterator_base_<Image, Exact>::address()
+    {
+      assert(exact(this)->is_valid());
+      return current_value_;
+    }
+
+    template <typename Image, typename Exact>
+    const typename pixel_iterator_base_<Image, Exact>::psite&
+    pixel_iterator_base_<Image, Exact>::site() const
+    {
+      //FIXME: update psite
+      return p_;
+    }
+
+    template <typename Image, typename Exact>
+    typename pixel_iterator_base_<Image, Exact>::psite&
+    pixel_iterator_base_<Image, Exact>::site()
+    {
+      //FIXME: update psite
+      return p_;
+    }
+
+
+// FIXME: Dead code
+//     /*! \brief pixel_iterator_base_ class
+//      */
+//     template <typename Exact, typename Image>
+//     class pixel_iterator_base_ : public Pixel_Iterator<Exact>
+//     {
+//     public:
+//       /// Image pixel value type.
+//       typedef mln_value(Image) value;
+//       /// Image pixel rvalue type.
+//       typedef mln_value(Image)& rvalue;
+//       /// Image pixel lvalue type
+//       typedef mln_value(Image) lvalue;
+
+//       // Go to the beginning of the image.
+//       void start();
+//       // Go on the next element.
+//       void next_();
+//       // Invalidate the iterator.
+//       void invalidate();
+//       // Is the iterator referencing a correct position in the image?
+//       bool is_valid() const;
+
+
+//       // Return the current pixel.
+//       rvalue operator* ();
+//       lvalue operator* () const;
+
+//     protected:
+//       // beginning of the image
+//       value* start_;
+//       // end of the image
+//       value* eoi_;
+//       // current position in the image
+//       value* current_;
+//       // End of Factoriasable
+
+//       pixel_iterator_base_();
+//     };
+
+// #ifndef MLN_INCLUDE_ONLY
+
+//     template <typename Exact, typename Image>
+//     pixel_iterator_base_<Exact, Image>::pixel_iterator_base_()
+//     {
+//     }
+
+//     template <typename Exact, typename Image>
+//     void pixel_iterator_base_<Exact, Image>::start()
+//     {
+//       current_ = start_;
+//     }
+
+//     template <typename Exact, typename Image>
+//     void pixel_iterator_base_<Exact, Image>::next_()
+//     {
+//       ++current_;
+//     }
+
+//     template <typename Exact, typename Image>
+//     void pixel_iterator_base_<Exact, Image>::invalidate()
+//     {
+//       current_ = eoi_;
+//     }
+
+//     template <typename Exact, typename Image>
+//     bool pixel_iterator_base_<Exact, Image>::is_valid() const
+//     {
+//       return (current_ != eoi_);
+//     }
+
+//     template <typename Exact, typename Image>
+//     typename pixel_iterator_base_<Exact, Image>::rvalue
+//     pixel_iterator_base_<Exact, Image>::operator*()
+//     {
+//       return *current_;
+//     }
+
+
+//     template <typename Exact, typename Image>
+//     typename pixel_iterator_base_<Exact, Image>::lvalue
+//     pixel_iterator_base_<Exact, Image>::operator*() const
+//     {
+//       return *current_;
+//     }
+
+#endif // ! MLN_INCLUDE_ONLY
+  } // end of namespace internal
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CORE_INTERNAL_PIXEL_ITERATOR_BASE_HH
Index: mln/level/fast_median.hh
--- mln/level/fast_median.hh	(revision 0)
+++ mln/level/fast_median.hh	(revision 0)
@@ -0,0 +1,176 @@
+// 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_LEVEL_FAST_MEDIAN_HH
+# define MLN_LEVEL_FAST_MEDIAN_HH
+
+/*! \file mln/level/median.hh
+ *
+ * \brief Fast Median filtering of an image.
+ */
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/window2d.hh>
+# include <mln/accu/median.hh>
+# include <ostream>
+
+
+namespace mln
+{
+
+  namespace level
+  {
+
+    /*! Compute in \p output the median filter of image \p input by
+     *  the window \p win.
+     *
+     * \param[in] input The image to be filtered.
+     * \param[in] win The window.
+     * \param[in,out] output The output image.
+     *
+     * \pre \p input and \p output have to be initialized.
+     */
+    template <typename I, typename W, typename O>
+    void fast_median(Image<I>& input, const Window<W>& win,
+		     Image<O>& output);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+    namespace impl
+    {
+
+      template <typename I, typename W, typename O>
+      void fast_median(I& input,
+		       const W& win,
+		       O& output)
+      {
+	mln_precondition(input.has_data());
+	mln_precondition(output.has_data());
+
+	int
+	  min_row = input.min_row(), max_row = input.max_row(),
+	  min_col = input.min_col(), max_col = input.max_col();
+
+	window2d
+	  win_fwd_plus  = win - (win + left),
+	  win_fwd_minus = (win + left) - win,
+	  win_bkd_plus  = win - (win + right),
+	  win_bkd_minus = (win + right) - win,
+	  win_bot  = win - (win + up),
+	  win_top = (win + up) - win;
+
+
+
+	//Fixme bug
+	point2d p;
+
+	accu::median_on<mln_value(I)> med;
+
+	// initialization
+
+	p = input.domain().pmin() + up;
+	mln_qixter(I)
+	  q_fp(win_fwd_plus, p, input), q_fm(win_fwd_minus, p, input),
+	  q_bp(win_bkd_plus, p, input), q_bm(win_bkd_minus, p, input),
+	  q_top(win_top, p, input), q_bot(win_bot, p, input);
+
+	med.init();
+	{
+	  mln_qixter(I) q(win, p, input);
+	  for_all(q) //if (input.has(q))
+	    med.take(*q);
+	}
+
+	int& row = p.row();
+	int& col = p.col();
+	bool fwd = true;
+
+	mln_assertion(p.col() == min_col);
+	mln_assertion(p.row() == min_row - 1);
+
+	for (row = min_row; row <= max_row; ++row)
+	  {
+
+	    // "go down"
+	    for_all(q_top) //if (input.has(q_top))
+	      med.untake(*q_top);
+
+	    for_all(q_bot) //if (input.has(q_bot))
+	      med.take(*q_bot);
+
+	    output(p) = med;
+
+	    if (fwd)
+	      // browse line fwd
+	      while (col < max_col)
+		{
+		  std::cout << "debug: psite" << q_fm.psite() << "\n";
+		  ++col;
+		  for_all(q_fm) //if (input.has(q_fm))
+		    med.untake(*q_fm);
+		  for_all(q_fp) //if (input.has(q_fp))
+		    med.take(*q_fp);
+		  output(p) = med;
+		}
+	    else
+	      // browse line bkd
+	      while (col > min_col)
+		{
+		  --col;
+		  for_all(q_bm) //if (input.has(q_bm))
+		    med.untake(*q_bm);
+		  for_all(q_bp) //if (input.has(q_bp))
+		    med.take(*q_bp);
+		  output(p) = med;
+		}
+	    // change browsing
+	    fwd = ! fwd;
+	  }
+      }
+
+    } // end of namespace mln::level::impl
+
+
+    // facade
+
+    template <typename I, typename W, typename O>
+    void fast_median(Image<I>& input, const Window<W>& win,
+		     Image<O>& output)
+    {
+      impl::fast_median(exact(input), exact(win), exact(output));
+    }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace mln::level
+
+} // end of namespace mln
+
+
+#endif // ! MLN_LEVEL_FAST_MEDIAN_HH
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                        https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from  Thierry Geraud  <thierry.geraud(a)lrde.epita.fr>
	New 2D window types in mln.
	* tests/median.cc: Clean up.
	* tests/hmedian.cc: New.
	* tests/erosion.cc: Clean up.
	* tests/rectangle2d.cc: Update.
	* mln/core/hline2d.hh: New.
	* mln/core/rectangle2d.hh
	(half_width_, half_height_): Change to...
	(width_, height_): ...these.
	Update.
	* mln/core/vline2d.hh: New.
	* mln/morpho/erosion.hh (erosion_wrt_win): New overload.
	* mln/level/was.median.hh: New.
	* mln/level/approx: New.
	* mln/level/approx/median.hh: New.
	* mln/level/median.hh (median_as_procedure): Move into...
	* mln/level/was.hmedian.hh: ...this new file.
 mln/core/hline2d.hh        |  176 ++++++++++++++++++++++++++++++++++++++++++++
 mln/core/rectangle2d.hh    |   48 ++++++------
 mln/core/vline2d.hh        |  178 +++++++++++++++++++++++++++++++++++++++++++++
 mln/level/approx/median.hh |   90 ++++++++++++++++++++++
 mln/level/median.hh        |  157 +++++++++++++++++----------------------
 mln/level/was.hmedian.hh   |  102 +++++++++++++++++++++++++
 mln/level/was.median.hh    |  136 ++++++++++++++++++++++++++++++++++
 mln/morpho/erosion.hh      |   31 ++++++-
 tests/erosion.cc           |    8 +-
 tests/hmedian.cc           |   64 ++++++++++++++++
 tests/median.cc            |   15 ++-
 tests/rectangle2d.cc       |    4 -
 12 files changed, 883 insertions(+), 126 deletions(-)
Index: tests/median.cc
--- tests/median.cc	(revision 1020)
+++ tests/median.cc	(working copy)
@@ -38,21 +38,26 @@
 
 #include <mln/value/int_u.hh>
 #include <mln/level/median.hh>
+#include <mln/level/approx/median.hh>
 
 
-using namespace mln;
-using namespace mln::value;
 
 
 int main()
 {
-  rectangle2d rec(64, 64);
-  border::thickness = 66;
+  using namespace mln;
+  using value::int_u8;
+
+  rectangle2d rect(51, 51);
+  border::thickness = 52;
 
   image2d_b<int_u8>
     lena = io::load_pgm("../img/lena.pgm"),
     out(lena.domain());
 
-  level::median(lena, rec, out);
+  level::median(lena, rect, out);
   io::save_pgm(out, "out.pgm");
+
+//   level::approx::median(lena, rec, out);
+//   io::save_pgm(out, "outa.pgm");
 }
Index: tests/hmedian.cc
--- tests/hmedian.cc	(revision 0)
+++ tests/hmedian.cc	(revision 0)
@@ -0,0 +1,64 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction.  Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License.  This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+/*! \file tests/hmedian.cc
+ *
+ * \brief Test on the hline2d version of mln::level::median.
+ */
+
+#include <mln/core/image2d_b.hh>
+#include <mln/core/rectangle2d.hh>
+
+#include <mln/io/load_pgm.hh>
+#include <mln/io/save_pgm.hh>
+
+#include <mln/value/int_u.hh>
+#include <mln/level/median.hh>
+#include <mln/level/compare.hh>
+
+
+
+
+int main()
+{
+  using namespace mln;
+  using value::int_u8;
+
+  border::thickness = 0;
+
+  image2d_b<int_u8>
+    lena = io::load_pgm("../img/lena.pgm"),
+    out(lena.domain()),
+    ref(lena.domain());
+
+  level::median(lena, rectangle2d(1, 101), ref);
+
+  level::median(lena, hline2d(101), out);
+  io::save_pgm(out, "out.pgm");
+
+  // FIXME: mln_assertion(out = ref);
+}
Index: tests/erosion.cc
--- tests/erosion.cc	(revision 1020)
+++ tests/erosion.cc	(working copy)
@@ -45,13 +45,13 @@
 #include <mln/fun/ops.hh>
 
 
-using namespace mln;
-using namespace mln::value;
-
 
 int main()
 {
-  rectangle2d rec(4, 4);//64, 64);
+  using namespace mln;
+  using value::int_u8;
+
+  rectangle2d rec(21, 21);
   border::thickness = 66;
 
   image2d_b<int_u8>
Index: tests/rectangle2d.cc
--- tests/rectangle2d.cc	(revision 1020)
+++ tests/rectangle2d.cc	(working copy)
@@ -38,12 +38,12 @@
 {
   using namespace mln;
 
-  const unsigned h = 3, w = 4;
+  const unsigned h = 3, w = 5;
   rectangle2d rec(h, w);
 
   mln_assertion(rec.is_centered());
   mln_assertion(rec.is_symmetric());
   mln_assertion(rec = -rec);
-  mln_assertion(rec.nelements() = (2*h+1) * (2*w+1));
+  mln_assertion(rec.nelements() = h * w);
 }
 
Index: mln/core/hline2d.hh
--- mln/core/hline2d.hh	(revision 0)
+++ mln/core/hline2d.hh	(revision 0)
@@ -0,0 +1,176 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction.  Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License.  This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_CORE_HLINE2D_HH
+# define MLN_CORE_HLINE2D_HH
+
+/*! \file mln/core/hline2d.hh
+ *
+ * \brief Definition of the mln::hline2d window.
+ */
+
+# include <mln/core/concept/window.hh>
+# include <mln/core/internal/set_of.hh>
+# include <mln/core/dpoint2d.hh>
+# include <mln/core/dpoints_piter.hh>
+
+
+namespace mln
+{
+ 
+  /*! \brief Horizontal line window defined on the 2D square grid.
+   *
+   * An hline2d is centered and symmetrical; so its height is 1 and
+   * its width (length) is odd.
+   *
+   * For instance: \n
+   *  o o x o o \n
+   * is defined with length = 5.
+   */
+  struct hline2d : public Window< hline2d >,
+		   public internal::set_of_<dpoint2d>
+  {
+    /// Point associated type.
+    typedef point2d point;
+
+    /// Dpoint associated type.
+    typedef dpoint2d dpoint;
+
+    /*! \brief Piter type to browse a hline such as: "for each row
+     * (increasing), for each column (increasing)."
+     */
+    typedef dpoints_fwd_piter<dpoint2d> fwd_qiter;
+
+    /*! \brief Piter type to browse a hline such as: "for each row
+     * (decreasing), for each column (decreasing)."
+     */
+    typedef dpoints_fwd_piter<dpoint2d> bkd_qiter; // FIXME: bkd!!!
+
+    /*! \brief Same as fwd_qiter.
+     */
+    typedef fwd_qiter qiter;
+
+    /*! \brief Constructor.
+     *
+     * \param[in] length Length, thus width, of the horizontal line.
+     *
+     * \pre \p length is odd.
+     */
+    hline2d(unsigned length);
+
+    /*! \brief Test if the window is centered.
+     *
+     * \return True.
+     */
+    bool is_centered() const;
+
+    /*! \brief Test if the window is symmetric.
+     *
+     * \return true.
+     */
+    bool is_symmetric() const;
+
+    /*! \brief Give the hline length, that is, its width.
+     */
+    unsigned length() const;
+
+    /*! \brief Give the maximum coordinate gap between the window
+     * center and a window point.
+     */
+    unsigned delta() const;
+
+    /// Get the symmetrical window.
+    hline2d sym_() const;
+
+  protected:
+    unsigned length_;
+  };
+
+
+  /*! \brief Print an horizontal 2D line window \p win into the output
+   *  stream \p ostr.
+   *
+   * \param[in,out] ostr An output stream.
+   * \param[in] win An horizontal 2D line window.
+   *
+   * \return The modified output stream \p ostr.
+   *
+   * \relates mln::hline2d
+   */
+  std::ostream& operator<<(std::ostream& ostr, const hline2d& win);
+
+ 
+
+# ifndef MLN_INCLUDE_ONLY
+
+  hline2d::hline2d(unsigned length)
+    : length_(length)
+  {
+    mln_precondition(length % 2 = 1);
+    const int dcol = length / 2;
+    for (int col = - dcol; col <= dcol; ++col)
+      insert(make::dpoint2d(0, col));
+  }
+
+  bool hline2d::is_centered() const
+  {
+    return true;
+  }
+
+  bool hline2d::is_symmetric() const
+  {
+    return true;
+  }
+
+  unsigned hline2d::length() const
+  {
+    return length_;
+  }
+
+  unsigned hline2d::delta() const
+  {
+    return length_ / 2;
+  }
+
+  hline2d hline2d::sym_() const
+  {
+    return *this;
+  }
+
+  std::ostream& operator<<(std::ostream& ostr, const hline2d& win)
+  {
+    ostr << "[line2d: length=" << win.length() << ']';
+    return ostr;
+  }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+} // end of namespace mln
+
+
+
+#endif // ! MLN_CORE_HLINE2D_HH
Index: mln/core/rectangle2d.hh
--- mln/core/rectangle2d.hh	(revision 1020)
+++ mln/core/rectangle2d.hh	(working copy)
@@ -47,13 +47,11 @@
    * A rectangle2d is a 2D window with rectangular shape.  It is
    * centered and symmetrical.
    *
-   * For instance:
-   *  o o o o o
-   *  o o x o o
-   *  o o o o o
-   * is defined with half_height = 1 and half_width = 2.
-   *
-   * \todo Consider width instead of half_width (same for height).
+   * For instance: \n
+   *  o o o o o \n
+   *  o o x o o \n
+   *  o o o o o \n
+   * is defined with height = 3 and width = 5.
    */
   struct rectangle2d : public Window< rectangle2d >,
 		       public internal::set_of_<dpoint2d>
@@ -80,12 +78,12 @@
 
     /*! \brief Constructor.
      *
-     * \param[in] half_height sic
-     * \param[in] half_width sic
+     * \param[in] height sic
+     * \param[in] width sic
      *
-     * \pre half_height != 0 and half_width != 0
+     * \pre Height and width are odd.
      */
-    rectangle2d(unsigned half_height, unsigned half_width);
+    rectangle2d(unsigned height, unsigned width);
 
     /*! \brief Test if the window is centered.
      *
@@ -116,7 +114,7 @@
     rectangle2d sym_() const;
 
   protected:
-    unsigned half_height_, half_width_;
+    unsigned height_, width_;
   };
 
 
@@ -136,12 +134,12 @@
 
 # ifndef MLN_INCLUDE_ONLY
 
-  rectangle2d::rectangle2d(unsigned half_height, unsigned half_width)
-    : half_height_(half_height),
-      half_width_(half_width)
+  rectangle2d::rectangle2d(unsigned height, unsigned width)
+    : height_(height),
+      width_(width)
   {
-    mln_precondition(half_height != 0 && half_width != 0);
-    const int drow = half_height, dcol = half_width;
+    mln_precondition(height % 2 = 1 && width % 2 = 1);
+    const int drow = height / 2, dcol = width / 2;
     for (int row = - drow; row <= drow; ++row)
       for (int col = - dcol; col <= dcol; ++col)
 	insert(make::dpoint2d(row, col));
@@ -159,17 +157,17 @@
 
   unsigned rectangle2d::height() const
   {
-    return 2 * half_height_ + 1;
+    return height_;
   }
 
   unsigned rectangle2d::width() const
   {
-    return 2 * half_width_ + 1;
+    return width_;
   }
 
   unsigned rectangle2d::delta() const
   {
-    return half_width_ > half_height_ ? half_width_ : half_height_;
+    return width_ > height_ ? width_ / 2 : height_ / 2;
   }
 
   rectangle2d rectangle2d::sym_() const
@@ -177,10 +175,9 @@
     return *this;
   }
 
-  std::ostream& operator<<(std::ostream& ostr,
-			   const rectangle2d& win)
+  std::ostream& operator<<(std::ostream& ostr, const rectangle2d& win)
   {
-    ostr << "[width=" << win.width() << ", height=" << win.height() << ']';
+    ostr << "[rectangle2d: width=" << win.width() << ", height=" << win.height() << ']';
     return ostr;
   }
 
@@ -190,4 +187,9 @@
 
 
 
+// when rectangle2d is involved, one surely also wants:
+# include <mln/core/hline2d.hh>
+# include <mln/core/vline2d.hh>
+
+
 #endif // ! MLN_CORE_RECTANGLE2D_HH
Index: mln/core/vline2d.hh
--- mln/core/vline2d.hh	(revision 0)
+++ mln/core/vline2d.hh	(revision 0)
@@ -0,0 +1,178 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction.  Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License.  This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_CORE_VLINE2D_HH
+# define MLN_CORE_VLINE2D_HH
+
+/*! \file mln/core/vline2d.hh
+ *
+ * \brief Definition of the mln::vline2d window.
+ */
+
+# include <mln/core/concept/window.hh>
+# include <mln/core/internal/set_of.hh>
+# include <mln/core/dpoint2d.hh>
+# include <mln/core/dpoints_piter.hh>
+
+
+namespace mln
+{
+ 
+  /*! \brief Vertical line window defined on the 2D square grid.
+   *
+   * An vline2d is centered and symmetrical; so its width is 1 and
+   * its height (length) is odd.
+   *
+   * For instance: \n
+   *  o \n
+   *  x \n
+   *  o \n
+   * is defined with length = 5.
+   */
+  struct vline2d : public Window< vline2d >,
+		   public internal::set_of_<dpoint2d>
+  {
+    /// Point associated type.
+    typedef point2d point;
+
+    /// Dpoint associated type.
+    typedef dpoint2d dpoint;
+
+    /*! \brief Piter type to browse a vline such as: "for each row
+     * (increasing), for each column (increasing)."
+     */
+    typedef dpoints_fwd_piter<dpoint2d> fwd_qiter;
+
+    /*! \brief Piter type to browse a vline such as: "for each row
+     * (decreasing), for each column (decreasing)."
+     */
+    typedef dpoints_fwd_piter<dpoint2d> bkd_qiter; // FIXME: bkd!!!
+
+    /*! \brief Same as fwd_qiter.
+     */
+    typedef fwd_qiter qiter;
+
+    /*! \brief Constructor.
+     *
+     * \param[in] length Length, thus height, of the vertical line.
+     *
+     * \pre \p length is odd.
+     */
+    vline2d(unsigned length);
+
+    /*! \brief Test if the window is centered.
+     *
+     * \return True.
+     */
+    bool is_centered() const;
+
+    /*! \brief Test if the window is symmetric.
+     *
+     * \return true.
+     */
+    bool is_symmetric() const;
+
+    /*! \brief Give the vline length, that is, its height.
+     */
+    unsigned length() const;
+
+    /*! \brief Give the maximum coordinate gap between the window
+     * center and a window point.
+     */
+    unsigned delta() const;
+
+    /// Get the symmetrical window.
+    vline2d sym_() const;
+
+  protected:
+    unsigned length_;
+  };
+
+
+  /*! \brief Print a vertical 2D line window \p win into the output
+   *  stream \p ostr.
+   *
+   * \param[in,out] ostr An output stream.
+   * \param[in] win A vertical 2D line window.
+   *
+   * \return The modified output stream \p ostr.
+   *
+   * \relates mln::vline2d
+   */
+  std::ostream& operator<<(std::ostream& ostr, const vline2d& win);
+
+ 
+
+# ifndef MLN_INCLUDE_ONLY
+
+  vline2d::vline2d(unsigned length)
+    : length_(length)
+  {
+    mln_precondition(length % 2 = 1);
+    const int drow = length / 2;
+    for (int row = - drow; row <= drow; ++row)
+      insert(make::dpoint2d(row, 0));
+  }
+
+  bool vline2d::is_centered() const
+  {
+    return true;
+  }
+
+  bool vline2d::is_symmetric() const
+  {
+    return true;
+  }
+
+  unsigned vline2d::length() const
+  {
+    return length_;
+  }
+
+  unsigned vline2d::delta() const
+  {
+    return length_ / 2;
+  }
+
+  vline2d vline2d::sym_() const
+  {
+    return *this;
+  }
+
+  std::ostream& operator<<(std::ostream& ostr, const vline2d& win)
+  {
+    ostr << "[line2d: length=" << win.length() << ']';
+    return ostr;
+  }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+} // end of namespace mln
+
+
+
+#endif // ! MLN_CORE_VLINE2D_HH
Index: mln/morpho/erosion.hh
--- mln/morpho/erosion.hh	(revision 1020)
+++ mln/morpho/erosion.hh	(working copy)
@@ -106,6 +106,7 @@
 
       // FIXME: stage 3: dispatch w.r.t. fast property
 
+
       // stage 2: dispatch w.r.t. the value kind
 
       template <typename I, typename W, typename O>
@@ -123,19 +124,34 @@
       }
 
 
+
       // stage 1: dispatch w.r.t. the window type
+      //   |
+      //   V
 
-      template <typename I, typename W, typename O> // general case
+      template <typename I, typename W, typename O>
       void erosion_wrt_win(const Image<I>& input, const Window<W>& win, Image<O>& output)
       {
 	erosion_wrt_value(mln_kind(I)(), exact(input), exact(win), output);
+	//                   | 
+	//                    -->  call stage 2: dispatch w.r.t. the value kind
       }
 
-//       template <typename I, typename O> // rectangle2d
-//       void erosion_wrt_win(const Image<I>& input, const rectangle2d& win, Image<O>& output)
-//       {
-// 	return FIXME;
-//       }
+#  ifdef MLN_CORE_RECTANGLE2D_HH
+
+      template <typename I, typename O>
+      void erosion_wrt_win(const Image<I>& input, const rectangle2d& win, Image<O>& output)
+      {
+	O tmp(exact(output).domain());
+	morpho::erosion(input, hline2d(win.width()),  tmp);
+	morpho::erosion(tmp,   vline2d(win.height()), output);
+      }
+
+#  endif // MLN_CORE_RECTANGLE2D_HH
+
+      //   ^
+      //   |
+      // end of stage1 (dispatch w.r.t. the window type)
       
 
     } // end of namespace mln::morpho::impl
@@ -146,6 +162,9 @@
     template <typename I, typename W, typename O>
     void erosion(const Image<I>& input, const Window<W>& win, Image<O>& output)
     {
+      mln_precondition(exact(output).domain() = exact(input).domain());
+      mln_precondition(! exact(win).is_empty());
+
       impl::erosion_wrt_win(input, exact(win), output);
       if (exact(win).is_centered())
 	mln_postcondition(output <= input);
Index: mln/level/was.median.hh
--- mln/level/was.median.hh	(revision 0)
+++ mln/level/was.median.hh	(revision 0)
@@ -0,0 +1,136 @@
+// 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_LEVEL_WAS_MEDIAN_HH
+# define MLN_LEVEL_WAS_MEDIAN_HH
+
+/*! \file mln/level/was.median.hh
+ *
+ * \brief Obsolete routine for the median filter.
+ */
+
+
+namespace mln
+{
+
+  namespace level
+  {
+
+    namespace impl
+    {
+
+      template <typename I, typename W, typename O>
+      void median_as_procedure(const I& input,
+			       const W& win,
+			       O& output)
+      {
+	mln_precondition(input.has_data());
+	mln_precondition(output.has_data());
+
+	int
+	  min_row = input.min_row(), max_row = input.max_row(),
+	  min_col = input.min_col(), max_col = input.max_col();
+
+	window2d
+	  win_fwd_plus  = win - (win + left),
+	  win_fwd_minus = (win + left) - win,
+	  win_bkd_plus  = win - (win + right),
+	  win_bkd_minus = (win + right) - win,
+	  win_bot  = win - (win + up),
+	  win_top = (win + up) - win;
+
+	point2d p;
+	mln_qiter(W)
+	  q_fp(win_fwd_plus, p), q_fm(win_fwd_minus, p),
+	  q_bp(win_bkd_plus, p), q_bm(win_bkd_minus, p),
+	  q_top(win_top, p), q_bot(win_bot, p);
+	
+	accu::median_on<mln_value(I)> med;
+
+	// initialization
+
+	p = input.domain().pmin() + up;
+	med.init();
+	{
+	  mln_qiter(W) q(win, p);
+	  for_all(q) if (input.has(q))
+	    med.take(input(q));
+	}
+
+	int& row = p.row();
+	int& col = p.col();
+	bool fwd = true;
+
+	mln_assertion(p.col() = min_col);
+	mln_assertion(p.row() = min_row - 1);
+
+	for (row = min_row; row <= max_row; ++row)
+	  {
+	    // "go down"
+	    for_all(q_top) if (input.has(q_top))
+	      med.untake(input(q_top));
+	    for_all(q_bot) if (input.has(q_bot))
+	      med.take(input(q_bot));
+	    output(p) = med;
+
+	    if (fwd)
+	      // browse line fwd
+	      while (col < max_col)
+		{
+		  ++col;
+		  for_all(q_fm) if (input.has(q_fm))
+		    med.untake(input(q_fm));
+		  for_all(q_fp) if (input.has(q_fp))
+		    med.take(input(q_fp));
+		  output(p) = med;
+		}
+	    else
+	      // browse line bkd
+	      while (col > min_col)
+		{
+		  --col;
+		  for_all(q_bm) if (input.has(q_bm))
+		    med.untake(input(q_bm));
+		  for_all(q_bp) if (input.has(q_bp))
+		    med.take(input(q_bp));
+		  output(p) = med;
+		}
+
+	    // change browsing
+	    fwd = ! fwd;
+	  }
+      }
+
+
+    } // end of namespace mln::level::impl
+
+  } // end of namespace mln::level
+
+} // end of namespace mln
+
+
+#endif // ! MLN_LEVEL_WAS_MEDIAN_HH
Index: mln/level/approx/median.hh
--- mln/level/approx/median.hh	(revision 0)
+++ mln/level/approx/median.hh	(revision 0)
@@ -0,0 +1,90 @@
+// 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_LEVEL_APPROX_MEDIAN_HH
+# define MLN_LEVEL_APPROX_MEDIAN_HH
+
+/*! \file mln/level/median.hh
+ *
+ * \brief Approximates of some median filters of an image.
+ */
+
+# include <mln/level/median.hh>
+# include <mln/core/rectangle2d.hh>
+
+
+namespace mln
+{
+
+  namespace level
+  {
+
+    namespace approx
+    {
+
+      /*! Compute in \p output an approximate of the median filter of
+       *  image \p input by the 2D rectangle \p win.
+       *
+       * \param[in] input The image to be filtered.
+       * \param[in] win The rectangle.
+       * \param[in,out] output The output image.
+       *
+       * The approximation is based on a vertical median ran after
+       * an horizontal median.
+       *
+       * \pre \p input and \p output have to be initialized.
+       */
+      template <typename I, typename O>
+      void median(const Image<I>& input, const rectangle2d& win,
+		  Image<O>& output);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+      template <typename I, typename O>
+      void median(const Image<I>& input_, const rectangle2d& win,
+		  Image<O>& output_)
+      {
+	const I& input = exact(input_);
+	O& output = exact(output_);
+	mln_assertion(output.domain() = input.domain());
+
+	O tmp(output.domain());
+	level::median(input, hline2d(win.width()),  tmp);
+	level::median(tmp,   vline2d(win.height()), output);
+      }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+    } // end of namespace mln::level::approx
+
+  } // end of namespace mln::level
+
+} // end of namespace mln
+
+
+#endif // ! MLN_LEVEL_APPROX_MEDIAN_HH
Index: mln/level/median.hh
--- mln/level/median.hh	(revision 1020)
+++ mln/level/median.hh	(working copy)
@@ -34,9 +34,11 @@
  */
 
 # include <mln/core/concept/image.hh>
+
 # include <mln/core/window2d.hh>
-# include <mln/accu/median.hh>
+# include <mln/core/hline2d.hh>
 
+# include <mln/accu/median.hh>
 # include <mln/canvas/sbrowsing.hh>
 
 
@@ -66,88 +68,6 @@
     namespace impl
     {
 
-      template <typename I, typename W, typename O>
-      void median_as_procedure(const I& input,
-			       const W& win,
-			       O& output)
-      {
-	mln_precondition(input.has_data());
-	mln_precondition(output.has_data());
-
-	int
-	  min_row = input.min_row(), max_row = input.max_row(),
-	  min_col = input.min_col(), max_col = input.max_col();
-
-	window2d
-	  win_fwd_plus  = win - (win + left),
-	  win_fwd_minus = (win + left) - win,
-	  win_bkd_plus  = win - (win + right),
-	  win_bkd_minus = (win + right) - win,
-	  win_bot  = win - (win + up),
-	  win_top = (win + up) - win;
-
-	point2d p;
-	mln_qiter(W)
-	  q_fp(win_fwd_plus, p), q_fm(win_fwd_minus, p),
-	  q_bp(win_bkd_plus, p), q_bm(win_bkd_minus, p),
-	  q_top(win_top, p), q_bot(win_bot, p);
-	
-	accu::median_on<mln_value(I)> med;
-
-	// initialization
-
-	p = input.domain().pmin() + up;
-	med.init();
-	{
-	  mln_qiter(W) q(win, p);
-	  for_all(q) if (input.has(q))
-	    med.take(input(q));
-	}
-
-	int& row = p.row();
-	int& col = p.col();
-	bool fwd = true;
-
-	mln_assertion(p.col() = min_col);
-	mln_assertion(p.row() = min_row - 1);
-
-	for (row = min_row; row <= max_row; ++row)
-	  {
-	    // "go down"
-	    for_all(q_top) if (input.has(q_top))
-	      med.untake(input(q_top));
-	    for_all(q_bot) if (input.has(q_bot))
-	      med.take(input(q_bot));
-	    output(p) = med;
-
-	    if (fwd)
-	      // browse line fwd
-	      while (col < max_col)
-		{
-		  ++col;
-		  for_all(q_fm) if (input.has(q_fm))
-		    med.untake(input(q_fm));
-		  for_all(q_fp) if (input.has(q_fp))
-		    med.take(input(q_fp));
-		  output(p) = med;
-		}
-	    else
-	      // browse line bkd
-	      while (col > min_col)
-		{
-		  --col;
-		  for_all(q_bm) if (input.has(q_bm))
-		    med.untake(input(q_bm));
-		  for_all(q_bp) if (input.has(q_bp))
-		    med.take(input(q_bp));
-		  output(p) = med;
-		}
-
-	    // change browsing
-	    fwd = ! fwd;
-	  }
-      }
-
 
       template <typename I, typename W, typename O>
       struct median_functor
@@ -167,7 +87,7 @@
 
 	// ctor
 
-	median_functor(I& input_, const W& win_, O& output_)
+	median_functor(const I& input_, const W& win_, O& output_)
 	  :
 	  // i/o
 	  input(exact(input_)),
@@ -224,15 +144,79 @@
       }; // end of median_functor
 
 
+
+
       template <typename I, typename W, typename O>
-      void median(I& input, const W& win, O& output)
+      void median(const I& input, const Window<W>& win, O& output)
       {
 	// FIXME: resize border!
-	impl::median_functor<I,W,O> f(input, win, output);
+	impl::median_functor<I,W,O> f(input, exact(win), output);
 	canvas::sbrowsing(f);
       }
 
 
+
+
+      template <typename I, typename O>
+      void median(const I& input, const hline2d& win, O& output)
+      {
+	const int
+	  max_row = input.max_row(),
+	  min_col = input.min_col(),
+	  max_col = input.max_col();
+	const unsigned half = win.length() / 2;
+
+	point2d p;
+	int& row = p.row();
+	int& col = p.col();
+
+	accu::median_on<mln_value(I)> med;
+
+	for (row = input.min_row(); row <= max_row; ++row)
+	  {
+	    int ct, cu;
+
+	    // initialization (before first point of the row)
+	    med.init();
+	    for (ct = min_col; ct < min_col + half; ++ct)
+	      med.take(input.at(row, ct));
+
+	    // left columns (just take new points)
+	    for (col = min_col; col <= min_col + half; ++col, ++ct)
+	      {
+		med.take(input.at(row, ct));
+		output(p) = med;
+	      }
+	    
+	    // middle columns (both take and untake)
+	    cu = min_col;
+	    for (; col <= max_col - half; ++cu, ++col, ++ct)
+	      {
+		med.take(input.at(row, ct));
+		med.untake(input.at(row, cu));
+		output(p) = med;
+	      }
+
+	    // right columns (now just untake old points)
+	    for (; col <= max_col; ++cu, ++col)
+	      {
+		med.untake(input.at(row, cu));
+		output(p) = med;
+	      }
+	  }
+      }
+
+
+      // FIXME: Use transpose.
+
+//       template <typename I, typename O>
+//       void median(const I& input, const vline2d& win, O& output)
+//       {
+
+// 	median(, hline2d(win.length()), output);
+//       }
+
+
     } // end of namespace mln::level::impl
 
 
@@ -242,6 +226,7 @@
     void median(const Image<I>& input, const Window<W>& win,
 		Image<O>& output)
     {
+      mln_assertion(exact(output).domain() = exact(input).domain());
       impl::median(exact(input), exact(win), exact(output)); 
     }
 
Index: mln/level/was.hmedian.hh
--- mln/level/was.hmedian.hh	(revision 0)
+++ mln/level/was.hmedian.hh	(revision 0)
@@ -0,0 +1,102 @@
+// 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_LEVEL_WAS_HMEDIAN_HH
+# define MLN_LEVEL_WAS_HMEDIAN_HH
+
+/*! \file mln/level/was.hmedian.hh
+ *
+ * \brief Median filtering of an image.
+ */
+
+
+namespace mln
+{
+
+  namespace level
+  {
+
+    namespace impl
+    {
+
+      template <typename I, typename O>
+      void hmedian(const I& input, const hline2d& win, O& output)
+      {
+	const int
+	  max_row = input.max_row(),
+	  min_col = input.min_col(),
+	  max_col = input.max_col();
+	const unsigned half = win.length() / 2;
+
+	point2d p;
+	int& row = p.row();
+	int& col = p.col();
+
+	accu::median_on<mln_value(I)> med;
+
+	for (row = input.min_row(); row <= max_row; ++row)
+	  {
+	    int ct, cu;
+
+	    // initialization (before first point of the row)
+	    med.init();
+	    for (ct = min_col; ct < min_col + half; ++ct)
+	      med.take(input.at(row, ct));
+
+	    // left columns (just take new points)
+	    for (col = min_col; col <= min_col + half; ++col, ++ct)
+	      {
+		med.take(input.at(row, ct));
+		output(p) = med;
+	      }
+	    
+	    // middle columns (both take and untake)
+	    cu = min_col;
+	    for (; col <= max_col - half; ++cu, ++col, ++ct)
+	      {
+		med.take(input.at(row, ct));
+		med.untake(input.at(row, cu));
+		output(p) = med;
+	      }
+
+	    // right columns (now just untake old points)
+	    for (; col <= max_col; ++cu, ++col)
+	      {
+		med.untake(input.at(row, cu));
+		output(p) = med;
+	      }
+	  }
+      }
+
+    } // end of namespace mln::level::impl
+
+  } // end of namespace mln::level
+
+} // end of namespace mln
+
+
+#endif // ! MLN_LEVEL_WAS_HMEDIAN_HH
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    17 Jul '07
                    
                        https://svn.lrde.epita.fr/svn/oln/trunk/olena
Index: ChangeLog
from  Roland Levillain  <roland(a)lrde.epita.fr>
	Use SCOOP mechanism from static/stc/, not olena/oln/stc/.
	* oln/core/equipment.hh: Include stc/scoop.hh (resp. stc/scoop.hxx)
	instead of oln/stc/scoop.hh (resp. oln/stc/scoop.hxx).
	* oln/stc/scoop.hh, oln/stc/scoop.hxx: Remove.
	* oln/stc: Remove directory.
 equipment.hh |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
Index: oln/core/equipment.hh
--- oln/core/equipment.hh	(revision 1019)
+++ oln/core/equipment.hh	(working copy)
@@ -30,7 +30,7 @@
 
 # include <mlc/contract.hh>
 # ifndef OLENA_USE_SCOOP_ALT
-#   include <oln/stc/scoop.hh> // FIXME: Remove "oln/" later.
+#   include <stc/scoop.hh>
 # else
 #   include <stc/scoop-alt.hh>
 # endif
@@ -46,7 +46,7 @@
 {
 
 # ifndef OLENA_USE_SCOOP_ALT
-#  include <oln/stc/scoop.hxx> // FIXME: Remove "oln/" later.
+#  include <stc/scoop.hxx>
 # else
 #  include <stc/scoop-alt.inc>
 # endif
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    17 Jul '07
                    
                        https://svn.lrde.epita.fr/svn/oln/trunk/static
Index: ChangeLog
from  Roland Levillain  <roland(a)lrde.epita.fr>
	Update stc/scoop.{hh,hxx} with the latest version from Olena.
	* stc/was.scoop.hh: Rename as...
	* stc/scoop-old-2006.hh: ...this.
	* stc/scoop.hh: Rename as...
	* stc/scoop-old-2007.hh: ...this.
	* stc/scoop.hh, stc/scoop.hxx: New.
	Imported from olena/stc/.
 0 files changed
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    17 Jul '07
                    
                        https://svn.lrde.epita.fr/svn/oln/trunk/olena
Index: ChangeLog
from  Roland Levillain  <roland(a)lrde.epita.fr>
	Have more tests pass with scoop-alt, and clean up a bit.
	Despite the new proxy-deferred mechanism in scoop-alt, a lot of
	tests still fail to compile.  A real deferring mechanism (as in
	standard scoop) is required.
	* oln/core/2d/image2d.hh (super_trait_< image2d<T> >): Move this
	class above vtypes< image2d<T> >.
	* oln/core/internal/box.hh
	(vtypes< box_fwd_piter_<B> >::point)
	(vtypes< box_bkd_piter_<B> >::point): Use stc_deduce_typename
	instead of a bare B::point.
	(box_fwd_piter_, box_bkd_piter_) [OLENA_USE_SCOOP_ALT]: Don't
	check static assertions (mlc_is_a(B, Point_Set)), since scoop-alt
	doesn't handle it yet.
	* oln/core/internal/f_ch_value.hh (oln_ch_value_, oln_ch_value)
	(oln_plain_value) [OLENA_USE_SCOOP_ALT]: Rely on stc_find_type_in
	instead of stc_type_in since scoop-alt doesn't handle it yet.
	* oln/core/internal/image_base.hh,
	* oln/core/internal/encoded_image.hh,
	* oln/core/gen/rle_image.hh,
	* oln/core/gen/sparse_image.hh,
	* oln/core/internal/dpoint_base.hh,
	* oln/core/internal/point_base.hh,
	* oln/core/internal/iterator_on_points_base.hh,
	* oln/core/internal/piter_adaptor.hh
	* oln/core/internal/neighborhood_base.hh,
	[OLENA_USE_SCOOP_ALT]: Handle deferred vtypes � la scoop-alt.
	* oln/core/internal/point_set_base.hh: Likewise.
	(super_trait_< internal::point_set_base_<Exact> >::ret): Set to
	mlc::none.
	(point_set_base_): Adjust super class: inherit from
	internal::point_set_selector_< stc_type(Exact, box)*, Exact >.
	instead of super_trait_< point_set_base_<Exact> >::ret.
	* oln/core/internal/dpoint_base.hh
	(super_trait_< internal::dpoint_base_<Exact> >::ret)
	* oln/core/internal/point_base.hh
	(super_trait_< internal::point_base_<Exact> >::ret):
	* oln/core/internal/iterator_on_points_base.hh
	Set to mlc::none.
	* oln/core/internal/category_of.hh: Rewrite the category
	retrieval, so that super_traits_ relationships not ending with
	mlc::none are caught.
	(get_category_of_): Remove.
	Replaced by...
	(get_category_as_a_typedef_, get_category_as_a_vtype_):
	...these (new) classes.
	(category_of_): Adjust.
	* oln/core/internal/encoded_image_pset.hh
	(vtypes< internal::enc_image_pset_<P> >::std_container): New
	typedef.
	(enc_image_pset_::std_container): New typedef.
	Use it to define...
	(enc_image_pset_piter_::con_): ...this member.
	(enc_image_pset_fwd_piter_, enc_image_pset_bkd_piter_):
	Use stc_using to retrieve the vtype std_container.
	Use it to define...
	(enc_image_pset_fwd_piter_::it_, enc_image_pset_bkd_piter_::it_):
	...these members.
	* tests/core/box2d.cc: New test.
	* tests/core/Makefile.am (check_PROGRAMS): Add box2d.
	(box2d_SOURCES): New.
	* oln/Makefile.am (nobase_oln_HEADERS): Remove dead files.
	Add value/gray_level.hh.
 oln/Makefile.am                              |   26 +--------------
 oln/core/2d/image2d.hh                       |   18 +++++-----
 oln/core/equipment.hh                        |    2 -
 oln/core/gen/rle_image.hh                    |   20 ++++++++++-
 oln/core/gen/sparse_image.hh                 |   21 +++++++++++-
 oln/core/internal/box.hh                     |   20 ++++++++---
 oln/core/internal/category_of.hh             |   46 +++++++++++++++++++++------
 oln/core/internal/dpoint_base.hh             |   13 ++++++-
 oln/core/internal/encoded_image.hh           |   15 ++++++++
 oln/core/internal/encoded_image_pset.hh      |   19 +++++++----
 oln/core/internal/f_ch_value.hh              |   20 ++++++++++-
 oln/core/internal/image_base.hh              |    8 ++++
 oln/core/internal/image_selectors.hh         |    2 -
 oln/core/internal/iterator_on_points_base.hh |   20 ++++++++++-
 oln/core/internal/neighborhood_base.hh       |    5 ++
 oln/core/internal/piter_adaptor.hh           |    4 ++
 oln/core/internal/point_base.hh              |    9 ++++-
 oln/core/internal/point_set_base.hh          |   12 +++++--
 tests/core/Makefile.am                       |    2 +
 tests/core/box2d.cc                          |   37 +++++++++++++++++++++
 20 files changed, 251 insertions(+), 68 deletions(-)
Index: tests/core/box2d.cc
--- tests/core/box2d.cc	(revision 0)
+++ tests/core/box2d.cc	(revision 0)
@@ -0,0 +1,37 @@
+// 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.
+
+#include <oln/core/2d/box2d.hh>
+
+
+int
+main()
+{
+  typedef oln::box2d box_t;
+  mlc::assert_< mlc_is_a_( box_t, oln::Point_Set ) >::check();
+  mlc::assert_< mlc_is_a_( box_t, oln::Box ) >::check();
+}
Index: tests/core/Makefile.am
--- tests/core/Makefile.am	(revision 1017)
+++ tests/core/Makefile.am	(working copy)
@@ -21,6 +21,7 @@
 check_PROGRAMS =				\
   apply						\
   at						\
+  box2d						\
   dpoint2d					\
   grid						\
   image1d					\
@@ -51,6 +52,7 @@
 
 # Images and auxiliary structures.
 dpoint2d_SOURCES = dpoint2d.cc
+box2d_SOURCES = box2d.cc
 grid_SOURCES = grid.cc
 image1d_SOURCES = image1d.cc
 image2d_SOURCES = image2d.cc
Index: oln/core/2d/image2d.hh
--- oln/core/2d/image2d.hh	(revision 1017)
+++ oln/core/2d/image2d.hh	(working copy)
@@ -43,6 +43,15 @@
   template <typename T> class image2d;
 
 
+  /// Super type.
+  template <typename T>
+  struct super_trait_< image2d<T> >
+  {
+    typedef image2d<T> current;
+    typedef internal::plain_primitive_image_<current> ret;
+  };
+
+
   // Virtual types.
   template <typename T>
   struct vtypes< image2d<T> >
@@ -66,15 +75,6 @@
   };
 
 
-  /// Super type.
-  template <typename T>
-  struct super_trait_< image2d<T> >
-  {
-    typedef image2d<T> current;
-    typedef internal::plain_primitive_image_<current> ret;
-  };
-
-
   /// General 2D image class.
 
   template <typename T>
Index: oln/core/equipment.hh
--- oln/core/equipment.hh	(revision 1017)
+++ oln/core/equipment.hh	(working copy)
@@ -170,8 +170,8 @@
 
 
 
-/// \{
 /// FIXME: Bad!
+/// \{
 
 # include <oln/core/init.hh>
 
Index: oln/core/gen/rle_image.hh
--- oln/core/gen/rle_image.hh	(revision 1017)
+++ oln/core/gen/rle_image.hh	(working copy)
@@ -59,10 +59,26 @@
     typedef P point;
     typedef typename P::coord coord;
 
-    typedef typename vtypes< internal::encoded_image_< rle_image<P, T> > >::pset pset__;
+#ifndef OLENA_USE_SCOOP_ALT
+  private:
+    typedef rle_image<P, T> self__;
+  public:
+    typedef std::pair< stc_deferred_type(self__, pset),
+		       std::vector< value > > data;
+#endif
+  };
 
-    typedef std::pair< pset__, std::vector< value > > data;
+#ifdef OLENA_USE_SCOOP_ALT
+  template <typename P, typename T>
+  struct single_vtype< rle_image<P, T>, typedef_::data >
+  {
+  private:
+    typedef rle_image<P, T> self__;
+    typedef T value__;
+  public:
+    typedef std::pair< stc_type(self__, pset), std::vector< value__ > > ret;
   };
+#endif
 
 
   // rle_image
Index: oln/core/gen/sparse_image.hh
--- oln/core/gen/sparse_image.hh	(revision 1017)
+++ oln/core/gen/sparse_image.hh	(working copy)
@@ -61,10 +61,27 @@
     typedef P point;
     typedef typename P::coord coord;
 
-    typedef typename vtypes< internal::encoded_image_< sparse_image<P, T> > >::pset pset__;
+#ifndef OLENA_USE_SCOOP_ALT
+  private:
+    typedef sparse_image<P, T> self__;
+  public:
+    typedef std::pair< stc_deferred_type(self__, pset),
+		       std::vector <std::vector<value> > > data;
+#endif
+  };
 
-    typedef std::pair< pset__, std::vector <std::vector<value> > > data;
+#ifdef OLENA_USE_SCOOP_ALT
+  template <typename P, typename T>
+  struct single_vtype< sparse_image<P, T>, typedef_::data >
+  {
+  private:
+    typedef sparse_image<P, T> self__;
+    typedef T value__;
+  public:
+    typedef std::pair< stc_type(self__, pset),
+		       std::vector< std::vector<value__> > > ret;
   };
+#endif
 
   // sparse_image class
   template < typename P, typename T>
Index: oln/core/internal/dpoint_base.hh
--- oln/core/internal/dpoint_base.hh	(revision 1017)
+++ oln/core/internal/dpoint_base.hh	(working copy)
@@ -45,7 +45,9 @@
   template <typename Exact>
   struct super_trait_< internal::dpoint_base_<Exact> >
   {
-    typedef Dpoint<Exact> ret;
+    // super_trait_ set to mlc::none, since Point is a concept
+    // (interface).
+    typedef mlc::none ret;
   };
 
   template <typename Exact>
@@ -54,7 +56,13 @@
     typedef stc::abstract grid;
 
     typedef stc_deferred(grid) grid__;
+
+    // FIXME: Improve scoop-alt to get rid of this difference.
+# ifndef OLENA_USE_SCOOP_ALT
     typedef stc::final< oln_dim(grid__) > dim;
+# else
+    typedef stc::final< stc_deferred_from(grid__, dim) > dim;
+# endif
 
     typedef stc::abstract coord;
     typedef stc::abstract point; // FIXME: Just like in point_base.hh
@@ -66,7 +74,8 @@
   namespace internal
   {
 
-    // FIXME: Factor code for classes defined over vectors (dpoint_base_ and point_base_).
+    // FIXME: Factor code for classes defined over vectors
+    // (dpoint_base_ and point_base_).
 
     template <typename Exact>
     class dpoint_base_ : public Dpoint<Exact>
Index: oln/core/internal/box.hh
--- oln/core/internal/box.hh	(revision 1017)
+++ oln/core/internal/box.hh	(working copy)
@@ -133,21 +133,25 @@
   template <typename B>
   struct vtypes< box_fwd_piter_<B> >
   {
-    typedef typename B::point point;
+    stc_deduce_typename(B, point);
   };
 
   template <typename B>
   struct vtypes< box_bkd_piter_<B> >
   {
-    typedef typename B::point point;
+    stc_deduce_typename(B, point);
   };
 
 
   /// Class box_fwd_piter_<P>.
 
   template <typename B>
-  class box_fwd_piter_ : public internal::iterator_on_points_base_< box_fwd_piter_<B> >,
-			 private mlc::assert_< mlc_is_a(B, Point_Set) >
+  class box_fwd_piter_ : public internal::iterator_on_points_base_< box_fwd_piter_<B> >
+  // FIXME: It seems we cannot check this assertion using while using
+  // scoop-alt.  Investigate.
+# ifndef OLENA_USE_SCOOP_ALT
+		       , private mlc::assert_< mlc_is_a(B, Point_Set) >
+# endif
   {
     typedef box_fwd_piter_<B> current;
     typedef internal::iterator_on_points_base_<current> super;
@@ -172,8 +176,12 @@
   /// Class box_bkd_piter_<B>.
 
   template <typename B>
-  class box_bkd_piter_ : public internal::iterator_on_points_base_< box_bkd_piter_<B> >,
-			 private mlc::assert_< mlc_is_a(B, Point_Set) >
+  class box_bkd_piter_ : public internal::iterator_on_points_base_< box_bkd_piter_<B> >
+  // FIXME: It seems we cannot check this assertion using while using
+  // scoop-alt.  Investigate.
+# ifndef OLENA_USE_SCOOP_ALT
+		       , private mlc::assert_< mlc_is_a(B, Point_Set) >
+# endif
   {
     typedef box_bkd_piter_<B> current;
     typedef internal::iterator_on_points_base_<current> super;
Index: oln/core/internal/f_ch_value.hh
--- oln/core/internal/f_ch_value.hh	(revision 1017)
+++ oln/core/internal/f_ch_value.hh	(working copy)
@@ -30,16 +30,32 @@
 
 # include <oln/core/internal/image_base.hh>
 
-
+// FIXME: scoop-alt is not robust to vtype checks (is_defined).
+# ifndef OLENA_USE_SCOOP_ALT
 #define oln_ch_value_(I, T) \
 oln::internal::f_ch_value_< stc_type_in_(oln, I, skeleton), T >::ret
 
 #define oln_ch_value(I, T) \
 typename oln::internal::f_ch_value_< stc_type_in(oln, I, skeleton), T >::ret
 
+#  define oln_plain_value(I, T)				\
+    typename oln::internal::f_ch_value_<		\
+      stc_type_in(oln, oln_plain(I), skeleton), T	\
+    >::ret
+# else
+#  define oln_ch_value_(I, T)						\
+    oln::internal::f_ch_value_< stc_find_type_in_(oln, I, skeleton), T >::ret
+
+#  define oln_ch_value(I, T)			\
+    typename oln::internal::f_ch_value_<	\
+      stc_find_type_in(oln, I, skeleton), T	\
+    >::ret
 
 # define oln_plain_value(I, T) \
-typename oln::internal::f_ch_value_< stc_type_in(oln, oln_plain(I), skeleton), T >::ret
+    typename oln::internal::f_ch_value_<		\
+      stc_find_type_in(oln, oln_plain(I), skeleton), T	\
+    >::ret
+# endif
 
 
 
Index: oln/core/internal/point_set_base.hh
--- oln/core/internal/point_set_base.hh	(revision 1017)
+++ oln/core/internal/point_set_base.hh	(working copy)
@@ -60,7 +60,9 @@
   template <typename Exact>
   struct super_trait_< internal::point_set_base_<Exact> >
   {
-    typedef internal::point_set_selector_< stc_deferred(box)*, Exact > ret;
+    // Set to mlc::none, since Point_Set and Box (the super classes of
+    // point_set_selector) are both concepts.
+    typedef mlc::none ret;
   };
 
 
@@ -77,7 +79,12 @@
     typedef stc_deferred(fwd_piter) fwd_piter__;
 
     typedef stc::final< stc::is<Point_Set> > category;
+    // FIXME: Improve scoop-alt to get rid of this difference.
+# ifndef OLENA_USE_SCOOP_ALT
     typedef stc::final< oln_grid(point__) >  grid;
+# else
+    typedef stc::final< stc_deferred_from(point__, grid) > grid;
+# endif
     // typedef stc::final< oln_coord(point__) > coord;
     typedef stc::final< fwd_piter__ >        piter;
   };
@@ -89,7 +96,8 @@
     /// Base class for point sets.
 
     template <typename Exact>
-    struct point_set_base_ : public super_trait_< point_set_base_<Exact> >::ret
+    struct point_set_base_ :
+      public internal::point_set_selector_< stc_type(Exact, box)*, Exact >
     {
     protected:
       point_set_base_();
Index: oln/core/internal/encoded_image.hh
--- oln/core/internal/encoded_image.hh	(revision 1017)
+++ oln/core/internal/encoded_image.hh	(working copy)
@@ -50,12 +50,27 @@
   template <typename Exact>
   struct vtypes< internal::encoded_image_<Exact> >
   {
+# ifndef OLENA_USE_SCOOP_ALT
     typedef stc_deferred(point) point__;
     typedef internal::enc_image_psite_<point__> psite;
     typedef internal::enc_image_pset_<point__> pset;
+# endif
     typedef mlc::none plain;
   };
 
+# ifdef OLENA_USE_SCOOP_ALT
+  template <typename Exact>
+  struct single_vtype< internal::encoded_image_<Exact>, typedef_::psite >
+  {
+    typedef internal::enc_image_psite_< stc_type(Exact, point) > ret;
+  };
+
+  template <typename Exact>
+  struct single_vtype< internal::encoded_image_<Exact>, typedef_::pset >
+  {
+    typedef internal::enc_image_pset_< stc_type(Exact, point) > ret;
+  };
+# endif
 
   namespace internal
   {
Index: oln/core/internal/image_selectors.hh
--- oln/core/internal/image_selectors.hh	(revision 1017)
+++ oln/core/internal/image_selectors.hh	(working copy)
@@ -59,7 +59,7 @@
     };
 
 
-    // FIXME: don't work
+    // FIXME: doesn't work
     template <typename Exact>
     struct case_< Image_mutability, Exact,  2 >
       :
Index: oln/core/internal/image_base.hh
--- oln/core/internal/image_base.hh	(revision 1017)
+++ oln/core/internal/image_base.hh	(working copy)
@@ -159,11 +159,19 @@
     // Final.
 
     typedef stc::final< stc::is<Image> >         category;
+# ifndef OLENA_USE_SCOOP_ALT
     typedef stc::final< oln_box(pset__) >	 box;
     typedef stc::final< oln_grid(point__) >      grid;
     typedef stc::final< oln_dpoint(point__) >    dpoint;
     typedef stc::final< oln_fwd_piter(pset__) >  fwd_piter;
     typedef stc::final< oln_bkd_piter(pset__) >  bkd_piter;
+# else
+    typedef stc::final< stc_deferred_from(pset__,  box) >        box;
+    typedef stc::final< stc_deferred_from(point__, grid) >       grid;
+    typedef stc::final< stc_deferred_from(point__, dpoint) >     dpoint;
+    typedef stc::final< stc_deferred_from(pset__,  fwd_piter) >  fwd_piter;
+    typedef stc::final< stc_deferred_from(pset__,  bkd_piter) >  bkd_piter;
+# endif
     typedef fwd_piter                            piter;
   };
 
Index: oln/core/internal/point_base.hh
--- oln/core/internal/point_base.hh	(revision 1017)
+++ oln/core/internal/point_base.hh	(working copy)
@@ -44,7 +44,9 @@
   template <typename Exact>
   struct super_trait_< internal::point_base_<Exact> >
   {
-    typedef Point<Exact> ret;
+    // super_trait_ set to mlc::none, since Point is a concept
+    // (interface).
+    typedef mlc::none ret;
   };
 
   template <typename Exact>
@@ -57,7 +59,12 @@
     typedef stc_deferred(grid) grid__;
 
     // Final:
+    // FIXME: Improve scoop-alt to get rid of this difference.
+# ifndef OLENA_USE_SCOOP_ALT
     typedef stc::final< oln_dim(grid__) > dim;
+# else
+    typedef stc::final< stc_deferred_from(grid__, dim) > dim;
+# endif
     typedef stc::final< stc::is<Point>  > category;
   };
 
Index: oln/core/internal/piter_adaptor.hh
--- oln/core/internal/piter_adaptor.hh	(revision 1017)
+++ oln/core/internal/piter_adaptor.hh	(working copy)
@@ -54,7 +54,11 @@
     typedef stc::abstract adapted;
 
     typedef stc_deferred(adapted) adapted__;
+# ifndef OLENA_USE_SCOOP_ALT
     typedef stc::final< oln_point(adapted__) > point;
+# else
+    typedef stc::final< stc_deferred_from (adapted__, point) > point;
+# endif
   };
 
 
Index: oln/core/internal/encoded_image_pset.hh
--- oln/core/internal/encoded_image_pset.hh	(revision 1017)
+++ oln/core/internal/encoded_image_pset.hh	(working copy)
@@ -65,6 +65,7 @@
     typedef typename oln::internal::f_point_to_box_< P >::ret box;
     typedef internal::enc_image_pset_fwd_piter_<P> fwd_piter;
     typedef internal::enc_image_pset_bkd_piter_<P> bkd_piter;
+    typedef std::vector<std::pair<point, unsigned> > std_container;
   };
 
   namespace internal
@@ -81,7 +82,7 @@
       stc_using(point);
       stc_using(box);
 
-      typedef std::vector<std::pair<point, unsigned> > std_container;
+      typedef stc_type(current, std_container) std_container;
 
       enc_image_pset_();
 
@@ -216,6 +217,7 @@
     public:
       stc_using(point);
       typedef enc_image_psite_<point> psite;
+      typedef stc_type(enc_image_pset_<point>, std_container) std_container;
 
       const enc_image_psite_<point>& impl_to_psite() const;
       const enc_image_psite_<point>* impl_psite_adr() const;
@@ -225,7 +227,7 @@
     protected:
       enc_image_pset_piter_(const enc_image_pset_<point>& con);
 
-      const typename enc_image_pset_<point>::std_container& con_;
+      const std_container& con_;
 
       point p_;
       enc_image_psite_<point> ps_;
@@ -294,12 +296,14 @@
   {
     // class enc_image_pset__fwd_iterator_
     template <typename P>
-    class  enc_image_pset_fwd_piter_ : public enc_image_pset_piter_<enc_image_pset_fwd_piter_<P> >
+    class enc_image_pset_fwd_piter_ :
+      public enc_image_pset_piter_<enc_image_pset_fwd_piter_<P> >
     {
       typedef enc_image_pset_piter_< enc_image_pset_fwd_piter_<P> > super;
       typedef enc_image_pset_fwd_piter_<P> current;
     public:
       stc_using(point);
+      stc_using(std_container);
 
       enc_image_pset_fwd_piter_(const enc_image_pset_<P>& con);
 
@@ -309,7 +313,7 @@
       bool impl_is_valid() const;
 
     protected:
-      typename enc_image_pset_<point>::std_container::const_iterator it_;
+      typename std_container::const_iterator it_;
     };
 
 # ifndef OLN_INCLUDE_ONLY
@@ -395,12 +399,14 @@
   {
     // enc_image_pset_bkd_piter_
     template <typename P>
-    class enc_image_pset_bkd_piter_ : public enc_image_pset_piter_<enc_image_pset_bkd_piter_<P> >
+    class enc_image_pset_bkd_piter_ :
+      public enc_image_pset_piter_<enc_image_pset_bkd_piter_<P> >
     {
       typedef enc_image_pset_piter_< enc_image_pset_bkd_piter_<P> > super;
       typedef enc_image_pset_bkd_piter_<P> current;
     public:
       stc_using(point);
+      stc_using(std_container);
 
       enc_image_pset_bkd_piter_(const enc_image_pset_<P>& con);
 
@@ -410,7 +416,8 @@
       bool impl_is_valid() const;
 
     protected:
-      typename enc_image_pset_<point>::std_container::const_reverse_iterator it_;
+//       typename enc_image_pset_<point>::std_container::const_reverse_iterator it_;
+      typename std_container::const_reverse_iterator it_;
     };
 
 # ifndef OLN_INCLUDE_ONLY
Index: oln/core/internal/category_of.hh
--- oln/core/internal/category_of.hh	(revision 1017)
+++ oln/core/internal/category_of.hh	(working copy)
@@ -43,24 +43,53 @@
   namespace internal
   {
 
-    template <typename T1, typename T2>
-    struct get_category_of_
-      : private mlc::abort_< pair<T1,T2> > // FIXME: Add error msg.
+    // get_category_as_a_vtype_
+
+    namespace ERROR
+    {
+      struct ILL_DEFINED_CATEGORY_IN_TYPEDEF;
+      struct CATEGORY_NOT_FOUND_AS_A_TYPEDEF_NOR_AS_A_VTYPE;
+    }
+
+    // Default case: error.
+    template <typename T>
+    struct get_category_as_a_vtype_ :
+      private mlc::abort_
+       <T, ERROR::CATEGORY_NOT_FOUND_AS_A_TYPEDEF_NOR_AS_A_VTYPE>
     {
     };
 
+    // Default case: error.
     template <template <class> class C>
-    struct get_category_of_< C<void>, mlc::not_found >
+    struct get_category_as_a_vtype_< stc::is<C> >
     {
       typedef stc::is<C> ret;
     };
 
-    template <template <class> class C>
-    struct get_category_of_< mlc::not_found, stc::is<C> >
+
+    // get_category_as_a_typedef_
+
+    // Default case: error.
+    template <typename T, typename U>
+    struct get_category_as_a_typedef_
+      : private mlc::abort_<T, ERROR::ILL_DEFINED_CATEGORY_IN_TYPEDEF>
+    {
+    };
+
+    template <typename T, template <class> class C>
+    struct get_category_as_a_typedef_< T, C<void> >
     {
       typedef stc::is<C> ret;
     };
 
+    template <typename T>
+    struct get_category_as_a_typedef_< T, mlc::not_found >
+    {
+      typedef stc_find_type(T, category) cat_vtype;
+      // Try to get the category from the vtypes of T.
+      typedef typename get_category_as_a_vtype_<cat_vtype>::ret ret;
+    };
+
 
     // category_of_
 
@@ -68,9 +97,8 @@
     struct category_of_
     {
       typedef mlc_basic(T) T__;
-      typedef mlc_typedef(T__, category)   ret_1;
-      typedef stc_find_type(T__, category) ret_2;
-      typedef typename get_category_of_<ret_1, ret_2>::ret ret;
+      typedef mlc_typedef(T__, category) cat_typedef;
+      typedef typename get_category_as_a_typedef_<T__, cat_typedef>::ret ret;
     };
 
 
Index: oln/core/internal/neighborhood_base.hh
--- oln/core/internal/neighborhood_base.hh	(revision 1017)
+++ oln/core/internal/neighborhood_base.hh	(working copy)
@@ -55,7 +55,12 @@
     typedef stc::abstract point;
 
     typedef stc_deferred(point) point__;
+    // FIXME: Improve scoop-alt to get rid of this difference.
+# ifndef OLENA_USE_SCOOP_ALT
     typedef stc::final< oln_grid(point__) >     grid;
+# else
+    typedef stc::final< stc_deferred_from(point__, grid) > grid;
+# endif
     typedef stc::final< stc::is<Neighborhood> > category;
   };
 
Index: oln/core/internal/iterator_on_points_base.hh
--- oln/core/internal/iterator_on_points_base.hh	(revision 1017)
+++ oln/core/internal/iterator_on_points_base.hh	(working copy)
@@ -42,7 +42,9 @@
   template <typename Exact>
   struct super_trait_< internal::iterator_on_points_base_<Exact> >
   {
-    typedef Iterator_on_Points<Exact> ret;
+    // super_trait_ set to mlc::none, since Iterator_on_Points is a
+    // concept (interface).
+    typedef mlc::none ret;
   };
 
   // Virtual types
@@ -54,10 +56,18 @@
     typedef stc::abstract point;
 
     typedef stc_deferred(point) point__;
+    // FIXME: Improve scoop-alt to get rid of this difference.
+# ifndef OLENA_USE_SCOOP_ALT
     typedef stc::final< oln_grid(point__) >   grid;
     typedef stc::final< oln_coord(point__) >  coord;
     typedef stc::final< oln_dim(point__) >    dim;
     typedef stc::final< oln_dpoint(point__) > dpoint;
+# else
+    typedef stc::final< stc_deferred_from(point__, grid  ) > grid;
+    typedef stc::final< stc_deferred_from(point__, coord ) > coord;
+    typedef stc::final< stc_deferred_from(point__, dim   ) > dim;
+    typedef stc::final< stc_deferred_from(point__, dpoint) > dpoint;
+# endif
   };
 
 
@@ -67,7 +77,13 @@
     template <typename Exact>
     class iterator_on_points_base_
       : public Iterator_on_Points<Exact>,
- 	public internal::iterator_on_points_impl_<mlc_value(stc_deferred(dim)), Exact>
+# ifndef OLENA_USE_SCOOP_ALT
+  	public internal::iterator_on_points_impl_<mlc_value(stc_deferred(dim)),
+						  Exact>
+# else
+  	public internal::iterator_on_points_impl_<mlc_value(stc_type(Exact, dim)),
+						  Exact>
+# endif
     {
     public:
       // Disambiguate.
Index: oln/Makefile.am
--- oln/Makefile.am	(revision 1017)
+++ oln/Makefile.am	(working copy)
@@ -26,20 +26,14 @@
 									\
   core/gen/bkd_viter_lut.hh						\
   core/gen/fwd_viter_lut.hh						\
-  core/gen/piter_isubset.hh						\
-  core/gen/piter_isubset.hh						\
   core/gen/mapimage.hh							\
   core/gen/neighb.hh							\
   core/gen/pw_value.hh							\
   core/gen/window.hh							\
 									\
-  core/internal/dpoint_nd.hh						\
   core/internal/tracked_ptr.hh						\
 									\
-  core/case.hh								\
   core/lookup_table.hh							\
-  core/traits.hh							\
-  core/traits_id.hh							\
 									\
   debug/print.hh							\
   debug/track.hh							\
@@ -52,22 +46,11 @@
   level/clone.hh							\
   level/fill.hh								\
 									\
-  morpher/internal/image_extension.hh					\
-  morpher/internal/image_value_morpher.hh				\
-									\
-  morpher/add_neighborhood.hh						\
-  morpher/count_rw.hh							\
   morpher/fwd_decls.hh							\
-  morpher/identity.hh							\
-  morpher/tags.hh							\
   morpher/slice.hh							\
-  morpher/stack.hh							\
-  morpher/stack_rw.hh							\
-  morpher/thru_fun.hh							\
   morpher/thru_mfun.hh							\
   morpher/two_way.hh							\
   morpher/two_way_rw.hh							\
-  morpher/value_cast.hh							\
   morpher/with_lut.hh							\
 									\
   value/color/rgb.hh							\
@@ -76,14 +59,11 @@
   value/all.hh								\
   value/bin.hh								\
   value/default.hh							\
-  value/greylevel.hh							\
+  value/graylevel.hh							\
+  value/gray_level.hh							\
   value/lut_value_proxy.hh						\
   value/proxy.hh							\
   value/rw_counter.hh							\
   value/tags.hh								\
   value/two_way.hh							\
-  value/two_way.hxx							\
-									\
-  basics1d.hh								\
-  basics2d.hh								\
-  basics3d.hh
+  value/two_way.hxx
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                        https://svn.lrde.epita.fr/svn/oln/trunk/static
Index: ChangeLog
from  Roland Levillain  <roland(a)lrde.epita.fr>
	Add a deferred vtype lookup mechanism to scoop-alt.
	* stc/scoop-alt.hh (deferred): New declaration.
	(stc_find_type_in_, stc_find_type_in)
	(stc_is_found_type, stc_is_not_found_type): New macros.
	(stc_is_a): Rely on stc_find_type, not stc_deferred.
	(stc_using_): New macro.
	(stc_deferred): Rely on stc::deferred<>, not deferred_vtype<>.
	(stc_deferred_from): New macro.
	* stc/scoop-alt.inc (find_vtype): New forward declaration.
	(direct_): New unwrapping mechanism.
	(find_vtype): Use it.
	* tests/scoop-alt.cc (ex9): Add a Point concept (interface).
	Fix this test case.
 stc/scoop-alt.hh   |   47 +++++++++++++++++++++++++++----
 stc/scoop-alt.inc  |   44 +++++++++++++++++++++++++++--
 tests/scoop-alt.cc |   80 ++++++++++++++++++++++++++++++++++++++++++-----------
 3 files changed, 148 insertions(+), 23 deletions(-)
Index: tests/scoop-alt.cc
--- tests/scoop-alt.cc	(revision 1016)
+++ tests/scoop-alt.cc	(working copy)
@@ -734,6 +734,28 @@
   // FIXME: I (Roland) don't know why this test succeeds, while the
   // equivalent SCOOP 2 hierarchy doesn't work in Olena.
 
+
+  /*--------.
+  | Point.  |
+  `--------*/
+
+  // Forward declaration.
+  namespace ex9
+  {
+    template <typename Exact>
+    struct Point
+    {
+      stc_typename(grid);
+      stc_typename(dim);
+
+      enum { n = mlc_value(dim) };
+
+    }; // end of oln::Point<Exact>
+
+  }
+
+
+
   /*------------------------.
   | internal::point_base_.  |
   `------------------------*/
@@ -751,6 +773,8 @@
   template <typename Exact>
   struct super_trait_< ex9::internal::point_base_<Exact> >
   {
+    // super_trait_ set to stc::none, since Point is a concept
+    // (interface).
     typedef stc::none ret;
   };
 
@@ -761,8 +785,8 @@
     typedef stc::abstract grid;
 
     typedef stc_deferred(grid) grid__;
-    typedef stc::final<stc_type(grid__, dim)> dim;
-
+    typedef stc_deferred_from(grid__, dim) dim__;
+    typedef stc::final< dim__ > dim;
   };
 
   // Actual definition.
@@ -773,7 +797,9 @@
       template <typename Exact>
       struct point_base_ : public stc::none
       {
-	stc_typename(dim);
+	typedef Point<Exact> super;
+
+	stc_using(dim);
 	static const unsigned dim_val = mlc_value(dim);
       };
     } // end of namespace my::ex9::internal
@@ -784,19 +810,41 @@
   | internal::point2d_.  |
   `---------------------*/
 
-  // FIXME: Add internal::point2d_, as in Olena, and check whether
-  // this addition triggers the same behavior observed in Olena.
+  namespace ex9
+  {
+    // Forward declarations.
+    namespace internal
+    {
+      template <typename Exact> struct point2d_;
+    }
+  }
+
+  /// Super type.
+  template<typename Exact>
+  struct super_trait_< ex9::internal::point2d_<Exact> >
+  {
+    typedef ex9::internal::point_base_<Exact> ret;
+  };
 
-//   namespace ex9
-//   {
-//     // Forward declarations.
-//     namespace internal
-//     {
-//       template <typename Exact> struct point2d_;
-//     }
-//   }
+  /// Virtual types associated to internal::point2d_<Exact>.
+  template <typename Exact>
+  struct vtypes< ex9::internal::point2d_<Exact> >
+  {
+  };
 
-  // ...
+  namespace ex9
+  {
+    // Actual definition.
+    namespace internal
+    {
+
+      template <typename Exact>
+      struct point2d_ : public point_base_<Exact>
+      {
+	typedef point_base_<Exact> super;
+      };
+    }
+  }
 
 
   /*---------.
@@ -846,7 +894,7 @@
   template <>
   struct super_trait_< ex9::point2d >
   {
-    typedef ex9::internal::point_base_<ex9::point2d> ret;
+    typedef ex9::internal::point2d_<ex9::point2d> ret;
   };
 
 
@@ -860,7 +908,7 @@
   // Actual definition.
   namespace ex9
   {
-    struct point2d : public internal::point_base_< point2d >
+    struct point2d : public internal::point2d_< point2d >
     {
     };
   }
Index: stc/scoop-alt.hh
--- stc/scoop-alt.hh	(revision 1016)
+++ stc/scoop-alt.hh	(working copy)
@@ -64,11 +64,16 @@
   struct not_found;
 #endif
   typedef mlc::not_found not_found;
+  // FIXME: Document all these tags!
   struct abstract;
   struct not_delegated;
   struct not_delegated_abstract;
   template <typename T> struct final;
 
+  // Deferred vtype lookup.
+  // FIXME: Document.
+  template <typename Source, typename Target> struct deferred;
+
   template < template <class> class category >
   struct is;
 
@@ -131,6 +136,8 @@
 
 // FIXME: Document all these macros.
 
+// FIXME: Consistency: stc_type vs vtype<>. 
+
 /// Access to associated type.
 /// \{
 # define stc_type_(Source, Target) vtype<Source, typedef_::Target>::ret
@@ -150,46 +157,76 @@
 /// \}
 
 
+// FIXME: Consistency: stc_find_type vs find_vtype<>. 
+
 /// Likewise, but more tolerant.
 /// \{
 # define stc_find_type_(Source, Target)	\
    find_vtype<Source, typedef_::Target>::ret
 # define stc_find_type(Source, Target)		\
    typename stc_find_type_(Source, Target)
+
+# define stc_find_type_in_(Namespace, Source, Target)			\
+   Namespace::find_vtype<Source, Namespace::typedef_::Target>::ret
+# define stc_find_type_in(Namespace, Source, Target)	\
+   typename stc_find_type_in_(Namespace, Source, Target)
+
+
 /// \}
 
 /// Boolean expression counterpart of stc_find_type
 /// \{
 # define stc_type_is_found(Target)		\
-   stc::is_found< stc_deferred(Target) >
+   stc::is_found< stc_find_type(Exact, Target) >
 # define stc_type_is_not_found(Target)		\
-   stc::is_not_found< stc_deferred(Target) >
+   stc::is_not_found< stc_find_type(Exact, Target) >
+
+# define stc_is_found_type(From, Type)			\
+   stc::is_found< stc_deferred_type(From, Type) >
+# define stc_is_not_found_type(From, Type)		\
+   stc::is_not_found< stc_deferred_type(From, Type) >
 /// \}
 
 
+// FIXME: Using stc_deferred here (in scoop-alt) is probably nonsense.
+// We probably ought to introduce another macro for stc_deferred /
+// stc_deferred_from (and try to stick as much as possible to its
+// initial meaning); something like stc_deferred_def /
+// stc_deferred_def_from.
+# if 0
 # define stc_is_a(T, U)							 \
    mlc::wrap_<								 \
      typename mlc::is_a_< sizeof(mlc::form::of< U >()) >		 \
        ::template ret< typename mlc::basic_< stc_deferred(T) >::ret, U > \
      >
+#endif
+
+# define stc_is_a(T, U)							\
+   mlc::wrap_<								\
+     typename mlc::is_a_< sizeof(mlc::form::of< U >()) >		\
+       ::template ret< typename mlc::basic_< stc_find_type(Exact, T) >::ret, U > \
+     >
+
 
 
 /// For concepts.
 /// \{
 # define stc_typename(Target) typedef stc_type(Exact, Target) Target
 # define stc_using(Target)    typedef typename super::Target Target
+# define stc_using_(Target)   typedef super::Target Target
 # define stc_using_from(Abstraction, Target)		\
    typedef typename Abstraction<Exact>::Target Target
+// FIXME: Might be renamed as stc_typename_from for consistency purpose.
 # define stc_deduce_typename(Src, Target) typedef stc_type(Src, Target) Target
 /// \}
 
 
 /// For implementation classes.
 /// \{
-/// Dummy
 # define stc_deferred(Target)			\
-   stc_find_type(Exact, Target)
-//   typename deferred_vtype<Exact, typedef_::Target >::ret
+   stc::deferred<Exact, typedef_::Target>
+# define stc_deferred_from(Source, Target)	\
+   stc::deferred<Source, typedef_::Target>
 # define stc_lookup(Target)					\
    typedef typename vtype< stc_type(current, exact_type),	\
                            typedef_::Target>::ret Target
Index: stc/scoop-alt.inc
--- stc/scoop-alt.inc	(revision 1016)
+++ stc/scoop-alt.inc	(working copy)
@@ -614,6 +614,10 @@
 
 /* ----------------------------------------------------------- find.  */
 
+/* Forward declaration.  */
+template <typename source, typename target> struct find_vtype;
+
+/* Unwrap the result.  */
 namespace find_
 {
   /* Forward declaration.  */
@@ -660,14 +664,49 @@
 
 } /* End of namespace find_.  */
 
+/* Evaluate the result, removing any deferred tag.  */
+namespace direct_
+{
+  /* Forward declaration.  */
+  template <typename T> struct match_with;
+
+  /* One-layer deferred type..  */
+  template <typename Source, typename Target>
+  struct match_with< stc::deferred<Source, Target> >
+  {
+    /* Get direct definitions of Source and Target.  */
+    typedef typename direct_::match_with<Source>::ret direct_source;
+    typedef typename direct_::match_with<Target>::ret direct_target;
+
+    /* Resolve the virtual type.  */
+    typedef typename find_vtype<direct_source, direct_target>::ret res;
+
+    /* Re-lauch the direct process, in case the previous result was
+       itself a postponed virtual type definition.  */
+    typedef typename direct_::match_with<res>::ret ret;
+  };
+
+
+  /* Default version.  */
+  template <typename T>
+  struct match_with
+  {
+    typedef T ret;
+  };
+} /* End of namespace direct_.  */
+
 
 /** Find a virtual type.  */
 template <typename source, typename target>
 struct find_vtype
 {
   typedef typename find_rec<source, target>::ret res;
-  /* Result.  */
-  typedef typename find_::match_with<res>::ret ret;
+
+  /* Unwrap the result.  */
+  typedef typename find_::match_with<res>::ret unwrapped;
+
+  /* Remove potential deferred tag, and return result.  */
+  typedef typename direct_::match_with<unwrapped>::ret ret;
 };
 
 
@@ -684,6 +723,7 @@
 };
 
 
+
 /*------------.
 | Selectors.  |
 `------------*/
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                        https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from  Thierry Geraud  <thierry.geraud(a)lrde.epita.fr>
	Add delta to windows in mln.
	* tests/erosion.cc: New.
	* mln/arith/minus.hh: New.
	* mln/core/point.hh,
	* mln/core/dpoint.hh (vec_t, to_vec): New.
	* mln/core/rectangle2d.hh,
	* mln/core/concept/window.hh,
	* mln/core/concept/doc/window.hh,
	* mln/core/window.hh (delta): New.
	* mln/level/fill.hh: New overload.
	* mln/norm: New.
	* mln/norm/infty.hh: New.
	* mln/accu/min.hh: New.
	* mln/accu/sum.hh: New.
	* mln/accu/max.hh: New.
	* tests/window2d.cc: Use delta.
	* tests/box2d.cc: Add assertion.
	* tests/dpoint2d.cc: Test to_vec.
	* mln/morpho/erosion.hh: Add dispatch.
	* mln/accu/mean.hh: Rewrite.
 mln/accu/max.hh                |  112 +++++++++++++++++++++++++++++++++++++++++
 mln/accu/mean.hh               |   17 +++---
 mln/accu/min.hh                |  112 +++++++++++++++++++++++++++++++++++++++++
 mln/accu/sum.hh                |  112 +++++++++++++++++++++++++++++++++++++++++
 mln/arith/minus.hh             |   82 ++++++++++++++++++++++++++++++
 mln/core/concept/doc/window.hh |    5 +
 mln/core/concept/window.hh     |    6 +-
 mln/core/dpoint.hh             |    8 ++
 mln/core/point.hh              |    7 ++
 mln/core/rectangle2d.hh        |   10 +++
 mln/core/window.hh             |   24 ++++++++
 mln/level/fill.hh              |   24 ++++++++
 mln/morpho/erosion.hh          |   99 ++++++++++++++++++++++++++++++------
 mln/norm/infty.hh              |   86 +++++++++++++++++++++++++++++++
 tests/box2d.cc                 |    1 
 tests/dpoint2d.cc              |    3 +
 tests/erosion.cc               |   78 ++++++++++++++++++++++++++++
 tests/window2d.cc              |    1 
 18 files changed, 761 insertions(+), 26 deletions(-)
Index: tests/window2d.cc
--- tests/window2d.cc	(revision 1015)
+++ tests/window2d.cc	(working copy)
@@ -49,4 +49,5 @@
   w.insert(make::dpoint2d( 1, 1));
   image2d_b<bool> ima = convert::to_image(w);
   debug::println(ima);
+  mln_assertion(w.delta() = 1);
 }
Index: tests/erosion.cc
--- tests/erosion.cc	(revision 0)
+++ tests/erosion.cc	(revision 0)
@@ -0,0 +1,78 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction.  Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License.  This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+/*! \file tests/median.cc
+ *
+ * \brief Test on mln::level::median.
+ */
+
+#include <mln/core/image2d_b.hh>
+#include <mln/core/rectangle2d.hh>
+
+#include <mln/io/load_pgm.hh>
+#include <mln/io/save_pgm.hh>
+
+#include <mln/value/int_u.hh>
+#include <mln/level/fill.hh>
+#include <mln/morpho/erosion.hh>
+
+#include <mln/fun/pw_value.hh>
+#include <mln/fun/val.hh>
+#include <mln/fun/ops.hh>
+
+
+using namespace mln;
+using namespace mln::value;
+
+
+int main()
+{
+  rectangle2d rec(4, 4);//64, 64);
+  border::thickness = 66;
+
+  image2d_b<int_u8>
+    lena = io::load_pgm("../img/lena.pgm"),
+    out(lena.domain());
+
+  morpho::erosion(lena, rec, out);
+  io::save_pgm(out, "out.pgm");
+
+  /*
+  {
+    image2d_b<bool> bin(lena.domain()), out(lena.domain());
+    level::fill(bin, pw_value(1) > val(127));
+    morpho::erosion(bin, rec, out);
+
+    image2d_b<int_u8> test(lena.domain());
+    image2d_b<int_u8>::piter p(lena.domain());
+    for_all(p)
+      test(p) = out(p) ? 255 : 0;
+    io::save_pgm(test, "test.pgm");
+  }
+  */
+
+}
Index: tests/box2d.cc
--- tests/box2d.cc	(revision 1015)
+++ tests/box2d.cc	(working copy)
@@ -39,4 +39,5 @@
   using namespace mln;
 
   box2d b = make::box2d(2, 3);
+  mln_assertion(b.nrows() = 2);
 }
Index: tests/dpoint2d.cc
--- tests/dpoint2d.cc	(revision 1015)
+++ tests/dpoint2d.cc	(working copy)
@@ -47,4 +47,7 @@
 
   mln_assertion(dp = q - p);
   mln_assertion(q = p + dp);
+
+  const int (&vec)[2] = dp.to_vec();
+  mln_assertion(vec[0] = 3);
 }
Index: mln/core/point.hh
--- mln/core/point.hh	(revision 1015)
+++ mln/core/point.hh	(working copy)
@@ -96,6 +96,13 @@
     /// Origin point (all coordinates are 0).
     static const point_<n,C> zero;
 
+
+    /// Type of the array of coordinates.
+    typedef const C (&vec_t)[n];
+
+    /// Hook to coordinates.
+    vec_t to_vec() const { return coord_; }
+
   protected:
     C coord_[n];
   };
Index: mln/core/rectangle2d.hh
--- mln/core/rectangle2d.hh	(revision 1015)
+++ mln/core/rectangle2d.hh	(working copy)
@@ -107,6 +107,11 @@
      */
     unsigned width() const;
 
+    /*! \brief Give the maximum coordinate gap between the window
+     * center and a window point.
+     */
+    unsigned delta() const;
+
     /// Get the symmetrical window.
     rectangle2d sym_() const;
 
@@ -162,6 +167,11 @@
     return 2 * half_width_ + 1;
   }
 
+  unsigned rectangle2d::delta() const
+  {
+    return half_width_ > half_height_ ? half_width_ : half_height_;
+  }
+
   rectangle2d rectangle2d::sym_() const
   {
     return *this;
Index: mln/core/dpoint.hh
--- mln/core/dpoint.hh	(revision 1015)
+++ mln/core/dpoint.hh	(working copy)
@@ -96,6 +96,14 @@
     /// Null delta-point (all coordinates are 0).
     static const dpoint_<n,C> zero;
 
+    const C* coords_() const { return coord_; }
+
+    /// Type of the array of coordinates.
+    typedef const C (&vec_t)[n];
+
+    /// Hook to coordinates.
+    vec_t to_vec() const { return coord_; }
+
   protected:
     C coord_[n];
   };
Index: mln/core/concept/window.hh
--- mln/core/concept/window.hh	(revision 1015)
+++ mln/core/concept/window.hh	(working copy)
@@ -59,6 +59,8 @@
       bool is_centered() const;
       bool is_symmetric() const;
 
+      unsigned delta() const;
+
       E sym_() const;
     */
 
@@ -93,8 +95,10 @@
     m2 = 0;
     bool (E::*m3)() const = & E::is_symmetric;
     m3 = 0;
-    E (E::*m4)() const = & E::sym_;
+    unsigned (E::*m4)() const = & E::delta;
     m4 = 0;
+    E (E::*m_)() const = & E::sym_;
+    m_ = 0;
   }
 
   template <typename W>
Index: mln/core/concept/doc/window.hh
--- mln/core/concept/doc/window.hh	(revision 1015)
+++ mln/core/concept/doc/window.hh	(working copy)
@@ -76,6 +76,11 @@
        */
       bool is_symmetric() const;
 
+      /*! \brief Give the maximum coordinate gap between the window
+	center and a window point.
+       */
+      unsigned delta() const;
+
       /*! \brief Give the symmetrical window.
        */
       E sym_() const;
Index: mln/core/window.hh
--- mln/core/window.hh	(revision 1015)
+++ mln/core/window.hh	(working copy)
@@ -41,6 +41,7 @@
 
 # include <mln/convert/to_dpoint.hh>
 # include <mln/fun/all.hh>
+# include <mln/norm/infty.hh>
 
 
 namespace mln
@@ -97,6 +98,11 @@
      */
     bool is_symmetric() const;
 
+    /*! \brief Give the maximum coordinate gap between the window
+      center and a window point.
+    */
+    unsigned delta() const;
+
     /// Give the symmetrical window.
     window_<D> sym_() const;
 
@@ -128,6 +134,8 @@
 
 # ifndef MLN_INCLUDE_ONLY
 
+  // window_<D>
+
   template <typename D>
   window_<D>::window_()
   {
@@ -147,6 +155,20 @@
   }
 
   template <typename D>
+  unsigned window_<D>::delta() const
+  {
+    unsigned d = 0;
+    const unsigned n = this->nelements();
+    for (unsigned i = 0; i < n; ++i)
+      {
+	unsigned dd = norm::infty(this->element(i).to_vec());
+	if (dd > d)
+	  d = dd;
+      }
+    return d;
+  }
+
+  template <typename D>
   window_<D>
   window_<D>::sym_() const
   {
@@ -157,6 +179,8 @@
     return tmp;
   }
 
+  // operators
+
   template <typename W>
   window_<mln_dpoint(W)> operator+(const Window<W>& win,
 				   const mln_dpoint(W)& dp)
Index: mln/morpho/erosion.hh
--- mln/morpho/erosion.hh	(revision 1015)
+++ mln/morpho/erosion.hh	(working copy)
@@ -30,8 +30,11 @@
 
 # include <mln/core/concept/image.hh>
 # include <mln/core/concept/window.hh>
-// FIXME: # include <mln/border/assign.hh>
+# include <mln/accu/min.hh>
 # include <mln/value/props.hh>
+# include <mln/level/compare.hh>
+# include <mln/level/fill.hh>
+// FIXME: # include <mln/border/assign.hh>
 
 
 namespace mln
@@ -40,8 +43,8 @@
   namespace morpho
   {
 
-    template <typename I, typename W>
-    I erosion(const Image<I>& input, const Window<W>& win);
+    template <typename I, typename W, typename O>
+    void erosion(const Image<I>& input, const Window<W>& win, Image<O>& output);
 
 
 # ifndef MLN_INCLUDE_ONLY
@@ -49,41 +52,103 @@
     namespace impl
     {
 
-      template <typename I, typename W>
-      I erosion(const Image<I>& input_, const Window<W>& win_)
+      // on function
+
+      template <typename I, typename W, typename O>
+      void erosion_on_function(const Image<I>& input_, const Window<W>& win_, Image<O>& output_)
       {
 	const I& input = exact(input_);
 	const W& win   = exact(win_);
+	O& output      = exact(output_);
 
-	typedef mln_value(I) value;
+	accu::min<mln_value(I)> min;
 
-	I output(input.domain());
 	mln_piter(I) p(input.domain());
 	mln_qiter(W) q(win, p);
 	for_all(p)
 	  {
-	    value v = mln_max(value);
-	    for_all(q) if (input.owns_(q))
-	      {
-		if (input(q) < v)
-		  v = input(q);
+	    min.init();
+	    for_all(q) if (input.has(q))
+	      min.take(input(q));
+	    output(p) = min;
+	  }
 	      }
-	    output(p) = v;
+
+
+      // on set
+
+      template <typename I, typename W, typename O>
+      void erosion_on_set(const Image<I>& input_, const Window<W>& win_, Image<O>& output_)
+      {
+	const I& input = exact(input_);
+	const W& win   = exact(win_);
+	O& output      = exact(output_);
+
+	level::fill(output, input);
+
+	mln_piter(I) p(input.domain());
+	mln_qiter(W) q(win, p);
+	for_all(p)
+	  if (input(p))
+	    for_all(q) if (input.has(q))
+	      if (! input(q))
+		{
+		  output(p) = false;
+		  break;
 	  }
-	return output;
       }
 
+
+
       // ...
 
+
+
+      // FIXME: stage 3: dispatch w.r.t. fast property
+
+      // stage 2: dispatch w.r.t. the value kind
+
+      template <typename I, typename W, typename O>
+      void erosion_wrt_value(value::binary_kind, // binary => morphology on sets
+			     const Image<I>& input, const Window<W>& win, Image<O>& output)
+      {
+	return impl::erosion_on_set(exact(input), exact(win), output);
+      }
+
+      template <typename K, typename I, typename W, typename O>
+      void erosion_wrt_value(K, // otherwise => morphology on functions
+			     const Image<I>& input, const Window<W>& win, Image<O>& output)
+      {
+	return impl::erosion_on_function(exact(input), exact(win), output);
+      }
+
+
+      // stage 1: dispatch w.r.t. the window type
+
+      template <typename I, typename W, typename O> // general case
+      void erosion_wrt_win(const Image<I>& input, const Window<W>& win, Image<O>& output)
+      {
+	erosion_wrt_value(mln_kind(I)(), exact(input), exact(win), output);
+      }
+
+//       template <typename I, typename O> // rectangle2d
+//       void erosion_wrt_win(const Image<I>& input, const rectangle2d& win, Image<O>& output)
+//       {
+// 	return FIXME;
+//       }
+      
+
     } // end of namespace mln::morpho::impl
 
 
     // facade
 
-    template <typename I, typename W>
-    I erosion(const Image<I>& input, const Window<W>& win)
+    template <typename I, typename W, typename O>
+    void erosion(const Image<I>& input, const Window<W>& win, Image<O>& output)
     {
-      return impl::erosion(exact(input), exact(win)); 
+      impl::erosion_wrt_win(input, exact(win), output);
+      if (exact(win).is_centered())
+	mln_postcondition(output <= input);
     }
 
 # endif // ! MLN_INCLUDE_ONLY
Index: mln/level/fill.hh
--- mln/level/fill.hh	(revision 1015)
+++ mln/level/fill.hh	(working copy)
@@ -34,6 +34,7 @@
  */
 
 # include <mln/core/concept/image.hh>
+# include <mln/core/concept/function.hh>
 
 
 namespace mln
@@ -53,6 +54,17 @@
     void fill(Image<I>& ima, const mln_value(I)& v);
 
 
+    /*! Fill the whole image \p ima with the function \p f.
+     *
+     * \param[in,out] ima The image to be filled.
+     * \param[in] f The function.
+     *
+     * \pre \p ima has to be initialized.
+     */
+    template <typename I, typename F>
+    void fill(Image<I>& ima, const Function_p2v<F>& f);
+
+
     /*! Fill the image \p ima by applying the function \p f.
      *
      * \param[in,out] ima The image to be filled.
@@ -110,6 +122,18 @@
 	ima(p) = value;
     }
 
+    template <typename I, typename F>
+    void fill(Image<I>& ima_,
+	      const Function_p2v<F>& f_)
+    {
+      I& ima = exact(ima_);
+      mln_precondition(ima.has_data());
+      const F& f = exact(f_);
+      mln_piter(I) p(ima.domain());
+      for_all(p)
+	ima(p) = f(p);
+    }
+
     template <typename I>
     void fill(Image<I>& ima_,
 	      mln_value(I) (*f)(const mln_point(I)& p))
Index: mln/arith/minus.hh
--- mln/arith/minus.hh	(revision 0)
+++ mln/arith/minus.hh	(revision 0)
@@ -0,0 +1,82 @@
+// 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_ARITH_MINUS_HH
+# define MLN_ARITH_MINUS_HH
+
+/*! \file mln/arith/minus.hh
+ *
+ * \brief Point-wise substraction between images.
+ */
+
+# include <mln/core/concept/image.hh>
+
+
+namespace mln
+{
+
+  namespace arith
+  {
+
+    /*! Point-wise substraction of images \p lhs and \p rhs.
+     *
+     * \param[in] lhs First operand image.
+     * \param[in] rhs Second operand image.
+     * \param[out] output The result image.
+     *
+     * \pre \p output.domain = \p lhs.domain = \p rhs.domain
+     */
+    template <typename L, typename R, typename O>
+    void minus(const Image<L>& lhs, const Image<R>& rhs, Image<O>& output);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+    template <typename L, typename R, typename O>
+    void minus(const Image<L>& lhs_, const Image<R>& rhs_, Image<O>& output_)
+    {
+      const L& lhs = exact(lhs_);
+      const R& rhs = exact(rhs_);
+      O& output = exact(output_);
+
+      mln_precondition(rhs.domain() = lhs.domain());
+      mln_precondition(output.domain() = lhs.domain());
+
+      mln_piter(I) p(output.domain());
+      for_all(p)
+	output(p) = lhs(p) - rhs(p);
+    }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace mln::arith
+
+} // end of namespace mln
+
+
+#endif // ! MLN_ARITH_MINUS_HH
Index: mln/norm/infty.hh
--- mln/norm/infty.hh	(revision 0)
+++ mln/norm/infty.hh	(revision 0)
@@ -0,0 +1,86 @@
+// 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_NORM_INFTY_HH
+# define MLN_NORM_INFTY_HH
+
+/*! \file mln/norm/infty.hh
+ *
+ * \brief Define some infinity-norm related routines.
+ */
+
+# include <cmath>
+
+
+namespace mln
+{
+
+  namespace norm
+  {
+
+    /// Infinity-norm of a vector \p vec.
+    template <unsigned n, typename C>
+    C infty(const C (&vec)[n]);
+
+    /// Infinity-norm distance between vectors \p v1 and \p v2.
+    template <unsigned n, typename C>
+    C infty_distance(const C (&v1)[n], const C (&v2)[n]);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+    template <unsigned n, typename C>
+    C infty(const C (&vec)[n])
+    {
+      C c = 0;
+      for (unsigned i = 0; i < n; ++i)
+	if (std::abs(vec[i]) > c)
+	  c = std::abs(vec[i]);
+      return c;
+    }
+
+    template <unsigned n, typename C>
+    C infty_distance(const C (&v1)[n], const C (&v2)[n])
+    {
+      C d = 0;
+      for (unsigned i = 0; i < n; ++i)
+	{
+	  C dd = v2[i] > v1[i] ? v2[i] - v1[i] : v1[i] - v2[i];
+	  if (dd > d)
+	    d = dd;
+	}
+      return d;
+    }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace mln::norm
+
+} // end of namespace mln
+
+
+#endif // ! MLN_NORM_INFTY_HH
Index: mln/accu/min.hh
--- mln/accu/min.hh	(revision 0)
+++ mln/accu/min.hh	(revision 0)
@@ -0,0 +1,112 @@
+// 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_ACCU_MIN_HH
+# define MLN_ACCU_MIN_HH
+
+/*! \file mln/accu/min.hh
+ *
+ * \brief Define an accumulator that computes a min.
+ */
+
+# include <mln/core/concept/accumulator.hh>
+# include <mln/value/props.hh>
+
+
+namespace mln
+{
+
+  namespace accu
+  {
+
+
+    /*! Generic min accumulator class.
+     *
+     * The parameter \c V is the type of values.
+     */
+    template <typename V>
+    struct min : public Accumulator< min<V> >
+    {
+      typedef V value;
+
+      min();
+      void take(const value& v);
+      void init();
+
+      operator V() const;
+      V to_value() const;
+      
+    protected:
+
+      V v_;
+    };
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+    template <typename V>
+    min<V>::min()
+    {
+      init();
+    }
+
+    template <typename V>
+    void min<V>::take(const value& v)
+    {
+      if (v < v_)
+	v_ = v;
+    }
+
+    template <typename V>
+    void
+    min<V>::init()
+    {
+      v_ = mln_max(V);
+    }
+
+    template <typename V>
+    min<V>::operator V() const
+    {
+      return v_;
+    }
+
+    template <typename V>
+    V
+    min<V>::to_value() const
+    {
+      return v_;
+    }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace mln::accu
+
+} // end of namespace mln
+
+
+#endif // ! MLN_ACCU_MIN_HH
Index: mln/accu/sum.hh
--- mln/accu/sum.hh	(revision 0)
+++ mln/accu/sum.hh	(revision 0)
@@ -0,0 +1,112 @@
+// 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_ACCU_SUM_HH
+# define MLN_ACCU_SUM_HH
+
+/*! \file mln/accu/sum.hh
+ *
+ * \brief Define an accumulator that computes a sum.
+ */
+
+# include <mln/core/concept/accumulator.hh>
+
+
+namespace mln
+{
+
+  namespace accu
+  {
+
+
+    /*! Generic sum accumulator class.
+     *
+     * Parameter \c V is the type of values that we sum.  Parameter \c
+     * S is the type to store the sum value; the default type of
+     * \c S is \c V.
+     */
+    template <typename V, typename S = V>
+    struct sum : public Accumulator< sum<V,S> >
+    {
+      typedef V value;
+
+      sum();
+      void take(const value& v);
+      void init();
+
+      operator S() const;
+      S to_value() const;
+      
+    protected:
+
+      S sum_;
+    };
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+    template <typename V, typename S>
+    sum<V,S>::sum()
+    {
+      init();
+    }
+
+    template <typename V, typename S>
+    void sum<V,S>::take(const value& v)
+    {
+      sum_ += v;
+    }
+
+    template <typename V, typename S>
+    void
+    sum<V,S>::init()
+    {
+      sum_ = 0;
+    }
+
+    template <typename V, typename S>
+    sum<V,S>::operator S() const
+    {
+      return to_value;
+    }
+
+    template <typename V, typename S>
+    S
+    sum<V,S>::to_value() const
+    {
+      return sum_ / count_;
+    }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace mln::accu
+
+} // end of namespace mln
+
+
+#endif // ! MLN_ACCU_SUM_HH
Index: mln/accu/max.hh
--- mln/accu/max.hh	(revision 0)
+++ mln/accu/max.hh	(revision 0)
@@ -0,0 +1,112 @@
+// 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_ACCU_MAX_HH
+# define MLN_ACCU_MAX_HH
+
+/*! \file mln/accu/max.hh
+ *
+ * \brief Define an accumulator that computes a max.
+ */
+
+# include <mln/core/concept/accumulator.hh>
+# include <mln/value/props.hh>
+
+
+namespace mln
+{
+
+  namespace accu
+  {
+
+
+    /*! Generic max accumulator class.
+     *
+     * The parameter \c V is the type of values.
+     */
+    template <typename V>
+    struct max : public Accumulator< max<V> >
+    {
+      typedef V value;
+
+      max();
+      void take(const value& v);
+      void init();
+
+      operator V() const;
+      V to_value() const;
+      
+    protected:
+
+      V v_;
+    };
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+    template <typename V>
+    max<V>::max()
+    {
+      init();
+    }
+
+    template <typename V>
+    void max<V>::take(const value& v)
+    {
+      if (v > v_)
+	v_ = v;
+    }
+
+    template <typename V>
+    void
+    max<V>::init()
+    {
+      v_ = mln_min(V);
+    }
+
+    template <typename V>
+    max<V>::operator V() const
+    {
+      return v_;
+    }
+
+    template <typename V>
+    V
+    max<V>::to_value() const
+    {
+      return v_;
+    }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace mln::accu
+
+} // end of namespace mln
+
+
+#endif // ! MLN_ACCU_MAX_HH
Index: mln/accu/mean.hh
--- mln/accu/mean.hh	(revision 1015)
+++ mln/accu/mean.hh	(working copy)
@@ -33,7 +33,8 @@
  * \brief Define an accumulator that computes a mean.
  */
 
-# include <mln/core/concept/accumulator.hh>
+# include <mln/accu/counter.hh>
+# include <mln/accu/sum.hh>
 
 
 namespace mln
@@ -64,8 +65,8 @@
       
     protected:
 
-      std::size_t count_;
-      S sum_;
+      accu::counter<V> count_;
+      accu::sum<V,S>   sum_;
     };
 
 
@@ -81,16 +82,16 @@
     template <typename V, typename S, typename M>
     void mean<V,S,M>::take(const value& v)
     {
-      ++count_;
-      sum_ += v;
+      count_.take(v);
+      sum_.take(v);
     }
 
     template <typename V, typename S, typename M>
     void
     mean<V,S,M>::init()
     {
-      count_ = 0;
-      sum_ = 0;
+      count_.init();
+      sum_.init();
     }
 
     template <typename V, typename S, typename M>
@@ -103,7 +104,7 @@
     M
     mean<V,S,M>::to_value() const
     {
-      return sum_ / count_;
+      return sum_.to_value() / count_.to_value();
     }
 
 # endif // ! MLN_INCLUDE_ONLY
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0