From 5a4b4e196d648645ed5151d5739ce1e6071dbea2 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Thu, 1 Feb 2018 16:15:02 +0000 Subject: [PATCH] allow remove thumbnail from exif if the user has removed (or set to NULL) the "jpeg-thumbnail-data" tag, remove it from the image EXIF on save see https://github.com/jcupitt/ruby-vips/issues/147 --- ChangeLog | 2 ++ libvips/foreign/exif.c | 51 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/ChangeLog b/ChangeLog index 9a9e471d..27d1f6b0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 23/12/17 started 8.7.0 - add magicksave, save image with libMagick [dlemstra] +- remove jpeg thumbnail from EXIF if "jpeg-thumbnail-data" has been removed by + user 5/1/18 started 8.6.2 - vips_sink_screen() keeps a ref to the input image ... stops a rare race diff --git a/libvips/foreign/exif.c b/libvips/foreign/exif.c index c36de7e5..efef0cf7 100644 --- a/libvips/foreign/exif.c +++ b/libvips/foreign/exif.c @@ -5,6 +5,8 @@ * - from jpeg2vips * 14/10/17 * - only read orientation from ifd0 + * 1/2/18 + * - remove exif thumbnail if "jpeg-thumbnail-data" has been removed */ /* @@ -827,6 +829,48 @@ vips_exif_set_orientation( ExifData *ed, VipsImage *im ) return( 0 ); } +/* And thumbnail. + */ +static int +vips_exif_set_thumbnail( ExifData *ed, VipsImage *im ) +{ + /* Delete any old thumbnail data. We should use the exif free func, + * but the memory allocator is not exposed by libexif! Hopefully they + * are just using free(). + * + * exif.c makes this assumption too when it tries to update a + * thumbnail. + */ + if( ed->data ) { + free( ed->data ); + ed->data = NULL; + } + ed->size = 0; + + /* Update EXIF thumbnail from metadata, if any. + */ + if( vips_image_get_typeof( im, "jpeg-thumbnail-data" ) ) { + void *data; + size_t length; + + if( !vips_image_get_blob( im, "jpeg-thumbnail-data", + &data, &length ) ) + return( -1 ); + + /* Again, we should use the exif allocator attached to this + * entry, but it is not exposed! + */ + if( length > 0 && + data ) { + ed->data = malloc( length ); + memcpy( ed->data, data, length ); + ed->size = length; + } + } + + return( 0 ); +} + /* See also vips_exif_to_s() ... keep in sync. */ static void @@ -1079,6 +1123,13 @@ vips__exif_update( VipsImage *image ) return( -1 ); } + /* Update the thumbnail. + */ + if( vips_exif_set_thumbnail( ed, image ) ) { + exif_data_free( ed ); + return( -1 ); + } + /* Reserialise and write. exif_data_save_data() returns an int for some * reason. */