[gimp/gimp-2-10] app, plug-ins: move file-gih-load from the file-gih plug-in to the core



commit 088418e004033088315ce2a1ca8a9cba6aaf3e9b
Author: Michael Natterer <mitch gimp org>
Date:   Tue Feb 19 23:27:28 2019 +0100

    app, plug-ins: move file-gih-load from the file-gih plug-in to the core
    
    (cherry picked from commit 52adaa1963431e0638f4cf44693b39726437ef0c)

 app/file-data/Makefile.am     |   2 +
 app/file-data/file-data-gih.c | 343 ++++++++++++++++++++++++++++++++++
 app/file-data/file-data-gih.h |  37 ++++
 app/file-data/file-data.c     |  65 +++++++
 plug-ins/common/file-gih.c    | 418 +-----------------------------------------
 po/POTFILES.in                |   1 +
 6 files changed, 449 insertions(+), 417 deletions(-)
---
diff --git a/app/file-data/Makefile.am b/app/file-data/Makefile.am
index 9c79dae1df..ba0fd577f2 100644
--- a/app/file-data/Makefile.am
+++ b/app/file-data/Makefile.am
@@ -18,5 +18,7 @@ libappfile_data_a_SOURCES = \
        file-data.h     \
        file-data-gbr.c \
        file-data-gbr.h \
+       file-data-gih.c \
+       file-data-gih.h \
        file-data-pat.c \
        file-data-pat.h
diff --git a/app/file-data/file-data-gih.c b/app/file-data/file-data-gih.c
new file mode 100644
index 0000000000..8bf66a630b
--- /dev/null
+++ b/app/file-data/file-data-gih.c
@@ -0,0 +1,343 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * 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 <https://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <cairo.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <gegl.h>
+
+#include "libgimpbase/gimpbase.h"
+#include "libgimpbase/gimpparasiteio.h"
+#include "libgimpcolor/gimpcolor.h"
+
+#include "core/core-types.h"
+
+#include "core/gimp.h"
+#include "core/gimpbrushpipe.h"
+#include "core/gimpbrushpipe-load.h"
+#include "core/gimpbrush-private.h"
+#include "core/gimpdrawable.h"
+#include "core/gimpimage.h"
+#include "core/gimplayer-new.h"
+#include "core/gimpparamspecs.h"
+#include "core/gimptempbuf.h"
+
+#include "pdb/gimpprocedure.h"
+
+#include "file-data-gbr.h"
+#include "file-data-gih.h"
+
+#include "gimp-intl.h"
+
+
+/*  local function prototypes  */
+
+static GimpImage     * file_gih_pipe_to_image (Gimp          *gimp,
+                                               GimpBrushPipe *pipe);
+static GimpBrushPipe * file_gih_image_to_pipe (GimpImage     *image,
+                                               GimpDrawable  *drawable,
+                                               const gchar   *name,
+                                               gdouble        spacing);
+
+
+/*  public functions  */
+
+GimpValueArray *
+file_gih_load_invoker (GimpProcedure         *procedure,
+                       Gimp                  *gimp,
+                       GimpContext           *context,
+                       GimpProgress          *progress,
+                       const GimpValueArray  *args,
+                       GError               **error)
+{
+  GimpValueArray *return_vals;
+  GimpImage      *image = NULL;
+  const gchar    *uri;
+  GFile          *file;
+  GInputStream   *input;
+  GError         *my_error = NULL;
+
+  gimp_set_busy (gimp);
+
+  uri  = g_value_get_string (gimp_value_array_index (args, 1));
+  file = g_file_new_for_uri (uri);
+
+  input = G_INPUT_STREAM (g_file_read (file, NULL, &my_error));
+
+  if (input)
+    {
+      GList *list = gimp_brush_pipe_load (context, file, input, error);
+
+      if (list)
+        {
+          GimpBrushPipe *pipe = list->data;
+
+          g_list_free (list);
+
+          image = file_gih_pipe_to_image (gimp, pipe);
+          g_object_unref (pipe);
+        }
+
+      g_object_unref (input);
+    }
+  else
+    {
+      g_propagate_prefixed_error (error, my_error,
+                                  _("Could not open '%s' for reading: "),
+                                  gimp_file_get_utf8_name (file));
+    }
+
+  g_object_unref (file);
+
+  return_vals = gimp_procedure_get_return_values (procedure, image != NULL,
+                                                  error ? *error : NULL);
+
+  if (image)
+    gimp_value_set_image (gimp_value_array_index (return_vals, 1), image);
+
+  gimp_unset_busy (gimp);
+
+  return return_vals;
+}
+
+GimpValueArray *
+file_gih_save_invoker (GimpProcedure         *procedure,
+                       Gimp                  *gimp,
+                       GimpContext           *context,
+                       GimpProgress          *progress,
+                       const GimpValueArray  *args,
+                       GError               **error)
+{
+  GimpValueArray *return_vals;
+  GimpImage      *image;
+  GimpDrawable   *drawable;
+  GimpBrushPipe  *pipe;
+  const gchar    *uri;
+  const gchar    *name;
+  GFile          *file;
+  gint            spacing;
+  gboolean        success;
+
+  gimp_set_busy (gimp);
+
+  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));
+  spacing  = g_value_get_int (gimp_value_array_index (args, 5));
+  name     = g_value_get_string (gimp_value_array_index (args, 6));
+
+  file = g_file_new_for_uri (uri);
+
+  pipe = file_gih_image_to_pipe (image, drawable, name, spacing);
+
+  gimp_data_set_file (GIMP_DATA (pipe), file, TRUE, TRUE);
+
+  success = gimp_data_save (GIMP_DATA (pipe), error);
+
+  g_object_unref (pipe);
+  g_object_unref (file);
+
+  return_vals = gimp_procedure_get_return_values (procedure, success,
+                                                  error ? *error : NULL);
+
+  gimp_unset_busy (gimp);
+
+  return return_vals;
+}
+
+
+/*  private functions  */
+
+static GimpImage *
+file_gih_pipe_to_image (Gimp          *gimp,
+                        GimpBrushPipe *pipe)
+{
+  GimpImage         *image;
+  const gchar       *name;
+  GimpImageBaseType  base_type;
+  GimpParasite      *parasite;
+  gint               i;
+
+  if (gimp_brush_get_pixmap (pipe->current))
+    base_type = GIMP_RGB;
+  else
+    base_type = GIMP_GRAY;
+
+  name = gimp_object_get_name (pipe);
+
+  image = gimp_image_new (gimp, 1, 1, base_type,
+                          GIMP_PRECISION_U8_GAMMA);
+
+  parasite = gimp_parasite_new ("gimp-brush-pipe-name",
+                                GIMP_PARASITE_PERSISTENT,
+                                strlen (name) + 1, name);
+  gimp_image_parasite_attach (image, parasite);
+  gimp_parasite_free (parasite);
+
+  for (i = 0; i < pipe->n_brushes; i++)
+    {
+      GimpLayer *layer;
+
+      layer = file_gbr_brush_to_layer (image, pipe->brushes[i]);
+      gimp_image_add_layer (image, layer, NULL, i, FALSE);
+    }
+
+  if (pipe->params)
+    {
+      GimpPixPipeParams  params;
+      gchar             *paramstring;
+
+      /* Since we do not (yet) load the pipe as described in the
+       * header, but use one layer per brush, we have to alter the
+       * paramstring before attaching it as a parasite.
+       *
+       * (this comment copied over from file-gih, whatever "as
+       * described in the header" means) -- mitch
+       */
+
+      gimp_pixpipe_params_init (&params);
+      gimp_pixpipe_params_parse (pipe->params, &params);
+
+      params.cellwidth  = gimp_image_get_width  (image);
+      params.cellheight = gimp_image_get_height (image);
+      params.cols       = 1;
+      params.rows       = 1;
+
+      paramstring = gimp_pixpipe_params_build (&params);
+      if (paramstring)
+        {
+          parasite = gimp_parasite_new ("gimp-brush-pipe-parameters",
+                                        GIMP_PARASITE_PERSISTENT,
+                                        strlen (paramstring) + 1,
+                                        paramstring);
+          gimp_image_parasite_attach (image, parasite);
+          gimp_parasite_free (parasite);
+          g_free (paramstring);
+        }
+    }
+
+  return image;
+}
+
+static GimpBrushPipe *
+file_gih_image_to_pipe (GimpImage    *image,
+                        GimpDrawable *drawable,
+                        const gchar  *name,
+                        gdouble       spacing)
+{
+#if 0
+  GimpBrush   *brush;
+  GeglBuffer  *buffer;
+  GimpTempBuf *mask;
+  GimpTempBuf *pixmap = NULL;
+  gint         width;
+  gint         height;
+
+  buffer = gimp_drawable_get_buffer (drawable);
+  width  = gimp_item_get_width  (GIMP_ITEM (drawable));
+  height = gimp_item_get_height (GIMP_ITEM (drawable));
+
+  brush = g_object_new (GIMP_TYPE_BRUSH,
+                        "name",      name,
+                        "mime-type", "image/x-gimp-gih",
+                        "spacing",   spacing,
+                        NULL);
+
+  mask = gimp_temp_buf_new (width, height, babl_format ("Y u8"));
+
+  if (gimp_drawable_is_gray (drawable))
+    {
+      guchar *m = gimp_temp_buf_get_data (mask);
+      gint    i;
+
+      if (gimp_drawable_has_alpha (drawable))
+        {
+          GeglBufferIterator *iter;
+          GimpRGB             white;
+
+          gimp_rgba_set_uchar (&white, 255, 255, 255, 255);
+
+          iter = gegl_buffer_iterator_new (buffer, NULL, 0,
+                                           babl_format ("Y'A u8"),
+                                           GEGL_ACCESS_READ, GEGL_ABYSS_NONE,
+                                           1);
+
+          while (gegl_buffer_iterator_next (iter))
+            {
+              guint8 *data = (guint8 *) iter->items[0].data;
+              gint    j;
+
+              for (j = 0; j < iter->length; j++)
+                {
+                  GimpRGB gray;
+                  gint    x, y;
+                  gint    dest;
+
+                  gimp_rgba_set_uchar (&gray,
+                                       data[0], data[0], data[0],
+                                       data[1]);
+
+                  gimp_rgb_composite (&gray, &white,
+                                      GIMP_RGB_COMPOSITE_BEHIND);
+
+                  x = iter->items[0].roi.x + j % iter->items[0].roi.width;
+                  y = iter->items[0].roi.y + j / iter->items[0].roi.width;
+
+                  dest = y * width + x;
+
+                  gimp_rgba_get_uchar (&gray, &m[dest], NULL, NULL, NULL);
+
+                  data += 2;
+                }
+            }
+        }
+      else
+        {
+          gegl_buffer_get (buffer, GEGL_RECTANGLE (0, 0, width, height), 1.0,
+                           babl_format ("Y' u8"), m,
+                           GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
+        }
+
+      /*  invert  */
+      for (i = 0; i < width * height; i++)
+        m[i] = 255 - m[i];
+    }
+  else
+    {
+      pixmap = gimp_temp_buf_new (width, height, babl_format ("R'G'B' u8"));
+
+      gegl_buffer_get (buffer, GEGL_RECTANGLE (0, 0, width, height), 1.0,
+                       babl_format ("R'G'B' u8"),
+                       gimp_temp_buf_get_data (pixmap),
+                       GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
+
+      gegl_buffer_get (buffer, GEGL_RECTANGLE (0, 0, width, height), 1.0,
+                       babl_format ("A u8"),
+                       gimp_temp_buf_get_data (mask),
+                       GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
+    }
+
+
+  brush->priv->mask   = mask;
+  brush->priv->pixmap = pixmap;
+
+  return brush;
+#endif
+
+  return NULL;
+}
diff --git a/app/file-data/file-data-gih.h b/app/file-data/file-data-gih.h
new file mode 100644
index 0000000000..877e4a53eb
--- /dev/null
+++ b/app/file-data/file-data-gih.h
@@ -0,0 +1,37 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * 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 <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef __FILE_DATA_GIH_H__
+#define __FILE_DATA_GIH_H__
+
+
+GimpValueArray * file_gih_load_invoker (GimpProcedure         *procedure,
+                                        Gimp                  *gimp,
+                                        GimpContext           *context,
+                                        GimpProgress          *progress,
+                                        const GimpValueArray  *args,
+                                        GError               **error);
+
+GimpValueArray * file_gih_save_invoker (GimpProcedure         *procedure,
+                                        Gimp                  *gimp,
+                                        GimpContext           *context,
+                                        GimpProgress          *progress,
+                                        const GimpValueArray  *args,
+                                        GError               **error);
+
+
+#endif /* __FILE_DATA_GIH_H__ */
diff --git a/app/file-data/file-data.c b/app/file-data/file-data.c
index e425813cf8..9468cc0855 100644
--- a/app/file-data/file-data.c
+++ b/app/file-data/file-data.c
@@ -32,6 +32,7 @@
 
 #include "file-data.h"
 #include "file-data-gbr.h"
+#include "file-data-gih.h"
 #include "file-data-pat.h"
 
 #include "gimp-intl.h"
@@ -197,6 +198,70 @@ file_data_init (Gimp *gimp)
   gimp_plug_in_manager_add_procedure (gimp->plug_in_manager, proc);
   g_object_unref (procedure);
 
+  /*  file-gih-load  */
+  file = g_file_new_for_path ("file-gih-load");
+  procedure = gimp_plug_in_procedure_new (GIMP_PLUGIN, file);
+  g_object_unref (file);
+
+  procedure->proc_type    = GIMP_INTERNAL;
+  procedure->marshal_func = file_gih_load_invoker;
+
+  proc = GIMP_PLUG_IN_PROCEDURE (procedure);
+  proc->menu_label = g_strdup (N_("GIMP brush (animated)"));
+  gimp_plug_in_procedure_set_icon (proc, GIMP_ICON_TYPE_ICON_NAME,
+                                   (const guint8 *) "gimp-brush",
+                                   strlen ("gimp-brush") + 1);
+  gimp_plug_in_procedure_set_image_types (proc, NULL);
+  gimp_plug_in_procedure_set_file_proc (proc, "gih", "", "");
+  gimp_plug_in_procedure_set_mime_types (proc, "image/gimp-x-gih");
+  gimp_plug_in_procedure_set_handles_uri (proc);
+
+  gimp_object_set_static_name (GIMP_OBJECT (procedure), "file-gih-load");
+  gimp_procedure_set_static_strings (procedure,
+                                     "file-gih-load",
+                                     "Loads GIMP animated brushes",
+                                     "This procedure loads a GIMP brush "
+                                     "pipe as an image.",
+                                     "Jens Lautenbacher, Sven Neumann, "
+                                     "Michael Natterer",
+                                     "Jens Lautenbacher, Sven Neumann, "
+                                     "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_string ("uri",
+                                                       "URI",
+                                                       "The URI of the file "
+                                                       "to load",
+                                                       TRUE, 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 load",
+                                                       TRUE, FALSE, TRUE,
+                                                       NULL,
+                                                       GIMP_PARAM_READWRITE));
+
+  gimp_procedure_add_return_value (procedure,
+                                   gimp_param_spec_image_id ("image",
+                                                             "Image",
+                                                             "Output image",
+                                                             gimp, FALSE,
+                                                             GIMP_PARAM_READWRITE));
+
+  gimp_plug_in_manager_add_procedure (gimp->plug_in_manager, proc);
+  g_object_unref (procedure);
+
   /*  file-pat-load  */
   file = g_file_new_for_path ("file-pat-load");
   procedure = gimp_plug_in_procedure_new (GIMP_PLUGIN, file);
diff --git a/plug-ins/common/file-gih.c b/plug-ins/common/file-gih.c
index a8f4698e96..d37cd1b045 100644
--- a/plug-ins/common/file-gih.c
+++ b/plug-ins/common/file-gih.c
@@ -53,7 +53,6 @@
 #include "libgimp/stdplugins-intl.h"
 
 
-#define LOAD_PROC      "file-gih-load"
 #define SAVE_PROC      "file-gih-save"
 #define PLUG_IN_BINARY "file-gih"
 #define PLUG_IN_ROLE   "gimp-file-gih"
@@ -96,12 +95,6 @@ static void      run                 (const gchar      *name,
                                       gint             *nreturn_vals,
                                       GimpParam       **return_vals);
 
-static gint32    gih_load_image      (GFile            *file,
-                                      GError          **error);
-static gboolean  gih_load_one_brush  (GInputStream     *input,
-                                      gint32            image_ID,
-                                      GError          **error);
-
 static gboolean  gih_save_dialog     (gint32            image_ID);
 static gboolean  gih_save_one_brush  (GOutputStream    *output,
                                       gint32            drawable_ID,
@@ -169,36 +162,6 @@ query (void)
     { GIMP_PDB_STRINGARRAY, "sel",          "Selection modes" }
   };
 
-  static const GimpParamDef gih_load_args[] =
-  {
-    { GIMP_PDB_INT32,  "run-mode", "The run mode { RUN-INTERACTIVE (0), RUN-NONINTERACTIVE (1) }" },
-    { GIMP_PDB_STRING, "uri",      "The name of the file to load" },
-    { GIMP_PDB_STRING, "raw-uri",  "The name of the file to load" }
-  };
-  static const GimpParamDef gih_load_return_vals[] =
-  {
-    { GIMP_PDB_IMAGE,  "image",     "Output image" }
-  };
-
-  gimp_install_procedure (LOAD_PROC,
-                          "loads images in GIMP brush pipe format",
-                          "This plug-in loads a GIMP brush pipe as an image.",
-                          "Jens Lautenbacher, Sven Neumann",
-                          "Jens Lautenbacher, Sven Neumann",
-                          "2000",
-                          N_("GIMP brush (animated)"),
-                          NULL,
-                          GIMP_PLUGIN,
-                          G_N_ELEMENTS (gih_load_args),
-                          G_N_ELEMENTS (gih_load_return_vals),
-                          gih_load_args, gih_load_return_vals);
-
-  gimp_plugin_icon_register (LOAD_PROC, GIMP_ICON_TYPE_ICON_NAME,
-                             (const guint8 *) GIMP_ICON_BRUSH);
-  gimp_register_file_handler_mime (LOAD_PROC, "image/x-gimp-gih");
-  gimp_register_file_handler_uri (LOAD_PROC);
-  gimp_register_magic_load_handler (LOAD_PROC, "gih", "", "");
-
   gimp_install_procedure (SAVE_PROC,
                           "exports images in GIMP brush pipe format",
                           "This plug-in exports an image in the GIMP brush pipe "
@@ -250,23 +213,7 @@ run (const gchar      *name,
   values[0].type          = GIMP_PDB_STATUS;
   values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
 
-  if (strcmp (name, LOAD_PROC) == 0)
-    {
-      image_ID = gih_load_image (g_file_new_for_uri (param[1].data.d_string),
-                                 &error);
-
-      if (image_ID != -1)
-        {
-          *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, SAVE_PROC) == 0)
+  if (strcmp (name, SAVE_PROC) == 0)
     {
       GFile        *file;
       GimpParasite *name_parasite;
@@ -445,369 +392,6 @@ run (const gchar      *name,
 }
 
 
-/*  load routines  */
-
-static gboolean
-gih_load_one_brush (GInputStream  *input,
-                    gint32         image_ID,
-                    GError       **error)
-{
-  gchar             *name       = NULL;
-  GimpBrushHeader    bh;
-  guchar            *brush_buf  = NULL;
-  gint32             layer_ID;
-  gsize              size;
-  GimpImageType      image_type;
-  gint               width, height;
-  gint               new_width, new_height;
-  gsize              bytes_read;
-
-  if (! g_input_stream_read_all (input, &bh, sizeof (bh),
-                                 &bytes_read, NULL, error) ||
-      bytes_read != sizeof (bh))
-    {
-      return FALSE;
-    }
-
-  /*  rearrange the bytes in each unsigned int  */
-  bh.header_size  = g_ntohl (bh.header_size);
-  bh.version      = g_ntohl (bh.version);
-  bh.width        = g_ntohl (bh.width);
-  bh.height       = g_ntohl (bh.height);
-  bh.bytes        = g_ntohl (bh.bytes);
-  bh.magic_number = g_ntohl (bh.magic_number);
-  bh.spacing      = g_ntohl (bh.spacing);
-
-  /* Sanitize values */
-  if ((bh.width  == 0) || (bh.width  > GIMP_BRUSH_MAX_SIZE) ||
-      (bh.height == 0) || (bh.height > GIMP_BRUSH_MAX_SIZE) ||
-      ((bh.bytes != 1) && (bh.bytes != 4)) ||
-      (G_MAXSIZE / bh.width / bh.height / bh.bytes < 1))
-    {
-      return FALSE;
-    }
-
-  if ((bh.magic_number != GIMP_BRUSH_MAGIC ||
-       bh.version != 2)                    ||
-      bh.header_size <= sizeof (bh))
-    {
-      return FALSE;
-    }
-
-  if ((size = (bh.header_size - sizeof (bh))) > 0)
-    {
-      if (size > GIMP_BRUSH_MAX_NAME)
-        {
-          g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
-                       _("Brush name is too long: %lu"),
-                       (gulong) size);
-          return FALSE;
-        }
-
-      name = g_new0 (gchar, size + 1);
-
-      if (! g_input_stream_read_all (input, name, size,
-                                     &bytes_read, NULL, error) ||
-          bytes_read != size)
-        {
-          g_free (name);
-          return FALSE;
-        }
-    }
-  else
-    {
-      name = g_strdup (_("Unnamed"));
-    }
-
-  /* Now there's just raw data left. */
-
-  size = (gsize) bh.width * bh.height * bh.bytes;
-  brush_buf = g_malloc (size);
-
-  if (! g_input_stream_read_all (input, brush_buf, size,
-                                 &bytes_read, NULL, error) ||
-      bytes_read != size)
-    {
-      g_free (brush_buf);
-      g_free (name);
-      return FALSE;
-    }
-
-  if (bh.bytes == 1)
-    {
-      GimpPatternHeader ph;
-
-      /* For backwards-compatibility, check if a pattern follows.
-       * The obsolete .gpb format did it this way.
-       */
-
-      if (g_input_stream_read_all (input, &ph, sizeof (GimpPatternHeader),
-                                   &bytes_read, NULL, error) &&
-          bytes_read == sizeof (GimpPatternHeader))
-        {
-          /*  rearrange the bytes in each unsigned int  */
-          ph.header_size  = g_ntohl (ph.header_size);
-          ph.version      = g_ntohl (ph.version);
-          ph.width        = g_ntohl (ph.width);
-          ph.height       = g_ntohl (ph.height);
-          ph.bytes        = g_ntohl (ph.bytes);
-          ph.magic_number = g_ntohl (ph.magic_number);
-
-          if (ph.magic_number == GIMP_PATTERN_MAGIC        &&
-              ph.version      == 1                         &&
-              ph.header_size  > sizeof (GimpPatternHeader) &&
-              ph.bytes        == 3                         &&
-              ph.width        == bh.width                  &&
-              ph.height       == bh.height                 &&
-              g_input_stream_skip (input,
-                                   ph.header_size - sizeof (GimpPatternHeader),
-                                   NULL, NULL) ==
-              ph.header_size - sizeof (GimpPatternHeader))
-            {
-              guchar *plain_brush = brush_buf;
-              gint    i;
-
-              bh.bytes = 4;
-              brush_buf = g_malloc ((gsize) bh.width * bh.height * 4);
-
-              for (i = 0; i < ph.width * ph.height; i++)
-                {
-                  if (! g_input_stream_read_all (input,
-                                                 brush_buf + i * 4, 3,
-                                                 &bytes_read, NULL, error) ||
-                      bytes_read != 3)
-                    {
-                      g_free (name);
-                      g_free (plain_brush);
-                      g_free (brush_buf);
-                      return FALSE;
-                    }
-
-                  brush_buf[i * 4 + 3] = plain_brush[i];
-                }
-
-              g_free (plain_brush);
-            }
-          else if (! g_seekable_seek (G_SEEKABLE (input),
-                                      - sizeof (GimpPatternHeader), G_SEEK_CUR,
-                                      NULL, NULL))
-            {
-              g_message (_("GIMP brush file appears to be corrupted."));
-              g_free (name);
-              g_free (brush_buf);
-              return FALSE;
-            }
-        }
-    }
-
-  /*
-   * Create a new layer of the proper size.
-   */
-
-  switch (bh.bytes)
-    {
-    case 1:
-      image_type = GIMP_GRAY_IMAGE;
-      break;
-
-    case 4:
-      image_type = GIMP_RGBA_IMAGE;
-      if (gimp_image_base_type (image_ID) == GIMP_GRAY)
-        gimp_image_convert_rgb (image_ID);
-      break;
-
-    default:
-      g_message ("Unsupported brush depth: %d\n"
-                 "GIMP Brushes must be GRAY or RGBA\n",
-                 bh.bytes);
-      g_free (name);
-      return FALSE;
-    }
-
-  new_width  = width  = gimp_image_width (image_ID);
-  new_height = height = gimp_image_height (image_ID);
-
-  if (bh.width > width || bh.height > height)
-    {
-      new_width  = MAX (width, bh.width);
-      new_height = MAX (height, bh.height);
-      gimp_image_resize (image_ID,
-                         new_width, new_height,
-                         (new_width - width) / 2, (new_height - height) / 2);
-    }
-
-  layer_ID = gimp_layer_new (image_ID, name,
-                             bh.width, bh.height,
-                             image_type,
-                             100,
-                             gimp_image_get_default_new_layer_mode (image_ID));
-  g_free (name);
-
-  if (layer_ID != -1)
-    {
-      GeglBuffer *buffer;
-      gint        i;
-
-      gimp_image_insert_layer (image_ID, layer_ID, -1, num_layers++);
-      gimp_layer_set_offsets (layer_ID,
-                              (new_width - bh.width)   / 2,
-                              (new_height - bh.height) / 2);
-
-      buffer = gimp_drawable_get_buffer (layer_ID);
-
-      /*  invert  */
-      if (image_type == GIMP_GRAY_IMAGE)
-        for (i = 0; i < bh.width * bh.height; i++)
-          brush_buf[i] = 255 - brush_buf[i];
-
-      gegl_buffer_set (buffer, GEGL_RECTANGLE (0, 0, bh.width, bh.height), 0,
-                       NULL, brush_buf, GEGL_AUTO_ROWSTRIDE);
-
-      g_object_unref (buffer);
-    }
-
-  g_free (brush_buf);
-
-  return TRUE;
-}
-
-static gint32
-gih_load_image (GFile   *file,
-                GError **error)
-{
-  GInputStream *input;
-  gint          i;
-  gint32        image_ID;
-  GString      *buffer;
-  gchar         c;
-  gchar        *name = NULL;
-  gint          num_of_brushes = 0;
-  gchar        *paramstring;
-  GimpParasite *name_parasite;
-  GimpParasite *pipe_parasite;
-  gsize         bytes_read;
-
-  gimp_progress_init_printf (_("Opening '%s'"),
-                             g_file_get_parse_name (file));
-
-  input = G_INPUT_STREAM (g_file_read (file, NULL, error));
-  if (! input)
-    return -1;
-
-  /* The file format starts with a painfully simple text header */
-
-  /*  get the name  */
-  buffer = g_string_new (NULL);
-  while (g_input_stream_read_all (input, &c, 1,
-                                  &bytes_read, NULL, error) &&
-         bytes_read == 1 &&
-         c != '\n'       &&
-         buffer->len < 1024)
-    {
-      g_string_append_c (buffer, c);
-    }
-
-  if (buffer->len > 0 && buffer->len < 1024)
-    name = buffer->str;
-
-  g_string_free (buffer, FALSE);
-
-  if (! name)
-    {
-      g_message ("Couldn't read name for brush pipe from '%s'",
-                 g_file_get_parse_name (file));
-      g_object_unref (input);
-      return -1;
-    }
-
-  /*  get the number of brushes  */
-  buffer = g_string_new (NULL);
-  while (g_input_stream_read_all (input, &c, 1,
-                                  &bytes_read, NULL, error) &&
-         bytes_read == 1 &&
-         c != '\n'       &&
-         buffer->len < 1024)
-    {
-      g_string_append_c (buffer, c);
-    }
-
-  if (buffer->len > 0 && buffer->len < 1024)
-    {
-      num_of_brushes = strtol (buffer->str, &paramstring, 10);
-    }
-
-  if (num_of_brushes < 1)
-    {
-      g_message ("Brush pipes should have at least one brush.");
-      g_object_unref (input);
-      g_free (name);
-      g_string_free (buffer, TRUE);
-      return -1;
-    }
-
-  image_ID = gimp_image_new (1, 1, GIMP_GRAY);
-  gimp_image_set_filename (image_ID, g_file_get_uri (file));
-
-  for (i = 0; i < num_of_brushes; i++)
-    {
-      if (! gih_load_one_brush (input, image_ID, error))
-        {
-          g_object_unref (input);
-          g_free (name);
-          g_string_free (buffer, TRUE);
-          return -1;
-        }
-
-      gimp_progress_update ((gdouble) i / (gdouble) num_of_brushes);
-    }
-
-  g_object_unref (input);
-
-  /*  Attaching name as a parasite */
-  name_parasite = gimp_parasite_new ("gimp-brush-pipe-name",
-                                     GIMP_PARASITE_PERSISTENT,
-                                     strlen (name) + 1,
-                                     name);
-  gimp_image_attach_parasite (image_ID, name_parasite);
-  gimp_parasite_free (name_parasite);
-
-  while (*paramstring && g_ascii_isspace (*paramstring))
-    paramstring++;
-
-  /*  Since we do not (yet) load the pipe as described in the header,
-      but use one layer per brush, we have to alter the paramstring
-      before attaching it as a parasite.
-   */
-
-  if (*paramstring)
-    {
-      gimp_pixpipe_params_parse (paramstring, &gihparams);
-
-      gihparams.cellwidth  = gimp_image_width  (image_ID);
-      gihparams.cellheight = gimp_image_height (image_ID);
-      gihparams.cols       = 1;
-      gihparams.rows       = 1;
-
-      paramstring = gimp_pixpipe_params_build (&gihparams);
-      if (paramstring)
-        {
-          pipe_parasite = gimp_parasite_new ("gimp-brush-pipe-parameters",
-                                             GIMP_PARASITE_PERSISTENT,
-                                             strlen (paramstring) + 1,
-                                             paramstring);
-          gimp_image_attach_parasite (image_ID, pipe_parasite);
-          gimp_parasite_free (pipe_parasite);
-          g_free (paramstring);
-        }
-    }
-
-  g_string_free (buffer, TRUE);
-
-  gimp_progress_update (1.0);
-
-  return image_ID;
-}
-
 /*  save routines */
 
 static void
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 8511a6ba6d..866aa089b7 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -276,6 +276,7 @@ app/file/file-save.c
 app/file/file-utils.c
 
 app/file-data/file-data-gbr.c
+app/file-data/file-data-gih.c
 app/file-data/file-data-pat.c
 app/file-data/file-data.c
 


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