[gimp] plug-ins: lots of cleanup and fixes in file-webp



commit e4ecba584a8eedc0bf750e24813e6ad66e27d0aa
Author: Michael Natterer <mitch gimp org>
Date:   Sun Sep 4 17:48:03 2016 +0200

    plug-ins: lots of cleanup and fixes in file-webp
    
    - handle all sorts of image types, gegl_buffer_get() will convert to u8
    - specify GIMP_EXPORT_CAN_HANDLE_LAYERS_AS_ANIMATION
    - modify the export duplicate, not the original image
    - fix handling of the drawable type and only save "R'G'B'A u8"
      or "R'G'B' u8", fixes bug 770664.
    - completely redo run(SAVE_PROC) to deal with export correctly
    - turn global variables into the standard SAVE_PROC, PLUG_IN_BINARY etc
      defines
    - simplify the save dialog

 plug-ins/file-webp/file-webp-dialog.c |   24 ++----
 plug-ins/file-webp/file-webp-load.c   |   14 ++--
 plug-ins/file-webp/file-webp-save.c   |   37 +++++++---
 plug-ins/file-webp/file-webp.c        |  131 +++++++++++++++++----------------
 plug-ins/file-webp/file-webp.h        |   14 ++-
 5 files changed, 115 insertions(+), 105 deletions(-)
---
diff --git a/plug-ins/file-webp/file-webp-dialog.c b/plug-ins/file-webp/file-webp-dialog.c
index 6580e5a..600b62a 100644
--- a/plug-ins/file-webp/file-webp-dialog.c
+++ b/plug-ins/file-webp/file-webp-dialog.c
@@ -98,7 +98,7 @@ save_dialog (WebPSaveParams *params,
   GtkWidget    *table;
   GtkWidget    *expander;
   GtkWidget    *frame;
-  GtkWidget    *table2;
+  GtkWidget    *vbox2;
   GtkWidget    *save_exif;
   GtkWidget    *save_xmp;
   GtkWidget    *preset_label;
@@ -117,8 +117,7 @@ save_dialog (WebPSaveParams *params,
   animation_supported = n_layers > 1;
 
   /* Create the dialog */
-  dialog = gimp_export_dialog_new (_("WebP"),BINARY_NAME,
-                                   SAVE_PROCEDURE);
+  dialog = gimp_export_dialog_new (_("WebP"), PLUG_IN_BINARY, SAVE_PROC);
 
   /* Create the vbox */
   vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
@@ -272,18 +271,14 @@ save_dialog (WebPSaveParams *params,
   gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
   gtk_widget_show (frame);
 
-  table2 = gtk_table_new (2, 1, FALSE);
-  gtk_table_set_col_spacings (GTK_TABLE (table2), 6);
-  gtk_table_set_row_spacings (GTK_TABLE (table2), 6);
-  gtk_table_set_col_spacing (GTK_TABLE (table2), 1, 12);
-  gtk_container_add (GTK_CONTAINER (frame), table2);
+  vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
+  gtk_container_add (GTK_CONTAINER (frame), vbox2);
+  gtk_widget_show (vbox2);
 
   /* Save EXIF data */
   save_exif = gtk_check_button_new_with_mnemonic (_("Save _Exif data"));
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (save_exif), params->exif);
-  gtk_widget_set_sensitive (save_exif, TRUE);
-  gtk_table_attach (GTK_TABLE (table2), save_exif, 0, 1,
-                    0, 1, GTK_FILL, 0, 0, 0);
+  gtk_box_pack_start (GTK_BOX (vbox2), save_exif, FALSE, FALSE, 0);
   gtk_widget_show (save_exif);
 
   g_signal_connect (save_exif, "toggled",
@@ -293,18 +288,13 @@ save_dialog (WebPSaveParams *params,
   /* XMP metadata */
   save_xmp = gtk_check_button_new_with_mnemonic (_("Save _XMP data"));
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (save_xmp), params->xmp);
-  gtk_table_attach (GTK_TABLE (table2), save_xmp, 0, 1,
-                    1, 2, GTK_FILL, 0, 0, 0);
+  gtk_box_pack_start (GTK_BOX (vbox2), save_xmp, FALSE, FALSE, 0);
   gtk_widget_show (save_xmp);
 
   g_signal_connect (save_xmp, "toggled",
                     G_CALLBACK (gimp_toggle_button_update),
                     &params->xmp);
 
-  gtk_widget_set_sensitive (save_xmp, TRUE);
-
-  gtk_widget_show (table2);
-
   gtk_widget_show (dialog);
 
   run = (gimp_dialog_run (GIMP_DIALOG (dialog)) == GTK_RESPONSE_OK);
diff --git a/plug-ins/file-webp/file-webp-load.c b/plug-ins/file-webp/file-webp-load.c
index 0b669f2..3bcc584 100644
--- a/plug-ins/file-webp/file-webp-load.c
+++ b/plug-ins/file-webp/file-webp-load.c
@@ -25,15 +25,15 @@
 #include <stdlib.h>
 #include <stdint.h>
 
+#include <webp/decode.h>
+#include <webp/demux.h>
+#include <webp/mux.h>
+
 #include <gegl.h>
 
 #include <libgimp/gimp.h>
 #include <libgimp/gimpui.h>
 
-#include <webp/decode.h>
-#include <webp/demux.h>
-#include <webp/mux.h>
-
 #include "file-webp-load.h"
 
 #include "libgimp/stdplugins-intl.h"
@@ -106,12 +106,12 @@ load_image (const gchar *filename,
       return -1;
     }
 
-  g_printerr ("Loading WebP file %s\n", filename);
-
   /* Validate WebP data */
   if (! WebPGetInfo (indata, indatalen, &width, &height))
     {
-      g_printerr ("Invalid WebP file\n");
+      g_set_error (error, G_FILE_ERROR, 0,
+                   "Invalid WebP file '%s'",
+                   gimp_filename_to_utf8 (filename));
       return -1;
     }
 
diff --git a/plug-ins/file-webp/file-webp-save.c b/plug-ins/file-webp/file-webp-save.c
index b7e380b..02f8b7f 100644
--- a/plug-ins/file-webp/file-webp-save.c
+++ b/plug-ins/file-webp/file-webp-save.c
@@ -179,9 +179,10 @@ save_layer (const gchar    *filename,
   WebPPicture       picture  = {0};
   guchar           *buffer   = NULL;
   gint              w, h;
+  gboolean          has_alpha;
+  const Babl       *format;
   gint              bpp;
   GimpColorProfile *profile;
-  GimpImageType     drawable_type;
   GeglBuffer       *geglbuffer = NULL;
   GeglRectangle     extent;
   gchar            *indata;
@@ -213,12 +214,18 @@ save_layer (const gchar    *filename,
         }
 
       /* Obtain the drawable type */
-      drawable_type = gimp_drawable_type (drawable_ID);
+      has_alpha = gimp_drawable_has_alpha (drawable_ID);
+
+      if (has_alpha)
+        format = babl_format ("R'G'B'A u8");
+      else
+        format = babl_format ("R'G'B' u8");
+
+      bpp = babl_format_get_bytes_per_pixel (format);
 
       /* Retrieve the buffer for the layer */
       geglbuffer = gimp_drawable_get_buffer (drawable_ID);
       extent = *gegl_buffer_get_extent (geglbuffer);
-      bpp = gimp_drawable_bpp (drawable_ID);
       w = extent.width;
       h = extent.height;
 
@@ -247,11 +254,11 @@ save_layer (const gchar    *filename,
         break;
 
       /* Read the region into the buffer */
-      gegl_buffer_get (geglbuffer, &extent, 1.0, NULL, buffer,
+      gegl_buffer_get (geglbuffer, &extent, 1.0, format, buffer,
                        GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
 
       /* Use the appropriate function to import the data from the buffer */
-      if (drawable_type == GIMP_RGB_IMAGE)
+      if (! has_alpha)
         {
           WebPPictureImportRGB (&picture, buffer, w * bpp);
         }
@@ -374,8 +381,10 @@ save_animation (const gchar    *filename,
   gboolean               status   = FALSE;
   FILE                  *outfile  = NULL;
   guchar                *buffer   = NULL;
-  gint                   w, h, bpp;
-  GimpImageType          drawable_type;
+  gint                   w, h;
+  gint                   bpp;
+  gboolean               has_alpha;
+  const Babl            *format;
   GimpColorProfile      *profile;
   WebPAnimEncoderOptions enc_options;
   WebPData               webp_data;
@@ -423,7 +432,14 @@ save_animation (const gchar    *filename,
           WebPMemoryWriter  mw = { 0 };
 
           /* Obtain the drawable type */
-          drawable_type = gimp_drawable_type (allLayers[loop]);
+          has_alpha = gimp_drawable_has_alpha (allLayers[loop]);
+
+          if (has_alpha)
+            format = babl_format ("R'G'B'A u8");
+          else
+            format = babl_format ("R'G'B' u8");
+
+          bpp = babl_format_get_bytes_per_pixel (format);
 
           /* fix layers to avoid offset errors */
           gimp_layer_resize_to_image_size (allLayers[loop]);
@@ -431,7 +447,6 @@ save_animation (const gchar    *filename,
           /* Retrieve the buffer for the layer */
           geglbuffer = gimp_drawable_get_buffer (allLayers[loop]);
           extent = *gegl_buffer_get_extent (geglbuffer);
-          bpp = gimp_drawable_bpp (allLayers[loop]);
           w = extent.width;
           h = extent.height;
 
@@ -477,11 +492,11 @@ save_animation (const gchar    *filename,
           picture.progress_hook = webp_file_progress;
 
           /* Read the region into the buffer */
-          gegl_buffer_get (geglbuffer, &extent, 1.0, NULL, buffer,
+          gegl_buffer_get (geglbuffer, &extent, 1.0, format, buffer,
                            GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
 
           /* Use the appropriate function to import the data from the buffer */
-          if (drawable_type == GIMP_RGB_IMAGE)
+          if (! has_alpha)
             {
               WebPPictureImportRGB (&picture, buffer, w * bpp);
             }
diff --git a/plug-ins/file-webp/file-webp.c b/plug-ins/file-webp/file-webp.c
index 0a8a9db..12853f6 100644
--- a/plug-ins/file-webp/file-webp.c
+++ b/plug-ins/file-webp/file-webp.c
@@ -36,19 +36,14 @@
 #include "libgimp/stdplugins-intl.h"
 
 
-const char BINARY_NAME[]    = "file-webp";
-const char LOAD_PROCEDURE[] = "file-webp-load";
-const char SAVE_PROCEDURE[] = "file-webp-save";
-
-/* Predeclare our entrypoints. */
 static void   query (void);
-static void   run   (const gchar *,
-                     gint,
-                     const GimpParam *,
-                     gint *,
-                     GimpParam **);
+static void   run   (const gchar      *name,
+                     gint              nparams,
+                     const GimpParam  *param,
+                     gint             *nreturn_vals,
+                     GimpParam       **return_vals);
+
 
-/* Declare our plugin entry points. */
 GimpPlugInInfo PLUG_IN_INFO =
 {
   NULL,
@@ -57,9 +52,9 @@ GimpPlugInInfo PLUG_IN_INFO =
   run
 };
 
+
 MAIN()
 
-/* This function registers our load and save handlers. */
 static void
 query (void)
 {
@@ -93,7 +88,7 @@ query (void)
     { GIMP_PDB_INT32,    "xmp",           "Toggle saving xmp data (0/1)" }
   };
 
-  gimp_install_procedure (LOAD_PROCEDURE,
+  gimp_install_procedure (LOAD_PROC,
                           "Loads images in the WebP file format",
                           "Loads images in the WebP file format",
                           "Nathan Osman, Ben Touchette",
@@ -107,29 +102,29 @@ query (void)
                           load_arguments,
                           load_return_values);
 
-  gimp_register_file_handler_mime (LOAD_PROCEDURE, "image/webp");
-  gimp_register_load_handler (LOAD_PROCEDURE, "webp", "");
-  gimp_register_magic_load_handler (LOAD_PROCEDURE,
+  gimp_register_file_handler_mime (LOAD_PROC, "image/webp");
+  gimp_register_load_handler (LOAD_PROC, "webp", "");
+  gimp_register_magic_load_handler (LOAD_PROC,
                                     "webp",
                                     "",
                                     "8,string,WEBP");
 
-  gimp_install_procedure (SAVE_PROCEDURE,
+  gimp_install_procedure (SAVE_PROC,
                           "Saves files in the WebP image format",
                           "Saves files in the WebP image format",
                           "Nathan Osman, Ben Touchette",
                           "(C) 2015-2016 Nathan Osman, (C) 2016 Ben Touchette",
                           "2015,2016",
                           N_("WebP image"),
-                          "RGB*",
+                          "RGB*, GRAY*, INDEXED*",
                           GIMP_PLUGIN,
                           G_N_ELEMENTS (save_arguments),
                           0,
                           save_arguments,
                           NULL);
 
-  gimp_register_file_handler_mime (SAVE_PROCEDURE, "image/webp");
-  gimp_register_save_handler (SAVE_PROCEDURE, "webp", "");
+  gimp_register_file_handler_mime (SAVE_PROC, "image/webp");
+  gimp_register_save_handler (SAVE_PROC, "webp", "");
 }
 
 static void
@@ -157,14 +152,11 @@ run (const gchar      *name,
   values[0].type          = GIMP_PDB_STATUS;
   values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
 
-  if (! strcmp (name, LOAD_PROCEDURE))
+  if (! strcmp (name, LOAD_PROC))
     {
-      /* No need to determine whether the plugin is being invoked
-       * interactively here since we don't need a UI for loading
-       */
       image_ID = load_image (param[1].data.d_string, FALSE, &error);
 
-      if(image_ID != -1)
+      if (image_ID != -1)
         {
           /* Return the new image that was loaded */
           *nreturn_vals = 2;
@@ -176,10 +168,10 @@ run (const gchar      *name,
           status = GIMP_PDB_EXECUTION_ERROR;
         }
     }
-  else if (! strcmp (name, SAVE_PROCEDURE))
+  else if (! strcmp (name, SAVE_PROC))
     {
       WebPSaveParams    params;
-      GimpExportReturn  export_ret = GIMP_EXPORT_CANCEL;
+      GimpExportReturn  export = GIMP_EXPORT_CANCEL;
       gint32           *layers;
       gint32            n_layers;
 
@@ -194,75 +186,84 @@ run (const gchar      *name,
       params.iptc          = TRUE;
       params.xmp           = TRUE;
 
-      /* Load the image and drawable IDs */
       image_ID    = param[1].data.d_int32;
       drawable_ID = param[2].data.d_int32;
 
-      layers = gimp_image_get_layers (image_ID, &n_layers);
-
-      /* What happens next depends on the run mode */
       switch (run_mode)
         {
         case GIMP_RUN_INTERACTIVE:
         case GIMP_RUN_WITH_LAST_VALS:
-          gimp_ui_init (BINARY_NAME, FALSE);
+          gimp_ui_init (PLUG_IN_BINARY, FALSE);
 
-          /* Attempt to export the image */
-          export_ret = gimp_export_image (&image_ID, &drawable_ID,
-                                          "WebP",
-                                          GIMP_EXPORT_CAN_HANDLE_RGB |
-                                          GIMP_EXPORT_CAN_HANDLE_ALPHA);
+          export = gimp_export_image (&image_ID, &drawable_ID, "WebP",
+                                      GIMP_EXPORT_CAN_HANDLE_RGB     |
+                                      GIMP_EXPORT_CAN_HANDLE_GRAY    |
+                                      GIMP_EXPORT_CAN_HANDLE_INDEXED |
+                                      GIMP_EXPORT_CAN_HANDLE_ALPHA   |
+                                      GIMP_EXPORT_CAN_HANDLE_LAYERS_AS_ANIMATION);
 
-          /* Return immediately if canceled */
-          if (export_ret == GIMP_EXPORT_CANCEL)
+          if (export == GIMP_EXPORT_CANCEL)
             {
               values[0].data.d_status = GIMP_PDB_CANCEL;
               return;
             }
+          break;
 
-          /* Display the dialog */
+        default:
+          break;
+        }
+
+      layers = gimp_image_get_layers (image_ID, &n_layers);
+
+      switch (run_mode)
+        {
+        case GIMP_RUN_INTERACTIVE:
           if (! save_dialog (&params, image_ID, n_layers))
-            {
-              values[0].data.d_status = GIMP_PDB_CANCEL;
-              return;
-            }
+            status = GIMP_PDB_CANCEL;
           break;
 
         case GIMP_RUN_NONINTERACTIVE:
-          /* Ensure the correct number of parameters were supplied */
           if (nparams != 10)
             {
               status = GIMP_PDB_CALLING_ERROR;
-              break;
             }
+          else
+            {
+              g_free (params.preset);
+              params.preset        = g_strdup (param[5].data.d_string);
+              params.lossless      = param[6].data.d_int32;
+              params.quality       = param[7].data.d_float;
+              params.alpha_quality = param[8].data.d_float;
+              params.animation     = param[9].data.d_int32;
+              params.loop          = param[10].data.d_int32;
+              params.exif          = param[11].data.d_int32;
+              params.iptc          = param[12].data.d_int32;
+              params.xmp           = param[13].data.d_int32;
+            }
+          break;
 
-          /* Load the parameters */
-          g_free (params.preset);
-          params.preset        = g_strdup (param[5].data.d_string);
-          params.lossless      = param[6].data.d_int32;
-          params.quality       = param[7].data.d_float;
-          params.alpha_quality = param[8].data.d_float;
-          params.animation     = param[9].data.d_int32;
-          params.loop          = param[10].data.d_int32;
-          params.exif          = param[11].data.d_int32;
-          params.iptc          = param[12].data.d_int32;
-          params.xmp           = param[13].data.d_int32;
+        default:
           break;
         }
 
-      /* Attempt to save the image */
-      if (! save_image (param[3].data.d_string,
-                        n_layers, layers,
-                        image_ID,
-                        drawable_ID,
-                        &params,
-                        &error))
+      if (status == GIMP_PDB_SUCCESS)
         {
-          status = GIMP_PDB_EXECUTION_ERROR;
+          if (! save_image (param[3].data.d_string,
+                            n_layers, layers,
+                            image_ID,
+                            drawable_ID,
+                            &params,
+                            &error))
+            {
+              status = GIMP_PDB_EXECUTION_ERROR;
+            }
         }
 
       g_free (params.preset);
       g_free (layers);
+
+      if (export == GIMP_EXPORT_EXPORT)
+        gimp_image_delete (image_ID);
     }
 
   /* If an error was supplied, include it in the return values */
diff --git a/plug-ins/file-webp/file-webp.h b/plug-ins/file-webp/file-webp.h
index 783aacf..244fe8e 100644
--- a/plug-ins/file-webp/file-webp.h
+++ b/plug-ins/file-webp/file-webp.h
@@ -19,10 +19,14 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef __WEBP_H__
-#define __WEBP_H__
+#ifndef __FILE_WEBP_H__
+#define __FILE_WEBP_H__
 
-extern const char BINARY_NAME[];
-extern const char SAVE_PROCEDURE[];
 
-#endif /* __WEBP_H__ */
+#define LOAD_PROC      "file-webp-load"
+#define SAVE_PROC      "file-webp-save"
+#define PLUG_IN_BINARY "file-webp"
+#define PLUG_IN_ROLE   "gimp-file-webp"
+
+
+#endif /* __FILE_WEBP_H__ */


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