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

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

html generated using doxygen and Python
VIGRA 1.5.0 (7 Dec 2006)