Faudrait demander au bocal de nous envoyer un gars qui doit faire un
TIG pour réecrire arith un de ces 4 ...
Index: integre/ChangeLog
from Nicolas Burrus <burrus_n(a)lrde.epita.fr>
* ntg/core/internal/global_ops.hh: Import min and max into
namespace ntg.
Index: olena/ChangeLog
from Nicolas Burrus <burrus_n(a)lrde.epita.fr>
* oln/arith/internal/opdecls.hh: Support builtin types. Document.
* oln/arith/ops.hh: Support builtin types.
* oln/utils/histogram.hh: Support builtin types.
* oln/convert/nrgbhsl.hh: Use ntg::{min,max} instead of
std::{min,max}.
* oln/core/box.hxx: Likewise.
* oln/morpho/reconstruction.hh: Likewise.
* oln/morpho/geodesic_dilation.hh: Force the output type of
arith::min. Use ntg::min instead of std::min.
* oln/morpho/geodesic_erosion.hh: Likewise with s/min/max/.
+2003-10-08 Nicolas Burrus <burrus_n(a)lrde.epita.fr>
+
* tests/morpho/tests/builtin_types: New test.
2003-09-27 Nicolas Burrus <burrus_n(a)lrde.epita.fr>
Index: olena/oln/arith/internal/opdecls.hh
--- olena/oln/arith/internal/opdecls.hh Thu, 07 Aug 2003 02:08:21 +0200 david
(oln/b/22_opdecls.hh 1.13 640)
+++ olena/oln/arith/internal/opdecls.hh Wed, 08 Oct 2003 23:36:51 +0200 burrus_n
(oln/b/22_opdecls.hh 1.14 640)
@@ -28,17 +28,33 @@
#ifndef OLENA_ARITH_INTERNAL_OPDECLS_HH
# define OLENA_ARITH_INTERNAL_OPDECLS_HH
-/*-------------------.
-| Binary functions. |
-`-------------------*/
+/*
+ These macros should be rewritten / split into real code to make
+ things clearer.
+
+ Operations are defined between two images and between one image and
+ one constant value (with the cst suffix).
+
+ The two main components are:
+
+ 1) Define functors for each operations, taking two values and
+ returning the result.
+
+ 2) Define front-end functions applying a functor on the whole image.
+ 3 versions are defined, leaving the possibility to specify the
+ return type automatically, manually or using a conversion (from
+ convert).
+*/
+
+/*------------------.
+| Binary functors. |
+`------------------*/
-/* For binary operators that takes rev_values<T> arguments
- and define ntg::internal::operator_##OPNAME##_traits. */
# define oln_arith_declare_binrecval_functor_(OPNAME, OPCODE) \
- template<class T1, class T2 = T1> \
- struct f_##OPNAME : std::binary_function<const ntg::value<T1>&, \
- const ntg::value<T2>&, \
- ntg_return_type(OPNAME, T1, T2) > \
+ template<class T1, class T2, class Ret> \
+ struct f_##OPNAME : std::binary_function<const T1&, \
+ const T2&, \
+ Ret> \
{ \
typedef f_##OPNAME self_type; \
typename self_type::result_type \
@@ -49,12 +65,12 @@
} \
} /* no ; */
-/* For binary operators that takes rev_values<T> arguments \
- and define ntg::internal::operator_##OPNAME##_traits. */ \
+// Functor used by operations between an image and a constant
+
# define oln_arith_declare_binrecvalcst_functor_(OPNAME, OPCODE_CST) \
- template<class T1, class T2 = T1> \
- struct f_##OPNAME##_cst : std::unary_function<const ntg::value<T1>&, \
- ntg_return_type(OPNAME, T1, T2) > \
+ template<class T1, class T2, class Ret> \
+ struct f_##OPNAME##_cst : std::unary_function<const T1&, \
+ Ret> \
{ \
typedef f_##OPNAME##_cst self_type; \
f_##OPNAME##_cst(T2 cst) : cst_(cst) {} \
@@ -73,7 +89,6 @@
oln_arith_declare_binrecval_functor_(OPNAME, OPCODE); \
oln_arith_declare_binrecvalcst_functor_(OPNAME, OPCODE_CST)
-
/* For binary functions that work on a single known datatype. */
# define oln_arith_declare_binfixedtype_functor_(OPNAME, OPCODE, TYPE) \
struct f_##OPNAME : std::binary_function< const TYPE&, const TYPE&,
TYPE> \
@@ -106,83 +121,123 @@
oln_arith_declare_binfixedtype_functor_(NAME, CODE, TYPE); \
oln_arith_declare_binfixedtypecst_functor_(NAME, CODE_CST, TYPE)
+// Shortcuts
+#define default_functor_return_type_(OPNAME, I1, I2) \
+ typename f_##OPNAME<oln_value_type(I1), \
+ oln_value_type(I2), \
+ ntg_return_type(OPNAME, \
+ oln_value_type(I1), \
+ oln_value_type(I2))>::result_type
+
+#define default_functor_type_cst_(OPNAME, I1, T2) \
+ f_##OPNAME##_cst<oln_value_type(I1), \
+ T2, \
+ ntg_return_type(OPNAME, \
+ oln_value_type(I1), \
+ T2)>
+
+#define default_functor_return_type_cst_(OPNAME, I1, T2) \
+ typename default_functor_type_cst_(OPNAME, I1, T2)::result_type
+
+/*----------------------------.
+| Declare front-end functions |
+`----------------------------*/
+
# define oln_arith_declare_binop_procs_(OPNAME) \
+ /* \
+ FIXME: this is a workaround for an odd bug of icc and como \
+
http://www.lrde.epita.fr/cgi-bin/twiki/view/Know/MysteriousTemplateFunction… \
+ Remove this traits and use its content directly when this bug gets fixed. \
+ */ \
+ template <class I1, class I2> \
+ struct arith_return_type_proxy_##OPNAME##_ \
+ { \
+ typedef typename mute<I1, default_functor_return_type_(OPNAME, I1, I2)>::ret
ret; \
+ }; \
+ \
/* Standard application of OPNAME */ \
template<class I1, class I2> inline \
- typename mute<I1, \
- typename
f_##OPNAME<oln_value_type(I1),oln_value_type(I2)>::result_type>::ret \
+ typename arith_return_type_proxy_##OPNAME##_<I1, I2>::ret \
OPNAME(const abstract::image<I1>& input1, const
abstract::image<I2>& input2) \
{ \
+ typedef oln_value_type(I1) T1; \
+ typedef oln_value_type(I2) T2; \
/* KLUGE: Build the functor, don't pass it as a parameter as in \
apply2<f_##OPNAME>(input1, input2) \
otherwise GCC 2.95.x will ICE. */ \
- return apply2(f_##OPNAME<oln_value_type(I1),oln_value_type(I2)>(), input1,
input2); \
+ return apply2(f_##OPNAME<T1, \
+ T2, \
+ ntg_return_type(OPNAME, T1, T2)>(), \
+ input1, input2); \
} \
\
/* Same as above, plus conversion. */ \
template<class C, class B, class I1, class I2> inline \
typename mute<I1, \
- typename convoutput<C, B, \
- typename
f_##OPNAME<oln_value_type(I1),oln_value_type(I2)>::result_type>::ret>::ret \
+ typename convoutput<C, B, default_functor_return_type_(OPNAME, I1,
I2)>::ret>::ret \
OPNAME(const convert::abstract::conversion<C, B>& conv, \
const abstract::image<I1>& input1, const abstract::image<I2>&
input2) \
{ \
+ typedef oln_value_type(I1) T1; \
+ typedef oln_value_type(I2) T2; \
return apply2(convert::compconv2(conv, \
- f_##OPNAME<oln_value_type(I1),oln_value_type(I2)>()), \
+ f_##OPNAME<T1, \
+ T2, \
+ ntg_return_type(OPNAME, T1, T2)>()), \
+ input1, input2); \
+ } \
+ \
+ /* Same as above, with inline conversion in the functor. */ \
+ template<class IRet, class I1, class I2> inline \
+ typename mute<I1, oln_value_type(IRet)>::ret \
+ OPNAME(const abstract::image<I1>& input1, const
abstract::image<I2>& input2) \
+ { \
+ return apply2(f_##OPNAME<oln_value_type(I1), \
+ oln_value_type(I2), \
+ oln_value_type(IRet)>(), \
input1, input2); \
}
# define oln_arith_declare_binopcst_procs_(OPNAME) \
/* Apply OPNAME with a constant as second operand. */ \
+ \
+ /* FIXME: cf explications above */ \
+ template <class I, class T> \
+ struct arith_return_type_proxy_cst_##OPNAME##_ \
+ { \
+ typedef typename mute<I, default_functor_return_type_cst_(OPNAME, I, T)>::ret
ret; \
+ }; \
+ \
template<class I, class T> inline \
- typename mute<I, \
- typename f_##OPNAME##_cst<oln_value_type(I), T>::result_type>::ret \
+ typename arith_return_type_proxy_cst_##OPNAME##_<I, T>::ret \
OPNAME##_cst(const abstract::image<I>& input, T val) \
{ \
- return apply(f_##OPNAME##_cst<oln_value_type(I),T>(val), input); \
+ typedef default_functor_type_cst_(OPNAME, I, T) functor_type; \
+ return apply(functor_type(val), input); \
} \
\
/* Same as above, plus conversion. */ \
template<class C, class B, class I, class T> inline \
typename mute<I, \
- typename convoutput<C, B, \
- typename f_##OPNAME##_cst<oln_value_type(I),
T>::result_type>::ret>::ret \
- OPNAME##_cst(const convert::abstract::conversion<C, B>& conv, const
abstract::image<I>& input, T val) \
+ typename convoutput<C, B, default_functor_return_type_cst_(OPNAME, I,
T)>::ret>::ret \
+ OPNAME##_cst(const convert::abstract::conversion<C, B>& conv, \
+ const abstract::image<I>& input, T val) \
{ \
- return apply(convert::compconv1(conv, \
- f_##OPNAME##_cst<oln_value_type(I),T>(val)), \
- input); \
+ typedef default_functor_type_cst_(OPNAME, I, T) functor_type; \
+ return apply(convert::compconv1(conv, functor_type(val)), input); \
+ } \
+ \
+ template<class IRet, class I, class T> inline \
+ typename mute<I, oln_value_type(IRet)>::ret \
+ OPNAME##_cst(const abstract::image<I>& input, T val) \
+ { \
+ return apply(f_##OPNAME##_cst<oln_value_type(I), T,
oln_value_type(IRet)>(val), input); \
}
# define oln_arith_declare_all_binop_procs_(OPNAME) \
oln_arith_declare_binop_procs_(OPNAME) \
oln_arith_declare_binopcst_procs_(OPNAME)
-
-/* Same as oln_arith_declare_binop_procs_, for functor parametred by
- a single type. */
-# define oln_arith_declare_semigeneric_binop_procs_(OPNAME) \
- /* Standard application of OPNAME */ \
- template<class I1, class I2> inline \
- typename mute<I1, \
- typename f_##OPNAME<oln_value_type(I1)>::result_type>::ret \
- OPNAME(const abstract::image<I1>& input1, const
abstract::image<I2>& input2) \
- { \
- return apply2<f_##OPNAME>(input1, input2); \
- } \
- \
- /* Same as above, plus conversion. */ \
- template<class C, class B, class I1, class I2> inline \
- typename mute<I1, \
- typename convoutput<C, B, \
- typename f_##OPNAME<oln_value_type(I1)>::result_type>::ret>::ret \
- OPNAME(const convert::abstract::conversion<C, B>& conv, \
- const abstract::image<I1>& input1, const abstract::image<I2>&
input2) \
- { \
- return apply2(convert::compconv2(conv, f_##OPNAME<oln_value_type(I1)>()), \
- input1, input2); \
- }
-
/* Same as oln_arith_declare_nongenericbinop_procs_ but for non template
functors. */
# define oln_arith_declare_nongenericbinop_procs_(OPNAME) \
@@ -221,7 +276,8 @@
typename mute<I, \
typename convoutput<C, B, \
typename f_##OPNAME##_cst::result_type>::ret>::ret \
- OPNAME##_cst(const convert::abstract::conversion<C, B>& conv, const
abstract::image<I>& input, T val) \
+ OPNAME##_cst(const convert::abstract::conversion<C, B>& conv, \
+ const abstract::image<I>& input, T val) \
{ \
return apply(convert::compconv1(conv, f_##OPNAME##_cst(val)), \
input); \
@@ -233,7 +289,6 @@
oln_arith_declare_nongenericbinop_procs_(OPNAME) \
oln_arith_declare_nongenericbinopcst_procs_(OPNAME)
-
/*------------------.
| Unary functions. |
`------------------*/
@@ -285,5 +340,34 @@
return apply(convert::compconv2(conv, f_##OPNAME<oln_value_type(I)>()),
input1); \
}
+// FIXME: this code sounds odd and isn't used anywhere.
+// It should be rewritten properly if we want to keep it.
+# if 0
+
+/* Same as oln_arith_declare_binop_procs_, for functor parametred by
+ a single type. */
+# define oln_arith_declare_semigeneric_binop_procs_(OPNAME) \
+ /* Standard application of OPNAME */ \
+ template<class I1, class I2> inline \
+ typename mute<I1, \
+ typename f_##OPNAME<oln_value_type(I1),
oln_value_type(I1)>::result_type>::ret \
+ OPNAME(const abstract::image<I1>& input1, const
abstract::image<I2>& input2) \
+ { \
+ return apply2<f_##OPNAME>(input1, input2); \
+ } \
+ \
+ /* Same as above, plus conversion. */ \
+ template<class C, class B, class I1, class I2> inline \
+ typename mute<I1, \
+ typename convoutput<C, B, \
+ typename f_##OPNAME<oln_value_type(I1)>::result_type>::ret>::ret \
+ OPNAME(const convert::abstract::conversion<C, B>& conv, \
+ const abstract::image<I1>& input1, const abstract::image<I2>&
input2) \
+ { \
+ return apply2(convert::compconv2(conv, f_##OPNAME<oln_value_type(I1)>()), \
+ input1, input2); \
+ }
+
+# endif
-#endif // OLENA_ARITH_INTERNAL_OPDECLS_HH
+#endif // ! OLENA_ARITH_INTERNAL_OPDECLS_HH
Index: olena/oln/arith/ops.hh
--- olena/oln/arith/ops.hh Thu, 07 Aug 2003 02:08:21 +0200 david (oln/b/23_ops.hh
1.5.1.2.1.7 640)
+++ olena/oln/arith/ops.hh Wed, 08 Oct 2003 23:36:51 +0200 burrus_n (oln/b/23_ops.hh
1.5.1.2.1.8 640)
@@ -41,24 +41,24 @@
namespace arith {
oln_arith_declare_binrecval_functors_(plus,
- val1.exact() + val2.exact(),
- val.exact() + cst_);
+ val1 + val2,
+ val + cst_);
// need a cast for the case int_u - int_u
oln_arith_declare_binrecval_functors_(minus,
- val1.exact() - val2.exact(),
- val.exact() - cst_);
+ val1 - val2,
+ val - cst_);
oln_arith_declare_binrecval_functors_(times,
- val1.exact() * val2.exact(),
- val.exact() * cst_);
+ val1 * val2,
+ val * cst_);
oln_arith_declare_binrecval_functors_(div,
- val1.exact() / val2.exact(),
- val.exact() / cst_);
+ val1 / val2,
+ val / cst_);
oln_arith_declare_binrecval_functors_(min,
- min(val1.exact(), val2.exact()),
- min(val.exact(), cst_));
+ ntg::min(val1, val2),
+ ntg::min(val, cst_));
oln_arith_declare_binrecval_functors_(max,
- max(val1.exact(), val2.exact()),
- max(val.exact(), cst_));
+ ntg::max(val1, val2),
+ ntg::max(val, cst_));
oln_arith_declare_all_binop_procs_(plus)
oln_arith_declare_all_binop_procs_(minus)
Index: olena/oln/convert/nrgbhsl.hh
--- olena/oln/convert/nrgbhsl.hh Thu, 07 Aug 2003 02:08:21 +0200 david (oln/12_nrgbhsl.hh
1.16 640)
+++ olena/oln/convert/nrgbhsl.hh Wed, 08 Oct 2003 23:36:51 +0200 burrus_n
(oln/12_nrgbhsl.hh 1.17 640)
@@ -63,8 +63,8 @@
vec<3, float> in = v.to_float();
vec<3, float> out;
- float max_in = std::max(in[nrgb_R], std::max(in[nrgb_B], in[nrgb_G]));
- float min_in = std::min(in[nrgb_R], std::min(in[nrgb_B], in[nrgb_G]));
+ float max_in = ntg::max(in[nrgb_R], std::max(in[nrgb_B], in[nrgb_G]));
+ float min_in = ntg::min(in[nrgb_R], std::min(in[nrgb_B], in[nrgb_G]));
float diff = max_in-min_in;
out[hsl_L] = (max_in + min_in) / 2;
Index: olena/oln/core/box.hxx
--- olena/oln/core/box.hxx Thu, 07 Aug 2003 02:08:21 +0200 david (oln/p/0_box.hxx
1.4.1.1.1.4 640)
+++ olena/oln/core/box.hxx Wed, 08 Oct 2003 23:36:51 +0200 burrus_n (oln/p/0_box.hxx
1.4.1.1.1.5 640)
@@ -64,7 +64,7 @@
{
for (unsigned i = 0; i < dim(); ++i)
{
- top_.nth(i) = std::max(top_.nth(i), p.nth(i));
+ top_.nth(i) = ntg::max(top_.nth(i), p.nth(i));
bottom_.nth(i) = std::min(bottom_.nth(i), p.nth(i));
mass_[i] += p.nth(i);
}
Index: olena/oln/morpho/geodesic_dilation.hh
--- olena/oln/morpho/geodesic_dilation.hh Thu, 07 Aug 2003 02:08:21 +0200 david
(oln/37_geodesic_d 1.11.1.9 640)
+++ olena/oln/morpho/geodesic_dilation.hh Wed, 08 Oct 2003 23:36:51 +0200 burrus_n
(oln/37_geodesic_d 1.11.1.10 640)
@@ -74,7 +74,9 @@
mlc::eq<I1::dim, N::dim>::ensure();
precondition(marker.size() == mask.size());
precondition(level::is_greater_or_equal(mask, marker));
- return arith::min(dilation(marker, convert::ng_to_cse(Ng)), mask);
+ return arith::min<oln_concrete_type(I1)>(dilation(marker,
+ convert::ng_to_cse(Ng)),
+ mask);
}
namespace sure {
@@ -116,7 +118,7 @@
marker.border_adapt_copy(Ng.delta());
oln_iter_type(I1) p(marker);
for_all (p)
- output[p] = min(morpho::max(marker, p, convert::ng_to_cse(Ng)), mask[p]);
+ output[p] = std::min(morpho::max(marker, p, convert::ng_to_cse(Ng)), mask[p]);
return output;
}
Index: olena/oln/morpho/geodesic_erosion.hh
--- olena/oln/morpho/geodesic_erosion.hh Thu, 07 Aug 2003 02:08:21 +0200 david
(oln/36_geodesic_e 1.16 640)
+++ olena/oln/morpho/geodesic_erosion.hh Wed, 08 Oct 2003 23:36:51 +0200 burrus_n
(oln/36_geodesic_e 1.17 640)
@@ -1,4 +1,4 @@
-// Copyright (C) 2001, 2002 EPITA Research and Development Laboratory
+// Copyright (C) 2001, 2002, 2003 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
@@ -70,10 +70,9 @@
mlc::eq<I1::dim, N::dim>::ensure();
precondition(marker.size() == mask.size());
precondition(level::is_greater_or_equal(marker, mask));
- return arith::max(erosion(marker, convert::ng_to_cse(Ng)), mask);
+ return arith::max<oln_concrete_type(I1)>(erosion(marker,
convert::ng_to_cse(Ng)), mask);
}
-
namespace sure {
/*=processing simple_geodesic_erosion
* ns: morpho
@@ -112,7 +111,7 @@
marker.border_adapt_copy(Ng.delta());
oln_iter_type(I1) p(marker);
for_all (p)
- output[p] = max(morpho::min(marker, p, convert::ng_to_cse(Ng)), mask[p]);
+ output[p] = ntg::max(morpho::min(marker, p, convert::ng_to_cse(Ng)), mask[p]);
return output;
}
Index: olena/oln/morpho/reconstruction.hh
--- olena/oln/morpho/reconstruction.hh Thu, 07 Aug 2003 02:08:21 +0200 david
(oln/35_reconstruc 1.13.1.10 640)
+++ olena/oln/morpho/reconstruction.hh Wed, 08 Oct 2003 23:36:51 +0200 burrus_n
(oln/35_reconstruc 1.13.1.11 640)
@@ -137,9 +137,9 @@
oln_concrete_type(I1) work = output.clone();
work.border_adapt_copy(Ng.delta());
for_all (fwd_p)
- work[fwd_p] = min(morpho::max(work, fwd_p, se_plus), mask[fwd_p]);
+ work[fwd_p] = ntg::min(morpho::max(work, fwd_p, se_plus), mask[fwd_p]);
for_all (bkd_p)
- work[bkd_p] = min(morpho::max(work, bkd_p, se_minus), mask[bkd_p]);
+ work[bkd_p] = ntg::min(morpho::max(work, bkd_p, se_minus), mask[bkd_p]);
non_stability = !(level::is_equal(work, output));
output = work;
}
@@ -217,13 +217,13 @@
typename I1::fwd_iter_type fwd_p(output);
typename I1::bkd_iter_type bkd_p(output);
for_all (fwd_p)
- output[fwd_p] = std::min(morpho::max(output, fwd_p, Ng_plus),
+ output[fwd_p] = ntg::min(morpho::max(output, fwd_p, Ng_plus),
mask[fwd_p]);
std::queue<oln_point_type(I1) > fifo;
for_all (bkd_p)
{
- output[bkd_p] = std::min(morpho::max(output, bkd_p, Ng_minus),
+ output[bkd_p] = ntg::min(morpho::max(output, bkd_p, Ng_minus),
mask[bkd_p]);
if (internal::exist_init_dilation(bkd_p.cur(), output, mask, Ng_minus))
fifo.push(bkd_p);
@@ -238,7 +238,7 @@
{
if ((output[q] < output[p]) && (mask[q] != output[q]))
{
- output[q] = std::min(output[p], mask[q]);
+ output[q] = ntg::min(output[p], mask[q]);
fifo.push(q);
}
}
@@ -345,9 +345,9 @@
oln_concrete_type(I1) work = output.clone();
work.border_adapt_copy(Ng.delta());
for_all (fwd_p)
- work[fwd_p] = max(morpho::min(work, fwd_p, se_plus), mask[fwd_p]);
+ work[fwd_p] = ntg::max(morpho::min(work, fwd_p, se_plus), mask[fwd_p]);
for_all (bkd_p)
- work[bkd_p] = max(morpho::min(work, bkd_p, se_minus), mask[bkd_p]);
+ work[bkd_p] = ntg::max(morpho::min(work, bkd_p, se_minus), mask[bkd_p]);
non_stability = !(level::is_equal(work, output));
output = work;
}
@@ -423,13 +423,13 @@
typename I1::fwd_iter_type fwd_p(output);
typename I1::bkd_iter_type bkd_p(output);
for_all (fwd_p)
- output[fwd_p] = max(morpho::min(output, fwd_p, Ng_plus),
+ output[fwd_p] = ntg::max(morpho::min(output, fwd_p, Ng_plus),
mask[fwd_p]);
std::queue<oln_point_type(I1) > fifo;
for_all (bkd_p)
{
- output[bkd_p] = max(morpho::min(output, bkd_p, Ng_minus),
+ output[bkd_p] = ntg::max(morpho::min(output, bkd_p, Ng_minus),
mask[bkd_p]);
if (internal::exist_init_erosion(bkd_p.cur(), output, mask, Ng_minus))
fifo.push(bkd_p);
@@ -444,7 +444,7 @@
{
if ((output[q] > output[p]) && (mask[q] != output[q]))
{
- output[q] = max(output[p], mask[q]);
+ output[q] = ntg::max(output[p], mask[q]);
fifo.push(q);
}
}
Index: integre/ntg/core/internal/global_ops.hh
--- integre/ntg/core/internal/global_ops.hh Wed, 30 Jul 2003 18:49:16 +0200 burrus_n
(oln/g/27_global_ops 1.11.1.13 640)
+++ integre/ntg/core/internal/global_ops.hh Wed, 08 Oct 2003 23:36:51 +0200 burrus_n
(oln/g/27_global_ops 1.11.1.14 640)
@@ -46,6 +46,9 @@
// macros defs
# include <ntg/core/internal/global_ops_defs.hh>
+// min and max
+# include <algorithm>
+
namespace ntg
{
@@ -204,6 +207,11 @@
| Min/Max operators |
`------------------*/
+ /*
+ These operators are slighly different from standard library ones
+ since they can operate on values of 2 different types.
+ */
+
template <class T1, class T2> inline
ntg_return_type(min, T1, T2)
min (const T1& lhs, const T2& rhs)
@@ -222,6 +230,12 @@
} // end of internal.
+ // FIXME: those are needed to handle max and min between two builtin
+ // types. Maybe std::min and std::max should be extended to work
+ // with builtin types?
+ using internal::min;
+ using internal::max;
+
} // end of ntg.
#endif // ndef NTG_CORE_INTERNAL_GLOBAL_OPS_HH
Index: olena/oln/utils/histogram.hh
--- olena/oln/utils/histogram.hh Thu, 07 Aug 2003 02:37:23 +0200 burrus_n
(oln/10_histogram. 1.6.1.12 640)
+++ olena/oln/utils/histogram.hh Wed, 08 Oct 2003 23:36:51 +0200 burrus_n
(oln/10_histogram. 1.6.1.13 640)
@@ -53,7 +53,6 @@
{
private:
typedef typename ntg_is_a(T, ntg::non_vectorial)::ensure_type ensure_type;
-
public:
histogram() : values_(0)
@@ -61,6 +60,10 @@
unsigned size = unsigned(ntg_max_val(T)
- ntg_min_val(T)
+ ntg_unit_val(T));
+ // FIXME: what if T is an unsigned int?
+ // This should be checked more strictly somewhere.
+ // size = max + 1 = 0
+ precondition(size > 0);
values_ = new U[size];
for (unsigned i = 0; i < size; ++i)
values_[i] = 0;
@@ -78,7 +81,7 @@
U&
operator[](const T& i)
{
- return values_[unsigned(i.val() - ntg_min_val(T))];
+ return values_[unsigned(i - ntg_min_val(T))];
}
friend T min<T, U>(const histogram<T, U>& hist);
@@ -91,7 +94,7 @@
oln_iter_type(I) p(img);
for_all (p)
- values_[unsigned(img[p].val())]++;
+ values_[unsigned(img[p])]++;
}
protected:
@@ -162,7 +165,7 @@
U&
operator[](const T& i)
{
- unsigned idx = unsigned(i.val() - ntg_min_val(T));
+ unsigned idx = unsigned(i - ntg_min_val(T));
adjust(idx);
return this->values_[idx];
}
@@ -210,7 +213,7 @@
U&
operator[](const T& i)
{
- unsigned idx = unsigned(i.val() - ntg_min_val(T));
+ unsigned idx = unsigned(i - ntg_min_val(T));
adjust(idx);
return this->values_[idx];
}
@@ -334,7 +337,7 @@
// level
oln_iter_type(I) p(im);
for_all(p)
- *(ptr[unsigned(im[p].val())]++) = p;
+ *(ptr[unsigned(im[p])]++) = p;
}
} // end of namespace utils
Index: olena/tests/morpho/tests/builtin_types
--- olena/tests/morpho/tests/builtin_types Wed, 08 Oct 2003 11:15:11 +0200 burrus_n
(oln/v/30_builtin_ty 1.1 640)
+++ olena/tests/morpho/tests/builtin_types Wed, 08 Oct 2003 23:36:51 +0200 burrus_n
(oln/v/30_builtin_ty 1.2 640)
@@ -1,8 +1,5 @@
// -*- c++ -*-
-// FIXME: this test should work before any serious release.
-// XFAIL
-
#include <oln/basics2d.hh>
#include <oln/morpho/opening.hh>
@@ -32,9 +29,9 @@
{
bool fail = false;
- image2d<unsigned> lena_uint = load(rdata("lena128.pgm"));
- image2d<signed> lena_sint = load(rdata("lena128.pgm"));
- image2d<unsigned> lena_open = morpho::fast::opening(lena_uint, win_c4p());
+ image2d<unsigned char> lena_uint = load(rdata("lena128.pgm"));
+ image2d<unsigned char> lena_open = morpho::fast::opening(lena_uint, win_c4p());
+
image2d<ntg::bin> minima_map(lena_uint.size());
image2d<int_u8> max_map(lena_uint.size());