diff --git a/ChangeLog b/ChangeLog index 8d23884b..b969473d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,7 @@ - added pbm (one bit) save - changed vips_gaussblur() parameters, sorry - add .szi as a dzsave zip synonym +- support tiff XMP metadata 25/7/14 started 7.41.0 - start working on --disable-deprecated diff --git a/libvips/foreign/foreign.c b/libvips/foreign/foreign.c index 404f2db3..d7d470fe 100644 --- a/libvips/foreign/foreign.c +++ b/libvips/foreign/foreign.c @@ -1679,7 +1679,8 @@ vips_magickload( const char *filename, VipsImage **out, ... ) * @page means load this page from the file. By default the first page (page * 0) is read. * - * Any ICC profile is read and attached to the VIPS image. + * Any ICC profile is read and attached to the VIPS image. Any XMP metadata is + * read and attached to the image. * * See also: vips_image_new_from_file(). * @@ -1811,6 +1812,9 @@ vips_tiffload_buffer( void *buf, size_t len, VipsImage **out, ... ) * Bigtiff is a variant of the TIFF * format that allows more than 4GB in a file. * + * If @in has a field called VIPS_META_XMP_NAME ("xmp-data") it is written to + * the tiff image. + * * See also: vips_tiffload(), vips_image_write_to_file(). * * Returns: 0 on success, -1 on error. diff --git a/libvips/foreign/tiff2vips.c b/libvips/foreign/tiff2vips.c index 5386f53a..1bfe73e0 100644 --- a/libvips/foreign/tiff2vips.c +++ b/libvips/foreign/tiff2vips.c @@ -150,6 +150,8 @@ * - 1/2/4 bit palette images can have alpha * 27/10/14 Lovell * - better istiff detector spots bigtiff + * 3/12/14 + * - read any XMP metadata */ /* @@ -1141,6 +1143,19 @@ parse_header( ReadTiff *rtiff, VipsImage *out ) (VipsCallbackFn) vips_free, data_copy, data_length ); } + /* Read any XMP metadata. + */ + if( TIFFGetField( rtiff->tiff, + TIFFTAG_XMLPACKET, &data_length, &data ) ) { + void *data_copy; + + if( !(data_copy = vips_malloc( NULL, data_length )) ) + return( -1 ); + memcpy( data_copy, data, data_length ); + vips_image_set_blob( out, VIPS_META_XMP_NAME, + (VipsCallbackFn) vips_free, data_copy, data_length ); + } + return( 0 ); } diff --git a/libvips/foreign/vips2tiff.c b/libvips/foreign/vips2tiff.c index e1d477e3e..d439dacf 100644 --- a/libvips/foreign/vips2tiff.c +++ b/libvips/foreign/vips2tiff.c @@ -139,7 +139,9 @@ * 26/1/14 * - add RGB as well as YCbCr write * 20/11/14 - * - cache input in tile write mode to keep us seqential + * - cache input in tile write mode to keep us sequential + * 3/12/14 + * - embed XMP in output */ /* @@ -455,6 +457,28 @@ embed_profile( TiffWrite *tw, TIFF *tif ) return( 0 ); } +/* Embed any XMP metadata. + */ +static int +embed_xmp( TiffWrite *tw, TIFF *tif ) +{ + void *data; + size_t data_length; + + if( !vips_image_get_typeof( tw->im, VIPS_META_XMP_NAME ) ) + return( 0 ); + if( vips_image_get_blob( tw->im, VIPS_META_XMP_NAME, + &data, &data_length ) ) + return( -1 ); + TIFFSetField( tif, TIFFTAG_XMLPACKET, data_length, data ); + +#ifdef DEBUG + printf( "vips2tiff: attached XMP from meta\n" ); +#endif /*DEBUG*/ + + return( 0 ); +} + /* Write a TIFF header. width and height are the size of the VipsImage we are * writing (may have been shrunk!). */ @@ -486,10 +510,10 @@ write_tiff_header( TiffWrite *tw, TIFF *tif, int width, int height ) TIFFSetField( tif, TIFFTAG_YRESOLUTION, VIPS_CLIP( 0.01, tw->yres, 10000 ) ); - /* Attach ICC profile. - */ if( embed_profile( tw, tif ) ) return( -1 ); + if( embed_xmp( tw, tif ) ) + return( -1 ); /* And colour fields. */ @@ -1466,10 +1490,12 @@ tiff_copy( TiffWrite *tw, TIFF *out, TIFF *in ) } } - /* We can't copy profiles :( Set again from TiffWrite. + /* We can't copy profiles or xmp :( Set again from TiffWrite. */ if( embed_profile( tw, out ) ) return( -1 ); + if( embed_xmp( tw, out ) ) + return( -1 ); buf = vips_malloc( NULL, TIFFTileSize( in ) ); n = TIFFNumberOfTiles( in );