mirror of
https://gitlab.gnome.org/GNOME/gimp.git
synced 2025-07-04 01:43:24 +00:00
app, plug-ins: move brush pipe saving from the file-gih plug-in to the core
As with .gbr and .pat, only the actual saving code, not the export logic and GUI.
This commit is contained in:
parent
861106a0b3
commit
cc7e07fecb
3 changed files with 249 additions and 378 deletions
|
@ -50,9 +50,9 @@
|
||||||
static GimpImage * file_gih_pipe_to_image (Gimp *gimp,
|
static GimpImage * file_gih_pipe_to_image (Gimp *gimp,
|
||||||
GimpBrushPipe *pipe);
|
GimpBrushPipe *pipe);
|
||||||
static GimpBrushPipe * file_gih_image_to_pipe (GimpImage *image,
|
static GimpBrushPipe * file_gih_image_to_pipe (GimpImage *image,
|
||||||
GimpDrawable *drawable,
|
|
||||||
const gchar *name,
|
const gchar *name,
|
||||||
gdouble spacing);
|
gdouble spacing,
|
||||||
|
const gchar *paramstring);
|
||||||
|
|
||||||
|
|
||||||
/* public functions */
|
/* public functions */
|
||||||
|
@ -125,25 +125,25 @@ file_gih_save_invoker (GimpProcedure *procedure,
|
||||||
{
|
{
|
||||||
GimpValueArray *return_vals;
|
GimpValueArray *return_vals;
|
||||||
GimpImage *image;
|
GimpImage *image;
|
||||||
GimpDrawable *drawable;
|
|
||||||
GimpBrushPipe *pipe;
|
GimpBrushPipe *pipe;
|
||||||
const gchar *uri;
|
const gchar *uri;
|
||||||
const gchar *name;
|
const gchar *name;
|
||||||
|
const gchar *params;
|
||||||
GFile *file;
|
GFile *file;
|
||||||
gint spacing;
|
gint spacing;
|
||||||
gboolean success;
|
gboolean success;
|
||||||
|
|
||||||
gimp_set_busy (gimp);
|
gimp_set_busy (gimp);
|
||||||
|
|
||||||
image = gimp_value_get_image (gimp_value_array_index (args, 1), 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));
|
||||||
uri = g_value_get_string (gimp_value_array_index (args, 3));
|
spacing = g_value_get_int (gimp_value_array_index (args, 5));
|
||||||
spacing = g_value_get_int (gimp_value_array_index (args, 5));
|
name = g_value_get_string (gimp_value_array_index (args, 6));
|
||||||
name = g_value_get_string (gimp_value_array_index (args, 6));
|
params = g_value_get_string (gimp_value_array_index (args, 7));
|
||||||
|
|
||||||
file = g_file_new_for_uri (uri);
|
file = g_file_new_for_uri (uri);
|
||||||
|
|
||||||
pipe = file_gih_image_to_pipe (image, drawable, name, spacing);
|
pipe = file_gih_image_to_pipe (image, name, spacing, params);
|
||||||
|
|
||||||
gimp_data_set_file (GIMP_DATA (pipe), file, TRUE, TRUE);
|
gimp_data_set_file (GIMP_DATA (pipe), file, TRUE, TRUE);
|
||||||
|
|
||||||
|
@ -235,109 +235,102 @@ file_gih_pipe_to_image (Gimp *gimp,
|
||||||
}
|
}
|
||||||
|
|
||||||
static GimpBrushPipe *
|
static GimpBrushPipe *
|
||||||
file_gih_image_to_pipe (GimpImage *image,
|
file_gih_image_to_pipe (GimpImage *image,
|
||||||
GimpDrawable *drawable,
|
const gchar *name,
|
||||||
const gchar *name,
|
gdouble spacing,
|
||||||
gdouble spacing)
|
const gchar *paramstring)
|
||||||
{
|
{
|
||||||
#if 0
|
GimpBrushPipe *pipe;
|
||||||
GimpBrush *brush;
|
GimpPixPipeParams params;
|
||||||
GeglBuffer *buffer;
|
GList *layers;
|
||||||
GimpTempBuf *mask;
|
GList *list;
|
||||||
GimpTempBuf *pixmap = NULL;
|
GList *brushes = NULL;
|
||||||
gint width;
|
gint image_width;
|
||||||
gint height;
|
gint image_height;
|
||||||
|
gint i;
|
||||||
|
|
||||||
buffer = gimp_drawable_get_buffer (drawable);
|
pipe = g_object_new (GIMP_TYPE_BRUSH_PIPE,
|
||||||
width = gimp_item_get_width (GIMP_ITEM (drawable));
|
"name", name,
|
||||||
height = gimp_item_get_height (GIMP_ITEM (drawable));
|
"mime-type", "image/x-gimp-gih",
|
||||||
|
"spacing", spacing,
|
||||||
|
NULL);
|
||||||
|
|
||||||
brush = g_object_new (GIMP_TYPE_BRUSH,
|
gimp_pixpipe_params_init (¶ms);
|
||||||
"name", name,
|
gimp_pixpipe_params_parse (paramstring, ¶ms);
|
||||||
"mime-type", "image/x-gimp-gih",
|
|
||||||
"spacing", spacing,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
mask = gimp_temp_buf_new (width, height, babl_format ("Y u8"));
|
image_width = gimp_image_get_width (image);
|
||||||
|
image_height = gimp_image_get_height (image);
|
||||||
|
|
||||||
if (gimp_drawable_is_gray (drawable))
|
layers = gimp_image_get_layer_iter (image);
|
||||||
|
|
||||||
|
for (list = layers; list; list = g_list_next (list))
|
||||||
{
|
{
|
||||||
guchar *m = gimp_temp_buf_get_data (mask);
|
GimpLayer *layer = list->data;
|
||||||
gint i;
|
gint width;
|
||||||
|
gint height;
|
||||||
|
gint offset_x;
|
||||||
|
gint offset_y;
|
||||||
|
gint row;
|
||||||
|
|
||||||
if (gimp_drawable_has_alpha (drawable))
|
width = gimp_item_get_width (GIMP_ITEM (layer));
|
||||||
|
height = gimp_item_get_height (GIMP_ITEM (layer));
|
||||||
|
|
||||||
|
gimp_item_get_offset (GIMP_ITEM (layer), &offset_x, &offset_y);
|
||||||
|
|
||||||
|
for (row = 0; row < params.rows; row++)
|
||||||
{
|
{
|
||||||
GeglBufferIterator *iter;
|
gint y, ynext;
|
||||||
GimpRGB white;
|
gint thisy, thish;
|
||||||
|
gint col;
|
||||||
|
|
||||||
gimp_rgba_set_uchar (&white, 255, 255, 255, 255);
|
y = (row * image_height) / params.rows;
|
||||||
|
ynext = ((row + 1) * image_height / params.rows);
|
||||||
|
|
||||||
iter = gegl_buffer_iterator_new (buffer, NULL, 0,
|
/* Assume layer is offset to positive direction in x and y.
|
||||||
babl_format ("Y'A u8"),
|
* That's reasonable, as otherwise all of the layer
|
||||||
GEGL_ACCESS_READ, GEGL_ABYSS_NONE,
|
* won't be visible.
|
||||||
1);
|
* thisy and thisx are in the drawable's coordinate space.
|
||||||
|
*/
|
||||||
|
thisy = MAX (0, y - offset_y);
|
||||||
|
thish = (ynext - offset_y) - thisy;
|
||||||
|
thish = MIN (thish, height - thisy);
|
||||||
|
|
||||||
while (gegl_buffer_iterator_next (iter))
|
for (col = 0; col < params.cols; col++)
|
||||||
{
|
{
|
||||||
guint8 *data = (guint8 *) iter->items[0].data;
|
GimpBrush *brush;
|
||||||
gint j;
|
gint x, xnext;
|
||||||
|
gint thisx, thisw;
|
||||||
|
|
||||||
for (j = 0; j < iter->length; j++)
|
x = (col * image_width / params.cols);
|
||||||
{
|
xnext = ((col + 1) * image_width / params.cols);
|
||||||
GimpRGB gray;
|
thisx = MAX (0, x - offset_x);
|
||||||
gint x, y;
|
thisw = (xnext - offset_x) - thisx;
|
||||||
gint dest;
|
thisw = MIN (thisw, width - thisx);
|
||||||
|
|
||||||
gimp_rgba_set_uchar (&gray,
|
brush = file_gbr_drawable_to_brush (GIMP_DRAWABLE (layer),
|
||||||
data[0], data[0], data[0],
|
GEGL_RECTANGLE (thisx, thisy,
|
||||||
data[1]);
|
thisw, thish),
|
||||||
|
gimp_object_get_name (layer),
|
||||||
|
spacing);
|
||||||
|
|
||||||
gimp_rgb_composite (&gray, &white,
|
brushes = g_list_prepend (brushes, brush);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
brushes = g_list_reverse (brushes);
|
||||||
|
|
||||||
brush->priv->mask = mask;
|
pipe->n_brushes = g_list_length (brushes);
|
||||||
brush->priv->pixmap = pixmap;
|
pipe->brushes = g_new0 (GimpBrush *, pipe->n_brushes);
|
||||||
|
|
||||||
return brush;
|
for (list = brushes, i = 0; list; list = g_list_next (list), i++)
|
||||||
#endif
|
pipe->brushes[i] = list->data;
|
||||||
|
|
||||||
return NULL;
|
g_list_free (brushes);
|
||||||
|
|
||||||
|
gimp_pixpipe_params_free (¶ms);
|
||||||
|
|
||||||
|
gimp_brush_pipe_set_params (pipe, paramstring);
|
||||||
|
|
||||||
|
return pipe;
|
||||||
}
|
}
|
||||||
|
|
|
@ -222,11 +222,9 @@ file_data_init (Gimp *gimp)
|
||||||
"Loads GIMP animated brushes",
|
"Loads GIMP animated brushes",
|
||||||
"This procedure loads a GIMP brush "
|
"This procedure loads a GIMP brush "
|
||||||
"pipe as an image.",
|
"pipe as an image.",
|
||||||
"Jens Lautenbacher, Sven Neumann, "
|
"Tor Lillqvist, Michael Natterer",
|
||||||
"Michael Natterer",
|
"Tor Lillqvist, Michael Natterer",
|
||||||
"Jens Lautenbacher, Sven Neumann, "
|
"1999-2019",
|
||||||
"Michael Natterer",
|
|
||||||
"1995-2019",
|
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
gimp_procedure_add_argument (procedure,
|
gimp_procedure_add_argument (procedure,
|
||||||
|
@ -262,6 +260,99 @@ file_data_init (Gimp *gimp)
|
||||||
gimp_plug_in_manager_add_procedure (gimp->plug_in_manager, proc);
|
gimp_plug_in_manager_add_procedure (gimp->plug_in_manager, proc);
|
||||||
g_object_unref (procedure);
|
g_object_unref (procedure);
|
||||||
|
|
||||||
|
/* file-gih-save-internal */
|
||||||
|
file = g_file_new_for_path ("file-gih-save-internal");
|
||||||
|
procedure = gimp_plug_in_procedure_new (GIMP_PLUGIN, file);
|
||||||
|
g_object_unref (file);
|
||||||
|
|
||||||
|
procedure->proc_type = GIMP_INTERNAL;
|
||||||
|
procedure->marshal_func = file_gih_save_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);
|
||||||
|
|
||||||
|
#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, "gih", "", NULL);
|
||||||
|
gimp_plug_in_procedure_set_mime_types (proc, "image/x-gimp-gih");
|
||||||
|
gimp_plug_in_procedure_set_handles_uri (proc);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
gimp_object_set_static_name (GIMP_OBJECT (procedure),
|
||||||
|
"file-gih-save-internal");
|
||||||
|
gimp_procedure_set_static_strings (procedure,
|
||||||
|
"file-gih-save-internal",
|
||||||
|
"Exports Gimp animated brush file (.gih)",
|
||||||
|
"Exports Gimp animated brush file (.gih)",
|
||||||
|
"Tor Lillqvist, Michael Natterer",
|
||||||
|
"Tor Lillqvist, Michael Natterer",
|
||||||
|
"1999-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_procedure_add_argument (procedure,
|
||||||
|
gimp_param_spec_string ("params",
|
||||||
|
"params",
|
||||||
|
"The pipe's parameters",
|
||||||
|
FALSE, FALSE, TRUE,
|
||||||
|
NULL,
|
||||||
|
GIMP_PARAM_READWRITE));
|
||||||
|
|
||||||
|
gimp_plug_in_manager_add_procedure (gimp->plug_in_manager, proc);
|
||||||
|
g_object_unref (procedure);
|
||||||
|
|
||||||
/* file-pat-load */
|
/* file-pat-load */
|
||||||
file = g_file_new_for_path ("file-pat-load");
|
file = g_file_new_for_path ("file-pat-load");
|
||||||
procedure = gimp_plug_in_procedure_new (GIMP_PLUGIN, file);
|
procedure = gimp_plug_in_procedure_new (GIMP_PLUGIN, file);
|
||||||
|
|
|
@ -41,15 +41,10 @@
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include <libgimp/gimp.h>
|
#include <libgimp/gimp.h>
|
||||||
#include <libgimp/gimpui.h>
|
#include <libgimp/gimpui.h>
|
||||||
#include <libgimpbase/gimpparasiteio.h>
|
#include <libgimpbase/gimpparasiteio.h>
|
||||||
|
|
||||||
#include "app/core/gimpbrush-header.h"
|
|
||||||
#include "app/core/gimppattern-header.h"
|
|
||||||
|
|
||||||
#include "libgimp/stdplugins-intl.h"
|
#include "libgimp/stdplugins-intl.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -88,26 +83,18 @@ typedef struct
|
||||||
|
|
||||||
/* local function prototypes */
|
/* local function prototypes */
|
||||||
|
|
||||||
static void query (void);
|
static void query (void);
|
||||||
static void run (const gchar *name,
|
static void run (const gchar *name,
|
||||||
gint nparams,
|
gint nparams,
|
||||||
const GimpParam *param,
|
const GimpParam *param,
|
||||||
gint *nreturn_vals,
|
gint *nreturn_vals,
|
||||||
GimpParam **return_vals);
|
GimpParam **return_vals);
|
||||||
|
|
||||||
static gboolean gih_save_dialog (gint32 image_ID);
|
static gboolean gih_save_dialog (gint32 image_ID);
|
||||||
static gboolean gih_save_one_brush (GOutputStream *output,
|
|
||||||
gint32 drawable_ID,
|
|
||||||
GeglRectangle *rect,
|
|
||||||
const gchar *name,
|
|
||||||
GError **error);
|
|
||||||
static gboolean gih_save_image (GFile *file,
|
|
||||||
gint32 image_ID,
|
|
||||||
gint32 orig_image_ID,
|
|
||||||
gint32 drawable_ID,
|
|
||||||
GError **error);
|
|
||||||
|
|
||||||
|
|
||||||
|
/* private variables */
|
||||||
|
|
||||||
const GimpPlugInInfo PLUG_IN_INFO =
|
const GimpPlugInInfo PLUG_IN_INFO =
|
||||||
{
|
{
|
||||||
NULL, /* init_proc */
|
NULL, /* init_proc */
|
||||||
|
@ -116,9 +103,6 @@ const GimpPlugInInfo PLUG_IN_INFO =
|
||||||
run, /* run_proc */
|
run, /* run_proc */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* private variables */
|
|
||||||
|
|
||||||
static BrushInfo info =
|
static BrushInfo info =
|
||||||
{
|
{
|
||||||
"GIMP Brush Pipe",
|
"GIMP Brush Pipe",
|
||||||
|
@ -198,12 +182,11 @@ run (const gchar *name,
|
||||||
GimpPDBStatusType status = GIMP_PDB_SUCCESS;
|
GimpPDBStatusType status = GIMP_PDB_SUCCESS;
|
||||||
gint32 image_ID;
|
gint32 image_ID;
|
||||||
gint32 drawable_ID;
|
gint32 drawable_ID;
|
||||||
gint i;
|
|
||||||
GimpExportReturn export = GIMP_EXPORT_CANCEL;
|
GimpExportReturn export = GIMP_EXPORT_CANCEL;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
gint i;
|
||||||
|
|
||||||
INIT_I18N();
|
INIT_I18N();
|
||||||
gegl_init (NULL, NULL);
|
|
||||||
|
|
||||||
run_mode = param[0].data.d_int32;
|
run_mode = param[0].data.d_int32;
|
||||||
|
|
||||||
|
@ -216,8 +199,7 @@ run (const gchar *name,
|
||||||
if (strcmp (name, SAVE_PROC) == 0)
|
if (strcmp (name, SAVE_PROC) == 0)
|
||||||
{
|
{
|
||||||
GFile *file;
|
GFile *file;
|
||||||
GimpParasite *name_parasite;
|
GimpParasite *parasite;
|
||||||
GimpParasite *pipe_parasite;
|
|
||||||
gint32 orig_image_ID;
|
gint32 orig_image_ID;
|
||||||
|
|
||||||
image_ID = param[1].data.d_int32;
|
image_ID = param[1].data.d_int32;
|
||||||
|
@ -247,17 +229,17 @@ run (const gchar *name,
|
||||||
/* Possibly retrieve data */
|
/* Possibly retrieve data */
|
||||||
gimp_get_data (SAVE_PROC, &info);
|
gimp_get_data (SAVE_PROC, &info);
|
||||||
|
|
||||||
name_parasite = gimp_image_get_parasite (orig_image_ID,
|
parasite = gimp_image_get_parasite (orig_image_ID,
|
||||||
"gimp-brush-pipe-name");
|
"gimp-brush-pipe-name");
|
||||||
if (name_parasite)
|
if (parasite)
|
||||||
{
|
{
|
||||||
strncpy (info.description,
|
strncpy (info.description,
|
||||||
gimp_parasite_data (name_parasite),
|
gimp_parasite_data (parasite),
|
||||||
MIN (sizeof (info.description),
|
MIN (sizeof (info.description),
|
||||||
gimp_parasite_data_size (name_parasite)));
|
gimp_parasite_data_size (parasite)));
|
||||||
info.description[sizeof (info.description) - 1] = '\0';
|
info.description[sizeof (info.description) - 1] = '\0';
|
||||||
|
|
||||||
gimp_parasite_free (name_parasite);
|
gimp_parasite_free (parasite);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -292,13 +274,13 @@ run (const gchar *name,
|
||||||
gihparams.cellwidth = gimp_image_width (image_ID) / gihparams.cols;
|
gihparams.cellwidth = gimp_image_width (image_ID) / gihparams.cols;
|
||||||
gihparams.cellheight = gimp_image_height (image_ID) / gihparams.rows;
|
gihparams.cellheight = gimp_image_height (image_ID) / gihparams.rows;
|
||||||
|
|
||||||
pipe_parasite = gimp_image_get_parasite (orig_image_ID,
|
parasite = gimp_image_get_parasite (orig_image_ID,
|
||||||
"gimp-brush-pipe-parameters");
|
"gimp-brush-pipe-parameters");
|
||||||
if (pipe_parasite)
|
if (parasite)
|
||||||
{
|
{
|
||||||
gimp_pixpipe_params_parse (gimp_parasite_data (pipe_parasite),
|
gimp_pixpipe_params_parse (gimp_parasite_data (parasite),
|
||||||
&gihparams);
|
&gihparams);
|
||||||
gimp_parasite_free (pipe_parasite);
|
gimp_parasite_free (parasite);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Force default rank to same as number of cells if there is
|
/* Force default rank to same as number of cells if there is
|
||||||
|
@ -347,28 +329,67 @@ run (const gchar *name,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GIMP_RUN_WITH_LAST_VALS:
|
case GIMP_RUN_WITH_LAST_VALS:
|
||||||
pipe_parasite = gimp_image_get_parasite (orig_image_ID,
|
parasite = gimp_image_get_parasite (orig_image_ID,
|
||||||
"gimp-brush-pipe-parameters");
|
"gimp-brush-pipe-parameters");
|
||||||
if (pipe_parasite)
|
if (parasite)
|
||||||
{
|
{
|
||||||
gimp_pixpipe_params_parse (gimp_parasite_data (pipe_parasite),
|
gimp_pixpipe_params_parse (gimp_parasite_data (parasite),
|
||||||
&gihparams);
|
&gihparams);
|
||||||
gimp_parasite_free (pipe_parasite);
|
gimp_parasite_free (parasite);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status == GIMP_PDB_SUCCESS)
|
if (status == GIMP_PDB_SUCCESS)
|
||||||
{
|
{
|
||||||
if (gih_save_image (file, image_ID, orig_image_ID, drawable_ID,
|
GimpParam *save_retvals;
|
||||||
&error))
|
gint n_save_retvals;
|
||||||
|
gchar *paramstring;
|
||||||
|
|
||||||
|
paramstring = gimp_pixpipe_params_build (&gihparams);
|
||||||
|
|
||||||
|
save_retvals =
|
||||||
|
gimp_run_procedure ("file-gih-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_STRING, paramstring,
|
||||||
|
GIMP_PDB_END);
|
||||||
|
|
||||||
|
if (save_retvals[0].data.d_status == GIMP_PDB_SUCCESS)
|
||||||
{
|
{
|
||||||
gimp_set_data (SAVE_PROC, &info, sizeof (info));
|
gimp_set_data (SAVE_PROC, &info, sizeof (info));
|
||||||
|
|
||||||
|
parasite = gimp_parasite_new ("gimp-brush-pipe-name",
|
||||||
|
GIMP_PARASITE_PERSISTENT,
|
||||||
|
strlen (info.description) + 1,
|
||||||
|
info.description);
|
||||||
|
gimp_image_attach_parasite (orig_image_ID, parasite);
|
||||||
|
gimp_parasite_free (parasite);
|
||||||
|
|
||||||
|
parasite = gimp_parasite_new ("gimp-brush-pipe-parameters",
|
||||||
|
GIMP_PARASITE_PERSISTENT,
|
||||||
|
strlen (paramstring) + 1,
|
||||||
|
paramstring);
|
||||||
|
gimp_image_attach_parasite (orig_image_ID, parasite);
|
||||||
|
gimp_parasite_free (parasite);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
g_set_error (&error, 0, 0,
|
||||||
|
"Running procedure 'file-gih-save-internal' "
|
||||||
|
"failed: %s",
|
||||||
|
gimp_get_pdb_error ());
|
||||||
|
|
||||||
status = GIMP_PDB_EXECUTION_ERROR;
|
status = GIMP_PDB_EXECUTION_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_free (paramstring);
|
||||||
}
|
}
|
||||||
|
|
||||||
gimp_pixpipe_params_free (&gihparams);
|
gimp_pixpipe_params_free (&gihparams);
|
||||||
|
@ -771,237 +792,3 @@ gih_save_dialog (gint32 image_ID)
|
||||||
|
|
||||||
return run;
|
return run;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
gih_save_one_brush (GOutputStream *output,
|
|
||||||
gint32 drawable_ID,
|
|
||||||
GeglRectangle *rect,
|
|
||||||
const gchar *name,
|
|
||||||
GError **error)
|
|
||||||
{
|
|
||||||
GeglBuffer *buffer;
|
|
||||||
const Babl *format;
|
|
||||||
GimpBrushHeader bh;
|
|
||||||
guchar *data;
|
|
||||||
GimpImageType drawable_type;
|
|
||||||
gint bpp;
|
|
||||||
gint y;
|
|
||||||
|
|
||||||
buffer = gimp_drawable_get_buffer (drawable_ID);
|
|
||||||
|
|
||||||
drawable_type = gimp_drawable_type (drawable_ID);
|
|
||||||
|
|
||||||
if (! name)
|
|
||||||
name = _("Unnamed");
|
|
||||||
|
|
||||||
switch (drawable_type)
|
|
||||||
{
|
|
||||||
case GIMP_GRAY_IMAGE:
|
|
||||||
case GIMP_GRAYA_IMAGE: /* alpha channel is ignored */
|
|
||||||
format = babl_format ("Y' u8");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GIMP_RGB_IMAGE: /* alpha channel is added */
|
|
||||||
case GIMP_RGBA_IMAGE:
|
|
||||||
format = babl_format ("R'G'B'A u8");
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
g_return_val_if_reached (FALSE);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
bpp = babl_format_get_bytes_per_pixel (format);
|
|
||||||
|
|
||||||
bh.header_size = g_htonl (sizeof (bh) + strlen (name) + 1);
|
|
||||||
bh.version = g_htonl (2);
|
|
||||||
bh.width = g_htonl (rect->width);
|
|
||||||
bh.height = g_htonl (rect->height);
|
|
||||||
bh.bytes = g_htonl (bpp);
|
|
||||||
bh.magic_number = g_htonl (GIMP_BRUSH_MAGIC);
|
|
||||||
bh.spacing = g_htonl (info.spacing);
|
|
||||||
|
|
||||||
if (! g_output_stream_write_all (output, &bh, sizeof (bh),
|
|
||||||
NULL, NULL, error))
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! g_output_stream_write_all (output, name, strlen (name) + 1,
|
|
||||||
NULL, NULL, error))
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
data = g_malloc (rect->width * bpp);
|
|
||||||
|
|
||||||
for (y = 0; y < rect->height; y++)
|
|
||||||
{
|
|
||||||
gint x;
|
|
||||||
|
|
||||||
gegl_buffer_get (buffer,
|
|
||||||
GEGL_RECTANGLE (rect->x, rect->y + y, rect->width, 1),
|
|
||||||
1.0, format, data,
|
|
||||||
GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
|
|
||||||
|
|
||||||
switch (bpp)
|
|
||||||
{
|
|
||||||
case 1: /* GRAY */
|
|
||||||
for (x = 0; x < rect->width; x++)
|
|
||||||
data[x] = 255 - data[x];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! g_output_stream_write_all (output, data, rect->width * bpp,
|
|
||||||
NULL, NULL, error))
|
|
||||||
{
|
|
||||||
g_free (data);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
g_free (data);
|
|
||||||
g_object_unref (buffer);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
gih_save_image (GFile *file,
|
|
||||||
gint32 image_ID,
|
|
||||||
gint32 orig_image_ID,
|
|
||||||
gint32 drawable_ID,
|
|
||||||
GError **error)
|
|
||||||
{
|
|
||||||
GOutputStream *output;
|
|
||||||
GimpParasite *name_parasite;
|
|
||||||
GimpParasite *pipe_parasite;
|
|
||||||
gchar *header;
|
|
||||||
gchar *parstring;
|
|
||||||
gint32 *layer_ID;
|
|
||||||
gint nlayers, layer;
|
|
||||||
gint row, col;
|
|
||||||
gint imagew, imageh;
|
|
||||||
gint offsetx, offsety;
|
|
||||||
gint k;
|
|
||||||
|
|
||||||
if (gihparams.ncells < 1)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
imagew = gimp_image_width (image_ID);
|
|
||||||
imageh = gimp_image_height (image_ID);
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
parstring = gimp_pixpipe_params_build (&gihparams);
|
|
||||||
|
|
||||||
header = g_strdup_printf ("%s\n%d %s\n",
|
|
||||||
info.description, gihparams.ncells, parstring);
|
|
||||||
|
|
||||||
if (! g_output_stream_write_all (output, header, strlen (header),
|
|
||||||
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 (parstring);
|
|
||||||
g_free (header);
|
|
||||||
g_object_unref (output);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_free (header);
|
|
||||||
|
|
||||||
name_parasite = gimp_parasite_new ("gimp-brush-pipe-name",
|
|
||||||
GIMP_PARASITE_PERSISTENT,
|
|
||||||
strlen (info.description) + 1,
|
|
||||||
info.description);
|
|
||||||
gimp_image_attach_parasite (orig_image_ID, name_parasite);
|
|
||||||
gimp_parasite_free (name_parasite);
|
|
||||||
|
|
||||||
pipe_parasite = gimp_parasite_new ("gimp-brush-pipe-parameters",
|
|
||||||
GIMP_PARASITE_PERSISTENT,
|
|
||||||
strlen (parstring) + 1, parstring);
|
|
||||||
gimp_image_attach_parasite (orig_image_ID, pipe_parasite);
|
|
||||||
gimp_parasite_free (pipe_parasite);
|
|
||||||
|
|
||||||
g_free (parstring);
|
|
||||||
|
|
||||||
layer_ID = gimp_image_get_layers (image_ID, &nlayers);
|
|
||||||
|
|
||||||
for (layer = 0, k = 0; layer < nlayers; layer++)
|
|
||||||
{
|
|
||||||
gchar *name = gimp_item_get_name (layer_ID[layer]);
|
|
||||||
gint width = gimp_drawable_width (layer_ID[layer]);
|
|
||||||
gint height = gimp_drawable_height (layer_ID[layer]);
|
|
||||||
|
|
||||||
gimp_drawable_offsets (layer_ID[layer], &offsetx, &offsety);
|
|
||||||
|
|
||||||
for (row = 0; row < gihparams.rows; row++)
|
|
||||||
{
|
|
||||||
gint y, ynext;
|
|
||||||
gint thisy, thish;
|
|
||||||
|
|
||||||
y = (row * imageh) / gihparams.rows;
|
|
||||||
ynext = ((row + 1) * imageh / gihparams.rows);
|
|
||||||
|
|
||||||
/* Assume layer is offset to positive direction in x and y.
|
|
||||||
* That's reasonable, as otherwise all of the layer
|
|
||||||
* won't be visible.
|
|
||||||
* thisy and thisx are in the drawable's coordinate space.
|
|
||||||
*/
|
|
||||||
thisy = MAX (0, y - offsety);
|
|
||||||
thish = (ynext - offsety) - thisy;
|
|
||||||
thish = MIN (thish, height - thisy);
|
|
||||||
|
|
||||||
for (col = 0; col < gihparams.cols; col++)
|
|
||||||
{
|
|
||||||
gint x, xnext;
|
|
||||||
gint thisx, thisw;
|
|
||||||
|
|
||||||
x = (col * imagew / gihparams.cols);
|
|
||||||
xnext = ((col + 1) * imagew / gihparams.cols);
|
|
||||||
thisx = MAX (0, x - offsetx);
|
|
||||||
thisw = (xnext - offsetx) - thisx;
|
|
||||||
thisw = MIN (thisw, width - thisx);
|
|
||||||
|
|
||||||
if (! gih_save_one_brush (output, layer_ID[layer],
|
|
||||||
GEGL_RECTANGLE (thisx, thisy,
|
|
||||||
thisw, thish),
|
|
||||||
name, 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
k++;
|
|
||||||
gimp_progress_update ((gdouble) k / gihparams.ncells);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
g_free (name);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
g_free (layer_ID);
|
|
||||||
g_object_unref (output);
|
|
||||||
|
|
||||||
gimp_progress_update (1.0);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue