The VIPS type mechanism is extensible. User plug-ins can add new types and user-interfaces can (to a certain extent) provide interfaces to these user-defined types.
Here is the definition of im_arg_desc
:
/* Describe a VIPS command argument. */ typedef struct { char *name; im_type_desc *desc; im_print_obj_fn print; } im_arg_desc;
The name
field is the argument name above. The desc
field
points to a structure defining the argument type, and the print
field
is an (optionally NULL
) pointer to a function which VIPS will call
for output arguments after your function successfully completes and before
the object is destroyed. It can be used to print results to the terminal,
or to copy results into a user-interface layer.
/* Success on an argument. This is * called if the image processing * function succeeds and should be used * to (for example) print output. */ typedef int (*im_print_obj_fn) ( im_object obj );
im_type_desc
is defined as:
/* Describe a VIPS type. */ typedef struct { im_arg_type type; int size; im_type_flags flags; im_init_obj_fn init; im_dest_obj_fn dest; } im_type_desc;
Where im_arg_type
is defined as
/* Type names. You may define your own, * but if you use one of these, then you * should use the built-in VIPS type * converters. */ #define IM_TYPE_IMAGEVEC "imagevec" #define IM_TYPE_REALVEC "realvec" #define IM_TYPE_DOUBLE "double" #define IM_TYPE_INT "integer" #define IM_TYPE_COMPLEX "complex" #define IM_TYPE_STRING "string" #define IM_TYPE_IMASK "intmask" #define IM_TYPE_DMASK "doublemask" #define IM_TYPE_IMAGE "image" #define IM_TYPE_DISPLAY "display" typedef char *im_arg_type;
In other words, it's just a string. When you add a new type, you just need to choose a new unique string to name it. Be aware that the string is printed to the user by various parts of VIPS, and so needs to be ``human-readable''. The flags are:
/* These bits are ored together to make * the flags in a type descriptor. * * IM_TYPE_OUTPUT: set to indicate * output, otherwise input. * * IM_TYPE_ARG: Two ways of making an * im_object --- with and without * a command-line string to help you * along. Arguments with a string * are thing like IMAGE descriptors, * which require a filename to * initialise. Arguments without are * things like output numbers, where * making the object simply involves * allocating storage. */ typedef enum { IM_TYPE_OUTPUT = 0x1, IM_TYPE_ARG = 0x2 } im_type_flags;
And the init
and destroy
functions are:
/* Initialise and destroy objects. The * "str" argument to the init function * will not be supplied if this is not an * ARG type. */ typedef int (*im_init_obj_fn) ( im_object *obj, char *str ); typedef int (*im_dest_obj_fn) ( im_object obj );
As an example, here is the definition for a new type of unsigned
integers. First, we need to define the init
and print
functions. These transform objects of the type to and from string
representation.
/* Init function for unsigned int input. */ static int uint_init( im_object *obj, char *str ) { unsigned int *i = (int *) *obj; if( sscanf( str, "%d", i ) != 1 || *i < 0 ) { im_error( "uint_init", "bad format" ); return( -1 ); } return( 0 ); } /* Print function for unsigned int * output. */ static int uint_print( im_object obj ) { unsigned int *i = (unsigned int *) obj; printf( "%d\n", (int) *i ); return( 0 ); }
Now we can define the type itself. We make two of these -- one for unsigned int used as input, and one for output.
/* Name our type. */ #define TYPE_UINT "uint" /* Input unsigned int type. */ static im_type_desc input_uint = { TYPE_UINT, /* Its an int */ sizeof( unsigned int ),/* Memory */ IM_TYPE_ARG, /* Needs arg */ uint_init, /* Init */ NULL /* Destroy */ }; /* Output unsigned int type. */ static im_type_desc output_uint = { TYPE_UINT, /* Its an int */ sizeof( unsigned int ),/* Memory */ IM_TYPE_OUTPUT, /* Its an output */ NULL, /* Init */ NULL /* Destroy */ };
Finally, we can define two macros to make structures of type
im_arg_desc
for us.
#define INPUT_UINT( S ) \ { S, &input_uint, NULL } #define OUTPUT_UINT( S ) \ { S, &output_uint, uint_print }
For more examples, see the definitions for the built-in VIPS types:
$VIPSHOME/libsrc/iofuncs/dispatch_types.c $VIPSHOME/include/vips/dispatch.h