https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Update the form of routines so that images are returned.
* mln/fun/ops.hh: Add traits.
(mln_decl_binary_expr_): Replace <opname> by <opname>_ when
it is a language keyword.
(mln_decl_unary_expr_): Likewise.
* mln/core/image_if_interval.hh: Update.
Use the "image foo(..)" form instead of "foo(.., output)";
Insert tracing calls to routines.
* tests/morpho_hit_or_miss.cc: .
* tests/labeling_level_fast.cc: .
* tests/arith_plus.cc: .
* tests/morpho_gradient.cc: .
* tests/window2d.cc: .
* tests/value_int_s.cc: .
* tests/morpho_thinning.cc: .
* tests/morpho_laplacian.cc: .
* tests/value_int_u8.cc: .
* tests/morpho_contrast.cc: .
* tests/pw_value.cc: .
* mln/core/concept/image.hh: .
* mln/core/clone.hh: .
* mln/arith/plus.hh: .
* mln/arith/min.hh: .
* mln/arith/revert.hh: .
* mln/arith/minus.hh: .
* mln/convert/to_image.hh: .
* mln/morpho/thickening.hh: .
* mln/morpho/plus.hh: .
* mln/morpho/min.hh: .
* mln/morpho/laplacian.hh: .
* mln/morpho/minus.hh: .
* mln/morpho/gradient.hh: .
* mln/morpho/contrast.hh: .
* mln/morpho/thick_miss.hh: .
* mln/morpho/closing.hh: .
* mln/morpho/top_hat.hh: .
* mln/morpho/complementation.hh: .
* mln/morpho/opening.hh: .
* mln/morpho/dilation.hh: .
* mln/morpho/thin_fit.hh: .
* mln/morpho/includes.hh: .
* mln/morpho/thinning.hh: .
* mln/morpho/hit_or_miss.hh: .
* mln/logical/and.hh: .
* mln/logical/and_not.hh: .
* mln/logical/or.hh: .
* mln/logical/not.hh: .
Misc.
* mln/value/builtin/ops.hh: Add versions for builtin OP= object.
* mln/value/cast.hh (cast_): Update using value::equiv.
* mln/trait/op/minus.hh (mln_trait_op_minus_twice): New.
* mln/fun/cast.hh: New.
* mln/fun/v2v/cast.hh: New.
* mln/fun/v2v/all.hh: Update.
* mln/arith/includes.hh: Update.
* img/picasso.pbm: New.
img/picasso.pbm | 0
mln/arith/includes.hh | 1
mln/arith/min.hh | 47 +++--
mln/arith/minus.hh | 344 ++++++++++++++++++++++++++++++++++++++----
mln/arith/plus.hh | 285 +++++++++++++++++++++++++++++-----
mln/arith/revert.hh | 43 +++--
mln/convert/to_image.hh | 2
mln/core/clone.hh | 4
mln/core/concept/image.hh | 2
mln/core/image_if_interval.hh | 2
mln/fun/cast.hh | 84 ++++++++++
mln/fun/ops.hh | 48 ++++-
mln/fun/v2v/all.hh | 1
mln/fun/v2v/cast.hh | 80 +++++++++
mln/fun/v2v/saturate.hh | 17 +-
mln/logical/and.hh | 44 +++--
mln/logical/and_not.hh | 44 +++--
mln/logical/not.hh | 35 ++--
mln/logical/or.hh | 46 +++--
mln/morpho/closing.hh | 25 +--
mln/morpho/complementation.hh | 66 +++++---
mln/morpho/contrast.hh | 31 +--
mln/morpho/dilation.hh | 18 ++
mln/morpho/gradient.hh | 83 ++++------
mln/morpho/hit_or_miss.hh | 270 +++++++++++++++++---------------
mln/morpho/includes.hh | 3
mln/morpho/laplacian.hh | 34 +++-
mln/morpho/min.hh | 58 ++++---
mln/morpho/minus.hh | 66 ++++----
mln/morpho/opening.hh | 25 +--
mln/morpho/plus.hh | 65 ++++---
mln/morpho/thick_miss.hh | 27 +--
mln/morpho/thickening.hh | 28 +--
mln/morpho/thin_fit.hh | 29 ++-
mln/morpho/thinning.hh | 43 ++---
mln/morpho/top_hat.hh | 82 ++++------
mln/trait/op/minus.hh | 1
mln/value/builtin/ops.hh | 84 ++++++++--
mln/value/cast.hh | 23 ++
tests/arith_plus.cc | 17 +-
tests/labeling_level_fast.cc | 10 -
tests/morpho_contrast.cc | 26 ---
tests/morpho_gradient.cc | 8
tests/morpho_hit_or_miss.cc | 16 +
tests/morpho_laplacian.cc | 5
tests/morpho_thinning.cc | 19 +-
tests/pw_value.cc | 6
tests/value_int_s.cc | 2
tests/value_int_u8.cc | 5
tests/window2d.cc | 2
50 files changed, 1609 insertions(+), 697 deletions(-)
Index: tests/morpho_hit_or_miss.cc
--- tests/morpho_hit_or_miss.cc (revision 1405)
+++ tests/morpho_hit_or_miss.cc (working copy)
@@ -38,8 +38,8 @@
#include <mln/geom/shift.hh>
#include <mln/set/diff.hh>
-#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
+#include <mln/io/pbm/load.hh>
+#include <mln/io/pbm/save.hh>
#include <mln/level/fill.hh>
#include <mln/level/stretch.hh>
@@ -75,11 +75,13 @@
border::thickness = 2;
- image2d<int_u8>
- pic = io::pgm::load("../img/picasso.pgm"),
- out(pic.domain());
+ image2d<bool>
+ pic = io::pbm::load("../img/picasso.pbm"),
+ out = morpho::hit_or_miss(pic, win_hit, win_miss);
+ io::pbm::save(out, "out.pbm");
- morpho::hit_or_miss(pic, win_hit, win_miss, out);
+ mln_postcondition(morpho::hit_or_miss(morpho::complementation(pic),
+ win_miss, win_hit) = out);
- io::pgm::save(out, "out.pgm");
+ // FIXME: Do not work if the input image is pgm!
}
Index: tests/labeling_level_fast.cc
--- tests/labeling_level_fast.cc (revision 1405)
+++ tests/labeling_level_fast.cc (working copy)
@@ -42,20 +42,20 @@
#include <mln/debug/iota.hh>
#include <mln/debug/println.hh>
+
int main()
{
using namespace mln;
using value::int_u8;
- unsigned border = 1;
-
- image2d<value::int_u8> i1(5, 5, border);
+ image2d<value::int_u8> i1(5, 5);
debug::iota(i1);
- i1[10] = i1[17] = i1[18] = i1[25] = i1[26] = i1[22] = i1[29] = 2;
+ i1(point2d(0, 2)) = i1(point2d(1, 2)) = i1(point2d(1, 3)) = i1(point2d(2, 3)) =
i1(point2d(2, 4)) = 2;
+ i1(point2d(2, 0)) = i1(point2d(3, 0)) = 2;
debug::println(i1);
unsigned n;
- image2d<value::int_u8> out(i1.domain(), border);
+ image2d<value::int_u8> out(i1.domain());
labeling::level(i1, 2, c4(), out, n);
std::cout << "n = " << n << std::endl;
Index: tests/arith_plus.cc
--- tests/arith_plus.cc (revision 1405)
+++ tests/arith_plus.cc (working copy)
@@ -37,6 +37,7 @@
#include <mln/arith/plus.hh>
#include <mln/arith/times.hh>
#include <mln/level/compare.hh>
+#include <mln/fun/v2v/cast.hh>
#include <mln/debug/iota.hh>
#include <mln/debug/println.hh>
@@ -47,6 +48,8 @@
{
using namespace mln;
+ // trace::quiet = false;
+
{
image2d<int> ref(3,3);
debug::iota(ref);
@@ -55,12 +58,16 @@
ima_i += ima_i;
mln_assertion(ima_i = 2 * ref);
-// debug::println(ima_i);
-// ima_i += 1;
-// debug::println(ima_i);
+ debug::println(ima_i);
+ ima_i += 1;
+ debug::println(ima_i);
+
+ image2d<float> ima_f(3,3);
+ debug::iota(ima_f);
+ debug::println(ima_i + ima_f);
-// debug::iota(ima_f);
-// debug::println(ima_i + ima_f);
+ point2d p(0, 0);
+ std::cout << arith::plus<float>(ima_i, ima_i)(p) / 5 << std::endl;
}
}
Index: tests/morpho_gradient.cc
--- tests/morpho_gradient.cc (revision 1405)
+++ tests/morpho_gradient.cc (working copy)
@@ -49,10 +49,8 @@
win::rectangle2d rect(5, 5);
border::thickness = 2;
- image2d<int_u8>
- lena = io::pgm::load("../img/tiny.pgm"),
- out(lena.domain());
+ image2d<int_u8> lena = io::pgm::load("../img/tiny.pgm");
- morpho::gradient(lena, rect, out);
- io::pgm::save(out, "out.pgm");
+ io::pgm::save( morpho::gradient(lena, rect),
+ "out.pgm" );
}
Index: tests/window2d.cc
--- tests/window2d.cc (revision 1405)
+++ tests/window2d.cc (working copy)
@@ -34,6 +34,7 @@
#include <mln/core/image2d.hh>
#include <mln/convert/to_image.hh>
#include <mln/debug/println.hh>
+#include <mln/logical/not.hh>
@@ -51,6 +52,7 @@
image2d<bool> ima = convert::to_image(w);
debug::println(ima);
+ debug::println(logical::not_(ima));
mln_assertion(w.delta() = 1);
}
Index: tests/value_int_s.cc
--- tests/value_int_s.cc (revision 1405)
+++ tests/value_int_s.cc (working copy)
@@ -31,6 +31,7 @@
*/
#include <mln/value/int_s.hh>
+#include <mln/value/int_u.hh>
int main()
@@ -47,5 +48,4 @@
mln_assertion(-i = -2);
mln_assertion(-3 * i = -6);
}
-
}
Index: tests/morpho_thinning.cc
--- tests/morpho_thinning.cc (revision 1405)
+++ tests/morpho_thinning.cc (working copy)
@@ -36,7 +36,9 @@
#include <mln/win/rectangle2d.hh>
#include <mln/core/window2d.hh>
+#include <mln/io/pbm/load.hh>
#include <mln/io/pgm/load.hh>
+#include <mln/io/pbm/save.hh>
#include <mln/io/pgm/save.hh>
#include <mln/morpho/thinning.hh>
@@ -59,11 +61,14 @@
border::thickness = 2;
- image2d<int_u8>
- pic = io::pgm::load("../img/picasso.pgm"),
- out(pic.domain());
-
- morpho::thinning(pic, win_fg, win_bg, out);
-
- io::pgm::save(out, "out.pgm");
+ {
+ image2d<bool> pic = io::pbm::load("../img/picasso.pbm");
+ io::pbm::save( morpho::thinning(pic, win_fg, win_bg),
+ "out.pbm" );
+ }
+// {
+// image2d<int_u8> pic = io::pgm::load("../img/picasso.pgm");
+// io::pgm::save( morpho::thinning(pic, win_fg, win_bg),
+// "out.pgm" );
+// }
}
Index: tests/morpho_laplacian.cc
--- tests/morpho_laplacian.cc (revision 1405)
+++ tests/morpho_laplacian.cc (working copy)
@@ -57,7 +57,6 @@
image2d<int> lap(lena.domain());
morpho::laplacian(lena, rect, lap);
- image2d< value::int_u_sat<8> > out(lena.domain());
- arith::plus_cst(lap, 128, out);
- io::pgm::save(out, "out.pgm");
+ io::pgm::save( arith::plus_cst< value::int_u_sat<8> >(lap, 128),
+ "out.pgm" );
}
Index: tests/value_int_u8.cc
--- tests/value_int_u8.cc (revision 1405)
+++ tests/value_int_u8.cc (working copy)
@@ -41,6 +41,11 @@
int_u8 i = 3, j;
+ {
+ int k = 0;
+ k += value::scalar(k);
+ }
+
// Assignment.
{
i = 51;
Index: tests/morpho_contrast.cc
--- tests/morpho_contrast.cc (revision 1405)
+++ tests/morpho_contrast.cc (working copy)
@@ -41,9 +41,6 @@
#include <mln/morpho/contrast.hh>
-#include <mln/level/fill.hh>
-#include <mln/level/saturate.hh>
-
int main()
{
@@ -53,27 +50,16 @@
win::rectangle2d rect(5, 5);
border::thickness = 2;
- image2d<int_u8>
- lena = io::pgm::load("../img/tiny.pgm"),
- out(lena.domain());
-
- image2d< value::int_s<10> >
- in(lena.domain()),
- tmp(lena.domain());
-
- level::fill(in, lena);
- morpho::contrast(in, rect, tmp);
-
- level::saturate(tmp, out);
+ image2d<int_u8> lena = io::pgm::load("../img/tiny.pgm");
+ image2d<int_u8> out = morpho::contrast(lena, rect);
io::pgm::save(out, "out.pgm");
{
// self-duality test:
- morpho::complementation_inplace(in);
- image2d< value::int_s<10> > tmp_(lena.domain());
- morpho::contrast(in, rect, tmp_);
- morpho::complementation_inplace(tmp_);
- mln_assertion(tmp_ = tmp);
+ image2d<int_u8> out_ = morpho::complementation( morpho::contrast(
morpho::complementation(lena),
+ rect )
+ );
+ mln_assertion(out_ = out);
}
}
Index: tests/pw_value.cc
--- tests/pw_value.cc (revision 1405)
+++ tests/pw_value.cc (working copy)
@@ -44,4 +44,10 @@
point2d p = make::point2d(1, 1);
ima(p) = 51;
mln_assertion( (pw::value(ima) = pw::cst(51))(p) = true );
+
+ {
+ image2d<float> imaf(3,3);
+ imaf(p) = 51;
+ mln_assertion(((pw::value(ima) + pw::value(imaf))(p) / 20) - 5.1 < 0.00001);
+ }
}
Index: mln/trait/op/minus.hh
--- mln/trait/op/minus.hh (revision 1405)
+++ mln/trait/op/minus.hh (working copy)
@@ -39,6 +39,7 @@
# define mln_trait_op_minus(L, R) typename mln::trait::op::minus< L , R >::ret
# define mln_trait_op_minus_(L, R) mln::trait::op::minus< L , R >::ret
+# define mln_trait_op_minus_twice(T) mln_trait_op_minus(T, T)
namespace mln
Index: mln/core/image_if_interval.hh
--- mln/core/image_if_interval.hh (revision 1405)
+++ mln/core/image_if_interval.hh (working copy)
@@ -39,7 +39,7 @@
# include <mln/value/interval.hh>
-# define F fun::and_p2b_expr_< \
+# define F fun::and__p2b_expr_< \
fun::geq_p2b_expr_< \
pw::value_<I>, \
pw::cst_<mln_value(I)> >, \
Index: mln/core/concept/image.hh
--- mln/core/concept/image.hh (revision 1405)
+++ mln/core/concept/image.hh (working copy)
@@ -183,12 +183,14 @@
template <typename I, typename J>
void initialize(Image<I>& target, const Image<J>& model)
{
+ trace::entering("core::initialize");
mln_precondition(! exact(target).has_data());
mln_precondition(exact(model).has_data());
init_(tag::image, exact(target), exact(model));
mln_postcondition(exact(target).has_data());
+ trace::exiting("core::initialize");
}
Index: mln/core/clone.hh
--- mln/core/clone.hh (revision 1405)
+++ mln/core/clone.hh (working copy)
@@ -58,9 +58,13 @@
mln_concrete(I) clone(const Image<I>& model)
{
// FIXME: Add a static check that mln_concrete(I) actually *is* concrete...
+ trace::entering("core::clone");
+
mln_concrete(I) tmp;
initialize(tmp, model);
level::fill(tmp, model);
+
+ trace::exiting("core::clone");
return tmp;
}
Index: mln/arith/plus.hh
--- mln/arith/plus.hh (revision 1405)
+++ mln/arith/plus.hh (working copy)
@@ -67,6 +67,7 @@
mln_trait_op_plus(L,R)
operator+(const Image<L>& lhs, const Image<R>& rhs);
+
template <typename L, typename R>
L&
operator+=(Image<L>& lhs, const Image<R>& rhs);
@@ -76,6 +77,7 @@
mln_trait_op_plus(I,S)
operator+(const Image<I>& ima, const value::Scalar<S>& s);
+
template <typename I, typename S>
I&
operator+=(Image<I>& ima, const value::Scalar<S>& s);
@@ -89,39 +91,111 @@
*
* \param[in] lhs First operand image.
* \param[in] rhs Second operand image.
- * \param[out] output The result image.
+ * \result The result image.
*
- * \pre \p output.domain = \p lhs.domain = \p rhs.domain
+ * \pre \p lhs.domain = \p rhs.domain
*/
- template <typename L, typename R, typename O>
- void plus(const Image<L>& lhs, const Image<R>& rhs,
Image<O>& output);
+ template <typename L, typename R>
+ mln_trait_op_plus(L, R)
+ plus(const Image<L>& lhs, const Image<R>& rhs);
- /*! Point-wise addition of the value \p val to image \p input.
+ /*! Point-wise addition of images \p lhs and \p rhs.
*
- * \param[in] input The image.
- * \param[in] val The value.
- * \param[out] output The result image.
+ * \param[in] lhs First operand image.
+ * \param[in] rhs Second operand image.
+ * \param[in] f Function.
+ * \result The result image.
+ *
+ * \pre \p lhs.domain = \p rhs.domain
+ */
+ template <typename L, typename R, typename F>
+ mln_ch_value(L, mln_result(F))
+ plus(const Image<L>& lhs, const Image<R>& rhs, const
Function_v2v<F>& f);
+
+
+ /*! Point-wise addition of images \p lhs and \p rhs.
*
- * \pre \p output.domain = \p input.domain
+ * \param[in] lhs First operand image.
+ * \param[in] rhs Second operand image.
+ * \result The result image.
+ *
+ * The free parameter \c V sets the destination value type.
+ *
+ * \pre \p lhs.domain = \p rhs.domain
*/
- template <typename I, typename V, typename O>
- void plus_cst(const Image<I>& input, const V& val, Image<O>&
output);
+ template <typename V, typename L, typename R>
+ mln_ch_value(L, V)
+ plus(const Image<L>& lhs, const Image<R>& rhs);
/*! Point-wise addition of image \p rhs in image \p lhs.
*
- * \param[in] lhs First operand image (subject to addition).
- * \param[in,out] rhs Second operand image (to be added to \p lhs).
+ * \param[in,out] lhs First operand image (subject to addition).
+ * \param[in] rhs Second operand image (to be added to \p lhs).
*
* This addition performs: \n
* for all p of rhs.domain \n
* lhs(p) += rhs(p)
*
- * \pre \p rhs.domain <= \p lhs.domain
+ * \pre \p rhs.domain = \p lhs.domain
*/
template <typename L, typename R>
- void plus_inplace(Image<L>& lhs, const Image<R>& rhs);
+ void
+ plus_inplace(Image<L>& lhs, const Image<R>& rhs);
+
+
+ /*! Point-wise addition of the value \p val to image \p input.
+ *
+ * \param[in] input The image.
+ * \param[in] val The value.
+ * \result The result image.
+ *
+ * \pre \p input.has_data
+ */
+ template <typename I, typename V>
+ mln_trait_op_plus(I, V)
+ plus_cst(const Image<I>& input, const V& val);
+
+
+ /*! Point-wise addition of the value \p val to image \p input.
+ *
+ * \param[in] input The image.
+ * \param[in] val The value.
+ * \param[in] f Function.
+ * \result The result image.
+ *
+ * \pre \p input.has_data
+ */
+ template <typename I, typename V, typename F>
+ mln_ch_value(I, mln_result(F))
+ plus_cst(const Image<I>& input, const V& val, const
Function_v2v<F>& f);
+
+
+ /*! Point-wise addition of the value \p val to image \p input.
+ *
+ * \param[in] input The image.
+ * \param[in] val The value.
+ * \param[in] f Function.
+ * \result The result image.
+ *
+ * \pre \p input.has_data
+ */
+ template <typename W, typename I, typename V>
+ mln_ch_value(I, W)
+ plus_cst(const Image<I>& input, const V& val);
+
+
+ /*! Point-wise addition of the value \p val to image \p input.
+ *
+ * \param[in,out] input The image.
+ * \param[in] val The value.
+ *
+ * \pre \p input.has_data
+ */
+ template <typename I, typename V>
+ I&
+ plus_cst_inplace(Image<I>& input, const V& val);
} // end of namespace mln::arith
@@ -136,19 +210,25 @@
mln_trait_op_plus(L,R)
operator+(const Image<L>& lhs, const Image<R>& rhs)
{
+ trace::entering("operator::plus");
mln_precondition(exact(rhs).domain() = exact(lhs).domain());
- mln_trait_op_plus(L,R) tmp;
- initialize(tmp, lhs);
- arith::plus(lhs, rhs, tmp);
- return tmp;
+
+ mln_trait_op_plus(L,R) output = arith::plus(lhs, rhs);
+
+ trace::exiting("operator::plus");
+ return output;
}
template <typename L, typename R>
L&
operator+=(Image<L>& lhs, const Image<R>& rhs)
{
+ trace::entering("operator::plus_eq");
mln_precondition(exact(rhs).domain() = exact(lhs).domain());
+
arith::plus_inplace(lhs, rhs);
+
+ trace::exiting("operator::plus_eq");
return exact(lhs);
}
@@ -157,19 +237,25 @@
mln_trait_op_plus(I,S)
operator+(const Image<I>& ima, const value::Scalar<S>& s)
{
+ trace::entering("operator::plus");
mln_precondition(exact(ima).has_data());
- mln_trait_op_plus(I,S) tmp;
- initialize(tmp, ima);
- arith::plus_cst(ima, exact(s), tmp);
- return tmp;
+
+ mln_trait_op_plus(I,S) output = arith::plus_cst(ima, exact(s));
+
+ trace::exiting("operator::plus");
+ return output;
}
template <typename I, typename S>
I&
operator+=(Image<I>& ima, const value::Scalar<S>& s)
{
+ trace::entering("operator::plus_eq");
mln_precondition(exact(ima).has_data());
- arith::plus_cst(ima, exact(s), ima);
+
+ arith::plus_cst_inplace(ima, exact(s));
+
+ trace::exiting("operator::plus_eq");
return exact(ima);
}
@@ -183,18 +269,25 @@
template <typename L, typename R, typename O>
void plus_(trait::image::speed::any, const L& lhs,
- trait::image::speed::any, const R& rhs,
- trait::image::speed::any, O& output)
+ trait::image::speed::any, const R& rhs, O& output)
{
mln_piter(L) p(lhs.domain());
for_all(p)
output(p) = lhs(p) + rhs(p);
}
+ template <typename L, typename R, typename F, typename O>
+ void plus_(trait::image::speed::any, const L& lhs,
+ trait::image::speed::any, const R& rhs, const F& f, O& output)
+ {
+ mln_piter(L) p(lhs.domain());
+ for_all(p)
+ output(p) = f(lhs(p) + rhs(p));
+ }
+
template <typename L, typename R, typename O>
void plus_(trait::image::speed::fastest, const L& lhs,
- trait::image::speed::fastest, const R& rhs,
- trait::image::speed::fastest, O& output)
+ trait::image::speed::fastest, const R& rhs, O& output)
{
mln_pixter(const L) lp(lhs);
mln_pixter(const R) rp(rhs);
@@ -203,11 +296,22 @@
op.val() = lp.val() + rp.val();
}
+ template <typename L, typename R, typename F, typename O>
+ void plus_(trait::image::speed::fastest, const L& lhs,
+ trait::image::speed::fastest, const R& rhs, const F& f, O& output)
+ {
+ mln_pixter(const L) lp(lhs);
+ mln_pixter(const R) rp(rhs);
+ mln_pixter(O) op(output);
+ for_all_3(lp, rp, op)
+ op.val() = f(lp.val() + rp.val());
+ }
+
template <typename L, typename R>
void plus_inplace_(trait::image::speed::any, L& lhs,
trait::image::speed::any, const R& rhs)
{
- mln_piter(R) p(rhs.domain());
+ mln_piter(L) p(lhs.domain());
for_all(p)
lhs(p) += rhs(p);
}
@@ -218,7 +322,7 @@
{
mln_pixter(L) lp(lhs);
mln_pixter(const R) rp(rhs);
- for_all_2(rp, lp)
+ for_all_2(lp, rp)
lp.val() += rp.val();
}
@@ -227,38 +331,133 @@
// Facades.
- template <typename L, typename R, typename O>
- void plus(const Image<L>& lhs, const Image<R>& rhs,
Image<O>& output)
+
+ template <typename L, typename R>
+ mln_trait_op_plus(L, R)
+ plus(const Image<L>& lhs, const Image<R>& rhs)
+ {
+ trace::entering("arith::plus");
+ mln_precondition(exact(rhs).domain() = exact(lhs).domain());
+
+ mln_trait_op_plus(L, R) output;
+ initialize(output, lhs);
+ impl::plus_(mln_trait_image_speed(L)(), exact(lhs),
+ mln_trait_image_speed(R)(), exact(rhs), output);
+
+ trace::exiting("arith::plus");
+ return output;
+ }
+
+
+ template <typename L, typename R, typename F>
+ mln_ch_value(L, mln_result(F))
+ plus(const Image<L>& lhs, const Image<R>& rhs, const
Function_v2v<F>& f)
{
+ trace::entering("arith::plus");
mln_precondition(exact(rhs).domain() = exact(lhs).domain());
- mln_precondition(exact(output).domain() = exact(lhs).domain());
+
+ mln_ch_value(L, mln_result(F)) output;
+ initialize(output, lhs);
impl::plus_(mln_trait_image_speed(L)(), exact(lhs),
- mln_trait_image_speed(R)(), exact(rhs),
- mln_trait_image_speed(O)(), exact(output));
+ mln_trait_image_speed(R)(), exact(rhs), exact(f), output);
+
+ trace::exiting("arith::plus");
+ return output;
+ }
+
+
+ template <typename V, typename L, typename R>
+ mln_ch_value(L, V)
+ plus(const Image<L>& lhs, const Image<R>& rhs)
+ {
+ trace::entering("arith::plus");
+ mln_precondition(exact(rhs).domain() = exact(lhs).domain());
+
+ // Calls the previous version.
+ mln_ch_value(L, V) output = plus(lhs, rhs,
+ mln::fun::v2v::cast<V>());
+
+ trace::exiting("arith::plus");
+ return output;
+ }
+
+
+ template <typename I, typename V>
+ mln_trait_op_plus(I, V)
+ plus_cst(const Image<I>& input, const V& val)
+ {
+ trace::entering("arith::plus_cst");
+ mln_precondition(exact(input).has_data());
+
+ // Calls the previous version.
+ mln_trait_op_plus(I, V) output = plus(input,
+ pw::cst(val) | exact(input).domain());
+
+ trace::exiting("arith::plus_cst");
+ return output;
+ }
+
+
+ template <typename I, typename V, typename F>
+ mln_ch_value(I, mln_result(F))
+ plus_cst(const Image<I>& input, const V& val, const
Function_v2v<F>& f)
+ {
+ trace::entering("arith::plus_cst");
+ mln_precondition(exact(input).has_data());
+
+ // Calls the previous version.
+ mln_ch_value(I, mln_result(F)) output = plus(input,
+ pw::cst(val) | exact(input).domain(),
+ f);
+
+ trace::exiting("arith::plus_cst");
+ return output;
}
- template <typename I, typename V, typename O>
- void plus_cst(const Image<I>& input, const V& val, Image<O>&
output)
+
+ template <typename W, typename I, typename V>
+ mln_ch_value(I, W)
+ plus_cst(const Image<I>& input, const V& val)
{
- mln_precondition(exact(output).domain() = exact(input).domain());
- plus(input, pw::cst(val) | exact(input).domain(), output);
+ trace::entering("arith::plus_cst");
+ mln_precondition(exact(input).has_data());
+
// Calls the previous version.
+ mln_ch_value(I, W) output = plus_cst(input, val,
+ mln::fun::v2v::cast<W>());
+
+ trace::exiting("arith::plus_cst");
+ return output;
}
+
template <typename L, typename R>
- void plus_inplace(Image<L>& lhs, const Image<R>& rhs)
+ void
+ plus_inplace(Image<L>& lhs, const Image<R>& rhs)
{
- mln_precondition(exact(rhs).domain() <= exact(lhs).domain());
+ trace::entering("arith::plus_inplace");
+ mln_precondition(exact(rhs).domain() = exact(lhs).domain());
+
impl::plus_inplace_(mln_trait_image_speed(L)(), exact(lhs),
mln_trait_image_speed(R)(), exact(rhs));
+
+ trace::exiting("arith::plus_inplace");
}
+
template <typename I, typename V>
- void plus_cst_inplace(Image<I>& input, const V& val)
+ I&
+ plus_cst_inplace(Image<I>& input, const V& val)
{
+ trace::entering("arith::plus_cst_inplace");
mln_precondition(exact(input).has_data());
- plus_inplace(input, pw::cst(val) | exact(input).domain());
+
// Calls the previous version.
+ plus_inplace(input,
+ pw::cst(val) | exact(input).domain());
+
+ trace::exiting("arith::plus_cst_inplace");
+ return exact(input);
}
} // end of namespace mln::arith
Index: mln/arith/min.hh
--- mln/arith/min.hh (revision 1405)
+++ mln/arith/min.hh (working copy)
@@ -46,12 +46,13 @@
*
* \param[in] lhs First operand image.
* \param[in] rhs Second operand image.
- * \param[out] output The result image.
+ * \result The result image.
*
- * \pre \p output.domain = \p lhs.domain = \p rhs.domain
+ * \pre \p lhs.domain = \p rhs.domain
*/
- template <typename L, typename R, typename O>
- void min(const Image<L>& lhs, const Image<R>& rhs,
Image<O>& output);
+ template <typename L, typename R>
+ mln_concrete(L)
+ min(const Image<L>& lhs, const Image<R>& rhs);
/*! Point-wise min of image \p lhs in image \p rhs.
@@ -59,12 +60,7 @@
* \param[in,out] lhs First operand image.
* \param[in] rhs Second operand image.
*
- * This substraction performs: \n
- * for all p of rhs.domain \n
- * if rhs(p) < lhs(p) \n
- * lhs(p) = rhs(p)
- *
- * \pre \p rhs.domain <= \p lhs.domain
+ * \pre \p rhs.domain = \p lhs.domain
*/
template <typename L, typename R>
void min_inplace(Image<L>& lhs, const Image<R>& rhs);
@@ -77,8 +73,7 @@
template <typename L, typename R, typename O>
void min_(trait::image::speed::any, const L& lhs,
- trait::image::speed::any, const R& rhs,
- trait::image::speed::any, O& output)
+ trait::image::speed::any, const R& rhs, O& output)
{
mln_piter(L) p(lhs.domain());
for_all(p)
@@ -87,8 +82,7 @@
template <typename L, typename R, typename O>
void min_(trait::image::speed::fastest, const L& lhs,
- trait::image::speed::fastest, const R& rhs,
- trait::image::speed::fastest, O& output)
+ trait::image::speed::fastest, const R& rhs, O& output)
{
mln_pixter(const L) lp(lhs);
mln_pixter(const R) rp(rhs);
@@ -101,7 +95,7 @@
void min_inplace_(trait::image::speed::any, L& lhs,
trait::image::speed::any, const R& rhs)
{
- mln_piter(R) p(rhs.domain());
+ mln_piter(L) p(lhs.domain());
for_all(p)
if (rhs(p) < lhs(p))
lhs(p) = rhs(p);
@@ -113,7 +107,7 @@
{
mln_pixter(L) lp(lhs);
mln_pixter(const R) rp(rhs);
- for_all_2(rp, lp)
+ for_all_2(lp, rp)
if (rp.val() < lp.val())
lp.val() = rp.val();
}
@@ -123,22 +117,31 @@
// Facades.
- template <typename L, typename R, typename O>
- void min(const Image<L>& lhs, const Image<R>& rhs,
Image<O>& output)
+ template <typename L, typename R>
+ mln_concrete(L) min(const Image<L>& lhs, const Image<R>& rhs)
{
+ trace::entering("arith::min");
mln_precondition(exact(rhs).domain() = exact(lhs).domain());
- mln_precondition(exact(output).domain() = exact(lhs).domain());
+
+ mln_concrete(L) output;
+ initialize(output, lhs);
impl::min_(mln_trait_image_speed(L)(), exact(lhs),
- mln_trait_image_speed(R)(), exact(rhs),
- mln_trait_image_speed(O)(), exact(output));
+ mln_trait_image_speed(R)(), exact(rhs), output);
+
+ trace::exiting("arith::min");
+ return output;
}
template <typename L, typename R>
void min_inplace(Image<L>& lhs, const Image<R>& rhs)
{
- mln_precondition(exact(rhs).domain() <= exact(lhs).domain());
+ trace::entering("arith::min_inplace");
+ mln_precondition(exact(rhs).domain() = exact(lhs).domain());
+
impl::min_inplace_(mln_trait_image_speed(L)(), exact(lhs),
mln_trait_image_speed(R)(), exact(rhs));
+
+ trace::exiting("arith::min_inplace");
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/arith/includes.hh
--- mln/arith/includes.hh (revision 1405)
+++ mln/arith/includes.hh (working copy)
@@ -37,6 +37,7 @@
# include <mln/value/ops.hh>
# include <mln/pw/cst.hh>
# include <mln/pw/image.hh>
+# include <mln/fun/v2v/cast.hh>
#endif // ! MLN_ARITH_INCLUDES_HH
Index: mln/arith/revert.hh
--- mln/arith/revert.hh (revision 1405)
+++ mln/arith/revert.hh (working copy)
@@ -52,18 +52,24 @@
/*! Point-wise reversion of image \p input.
*
* \param[in] input the input image.
- * \param[out] output The result image.
+ * \result The result image.
*
- * \pre \p output.domain = \p input.domain
+ * \pre \p input.has_data
+ *
+ * It performs: \n
+ * for all p of input.domain \n
+ * output(p) = min + (max - input(p))
*/
- template <typename I, typename O>
- void revert(const Image<I>& input, Image<O>& output);
+ template <typename I>
+ mln_concrete(I) revert(const Image<I>& input);
/*! Point-wise in-place reversion of image \p input.
*
* \param[in,out] input The target image.
*
+ * \pre \p input.has_data
+ *
* It performs: \n
* for all p of input.domain \n
* input(p) = min + (max - input(p))
@@ -78,8 +84,7 @@
{
template <typename I, typename O>
- void revert_(trait::image::speed::any, const I& input,
- trait::image::speed::any, O& output)
+ void revert_(trait::image::speed::any, const I& input, O& output)
{
typedef mln_value(I) V;
mln_piter(I) p(input.domain());
@@ -88,8 +93,7 @@
}
template <typename I, typename O>
- void revert_(trait::image::speed::fastest, const I& input,
- trait::image::speed::fastest, O& output)
+ void revert_(trait::image::speed::fastest, const I& input, O& output)
{
typedef mln_value(I) V;
mln_pixter(const I) ip(input);
@@ -103,20 +107,29 @@
// Facades.
- template <typename I, typename O>
- void revert(const Image<I>& input, Image<O>& output)
+ template <typename I>
+ mln_concrete(I) revert(const Image<I>& input)
{
- mln_precondition(exact(output).domain() = exact(input).domain());
- impl::revert_(mln_trait_image_speed(I)(), exact(input),
- mln_trait_image_speed(O)(), exact(output));
+ trace::entering("arith::revert");
+ mln_precondition(exact(input).has_data());
+
+ mln_concrete(I) output;
+ initialize(output, input);
+ impl::revert_(mln_trait_image_speed(I)(), exact(input), output);
+
+ trace::exiting("arith::revert");
+ return output;
}
template <typename I>
void revert_inplace(Image<I>& input)
{
+ trace::entering("arith::revert_inplace");
mln_precondition(exact(input).has_data());
- impl::revert_(mln_trait_image_speed(I)(), exact(input),
- mln_trait_image_speed(I)(), exact(input));
+
+ impl::revert_(mln_trait_image_speed(I)(), exact(input), exact(input));
+
+ trace::exiting("arith::revert_inplace");
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/arith/minus.hh
--- mln/arith/minus.hh (revision 1405)
+++ mln/arith/minus.hh (working copy)
@@ -31,63 +31,249 @@
/*! \file mln/arith/minus.hh
*
* \brief Point-wise substraction between images.
+ *
+ * \todo Speedup; some versions are not optimal.
*/
-# include <mln/core/concept/image.hh>
+# include <mln/arith/includes.hh>
namespace mln
{
+
+ namespace trait
+ {
+
+ template <typename L, typename R>
+ struct set_binary_< op::minus, Image, L, Image, R >
+ {
+ typedef mln_trait_op_minus(mln_value(L), mln_value(R)) value;
+ typedef mln_ch_value(L, value) ret;
+ };
+
+ template <typename I, typename S>
+ struct set_binary_< op::minus, Image, I, mln::value::Scalar, S >
+ {
+ typedef mln_trait_op_minus(mln_value(I), S) value;
+ typedef mln_ch_value(I, value) ret;
+ };
+
+ } // end of namespace mln::trait
+
+
+
+ template <typename L, typename R>
+ mln_trait_op_minus(L,R)
+ operator-(const Image<L>& lhs, const Image<R>& rhs);
+
+
+ template <typename L, typename R>
+ L&
+ operator-=(Image<L>& lhs, const Image<R>& rhs);
+
+
+ template <typename I, typename S>
+ mln_trait_op_minus(I,S)
+ operator-(const Image<I>& ima, const value::Scalar<S>& s);
+
+
+ template <typename I, typename S>
+ I&
+ operator-=(Image<I>& ima, const value::Scalar<S>& s);
+
+
+
namespace arith
{
- /*! Point-wise substraction of images \p lhs and \p rhs.
+ /*! Point-wise addition of images \p lhs and \p rhs.
*
* \param[in] lhs First operand image.
* \param[in] rhs Second operand image.
- * \param[out] output The result image.
+ * \result The result image.
*
- * \pre \p output.domain = \p lhs.domain = \p rhs.domain
+ * \pre \p lhs.domain = \p rhs.domain
*/
- template <typename L, typename R, typename O>
- void minus(const Image<L>& lhs, const Image<R>& rhs,
Image<O>& output);
+ template <typename L, typename R>
+ mln_trait_op_minus(L, R)
+ minus(const Image<L>& lhs, const Image<R>& rhs);
- /*! Point-wise substraction of image \p lhs in image \p rhs.
+ /*! Point-wise addition of images \p lhs and \p rhs.
*
- * \param[in,out] lhs First operand image (subject to substraction).
- * \param[in] rhs Second operand image (to be substracted to \p lhs).
+ * \param[in] lhs First operand image.
+ * \param[in] rhs Second operand image.
+ * \param[in] f Function.
+ * \result The result image.
*
- * This substraction performs: \n
+ * \pre \p lhs.domain = \p rhs.domain
+ */
+ template <typename L, typename R, typename F>
+ mln_ch_value(L, mln_result(F))
+ minus(const Image<L>& lhs, const Image<R>& rhs, const
Function_v2v<F>& f);
+
+
+ /*! Point-wise addition of images \p lhs and \p rhs.
+ *
+ * \param[in] lhs First operand image.
+ * \param[in] rhs Second operand image.
+ * \result The result image.
+ *
+ * The free parameter \c V sets the destination value type.
+ *
+ * \pre \p lhs.domain = \p rhs.domain
+ */
+ template <typename V, typename L, typename R>
+ mln_ch_value(L, V)
+ minus(const Image<L>& lhs, const Image<R>& rhs);
+
+
+ /*! Point-wise addition of image \p rhs in image \p lhs.
+ *
+ * \param[in,out] lhs First operand image (subject to addition).
+ * \param[in] rhs Second operand image (to be added to \p lhs).
+ *
+ * This addition performs: \n
* for all p of rhs.domain \n
* lhs(p) -= rhs(p)
*
- * \pre \p rhs.domain <= \p lhs.domain
+ * \pre \p rhs.domain = \p lhs.domain
*/
template <typename L, typename R>
- void minus_inplace(Image<L>& lhs, const Image<R>& rhs);
+ void
+ minus_inplace(Image<L>& lhs, const Image<R>& rhs);
+
+
+ /*! Point-wise addition of the value \p val to image \p input.
+ *
+ * \param[in] input The image.
+ * \param[in] val The value.
+ * \result The result image.
+ *
+ * \pre \p input.has_data
+ */
+ template <typename I, typename V>
+ mln_trait_op_minus(I, V)
+ minus_cst(const Image<I>& input, const V& val);
+
+
+ /*! Point-wise addition of the value \p val to image \p input.
+ *
+ * \param[in] input The image.
+ * \param[in] val The value.
+ * \param[in] f Function.
+ * \result The result image.
+ *
+ * \pre \p input.has_data
+ */
+ template <typename I, typename V, typename F>
+ mln_ch_value(I, mln_result(F))
+ minus_cst(const Image<I>& input, const V& val, const
Function_v2v<F>& f);
+
+
+ /*! Point-wise addition of the value \p val to image \p input.
+ *
+ * \param[in,out] input The image.
+ * \param[in] val The value.
+ *
+ * \pre \p input.has_data
+ */
+ template <typename I, typename V>
+ I&
+ minus_cst_inplace(Image<I>& input, const V& val);
+
+
+ } // end of namespace mln::arith
+
+
# ifndef MLN_INCLUDE_ONLY
+
+ template <typename L, typename R>
+ mln_trait_op_minus(L,R)
+ operator-(const Image<L>& lhs, const Image<R>& rhs)
+ {
+ trace::entering("operator::minus");
+ mln_precondition(exact(rhs).domain() = exact(lhs).domain());
+
+ mln_trait_op_minus(L,R) output = arith::minus(lhs, rhs);
+
+ trace::exiting("operator::minus");
+ return output;
+ }
+
+ template <typename L, typename R>
+ L&
+ operator-=(Image<L>& lhs, const Image<R>& rhs)
+ {
+ trace::entering("operator::minus_eq");
+ mln_precondition(exact(rhs).domain() = exact(lhs).domain());
+
+ arith::minus_inplace(lhs, rhs);
+
+ trace::exiting("operator::minus_eq");
+ return exact(lhs);
+ }
+
+
+ template <typename I, typename S>
+ mln_trait_op_minus(I,S)
+ operator-(const Image<I>& ima, const value::Scalar<S>& s)
+ {
+ trace::entering("operator::minus");
+ mln_precondition(exact(ima).has_data());
+
+ mln_trait_op_minus(I,S) output = arith::minus_cst(ima, exact(s));
+
+ trace::exiting("operator::minus");
+ return output;
+ }
+
+ template <typename I, typename S>
+ I&
+ operator-=(Image<I>& ima, const value::Scalar<S>& s)
+ {
+ trace::entering("operator::minus_eq");
+ mln_precondition(exact(ima).has_data());
+
+ arith::minus_cst_inplace(ima, exact(s));
+
+ trace::exiting("operator::minus_eq");
+ return exact(ima);
+ }
+
+
+
+ namespace arith
+ {
+
namespace impl
{
template <typename L, typename R, typename O>
void minus_(trait::image::speed::any, const L& lhs,
- trait::image::speed::any, const R& rhs,
- trait::image::speed::any, O& output)
+ trait::image::speed::any, const R& rhs, O& output)
{
mln_piter(L) p(lhs.domain());
for_all(p)
output(p) = lhs(p) - rhs(p);
}
+ template <typename L, typename R, typename F, typename O>
+ void minus_(trait::image::speed::any, const L& lhs,
+ trait::image::speed::any, const R& rhs, const F& f, O& output)
+ {
+ mln_piter(L) p(lhs.domain());
+ for_all(p)
+ output(p) = f(lhs(p) - rhs(p));
+ }
+
template <typename L, typename R, typename O>
void minus_(trait::image::speed::fastest, const L& lhs,
- trait::image::speed::fastest, const R& rhs,
- trait::image::speed::fastest, O& output)
+ trait::image::speed::fastest, const R& rhs, O& output)
{
mln_pixter(const L) lp(lhs);
mln_pixter(const R) rp(rhs);
@@ -96,11 +282,22 @@
op.val() = lp.val() - rp.val();
}
+ template <typename L, typename R, typename F, typename O>
+ void minus_(trait::image::speed::fastest, const L& lhs,
+ trait::image::speed::fastest, const R& rhs, const F& f, O& output)
+ {
+ mln_pixter(const L) lp(lhs);
+ mln_pixter(const R) rp(rhs);
+ mln_pixter(O) op(output);
+ for_all_3(lp, rp, op)
+ op.val() = f(lp.val() - rp.val());
+ }
+
template <typename L, typename R>
void minus_inplace_(trait::image::speed::any, L& lhs,
trait::image::speed::any, const R& rhs)
{
- mln_piter(R) p(rhs.domain());
+ mln_piter(L) p(lhs.domain());
for_all(p)
lhs(p) -= rhs(p);
}
@@ -111,7 +308,7 @@
{
mln_pixter(L) lp(lhs);
mln_pixter(const R) rp(rhs);
- for_all_2(rp, lp)
+ for_all_2(lp, rp)
lp.val() -= rp.val();
}
@@ -120,28 +317,123 @@
// Facades.
- template <typename L, typename R, typename O>
- void minus(const Image<L>& lhs, const Image<R>& rhs,
Image<O>& output)
+
+ template <typename L, typename R>
+ mln_trait_op_minus(L, R)
+ minus(const Image<L>& lhs, const Image<R>& rhs)
{
+ trace::entering("arith::minus");
mln_precondition(exact(rhs).domain() = exact(lhs).domain());
- mln_precondition(exact(output).domain() = exact(lhs).domain());
+
+ mln_trait_op_minus(L, R) output;
+ initialize(output, lhs);
impl::minus_(mln_trait_image_speed(L)(), exact(lhs),
- mln_trait_image_speed(R)(), exact(rhs),
- mln_trait_image_speed(O)(), exact(output));
+ mln_trait_image_speed(R)(), exact(rhs), output);
+
+ trace::exiting("arith::minus");
+ return output;
}
+
+ template <typename L, typename R, typename F>
+ mln_ch_value(L, mln_result(F))
+ minus(const Image<L>& lhs, const Image<R>& rhs, const
Function_v2v<F>& f)
+ {
+ trace::entering("arith::minus");
+ mln_precondition(exact(rhs).domain() = exact(lhs).domain());
+
+ mln_ch_value(L, mln_result(F)) output;
+ initialize(output, lhs);
+ impl::minus_(mln_trait_image_speed(L)(), exact(lhs),
+ mln_trait_image_speed(R)(), exact(rhs), exact(f), output);
+
+ trace::exiting("arith::minus");
+ return output;
+ }
+
+
+ template <typename V, typename L, typename R>
+ mln_ch_value(L, V)
+ minus(const Image<L>& lhs, const Image<R>& rhs)
+ {
+ trace::entering("arith::minus");
+ mln_precondition(exact(rhs).domain() = exact(lhs).domain());
+
+ // Calls the previous version.
+ mln_ch_value(L, V) output = minus(lhs, rhs,
+ mln::fun::v2v::cast<V>());
+
+ trace::exiting("arith::minus");
+ return output;
+ }
+
+
+ template <typename I, typename V>
+ mln_trait_op_minus(I, V)
+ minus_cst(const Image<I>& input, const V& val)
+ {
+ trace::entering("arith::minus_cst");
+ mln_precondition(exact(input).has_data());
+
+ // Calls the previous version.
+ mln_trait_op_minus(I, V) output = minus(input,
+ pw::cst(val) | exact(input).domain());
+
+ trace::exiting("arith::minus_cst");
+ return output;
+ }
+
+
+ template <typename I, typename V, typename F>
+ mln_ch_value(I, mln_result(F))
+ minus_cst(const Image<I>& input, const V& val, const
Function_v2v<F>& f)
+ {
+ trace::entering("arith::minus_cst");
+ mln_precondition(exact(input).has_data());
+
+ // Calls the previous version.
+ mln_ch_value(I, mln_result(F)) output = minus(input,
+ pw::cst(val) | exact(input).domain(),
+ f);
+
+ trace::exiting("arith::minus_cst");
+ return output;
+ }
+
+
template <typename L, typename R>
- void minus_inplace(Image<L>& lhs, const Image<R>& rhs)
+ void
+ minus_inplace(Image<L>& lhs, const Image<R>& rhs)
{
- mln_precondition(exact(rhs).domain() <= exact(lhs).domain());
+ trace::entering("arith::minus_inplace");
+ mln_precondition(exact(rhs).domain() = exact(lhs).domain());
+
impl::minus_inplace_(mln_trait_image_speed(L)(), exact(lhs),
mln_trait_image_speed(R)(), exact(rhs));
+
+ trace::exiting("arith::minus_inplace");
}
-# endif // ! MLN_INCLUDE_ONLY
+
+ template <typename I, typename V>
+ I&
+ minus_cst_inplace(Image<I>& input, const V& val)
+ {
+ trace::entering("arith::minus_cst_inplace");
+ mln_precondition(exact(input).has_data());
+
+ // Calls the previous version.
+ minus_inplace(input,
+ pw::cst(val) | exact(input).domain());
+
+ trace::exiting("arith::minus_cst_inplace");
+ return exact(input);
+ }
} // end of namespace mln::arith
+# endif // ! MLN_INCLUDE_ONLY
+
} // end of namespace mln
Index: mln/value/cast.hh
--- mln/value/cast.hh (revision 1405)
+++ mln/value/cast.hh (working copy)
@@ -34,6 +34,7 @@
*/
# include <mln/core/concept/value.hh>
+# include <mln/value/equiv.hh>
namespace mln
@@ -56,24 +57,34 @@
template <typename S>
const S&
- cast_(const S& src, ...)
+ cast_(const void*, const S& src)
{
return src;
}
- template <typename T, typename S>
- typename S::equiv // FIXME: Is-that equiv here?
- cast_(const T&, const Value<S>& src)
+ template <typename O, typename S>
+ const S&
+ cast_(const Object<O>*, const S& src)
+ {
+ return src;
+ }
+
+ template <typename V, typename S>
+ mln_value_equiv(S)
+ cast_(const Value<V>*, const S& src)
{
- return exact(src);
+ return mln::value::equiv(src);
}
} // end of namespace mln::value::internal
+
template <typename Dest, typename Src>
Dest cast(const Src& src)
{
- return internal::cast_(src, src);
+ // FIXME: Add static_cast<Dest>?
+ // FIXME: Add exact()?
+ return internal::cast_(&src, src);
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/value/builtin/ops.hh
--- mln/value/builtin/ops.hh (revision 1405)
+++ mln/value/builtin/ops.hh (working copy)
@@ -185,7 +185,6 @@
// Operator "Builtin minus Object" is a special case.
-
# define mln_internal_decl_bi_minus_obj_(Builtin) \
\
template <typename O> \
@@ -194,7 +193,6 @@
\
struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
-
# define mln_internal_def_bi_minus_obj_(Builtin) \
\
template <typename O> \
@@ -227,7 +225,6 @@
// Operator "Builtin 'div or mod' Object" is a special case.
-
# define mln_internal_decl_bi_dvmd_obj_(Symb, Name, Builtin) \
\
template <typename O> \
@@ -236,7 +233,6 @@
\
struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
-
# define mln_internal_def_bi_dvmd_obj_(Symb, Name, Builtin) \
\
template <typename O> \
@@ -264,7 +260,6 @@
\
struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
-
# define mln_internal_op_builtins_cmp_(De, Symb, Name) \
\
mln_internal_##De##_op_cmp_(Symb, Name, signed char); \
@@ -280,6 +275,48 @@
\
struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
+
+
+// Operator "Builtin Op= Object" is a special case.
+
+
+# define mln_internal_decl_bi_opeq_obj_(Symb, Builtin) \
+ \
+ template <typename O> \
+ Builtin & \
+ operator Symb##= (Builtin & lhs, const Object<O>& rhs); \
+ \
+ struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
+
+# define mln_internal_def_bi_opeq_obj_(Symb, Builtin) \
+ \
+ template <typename O> \
+ Builtin & \
+ operator Symb##= (Builtin & lhs, const Object<O>& rhs) \
+ { \
+ lhs Symb##= exact(rhs).to_equiv(); \
+ return lhs; \
+ } \
+ \
+ struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
+
+# define mln_internal_builtins_opeq_obj_(De, Symb) \
+ \
+ mln_internal_##De##_bi_opeq_obj_(Symb, signed char); \
+ mln_internal_##De##_bi_opeq_obj_(Symb, unsigned char); \
+ mln_internal_##De##_bi_opeq_obj_(Symb, signed short); \
+ mln_internal_##De##_bi_opeq_obj_(Symb, unsigned short); \
+ mln_internal_##De##_bi_opeq_obj_(Symb, signed int); \
+ mln_internal_##De##_bi_opeq_obj_(Symb, unsigned int); \
+ mln_internal_##De##_bi_opeq_obj_(Symb, signed long); \
+ mln_internal_##De##_bi_opeq_obj_(Symb, unsigned long); \
+ mln_internal_##De##_bi_opeq_obj_(Symb, float); \
+ mln_internal_##De##_bi_opeq_obj_(Symb, double); \
+ \
+ struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
+
+
+
// FIXME: What about pointers, arrays, bool, etc.
// FIXME: Mod is not defined for float and double...
@@ -339,11 +376,10 @@
template<> struct set_precise_unary_< op::uminus, unsigned short > {
typedef int ret; };
template<> struct set_precise_unary_< op::uminus, signed int > {
typedef signed int ret; };
- // Disabled cause no correct result can be obtained
- // e.g., (- unsigned int) is an (unsigned int)!
- template<> struct set_precise_unary_< op::uminus, unsigned int > {};
- template<> struct set_precise_unary_< op::uminus, signed long > {};
- template<> struct set_precise_unary_< op::uminus, unsigned long > {};
+ template<> struct set_precise_unary_< op::uminus, unsigned int > {
typedef signed int ret; };
+ template<> struct set_precise_unary_< op::uminus, signed long > {
typedef signed long ret; };
+ template<> struct set_precise_unary_< op::uminus, unsigned long > {
typedef signed long ret; };
+
template<> struct set_precise_unary_< op::uminus, bool > {};
template<> struct set_precise_unary_< op::uminus, float > { typedef
float ret; };
@@ -356,11 +392,20 @@
// A couple of builtins => promotion...
mln_internal_set_builtin_trait_is_promotion_(op::plus);
- mln_internal_set_builtin_trait_is_promotion_(op::minus);
mln_internal_set_builtin_trait_is_promotion_(op::times);
mln_internal_set_builtin_trait_is_promotion_(op::div);
mln_internal_set_builtin_trait_is_promotion_(op::mod);
+ // mln_internal_set_builtin_trait_is_promotion_(op::minus);
+
+ template <typename Bl, typename Br>
+ struct set_binary_< op::minus,
+ mln::value::Built_In, Bl, mln::value::Built_In, Br >
+ {
+ typedef mln_trait_op_uminus(Br) minus_Br;
+ typedef mln_trait_promote(Bl, minus_Br) ret;
+ };
+
// For comparisons (such as "less-than"), we get bool.
mln_internal_set_builtin_trait_is_bool_(op::eq);
@@ -495,6 +540,15 @@
// FIXME: ...
+ // Ops "bi Op= obj"
+ mln_internal_builtins_opeq_obj_(decl, +);
+ mln_internal_builtins_opeq_obj_(decl, -);
+ mln_internal_builtins_opeq_obj_(decl, *);
+ mln_internal_builtins_opeq_obj_(decl, /);
+ mln_internal_builtins_opeq_obj_(decl, %);
+
+
+
# ifndef MLN_INCLUDE_ONLY
mln_internal_op_obj_builtins_(def, +, plus);
@@ -521,6 +575,14 @@
// FIXME: Add less, etc.
+ // Ops "bi Op= obj"
+ mln_internal_builtins_opeq_obj_(def, +);
+ mln_internal_builtins_opeq_obj_(def, -);
+ mln_internal_builtins_opeq_obj_(def, *);
+ mln_internal_builtins_opeq_obj_(def, /);
+ mln_internal_builtins_opeq_obj_(def, %);
+
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln
Index: mln/convert/to_image.hh
--- mln/convert/to_image.hh (revision 1405)
+++ mln/convert/to_image.hh (working copy)
@@ -124,6 +124,8 @@
template <typename S>
image1d<std::size_t> to_image(const mln::histo::data<S>& h);
+
+
# ifndef MLN_INCLUDE_ONLY
template <typename S>
Index: mln/fun/ops.hh
--- mln/fun/ops.hh (revision 1405)
+++ mln/fun/ops.hh (working copy)
@@ -35,6 +35,7 @@
# include <mln/core/concept/function.hh>
# include <mln/fun/internal/selector.hh>
+# include <mln/trait/all.hh>
@@ -47,7 +48,8 @@
struct Name##_##Out##_expr_ \
: public Function_##Out < Name##_##Out##_expr_<L,R> > \
{ \
- typedef mln_result(L) result; \
+ typedef typename mln::trait::op:: Name < mln_result(L), \
+ mln_result(R) >::ret result; \
\
Name##_##Out##_expr_(const L& l, const R& r) \
: l_(l), r_(r) \
@@ -67,6 +69,18 @@
\
} \
\
+ namespace trait \
+ { \
+ \
+ template <typename L, typename R> \
+ struct set_binary_< op::Name, \
+ Function_##In, L, \
+ Function_##In, R > \
+ { \
+ typedef fun::Name##_##Out##_expr_<L,R> ret; \
+ }; \
+ } \
+ \
template <typename L, typename R> \
fun::Name##_##Out##_expr_<L,R> \
operator Symbol (const Function_##In<L>& lhs, const
Function_##In<R>& rhs) \
@@ -75,7 +89,7 @@
return tmp; \
} \
\
- struct dummy
+ struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
# define mln_decl_unary_expr_(In, Out, Name, Symbol) \
@@ -87,7 +101,7 @@
struct Name##_##Out##_expr_ \
: public Function_##Out< Name##_##Out##_expr_<F> > \
{ \
- typedef mln_result(F) result; \
+ typedef typename mln::trait::op:: Name < mln_result(F) >::ret result; \
\
Name##_##Out##_expr_(const F& f) \
: f_(f) \
@@ -106,6 +120,16 @@
\
} \
\
+ namespace trait \
+ { \
+ template <typename F> \
+ struct set_unary_< op::Name, \
+ Function_##In, F > \
+ { \
+ typedef fun::Name##_##Out##_expr_<F> ret; \
+ }; \
+ } \
+ \
template <typename F> \
fun::Name##_##Out##_expr_<F> \
operator Symbol (const Function_##In<F>& f) \
@@ -114,7 +138,7 @@
return tmp; \
} \
\
- struct dummy
+ struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
@@ -130,11 +154,11 @@
mln_decl_binary_expr_(p2v, p2b, geq, >=);
mln_decl_binary_expr_(p2v, p2b, greater, >);
- mln_decl_binary_expr_(p2b, p2b, and, &&);
- mln_decl_binary_expr_(p2b, p2b, or, ||);
- mln_decl_binary_expr_(p2b, p2b, xor, ^);
+ mln_decl_binary_expr_(p2b, p2b, and_, &&);
+ mln_decl_binary_expr_(p2b, p2b, or_, ||);
+ mln_decl_binary_expr_(p2b, p2b, xor_, ^);
- mln_decl_unary_expr_(p2b, p2b, not, !);
+ mln_decl_unary_expr_(p2b, p2b, not_, !);
mln_decl_binary_expr_(p2v, p2v, plus, +);
mln_decl_binary_expr_(p2v, p2v, minus, -);
@@ -155,11 +179,11 @@
mln_decl_binary_expr_(v2v, v2b, geq, >=);
mln_decl_binary_expr_(v2v, v2b, greater, >);
- mln_decl_binary_expr_(v2b, v2b, and, &&);
- mln_decl_binary_expr_(v2b, v2b, or, ||);
- mln_decl_binary_expr_(v2b, v2b, xor, ^);
+ mln_decl_binary_expr_(v2b, v2b, and_, &&);
+ mln_decl_binary_expr_(v2b, v2b, or_, ||);
+ mln_decl_binary_expr_(v2b, v2b, xor_, ^);
- mln_decl_unary_expr_(v2b, v2b, not, !);
+ mln_decl_unary_expr_(v2b, v2b, not_, !);
} // end of namespace mln
Index: mln/fun/cast.hh
--- mln/fun/cast.hh (revision 0)
+++ mln/fun/cast.hh (revision 0)
@@ -0,0 +1,84 @@
+// 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_FUN_CAST_HH
+# define MLN_FUN_CAST_HH
+
+/*! \file mln/fun/cast.hh
+ *
+ * \brief FIXME.
+ */
+
+# include <mln/core/concept/function.hh>
+
+
+namespace mln
+{
+
+ namespace fun
+ {
+
+ // FIXME: Doc!
+ template <typename V, typename F>
+ struct cast_p2v_expr_ : public Function_p2v< cast_p2v_expr_<V,F> >
+ {
+ typedef V result;
+
+ cast_p2v_expr_(const F& f)
+ : f_(f)
+ {}
+
+ template <typename P>
+ V operator()(const P& p) const
+ {
+ return static_cast<V>(f_(p)); // FIXME: value::cast?
+ }
+
+ protected:
+ const F f_;
+ };
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename V, typename F>
+ cast_p2v_expr_<V, F>
+ cast(const Function_p2v<F>& f)
+ {
+ cast_p2v_expr_<V, F> tmp(exact(f));
+ return tmp;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::fun
+
+} // end of namespace mln
+
+
+#endif // ! MLN_FUN_CAST_HH
Index: mln/fun/v2v/saturate.hh
--- mln/fun/v2v/saturate.hh (revision 1405)
+++ mln/fun/v2v/saturate.hh (working copy)
@@ -87,16 +87,21 @@
V
saturate<V>::operator()(const W& w) const
{
+ // FIXME: Check that W is a larger type than V; otherwise
+ // alt code.
+ static const W min_W = mln::value::cast<W>(min_);
+ static const W max_W = mln::value::cast<W>(max_);
+
// FIXME: Below we need something more powerful that mlc_converts_to
- // FIXME: for instance, with W=int_s<10u> and V=int_u<8u>, it does not
- // FIXME: works cause the cast is not obvious...
+ // for instance, with W=int_s<10u> and V=int_u<8u>, it does not
+ // works cause the cast is not obvious...
// mlc_converts_to(W, V)::check();
- V w_ = mln::value::cast<V>(w);
- if (w_ < min_)
+
+ if (w < min_W)
return min_;
- if (w_ > max_)
+ if (w > max_W)
return max_;
- return w_;
+ return mln::value::cast<W>(w);
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/fun/v2v/all.hh
--- mln/fun/v2v/all.hh (revision 1405)
+++ mln/fun/v2v/all.hh (working copy)
@@ -50,6 +50,7 @@
# include <mln/fun/v2v/abs.hh>
+# include <mln/fun/v2v/cast.hh>
# include <mln/fun/v2v/enc.hh>
# include <mln/fun/v2v/id.hh>
# include <mln/fun/v2v/linear.hh>
Index: mln/fun/v2v/cast.hh
--- mln/fun/v2v/cast.hh (revision 0)
+++ mln/fun/v2v/cast.hh (revision 0)
@@ -0,0 +1,80 @@
+// 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_FUN_V2V_CAST_HH
+# define MLN_FUN_V2V_CAST_HH
+
+/*! \file mln/fun/v2v/cast.hh
+ *
+ * \brief FIXME.
+ */
+
+# include <mln/core/concept/function.hh>
+# include <mln/value/cast.hh>
+
+
+namespace mln
+{
+
+ namespace fun
+ {
+
+ namespace v2v
+ {
+
+ // FIXME: Doc!
+
+ template <typename V>
+ struct cast : public Function_v2v< cast<V> >
+ {
+ typedef V result;
+
+ template <typename W>
+ V operator()(const W& w) const;
+ };
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename V>
+ template <typename W>
+ V
+ cast<V>::operator()(const W& w) const
+ {
+ return mln::value::cast<V>(w);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::fun::v2v
+
+ } // end of namespace mln::fun
+
+} // end of namespace mln
+
+
+#endif // ! MLN_FUN_V2V_CAST_HH
Index: mln/morpho/thickening.hh
--- mln/morpho/thickening.hh (revision 1405)
+++ mln/morpho/thickening.hh (working copy)
@@ -47,26 +47,30 @@
*
* This operator is THICK_B = Id + HMT_B, where B = (Bfg, Bbg).
*/
- template <typename I, typename Wfg, typename Wbg, typename O>
- void thickening(const Image<I>& input,
- const Window<Wfg>& win_fg, const Window<Wbg>& win_bg,
- Image<O>& output);
+ template <typename I, typename Wfg, typename Wbg>
+ mln_concrete(I)
+ thickening(const Image<I>& input,
+ const Window<Wfg>& win_fg, const Window<Wbg>& win_bg);
# ifndef MLN_INCLUDE_ONLY
- template <typename I, typename Wfg, typename Wbg, typename O>
- void thickening(const Image<I>& input,
- const Window<Wfg>& win_fg, const Window<Wbg>& win_bg,
- Image<O>& output)
+ template <typename I, typename Wfg, typename Wbg>
+ mln_concrete(I)
+ thickening(const Image<I>& input,
+ const Window<Wfg>& win_fg, const Window<Wbg>& win_bg)
{
- mln_precondition(exact(output).domain() = exact(input).domain());
+ trace::entering("morpho::thickening");
+ mln_precondition(exact(input).has_data());
mln_precondition(exact(win_bg).is_centered());
+ mln_precondition(! exact(win_fg).is_empty());
mln_precondition(set::inter(exact(win_fg), exact(win_bg)).is_empty());
- O temp(exact(input).domain());
- hit_or_miss(input, win_fg, win_bg, temp);
- morpho::plus(input, temp, output);
+ mln_concrete(I) output = morpho::plus( input,
+ hit_or_miss(input, win_fg, win_bg) );
+
+ trace::exiting("morpho::thickening");
+ return output;
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/morpho/plus.hh
--- mln/morpho/plus.hh (revision 1405)
+++ mln/morpho/plus.hh (working copy)
@@ -49,16 +49,16 @@
/*! Morphological plus: either a "logical or" (if morpho on sets)
* or an "arithmetical plus" (if morpho on functions).
*/
- template <typename I, typename J, typename O>
- void plus(const Image<I>& lhs, const Image<J>& rhs,
- Image<O>& output);
-
- /*! Morphological plus, inplace version: either a "logical or" (if
- * morpho on sets) or an "arithmetical plus" (if morpho on
- * functions).
- */
template <typename I, typename J>
- void plus_inplace(Image<I>& lhs, const Image<J>& rhs);
+ mln_concrete(I) plus(const Image<I>& lhs, const Image<J>& rhs);
+
+
+// /*! Morphological plus, inplace version: either a "logical or" (if
+// * morpho on sets) or an "arithmetical plus" (if morpho on
+// * functions).
+// */
+// template <typename I, typename J>
+// void plus_inplace(Image<I>& lhs, const Image<J>& rhs);
# ifndef MLN_INCLUDE_ONLY
@@ -66,20 +66,22 @@
namespace impl
{
- template <typename I, typename J, typename O>
- void plus_(trait::image::kind::logic, // binary => morphology on sets
- const Image<I>& lhs, const Image<J>& rhs,
- Image<O>& output)
+ // Binary => morphology on sets.
+
+ template <typename I, typename J>
+ mln_concrete(I) plus_(trait::image::kind::logic,
+ const I& lhs, const J& rhs)
{
- return logical::or_(lhs, rhs, output);
+ return logical::or_(lhs, rhs);
}
- template <typename K, typename I, typename J, typename O>
- void plus_(K, // otherwise => morphology on functions
- const Image<I>& lhs, const Image<J>& rhs,
- Image<O>& output)
+ // Otherwise => morphology on functions.
+
+ template <typename I, typename J>
+ mln_concrete(I) plus_(trait::image::kind::any,
+ const I& lhs, const J& rhs)
{
- return arith::plus(lhs, rhs, output);
+ return arith::plus<mln_value(I)>(lhs, rhs);
}
} // end of namespace mln::morpho::impl
@@ -87,21 +89,26 @@
// Facades.
- template <typename I, typename J, typename O>
- void plus(const Image<I>& lhs, const Image<J>& rhs,
Image<O>& output)
- {
- mln_precondition(exact(rhs).domain() = exact(lhs).domain());
- mln_precondition(exact(output).domain() = exact(lhs).domain());
- impl::plus_(mln_trait_image_kind(I)(), exact(lhs), exact(rhs), output);
- }
-
template <typename I, typename J>
- void plus_inplace(Image<I>& lhs, const Image<J>& rhs)
+ mln_concrete(I) plus(const Image<I>& lhs, const Image<J>& rhs)
{
+ trace::entering("morpho::plus");
mln_precondition(exact(rhs).domain() = exact(lhs).domain());
- morpho::plus(lhs, rhs, lhs); // Calls the previous version.
+
+ mln_concrete(I) output = impl::plus_(mln_trait_image_kind(I)(),
+ exact(lhs), exact(rhs));
+
+ trace::exiting("morpho::plus");
+ return output;
}
+// template <typename I, typename J>
+// void plus_inplace(Image<I>& lhs, const Image<J>& rhs)
+// {
+// mln_precondition(exact(rhs).domain() = exact(lhs).domain());
+// morpho::plus(lhs, rhs, lhs); // Calls the previous version.
+// }
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::morpho
Index: mln/morpho/min.hh
--- mln/morpho/min.hh (revision 1405)
+++ mln/morpho/min.hh (working copy)
@@ -49,9 +49,10 @@
/*! Morphological min: either a logical "and" (if morpho on sets)
* or an arithmetical min (if morpho on functions).
*/
- template <typename I, typename J, typename O>
- void min(const Image<I>& lhs, const Image<J>& rhs,
- Image<O>& output);
+ template <typename I, typename J>
+ mln_concrete(I)
+ min(const Image<I>& lhs, const Image<J>& rhs);
+
/*! Morphological min, inplace version: either a logical "and" (if
* morpho on sets) or an arithmetical min (if morpho on
@@ -66,36 +67,36 @@
namespace impl
{
+ // Binary => morphology on sets.
+
template <typename I, typename J, typename O>
- void min_(trait::image::kind::logic, // binary => morphology on sets
- const Image<I>& lhs, const Image<J>& rhs,
- Image<O>& output)
+ mln_concrete(I) min_(trait::image::kind::logic,
+ const I& lhs, const J& rhs)
{
- return logical::and_(lhs, rhs, output);
+ return logical::and_(lhs, rhs);
}
- template <typename K, typename I, typename J, typename O>
- void min_(K, // otherwise => morphology on functions
- const Image<I>& lhs, const Image<J>& rhs,
- Image<O>& output)
+ template <typename I, typename J>
+ void min_inplace_(trait::image::kind::logic,
+ I& lhs, const J& rhs)
{
- return arith::min(lhs, rhs, output);
+ logical::and_inplace(lhs, rhs);
}
- // in place
+ // Otherwise => morphology on functions.
template <typename I, typename J>
- void min_inplace_(trait::image::kind::logic, // binary => morphology on sets
- Image<I>& lhs, const Image<J>& rhs)
+ mln_concrete(I) min_(trait::image::kind::any,
+ const I& lhs, const J& rhs)
{
- return logical::and_inplace(lhs, rhs);
+ return arith::min(lhs, rhs);
}
- template <typename K, typename I, typename J>
- void min_inplace_(K, // otherwise => morphology on functions
- Image<I>& lhs, const Image<J>& rhs)
+ template <typename I, typename J>
+ void min_inplace_(trait::image::kind::any,
+ I& lhs, const J& rhs)
{
- return arith::min_inplace(lhs, rhs);
+ arith::min_inplace(lhs, rhs);
}
} // end of namespace mln::morpho::impl
@@ -103,19 +104,28 @@
// Facades.
- template <typename I, typename J, typename O>
- void min(const Image<I>& lhs, const Image<J>& rhs,
Image<O>& output)
+ template <typename I, typename J>
+ mln_concrete(I)
+ min(const Image<I>& lhs, const Image<J>& rhs)
{
+ trace::entering("morpho::min");
mln_precondition(exact(rhs).domain() = exact(lhs).domain());
- mln_precondition(exact(output).domain() = exact(lhs).domain());
- impl::min_(mln_trait_image_kind(I)(), exact(lhs), exact(rhs), output);
+
+ mln_concrete(I) output = impl::min_(mln_trait_image_kind(I)(), exact(lhs),
exact(rhs));
+
+ trace::exiting("morpho::min");
+ return output;
}
template <typename I, typename J>
void min_inplace(Image<I>& lhs, const Image<J>& rhs)
{
+ trace::entering("morpho::min_inplace");
mln_precondition(exact(rhs).domain() = exact(lhs).domain());
+
impl::min_inplace_(mln_trait_image_kind(I)(), exact(lhs), exact(rhs));
+
+ trace::exiting("morpho::min_inplace_");
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/morpho/laplacian.hh
--- mln/morpho/laplacian.hh (revision 1405)
+++ mln/morpho/laplacian.hh (working copy)
@@ -53,24 +53,42 @@
Image<O>& output);
+ template <typename I, typename W>
+ mln_trait_op_minus_twice(mln_concrete(I))
+ laplacian(const Image<I>& input, const Window<W>& win);
+
+
# ifndef MLN_INCLUDE_ONLY
template <typename I, typename W, typename O>
void laplacian(const Image<I>& input, const Window<W>& win,
Image<O>& output)
{
+ trace::entering("morpho::laplacian");
mln_precondition(exact(output).domain() = exact(input).domain());
mln_precondition(! exact(win).is_empty());
- dilation(input, win, output); // output = dilation
- morpho::minus_inplace(output, input); // now output = dilation - input
+ mln_concrete(I)
+ d_I = morpho::minus(dilation(input, win), input),
+ e_I = morpho::minus(input, erosion(input, win));
+ level::fill(output, d_I - e_I);
- O temp(exact(input).domain());
- {
- O temp_(exact(input).domain());
- erosion(input, win, temp_); // temp_ = erosion
- morpho::minus(input, temp_, temp); // temp = input - erosion
+ trace::exiting("morpho::laplacian");
}
- morpho::minus_inplace(output, temp); // now output = (dilation - input) - (input -
erosion)
+
+ template <typename I, typename W>
+ mln_trait_op_minus_twice(mln_concrete(I))
+ laplacian(const Image<I>& input, const Window<W>& win)
+ {
+ trace::entering("morpho::laplacian");
+ mln_precondition(exact(input).has_data());
+ mln_precondition(! exact(win).is_empty());
+
+ mln_trait_op_minus_twice(mln_concrete(I)) output;
+ initialize(output, input);
+ laplacian(input, win, output); // Calls previous version.
+
+ trace::exiting("morpho::laplacian");
+ return output;
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/morpho/minus.hh
--- mln/morpho/minus.hh (revision 1405)
+++ mln/morpho/minus.hh (working copy)
@@ -49,16 +49,16 @@
/*! Morphological minus: either a logical "and not" (if morpho on
* sets) or an arithmetical minus (if morpho on functions).
*/
- template <typename I, typename J, typename O>
- void minus(const Image<I>& lhs, const Image<J>& rhs,
- Image<O>& output);
-
- /*! Morphological minus, inplace version: either a logical "and
- * not" (if morpho on sets) or an arithmetical minus (if morpho
- * on functions).
- */
template <typename I, typename J>
- void minus_inplace(Image<I>& lhs, const Image<J>& rhs);
+ mln_concrete(I) minus(const Image<I>& lhs, const Image<J>& rhs);
+
+
+// /*! Morphological minus, inplace version: either a logical "and
+// * not" (if morpho on sets) or an arithmetical minus (if morpho
+// * on functions).
+// */
+// template <typename I, typename J>
+// void minus_inplace(Image<I>& lhs, const Image<J>& rhs);
# ifndef MLN_INCLUDE_ONLY
@@ -66,20 +66,22 @@
namespace impl
{
- template <typename I, typename J, typename O>
- void minus_(trait::image::kind::logic, // binary => morphology on sets
- const Image<I>& lhs, const Image<J>& rhs,
- Image<O>& output)
+ // Binary => morphology on sets.
+
+ template <typename I, typename J>
+ mln_concrete(I) minus_(trait::image::kind::logic,
+ const I& lhs, const J& rhs)
{
- return logical::and_not(lhs, rhs, output);
+ return logical::and_not(lhs, rhs);
}
- template <typename K, typename I, typename J, typename O>
- void minus_(K, // otherwise => morphology on functions
- const Image<I>& lhs, const Image<J>& rhs,
- Image<O>& output)
+ // Otherwise => morphology on functions.
+
+ template <typename I, typename J>
+ mln_concrete(I) minus_(trait::image::kind::any,
+ const I& lhs, const J& rhs)
{
- return arith::minus(lhs, rhs, output);
+ return arith::minus<mln_value(I)>(lhs, rhs);
}
} // end of namespace mln::morpho::impl
@@ -87,21 +89,27 @@
// Facades.
- template <typename I, typename J, typename O>
- void minus(const Image<I>& lhs, const Image<J>& rhs,
Image<O>& output)
- {
- mln_precondition(exact(rhs).domain() = exact(lhs).domain());
- mln_precondition(exact(output).domain() = exact(lhs).domain());
- impl::minus_(mln_trait_image_kind(I)(), exact(lhs), exact(rhs), output);
- }
-
template <typename I, typename J>
- void minus_inplace(Image<I>& lhs, const Image<J>& rhs)
+ mln_concrete(I)
+ minus(const Image<I>& lhs, const Image<J>& rhs)
{
+ trace::entering("morpho::minus");
mln_precondition(exact(rhs).domain() = exact(lhs).domain());
- morpho::minus(lhs, rhs, lhs); // Calls the previous version.
+
+ mln_concrete(I) output = impl::minus_(mln_trait_image_kind(I)(),
+ exact(lhs), exact(rhs));
+
+ trace::exiting("morpho::minus");
+ return output;
}
+// template <typename I, typename J>
+// void minus_inplace(Image<I>& lhs, const Image<J>& rhs)
+// {
+// mln_precondition(exact(rhs).domain() = exact(lhs).domain());
+// morpho::minus(lhs, rhs, lhs); // Calls the previous version.
+// }
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::morpho
Index: mln/morpho/gradient.hh
--- mln/morpho/gradient.hh (revision 1405)
+++ mln/morpho/gradient.hh (working copy)
@@ -48,82 +48,73 @@
*
* This operator is d_B - e_B.
*/
- template <typename I, typename W, typename O>
- void gradient(const Image<I>& input, const Window<W>& win,
- Image<O>& output);
+ template <typename I, typename W>
+ mln_concrete(I) gradient(const Image<I>& input, const Window<W>&
win);
/*! Morphological internal gradient.
*
* This operator is Id - e_B.
*/
- template <typename I, typename W, typename O>
- void gradient_internal(const Image<I>& input, const Window<W>&
win,
- Image<O>& output);
+ template <typename I, typename W>
+ mln_concrete(I) gradient_internal(const Image<I>& input, const
Window<W>& win);
/*! Morphological external gradient.
*
* This operator is d_B - Id.
*/
- template <typename I, typename W, typename O>
- void gradient_external(const Image<I>& input, const Window<W>&
win,
- Image<O>& output);
+ template <typename I, typename W>
+ mln_concrete(I) gradient_external(const Image<I>& input, const
Window<W>& win);
# ifndef MLN_INCLUDE_ONLY
- template <typename I, typename W, typename O>
- void gradient(const Image<I>& input_, const Window<W>& win_,
Image<O>& output_)
+ template <typename I, typename W>
+ mln_concrete(I) gradient(const Image<I>& input, const Window<W>&
win)
{
- const I& input = exact(input_);
- const W& win = exact(win_);
- O& output = exact(output_);
-
- mln_precondition(output.domain() = input.domain());
- mln_precondition(! win.is_empty());
-
- dilation(input, win, output); // output = dilation
- O temp(input.domain());
- erosion(input, win, temp); // temp = erosion
- morpho::minus_inplace(output, temp); // now output = dilation - erosion
+ trace::entering("morpho::gradient");
+ mln_precondition(exact(input).has_data());
+ mln_precondition(! exact(win).is_empty());
+
+ mln_concrete(I) output = morpho::minus(dilation(input, win),
+ erosion(input, win));
mln_postcondition(test::positive(output));
+ trace::exiting("morpho::gradient");
+ return output;
}
- template <typename I, typename W, typename O>
- void gradient_internal(const Image<I>& input_, const Window<W>&
win_,
- Image<O>& output_)
+
+ template <typename I, typename W>
+ mln_concrete(I) gradient_internal(const Image<I>& input, const
Window<W>& win)
{
- const I& input = exact(input_);
- const W& win = exact(win_);
- O& output = exact(output_);
-
- mln_precondition(output.domain() = input.domain());
- mln_precondition(! win.is_empty());
-
- O temp(input.domain());
- erosion(input, win, temp); // temp = erosion
- morpho::minus(input, temp, output); // output = input - erosion
+ trace::entering("morpho::gradient_internal");
+ mln_precondition(exact(input).has_data());
+ mln_precondition(! exact(win).is_empty());
+
+ mln_concrete(I) output = morpho::minus(input,
+ erosion(input, win));
mln_postcondition(test::positive(output));
+ trace::exiting("morpho::gradient_internal");
+ return output;
}
- template <typename I, typename W, typename O>
- void gradient_external(const Image<I>& input_, const Window<W>&
win_,
- Image<O>& output_)
- {
- const I& input = exact(input_);
- const W& win = exact(win_);
- O& output = exact(output_);
- mln_precondition(output.domain() = input.domain());
- mln_precondition(! win.is_empty());
+ template <typename I, typename W>
+ mln_concrete(I) gradient_external(const Image<I>& input, const
Window<W>& win)
+ {
+ trace::entering("morpho::gradient_external");
+ mln_precondition(exact(input).has_data());
+ mln_precondition(! exact(win).is_empty());
- dilation(input, win, output); // output = dilation
- morpho::minus_inplace(output, input); // now output = dilation - input
+ mln_concrete(I) output = morpho::minus(dilation(input, win),
+ input);
mln_postcondition(test::positive(output));
+ trace::exiting("morpho::gradient_external");
+ return output;
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/morpho/contrast.hh
--- mln/morpho/contrast.hh (revision 1405)
+++ mln/morpho/contrast.hh (working copy)
@@ -48,28 +48,25 @@
*
* This operator is Id + wth_B - bth_B.
*/
- template <typename I, typename W, typename O>
- void contrast(const Image<I>& input, const Window<W>& win,
- Image<O>& output);
+ template <typename I, typename W>
+ mln_concrete(I) contrast(const Image<I>& input, const Window<W>&
win);
# ifndef MLN_INCLUDE_ONLY
- template <typename I, typename W, typename O>
- void contrast(const Image<I>& input_, const Window<W>& win_,
Image<O>& output_)
+ template <typename I, typename W>
+ mln_concrete(I) contrast(const Image<I>& input, const Window<W>&
win)
{
- const I& input = exact(input_);
- const W& win = exact(win_);
- O& output = exact(output_);
-
- mln_precondition(output.domain() = input.domain());
- mln_precondition(! win.is_empty());
-
- top_hat_white(input, win, output); // output = wth
- morpho::plus_inplace(output, input); // now output = wth + input
- O temp(input.domain());
- top_hat_black(input, win, temp); // temp = bth
- morpho::minus_inplace(output, temp); // now output = wth + input - bth
+ trace::entering("morpho::contrast");
+ mln_precondition(exact(input).has_data());
+ mln_precondition(! exact(win).is_empty());
+
+ mln_concrete(I) output = arith::plus( input,
+ top_hat_white(input, win) - top_hat_black(input, win),
+ fun::v2v::saturate<mln_value(I)>() );
+
+ trace::exiting("morpho::contrast");
+ return output;
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/morpho/thick_miss.hh
--- mln/morpho/thick_miss.hh (revision 1405)
+++ mln/morpho/thick_miss.hh (working copy)
@@ -47,26 +47,31 @@
*
* This operator is THICK_B = Id + HMTopeBG_B, where B = (Bfg, Bbg).
*/
- template <typename I, typename Wfg, typename Wbg, typename O>
- void thick_miss(const Image<I>& input,
- const Window<Wfg>& win_fg, const Window<Wbg>& win_bg,
- Image<O>& output);
+ template <typename I, typename Wfg, typename Wbg>
+ mln_concrete(I)
+ thick_miss(const Image<I>& input,
+ const Window<Wfg>& win_fg, const Window<Wbg>& win_bg);
# ifndef MLN_INCLUDE_ONLY
- template <typename I, typename Wfg, typename Wbg, typename O>
- void thick_miss(const Image<I>& input,
- const Window<Wfg>& win_fg, const Window<Wbg>& win_bg,
- Image<O>& output)
+ template <typename I, typename Wfg, typename Wbg>
+ mln_concrete(I)
+ thick_miss(const Image<I>& input,
+ const Window<Wfg>& win_fg, const Window<Wbg>& win_bg)
{
+ trace::entering("morpho::thick_miss");
mln_precondition(exact(output).domain() = exact(input).domain());
mln_precondition(exact(win_miss).is_centered());
mln_precondition(set::inter(exact(win_fg), exact(win_bg)).is_empty());
- O temp(exact(input).domain());
- hit_or_miss_background_opening(input, win_fg, win_bg, temp);
- morpho::plus(input, temp, output);
+ mln_concrete(I)
+ output = morpho::plus( input,
+ hit_or_miss_background_opening(input,
+ win_fg, win_bg) );
+
+ trace::exiting("morpho::thick_miss");
+ return output;
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/morpho/closing.hh
--- mln/morpho/closing.hh (revision 1405)
+++ mln/morpho/closing.hh (working copy)
@@ -46,27 +46,24 @@
*
* This operator is e_{-B} o d_B.
*/
- template <typename I, typename W, typename O>
- void closing(const Image<I>& input, const Window<W>& win,
Image<O>& output);
+ template <typename I, typename W>
+ mln_concrete(I) closing(const Image<I>& input, const Window<W>&
win);
# ifndef MLN_INCLUDE_ONLY
- template <typename I, typename W, typename O>
- void closing(const Image<I>& input_, const Window<W>& win_,
Image<O>& output_)
+ template <typename I, typename W>
+ mln_concrete(I) closing(const Image<I>& input, const Window<W>&
win)
{
- const I& input = exact(input_);
- const W& win = exact(win_);
- O& output = exact(output_);
-
- mln_precondition(output.domain() = input.domain());
- mln_precondition(! win.is_empty());
-
- O temp(input.domain());
- dilation(input, win, temp);
- erosion(temp, geom::sym(win), output);
+ trace::entering("morpho::closing");
+ mln_precondition(exact(input).has_data());
+ mln_precondition(! exact(win).is_empty());
+
+ mln_concrete(I) output = erosion(dilation(input, win), geom::sym(win));
mln_postcondition(output >= input);
+ trace::exiting("morpho::closing");
+ return output;
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/morpho/top_hat.hh
--- mln/morpho/top_hat.hh (revision 1405)
+++ mln/morpho/top_hat.hh (working copy)
@@ -49,18 +49,18 @@
*
* This operator is Id - ope_B.
*/
- template <typename I, typename W, typename O>
- void top_hat_white(const Image<I>& input, const Window<W>& win,
- Image<O>& output);
+ template <typename I, typename W>
+ mln_concrete(I)
+ top_hat_white(const Image<I>& input, const Window<W>& win);
/*! Morphological black top-hat (for background / dark objects).
*
* This operator is clo_B - Id.
*/
- template <typename I, typename W, typename O>
- void top_hat_black(const Image<I>& input, const Window<W>& win,
- Image<O>& output);
+ template <typename I, typename W>
+ mln_concrete(I)
+ top_hat_black(const Image<I>& input, const Window<W>& win);
/*! Morphological self-complementary top-hat.
@@ -70,62 +70,56 @@
* = (input - opening) + (closing - input) \n
* = closing - opening. \n
*/
- template <typename I, typename W, typename O>
- void top_hat_self_complementary(const Image<I>& input, const
Window<W>& win,
- Image<O>& output);
+ template <typename I, typename W>
+ mln_concrete(I)
+ top_hat_self_complementary(const Image<I>& input, const
Window<W>& win);
# ifndef MLN_INCLUDE_ONLY
- template <typename I, typename W, typename O>
- void top_hat_white(const Image<I>& input_, const Window<W>& win_,
Image<O>& output_)
+ template <typename I, typename W>
+ mln_concrete(I) top_hat_white(const Image<I>& input, const
Window<W>& win)
{
- const I& input = exact(input_);
- const W& win = exact(win_);
- O& output = exact(output_);
-
- mln_precondition(output.domain() = input.domain());
- mln_precondition(! win.is_empty());
-
- O temp(input.domain());
- opening(input, win, temp); // temp = opening
- morpho::minus(input, temp, output); // output = input - opening
+ trace::entering("morpho::top_hat_white");
+ mln_precondition(exact(input).has_data());
+ mln_precondition(! exact(win).is_empty());
+
+ mln_concrete(I) output = morpho::minus(input,
+ opening(input, win));
mln_postcondition(test::positive(output));
+ trace::exiting("morpho::top_hat_white");
+ return output;
}
- template <typename I, typename W, typename O>
- void top_hat_black(const Image<I>& input_, const Window<W>& win_,
Image<O>& output_)
+ template <typename I, typename W>
+ mln_concrete(I) top_hat_black(const Image<I>& input, const
Window<W>& win)
{
- const I& input = exact(input_);
- const W& win = exact(win_);
- O& output = exact(output_);
-
- mln_precondition(output.domain() = input.domain());
- mln_precondition(! win.is_empty());
+ trace::entering("morpho::top_hat_black");
+ mln_precondition(exact(input).has_data());
+ mln_precondition(! exact(win).is_empty());
- closing(input, win, output); // output = closing
- morpho::minus_inplace(output, input); // now output = closing - input
+ mln_concrete(I) output = morpho::minus(closing(input, win),
+ input);
mln_postcondition(test::positive(output));
+ trace::exiting("morpho::top_hat_black");
+ return output;
}
- template <typename I, typename W, typename O>
- void top_hat_self_complementary(const Image<I>& input_, const
Window<W>& win_, Image<O>& output_)
+ template <typename I, typename W>
+ mln_concrete(I) top_hat_self_complementary(const Image<I>& input, const
Window<W>& win)
{
- const I& input = exact(input_);
- const W& win = exact(win_);
- O& output = exact(output_);
-
- mln_precondition(output.domain() = input.domain());
- mln_precondition(! win.is_empty());
-
- closing(input, win, output); // output = closing
- O temp(input.domain());
- opening(input, win, temp); // temp = opening
- morpho::minus_inplace(output, temp); // now output = closing - opening
+ trace::entering("morpho::top_hat_self_complementary");
+ mln_precondition(exact(input).has_data());
+ mln_precondition(! exact(win).is_empty());
+
+ mln_concrete(I) output = morpho::minus(closing(input, win),
+ opening(input, win));
mln_postcondition(test::positive(output));
+ trace::exiting("morpho::top_hat_self_complementary");
+ return output;
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/morpho/complementation.hh
--- mln/morpho/complementation.hh (revision 1405)
+++ mln/morpho/complementation.hh (working copy)
@@ -50,8 +50,8 @@
* morpho on sets) or an arithmetical complementation (if morpho
* on functions).
*/
- template <typename I, typename O>
- void complementation(const Image<I>& input, Image<O>& output);
+ template <typename I>
+ mln_concrete(I) complementation(const Image<I>& input);
/*! Morphological complementation, inplace version: either a
@@ -67,20 +67,41 @@
namespace impl
{
- template <typename I, typename O>
- void complementation_(trait::image::kind::logic, // binary => morphology on
sets
- const Image<I>& input,
- Image<O>& output)
+ // Binary => morphology on sets.
+
+ template <typename I>
+ mln_concrete(I)
+ complementation_(trait::image::kind::logic,
+ const Image<I>& input)
+ {
+ return logical::not_(input);
+ }
+
+ template <typename I>
+ void
+ complementation_inplace_(trait::image::kind::logic,
+ Image<I>& input)
+ {
+ logical::not_inplace(input);
+ }
+
+
+ // Otherwise => morphology on functions.
+
+ template <typename I>
+ mln_concrete(I)
+ complementation_(trait::image::kind::any,
+ const Image<I>& input)
{
- return logical::not_(input, output);
+ return arith::revert(input);
}
- template <typename K, typename I, typename O>
- void complementation_(K, // otherwise => morphology on functions
- const Image<I>& input,
- Image<O>& output)
+ template <typename I>
+ void
+ complementation_inplace_(trait::image::kind::any,
+ Image<I>& input)
{
- return arith::revert(input, output);
+ arith::revert_inplace(input);
}
} // end of namespace mln::morpho::impl
@@ -88,18 +109,29 @@
// Facades.
- template <typename I, typename O>
- void complementation(const Image<I>& input, Image<O>& output)
+ template <typename I>
+ mln_concrete(I) complementation(const Image<I>& input)
{
- mln_precondition(exact(output).domain() = exact(input).domain());
- impl::complementation_(mln_trait_image_kind(I)(), exact(input), output);
+ trace::entering("morpho::complementation");
+ mln_precondition(exact(input).has_data());
+
+ mln_concrete(I) output = impl::complementation_(mln_trait_image_kind(I)(),
+ input);
+
+ trace::exiting("morpho::complementation");
+ return output;
}
template <typename I>
void complementation_inplace(Image<I>& input)
{
+ trace::entering("morpho::complementation_inplace");
mln_precondition(exact(input).has_data());
- morpho::complementation(input, input); // Calls the previous version.
+
+ impl::complementation_inplace_(mln_trait_image_kind(I)(),
+ input);
+
+ trace::exiting("morpho::complementation_inplace");
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/morpho/opening.hh
--- mln/morpho/opening.hh (revision 1405)
+++ mln/morpho/opening.hh (working copy)
@@ -46,27 +46,24 @@
*
* This operator is d_{-B} o e_B.
*/
- template <typename I, typename W, typename O>
- void opening(const Image<I>& input, const Window<W>& win,
Image<O>& output);
+ template <typename I, typename W>
+ mln_concrete(I) opening(const Image<I>& input, const Window<W>&
win);
# ifndef MLN_INCLUDE_ONLY
- template <typename I, typename W, typename O>
- void opening(const Image<I>& input_, const Window<W>& win_,
Image<O>& output_)
+ template <typename I, typename W>
+ mln_concrete(I) opening(const Image<I>& input, const Window<W>&
win)
{
- const I& input = exact(input_);
- const W& win = exact(win_);
- O& output = exact(output_);
-
- mln_precondition(output.domain() = input.domain());
- mln_precondition(! win.is_empty());
-
- O temp(input.domain());
- erosion(input, win, temp);
- dilation(temp, geom::sym(win), output);
+ trace::entering("morpho::opening");
+ mln_precondition(exact(input).has_data());
+ mln_precondition(! exact(win).is_empty());
+
+ mln_concrete(I) output = dilation(erosion(input, win), geom::sym(win));
mln_postcondition(output <= input);
+ trace::exiting("morpho::opening");
+ return output;
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/morpho/dilation.hh
--- mln/morpho/dilation.hh (revision 1405)
+++ mln/morpho/dilation.hh (working copy)
@@ -51,6 +51,10 @@
template <typename I, typename W, typename O>
void dilation(const Image<I>& input, const Window<W>& win,
Image<O>& output);
+ template <typename I, typename W>
+ mln_concrete(I) dilation(const Image<I>& input, const Window<W>&
win);
+
+
# ifndef MLN_INCLUDE_ONLY
@@ -194,6 +198,20 @@
mln_postcondition(output >= input);
}
+ template <typename I, typename W>
+ mln_concrete(I)
+ dilation(const Image<I>& input, const Window<W>& win)
+ {
+ trace::entering("morpho::dilation");
+
+ mln_concrete(I) output;
+ initialize(output, input);
+ dilation(input, win, output);
+
+ trace::exiting("morpho::dilation");
+ return output;
+ }
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::morpho
Index: mln/morpho/thin_fit.hh
--- mln/morpho/thin_fit.hh (revision 1405)
+++ mln/morpho/thin_fit.hh (working copy)
@@ -47,26 +47,31 @@
*
* This operator is THIN_B = Id - HMTope_B where B = (Bfg, Bbg).
*/
- template <typename I, typename Wfg, typename Wbg, typename O>
- void thin_fit(const Image<I>& input,
- const Window<Wfg>& win_fg, const Window<Wbg>& win_bg,
- Image<O>& output);
+ template <typename I, typename Wfg, typename Wbg>
+ mln_concrete(I)
+ thin_fit(const Image<I>& input,
+ const Window<Wfg>& win_fg, const Window<Wbg>& win_bg);
# ifndef MLN_INCLUDE_ONLY
- template <typename I, typename Wfg, typename Wbg, typename O>
- void thin_fit(const Image<I>& input,
- const Window<Wfg>& win_fg, const Window<Wbg>& win_bg,
- Image<O>& output)
+ template <typename I, typename Wfg, typename Wbg>
+ mln_concrete(I)
+ thin_fit(const Image<I>& input,
+ const Window<Wfg>& win_fg, const Window<Wbg>& win_bg)
{
- mln_precondition(exact(output).domain() = exact(input).domain());
+ trace::entering("morpho::thin_fit");
+ mln_precondition(exact(input).has_data());
mln_precondition(exact(win_fg).is_centered());
mln_precondition(set::inter(exact(win_fg), exact(win_bg)).is_empty());
- O temp(exact(input).domain());
- hit_or_miss_opening(input, win_fg, win_bg, temp);
- morpho::minus(input, temp, output);
+ mln_concrete(I)
+ output = morpho::minus( input,
+ hit_or_miss_opening(input,
+ win_fg, win_bg) );
+
+ trace::exiting("morpho::thin_fit");
+ return output;
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/morpho/includes.hh
--- mln/morpho/includes.hh (revision 1405)
+++ mln/morpho/includes.hh (working copy)
@@ -45,11 +45,12 @@
# include <mln/accu/min_h.hh>
# include <mln/accu/max_h.hh>
+# include <mln/fun/v2v/saturate.hh>
+
# include <mln/level/compare.hh>
# include <mln/level/fill.hh>
# include <mln/test/positive.hh>
-
# include <mln/border/resize.hh>
# include <mln/border/fill.hh>
Index: mln/morpho/thinning.hh
--- mln/morpho/thinning.hh (revision 1405)
+++ mln/morpho/thinning.hh (working copy)
@@ -36,6 +36,8 @@
# include <mln/morpho/hit_or_miss.hh>
# include <mln/morpho/thickening.hh>
+#include <mln/io/pgm/save.hh>
+
namespace mln
{
@@ -48,37 +50,32 @@
*
* This operator is THIN_B = Id - HMT_B, where B = (Bfg, Bbg).
*/
- template <typename I, typename Wfg, typename Wbg, typename O>
- void thinning(const Image<I>& input,
- const Window<Wfg>& win_fg, const Window<Wbg>& win_bg,
- Image<O>& output);
+ template <typename I, typename Wfg, typename Wbg>
+ mln_concrete(I)
+ thinning(const Image<I>& input,
+ const Window<Wfg>& win_fg, const Window<Wbg>& win_bg);
# ifndef MLN_INCLUDE_ONLY
- template <typename I, typename Wfg, typename Wbg, typename O>
- void thinning(const Image<I>& input,
- const Window<Wfg>& win_fg, const Window<Wbg>& win_bg,
- Image<O>& output)
+ template <typename I, typename Wfg, typename Wbg>
+ mln_concrete(I)
+ thinning(const Image<I>& input,
+ const Window<Wfg>& win_fg, const Window<Wbg>& win_bg)
{
- mln_precondition(exact(output).domain() = exact(input).domain());
+ trace::entering("morpho::thinning");
+ mln_precondition(exact(input).has_data());
mln_precondition(exact(win_fg).is_centered());
+ mln_precondition(! exact(win_bg).is_empty());
mln_precondition(set::inter(exact(win_fg), exact(win_bg)).is_empty());
- O temp(exact(input).domain());
- hit_or_miss(input, win_fg, win_bg, temp);
- morpho::minus(input, temp, output);
- // FIXME: Pass postcondition!
-# ifndef NDEBUG
- {
- O temp(exact(input).domain());
- complementation(input, temp);
- O output_(exact(input).domain());
- thickening(temp, win_bg, win_fg, output_);
- complementation_inplace(output_);
- mln_postcondition(output_ = output);
- }
-# endif // ! NDEBUG
+ mln_concrete(I) output = morpho::minus( input,
+ hit_or_miss(input, win_fg, win_bg) );
+
+ mln_postcondition( complementation( thickening( complementation(input),
+ win_bg, win_fg ) ) = output);
+ trace::exiting("morpho::thinning");
+ return output;
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/morpho/hit_or_miss.hh
--- mln/morpho/hit_or_miss.hh (revision 1405)
+++ mln/morpho/hit_or_miss.hh (working copy)
@@ -38,6 +38,7 @@
# include <mln/morpho/includes.hh>
# include <mln/pw/all.hh>
# include <mln/fun/p2v/ternary.hh>
+# include <mln/fun/cast.hh>
# include <mln/literal/zero.hh>
@@ -55,46 +56,51 @@
*
* This operator is HMT_(Bh,Bm) = e_Bh /\ (e_Bm o C).
*/
- template <typename I, typename Wh, typename Wm, typename O>
- void hit_or_miss(const Image<I>& input,
- const Window<Wh>& win_hit, const Window<Wm>& win_miss,
- Image<O>& output);
+ template <typename I, typename Wh, typename Wm>
+ mln_concrete(I)
+ hit_or_miss(const Image<I>& input,
+ const Window<Wh>& win_hit, const Window<Wm>& win_miss);
+
/*! Morphological hit-or-miss opening.
*
* This operator is HMTope_(Bh,Bm) = d_(-Bh) o HMT_(Bh,Bm).
*/
- template <typename I, typename Wh, typename Wm, typename O>
- void hit_or_miss_opening(const Image<I>& input,
- const Window<Wh>& win_hit, const Window<Wm>& win_miss,
- Image<O>& output);
+ template <typename I, typename Wh, typename Wm>
+ mln_concrete(I)
+ hit_or_miss_opening(const Image<I>& input,
+ const Window<Wh>& win_hit, const Window<Wm>& win_miss);
+
/*! Morphological hit-or-miss opening of the background.
*
* This operator is HMTopeBG = HMTope_(Bm,Bh) o C = d_(-Bm) o HMT_(Bh,Bm).
*/
- template <typename I, typename Wh, typename Wm, typename O>
- void hit_or_miss_background_opening(const Image<I>& input,
- const Window<Wh>& win_hit, const Window<Wm>& win_miss,
- Image<O>& output);
+ template <typename I, typename Wh, typename Wm>
+ mln_concrete(I)
+ hit_or_miss_background_opening(const Image<I>& input,
+ const Window<Wh>& win_hit, const Window<Wm>& win_miss);
+
/*! Morphological hit-or-miss closing.
*
* This operator is C o HMTope o C.
*/
- template <typename I, typename Wh, typename Wm, typename O>
- void hit_or_miss_closing(const Image<I>& input,
- const Window<Wh>& win_hit, const Window<Wm>& win_miss,
- Image<O>& output);
+ template <typename I, typename Wh, typename Wm>
+ mln_concrete(I)
+ hit_or_miss_closing(const Image<I>& input,
+ const Window<Wh>& win_hit, const Window<Wm>& win_miss);
+
/*! Morphological hit-or-miss closing of the background.
*
* This operator is C o HMTopeBG o C.
*/
- template <typename I, typename Wh, typename Wm, typename O>
- void hit_or_miss_background_closing(const Image<I>& input,
- const Window<Wh>& win_hit, const Window<Wm>& win_miss,
- Image<O>& output);
+ template <typename I, typename Wh, typename Wm>
+ mln_concrete(I)
+ hit_or_miss_background_closing(const Image<I>& input,
+ const Window<Wh>& win_hit, const Window<Wm>& win_miss);
+
# ifndef MLN_INCLUDE_ONLY
@@ -102,164 +108,172 @@
namespace impl
{
+
// Preconditions.
- template <typename I, typename Wh, typename Wm, typename O>
+ template <typename I, typename Wh, typename Wm>
void hit_or_miss_preconditions_(const Image<I>& input,
- const Window<Wh>& win_hit, const Window<Wm>& win_miss,
- Image<O>& output)
+ const Window<Wh>& win_hit, const Window<Wm>& win_miss)
{
- mln_precondition(exact(output).domain() = exact(input).domain());
+ mln_precondition(exact(input).has_data());
mln_precondition(set::inter(exact(win_hit), exact(win_miss)).is_empty());
}
+
// On sets.
- template <typename I, typename Wh, typename Wm, typename O>
- void hit_or_miss_(trait::image::kind::logic, // binary => morphology on sets
- const Image<I>& input,
- const Window<Wh>& win_hit, const Window<Wm>& win_miss,
- Image<O>& output)
+ template <typename I, typename Wh, typename Wm>
+ mln_concrete(I)
+ hit_or_miss_(trait::image::kind::logic,
+ const I& input,
+ const Wh& win_hit, const Wm& win_miss)
{
- erosion(input, win_hit, output); // output = ero(input)_hit
-
- O temp_1(exact(input).domain());
- complementation(input, temp_1); // temp1 = C(input)
-
- O temp_2(exact(input).domain());
- erosion(temp_1, win_miss, temp_2); // temp_2 = ero(C(input))_miss
-
- logical::and_inplace(output, temp_2); // output = ero(input)_hit /\ ero(C(input))_miss
+ return logical::and_(erosion(input, win_hit),
+ erosion(complementation(input), win_miss));
}
+
// On functions.
- template <typename K,
- typename I, typename Wh, typename Wm, typename O>
- void hit_or_miss_(K, // otherwise => morphology on functions
- const Image<I>& input,
- const Window<Wh>& win_hit, const Window<Wm>& win_miss,
- Image<O>& output)
+ template <typename I, typename Wh, typename Wm>
+ mln_concrete(I)
+ hit_or_miss_(trait::image::kind::any,
+ const I& input,
+ const Wh& win_hit, const Wm& win_miss)
{
- typedef mln_value(O) V;
+ typedef mln_value(I) V;
+ mln_value(I) zero_V = literal::zero;
+
+ mln_concrete(I) output;
+ initialize(output, input);
if (constrained_hit_or_miss) // CHMT.
{
- if (exact(win_hit).is_centered())
+ if (win_hit.is_centered())
{
- O ero_fg(exact(input).domain()), dil_bg(exact(input).domain());
- erosion(input, win_hit, ero_fg);
- dilation(input, win_miss, dil_bg);
+ mln_concrete(I)
+ ero_fg = erosion(input, win_hit),
+ dil_bg = dilation(input, win_miss);
level::fill(output,
fun::p2v::ternary(pw::value(input) = pw::value(ero_fg)
&& pw::value(dil_bg) < pw::value(input),
- pw::value(input) - pw::value(dil_bg),
- pw::cst( V(literal::zero) )));
-
- // FIXME: Replace 'pw::cst(V::zero)' by 'pw::cst(V(literal::zero))'
- // FIXME: and then by 'literal::zero'!
+ fun::cast<V>(pw::value(input) - pw::value(dil_bg)),
+ pw::cst(zero_V)));
}
- else if (exact(win_miss).is_centered())
+ else if (win_miss.is_centered())
{
- O ero_bg(exact(input).domain()), dil_fg(exact(input).domain());
- erosion(input, win_miss, ero_bg);
- dilation(input, win_hit, dil_fg);
+ mln_concrete(I)
+ ero_bg = erosion(input, win_miss),
+ dil_fg = dilation(input, win_hit);
level::fill(output,
fun::p2v::ternary(pw::value(input) = pw::value(dil_fg)
&& pw::value(ero_bg) > pw::value(input),
- pw::value(ero_bg) - pw::value(input),
- pw::cst( V(literal::zero) )));
+ fun::cast<V>(pw::value(ero_bg) - pw::value(input)),
+ pw::cst(zero_V)));
}
else
- level::fill(output, V(literal::zero));
+ level::fill(output, zero_V);
}
else // Unconstrained: UHMT.
{
- O ero(exact(input).domain()), dil(exact(input).domain());
- erosion(input, win_hit, ero);
- dilation(input, win_miss, dil);
+ mln_concrete(I)
+ ero = erosion(input, win_hit),
+ dil = dilation(input, win_miss);
level::fill(output,
fun::p2v::ternary(pw::value(dil) < pw::value(ero),
- pw::value(ero) - pw::value(dil),
- pw::cst( V(literal::zero) )));
+ fun::cast<V>(pw::value(ero) - pw::value(dil)),
+ pw::cst(zero_V)));
}
+
+ return output;
}
+
} // end of mln::morpho::impl
- template <typename I, typename Wh, typename Wm, typename O>
- void hit_or_miss(const Image<I>& input,
- const Window<Wh>& win_hit, const Window<Wm>& win_miss,
- Image<O>& output)
+
+ template <typename I, typename Wh, typename Wm>
+ mln_concrete(I)
+ hit_or_miss(const Image<I>& input,
+ const Window<Wh>& win_hit, const Window<Wm>& win_miss)
+ {
+ trace::entering("morpho::hit_or_miss");
+ impl::hit_or_miss_preconditions_(input, win_hit, win_miss);
+
+ mln_concrete(I) output = impl::hit_or_miss_(mln_trait_image_kind(I)(),
+ exact(input),
+ exact(win_hit), exact(win_miss));
+
+ trace::exiting("morpho::hit_or_miss");
+ return output;
+ }
+
+
+ template <typename I, typename Wh, typename Wm>
+ mln_concrete(I)
+ hit_or_miss_opening(const Image<I>& input,
+ const Window<Wh>& win_hit, const Window<Wm>& win_miss)
{
- impl::hit_or_miss_preconditions_(input, win_hit, win_miss, output);
- impl::hit_or_miss_(mln_trait_image_kind(I)(), input, win_hit, win_miss, output);
+ trace::entering("morpho::hit_or_miss_opening");
+ impl::hit_or_miss_preconditions_(input, win_hit, win_miss);
+
+ mln_concrete(I) output = dilation( hit_or_miss(input, win_hit, win_miss),
+ geom::sym(win_hit) );
+
+ trace::exiting("morpho::hit_or_miss_opening");
+ return output;
}
- template <typename I, typename Wh, typename Wm, typename O>
- void hit_or_miss_opening(const Image<I>& input,
- const Window<Wh>& win_hit, const Window<Wm>& win_miss,
- Image<O>& output)
+
+ template <typename I, typename Wh, typename Wm>
+ mln_concrete(I)
+ hit_or_miss_background_opening(const Image<I>& input,
+ const Window<Wh>& win_hit, const Window<Wm>& win_miss)
{
- impl::hit_or_miss_preconditions_(input, win_hit, win_miss, output);
+ trace::entering("morpho::hit_or_miss_background_opening");
+ impl::hit_or_miss_preconditions_(input, win_hit, win_miss);
- O temp(exact(input).domain());
- hit_or_miss(input, win_hit, win_miss, temp);
- dilation(temp, geom::sym(win_hit), output);
- // FIXME: Postcondition.
+ mln_concrete(I) output = hit_or_miss_opening(complementation(input), win_miss,
win_hit);
+
+ mln_postcondition( dilation( hit_or_miss(input, win_hit, win_miss),
+ geom::sym(win_miss) ) = output);
+ trace::exiting("morpho::hit_or_miss_background_opening");
+ return output;
}
- template <typename I, typename Wh, typename Wm, typename O>
- void hit_or_miss_background_opening(const Image<I>& input,
- const Window<Wh>& win_hit, const Window<Wm>& win_miss,
- Image<O>& output)
- {
- impl::hit_or_miss_preconditions_(input, win_hit, win_miss, output);
- O temp(exact(input).domain());
- complementation(input, temp);
- hit_or_miss_opening(temp, win_miss, win_hit, output);
-# ifndef NDEBUG
- {
- O temp(exact(input).domain());
- hit_or_miss(input, win_hit, win_miss, temp);
- O output_(exact(input).domain());
- dilation(temp, geom::sym(win_miss), output_);
- mln_postcondition(output_ = output);
- }
-# endif // ! NDEBUG
- }
-
- template <typename I, typename Wh, typename Wm, typename O>
- void hit_or_miss_closing(const Image<I>& input,
- const Window<Wh>& win_hit, const Window<Wm>& win_miss,
- Image<O>& output)
- {
- impl::hit_or_miss_preconditions_(input, win_hit, win_miss, output);
- I temp(input.domain());
- complementation(input, temp);
- hit_or_miss_opening(temp, win_hit, win_miss, output);
- complementation_inplace(output);
+
+ template <typename I, typename Wh, typename Wm>
+ mln_concrete(I)
+ hit_or_miss_closing(const Image<I>& input,
+ const Window<Wh>& win_hit, const Window<Wm>& win_miss)
+ {
+ trace::entering("morpho::hit_or_miss_closing");
+ impl::hit_or_miss_preconditions_(input, win_hit, win_miss);
+
+ mln_concrete(I) output = complementation( hit_or_miss_opening(
complementation(input),
+ win_hit, win_miss ) );
+
// FIXME: Postcondition.
+ trace::exiting("morpho::hit_or_miss_closing");
+ return output;
}
- template <typename I, typename Wh, typename Wm, typename O>
- void hit_or_miss_background_closing(const Image<I>& input,
- const Window<Wh>& win_hit, const Window<Wm>& win_miss,
- Image<O>& output)
- {
- impl::hit_or_miss_preconditions_(input, win_hit, win_miss, output);
- hit_or_miss_closing(input, win_miss, win_hit, output);
-# ifndef NDEBUG
- {
- O temp(exact(input).domain());
- complementation(input, temp);
- O output_(exact(input).domain());
- hit_or_miss_background_opening(temp, win_hit, win_miss, output_);
- complementation_inplace(output_);
- mln_postcondition(output_ = output);
- }
-# endif // ! NDEBUG
+
+ template <typename I, typename Wh, typename Wm>
+ mln_concrete(I)
+ hit_or_miss_background_closing(const Image<I>& input,
+ const Window<Wh>& win_hit, const Window<Wm>& win_miss)
+ {
+ trace::entering("morpho::hit_or_miss_background_closing");
+ impl::hit_or_miss_preconditions_(input, win_hit, win_miss);
+
+ mln_concrete(I) output = hit_or_miss_closing(input, win_miss, win_hit);
+
+ mln_postcondition( complementation( hit_or_miss_background_opening(
complementation(input),
+ win_hit, win_miss ) ) = output );
+ trace::exiting("morpho::hit_or_miss_background_closing");
+ return output;
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/logical/and.hh
--- mln/logical/and.hh (revision 1405)
+++ mln/logical/and.hh (working copy)
@@ -48,24 +48,24 @@
*
* \param[in] lhs First operand image.
* \param[in] rhs Second operand image.
- * \param[out] output The result image.
+ * \result The result image.
*
- * \pre \p output.domain = \p lhs.domain = \p rhs.domain
+ * \pre \p lhs.domain = \p rhs.domain
*/
- template <typename L, typename R, typename O>
- void and_(const Image<L>& lhs, const Image<R>& rhs,
Image<O>& output);
+ template <typename L, typename R>
+ mln_concrete(L) and_(const Image<L>& lhs, const Image<R>& rhs);
/*! Point-wise in-place "logical and" of image \p rhs in image \p lhs.
*
- * \param[in] lhs First operand image.
- * \param[in,out] rhs Second operand image.
+ * \param[in,out] lhs First operand image.
+ * \param[in] rhs Second operand image.
*
* It performs: \n
* for all p of rhs.domain \n
* lhs(p) = lhs(p) and rhs(p)
*
- * \pre \p rhs.domain <= \p lhs.domain
+ * \pre \p rhs.domain >= \p lhs.domain
*/
template <typename L, typename R>
void and_inplace(Image<L>& lhs, const Image<R>& rhs);
@@ -78,8 +78,7 @@
template <typename L, typename R, typename O>
void and__(trait::image::speed::any, const L& lhs,
- trait::image::speed::any, const R& rhs,
- trait::image::speed::any, O& output)
+ trait::image::speed::any, const R& rhs, O& output)
{
mln_piter(L) p(lhs.domain());
for_all(p)
@@ -88,8 +87,7 @@
template <typename L, typename R, typename O>
void and__(trait::image::speed::fastest, const L& lhs,
- trait::image::speed::fastest, const R& rhs,
- trait::image::speed::fastest, O& output)
+ trait::image::speed::fastest, const R& rhs, O& output)
{
mln_pixter(const L) lp(lhs);
mln_pixter(const R) rp(rhs);
@@ -103,23 +101,31 @@
// Facades.
- template <typename L, typename R, typename O>
- void and_(const Image<L>& lhs, const Image<R>& rhs,
Image<O>& output)
+ template <typename L, typename R>
+ mln_concrete(L) and_(const Image<L>& lhs, const Image<R>& rhs)
{
+ trace::entering("logical::and_");
mln_precondition(exact(rhs).domain() = exact(lhs).domain());
- mln_precondition(exact(output).domain() = exact(lhs).domain());
+
+ mln_concrete(L) output;
+ initialize(output, lhs);
impl::and__(mln_trait_image_speed(L)(), exact(lhs),
- mln_trait_image_speed(R)(), exact(rhs),
- mln_trait_image_speed(O)(), exact(output));
+ mln_trait_image_speed(R)(), exact(rhs), output);
+
+ trace::exiting("logical::and_");
+ return output;
}
template <typename L, typename R>
void and_inplace(Image<L>& lhs, const Image<R>& rhs)
{
- mln_precondition(exact(rhs).domain() <= exact(lhs).domain());
+ trace::entering("logical::and_inplace");
+ mln_precondition(exact(rhs).domain() >= exact(lhs).domain());
+
impl::and__(mln_trait_image_speed(L)(), exact(lhs),
- mln_trait_image_speed(R)(), exact(rhs),
- mln_trait_image_speed(L)(), exact(lhs));
+ mln_trait_image_speed(R)(), exact(rhs), exact(lhs));
+
+ trace::exiting("logical::and_inplace");
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/logical/and_not.hh
--- mln/logical/and_not.hh (revision 1405)
+++ mln/logical/and_not.hh (working copy)
@@ -48,24 +48,24 @@
*
* \param[in] lhs First operand image.
* \param[in] rhs Second operand image.
- * \param[out] output The result image.
+ * \result The result image.
*
- * \pre \p output.domain = \p lhs.domain = \p rhs.domain
+ * \pre \p lhs.domain = \p rhs.domain
*/
- template <typename L, typename R, typename O>
- void and_not(const Image<L>& lhs, const Image<R>& rhs,
Image<O>& output);
+ template <typename L, typename R>
+ mln_concrete(L) and_not(const Image<L>& lhs, const Image<R>&
rhs);
/*! Point-wise in-place logical "and not" of image \p rhs in image \p lhs.
*
- * \param[in] lhs First operand image.
- * \param[in,out] rhs Second operand image.
+ * \param[in,out] lhs First operand image.
+ * \param[in] rhs Second operand image.
*
* It performs: \n
* for all p of rhs.domain \n
* lhs(p) = lhs(p) and not rhs(p)
*
- * \pre \p rhs.domain <= \p lhs.domain
+ * \pre \p rhs.domain >= \p lhs.domain
*/
template <typename L, typename R>
void and_not_inplace(Image<L>& lhs, const Image<R>& rhs);
@@ -78,8 +78,7 @@
template <typename L, typename R, typename O>
void and_not_(trait::image::speed::any, const L& lhs,
- trait::image::speed::any, const R& rhs,
- trait::image::speed::any, O& output)
+ trait::image::speed::any, const R& rhs, O& output)
{
mln_piter(L) p(lhs.domain());
for_all(p)
@@ -88,8 +87,7 @@
template <typename L, typename R, typename O>
void and_not_(trait::image::speed::fastest, const L& lhs,
- trait::image::speed::fastest, const R& rhs,
- trait::image::speed::fastest, O& output)
+ trait::image::speed::fastest, const R& rhs, O& output)
{
mln_pixter(const L) lp(lhs);
mln_pixter(const R) rp(rhs);
@@ -103,23 +101,31 @@
// Facades.
- template <typename L, typename R, typename O>
- void and_not(const Image<L>& lhs, const Image<R>& rhs,
Image<O>& output)
+ template <typename L, typename R>
+ mln_concrete(L) and_not(const Image<L>& lhs, const Image<R>&
rhs)
{
+ trace::entering("logical::and_not");
mln_precondition(exact(rhs).domain() = exact(lhs).domain());
- mln_precondition(exact(output).domain() = exact(lhs).domain());
+
+ mln_concrete(L) output;
+ initialize(output, lhs);
impl::and_not_(mln_trait_image_speed(L)(), exact(lhs),
- mln_trait_image_speed(R)(), exact(rhs),
- mln_trait_image_speed(O)(), exact(output));
+ mln_trait_image_speed(R)(), exact(rhs), output);
+
+ trace::exiting("logical::and_not");
+ return output;
}
template <typename L, typename R>
void and_not_inplace(Image<L>& lhs, const Image<R>& rhs)
{
- mln_precondition(exact(rhs).domain() <= exact(lhs).domain());
+ trace::entering("logical::and_not_inplace");
+ mln_precondition(exact(rhs).domain() >= exact(lhs).domain());
+
impl::and_not_(mln_trait_image_speed(L)(), exact(lhs),
- mln_trait_image_speed(R)(), exact(rhs),
- mln_trait_image_speed(L)(), exact(lhs));
+ mln_trait_image_speed(R)(), exact(rhs), exact(lhs));
+
+ trace::exiting("logical::and_not_inplace");
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/logical/or.hh
--- mln/logical/or.hh (revision 1405)
+++ mln/logical/or.hh (working copy)
@@ -48,24 +48,24 @@
*
* \param[in] lhs First operand image.
* \param[in] rhs Second operand image.
- * \param[out] output The result image.
+ * \result The result image.
*
- * \pre \p output.domain = \p lhs.domain = \p rhs.domain
+ * \pre \p lhs.domain = \p rhs.domain
*/
- template <typename L, typename R, typename O>
- void or_(const Image<L>& lhs, const Image<R>& rhs,
Image<O>& output);
+ template <typename L, typename R>
+ mln_concrete(L) or_(const Image<L>& lhs, const Image<R>& rhs);
/*! Point-wise in-place "logical or" of image \p rhs in image \p lhs.
*
- * \param[in] lhs First operand image.
- * \param[in,out] rhs Second operand image.
+ * \param[in,out] lhs First operand image.
+ * \param[in] rhs Second operand image.
*
* It performs: \n
- * for all p of rhs.domain \n
+ * for all p of lhs.domain \n
* lhs(p) = lhs(p) or rhs(p)
*
- * \pre \p rhs.domain <= \p lhs.domain
+ * \pre \p rhs.domain >= \p lhs.domain
*/
template <typename L, typename R>
void or_inplace(Image<L>& lhs, const Image<R>& rhs);
@@ -78,8 +78,7 @@
template <typename L, typename R, typename O>
void or__(trait::image::speed::any, const L& lhs,
- trait::image::speed::any, const R& rhs,
- trait::image::speed::any, O& output)
+ trait::image::speed::any, const R& rhs, O& output)
{
mln_piter(L) p(lhs.domain());
for_all(p)
@@ -88,8 +87,7 @@
template <typename L, typename R, typename O>
void or__(trait::image::speed::fastest, const L& lhs,
- trait::image::speed::fastest, const R& rhs,
- trait::image::speed::fastest, O& output)
+ trait::image::speed::fastest, const R& rhs, O& output)
{
mln_pixter(const L) lp(lhs);
mln_pixter(const R) rp(rhs);
@@ -103,23 +101,31 @@
// Facades.
- template <typename L, typename R, typename O>
- void or_(const Image<L>& lhs, const Image<R>& rhs,
Image<O>& output)
+ template <typename L, typename R>
+ mln_concrete(L) or_(const Image<L>& lhs, const Image<R>& rhs)
{
+ trace::entering("logical::or_");
mln_precondition(exact(rhs).domain() = exact(lhs).domain());
- mln_precondition(exact(output).domain() = exact(lhs).domain());
+
+ mln_concrete(L) output;
+ initialize(output, lhs);
impl::or__(mln_trait_image_speed(L)(), exact(lhs),
- mln_trait_image_speed(R)(), exact(rhs),
- mln_trait_image_speed(O)(), exact(output));
+ mln_trait_image_speed(R)(), exact(rhs), output);
+
+ trace::exiting("logical::or_");
+ return output;
}
template <typename L, typename R>
void or_inplace(Image<L>& lhs, const Image<R>& rhs)
{
- mln_precondition(exact(rhs).domain() <= exact(lhs).domain());
+ trace::entering("logical::or_inplace");
+ mln_precondition(exact(rhs).domain() >= exact(lhs).domain());
+
impl::or__(mln_trait_image_speed(L)(), exact(lhs),
- mln_trait_image_speed(R)(), exact(rhs),
- mln_trait_image_speed(L)(), exact(lhs));
+ mln_trait_image_speed(R)(), exact(rhs), exact(lhs));
+
+ trace::exiting("logical::or_inplace");
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/logical/not.hh
--- mln/logical/not.hh (revision 1405)
+++ mln/logical/not.hh (working copy)
@@ -47,12 +47,12 @@
/*! Point-wise "logical not" of image \p input.
*
* \param[in] input the input image.
- * \param[out] output The result image.
+ * \result The result image.
*
- * \pre \p output.domain = \p input.domain
+ * \pre \p input.has_data
*/
- template <typename I, typename O>
- void not_(const Image<I>& input, Image<O>& output);
+ template <typename I>
+ mln_concrete(I) not_(const Image<I>& input);
/*! Point-wise in-place "logical not" of image \p input.
@@ -73,8 +73,7 @@
{
template <typename I, typename O>
- void not__(trait::image::speed::any, const I& input,
- trait::image::speed::any, O& output)
+ void not__(trait::image::speed::any, const I& input, O& output)
{
mln_piter(I) p(input.domain());
for_all(p)
@@ -82,8 +81,7 @@
}
template <typename I, typename O>
- void not__(trait::image::speed::fastest, const I& input,
- trait::image::speed::fastest, O& output)
+ void not__(trait::image::speed::fastest, const I& input, O& output)
{
mln_pixter(const I) ip(input);
mln_pixter(O) op(output);
@@ -96,20 +94,27 @@
// Facades.
- template <typename I, typename O>
- void not_(const Image<I>& input, Image<O>& output)
+ template <typename I>
+ mln_concrete(I) not_(const Image<I>& input)
{
- mln_precondition(exact(output).domain() = exact(input).domain());
- impl::not__(mln_trait_image_speed(I)(), exact(input),
- mln_trait_image_speed(O)(), exact(output));
+ trace::entering("logical::not");
+ mln_precondition(exact(input).has_data());
+
+ mln_concrete(I) output;
+ initialize(output, input);
+ impl::not__(mln_trait_image_speed(I)(), exact(input), output);
+
+ trace::exiting("logical::not");
+ return output;
}
template <typename I>
void not_inplace(Image<I>& input)
{
+ trace::entering("logical::not_inplace");
mln_precondition(exact(input).has_data());
- impl::not__(mln_trait_image_speed(I)(), exact(input),
- mln_trait_image_speed(I)(), exact(input));
+ impl::not__(mln_trait_image_speed(I)(), exact(input), exact(input));
+ trace::exiting("logical::not_inplace");
}
# endif // ! MLN_INCLUDE_ONLY
Index: img/picasso.pbm
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: img/picasso.pbm
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream