From 9b6f96ed41e0a92a2e59750b73a9a4d8b031b4b6 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Fri, 2 Aug 2013 09:41:11 +0100 Subject: [PATCH] redo falsecolour, gammacorrect as classes --- ChangeLog | 7 +- TODO | 3 +- libvips/conversion/Makefile.am | 3 +- libvips/conversion/conversion.c | 4 + .../{im_falsecolour.c => falsecolour.c} | 113 ++++++++++--- libvips/conversion/gammacorrect.c | 159 ++++++++++++++++++ libvips/deprecated/vips7compat.c | 36 ++++ libvips/histogram/Makefile.am | 1 - libvips/histogram/im_gammacorrect.c | 84 --------- libvips/include/vips/conversion.h | 7 +- libvips/include/vips/histogram.h | 1 - libvips/include/vips/vips7compat.h | 3 + 12 files changed, 298 insertions(+), 123 deletions(-) rename libvips/conversion/{im_falsecolour.c => falsecolour.c} (72%) create mode 100644 libvips/conversion/gammacorrect.c delete mode 100644 libvips/histogram/im_gammacorrect.c diff --git a/ChangeLog b/ChangeLog index cca15af2..e5d90a26 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,9 +2,10 @@ - added vips_matrixload() and vips_matrixsave(), load and save vips mat format - rename image arrays as image matrices ... INTERPRETATION_ARRAY -> INTERPRETATION_MATRIX etc. -- rewrite im_buildlut(), im_identity*(), im_maplut() as classes -- added vips_error_freeze()/vips_error_thaw() -- used freeze()/thaw() to stop file format sniffers logging spurious errors +- rewrite im_buildlut(), im_identity*(), im_maplut(), im_falsecolour(), + im_gammacorrect() as classes +- added vips_error_freeze() / vips_error_thaw() +- used freeze() / thaw() to stop file format sniffers logging spurious errors - vipsthumbnail uses embedded jpg thumbnails if it can 3/7/13 started 7.34.2 diff --git a/TODO b/TODO index f330def8..fc79bbfd 100644 --- a/TODO +++ b/TODO @@ -30,7 +30,6 @@ we've moved all the no-input ones of to create now, I think - - object construction is threadsafe, but class construction is not https://github.com/jcupitt/libvips/issues/64 @@ -38,7 +37,7 @@ we worked around this by adding vips_class_ping_all() to dsave build, but this is not a good fix - find out why vips class construct fails, test on seurat, kirk's 12-core + find out why vips class construct fails, test on seurat, kirk's 24-core monster diff --git a/libvips/conversion/Makefile.am b/libvips/conversion/Makefile.am index 47b7f026..f0ab2221 100644 --- a/libvips/conversion/Makefile.am +++ b/libvips/conversion/Makefile.am @@ -4,6 +4,7 @@ libconversion_la_SOURCES = \ conversion.c \ pconversion.h \ tilecache.c \ + gammacorrect.c \ sequential.c \ flatten.c \ cache.c \ @@ -23,7 +24,7 @@ libconversion_la_SOURCES = \ bandary.c \ rot.c \ ifthenelse.c \ - im_falsecolour.c \ + falsecolour.c \ msb.c \ grid.c \ scale.c \ diff --git a/libvips/conversion/conversion.c b/libvips/conversion/conversion.c index df67835d..4e94d75b 100644 --- a/libvips/conversion/conversion.c +++ b/libvips/conversion/conversion.c @@ -153,6 +153,8 @@ vips_conversion_operation_init( void ) extern GType vips_text_get_type( void ); #endif /*HAVE_PANGOFT2*/ extern GType vips_xyz_get_type( void ); + extern GType vips_falsecolour_get_type( void ); + extern GType vips_gammacorrect_get_type( void ); vips_copy_get_type(); vips_tile_cache_get_type(); @@ -186,6 +188,8 @@ vips_conversion_operation_init( void ) vips_text_get_type(); #endif /*HAVE_PANGOFT2*/ vips_xyz_get_type(); + vips_falsecolour_get_type(); + vips_gammacorrect_get_type(); } /* The common part of most binary conversion diff --git a/libvips/conversion/im_falsecolour.c b/libvips/conversion/falsecolour.c similarity index 72% rename from libvips/conversion/im_falsecolour.c rename to libvips/conversion/falsecolour.c index cfc28248..d522744a 100644 --- a/libvips/conversion/im_falsecolour.c +++ b/libvips/conversion/falsecolour.c @@ -12,6 +12,8 @@ * - gtkdoc * 12/7/11 * - force input to mono 8-bit for the user + * 1/8/13 + * - redone as a class */ /* @@ -51,9 +53,21 @@ #include +#include "pconversion.h" + +typedef struct _VipsFalsecolour { + VipsConversion parent_instance; + + VipsImage *in; +} VipsFalsecolour; + +typedef VipsConversionClass VipsFalsecolourClass; + +G_DEFINE_TYPE( VipsFalsecolour, vips_falsecolour, VIPS_TYPE_CONVERSION ); + /* Falsecolour scale nicked from a PET scan. */ -static unsigned char PET_colour[][3] = { +static unsigned char vips_falsecolour_pet[][3] = { { 12, 0, 25 }, { 17, 0, 34 }, { 20, 0, 41 }, @@ -312,45 +326,88 @@ static unsigned char PET_colour[][3] = { { 174, 0, 0 } }; +static int +vips_falsecolour_build( VipsObject *object ) +{ + VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object ); + VipsConversion *conversion = VIPS_CONVERSION( object ); + VipsFalsecolour *falsecolour = (VipsFalsecolour *) object; + VipsImage **t = (VipsImage **) vips_object_local_array( object, 4 ); + + if( VIPS_OBJECT_CLASS( vips_falsecolour_parent_class )-> + build( object ) ) + return( -1 ); + + if( !(t[0] = vips_image_new_from_memory( (void *) vips_falsecolour_pet, + 1, VIPS_NUMBER( vips_falsecolour_pet ), 3, + VIPS_FORMAT_UCHAR )) ) + return( -1 ); + + /* Force to mono 8-bit. + */ + if( vips_check_uncoded( class->nickname, falsecolour->in ) || + vips_extract_band( falsecolour->in, &t[1], 0, NULL ) || + vips_cast( t[1], &t[2], VIPS_FORMAT_UCHAR, NULL ) || + vips_maplut( falsecolour->in, &t[3], t[0], NULL ) || + vips_image_write( t[3], conversion->out ) ) + return( -1 ); + + return( 0 ); +} + +static void +vips_falsecolour_class_init( VipsFalsecolourClass *class ) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS( class ); + VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS( class ); + VipsOperationClass *operation_class = VIPS_OPERATION_CLASS( class ); + + gobject_class->set_property = vips_object_set_property; + gobject_class->get_property = vips_object_get_property; + + vobject_class->nickname = "falsecolour"; + vobject_class->description = _( "false colour an image" ); + vobject_class->build = vips_falsecolour_build; + + operation_class->flags = VIPS_OPERATION_SEQUENTIAL; + + VIPS_ARG_IMAGE( class, "in", 0, + _( "in" ), + _( "Input image" ), + VIPS_ARGUMENT_REQUIRED_INPUT, + G_STRUCT_OFFSET( VipsFalsecolour, in ) ); + +} + +static void +vips_falsecolour_init( VipsFalsecolour *falsecolour ) +{ +} + /** - * im_falsecolour: - * @in: input image + * vips_falsecolour: + * @in: input image * @out: output image + * @...: %NULL-terminated list of optional named arguments * * Force @in to 1 band, 8-bit, then transform to - * 3-band 8-bit image with a false colour + * a 3-band 8-bit image with a false colour * map. The map is supposed to make small differences in brightness more * obvious. * - * See also: im_maplut(). + * See also: vips_maplut(). * * Returns: 0 on success, -1 on error */ int -im_falsecolour( IMAGE *in, IMAGE *out ) +vips_falsecolour( VipsImage *in, VipsImage **out, ... ) { - IMAGE *t[2]; - IMAGE *lut; + va_list ap; + int result; - /* Check our args, force to mono 8-bit. - */ - if( im_piocheck( in, out ) || - im_check_uncoded( "im_falsecolour", in ) || - im_open_local_array( out, t, 2, "im_falsecolour", "p" ) || - im_extract_band( in, t[0], 0 ) || - im_clip2fmt( t[0], t[1], IM_BANDFMT_UCHAR ) ) - return( -1 ); - in = t[1]; + va_start( ap, out ); + result = vips_call_split( "falsecolour", ap, in, out ); + va_end( ap ); - if( !(lut = im_image( (VipsPel *) PET_colour, - 1, 256, 3, IM_BANDFMT_UCHAR )) ) - return( -1 ); - if( im_maplut( in, out, lut ) ) { - im_close( lut ); - return( -1 ); - } - - im_close( lut ); - - return( 0 ); + return( result ); } diff --git a/libvips/conversion/gammacorrect.c b/libvips/conversion/gammacorrect.c new file mode 100644 index 00000000..6de28524 --- /dev/null +++ b/libvips/conversion/gammacorrect.c @@ -0,0 +1,159 @@ +/* Gamma-correct image with factor gammafactor. + * + * Copyright: 1990, N. Dessipris. + * + * Written on: 19/07/1990 + * Modified on: + * 19/6/95 JC + * - redone as library function + * 23/3/10 + * - gtkdoc + * - 16 bit as well + * 1/8/13 + * - redone 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 "pconversion.h" + +typedef struct _VipsGammacorrect { + VipsConversion parent_instance; + + VipsImage *in; + double exponent; +} VipsGammacorrect; + +typedef VipsConversionClass VipsGammacorrectClass; + +G_DEFINE_TYPE( VipsGammacorrect, vips_gammacorrect, VIPS_TYPE_CONVERSION ); + +static int +vips_gammacorrect_build( VipsObject *object ) +{ + VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object ); + VipsConversion *conversion = VIPS_CONVERSION( object ); + VipsGammacorrect *gammacorrect = (VipsGammacorrect *) object; + VipsImage **t = (VipsImage **) vips_object_local_array( object, 5 ); + VipsImage *in = gammacorrect->in; + + double mx1, mx2; + + if( VIPS_OBJECT_CLASS( vips_gammacorrect_parent_class )-> + build( object ) ) + return( -1 ); + + if( vips_check_u8or16( class->nickname, in ) || + vips_identity( &t[0], + "ushort", in->BandFmt == VIPS_FORMAT_USHORT, + NULL ) || + vips_pow_const1( t[0], &t[1], gammacorrect->exponent, NULL ) || + vips_max( t[0], &mx1, NULL ) || + vips_max( t[1], &mx2, NULL ) || + vips_linear1( t[1], &t[2], mx1 / mx2, 0, NULL ) || + vips_cast( t[2], &t[3], in->BandFmt, NULL ) || + vips_maplut( in, &t[4], t[3], NULL ) || + vips_image_write( t[4], conversion->out ) ) + return( -1 ); + + return( 0 ); +} + +static void +vips_gammacorrect_class_init( VipsGammacorrectClass *class ) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS( class ); + VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS( class ); + VipsOperationClass *operation_class = VIPS_OPERATION_CLASS( class ); + + gobject_class->set_property = vips_object_set_property; + gobject_class->get_property = vips_object_get_property; + + vobject_class->nickname = "gammacorrect"; + vobject_class->description = _( "gammacorrect a pair of images" ); + vobject_class->build = vips_gammacorrect_build; + + operation_class->flags = VIPS_OPERATION_SEQUENTIAL; + + VIPS_ARG_IMAGE( class, "in", -1, + _( "in" ), + _( "Input image" ), + VIPS_ARGUMENT_REQUIRED_INPUT, + G_STRUCT_OFFSET( VipsGammacorrect, in ) ); + + VIPS_ARG_DOUBLE( class, "exponent", 0, + _( "exponent" ), + _( "Gamma factor" ), + VIPS_ARGUMENT_OPTIONAL_INPUT, + G_STRUCT_OFFSET( VipsGammacorrect, exponent ), + 0.000001, 1000.0, 2.4 ); + +} + +static void +vips_gammacorrect_init( VipsGammacorrect *gammacorrect ) +{ + gammacorrect->exponent = 2.4; +} + +/** + * vips_gammacorrect: + * @in: input image + * @out: output image + * @...: %NULL-terminated list of optional named arguments + * + * Optional arguments: + * + * @exponent: gamma factor, default 2.4 + * + * Gamma-correct an 8- or 16-bit unsigned image with a lookup table. The + * output format is the same as the input format. + * + * See also: vips_identity(), vips_pow_const1(), vips_maplut() + * + * Returns: 0 on success, -1 on error + */ +int +vips_gammacorrect( VipsImage *in, VipsImage **out, ... ) +{ + va_list ap; + int result; + + va_start( ap, out ); + result = vips_call_split( "gammacorrect", ap, in, out ); + va_end( ap ); + + return( result ); +} diff --git a/libvips/deprecated/vips7compat.c b/libvips/deprecated/vips7compat.c index 2e08d7ef..0a775950 100644 --- a/libvips/deprecated/vips7compat.c +++ b/libvips/deprecated/vips7compat.c @@ -3324,6 +3324,42 @@ im_maplut( IMAGE *in, IMAGE *out, IMAGE *lut ) return( 0 ); } +int +im_falsecolour( IMAGE *in, IMAGE *out ) +{ + VipsImage *x; + + if( vips_falsecolour( in, &x, NULL ) ) + return( -1 ); + + if( im_copy( x, out ) ) { + g_object_unref( x ); + return( -1 ); + } + g_object_unref( x ); + + return( 0 ); +} + +int +im_gammacorrect( IMAGE *in, IMAGE *out, double exponent ) +{ + VipsImage *x; + + if( vips_gammacorrect( in, &x, + "exponent", exponent, + NULL ) ) + return( -1 ); + + if( im_copy( x, out ) ) { + g_object_unref( x ); + return( -1 ); + } + g_object_unref( x ); + + return( 0 ); +} + /* This is used by the carrierwave shrinker to cache the * output of shrink before doing the final affine. * diff --git a/libvips/histogram/Makefile.am b/libvips/histogram/Makefile.am index 3a3d7b11..072d99df 100644 --- a/libvips/histogram/Makefile.am +++ b/libvips/histogram/Makefile.am @@ -5,7 +5,6 @@ libhistogram_la_SOURCES = \ histogram.c \ phistogram.h \ hist_dispatch.c \ - im_gammacorrect.c \ im_heq.c \ im_hist.c \ im_histeq.c \ diff --git a/libvips/histogram/im_gammacorrect.c b/libvips/histogram/im_gammacorrect.c deleted file mode 100644 index 5ba68a07..00000000 --- a/libvips/histogram/im_gammacorrect.c +++ /dev/null @@ -1,84 +0,0 @@ -/* Gamma-correct image with factor gammafactor. - * - * Copyright: 1990, N. Dessipris. - * - * Written on: 19/07/1990 - * Modified on: - * 19/6/95 JC - * - redone as library function - * 23/3/10 - * - gtkdoc - * - 16 bit as well - */ - -/* - - 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 - -/** - * im_gammacorrect: - * @in: input image - * @out: output image - * @exponent: gamma factor - * - * Gamma-correct an 8- or 16-bit unsigned image with a lookup table. The - * output format is the same as the input format. - * - * See also: im_identity(), im_powtra(), im_maplut() - * - * Returns: 0 on success, -1 on error - */ -int -im_gammacorrect( IMAGE *in, IMAGE *out, double exponent ) -{ - IMAGE *t[4]; - double mx1, mx2; - - if( im_open_local_array( out, t, 4, "im_gammacorrect", "p" ) || - im_check_u8or16( "im_gammacorrect", in ) || - im_piocheck( in, out ) || - (in->BandFmt == IM_BANDFMT_UCHAR ? - im_identity( t[0], 1 ) : - im_identity_ushort( t[0], 1, 65536 )) || - im_powtra( t[0], t[1], exponent ) || - im_max( t[0], &mx1 ) || - im_max( t[1], &mx2 ) || - im_lintra( mx1 / mx2, t[1], 0, t[2] ) || - im_clip2fmt( t[2], t[3], in->BandFmt ) || - im_maplut( in, out, t[3] ) ) - return( -1 ); - - return( 0 ); -} diff --git a/libvips/include/vips/conversion.h b/libvips/include/vips/conversion.h index 8dd65a5d..320e9909 100644 --- a/libvips/include/vips/conversion.h +++ b/libvips/include/vips/conversion.h @@ -256,9 +256,10 @@ int vips_ifthenelse( VipsImage *cond, VipsImage *in1, VipsImage *in2, int vips_flatten( VipsImage *in, VipsImage **out, ... ) __attribute__((sentinel)); - - -int im_falsecolour( VipsImage *in, VipsImage *out ); +int vips_falsecolour( VipsImage *in, VipsImage **out, ... ) + __attribute__((sentinel)); +int vips_gammacorrect( VipsImage *in, VipsImage **out, ... ) + __attribute__((sentinel)); int im_insertset( VipsImage *main, VipsImage *sub, VipsImage *out, int n, int *x, int *y ); diff --git a/libvips/include/vips/histogram.h b/libvips/include/vips/histogram.h index e329fa3b..ac9260e4 100644 --- a/libvips/include/vips/histogram.h +++ b/libvips/include/vips/histogram.h @@ -57,7 +57,6 @@ int im_histplot( VipsImage *in, VipsImage *out ); int im_hist( VipsImage *in, VipsImage *out, int bandno ); int im_hsp( VipsImage *in, VipsImage *ref, VipsImage *out ); -int im_gammacorrect( VipsImage *in, VipsImage *out, double exponent ); int im_mpercent( VipsImage *in, double percent, int *out ); int im_mpercent_hist( VipsImage *hist, double percent, int *out ); diff --git a/libvips/include/vips/vips7compat.h b/libvips/include/vips/vips7compat.h index 6d0855e3..a9604e31 100644 --- a/libvips/include/vips/vips7compat.h +++ b/libvips/include/vips/vips7compat.h @@ -763,6 +763,9 @@ int im_recomb( VipsImage *in, VipsImage *out, DOUBLEMASK *recomb ); int im_argb2rgba( VipsImage *in, VipsImage *out ); +int im_falsecolour( VipsImage *in, VipsImage *out ); +int im_gammacorrect( VipsImage *in, VipsImage *out, double exponent ); + int im_shrink( VipsImage *in, VipsImage *out, double xshrink, double yshrink ); int im_affinei( VipsImage *in, VipsImage *out, VipsInterpolate *interpolate,