[ 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.2.0, Aug 07 2003 )                                    */
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         int operator-(type const & rhs) const
00471          { return current_ - rhs.current_; }
00472 
00473         T operator()() const
00474         { return current_; }
00475 
00476         T operator()(int d) const
00477         { return current_ + d; }
00478         
00479         T current_;
00480     };
00481 };
00482 
00483 template <>
00484 class DirectionSelector<StridedArrayTag>
00485 {
00486   public:
00487 
00488     template <class T>
00489     class type
00490     {
00491       public:
00492         type(int stride, T base = 0)
00493         : stride_(stride),
00494           current_(base)
00495         {}
00496 
00497         type(type const & rhs)
00498         : stride_(rhs.stride_),
00499           current_(rhs.current_)
00500         {}
00501         
00502         type & operator=(type const & rhs)
00503         {
00504             stride_ = rhs.stride_;
00505             current_ = rhs.current_;
00506             return *this;
00507         }
00508 
00509         void operator++() {current_ += stride_; }
00510         void operator++(int) {current_ += stride_; }
00511         void operator--() {current_ -= stride_; }
00512         void operator--(int) {current_ -= stride_; }
00513         void operator+=(int dy) {current_ += dy*stride_; }
00514         void operator-=(int dy) {current_ -= dy*stride_; }
00515 
00516         bool operator==(type const & rhs) const
00517          { return (current_ == rhs.current_); }
00518 
00519         bool operator!=(type const & rhs) const
00520          { return (current_ != rhs.current_); }
00521 
00522         bool operator<(type const & rhs) const
00523          { return (current_ < rhs.current_); }
00524 
00525         int operator-(type const & rhs) const
00526          { return (current_ - rhs.current_) / stride_; }
00527 
00528         T operator()() const
00529         { return current_; }
00530 
00531         T operator()(int d) const
00532         { return current_ + d*stride_; }
00533 
00534         int stride_;
00535         T current_;
00536     };
00537 };
00538 
00539 template <class StridedOrUnstrided>
00540 class LinearIteratorSelector;
00541 
00542 template <>
00543 class LinearIteratorSelector<UnstridedArrayTag>
00544 {
00545   public:
00546     template <class IMAGEITERATOR>
00547     class type
00548     {
00549       public:
00550         typedef typename IMAGEITERATOR::pointer res;
00551         
00552         template <class DirSelect>
00553         static res construct(typename IMAGEITERATOR::pointer data, DirSelect const &)
00554         {
00555             return data;
00556         }
00557     };
00558 };
00559 
00560 template <>
00561 class LinearIteratorSelector<StridedArrayTag>
00562 {
00563   public:
00564     template <class IMAGEITERATOR>
00565     class type
00566     {
00567       public:
00568         typedef IteratorAdaptor<StridedIteratorPolicy<IMAGEITERATOR> > res;
00569         
00570         template <class DirSelect>
00571         static res construct(typename IMAGEITERATOR::pointer data, DirSelect const & d)
00572         {
00573             typedef typename res::BaseType Base;
00574             return res(Base(data, d.stride_));
00575         }
00576     };
00577 };
00578 
00579 
00580 } // namespace detail
00581 
00582 /********************************************************/
00583 /*                                                      */
00584 /*                      ImageIteratorBase               */
00585 /*                                                      */
00586 /********************************************************/
00587 
00588 /** \brief Base class for 2D random access iterators.
00589 
00590     This class contains the navigational part of the iterator.
00591     Use derived classes to specifiy the access to the pixels.
00592 
00593     <b>\#include</b> "<a href="imageiterator_8hxx-source.html">vigra/imageiterator.hxx</a>"
00594 
00595     Namespace: vigra
00596 
00597     The usage examples assume that you constructed two iterators like
00598     this:
00599 
00600     \code
00601     vigra::ImageIteratorBase<SomePixelType> iterator(base, width);
00602     vigra::ImageIteratorBase<SomePixelType> iterator1(base, width);
00603     \endcode
00604 
00605     See the paper: U. Koethe:
00606     <a href="documents/GenericProg2D.ps">Reusable Algorithms in Image Processing</a>
00607     for a discussion of the concepts behind ImageIterators.
00608 
00609 */
00610 template <class IMAGEITERATOR,
00611           class PIXELTYPE, class REFERENCE, class POINTER,
00612           class StridedOrUnstrided = UnstridedArrayTag>
00613 class ImageIteratorBase
00614 {
00615     typedef typename 
00616         detail::LinearIteratorSelector<StridedOrUnstrided>::template type<ImageIteratorBase>
00617         RowIteratorSelector;
00618     typedef typename 
00619         detail::LinearIteratorSelector<StridedArrayTag>::template type<ImageIteratorBase>
00620         ColumnIteratorSelector;
00621   public:
00622     typedef ImageIteratorBase<IMAGEITERATOR,
00623                  PIXELTYPE, REFERENCE, POINTER, StridedOrUnstrided> self_type;
00624 
00625         /** The underlying image's pixel type.
00626         */
00627     typedef PIXELTYPE value_type;
00628 
00629         /** deprecated, use <TT>value_type</TT> instead.
00630         */
00631     typedef PIXELTYPE PixelType;
00632 
00633         /** the iterator's reference type (return type of <TT>*iter</TT>)
00634         */
00635     typedef REFERENCE            reference;
00636 
00637         /** the iterator's index reference type (return type of <TT>iter[diff]</TT>)
00638         */
00639     typedef REFERENCE            index_reference;
00640 
00641         /** the iterator's pointer type (return type of <TT>iter.operator->()</TT>)
00642         */
00643     typedef POINTER              pointer;
00644 
00645         /** the iterator's difference type (argument type of <TT>iter[diff]</TT>)
00646         */
00647     typedef Diff2D               difference_type;
00648 
00649         /** the iterator tag (image traverser)
00650         */
00651     typedef image_traverser_tag  iterator_category;
00652 
00653         /** The associated row iterator.
00654         */
00655     typedef typename RowIteratorSelector::res row_iterator;
00656 
00657         /** The associated column iterator.
00658         */
00659     typedef typename ColumnIteratorSelector::res column_iterator;
00660 
00661         /** Let operations act in X direction
00662         */
00663     typedef typename 
00664         detail::DirectionSelector<StridedOrUnstrided>::template type<pointer> MoveX;
00665 
00666         /** Let operations act in Y direction
00667         */
00668     typedef typename 
00669         detail::DirectionSelector<StridedArrayTag>::template type<int> MoveY;
00670 
00671     /** @name Comparison of Iterators */
00672     //@{
00673         /** usage: <TT> iterator == iterator1 </TT>
00674         */
00675     bool operator==(ImageIteratorBase const & rhs) const
00676     {
00677         return (x == rhs.x) && (y == rhs.y);
00678     }
00679 
00680         /** usage: <TT> iterator != iterator1 </TT>
00681         */
00682     bool operator!=(ImageIteratorBase const & rhs) const
00683     {
00684         return (x != rhs.x) || (y != rhs.y);
00685     }
00686 
00687         /** usage: <TT> Diff2D dist = iterator - iterator1 </TT>
00688         */
00689     difference_type operator-(ImageIteratorBase const & rhs) const
00690     {
00691         return difference_type(x - rhs.x, y - rhs.y);
00692     }
00693 
00694     //@}
00695 
00696     /** @name Specify coordinate to operate on */
00697     //@{
00698         /** Refer to iterator's x coordinate.
00699             Usage examples:<br>
00700             \code
00701             ++iterator.x;        // move one step to the right
00702             --iterator.x;        // move one step to the left
00703             iterator.x += dx;    // move dx steps to the right
00704             iterator.x -= dx;    // move dx steps to the left
00705             bool notAtEndOfRow = iterator.x < lowerRight.x;   // compare x coordinates of two iterators
00706             int width = lowerRight.x - upperLeft.x;           // calculate difference of x coordinates
00707                                                               // between two iterators
00708             \endcode
00709         */
00710     MoveX x;
00711         /** Refer to iterator's y coordinate.
00712             Usage examples:<br>
00713             \code
00714             ++iterator.y;        // move one step down
00715             --iterator.y;        // move one step up
00716             iterator.y += dy;    // move dy steps down
00717             iterator.y -= dy;    // move dy steps up
00718             bool notAtEndOfColumn = iterator.y < lowerRight.y; // compare y coordinates of two iterators
00719             int height = lowerRight.y - upperLeft.y;           // calculate difference of y coordinates
00720                                                                // between two iterators
00721             \endcode
00722         */
00723     MoveY y;
00724     //@}
00725 
00726   protected:
00727         /** Construct from raw memory with a vertical stride of <TT>ystride</TT>.
00728         <TT>ystride</TT> must equal the physical image width (row length), 
00729         even if the iterator will only be used for a sub image. This constructor
00730         must only be called for unstrided iterators 
00731         (<tt>StridedOrUnstrided == UnstridedArrayTag</tt>)
00732         */
00733     ImageIteratorBase(pointer base, int ystride)
00734     : x(base),
00735       y(ystride)
00736     {}
00737 
00738         /** Construct from raw memory with a horizontal stride of <TT>xstride</TT>
00739         and a vertical stride of <TT>ystride</TT>. This constructor 
00740         may be used for iterators that shall skip pixels. Thus, it
00741         must only be called for strided iterators 
00742         (<tt>StridedOrUnstrided == StridedArrayTag</tt>)
00743         */
00744     ImageIteratorBase(pointer base, int xstride, int ystride)
00745     : x(xstride, base),
00746       y(ystride)
00747     {}
00748 
00749         /** Copy constructor */
00750     ImageIteratorBase(ImageIteratorBase const & rhs)
00751     : x(rhs.x),
00752       y(rhs.y)
00753     {}
00754 
00755         /** Default constructor */
00756     ImageIteratorBase()
00757     : x(0),
00758       y(0)
00759     {}
00760 
00761         /** Copy assignment */
00762     ImageIteratorBase & operator=(ImageIteratorBase const & rhs)
00763     {
00764         if(this != &rhs)
00765         {
00766             x = rhs.x;
00767             y = rhs.y;
00768         }
00769         return *this;
00770     }
00771 
00772   public:
00773     /** @name Random navigation */
00774     //@{
00775         /** Add offset via Diff2D
00776         */
00777     IMAGEITERATOR & operator+=(difference_type const & s)
00778     {
00779         x += s.x;
00780         y += s.y;
00781         return static_cast<IMAGEITERATOR &>(*this);
00782     }
00783         /** Subtract offset via Diff2D
00784         */
00785     IMAGEITERATOR & operator-=(difference_type const & s)
00786     {
00787         x -= s.x;
00788         y -= s.y;
00789         return static_cast<IMAGEITERATOR &>(*this);
00790     }
00791 
00792         /** Add a distance
00793         */
00794     IMAGEITERATOR operator+(difference_type const & s) const
00795     {
00796         IMAGEITERATOR ret(static_cast<IMAGEITERATOR const &>(*this));
00797 
00798         ret += s;
00799 
00800         return ret;
00801     }
00802 
00803         /** Subtract a distance
00804         */
00805     IMAGEITERATOR operator-(difference_type const & s) const
00806     {
00807         IMAGEITERATOR ret(static_cast<IMAGEITERATOR const &>(*this));
00808 
00809         ret -= s;
00810 
00811         return ret;
00812     }
00813    //@}
00814 
00815     /** @name Access the Pixels */
00816     //@{
00817         /** Access current pixel. <br>
00818             usage: <TT> SomePixelType value = *iterator </TT>
00819         */
00820     reference operator*() const
00821     {
00822         return *current();
00823     }
00824 
00825         /** Call member of current pixel. <br>
00826             usage: <TT> iterator->pixelMemberFunction() </TT>
00827         */
00828     pointer operator->() const
00829     {
00830         return current();
00831     }
00832 
00833         /** Access pixel at offset from current location. <br>
00834             usage: <TT> SomePixelType value = iterator[Diff2D(1,1)] </TT>
00835         */
00836     index_reference operator[](Diff2D const & d) const
00837     {
00838         return *current(d.x, d.y);
00839     }
00840 
00841         /** Access pixel at offset (dx, dy) from current location. <br>
00842             usage: <TT> SomePixelType value = iterator(dx, dy) </TT>
00843         */
00844     index_reference operator()(int dx, int dy) const
00845     {
00846         return *current(dx, dy);
00847     }
00848 
00849         /** Read pixel with offset [dy][dx] from current pixel.
00850             Note that the 'x' index is the trailing index. <br>
00851             usage: <TT> SomePixelType value = iterator[dy][dx] </TT>
00852         */
00853     pointer operator[](int dy) const
00854     {
00855         return x() + y(dy);
00856     }
00857     //@}
00858 
00859     row_iterator rowIterator() const
00860     { 
00861         return RowIteratorSelector::construct(current(), x);
00862     }
00863 
00864     column_iterator columnIterator() const
00865     {
00866         return ColumnIteratorSelector::construct(current(), y);
00867     }
00868 
00869   private:
00870 
00871     pointer current() const
00872         { return x() + y(); }
00873 
00874     pointer current(int dx, int dy) const
00875         { return x(dx) + y(dy); }
00876 };
00877 
00878 /********************************************************/
00879 /*                                                      */
00880 /*                      ImageIterator                   */
00881 /*                                                      */
00882 /********************************************************/
00883 
00884 /** \brief Standard 2D random access iterator for images that store the
00885     data in a linear array.
00886 
00887     Most functions and local types are inherited from ImageIteratorBase.
00888 
00889     See the paper: U. Koethe:
00890     <a href="documents/GenericProg2D.ps">Reusable Algorithms in Image Processing</a>
00891     for a discussion of the concepts behind ImageIterators.
00892 
00893     <b>\#include</b> "<a href="imageiterator_8hxx-source.html">vigra/imageiterator.hxx</a>"
00894 
00895     Namespace: vigra
00896 
00897 */
00898 template <class PIXELTYPE>
00899 class ImageIterator
00900 : public ImageIteratorBase<ImageIterator<PIXELTYPE>,
00901                            PIXELTYPE, PIXELTYPE &, PIXELTYPE *>
00902 {
00903   public:
00904     typedef ImageIteratorBase<ImageIterator<PIXELTYPE>,
00905                               PIXELTYPE, PIXELTYPE &, PIXELTYPE *> Base;
00906 
00907     typedef typename Base::pointer         pointer;
00908     typedef typename Base::difference_type difference_type;
00909 
00910         /** Construct from raw memory with a vertical stride of <TT>ystride</TT>.
00911         <TT>ystride</TT> must equal the physical image width (row length), 
00912         even if the iterator will only be used for a sub image.
00913         If the raw memory is encapsulated in an image object this
00914         object should have a factory function that constructs the
00915         iterator.
00916         */
00917     ImageIterator(pointer base, int ystride)
00918     : Base(base, ystride)
00919     {}
00920 
00921         /** Default constructor */
00922     ImageIterator()
00923     : Base()
00924     {}
00925 
00926 };
00927 
00928 /********************************************************/
00929 /*                                                      */
00930 /*                   ConstImageIterator                 */
00931 /*                                                      */
00932 /********************************************************/
00933 
00934 /** \brief Standard 2D random access const iterator for images that
00935     store the data as a linear array.
00936 
00937     Most functions are inherited from ImageIteratorBase.
00938 
00939     <b>\#include</b> "<a href="imageiterator_8hxx-source.html">vigra/imageiterator.hxx</a>"
00940 
00941     Namespace: vigra
00942 
00943 */
00944 template <class PIXELTYPE>
00945 class ConstImageIterator
00946 : public ImageIteratorBase<ConstImageIterator<PIXELTYPE>,
00947                            PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *>
00948 {
00949   public:
00950     typedef ImageIteratorBase<ConstImageIterator<PIXELTYPE>,
00951                         PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *> Base;
00952 
00953     typedef typename Base::pointer         pointer;
00954     typedef typename Base::difference_type difference_type;
00955 
00956         /** Construct from raw memory with a vertical stride of <TT>ystride</TT>.
00957         <TT>ystride</TT> must equal the physical image width (row length), 
00958         even if the iterator will only be used for a sub image.
00959         If the raw memory is encapsulated in an image object this
00960         object should have a factory function that constructs the
00961         iterator.
00962         */
00963     ConstImageIterator(pointer base, int ystride)
00964     : Base(base, ystride)
00965     {}
00966 
00967     ConstImageIterator(ImageIterator<PIXELTYPE> const & o)
00968     : Base(o.x, o.y)
00969     {}
00970 
00971         /** Default constructor */
00972     ConstImageIterator()
00973     : Base()
00974     {}
00975 
00976     ConstImageIterator & operator=(ImageIterator<PIXELTYPE> const & o)
00977     {
00978         x = o.x;
00979         y = o.y;
00980         return *this;
00981     }
00982 };
00983 
00984 /********************************************************/
00985 /*                                                      */
00986 /*                 StridedImageIterator                 */
00987 /*                                                      */
00988 /********************************************************/
00989 
00990 /** \brief Iterator to be used when pixels are to be skipped.
00991 
00992     This iterator can be used when some pixels shall be automatically skipped, for example
00993     if an image is to be sub-sampled: instead of advancing to the next pixel,
00994     <tt>++iterator.x</tt> jumps to the pixel at a horizontal offset of <tt>xskip</tt>.
00995     Likewise with <tt>yskip</tt> in vertical direction. Most functions and local types 
00996     are inherited from ImageIteratorBase.
00997     
00998     <b> Usage:</b>
00999     
01000     \code
01001     BImage img(w,h);
01002     ...
01003     int xskip = 2, yskip = 2;
01004     int wskip = w / xskip + 1, hskip = h / yskip + 1;
01005     
01006     StridedImageIterator<BImage::value_type> upperLeft(&img(0,0), w, xskip, yskip);
01007     StridedImageIterator<BImage::value_type> lowerRight = upperLeft + Diff2D(wskip, hskip);
01008     
01009     // now navigation with upperLeft and lowerRight lets the image appear to have half
01010     // the original resolution in either dimension
01011     \endcode
01012 
01013     <b>\#include</b> "<a href="imageiterator_8hxx-source.html">vigra/imageiterator.hxx</a>"
01014 
01015     Namespace: vigra
01016 
01017 */
01018 template <class PIXELTYPE>
01019 class StridedImageIterator
01020 : public ImageIteratorBase<StridedImageIterator<PIXELTYPE>,
01021                            PIXELTYPE, PIXELTYPE &, PIXELTYPE *, StridedArrayTag>
01022 {
01023   public:
01024     typedef ImageIteratorBase<StridedImageIterator<PIXELTYPE>,
01025                               PIXELTYPE, PIXELTYPE &, PIXELTYPE *, StridedArrayTag> Base;
01026 
01027     typedef typename Base::pointer         pointer;
01028     typedef typename Base::difference_type difference_type;
01029 
01030         /** Construct from raw memory with a vertical stride of <TT>ystride</TT>,
01031         jumping by <tt>xskip</tt> horizontally and <tt>yskip</tt> vertically. 
01032         <tt>ystride</tt> must be the physical width (row length) of the image.
01033         */
01034     StridedImageIterator(pointer base, int ystride, int xskip, int yskip)
01035     : Base(base, xskip, ystride*yskip)
01036     {}
01037 
01038         /** Default constructor */
01039     StridedImageIterator()
01040     : Base()
01041     {}
01042 
01043 };
01044 
01045 /********************************************************/
01046 /*                                                      */
01047 /*               ConstStridedImageIterator              */
01048 /*                                                      */
01049 /********************************************************/
01050 
01051 /** \brief Const iterator to be used when pixels are to be skipped.
01052 
01053     This iterator can be used when some pixels shall be automatically skipped, for example
01054     if an image is to be sub-sampled: instead of advancing to the next pixel,
01055     <tt>++iterator.x</tt> jumps to the pixel at a horizontal offset of <tt>xskip</tt>.
01056     Likewise with <tt>yskip</tt> in vertical direction. Most functions and local types 
01057     are inherited from ImageIteratorBase.
01058     
01059     <b> Usage:</b>
01060     
01061     \code
01062     BImage img(w,h);
01063     ...
01064     int xskip = 2, yskip = 2;
01065     int wskip = w / xskip + 1, hskip = h / yskip + 1;
01066     
01067     ConstStridedImageIterator<BImage::value_type> upperLeft(&img(0,0), w, xskip, yskip);
01068     ConstStridedImageIterator<BImage::value_type> lowerRight = upperLeft + Diff2D(wskip, hskip);
01069     
01070     // now navigation with upperLeft and lowerRight lets the image appear to have half
01071     // the original resolution in either dimension
01072     \endcode
01073 
01074     <b>\#include</b> "<a href="imageiterator_8hxx-source.html">vigra/imageiterator.hxx</a>"
01075 
01076     Namespace: vigra
01077 
01078 */
01079 template <class PIXELTYPE>
01080 class ConstStridedImageIterator
01081 : public ImageIteratorBase<ConstStridedImageIterator<PIXELTYPE>,
01082                            PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *,
01083                            StridedArrayTag>
01084 {
01085   public:
01086     typedef ImageIteratorBase<ConstStridedImageIterator<PIXELTYPE>,
01087                         PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *,
01088                         StridedArrayTag> Base;
01089 
01090     typedef typename Base::pointer         pointer;
01091     typedef typename Base::difference_type difference_type;
01092 
01093         /** Construct from raw memory with a vertical stride of <TT>ystride</TT>,
01094         jumping by <tt>xskip</tt> horizontally and <tt>yskip</tt> vertically. 
01095         <tt>ystride</tt> must be the physical width (row length) of the image.
01096         */
01097     ConstStridedImageIterator(pointer base, int ystride, int xskip, int yskip)
01098     : Base(base, xskip, ystride*yskip)
01099     {}
01100 
01101         /** Copy-construct from mutable iterator */
01102     ConstStridedImageIterator(StridedImageIterator<PIXELTYPE> const & o)
01103     : Base(o.x, o.y)
01104     {}
01105 
01106         /** Default constructor */
01107     ConstStridedImageIterator()
01108     : Base()
01109     {}
01110 
01111         /** Assign mutable iterator */
01112     ConstStridedImageIterator & operator=(StridedImageIterator<PIXELTYPE> const & o)
01113     {
01114         x = o.x;
01115         y = o.y;
01116         return *this;
01117     }
01118 };
01119 
01120 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
01121 
01122 template <class T>
01123 struct IteratorTraits<ImageIterator<T> >
01124 {
01125     typedef ImageIterator<T>                     Iterator;
01126     typedef ImageIterator<T>                     iterator;
01127     typedef typename iterator::iterator_category iterator_category;
01128     typedef typename iterator::value_type        value_type;
01129     typedef typename iterator::reference         reference;
01130     typedef typename iterator::index_reference   index_reference;
01131     typedef typename iterator::pointer           pointer;
01132     typedef typename iterator::difference_type   difference_type;
01133     typedef typename iterator::row_iterator      row_iterator;
01134     typedef typename iterator::column_iterator   column_iterator;
01135     typedef StandardAccessor<T>                  DefaultAccessor;
01136     typedef StandardAccessor<T>                  default_accessor;
01137 };
01138 
01139 template <class T>
01140 struct IteratorTraits<ConstImageIterator<T> >
01141 {
01142     typedef ConstImageIterator<T>                Iterator;
01143     typedef ConstImageIterator<T>                iterator;
01144     typedef typename iterator::iterator_category iterator_category;
01145     typedef typename iterator::value_type        value_type;
01146     typedef typename iterator::reference         reference;
01147     typedef typename iterator::index_reference   index_reference;
01148     typedef typename iterator::pointer           pointer;
01149     typedef typename iterator::difference_type   difference_type;
01150     typedef typename iterator::row_iterator      row_iterator;
01151     typedef typename iterator::column_iterator   column_iterator;
01152     typedef StandardConstAccessor<T>             DefaultAccessor;
01153     typedef StandardConstAccessor<T>             default_accessor;
01154 };
01155 
01156 template <class T>
01157 struct IteratorTraits<StridedImageIterator<T> >
01158 {
01159     typedef StridedImageIterator<T>              Iterator;
01160     typedef StridedImageIterator<T>              iterator;
01161     typedef typename iterator::iterator_category iterator_category;
01162     typedef typename iterator::value_type        value_type;
01163     typedef typename iterator::reference         reference;
01164     typedef typename iterator::index_reference   index_reference;
01165     typedef typename iterator::pointer           pointer;
01166     typedef typename iterator::difference_type   difference_type;
01167     typedef typename iterator::row_iterator      row_iterator;
01168     typedef typename iterator::column_iterator   column_iterator;
01169     typedef StandardAccessor<T>                  DefaultAccessor;
01170     typedef StandardAccessor<T>                  default_accessor;
01171 };
01172 
01173 template <class T>
01174 struct IteratorTraits<ConstStridedImageIterator<T> >
01175 {
01176     typedef ConstStridedImageIterator<T>         Iterator;
01177     typedef ConstStridedImageIterator<T>         iterator;
01178     typedef typename iterator::iterator_category iterator_category;
01179     typedef typename iterator::value_type        value_type;
01180     typedef typename iterator::reference         reference;
01181     typedef typename iterator::index_reference   index_reference;
01182     typedef typename iterator::pointer           pointer;
01183     typedef typename iterator::difference_type   difference_type;
01184     typedef typename iterator::row_iterator      row_iterator;
01185     typedef typename iterator::column_iterator   column_iterator;
01186     typedef StandardConstAccessor<T>             DefaultAccessor;
01187     typedef StandardConstAccessor<T>             default_accessor;
01188 };
01189 
01190 #endif
01191 
01192 #define VIGRA_DEFINE_ITERATORTRAITS(ITERATOR, VALUETYPE, ACCESSOR) \
01193     template<> \
01194     struct IteratorTraits<ITERATOR<VALUETYPE > > \
01195     { \
01196         typedef ITERATOR<VALUETYPE >                  Iterator; \
01197         typedef ITERATOR<VALUETYPE >                  iterator; \
01198         typedef iterator::iterator_category           iterator_category; \
01199         typedef iterator::value_type                  value_type; \
01200         typedef iterator::reference                   reference; \
01201         typedef iterator::index_reference             index_reference; \
01202         typedef iterator::pointer                     pointer; \
01203         typedef iterator::difference_type             difference_type; \
01204         typedef iterator::row_iterator                row_iterator; \
01205         typedef iterator::column_iterator             column_iterator; \
01206         typedef ACCESSOR<VALUETYPE >                  default_accessor; \
01207         typedef ACCESSOR<VALUETYPE >                  DefaultAccessor; \
01208     };
01209 
01210 VIGRA_DEFINE_ITERATORTRAITS(ImageIterator, unsigned char, StandardValueAccessor)
01211 VIGRA_DEFINE_ITERATORTRAITS(ConstImageIterator, unsigned char, StandardConstValueAccessor)
01212 VIGRA_DEFINE_ITERATORTRAITS(ImageIterator, short, StandardValueAccessor)
01213 VIGRA_DEFINE_ITERATORTRAITS(ConstImageIterator, short, StandardConstValueAccessor)
01214 VIGRA_DEFINE_ITERATORTRAITS(ImageIterator, int, StandardValueAccessor)
01215 VIGRA_DEFINE_ITERATORTRAITS(ConstImageIterator, int, StandardConstValueAccessor)
01216 VIGRA_DEFINE_ITERATORTRAITS(ImageIterator, float, StandardValueAccessor)
01217 VIGRA_DEFINE_ITERATORTRAITS(ConstImageIterator, float, StandardConstValueAccessor)
01218 VIGRA_DEFINE_ITERATORTRAITS(ImageIterator, double, StandardValueAccessor)
01219 VIGRA_DEFINE_ITERATORTRAITS(ConstImageIterator, double, StandardConstValueAccessor)
01220 
01221 template <class T> class RGBValue;
01222 template <class T> class RGBAccessor;
01223 
01224 VIGRA_DEFINE_ITERATORTRAITS(ImageIterator, RGBValue<unsigned char>, RGBAccessor)
01225 VIGRA_DEFINE_ITERATORTRAITS(ConstImageIterator, RGBValue<unsigned char>, RGBAccessor)
01226 VIGRA_DEFINE_ITERATORTRAITS(ImageIterator, RGBValue<int>, RGBAccessor)
01227 VIGRA_DEFINE_ITERATORTRAITS(ConstImageIterator, RGBValue<int>, RGBAccessor)
01228 VIGRA_DEFINE_ITERATORTRAITS(ImageIterator, RGBValue<float>, RGBAccessor)
01229 VIGRA_DEFINE_ITERATORTRAITS(ConstImageIterator, RGBValue<float>, RGBAccessor)
01230 VIGRA_DEFINE_ITERATORTRAITS(ImageIterator, RGBValue<double>, RGBAccessor)
01231 VIGRA_DEFINE_ITERATORTRAITS(ConstImageIterator, RGBValue<double>, RGBAccessor)
01232 
01233 template <class VALUETYPE, int SIZE>
01234 class TinyVector;
01235 
01236 #define VIGRA_PIXELTYPE TinyVector<float, 2>
01237 VIGRA_DEFINE_ITERATORTRAITS(ImageIterator, VIGRA_PIXELTYPE, VectorAccessor)
01238 VIGRA_DEFINE_ITERATORTRAITS(ConstImageIterator, VIGRA_PIXELTYPE, VectorAccessor)
01239 #undef VIGRA_PIXELTYPE
01240 #define VIGRA_PIXELTYPE TinyVector<float, 3>
01241 VIGRA_DEFINE_ITERATORTRAITS(ImageIterator, VIGRA_PIXELTYPE, VectorAccessor)
01242 VIGRA_DEFINE_ITERATORTRAITS(ConstImageIterator, VIGRA_PIXELTYPE, VectorAccessor)
01243 #undef VIGRA_PIXELTYPE
01244 #define VIGRA_PIXELTYPE TinyVector<float, 4>
01245 VIGRA_DEFINE_ITERATORTRAITS(ImageIterator, VIGRA_PIXELTYPE, VectorAccessor)
01246 VIGRA_DEFINE_ITERATORTRAITS(ConstImageIterator, VIGRA_PIXELTYPE, VectorAccessor)
01247 #undef VIGRA_PIXELTYPE
01248 #define VIGRA_PIXELTYPE TinyVector<double, 2>
01249 VIGRA_DEFINE_ITERATORTRAITS(ImageIterator, VIGRA_PIXELTYPE, VectorAccessor)
01250 VIGRA_DEFINE_ITERATORTRAITS(ConstImageIterator, VIGRA_PIXELTYPE, VectorAccessor)
01251 #undef VIGRA_PIXELTYPE
01252 #define VIGRA_PIXELTYPE TinyVector<double, 3>
01253 VIGRA_DEFINE_ITERATORTRAITS(ImageIterator, VIGRA_PIXELTYPE, VectorAccessor)
01254 VIGRA_DEFINE_ITERATORTRAITS(ConstImageIterator, VIGRA_PIXELTYPE, VectorAccessor)
01255 #undef VIGRA_PIXELTYPE
01256 #define VIGRA_PIXELTYPE TinyVector<double, 4>
01257 VIGRA_DEFINE_ITERATORTRAITS(ImageIterator, VIGRA_PIXELTYPE, VectorAccessor)
01258 VIGRA_DEFINE_ITERATORTRAITS(ConstImageIterator, VIGRA_PIXELTYPE, VectorAccessor)
01259 #undef VIGRA_PIXELTYPE
01260 
01261 #undef VIGRA_DEFINE_ITERATORTRAITS
01262 
01263 template <class PIXELTYPE>
01264 class ConstValueIteratorPolicy
01265 {
01266   public:
01267 
01268     typedef PIXELTYPE                       value_type;
01269     typedef int                             difference_type;
01270     typedef PIXELTYPE const &               reference;
01271     typedef PIXELTYPE const &               index_reference;
01272     typedef PIXELTYPE const *               pointer;
01273     typedef std::random_access_iterator_tag iterator_category;
01274 
01275     struct BaseType
01276     {
01277         BaseType(PIXELTYPE const & v = PIXELTYPE(), int p = 0)
01278         : value(v), pos(p)
01279         {}
01280 
01281         PIXELTYPE value;
01282         int pos;
01283     };
01284 
01285     static void initialize(BaseType & d) {}
01286 
01287     static reference dereference(BaseType const & d)
01288         { return d.value; }
01289 
01290     static index_reference dereference(BaseType d, difference_type)
01291     {
01292         return d.value;
01293     }
01294 
01295     static bool equal(BaseType const & d1, BaseType const & d2)
01296         { return d1.pos == d2.pos; }
01297 
01298     static bool less(BaseType const & d1, BaseType const & d2)
01299         { return d1.pos < d2.pos; }
01300 
01301     static difference_type difference(BaseType const & d1, BaseType const & d2)
01302         { return d1.pos - d2.pos; }
01303 
01304     static void increment(BaseType & d)
01305         { ++d.pos; }
01306 
01307     static void decrement(BaseType & d)
01308         { --d.pos; }
01309 
01310     static void advance(BaseType & d, difference_type n)
01311         { d.pos += n; }
01312 };
01313 
01314 /********************************************************/
01315 /*                                                      */
01316 /*                 ConstValueIterator                   */
01317 /*                                                      */
01318 /********************************************************/
01319 
01320 /** \brief Iterator that always returns the constant specified in the
01321     constructor.
01322 
01323     This iterator can be used to simulate an image that
01324     does not actually exist.
01325 
01326     <b>\#include</b> "<a href="imageiterator_8hxx-source.html">vigra/imageiterator.hxx</a>"
01327 
01328     Namespace: vigra
01329 
01330 */
01331 template <class PIXELTYPE>
01332 class ConstValueIterator
01333 {
01334   public:
01335         /** The type of the constant the iterator holds.
01336         */
01337    typedef PIXELTYPE value_type;
01338 
01339         /** The type of the constant the iterator holds.
01340         */
01341     typedef PIXELTYPE PixelType;
01342 
01343         /** the iterator's reference type (return type of <TT>*iter</TT>)
01344         */
01345     typedef PIXELTYPE const &    reference;
01346 
01347         /** the iterator's index reference type (return type of <TT>iter[diff]</TT>)
01348         */
01349     typedef PIXELTYPE const &    index_reference;
01350 
01351         /** the iterator's pointer type (return type of <TT>iter.operator->()</TT>)
01352         */
01353     typedef PIXELTYPE const *    pointer;
01354 
01355         /** the iterator's difference type (argument type of <TT>iter[diff]</TT>)
01356         */
01357     typedef Diff2D               difference_type;
01358 
01359         /** the iterator tag (image traverser)
01360         */
01361     typedef image_traverser_tag  iterator_category;
01362 
01363         /** The associated row iterator.
01364         */
01365     typedef IteratorAdaptor<ConstValueIteratorPolicy<PIXELTYPE> > row_iterator;
01366 
01367         /** The associated column iterator.
01368         */
01369     typedef IteratorAdaptor<ConstValueIteratorPolicy<PIXELTYPE> > column_iterator;
01370 
01371         /** Let operations act in X direction
01372         */
01373     typedef int MoveX;
01374 
01375         /** Let operations act in Y direction
01376         */
01377     typedef int MoveY;
01378 
01379         /** Default Constructor. (the constant is set to
01380         <TT>NumericTraits<PIXELTYPE>::zero()</TT> )
01381         */
01382     ConstValueIterator()
01383     : value_(NumericTraits<PIXELTYPE>::zero()), x(0), y(0)
01384     {}
01385 
01386         /** Construct with given constant.
01387         */
01388     ConstValueIterator(PixelType const & v)
01389     : value_(v), x(0), y(0)
01390     {}
01391 
01392         /** Copy Constructor.
01393        */
01394     ConstValueIterator(ConstValueIterator const & v)
01395     : value_(v.value_), x(v.x), y(v.y)
01396     {}
01397 
01398         /** Copy Assigment.
01399         */
01400     ConstValueIterator & operator=(ConstValueIterator const & v)
01401     {
01402         if(this != &v)
01403         {
01404             value_ = v.value_;
01405             x = v.x;
01406             y = v.y;
01407         }
01408         return *this;
01409     }
01410 
01411         /** Move iterator by specified distance.
01412         */
01413     ConstValueIterator & operator+=(Diff2D const & d)
01414     {
01415         x += d.x;
01416         y += d.y;
01417         return *this;
01418     }
01419 
01420         /** Move iterator by specified distance.
01421         */
01422     ConstValueIterator & operator-=(Diff2D const & d)
01423     {
01424         x -= d.x;
01425         y -= d.y;
01426         return *this;
01427     }
01428 
01429         /** Create iterator at specified distance.
01430         */
01431     ConstValueIterator operator+(Diff2D const & d) const
01432     {
01433         ConstValueIterator ret(*this);
01434         ret += d;
01435         return ret;
01436     }
01437 
01438         /** Create iterator at specified distance.
01439         */
01440     ConstValueIterator operator-(Diff2D const & d) const
01441     {
01442         ConstValueIterator ret(*this);
01443         ret -= d;
01444         return ret;
01445     }
01446 
01447         /** Compute distance between two iterators
01448         */
01449     Diff2D operator-(ConstValueIterator const & r) const
01450     {
01451         return Diff2D(x - r.x, y - r.y);
01452     }
01453 
01454         /** Equality.
01455         */
01456     bool operator==(ConstValueIterator const & r) const
01457     {
01458         return (x == r.x) && (y == r.y);
01459     }
01460 
01461         /** Inequality.
01462         */
01463     bool operator!=(ConstValueIterator const & r) const
01464     {
01465         return (x != r.x) || (y != r.y);
01466     }
01467 
01468         /** Read current pixel (return specified constant).
01469         */
01470     reference operator*() const
01471     {
01472         return value_;
01473     }
01474 
01475         /** Call member function for stored constant.
01476         */
01477     pointer operator->() const
01478     {
01479         return &value_;
01480     }
01481 
01482         /** Read pixel at a distance (return specified constant).
01483         */
01484     index_reference operator()(int const &, int const &) const
01485     {
01486         return value_;
01487     }
01488 
01489         /** Read pixel at a distance (return specified constant).
01490         */
01491     index_reference operator[](Diff2D const &) const
01492     {
01493         return value_;
01494     }
01495 
01496         /** Get row iterator at current position (which will also hold the constant).
01497         */
01498     row_iterator rowIterator() const
01499         { return row_iterator(typename row_iterator::BaseType(value_, x)); }
01500 
01501         /** Get column iterator at current position (which will also hold the constant).
01502         */
01503     column_iterator columnIterator() const
01504         { return column_iterator(typename column_iterator::BaseType(value_, y)); }
01505 
01506     /** @name Specify coordinate direction for navigation commands */
01507     //@{
01508         /// refer to x coordinate
01509     int x;
01510         /// refer to y coordinate
01511     int y;
01512     //@}
01513 
01514   private:
01515 
01516     PixelType value_;
01517 };
01518 
01519 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
01520 
01521 template <class T>
01522 struct IteratorTraits<ConstValueIterator<T> >
01523 {
01524     typedef ConstValueIterator<T>                  Iterator;
01525     typedef Iterator                               iterator;
01526     typedef typename iterator::iterator_category   iterator_category;
01527     typedef typename iterator::value_type          value_type;
01528     typedef typename iterator::reference           reference;
01529     typedef typename iterator::index_reference     index_reference;
01530     typedef typename iterator::pointer             pointer;
01531     typedef typename iterator::difference_type     difference_type;
01532     typedef typename iterator::row_iterator        row_iterator;
01533     typedef typename iterator::column_iterator     column_iterator;
01534     typedef StandardConstAccessor<T>               DefaultAccessor;
01535     typedef StandardConstAccessor<T>               default_accessor;
01536 };
01537 
01538 #endif
01539 
01540 typedef Diff2D CoordinateIterator;
01541 
01542 /** \class CoordinateIterator
01543 
01544     This used to be a separate class,
01545     but has now become an alias for \ref vigra::Diff2D. This is possible because
01546     Diff2D now provides all the necessary functionality.
01547 
01548     CoordinateIterator behaves like a read-only \ref ImageIterator for
01549     an image in which each pixel contains its coordinate. This is useful for
01550     algorithms that need access to the current pixel's location.
01551     For example, you can use CoordinateIterator/Diff2D to
01552     find the center of mass of an image region. To implement this,
01553     we first need a functor for center-of-mass calculations:
01554 
01555     \code
01556 
01557     struct CenterOfMassFunctor
01558     {
01559         CenterOfMassFunctor()
01560         : x(0.0), y(0.0), size(0)
01561         {}
01562 
01563         void operator()(Diff2d const& diff)
01564         {
01565             ++size;
01566             x += diff.x;
01567             y += diff.y;
01568         }
01569 
01570         float xCenter() const
01571         {   return x / size; }
01572 
01573         float yCenter() const
01574         {   return y / size; }
01575 
01576         float x;
01577         float y;
01578         int size;
01579     };
01580     \endcode
01581 
01582     Using this functor, we find the center of mass like so:
01583 
01584     \code
01585     vigra::BImage img(w,h);
01586     ... // mark a region in the image with '1', background with '0'
01587 
01588     CenterOfMassFunctor center;
01589 
01590     vigra::inspectImageIf(
01591         srcIterRange(Diff2D(), Diff2D() + img.size()),
01592         srcImage(img),
01593         center);
01594 
01595     std::cout << "Center of mass: " << center.xCenter() <<
01596                                 ", " << center.yCenter() << std::endl;
01597     \endcode
01598 
01599     <b>\#include</b> "<a href="imageiterator_8hxx-source.html">vigra/imageiterator.hxx</a>"
01600 
01601     Namespace: vigra
01602 
01603     \brief Simulate an image where each pixel contains its coordinate
01604 */
01605 
01606 //@}
01607 
01608 } // namespace vigra
01609 
01610 #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.2.0 (7 Aug 2003)