[gthumb] jpeg info: use a single function to read exif tags, added ColorSpace
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gthumb] jpeg info: use a single function to read exif tags, added ColorSpace
- Date: Wed, 28 Jun 2017 09:51:27 +0000 (UTC)
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]