[gimp] Bug 492048 - Detect color space in Exif 2.21/DCF 2.0 option files



commit 15b7b17b12ab73b0d90a26c822da3cb20bdeb917
Author: Michael Natterer <mitch gimp org>
Date:   Wed Sep 30 20:47:52 2015 +0200

    Bug 492048 - Detect color space in Exif 2.21/DCF 2.0 option files
    
    Some refactoring: add gimp_metadata_get,set_colorspace() and a new
    enum GimpMetadataColorspace which so far can be one of { UNSPECIFIED,
    UNCALIBRATED, SRGB, ADOBERGB }. The setter is untested and I don't
    know if it's doing the right thing, please review. Use the getter in
    gimp_image_metadata_load_finish(), so complex metadata logic and
    profile creation/setting are separated.

 libgimp/gimpimagemetadata.c |   79 +++-----------------
 libgimpbase/gimpbase.def    |    2 +
 libgimpbase/gimpmetadata.c  |  172 ++++++++++++++++++++++++++++++++++++++++++-
 libgimpbase/gimpmetadata.h  |   87 +++++++++++++---------
 4 files changed, 233 insertions(+), 107 deletions(-)
---
diff --git a/libgimp/gimpimagemetadata.c b/libgimp/gimpimagemetadata.c
index 1b77435..a65dffc 100644
--- a/libgimp/gimpimagemetadata.c
+++ b/libgimp/gimpimagemetadata.c
@@ -181,81 +181,24 @@ gimp_image_metadata_load_finish (gint32                 image_ID,
 
       /* only look for colorspace information from metadata if the
        * image didn't contain an embedded color profile
-       *
-       * the logic here was mostly taken from darktable and libkexiv2
        */
       if (! profile)
         {
-          glong colorspace = -1;
+          GimpMetadataColorspace colorspace;
 
-          if (gexiv2_metadata_has_tag (metadata,
-                                       "Exif.Photo.ColorSpace"))
-            {
-              colorspace = gexiv2_metadata_get_tag_long (metadata,
-                                                         "Exif.Photo.ColorSpace");
-            }
-          else if (gexiv2_metadata_has_tag (metadata,
-                                            "Xmp.exif.ColorSpace"))
-            {
-              colorspace = gexiv2_metadata_get_tag_long (metadata,
-                                                         "Xmp.exif.ColorSpace");
-            }
+          colorspace = gimp_metadata_get_colorspace (metadata);
 
-          if (colorspace == 0x01)
-            {
-              /* sRGB, a NULL profile will do the right thing  */
-            }
-          else if (colorspace == 0x02)
-            {
-              profile = gimp_color_profile_new_adobe_rgb ();
-            }
-          else if (colorspace == 0xffff)
+          switch (colorspace)
             {
-              gchar *iop_index;
-
-              iop_index = gexiv2_metadata_get_tag_string (metadata,
-                                                          "Exif.Iop.InteroperabilityIndex");
+            case GIMP_METADATA_COLORSPACE_UNSPECIFIED:
+            case GIMP_METADATA_COLORSPACE_UNCALIBRATED:
+            case GIMP_METADATA_COLORSPACE_SRGB:
+              /* use sRGB, a NULL profile will do the right thing  */
+              break;
 
-              if (! g_strcmp0 (iop_index, "R03"))
-                {
-                  profile = gimp_color_profile_new_adobe_rgb ();
-                }
-              else if (! g_strcmp0 (iop_index, "R98"))
-                {
-                  /* sRGB, a NULL profile will do the right thing  */
-                }
-
-              g_free (iop_index);
-            }
-          else if (gexiv2_metadata_has_tag (metadata,
-                                            "Exif.Nikon3.ColorSpace"))
-            {
-              colorspace = gexiv2_metadata_get_tag_long (metadata,
-                                                         "Exif.Nikon3.ColorSpace");
-
-              if (colorspace == 0x01)
-                {
-                  /* sRGB, a NULL profile will do the right thing  */
-                }
-              else if (colorspace == 0x02)
-                {
-                  profile = gimp_color_profile_new_adobe_rgb ();
-                }
-            }
-          else if (gexiv2_metadata_has_tag (metadata,
-                                            "Exif.Canon.ColorSpace"))
-            {
-              colorspace = gexiv2_metadata_get_tag_long (metadata,
-                                                         "Exif.Canon.ColorSpace");
-
-              if (colorspace == 0x01)
-                {
-                  /* sRGB, a NULL profile will do the right thing  */
-                }
-              else if (colorspace == 0x02)
-                {
-                  profile = gimp_color_profile_new_adobe_rgb ();
-                }
+            case GIMP_METADATA_COLORSPACE_ADOBERGB:
+              profile = gimp_color_profile_new_adobe_rgb ();
+              break;
             }
 
           if (profile)
diff --git a/libgimpbase/gimpbase.def b/libgimpbase/gimpbase.def
index 2e4a20b..32e7ff9 100644
--- a/libgimpbase/gimpbase.def
+++ b/libgimpbase/gimpbase.def
@@ -69,6 +69,7 @@ EXPORTS
        gimp_message_handler_type_get_type
        gimp_metadata_deserialize
        gimp_metadata_duplicate
+       gimp_metadata_get_colorspace
        gimp_metadata_get_resolution
        gimp_metadata_is_tag_supported
        gimp_metadata_load_from_file
@@ -76,6 +77,7 @@ EXPORTS
        gimp_metadata_save_to_file
        gimp_metadata_serialize
        gimp_metadata_set_bits_per_sample
+       gimp_metadata_set_colorspace
        gimp_metadata_set_from_exif
        gimp_metadata_set_from_xmp
        gimp_metadata_set_pixel_size
diff --git a/libgimpbase/gimpmetadata.c b/libgimpbase/gimpmetadata.c
index 131de6e..0495699 100644
--- a/libgimpbase/gimpmetadata.c
+++ b/libgimpbase/gimpmetadata.c
@@ -856,7 +856,7 @@ gimp_metadata_get_resolution (GimpMetadata *metadata,
  * @unit:     The image's unit
  *
  * Sets Exif.Image.XResolution, Exif.Image.YResolution and
- * Exif.Image.ResolutionUnit @metadata.
+ * Exif.Image.ResolutionUnit of @metadata.
  *
  * Since: 2.10
  */
@@ -904,6 +904,175 @@ gimp_metadata_set_resolution (GimpMetadata *metadata,
 }
 
 /**
+ * gimp_metadata_get_colorspace:
+ * @metadata: A #GimpMetadata instance.
+ *
+ * Returns values based on Exif.Photo.ColorSpace, Xmp.exif.ColorSpace,
+ * Exif.Iop.InteroperabilityIndex, Exif.Nikon3.ColorSpace,
+ * Exif.Canon.ColorSpace of @metadata.
+ *
+ * Return value: The colorspace specified by above tags.
+ *
+ * Since: 2.10
+ */
+GimpMetadataColorspace
+gimp_metadata_get_colorspace (GimpMetadata *metadata)
+{
+  glong colorspace = -1;
+
+  g_return_val_if_fail (GEXIV2_IS_METADATA (metadata),
+                        GIMP_METADATA_COLORSPACE_UNSPECIFIED);
+
+  /*  the logic here was mostly taken from darktable and libkexiv2  */
+
+  if (gexiv2_metadata_has_tag (metadata, "Exif.Photo.ColorSpace"))
+    {
+      colorspace = gexiv2_metadata_get_tag_long (metadata,
+                                                 "Exif.Photo.ColorSpace");
+    }
+  else if (gexiv2_metadata_has_tag (metadata, "Xmp.exif.ColorSpace"))
+    {
+      colorspace = gexiv2_metadata_get_tag_long (metadata,
+                                                 "Xmp.exif.ColorSpace");
+    }
+
+  if (colorspace == 0x01)
+    {
+      return GIMP_METADATA_COLORSPACE_SRGB;
+    }
+  else if (colorspace == 0x02)
+    {
+      return GIMP_METADATA_COLORSPACE_ADOBERGB;
+    }
+  else if (colorspace == 0xffff)
+    {
+      gchar *iop_index;
+
+      iop_index = gexiv2_metadata_get_tag_string (metadata,
+                                                  "Exif.Iop.InteroperabilityIndex");
+
+      if (! g_strcmp0 (iop_index, "R03"))
+        {
+          g_free (iop_index);
+
+          return GIMP_METADATA_COLORSPACE_ADOBERGB;
+        }
+      else if (! g_strcmp0 (iop_index, "R98"))
+        {
+          g_free (iop_index);
+
+          return GIMP_METADATA_COLORSPACE_SRGB;
+        }
+
+      g_free (iop_index);
+
+      return GIMP_METADATA_COLORSPACE_UNCALIBRATED;
+    }
+  else if (gexiv2_metadata_has_tag (metadata, "Exif.Nikon3.ColorSpace"))
+    {
+      colorspace = gexiv2_metadata_get_tag_long (metadata,
+                                                 "Exif.Nikon3.ColorSpace");
+
+      if (colorspace == 0x01)
+        {
+          return GIMP_METADATA_COLORSPACE_SRGB;
+        }
+      else if (colorspace == 0x02)
+        {
+          return GIMP_METADATA_COLORSPACE_ADOBERGB;
+        }
+    }
+  else if (gexiv2_metadata_has_tag (metadata, "Exif.Canon.ColorSpace"))
+    {
+      colorspace = gexiv2_metadata_get_tag_long (metadata,
+                                                 "Exif.Canon.ColorSpace");
+
+      if (colorspace == 0x01)
+        {
+          return GIMP_METADATA_COLORSPACE_SRGB;
+        }
+      else if (colorspace == 0x02)
+        {
+          return GIMP_METADATA_COLORSPACE_ADOBERGB;
+        }
+    }
+
+  return GIMP_METADATA_COLORSPACE_UNSPECIFIED;
+}
+
+/**
+ * gimp_metadata_set_colorspace:
+ * @metadata:   A #GimpMetadata instance.
+ * @colorspace: The color space.
+ *
+ * Sets Exif.Photo.ColorSpace, Xmp.exif.ColorSpace,
+ * Exif.Iop.InteroperabilityIndex, Exif.Nikon3.ColorSpace,
+ * Exif.Canon.ColorSpace of @metadata.
+ *
+ * Since: 2.10
+ */
+void
+gimp_metadata_set_colorspace (GimpMetadata           *metadata,
+                              GimpMetadataColorspace  colorspace)
+{
+  g_return_if_fail (GEXIV2_IS_METADATA (metadata));
+
+  switch (colorspace)
+    {
+    case GIMP_METADATA_COLORSPACE_UNSPECIFIED:
+      gexiv2_metadata_clear_tag (metadata, "Exif.Photo.ColorSpace");
+      gexiv2_metadata_clear_tag (metadata, "Xmp.exif.ColorSpace");
+      gexiv2_metadata_clear_tag (metadata, "Exif.Iop.InteroperabilityIndex");
+      gexiv2_metadata_clear_tag (metadata, "Exif.Nikon3.ColorSpace");
+      gexiv2_metadata_clear_tag (metadata, "Exif.Canon.ColorSpace");
+      break;
+
+    case GIMP_METADATA_COLORSPACE_UNCALIBRATED:
+      gexiv2_metadata_set_tag_long (metadata, "Exif.Photo.ColorSpace", 0xffff);
+      if (gexiv2_metadata_has_tag (metadata, "Xmp.exif.ColorSpace"))
+        gexiv2_metadata_set_tag_long (metadata, "Xmp.exif.ColorSpace", 0xffff);
+      gexiv2_metadata_clear_tag (metadata, "Exif.Iop.InteroperabilityIndex");
+      gexiv2_metadata_clear_tag (metadata, "Exif.Nikon3.ColorSpace");
+      gexiv2_metadata_clear_tag (metadata, "Exif.Canon.ColorSpace");
+      break;
+
+    case GIMP_METADATA_COLORSPACE_SRGB:
+      gexiv2_metadata_set_tag_long (metadata, "Exif.Photo.ColorSpace", 0x01);
+
+      if (gexiv2_metadata_has_tag (metadata, "Xmp.exif.ColorSpace"))
+        gexiv2_metadata_set_tag_long (metadata, "Xmp.exif.ColorSpace", 0x01);
+
+      if (gexiv2_metadata_has_tag (metadata, "Exif.Iop.InteroperabilityIndex"))
+        gexiv2_metadata_set_tag_string (metadata,
+                                        "Exif.Iop.InteroperabilityIndex", "R98");
+
+      if (gexiv2_metadata_has_tag (metadata, "Exif.Nikon3.ColorSpace"))
+        gexiv2_metadata_set_tag_long (metadata, "Exif.Nikon3.ColorSpace", 0x01);
+
+      if (gexiv2_metadata_has_tag (metadata, "Exif.Canon.ColorSpace"))
+        gexiv2_metadata_set_tag_long (metadata, "Exif.Canon.ColorSpace", 0x01);
+      break;
+
+    case GIMP_METADATA_COLORSPACE_ADOBERGB:
+      gexiv2_metadata_set_tag_long (metadata, "Exif.Photo.ColorSpace", 0x02);
+
+      if (gexiv2_metadata_has_tag (metadata, "Xmp.exif.ColorSpace"))
+        gexiv2_metadata_set_tag_long (metadata, "Xmp.exif.ColorSpace", 0x02);
+
+      if (gexiv2_metadata_has_tag (metadata, "Exif.Iop.InteroperabilityIndex"))
+        gexiv2_metadata_set_tag_string (metadata,
+                                        "Exif.Iop.InteroperabilityIndex", "R03");
+
+      if (gexiv2_metadata_has_tag (metadata, "Exif.Nikon3.ColorSpace"))
+        gexiv2_metadata_set_tag_long (metadata, "Exif.Nikon3.ColorSpace", 0x02);
+
+      if (gexiv2_metadata_has_tag (metadata, "Exif.Canon.ColorSpace"))
+        gexiv2_metadata_set_tag_long (metadata, "Exif.Canon.ColorSpace", 0x02);
+      break;
+    }
+}
+
+/**
  * gimp_metadata_is_tag_supported:
  * @tag:       A metadata tag name
  * @mime_type: A mime type
@@ -994,7 +1163,6 @@ gimp_metadata_add (GimpMetadata *src,
         }
     }
 
-
   if (gexiv2_metadata_get_supports_xmp (src) &&
       gexiv2_metadata_get_supports_xmp (dest))
     {
diff --git a/libgimpbase/gimpmetadata.h b/libgimpbase/gimpmetadata.h
index 6e6320e..3a6b27c 100644
--- a/libgimpbase/gimpmetadata.h
+++ b/libgimpbase/gimpmetadata.h
@@ -44,45 +44,58 @@ typedef enum
   GIMP_METADATA_SAVE_ALL       = 0xffffffff
 } GimpMetadataSaveFlags;
 
+typedef enum
+{
+  GIMP_METADATA_COLORSPACE_UNSPECIFIED,
+  GIMP_METADATA_COLORSPACE_UNCALIBRATED,
+  GIMP_METADATA_COLORSPACE_SRGB,
+  GIMP_METADATA_COLORSPACE_ADOBERGB
+} GimpMetadataColorspace;
+
 
 GimpMetadata * gimp_metadata_new                 (void);
-GimpMetadata * gimp_metadata_duplicate           (GimpMetadata  *metadata);
-
-GimpMetadata * gimp_metadata_deserialize         (const gchar   *metadata_xml);
-gchar        * gimp_metadata_serialize           (GimpMetadata  *metadata);
-
-GimpMetadata * gimp_metadata_load_from_file      (GFile         *file,
-                                                  GError       **error);
-gboolean       gimp_metadata_save_to_file        (GimpMetadata  *metadata,
-                                                  GFile         *file,
-                                                  GError       **error);
-
-gboolean       gimp_metadata_set_from_exif       (GimpMetadata  *metadata,
-                                                  const guchar  *exif_data,
-                                                  gint           exif_data_length,
-                                                  GError       **error);
-gboolean       gimp_metadata_set_from_xmp        (GimpMetadata  *metadata,
-                                                  const guchar  *xmp_data,
-                                                  gint           xmp_data_length,
-                                                  GError       **error);
-
-void           gimp_metadata_set_pixel_size      (GimpMetadata  *metadata,
-                                                  gint           width,
-                                                  gint           height);
-void           gimp_metadata_set_bits_per_sample (GimpMetadata  *metadata,
-                                                  gint           bits_per_sample);
-
-gboolean       gimp_metadata_get_resolution      (GimpMetadata  *metadata,
-                                                  gdouble       *xres,
-                                                  gdouble       *yres,
-                                                  GimpUnit      *unit);
-void           gimp_metadata_set_resolution      (GimpMetadata  *metadata,
-                                                  gdouble        xres,
-                                                  gdouble        yres,
-                                                  GimpUnit       unit);
-
-gboolean       gimp_metadata_is_tag_supported    (const gchar   *tag,
-                                                  const gchar   *mime_type);
+GimpMetadata * gimp_metadata_duplicate           (GimpMetadata           *metadata);
+
+GimpMetadata * gimp_metadata_deserialize         (const gchar            *metadata_xml);
+gchar        * gimp_metadata_serialize           (GimpMetadata           *metadata);
+
+GimpMetadata * gimp_metadata_load_from_file      (GFile                  *file,
+                                                  GError                **error);
+gboolean       gimp_metadata_save_to_file        (GimpMetadata           *metadata,
+                                                  GFile                  *file,
+                                                  GError                **error);
+
+gboolean       gimp_metadata_set_from_exif       (GimpMetadata           *metadata,
+                                                  const guchar           *exif_data,
+                                                  gint                    exif_data_length,
+                                                  GError                **error);
+gboolean       gimp_metadata_set_from_xmp        (GimpMetadata           *metadata,
+                                                  const guchar           *xmp_data,
+                                                  gint                    xmp_data_length,
+                                                  GError                **error);
+
+void           gimp_metadata_set_pixel_size      (GimpMetadata           *metadata,
+                                                  gint                    width,
+                                                  gint                    height);
+void           gimp_metadata_set_bits_per_sample (GimpMetadata           *metadata,
+                                                  gint                    bits_per_sample);
+
+gboolean       gimp_metadata_get_resolution      (GimpMetadata           *metadata,
+                                                  gdouble                *xres,
+                                                  gdouble                *yres,
+                                                  GimpUnit               *unit);
+void           gimp_metadata_set_resolution      (GimpMetadata           *metadata,
+                                                  gdouble                 xres,
+                                                  gdouble                 yres,
+                                                  GimpUnit                unit);
+
+GimpMetadataColorspace
+               gimp_metadata_get_colorspace      (GimpMetadata           *metadata);
+void           gimp_metadata_set_colorspace      (GimpMetadata           *metadata,
+                                                  GimpMetadataColorspace  colorspace);
+
+gboolean       gimp_metadata_is_tag_supported    (const gchar            *tag,
+                                                  const gchar            *mime_type);
 
 G_END_DECLS
 


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