From a17ef9b7c898af4ed8826b0955644704e79cea07 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Wed, 9 Apr 2014 11:42:03 +0100 Subject: [PATCH] vips_system() allows many input images you can change the image argument order too, with %Ns added postbuild signal --- ChangeLog | 3 + TODO | 18 +++++ libvips/conversion/bandjoin.c | 2 +- libvips/deprecated/vips7compat.c | 28 ++++++-- libvips/include/vips/internal.h | 1 + libvips/include/vips/object.h | 4 ++ libvips/include/vips/type.h | 1 + libvips/iofuncs/Makefile.am | 14 +++- libvips/iofuncs/object.c | 48 +++++++++++++ libvips/iofuncs/operation.c | 25 ++++--- libvips/iofuncs/system.c | 119 +++++++++++++++++-------------- libvips/iofuncs/util.c | 73 +++++++++++++++++++ libvips/iofuncs/vipsmarshal.c | 89 +++++++++++++++++++++++ libvips/iofuncs/vipsmarshal.h | 20 ++++++ libvips/iofuncs/vipsmarshal.list | 27 +++++++ 15 files changed, 401 insertions(+), 71 deletions(-) create mode 100644 libvips/iofuncs/vipsmarshal.c create mode 100644 libvips/iofuncs/vipsmarshal.h create mode 100644 libvips/iofuncs/vipsmarshal.list diff --git a/ChangeLog b/ChangeLog index 9e61a2ed..6775368f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -17,6 +17,9 @@ - add "mode" param to vips_draw_image() - add vips_hough_circle() - reduce default cache size to 1,000 operations +- added "postbuild" signal +- vips_system() now supports many input images and you can change image + argument order 6/3/14 started 7.38.6 - grey ramp minimum was wrong diff --git a/TODO b/TODO index 25e74a51..523113c2 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,25 @@ +- try: + + $ vips system "vips add %s %s %s" --in "k2.jpg k4.jpg" \ + --out-format "%s.tif" --out x.v --log + memory: high-water mark 9.37 MB + "" + memory: high-water mark 27.89 MB + $ + + but x.v does not appear + +- can we use postbuild elsewhere? look at use of "preclose" / "written", etc. + + + + - why is cache in nip2 so slow? its awful investigate again + is it using vips_sinkscreen()? should it use tilecache? + - test draw_mask on labq images diff --git a/libvips/conversion/bandjoin.c b/libvips/conversion/bandjoin.c index 42fe4cba..fb724711 100644 --- a/libvips/conversion/bandjoin.c +++ b/libvips/conversion/bandjoin.c @@ -78,7 +78,7 @@ typedef struct _VipsBandjoin { /* The input images. */ - VipsArea *in; + VipsArrayImage *in; } VipsBandjoin; typedef VipsBandaryClass VipsBandjoinClass; diff --git a/libvips/deprecated/vips7compat.c b/libvips/deprecated/vips7compat.c index be351172..79be5833 100644 --- a/libvips/deprecated/vips7compat.c +++ b/libvips/deprecated/vips7compat.c @@ -1754,14 +1754,24 @@ im_text( IMAGE *out, const char *text, const char *font, int im_system( VipsImage *im, const char *cmd, char **out ) { + VipsArea *area; + VipsImage **array; char *str; + area = vips_area_new_array_object( 1 ); + array = (VipsImage **) area->data; + array[0] = im; + if( vips_system( cmd, - "in", im, + "in", area, "in_format", "%s.v", "log", &str, - NULL ) ) + NULL ) ) { + vips_area_unref( area ); return( -1 ); + } + + vips_area_unref( area ); if( out ) *out = str; @@ -1774,17 +1784,27 @@ im_system_image( VipsImage *im, const char *in_format, const char *out_format, const char *cmd_format, char **log ) { + VipsArea *area; + VipsImage **array; char *str; VipsImage *out; + area = vips_area_new_array_object( 1 ); + array = (VipsImage **) area->data; + array[0] = im; + if( vips_system( cmd_format, - "in", im, + "in", area, "out", &out, "in_format", in_format, "out_format", out_format, "log", &str, - NULL ) ) + NULL ) ) { + vips_area_unref( area ); return( NULL ); + } + + vips_area_unref( area ); if( log ) *log = str; diff --git a/libvips/include/vips/internal.h b/libvips/include/vips/internal.h index acf80275..6baae9ce 100644 --- a/libvips/include/vips/internal.h +++ b/libvips/include/vips/internal.h @@ -307,6 +307,7 @@ void vips_convolution_operation_init( void ); void vips_draw_operation_init( void ); guint64 vips__parse_size( const char *size_string ); +int vips__substitute( const char *domain, char *buf, size_t len, char *sub ); IMAGE *vips__deprecated_open_read( const char *filename, gboolean sequential ); IMAGE *vips__deprecated_open_write( const char *filename ); diff --git a/libvips/include/vips/object.h b/libvips/include/vips/object.h index 13274b57..a23af7ec 100644 --- a/libvips/include/vips/object.h +++ b/libvips/include/vips/object.h @@ -445,6 +445,10 @@ struct _VipsObjectClass { */ int (*build)( VipsObject *object ); + /* Just after build ... the object is fully ready for work. + */ + int (*postbuild)( VipsObject *object ); + /* Try to print something about the class, handy for help displays. * Keep to one line. */ diff --git a/libvips/include/vips/type.h b/libvips/include/vips/type.h index 1d6abb9b..77fefada 100644 --- a/libvips/include/vips/type.h +++ b/libvips/include/vips/type.h @@ -162,6 +162,7 @@ GType vips_array_int_get_type( void ); * The #GType for a #VipsArrayImage. */ #define VIPS_TYPE_ARRAY_IMAGE (vips_array_image_get_type()) +typedef VipsArea VipsArrayImage; GType vips_array_image_get_type( void ); void vips_value_set_area( GValue *value, VipsCallbackFn free_fn, void *data ); diff --git a/libvips/iofuncs/Makefile.am b/libvips/iofuncs/Makefile.am index af1af54b..e0869892 100644 --- a/libvips/iofuncs/Makefile.am +++ b/libvips/iofuncs/Makefile.am @@ -1,6 +1,8 @@ noinst_LTLIBRARIES = libiofuncs.la libiofuncs_la_SOURCES = \ + vipsmarshal.h \ + vipsmarshal.c \ type.c \ gate.c \ enumtypes.c \ @@ -33,7 +35,17 @@ libiofuncs_la_SOURCES = \ system.c \ buffer.c -EXTRA_DIST = enumtemplate +vipsmarshal.h: + glib-genmarshal --prefix=vips --header vipsmarshal.list > vipsmarshal.h +vipsmarshal.c: + echo "#include \"vipsmarshal.h\"" > vipsmarshal.c + glib-genmarshal --prefix=vips --body vipsmarshal.list >> vipsmarshal.c + +EXTRA_DIST = \ + enumtemplate \ + vipsmarshal.h \ + vipsmarshal.c \ + vipsmarshal.list AM_CPPFLAGS = -I${top_srcdir}/libvips/include @VIPS_CFLAGS@ @VIPS_INCLUDES@ diff --git a/libvips/iofuncs/object.c b/libvips/iofuncs/object.c index 62e7fb4c..dd07472c 100644 --- a/libvips/iofuncs/object.c +++ b/libvips/iofuncs/object.c @@ -52,6 +52,8 @@ #include +#include "vipsmarshal.h" + /** * SECTION: object * @short_description: the VIPS base object class @@ -111,6 +113,7 @@ /* Our signals. */ enum { + SIG_POSTBUILD, SIG_PRECLOSE, SIG_CLOSE, SIG_POSTCLOSE, @@ -132,6 +135,24 @@ static GHashTable *vips__object_nickname_table = NULL; G_DEFINE_ABSTRACT_TYPE( VipsObject, vips_object, G_TYPE_OBJECT ); +/* Don't call this directly, see vips_object_build(). + */ +static int +vips_object_postbuild( VipsObject *object ) +{ + int result; + +#ifdef DEBUG + printf( "vips_object_postbuild: " ); + vips_object_print_name( object ); + printf( "\n" ); +#endif /*DEBUG*/ + + g_signal_emit( object, vips_object_signals[SIG_POSTBUILD], 0, &result ); + + return( result ); +} + void vips_object_preclose( VipsObject *object ) { @@ -250,6 +271,11 @@ vips_object_build( VipsObject *object ) */ object->constructed = TRUE; + /* Only postbuild on success. + */ + if( !result ) + result = vips_object_postbuild( object ); + return( result ); } @@ -1285,6 +1311,20 @@ vips_object_real_build( VipsObject *object ) return( result ); } +static int +vips_object_real_postbuild( VipsObject *object ) +{ +#ifdef DEBUG + printf( "vips_object_real_postbuild: " ); + vips_object_print_name( object ); + printf( "\n" ); +#endif /*DEBUG*/ + + g_assert( object->constructed ); + + return( 0 ); +} + static void vips_object_real_summary_class( VipsObjectClass *class, VipsBuf *buf ) { @@ -1384,6 +1424,7 @@ vips_object_class_init( VipsObjectClass *class ) gobject_class->get_property = vips_object_get_property; class->build = vips_object_real_build; + class->postbuild = vips_object_real_postbuild; class->summary_class = vips_object_real_summary_class; class->summary = vips_object_real_summary; class->dump = vips_object_real_dump; @@ -1419,6 +1460,13 @@ vips_object_class_init( VipsObjectClass *class ) G_STRUCT_OFFSET( VipsObject, description ), "" ); + vips_object_signals[SIG_POSTBUILD] = g_signal_new( "postbuild", + G_TYPE_FROM_CLASS( class ), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET( VipsObjectClass, postbuild ), + NULL, NULL, + vips_INT__VOID, + G_TYPE_INT, 0 ); vips_object_signals[SIG_PRECLOSE] = g_signal_new( "preclose", G_TYPE_FROM_CLASS( class ), G_SIGNAL_RUN_LAST, diff --git a/libvips/iofuncs/operation.c b/libvips/iofuncs/operation.c index c75b812a..4f37ad2c 100644 --- a/libvips/iofuncs/operation.c +++ b/libvips/iofuncs/operation.c @@ -773,28 +773,30 @@ vips_call_find_pspec( VipsObject *object, */ typedef struct _VipsCallOptionOutput { VipsArgumentInstance *argument_instance; - const char *value; + char *value; } VipsCallOptionOutput; -static void +static int vips_call_option_output( VipsObject *object, VipsCallOptionOutput *output ) { VipsArgumentInstance *argument_instance = output->argument_instance; GParamSpec *pspec = ((VipsArgument *) argument_instance)->pspec; + int result; + /* Don't look at the output arg if _build() hasn't run sucessfully, it * probably won't have been set. */ + result = 0; if( object->constructed ) - if( vips_object_get_argument_to_string( object, - g_param_spec_get_name( pspec ), output->value ) ) { - /* FIXME .. Hmm what can we do here? If an arg is image - * output, for example, we will lose the error. - */ - } + result = vips_object_get_argument_to_string( object, + g_param_spec_get_name( pspec ), output->value ); + VIPS_FREE( output->value ); g_free( output ); + + return( result ); } static gboolean @@ -857,14 +859,11 @@ vips_call_options_set( const gchar *option_name, const gchar *value, /* We can't do output now, we have to attach a callback to do * the processing after the operation has run. - * - * FIXME ... something like posteval or postbuild might be - * better for this? */ output = g_new( VipsCallOptionOutput, 1 ); output->argument_instance = argument_instance; - output->value = value; - g_signal_connect( operation, "preclose", + output->value = g_strdup( value ); + g_signal_connect( operation, "postbuild", G_CALLBACK( vips_call_option_output ), output ); } diff --git a/libvips/iofuncs/system.c b/libvips/iofuncs/system.c index 908de337..1f5cc241 100644 --- a/libvips/iofuncs/system.c +++ b/libvips/iofuncs/system.c @@ -62,21 +62,21 @@ #include #include +#include typedef struct _VipsSystem { VipsOperation parent_instance; - VipsImage *in; + VipsArrayImage *in; VipsImage *out; char *cmd_format; char *in_format; char *out_format; char *log; - /* Set to delete in_name on close. + /* Array of names we wrote the input images to. */ - gboolean delete_on_close; - char *in_name; + char **in_name; char *out_name; @@ -91,11 +91,14 @@ vips_system_dispose( GObject *gobject ) { VipsSystem *system = (VipsSystem *) gobject; - if( system->delete_on_close && - system->in_name ) - g_unlink( system->in_name ); - VIPS_FREE( system->in_name ); - system->delete_on_close = FALSE; + if( system->in_name ) { + int i; + + for( i = 0; i < system->in->n; i++ ) { + g_unlink( system->in_name[i] ); + VIPS_FREE( system->in_name[i] ); + } + } VIPS_FREE( system->out_name ); @@ -108,6 +111,10 @@ vips_system_build( VipsObject *object ) VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object ); VipsSystem *system = (VipsSystem *) object; + int i; + + char cmd[VIPS_PATH_MAX]; + FILE *fp; char line[VIPS_PATH_MAX]; char txt[VIPS_PATH_MAX]; @@ -117,19 +124,27 @@ vips_system_build( VipsObject *object ) if( VIPS_OBJECT_CLASS( vips_system_parent_class )->build( object ) ) return( -1 ); - /* Write the input image to a file. We must always make a copy of the - * file, even if this is a disc file already, in case the command - * needs a different format. + /* Write the input images to files. We must always make copies of the + * files, even if this image is a disc file already, in case the + * command needs a different format. */ if( system->in ) { char *in_format = system->in_format ? system->in_format : "%s.tif"; + VipsImage **in = (VipsImage **) system->in->data; - if( !(system->in_name = vips__temp_name( in_format )) ) - return( -1 ); - if( vips_image_write_to_file( system->in, system->in_name ) ) - return( -1 ); - system->delete_on_close = TRUE; + if( !(system->in_name = VIPS_ARRAY( object, + system->in->n, char * )) ) + return( -1 ); + memset( system->in_name, 0, system->in->n * sizeof( char * ) ); + for( i = 0; i < system->in->n; i++ ) { + if( !(system->in_name[i] = + vips__temp_name( in_format )) ) + return( -1 ); + if( vips_image_write_to_file( in[i], + system->in_name[i] ) ) + return( -1 ); + } } /* Make the output filename. @@ -138,16 +153,19 @@ vips_system_build( VipsObject *object ) !(system->out_name = vips__temp_name( system->out_format )) ) return( -1 ); - if( system->in_name ) { - if( !(fp = vips_popenf( system->cmd_format, "r", - system->in_name, system->out_name )) ) - return( -1 ); - } - else { - if( !(fp = vips_popenf( system->cmd_format, "r", - system->out_name )) ) - return( -1 ); - } + vips_strncpy( cmd, system->cmd_format, VIPS_PATH_MAX ); + if( system->in ) + for( i = 0; i < system->in->n; i++ ) + if( vips__substitute( class->nickname, + cmd, VIPS_PATH_MAX, system->in_name[i] ) ) + return( -1 ); + if( system->out_name && + vips__substitute( class->nickname, + cmd, VIPS_PATH_MAX, system->out_name ) ) + return( -1 ); + + if( !(fp = vips_popenf( "%s", "r", cmd )) ) + return( -1 ); while( fgets( line, VIPS_PATH_MAX, fp ) ) if( !vips_buf_appends( &buf, line ) ) @@ -161,13 +179,12 @@ vips_system_build( VipsObject *object ) return( -1 ); } - if( system->out_format ) { + if( system->out_name ) { VipsImage *out; if( !(out = vips_image_new_from_file( system->out_name )) ) return( -1 ); vips_image_set_delete_on_close( out, TRUE ); - g_object_set( system, "out", out, NULL ); } @@ -188,11 +205,12 @@ vips_system_class_init( VipsSystemClass *class ) vobject_class->description = _( "run an external command" ); vobject_class->build = vips_system_build; - VIPS_ARG_IMAGE( class, "in", 0, + VIPS_ARG_BOXED( class, "in", 0, _( "Input" ), - _( "Input image" ), - VIPS_ARGUMENT_OPTIONAL_INPUT, - G_STRUCT_OFFSET( VipsSystem, in ) ); + _( "Array of input images" ), + VIPS_ARGUMENT_OPTIONAL_INPUT, + G_STRUCT_OFFSET( VipsSystem, in ), + VIPS_TYPE_ARRAY_IMAGE ); VIPS_ARG_IMAGE( class, "out", 1, _( "Output" ), @@ -242,21 +260,20 @@ vips_system_init( VipsSystem *system ) * * Optional arguments: * - * @in: input image + * @in: array of input images * @out: output image - * @in_format: write input file like this + * @in_format: write input files like this * @out_format: write output filename like this * @log: stdout of command is returned here * - * vips_system() runs a command, optionally passing an image in and - * optionally getting an image - * back. The command's stdout is returned in @log. + * vips_system() runs a command, optionally passing a set of images in and + * optionally getting an image back. The command's stdout is returned in @log. * - * First, if @in is set, it is written to a file. The filename is formed by - * substituting something like "vips-49857-1" for the first %%s in @in_format, - * then - * prepending "/tmp". If the environment variable TMPDIR is defined, it - * can be used to set a different temporary directory. + * First, if @in is set, the array of images are written to files. The + * filenames are formed by substituting something like "vips-49857-1" for + * the first %%s in @in_format, then prepending "/tmp". If the environment + * variable TMPDIR is defined, it can be used to set a different temporary + * directory. * * On Windows, if the environment variable TMPDIR is not defined, VIPS calls * GetTempPath() to get the user's preferred temporary area. If that fails, it @@ -268,16 +285,17 @@ vips_system_init( VipsSystem *system ) * * If @out_format is set, an output filename is formed in the same way. * - * The - * command string to run is made by substituting the first %%s in @cmd_format - * for the name of the input file, if @in is set, and the second %%s for the - * output filename, if set. + * The command string to run is made by substituting the first set of %%s + * in @cmd_format for the names of the input files, if @in is set, and then + * the next %%s for the output filename, if @out_format is set. + * You can put a number between the %% and the s to change the order in which + * the substitution occurs. * * The command is executed with popen() and the output captured in @log. * * After the command finishes, if @out_format is set, the output image is * opened and returned in @out. - * Closing the output image will automatically delete the output file. + * Closing @out image will automatically delete the output file. * * Finally the input images are deleted. * @@ -285,7 +303,7 @@ vips_system_init( VipsSystem *system ) * image, using JPEG files to pass images into and out of the convert command. * * |[ - * VipsImage *in; + * VipsArrayImage *in; * VipsImage *out; * char *log; * @@ -313,6 +331,3 @@ vips_system( const char *cmd_format, ... ) return( result ); } - - - diff --git a/libvips/iofuncs/util.c b/libvips/iofuncs/util.c index 2b608e54..2a816b90 100644 --- a/libvips/iofuncs/util.c +++ b/libvips/iofuncs/util.c @@ -1673,3 +1673,76 @@ vips_enum_from_nick( const char *domain, GType type, const char *nick ) return( -1 ); } + +#define BIGBUF (10000) + +/* Scan @buf for the first "%ns" (eg. "%12s") and substitute the + * lowest-numbered one for @sub. @buf is @len bytes + * in size. + * + * If there are no %ns, use the first %s. + */ +int +vips__substitute( const char *domain, char *buf, size_t len, char *sub ) +{ + size_t buflen = strlen( buf ); + size_t sublen = strlen( sub ); + + int lowest_n; + char *sub_start; + char *p; + char *sub_end; + size_t before_len, marker_len, after_len, final_len; + + g_assert( buflen < len ); + + lowest_n = -1; + sub_start = NULL; + for( p = buf; (p = strchr( p, '%' )); p++ ) + if( isdigit( p[1] ) ) { + char *q; + + for( q = p + 1; isdigit( *q ); q++ ) + ; + if( q[0] == 's' ) { + int n; + + n = atoi( p + 1 ); + if( lowest_n == -1 || + n < lowest_n ) { + sub_start = p; + sub_end = q + 1; + } + } + } + + if( !sub_start ) + for( p = buf; (p = strchr( p, '%' )); p++ ) + if( p[1] == 's' ) { + sub_start = p; + sub_end = p + 2; + break; + } + + if( !sub_start ) { + vips_error( domain, + "%s", _( "string contains no substitute marker" ) ); + return( -1 ); + } + + before_len = sub_start - buf; + marker_len = sub_end - sub_start; + after_len = buflen - (before_len + marker_len); + final_len = before_len + sublen + after_len + 1; + if( final_len > len ) { + vips_error( domain, + "%s", _( "not enough space to substitute" ) ); + return( -1 ); + } + + memmove( buf + before_len + sublen, buf + before_len + marker_len, + after_len + 1 ); + memmove( buf + before_len, sub, sublen ); + + return( 0 ); +} diff --git a/libvips/iofuncs/vipsmarshal.c b/libvips/iofuncs/vipsmarshal.c new file mode 100644 index 00000000..655ffb32 --- /dev/null +++ b/libvips/iofuncs/vipsmarshal.c @@ -0,0 +1,89 @@ +#include "vipsmarshal.h" + +#include + + +#ifdef G_ENABLE_DEBUG +#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v) +#define g_marshal_value_peek_char(v) g_value_get_schar (v) +#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v) +#define g_marshal_value_peek_int(v) g_value_get_int (v) +#define g_marshal_value_peek_uint(v) g_value_get_uint (v) +#define g_marshal_value_peek_long(v) g_value_get_long (v) +#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v) +#define g_marshal_value_peek_int64(v) g_value_get_int64 (v) +#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v) +#define g_marshal_value_peek_enum(v) g_value_get_enum (v) +#define g_marshal_value_peek_flags(v) g_value_get_flags (v) +#define g_marshal_value_peek_float(v) g_value_get_float (v) +#define g_marshal_value_peek_double(v) g_value_get_double (v) +#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v) +#define g_marshal_value_peek_param(v) g_value_get_param (v) +#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v) +#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v) +#define g_marshal_value_peek_object(v) g_value_get_object (v) +#define g_marshal_value_peek_variant(v) g_value_get_variant (v) +#else /* !G_ENABLE_DEBUG */ +/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API. + * Do not access GValues directly in your code. Instead, use the + * g_value_get_*() functions + */ +#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int +#define g_marshal_value_peek_char(v) (v)->data[0].v_int +#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint +#define g_marshal_value_peek_int(v) (v)->data[0].v_int +#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint +#define g_marshal_value_peek_long(v) (v)->data[0].v_long +#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong +#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64 +#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64 +#define g_marshal_value_peek_enum(v) (v)->data[0].v_long +#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong +#define g_marshal_value_peek_float(v) (v)->data[0].v_float +#define g_marshal_value_peek_double(v) (v)->data[0].v_double +#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_variant(v) (v)->data[0].v_pointer +#endif /* !G_ENABLE_DEBUG */ + + +/* INT:VOID (vipsmarshal.list:25) */ +void +vips_INT__VOID (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef gint (*GMarshalFunc_INT__VOID) (gpointer data1, + gpointer data2); + register GMarshalFunc_INT__VOID callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + gint v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 1); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_INT__VOID) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + data2); + + g_value_set_int (return_value, v_return); +} + diff --git a/libvips/iofuncs/vipsmarshal.h b/libvips/iofuncs/vipsmarshal.h new file mode 100644 index 00000000..2f3e711f --- /dev/null +++ b/libvips/iofuncs/vipsmarshal.h @@ -0,0 +1,20 @@ + +#ifndef __vips_MARSHAL_H__ +#define __vips_MARSHAL_H__ + +#include + +G_BEGIN_DECLS + +/* INT:VOID (vipsmarshal.list:25) */ +extern void vips_INT__VOID (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + +G_END_DECLS + +#endif /* __vips_MARSHAL_H__ */ + diff --git a/libvips/iofuncs/vipsmarshal.list b/libvips/iofuncs/vipsmarshal.list new file mode 100644 index 00000000..0ce2c772 --- /dev/null +++ b/libvips/iofuncs/vipsmarshal.list @@ -0,0 +1,27 @@ +# see glib-genmarshal(1) for a detailed description of the file format, +# possible parameter types are: +# VOID indicates no return type, or no extra +# parameters. if VOID is used as the parameter +# list, no additional parameters may be present. +# BOOLEAN for boolean types (gboolean) +# CHAR for signed char types (gchar) +# UCHAR for unsigned char types (guchar) +# INT for signed integer types (gint) +# UINT for unsigned integer types (guint) +# LONG for signed long integer types (glong) +# ULONG for unsigned long integer types (gulong) +# ENUM for enumeration types (gint) +# FLAGS for flag enumeration types (guint) +# FLOAT for single-precision float types (gfloat) +# DOUBLE for double-precision float types (gdouble) +# STRING for string types (gchar*) +# BOXED for boxed (anonymous but reference counted) types (GBoxed*) +# POINTER for anonymous pointer types (gpointer) +# PARAM for GParamSpec or derived types (GParamSpec*) +# OBJECT for GObject or derived types (GObject*) +# NONE deprecated alias for VOID +# BOOL deprecated alias for BOOLEAN + +INT: VOID + +