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))
64 const Image<I>& input, const Window<W>& win);
67 template <typename A, typename I, typename W>
68 mln_ch_value(I, mln_meta_accu_result(A, mln_value(I)))
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
110 mln_ch_value(I, mln_result(A)) output;
114 typedef mln_site(I) S;
115 enum { dim = S::dim };
117 window2d win_left, win_right;
119 mln_qiter(window2d) q_l, q_r;
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
173 mln_ch_value(I, mln_result(A)) output;
177 typedef mln_site(I) S;
178 enum { dim = S::dim };
180 window2d win_left, win_right;
182 mln_qiter(window2d) q_l, q_r;
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
239 mln_ch_value(I, mln_result(A)) output;
243 typedef mln_site(I) S;
244 enum { dim = S::dim };
246 window2d win_left, win_right;
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
301 mln_ch_value(I, mln_result(A)) output;
305 typedef mln_site(I) S;
306 enum { dim = S::dim };
308 window2d win_left, win_right;
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;
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;
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;
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;
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))
430 const Image<I>& input, const Window<W>& win)
432 mln_trace(
"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);
444 template <typename A, typename I, typename W>
446 mln_ch_value(I, mln_meta_accu_result(A, mln_value(I)))
448 const Image<I>& input, const Window<W>& win)
450 mln_trace(
"accu::transform_diagonal");
452 internal::transform_diagonal_tests(input, win);
454 typedef mln_accu_with(A, mln_value(I)) A_;
458 mln_ch_value(I, mln_result(A_)) output;
459 output = internal::transform_diagonal_dispatch(a_, input, win);
465 # endif // ! MLN_INCLUDE_ONLY
472 #endif // ! MLN_ACCU_TRANSFORM_DIAGONAL_HH