diff --git a/ChangeLog b/ChangeLog index 0b2e13c7..46a834f7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,7 @@ - add shift option to cast - sRGB2scRGB and scRGB2sRGB scale 16-bit alpha to and from 8-bit - tiff pyramid writer no longer copies base image +- add magicload_buffer() [mcuelenaere] 6/2/15 started 7.42.3 - bump version for back-compat ABI change diff --git a/libvips/foreign/foreign.c b/libvips/foreign/foreign.c index eaa4e0ce..f0113880 100644 --- a/libvips/foreign/foreign.c +++ b/libvips/foreign/foreign.c @@ -1674,7 +1674,7 @@ vips_magickload( const char *filename, VipsImage **out, ... ) * vips_magickload_buffer: * @buf: memory area to load * @len: size of memory area - * @out: decompressed image + * @out: image to write * @...: %NULL-terminated list of optional named arguments * * Optional arguments: diff --git a/libvips/foreign/magick2vips.c b/libvips/foreign/magick2vips.c index ecb00d2d..9dffc9ea 100644 --- a/libvips/foreign/magick2vips.c +++ b/libvips/foreign/magick2vips.c @@ -42,6 +42,8 @@ * - add @all_frames option, off by default * 4/12/14 Lovell * - add @density option + * 16/2/15 mcuelenaere + * - add blob read */ /* @@ -176,9 +178,9 @@ read_new( const char *filename, VipsImage *im, gboolean all_frames, if( !read->image_info ) return( NULL ); - if (filename) { - vips_strncpy( read->image_info->filename, filename, MaxTextExtent ); - } + if( filename ) + vips_strncpy( read->image_info->filename, + filename, MaxTextExtent ); /* Canvas resolution for rendering vector formats like SVG. */ @@ -770,7 +772,8 @@ vips__magick_read_buffer( const void *buf, const size_t len, VipsImage *out, printf( "magick2vips: calling BlobToImage() ...\n" ); #endif /*DEBUG*/ - read->image = BlobToImage( read->image_info, buf, len, &read->exception ); + read->image = BlobToImage( read->image_info, + buf, len, &read->exception ); if( !read->image ) { vips_error( "magick2vips", _( "unable to read buffer\n" "libMagick error: %s %s" ), @@ -815,7 +818,8 @@ vips__magick_read_buffer_header( const void *buf, const size_t len, if( parse_header( read ) ) return( -1 ); - if( im->Xsize <= 0 || im->Ysize <= 0 ) { + if( im->Xsize <= 0 || + im->Ysize <= 0 ) { vips_error( "magick2vips", "%s", _( "bad image size" ) ); return( -1 ); } diff --git a/libvips/foreign/magickload.c b/libvips/foreign/magickload.c index 9064e2f9..d2ec6ddb 100644 --- a/libvips/foreign/magickload.c +++ b/libvips/foreign/magickload.c @@ -59,7 +59,6 @@ typedef struct _VipsForeignLoadMagick { VipsForeignLoad parent_object; - char *filename; gboolean all_frames; char *density; @@ -67,24 +66,9 @@ typedef struct _VipsForeignLoadMagick { typedef VipsForeignLoadClass VipsForeignLoadMagickClass; -G_DEFINE_TYPE( VipsForeignLoadMagick, vips_foreign_load_magick, +G_DEFINE_ABSTRACT_TYPE( VipsForeignLoadMagick, vips_foreign_load_magick, VIPS_TYPE_FOREIGN_LOAD ); -static gboolean -ismagick( const char *filename ) -{ - VipsImage *t; - int result; - - t = vips_image_new(); - vips_error_freeze(); - result = vips__magick_read_header( filename, t, FALSE, NULL ); - g_object_unref( t ); - vips_error_thaw(); - - return( result == 0 ); -} - static VipsForeignFlags vips_foreign_load_magick_get_flags_filename( const char *filename ) { @@ -94,32 +78,7 @@ vips_foreign_load_magick_get_flags_filename( const char *filename ) static VipsForeignFlags vips_foreign_load_magick_get_flags( VipsForeignLoad *load ) { - VipsForeignLoadMagick *magick = (VipsForeignLoadMagick *) load; - - return( vips_foreign_load_magick_get_flags_filename( - magick->filename ) ); -} - -/* - * Unfortunately, libMagick does not support header-only reads very well. See - * - * http://www.imagemagick.org/discourse-server/viewtopic.php?f=1&t=20017 - * - * Test especially with BMP, GIF, TGA. So we are forced to read the entire - * image in the @header() method. - */ -static int -vips_foreign_load_magick_header( VipsForeignLoad *load ) -{ - VipsForeignLoadMagick *magick = (VipsForeignLoadMagick *) load; - - if( vips__magick_read( magick->filename, - load->out, magick->all_frames, magick->density ) ) - return( -1 ); - - VIPS_SETSTR( load->out->filename, magick->filename ); - - return( 0 ); + return( VIPS_FOREIGN_PARTIAL ); } static void @@ -133,27 +92,17 @@ vips_foreign_load_magick_class_init( VipsForeignLoadMagickClass *class ) gobject_class->set_property = vips_object_set_property; gobject_class->get_property = vips_object_get_property; - object_class->nickname = "magickload"; - object_class->description = _( "load file with ImageMagick" ); + object_class->nickname = "magickload_base"; + object_class->description = _( "load with ImageMagick" ); - /* We need to be well to the back of the queue since the vips's + /* We need to be well to the back of the queue since vips's * dedicated loaders are usually preferable. */ foreign_class->priority = -100; - load_class->is_a = ismagick; load_class->get_flags_filename = vips_foreign_load_magick_get_flags_filename; load_class->get_flags = vips_foreign_load_magick_get_flags; - load_class->header = vips_foreign_load_magick_header; - load_class->load = NULL; - - VIPS_ARG_STRING( class, "filename", 1, - _( "Filename" ), - _( "Filename to load from" ), - VIPS_ARGUMENT_REQUIRED_INPUT, - G_STRUCT_OFFSET( VipsForeignLoadMagick, filename ), - NULL ); VIPS_ARG_BOOL( class, "all_frames", 3, _( "all_frames" ), @@ -175,19 +124,99 @@ vips_foreign_load_magick_init( VipsForeignLoadMagick *magick ) { } +typedef struct _VipsForeignLoadMagickFile { + VipsForeignLoadMagick parent_object; + + char *filename; + +} VipsForeignLoadMagickFile; + +typedef VipsForeignLoadMagickClass VipsForeignLoadMagickFileClass; + +G_DEFINE_TYPE( VipsForeignLoadMagickFile, vips_foreign_load_magick_file, + vips_foreign_load_magick_get_type() ); + +static gboolean +ismagick( const char *filename ) +{ + VipsImage *t; + int result; + + t = vips_image_new(); + vips_error_freeze(); + result = vips__magick_read_header( filename, t, FALSE, NULL ); + g_object_unref( t ); + vips_error_thaw(); + + return( result == 0 ); +} + +/* Unfortunately, libMagick does not support header-only reads very well. See + * + * http://www.imagemagick.org/discourse-server/viewtopic.php?f=1&t=20017 + * + * Test especially with BMP, GIF, TGA. So we are forced to read the entire + * image in the @header() method. + */ +static int +vips_foreign_load_magick_file_header( VipsForeignLoad *load ) +{ + VipsForeignLoadMagick *magick = (VipsForeignLoadMagick *) load; + VipsForeignLoadMagickFile *magick_file = + (VipsForeignLoadMagickFile *) load; + + if( vips__magick_read( magick_file->filename, + load->out, magick->all_frames, magick->density ) ) + return( -1 ); + + VIPS_SETSTR( load->out->filename, magick_file->filename ); + + return( 0 ); +} + +static void +vips_foreign_load_magick_file_class_init( + VipsForeignLoadMagickFileClass *class ) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS( class ); + VipsObjectClass *object_class = (VipsObjectClass *) class; + VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class; + + gobject_class->set_property = vips_object_set_property; + gobject_class->get_property = vips_object_get_property; + + object_class->nickname = "magickload"; + object_class->description = _( "load file with ImageMagick" ); + + load_class->is_a = ismagick; + load_class->header = vips_foreign_load_magick_file_header; + load_class->load = NULL; + + VIPS_ARG_STRING( class, "filename", 1, + _( "Filename" ), + _( "Filename to load from" ), + VIPS_ARGUMENT_REQUIRED_INPUT, + G_STRUCT_OFFSET( VipsForeignLoadMagickFile, filename ), + NULL ); + +} + +static void +vips_foreign_load_magick_file_init( VipsForeignLoadMagickFile *magick_file ) +{ +} + typedef struct _VipsForeignLoadMagickBuffer { - VipsForeignLoad parent_object; + VipsForeignLoadMagick parent_object; VipsArea *buf; - gboolean all_frames; - char *density; } VipsForeignLoadMagickBuffer; -typedef VipsForeignLoadClass VipsForeignLoadMagickBufferClass; +typedef VipsForeignLoadMagickClass VipsForeignLoadMagickBufferClass; G_DEFINE_TYPE( VipsForeignLoadMagickBuffer, vips_foreign_load_magick_buffer, - VIPS_TYPE_FOREIGN_LOAD ); + vips_foreign_load_magick_get_type() ); static gboolean vips_foreign_load_magick_buffer_is_a_buffer ( void* buf, size_t len ) @@ -204,42 +233,34 @@ vips_foreign_load_magick_buffer_is_a_buffer ( void* buf, size_t len ) return( result == 0 ); } -static VipsForeignFlags -vips_foreign_load_magick_buffer_get_flags( VipsForeignLoad *load ) -{ - return( VIPS_FOREIGN_PARTIAL ); -} - +/* Unfortunately, libMagick does not support header-only reads very well. See + * + * http://www.imagemagick.org/discourse-server/viewtopic.php?f=1&t=20017 + * + * Test especially with BMP, GIF, TGA. So we are forced to read the entire + * image in the @header() method. + */ static int vips_foreign_load_magick_buffer_header( VipsForeignLoad *load ) { - VipsForeignLoadMagickBuffer *magick = (VipsForeignLoadMagickBuffer *) load; + VipsForeignLoadMagick *magick = (VipsForeignLoadMagick *) load; + VipsForeignLoadMagickBuffer *magick_buffer = + (VipsForeignLoadMagickBuffer *) load; - if( vips__magick_read_buffer_header( magick->buf->data, magick->buf->length, + if( vips__magick_read_buffer( + magick_buffer->buf->data, magick_buffer->buf->length, load->out, magick->all_frames, magick->density ) ) return( -1 ); return( 0 ); } -static int -vips_foreign_load_magick_buffer_load( VipsForeignLoad *load ) -{ - VipsForeignLoadMagickBuffer *magick = (VipsForeignLoadMagickBuffer *) load; - - if( vips__magick_read_buffer( magick->buf->data, magick->buf->length, - load->real, magick->all_frames, magick->density ) ) - return( -1 ); - - return( 0 ); -} - static void -vips_foreign_load_magick_buffer_class_init( VipsForeignLoadMagickBufferClass *class ) +vips_foreign_load_magick_buffer_class_init( + VipsForeignLoadMagickBufferClass *class ) { GObjectClass *gobject_class = G_OBJECT_CLASS( class ); VipsObjectClass *object_class = (VipsObjectClass *) class; - VipsForeignClass *foreign_class = (VipsForeignClass *) class; VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class; gobject_class->set_property = vips_object_set_property; @@ -248,15 +269,9 @@ vips_foreign_load_magick_buffer_class_init( VipsForeignLoadMagickBufferClass *cl object_class->nickname = "magickload_buffer"; object_class->description = _( "load buffer with ImageMagick" ); - /* We need to be well to the back of the queue since the vips's - * dedicated loaders are usually preferable. - */ - foreign_class->priority = -100; - load_class->is_a_buffer = vips_foreign_load_magick_buffer_is_a_buffer; - load_class->get_flags = vips_foreign_load_magick_buffer_get_flags; load_class->header = vips_foreign_load_magick_buffer_header; - load_class->load = vips_foreign_load_magick_buffer_load; + load_class->load = NULL; VIPS_ARG_BOXED( class, "buffer", 1, _( "Buffer" ), @@ -265,19 +280,6 @@ vips_foreign_load_magick_buffer_class_init( VipsForeignLoadMagickBufferClass *cl G_STRUCT_OFFSET( VipsForeignLoadMagickBuffer, buf ), VIPS_TYPE_BLOB ); - VIPS_ARG_BOOL( class, "all_frames", 3, - _( "all_frames" ), - _( "Read all frames from an image" ), - VIPS_ARGUMENT_OPTIONAL_INPUT, - G_STRUCT_OFFSET( VipsForeignLoadMagickBuffer, all_frames ), - FALSE ); - - VIPS_ARG_STRING( class, "density", 4, - _( "Density" ), - _( "Canvas resolution for rendering vector formats like SVG" ), - VIPS_ARGUMENT_OPTIONAL_INPUT, - G_STRUCT_OFFSET( VipsForeignLoadMagickBuffer, density ), - NULL ); } static void