[gthumb] jpeg info: use a single function to read exif tags, added ColorSpace



commit d06b6d8e47186997c290cd282bcc4f72311d1bab
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Tue Jun 27 16:51:39 2017 +0200

    jpeg info: use a single function to read exif tags, added ColorSpace

 extensions/jpeg_utils/jpeg-info.c |  189 ++++++++++---------------------------
 extensions/jpeg_utils/jpeg-info.h |    8 +-
 gthumb/typedefs.h                 |    7 ++
 3 files changed, 63 insertions(+), 141 deletions(-)
---
diff --git a/extensions/jpeg_utils/jpeg-info.c b/extensions/jpeg_utils/jpeg-info.c
index 1239044..d4f2d44 100644
--- a/extensions/jpeg_utils/jpeg-info.c
+++ b/extensions/jpeg_utils/jpeg-info.c
@@ -111,16 +111,17 @@ _jpeg_skip_segment_data (GInputStream  *stream,
 
 
 static gboolean
-_jpeg_exif_orientation_from_app1_segment (guchar       *in_buffer,
-                                         gsize          app1_segment_size,
-                                         JpegInfoData  *data)
+_jpeg_exif_tags_from_app1_segment (guchar       *in_buffer,
+                                  gsize          app1_segment_size,
+                                  JpegInfoFlags  flags,
+                                  JpegInfoData  *data)
 {
        int       pos;
        guint     length;
        gboolean  big_endian;
        guchar   *exif_data;
        guint     offset, number_of_tags, tagnum;
-       int       orientation;
+       int       remaining_tags;
 
        /* Length includes itself, so must be at least 2 */
        /* Following Exif data length must be at least 6 */
@@ -205,7 +206,15 @@ _jpeg_exif_orientation_from_app1_segment (guchar   *in_buffer,
 
        offset += 2;
 
-       /* Search for Orientation Tag in IFD0 */
+       /* Search the tags in IFD0 */
+
+       remaining_tags = 0;
+       if (flags & _JPEG_INFO_EXIF_ORIENTATION)
+               remaining_tags += 1;
+       if (flags & _JPEG_INFO_EXIF_COLORIMETRY)
+               remaining_tags += 3;
+       if (flags & _JPEG_INFO_EXIF_COLOR_SPACE)
+               remaining_tags += 1;
 
        for (;;) {
                if (offset > length - 12) /* check end of data segment */
@@ -218,7 +227,9 @@ _jpeg_exif_orientation_from_app1_segment (guchar    *in_buffer,
                else
                        tagnum = (exif_data[offset+1] << 8) + exif_data[offset];
 
-               if (tagnum == 0x0112) { /* found Orientation Tag */
+               if ((flags & _JPEG_INFO_EXIF_ORIENTATION) && (tagnum == 0x0112)) { /* Orientation */
+                       int orientation;
+
                        if (big_endian) {
                                if (exif_data[offset + 8] != 0)
                                        return FALSE;
@@ -232,137 +243,45 @@ _jpeg_exif_orientation_from_app1_segment (guchar *in_buffer,
                        if (orientation > 8)
                                orientation = 0;
                        data->orientation = orientation;
-                       break;
-               }
-
-               if (--number_of_tags == 0)
-                       return FALSE;
-
-               offset += 12;
-       }
-
-       return TRUE;
-}
-
-
-static gboolean
-_jpeg_exif_colorimetry_from_app1_segment (guchar       *in_buffer,
-                                         gsize          app1_segment_size,
-                                         JpegInfoData  *data)
-{
-       int       pos;
-       guint     length;
-       gboolean  big_endian;
-       guchar   *exif_data;
-       guint     offset, number_of_tags, tagnum;
-       int       remaining_tags;
-
-       /* Length includes itself, so must be at least 2 */
-       /* Following Exif data length must be at least 6 */
-
-       length = app1_segment_size;
-       if (length < 6)
-               return FALSE;
-
-       pos = 0;
-
-       /* Read Exif head, check for "Exif" */
-
-       if ((in_buffer[pos++] != 'E')
-           || (in_buffer[pos++] != 'x')
-           || (in_buffer[pos++] != 'i')
-           || (in_buffer[pos++] != 'f')
-           || (in_buffer[pos++] != 0)
-           || (in_buffer[pos++] != 0))
-       {
-               return FALSE;
-       }
-
-       /* Length of an IFD entry */
-
-       if (length < 12)
-               return FALSE;
-
-       exif_data = in_buffer + pos;
-
-       /* Discover byte order */
-
-       if ((exif_data[0] == 0x49) && (exif_data[1] == 0x49))
-               big_endian = FALSE;
-       else if ((exif_data[0] == 0x4D) && (exif_data[1] == 0x4D))
-               big_endian = TRUE;
-       else
-               return FALSE;
-
-       /* Check Tag Mark */
-
-       if (big_endian) {
-               if (exif_data[2] != 0)
-                       return FALSE;
-               if (exif_data[3] != 0x2A)
-                       return FALSE;
-       }
-       else {
-               if (exif_data[3] != 0)
-                       return FALSE;
-               if (exif_data[2] != 0x2A)
-                       return FALSE;
-       }
-
-       /* Get first IFD offset (offset to IFD0) */
-
-       if (big_endian) {
-               if (exif_data[4] != 0)
-                       return FALSE;
-               if (exif_data[5] != 0)
-                       return FALSE;
-               offset = (exif_data[6] << 8) + exif_data[7];
-       }
-       else {
-               if (exif_data[7] != 0)
-                       return FALSE;
-               if (exif_data[6] != 0)
-                       return FALSE;
-               offset = (exif_data[5] << 8) + exif_data[4];
-       }
-
-       if (offset > length - 2) /* check end of data segment */
-               return FALSE;
+                       data->valid |= _JPEG_INFO_EXIF_ORIENTATION;
 
-       /* Get the number of directory entries contained in this IFD */
-
-       if (big_endian)
-               number_of_tags = (exif_data[offset] << 8) + exif_data[offset+1];
-       else
-               number_of_tags = (exif_data[offset+1] << 8) + exif_data[offset];
-       if (number_of_tags == 0)
-               return FALSE;
-
-       offset += 2;
-
-       /* Search the tags in IFD0 */
-
-       remaining_tags = 3;
-       for (;;) {
-               if (offset > length - 12) /* check end of data segment */
-                       return FALSE;
-
-               /* Get Tag number */
+                       remaining_tags--;
+               }
 
-               if (big_endian)
-                       tagnum = (exif_data[offset] << 8) + exif_data[offset+1];
-               else
-                       tagnum = (exif_data[offset+1] << 8) + exif_data[offset];
+               if ((flags & _JPEG_INFO_EXIF_COLORIMETRY) && (tagnum == 0x012D)) { /* TransferFunction */
+                       remaining_tags--;
+               }
 
-               if (tagnum == 0x012D) { /* TransferFunction */
+               if ((flags & _JPEG_INFO_EXIF_COLORIMETRY) && (tagnum == 0x013E)) { /* WhitePoint */
                        remaining_tags--;
                }
 
-               if (tagnum == 0x013E) { /* WhitePoint */
+               if ((flags & _JPEG_INFO_EXIF_COLORIMETRY) && (tagnum == 0x013F)) { /* PrimaryChromaticities */
                        remaining_tags--;
                }
 
-               if (tagnum == 0x013F) { /* PrimaryChromaticities */
+               if ((flags & _JPEG_INFO_EXIF_COLOR_SPACE) && (tagnum == 0xA001)) { /* ColorSpace */
+                       int value;
+
+                       if (big_endian) {
+                               if (exif_data[offset + 8] != 0)
+                                       return FALSE;
+                               value = exif_data[offset + 9];
+                       }
+                       else {
+                               if (exif_data[offset + 9] != 0)
+                                       return FALSE;
+                               value = exif_data[offset + 8];
+                       }
+
+                       if (value == 1)
+                               data->color_space = GTH_COLOR_SPACE_SRGB;
+                       else if (value == 0xFFFF)
+                               data->color_space = GTH_COLOR_SPACE_UNCALIBRATED;
+                       else
+                               data->color_space = GTH_COLOR_SPACE_UNKNOWN;
+                       data->valid |= _JPEG_INFO_EXIF_COLOR_SPACE;
+
                        remaining_tags--;
                }
 
@@ -512,7 +431,9 @@ _jpeg_info_get_from_stream (GInputStream     *stream,
                        segment_data_consumed = TRUE;
                }
 
-               if (((flags & _JPEG_INFO_EXIF_ORIENTATION) || (flags & _JPEG_INFO_EXIF_COLORIMETRY))
+               if (((flags & _JPEG_INFO_EXIF_ORIENTATION)
+                    || (flags & _JPEG_INFO_EXIF_COLORIMETRY)
+                    || (flags & _JPEG_INFO_EXIF_COLOR_SPACE))
                    && (marker_id == _JPEG_MARKER_APP1))
                {
                        guint   h, l;
@@ -530,15 +451,7 @@ _jpeg_info_get_from_stream (GInputStream    *stream,
                                                 cancellable,
                                                 error) > 0)
                        {
-                               if (flags & _JPEG_INFO_EXIF_ORIENTATION) {
-                                       if (_jpeg_exif_orientation_from_app1_segment (app1_segment, 
app1_segment_size, data))
-                                               data->valid |= _JPEG_INFO_EXIF_ORIENTATION;
-                               }
-
-                               if (flags & _JPEG_INFO_EXIF_COLORIMETRY) {
-                                       if (_jpeg_exif_colorimetry_from_app1_segment (app1_segment, 
app1_segment_size, data))
-                                               data->valid |= _JPEG_INFO_EXIF_ORIENTATION;
-                               }
+                               _jpeg_exif_tags_from_app1_segment (app1_segment, app1_segment_size, flags, 
data);
                        }
 
                        segment_data_consumed = TRUE;
diff --git a/extensions/jpeg_utils/jpeg-info.h b/extensions/jpeg_utils/jpeg-info.h
index f475969..79f24d6 100644
--- a/extensions/jpeg_utils/jpeg-info.h
+++ b/extensions/jpeg_utils/jpeg-info.h
@@ -29,9 +29,10 @@
 typedef enum /*< skip >*/ {
        _JPEG_INFO_NONE = 0,
        _JPEG_INFO_IMAGE_SIZE = 1 << 0,
-       _JPEG_INFO_EXIF_ORIENTATION = 1 << 1,
-       _JPEG_INFO_ICC_PROFILE = 1 << 2,
-       _JPEG_INFO_EXIF_COLORIMETRY = 1 << 3
+       _JPEG_INFO_ICC_PROFILE = 1 << 1,
+       _JPEG_INFO_EXIF_ORIENTATION = 1 << 2,
+       _JPEG_INFO_EXIF_COLORIMETRY = 1 << 3,
+       _JPEG_INFO_EXIF_COLOR_SPACE = 1 << 4,
 } JpegInfoFlags;
 
 typedef struct {
@@ -41,6 +42,7 @@ typedef struct {
        GthTransform    orientation;
        gpointer        icc_data;
        gsize           icc_data_size;
+       GthColorSpace   color_space;
 } JpegInfoData;
 
 void           _jpeg_info_data_init                    (JpegInfoData            *data);
diff --git a/gthumb/typedefs.h b/gthumb/typedefs.h
index a532907..5d2f738 100644
--- a/gthumb/typedefs.h
+++ b/gthumb/typedefs.h
@@ -123,6 +123,13 @@ typedef enum /*< skip >*/ {
 } GthChannel;
 
 
+typedef enum /*< skip >*/ {
+       GTH_COLOR_SPACE_UNKNOWN,
+       GTH_COLOR_SPACE_SRGB,
+       GTH_COLOR_SPACE_UNCALIBRATED
+} GthColorSpace;
+
+
 typedef void (*DataFunc)         (gpointer    user_data);
 typedef void (*ReadyFunc)        (GError     *error,
                                  gpointer    user_data);


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