Merge pull request #518 from UlysseM/master
Better support for exif resolution
This commit is contained in:
commit
9f9c077974
|
@ -76,6 +76,9 @@
|
||||||
* - switch to new orientation tag
|
* - switch to new orientation tag
|
||||||
* 11/7/16
|
* 11/7/16
|
||||||
* - new --fail handling
|
* - new --fail handling
|
||||||
|
* 07/09/16
|
||||||
|
* - Don't use the exif resolution if x_resolution / y_resolution /
|
||||||
|
* resolution_unit is missing
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -347,6 +350,19 @@ show_values( ExifData *data )
|
||||||
#endif /*HAVE_EXIF*/
|
#endif /*HAVE_EXIF*/
|
||||||
|
|
||||||
#ifdef HAVE_EXIF
|
#ifdef HAVE_EXIF
|
||||||
|
static ExifData*
|
||||||
|
vips_exif_load_data_without_fix(const unsigned char* data, unsigned int size)
|
||||||
|
{
|
||||||
|
ExifData *edata = exif_data_new();
|
||||||
|
|
||||||
|
if ( !edata )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
exif_data_unset_option(edata, EXIF_DATA_OPTION_FOLLOW_SPECIFICATION);
|
||||||
|
exif_data_load_data (edata, data, size);
|
||||||
|
return edata;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
vips_exif_get_int( ExifData *ed,
|
vips_exif_get_int( ExifData *ed,
|
||||||
ExifEntry *entry, unsigned long component, int *out )
|
ExifEntry *entry, unsigned long component, int *out )
|
||||||
|
@ -526,6 +542,34 @@ get_entry_double( ExifData *ed, int ifd, ExifTag tag, double *out )
|
||||||
return( vips_exif_get_double( ed, entry, 0, out ) );
|
return( vips_exif_get_double( ed, entry, 0, out ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_entry_double( ExifData *ed, int ifd, ExifTag tag, double in)
|
||||||
|
{
|
||||||
|
ExifEntry *entry;
|
||||||
|
|
||||||
|
if( (entry = exif_content_get_entry( ed->ifd[ifd], tag )) ) {
|
||||||
|
/* Let's remove the current value */
|
||||||
|
exif_content_remove_entry( ed->ifd[ifd], entry );
|
||||||
|
entry = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !( entry = exif_entry_new() ) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
entry->tag = tag;
|
||||||
|
exif_content_add_entry( ed->ifd[ifd], entry );
|
||||||
|
|
||||||
|
exif_entry_initialize( entry, tag );
|
||||||
|
|
||||||
|
/* This is a simple yet sufficient implementation */
|
||||||
|
ExifRational value;
|
||||||
|
value.numerator = in * 1000;
|
||||||
|
value.denominator = 1000;
|
||||||
|
|
||||||
|
if ( entry->data )
|
||||||
|
exif_set_rational( entry->data, exif_data_get_byte_order( ed ), value );
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
get_entry_int( ExifData *ed, int ifd, ExifTag tag, int *out )
|
get_entry_int( ExifData *ed, int ifd, ExifTag tag, int *out )
|
||||||
{
|
{
|
||||||
|
@ -538,7 +582,7 @@ get_entry_int( ExifData *ed, int ifd, ExifTag tag, int *out )
|
||||||
return( vips_exif_get_int( ed, entry, 0, out ) );
|
return( vips_exif_get_int( ed, entry, 0, out ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static int
|
||||||
res_from_exif( VipsImage *im, ExifData *ed )
|
res_from_exif( VipsImage *im, ExifData *ed )
|
||||||
{
|
{
|
||||||
double xres, yres;
|
double xres, yres;
|
||||||
|
@ -552,7 +596,7 @@ res_from_exif( VipsImage *im, ExifData *ed )
|
||||||
get_entry_int( ed, 0, EXIF_TAG_RESOLUTION_UNIT, &unit ) ) {
|
get_entry_int( ed, 0, EXIF_TAG_RESOLUTION_UNIT, &unit ) ) {
|
||||||
vips_warn( "VipsJpeg",
|
vips_warn( "VipsJpeg",
|
||||||
"%s", _( "error reading resolution" ) );
|
"%s", _( "error reading resolution" ) );
|
||||||
return;
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -589,7 +633,7 @@ res_from_exif( VipsImage *im, ExifData *ed )
|
||||||
default:
|
default:
|
||||||
vips_warn( "VipsJpeg",
|
vips_warn( "VipsJpeg",
|
||||||
"%s", _( "unknown EXIF resolution unit" ) );
|
"%s", _( "unknown EXIF resolution unit" ) );
|
||||||
return;
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -599,6 +643,8 @@ res_from_exif( VipsImage *im, ExifData *ed )
|
||||||
|
|
||||||
im->Xres = xres;
|
im->Xres = xres;
|
||||||
im->Yres = yres;
|
im->Yres = yres;
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -626,7 +672,7 @@ parse_exif( VipsImage *im, void *data, int data_length )
|
||||||
ExifData *ed;
|
ExifData *ed;
|
||||||
VipsExif ve;
|
VipsExif ve;
|
||||||
|
|
||||||
if( !(ed = exif_data_new_from_data( data, data_length )) )
|
if( !(ed = vips_exif_load_data_without_fix( data, data_length )) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
#ifdef DEBUG_VERBOSE
|
#ifdef DEBUG_VERBOSE
|
||||||
|
@ -645,16 +691,23 @@ parse_exif( VipsImage *im, void *data, int data_length )
|
||||||
*/
|
*/
|
||||||
ve.image = im;
|
ve.image = im;
|
||||||
ve.ed = ed;
|
ve.ed = ed;
|
||||||
exif_data_foreach_content( ed,
|
|
||||||
(ExifDataForeachContentFunc) attach_exif_content, &ve );
|
|
||||||
|
|
||||||
/* Look for resolution fields and use them to set the VIPS
|
/* Look for resolution fields and use them to set the VIPS
|
||||||
* xres/yres fields.
|
* xres/yres fields.
|
||||||
|
* If the fields are missing, write the one from the jfif.
|
||||||
*/
|
*/
|
||||||
res_from_exif( im, ed );
|
if ( res_from_exif( im, ed ) ) {
|
||||||
|
set_entry_double( ed, 0, EXIF_TAG_X_RESOLUTION, im->Xres );
|
||||||
|
set_entry_double( ed, 0, EXIF_TAG_Y_RESOLUTION, im->Yres );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Let's make sure the fields are valid. */
|
||||||
|
exif_data_fix( ed );
|
||||||
|
|
||||||
|
exif_data_foreach_content( ed,
|
||||||
|
(ExifDataForeachContentFunc) attach_exif_content, &ve );
|
||||||
|
|
||||||
attach_thumbnail( im, ed );
|
attach_thumbnail( im, ed );
|
||||||
|
|
||||||
exif_data_free( ed );
|
exif_data_free( ed );
|
||||||
}
|
}
|
||||||
#endif /*HAVE_EXIF*/
|
#endif /*HAVE_EXIF*/
|
||||||
|
|
Loading…
Reference in New Issue