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