[gimp] Bug 769871 - Adds selection to save exif/xmp when exporting a webp file.



commit 05e4c5fe28d9b7a054a09fee54d801fe150f115f
Author: Benoit Touchette <draekko software+gimp gmail com>
Date:   Tue Aug 16 16:49:57 2016 -0400

    Bug 769871 - Adds selection to save exif/xmp when exporting a webp file.
    
    This adds an expander to the webp file plug-in  to select whether
    to save or not the exif, and xmp data for webp files. This harmonizes
    the plug-in with a similar option to the jpg/png file plug-ins.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=769871

 plug-ins/file-webp/file-webp-dialog.c    |   56 +++-
 plug-ins/file-webp/file-webp-save.c      |   19 +
 plug-ins/file-webp/file-webp-save.c.orig |  622 ++++++++++++++++++++++++++++++
 plug-ins/file-webp/file-webp-save.h      |    3 +
 plug-ins/file-webp/file-webp.c           |   11 +-
 5 files changed, 709 insertions(+), 2 deletions(-)
---
diff --git a/plug-ins/file-webp/file-webp-dialog.c b/plug-ins/file-webp/file-webp-dialog.c
index 678a45f..6580e5a 100644
--- a/plug-ins/file-webp/file-webp-dialog.c
+++ b/plug-ins/file-webp/file-webp-dialog.c
@@ -52,7 +52,6 @@ static struct
   { 0 }
 };
 
-
 static GtkListStore *
 save_dialog_presets (void)
 {
@@ -97,6 +96,11 @@ save_dialog (WebPSaveParams *params,
   GtkWidget    *vbox;
   GtkWidget    *label;
   GtkWidget    *table;
+  GtkWidget    *expander;
+  GtkWidget    *frame;
+  GtkWidget    *table2;
+  GtkWidget    *save_exif;
+  GtkWidget    *save_xmp;
   GtkWidget    *preset_label;
   GtkListStore *preset_list;
   GtkWidget    *preset_combo;
@@ -108,6 +112,7 @@ save_dialog (WebPSaveParams *params,
   gboolean      animation_supported = FALSE;
   gint          slider1 , slider2;
   gboolean      run;
+  gchar        *text;
 
   animation_supported = n_layers > 1;
 
@@ -251,6 +256,55 @@ save_dialog (WebPSaveParams *params,
                     G_CALLBACK (save_dialog_toggle_scale),
                     alpha_quality_scale);
 
+  text = g_strdup_printf ("<b>%s</b>", _("_Advanced Options"));
+  expander = gtk_expander_new_with_mnemonic (text);
+  gtk_expander_set_use_markup (GTK_EXPANDER (expander), TRUE);
+  g_free (text);
+
+  gtk_box_pack_start (GTK_BOX (vbox), expander, TRUE, TRUE, 0);
+  gtk_widget_show (expander);
+
+  vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
+  gtk_container_add (GTK_CONTAINER (expander), vbox);
+  gtk_widget_show (vbox);
+
+  frame = gimp_frame_new ("<expander>");
+  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);
+
+  /* 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_widget_show (save_exif);
+
+  g_signal_connect (save_exif, "toggled",
+                    G_CALLBACK (gimp_toggle_button_update),
+                    &params->exif);
+
+  /* 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_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-save.c b/plug-ins/file-webp/file-webp-save.c
index 4f050e4..b7e380b 100644
--- a/plug-ins/file-webp/file-webp-save.c
+++ b/plug-ins/file-webp/file-webp-save.c
@@ -609,6 +609,25 @@ save_image (const gchar    *filename,
   if (metadata)
     {
       gimp_metadata_set_bits_per_sample (metadata, 8);
+
+      if (params->exif)
+        metadata_flags |= GIMP_METADATA_SAVE_EXIF;
+      else
+        metadata_flags &= ~GIMP_METADATA_SAVE_EXIF;
+
+      /* WebP doesn't support iptc natively and
+         sets it via xmp */
+      if (params->xmp)
+        {
+          metadata_flags |= GIMP_METADATA_SAVE_XMP;
+          metadata_flags |= GIMP_METADATA_SAVE_IPTC;
+        }
+      else
+        {
+          metadata_flags &= ~GIMP_METADATA_SAVE_XMP;
+          metadata_flags &= ~GIMP_METADATA_SAVE_IPTC;
+        }
+
       file = g_file_new_for_path (filename);
       gimp_image_metadata_save_finish (image_ID,
                                        "image/webp",
diff --git a/plug-ins/file-webp/file-webp-save.c.orig b/plug-ins/file-webp/file-webp-save.c.orig
new file mode 100644
index 0000000..4f050e4
--- /dev/null
+++ b/plug-ins/file-webp/file-webp-save.c.orig
@@ -0,0 +1,622 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * file-webp - WebP file format plug-in for the GIMP
+ * Copyright (C) 2015  Nathan Osman
+ * Copyright (C) 2016  Ben Touchette
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <errno.h>
+#include <glib/gstdio.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#include <gegl.h>
+
+#include <libgimp/gimp.h>
+#include <libgimp/gimpui.h>
+
+#include <webp/encode.h>
+#include <webp/mux.h>
+
+#include "file-webp-save.h"
+
+#include "libgimp/stdplugins-intl.h"
+
+
+WebPPreset    webp_preset_by_name   (gchar             *name);
+int           webp_anim_file_writer (FILE              *outfile,
+                                     const uint8_t     *data,
+                                     size_t             data_size);
+int           webp_file_writer      (const uint8_t     *data,
+                                     size_t             data_size,
+                                     const WebPPicture *picture);
+int           webp_file_progress    (int                percent,
+                                     const WebPPicture *picture);
+const gchar * webp_error_string     (WebPEncodingError  error_code);
+
+gboolean      save_layer            (const gchar       *filename,
+                                     gint32             nLayers,
+                                     gint32             image_ID,
+                                     gint32             drawable_ID,
+                                     WebPSaveParams    *params,
+                                     GError           **error);
+
+gboolean      save_animation        (const gchar       *filename,
+                                     gint32             nLayers,
+                                     gint32            *allLayers,
+                                     gint32             image_ID,
+                                     gint32             drawable_ID,
+                                     WebPSaveParams    *params,
+                                     GError           **error);
+
+
+WebPPreset
+webp_preset_by_name (gchar *name)
+{
+  if( ! strcmp (name, "picture"))
+    {
+      return WEBP_PRESET_PICTURE;
+    }
+  else if (! strcmp (name, "photo"))
+    {
+      return WEBP_PRESET_PHOTO;
+    }
+  else if (! strcmp (name, "drawing"))
+    {
+      return WEBP_PRESET_DRAWING;
+    }
+  else if (! strcmp (name, "icon"))
+    {
+      return WEBP_PRESET_ICON;
+    }
+  else if (! strcmp (name, "text"))
+    {
+      return WEBP_PRESET_TEXT;
+    }
+  else
+    {
+      return WEBP_PRESET_DEFAULT;
+    }
+}
+
+int
+webp_anim_file_writer (FILE          *outfile,
+                       const uint8_t *data,
+                       size_t         data_size)
+{
+  int ok = 0;
+
+  if (data == NULL)
+    return 0;
+
+  ok = (fwrite (data, data_size, 1, outfile) == 1);
+
+  return ok;
+}
+
+int
+webp_file_writer (const uint8_t     *data,
+                  size_t             data_size,
+                  const WebPPicture *picture)
+{
+  FILE *outfile;
+
+  /* Obtain the FILE* and write the data to the file */
+  outfile = (FILE *) picture->custom_ptr;
+
+  return fwrite (data, sizeof (uint8_t), data_size, outfile) == data_size;
+}
+
+int
+webp_file_progress (int                percent,
+                    const WebPPicture *picture)
+{
+  return gimp_progress_update (percent / 100.0);
+}
+
+const gchar *
+webp_error_string (WebPEncodingError error_code)
+{
+  switch (error_code)
+    {
+    case VP8_ENC_ERROR_OUT_OF_MEMORY:
+      return _("out of memory");
+    case VP8_ENC_ERROR_BITSTREAM_OUT_OF_MEMORY:
+      return _("not enough memory to flush bits");
+    case VP8_ENC_ERROR_NULL_PARAMETER:
+      return _("NULL parameter");
+    case VP8_ENC_ERROR_INVALID_CONFIGURATION:
+      return _("invalid configuration");
+    case VP8_ENC_ERROR_BAD_DIMENSION:
+      return _("bad image dimensions");
+    case VP8_ENC_ERROR_PARTITION0_OVERFLOW:
+      return _("partition is bigger than 512K");
+    case VP8_ENC_ERROR_PARTITION_OVERFLOW:
+      return _("partition is bigger than 16M");
+    case VP8_ENC_ERROR_BAD_WRITE:
+      return _("unable to flush bytes");
+    case VP8_ENC_ERROR_FILE_TOO_BIG:
+      return _("file is larger than 4GiB");
+    case VP8_ENC_ERROR_USER_ABORT:
+      return _("user aborted encoding");
+    case VP8_ENC_ERROR_LAST:
+      return _("list terminator");
+    default:
+      return _("unknown error");
+    }
+}
+
+gboolean
+save_layer (const gchar    *filename,
+            gint32          nLayers,
+            gint32          image_ID,
+            gint32          drawable_ID,
+            WebPSaveParams *params,
+            GError        **error)
+{
+  gboolean          status   = FALSE;
+  FILE             *outfile  = NULL;
+  WebPConfig        config   = {0};
+  WebPPicture       picture  = {0};
+  guchar           *buffer   = NULL;
+  gint              w, h;
+  gint              bpp;
+  GimpColorProfile *profile;
+  GimpImageType     drawable_type;
+  GeglBuffer       *geglbuffer = NULL;
+  GeglRectangle     extent;
+  gchar            *indata;
+  gsize             indatalen;
+  struct            stat stsz;
+  int               fd_outfile;
+  WebPData          chunk;
+  int               res;
+
+  /* The do...while() loop is a neat little trick that makes it easier
+   * to jump to error handling code while still ensuring proper
+   * cleanup
+   */
+
+  do
+    {
+      /* Begin displaying export progress */
+      gimp_progress_init_printf (_("Saving '%s'"),
+                                 gimp_filename_to_utf8(filename));
+
+      /* Attempt to open the output file */
+      if ((outfile = g_fopen (filename, "wb+")) == NULL)
+        {
+          g_set_error (error, G_FILE_ERROR,
+                       g_file_error_from_errno (errno),
+                       _("Unable to open '%s' for writing"),
+                       gimp_filename_to_utf8 (filename));
+          break;
+        }
+
+      /* Obtain the drawable type */
+      drawable_type = gimp_drawable_type (drawable_ID);
+
+      /* 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;
+
+      /* Initialize the WebP configuration with a preset and fill in the
+       * remaining values */
+      WebPConfigPreset (&config,
+                        webp_preset_by_name (params->preset),
+                        params->quality);
+
+      config.lossless      = params->lossless;
+      config.method        = 6;  /* better quality */
+      config.alpha_quality = params->alpha_quality;
+
+      /* Prepare the WebP structure */
+      WebPPictureInit (&picture);
+      picture.use_argb      = 1;
+      picture.width         = w;
+      picture.height        = h;
+      picture.writer        = webp_file_writer;
+      picture.custom_ptr    = outfile;
+      picture.progress_hook = webp_file_progress;
+
+      /* Attempt to allocate a buffer of the appropriate size */
+      buffer = (guchar *) g_malloc (w * h * bpp);
+      if(! buffer)
+        break;
+
+      /* Read the region into the buffer */
+      gegl_buffer_get (geglbuffer, &extent, 1.0, NULL, buffer,
+                       GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
+
+      /* Use the appropriate function to import the data from the buffer */
+      if (drawable_type == GIMP_RGB_IMAGE)
+        {
+          WebPPictureImportRGB (&picture, buffer, w * bpp);
+        }
+      else
+        {
+          WebPPictureImportRGBA (&picture, buffer, w * bpp);
+        }
+
+      /* Perform the actual encode */
+      if (! WebPEncode (&config, &picture))
+        {
+          g_printerr ("WebP error: '%s'",
+                      webp_error_string (picture.error_code));
+          g_set_error (error, G_FILE_ERROR,
+                       picture.error_code,
+                       _("WebP error: '%s'"),
+                       webp_error_string (picture.error_code));
+          break;
+        }
+
+      /* The cleanup stuff still needs to run but indicate that everything
+       * completed successfully
+       */
+      status = TRUE;
+
+    }
+  while (0);
+
+  /* Flush the drawable and detach */
+  if (geglbuffer)
+    {
+      gegl_buffer_flush (geglbuffer);
+      g_object_unref (geglbuffer);
+    }
+
+  fflush (outfile);
+  fd_outfile = fileno (outfile);
+  fstat (fd_outfile, &stsz);
+  indatalen = stsz.st_size;
+  if (indatalen > 0)
+    {
+      indata = (gchar*) g_malloc (indatalen);
+      rewind (outfile);
+      res = fread (indata, 1, indatalen, outfile);
+      if (res > 0)
+        {
+          WebPMux *mux;
+          WebPData wp_data;
+
+          wp_data.bytes = (uint8_t*) indata;
+          wp_data.size = indatalen;
+          mux = WebPMuxCreate (&wp_data, 1);
+
+          if (mux)
+            {
+              gboolean saved = FALSE;
+
+              /* Save ICC data */
+              profile = gimp_image_get_color_profile (image_ID);
+              if (profile)
+                {
+                  const guint8 *icc_data;
+                  gsize         icc_data_size;
+
+                  saved = TRUE;
+
+                  icc_data = gimp_color_profile_get_icc_profile (profile,
+                                                                 &icc_data_size);
+                  chunk.bytes = icc_data;
+                  chunk.size = icc_data_size;
+                  WebPMuxSetChunk(mux, "ICCP", &chunk, 1);
+                  g_object_unref (profile);
+                }
+
+              if (saved == TRUE)
+                {
+                  WebPMuxAssemble (mux, &wp_data);
+                  rewind (outfile);
+                  webp_anim_file_writer (outfile, wp_data.bytes, wp_data.size);
+                }
+            }
+          else
+            {
+              g_printerr ("ERROR: Cannot create mux. Can't save features update.\n");
+            }
+
+          WebPDataClear (&wp_data);
+        }
+      else
+        {
+          g_printerr ("ERROR: No data read for features. Can't save features update.\n");
+        }
+    }
+  else
+    {
+      g_printerr ("ERROR: No data for features. Can't save features update.\n");
+    }
+
+  /* Free any resources */
+  if (outfile)
+    fclose (outfile);
+
+  if (buffer)
+    free (buffer);
+
+  WebPPictureFree (&picture);
+
+  return status;
+}
+
+gboolean
+save_animation (const gchar    *filename,
+                gint32          nLayers,
+                gint32         *allLayers,
+                gint32          image_ID,
+                gint32          drawable_ID,
+                WebPSaveParams *params,
+                GError        **error)
+{
+  gboolean               status   = FALSE;
+  FILE                  *outfile  = NULL;
+  guchar                *buffer   = NULL;
+  gint                   w, h, bpp;
+  GimpImageType          drawable_type;
+  GimpColorProfile      *profile;
+  WebPAnimEncoderOptions enc_options;
+  WebPData               webp_data;
+  int                    frame_timestamp = 0;
+  WebPAnimEncoder       *enc;
+  WebPMux               *mux;
+  WebPMuxAnimParams      anim_params = {0};
+
+  if (nLayers < 1)
+    return FALSE;
+
+  gimp_image_undo_freeze (image_ID);
+
+  do
+    {
+      gint loop;
+
+      /* Begin displaying export progress */
+      gimp_progress_init_printf (_("Saving '%s'"),
+                                 gimp_filename_to_utf8 (filename));
+
+      /* Attempt to open the output file */
+      if ((outfile = g_fopen (filename, "wb")) == NULL)
+        {
+          g_set_error (error, G_FILE_ERROR,
+                       g_file_error_from_errno (errno),
+                       _("Unable to open '%s' for writing"),
+                       gimp_filename_to_utf8 (filename));
+          break;
+        }
+
+      WebPDataInit (&webp_data);
+      if (! WebPAnimEncoderOptionsInit (&enc_options))
+        {
+          g_printerr ("ERROR: verion mismatch\n");
+          break;
+        }
+
+      for (loop = 0; loop < nLayers; loop++)
+        {
+          GeglBuffer       *geglbuffer;
+          GeglRectangle     extent;
+          WebPConfig        config;
+          WebPPicture       picture;
+          WebPMemoryWriter  mw = { 0 };
+
+          /* Obtain the drawable type */
+          drawable_type = gimp_drawable_type (allLayers[loop]);
+
+          /* fix layers to avoid offset errors */
+          gimp_layer_resize_to_image_size (allLayers[loop]);
+
+          /* 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;
+
+          if (loop == 0)
+            {
+              enc = WebPAnimEncoderNew (w, h, &enc_options);
+              if (! enc)
+                {
+                  g_printerr ("ERROR: enc == null\n");
+                  break;
+                }
+            }
+
+          /* Attempt to allocate a buffer of the appropriate size */
+          buffer = (guchar *) g_malloc (w * h * bpp);
+          if(! buffer)
+            {
+              g_printerr ("Buffer error: 'buffer null'\n");
+              status = FALSE;
+              break;
+            }
+
+          WebPConfigInit (&config);
+          WebPConfigPreset (&config,
+                            webp_preset_by_name (params->preset),
+                            params->quality);
+
+          config.lossless      = params->lossless;
+          config.method        = 6;  /* better quality */
+          config.alpha_quality = params->alpha_quality;
+          config.exact         = 1;
+
+          WebPMemoryWriterInit (&mw);
+
+          /* Prepare the WebP structure */
+          WebPPictureInit (&picture);
+          picture.use_argb      = 1;
+          picture.argb_stride   = w * bpp;
+          picture.width         = w;
+          picture.height        = h;
+          picture.custom_ptr    = &mw;
+          picture.writer        = WebPMemoryWrite;
+          picture.progress_hook = webp_file_progress;
+
+          /* Read the region into the buffer */
+          gegl_buffer_get (geglbuffer, &extent, 1.0, NULL, buffer,
+                           GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
+
+          /* Use the appropriate function to import the data from the buffer */
+          if (drawable_type == GIMP_RGB_IMAGE)
+            {
+              WebPPictureImportRGB (&picture, buffer, w * bpp);
+            }
+          else
+            {
+              WebPPictureImportRGBA (&picture, buffer, w * bpp);
+            }
+
+          /* Perform the actual encode */
+          if (! WebPAnimEncoderAdd (enc, &picture, frame_timestamp, &config))
+            {
+              g_printerr ("ERROR[%d]: %s\n",
+                          picture.error_code,
+                          webp_error_string (picture.error_code));
+            }
+
+          WebPMemoryWriterClear (&mw);
+          WebPPictureFree (&picture);
+
+          if (buffer)
+            free (buffer);
+
+          /* Flush the drawable and detach */
+          gegl_buffer_flush (geglbuffer);
+          g_object_unref (geglbuffer);
+        }
+
+      WebPAnimEncoderAdd (enc, NULL, frame_timestamp, NULL);
+
+      if (! WebPAnimEncoderAssemble (enc, &webp_data))
+        {
+          g_printerr ("ERROR: %s\n",
+                      WebPAnimEncoderGetError (enc));
+        }
+
+      /* Set animations parameters */
+      mux = WebPMuxCreate (&webp_data, 1);
+
+      anim_params.loop_count = 0;
+      if (params->loop == FALSE)
+        {
+          anim_params.loop_count = 1;
+        }
+
+      WebPMuxSetAnimationParams (mux, &anim_params);
+
+      /* Save ICC data */
+      profile = gimp_image_get_color_profile (image_ID);
+      if (profile)
+        {
+          WebPData      chunk;
+          const guint8 *icc_data;
+          gsize         icc_data_size;
+
+          icc_data = gimp_color_profile_get_icc_profile (profile, &icc_data_size);
+          chunk.bytes = icc_data;
+          chunk.size  = icc_data_size;
+          WebPMuxSetChunk (mux, "ICCP", &chunk, 1);
+          g_object_unref (profile);
+        }
+
+      WebPMuxAssemble (mux, &webp_data);
+
+      webp_anim_file_writer (outfile, webp_data.bytes, webp_data.size);
+
+      WebPDataClear (&webp_data);
+      WebPAnimEncoderDelete (enc);
+
+      status = TRUE;
+    }
+  while (0);
+
+  /* Free any resources */
+  if (outfile)
+    fclose (outfile);
+
+  return status;
+}
+
+
+gboolean
+save_image (const gchar    *filename,
+            gint32          nLayers,
+            gint32         *allLayers,
+            gint32          image_ID,
+            gint32          drawable_ID,
+            WebPSaveParams *params,
+            GError        **error)
+{
+  GimpMetadata          *metadata;
+  GimpMetadataSaveFlags  metadata_flags;
+  gboolean               status = FALSE;
+  GFile                 *file;
+
+  if (nLayers == 0)
+    return FALSE;
+
+  g_printerr("Saving WebP file %s\n", filename);
+
+  if (nLayers == 1)
+    {
+      status = save_layer (filename, nLayers, image_ID, drawable_ID, params,
+                           error);
+    }
+  else
+    {
+      if (! params->animation)
+        {
+          status = save_layer (filename,
+                               nLayers, image_ID, drawable_ID, params,
+                               error);
+        }
+      else
+        {
+          status = save_animation (filename,
+                                   nLayers, allLayers, image_ID, drawable_ID,
+                                   params, error);
+        }
+    }
+
+  metadata = gimp_image_metadata_save_prepare (image_ID,
+                                               "image/webp",
+                                               &metadata_flags);
+
+  if (metadata)
+    {
+      gimp_metadata_set_bits_per_sample (metadata, 8);
+      file = g_file_new_for_path (filename);
+      gimp_image_metadata_save_finish (image_ID,
+                                       "image/webp",
+                                       metadata, metadata_flags,
+                                       file, NULL);
+      g_object_unref (file);
+    }
+
+  /* Return the status */
+  return status;
+}
diff --git a/plug-ins/file-webp/file-webp-save.h b/plug-ins/file-webp/file-webp-save.h
index 643ccf8..98fb202 100644
--- a/plug-ins/file-webp/file-webp-save.h
+++ b/plug-ins/file-webp/file-webp-save.h
@@ -31,6 +31,9 @@ typedef struct
   gboolean  loop;
   gfloat    quality;
   gfloat    alpha_quality;
+  gboolean  exif;
+  gboolean  iptc;
+  gboolean  xmp;
 } WebPSaveParams;
 
 
diff --git a/plug-ins/file-webp/file-webp.c b/plug-ins/file-webp/file-webp.c
index b845525..0a8a9db 100644
--- a/plug-ins/file-webp/file-webp.c
+++ b/plug-ins/file-webp/file-webp.c
@@ -87,7 +87,10 @@ query (void)
     { GIMP_PDB_FLOAT,    "quality",       "Quality of the image (0 <= quality <= 100)" },
     { GIMP_PDB_FLOAT,    "alpha-quality", "Quality of the image's alpha channel (0 <= alpha-quality <= 100)" 
},
     { GIMP_PDB_INT32,    "animation",     "Use layers for animation (0/1)" },
-    { GIMP_PDB_INT32,    "anim-loop",     "Loop animation infinitely (0/1)" }
+    { GIMP_PDB_INT32,    "anim-loop",     "Loop animation infinitely (0/1)" },
+    { GIMP_PDB_INT32,    "exif",          "Toggle saving exif data (0/1)" },
+    { GIMP_PDB_INT32,    "iptc",          "Toggle saving iptc data (0/1)" },
+    { GIMP_PDB_INT32,    "xmp",           "Toggle saving xmp data (0/1)" }
   };
 
   gimp_install_procedure (LOAD_PROCEDURE,
@@ -187,6 +190,9 @@ run (const gchar      *name,
       params.loop          = TRUE;
       params.quality       = 90.0f;
       params.alpha_quality = 100.0f;
+      params.exif          = TRUE;
+      params.iptc          = TRUE;
+      params.xmp           = TRUE;
 
       /* Load the image and drawable IDs */
       image_ID    = param[1].data.d_int32;
@@ -238,6 +244,9 @@ run (const gchar      *name,
           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;
         }
 


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