https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena Index: ChangeLog from Nicolas Ballas <ballas@lrde.epita.fr> Update dispatch of level::transform_inplace routine. * tests/level/transform_inplace.cc: Add new tests. * doc/technical/designs/properties/values.txt: Fix typos. * mln/level/transform.spe.hh: Minor changes. * mln/level/transform_inplace.hh: Update routine disptach. doc/technical/designs/properties/values.txt | 3 mln/level/transform.spe.hh | 53 ++++--- mln/level/transform_inplace.hh | 195 ++++++++++++++++++++++++++-- tests/level/transform_inplace.cc | 106 +++++++++++++++ 4 files changed, 325 insertions(+), 32 deletions(-) Index: tests/level/transform_inplace.cc --- tests/level/transform_inplace.cc (revision 2870) +++ tests/level/transform_inplace.cc (working copy) @@ -29,8 +29,19 @@ /// /// Tests on mln::level::transform_inplace + +#include <mln/core/image/image1d.hh> #include <mln/core/image/image2d.hh> +#include <mln/core/image/image3d.hh> +#include <mln/core/image/flat_image.hh> +#include <mln/core/image/image_if.hh> +#include <mln/core/image/sub_image.hh> +#include <mln/core/image/extension_val.hh> + + #include <mln/core/routine/clone.hh> + + #include <mln/fun/v2v/inc.hh> #include <mln/fun/v2v/dec.hh> #include <mln/debug/iota.hh> @@ -38,6 +49,7 @@ #include <mln/level/transform_inplace.hh> #include <mln/level/compare.hh> +#include <mln/fun/p2b/chess.hh> int main() @@ -45,6 +57,9 @@ using namespace mln; const unsigned size = 50; + + // image 2d tests + { image2d<int> ref(size, size); debug::iota(ref); @@ -54,3 +69,94 @@ mln_assertion(ima == ref); } + + /// image 1d test + { + image1d<unsigned short> ref(size); + debug::iota(ref); + + image1d<unsigned short> ima = clone(ref); + level::transform_inplace(ima, fun::v2v::inc<int>()); + level::transform_inplace(ima, fun::v2v::dec<int>()); + + mln_assertion(ima == ref); + } + + + /// image 3d test + { + image3d<unsigned short> ref(size, size, size); + debug::iota(ref); + + image3d<unsigned short> ima = clone(ref); + level::transform_inplace(ima, fun::v2v::inc<int>()); + level::transform_inplace(ima, fun::v2v::dec<int>()); + + mln_assertion(ima == ref); + } + + // flat image test + { + flat_image<short, box2d> ref(5, make::box2d(size, size)); + + flat_image<short, box2d> ima(5, make::box2d(size, size)); + level::transform_inplace(ima, fun::v2v::inc<int>()); + level::transform_inplace(ima, fun::v2v::dec<int>()); + + mln_assertion(ima == ref); + } + + // image if test + { + typedef image2d<unsigned short> I; + typedef image_if<I, fun::p2b::chess> II; + + I ref(size, size); + debug::iota(ref); + II ref_if = ref | fun::p2b::chess(); + + I ima = clone(ref); + II ima_if = ima | fun::p2b::chess(); + + level::transform_inplace(ima_if, fun::v2v::inc<int>()); + level::transform_inplace(ima_if, fun::v2v::dec<int>()); + + mln_assertion(ima_if == ref_if); + } + + // sub_image test + { + typedef image2d<int> I; + typedef sub_image< image2d<int>, box2d > II; + typedef image2d<unsigned short> III; + + I ref(size, size); + debug::iota(ref); + II sub_ref(ref, make::box2d(4,4, 10,10)); + + I ima = clone(ref); + II sub_ima(ima, make::box2d(4,4, 10,10)); + + level::transform_inplace(sub_ima, fun::v2v::inc<int>()); + level::transform_inplace(sub_ima, fun::v2v::dec<int>()); + + mln_assertion(sub_ima == sub_ref); + } + + // extended image test + { + typedef image2d<int> I; + typedef extension_val< image2d<int> > II; + + I ref(size, size); + + I ima = clone(ref); + II extend_ima(ima, 5); + + level::transform_inplace(extend_ima, fun::v2v::inc<int>()); + level::transform_inplace(extend_ima, fun::v2v::dec<int>()); + + mln_assertion(extend_ima == ref); + + } +} Index: doc/technical/designs/properties/values.txt --- doc/technical/designs/properties/values.txt (revision 2870) +++ doc/technical/designs/properties/values.txt (working copy) @@ -18,7 +18,8 @@ | + -- computed -=> Definition: This property indicates if the image value are stored in memory. +=> Definition: This property indicates if the image value. are stored in +memory. - direct: Images store all their values in memory, we can take a reference of the values. Index: mln/level/transform.spe.hh --- mln/level/transform.spe.hh (revision 2870) +++ mln/level/transform.spe.hh (working copy) @@ -85,6 +85,13 @@ template <typename I, typename F> mln_ch_value(I, mln_result(F)) transform(const Image<I>& input_, const Function_v2v<F>& f_); + + template <typename I1, typename I2, typename F> + mln_ch_value(I1, mln_result(F)) + transform(const Image<I1>& input1, + const Image<I2>& input2, + const Function_vv2v<F>& f); + } @@ -262,8 +269,8 @@ template <typename I, typename F> inline mln_ch_value(I, mln_result(F)) - transform_dispatch(mln::trait::undef, - mln::trait::image::quant::any, + transform_dispatch(trait::undef, + trait::image::quant::any, const Image<I>& input, const Function_v2v<F>& f) { return level::impl::generic::transform(input, f); @@ -272,8 +279,8 @@ template <typename I, typename F> inline mln_ch_value(I, mln_result(F)) - transform_dispatch(mln::trait::image::vw_set::any, - mln::trait::image::quant::any, + transform_dispatch(trait::image::vw_set::any, + trait::image::quant::any, const Image<I>& input, const Function_v2v<F>& f) { return level::impl::generic::transform(input, f); @@ -282,8 +289,8 @@ template <typename I, typename F> inline mln_ch_value(I, mln_result(F)) - transform_dispatch(mln::trait::image::vw_set::uni, - mln::trait::image::quant::any, + transform_dispatch(trait::image::vw_set::uni, + trait::image::quant::any, const Image<I>& input, const Function_v2v<F>& f) { return level::impl::transform_taken(input, f); @@ -293,8 +300,8 @@ template <typename I, typename F> inline mln_ch_value(I, mln_result(F)) - transform_dispatch(mln::trait::image::vw_set::any, - mln::trait::image::quant::low, + transform_dispatch(trait::image::vw_set::any, + trait::image::quant::low, const Image<I>& input, const Function_v2v<F>& f) { return level::impl::transform_lowq(input, f); @@ -305,8 +312,8 @@ template <typename I, typename F> inline mln_ch_value(I, mln_result(F)) - transform_dispatch(mln::trait::image::quant::any, - mln::trait::image::value_access::direct, + transform_dispatch(trait::image::quant::any, + trait::image::value_access::direct, const Image<I>& input, const Function_v2v<F>& f) { return level::impl::transform_fast(input, f); @@ -316,8 +323,8 @@ template <typename I, typename F> inline mln_ch_value(I, mln_result(F)) - transform_dispatch(mln::trait::image::quant::low, - mln::trait::image::value_access::direct, + transform_dispatch(trait::image::quant::low, + trait::image::value_access::direct, const Image<I>& input, const Function_v2v<F>& f) { return level::impl::transform_fast_lowq(input, f); @@ -328,8 +335,8 @@ template <typename I, typename F> inline mln_ch_value(I, mln_result(F)) - transform_dispatch(mln::trait::image::quant::any, - mln::trait::image::value_access::any, + transform_dispatch(trait::image::quant::any, + trait::image::value_access::any, const Image<I>& input, const Function_v2v<F>& f) { return transform_dispatch(mln_trait_image_vw_set(I)(), @@ -341,7 +348,7 @@ template <typename I, typename F> inline mln_ch_value(I, mln_result(F)) - transform_dispatch(mln::trait::image::value_storage::any, + transform_dispatch(trait::image::value_storage::any, const Image<I>& input, const Function_v2v<F>& f) { return transform_dispatch(mln_trait_image_vw_set(I)(), @@ -352,7 +359,7 @@ template <typename I, typename F> inline mln_ch_value(I, mln_result(F)) - transform_dispatch(mln::trait::image::value_storage::singleton, + transform_dispatch(trait::image::value_storage::singleton, const Image<I>& input, const Function_v2v<F>& f) { return level::impl::transform_singleton(input, f); @@ -361,7 +368,7 @@ template <typename I, typename F> inline mln_ch_value(I, mln_result(F)) - transform_dispatch(mln::trait::image::value_storage::one_block, + transform_dispatch(trait::image::value_storage::one_block, const Image<I>& input_, const Function_v2v<F>& f_) { const I& input = exact(input_); @@ -384,7 +391,9 @@ template <typename I1, typename I2, typename F> mln_ch_value(I1, mln_result(F)) - transform_dispatch_2(trait::image::speed::any, + transform_dispatch_2(trait::image::value_alignement::any, + trait::image::value_alignement::any, + trait::image::speed::any, trait::image::speed::any, const Image<I1>& input1, const Image<I2>& input2, const Function_vv2v<F>& f) @@ -394,7 +403,9 @@ template <typename I1, typename I2, typename F> mln_ch_value(I1, mln_result(F)) - transform_dispatch_2(trait::image::speed::fastest, + transform_dispatch_2(trait::image::value_alignement::with_grid, + trait::image::value_alignement::with_grid, + trait::image::speed::fastest, trait::image::speed::fastest, const Image<I1>& input1, const Image<I2>& input2, const Function_vv2v<F>& f) @@ -421,7 +432,9 @@ transform_dispatch(const Image<I1>& input1, const Image<I2>& input2, const Function_vv2v<F>& f) { - return transform_dispatch_2(mln_trait_image_speed(I1)(), + return transform_dispatch_2(mln_trait_image_value_alignement(I1)(), + mln_trait_image_value_alignement(I2)(), + mln_trait_image_speed(I1)(), mln_trait_image_speed(I2)(), input1, input2, f); } Index: mln/level/transform_inplace.hh --- mln/level/transform_inplace.hh (revision 2870) +++ mln/level/transform_inplace.hh (working copy) @@ -36,6 +36,8 @@ # include <mln/core/concept/image.hh> # include <mln/core/concept/function.hh> +# include <mln/value/set.hh> +# include <mln/value/lut_vec.hh> namespace mln @@ -184,16 +186,82 @@ } // end of namespace mln::level::impl::generic + /// Specialized implementation template <typename I, typename F> void - transform_inplace_fastest(Image<I>& ima_, const Function_v2v<F>& f_) + transform_inplace_lowq(Image<I>& input_, + const Function_v2v<F>& f_) { - trace::entering("level::impl::transform_inplace_fastest"); + trace::entering("level::impl::transform_inplace_lowq"); mlc_is(mln_trait_image_pw_io(I), trait::image::pw_io::read_write)::check(); + I& input = exact(input_); + const F& f = exact(f_); + + level::internal::transform_inplace_tests(input, f); + + value::lut_vec<mln_vset(I), mln_result(F)> + lut(input.values_eligible(), f); + + mln_piter(I) p(input.domain()); + for_all(p) + input(p) = lut(input(p)); + + trace::exiting("level::impl::transform_inplace_lowq"); + } + + template <typename I, typename F> + void + transform_inplace_taken(Image<I>& input_, + const Function_v2v<F>& f_) + { + trace::entering("level::impl::transform_inplace_taken"); + + mlc_is(mln_trait_image_pw_io(I), + trait::image::pw_io::read_write)::check(); + + I& input = exact(input_); + const F& f = exact(f_); + + level::internal::transform_inplace_tests(input, f); + + value::lut_vec<mln_vset(I), mln_result(F)> + lut(input.taken_values(), f); + + mln_piter(I) p(input.domain()); + for_all(p) + input(p) = lut(input(p)); + + trace::exiting("level::impl::transform_inplace_taken"); + } + + + template <typename I, typename F> + void + transform_inplace_singleton(Image<I>& input_, + const Function_v2v<F>& f_) + { + trace::entering("level::impl::transform_inplace_singleton"); + + I& input = exact(input_); + const F& f = exact(f_); + + level::internal::transform_inplace_tests(input, f); + + input.val() = f(input.val()); + + trace::exiting("level::impl::transform_inplace_singleton"); + } + + template <typename I, typename F> + void + transform_inplace_fastest(Image<I>& ima_, const Function_v2v<F>& f_) + { + trace::entering("level::impl::transform_inplace_fastest"); + I& ima = exact(ima_); const F& f = exact(f_); @@ -207,6 +275,29 @@ } + template <typename I, typename F> + void + transform_inplace_fastest_lowq(Image<I>& input_, + const Function_v2v<F>& f_) + { + trace::entering("level::impl::transform_inplace_fastest_lowq"); + + I& input = exact(input_); + const F& f = exact(f_); + + level::internal::transform_inplace_tests(input, f); + + value::lut_vec<mln_vset(I), mln_result(F)> + lut(input.values_eligible(), f); + + mln_pixter(I) pi(input); + for_all(pi) + pi.val() = lut(pi.val()); + + trace::exiting("level::impl::transform_inplace_fastest_lowq"); + } + + template <typename I1, typename I2, typename F> void transform_inplace_fastest(Image<I1>& ima_, const Image<I2>& aux_, @@ -243,9 +334,11 @@ // (ima, f) version. + /// Dispatch on quantization template <typename I, typename F> void - transform_inplace_dispatch(trait::image::speed::any, + transform_inplace_dispatch(trait::image::vw_set::any, + trait::image::quant::any, Image<I>& ima, const Function_v2v<F>& f) { level::impl::generic::transform_inplace(ima, f); @@ -253,7 +346,28 @@ template <typename I, typename F> void - transform_inplace_dispatch(trait::image::speed::fastest, + transform_inplace_dispatch(trait::image::vw_set::uni, + trait::image::quant::any, + Image<I>& ima, const Function_v2v<F>& f) + { + level::impl::transform_inplace_taken(ima, f); + } + + template <typename I, typename F> + void + transform_inplace_dispatch(trait::image::vw_set::any, + trait::image::quant::low, + Image<I>& ima, const Function_v2v<F>& f) + { + level::impl::transform_inplace_lowq(ima, f); + } + + + + /// Dispatch for fast image + template <typename I, typename F> + void + transform_inplace_dispatch_fast(trait::image::quant::any, Image<I>& ima, const Function_v2v<F>& f) { level::impl::transform_inplace_fastest(ima, f); @@ -261,37 +375,96 @@ template <typename I, typename F> void + transform_inplace_dispatch_fast(trait::image::quant::low, + Image<I>& ima, const Function_v2v<F>& f) + { + level::impl::transform_inplace_fastest_lowq(ima, f); + } + + + + + /// Dispatch on value storage + template <typename I, typename F> + void + transform_inplace_dispatch(trait::image::value_storage::any, + trait::image::value_access::any, + Image<I>& ima, const Function_v2v<F>& f) + { + transform_inplace_dispatch(mln_trait_image_vw_set(I)(), + mln_trait_image_quant(I)(), + ima, f); + } + + template <typename I, typename F> + void + transform_inplace_dispatch(trait::image::value_storage::singleton, + trait::image::value_access::any, + Image<I>& ima, const Function_v2v<F>& f) + { + level::impl::transform_inplace_singleton(ima, f); + } + + + template <typename I, typename F> + void + transform_inplace_dispatch(trait::image::value_storage::one_block, + trait::image::value_access::direct, + Image<I>& ima, const Function_v2v<F>& f) + { + transform_inplace_dispatch_fast(mln_trait_image_quant(I)(), + ima, f); + } + + + + + /// First dispatch + template <typename I, typename F> + void transform_inplace_dispatch(Image<I>& ima, const Function_v2v<F>& f) { - transform_inplace_dispatch(mln_trait_image_speed(I)(), + transform_inplace_dispatch(mln_trait_image_value_storage(I)(), + mln_trait_image_value_access(I)(), ima, f); } + + // (ima, aux, f) version. template <typename I1, typename I2, typename F> void - transform_inplace_dispatch(trait::image::speed::any, + transform_inplace_dispatch(trait::image::value_alignement::any, + trait::image::value_alignement::any, + trait::image::speed::any, trait::image::speed::any, - Image<I1>& ima, const Image<I2>& aux, const Function_vv2v<F>& f) + Image<I1>& ima, const Image<I2>& aux, + const Function_vv2v<F>& f) { level::impl::generic::transform_inplace(ima, aux, f); } template <typename I1, typename I2, typename F> void - transform_inplace_dispatch(trait::image::speed::fastest, + transform_inplace_dispatch(trait::image::value_alignement::with_grid, + trait::image::value_alignement::with_grid, trait::image::speed::fastest, - Image<I1>& ima, const Image<I2>& aux, const Function_vv2v<F>& f) + trait::image::speed::fastest, + Image<I1>& ima, const Image<I2>& aux, + const Function_vv2v<F>& f) { level::impl::transform_inplace_fastest(ima, aux, f); } template <typename I1, typename I2, typename F> void - transform_inplace_dispatch(Image<I1>& ima, const Image<I2>& aux, const Function_vv2v<F>& f) + transform_inplace_dispatch(Image<I1>& ima, const Image<I2>& aux, + const Function_vv2v<F>& f) { - transform_inplace_dispatch(mln_trait_image_speed(I1)(), + transform_inplace_dispatch(mln_trait_image_value_alignement(I1)(), + mln_trait_image_value_alignement(I2)(), + mln_trait_image_speed(I1)(), mln_trait_image_speed(I2)(), ima, aux, f); }