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

imageiterator.hxx
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+=(int dx) {current_ += dx; }
391  void operator-=(int 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  int operator-(type const & rhs) const
412  { return current_ - rhs.current_; }
413 
414  T operator()() const
415  { return current_; }
416 
417  T operator()(int 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(int 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+=(int dy) {current_ += dy*stride_; }
455  void operator-=(int 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  int operator-(type const & rhs) const
476  { return (current_ - rhs.current_) / stride_; }
477 
478  T operator()() const
479  { return current_; }
480 
481  T operator()(int d) const
482  { return current_ + d*stride_; }
483 
484  int 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>
545 
546  Namespace: vigra
547 
548  The usage examples assume that you constructed two iterators like
549  this:
550 
551  \code
552  vigra::ImageIterator<SomePixelType> iterator(base, width);
553  vigra::ImageIterator<SomePixelType> iterator1(base, width);
554  \endcode
555 
556  See the paper: U. Koethe:
557  <a href="http://hci.iwr.uni-heidelberg.de/vigra/documents/GenericProg2D.ps">Reusable Algorithms in Image Processing</a>
558  for a discussion of the concepts behind ImageIterators.
559 
560 */
561 template <class IMAGEITERATOR,
562  class PIXELTYPE, class REFERENCE, class POINTER,
563  class StridedOrUnstrided = UnstridedArrayTag>
565 {
566  typedef typename
567  vigra::detail::LinearIteratorSelector<StridedOrUnstrided>::template type<ImageIteratorBase>
568  RowIteratorSelector;
569  typedef typename
570  vigra::detail::LinearIteratorSelector<StridedArrayTag>::template type<ImageIteratorBase>
571  ColumnIteratorSelector;
572  public:
573  typedef ImageIteratorBase<IMAGEITERATOR,
574  PIXELTYPE, REFERENCE, POINTER, StridedOrUnstrided> self_type;
575 
576  /** The underlying image's pixel type.
577  */
578  typedef PIXELTYPE value_type;
579 
580  /** deprecated, use <TT>value_type</TT> instead.
581  */
582  typedef PIXELTYPE PixelType;
583 
584  /** the iterator's reference type (return type of <TT>*iter</TT>)
585  */
586  typedef REFERENCE reference;
587 
588  /** the iterator's index reference type (return type of <TT>iter[diff]</TT>)
589  */
590  typedef REFERENCE index_reference;
591 
592  /** the iterator's pointer type (return type of <TT>iter.operator->()</TT>)
593  */
594  typedef POINTER pointer;
595 
596  /** the iterator's difference type (argument type of <TT>iter[diff]</TT>)
597  */
599 
600  /** the iterator tag (image traverser)
601  */
602  typedef image_traverser_tag iterator_category;
603 
604  /** The associated row iterator.
605  */
606  typedef typename RowIteratorSelector::res row_iterator;
607 
608  /** The associated column iterator.
609  */
610  typedef typename ColumnIteratorSelector::res column_iterator;
611 
612  /** Let operations act in X direction
613  */
614  typedef typename
615  vigra::detail::DirectionSelector<StridedOrUnstrided>::template type<pointer> MoveX;
616 
617  /** Let operations act in Y direction
618  */
619  typedef typename
620  vigra::detail::DirectionSelector<StridedArrayTag>::template type<int> MoveY;
621 
622  /** @name Comparison of Iterators */
623  //@{
624  /** usage: <TT> iterator == iterator1 </TT>
625  */
626  bool operator==(ImageIteratorBase const & rhs) const
627  {
628  return (x == rhs.x) && (y == rhs.y);
629  }
630 
631  /** usage: <TT> iterator != iterator1 </TT>
632  */
633  bool operator!=(ImageIteratorBase const & rhs) const
634  {
635  return (x != rhs.x) || (y != rhs.y);
636  }
637 
638  /** usage: <TT> Diff2D dist = iterator - iterator1 </TT>
639  */
641  {
642  return difference_type(x - rhs.x, y - rhs.y);
643  }
644 
645  //@}
646 
647  /** @name Specify coordinate to operate on */
648  //@{
649  /** Refer to iterator's x coordinate.
650  Usage examples:<br>
651  \code
652  ++iterator.x; // move one step to the right
653  --iterator.x; // move one step to the left
654  iterator.x += dx; // move dx steps to the right
655  iterator.x -= dx; // move dx steps to the left
656  bool notAtEndOfRow = iterator.x < lowerRight.x; // compare x coordinates of two iterators
657  int width = lowerRight.x - upperLeft.x; // calculate difference of x coordinates
658  // between two iterators
659  \endcode
660  */
662  /** Refer to iterator's y coordinate.
663  Usage examples:<br>
664  \code
665  ++iterator.y; // move one step down
666  --iterator.y; // move one step up
667  iterator.y += dy; // move dy steps down
668  iterator.y -= dy; // move dy steps up
669  bool notAtEndOfColumn = iterator.y < lowerRight.y; // compare y coordinates of two iterators
670  int height = lowerRight.y - upperLeft.y; // calculate difference of y coordinates
671  // between two iterators
672  \endcode
673  */
675  //@}
676 
677  protected:
678  /** Construct from raw memory with a vertical stride of <TT>ystride</TT>.
679  <TT>ystride</TT> must equal the physical image width (row length),
680  even if the iterator will only be used for a sub image. This constructor
681  must only be called for unstrided iterators
682  (<tt>StridedOrUnstrided == UnstridedArrayTag</tt>)
683  */
684  ImageIteratorBase(pointer base, int ystride)
685  : x(base),
686  y(ystride)
687  {}
688 
689  /** Construct from raw memory with a horizontal stride of <TT>xstride</TT>
690  and a vertical stride of <TT>ystride</TT>. This constructor
691  may be used for iterators that shall skip pixels. Thus, it
692  must only be called for strided iterators
693  (<tt>StridedOrUnstrided == StridedArrayTag</tt>)
694  */
695  ImageIteratorBase(pointer base, int xstride, int ystride)
696  : x(xstride, base),
697  y(ystride)
698  {}
699 
700  /** Copy constructor */
702  : x(rhs.x),
703  y(rhs.y)
704  {}
705 
706  /** Default constructor */
708  : x(0),
709  y(0)
710  {}
711 
712  /** Copy assignment */
714  {
715  if(this != &rhs)
716  {
717  x = rhs.x;
718  y = rhs.y;
719  }
720  return *this;
721  }
722 
723  public:
724  /** @name Random navigation */
725  //@{
726  /** Add offset via Diff2D
727  */
728  IMAGEITERATOR & operator+=(difference_type const & s)
729  {
730  x += s.x;
731  y += s.y;
732  return static_cast<IMAGEITERATOR &>(*this);
733  }
734  /** Subtract offset via Diff2D
735  */
736  IMAGEITERATOR & operator-=(difference_type const & s)
737  {
738  x -= s.x;
739  y -= s.y;
740  return static_cast<IMAGEITERATOR &>(*this);
741  }
742 
743  /** Add a distance
744  */
745  IMAGEITERATOR operator+(difference_type const & s) const
746  {
747  IMAGEITERATOR ret(static_cast<IMAGEITERATOR const &>(*this));
748 
749  ret += s;
750 
751  return ret;
752  }
753 
754  /** Subtract a distance
755  */
756  IMAGEITERATOR operator-(difference_type const & s) const
757  {
758  IMAGEITERATOR ret(static_cast<IMAGEITERATOR const &>(*this));
759 
760  ret -= s;
761 
762  return ret;
763  }
764  //@}
765 
766  /** @name Access the Pixels */
767  //@{
768  /** Access current pixel. <br>
769  usage: <TT> SomePixelType value = *iterator </TT>
770  */
772  {
773  return *current();
774  }
775 
776  /** Call member of current pixel. <br>
777  usage: <TT> iterator->pixelMemberFunction() </TT>
778  */
780  {
781  return current();
782  }
783 
784  /** Access pixel at offset from current location. <br>
785  usage: <TT> SomePixelType value = iterator[Diff2D(1,1)] </TT>
786  */
788  {
789  return *current(d.x, d.y);
790  }
791 
792  /** Access pixel at offset (dx, dy) from current location. <br>
793  usage: <TT> SomePixelType value = iterator(dx, dy) </TT>
794  */
795  index_reference operator()(int dx, int dy) const
796  {
797  return *current(dx, dy);
798  }
799 
800  /** Read pixel with offset [dy][dx] from current pixel.
801  Note that the 'x' index is the trailing index. <br>
802  usage: <TT> SomePixelType value = iterator[dy][dx] </TT>
803  */
804  pointer operator[](int dy) const
805  {
806  return x() + y(dy);
807  }
808  //@}
809 
810  row_iterator rowIterator() const
811  {
812  return RowIteratorSelector::construct(current(), x);
813  }
814 
815  column_iterator columnIterator() const
816  {
817  return ColumnIteratorSelector::construct(current(), y);
818  }
819 
820  private:
821 
822  pointer current() const
823  { return x() + y(); }
824 
825  pointer current(int dx, int dy) const
826  { return x(dx) + y(dy); }
827 };
828 
829 /********************************************************/
830 /* */
831 /* ImageIterator */
832 /* */
833 /********************************************************/
834 
835 /** \brief Standard 2D random access iterator for images that store the
836  data in a linear array.
837 
838  Most functions and local types are inherited from ImageIteratorBase.
839 
840  See the paper: U. Koethe:
841  <a href="http://hci.iwr.uni-heidelberg.de/vigra/documents/GenericProg2D.ps">Reusable Algorithms in Image Processing</a>
842  for a discussion of the concepts behind ImageIterators.
843 
844  <b>\#include</b> <vigra/imageiterator.hxx>
845 
846  Namespace: vigra
847 
848 */
849 template <class PIXELTYPE>
851 : public ImageIteratorBase<ImageIterator<PIXELTYPE>,
852  PIXELTYPE, PIXELTYPE &, PIXELTYPE *>
853 {
854  public:
856  PIXELTYPE, PIXELTYPE &, PIXELTYPE *> Base;
857 
858  typedef typename Base::pointer pointer;
859  typedef typename Base::difference_type difference_type;
860 
861  /** Construct from raw memory with a vertical stride of <TT>ystride</TT>.
862  <TT>ystride</TT> must equal the physical image width (row length),
863  even if the iterator will only be used for a sub image.
864  If the raw memory is encapsulated in an image object this
865  object should have a factory function that constructs the
866  iterator.
867  */
868  ImageIterator(pointer base, int ystride)
869  : Base(base, ystride)
870  {}
871 
872  /** Default constructor */
874  : Base()
875  {}
876 
877 };
878 
879 /********************************************************/
880 /* */
881 /* ConstImageIterator */
882 /* */
883 /********************************************************/
884 
885 /** \brief Standard 2D random access const iterator for images that
886  store the data as a linear array.
887 
888  Most functions are inherited from ImageIteratorBase.
889 
890  <b>\#include</b> <vigra/imageiterator.hxx>
891 
892  Namespace: vigra
893 
894 */
895 template <class PIXELTYPE>
897 : public ImageIteratorBase<ConstImageIterator<PIXELTYPE>,
898  PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *>
899 {
900  public:
902  PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *> Base;
903 
904  typedef typename Base::pointer pointer;
905  typedef typename Base::difference_type difference_type;
906 
907  /** Construct from raw memory with a vertical stride of <TT>ystride</TT>.
908  <TT>ystride</TT> must equal the physical image width (row length),
909  even if the iterator will only be used for a sub image.
910  If the raw memory is encapsulated in an image object this
911  object should have a factory function that constructs the
912  iterator.
913  */
914  ConstImageIterator(pointer base, int ystride)
915  : Base(base, ystride)
916  {}
917 
919  : Base(o.x, o.y)
920  {}
921 
922  /** Default constructor */
924  : Base()
925  {}
926 
927  ConstImageIterator & operator=(ImageIterator<PIXELTYPE> const & o)
928  {
929  Base::x = o.x;
930  Base::y = o.y;
931  return *this;
932  }
933 };
934 
935 /********************************************************/
936 /* */
937 /* StridedImageIterator */
938 /* */
939 /********************************************************/
940 
941 /** \brief Iterator to be used when pixels are to be skipped.
942 
943  This iterator can be used when some pixels shall be automatically skipped, for example
944  if an image is to be sub-sampled: instead of advancing to the next pixel,
945  <tt>++iterator.x</tt> jumps to the pixel at a horizontal offset of <tt>xskip</tt>.
946  Likewise with <tt>yskip</tt> in vertical direction. Most functions and local types
947  are inherited from ImageIteratorBase.
948 
949  <b> Usage:</b>
950 
951  \code
952  BImage img(w,h);
953  ...
954  int xskip = 2, yskip = 2;
955  int wskip = w / xskip + 1, hskip = h / yskip + 1;
956 
957  StridedImageIterator<BImage::value_type> upperLeft(&img(0,0), w, xskip, yskip);
958  StridedImageIterator<BImage::value_type> lowerRight = upperLeft + Diff2D(wskip, hskip);
959 
960  // now navigation with upperLeft and lowerRight lets the image appear to have half
961  // the original resolution in either dimension
962  \endcode
963 
964  <b>\#include</b> <vigra/imageiterator.hxx>
965 
966  Namespace: vigra
967 
968 */
969 template <class PIXELTYPE>
971 : public ImageIteratorBase<StridedImageIterator<PIXELTYPE>,
972  PIXELTYPE, PIXELTYPE &, PIXELTYPE *, StridedArrayTag>
973 {
974  public:
976  PIXELTYPE, PIXELTYPE &, PIXELTYPE *, StridedArrayTag> Base;
977 
978  typedef typename Base::pointer pointer;
979  typedef typename Base::difference_type difference_type;
980 
981  /** Construct from raw memory with a vertical stride of <TT>ystride</TT>,
982  jumping by <tt>xskip</tt> horizontally and <tt>yskip</tt> vertically.
983  <tt>ystride</tt> must be the physical width (row length) of the image.
984  */
985  StridedImageIterator(pointer base, int ystride, int xskip, int yskip)
986  : Base(base, xskip, ystride*yskip)
987  {}
988 
989  /** Default constructor */
991  : Base()
992  {}
993 
994 };
995 
996 /********************************************************/
997 /* */
998 /* ConstStridedImageIterator */
999 /* */
1000 /********************************************************/
1001 
1002 /** \brief Const iterator to be used when pixels are to be skipped.
1003 
1004  This iterator can be used when some pixels shall be automatically skipped, for example
1005  if an image is to be sub-sampled: instead of advancing to the next pixel,
1006  <tt>++iterator.x</tt> jumps to the pixel at a horizontal offset of <tt>xskip</tt>.
1007  Likewise with <tt>yskip</tt> in vertical direction. Most functions and local types
1008  are inherited from ImageIteratorBase.
1009 
1010  <b> Usage:</b>
1011 
1012  \code
1013  BImage img(w,h);
1014  ...
1015  int xskip = 2, yskip = 2;
1016  int wskip = w / xskip + 1, hskip = h / yskip + 1;
1017 
1018  ConstStridedImageIterator<BImage::value_type> upperLeft(&img(0,0), w, xskip, yskip);
1019  ConstStridedImageIterator<BImage::value_type> lowerRight = upperLeft + Diff2D(wskip, hskip);
1020 
1021  // now navigation with upperLeft and lowerRight lets the image appear to have half
1022  // the original resolution in either dimension
1023  \endcode
1024 
1025  <b>\#include</b> <vigra/imageiterator.hxx>
1026 
1027  Namespace: vigra
1028 
1029 */
1030 template <class PIXELTYPE>
1032 : public ImageIteratorBase<ConstStridedImageIterator<PIXELTYPE>,
1033  PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *,
1034  StridedArrayTag>
1035 {
1036  public:
1038  PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *,
1040 
1041  typedef typename Base::pointer pointer;
1042  typedef typename Base::difference_type difference_type;
1043 
1044  /** Construct from raw memory with a vertical stride of <TT>ystride</TT>,
1045  jumping by <tt>xskip</tt> horizontally and <tt>yskip</tt> vertically.
1046  <tt>ystride</tt> must be the physical width (row length) of the image.
1047  */
1048  ConstStridedImageIterator(pointer base, int ystride, int xskip, int yskip)
1049  : Base(base, xskip, ystride*yskip)
1050  {}
1051 
1052  /** Copy-construct from mutable iterator */
1054  : Base(o.x, o.y)
1055  {}
1056 
1057  /** Default constructor */
1059  : Base()
1060  {}
1061 
1062  /** Assign mutable iterator */
1064  {
1065  Base::x = o.x;
1066  Base::y = o.y;
1067  return *this;
1068  }
1069 };
1070 
1071 /********************************************************/
1072 /* */
1073 /* definition of iterator traits */
1074 /* */
1075 /********************************************************/
1076 
1077 
1078 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
1079 
1080 template <class T>
1081 struct IteratorTraits<ImageIterator<T> >
1082 : public IteratorTraitsBase<ImageIterator<T> >
1083 {
1084  typedef ImageIterator<T> mutable_iterator;
1085  typedef ConstImageIterator<T> const_iterator;
1086  typedef typename AccessorTraits<T>::default_accessor DefaultAccessor;
1087  typedef DefaultAccessor default_accessor;
1088  typedef VigraTrueType hasConstantStrides;
1089 };
1090 
1091 template <class T>
1092 struct IteratorTraits<ConstImageIterator<T> >
1093 : public IteratorTraitsBase<ConstImageIterator<T> >
1094 {
1095  typedef ImageIterator<T> mutable_iterator;
1096  typedef ConstImageIterator<T> const_iterator;
1097  typedef typename AccessorTraits<T>::default_const_accessor DefaultAccessor;
1098  typedef DefaultAccessor default_accessor;
1099  typedef VigraTrueType hasConstantStrides;
1100 };
1101 
1102 template <class T>
1103 struct IteratorTraits<StridedImageIterator<T> >
1104 : public IteratorTraitsBase<StridedImageIterator<T> >
1105 {
1106  typedef StridedImageIterator<T> mutable_iterator;
1107  typedef ConstStridedImageIterator<T> const_iterator;
1108  typedef typename AccessorTraits<T>::default_accessor DefaultAccessor;
1109  typedef DefaultAccessor default_accessor;
1110  typedef VigraTrueType hasConstantStrides;
1111 };
1112 
1113 template <class T>
1114 struct IteratorTraits<ConstStridedImageIterator<T> >
1115 : public IteratorTraitsBase<ConstStridedImageIterator<T> >
1116 {
1117  typedef StridedImageIterator<T> mutable_iterator;
1118  typedef ConstStridedImageIterator<T> const_iterator;
1119  typedef typename AccessorTraits<T>::default_const_accessor DefaultAccessor;
1120  typedef DefaultAccessor default_accessor;
1121  typedef VigraTrueType hasConstantStrides;
1122 };
1123 
1124 #else // NO_PARTIAL_TEMPLATE_SPECIALIZATION
1125 
1126 #define VIGRA_DEFINE_ITERATORTRAITS(VALUETYPE) \
1127  template <> \
1128  struct IteratorTraits<ImageIterator<VALUETYPE > > \
1129  : public IteratorTraitsBase<ImageIterator<VALUETYPE > > \
1130  { \
1131  typedef ImageIterator<VALUETYPE> mutable_iterator; \
1132  typedef ConstImageIterator<VALUETYPE> const_iterator; \
1133  typedef typename AccessorTraits<VALUETYPE >::default_accessor DefaultAccessor; \
1134  typedef DefaultAccessor default_accessor; \
1135  typedef VigraTrueType hasConstantStrides; \
1136  }; \
1137  \
1138  template <> \
1139  struct IteratorTraits<ConstImageIterator<VALUETYPE > > \
1140  : public IteratorTraitsBase<ConstImageIterator<VALUETYPE > > \
1141  { \
1142  typedef ImageIterator<VALUETYPE> mutable_iterator; \
1143  typedef ConstImageIterator<VALUETYPE> const_iterator; \
1144  typedef typename AccessorTraits<VALUETYPE >::default_const_accessor DefaultAccessor; \
1145  typedef DefaultAccessor default_accessor; \
1146  typedef VigraTrueType hasConstantStrides; \
1147  }; \
1148  template <> \
1149  struct IteratorTraits<StridedImageIterator<VALUETYPE > > \
1150  : public IteratorTraitsBase<StridedImageIterator<VALUETYPE > > \
1151  { \
1152  typedef StridedImageIterator<VALUETYPE> mutable_iterator; \
1153  typedef ConstStridedImageIterator<VALUETYPE> const_iterator; \
1154  typedef typename AccessorTraits<VALUETYPE >::default_accessor DefaultAccessor; \
1155  typedef DefaultAccessor default_accessor; \
1156  typedef VigraTrueType hasConstantStrides; \
1157  }; \
1158  \
1159  template <> \
1160  struct IteratorTraits<ConstStridedImageIterator<VALUETYPE > > \
1161  : public IteratorTraitsBase<ConstStridedImageIterator<VALUETYPE > > \
1162  { \
1163  typedef StridedImageIterator<VALUETYPE> mutable_iterator; \
1164  typedef ConstStridedImageIterator<VALUETYPE> const_iterator; \
1165  typedef typename AccessorTraits<VALUETYPE >::default_const_accessor DefaultAccessor; \
1166  typedef DefaultAccessor default_accessor; \
1167  typedef VigraTrueType hasConstantStrides; \
1168  };
1169 
1170 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<unsigned char>)
1171 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<short>)
1172 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<int>)
1173 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<float>)
1174 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<double>)
1175 
1176 #define VIGRA_PIXELTYPE TinyVector<unsigned char, 2>
1177 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1178 #undef VIGRA_PIXELTYPE
1179 #define VIGRA_PIXELTYPE TinyVector<unsigned char, 3>
1180 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1181 #undef VIGRA_PIXELTYPE
1182 #define VIGRA_PIXELTYPE TinyVector<unsigned char, 4>
1183 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1184 #undef VIGRA_PIXELTYPE
1185 #define VIGRA_PIXELTYPE TinyVector<short, 2>
1186 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1187 #undef VIGRA_PIXELTYPE
1188 #define VIGRA_PIXELTYPE TinyVector<short, 3>
1189 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1190 #undef VIGRA_PIXELTYPE
1191 #define VIGRA_PIXELTYPE TinyVector<short, 4>
1192 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1193 #undef VIGRA_PIXELTYPE
1194 #define VIGRA_PIXELTYPE TinyVector<int, 2>
1195 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1196 #undef VIGRA_PIXELTYPE
1197 #define VIGRA_PIXELTYPE TinyVector<int, 3>
1198 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1199 #undef VIGRA_PIXELTYPE
1200 #define VIGRA_PIXELTYPE TinyVector<int, 4>
1201 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1202 #undef VIGRA_PIXELTYPE
1203 #define VIGRA_PIXELTYPE TinyVector<float, 2>
1204 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1205 #undef VIGRA_PIXELTYPE
1206 #define VIGRA_PIXELTYPE TinyVector<float, 3>
1207 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1208 #undef VIGRA_PIXELTYPE
1209 #define VIGRA_PIXELTYPE TinyVector<float, 4>
1210 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1211 #undef VIGRA_PIXELTYPE
1212 #define VIGRA_PIXELTYPE TinyVector<double, 2>
1213 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1214 #undef VIGRA_PIXELTYPE
1215 #define VIGRA_PIXELTYPE TinyVector<double, 3>
1216 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1217 #undef VIGRA_PIXELTYPE
1218 #define VIGRA_PIXELTYPE TinyVector<double, 4>
1219 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1220 #undef VIGRA_PIXELTYPE
1221 
1222 #undef VIGRA_DEFINE_ITERATORTRAITS
1223 
1224 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
1225 
1226 template <class PIXELTYPE>
1227 class ConstValueIteratorPolicy
1228 {
1229  public:
1230 
1231  typedef PIXELTYPE value_type;
1232  typedef int difference_type;
1233  typedef PIXELTYPE const & reference;
1234  typedef PIXELTYPE const & index_reference;
1235  typedef PIXELTYPE const * pointer;
1236  typedef std::random_access_iterator_tag iterator_category;
1237 
1238  struct BaseType
1239  {
1240  BaseType(PIXELTYPE const & v = PIXELTYPE(), int p = 0)
1241  : value(v), pos(p)
1242  {}
1243 
1244  PIXELTYPE value;
1245  int pos;
1246  };
1247 
1248  static void initialize(BaseType & d) {}
1249 
1250  static reference dereference(BaseType const & d)
1251  { return d.value; }
1252 
1253  static index_reference dereference(BaseType d, difference_type)
1254  {
1255  return d.value;
1256  }
1257 
1258  static bool equal(BaseType const & d1, BaseType const & d2)
1259  { return d1.pos == d2.pos; }
1260 
1261  static bool less(BaseType const & d1, BaseType const & d2)
1262  { return d1.pos < d2.pos; }
1263 
1264  static difference_type difference(BaseType const & d1, BaseType const & d2)
1265  { return d1.pos - d2.pos; }
1266 
1267  static void increment(BaseType & d)
1268  { ++d.pos; }
1269 
1270  static void decrement(BaseType & d)
1271  { --d.pos; }
1272 
1273  static void advance(BaseType & d, difference_type n)
1274  { d.pos += n; }
1275 };
1276 
1277 /********************************************************/
1278 /* */
1279 /* ConstValueIterator */
1280 /* */
1281 /********************************************************/
1282 
1283 /** \brief Iterator that always returns the constant specified in the
1284  constructor.
1285 
1286  This iterator can be used to simulate an image that
1287  does not actually exist.
1288 
1289  <b>\#include</b> <vigra/imageiterator.hxx>
1290 
1291  Namespace: vigra
1292 
1293 */
1294 template <class PIXELTYPE>
1296 {
1297  public:
1298  /** The type of the constant the iterator holds.
1299  */
1300  typedef PIXELTYPE value_type;
1301 
1302  /** The type of the constant the iterator holds.
1303  */
1304  typedef PIXELTYPE PixelType;
1305 
1306  /** the iterator's reference type (return type of <TT>*iter</TT>)
1307  */
1308  typedef PIXELTYPE const & reference;
1309 
1310  /** the iterator's index reference type (return type of <TT>iter[diff]</TT>)
1311  */
1312  typedef PIXELTYPE const & index_reference;
1313 
1314  /** the iterator's pointer type (return type of <TT>iter.operator->()</TT>)
1315  */
1316  typedef PIXELTYPE const * pointer;
1317 
1318  /** the iterator's difference type (argument type of <TT>iter[diff]</TT>)
1319  */
1321 
1322  /** the iterator tag (image traverser)
1323  */
1324  typedef image_traverser_tag iterator_category;
1325 
1326  /** The associated row iterator.
1327  */
1329 
1330  /** The associated column iterator.
1331  */
1333 
1334  /** Let operations act in X direction
1335  */
1336  typedef int MoveX;
1337 
1338  /** Let operations act in Y direction
1339  */
1340  typedef int MoveY;
1341 
1342  /** Default Constructor. (the constant is set to
1343  <TT>NumericTraits<PIXELTYPE>::zero()</TT> )
1344  */
1346  : value_(NumericTraits<PIXELTYPE>::zero()), x(0), y(0)
1347  {}
1348 
1349  /** Construct with given constant.
1350  */
1352  : value_(v), x(0), y(0)
1353  {}
1354 
1355  /** Copy Constructor.
1356  */
1358  : value_(v.value_), x(v.x), y(v.y)
1359  {}
1360 
1361  /** Copy Assigment.
1362  */
1364  {
1365  if(this != &v)
1366  {
1367  value_ = v.value_;
1368  x = v.x;
1369  y = v.y;
1370  }
1371  return *this;
1372  }
1373 
1374  /** Move iterator by specified distance.
1375  */
1377  {
1378  x += d.x;
1379  y += d.y;
1380  return *this;
1381  }
1382 
1383  /** Move iterator by specified distance.
1384  */
1386  {
1387  x -= d.x;
1388  y -= d.y;
1389  return *this;
1390  }
1391 
1392  /** Create iterator at specified distance.
1393  */
1395  {
1396  ConstValueIterator ret(*this);
1397  ret += d;
1398  return ret;
1399  }
1400 
1401  /** Create iterator at specified distance.
1402  */
1404  {
1405  ConstValueIterator ret(*this);
1406  ret -= d;
1407  return ret;
1408  }
1409 
1410  /** Compute distance between two iterators
1411  */
1413  {
1414  return Diff2D(x - r.x, y - r.y);
1415  }
1416 
1417  /** Equality.
1418  */
1419  bool operator==(ConstValueIterator const & r) const
1420  {
1421  return (x == r.x) && (y == r.y);
1422  }
1423 
1424  /** Inequality.
1425  */
1426  bool operator!=(ConstValueIterator const & r) const
1427  {
1428  return (x != r.x) || (y != r.y);
1429  }
1430 
1431  /** Read current pixel (return specified constant).
1432  */
1434  {
1435  return value_;
1436  }
1437 
1438  /** Call member function for stored constant.
1439  */
1441  {
1442  return &value_;
1443  }
1444 
1445  /** Read pixel at a distance (return specified constant).
1446  */
1447  index_reference operator()(int const &, int const &) const
1448  {
1449  return value_;
1450  }
1451 
1452  /** Read pixel at a distance (return specified constant).
1453  */
1455  {
1456  return value_;
1457  }
1458 
1459  /** Get row iterator at current position (which will also hold the constant).
1460  */
1462  { return row_iterator(typename row_iterator::BaseType(value_, x)); }
1463 
1464  /** Get column iterator at current position (which will also hold the constant).
1465  */
1467  { return column_iterator(typename column_iterator::BaseType(value_, y)); }
1468 
1469  /** @name Specify coordinate direction for navigation commands */
1470  //@{
1471  /// refer to x coordinate
1472  int x;
1473  /// refer to y coordinate
1474  int y;
1475  //@}
1476 
1477  private:
1478 
1479  PixelType value_;
1480 };
1481 
1482 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
1483 
1484 template <class T>
1486 {
1487  typedef ConstValueIterator<T> Iterator;
1488  typedef Iterator iterator;
1489  typedef typename iterator::iterator_category iterator_category;
1490  typedef typename iterator::value_type value_type;
1491  typedef typename iterator::reference reference;
1492  typedef typename iterator::index_reference index_reference;
1493  typedef typename iterator::pointer pointer;
1494  typedef typename iterator::difference_type difference_type;
1495  typedef typename iterator::row_iterator row_iterator;
1496  typedef typename iterator::column_iterator column_iterator;
1497  typedef StandardConstAccessor<T> DefaultAccessor;
1498  typedef StandardConstAccessor<T> default_accessor;
1499  typedef VigraTrueType hasConstantStrides;
1500 };
1501 
1502 #endif
1503 
1504 /** \brief Simulate an image where each pixel contains its coordinate.
1505 
1506  CoordinateIterator used to be a separate class,
1507  but has now become an alias for \ref vigra::Diff2D. This is possible because
1508  Diff2D now provides all the necessary functionality.
1509 
1510  CoordinateIterator behaves like a read-only \ref vigra::ImageIterator for
1511  an image in which each pixel contains its coordinate. This is useful for
1512  algorithms that need access to the current pixel's location.
1513  For example, you can use CoordinateIterator/Diff2D to
1514  find the center of mass of an image region. To implement this,
1515  we first need a functor for center-of-mass calculations:
1516 
1517  \code
1518 
1519  struct CenterOfMassFunctor
1520  {
1521  CenterOfMassFunctor()
1522  : x(0.0), y(0.0), size(0)
1523  {}
1524 
1525  void operator()(Diff2d const& diff)
1526  {
1527  ++size;
1528  x += diff.x;
1529  y += diff.y;
1530  }
1531 
1532  float xCenter() const
1533  { return x / size; }
1534 
1535  float yCenter() const
1536  { return y / size; }
1537 
1538  float x;
1539  float y;
1540  int size;
1541  };
1542  \endcode
1543 
1544  Using this functor, we find the center of mass like so:
1545 
1546  \code
1547  vigra::BImage img(w,h);
1548  ... // mark a region in the image with '1', background with '0'
1549 
1550  CenterOfMassFunctor center;
1551 
1552  vigra::inspectImageIf(
1553  srcIterRange(Diff2D(), Diff2D() + img.size()),
1554  srcImage(img),
1555  center);
1556 
1557  std::cout << "Center of mass: " << center.xCenter() <<
1558  ", " << center.yCenter() << std::endl;
1559  \endcode
1560 
1561  <b>\#include</b> <vigra/imageiterator.hxx>
1562 
1563  Namespace: vigra
1564 */
1566 
1567 //@}
1568 
1569 } // namespace vigra
1570 
1571 #endif // VIGRA_IMAGEITERATOR_HXX

© 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.9.0 (Tue Oct 22 2013)