/************************************************************************/
/* */
/* 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_INTERPOLATING_ACCESSOR_HXX
#define VIGRA_INTERPOLATING_ACCESSOR_HXX
#include "vigra/accessor.hxx"
#include "vigra/diff2d.hxx"
namespace vigra {
/** \addtogroup DataAccessors
*/
//@{
/********************************************************/
/* */
/* BilinearInterpolatingAccessor */
/* */
/********************************************************/
/** \brief Bilinear interpolation at non-integer positions.
This accessor allows an image be accessed at arbitrary non-integer
coordinates and performs an bi-linear interpolation to
obtain a pixel value.
It uses the given ACCESSOR (which is usually the
accessor originally associated with the iterator)
to access data.
\#include "vigra/accessor.hxx"
Namespace: vigra
Required Interface:
\code
ITERATOR iter;
ACCESSOR a;
VALUETYPE destvalue;
float s;
int x, y;
destvalue = s * a(iter, x, y) + s * a(iter, x, y);
\endcode
*/
template
class BilinearInterpolatingAccessor
{
public:
/** the iterators' pixel type
*/
typedef VALUETYPE value_type;
/** init from given accessor
*/
BilinearInterpolatingAccessor(ACCESSOR a)
: a_(a)
{}
/** Interpolate the data item at a non-integer position.
Ensure that no outside pixels are accessed if
(x, y) is near the image border (as long as
0 <= x <= width-1, 0 <= y <= height-1).
*/
template
value_type operator()(ITERATOR const & i, float x, float y) const
{
int ix = int(x);
int iy = int(y);
float dx = x - ix;
float dy = y - iy;
value_type ret;
// avoid dereferencing the iterator outside its range
if(dx == 0.0)
{
if(dy == 0.0)
{
ret = a_(i, Diff2D(ix, iy));
}
else
{
ret = detail::RequiresExplicitCast::cast(
(1.0 - dy) * a_(i, Diff2D(ix, iy)) +
dy * a_(i, Diff2D(ix, iy + 1)));
}
}
else
{
if(dy == 0.0)
{
ret = detail::RequiresExplicitCast::cast(
(1.0 - dx) * a_(i, Diff2D(ix, iy)) +
dx * a_(i, Diff2D(ix + 1, iy)));
}
else
{
ret = detail::RequiresExplicitCast::cast(
(1.0 - dx) * (1.0 - dy) * a_(i, Diff2D(ix, iy)) +
dx * (1.0 - dy) * a_(i, Diff2D(ix + 1, iy)) +
(1.0 - dx) * dy * a_(i, Diff2D(ix, iy + 1)) +
dx * dy * a_(i, Diff2D(ix + 1, iy + 1)));
}
}
return ret;
}
/** Interpolate the data item at a non-integer position.
This function works as long as 0 <= x < width-1,
0 <= y < height-1. It is slightly faster than operator().
*/
template
value_type unchecked(ITERATOR const & i, float x, float y) const
{
int ix = int(x);
int iy = int(y);
float dx = x - ix;
float dy = y - iy;
return detail::RequiresExplicitCast::cast(
(1.0 - dx) * (1.0 - dy) * a_(i, Diff2D(ix, iy)) +
dx * (1.0 - dy) * a_(i, Diff2D(ix + 1, iy)) +
(1.0 - dx) * dy * a_(i, Diff2D(ix, iy + 1)) +
dx * dy * a_(i, Diff2D(ix + 1, iy + 1)));
}
private:
ACCESSOR a_;
};
//@}
} // namespace vigra
#endif /* VIGRA_INTERPOLATING_ACCESSOR_HXX */