This commit is contained in:
John Cupitt 2008-08-21 08:32:24 +00:00
parent b1395e18b9
commit ae5e658f1c
5 changed files with 110 additions and 46 deletions

10
TODO
View File

@ -1,7 +1,17 @@
- have vips -> gvalue and gvalue -> vips methods in type struct
converters need arg flags too, so they know whether it's read or write
is this enough? maybe
- do we need init functions? maybe for arrays I guess
should gvalues be inited to a specific type?
- we need init functions which are parameterizied for the specific value
im_value_double_init( value, 12.3 )

View File

@ -48,6 +48,11 @@ extern "C" {
#define IM_TYPE_NAME_GVALUE "gvalue" /* GValue wrapper */
#define IM_TYPE_NAME_ARRAY "array" /* Array of other values of some type */
/* Handy type lookups.
*/
#define IM_TYPE_IM (im_type_lookup( IM_TYPE_NAME_IMAGE, NULL ))
#define IM_TYPE_AR( OF ) (im_type_lookup( IM_TYPE_NAME_ARRAY, OF ))
/* A VIPS type.
*/
typedef struct im__type_t {
@ -73,12 +78,20 @@ typedef struct {
im_value_t **array; /* Array */
} im_value_array_t;
/* Flags for arguments.
* operation,
*/
typedef enum {
IM_ARGUMENT_NONE = 0, /* No flags set */
IM_ARGUMENT_OUTPUT = 0x1 /* Is an output arg */
} im_argument_flags;
/* An argument to a VIPS operation.
*/
typedef struct im__argument_t {
const char *name; /* Eg. "in2" */
im_type_t *type; /* Argument type */
gboolean input; /* TRUE means arg to operation */
im_argument_flags flags; /* Output/input etc. */
} im_argument_t;
/* Flags for operations. Various hints for UIs about the behaviour of the
@ -118,13 +131,15 @@ im_type_t *im_type_lookup( const char *name, im_type_t *type_param );
*/
im_operation_t *im_operation_register( const char *name, const char *desc,
im_operation_flags flags, im_operation_dispatch_fn disp, int argc );
im_operation_t *im_operation_registerv( const char *name, const char *desc,
im_operation_flags flags, im_operation_dispatch_fn disp, ... );
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 );
im_type_t *type, im_argument_flags flags );
#ifdef __cplusplus
}

View File

@ -291,6 +291,8 @@ void im_slist_free_all( GSList *list );
void *im_map_equal( void *a, void *b );
void *im_hash_table_map( GHashTable *hash, VSListMap2Fn fn, void *a, void *b );
char *im_strncpy( char *dest, const char *src, int n );
char *im_strrstr( const char *haystack, const char *needle );
char *im_strdup( IMAGE *im, const char *str );

View File

@ -34,6 +34,7 @@
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <vips/vips.h>
@ -90,34 +91,6 @@ im_type_register( const char *name,
return( type );
}
typedef struct {
void *a;
void *b;
VSListMap2Fn fn;
void *result;
} Pair;
static gboolean
im_hash_table_predicate( const char *key, im_type_t *type, Pair *pair )
{
return( (pair->result == pair->fn( type, pair->a, pair->b )) );
}
void *
im_hash_table_map( GHashTable *hash, VSListMap2Fn fn, void *a, void *b )
{
Pair pair;
pair.a = a;
pair.b = b;
pair.fn = fn;
pair.result = NULL;
g_hash_table_find( hash, (GHRFunc) im_hash_table_predicate, &pair );
return( pair.result );
}
void *
im_type_map( VSListMap2Fn fn, void *a, void *b )
{
@ -127,12 +100,27 @@ im_type_map( VSListMap2Fn fn, void *a, void *b )
im_type_t *
im_type_lookup( const char *name, im_type_t *type_param )
{
im_type_t type;
im_type_t tmp;
im_type_t *type;
type.name = name;
type.type_param = type_param;
/* Look for this exact type.
*/
tmp.name = name;
tmp.type_param = type_param;
if( !(type = (im_type_t *)
g_hash_table_lookup( im_type_table, &tmp )) ) {
/* Not found. Look for just the name type, eg. "array".
*/
tmp.type_param = NULL;
if( (type = (im_type_t *)
g_hash_table_lookup( im_type_table, &tmp )) )
/* Found it. Register a new compound type with this
* param.
*/
type = im_type_register( name, type_param, type->size );
}
return( (im_type_t *) g_hash_table_lookup( im_type_table, &type ) );
return( type );
}
/* Register the base VIPS types.
@ -239,7 +227,7 @@ im_value_imask_input_init( im_value_mask_t *value, const char *name )
/* Create arguments.
*/
im_argument_t *
im_argument_new( const char *name, im_type_t *type, gboolean input )
im_argument_new( const char *name, im_type_t *type, im_argument_flags flags )
{
im_argument_t *argument;
@ -247,7 +235,7 @@ im_argument_new( const char *name, im_type_t *type, gboolean input )
return( NULL );
argument->name = name;
argument->type = type;
argument->input = input;
argument->flags = flags;
return( argument );
}
@ -306,6 +294,30 @@ im_operation_register( const char *name, const char *desc,
return( operation );
}
im_operation_t *
im_operation_registerv( const char *name, const char *desc,
im_operation_flags flags, im_operation_dispatch_fn disp, ... )
{
im_operation_t *operation;
im_argument_t *argument;
va_list ap;
int argc;
int i;
va_start( ap, disp );
for( argc = 0; va_arg( ap, im_argument_t * ); argc++ )
;
va_end( ap );
operation = im_operation_register( name, desc, flags, disp, argc );
va_start( ap, disp );
for( i = 0; (argument = va_arg( ap, im_argument_t * )); i++ )
operation->argv[i] = argument;
va_end( ap );
return( operation );
}
void *
im_operation_map( VSListMap2Fn fn, void *a, void *b )
{
@ -330,16 +342,11 @@ add_vec( im_value_t **argv )
void
im__operation_init( void )
{
im_operation_t *operation;
operation = im_operation_register( "im_add", _( "add two images" ),
im_operation_registerv( "im_add", _( "add two images" ),
IM_FN_PIO | IM_FN_PTOP,
add_vec,
3 );
operation->argv[0] = im_argument_new( "in1",
im_type_lookup( IM_TYPE_NAME_IMAGE, NULL ), TRUE );
operation->argv[1] = im_argument_new( "in2",
im_type_lookup( IM_TYPE_NAME_IMAGE, NULL ), TRUE );
operation->argv[2] = im_argument_new( "out",
im_type_lookup( IM_TYPE_NAME_IMAGE, NULL ), TRUE );
im_argument_new( "in1", IM_TYPE_IM, 0 ),
im_argument_new( "in2", IM_TYPE_IM, 0 ),
im_argument_new( "out", IM_TYPE_IM, IM_ARGUMENT_OUTPUT ),
NULL );
}

View File

@ -212,6 +212,36 @@ im_slist_filter( GSList *list, VSListMap2Fn fn, void *a, void *b )
return( list );
}
typedef struct {
void *a;
void *b;
VSListMap2Fn fn;
void *result;
} Pair;
static gboolean
im_hash_table_predicate( const char *key, im_type_t *type, Pair *pair )
{
return( (pair->result == pair->fn( type, pair->a, pair->b )) );
}
/* Like slist map, but for a hash table.
*/
void *
im_hash_table_map( GHashTable *hash, VSListMap2Fn fn, void *a, void *b )
{
Pair pair;
pair.a = a;
pair.b = b;
pair.fn = fn;
pair.result = NULL;
g_hash_table_find( hash, (GHRFunc) im_hash_table_predicate, &pair );
return( pair.result );
}
/* Like strncpy(), but always NULL-terminate, and don't pad with NULLs.
*/
char *