move im_generate to vips_
rename and reorganise im_generate and friends
This commit is contained in:
parent
9259d686f9
commit
b8e4c57830
@ -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 );
|
||||
|
@ -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*/
|
||||
|
@ -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,
|
||||
|
@ -106,10 +106,8 @@ extern "C" {
|
||||
#include <vips/mask.h>
|
||||
#include <vips/image.h>
|
||||
#include <vips/memory.h>
|
||||
#include <vips/almostdeprecated.h>
|
||||
#include <vips/error.h>
|
||||
#include <vips/format.h>
|
||||
#include <vips/dispatch.h>
|
||||
#include <vips/region.h>
|
||||
#include <vips/generate.h>
|
||||
#include <vips/check.h>
|
||||
@ -139,13 +137,16 @@ extern "C" {
|
||||
#include <vips/video.h>
|
||||
#include <vips/cimg_funcs.h>
|
||||
|
||||
#ifndef VIPS_DISABLE_VIPS7COMPAT
|
||||
#include <vips/vips7compat.h>
|
||||
#endif /*VIPS_DISABLE_VIPS7COMPAT*/
|
||||
|
||||
#ifdef VIPS_ENABLE_DEPRECATED
|
||||
#include <vips/deprecated.h>
|
||||
#endif /*VIPS_ENABLE_DEPRECATED*/
|
||||
|
||||
#ifndef VIPS_DISABLE_VIPS7COMPAT
|
||||
#include <vips/vips7compat.h>
|
||||
#endif /*VIPS_DISABLE_VIPS7COMPAT*/
|
||||
#include <vips/almostdeprecated.h>
|
||||
#include <vips/dispatch.h>
|
||||
|
||||
const char *vips_get_argv0( void );
|
||||
int vips_init( const char *argv0 );
|
||||
|
@ -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*/
|
||||
|
@ -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().
|
||||
*
|
||||
|
@ -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 );
|
||||
}
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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 );
|
||||
|
Loading…
Reference in New Issue
Block a user