[gimp] app, plug-ins: start consolidating brush and pattern loading/saving code



commit a4e77e57f61473f3cfda2ba1d87a0a5dd1035270
Author: Michael Natterer <mitch gimp org>
Date:   Mon Feb 11 12:45:06 2019 +0100

    app, plug-ins: start consolidating brush and pattern loading/saving code
    
    We currently have brush and pattern I/O code in both the core and
    plug-ins. This commit starts removing plug-in code in favor of having
    one copy of the code in the core, much like XCF loading and saving is
    implemented.
    
    Add app/file-data/ module with file procedure registering code, for
    now just with an implementation of file-gbr-load.
    
    Remove the file-gbr-load code from the file-gbr plug-in.

 app/Makefile.am               |   2 +
 app/core/gimp.c               |   3 +
 app/file-data/.gitignore      |   7 +
 app/file-data/Makefile.am     |  20 +++
 app/file-data/file-data-gbr.c | 240 ++++++++++++++++++++++++++
 app/file-data/file-data-gbr.h |  37 +++++
 app/file-data/file-data.c     | 118 +++++++++++++
 app/file-data/file-data.h     |  26 +++
 configure.ac                  |   1 +
 plug-ins/common/file-gbr.c    | 379 +-----------------------------------------
 po/POTFILES.in                |   3 +
 11 files changed, 458 insertions(+), 378 deletions(-)
---
diff --git a/app/Makefile.am b/app/Makefile.am
index 052426d927..c6774f0492 100644
--- a/app/Makefile.am
+++ b/app/Makefile.am
@@ -28,6 +28,7 @@ SUBDIRS = \
        plug-in         \
        xcf             \
        file            \
+       file-data       \
        pdb             \
        widgets         \
        propgui         \
@@ -159,6 +160,7 @@ gimpconsoleldadd = \
        vectors/libappvectors.a                                 \
        core/libappcore.a                                       \
        file/libappfile.a                                       \
+       file-data/libappfile-data.a                             \
        text/libapptext.a                                       \
        paint/libapppaint.a                                     \
        operations/libappoperations.a                           \
diff --git a/app/core/gimp.c b/app/core/gimp.c
index 08ffced6ad..ce6d7f8732 100644
--- a/app/core/gimp.c
+++ b/app/core/gimp.c
@@ -41,6 +41,7 @@
 #include "paint/gimp-paint.h"
 
 #include "xcf/xcf.h"
+#include "file-data/file-data.h"
 
 #include "gimp.h"
 #include "gimp-contexts.h"
@@ -284,6 +285,7 @@ gimp_constructed (GObject *object)
   gimp->pdb               = gimp_pdb_new (gimp);
 
   xcf_init (gimp);
+  file_data_init (gimp);
 
   /*  create user and default context  */
   gimp_contexts_init (gimp);
@@ -390,6 +392,7 @@ gimp_finalize (GObject *object)
       g_clear_object (&gimp->tool_info_list);
     }
 
+  file_data_exit (gimp);
   xcf_exit (gimp);
 
   g_clear_object (&gimp->pdb);
diff --git a/app/file-data/.gitignore b/app/file-data/.gitignore
new file mode 100644
index 0000000000..e882491b0b
--- /dev/null
+++ b/app/file-data/.gitignore
@@ -0,0 +1,7 @@
+/Makefile
+/Makefile.in
+/.deps
+/.libs
+/*.lo
+/libappfile-data.a
+/libappfile-data.la
diff --git a/app/file-data/Makefile.am b/app/file-data/Makefile.am
new file mode 100644
index 0000000000..f703ca51d9
--- /dev/null
+++ b/app/file-data/Makefile.am
@@ -0,0 +1,20 @@
+## Process this file with automake to produce Makefile.in
+
+AM_CPPFLAGS = \
+       -DG_LOG_DOMAIN=\"Gimp-File-Data\"       \
+       -I$(top_builddir)                       \
+       -I$(top_srcdir)                         \
+       -I$(top_builddir)/app                   \
+       -I$(top_srcdir)/app                     \
+       $(CAIRO_CFLAGS)                         \
+       $(GEGL_CFLAGS)                          \
+       $(GDK_PIXBUF_CFLAGS)                    \
+       -I$(includedir)
+
+noinst_LIBRARIES = libappfile-data.a
+
+libappfile_data_a_SOURCES = \
+       file-data.c     \
+       file-data.h     \
+       file-data-gbr.c \
+       file-data-gbr.h
diff --git a/app/file-data/file-data-gbr.c b/app/file-data/file-data-gbr.c
new file mode 100644
index 0000000000..56c9f008a4
--- /dev/null
+++ b/app/file-data/file-data-gbr.c
@@ -0,0 +1,240 @@
+/* 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 <gdk-pixbuf/gdk-pixbuf.h>
+#include <gegl.h>
+
+#include "libgimpbase/gimpbase.h"
+
+#include "core/core-types.h"
+
+#include "core/gimp.h"
+#include "core/gimpbrush.h"
+#include "core/gimpbrush-load.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 "gimp-intl.h"
+
+
+/*  local function prototypes  */
+
+static GimpImage * file_gbr_brush_to_image (Gimp      *gimp,
+                                            GimpBrush *brush);
+static GimpBrush * file_gbr_image_to_brush (GimpImage *image);
+
+
+/*  public functions  */
+
+GimpValueArray *
+file_gbr_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)
+    {
+      GimpBrush *brush = gimp_brush_load_brush (context, file, input, error);
+
+      if (brush)
+        {
+          image = file_gbr_brush_to_image (gimp, brush);
+          g_object_unref (brush);
+        }
+
+      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_gbr_save_invoker (GimpProcedure         *procedure,
+                       Gimp                  *gimp,
+                       GimpContext           *context,
+                       GimpProgress          *progress,
+                       const GimpValueArray  *args,
+                       GError               **error)
+{
+  GimpValueArray *return_vals;
+  GimpImage      *image;
+  GimpBrush      *brush;
+  const gchar    *uri;
+  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);
+
+  brush = file_gbr_image_to_brush (image);
+
+  gimp_data_set_file (GIMP_DATA (brush), file, TRUE, TRUE);
+
+  success = gimp_data_save (GIMP_DATA (brush), error);
+
+  g_object_unref (brush);
+  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_gbr_brush_to_image (Gimp      *gimp,
+                         GimpBrush *brush)
+{
+  GimpImage         *image;
+  GimpLayer         *layer;
+  const Babl        *format;
+  const gchar       *name;
+  GimpImageBaseType  base_type;
+  gboolean           alpha;
+  gint               width;
+  gint               height;
+  GimpTempBuf       *mask   = gimp_brush_get_mask   (brush);
+  GimpTempBuf       *pixmap = gimp_brush_get_pixmap (brush);
+  GeglBuffer        *buffer;
+  GimpParasite      *parasite;
+
+  if (pixmap)
+    {
+      base_type = GIMP_RGB;
+      alpha     = TRUE;
+    }
+  else
+    {
+      base_type = GIMP_GRAY;
+      alpha     = FALSE;
+    }
+
+  name   = gimp_object_get_name (brush);
+  width  = gimp_temp_buf_get_width  (mask);
+  height = gimp_temp_buf_get_height (mask);
+
+  image = gimp_image_new (gimp, width, height, base_type,
+                          GIMP_PRECISION_U8_PERCEPTUAL);
+
+  parasite = gimp_parasite_new ("gimp-brush-name",
+                                GIMP_PARASITE_PERSISTENT,
+                                strlen (name) + 1, name);
+  gimp_image_parasite_attach (image, parasite);
+  gimp_parasite_free (parasite);
+
+  format = gimp_image_get_layer_format (image, alpha);
+
+  layer = gimp_layer_new (image, width, height, format, name,
+                          1.0, GIMP_LAYER_MODE_NORMAL);
+  gimp_image_add_layer (image, layer, NULL, 0, FALSE);
+
+  buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (layer));
+
+  if (pixmap)
+    {
+      guchar *pixmap_data;
+      guchar *mask_data;
+      guchar *p;
+      guchar *m;
+      gint    i;
+
+      gegl_buffer_set (buffer, GEGL_RECTANGLE (0, 0, width, height), 0,
+                       babl_format ("R'G'B' u8"),
+                       gimp_temp_buf_get_data (pixmap), GEGL_AUTO_ROWSTRIDE);
+
+      pixmap_data = gegl_buffer_linear_open (buffer, NULL, NULL, NULL);
+      mask_data   = gimp_temp_buf_get_data (mask);
+
+      for (i = 0, p = pixmap_data, m = mask_data;
+           i < width * height;
+           i++, p += 4, m += 1)
+        {
+          p[3] = *m;
+        }
+
+      gegl_buffer_linear_close (buffer, pixmap_data);
+    }
+  else
+    {
+      guchar *mask_data = gimp_temp_buf_get_data (mask);
+      gint    i;
+
+      for (i = 0; i < width * height; i++)
+        mask_data[i] = 255 - mask_data[i];
+
+      gegl_buffer_set (buffer, GEGL_RECTANGLE (0, 0, width, height), 0,
+                       babl_format ("Y' u8"),
+                       mask_data, GEGL_AUTO_ROWSTRIDE);
+    }
+
+  return image;
+}
+
+static GimpBrush *
+file_gbr_image_to_brush (GimpImage *image)
+{
+  return NULL;
+}
diff --git a/app/file-data/file-data-gbr.h b/app/file-data/file-data-gbr.h
new file mode 100644
index 0000000000..3cc355ef50
--- /dev/null
+++ b/app/file-data/file-data-gbr.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_GBR_H__
+#define __FILE_DATA_GBR_H__
+
+
+GimpValueArray * file_gbr_load_invoker (GimpProcedure         *procedure,
+                                        Gimp                  *gimp,
+                                        GimpContext           *context,
+                                        GimpProgress          *progress,
+                                        const GimpValueArray  *args,
+                                        GError               **error);
+
+GimpValueArray * file_gbr_save_invoker (GimpProcedure         *procedure,
+                                        Gimp                  *gimp,
+                                        GimpContext           *context,
+                                        GimpProgress          *progress,
+                                        const GimpValueArray  *args,
+                                        GError               **error);
+
+
+#endif /* __FILE_DATA_GBR_H__ */
diff --git a/app/file-data/file-data.c b/app/file-data/file-data.c
new file mode 100644
index 0000000000..953cec7246
--- /dev/null
+++ b/app/file-data/file-data.c
@@ -0,0 +1,118 @@
+/* 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 <gdk-pixbuf/gdk-pixbuf.h>
+#include <gegl.h>
+
+#include "libgimpbase/gimpbase.h"
+
+#include "core/core-types.h"
+
+#include "core/gimp.h"
+#include "core/gimpparamspecs.h"
+
+#include "plug-in/gimppluginmanager.h"
+#include "plug-in/gimppluginprocedure.h"
+
+#include "file-data.h"
+#include "file-data-gbr.h"
+
+#include "gimp-intl.h"
+
+
+void
+file_data_init (Gimp *gimp)
+{
+  GimpPlugInProcedure *proc;
+  GFile               *file;
+  GimpProcedure       *procedure;
+
+  g_return_if_fail (GIMP_IS_GIMP (gimp));
+
+  /*  file-gbr-load  */
+  file = g_file_new_for_path ("file-gbr-load");
+  procedure = gimp_plug_in_procedure_new (GIMP_PLUGIN, file);
+  g_object_unref (file);
+
+  procedure->proc_type    = GIMP_INTERNAL;
+  procedure->marshal_func = file_gbr_load_invoker;
+
+  proc = GIMP_PLUG_IN_PROCEDURE (procedure);
+  proc->menu_label = g_strdup (N_("GIMP brush"));
+  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, "gbr, gbp", "",
+                                        "20, string, GIMP");
+  gimp_plug_in_procedure_set_mime_types (proc, "image/gimp-x-gbr");
+  gimp_plug_in_procedure_set_handles_uri (proc);
+
+  gimp_object_set_static_name (GIMP_OBJECT (procedure), "file-gbr-load");
+  gimp_procedure_set_static_strings (procedure,
+                                     "file-gbr-load",
+                                     "Loads GIMP brushes",
+                                     "Loads GIMP brushes (1 or 4 bpp "
+                                     "and old .gpb format)",
+                                     "Tim Newsome, Jens Lautenbacher, "
+                                     "Sven Neumann, Michael Natterer",
+                                     "Tim Newsome, 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);
+}
+
+void
+file_data_exit (Gimp *gimp)
+{
+  g_return_if_fail (GIMP_IS_GIMP (gimp));
+}
diff --git a/app/file-data/file-data.h b/app/file-data/file-data.h
new file mode 100644
index 0000000000..a36381d81a
--- /dev/null
+++ b/app/file-data/file-data.h
@@ -0,0 +1,26 @@
+/* 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_H__
+#define __FILE_DATA_H__
+
+
+void   file_data_init (Gimp *gimp);
+void   file_data_exit (Gimp *gimp);
+
+
+#endif /* __FILE_DATA_H__ */
diff --git a/configure.ac b/configure.ac
index 610054d47d..63f81cfac9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2773,6 +2773,7 @@ app/gegl/Makefile
 app/dialogs/Makefile
 app/display/Makefile
 app/file/Makefile
+app/file-data/Makefile
 app/gui/Makefile
 app/menus/Makefile
 app/paint/Makefile
diff --git a/plug-ins/common/file-gbr.c b/plug-ins/common/file-gbr.c
index d104185be2..580c1a4ce5 100644
--- a/plug-ins/common/file-gbr.c
+++ b/plug-ins/common/file-gbr.c
@@ -43,7 +43,6 @@
 #include "libgimp/stdplugins-intl.h"
 
 
-#define LOAD_PROC      "file-gbr-load"
 #define SAVE_PROC      "file-gbr-save"
 #define PLUG_IN_BINARY "file-gbr"
 #define PLUG_IN_ROLE   "gimp-file-gbr"
@@ -65,8 +64,6 @@ static void       run            (const gchar      *name,
                                   gint             *nreturn_vals,
                                   GimpParam       **return_vals);
 
-static gint32     load_image     (GFile            *file,
-                                  GError          **error);
 static gboolean   save_image     (GFile            *file,
                                   gint32            image_ID,
                                   gint32            drawable_ID,
@@ -100,17 +97,6 @@ MAIN ()
 static void
 query (void)
 {
-  static const GimpParamDef load_args[] =
-  {
-    { GIMP_PDB_INT32,  "run-mode", "The run mode { RUN-INTERACTIVE (0), RUN-NONINTERACTIVE (1) }" },
-    { GIMP_PDB_STRING, "uri",      "The URI of the file to load" },
-    { GIMP_PDB_STRING, "raw-uri",  "The URI of the file to load" }
-  };
-  static const GimpParamDef load_return_vals[] =
-  {
-    { GIMP_PDB_IMAGE,  "image",        "Output image" }
-  };
-
   static const GimpParamDef save_args[] =
   {
     { GIMP_PDB_INT32,    "run-mode",    "The run mode { RUN-INTERACTIVE (0), RUN-NONINTERACTIVE (1) }" },
@@ -122,28 +108,6 @@ query (void)
     { GIMP_PDB_STRING,   "description", "Short description of the brush" }
   };
 
-  gimp_install_procedure (LOAD_PROC,
-                          "Loads GIMP brushes",
-                          "Loads GIMP brushes (1 or 4 bpp and old .gpb format)",
-                          "Tim Newsome, Jens Lautenbacher, Sven Neumann",
-                          "Tim Newsome, Jens Lautenbacher, Sven Neumann",
-                          "1997-2005",
-                          N_("GIMP brush"),
-                          NULL,
-                          GIMP_PLUGIN,
-                          G_N_ELEMENTS (load_args),
-                          G_N_ELEMENTS (load_return_vals),
-                          load_args, 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-gbr");
-  gimp_register_file_handler_uri (LOAD_PROC);
-  gimp_register_magic_load_handler (LOAD_PROC,
-                                    "gbr, gpb",
-                                    "",
-                                    "20, string, GIMP");
-
   gimp_install_procedure (SAVE_PROC,
                           "Exports files in the GIMP brush file format",
                           "Exports files in the GIMP brush file format",
@@ -189,23 +153,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 = 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 *parasite;
@@ -342,331 +290,6 @@ run (const gchar      *name,
   values[0].data.d_status = status;
 }
 
-static gint32
-load_image (GFile   *file,
-            GError **error)
-{
-  GInputStream      *input;
-  gchar             *name;
-  GimpBrushHeader    bh;
-  guchar            *brush_buf = NULL;
-  gint32             image_ID;
-  gint32             layer_ID;
-  GimpParasite      *parasite;
-  GeglBuffer        *buffer;
-  const Babl        *format;
-  GimpImageBaseType  base_type;
-  GimpImageType      image_type;
-  gsize              bytes_read;
-  gsize              size;
-  gint               i;
-
-  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;
-
-  size = G_STRUCT_OFFSET (GimpBrushHeader, magic_number);
-
-  if (! g_input_stream_read_all (input, &bh, size,
-                                 &bytes_read, NULL, error) ||
-      bytes_read != size)
-    {
-      g_object_unref (input);
-      return -1;
-    }
-
-  /*  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);
-
-  /* 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 != 2) && (bh.bytes != 4) &&
-       (bh.bytes != 18)) ||
-      (G_MAXSIZE / bh.width / bh.height / MAX (4, bh.bytes) < 1))
-    {
-      g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
-                   _("Invalid header data in '%s': width=%lu, height=%lu, "
-                     "bytes=%lu"), g_file_get_parse_name (file),
-                   (gulong) bh.width,
-                   (gulong) bh.height,
-                   (gulong) bh.bytes);
-      return -1;
-    }
-
-  switch (bh.version)
-    {
-    case 1:
-      /* Version 1 didn't have a magic number and had no spacing  */
-      bh.spacing = 25;
-      bh.header_size += 8;
-      if (bh.header_size < sizeof (GimpBrushHeader))
-        {
-          g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
-                       _("Unsupported brush format"));
-          g_object_unref (input);
-          return -1;
-        }
-      break;
-
-    case 2:
-    case 3: /*  cinepaint brush  */
-      size = sizeof (bh.magic_number) + sizeof (bh.spacing);
-
-      if (! g_input_stream_read_all (input,
-                                     (guchar *) &bh +
-                                     G_STRUCT_OFFSET (GimpBrushHeader,
-                                                      magic_number), size,
-                                     &bytes_read, NULL, error) ||
-          bytes_read != size)
-        {
-          g_object_unref (input);
-          return -1;
-        }
-
-      bh.magic_number = g_ntohl (bh.magic_number);
-      bh.spacing      = g_ntohl (bh.spacing);
-
-      if (bh.version == 3)
-        {
-          if (bh.bytes == 18 /* FLOAT16_GRAY_GIMAGE */)
-            {
-              bh.bytes = 2;
-            }
-          else
-            {
-              g_message (_("Unsupported brush format"));
-              g_object_unref (input);
-              return -1;
-            }
-        }
-
-      if (bh.magic_number == GIMP_BRUSH_MAGIC &&
-          bh.header_size  >  sizeof (GimpBrushHeader))
-        break;
-
-    default:
-      g_message (_("Unsupported brush format"));
-      g_object_unref (input);
-      return -1;
-    }
-
-  if ((size = (bh.header_size - sizeof (GimpBrushHeader))) > 0)
-    {
-      gchar *temp;
-
-      if (size > GIMP_BRUSH_MAX_NAME)
-        {
-          g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
-                       _("Invalid header data in '%s': "
-                         "Brush name is too long: %lu"),
-                       gimp_file_get_utf8_name (file),
-                       (gulong) size);
-          return -1;
-        }
-
-      temp = g_new0 (gchar, size + 1);
-
-      if (! g_input_stream_read_all (input, temp, size,
-                                     &bytes_read, NULL, error) ||
-          bytes_read != size)
-        {
-          g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
-                       _("Error in GIMP brush file '%s'"),
-                       g_file_get_parse_name (file));
-          g_object_unref (input);
-          g_free (temp);
-          return -1;
-        }
-
-      name = gimp_any_to_utf8 (temp, size - 1,
-                               _("Invalid UTF-8 string in brush file '%s'."),
-                               g_file_get_parse_name (file));
-      g_free (temp);
-    }
-  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_object_unref (input);
-      g_free (brush_buf);
-      g_free (name);
-      return -1;
-    }
-
-  switch (bh.bytes)
-    {
-    case 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, NULL) &&
-            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_object_unref (input);
-                        g_free (name);
-                        g_free (plain_brush);
-                        g_free (brush_buf);
-                        return -1;
-                      }
-
-                    brush_buf[i * 4 + 3] = plain_brush[i];
-                  }
-
-                g_free (plain_brush);
-              }
-          }
-      }
-      break;
-
-    case 2:
-      {
-        guint16 *buf = (guint16 *) brush_buf;
-
-        for (i = 0; i < bh.width * bh.height; i++, buf++)
-          {
-            union
-            {
-              guint16 u[2];
-              gfloat  f;
-            } short_float;
-
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
-            short_float.u[0] = 0;
-            short_float.u[1] = GUINT16_FROM_BE (*buf);
-#else
-            short_float.u[0] = GUINT16_FROM_BE (*buf);
-            short_float.u[1] = 0;
-#endif
-
-            brush_buf[i] = (guchar) (short_float.f * 255.0 + 0.5);
-          }
-
-        bh.bytes = 1;
-      }
-      break;
-
-    default:
-      break;
-    }
-
-  /*
-   * Create a new image of the proper size and
-   * associate the filename with it.
-   */
-
-  switch (bh.bytes)
-    {
-    case 1:
-      base_type = GIMP_GRAY;
-      image_type = GIMP_GRAY_IMAGE;
-      format = babl_format ("Y' u8");
-      break;
-
-    case 4:
-      base_type = GIMP_RGB;
-      image_type = GIMP_RGBA_IMAGE;
-      format = babl_format ("R'G'B'A u8");
-      break;
-
-    default:
-      g_message ("Unsupported brush depth: %d\n"
-                 "GIMP Brushes must be GRAY or RGBA\n",
-                 bh.bytes);
-      g_free (name);
-      return -1;
-    }
-
-  image_ID = gimp_image_new (bh.width, bh.height, base_type);
-  gimp_image_set_filename (image_ID, g_file_get_uri (file));
-
-  parasite = gimp_parasite_new ("gimp-brush-name",
-                                GIMP_PARASITE_PERSISTENT,
-                                strlen (name) + 1, name);
-  gimp_image_attach_parasite (image_ID, parasite);
-  gimp_parasite_free (parasite);
-
-  layer_ID = gimp_layer_new (image_ID, name, bh.width, bh.height,
-                             image_type,
-                             100,
-                             gimp_image_get_default_new_layer_mode (image_ID));
-  gimp_image_insert_layer (image_ID, layer_ID, -1, 0);
-
-  g_free (name);
-
-  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,
-                   format, brush_buf, GEGL_AUTO_ROWSTRIDE);
-
-  g_free (brush_buf);
-  g_object_unref (buffer);
-  g_object_unref (input);
-
-  gimp_progress_update (1.0);
-
-  return image_ID;
-}
-
 static gboolean
 save_image (GFile   *file,
             gint32   image_ID,
diff --git a/po/POTFILES.in b/po/POTFILES.in
index ac5f03a6ff..122592c1d4 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -278,6 +278,9 @@ app/file/file-remote.c
 app/file/file-save.c
 app/file/file-utils.c
 
+app/file-data/file-data-gbr.c
+app/file-data/file-data.c
+
 app/gegl/gimp-babl.c
 app/gegl/gimp-gegl-enums.c
 


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