/************************************************************************/ /* */ /* Copyright 1998-2002 by Ullrich Koethe */ /* Cognitive Systems Group, University of Hamburg, Germany */ /* */ /* This file is part of the VIGRA computer vision library. */ /* The VIGRA Website is */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* Please direct questions, bug reports, and contributions to */ /* koethe@informatik.uni-hamburg.de or */ /* vigra@kogs1.informatik.uni-hamburg.de */ /* */ /* Permission is hereby granted, free of charge, to any person */ /* obtaining a copy of this software and associated documentation */ /* files (the "Software"), to deal in the Software without */ /* restriction, including without limitation the rights to use, */ /* copy, modify, merge, publish, distribute, sublicense, and/or */ /* sell copies of the Software, and to permit persons to whom the */ /* Software is furnished to do so, subject to the following */ /* conditions: */ /* */ /* The above copyright notice and this permission notice shall be */ /* included in all copies or substantial portions of the */ /* Software. */ /* */ /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */ /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */ /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */ /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */ /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */ /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */ /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */ /* OTHER DEALINGS IN THE SOFTWARE. */ /* */ /************************************************************************/ #ifndef VIGRA_IMAGEITERATOR_HXX #define VIGRA_IMAGEITERATOR_HXX #include "vigra/utilities.hxx" #include "vigra/accessor.hxx" #include "vigra/iteratortraits.hxx" #include "vigra/metaprogramming.hxx" namespace vigra { template class StridedIteratorPolicy { public: typedef IMAGEITERATOR ImageIterator; typedef typename IMAGEITERATOR::value_type value_type; typedef typename IMAGEITERATOR::difference_type::MoveY difference_type; typedef typename IMAGEITERATOR::reference reference; typedef typename IMAGEITERATOR::index_reference index_reference; typedef typename IMAGEITERATOR::pointer pointer; typedef std::random_access_iterator_tag iterator_category; struct BaseType { explicit BaseType(pointer c = 0, difference_type stride = 0) : current_(c), stride_(stride) {} pointer current_; difference_type stride_; }; static void initialize(BaseType & /* d */) {} static reference dereference(BaseType const & d) { return const_cast(*d.current_); } static index_reference dereference(BaseType const & d, difference_type n) { return const_cast(d.current_[n*d.stride_]); } static bool equal(BaseType const & d1, BaseType const & d2) { return d1.current_ == d2.current_; } static bool less(BaseType const & d1, BaseType const & d2) { return d1.current_ < d2.current_; } static difference_type difference(BaseType const & d1, BaseType const & d2) { return (d1.current_ - d2.current_) / d1.stride_; } static void increment(BaseType & d) { d.current_ += d.stride_; } static void decrement(BaseType & d) { d.current_ -= d.stride_; } static void advance(BaseType & d, difference_type n) { d.current_ += d.stride_*n; } }; /** \addtogroup ImageIterators Image Iterators \brief General image iterator definition and implementations.

The following tables describe the general requirements for image iterators and their iterator traits. The iterator implementations provided here may be used for any image data type that stores its data as a linear array of pixels. The array will be interpreted as a row-major matrix with a particular width.

Requirements for Image Iterators

\endhtmlonly \endhtmlonly
\htmlonly \endhtmlonly Local Types \htmlonly \endhtmlonly Meaning \htmlonly
\htmlonly \endhtmlonly ImageIterator::value_typethe underlying image's pixel type
\htmlonly \endhtmlonly ImageIterator::PixelTypethe underlying image's pixel type
\htmlonly \endhtmlonly ImageIterator::reference the iterator's reference type (return type of *iter). Will be value_type & for a mutable iterator, and convertible to value_type const & for a const iterator.
\htmlonly \endhtmlonly ImageIterator::index_reference the iterator's index reference type (return type of iter[diff]). Will be value_type & for a mutable iterator, and convertible to value_type const & for a const iterator.
\htmlonly \endhtmlonly ImageIterator::pointer the iterator's pointer type (return type of iter.operator->()). Will be value_type * for a mutable iterator, and convertible to value_type const * for a const iterator.
\htmlonly \endhtmlonly ImageIterator::difference_type the iterator's difference type (vigra::Diff2D)
\htmlonly \endhtmlonly ImageIterator::iterator_category the iterator tag (vigra::image_traverser_tag)
\htmlonly \endhtmlonly ImageIterator::row_iteratorthe associated row iterator
\htmlonly \endhtmlonly ImageIterator::column_iteratorthe associated column iterator
\htmlonly \endhtmlonly ImageIterator::MoveXtype of the horizontal navigator
\htmlonly \endhtmlonly ImageIterator::MoveYtype of the vertical navigator
\htmlonly \endhtmlonly Operation \htmlonly \endhtmlonly Result \htmlonly \endhtmlonly Semantics \htmlonly
++i.x
i.x--
voidincrement x-coordinate
--i.x
i.x--
voiddecrement x-coordinate
i.x += dxImageIterator::MoveX & add dx to x-coordinate
i.x -= dxImageIterator::MoveX & subtract dx from x-coordinate
i.x - j.xint difference of the x-coordinates of i and j
i.x = j.xImageIterator::MoveX &i.x += j.x - i.x
i.x == i.yboolj.x - i.x == 0
i.x < j.xboolj.x - i.x > 0
++i.y
i.y++
voidincrement y-coordinate
--i.y
i.y--
voiddecrement y-coordinate
i.y += dyImageIterator::MoveY & add dy to y-coordinate
i.y -= dyImageIterator::MoveY & subtract dy from y-coordinate
i.y - j.yint difference of the y-coordinates of i and j
i.y = j.yImageIterator::MoveY &i.y += j.y - i.y
i.y == j.yboolj.y - i.y == 0
i.y < j.yboolj.y - i.y > 0
\htmlonly \endhtmlonly ImageIterator k(i)copy constructor
k = iImageIterator &assignment
\htmlonly \endhtmlonly ImageIterator kdefault constructor
\htmlonly \endhtmlonly ImageIterator::row_iterator r(i)construction of row iterator
\htmlonly \endhtmlonly ImageIterator::column_iterator c(i)construction of column iterator
i += diffImageIterator & { i.x += diff.x
i.y += diff.y; }
i -= diffImageIterator & { i.x -= diff.x
i.y -= diff.y; }
i + diffImageIterator { ImageIterator tmp(i);
tmp += diff;
return tmp; }
i - diffImageIterator { ImageIterator tmp(i);
tmp -= diff;
return tmp; }
i - jImageIterator::difference_type { ImageIterator::difference_type tmp(i.x - j.x, i.y - j.y);
return tmp; }
i == jbool i.x == j.x && i.y == j.y
*iImageIterator::reference access the current pixel
i[diff]ImageIterator::index_reference access pixel at offset diff
i(dx, dy)ImageIterator::index_reference access pixel at offset (dx, dy)
i->member()depends on operation call member function of underlying pixel type via operator-> of iterator
\htmlonly \endhtmlonly i, j, k are of type ImageIterator
diff is of type ImageIterator::difference_type
dx, dy are of type int

Requirements for Image Iterator Traits

The following iterator traits must be defined for an image iterator:

\endhtmlonly
\htmlonly \endhtmlonly Types \htmlonly \endhtmlonly Meaning \htmlonly
IteratorTraits<ImageIterator>::Iteratorthe iterator type the traits are referring to
IteratorTraits<ImageIterator>::iteratorthe iterator type the traits are referring to
IteratorTraits<ImageIterator>::value_typethe underlying image's pixel type
IteratorTraits<ImageIterator>::reference the iterator's reference type (return type of *iter)
IteratorTraits<ImageIterator>::index_reference the iterator's index reference type (return type of iter[diff])
IteratorTraits<ImageIterator>::pointer the iterator's pointer type (return type of iter.operator->())
IteratorTraits<ImageIterator>::difference_type the iterator's difference type
IteratorTraits<ImageIterator>::iterator_category the iterator tag (vigra::image_traverser_tag)
IteratorTraits<ImageIterator>::row_iteratorthe associated row iterator
IteratorTraits<ImageIterator>::column_iteratorthe associated column iterator
IteratorTraits<ImageIterator>::DefaultAccessor the default accessor to be used with the iterator
IteratorTraits<ImageIterator>::default_accessor the default accessor to be used with the iterator
IteratorTraits<ImageIterator>::hasConstantStrides whether the iterator uses constant strides on the underlying memory (always VigraTrueType for ImageIterators).

*/ //@{ namespace detail { template class DirectionSelector; template <> class DirectionSelector { public: template class type { public: type(T base) : current_(base) {} type(type const & rhs) : current_(rhs.current_) {} type & operator=(type const & rhs) { current_ = rhs.current_; return *this; } void operator++() {++current_;} void operator++(int) {++current_;} void operator--() {--current_;} void operator--(int) {--current_;} void operator+=(int dx) {current_ += dx; } void operator-=(int dx) {current_ -= dx; } bool operator==(type const & rhs) const { return current_ == rhs.current_; } bool operator!=(type const & rhs) const { return current_ != rhs.current_; } bool operator<(type const & rhs) const { return current_ < rhs.current_; } bool operator<=(type const & rhs) const { return current_ <= rhs.current_; } bool operator>(type const & rhs) const { return current_ > rhs.current_; } bool operator>=(type const & rhs) const { return current_ >= rhs.current_; } int operator-(type const & rhs) const { return current_ - rhs.current_; } T operator()() const { return current_; } T operator()(int d) const { return current_ + d; } T current_; }; }; template <> class DirectionSelector { public: template class type { public: type(int stride, T base = 0) : stride_(stride), current_(base) {} type(type const & rhs) : stride_(rhs.stride_), current_(rhs.current_) {} type & operator=(type const & rhs) { stride_ = rhs.stride_; current_ = rhs.current_; return *this; } void operator++() {current_ += stride_; } void operator++(int) {current_ += stride_; } void operator--() {current_ -= stride_; } void operator--(int) {current_ -= stride_; } void operator+=(int dy) {current_ += dy*stride_; } void operator-=(int dy) {current_ -= dy*stride_; } bool operator==(type const & rhs) const { return (current_ == rhs.current_); } bool operator!=(type const & rhs) const { return (current_ != rhs.current_); } bool operator<(type const & rhs) const { return (current_ < rhs.current_); } bool operator<=(type const & rhs) const { return (current_ <= rhs.current_); } bool operator>(type const & rhs) const { return (current_ > rhs.current_); } bool operator>=(type const & rhs) const { return (current_ >= rhs.current_); } int operator-(type const & rhs) const { return (current_ - rhs.current_) / stride_; } T operator()() const { return current_; } T operator()(int d) const { return current_ + d*stride_; } int stride_; T current_; }; }; template class LinearIteratorSelector; template <> class LinearIteratorSelector { public: template class type { public: typedef typename IMAGEITERATOR::pointer res; template static res construct(typename IMAGEITERATOR::pointer data, DirSelect const &) { return data; } }; }; template <> class LinearIteratorSelector { public: template class type { public: typedef IteratorAdaptor > res; template static res construct(typename IMAGEITERATOR::pointer data, DirSelect const & d) { typedef typename res::BaseType Base; return res(Base(data, d.stride_)); } }; }; } // namespace detail /********************************************************/ /* */ /* ImageIteratorBase */ /* */ /********************************************************/ /** \brief Base class for 2D random access iterators. This class contains the navigational part of the iterator. It is usually not constructed directly, but via some derived class such as \ref ImageIterator or \ref StridedImageIterator. \#include "vigra/imageiterator.hxx" Namespace: vigra The usage examples assume that you constructed two iterators like this: \code vigra::ImageIterator iterator(base, width); vigra::ImageIterator iterator1(base, width); \endcode See the paper: U. Koethe: Reusable Algorithms in Image Processing for a discussion of the concepts behind ImageIterators. */ template class ImageIteratorBase { typedef typename detail::LinearIteratorSelector::template type RowIteratorSelector; typedef typename detail::LinearIteratorSelector::template type ColumnIteratorSelector; public: typedef ImageIteratorBase self_type; /** The underlying image's pixel type. */ typedef PIXELTYPE value_type; /** deprecated, use value_type instead. */ typedef PIXELTYPE PixelType; /** the iterator's reference type (return type of *iter) */ typedef REFERENCE reference; /** the iterator's index reference type (return type of iter[diff]) */ typedef REFERENCE index_reference; /** the iterator's pointer type (return type of iter.operator->()) */ typedef POINTER pointer; /** the iterator's difference type (argument type of iter[diff]) */ typedef Diff2D difference_type; /** the iterator tag (image traverser) */ typedef image_traverser_tag iterator_category; /** The associated row iterator. */ typedef typename RowIteratorSelector::res row_iterator; /** The associated column iterator. */ typedef typename ColumnIteratorSelector::res column_iterator; /** Let operations act in X direction */ typedef typename detail::DirectionSelector::template type MoveX; /** Let operations act in Y direction */ typedef typename detail::DirectionSelector::template type MoveY; /** @name Comparison of Iterators */ //@{ /** usage: iterator == iterator1 */ bool operator==(ImageIteratorBase const & rhs) const { return (x == rhs.x) && (y == rhs.y); } /** usage: iterator != iterator1 */ bool operator!=(ImageIteratorBase const & rhs) const { return (x != rhs.x) || (y != rhs.y); } /** usage: Diff2D dist = iterator - iterator1 */ difference_type operator-(ImageIteratorBase const & rhs) const { return difference_type(x - rhs.x, y - rhs.y); } //@} /** @name Specify coordinate to operate on */ //@{ /** Refer to iterator's x coordinate. Usage examples:
\code ++iterator.x; // move one step to the right --iterator.x; // move one step to the left iterator.x += dx; // move dx steps to the right iterator.x -= dx; // move dx steps to the left bool notAtEndOfRow = iterator.x < lowerRight.x; // compare x coordinates of two iterators int width = lowerRight.x - upperLeft.x; // calculate difference of x coordinates // between two iterators \endcode */ MoveX x; /** Refer to iterator's y coordinate. Usage examples:
\code ++iterator.y; // move one step down --iterator.y; // move one step up iterator.y += dy; // move dy steps down iterator.y -= dy; // move dy steps up bool notAtEndOfColumn = iterator.y < lowerRight.y; // compare y coordinates of two iterators int height = lowerRight.y - upperLeft.y; // calculate difference of y coordinates // between two iterators \endcode */ MoveY y; //@} protected: /** Construct from raw memory with a vertical stride of ystride. ystride must equal the physical image width (row length), even if the iterator will only be used for a sub image. This constructor must only be called for unstrided iterators (StridedOrUnstrided == UnstridedArrayTag) */ ImageIteratorBase(pointer base, int ystride) : x(base), y(ystride) {} /** Construct from raw memory with a horizontal stride of xstride and a vertical stride of ystride. This constructor may be used for iterators that shall skip pixels. Thus, it must only be called for strided iterators (StridedOrUnstrided == StridedArrayTag) */ ImageIteratorBase(pointer base, int xstride, int ystride) : x(xstride, base), y(ystride) {} /** Copy constructor */ ImageIteratorBase(ImageIteratorBase const & rhs) : x(rhs.x), y(rhs.y) {} /** Default constructor */ ImageIteratorBase() : x(0), y(0) {} /** Copy assignment */ ImageIteratorBase & operator=(ImageIteratorBase const & rhs) { if(this != &rhs) { x = rhs.x; y = rhs.y; } return *this; } public: /** @name Random navigation */ //@{ /** Add offset via Diff2D */ IMAGEITERATOR & operator+=(difference_type const & s) { x += s.x; y += s.y; return static_cast(*this); } /** Subtract offset via Diff2D */ IMAGEITERATOR & operator-=(difference_type const & s) { x -= s.x; y -= s.y; return static_cast(*this); } /** Add a distance */ IMAGEITERATOR operator+(difference_type const & s) const { IMAGEITERATOR ret(static_cast(*this)); ret += s; return ret; } /** Subtract a distance */ IMAGEITERATOR operator-(difference_type const & s) const { IMAGEITERATOR ret(static_cast(*this)); ret -= s; return ret; } //@} /** @name Access the Pixels */ //@{ /** Access current pixel.
usage: SomePixelType value = *iterator */ reference operator*() const { return *current(); } /** Call member of current pixel.
usage: iterator->pixelMemberFunction() */ pointer operator->() const { return current(); } /** Access pixel at offset from current location.
usage: SomePixelType value = iterator[Diff2D(1,1)] */ index_reference operator[](Diff2D const & d) const { return *current(d.x, d.y); } /** Access pixel at offset (dx, dy) from current location.
usage: SomePixelType value = iterator(dx, dy) */ index_reference operator()(int dx, int dy) const { return *current(dx, dy); } /** Read pixel with offset [dy][dx] from current pixel. Note that the 'x' index is the trailing index.
usage: SomePixelType value = iterator[dy][dx] */ pointer operator[](int dy) const { return x() + y(dy); } //@} row_iterator rowIterator() const { return RowIteratorSelector::construct(current(), x); } column_iterator columnIterator() const { return ColumnIteratorSelector::construct(current(), y); } private: pointer current() const { return x() + y(); } pointer current(int dx, int dy) const { return x(dx) + y(dy); } }; /********************************************************/ /* */ /* ImageIterator */ /* */ /********************************************************/ /** \brief Standard 2D random access iterator for images that store the data in a linear array. Most functions and local types are inherited from ImageIteratorBase. See the paper: U. Koethe: Reusable Algorithms in Image Processing for a discussion of the concepts behind ImageIterators. \#include "vigra/imageiterator.hxx" Namespace: vigra */ template class ImageIterator : public ImageIteratorBase, PIXELTYPE, PIXELTYPE &, PIXELTYPE *> { public: typedef ImageIteratorBase, PIXELTYPE, PIXELTYPE &, PIXELTYPE *> Base; typedef typename Base::pointer pointer; typedef typename Base::difference_type difference_type; /** Construct from raw memory with a vertical stride of ystride. ystride must equal the physical image width (row length), even if the iterator will only be used for a sub image. If the raw memory is encapsulated in an image object this object should have a factory function that constructs the iterator. */ ImageIterator(pointer base, int ystride) : Base(base, ystride) {} /** Default constructor */ ImageIterator() : Base() {} }; /********************************************************/ /* */ /* ConstImageIterator */ /* */ /********************************************************/ /** \brief Standard 2D random access const iterator for images that store the data as a linear array. Most functions are inherited from ImageIteratorBase. \#include "vigra/imageiterator.hxx" Namespace: vigra */ template class ConstImageIterator : public ImageIteratorBase, PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *> { public: typedef ImageIteratorBase, PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *> Base; typedef typename Base::pointer pointer; typedef typename Base::difference_type difference_type; /** Construct from raw memory with a vertical stride of ystride. ystride must equal the physical image width (row length), even if the iterator will only be used for a sub image. If the raw memory is encapsulated in an image object this object should have a factory function that constructs the iterator. */ ConstImageIterator(pointer base, int ystride) : Base(base, ystride) {} ConstImageIterator(ImageIterator const & o) : Base(o.x, o.y) {} /** Default constructor */ ConstImageIterator() : Base() {} ConstImageIterator & operator=(ImageIterator const & o) { Base::x = o.x; Base::y = o.y; return *this; } }; /********************************************************/ /* */ /* StridedImageIterator */ /* */ /********************************************************/ /** \brief Iterator to be used when pixels are to be skipped. This iterator can be used when some pixels shall be automatically skipped, for example if an image is to be sub-sampled: instead of advancing to the next pixel, ++iterator.x jumps to the pixel at a horizontal offset of xskip. Likewise with yskip in vertical direction. Most functions and local types are inherited from ImageIteratorBase. Usage: \code BImage img(w,h); ... int xskip = 2, yskip = 2; int wskip = w / xskip + 1, hskip = h / yskip + 1; StridedImageIterator upperLeft(&img(0,0), w, xskip, yskip); StridedImageIterator lowerRight = upperLeft + Diff2D(wskip, hskip); // now navigation with upperLeft and lowerRight lets the image appear to have half // the original resolution in either dimension \endcode \#include "vigra/imageiterator.hxx" Namespace: vigra */ template class StridedImageIterator : public ImageIteratorBase, PIXELTYPE, PIXELTYPE &, PIXELTYPE *, StridedArrayTag> { public: typedef ImageIteratorBase, PIXELTYPE, PIXELTYPE &, PIXELTYPE *, StridedArrayTag> Base; typedef typename Base::pointer pointer; typedef typename Base::difference_type difference_type; /** Construct from raw memory with a vertical stride of ystride, jumping by xskip horizontally and yskip vertically. ystride must be the physical width (row length) of the image. */ StridedImageIterator(pointer base, int ystride, int xskip, int yskip) : Base(base, xskip, ystride*yskip) {} /** Default constructor */ StridedImageIterator() : Base() {} }; /********************************************************/ /* */ /* ConstStridedImageIterator */ /* */ /********************************************************/ /** \brief Const iterator to be used when pixels are to be skipped. This iterator can be used when some pixels shall be automatically skipped, for example if an image is to be sub-sampled: instead of advancing to the next pixel, ++iterator.x jumps to the pixel at a horizontal offset of xskip. Likewise with yskip in vertical direction. Most functions and local types are inherited from ImageIteratorBase. Usage: \code BImage img(w,h); ... int xskip = 2, yskip = 2; int wskip = w / xskip + 1, hskip = h / yskip + 1; ConstStridedImageIterator upperLeft(&img(0,0), w, xskip, yskip); ConstStridedImageIterator lowerRight = upperLeft + Diff2D(wskip, hskip); // now navigation with upperLeft and lowerRight lets the image appear to have half // the original resolution in either dimension \endcode \#include "vigra/imageiterator.hxx" Namespace: vigra */ template class ConstStridedImageIterator : public ImageIteratorBase, PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *, StridedArrayTag> { public: typedef ImageIteratorBase, PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *, StridedArrayTag> Base; typedef typename Base::pointer pointer; typedef typename Base::difference_type difference_type; /** Construct from raw memory with a vertical stride of ystride, jumping by xskip horizontally and yskip vertically. ystride must be the physical width (row length) of the image. */ ConstStridedImageIterator(pointer base, int ystride, int xskip, int yskip) : Base(base, xskip, ystride*yskip) {} /** Copy-construct from mutable iterator */ ConstStridedImageIterator(StridedImageIterator const & o) : Base(o.x, o.y) {} /** Default constructor */ ConstStridedImageIterator() : Base() {} /** Assign mutable iterator */ ConstStridedImageIterator & operator=(StridedImageIterator const & o) { Base::x = o.x; Base::y = o.y; return *this; } }; /********************************************************/ /* */ /* definition of iterator traits */ /* */ /********************************************************/ #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION template struct IteratorTraits > : public IteratorTraitsBase > { typedef ImageIterator mutable_iterator; typedef ConstImageIterator const_iterator; typedef typename AccessorTraits::default_accessor DefaultAccessor; typedef DefaultAccessor default_accessor; typedef VigraTrueType hasConstantStrides; }; template struct IteratorTraits > : public IteratorTraitsBase > { typedef ImageIterator mutable_iterator; typedef ConstImageIterator const_iterator; typedef typename AccessorTraits::default_const_accessor DefaultAccessor; typedef DefaultAccessor default_accessor; typedef VigraTrueType hasConstantStrides; }; template struct IteratorTraits > : public IteratorTraitsBase > { typedef StridedImageIterator mutable_iterator; typedef ConstStridedImageIterator const_iterator; typedef typename AccessorTraits::default_accessor DefaultAccessor; typedef DefaultAccessor default_accessor; typedef VigraTrueType hasConstantStrides; }; template struct IteratorTraits > : public IteratorTraitsBase > { typedef StridedImageIterator mutable_iterator; typedef ConstStridedImageIterator const_iterator; typedef typename AccessorTraits::default_const_accessor DefaultAccessor; typedef DefaultAccessor default_accessor; typedef VigraTrueType hasConstantStrides; }; #else // NO_PARTIAL_TEMPLATE_SPECIALIZATION #define VIGRA_DEFINE_ITERATORTRAITS(VALUETYPE) \ template <> \ struct IteratorTraits > \ : public IteratorTraitsBase > \ { \ typedef ImageIterator mutable_iterator; \ typedef ConstImageIterator const_iterator; \ typedef typename AccessorTraits::default_accessor DefaultAccessor; \ typedef DefaultAccessor default_accessor; \ typedef VigraTrueType hasConstantStrides; \ }; \ \ template <> \ struct IteratorTraits > \ : public IteratorTraitsBase > \ { \ typedef ImageIterator mutable_iterator; \ typedef ConstImageIterator const_iterator; \ typedef typename AccessorTraits::default_const_accessor DefaultAccessor; \ typedef DefaultAccessor default_accessor; \ typedef VigraTrueType hasConstantStrides; \ }; \ template <> \ struct IteratorTraits > \ : public IteratorTraitsBase > \ { \ typedef StridedImageIterator mutable_iterator; \ typedef ConstStridedImageIterator const_iterator; \ typedef typename AccessorTraits::default_accessor DefaultAccessor; \ typedef DefaultAccessor default_accessor; \ typedef VigraTrueType hasConstantStrides; \ }; \ \ template <> \ struct IteratorTraits > \ : public IteratorTraitsBase > \ { \ typedef StridedImageIterator mutable_iterator; \ typedef ConstStridedImageIterator const_iterator; \ typedef typename AccessorTraits::default_const_accessor DefaultAccessor; \ typedef DefaultAccessor default_accessor; \ typedef VigraTrueType hasConstantStrides; \ }; VIGRA_DEFINE_ITERATORTRAITS(RGBValue) VIGRA_DEFINE_ITERATORTRAITS(RGBValue) VIGRA_DEFINE_ITERATORTRAITS(RGBValue) VIGRA_DEFINE_ITERATORTRAITS(RGBValue) VIGRA_DEFINE_ITERATORTRAITS(RGBValue) #define VIGRA_PIXELTYPE TinyVector VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) #undef VIGRA_PIXELTYPE #define VIGRA_PIXELTYPE TinyVector VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) #undef VIGRA_PIXELTYPE #define VIGRA_PIXELTYPE TinyVector VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) #undef VIGRA_PIXELTYPE #define VIGRA_PIXELTYPE TinyVector VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) #undef VIGRA_PIXELTYPE #define VIGRA_PIXELTYPE TinyVector VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) #undef VIGRA_PIXELTYPE #define VIGRA_PIXELTYPE TinyVector VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) #undef VIGRA_PIXELTYPE #define VIGRA_PIXELTYPE TinyVector VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) #undef VIGRA_PIXELTYPE #define VIGRA_PIXELTYPE TinyVector VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) #undef VIGRA_PIXELTYPE #define VIGRA_PIXELTYPE TinyVector VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) #undef VIGRA_PIXELTYPE #define VIGRA_PIXELTYPE TinyVector VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) #undef VIGRA_PIXELTYPE #define VIGRA_PIXELTYPE TinyVector VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) #undef VIGRA_PIXELTYPE #define VIGRA_PIXELTYPE TinyVector VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) #undef VIGRA_PIXELTYPE #define VIGRA_PIXELTYPE TinyVector VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) #undef VIGRA_PIXELTYPE #define VIGRA_PIXELTYPE TinyVector VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) #undef VIGRA_PIXELTYPE #define VIGRA_PIXELTYPE TinyVector VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) #undef VIGRA_PIXELTYPE #undef VIGRA_DEFINE_ITERATORTRAITS #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION template class ConstValueIteratorPolicy { public: typedef PIXELTYPE value_type; typedef int difference_type; typedef PIXELTYPE const & reference; typedef PIXELTYPE const & index_reference; typedef PIXELTYPE const * pointer; typedef std::random_access_iterator_tag iterator_category; struct BaseType { BaseType(PIXELTYPE const & v = PIXELTYPE(), int p = 0) : value(v), pos(p) {} PIXELTYPE value; int pos; }; static void initialize(BaseType & d) {} static reference dereference(BaseType const & d) { return d.value; } static index_reference dereference(BaseType d, difference_type) { return d.value; } static bool equal(BaseType const & d1, BaseType const & d2) { return d1.pos == d2.pos; } static bool less(BaseType const & d1, BaseType const & d2) { return d1.pos < d2.pos; } static difference_type difference(BaseType const & d1, BaseType const & d2) { return d1.pos - d2.pos; } static void increment(BaseType & d) { ++d.pos; } static void decrement(BaseType & d) { --d.pos; } static void advance(BaseType & d, difference_type n) { d.pos += n; } }; /********************************************************/ /* */ /* ConstValueIterator */ /* */ /********************************************************/ /** \brief Iterator that always returns the constant specified in the constructor. This iterator can be used to simulate an image that does not actually exist. \#include "vigra/imageiterator.hxx" Namespace: vigra */ template class ConstValueIterator { public: /** The type of the constant the iterator holds. */ typedef PIXELTYPE value_type; /** The type of the constant the iterator holds. */ typedef PIXELTYPE PixelType; /** the iterator's reference type (return type of *iter) */ typedef PIXELTYPE const & reference; /** the iterator's index reference type (return type of iter[diff]) */ typedef PIXELTYPE const & index_reference; /** the iterator's pointer type (return type of iter.operator->()) */ typedef PIXELTYPE const * pointer; /** the iterator's difference type (argument type of iter[diff]) */ typedef Diff2D difference_type; /** the iterator tag (image traverser) */ typedef image_traverser_tag iterator_category; /** The associated row iterator. */ typedef IteratorAdaptor > row_iterator; /** The associated column iterator. */ typedef IteratorAdaptor > column_iterator; /** Let operations act in X direction */ typedef int MoveX; /** Let operations act in Y direction */ typedef int MoveY; /** Default Constructor. (the constant is set to NumericTraits::zero() ) */ ConstValueIterator() : value_(NumericTraits::zero()), x(0), y(0) {} /** Construct with given constant. */ ConstValueIterator(PixelType const & v) : value_(v), x(0), y(0) {} /** Copy Constructor. */ ConstValueIterator(ConstValueIterator const & v) : value_(v.value_), x(v.x), y(v.y) {} /** Copy Assigment. */ ConstValueIterator & operator=(ConstValueIterator const & v) { if(this != &v) { value_ = v.value_; x = v.x; y = v.y; } return *this; } /** Move iterator by specified distance. */ ConstValueIterator & operator+=(Diff2D const & d) { x += d.x; y += d.y; return *this; } /** Move iterator by specified distance. */ ConstValueIterator & operator-=(Diff2D const & d) { x -= d.x; y -= d.y; return *this; } /** Create iterator at specified distance. */ ConstValueIterator operator+(Diff2D const & d) const { ConstValueIterator ret(*this); ret += d; return ret; } /** Create iterator at specified distance. */ ConstValueIterator operator-(Diff2D const & d) const { ConstValueIterator ret(*this); ret -= d; return ret; } /** Compute distance between two iterators */ Diff2D operator-(ConstValueIterator const & r) const { return Diff2D(x - r.x, y - r.y); } /** Equality. */ bool operator==(ConstValueIterator const & r) const { return (x == r.x) && (y == r.y); } /** Inequality. */ bool operator!=(ConstValueIterator const & r) const { return (x != r.x) || (y != r.y); } /** Read current pixel (return specified constant). */ reference operator*() const { return value_; } /** Call member function for stored constant. */ pointer operator->() const { return &value_; } /** Read pixel at a distance (return specified constant). */ index_reference operator()(int const &, int const &) const { return value_; } /** Read pixel at a distance (return specified constant). */ index_reference operator[](Diff2D const &) const { return value_; } /** Get row iterator at current position (which will also hold the constant). */ row_iterator rowIterator() const { return row_iterator(typename row_iterator::BaseType(value_, x)); } /** Get column iterator at current position (which will also hold the constant). */ column_iterator columnIterator() const { return column_iterator(typename column_iterator::BaseType(value_, y)); } /** @name Specify coordinate direction for navigation commands */ //@{ /// refer to x coordinate int x; /// refer to y coordinate int y; //@} private: PixelType value_; }; #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION template struct IteratorTraits > { typedef ConstValueIterator Iterator; typedef Iterator iterator; typedef typename iterator::iterator_category iterator_category; typedef typename iterator::value_type value_type; typedef typename iterator::reference reference; typedef typename iterator::index_reference index_reference; typedef typename iterator::pointer pointer; typedef typename iterator::difference_type difference_type; typedef typename iterator::row_iterator row_iterator; typedef typename iterator::column_iterator column_iterator; typedef StandardConstAccessor DefaultAccessor; typedef StandardConstAccessor default_accessor; typedef VigraTrueType hasConstantStrides; }; #endif typedef Diff2D CoordinateIterator; /** \class CoordinateIterator This used to be a separate class, but has now become an alias for \ref vigra::Diff2D. This is possible because Diff2D now provides all the necessary functionality. CoordinateIterator behaves like a read-only \ref ImageIterator for an image in which each pixel contains its coordinate. This is useful for algorithms that need access to the current pixel's location. For example, you can use CoordinateIterator/Diff2D to find the center of mass of an image region. To implement this, we first need a functor for center-of-mass calculations: \code struct CenterOfMassFunctor { CenterOfMassFunctor() : x(0.0), y(0.0), size(0) {} void operator()(Diff2d const& diff) { ++size; x += diff.x; y += diff.y; } float xCenter() const { return x / size; } float yCenter() const { return y / size; } float x; float y; int size; }; \endcode Using this functor, we find the center of mass like so: \code vigra::BImage img(w,h); ... // mark a region in the image with '1', background with '0' CenterOfMassFunctor center; vigra::inspectImageIf( srcIterRange(Diff2D(), Diff2D() + img.size()), srcImage(img), center); std::cout << "Center of mass: " << center.xCenter() << ", " << center.yCenter() << std::endl; \endcode \#include "vigra/imageiterator.hxx" Namespace: vigra \brief Simulate an image where each pixel contains its coordinate */ //@} } // namespace vigra #endif // VIGRA_IMAGEITERATOR_HXX