26 #ifndef MLN_ACCU_TRANSFORM_DIAGONAL_HH
27 # define MLN_ACCU_TRANSFORM_DIAGONAL_HH
38 #include <mln/core/concept/image.hh>
39 #include <mln/core/concept/meta_accumulator.hh>
40 #include <mln/core/alias/window2d.hh>
41 #include <mln/win/diff.hh>
42 #include <mln/win/shift.hh>
43 #include <mln/geom/delta.hh>
44 #include <mln/extension/adjust.hh>
46 #include <mln/win/diag2d.hh>
47 #include <mln/canvas/browsing/diagonal2d.hh>
49 #include <mln/win/backdiag2d.hh>
50 #include <mln/canvas/browsing/backdiagonal2d.hh>
61 template <
typename A,
typename I,
typename W>
62 mln_ch_value(I, mln_result(A))
63 transform_diagonal(const Accumulator<A>& a,
64 const Image<I>& input, const Window<W>& win);
67 template <typename A, typename I, typename W>
69 transform_diagonal(const Meta_Accumulator<A>& a,
70 const Image<I>& input, const Window<W>& win);
74 # ifndef MLN_INCLUDE_ONLY
83 template <
typename I,
typename W>
84 void transform_diagonal_tests(
const Image<I>& input_,
const Window<W>& win_)
86 const I& input = exact(input_);
87 const W& win = exact(win_);
89 mln_precondition(input.is_valid());
90 mln_precondition(win.is_valid());
91 mln_precondition(! win.is_empty());
102 template <
typename I_,
typename W,
typename A>
103 struct diagonal_functor
106 typedef mln_deduce(I, psite, delta) dpsite;
110 mln_ch_value(I, mln_result(A)) output;
114 typedef mln_site(I) S;
115 enum { dim = S::dim };
121 diagonal_functor(const I& input, const W& win, const A& a)
125 win_left(win::shift(win, dpsite(1, -1)) - win),
126 win_right(win - win::shift(win, dpsite(1, -1))),
140 accu.untake(input(q_l));
142 accu.
take(input(q_r));
150 p = p - dpsite(-1, 1);
151 mln_qiter(W) q(win, p);
154 p = p + dpsite(-1, 1);
165 template <
typename I_,
typename W,
typename A>
166 struct backdiagonal_functor
169 typedef mln_deduce(I, psite, delta) dpsite;
173 mln_ch_value(I, mln_result(A)) output;
177 typedef mln_site(I) S;
178 enum { dim = S::dim };
184 backdiagonal_functor(const I& input, const W& win, const A& a)
188 win_left(win::shift(win, dpsite(-1, -1)) - win),
189 win_right(win - win::shift(win, dpsite(-1, -1))),
203 accu.untake(input(q_l));
205 accu.
take(input(q_r));
213 p = p - dpsite(1, 1);
214 mln_qiter(W) q(win, p);
217 p = p + dpsite(1, 1);
231 template <
typename I_,
typename W,
typename A>
232 struct diagonal_fastest_functor
235 typedef mln_deduce(I, psite, delta) dpsite;
239 mln_ch_value(I, mln_result(A)) output;
243 typedef mln_site(I) S;
244 enum { dim = S::dim };
248 mln_qixter(
const I,
window2d) q_l, q_r;
250 diagonal_fastest_functor(const I& input, const W& win, const A& a)
254 win_left(win::shift(win, dpsite(1, -1)) - win),
255 win_right(win - win::shift(win, dpsite(1, -1))),
256 q_l(input, win_left, p),
257 q_r(input, win_right, p)
269 accu.untake(q_l.val());
271 accu.
take(q_r.val());
279 p = p - dpsite(-1, 1);
280 mln_qixter(
const I, W) q(input, win, p);
283 p = p + dpsite(-1, 1);
293 template <
typename I_,
typename W,
typename A>
294 struct backdiagonal_fastest_functor
297 typedef mln_deduce(I, psite, delta) dpsite;
301 mln_ch_value(I, mln_result(A)) output;
305 typedef mln_site(I) S;
306 enum { dim = S::dim };
310 mln_qixter(
const I,
window2d) q_l, q_r;
312 backdiagonal_fastest_functor(const I& input, const W& win, const A& a)
316 win_left(win::shift(win, dpsite(-1, -1)) - win),
317 win_right(win - win::shift(win, dpsite(-1, -1))),
318 q_l(input, win_left, p),
319 q_r(input, win_right, p)
331 accu.untake(q_l.val());
333 accu.
take(q_r.val());
341 p = p - dpsite(1, 1);
342 mln_qixter(
const I, W) q(input, win, p);
345 p = p + dpsite(1, 1);
359 template <
typename A,
typename I>
361 mln_ch_value(I, mln_result(A))
362 transform_diagonal_dispatch(metal::false_,
363 const Accumulator<A>& a,
364 const Image<I>& input, const win::diag2d& win)
366 typedef diagonal_functor<I, win::diag2d, A> F;
367 F f(exact(input), win, exact(a));
368 canvas::browsing::diagonal2d(f);
372 template <
typename B,
typename A,
typename I>
374 mln_ch_value(I, mln_result(A))
375 transform_diagonal_dispatch(metal::false_,
376 const Accumulator<A>& a,
377 const Image<I>& input, const win::backdiag2d& win)
379 typedef backdiagonal_functor<I, win::backdiag2d, A> F;
380 F f(exact(input), win, exact(a));
381 canvas::browsing::backdiagonal2d(f);
385 template <
typename A,
typename I>
387 mln_ch_value(I, mln_result(A))
388 transform_diagonal_dispatch(metal::true_,
389 const Accumulator<A>& a,
390 const Image<I>& input, const win::diag2d& win)
392 typedef diagonal_fastest_functor<I, win::diag2d, A> F;
393 F f(exact(input), win, exact(a));
394 canvas::browsing::diagonal2d(f);
398 template <
typename A,
typename I>
400 mln_ch_value(I, mln_result(A))
401 transform_diagonal_dispatch(metal::true_,
402 const Accumulator<A>& a,
403 const Image<I>& input, const win::backdiag2d& win)
405 typedef backdiagonal_fastest_functor<I, win::backdiag2d, A> F;
406 F f(exact(input), win, exact(a));
407 canvas::browsing::backdiagonal2d(f);
411 template <
typename A,
typename I,
typename W>
413 mln_ch_value(I, mln_result(A))
414 transform_diagonal_dispatch(const Accumulator<A>& a,
415 const Image<I>& input, const Window<W>& win)
417 return transform_diagonal_dispatch(mln_is_fastest_IW(I, W)(),
418 a, input, exact(win));
426 template <
typename A,
typename I,
typename W>
428 mln_ch_value(I, mln_result(A))
429 transform_diagonal(const Accumulator<A>& a,
430 const Image<I>& input, const Window<W>& win)
432 trace::entering(
"accu::transform_diagonal");
434 internal::transform_diagonal_tests(input, win);
437 mln_ch_value(I, mln_result(A)) output;
438 output = internal::transform_diagonal_dispatch(a, input, win);
440 trace::exiting("accu::transform_diagonal");
445 template <typename A, typename I, typename W>
448 transform_diagonal(const Meta_Accumulator<A>& a,
449 const Image<I>& input, const Window<W>& win)
451 trace::entering(
"accu::transform_diagonal");
453 internal::transform_diagonal_tests(input, win);
455 typedef mln_accu_with(A, mln_value(I)) A_;
456 A_ a_ = accu::unmeta(exact(a), mln_value(I)());
458 extension::adjust(input, geom::delta(win) + 1);
459 mln_ch_value(I, mln_result(A_)) output;
460 output = internal::transform_diagonal_dispatch(a_, input, win);
462 trace::exiting("accu::transform_diagonal");
467 # endif // ! MLN_INCLUDE_ONLY
474 #endif // ! MLN_ACCU_TRANSFORM_DIAGONAL_HH