[gimp/gimp-2-10] app, plug-ins: move brush (gbr) saving to the core
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/gimp-2-10] app, plug-ins: move brush (gbr) saving to the core
- Date: Sat, 16 Feb 2019 18:05:16 +0000 (UTC)
commit a04e24ce3e050a29c4b374097deb1f40adca0c24
Author: Michael Natterer <mitch gimp org>
Date: Sat Feb 16 19:00:04 2019 +0100
app, plug-ins: move brush (gbr) saving to the core
just the export logic remains in the plug-in, just as for patterns.
(cherry picked from commit 90164c4951222349b712d33ea043c870c9b0b44f)
app/file-data/file-data-gbr.c | 129 ++++++++++++++++++++++++++---
app/file-data/file-data.c | 87 +++++++++++++++++++-
plug-ins/common/file-gbr.c | 184 ++++++------------------------------------
3 files changed, 229 insertions(+), 171 deletions(-)
---
diff --git a/app/file-data/file-data-gbr.c b/app/file-data/file-data-gbr.c
index b4eb1bd2b8..2c434d388c 100644
--- a/app/file-data/file-data-gbr.c
+++ b/app/file-data/file-data-gbr.c
@@ -17,16 +17,19 @@
#include "config.h"
+#include <cairo.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gegl.h>
#include "libgimpbase/gimpbase.h"
+#include "libgimpcolor/gimpcolor.h"
#include "core/core-types.h"
#include "core/gimp.h"
#include "core/gimpbrush.h"
#include "core/gimpbrush-load.h"
+#include "core/gimpbrush-private.h"
#include "core/gimpdrawable.h"
#include "core/gimpimage.h"
#include "core/gimplayer-new.h"
@@ -42,9 +45,12 @@
/* local function prototypes */
-static GimpImage * file_gbr_brush_to_image (Gimp *gimp,
- GimpBrush *brush);
-static GimpBrush * file_gbr_image_to_brush (GimpImage *image);
+static GimpImage * file_gbr_brush_to_image (Gimp *gimp,
+ GimpBrush *brush);
+static GimpBrush * file_gbr_image_to_brush (GimpImage *image,
+ GimpDrawable *drawable,
+ const gchar *name,
+ gdouble spacing);
/* public functions */
@@ -113,18 +119,25 @@ file_gbr_save_invoker (GimpProcedure *procedure,
{
GimpValueArray *return_vals;
GimpImage *image;
+ GimpDrawable *drawable;
GimpBrush *brush;
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);
- uri = g_value_get_string (gimp_value_array_index (args, 3));
- file = g_file_new_for_uri (uri);
+ image = gimp_value_get_image (gimp_value_array_index (args, 1), gimp);
+ drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
+ uri = g_value_get_string (gimp_value_array_index (args, 3));
+ spacing = g_value_get_int (gimp_value_array_index (args, 5));
+ name = g_value_get_string (gimp_value_array_index (args, 6));
- brush = file_gbr_image_to_brush (image);
+ file = g_file_new_for_uri (uri);
+
+ brush = file_gbr_image_to_brush (image, drawable, name, spacing);
gimp_data_set_file (GIMP_DATA (brush), file, TRUE, TRUE);
@@ -234,7 +247,105 @@ file_gbr_brush_to_image (Gimp *gimp,
}
static GimpBrush *
-file_gbr_image_to_brush (GimpImage *image)
+file_gbr_image_to_brush (GimpImage *image,
+ GimpDrawable *drawable,
+ const gchar *name,
+ gdouble spacing)
{
- return NULL;
+ 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-gbr",
+ "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;
}
diff --git a/app/file-data/file-data.c b/app/file-data/file-data.c
index fc4eecca1b..e425813cf8 100644
--- a/app/file-data/file-data.c
+++ b/app/file-data/file-data.c
@@ -111,6 +111,92 @@ file_data_init (Gimp *gimp)
gimp_plug_in_manager_add_procedure (gimp->plug_in_manager, proc);
g_object_unref (procedure);
+ /* file-gbr-save-internal */
+ file = g_file_new_for_path ("file-gbr-save-internal");
+ procedure = gimp_plug_in_procedure_new (GIMP_PLUGIN, file);
+ g_object_unref (file);
+
+ procedure->proc_type = GIMP_INTERNAL;
+ procedure->marshal_func = file_gbr_save_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);
+
+#if 0
+ /* do not register as file procedure */
+ gimp_plug_in_procedure_set_image_types (proc, "RGB*, GRAY*, INDEXED*");
+ gimp_plug_in_procedure_set_file_proc (proc, "gbr", "", NULL);
+ gimp_plug_in_procedure_set_mime_types (proc, "image/x-gimp-gbr");
+ gimp_plug_in_procedure_set_handles_uri (proc);
+#endif
+
+ gimp_object_set_static_name (GIMP_OBJECT (procedure),
+ "file-gbr-save-internal");
+ gimp_procedure_set_static_strings (procedure,
+ "file-gbr-save-internal",
+ "Exports Gimp brush file (.GBR)",
+ "Exports Gimp brush file (.GBR)",
+ "Tim Newsome, Michael Natterer",
+ "Tim Newsome, Michael Natterer",
+ "1995-2019",
+ NULL);
+
+ gimp_procedure_add_argument (procedure,
+ gimp_param_spec_int32 ("dummy-param",
+ "Dummy Param",
+ "Dummy parameter",
+ G_MININT32, G_MAXINT32, 0,
+ GIMP_PARAM_READWRITE));
+ gimp_procedure_add_argument (procedure,
+ gimp_param_spec_image_id ("image",
+ "Image",
+ "Input image",
+ gimp, FALSE,
+ GIMP_PARAM_READWRITE));
+ gimp_procedure_add_argument (procedure,
+ gimp_param_spec_drawable_id ("drawable",
+ "Drawable",
+ "Active drawable "
+ "of input image",
+ gimp, FALSE,
+ GIMP_PARAM_READWRITE));
+ gimp_procedure_add_argument (procedure,
+ gimp_param_spec_string ("uri",
+ "URI",
+ "The URI of the file "
+ "to export",
+ FALSE, FALSE, TRUE,
+ NULL,
+ GIMP_PARAM_READWRITE));
+ gimp_procedure_add_argument (procedure,
+ gimp_param_spec_string ("raw-uri",
+ "Raw URI",
+ "The URI of the file "
+ "to export",
+ FALSE, FALSE, TRUE,
+ NULL,
+ GIMP_PARAM_READWRITE));
+ gimp_procedure_add_argument (procedure,
+ gimp_param_spec_int32 ("spacing",
+ "spacing",
+ "Spacing of the brush",
+ 1, 1000, 10,
+ GIMP_PARAM_READWRITE));
+ gimp_procedure_add_argument (procedure,
+ gimp_param_spec_string ("name",
+ "name",
+ "The name of the "
+ "brush",
+ FALSE, FALSE, TRUE,
+ "GIMP Brush",
+ 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);
@@ -162,7 +248,6 @@ file_data_init (Gimp *gimp)
TRUE, FALSE, TRUE,
NULL,
GIMP_PARAM_READWRITE));
-
gimp_procedure_add_return_value (procedure,
gimp_param_spec_image_id ("image",
"Image",
diff --git a/plug-ins/common/file-gbr.c b/plug-ins/common/file-gbr.c
index d345ce3d76..a8319508c0 100644
--- a/plug-ins/common/file-gbr.c
+++ b/plug-ins/common/file-gbr.c
@@ -37,9 +37,6 @@
#include <libgimp/gimp.h>
#include <libgimp/gimpui.h>
-#include "app/core/gimpbrush-header.h"
-#include "app/core/gimppattern-header.h"
-
#include "libgimp/stdplugins-intl.h"
@@ -64,11 +61,6 @@ static void run (const gchar *name,
gint *nreturn_vals,
GimpParam **return_vals);
-static gboolean save_image (GFile *file,
- gint32 image_ID,
- gint32 drawable_ID,
- GError **error);
-
static gboolean save_dialog (void);
static void entry_callback (GtkWidget *widget,
gpointer data);
@@ -143,7 +135,6 @@ run (const gchar *name,
GError *error = NULL;
INIT_I18N ();
- gegl_init (NULL, NULL);
run_mode = param[0].data.d_int32;
@@ -246,14 +237,36 @@ run (const gchar *name,
if (status == GIMP_PDB_SUCCESS)
{
- if (save_image (file, image_ID, drawable_ID, &error))
+ GimpParam *save_retvals;
+ gint n_save_retvals;
+
+ save_retvals =
+ gimp_run_procedure ("file-gbr-save-internal",
+ &n_save_retvals,
+ GIMP_PDB_INT32, GIMP_RUN_NONINTERACTIVE,
+ GIMP_PDB_IMAGE, image_ID,
+ GIMP_PDB_DRAWABLE, drawable_ID,
+ GIMP_PDB_STRING, param[3].data.d_string,
+ GIMP_PDB_STRING, param[4].data.d_string,
+ GIMP_PDB_INT32, info.spacing,
+ GIMP_PDB_STRING, info.description,
+ GIMP_PDB_END);
+
+ if (save_retvals[0].data.d_status == GIMP_PDB_SUCCESS)
{
gimp_set_data (SAVE_PROC, &info, sizeof (info));
}
else
{
+ g_set_error (&error, 0, 0,
+ "Running procedure 'file-gbr-save-internal' "
+ "failed: %s",
+ gimp_get_pdb_error ());
+
status = GIMP_PDB_EXECUTION_ERROR;
}
+
+ gimp_destroy_params (save_retvals, n_save_retvals);
}
if (export == GIMP_EXPORT_EXPORT)
@@ -290,157 +303,6 @@ run (const gchar *name,
values[0].data.d_status = status;
}
-static gboolean
-save_image (GFile *file,
- gint32 image_ID,
- gint32 drawable_ID,
- GError **error)
-{
- GOutputStream *output;
- GimpBrushHeader bh;
- guchar *brush_buf;
- GeglBuffer *buffer;
- const Babl *format;
- gint line;
- gint x;
- gint bpp;
- gint file_bpp;
- gint width;
- gint height;
- GimpRGB gray, white;
-
- gimp_rgba_set_uchar (&white, 255, 255, 255, 255);
-
- switch (gimp_drawable_type (drawable_ID))
- {
- case GIMP_GRAY_IMAGE:
- file_bpp = 1;
- format = babl_format ("Y' u8");
- break;
-
- case GIMP_GRAYA_IMAGE:
- file_bpp = 1;
- format = babl_format ("Y'A u8");
- break;
-
- default:
- file_bpp = 4;
- format = babl_format ("R'G'B'A u8");
- break;
- }
-
- bpp = babl_format_get_bytes_per_pixel (format);
-
- gimp_progress_init_printf (_("Exporting '%s'"),
- g_file_get_parse_name (file));
-
- output = G_OUTPUT_STREAM (g_file_replace (file,
- NULL, FALSE, G_FILE_CREATE_NONE,
- NULL, error));
- if (! output)
- return FALSE;
-
- buffer = gimp_drawable_get_buffer (drawable_ID);
-
- width = gimp_drawable_width (drawable_ID);
- height = gimp_drawable_height (drawable_ID);
-
- bh.header_size = g_htonl (sizeof (GimpBrushHeader) +
- strlen (info.description) + 1);
- bh.version = g_htonl (2);
- bh.width = g_htonl (width);
- bh.height = g_htonl (height);
- bh.bytes = g_htonl (file_bpp);
- bh.magic_number = g_htonl (GIMP_BRUSH_MAGIC);
- bh.spacing = g_htonl (info.spacing);
-
- if (! g_output_stream_write_all (output, &bh, sizeof (GimpBrushHeader),
- NULL, NULL, error))
- {
- GCancellable *cancellable = g_cancellable_new ();
-
- g_cancellable_cancel (cancellable);
- g_output_stream_close (output, cancellable, NULL);
- g_object_unref (cancellable);
-
- g_object_unref (output);
- return FALSE;
- }
-
- if (! g_output_stream_write_all (output,
- info.description,
- strlen (info.description) + 1,
- NULL, NULL, error))
- {
- GCancellable *cancellable = g_cancellable_new ();
-
- g_cancellable_cancel (cancellable);
- g_output_stream_close (output, cancellable, NULL);
- g_object_unref (cancellable);
-
- g_object_unref (output);
- return FALSE;
- }
-
- brush_buf = g_new (guchar, width * bpp);
-
- for (line = 0; line < height; line++)
- {
- gegl_buffer_get (buffer, GEGL_RECTANGLE (0, line, width, 1), 1.0,
- format, brush_buf,
- GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
-
- switch (bpp)
- {
- case 1:
- /* invert */
- for (x = 0; x < width; x++)
- brush_buf[x] = 255 - brush_buf[x];
- break;
-
- case 2:
- for (x = 0; x < width; x++)
- {
- /* apply alpha channel */
- gimp_rgba_set_uchar (&gray,
- brush_buf[2 * x],
- brush_buf[2 * x],
- brush_buf[2 * x],
- brush_buf[2 * x + 1]);
- gimp_rgb_composite (&gray, &white, GIMP_RGB_COMPOSITE_BEHIND);
- gimp_rgba_get_uchar (&gray, &brush_buf[x], NULL, NULL, NULL);
- /* invert */
- brush_buf[x] = 255 - brush_buf[x];
- }
- break;
- }
-
- if (! g_output_stream_write_all (output, brush_buf, width * file_bpp,
- NULL, NULL, error))
- {
- GCancellable *cancellable = g_cancellable_new ();
-
- g_cancellable_cancel (cancellable);
- g_output_stream_close (output, cancellable, NULL);
- g_object_unref (cancellable);
-
- g_free (brush_buf);
- g_object_unref (output);
- return FALSE;
- }
-
- gimp_progress_update ((gdouble) line / (gdouble) height);
- }
-
- g_free (brush_buf);
- g_object_unref (buffer);
- g_object_unref (output);
-
- gimp_progress_update (1.0);
-
- return TRUE;
-}
-
static gboolean
save_dialog (void)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]