[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

imageiterator.hxx VIGRA

1 /************************************************************************/
2 /* */
3 /* Copyright 1998-2002 by Ullrich Koethe */
4 /* */
5 /* This file is part of the VIGRA computer vision library. */
6 /* The VIGRA Website is */
7 /* http://hci.iwr.uni-heidelberg.de/vigra/ */
8 /* Please direct questions, bug reports, and contributions to */
9 /* ullrich.koethe@iwr.uni-heidelberg.de or */
10 /* vigra@informatik.uni-hamburg.de */
11 /* */
12 /* Permission is hereby granted, free of charge, to any person */
13 /* obtaining a copy of this software and associated documentation */
14 /* files (the "Software"), to deal in the Software without */
15 /* restriction, including without limitation the rights to use, */
16 /* copy, modify, merge, publish, distribute, sublicense, and/or */
17 /* sell copies of the Software, and to permit persons to whom the */
18 /* Software is furnished to do so, subject to the following */
19 /* conditions: */
20 /* */
21 /* The above copyright notice and this permission notice shall be */
22 /* included in all copies or substantial portions of the */
23 /* Software. */
24 /* */
25 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */
26 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */
27 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */
28 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */
29 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
30 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */
31 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
32 /* OTHER DEALINGS IN THE SOFTWARE. */
33 /* */
34 /************************************************************************/
35 
36 
37 #ifndef VIGRA_IMAGEITERATOR_HXX
38 #define VIGRA_IMAGEITERATOR_HXX
39 
40 #include "utilities.hxx"
41 #include "accessor.hxx"
42 #include "iteratortraits.hxx"
43 #include "metaprogramming.hxx"
44 
45 namespace vigra {
46 
47 template <class IMAGEITERATOR>
48 class StridedIteratorPolicy
49 {
50  public:
51  typedef IMAGEITERATOR ImageIterator;
52  typedef typename IMAGEITERATOR::value_type value_type;
53  typedef typename IMAGEITERATOR::difference_type::MoveY
54  difference_type;
55  typedef typename IMAGEITERATOR::reference reference;
56  typedef typename IMAGEITERATOR::index_reference index_reference;
57  typedef typename IMAGEITERATOR::pointer pointer;
58  typedef std::random_access_iterator_tag iterator_category;
59 
60 
61  struct BaseType
62  {
63  explicit BaseType(pointer c = 0, difference_type stride = 0)
64  : current_(c), stride_(stride)
65  {}
66 
67  pointer current_;
68  difference_type stride_;
69  };
70 
71  static void initialize(BaseType & /* d */) {}
72 
73  static reference dereference(BaseType const & d)
74  { return const_cast<reference>(*d.current_); }
75 
76  static index_reference dereference(BaseType const & d, difference_type n)
77  {
78  return const_cast<index_reference>(d.current_[n*d.stride_]);
79  }
80 
81  static bool equal(BaseType const & d1, BaseType const & d2)
82  { return d1.current_ == d2.current_; }
83 
84  static bool less(BaseType const & d1, BaseType const & d2)
85  { return d1.current_ < d2.current_; }
86 
87  static difference_type difference(BaseType const & d1, BaseType const & d2)
88  { return (d1.current_ - d2.current_) / d1.stride_; }
89 
90  static void increment(BaseType & d)
91  { d.current_ += d.stride_; }
92 
93  static void decrement(BaseType & d)
94  { d.current_ -= d.stride_; }
95 
96  static void advance(BaseType & d, difference_type n)
97  { d.current_ += d.stride_*n; }
98 };
99 
100 /** \addtogroup ImageIterators Image Iterators
101 
102  \brief General image iterator definition and implementations.
103 
104 <p>
105  The following tables describe the general requirements for image iterators
106  and their iterator traits. The iterator implementations provided here
107  may be used for any image data type that stores its
108  data as a linear array of pixels. The array will be interpreted as a
109  row-major matrix with a particular width.
110 </p>
111 <h3>Requirements for Image Iterators</h3>
112 <p>
113 
114 <table border=2 cellspacing=0 cellpadding=2 width="100%">
115 <tr><th colspan=2>
116  Local Types
117  </th><th>
118  Meaning
119  </th>
120 </tr>
121 <tr><td colspan=2>
122  <tt>ImageIterator::value_type</tt></td><td>the underlying image's pixel type</td>
123 </tr>
124 <tr><td colspan=2>
125  <tt>ImageIterator::PixelType</tt></td><td>the underlying image's pixel type</td>
126 </tr>
127 <tr><td colspan=2>
128  <tt>ImageIterator::reference</tt></td>
129  <td>the iterator's reference type (return type of <TT>*iter</TT>). Will be
130  <tt>value_type &</tt> for a mutable iterator, and convertible to
131  <tt>value_type const &</tt> for a const iterator.</td>
132 </tr>
133 <tr><td colspan=2>
134  <tt>ImageIterator::index_reference</tt></td>
135  <td>the iterator's index reference type (return type of <TT>iter[diff]</TT>). Will be
136  <tt>value_type &</tt> for a mutable iterator, and convertible to
137  <tt>value_type const &</tt> for a const iterator.</td>
138 </tr>
139 <tr><td colspan=2>
140  <tt>ImageIterator::pointer</tt></td>
141  <td>the iterator's pointer type (return type of <TT>iter.operator->()</TT>). Will be
142  <tt>value_type *</tt> for a mutable iterator, and convertible to
143  <tt>value_type const *</tt> for a const iterator.</td>
144 </tr>
145 <tr><td colspan=2>
146  <tt>ImageIterator::difference_type</tt></td>
147  <td>the iterator's difference type (<TT>vigra::Diff2D</TT>)</td>
148 </tr>
149 <tr><td colspan=2>
150  <tt>ImageIterator::iterator_category</tt></td>
151  <td>the iterator tag (<tt>vigra::image_traverser_tag</tt>)</td>
152 </tr>
153 <tr><td colspan=2>
154  <tt>ImageIterator::row_iterator</tt></td><td>the associated row iterator</td>
155 </tr>
156 <tr><td colspan=2>
157  <tt>ImageIterator::column_iterator</tt></td><td>the associated column iterator</td>
158 </tr>
159 <tr><td colspan=2>
160  <tt>ImageIterator::MoveX</tt></td><td>type of the horizontal navigator</td>
161 </tr>
162 <tr><td colspan=2>
163  <tt>ImageIterator::MoveY</tt></td><td>type of the vertical navigator</td>
164 </tr>
165 <tr><th>
166  Operation
167  </th><th>
168  Result
169  </th><th>
170  Semantics
171  </th>
172 </tr>
173 <tr>
174  <td><tt>++i.x<br>i.x--</tt></td><td><tt>void</tt></td><td>increment x-coordinate</td>
175 </tr>
176 <tr>
177  <td><tt>--i.x<br>i.x--</tt></td><td><tt>void</tt></td><td>decrement x-coordinate</td>
178 </tr>
179 <tr>
180  <td><tt>i.x += dx</tt></td><td><tt>ImageIterator::MoveX &</tt></td>
181  <td>add <tt>dx</tt> to x-coordinate</td>
182 </tr>
183 <tr>
184  <td><tt>i.x -= dx</tt></td><td><tt>ImageIterator::MoveX &</tt></td>
185  <td>subtract <tt>dx</tt> from x-coordinate</td>
186 </tr>
187 <tr>
188  <td><tt>i.x - j.x</tt></td><td><tt>int</tt></td>
189  <td>difference of the x-coordinates of <tt>i</tt> and <tt>j</tt></td>
190 </tr>
191 <tr>
192  <td><tt>i.x = j.x</tt></td><td><tt>ImageIterator::MoveX &</tt></td><td><tt>i.x += j.x - i.x</tt></td>
193 </tr>
194 <tr>
195  <td><tt>i.x == i.y</tt></td><td><tt>bool</tt></td><td><tt>j.x - i.x == 0</tt></td>
196 
197 </tr>
198 <tr>
199  <td><tt>i.x < j.x</tt></td><td><tt>bool</tt></td><td><tt>j.x - i.x > 0</tt></td>
200 
201 </tr>
202 <tr>
203  <td><tt>++i.y<br>i.y++</tt></td><td><tt>void</tt></td><td>increment y-coordinate</td>
204 </tr>
205 <tr>
206  <td><tt>--i.y<br>i.y--</tt></td><td><tt>void</tt></td><td>decrement y-coordinate</td>
207 </tr>
208 <tr>
209  <td><tt>i.y += dy</tt></td><td><tt>ImageIterator::MoveY &</tt></td>
210  <td>add <tt>dy</tt> to y-coordinate</td>
211 </tr>
212 <tr>
213  <td><tt>i.y -= dy</tt></td><td><tt>ImageIterator::MoveY &</tt></td>
214  <td>subtract <tt>dy</tt> from y-coordinate</td>
215 </tr>
216 <tr>
217  <td><tt>i.y - j.y</tt></td><td><tt>int</tt></td>
218  <td>difference of the y-coordinates of <tt>i</tt> and <tt>j</tt></td>
219 </tr>
220 <tr>
221  <td><tt>i.y = j.y</tt></td><td><tt>ImageIterator::MoveY &</tt></td><td><tt>i.y += j.y - i.y</tt></td>
222 </tr>
223 <tr>
224  <td><tt>i.y == j.y</tt></td><td><tt>bool</tt></td><td><tt>j.y - i.y == 0</tt></td>
225 
226 </tr>
227 <tr>
228  <td><tt>i.y < j.y</tt></td><td><tt>bool</tt></td><td><tt>j.y - i.y > 0</tt></td>
229 </tr>
230 <tr><td colspan=2>
231  <tt>ImageIterator k(i)</tt></td><td>copy constructor</td>
232 </tr>
233 <tr>
234  <td><tt>k = i</tt></td><td><tt>ImageIterator &</tt></td><td>assignment</td>
235 </tr>
236 <tr><td colspan=2>
237  <tt>ImageIterator k</tt></td><td>default constructor</td>
238 </tr>
239 <tr><td colspan=2>
240  <tt>ImageIterator::row_iterator r(i)</tt></td><td>construction of row iterator</td>
241 </tr>
242 <tr><td colspan=2>
243  <tt>ImageIterator::column_iterator c(i)</tt></td><td>construction of column iterator</td>
244 </tr>
245 <tr>
246  <td><tt>i += diff</tt></td><td><tt>ImageIterator &</tt></td>
247  <td><tt>{ i.x += diff.x<br>i.y += diff.y; }</tt></td>
248 </tr>
249 <tr>
250  <td><tt>i -= diff</tt></td><td><tt>ImageIterator &</tt></td>
251  <td><tt>{ i.x -= diff.x<br>i.y -= diff.y; }</tt></td>
252 </tr>
253 <tr>
254  <td><tt>i + diff</tt></td><td><tt>ImageIterator</tt></td>
255  <td><tt>{ ImageIterator tmp(i);<br>tmp += diff;<br>return tmp; }</tt></td>
256 </tr>
257 <tr>
258  <td><tt>i - diff</tt></td><td><tt>ImageIterator</tt></td>
259  <td><tt>{ ImageIterator tmp(i);<br>tmp -= diff;<br>return tmp; }</tt></td>
260 </tr>
261 <tr>
262  <td><tt>i - j</tt></td><td><tt>ImageIterator::difference_type</tt></td>
263  <td><tt>{ ImageIterator::difference_type tmp(i.x - j.x, i.y - j.y);<br>return tmp; }</tt></td>
264 </tr>
265 <tr>
266  <td><tt>i == j</tt></td><td><tt>bool</tt></td>
267  <td><tt>i.x == j.x && i.y == j.y</tt></td>
268 </tr>
269 <tr>
270  <td><tt>*i</tt></td><td><tt>ImageIterator::reference</tt></td>
271  <td>access the current pixel</td>
272 </tr>
273 <tr>
274  <td><tt>i[diff]</tt></td><td><tt>ImageIterator::index_reference</tt></td>
275  <td>access pixel at offset <tt>diff</tt></td>
276 </tr>
277 <tr>
278  <td><tt>i(dx, dy)</tt></td><td><tt>ImageIterator::index_reference</tt></td>
279  <td>access pixel at offset <tt>(dx, dy)</tt></td>
280 </tr>
281 <tr>
282  <td><tt>i->member()</tt></td><td>depends on operation</td>
283  <td>call member function of underlying pixel type via <tt>operator-></tt> of iterator</td>
284 </tr>
285 <tr><td colspan=3>
286  <tt>i, j, k</tt> are of type <tt>ImageIterator</tt><br>
287  <tt>diff</tt> is of type <tt>ImageIterator::difference_type</tt><br>
288  <tt>dx, dy</tt> are of type <tt>int</tt><br>
289  </td>
290 </tr>
291 </table>
292 </p>
293 <h3>Requirements for Image Iterator Traits</h3>
294 <p>
295 The following iterator traits must be defined for an image iterator:
296 </p>
297 <p>
298 <table border=2 cellspacing=0 cellpadding=2 width="100%">
299 <tr><th>
300  Types
301  </th><th>
302  Meaning
303  </th>
304 </tr>
305 <tr>
306  <td><tt>IteratorTraits<ImageIterator>::Iterator</tt></td><td>the iterator type the traits are referring to</td>
307 </tr>
308 <tr>
309  <td><tt>IteratorTraits<ImageIterator>::iterator</tt></td><td>the iterator type the traits are referring to</td>
310 </tr>
311 <tr>
312  <td><tt>IteratorTraits<ImageIterator>::value_type</tt></td><td>the underlying image's pixel type</td>
313 </tr>
314 <tr>
315  <td><tt>IteratorTraits<ImageIterator>::reference</tt></td>
316  <td>the iterator's reference type (return type of <TT>*iter</TT>)</td>
317 </tr>
318 <tr>
319  <td><tt>IteratorTraits<ImageIterator>::index_reference</tt></td>
320  <td>the iterator's index reference type (return type of <TT>iter[diff]</TT>)</td>
321 </tr>
322 <tr>
323  <td><tt>IteratorTraits<ImageIterator>::pointer</tt></td>
324  <td>the iterator's pointer type (return type of <TT>iter.operator->()</TT>)</td>
325 </tr>
326 <tr>
327  <td><tt>IteratorTraits<ImageIterator>::difference_type</tt></td>
328  <td>the iterator's difference type</td>
329 </tr>
330 <tr>
331  <td><tt>IteratorTraits<ImageIterator>::iterator_category</tt></td>
332  <td>the iterator tag (<tt>vigra::image_traverser_tag</tt>)</td>
333 </tr>
334 <tr>
335  <td><tt>IteratorTraits<ImageIterator>::row_iterator</tt></td><td>the associated row iterator</td>
336 </tr>
337 <tr>
338  <td><tt>IteratorTraits<ImageIterator>::column_iterator</tt></td><td>the associated column iterator</td>
339 </tr>
340 <tr>
341  <td><tt>IteratorTraits<ImageIterator>::DefaultAccessor</tt></td>
342  <td>the default accessor to be used with the iterator</td>
343 </tr>
344 <tr>
345  <td><tt>IteratorTraits<ImageIterator>::default_accessor</tt></td>
346  <td>the default accessor to be used with the iterator</td>
347 </tr>
348 <tr>
349  <td><tt>IteratorTraits<ImageIterator>::hasConstantStrides</tt></td>
350  <td>whether the iterator uses constant strides on the underlying memory
351  (always <tt>VigraTrueType</tt> for <tt>ImageIterator</tt>s).</td>
352 </tr>
353 </table>
354 </p>
355 */
356 //@{
357 
358 namespace detail {
359 
360 template <class StridedOrUnstrided>
361 class DirectionSelector;
362 
363 template <>
364 class DirectionSelector<UnstridedArrayTag>
365 {
366  public:
367 
368  template <class T>
369  class type
370  {
371  public:
372  type(T base)
373  : current_(base)
374  {}
375 
376  type(type const & rhs)
377  : current_(rhs.current_)
378  {}
379 
380  type & operator=(type const & rhs)
381  {
382  current_ = rhs.current_;
383  return *this;
384  }
385 
386  void operator++() {++current_;}
387  void operator++(int) {++current_;}
388  void operator--() {--current_;}
389  void operator--(int) {--current_;}
390  void operator+=(std::ptrdiff_t dx) {current_ += dx; }
391  void operator-=(std::ptrdiff_t dx) {current_ -= dx; }
392 
393  bool operator==(type const & rhs) const
394  { return current_ == rhs.current_; }
395 
396  bool operator!=(type const & rhs) const
397  { return current_ != rhs.current_; }
398 
399  bool operator<(type const & rhs) const
400  { return current_ < rhs.current_; }
401 
402  bool operator<=(type const & rhs) const
403  { return current_ <= rhs.current_; }
404 
405  bool operator>(type const & rhs) const
406  { return current_ > rhs.current_; }
407 
408  bool operator>=(type const & rhs) const
409  { return current_ >= rhs.current_; }
410 
411  std::ptrdiff_t operator-(type const & rhs) const
412  { return current_ - rhs.current_; }
413 
414  T operator()() const
415  { return current_; }
416 
417  T operator()(std::ptrdiff_t d) const
418  { return current_ + d; }
419 
420  T current_;
421  };
422 };
423 
424 template <>
425 class DirectionSelector<StridedArrayTag>
426 {
427  public:
428 
429  template <class T>
430  class type
431  {
432  public:
433  type(std::ptrdiff_t stride, T base = 0)
434  : stride_(stride),
435  current_(base)
436  {}
437 
438  type(type const & rhs)
439  : stride_(rhs.stride_),
440  current_(rhs.current_)
441  {}
442 
443  type & operator=(type const & rhs)
444  {
445  stride_ = rhs.stride_;
446  current_ = rhs.current_;
447  return *this;
448  }
449 
450  void operator++() {current_ += stride_; }
451  void operator++(int) {current_ += stride_; }
452  void operator--() {current_ -= stride_; }
453  void operator--(int) {current_ -= stride_; }
454  void operator+=(std::ptrdiff_t dy) {current_ += dy*stride_; }
455  void operator-=(std::ptrdiff_t dy) {current_ -= dy*stride_; }
456 
457  bool operator==(type const & rhs) const
458  { return (current_ == rhs.current_); }
459 
460  bool operator!=(type const & rhs) const
461  { return (current_ != rhs.current_); }
462 
463  bool operator<(type const & rhs) const
464  { return (current_ < rhs.current_); }
465 
466  bool operator<=(type const & rhs) const
467  { return (current_ <= rhs.current_); }
468 
469  bool operator>(type const & rhs) const
470  { return (current_ > rhs.current_); }
471 
472  bool operator>=(type const & rhs) const
473  { return (current_ >= rhs.current_); }
474 
475  std::ptrdiff_t operator-(type const & rhs) const
476  { return (current_ - rhs.current_) / stride_; }
477 
478  T operator()() const
479  { return current_; }
480 
481  T operator()(std::ptrdiff_t d) const
482  { return current_ + d*stride_; }
483 
484  std::ptrdiff_t stride_;
485  T current_;
486  };
487 };
488 
489 template <class StridedOrUnstrided>
490 class LinearIteratorSelector;
491 
492 template <>
493 class LinearIteratorSelector<UnstridedArrayTag>
494 {
495  public:
496  template <class IMAGEITERATOR>
497  class type
498  {
499  public:
500  typedef typename IMAGEITERATOR::pointer res;
501 
502  template <class DirSelect>
503  static res construct(typename IMAGEITERATOR::pointer data, DirSelect const &)
504  {
505  return data;
506  }
507  };
508 };
509 
510 template <>
511 class LinearIteratorSelector<StridedArrayTag>
512 {
513  public:
514  template <class IMAGEITERATOR>
515  class type
516  {
517  public:
518  typedef IteratorAdaptor<StridedIteratorPolicy<IMAGEITERATOR> > res;
519 
520  template <class DirSelect>
521  static res construct(typename IMAGEITERATOR::pointer data, DirSelect const & d)
522  {
523  typedef typename res::BaseType Base;
524  return res(Base(data, d.stride_));
525  }
526  };
527 };
528 
529 
530 } // namespace detail
531 
532 /********************************************************/
533 /* */
534 /* ImageIteratorBase */
535 /* */
536 /********************************************************/
537 
538 /** \brief Base class for 2D random access iterators.
539 
540  This class contains the navigational part of the iterator.
541  It is usually not constructed directly, but via some derived class such as
542  \ref ImageIterator or \ref StridedImageIterator.
543 
544  <b>\#include</b> <vigra/imageiterator.hxx> <br/>
545  Namespace: vigra
546 
547  The usage examples assume that you constructed two iterators like
548  this:
549 
550  \code
551  vigra::ImageIterator<SomePixelType> iterator(base, width);
552  vigra::ImageIterator<SomePixelType> iterator1(base, width);
553  \endcode
554 
555  See the paper: U. Koethe:
556  <a href="http://hci.iwr.uni-heidelberg.de/vigra/documents/GenericProg2D.ps">Reusable Algorithms in Image Processing</a>
557  for a discussion of the concepts behind ImageIterators.
558 
559 */
560 template <class IMAGEITERATOR,
561  class PIXELTYPE, class REFERENCE, class POINTER,
562  class StridedOrUnstrided = UnstridedArrayTag>
564 {
565  typedef typename
566  vigra::detail::LinearIteratorSelector<StridedOrUnstrided>::template type<ImageIteratorBase>
567  RowIteratorSelector;
568  typedef typename
569  vigra::detail::LinearIteratorSelector<StridedArrayTag>::template type<ImageIteratorBase>
570  ColumnIteratorSelector;
571  public:
572  typedef ImageIteratorBase<IMAGEITERATOR,
573  PIXELTYPE, REFERENCE, POINTER, StridedOrUnstrided> self_type;
574 
575  /** The underlying image's pixel type.
576  */
577  typedef PIXELTYPE value_type;
578 
579  /** deprecated, use <TT>value_type</TT> instead.
580  */
581  typedef PIXELTYPE PixelType;
582 
583  /** the iterator's reference type (return type of <TT>*iter</TT>)
584  */
585  typedef REFERENCE reference;
586 
587  /** the iterator's index reference type (return type of <TT>iter[diff]</TT>)
588  */
589  typedef REFERENCE index_reference;
590 
591  /** the iterator's pointer type (return type of <TT>iter.operator->()</TT>)
592  */
593  typedef POINTER pointer;
594 
595  /** the iterator's difference type (argument type of <TT>iter[diff]</TT>)
596  */
598 
599  /** the iterator tag (image traverser)
600  */
601  typedef image_traverser_tag iterator_category;
602 
603  /** The associated row iterator.
604  */
605  typedef typename RowIteratorSelector::res row_iterator;
606 
607  /** The associated column iterator.
608  */
609  typedef typename ColumnIteratorSelector::res column_iterator;
610 
611  /** Let operations act in X direction
612  */
613  typedef typename
614  vigra::detail::DirectionSelector<StridedOrUnstrided>::template type<pointer> MoveX;
615 
616  /** Let operations act in Y direction
617  */
618  typedef typename
619  vigra::detail::DirectionSelector<StridedArrayTag>::template type<std::ptrdiff_t> MoveY;
620 
621  /** @name Comparison of Iterators */
622  //@{
623  /** usage: <TT> iterator == iterator1 </TT>
624  */
625  bool operator==(ImageIteratorBase const & rhs) const
626  {
627  return (x == rhs.x) && (y == rhs.y);
628  }
629 
630  /** usage: <TT> iterator != iterator1 </TT>
631  */
632  bool operator!=(ImageIteratorBase const & rhs) const
633  {
634  return (x != rhs.x) || (y != rhs.y);
635  }
636 
637  /** usage: <TT> Diff2D dist = iterator - iterator1 </TT>
638  */
640  {
641  return difference_type(x - rhs.x, y - rhs.y);
642  }
643 
644  //@}
645 
646  /** @name Specify coordinate to operate on */
647  //@{
648  /** Refer to iterator's x coordinate.
649  Usage examples:<br>
650  \code
651  ++iterator.x; // move one step to the right
652  --iterator.x; // move one step to the left
653  iterator.x += dx; // move dx steps to the right
654  iterator.x -= dx; // move dx steps to the left
655  bool notAtEndOfRow = iterator.x < lowerRight.x; // compare x coordinates of two iterators
656  int width = lowerRight.x - upperLeft.x; // calculate difference of x coordinates
657  // between two iterators
658  \endcode
659  */
661  /** Refer to iterator's y coordinate.
662  Usage examples:<br>
663  \code
664  ++iterator.y; // move one step down
665  --iterator.y; // move one step up
666  iterator.y += dy; // move dy steps down
667  iterator.y -= dy; // move dy steps up
668  bool notAtEndOfColumn = iterator.y < lowerRight.y; // compare y coordinates of two iterators
669  int height = lowerRight.y - upperLeft.y; // calculate difference of y coordinates
670  // between two iterators
671  \endcode
672  */
674  //@}
675 
676  protected:
677  /** Construct from raw memory with a vertical stride of <TT>ystride</TT>.
678  <TT>ystride</TT> must equal the physical image width (row length),
679  even if the iterator will only be used for a sub image. This constructor
680  must only be called for unstrided iterators
681  (<tt>StridedOrUnstrided == UnstridedArrayTag</tt>)
682  */
683  ImageIteratorBase(pointer base, std::ptrdiff_t ystride)
684  : x(base),
685  y(ystride)
686  {}
687 
688  /** Construct from raw memory with a horizontal stride of <TT>xstride</TT>
689  and a vertical stride of <TT>ystride</TT>. This constructor
690  may be used for iterators that shall skip pixels. Thus, it
691  must only be called for strided iterators
692  (<tt>StridedOrUnstrided == StridedArrayTag</tt>)
693  */
694  ImageIteratorBase(pointer base, std::ptrdiff_t xstride, std::ptrdiff_t ystride)
695  : x(xstride, base),
696  y(ystride)
697  {}
698 
699  /** Copy constructor */
701  : x(rhs.x),
702  y(rhs.y)
703  {}
704 
705  /** Default constructor */
707  : x(0),
708  y(0)
709  {}
710 
711  /** Copy assignment */
713  {
714  if(this != &rhs)
715  {
716  x = rhs.x;
717  y = rhs.y;
718  }
719  return *this;
720  }
721 
722  public:
723  /** @name Random navigation */
724  //@{
725  /** Add offset via Diff2D
726  */
727  IMAGEITERATOR & operator+=(difference_type const & s)
728  {
729  x += s.x;
730  y += s.y;
731  return static_cast<IMAGEITERATOR &>(*this);
732  }
733  /** Subtract offset via Diff2D
734  */
735  IMAGEITERATOR & operator-=(difference_type const & s)
736  {
737  x -= s.x;
738  y -= s.y;
739  return static_cast<IMAGEITERATOR &>(*this);
740  }
741 
742  /** Add a distance
743  */
744  IMAGEITERATOR operator+(difference_type const & s) const
745  {
746  IMAGEITERATOR ret(static_cast<IMAGEITERATOR const &>(*this));
747 
748  ret += s;
749 
750  return ret;
751  }
752 
753  /** Subtract a distance
754  */
755  IMAGEITERATOR operator-(difference_type const & s) const
756  {
757  IMAGEITERATOR ret(static_cast<IMAGEITERATOR const &>(*this));
758 
759  ret -= s;
760 
761  return ret;
762  }
763  //@}
764 
765  /** @name Access the Pixels */
766  //@{
767  /** Access current pixel. <br>
768  usage: <TT> SomePixelType value = *iterator </TT>
769  */
771  {
772  return *current();
773  }
774 
775  /** Call member of current pixel. <br>
776  usage: <TT> iterator->pixelMemberFunction() </TT>
777  */
779  {
780  return current();
781  }
782 
783  /** Access pixel at offset from current location. <br>
784  usage: <TT> SomePixelType value = iterator[Diff2D(1,1)] </TT>
785  */
787  {
788  return *current(d.x, d.y);
789  }
790 
791  /** Access pixel at offset (dx, dy) from current location. <br>
792  usage: <TT> SomePixelType value = iterator(dx, dy) </TT>
793  */
794  index_reference operator()(std::ptrdiff_t dx, std::ptrdiff_t dy) const
795  {
796  return *current(dx, dy);
797  }
798 
799  /** Read pixel with offset [dy][dx] from current pixel.
800  Note that the 'x' index is the trailing index. <br>
801  usage: <TT> SomePixelType value = iterator[dy][dx] </TT>
802  */
803  pointer operator[](std::ptrdiff_t dy) const
804  {
805  return x() + y(dy);
806  }
807  //@}
808 
809  row_iterator rowIterator() const
810  {
811  return RowIteratorSelector::construct(current(), x);
812  }
813 
814  column_iterator columnIterator() const
815  {
816  return ColumnIteratorSelector::construct(current(), y);
817  }
818 
819  private:
820 
821  pointer current() const
822  { return x() + y(); }
823 
824  pointer current(std::ptrdiff_t dx, std::ptrdiff_t dy) const
825  { return x(dx) + y(dy); }
826 };
827 
828 /********************************************************/
829 /* */
830 /* ImageIterator */
831 /* */
832 /********************************************************/
833 
834 /** \brief Standard 2D random access iterator for images that store the
835  data in a linear array.
836 
837  Most functions and local types are inherited from ImageIteratorBase.
838 
839  See the paper: U. Koethe:
840  <a href="http://hci.iwr.uni-heidelberg.de/vigra/documents/GenericProg2D.ps">Reusable Algorithms in Image Processing</a>
841  for a discussion of the concepts behind ImageIterators.
842 
843  <b>\#include</b> <vigra/imageiterator.hxx> <br/>
844  Namespace: vigra
845 
846 */
847 template <class PIXELTYPE>
849 : public ImageIteratorBase<ImageIterator<PIXELTYPE>,
850  PIXELTYPE, PIXELTYPE &, PIXELTYPE *>
851 {
852  public:
854  PIXELTYPE, PIXELTYPE &, PIXELTYPE *> Base;
855 
856  typedef typename Base::pointer pointer;
857  typedef typename Base::difference_type difference_type;
858 
859  /** Construct from raw memory with a vertical stride of <TT>ystride</TT>.
860  <TT>ystride</TT> must equal the physical image width (row length),
861  even if the iterator will only be used for a sub image.
862  If the raw memory is encapsulated in an image object this
863  object should have a factory function that constructs the
864  iterator.
865  */
866  ImageIterator(pointer base, std::ptrdiff_t ystride)
867  : Base(base, ystride)
868  {}
869 
870  /** Default constructor */
872  : Base()
873  {}
874 
875 };
876 
877 /********************************************************/
878 /* */
879 /* ConstImageIterator */
880 /* */
881 /********************************************************/
882 
883 /** \brief Standard 2D random access const iterator for images that
884  store the data as a linear array.
885 
886  Most functions are inherited from ImageIteratorBase.
887 
888  <b>\#include</b> <vigra/imageiterator.hxx> <br/>
889  Namespace: vigra
890 
891 */
892 template <class PIXELTYPE>
894 : public ImageIteratorBase<ConstImageIterator<PIXELTYPE>,
895  PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *>
896 {
897  public:
899  PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *> Base;
900 
901  typedef typename Base::pointer pointer;
902  typedef typename Base::difference_type difference_type;
903 
904  /** Construct from raw memory with a vertical stride of <TT>ystride</TT>.
905  <TT>ystride</TT> must equal the physical image width (row length),
906  even if the iterator will only be used for a sub image.
907  If the raw memory is encapsulated in an image object this
908  object should have a factory function that constructs the
909  iterator.
910  */
911  ConstImageIterator(pointer base, std::ptrdiff_t ystride)
912  : Base(base, ystride)
913  {}
914 
916  : Base(o.x, o.y)
917  {}
918 
919  /** Default constructor */
921  : Base()
922  {}
923 
924  ConstImageIterator & operator=(ImageIterator<PIXELTYPE> const & o)
925  {
926  Base::x = o.x;
927  Base::y = o.y;
928  return *this;
929  }
930 };
931 
932 /********************************************************/
933 /* */
934 /* StridedImageIterator */
935 /* */
936 /********************************************************/
937 
938 /** \brief Iterator to be used when pixels are to be skipped.
939 
940  This iterator can be used when some pixels shall be automatically skipped, for example
941  if an image is to be sub-sampled: instead of advancing to the next pixel,
942  <tt>++iterator.x</tt> jumps to the pixel at a horizontal offset of <tt>xskip</tt>.
943  Likewise with <tt>yskip</tt> in vertical direction. Most functions and local types
944  are inherited from ImageIteratorBase.
945 
946  <b> Usage:</b>
947 
948  \code
949  BImage img(w,h);
950  ...
951  int xskip = 2, yskip = 2;
952  int wskip = w / xskip + 1, hskip = h / yskip + 1;
953 
954  StridedImageIterator<BImage::value_type> upperLeft(&img(0,0), w, xskip, yskip);
955  StridedImageIterator<BImage::value_type> lowerRight = upperLeft + Diff2D(wskip, hskip);
956 
957  // now navigation with upperLeft and lowerRight lets the image appear to have half
958  // the original resolution in either dimension
959  \endcode
960 
961  <b>\#include</b> <vigra/imageiterator.hxx> <br/>
962  Namespace: vigra
963 
964 */
965 template <class PIXELTYPE>
967 : public ImageIteratorBase<StridedImageIterator<PIXELTYPE>,
968  PIXELTYPE, PIXELTYPE &, PIXELTYPE *, StridedArrayTag>
969 {
970  public:
972  PIXELTYPE, PIXELTYPE &, PIXELTYPE *, StridedArrayTag> Base;
973 
974  typedef typename Base::pointer pointer;
975  typedef typename Base::difference_type difference_type;
976 
977  /** Construct from raw memory with a vertical stride of <TT>ystride</TT>,
978  jumping by <tt>xskip</tt> horizontally and <tt>yskip</tt> vertically.
979  <tt>ystride</tt> must be the physical width (row length) of the image.
980  */
981  StridedImageIterator(pointer base, std::ptrdiff_t ystride, std::ptrdiff_t xskip, std::ptrdiff_t yskip)
982  : Base(base, xskip, ystride*yskip)
983  {}
984 
985  /** Default constructor */
987  : Base()
988  {}
989 
990 };
991 
992 /********************************************************/
993 /* */
994 /* ConstStridedImageIterator */
995 /* */
996 /********************************************************/
997 
998 /** \brief Const iterator to be used when pixels are to be skipped.
999 
1000  This iterator can be used when some pixels shall be automatically skipped, for example
1001  if an image is to be sub-sampled: instead of advancing to the next pixel,
1002  <tt>++iterator.x</tt> jumps to the pixel at a horizontal offset of <tt>xskip</tt>.
1003  Likewise with <tt>yskip</tt> in vertical direction. Most functions and local types
1004  are inherited from ImageIteratorBase.
1005 
1006  <b> Usage:</b>
1007 
1008  \code
1009  BImage img(w,h);
1010  ...
1011  int xskip = 2, yskip = 2;
1012  int wskip = w / xskip + 1, hskip = h / yskip + 1;
1013 
1014  ConstStridedImageIterator<BImage::value_type> upperLeft(&img(0,0), w, xskip, yskip);
1015  ConstStridedImageIterator<BImage::value_type> lowerRight = upperLeft + Diff2D(wskip, hskip);
1016 
1017  // now navigation with upperLeft and lowerRight lets the image appear to have half
1018  // the original resolution in either dimension
1019  \endcode
1020 
1021  <b>\#include</b> <vigra/imageiterator.hxx> <br/>
1022  Namespace: vigra
1023 
1024 */
1025 template <class PIXELTYPE>
1027 : public ImageIteratorBase<ConstStridedImageIterator<PIXELTYPE>,
1028  PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *,
1029  StridedArrayTag>
1030 {
1031  public:
1033  PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *,
1035 
1036  typedef typename Base::pointer pointer;
1037  typedef typename Base::difference_type difference_type;
1038 
1039  /** Construct from raw memory with a vertical stride of <TT>ystride</TT>,
1040  jumping by <tt>xskip</tt> horizontally and <tt>yskip</tt> vertically.
1041  <tt>ystride</tt> must be the physical width (row length) of the image.
1042  */
1043  ConstStridedImageIterator(pointer base, std::ptrdiff_t ystride, std::ptrdiff_t xskip, std::ptrdiff_t yskip)
1044  : Base(base, xskip, ystride*yskip)
1045  {}
1046 
1047  /** Copy-construct from mutable iterator */
1049  : Base(o.x, o.y)
1050  {}
1051 
1052  /** Default constructor */
1054  : Base()
1055  {}
1056 
1057  /** Assign mutable iterator */
1059  {
1060  Base::x = o.x;
1061  Base::y = o.y;
1062  return *this;
1063  }
1064 };
1065 
1066 /********************************************************/
1067 /* */
1068 /* definition of iterator traits */
1069 /* */
1070 /********************************************************/
1071 
1072 
1073 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
1074 
1075 template <class T>
1076 struct IteratorTraits<ImageIterator<T> >
1077 : public IteratorTraitsBase<ImageIterator<T> >
1078 {
1079  typedef ImageIterator<T> mutable_iterator;
1080  typedef ConstImageIterator<T> const_iterator;
1081  typedef typename AccessorTraits<T>::default_accessor DefaultAccessor;
1082  typedef DefaultAccessor default_accessor;
1083  typedef VigraTrueType hasConstantStrides;
1084 };
1085 
1086 template <class T>
1087 struct IteratorTraits<ConstImageIterator<T> >
1088 : public IteratorTraitsBase<ConstImageIterator<T> >
1089 {
1090  typedef ImageIterator<T> mutable_iterator;
1091  typedef ConstImageIterator<T> const_iterator;
1092  typedef typename AccessorTraits<T>::default_const_accessor DefaultAccessor;
1093  typedef DefaultAccessor default_accessor;
1094  typedef VigraTrueType hasConstantStrides;
1095 };
1096 
1097 template <class T>
1098 struct IteratorTraits<StridedImageIterator<T> >
1099 : public IteratorTraitsBase<StridedImageIterator<T> >
1100 {
1101  typedef StridedImageIterator<T> mutable_iterator;
1102  typedef ConstStridedImageIterator<T> const_iterator;
1103  typedef typename AccessorTraits<T>::default_accessor DefaultAccessor;
1104  typedef DefaultAccessor default_accessor;
1105  typedef VigraTrueType hasConstantStrides;
1106 };
1107 
1108 template <class T>
1109 struct IteratorTraits<ConstStridedImageIterator<T> >
1110 : public IteratorTraitsBase<ConstStridedImageIterator<T> >
1111 {
1112  typedef StridedImageIterator<T> mutable_iterator;
1113  typedef ConstStridedImageIterator<T> const_iterator;
1114  typedef typename AccessorTraits<T>::default_const_accessor DefaultAccessor;
1115  typedef DefaultAccessor default_accessor;
1116  typedef VigraTrueType hasConstantStrides;
1117 };
1118 
1119 #else // NO_PARTIAL_TEMPLATE_SPECIALIZATION
1120 
1121 #define VIGRA_DEFINE_ITERATORTRAITS(VALUETYPE) \
1122  template <> \
1123  struct IteratorTraits<ImageIterator<VALUETYPE > > \
1124  : public IteratorTraitsBase<ImageIterator<VALUETYPE > > \
1125  { \
1126  typedef ImageIterator<VALUETYPE> mutable_iterator; \
1127  typedef ConstImageIterator<VALUETYPE> const_iterator; \
1128  typedef typename AccessorTraits<VALUETYPE >::default_accessor DefaultAccessor; \
1129  typedef DefaultAccessor default_accessor; \
1130  typedef VigraTrueType hasConstantStrides; \
1131  }; \
1132  \
1133  template <> \
1134  struct IteratorTraits<ConstImageIterator<VALUETYPE > > \
1135  : public IteratorTraitsBase<ConstImageIterator<VALUETYPE > > \
1136  { \
1137  typedef ImageIterator<VALUETYPE> mutable_iterator; \
1138  typedef ConstImageIterator<VALUETYPE> const_iterator; \
1139  typedef typename AccessorTraits<VALUETYPE >::default_const_accessor DefaultAccessor; \
1140  typedef DefaultAccessor default_accessor; \
1141  typedef VigraTrueType hasConstantStrides; \
1142  }; \
1143  template <> \
1144  struct IteratorTraits<StridedImageIterator<VALUETYPE > > \
1145  : public IteratorTraitsBase<StridedImageIterator<VALUETYPE > > \
1146  { \
1147  typedef StridedImageIterator<VALUETYPE> mutable_iterator; \
1148  typedef ConstStridedImageIterator<VALUETYPE> const_iterator; \
1149  typedef typename AccessorTraits<VALUETYPE >::default_accessor DefaultAccessor; \
1150  typedef DefaultAccessor default_accessor; \
1151  typedef VigraTrueType hasConstantStrides; \
1152  }; \
1153  \
1154  template <> \
1155  struct IteratorTraits<ConstStridedImageIterator<VALUETYPE > > \
1156  : public IteratorTraitsBase<ConstStridedImageIterator<VALUETYPE > > \
1157  { \
1158  typedef StridedImageIterator<VALUETYPE> mutable_iterator; \
1159  typedef ConstStridedImageIterator<VALUETYPE> const_iterator; \
1160  typedef typename AccessorTraits<VALUETYPE >::default_const_accessor DefaultAccessor; \
1161  typedef DefaultAccessor default_accessor; \
1162  typedef VigraTrueType hasConstantStrides; \
1163  };
1164 
1165 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<unsigned char>)
1166 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<short>)
1167 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<int>)
1168 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<float>)
1169 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<double>)
1170 
1171 #define VIGRA_PIXELTYPE TinyVector<unsigned char, 2>
1172 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1173 #undef VIGRA_PIXELTYPE
1174 #define VIGRA_PIXELTYPE TinyVector<unsigned char, 3>
1175 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1176 #undef VIGRA_PIXELTYPE
1177 #define VIGRA_PIXELTYPE TinyVector<unsigned char, 4>
1178 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1179 #undef VIGRA_PIXELTYPE
1180 #define VIGRA_PIXELTYPE TinyVector<short, 2>
1181 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1182 #undef VIGRA_PIXELTYPE
1183 #define VIGRA_PIXELTYPE TinyVector<short, 3>
1184 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1185 #undef VIGRA_PIXELTYPE
1186 #define VIGRA_PIXELTYPE TinyVector<short, 4>
1187 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1188 #undef VIGRA_PIXELTYPE
1189 #define VIGRA_PIXELTYPE TinyVector<int, 2>
1190 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1191 #undef VIGRA_PIXELTYPE
1192 #define VIGRA_PIXELTYPE TinyVector<int, 3>
1193 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1194 #undef VIGRA_PIXELTYPE
1195 #define VIGRA_PIXELTYPE TinyVector<int, 4>
1196 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1197 #undef VIGRA_PIXELTYPE
1198 #define VIGRA_PIXELTYPE TinyVector<float, 2>
1199 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1200 #undef VIGRA_PIXELTYPE
1201 #define VIGRA_PIXELTYPE TinyVector<float, 3>
1202 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1203 #undef VIGRA_PIXELTYPE
1204 #define VIGRA_PIXELTYPE TinyVector<float, 4>
1205 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1206 #undef VIGRA_PIXELTYPE
1207 #define VIGRA_PIXELTYPE TinyVector<double, 2>
1208 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1209 #undef VIGRA_PIXELTYPE
1210 #define VIGRA_PIXELTYPE TinyVector<double, 3>
1211 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1212 #undef VIGRA_PIXELTYPE
1213 #define VIGRA_PIXELTYPE TinyVector<double, 4>
1214 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1215 #undef VIGRA_PIXELTYPE
1216 
1217 #undef VIGRA_DEFINE_ITERATORTRAITS
1218 
1219 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
1220 
1221 template <class PIXELTYPE>
1222 class ConstValueIteratorPolicy
1223 {
1224  public:
1225 
1226  typedef PIXELTYPE value_type;
1227  typedef std::ptrdiff_t difference_type;
1228  typedef PIXELTYPE const & reference;
1229  typedef PIXELTYPE const & index_reference;
1230  typedef PIXELTYPE const * pointer;
1231  typedef std::random_access_iterator_tag iterator_category;
1232 
1233  struct BaseType
1234  {
1235  BaseType(PIXELTYPE const & v = PIXELTYPE(), std::ptrdiff_t p = 0)
1236  : value(v), pos(p)
1237  {}
1238 
1239  PIXELTYPE value;
1240  std::ptrdiff_t pos;
1241  };
1242 
1243  static void initialize(BaseType & /* d */) {}
1244 
1245  static reference dereference(BaseType const & d)
1246  { return d.value; }
1247 
1248  static index_reference dereference(BaseType d, difference_type)
1249  {
1250  return d.value;
1251  }
1252 
1253  static bool equal(BaseType const & d1, BaseType const & d2)
1254  { return d1.pos == d2.pos; }
1255 
1256  static bool less(BaseType const & d1, BaseType const & d2)
1257  { return d1.pos < d2.pos; }
1258 
1259  static difference_type difference(BaseType const & d1, BaseType const & d2)
1260  { return d1.pos - d2.pos; }
1261 
1262  static void increment(BaseType & d)
1263  { ++d.pos; }
1264 
1265  static void decrement(BaseType & d)
1266  { --d.pos; }
1267 
1268  static void advance(BaseType & d, difference_type n)
1269  { d.pos += n; }
1270 };
1271 
1272 /********************************************************/
1273 /* */
1274 /* ConstValueIterator */
1275 /* */
1276 /********************************************************/
1277 
1278 /** \brief Iterator that always returns the constant specified in the
1279  constructor.
1280 
1281  This iterator can be used to simulate an image that
1282  does not actually exist.
1283 
1284  <b>\#include</b> <vigra/imageiterator.hxx> <br/>
1285  Namespace: vigra
1286 
1287 */
1288 template <class PIXELTYPE>
1290 {
1291  public:
1292  /** The type of the constant the iterator holds.
1293  */
1294  typedef PIXELTYPE value_type;
1295 
1296  /** The type of the constant the iterator holds.
1297  */
1298  typedef PIXELTYPE PixelType;
1299 
1300  /** the iterator's reference type (return type of <TT>*iter</TT>)
1301  */
1302  typedef PIXELTYPE const & reference;
1303 
1304  /** the iterator's index reference type (return type of <TT>iter[diff]</TT>)
1305  */
1306  typedef PIXELTYPE const & index_reference;
1307 
1308  /** the iterator's pointer type (return type of <TT>iter.operator->()</TT>)
1309  */
1310  typedef PIXELTYPE const * pointer;
1311 
1312  /** the iterator's difference type (argument type of <TT>iter[diff]</TT>)
1313  */
1315 
1316  /** the iterator tag (image traverser)
1317  */
1318  typedef image_traverser_tag iterator_category;
1319 
1320  /** The associated row iterator.
1321  */
1323 
1324  /** The associated column iterator.
1325  */
1327 
1328  /** Let operations act in X direction
1329  */
1330  typedef std::ptrdiff_t MoveX;
1331 
1332  /** Let operations act in Y direction
1333  */
1334  typedef std::ptrdiff_t MoveY;
1335 
1336  /** Default Constructor. (the constant is set to
1337  <TT>NumericTraits<PIXELTYPE>::zero()</TT> )
1338  */
1340  : value_(NumericTraits<PIXELTYPE>::zero()), x(0), y(0)
1341  {}
1342 
1343  /** Construct with given constant.
1344  */
1346  : value_(v), x(0), y(0)
1347  {}
1348 
1349  /** Copy Constructor.
1350  */
1352  : value_(v.value_), x(v.x), y(v.y)
1353  {}
1354 
1355  /** Copy Assigment.
1356  */
1358  {
1359  if(this != &v)
1360  {
1361  value_ = v.value_;
1362  x = v.x;
1363  y = v.y;
1364  }
1365  return *this;
1366  }
1367 
1368  /** Move iterator by specified distance.
1369  */
1371  {
1372  x += d.x;
1373  y += d.y;
1374  return *this;
1375  }
1376 
1377  /** Move iterator by specified distance.
1378  */
1380  {
1381  x -= d.x;
1382  y -= d.y;
1383  return *this;
1384  }
1385 
1386  /** Create iterator at specified distance.
1387  */
1389  {
1390  ConstValueIterator ret(*this);
1391  ret += d;
1392  return ret;
1393  }
1394 
1395  /** Create iterator at specified distance.
1396  */
1398  {
1399  ConstValueIterator ret(*this);
1400  ret -= d;
1401  return ret;
1402  }
1403 
1404  /** Compute distance between two iterators
1405  */
1407  {
1408  return Diff2D(x - r.x, y - r.y);
1409  }
1410 
1411  /** Equality.
1412  */
1413  bool operator==(ConstValueIterator const & r) const
1414  {
1415  return (x == r.x) && (y == r.y);
1416  }
1417 
1418  /** Inequality.
1419  */
1420  bool operator!=(ConstValueIterator const & r) const
1421  {
1422  return (x != r.x) || (y != r.y);
1423  }
1424 
1425  /** Read current pixel (return specified constant).
1426  */
1428  {
1429  return value_;
1430  }
1431 
1432  /** Call member function for stored constant.
1433  */
1435  {
1436  return &value_;
1437  }
1438 
1439  /** Read pixel at a distance (return specified constant).
1440  */
1441  index_reference operator()(std::ptrdiff_t const &, std::ptrdiff_t const &) const
1442  {
1443  return value_;
1444  }
1445 
1446  /** Read pixel at a distance (return specified constant).
1447  */
1449  {
1450  return value_;
1451  }
1452 
1453  /** Get row iterator at current position (which will also hold the constant).
1454  */
1456  { return row_iterator(typename row_iterator::BaseType(value_, x)); }
1457 
1458  /** Get column iterator at current position (which will also hold the constant).
1459  */
1461  { return column_iterator(typename column_iterator::BaseType(value_, y)); }
1462 
1463  /** @name Specify coordinate direction for navigation commands */
1464  //@{
1465  /// refer to x coordinate
1466  std::ptrdiff_t x;
1467  /// refer to y coordinate
1468  std::ptrdiff_t y;
1469  //@}
1470 
1471  private:
1472 
1473  PixelType value_;
1474 };
1475 
1476 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
1477 
1478 template <class T>
1480 {
1481  typedef ConstValueIterator<T> Iterator;
1482  typedef Iterator iterator;
1483  typedef typename iterator::iterator_category iterator_category;
1484  typedef typename iterator::value_type value_type;
1485  typedef typename iterator::reference reference;
1486  typedef typename iterator::index_reference index_reference;
1487  typedef typename iterator::pointer pointer;
1488  typedef typename iterator::difference_type difference_type;
1489  typedef typename iterator::row_iterator row_iterator;
1490  typedef typename iterator::column_iterator column_iterator;
1491  typedef StandardConstAccessor<T> DefaultAccessor;
1492  typedef StandardConstAccessor<T> default_accessor;
1493  typedef VigraTrueType hasConstantStrides;
1494 };
1495 
1496 #endif
1497 
1498 /** \brief Simulate an image where each pixel contains its coordinate.
1499 
1500  CoordinateIterator used to be a separate class,
1501  but has now become an alias for \ref vigra::Diff2D. This is possible because
1502  Diff2D now provides all the necessary functionality.
1503 
1504  CoordinateIterator behaves like a read-only \ref vigra::ImageIterator for
1505  an image in which each pixel contains its coordinate. This is useful for
1506  algorithms that need access to the current pixel's location.
1507  For example, you can use CoordinateIterator/Diff2D to
1508  find the center of mass of an image region. To implement this,
1509  we first need a functor for center-of-mass calculations:
1510 
1511  \code
1512 
1513  struct CenterOfMassFunctor
1514  {
1515  CenterOfMassFunctor()
1516  : x(0.0), y(0.0), size(0)
1517  {}
1518 
1519  void operator()(Diff2d const& diff)
1520  {
1521  ++size;
1522  x += diff.x;
1523  y += diff.y;
1524  }
1525 
1526  float xCenter() const
1527  { return x / size; }
1528 
1529  float yCenter() const
1530  { return y / size; }
1531 
1532  float x;
1533  float y;
1534  int size;
1535  };
1536  \endcode
1537 
1538  Using this functor, we find the center of mass like so:
1539 
1540  \code
1541  vigra::BImage img(w,h);
1542  ... // mark a region in the image with '1', background with '0'
1543 
1544  CenterOfMassFunctor center;
1545 
1546  vigra::inspectImageIf(
1547  srcIterRange(Diff2D(), Diff2D() + img.size()),
1548  srcImage(img),
1549  center);
1550 
1551  std::cout << "Center of mass: " << center.xCenter() <<
1552  ", " << center.yCenter() << std::endl;
1553  \endcode
1554 
1555  <b>\#include</b> <vigra/imageiterator.hxx> <br/>
1556  Namespace: vigra
1557 */
1559 
1560 //@}
1561 
1562 } // namespace vigra
1563 
1564 #endif // VIGRA_IMAGEITERATOR_HXX
POINTER pointer
Definition: imageiterator.hxx:593
ConstValueIterator(PixelType const &v)
Definition: imageiterator.hxx:1345
PIXELTYPE PixelType
Definition: imageiterator.hxx:581
Export associated information for each image iterator.
Definition: iteratortraits.hxx:109
image_traverser_tag iterator_category
Definition: imageiterator.hxx:601
ImageIteratorBase()
Definition: imageiterator.hxx:706
IteratorAdaptor< ConstValueIteratorPolicy< PIXELTYPE > > column_iterator
Definition: imageiterator.hxx:1326
MoveX x
Definition: imageiterator.hxx:660
int y
Definition: diff2d.hxx:392
pointer operator->() const
Definition: imageiterator.hxx:778
Diff2D operator-(Diff2D const &a, Diff2D const &b)
Definition: diff2d.hxx:711
ConstValueIterator()
Definition: imageiterator.hxx:1339
REFERENCE reference
Definition: imageiterator.hxx:585
MoveY y
Definition: imageiterator.hxx:673
ImageIteratorBase(pointer base, std::ptrdiff_t ystride)
Definition: imageiterator.hxx:683
pointer operator->() const
Definition: imageiterator.hxx:1434
ConstValueIterator & operator-=(Diff2D const &d)
Definition: imageiterator.hxx:1379
int x
Definition: diff2d.hxx:385
ImageIteratorBase & operator=(ImageIteratorBase const &rhs)
Definition: imageiterator.hxx:712
RowIteratorSelector::res row_iterator
Definition: imageiterator.hxx:605
ConstValueIterator operator+(Diff2D const &d) const
Definition: imageiterator.hxx:1388
ImageIteratorBase(pointer base, std::ptrdiff_t xstride, std::ptrdiff_t ystride)
Definition: imageiterator.hxx:694
Two dimensional difference vector.
Definition: diff2d.hxx:185
ColumnIteratorSelector::res column_iterator
Definition: imageiterator.hxx:609
std::ptrdiff_t y
refer to y coordinate
Definition: imageiterator.hxx:1468
ImageIterator(pointer base, std::ptrdiff_t ystride)
Definition: imageiterator.hxx:866
bool operator!=(ImageIteratorBase const &rhs) const
Definition: imageiterator.hxx:632
ImageIterator()
Definition: imageiterator.hxx:871
Standard 2D random access const iterator for images that store the data as a linear array...
Definition: imageiterator.hxx:893
IMAGEITERATOR & operator-=(difference_type const &s)
Definition: imageiterator.hxx:735
StridedImageIterator(pointer base, std::ptrdiff_t ystride, std::ptrdiff_t xskip, std::ptrdiff_t yskip)
Definition: imageiterator.hxx:981
StridedImageIterator()
Definition: imageiterator.hxx:986
ConstValueIterator & operator=(ConstValueIterator const &v)
Definition: imageiterator.hxx:1357
Diff2D CoordinateIterator
Simulate an image where each pixel contains its coordinate.
Definition: imageiterator.hxx:1558
FFTWComplex< R > & operator-=(FFTWComplex< R > &a, const FFTWComplex< R > &b)
subtract-assignment
Definition: fftw3.hxx:867
ConstValueIterator & operator+=(Diff2D const &d)
Definition: imageiterator.hxx:1370
ConstStridedImageIterator(StridedImageIterator< PIXELTYPE > const &o)
Definition: imageiterator.hxx:1048
bool operator!=(ConstValueIterator const &r) const
Definition: imageiterator.hxx:1420
PIXELTYPE value_type
Definition: imageiterator.hxx:577
Const iterator to be used when pixels are to be skipped.
Definition: imageiterator.hxx:1026
bool operator<=(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r)
less or equal
Definition: fixedpoint.hxx:521
reference operator*() const
Definition: imageiterator.hxx:1427
difference_type operator-(ImageIteratorBase const &rhs) const
Definition: imageiterator.hxx:639
FFTWComplex< R > & operator+=(FFTWComplex< R > &a, const FFTWComplex< R > &b)
add-assignment
Definition: fftw3.hxx:859
bool operator==(ImageIteratorBase const &rhs) const
Definition: imageiterator.hxx:625
vigra::detail::DirectionSelector< StridedArrayTag >::template type< std::ptrdiff_t > MoveY
Definition: imageiterator.hxx:619
PIXELTYPE const * pointer
Definition: imageiterator.hxx:1310
IteratorAdaptor< ConstValueIteratorPolicy< PIXELTYPE > > row_iterator
Definition: imageiterator.hxx:1322
bool operator!=(FFTWComplex< R > const &a, const FFTWComplex< R > &b)
not equal
Definition: fftw3.hxx:841
ConstStridedImageIterator & operator=(StridedImageIterator< PIXELTYPE > const &o)
Definition: imageiterator.hxx:1058
std::ptrdiff_t MoveY
Definition: imageiterator.hxx:1334
bool operator==(FFTWComplex< R > const &a, const FFTWComplex< R > &b)
equal
Definition: fftw3.hxx:825
Diff2D difference_type
Definition: imageiterator.hxx:1314
index_reference operator[](Diff2D const &) const
Definition: imageiterator.hxx:1448
Definition: metaprogramming.hxx:116
IMAGEITERATOR operator-(difference_type const &s) const
Definition: imageiterator.hxx:755
Diff2D difference_type
Definition: imageiterator.hxx:597
bool operator<(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r)
less than
Definition: fixedpoint.hxx:512
Iterator that always returns the constant specified in the constructor.
Definition: imageiterator.hxx:1289
ConstValueIterator operator-(Diff2D const &d) const
Definition: imageiterator.hxx:1397
Standard 2D random access iterator for images that store the data in a linear array.
Definition: imageiterator.hxx:848
ConstValueIterator(ConstValueIterator const &v)
Definition: imageiterator.hxx:1351
Encapsulate read access to the values an iterator points to.
Definition: accessor.hxx:269
bool operator>=(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r)
greater or equal
Definition: fixedpoint.hxx:539
index_reference operator[](Diff2D const &d) const
Definition: imageiterator.hxx:786
ConstImageIterator(pointer base, std::ptrdiff_t ystride)
Definition: imageiterator.hxx:911
vigra::detail::DirectionSelector< StridedOrUnstrided >::template type< pointer > MoveX
Definition: imageiterator.hxx:614
ConstStridedImageIterator(pointer base, std::ptrdiff_t ystride, std::ptrdiff_t xskip, std::ptrdiff_t yskip)
Definition: imageiterator.hxx:1043
row_iterator rowIterator() const
Definition: imageiterator.hxx:1455
image_traverser_tag iterator_category
Definition: imageiterator.hxx:1318
std::ptrdiff_t MoveX
Definition: imageiterator.hxx:1330
IMAGEITERATOR operator+(difference_type const &s) const
Definition: imageiterator.hxx:744
PIXELTYPE const & reference
Definition: imageiterator.hxx:1302
index_reference operator()(std::ptrdiff_t dx, std::ptrdiff_t dy) const
Definition: imageiterator.hxx:794
ImageIteratorBase(ImageIteratorBase const &rhs)
Definition: imageiterator.hxx:700
PIXELTYPE const & index_reference
Definition: imageiterator.hxx:1306
Iterator to be used when pixels are to be skipped.
Definition: imageiterator.hxx:966
IMAGEITERATOR & operator+=(difference_type const &s)
Definition: imageiterator.hxx:727
bool operator>(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r)
greater
Definition: fixedpoint.hxx:530
Quickly create 1-dimensional iterator adapters.
Definition: iteratoradapter.hxx:147
std::ptrdiff_t x
refer to x coordinate
Definition: imageiterator.hxx:1466
pointer operator[](std::ptrdiff_t dy) const
Definition: imageiterator.hxx:803
index_reference operator()(std::ptrdiff_t const &, std::ptrdiff_t const &) const
Definition: imageiterator.hxx:1441
column_iterator columnIterator() const
Definition: imageiterator.hxx:1460
reference operator*() const
Definition: imageiterator.hxx:770
PIXELTYPE value_type
Definition: imageiterator.hxx:1294
Diff2D operator-(ConstValueIterator const &r) const
Definition: imageiterator.hxx:1406
ConstImageIterator()
Definition: imageiterator.hxx:920
REFERENCE index_reference
Definition: imageiterator.hxx:589
Base class for 2D random access iterators.
Definition: imageiterator.hxx:563
PIXELTYPE PixelType
Definition: imageiterator.hxx:1298
ConstStridedImageIterator()
Definition: imageiterator.hxx:1053
bool operator==(ConstValueIterator const &r) const
Definition: imageiterator.hxx:1413

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de)
Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany

html generated using doxygen and Python
vigra 1.11.1 (Fri May 19 2017)