much faster ismagick

We used to Ping files to see if IM would load them, but this can be
extremely slow for file formats like ARW.

Instead, use GetImageMagick() ... it just checks the magic number.
This commit is contained in:
John Cupitt 2019-06-08 16:47:40 +01:00
parent eb6c803481
commit bb75535151
5 changed files with 33 additions and 56 deletions

View File

@ -6,6 +6,7 @@
- fix memleak in tiff pyr save to memory [scossu]
- istiff attempts to read the first directory rather than just testing the
magic number [przemyslawpluta]
- much faster ismagick() [jcupitt]
21/9/18 started 8.8.0
- much faster smartcrop [lovell]

View File

@ -641,4 +641,16 @@ magick_set_magick_profile( Image *image,
return( 0 );
}
/* Does a few bytes look like a file IM can handle?
*/
gboolean
magick_ismagick( const unsigned char *buf, size_t length )
{
char format[MagickPathExtent];
magick_genesis();
return( GetImageMagick( buf, length, format ) );
}
#endif /*HAVE_MAGICK*/

View File

@ -84,4 +84,6 @@ int magick_set_vips_profile( VipsImage *im, Image *image );
int magick_set_magick_profile( Image *image,
VipsImage *im, ExceptionInfo *exception );
gboolean magick_ismagick( const unsigned char *buf, size_t length );
#endif /*HAVE_MAGICK6*/

View File

@ -757,26 +757,15 @@ G_DEFINE_TYPE( VipsForeignLoadMagick7File, vips_foreign_load_magick7_file,
static gboolean
ismagick7( const char *filename )
{
Image *image;
ImageInfo *image_info;
ExceptionInfo *exception;
int result;
magick_genesis();
/* Horribly slow :-(
/* Fetch the first 100 bytes. Hopefully that'll be enough.
*/
image_info = CloneImageInfo( NULL );
exception = magick_acquire_exception();
vips_strncpy( image_info->filename, filename, MagickPathExtent );
magick_sniff_file( image_info, filename );
image = PingImage( image_info, exception );
result = image != NULL;
VIPS_FREEF( DestroyImageList, image );
VIPS_FREEF( DestroyImageInfo, image_info );
VIPS_FREEF( magick_destroy_exception, exception );
unsigned char buf[100];
return( result );
/* Files shorter than 100 bytes will leave nonsense at the end of buf,
* but it shouldn't matter.
*/
return( vips__get_bytes( filename, buf, 100 ) &&
magick_ismagick( buf, 100 ) );
}
static int
@ -860,25 +849,7 @@ G_DEFINE_TYPE( VipsForeignLoadMagick7Buffer, vips_foreign_load_magick7_buffer,
static gboolean
vips_foreign_load_magick7_buffer_is_a_buffer( const void *buf, size_t len )
{
Image *image;
ImageInfo *image_info;
ExceptionInfo *exception;
int result;
magick_genesis();
/* Horribly slow :-(
*/
image_info = CloneImageInfo( NULL );
exception = magick_acquire_exception();
magick_sniff_bytes( image_info, buf, len );
image = PingBlob( image_info, buf, len, exception );
result = image != NULL;
VIPS_FREEF( DestroyImageList, image );
VIPS_FREEF( DestroyImageInfo, image_info );
VIPS_FREEF( magick_destroy_exception, exception );
return( result );
return( magick_ismagick( (const unsigned char *) buf, len ) );
}
static int

View File

@ -63,6 +63,7 @@
#ifdef HAVE_MAGICK6
#include "pforeign.h"
#include "magick.h"
typedef struct _VipsForeignLoadMagick {
VipsForeignLoad parent_object;
@ -172,16 +173,15 @@ G_DEFINE_TYPE( VipsForeignLoadMagickFile, vips_foreign_load_magick_file,
static gboolean
ismagick( const char *filename )
{
VipsImage *t;
int result;
/* Fetch the first 100 bytes. Hopefully that'll be enough.
*/
unsigned char buf[100];
t = vips_image_new();
vips_error_freeze();
result = vips__magick_read_header( filename, t, NULL, 0, 1 );
g_object_unref( t );
vips_error_thaw();
return( result == 0 );
/* Files shorter than 100 bytes will leave nonsense at the end of buf,
* but it shouldn't matter.
*/
return( vips__get_bytes( filename, buf, 100 ) &&
magick_ismagick( buf, 100 ) );
}
/* Unfortunately, libMagick does not support header-only reads very well. See
@ -258,16 +258,7 @@ G_DEFINE_TYPE( VipsForeignLoadMagickBuffer, vips_foreign_load_magick_buffer,
static gboolean
vips_foreign_load_magick_buffer_is_a_buffer( const void *buf, size_t len )
{
VipsImage *t;
int result;
t = vips_image_new();
vips_error_freeze();
result = vips__magick_read_buffer_header( buf, len, t, NULL, 0, 1 );
g_object_unref( t );
vips_error_thaw();
return( result == 0 );
return( magick_ismagick( (const unsigned char *) buf, len ) );
}
/* Unfortunately, libMagick does not support header-only reads very well. See