https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Some renaming and add phantom border routines.
* mln/pw: New directory.
* mln/fun/var.hh: Rename as...
* mln/pw/var.hh: ...this.
* mln/fun/val.hh: Rename as...
* mln/pw/cst.hh: ...this.
* mln/fun/pw_value.hh: Renameas ...
* mln/pw/value.hh: ...this.
* mln/core/concept/image.hh: .
* mln/core/concept/iterator.hh: .
* tests/erosion.cc,
* tests/pw_value.cc,
* TODO: Update.
* mln/convert/to_window.hh: Fix doc.
* mln/border/resize.hh: New.
* mln/border/fill.hh: New.
* mln/border/all.hh: New.
* mln/border/duplicate.hh: New.
* mln/border/mirror.hh: New.
TODO | 15 -------
mln/border/all.hh | 54 ++++++++++++++++++++++++++++
mln/border/duplicate.hh | 75 +++++++++++++++++++++++++++++++++++++++
mln/border/fill.hh | 76 ++++++++++++++++++++++++++++++++++++++++
mln/border/mirror.hh | 75 +++++++++++++++++++++++++++++++++++++++
mln/border/resize.hh | 81 +++++++++++++++++++++++++++++++++++++++++++
mln/convert/to_window.hh | 2 -
mln/core/concept/image.hh | 4 ++
mln/core/concept/iterator.hh | 6 +++
mln/pw/cst.hh | 41 ++++++++++++---------
mln/pw/value.hh | 57 ++++++++++++------------------
mln/pw/var.hh | 28 +++++++-------
tests/erosion.cc | 10 ++---
tests/pw_value.cc | 6 +--
14 files changed, 442 insertions(+), 88 deletions(-)
Index: tests/erosion.cc
--- tests/erosion.cc (revision 1030)
+++ tests/erosion.cc (working copy)
@@ -40,8 +40,8 @@
#include <mln/level/fill.hh>
#include <mln/morpho/erosion.hh>
-#include <mln/fun/pw_value.hh>
-#include <mln/fun/val.hh>
+#include <mln/pw/value.hh>
+#include <mln/pw/cst.hh>
#include <mln/fun/ops.hh>
@@ -61,18 +61,16 @@
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));
+ level::fill(bin, pw::value(lena) > pw::cst(127));
morpho::erosion(bin, rec, out);
image2d_b<int_u8> test(lena.domain());
- image2d_b<int_u8>::piter p(lena.domain());
+ image2d_b<int_u8>::fwd_piter p(lena.domain());
for_all(p)
test(p) = out(p) ? 255 : 0;
io::save_pgm(test, "test.pgm");
}
- */
}
Index: tests/pw_value.cc
--- tests/pw_value.cc (revision 1030)
+++ tests/pw_value.cc (working copy)
@@ -31,9 +31,9 @@
*/
#include <mln/core/image2d_b.hh>
-#include <mln/fun/pw_value.hh>
#include <mln/fun/ops.hh>
-#include <mln/fun/val.hh>
+#include <mln/pw/value.hh>
+#include <mln/pw/cst.hh>
int main()
@@ -44,5 +44,5 @@
point2d p = make::point2d(1, 1);
ima(p) = 51;
- std::cout << (pw_value(ima) = val(51))(p) << std::endl;
+ mln_assertion( (pw::value(ima) = pw::cst(51))(p) = true );
}
Index: TODO
--- TODO (revision 1030)
+++ TODO (working copy)
@@ -31,12 +31,12 @@
* renaming
mlc into metal
-point-wise material: pw::value_of, pw::constant, and pw::variable
* clean-up
accu::histo and median: remove inheritance
+select_function in fun::internal::selector_p2? etc.
* processing routines
@@ -48,16 +48,3 @@
border::* and no-op versions if not fast image
arith::inplace_plus et al.
linear:: for convolutions
-
-
-svn mv genpoint.hh generalized_point.hh
-svn mv genpixel.hh generalized_pixel.hh
-svn mv psite.hh point_site.hh
-svn mv viter.hh value_iterator.hh
-svn mv piter.hh point_iterator.hh
-
-
-svn mv doc/genpoint.hh doc/generalized_point.hh
-svn mv doc/genpixel.hh doc/generalized_pixel.hh
-svn mv doc/viter.hh doc/value_iterator.hh
-svn mv doc/piter.hh doc/point_iterator.hh
Index: mln/convert/to_window.hh
--- mln/convert/to_window.hh (revision 1030)
+++ mln/convert/to_window.hh (working copy)
@@ -30,7 +30,7 @@
/*! \file mln/convert/to_window.hh
*
- * \brief Convertions to mln::Image.
+ * \brief Convertions to mln::Window.
*/
# include <mln/core/concept/neighborhood.hh>
Index: mln/pw/var.hh
--- mln/pw/var.hh (revision 0)
+++ mln/pw/var.hh (working copy)
@@ -25,10 +25,10 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_FUN_VAR_HH
-# define MLN_FUN_VAR_HH
+#ifndef MLN_PW_VAR_HH
+# define MLN_PW_VAR_HH
-/*! \file mln/fun/var.hh
+/*! \file mln/pw/var.hh
*
* \brief FIXME.
*/
@@ -41,31 +41,31 @@
// FIXME: Doc!
- namespace fun
+ namespace pw
{
template <typename V>
struct var_ : public Function_p2v< var_<V> >
{
typedef V result;
+
var_(const V& v);
+
template <typename P>
const V& operator()(const P&) const;
+
private:
const V& v_;
};
- } // end of namespace mln::fun
-
template <typename V>
- fun::var_<V> var(const V& v);
+ var_<V> var(const V& v);
# ifndef MLN_INCLUDE_ONLY
- namespace fun
- {
+ // pw::var_<V>
template <typename V>
var_<V>::var_(const V& v)
@@ -81,18 +81,20 @@
return v_;
}
- } // end of namespace mln::fun
+ // pw::var(v)
template <typename V>
- fun::var_<V> var(const V& v)
+ var_<V> var(const V& v)
{
- fun::var_<V> tmp(v);
+ var_<V> tmp(v);
return tmp;
}
# endif // ! MLN_INCLUDE_ONLY
+ } // end of namespace mln::pw
+
} // end of namespace mln
-#endif // ! MLN_FUN_VAR_HH
+#endif // ! MLN_PW_VAR_HH
Index: mln/pw/cst.hh
--- mln/pw/cst.hh (revision 0)
+++ mln/pw/cst.hh (working copy)
@@ -25,10 +25,10 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_FUN_VAL_HH
-# define MLN_FUN_VAL_HH
+#ifndef MLN_PW_CST_HH
+# define MLN_PW_CST_HH
-/*! \file mln/fun/val.hh
+/*! \file mln/pw/cst.hh
*
* \brief FIXME.
*/
@@ -39,35 +39,38 @@
namespace mln
{
- // FIXME: Doc!
-
- namespace fun
+ namespace pw
{
+ // FIXME: Doc!
+
template <typename T>
- struct val_ : public Function_p2v< val_<T> >
+ struct cst_ : public Function_p2v< cst_<T> >
{
typedef T result;
- val_(T t);
+
+ cst_(T t);
+
template <typename P>
T operator()(const P&) const;
+
private:
T t_;
};
- } // end of namespace mln::fun
+
+ // FIXME: Doc!
template <typename T>
- fun::val_<T> val(T t);
+ cst_<T> cst(T t);
# ifndef MLN_INCLUDE_ONLY
- namespace fun
- {
+ // pw::cst_<T>
template <typename T>
- val_<T>::val_(T t)
+ cst_<T>::cst_(T t)
: t_(t)
{
}
@@ -75,23 +78,25 @@
template <typename T>
template <typename P>
T
- val_<T>::operator()(const P&) const
+ cst_<T>::operator()(const P&) const
{
return t_;
}
- } // end of namespace mln::fun
+ // pw::cst(t)
template <typename T>
- fun::val_<T> val(T t)
+ cst_<T> cst(T t)
{
- fun::val_<T> tmp(t);
+ cst_<T> tmp(t);
return tmp;
}
# endif // ! MLN_INCLUDE_ONLY
+ } // end of namespace mln::pw
+
} // end of namespace mln
-#endif // ! MLN_FUN_VAL_HH
+#endif // ! MLN_PW_CST_HH
Index: mln/pw/value.hh
--- mln/pw/value.hh (revision 0)
+++ mln/pw/value.hh (working copy)
@@ -25,10 +25,10 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_FUN_PW_VALUE_HH
-# define MLN_FUN_PW_VALUE_HH
+#ifndef MLN_PW_VALUE_HH
+# define MLN_PW_VALUE_HH
-/*! \file mln/fun/pw_value.hh
+/*! \file mln/fun/pw/value.hh
*
* \brief FIXME.
*/
@@ -42,19 +42,7 @@
namespace mln
{
- // Fwd decl.
- namespace fun { template <typename I> struct pw_value; }
-
-
-
- // FIXME: Doc!
-
- template <typename I>
- fun::pw_value<I> pw_value(const Image<I>& ima);
-
-
-
- namespace fun
+ namespace pw
{
// FIXME: Move!
@@ -70,16 +58,16 @@
struct select_function_< value::binary_kind, E > : Function_p2b<E>
{};
- } // end of namespace mln::fun::internal
+ } // end of namespace mln::pw::internal
// FIXME: Doc!
template <typename I>
- struct pw_value : public internal::select_function_< mln_value_kind(I),
pw_value<I> >
+ struct value_ : public internal::select_function_< mln_value_kind(I),
value_<I> >
{
typedef mln_value(I) result;
- pw_value(const I& ima);
+ value_(const I& ima);
mln_rvalue(I) operator()(const mln_psite(I)& p) const;
protected:
const I& ima_;
@@ -87,44 +75,47 @@
+ // FIXME: Doc!
+
+ template <typename I>
+ value_<I> value(const Image<I>& ima);
+
+
+
# ifndef MLN_INCLUDE_ONLY
- // fun::pw_value<I>
+ // pw::value_<I>
template <typename I>
- pw_value<I>::pw_value(const I& ima)
+ value_<I>::value_(const I& ima)
: ima_(ima)
{
}
template <typename I>
mln_rvalue(I)
- pw_value<I>::operator()(const mln_psite(I)& p) const
+ value_<I>::operator()(const mln_psite(I)& p) const
{
mln_precondition(ima_.owns_(p));
return ima_(p);
}
-# endif // ! MLN_INCLUDE_ONLY
-
- } // end of namespace mln::fun
-
-# ifndef MLN_INCLUDE_ONLY
-
- // pw_value
+ // pw::value(ima)
template <typename I>
- fun::pw_value<I>
- pw_value(const Image<I>& ima)
+ value_<I>
+ value(const Image<I>& ima)
{
mln_precondition(exact(ima).has_data());
- fun::pw_value<I> tmp(exact(ima));
+ value_<I> tmp(exact(ima));
return tmp;
}
# endif // ! MLN_INCLUDE_ONLY
+ } // end of namespace mln::pw
+
} // end of namespace mln
-#endif // ! MLN_FUN_PW_VALUE_HH
+#endif // ! MLN_PW_VALUE_HH
Index: mln/core/concept/image.hh
--- mln/core/concept/image.hh (revision 1030)
+++ mln/core/concept/image.hh (working copy)
@@ -134,6 +134,10 @@
m6 = 0;
lvalue (E::*m7)(const psite& p) = & E::operator();
m7 = 0;
+
+ typedef mln_vset(E) vset;
+ const vset& (E::*m8)() const = & E::values;
+ m8 = 0;
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/core/concept/iterator.hh
--- mln/core/concept/iterator.hh (revision 1030)
+++ mln/core/concept/iterator.hh (working copy)
@@ -40,6 +40,12 @@
# define for_all(x) for(x.start(); x.is_valid(); x.next())
+/*! \brief Loop to browse all the elements targetted by the couples of
+ * iterators \p x1 and \p x2.
+ */
+# define for_all_2(x1, x2) for(x1.start(),x2.start(); x1.is_valid();
x1.next(),x2.next())
+
+
/*! \brief Loop to browse all the remaining elements targetted by the
* iterator \p x.
*/
Index: mln/border/resize.hh
--- mln/border/resize.hh (revision 0)
+++ mln/border/resize.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_BORDER_RESIZE_HH
+# define MLN_BORDER_RESIZE_HH
+
+/*! \file mln/border/resize.hh
+ *
+ * \brief FIXME.
+ */
+
+# include <mln/core/concept/image.hh>
+
+
+namespace mln
+{
+
+ namespace border
+ {
+
+ /*! Resize the virtual (outer) border of image \p ima to at least
+ * \p thickness.
+ *
+ * \param[in,out] ima The image whose border is to be resized.
+ * \param[in] thickness The expected minimum border size.
+ *
+ * \pre \p ima has to be initialized.
+ *
+ * \warning If the image border already has a size greater than \p
+ * thickness, this routine is a no-op.
+ *
+ * \todo Implement it.
+ */
+ template <typename I>
+ void resize(const Fast_Image<I>& ima, unsigned thickness);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename I>
+ void resize(const Fast_Image<I>& ima_, unsigned thickness)
+ {
+ const I& ima = exact(ima_);
+ mln_precondition(ima_.has_data());
+ if (ima.border() >= thickness)
+ return;
+ mln_invariant(0); // FIXME: NYI
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::border
+
+} // end of namespace mln
+
+
+#endif // ! MLN_BORDER_RESIZE_HH
Index: mln/border/fill.hh
--- mln/border/fill.hh (revision 0)
+++ mln/border/fill.hh (revision 0)
@@ -0,0 +1,76 @@
+// 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_BORDER_FILL_HH
+# define MLN_BORDER_FILL_HH
+
+/*! \file mln/border/fill.hh
+ *
+ * \brief FIXME.
+ */
+
+# include <mln/core/concept/image.hh>
+
+
+namespace mln
+{
+
+ namespace border
+ {
+
+ /*! Fill the virtual (outer) border of image \p ima with the
+ * single value \p v.
+ *
+ * \param[in,out] ima The image whose border is to be filled.
+ * \param[in] v The value to assign to all border pixels.
+ *
+ * \pre \p ima has to be initialized.
+ *
+ * \todo Implement it + optimize with memset if possible.
+ */
+ template <typename I>
+ void fill(const Fast_Image<I>& ima, const mln_value(I)& v);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename I>
+ void fill(const Fast_Image<I>& ima_, const mln_value(I)& v)
+ {
+ const I& ima = exact(ima_);
+ mln_precondition(ima_.has_data());
+ mln_invariant(0); // FIXME: NYI
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::border
+
+} // end of namespace mln
+
+
+#endif // ! MLN_BORDER_FILL_HH
Index: mln/border/all.hh
--- mln/border/all.hh (revision 0)
+++ mln/border/all.hh (revision 0)
@@ -0,0 +1,54 @@
+// 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_BORDER_ALL_HH
+# define MLN_BORDER_ALL_HH
+
+/*! \file mln/border/all.hh
+ *
+ * \brief File that includes all border-related routines.
+ */
+
+
+namespace mln
+{
+
+ /*! Namespace of routines related to image virtual (outer) border.
+ */
+ namespace border {}
+
+}
+
+
+# include <mln/border/duplicate.hh>
+# include <mln/border/fill.hh>
+# include <mln/border/mirror.hh>
+# include <mln/border/resize.hh>
+# include <mln/border/thickness.hh>
+
+
+#endif // ! MLN_BORDER_ALL_HH
Index: mln/border/duplicate.hh
--- mln/border/duplicate.hh (revision 0)
+++ mln/border/duplicate.hh (revision 0)
@@ -0,0 +1,75 @@
+// 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_BORDER_DUPLICATE_HH
+# define MLN_BORDER_DUPLICATE_HH
+
+/*! \file mln/border/duplicate.hh
+ *
+ * \brief FIXME.
+ */
+
+# include <mln/core/concept/image.hh>
+
+
+namespace mln
+{
+
+ namespace border
+ {
+
+ /*! Assign the virtual (outer) border of image \p ima with the
+ * dupplicate of the inner border of this image.
+ *
+ * \param[in,out] ima The image whose border is to be duplicated.
+ *
+ * \pre \p ima has to be initialized.
+ *
+ * \todo Implement it + optimize with memcpy if possible.
+ */
+ template <typename I>
+ void duplicate(const Fast_Image<I>& ima);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename I>
+ void duplicate(const Fast_Image<I>& ima_)
+ {
+ const I& ima = exact(ima_);
+ mln_precondition(ima_.has_data());
+ mln_invariant(0); // FIXME: NYI
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::border
+
+} // end of namespace mln
+
+
+#endif // ! MLN_BORDER_DUPLICATE_HH
Index: mln/border/mirror.hh
--- mln/border/mirror.hh (revision 0)
+++ mln/border/mirror.hh (revision 0)
@@ -0,0 +1,75 @@
+// 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_BORDER_MIRROR_HH
+# define MLN_BORDER_MIRROR_HH
+
+/*! \file mln/border/mirror.hh
+ *
+ * \brief FIXME.
+ */
+
+# include <mln/core/concept/image.hh>
+
+
+namespace mln
+{
+
+ namespace border
+ {
+
+ /*! Mirror the virtual (outer) border of image \p ima with the
+ * (inner) level contents of this image.
+ *
+ * \param[in,out] ima The image whose border is to be mirrored.
+ *
+ * \pre \p ima has to be initialized.
+ *
+ * \todo Implement it + optimize with memset if possible.
+ */
+ template <typename I>
+ void mirror(const Fast_Image<I>& ima);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename I>
+ void mirror(const Fast_Image<I>& ima_)
+ {
+ const I& ima = exact(ima_);
+ mln_precondition(ima_.has_data());
+ mln_invariant(0); // FIXME: NYI
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::border
+
+} // end of namespace mln
+
+
+#endif // ! MLN_BORDER_MIRROR_HH