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