[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

vigra/imageiterator.hxx VIGRA

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

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de)
Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany

html generated using doxygen and Python
vigra 1.9.0 (Tue Nov 6 2012)