vigra - vigra/imageiterator.hxx Source File

[ 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> <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>
563 class ImageIteratorBase
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 */
597 typedef Diff2D difference_type;
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<int> 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 */
639 difference_type operator-(ImageIteratorBase const & rhs) const
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 */
660 MoveX x;
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 */
673 MoveY y;
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, int 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, int xstride, int ystride)
695 : x(xstride, base),
696 y(ystride)
697 {}
698
699 /** Copy constructor */
700 ImageIteratorBase(ImageIteratorBase const & rhs)
701 : x(rhs.x),
702 y(rhs.y)
703 {}
704
705 /** Default constructor */
706 ImageIteratorBase()
707 : x(0),
708 y(0)
709 {}
710
711 /** Copy assignment */
712 ImageIteratorBase & operator=(ImageIteratorBase const & rhs)
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 */
770 reference operator*() const
771 {
772 return *current();
773 }
774
775 /** Call member of current pixel. <br>
776 usage: <TT> iterator->pixelMemberFunction() </TT>
777 */
778 pointer operator->() const
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 */
786 index_reference operator[](Diff2D const & d) const
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()(int dx, int 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[](int 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(int dx, int 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>
848 class ImageIterator
849 : public ImageIteratorBase<ImageIterator<PIXELTYPE>,
850 PIXELTYPE, PIXELTYPE &, PIXELTYPE *>
851 {
852 public:
853 typedef ImageIteratorBase<ImageIterator<PIXELTYPE>,
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, int ystride)
867 : Base(base, ystride)
868 {}
869
870 /** Default constructor */
871 ImageIterator()
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>
893 class ConstImageIterator
894 : public ImageIteratorBase<ConstImageIterator<PIXELTYPE>,
895 PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *>
896 {
897 public:
898 typedef ImageIteratorBase<ConstImageIterator<PIXELTYPE>,
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, int ystride)
912 : Base(base, ystride)
913 {}
914
915 ConstImageIterator(ImageIterator<PIXELTYPE> const & o)
916 : Base(o.x, o.y)
917 {}
918
919 /** Default constructor */
920 ConstImageIterator()
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>
966 class StridedImageIterator
967 : public ImageIteratorBase<StridedImageIterator<PIXELTYPE>,
968 PIXELTYPE, PIXELTYPE &, PIXELTYPE *, StridedArrayTag>
969 {
970 public:
971 typedef ImageIteratorBase<StridedImageIterator<PIXELTYPE>,
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, int ystride, int xskip, int yskip)
982 : Base(base, xskip, ystride*yskip)
983 {}
984
985 /** Default constructor */
986 StridedImageIterator()
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>
1026 class ConstStridedImageIterator
1027 : public ImageIteratorBase<ConstStridedImageIterator<PIXELTYPE>,
1028 PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *,
1029 StridedArrayTag>
1030 {
1031 public:
1032 typedef ImageIteratorBase<ConstStridedImageIterator<PIXELTYPE>,
1033 PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *,
1034 StridedArrayTag> Base;
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, int ystride, int xskip, int yskip)
1044 : Base(base, xskip, ystride*yskip)
1045 {}
1046
1047 /** Copy-construct from mutable iterator */
1048 ConstStridedImageIterator(StridedImageIterator<PIXELTYPE> const & o)
1049 : Base(o.x, o.y)
1050 {}
1051
1052 /** Default constructor */
1053 ConstStridedImageIterator()
1054 : Base()
1055 {}
1056
1057 /** Assign mutable iterator */
1058 ConstStridedImageIterator & operator=(StridedImageIterator<PIXELTYPE> const & o)
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 int 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(), int p = 0)
1236 : value(v), pos(p)
1237 {}
1238
1239 PIXELTYPE value;
1240 int 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>
1289 class ConstValueIterator
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 */
1314 typedef Diff2D difference_type;
1315
1316 /** the iterator tag (image traverser)
1317 */
1318 typedef image_traverser_tag iterator_category;
1319
1320 /** The associated row iterator.
1321 */
1322 typedef IteratorAdaptor<ConstValueIteratorPolicy<PIXELTYPE> > row_iterator;
1323
1324 /** The associated column iterator.
1325 */
1326 typedef IteratorAdaptor<ConstValueIteratorPolicy<PIXELTYPE> > column_iterator;
1327
1328 /** Let operations act in X direction
1329 */
1330 typedef int MoveX;
1331
1332 /** Let operations act in Y direction
1333 */
1334 typedef int MoveY;
1335
1336 /** Default Constructor. (the constant is set to
1337 <TT>NumericTraits<PIXELTYPE>::zero()</TT> )
1338 */
1339 ConstValueIterator()
1340 : value_(NumericTraits<PIXELTYPE>::zero()), x(0), y(0)
1341 {}
1342
1343 /** Construct with given constant.
1344 */
1345 ConstValueIterator(PixelType const & v)
1346 : value_(v), x(0), y(0)
1347 {}
1348
1349 /** Copy Constructor.
1350 */
1351 ConstValueIterator(ConstValueIterator const & v)
1352 : value_(v.value_), x(v.x), y(v.y)
1353 {}
1354
1355 /** Copy Assigment.
1356 */
1357 ConstValueIterator & operator=(ConstValueIterator const & v)
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 */
1370 ConstValueIterator & operator+=(Diff2D const & d)
1371 {
1372 x += d.x;
1373 y += d.y;
1374 return *this;
1375 }
1376
1377 /** Move iterator by specified distance.
1378 */
1379 ConstValueIterator & operator-=(Diff2D const & d)
1380 {
1381 x -= d.x;
1382 y -= d.y;
1383 return *this;
1384 }
1385
1386 /** Create iterator at specified distance.
1387 */
1388 ConstValueIterator operator+(Diff2D const & d) const
1389 {
1390 ConstValueIterator ret(*this);
1391 ret += d;
1392 return ret;
1393 }
1394
1395 /** Create iterator at specified distance.
1396 */
1397 ConstValueIterator operator-(Diff2D const & d) const
1398 {
1399 ConstValueIterator ret(*this);
1400 ret -= d;
1401 return ret;
1402 }
1403
1404 /** Compute distance between two iterators
1405 */
1406 Diff2D operator-(ConstValueIterator const & r) const
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 */
1427 reference operator*() const
1428 {
1429 return value_;
1430 }
1431
1432 /** Call member function for stored constant.
1433 */
1434 pointer operator->() const
1435 {
1436 return &value_;
1437 }
1438
1439 /** Read pixel at a distance (return specified constant).
1440 */
1441 index_reference operator()(int const &, int const &) const
1442 {
1443 return value_;
1444 }
1445
1446 /** Read pixel at a distance (return specified constant).
1447 */
1448 index_reference operator[](Diff2D const &) const
1449 {
1450 return value_;
1451 }
1452
1453 /** Get row iterator at current position (which will also hold the constant).
1454 */
1455 row_iterator rowIterator() const
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 */
1460 column_iterator columnIterator() const
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 int x;
1467 /// refer to y coordinate
1468 int y;
1469 //@}
1470
1471 private:
1472
1473 PixelType value_;
1474 };
1475
1476 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
1477
1478 template <class T>
1479 struct IteratorTraits<ConstValueIterator<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 */
1558 typedef Diff2D CoordinateIterator;
1559
1560 //@}
1561
1562 } // namespace vigra
1563
1564 #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.10.0 (Mon Nov 18 2013)