Moved code to magicksave.c and added extra define to enable only saving with ImageMagick.
This commit is contained in:
parent
ccf894c738
commit
383125a031
@ -1882,16 +1882,17 @@ vips_foreign_operation_init( void )
|
||||
#ifdef HAVE_MAGICK
|
||||
vips_foreign_load_magick_file_get_type();
|
||||
vips_foreign_load_magick_buffer_get_type();
|
||||
vips_foreign_save_magick_file_get_type();
|
||||
vips_foreign_save_magick_buffer_get_type();
|
||||
#endif /*HAVE_MAGICK*/
|
||||
|
||||
#ifdef HAVE_MAGICK7
|
||||
vips_foreign_load_magick7_file_get_type();
|
||||
vips_foreign_load_magick7_buffer_get_type();
|
||||
#endif /*HAVE_MAGICK7*/
|
||||
|
||||
#ifdef HAVE_MAGICKSAVE
|
||||
vips_foreign_save_magick_file_get_type();
|
||||
vips_foreign_save_magick_buffer_get_type();
|
||||
#endif /*HAVE_MAGICK7*/
|
||||
#endif /*HAVE_MAGICKSAVE*/
|
||||
|
||||
#ifdef HAVE_CFITSIO
|
||||
vips_foreign_load_fits_get_type();
|
||||
|
@ -93,6 +93,8 @@
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
#include <vips/intl.h>
|
||||
|
||||
#ifdef HAVE_MAGICK
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -100,36 +102,15 @@
|
||||
|
||||
#include <vips/vips.h>
|
||||
|
||||
#if HAVE_MAGICK || HAVE_MAGICK7
|
||||
#include <magick/api.h>
|
||||
|
||||
#if HAVE_MAGICK
|
||||
#include <magick/api.h>
|
||||
/* pre-float Magick used to call this MaxRGB.
|
||||
*/
|
||||
#if !defined(QuantumRange)
|
||||
# define QuantumRange MaxRGB
|
||||
#endif
|
||||
#define MaxPathExtent MaxTextExtent
|
||||
#elif HAVE_MAGICK7
|
||||
#include <MagickCore/MagickCore.h>
|
||||
#define MaxPathExtent MagickPathExtent
|
||||
#endif
|
||||
#include "pforeign.h"
|
||||
|
||||
/* What we track during a write call.
|
||||
/* pre-float Magick used to call this MaxRGB.
|
||||
*/
|
||||
typedef struct _Write {
|
||||
VipsImage *im;
|
||||
|
||||
Image *images;
|
||||
ImageInfo *image_info;
|
||||
ExceptionInfo *exception;
|
||||
|
||||
Image *current_image;
|
||||
char *map;
|
||||
StorageType storageType;
|
||||
} Write;
|
||||
|
||||
#if HAVE_MAGICK
|
||||
#if !defined(QuantumRange)
|
||||
# define QuantumRange MaxRGB
|
||||
#endif
|
||||
|
||||
/* And this used to be UseHDRI.
|
||||
*/
|
||||
@ -137,8 +118,6 @@ typedef struct _Write {
|
||||
# define UseHDRI 1
|
||||
#endif
|
||||
|
||||
#include "pforeign.h"
|
||||
|
||||
/* What we track during a read call.
|
||||
*/
|
||||
typedef struct _Read {
|
||||
@ -232,7 +211,7 @@ read_new( const char *filename, VipsImage *im,
|
||||
|
||||
if( filename )
|
||||
vips_strncpy( read->image_info->filename,
|
||||
filename, MaxPathExtent );
|
||||
filename, MaxTextExtent );
|
||||
|
||||
/* Canvas resolution for rendering vector formats like SVG.
|
||||
*/
|
||||
@ -915,396 +894,3 @@ vips__magick_read_buffer_header( const void *buf, const size_t len,
|
||||
|
||||
#endif /*HAVE_MAGICK*/
|
||||
|
||||
#ifdef HAVE_MAGICK7
|
||||
|
||||
static Image*
|
||||
magick_acquire_image( const ImageInfo *image_info, ExceptionInfo *exception )
|
||||
{
|
||||
return AcquireImage( image_info, exception );
|
||||
}
|
||||
|
||||
static void
|
||||
magick_acquire_next_image( const ImageInfo *image_info, Image *image,
|
||||
ExceptionInfo *exception)
|
||||
{
|
||||
AcquireNextImage( image_info, image, exception );
|
||||
}
|
||||
|
||||
static int
|
||||
magick_set_image_size( Image *image, const size_t width, const size_t height,
|
||||
ExceptionInfo *exception)
|
||||
{
|
||||
return SetImageExtent( image, width, height, exception );
|
||||
}
|
||||
|
||||
static int
|
||||
magick_import_pixels( Image *image, const ssize_t x, const ssize_t y,
|
||||
const size_t width, const size_t height, const char *map,
|
||||
const StorageType type,const void *pixels, ExceptionInfo *exception )
|
||||
{
|
||||
return ImportImagePixels( image, x, y, width, height, map,
|
||||
type, pixels, exception );
|
||||
}
|
||||
|
||||
static void
|
||||
magick_set_property( Image *image, const char *property, const char *value,
|
||||
ExceptionInfo *exception )
|
||||
{
|
||||
(void) SetImageProperty( image, property, value, exception );
|
||||
}
|
||||
|
||||
static void
|
||||
magick_inherit_exception( Write *write, Image *image ) {
|
||||
(void) write;
|
||||
(void) image;
|
||||
}
|
||||
|
||||
#endif /*HAVE_MAGICK7 */
|
||||
|
||||
#ifdef HAVE_MAGICK
|
||||
|
||||
static Image*
|
||||
magick_acquire_image(const ImageInfo *image_info, ExceptionInfo *exception)
|
||||
{
|
||||
(void) exception;
|
||||
return AcquireImage( image_info );
|
||||
}
|
||||
|
||||
static void
|
||||
magick_acquire_next_image( const ImageInfo *image_info, Image *image,
|
||||
ExceptionInfo *exception )
|
||||
{
|
||||
(void) exception;
|
||||
AcquireNextImage( image_info, image );
|
||||
}
|
||||
|
||||
static int
|
||||
magick_set_image_size( Image *image, const size_t width, const size_t height,
|
||||
ExceptionInfo *exception )
|
||||
{
|
||||
(void) exception;
|
||||
return SetImageExtent( image, width, height );
|
||||
}
|
||||
|
||||
static int
|
||||
magick_import_pixels( Image *image, const ssize_t x, const ssize_t y,
|
||||
const size_t width, const size_t height, const char *map,
|
||||
const StorageType type,const void *pixels, ExceptionInfo *exception )
|
||||
{
|
||||
(void) exception;
|
||||
return ImportImagePixels( image, x, y, width, height, map,
|
||||
type, pixels );
|
||||
}
|
||||
|
||||
static void
|
||||
magick_set_property( Image *image, const char *property, const char *value,
|
||||
ExceptionInfo *exception )
|
||||
{
|
||||
(void) exception;
|
||||
(void) SetImageProperty( image, property, value );
|
||||
}
|
||||
|
||||
static void
|
||||
magick_inherit_exception( Write *write, Image *image ) {
|
||||
InheritException( write->exception, &image->exception );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Can be called many times.
|
||||
*/
|
||||
static void
|
||||
write_free( Write *write )
|
||||
{
|
||||
VIPS_FREE( write->map );
|
||||
VIPS_FREEF( DestroyImageList, write->images );
|
||||
VIPS_FREEF( DestroyImageInfo, write->image_info );
|
||||
VIPS_FREEF( DestroyExceptionInfo, write->exception );
|
||||
}
|
||||
|
||||
/* Can be called many times.
|
||||
*/
|
||||
static int
|
||||
write_close( VipsImage *im, Write *write )
|
||||
{
|
||||
write_free( write );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static Write *
|
||||
write_new( VipsImage *im, const char *filename, const char *format,
|
||||
const size_t quality )
|
||||
{
|
||||
Write *write;
|
||||
static int inited = 0;
|
||||
|
||||
if( !inited ) {
|
||||
MagickCoreGenesis( vips_get_argv0(), MagickFalse );
|
||||
inited = 1;
|
||||
}
|
||||
|
||||
if( !(write = VIPS_NEW( im, Write )) )
|
||||
return( NULL );
|
||||
write->im = im;
|
||||
write->images = NULL;
|
||||
|
||||
write->storageType = UndefinedPixel;
|
||||
switch( im->BandFmt ) {
|
||||
case VIPS_FORMAT_UCHAR:
|
||||
write->storageType = CharPixel;
|
||||
break;
|
||||
case VIPS_FORMAT_USHORT:
|
||||
write->storageType = ShortPixel;
|
||||
break;
|
||||
case VIPS_FORMAT_UINT:
|
||||
write->storageType = LongPixel;
|
||||
break;
|
||||
case VIPS_FORMAT_FLOAT:
|
||||
write->storageType = FloatPixel;
|
||||
break;
|
||||
case VIPS_FORMAT_DOUBLE:
|
||||
write->storageType = DoublePixel;
|
||||
break;
|
||||
|
||||
default:
|
||||
write_free(write);
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
write->map = NULL;
|
||||
switch( im->Bands ) {
|
||||
case 1:
|
||||
write->map = g_strdup("R");
|
||||
break;
|
||||
case 2:
|
||||
write->map = g_strdup("RA");
|
||||
break;
|
||||
case 3:
|
||||
write->map = g_strdup("RGB");
|
||||
break;
|
||||
case 4:
|
||||
if( im->Type == VIPS_INTERPRETATION_CMYK )
|
||||
write->map = g_strdup("CMYK");
|
||||
else
|
||||
write->map = g_strdup("RGBA");
|
||||
break;
|
||||
case 5:
|
||||
write->map = g_strdup("CMYKA");
|
||||
break;
|
||||
|
||||
default:
|
||||
write_free(write);
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
write->image_info = CloneImageInfo( NULL );
|
||||
if( !write->image_info) {
|
||||
write_free(write);
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
if( format ) {
|
||||
vips_strncpy( write->image_info->magick,
|
||||
format, MaxPathExtent );
|
||||
if ( filename ) {
|
||||
(void) vips_snprintf( write->image_info->filename,
|
||||
MaxPathExtent, "%s:%s", format, filename );
|
||||
}
|
||||
}
|
||||
else if ( filename ) {
|
||||
vips_strncpy( write->image_info->filename,
|
||||
filename, MaxPathExtent );
|
||||
}
|
||||
|
||||
if ( quality > 0 ) {
|
||||
write->image_info->quality = quality;
|
||||
}
|
||||
|
||||
write->exception = AcquireExceptionInfo();
|
||||
if( !write->exception) {
|
||||
write_free(write);
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
g_signal_connect( im, "close", G_CALLBACK( write_close ), write );
|
||||
|
||||
return( write );
|
||||
}
|
||||
|
||||
static int
|
||||
magick_set_properties( Write *write )
|
||||
{
|
||||
int number;
|
||||
const char *str;
|
||||
|
||||
if( vips_image_get_typeof( write->im, "gif-delay" ) &&
|
||||
!vips_image_get_int( write->im, "gif-delay", &number ) )
|
||||
write->current_image->delay = (size_t) number;
|
||||
|
||||
if( vips_image_get_typeof( write->im, "gif-loop" ) &&
|
||||
!vips_image_get_int( write->im, "gif-loop", &number ) )
|
||||
write->current_image->iterations = (size_t) number;
|
||||
|
||||
if( vips_image_get_typeof( write->im, "gif-comment" ) &&
|
||||
!vips_image_get_string( write->im, "gif-comment", &str ) )
|
||||
magick_set_property( write->current_image, "comment",
|
||||
str, write->exception );
|
||||
}
|
||||
|
||||
static int
|
||||
magick_write_block( VipsRegion *region, VipsRect *area, void *a )
|
||||
{
|
||||
Write *write = (Write *) a;
|
||||
MagickBooleanType status;
|
||||
void *p;
|
||||
|
||||
p = VIPS_REGION_ADDR(region, area->left, area->top);
|
||||
|
||||
status=magick_import_pixels( write->current_image, area->left, area->top,
|
||||
area->width, area->height, write->map, write->storageType, p,
|
||||
write->exception );
|
||||
|
||||
return( status == MagickFalse ? -1 : 0 );
|
||||
}
|
||||
|
||||
static int
|
||||
magick_create_image( Write *write, VipsImage *im )
|
||||
{
|
||||
Image *image;
|
||||
int status;
|
||||
|
||||
if( write->images == NULL ) {
|
||||
image = magick_acquire_image( write->image_info, write->exception );
|
||||
if( image == NULL )
|
||||
return( -1 );
|
||||
|
||||
write->images = image;
|
||||
}
|
||||
else {
|
||||
image=GetLastImageInList( write->images );
|
||||
magick_acquire_next_image( write->image_info, image, write->exception );
|
||||
if( GetNextImageInList( image ) == NULL )
|
||||
return( -1 );
|
||||
|
||||
image=SyncNextImageInList( image );
|
||||
}
|
||||
|
||||
if( !magick_set_image_size( image, im->Xsize, im->Ysize, write->exception ) )
|
||||
return( -1 );
|
||||
|
||||
write->current_image=image;
|
||||
magick_set_properties( write );
|
||||
status = vips_sink_disc( im, magick_write_block, write );
|
||||
magick_inherit_exception( write, write->current_image );
|
||||
return( status );
|
||||
}
|
||||
|
||||
static int
|
||||
magick_create_images( Write *write )
|
||||
{
|
||||
int height;
|
||||
int count;
|
||||
int status;
|
||||
|
||||
height = 0;
|
||||
if( vips_image_get_typeof( write->im, VIPS_META_PAGE_HEIGHT ) &&
|
||||
vips_image_get_int( write->im, VIPS_META_PAGE_HEIGHT, &height ) )
|
||||
return( magick_create_image( write, write->im ) );
|
||||
|
||||
for( int top=0; top < write->im->Ysize ; top+=height ) {
|
||||
VipsImage *im;
|
||||
|
||||
if( vips_crop( write->im, &im, 0, top, write->im->Xsize, height, NULL ) )
|
||||
return( -1 );
|
||||
|
||||
status = magick_create_image( write, im );
|
||||
|
||||
g_object_unref( im );
|
||||
|
||||
if( status )
|
||||
break;
|
||||
}
|
||||
|
||||
return( status );
|
||||
}
|
||||
|
||||
static int
|
||||
magick_write_images( Write *write )
|
||||
{
|
||||
if( !WriteImages( write->image_info, write->images,
|
||||
write->image_info->filename, write->exception ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static int
|
||||
magick_write_images_buf( Write *write, void **obuf, size_t *olen )
|
||||
{
|
||||
*obuf=ImagesToBlob( write->image_info, write->images, olen,
|
||||
write->exception );
|
||||
|
||||
if( !*obuf )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int
|
||||
vips__magick_write( VipsImage *im, const char *filename,
|
||||
const char *format, const size_t quality )
|
||||
{
|
||||
Write *write;
|
||||
|
||||
if( !(write = write_new( im, filename, format, quality )) )
|
||||
return( -1 );
|
||||
|
||||
if ( magick_create_images( write ) ) {
|
||||
vips_error( "magick2vips", _( "unable to write file \"%s\"\n"
|
||||
"libMagick error: %s %s" ),
|
||||
filename,
|
||||
write->exception->reason, write->exception->description );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
if( magick_write_images( write ) ) {
|
||||
magick_inherit_exception( write, write->images );
|
||||
vips_error( "magick2vips", _( "unable to write file \"%s\"\n"
|
||||
"libMagick error: %s %s" ),
|
||||
filename,
|
||||
write->exception->reason, write->exception->description );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int
|
||||
vips__magick_write_buf( VipsImage *im, void **obuf, size_t *olen,
|
||||
const char *format, const size_t quality )
|
||||
{
|
||||
Write *write;
|
||||
|
||||
if( !(write = write_new( im, NULL, format, quality )) )
|
||||
return( -1 );
|
||||
|
||||
if ( magick_create_images( write ) ) {
|
||||
vips_error( "magick2vips", _( "unable to write buffer \n"
|
||||
"libMagick error: %s %s" ),
|
||||
write->exception->reason, write->exception->description );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
if( magick_write_images_buf( write, obuf, olen ) ) {
|
||||
vips_error( "magick2vips", _( "unable to write buffer \n"
|
||||
"libMagick error: %s %s" ),
|
||||
write->exception->reason, write->exception->description );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#endif /*HAVE_MAGICK | HAVE_MAGICK7*/
|
||||
|
||||
|
@ -33,7 +33,11 @@
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
#include <vips/intl.h>
|
||||
|
||||
#if HAVE_MAGICK || HAVE_MAGICK7
|
||||
/* Should be removed and added as a configure option */
|
||||
#define HAVE_MAGICKSAVE 1
|
||||
/* Should be removed and added as a configure option */
|
||||
|
||||
#ifdef HAVE_MAGICKSAVE
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -43,6 +47,424 @@
|
||||
|
||||
#include "pforeign.h"
|
||||
|
||||
#ifdef HAVE_MAGICK
|
||||
#include <magick/api.h>
|
||||
/* pre-float Magick used to call this MaxRGB.
|
||||
*/
|
||||
#define MaxPathExtent MaxTextExtent
|
||||
#endif
|
||||
#ifdef HAVE_MAGICK7
|
||||
#include <MagickCore/MagickCore.h>
|
||||
#define MaxPathExtent MagickPathExtent
|
||||
#endif
|
||||
|
||||
/* What we track during a write call.
|
||||
*/
|
||||
typedef struct _Write {
|
||||
VipsImage *im;
|
||||
|
||||
Image *images;
|
||||
ImageInfo *image_info;
|
||||
ExceptionInfo *exception;
|
||||
|
||||
Image *current_image;
|
||||
char *map;
|
||||
StorageType storageType;
|
||||
} Write;
|
||||
|
||||
#ifdef HAVE_MAGICK7
|
||||
|
||||
static Image*
|
||||
magick_acquire_image( const ImageInfo *image_info, ExceptionInfo *exception )
|
||||
{
|
||||
return AcquireImage( image_info, exception );
|
||||
}
|
||||
|
||||
static void
|
||||
magick_acquire_next_image( const ImageInfo *image_info, Image *image,
|
||||
ExceptionInfo *exception)
|
||||
{
|
||||
AcquireNextImage( image_info, image, exception );
|
||||
}
|
||||
|
||||
static int
|
||||
magick_set_image_size( Image *image, const size_t width, const size_t height,
|
||||
ExceptionInfo *exception)
|
||||
{
|
||||
return SetImageExtent( image, width, height, exception );
|
||||
}
|
||||
|
||||
static int
|
||||
magick_import_pixels( Image *image, const ssize_t x, const ssize_t y,
|
||||
const size_t width, const size_t height, const char *map,
|
||||
const StorageType type,const void *pixels, ExceptionInfo *exception )
|
||||
{
|
||||
return ImportImagePixels( image, x, y, width, height, map,
|
||||
type, pixels, exception );
|
||||
}
|
||||
|
||||
static void
|
||||
magick_set_property( Image *image, const char *property, const char *value,
|
||||
ExceptionInfo *exception )
|
||||
{
|
||||
(void) SetImageProperty( image, property, value, exception );
|
||||
}
|
||||
|
||||
static void
|
||||
magick_inherit_exception( Write *write, Image *image ) {
|
||||
(void) write;
|
||||
(void) image;
|
||||
}
|
||||
|
||||
#endif /*HAVE_MAGICK7 */
|
||||
|
||||
#ifdef HAVE_MAGICK
|
||||
|
||||
static Image*
|
||||
magick_acquire_image(const ImageInfo *image_info, ExceptionInfo *exception)
|
||||
{
|
||||
(void) exception;
|
||||
return AcquireImage( image_info );
|
||||
}
|
||||
|
||||
static void
|
||||
magick_acquire_next_image( const ImageInfo *image_info, Image *image,
|
||||
ExceptionInfo *exception )
|
||||
{
|
||||
(void) exception;
|
||||
AcquireNextImage( image_info, image );
|
||||
}
|
||||
|
||||
static int
|
||||
magick_set_image_size( Image *image, const size_t width, const size_t height,
|
||||
ExceptionInfo *exception )
|
||||
{
|
||||
(void) exception;
|
||||
return SetImageExtent( image, width, height );
|
||||
}
|
||||
|
||||
static int
|
||||
magick_import_pixels( Image *image, const ssize_t x, const ssize_t y,
|
||||
const size_t width, const size_t height, const char *map,
|
||||
const StorageType type,const void *pixels, ExceptionInfo *exception )
|
||||
{
|
||||
(void) exception;
|
||||
return ImportImagePixels( image, x, y, width, height, map,
|
||||
type, pixels );
|
||||
}
|
||||
|
||||
static void
|
||||
magick_set_property( Image *image, const char *property, const char *value,
|
||||
ExceptionInfo *exception )
|
||||
{
|
||||
(void) exception;
|
||||
(void) SetImageProperty( image, property, value );
|
||||
}
|
||||
|
||||
static void
|
||||
magick_inherit_exception( Write *write, Image *image ) {
|
||||
InheritException( write->exception, &image->exception );
|
||||
}
|
||||
|
||||
#endif /*HAVE_MAGICK */
|
||||
|
||||
/* Can be called many times.
|
||||
*/
|
||||
static void
|
||||
write_free( Write *write )
|
||||
{
|
||||
VIPS_FREE( write->map );
|
||||
VIPS_FREEF( DestroyImageList, write->images );
|
||||
VIPS_FREEF( DestroyImageInfo, write->image_info );
|
||||
VIPS_FREEF( DestroyExceptionInfo, write->exception );
|
||||
}
|
||||
|
||||
/* Can be called many times.
|
||||
*/
|
||||
static int
|
||||
write_close( VipsImage *im, Write *write )
|
||||
{
|
||||
write_free( write );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static Write *
|
||||
write_new( VipsImage *im, const char *filename, const char *format,
|
||||
const size_t quality )
|
||||
{
|
||||
Write *write;
|
||||
static int inited = 0;
|
||||
|
||||
if( !inited ) {
|
||||
MagickCoreGenesis( vips_get_argv0(), MagickFalse );
|
||||
inited = 1;
|
||||
}
|
||||
|
||||
if( !(write = VIPS_NEW( im, Write )) )
|
||||
return( NULL );
|
||||
write->im = im;
|
||||
write->images = NULL;
|
||||
|
||||
write->storageType = UndefinedPixel;
|
||||
switch( im->BandFmt ) {
|
||||
case VIPS_FORMAT_UCHAR:
|
||||
write->storageType = CharPixel;
|
||||
break;
|
||||
case VIPS_FORMAT_USHORT:
|
||||
write->storageType = ShortPixel;
|
||||
break;
|
||||
case VIPS_FORMAT_UINT:
|
||||
write->storageType = LongPixel;
|
||||
break;
|
||||
case VIPS_FORMAT_FLOAT:
|
||||
write->storageType = FloatPixel;
|
||||
break;
|
||||
case VIPS_FORMAT_DOUBLE:
|
||||
write->storageType = DoublePixel;
|
||||
break;
|
||||
|
||||
default:
|
||||
write_free(write);
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
write->map = NULL;
|
||||
switch( im->Bands ) {
|
||||
case 1:
|
||||
write->map = g_strdup("R");
|
||||
break;
|
||||
case 2:
|
||||
write->map = g_strdup("RA");
|
||||
break;
|
||||
case 3:
|
||||
write->map = g_strdup("RGB");
|
||||
break;
|
||||
case 4:
|
||||
if( im->Type == VIPS_INTERPRETATION_CMYK )
|
||||
write->map = g_strdup("CMYK");
|
||||
else
|
||||
write->map = g_strdup("RGBA");
|
||||
break;
|
||||
case 5:
|
||||
write->map = g_strdup("CMYKA");
|
||||
break;
|
||||
|
||||
default:
|
||||
write_free(write);
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
write->image_info = CloneImageInfo( NULL );
|
||||
if( !write->image_info) {
|
||||
write_free(write);
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
if( format ) {
|
||||
vips_strncpy( write->image_info->magick,
|
||||
format, MaxPathExtent );
|
||||
if ( filename ) {
|
||||
(void) vips_snprintf( write->image_info->filename,
|
||||
MaxPathExtent, "%s:%s", format, filename );
|
||||
}
|
||||
}
|
||||
else if ( filename ) {
|
||||
vips_strncpy( write->image_info->filename,
|
||||
filename, MaxPathExtent );
|
||||
}
|
||||
|
||||
if ( quality > 0 ) {
|
||||
write->image_info->quality = quality;
|
||||
}
|
||||
|
||||
write->exception = AcquireExceptionInfo();
|
||||
if( !write->exception) {
|
||||
write_free(write);
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
g_signal_connect( im, "close", G_CALLBACK( write_close ), write );
|
||||
|
||||
return( write );
|
||||
}
|
||||
|
||||
static int
|
||||
magick_set_properties( Write *write )
|
||||
{
|
||||
int number;
|
||||
const char *str;
|
||||
|
||||
if( vips_image_get_typeof( write->im, "gif-delay" ) &&
|
||||
!vips_image_get_int( write->im, "gif-delay", &number ) )
|
||||
write->current_image->delay = (size_t) number;
|
||||
|
||||
if( vips_image_get_typeof( write->im, "gif-loop" ) &&
|
||||
!vips_image_get_int( write->im, "gif-loop", &number ) )
|
||||
write->current_image->iterations = (size_t) number;
|
||||
|
||||
if( vips_image_get_typeof( write->im, "gif-comment" ) &&
|
||||
!vips_image_get_string( write->im, "gif-comment", &str ) )
|
||||
magick_set_property( write->current_image, "comment",
|
||||
str, write->exception );
|
||||
}
|
||||
|
||||
static int
|
||||
magick_write_block( VipsRegion *region, VipsRect *area, void *a )
|
||||
{
|
||||
Write *write = (Write *) a;
|
||||
MagickBooleanType status;
|
||||
void *p;
|
||||
|
||||
p = VIPS_REGION_ADDR(region, area->left, area->top);
|
||||
|
||||
status=magick_import_pixels( write->current_image, area->left, area->top,
|
||||
area->width, area->height, write->map, write->storageType, p,
|
||||
write->exception );
|
||||
|
||||
return( status == MagickFalse ? -1 : 0 );
|
||||
}
|
||||
|
||||
static int
|
||||
magick_create_image( Write *write, VipsImage *im )
|
||||
{
|
||||
Image *image;
|
||||
int status;
|
||||
|
||||
if( write->images == NULL ) {
|
||||
image = magick_acquire_image( write->image_info, write->exception );
|
||||
if( image == NULL )
|
||||
return( -1 );
|
||||
|
||||
write->images = image;
|
||||
}
|
||||
else {
|
||||
image=GetLastImageInList( write->images );
|
||||
magick_acquire_next_image( write->image_info, image, write->exception );
|
||||
if( GetNextImageInList( image ) == NULL )
|
||||
return( -1 );
|
||||
|
||||
image=SyncNextImageInList( image );
|
||||
}
|
||||
|
||||
if( !magick_set_image_size( image, im->Xsize, im->Ysize, write->exception ) )
|
||||
return( -1 );
|
||||
|
||||
write->current_image=image;
|
||||
magick_set_properties( write );
|
||||
status = vips_sink_disc( im, magick_write_block, write );
|
||||
magick_inherit_exception( write, write->current_image );
|
||||
return( status );
|
||||
}
|
||||
|
||||
static int
|
||||
magick_create_images( Write *write )
|
||||
{
|
||||
int height;
|
||||
int count;
|
||||
int status;
|
||||
|
||||
height = 0;
|
||||
if( vips_image_get_typeof( write->im, VIPS_META_PAGE_HEIGHT ) &&
|
||||
vips_image_get_int( write->im, VIPS_META_PAGE_HEIGHT, &height ) )
|
||||
return( magick_create_image( write, write->im ) );
|
||||
|
||||
for( int top=0; top < write->im->Ysize ; top+=height ) {
|
||||
VipsImage *im;
|
||||
|
||||
if( vips_crop( write->im, &im, 0, top, write->im->Xsize, height, NULL ) )
|
||||
return( -1 );
|
||||
|
||||
status = magick_create_image( write, im );
|
||||
|
||||
g_object_unref( im );
|
||||
|
||||
if( status )
|
||||
break;
|
||||
}
|
||||
|
||||
return( status );
|
||||
}
|
||||
|
||||
static int
|
||||
magick_write_images( Write *write )
|
||||
{
|
||||
if( !WriteImages( write->image_info, write->images,
|
||||
write->image_info->filename, write->exception ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static int
|
||||
magick_write_images_buf( Write *write, void **obuf, size_t *olen )
|
||||
{
|
||||
*obuf=ImagesToBlob( write->image_info, write->images, olen,
|
||||
write->exception );
|
||||
|
||||
if( !*obuf )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static int
|
||||
magick_write( VipsImage *im, const char *filename,
|
||||
const char *format, const size_t quality )
|
||||
{
|
||||
Write *write;
|
||||
|
||||
if( !(write = write_new( im, filename, format, quality )) )
|
||||
return( -1 );
|
||||
|
||||
if ( magick_create_images( write ) ) {
|
||||
vips_error( "magick2vips", _( "unable to write file \"%s\"\n"
|
||||
"libMagick error: %s %s" ),
|
||||
filename,
|
||||
write->exception->reason, write->exception->description );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
if( magick_write_images( write ) ) {
|
||||
magick_inherit_exception( write, write->images );
|
||||
vips_error( "magick2vips", _( "unable to write file \"%s\"\n"
|
||||
"libMagick error: %s %s" ),
|
||||
filename,
|
||||
write->exception->reason, write->exception->description );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static int
|
||||
magick_write_buf( VipsImage *im, void **obuf, size_t *olen,
|
||||
const char *format, const size_t quality )
|
||||
{
|
||||
Write *write;
|
||||
|
||||
if( !(write = write_new( im, NULL, format, quality )) )
|
||||
return( -1 );
|
||||
|
||||
if ( magick_create_images( write ) ) {
|
||||
vips_error( "magick2vips", _( "unable to write buffer \n"
|
||||
"libMagick error: %s %s" ),
|
||||
write->exception->reason, write->exception->description );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
if( magick_write_images_buf( write, obuf, olen ) ) {
|
||||
vips_error( "magick2vips", _( "unable to write buffer \n"
|
||||
"libMagick error: %s %s" ),
|
||||
write->exception->reason, write->exception->description );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
typedef struct _VipsForeignSaveMagick {
|
||||
VipsForeignSave parent_object;
|
||||
|
||||
@ -119,7 +541,7 @@ vips_foreign_save_magick_file_build( VipsObject *object )
|
||||
build( object ) )
|
||||
return( -1 );
|
||||
|
||||
if( vips__magick_write( save->ready, file->filename, file->format,
|
||||
if( magick_write( save->ready, file->filename, file->format,
|
||||
file->quality ) )
|
||||
return( -1 );
|
||||
|
||||
@ -199,7 +621,7 @@ vips_foreign_save_magick_buffer_build( VipsObject *object )
|
||||
build( object ) )
|
||||
return( -1 );
|
||||
|
||||
if( vips__magick_write_buf( save->ready, &obuf, &olen,
|
||||
if( magick_write_buf( save->ready, &obuf, &olen,
|
||||
buffer->format, buffer->quality ) )
|
||||
return( -1 );
|
||||
|
||||
@ -252,4 +674,4 @@ vips_foreign_save_magick_buffer_init( VipsForeignSaveMagickBuffer *buffer )
|
||||
{
|
||||
}
|
||||
|
||||
#endif /*HAVE_MAGICK || HAVE_MAGICK7*/
|
||||
#endif /*HAVE_MAGICKSAVE*/
|
||||
|
@ -132,11 +132,6 @@ int 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 );
|
||||
|
||||
int vips__magick_write( VipsImage *in, const char *filename,
|
||||
const char *format, const size_t quality );
|
||||
int vips__magick_write_buf( VipsImage *in, void **obuf, size_t *olen,
|
||||
const char *format, const size_t quality );
|
||||
|
||||
extern const char *vips__mat_suffs[];
|
||||
|
||||
int vips__mat_load( const char *filename, VipsImage *out );
|
||||
|
Loading…
Reference in New Issue
Block a user