From b8e4c57830b3ec5a35eddc74ae6c378a0c1bf3ef Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Fri, 25 Mar 2011 09:52:36 +0000 Subject: [PATCH] move im_generate to vips_ rename and reorganise im_generate and friends --- libvips/include/vips/almostdeprecated.h | 11 +- libvips/include/vips/generate.h | 26 +- libvips/include/vips/internal.h | 2 +- libvips/include/vips/vips.h | 11 +- libvips/include/vips/vips7compat.h | 11 + libvips/iofuncs/check.c | 10 +- libvips/iofuncs/generate.c | 694 ++++++++++++------------ libvips/iofuncs/im_wrapmany.c | 10 +- libvips/iofuncs/image.c | 11 +- libvips/iofuncs/sink.c | 10 +- libvips/iofuncs/sinkscreen.c | 5 +- 11 files changed, 405 insertions(+), 396 deletions(-) diff --git a/libvips/include/vips/almostdeprecated.h b/libvips/include/vips/almostdeprecated.h index 260d1c09..658dda4a 100644 --- a/libvips/include/vips/almostdeprecated.h +++ b/libvips/include/vips/almostdeprecated.h @@ -62,12 +62,6 @@ typedef struct { *(channel select) */ } IMAGE_BOX; -/* Compatibility typedefs. - */ -typedef VipsDemandStyle im_demand_type; -typedef VipsProgress im_time_t; -typedef VipsImage IMAGE; - int im_extract( IMAGE *, IMAGE *, IMAGE_BOX * ); DOUBLEMASK *im_measure( IMAGE *im, IMAGE_BOX *box, int h, int v, int *sel, int nsel, const char *name ); @@ -136,6 +130,11 @@ void im_diagnostics( const char *fmt, ... ) void im_warning( const char *fmt, ... ) __attribute__((format(printf, 1, 2))); +int im_iterate( VipsImage *im, + VipsStartFn start, VipsGenerateFn generate, VipsStopFn stop, + void *a, void *b +); + /* Deprecated operations. */ int im_cmulnorm( IMAGE *in1, IMAGE *in2, IMAGE *out ); diff --git a/libvips/include/vips/generate.h b/libvips/include/vips/generate.h index c8d2490a..ca808546 100644 --- a/libvips/include/vips/generate.h +++ b/libvips/include/vips/generate.h @@ -36,23 +36,19 @@ extern "C" { #endif /*__cplusplus*/ -typedef void *(*im_start_fn)( VipsImage *out, void *a, void *b ); -typedef int (*im_generate_fn)( VipsRegion *out, void *seq, void *a, void *b ); -typedef int (*im_stop_fn)( void *seq, void *a, void *b ); +typedef void *(*VipsStartFn)( VipsImage *out, void *a, void *b ); +typedef int (*VipsGenerateFn)( VipsRegion *out, void *seq, void *a, void *b ); +typedef int (*VipsStopFn)( void *seq, void *a, void *b ); -void *im_start_one( VipsImage *out, void *a, void *b ); -int im_stop_one( void *seq, void *a, void *b ); -void *im_start_many( VipsImage *out, void *a, void *b ); -int im_stop_many( void *seq, void *a, void *b ); -VipsImage **im_allocate_input_array( VipsImage *out, ... ) +void *vips_start_one( VipsImage *out, void *a, void *b ); +int vips_stop_one( void *seq, void *a, void *b ); +void *vips_start_many( VipsImage *out, void *a, void *b ); +int vips_stop_many( void *seq, void *a, void *b ); +VipsImage **vips_allocate_input_array( VipsImage *out, ... ) __attribute__((sentinel)); -int im_generate( VipsImage *im, - im_start_fn start, im_generate_fn generate, im_stop_fn stop, - void *a, void *b -); -int im_iterate( VipsImage *im, - im_start_fn start, im_generate_fn generate, im_stop_fn stop, +int vips_image_generate( VipsImage *im, + VipsStartFn start, VipsGenerateFn generate, VipsStopFn stop, void *a, void *b ); @@ -86,8 +82,6 @@ int im_render_priority( VipsImage *in, VipsImage *out, VipsImage *mask, void (*notify)( VipsImage *, VipsRect *, void * ), void *client ); int im_cache( VipsImage *in, VipsImage *out, int width, int height, int max ); -int im_setupout( VipsImage *im ); - #ifdef __cplusplus } #endif /*__cplusplus*/ diff --git a/libvips/include/vips/internal.h b/libvips/include/vips/internal.h index 1f235894..b9faf78e 100644 --- a/libvips/include/vips/internal.h +++ b/libvips/include/vips/internal.h @@ -161,7 +161,7 @@ int im__arith_binary_const( const char *domain, int im__value( VipsImage *im, double *value ); typedef int (*im__wrapscan_fn)( void *p, int n, void *seq, void *a, void *b ); int im__wrapscan( VipsImage *in, - im_start_fn start, im__wrapscan_fn scan, im_stop_fn stop, + VipsStartFn start, im__wrapscan_fn scan, VipsStopFn stop, void *a, void *b ); int im__colour_difference( const char *domain, VipsImage *in1, VipsImage *in2, VipsImage *out, diff --git a/libvips/include/vips/vips.h b/libvips/include/vips/vips.h index 16c3aae9..56aa0bcc 100644 --- a/libvips/include/vips/vips.h +++ b/libvips/include/vips/vips.h @@ -106,10 +106,8 @@ extern "C" { #include #include #include -#include #include #include -#include #include #include #include @@ -139,13 +137,16 @@ extern "C" { #include #include +#ifndef VIPS_DISABLE_VIPS7COMPAT +#include +#endif /*VIPS_DISABLE_VIPS7COMPAT*/ + #ifdef VIPS_ENABLE_DEPRECATED #include #endif /*VIPS_ENABLE_DEPRECATED*/ -#ifndef VIPS_DISABLE_VIPS7COMPAT -#include -#endif /*VIPS_DISABLE_VIPS7COMPAT*/ +#include +#include const char *vips_get_argv0( void ); int vips_init( const char *argv0 ); diff --git a/libvips/include/vips/vips7compat.h b/libvips/include/vips/vips7compat.h index 00241101..d3790878 100644 --- a/libvips/include/vips/vips7compat.h +++ b/libvips/include/vips/vips7compat.h @@ -284,6 +284,17 @@ VipsDemandStyle im_char2dhint( const char *str ); #define im_demand_hint vips_demand_hint #define im_demand_hint_array vips_demand_hint_array +#define im_start_one vips_start_one +#define im_stop_one vips_stop_one +#define im_start_many vips_start_many +#define im_stop_many vips_stop_many +#define im_allocate_input_array vips_allocate_input_array +#define im_start_fn VipsStartFn +#define im_generate_fn VipsGenerateFn +#define im_stop_fn VipsStopFn + +#define im_generate vips_image_generate + #ifdef __cplusplus } #endif /*__cplusplus*/ diff --git a/libvips/iofuncs/check.c b/libvips/iofuncs/check.c index 5d8a912b..163c5131 100644 --- a/libvips/iofuncs/check.c +++ b/libvips/iofuncs/check.c @@ -482,10 +482,10 @@ im_pincheck( IMAGE *im ) * im_poutcheck: * @im: image to check * - * Check that an image is writeable with im_generate(). If it isn't, - * try to transform the image so that im_generate() can work. + * Check that an image is writeable with vips_image_generate(). If it isn't, + * try to transform the image so that vips_image_generate() can work. * - * See also: im_incheck(), im_poutcheck(), im_generate(). + * See also: im_incheck(), im_poutcheck(), vips_image_generate(). * * Returns: 0 on succeess, or -1 on error. */ @@ -543,8 +543,8 @@ im_poutcheck( IMAGE *im ) * @in: input image * @out: output image * - * A convenience function to check a pair of images for IO via im_prepare() - * and im_generate(). + * A convenience function to check a pair of images for IO via + * vips_region_prepare() and vips_image_generate(). * * See also: im_pincheck(), im_poutcheck(). * diff --git a/libvips/iofuncs/generate.c b/libvips/iofuncs/generate.c index 174e59ce..9cecf14b 100644 --- a/libvips/iofuncs/generate.c +++ b/libvips/iofuncs/generate.c @@ -47,6 +47,9 @@ * - gtkdoc comments * 16/4/10 * - remove threadgroup stuff + * 24/3/11 + * - move demand_hint stuff in here + * - move to vips_ namespace */ /* @@ -116,347 +119,6 @@ * processing operation, and ask for regions of image to be calculated. */ -/** - * im_start_one: - * @out: image to generate - * @a: user data - * @b: user data - * - * Start function for one image in. Input image is first user data. - * - * See also: im_generate(). - */ -void * -im_start_one( IMAGE *out, void *a, void *b ) -{ - IMAGE *in = (IMAGE *) a; - - return( vips_region_new( in ) ); -} - -/** - * im_stop_one: - * @seq: sequence value - * @a: user data - * @b: user data - * - * Stop function for one image in. Input image is @a. - * - * See also: im_generate(). - */ -int -im_stop_one( void *seq, void *a, void *b ) -{ - VipsRegion *reg = (VipsRegion *) seq; - - g_object_unref( reg ); - - return( 0 ); -} - -/** - * im_stop_many: - * @seq: sequence value - * @a: user data - * @b: user data - * - * Stop function for many images in. First user data is a pointer to - * a %NULL-terminated array of input images. - * - * See also: im_generate(). - */ -int -im_stop_many( void *seq, void *a, void *b ) -{ - VipsRegion **ar = (VipsRegion **) seq; - - if( ar ) { - int i; - - for( i = 0; ar[i]; i++ ) - g_object_unref( ar[i] ); - im_free( (char *) ar ); - } - - return( 0 ); -} - -/** - * im_start_many: - * @out: image to generate - * @a: user data - * @b: user data - * - * Start function for many images in. @a is a pointer to - * a %NULL-terminated array of input images. - * - * See also: im_generate(), im_allocate_input_array() - */ -void * -im_start_many( IMAGE *out, void *a, void *b ) -{ - IMAGE **in = (IMAGE **) a; - - int i, n; - VipsRegion **ar; - - /* How many images? - */ - for( n = 0; in[n]; n++ ) - ; - - /* Alocate space for region array. - */ - if( !(ar = VIPS_ARRAY( NULL, n + 1, VipsRegion * )) ) - return( NULL ); - - /* Create a set of regions. - */ - for( i = 0; i < n; i++ ) - if( !(ar[i] = vips_region_new( in[i] )) ) { - im_stop_many( ar, NULL, NULL ); - return( NULL ); - } - ar[n] = NULL; - - return( ar ); -} - -/** - * im_allocate_input_array: - * @out: free array when this image closes - * @Varargs: %NULL-terminated list of input images - * - * Convenience function --- make a %NULL-terminated array of input images. - * Use with im_start_many(). - * - * See also: im_generate(), im_start_many(). - * - * Returns: %NULL-terminated array of images. Do not free the result. - */ -IMAGE ** -im_allocate_input_array( IMAGE *out, ... ) -{ - va_list ap; - IMAGE **ar; - IMAGE *im; - int i, n; - - /* Count input images. - */ - va_start( ap, out ); - for( n = 0; (im = va_arg( ap, IMAGE * )); n++ ) - ; - va_end( ap ); - - /* Allocate array. - */ - if( !(ar = VIPS_ARRAY( out, n + 1, IMAGE * )) ) - return( NULL ); - - /* Fill array. - */ - va_start( ap, out ); - for( i = 0; i < n; i++ ) - ar[i] = va_arg( ap, IMAGE * ); - va_end( ap ); - ar[n] = NULL; - - return( ar ); -} - -/** - * im_start_fn: - * @out: image being calculated - * @a: user data - * @b: user data - * - * Start a new processing sequence for this generate function. This allocates - * per-thread state, such as an input region. - * - * See also: im_start_one(), im_start_many(). - * - * Returns: a new sequence value - */ - -/** - * im_generate_fn: - * @out: #VipsRegion to fill - * @seq: sequence value - * @a: user data - * @b: user data - * - * Fill @out->valid with pixels. @seq contains per-thread state, such as the - * input regions. - * - * See also: im_generate(), im_stop_many(). - * - * Returns: 0 on success, -1 on error. - */ - -/** - * im_stop_fn: - * @seq: sequence value - * @a: user data - * @b: user data - * - * Stop a processing sequence. This frees - * per-thread state, such as an input region. - * - * See also: im_stop_one(), im_stop_many(). - * - * Returns: 0 on success, -1 on error. - */ - -/* A write function for VIPS images. Just write() the pixel data. - */ -static int -write_vips( VipsRegion *region, VipsRect *area, void *a, void *b ) -{ - size_t nwritten, count; - void *buf; - - count = region->bpl * area->height; - buf = VIPS_REGION_ADDR( region, 0, area->top ); - do { - nwritten = write( region->im->fd, buf, count ); - if( nwritten == (size_t) -1 ) - return( errno ); - - buf = (void *) ((char *) buf + nwritten); - count -= nwritten; - } while( count > 0 ); - - return( 0 ); -} - -/** - * im_generate: - * @im: generate this image - * @start: start sequences with this function - * @generate: generate pixels with this function - * @stop: stop sequences with this function - * @a: user data - * @b: user data - * - * Generates an image. The action depends on the image type. - * - * For images opened with "p", im_generate() just attaches the - * start/generate/stop callbacks and returns. - * - * For "t" images, memory is allocated for the whole image and it is entirely - * generated using vips_sink(). - * - * For "w" images, memory for a few scanlines is allocated and - * vips_sink_disc() used to generate the image in small chunks. As each - * chunk is generated, it is written to disc. - * - * See also: vips_sink(), im_open(), im_prepare(), im_wrapone(). - * - * Returns: 0 on success, or -1 on error. - */ -int -im_generate( IMAGE *im, - im_start_fn start, im_generate_fn generate, im_stop_fn stop, - void *a, void *b ) -{ - int res; - - g_assert( vips_object_sanity( VIPS_OBJECT( im ) ) ); - - if( !im->hint_set ) { - vips_error( "im_generate", - "%s", _( "im_demand_hint() not set" ) ); - return( -1 ); - } - - if( im->Xsize <= 0 || im->Ysize <= 0 || im->Bands <= 0 ) { - vips_error( "im_generate", - "%s", _( "bad dimensions" ) ); - return( -1 ); - } - - /* We don't use this, but make sure it's set in case any old binaries - * are expecting it. - */ - im->Bbits = vips_format_sizeof( im->BandFmt ) << 3; - - /* Look at output type to decide our action. - */ - switch( im->dtype ) { - case VIPS_IMAGE_PARTIAL: - /* Output to partial image. Just attach functions and return. - */ - if( im->generate || im->start || im->stop ) { - vips_error( "im_generate", - "%s", _( "func already attached" ) ); - return( -1 ); - } - - im->start = start; - im->generate = generate; - im->stop = stop; - im->client1 = a; - im->client2 = b; - -#ifdef DEBUG_IO - printf( "im_generate: attaching partial callbacks\n" ); -#endif /*DEBUG_IO*/ - - break; - - case VIPS_IMAGE_SETBUF: - case VIPS_IMAGE_SETBUF_FOREIGN: - case VIPS_IMAGE_MMAPINRW: - case VIPS_IMAGE_OPENOUT: - /* Eval now .. sanity check. - */ - if( im->generate || im->start || im->stop ) { - vips_error( "im_generate", - "%s", _( "func already attached" ) ); - return( -1 ); - } - - /* Get output ready. - */ - if( vips__image_write_prepare( im ) ) - return( -1 ); - - /* Attach callbacks. - */ - im->start = start; - im->generate = generate; - im->stop = stop; - im->client1 = a; - im->client2 = b; - - if( im->dtype == VIPS_IMAGE_OPENOUT ) - res = vips_sink_disc( im, - (VipsRegionWrite) write_vips, NULL ); - else - res = vips_sink_memory( im ); - - /* Error? - */ - if( res ) - return( -1 ); - - break; - - default: - /* Not a known output style. - */ - vips_error( "im_generate", _( "unable to output to a %s image" ), - im_dtype2char( im->dtype ) ); - return( -1 ); - } - - if( vips_image_written( im ) ) - return( -1 ); - - return( 0 ); -} - /* Max number of images we can handle. */ #define MAX_IMAGES (1000) @@ -591,14 +253,14 @@ vips__link_map( VipsImage *image, VSListMap2Fn fn, void *a, void *b ) * Operations can set demand hints, that is, hints to the VIPS IO system about * the type of region geometry this operation works best with. For example, * operations which transform coordinates will usually work best with - * %IM_SMALLTILE, operations which work on local windows of pixels will like - * %IM_FATSTRIP. + * %VIPS_DEMAND_STYLE_SMALLTILE, operations which work on local windows of + * pixels will like %VIPS_DEMAND_STYLE_FATSTRIP. * * VIPS uses the list of input images to build the tree of operations it needs * for the cache invalidation system. You have to call this function, or its * varargs friend vips_demand_hint(). * - * See also: vips_demand_hint(), im_generate(). + * See also: vips_demand_hint(), vips_image_generate(). * * Returns: 0 on success, or -1 on error. */ @@ -656,7 +318,7 @@ vips_demand_hint_array( VipsImage *image, VipsDemandStyle hint, VipsImage **in ) vips__link_make( in[i], image ); /* Set a flag on the image to say we remember to call this thing. - * im_generate() and friends check this. + * vips_image_generate() and friends check this. */ image->hint_set = TRUE; @@ -671,7 +333,7 @@ vips_demand_hint_array( VipsImage *image, VipsDemandStyle hint, VipsImage **in ) * * Build an array and call vips_demand_hint_array(). * - * See also: vips_demand_hint(), im_generate(). + * See also: vips_demand_hint(), vips_image_generate(). * * Returns: 0 on success, or -1 on error. */ @@ -695,3 +357,343 @@ vips_demand_hint( VipsImage *image, VipsDemandStyle hint, ... ) return( vips_demand_hint_array( image, hint, ar ) ); } +/** + * vips_start_one: + * @out: image to generate + * @a: user data + * @b: user data + * + * Start function for one image in. Input image is @a. + * + * See also: vips_image_generate(). + */ +void * +vips_start_one( VipsImage *out, void *a, void *b ) +{ + VipsImage *in = (VipsImage *) a; + + return( vips_region_new( in ) ); +} + +/** + * vips_stop_one: + * @seq: sequence value + * @a: user data + * @b: user data + * + * Stop function for one image in. Input image is @a. + * + * See also: vips_image_generate(). + */ +int +vips_stop_one( void *seq, void *a, void *b ) +{ + VipsRegion *reg = (VipsRegion *) seq; + + g_object_unref( reg ); + + return( 0 ); +} + +/** + * vips_stop_many: + * @seq: sequence value + * @a: user data + * @b: user data + * + * Stop function for many images in. @a is a pointer to + * a %NULL-terminated array of input images. + * + * See also: vips_image_generate(). + */ +int +vips_stop_many( void *seq, void *a, void *b ) +{ + VipsRegion **ar = (VipsRegion **) seq; + + if( ar ) { + int i; + + for( i = 0; ar[i]; i++ ) + g_object_unref( ar[i] ); + im_free( (char *) ar ); + } + + return( 0 ); +} + +/** + * vips_start_many: + * @out: image to generate + * @a: user data + * @b: user data + * + * Start function for many images in. @a is a pointer to + * a %NULL-terminated array of input images. + * + * See also: vips_image_generate(), im_allocate_input_array() + */ +void * +vips_start_many( VipsImage *out, void *a, void *b ) +{ + VipsImage **in = (VipsImage **) a; + + int i, n; + VipsRegion **ar; + + /* How many images? + */ + for( n = 0; in[n]; n++ ) + ; + + /* Alocate space for region array. + */ + if( !(ar = VIPS_ARRAY( NULL, n + 1, VipsRegion * )) ) + return( NULL ); + + /* Create a set of regions. + */ + for( i = 0; i < n; i++ ) + if( !(ar[i] = vips_region_new( in[i] )) ) { + vips_stop_many( ar, NULL, NULL ); + return( NULL ); + } + ar[n] = NULL; + + return( ar ); +} + +/** + * vips_allocate_input_array: + * @image: free array when this image closes + * @Varargs: %NULL-terminated list of input images + * + * Convenience function --- make a %NULL-terminated array of input images. + * Use with vips_start_many(). + * + * See also: vips_image_generate(), vips_start_many(). + * + * Returns: %NULL-terminated array of images. Do not free the result. + */ +VipsImage ** +vips_allocate_input_array( VipsImage *image, ... ) +{ + va_list ap; + VipsImage **ar; + VipsImage *im; + int i, n; + + /* Count input images. + */ + va_start( ap, image ); + for( n = 0; (im = va_arg( ap, VipsImage * )); n++ ) + ; + va_end( ap ); + + /* Allocate array. + */ + if( !(ar = VIPS_ARRAY( image, n + 1, VipsImage * )) ) + return( NULL ); + + /* Fill array. + */ + va_start( ap, image ); + for( i = 0; i < n; i++ ) + ar[i] = va_arg( ap, VipsImage * ); + va_end( ap ); + ar[n] = NULL; + + return( ar ); +} + +/** + * VipsStartFn: + * @image: image being calculated + * @a: user data + * @b: user data + * + * Start a new processing sequence for this generate function. This allocates + * per-thread state, such as an input region. + * + * See also: vips_start_one(), vips_start_many(). + * + * Returns: a new sequence value + */ + +/** + * VipsGenerateFn: + * @region: #VipsRegion to fill + * @seq: sequence value + * @a: user data + * @b: user data + * + * Fill @image->valid with pixels. @seq contains per-thread state, such as the + * input regions. + * + * See also: vips_image_generate(), vips_stop_many(). + * + * Returns: 0 on success, -1 on error. + */ + +/** + * VipsStopFn: + * @seq: sequence value + * @a: user data + * @b: user data + * + * Stop a processing sequence. This frees + * per-thread state, such as an input region. + * + * See also: vips_stop_one(), vips_stop_many(). + * + * Returns: 0 on success, -1 on error. + */ + +/* A write function for VIPS images. Just write() the pixel data. + */ +static int +write_vips( VipsRegion *region, VipsRect *area, void *a, void *b ) +{ + size_t nwritten, count; + void *buf; + + count = region->bpl * area->height; + buf = VIPS_REGION_ADDR( region, 0, area->top ); + do { + nwritten = write( region->im->fd, buf, count ); + if( nwritten == (size_t) -1 ) + return( errno ); + + buf = (void *) ((char *) buf + nwritten); + count -= nwritten; + } while( count > 0 ); + + return( 0 ); +} + +/** + * vips_image_generate: + * @image: generate this image + * @start: start sequences with this function + * @generate: generate pixels with this function + * @stop: stop sequences with this function + * @a: user data + * @b: user data + * + * Generates an image. The action depends on the image type. + * + * For images opened with "p", vips_image_generate() just attaches the + * start/generate/stop callbacks and returns. + * + * For "t" images, memory is allocated for the whole image and it is entirely + * generated using vips_sink(). + * + * For "w" images, memory for a few scanlines is allocated and + * vips_sink_disc() used to generate the image in small chunks. As each + * chunk is generated, it is written to disc. + * + * See also: vips_sink(), vips_image_new(), vips_region_prepare(). + * + * Returns: 0 on success, or -1 on error. + */ +int +vips_image_generate( VipsImage *image, + VipsStartFn start, VipsGenerateFn generate, VipsStopFn stop, + void *a, void *b ) +{ + int res; + + g_assert( vips_object_sanity( VIPS_OBJECT( image ) ) ); + + if( !image->hint_set ) { + vips_error( "vips_image_generate", + "%s", _( "im_demand_hint() not set" ) ); + return( -1 ); + } + + /* We don't use this, but make sure it's set in case any old binaries + * are expecting it. + */ + image->Bbits = vips_format_sizeof( image->BandFmt ) << 3; + + /* Look at output type to decide our action. + */ + switch( image->dtype ) { + case VIPS_IMAGE_PARTIAL: + /* Output to partial image. Just attach functions and return. + */ + if( image->generate || + image->start || + image->stop ) { + vips_error( "VipsImage", + "%s", _( "func already attached" ) ); + return( -1 ); + } + + image->start = start; + image->generate = generate; + image->stop = stop; + image->client1 = a; + image->client2 = b; + +#ifdef DEBUG_IO + printf( "vips_image_generate: attaching partial callbacks\n" ); +#endif /*DEBUG_IO*/ + + break; + + case VIPS_IMAGE_SETBUF: + case VIPS_IMAGE_SETBUF_FOREIGN: + case VIPS_IMAGE_MMAPINRW: + case VIPS_IMAGE_OPENOUT: + /* Eval now .. sanity check. + */ + if( image->generate || + image->start || + image->stop ) { + vips_error( "VipsImage", + "%s", _( "func already attached" ) ); + return( -1 ); + } + + /* Attach callbacks. + */ + image->start = start; + image->generate = generate; + image->stop = stop; + image->client1 = a; + image->client2 = b; + + /* Get output ready. + */ + if( vips__image_write_prepare( image ) ) + return( -1 ); + + if( image->dtype == VIPS_IMAGE_OPENOUT ) + res = vips_sink_disc( image, + (VipsRegionWrite) write_vips, NULL ); + else + res = vips_sink_memory( image ); + + /* Error? + */ + if( res ) + return( -1 ); + + break; + + default: + /* Not a known output style. + */ + vips_error( "VipsImage", + _( "unable to output to a %s image" ), + VIPS_ENUM_NICK( VIPS_TYPE_DEMAND_STYLE, + image->dtype ) ); + return( -1 ); + } + + if( vips_image_written( image ) ) + return( -1 ); + + return( 0 ); +} diff --git a/libvips/iofuncs/im_wrapmany.c b/libvips/iofuncs/im_wrapmany.c index 17f54d09..87feab8a 100644 --- a/libvips/iofuncs/im_wrapmany.c +++ b/libvips/iofuncs/im_wrapmany.c @@ -162,7 +162,7 @@ dupims( IMAGE *out, IMAGE **in ) * output image and a buffer processing function, make a PIO image processing * operation. * - * See also: im_wrapone(), im_wraptwo(), im_generate(). + * See also: im_wrapone(), im_wraptwo(), vips_image_generate(). * * Returns: 0 on success, or -1 on error. */ @@ -213,8 +213,8 @@ im_wrapmany( IMAGE **in, IMAGE *out, im_wrapmany_fn fn, void *a, void *b ) /* Generate! */ - if( im_generate( out, - im_start_many, process_region, im_stop_many, in, bun ) ) + if( vips_image_generate( out, + vips_start_many, process_region, vips_stop_many, in, bun ) ) return( -1 ); return( 0 ); @@ -251,7 +251,7 @@ wrapone_gen( void **ins, void *out, int width, Bundle *bun, void *dummy ) * output image and a buffer processing function, make a PIO image processing * operation. * - * See also: im_wrapmany(), im_wraptwo(), im_generate(). + * See also: im_wrapmany(), im_wraptwo(), vips_image_generate(). * * Returns: 0 on success, or -1 on error. */ @@ -306,7 +306,7 @@ wraptwo_gen( void **ins, void *out, int width, Bundle *bun, void *dummy ) * output image and a buffer processing function, make a PIO image processing * operation. * - * See also: im_wrapone(), im_wrapmany(), im_generate(). + * See also: im_wrapone(), im_wrapmany(), vips_image_generate(). * * Returns: 0 on success, or -1 on error. */ diff --git a/libvips/iofuncs/image.c b/libvips/iofuncs/image.c index fe1314ac..3d604d22 100644 --- a/libvips/iofuncs/image.c +++ b/libvips/iofuncs/image.c @@ -88,7 +88,8 @@ * the kind of demand geometry they prefer. * * These demand styles are given below in order of increasing - * restrictiveness. When demanding output from a pipeline, im_generate() + * restrictiveness. When demanding output from a pipeline, + * vips_image_generate() * will use the most restrictive of the styles requested by the operations * in the pipeline. * @@ -782,8 +783,8 @@ vips_image_open_lazy( VipsImage *image, /* Then 'start' creates the real image and 'gen' paints 'out' with * pixels from the real image on demand. */ - if( im_generate( image, - open_lazy_start, open_lazy_generate, im_stop_one, + if( vips_image_generate( image, + open_lazy_start, open_lazy_generate, vips_stop_one, lazy, NULL ) ) return( -1 ); @@ -1802,7 +1803,7 @@ vips_image_new_array( VipsImage *parent, VipsImage **images, int n ) } /* Get the image ready for writing. This can get called many - * times. Used by im_generate() and vips_image_write_line(). vips7 compat can + * times. Used by vips_image_generate() and vips_image_write_line(). vips7 compat can * call this as im_setupout(). */ int @@ -1870,7 +1871,7 @@ vips__image_write_prepare( VipsImage *image ) * with @ypos increasing from 0 to @YSize - * @linebuffer must be IM_IMAGE_SIZEOF_LINE() bytes long. * - * See also: im_setupout(), im_generate(). + * See also: vips_image_generate(). * * Returns: 0 on success, or -1 on error. */ diff --git a/libvips/iofuncs/sink.c b/libvips/iofuncs/sink.c index c13f19d2..ec30862f 100644 --- a/libvips/iofuncs/sink.c +++ b/libvips/iofuncs/sink.c @@ -74,9 +74,9 @@ typedef struct _Sink { /* Call params. */ - im_start_fn start; - im_generate_fn generate; - im_stop_fn stop; + VipsStartFn start; + VipsGenerateFn generate; + VipsStopFn stop; void *a; void *b; } Sink; @@ -208,7 +208,7 @@ sink_free( Sink *sink ) static int sink_init( Sink *sink, VipsImage *im, - im_start_fn start, im_generate_fn generate, im_stop_fn stop, + VipsStartFn start, VipsGenerateFn generate, VipsStopFn stop, void *a, void *b ) { sink->im = im; @@ -385,7 +385,7 @@ vips_sink_tile( VipsImage *im, * Each set of pixels is sized according to the requirements of the image * pipeline that generated @im. * - * See also: im_generate(), im_open(). + * See also: vips_image_generate(), vips_image_new(). * * Returns: 0 on success, or -1 on error. */ diff --git a/libvips/iofuncs/sinkscreen.c b/libvips/iofuncs/sinkscreen.c index 54a46b11..9e51b26e 100644 --- a/libvips/iofuncs/sinkscreen.c +++ b/libvips/iofuncs/sinkscreen.c @@ -1110,11 +1110,12 @@ vips_sink_screen( VipsImage *in, VipsImage *out, VipsImage *mask, VIPS_DEBUG_MSG( "vips_sink_screen: max = %d, %p\n", max_tiles, render ); - if( im_generate( out, + if( vips_image_generate( out, image_start, image_fill, image_stop, render, NULL ) ) return( -1 ); if( mask && - im_generate( mask, NULL, mask_fill, NULL, render, NULL ) ) + vips_image_generate( mask, + NULL, mask_fill, NULL, render, NULL ) ) return( -1 ); return( 0 );