/************************************************************************/
/* */
/* 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_BASICIMAGEVIEW_HXX
#define VIGRA_BASICIMAGEVIEW_HXX
#include "vigra/imageiterator.hxx"
#include "vigra/initimage.hxx"
namespace vigra {
/********************************************************/
/* */
/* BasicImageView */
/* */
/********************************************************/
/** \brief BasicImage using foreign memory.
This class provides the same interface as \ref vigra::BasicImage
(with the exception of resize()) but the image's
memory is provided from the outside instead of allocated internally.
A BasicImageView can also be created from a
\ref vigra::MultiArrayView with the appropriate shape -- see
\ref MultiArrayToImage.
\#include "vigra/basicimageview.hxx"
Namespace: vigra
*/
template
class BasicImageView
{
public:
/** the BasicImageView's pixel type
*/
typedef PIXELTYPE value_type;
/** the BasicImageView's pixel type
*/
typedef PIXELTYPE PixelType;
/** the BasicImageView's reference type (i.e. the
return type of image[diff] and image(dx,dy))
*/
typedef PIXELTYPE & reference;
/** the BasicImageView's const reference type (i.e. the
return type of image[diff] and image(dx,dy) when image is const)
*/
typedef PIXELTYPE const & const_reference;
/** the BasicImageView's pointer type
*/
typedef PIXELTYPE * pointer;
/** the BasicImageView's const pointer type
*/
typedef PIXELTYPE const * const_pointer;
/** the BasicImageView's 1D random access iterator
(note: lower case 'iterator' is a STL compatible 1D random
access iterator, don't confuse with capitalized Iterator)
*/
typedef PIXELTYPE * iterator;
/** deprecated, use iterator instead
*/
typedef PIXELTYPE * ScanOrderIterator;
/** the BasicImageView's 1D random access const iterator
(note: lower case 'const_iterator' is a STL compatible 1D
random access const iterator)
*/
typedef PIXELTYPE const * const_iterator;
/** deprecated, use const_iterator instead
*/
typedef PIXELTYPE const * ConstScanOrderIterator;
/** the BasicImageView's 2D random access iterator ('traverser')
*/
typedef ImageIterator traverser;
/** deprecated, use traverser instead
*/
typedef ImageIterator Iterator;
/** the BasicImageView's 2D random access const iterator ('const traverser')
*/
typedef ConstImageIterator const_traverser;
/** deprecated, use const_traverser instead
*/
typedef ConstImageIterator ConstIterator;
/** the row iterator associated with the traverser
*/
typedef typename traverser::row_iterator row_iterator;
/** the const row iterator associated with the const_traverser
*/
typedef typename const_traverser::row_iterator const_row_iterator;
/** the column iterator associated with the traverser
*/
typedef typename traverser::column_iterator column_iterator;
/** the const column iterator associated with the const_traverser
*/
typedef typename const_traverser::column_iterator const_column_iterator;
/** the BasicImageView's difference type (argument type of image[diff])
*/
typedef Diff2D difference_type;
/** the BasicImageView's size type (result type of image.size())
*/
typedef Size2D size_type;
/** the BasicImageView's default accessor
*/
typedef typename
IteratorTraits::DefaultAccessor Accessor;
/** the BasicImageView's default const accessor
*/
typedef typename
IteratorTraits::DefaultAccessor ConstAccessor;
/** construct image of size 0x0
*/
BasicImageView()
: data_(0),
width_(0),
height_(0),
stride_(0)
{}
/** construct view of size w x h
*/
BasicImageView(const_pointer data, int w, int h, int stride = 0)
: data_(const_cast(data)),
width_(w),
height_(h),
stride_(stride == 0 ? w : stride)
{}
/** construct view of size size.x x size.y
*/
BasicImageView(const_pointer data, difference_type const & size, int stride = 0)
: data_(const_cast(data)),
width_(size.x),
height_(size.y),
stride_(stride == 0 ? size.x : stride)
{}
/** set Image with const value
*/
BasicImageView & init(value_type const & pixel)
{
initImage(upperLeft(), lowerRight(), accessor(), pixel);
return *this;
}
/** width of Image
*/
int width() const
{
return width_;
}
/** height of Image
*/
int height() const
{
return height_;
}
/** stride of Image.
Memory offset between the start of two successive rows.
*/
int stride() const
{
return stride_;
}
/** size of Image
*/
size_type size() const
{
return size_type(width(), height());
}
/** test whether a given coordinate is inside the image
*/
bool isInside(difference_type const & d) const
{
return d.x >= 0 && d.y >= 0 &&
d.x < width() && d.y < height();
}
/** access pixel at given location.
usage: value_type value = image[Diff2D(1,2)]
*/
reference operator[](difference_type const & d)
{
return data_[d.y*stride_ + d.x];
}
/** read pixel at given location.
usage: value_type value = image[Diff2D(1,2)]
*/
const_reference operator[](difference_type const & d) const
{
return data_[d.y*stride_ + d.x];
}
/** access pixel at given location.
usage: value_type value = image(1,2)
*/
reference operator()(int dx, int dy)
{
return data_[dy*stride_ + dx];
}
/** read pixel at given location.
usage: value_type value = image(1,2)
*/
const_reference operator()(int dx, int dy) const
{
return data_[dy*stride_ + dx];
}
/** access pixel at given location.
Note that the 'x' index is the trailing index.
usage: value_type value = image[2][1]
*/
pointer operator[](int dy)
{
return data_ + dy*stride_;
}
/** read pixel at given location.
Note that the 'x' index is the trailing index.
usage: value_type value = image[2][1]
*/
const_pointer operator[](int dy) const
{
return data_ + dy*stride_;
}
/** init 2D random access iterator poining to upper left pixel
*/
traverser upperLeft()
{
return traverser(data_, stride_);
}
/** init 2D random access iterator poining to
pixel(width, height), i.e. one pixel right and below lower right
corner of the image as is common in C/C++.
*/
traverser lowerRight()
{
return upperLeft() + size();
}
/** init 2D random access const iterator poining to upper left pixel
*/
const_traverser upperLeft() const
{
return const_traverser(data_, stride_);
}
/** init 2D random access const iterator poining to
pixel(width, height), i.e. one pixel right and below lower right
corner of the image as is common in C/C++.
*/
const_traverser lowerRight() const
{
return upperLeft() + size();
}
/** init 1D random access iterator pointing to first pixel.
Note: Only works if stride equals width.
*/
iterator begin()
{
vigra_precondition(stride_ == width_,
"BasicImageView::begin(): "
"can only create scan order iterator if width() == stride().");
return data_;
}
/** init 1D random access iterator pointing past the end.
Note: Only works if stride equals width.
*/
iterator end()
{
vigra_precondition(stride_ == width_,
"BasicImageView::end(): "
"can only create scan order iterator if width() == stride().");
return data_ + width() * height();
}
/** init 1D random access const iterator pointing to first pixel.
Note: Only works if stride equals width.
*/
const_iterator begin() const
{
vigra_precondition(stride_ == width_,
"BasicImageView::begin(): "
"can only create scan order iterator if width() == stride().");
return data_;
}
/** init 1D random access const iterator pointing past the end.
Note: Only works if stride equals width.
*/
const_iterator end() const
{
vigra_precondition(stride_ == width_,
"BasicImageView::end(): "
"can only create scan order iterator if width() == stride().");
return data_ + width() * height();
}
/** init 1D random access iterator pointing to first pixel of row \a y
*/
row_iterator rowBegin(int y)
{
return data_ + stride_ * y;
}
/** init 1D random access iterator pointing past the end of row \a y
*/
row_iterator rowEnd(int y)
{
return rowBegin(y) + width();
}
/** init 1D random access const iterator pointing to first pixel of row \a y
*/
const_row_iterator rowBegin(int y) const
{
return data_ + stride_ * y;
}
/** init 1D random access const iterator pointing past the end of row \a y
*/
const_row_iterator rowEnd(int y) const
{
return rowBegin(y) + width();
}
/** init 1D random access iterator pointing to first pixel of column \a x
*/
column_iterator columnBegin(int x)
{
typedef typename column_iterator::BaseType Iter;
return column_iterator(Iter(data_ + x, stride_));
}
/** init 1D random access iterator pointing past the end of column \a x
*/
column_iterator columnEnd(int x)
{
return columnBegin(x) + height();
}
/** init 1D random access const iterator pointing to first pixel of column \a x
*/
const_column_iterator columnBegin(int x) const
{
typedef typename const_column_iterator::BaseType Iter;
return const_column_iterator(Iter(data_ + x, stride_));
}
/** init 1D random access const iterator pointing past the end of column \a x
*/
const_column_iterator columnEnd(int x) const
{
return columnBegin(x) + height();
}
/** get a pointer to the internal data
*/
const_pointer data() const
{
return data_;
}
/** return default accessor
*/
Accessor accessor()
{
return Accessor();
}
/** return default const accessor
*/
ConstAccessor accessor() const
{
return ConstAccessor();
}
private:
pointer data_;
int width_, height_, stride_;
};
/********************************************************/
/* */
/* argument object factories */
/* */
/********************************************************/
template
inline triple::const_traverser,
typename BasicImageView::const_traverser, Accessor>
srcImageRange(BasicImageView const & img, Accessor a)
{
return triple::const_traverser,
typename BasicImageView::const_traverser,
Accessor>(img.upperLeft(),
img.lowerRight(),
a);
}
template
inline pair::const_traverser, Accessor>
srcImage(BasicImageView const & img, Accessor a)
{
return pair::const_traverser,
Accessor>(img.upperLeft(), a);
}
template
inline triple::traverser,
typename BasicImageView::traverser, Accessor>
destImageRange(BasicImageView & img, Accessor a)
{
return triple::traverser,
typename BasicImageView::traverser,
Accessor>(img.upperLeft(),
img.lowerRight(),
a);
}
template
inline pair::traverser, Accessor>
destImage(BasicImageView & img, Accessor a)
{
return pair::traverser,
Accessor>(img.upperLeft(), a);
}
template
inline pair::const_traverser, Accessor>
maskImage(BasicImageView const & img, Accessor a)
{
return pair::const_traverser,
Accessor>(img.upperLeft(), a);
}
/****************************************************************/
template
inline triple::const_traverser,
typename BasicImageView::const_traverser,
typename BasicImageView::ConstAccessor>
srcImageRange(BasicImageView const & img)
{
return triple::const_traverser,
typename BasicImageView::const_traverser,
typename BasicImageView::ConstAccessor>(img.upperLeft(),
img.lowerRight(),
img.accessor());
}
template
inline pair< typename BasicImageView::const_traverser,
typename BasicImageView::ConstAccessor>
srcImage(BasicImageView const & img)
{
return pair::const_traverser,
typename BasicImageView::ConstAccessor>(img.upperLeft(),
img.accessor());
}
template
inline triple< typename BasicImageView::traverser,
typename BasicImageView::traverser,
typename BasicImageView::Accessor>
destImageRange(BasicImageView & img)
{
return triple::traverser,
typename BasicImageView::traverser,
typename BasicImageView::Accessor>(img.upperLeft(),
img.lowerRight(),
img.accessor());
}
template
inline pair< typename BasicImageView::traverser,
typename BasicImageView::Accessor>
destImage(BasicImageView & img)
{
return pair::traverser,
typename BasicImageView::Accessor>(img.upperLeft(),
img.accessor());
}
template
inline pair< typename BasicImageView::const_traverser,
typename BasicImageView::ConstAccessor>
maskImage(BasicImageView const & img)
{
return pair::const_traverser,
typename BasicImageView::ConstAccessor>(img.upperLeft(),
img.accessor());
}
} // namespace vigra
#endif /* VIGRA_BASICIMAGEVIEW_HXX */