fix mapim typo

oops! typo ... also an off-by-one issue for larger stencils

more error checking in interpolators

fix rounding in nohalo/lbb ... they were rounding to nearest in the
interpolator, rather than using floor. This broke assumptions about
stencil position elsewhere. The right way to do centre convention is to offset
the whole input by 0.5 pixels.
This commit is contained in:
John Cupitt 2015-11-22 10:29:45 +00:00
parent 16c4eeabad
commit 18baf40b1a
7 changed files with 38 additions and 15 deletions

10
TODO
View File

@ -1,11 +1,5 @@
- get some brightly coloured spots with nohalo / vsqbs on wobble.ws ... very
- easy to get a segv with Nicolas's interpolators, argh odd, the interpolation shouldn't change between bands
just with float images?
try to_polar workspace, set LBB, zoom in and scroll around a bit
- still not happy about float->int mask conversion in im_vips2mask.c - still not happy about float->int mask conversion in im_vips2mask.c

View File

@ -408,6 +408,17 @@ vips_interpolate_bicubic_interpolate( VipsInterpolate *interpolate,
const int bands = in->im->Bands; const int bands = in->im->Bands;
const int lskip = VIPS_REGION_LSKIP( in ); const int lskip = VIPS_REGION_LSKIP( in );
g_assert( ix - 1 >= in->valid.left );
g_assert( iy - 1 >= in->valid.top );
g_assert( ix + 2 < VIPS_RECT_RIGHT( &in->valid ) );
g_assert( iy + 2 < VIPS_RECT_BOTTOM( &in->valid ) );
/* Confirm that absolute_x and absolute_y are >= 1, because of
* window_offset.
*/
g_assert( x >= 1.0 );
g_assert( y >= 1.0 );
#ifdef DEBUG #ifdef DEBUG
printf( "vips_interpolate_bicubic_interpolate: %g %g\n", x, y ); printf( "vips_interpolate_bicubic_interpolate: %g %g\n", x, y );
printf( "\tleft=%d, top=%d, width=%d, height=%d\n", printf( "\tleft=%d, top=%d, width=%d, height=%d\n",

View File

@ -513,6 +513,11 @@ vips_interpolate_bilinear_interpolate( VipsInterpolate *interpolate,
int z; int z;
g_assert( (int) x >= in->valid.left );
g_assert( (int) y >= in->valid.top );
g_assert( (int) x + 1 < VIPS_RECT_RIGHT( &in->valid ) );
g_assert( (int) y + 1 < VIPS_RECT_BOTTOM( &in->valid ) );
SWITCH_INTERPOLATE( in->im->BandFmt, SWITCH_INTERPOLATE( in->im->BandFmt,
BILINEAR_INT, BILINEAR_FLOAT ); BILINEAR_INT, BILINEAR_FLOAT );
} }

View File

@ -800,6 +800,11 @@ vips_interpolate_lbb_interpolate( VipsInterpolate* restrict interpolate,
vips_band_format_iscomplex( in->im->BandFmt ) ? vips_band_format_iscomplex( in->im->BandFmt ) ?
2 * actual_bands : actual_bands; 2 * actual_bands : actual_bands;
g_assert( ix - 1 >= in->valid.left );
g_assert( iy - 1 >= in->valid.top );
g_assert( ix + 2 < VIPS_RECT_RIGHT( &in->valid ) );
g_assert( iy + 2 < VIPS_RECT_BOTTOM( &in->valid ) );
/* Confirm that absolute_x and absolute_y are >= 1, see above. /* Confirm that absolute_x and absolute_y are >= 1, see above.
*/ */
g_assert( absolute_x >= 1.0 ); g_assert( absolute_x >= 1.0 );

View File

@ -188,7 +188,7 @@ vips_mapim_region_minmax( VipsRegion *region, VipsRect *r, VipsRect *bounds )
for( z = 0; z < ps; z++ ) \ for( z = 0; z < ps; z++ ) \
q[z] = 0; \ q[z] = 0; \
} \ } \
else \ else \
interpolate( mapim->interpolate, q, ir[0], \ interpolate( mapim->interpolate, q, ir[0], \
px + window_offset, py + window_offset ); \ px + window_offset, py + window_offset ); \
\ \
@ -243,8 +243,6 @@ vips_mapim_gen( VipsRegion *or, void *seq, void *a, void *b, gboolean *stop )
*/ */
bounds.width += window_size - 1; bounds.width += window_size - 1;
bounds.height += window_size - 1; bounds.height += window_size - 1;
bounds.left -= window_offset;
bounds.height -= window_offset;
/* Clip against the source image. /* Clip against the source image.
*/ */

View File

@ -1493,8 +1493,8 @@ vips_interpolate_nohalo_interpolate( VipsInterpolate* restrict interpolate,
* *
* It's 2 not 0 since we ask for a window_offset of 2 at the bottom. * It's 2 not 0 since we ask for a window_offset of 2 at the bottom.
*/ */
const int ix = (int) (absolute_x + 0.5); const int ix = (int) absolute_x;
const int iy = (int) (absolute_y + 0.5); const int iy = (int) absolute_y;
/* /*
* Move the pointer to (the first band of) the top/left pixel of the * Move the pointer to (the first band of) the top/left pixel of the
@ -1521,6 +1521,11 @@ vips_interpolate_nohalo_interpolate( VipsInterpolate* restrict interpolate,
vips_band_format_iscomplex( in->im->BandFmt ) ? vips_band_format_iscomplex( in->im->BandFmt ) ?
2 * actual_bands : actual_bands; 2 * actual_bands : actual_bands;
g_assert( ix - 2 >= in->valid.left );
g_assert( iy - 2 >= in->valid.top );
g_assert( ix + 2 < VIPS_RECT_RIGHT( &in->valid ) );
g_assert( iy + 2 < VIPS_RECT_BOTTOM( &in->valid ) );
/* Confirm that absolute_x and absolute_y are >= 2, see above. /* Confirm that absolute_x and absolute_y are >= 2, see above.
*/ */
g_assert( absolute_x >= 2.0 ); g_assert( absolute_x >= 2.0 );

View File

@ -313,8 +313,8 @@ vips_interpolate_vsqbs_interpolate( VipsInterpolate* restrict interpolate,
* *
* It's 1 not 0 since we ask for a window_offset of 1 at the bottom. * It's 1 not 0 since we ask for a window_offset of 1 at the bottom.
*/ */
const int ix = (int) (absolute_x + 0.5); const int ix = (int) absolute_x;
const int iy = (int) (absolute_y + 0.5); const int iy = (int) absolute_y;
/* /*
* Move the pointer to (the first band of) the top/left pixel of the * Move the pointer to (the first band of) the top/left pixel of the
@ -341,6 +341,11 @@ vips_interpolate_vsqbs_interpolate( VipsInterpolate* restrict interpolate,
vips_band_format_iscomplex( in->im->BandFmt ) ? vips_band_format_iscomplex( in->im->BandFmt ) ?
2 * actual_bands : actual_bands; 2 * actual_bands : actual_bands;
g_assert( ix - 1 >= in->valid.left );
g_assert( iy - 1 >= in->valid.top );
g_assert( ix + 1 < VIPS_RECT_RIGHT( &in->valid ) );
g_assert( iy + 1 < VIPS_RECT_BOTTOM( &in->valid ) );
/* Confirm that absolute_x and absolute_y are >= 1, see above. /* Confirm that absolute_x and absolute_y are >= 1, see above.
*/ */
g_assert( absolute_x >= 1.0 ); g_assert( absolute_x >= 1.0 );