27 #ifndef MLN_ACCU_LINE_HH
28 # define MLN_ACCU_LINE_HH
36 # include <mln/core/concept/meta_accumulator.hh>
37 # include <mln/core/concept/image.hh>
63 template <
typename Meta_Accu,
unsigned Dir,
64 typename I,
typename O>
66 line(
const Image<I>& input,
73 # ifndef MLN_INCLUDE_ONLY
78 template <
typename Meta_Accu,
unsigned Dir,
79 typename I,
typename O>
81 line_tests(
const Image<I>& input_,
82 const mln_site(I)&,
unsigned,
86 mlc_is_a(Meta_Accu, Meta_Accumulator)::check();
88 typedef mln_accu_with(Meta_Accu, mln_value(I)) A;
89 mlc_converts_to(mln_result(A), mln_value(O))::check();
91 typedef mln_site(I) P;
92 mlc_bool(Dir < P::dim)::check();
94 mlc_is(mln_trait_image_value_io(O),
95 mln::trait::image::value_io::read_write)::check();
97 const I& input =
exact(input_);
98 O& output =
exact(output_);
99 mln_precondition(input.is_valid());
100 mln_precondition(output.is_valid());
112 template <
typename Meta_Accu,
unsigned Dir,
113 typename I,
typename O>
115 line(
const Image<I>& input_,
116 const mln_site(I)& p_start,
unsigned len_,
117 unsigned half_length_,
120 typedef mln_site(I) P;
121 typedef mln_accu_with(Meta_Accu, mln_value(I)) A;
123 const I& input =
exact(input_);
124 O& output =
exact(output_);
127 const def::
coord len = static_cast<def::
coord>(len_);
128 const def::
coord half_length = static_cast<def::
coord>(half_length_);
131 internal::line_tests<Meta_Accu, Dir>(input,
137 const def::
coord start = p_start[Dir];
138 const def::
coord last = static_cast<def::
coord>(start + len - 1);
146 for (def::
coord c = 0; c <= half_length && c < len; ++c)
161 plus =
static_cast<def::coord>(plus + half_length);
163 while (cur < start + half_length && cur < last)
168 a.take(input(p_plus));
181 while (cur < last - half_length)
186 mln_invariant(plus >= start && plus <= last);
187 a.take(input(p_plus));
188 mln_invariant(minus >= start && minus <= last);
189 a.untake(input(p_minus));
202 mln_invariant(minus >= start && minus <= last);
203 a.untake(input(p_minus));
212 template <
typename Meta_Accu,
unsigned Dir,
213 typename I,
typename O>
215 line_fastest(
const Image<I>& input_,
220 typedef mln_site(I) P;
221 typedef mln_value(I) V;
222 typedef mln_accu_with(Meta_Accu, V) A;
224 const I& input =
exact(input_);
225 O& output =
exact(output_);
228 internal::line_tests<Meta_Accu, Dir>(input,
235 const def::
coord start = p_start[Dir];
236 const def::
coord last = start + len - 1;
238 const V* p_in = & input(p_start);
239 V* p_out = & output(p_start);
241 mln_delta(P) dp = literal::zero;
243 unsigned offset = input.delta_offset(dp);
251 for (def::
coord c = 0; c <= half_length && c < len; ++c)
265 const V* p_plus = p_in + half_length * offset;
267 while (cur < start + half_length && cur < last)
285 const V* p_minus = p_in - offset;
287 while (cur < last - half_length)
295 mln_invariant(plus >= start && plus <= last);
297 mln_invariant(minus >= start && minus <= last);
314 mln_invariant(minus >= start && minus <= last);
331 template <
typename Meta_Accu,
unsigned Dir,
332 typename I,
typename O>
334 line_dispatch(trait::image::speed::any,
335 const Image<I>& input,
336 const mln_site(I)& p_start,
unsigned len,
337 unsigned half_length,
340 impl::generic::line<Meta_Accu, Dir>(input,
361 template <
typename Meta_Accu,
unsigned Dir,
362 typename I,
typename O>
364 line_dispatch(
const Image<I>& input,
365 const mln_site(I)& p_start,
unsigned len,
366 unsigned half_length,
369 line_dispatch<Meta_Accu, Dir>(mln_trait_image_speed(I)(),
379 template <
typename Meta_Accu,
unsigned Dir,
380 typename I,
typename O>
382 line(
const Image<I>& input,
383 const mln_site(I)& p_start,
unsigned len,
384 unsigned half_length,
387 internal::line_tests<Meta_Accu, Dir>(input,
391 internal::line_dispatch<Meta_Accu, Dir>(input,
397 # endif // ! MLN_INCLUDE_ONLY
404 #endif // ! MLN_ACCU_LINE_HH