change exif names argh

change exif names again: we were storing under @title, but that's both
subject to i18n, and unlookupable in libexif

we now use @name, which is not subject to i18n and can be searched for
... this will break most code which expects certain exif tag names

also, when we update exif, allow any tag, not just updates to existing
tags, see:

https://github.com/lovell/sharp/issues/189
This commit is contained in:
John Cupitt 2015-07-15 13:27:47 +01:00
parent ee0f082059
commit fbe321eebf
3 changed files with 56 additions and 31 deletions

View File

@ -13,6 +13,8 @@
- dzsave supports zip output > 4gb, thanks benjamin
- add support for HSV colourspace [Jonas Øgaard]
- skip oversized markers in jpeg write
- jpeg exif tags saved as name rather than title
- can now set any jpeg exif tag, not just modify existing tags
7/5/15 started 8.0.3
- dzsave and tif pyr write could fail for some image dimensions, thanks Jonas

View File

@ -67,6 +67,8 @@
* 26/2/15
* - close the jpeg read down early for a header read ... this saves an
* fd during jpg read, handy for large numbers of input images
* 15/7/15
* - save exif tags using @name, not @title ... @title is subject to i18n
*/
/*
@ -492,7 +494,7 @@ attach_exif_entry( ExifEntry *entry, VipsExif *ve )
vips_buf_appendf( &name, "exif-ifd%d-%s",
exif_entry_get_ifd( entry ),
exif_tag_get_title( entry->tag ) );
exif_tag_get_name( entry->tag ) );
vips_exif_to_s( ve->ed, entry, &value );
/* Can't do anything sensible with the error return.

View File

@ -67,6 +67,9 @@
* - support "none" as a resolution unit
* 8/7/15
* - omit oversized jpeg markers
* 15/7/15
* - exif tags use @name, not @title
* - set arbitrary exif tags from metadata
*/
/*
@ -111,6 +114,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <setjmp.h>
#include <math.h>
@ -580,49 +584,66 @@ vips_exif_from_s( ExifData *ed, ExifEntry *entry, const char *value )
}
}
typedef struct _VipsExif {
VipsImage *image;
ExifData *ed;
ExifContent *content;
} VipsExif;
static void
vips_exif_update_entry( ExifEntry *entry, VipsExif *ve )
static void
vips_exif_set_entry( ExifData *ed, ExifEntry *entry,
unsigned long component, void *data )
{
char name[256];
const char *value;
const char *string = (const char *) data;
vips_snprintf( name, 256, "exif-ifd%d-%s",
exif_entry_get_ifd( entry ),
exif_tag_get_title( entry->tag ) );
if( vips_image_get_typeof( ve->image, name ) ) {
(void) vips_image_get_string( ve->image, name, &value );
vips_exif_from_s( ve->ed, entry, value );
}
else
exif_content_remove_entry( ve->content, entry );
vips_exif_from_s( ed, entry, string );
}
static void
vips_exif_update_content( ExifContent *content, VipsExif *ve )
static void *
vips_exif_image_field( VipsImage *image,
const char *field, GValue *value, void *data )
{
ve->content = content;
exif_content_foreach_entry( content,
(ExifContentForeachEntryFunc) vips_exif_update_entry, ve );
ExifData *ed = (ExifData *) data;
const char *string;
int ifd;
const char *p;
ExifTag tag;
if( !vips_isprefix( "exif-ifd", field ) )
return( NULL );
/* value must be a string.
*/
if( vips_image_get_string( image, field, &string ) ) {
vips_warn( "VipsJpeg", _( "bad exif meta \"%s\"" ), field );
return( NULL );
}
p = field + strlen( "exif-ifd" );
ifd = atoi( p );
for( ; isdigit( *p ); p++ )
;
if( *p != '-' ) {
vips_warn( "VipsJpeg", _( "bad exif meta \"%s\"" ), field );
return( NULL );
}
if( !(tag = exif_tag_from_name( p + 1 )) ) {
vips_warn( "VipsJpeg", _( "bad exif meta \"%s\"" ), field );
return( NULL );
}
VIPS_DEBUG_MSG( "vips_exif_image_field: %s = %s\n", p + 1, string );
write_tag( ed, ifd, tag, vips_exif_set_entry, (void *) string );
return( NULL );
}
static void
vips_exif_update( ExifData *ed, VipsImage *image )
{
VipsExif ve;
VIPS_DEBUG_MSG( "vips_exif_update: \n" );
ve.image = image;
ve.ed = ed;
exif_data_foreach_content( ed,
(ExifDataForeachContentFunc) vips_exif_update_content, &ve );
vips_image_map( image,
vips_exif_image_field, ed );
}
#endif /*HAVE_EXIF*/
static int