$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
multiple.hh
1 // Copyright (C) 2008, 2009, 2012 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_WIN_MULTIPLE_HH
28 # define MLN_WIN_MULTIPLE_HH
29 
35 
36 # include <mln/core/window.hh>
37 # include <mln/core/internal/site_relative_iterator_base.hh>
38 # include <mln/util/array.hh>
39 
40 
41 
42 namespace mln
43 {
44 
45  // Forward declarations.
46  namespace win
47  {
48  template <typename W, typename F> class multiple;
49  template <typename W, typename F> class multiple_qiter;
50  }
51 
52 
53 
54  namespace trait
55  {
56 
57  template <typename W, typename F>
58  struct window_< win::multiple<W,F> >
59  {
60  typedef trait::window::size::fixed size;
61  typedef trait::window::support::regular support;
62  typedef trait::window::definition::n_ary definition;
63  };
64 
65  } // end of namespace trait
66 
67 
68 
69  namespace win
70  {
71 
72 
76  template <typename W, typename F>
77  class multiple
78 
79  : public internal::window_base< mln_dpsite(W), multiple<W,F> >,
80 
81  private metal::and_< mlc_is(mln_trait_window_size(W),
82  trait::window::size::fixed),
83  mlc_is(mln_trait_window_support(W),
84  trait::window::support::regular) >::check_t
85  {
86  public:
87 
88  typedef mln_dpsite(W) dpsite;
89  typedef mln_psite(W) psite;
90  typedef mln_site(W) site;
91 
92  typedef multiple< window<dpsite>, F > regular;
93 
94  typedef multiple_qiter<W,F> fwd_qiter;
95  typedef /* FIXME: */ multiple_qiter<W,F> bkd_qiter;
96  typedef multiple_qiter<W,F> qiter;
97 
98  typedef W element;
99 
100  multiple();
101 
102  multiple(const F& f);
103 
104  bool is_empty() const;
105 
106  void set_window(unsigned i, const W& win);
107 
108  const W& window_(unsigned i) const;
109 
110  unsigned nwindows() const;
111 
112  const F& function() const;
113 
114  unsigned size() const;
115 
116  const mln_dpsite(W)& ith_dp_around(unsigned i, const mln_psite(W)& p) const;
117 
118  bool is_centered() const;
119 
120  bool is_symmetric() const;
121 
122  void sym();
123 
124  unsigned delta() const;
125 
126  private:
127 
128  util::array<W> win_;
129  F f_;
130  };
131 
132 
133  template <typename W, typename F>
135  : public internal::site_relative_iterator_base< multiple<W,F>,
136  multiple_qiter<W,F> >
137  {
138  typedef multiple_qiter<W,F> self_;
140  public:
141 
142  multiple_qiter();
143  template <typename Pref>
144  multiple_qiter(const multiple<W,F>& w, const Pref& c);
145 
147  void change_target(const multiple<W,F>& w);
148 
150  template <typename Pref>
151  void init_(const multiple<W,F>& w, const Pref& c);
152 
154  bool is_valid_() const;
155 
157  void invalidate_();
158 
160  void do_start_();
161 
163  void do_next_();
164 
166  mln_psite(W) compute_p_() const;
167 
168  private:
169  unsigned i_;
170  unsigned size_;
171  };
172 
173 
174 
175 # ifndef MLN_INCLUDE_ONLY
176 
177  // win::multiple<W,F>
178 
179  template <typename W, typename F>
180  inline
182  : f_()
183  {
184  }
185 
186  template <typename W, typename F>
187  inline
188  multiple<W,F>::multiple(const F& f)
189  : f_(f)
190  {
191  }
192 
193  template <typename W, typename F>
194  inline
195  bool
197  {
198  return win_.is_empty();
199  }
200 
201  template <typename W, typename F>
202  inline
203  void
204  multiple<W,F>::set_window(unsigned i, const W& win)
205  {
206  mln_precondition(i == win_.nelements());
207  if (i >= 1)
208  mln_precondition(win.size() == win_[0].size());
209  win_.append(win);
210  }
211 
212  template <typename W, typename F>
213  inline
214  const W&
215  multiple<W,F>::window_(unsigned i) const
216  {
217  mln_precondition(i < win_.nelements());
218  return win_[i];
219  }
220 
221  template <typename W, typename F>
222  inline
223  unsigned
225  {
226  return win_.nelements();
227  }
228 
229  template <typename W, typename F>
230  inline
231  const F&
233  {
234  return f_;
235  }
236 
237  template <typename W, typename F>
238  inline
239  unsigned
240  multiple<W,F>::size() const
241  {
242  mln_precondition(win_.nelements() >= 2); // Multiple cannot be just 1 element.
243  unsigned s = win_[0].size();
244  for (unsigned i = 1; i < win_.nelements(); ++i)
245  mln_precondition(win_[i].size() == s);
246  return s;
247  }
248 
249  template <typename W, typename F>
250  inline
251  bool
253  {
254  mln_precondition(win_.nelements() >= 1);
255  for (unsigned i = 0; i < win_.nelements(); ++i)
256  if (! win_[i].is_centered())
257  return false;
258  return true;
259  }
260 
261  template <typename W, typename F>
262  inline
263  bool
265  {
266  mln_precondition(win_.nelements() >= 1);
267  for (unsigned i = 0; i < win_.nelements(); ++i)
268  if (! win_[i].is_symmetric())
269  return false;
270  return true;
271  }
272 
273 
274  template <typename W, typename F>
275  inline
276  void
278  {
279  mln_precondition(win_.nelements() >= 1);
280  for (unsigned i = 0; i < win_.nelements(); ++i)
281  win_[i].sym();
282  }
283 
284  template <typename W, typename F>
285  inline
286  unsigned
287  multiple<W,F>::delta() const
288  {
289  mln_precondition(win_.nelements() >= 1);
290  unsigned d = win_[0].delta();
291  for (unsigned i = 1; i < win_.nelements(); ++i)
292  {
293  unsigned d_i = win_[i].delta();
294  if (d_i > d)
295  d = d_i;
296  }
297  return d;
298  }
299 
300  template <typename W, typename F>
301  inline
302  const mln_dpsite(W)&
303  multiple<W,F>::ith_dp_around(unsigned i, const mln_psite(W)& p) const
304  {
305  mln_precondition(f_(p) < win_.nelements());
306  mln_precondition(i < win_[f_(p)].size());
307  return win_[f_(p)].dp(i);
308  }
309 
310 
311  // win::multiple_qiter<W,F>
312 
313  template <typename W, typename F>
314  inline
316  {
317  }
318 
319  template <typename W, typename F>
320  template <typename Pref>
321  inline
322  multiple_qiter<W,F>::multiple_qiter(const multiple<W,F>& w, const Pref& c)
323  {
324  init_(w, c);
325  }
326 
327  template <typename W, typename F>
328  template <typename Pref>
329  inline
330  void
331  multiple_qiter<W,F>::init_(const multiple<W,F>& w, const Pref& c)
332  {
333  this->center_at(c);
334  // We have to first change the center so that 'invalidate' can
335  // work when changing the target.
336  change_target(w);
337  }
338 
339  template <typename W, typename F>
340  inline
341  void
342  multiple_qiter<W,F>::change_target(const multiple<W,F>& w)
343  {
344  size_ = w.size();
345  this->super_::change_target(w);
346  }
347 
348  template <typename W, typename F>
349  inline
350  bool
352  {
353  return i_ < size_;
354  }
355 
356  template <typename W, typename F>
357  inline
358  void
360  {
361  i_ = size_;
362  }
363 
364  template <typename W, typename F>
365  inline
366  void
368  {
369  i_ = 0;
370  }
371 
372  template <typename W, typename F>
373  inline
374  void
376  {
377  ++i_;
378  }
379 
380  template <typename W, typename F>
381  inline
382  mln_psite(W)
383  multiple_qiter<W,F>::compute_p_() const
384  {
385  return *this->c_ + this->s_->ith_dp_around(i_, *this->c_);
386  }
387 
388 # endif // ! MLN_INCLUDE_ONLY
389 
390 
391  } // end of namespace mln::win
392 
393 } // end of namespace mln
394 
395 
396 #endif // ! MLN_WIN_MULTIPLE_HH