From 32625146db57b5a341d2fb767dd8072529ea98e7 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 30 Dec 2014 11:27:04 +0000 Subject: [PATCH] cpp can set enums from strings eg. set("extend", "copy")-> --- ChangeLog | 3 +++ TODO | 31 +++++++++++++++++++++++ configure.ac | 6 ++--- cplusplus/VImage.cpp | 49 +++++++++++++++++++++++++++++++++++-- doc/reference/using-cpp.xml | 10 +++++--- libvips/iofuncs/error.c | 3 ++- 6 files changed, 93 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0b0d0794..d3ba590b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +30/12/14 started 7.42.2 +- allow c++ set enum from string + 24/12/14 started 7.42.1 - add gobject-2.0 to Requires: in vips and vips-cpp .pc files - bump soname diff --git a/TODO b/TODO index 6f65a300..35727173 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,34 @@ +- display of optional params should show default value + + also display possible enum values? + + min and max for int/float params? + + maybe: + +$ vips embed +embed an image in a larger image +usage: + embed in out x y width height +where: + in - Input image, input VipsImage + out - Output image, output VipsImage + x - Left edge of input in output, input gint + (default: 0, min: -inf, max: inf) + y - Top edge of input in output, input gint + (default: 0, min: -inf, max: inf) + width - Image width in pixels, input gint + (default: 100, min: 0, max: inf) + height - Image height in pixels, input gint + (default: 100, min: 0, max: inf) +optional arguments: + extend - How to generate the extra pixels, input VipsExtend + (default: black, allowed: copy, extend, mirror) + background - Colour for background pixels, input VipsArrayDouble + (default: 0, min: 0, max: inf) +operation flags: sequential-unbuffered + + - use vips_resize() in vipsthumbnail? should the sharpening filter be selectable? diff --git a/configure.ac b/configure.ac index 5ff1de2b..a38449c5 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # also update the version number in the m4 macros below -AC_INIT([vips], [7.42.1], [vipsip@jiscmail.ac.uk]) +AC_INIT([vips], [7.42.2], [vipsip@jiscmail.ac.uk]) # required for gobject-introspection AC_PREREQ(2.62) @@ -18,7 +18,7 @@ AC_CONFIG_MACRO_DIR([m4]) # user-visible library versioning m4_define([vips_major_version], [7]) m4_define([vips_minor_version], [42]) -m4_define([vips_micro_version], [1]) +m4_define([vips_micro_version], [2]) m4_define([vips_version], [vips_major_version.vips_minor_version.vips_micro_version]) @@ -38,7 +38,7 @@ VIPS_VERSION_STRING=$VIPS_VERSION-`date` # binary interface changes not backwards compatible?: reset age to 0 LIBRARY_CURRENT=40 -LIBRARY_REVISION=0 +LIBRARY_REVISION=1 LIBRARY_AGE=0 # patched into include/vips/version.h diff --git a/cplusplus/VImage.cpp b/cplusplus/VImage.cpp index 8e70f1bc..58921448 100644 --- a/cplusplus/VImage.cpp +++ b/cplusplus/VImage.cpp @@ -1,4 +1,8 @@ -// Object part of VImage class +/* Object part of VImage class + * + * 30/12/14 + * - allow set enum value from string + */ /* @@ -327,6 +331,47 @@ VOption::set( const char *name, VipsBlob **value ) return( this ); } +// just g_object_set_property(), except we allow set enum from string +static void +set_property( VipsObject *object, const char *name, const GValue *value ) +{ + VipsObjectClass *object_class = VIPS_OBJECT_GET_CLASS( object ); + GType type = G_VALUE_TYPE( value ); + + GParamSpec *pspec; + VipsArgumentClass *argument_class; + VipsArgumentInstance *argument_instance; + + if( vips_object_get_argument( object, name, + &pspec, &argument_class, &argument_instance ) ) { + vips_warn( NULL, "%s", vips_error_buffer() ); + vips_error_clear(); + return; + } + + if( G_IS_PARAM_SPEC_ENUM( pspec ) && + type == G_TYPE_STRING ) { + GType pspec_type = G_PARAM_SPEC_VALUE_TYPE( pspec ); + + int enum_value; + GValue value2 = { 0 }; + + if( (enum_value = vips_enum_from_nick( object_class->nickname, + pspec_type, g_value_get_string( value ) )) < 0 ) { + vips_warn( NULL, "%s", vips_error_buffer() ); + vips_error_clear(); + return; + } + + g_value_init( &value2, pspec_type ); + g_value_set_enum( &value2, enum_value ); + g_object_set_property( G_OBJECT( object ), name, &value2 ); + g_value_unset( &value2 ); + } + else + g_object_set_property( G_OBJECT( object ), name, value ); +} + // walk the options and set props on the operation void VOption::set_operation( VipsOperation *operation ) @@ -343,7 +388,7 @@ VOption::set_operation( VipsOperation *operation ) g_free( str_value ); #endif /*VIPS_DEBUG_VERBOSE*/ - g_object_set_property( G_OBJECT( operation ), + set_property( VIPS_OBJECT( operation ), (*i)->name, &(*i)->value ); } } diff --git a/doc/reference/using-cpp.xml b/doc/reference/using-cpp.xml index 32452810..cd3577f6 100644 --- a/doc/reference/using-cpp.xml +++ b/doc/reference/using-cpp.xml @@ -73,7 +73,7 @@ main( int argc, char **argv ) VImage out = in.embed( 10, 10, 1000, 1000, VImage::option()-> - set( "extend", VIPS_EXTEND_BACKGROUND )-> + set( "extend", "background" )-> set( "background", 128 ) ); out.write_to_file( argv[2] ); @@ -113,7 +113,9 @@ main( int argc, char **argv ) In this case we request unbuffered IO for the image, meaning, we expect to do a single top-to-bottom scan of the image and do not - need it to be decompressed entirely. + need it to be decompressed entirely. You can use the C enum name, + as is done in this case, or use a string and have the string + looked up. See below. @@ -197,7 +199,9 @@ VImage VImage::add( VImage right, VOption *options = 0 ); The next line runs vips_embed() with two optional parameters. The first - sets the value to an enum (you just use the ones from the C API), the + sets the value to an enum (here we use a string to set the value, it'll + be looked up in the list of possible enum values, or you can use the + symbols from the C API), the second sets the value to an int. The "background" parameter is actually a #VipsArrayDouble: if you pass an diff --git a/libvips/iofuncs/error.c b/libvips/iofuncs/error.c index 15e879ef..5c5735e4 100644 --- a/libvips/iofuncs/error.c +++ b/libvips/iofuncs/error.c @@ -206,7 +206,8 @@ vips_verror( const char *domain, const char *fmt, va_list ap ) g_mutex_lock( vips__global_lock ); g_assert( vips_error_freeze_count >= 0 ); if( !vips_error_freeze_count ) { - vips_buf_appendf( &vips_error_buf, "%s: ", domain ); + if( domain ) + vips_buf_appendf( &vips_error_buf, "%s: ", domain ); vips_buf_vappendf( &vips_error_buf, fmt, ap ); vips_buf_appends( &vips_error_buf, "\n" ); }