From 4311d452f12977851030a07532dfcdeeba2df17d Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Thu, 30 May 2013 16:29:58 +0100 Subject: [PATCH] redo im_scale() as a class --- ChangeLog | 2 +- libvips/conversion/Makefile.am | 2 +- libvips/conversion/conversion.c | 2 + libvips/conversion/copy.c | 3 +- libvips/conversion/grid.c | 4 +- libvips/conversion/im_scale.c | 100 ----------------- libvips/conversion/scale.c | 165 +++++++++++++++++++++++++++++ libvips/deprecated/vips7compat.c | 18 +++- libvips/include/vips/conversion.h | 6 +- libvips/include/vips/vips7compat.h | 1 + po/POTFILES.in | 5 +- 11 files changed, 198 insertions(+), 110 deletions(-) delete mode 100644 libvips/conversion/im_scale.c create mode 100644 libvips/conversion/scale.c diff --git a/ChangeLog b/ChangeLog index 6bf62058..008c3894 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,7 +3,7 @@ - turn off caching for im_copy()/vips_copy(), we use copy to stop sharing, and it's cheap so caching doesn't help anyway - auto rshift down to 8 bits on save, if necessary -- im_gaussnoise(), im_copy_file(), im_grid() redone as classes +- im_gaussnoise(), im_copy_file(), im_grid(), im_scale() redone as classes - add --angle option to dzsave 14/5/13 started 7.32.4 diff --git a/libvips/conversion/Makefile.am b/libvips/conversion/Makefile.am index de5e1de3..ef2a667c 100644 --- a/libvips/conversion/Makefile.am +++ b/libvips/conversion/Makefile.am @@ -29,7 +29,7 @@ libconversion_la_SOURCES = \ im_falsecolour.c \ im_msb.c \ grid.c \ - im_scale.c \ + scale.c \ im_scaleps.c \ im_subsample.c \ im_system.c \ diff --git a/libvips/conversion/conversion.c b/libvips/conversion/conversion.c index 670947d3..c74daede 100644 --- a/libvips/conversion/conversion.c +++ b/libvips/conversion/conversion.c @@ -127,6 +127,7 @@ vips_conversion_operation_init( void ) extern GType vips_bandbool_get_type( void ); extern GType vips_gaussnoise_get_type( void ); extern GType vips_grid_get_type( void ); + extern GType vips_scale_get_type( void ); vips_copy_get_type(); vips_tile_cache_get_type(); @@ -151,6 +152,7 @@ vips_conversion_operation_init( void ) vips_bandbool_get_type(); vips_gaussnoise_get_type(); vips_grid_get_type(); + vips_scale_get_type(); } /* The common part of most binary conversion diff --git a/libvips/conversion/copy.c b/libvips/conversion/copy.c index 8faafc5d..6bc6ba1f 100644 --- a/libvips/conversion/copy.c +++ b/libvips/conversion/copy.c @@ -464,6 +464,7 @@ vips_copy( VipsImage *in, VipsImage **out, ... ) * vips_copy_file: * @in: input image * @out: output image + * @...: %NULL-terminated list of optional named arguments * * A simple convenience function to copy an image to a file, then copy * again to output. If the image is already a file, just copy straight @@ -477,7 +478,7 @@ vips_copy( VipsImage *in, VipsImage **out, ... ) * Returns: 0 on success, -1 on error */ int -vips_copy_file( VipsImage *in, VipsImage **out ) +vips_copy_file( VipsImage *in, VipsImage **out, ... ) { VipsImage *file; diff --git a/libvips/conversion/grid.c b/libvips/conversion/grid.c index 46cd17ad..17c34306 100644 --- a/libvips/conversion/grid.c +++ b/libvips/conversion/grid.c @@ -1,4 +1,4 @@ -/* im_grid +/* vips_grid * * 4/8/05 * 7/9/05 @@ -6,6 +6,8 @@ * 30/1/10 * - gtkdoc * - small cleanups + * 30/5/13 + * - redo as a class */ /* diff --git a/libvips/conversion/im_scale.c b/libvips/conversion/im_scale.c deleted file mode 100644 index 999adca4..00000000 --- a/libvips/conversion/im_scale.c +++ /dev/null @@ -1,100 +0,0 @@ -/* im_scale - * - * Author: John Cupitt - * Written on: 22/4/93 - * Modified on: - * 30/6/93 JC - * - adapted for partial v2 - * - ANSI - * 31/8/93 JC - * - calculation of offset now includes scale - * 8/5/06 - * - set Type on output too - * 16/10/06 - * - what? no, don't set Type, useful to be able to scale histograms, for - * example - * 1/2/10 - * - gtkdoc - */ - -/* - - This file is part of VIPS. - - VIPS is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301 USA - - */ - -/* - - These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk - - */ - -#ifdef HAVE_CONFIG_H -#include -#endif /*HAVE_CONFIG_H*/ -#include - -#include -#include - -#include - -/** - * im_scale: - * @in: input image - * @out: output image - * - * Search the image for the maximum and minimum value, then return the image - * as unsigned 8-bit, scaled so that the maximum value is 255 and the - * minimum is zero. - * - * See also: im_clip2fmt(), im_scaleps(). - * - * Returns: 0 on success, -1 on error - */ -int -im_scale( IMAGE *in, IMAGE *out ) -{ - DOUBLEMASK *stats; - IMAGE *t = im_open_local( out, "im_scale:1", "p" ); - double mx, mn; - double scale, offset; - - /* Measure min and max, calculate transform. - */ - if( !t || !(stats = im_stats( in )) ) - return( -1 ); - mn = VIPS_MASK( stats, 0, 0 ); - mx = VIPS_MASK( stats, 1, 0 ); - im_free_dmask( stats ); - - if( mn == mx ) - /* Range of zero: just return black. - */ - return( im_black( out, in->Xsize, in->Ysize, in->Bands ) ); - scale = 255.0 / (mx - mn); - offset = -(mn * scale); - - /* Transform! - */ - if( im_lintra( scale, in, offset, t ) || - im_clip2fmt( t, out, IM_BANDFMT_UCHAR ) ) - return( -1 ); - - return( 0 ); -} diff --git a/libvips/conversion/scale.c b/libvips/conversion/scale.c new file mode 100644 index 00000000..3a434339 --- /dev/null +++ b/libvips/conversion/scale.c @@ -0,0 +1,165 @@ +/* im_scale + * + * Author: John Cupitt + * Written on: 22/4/93 + * Modified on: + * 30/6/93 JC + * - adapted for partial v2 + * - ANSI + * 31/8/93 JC + * - calculation of offset now includes scale + * 8/5/06 + * - set Type on output too + * 16/10/06 + * - what? no, don't set Type, useful to be able to scale histograms, for + * example + * 1/2/10 + * - gtkdoc + * 30/5/13 + * - redo as a class + */ + +/* + + This file is part of VIPS. + + VIPS is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA + + */ + +/* + + These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk + + */ + +#ifdef HAVE_CONFIG_H +#include +#endif /*HAVE_CONFIG_H*/ +#include + +#include +#include + +#include + +#include "conversion.h" + +typedef struct _VipsScale { + VipsConversion parent_instance; + + VipsImage *in; + +} VipsScale; + +typedef VipsConversionClass VipsScaleClass; + +G_DEFINE_TYPE( VipsScale, vips_scale, VIPS_TYPE_CONVERSION ); + +#define ARY( im, x, y ) *((double *) VIPS_IMAGE_ADDR( im, x, y )) + +static int +vips_scale_build( VipsObject *object ) +{ + VipsConversion *conversion = VIPS_CONVERSION( object ); + VipsScale *scale = (VipsScale *) object; + VipsImage **t = (VipsImage **) vips_object_local_array( object, 7 ); + + double mx; + double mn; + + if( VIPS_OBJECT_CLASS( vips_scale_parent_class )->build( object ) ) + return( -1 ); + + if( vips_stats( scale->in, &t[0], NULL ) ) + return( -1 ); + mn = ARY( t[0], 0, 0 ); + mx = ARY( t[0], 1, 0 ); + + if( mn == mx ) { + /* Range of zero: just return black. + */ + if( vips_black( &t[1], + scale->in->Xsize, scale->in->Ysize, scale->in->Bands, + NULL ) || + vips_image_write( t[1], conversion->out ) ) + return( -1 ); + } + else { + double f = 255.0 / (mx - mn); + double a = -(mn * f); + + if( vips_linear1( scale->in, &t[2], f, a, NULL ) || + vips_cast( t[2], &t[3], VIPS_FORMAT_UCHAR, NULL ) || + vips_image_write( t[3], conversion->out ) ) + return( -1 ); + } + + return( 0 ); +} + +static void +vips_scale_class_init( VipsScaleClass *class ) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS( class ); + VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS( class ); + + gobject_class->set_property = vips_object_set_property; + gobject_class->get_property = vips_object_get_property; + + vobject_class->nickname = "scale"; + vobject_class->description = _( "scale an image to uchar" ); + vobject_class->build = vips_scale_build; + + VIPS_ARG_IMAGE( class, "in", 1, + _( "Input" ), + _( "Input image" ), + VIPS_ARGUMENT_REQUIRED_INPUT, + G_STRUCT_OFFSET( VipsScale, in ) ); + +} + +static void +vips_scale_init( VipsScale *scale ) +{ +} + +/** + * vips_scale: + * @in: input image + * @out: output image + * @...: %NULL-terminated list of optional named arguments + * + * Search the image for the maximum and minimum value, then return the image + * as unsigned 8-bit, scaled so that the maximum value is 255 and the + * minimum is zero. + * + * See also: vips_cast(). + * + * Returns: 0 on success, -1 on error + */ +int +vips_scale( VipsImage *in, VipsImage **out, ... ) +{ + va_list ap; + int result; + + va_start( ap, out ); + result = vips_call_split( "scale", ap, in, out ); + va_end( ap ); + + return( result ); +} diff --git a/libvips/deprecated/vips7compat.c b/libvips/deprecated/vips7compat.c index 59874100..543f4c32 100644 --- a/libvips/deprecated/vips7compat.c +++ b/libvips/deprecated/vips7compat.c @@ -1511,6 +1511,22 @@ im_grid( VipsImage *in, VipsImage *out, int tile_height, int across, int down ) return( 0 ); } +int +im_scale( VipsImage *in, VipsImage *out ) +{ + VipsImage *t; + + if( vips_scale( in, &t, NULL ) ) + return( -1 ); + if( vips_image_write( t, out ) ) { + g_object_unref( t ); + return( -1 ); + } + g_object_unref( t ); + + return( 0 ); +} + static int vips__math( VipsImage *in, VipsImage *out, VipsOperationMath math ) { @@ -3064,7 +3080,7 @@ im_copy_file( IMAGE *in, IMAGE *out ) { VipsImage *x; - if( vips_copy_file( in, &x ) ) + if( vips_copy_file( in, &x, NULL ) ) return( -1 ); if( im_copy( x, out ) ) { g_object_unref( x ); diff --git a/libvips/include/vips/conversion.h b/libvips/include/vips/conversion.h index d5105e3b..57e643bc 100644 --- a/libvips/include/vips/conversion.h +++ b/libvips/include/vips/conversion.h @@ -168,7 +168,8 @@ int vips_sequential( VipsImage *in, VipsImage **out, ... ) __attribute__((sentinel)); int vips_cache( VipsImage *in, VipsImage **out, ... ) __attribute__((sentinel)); -int vips_copy_file( VipsImage *in, VipsImage **out ); +int vips_copy_file( VipsImage *in, VipsImage **out, ... ) + __attribute__((sentinel)); int vips_embed( VipsImage *in, VipsImage **out, int x, int y, int width, int height, ... ) @@ -214,6 +215,8 @@ int vips_cast_complex( VipsImage *in, VipsImage **out, ... ) __attribute__((sentinel)); int vips_cast_dpcomplex( VipsImage *in, VipsImage **out, ... ) __attribute__((sentinel)); +int vips_scale( VipsImage *in, VipsImage **out, ... ) + __attribute__((sentinel)); int vips_bandjoin( VipsImage **in, VipsImage **out, int n, ... ) __attribute__((sentinel)); @@ -252,7 +255,6 @@ int vips_flatten( VipsImage *in, VipsImage **out, ... ) -int im_scale( VipsImage *in, VipsImage *out ); int im_msb( VipsImage *in, VipsImage *out ); int im_msb_band( VipsImage *in, VipsImage *out, int band ); diff --git a/libvips/include/vips/vips7compat.h b/libvips/include/vips/vips7compat.h index 293a1b5b..e7443ed0 100644 --- a/libvips/include/vips/vips7compat.h +++ b/libvips/include/vips/vips7compat.h @@ -711,6 +711,7 @@ int im_gbandjoin( VipsImage **in, VipsImage *out, int n ); int im_black( VipsImage *out, int x, int y, int bands ); int im_gaussnoise( VipsImage *out, int x, int y, double mean, double sigma ); int im_grid( VipsImage *in, VipsImage *out, int tile_height, int across, int down ); +int im_scale( VipsImage *in, VipsImage *out ); int im_c2amph( VipsImage *in, VipsImage *out ); int im_c2rect( VipsImage *in, VipsImage *out ); diff --git a/po/POTFILES.in b/po/POTFILES.in index 8fe260d0..1096243c 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -62,16 +62,15 @@ libvips/conversion/cast.c libvips/conversion/conversion.c libvips/conversion/flatten.c libvips/conversion/im_subsample.c -libvips/conversion/im_grid.c +libvips/conversion/grid.c libvips/conversion/extract.c libvips/conversion/bandjoin.c libvips/conversion/im_msb.c -libvips/conversion/im_copy_file.c libvips/conversion/black.c libvips/conversion/bandbool.c libvips/conversion/copy.c libvips/conversion/rot.c -libvips/conversion/im_scale.c +libvips/conversion/scale.c libvips/conversion/replicate.c libvips/conversion/join.c libvips/conversion/im_text.c