im_jpeg2vips() ignores weird APP1 chunks

Some JPEGs seem to have multiple APP1 chunks. There should only be one,
and it should only contain EXIF data (I think), but some seem to have
many.

This was causing problems: the loader was trying to read exif
from all chunks, and a second chunk with invalid data was zapping the
stored exif meta tag. As a result, things like

  vips im_copy a.jpg b.jpg

would appear to lose EXIF info if a.jpg had spurious APP1.
This commit is contained in:
John Cupitt 2011-02-21 17:01:00 +00:00
parent d5d312aa91
commit a7d2288bad
4 changed files with 27 additions and 18 deletions

View File

@ -31,6 +31,7 @@
- set MAP_NOCACHE on OS X, otherwise performance dives off a cliff with
files larger than memory
- removed man pages, we are all gtk-doc now
- im_jpeg2vips() ignores weird APP1 chunks
30/11/10 started 7.24.0
- bump for new stable

View File

@ -30,6 +30,9 @@
* - gtkdoc
* 4/12/10
* - attach the jpeg thumbnail and multiscan fields (thanks Mike)
* 21/2/10
* - only accept the first APP1 block which starts "Exif..." as exif
* data, some jpegs seem to have several APP1s, argh
*/
/*
@ -59,8 +62,8 @@
*/
/*
#define DEBUG
#define DEBUG_VERBOSE
#define DEBUG
*/
#ifdef HAVE_CONFIG_H
@ -396,7 +399,18 @@ attach_thumbnail( IMAGE *im, ExifData *ed )
static int
read_exif( IMAGE *im, void *data, int data_length )
{
char *data_copy;
char *data_copy;
/* Horrifyingly, some JPEGs have several APP1 sections. We must only
* use the first one that starts "Exif.."
*/
if( ((char *) data)[0] != 'E' ||
((char *) data)[1] != 'x' ||
((char *) data)[2] != 'i' ||
((char *) data)[3] != 'f' )
return( 0 );
if( im_header_get_typeof( im, IM_META_EXIF_NAME ) )
return( 0 );
/* Always attach a copy of the unparsed exif data.
*/
@ -424,10 +438,11 @@ char *data_copy;
/* Attach informational fields for what we find.
FIXME ... better to have this in the UI layer?
FIXME ... better to have this in the UI layer?
Or we could attach non-human-readable tags here (int, double
etc) and then move the human stuff to the UI layer?
Or we could attach non-human-readable tags here (int,
double etc) and then move the human stuff to the UI
layer?
*/
exif_data_foreach_content( ed,
@ -521,7 +536,7 @@ read_jpeg_header( struct jpeg_decompress_struct *cinfo,
/* EXIF data.
*/
#ifdef DEBUG
printf( "read_jpeg_header: seen %d bytes of EXIF\n",
printf( "read_jpeg_header: seen %d bytes of APP1\n",
p->data_length );
#endif /*DEBUG*/
if( read_exif( out, p->data, p->data_length ) )
@ -532,7 +547,7 @@ read_jpeg_header( struct jpeg_decompress_struct *cinfo,
/* ICC profile.
*/
#ifdef DEBUG
printf( "read_jpeg_header: seen %d bytes of ICC\n",
printf( "read_jpeg_header: seen %d bytes of APP2\n",
p->data_length );
#endif /*DEBUG*/

View File

@ -376,7 +376,7 @@ write_exif( Write *write )
else
ed = exif_data_new();
/* Set EXIF resolution from VIPS.
/* Update EXIF resolution from VIPS.
*/
if( set_exif_resolution( ed, write->in ) ) {
exif_data_free( ed );

View File

@ -1,13 +1,4 @@
/* @(#) Function which copies IMAGE descriptor image2 to image1;
* @(#) data, fd and filename are not copied
* @(#) used to make programs simpler by copying most parameters
* @(#)
* @(#) int
* @(#) im_cp_desc( image1, image2 )
* @(#) IMAGE *image1, *image2;
* @(#)
* @(#) Returns 0 on success or -1 on fail.
* @(#)
/* copy descriptors between images
*
* Copyright: Nicos Dessipris
* Written on: 09/02/1990
@ -30,6 +21,8 @@
* - simplified ... no more skip the first line stuff
* 4/1/07
* - merge hists with history_list instead
* 20/1/10
* - gtk-doc
*/
/*