added postclose callbacks
This commit is contained in:
parent
88779a7e3b
commit
157e01bb4c
@ -12,6 +12,7 @@
|
||||
- im_flood() and friends rewritten, typically 4x faster
|
||||
- removed --with-cimg option, added --disable-cxx
|
||||
- added im_system_image() (thanks Roland)
|
||||
- added postclose callbacks
|
||||
|
||||
26/11/09 started 7.20.3
|
||||
- updated en_GB.po translation
|
||||
|
@ -27,7 +27,7 @@ echo " by" `header -f Ysize temp.v` "pixels"
|
||||
echo "starting benchmark ..."
|
||||
echo "chain=$chain"
|
||||
|
||||
for cpus in 1 2 ; do
|
||||
for cpus in 1 2 3 4 5 6 ; do
|
||||
export IM_CONCURRENCY=$cpus
|
||||
|
||||
echo IM_CONCURRENCY=$IM_CONCURRENCY
|
||||
|
@ -92,26 +92,30 @@ static int
|
||||
system_image_vec( im_object *argv )
|
||||
{
|
||||
IMAGE *in = argv[0];
|
||||
char *in_format = argv[1];
|
||||
char *out_format = argv[2];
|
||||
char *cmd = argv[3];
|
||||
char **log = (char **) &argv[4];
|
||||
char **out_file = (char **) &argv[5];
|
||||
IMAGE *out = argv[1];
|
||||
char *in_format = argv[2];
|
||||
char *out_format = argv[3];
|
||||
char *cmd = argv[4];
|
||||
char **log = (char **) &argv[5];
|
||||
|
||||
*out_file = im_system_image( in, in_format, out_format, cmd, log );
|
||||
if( !*out_file )
|
||||
*out_file = im_strdup( NULL, "" );
|
||||
IMAGE *out_image;
|
||||
|
||||
if( (out_image = im_system_image( in,
|
||||
in_format, out_format, cmd, log )) )
|
||||
im_copy_file( out_image, out );
|
||||
|
||||
/* We always succeed, but out may be invalid.
|
||||
*/
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static im_arg_desc system_image_args[] = {
|
||||
IM_INPUT_IMAGE( "im" ),
|
||||
IM_INPUT_IMAGE( "in" ),
|
||||
IM_OUTPUT_IMAGE( "out" ),
|
||||
IM_INPUT_STRING( "in_format" ),
|
||||
IM_INPUT_STRING( "out_format" ),
|
||||
IM_INPUT_STRING( "command" ),
|
||||
IM_OUTPUT_STRING( "log" ),
|
||||
IM_OUTPUT_STRING( "out_file" )
|
||||
IM_OUTPUT_STRING( "log" )
|
||||
};
|
||||
|
||||
static im_function system_image_desc = {
|
||||
|
@ -60,7 +60,7 @@ im_copy_file( IMAGE *in, IMAGE *out )
|
||||
if( !im_isfile( in ) ) {
|
||||
IMAGE *disc;
|
||||
|
||||
if( !(disc = im__open_temp()) )
|
||||
if( !(disc = im__open_temp( "%s.v" )) )
|
||||
return( -1 );
|
||||
if( im_add_close_callback( out,
|
||||
(im_callback_fn) im_close, disc, NULL ) ) {
|
||||
|
@ -79,7 +79,7 @@ im_system( IMAGE *im, const char *cmd, char **out )
|
||||
if( !im_isfile( im ) ) {
|
||||
IMAGE *disc;
|
||||
|
||||
if( !(disc = im__open_temp()) )
|
||||
if( !(disc = im__open_temp( "%s.v" )) )
|
||||
return( -1 );
|
||||
if( im_copy( im, disc ) ||
|
||||
im_system( disc, cmd, out ) ) {
|
||||
|
@ -60,31 +60,20 @@
|
||||
|
||||
static int
|
||||
system_image( IMAGE *im,
|
||||
const char *in_name, const char *out_name, const char *cmd_format,
|
||||
IMAGE *in_image, IMAGE *out_image, const char *cmd_format,
|
||||
char **log )
|
||||
{
|
||||
IMAGE *disc;
|
||||
const char *in_name = in_image->filename;
|
||||
const char *out_name = out_image->filename;
|
||||
FILE *fp;
|
||||
char line[IM_MAX_STRSIZE];
|
||||
char txt[IM_MAX_STRSIZE];
|
||||
VipsBuf buf = VIPS_BUF_STATIC( txt );
|
||||
int result;
|
||||
|
||||
if( !(disc = im_open( in_name, "w" )) )
|
||||
if( im_copy( im, in_image ) ||
|
||||
!(fp = im_popenf( cmd_format, "r", in_name, out_name )) )
|
||||
return( -1 );
|
||||
if( im_copy( im, disc ) ) {
|
||||
im_close( im );
|
||||
g_unlink( in_name );
|
||||
|
||||
return( -1 );
|
||||
}
|
||||
im_close( im );
|
||||
|
||||
if( !(fp = im_popenf( cmd_format, "r", in_name, out_name )) ) {
|
||||
g_unlink( in_name );
|
||||
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
while( fgets( line, IM_MAX_STRSIZE, fp ) )
|
||||
if( !vips_buf_appends( &buf, line ) )
|
||||
@ -92,15 +81,14 @@ system_image( IMAGE *im,
|
||||
|
||||
result = pclose( fp );
|
||||
|
||||
g_unlink( in_name );
|
||||
|
||||
if( log )
|
||||
*log = im_strdup( NULL, vips_buf_all( &buf ) );
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* im_system_image:
|
||||
|
||||
Run a command on an image, returning a new image.
|
||||
|
||||
@ -127,29 +115,29 @@ system_image( IMAGE *im,
|
||||
|
||||
*/
|
||||
|
||||
char *
|
||||
IMAGE *
|
||||
im_system_image( IMAGE *im,
|
||||
const char *in_format, const char *out_format, const char *cmd_format,
|
||||
char **log )
|
||||
{
|
||||
char *in_name;
|
||||
char *out_name;
|
||||
IMAGE *in_image;
|
||||
IMAGE *out_image;
|
||||
|
||||
if( log )
|
||||
*log = NULL;
|
||||
|
||||
in_name = im__temp_name( in_format );
|
||||
out_name = im__temp_name( in_format );
|
||||
in_image = im__open_temp( in_format );
|
||||
out_image = im__open_temp( out_format );
|
||||
|
||||
if( !in_name ||
|
||||
!out_name ||
|
||||
system_image( im, in_name, out_name, cmd_format, log ) ) {
|
||||
g_free( in_name );
|
||||
g_free( out_name );
|
||||
if( !in_image ||
|
||||
!out_image ||
|
||||
system_image( im, in_image, out_image, cmd_format, log ) ) {
|
||||
im_close( in_image );
|
||||
im_close( out_image );
|
||||
|
||||
return( NULL );
|
||||
}
|
||||
g_free( in_name );
|
||||
im_close( in_image );
|
||||
|
||||
return( out_name );
|
||||
return( out_image );
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ typedef int (*im_callback_fn)( void *a, void *b );
|
||||
|
||||
int im_add_close_callback( IMAGE *im, im_callback_fn fn, void *a, void *b );
|
||||
int im_add_preclose_callback( IMAGE *im, im_callback_fn fn, void *a, void *b );
|
||||
int im_add_postclose_callback( IMAGE *im, im_callback_fn fn, void *a, void *b );
|
||||
|
||||
int im_add_evalstart_callback( IMAGE *im, im_callback_fn fn, void *a, void *b );
|
||||
int im_add_eval_callback( IMAGE *im, im_callback_fn fn, void *a, void *b );
|
||||
|
@ -111,7 +111,7 @@ int im_subsample( IMAGE *in, IMAGE *out, int x, int y );
|
||||
int im_zoom( IMAGE *in, IMAGE *out, int x, int y );
|
||||
|
||||
int im_system( IMAGE *im, const char *cmd, char **out );
|
||||
char *im_system_image( IMAGE *im,
|
||||
IMAGE *im_system_image( IMAGE *im,
|
||||
const char *in_format, const char *out_format, const char *cmd_format,
|
||||
char **log );
|
||||
|
||||
|
@ -240,6 +240,11 @@ typedef struct _VipsImage {
|
||||
* relationships, so it's a mandatory thing.
|
||||
*/
|
||||
gboolean hint_set;
|
||||
|
||||
/* Post-close callbacks happen on finalize. Eg. deleting the file
|
||||
* associated with this temp image.
|
||||
*/
|
||||
GSList *postclosefns;
|
||||
} VipsImage;
|
||||
|
||||
extern const size_t im__sizeof_bandfmt[];
|
||||
|
@ -255,7 +255,7 @@ int im_isvips( const char *filename );
|
||||
int im_amiMSBfirst( void );
|
||||
|
||||
char *im__temp_name( const char *format );
|
||||
IMAGE *im__open_temp( void );
|
||||
IMAGE *im__open_temp( const char *format );
|
||||
|
||||
int im_bits_of_fmt( VipsBandFmt fmt );
|
||||
|
||||
|
@ -108,11 +108,11 @@ add_callback( IMAGE *im, GSList **cblist, im_callback_fn fn, void *a, void *b )
|
||||
*
|
||||
* Attaches a close callback @fn to @im.
|
||||
*
|
||||
* Close callbacks are triggered exactly once when the image has been closed
|
||||
* Close callbacks are triggered exactly once, when the image has been closed
|
||||
* and most resources freed, but just before the memory for @im is released.
|
||||
*
|
||||
* Close callbacks are a good place to free memory that was need to generate
|
||||
* @im, delete temporary files and so on. You can close other images and there
|
||||
* @im. You can close other images and there
|
||||
* may even be circularity in your close lists.
|
||||
*
|
||||
* See also: im_malloc() (implemented with im_add_close_callback()),
|
||||
@ -127,6 +127,29 @@ im_add_close_callback( IMAGE *im, im_callback_fn fn, void *a, void *b )
|
||||
return( add_callback( im, &im->closefns, fn, a, b ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* im_add_postclose_callback:
|
||||
* @im: image to attach callback to
|
||||
* @fn: callback function
|
||||
* @a: user data 1
|
||||
* @b: user data 2
|
||||
*
|
||||
* Attaches a close callback @fn to @im.
|
||||
*
|
||||
* Post-close callbacks are triggered exactly once, just before the memory
|
||||
* associated with @im is released.
|
||||
*
|
||||
* Close callbacks are a good place to delete temporary files. You can close
|
||||
* other images and there may even be circularity in your close lists.
|
||||
*
|
||||
* Returns: 0 on success, or -1 on error.
|
||||
*/
|
||||
int
|
||||
im_add_postclose_callback( IMAGE *im, im_callback_fn fn, void *a, void *b )
|
||||
{
|
||||
return( add_callback( im, &im->postclosefns, fn, a, b ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* im_add_preclose_callback:
|
||||
* @im: image to attach callback to
|
||||
|
@ -393,16 +393,18 @@ im_printdesc( IMAGE *image )
|
||||
*/
|
||||
if( image->generate )
|
||||
printf( "generate function attached\n" );
|
||||
if( image->preclosefns )
|
||||
printf( "preclose callbacks attached\n" );
|
||||
if( image->closefns )
|
||||
printf( "close callbacks attached\n" );
|
||||
if( image->postclosefns )
|
||||
printf( "postclose callbacks attached\n" );
|
||||
if( image->evalfns )
|
||||
printf( "eval callbacks attached\n" );
|
||||
if( image->evalendfns )
|
||||
printf( "evalend callbacks attached\n" );
|
||||
if( image->evalstartfns )
|
||||
printf( "evalstart callbacks attached\n" );
|
||||
if( image->preclosefns )
|
||||
printf( "preclose callbacks attached\n" );
|
||||
if( image->invalidatefns )
|
||||
printf( "invalidate callbacks attached\n" );
|
||||
if( image->regions ) {
|
||||
|
@ -50,6 +50,8 @@
|
||||
* released
|
||||
* 6/10/09
|
||||
* - gtkdoc comment
|
||||
* 10/1/09
|
||||
* - added postclose
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -294,6 +296,8 @@ im_close( IMAGE *im )
|
||||
|
||||
/* Final cleanup.
|
||||
*/
|
||||
result |= im__trigger_callbacks( im->postclosefns );
|
||||
IM_FREEF( im_slist_free_all, im->postclosefns );
|
||||
IM_FREEF( g_mutex_free, im->sslock );
|
||||
IM_FREE( im->filename );
|
||||
IM_FREE( im->Hist );
|
||||
|
@ -32,6 +32,8 @@
|
||||
* - add file_length
|
||||
* 8/10/09
|
||||
* - add set_hint
|
||||
* 10/1/09
|
||||
* - added postclose
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -173,6 +175,8 @@ im_init( const char *filename )
|
||||
|
||||
im->hint_set = FALSE;
|
||||
|
||||
im->postclosefns = NULL;
|
||||
|
||||
if( !(im->filename = im_strdup( NULL, filename )) ) {
|
||||
im_close( im );
|
||||
return( NULL );
|
||||
|
@ -1546,14 +1546,15 @@ im__temp_name( const char *format )
|
||||
}
|
||||
|
||||
/* Make a disc IMAGE which will be automatically unlinked on im_close().
|
||||
* Format is something like "%s.v" for a vips file.
|
||||
*/
|
||||
IMAGE *
|
||||
im__open_temp( void )
|
||||
im__open_temp( const char *format )
|
||||
{
|
||||
char *name;
|
||||
IMAGE *disc;
|
||||
|
||||
if( !(name = im__temp_name( "%s.v" )) )
|
||||
if( !(name = im__temp_name( format )) )
|
||||
return( NULL );
|
||||
|
||||
if( !(disc = im_open( name, "w" )) ) {
|
||||
@ -1562,7 +1563,10 @@ im__open_temp( void )
|
||||
}
|
||||
g_free( name );
|
||||
|
||||
if( im_add_close_callback( disc,
|
||||
/* Needs to be postclose so we can rewindd disc after write without
|
||||
* deleting the file.
|
||||
*/
|
||||
if( im_add_postclose_callback( disc,
|
||||
(im_callback_fn) unlink, disc->filename, NULL ) ) {
|
||||
im_close( disc );
|
||||
g_unlink( name );
|
||||
|
@ -184,7 +184,7 @@ im_create_imask( const char *filename, int xs, int ys )
|
||||
|
||||
INTMASK *
|
||||
im_create_imaskv( const char *filename, int xs, int ys, ... )
|
||||
{
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
INTMASK *m;
|
||||
|
Loading…
Reference in New Issue
Block a user