Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
influence_zone_geodesic.hh
1 // Copyright (C) 2008, 2009, 2011 EPITA Research and Development
2 // Laboratory (LRDE)
3 //
4 // This file is part of Olena.
5 //
6 // Olena is free software: you can redistribute it and/or modify it under
7 // the terms of the GNU General Public License as published by the Free
8 // Software Foundation, version 2 of the License.
9 //
10 // Olena is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
17 //
18 // As a special exception, you may use this file as part of a free
19 // software project without restriction. Specifically, if other files
20 // instantiate templates or use macros or inline functions from this
21 // file, or you compile this file and link it with other files to produce
22 // an executable, this file does not by itself cause the resulting
23 // executable to be covered by the GNU General Public License. This
24 // exception does not however invalidate any other reasons why the
25 // executable file might be covered by the GNU General Public License.
26 
27 #ifndef MLN_TRANSFORM_INFLUENCE_ZONE_GEODESIC_HH
28 # define MLN_TRANSFORM_INFLUENCE_ZONE_GEODESIC_HH
29 
33 
34 # include <mln/extension/adjust.hh>
35 # include <mln/canvas/distance_geodesic.hh>
36 # include <mln/transform/internal/influence_zone_functor.hh>
37 
38 
39 namespace mln
40 {
41 
42  namespace transform
43  {
44 
51  //
52  template <typename I, typename N>
53  mln_concrete(I)
54  influence_zone_geodesic(const Image<I>& input, const Neighborhood<N>& nbh);
55 
56 
57 
58 # ifndef MLN_INCLUDE_ONLY
59 
60 
61  namespace internal
62  {
63 
64  template <typename I, typename N>
65  void
66  influence_zone_geodesic_tests(const Image<I>& input,
67  const Neighborhood<N>& nbh)
68  {
69  mln_precondition(exact(input).is_valid());
70  mln_precondition(exact(nbh).is_valid());
71 
72  (void) input;
73  (void) nbh;
74  }
75 
76  } // end of namespace mln::transform::internal
77 
78 
79  namespace impl
80  {
81 
82  namespace generic
83  {
84 
85  template <typename I, typename N>
86  mln_concrete(I)
87  influence_zone_geodesic(const Image<I>& input,
88  const Neighborhood<N>& nbh)
89  {
90  (void) input;
91  (void) nbh;
92 
93  // FIXME: To be written...
94  mlc_abort(I)::check();
95  }
96 
97  } // end of namespace mln::transform::impl::generic
98 
99 
100  template <typename I, typename N>
101  mln_concrete(I)
102  influence_zone_geodesic_fastest(const Image<I>& input_,
103  const Neighborhood<N>& nbh_)
104  {
105  trace::entering("transform::impl::influence_zone_geodesic_fastest");
106 
107  const I& input = exact(input_);
108  const N& nbh = exact(nbh_);
109 
110  internal::influence_zone_geodesic_tests(input, nbh);
111 
112  std::queue<mln_value(I)*> q;
113  mln_concrete(I) output;
114 
115  util::array<int> dp = offsets_wrt(input, nbh);
116  const unsigned n_nbhs = dp.nelements();
117 
118  // Initialization.
119  {
120  extension::adjust(input, nbh);
121  output = duplicate(input);
122  // For the extension to be ignored:
123  extension::fill(input, 0); // in initialization
124  extension::fill(output, 1); // in propagation
125 
126  const unsigned nelts = input.nelements();
127  const mln_value(I)* p_i = input.buffer();
128  mln_value(I)* p_o = output.buffer();
129  for (unsigned i = 0; i < nelts; ++i, ++p_i, ++p_o)
130  {
131  if (*p_i == 0)
132  continue;
133  for (unsigned j = 0; j < n_nbhs; ++j)
134  {
135  const mln_value(I)* n_i = p_i + dp[j];
136  if (*n_i == 0)
137  {
138  q.push(p_o);
139  break;
140  }
141  }
142  }
143 
144  }
145 
146  // Propagation.
147  {
148  mln_value(I)* ptr;
149 
150  while (! q.empty())
151  {
152  ptr = q.front();
153  q.pop();
154  mln_invariant(*ptr != 0);
155  for (unsigned j = 0; j < n_nbhs; ++j)
156  {
157  mln_value(I)* ntr = ptr + dp[j];
158  if (*ntr == 0)
159  {
160  *ntr = *ptr;
161  q.push(ntr);
162  }
163  }
164  }
165  }
166 
167  trace::exiting("transform::impl::influence_zone_geodesic_fastest");
168  return output;
169  }
170 
171 
172  } // end of namespace mln::transform::impl
173 
174 
175  namespace internal
176  {
177 
178  template <typename I, typename N>
179  mln_concrete(I)
180  influence_zone_geodesic_dispatch(trait::image::value_alignment::any,
181  trait::image::value_storage::any,
182  trait::image::value_access::any,
183  const I& input,
184  const N& nbh)
185  {
186  return impl::generic::influence_zone_geodesic(input, nbh);
187  }
188 
189 
190  template <typename I, typename N>
191  mln_concrete(I)
192  influence_zone_geodesic_dispatch(trait::image::value_alignment::with_grid,
193  trait::image::value_storage::one_block,
194  trait::image::value_access::direct,
195  const I& input,
196  const N& nbh)
197  {
198  return impl::influence_zone_geodesic_fastest(input, nbh);
199  }
200 
201 
202  template <typename I, typename N>
203  mln_concrete(I)
204  influence_zone_geodesic_dispatch(const Image<I>& input,
205  const Neighborhood<N>& nbh)
206  {
207  return
208  influence_zone_geodesic_dispatch(mln_trait_image_value_alignment(I)(),
209  mln_trait_image_value_storage(I)(),
210  mln_trait_image_value_access(I)(),
211  exact(input), exact(nbh));
212  }
213 
214  } // end of namespace mln::transform::internal
215 
216 
217  template <typename I, typename N>
218  mln_concrete(I)
219  influence_zone_geodesic(const Image<I>& input, const Neighborhood<N>& nbh)
220  {
221  trace::entering("transform::influence_zone_geodesic");
222 
223  internal::influence_zone_geodesic_tests(input, nbh);
224 
225  mln_concrete(I)
226  output = internal::influence_zone_geodesic_dispatch(input, nbh);
227 
228  trace::exiting("transform::influence_zone_geodesic");
229  return output;
230  }
231 
232 # endif // ! MLN_INCLUDE_ONLY
233 
234  } // end of namespace mln::transform
235 
236 } // end of namespace mln
237 
238 
239 #endif // ! MLN_TRANSFORM_INFLUENCE_ZONE_GEODESIC_HH