2.6 Interpolators
VIPS has a general system for representing pixel interpolators.
You can select an interpolator to pass to other VIPS
operations, such as im_affinei(), you can add new
interpolators, and you can write operations which take a
general interpolator as a parameter.
An interpolator is a function of the form:
typedef void (⋆VipsInterpolateMethod)( VipsInterpolate ⋆,
PEL ⋆out, REGION ⋆in, double x, double y );
given the set of input pixels in, it has to calculate a value
for the fractional position (x,y) and write this value to the
memory pointed to by out.
VIPS uses corner convention, so the value of pixel (0,0)
is the value of the surface the interpolator fits at the
fractional position (0.0,0.0).
2.6.1 How an interpolator is represented
See the man page for VipsInterpolate for full
details, but briefly, an interpolator is a subclass of
VipsInterpolate implementing the following
items:
- An interpolation method, with the type signature
above.
- A function get_window_size()
which returns the size of the area of pixels that
the interpolator needs in order to calculate a value.
For example, a bilinear interpolator needs the four
pixels surrounding the point to be calculated, or a
2 by 2 window, so window size should be 2.
- Or if the window size is constant, you can leave
get_window_size() NULL and just set the
int value window_size.
2.6.2 A sample interpolator
As an example, Figure 2.10 shows how to register a new
interpolator in a plugin.
// This interpolator adds no new members.
typedef VipsInterpolate Myinterpolator;
typedef VipsInterpolateClass MyinterpolatorClass;
G_DEFINE_TYPE( Myinterpolator, myinterpolator, VIPS_TYPE_INTERPOLATE );
static void
myinterpolator_interpolate( VipsInterpolate ⋆interpolate,
PEL ⋆out, REGION ⋆in, double x, double y )
{
MyinterpolatorClass ⋆class =
MYINTERPOLATOR_GET_CLASS( interpolate );
/⋆ Nearest-neighbor.
⋆/
memcpy( out,
IM_REGION_ADDR( in, floor( x ), floor( y ) ),
IM_IMAGE_SIZEOF_PEL( in->im ) );
}
static void
myinterpolator_class_init( MyinterpolatorClass ⋆class )
{
VipsObjectClass ⋆object_class = (VipsObjectClass ⋆) class;
VipsInterpolateClass ⋆interpolate_class = (VipsInterpolateClass ⋆) class;
object_class->nickname = "myinterpolator";
object_class->description = _( "My interpolator" );
interpolate_class->interpolate = myinterpolator_interpolate;
}
static void
myinterpolate_init( Myinterpolate ⋆object )
{
}
char ⋆
g_module_check_init( GModule ⋆self )
{
// register the type
myinterpolator_get_type();
}
Figure 2.10: Registering an interpolator in a plugin
2.6.3 Writing a VIPS operation that takes an interpolator
as an argument
Operations just take a VipsInterpolate as an
argument, for example:
int im_affinei_all( IMAGE ⋆in, IMAGE ⋆out,
VipsInterpolate ⋆interpolate,
double a, double b, double c, double d,
double dx, double dy );
To use the interpolator, use vips_interpolate():
void vips_interpolate( VipsInterpolate ⋆interpolate,
PEL ⋆out, REGION ⋆in, double x, double y );
This looks up the interpolate method for the object and calls
it for you.
You can save the cost of the lookup in an inner loop with
vips_interpolate_get_method():
VipsInterpolateMethod
vips_interpolate_get_method(
VipsInterpolate ⋆interpolate );
2.6.4 Passing an interpolator to a VIPS operation
You can build an instance of a VipsInterpolator
with the vips_object_⋆() family of functions, see
§2.4.
Convenience functions return a static instance of one of
the standard interpolators:
VipsInterpolate ⋆vips_interpolate_nearest_static( void );
VipsInterpolate ⋆vips_interpolate_bilinear_static( void );
Don’t free the result.
Finally, vips_interpolate_new() makes a
VipsInterpolate from a nickname:
VipsInterpolate ⋆vips_interpolate_new( const char ⋆nickname );
For example:
VipsInterpolate ⋆interpolate = vips_interpolate_new( "nohalo" );
You must drop your ref after you’re done with the object
with g_object_unref().