fix a crash in the tiff reader
some tiffs have HUGE values for RowsPerStrip ... clip these down to avoid confusing later bits of vips also, a better error msg for non-contig images
This commit is contained in:
parent
1ee48e4cd6
commit
75a68100bd
@ -5,6 +5,8 @@
|
||||
- make jpeg pyramids work with tiff4
|
||||
- tiff loader always offers THINSTRIP (thanks Diuming)
|
||||
- add "nocache" operation flag, set for sequential load (thanks Diuming)
|
||||
- fix a crash in the tiff reader for huge values of RowsPerStrip (thanks
|
||||
Nicolas)
|
||||
|
||||
19/4/12 started 7.28.5
|
||||
- ifthenelse blend mode was broken
|
||||
|
@ -931,6 +931,8 @@ vips_foreign_load_init( VipsForeignLoad *load )
|
||||
load->disc = TRUE;
|
||||
}
|
||||
|
||||
/* Make a sequential cache for a file reader.
|
||||
*/
|
||||
int
|
||||
vips_foreign_tilecache( VipsImage *in, VipsImage **out, int strip_height )
|
||||
{
|
||||
|
@ -131,6 +131,10 @@
|
||||
* 3/6/12
|
||||
* - always offer THINSTRIP ... later stages can ask for something more
|
||||
* relaxed if they wish
|
||||
* 7/6/12
|
||||
* - clip rows_per_strip down to image height to avoid overflows for huge
|
||||
* values (thanks Nicolas)
|
||||
* - better error msg for not PLANARCONFIG_CONTIG images
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -253,29 +257,6 @@ tfexists( TIFF *tif, ttag_t tag )
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/* Test a uint16 field. Field must be defined and equal to the value.
|
||||
*/
|
||||
static int
|
||||
tfequals( TIFF *tif, ttag_t tag, uint16 val )
|
||||
{
|
||||
uint16 fld;
|
||||
|
||||
if( !TIFFGetFieldDefaulted( tif, tag, &fld ) ) {
|
||||
vips_error( "tiff2vips",
|
||||
_( "required field %d missing" ), tag );
|
||||
return( 0 );
|
||||
}
|
||||
if( fld != val ) {
|
||||
vips_error( "tiff2vips", _( "required field %d=%d, not %d" ),
|
||||
tag, fld, val );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/* All ok.
|
||||
*/
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
/* Get a uint32 field.
|
||||
*/
|
||||
static int
|
||||
@ -307,9 +288,26 @@ tfget16( TIFF *tif, ttag_t tag, int *out )
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/* All ok.
|
||||
*/
|
||||
*out = fld;
|
||||
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
/* Test a uint16 field. Field must be defined and equal to the value.
|
||||
*/
|
||||
static int
|
||||
tfequals( TIFF *tif, ttag_t tag, uint16 val )
|
||||
{
|
||||
int v;
|
||||
|
||||
if( !tfget16( tif, tag, &v ) )
|
||||
return( 0 );
|
||||
if( v != val ) {
|
||||
vips_error( "tiff2vips",
|
||||
_( "required field %d = %d, not %d" ), tag, v, val );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
@ -900,10 +898,16 @@ parse_header( ReadTiff *rtiff, VipsImage *out )
|
||||
|
||||
/* Ban separate planes, too annoying.
|
||||
*/
|
||||
if( tfexists( rtiff->tiff, TIFFTAG_PLANARCONFIG ) &&
|
||||
!tfequals( rtiff->tiff,
|
||||
TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG ) )
|
||||
return( -1 );
|
||||
if( tfexists( rtiff->tiff, TIFFTAG_PLANARCONFIG ) ) {
|
||||
int v;
|
||||
|
||||
tfget16( rtiff->tiff, TIFFTAG_PLANARCONFIG, &v );
|
||||
if( v != PLANARCONFIG_CONTIG ) {
|
||||
vips_error( "tiff2vips",
|
||||
"%s", _( "not a PLANARCONFIG_CONTIG image" ) );
|
||||
return( -1 );
|
||||
}
|
||||
}
|
||||
|
||||
/* Always need dimensions.
|
||||
*/
|
||||
@ -1347,8 +1351,8 @@ tiff2vips_stripwise_generate( VipsRegion *or,
|
||||
/* If necessary, unpack to destination.
|
||||
*/
|
||||
if( !rtiff->memcpy ) {
|
||||
int height = VIPS_MIN( rtiff->rows_per_strip,
|
||||
or->im->Ysize - (r->top + y) );
|
||||
int height = VIPS_MIN( VIPS_MIN( rtiff->rows_per_strip,
|
||||
or->im->Ysize - (r->top + y) ), r->height );
|
||||
int z;
|
||||
|
||||
for( z = 0; z < height; z++ ) {
|
||||
@ -1398,6 +1402,11 @@ read_stripwise( ReadTiff *rtiff, VipsImage *out )
|
||||
rtiff->strip_size = TIFFStripSize( rtiff->tiff );
|
||||
rtiff->number_of_strips = TIFFNumberOfStrips( rtiff->tiff );
|
||||
|
||||
/* rows_per_strip can be 2**32-1, meaning the whole image. Clip this
|
||||
* down to ysize to avoid confusing vips.
|
||||
*/
|
||||
rtiff->rows_per_strip = VIPS_MIN( rtiff->rows_per_strip, t[0]->Ysize );
|
||||
|
||||
#ifdef DEBUG
|
||||
printf( "read_stripwise: rows_per_strip = %u\n",
|
||||
rtiff->rows_per_strip );
|
||||
|
Loading…
Reference in New Issue
Block a user