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