From c77386f3cf52f390de82bcff71b4f3ec09c68822 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 11 Jun 2013 14:29:43 +0100 Subject: [PATCH] vips_magickload() only reads 1st image in sequence with an @all_frames option to get them all, thanks acrispino --- ChangeLog | 1 + libvips/deprecated/im_magick2vips.c | 4 +++- libvips/foreign/foreign.c | 7 +++++++ libvips/foreign/magick.h | 6 ++++-- libvips/foreign/magick2vips.c | 26 ++++++++++++++++++++------ libvips/foreign/magickload.c | 15 +++++++++++---- 6 files changed, 46 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0ae47303..58d0a731 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,7 @@ - oops, VImage.PIL_mode_from_vips() failed for CMYK, thanks Alessandro - fix no-pango build - add im_vips2dz(): run the deepzoom writer from vips7 +- vips_magickload() has an option to read all images in a sequence 12/3/13 started 7.33.0 - vipsthumbnail lets you specify the sharpening mask diff --git a/libvips/deprecated/im_magick2vips.c b/libvips/deprecated/im_magick2vips.c index ae41fc2e..183d0efe 100644 --- a/libvips/deprecated/im_magick2vips.c +++ b/libvips/deprecated/im_magick2vips.c @@ -48,7 +48,9 @@ int im_magick2vips( const char *filename, IMAGE *out ) { #ifdef HAVE_MAGICK - return( vips__magick_read( filename, out ) ); + /* Old behaviour was always to read all frames. + */ + return( vips__magick_read( filename, out, TRUE ) ); #else vips_error( "im_magick2vips", _( "no libMagick support in your libvips" ) ); diff --git a/libvips/foreign/foreign.c b/libvips/foreign/foreign.c index b649defb..47f248ec 100644 --- a/libvips/foreign/foreign.c +++ b/libvips/foreign/foreign.c @@ -1668,6 +1668,10 @@ vips_foreign_operation_init( void ) * @out: decompressed image * @...: %NULL-terminated list of optional named arguments * + * Optional arguments: + * + * @all_frames: load all frames in sequence + * * Read in an image using libMagick, the ImageMagick library. This library can * read more than 80 file formats, including SVG, BMP, EPS, DICOM and many * others. @@ -1678,6 +1682,9 @@ vips_foreign_operation_init( void ) * The reader should also work with most versions of GraphicsMagick. See the * "--with-magickpackage" configure option. * + * Normally it will only load the first image in a many-image sequence (such + * as a GIF). Set @all_frames to true to read the whole image sequence. + * * See also: vips_image_new_from_file(). * * Returns: 0 on success, -1 on error. diff --git a/libvips/foreign/magick.h b/libvips/foreign/magick.h index 37a56bec..df67db0a 100644 --- a/libvips/foreign/magick.h +++ b/libvips/foreign/magick.h @@ -35,8 +35,10 @@ extern "C" { #endif /*__cplusplus*/ -int vips__magick_read( const char *filename, VipsImage *out ); -int vips__magick_read_header( const char *filename, VipsImage *out ); +int vips__magick_read( const char *filename, + VipsImage *out, gboolean all_frames ); +int vips__magick_read_header( const char *filename, + VipsImage *out, gboolean all_frames ); #ifdef __cplusplus } diff --git a/libvips/foreign/magick2vips.c b/libvips/foreign/magick2vips.c index 1ae4eeb5..b6c0d973 100644 --- a/libvips/foreign/magick2vips.c +++ b/libvips/foreign/magick2vips.c @@ -68,8 +68,8 @@ */ /* Turn on debugging output. -#define DEBUG */ +#define DEBUG #ifdef HAVE_CONFIG_H #include @@ -106,6 +106,7 @@ typedef struct _Read { char *filename; VipsImage *im; + gboolean all_frames; Image *image; ImageInfo *image_info; @@ -138,7 +139,7 @@ read_destroy( VipsImage *im, Read *read ) } static Read * -read_new( const char *filename, VipsImage *im ) +read_new( const char *filename, VipsImage *im, gboolean all_frames ) { Read *read; static int inited = 0; @@ -155,6 +156,7 @@ read_new( const char *filename, VipsImage *im ) if( !(read = VIPS_NEW( im, Read )) ) return( NULL ); read->filename = g_strdup( filename ); + read->all_frames = all_frames; read->im = im; read->image = NULL; read->image_info = CloneImageInfo( NULL ); @@ -245,6 +247,8 @@ parse_header( Read *read ) IsMonochromeImage( image, &image->exception ) ); printf( "IsOpaqueImage() = %d\n", IsOpaqueImage( image, &image->exception ) ); + printf( "image->columns = %zd\n", image->columns ); + printf( "image->rows = %zd\n", image->rows ); #endif /*DEBUG*/ im->Xsize = image->columns; @@ -405,6 +409,15 @@ parse_header( Read *read ) */ read->n_frames = 1; +#ifdef DEBUG + printf( "image has %d frames\n", read->n_frames ); +#endif /*DEBUG*/ + + /* If all_frames is off, just get the first one. + */ + if( !read->all_frames ) + read->n_frames = 1; + /* Record frame pointers. */ im->Ysize *= read->n_frames; @@ -632,7 +645,7 @@ magick_fill_region( VipsRegion *out, } int -vips__magick_read( const char *filename, VipsImage *out ) +vips__magick_read( const char *filename, VipsImage *out, gboolean all_frames ) { Read *read; @@ -640,7 +653,7 @@ vips__magick_read( const char *filename, VipsImage *out ) printf( "magick2vips: vips__magick_read: %s\n", filename ); #endif /*DEBUG*/ - if( !(read = read_new( filename, out )) ) + if( !(read = read_new( filename, out, all_frames )) ) return( -1 ); #ifdef HAVE_SETIMAGEOPTION @@ -681,7 +694,8 @@ vips__magick_read( const char *filename, VipsImage *out ) * http://www.imagemagick.org/discourse-server/viewtopic.php?f=1&t=20017 */ int -vips__magick_read_header( const char *filename, VipsImage *im ) +vips__magick_read_header( const char *filename, VipsImage *im, + gboolean all_frames ) { Read *read; @@ -689,7 +703,7 @@ vips__magick_read_header( const char *filename, VipsImage *im ) printf( "vips__magick_read_header: %s\n", filename ); #endif /*DEBUG*/ - if( !(read = read_new( filename, im )) ) + if( !(read = read_new( filename, im, all_frames )) ) return( -1 ); #ifdef DEBUG diff --git a/libvips/foreign/magickload.c b/libvips/foreign/magickload.c index 2ad1aca4..d491781f 100644 --- a/libvips/foreign/magickload.c +++ b/libvips/foreign/magickload.c @@ -57,9 +57,8 @@ typedef struct _VipsForeignLoadMagick { VipsForeignLoad parent_object; - /* Filename for load. - */ char *filename; + gboolean all_frames; } VipsForeignLoadMagick; @@ -74,7 +73,7 @@ ismagick( const char *filename ) VipsImage *t; t = vips_image_new(); - if( vips__magick_read_header( filename, t ) ) { + if( vips__magick_read_header( filename, t, FALSE ) ) { g_object_unref( t ); return( FALSE ); } @@ -111,7 +110,8 @@ vips_foreign_load_magick_header( VipsForeignLoad *load ) { VipsForeignLoadMagick *magick = (VipsForeignLoadMagick *) load; - if( vips__magick_read( magick->filename, load->out ) ) + if( vips__magick_read( magick->filename, + load->out, magick->all_frames ) ) return( -1 ); return( 0 ); @@ -149,6 +149,13 @@ vips_foreign_load_magick_class_init( VipsForeignLoadMagickClass *class ) VIPS_ARGUMENT_REQUIRED_INPUT, G_STRUCT_OFFSET( VipsForeignLoadMagick, filename ), NULL ); + + VIPS_ARG_BOOL( class, "all_frames", 3, + _( "all_frames" ), + _( "Read all frames from an image" ), + VIPS_ARGUMENT_OPTIONAL_INPUT, + G_STRUCT_OFFSET( VipsForeignLoadMagick, all_frames ), + FALSE ); } static void