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