stuff
This commit is contained in:
parent
21ec53fda9
commit
4fce90fabb
@ -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
|
||||
|
@ -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 );
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include <vips/vips.h>
|
||||
#include <vips/dispatch.h>
|
||||
|
||||
#ifdef WITH_DMALLOC
|
||||
#include <dmalloc.h>
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include <vips/intl.h>
|
||||
|
||||
#include <vips/vips.h>
|
||||
#include <vips/dispatch.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -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>
|
||||
|
@ -56,6 +56,7 @@
|
||||
#include <assert.h>
|
||||
|
||||
#include <vips/vips.h>
|
||||
#include <vips/dispatch.h>
|
||||
|
||||
#ifdef WITH_DMALLOC
|
||||
#include <dmalloc.h>
|
||||
|
@ -65,6 +65,7 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <vips/vips.h>
|
||||
#include <vips/dispatch.h>
|
||||
|
||||
#ifdef WITH_DMALLOC
|
||||
#include <dmalloc.h>
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user