add xmp/ipct/icc etc. to magickload

ImageMagick supports binary metadata with `ResetImageProfileIterator()`
etc.

Implementing support gives us xmp / ipct / icc support, plus perhaps
some others.
This commit is contained in:
John Cupitt 2019-02-04 17:54:57 +00:00
parent 38bd4f1be4
commit 8d5af9fe8a
4 changed files with 73 additions and 2 deletions

View File

@ -20,6 +20,7 @@
- fix race in temp filename creation [lhecker] - fix race in temp filename creation [lhecker]
- add @reduction_effort param to webpsave [lovell] - add @reduction_effort param to webpsave [lovell]
- add @option_string param to thumbnail_buffer [kleisauke] - add @option_string param to thumbnail_buffer [kleisauke]
- add XMP, IPCT, ICC etc. to magickload
4/1/19 started 8.7.4 4/1/19 started 8.7.4
- magickload with magick6 API did not chain exceptions correctly causing a - magickload with magick6 API did not chain exceptions correctly causing a

View File

@ -700,6 +700,16 @@ if test x"$magick6" = x"yes"; then
LIBS="$save_LIBS" LIBS="$save_LIBS"
fi fi
if test x"$magick6" = x"yes"; then
# GM does not have ResetImageProfileIterator
save_LIBS="$LIBS"
LIBS="$LIBS $MAGICK_LIBS"
AC_CHECK_FUNCS(ResetImageProfileIterator,
AC_DEFINE(HAVE_RESETIMAGEPROFILEITERATOR,1,
[define if your magick has ResetImageProfileIterator.]))
LIBS="$save_LIBS"
fi
if test x"$magick6" = x"yes"; then if test x"$magick6" = x"yes"; then
# more recent magicks have GetVirtualPixels rather than GetImagePixels # more recent magicks have GetVirtualPixels rather than GetImagePixels
save_LIBS="$LIBS" save_LIBS="$LIBS"

View File

@ -62,6 +62,8 @@
* 4/1/19 kleisauke * 4/1/19 kleisauke
* - we did not chain exceptions correctly, causing a memory leak * - we did not chain exceptions correctly, causing a memory leak
* - added wrapper funcs for exception handling * - added wrapper funcs for exception handling
* 4/2/19
* - add profile (xmp, ipct, etc.) read
*/ */
/* /*
@ -421,8 +423,38 @@ parse_header( Read *read )
vips_image_pipelinev( im, VIPS_DEMAND_STYLE_SMALLTILE, NULL ); vips_image_pipelinev( im, VIPS_DEMAND_STYLE_SMALLTILE, NULL );
/* Three ways to loop over attributes / properties :-( #ifdef HAVE_RESETIMAGEPROFILEITERATOR
{
/* "Profiles" are things like icc profiles, xmp, iptc, etc. and are
* stored as blobs, since they may contain embedded \0.
*/ */
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
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 );
}
}
#endif /*HAVE_RESETIMAGEPROFILEITERATOR*/
#ifdef HAVE_RESETIMAGEPROPERTYITERATOR #ifdef HAVE_RESETIMAGEPROPERTYITERATOR
{ {

View File

@ -6,6 +6,8 @@
* - add @n, deprecate @all_frames (just sets n = -1) * - add @n, deprecate @all_frames (just sets n = -1)
* 24/7/18 * 24/7/18
* - sniff extra filetypes * - sniff extra filetypes
* 4/2/19
* - add profile (xmp, ipct, etc.) read
*/ */
/* /*
@ -527,7 +529,7 @@ vips_foreign_load_magick7_parse( VipsForeignLoadMagick7 *magick7,
vips_image_pipelinev( out, VIPS_DEMAND_STYLE_SMALLTILE, NULL ); vips_image_pipelinev( out, VIPS_DEMAND_STYLE_SMALLTILE, NULL );
/* Get all the metadata. /* Get all the string metadata.
*/ */
ResetImagePropertyIterator( image ); ResetImagePropertyIterator( image );
while( (key = GetNextImageProperty( image )) ) { while( (key = GetNextImageProperty( image )) ) {
@ -544,6 +546,32 @@ vips_foreign_load_magick7_parse( VipsForeignLoadMagick7 *magick7,
vips_image_set_string( out, vips_buf_all( &name ), value ); vips_image_set_string( out, vips_buf_all( &name ), value );
} }
/* All the binary metadata.
*/
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
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 );
}
magick7->n_pages = GetImageListLength( GetFirstImageInList( image ) ); magick7->n_pages = GetImageListLength( GetFirstImageInList( image ) );
#ifdef DEBUG #ifdef DEBUG
printf( "image has %d pages\n", magick7->n_pages ); printf( "image has %d pages\n", magick7->n_pages );