[gdk-pixbuf] Fix parsing of JPEG orientation tag



commit ff9d69d5328abd846b2c66e3ed5ad0e90de8f5d8
Author: Tormod Volden <debian tormod gmail com>
Date:   Thu Nov 15 21:17:29 2012 +0100

    Fix parsing of JPEG orientation tag
    
    Parsing the orientation tag in big-endian file formats got broken in
    commit 0179dfd as reported in https://bugs.launchpad.net/bugs/1077186
    
    A short (16 bit) value like the orientation value occupies the two first
    bytes of the 4-byte offset field, independently of endianness. The
    commit changed the code from using de_get16() to de_get32 to read out
    this value, which broke on big-endian (MM/Motorola) byte order JPEG file
    formats. I believe little-endian files would still work as long as the
    two last, unused bytes were zero.
    
    From http://www.cipa.jp/english/hyoujunka/kikaku/pdf/DC-008-2010_E.pdf
    
    "Value Offset
    This tag records the offset from the start of the TIFF header to the
    position where the value itself is recorded. In cases where the value
    fits in 4 Bytes, the value itself is recorded. If the value is smaller
    than 4 Bytes, the value is stored in the 4-Byte area starting from the
    left, i.e., from the lower end of the byte offset area. For example, in
    big endian format, if the type is SHORT and the value is 1, it is
    recorded as 00010000.H."
    
    Also avoid the confusing recycling of the "offset" variable, use a
    better name for the second use and make it and its siblings
    local to the block where they are used.
    
    Signed-off-by: Tormod Volden <debian tormod gmail com>
    
    https://bugzilla.gnome.org/show_bug.cgi?id=688427

 gdk-pixbuf/io-jpeg.c |   14 ++++++--------
 1 files changed, 6 insertions(+), 8 deletions(-)
---
diff --git a/gdk-pixbuf/io-jpeg.c b/gdk-pixbuf/io-jpeg.c
index bcdf0bb..910158b 100644
--- a/gdk-pixbuf/io-jpeg.c
+++ b/gdk-pixbuf/io-jpeg.c
@@ -393,9 +393,6 @@ jpeg_parse_exif_app1 (JpegExifContext *context, jpeg_saved_marker_ptr marker)
 	guint ret = FALSE;
 	guint offset;
 	guint tags;	   /* number of tags in current ifd */
-	guint tag;
-	guint type;
-	guint count;
 	guint endian = 0;	/* detected endian of data */
 	const char leth[]  = {0x49, 0x49, 0x2a, 0x00};	// Little endian TIFF header
 	const char beth[]  = {0x4d, 0x4d, 0x00, 0x2a};	// Big endian TIFF header
@@ -472,10 +469,11 @@ jpeg_parse_exif_app1 (JpegExifContext *context, jpeg_saved_marker_ptr marker)
 
 	/* check through IFD0 for tags */
 	while (tags--){
-		tag    = de_get16(&marker->data[i + 0], endian);
-		type   = de_get16(&marker->data[i + 2], endian);
-		count  = de_get32(&marker->data[i + 4], endian);
-		offset = de_get32(&marker->data[i + 8], endian);
+		guint tag   = de_get16(&marker->data[i + 0], endian);
+		guint type  = de_get16(&marker->data[i + 2], endian);
+		guint count = de_get32(&marker->data[i + 4], endian);
+		/* values of types small enough to fit are stored directly in the (first) bytes of the Value Offset field */
+		guint short_value = de_get16(&marker->data[i + 8], endian);
 
 		/* orientation tag? */
 		if (tag == 0x112){
@@ -485,7 +483,7 @@ jpeg_parse_exif_app1 (JpegExifContext *context, jpeg_saved_marker_ptr marker)
 				continue;
 
 			/* get the orientation value */
-			context->orientation = offset <= 8 ? offset : 0;
+			context->orientation = short_value <= 8 ? short_value : 0;
 		}
 		/* move the pointer to the next 12-byte tag field. */
 		i = i + 12;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]