diff --git a/ChangeLog b/ChangeLog index 79a20cd4..9319fe95 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +29/1/16 started 8.3 +- add vips_reduce*() ... a fast path for bicubic downsize +- vips_resize() and vips_similarity use it when they can + 12/1/16 started 8.2.2 - changes to ease compiling C++ binding with MSVC [Lovell Fuller] - reorder file tests to put slow loaders last diff --git a/TODO b/TODO index 78e39756..a3dd5f54 100644 --- a/TODO +++ b/TODO @@ -45,9 +45,10 @@ more small tweaks $ time vipsthumbnail wtc.tif -o x.tif -s 7000 - real 0m1.843s - user 0m6.040s - sys 0m0.252s + real 0m1.818s + user 0m5.956s + sys 0m0.296s + - get some brightly coloured spots with nohalo / vsqbs on wobble.ws ... very diff --git a/configure.ac b/configure.ac index d9f60b69..bfce240a 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # also update the version number in the m4 macros below -AC_INIT([vips], [8.2.2], [vipsip@jiscmail.ac.uk]) +AC_INIT([vips], [8.3.0], [vipsip@jiscmail.ac.uk]) # required for gobject-introspection AC_PREREQ(2.62) @@ -17,8 +17,8 @@ AC_CONFIG_MACRO_DIR([m4]) # user-visible library versioning m4_define([vips_major_version], [8]) -m4_define([vips_minor_version], [2]) -m4_define([vips_micro_version], [2]) +m4_define([vips_minor_version], [3]) +m4_define([vips_micro_version], [0]) m4_define([vips_version], [vips_major_version.vips_minor_version.vips_micro_version]) @@ -37,9 +37,9 @@ VIPS_VERSION_STRING=$VIPS_VERSION-`date` # binary interface changes backwards compatible?: increment age # binary interface changes not backwards compatible?: reset age to 0 -LIBRARY_CURRENT=45 -LIBRARY_REVISION=2 -LIBRARY_AGE=3 +LIBRARY_CURRENT=46 +LIBRARY_REVISION=0 +LIBRARY_AGE=4 # patched into include/vips/version.h AC_SUBST(VIPS_VERSION) diff --git a/libvips/resample/reduce.c b/libvips/resample/reduce.c index ebaa02d7..8eebfb7c 100644 --- a/libvips/resample/reduce.c +++ b/libvips/resample/reduce.c @@ -73,38 +73,11 @@ vips_reduce_build( VipsObject *object ) if( VIPS_OBJECT_CLASS( vips_reduce_parent_class )->build( object ) ) return( -1 ); - /* - if( vips_reduceh( resample->in, &t[0], reduce->xshrink, NULL ) || - vips_linecache( t[0], &t[1], - "tile_height", 4, - NULL ) || - vips_reducev( t[1], &t[2], reduce->yshrink, NULL ) || - vips_image_write( t[2], resample->out ) ) - return( -1 ); - */ - - /* - if( vips_reducev( resample->in, &t[0], reduce->yshrink, NULL ) || - vips_linecache( t[0], &t[1], - "tile_height", 4, - NULL ) || - vips_reduceh( t[1], &t[2], reduce->xshrink, NULL ) || - vips_image_write( t[2], resample->out ) ) - return( -1 ); - */ - if( vips_reducev( resample->in, &t[0], reduce->yshrink, NULL ) || vips_reduceh( t[0], &t[1], reduce->xshrink, NULL ) || vips_image_write( t[1], resample->out ) ) return( -1 ); - /* - if( vips_reduceh( resample->in, &t[0], reduce->xshrink, NULL ) || - vips_reducev( t[0], &t[1], reduce->yshrink, NULL ) || - vips_image_write( t[1], resample->out ) ) - return( -1 ); - */ - return( 0 ); } diff --git a/libvips/resample/resize.c b/libvips/resample/resize.c index 36947d30..5c4bd393 100644 --- a/libvips/resample/resize.c +++ b/libvips/resample/resize.c @@ -230,18 +230,26 @@ vips_resize_build( VipsObject *object ) vips_info( class->nickname, "%s interpolation", nickname ); } - /* - if( vips_affine( in, &t[3], hresidual, 0, 0, vresidual, - "interpolate", resize->interpolate, - "idx", resize->idx, - "idy", resize->idy, - NULL ) ) - return( -1 ); + /* We have a special path for bicubic, idx/idy == 0. */ - - if( vips_reduce( in, &t[3], 1.0 / hresidual, 1.0 / vresidual, NULL ) ) - return( -1 ); - + if( resize->interpolate && + strcmp( VIPS_OBJECT_GET_CLASS( resize->interpolate )->nickname, + "bicubic" ) == 0 && + resize->idx == 0.0 && + resize->idy == 0.0 ) { + vips_info( class->nickname, "using fast path for residual" ); + if( vips_reduce( in, &t[3], + 1.0 / hresidual, 1.0 / vresidual, NULL ) ) + return( -1 ); + } + else { + if( vips_affine( in, &t[3], hresidual, 0, 0, vresidual, + "interpolate", resize->interpolate, + "idx", resize->idx, + "idy", resize->idy, + NULL ) ) + return( -1 ); + } in = t[3]; /* If we are upsampling, don't sharpen. Also don't sharpen if we diff --git a/libvips/resample/similarity.c b/libvips/resample/similarity.c index 2d298cc4..5c9ea8f3 100644 --- a/libvips/resample/similarity.c +++ b/libvips/resample/similarity.c @@ -47,6 +47,7 @@ #include #include +#include #include @@ -78,24 +79,43 @@ vips_similarity_build( VipsObject *object ) VipsImage **t = (VipsImage **) vips_object_local_array( object, 4 ); - double a, b, c, d; - if( VIPS_OBJECT_CLASS( vips_similarity_parent_class )->build( object ) ) return( -1 ); - a = similarity->scale * cos( VIPS_RAD( similarity->angle ) ); - b = similarity->scale * -sin( VIPS_RAD( similarity->angle ) ); - c = -b; - d = a; + /* Use vips_reduce(), if we can. + */ + if( similarity->interpolate && + strcmp( VIPS_OBJECT_GET_CLASS( similarity->interpolate )-> + nickname, "bicubic" ) == 0 && + 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 ); + } + else { + double a = similarity->scale * + cos( VIPS_RAD( similarity->angle ) ); + double b = similarity->scale * + -sin( VIPS_RAD( similarity->angle ) ); + double c = -b; + double d = a; - if( vips_affine( resample->in, &t[0], a, b, c, d, - "interpolate", similarity->interpolate, - "odx", similarity->odx, - "ody", similarity->ody, - "idx", similarity->idx, - "idy", similarity->idy, - NULL ) || - vips_image_write( t[0], resample->out ) ) + if( vips_affine( resample->in, &t[0], a, b, c, d, + "interpolate", similarity->interpolate, + "odx", similarity->odx, + "ody", similarity->ody, + "idx", similarity->idx, + "idy", similarity->idy, + NULL ) ) + return( -1 ); + } + + if( vips_image_write( t[0], resample->out ) ) return( -1 ); return( 0 );