From 035d9239c1606a92f3f7d9e82fdcbcc71cdf4f61 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 19 Aug 2008 14:06:09 +0000 Subject: [PATCH] stuff --- TODO | 8 ++- include/vips/type.h | 60 ++++++++-------- libsrc/iofuncs/type.c | 157 ++++++++++++++++++++++++++---------------- 3 files changed, 135 insertions(+), 90 deletions(-) diff --git a/TODO b/TODO index 2049445f..c18742e9 100644 --- a/TODO +++ b/TODO @@ -4,10 +4,16 @@ have a field in im_type_t for typeof or somesuch? - need im_object_t + need im_object_t ... im_thing_t? should size be called sizeof + when we compare two types, we need to consider the typeof pointer too ... + array is not the same as array + + I guess we can have array>?:wq + + - needs docs in vips manual for format stuff I guess - operations and jesper's types should all use the new register/unregister diff --git a/include/vips/type.h b/include/vips/type.h index 895ea70f..8b2f47d1 100644 --- a/include/vips/type.h +++ b/include/vips/type.h @@ -37,7 +37,7 @@ extern "C" { /* Type names. Old code might use "doublevec" etc. from before we had the * "array" type. */ -#define IM_TYPE_NAME_DOUBLE "double" /* im_object is ptr to double */ +#define IM_TYPE_NAME_DOUBLE "double" /* im_value_t is ptr to double */ #define IM_TYPE_NAME_INT "integer" /* 32-bit integer */ #define IM_TYPE_NAME_COMPLEX "complex" /* Pair of doubles */ #define IM_TYPE_NAME_STRING "string" /* Zero-terminated char array */ @@ -48,38 +48,39 @@ extern "C" { #define IM_TYPE_NAME_GVALUE "gvalue" /* GValue wrapper */ #define IM_TYPE_NAME_ARRAY "array" /* Array of other values of some type */ -/* The arg to the init function is a pointer to the object. +/* Pass (array of pointers to im_value_t) to operations as the argument list. + * Cast to the appropriate type for this argument, eg. (int *) or (IMAGE *). */ -typedef void (*im_type_init_fn)( im_object *obj ); -typedef void (*im_type_free_fn)( im_object obj ); +typedef void im_value_t; + +/* The arg to the init function is a pointer to the value, since we can have + * nothing allocated for eg. an IMAGE*. + */ +typedef struct im__type_t im_type_t; +typedef gboolean (*im_value_init_fn)( im_value_t **value, im_type_t *type ); +typedef void (*im_value_free_fn)( im_value_t *value, im_type_t *type ); /* A VIPS type. */ -typedef struct im__type_t { +struct im__type_t { const char *name; /* Name of type, eg. "double" */ - size_t size; /* sizeof( im_object repres. ) */ - im_type_init_fn init; /* Init memory */ - im_type_free_fn free; /* Destroy object */ -} im_type_t; + im_type_t *type_param; /* What this is an array of */ + size_t size; /* sizeof( im_value_t ) repres. ) */ + im_value_init_fn init; /* Init memory */ + im_value_free_fn free; /* Destroy value */ +}; -/* A 'subclass' of im_type_t for array objects, eg. array-of-double. - */ -typedef struct im__type_array_t { - im_type_t parent; /* "array" */ - im_type_t *type; /* What this is an array of */ -} im_type_array_t; - -/* Various im_object values. +/* Various im_value_t values. */ typedef struct { char *name; /* Command-line name in */ void *mask; /* Mask --- DOUBLE or INT */ -} im_object_mask_t; +} im_value_mask_t; typedef struct { int n; /* Array length */ - im_object *array; /* Array */ -} im_object_array_t; + im_value_t **array; /* Array */ +} im_value_array_t; /* An argument to a VIPS operation. */ @@ -102,7 +103,7 @@ typedef enum { /* Type of a VIPS dispatch funtion. */ -typedef int (*im_operation_dispatch_fn)( im_object *argv ); +typedef int (*im_operation_dispatch_fn)( im_value_t **argv ); /* A VIPS operation. */ @@ -117,15 +118,11 @@ typedef struct im__operation_t { /* Register/iterate over types. */ -im_type_t *im_type_register( const char *name, size_t size, - im_type_init_fn init, im_type_free_fn free ); +im_type_t *im_type_register( const char *name, + im_type_t *type_param, size_t size, + im_value_init_fn init, im_value_free_fn free ); void *im_type_map( VSListMap2Fn fn, void *a, void *b ); -im_type_t *im_type_lookup( const char *name ); - -/* Create arguments. - */ -im_argument_t *im_argument_new( const char *name, - im_type_t *type, gboolean input ); +im_type_t *im_type_lookup( const char *name, im_type_t *type_param ); /* Register/iterate/lookup operations. */ @@ -134,6 +131,11 @@ im_operation_t *im_operation_register( const char *name, const char *desc, void *im_operation_map( VSListMap2Fn fn, void *a, void *b ); im_operation_t *im_operation_lookup( const char *name ); +/* Create arguments. + */ +im_argument_t *im_argument_new( const char *name, + im_type_t *type, gboolean input ); + #ifdef __cplusplus } #endif /*__cplusplus*/ diff --git a/libsrc/iofuncs/type.c b/libsrc/iofuncs/type.c index 9b168a80..aa7f4d81 100644 --- a/libsrc/iofuncs/type.c +++ b/libsrc/iofuncs/type.c @@ -41,17 +41,32 @@ #include #endif /*WITH_DMALLOC*/ -/* Keep types in a GHashTable, indexed by name. +/* Keep types in a GHashTable, indexed by name + type_param. */ static GHashTable *im_type_table = NULL; +static unsigned int +im_type_hash( im_type_t *type ) +{ + return( g_str_hash( type->name ) | + GPOINTER_TO_UINT( type->type_param ) ); +} + +static gboolean +im_type_equal( im_type_t *type1, im_type_t *type2 ) +{ + return( type1->type_param == type2->type_param && + g_str_equal( type1->name, type2->name ) ); +} + im_type_t * -im_type_register( const char *name, size_t size, - im_type_init_fn init, im_type_free_fn free ) +im_type_register( const char *name, + im_type_t *type_param, size_t size, + im_value_init_fn init, im_value_free_fn free ) { im_type_t *type; - if( im_type_lookup( name ) ) { + if( im_type_lookup( name, type_param ) ) { im_error( "im_type_register", _( "type name already registered" ) ); return( NULL ); @@ -59,15 +74,17 @@ im_type_register( const char *name, size_t size, if( !(type = IM_NEW( NULL, im_type_t )) ) return( NULL ); - type->name = name; + type->type_param = type_param; type->size = size; type->init = init; type->free = free; if( !im_type_table ) - im_type_table = g_hash_table_new( g_str_hash, g_str_equal ); - g_hash_table_insert( im_type_table, (char *) name, type ); + im_type_table = g_hash_table_new( + (GHashFunc) im_type_hash, + (GEqualFunc) im_type_equal ); + g_hash_table_insert( im_type_table, type, type ); return( type ); } @@ -102,80 +119,100 @@ im_type_map( VSListMap2Fn fn, void *a, void *b ) } im_type_t * -im_type_lookup( const char *name ) +im_type_lookup( const char *name, im_type_t *type_param ) { - return( (im_type_t *) g_hash_table_lookup( im_type_table, name ) ); + im_type_t type; + + type.name = name; + type.type_param = type_param; + + return( (im_type_t *) g_hash_table_lookup( im_type_table, &type ) ); +} + +/* Allocate an im_value_t. + */ +static im_value_t * +im_value_new( im_value_t **value, im_type_t *type ) +{ + if( type->size ) { + if( !(*value = im_malloc( NULL, type->size )) ) + return( NULL ); + memset( *value, 0, type->size ); + } + else + *value = NULL; + + if( type->init ) + if( type->init( value, type ) ); + + return( *value ); +} + +/* Free an im_value_t. + */ +static void +im_value_free( im_value_t **value, im_type_t *type ) +{ + if( type->free && *value ) + type->free( *value, type ); + if( type->size ) + IM_FREE( *value ); } /* Free a mask object. */ static void -im_object_imask_free( im_object_mask_t *mask ) +im_value_imask_free( im_value_mask_t *value, im_type_t *type ) { - IM_FREE( mask->name ); - IM_FREEF( im_free_imask, mask->mask ); + IM_FREE( value->name ); + IM_FREEF( im_free_imask, value->mask ); } static void -im_object_dmask_free( im_object_mask_t *mask ) +im_value_dmask_free( im_value_mask_t *value, im_type_t *type ) { - IM_FREE( mask->name ); - IM_FREEF( im_free_dmask, mask->mask ); + IM_FREE( value->name ); + IM_FREEF( im_free_dmask, value->mask ); } static void -gvalue_free( im_object obj ) +im_value_gvalue_free( GValue *value, im_type_t *type ) { - GValue *value = obj; - g_value_unset( value ); } +static void +im_value_array_free( im_value_array_t *value, im_type_t *type ) +{ + int i; + + for( i = 0; i < value->n; i++ ) + im_value_free( value->array[i], type->type_param ); +} + /* Register the base VIPS types. */ void im__type_init( void ) { - im_type_register( IM_TYPE_NAME_DOUBLE, - sizeof( double ), NULL, NULL ); - im_type_register( IM_TYPE_NAME_INT, - sizeof( int ), NULL, NULL ); - im_type_register( IM_TYPE_NAME_COMPLEX, - 2 * sizeof( double ), NULL, NULL ); - im_type_register( IM_TYPE_NAME_STRING, - 0, NULL, (im_type_free_fn) im_free ); - im_type_register( IM_TYPE_NAME_IMASK, - sizeof( im_object_mask_t ), - NULL, (im_type_free_fn) im_object_imask_free ); - im_type_register( IM_TYPE_NAME_DMASK, - sizeof( im_object_mask_t ), - NULL, (im_type_free_fn) im_object_dmask_free ); - im_type_register( IM_TYPE_NAME_IMAGE, - 0, NULL, NULL ); - im_type_register( IM_TYPE_NAME_DISPLAY, - 0, NULL, NULL ); - im_type_register( IM_TYPE_NAME_GVALUE, - 0, NULL, gvalue_free ); - im_type_register( IM_TYPE_NAME_ARRAY, - 0, NULL, NULL ); + im_type_register( IM_TYPE_NAME_DOUBLE, NULL, sizeof( double ), + NULL, NULL ); + im_type_register( IM_TYPE_NAME_INT, NULL, sizeof( int ), + NULL, NULL ); + im_type_register( IM_TYPE_NAME_COMPLEX, NULL, 2 * sizeof( double ), + NULL, NULL ); + im_type_register( IM_TYPE_NAME_STRING, NULL, 0, + NULL, (im_value_free_fn) im_free ); + im_type_register( IM_TYPE_NAME_IMASK, NULL, sizeof( im_value_mask_t ), + NULL, (im_value_free_fn) im_value_imask_free ); + im_type_register( IM_TYPE_NAME_DMASK, NULL, sizeof( im_value_mask_t ), + NULL, (im_value_free_fn) im_value_dmask_free ); + im_type_register( IM_TYPE_NAME_IMAGE, NULL, 0, + NULL, NULL ); + im_type_register( IM_TYPE_NAME_DISPLAY, NULL, 0, + NULL, NULL ); + im_type_register( IM_TYPE_NAME_GVALUE, NULL, sizeof( GValue ), + NULL, (im_value_free_fn) im_value_gvalue_free ); + im_type_register( IM_TYPE_NAME_ARRAY, NULL, sizeof( im_value_array_t ), + NULL, (im_value_free_fn) im_value_array_free ); } - -/* Allocate an im_object. - */ -static im_object_t * -im_object_new( im_type_t *type, im_object_t **object ) -{ - im_object_t *object; - - if( type->size ) { - if( !(*object = im_malloc( NULL, type->size )) ) - return( NULL ); - memset( *object, 0,, type->size ); - } - else - *object = NULL; - - if( type->init ) - type->init( object ); -} -