[ 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)