From 59187ed20ff66b0a3d98e29681a6946049d19252 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 22 Oct 2007 13:24:46 +0000 Subject: [PATCH] add intvec and doublevec output --- ChangeLog | 1 + TODO | 16 ------ include/vips/dispatch.h | 79 ++++++++++++++++++----------- libsrc/arithmetic/arith_dispatch.c | 80 ++++++++++++++++++++++++++++++ libsrc/arithmetic/im_maxpos_vec.c | 2 +- libsrc/iofuncs/dispatch_types.c | 56 +++++++++++++++++++++ libsrc/iofuncs/package.c | 4 +- 7 files changed, 190 insertions(+), 48 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0cead0fa..26f8b9b2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,7 @@ - oop, include missing - add protos for generate/iterate function args, fix warnings - add cimg package, we now have C++ source inside VIPS, sigh +- added OUTPUT_DOUBLEVEC and OUTPUT_INTVEC, use for im_maxpos_vec() and friends 29/8/07 started 7.13.0 - we now have a trunk and the version is 7.13.x, woo! diff --git a/TODO b/TODO index a402cda8..03470ddc 100644 --- a/TODO +++ b/TODO @@ -6,8 +6,6 @@ - im_spcor2() has a potential leak in the start function -- zerox_gen() passes an int as a void*, hmm - Python binding ============== @@ -42,20 +40,6 @@ WONTFIX consider openexr write -- add GREYCstoration filter - - http://www.haypocalc.com/wiki/Gimp_Plugin_GREYCstoration - - actually, it has to be a plugin, since their code is GPL - - and very memory-hungry for large images :-( needs 20x size of image to be - processed - - could we rewrite with VIPS? how much more stuff would we need to add? - - try again using the current version of the filter from the suthors rather - than the gimp plugin - - im_csv2vips() could use "-" for filename to mean stdin but then we'd have to read to a malloced buffer of some sort rather than an diff --git a/include/vips/dispatch.h b/include/vips/dispatch.h index e9fb4359..98971595 100644 --- a/include/vips/dispatch.h +++ b/include/vips/dispatch.h @@ -176,60 +176,79 @@ typedef struct { /* Built-in VIPS types. */ +extern im_type_desc im__input_int; +extern im_type_desc im__input_intvec; +extern im_type_desc im__input_imask; +extern im_type_desc im__output_int; +extern im_type_desc im__output_intvec; +extern im_type_desc im__output_imask; + +extern im_type_desc im__input_double; +extern im_type_desc im__input_doublevec; +extern im_type_desc im__input_dmask; +extern im_type_desc im__output_double; +extern im_type_desc im__output_doublevec; +extern im_type_desc im__output_dmask; +extern im_type_desc im__output_dmask_screen; + +extern im_type_desc im__output_complex; + +extern im_type_desc im__input_string; +extern im_type_desc im__output_string; + extern im_type_desc im__input_imagevec; extern im_type_desc im__input_image; extern im_type_desc im__output_image; extern im_type_desc im__rw_image; -extern im_type_desc im__input_doublevec; -extern im_type_desc im__input_intvec; -extern im_type_desc im__input_double; -extern im_type_desc im__output_double; -extern im_type_desc im__input_int; -extern im_type_desc im__output_int; -extern im_type_desc im__input_string; -extern im_type_desc im__output_string; -extern im_type_desc im__output_complex; -extern im_type_desc im__input_dmask; -extern im_type_desc im__output_dmask; -extern im_type_desc im__output_dmask_screen; + extern im_type_desc im__input_display; extern im_type_desc im__output_display; -extern im_type_desc im__input_imask; -extern im_type_desc im__output_imask; + extern im_type_desc im__input_gvalue; +extern im_type_desc im__output_gvalue; /* VIPS print functions. */ int im__iprint( im_object obj ); /* int */ +int im__ivprint( im_object obj ); /* intvec */ int im__dprint( im_object obj ); /* double */ +int im__dvprint( im_object obj ); /* doublevec */ +int im__dmsprint( im_object obj ); /* DOUBLEMASK as stats */ int im__cprint( im_object obj ); /* complex */ int im__sprint( im_object obj ); /* string */ int im__displayprint( im_object obj ); /* im_col_display */ -int im__dmsprint( im_object obj ); /* DOUBLEMASK as stats */ int im__gprint( im_object obj ); /* GValue */ /* Macros for convenient creation. */ -#define IM_INPUT_IMAGEVEC( S ) { S, &im__input_imagevec, NULL } -#define IM_INPUT_IMAGE( S ) { S, &im__input_image, NULL } -#define IM_OUTPUT_IMAGE( S ) { S, &im__output_image, NULL } -#define IM_RW_IMAGE( S ) { S, &im__rw_image, NULL } +#define IM_INPUT_INT( S ) { S, &im__input_int, NULL } +#define IM_INPUT_INTVEC( S ) { S, &im__input_intvec, NULL } +#define IM_INPUT_IMASK( S ) { S, &im__input_imask, NULL } +#define IM_OUTPUT_INT( S ) { S, &im__output_int, im__iprint } +#define IM_OUTPUT_INTVEC( S ) { S, &im__output_intvec, im__ivprint } +#define IM_OUTPUT_IMASK( S ) { S, &im__output_imask, NULL } + #define IM_INPUT_DOUBLE( S ) { S, &im__input_double, NULL } #define IM_INPUT_DOUBLEVEC( S ) { S, &im__input_doublevec, NULL } -#define IM_INPUT_INTVEC( S ) { S, &im__input_intvec, NULL } -#define IM_OUTPUT_DOUBLE( S ) { S, &im__output_double, im__dprint } -#define IM_INPUT_INT( S ) { S, &im__input_int, NULL } -#define IM_OUTPUT_INT( S ) { S, &im__output_int, im__iprint } -#define IM_INPUT_STRING( S ) { S, &im__input_string, NULL } -#define IM_OUTPUT_STRING( S ) { S, &im__output_string, im__sprint } -#define IM_INPUT_DISPLAY( S ) { S, &im__input_display, NULL } -#define IM_OUTPUT_DISPLAY( S ) { S, &im__output_display, im__displayprint } -#define IM_OUTPUT_COMPLEX( S ) { S, &im__output_complex, im__cprint } #define IM_INPUT_DMASK( S ) { S, &im__input_dmask, NULL } +#define IM_OUTPUT_DOUBLE( S ) { S, &im__output_double, im__dprint } +#define IM_OUTPUT_DOUBLEVEC( S ) { S, &im__output_doublevec, im__dvprint } #define IM_OUTPUT_DMASK( S ) { S, &im__output_dmask, NULL } #define IM_OUTPUT_DMASK_STATS( S ) { S, &im__output_dmask_screen, im__dmsprint } -#define IM_INPUT_IMASK( S ) { S, &im__input_imask, NULL } -#define IM_OUTPUT_IMASK( S ) { S, &im__output_imask, NULL } + +#define IM_OUTPUT_COMPLEX( S ) { S, &im__output_complex, im__cprint } + +#define IM_INPUT_STRING( S ) { S, &im__input_string, NULL } +#define IM_OUTPUT_STRING( S ) { S, &im__output_string, im__sprint } + +#define IM_INPUT_IMAGE( S ) { S, &im__input_image, NULL } +#define IM_INPUT_IMAGEVEC( S ) { S, &im__input_imagevec, NULL } +#define IM_OUTPUT_IMAGE( S ) { S, &im__output_image, NULL } +#define IM_RW_IMAGE( S ) { S, &im__rw_image, NULL } + +#define IM_INPUT_DISPLAY( S ) { S, &im__input_display, NULL } +#define IM_OUTPUT_DISPLAY( S ) { S, &im__output_display, im__displayprint } + #define IM_INPUT_GVALUE( S ) { S, &im__input_gvalue, NULL } #define IM_OUTPUT_GVALUE( S ) { S, &im__output_gvalue, im__gprint } diff --git a/libsrc/arithmetic/arith_dispatch.c b/libsrc/arithmetic/arith_dispatch.c index 579c7deb..e43e1e64 100644 --- a/libsrc/arithmetic/arith_dispatch.c +++ b/libsrc/arithmetic/arith_dispatch.c @@ -838,6 +838,84 @@ static im_function maxpos_avg_desc = { maxpos_avg_args }; +/* Args to im_min/maxpos_vec. + */ +static im_arg_desc maxpos_vec_args[] = { + IM_INPUT_IMAGE ("in"), + IM_INPUT_INT ("n"), + IM_OUTPUT_INTVEC("xes"), + IM_OUTPUT_INTVEC("yes"), + IM_OUTPUT_DOUBLEVEC("maxima") +}; + +/* Call im_maxpos_vec via arg vector. + */ +static int +maxpos_vec_vec( im_object *argv ) +{ + int n = *((int *) argv[1]); + im_intvec_object *xes = argv[2]; + im_intvec_object *yes = argv[3]; + im_doublevec_object *maxima = argv[4]; + + xes->vec = IM_ARRAY( NULL, n, int ); + xes->n = n; + yes->vec = IM_ARRAY( NULL, n, int ); + yes->n = n; + maxima->vec = IM_ARRAY( NULL, n, double ); + maxima->n = n; + if( !xes->vec || !yes->vec || !maxima->vec || + im_maxpos_vec( argv[0], xes->vec, yes->vec, maxima->vec, n ) ) + return -1; + + return 0; +} + +/* Description of im_maxpos_vec. + */ +static im_function maxpos_vec_desc = { + "im_maxpos_vec", + "position and value of n maxima of image", + IM_FN_PIO, + maxpos_vec_vec, + IM_NUMBER( maxpos_vec_args ), + maxpos_vec_args +}; + +/* Call im_minpos_vec via arg vector. + */ +static int +minpos_vec_vec( im_object *argv ) +{ + int n = *((int *) argv[1]); + im_intvec_object *xes = argv[2]; + im_intvec_object *yes = argv[3]; + im_doublevec_object *minima = argv[4]; + + xes->vec = IM_ARRAY( NULL, n, int ); + xes->n = n; + yes->vec = IM_ARRAY( NULL, n, int ); + yes->n = n; + minima->vec = IM_ARRAY( NULL, n, double ); + minima->n = n; + if( !xes->vec || !yes->vec || !minima->vec || + im_minpos_vec( argv[0], xes->vec, yes->vec, minima->vec, n ) ) + return -1; + + return 0; +} + +/* Description of im_minpos_vec. + */ +static im_function minpos_vec_desc = { + "im_minpos_vec", + "position and value of n minima of image", + IM_FN_PIO, + minpos_vec_vec, + IM_NUMBER( maxpos_vec_args ), + maxpos_vec_args +}; + /* Args for measure. */ static im_arg_desc measure_args[] = { @@ -1221,9 +1299,11 @@ static im_function *arith_list[] = { &max_desc, &maxpos_desc, &maxpos_avg_desc, + &maxpos_vec_desc, &measure_desc, &min_desc, &minpos_desc, + &minpos_vec_desc, &multiply_desc, &powtra_desc, &powtra_vec_desc, diff --git a/libsrc/arithmetic/im_maxpos_vec.c b/libsrc/arithmetic/im_maxpos_vec.c index 499652c8..67a425de 100644 --- a/libsrc/arithmetic/im_maxpos_vec.c +++ b/libsrc/arithmetic/im_maxpos_vec.c @@ -106,7 +106,7 @@ static int minpos_vec_stop( void *seq, void *, void * ); int im_maxpos_vec( IMAGE *im, int *xpos, int *ypos, double *maxima, int n ){ #define FUNCTION_NAME "im_maxpos_vec" /* number of sequences used is beyond my control at this level, but I note that */ - /* effeciency decreases as more sequences are used - speed may still increase */ + /* efficiency decreases as more sequences are used - speed may still increase */ int result; int *pointers= im_malloc( NULL, n * sizeof( int* ) ); diff --git a/libsrc/iofuncs/dispatch_types.c b/libsrc/iofuncs/dispatch_types.c index c723c888..f6844146 100644 --- a/libsrc/iofuncs/dispatch_types.c +++ b/libsrc/iofuncs/dispatch_types.c @@ -473,6 +473,34 @@ im_type_desc im__input_doublevec = { doublevec_dest /* Destroy function */ }; +/* Print function for doublevec output. + */ +int +im__dvprint( im_object obj ) +{ + im_doublevec_object *dv = obj; + int i; + + for( i = 0; i < dv->n; i++ ) { + if( i > 0 ) + printf( "," ); + printf( "%G", dv->vec[i] ); + } + printf( "\n" ); + + return( 0 ); +} + +/* Output double vector type. + */ +im_type_desc im__output_doublevec = { + IM_TYPE_DOUBLEVEC, /* Its an array of double */ + sizeof( im_doublevec_object ), /* Memory to allocate in vec build */ + IM_TYPE_OUTPUT, /* Output type */ + NULL, /* Init function */ + doublevec_dest /* Destroy function */ +}; + /* im_intvec_object destroy function. */ static int @@ -539,6 +567,34 @@ im_type_desc im__input_intvec = { intvec_dest /* Destroy function */ }; +/* Print function for intvec output. + */ +int +im__ivprint( im_object obj ) +{ + im_intvec_object *iv = obj; + int i; + + for( i = 0; i < iv->n; i++ ) { + if( i > 0 ) + printf( "," ); + printf( "%d", iv->vec[i] ); + } + printf( "\n" ); + + return( 0 ); +} + +/* Output int vector type. + */ +im_type_desc im__output_intvec = { + IM_TYPE_INTVEC, /* It's an array of int */ + sizeof( im_intvec_object ), /* Memory to allocate in vec build */ + IM_TYPE_OUTPUT, /* Output arg */ + NULL, /* Init function */ + intvec_dest /* Destroy function */ +}; + /* Init function for int input. */ static int diff --git a/libsrc/iofuncs/package.c b/libsrc/iofuncs/package.c index a5e58448..72a3866e 100644 --- a/libsrc/iofuncs/package.c +++ b/libsrc/iofuncs/package.c @@ -886,9 +886,11 @@ print_args( im_function *fn, im_object *vargv ) /* Print all elements. */ for( i = 0; i < vargc; i++ ) - if( fn->argv[i].print && vargv[i] ) + if( fn->argv[i].print && vargv[i] ) { + printf( "%s: ", fn->argv[i].name ); if( fn->argv[i].print( vargv[i] ) ) return( -1 ); + } return( 0 ); }