[gimp] file-jpeg: Bug #594282 - Set image resolution from EXIF if available



commit 9538f4d61f187b0fea293a729852533cc8477349
Author: Mukund Sivaraman <muks banu com>
Date:   Fri Mar 18 03:38:16 2011 +0530

    file-jpeg: Bug #594282 - Set image resolution from EXIF if available

 plug-ins/file-jpeg/jpeg-exif.c |   60 +++++++++++++++++++++++++++++++++++++
 plug-ins/file-jpeg/jpeg-load.c |   64 +++++++++++++++++++++++++++++++++++++--
 plug-ins/file-jpeg/jpeg.h      |    5 +++
 3 files changed, 125 insertions(+), 4 deletions(-)
---
diff --git a/plug-ins/file-jpeg/jpeg-exif.c b/plug-ins/file-jpeg/jpeg-exif.c
index 2805858..a1f8879 100644
--- a/plug-ins/file-jpeg/jpeg-exif.c
+++ b/plug-ins/file-jpeg/jpeg-exif.c
@@ -99,6 +99,66 @@ jpeg_exif_get_orientation (ExifData *exif_data)
 }
 
 
+gboolean
+jpeg_exif_get_resolution (ExifData *exif_data,
+                          gdouble  *xresolution,
+                          gdouble  *yresolution,
+                          gint     *unit)
+{
+  gboolean       success;
+  ExifEntry     *entry;
+  gint           byte_order;
+  gdouble        xres;
+  gdouble        yres;
+  gint           ruint;
+  ExifRational   r;
+
+  success = FALSE;
+  byte_order = exif_data_get_byte_order (exif_data);
+
+  do
+    {
+      entry = exif_content_get_entry (exif_data->ifd[EXIF_IFD_0],
+                                      EXIF_TAG_X_RESOLUTION);
+      if (!entry)
+        break;
+
+      r = exif_get_rational (entry->data, byte_order);
+      xres = r.numerator / r.denominator;
+
+      entry = exif_content_get_entry (exif_data->ifd[EXIF_IFD_0],
+                                      EXIF_TAG_Y_RESOLUTION);
+      if (!entry)
+        break;
+
+      r = exif_get_rational (entry->data, byte_order);
+      yres = r.numerator / r.denominator;
+
+      entry = exif_content_get_entry (exif_data->ifd[EXIF_IFD_0],
+                                      EXIF_TAG_RESOLUTION_UNIT);
+      if (!entry)
+        break;
+
+      ruint = exif_get_short (entry->data, byte_order);
+      if ((ruint != 2) && /* inches */
+          (ruint != 3))   /* centimetres */
+        break;
+
+      success = TRUE;
+    }
+  while (0);
+
+  if (success)
+    {
+      *xresolution = xres;
+      *yresolution = yres;
+      *unit = ruint;
+    }
+
+  return success;
+}
+
+
 void
 jpeg_setup_exif_for_save (ExifData     *exif_data,
                           const gint32  image_ID)
diff --git a/plug-ins/file-jpeg/jpeg-load.c b/plug-ins/file-jpeg/jpeg-load.c
index e5fed82..1141edf 100644
--- a/plug-ins/file-jpeg/jpeg-load.c
+++ b/plug-ins/file-jpeg/jpeg-load.c
@@ -47,8 +47,14 @@
 #include "jpeg-load.h"
 
 
-static void      jpeg_load_resolution  (gint32                         image_ID,
-                                        struct jpeg_decompress_struct *cinfo);
+static void  jpeg_load_resolution           (gint32    image_ID,
+                                             struct jpeg_decompress_struct
+                                                       *cinfo);
+
+#ifdef HAVE_EXIF
+static gboolean  jpeg_load_exif_resolution  (gint32    image_ID,
+                                             ExifData *exif_data);
+#endif
 
 static void      jpeg_load_sanitize_comment (gchar    *comment);
 
@@ -231,8 +237,6 @@ load_image (const gchar  *filename,
 
       gimp_image_undo_disable (image_ID);
       gimp_image_set_filename (image_ID, filename);
-
-      jpeg_load_resolution (image_ID, &cinfo);
     }
 
   if (preview)
@@ -307,6 +311,12 @@ load_image (const gchar  *filename,
 #endif
             }
         }
+
+#ifdef HAVE_EXIF
+      if (!jpeg_load_exif_resolution (image_ID, exif_data))
+#endif
+        jpeg_load_resolution (image_ID, &cinfo);
+
       /* if we found any comments, then make a parasite for them */
       if (comment_buffer && comment_buffer->len)
         {
@@ -517,6 +527,52 @@ jpeg_load_resolution (gint32                         image_ID,
     }
 }
 
+#ifdef HAVE_EXIF
+
+static gboolean
+jpeg_load_exif_resolution (gint32        image_ID,
+                           ExifData     *exif_data)
+{
+  gboolean success;
+  gdouble xresolution;
+  gdouble yresolution;
+  gint    unit;
+
+  if (!exif_data)
+    return FALSE;
+
+  if (!jpeg_exif_get_resolution (exif_data,
+                                 &xresolution,
+                                 &yresolution,
+                                 &unit))
+    return FALSE;
+
+  switch (unit)
+    {
+    case 2:
+      success = TRUE;
+      break;
+    case 3: /* dots per cm */
+      xresolution *= 2.54;
+      yresolution *= 2.54;
+      gimp_image_set_unit (image_ID, GIMP_UNIT_MM);
+      success = TRUE;
+      break;
+    default:
+      g_warning ("Unknown EXIF resolution unit %d; skipping EXIF resolution.",
+                 unit);
+      success = FALSE;
+    }
+
+  if (success)
+    {
+      gimp_image_set_resolution (image_ID, xresolution, yresolution);
+    }
+
+  return success;
+}
+
+#endif /* HAVE_EXIF */
 
 /*
  * A number of JPEG files have comments written in a local character set
diff --git a/plug-ins/file-jpeg/jpeg.h b/plug-ins/file-jpeg/jpeg.h
index 3402be4..6665afd 100644
--- a/plug-ins/file-jpeg/jpeg.h
+++ b/plug-ins/file-jpeg/jpeg.h
@@ -76,6 +76,11 @@ ExifData * jpeg_exif_data_new_from_file (const gchar   *filename,
 
 gint      jpeg_exif_get_orientation     (ExifData      *exif_data);
 
+gboolean  jpeg_exif_get_resolution      (ExifData       *exif_data,
+                                         gdouble        *xresolution,
+                                         gdouble        *yresolution,
+                                         gint           *unit);
+
 void      jpeg_setup_exif_for_save      (ExifData      *exif_data,
                                          const gint32   image_ID);
 



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