This commit is contained in:
John Cupitt 2009-09-10 10:44:10 +00:00
parent 21ec53fda9
commit 4fce90fabb
8 changed files with 81 additions and 135 deletions

View File

@ -29,6 +29,8 @@
- faster, simpler, better im_max(), im_min, im_avg(), im_deviate()
- im_max() returns true modulus, not square of modulus, for complex images
- im_avg() works for complex, returning average modulus
- im_system() fix (thanks Roland)
- im_system() rewrite
- im_maxpos()/im_minpos() are partial and work for complex
- im_max()/im_min() are now convenience functions
- im_maxpos_avg() handles complex and multi-band images

View File

@ -8,6 +8,10 @@
* - out can be NULL
* 23/12/04
* - use g_mkstemp()
* 8/9/09
* - add .v suffix (thanks Roland)
* - use vipsbuf
* - rewrite to make it simpler
*/
/*
@ -62,88 +66,8 @@
#ifdef OS_WIN32
#define popen(b,m) _popen(b,m)
#define pclose(f) _pclose(f)
#define mktemp(f) _mktemp(f)
#endif /*OS_WIN32*/
/* A string being written to ... multiple calls to buf_append add to it, on
* overflow append "..." and block further writes.
*/
typedef struct {
char *base; /* String base */
int mx; /* Maximum length */
int i; /* Current write point */
int full; /* String has filled, block writes */
int lasti; /* For read-recent */
} BufInfo;
/* Set to start state.
*/
static void
buf_rewind( BufInfo *buf )
{
buf->i = 0;
buf->lasti = 0;
buf->full = 0;
strcpy( buf->base, "" );
}
/* Init a buf struct.
*/
static void
buf_init( BufInfo *buf, char *base, int mx )
{
buf->base = base;
buf->mx = mx;
buf_rewind( buf );
}
/* Append string to buf. Error on overflow.
*/
static int
buf_appends( BufInfo *buf, const char *str )
{
int len;
int avail;
int cpy;
if( buf->full )
return( 0 );
/* Amount we want to copy.
*/
len = strlen( str );
/* Space available.
*/
avail = buf->mx - buf->i - 4;
/* Amount we actually copy.
*/
cpy = IM_MIN( len, avail );
strncpy( buf->base + buf->i, str, cpy );
buf->i += cpy;
if( buf->i >= buf->mx - 4 ) {
buf->full = 1;
strcpy( buf->base + buf->mx - 4, "..." );
buf->i = buf->mx - 1;
return( 0 );
}
return( 1 );
}
/* Read all text from buffer.
*/
static char *
buf_all( BufInfo *buf )
{
buf->base[buf->i] = '\0';
return( buf->base );
}
/* Do popen(), with printf-style args.
*/
static FILE *
@ -151,12 +75,53 @@ popenf( const char *fmt, const char *mode, ... )
{
va_list args;
char buf[IM_MAX_STRSIZE];
FILE *fp;
va_start( args, mode );
(void) im_vsnprintf( buf, IM_MAX_STRSIZE, fmt, args );
va_end( args );
return( popen( buf, mode ) );
if( !(fp = popen( buf, mode )) ) {
im_error( "popenf", "%s", strerror( errno ) );
return( NULL );
}
return( fp );
}
/* Make a disc IMAGE which will be automatically unlinked on im_close().
*/
static IMAGE *
system_temp( void )
{
const char *tmpd;
char name[IM_MAX_STRSIZE];
int fd;
IMAGE *disc;
if( !(tmpd = g_getenv( "TMPDIR" )) )
tmpd = "/tmp";
strcpy( name, tmpd );
strcat( name, "/vips_XXXXXX.v" );
if( (fd = g_mkstemp( name )) == -1 ) {
im_error( "im_system",
_( "unable to make temp file %s" ), name );
return( NULL );
}
close( fd );
if( !(disc = im_open( name, "w" )) ) {
unlink( name );
return( NULL );
}
if( im_add_close_callback( disc,
(im_callback_fn) unlink, disc->filename, NULL ) ) {
im_close( disc );
unlink( name );
}
return( disc );
}
/* Run a command on an IMAGE ... copy to tmp (if necessary), run
@ -165,61 +130,33 @@ popenf( const char *fmt, const char *mode, ... )
int
im_system( IMAGE *im, const char *cmd, char **out )
{
char *filename = im->filename;
int delete = 0;
FILE *fp;
if( !im_isfile( im ) ) {
const char *tmpd;
char name[IM_MAX_STRSIZE];
IMAGE *disc;
if( !(tmpd = g_getenv( "TMPDIR" )) )
tmpd = "/tmp";
strcpy( name, tmpd );
strcat( name, "/vips_XXXXXX" );
close( g_mkstemp( name ) );
filename = im_strdup( NULL, name );
if( !(disc = im_open( filename, "w" )) ) {
unlink( filename );
free( filename );
if( !(disc = system_temp()) )
return( -1 );
}
if( im_copy( im, disc ) ) {
if( im_copy( im, disc ) ||
im_system( disc, cmd, out ) ) {
im_close( disc );
unlink( filename );
free( filename );
return( -1 );
}
im_close( disc );
delete = 1;
}
if( (fp = popenf( cmd, "r", filename )) ) {
else if( (fp = popenf( cmd, "r", im->filename )) ) {
char line[IM_MAX_STRSIZE];
BufInfo buf;
char txt_buffer[IM_MAX_STRSIZE];
VipsBuf buf;
char str[IM_MAX_STRSIZE];
buf_init( &buf, txt_buffer, IM_MAX_STRSIZE );
vips_buf_init_static( &buf, str, IM_MAX_STRSIZE );
while( fgets( line, IM_MAX_STRSIZE, fp ) )
if( !buf_appends( &buf, line ) )
if( !vips_buf_appends( &buf, line ) )
break;
pclose( fp );
if( out )
*out = im_strdup( NULL, buf_all( &buf ) );
}
if( delete ) {
unlink( filename );
im_free( filename );
}
if( !fp ) {
im_errormsg( "popen: %s", strerror( errno ) );
return( -1 );
*out = im_strdup( NULL, vips_buf_all( &buf ) );
}
return( 0 );

View File

@ -35,6 +35,7 @@
#include <stdio.h>
#include <vips/vips.h>
#include <vips/dispatch.h>
#ifdef WITH_DMALLOC
#include <dmalloc.h>

View File

@ -46,6 +46,7 @@
#include <vips/intl.h>
#include <vips/vips.h>
#include <vips/dispatch.h>
#include <stdio.h>
#include <stdlib.h>

View File

@ -37,6 +37,7 @@ Copyright (C) 1992, Kirk Martinez, History of Art Dept, Birkbeck College
#include <string.h>
#include <vips/vips.h>
#include <vips/dispatch.h>
#ifdef WITH_DMALLOC
#include <dmalloc.h>

View File

@ -56,6 +56,7 @@
#include <assert.h>
#include <vips/vips.h>
#include <vips/dispatch.h>
#ifdef WITH_DMALLOC
#include <dmalloc.h>

View File

@ -65,6 +65,7 @@
#include <stdlib.h>
#include <vips/vips.h>
#include <vips/dispatch.h>
#ifdef WITH_DMALLOC
#include <dmalloc.h>

View File

@ -44,7 +44,7 @@
* 16/1/04 JC
* - frees as much as possible on im_close() failure
* 6/6/05 Markus Wollgarten
* - free Meta on close
* - free Meta on close
* 30/6/05 JC
* - actually, free Meta on final close, so we carry meta over on an
* im__close()/im_openin() pair (eg. see im_pincheck())
@ -57,7 +57,12 @@
* 23/7/08
* - im__close() will no longer free regions
* 9/8/08
* - lock global image list (thanks lee)
* - lock global image list (thanks Lee)
* 8/9/09
* - move close callbacks *after* we have released resources --- we
* can now write close callbacks that unlink() temporary files
* - use preclose callbacks if you want to run before resources are
* released
*/
/*
@ -168,15 +173,6 @@ im__close( IMAGE *im )
im_window_print( (im_window_t *) p->data );
}
/* Junk all callbacks, perform close callbacks.
*/
IM_FREEF( im_slist_free_all, im->evalstartfns );
IM_FREEF( im_slist_free_all, im->evalfns );
IM_FREEF( im_slist_free_all, im->evalendfns );
IM_FREEF( im_slist_free_all, im->invalidatefns );
result |= im__trigger_callbacks( im->closefns );
IM_FREEF( im_slist_free_all, im->closefns );
/* Junk generate functions.
*/
im->start = NULL;
@ -208,14 +204,11 @@ im__close( IMAGE *im )
printf( "im__close: closing output file ..\n" );
#endif /*DEBUG_IO*/
if( im->dtype == IM_OPENOUT && im__writehist( im ) ) {
im_errormsg( "im_close: unable to write metadata "
"for %s", im->filename );
if( im->dtype == IM_OPENOUT && im__writehist( im ) )
result = -1;
}
if( close( im->fd ) == -1 ) {
im_errormsg( "im_close: unable to close fd (2) "
"for %s", im->filename );
im_error( "im_close", _( "unable to close fd for %s" ),
im->filename );
result = -1;
}
im->fd = -1;
@ -237,6 +230,15 @@ im__close( IMAGE *im )
im->data = NULL;
}
/* Junk all callbacks, perform close callbacks.
*/
IM_FREEF( im_slist_free_all, im->evalstartfns );
IM_FREEF( im_slist_free_all, im->evalfns );
IM_FREEF( im_slist_free_all, im->evalendfns );
IM_FREEF( im_slist_free_all, im->invalidatefns );
result |= im__trigger_callbacks( im->closefns );
IM_FREEF( im_slist_free_all, im->closefns );
/* Reset other state.
*/
im->dtype = IM_NONE;