[gimp] app, plug-ins: move pattern saving to the core



commit b29ecfb5daf1e27314a878814b796670bd482a45
Author: Michael Natterer <mitch gimp org>
Date:   Tue Feb 12 21:27:13 2019 +0100

    app, plug-ins: move pattern saving to the core
    
    but only the actual saving code, not the export magic and dialog.
    
    Add new internal procedure file-pat-save-internal which is not
    registered as a file procedure and always works non-interactively on
    the passed arguments and only saves the passed drawable. Use the new
    internal procedure from the file-pat-save code and remove all file
    writing code from the plug-in.
    
    This way all pattern file writing code duplication is killed, while
    the whole export mechanism is completely unchanged.

 app/file-data/file-data-pat.c |  55 +++++++++++---
 app/file-data/file-data.c     |  81 +++++++++++++++++++++
 plug-ins/common/file-pat.c    | 164 +++++++-----------------------------------
 3 files changed, 152 insertions(+), 148 deletions(-)
---
diff --git a/app/file-data/file-data-pat.c b/app/file-data/file-data-pat.c
index 647b81c19b..30041d0b47 100644
--- a/app/file-data/file-data-pat.c
+++ b/app/file-data/file-data-pat.c
@@ -24,6 +24,8 @@
 
 #include "core/core-types.h"
 
+#include "gegl/gimp-babl.h"
+
 #include "core/gimp.h"
 #include "core/gimpdrawable.h"
 #include "core/gimpimage.h"
@@ -42,9 +44,11 @@
 
 /*  local function prototypes  */
 
-static GimpImage   * file_pat_pattern_to_image (Gimp        *gimp,
-                                                GimpPattern *pattern);
-static GimpPattern * file_pat_image_to_pattern (GimpImage   *image);
+static GimpImage   * file_pat_pattern_to_image (Gimp         *gimp,
+                                                GimpPattern  *pattern);
+static GimpPattern * file_pat_image_to_pattern (GimpImage    *image,
+                                                GimpDrawable *drawable,
+                                                const gchar  *name);
 
 
 /*  public functions  */
@@ -119,18 +123,23 @@ file_pat_save_invoker (GimpProcedure         *procedure,
 {
   GimpValueArray *return_vals;
   GimpImage      *image;
+  GimpDrawable   *drawable;
   GimpPattern    *pattern;
   const gchar    *uri;
+  const gchar    *name;
   GFile          *file;
   gboolean        success;
 
   gimp_set_busy (gimp);
 
-  image = gimp_value_get_image (gimp_value_array_index (args, 1), gimp);
-  uri   = g_value_get_string (gimp_value_array_index (args, 3));
-  file  = g_file_new_for_uri (uri);
+  image    = gimp_value_get_image (gimp_value_array_index (args, 1), gimp);
+  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
+  uri      = g_value_get_string (gimp_value_array_index (args, 3));
+  name     = g_value_get_string (gimp_value_array_index (args, 5));
+
+  file = g_file_new_for_uri (uri);
 
-  pattern = file_pat_image_to_pattern (image);
+  pattern = file_pat_image_to_pattern (image, drawable, name);
 
   gimp_data_set_file (GIMP_DATA (pattern), file, TRUE, TRUE);
 
@@ -223,7 +232,35 @@ file_pat_pattern_to_image (Gimp        *gimp,
 }
 
 static GimpPattern *
-file_pat_image_to_pattern (GimpImage *image)
+file_pat_image_to_pattern (GimpImage    *image,
+                           GimpDrawable *drawable,
+                           const gchar  *name)
 {
-  return NULL;
+  GimpPattern *pattern;
+  const Babl  *format;
+  gint         width;
+  gint         height;
+
+  format = gimp_babl_format (gimp_drawable_is_gray (drawable) ?
+                             GIMP_GRAY : GIMP_RGB,
+                             GIMP_PRECISION_U8_PERCEPTUAL,
+                             gimp_drawable_has_alpha (drawable),
+                             NULL);
+
+  width  = gimp_item_get_width  (GIMP_ITEM (drawable));
+  height = gimp_item_get_height (GIMP_ITEM (drawable));
+
+  pattern = g_object_new (GIMP_TYPE_PATTERN,
+                          "name",      name,
+                          "mime-type", "image/x-gimp-pat",
+                          NULL);
+
+  pattern->mask = gimp_temp_buf_new (width, height, format);
+
+  gegl_buffer_get (gimp_drawable_get_buffer (drawable),
+                   GEGL_RECTANGLE (0, 0, width, height), 1.0,
+                   format, gimp_temp_buf_get_data (pattern->mask),
+                   GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
+
+  return pattern;
 }
diff --git a/app/file-data/file-data.c b/app/file-data/file-data.c
index 8738af8506..fc4eecca1b 100644
--- a/app/file-data/file-data.c
+++ b/app/file-data/file-data.c
@@ -172,6 +172,87 @@ file_data_init (Gimp *gimp)
 
   gimp_plug_in_manager_add_procedure (gimp->plug_in_manager, proc);
   g_object_unref (procedure);
+
+  /*  file-pat-save-internal  */
+  file = g_file_new_for_path ("file-pat-save-internal");
+  procedure = gimp_plug_in_procedure_new (GIMP_PLUGIN, file);
+  g_object_unref (file);
+
+  procedure->proc_type    = GIMP_INTERNAL;
+  procedure->marshal_func = file_pat_save_invoker;
+
+  proc = GIMP_PLUG_IN_PROCEDURE (procedure);
+  proc->menu_label = g_strdup (N_("GIMP pattern"));
+  gimp_plug_in_procedure_set_icon (proc, GIMP_ICON_TYPE_ICON_NAME,
+                                   (const guint8 *) "gimp-pattern",
+                                   strlen ("gimp-pattern") + 1);
+
+#if 0
+  /* do not register as file procedure */
+  gimp_plug_in_procedure_set_image_types (proc, "RGB*, GRAY*, INDEXED*");
+  gimp_plug_in_procedure_set_file_proc (proc, "pat", "", NULL);
+  gimp_plug_in_procedure_set_mime_types (proc, "image/x-gimp-pat");
+  gimp_plug_in_procedure_set_handles_uri (proc);
+#endif
+
+  gimp_object_set_static_name (GIMP_OBJECT (procedure),
+                               "file-pat-save-internal");
+  gimp_procedure_set_static_strings (procedure,
+                                     "file-pat-save-internal",
+                                     "Exports Gimp pattern file (.PAT)",
+                                     "Exports Gimp pattern file (.PAT)",
+                                     "Tim Newsome, Michael Natterer",
+                                     "Tim Newsome, Michael Natterer",
+                                     "1995-2019",
+                                     NULL);
+
+  gimp_procedure_add_argument (procedure,
+                               gimp_param_spec_int32 ("dummy-param",
+                                                      "Dummy Param",
+                                                      "Dummy parameter",
+                                                      G_MININT32, G_MAXINT32, 0,
+                                                      GIMP_PARAM_READWRITE));
+  gimp_procedure_add_argument (procedure,
+                               gimp_param_spec_image_id ("image",
+                                                         "Image",
+                                                         "Input image",
+                                                         gimp, FALSE,
+                                                         GIMP_PARAM_READWRITE));
+  gimp_procedure_add_argument (procedure,
+                               gimp_param_spec_drawable_id ("drawable",
+                                                            "Drawable",
+                                                            "Active drawable "
+                                                            "of input image",
+                                                            gimp, FALSE,
+                                                            GIMP_PARAM_READWRITE));
+  gimp_procedure_add_argument (procedure,
+                               gimp_param_spec_string ("uri",
+                                                       "URI",
+                                                       "The URI of the file "
+                                                       "to export",
+                                                       FALSE, FALSE, TRUE,
+                                                       NULL,
+                                                       GIMP_PARAM_READWRITE));
+  gimp_procedure_add_argument (procedure,
+                               gimp_param_spec_string ("raw-uri",
+                                                       "Raw URI",
+                                                       "The URI of the file "
+                                                       "to export",
+                                                       FALSE, FALSE, TRUE,
+                                                       NULL,
+                                                       GIMP_PARAM_READWRITE));
+
+  gimp_procedure_add_argument (procedure,
+                               gimp_param_spec_string ("name",
+                                                       "name",
+                                                       "The name of the "
+                                                       "pattern",
+                                                       FALSE, FALSE, TRUE,
+                                                       "GIMP Pattern",
+                                                       GIMP_PARAM_READWRITE));
+
+  gimp_plug_in_manager_add_procedure (gimp->plug_in_manager, proc);
+  g_object_unref (procedure);
 }
 
 void
diff --git a/plug-ins/common/file-pat.c b/plug-ins/common/file-pat.c
index 3acf6150b2..6f2539a265 100644
--- a/plug-ins/common/file-pat.c
+++ b/plug-ins/common/file-pat.c
@@ -36,18 +36,14 @@
 
 /*  local function prototypes  */
 
-static void       query          (void);
-static void       run            (const gchar      *name,
-                                  gint              nparams,
-                                  const GimpParam  *param,
-                                  gint             *nreturn_vals,
-                                  GimpParam       **return_vals);
-static gboolean   save_image     (GFile            *file,
-                                  gint32            image_ID,
-                                  gint32            drawable_ID,
-                                  GError          **error);
+static void       query       (void);
+static void       run         (const gchar      *name,
+                               gint              nparams,
+                               const GimpParam  *param,
+                               gint             *nreturn_vals,
+                               GimpParam       **return_vals);
 
-static gboolean   save_dialog    (void);
+static gboolean   save_dialog (void);
 
 
 const GimpPlugInInfo PLUG_IN_INFO =
@@ -217,7 +213,22 @@ run (const gchar      *name,
 
       if (status == GIMP_PDB_SUCCESS)
         {
-          if (save_image (file, image_ID, drawable_ID, &error))
+          GimpParam *save_retvals;
+          gint       n_save_retvals;
+
+          save_retvals =
+            gimp_run_procedure ("file-pat-save-internal",
+                                &n_save_retvals,
+                                GIMP_PDB_INT32,    GIMP_RUN_NONINTERACTIVE,
+                                GIMP_PDB_IMAGE,    image_ID,
+                                GIMP_PDB_DRAWABLE, drawable_ID,
+                                GIMP_PDB_STRING,   param[3].data.d_string,
+                                GIMP_PDB_STRING,   param[4].data.d_string,
+                                GIMP_PDB_STRING,   description,
+                                GIMP_PDB_END);
+
+
+          if (save_retvals[0].data.d_status == GIMP_PDB_SUCCESS)
             {
               gimp_set_data (SAVE_PROC, description, sizeof (description));
             }
@@ -225,6 +236,8 @@ run (const gchar      *name,
             {
               status = GIMP_PDB_EXECUTION_ERROR;
             }
+
+          gimp_destroy_params (save_retvals, n_save_retvals);
         }
 
       if (export == GIMP_EXPORT_EXPORT)
@@ -261,133 +274,6 @@ run (const gchar      *name,
   values[0].data.d_status = status;
 }
 
-static gboolean
-save_image (GFile   *file,
-            gint32   image_ID,
-            gint32   drawable_ID,
-            GError **error)
-{
-  GOutputStream     *output;
-  GimpPatternHeader  ph;
-  GeglBuffer        *buffer;
-  const Babl        *file_format;
-  guchar            *buf;
-  gint               width;
-  gint               height;
-  gint               line_size;
-  gint               line;
-
-  switch (gimp_drawable_type (drawable_ID))
-    {
-    case GIMP_GRAY_IMAGE:
-      file_format = babl_format ("Y' u8");
-      break;
-
-    case GIMP_GRAYA_IMAGE:
-      file_format = babl_format ("Y'A u8");
-      break;
-
-    case GIMP_RGB_IMAGE:
-    case GIMP_INDEXED_IMAGE:
-      file_format = babl_format ("R'G'B' u8");
-      break;
-
-    case GIMP_RGBA_IMAGE:
-    case GIMP_INDEXEDA_IMAGE:
-      file_format = babl_format ("R'G'B'A u8");
-      break;
-
-    default:
-      g_message ("Unsupported image type: %d\n"
-                 "GIMP Patterns must be GRAY or RGB",
-                 gimp_drawable_type (drawable_ID));
-      return FALSE;
-    }
-
-  gimp_progress_init_printf (_("Exporting '%s'"),
-                             g_file_get_parse_name (file));
-
-  output = G_OUTPUT_STREAM (g_file_replace (file,
-                                            NULL, FALSE, G_FILE_CREATE_NONE,
-                                            NULL, error));
-  if (! output)
-    return FALSE;
-
-  buffer = gimp_drawable_get_buffer (drawable_ID);
-
-  width  = gegl_buffer_get_width (buffer);
-  height = gegl_buffer_get_height (buffer);
-
-  ph.header_size  = g_htonl (sizeof (GimpPatternHeader) + strlen (description) + 1);
-  ph.version      = g_htonl (1);
-  ph.width        = g_htonl (width);
-  ph.height       = g_htonl (height);
-  ph.bytes        = g_htonl (babl_format_get_bytes_per_pixel (file_format));
-  ph.magic_number = g_htonl (GIMP_PATTERN_MAGIC);
-
-  if (! g_output_stream_write_all (output, &ph, sizeof (GimpPatternHeader),
-                                   NULL, NULL, error))
-    {
-      GCancellable *cancellable = g_cancellable_new ();
-
-      g_cancellable_cancel (cancellable);
-      g_output_stream_close (output, cancellable, NULL);
-      g_object_unref (cancellable);
-
-      g_object_unref (output);
-      return FALSE;
-    }
-
-  if (! g_output_stream_write_all (output,
-                                   description, strlen (description) + 1,
-                                   NULL, NULL, error))
-    {
-      GCancellable *cancellable = g_cancellable_new ();
-
-      g_cancellable_cancel (cancellable);
-      g_output_stream_close (output, cancellable, NULL);
-      g_object_unref (cancellable);
-
-      g_object_unref (output);
-      return FALSE;
-    }
-
-  line_size = width * babl_format_get_bytes_per_pixel (file_format);
-
-  /* this can't overflow because drawable->width is <= GIMP_PATTERN_MAX_SIZE */
-  buf = g_alloca (line_size);
-
-  for (line = 0; line < height; line++)
-    {
-      gegl_buffer_get (buffer, GEGL_RECTANGLE (0, line, width, 1), 1.0,
-                       file_format, buf,
-                       GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
-
-      if (! g_output_stream_write_all (output, buf, line_size,
-                                       NULL, NULL, error))
-        {
-          GCancellable *cancellable = g_cancellable_new ();
-
-          g_cancellable_cancel (cancellable);
-          g_output_stream_close (output, cancellable, NULL);
-          g_object_unref (cancellable);
-
-          g_object_unref (buffer);
-          g_object_unref (output);
-          return FALSE;
-        }
-
-      gimp_progress_update ((gdouble) line / (gdouble) height);
-    }
-
-  g_object_unref (buffer);
-  g_object_unref (output);
-
-  gimp_progress_update (1.0);
-
-  return TRUE;
-}
-
 static gboolean
 save_dialog (void)
 {


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