27 #ifndef MLN_CANVAS_DISTANCE_FRONT_HH
28 # define MLN_CANVAS_DISTANCE_FRONT_HH
35 # include <mln/core/concept/image.hh>
36 # include <mln/core/concept/neighborhood.hh>
37 # include <mln/core/concept/weighted_window.hh>
38 # include <mln/data/fill.hh>
39 # include <mln/accu/stat/max.hh>
40 # include <mln/extension/adjust_fill.hh>
55 typename N,
typename W,
typename D,
59 const Neighborhood<N>& nbh, const Weighted_Window<W>& w_win, D
max,
64 # ifndef MLN_INCLUDE_ONLY
73 typename N,
typename W,
typename D,
76 distance_front_tests(
const Image<I>& input_,
77 const Neighborhood<N>& nbh_,
78 const Weighted_Window<W>& w_win_,
82 const I& input =
exact(input_);
83 const N& nbh =
exact(nbh_);
84 const W& w_win =
exact(w_win_);
86 mln_precondition(input.is_valid());
87 mln_precondition(nbh.is_valid());
109 template <
typename I,
110 typename N,
typename W,
typename D,
114 const Neighborhood<N>& nbh_,
115 const Weighted_Window<W>& w_win_,
119 mln_trace(
"canvas::impl::generic::distance_front");
121 const I& input =
exact(input_);
122 const N& nbh =
exact(nbh_);
123 const W& w_win =
exact(w_win_);
125 mln_precondition(input.is_valid());
126 mln_precondition(w_win.is_valid());
128 typedef mln_site(I) P;
129 typedef std::vector<P> bucket_t;
132 mln_ch_value(I, D) dmap;
139 accu::stat::max<unsigned> m;
140 for (
unsigned i = 0; i < w_win.size(); ++i)
146 std::vector<bucket_t> bucket(mod);
147 unsigned bucket_size = 0;
152 mln_piter(I)
p(input.domain());
153 mln_niter(N) n(nbh,
p);
155 if (functor.inqueue_p_wrt_input_p(input(p)))
159 if (input.domain().has(n) &&
160 functor.inqueue_p_wrt_input_n(input(n)))
162 bucket[0].push_back(p);
172 mln_qiter(W) q(w_win, p);
173 for (
unsigned d = 0; bucket_size != 0; ++d)
175 bucket_t& bucket_d = bucket[d % mod];
176 for (
unsigned i = 0; i < bucket_d.size(); ++i)
183 bucket_size = bucket_d.size();
192 if (dmap.domain().has(q) && dmap(q) > d)
194 unsigned d_ = d + q.w();
198 functor.process(p, q);
199 bucket[d_ % mod].push_back(q);
204 bucket_size -= bucket_d.size();
218 template <
typename I,
219 typename N,
typename W,
typename D,
222 distance_front_fastest(const Image<I>& input_,
223 const Neighborhood<N>& nbh_,
224 const Weighted_Window<W>& w_win_,
227 mln_trace(
"canvas::impl::distance_front_fastest");
229 const I& input =
exact(input_);
230 const N& nbh =
exact(nbh_);
231 const W& w_win =
exact(w_win_);
233 mln_precondition(input.is_valid());
234 mln_precondition(w_win.is_valid());
238 const unsigned n_ws = w_win.size();
239 util::array<int>
dp = offsets_wrt(input, w_win.win());
240 mln_invariant(dp.nelements() == n_ws);
243 mln_ch_value(I, D) dmap;
250 accu::stat::max<unsigned> m;
251 for (
unsigned i = 0; i < w_win.size(); ++i)
257 typedef std::vector<unsigned> bucket_t;
258 std::vector<bucket_t> bucket(mod);
259 unsigned bucket_size = 0;
263 functor.init_(input);
269 mln_pixter(
const I) p(input);
270 mln_nixter(const I, N) n(p, nbh);
272 if (functor.inqueue_p_wrt_input_p_(p.val()))
274 dmap.element(p.offset()) = 0;
276 if (functor.inqueue_p_wrt_input_n_(n.val()))
278 bucket[0].push_back(p.offset());
289 for (
unsigned d = 0; bucket_size != 0; ++d)
291 bucket_t& bucket_d = bucket[d % mod];
292 for (
unsigned i = 0; i < bucket_d.size(); ++i)
296 if (dmap.element(p) ==
max)
299 bucket_size = bucket_d.size();
303 if (dmap.element(p) < d)
307 for (
unsigned i = 0; i < n_ws; ++i)
309 unsigned q = p + dp[i];
310 if (dmap.element(q) > d)
312 unsigned d_ = d + w_win.w(i);
313 if (d_ < dmap.element(q))
315 dmap.element(q) = d_;
316 functor.process_(p, q);
317 bucket[d_ % mod].push_back(q);
323 bucket_size -= bucket_d.size();
341 template <
typename I,
342 typename N,
typename W,
typename D,
346 distance_front_dispatch(metal::false_,
347 const Image<I>& input,
348 const Neighborhood<N>& nbh, const Weighted_Window<W>& w_win,
354 template <
typename I,
355 typename N,
typename W,
typename D,
359 distance_front_dispatch(metal::true_,
360 const Image<I>& input,
361 const Neighborhood<N>& nbh, const Weighted_Window<W>& w_win,
364 return impl::distance_front_fastest(input, nbh, w_win, max, functor);
367 template <
typename I,
368 typename N,
typename W,
typename D,
372 distance_front_dispatch(const Image<I>& input,
373 const Neighborhood<N>& nbh, const Weighted_Window<W>& w_win,
377 test = mlc_equal(mln_trait_image_speed(I),
378 trait::image::speed::fastest)::
value
380 mln_is_simple_neighborhood(N)::
value
382 mln_is_simple_weighted_window(W)::
value
384 return distance_front_dispatch(metal::bool_<test>(),
385 input, nbh, w_win, max, functor);
395 template <
typename I,
396 typename N,
typename W,
typename D,
401 const Neighborhood<N>& nbh, const Weighted_Window<W>& w_win,
404 mln_trace(
"canvas::distance_front");
406 internal::distance_front_tests(input, nbh, w_win, max, functor);
408 mln_ch_value(I,D) output;
409 output = internal::distance_front_dispatch(input, nbh, w_win, max, functor);
415 # endif // ! MLN_INCLUDE_ONLY
422 #endif // ! MLN_CANVAS_DISTANCE_FRONT_HH