faster and more accurate bilinear

go to fixed point earlier in calculation of interpolation coefficients
This commit is contained in:
John Cupitt 2019-05-14 13:10:45 +01:00
parent 29d9673fd8
commit da402cee23

View File

@ -431,8 +431,8 @@ G_DEFINE_TYPE( VipsInterpolateBilinear, vips_interpolate_bilinear,
*/ */
#define BILINEAR_INT_INNER { \ #define BILINEAR_INT_INNER { \
tq[z] = (sc1 * tp1[z] + sc2 * tp2[z] + \ tq[z] = (c1 * tp1[z] + c2 * tp2[z] + \
sc3 * tp3[z] + sc4 * tp4[z] + \ c3 * tp3[z] + c4 * tp4[z] + \
(1 << VIPS_INTERPOLATE_SHIFT) / 2) >> VIPS_INTERPOLATE_SHIFT; \ (1 << VIPS_INTERPOLATE_SHIFT) / 2) >> VIPS_INTERPOLATE_SHIFT; \
z += 1; \ z += 1; \
} }
@ -442,20 +442,15 @@ G_DEFINE_TYPE( VipsInterpolateBilinear, vips_interpolate_bilinear,
#define BILINEAR_INT( TYPE ) { \ #define BILINEAR_INT( TYPE ) { \
TYPE * restrict tq = (TYPE *) out; \ TYPE * restrict tq = (TYPE *) out; \
\ \
float Y = y - iy; \ int X = (x - ix) * VIPS_INTERPOLATE_SCALE; \
float X = x - ix; \ int Y = (y - iy) * VIPS_INTERPOLATE_SCALE; \
\ \
float Yd = 1.0f - Y; \ int Yd = VIPS_INTERPOLATE_SCALE - Y; \
\ \
float c4 = Y * X; \ int c4 = (Y * X) >> VIPS_INTERPOLATE_SHIFT; \
float c2 = Yd * X; \ int c2 = (Yd * X) >> VIPS_INTERPOLATE_SHIFT; \
float c3 = Y - c4; \ int c3 = Y - c4; \
float c1 = Yd - c2; \ int c1 = Yd - c2; \
\
int sc1 = VIPS_INTERPOLATE_SCALE * c1; \
int sc2 = VIPS_INTERPOLATE_SCALE * c2; \
int sc3 = VIPS_INTERPOLATE_SCALE * c3; \
int sc4 = VIPS_INTERPOLATE_SCALE * c4; \
\ \
const TYPE * restrict tp1 = (TYPE *) p1; \ const TYPE * restrict tp1 = (TYPE *) p1; \
const TYPE * restrict tp2 = (TYPE *) p2; \ const TYPE * restrict tp2 = (TYPE *) p2; \
@ -479,8 +474,8 @@ G_DEFINE_TYPE( VipsInterpolateBilinear, vips_interpolate_bilinear,
#define BILINEAR_FLOAT( TYPE ) { \ #define BILINEAR_FLOAT( TYPE ) { \
TYPE * restrict tq = (TYPE *) out; \ TYPE * restrict tq = (TYPE *) out; \
\ \
double Y = y - iy; \
double X = x - ix; \ double X = x - ix; \
double Y = y - iy; \
\ \
double Yd = 1.0f - Y; \ double Yd = 1.0f - Y; \
\ \
@ -505,8 +500,8 @@ G_DEFINE_TYPE( VipsInterpolateBilinear, vips_interpolate_bilinear,
switch( (FMT) ) { \ switch( (FMT) ) { \
case VIPS_FORMAT_UCHAR: INT( unsigned char ); break; \ case VIPS_FORMAT_UCHAR: INT( unsigned char ); break; \
case VIPS_FORMAT_CHAR: INT( char ); break; \ case VIPS_FORMAT_CHAR: INT( char ); break; \
case VIPS_FORMAT_USHORT:FLOAT( unsigned short ); break; \ case VIPS_FORMAT_USHORT:INT( unsigned short ); break; \
case VIPS_FORMAT_SHORT: FLOAT( short ); break; \ case VIPS_FORMAT_SHORT: INT( short ); break; \
case VIPS_FORMAT_UINT: FLOAT( unsigned int ); break; \ case VIPS_FORMAT_UINT: FLOAT( unsigned int ); break; \
case VIPS_FORMAT_INT: FLOAT( int ); break; \ case VIPS_FORMAT_INT: FLOAT( int ); break; \
case VIPS_FORMAT_FLOAT: FLOAT( float ); break; \ case VIPS_FORMAT_FLOAT: FLOAT( float ); break; \