[gdk-pixbuf] jpeg: Fix reading orientation EXIF tag for some photos



commit f3e395871001738571acdded3dedbe93ba3b5137
Author: Bastien Nocera <hadess hadess net>
Date:   Tue Apr 21 13:17:00 2015 +0200

    jpeg: Fix reading orientation EXIF tag for some photos
    
    Some cameras don't use the right data-type to store the EXIF Orientation
    tag. GIMP still knows how to process it, and it seems common enough that
    we should handle it.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=725582

 gdk-pixbuf/io-jpeg.c |   19 ++++++++++++-------
 1 files changed, 12 insertions(+), 7 deletions(-)
---
diff --git a/gdk-pixbuf/io-jpeg.c b/gdk-pixbuf/io-jpeg.c
index 8e594eb..fa6bec1 100644
--- a/gdk-pixbuf/io-jpeg.c
+++ b/gdk-pixbuf/io-jpeg.c
@@ -467,18 +467,23 @@ jpeg_parse_exif_app1 (JpegExifContext *context, jpeg_saved_marker_ptr marker)
                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){
 
-                       /* The orientation field should consist of a single 2-byte integer */
-                       if (type != 0x3 || count != 1)
-                               continue;
+                       /* The orientation field should consist of a single 2-byte integer,
+                        * but might be a signed long.
+                        * Values of types smaller than 4 bytes are stored directly in the
+                        * Value Offset field */
+                       if (type == 0x3 && count == 1) {
+                               guint short_value = de_get16(&marker->data[i + 8], endian);
+
+                               context->orientation = short_value <= 8 ? short_value : 0;
+                       } else if (type == 0x9 && count == 1) {
+                               guint long_value = de_get32(&marker->data[i + 8], endian);
 
-                       /* get the orientation value */
-                       context->orientation = short_value <= 8 ? short_value : 0;
+                               context->orientation = long_value <= 8 ? long_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]