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@lrde.epita.fr
* ntg/core/internal/global_ops.hh: Import min and max into namespace ntg.
Index: olena/ChangeLog from Nicolas Burrus burrus_n@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@lrde.epita.fr + * tests/morpho/tests/builtin_types: New test.
2003-09-27 Nicolas Burrus burrus_n@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/MysteriousTemplateFunctionO... \ + 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()); + image2dntg::bin minima_map(lena_uint.size()); image2d<int_u8> max_map(lena_uint.size());