[ 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
45namespace vigra {
46
47template <class IMAGEITERATOR>
48class 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>
295The 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
358namespace detail {
359
360template <class StridedOrUnstrided>
361class DirectionSelector;
362
363template <>
364class DirectionSelector<UnstridedArrayTag>
365{
366 public:
367
368 template <class T>
369 class type
370 {
371 public:
372 type(T base)
373 : current_(base)
374 {}
375
376 type(type const & rhs)
377 : current_(rhs.current_)
378 {}
379
380 type & operator=(type const & rhs)
381 {
382 current_ = rhs.current_;
383 return *this;
384 }
385
386 void operator++() {++current_;}
387 void operator++(int) {++current_;}
388 void operator--() {--current_;}
389 void operator--(int) {--current_;}
390 void operator+=(std::ptrdiff_t dx) {current_ += dx; }
391 void operator-=(std::ptrdiff_t dx) {current_ -= dx; }
392
393 bool operator==(type const & rhs) const
394 { return current_ == rhs.current_; }
395
396 bool operator!=(type const & rhs) const
397 { return current_ != rhs.current_; }
398
399 bool operator<(type const & rhs) const
400 { return current_ < rhs.current_; }
401
402 bool operator<=(type const & rhs) const
403 { return current_ <= rhs.current_; }
404
405 bool operator>(type const & rhs) const
406 { return current_ > rhs.current_; }
407
408 bool operator>=(type const & rhs) const
409 { return current_ >= rhs.current_; }
410
411 std::ptrdiff_t operator-(type const & rhs) const
412 { return current_ - rhs.current_; }
413
414 T operator()() const
415 { return current_; }
416
417 T operator()(std::ptrdiff_t d) const
418 { return current_ + d; }
419
420 T current_;
421 };
422};
423
424template <>
425class DirectionSelector<StridedArrayTag>
426{
427 public:
428
429 template <class T>
430 class type
431 {
432 public:
433 type(std::ptrdiff_t stride, T base = 0)
434 : stride_(stride),
435 current_(base)
436 {}
437
438 type(type const & rhs)
439 : stride_(rhs.stride_),
440 current_(rhs.current_)
441 {}
442
443 type & operator=(type const & rhs)
444 {
445 stride_ = rhs.stride_;
446 current_ = rhs.current_;
447 return *this;
448 }
449
450 void operator++() {current_ += stride_; }
451 void operator++(int) {current_ += stride_; }
452 void operator--() {current_ -= stride_; }
453 void operator--(int) {current_ -= stride_; }
454 void operator+=(std::ptrdiff_t dy) {current_ += dy*stride_; }
455 void operator-=(std::ptrdiff_t dy) {current_ -= dy*stride_; }
456
457 bool operator==(type const & rhs) const
458 { return (current_ == rhs.current_); }
459
460 bool operator!=(type const & rhs) const
461 { return (current_ != rhs.current_); }
462
463 bool operator<(type const & rhs) const
464 { return (current_ < rhs.current_); }
465
466 bool operator<=(type const & rhs) const
467 { return (current_ <= rhs.current_); }
468
469 bool operator>(type const & rhs) const
470 { return (current_ > rhs.current_); }
471
472 bool operator>=(type const & rhs) const
473 { return (current_ >= rhs.current_); }
474
475 std::ptrdiff_t operator-(type const & rhs) const
476 { return (current_ - rhs.current_) / stride_; }
477
478 T operator()() const
479 { return current_; }
480
481 T operator()(std::ptrdiff_t d) const
482 { return current_ + d*stride_; }
483
484 std::ptrdiff_t stride_;
485 T current_;
486 };
487};
488
489template <class StridedOrUnstrided>
490class LinearIteratorSelector;
491
492template <>
493class 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
510template <>
511class 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*/
560template <class IMAGEITERATOR,
561 class PIXELTYPE, class REFERENCE, class POINTER,
562 class StridedOrUnstrided = UnstridedArrayTag>
564{
565 typedef typename
566 vigra::detail::LinearIteratorSelector<StridedOrUnstrided>::template type<ImageIteratorBase>
567 RowIteratorSelector;
568 typedef typename
569 vigra::detail::LinearIteratorSelector<StridedArrayTag>::template type<ImageIteratorBase>
570 ColumnIteratorSelector;
571 public:
572 typedef ImageIteratorBase<IMAGEITERATOR,
574
575 /** The underlying image's pixel type.
576 */
578
579 /** deprecated, use <TT>value_type</TT> instead.
580 */
582
583 /** the iterator's reference type (return type of <TT>*iter</TT>)
584 */
586
587 /** the iterator's index reference type (return type of <TT>iter[diff]</TT>)
588 */
590
591 /** the iterator's pointer type (return type of <TT>iter.operator->()</TT>)
592 */
594
595 /** the iterator's difference type (argument type of <TT>iter[diff]</TT>)
596 */
598
599 /** the iterator tag (image traverser)
600 */
601 typedef image_traverser_tag iterator_category;
602
603 /** The associated row iterator.
604 */
605 typedef typename RowIteratorSelector::res row_iterator;
606
607 /** The associated column iterator.
608 */
609 typedef typename ColumnIteratorSelector::res column_iterator;
610
611 /** Let operations act in X direction
612 */
613 typedef typename
614 vigra::detail::DirectionSelector<StridedOrUnstrided>::template type<pointer> MoveX;
615
616 /** Let operations act in Y direction
617 */
618 typedef typename
619 vigra::detail::DirectionSelector<StridedArrayTag>::template type<std::ptrdiff_t> MoveY;
620
621 /** @name Comparison of Iterators */
622 //@{
623 /** usage: <TT> iterator == iterator1 </TT>
624 */
625 bool operator==(ImageIteratorBase const & rhs) const
626 {
627 return (x == rhs.x) && (y == rhs.y);
628 }
629
630 /** usage: <TT> iterator != iterator1 </TT>
631 */
632 bool operator!=(ImageIteratorBase const & rhs) const
633 {
634 return (x != rhs.x) || (y != rhs.y);
635 }
636
637 /** usage: <TT> Diff2D dist = iterator - iterator1 </TT>
638 */
640 {
641 return difference_type(x - rhs.x, y - rhs.y);
642 }
643
644 //@}
645
646 /** @name Specify coordinate to operate on */
647 //@{
648 /** Refer to iterator's x coordinate.
649 Usage examples:<br>
650 \code
651 ++iterator.x; // move one step to the right
652 --iterator.x; // move one step to the left
653 iterator.x += dx; // move dx steps to the right
654 iterator.x -= dx; // move dx steps to the left
655 bool notAtEndOfRow = iterator.x < lowerRight.x; // compare x coordinates of two iterators
656 int width = lowerRight.x - upperLeft.x; // calculate difference of x coordinates
657 // between two iterators
658 \endcode
659 */
661 /** Refer to iterator's y coordinate.
662 Usage examples:<br>
663 \code
664 ++iterator.y; // move one step down
665 --iterator.y; // move one step up
666 iterator.y += dy; // move dy steps down
667 iterator.y -= dy; // move dy steps up
668 bool notAtEndOfColumn = iterator.y < lowerRight.y; // compare y coordinates of two iterators
669 int height = lowerRight.y - upperLeft.y; // calculate difference of y coordinates
670 // between two iterators
671 \endcode
672 */
674 //@}
675
676 protected:
677 /** Construct from raw memory with a vertical stride of <TT>ystride</TT>.
678 <TT>ystride</TT> must equal the physical image width (row length),
679 even if the iterator will only be used for a sub image. This constructor
680 must only be called for unstrided iterators
681 (<tt>StridedOrUnstrided == UnstridedArrayTag</tt>)
682 */
683 ImageIteratorBase(pointer base, std::ptrdiff_t ystride)
684 : x(base),
685 y(ystride)
686 {}
687
688 /** Construct from raw memory with a horizontal stride of <TT>xstride</TT>
689 and a vertical stride of <TT>ystride</TT>. This constructor
690 may be used for iterators that shall skip pixels. Thus, it
691 must only be called for strided iterators
692 (<tt>StridedOrUnstrided == StridedArrayTag</tt>)
693 */
694 ImageIteratorBase(pointer base, std::ptrdiff_t xstride, std::ptrdiff_t ystride)
695 : x(xstride, base),
696 y(ystride)
697 {}
698
699 /** Copy constructor */
701 : x(rhs.x),
702 y(rhs.y)
703 {}
704
705 /** Default constructor */
707 : x(0),
708 y(0)
709 {}
710
711 /** Copy assignment */
713 {
714 if(this != &rhs)
715 {
716 x = rhs.x;
717 y = rhs.y;
718 }
719 return *this;
720 }
721
722 public:
723 /** @name Random navigation */
724 //@{
725 /** Add offset via Diff2D
726 */
727 IMAGEITERATOR & operator+=(difference_type const & s)
728 {
729 x += s.x;
730 y += s.y;
731 return static_cast<IMAGEITERATOR &>(*this);
732 }
733 /** Subtract offset via Diff2D
734 */
735 IMAGEITERATOR & operator-=(difference_type const & s)
736 {
737 x -= s.x;
738 y -= s.y;
739 return static_cast<IMAGEITERATOR &>(*this);
740 }
741
742 /** Add a distance
743 */
744 IMAGEITERATOR operator+(difference_type const & s) const
745 {
746 IMAGEITERATOR ret(static_cast<IMAGEITERATOR const &>(*this));
747
748 ret += s;
749
750 return ret;
751 }
752
753 /** Subtract a distance
754 */
755 IMAGEITERATOR operator-(difference_type const & s) const
756 {
757 IMAGEITERATOR ret(static_cast<IMAGEITERATOR const &>(*this));
758
759 ret -= s;
760
761 return ret;
762 }
763 //@}
764
765 /** @name Access the Pixels */
766 //@{
767 /** Access current pixel. <br>
768 usage: <TT> SomePixelType value = *iterator </TT>
769 */
771 {
772 return *current();
773 }
774
775 /** Call member of current pixel. <br>
776 usage: <TT> iterator->pixelMemberFunction() </TT>
777 */
779 {
780 return current();
781 }
782
783 /** Access pixel at offset from current location. <br>
784 usage: <TT> SomePixelType value = iterator[Diff2D(1,1)] </TT>
785 */
787 {
788 return *current(d.x, d.y);
789 }
790
791 /** Access pixel at offset (dx, dy) from current location. <br>
792 usage: <TT> SomePixelType value = iterator(dx, dy) </TT>
793 */
794 index_reference operator()(std::ptrdiff_t dx, std::ptrdiff_t dy) const
795 {
796 return *current(dx, dy);
797 }
798
799 /** Read pixel with offset [dy][dx] from current pixel.
800 Note that the 'x' index is the trailing index. <br>
801 usage: <TT> SomePixelType value = iterator[dy][dx] </TT>
802 */
803 pointer operator[](std::ptrdiff_t dy) const
804 {
805 return x() + y(dy);
806 }
807 //@}
808
809 row_iterator rowIterator() const
810 {
811 return RowIteratorSelector::construct(current(), x);
812 }
813
814 column_iterator columnIterator() const
815 {
816 return ColumnIteratorSelector::construct(current(), y);
817 }
818
819 private:
820
821 pointer current() const
822 { return x() + y(); }
823
824 pointer current(std::ptrdiff_t dx, std::ptrdiff_t dy) const
825 { return x(dx) + y(dy); }
826};
827
828/********************************************************/
829/* */
830/* ImageIterator */
831/* */
832/********************************************************/
833
834/** \brief Standard 2D random access iterator for images that store the
835 data in a linear array.
836
837 Most functions and local types are inherited from ImageIteratorBase.
838
839 See the paper: U. Koethe:
840 <a href="http://hci.iwr.uni-heidelberg.de/vigra/documents/GenericProg2D.ps">Reusable Algorithms in Image Processing</a>
841 for a discussion of the concepts behind ImageIterators.
842
843 <b>\#include</b> <vigra/imageiterator.hxx> <br/>
844 Namespace: vigra
845
846*/
847template <class PIXELTYPE>
849: public ImageIteratorBase<ImageIterator<PIXELTYPE>,
850 PIXELTYPE, PIXELTYPE &, PIXELTYPE *>
851{
852 public:
855
856 typedef typename Base::pointer pointer;
857 typedef typename Base::difference_type difference_type;
858
859 /** Construct from raw memory with a vertical stride of <TT>ystride</TT>.
860 <TT>ystride</TT> must equal the physical image width (row length),
861 even if the iterator will only be used for a sub image.
862 If the raw memory is encapsulated in an image object this
863 object should have a factory function that constructs the
864 iterator.
865 */
866 ImageIterator(pointer base, std::ptrdiff_t ystride)
867 : Base(base, ystride)
868 {}
869
870 /** Default constructor */
872 : Base()
873 {}
874
875};
876
877/********************************************************/
878/* */
879/* ConstImageIterator */
880/* */
881/********************************************************/
882
883/** \brief Standard 2D random access const iterator for images that
884 store the data as a linear array.
885
886 Most functions are inherited from ImageIteratorBase.
887
888 <b>\#include</b> <vigra/imageiterator.hxx> <br/>
889 Namespace: vigra
890
891*/
892template <class PIXELTYPE>
894: public ImageIteratorBase<ConstImageIterator<PIXELTYPE>,
895 PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *>
896{
897 public:
899 PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *> Base;
900
901 typedef typename Base::pointer pointer;
902 typedef typename Base::difference_type difference_type;
903
904 /** Construct from raw memory with a vertical stride of <TT>ystride</TT>.
905 <TT>ystride</TT> must equal the physical image width (row length),
906 even if the iterator will only be used for a sub image.
907 If the raw memory is encapsulated in an image object this
908 object should have a factory function that constructs the
909 iterator.
910 */
911 ConstImageIterator(pointer base, std::ptrdiff_t ystride)
912 : Base(base, ystride)
913 {}
914
916 : Base(o.x, o.y)
917 {}
918
919 /** Default constructor */
921 : Base()
922 {}
923
924 ConstImageIterator & operator=(ImageIterator<PIXELTYPE> const & o)
925 {
926 Base::x = o.x;
927 Base::y = o.y;
928 return *this;
929 }
930};
931
932/********************************************************/
933/* */
934/* StridedImageIterator */
935/* */
936/********************************************************/
937
938/** \brief Iterator to be used when pixels are to be skipped.
939
940 This iterator can be used when some pixels shall be automatically skipped, for example
941 if an image is to be sub-sampled: instead of advancing to the next pixel,
942 <tt>++iterator.x</tt> jumps to the pixel at a horizontal offset of <tt>xskip</tt>.
943 Likewise with <tt>yskip</tt> in vertical direction. Most functions and local types
944 are inherited from ImageIteratorBase.
945
946 <b> Usage:</b>
947
948 \code
949 BImage img(w,h);
950 ...
951 int xskip = 2, yskip = 2;
952 int wskip = w / xskip + 1, hskip = h / yskip + 1;
953
954 StridedImageIterator<BImage::value_type> upperLeft(&img(0,0), w, xskip, yskip);
955 StridedImageIterator<BImage::value_type> lowerRight = upperLeft + Diff2D(wskip, hskip);
956
957 // now navigation with upperLeft and lowerRight lets the image appear to have half
958 // the original resolution in either dimension
959 \endcode
960
961 <b>\#include</b> <vigra/imageiterator.hxx> <br/>
962 Namespace: vigra
963
964*/
965template <class PIXELTYPE>
967: public ImageIteratorBase<StridedImageIterator<PIXELTYPE>,
968 PIXELTYPE, PIXELTYPE &, PIXELTYPE *, StridedArrayTag>
969{
970 public:
973
974 typedef typename Base::pointer pointer;
975 typedef typename Base::difference_type difference_type;
976
977 /** Construct from raw memory with a vertical stride of <TT>ystride</TT>,
978 jumping by <tt>xskip</tt> horizontally and <tt>yskip</tt> vertically.
979 <tt>ystride</tt> must be the physical width (row length) of the image.
980 */
981 StridedImageIterator(pointer base, std::ptrdiff_t ystride, std::ptrdiff_t xskip, std::ptrdiff_t yskip)
982 : Base(base, xskip, ystride*yskip)
983 {}
984
985 /** Default constructor */
987 : Base()
988 {}
989
990};
991
992/********************************************************/
993/* */
994/* ConstStridedImageIterator */
995/* */
996/********************************************************/
997
998/** \brief Const iterator to be used when pixels are to be skipped.
999
1000 This iterator can be used when some pixels shall be automatically skipped, for example
1001 if an image is to be sub-sampled: instead of advancing to the next pixel,
1002 <tt>++iterator.x</tt> jumps to the pixel at a horizontal offset of <tt>xskip</tt>.
1003 Likewise with <tt>yskip</tt> in vertical direction. Most functions and local types
1004 are inherited from ImageIteratorBase.
1005
1006 <b> Usage:</b>
1007
1008 \code
1009 BImage img(w,h);
1010 ...
1011 int xskip = 2, yskip = 2;
1012 int wskip = w / xskip + 1, hskip = h / yskip + 1;
1013
1014 ConstStridedImageIterator<BImage::value_type> upperLeft(&img(0,0), w, xskip, yskip);
1015 ConstStridedImageIterator<BImage::value_type> lowerRight = upperLeft + Diff2D(wskip, hskip);
1016
1017 // now navigation with upperLeft and lowerRight lets the image appear to have half
1018 // the original resolution in either dimension
1019 \endcode
1020
1021 <b>\#include</b> <vigra/imageiterator.hxx> <br/>
1022 Namespace: vigra
1023
1024*/
1025template <class PIXELTYPE>
1027: public ImageIteratorBase<ConstStridedImageIterator<PIXELTYPE>,
1028 PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *,
1029 StridedArrayTag>
1030{
1031 public:
1033 PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *,
1035
1036 typedef typename Base::pointer pointer;
1037 typedef typename Base::difference_type difference_type;
1038
1039 /** Construct from raw memory with a vertical stride of <TT>ystride</TT>,
1040 jumping by <tt>xskip</tt> horizontally and <tt>yskip</tt> vertically.
1041 <tt>ystride</tt> must be the physical width (row length) of the image.
1042 */
1043 ConstStridedImageIterator(pointer base, std::ptrdiff_t ystride, std::ptrdiff_t xskip, std::ptrdiff_t yskip)
1044 : Base(base, xskip, ystride*yskip)
1045 {}
1046
1047 /** Copy-construct from mutable iterator */
1051
1052 /** Default constructor */
1056
1057 /** Assign mutable iterator */
1059 {
1060 Base::x = o.x;
1061 Base::y = o.y;
1062 return *this;
1063 }
1064};
1065
1066/********************************************************/
1067/* */
1068/* definition of iterator traits */
1069/* */
1070/********************************************************/
1071
1072
1073#ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
1074
1075template <class T>
1076struct 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
1086template <class T>
1087struct 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
1097template <class T>
1098struct 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
1108template <class T>
1109struct 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
1165VIGRA_DEFINE_ITERATORTRAITS(RGBValue<unsigned char>)
1166VIGRA_DEFINE_ITERATORTRAITS(RGBValue<short>)
1167VIGRA_DEFINE_ITERATORTRAITS(RGBValue<int>)
1168VIGRA_DEFINE_ITERATORTRAITS(RGBValue<float>)
1169VIGRA_DEFINE_ITERATORTRAITS(RGBValue<double>)
1170
1171#define VIGRA_PIXELTYPE TinyVector<unsigned char, 2>
1172VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1173#undef VIGRA_PIXELTYPE
1174#define VIGRA_PIXELTYPE TinyVector<unsigned char, 3>
1175VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1176#undef VIGRA_PIXELTYPE
1177#define VIGRA_PIXELTYPE TinyVector<unsigned char, 4>
1178VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1179#undef VIGRA_PIXELTYPE
1180#define VIGRA_PIXELTYPE TinyVector<short, 2>
1181VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1182#undef VIGRA_PIXELTYPE
1183#define VIGRA_PIXELTYPE TinyVector<short, 3>
1184VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1185#undef VIGRA_PIXELTYPE
1186#define VIGRA_PIXELTYPE TinyVector<short, 4>
1187VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1188#undef VIGRA_PIXELTYPE
1189#define VIGRA_PIXELTYPE TinyVector<int, 2>
1190VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1191#undef VIGRA_PIXELTYPE
1192#define VIGRA_PIXELTYPE TinyVector<int, 3>
1193VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1194#undef VIGRA_PIXELTYPE
1195#define VIGRA_PIXELTYPE TinyVector<int, 4>
1196VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1197#undef VIGRA_PIXELTYPE
1198#define VIGRA_PIXELTYPE TinyVector<float, 2>
1199VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1200#undef VIGRA_PIXELTYPE
1201#define VIGRA_PIXELTYPE TinyVector<float, 3>
1202VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1203#undef VIGRA_PIXELTYPE
1204#define VIGRA_PIXELTYPE TinyVector<float, 4>
1205VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1206#undef VIGRA_PIXELTYPE
1207#define VIGRA_PIXELTYPE TinyVector<double, 2>
1208VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1209#undef VIGRA_PIXELTYPE
1210#define VIGRA_PIXELTYPE TinyVector<double, 3>
1211VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1212#undef VIGRA_PIXELTYPE
1213#define VIGRA_PIXELTYPE TinyVector<double, 4>
1214VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
1215#undef VIGRA_PIXELTYPE
1216
1217#undef VIGRA_DEFINE_ITERATORTRAITS
1218
1219#endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
1220
1221template <class PIXELTYPE>
1222class ConstValueIteratorPolicy
1223{
1224 public:
1225
1226 typedef PIXELTYPE value_type;
1227 typedef std::ptrdiff_t difference_type;
1228 typedef PIXELTYPE const & reference;
1229 typedef PIXELTYPE const & index_reference;
1230 typedef PIXELTYPE const * pointer;
1231 typedef std::random_access_iterator_tag iterator_category;
1232
1233 struct BaseType
1234 {
1235 BaseType(PIXELTYPE const & v = PIXELTYPE(), std::ptrdiff_t p = 0)
1236 : value(v), pos(p)
1237 {}
1238
1239 PIXELTYPE value;
1240 std::ptrdiff_t pos;
1241 };
1242
1243 static void initialize(BaseType & /* d */) {}
1244
1245 static reference dereference(BaseType const & d)
1246 { return d.value; }
1247
1248 static index_reference dereference(BaseType d, difference_type)
1249 {
1250 return d.value;
1251 }
1252
1253 static bool equal(BaseType const & d1, BaseType const & d2)
1254 { return d1.pos == d2.pos; }
1255
1256 static bool less(BaseType const & d1, BaseType const & d2)
1257 { return d1.pos < d2.pos; }
1258
1259 static difference_type difference(BaseType const & d1, BaseType const & d2)
1260 { return d1.pos - d2.pos; }
1261
1262 static void increment(BaseType & d)
1263 { ++d.pos; }
1264
1265 static void decrement(BaseType & d)
1266 { --d.pos; }
1267
1268 static void advance(BaseType & d, difference_type n)
1269 { d.pos += n; }
1270};
1271
1272/********************************************************/
1273/* */
1274/* ConstValueIterator */
1275/* */
1276/********************************************************/
1277
1278/** \brief Iterator that always returns the constant specified in the
1279 constructor.
1280
1281 This iterator can be used to simulate an image that
1282 does not actually exist.
1283
1284 <b>\#include</b> <vigra/imageiterator.hxx> <br/>
1285 Namespace: vigra
1286
1287*/
1288template <class PIXELTYPE>
1290{
1291 public:
1292 /** The type of the constant the iterator holds.
1293 */
1295
1296 /** The type of the constant the iterator holds.
1297 */
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 */
1307
1308 /** the iterator's pointer type (return type of <TT>iter.operator->()</TT>)
1309 */
1310 typedef PIXELTYPE const * pointer;
1311
1312 /** the iterator's difference type (argument type of <TT>iter[diff]</TT>)
1313 */
1315
1316 /** the iterator tag (image traverser)
1317 */
1318 typedef image_traverser_tag iterator_category;
1319
1320 /** The associated row iterator.
1321 */
1323
1324 /** The associated column iterator.
1325 */
1327
1328 /** Let operations act in X direction
1329 */
1330 typedef std::ptrdiff_t MoveX;
1331
1332 /** Let operations act in Y direction
1333 */
1334 typedef std::ptrdiff_t MoveY;
1335
1336 /** Default Constructor. (the constant is set to
1337 <TT>NumericTraits<PIXELTYPE>::zero()</TT> )
1338 */
1340 : value_(NumericTraits<PIXELTYPE>::zero()), x(0), y(0)
1341 {}
1342
1343 /** Construct with given constant.
1344 */
1346 : value_(v), x(0), y(0)
1347 {}
1348
1349 /** Copy Constructor.
1350 */
1352 : value_(v.value_), x(v.x), y(v.y)
1353 {}
1354
1355 /** Copy Assigment.
1356 */
1358 {
1359 if(this != &v)
1360 {
1361 value_ = v.value_;
1362 x = v.x;
1363 y = v.y;
1364 }
1365 return *this;
1366 }
1367
1368 /** Move iterator by specified distance.
1369 */
1371 {
1372 x += d.x;
1373 y += d.y;
1374 return *this;
1375 }
1376
1377 /** Move iterator by specified distance.
1378 */
1380 {
1381 x -= d.x;
1382 y -= d.y;
1383 return *this;
1384 }
1385
1386 /** Create iterator at specified distance.
1387 */
1389 {
1390 ConstValueIterator ret(*this);
1391 ret += d;
1392 return ret;
1393 }
1394
1395 /** Create iterator at specified distance.
1396 */
1398 {
1399 ConstValueIterator ret(*this);
1400 ret -= d;
1401 return ret;
1402 }
1403
1404 /** Compute distance between two iterators
1405 */
1407 {
1408 return Diff2D(x - r.x, y - r.y);
1409 }
1410
1411 /** Equality.
1412 */
1413 bool operator==(ConstValueIterator const & r) const
1414 {
1415 return (x == r.x) && (y == r.y);
1416 }
1417
1418 /** Inequality.
1419 */
1420 bool operator!=(ConstValueIterator const & r) const
1421 {
1422 return (x != r.x) || (y != r.y);
1423 }
1424
1425 /** Read current pixel (return specified constant).
1426 */
1428 {
1429 return value_;
1430 }
1431
1432 /** Call member function for stored constant.
1433 */
1435 {
1436 return &value_;
1437 }
1438
1439 /** Read pixel at a distance (return specified constant).
1440 */
1441 index_reference operator()(std::ptrdiff_t const &, std::ptrdiff_t const &) const
1442 {
1443 return value_;
1444 }
1445
1446 /** Read pixel at a distance (return specified constant).
1447 */
1449 {
1450 return value_;
1451 }
1452
1453 /** Get row iterator at current position (which will also hold the constant).
1454 */
1456 { return row_iterator(typename row_iterator::BaseType(value_, x)); }
1457
1458 /** Get column iterator at current position (which will also hold the constant).
1459 */
1461 { return column_iterator(typename column_iterator::BaseType(value_, y)); }
1462
1463 /** @name Specify coordinate direction for navigation commands */
1464 //@{
1465 /// refer to x coordinate
1466 std::ptrdiff_t x;
1467 /// refer to y coordinate
1468 std::ptrdiff_t y;
1469 //@}
1470
1471 private:
1472
1473 PixelType value_;
1474};
1475
1476#ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
1477
1478template <class T>
1480{
1481 typedef ConstValueIterator<T> Iterator;
1482 typedef Iterator iterator;
1483 typedef typename iterator::iterator_category iterator_category;
1484 typedef typename iterator::value_type value_type;
1485 typedef typename iterator::reference reference;
1486 typedef typename iterator::index_reference index_reference;
1487 typedef typename iterator::pointer pointer;
1488 typedef typename iterator::difference_type difference_type;
1489 typedef typename iterator::row_iterator row_iterator;
1490 typedef typename iterator::column_iterator column_iterator;
1491 typedef StandardConstAccessor<T> DefaultAccessor;
1492 typedef StandardConstAccessor<T> default_accessor;
1493 typedef VigraTrueType hasConstantStrides;
1494};
1495
1496#endif
1497
1498/** \brief Simulate an image where each pixel contains its coordinate.
1499
1500 CoordinateIterator used to be a separate class,
1501 but has now become an alias for \ref vigra::Diff2D. This is possible because
1502 Diff2D now provides all the necessary functionality.
1503
1504 CoordinateIterator behaves like a read-only \ref vigra::ImageIterator for
1505 an image in which each pixel contains its coordinate. This is useful for
1506 algorithms that need access to the current pixel's location.
1507 For example, you can use CoordinateIterator/Diff2D to
1508 find the center of mass of an image region. To implement this,
1509 we first need a functor for center-of-mass calculations:
1510
1511 \code
1512
1513 struct CenterOfMassFunctor
1514 {
1515 CenterOfMassFunctor()
1516 : x(0.0), y(0.0), size(0)
1517 {}
1518
1519 void operator()(Diff2d const& diff)
1520 {
1521 ++size;
1522 x += diff.x;
1523 y += diff.y;
1524 }
1525
1526 float xCenter() const
1527 { return x / size; }
1528
1529 float yCenter() const
1530 { return y / size; }
1531
1532 float x;
1533 float y;
1534 int size;
1535 };
1536 \endcode
1537
1538 Using this functor, we find the center of mass like so:
1539
1540 \code
1541 vigra::BImage img(w,h);
1542 ... // mark a region in the image with '1', background with '0'
1543
1544 CenterOfMassFunctor center;
1545
1546 vigra::inspectImageIf(
1547 srcIterRange(Diff2D(), Diff2D() + img.size()),
1548 srcImage(img),
1549 center);
1550
1551 std::cout << "Center of mass: " << center.xCenter() <<
1552 ", " << center.yCenter() << std::endl;
1553 \endcode
1554
1555 <b>\#include</b> <vigra/imageiterator.hxx> <br/>
1556 Namespace: vigra
1557*/
1559
1560//@}
1561
1562} // namespace vigra
1563
1564#endif // VIGRA_IMAGEITERATOR_HXX
Standard 2D random access const iterator for images that store the data as a linear array.
Definition imageiterator.hxx:896
ConstImageIterator(pointer base, std::ptrdiff_t ystride)
Definition imageiterator.hxx:911
ConstImageIterator()
Definition imageiterator.hxx:920
Const iterator to be used when pixels are to be skipped.
Definition imageiterator.hxx:1030
ConstStridedImageIterator(pointer base, std::ptrdiff_t ystride, std::ptrdiff_t xskip, std::ptrdiff_t yskip)
Definition imageiterator.hxx:1043
ConstStridedImageIterator()
Definition imageiterator.hxx:1053
ConstStridedImageIterator & operator=(StridedImageIterator< PIXELTYPE > const &o)
Definition imageiterator.hxx:1058
ConstStridedImageIterator(StridedImageIterator< PIXELTYPE > const &o)
Definition imageiterator.hxx:1048
Iterator that always returns the constant specified in the constructor.
Definition imageiterator.hxx:1290
ConstValueIterator operator+(Diff2D const &d) const
Definition imageiterator.hxx:1388
ConstValueIterator(ConstValueIterator const &v)
Definition imageiterator.hxx:1351
index_reference operator[](Diff2D const &) const
Definition imageiterator.hxx:1448
PIXELTYPE const & index_reference
Definition imageiterator.hxx:1306
index_reference operator()(std::ptrdiff_t const &, std::ptrdiff_t const &) const
Definition imageiterator.hxx:1441
PIXELTYPE const & reference
Definition imageiterator.hxx:1302
ConstValueIterator & operator=(ConstValueIterator const &v)
Definition imageiterator.hxx:1357
std::ptrdiff_t x
refer to x coordinate
Definition imageiterator.hxx:1466
std::ptrdiff_t MoveY
Definition imageiterator.hxx:1334
PIXELTYPE const * pointer
Definition imageiterator.hxx:1310
bool operator!=(ConstValueIterator const &r) const
Definition imageiterator.hxx:1420
row_iterator rowIterator() const
Definition imageiterator.hxx:1455
IteratorAdaptor< ConstValueIteratorPolicy< PIXELTYPE > > column_iterator
Definition imageiterator.hxx:1326
IteratorAdaptor< ConstValueIteratorPolicy< PIXELTYPE > > row_iterator
Definition imageiterator.hxx:1322
image_traverser_tag iterator_category
Definition imageiterator.hxx:1318
ConstValueIterator & operator+=(Diff2D const &d)
Definition imageiterator.hxx:1370
std::ptrdiff_t MoveX
Definition imageiterator.hxx:1330
ConstValueIterator operator-(Diff2D const &d) const
Definition imageiterator.hxx:1397
reference operator*() const
Definition imageiterator.hxx:1427
ConstValueIterator()
Definition imageiterator.hxx:1339
PIXELTYPE PixelType
Definition imageiterator.hxx:1298
std::ptrdiff_t y
refer to y coordinate
Definition imageiterator.hxx:1468
bool operator==(ConstValueIterator const &r) const
Definition imageiterator.hxx:1413
PIXELTYPE value_type
Definition imageiterator.hxx:1294
ConstValueIterator(PixelType const &v)
Definition imageiterator.hxx:1345
Diff2D operator-(ConstValueIterator const &r) const
Definition imageiterator.hxx:1406
column_iterator columnIterator() const
Definition imageiterator.hxx:1460
pointer operator->() const
Definition imageiterator.hxx:1434
ConstValueIterator & operator-=(Diff2D const &d)
Definition imageiterator.hxx:1379
Diff2D difference_type
Definition imageiterator.hxx:1314
Two dimensional difference vector.
Definition diff2d.hxx:186
int y
Definition diff2d.hxx:392
int x
Definition diff2d.hxx:385
Base class for 2D random access iterators.
Definition imageiterator.hxx:564
ImageIteratorBase(pointer base, std::ptrdiff_t xstride, std::ptrdiff_t ystride)
Definition imageiterator.hxx:694
difference_type operator-(ImageIteratorBase const &rhs) const
Definition imageiterator.hxx:639
vigra::detail::DirectionSelector< StridedArrayTag >::template type< std::ptrdiff_t > MoveY
Definition imageiterator.hxx:619
bool operator!=(ImageIteratorBase const &rhs) const
Definition imageiterator.hxx:632
ImageIteratorBase & operator=(ImageIteratorBase const &rhs)
Definition imageiterator.hxx:712
IMAGEITERATOR operator+(difference_type const &s) const
Definition imageiterator.hxx:744
ImageIteratorBase(ImageIteratorBase const &rhs)
Definition imageiterator.hxx:700
IMAGEITERATOR & operator+=(difference_type const &s)
Definition imageiterator.hxx:727
IMAGEITERATOR & operator-=(difference_type const &s)
Definition imageiterator.hxx:735
pointer operator[](std::ptrdiff_t dy) const
Definition imageiterator.hxx:803
RowIteratorSelector::res row_iterator
Definition imageiterator.hxx:605
index_reference operator[](Diff2D const &d) const
Definition imageiterator.hxx:786
MoveX x
Definition imageiterator.hxx:660
vigra::detail::DirectionSelector< StridedOrUnstrided >::template type< pointer > MoveX
Definition imageiterator.hxx:614
index_reference operator()(std::ptrdiff_t dx, std::ptrdiff_t dy) const
Definition imageiterator.hxx:794
image_traverser_tag iterator_category
Definition imageiterator.hxx:601
ImageIteratorBase(pointer base, std::ptrdiff_t ystride)
Definition imageiterator.hxx:683
ColumnIteratorSelector::res column_iterator
Definition imageiterator.hxx:609
REFERENCE reference
Definition imageiterator.hxx:585
reference operator*() const
Definition imageiterator.hxx:770
MoveY y
Definition imageiterator.hxx:673
ImageIteratorBase()
Definition imageiterator.hxx:706
IMAGEITERATOR operator-(difference_type const &s) const
Definition imageiterator.hxx:755
PIXELTYPE PixelType
Definition imageiterator.hxx:581
PIXELTYPE value_type
Definition imageiterator.hxx:577
pointer operator->() const
Definition imageiterator.hxx:778
REFERENCE index_reference
Definition imageiterator.hxx:589
Diff2D difference_type
Definition imageiterator.hxx:597
POINTER pointer
Definition imageiterator.hxx:593
bool operator==(ImageIteratorBase const &rhs) const
Definition imageiterator.hxx:625
Standard 2D random access iterator for images that store the data in a linear array.
Definition imageiterator.hxx:851
ImageIterator(pointer base, std::ptrdiff_t ystride)
Definition imageiterator.hxx:866
ImageIterator()
Definition imageiterator.hxx:871
Class for a single RGB value.
Definition rgbvalue.hxx:128
Iterator to be used when pixels are to be skipped.
Definition imageiterator.hxx:969
StridedImageIterator(pointer base, std::ptrdiff_t ystride, std::ptrdiff_t xskip, std::ptrdiff_t yskip)
Definition imageiterator.hxx:981
StridedImageIterator()
Definition imageiterator.hxx:986
Diff2D CoordinateIterator
Simulate an image where each pixel contains its coordinate.
Definition imageiterator.hxx:1558
bool operator<=(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r)
less or equal
Definition fixedpoint.hxx:521
bool operator>=(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r)
greater or equal
Definition fixedpoint.hxx:539
FFTWComplex< R > & operator+=(FFTWComplex< R > &a, const FFTWComplex< R > &b)
add-assignment
Definition fftw3.hxx:859
FFTWComplex< R > & operator-=(FFTWComplex< R > &a, const FFTWComplex< R > &b)
subtract-assignment
Definition fftw3.hxx:867
bool operator>(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r)
greater
Definition fixedpoint.hxx:530
bool operator<(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r)
less than
Definition fixedpoint.hxx:512
Export associated information for each image iterator.
Definition iteratortraits.hxx:110
Definition metaprogramming.hxx:116

© 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.12.1