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,
|
||||
GimpBrushPipe *pipe);
|
||||
static GimpBrushPipe * file_gih_image_to_pipe (GimpImage *image,
|
||||
GimpDrawable *drawable,
|
||||
const gchar *name,
|
||||
gdouble spacing);
|
||||
gdouble spacing,
|
||||
const gchar *paramstring);
|
||||
|
||||
|
||||
/* public functions */
|
||||
|
@ -125,10 +125,10 @@ file_gih_save_invoker (GimpProcedure *procedure,
|
|||
{
|
||||
GimpValueArray *return_vals;
|
||||
GimpImage *image;
|
||||
GimpDrawable *drawable;
|
||||
GimpBrushPipe *pipe;
|
||||
const gchar *uri;
|
||||
const gchar *name;
|
||||
const gchar *params;
|
||||
GFile *file;
|
||||
gint spacing;
|
||||
gboolean success;
|
||||
|
@ -136,14 +136,14 @@ file_gih_save_invoker (GimpProcedure *procedure,
|
|||
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));
|
||||
params = g_value_get_string (gimp_value_array_index (args, 7));
|
||||
|
||||
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);
|
||||
|
||||
|
@ -236,108 +236,101 @@ file_gih_pipe_to_image (Gimp *gimp,
|
|||
|
||||
static GimpBrushPipe *
|
||||
file_gih_image_to_pipe (GimpImage *image,
|
||||
GimpDrawable *drawable,
|
||||
const gchar *name,
|
||||
gdouble spacing)
|
||||
gdouble spacing,
|
||||
const gchar *paramstring)
|
||||
{
|
||||
#if 0
|
||||
GimpBrush *brush;
|
||||
GeglBuffer *buffer;
|
||||
GimpTempBuf *mask;
|
||||
GimpTempBuf *pixmap = NULL;
|
||||
gint width;
|
||||
gint height;
|
||||
GimpBrushPipe *pipe;
|
||||
GimpPixPipeParams params;
|
||||
GList *layers;
|
||||
GList *list;
|
||||
GList *brushes = NULL;
|
||||
gint image_width;
|
||||
gint image_height;
|
||||
gint i;
|
||||
|
||||
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,
|
||||
pipe = g_object_new (GIMP_TYPE_BRUSH_PIPE,
|
||||
"name", name,
|
||||
"mime-type", "image/x-gimp-gih",
|
||||
"spacing", spacing,
|
||||
NULL);
|
||||
|
||||
mask = gimp_temp_buf_new (width, height, babl_format ("Y u8"));
|
||||
gimp_pixpipe_params_init (¶ms);
|
||||
gimp_pixpipe_params_parse (paramstring, ¶ms);
|
||||
|
||||
if (gimp_drawable_is_gray (drawable))
|
||||
image_width = gimp_image_get_width (image);
|
||||
image_height = gimp_image_get_height (image);
|
||||
|
||||
layers = gimp_image_get_layer_iter (image);
|
||||
|
||||
for (list = layers; list; list = g_list_next (list))
|
||||
{
|
||||
guchar *m = gimp_temp_buf_get_data (mask);
|
||||
gint i;
|
||||
GimpLayer *layer = list->data;
|
||||
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;
|
||||
GimpRGB white;
|
||||
gint y, ynext;
|
||||
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,
|
||||
babl_format ("Y'A u8"),
|
||||
GEGL_ACCESS_READ, GEGL_ABYSS_NONE,
|
||||
1);
|
||||
/* 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 - 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;
|
||||
gint j;
|
||||
GimpBrush *brush;
|
||||
gint x, xnext;
|
||||
gint thisx, thisw;
|
||||
|
||||
for (j = 0; j < iter->length; j++)
|
||||
{
|
||||
GimpRGB gray;
|
||||
gint x, y;
|
||||
gint dest;
|
||||
x = (col * image_width / params.cols);
|
||||
xnext = ((col + 1) * image_width / params.cols);
|
||||
thisx = MAX (0, x - offset_x);
|
||||
thisw = (xnext - offset_x) - thisx;
|
||||
thisw = MIN (thisw, width - thisx);
|
||||
|
||||
gimp_rgba_set_uchar (&gray,
|
||||
data[0], data[0], data[0],
|
||||
data[1]);
|
||||
brush = file_gbr_drawable_to_brush (GIMP_DRAWABLE (layer),
|
||||
GEGL_RECTANGLE (thisx, thisy,
|
||||
thisw, thish),
|
||||
gimp_object_get_name (layer),
|
||||
spacing);
|
||||
|
||||
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;
|
||||
brushes = g_list_prepend (brushes, brush);
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
|
||||
brushes = g_list_reverse (brushes);
|
||||
|
||||
pipe->n_brushes = g_list_length (brushes);
|
||||
pipe->brushes = g_new0 (GimpBrush *, pipe->n_brushes);
|
||||
|
||||
for (list = brushes, i = 0; list; list = g_list_next (list), i++)
|
||||
pipe->brushes[i] = list->data;
|
||||
|
||||
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",
|
||||
"This procedure loads a GIMP brush "
|
||||
"pipe as an image.",
|
||||
"Jens Lautenbacher, Sven Neumann, "
|
||||
"Michael Natterer",
|
||||
"Jens Lautenbacher, Sven Neumann, "
|
||||
"Michael Natterer",
|
||||
"1995-2019",
|
||||
"Tor Lillqvist, Michael Natterer",
|
||||
"Tor Lillqvist, Michael Natterer",
|
||||
"1999-2019",
|
||||
NULL);
|
||||
|
||||
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);
|
||||
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 = g_file_new_for_path ("file-pat-load");
|
||||
procedure = gimp_plug_in_procedure_new (GIMP_PLUGIN, file);
|
||||
|
|
|
@ -41,15 +41,10 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <libgimp/gimp.h>
|
||||
#include <libgimp/gimpui.h>
|
||||
#include <libgimpbase/gimpparasiteio.h>
|
||||
|
||||
#include "app/core/gimpbrush-header.h"
|
||||
#include "app/core/gimppattern-header.h"
|
||||
|
||||
#include "libgimp/stdplugins-intl.h"
|
||||
|
||||
|
||||
|
@ -96,18 +91,10 @@ static void run (const gchar *name,
|
|||
GimpParam **return_vals);
|
||||
|
||||
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 =
|
||||
{
|
||||
NULL, /* init_proc */
|
||||
|
@ -116,9 +103,6 @@ const GimpPlugInInfo PLUG_IN_INFO =
|
|||
run, /* run_proc */
|
||||
};
|
||||
|
||||
|
||||
/* private variables */
|
||||
|
||||
static BrushInfo info =
|
||||
{
|
||||
"GIMP Brush Pipe",
|
||||
|
@ -198,12 +182,11 @@ run (const gchar *name,
|
|||
GimpPDBStatusType status = GIMP_PDB_SUCCESS;
|
||||
gint32 image_ID;
|
||||
gint32 drawable_ID;
|
||||
gint i;
|
||||
GimpExportReturn export = GIMP_EXPORT_CANCEL;
|
||||
GError *error = NULL;
|
||||
gint i;
|
||||
|
||||
INIT_I18N();
|
||||
gegl_init (NULL, NULL);
|
||||
|
||||
run_mode = param[0].data.d_int32;
|
||||
|
||||
|
@ -216,8 +199,7 @@ run (const gchar *name,
|
|||
if (strcmp (name, SAVE_PROC) == 0)
|
||||
{
|
||||
GFile *file;
|
||||
GimpParasite *name_parasite;
|
||||
GimpParasite *pipe_parasite;
|
||||
GimpParasite *parasite;
|
||||
gint32 orig_image_ID;
|
||||
|
||||
image_ID = param[1].data.d_int32;
|
||||
|
@ -247,17 +229,17 @@ run (const gchar *name,
|
|||
/* Possibly retrieve data */
|
||||
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");
|
||||
if (name_parasite)
|
||||
if (parasite)
|
||||
{
|
||||
strncpy (info.description,
|
||||
gimp_parasite_data (name_parasite),
|
||||
gimp_parasite_data (parasite),
|
||||
MIN (sizeof (info.description),
|
||||
gimp_parasite_data_size (name_parasite)));
|
||||
gimp_parasite_data_size (parasite)));
|
||||
info.description[sizeof (info.description) - 1] = '\0';
|
||||
|
||||
gimp_parasite_free (name_parasite);
|
||||
gimp_parasite_free (parasite);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -292,13 +274,13 @@ run (const gchar *name,
|
|||
gihparams.cellwidth = gimp_image_width (image_ID) / gihparams.cols;
|
||||
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");
|
||||
if (pipe_parasite)
|
||||
if (parasite)
|
||||
{
|
||||
gimp_pixpipe_params_parse (gimp_parasite_data (pipe_parasite),
|
||||
gimp_pixpipe_params_parse (gimp_parasite_data (parasite),
|
||||
&gihparams);
|
||||
gimp_parasite_free (pipe_parasite);
|
||||
gimp_parasite_free (parasite);
|
||||
}
|
||||
|
||||
/* Force default rank to same as number of cells if there is
|
||||
|
@ -347,28 +329,67 @@ run (const gchar *name,
|
|||
break;
|
||||
|
||||
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");
|
||||
if (pipe_parasite)
|
||||
if (parasite)
|
||||
{
|
||||
gimp_pixpipe_params_parse (gimp_parasite_data (pipe_parasite),
|
||||
gimp_pixpipe_params_parse (gimp_parasite_data (parasite),
|
||||
&gihparams);
|
||||
gimp_parasite_free (pipe_parasite);
|
||||
gimp_parasite_free (parasite);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (status == GIMP_PDB_SUCCESS)
|
||||
{
|
||||
if (gih_save_image (file, image_ID, orig_image_ID, drawable_ID,
|
||||
&error))
|
||||
GimpParam *save_retvals;
|
||||
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));
|
||||
|
||||
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
|
||||
{
|
||||
g_set_error (&error, 0, 0,
|
||||
"Running procedure 'file-gih-save-internal' "
|
||||
"failed: %s",
|
||||
gimp_get_pdb_error ());
|
||||
|
||||
status = GIMP_PDB_EXECUTION_ERROR;
|
||||
}
|
||||
|
||||
g_free (paramstring);
|
||||
}
|
||||
|
||||
gimp_pixpipe_params_free (&gihparams);
|
||||
|
@ -771,237 +792,3 @@ gih_save_dialog (gint32 image_ID)
|
|||
|
||||
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