From c2035eb0f0fe2d38b3579952a24a6c842f370199 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 21 Mar 2016 14:18:01 +0000 Subject: [PATCH] similarity uses reduce more often --- libvips/resample/reduceh.cpp | 6 ++--- libvips/resample/similarity.c | 49 ++++++++++++++++++++++++++++------- libvips/resample/templates.h | 2 +- 3 files changed, 43 insertions(+), 14 deletions(-) diff --git a/libvips/resample/reduceh.cpp b/libvips/resample/reduceh.cpp index f3eca44a..79149585 100644 --- a/libvips/resample/reduceh.cpp +++ b/libvips/resample/reduceh.cpp @@ -169,13 +169,11 @@ reduceh_unsigned_int_tab( VipsReduceh *reduceh, for( int z = 0; z < bands; z++ ) { int sum; - sum = reduce_sum( in, bands, cx, n ); + sum = reduce_sum( in + z, bands, cx, n ); sum = unsigned_fixed_round( sum ); sum = VIPS_CLIP( 0, sum, max_value ); - - out[z] = sum; - in += 1; + out[z] = sum; } } diff --git a/libvips/resample/similarity.c b/libvips/resample/similarity.c index 6aaa306f..9259cbdd 100644 --- a/libvips/resample/similarity.c +++ b/libvips/resample/similarity.c @@ -72,34 +72,65 @@ typedef VipsResampleClass VipsSimilarityClass; G_DEFINE_TYPE( VipsSimilarity, vips_similarity, VIPS_TYPE_RESAMPLE ); +/* Map interpolator names to vips kernels. + */ +typedef struct _VipsInterpolateKernel { + const char *nickname; + VipsKernel kernel; +} VipsInterpolateKernel; + +static VipsInterpolateKernel vips_similarity_kernel[] = { + { "bicubic", VIPS_KERNEL_CUBIC }, + { "bilinear", VIPS_KERNEL_LINEAR }, + { "nearest", VIPS_KERNEL_NEAREST } +}; + static int vips_similarity_build( VipsObject *object ) { VipsResample *resample = VIPS_RESAMPLE( object ); VipsSimilarity *similarity = (VipsSimilarity *) object; - VipsImage **t = (VipsImage **) vips_object_local_array( object, 4 ); + gboolean handled; + if( VIPS_OBJECT_CLASS( vips_similarity_parent_class )->build( object ) ) return( -1 ); + handled = FALSE; + /* Use vips_reduce(), if we can. */ - if( similarity->interpolate && - strcmp( VIPS_OBJECT_GET_CLASS( similarity->interpolate )-> - nickname, "bicubic" ) == 0 && + if( similarity->interpolate && similarity->angle == 0.0 && similarity->idx == 0.0 && similarity->idy == 0.0 && similarity->odx == 0.0 && similarity->ody == 0.0 ) { - if( vips_reduce( resample->in, &t[0], - 1.0 / similarity->scale, - 1.0 / similarity->scale, NULL ) ) - return( -1 ); + const char *nickname = VIPS_OBJECT_GET_CLASS( + similarity->interpolate )->nickname; + + int i; + + for( i = 0; i < VIPS_NUMBER( vips_similarity_kernel ); i++ ) { + VipsInterpolateKernel *ik = &vips_similarity_kernel[i]; + + if( strcmp( nickname, ik->nickname ) == 0 ) { + if( vips_reduce( resample->in, &t[0], + 1.0 / similarity->scale, + 1.0 / similarity->scale, + "kernel", ik->kernel, + NULL ) ) + return( -1 ); + + handled = TRUE; + break; + } + } } - else { + + if( !handled ) { double a = similarity->scale * cos( VIPS_RAD( similarity->angle ) ); double b = similarity->scale * diff --git a/libvips/resample/templates.h b/libvips/resample/templates.h index 6a2167cd..04387752 100644 --- a/libvips/resample/templates.h +++ b/libvips/resample/templates.h @@ -356,7 +356,7 @@ calculate_coefficients_lanczos( const int a, const double shrink, } /* Our inner loop for resampling with a convolution. Operate on elements of - * size T, gather results in an intermediate of type IT. + * type T, gather results in an intermediate of type IT. */ template static IT