https://svn.lrde.epita.fr/svn/oln/trunk/metalic
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Add some documentation and types to Metalic.
* mlc/cmp.hh: More documentation.
(is_found, is_not_found, is_ok): New.
* mlc/implies.hh, mlc/is_a.hh: Fix Doxygen comment.
* mlc/flags.hh: More documentation.
(dummy, locked): New.
From Thierry G�raud.
* mlc/value.hh: Remove dead code.
cmp.hh | 35 ++++++++++++--
flags.hh | 149 +++++++++++++++++++++++++++++++++++++++++++++++++++----------
implies.hh | 4 -
is_a.hh | 4 -
value.hh | 19 -------
5 files changed, 162 insertions(+), 49 deletions(-)
Index: mlc/implies.hh
--- mlc/implies.hh (revision 398)
+++ mlc/implies.hh (working copy)
@@ -31,9 +31,9 @@
# include <mlc/bool.hh>
-/*! \macro mlc_implies(Left_BExpr, Right_BExpr)
+/*! \def mlc_implies(Left_BExpr, Right_BExpr)
**
-** Macro correponding to mlc::implies_<L, R>, for use in a template
+** Macro corresponding to mlc::implies_<L, R>, for use in a template
** context.
**
** \see mlc::implies_<L, R>
Index: mlc/is_a.hh
--- mlc/is_a.hh (revision 398)
+++ mlc/is_a.hh (working copy)
@@ -205,7 +205,7 @@
-/*! \macro mlc_is_a(T, U)
+/*! \def mlc_is_a(T, U)
**
** Macro that answers if T is an U. T should be a type and U can have
** different forms: class, template class, etc. The result is a
@@ -240,7 +240,7 @@
mlc::wrap_<typename mlc::internal::is_a<sizeof(mlc::form::of<U >())>::ret<T,U > >
-/*! \macro mlc_is_a_(T, U)
+/*! \def mlc_is_a_(T, U)
**
** Macro equivalent as mlc_is_a(T, U) for use in a non templated
** context. The result is a Boolean expression type.
Index: mlc/flags.hh
--- mlc/flags.hh (revision 398)
+++ mlc/flags.hh (working copy)
@@ -38,9 +38,15 @@
/*! \class mlc::abstract::flag
**
- ** Abstract base class for types that are only flags.
+ ** Abstract base class for types that are flags. A flag type
+ ** expresses a particular property translated by the name of the
+ ** type. For instance, mlc::undefined is a flag type which
+ ** means "declared but not defined".
**
- ** Example: mlc::undefined is a mlc::abstract::flag.
+ ** Flag types have no interface; they only serve as types.
+ **
+ ** The flags provided in mlc are: dummy, locked, none, not_found,
+ ** undefined, and unknown.
*/
struct flag : public type {};
@@ -48,37 +54,91 @@
} // end of namespace mlc::abstract
- /*! \class mlc::undefined
+ /*! \class mlc::dummy
**
- ** Flag class to state that a type is undefined, that is, declared
- ** but not defined.
+ ** Flag class to value a type when one knows that this value does
+ ** not matter and will not be used.
**
- ** Sample use: you want to define a trait to get the signed version
- ** of a type T. For that, you write:
+ ** The dummy type appears typically in some part of meta-program
+ ** that are ignored. In mlc_typedef_onlyif, for instance, dummy is
+ ** returned when the guard value is false. When defining a
+ ** pattern matching meta-program, if a clause is not a match, the
+ ** returned type for this clause is evaluated into dummy.
+ */
+ struct dummy : public abstract::flag {};
+
+
+ /*! \class mlc::locked
+ **
+ ** Flag class whose purpose is to state and ensure that a type
+ ** should not be re-defined (or specialized) by the client.
+ **
+ ** Let us consider a type that should not be re-defined or
+ ** specialized by the client. Such a type is defined having
+ ** mlc::locked as base class. Inserting the static check
+ ** mlc_is_a(type, locked) then ensures that this type is untouched.
+ **
+ ** Sample use: First a type (set_foo) is declared for the user to
+ ** specialize it:
+ **
+ ** template <typename T> struct set_foo;
+ **
+ ** and the access to this specialization (handled by the type
+ ** get_foo), for use in a meta-program, is written once for all.
+ ** The access code should not be re-defined by the client so it is
+ ** tagged as locked:
**
** template <typename T>
- ** struct signed_type_of
- ** {
- ** typedef mlc::undefined ret;
+ ** struct get_foo : public mlc::locked,
+ ** public set_foo<T> {
+ ** using set_foo<T>::ret;
** };
**
- ** which means that the return type (ret) is not defined by default.
- ** Put differently, this trait is just declared. So far, the
- ** type "signed_type_of<unsigned short>::ret" is "mlc::undefined".
- **
- ** Other flags are mlc::unknown, mlc::none, and mlc::not_found.
+ ** The meta-program that reads the value of get_foo<T>::ret also
+ ** checks that get_foo<T> derives from mlc::locked. That thus
+ ** ensures that the client has not confuse set_foo with get_foo.
*/
- struct undefined : public abstract::flag {};
+ struct locked : public abstract::flag {};
- struct unknown : public abstract::flag {};
+ /*! \class mlc::none
+ **
+ ** Flag class to state that there is no type corresponding to a
+ ** request.
+ **
+ ** Sample use 1: In the context of a variadic parameter list, none
+ ** is the default value for every parameter after the first one.
+ **
+ ** With:
+ ** template <typename P1,
+ ** typename P2 = none,
+ ** typename P3 = none>
+ ** struct foo {
+ ** typedef P1 param1;
+ ** typedef P2 param2;
+ ** typedef P3 param3;
+ ** };
+ **
+ ** instantiated into foo<int, float>, we thus have param3 set to
+ ** none.
+ **
+ ** Sample use 2: The type none can be used as a trait value. For
+ ** instance:
+ **
+ ** template<>
+ ** struct super_type_of <int> {
+ ** typedef none ret;
+ ** };
+ */
struct none : public abstract::flag {};
/*! \class mlc::not_found
**
- ** Flag class to state that a type is not found (for use in the
- ** context of trying to retrieve a type).
+ ** Flag class to state that a type is not found. This class is for
+ ** use in the context of trying to retrieve a type. More precisely,
+ ** this flag type should only appear as a return of a piece of
+ ** meta-program.
**
** Design issue: this flag is used in some meta-code to handle the
** case of an "absent" typedef. For instance it is used in the
@@ -86,14 +146,59 @@
** mlc_typedef(std::vector<int>, value_type) is int, whereas
** mlc_typedef(std::vector<int>, walue_type) is mlc::not_found.
**
- ** Other flags are mlc::undefined, mlc::unknown, and mlc::none.
- **
** \see mlc_typedef
*/
struct not_found : public abstract::flag {};
- // FIXME: add corresponding is_* types
+ /*! \class mlc::undefined
+ **
+ ** Flag class to state that a type is undefined, that is, declared
+ ** but not defined.
+ **
+ ** Sample use: When you want to define a trait to get the signed
+ ** version of a type T, you write:
+ **
+ ** template <typename T>
+ ** struct signed_type_of
+ ** {
+ ** typedef mlc::undefined ret;
+ ** };
+ **
+ ** meaning that the return type (ret) is not defined by default.
+ ** Put differently, this trait is just declared. So far, the trait
+ ** value signed_type_of<unsigned short>::ret is mlc::undefined. If
+ ** it happens that this trait value is not specialized in some
+ ** following code, this value thus remains mlc::undefined, which
+ ** clearly denotes an error.
+ **
+ ** \see mlc::abstract::flag.
+ */
+ struct undefined : public abstract::flag {};
+
+
+ /*! \class mlc::unknown
+ **
+ ** Flag class to state that a result is yet unknown.
+ **
+ ** Sample use: This flag can be used in a meta-program to express
+ ** that a sub-program fails to give the expected result. For
+ ** instance in:
+ **
+ ** template <class T>
+ ** struct foo {
+ ** typedef sub_program_1 ret1;
+ ** typedef sub_program_2 ret2;
+ ** typedef typename if_< neq_<ret1, unknown>,
+ ** ret1,
+ ** ret2 >::ret ret;
+ ** };
+ */
+ struct unknown : public abstract::flag {};
+
+
+ // FIXME: Doc.
+ struct not_ok : public abstract::flag {};
} // end of namespace mlc
Index: mlc/value.hh
--- mlc/value.hh (revision 398)
+++ mlc/value.hh (working copy)
@@ -164,23 +164,4 @@
# include <mlc/bool.hh>
-// FIXME: the following code causes inclusion recursion...
-
-// # include <mlc/is_a.hh>
-
-// namespace mlc {
-
-// template <typename T>
-// struct is_value : public mlc_is_a(T, mlc::abstract::value)
-// {
-// };
-
-// template <typename T>
-// struct is_not_value : public not_<mlc_is_a(T, mlc::abstract::value)>
-// {
-// };
-
-// } // end of namespace mlc
-
-
#endif // ! METALIC_VALUE_HH
Index: mlc/cmp.hh
--- mlc/cmp.hh (revision 398)
+++ mlc/cmp.hh (working copy)
@@ -39,13 +39,14 @@
namespace mlc
{
- // FIXME: code moved from the end of value.hh
+ /// Check whether \a T is a mlc::abstract::value.
template <typename T>
struct is_value : public mlc_is_a(T, mlc::abstract::value)
{
};
+ /// Check whether \a T is not a mlc::abstract::value.
template <typename T>
struct is_not_value : public not_<mlc_is_a(T, mlc::abstract::value)>
{
@@ -54,7 +55,7 @@
/// Equality test between a couple of types.
-
+ /// \{
template <typename T1, typename T2>
struct eq_ : private ensure_list_< is_not_value<T1>,
is_not_value<T2> >,
@@ -67,10 +68,10 @@
public true_
{
};
-
+ /// \}
/// Inequality test between a couple of types.
-
+ /// \{
template <typename T1, typename T2>
struct neq_ : private ensure_list_< is_not_value<T1>,
is_not_value<T2> >,
@@ -83,7 +84,33 @@
public false_
{
};
+ /// \}
+
+
+ /*--------------------------------------.
+ | Syntactic sugar for flag comparison. |
+ `--------------------------------------*/
+
+ /// Shortcuts for comparison with mlc::not_found.
+ /// \{
+ template <typename T>
+ struct is_found : public neq_<T, not_found>
+ {
+ };
+
+ template <typename T>
+ struct is_not_found : public neq_<T, not_found>
+ {
+ };
+ /// \}
+
+ /// Check whether a type is a sound (supposedly before using it).
+ struct is_ok : public ands_< neq_<T, not_found>,
+ neq_<T, not_ok>,
+ neq_<T, undefined > >
+ {
+ };
} // end of namespace mlc
https://svn/svn/oln/prototypes/proto-1.0/olena
Index: ChangeLog
from Nicolas Widynski <nicolas.widynski(a)lrde.epita.fr>
Util function : set outsides boundaries at the same value of image boundaries.
* oln/utils/clean_boundaries.hh: New. To clean image boundaries.
clean_boundaries.hh | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 79 insertions(+)
Index: oln/utils/clean_boundaries.hh
--- oln/utils/clean_boundaries.hh (revision 0)
+++ oln/utils/clean_boundaries.hh (revision 0)
@@ -0,0 +1,79 @@
+// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 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, 59 Temple Place - Suite 330, 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 OLN_UTILS_CLEAN_BOUNDARIES_HH
+# define OLN_UTILS_CLEAN_BOUNDARIES_HH
+
+# include <oln/core/abstract/image.hh>
+# include <oln/core/1d/image1d.hh>
+# include <oln/core/2d/image2d.hh>
+
+namespace oln {
+
+ namespace utils {
+
+ namespace impl {
+
+ template <typename T>
+ void clean_boundaries_(image1d<T>& ima)
+ {
+ ima(-1) = ima(0);
+ ima(ima.size().nindices()) = ima(ima.size().nindices() - 1);
+ }
+
+ template <typename T>
+ void clean_boundaries_(image2d<T>& ima)
+ {
+ for (int j = 0; j < ima.size().ncols(); j++)
+ {
+ ima(-1, j) = ima(0, j);
+ ima(ima.size().nrows(), j) = ima(ima.size().nrows() - 1, j);
+ }
+ for (int j = 0; j < ima.size().nrows(); j++)
+ {
+ ima(j, -1) = ima(j, 0);
+ ima(j, ima.size().ncols()) = ima(j, ima.size().ncols() - 1);
+ }
+ }
+
+
+ } // end of namespace oln::utils::impl
+
+
+ // set outsides boundaries of the image at the boundary value.
+ template <typename I>
+ void clean_boundaries(abstract::image<I>& input)
+ {
+ if (input.size().border() != 0)
+ impl::clean_boundaries_(input.exact());
+ }
+
+ } // end of namespace oln::utils
+
+} // end of namespace oln
+
+#endif // ! OLN_UTILS_CLEAN_BOUNDARIES_HH
https://svn.lrde.epita.fr/svn/oln/trunk/metalic
Index: ChangeLog
from Thierry Geraud <theo(a)lrde.epita.fr>
Add implies, comma, typedef ret handling; then update.
* mlc/implies.hh: New file.
* mlc/is_a.hh: Update.
* mlc/comma.hh: New file.
* mlc/typedef.hh (in_, in_onlyif_): Rename as...
(from_, from_only_if_): ...this.
(mlc_typedef_in, mlc_typedef_in_): New macros.
(mlc_ret): New macro.
comma.hh | 39 +++++++++++++++++++++++++++++++++
implies.hh | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
is_a.hh | 4 +--
typedef.hh | 41 +++++++++++++++++++++++++++--------
4 files changed, 144 insertions(+), 11 deletions(-)
Index: mlc/implies.hh
--- mlc/implies.hh (revision 0)
+++ mlc/implies.hh (revision 0)
@@ -0,0 +1,71 @@
+// Copyright (C) 2005, 2006 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, 59 Temple Place - Suite 330, 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 METALIC_IMPLIES_HH
+# define METALIC_IMPLIES_HH
+
+# include <mlc/bool.hh>
+
+
+/*! \macro mlc_implies(Left_BExpr, Right_BExpr)
+**
+** Macro correponding to mlc::implies_<L, R>, for use in a template
+** context.
+**
+** \see mlc::implies_<L, R>
+*/
+
+# define mlc_implies(Left_BExpr, Right_BExpr) \
+ typename mlc::implies_<Left_BExpr, Right_BExpr>::ret
+
+# define mlc_implies_(Left_BExpr, Right_BExpr) \
+ mlc::implies_<Left_BExpr, Right_BExpr>::ret
+
+
+namespace mlc
+{
+
+ /*! \class mlc::implies_<L, R>
+ **
+ ** Logical implication "L => R" with L and R being Boolean
+ ** expression types. This class is also a Boolean expression type.
+ **
+ ** Sample use:
+ ** mlc::implies_< mlc_is_builtin(T), mlc_eq(T, int) >::ensure();
+ ** which means "if T is a buit-in type, it has to be int".
+ */
+
+ template <typename L, typename R>
+ struct implies_
+ : public bool_<( !mlc_bool(L) || mlc_bool(R) )>
+ {};
+
+} // end of namespace mlc
+
+
+
+#endif // ! METALIC_IMPLIES_HH
Index: mlc/is_a.hh
--- mlc/is_a.hh (revision 393)
+++ mlc/is_a.hh (working copy)
@@ -237,7 +237,7 @@
*/
# define mlc_is_a(T, U) \
-mlc::wrap<typename mlc::internal::is_a<sizeof(mlc::form::of<U >())>::ret<T,U > >
+mlc::wrap_<typename mlc::internal::is_a<sizeof(mlc::form::of<U >())>::ret<T,U > >
/*! \macro mlc_is_a_(T, U)
@@ -249,7 +249,7 @@
*/
# define mlc_is_a_(T, U) \
-mlc::wrap<mlc::internal::is_a< sizeof(mlc::form::of<U >())>::ret<T,U > >
+mlc::wrap_<mlc::internal::is_a< sizeof(mlc::form::of<U >())>::ret<T,U > >
#endif // ! METALIC_IS_A_HH
Index: mlc/comma.hh
--- mlc/comma.hh (revision 0)
+++ mlc/comma.hh (revision 0)
@@ -0,0 +1,39 @@
+// Copyright (C) 2006 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, 59 Temple Place - Suite 330, 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 METALIC_COMMA_HH
+# define METALIC_COMMA_HH
+
+
+// FIXME: doc
+
+# define mlc_comma_1(a, b) a, b
+# define mlc_comma_2(a, b, c) a, b, c
+# define mlc_comma_3(a, b, c, d) a, b, c, d
+
+
+#endif // ! METALIC_COMMA_HH
Index: mlc/typedef.hh
--- mlc/typedef.hh (revision 393)
+++ mlc/typedef.hh (working copy)
@@ -169,7 +169,7 @@
struct TypedefName \
{ \
template <class T> \
- struct in_ \
+ struct from_ \
{ \
private: \
typedef internal::TypedefName helper_; \
@@ -184,17 +184,17 @@
}; \
\
template <class T, bool b> \
- struct in_onlyif_; \
+ struct from_onlyif_; \
\
\
template <class T> \
- struct in_onlyif_ <T, true> \
+ struct from_onlyif_ <T, true> \
{ \
- typedef typename in_<T>::ret ret; \
+ typedef typename from_<T>::ret ret; \
}; \
\
template <class T> \
- struct in_onlyif_ <T, false> \
+ struct from_onlyif_ <T, false> \
{ \
typedef mlc::dummy ret; \
}; \
@@ -214,13 +214,25 @@
*/
#define mlc_typedef(Type, TypedefName) \
- typename typedef_::TypedefName::in_<Type>::ret
+ typename typedef_::TypedefName::from_<Type>::ret
#define mlc_typedef_(Type, TypedefName) \
- typedef_::TypedefName::in_<Type>::ret
+ typedef_::TypedefName::from_<Type>::ret
+/*! \macro mlc_typedef_in(Namespace, Type, TypedefName)
+**
+** FIXME: doc
+*/
+
+# define mlc_typedef_in(Namespace, Type, TypedefName) \
+ typename Namespace::typedef_::TypedefName::from_<Type>::ret
+
+# define mlc_typedef_in_(Namespace, Type, TypedefName) \
+ Namespace::typedef_::TypedefName::from_<Type>::ret
+
+
/*! \macro mlc_typedef_onlyif(Type, TypedefName, Bexpr)
**
@@ -228,11 +240,22 @@
*/
#define mlc_typedef_onlyif(Type, TypedefName, Bexpr) \
- typename typedef_::TypedefName::in_onlyif_<Type, mlc_bool(Bexpr)>::ret
+ typename typedef_::TypedefName::from_onlyif_<Type, mlc_bool(Bexpr)>::ret
#define mlc_typedef_onlyif_(Type, TypedefName, Bexpr) \
- typedef_::TypedefName::in_onlyif_<Type, mlc_bool(Bexpr)>::ret
+ typedef_::TypedefName::from_onlyif_<Type, mlc_bool(Bexpr)>::ret
+
+
+
+/*! \FIXME: what's the correct comment flag here?
+**
+** Since we often rely on having a typedef named "ret" in types, we offer
+** a default equipment for this particular typedef. FIXME: doc
+*/
+
+mlc_decl_typedef(ret);
+# define mlc_ret(Type) typename typedef_::ret::from_<Type>::ret
This implementation is not generic but shows difficulties with the use
of point and dpoint.
For details, please see the topic in lrde.olena (coming soon :)) about
the arguing of points and dpoints in Olena.
--
Widynski Nicolas
Promo 2007
https://svn/svn/oln/prototypes/proto-1.0/olena
Index: ChangeLog
from Nicolas Widynski <nicolas.widynski(a)lrde.epita.fr>
Implementation of a denoising image processing algorithm : Non Local Means.
* oln/appli/denoising/nl_means.hh: New. NL-means algorithm.
* oln/makefile.src: Update for laplacian convolution and NL-means algorithm.
appli/denoising/nl_means.hh | 141 ++++++++++++++++++++++++++++++++++++++++++++
makefile.src | 4 +
2 files changed, 145 insertions(+)
Index: oln/appli/denoising/nl_means.hh
--- oln/appli/denoising/nl_means.hh (revision 0)
+++ oln/appli/denoising/nl_means.hh (revision 0)
@@ -0,0 +1,141 @@
+// Copyright (C) 2001, 2002, 2004, 2005, 2006 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, 59 Temple Place - Suite 330, 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 OLENA_DENOISING_NLMEANS_HH
+# define OLENA_DENOISING_NLMEANS_HH
+
+# define SQR(u) u*u
+# define PI 3.141592653589793238462643
+
+# include <cmath>
+# include <oln/level/fill.hh>
+
+namespace oln {
+
+ namespace denoising {
+
+ namespace impl {
+
+
+ template<typename I>
+ const oln_type_of(I, concrete) gaussian_mask(double variance,
+ int rows,
+ int cols)
+ {
+ oln_type_of(I, concrete) g_m(rows, cols, 0);
+
+ int i, j;
+
+ for (i = 0; i < rows; i++)
+ for (j = 0; j < cols; j++)
+ g_m(i,j) = (1 / 2 * PI * SQR(variance)) * exp(-(SQR(rows / 2 - i) + SQR(cols / 2 - j)));
+
+ return g_m;
+ }
+
+
+ template<typename I>
+ oln_type_of(I, concrete) nl_means_(const oln::abstract::image<I>& input,
+ int window,
+ double variance,
+ int horizon)
+ {
+ oln_type_of(I, concrete) nl(input.size(), "nl_means");
+ oln_type_of(I, concrete) g_m;
+ oln_type_of(I, fwd_piter) p(input.size());
+ oln_type_of(I, point) pt1;
+ oln_type_of(I, point) pt2;
+
+ int i, j, k, l, i2, j2, k2, l2;
+ double dist;
+ double w;
+ double Z;
+ double val;
+
+
+ level::fill(nl, 0);
+
+ g_m = gaussian_mask<I>(variance, window, window);
+
+ for (i = 0; i < input.size().ncols(); i++)
+ {
+ for (j = 0; j < input.size().nrows(); j++)
+ {
+ Z = 0;
+ val = 0;
+
+ for (k = i - horizon; k < i + horizon; k++)
+ for (l = j - horizon; l < j + horizon; l++)
+ {
+ if (not (k >= 0 and k < (int)input.size().ncols() and l >= 0 and l < (int)input.size().nrows()))
+ continue;
+
+ dist = 0;
+ w = 0;
+
+ for (k2 = k - window / 2, i2 = i - window / 2; k2 < (k + window / 2 + window % 2); k2++, i2++)
+ for (l2 = l - window / 2, j2 = j - window / 2; l2 < (l + window / 2 + window % 2); l2++, j2++)
+
+ if (i2 >= 0 and i2 < input.size().ncols() && j2 >= 0 and j2 < input.size().nrows() and
+ k2 >= 0 and k2 < input.size().ncols() && l2 >= 0 and l2 < input.size().nrows())
+ {
+ dist += g_m.exact()(k2 + window / 2 - k, l2 + window / 2 - l) *
+ ((input.exact()(i2, j2) - input.exact()(k2, l2)) *
+ (input.exact()(i2, j2) - input.exact()(k2, l2)));
+ }
+
+ w = exp(-dist/(SQR(variance)));
+ val += w * input.exact()(k, l).value();
+ Z += w;
+ }
+
+ nl(i,j) = val / Z;
+ }
+
+ std::cout << (int)input.size().nrows() << " / " << i + 1 << std::endl;
+ }
+
+ return nl;
+ }
+
+ } // end of namespace oln::denoising::impl
+
+ template<typename I>
+ oln_type_of(I, concrete) nl_means(const oln::abstract::image<I>& input,
+ int window,
+ double variance,
+ int horizon)
+ {
+ return impl::nl_means_(input.exact(), window, variance, horizon);
+ }
+
+
+ } // end of namespace oln::denoising
+
+} // end of namespace oln
+
+#endif // OLENA_DENOISING_NLMEANS_HH
Index: oln/makefile.src
--- oln/makefile.src (revision 390)
+++ oln/makefile.src (working copy)
@@ -10,6 +10,8 @@
appli/astro/tree_coherence_check.hh \
appli/astro/tree_statistics.hh \
\
+ appli/denoising/nl_means.hh \
+ \
basics1d.hh \
basics2d.hh \
basics3d.hh \
@@ -30,6 +32,8 @@
convert/stretch.hh \
convert/value_to_point.hh \
\
+ convolution/laplacian.hh \
+ \
core/1d/array1d.hh \
core/1d/bkd_piter1d.hh \
core/1d/dpoint1d.hh \