* mln/world/k1/immerse.hh: Make use of kn::immerse.
* mln/world/k2/convert_on_access.hh,
* mln/world/k2/fill_0_from_1_faces.hh,
* mln/world/k2/fill_1_from_2_faces.hh,
* mln/world/k2/fill_non_primary_from_primary_faces.hh,
* mln/world/k2/immerse.hh,
* mln/world/k2/immerse_with.hh,
* mln/world/k2/is_non_primary_face.hh,
* mln/world/k2/is_non_primary_face_cross.hh,
* mln/world/k2/is_non_primary_face_horizontal.hh,
* mln/world/k2/is_non_primary_face_vertical.hh,
* mln/world/k2/is_primary_face.hh,
* mln/world/k2/neighb2d.hh,
* mln/world/kn/immerse.hh: New.
---
milena/ChangeLog | 20 ++
milena/mln/world/k1/immerse.hh | 64 +++----
milena/mln/world/k2/convert_on_access.hh | 126 ++++++++++++
milena/mln/world/k2/fill_0_from_1_faces.hh | 114 +++++++++++
milena/mln/world/k2/fill_1_from_2_faces.hh | 118 +++++++++++
.../k2/fill_non_primary_from_primary_faces.hh | 212 ++++++++++++++++++++
milena/mln/world/k2/immerse.hh | 127 ++++++++++++
milena/mln/world/k2/immerse_with.hh | 173 ++++++++++++++++
milena/mln/world/k2/is_non_primary_face.hh | 83 ++++++++
milena/mln/world/k2/is_non_primary_face_cross.hh | 88 ++++++++
.../mln/world/k2/is_non_primary_face_horizontal.hh | 83 ++++++++
.../mln/world/k2/is_non_primary_face_vertical.hh | 83 ++++++++
milena/mln/world/k2/is_primary_face.hh | 82 ++++++++
milena/mln/world/k2/neighb2d.hh | 139 +++++++++++++
milena/mln/world/kn/immerse.hh | 161 +++++++++++++++
15 files changed, 1635 insertions(+), 38 deletions(-)
create mode 100644 milena/mln/world/k2/convert_on_access.hh
create mode 100644 milena/mln/world/k2/fill_0_from_1_faces.hh
create mode 100644 milena/mln/world/k2/fill_1_from_2_faces.hh
create mode 100644 milena/mln/world/k2/fill_non_primary_from_primary_faces.hh
create mode 100644 milena/mln/world/k2/immerse.hh
create mode 100644 milena/mln/world/k2/immerse_with.hh
create mode 100644 milena/mln/world/k2/is_non_primary_face.hh
create mode 100644 milena/mln/world/k2/is_non_primary_face_cross.hh
create mode 100644 milena/mln/world/k2/is_non_primary_face_horizontal.hh
create mode 100644 milena/mln/world/k2/is_non_primary_face_vertical.hh
create mode 100644 milena/mln/world/k2/is_primary_face.hh
create mode 100644 milena/mln/world/k2/neighb2d.hh
create mode 100644 milena/mln/world/kn/immerse.hh
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 551ff9d..98c1406 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,25 @@
2012-10-18 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Introduce K2 and Kn spaces.
+
+ * mln/world/k1/immerse.hh: Make use of kn::immerse.
+
+ * mln/world/k2/convert_on_access.hh,
+ * mln/world/k2/fill_0_from_1_faces.hh,
+ * mln/world/k2/fill_1_from_2_faces.hh,
+ * mln/world/k2/fill_non_primary_from_primary_faces.hh,
+ * mln/world/k2/immerse.hh,
+ * mln/world/k2/immerse_with.hh,
+ * mln/world/k2/is_non_primary_face.hh,
+ * mln/world/k2/is_non_primary_face_cross.hh,
+ * mln/world/k2/is_non_primary_face_horizontal.hh,
+ * mln/world/k2/is_non_primary_face_vertical.hh,
+ * mln/world/k2/is_primary_face.hh,
+ * mln/world/k2/neighb2d.hh,
+ * mln/world/kn/immerse.hh: New.
+
+2012-10-18 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Some fixes.
* mln/labeling/compute.hh: Fix include.
diff --git a/milena/mln/world/k1/immerse.hh b/milena/mln/world/k1/immerse.hh
index b9b58fb..1f59f7e 100644
--- a/milena/mln/world/k1/immerse.hh
+++ b/milena/mln/world/k1/immerse.hh
@@ -34,6 +34,8 @@
# include <mln/core/concept/box.hh>
# include <mln/core/alias/point2d.hh>
+# include <mln/world/kn/immerse.hh>
+
namespace mln
{
@@ -45,6 +47,11 @@ namespace mln
/*! \brief Immerse a 2D image into K1.
+ \param[in] ima 2D Image in K0.
+ \param[in] new_type Value type of the immersed image.
+
+ \return A 2D image immersed in k1 of value type \tparam V.
+
\verbatim
-1 0 1 2 3
@@ -57,60 +64,41 @@ namespace mln
\endverbatim
*/
+ template <typename I, typename V>
+ mln_concrete(I) immerse(const Image<I>& ima, const V& new_type);
+
+ /// \overload
+ /// new_type is set to mln_value(I).
template <typename I>
mln_concrete(I) immerse(const Image<I>& ima);
# ifndef MLN_INCLUDE_ONLY
- namespace internal
- {
-
- /// Return the equivalent point in K1 from a point in K0.
- inline
- point2d immerse_point(const point2d& p)
- {
- point2d tmp(2 * p.row(), 2 * p.col());
- return tmp;
- }
-
- /// \brief Return the equivalent domain in K1 from a domain in
- /// K0.
- template <typename B>
- inline
- B domain_from_K0(const Box<B>& b_)
- {
- mln_precondition(exact(b_).is_valid());
- const B& b = exact(b_);
-
- mln_deduce(B, site, delta) one;
- one.set_all(1);
- return B(immerse_point(b.pmin()) - one, immerse_point(b.pmax()) + one);
- }
-
- } // end of namespace mln::world::k1::internal
-
-
-
// Facade
- template <typename I>
- mln_concrete(I) immerse(const Image<I>& ima_)
+ template <typename I, typename V>
+ mln_concrete(I)
+ immerse(const Image<I>& ima, const V& new_type)
{
trace::entering("mln::world::k1::immerse");
- mln_precondition(exact(ima_).is_valid());
- const I& ima = exact(ima_);
+ mln_precondition(exact(ima).is_valid());
- mln_concrete(I) output(internal::domain_from_K0(ima.domain()));
-
- mln_piter(I) p(ima.domain());
- for_all(p)
- output(internal::immerse_point(p)) = ima(p);
+ mln_concrete(I) output = kn::immerse(ima, 1, V());
trace::exiting("mln::world::k1::immerse");
return output;
}
+
+ template <typename I>
+ mln_concrete(I)
+ immerse(const Image<I>& ima)
+ {
+ typedef mln_value(I) V;
+ return immerse(ima, V());
+ }
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::world::k1
diff --git a/milena/mln/world/k2/convert_on_access.hh
b/milena/mln/world/k2/convert_on_access.hh
new file mode 100644
index 0000000..4c9ab20
--- /dev/null
+++ b/milena/mln/world/k2/convert_on_access.hh
@@ -0,0 +1,126 @@
+// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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
+///
+/// \brief Fill 1 faces in a K2 2D image using its 2 faces.
+
+#ifndef MLN_WORLD_K2_CONVERT_ON_ACCESS_HH
+# define MLN_WORLD_K2_CONVERT_ON_ACCESS_HH
+
+# include <mln/core/alias/point2d.hh>
+# include <mln/world/k2/is_non_primary_face_vertical.hh>
+# include <mln/world/k2/is_non_primary_face_horizontal.hh>
+# include <mln/world/k2/convert_on_access.hh>
+
+# include <mln/value/int_u8.hh>
+# include <mln/value/intsub.hh>
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace k2
+ {
+
+ using namespace mln::value;
+
+ template <unsigned n>
+ void convert_on_access(const intsub<n>& from, intsub<n/2>&
to);
+
+ template <unsigned n>
+ void convert_on_access(const int_u8& from, intsub<n>& to);
+
+ template <unsigned n>
+ void convert_on_access(const int_u8& from, interval<intsub<n>
>& to);
+
+ template <unsigned n>
+ void convert_on_access(const interval<intsub<n> >& from, int&
to);
+
+ template <unsigned n>
+ void convert_on_access(const interval<intsub<n> >& from,
value::int_u8& to);
+
+ template <typename T, typename U>
+ void convert_on_access(const T& from, U& to);
+
+
+#ifndef MLN_INCLUDE_ONLY
+
+ template <unsigned n>
+ void convert_on_access(const intsub<n/2>& from, intsub<n>& to)
+ {
+ to = from.to_int();
+ }
+
+ template <unsigned n>
+ void convert_on_access(const int_u8& from, intsub<n>& to)
+ {
+ to = from.to_equiv();
+ }
+
+ template <unsigned n>
+ void convert_on_access(const int_u8& from, interval<intsub<n>
>& to)
+ {
+ to = intsub<n>(from.to_interop());
+ }
+
+ template <unsigned n>
+ void convert_on_access(const interval<intsub<n> >& from, int&
to)
+ {
+ mln_precondition(from.is_degenerated());
+ to = from.first();
+ }
+
+ template <unsigned n>
+ void convert_on_access(const interval<intsub<n> >& from,
value::int_u8& to)
+ {
+ mln_precondition(from.is_degenerated());
+ to = from.first();
+ }
+
+ template <unsigned n>
+ void convert_on_access(const interval<intsub<n> >& from,
intsub<n/2>& to)
+ {
+ mln_precondition(from.is_degenerated());
+ to = from.first().to_interop();
+ }
+
+ template <typename T, typename U>
+ void convert_on_access(const T& from, U& to)
+ {
+ to = static_cast<U>(from);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::world::k2
+
+ } // end of namespace mln::world
+
+} // end of namespace mln
+
+#endif // ! MLN_WORLD_K2_CONVERT_ON_ACCESS_HH
diff --git a/milena/mln/world/k2/fill_0_from_1_faces.hh
b/milena/mln/world/k2/fill_0_from_1_faces.hh
new file mode 100644
index 0000000..5f4830e
--- /dev/null
+++ b/milena/mln/world/k2/fill_0_from_1_faces.hh
@@ -0,0 +1,114 @@
+// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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
+///
+/// \brief Fill 1 faces in a K2 2D image using its 2 faces.
+
+#ifndef MLN_WORLD_K2_FILL_0_FROM_1_FACES_HH
+# define MLN_WORLD_K2_FILL_0_FROM_1_FACES_HH
+
+# include <mln/core/alias/point2d.hh>
+# include <mln/world/k1/is_0_face.hh>
+
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace k2
+ {
+
+ /*! \brief Fill 1 faces in a K2 2D image using its 2 faces.
+
+ \param[in,out] inout A 2D image immersed in K2.
+ \param[in,out] accu An accumulator.
+
+ This function use the following neighborhoods:
+
+ * In case of vertical 1 faces:
+
+ \verbatim
+ x | x
+ \endverbatim
+
+ * In case of horizontal 1 face:
+
+ \verbatim
+ x
+ -
+ x
+ \endverbatim
+
+ */
+ template <typename I, typename A>
+ void fill_0_from_1_faces(Image<I>& inout,
+ const Accumulator<A>& accu);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ // Facade
+
+
+ template <typename I, typename A>
+ void fill_0_from_1_faces(Image<I>& inout_,
+ const Accumulator<A>& accu_)
+ {
+ trace::entering("mln::world::k2::fill_0_from_1_faces");
+
+ mln_precondition(exact(inout_).is_valid());
+ I& inout = exact(inout_);
+ (void) accu_;
+
+ A accu = A();
+ mln_piter(I) p(inout.domain());
+ for_all(p)
+ if (k1::is_0_face(p))
+ {
+ accu.init();
+ accu.take(inout(p + left));
+ accu.take(inout(p + right));
+ accu.take(inout(p + up));
+ accu.take(inout(p + down));
+ inout(p) = accu.to_result();
+ }
+
+ trace::exiting("mln::world::k2::fill_0_from_1_faces");
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::world::k2
+
+ } // end of namespace mln::world
+
+} // end of namespace mln
+
+#endif // ! MLN_WORLD_K2_FILL_0_FROM_1_FACES_HH
diff --git a/milena/mln/world/k2/fill_1_from_2_faces.hh
b/milena/mln/world/k2/fill_1_from_2_faces.hh
new file mode 100644
index 0000000..5e242d2
--- /dev/null
+++ b/milena/mln/world/k2/fill_1_from_2_faces.hh
@@ -0,0 +1,118 @@
+// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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
+///
+/// \brief Fill 1 faces in a K2 2D image using its 2 faces.
+
+#ifndef MLN_WORLD_K2_FILL_1_FROM_2_FACES_HH
+# define MLN_WORLD_K2_FILL_1_FROM_2_FACES_HH
+
+# include <mln/core/alias/point2d.hh>
+# include <mln/world/k1/is_1_face_vertical.hh>
+# include <mln/world/k1/is_1_face_horizontal.hh>
+
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace k2
+ {
+
+ /*! \brief Fill 1 faces in a K2 2D image using its 2 faces.
+
+ \param[in,out] inout A 2D image immersed in K2.
+ \param[in,out] accu An accumulator.
+
+ This function use the following neighborhoods:
+
+ * In case of vertical 1 faces:
+
+ \verbatim
+ x | x
+ \endverbatim
+
+ * In case of horizontal 1 face:
+
+ \verbatim
+ x
+ -
+ x
+ \endverbatim
+
+ */
+ template <typename I, typename A>
+ void fill_1_from_2_faces(Image<I>& inout, const Accumulator<A>&
accu);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ // Facade
+
+
+ template <typename I, typename A>
+ void fill_1_from_2_faces(Image<I>& inout_, const
Accumulator<A>& accu_)
+ {
+ trace::entering("mln::world::k2::fill_1_from_2_faces");
+
+ mln_precondition(exact(inout_).is_valid());
+ I& inout = exact(inout_);
+ (void) accu_;
+
+ A accu = A();
+ mln_piter(I) p(inout.domain());
+ for_all(p)
+ if (k1::is_1_face_vertical(p))
+ {
+ accu.init();
+ accu.take(inout(p + left));
+ accu.take(inout(p + right));
+ inout(p) = accu.to_result();
+ }
+ else if (k1::is_1_face_horizontal(p))
+ {
+ accu.init();
+ accu.take(inout(p + up));
+ accu.take(inout(p + down));
+ inout(p) = accu.to_result();
+ }
+
+ trace::exiting("mln::world::k2::fill_1_from_2_faces");
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::world::k2
+
+ } // end of namespace mln::world
+
+} // end of namespace mln
+
+#endif // ! MLN_WORLD_K2_FILL_1_FROM_2_FACES_HH
diff --git a/milena/mln/world/k2/fill_non_primary_from_primary_faces.hh
b/milena/mln/world/k2/fill_non_primary_from_primary_faces.hh
new file mode 100644
index 0000000..bc7509f
--- /dev/null
+++ b/milena/mln/world/k2/fill_non_primary_from_primary_faces.hh
@@ -0,0 +1,212 @@
+// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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
+///
+/// \brief Fill 1 faces in a K2 2D image using its 2 faces.
+
+#ifndef MLN_WORLD_K2_FILL_NON_PRIMARY_FROM_PRIMARY_FACES_HH
+# define MLN_WORLD_K2_FILL_NON_PRIMARY_FROM_PRIMARY_FACES_HH
+
+# include <mln/core/alias/point2d.hh>
+# include <mln/world/k2/is_non_primary_face_vertical.hh>
+# include <mln/world/k2/is_non_primary_face_horizontal.hh>
+# include <mln/world/k2/is_non_primary_face_cross.hh>
+# include <mln/world/k2/convert_on_access.hh>
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace k2
+ {
+
+ /*! \brief Fill non-primary 2-faces in a K2 2D image using
+ * primary 2-faces.
+
+ \param[in,out] inout A 2D image immersed in K2.
+ \param[in,out] accu An accumulator.
+
+ This function use the following neighborhoods:
+
+ * In case of vertical non-primary 2-faces:
+
+ \verbatim
+ x o x
+ \endverbatim
+
+ * In case of horizontal non-primary 2-face:
+
+ \verbatim
+ x
+ o
+ x
+ \endverbatim
+
+ * In case of cross non-primary 2-face:
+
+ \verbatim
+ x x
+ o
+ x x
+ \endverbatim
+
+ */
+ /// \overload
+ template <typename I, typename A>
+ void fill_non_primary_from_primary_faces(Image<I>& inout,
+ const Accumulator<A>& accu);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ // Facade
+
+ template <typename I, typename A>
+ void fill_non_primary_from_primary_faces(Image<I>& inout_,
+ F& functor_)
+ {
+ trace::entering("mln::world::k2::fill_non_primary_from_primary_faces");
+
+ mln_precondition(exact(inout_).is_valid());
+ I& inout = exact(inout_);
+ (void) accu_;
+ typedef typename A::argument V;
+
+ A& accu = exact(accu_);
+
+ mln_piter(I) p(inout.domain());
+ for_all(p)
+ if (is_non_primary_face_vertical(p))
+ {
+ accu.init();
+ V tmp1, tmp2;
+
+ convert_on_access(inout(p + 2 * left), tmp1);
+ convert_on_access(inout(p + 2 * right), tmp2);
+ convert_on_access(f(tmp1, tmp2), inout(p));
+ }
+ else if (is_non_primary_face_horizontal(p))
+ {
+ accu.init();
+ V tmp1, tmp2;
+
+ convert_on_access(inout(p + 2 * up), tmp1);
+ convert_on_access(inout(p + 2 * down), tmp2);
+ convert_on_access(f(tmp1, tmp2), inout(p));
+ }
+ else if (is_non_primary_face_cross(p))
+ {
+ accu.init();
+ V tmp1, tmp2, tmp3, tmp4;
+
+ convert_on_access(inout(p + 2 * up_left), tmp1);
+ convert_on_access(inout(p + 2 * up_right), tmp2);
+ convert_on_access(inout(p + 2 * down_left), tmp3);
+ convert_on_access(inout(p + 2 * down_right), tmp4);
+ convert_on_access(f(tmp1, tmp2, tmp3, tmp4), inout(p));
+ }
+
+ trace::exiting("mln::world::k2::fill_non_primary_from_primary_faces");
+ }
+
+
+ template <typename I, typename A>
+ void fill_non_primary_from_primary_faces(Image<I>& inout_,
+ Accumulator<A>& accu_)
+ {
+ trace::entering("mln::world::k2::fill_non_primary_from_primary_faces");
+
+ mln_precondition(exact(inout_).is_valid());
+ I& inout = exact(inout_);
+ (void) accu_;
+ typedef typename A::argument V;
+
+ A& accu = exact(accu_);
+
+ mln_piter(I) p(inout.domain());
+ for_all(p)
+ if (is_non_primary_face_vertical(p))
+ {
+ accu.init();
+ V tmp;
+
+ convert_on_access(inout(p + 2 * left), tmp);
+ accu.take(tmp);
+
+ convert_on_access(inout(p + 2 * right), tmp);
+ accu.take(tmp);
+
+ convert_on_access(accu.to_result(), inout(p));
+ }
+ else if (is_non_primary_face_horizontal(p))
+ {
+ accu.init();
+ V tmp;
+
+ convert_on_access(inout(p + 2 * up), tmp);
+ accu.take(tmp);
+
+ convert_on_access(inout(p + 2 * down), tmp);
+ accu.take(tmp);
+
+ convert_on_access(accu.to_result(), inout(p));
+ }
+ else if (is_non_primary_face_cross(p))
+ {
+ accu.init();
+ V tmp;
+
+ convert_on_access(inout(p + 2 * up_left), tmp);
+ accu.take(tmp);
+
+ convert_on_access(inout(p + 2 * up_right), tmp);
+ accu.take(tmp);
+
+ convert_on_access(inout(p + 2 * down_left), tmp);
+ accu.take(tmp);
+
+ convert_on_access(inout(p + 2 * down_right), tmp);
+ accu.take(tmp);
+
+ convert_on_access(accu.to_result(), inout(p));
+ }
+
+ trace::exiting("mln::world::k2::fill_non_primary_from_primary_faces");
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::world::k2
+
+ } // end of namespace mln::world
+
+} // end of namespace mln
+
+#endif // ! MLN_WORLD_K2_FILL_NON_PRIMARY_FROM_PRIMARY_FACES_HH
diff --git a/milena/mln/world/k2/immerse.hh b/milena/mln/world/k2/immerse.hh
new file mode 100644
index 0000000..eb6ba30
--- /dev/null
+++ b/milena/mln/world/k2/immerse.hh
@@ -0,0 +1,127 @@
+// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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
+///
+/// \brief Immerse a 2D image into K2.
+
+#ifndef MLN_WORLD_K2_IMMERSE_HH
+# define MLN_WORLD_K2_IMMERSE_HH
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/box.hh>
+# include <mln/core/alias/point2d.hh>
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace k2
+ {
+
+ /*! \brief Immerse a 2D image into K2.
+
+ \verbatim
+
+ -1 0 1 2 3
+ 0 1 -1 . - . - .
+ 0 o o 0 | o | o |
+ 1 o o -> 1 . - . - .
+ 2 | o | o |
+ 3 . - . - .
+
+ \endverbatim
+
+ */
+ template <typename I>
+ mln_concrete(I) immerse(const Image<I>& ima);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+
+ /// Return the equivalent point in K2 from a point in K0.
+ inline
+ point2d immerse_point(const point2d& p)
+ {
+ point2d tmp(4 * p.row(), 4 * p.col());
+ return tmp;
+ }
+
+ /// \brief Return the equivalent domain in K2 from a domain in
+ /// K0.
+ template <typename B>
+ inline
+ B domain_from_K0(const Box<B>& b_)
+ {
+ mln_precondition(exact(b_).is_valid());
+ const B& b = exact(b_);
+
+ mln_deduce(B, site, delta) one;
+ one.set_all(1);
+ return B(immerse_point(b.pmin()) - one, immerse_point(b.pmax()) + one);
+ }
+
+ } // end of namespace mln::world::k2::internal
+
+
+
+ // Facade
+
+ template <typename I>
+ mln_concrete(I) immerse(const Image<I>& ima_)
+ {
+ trace::entering("mln::world::k2::immerse");
+ mln_precondition(exact(ima_).is_valid());
+ const I& ima = exact(ima_);
+
+ mln_concrete(I) output(internal::domain_from_K0(ima.domain()));
+
+ mln_piter(I) p(ima.domain());
+ for_all(p)
+ {
+ output(internal::immerse_point(p)) = ima(p);
+ output(internal::immerse_point(p) + 2 * right) = ima(p);
+ output(internal::immerse_point(p) + 2 * down) = ima(p);
+ output(internal::immerse_point(p) + 2 * down_right) = ima(p);
+ }
+
+ trace::exiting("mln::world::k2::immerse");
+ return output;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::world::k2
+
+ } // end of namespace mln::world
+
+} // end of namespace mln
+
+#endif // ! MLN_WORLD_K2_IMMERSE_HH
diff --git a/milena/mln/world/k2/immerse_with.hh b/milena/mln/world/k2/immerse_with.hh
new file mode 100644
index 0000000..bc8e8ad
--- /dev/null
+++ b/milena/mln/world/k2/immerse_with.hh
@@ -0,0 +1,173 @@
+// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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
+///
+/// \brief Immerse a 2D image into K2.
+
+#ifndef MLN_WORLD_K2_IMMERSE_HH
+# define MLN_WORLD_K2_IMMERSE_HH
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/box.hh>
+# include <mln/core/alias/point2d.hh>
+# include <mln/value/interval.hh>
+# include <mln/fun/vv2v/span.hh>
+# include <mln/fun/vvvv2v/span.hh>
+
+# include <mln/world/k1/fill_0_from_1_faces.hh>
+# include <mln/world/k1/fill_1_from_2_faces.hh>
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace k2
+ {
+
+ /*! \brief Immerse a 2D image into K2.
+
+ \verbatim
+
+ -1 0 1 2 3
+ 0 1 -1 . - . - .
+ 0 o o 0 | o | o |
+ 1 o o -> 1 . - . - .
+ 2 | o | o |
+ 3 . - . - .
+
+ \endverbatim
+
+ */
+ template <typename I>
+ mln_concrete(I) immerse(const Image<I>& ima);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+
+ /// Return the equivalent point in K2 from a point in K0.
+ inline
+ point2d immerse_point(const point2d& p)
+ {
+ point2d tmp(4 * p.row(), 4 * p.col());
+ return tmp;
+ }
+
+ /// \brief Return the equivalent domain in K2 from a domain in
+ /// K0.
+ template <typename B>
+ inline
+ B domain_from_K0(const Box<B>& b_)
+ {
+ mln_precondition(exact(b_).is_valid());
+ const B& b = exact(b_);
+
+ mln_deduce(B, site, delta) one;
+ one.set_all(1);
+ return B(immerse_point(b.pmin()) - one, immerse_point(b.pmax()) + one);
+ }
+
+ } // end of namespace mln::world::k2::internal
+
+
+
+ // Facade
+
+ template <typename I, typename F2, typename F4>
+ mln_ch_value(I, value::interval<mln_result(F4)>)
+ immerse_with(const Image<I>& ima_,
+ Function_vv2v<F2>& f2_, Function_vvvv2v<F4>& f4_)
+ {
+ trace::entering("mln::world::k2::immerse_with");
+ mln_precondition(exact(ima_).is_valid());
+ const I& ima = exact(ima_);
+ const F2& f2 = exact(f2_);
+ const F4& f4 = exact(f4_);
+
+ // FIXME: how to initialize the border... ?
+ // border::fill(ima, 0);
+
+ typedef mln_result(F4) V;
+ typedef value::interval<V> VOUT;
+ mln_ch_value(I,VOUT)
+ output(internal::domain_from_K0(ima.domain()));
+
+ // Filling 2-Faces
+ mln_piter(I) p(ima.domain());
+ for_all(p)
+ {
+ // .-.-
+ // ab |x|*| -> a
+ // cd -> .-.-.
+ // |*|*|
+ // .-.-.
+ output(internal::immerse_point(p)) = ima(p);
+
+ // .-.-
+ // ab |*|x| -> f2(a,b)
+ // cd -> .-.-.
+ // |*|*|
+ // .-.-.
+ output(internal::immerse_point(p) + 2 * right) = f2(ima(p), ima(p + right));
+
+ // .-.-
+ // ab |*|*|
+ // cd -> .-.-.
+ // |x|*| -> f2(a,c)
+ // .-.-.
+ output(internal::immerse_point(p) + 2 * down) = f2(ima(p), ima(p + down));
+
+ // .-.-
+ // ab |*|*|
+ // cd -> .-.-.
+ // |*|x| -> f4(a,b,c,d)
+ // .-.-.
+ output(internal::immerse_point(p) + 2 * down_right)
+ = f4(ima(p), ima(p + right), ima(p + down), ima(p + down_right));
+ }
+
+ fun::vv2v::span<V> span2;
+ k1::fill_1_from_2_faces(output, span2);
+ fun::vvvv2v::span<V> span4;
+ k1::fill_0_from_1_faces(output, span4);
+
+ trace::exiting("mln::world::k2::immerse_with");
+ return output;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::world::k2
+
+ } // end of namespace mln::world
+
+} // end of namespace mln
+
+#endif // ! MLN_WORLD_K2_IMMERSE_HH
diff --git a/milena/mln/world/k2/is_non_primary_face.hh
b/milena/mln/world/k2/is_non_primary_face.hh
new file mode 100644
index 0000000..2088040
--- /dev/null
+++ b/milena/mln/world/k2/is_non_primary_face.hh
@@ -0,0 +1,83 @@
+// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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
+///
+/// \brief Check if site is a non-primary face.
+
+#ifndef MLN_WORLD_K2_IS_NON_PRIMARY_FACE_HH
+# define MLN_WORLD_K2_IS_NON_PRIMARY_FACE_HH
+
+# include <mln/core/alias/point2d.hh>
+# include <mln/world/k1/is_2_face.hh>
+# include <mln/world/k2/is_primary_face.hh>
+
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace k2
+ {
+
+ /// \brief Check if site is a non-primary face
+ bool is_non_primary_face(const point2d& p);
+
+
+ /// \overload
+ bool is_non_primary_face(const mln::def::coord& row,
+ const mln::def::coord& col);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ // Facade
+
+ inline
+ bool is_non_primary_face(const point2d& p)
+ {
+ return is_non_primary_face(p.row(), p.col());
+ }
+
+ inline
+ bool is_non_primary_face(const mln::def::coord& row,
+ const mln::def::coord& col)
+ {
+ return k1::is_2_face(row, col) && !is_primary_face(row, col);
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::world::k2
+
+ } // end of namespace mln::world
+
+} // end of namespace mln
+
+#endif // ! MLN_WORLD_K2_IS_NON_PRIMARY_FACE_HH
diff --git a/milena/mln/world/k2/is_non_primary_face_cross.hh
b/milena/mln/world/k2/is_non_primary_face_cross.hh
new file mode 100644
index 0000000..fad4c23
--- /dev/null
+++ b/milena/mln/world/k2/is_non_primary_face_cross.hh
@@ -0,0 +1,88 @@
+// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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
+///
+/// \brief Check if site is a cross non-primary face.
+
+#ifndef MLN_WORLD_K2_IS_NON_PRIMARY_FACE_CROSS_HH
+# define MLN_WORLD_K2_IS_NON_PRIMARY_FACE_CROSS_HH
+
+# include <mln/core/alias/point2d.hh>
+
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace k2
+ {
+
+ /// \brief Check if site is a cross non-primary face
+ ///
+ /// |a| |b|
+ /// .-.-.-.
+ /// | |x| |
+ /// .-.-.-.
+ /// |c| |d|
+ ///
+ bool is_non_primary_face_cross(const point2d& p);
+
+
+ /// \overload
+ bool is_non_primary_face_cross(const mln::def::coord& row,
+ const mln::def::coord& col);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ // Facade
+
+ inline
+ bool is_non_primary_face_cross(const point2d& p)
+ {
+ return is_non_primary_face_cross(p.row(), p.col());
+ }
+
+ inline
+ bool is_non_primary_face_cross(const mln::def::coord& row,
+ const mln::def::coord& col)
+ {
+ return (row % 4 == 2) && (col % 4 == 2);
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::world::k2
+
+ } // end of namespace mln::world
+
+} // end of namespace mln
+
+#endif // ! MLN_WORLD_K2_IS_NON_PRIMARY_FACE_CROSS_HH
diff --git a/milena/mln/world/k2/is_non_primary_face_horizontal.hh
b/milena/mln/world/k2/is_non_primary_face_horizontal.hh
new file mode 100644
index 0000000..3a65995
--- /dev/null
+++ b/milena/mln/world/k2/is_non_primary_face_horizontal.hh
@@ -0,0 +1,83 @@
+// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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
+///
+/// \brief Check if site is a horizontal non-primary face.
+
+#ifndef MLN_WORLD_K2_IS_NON_PRIMARY_FACE_HORIZONTAL_HH
+# define MLN_WORLD_K2_IS_NON_PRIMARY_FACE_HORIZONTAL_HH
+
+# include <mln/core/alias/point2d.hh>
+# include <mln/world/k1/is_2_face.hh>
+# include <mln/world/k2/is_non_primary_face.hh>
+
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace k2
+ {
+
+ /// \brief Check if site is a horizontal non-primary face
+ bool is_non_primary_face_horizontal(const point2d& p);
+
+
+ /// \overload
+ bool is_non_primary_face_horizontal(const mln::def::coord& row,
+ const mln::def::coord& col);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ // Facade
+
+ inline
+ bool is_non_primary_face_horizontal(const point2d& p)
+ {
+ return is_non_primary_face_horizontal(p.row(), p.col());
+ }
+
+ inline
+ bool is_non_primary_face_horizontal(const mln::def::coord& row,
+ const mln::def::coord& col)
+ {
+ return is_non_primary_face(row, col) && ! (col % 4);
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::world::k2
+
+ } // end of namespace mln::world
+
+} // end of namespace mln
+
+#endif // ! MLN_WORLD_K2_IS_NON_PRIMARY_FACE_HORIZONTAL_HH
diff --git a/milena/mln/world/k2/is_non_primary_face_vertical.hh
b/milena/mln/world/k2/is_non_primary_face_vertical.hh
new file mode 100644
index 0000000..5fd2d24
--- /dev/null
+++ b/milena/mln/world/k2/is_non_primary_face_vertical.hh
@@ -0,0 +1,83 @@
+// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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
+///
+/// \brief Check if site is a vertical non-primary face.
+
+#ifndef MLN_WORLD_K2_IS_NON_PRIMARY_FACE_VERTICAL_HH
+# define MLN_WORLD_K2_IS_NON_PRIMARY_FACE_VERTICAL_HH
+
+# include <mln/core/alias/point2d.hh>
+# include <mln/world/k1/is_2_face.hh>
+# include <mln/world/k2/is_non_primary_face.hh>
+
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace k2
+ {
+
+ /// \brief Check if site is a vertical non-primary face
+ bool is_non_primary_face_vertical(const point2d& p);
+
+
+ /// \overload
+ bool is_non_primary_face_vertical(const mln::def::coord& row,
+ const mln::def::coord& col);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ // Facade
+
+ inline
+ bool is_non_primary_face_vertical(const point2d& p)
+ {
+ return is_non_primary_face_vertical(p.row(), p.col());
+ }
+
+ inline
+ bool is_non_primary_face_vertical(const mln::def::coord& row,
+ const mln::def::coord& col)
+ {
+ return is_non_primary_face(row, col) && ! (row % 4);
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::world::k2
+
+ } // end of namespace mln::world
+
+} // end of namespace mln
+
+#endif // ! MLN_WORLD_K2_IS_NON_PRIMARY_FACE_VERTICAL_HH
diff --git a/milena/mln/world/k2/is_primary_face.hh
b/milena/mln/world/k2/is_primary_face.hh
new file mode 100644
index 0000000..033c7a4
--- /dev/null
+++ b/milena/mln/world/k2/is_primary_face.hh
@@ -0,0 +1,82 @@
+// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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
+///
+/// \brief Check if site is a primary face.
+
+#ifndef MLN_WORLD_K2_IS_PRIMARY_FACE_HH
+# define MLN_WORLD_K2_IS_PRIMARY_FACE_HH
+
+# include <mln/core/alias/point2d.hh>
+# include <mln/world/k1/is_2_face.hh>
+
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace k2
+ {
+
+ /// \brief Check if site is a primary face
+ bool is_primary_face(const point2d& p);
+
+
+ /// \overload
+ bool is_primary_face(const mln::def::coord& row,
+ const mln::def::coord& col);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ // Facade
+
+ inline
+ bool is_primary_face(const point2d& p)
+ {
+ return is_primary_face(p.row(), p.col());
+ }
+
+ inline
+ bool is_primary_face(const mln::def::coord& row,
+ const mln::def::coord& col)
+ {
+ return !((row % 4) + (col % 4));
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::world::k2
+
+ } // end of namespace mln::world
+
+} // end of namespace mln
+
+#endif // ! MLN_WORLD_K2_IS_PRIMARY_FACE_HH
diff --git a/milena/mln/world/k2/neighb2d.hh b/milena/mln/world/k2/neighb2d.hh
new file mode 100644
index 0000000..e248cef
--- /dev/null
+++ b/milena/mln/world/k2/neighb2d.hh
@@ -0,0 +1,139 @@
+// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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
+///
+/// \brief 2D neighborhood working in K2.
+
+#ifndef MLN_WORLD_K2_NEIGHB2D_HH
+# define MLN_WORLD_K2_NEIGHB2D_HH
+
+# include <mln/core/alias/point2d.hh>
+# include <mln/core/alias/neighb2d.hh>
+# include <mln/win/multiple.hh>
+# include <mln/make/double_neighb2d.hh>
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace k2
+ {
+
+ /*! \brief Non-primary to primary faces neighborhood.
+
+ \verbatim
+ o| |o
+ -.-.-
+ |x|
+ -.-.-
+ o| |o
+ \endverbatim
+ */
+ const neighb2d& cross_np2p_faces();
+
+ /*! \brief Non-primary to primary faces neighborhood.
+
+ \verbatim
+ |o|
+ .-.
+ |x|
+ .-.
+ |o|
+ \endverbatim
+ */
+ const neighb2d& vertical_np2p_faces();
+
+ /*! \brief Non-primary to primary faces neighborhood.
+
+ \verbatim
+ .-.-.-.
+ |o|x|o|
+ .-.-.-.
+ \endverbatim
+ */
+ const neighb2d& horizontal_np2p_faces();
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ const neighb2d& cross_np2p_faces()
+ {
+ static neighb2d it;
+ if (it.size() == 0)
+ {
+ static bool vals[] = { 1, 0, 0, 0, 1,
+ 0, 0, 0, 0, 0,
+ 0, 0, X, 0, 0,
+ 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 1 };
+ convert::from_to(vals, it);
+ }
+ return it;
+ }
+
+
+ const neighb2d& vertical_np2p_faces()
+ {
+ static neighb2d it;
+ if (it.size() == 0)
+ {
+ static bool vals[] = { 0, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0 };
+ convert::from_to(vals, it);
+ }
+ return it;
+ }
+
+
+ const neighb2d& horizontal_np2p_faces()
+ {
+ static neighb2d it;
+ if (it.size() == 0)
+ {
+ static bool vals[] = { 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 1,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0 };
+ convert::from_to(vals, it);
+ }
+ return it;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::world::k2
+
+ } // end of namespace mln::world
+
+} // end of namespace mln
+
+#endif // ! MLN_WORLD_K2_NEIGHB2D_HH
diff --git a/milena/mln/world/kn/immerse.hh b/milena/mln/world/kn/immerse.hh
new file mode 100644
index 0000000..380b52f
--- /dev/null
+++ b/milena/mln/world/kn/immerse.hh
@@ -0,0 +1,161 @@
+// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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
+///
+/// \brief Immerse a 2D image into Kn.
+
+#ifndef MLN_WORLD_Kn_IMMERSE_HH
+# define MLN_WORLD_Kn_IMMERSE_HH
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/box.hh>
+# include <mln/core/alias/point2d.hh>
+# include <mln/value/interval.hh>
+# include <mln/fun/vv2v/span.hh>
+# include <mln/fun/vvvv2v/span.hh>
+
+# include <mln/world/k1/fill_0_from_1_faces.hh>
+# include <mln/world/k1/fill_1_from_2_faces.hh>
+
+# include <mln/world/k2/convert_on_access.hh>
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace kn
+ {
+
+ /*! \brief Immerse a 2D image into Kn.
+
+ \param[in] ima 2D Image in K0.
+ \param[in] n Set in which space to immerse \p ima (ex: n=1 => k1).
+ \param[in] new_type Value type of the immersed image.
+
+ \return A 2D image immersed in k\p n of value type \tparam V.
+
+ \verbatim
+
+ Example with n=1 :
+
+ -1 0 1 2 3
+ 0 1 -1 . - . - .
+ 0 o o 0 | o | o |
+ 1 o o -> 1 . - . - .
+ 2 | o | o |
+ 3 . - . - .
+
+ \endverbatim
+
+ */
+ template <typename I, typename V>
+ mln_ch_value(I, V)
+ immerse(const Image<I>& ima_, const unsigned n, const V& new_type);
+
+ /// \overload
+ template <typename I>
+ mln_concrete(I)
+ immerse(const Image<I>& ima, const unsigned n);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+
+ /// Return the equivalent point in Kn from a point in K0.
+ inline
+ point2d immerse_point(const point2d& p, const unsigned n)
+ {
+ point2d tmp(std::pow(2u, n) * p.row(), std::pow(2u, n) * p.col());
+ return tmp;
+ }
+
+ /// \brief Return the equivalent domain in Kn from a domain in
+ /// K0.
+ template <typename B>
+ inline
+ B domain_from_K0(const Box<B>& b_, const unsigned n)
+ {
+ mln_precondition(exact(b_).is_valid());
+ const B& b = exact(b_);
+
+ mln_deduce(B, site, delta) one;
+ one.set_all(1);
+ return B(immerse_point(b.pmin(), n) - one, immerse_point(b.pmax(), n) + one);
+ }
+
+ } // end of namespace mln::world::kn::internal
+
+
+
+ // Facade
+
+ template <typename I, typename V>
+ mln_ch_value(I, V)
+ immerse(const Image<I>& ima_, const unsigned n, const V& new_type)
+ {
+ trace::entering("mln::world::kn::immerse_with");
+ mln_precondition(exact(ima_).is_valid());
+ const I& ima = exact(ima_);
+ (void) new_type;
+
+ mln_ch_value(I,V)
+ output(internal::domain_from_K0(ima.domain(), n));
+
+ // Filling Primary 2-Faces
+ mln_piter(I) p(ima.domain());
+ for_all(p)
+ {
+ V tmp;
+ k2::convert_on_access(ima(p), tmp);
+ output(internal::immerse_point(p, n)) = tmp;
+ }
+
+ trace::exiting("mln::world::kn::immerse_with");
+ return output;
+ }
+
+ template <typename I>
+ mln_concrete(I)
+ immerse(const Image<I>& ima, const unsigned n)
+ {
+ typedef mln_value(I) V;
+ return immerse(ima, n, V());
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::world::kn
+
+ } // end of namespace mln::world
+
+} // end of namespace mln
+
+#endif // ! MLN_WORLD_Kn_IMMERSE_HH
--
1.7.2.5