Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
dpoints_pixter.hh
1 // Copyright (C) 2007, 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_CORE_DPOINTS_PIXTER_HH
28 # define MLN_CORE_DPOINTS_PIXTER_HH
29 
36 
37 # include <cassert>
38 # include <vector>
39 
40 # include <mln/core/concept/proxy.hh>
41 # include <mln/core/concept/pixel_iterator.hh>
42 # include <mln/core/internal/pixel_impl.hh>
43 # include <mln/metal/converts_to.hh>
44 
45 
46 namespace mln
47 {
48 
49  /*------------------------.
50  | dpoints_fwd_pixter<I>. |
51  `------------------------*/
52 
57  template <typename I>
59  : public Pixel_Iterator< dpoints_fwd_pixter<I> >,
60  public internal::pixel_impl_< I, dpoints_fwd_pixter<I> >
61  {
62  typedef typename internal::pixel_impl_< I, dpoints_fwd_pixter<I> > super_;
63 
64  public:
72  template <typename Dps, typename Pref>
73  dpoints_fwd_pixter(I& image,
74  const Dps& dps,
75  const Pref& p_ref);
76 
82  template <typename Dps, typename Pref>
84  const Dps& dps);
85 
89  void start();
91  void next_();
92 
94  void invalidate();
96  bool is_valid() const;
97 
100  void update();
102 
104  const mln_value(I)& center_val() const;
105 
106  private:
107  template <typename Dps>
108  void init_(const Dps& dps);
109 
110  private:
116  std::vector<int> offset_;
118  typename std::vector<int>::const_iterator i_;
119 
125  mln_qlf_value(I)** value_ref_;
127  const mln_psite(I)* p_ref_;
129  };
130 
131 
132  /*------------------------.
133  | dpoints_bkd_pixter<I>. |
134  `------------------------*/
135 
140  template <typename I>
142  : public Pixel_Iterator< dpoints_bkd_pixter<I> >,
143  public internal::pixel_impl_< I, dpoints_bkd_pixter<I> >
144  {
145  typedef typename internal::pixel_impl_< I, dpoints_bkd_pixter<I> > super_;
146 
147  public:
155  template <typename Dps, typename Pref>
156  dpoints_bkd_pixter(I& image,
157  const Dps& dps,
158  const Pref& p_ref);
159 
165  template <typename Dps, typename Pref>
167  const Dps& dps);
168 
172  void start();
174  void next_();
175 
177  void invalidate();
179  bool is_valid() const;
180 
183  void update();
185 
187  const mln_value(I)& center_val() const;
188 
189  private:
190  template <typename Dps>
191  void init_(const Dps& dps);
192 
193  private:
199  std::vector<int> offset_;
201  typename std::vector<int>::const_reverse_iterator i_;
202 
208  mln_qlf_value(I)** value_ref_;
210  const mln_psite(I)* p_ref_;
212  };
213 
214 
215 
216 #ifndef MLN_INCLUDE_ONLY
217 
218  /*------------------------.
219  | dpoints_fwd_pixter<I>. |
220  `------------------------*/
221 
222  template <typename I>
223  template <typename Dps, typename Pref>
224  inline
226  const Dps& dps,
227  const Pref& p_ref)
228  : super_(image)
229  {
230  mln_precondition(image.is_valid());
231 
232  mlc_converts_to(Pref, const mln_psite(I)&)::check();
233  p_ref_ = & static_cast< const mln_psite(I)& >(p_ref);
234 
235  value_ref_ = 0;
236  init_(dps);
237  }
238 
239  template <typename I>
240  template <typename Dps, typename Pref>
241  inline
243  const Dps& dps)
244  : super_(internal::force_exact<Pref>(pxl_ref_).ima())
245  {
246  const Pref& pxl_ref = internal::force_exact<Pref>(pxl_ref_);
247  mln_precondition(pxl_ref.ima().is_valid());
248  p_ref_ = 0;
249  // Potential promotion from (T**) to (const T**) shall be forced.
250  value_ref_ = const_cast<mln_qlf_value(I)**>(pxl_ref.address_());
251  init_(dps);
252  }
253 
254  template <typename I>
255  inline
256  const mln_value(I)&
258  {
259  mln_invariant(value_ref_ != 0 || p_ref_ != 0);
260  if (p_ref_)
261  return this->image_(*p_ref_);
262  else
263  return **value_ref_;
264  }
265 
266  template <typename I>
267  template <typename Dps>
268  inline
269  void
270  dpoints_fwd_pixter<I>::init_(const Dps& dps)
271  {
272  for (unsigned i = 0; i < dps.size(); ++i)
273  offset_.push_back(this->image_.delta_index(dps.dp(i)));
274  // offset_[0] is absolute
275  // other offsets are relative:
276  if (dps.size() > 1)
277  for (unsigned i = dps.size() - 1; i > 0; --i)
278  offset_[i] -= offset_[i - 1];
279  invalidate();
280  }
281 
282  template <typename I>
283  inline
284  void
286  {
287  if (is_valid())
288  {
289  if (p_ref_)
290  this->value_ptr_ = & this->image_(*p_ref_) + *i_;
291  else
292  this->value_ptr_ = * value_ref_ + *i_;
293  }
294  }
295 
296  template <typename I>
297  inline
298  void
300  {
301  i_ = offset_.begin();
302  update();
303  }
304 
305  template <typename I>
306  inline
307  void
309  {
310  ++i_;
311  if (is_valid())
312  this->value_ptr_ += *i_;
313  }
314 
315  template <typename I>
316  inline
317  bool
319  {
320  return i_ != offset_.end();
321  }
322 
323  template <typename I>
324  inline
325  void
327  {
328  i_ = offset_.end();
329  }
330 
331 
332  /*------------------------.
333  | dpoints_bkd_pixter<I>. |
334  `------------------------*/
335 
336  template <typename I>
337  template <typename Dps, typename Pref>
338  inline
340  const Dps& dps,
341  const Pref& p_ref)
342  : super_(image)
343  {
344  mln_precondition(image.is_valid());
345  internal::get_adr(p_ref_, p_ref);
346  value_ref_ = 0;
347  init_(dps);
348  }
349 
350  template <typename I>
351  template <typename Dps, typename Pref>
352  inline
354  const Dps& dps)
355  : super_(internal::force_exact<Pref>(pxl_ref_).ima())
356  {
357  const Pref& pxl_ref = internal::force_exact<Pref>(pxl_ref_);
358  mln_precondition(pxl_ref.ima().is_valid());
359  p_ref_ = 0;
360  // Potential promotion from (T**) to (const T**) shall be forced.
361  value_ref_ = const_cast<mln_qlf_value(I)**>(pxl_ref.address_());
362  init_(dps);
363  }
364 
365  template <typename I>
366  inline
367  const mln_value(I)&
369  {
370  mln_invariant(value_ref_ != 0 || p_ref_ != 0);
371  if (p_ref_)
372  return this->image_(*p_ref_);
373  else
374  return **value_ref_;
375  }
376 
377  template <typename I>
378  template <typename Dps>
379  inline
380  void
381  dpoints_bkd_pixter<I>::init_(const Dps& dps)
382  {
383  for (unsigned i = 0; i < dps.size(); ++i)
384  offset_.push_back(this->image_.delta_index(dps.dp(i)));
385  // offset_[size() - 1] is absolute
386  // other offsets are relative:
387  if (dps.size() > 1)
388  for (unsigned i = 0; i < dps.size() - 1; ++i)
389  offset_[i] -= offset_[i + 1];
390  invalidate();
391  }
392 
393  template <typename I>
394  inline
395  void
397  {
398  if (is_valid())
399  {
400  if (p_ref_)
401  this->value_ptr_ = & this->image_(*p_ref_) + *i_;
402  else
403  this->value_ptr_ = * value_ref_ + *i_;
404  }
405  }
406 
407  template <typename I>
408  inline
409  void
411  {
412  i_ = offset_.rbegin();
413  update();
414  }
415 
416  template <typename I>
417  inline
418  void
420  {
421  ++i_;
422  if (is_valid())
423  this->value_ptr_ += *i_;
424  }
425 
426  template <typename I>
427  inline
428  bool
430  {
431  return i_ != offset_.rend();
432  }
433 
434  template <typename I>
435  inline
436  void
438  {
439  i_ = offset_.rend();
440  }
441 
442 #endif // ! MLN_INCLUDE_ONLY
443 
444 } // end of namespace mln
445 
446 
447 #endif // ! MLN_CORE_DPOINTS_PIXTER_HH