Sven Neumann writes:
 > If someone wants to try to recover some of the JPEG save settings
 > when loading the JPEG file, feel free.

I did.

Index: plug-ins/jpeg/jpeg-load.c
===================================================================
--- plug-ins/jpeg/jpeg-load.c   (revision 22905)
+++ plug-ins/jpeg/jpeg-load.c   (working copy)
@@ -50,6 +50,61 @@
 gint32           layer_ID_global;
 
 
+static gboolean
+check_table (const JQUANT_TBL *file_table,
+             gint              quant_tbl_no,
+             gint             *quality)
+{
+  int i;
+  gboolean all_ones = TRUE;
+  gint     q;
+  struct jpeg_compress_struct cinfo;
+
+  /* First do the simple check for quality 100, a table with all ones */
+  for (i = 0; i < 64; i++)
+    {
+      if (file_table->quantval[i] != 1)
+        all_ones = 0;
+    }
+
+  if (all_ones)
+    {
+      *quality = 100;
+      return TRUE;
+    }
+
+  /* Then produce tables for all qualities 1..99 and compare. It's
+   * better to do it this way than to calculate the quality factor
+   * backwards from the table in the file because of rounding errors:
+   * We would never match all quality factors exactly.
+   */
+  for (q = 1; q < 100; q++)
+    {
+      jpeg_create_compress (&cinfo);
+
+      jpeg_set_quality (&cinfo, q, TRUE);
+
+      for (i = 0; i < 64; i++)
+        {
+          if (cinfo.quant_tbl_ptrs[quant_tbl_no]->quantval[i] != 
file_table->quantval[i])
+            break;
+        }
+
+      jpeg_destroy_compress (&cinfo);
+
+      if (i == 64)
+        break;
+    }
+
+  if (q < 100)
+    {
+      *quality = q;
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
 gint32
 load_image (const gchar *filename,
             GimpRunMode  runmode,
@@ -57,6 +112,7 @@
 {
   GimpPixelRgn     pixel_rgn;
   GimpDrawable    *drawable;
+  GimpParasite    *parasite;
   gint32 volatile  image_ID;
   gint32           layer_ID;
   struct jpeg_decompress_struct cinfo;
@@ -76,6 +132,8 @@
   GimpParasite * volatile comment_parasite = NULL;
   jpeg_saved_marker_ptr marker;
   gboolean found_exif = FALSE;
+  gint     q0, q1, q2;
+  gint     quality = -1;
 
   /* We set up the normal JPEG error routines. */
   cinfo.err = jpeg_std_error (&jerr.pub);
@@ -153,6 +211,32 @@
 
   (void) jpeg_read_header (&cinfo, TRUE);
 
+  /* Check if the quantization tables used are produced by libjpeg's
+   * jpeg_set_quality().
+   */
+
+  if ((cinfo.jpeg_color_space == JCS_GRAYSCALE &&
+       check_table (cinfo.quant_tbl_ptrs[cinfo.comp_info[0].quant_tbl_no],
+                    cinfo.comp_info[0].quant_tbl_no,
+                    &q0)) ||
+      (cinfo.jpeg_color_space == JCS_YCbCr &&
+       check_table (cinfo.quant_tbl_ptrs[cinfo.comp_info[0].quant_tbl_no],
+                    cinfo.comp_info[0].quant_tbl_no,
+                    &q0) &&
+       check_table (cinfo.quant_tbl_ptrs[cinfo.comp_info[1].quant_tbl_no],
+                    cinfo.comp_info[1].quant_tbl_no,
+                    &q1) &&
+       q0 == q1 &&
+       (cinfo.comp_info[1].quant_tbl_no == cinfo.comp_info[2].quant_tbl_no ||
+        (check_table (cinfo.quant_tbl_ptrs[cinfo.comp_info[2].quant_tbl_no],
+                      cinfo.comp_info[2].quant_tbl_no,
+                      &q2) &&
+         q1 == q2))))
+    {
+      /* Yes. Store the quality in a parasite below. */
+      quality = q0;
+    }
+  
   /* We can ignore the return value from jpeg_read_header since
    *   (a) suspension is not possible with the stdio data source, and
    *   (b) we passed TRUE to reject a tables-only JPEG file as an error.
@@ -257,6 +341,14 @@
                                  layer_type, 100, GIMP_NORMAL_MODE);
     }
 
+  if (quality > 0)
+    {
+      parasite = gimp_parasite_new ("jpeg-original-quality",
+                                    0, sizeof (gint), &quality);
+      gimp_image_parasite_attach (image_ID, parasite);
+      gimp_parasite_free (parasite);
+    }
+
   drawable_global = drawable = gimp_drawable_get (layer_ID);
   gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0,
                        drawable->width, drawable->height, TRUE, FALSE);
Index: plug-ins/jpeg/jpeg.c
===================================================================
--- plug-ins/jpeg/jpeg.c        (revision 22905)
+++ plug-ins/jpeg/jpeg.c        (working copy)
@@ -428,6 +428,23 @@
                * over the JPEG encoding parameters.
                */
               run_mode = GIMP_RUN_INTERACTIVE;
+
+              /* If we have stored an estimate of the libjpeg quality
+               * factor used when creating the original image, and
+               * that is larger than the default quality, use it as
+               * default for the dialog.
+               */
+              parasite = gimp_image_parasite_find (orig_image_ID,
+                                                   "jpeg-original-quality");
+              if (parasite)
+                {
+                  gint quality;
+                  memmove (&quality, gimp_parasite_data (parasite), sizeof 
(gint));
+                  gimp_parasite_free (parasite);
+
+                  if (quality > jsvals.quality)
+                    jsvals.quality = quality;
+                }
             }
           break;
         }

_______________________________________________
Gimp-developer mailing list
Gimp-developer@lists.XCF.Berkeley.EDU
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer

Reply via email to