From 18baf40b1a8aca10e1bec08997e289f186e5f008 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sun, 22 Nov 2015 10:29:45 +0000 Subject: [PATCH] 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. --- TODO | 10 ++-------- libvips/resample/bicubic.cpp | 11 +++++++++++ libvips/resample/interpolate.c | 5 +++++ libvips/resample/lbb.cpp | 5 +++++ libvips/resample/mapim.c | 4 +--- libvips/resample/nohalo.cpp | 9 +++++++-- libvips/resample/vsqbs.cpp | 9 +++++++-- 7 files changed, 38 insertions(+), 15 deletions(-) diff --git a/TODO b/TODO index b521c35d..a033d7d3 100644 --- a/TODO +++ b/TODO @@ -1,11 +1,5 @@ - -- easy to get a segv with Nicolas's interpolators, argh - - just with float images? - - try to_polar workspace, set LBB, zoom in and scroll around a bit - - +- get some brightly coloured spots with nohalo / vsqbs on wobble.ws ... very + odd, the interpolation shouldn't change between bands - still not happy about float->int mask conversion in im_vips2mask.c diff --git a/libvips/resample/bicubic.cpp b/libvips/resample/bicubic.cpp index 238bf991..7525bc35 100644 --- a/libvips/resample/bicubic.cpp +++ b/libvips/resample/bicubic.cpp @@ -408,6 +408,17 @@ vips_interpolate_bicubic_interpolate( VipsInterpolate *interpolate, const int bands = in->im->Bands; 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 printf( "vips_interpolate_bicubic_interpolate: %g %g\n", x, y ); printf( "\tleft=%d, top=%d, width=%d, height=%d\n", diff --git a/libvips/resample/interpolate.c b/libvips/resample/interpolate.c index 42320cb4..d1de9d6f 100644 --- a/libvips/resample/interpolate.c +++ b/libvips/resample/interpolate.c @@ -513,6 +513,11 @@ vips_interpolate_bilinear_interpolate( VipsInterpolate *interpolate, 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, BILINEAR_INT, BILINEAR_FLOAT ); } diff --git a/libvips/resample/lbb.cpp b/libvips/resample/lbb.cpp index a678174b..17ba39bd 100644 --- a/libvips/resample/lbb.cpp +++ b/libvips/resample/lbb.cpp @@ -800,6 +800,11 @@ vips_interpolate_lbb_interpolate( VipsInterpolate* restrict interpolate, vips_band_format_iscomplex( in->im->BandFmt ) ? 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. */ g_assert( absolute_x >= 1.0 ); diff --git a/libvips/resample/mapim.c b/libvips/resample/mapim.c index f40d2ccc..b32d83dc 100644 --- a/libvips/resample/mapim.c +++ b/libvips/resample/mapim.c @@ -188,7 +188,7 @@ vips_mapim_region_minmax( VipsRegion *region, VipsRect *r, VipsRect *bounds ) for( z = 0; z < ps; z++ ) \ q[z] = 0; \ } \ - else \ + else \ interpolate( mapim->interpolate, q, ir[0], \ 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.height += window_size - 1; - bounds.left -= window_offset; - bounds.height -= window_offset; /* Clip against the source image. */ diff --git a/libvips/resample/nohalo.cpp b/libvips/resample/nohalo.cpp index 332b1786..01e5cf51 100644 --- a/libvips/resample/nohalo.cpp +++ b/libvips/resample/nohalo.cpp @@ -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. */ - const int ix = (int) (absolute_x + 0.5); - const int iy = (int) (absolute_y + 0.5); + const int ix = (int) absolute_x; + const int iy = (int) absolute_y; /* * 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 ) ? 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. */ g_assert( absolute_x >= 2.0 ); diff --git a/libvips/resample/vsqbs.cpp b/libvips/resample/vsqbs.cpp index 528b2b30..77e1ecb4 100644 --- a/libvips/resample/vsqbs.cpp +++ b/libvips/resample/vsqbs.cpp @@ -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. */ - const int ix = (int) (absolute_x + 0.5); - const int iy = (int) (absolute_y + 0.5); + const int ix = (int) absolute_x; + const int iy = (int) absolute_y; /* * 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 ) ? 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. */ g_assert( absolute_x >= 1.0 );