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

details vigra/imageiterator.hxx VIGRA

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

© Ullrich Köthe (koethe@informatik.uni-hamburg.de)
Cognitive Systems Group, University of Hamburg, Germany

html generated using doxygen and Python
VIGRA 1.3.2 (27 Jan 2005)