From e1f2c0677248f71c34f45efd9bab110b94725943 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sat, 2 Nov 2013 09:33:10 +0000 Subject: [PATCH] add @point subsample mode to vips_subsample() --- ChangeLog | 1 + libvips/conversion/subsample.c | 35 +++++++++++++++++++++++++++------- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 19902d8e..0776cbfb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -9,6 +9,7 @@ vips_image_pipeline() to do both jobs - vipsthumbnail allows non-square bounding boxes, thanks seth - add vips_matrixprint() +- add @point subsample mode to vips_subsample() 18/10/13 started 7.36.3 - fix compiler warnings in ubuntu 13.10 diff --git a/libvips/conversion/subsample.c b/libvips/conversion/subsample.c index d4ace719..4f0c7aa0 100644 --- a/libvips/conversion/subsample.c +++ b/libvips/conversion/subsample.c @@ -11,6 +11,8 @@ * - gtkdoc * 1/6/13 * - redo as a class + * 2/11/13 + * - add @point to force point sample mode */ /* @@ -55,12 +57,10 @@ typedef struct _VipsSubsample { VipsConversion parent_instance; - /* The input image. - */ VipsImage *in; - - int xfac; /* Subsample factors */ + int xfac; int yfac; + gboolean point; } VipsSubsample; @@ -215,6 +215,7 @@ vips_subsample_build( VipsObject *object ) if( vips_image_pipelinev( conversion->out, VIPS_DEMAND_STYLE_THINSTRIP, subsample->in, NULL ) ) return( -1 ); + /* Prepare output. Note: we round the output width down! */ conversion->out->Xsize = subsample->in->Xsize / subsample->xfac; @@ -228,13 +229,15 @@ vips_subsample_build( VipsObject *object ) return( -1 ); } - /* Generate! If this is a very large shrink, then it's - * probably faster to do it a pixel at a time. + /* Generate! If this is a very large shrink, then it's probably faster + * to do it a pixel at a time. */ - if( subsample->xfac > 10 ) + if( subsample->point || + subsample->xfac > 10 ) subsample_fn = vips_subsample_point_gen; else subsample_fn = vips_subsample_line_gen; + if( vips_image_generate( conversion->out, vips_start_one, subsample_fn, vips_stop_one, subsample->in, subsample ) ) @@ -284,6 +287,13 @@ vips_subsample_class_init( VipsSubsampleClass *class ) G_STRUCT_OFFSET( VipsSubsample, yfac ), 1, RANGE, 1 ); + VIPS_ARG_BOOL( class, "point", 2, + _( "Point" ), + _( "Point sample" ), + VIPS_ARGUMENT_OPTIONAL_INPUT, + G_STRUCT_OFFSET( VipsSubsample, point ), + FALSE ); + } static void @@ -299,9 +309,20 @@ vips_subsample_init( VipsSubsample *subsample ) * @yfac: vertical shrink factor * @...: %NULL-terminated list of optional named arguments * + * Optional arguments: + * + * @point: turn on point sample mode + * * Subsample an image by an integer fraction. This is fast, nearest-neighbour * shrink. * + * For small horizontal shrinks, this operation will fetch lines of pixels + * from @in and then subsample that line. For large shrinks it will fetch + * single pixels. + * + * If @point is set, @in will always be sampled in points. This can be faster + * if the previous operations in the pipeline are very slow. + * * See also: vips_affine(), vips_shrink(), vips_zoom(). * * Returns: 0 on success, -1 on error.