[gimp] app, plug-ins: move file-gih-load from the file-gih plug-in to the core
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app, plug-ins: move file-gih-load from the file-gih plug-in to the core
- Date: Tue, 19 Feb 2019 22:45:17 +0000 (UTC)
commit 52adaa1963431e0638f4cf44693b39726437ef0c
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
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..b07b57d743
--- /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_NON_LINEAR);
+
+ 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 (¶ms);
+ gimp_pixpipe_params_parse (pipe->params, ¶ms);
+
+ 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 (¶ms);
+ 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 650cd64299..26c31bf8ea 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, ¶mstring, 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 3549d5068d..572d0e3bfa 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -279,6 +279,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]