From a09929ef947db39a993626bdbf467c2eb223d560 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Thu, 27 Oct 2011 15:27:03 +0100 Subject: [PATCH] added image array args --- TODO | 25 +++++++ libvips/include/vips/header.h | 21 ++++-- libvips/iofuncs/header.c | 119 ++++++++++++++++++++++++++++++++++ 3 files changed, 160 insertions(+), 5 deletions(-) diff --git a/TODO b/TODO index c1714645..ad617579 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,30 @@ +- im_gbandjoin() needed by binary + + + +- does transform_array_g_string() work? it seems to use + g_value_set_instance() incorrectly + + try printing an array of double + + + + - lintra_vec next + get rid of binary.c, instead have a general 'pointwise' class which takes + any number of input images and runs a buffer-processing function over them + + fold binary.c into arithmetic.c + + VipsArithmetic has a "number of input images" thing set by subclasses, cf. + format_table + + proper likes "left" and "right" created by subclasses + + + + diff --git a/libvips/include/vips/header.h b/libvips/include/vips/header.h index 3deef401..8781c4e8 100644 --- a/libvips/include/vips/header.h +++ b/libvips/include/vips/header.h @@ -151,7 +151,7 @@ void *vips_image_map( VipsImage *im, VipsImageMapFn fn, void *a ); /** * VIPS_TYPE_SAVE_STRING: * - * The #GType for an "vips_save_string". + * The #GType for a "vips_save_string". */ #define VIPS_TYPE_SAVE_STRING (vips_save_string_get_type()) GType vips_save_string_get_type( void ); @@ -163,7 +163,7 @@ void vips_save_string_setf( GValue *value, const char *fmt, ... ) /** * VIPS_TYPE_AREA: * - * The #GType for an #vips_area. + * The #GType for a #vips_area. */ #define VIPS_TYPE_AREA (vips_area_get_type()) GType vips_area_get_type( void ); @@ -174,7 +174,7 @@ VipsArea *vips_area_copy( VipsArea *area ); /** * VIPS_TYPE_REF_STRING: * - * The #GType for an #vips_refstring. + * The #GType for a #vips_refstring. */ #define VIPS_TYPE_REF_STRING (vips_ref_string_get_type()) GType vips_ref_string_get_type( void ); @@ -185,7 +185,7 @@ size_t vips_ref_string_get_length( const GValue *value ); /** * VIPS_TYPE_BLOB: * - * The #GType for an #vips_blob. + * The #GType for a #vips_blob. */ #define VIPS_TYPE_BLOB (vips_blob_get_type()) @@ -197,7 +197,7 @@ int vips_blob_set( GValue *value, VipsCallbackFn free_fn, /** * VIPS_TYPE_ARRAY_DOUBLE: * - * The #GType for an #vips_array_double. + * The #GType for a #vips_array_double. */ #define VIPS_TYPE_ARRAY_DOUBLE (vips_array_double_get_type()) @@ -205,6 +205,17 @@ GType vips_array_double_get_type( void ); double *vips_array_double_get( const GValue *value, int *n ); int vips_array_double_set( GValue *value, const double *array, int n ); +/** + * VIPS_TYPE_ARRAY_IMAGE: + * + * The #GType for a #vips_array_image. + */ + +#define VIPS_TYPE_ARRAY_IMAGE (vips_array_image_get_type()) +GType vips_array_image_get_type( void ); +GObject **vips_array_object_get( const GValue *value, int *n ); +int vips_array_object_set( GValue *value, int n ); + void vips_image_set_area( VipsImage *image, const char *field, VipsCallbackFn free_fn, void *data ); int vips_image_get_area( VipsImage *image, const char *field, void **data ); diff --git a/libvips/iofuncs/header.c b/libvips/iofuncs/header.c index f2a7dbd0..292d042a 100644 --- a/libvips/iofuncs/header.c +++ b/libvips/iofuncs/header.c @@ -1670,6 +1670,125 @@ vips_array_double_set( GValue *value, const double *array, int n ) return( 0 ); } +static void +vips_array_object_free( VipsArea *area ) +{ + GObject **array = (GObject **) area->data; + + int i; + + for( i = 0; i < area->n; i++ ) + VIPS_FREEF( g_object_unref, array[i] ); + + g_free( area ); +} + +/* An area which holds an array of GObjects. + */ +VipsArea * +vips_array_object_new( int n ) +{ + GObject **array; + VipsArea *area; + + array = g_new0( GObject *, n ); + if( !(area = area_new( + (VipsCallbackFn) vips_array_object_free, array )) ) + return( NULL ); + area->n = n; + area->length = n * sizeof( GObject * ); + area->type = G_TYPE_OBJECT; + area->sizeof_type = sizeof( GObject * ); + + return( area ); +} + +/** + * vips_array_object_get: + * @value: #GValue to get from + * @n: return the number of elements here, optionally + * + * Return the start of the array of #GObject held by @value. + * optionally return the number of elements in @n. + * + * See also: vips_array_object_set(). + * + * Returns: The array address. + */ +GObject ** +vips_array_object_get( const GValue *value, int *n ) +{ + return( vips_array_get( value, n, NULL, NULL ) ); +} + +/** + * vips_array_object_set: + * @value: #GValue to set + * @n: the number of elements + * + * Set @value to hold an array of GObject. Pass in the array length in @n. + * + * See also: vips_array_object_get(). + * + * Returns: 0 on success, -1 otherwise. + */ +int +vips_array_object_set( GValue *value, int n ) +{ + VipsArea *area; + + if( !(area = vips_array_object_new( n )) ) + return( -1 ); + g_value_set_boxed( value, area ); + vips_area_unref( area ); + + return( 0 ); +} + +static void +transform_g_string_array_image( const GValue *src_value, GValue *dest_value ) +{ + char *str; + int n; + char *p, *q; + int i; + GObject **array; + + /* We need a copy of the string, since we insert \0 during + * scan. + */ + str = g_strdup_value_contents( src_value ); + for( n = 0; (q = vips_break_token( p, " " )); n++, p = q ) + ; + g_free( str ); + + vips_array_object_set( dest_value, n ); + array = vips_array_object_get( dest_value, NULL ); + + str = g_strdup_value_contents( src_value ); + for( i = 0; (q = vips_break_token( p, " " )); i++, p = q ) + /* Sadly there's no error return possible here. + */ + array[i] = G_OBJECT( vips_image_new_from_file( p ) ); + g_free( str ); +} + +GType +vips_array_image( void ) +{ + static GType type = 0; + + if( !type ) { + type = g_boxed_type_register_static( "vips_array_image", + (GBoxedCopyFunc) vips_area_copy, + (GBoxedFreeFunc) vips_area_unref ); + g_value_register_transform_func( G_TYPE_STRING, type, + transform_g_string_array_image ); + } + + return( type ); +} + /** * vips_image_set_blob: * @image: image to attach the metadata to