more accurate bilinear

use double, not float, for coefficient calculation, or we get overshoots
in some cases

see https://github.com/libvips/libvips/issues/1239
This commit is contained in:
John Cupitt 2019-02-27 20:33:31 +00:00
parent 90ca1d8038
commit b565f2fc68
1 changed files with 11 additions and 8 deletions

View File

@ -16,6 +16,8 @@
* - gtk-doc * - gtk-doc
* 16/12/15 * 16/12/15
* - faster bilinear * - faster bilinear
* 27/2/19 s-sajid-ali
* - more accurate bilinear
*/ */
/* /*
@ -471,20 +473,21 @@ G_DEFINE_TYPE( VipsInterpolateBilinear, vips_interpolate_bilinear,
} }
/* Interpolate a pel ... int32 and float types, no tables, float /* Interpolate a pel ... int32 and float types, no tables, float
* arithmetic. * arithmetic. Use float, not double, for coefficient calculation, or we can
* get small over/undershoots.
*/ */
#define BILINEAR_FLOAT( TYPE ) { \ #define BILINEAR_FLOAT( TYPE ) { \
TYPE * restrict tq = (TYPE *) out; \ TYPE * restrict tq = (TYPE *) out; \
\ \
float Y = y - iy; \ double Y = y - iy; \
float X = x - ix; \ double X = x - ix; \
\ \
float Yd = 1.0f - Y; \ double Yd = 1.0f - Y; \
\ \
float c4 = Y * X; \ double c4 = Y * X; \
float c2 = Yd * X; \ double c2 = Yd * X; \
float c3 = Y - c4; \ double c3 = Y - c4; \
float c1 = Yd - c2; \ double c1 = Yd - c2; \
\ \
const TYPE * restrict tp1 = (TYPE *) p1; \ const TYPE * restrict tp1 = (TYPE *) p1; \
const TYPE * restrict tp2 = (TYPE *) p2; \ const TYPE * restrict tp2 = (TYPE *) p2; \