diff --git a/ChangeLog b/ChangeLog index c7e0be7d..29aeede4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,8 @@ - saner im_buildlut() behaviour - added im_gauss_imask_sep() - allow open of truncated images, but block pixel access +- revising rounding on im_affine*() coordinate transforms to make them more + stable 3/3/09 started 7.17.2 - im_magick2vips.c: allow funky bit depths, like 14 (thanks Mikkel) diff --git a/TODO b/TODO index 5a0e3aa9..e9e68b60 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,10 @@ +- try + + vips im_affinei_all ~/in.v ~/out.v bilinear 1.0928961748633881 0 0 1 0 0 + + where in.v is a 366 pixel wide image, and 1.092... is (400 / 366) + + - mask subscript in Pythion seems to be broken >>> from vipsCC import * diff --git a/libsrc/resample/im_affine.c b/libsrc/resample/im_affine.c index 96f7a169..66eaea4c 100644 --- a/libsrc/resample/im_affine.c +++ b/libsrc/resample/im_affine.c @@ -231,9 +231,9 @@ affinei_gen( REGION *or, void *seq, void *a, void *b ) need.left += iarea->left; need.top += iarea->top; - /* Add a border for interpolation. + /* Add a border for interpolation. Plus one for rounding errors. */ - im_rect_marginadjust( &need, half_window_size ); + im_rect_marginadjust( &need, half_window_size + 1 ); /* Clip against the size of (2). */ diff --git a/libsrc/resample/transform.c b/libsrc/resample/transform.c index 8aadf033..20abddfa 100644 --- a/libsrc/resample/transform.c +++ b/libsrc/resample/transform.c @@ -181,7 +181,7 @@ typedef void (*transform_fn)( const Transformation *, */ static void transform_rect( const Transformation *trn, transform_fn transform, - const Rect *in, /* In input space */ + const Rect *in, /* In input space */ Rect *out ) /* In output space */ { double x1, y1; /* Map corners */ @@ -197,17 +197,18 @@ transform_rect( const Transformation *trn, transform_fn transform, transform( trn, IM_RECT_RIGHT( in ), in->top, &x2, &y2 ); transform( trn, IM_RECT_RIGHT( in ), IM_RECT_BOTTOM( in ), &x4, &y4 ); - /* Find bounding box for these four corners. + /* Find bounding box for these four corners. Round-to-nearest to try + * to stop rounding errors growing images. */ left = IM_MIN( x1, IM_MIN( x2, IM_MIN( x3, x4 ) ) ); right = IM_MAX( x1, IM_MAX( x2, IM_MAX( x3, x4 ) ) ); top = IM_MIN( y1, IM_MIN( y2, IM_MIN( y3, y4 ) ) ); bottom = IM_MAX( y1, IM_MAX( y2, IM_MAX( y3, y4 ) ) ); - out->left = floor( left ); - out->top = floor( top ); - out->width = ceil( right ) - out->left; - out->height = ceil( bottom ) - out->top; + out->left = IM_RINT( left ); + out->top = IM_RINT( top ); + out->width = IM_RINT( right - left ); + out->height = IM_RINT( bottom - top ); } /* Given an area in the input image, calculate the bounding box for those