diff --git a/ChangeLog b/ChangeLog index 36fd9927..a0bebeeb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -66,6 +66,7 @@ im_iterate() to scan more than one image at once - threadgroup no longer has any default action, you must attach a work function +- added im_copy_file() 25/3/09 started 7.18.0 - revised version numbers diff --git a/TODO b/TODO index fef48ee7..2d5e7851 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,8 @@ +- im_cache() seems to kill threading? + + pipeline, im_cache(), output + + can we get >100% cpu? try a tiny test program - memory.c diff --git a/libvips/conversion/Makefile.am b/libvips/conversion/Makefile.am index d7857fd9..6164fe0f 100644 --- a/libvips/conversion/Makefile.am +++ b/libvips/conversion/Makefile.am @@ -12,6 +12,7 @@ libconversion_la_SOURCES = \ im_c2real.c \ im_clip.c \ im_copy.c \ + im_copy_file.c \ im_extract.c \ im_falsecolour.c \ im_fliphor.c \ diff --git a/libvips/conversion/conver_dispatch.c b/libvips/conversion/conver_dispatch.c index 2847425c..3ba23505 100644 --- a/libvips/conversion/conver_dispatch.c +++ b/libvips/conversion/conver_dispatch.c @@ -933,6 +933,30 @@ static im_function copy_desc = { one_in_one_out /* Arg list */ }; +/* Call im_copy_file via arg vector. + */ +static int +copy_file_vec( im_object *argv ) +{ + return( im_copy_file( argv[0], argv[1] ) ); +} + +/* Description of im_copy_file. + */ +static im_function copy_file_desc = { + "im_copy_file", /* Name */ + "copy image to a file and return that", + + /* Can't set PTOP ... we don't want to zap the LUT, we want the real + * image. + */ + IM_FN_PIO, /* Flags */ + + copy_file_vec, /* Dispatch function */ + IM_NUMBER( one_in_one_out ), /* Size of arg list */ + one_in_one_out /* Arg list */ +}; + /* Call im_copy_swap via arg vector. */ static int @@ -1581,6 +1605,7 @@ static im_function *conv_list[] = { &clip2us_desc, &clip_desc, ©_desc, + ©_file_desc, ©_morph_desc, ©_swap_desc, ©_set_desc, diff --git a/libvips/conversion/im_copy_file.c b/libvips/conversion/im_copy_file.c new file mode 100644 index 00000000..0a3763ce --- /dev/null +++ b/libvips/conversion/im_copy_file.c @@ -0,0 +1,81 @@ +/* copy an image to a file and then copy that to the output ... a disc cache + * + * 16/10/09 + * - from im_system() + */ + +/* + + This file is part of VIPS. + + VIPS is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + */ + +/* + + These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk + + */ + +#ifdef HAVE_CONFIG_H +#include +#endif /*HAVE_CONFIG_H*/ +#include + +#include +#include + +#ifdef HAVE_UNISTD_H +#include +#endif /*HAVE_UNISTD_H*/ +#include +#include +#include + +#include + +#ifdef WITH_DMALLOC +#include +#endif /*WITH_DMALLOC*/ + +/* Copy an image to a disc file, then copy again to output. If the image is + * already a disc file, just copy straight through. + */ +int +im_copy_file( IMAGE *in, IMAGE *out ) +{ + if( !im_isfile( in ) ) { + IMAGE *disc; + + if( !(disc = im__open_temp()) ) + return( -1 ); + if( im_add_close_callback( out, + (im_callback_fn) im_close, disc, NULL ) ) { + im_close( disc ); + return( -1 ); + } + + if( im_copy( in, disc ) || + im_copy( disc, out ) ) + return( -1 ); + } + else { + if( im_copy( in, out ) ) + return( -1 ); + } + + return( 0 ); +} diff --git a/libvips/conversion/im_system.c b/libvips/conversion/im_system.c index 8ee0f852..638ca9c8 100644 --- a/libvips/conversion/im_system.c +++ b/libvips/conversion/im_system.c @@ -89,41 +89,6 @@ popenf( const char *fmt, const char *mode, ... ) 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 * command on it, unlink (if we copied), return stdout from command. */ @@ -135,7 +100,7 @@ im_system( IMAGE *im, const char *cmd, char **out ) if( !im_isfile( im ) ) { IMAGE *disc; - if( !(disc = system_temp()) ) + if( !(disc = im__open_temp()) ) return( -1 ); if( im_copy( im, disc ) || im_system( disc, cmd, out ) ) { diff --git a/libvips/include/vips/proto.h b/libvips/include/vips/proto.h index acaa24eb..3ffa1a76 100644 --- a/libvips/include/vips/proto.h +++ b/libvips/include/vips/proto.h @@ -264,6 +264,7 @@ int im_copy_morph( IMAGE *, IMAGE *, int, int, int ); int im_copy( IMAGE *, IMAGE * ); int im_copy_swap( IMAGE *in, IMAGE *out ); int im_copy_from( IMAGE *in, IMAGE *out, im_arch_type architecture ); +int im_copy_file( IMAGE *in, IMAGE *out ); int im_extract_band( IMAGE *in, IMAGE *out, int band ); int im_extract_bands( IMAGE *in, IMAGE *out, int band, int nbands ); int im_extract_area( IMAGE *in, IMAGE *out, int x, int y, int w, int h ); diff --git a/libvips/include/vips/util.h b/libvips/include/vips/util.h index b631bfb5..bde0bccf 100644 --- a/libvips/include/vips/util.h +++ b/libvips/include/vips/util.h @@ -252,6 +252,8 @@ int im_ispoweroftwo( int p ); int im_isvips( const char *filename ); int im_amiMSBfirst( void ); +IMAGE *im__open_temp( void ); + #ifdef __cplusplus } #endif /*__cplusplus*/ diff --git a/libvips/iofuncs/util.c b/libvips/iofuncs/util.c index 873808e3..74eefaa1 100644 --- a/libvips/iofuncs/util.c +++ b/libvips/iofuncs/util.c @@ -1477,3 +1477,41 @@ im_amiMSBfirst( void ) return( 1 ); } +/* Make a disc IMAGE which will be automatically unlinked on im_close(). + */ +IMAGE * +im__open_temp( void ) +{ + const char *tmpd; + char *name; + int fd; + IMAGE *disc; + + if( !(tmpd = g_getenv( "TMPDIR" )) ) + tmpd = "/tmp"; + name = g_build_filename( tmpd, "vips_XXXXXX.v", NULL ); + + if( (fd = g_mkstemp( name )) == -1 ) { + im_error( "tempfile", + _( "unable to make temp file %s" ), name ); + g_free( name ); + return( NULL ); + } + close( fd ); + + if( !(disc = im_open( name, "w" )) ) { + unlink( name ); + g_free( name ); + return( NULL ); + } + g_free( name ); + + if( im_add_close_callback( disc, + (im_callback_fn) unlink, disc->filename, NULL ) ) { + im_close( disc ); + unlink( name ); + } + + return( disc ); +} +