added postclose callbacks
This commit is contained in:
parent
88779a7e3b
commit
157e01bb4c
@ -12,6 +12,7 @@
|
|||||||
- im_flood() and friends rewritten, typically 4x faster
|
- im_flood() and friends rewritten, typically 4x faster
|
||||||
- removed --with-cimg option, added --disable-cxx
|
- removed --with-cimg option, added --disable-cxx
|
||||||
- added im_system_image() (thanks Roland)
|
- added im_system_image() (thanks Roland)
|
||||||
|
- added postclose callbacks
|
||||||
|
|
||||||
26/11/09 started 7.20.3
|
26/11/09 started 7.20.3
|
||||||
- updated en_GB.po translation
|
- updated en_GB.po translation
|
||||||
|
@ -27,7 +27,7 @@ echo " by" `header -f Ysize temp.v` "pixels"
|
|||||||
echo "starting benchmark ..."
|
echo "starting benchmark ..."
|
||||||
echo "chain=$chain"
|
echo "chain=$chain"
|
||||||
|
|
||||||
for cpus in 1 2 ; do
|
for cpus in 1 2 3 4 5 6 ; do
|
||||||
export IM_CONCURRENCY=$cpus
|
export IM_CONCURRENCY=$cpus
|
||||||
|
|
||||||
echo IM_CONCURRENCY=$IM_CONCURRENCY
|
echo IM_CONCURRENCY=$IM_CONCURRENCY
|
||||||
|
@ -92,26 +92,30 @@ static int
|
|||||||
system_image_vec( im_object *argv )
|
system_image_vec( im_object *argv )
|
||||||
{
|
{
|
||||||
IMAGE *in = argv[0];
|
IMAGE *in = argv[0];
|
||||||
char *in_format = argv[1];
|
IMAGE *out = argv[1];
|
||||||
char *out_format = argv[2];
|
char *in_format = argv[2];
|
||||||
char *cmd = argv[3];
|
char *out_format = argv[3];
|
||||||
char **log = (char **) &argv[4];
|
char *cmd = argv[4];
|
||||||
char **out_file = (char **) &argv[5];
|
char **log = (char **) &argv[5];
|
||||||
|
|
||||||
*out_file = im_system_image( in, in_format, out_format, cmd, log );
|
IMAGE *out_image;
|
||||||
if( !*out_file )
|
|
||||||
*out_file = im_strdup( NULL, "" );
|
|
||||||
|
|
||||||
|
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 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
static im_arg_desc system_image_args[] = {
|
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( "in_format" ),
|
||||||
IM_INPUT_STRING( "out_format" ),
|
IM_INPUT_STRING( "out_format" ),
|
||||||
IM_INPUT_STRING( "command" ),
|
IM_INPUT_STRING( "command" ),
|
||||||
IM_OUTPUT_STRING( "log" ),
|
IM_OUTPUT_STRING( "log" )
|
||||||
IM_OUTPUT_STRING( "out_file" )
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static im_function system_image_desc = {
|
static im_function system_image_desc = {
|
||||||
|
@ -60,7 +60,7 @@ im_copy_file( IMAGE *in, IMAGE *out )
|
|||||||
if( !im_isfile( in ) ) {
|
if( !im_isfile( in ) ) {
|
||||||
IMAGE *disc;
|
IMAGE *disc;
|
||||||
|
|
||||||
if( !(disc = im__open_temp()) )
|
if( !(disc = im__open_temp( "%s.v" )) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
if( im_add_close_callback( out,
|
if( im_add_close_callback( out,
|
||||||
(im_callback_fn) im_close, disc, NULL ) ) {
|
(im_callback_fn) im_close, disc, NULL ) ) {
|
||||||
|
@ -79,7 +79,7 @@ im_system( IMAGE *im, const char *cmd, char **out )
|
|||||||
if( !im_isfile( im ) ) {
|
if( !im_isfile( im ) ) {
|
||||||
IMAGE *disc;
|
IMAGE *disc;
|
||||||
|
|
||||||
if( !(disc = im__open_temp()) )
|
if( !(disc = im__open_temp( "%s.v" )) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
if( im_copy( im, disc ) ||
|
if( im_copy( im, disc ) ||
|
||||||
im_system( disc, cmd, out ) ) {
|
im_system( disc, cmd, out ) ) {
|
||||||
|
@ -60,31 +60,20 @@
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
system_image( IMAGE *im,
|
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 )
|
char **log )
|
||||||
{
|
{
|
||||||
IMAGE *disc;
|
const char *in_name = in_image->filename;
|
||||||
|
const char *out_name = out_image->filename;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char line[IM_MAX_STRSIZE];
|
char line[IM_MAX_STRSIZE];
|
||||||
char txt[IM_MAX_STRSIZE];
|
char txt[IM_MAX_STRSIZE];
|
||||||
VipsBuf buf = VIPS_BUF_STATIC( txt );
|
VipsBuf buf = VIPS_BUF_STATIC( txt );
|
||||||
int result;
|
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 );
|
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 ) )
|
while( fgets( line, IM_MAX_STRSIZE, fp ) )
|
||||||
if( !vips_buf_appends( &buf, line ) )
|
if( !vips_buf_appends( &buf, line ) )
|
||||||
@ -92,15 +81,14 @@ system_image( IMAGE *im,
|
|||||||
|
|
||||||
result = pclose( fp );
|
result = pclose( fp );
|
||||||
|
|
||||||
g_unlink( in_name );
|
|
||||||
|
|
||||||
if( log )
|
if( log )
|
||||||
*log = im_strdup( NULL, vips_buf_all( &buf ) );
|
*log = im_strdup( NULL, vips_buf_all( &buf ) );
|
||||||
|
|
||||||
return( result );
|
return( result );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
|
* im_system_image:
|
||||||
|
|
||||||
Run a command on an image, returning a new 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,
|
im_system_image( IMAGE *im,
|
||||||
const char *in_format, const char *out_format, const char *cmd_format,
|
const char *in_format, const char *out_format, const char *cmd_format,
|
||||||
char **log )
|
char **log )
|
||||||
{
|
{
|
||||||
char *in_name;
|
IMAGE *in_image;
|
||||||
char *out_name;
|
IMAGE *out_image;
|
||||||
|
|
||||||
if( log )
|
if( log )
|
||||||
*log = NULL;
|
*log = NULL;
|
||||||
|
|
||||||
in_name = im__temp_name( in_format );
|
in_image = im__open_temp( in_format );
|
||||||
out_name = im__temp_name( in_format );
|
out_image = im__open_temp( out_format );
|
||||||
|
|
||||||
if( !in_name ||
|
if( !in_image ||
|
||||||
!out_name ||
|
!out_image ||
|
||||||
system_image( im, in_name, out_name, cmd_format, log ) ) {
|
system_image( im, in_image, out_image, cmd_format, log ) ) {
|
||||||
g_free( in_name );
|
im_close( in_image );
|
||||||
g_free( out_name );
|
im_close( out_image );
|
||||||
|
|
||||||
return( NULL );
|
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_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_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_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 );
|
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_zoom( IMAGE *in, IMAGE *out, int x, int y );
|
||||||
|
|
||||||
int im_system( IMAGE *im, const char *cmd, char **out );
|
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,
|
const char *in_format, const char *out_format, const char *cmd_format,
|
||||||
char **log );
|
char **log );
|
||||||
|
|
||||||
|
@ -240,6 +240,11 @@ typedef struct _VipsImage {
|
|||||||
* relationships, so it's a mandatory thing.
|
* relationships, so it's a mandatory thing.
|
||||||
*/
|
*/
|
||||||
gboolean hint_set;
|
gboolean hint_set;
|
||||||
|
|
||||||
|
/* Post-close callbacks happen on finalize. Eg. deleting the file
|
||||||
|
* associated with this temp image.
|
||||||
|
*/
|
||||||
|
GSList *postclosefns;
|
||||||
} VipsImage;
|
} VipsImage;
|
||||||
|
|
||||||
extern const size_t im__sizeof_bandfmt[];
|
extern const size_t im__sizeof_bandfmt[];
|
||||||
|
@ -255,7 +255,7 @@ int im_isvips( const char *filename );
|
|||||||
int im_amiMSBfirst( void );
|
int im_amiMSBfirst( void );
|
||||||
|
|
||||||
char *im__temp_name( const char *format );
|
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 );
|
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.
|
* 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.
|
* 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
|
* 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.
|
* may even be circularity in your close lists.
|
||||||
*
|
*
|
||||||
* See also: im_malloc() (implemented with im_add_close_callback()),
|
* 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 ) );
|
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_add_preclose_callback:
|
||||||
* @im: image to attach callback to
|
* @im: image to attach callback to
|
||||||
|
@ -393,16 +393,18 @@ im_printdesc( IMAGE *image )
|
|||||||
*/
|
*/
|
||||||
if( image->generate )
|
if( image->generate )
|
||||||
printf( "generate function attached\n" );
|
printf( "generate function attached\n" );
|
||||||
|
if( image->preclosefns )
|
||||||
|
printf( "preclose callbacks attached\n" );
|
||||||
if( image->closefns )
|
if( image->closefns )
|
||||||
printf( "close callbacks attached\n" );
|
printf( "close callbacks attached\n" );
|
||||||
|
if( image->postclosefns )
|
||||||
|
printf( "postclose callbacks attached\n" );
|
||||||
if( image->evalfns )
|
if( image->evalfns )
|
||||||
printf( "eval callbacks attached\n" );
|
printf( "eval callbacks attached\n" );
|
||||||
if( image->evalendfns )
|
if( image->evalendfns )
|
||||||
printf( "evalend callbacks attached\n" );
|
printf( "evalend callbacks attached\n" );
|
||||||
if( image->evalstartfns )
|
if( image->evalstartfns )
|
||||||
printf( "evalstart callbacks attached\n" );
|
printf( "evalstart callbacks attached\n" );
|
||||||
if( image->preclosefns )
|
|
||||||
printf( "preclose callbacks attached\n" );
|
|
||||||
if( image->invalidatefns )
|
if( image->invalidatefns )
|
||||||
printf( "invalidate callbacks attached\n" );
|
printf( "invalidate callbacks attached\n" );
|
||||||
if( image->regions ) {
|
if( image->regions ) {
|
||||||
|
@ -50,6 +50,8 @@
|
|||||||
* released
|
* released
|
||||||
* 6/10/09
|
* 6/10/09
|
||||||
* - gtkdoc comment
|
* - gtkdoc comment
|
||||||
|
* 10/1/09
|
||||||
|
* - added postclose
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -294,6 +296,8 @@ im_close( IMAGE *im )
|
|||||||
|
|
||||||
/* Final cleanup.
|
/* Final cleanup.
|
||||||
*/
|
*/
|
||||||
|
result |= im__trigger_callbacks( im->postclosefns );
|
||||||
|
IM_FREEF( im_slist_free_all, im->postclosefns );
|
||||||
IM_FREEF( g_mutex_free, im->sslock );
|
IM_FREEF( g_mutex_free, im->sslock );
|
||||||
IM_FREE( im->filename );
|
IM_FREE( im->filename );
|
||||||
IM_FREE( im->Hist );
|
IM_FREE( im->Hist );
|
||||||
|
@ -32,6 +32,8 @@
|
|||||||
* - add file_length
|
* - add file_length
|
||||||
* 8/10/09
|
* 8/10/09
|
||||||
* - add set_hint
|
* - add set_hint
|
||||||
|
* 10/1/09
|
||||||
|
* - added postclose
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -173,6 +175,8 @@ im_init( const char *filename )
|
|||||||
|
|
||||||
im->hint_set = FALSE;
|
im->hint_set = FALSE;
|
||||||
|
|
||||||
|
im->postclosefns = NULL;
|
||||||
|
|
||||||
if( !(im->filename = im_strdup( NULL, filename )) ) {
|
if( !(im->filename = im_strdup( NULL, filename )) ) {
|
||||||
im_close( im );
|
im_close( im );
|
||||||
return( NULL );
|
return( NULL );
|
||||||
|
@ -1546,14 +1546,15 @@ im__temp_name( const char *format )
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Make a disc IMAGE which will be automatically unlinked on im_close().
|
/* Make a disc IMAGE which will be automatically unlinked on im_close().
|
||||||
|
* Format is something like "%s.v" for a vips file.
|
||||||
*/
|
*/
|
||||||
IMAGE *
|
IMAGE *
|
||||||
im__open_temp( void )
|
im__open_temp( const char *format )
|
||||||
{
|
{
|
||||||
char *name;
|
char *name;
|
||||||
IMAGE *disc;
|
IMAGE *disc;
|
||||||
|
|
||||||
if( !(name = im__temp_name( "%s.v" )) )
|
if( !(name = im__temp_name( format )) )
|
||||||
return( NULL );
|
return( NULL );
|
||||||
|
|
||||||
if( !(disc = im_open( name, "w" )) ) {
|
if( !(disc = im_open( name, "w" )) ) {
|
||||||
@ -1562,7 +1563,10 @@ im__open_temp( void )
|
|||||||
}
|
}
|
||||||
g_free( name );
|
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_callback_fn) unlink, disc->filename, NULL ) ) {
|
||||||
im_close( disc );
|
im_close( disc );
|
||||||
g_unlink( name );
|
g_unlink( name );
|
||||||
|
Loading…
x
Reference in New Issue
Block a user