27 #ifndef MLN_ACCU_TRANSFORM_DIRECTIONAL_HH
28 # define MLN_ACCU_TRANSFORM_DIRECTIONAL_HH
39 # include <mln/core/concept/image.hh>
40 # include <mln/core/concept/meta_accumulator.hh>
41 # include <mln/core/alias/window2d.hh>
42 # include <mln/win/diff.hh>
43 # include <mln/win/shift.hh>
44 # include <mln/geom/delta.hh>
45 # include <mln/literal/zero.hh>
46 # include <mln/extension/adjust.hh>
47 # include <mln/canvas/browsing/directional.hh>
58 template <
typename A,
typename I,
typename W>
59 mln_ch_value(I, mln_result(A))
61 const Image<I>& input, const Window<W>& win,
65 template <typename A, typename I, typename W>
66 mln_ch_value(I, mln_meta_accu_result(A, mln_value(I)))
68 const Image<I>& input, const Window<W>& win,
73 # ifndef MLN_INCLUDE_ONLY
82 template <
typename I,
typename W>
83 void transform_directional_tests(
const Image<I>& input_,
const Window<W>& win_)
85 const I& input =
exact(input_);
86 const W& win =
exact(win_);
88 mln_precondition(input.is_valid());
89 mln_precondition(win.is_valid());
90 mln_precondition(! win.is_empty());
101 template <
typename Dp>
102 Dp dp_directional(
int dir)
114 template <
typename I_,
typename W,
typename A>
115 struct directional_functor
122 mln_ch_value(I, mln_result(A)) output;
125 typedef mln_site(I) S;
126 enum { dim = S::dim };
139 directional_functor(const I& input, const W& win, const A& a,
int dir)
144 win_left(win::shift(win, -dp_directional<dpsite>(dir)) - win),
145 win_right(win - win::shift(win, -dp_directional<dpsite>(dir))),
161 mln_qiter(W) q(win,
p);
162 for_all(q) if (input.has(q))
169 for_all(q_l) if (input.has(q_l))
170 accu.untake(input(q_l));
171 for_all(q_r) if (input.has(q_r))
172 accu.
take(input(q_r));
187 template <
typename I_,
typename W,
typename A>
188 struct directional_fastest_functor
195 mln_ch_value(I, mln_result(A)) output;
199 typedef mln_site(I) S;
200 enum { dim = S::dim };
203 window2d win_left, win_right;
205 mln_qixter(
const I, window2d) q_l, q_r;
207 directional_fastest_functor(const I& input, const W& win, const A& a,
unsigned dir)
212 win_left(win::shift(win, -dp_directional<dpsite>(dir)) - win),
213 win_right(win - win::shift(win, -dp_directional<dpsite>(dir))),
214 q_l(input, win_left,
p),
215 q_r(input, win_right, p)
227 accu.untake(q_l.val());
229 accu.
take(q_r.val());
238 mln_qixter(
const I, W) q(input, win,
p);
255 template <
typename A,
typename I,
typename W>
257 mln_ch_value(I, mln_result(A))
258 transform_directional_dispatch(metal::false_,
259 const Accumulator<A>& a,
260 const Image<I>& input, const Window<W>& win,
263 typedef directional_functor<I, W, A> F;
269 template <
typename A,
typename I,
typename W>
271 mln_ch_value(I, mln_result(A))
272 transform_directional_dispatch(metal::true_,
273 const Accumulator<A>& a,
274 const Image<I>& input, const Window<W>& win,
277 typedef directional_fastest_functor<I, W, A> F;
283 template <
typename A,
typename I,
typename W>
285 mln_ch_value(I, mln_result(A))
286 transform_directional_dispatch(const Accumulator<A>& a,
287 const Image<I>& input, const Window<W>& win,
290 return transform_directional_dispatch(mln_is_fastest_IW(I, W)(),
299 template <
typename A,
typename I,
typename W>
301 mln_ch_value(I, mln_result(A))
303 const Image<I>& input, const Window<W>& win,
306 mln_trace(
"accu::transform_directional");
308 internal::transform_directional_tests(input, win);
311 mln_ch_value(I, mln_result(A)) output;
312 output = internal::transform_directional_dispatch(a, input, win, dir);
318 template <typename A, typename I, typename W>
320 mln_ch_value(I, mln_meta_accu_result(A, mln_value(I)))
322 const Image<I>& input, const Window<W>& win,
325 mln_trace(
"accu::transform_directional");
327 internal::transform_directional_tests(input, win);
329 typedef mln_accu_with(A, mln_value(I)) A_;
333 mln_ch_value(I, mln_result(A_)) output;
334 output = internal::transform_directional_dispatch(a_, input, win, dir);
340 # endif // ! MLN_INCLUDE_ONLY
347 #endif // ! MLN_ACCU_TRANSFORM_DIRECTIONAL_HH