add vips_interpolate_get_window_offset()

This commit is contained in:
John Cupitt 2009-09-14 15:33:26 +00:00
parent 5875278850
commit 6a745c5264
4 changed files with 37 additions and 8 deletions

View File

@ -35,6 +35,7 @@
- im_max()/im_min() are now convenience functions
- im_maxpos_avg() handles complex and multi-band images
- added im_point(), rewrite im_point_bilinear() in terms of this
- added vips_interpolate_get_window_offset()
25/3/09 started 7.18.0
- revised version numbers

View File

@ -78,6 +78,11 @@ typedef struct _VipsInterpolateClass {
/* Or just set this if you want a constant.
*/
int window_size;
/* Stencils are offset by this much. Default to window_size / 2
* (centering) if undefined.
*/
int (*get_window_offset)( VipsInterpolate * );
} VipsInterpolateClass;
GType vips_interpolate_get_type( void );
@ -85,6 +90,7 @@ void vips_interpolate( VipsInterpolate *interpolate,
PEL *out, REGION *in, double x, double y );
VipsInterpolateMethod vips_interpolate_get_method( VipsInterpolate * );
int vips_interpolate_get_window_size( VipsInterpolate *interpolate );
int vips_interpolate_get_window_offset( VipsInterpolate *interpolate );
/* How many bits of precision we keep for transformations, ie. how many
* pre-computed matricies we have.

View File

@ -186,9 +186,8 @@ affinei_gen( REGION *or, void *seq, void *a, void *b )
REGION *ir = (REGION *) seq;
const IMAGE *in = (IMAGE *) a;
const Affine *affine = (Affine *) b;
const int window_size =
vips_interpolate_get_window_size( affine->interpolate );
const int half_window_size = window_size / 2;
const int window_offset =
vips_interpolate_get_window_offset( affine->interpolate );
const VipsInterpolateMethod interpolate =
vips_interpolate_get_method( affine->interpolate );
@ -233,7 +232,7 @@ affinei_gen( REGION *or, void *seq, void *a, void *b )
/* Add a border for interpolation. Plus one for rounding errors.
*/
im_rect_marginadjust( &need, half_window_size + 1 );
im_rect_marginadjust( &need, window_offset + 1 );
/* Clip against the size of (2).
*/
@ -401,22 +400,25 @@ im__affinei( IMAGE *in, IMAGE *out,
VipsInterpolate *interpolate, Transformation *trn )
{
IMAGE *t3 = im_open_local( out, "im_affine:3", "p" );
const int window_size = vips_interpolate_get_window_size( interpolate );
const int window_size =
vips_interpolate_get_window_size( interpolate );
const int window_offset =
vips_interpolate_get_window_offset( interpolate );
Transformation trn2;
/* Add new pixels around the input so we can interpolate at the edges.
*/
if( !t3 ||
im_embed( in, t3, 1,
window_size / 2, window_size / 2,
window_offset, window_offset,
in->Xsize + window_size, in->Ysize + window_size ) )
return( -1 );
/* Set iarea so we know what part of the input we can take.
*/
trn2 = *trn;
trn2.iarea.left += window_size / 2;
trn2.iarea.top += window_size / 2;
trn2.iarea.left += window_offset;
trn2.iarea.top += window_offset;
#ifdef DEBUG_GEOMETRY
printf( "im__affinei: %s\n", in->filename );

View File

@ -94,6 +94,12 @@ vips_interpolate_real_get_window_size( VipsInterpolate *interpolate )
return( class->window_size );
}
static int
vips_interpolate_real_get_window_offset( VipsInterpolate *interpolate )
{
return( vips_interpolate_get_window_size( interpolate ) / 2 );
}
static void
vips_interpolate_class_init( VipsInterpolateClass *class )
{
@ -106,6 +112,7 @@ vips_interpolate_class_init( VipsInterpolateClass *class )
#endif /*DEBUG*/
class->interpolate = NULL;
class->get_window_size = vips_interpolate_real_get_window_size;
class->get_window_size = vips_interpolate_real_get_window_offset;
class->window_size = -1;
}
@ -152,9 +159,22 @@ vips_interpolate_get_window_size( VipsInterpolate *interpolate )
VipsInterpolateClass *class = VIPS_INTERPOLATE_GET_CLASS( interpolate );
g_assert( class->get_window_size );
return( class->get_window_size( interpolate ) );
}
/* Get this interpolator's required window offset.
*/
int
vips_interpolate_get_window_offset( VipsInterpolate *interpolate )
{
VipsInterpolateClass *class = VIPS_INTERPOLATE_GET_CLASS( interpolate );
g_assert( class->get_window_offset );
return( class->get_window_offset( interpolate ) );
}
/* VipsInterpolateNearest class
*/