vips_magickload() only reads 1st image in sequence

with an @all_frames option to get them all, thanks acrispino
This commit is contained in:
John Cupitt 2013-06-11 14:29:43 +01:00
parent e15f02161e
commit c77386f3cf
6 changed files with 46 additions and 13 deletions

View File

@ -3,6 +3,7 @@
- oops, VImage.PIL_mode_from_vips() failed for CMYK, thanks Alessandro - oops, VImage.PIL_mode_from_vips() failed for CMYK, thanks Alessandro
- fix no-pango build - fix no-pango build
- add im_vips2dz(): run the deepzoom writer from vips7 - 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 12/3/13 started 7.33.0
- vipsthumbnail lets you specify the sharpening mask - vipsthumbnail lets you specify the sharpening mask

View File

@ -48,7 +48,9 @@ int
im_magick2vips( const char *filename, IMAGE *out ) im_magick2vips( const char *filename, IMAGE *out )
{ {
#ifdef HAVE_MAGICK #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 #else
vips_error( "im_magick2vips", vips_error( "im_magick2vips",
_( "no libMagick support in your libvips" ) ); _( "no libMagick support in your libvips" ) );

View File

@ -1668,6 +1668,10 @@ vips_foreign_operation_init( void )
* @out: decompressed image * @out: decompressed image
* @...: %NULL-terminated list of optional named arguments * @...: %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 in an image using libMagick, the ImageMagick library. This library can
* read more than 80 file formats, including SVG, BMP, EPS, DICOM and many * read more than 80 file formats, including SVG, BMP, EPS, DICOM and many
* others. * others.
@ -1678,6 +1682,9 @@ vips_foreign_operation_init( void )
* The reader should also work with most versions of GraphicsMagick. See the * The reader should also work with most versions of GraphicsMagick. See the
* "--with-magickpackage" configure option. * "--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(). * See also: vips_image_new_from_file().
* *
* Returns: 0 on success, -1 on error. * Returns: 0 on success, -1 on error.

View File

@ -35,8 +35,10 @@
extern "C" { extern "C" {
#endif /*__cplusplus*/ #endif /*__cplusplus*/
int vips__magick_read( const char *filename, VipsImage *out ); int vips__magick_read( const char *filename,
int vips__magick_read_header( const char *filename, VipsImage *out ); VipsImage *out, gboolean all_frames );
int vips__magick_read_header( const char *filename,
VipsImage *out, gboolean all_frames );
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -68,8 +68,8 @@
*/ */
/* Turn on debugging output. /* Turn on debugging output.
#define DEBUG
*/ */
#define DEBUG
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include <config.h> #include <config.h>
@ -106,6 +106,7 @@
typedef struct _Read { typedef struct _Read {
char *filename; char *filename;
VipsImage *im; VipsImage *im;
gboolean all_frames;
Image *image; Image *image;
ImageInfo *image_info; ImageInfo *image_info;
@ -138,7 +139,7 @@ read_destroy( VipsImage *im, Read *read )
} }
static Read * static Read *
read_new( const char *filename, VipsImage *im ) read_new( const char *filename, VipsImage *im, gboolean all_frames )
{ {
Read *read; Read *read;
static int inited = 0; static int inited = 0;
@ -155,6 +156,7 @@ read_new( const char *filename, VipsImage *im )
if( !(read = VIPS_NEW( im, Read )) ) if( !(read = VIPS_NEW( im, Read )) )
return( NULL ); return( NULL );
read->filename = g_strdup( filename ); read->filename = g_strdup( filename );
read->all_frames = all_frames;
read->im = im; read->im = im;
read->image = NULL; read->image = NULL;
read->image_info = CloneImageInfo( NULL ); read->image_info = CloneImageInfo( NULL );
@ -245,6 +247,8 @@ parse_header( Read *read )
IsMonochromeImage( image, &image->exception ) ); IsMonochromeImage( image, &image->exception ) );
printf( "IsOpaqueImage() = %d\n", printf( "IsOpaqueImage() = %d\n",
IsOpaqueImage( image, &image->exception ) ); IsOpaqueImage( image, &image->exception ) );
printf( "image->columns = %zd\n", image->columns );
printf( "image->rows = %zd\n", image->rows );
#endif /*DEBUG*/ #endif /*DEBUG*/
im->Xsize = image->columns; im->Xsize = image->columns;
@ -405,6 +409,15 @@ parse_header( Read *read )
*/ */
read->n_frames = 1; 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. /* Record frame pointers.
*/ */
im->Ysize *= read->n_frames; im->Ysize *= read->n_frames;
@ -632,7 +645,7 @@ magick_fill_region( VipsRegion *out,
} }
int int
vips__magick_read( const char *filename, VipsImage *out ) vips__magick_read( const char *filename, VipsImage *out, gboolean all_frames )
{ {
Read *read; Read *read;
@ -640,7 +653,7 @@ vips__magick_read( const char *filename, VipsImage *out )
printf( "magick2vips: vips__magick_read: %s\n", filename ); printf( "magick2vips: vips__magick_read: %s\n", filename );
#endif /*DEBUG*/ #endif /*DEBUG*/
if( !(read = read_new( filename, out )) ) if( !(read = read_new( filename, out, all_frames )) )
return( -1 ); return( -1 );
#ifdef HAVE_SETIMAGEOPTION #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 * http://www.imagemagick.org/discourse-server/viewtopic.php?f=1&t=20017
*/ */
int int
vips__magick_read_header( const char *filename, VipsImage *im ) vips__magick_read_header( const char *filename, VipsImage *im,
gboolean all_frames )
{ {
Read *read; Read *read;
@ -689,7 +703,7 @@ vips__magick_read_header( const char *filename, VipsImage *im )
printf( "vips__magick_read_header: %s\n", filename ); printf( "vips__magick_read_header: %s\n", filename );
#endif /*DEBUG*/ #endif /*DEBUG*/
if( !(read = read_new( filename, im )) ) if( !(read = read_new( filename, im, all_frames )) )
return( -1 ); return( -1 );
#ifdef DEBUG #ifdef DEBUG

View File

@ -57,9 +57,8 @@
typedef struct _VipsForeignLoadMagick { typedef struct _VipsForeignLoadMagick {
VipsForeignLoad parent_object; VipsForeignLoad parent_object;
/* Filename for load.
*/
char *filename; char *filename;
gboolean all_frames;
} VipsForeignLoadMagick; } VipsForeignLoadMagick;
@ -74,7 +73,7 @@ ismagick( const char *filename )
VipsImage *t; VipsImage *t;
t = vips_image_new(); t = vips_image_new();
if( vips__magick_read_header( filename, t ) ) { if( vips__magick_read_header( filename, t, FALSE ) ) {
g_object_unref( t ); g_object_unref( t );
return( FALSE ); return( FALSE );
} }
@ -111,7 +110,8 @@ vips_foreign_load_magick_header( VipsForeignLoad *load )
{ {
VipsForeignLoadMagick *magick = (VipsForeignLoadMagick *) 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( -1 );
return( 0 ); return( 0 );
@ -149,6 +149,13 @@ vips_foreign_load_magick_class_init( VipsForeignLoadMagickClass *class )
VIPS_ARGUMENT_REQUIRED_INPUT, VIPS_ARGUMENT_REQUIRED_INPUT,
G_STRUCT_OFFSET( VipsForeignLoadMagick, filename ), G_STRUCT_OFFSET( VipsForeignLoadMagick, filename ),
NULL ); 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 static void