add format option to magickload
Some magick coders (eg. ICO) don't sniff the filetype from the data, so when you try to load from a string, imagemagick is unable to pick the right decode path. Add a @format option so callers can hint the filetype. see https://github.com/jcupitt/pyvips/issues/39
This commit is contained in:
parent
a40382fe50
commit
c410dc2db8
|
@ -15,6 +15,7 @@
|
|||
- use O_TMPFILE, if available [Alexander--]
|
||||
- set "interlaced=1" for interlaced JPG and PNG images
|
||||
- add PDFium PDF loader
|
||||
- add @format option to magickload
|
||||
|
||||
12/3/18 started 8.6.4
|
||||
- better fitting of fonts with overhanging edges [Adrià]
|
||||
|
|
|
@ -216,7 +216,7 @@ magick_genesis_cb( void *client )
|
|||
printf( "magick_genesis_cb:\n" );
|
||||
#endif /*DEBUG*/
|
||||
|
||||
#ifdef HAVE_MAGICKCOREGENESIS
|
||||
#if defined(HAVE_MAGICKCOREGENESIS) || defined(HAVE_MAGICK7)
|
||||
MagickCoreGenesis( vips_get_argv0(), MagickFalse );
|
||||
#else /*!HAVE_MAGICKCOREGENESIS*/
|
||||
InitializeMagick( "" );
|
||||
|
|
|
@ -55,6 +55,8 @@
|
|||
* - remove @all_frames, add @n
|
||||
* 23/2/17
|
||||
* - try using GetImageChannelDepth() instead of ->depth
|
||||
* 24/4/18
|
||||
* - add format hint
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -172,7 +174,7 @@ read_close( VipsImage *im, Read *read )
|
|||
|
||||
static Read *
|
||||
read_new( const char *filename, VipsImage *im,
|
||||
const char *density, int page, int n )
|
||||
const char *format, const char *density, int page, int n )
|
||||
{
|
||||
Read *read;
|
||||
static int inited = 0;
|
||||
|
@ -215,6 +217,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 );
|
||||
|
||||
/* Canvas resolution for rendering vector formats like SVG.
|
||||
*/
|
||||
VIPS_SETSTR( read->image_info->density, density );
|
||||
|
@ -743,7 +751,8 @@ magick_fill_region( VipsRegion *out,
|
|||
|
||||
int
|
||||
vips__magick_read( const char *filename,
|
||||
VipsImage *out, const char *density, int page, int n )
|
||||
VipsImage *out, const char *format, const char *density,
|
||||
int page, int n )
|
||||
{
|
||||
Read *read;
|
||||
|
||||
|
@ -751,7 +760,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, format, density, page, n )) )
|
||||
return( -1 );
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -782,7 +791,8 @@ vips__magick_read( const char *filename,
|
|||
*/
|
||||
int
|
||||
vips__magick_read_header( const char *filename,
|
||||
VipsImage *out, const char *density, int page, int n )
|
||||
VipsImage *out, const char *format, const char *density,
|
||||
int page, int n )
|
||||
{
|
||||
Read *read;
|
||||
|
||||
|
@ -790,7 +800,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, format, density, page, n )) )
|
||||
return( -1 );
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -824,7 +834,8 @@ vips__magick_read_header( const char *filename,
|
|||
|
||||
int
|
||||
vips__magick_read_buffer( const void *buf, const size_t len,
|
||||
VipsImage *out, const char *density, int page, int n )
|
||||
VipsImage *out, const char *format, const char *density,
|
||||
int page, int n )
|
||||
{
|
||||
Read *read;
|
||||
|
||||
|
@ -832,7 +843,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, format, density, page, n )) )
|
||||
return( -1 );
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -859,7 +870,8 @@ vips__magick_read_buffer( const void *buf, const size_t len,
|
|||
|
||||
int
|
||||
vips__magick_read_buffer_header( const void *buf, const size_t len,
|
||||
VipsImage *out, const char *density, int page, int n )
|
||||
VipsImage *out, const char *format, const char *density,
|
||||
int page, int n )
|
||||
{
|
||||
Read *read;
|
||||
|
||||
|
@ -867,7 +879,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, format, 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/4/18
|
||||
* - add format hint
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -56,6 +58,8 @@
|
|||
|
||||
#include <MagickCore/MagickCore.h>
|
||||
|
||||
#include "magick.h"
|
||||
|
||||
typedef struct _VipsForeignLoadMagick7 {
|
||||
VipsForeignLoad parent_object;
|
||||
|
||||
|
@ -63,6 +67,7 @@ typedef struct _VipsForeignLoadMagick7 {
|
|||
*/
|
||||
gboolean all_frames;
|
||||
|
||||
char *format; /* Format hint */
|
||||
char *density; /* Load at this resolution */
|
||||
int page; /* Load this page (frame) */
|
||||
int n; /* Load this many pages */
|
||||
|
@ -307,7 +312,7 @@ vips_foreign_load_magick7_build( VipsObject *object )
|
|||
printf( "vips_foreign_load_magick7_build: %p\n", object );
|
||||
#endif /*DEBUG*/
|
||||
|
||||
vips_foreign_load_magick7_genesis();
|
||||
magick_genesis();
|
||||
|
||||
magick7->image_info = CloneImageInfo( NULL );
|
||||
magick7->exception = AcquireExceptionInfo();
|
||||
|
@ -319,6 +324,12 @@ 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 );
|
||||
|
@ -377,12 +388,12 @@ vips_foreign_load_magick7_class_init( VipsForeignLoadMagick7Class *class )
|
|||
vips_foreign_load_magick7_get_flags_filename;
|
||||
load_class->get_flags = vips_foreign_load_magick7_get_flags;
|
||||
|
||||
VIPS_ARG_BOOL( class, "all_frames", 3,
|
||||
_( "all_frames" ),
|
||||
_( "Read all frames from an image" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT | VIPS_ARGUMENT_DEPRECATED,
|
||||
G_STRUCT_OFFSET( VipsForeignLoadMagick7, all_frames ),
|
||||
FALSE );
|
||||
VIPS_ARG_STRING( class, "format", 3,
|
||||
_( "Format" ),
|
||||
_( "Image format hint" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsForeignLoadMagick7, format ),
|
||||
NULL );
|
||||
|
||||
VIPS_ARG_STRING( class, "density", 4,
|
||||
_( "Density" ),
|
||||
|
@ -405,6 +416,13 @@ vips_foreign_load_magick7_class_init( VipsForeignLoadMagick7Class *class )
|
|||
G_STRUCT_OFFSET( VipsForeignLoadMagick7, n ),
|
||||
-1, 100000, 1 );
|
||||
|
||||
VIPS_ARG_BOOL( class, "all_frames", 7,
|
||||
_( "all_frames" ),
|
||||
_( "Read all frames from an image" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT | VIPS_ARGUMENT_DEPRECATED,
|
||||
G_STRUCT_OFFSET( VipsForeignLoadMagick7, all_frames ),
|
||||
FALSE );
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -579,7 +597,7 @@ vips_foreign_load_magick7_parse( VipsForeignLoadMagick7 *magick7,
|
|||
return( 0 );
|
||||
}
|
||||
|
||||
/* We don't bother with GetPixelReadMask((), assume it's everywhere. Don't
|
||||
/* We don't bother with GetPixelReadMask(), assume it's everywhere. Don't
|
||||
* bother with traits, assume taht's always update.
|
||||
*
|
||||
* We do skip index channels. Palette images add extra index channels
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
* - add @n, deprecate @all_frames (just sets n = -1)
|
||||
* 8/9/17
|
||||
* - don't cache magickload
|
||||
* 24/4/18
|
||||
* - add format hint
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -72,6 +74,7 @@ typedef struct _VipsForeignLoadMagick {
|
|||
gboolean all_frames;
|
||||
|
||||
char *density; /* Load at this resolution */
|
||||
char *format; /* Load format hint */
|
||||
int page; /* Load this page (frame) */
|
||||
int n; /* Load this many pages */
|
||||
|
||||
|
@ -122,28 +125,35 @@ vips_foreign_load_magick_class_init( VipsForeignLoadMagickClass *class )
|
|||
vips_foreign_load_magick_get_flags_filename;
|
||||
load_class->get_flags = vips_foreign_load_magick_get_flags;
|
||||
|
||||
VIPS_ARG_BOOL( class, "all_frames", 3,
|
||||
VIPS_ARG_STRING( class, "format", 3,
|
||||
_( "Format" ),
|
||||
_( "Image format hint" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsForeignLoadMagick, format ),
|
||||
NULL );
|
||||
|
||||
VIPS_ARG_BOOL( class, "all_frames", 4,
|
||||
_( "all_frames" ),
|
||||
_( "Read all frames from an image" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT | VIPS_ARGUMENT_DEPRECATED,
|
||||
G_STRUCT_OFFSET( VipsForeignLoadMagick, all_frames ),
|
||||
FALSE );
|
||||
|
||||
VIPS_ARG_STRING( class, "density", 4,
|
||||
VIPS_ARG_STRING( class, "density", 5,
|
||||
_( "Density" ),
|
||||
_( "Canvas resolution for rendering vector formats like SVG" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsForeignLoadMagick, density ),
|
||||
NULL );
|
||||
|
||||
VIPS_ARG_INT( class, "page", 5,
|
||||
VIPS_ARG_INT( class, "page", 6,
|
||||
_( "Page" ),
|
||||
_( "Load this page from the file" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsForeignLoadMagick, page ),
|
||||
0, 100000, 0 );
|
||||
|
||||
VIPS_ARG_INT( class, "n", 6,
|
||||
VIPS_ARG_INT( class, "n", 7,
|
||||
_( "n" ),
|
||||
_( "Load this many pages" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
|
@ -177,7 +187,7 @@ ismagick( const char *filename )
|
|||
|
||||
t = vips_image_new();
|
||||
vips_error_freeze();
|
||||
result = vips__magick_read_header( filename, t, NULL, 0, 1 );
|
||||
result = vips__magick_read_header( filename, t, NULL, NULL, 0, 1 );
|
||||
g_object_unref( t );
|
||||
vips_error_thaw();
|
||||
|
||||
|
@ -202,7 +212,8 @@ vips_foreign_load_magick_file_header( VipsForeignLoad *load )
|
|||
magick->n = -1;
|
||||
|
||||
if( vips__magick_read( magick_file->filename,
|
||||
load->out, magick->density, magick->page, magick->n ) )
|
||||
load->out, magick->format, magick->density,
|
||||
magick->page, magick->n ) )
|
||||
return( -1 );
|
||||
|
||||
VIPS_SETSTR( load->out->filename, magick_file->filename );
|
||||
|
@ -262,7 +273,8 @@ vips_foreign_load_magick_buffer_is_a_buffer( const void *buf, size_t len )
|
|||
|
||||
t = vips_image_new();
|
||||
vips_error_freeze();
|
||||
result = vips__magick_read_buffer_header( buf, len, t, NULL, 0, 1 );
|
||||
result = vips__magick_read_buffer_header( buf, len, t,
|
||||
NULL, NULL, 0, 1 );
|
||||
g_object_unref( t );
|
||||
vips_error_thaw();
|
||||
|
||||
|
@ -288,7 +300,8 @@ vips_foreign_load_magick_buffer_header( VipsForeignLoad *load )
|
|||
|
||||
if( vips__magick_read_buffer(
|
||||
magick_buffer->buf->data, magick_buffer->buf->length,
|
||||
load->out, magick->density, magick->page, magick->n ) )
|
||||
load->out, magick->format, magick->density, magick->page,
|
||||
magick->n ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
|
@ -338,6 +351,7 @@ vips_foreign_load_magick_buffer_init( VipsForeignLoadMagickBuffer *buffer )
|
|||
*
|
||||
* Optional arguments:
|
||||
*
|
||||
* * @format: string, format hint, eg. "JPG"
|
||||
* * @page: %gint, load from this page
|
||||
* * @n: %gint, load this many pages
|
||||
* * @density: string, canvas resolution for rendering vector formats like SVG
|
||||
|
@ -352,6 +366,10 @@ vips_foreign_load_magick_buffer_init( VipsForeignLoadMagickBuffer *buffer )
|
|||
* The reader should also work with most versions of GraphicsMagick. See the
|
||||
* "--with-magickpackage" configure option.
|
||||
*
|
||||
* The file format is usually guessed from the filename suffix. You can
|
||||
* override this with @format -- for example `"ICO"` selects Windows icon
|
||||
* format. See the ImageMagick documentation for a list of format names.
|
||||
*
|
||||
* Normally it will only load the first image in a many-image sequence (such
|
||||
* as a GIF or a PDF). Use @page and @n to set the start page and number of
|
||||
* pages to load. Set @n to -1 to load all pages from @page onwards.
|
||||
|
@ -387,6 +405,7 @@ vips_magickload( const char *filename, VipsImage **out, ... )
|
|||
*
|
||||
* Optional arguments:
|
||||
*
|
||||
* * @format: string, format hint, eg. "JPG"
|
||||
* * @page: %gint, load from this page
|
||||
* * @n: %gint, load this many pages
|
||||
* * @density: string, canvas resolution for rendering vector formats like SVG
|
||||
|
@ -394,6 +413,12 @@ vips_magickload( const char *filename, VipsImage **out, ... )
|
|||
* Read an image memory block using libMagick into a VIPS image. Exactly as
|
||||
* vips_magickload(), but read from a memory source.
|
||||
*
|
||||
* The file format is usually guessed from the buffer contents, but this does
|
||||
* not work for all image formats. You can
|
||||
* set the format explicitly with @format -- for example `"ICO"` selects
|
||||
* Windows icon
|
||||
* format. See the ImageMagick documentation for a list of format names.
|
||||
*
|
||||
* You must not free the buffer while @out is active. The
|
||||
* #VipsObject::postclose signal on @out is a good place to free.
|
||||
*
|
||||
|
|
|
@ -123,14 +123,18 @@ int vips__fits_read( const char *filename, VipsImage *out );
|
|||
int vips__fits_write( VipsImage *in, const char *filename );
|
||||
|
||||
int vips__magick_read( const char *filename,
|
||||
VipsImage *out, const char *density, int page, int n );
|
||||
VipsImage *out, const char *format, const char *density,
|
||||
int page, int n );
|
||||
int vips__magick_read_header( const char *filename,
|
||||
VipsImage *out, const char *density, int page, int n );
|
||||
VipsImage *out, const char *format, const char *density,
|
||||
int page, int n );
|
||||
|
||||
int vips__magick_read_buffer( const void *buf, const size_t len,
|
||||
VipsImage *out, const char *density, int page, int n );
|
||||
VipsImage *out, const char *format, const char *density,
|
||||
int page, int n );
|
||||
int vips__magick_read_buffer_header( const void *buf, const size_t len,
|
||||
VipsImage *out, const char *density, int page, int n );
|
||||
VipsImage *out, const char *format, const char *density,
|
||||
int page, int n );
|
||||
|
||||
extern const char *vips__mat_suffs[];
|
||||
|
||||
|
@ -162,12 +166,14 @@ int vips__jpeg_write_file( VipsImage *in,
|
|||
const char *filename, int Q, const char *profile,
|
||||
gboolean optimize_coding, gboolean progressive, gboolean strip,
|
||||
gboolean no_subsample, gboolean trellis_quant,
|
||||
gboolean overshoot_deringing, gboolean optimize_scans, int quant_table );
|
||||
gboolean overshoot_deringing, gboolean optimize_scans,
|
||||
int quant_table );
|
||||
int vips__jpeg_write_buffer( VipsImage *in,
|
||||
void **obuf, size_t *olen, int Q, const char *profile,
|
||||
gboolean optimize_coding, gboolean progressive, gboolean strip,
|
||||
gboolean no_subsample, gboolean trellis_quant,
|
||||
gboolean overshoot_deringing, gboolean optimize_scans, int quant_table );
|
||||
gboolean overshoot_deringing, gboolean optimize_scans,
|
||||
int quant_table );
|
||||
|
||||
int vips__isjpeg_buffer( const void *buf, size_t len );
|
||||
int vips__isjpeg( const char *filename );
|
||||
|
|
Loading…
Reference in New Issue