$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
concept/window.hh
1 // Copyright (C) 2007, 2008, 2009, 2011, 2012, 2013 EPITA Research and
2 // Development 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_CORE_CONCEPT_WINDOW_HH
28 # define MLN_CORE_CONCEPT_WINDOW_HH
29 
37 
38 # include <mln/core/concept/object.hh>
39 # include <mln/core/concept/iterator.hh>
40 # include <mln/trait/windows.hh>
41 
42 # include <mln/core/site_set/p_array.hh>
43 # include <mln/core/internal/geom_bbox.hh> // For use in from_to_.
44 # include <mln/util/array.hh>
45 
46 
47 
48 # define mln_is_simple_window(W) \
49  \
50 mln::metal::and_< mlc_is(mln_trait_window_size(W), \
51  mln::trait::window::size::fixed), \
52  mln::metal::and_< mlc_is(mln_trait_window_support(W), \
53  mln::trait::window::support::regular), \
54  mlc_is(mln_trait_window_definition(W), \
55  mln::trait::window::definition::unique) > >
56 
57 
58 # define mln_is_fastest_IW(I, W) \
59  \
60 mlc_and(mlc_is(mln_trait_image_speed(I), \
61  trait::image::speed::fastest), \
62  mln_is_simple_window(W))
63 
64 
65 
66 namespace mln
67 {
68 
69  // Forward declarations.
70  template <typename E> struct Window;
71  template <typename E> struct Image;
72 
73 
76  template <>
77  struct Window<void>
78  {
80  };
82 
83 
92  template <typename E>
93  struct Window : public Object<E>
94  {
96 
97  /*
98  typedef site;
99  typedef psite;
100  typedef dpsite;
101 
102  typedef qiter;
103  typedef fwd_qiter;
104  typedef bkd_qiter;
105  */
106 
107  protected:
108  Window();
109  };
110 
111 
112  template <typename Wl, typename Wr>
113  bool operator==(const Window<Wl>& lhs, const Window<Wr>& rhs);
114 
115 
116  template <typename W>
117  std::ostream& operator<<(std::ostream& ostr, const Window<W>& win);
118 
119 
124  template <typename W, typename I>
125  void
126  from_to_(const Window<W>& from, Image<I>& to);
127 
128 
129  // FIXME: Move as a method of Image?
131  template <typename I, typename W>
133  offsets_wrt(const Image<I>& ima, const Window<W>& win);
134 
135  // FIXME: Move as a method of Image?
137  template <typename I, typename W>
139  positive_offsets_wrt(const Image<I>& ima, const Window<W>& win);
140 
141  // FIXME: Move as a method of Image?
143  template <typename I, typename W>
145  negative_offsets_wrt(const Image<I>& ima, const Window<W>& win);
146 
147 
148 
149 # ifndef MLN_INCLUDE_ONLY
150 
151  namespace internal
152  {
153 
154  // size: fixed or unknown.
155 
156  template <typename trait_size, typename E>
157  struct window_size_check
158  {
159  static void run() { /* No requirement. */ }
160  };
161 
162  template <typename E>
163  struct window_size_check< mln::trait::window::size::fixed, E >
164  {
165  static void run()
166  {
167  unsigned (E::*m)() const = & E::size;
168  (void) m;
169  }
170  };
171 
172  // support: regular or irregular.
173 
174  template <typename trait_support, typename E>
175  struct window_support_check
176  {
177  static void run() { /* No requirement. */ }
178  };
179 
180  template <typename E>
181  struct window_support_check< mln::trait::window::support::regular, E >
182  {
183  static void run_extra()
184  {
185  // Associated type.
186  typedef mln_regular(E) regular;
187 
188  // Methods.
189  bool (E::*m1)() const = &E::is_centered;
190  (void) m1;
191  bool (E::*m2)() const = &E::is_symmetric;
192  (void) m2;
193  void (E::*m3)() = &E::sym;
194  (void) m3;
195  unsigned (E::*m4)() const = &E::delta;
196  (void) m4;
197  bool (E::*m5)() const = &E::is_valid;
198  (void) m5;
199  }
200 
201  static void run(mln::trait::window::definition::unique)
202  {
203  typedef mln_dpsite(E) D;
204  const D& (E::*m1)(unsigned) const = &E::dp;
205  (void) m1;
206  bool (E::*m2)(const D&) const = &E::has;
207  (void) m2;
208  run_extra();
209  }
210 
211  static void run(mln::trait::window::definition::n_ary)
212  {
213  run_extra();
214  }
215 
216  static void run(mln::trait::window::definition::varying)
217  {
218  /* No requirement. */
219  }
220 
221  static void run()
222  {
223  run(mln_trait_window_definition(E)());
224  }
225  };
226 
227  // definition: unique, n_ary, or varying.
228 
229  template <typename trait_definition, typename E>
230  struct window_definition_check
231  {
232  static void run() { /* No requirement. */ }
233  };
234 
235  template <typename E>
236  struct window_definition_check< mln::trait::window::definition::multiple, E >
237  {
238  static void run()
239  {
240  typedef mln_element(E) W;
241  void (E::*m1)(unsigned, const W&) = &E::set_window;
242  (void) m1;
243  const W& (E::*m2)(unsigned) const = &E::window;
244  (void) m2;
245  unsigned (E::*m3)() const = &E::nwindows;
246  (void) m3;
247  }
248  };
249 
250  } // end of namespace mln::internal
251 
252 
253  template <typename E>
254  inline
255  Window<E>::Window()
256  {
257  // Check properties.
258  mlc_not_equal( mln_trait_window_size(E), mln::trait::undef )::check();
259  mlc_not_equal( mln_trait_window_support(E), mln::trait::undef )::check();
260  mlc_not_equal( mln_trait_window_definition(E), mln::trait::undef )::check();
261 
262  // Check associated types.
263  typedef mln_site(E) site;
264  typedef mln_psite(E) psite;
265  typedef mln_dpsite(E) dpsite;
266  typedef mln_qiter(E) qiter;
267  typedef mln_fwd_qiter(E) fwd_qiter;
268  typedef mln_bkd_qiter(E) bkd_qiter;
269 
270  // Check methods depending upon properties.
271  internal::window_size_check < mln_trait_window_size(E), E >::run();
272  internal::window_support_check < mln_trait_window_support(E), E >::run();
273  internal::window_definition_check< mln_trait_window_definition(E), E >::run();
274  }
275 
276  template <typename Wl, typename Wr>
277  inline
278  bool operator==(const Window<Wl>& lhs, const Window<Wr>& rhs)
279  {
280  return exact(lhs).std_vector() == exact(rhs).std_vector();
281  }
282 
283 
284  // Operator <<.
285 
286  namespace internal
287  {
288 
289  template <typename W>
290  inline
291  void print(trait::window::definition::unique,
292  std::ostream& ostr, const W& win) // FIXME: Add Window<W> to win?
293  {
294  win.print(ostr);
295  }
296 
297  template <typename W>
298  inline
299  void print(trait::window::definition::multiple,
300  std::ostream& ostr, const W& win) // FIXME: Add Window<W> to win?
301  {
302  ostr << "[";
303  const unsigned nw = win.nwindows();
304  for (unsigned w = 0; w < nw; ++w)
305  {
306  ostr << " #" << w << ':';
307  win.window_(w).print(ostr);
308  }
309  ostr << " ]";
310  }
311 
312  } // end of namespace mln::internal
313 
314  template <typename W>
315  inline
316  std::ostream& operator<<(std::ostream& ostr, const Window<W>& win)
317  {
318  mlc_is(mln_trait_window_support(W),
319  trait::window::support::regular)::check();
320  mlc_is_not(mln_trait_window_definition(W),
321  trait::window::definition::varying)::check();
322  // FIXME: test on is_empty?
323  internal::print(mln_trait_window_definition(W)(),
324  ostr, exact(win));
325  return ostr;
326  }
327 
328 
329  template <typename W, typename I>
330  void
331  from_to_(const Window<W>& win_, Image<I>& ima_)
332  {
333  mln_is_simple_window(W)::check();
334  typedef mln_psite(I) P;
335  mlc_converts_to(mln_dpsite(W), mln_delta(P))::check();
336  mlc_equal(mln_value(I), bool)::check();
337 
338  const W& win = exact(win_);
339  I& ima = exact(ima_);
340 
341  mln_precondition(win.is_valid());
342  mln_precondition(! ima.is_valid());
343 
344  // Hack (below) to avoid circular dependency.
345  ima.init_(mln::internal::geom_bbox(win));
346  {
347  // data::fill(ima, false) is:
348  mln_piter(I) p(ima.domain());
349  for_all(p)
350  ima(p) = false;
351  }
352  unsigned n = win.size();
353  for (unsigned i = 0; i < n; ++i)
354  ima(convert::to<P>(win.dp(i))) = true;
355  }
356 
357 
358  template <typename I, typename W>
359  inline
360  util::array<int>
361  offsets_wrt(const Image<I>& ima_, const Window<W>& win_)
362  {
363  mln_is_simple_window(W)::check();
364 
365  const I& ima = exact(ima_);
366  const W& win = exact(win_);
367  mln_precondition(ima.is_valid());
368  mln_precondition(win.is_valid());
369 
370  util::array<int> arr;
371  unsigned n = win.size();
372 
373  for (unsigned i = 0; i < n; ++i)
374  arr.append(ima.delta_offset(win.dp(i)));
375 
376  return arr;
377  }
378 
379 
380  template <typename I, typename W>
381  inline
382  util::array<int>
383  positive_offsets_wrt(const Image<I>& ima_, const Window<W>& win_)
384  {
385  mln_is_simple_window(W)::check();
386 
387  const I& ima = exact(ima_);
388  const W& win = exact(win_);
389  mln_precondition(ima.is_valid());
390  mln_precondition(win.is_valid());
391 
392  util::array<int> arr;
393  unsigned n = win.size();
394 
395  for (unsigned i = 0; i < n; ++i)
396  {
397  int offset = ima.delta_offset(win.dp(i));
398  if (offset > 0)
399  arr.append(offset);
400  }
401 
402  return arr;
403  }
404 
405 
406  template <typename I, typename W>
407  inline
408  util::array<int>
409  negative_offsets_wrt(const Image<I>& ima_, const Window<W>& win_)
410  {
411  mln_is_simple_window(W)::check();
412 
413  const I& ima = exact(ima_);
414  const W& win = exact(win_);
415  mln_precondition(ima.is_valid());
416  mln_precondition(win.is_valid());
417 
418  util::array<int> arr;
419  unsigned n = win.size();
420 
421  for (unsigned i = 0; i < n; ++i)
422  {
423  int offset = ima.delta_offset(win.dp(i));
424  if (offset < 0)
425  arr.append(offset);
426  }
427 
428  return arr;
429  }
430 
431 # endif // ! MLN_INCLUDE_ONLY
432 
433 } // end of namespace mln
434 
435 
436 #endif // ! MLN_CORE_CONCEPT_WINDOW_HH