vigra - vigra/imageiterator.hxx Source File

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

vigra/imageiterator.hxx |

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