[gimp] plug-ins: port file-jpeg to GimpPlugIn and to libgimp objects



commit 3bef94d56fdad9a3abd33f3038e620feb2b185f5
Author: Michael Natterer <mitch gimp org>
Date:   Sat Aug 24 02:33:45 2019 +0200

    plug-ins: port file-jpeg to GimpPlugIn and to libgimp objects

 plug-ins/file-jpeg/Makefile.am     |    1 -
 plug-ins/file-jpeg/jpeg-load.c     |  104 ++--
 plug-ins/file-jpeg/jpeg-load.h     |   20 +-
 plug-ins/file-jpeg/jpeg-save.c     |   52 +-
 plug-ins/file-jpeg/jpeg-save.h     |   10 +-
 plug-ins/file-jpeg/jpeg-settings.c |   39 +-
 plug-ins/file-jpeg/jpeg-settings.h |    8 +-
 plug-ins/file-jpeg/jpeg.c          | 1022 ++++++++++++++++++++----------------
 plug-ins/file-jpeg/jpeg.h          |    6 +-
 9 files changed, 677 insertions(+), 585 deletions(-)
---
diff --git a/plug-ins/file-jpeg/Makefile.am b/plug-ins/file-jpeg/Makefile.am
index 007ac53ab7..20a307ee34 100644
--- a/plug-ins/file-jpeg/Makefile.am
+++ b/plug-ins/file-jpeg/Makefile.am
@@ -22,7 +22,6 @@ AM_LDFLAGS = $(mwindows)
 libexecdir = $(gimpplugindir)/plug-ins/file-jpeg
 
 AM_CPPFLAGS = \
-       -DGIMP_DEPRECATED_REPLACE_NEW_API \
        -I$(top_srcdir)         \
        $(GTK_CFLAGS)           \
        $(EXIF_CFLAGS)          \
diff --git a/plug-ins/file-jpeg/jpeg-load.c b/plug-ins/file-jpeg/jpeg-load.c
index aefa7c2438..2e96df3f2f 100644
--- a/plug-ins/file-jpeg/jpeg-load.c
+++ b/plug-ins/file-jpeg/jpeg-load.c
@@ -40,7 +40,7 @@
 #include "jpeg-settings.h"
 #include "jpeg-load.h"
 
-static gboolean  jpeg_load_resolution       (gint32    image_ID,
+static gboolean  jpeg_load_resolution       (GimpImage *image,
                                              struct jpeg_decompress_struct
                                                        *cinfo);
 
@@ -52,18 +52,18 @@ static void      jpeg_load_cmyk_to_rgb      (guchar   *buf,
                                              glong     pixels,
                                              gpointer  transform);
 
-gint32 volatile  preview_image_ID;
-gint32           preview_layer_ID;
+GimpImage * volatile  preview_image;
+GimpLayer *           preview_layer;
 
-gint32
+GimpImage *
 load_image (const gchar  *filename,
             GimpRunMode   runmode,
             gboolean      preview,
             gboolean     *resolution_loaded,
             GError      **error)
 {
-  gint32 volatile    image_ID;
-  gint32             layer_ID;
+  GimpImage * volatile image;
+  GimpLayer           *layer;
   struct jpeg_decompress_struct cinfo;
   struct my_error_mgr           jerr;
   jpeg_saved_marker_ptr         marker;
@@ -96,10 +96,10 @@ load_image (const gchar  *filename,
       g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
                    _("Could not open '%s' for reading: %s"),
                    gimp_filename_to_utf8 (filename), g_strerror (errno));
-      return -1;
+      return NULL;
     }
 
-  image_ID = -1;
+  image = NULL;
 
   /* Establish the setjmp return context for my_error_exit to use. */
   if (setjmp (jerr.setjmp_buffer))
@@ -111,8 +111,8 @@ load_image (const gchar  *filename,
       if (infile)
         fclose (infile);
 
-      if (image_ID != -1 && !preview)
-        gimp_image_delete (image_ID);
+      if (image && !preview)
+        gimp_image_delete (image);
 
       if (preview)
         destroy_preview ();
@@ -120,7 +120,7 @@ load_image (const gchar  *filename,
       if (buffer)
         g_object_unref (buffer);
 
-      return -1;
+      return NULL;
     }
 
   /* Now we can initialize the JPEG decompression object. */
@@ -207,7 +207,7 @@ load_image (const gchar  *filename,
                  "with %d color channels, using colorspace %d (%d).",
                  cinfo.output_components, cinfo.out_color_space,
                  cinfo.jpeg_color_space);
-      return -1;
+      return NULL;
       break;
     }
 
@@ -215,7 +215,7 @@ load_image (const gchar  *filename,
     {
       layer_name = _("JPEG preview");
 
-      image_ID = preview_image_ID;
+      image = preview_image;
     }
   else
     {
@@ -225,16 +225,16 @@ load_image (const gchar  *filename,
 
       layer_name = _("Background");
 
-      image_ID = gimp_image_new_with_precision (cinfo.output_width,
-                                                cinfo.output_height,
-                                                image_type,
-                                                GIMP_PRECISION_U8_NON_LINEAR);
+      image = gimp_image_new_with_precision (cinfo.output_width,
+                                             cinfo.output_height,
+                                             image_type,
+                                             GIMP_PRECISION_U8_NON_LINEAR);
 
-      gimp_image_undo_disable (image_ID);
-      gimp_image_set_filename (image_ID, filename);
+      gimp_image_undo_disable (image);
+      gimp_image_set_filename (image, filename);
 
       /* Step 5.0: save the original JPEG settings in a parasite */
-      jpeg_detect_original_settings (&cinfo, image_ID);
+      jpeg_detect_original_settings (&cinfo, image);
 
       /* Step 5.1: check for comments, or Exif metadata in APP1 markers */
       for (marker = cinfo.marker_list; marker; marker = marker->next)
@@ -271,7 +271,7 @@ load_image (const gchar  *filename,
             }
         }
 
-      if (jpeg_load_resolution (image_ID, &cinfo))
+      if (jpeg_load_resolution (image, &cinfo))
         {
           if (resolution_loaded)
             *resolution_loaded = TRUE;
@@ -287,7 +287,7 @@ load_image (const gchar  *filename,
                                         GIMP_PARASITE_PERSISTENT,
                                         strlen (comment_buffer->str) + 1,
                                         comment_buffer->str);
-          gimp_image_attach_parasite (image_ID, parasite);
+          gimp_image_attach_parasite (image, parasite);
           gimp_parasite_free (parasite);
 
           g_string_free (comment_buffer, TRUE);
@@ -309,7 +309,7 @@ load_image (const gchar  *filename,
                                                              NULL);
           if (profile)
             {
-              gimp_image_set_color_profile (image_ID, profile);
+              gimp_image_set_color_profile (image, profile);
               g_object_unref (profile);
             }
         }
@@ -321,15 +321,15 @@ load_image (const gchar  *filename,
        */
     }
 
-  layer_ID = gimp_layer_new (image_ID, layer_name,
-                             cinfo.output_width,
-                             cinfo.output_height,
-                             layer_type,
-                             100,
-                             gimp_image_get_default_new_layer_mode (image_ID));
+  layer = gimp_layer_new (image, layer_name,
+                          cinfo.output_width,
+                          cinfo.output_height,
+                          layer_type,
+                          100,
+                          gimp_image_get_default_new_layer_mode (image));
 
   if (preview)
-    preview_layer_ID = layer_ID;
+    preview_layer = layer;
 
   /* Step 6: while (scan lines remain to be read) */
   /*           jpeg_read_scanlines(...); */
@@ -338,11 +338,11 @@ load_image (const gchar  *filename,
    * loop counter, so that we don't have to keep track ourselves.
    */
 
-  buffer = gimp_drawable_get_buffer (layer_ID);
+  buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (layer));
 
   format = babl_format_with_space (image_type == GIMP_RGB ?
                                    "R'G'B' u8" : "Y' u8",
-                                   gimp_drawable_get_format (layer_ID));
+                                   gimp_drawable_get_format (GIMP_DRAWABLE (layer)));
 
   while (cinfo.output_scanline < cinfo.output_height)
     {
@@ -433,13 +433,13 @@ load_image (const gchar  *filename,
       gimp_progress_update (1.0);
     }
 
-  gimp_image_insert_layer (image_ID, layer_ID, -1, 0);
+  gimp_image_insert_layer (image, layer, NULL, 0);
 
-  return image_ID;
+  return image;
 }
 
 static gboolean
-jpeg_load_resolution (gint32                         image_ID,
+jpeg_load_resolution (GimpImage                     *image,
                       struct jpeg_decompress_struct *cinfo)
 {
   if (cinfo->saw_JFIF_marker && cinfo->X_density != 0 && cinfo->Y_density != 0)
@@ -455,7 +455,7 @@ jpeg_load_resolution (gint32                         image_ID,
                  */
           asymmetry = xresolution / yresolution;
 
-          gimp_image_get_resolution (image_ID, &xresolution, &yresolution);
+          gimp_image_get_resolution (image, &xresolution, &yresolution);
 
           xresolution *= asymmetry;
           break;
@@ -466,7 +466,7 @@ jpeg_load_resolution (gint32                         image_ID,
         case 2: /* dots per cm */
           xresolution *= 2.54;
           yresolution *= 2.54;
-          gimp_image_set_unit (image_ID, GIMP_UNIT_MM);
+          gimp_image_set_unit (image, GIMP_UNIT_MM);
           break;
 
         default:
@@ -475,7 +475,7 @@ jpeg_load_resolution (gint32                         image_ID,
           break;
         }
 
-      gimp_image_set_resolution (image_ID, xresolution, yresolution);
+      gimp_image_set_resolution (image, xresolution, yresolution);
 
       return TRUE;
     }
@@ -509,14 +509,14 @@ jpeg_load_sanitize_comment (gchar *comment)
     }
 }
 
-gint32
+GimpImage *
 load_thumbnail_image (GFile         *file,
                       gint          *width,
                       gint          *height,
                       GimpImageType *type,
                       GError       **error)
 {
-  gint32 volatile               image_ID = -1;
+  GimpImage * volatile          image = NULL;
   struct jpeg_decompress_struct cinfo;
   struct my_error_mgr           jerr;
   FILE                         *infile   = NULL;
@@ -524,9 +524,9 @@ load_thumbnail_image (GFile         *file,
   gimp_progress_init_printf (_("Opening thumbnail for '%s'"),
                              g_file_get_parse_name (file));
 
-  image_ID = gimp_image_metadata_load_thumbnail (file, error);
-  if (image_ID < 1)
-    return -1;
+  image = gimp_image_metadata_load_thumbnail (file, error);
+  if (! image)
+    return NULL;
 
   cinfo.err = jpeg_std_error (&jerr.pub);
   jerr.pub.error_exit     = my_error_exit;
@@ -538,10 +538,10 @@ load_thumbnail_image (GFile         *file,
                    _("Could not open '%s' for reading: %s"),
                    g_file_get_parse_name (file), g_strerror (errno));
 
-      if (image_ID != -1)
-        gimp_image_delete (image_ID);
+      if (image)
+        gimp_image_delete (image);
 
-      return -1;
+      return NULL;
     }
 
   /* Establish the setjmp return context for my_error_exit to use. */
@@ -553,10 +553,10 @@ load_thumbnail_image (GFile         *file,
        */
       jpeg_destroy_decompress (&cinfo);
 
-      if (image_ID != -1)
-        gimp_image_delete (image_ID);
+      if (image)
+        gimp_image_delete (image);
 
-      return -1;
+      return NULL;
     }
 
   /* Now we can initialize the JPEG decompression object. */
@@ -599,8 +599,8 @@ load_thumbnail_image (GFile         *file,
                  cinfo.output_components, cinfo.out_color_space,
                  cinfo.jpeg_color_space);
 
-      gimp_image_delete (image_ID);
-      image_ID = -1;
+      gimp_image_delete (image);
+      image = NULL;
       break;
     }
 
@@ -613,7 +613,7 @@ load_thumbnail_image (GFile         *file,
 
   fclose (infile);
 
-  return image_ID;
+  return image;
 }
 
 static gpointer
diff --git a/plug-ins/file-jpeg/jpeg-load.h b/plug-ins/file-jpeg/jpeg-load.h
index 3844097781..9bf25d8a06 100644
--- a/plug-ins/file-jpeg/jpeg-load.h
+++ b/plug-ins/file-jpeg/jpeg-load.h
@@ -18,16 +18,16 @@
 #ifndef __JPEG_LOAD_H__
 #define __JPEG_LOAD_H__
 
-gint32 load_image           (const gchar  *filename,
-                             GimpRunMode   runmode,
-                             gboolean      preview,
-                             gboolean     *resolution_loaded,
-                             GError      **error);
+GimpImage * load_image           (const gchar  *filename,
+                                  GimpRunMode   runmode,
+                                  gboolean      preview,
+                                  gboolean     *resolution_loaded,
+                                  GError      **error);
 
-gint32 load_thumbnail_image (GFile         *file,
-                             gint          *width,
-                             gint          *height,
-                             GimpImageType *type,
-                             GError       **error);
+GimpImage * load_thumbnail_image (GFile         *file,
+                                  gint          *width,
+                                  gint          *height,
+                                  GimpImageType *type,
+                                  GError       **error);
 
 #endif /* __JPEG_LOAD_H__ */
diff --git a/plug-ins/file-jpeg/jpeg-save.c b/plug-ins/file-jpeg/jpeg-save.c
index 7926ab5872..510a82ec54 100644
--- a/plug-ins/file-jpeg/jpeg-save.c
+++ b/plug-ins/file-jpeg/jpeg-save.c
@@ -261,9 +261,9 @@ background_jpeg_save (PreviewPersistent *pp)
 
 gboolean
 save_image (const gchar  *filename,
-            gint32        image_ID,
-            gint32        drawable_ID,
-            gint32        orig_image_ID,
+            GimpImage    *image,
+            GimpDrawable *drawable,
+            GimpImage    *orig_image,
             gboolean      preview,
             GError      **error)
 {
@@ -285,9 +285,9 @@ save_image (const gchar  *filename,
   gboolean         out_linear = FALSE;
   gint             rowstride, yend;
 
-  drawable_type = gimp_drawable_type (drawable_ID);
-  buffer = gimp_drawable_get_buffer (drawable_ID);
-  space = gimp_drawable_get_format (drawable_ID);
+  drawable_type = gimp_drawable_type (drawable);
+  buffer = gimp_drawable_get_buffer (drawable);
+  space = gimp_drawable_get_format (drawable);
 
   if (! preview)
     gimp_progress_init_printf (_("Exporting '%s'"),
@@ -346,7 +346,7 @@ save_image (const gchar  *filename,
    */
   if (jsvals.save_profile)
     {
-      profile = gimp_image_get_color_profile (orig_image_ID);
+      profile = gimp_image_get_color_profile (orig_image);
 
       /* If a profile is explicitly set, follow its TRC, whatever the
        * storage format.
@@ -357,11 +357,11 @@ save_image (const gchar  *filename,
       if (! profile)
         {
           /* There is always an effective profile. */
-          profile = gimp_image_get_effective_color_profile (orig_image_ID);
+          profile = gimp_image_get_effective_color_profile (orig_image);
 
           if (gimp_color_profile_is_linear (profile))
             {
-              if (gimp_image_get_precision (image_ID) != GIMP_PRECISION_U8_LINEAR)
+              if (gimp_image_get_precision (image) != GIMP_PRECISION_U8_LINEAR)
                 {
                   GimpColorProfile *saved_profile;
 
@@ -390,7 +390,7 @@ save_image (const gchar  *filename,
           g_printerr ("%s: error getting the profile space: %s",
                      G_STRFUNC, (*error)->message);
           g_clear_error (error);
-          space = gimp_drawable_get_format (drawable_ID);
+          space = gimp_drawable_get_format (drawable);
         }
     }
 
@@ -476,7 +476,7 @@ save_image (const gchar  *filename,
       gint    t;
 
       /* override tables generated by jpeg_set_quality() with custom tables */
-      quant_tables = jpeg_restore_original_tables (image_ID, num_quant_tables);
+      quant_tables = jpeg_restore_original_tables (image, num_quant_tables);
       if (quant_tables)
         {
           for (t = 0; t < num_quant_tables; t++)
@@ -498,7 +498,7 @@ save_image (const gchar  *filename,
   else
     cinfo.optimize_coding = jsvals.optimize;
 
-  subsampling = (gimp_drawable_is_rgb (drawable_ID) ?
+  subsampling = (gimp_drawable_is_rgb (drawable) ?
                  jsvals.subsmp : JPEG_SUBSAMPLING_1x1_1x1_1x1);
 
   /*  smoothing is not supported with nonstandard sampling ratios  */
@@ -576,13 +576,13 @@ save_image (const gchar  *filename,
     gdouble xresolution;
     gdouble yresolution;
 
-    gimp_image_get_resolution (orig_image_ID, &xresolution, &yresolution);
+    gimp_image_get_resolution (orig_image, &xresolution, &yresolution);
 
     if (xresolution > 1e-5 && yresolution > 1e-5)
       {
         gdouble factor;
 
-        factor = gimp_unit_get_factor (gimp_image_get_unit (orig_image_ID));
+        factor = gimp_unit_get_factor (gimp_image_get_unit (orig_image));
 
         if (factor == 2.54 /* cm */ ||
             factor == 25.4 /* mm */)
@@ -746,19 +746,19 @@ make_preview (void)
         {
           /* we freeze undo saving so that we can avoid sucking up
            * tile cache with our unneeded preview steps. */
-          gimp_image_undo_freeze (preview_image_ID);
+          gimp_image_undo_freeze (preview_image);
 
           undo_touched = TRUE;
         }
 
       save_image (tn,
-                  preview_image_ID,
-                  drawable_ID_global,
-                  orig_image_ID_global,
+                  preview_image,
+                  drawable_global,
+                  orig_image_global,
                   TRUE, NULL);
 
-      if (display_ID == -1)
-        display_ID = gimp_display_new (preview_image_ID);
+      if (! display)
+        display = gimp_display_new (preview_image);
     }
   else
     {
@@ -779,15 +779,15 @@ destroy_preview (void)
       g_source_remove (id);
     }
 
-  if (gimp_image_is_valid (preview_image_ID) &&
-      gimp_item_is_valid (preview_layer_ID))
+  if (gimp_image_is_valid (preview_image) &&
+      gimp_item_is_valid (preview_layer))
     {
       /*  assuming that reference counting is working correctly,
           we do not need to delete the layer, removing it from
           the image should be sufficient  */
-      gimp_image_remove_layer (preview_image_ID, preview_layer_ID);
+      gimp_image_remove_layer (preview_image, preview_layer);
 
-      preview_layer_ID = -1;
+      preview_layer = NULL;
     }
 }
 
@@ -1189,7 +1189,7 @@ save_dialog (void)
 
   gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo);
 
-  if (gimp_drawable_is_rgb (drawable_ID_global))
+  if (gimp_drawable_is_rgb (drawable_global))
     {
       gimp_int_combo_box_connect (GIMP_INT_COMBO_BOX (combo),
                                   jsvals.subsmp,
@@ -1439,7 +1439,7 @@ load_gui_defaults (JpegSaveGui *pg)
     {
       gtk_adjustment_set_value (pg->quality, jsvals.quality);
 
-      if (gimp_drawable_is_rgb (drawable_ID_global))
+      if (gimp_drawable_is_rgb (drawable_global))
         {
           gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (pg->subsmp),
                                          jsvals.subsmp);
diff --git a/plug-ins/file-jpeg/jpeg-save.h b/plug-ins/file-jpeg/jpeg-save.h
index 34f0eb544d..58b5c4e91d 100644
--- a/plug-ins/file-jpeg/jpeg-save.h
+++ b/plug-ins/file-jpeg/jpeg-save.h
@@ -40,14 +40,14 @@ typedef struct
 
 extern JpegSaveVals     jsvals;
 
-extern gint32           orig_image_ID_global;
-extern gint32           drawable_ID_global;
+extern GimpImage       *orig_image_global;
+extern GimpDrawable    *drawable_global;
 
 
 gboolean    save_image         (const gchar  *filename,
-                                gint32        image_ID,
-                                gint32        drawable_ID,
-                                gint32        orig_image_ID,
+                                GimpImage    *image,
+                                GimpDrawable *drawable,
+                                GimpImage    *orig_image,
                                 gboolean      preview,
                                 GError      **error);
 gboolean    save_dialog        (void);
diff --git a/plug-ins/file-jpeg/jpeg-settings.c b/plug-ins/file-jpeg/jpeg-settings.c
index 65a2d216b6..ed80db4f81 100644
--- a/plug-ins/file-jpeg/jpeg-settings.c
+++ b/plug-ins/file-jpeg/jpeg-settings.c
@@ -61,21 +61,21 @@
 /**
  * jpeg_detect_original_settings:
  * @cinfo: a pointer to a JPEG decompressor info.
- * @image_ID: the image to which the parasite should be attached.
+ * @image: the image to which the parasite should be attached.
  *
  * Analyze the image being decompressed (@cinfo) and extract the
  * sampling factors, quantization tables and overall image quality.
- * Store this information in a parasite and attach it to @image_ID.
+ * Store this information in a parasite and attach it to @image.
  *
  * This function must be called after jpeg_read_header() so that
  * @cinfo contains the quantization tables and the sampling factors
  * for each component.
  *
- * Returns: TRUE if a parasite has been attached to @image_ID.
+ * Returns: TRUE if a parasite has been attached to @image.
  */
 gboolean
 jpeg_detect_original_settings (struct jpeg_decompress_struct *cinfo,
-                               gint32                         image_ID)
+                               GimpImage                     *image)
 {
   guint         parasite_size;
   guchar       *parasite_data;
@@ -132,8 +132,9 @@ jpeg_detect_original_settings (struct jpeg_decompress_struct *cinfo,
                                 parasite_size,
                                 parasite_data);
   g_free (parasite_data);
-  gimp_image_attach_parasite (image_ID, parasite);
+  gimp_image_attach_parasite (image, parasite);
   gimp_parasite_free (parasite);
+
   return TRUE;
 }
 
@@ -143,28 +144,28 @@ jpeg_detect_original_settings (struct jpeg_decompress_struct *cinfo,
  * GIMP color space of the drawable to be saved.  If one of them is
  * grayscale and the other isn't, then the quality setting may be used
  * but the subsampling parameters and quantization tables should be
- * ignored.  The drawable_ID needs to be passed around because the
+ * ignored.  The drawable needs to be passed around because the
  * color space of the drawable may be different from that of the image
  * (e.g., when saving a mask or channel).
  */
 
 /**
  * jpeg_restore_original_settings:
- * @image_ID: the image that may contain original jpeg settings in a parasite.
+ * @image: the image that may contain original jpeg settings in a parasite.
  * @quality: where to store the original jpeg quality.
  * @subsmp: where to store the original subsampling type.
  * @num_quant_tables: where to store the number of quantization tables found.
  *
  * Retrieve the original JPEG settings (quality, type of subsampling
  * and number of quantization tables) from the parasite attached to
- * @image_ID.  If the number of quantization tables is greater than
+ * @image.  If the number of quantization tables is greater than
  * zero, then these tables can be retrieved from the parasite by
  * calling jpeg_restore_original_tables().
  *
  * Returns: TRUE if a valid parasite was attached to the image
  */
 gboolean
-jpeg_restore_original_settings (gint32           image_ID,
+jpeg_restore_original_settings (GimpImage       *image,
                                 gint            *quality,
                                 JpegSubsampling *subsmp,
                                 gint            *num_quant_tables)
@@ -183,7 +184,7 @@ jpeg_restore_original_settings (gint32           image_ID,
   g_return_val_if_fail (subsmp != NULL, FALSE);
   g_return_val_if_fail (num_quant_tables != NULL, FALSE);
 
-  parasite = gimp_image_get_parasite (image_ID, "jpeg-settings");
+  parasite = gimp_image_get_parasite (image, "jpeg-settings");
   if (parasite)
     {
       src = gimp_parasite_data (parasite);
@@ -248,11 +249,11 @@ jpeg_restore_original_settings (gint32           image_ID,
 
 /**
  * jpeg_restore_original_tables:
- * @image_ID: the image that may contain original jpeg settings in a parasite.
+ * @image: the image that may contain original jpeg settings in a parasite.
  * @num_quant_tables: the number of quantization tables to restore.
  *
  * Retrieve the original quantization tables from the parasite
- * attached to @image_ID.  Each table is an array of coefficients that
+ * attached to @image.  Each table is an array of coefficients that
  * can be associated with a component of a JPEG image when saving it.
  *
  * An array of newly allocated tables is returned if @num_quant_tables
@@ -267,8 +268,8 @@ jpeg_restore_original_settings (gint32           image_ID,
  * Returns: (nullable): an array of quantization tables, or NULL.
  */
 guint **
-jpeg_restore_original_tables (gint32    image_ID,
-                              gint      num_quant_tables)
+jpeg_restore_original_tables (GimpImage *image,
+                              gint       num_quant_tables)
 {
   GimpParasite *parasite;
   const guchar *src;
@@ -279,7 +280,7 @@ jpeg_restore_original_tables (gint32    image_ID,
   gint          t;
   gint          i;
 
-  parasite = gimp_image_get_parasite (image_ID, "jpeg-settings");
+  parasite = gimp_image_get_parasite (image, "jpeg-settings");
   if (parasite)
     {
       src_size = gimp_parasite_data_size (parasite);
@@ -319,7 +320,7 @@ jpeg_restore_original_tables (gint32    image_ID,
 
 /**
  * jpeg_swap_original_settings:
- * @image_ID: the image that may contain original jpeg settings in a parasite.
+ * @image: the image that may contain original jpeg settings in a parasite.
  *
  * Swap the horizontal and vertical axis for the saved subsampling
  * parameters and quantization tables.  This should be done if the
@@ -327,7 +328,7 @@ jpeg_restore_original_tables (gint32    image_ID,
  * mirrored along its diagonal.
  */
 void
-jpeg_swap_original_settings (gint32 image_ID)
+jpeg_swap_original_settings (GimpImage *image)
 {
   GimpParasite *parasite;
   const guchar *src;
@@ -340,7 +341,7 @@ jpeg_swap_original_settings (gint32 image_ID)
   gint          i;
   gint          j;
 
-  parasite = gimp_image_get_parasite (image_ID, "jpeg-settings");
+  parasite = gimp_image_get_parasite (image, "jpeg-settings");
   if (parasite)
     {
       src_size = gimp_parasite_data_size (parasite);
@@ -389,7 +390,7 @@ jpeg_swap_original_settings (gint32 image_ID)
                                             src_size,
                                             new_data);
               g_free (new_data);
-              gimp_image_attach_parasite (image_ID, parasite);
+              gimp_image_attach_parasite (image, parasite);
             }
         }
       gimp_parasite_free (parasite);
diff --git a/plug-ins/file-jpeg/jpeg-settings.h b/plug-ins/file-jpeg/jpeg-settings.h
index 0399b84ba2..70cbea14b0 100644
--- a/plug-ins/file-jpeg/jpeg-settings.h
+++ b/plug-ins/file-jpeg/jpeg-settings.h
@@ -22,16 +22,16 @@
 #define __JPEG_SETTINGS_H__
 
 gboolean  jpeg_detect_original_settings  (struct jpeg_decompress_struct *cinfo,
-                                          gint32           image_ID);
+                                          GimpImage       *image);
 
-gboolean  jpeg_restore_original_settings (gint32           image_ID,
+gboolean  jpeg_restore_original_settings (GimpImage       *image,
                                           gint            *quality,
                                           JpegSubsampling *subsmp,
                                           gint            *num_quant_tables);
 
-guint   **jpeg_restore_original_tables   (gint32           image_ID,
+guint   **jpeg_restore_original_tables   (GimpImage       *image,
                                           gint             num_quant_tables);
 
-void      jpeg_swap_original_settings    (gint32           image_ID);
+void      jpeg_swap_original_settings    (GimpImage       *image);
 
 #endif /* __JPEG_SETTINGS_H__ */
diff --git a/plug-ins/file-jpeg/jpeg.c b/plug-ins/file-jpeg/jpeg.c
index f645d64da4..7e9373df6f 100644
--- a/plug-ins/file-jpeg/jpeg.c
+++ b/plug-ins/file-jpeg/jpeg.c
@@ -34,568 +34,660 @@
 #include "jpeg-load.h"
 #include "jpeg-save.h"
 
-/* Declare local functions.
- */
 
-static void  query (void);
-static void  run   (const gchar      *name,
-                    gint              nparams,
-                    const GimpParam  *param,
-                    gint             *nreturn_vals,
-                    GimpParam       **return_vals);
+typedef struct _Jpeg      Jpeg;
+typedef struct _JpegClass JpegClass;
+
+struct _Jpeg
+{
+  GimpPlugIn      parent_instance;
+};
+
+struct _JpegClass
+{
+  GimpPlugInClass parent_class;
+};
+
+
+#define JPEG_TYPE  (jpeg_get_type ())
+#define JPEG (obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), JPEG_TYPE, Jpeg))
+
+GType                   jpeg_get_type         (void) G_GNUC_CONST;
+
+static GList          * jpeg_query_procedures (GimpPlugIn           *plug_in);
+static GimpProcedure  * jpeg_create_procedure (GimpPlugIn           *plug_in,
+                                              const gchar          *name);
+
+static GimpValueArray * jpeg_load             (GimpProcedure        *procedure,
+                                              GimpRunMode           run_mode,
+                                              GFile                *file,
+                                              const GimpValueArray *args,
+                                              gpointer              run_data);
+static GimpValueArray * jpeg_load_thumb       (GimpProcedure        *procedure,
+                                              GFile                *file,
+                                              gint                  size,
+                                              const GimpValueArray *args,
+                                              gpointer              run_data);
+static GimpValueArray * jpeg_save             (GimpProcedure        *procedure,
+                                              GimpRunMode           run_mode,
+                                              GimpImage            *image,
+                                              GimpDrawable         *drawable,
+                                              GFile                *file,
+                                              const GimpValueArray *args,
+                                              gpointer              run_data);
+
+
+G_DEFINE_TYPE (Jpeg, jpeg, GIMP_TYPE_PLUG_IN)
+
+GIMP_MAIN (JPEG_TYPE)
+
 
 gboolean         undo_touched;
 gboolean         load_interactive;
 gchar           *image_comment;
-gint32           display_ID;
+GimpDisplay     *display;
 JpegSaveVals     jsvals;
-gint32           orig_image_ID_global;
-gint32           drawable_ID_global;
+GimpImage       *orig_image_global;
+GimpDrawable    *drawable_global;
 gint             orig_quality;
 JpegSubsampling  orig_subsmp;
 gint             num_quant_tables;
 
 
-const GimpPlugInInfo PLUG_IN_INFO =
+static void
+jpeg_class_init (JpegClass *klass)
 {
-  NULL,  /* init_proc  */
-  NULL,  /* quit_proc  */
-  query, /* query_proc */
-  run,   /* run_proc   */
-};
-
-
-MAIN ()
+  GimpPlugInClass *plug_in_class = GIMP_PLUG_IN_CLASS (klass);
 
+  plug_in_class->query_procedures = jpeg_query_procedures;
+  plug_in_class->create_procedure = jpeg_create_procedure;
+}
 
 static void
-query (void)
+jpeg_init (Jpeg *jpeg)
 {
-  static const GimpParamDef load_args[] =
-  {
-    { GIMP_PDB_INT32,    "run-mode",     "The run mode { RUN-INTERACTIVE (0), RUN-NONINTERACTIVE (1) }" },
-    { GIMP_PDB_STRING,   "filename",     "The name of the file to load" },
-    { GIMP_PDB_STRING,   "raw-filename", "The name of the file to load" }
-  };
-  static const GimpParamDef load_return_vals[] =
-  {
-    { GIMP_PDB_IMAGE,   "image",         "Output image" }
-  };
-
-  static const GimpParamDef thumb_args[] =
-  {
-    { GIMP_PDB_STRING, "filename",     "The name of the file to load"  },
-    { GIMP_PDB_INT32,  "thumb-size",   "Preferred thumbnail size"      }
-  };
-  static const GimpParamDef thumb_return_vals[] =
-  {
-    { GIMP_PDB_IMAGE,  "image",        "Thumbnail image"               },
-    { GIMP_PDB_INT32,  "image-width",  "Width of full-sized image"     },
-    { GIMP_PDB_INT32,  "image-height", "Height of full-sized image"    }
-  };
-
-  static const GimpParamDef save_args[] =
-  {
-    { GIMP_PDB_INT32,    "run-mode",     "The run mode { RUN-INTERACTIVE (0), RUN-NONINTERACTIVE (1) }" },
-    { GIMP_PDB_IMAGE,    "image",        "Input image" },
-    { GIMP_PDB_DRAWABLE, "drawable",     "Drawable to save" },
-    { GIMP_PDB_STRING,   "filename",     "The name of the file to save the image in" },
-    { GIMP_PDB_STRING,   "raw-filename", "The name of the file to save the image in" },
-    { GIMP_PDB_FLOAT,    "quality",      "Quality of saved image (0 <= quality <= 1)" },
-    { GIMP_PDB_FLOAT,    "smoothing",    "Smoothing factor for saved image (0 <= smoothing <= 1)" },
-    { GIMP_PDB_INT32,    "optimize",     "Use optimized tables during Huffman coding (0/1)" },
-    { GIMP_PDB_INT32,    "progressive",  "Create progressive JPEG images (0/1)" },
-    { GIMP_PDB_STRING,   "comment",      "Image comment" },
-    { GIMP_PDB_INT32,    "subsmp",       "Sub-sampling type { 0, 1, 2, 3 } 0 == 4:2:0 (chroma quartered), 1 
== 4:2:2 Horizontal (chroma halved), 2 == 4:4:4 (best quality), 3 == 4:2:2 Vertical (chroma halved)" },
-    { GIMP_PDB_INT32,    "baseline",     "Force creation of a baseline JPEG (non-baseline JPEGs can't be 
read by all decoders) (0/1)" },
-    { GIMP_PDB_INT32,    "restart",      "Interval of restart markers (in MCU rows, 0 = no restart markers)" 
},
-    { GIMP_PDB_INT32,    "dct",          "DCT method to use { INTEGER (0), FIXED (1), FLOAT (2) }" }
-  };
-
-  gimp_install_procedure (LOAD_PROC,
-                          "loads files in the JPEG file format",
-                          "loads files in the JPEG file format",
-                          "Spencer Kimball, Peter Mattis & others",
-                          "Spencer Kimball & Peter Mattis",
-                          "1995-2007",
-                          N_("JPEG image"),
-                          NULL,
-                          GIMP_PLUGIN,
-                          G_N_ELEMENTS (load_args),
-                          G_N_ELEMENTS (load_return_vals),
-                          load_args, load_return_vals);
-
-  gimp_register_file_handler_mime (LOAD_PROC, "image/jpeg");
-  gimp_register_magic_load_handler (LOAD_PROC,
-                                    "jpg,jpeg,jpe",
-                                    "",
-                                    "6,string,JFIF,6,string,Exif");
-
-  gimp_install_procedure (LOAD_THUMB_PROC,
-                          "Loads a thumbnail from a JPEG image",
-                          "Loads a thumbnail from a JPEG image (only if it exists)",
-                          "Mukund Sivaraman <muks mukund org>, Sven Neumann <sven gimp org>",
-                          "Mukund Sivaraman <muks mukund org>, Sven Neumann <sven gimp org>",
-                          "November 15, 2004",
-                          NULL,
-                          NULL,
-                          GIMP_PLUGIN,
-                          G_N_ELEMENTS (thumb_args),
-                          G_N_ELEMENTS (thumb_return_vals),
-                          thumb_args, thumb_return_vals);
-
-  gimp_register_thumbnail_loader (LOAD_PROC, LOAD_THUMB_PROC);
-
-  gimp_install_procedure (SAVE_PROC,
-                          "saves files in the JPEG file format",
-                          "saves files in the lossy, widely supported JPEG format",
-                          "Spencer Kimball, Peter Mattis & others",
-                          "Spencer Kimball & Peter Mattis",
-                          "1995-2007",
-                          N_("JPEG image"),
-                          "RGB*, GRAY*",
-                          GIMP_PLUGIN,
-                          G_N_ELEMENTS (save_args), 0,
-                          save_args, NULL);
-
-  gimp_register_file_handler_mime (SAVE_PROC, "image/jpeg");
-  gimp_register_save_handler (SAVE_PROC, "jpg,jpeg,jpe", "");
 }
 
-static void
-run (const gchar      *name,
-     gint              nparams,
-     const GimpParam  *param,
-     gint             *nreturn_vals,
-     GimpParam       **return_vals)
+static GList *
+jpeg_query_procedures (GimpPlugIn *plug_in)
 {
-  static GimpParam   values[6];
-  GimpRunMode        run_mode;
-  GimpPDBStatusType  status = GIMP_PDB_SUCCESS;
-  gint32             image_ID;
-  gint32             drawable_ID;
-  GimpParasite      *parasite;
-  GError            *error  = NULL;
+  GList *list = NULL;
 
-  run_mode = param[0].data.d_int32;
+  list = g_list_append (list, g_strdup (LOAD_PROC));
+  list = g_list_append (list, g_strdup (LOAD_THUMB_PROC));
+  list = g_list_append (list, g_strdup (SAVE_PROC));
+
+  return list;
+}
+
+static GimpProcedure *
+jpeg_create_procedure (GimpPlugIn  *plug_in,
+                      const gchar *name)
+{
+  GimpProcedure *procedure = NULL;
+
+  if (! strcmp (name, LOAD_PROC))
+    {
+      procedure = gimp_load_procedure_new (plug_in, name, GIMP_PLUGIN,
+                                           jpeg_load, NULL, NULL);
+
+      gimp_procedure_set_menu_label (procedure, N_("JPEG image"));
+
+      gimp_procedure_set_documentation (procedure,
+                                        "Loads files in the JPEG file format",
+                                        "Loads files in the JPEG file format",
+                                        name);
+      gimp_procedure_set_attribution (procedure,
+                                      "Spencer Kimball, Peter Mattis & others",
+                                      "Spencer Kimball & Peter Mattis",
+                                      "1995-2007");
+
+      gimp_file_procedure_set_mime_types (GIMP_FILE_PROCEDURE (procedure),
+                                          "image/jpeg");
+      gimp_file_procedure_set_extensions (GIMP_FILE_PROCEDURE (procedure),
+                                          "jpg,jpeg,jpe");
+      gimp_file_procedure_set_magics (GIMP_FILE_PROCEDURE (procedure),
+                                      "6,string,JFIF,6,string,Exif");
+
+      gimp_load_procedure_set_thumbnail_loader (GIMP_LOAD_PROCEDURE (procedure),
+                                                LOAD_THUMB_PROC);
+    }
+  else if (! strcmp (name, LOAD_THUMB_PROC))
+    {
+      procedure = gimp_thumbnail_procedure_new (plug_in, name, GIMP_PLUGIN,
+                                                jpeg_load_thumb, NULL, NULL);
+
+      gimp_procedure_set_documentation (procedure,
+                                        "Loads a thumbnail from a JPEG image",
+                                        "Loads a thumbnail from a JPEG image, "
+                                        "if one exists",
+                                        name);
+      gimp_procedure_set_attribution (procedure,
+                                      "Mukund Sivaraman <muks mukund org>, "
+                                      "Sven Neumann <sven gimp org>",
+                                      "Mukund Sivaraman <muks mukund org>, "
+                                      "Sven Neumann <sven gimp org>",
+                                      "November 15, 2004");
+    }
+  else if (! strcmp (name, SAVE_PROC))
+    {
+      procedure = gimp_save_procedure_new (plug_in, name, GIMP_PLUGIN,
+                                           jpeg_save, NULL, NULL);
+
+      gimp_procedure_set_image_types (procedure, "RGB*, GRAY*");
+
+      gimp_procedure_set_menu_label (procedure, N_("JPEG image"));
+
+      gimp_procedure_set_documentation (procedure,
+                                        "Saves files in the JPEG file format",
+                                        "Saves files in the lossy, widely "
+                                        "supported JPEG format",
+                                        name);
+      gimp_procedure_set_attribution (procedure,
+                                      "Spencer Kimball, Peter Mattis & others",
+                                      "Spencer Kimball & Peter Mattis",
+                                      "1995-2007");
+
+      gimp_file_procedure_set_mime_types (GIMP_FILE_PROCEDURE (procedure),
+                                          "image/jpeg");
+      gimp_file_procedure_set_extensions (GIMP_FILE_PROCEDURE (procedure),
+                                          "jpg,jpeg,jpe");
+
+      GIMP_PROC_ARG_DOUBLE (procedure, "quality",
+                            "Quality",
+                            "Quality of saved image",
+                            0.0, 1.0, 0.9,
+                            G_PARAM_READWRITE);
+
+      GIMP_PROC_ARG_DOUBLE (procedure, "smoothing",
+                            "Smoothing",
+                            "Smoothing factor for saved image",
+                            0.0, 1.0, 0.0,
+                            G_PARAM_READWRITE);
+
+      GIMP_PROC_ARG_BOOLEAN (procedure, "optimize",
+                             "Optimize",
+                             "Use optimized tables during Huffman coding",
+                             TRUE,
+                             G_PARAM_READWRITE);
+
+      GIMP_PROC_ARG_BOOLEAN (procedure, "progressive",
+                             "Progressive",
+                             "Create progressive JPEG images",
+                             TRUE,
+                             G_PARAM_READWRITE);
+
+      GIMP_PROC_ARG_STRING (procedure, "comment",
+                            "Comment",
+                            "Image comment",
+                            NULL,
+                            G_PARAM_READWRITE);
+
+      GIMP_PROC_ARG_INT (procedure, "sub-sampling",
+                         "Sub-sampling",
+                         "Sub-sampling type { 0 == 4:2:0 (chroma quartered), "
+                         "1 == 4:2:2 Horizontal (chroma halved), "
+                         "2 == 4:4:4 (best quality), "
+                         "3 == 4:2:2 Vertical (chroma halved)",
+                         JPEG_SUBSAMPLING_2x2_1x1_1x1,
+                         JPEG_SUBSAMPLING_1x2_1x1_1x1,
+                         JPEG_SUBSAMPLING_1x1_1x1_1x1,
+                         G_PARAM_READWRITE);
+
+      GIMP_PROC_ARG_BOOLEAN (procedure, "baseline",
+                             "Baseline",
+                             "Force creation of a baseline JPEG "
+                             "(non-baseline JPEGs can't be read by all decoders)",
+                             TRUE,
+                             G_PARAM_READWRITE);
+
+      GIMP_PROC_ARG_INT (procedure, "restart",
+                         "Restart",
+                         "Interval of restart markers "
+                         "(in MCU rows, 0 = no restart markers)",
+                         0, 64, 0,
+                         G_PARAM_READWRITE);
+
+      GIMP_PROC_ARG_INT (procedure, "dct",
+                         "DCT",
+                         "DCT method to use { "
+                         "INTEGER (0), "
+                         "FIXED (1), "
+                         "FLOAT (2) }",
+                         0, 2, 0,
+                         G_PARAM_READWRITE);
+    }
+
+  return procedure;
+}
+
+static GimpValueArray *
+jpeg_load (GimpProcedure        *procedure,
+          GimpRunMode           run_mode,
+          GFile                *file,
+          const GimpValueArray *args,
+          gpointer              run_data)
+{
+  GimpValueArray *return_vals;
+  gchar          *filename;
+  GimpImage      *image;
+  gboolean        resolution_loaded = FALSE;
+  GError         *error             = NULL;
 
   INIT_I18N ();
   gegl_init (NULL, NULL);
 
-  *nreturn_vals = 1;
-  *return_vals  = values;
-  values[0].type          = GIMP_PDB_STATUS;
-  values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
-
-  preview_image_ID = -1;
-  preview_layer_ID = -1;
+  preview_image = NULL;
+  preview_layer = NULL;
 
   orig_quality = 0;
   orig_subsmp = JPEG_SUBSAMPLING_2x2_1x1_1x1;
   num_quant_tables = 0;
 
-  if (strcmp (name, LOAD_PROC) == 0)
+  filename = g_file_get_path (file);
+
+  switch (run_mode)
     {
-      GFile *file = g_file_new_for_uri (param[1].data.d_string);
+    case GIMP_RUN_INTERACTIVE:
+    case GIMP_RUN_WITH_LAST_VALS:
+      gimp_ui_init (PLUG_IN_BINARY, FALSE);
+      load_interactive = TRUE;
+      break;
+
+    default:
+      load_interactive = FALSE;
+      break;
+    }
+
+  image = load_image (filename, run_mode, FALSE,
+                      &resolution_loaded, &error);
 
-      gboolean  resolution_loaded = FALSE;
+  if (image)
+    {
+      GimpMetadata *metadata;
 
-      switch (run_mode)
+      metadata = gimp_image_metadata_load_prepare (image, "image/jpeg",
+                                                   file, NULL);
+
+      if (metadata)
         {
-        case GIMP_RUN_INTERACTIVE:
-        case GIMP_RUN_WITH_LAST_VALS:
-          gimp_ui_init (PLUG_IN_BINARY, FALSE);
-          load_interactive = TRUE;
-          break;
-        default:
-          load_interactive = FALSE;
-          break;
+          GimpMetadataLoadFlags flags = GIMP_METADATA_LOAD_ALL;
+
+          if (resolution_loaded)
+            flags &= ~GIMP_METADATA_LOAD_RESOLUTION;
+
+          gimp_image_metadata_load_finish (image, "image/jpeg",
+                                           metadata, flags,
+                                           load_interactive);
+
+          g_object_unref (metadata);
         }
+    }
 
-      image_ID = load_image (g_file_get_path (file), run_mode, FALSE,
-                             &resolution_loaded, &error);
+  g_free (filename);
 
-      if (image_ID != -1)
-        {
-          GimpMetadata *metadata;
+  if (! image)
+    return gimp_procedure_new_return_values (procedure,
+                                             GIMP_PDB_EXECUTION_ERROR,
+                                             error);
 
-          metadata = gimp_image_metadata_load_prepare (image_ID, "image/jpeg",
-                                                       file, NULL);
+  return_vals = gimp_procedure_new_return_values (procedure,
+                                                  GIMP_PDB_SUCCESS,
+                                                  NULL);
 
-          if (metadata)
-            {
-              GimpMetadataLoadFlags flags = GIMP_METADATA_LOAD_ALL;
+  GIMP_VALUES_SET_IMAGE (return_vals, 1, image);
 
-              if (resolution_loaded)
-                flags &= ~GIMP_METADATA_LOAD_RESOLUTION;
+  return return_vals;
+}
 
-              gimp_image_metadata_load_finish (image_ID, "image/jpeg",
-                                               metadata, flags,
-                                               load_interactive);
+static GimpValueArray *
+jpeg_load_thumb (GimpProcedure        *procedure,
+                GFile                *file,
+                gint                  size,
+                const GimpValueArray *args,
+                gpointer              run_data)
+{
+  GimpValueArray *return_vals;
+  GimpImage      *image;
+  gint            width  = 0;
+  gint            height = 0;
+  GimpImageType   type   = -1;
+  GError         *error  = NULL;
 
-              g_object_unref (metadata);
-            }
+  INIT_I18N ();
+  gegl_init (NULL, NULL);
 
-          *nreturn_vals = 2;
-          values[1].type         = GIMP_PDB_IMAGE;
-          values[1].data.d_image = image_ID;
-        }
-      else
-        {
-          status = GIMP_PDB_EXECUTION_ERROR;
-        }
-    }
-  else if (strcmp (name, LOAD_THUMB_PROC) == 0)
-    {
-      if (nparams < 2)
-        {
-          status = GIMP_PDB_CALLING_ERROR;
-        }
-      else
-        {
-          GFile        *file   = g_file_new_for_uri (param[0].data.d_string);
-          gint          width  = 0;
-          gint          height = 0;
-          GimpImageType type   = -1;
+  preview_image = NULL;
+  preview_layer = NULL;
 
-          image_ID = load_thumbnail_image (file, &width, &height, &type,
-                                           &error);
+  orig_quality = 0;
+  orig_subsmp = JPEG_SUBSAMPLING_2x2_1x1_1x1;
+  num_quant_tables = 0;
 
-          g_object_unref (file);
+  image = load_thumbnail_image (file, &width, &height, &type,
+                                &error);
 
-          if (image_ID != -1)
-            {
-              *nreturn_vals = 6;
-              values[1].type         = GIMP_PDB_IMAGE;
-              values[1].data.d_image = image_ID;
-              values[2].type         = GIMP_PDB_INT32;
-              values[2].data.d_int32 = width;
-              values[3].type         = GIMP_PDB_INT32;
-              values[3].data.d_int32 = height;
-              values[4].type         = GIMP_PDB_INT32;
-              values[4].data.d_int32 = type;
-              values[5].type         = GIMP_PDB_INT32;
-              values[5].data.d_int32 = 1; /* num_layers */
-            }
-          else
-            {
-              status = GIMP_PDB_EXECUTION_ERROR;
-            }
-        }
-    }
-  else if (strcmp (name, SAVE_PROC) == 0)
-    {
-      GFile                 *file = g_file_new_for_uri (param[3].data.d_string);
-      GimpMetadata          *metadata;
-      GimpMetadataSaveFlags  metadata_flags;
-      gint32                 orig_image_ID;
-      GimpExportReturn       export = GIMP_EXPORT_CANCEL;
 
-      image_ID    = param[1].data.d_int32;
-      drawable_ID = param[2].data.d_int32;
+  if (! image)
+    return gimp_procedure_new_return_values (procedure,
+                                             GIMP_PDB_EXECUTION_ERROR,
+                                             error);
 
-      orig_image_ID = image_ID;
+  return_vals = gimp_procedure_new_return_values (procedure,
+                                                  GIMP_PDB_SUCCESS,
+                                                  NULL);
 
-      switch (run_mode)
-        {
-        case GIMP_RUN_INTERACTIVE:
-        case GIMP_RUN_WITH_LAST_VALS:
-          gimp_ui_init (PLUG_IN_BINARY, FALSE);
+  GIMP_VALUES_SET_IMAGE (return_vals, 1, image);
+  GIMP_VALUES_SET_INT   (return_vals, 2, width);
+  GIMP_VALUES_SET_INT   (return_vals, 3, height);
+  GIMP_VALUES_SET_ENUM  (return_vals, 4, type);
+  GIMP_VALUES_SET_INT   (return_vals, 5, 1); /* 1 layer */
 
-          export = gimp_export_image (&image_ID, &drawable_ID, "JPEG",
-                                      GIMP_EXPORT_CAN_HANDLE_RGB |
-                                      GIMP_EXPORT_CAN_HANDLE_GRAY);
+  return return_vals;
+}
 
-          switch (export)
-            {
-            case GIMP_EXPORT_EXPORT:
+static GimpValueArray *
+jpeg_save (GimpProcedure        *procedure,
+          GimpRunMode           run_mode,
+          GimpImage            *image,
+          GimpDrawable         *drawable,
+          GFile                *file,
+          const GimpValueArray *args,
+          gpointer              run_data)
+{
+  GimpPDBStatusType      status = GIMP_PDB_SUCCESS;
+  gchar                 *filename;
+  GimpParasite          *parasite;
+  GimpMetadata          *metadata;
+  GimpMetadataSaveFlags  metadata_flags;
+  GimpImage             *orig_image;
+  GimpExportReturn       export = GIMP_EXPORT_CANCEL;
+  GError                *error  = NULL;
+
+  INIT_I18N ();
+  gegl_init (NULL, NULL);
+
+  preview_image = NULL;
+  preview_layer = NULL;
+
+  orig_quality = 0;
+  orig_subsmp = JPEG_SUBSAMPLING_2x2_1x1_1x1;
+  num_quant_tables = 0;
+
+  orig_image = image;
+
+  filename = g_file_get_path (file);
+
+  switch (run_mode)
+    {
+    case GIMP_RUN_INTERACTIVE:
+    case GIMP_RUN_WITH_LAST_VALS:
+      gimp_ui_init (PLUG_IN_BINARY, FALSE);
+
+      export = gimp_export_image (&image, &drawable, "JPEG",
+                                  GIMP_EXPORT_CAN_HANDLE_RGB |
+                                  GIMP_EXPORT_CAN_HANDLE_GRAY);
+
+      switch (export)
+        {
+        case GIMP_EXPORT_EXPORT:
+          {
+            gchar *tmp = g_filename_from_utf8 (_("Export Preview"), -1,
+                                               NULL, NULL, NULL);
+            if (tmp)
               {
-                gchar *tmp = g_filename_from_utf8 (_("Export Preview"), -1,
-                                                   NULL, NULL, NULL);
-                if (tmp)
-                  {
-                    gimp_image_set_filename (image_ID, tmp);
-                    g_free (tmp);
-                  }
-
-                display_ID = -1;
+                gimp_image_set_filename (image, tmp);
+                g_free (tmp);
               }
-              break;
 
-            case GIMP_EXPORT_IGNORE:
-              break;
+            display = NULL;
+          }
+          break;
 
-            case GIMP_EXPORT_CANCEL:
-              values[0].data.d_status = GIMP_PDB_CANCEL;
-              return;
-              break;
-            }
+        case GIMP_EXPORT_IGNORE:
           break;
 
-        default:
+        case GIMP_EXPORT_CANCEL:
+          return gimp_procedure_new_return_values (procedure,
+                                                   GIMP_PDB_CANCEL,
+                                                   NULL);
           break;
         }
+      break;
 
-      /* Initialize with hardcoded defaults */
-      load_defaults ();
+    default:
+      break;
+    }
 
-      /* Override the defaults with preferences. */
-      metadata = gimp_image_metadata_save_prepare (orig_image_ID,
-                                                   "image/jpeg",
-                                                   &metadata_flags);
-      jsvals.save_exif      = (metadata_flags & GIMP_METADATA_SAVE_EXIF) != 0;
-      jsvals.save_xmp       = (metadata_flags & GIMP_METADATA_SAVE_XMP) != 0;
-      jsvals.save_iptc      = (metadata_flags & GIMP_METADATA_SAVE_IPTC) != 0;
-      jsvals.save_thumbnail = (metadata_flags & GIMP_METADATA_SAVE_THUMBNAIL) != 0;
-      jsvals.save_profile   = (metadata_flags & GIMP_METADATA_SAVE_COLOR_PROFILE) != 0;
+  /* Initialize with hardcoded defaults */
+  load_defaults ();
 
-      parasite = gimp_image_get_parasite (orig_image_ID, "gimp-comment");
+  /* Override the defaults with preferences. */
+  metadata = gimp_image_metadata_save_prepare (orig_image,
+                                               "image/jpeg",
+                                               &metadata_flags);
+  jsvals.save_exif      = (metadata_flags & GIMP_METADATA_SAVE_EXIF) != 0;
+  jsvals.save_xmp       = (metadata_flags & GIMP_METADATA_SAVE_XMP) != 0;
+  jsvals.save_iptc      = (metadata_flags & GIMP_METADATA_SAVE_IPTC) != 0;
+  jsvals.save_thumbnail = (metadata_flags & GIMP_METADATA_SAVE_THUMBNAIL) != 0;
+  jsvals.save_profile   = (metadata_flags & GIMP_METADATA_SAVE_COLOR_PROFILE) != 0;
+
+  parasite = gimp_image_get_parasite (orig_image, "gimp-comment");
+  if (parasite)
+    {
+      image_comment = g_strndup (gimp_parasite_data (parasite),
+                                 gimp_parasite_data_size (parasite));
+      gimp_parasite_free (parasite);
+    }
+
+  /* Override preferences from JPG export defaults (if saved). */
+  load_parasite ();
+
+  switch (run_mode)
+    {
+    case GIMP_RUN_NONINTERACTIVE:
+      g_free (image_comment);
+
+      jsvals.quality     = GIMP_VALUES_GET_DOUBLE  (args, 0) * 100.0;
+      jsvals.smoothing   = GIMP_VALUES_GET_DOUBLE  (args, 1);
+      jsvals.optimize    = GIMP_VALUES_GET_BOOLEAN (args, 2);
+      jsvals.progressive = GIMP_VALUES_GET_BOOLEAN (args, 3);
+      image_comment      = GIMP_VALUES_DUP_STRING  (args, 4);
+      jsvals.subsmp      = GIMP_VALUES_GET_DOUBLE  (args, 5);
+      jsvals.baseline    = GIMP_VALUES_GET_DOUBLE  (args, 6);
+      jsvals.restart     = GIMP_VALUES_GET_DOUBLE  (args, 7);
+      jsvals.dct         = GIMP_VALUES_GET_DOUBLE  (args, 8);
+      jsvals.preview     = FALSE;
+      break;
+
+    case GIMP_RUN_INTERACTIVE:
+    case GIMP_RUN_WITH_LAST_VALS:
+      /* restore the values found when loading the file (if available) */
+      jpeg_restore_original_settings (orig_image,
+                                      &orig_quality,
+                                      &orig_subsmp,
+                                      &num_quant_tables);
+
+      /* load up the previously used values (if file was saved once) */
+      parasite = gimp_image_get_parasite (orig_image,
+                                          "jpeg-save-options");
       if (parasite)
         {
-          image_comment = g_strndup (gimp_parasite_data (parasite),
-                                     gimp_parasite_data_size (parasite));
+          const JpegSaveVals *save_vals = gimp_parasite_data (parasite);
+
+          jsvals.quality          = save_vals->quality;
+          jsvals.smoothing        = save_vals->smoothing;
+          jsvals.optimize         = save_vals->optimize;
+          jsvals.progressive      = save_vals->progressive;
+          jsvals.baseline         = save_vals->baseline;
+          jsvals.subsmp           = save_vals->subsmp;
+          jsvals.restart          = save_vals->restart;
+          jsvals.dct              = save_vals->dct;
+          jsvals.preview          = save_vals->preview;
+          jsvals.save_exif        = save_vals->save_exif;
+          jsvals.save_thumbnail   = save_vals->save_thumbnail;
+          jsvals.save_xmp         = save_vals->save_xmp;
+          jsvals.save_iptc        = save_vals->save_iptc;
+          jsvals.use_orig_quality = save_vals->use_orig_quality;
+
           gimp_parasite_free (parasite);
         }
-
-      /* Override preferences from JPG export defaults (if saved). */
-      load_parasite ();
-
-      switch (run_mode)
+      else
         {
-        case GIMP_RUN_NONINTERACTIVE:
-          /*  Make sure all the arguments are there!  */
-          /*  pw - added two more progressive and comment */
-          /*  sg - added subsampling, preview, baseline, restarts and DCT */
-          if (nparams != 14)
-            {
-              status = GIMP_PDB_CALLING_ERROR;
-            }
-          else
+          /* We are called with GIMP_RUN_WITH_LAST_VALS but this image
+           * doesn't have a "jpeg-save-options" parasite. It's better
+           * to prompt the user with a dialog now so that she has
+           * control over the JPEG encoding parameters.
+           */
+          run_mode = GIMP_RUN_INTERACTIVE;
+
+          /* If this image was loaded from a JPEG file and has not
+           * been saved yet, try to use some of the settings from the
+           * original file if they are better than the default values.
+           */
+          if (orig_quality > jsvals.quality)
             {
-              /* Once the PDB gets default parameters, remove this hack */
-              if (param[5].data.d_float >= 0.01)
-                {
-                  jsvals.quality     = 100.0 * param[5].data.d_float;
-                  jsvals.smoothing   = param[6].data.d_float;
-                  jsvals.optimize    = param[7].data.d_int32;
-                  jsvals.progressive = param[8].data.d_int32;
-                  jsvals.baseline    = param[11].data.d_int32;
-                  jsvals.subsmp      = param[10].data.d_int32;
-                  jsvals.restart     = param[12].data.d_int32;
-                  jsvals.dct         = param[13].data.d_int32;
-
-                  /* free up the default -- wasted some effort earlier */
-                  g_free (image_comment);
-                  image_comment = g_strdup (param[9].data.d_string);
-                }
-
-              jsvals.preview = FALSE;
-
-              if (jsvals.quality < 0.0 || jsvals.quality > 100.0)
-                status = GIMP_PDB_CALLING_ERROR;
-              else if (jsvals.smoothing < 0.0 || jsvals.smoothing > 1.0)
-                status = GIMP_PDB_CALLING_ERROR;
-              else if (jsvals.subsmp < 0 || jsvals.subsmp > 3)
-                status = GIMP_PDB_CALLING_ERROR;
-              else if (jsvals.dct < 0 || jsvals.dct > 2)
-                status = GIMP_PDB_CALLING_ERROR;
+              jsvals.quality = orig_quality;
             }
-          break;
 
-        case GIMP_RUN_INTERACTIVE:
-        case GIMP_RUN_WITH_LAST_VALS:
-          /* restore the values found when loading the file (if available) */
-          jpeg_restore_original_settings (orig_image_ID,
-                                          &orig_quality,
-                                          &orig_subsmp,
-                                          &num_quant_tables);
-
-          /* load up the previously used values (if file was saved once) */
-          parasite = gimp_image_get_parasite (orig_image_ID,
-                                              "jpeg-save-options");
-          if (parasite)
+          /* Skip changing subsampling to original if we already have
+           * best setting or if original have worst setting
+           */
+          if (!(jsvals.subsmp == JPEG_SUBSAMPLING_1x1_1x1_1x1 ||
+                orig_subsmp == JPEG_SUBSAMPLING_2x2_1x1_1x1))
             {
-              const JpegSaveVals *save_vals = gimp_parasite_data (parasite);
-
-              jsvals.quality          = save_vals->quality;
-              jsvals.smoothing        = save_vals->smoothing;
-              jsvals.optimize         = save_vals->optimize;
-              jsvals.progressive      = save_vals->progressive;
-              jsvals.baseline         = save_vals->baseline;
-              jsvals.subsmp           = save_vals->subsmp;
-              jsvals.restart          = save_vals->restart;
-              jsvals.dct              = save_vals->dct;
-              jsvals.preview          = save_vals->preview;
-              jsvals.save_exif        = save_vals->save_exif;
-              jsvals.save_thumbnail   = save_vals->save_thumbnail;
-              jsvals.save_xmp         = save_vals->save_xmp;
-              jsvals.save_iptc        = save_vals->save_iptc;
-              jsvals.use_orig_quality = save_vals->use_orig_quality;
-
-              gimp_parasite_free (parasite);
+              jsvals.subsmp = orig_subsmp;
             }
-          else
+
+          if (orig_quality == jsvals.quality &&
+              orig_subsmp == jsvals.subsmp)
             {
-              /* We are called with GIMP_RUN_WITH_LAST_VALS but this image
-               * doesn't have a "jpeg-save-options" parasite. It's better
-               * to prompt the user with a dialog now so that she has control
-               * over the JPEG encoding parameters.
-               */
-              run_mode = GIMP_RUN_INTERACTIVE;
-
-              /* If this image was loaded from a JPEG file and has not been
-               * saved yet, try to use some of the settings from the
-               * original file if they are better than the default values.
-               */
-              if (orig_quality > jsvals.quality)
-                {
-                  jsvals.quality = orig_quality;
-                }
-
-              /* Skip changing subsampling to original if we already have best
-               * setting or if original have worst setting */
-              if (!(jsvals.subsmp == JPEG_SUBSAMPLING_1x1_1x1_1x1 ||
-                    orig_subsmp == JPEG_SUBSAMPLING_2x2_1x1_1x1))
-                {
-                  jsvals.subsmp = orig_subsmp;
-                }
-
-              if (orig_quality == jsvals.quality &&
-                  orig_subsmp == jsvals.subsmp)
-                {
-                  jsvals.use_orig_quality = TRUE;
-                }
+              jsvals.use_orig_quality = TRUE;
             }
-          break;
         }
+      break;
+    }
 
-      if (run_mode == GIMP_RUN_INTERACTIVE)
+  if (run_mode == GIMP_RUN_INTERACTIVE)
+    {
+      if (jsvals.preview)
         {
-          if (jsvals.preview)
-            {
-              /* we freeze undo saving so that we can avoid sucking up
-               * tile cache with our unneeded preview steps. */
-              gimp_image_undo_freeze (image_ID);
+          /* we freeze undo saving so that we can avoid sucking up
+           * tile cache with our unneeded preview steps. */
+          gimp_image_undo_freeze (image);
 
-              undo_touched = TRUE;
-            }
-
-          /* prepare for the preview */
-          preview_image_ID = image_ID;
-          orig_image_ID_global = orig_image_ID;
-          drawable_ID_global = drawable_ID;
-
-          /*  First acquire information with a dialog  */
-          status = (save_dialog () ? GIMP_PDB_SUCCESS : GIMP_PDB_CANCEL);
-
-          if (undo_touched)
-            {
-              /* thaw undo saving and flush the displays to have them
-               * reflect the current shortcuts */
-              gimp_image_undo_thaw (image_ID);
-              gimp_displays_flush ();
-            }
+          undo_touched = TRUE;
         }
 
-      if (status == GIMP_PDB_SUCCESS)
+      /* prepare for the preview */
+      preview_image     = image;
+      orig_image_global = orig_image;
+      drawable_global   = drawable;
+
+      /*  First acquire information with a dialog  */
+      if (! save_dialog ())
         {
-          if (! save_image (g_file_get_path (file),
-                            image_ID, drawable_ID, orig_image_ID, FALSE,
-                            &error))
-            {
-              status = GIMP_PDB_EXECUTION_ERROR;
-            }
+          status = GIMP_PDB_CANCEL;
         }
 
-      if (export == GIMP_EXPORT_EXPORT)
+      if (undo_touched)
         {
-          /* If the image was exported, delete the new display. */
-          /* This also deletes the image.
+          /* thaw undo saving and flush the displays to have them
+           * reflect the current shortcuts
            */
-
-          if (display_ID != -1)
-            gimp_display_delete (display_ID);
-          else
-            gimp_image_delete (image_ID);
+          gimp_image_undo_thaw (image);
+          gimp_displays_flush ();
         }
+    }
 
-      if (status == GIMP_PDB_SUCCESS)
+  if (status == GIMP_PDB_SUCCESS)
+    {
+      if (! save_image (filename,
+                        image, drawable, orig_image, FALSE,
+                        &error))
         {
-          /* pw - now we need to change the defaults to be whatever
-           * was used to save this image.  Dump the old parasites
-           * and add new ones.
-           */
+          status = GIMP_PDB_EXECUTION_ERROR;
+        }
+    }
 
-          gimp_image_detach_parasite (orig_image_ID, "gimp-comment");
-          if (image_comment && strlen (image_comment))
-            {
-              parasite = gimp_parasite_new ("gimp-comment",
-                                            GIMP_PARASITE_PERSISTENT,
-                                            strlen (image_comment) + 1,
-                                            image_comment);
-              gimp_image_attach_parasite (orig_image_ID, parasite);
-              gimp_parasite_free (parasite);
-            }
+  if (export == GIMP_EXPORT_EXPORT)
+    {
+      /* If the image was exported, delete the new display. This also
+       * deletes the image.
+       */
+      if (display)
+        gimp_display_delete (display);
+      else
+        gimp_image_delete (image);
+    }
 
-          parasite = gimp_parasite_new ("jpeg-save-options",
-                                        0, sizeof (jsvals), &jsvals);
-          gimp_image_attach_parasite (orig_image_ID, parasite);
+  if (status == GIMP_PDB_SUCCESS)
+    {
+      /* pw - now we need to change the defaults to be whatever was
+       * used to save this image.  Dump the old parasites and add new
+       * ones.
+       */
+
+      gimp_image_detach_parasite (orig_image, "gimp-comment");
+      if (image_comment && strlen (image_comment))
+        {
+          parasite = gimp_parasite_new ("gimp-comment",
+                                        GIMP_PARASITE_PERSISTENT,
+                                        strlen (image_comment) + 1,
+                                        image_comment);
+          gimp_image_attach_parasite (orig_image, parasite);
           gimp_parasite_free (parasite);
+        }
 
-          /* write metadata */
+      parasite = gimp_parasite_new ("jpeg-save-options",
+                                    0, sizeof (jsvals), &jsvals);
+      gimp_image_attach_parasite (orig_image, parasite);
+      gimp_parasite_free (parasite);
 
-          if (metadata)
-            {
-              gimp_metadata_set_bits_per_sample (metadata, 8);
-
-              if (jsvals.save_exif)
-                metadata_flags |= GIMP_METADATA_SAVE_EXIF;
-              else
-                metadata_flags &= ~GIMP_METADATA_SAVE_EXIF;
-
-              if (jsvals.save_xmp)
-                metadata_flags |= GIMP_METADATA_SAVE_XMP;
-              else
-                metadata_flags &= ~GIMP_METADATA_SAVE_XMP;
-
-              if (jsvals.save_iptc)
-                metadata_flags |= GIMP_METADATA_SAVE_IPTC;
-              else
-                metadata_flags &= ~GIMP_METADATA_SAVE_IPTC;
-
-              if (jsvals.save_thumbnail)
-                metadata_flags |= GIMP_METADATA_SAVE_THUMBNAIL;
-              else
-                metadata_flags &= ~GIMP_METADATA_SAVE_THUMBNAIL;
-
-              if (jsvals.save_profile)
-                metadata_flags |= GIMP_METADATA_SAVE_COLOR_PROFILE;
-              else
-                metadata_flags &= ~GIMP_METADATA_SAVE_COLOR_PROFILE;
-
-              gimp_image_metadata_save_finish (orig_image_ID,
-                                               "image/jpeg",
-                                               metadata, metadata_flags,
-                                               file, NULL);
-            }
-        }
+      /* write metadata */
 
       if (metadata)
-        g_object_unref (metadata);
-    }
-  else
-    {
-      status = GIMP_PDB_CALLING_ERROR;
-    }
+        {
+          gimp_metadata_set_bits_per_sample (metadata, 8);
 
-  if (status != GIMP_PDB_SUCCESS && error)
-    {
-      *nreturn_vals = 2;
-      values[1].type          = GIMP_PDB_STRING;
-      values[1].data.d_string = error->message;
+          if (jsvals.save_exif)
+            metadata_flags |= GIMP_METADATA_SAVE_EXIF;
+          else
+            metadata_flags &= ~GIMP_METADATA_SAVE_EXIF;
+
+          if (jsvals.save_xmp)
+            metadata_flags |= GIMP_METADATA_SAVE_XMP;
+          else
+            metadata_flags &= ~GIMP_METADATA_SAVE_XMP;
+
+          if (jsvals.save_iptc)
+            metadata_flags |= GIMP_METADATA_SAVE_IPTC;
+          else
+            metadata_flags &= ~GIMP_METADATA_SAVE_IPTC;
+
+          if (jsvals.save_thumbnail)
+            metadata_flags |= GIMP_METADATA_SAVE_THUMBNAIL;
+          else
+            metadata_flags &= ~GIMP_METADATA_SAVE_THUMBNAIL;
+
+          if (jsvals.save_profile)
+            metadata_flags |= GIMP_METADATA_SAVE_COLOR_PROFILE;
+          else
+            metadata_flags &= ~GIMP_METADATA_SAVE_COLOR_PROFILE;
+
+          gimp_image_metadata_save_finish (orig_image,
+                                           "image/jpeg",
+                                           metadata, metadata_flags,
+                                           file, NULL);
+        }
     }
 
-  values[0].data.d_status = status;
+  if (metadata)
+    g_object_unref (metadata);
+
+  g_free (filename);
+
+  return gimp_procedure_new_return_values (procedure, status, error);
 }
 
 /*
diff --git a/plug-ins/file-jpeg/jpeg.h b/plug-ins/file-jpeg/jpeg.h
index 0bf9af0cf3..ca0710c948 100644
--- a/plug-ins/file-jpeg/jpeg.h
+++ b/plug-ins/file-jpeg/jpeg.h
@@ -51,11 +51,11 @@ typedef enum
   JPEG_SUBSAMPLING_1x2_1x1_1x1 = 3
 } JpegSubsampling;
 
-extern gint32 volatile  preview_image_ID;
-extern gint32           preview_layer_ID;
+extern GimpImage * volatile  preview_image;
+extern GimpLayer *      preview_layer;
 extern gboolean         undo_touched;
 extern gboolean         load_interactive;
-extern gint32           display_ID;
+extern GimpDisplay     *display;
 extern gchar           *image_comment;
 extern gint             orig_quality;
 extern JpegSubsampling  orig_subsmp;


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