From ed5cb531bdf0e1a3b48f467456f6b469ac00b9cb Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 18 Jul 2011 17:10:41 +0100 Subject: [PATCH] wrap7 works, for images at least still need to add masks, doubles, strings, etc. --- TODO | 17 -------- libvips/deprecated/wrapvips7.c | 77 ++++++---------------------------- libvips/include/vips/object.h | 3 +- libvips/iofuncs/object.c | 54 +++++++----------------- libvips/iofuncs/operation.c | 24 ++++++++++- tools/vips.c | 6 ++- 6 files changed, 54 insertions(+), 127 deletions(-) diff --git a/TODO b/TODO index a16c6262..1faf1b79 100644 --- a/TODO +++ b/TODO @@ -1,20 +1,3 @@ -- try - - vips subtract a b c - - fails in vips_call_argv(), operation gets unreffed too early - - I guess out is not reffing operation? or are we losing a ref somewhere else? - - vips_call_argv_unref_output() gets the value, has a count of 2 after the - get, seems correct - - operation has a count of 3 - - unref the value twice (correctly) on 2nd unref, as the value count hits - zero, the operation is unreffed 3 times, not just once (as it should be) - - - revisit orc conv diff --git a/libvips/deprecated/wrapvips7.c b/libvips/deprecated/wrapvips7.c index 5c43a2ac..df7a8f47 100644 --- a/libvips/deprecated/wrapvips7.c +++ b/libvips/deprecated/wrapvips7.c @@ -31,10 +31,10 @@ */ /* - */ #define DEBUG #define VIPS_DEBUG #define DEBUG_REF + */ #ifdef HAVE_CONFIG_H #include @@ -343,7 +343,8 @@ vips_wrap7_object_set_property( GObject *gobject, * built. */ if( argument_class->flags & VIPS_ARGUMENT_CONSTRUCT && - object->constructed ) { + object->constructed && + !vips_pspec_value_is_null( pspec, value ) ) { g_warning( "%s: %s can't assign '%s' after construct", G_STRLOC, G_OBJECT_TYPE_NAME( gobject ), @@ -354,7 +355,8 @@ vips_wrap7_object_set_property( GObject *gobject, /* If this is a set-once argument, check we've not set it before. */ if( argument_class->flags & VIPS_ARGUMENT_SET_ONCE && - argument_instance->assigned ) { + argument_instance->assigned && + !vips_pspec_value_is_null( pspec, value ) ) { g_warning( "%s: %s can only assign '%s' once", G_STRLOC, G_OBJECT_TYPE_NAME( gobject ), @@ -539,6 +541,12 @@ vips_wrap7_build( VipsObject *object ) return( -1 ); } +#ifdef DEBUG + printf( "vips_wrap7_build: " ); + vips_object_print_name( VIPS_OBJECT( wrap7 ) ); + printf( " building output\n" ); +#endif /*DEBUG*/ + /* Init all the output args. */ (void) vips_argument_map( VIPS_OBJECT( wrap7 ), @@ -635,65 +643,6 @@ vips_wrap7_init( VipsWrap7 *wrap7 ) /* Build a subclass of vips7 for every vips7 operation. */ -static gboolean -drop_postfix( char *str, const char *postfix ) -{ - if( vips_ispostfix( str, postfix ) ) { - str[strlen( str ) - strlen( postfix )] = '\0'; - - return( TRUE ); - } - - return( FALSE ); -} - -/* Turn a vips7 name into a nickname. Eg. im_lintra_vec becomes lin. - */ -static void -vips_wrap7_nickname( const char *in, char *out ) -{ - static const char *dont_drop[] = { - "_set", - }; - static const char *drop[] = { - "_vec", - "const", - "tra", - "set", - "_f" - }; - - int i; - gboolean changed; - - /* Copy, chopping off "im_" prefix. - */ - if( vips_isprefix( "im_", in ) ) - strcpy( out, in + 3 ); - else - strcpy( out, in ); - - /* Repeatedly drop postfixes while we can. Stop if we see a dont_drop - * postfix. - */ - do { - gboolean found; - - found = FALSE; - for( i = 0; i < IM_NUMBER( dont_drop ); i++ ) - if( vips_ispostfix( out, dont_drop[i] ) ) { - found = TRUE; - break; - } - if( found ) - break; - - changed = FALSE; - for( i = 0; i < IM_NUMBER( drop ); i++ ) - changed |= drop_postfix( out, drop[i] ); - } while( changed ); -} - static void vips_wrap7_subclass_class_init( VipsWrap7Class *class ) { @@ -706,7 +655,6 @@ vips_wrap7_subclass_class_init( VipsWrap7Class *class ) strlen( VIPS_WRAP7_PREFIX ); im_function *fn = im_find_function( name ); - char nickname[4096]; int i; g_assert( !class->fn ); @@ -715,8 +663,7 @@ vips_wrap7_subclass_class_init( VipsWrap7Class *class ) gobject_class->set_property = vips_wrap7_object_set_property; gobject_class->get_property = vips_wrap7_object_get_property; - vips_wrap7_nickname( name, nickname ); - vobject_class->nickname = im_strdup( NULL, nickname ); + vobject_class->nickname = im_strdup( NULL, name ); vobject_class->description = fn->desc; class->fn = fn; diff --git a/libvips/include/vips/object.h b/libvips/include/vips/object.h index 0b50de9e..f6081165 100644 --- a/libvips/include/vips/object.h +++ b/libvips/include/vips/object.h @@ -308,6 +308,7 @@ struct _VipsObjectClass { GSList *argument_table_traverse; }; +gboolean vips_pspec_value_is_null( GParamSpec *pspec, const GValue *value ); void vips_object_set_property( GObject *gobject, guint property_id, const GValue *value, GParamSpec *pspec ); void vips_object_get_property( GObject *gobject, @@ -352,8 +353,6 @@ int vips_class_depth( VipsObjectClass *klass ); VipsObjectClass *vips_class_find( const char *basename, const char *nickname ); GType vips_type_find( const char *basename, const char *nickname ); -int vips_object_unref( VipsObject *obj ); - void vips_object_local_cb( VipsObject *vobject, GObject *gobject ); #define vips_object_local( V, G ) \ (g_signal_connect( V, "close", \ diff --git a/libvips/iofuncs/object.c b/libvips/iofuncs/object.c index 264c7ce3..20f81e6b 100644 --- a/libvips/iofuncs/object.c +++ b/libvips/iofuncs/object.c @@ -385,19 +385,6 @@ vips_object_clear_member( VipsObject *object, GParamSpec *pspec, } } -/* Clear a member variable, where the member has an offset. - */ -static void -vips_object_clear_object( VipsObject *object, GParamSpec *pspec ) -{ - VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object ); - VipsArgumentClass *argument_class = (VipsArgumentClass *) - vips__argument_table_lookup( class->argument_table, pspec ); - - vips_object_clear_member( object, pspec, - &G_STRUCT_MEMBER( GObject *, object, argument_class->offset ) ); -} - /* Free any args which are holding resources. */ static void * @@ -548,9 +535,12 @@ vips_object_arg_close( GObject *argument, VipsObject *object = argument_instance->object; GParamSpec *pspec = ((VipsArgument *) argument_instance)->pspec; - /* Argument had reffed us ... now it's being closed, so we unref. + /* Argument had reffed us ... now it's being closed, so we NULL out + * the pointer to unref. */ - vips_object_clear_object( object, pspec ); + g_object_set( object, + g_param_spec_get_name( pspec ), NULL, + NULL ); } /* Set a member to an object. Handle the ref counts and signal @@ -576,7 +566,7 @@ vips__object_set_member( VipsObject *object, GParamSpec *pspec, if( *member ) { if( argument_class->flags & VIPS_ARGUMENT_INPUT ) { #ifdef DEBUG_REF - printf( "vips_object_set_object: vips object: " ); + printf( "vips_object_set_member: vips object: " ); vips_object_print_name( object ); printf( " refers to gobject %s (%p)\n", G_OBJECT_TYPE_NAME( *member ), *member ); @@ -590,7 +580,7 @@ vips__object_set_member( VipsObject *object, GParamSpec *pspec, } else if( argument_class->flags & VIPS_ARGUMENT_OUTPUT ) { #ifdef DEBUG_REF - printf( "vips_object_set_object: gobject %s (%p)\n", + printf( "vips_object_set_member: gobject %s (%p)\n", G_OBJECT_TYPE_NAME( *member ), *member ); printf( " refers to vips object: " ); vips_object_print_name( object ); @@ -610,22 +600,9 @@ vips__object_set_member( VipsObject *object, GParamSpec *pspec, } } -static void -vips_object_set_object( VipsObject *object, GParamSpec *pspec, - GObject *argument ) -{ - VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object ); - VipsArgumentClass *argument_class = (VipsArgumentClass *) - vips__argument_table_lookup( class->argument_table, pspec ); - GObject **member = &G_STRUCT_MEMBER( GObject *, object, - argument_class->offset ); - - vips__object_set_member( object, pspec, member, argument ); -} - /* Is a value NULL? We allow multiple sets of NULL so props can be cleared. */ -static gboolean +gboolean vips_pspec_value_is_null( GParamSpec *pspec, const GValue *value ) { if( G_IS_PARAM_SPEC_STRING( pspec ) && @@ -712,7 +689,10 @@ vips_object_set_property( GObject *gobject, VIPS_SETSTR( *member, g_value_get_string( value ) ); } else if( G_IS_PARAM_SPEC_OBJECT( pspec ) ) { - vips_object_set_object( object, pspec, + GObject **member = &G_STRUCT_MEMBER( GObject *, object, + argument_class->offset ); + + vips__object_set_member( object, pspec, member, g_value_get_object( value ) ); } else if( G_IS_PARAM_SPEC_INT( pspec ) ) { @@ -1690,20 +1670,14 @@ vips_type_find( const char *basename, const char *nickname ) return( G_OBJECT_CLASS_TYPE( class ) ); } +/* The vips_object_local() macros uses this as its callback. + */ void vips_object_local_cb( VipsObject *vobject, GObject *gobject ) { g_object_unref( gobject ); } -int -vips_object_unref( VipsObject *obj ) -{ - g_object_unref( obj ); - - return( 0 ); -} - static void * vips_object_print_all_cb( VipsObject *object, int *n ) { diff --git a/libvips/iofuncs/operation.c b/libvips/iofuncs/operation.c index 2744dd6f..c228f012 100644 --- a/libvips/iofuncs/operation.c +++ b/libvips/iofuncs/operation.c @@ -28,8 +28,8 @@ */ /* - */ #define VIPS_DEBUG + */ #ifdef HAVE_CONFIG_H #include @@ -55,6 +55,22 @@ G_DEFINE_ABSTRACT_TYPE( VipsOperation, vips_operation, VIPS_TYPE_OBJECT ); +static void +vips_operation_finalize( GObject *gobject ) +{ + VIPS_DEBUG_MSG( "vips_operation_finalize: %p\n", gobject ); + + G_OBJECT_CLASS( vips_operation_parent_class )->finalize( gobject ); +} + +static void +vips_operation_dispose( GObject *gobject ) +{ + VIPS_DEBUG_MSG( "vips_operation_dispose: %p\n", gobject ); + + G_OBJECT_CLASS( vips_operation_parent_class )->dispose( gobject ); +} + /* What to show about the argument. */ typedef struct { @@ -176,8 +192,12 @@ vips_operation_build( VipsObject *object ) static void vips_operation_class_init( VipsOperationClass *class ) { + GObjectClass *gobject_class = G_OBJECT_CLASS( class ); VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS( class ); + gobject_class->finalize = vips_operation_finalize; + gobject_class->dispose = vips_operation_dispose; + vobject_class->nickname = "operation"; vobject_class->description = _( "VIPS operations" ); vobject_class->print = vips_operation_print; @@ -201,6 +221,8 @@ vips_operation_new( const char *name ) return( NULL ); operation = VIPS_OPERATION( g_object_new( type, NULL ) ); + VIPS_DEBUG_MSG( "vips_operation_new: %s (%p)\n", name, operation ); + return( operation ); } diff --git a/tools/vips.c b/tools/vips.c index eded6949..643dcf8e 100644 --- a/tools/vips.c +++ b/tools/vips.c @@ -1113,9 +1113,11 @@ main( int argc, char **argv ) printf( "%s", _( "possible actions:\n" ) ); for( i = 0; i < VIPS_NUMBER( actions ); i++ ) printf( "%10s - %s\n", - actions[i].name, actions[i].description ); + actions[i].name, _( actions[i].description ) ); + printf( "%10s - %s\n", + "", _( "execute named vips operation" ) ); - error_exit( "unknown action \"%s\"", action ); + error_exit( _( "unknown action \"%s\"" ), action ); } if( !handled ) {