add sniffing framework to magickload
though it only spots ICO for now see https://github.com/jcupitt/pyvips/issues/39
This commit is contained in:
parent
72f589764a
commit
e89dac20bb
@ -35,6 +35,7 @@
|
||||
- paste in the test suite from pyvips
|
||||
- get EXIF tag names from tag plus ifd [@Nan619]
|
||||
- escape ASCII control characters in XML
|
||||
- magickload now sniffs some file types itself
|
||||
|
||||
12/3/18 started 8.6.4
|
||||
- better fitting of fonts with overhanging edges [Adrià]
|
||||
|
@ -1,6 +1,9 @@
|
||||
/* Common functions for interfacing with ImageMagick.
|
||||
*
|
||||
* 22/12/17 dlemstra
|
||||
*
|
||||
* 24/7/18
|
||||
* - add the sniffer
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -238,6 +241,46 @@ magick_set_image_option( ImageInfo *image_info,
|
||||
#endif /*HAVE_SETIMAGEOPTION*/
|
||||
}
|
||||
|
||||
/* ImageMagick can't detect some formats, like ICO, by examining the contents --
|
||||
* ico.c simply does not have a recogniser.
|
||||
*
|
||||
* For these formats, do the detection ourselves.
|
||||
*
|
||||
* Set image_info->magick if we spot one of the things we can spot.
|
||||
*/
|
||||
static const char *
|
||||
magick_sniff( const unsigned char *bytes, size_t length )
|
||||
{
|
||||
if( length >= 4 &&
|
||||
bytes[0] == 0 &&
|
||||
bytes[1] == 0 &&
|
||||
bytes[2] == 1 &&
|
||||
bytes[3] == 0 )
|
||||
return( "ICO" );
|
||||
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
void
|
||||
magick_sniff_bytes( ImageInfo *image_info,
|
||||
const unsigned char *bytes, size_t length )
|
||||
{
|
||||
const char *format;
|
||||
|
||||
if( (format = magick_sniff( bytes, length )) )
|
||||
vips_strncpy( image_info->magick, format, MaxTextExtent );
|
||||
}
|
||||
|
||||
void
|
||||
magick_sniff_file( ImageInfo *image_info, const char *filename )
|
||||
{
|
||||
unsigned char bytes[256];
|
||||
size_t length;
|
||||
|
||||
if( (length = vips__get_bytes( filename, bytes, 256 )) >= 4 )
|
||||
magick_sniff_bytes( image_info, bytes, 256 );
|
||||
}
|
||||
|
||||
void
|
||||
magick_vips_error( const char *domain, ExceptionInfo *exception )
|
||||
{
|
||||
|
@ -59,6 +59,9 @@ void magick_set_number_scenes( ImageInfo *image_info,
|
||||
int scene, int number_scenes );
|
||||
|
||||
void magick_inherit_exception( ExceptionInfo *exception, Image *image );
|
||||
void magick_sniff_bytes( ImageInfo *image_info,
|
||||
const unsigned char *bytes, size_t length );
|
||||
void magick_sniff_file( ImageInfo *image_info, const char *filename );
|
||||
void magick_vips_error( const char *domain, ExceptionInfo *exception );
|
||||
|
||||
void magick_genesis( void );
|
||||
|
@ -57,6 +57,8 @@
|
||||
* - try using GetImageChannelDepth() instead of ->depth
|
||||
* 25/5/18
|
||||
* - don't use Ping, it's too unreliable
|
||||
* 24/7/18
|
||||
* - sniff extra filetypes
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -128,6 +130,8 @@
|
||||
typedef struct _Read {
|
||||
char *filename;
|
||||
VipsImage *im;
|
||||
const void *buf;
|
||||
size_t len;
|
||||
int page;
|
||||
int n;
|
||||
|
||||
@ -182,7 +186,8 @@ read_close( VipsImage *im, Read *read )
|
||||
|
||||
static Read *
|
||||
read_new( const char *filename, VipsImage *im,
|
||||
const char *density, int page, int n )
|
||||
const void *buf, const size_t len,
|
||||
const char *density, int page, int n )
|
||||
{
|
||||
Read *read;
|
||||
|
||||
@ -197,6 +202,8 @@ read_new( const char *filename, VipsImage *im,
|
||||
if( !(read = VIPS_NEW( im, Read )) )
|
||||
return( NULL );
|
||||
read->filename = filename ? g_strdup( filename ) : NULL;
|
||||
read->buf = buf;
|
||||
read->len = len;
|
||||
read->page = page;
|
||||
read->n = n;
|
||||
read->im = im;
|
||||
@ -218,15 +225,12 @@ read_new( const char *filename, VipsImage *im,
|
||||
vips_strncpy( read->image_info->filename,
|
||||
filename, MaxTextExtent );
|
||||
|
||||
/* The file format hint, eg. "ICO".
|
||||
*
|
||||
if( format )
|
||||
vips_strncpy( read->image_info->magick,
|
||||
format, MaxTextExtent );
|
||||
*
|
||||
/* Any extra file format detection.
|
||||
*/
|
||||
printf( "magick2vips: insert format stuff here\n" );
|
||||
|
||||
if( filename )
|
||||
magick_sniff_file( read->image_info, filename );
|
||||
if( buf )
|
||||
magick_sniff_bytes( read->image_info, buf, len );
|
||||
|
||||
/* Canvas resolution for rendering vector formats like SVG.
|
||||
*/
|
||||
@ -754,7 +758,7 @@ vips__magick_read( const char *filename,
|
||||
printf( "magick2vips: vips__magick_read: %s\n", filename );
|
||||
#endif /*DEBUG*/
|
||||
|
||||
if( !(read = read_new( filename, out, density, page, n )) )
|
||||
if( !(read = read_new( filename, out, NULL, n, density, page, n )) )
|
||||
return( -1 );
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -788,7 +792,7 @@ vips__magick_read_header( const char *filename,
|
||||
printf( "vips__magick_read_header: %s\n", filename );
|
||||
#endif /*DEBUG*/
|
||||
|
||||
if( !(read = read_new( filename, out, density, page, n )) )
|
||||
if( !(read = read_new( filename, out, NULL, 0, density, page, n )) )
|
||||
return( -1 );
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -833,7 +837,7 @@ vips__magick_read_buffer( const void *buf, const size_t len,
|
||||
printf( "magick2vips: vips__magick_read_buffer: %p %zu\n", buf, len );
|
||||
#endif /*DEBUG*/
|
||||
|
||||
if( !(read = read_new( NULL, out, density, page, n )) )
|
||||
if( !(read = read_new( NULL, out, buf, len, density, page, n )) )
|
||||
return( -1 );
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -867,7 +871,7 @@ vips__magick_read_buffer_header( const void *buf, const size_t len,
|
||||
printf( "vips__magick_read_buffer_header: %p %zu\n", buf, len );
|
||||
#endif /*DEBUG*/
|
||||
|
||||
if( !(read = read_new( NULL, out, density, page, n )) )
|
||||
if( !(read = read_new( NULL, out, buf, len, density, page, n )) )
|
||||
return( -1 );
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -4,6 +4,8 @@
|
||||
* - from magickload
|
||||
* 25/11/16
|
||||
* - add @n, deprecate @all_frames (just sets n = -1)
|
||||
* 24/7/18
|
||||
* - sniff extra filetypes
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -305,14 +307,6 @@ vips_foreign_load_magick7_build( VipsObject *object )
|
||||
if( magick7->all_frames )
|
||||
magick7->n = -1;
|
||||
|
||||
/* The file format hint, eg. "ICO".
|
||||
*
|
||||
if( magick7->format )
|
||||
vips_strncpy( magick7->image_info->magick,
|
||||
magick7->format, MaxTextExtent );
|
||||
*
|
||||
*/
|
||||
|
||||
/* Canvas resolution for rendering vector formats like SVG.
|
||||
*/
|
||||
VIPS_SETSTR( magick7->image_info->density, magick7->density );
|
||||
@ -768,6 +762,7 @@ ismagick7( const char *filename )
|
||||
image_info = CloneImageInfo( NULL );
|
||||
exception = AcquireExceptionInfo();
|
||||
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 );
|
||||
@ -790,6 +785,8 @@ vips_foreign_load_magick7_file_header( VipsForeignLoad *load )
|
||||
vips_strncpy( magick7->image_info->filename, file->filename,
|
||||
MagickPathExtent );
|
||||
|
||||
magick_sniff_file( magick7->image_info, file->filename );
|
||||
|
||||
/* It would be great if we could PingImage and just read the header,
|
||||
* but sadly many IM coders do not support ping. The critical one for
|
||||
* us is DICOM.
|
||||
@ -867,6 +864,7 @@ vips_foreign_load_magick7_buffer_is_a_buffer( const void *buf, size_t len )
|
||||
*/
|
||||
image_info = CloneImageInfo( NULL );
|
||||
exception = AcquireExceptionInfo();
|
||||
magick_sniff_bytes( image_info, buf, len );
|
||||
image = PingBlob( image_info, buf, len, exception );
|
||||
result = image != NULL;
|
||||
VIPS_FREEF( DestroyImageList, image );
|
||||
@ -893,6 +891,8 @@ vips_foreign_load_magick7_buffer_header( VipsForeignLoad *load )
|
||||
*
|
||||
* We have to read the whole image in _header.
|
||||
*/
|
||||
magick_sniff_bytes( magick7->image_info,
|
||||
magick7_buffer->buf->data, magick7_buffer->buf->length );
|
||||
magick7->image = BlobToImage( magick7->image_info,
|
||||
magick7_buffer->buf->data, magick7_buffer->buf->length,
|
||||
magick7->exception );
|
||||
|
Loading…
Reference in New Issue
Block a user