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