more accurate bilinear for int16 pixels
fixed-point interpolation could give small errors see https://github.com/libvips/libvips/issues/1309 need a similar change for bicubic etc.
This commit is contained in:
parent
a02229245e
commit
c9ba0915c1
|
@ -472,8 +472,8 @@ G_DEFINE_TYPE( VipsInterpolateBilinear, vips_interpolate_bilinear,
|
||||||
z += 1; \
|
z += 1; \
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Interpolate a pel ... int32 and float types, no tables, float
|
/* Interpolate a pel ... int16, int32 and float types, no tables, float
|
||||||
* arithmetic. Use float, not double, for coefficient calculation, or we can
|
* arithmetic. Use double not float for coefficient calculation or we can
|
||||||
* get small over/undershoots.
|
* get small over/undershoots.
|
||||||
*/
|
*/
|
||||||
#define BILINEAR_FLOAT( TYPE ) { \
|
#define BILINEAR_FLOAT( TYPE ) { \
|
||||||
|
@ -498,15 +498,15 @@ G_DEFINE_TYPE( VipsInterpolateBilinear, vips_interpolate_bilinear,
|
||||||
VIPS_UNROLL( b, BILINEAR_FLOAT_INNER ); \
|
VIPS_UNROLL( b, BILINEAR_FLOAT_INNER ); \
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Expand for band types. with a fixed-point interpolator and a float
|
/* The fixed-point path is fine for uchar pixels, but it'll be inaccurate for
|
||||||
* interpolator.
|
* shorts and larger.
|
||||||
*/
|
*/
|
||||||
#define SWITCH_INTERPOLATE( FMT, INT, FLOAT ) { \
|
#define SWITCH_INTERPOLATE( FMT, INT, FLOAT ) { \
|
||||||
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:INT( unsigned short ); break; \
|
case VIPS_FORMAT_USHORT:FLOAT( unsigned short ); break; \
|
||||||
case VIPS_FORMAT_SHORT: INT( short ); break; \
|
case VIPS_FORMAT_SHORT: FLOAT( 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; \
|
||||||
|
@ -544,8 +544,7 @@ vips_interpolate_bilinear_interpolate( VipsInterpolate *interpolate,
|
||||||
g_assert( (int) x + 1 < VIPS_RECT_RIGHT( &in->valid ) );
|
g_assert( (int) x + 1 < VIPS_RECT_RIGHT( &in->valid ) );
|
||||||
g_assert( (int) y + 1 < VIPS_RECT_BOTTOM( &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 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
Loading…
Reference in New Issue