diff --git a/ChangeLog b/ChangeLog index c1a05d31..0fc484d3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -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] diff --git a/libvips/foreign/magick.c b/libvips/foreign/magick.c index 5119b7ed..367a4ba5 100644 --- a/libvips/foreign/magick.c +++ b/libvips/foreign/magick.c @@ -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*/ diff --git a/libvips/foreign/magick.h b/libvips/foreign/magick.h index 8993a31e..9c9be67d 100644 --- a/libvips/foreign/magick.h +++ b/libvips/foreign/magick.h @@ -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*/ diff --git a/libvips/foreign/magick7load.c b/libvips/foreign/magick7load.c index 6592ff74..5c0ceb76 100644 --- a/libvips/foreign/magick7load.c +++ b/libvips/foreign/magick7load.c @@ -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 diff --git a/libvips/foreign/magickload.c b/libvips/foreign/magickload.c index 9643805e..a1215a30 100644 --- a/libvips/foreign/magickload.c +++ b/libvips/foreign/magickload.c @@ -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