istiff tests first dir rather than magic number
We were testing for TIFF by checking the magic number at the head of the file. However, formats like ARW are TIFF-like without being TIFF, and will not load with tiffload. Instead, try reading the whole of the first directory. This is enough to stop tiffload trying to load files where it will simply fail immediately, and make libvips fall back to eg. imagemagick. see https://github.com/libvips/libvips/issues/1304
This commit is contained in:
parent
dc16f1253a
commit
eb6c803481
@ -4,6 +4,8 @@
|
||||
- more consistent behaviour for page-height metadata
|
||||
- fix for composite with many small images and some combinations of blend modes
|
||||
- fix memleak in tiff pyr save to memory [scossu]
|
||||
- istiff attempts to read the first directory rather than just testing the
|
||||
magic number [przemyslawpluta]
|
||||
|
||||
21/9/18 started 8.8.0
|
||||
- much faster smartcrop [lovell]
|
||||
|
@ -186,6 +186,9 @@
|
||||
* 28/3/19 omira-sch
|
||||
* - better buffer sizing
|
||||
* - ban chroma-subsampled, non-jpg compressed images
|
||||
* 7/6/19
|
||||
* - istiff reads the first directory rather than just testing the magic
|
||||
* number, so it ignores more TIFF-like, but not TIFF images
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -2424,11 +2427,13 @@ vips__tiff_read_header( const char *filename, VipsImage *out,
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
gboolean
|
||||
vips__istifftiled( const char *filename )
|
||||
typedef gboolean (*TiffPropertyFn)( TIFF *tif );
|
||||
|
||||
static gboolean
|
||||
vips__testtiff( const char *filename, TiffPropertyFn fn )
|
||||
{
|
||||
TIFF *tif;
|
||||
gboolean tiled;
|
||||
gboolean property;
|
||||
|
||||
vips__tiff_init();
|
||||
|
||||
@ -2436,37 +2441,59 @@ vips__istifftiled( const char *filename )
|
||||
vips_error_clear();
|
||||
return( FALSE );
|
||||
}
|
||||
tiled = TIFFIsTiled( tif );
|
||||
|
||||
property = fn ? fn( tif ) : TRUE;
|
||||
|
||||
TIFFClose( tif );
|
||||
|
||||
return( tiled );
|
||||
return( property );
|
||||
}
|
||||
|
||||
gboolean
|
||||
vips__testtiff_buffer( const void *buf, size_t len, TiffPropertyFn fn )
|
||||
{
|
||||
VipsImage *im;
|
||||
TIFF *tif;
|
||||
gboolean property;
|
||||
|
||||
vips__tiff_init();
|
||||
|
||||
im = vips_image_new();
|
||||
|
||||
if( !(tif = vips__tiff_openin_buffer( im, buf, len )) ) {
|
||||
g_object_unref( im );
|
||||
vips_error_clear();
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
property = fn ? fn( tif ) : TRUE;
|
||||
|
||||
TIFFClose( tif );
|
||||
g_object_unref( im );
|
||||
|
||||
return( property );
|
||||
}
|
||||
|
||||
gboolean
|
||||
vips__istifftiled( const char *filename )
|
||||
{
|
||||
return( vips__testtiff( filename, TIFFIsTiled ) );
|
||||
}
|
||||
|
||||
/* We test for TIFF by trying to read the first directory. We could just test
|
||||
* the magic number, but many formats (eg. ARW) use a TIFF-like container and
|
||||
* we don't want to open those with vips tiffload.
|
||||
*/
|
||||
gboolean
|
||||
vips__istiff( const char *filename )
|
||||
{
|
||||
return( vips__testtiff( filename, NULL ) );
|
||||
}
|
||||
|
||||
gboolean
|
||||
vips__istiff_buffer( const void *buf, size_t len )
|
||||
{
|
||||
char *str = (char *) buf;
|
||||
|
||||
if( len >= 4 &&
|
||||
((str[0] == 'M' && str[1] == 'M' &&
|
||||
str[2] == '\0' && (str[3] == '*' || str[3] == '+')) ||
|
||||
(str[0] == 'I' && str[1] == 'I' &&
|
||||
(str[2] == '*' || str[2] == '+') && str[3] == '\0')) )
|
||||
return( TRUE );
|
||||
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
gboolean
|
||||
vips__istiff( const char *filename )
|
||||
{
|
||||
unsigned char buf[4];
|
||||
|
||||
if( vips__get_bytes( filename, buf, 4 ) == 4 &&
|
||||
vips__istiff_buffer( buf, 4 ) )
|
||||
return( TRUE );
|
||||
|
||||
return( FALSE );
|
||||
return( vips__testtiff_buffer( buf, len, NULL ) );
|
||||
}
|
||||
|
||||
int
|
||||
|
Loading…
x
Reference in New Issue
Block a user