Permalink
Browse files

fix up and test with im6/im7/gm

seems to work! phew
  • Loading branch information...
jcupitt committed Feb 7, 2019
1 parent 90fef08 commit 931b661d2b4275a1a3f142819cdfe61c94142c15
@@ -20,7 +20,7 @@
- fix race in temp filename creation [lhecker]
- add @reduction_effort param to webpsave [lovell]
- add @option_string param to thumbnail_buffer [kleisauke]
- add XMP, IPCT, ICC etc. to magickload
- add XMP, IPCT, ICC, EXIF etc. support to magickload/magicksave

4/1/19 started 8.7.4
- magickload with magick6 API did not chain exceptions correctly causing a
@@ -43,6 +43,7 @@
#include <string.h>

#include <vips/vips.h>
#include <vips/internal.h>

#include "pforeign.h"
#include "magick.h"
@@ -107,6 +108,28 @@ magick_set_profile( Image *image,
return( result );
}

void *
magick_profile_map( Image *image, MagickMapProfileFn fn, void *a )
{
char *name;

ResetImageProfileIterator( image );
while( (name = GetNextImageProfile( image )) ) {
const StringInfo *profile;
void *data;
size_t length;
void *result;

profile = GetImageProfile( image, name );
data = GetStringInfoDatum( profile );
length = GetStringInfoLength( profile );
if( (result = fn( image, name, data, length, a )) )
return( result );
}

return( NULL );
}

ExceptionInfo *
magick_acquire_exception( void )
{
@@ -262,6 +285,44 @@ magick_set_profile( Image *image,
return( result );
}

void *
magick_profile_map( Image *image, MagickMapProfileFn fn, void *a )
{
const char *name;
const void *data;
size_t length;
void *result;

#ifdef HAVE_RESETIMAGEPROFILEITERATOR
ResetImageProfileIterator( image );
while( (name = GetNextImageProfile( image )) ) {
const StringInfo *profile;

profile = GetImageProfile( image, name );
data = GetStringInfoDatum( profile );
length = GetStringInfoLength( profile );
if( (result = fn( image, name, data, length, a )) )
return( result );
}
#else /*!HAVE_RESETIMAGEPROFILEITERATOR*/
{
ImageProfileIterator *iter;

iter = AllocateImageProfileIterator( image );
while( NextImageProfile( iter,
&name, (const unsigned char **) &data, &length ) ) {
if( (result = fn( image, name, data, length, a )) ) {
DeallocateImageProfileIterator( iter );
return( result );
}
}
DeallocateImageProfileIterator( iter );
}
#endif /*HAVE_RESETIMAGEPROFILEITERATOR*/

return( NULL );
}

ExceptionInfo *
magick_acquire_exception( void )
{
@@ -422,4 +483,101 @@ magick_genesis( void )
VIPS_ONCE( &once, magick_genesis_cb, NULL );
}

/* Set vips metadata from a magick profile.
*/
static void *
magick_set_vips_profile_cb( Image *image,
const char *name, const void *data, size_t length, void *a )
{
VipsImage *im = (VipsImage *) a;

char name_text[256];
VipsBuf vips_name = VIPS_BUF_STATIC( name_text );

if( strcmp( name, "XMP" ) == 0 )
vips_buf_appendf( &vips_name, VIPS_META_XMP_NAME );
else if( strcmp( name, "IPTC" ) == 0 )
vips_buf_appendf( &vips_name, VIPS_META_IPTC_NAME );
else if( strcmp( name, "ICM" ) == 0 )
vips_buf_appendf( &vips_name, VIPS_META_ICC_NAME );
else if( strcmp( name, "EXIF" ) == 0 )
vips_buf_appendf( &vips_name, VIPS_META_EXIF_NAME );
else
vips_buf_appendf( &vips_name, "magickprofile-%s", name );

vips_image_set_blob_copy( im,
vips_buf_all( &vips_name ), data, length );

if( strcmp( name, "exif" ) == 0 )
(void) vips__exif_parse( im );

return( NULL );
}

/* Set vips metadata from ImageMagick profiles.
*/
int
magick_set_vips_profile( VipsImage *im, Image *image )
{
if( magick_profile_map( image, magick_set_vips_profile_cb, im ) )
return( -1 );

return( 0 );
}

typedef struct {
Image *image;
ExceptionInfo *exception;
} CopyProfileInfo;

static void *
magick_set_magick_profile_cb( VipsImage *im,
const char *name, GValue *value, CopyProfileInfo *info )
{
char txt[256];
VipsBuf buf = VIPS_BUF_STATIC( txt );
const void *data;
size_t length;

if( strcmp( name, VIPS_META_XMP_NAME ) == 0 )
vips_buf_appendf( &buf, "XMP" );
else if( strcmp( name, VIPS_META_IPTC_NAME ) == 0 )
vips_buf_appendf( &buf, "IPTC" );
else if( strcmp( name, VIPS_META_ICC_NAME ) == 0 )
vips_buf_appendf( &buf, "ICM" );
else if( strcmp( name, VIPS_META_EXIF_NAME ) == 0 )
vips_buf_appendf( &buf, "EXIF" );
else if( vips_isprefix( "magickprofile-", name ) )
vips_buf_appendf( &buf,
"%s", name + strlen( "magickprofile-" ) );

if( vips_buf_is_empty( &buf ) )
return( NULL );
if( !vips_image_get_typeof( im, name ) )
return( NULL );
if( vips_image_get_blob( im, name, &data, &length ) )
return( im );

if( !magick_set_profile( info->image,
vips_buf_all( &buf ), data, length, info->exception ) )
return( im );

return( NULL );
}

int
magick_set_magick_profile( Image *image,
VipsImage *im, ExceptionInfo *exception )
{
CopyProfileInfo info;

info.image = image;
info.exception = exception;
if( vips_image_map( im,
(VipsImageMapFn) magick_set_magick_profile_cb, &info ) )
return( -1 );

return( 0 );
}

#endif /*HAVE_MAGICK*/
@@ -55,6 +55,9 @@ void *magick_images_to_blob( const ImageInfo *image_info, Image *images,
size_t *length, ExceptionInfo *exception );
void magick_set_property( Image *image,
const char *property, const char *value, ExceptionInfo *exception );
typedef void *(*MagickMapProfileFn)( Image *image,
const char *name, const void *data, size_t length, void *a );
void *magick_profile_map( Image *image, MagickMapProfileFn fn, void *a );
int magick_set_profile( Image *image,
const char *name, const void *data, size_t length,
ExceptionInfo *exception );
@@ -74,4 +77,8 @@ void magick_vips_error( const char *domain, ExceptionInfo *exception );

void magick_genesis( void );

int magick_set_vips_profile( VipsImage *im, Image *image );
int magick_set_magick_profile( Image *image,
VipsImage *im, ExceptionInfo *exception );

#endif /*HAVE_MAGICK6*/
@@ -112,6 +112,7 @@
#include <sys/types.h>

#include <vips/vips.h>
#include <vips/internal.h>

#include <magick/api.h>

@@ -423,43 +424,10 @@ parse_header( Read *read )

vips_image_pipelinev( im, VIPS_DEMAND_STYLE_SMALLTILE, NULL );

#ifdef HAVE_RESETIMAGEPROFILEITERATOR
{
/* "Profiles" are things like icc profiles, xmp, iptc, etc. and are
* stored as blobs, since they may contain embedded \0.
/* Set vips metadata from ImageMagick profiles.
*/
char *key;

ResetImageProfileIterator( image );
while( (key = GetNextImageProfile( image )) ) {
char name_text[256];
VipsBuf name = VIPS_BUF_STATIC( name_text );
const StringInfo *profile;
void *data;
size_t length;

if( strcmp( key, "xmp" ) == 0 )
vips_buf_appendf( &name, VIPS_META_XMP_NAME );
else if( strcmp( key, "iptc" ) == 0 )
vips_buf_appendf( &name, VIPS_META_IPTC_NAME );
else if( strcmp( key, "icc" ) == 0 )
vips_buf_appendf( &name, VIPS_META_ICC_NAME );
else if( strcmp( key, "exif" ) == 0 )
vips_buf_appendf( &name, VIPS_META_EXIF_NAME );
else
vips_buf_appendf( &name, "magickprofile-%s", key );

profile = GetImageProfile( image, key );
data = GetStringInfoDatum( profile );
length = GetStringInfoLength( profile );
vips_image_set_blob_copy( im, vips_buf_all( &name ),
data, length );

if( strcmp( key, "exif" ) == 0 )
(void) vips__exif_parse( im );
}
}
#endif /*HAVE_RESETIMAGEPROFILEITERATOR*/
if( magick_set_vips_profile( im, image ) )
return( -1 );

#ifdef HAVE_RESETIMAGEPROPERTYITERATOR
{
@@ -546,36 +546,10 @@ vips_foreign_load_magick7_parse( VipsForeignLoadMagick7 *magick7,
vips_image_set_string( out, vips_buf_all( &name ), value );
}

/* All the binary metadata.
/* Set vips metadata from ImageMagick profiles.
*/
ResetImageProfileIterator( image );
while( (key = GetNextImageProfile( image )) ) {
char name_text[256];
VipsBuf name = VIPS_BUF_STATIC( name_text );
const StringInfo *profile;
void *data;
size_t length;

if( strcmp( key, "xmp" ) == 0 )
vips_buf_appendf( &name, VIPS_META_XMP_NAME );
else if( strcmp( key, "iptc" ) == 0 )
vips_buf_appendf( &name, VIPS_META_IPTC_NAME );
else if( strcmp( key, "icc" ) == 0 )
vips_buf_appendf( &name, VIPS_META_ICC_NAME );
else if( strcmp( key, "exif" ) == 0 )
vips_buf_appendf( &name, VIPS_META_EXIF_NAME );
else
vips_buf_appendf( &name, "magickprofile-%s", key );

profile = GetImageProfile( image, key );
data = GetStringInfoDatum( profile );
length = GetStringInfoLength( profile );
vips_image_set_blob_copy( out, vips_buf_all( &name ),
data, length );

if( strcmp( key, "exif" ) == 0 )
(void) vips__exif_parse( im );
}
if( magick_set_vips_profile( out, image ) )
return( -1 );

magick7->n_pages = GetImageListLength( GetFirstImageInList( image ) );
#ifdef DEBUG
@@ -89,59 +89,14 @@ vips_foreign_save_magick_dispose( GObject *gobject )
dispose( gobject );
}

typedef struct {
VipsForeignSaveMagick *magick;
Image *image;
} CopyProfileInfo;

static void *
vips_foreign_save_magick_copy_profile( VipsImage *im,
const char *name, GValue *value, CopyProfileInfo *info )
{
char txt[256];
VipsBuf buf = VIPS_BUF_STATIC( txt );
const void *data;
size_t length;
int result;

if( strcmp( name, VIPS_META_XMP_NAME ) == 0 )
vips_buf_appendf( &buf, "xmp" );
else if( strcmp( name, VIPS_META_IPTC_NAME ) == 0 )
vips_buf_appendf( &buf, "iptc" );
else if( strcmp( name, VIPS_META_ICC_NAME ) == 0 )
vips_buf_appendf( &buf, "icc" );
else if( strcmp( name, VIPS_META_EXIF_NAME ) == 0 )
vips_buf_appendf( &buf, "exif" );
else if( vips_isprefix( "magickprofile-", name ) )
vips_buf_appendf( &buf,
"%s", name + strlen( "magickprofile-" ) );

if( vips_buf_is_empty( &buf ) )
return( NULL );
if( !vips_image_get_typeof( im, name ) )
return( NULL );
if( vips_image_get_blob( im, name, &data, &length ) )
return( im );

result = magick_set_profile( info->image,
vips_buf_all( &buf ), data, length, info->magick->exception );
if( !result ) {
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( info->magick );

magick_vips_error( class->nickname, info->magick->exception );
return( im );
}

return( NULL );
}

static int
vips_foreign_save_magick_set_properties( VipsForeignSaveMagick *magick,
Image *image, VipsImage *im )
{
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( magick );

int number;
const char *str;
CopyProfileInfo info;

if( vips_image_get_typeof( im, "gif-delay" ) &&
!vips_image_get_int( im, "gif-delay", &number ) )
@@ -155,12 +110,10 @@ vips_foreign_save_magick_set_properties( VipsForeignSaveMagick *magick,
!vips_image_get_string( im, "gif-comment", &str ) )
magick_set_property( image, "comment", str, magick->exception );

info.magick = magick;
info.image = image;
if( vips_image_map( im,
(VipsImageMapFn) vips_foreign_save_magick_copy_profile,
&info ) )
return( -1 );
if( magick_set_magick_profile( image, im, magick->exception ) ) {
magick_vips_error( class->nickname, magick->exception );
return( -1 );
}

return( 0 );
}
Oops, something went wrong.

0 comments on commit 931b661

Please sign in to comment.