https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena
Index: ChangeLog
from Nicolas Ballas <ballas(a)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);
}