https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena
Index: ChangeLog
from Nicolas Ballas <ballas(a)lrde.epita.fr>
Update dispatch in the transform algo according to image properties.
* tests/level/transform.cc: Add tests.
* mln/trait/image/props.hh: Fix a mistakes.
* mln/level/transform.spe.hh: Add dispatch.
* mln/level/transform.hh: Add transform_tests function.
mln/level/transform.hh | 44 +++++-
mln/level/transform.spe.hh | 312 ++++++++++++++++++++++++++++++++++++++++-----
mln/trait/image/props.hh | 3
tests/level/transform.cc | 59 +++++++-
4 files changed, 378 insertions(+), 40 deletions(-)
Index: tests/level/transform.cc
--- tests/level/transform.cc (revision 2558)
+++ tests/level/transform.cc (working copy)
@@ -33,9 +33,14 @@
#include <cmath>
#include <mln/core/image/image2d.hh>
+#include <mln/core/image/flat_image.hh>
+#include <mln/core/image/image_if.hh>
+
#include <mln/level/transform.hh>
#include <mln/debug/iota.hh>
+#include <mln/core/var.hh>
+#include <mln/fun/p2b/chess.hh>
struct mysqrt : mln::Function_v2v<mysqrt>
{
@@ -51,12 +56,11 @@
int main()
{
using namespace mln;
-
const unsigned size = 1000;
- image2d<unsigned short>
- ima(size, size);
- image2d<unsigned short>
- out(size, size);
+
+ {
+ image2d<unsigned short> ima(size, size);
+ image2d<unsigned short> out(size, size);
(std::cout << "iota... ").flush();
debug::iota(ima);
@@ -72,3 +76,48 @@
mln_assertion((unsigned short)std::sqrt(ima(p)) == out(p));
std::cout << "done" << std::endl;
}
+
+ {
+ flat_image<short, box2d> ima(5, make::box2d(size, size));
+ image2d<unsigned short> out(size, size);
+
+ (std::cout << "fill... ").flush();
+ level::fill_with_value(ima, 51);
+ std::cout << "done" << std::endl;
+
+ (std::cout << "transform... ").flush();
+ level::transform(ima, mysqrt(), out);
+ std::cout << "done" << std::endl;
+
+ (std::cout << "checking... ").flush();
+ box2d::piter p(out.domain());
+ for_all(p)
+ mln_assertion((unsigned short)std::sqrt(ima(p)) == out(p));
+ std::cout << "done" << std::endl;
+ }
+
+ {
+ typedef image2d<unsigned short> I;
+ typedef image_if<I, fun::p2b::chess_t> II;
+
+ I ima(size, size);
+ I out(size, size);
+ II ima_if = ima | fun::p2b::chess;
+
+ level::fill_with_value(ima, 0);
+ (std::cout << "iota... ").flush();
+ debug::iota(ima);
+ std::cout << "done" << std::endl;;
+
+ (std::cout << "transform... ").flush();
+ level::transform(ima_if, mysqrt(), out);
+ std::cout << "done" << std::endl;
+
+ (std::cout << "checking... ").flush();
+ II::piter p(ima_if.domain());
+ for_all(p)
+ mln_assertion((unsigned short)std::sqrt(ima_if(p)) == out(p));
+ std::cout << "done" << std::endl;
+ }
+
+}
Index: mln/trait/image/props.hh
--- mln/trait/image/props.hh (revision 2558)
+++ mln/trait/image/props.hh (working copy)
@@ -424,7 +424,8 @@
{
struct any { protected: any() {} };
struct some : any { protected: some() {} };
- struct none : any { protected: none() {} };
+ struct none
+ : any { std::string name() const { return "vw_set::none";} };
struct uni
: some { std::string name() const { return "vw_set::uni";} };
struct multi
Index: mln/level/transform.spe.hh
--- mln/level/transform.spe.hh (revision 2558)
+++ mln/level/transform.spe.hh (working copy)
@@ -41,6 +41,8 @@
# include <mln/core/concept/image.hh>
# include <mln/core/concept/function.hh>
+# include <mln/level/fill_with_value.hh>
+
# include <mln/value/set.hh>
# include <mln/value/lut_vec.hh>
@@ -54,7 +56,18 @@
namespace level
{
+ namespace internal
+ {
+ template <typename I, typename F, typename O>
+ inline
+ void transform_tests(const Image<I>& input,
+ const Function_v2v<F>& f,
+ Image<O>& output);
+ }
+
+ // Implementation
+ // --------------
namespace impl
{
@@ -62,58 +75,295 @@
namespace generic
{
template <typename I, typename F, typename O>
- void transform_(const Image<I>& input_, const Function_v2v<F>& f_,
Image<O>& output_);
+ void transform(const Image<I>& input_,
+ const Function_v2v<F>& f_,
+ Image<O>& output_);
}
+
+
template <typename I, typename F, typename O>
- inline
- void transform_(mln::trait::image::quant::any, // general case
- const Image<I>& input_, const Function_v2v<F>& f_,
Image<O>& output_)
+ void transform_lowq(const Image<I>& input_,
+ const Function_v2v<F>& f_,
+ Image<O>& output_)
{
- generic::transform_(input_, f_, output_);
- }
+ trace::entering("level::impl::transform_lowq");
+
+ const I& input = exact(input_);
+ const F& f = exact(f_);
+ O& output = exact(output_);
+ level::internal::transform_tests(input, f, output);
+ mlc_is(mln_trait_image_pw_io(O),
+ trait::image::pw_io::read_write)::check();
+
+ value::lut_vec<mln_vset(I), mln_result(F)>
+ lut(input.values_eligible(), f);
+
+ mln_piter(I) p(input.domain());
+ for_all(p)
+ output(p) = lut(input(p));
+
+ trace::exiting("level::impl::transform_lowq");
+ }
template <typename I, typename F, typename O>
- inline
- void transform_(mln::trait::image::quant::low, // low quantization
- const Image<I>& input_, const Function_v2v<F>& f_,
Image<O>& output_)
+ void transform_taken(const Image<I>& input_,
+ const Function_v2v<F>& f_,
+ Image<O>& output_)
{
- trace::entering("level::impl::transform");
+ trace::entering("level::impl::transform_taken");
const I& input = exact(input_);
const F& f = exact(f_);
O& output = exact(output_);
- value::lut_vec<mln_vset(I), mln_result(F)> lut(input.values_eligible(), f);
+ level::internal::transform_tests(input, f, output);
+ mlc_is(mln_trait_image_pw_io(O),
+ trait::image::pw_io::read_write)::check();
+
+ value::lut_vec<mln_vset(I), mln_result(F)>
+ lut(input.taken_values(), f);
+
mln_piter(I) p(input.domain());
for_all(p)
output(p) = lut(input(p));
- trace::exiting("level::impl::transform");
+ trace::exiting("level::impl::transform_taken");
+ }
+
+
+ template <typename I, typename F, typename O>
+ void transform_singleton(const Image<I>& input_,
+ const Function_v2v<F>& f_,
+ Image<O>& output_)
+ {
+ trace::entering("level::impl::transform_singleton");
+
+ const I& input = exact(input_);
+ const F& f = exact(f_);
+
+ level::internal::transform_tests(input_, f_, output_);
+ mln_precondition((mlc_is(mln_trait_image_pw_io(O),
+ trait::image::pw_io::read_write)::value ||
+ mlc_is(mln_trait_image_vw_io(O),
+ trait::image::vw_io::read_write)::value));
+
+ mln_result(F) val = f(input.val());
+ fill_with_value(output_, val);
+
+ trace::exiting("level::impl::transform_singleton");
+ }
+
+ template <typename I, typename F, typename O>
+ void transform_fast(const Image<I>& input_,
+ const Function_v2v<F>& f_,
+ Image<O>& output_)
+ {
+ trace::entering("level::impl::transform_fast");
+
+ const I& input = exact(input_);
+ const F& f = exact(f_);
+ O& output = exact(output_);
+
+ level::internal::transform_tests(input, f, output);
+
+ mln_pixter(const I) pi(input);
+ mln_pixter(O) po(output);
+
+ po.start();
+ for_all(pi)
+ {
+ po.val() = f(pi.val());
}
+ trace::exiting("level::impl::transform_fast");
+ }
+
+
+
+ template <typename I, typename F, typename O>
+ void transform_fast_lowq(const Image<I>& input_,
+ const Function_v2v<F>& f_,
+ Image<O>& output_)
+ {
+ trace::entering("level::impl::transform_fast_lowq");
+
+ const I& input = exact(input_);
+ const F& f = exact(f_);
+ O& output = exact(output_);
+
+ level::internal::transform_tests(input, f, output);
+
+ value::lut_vec<mln_vset(I), mln_result(F)>
+ lut(input.values_eligible(), f);
+
+ mln_pixter(const I) pi(input);
+ mln_pixter(O) po(output);
+
+ po.start();
+ for_all(pi)
+ {
+ //po.val() = lut(pi.val);
+ po.val() = f(pi.val());
+ }
+
+ trace::exiting("level::impl::transform_fast_lowq");
+ }
+
+
+
+ // Dispatch
+ // --------
+ namespace internal
+ {
+
+ /// Deal with image not updated
+ template <typename I, typename F, typename O>
+ void transform_dispatch(mln::trait::undef,
+ mln::trait::image::quant::any,
+ const Image<I>& input,
+ const Function_v2v<F>& f,
+ Image<O>& output)
+ {
+ impl::generic::transform(input, f, output);
+ }
+
+ template <typename I, typename F, typename O>
+ void transform_dispatch(mln::trait::image::vw_set::any,
+ mln::trait::image::quant::any,
+ const Image<I>& input,
+ const Function_v2v<F>& f,
+ Image<O>& output)
+ {
+ impl::generic::transform(input, f, output);
+ }
+
+ template <typename I, typename F, typename O>
+ void transform_dispatch(mln::trait::image::vw_set::uni,
+ mln::trait::image::quant::any,
+ const Image<I>& input,
+ const Function_v2v<F>& f,
+ Image<O>& output)
+ {
+ impl::transform_taken(input, f, output);
+ }
+
+
+ template <typename I, typename F, typename O>
+ void transform_dispatch(mln::trait::image::vw_set::none,
+ mln::trait::image::quant::low,
+ const Image<I>& input,
+ const Function_v2v<F>& f,
+ Image<O>& output)
+ {
+ impl::transform_lowq(input, f, output);
+ }
+
+ template <typename I, typename F, typename O>
+ void transform_dispatch_oneblock(mln::trait::image::quant::any,
+ const Image<I>& input,
+ const Function_v2v<F>& f,
+ Image<O>& output)
+ {
+ transform_fast(input, f, output);
+ }
+
+ template <typename I, typename F, typename O>
+ void transform_dispatch_oneblock(mln::trait::image::quant::low,
+ const Image<I>& input,
+ const Function_v2v<F>& f,
+ Image<O>& output)
+ {
+ transform_fast_lowq(input, f, output);
+ }
+
+
+ template <typename I, typename F, typename O>
+ void transform_dispatch(mln::trait::image::value_storage::any,
+ mln::trait::image::value_storage::any,
+ const Image<I>& input,
+ const Function_v2v<F>& f,
+ Image<O>& output)
+ {
+ transform_dispatch(mln_trait_image_vw_set(I)(),
+ mln_trait_image_quant(I)(),
+ input, f, output);
+ }
+
+ template <typename I, typename F, typename O>
+ void transform_dispatch(mln::trait::image::value_storage::singleton,
+ mln::trait::image::value_storage::any,
+ const Image<I>& input,
+ const Function_v2v<F>& f,
+ Image<O>& output)
+ {
+ transform_singleton(input, f, output);
+ }
+
+ template <typename I, typename F, typename O>
+ void transform_dispatch(mln::trait::image::value_storage::one_block,
+ mln::trait::image::value_storage::one_block,
+ const Image<I>& input_,
+ const Function_v2v<F>& f_,
+ Image<O>& output_)
+ {
+ const I& input = exact(input_);
+ O& output = exact(output_);
+
+ /// Check basic properties
+ if (mlc_is(mln_trait_image_value_access(O),
+ trait::image::value_access::direct)::value &&
+ mlc_is(mln_trait_image_value_access(I),
+ trait::image::value_access::direct)::value &&
+ mlc_is(mln_trait_image_value_alignement(I),
+ trait::image::value_alignement::with_grid)::value &&
+ mlc_is(mln_trait_image_value_alignement(O),
+ trait::image::value_alignement::with_grid)::value)
+ {
+ /// Check ext_domain
+ if (
+ ((mlc_is(mln_trait_image_ext_domain(I),
+ trait::image::ext_domain::fixed)::value ||
+ mlc_is(mln_trait_image_ext_domain(I),
+ trait::image::ext_domain::extendable)::value) &&
+ (mlc_is(mln_trait_image_ext_domain(O),
+ trait::image::ext_domain::fixed)::value ||
+ mlc_is(mln_trait_image_ext_domain(O),
+ trait::image::ext_domain::extendable)::value) &&
+ input.border() == output.border()) ||
+ (mlc_is(mln_trait_image_ext_domain(I),
+ trait::image::ext_domain::none)::value &&
+ mlc_is(mln_trait_image_ext_domain(O),
+ trait::image::ext_domain::none)::value))
+ {
+
+ /// Check domain
+ if (input.domain() == output.domain())
+ transform_dispatch_oneblock(mln_trait_image_quant(I)(),
+ input, f_, output);
+ }
+ }
+ transform_dispatch(mln_trait_image_vw_set(I)(),
+ mln_trait_image_quant(I)(),
+ input, f_, output);
+ }
+
+
+
+ template <typename I, typename F, typename O>
+ void transform_dispatch(const Image<I>& input,
+ const Function_v2v<F>& f,
+ Image<O>& output)
+ {
+ transform_dispatch(mln_trait_image_value_storage(I)(),
+ mln_trait_image_value_storage(O)(),
+ input, f, output);
+ }
+
+ }
- // FIXME: Handle the cases of fastest images.
-// template <typename I, typename F, typename O>
-// void transform(metal::true_, // low quantization
-// const Image<I>& input_, const Function_v2v<F>& f_,
Image<O>& output_)
-// {
-// const I& input = exact(input_);
-// const F& f = exact(f_);
-// O& output = exact(output_);
-
-// value::lut_vec<mln_vset(I), mln_result(F)> lut(input.values(), f);
-// mln_pixter(const I) pi(input); // FIXME
-// mln_pixter(O) po(output);
-// po.start();
-// for_all(pi)
-// {
-// po.val() = lut(pi.val());
-// po.next();
-// }
-// }
} // end of namespace mln::level::impl
Index: mln/level/transform.hh
--- mln/level/transform.hh (revision 2558)
+++ mln/level/transform.hh (working copy)
@@ -76,23 +76,61 @@
# ifndef MLN_INCLUDE_ONLY
+ namespace internal
+ {
+ template <typename I, typename F, typename O>
+ inline
+ void transform_tests(const Image<I>& input,
+ const Function_v2v<F>& f,
+ Image<O>& output)
+ {
+ // Avoid a warning about an undefined variable when NDEBUG
+ // is not defined.
+ (void) input;
+ (void) f;
+ (void) output;
+
+ // Properties check
+ mln_precondition((mlc_is(mln_trait_image_pw_io(O),
+ trait::image::pw_io::read_write)::value ||
+ mlc_is(mln_trait_image_vw_io(O),
+ trait::image::vw_io::read_write)::value));
+
+ // FIXME Convert test
+ mlc_converts_to(mln_result(F), mln_value(O))::check();
+
+
+ // Dynamic tests
+ mln_precondition(exact(input).has_data());
+ mln_precondition(exact(output).domain() >= exact(input).domain());
+ }
+ } // end of namespace mln::level::internal
+
+
namespace impl
{
+
namespace generic
{
+ // Generic implementation.
template <typename I, typename F, typename O>
inline
- void transform_(const Image<I>& input_, const Function_v2v<F>& f_,
+ void transform(const Image<I>& input_, const Function_v2v<F>& f_,
Image<O>& output_)
{
trace::entering("level::impl::generic::transform");
+
const I& input = exact(input_);
const F& f = exact(f_);
O& output = exact(output_);
+ level::internal::transform_tests(input, f, output);
+ mlc_is(mln_trait_image_pw_io(O),
+ trait::image::pw_io::read_write)::check();
+
mln_piter(I) p(input.domain());
for_all(p)
output(p) = f( input(p) );
@@ -115,8 +153,8 @@
trace::entering("level::transform");
mln_precondition(exact(output).domain() >= exact(input).domain());
- impl::transform_(mln_trait_image_quant(I)(),
- exact(input), exact(f), exact(output));
+ impl::internal::transform_dispatch(exact(input), exact(f),
+ exact(output));
trace::exiting("level::transform");
}