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

vigra/imageiterator.hxx

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

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

html generated using doxygen and Python
VIGRA 1.6.0 (13 Aug 2008)