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