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

View File

@ -641,4 +641,16 @@ magick_set_magick_profile( Image *image,
return( 0 ); 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*/ #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, int magick_set_magick_profile( Image *image,
VipsImage *im, ExceptionInfo *exception ); VipsImage *im, ExceptionInfo *exception );
gboolean magick_ismagick( const unsigned char *buf, size_t length );
#endif /*HAVE_MAGICK6*/ #endif /*HAVE_MAGICK6*/

View File

@ -757,26 +757,15 @@ G_DEFINE_TYPE( VipsForeignLoadMagick7File, vips_foreign_load_magick7_file,
static gboolean static gboolean
ismagick7( const char *filename ) ismagick7( const char *filename )
{ {
Image *image; /* Fetch the first 100 bytes. Hopefully that'll be enough.
ImageInfo *image_info;
ExceptionInfo *exception;
int result;
magick_genesis();
/* Horribly slow :-(
*/ */
image_info = CloneImageInfo( NULL ); unsigned char buf[100];
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 );
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 static int
@ -860,25 +849,7 @@ G_DEFINE_TYPE( VipsForeignLoadMagick7Buffer, vips_foreign_load_magick7_buffer,
static gboolean static gboolean
vips_foreign_load_magick7_buffer_is_a_buffer( const void *buf, size_t len ) vips_foreign_load_magick7_buffer_is_a_buffer( const void *buf, size_t len )
{ {
Image *image; return( magick_ismagick( (const unsigned char *) buf, len ) );
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 );
} }
static int static int

View File

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