load and save XMP metadata in tiff

see https://github.com/jcupitt/libvips/issues/198
This commit is contained in:
John Cupitt 2014-12-03 09:03:09 +00:00
parent 90b78fe9c6
commit f8cca8e59d
4 changed files with 51 additions and 5 deletions

View File

@ -4,6 +4,7 @@
- added pbm (one bit) save - added pbm (one bit) save
- changed vips_gaussblur() parameters, sorry - changed vips_gaussblur() parameters, sorry
- add .szi as a dzsave zip synonym - add .szi as a dzsave zip synonym
- support tiff XMP metadata
25/7/14 started 7.41.0 25/7/14 started 7.41.0
- start working on --disable-deprecated - start working on --disable-deprecated

View File

@ -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 * @page means load this page from the file. By default the first page (page
* 0) is read. * 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(). * 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 * Bigtiff is a variant of the TIFF
* format that allows more than 4GB in a file. * 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(). * See also: vips_tiffload(), vips_image_write_to_file().
* *
* Returns: 0 on success, -1 on error. * Returns: 0 on success, -1 on error.

View File

@ -150,6 +150,8 @@
* - 1/2/4 bit palette images can have alpha * - 1/2/4 bit palette images can have alpha
* 27/10/14 Lovell * 27/10/14 Lovell
* - better istiff detector spots bigtiff * - 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 ); (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 ); return( 0 );
} }

View File

@ -139,7 +139,9 @@
* 26/1/14 * 26/1/14
* - add RGB as well as YCbCr write * - add RGB as well as YCbCr write
* 20/11/14 * 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 ); 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 /* Write a TIFF header. width and height are the size of the VipsImage we are
* writing (may have been shrunk!). * writing (may have been shrunk!).
*/ */
@ -486,10 +510,10 @@ write_tiff_header( TiffWrite *tw, TIFF *tif, int width, int height )
TIFFSetField( tif, TIFFTAG_YRESOLUTION, TIFFSetField( tif, TIFFTAG_YRESOLUTION,
VIPS_CLIP( 0.01, tw->yres, 10000 ) ); VIPS_CLIP( 0.01, tw->yres, 10000 ) );
/* Attach ICC profile.
*/
if( embed_profile( tw, tif ) ) if( embed_profile( tw, tif ) )
return( -1 ); return( -1 );
if( embed_xmp( tw, tif ) )
return( -1 );
/* And colour fields. /* 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 ) ) if( embed_profile( tw, out ) )
return( -1 ); return( -1 );
if( embed_xmp( tw, out ) )
return( -1 );
buf = vips_malloc( NULL, TIFFTileSize( in ) ); buf = vips_malloc( NULL, TIFFTileSize( in ) );
n = TIFFNumberOfTiles( in ); n = TIFFNumberOfTiles( in );