make file format readers close fds early

we were using two fds per open image, now we just use one

jpg, magick, tiff, png
This commit is contained in:
John Cupitt 2015-02-26 14:09:01 +00:00
parent cdeec4a912
commit fc5a4a917a
6 changed files with 61 additions and 7 deletions

View File

@ -8,6 +8,7 @@
- add magicload_buffer() [mcuelenaere] - add magicload_buffer() [mcuelenaere]
- added test_foreign.py, plus more test images - added test_foreign.py, plus more test images
- rewritten tiff writer is about 3 - 4x faster at making pyramids - rewritten tiff writer is about 3 - 4x faster at making pyramids
- jpg, magick, png, tiff readers now use only 1 fd per input image
6/2/15 started 7.42.3 6/2/15 started 7.42.3
- bump version for back-compat ABI change - bump version for back-compat ABI change

1
TODO
View File

@ -1,3 +1,4 @@
- support orientation tag in tiff images - support orientation tag in tiff images
see see

View File

@ -64,6 +64,9 @@
* 20/1/15 * 20/1/15
* - don't call jpeg_finish_decompress(), all it does is read and check * - don't call jpeg_finish_decompress(), all it does is read and check
* the tail of the file * the tail of the file
* 26/2/15
* - close the jpeg read down early for a header read ... this saves an
* fd during jpg read, handy for large numbers of input images
*/ */
/* /*
@ -166,6 +169,8 @@ typedef struct _ReadJpeg {
gboolean autorotate; gboolean autorotate;
} ReadJpeg; } ReadJpeg;
/* This can be called many times.
*/
static int static int
readjpeg_free( ReadJpeg *jpeg ) readjpeg_free( ReadJpeg *jpeg )
{ {
@ -199,7 +204,7 @@ readjpeg_free( ReadJpeg *jpeg )
VIPS_FREE( jpeg->filename ); VIPS_FREE( jpeg->filename );
jpeg->eman.fp = NULL; jpeg->eman.fp = NULL;
/* I don't think this can fail. /* I don't think this can fail. It's harmless to call many times.
*/ */
jpeg_destroy_decompress( &jpeg->cinfo ); jpeg_destroy_decompress( &jpeg->cinfo );
@ -1111,6 +1116,12 @@ vips__jpeg_read_file( const char *filename, VipsImage *out,
if( vips__jpeg_read( jpeg, out, header_only ) ) if( vips__jpeg_read( jpeg, out, header_only ) )
return( -1 ); return( -1 );
/* We can kill off the decompress early if this is just a header read.
* This saves an fd during read.
*/
if( header_only )
readjpeg_free( jpeg );
return( 0 ); return( 0 );
} }

View File

@ -44,6 +44,9 @@
* - add @density option * - add @density option
* 16/2/15 mcuelenaere * 16/2/15 mcuelenaere
* - add blob read * - add blob read
* 26/2/15
* - close the read down early for a header read ... this saves an
* fd during file read, handy for large numbers of input images
*/ */
/* /*
@ -127,11 +130,13 @@ typedef struct _Read {
GMutex *lock; GMutex *lock;
} Read; } Read;
static int /* Can be called many times.
read_destroy( VipsImage *im, Read *read ) */
static void
read_free( Read *read )
{ {
#ifdef DEBUG #ifdef DEBUG
printf( "magick2vips: read_destroy: %s\n", read->filename ); printf( "magick2vips: read_free: %s\n", read->filename );
#endif /*DEBUG*/ #endif /*DEBUG*/
VIPS_FREE( read->filename ); VIPS_FREE( read->filename );
@ -140,6 +145,14 @@ read_destroy( VipsImage *im, Read *read )
VIPS_FREE( read->frames ); VIPS_FREE( read->frames );
DestroyExceptionInfo( &read->exception ); DestroyExceptionInfo( &read->exception );
VIPS_FREEF( vips_g_mutex_free, read->lock ); VIPS_FREEF( vips_g_mutex_free, read->lock );
}
/* Can be called many times.
*/
static int
read_close( VipsImage *im, Read *read )
{
read_free( read );
return( 0 ); return( 0 );
} }
@ -173,7 +186,7 @@ read_new( const char *filename, VipsImage *im, gboolean all_frames,
read->frame_height = 0; read->frame_height = 0;
read->lock = vips_g_mutex_new(); read->lock = vips_g_mutex_new();
g_signal_connect( im, "close", G_CALLBACK( read_destroy ), read ); g_signal_connect( im, "close", G_CALLBACK( read_close ), read );
if( !read->image_info ) if( !read->image_info )
return( NULL ); return( NULL );
@ -741,6 +754,10 @@ vips__magick_read_header( const char *filename, VipsImage *im,
return( -1 ); return( -1 );
} }
/* Just a header read: we can free the read early and save an fd.
*/
read_free( read );
return( 0 ); return( 0 );
} }

View File

@ -154,6 +154,9 @@
* - read any XMP metadata * - read any XMP metadata
* 19/1/15 * 19/1/15
* - try to handle 8-bit colormaps * - try to handle 8-bit colormaps
* 26/2/15
* - close the read down early for a header read ... this saves an
* fd during file read, handy for large numbers of input images
*/ */
/* /*
@ -1678,12 +1681,20 @@ read_stripwise( ReadTiff *rtiff, VipsImage *out )
return( 0 ); return( 0 );
} }
/* Can be called many times.
*/
static void static void
readtiff_destroy( VipsObject *object, ReadTiff *rtiff ) readtiff_free( ReadTiff *rtiff )
{ {
VIPS_FREEF( TIFFClose, rtiff->tiff ); VIPS_FREEF( TIFFClose, rtiff->tiff );
} }
static void
readtiff_close( VipsObject *object, ReadTiff *rtiff )
{
readtiff_free( rtiff );
}
static ReadTiff * static ReadTiff *
readtiff_new( VipsImage *out, int page, gboolean readbehind ) readtiff_new( VipsImage *out, int page, gboolean readbehind )
{ {
@ -1710,7 +1721,7 @@ readtiff_new( VipsImage *out, int page, gboolean readbehind )
rtiff->contig_buf = NULL; rtiff->contig_buf = NULL;
g_signal_connect( out, "close", g_signal_connect( out, "close",
G_CALLBACK( readtiff_destroy ), rtiff ); G_CALLBACK( readtiff_close ), rtiff );
if( rtiff->page < 0 || rtiff->page > 1000000 ) { if( rtiff->page < 0 || rtiff->page > 1000000 ) {
vips_error( "tiff2vips", _( "bad page number %d" ), vips_error( "tiff2vips", _( "bad page number %d" ),
@ -1918,6 +1929,10 @@ vips__tiff_read_header( const char *filename, VipsImage *out, int page )
if( parse_header( rtiff, out ) ) if( parse_header( rtiff, out ) )
return( -1 ); return( -1 );
/* Just a header read: we can free the tiff read early and save an fd.
*/
readtiff_free( rtiff );
return( 0 ); return( 0 );
} }

View File

@ -52,6 +52,9 @@
* - don't check profiles, helps with libpng >=1.6.11 * - don't check profiles, helps with libpng >=1.6.11
* 27/10/14 Lovell * 27/10/14 Lovell
* - add @filter option * - add @filter option
* 26/2/15
* - close the read down early for a header read ... this saves an
* fd during file read, handy for large numbers of input images
*/ */
/* /*
@ -150,6 +153,8 @@ typedef struct {
} Read; } Read;
/* Can be called many times.
*/
static void static void
read_destroy( Read *read ) read_destroy( Read *read )
{ {
@ -423,6 +428,10 @@ vips__png_header( const char *name, VipsImage *out )
png2vips_header( read, out ) ) png2vips_header( read, out ) )
return( -1 ); return( -1 );
/* Just a header read: we can free the read early and save an fd.
*/
read_destroy( read );
return( 0 ); return( 0 );
} }