From 269cbb8641c43d7cc5acdc661e736b5072a8ab88 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 11 Apr 2016 13:19:00 +0100 Subject: [PATCH] better mask sizing for lanczos --- TODO | 7 ------- libvips/resample/presample.h | 4 ++-- libvips/resample/reduceh.cpp | 18 +++++++++--------- libvips/resample/reducev.cpp | 12 ++++++------ libvips/resample/templates.h | 6 +++--- 5 files changed, 20 insertions(+), 27 deletions(-) diff --git a/TODO b/TODO index 9f856521..16e16bf9 100644 --- a/TODO +++ b/TODO @@ -1,10 +1,3 @@ -- have some zero elements in lanczos3 masks, can we improve mask sizing? - - eg. - - $ vips reducev ~/pics/babe.jpg x.png 1.1 - - has an extra 0 at the end - compare lanczos2 vs. 3, any differences? diff --git a/libvips/resample/presample.h b/libvips/resample/presample.h index f5ce9782..be563059 100644 --- a/libvips/resample/presample.h +++ b/libvips/resample/presample.h @@ -70,8 +70,8 @@ GType vips_resample_get_type( void ); #define MAX_POINT (50) int vips_reduce_get_points( VipsKernel kernel, double shrink ); -void vips_reduce_make_mask( VipsKernel kernel, double shrink, - double x, double *c ); +void vips_reduce_make_mask( double *c, + VipsKernel kernel, double shrink, double x ); #ifdef __cplusplus } diff --git a/libvips/resample/reduceh.cpp b/libvips/resample/reduceh.cpp index 12e81a4e..9048bef3 100644 --- a/libvips/resample/reduceh.cpp +++ b/libvips/resample/reduceh.cpp @@ -112,10 +112,10 @@ vips_reduce_get_points( VipsKernel kernel, double shrink ) case VIPS_KERNEL_LANCZOS2: /* Needs to be in sync with calculate_coefficients_lanczos(). */ - return( ceil( 2 * 2 * shrink ) + 2 ); + return( rint( 2 * 2 * shrink ) + 1 ); case VIPS_KERNEL_LANCZOS3: - return( ceil( 2 * 3 * shrink ) + 2 ); + return( rint( 2 * 3 * shrink ) + 1 ); default: g_assert_not_reached(); @@ -126,7 +126,7 @@ vips_reduce_get_points( VipsKernel kernel, double shrink ) /* Calculate a mask element. */ void -vips_reduce_make_mask( VipsKernel kernel, double shrink, double x, double *c ) +vips_reduce_make_mask( double *c, VipsKernel kernel, double shrink, double x ) { switch( kernel ) { case VIPS_KERNEL_NEAREST: @@ -143,11 +143,11 @@ vips_reduce_make_mask( VipsKernel kernel, double shrink, double x, double *c ) break; case VIPS_KERNEL_LANCZOS2: - calculate_coefficients_lanczos( 2, shrink, x, c ); + calculate_coefficients_lanczos( c, 2, shrink, x ); break; case VIPS_KERNEL_LANCZOS3: - calculate_coefficients_lanczos( 3, shrink, x, c ); + calculate_coefficients_lanczos( c, 3, shrink, x ); break; default: @@ -276,7 +276,7 @@ reduceh_notab( VipsReduceh *reduceh, double cx[MAX_POINT]; - vips_reduce_make_mask( reduceh->kernel, reduceh->xshrink, x, cx ); + vips_reduce_make_mask( cx, reduceh->kernel, reduceh->xshrink, x ); for( int z = 0; z < bands; z++ ) { out[z] = reduce_sum( in, bands, cx, n ); @@ -452,9 +452,9 @@ vips_reduceh_build( VipsObject *object ) !reduceh->matrixi[x] ) return( -1 ); - vips_reduce_make_mask( reduceh->kernel, reduceh->xshrink, - (float) x / VIPS_TRANSFORM_SCALE, - reduceh->matrixf[x] ); + vips_reduce_make_mask( reduceh->matrixf[x], + reduceh->kernel, reduceh->xshrink, + (float) x / VIPS_TRANSFORM_SCALE ); for( int i = 0; i < reduceh->n_point; i++ ) reduceh->matrixi[x][i] = reduceh->matrixf[x][i] * diff --git a/libvips/resample/reducev.cpp b/libvips/resample/reducev.cpp index 9790e75c..49416b7d 100644 --- a/libvips/resample/reducev.cpp +++ b/libvips/resample/reducev.cpp @@ -490,7 +490,7 @@ reducev_notab( VipsReducev *reducev, double cy[MAX_POINT]; - vips_reduce_make_mask( reducev->kernel, reducev->yshrink, y, cy ); + vips_reduce_make_mask( cy, reducev->kernel, reducev->yshrink, y ); for( int z = 0; z < ne; z++ ) out[z] = reduce_sum( in + z, l1, cy, n ); @@ -760,14 +760,14 @@ vips_reducev_raw( VipsReducev *reducev, VipsImage *in ) if( !reducev->matrixf[y] ) return( -1 ); - vips_reduce_make_mask( reducev->kernel, reducev->yshrink, - (float) y / VIPS_TRANSFORM_SCALE, - reducev->matrixf[y] ); + vips_reduce_make_mask( reducev->matrixf[y], + reducev->kernel, reducev->yshrink, + (float) y / VIPS_TRANSFORM_SCALE ); #ifdef DEBUG - printf( "%4g ", (double) y / VIPS_TRANSFORM_SCALE ); + printf( "%6.2g", (double) y / VIPS_TRANSFORM_SCALE ); for( int i = 0; i < reducev->n_point; i++ ) - printf( " %4g", reducev->matrixf[y][i] ); + printf( ", %6.2g", reducev->matrixf[y][i] ); printf( "\n" ); #endif /*DEBUG*/ } diff --git a/libvips/resample/templates.h b/libvips/resample/templates.h index 04387752..70489bcf 100644 --- a/libvips/resample/templates.h +++ b/libvips/resample/templates.h @@ -320,12 +320,12 @@ calculate_coefficients_catmull( const double x, double c[4] ) * points for large decimations to avoid aliasing. */ static void inline -calculate_coefficients_lanczos( const int a, const double shrink, - const double x, double *c ) +calculate_coefficients_lanczos( double *c, + const int a, const double shrink, const double x ) { /* Needs to be in sync with vips_reduce_get_points(). */ - const int n_points = ceil( 2 * a * shrink ) + 2; + const int n_points = rint( 2 * a * shrink ) + 1; int i; double sum;