[gimp/gimp-2-10] plug-ins: port gradient-flare to GEGL, stupid 8-bit only
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/gimp-2-10] plug-ins: port gradient-flare to GEGL, stupid 8-bit only
- Date: Sat, 6 Jul 2019 13:27:16 +0000 (UTC)
commit 5e5060d598c7c5f15b4807af2794758330da09d0
Author: Michael Natterer <mitch gimp org>
Date: Sat Jul 6 15:14:55 2019 +0200
plug-ins: port gradient-flare to GEGL, stupid 8-bit only
(cherry picked from commit 1900384cc098fc381670a4b44d027b8abd3793ac)
plug-ins/gradient-flare/Makefile.am | 1 +
plug-ins/gradient-flare/gradient-flare.c | 297 +++++++++++++++++--------------
2 files changed, 167 insertions(+), 131 deletions(-)
---
diff --git a/plug-ins/gradient-flare/Makefile.am b/plug-ins/gradient-flare/Makefile.am
index 5174815510..f531be4461 100644
--- a/plug-ins/gradient-flare/Makefile.am
+++ b/plug-ins/gradient-flare/Makefile.am
@@ -45,6 +45,7 @@ LDADD = \
$(libgimpmath) \
$(libgimpbase) \
$(GTK_LIBS) \
+ $(GEGL_LIBS) \
$(RT_LIBS) \
$(INTLLIBS) \
$(gradient_flare_RC)
diff --git a/plug-ins/gradient-flare/gradient-flare.c b/plug-ins/gradient-flare/gradient-flare.c
index 059b7cd11a..49cd0978e9 100644
--- a/plug-ins/gradient-flare/gradient-flare.c
+++ b/plug-ins/gradient-flare/gradient-flare.c
@@ -280,11 +280,11 @@ typedef struct
typedef struct
{
- gint is_color;
- gint has_alpha;
- gint x, y, w, h; /* mask bounds */
- gint tile_width, tile_height;
- /* these values don't belong to drawable, though. */
+ const Babl *format;
+ gint bpp;
+ gint is_color;
+ gint has_alpha;
+ gint x, y, w, h; /* mask bounds */
} DrawableInfo;
typedef struct _GradientMenu GradientMenu;
@@ -555,10 +555,8 @@ static const gchar *gflare_menu_modes[] =
};
static gint32 image_ID;
-static GimpDrawable *drawable;
+static gint32 drawable_ID;
static DrawableInfo dinfo;
-static GimpPixelFetcher *tk_read;
-static GimpPixelFetcher *tk_write;
static GFlareDialog *dlg = NULL;
static GFlareEditor *ed = NULL;
static GList *gflares_list = NULL;
@@ -589,8 +587,10 @@ static clock_t get_values_external_clock = 0;
static void plugin_do (void);
-static void plugin_do_non_asupsample (void);
-static void plugin_do_asupsample (void);
+static void plugin_do_non_asupsample (GeglBuffer *src_buffer,
+ GeglBuffer *dest_buffer);
+static void plugin_do_asupsample (GeglBuffer *src_buffer,
+ GeglBuffer *dest_buffer);
static void plugin_render_func (gdouble x,
gdouble y,
GimpRGB *color,
@@ -831,10 +831,8 @@ plugin_run (const gchar *name,
GimpPDBStatusType status = GIMP_PDB_SUCCESS;
gchar *path;
- /* Initialize */
- run_mode = param[0].data.d_int32;
-
INIT_I18N ();
+ gegl_init (NULL, NULL);
*nreturn_vals = 1;
*return_vals = values;
@@ -842,22 +840,34 @@ plugin_run (const gchar *name,
values[0].type = GIMP_PDB_STATUS;
values[0].data.d_status = status;
- /*
- * Get the specified drawable and its info (global variable)
- */
+ run_mode = param[0].data.d_int32;
+ image_ID = param[1].data.d_image;
+ drawable_ID = param[2].data.d_drawable;
- image_ID = param[1].data.d_image;
- drawable = gimp_drawable_get (param[2].data.d_drawable);
- dinfo.is_color = gimp_drawable_is_rgb (drawable->drawable_id);
- dinfo.has_alpha = gimp_drawable_has_alpha (drawable->drawable_id);
+ dinfo.is_color = gimp_drawable_is_rgb (drawable_ID);
+ dinfo.has_alpha = gimp_drawable_has_alpha (drawable_ID);
- if (! gimp_drawable_mask_intersect (drawable->drawable_id,
+ if (dinfo.is_color)
+ {
+ if (dinfo.has_alpha)
+ dinfo.format = babl_format ("R'G'B'A u8");
+ else
+ dinfo.format = babl_format ("R'G'B' u8");
+ }
+ else
+ {
+ if (dinfo.has_alpha)
+ dinfo.format = babl_format ("Y'A u8");
+ else
+ dinfo.format = babl_format ("Y u8");
+ }
+
+ dinfo.bpp = babl_format_get_bytes_per_pixel (dinfo.format);
+
+ if (! gimp_drawable_mask_intersect (drawable_ID,
&dinfo.x, &dinfo.y, &dinfo.w, &dinfo.h))
return;
- dinfo.tile_width = gimp_tile_width ();
- dinfo.tile_height = gimp_tile_height ();
-
/*
* Start gradient caching
*/
@@ -894,9 +904,6 @@ plugin_run (const gchar *name,
gflares_list_load_all ();
- gimp_tile_cache_ntiles (drawable->width / gimp_tile_width () + 2);
-
-
switch (run_mode)
{
case GIMP_RUN_INTERACTIVE:
@@ -906,10 +913,7 @@ plugin_run (const gchar *name,
/* First acquire information with a dialog */
if (! dlg_run ())
- {
- gimp_drawable_detach (drawable);
- return;
- }
+ return;
break;
case GIMP_RUN_NONINTERACTIVE:
@@ -948,8 +952,8 @@ plugin_run (const gchar *name,
if (status == GIMP_PDB_SUCCESS)
{
/* Make sure that the drawable is gray or RGB color */
- if (gimp_drawable_is_rgb (drawable->drawable_id) ||
- gimp_drawable_is_gray (drawable->drawable_id))
+ if (gimp_drawable_is_rgb (drawable_ID) ||
+ gimp_drawable_is_gray (drawable_ID))
{
gimp_progress_init (_("Gradient Flare"));
plugin_do ();
@@ -976,13 +980,14 @@ plugin_run (const gchar *name,
* Deinitialization
*/
gradient_free ();
- gimp_drawable_detach (drawable);
}
static void
plugin_do (void)
{
- GFlare *gflare;
+ GeglBuffer *src_buffer;
+ GeglBuffer *dest_buffer;
+ GFlare *gflare;
gflare = gflares_list_lookup (pvals.gflare_name);
if (gflare == NULL)
@@ -999,53 +1004,69 @@ plugin_do (void)
pvals.vangle, pvals.vlength);
while (calc_init_progress ()) ;
+ src_buffer = gimp_drawable_get_buffer (drawable_ID);
+ dest_buffer = gimp_drawable_get_shadow_buffer (drawable_ID);
+
/* Render it ! */
if (pvals.use_asupsample)
- plugin_do_asupsample ();
+ plugin_do_asupsample (src_buffer, dest_buffer);
else
- plugin_do_non_asupsample ();
+ plugin_do_non_asupsample (src_buffer, dest_buffer);
+
+ g_object_unref (src_buffer);
+ g_object_unref (dest_buffer);
gimp_progress_update (1.0);
+
/* Clean up */
calc_deinit ();
- gimp_drawable_flush (drawable);
- gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
- gimp_drawable_update (drawable->drawable_id, dinfo.x, dinfo.y,
- dinfo.w, dinfo.h);
+
+ gimp_drawable_merge_shadow (drawable_ID, TRUE);
+ gimp_drawable_update (drawable_ID, dinfo.x, dinfo.y, dinfo.w, dinfo.h);
}
/* these routines should be almost rewritten anyway */
static void
-plugin_do_non_asupsample (void)
+plugin_do_non_asupsample (GeglBuffer *src_buffer,
+ GeglBuffer *dest_buffer)
{
- GimpPixelRgn src_rgn, dest_rgn;
- gpointer pr;
- gint progress, max_progress;
-
+ GeglBufferIterator *iter;
+ gint progress;
+ gint max_progress;
progress = 0;
max_progress = dinfo.w * dinfo.h;
- gimp_pixel_rgn_init (&src_rgn, drawable,
- dinfo.x, dinfo.y, dinfo.w, dinfo.h, FALSE, FALSE);
- gimp_pixel_rgn_init (&dest_rgn, drawable,
- dinfo.x, dinfo.y, dinfo.w, dinfo.h, TRUE, TRUE);
+ iter = gegl_buffer_iterator_new (src_buffer,
+ GEGL_RECTANGLE (dinfo.x, dinfo.y,
+ dinfo.w, dinfo.h), 0,
+ dinfo.format,
+ GEGL_ACCESS_READ, GEGL_ABYSS_NONE, 2);
+
+ gegl_buffer_iterator_add (iter, dest_buffer,
+ GEGL_RECTANGLE (dinfo.x, dinfo.y,
+ dinfo.w, dinfo.h), 0,
+ dinfo.format,
+ GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE);
- for (pr = gimp_pixel_rgns_register (2, &src_rgn, &dest_rgn);
- pr != NULL; pr = gimp_pixel_rgns_process (pr))
+ while (gegl_buffer_iterator_next (iter))
{
- const guchar *src_row = src_rgn.data;
- guchar *dest_row = dest_rgn.data;
+ const guchar *src_row = iter->items[0].data;
+ guchar *dest_row = iter->items[1].data;
gint row, y;
- for (row = 0, y = src_rgn.y; row < src_rgn.h; row++, y++)
+ for (row = 0, y = iter->items[0].roi.y;
+ row < iter->items[0].roi.height;
+ row++, y++)
{
const guchar *src = src_row;
guchar *dest = dest_row;
gint col, x;
- for (col = 0, x = src_rgn.x; col < src_rgn.w; col++, x++)
+ for (col = 0, x = iter->items[0].roi.x;
+ col < iter->items[0].roi.width;
+ col++, x++)
{
guchar src_pix[4];
guchar dest_pix[4];
@@ -1054,7 +1075,7 @@ plugin_do_non_asupsample (void)
for (b = 0; b < 3; b++)
src_pix[b] = dinfo.is_color ? src[b] : src[0];
- src_pix[3] = dinfo.has_alpha ? src[src_rgn.bpp - 1] : OPAQUE;
+ src_pix[3] = dinfo.has_alpha ? src[dinfo.bpp - 1] : OPAQUE;
calc_gflare_pix (dest_pix, x, y, src_pix);
@@ -1069,43 +1090,36 @@ plugin_do_non_asupsample (void)
}
if (dinfo.has_alpha)
- dest[src_rgn.bpp - 1] = dest_pix[3];
+ dest[dinfo.bpp - 1] = dest_pix[3];
- src += src_rgn.bpp;
- dest += dest_rgn.bpp;
+ src += dinfo.bpp;
+ dest += dinfo.bpp;
}
- src_row += src_rgn.rowstride;
- dest_row += dest_rgn.rowstride;
+ src_row += dinfo.bpp * iter->items[0].roi.width;
+ dest_row += dinfo.bpp * iter->items[1].roi.width;
}
/* Update progress */
- progress += src_rgn.w * src_rgn.h;
+ progress += iter->items[0].roi.width * iter->items[0].roi.height;
gimp_progress_update ((double) progress / (double) max_progress);
}
}
static void
-plugin_do_asupsample (void)
+plugin_do_asupsample (GeglBuffer *src_buffer,
+ GeglBuffer *dest_buffer)
{
- tk_read = gimp_pixel_fetcher_new (drawable, FALSE);
- gimp_pixel_fetcher_set_edge_mode (tk_read, GIMP_PIXEL_FETCHER_EDGE_BLACK);
-
- tk_write = gimp_pixel_fetcher_new (drawable, TRUE);
-
gimp_adaptive_supersample_area (dinfo.x, dinfo.y,
dinfo.x + dinfo.w - 1, dinfo.y + dinfo.h - 1,
pvals.asupsample_max_depth,
pvals.asupsample_threshold,
plugin_render_func,
- NULL,
+ src_buffer,
plugin_put_pixel_func,
- NULL,
+ dest_buffer,
plugin_progress_func,
NULL);
-
- gimp_pixel_fetcher_destroy (tk_write);
- gimp_pixel_fetcher_destroy (tk_read);
}
/*
@@ -1121,22 +1135,24 @@ plugin_render_func (gdouble x,
GimpRGB *color,
gpointer data)
{
- guchar src_pix[4];
- guchar flare_pix[4];
- guchar src[4];
- gint b;
- gint ix, iy;
+ GeglBuffer *src_buffer = data;
+ guchar src_pix[4];
+ guchar flare_pix[4];
+ guchar src[4];
+ gint b;
+ gint ix, iy;
/* translate (0.5, 0.5) before convert to `int' so that it can surely
point the center of pixel */
ix = floor (x + 0.5);
iy = floor (y + 0.5);
- gimp_pixel_fetcher_get_pixel (tk_read, ix, iy, src);
+ gegl_buffer_sample (src_buffer, ix, iy, NULL, src, dinfo.format,
+ GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
for (b = 0; b < 3; b++)
src_pix[b] = dinfo.is_color ? src[b] : src[0];
- src_pix[3] = dinfo.has_alpha ? src[drawable->bpp - 1] : OPAQUE;
+ src_pix[3] = dinfo.has_alpha ? src[dinfo.bpp - 1] : OPAQUE;
calc_gflare_pix (flare_pix, x, y, src_pix);
@@ -1152,7 +1168,8 @@ plugin_put_pixel_func (gint ix,
GimpRGB *color,
gpointer data)
{
- guchar dest[4];
+ GeglBuffer *dest_buffer = data;
+ guchar dest[4];
if (dinfo.is_color)
{
@@ -1166,9 +1183,10 @@ plugin_put_pixel_func (gint ix,
}
if (dinfo.has_alpha)
- dest[drawable->bpp - 1] = color->a * 255;
+ dest[dinfo.bpp - 1] = color->a * 255;
- gimp_pixel_fetcher_put_pixel (tk_write, ix, iy, dest);
+ gegl_buffer_set (dest_buffer, GEGL_RECTANGLE (ix, iy, 1, 1), 0,
+ dinfo.format, dest, GEGL_AUTO_ROWSTRIDE);
}
static void
@@ -2364,14 +2382,15 @@ calc_overlay (guchar *dest, guchar *src1, guchar *src2)
static gboolean
dlg_run (void)
{
- GtkWidget *shell;
- GtkWidget *hbox;
- GtkWidget *vbox;
- GtkWidget *frame;
- GtkWidget *abox;
- GtkWidget *button;
- GtkWidget *notebook;
- gboolean run = FALSE;
+ GeglBuffer *src_buffer;
+ GtkWidget *shell;
+ GtkWidget *hbox;
+ GtkWidget *vbox;
+ GtkWidget *frame;
+ GtkWidget *abox;
+ GtkWidget *button;
+ GtkWidget *notebook;
+ gboolean run = FALSE;
gimp_ui_init (PLUG_IN_BINARY, TRUE);
@@ -2435,9 +2454,11 @@ dlg_run (void)
gtk_container_add (GTK_CONTAINER (abox), frame);
gtk_widget_show (frame);
+ src_buffer = gimp_drawable_get_buffer (drawable_ID);
+
dlg->preview = preview_new (DLG_PREVIEW_WIDTH, DLG_PREVIEW_HEIGHT,
dlg_preview_init_func, NULL,
- dlg_preview_render_func, NULL,
+ dlg_preview_render_func, src_buffer,
dlg_preview_deinit_func, NULL);
gtk_widget_set_events (GTK_WIDGET (dlg->preview->widget), DLG_PREVIEW_MASK);
gtk_container_add (GTK_CONTAINER (frame), dlg->preview->widget);
@@ -2487,6 +2508,8 @@ dlg_run (void)
run = TRUE;
}
+ g_object_unref (src_buffer);
+
gtk_widget_destroy (shell);
return run;
@@ -2523,56 +2546,61 @@ dlg_setup_gflare (void)
void
dlg_preview_calc_window (void)
{
+ gint width = gimp_drawable_width (drawable_ID);
+ gint height = gimp_drawable_height (drawable_ID);
gint is_wide;
gdouble offx, offy;
- is_wide = ((double) DLG_PREVIEW_HEIGHT * drawable->width
- >= (double) DLG_PREVIEW_WIDTH * drawable->height);
+ is_wide = ((double) DLG_PREVIEW_HEIGHT * width >=
+ (double) DLG_PREVIEW_WIDTH * height);
+
if (is_wide)
{
- offy = ((double) drawable->width * DLG_PREVIEW_HEIGHT / DLG_PREVIEW_WIDTH) / 2.0;
+ offy = ((double) width * DLG_PREVIEW_HEIGHT / DLG_PREVIEW_WIDTH) / 2.0;
dlg->pwin.x0 = 0;
- dlg->pwin.x1 = drawable->width;
- dlg->pwin.y0 = drawable->height / 2.0 - offy;
- dlg->pwin.y1 = drawable->height / 2.0 + offy;
+ dlg->pwin.x1 = width;
+ dlg->pwin.y0 = height / 2.0 - offy;
+ dlg->pwin.y1 = height / 2.0 + offy;
}
else
{
- offx = ((double) drawable->height * DLG_PREVIEW_WIDTH / DLG_PREVIEW_HEIGHT) / 2.0;
+ offx = ((double) height * DLG_PREVIEW_WIDTH / DLG_PREVIEW_HEIGHT) / 2.0;
- dlg->pwin.x0 = drawable->width / 2.0 - offx;
- dlg->pwin.x1 = drawable->width / 2.0 + offx;
+ dlg->pwin.x0 = width / 2.0 - offx;
+ dlg->pwin.x1 = width / 2.0 + offx;
dlg->pwin.y0 = 0;
- dlg->pwin.y1 = drawable->height;
+ dlg->pwin.y1 = height;
}
}
void
ed_preview_calc_window (void)
{
+ gint width = gimp_drawable_width (drawable_ID);
+ gint height = gimp_drawable_height (drawable_ID);
gint is_wide;
gdouble offx, offy;
- is_wide = ((double) DLG_PREVIEW_HEIGHT * drawable->width
- >= (double) DLG_PREVIEW_WIDTH * drawable->height);
+ is_wide = ((double) DLG_PREVIEW_HEIGHT * width >=
+ (double) DLG_PREVIEW_WIDTH * height);
+
if (is_wide)
{
- offy = ((double) drawable->width * DLG_PREVIEW_HEIGHT / DLG_PREVIEW_WIDTH) / 2.0;
+ offy = ((double) width * DLG_PREVIEW_HEIGHT / DLG_PREVIEW_WIDTH) / 2.0;
dlg->pwin.x0 = 0;
- dlg->pwin.x1 = drawable->width;
- dlg->pwin.y0 = drawable->height / 2.0 - offy;
- dlg->pwin.y1 = drawable->height / 2.0 + offy;
+ dlg->pwin.x1 = width;
+ dlg->pwin.y0 = height / 2.0 - offy;
+ dlg->pwin.y1 = height / 2.0 + offy;
}
else
{
- offx = ((double) drawable->height * DLG_PREVIEW_WIDTH / DLG_PREVIEW_HEIGHT) / 2.0;
+ offx = ((double) height * DLG_PREVIEW_WIDTH / DLG_PREVIEW_HEIGHT) / 2.0;
- dlg->pwin.x0 = drawable->width / 2.0 - offx;
- dlg->pwin.x1 = drawable->width / 2.0 + offx;
+ dlg->pwin.x0 = width / 2.0 - offx; dlg->pwin.x1 = width / 2.0 + offx;
dlg->pwin.y0 = 0;
- dlg->pwin.y1 = drawable->height;
+ dlg->pwin.y1 = height;
}
}
@@ -2666,33 +2694,36 @@ dlg_preview_render_func (Preview *preview,
gint y,
gpointer data)
{
- GimpPixelRgn srcPR;
- gint x;
- gint dx, dy; /* drawable x, y */
- guchar *src_row, *src;
- guchar src_pix[4], dest_pix[4];
- gint b;
+ GeglBuffer *src_buffer = data;
+ gint width = gimp_drawable_width (drawable_ID);
+ gint height = gimp_drawable_height (drawable_ID);
+ gint x;
+ gint dx, dy; /* drawable x, y */
+ guchar *src_row, *src;
+ guchar src_pix[4], dest_pix[4];
+ gint b;
dy = (dlg->pwin.y0 +
(gdouble) (dlg->pwin.y1 - dlg->pwin.y0) * y / DLG_PREVIEW_HEIGHT);
- if (dy < 0 || dy >= drawable->height)
+ if (dy < 0 || dy >= height)
{
memset (dest, GRAY50, 3 * DLG_PREVIEW_WIDTH);
return;
}
- src_row = g_new (guchar, drawable->bpp * drawable->width);
- gimp_pixel_rgn_init (&srcPR, drawable,
- 0, 0, drawable->width, drawable->height, FALSE, FALSE);
- gimp_pixel_rgn_get_row (&srcPR, src_row, 0, dy, drawable->width);
+ src_row = g_new (guchar, dinfo.bpp * width);
+
+ gegl_buffer_get (src_buffer, GEGL_RECTANGLE (0, dy, width, 1), 1.0,
+ dinfo.format, src_row,
+ GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
for (x = 0; x < DLG_PREVIEW_HEIGHT; x++)
{
dx = (dlg->pwin.x0 +
(double) (dlg->pwin.x1 - dlg->pwin.x0) * x / DLG_PREVIEW_WIDTH);
- if (dx < 0 || dx >= drawable->width)
+ if (dx < 0 || dx >= width)
{
for (b = 0; b < 3; b++)
*dest++ = GRAY50;
@@ -2700,11 +2731,11 @@ dlg_preview_render_func (Preview *preview,
}
/* Get drawable pix value */
- src = &src_row[dx * drawable->bpp];
+ src = &src_row[dx * dinfo.bpp];
for (b = 0; b < 3; b++)
src_pix[b] = dinfo.is_color ? src[b] : src[0];
- src_pix[3] = dinfo.has_alpha ? src[drawable->bpp-1] : OPAQUE;
+ src_pix[3] = dinfo.has_alpha ? src[dinfo.bpp - 1] : OPAQUE;
/* Get GFlare pix value */
@@ -2764,11 +2795,11 @@ dlg_make_page_settings (GFlareDialog *dlg,
_("_X:"), pvals.xcenter, xres,
-GIMP_MAX_IMAGE_SIZE, GIMP_MAX_IMAGE_SIZE,
- 0, gimp_drawable_width (drawable->drawable_id),
+ 0, gimp_drawable_width (drawable_ID),
_("_Y:"), pvals.ycenter, yres,
-GIMP_MAX_IMAGE_SIZE, GIMP_MAX_IMAGE_SIZE,
- 0, gimp_drawable_height (drawable->drawable_id));
+ 0, gimp_drawable_height (drawable_ID));
chain = GTK_WIDGET (GIMP_COORDINATES_CHAINBUTTON (center));
@@ -2796,7 +2827,8 @@ dlg_make_page_settings (GFlareDialog *dlg,
adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++,
_("_Radius:"), SCALE_WIDTH, 6,
- pvals.radius, 0.0, drawable->width / 2,
+ pvals.radius, 0.0,
+ gimp_drawable_width (drawable_ID) / 2,
1.0, 10.0, 1,
FALSE, 0.0, GIMP_MAX_IMAGE_SIZE,
NULL, NULL);
@@ -4153,7 +4185,10 @@ ed_preview_deinit_func (Preview *preview, gpointer data)
}
static void
-ed_preview_render_func (Preview *preview, guchar *buffer, gint y, gpointer data)
+ed_preview_render_func (Preview *preview,
+ guchar *buffer,
+ gint y,
+ gpointer data)
{
switch (ed->cur_page)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]