pngload supports restart after minimise
plus a test
This commit is contained in:
parent
3eca1ff3ee
commit
2d374c3114
@ -985,15 +985,10 @@ vips__rad_israd( const char *filename )
|
||||
}
|
||||
|
||||
static void
|
||||
read_minimise( VipsObject *object, Read *read )
|
||||
read_destroy( VipsObject *object, Read *read )
|
||||
{
|
||||
VIPS_FREEF( buffer_free, read->buffer );
|
||||
VIPS_FREEF( fclose, read->fin );
|
||||
}
|
||||
|
||||
static void
|
||||
read_destroy( VipsObject *object, Read *read )
|
||||
{
|
||||
VIPS_FREE( read->filename );
|
||||
}
|
||||
|
||||
@ -1024,8 +1019,6 @@ read_new( const char *filename, VipsImage *out )
|
||||
read->prims[3][1] = CIE_y_w;
|
||||
read->buffer = NULL;
|
||||
|
||||
g_signal_connect( out, "minimise",
|
||||
G_CALLBACK( read_minimise ), read );
|
||||
g_signal_connect( out, "close",
|
||||
G_CALLBACK( read_destroy ), read );
|
||||
|
||||
|
@ -73,6 +73,8 @@
|
||||
* - support xmp read/write
|
||||
* 20/4/19
|
||||
* - allow huge xmp metadata
|
||||
* 7/10/19
|
||||
* - restart after minimise
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -167,9 +169,11 @@ typedef struct {
|
||||
png_infop pInfo;
|
||||
png_bytep *row_pointer;
|
||||
|
||||
/* For FILE input.
|
||||
/* For FILE input. If we close and reopen, save the ftell point in
|
||||
* seek_position.
|
||||
*/
|
||||
FILE *fp;
|
||||
long seek_position;
|
||||
|
||||
/* For memory input.
|
||||
*/
|
||||
@ -179,12 +183,42 @@ typedef struct {
|
||||
|
||||
} Read;
|
||||
|
||||
/* This can be called many times.
|
||||
*/
|
||||
static void
|
||||
read_close_input( Read *read )
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf( "read_close_input:\n" );
|
||||
#endif /*DEBUG*/
|
||||
|
||||
if( read->fp ) {
|
||||
read->seek_position = ftell( read->fp );
|
||||
VIPS_FREEF( fclose, read->fp );
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
read_open_input( Read *read )
|
||||
{
|
||||
if( !read->fp &&
|
||||
read->name ) {
|
||||
if( !(read->fp =
|
||||
vips__file_open_read( read->name, NULL, FALSE )) )
|
||||
return( -1 );
|
||||
if( read->seek_position != -1 )
|
||||
fseek( read->fp, read->seek_position, SEEK_SET );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/* Can be called many times.
|
||||
*/
|
||||
static void
|
||||
read_destroy( Read *read )
|
||||
{
|
||||
VIPS_FREEF( fclose, read->fp );
|
||||
read_close_input( read );
|
||||
if( read->pPng )
|
||||
png_destroy_read_struct( &read->pPng, &read->pInfo, NULL );
|
||||
VIPS_FREE( read->row_pointer );
|
||||
@ -199,17 +233,7 @@ read_close_cb( VipsImage *out, Read *read )
|
||||
static void
|
||||
read_minimise_cb( VipsImage *out, Read *read )
|
||||
{
|
||||
/* Catch errors from png_read_end(). This can fail on a truncated
|
||||
* file.
|
||||
*/
|
||||
if( read->pPng ) {
|
||||
/* Catch and ignore error returns from png_read_end().
|
||||
*/
|
||||
if( !setjmp( png_jmpbuf( read->pPng ) ) )
|
||||
png_read_end( read->pPng, NULL );
|
||||
}
|
||||
|
||||
read_destroy( read );
|
||||
read_close_input( read );
|
||||
}
|
||||
|
||||
static Read *
|
||||
@ -228,6 +252,7 @@ read_new( VipsImage *out, gboolean fail )
|
||||
read->pInfo = NULL;
|
||||
read->row_pointer = NULL;
|
||||
read->fp = NULL;
|
||||
read->seek_position = -1;
|
||||
read->buffer = NULL;
|
||||
read->length = 0;
|
||||
read->read_pos = 0;
|
||||
@ -289,7 +314,7 @@ read_new_filename( VipsImage *out, const char *name, gboolean fail )
|
||||
|
||||
read->name = vips_strdup( VIPS_OBJECT( out ), name );
|
||||
|
||||
if( !(read->fp = vips__file_open_read( name, NULL, FALSE )) )
|
||||
if( read_open_input( read ) )
|
||||
return( NULL );
|
||||
|
||||
/* Catch PNG errors from png_read_info().
|
||||
@ -553,12 +578,11 @@ vips__png_header( const char *name, VipsImage *out )
|
||||
Read *read;
|
||||
|
||||
if( !(read = read_new_filename( out, name, TRUE )) ||
|
||||
png2vips_header( read, out ) )
|
||||
png2vips_header( read, out ) ) {
|
||||
read_close_input( read );
|
||||
return( -1 );
|
||||
|
||||
/* Just a header read: we can free the read early and save an fd.
|
||||
*/
|
||||
read_destroy( read );
|
||||
}
|
||||
read_close_input( read );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
@ -621,6 +645,9 @@ png2vips_generate( VipsRegion *or,
|
||||
g_assert( r->height == VIPS_MIN( VIPS__FATSTRIP_HEIGHT,
|
||||
or->im->Ysize - r->top ) );
|
||||
|
||||
if( read_open_input( read ) )
|
||||
return( -1 );
|
||||
|
||||
/* And check that y_pos is correct. It should be, since we are inside
|
||||
* a vips_sequential().
|
||||
*/
|
||||
@ -738,6 +765,10 @@ png2vips_image( Read *read, VipsImage *out )
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
/* _generate will reopen.
|
||||
*/
|
||||
read_close_input( read );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
|
@ -22,3 +22,7 @@ fi
|
||||
if test_supported pdfload; then
|
||||
./test_descriptors $test_images/ISO_12233-reschart.pdf
|
||||
fi
|
||||
|
||||
if test_supported pngload; then
|
||||
./test_descriptors $test_images/sample.png
|
||||
fi
|
||||
|
Loading…
Reference in New Issue
Block a user