[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]
00001 /************************************************************************/ 00002 /* */ 00003 /* Copyright 1998-2002 by Ullrich Koethe */ 00004 /* Cognitive Systems Group, University of Hamburg, Germany */ 00005 /* */ 00006 /* This file is part of the VIGRA computer vision library. */ 00007 /* The VIGRA Website is */ 00008 /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ 00009 /* Please direct questions, bug reports, and contributions to */ 00010 /* ullrich.koethe@iwr.uni-heidelberg.de or */ 00011 /* vigra@informatik.uni-hamburg.de */ 00012 /* */ 00013 /* Permission is hereby granted, free of charge, to any person */ 00014 /* obtaining a copy of this software and associated documentation */ 00015 /* files (the "Software"), to deal in the Software without */ 00016 /* restriction, including without limitation the rights to use, */ 00017 /* copy, modify, merge, publish, distribute, sublicense, and/or */ 00018 /* sell copies of the Software, and to permit persons to whom the */ 00019 /* Software is furnished to do so, subject to the following */ 00020 /* conditions: */ 00021 /* */ 00022 /* The above copyright notice and this permission notice shall be */ 00023 /* included in all copies or substantial portions of the */ 00024 /* Software. */ 00025 /* */ 00026 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */ 00027 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */ 00028 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */ 00029 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */ 00030 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */ 00031 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */ 00032 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */ 00033 /* OTHER DEALINGS IN THE SOFTWARE. */ 00034 /* */ 00035 /************************************************************************/ 00036 00037 00038 #ifndef VIGRA_IMAGEITERATOR_HXX 00039 #define VIGRA_IMAGEITERATOR_HXX 00040 00041 #include "utilities.hxx" 00042 #include "accessor.hxx" 00043 #include "iteratortraits.hxx" 00044 #include "metaprogramming.hxx" 00045 00046 namespace vigra { 00047 00048 template <class IMAGEITERATOR> 00049 class StridedIteratorPolicy 00050 { 00051 public: 00052 typedef IMAGEITERATOR ImageIterator; 00053 typedef typename IMAGEITERATOR::value_type value_type; 00054 typedef typename IMAGEITERATOR::difference_type::MoveY 00055 difference_type; 00056 typedef typename IMAGEITERATOR::reference reference; 00057 typedef typename IMAGEITERATOR::index_reference index_reference; 00058 typedef typename IMAGEITERATOR::pointer pointer; 00059 typedef std::random_access_iterator_tag iterator_category; 00060 00061 00062 struct BaseType 00063 { 00064 explicit BaseType(pointer c = 0, difference_type stride = 0) 00065 : current_(c), stride_(stride) 00066 {} 00067 00068 pointer current_; 00069 difference_type stride_; 00070 }; 00071 00072 static void initialize(BaseType & /* d */) {} 00073 00074 static reference dereference(BaseType const & d) 00075 { return const_cast<reference>(*d.current_); } 00076 00077 static index_reference dereference(BaseType const & d, difference_type n) 00078 { 00079 return const_cast<index_reference>(d.current_[n*d.stride_]); 00080 } 00081 00082 static bool equal(BaseType const & d1, BaseType const & d2) 00083 { return d1.current_ == d2.current_; } 00084 00085 static bool less(BaseType const & d1, BaseType const & d2) 00086 { return d1.current_ < d2.current_; } 00087 00088 static difference_type difference(BaseType const & d1, BaseType const & d2) 00089 { return (d1.current_ - d2.current_) / d1.stride_; } 00090 00091 static void increment(BaseType & d) 00092 { d.current_ += d.stride_; } 00093 00094 static void decrement(BaseType & d) 00095 { d.current_ -= d.stride_; } 00096 00097 static void advance(BaseType & d, difference_type n) 00098 { d.current_ += d.stride_*n; } 00099 }; 00100 00101 /** \addtogroup ImageIterators Image Iterators 00102 00103 \brief General image iterator definition and implementations. 00104 00105 <p> 00106 The following tables describe the general requirements for image iterators 00107 and their iterator traits. The iterator implementations provided here 00108 may be used for any image data type that stores its 00109 data as a linear array of pixels. The array will be interpreted as a 00110 row-major matrix with a particular width. 00111 </p> 00112 <h3>Requirements for Image Iterators</h3> 00113 <p> 00114 00115 <table border=2 cellspacing=0 cellpadding=2 width="100%"> 00116 <tr><th colspan=2> 00117 Local Types 00118 </th><th> 00119 Meaning 00120 </th> 00121 </tr> 00122 <tr><td colspan=2> 00123 <tt>ImageIterator::value_type</tt></td><td>the underlying image's pixel type</td> 00124 </tr> 00125 <tr><td colspan=2> 00126 <tt>ImageIterator::PixelType</tt></td><td>the underlying image's pixel type</td> 00127 </tr> 00128 <tr><td colspan=2> 00129 <tt>ImageIterator::reference</tt></td> 00130 <td>the iterator's reference type (return type of <TT>*iter</TT>). Will be 00131 <tt>value_type &</tt> for a mutable iterator, and convertible to 00132 <tt>value_type const &</tt> for a const iterator.</td> 00133 </tr> 00134 <tr><td colspan=2> 00135 <tt>ImageIterator::index_reference</tt></td> 00136 <td>the iterator's index reference type (return type of <TT>iter[diff]</TT>). Will be 00137 <tt>value_type &</tt> for a mutable iterator, and convertible to 00138 <tt>value_type const &</tt> for a const iterator.</td> 00139 </tr> 00140 <tr><td colspan=2> 00141 <tt>ImageIterator::pointer</tt></td> 00142 <td>the iterator's pointer type (return type of <TT>iter.operator->()</TT>). Will be 00143 <tt>value_type *</tt> for a mutable iterator, and convertible to 00144 <tt>value_type const *</tt> for a const iterator.</td> 00145 </tr> 00146 <tr><td colspan=2> 00147 <tt>ImageIterator::difference_type</tt></td> 00148 <td>the iterator's difference type (<TT>vigra::Diff2D</TT>)</td> 00149 </tr> 00150 <tr><td colspan=2> 00151 <tt>ImageIterator::iterator_category</tt></td> 00152 <td>the iterator tag (<tt>vigra::image_traverser_tag</tt>)</td> 00153 </tr> 00154 <tr><td colspan=2> 00155 <tt>ImageIterator::row_iterator</tt></td><td>the associated row iterator</td> 00156 </tr> 00157 <tr><td colspan=2> 00158 <tt>ImageIterator::column_iterator</tt></td><td>the associated column iterator</td> 00159 </tr> 00160 <tr><td colspan=2> 00161 <tt>ImageIterator::MoveX</tt></td><td>type of the horizontal navigator</td> 00162 </tr> 00163 <tr><td colspan=2> 00164 <tt>ImageIterator::MoveY</tt></td><td>type of the vertical navigator</td> 00165 </tr> 00166 <tr><th> 00167 Operation 00168 </th><th> 00169 Result 00170 </th><th> 00171 Semantics 00172 </th> 00173 </tr> 00174 <tr> 00175 <td><tt>++i.x<br>i.x--</tt></td><td><tt>void</tt></td><td>increment x-coordinate</td> 00176 </tr> 00177 <tr> 00178 <td><tt>--i.x<br>i.x--</tt></td><td><tt>void</tt></td><td>decrement x-coordinate</td> 00179 </tr> 00180 <tr> 00181 <td><tt>i.x += dx</tt></td><td><tt>ImageIterator::MoveX &</tt></td> 00182 <td>add <tt>dx</tt> to x-coordinate</td> 00183 </tr> 00184 <tr> 00185 <td><tt>i.x -= dx</tt></td><td><tt>ImageIterator::MoveX &</tt></td> 00186 <td>subtract <tt>dx</tt> from x-coordinate</td> 00187 </tr> 00188 <tr> 00189 <td><tt>i.x - j.x</tt></td><td><tt>int</tt></td> 00190 <td>difference of the x-coordinates of <tt>i</tt> and <tt>j</tt></td> 00191 </tr> 00192 <tr> 00193 <td><tt>i.x = j.x</tt></td><td><tt>ImageIterator::MoveX &</tt></td><td><tt>i.x += j.x - i.x</tt></td> 00194 </tr> 00195 <tr> 00196 <td><tt>i.x == i.y</tt></td><td><tt>bool</tt></td><td><tt>j.x - i.x == 0</tt></td> 00197 00198 </tr> 00199 <tr> 00200 <td><tt>i.x < j.x</tt></td><td><tt>bool</tt></td><td><tt>j.x - i.x > 0</tt></td> 00201 00202 </tr> 00203 <tr> 00204 <td><tt>++i.y<br>i.y++</tt></td><td><tt>void</tt></td><td>increment y-coordinate</td> 00205 </tr> 00206 <tr> 00207 <td><tt>--i.y<br>i.y--</tt></td><td><tt>void</tt></td><td>decrement y-coordinate</td> 00208 </tr> 00209 <tr> 00210 <td><tt>i.y += dy</tt></td><td><tt>ImageIterator::MoveY &</tt></td> 00211 <td>add <tt>dy</tt> to y-coordinate</td> 00212 </tr> 00213 <tr> 00214 <td><tt>i.y -= dy</tt></td><td><tt>ImageIterator::MoveY &</tt></td> 00215 <td>subtract <tt>dy</tt> from y-coordinate</td> 00216 </tr> 00217 <tr> 00218 <td><tt>i.y - j.y</tt></td><td><tt>int</tt></td> 00219 <td>difference of the y-coordinates of <tt>i</tt> and <tt>j</tt></td> 00220 </tr> 00221 <tr> 00222 <td><tt>i.y = j.y</tt></td><td><tt>ImageIterator::MoveY &</tt></td><td><tt>i.y += j.y - i.y</tt></td> 00223 </tr> 00224 <tr> 00225 <td><tt>i.y == j.y</tt></td><td><tt>bool</tt></td><td><tt>j.y - i.y == 0</tt></td> 00226 00227 </tr> 00228 <tr> 00229 <td><tt>i.y < j.y</tt></td><td><tt>bool</tt></td><td><tt>j.y - i.y > 0</tt></td> 00230 </tr> 00231 <tr><td colspan=2> 00232 <tt>ImageIterator k(i)</tt></td><td>copy constructor</td> 00233 </tr> 00234 <tr> 00235 <td><tt>k = i</tt></td><td><tt>ImageIterator &</tt></td><td>assignment</td> 00236 </tr> 00237 <tr><td colspan=2> 00238 <tt>ImageIterator k</tt></td><td>default constructor</td> 00239 </tr> 00240 <tr><td colspan=2> 00241 <tt>ImageIterator::row_iterator r(i)</tt></td><td>construction of row iterator</td> 00242 </tr> 00243 <tr><td colspan=2> 00244 <tt>ImageIterator::column_iterator c(i)</tt></td><td>construction of column iterator</td> 00245 </tr> 00246 <tr> 00247 <td><tt>i += diff</tt></td><td><tt>ImageIterator &</tt></td> 00248 <td><tt>{ i.x += diff.x<br>i.y += diff.y; }</tt></td> 00249 </tr> 00250 <tr> 00251 <td><tt>i -= diff</tt></td><td><tt>ImageIterator &</tt></td> 00252 <td><tt>{ i.x -= diff.x<br>i.y -= diff.y; }</tt></td> 00253 </tr> 00254 <tr> 00255 <td><tt>i + diff</tt></td><td><tt>ImageIterator</tt></td> 00256 <td><tt>{ ImageIterator tmp(i);<br>tmp += diff;<br>return tmp; }</tt></td> 00257 </tr> 00258 <tr> 00259 <td><tt>i - diff</tt></td><td><tt>ImageIterator</tt></td> 00260 <td><tt>{ ImageIterator tmp(i);<br>tmp -= diff;<br>return tmp; }</tt></td> 00261 </tr> 00262 <tr> 00263 <td><tt>i - j</tt></td><td><tt>ImageIterator::difference_type</tt></td> 00264 <td><tt>{ ImageIterator::difference_type tmp(i.x - j.x, i.y - j.y);<br>return tmp; }</tt></td> 00265 </tr> 00266 <tr> 00267 <td><tt>i == j</tt></td><td><tt>bool</tt></td> 00268 <td><tt>i.x == j.x && i.y == j.y</tt></td> 00269 </tr> 00270 <tr> 00271 <td><tt>*i</tt></td><td><tt>ImageIterator::reference</tt></td> 00272 <td>access the current pixel</td> 00273 </tr> 00274 <tr> 00275 <td><tt>i[diff]</tt></td><td><tt>ImageIterator::index_reference</tt></td> 00276 <td>access pixel at offset <tt>diff</tt></td> 00277 </tr> 00278 <tr> 00279 <td><tt>i(dx, dy)</tt></td><td><tt>ImageIterator::index_reference</tt></td> 00280 <td>access pixel at offset <tt>(dx, dy)</tt></td> 00281 </tr> 00282 <tr> 00283 <td><tt>i->member()</tt></td><td>depends on operation</td> 00284 <td>call member function of underlying pixel type via <tt>operator-></tt> of iterator</td> 00285 </tr> 00286 <tr><td colspan=3> 00287 <tt>i, j, k</tt> are of type <tt>ImageIterator</tt><br> 00288 <tt>diff</tt> is of type <tt>ImageIterator::difference_type</tt><br> 00289 <tt>dx, dy</tt> are of type <tt>int</tt><br> 00290 </td> 00291 </tr> 00292 </table> 00293 </p> 00294 <h3>Requirements for Image Iterator Traits</h3> 00295 <p> 00296 The following iterator traits must be defined for an image iterator: 00297 </p> 00298 <p> 00299 <table border=2 cellspacing=0 cellpadding=2 width="100%"> 00300 <tr><th> 00301 Types 00302 </th><th> 00303 Meaning 00304 </th> 00305 </tr> 00306 <tr> 00307 <td><tt>IteratorTraits<ImageIterator>::Iterator</tt></td><td>the iterator type the traits are referring to</td> 00308 </tr> 00309 <tr> 00310 <td><tt>IteratorTraits<ImageIterator>::iterator</tt></td><td>the iterator type the traits are referring to</td> 00311 </tr> 00312 <tr> 00313 <td><tt>IteratorTraits<ImageIterator>::value_type</tt></td><td>the underlying image's pixel type</td> 00314 </tr> 00315 <tr> 00316 <td><tt>IteratorTraits<ImageIterator>::reference</tt></td> 00317 <td>the iterator's reference type (return type of <TT>*iter</TT>)</td> 00318 </tr> 00319 <tr> 00320 <td><tt>IteratorTraits<ImageIterator>::index_reference</tt></td> 00321 <td>the iterator's index reference type (return type of <TT>iter[diff]</TT>)</td> 00322 </tr> 00323 <tr> 00324 <td><tt>IteratorTraits<ImageIterator>::pointer</tt></td> 00325 <td>the iterator's pointer type (return type of <TT>iter.operator->()</TT>)</td> 00326 </tr> 00327 <tr> 00328 <td><tt>IteratorTraits<ImageIterator>::difference_type</tt></td> 00329 <td>the iterator's difference type</td> 00330 </tr> 00331 <tr> 00332 <td><tt>IteratorTraits<ImageIterator>::iterator_category</tt></td> 00333 <td>the iterator tag (<tt>vigra::image_traverser_tag</tt>)</td> 00334 </tr> 00335 <tr> 00336 <td><tt>IteratorTraits<ImageIterator>::row_iterator</tt></td><td>the associated row iterator</td> 00337 </tr> 00338 <tr> 00339 <td><tt>IteratorTraits<ImageIterator>::column_iterator</tt></td><td>the associated column iterator</td> 00340 </tr> 00341 <tr> 00342 <td><tt>IteratorTraits<ImageIterator>::DefaultAccessor</tt></td> 00343 <td>the default accessor to be used with the iterator</td> 00344 </tr> 00345 <tr> 00346 <td><tt>IteratorTraits<ImageIterator>::default_accessor</tt></td> 00347 <td>the default accessor to be used with the iterator</td> 00348 </tr> 00349 <tr> 00350 <td><tt>IteratorTraits<ImageIterator>::hasConstantStrides</tt></td> 00351 <td>whether the iterator uses constant strides on the underlying memory 00352 (always <tt>VigraTrueType</tt> for <tt>ImageIterator</tt>s).</td> 00353 </tr> 00354 </table> 00355 </p> 00356 */ 00357 //@{ 00358 00359 namespace detail { 00360 00361 template <class StridedOrUnstrided> 00362 class DirectionSelector; 00363 00364 template <> 00365 class DirectionSelector<UnstridedArrayTag> 00366 { 00367 public: 00368 00369 template <class T> 00370 class type 00371 { 00372 public: 00373 type(T base) 00374 : current_(base) 00375 {} 00376 00377 type(type const & rhs) 00378 : current_(rhs.current_) 00379 {} 00380 00381 type & operator=(type const & rhs) 00382 { 00383 current_ = rhs.current_; 00384 return *this; 00385 } 00386 00387 void operator++() {++current_;} 00388 void operator++(int) {++current_;} 00389 void operator--() {--current_;} 00390 void operator--(int) {--current_;} 00391 void operator+=(int dx) {current_ += dx; } 00392 void operator-=(int dx) {current_ -= dx; } 00393 00394 bool operator==(type const & rhs) const 00395 { return current_ == rhs.current_; } 00396 00397 bool operator!=(type const & rhs) const 00398 { return current_ != rhs.current_; } 00399 00400 bool operator<(type const & rhs) const 00401 { return current_ < rhs.current_; } 00402 00403 bool operator<=(type const & rhs) const 00404 { return current_ <= rhs.current_; } 00405 00406 bool operator>(type const & rhs) const 00407 { return current_ > rhs.current_; } 00408 00409 bool operator>=(type const & rhs) const 00410 { return current_ >= rhs.current_; } 00411 00412 int operator-(type const & rhs) const 00413 { return current_ - rhs.current_; } 00414 00415 T operator()() const 00416 { return current_; } 00417 00418 T operator()(int d) const 00419 { return current_ + d; } 00420 00421 T current_; 00422 }; 00423 }; 00424 00425 template <> 00426 class DirectionSelector<StridedArrayTag> 00427 { 00428 public: 00429 00430 template <class T> 00431 class type 00432 { 00433 public: 00434 type(int stride, T base = 0) 00435 : stride_(stride), 00436 current_(base) 00437 {} 00438 00439 type(type const & rhs) 00440 : stride_(rhs.stride_), 00441 current_(rhs.current_) 00442 {} 00443 00444 type & operator=(type const & rhs) 00445 { 00446 stride_ = rhs.stride_; 00447 current_ = rhs.current_; 00448 return *this; 00449 } 00450 00451 void operator++() {current_ += stride_; } 00452 void operator++(int) {current_ += stride_; } 00453 void operator--() {current_ -= stride_; } 00454 void operator--(int) {current_ -= stride_; } 00455 void operator+=(int dy) {current_ += dy*stride_; } 00456 void operator-=(int dy) {current_ -= dy*stride_; } 00457 00458 bool operator==(type const & rhs) const 00459 { return (current_ == rhs.current_); } 00460 00461 bool operator!=(type const & rhs) const 00462 { return (current_ != rhs.current_); } 00463 00464 bool operator<(type const & rhs) const 00465 { return (current_ < rhs.current_); } 00466 00467 bool operator<=(type const & rhs) const 00468 { return (current_ <= rhs.current_); } 00469 00470 bool operator>(type const & rhs) const 00471 { return (current_ > rhs.current_); } 00472 00473 bool operator>=(type const & rhs) const 00474 { return (current_ >= rhs.current_); } 00475 00476 int operator-(type const & rhs) const 00477 { return (current_ - rhs.current_) / stride_; } 00478 00479 T operator()() const 00480 { return current_; } 00481 00482 T operator()(int d) const 00483 { return current_ + d*stride_; } 00484 00485 int stride_; 00486 T current_; 00487 }; 00488 }; 00489 00490 template <class StridedOrUnstrided> 00491 class LinearIteratorSelector; 00492 00493 template <> 00494 class LinearIteratorSelector<UnstridedArrayTag> 00495 { 00496 public: 00497 template <class IMAGEITERATOR> 00498 class type 00499 { 00500 public: 00501 typedef typename IMAGEITERATOR::pointer res; 00502 00503 template <class DirSelect> 00504 static res construct(typename IMAGEITERATOR::pointer data, DirSelect const &) 00505 { 00506 return data; 00507 } 00508 }; 00509 }; 00510 00511 template <> 00512 class LinearIteratorSelector<StridedArrayTag> 00513 { 00514 public: 00515 template <class IMAGEITERATOR> 00516 class type 00517 { 00518 public: 00519 typedef IteratorAdaptor<StridedIteratorPolicy<IMAGEITERATOR> > res; 00520 00521 template <class DirSelect> 00522 static res construct(typename IMAGEITERATOR::pointer data, DirSelect const & d) 00523 { 00524 typedef typename res::BaseType Base; 00525 return res(Base(data, d.stride_)); 00526 } 00527 }; 00528 }; 00529 00530 00531 } // namespace detail 00532 00533 /********************************************************/ 00534 /* */ 00535 /* ImageIteratorBase */ 00536 /* */ 00537 /********************************************************/ 00538 00539 /** \brief Base class for 2D random access iterators. 00540 00541 This class contains the navigational part of the iterator. 00542 It is usually not constructed directly, but via some derived class such as 00543 \ref ImageIterator or \ref StridedImageIterator. 00544 00545 <b>\#include</b> <<a href="imageiterator_8hxx-source.html">vigra/imageiterator.hxx</a>> 00546 00547 Namespace: vigra 00548 00549 The usage examples assume that you constructed two iterators like 00550 this: 00551 00552 \code 00553 vigra::ImageIterator<SomePixelType> iterator(base, width); 00554 vigra::ImageIterator<SomePixelType> iterator1(base, width); 00555 \endcode 00556 00557 See the paper: U. Koethe: 00558 <a href="documents/GenericProg2D.ps">Reusable Algorithms in Image Processing</a> 00559 for a discussion of the concepts behind ImageIterators. 00560 00561 */ 00562 template <class IMAGEITERATOR, 00563 class PIXELTYPE, class REFERENCE, class POINTER, 00564 class StridedOrUnstrided = UnstridedArrayTag> 00565 class ImageIteratorBase 00566 { 00567 typedef typename 00568 detail::LinearIteratorSelector<StridedOrUnstrided>::template type<ImageIteratorBase> 00569 RowIteratorSelector; 00570 typedef typename 00571 detail::LinearIteratorSelector<StridedArrayTag>::template type<ImageIteratorBase> 00572 ColumnIteratorSelector; 00573 public: 00574 typedef ImageIteratorBase<IMAGEITERATOR, 00575 PIXELTYPE, REFERENCE, POINTER, StridedOrUnstrided> self_type; 00576 00577 /** The underlying image's pixel type. 00578 */ 00579 typedef PIXELTYPE value_type; 00580 00581 /** deprecated, use <TT>value_type</TT> instead. 00582 */ 00583 typedef PIXELTYPE PixelType; 00584 00585 /** the iterator's reference type (return type of <TT>*iter</TT>) 00586 */ 00587 typedef REFERENCE reference; 00588 00589 /** the iterator's index reference type (return type of <TT>iter[diff]</TT>) 00590 */ 00591 typedef REFERENCE index_reference; 00592 00593 /** the iterator's pointer type (return type of <TT>iter.operator->()</TT>) 00594 */ 00595 typedef POINTER pointer; 00596 00597 /** the iterator's difference type (argument type of <TT>iter[diff]</TT>) 00598 */ 00599 typedef Diff2D difference_type; 00600 00601 /** the iterator tag (image traverser) 00602 */ 00603 typedef image_traverser_tag iterator_category; 00604 00605 /** The associated row iterator. 00606 */ 00607 typedef typename RowIteratorSelector::res row_iterator; 00608 00609 /** The associated column iterator. 00610 */ 00611 typedef typename ColumnIteratorSelector::res column_iterator; 00612 00613 /** Let operations act in X direction 00614 */ 00615 typedef typename 00616 detail::DirectionSelector<StridedOrUnstrided>::template type<pointer> MoveX; 00617 00618 /** Let operations act in Y direction 00619 */ 00620 typedef typename 00621 detail::DirectionSelector<StridedArrayTag>::template type<int> MoveY; 00622 00623 /** @name Comparison of Iterators */ 00624 //@{ 00625 /** usage: <TT> iterator == iterator1 </TT> 00626 */ 00627 bool operator==(ImageIteratorBase const & rhs) const 00628 { 00629 return (x == rhs.x) && (y == rhs.y); 00630 } 00631 00632 /** usage: <TT> iterator != iterator1 </TT> 00633 */ 00634 bool operator!=(ImageIteratorBase const & rhs) const 00635 { 00636 return (x != rhs.x) || (y != rhs.y); 00637 } 00638 00639 /** usage: <TT> Diff2D dist = iterator - iterator1 </TT> 00640 */ 00641 difference_type operator-(ImageIteratorBase const & rhs) const 00642 { 00643 return difference_type(x - rhs.x, y - rhs.y); 00644 } 00645 00646 //@} 00647 00648 /** @name Specify coordinate to operate on */ 00649 //@{ 00650 /** Refer to iterator's x coordinate. 00651 Usage examples:<br> 00652 \code 00653 ++iterator.x; // move one step to the right 00654 --iterator.x; // move one step to the left 00655 iterator.x += dx; // move dx steps to the right 00656 iterator.x -= dx; // move dx steps to the left 00657 bool notAtEndOfRow = iterator.x < lowerRight.x; // compare x coordinates of two iterators 00658 int width = lowerRight.x - upperLeft.x; // calculate difference of x coordinates 00659 // between two iterators 00660 \endcode 00661 */ 00662 MoveX x; 00663 /** Refer to iterator's y coordinate. 00664 Usage examples:<br> 00665 \code 00666 ++iterator.y; // move one step down 00667 --iterator.y; // move one step up 00668 iterator.y += dy; // move dy steps down 00669 iterator.y -= dy; // move dy steps up 00670 bool notAtEndOfColumn = iterator.y < lowerRight.y; // compare y coordinates of two iterators 00671 int height = lowerRight.y - upperLeft.y; // calculate difference of y coordinates 00672 // between two iterators 00673 \endcode 00674 */ 00675 MoveY y; 00676 //@} 00677 00678 protected: 00679 /** Construct from raw memory with a vertical stride of <TT>ystride</TT>. 00680 <TT>ystride</TT> must equal the physical image width (row length), 00681 even if the iterator will only be used for a sub image. This constructor 00682 must only be called for unstrided iterators 00683 (<tt>StridedOrUnstrided == UnstridedArrayTag</tt>) 00684 */ 00685 ImageIteratorBase(pointer base, int ystride) 00686 : x(base), 00687 y(ystride) 00688 {} 00689 00690 /** Construct from raw memory with a horizontal stride of <TT>xstride</TT> 00691 and a vertical stride of <TT>ystride</TT>. This constructor 00692 may be used for iterators that shall skip pixels. Thus, it 00693 must only be called for strided iterators 00694 (<tt>StridedOrUnstrided == StridedArrayTag</tt>) 00695 */ 00696 ImageIteratorBase(pointer base, int xstride, int ystride) 00697 : x(xstride, base), 00698 y(ystride) 00699 {} 00700 00701 /** Copy constructor */ 00702 ImageIteratorBase(ImageIteratorBase const & rhs) 00703 : x(rhs.x), 00704 y(rhs.y) 00705 {} 00706 00707 /** Default constructor */ 00708 ImageIteratorBase() 00709 : x(0), 00710 y(0) 00711 {} 00712 00713 /** Copy assignment */ 00714 ImageIteratorBase & operator=(ImageIteratorBase const & rhs) 00715 { 00716 if(this != &rhs) 00717 { 00718 x = rhs.x; 00719 y = rhs.y; 00720 } 00721 return *this; 00722 } 00723 00724 public: 00725 /** @name Random navigation */ 00726 //@{ 00727 /** Add offset via Diff2D 00728 */ 00729 IMAGEITERATOR & operator+=(difference_type const & s) 00730 { 00731 x += s.x; 00732 y += s.y; 00733 return static_cast<IMAGEITERATOR &>(*this); 00734 } 00735 /** Subtract offset via Diff2D 00736 */ 00737 IMAGEITERATOR & operator-=(difference_type const & s) 00738 { 00739 x -= s.x; 00740 y -= s.y; 00741 return static_cast<IMAGEITERATOR &>(*this); 00742 } 00743 00744 /** Add a distance 00745 */ 00746 IMAGEITERATOR operator+(difference_type const & s) const 00747 { 00748 IMAGEITERATOR ret(static_cast<IMAGEITERATOR const &>(*this)); 00749 00750 ret += s; 00751 00752 return ret; 00753 } 00754 00755 /** Subtract a distance 00756 */ 00757 IMAGEITERATOR operator-(difference_type const & s) const 00758 { 00759 IMAGEITERATOR ret(static_cast<IMAGEITERATOR const &>(*this)); 00760 00761 ret -= s; 00762 00763 return ret; 00764 } 00765 //@} 00766 00767 /** @name Access the Pixels */ 00768 //@{ 00769 /** Access current pixel. <br> 00770 usage: <TT> SomePixelType value = *iterator </TT> 00771 */ 00772 reference operator*() const 00773 { 00774 return *current(); 00775 } 00776 00777 /** Call member of current pixel. <br> 00778 usage: <TT> iterator->pixelMemberFunction() </TT> 00779 */ 00780 pointer operator->() const 00781 { 00782 return current(); 00783 } 00784 00785 /** Access pixel at offset from current location. <br> 00786 usage: <TT> SomePixelType value = iterator[Diff2D(1,1)] </TT> 00787 */ 00788 index_reference operator[](Diff2D const & d) const 00789 { 00790 return *current(d.x, d.y); 00791 } 00792 00793 /** Access pixel at offset (dx, dy) from current location. <br> 00794 usage: <TT> SomePixelType value = iterator(dx, dy) </TT> 00795 */ 00796 index_reference operator()(int dx, int dy) const 00797 { 00798 return *current(dx, dy); 00799 } 00800 00801 /** Read pixel with offset [dy][dx] from current pixel. 00802 Note that the 'x' index is the trailing index. <br> 00803 usage: <TT> SomePixelType value = iterator[dy][dx] </TT> 00804 */ 00805 pointer operator[](int dy) const 00806 { 00807 return x() + y(dy); 00808 } 00809 //@} 00810 00811 row_iterator rowIterator() const 00812 { 00813 return RowIteratorSelector::construct(current(), x); 00814 } 00815 00816 column_iterator columnIterator() const 00817 { 00818 return ColumnIteratorSelector::construct(current(), y); 00819 } 00820 00821 private: 00822 00823 pointer current() const 00824 { return x() + y(); } 00825 00826 pointer current(int dx, int dy) const 00827 { return x(dx) + y(dy); } 00828 }; 00829 00830 /********************************************************/ 00831 /* */ 00832 /* ImageIterator */ 00833 /* */ 00834 /********************************************************/ 00835 00836 /** \brief Standard 2D random access iterator for images that store the 00837 data in a linear array. 00838 00839 Most functions and local types are inherited from ImageIteratorBase. 00840 00841 See the paper: U. Koethe: 00842 <a href="documents/GenericProg2D.ps">Reusable Algorithms in Image Processing</a> 00843 for a discussion of the concepts behind ImageIterators. 00844 00845 <b>\#include</b> <<a href="imageiterator_8hxx-source.html">vigra/imageiterator.hxx</a>> 00846 00847 Namespace: vigra 00848 00849 */ 00850 template <class PIXELTYPE> 00851 class ImageIterator 00852 : public ImageIteratorBase<ImageIterator<PIXELTYPE>, 00853 PIXELTYPE, PIXELTYPE &, PIXELTYPE *> 00854 { 00855 public: 00856 typedef ImageIteratorBase<ImageIterator<PIXELTYPE>, 00857 PIXELTYPE, PIXELTYPE &, PIXELTYPE *> Base; 00858 00859 typedef typename Base::pointer pointer; 00860 typedef typename Base::difference_type difference_type; 00861 00862 /** Construct from raw memory with a vertical stride of <TT>ystride</TT>. 00863 <TT>ystride</TT> must equal the physical image width (row length), 00864 even if the iterator will only be used for a sub image. 00865 If the raw memory is encapsulated in an image object this 00866 object should have a factory function that constructs the 00867 iterator. 00868 */ 00869 ImageIterator(pointer base, int ystride) 00870 : Base(base, ystride) 00871 {} 00872 00873 /** Default constructor */ 00874 ImageIterator() 00875 : Base() 00876 {} 00877 00878 }; 00879 00880 /********************************************************/ 00881 /* */ 00882 /* ConstImageIterator */ 00883 /* */ 00884 /********************************************************/ 00885 00886 /** \brief Standard 2D random access const iterator for images that 00887 store the data as a linear array. 00888 00889 Most functions are inherited from ImageIteratorBase. 00890 00891 <b>\#include</b> <<a href="imageiterator_8hxx-source.html">vigra/imageiterator.hxx</a>> 00892 00893 Namespace: vigra 00894 00895 */ 00896 template <class PIXELTYPE> 00897 class ConstImageIterator 00898 : public ImageIteratorBase<ConstImageIterator<PIXELTYPE>, 00899 PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *> 00900 { 00901 public: 00902 typedef ImageIteratorBase<ConstImageIterator<PIXELTYPE>, 00903 PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *> Base; 00904 00905 typedef typename Base::pointer pointer; 00906 typedef typename Base::difference_type difference_type; 00907 00908 /** Construct from raw memory with a vertical stride of <TT>ystride</TT>. 00909 <TT>ystride</TT> must equal the physical image width (row length), 00910 even if the iterator will only be used for a sub image. 00911 If the raw memory is encapsulated in an image object this 00912 object should have a factory function that constructs the 00913 iterator. 00914 */ 00915 ConstImageIterator(pointer base, int ystride) 00916 : Base(base, ystride) 00917 {} 00918 00919 ConstImageIterator(ImageIterator<PIXELTYPE> const & o) 00920 : Base(o.x, o.y) 00921 {} 00922 00923 /** Default constructor */ 00924 ConstImageIterator() 00925 : Base() 00926 {} 00927 00928 ConstImageIterator & operator=(ImageIterator<PIXELTYPE> const & o) 00929 { 00930 Base::x = o.x; 00931 Base::y = o.y; 00932 return *this; 00933 } 00934 }; 00935 00936 /********************************************************/ 00937 /* */ 00938 /* StridedImageIterator */ 00939 /* */ 00940 /********************************************************/ 00941 00942 /** \brief Iterator to be used when pixels are to be skipped. 00943 00944 This iterator can be used when some pixels shall be automatically skipped, for example 00945 if an image is to be sub-sampled: instead of advancing to the next pixel, 00946 <tt>++iterator.x</tt> jumps to the pixel at a horizontal offset of <tt>xskip</tt>. 00947 Likewise with <tt>yskip</tt> in vertical direction. Most functions and local types 00948 are inherited from ImageIteratorBase. 00949 00950 <b> Usage:</b> 00951 00952 \code 00953 BImage img(w,h); 00954 ... 00955 int xskip = 2, yskip = 2; 00956 int wskip = w / xskip + 1, hskip = h / yskip + 1; 00957 00958 StridedImageIterator<BImage::value_type> upperLeft(&img(0,0), w, xskip, yskip); 00959 StridedImageIterator<BImage::value_type> lowerRight = upperLeft + Diff2D(wskip, hskip); 00960 00961 // now navigation with upperLeft and lowerRight lets the image appear to have half 00962 // the original resolution in either dimension 00963 \endcode 00964 00965 <b>\#include</b> <<a href="imageiterator_8hxx-source.html">vigra/imageiterator.hxx</a>> 00966 00967 Namespace: vigra 00968 00969 */ 00970 template <class PIXELTYPE> 00971 class StridedImageIterator 00972 : public ImageIteratorBase<StridedImageIterator<PIXELTYPE>, 00973 PIXELTYPE, PIXELTYPE &, PIXELTYPE *, StridedArrayTag> 00974 { 00975 public: 00976 typedef ImageIteratorBase<StridedImageIterator<PIXELTYPE>, 00977 PIXELTYPE, PIXELTYPE &, PIXELTYPE *, StridedArrayTag> Base; 00978 00979 typedef typename Base::pointer pointer; 00980 typedef typename Base::difference_type difference_type; 00981 00982 /** Construct from raw memory with a vertical stride of <TT>ystride</TT>, 00983 jumping by <tt>xskip</tt> horizontally and <tt>yskip</tt> vertically. 00984 <tt>ystride</tt> must be the physical width (row length) of the image. 00985 */ 00986 StridedImageIterator(pointer base, int ystride, int xskip, int yskip) 00987 : Base(base, xskip, ystride*yskip) 00988 {} 00989 00990 /** Default constructor */ 00991 StridedImageIterator() 00992 : Base() 00993 {} 00994 00995 }; 00996 00997 /********************************************************/ 00998 /* */ 00999 /* ConstStridedImageIterator */ 01000 /* */ 01001 /********************************************************/ 01002 01003 /** \brief Const iterator to be used when pixels are to be skipped. 01004 01005 This iterator can be used when some pixels shall be automatically skipped, for example 01006 if an image is to be sub-sampled: instead of advancing to the next pixel, 01007 <tt>++iterator.x</tt> jumps to the pixel at a horizontal offset of <tt>xskip</tt>. 01008 Likewise with <tt>yskip</tt> in vertical direction. Most functions and local types 01009 are inherited from ImageIteratorBase. 01010 01011 <b> Usage:</b> 01012 01013 \code 01014 BImage img(w,h); 01015 ... 01016 int xskip = 2, yskip = 2; 01017 int wskip = w / xskip + 1, hskip = h / yskip + 1; 01018 01019 ConstStridedImageIterator<BImage::value_type> upperLeft(&img(0,0), w, xskip, yskip); 01020 ConstStridedImageIterator<BImage::value_type> lowerRight = upperLeft + Diff2D(wskip, hskip); 01021 01022 // now navigation with upperLeft and lowerRight lets the image appear to have half 01023 // the original resolution in either dimension 01024 \endcode 01025 01026 <b>\#include</b> <<a href="imageiterator_8hxx-source.html">vigra/imageiterator.hxx</a>> 01027 01028 Namespace: vigra 01029 01030 */ 01031 template <class PIXELTYPE> 01032 class ConstStridedImageIterator 01033 : public ImageIteratorBase<ConstStridedImageIterator<PIXELTYPE>, 01034 PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *, 01035 StridedArrayTag> 01036 { 01037 public: 01038 typedef ImageIteratorBase<ConstStridedImageIterator<PIXELTYPE>, 01039 PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *, 01040 StridedArrayTag> Base; 01041 01042 typedef typename Base::pointer pointer; 01043 typedef typename Base::difference_type difference_type; 01044 01045 /** Construct from raw memory with a vertical stride of <TT>ystride</TT>, 01046 jumping by <tt>xskip</tt> horizontally and <tt>yskip</tt> vertically. 01047 <tt>ystride</tt> must be the physical width (row length) of the image. 01048 */ 01049 ConstStridedImageIterator(pointer base, int ystride, int xskip, int yskip) 01050 : Base(base, xskip, ystride*yskip) 01051 {} 01052 01053 /** Copy-construct from mutable iterator */ 01054 ConstStridedImageIterator(StridedImageIterator<PIXELTYPE> const & o) 01055 : Base(o.x, o.y) 01056 {} 01057 01058 /** Default constructor */ 01059 ConstStridedImageIterator() 01060 : Base() 01061 {} 01062 01063 /** Assign mutable iterator */ 01064 ConstStridedImageIterator & operator=(StridedImageIterator<PIXELTYPE> const & o) 01065 { 01066 Base::x = o.x; 01067 Base::y = o.y; 01068 return *this; 01069 } 01070 }; 01071 01072 /********************************************************/ 01073 /* */ 01074 /* definition of iterator traits */ 01075 /* */ 01076 /********************************************************/ 01077 01078 01079 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION 01080 01081 template <class T> 01082 struct IteratorTraits<ImageIterator<T> > 01083 : public IteratorTraitsBase<ImageIterator<T> > 01084 { 01085 typedef ImageIterator<T> mutable_iterator; 01086 typedef ConstImageIterator<T> const_iterator; 01087 typedef typename AccessorTraits<T>::default_accessor DefaultAccessor; 01088 typedef DefaultAccessor default_accessor; 01089 typedef VigraTrueType hasConstantStrides; 01090 }; 01091 01092 template <class T> 01093 struct IteratorTraits<ConstImageIterator<T> > 01094 : public IteratorTraitsBase<ConstImageIterator<T> > 01095 { 01096 typedef ImageIterator<T> mutable_iterator; 01097 typedef ConstImageIterator<T> const_iterator; 01098 typedef typename AccessorTraits<T>::default_const_accessor DefaultAccessor; 01099 typedef DefaultAccessor default_accessor; 01100 typedef VigraTrueType hasConstantStrides; 01101 }; 01102 01103 template <class T> 01104 struct IteratorTraits<StridedImageIterator<T> > 01105 : public IteratorTraitsBase<StridedImageIterator<T> > 01106 { 01107 typedef StridedImageIterator<T> mutable_iterator; 01108 typedef ConstStridedImageIterator<T> const_iterator; 01109 typedef typename AccessorTraits<T>::default_accessor DefaultAccessor; 01110 typedef DefaultAccessor default_accessor; 01111 typedef VigraTrueType hasConstantStrides; 01112 }; 01113 01114 template <class T> 01115 struct IteratorTraits<ConstStridedImageIterator<T> > 01116 : public IteratorTraitsBase<ConstStridedImageIterator<T> > 01117 { 01118 typedef StridedImageIterator<T> mutable_iterator; 01119 typedef ConstStridedImageIterator<T> const_iterator; 01120 typedef typename AccessorTraits<T>::default_const_accessor DefaultAccessor; 01121 typedef DefaultAccessor default_accessor; 01122 typedef VigraTrueType hasConstantStrides; 01123 }; 01124 01125 #else // NO_PARTIAL_TEMPLATE_SPECIALIZATION 01126 01127 #define VIGRA_DEFINE_ITERATORTRAITS(VALUETYPE) \ 01128 template <> \ 01129 struct IteratorTraits<ImageIterator<VALUETYPE > > \ 01130 : public IteratorTraitsBase<ImageIterator<VALUETYPE > > \ 01131 { \ 01132 typedef ImageIterator<VALUETYPE> mutable_iterator; \ 01133 typedef ConstImageIterator<VALUETYPE> const_iterator; \ 01134 typedef typename AccessorTraits<VALUETYPE >::default_accessor DefaultAccessor; \ 01135 typedef DefaultAccessor default_accessor; \ 01136 typedef VigraTrueType hasConstantStrides; \ 01137 }; \ 01138 \ 01139 template <> \ 01140 struct IteratorTraits<ConstImageIterator<VALUETYPE > > \ 01141 : public IteratorTraitsBase<ConstImageIterator<VALUETYPE > > \ 01142 { \ 01143 typedef ImageIterator<VALUETYPE> mutable_iterator; \ 01144 typedef ConstImageIterator<VALUETYPE> const_iterator; \ 01145 typedef typename AccessorTraits<VALUETYPE >::default_const_accessor DefaultAccessor; \ 01146 typedef DefaultAccessor default_accessor; \ 01147 typedef VigraTrueType hasConstantStrides; \ 01148 }; \ 01149 template <> \ 01150 struct IteratorTraits<StridedImageIterator<VALUETYPE > > \ 01151 : public IteratorTraitsBase<StridedImageIterator<VALUETYPE > > \ 01152 { \ 01153 typedef StridedImageIterator<VALUETYPE> mutable_iterator; \ 01154 typedef ConstStridedImageIterator<VALUETYPE> const_iterator; \ 01155 typedef typename AccessorTraits<VALUETYPE >::default_accessor DefaultAccessor; \ 01156 typedef DefaultAccessor default_accessor; \ 01157 typedef VigraTrueType hasConstantStrides; \ 01158 }; \ 01159 \ 01160 template <> \ 01161 struct IteratorTraits<ConstStridedImageIterator<VALUETYPE > > \ 01162 : public IteratorTraitsBase<ConstStridedImageIterator<VALUETYPE > > \ 01163 { \ 01164 typedef StridedImageIterator<VALUETYPE> mutable_iterator; \ 01165 typedef ConstStridedImageIterator<VALUETYPE> const_iterator; \ 01166 typedef typename AccessorTraits<VALUETYPE >::default_const_accessor DefaultAccessor; \ 01167 typedef DefaultAccessor default_accessor; \ 01168 typedef VigraTrueType hasConstantStrides; \ 01169 }; 01170 01171 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<unsigned char>) 01172 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<short>) 01173 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<int>) 01174 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<float>) 01175 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<double>) 01176 01177 #define VIGRA_PIXELTYPE TinyVector<unsigned char, 2> 01178 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 01179 #undef VIGRA_PIXELTYPE 01180 #define VIGRA_PIXELTYPE TinyVector<unsigned char, 3> 01181 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 01182 #undef VIGRA_PIXELTYPE 01183 #define VIGRA_PIXELTYPE TinyVector<unsigned char, 4> 01184 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 01185 #undef VIGRA_PIXELTYPE 01186 #define VIGRA_PIXELTYPE TinyVector<short, 2> 01187 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 01188 #undef VIGRA_PIXELTYPE 01189 #define VIGRA_PIXELTYPE TinyVector<short, 3> 01190 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 01191 #undef VIGRA_PIXELTYPE 01192 #define VIGRA_PIXELTYPE TinyVector<short, 4> 01193 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 01194 #undef VIGRA_PIXELTYPE 01195 #define VIGRA_PIXELTYPE TinyVector<int, 2> 01196 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 01197 #undef VIGRA_PIXELTYPE 01198 #define VIGRA_PIXELTYPE TinyVector<int, 3> 01199 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 01200 #undef VIGRA_PIXELTYPE 01201 #define VIGRA_PIXELTYPE TinyVector<int, 4> 01202 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 01203 #undef VIGRA_PIXELTYPE 01204 #define VIGRA_PIXELTYPE TinyVector<float, 2> 01205 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 01206 #undef VIGRA_PIXELTYPE 01207 #define VIGRA_PIXELTYPE TinyVector<float, 3> 01208 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 01209 #undef VIGRA_PIXELTYPE 01210 #define VIGRA_PIXELTYPE TinyVector<float, 4> 01211 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 01212 #undef VIGRA_PIXELTYPE 01213 #define VIGRA_PIXELTYPE TinyVector<double, 2> 01214 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 01215 #undef VIGRA_PIXELTYPE 01216 #define VIGRA_PIXELTYPE TinyVector<double, 3> 01217 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 01218 #undef VIGRA_PIXELTYPE 01219 #define VIGRA_PIXELTYPE TinyVector<double, 4> 01220 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 01221 #undef VIGRA_PIXELTYPE 01222 01223 #undef VIGRA_DEFINE_ITERATORTRAITS 01224 01225 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION 01226 01227 template <class PIXELTYPE> 01228 class ConstValueIteratorPolicy 01229 { 01230 public: 01231 01232 typedef PIXELTYPE value_type; 01233 typedef int difference_type; 01234 typedef PIXELTYPE const & reference; 01235 typedef PIXELTYPE const & index_reference; 01236 typedef PIXELTYPE const * pointer; 01237 typedef std::random_access_iterator_tag iterator_category; 01238 01239 struct BaseType 01240 { 01241 BaseType(PIXELTYPE const & v = PIXELTYPE(), int p = 0) 01242 : value(v), pos(p) 01243 {} 01244 01245 PIXELTYPE value; 01246 int pos; 01247 }; 01248 01249 static void initialize(BaseType & d) {} 01250 01251 static reference dereference(BaseType const & d) 01252 { return d.value; } 01253 01254 static index_reference dereference(BaseType d, difference_type) 01255 { 01256 return d.value; 01257 } 01258 01259 static bool equal(BaseType const & d1, BaseType const & d2) 01260 { return d1.pos == d2.pos; } 01261 01262 static bool less(BaseType const & d1, BaseType const & d2) 01263 { return d1.pos < d2.pos; } 01264 01265 static difference_type difference(BaseType const & d1, BaseType const & d2) 01266 { return d1.pos - d2.pos; } 01267 01268 static void increment(BaseType & d) 01269 { ++d.pos; } 01270 01271 static void decrement(BaseType & d) 01272 { --d.pos; } 01273 01274 static void advance(BaseType & d, difference_type n) 01275 { d.pos += n; } 01276 }; 01277 01278 /********************************************************/ 01279 /* */ 01280 /* ConstValueIterator */ 01281 /* */ 01282 /********************************************************/ 01283 01284 /** \brief Iterator that always returns the constant specified in the 01285 constructor. 01286 01287 This iterator can be used to simulate an image that 01288 does not actually exist. 01289 01290 <b>\#include</b> <<a href="imageiterator_8hxx-source.html">vigra/imageiterator.hxx</a>> 01291 01292 Namespace: vigra 01293 01294 */ 01295 template <class PIXELTYPE> 01296 class ConstValueIterator 01297 { 01298 public: 01299 /** The type of the constant the iterator holds. 01300 */ 01301 typedef PIXELTYPE value_type; 01302 01303 /** The type of the constant the iterator holds. 01304 */ 01305 typedef PIXELTYPE PixelType; 01306 01307 /** the iterator's reference type (return type of <TT>*iter</TT>) 01308 */ 01309 typedef PIXELTYPE const & reference; 01310 01311 /** the iterator's index reference type (return type of <TT>iter[diff]</TT>) 01312 */ 01313 typedef PIXELTYPE const & index_reference; 01314 01315 /** the iterator's pointer type (return type of <TT>iter.operator->()</TT>) 01316 */ 01317 typedef PIXELTYPE const * pointer; 01318 01319 /** the iterator's difference type (argument type of <TT>iter[diff]</TT>) 01320 */ 01321 typedef Diff2D difference_type; 01322 01323 /** the iterator tag (image traverser) 01324 */ 01325 typedef image_traverser_tag iterator_category; 01326 01327 /** The associated row iterator. 01328 */ 01329 typedef IteratorAdaptor<ConstValueIteratorPolicy<PIXELTYPE> > row_iterator; 01330 01331 /** The associated column iterator. 01332 */ 01333 typedef IteratorAdaptor<ConstValueIteratorPolicy<PIXELTYPE> > column_iterator; 01334 01335 /** Let operations act in X direction 01336 */ 01337 typedef int MoveX; 01338 01339 /** Let operations act in Y direction 01340 */ 01341 typedef int MoveY; 01342 01343 /** Default Constructor. (the constant is set to 01344 <TT>NumericTraits<PIXELTYPE>::zero()</TT> ) 01345 */ 01346 ConstValueIterator() 01347 : value_(NumericTraits<PIXELTYPE>::zero()), x(0), y(0) 01348 {} 01349 01350 /** Construct with given constant. 01351 */ 01352 ConstValueIterator(PixelType const & v) 01353 : value_(v), x(0), y(0) 01354 {} 01355 01356 /** Copy Constructor. 01357 */ 01358 ConstValueIterator(ConstValueIterator const & v) 01359 : value_(v.value_), x(v.x), y(v.y) 01360 {} 01361 01362 /** Copy Assigment. 01363 */ 01364 ConstValueIterator & operator=(ConstValueIterator const & v) 01365 { 01366 if(this != &v) 01367 { 01368 value_ = v.value_; 01369 x = v.x; 01370 y = v.y; 01371 } 01372 return *this; 01373 } 01374 01375 /** Move iterator by specified distance. 01376 */ 01377 ConstValueIterator & operator+=(Diff2D const & d) 01378 { 01379 x += d.x; 01380 y += d.y; 01381 return *this; 01382 } 01383 01384 /** Move iterator by specified distance. 01385 */ 01386 ConstValueIterator & operator-=(Diff2D const & d) 01387 { 01388 x -= d.x; 01389 y -= d.y; 01390 return *this; 01391 } 01392 01393 /** Create iterator at specified distance. 01394 */ 01395 ConstValueIterator operator+(Diff2D const & d) const 01396 { 01397 ConstValueIterator ret(*this); 01398 ret += d; 01399 return ret; 01400 } 01401 01402 /** Create iterator at specified distance. 01403 */ 01404 ConstValueIterator operator-(Diff2D const & d) const 01405 { 01406 ConstValueIterator ret(*this); 01407 ret -= d; 01408 return ret; 01409 } 01410 01411 /** Compute distance between two iterators 01412 */ 01413 Diff2D operator-(ConstValueIterator const & r) const 01414 { 01415 return Diff2D(x - r.x, y - r.y); 01416 } 01417 01418 /** Equality. 01419 */ 01420 bool operator==(ConstValueIterator const & r) const 01421 { 01422 return (x == r.x) && (y == r.y); 01423 } 01424 01425 /** Inequality. 01426 */ 01427 bool operator!=(ConstValueIterator const & r) const 01428 { 01429 return (x != r.x) || (y != r.y); 01430 } 01431 01432 /** Read current pixel (return specified constant). 01433 */ 01434 reference operator*() const 01435 { 01436 return value_; 01437 } 01438 01439 /** Call member function for stored constant. 01440 */ 01441 pointer operator->() const 01442 { 01443 return &value_; 01444 } 01445 01446 /** Read pixel at a distance (return specified constant). 01447 */ 01448 index_reference operator()(int const &, int const &) const 01449 { 01450 return value_; 01451 } 01452 01453 /** Read pixel at a distance (return specified constant). 01454 */ 01455 index_reference operator[](Diff2D const &) const 01456 { 01457 return value_; 01458 } 01459 01460 /** Get row iterator at current position (which will also hold the constant). 01461 */ 01462 row_iterator rowIterator() const 01463 { return row_iterator(typename row_iterator::BaseType(value_, x)); } 01464 01465 /** Get column iterator at current position (which will also hold the constant). 01466 */ 01467 column_iterator columnIterator() const 01468 { return column_iterator(typename column_iterator::BaseType(value_, y)); } 01469 01470 /** @name Specify coordinate direction for navigation commands */ 01471 //@{ 01472 /// refer to x coordinate 01473 int x; 01474 /// refer to y coordinate 01475 int y; 01476 //@} 01477 01478 private: 01479 01480 PixelType value_; 01481 }; 01482 01483 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION 01484 01485 template <class T> 01486 struct IteratorTraits<ConstValueIterator<T> > 01487 { 01488 typedef ConstValueIterator<T> Iterator; 01489 typedef Iterator iterator; 01490 typedef typename iterator::iterator_category iterator_category; 01491 typedef typename iterator::value_type value_type; 01492 typedef typename iterator::reference reference; 01493 typedef typename iterator::index_reference index_reference; 01494 typedef typename iterator::pointer pointer; 01495 typedef typename iterator::difference_type difference_type; 01496 typedef typename iterator::row_iterator row_iterator; 01497 typedef typename iterator::column_iterator column_iterator; 01498 typedef StandardConstAccessor<T> DefaultAccessor; 01499 typedef StandardConstAccessor<T> default_accessor; 01500 typedef VigraTrueType hasConstantStrides; 01501 }; 01502 01503 #endif 01504 01505 /** \brief Simulate an image where each pixel contains its coordinate. 01506 01507 CoordinateIterator used to be a separate class, 01508 but has now become an alias for \ref vigra::Diff2D. This is possible because 01509 Diff2D now provides all the necessary functionality. 01510 01511 CoordinateIterator behaves like a read-only \ref vigra::ImageIterator for 01512 an image in which each pixel contains its coordinate. This is useful for 01513 algorithms that need access to the current pixel's location. 01514 For example, you can use CoordinateIterator/Diff2D to 01515 find the center of mass of an image region. To implement this, 01516 we first need a functor for center-of-mass calculations: 01517 01518 \code 01519 01520 struct CenterOfMassFunctor 01521 { 01522 CenterOfMassFunctor() 01523 : x(0.0), y(0.0), size(0) 01524 {} 01525 01526 void operator()(Diff2d const& diff) 01527 { 01528 ++size; 01529 x += diff.x; 01530 y += diff.y; 01531 } 01532 01533 float xCenter() const 01534 { return x / size; } 01535 01536 float yCenter() const 01537 { return y / size; } 01538 01539 float x; 01540 float y; 01541 int size; 01542 }; 01543 \endcode 01544 01545 Using this functor, we find the center of mass like so: 01546 01547 \code 01548 vigra::BImage img(w,h); 01549 ... // mark a region in the image with '1', background with '0' 01550 01551 CenterOfMassFunctor center; 01552 01553 vigra::inspectImageIf( 01554 srcIterRange(Diff2D(), Diff2D() + img.size()), 01555 srcImage(img), 01556 center); 01557 01558 std::cout << "Center of mass: " << center.xCenter() << 01559 ", " << center.yCenter() << std::endl; 01560 \endcode 01561 01562 <b>\#include</b> <<a href="imageiterator_8hxx-source.html">vigra/imageiterator.hxx</a>> 01563 01564 Namespace: vigra 01565 */ 01566 typedef Diff2D CoordinateIterator; 01567 01568 //@} 01569 01570 } // namespace vigra 01571 01572 #endif // VIGRA_IMAGEITERATOR_HXX
© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de) |
html generated using doxygen and Python
|