$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
transform_directional.hh
1 // Copyright (C) 2008, 2009 EPITA Research and Development Laboratory
2 // (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_ACCU_TRANSFORM_DIRECTIONAL_HH
28 # define MLN_ACCU_TRANSFORM_DIRECTIONAL_HH
29 
37 
38 
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>
48 
49 
50 
51 namespace mln
52 {
53 
54  namespace accu
55  {
56 
57 
58  template <typename A, typename I, typename W>
59  mln_ch_value(I, mln_result(A))
60  transform_directional(const Accumulator<A>& a,
61  const Image<I>& input, const Window<W>& win,
62  unsigned dir);
63 
64 
65  template <typename A, typename I, typename W>
66  mln_ch_value(I, mln_meta_accu_result(A, mln_value(I)))
67  transform_directional(const Meta_Accumulator<A>& a,
68  const Image<I>& input, const Window<W>& win,
69  unsigned dir);
70 
71 
72 
73 # ifndef MLN_INCLUDE_ONLY
74 
75  namespace internal
76  {
77 
78 
79  // Tests.
80 
81 
82  template <typename I, typename W>
83  void transform_directional_tests(const Image<I>& input_, const Window<W>& win_)
84  {
85  const I& input = exact(input_);
86  const W& win = exact(win_);
87 
88  mln_precondition(input.is_valid());
89  mln_precondition(win.is_valid());
90  mln_precondition(! win.is_empty());
91 
92  (void) input;
93  (void) win;
94  }
95 
96 
97 
98  // Utility.
99 
100 
101  template <typename Dp>
102  Dp dp_directional(int dir)
103  {
104  Dp dp = literal::zero;
105  dp[dir] = 1;
106  return dp;
107  }
108 
109 
110 
111  // Functor.
112 
113 
114  template <typename I_, typename W, typename A>
115  struct directional_functor
116  {
117  typedef I_ I;
118  typedef mln_deduce(I, psite, delta) dpsite;
119 
120  const I& input;
121  const W& win;
122  mln_ch_value(I, mln_result(A)) output;
123  A accu;
124 
125  typedef mln_site(I) S; // Help g++-2.95.
126  enum { dim = S::dim };
127 
128  mln_psite(I) p;
129  unsigned dir;
130 
131  window2d
132  win_left,
133  win_right;
134 
135  mln_qiter(window2d)
136  q_l,
137  q_r;
138 
139  directional_functor(const I& input, const W& win, const A& a, int dir)
140  : input(input),
141  win(win),
142  accu(a),
143  dir(dir),
144  win_left(win::shift(win, -dp_directional<dpsite>(dir)) - win),
145  win_right(win - win::shift(win, -dp_directional<dpsite>(dir))),
146  q_l(win_left, p),
147  q_r(win_right, p)
148  {
149 
150  }
151 
152  void init()
153  {
154  initialize(output, input);
155  }
156 
157  void init_run()
158  {
159  accu.init();
160  p[dir]--;
161  mln_qiter(W) q(win, p);
162  for_all(q) if (input.has(q))
163  accu.take(input(q));
164  p[dir]++;
165  }
166 
167  void next()
168  {
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));
173  output(p) = accu;
174  }
175 
176  void final()
177  {
178  }
179 
180  };
181 
182 
183 
184  // Functor (fastest version).
185 
186 
187  template <typename I_, typename W, typename A>
188  struct directional_fastest_functor
189  {
190  typedef I_ I;
191  typedef mln_deduce(I, psite, delta) dpsite;
192 
193  const I& input;
194  const W& win;
195  mln_ch_value(I, mln_result(A)) output;
196  A accu;
197 
198  mln_psite(I) p;
199  typedef mln_site(I) S;
200  enum { dim = S::dim };
201  unsigned dir;
202 
203  window2d win_left, win_right;
204 
205  mln_qixter(const I, window2d) q_l, q_r;
206 
207  directional_fastest_functor(const I& input, const W& win, const A& a, unsigned dir)
208  : input(input),
209  win(win),
210  accu(a),
211  dir(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)
216  {
217  }
218 
219  void init()
220  {
221  initialize(output, input);
222  }
223 
224  void next()
225  {
226  for_all(q_l)
227  accu.untake(q_l.val());
228  for_all(q_r)
229  accu.take(q_r.val());
230  output(p) = accu;
231  }
232 
233 
234  void init_run()
235  {
236  accu.init();
237  p[dir]--;
238  mln_qixter(const I, W) q(input, win, p);
239  for_all(q)
240  accu.take(q.val());
241  p[dir]++;
242  }
243 
244  void final()
245  {
246  }
247 
248  };
249 
250 
251 
252 
253  // Both dispatch and implementation (hum...)
254 
255  template <typename A, typename I, typename W>
256  inline
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,
261  unsigned dir)
262  {
263  typedef directional_functor<I, W, A> F;
264  F f(exact(input), exact(win), exact(a), dir);
266  return f.output;
267  }
268 
269  template <typename A, typename I, typename W>
270  inline
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,
275  unsigned dir)
276  {
277  typedef directional_fastest_functor<I, W, A> F;
278  F f(exact(input), exact(win), exact(a), dir);
280  return f.output;
281  }
282 
283  template <typename A, typename I, typename W>
284  inline
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,
288  unsigned dir)
289  {
290  return transform_directional_dispatch(mln_is_fastest_IW(I, W)(),
291  a, input, win, dir);
292  }
293 
294  } // end of namespace mln::accu::internal
295 
296 
297 
298 
299  template <typename A, typename I, typename W>
300  inline
301  mln_ch_value(I, mln_result(A))
302  transform_directional(const Accumulator<A>& a,
303  const Image<I>& input, const Window<W>& win,
304  unsigned dir)
305  {
306  mln_trace("accu::transform_directional");
307 
308  internal::transform_directional_tests(input, win);
309 
310  extension::adjust(input, geom::delta(win) + 1);
311  mln_ch_value(I, mln_result(A)) output;
312  output = internal::transform_directional_dispatch(a, input, win, dir);
313 
314  return output;
315  }
316 
317 
318  template <typename A, typename I, typename W>
319  inline
320  mln_ch_value(I, mln_meta_accu_result(A, mln_value(I)))
321  transform_directional(const Meta_Accumulator<A>& a,
322  const Image<I>& input, const Window<W>& win,
323  unsigned dir)
324  {
325  mln_trace("accu::transform_directional");
326 
327  internal::transform_directional_tests(input, win);
328 
329  typedef mln_accu_with(A, mln_value(I)) A_;
330  A_ a_ = accu::unmeta(exact(a), mln_value(I)());
331 
332  extension::adjust(input, geom::delta(win) + 1);
333  mln_ch_value(I, mln_result(A_)) output;
334  output = internal::transform_directional_dispatch(a_, input, win, dir);
335 
336  return output;
337  }
338 
339 
340 # endif // ! MLN_INCLUDE_ONLY
341 
342  } // end of namespace mln::accu
343 
344 } // end of namespace mln
345 
346 
347 #endif // ! MLN_ACCU_TRANSFORM_DIRECTIONAL_HH