plug-ins: port nl-filter to GEGL, 8 bit only

(cherry picked from commit 267d925025)
This commit is contained in:
Michael Natterer
2019-06-28 19:24:56 +02:00
parent dd48c7862b
commit 190296b47b
3 changed files with 99 additions and 59 deletions

View File

@ -1572,6 +1572,7 @@ nl_filter_LDADD = \
$(libgimpcolor) \ $(libgimpcolor) \
$(libgimpbase) \ $(libgimpbase) \
$(GTK_LIBS) \ $(GTK_LIBS) \
$(GEGL_LIBS) \
$(RT_LIBS) \ $(RT_LIBS) \
$(INTLLIBS) \ $(INTLLIBS) \
$(nl_filter_RC) $(nl_filter_RC)

View File

@ -73,9 +73,12 @@ static void run (const gchar *name,
gint *nretvals, gint *nretvals,
GimpParam **retvals); GimpParam **retvals);
static void nlfilter (GimpDrawable *drawable, static void nlfilter (gint32 drawable_id,
GimpPreview *preview); GimpPreview *preview);
static gboolean nlfilter_dialog (GimpDrawable *drawable); static void nlfilter_preview (gpointer drawable_id,
GimpPreview *preview);
static gboolean nlfilter_dialog (gint32 drawable_id);
static gint nlfiltInit (gdouble alpha, static gint nlfiltInit (gdouble alpha,
gdouble radius, gdouble radius,
@ -89,6 +92,7 @@ static void nlfiltRow (guchar *srclast,
gint bpp, gint bpp,
gint filtno); gint filtno);
const GimpPlugInInfo PLUG_IN_INFO = const GimpPlugInInfo PLUG_IN_INFO =
{ {
NULL, /* init_proc */ NULL, /* init_proc */
@ -139,15 +143,15 @@ run (const gchar *name,
GimpParam **return_vals) GimpParam **return_vals)
{ {
static GimpParam values[1]; static GimpParam values[1];
GimpDrawable *drawable;
GimpRunMode run_mode; GimpRunMode run_mode;
gint32 drawable_id;
GimpPDBStatusType status = GIMP_PDB_SUCCESS; GimpPDBStatusType status = GIMP_PDB_SUCCESS;
run_mode = param[0].data.d_int32;
INIT_I18N (); INIT_I18N ();
gegl_init (NULL, NULL);
drawable = gimp_drawable_get (param[2].data.d_drawable); run_mode = param[0].data.d_int32;
drawable_id = param[2].data.d_drawable;
*nreturn_vals = 1; *nreturn_vals = 1;
*return_vals = values; *return_vals = values;
@ -160,7 +164,7 @@ run (const gchar *name,
case GIMP_RUN_INTERACTIVE: case GIMP_RUN_INTERACTIVE:
gimp_get_data (PLUG_IN_PROC, &nlfvals); gimp_get_data (PLUG_IN_PROC, &nlfvals);
if (! nlfilter_dialog (drawable)) if (! nlfilter_dialog (drawable_id))
return; return;
break; break;
@ -188,7 +192,7 @@ run (const gchar *name,
if (status == GIMP_PDB_SUCCESS) if (status == GIMP_PDB_SUCCESS)
{ {
nlfilter (drawable, NULL); nlfilter (drawable_id, NULL);
/* Store data */ /* Store data */
if (run_mode == GIMP_RUN_INTERACTIVE) if (run_mode == GIMP_RUN_INTERACTIVE)
@ -196,8 +200,6 @@ run (const gchar *name,
} }
values[0].data.d_status = status; values[0].data.d_status = status;
gimp_drawable_detach (drawable);
} }
/* pnmnlfilt.c - 4 in 1 (2 non-linear) filter /* pnmnlfilt.c - 4 in 1 (2 non-linear) filter
@ -899,10 +901,12 @@ rectang_area (gdouble rx0, gdouble ry0, gdouble rx1, gdouble ry1, gdouble tx0,
} }
static void static void
nlfilter (GimpDrawable *drawable, nlfilter (gint32 drawable_id,
GimpPreview *preview) GimpPreview *preview)
{ {
GimpPixelRgn srcPr, dstPr; GeglBuffer *src_buffer;
GeglBuffer *dest_buffer;
const Babl *format;
guchar *srcbuf, *dstbuf; guchar *srcbuf, *dstbuf;
guchar *lastrow, *thisrow, *nextrow, *temprow; guchar *lastrow, *thisrow, *nextrow, *temprow;
gint x1, y1, y2; gint x1, y1, y2;
@ -917,27 +921,31 @@ nlfilter (GimpDrawable *drawable,
} }
else else
{ {
if (! gimp_drawable_mask_intersect (drawable->drawable_id, if (! gimp_drawable_mask_intersect (drawable_id,
&x1, &y1, &width, &height)) &x1, &y1, &width, &height))
return; return;
y2 = y1 + height; y2 = y1 + height;
} }
bpp = drawable->bpp; if (gimp_drawable_has_alpha (drawable_id))
format = babl_format ("R'G'B'A u8");
else
format = babl_format ("R'G'B' u8");
src_buffer = gimp_drawable_get_buffer (drawable_id);
if (preview)
dest_buffer = gegl_buffer_new (gegl_buffer_get_extent (src_buffer), format);
else
dest_buffer = gimp_drawable_get_shadow_buffer (drawable_id);
bpp = babl_format_get_bytes_per_pixel (format);
rowsize = width * bpp; rowsize = width * bpp;
exrowsize = (width + 2) * bpp; exrowsize = (width + 2) * bpp;
p_update = width / 20 + 1; p_update = width / 20 + 1;
gimp_tile_cache_ntiles (2 * (width / gimp_tile_width () + 1));
gimp_pixel_rgn_init (&srcPr, drawable,
x1, y1, width, height, FALSE, FALSE);
gimp_pixel_rgn_init (&dstPr, drawable,
x1, y1, width, height,
preview == NULL, TRUE);
/* source buffer gives one pixel margin all around destination buffer */ /* source buffer gives one pixel margin all around destination buffer */
srcbuf = g_new0 (guchar, exrowsize * 3); srcbuf = g_new0 (guchar, exrowsize * 3);
dstbuf = g_new0 (guchar, rowsize); dstbuf = g_new0 (guchar, rowsize);
@ -953,7 +961,10 @@ nlfilter (GimpDrawable *drawable,
gimp_progress_init (_("NL Filter")); gimp_progress_init (_("NL Filter"));
/* first row */ /* first row */
gimp_pixel_rgn_get_row (&srcPr, thisrow, x1, y1, width); gegl_buffer_get (src_buffer, GEGL_RECTANGLE (x1, y1, width, 1), 1.0,
format, thisrow,
GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
/* copy thisrow[0] to thisrow[-1], thisrow[width-1] to thisrow[width] */ /* copy thisrow[0] to thisrow[-1], thisrow[width-1] to thisrow[width] */
memcpy (thisrow - bpp, thisrow, bpp); memcpy (thisrow - bpp, thisrow, bpp);
memcpy (thisrow + rowsize, thisrow + rowsize - bpp, bpp); memcpy (thisrow + rowsize, thisrow + rowsize - bpp, bpp);
@ -965,11 +976,18 @@ nlfilter (GimpDrawable *drawable,
if (((y % p_update) == 0) && !preview) if (((y % p_update) == 0) && !preview)
gimp_progress_update ((gdouble) y / (gdouble) height); gimp_progress_update ((gdouble) y / (gdouble) height);
gimp_pixel_rgn_get_row (&srcPr, nextrow, x1, y + 1, width); gegl_buffer_get (src_buffer, GEGL_RECTANGLE (x1, y + 1, width, 1), 1.0,
format, nextrow,
GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
memcpy (nextrow - bpp, nextrow, bpp); memcpy (nextrow - bpp, nextrow, bpp);
memcpy (nextrow + rowsize, nextrow + rowsize - bpp, bpp); memcpy (nextrow + rowsize, nextrow + rowsize - bpp, bpp);
nlfiltRow (lastrow, thisrow, nextrow, dstbuf, width, bpp, filtno); nlfiltRow (lastrow, thisrow, nextrow, dstbuf, width, bpp, filtno);
gimp_pixel_rgn_set_row (&dstPr, dstbuf, x1, y, width);
gegl_buffer_set (dest_buffer, GEGL_RECTANGLE (x1, y, width, 1), 0,
format, dstbuf,
GEGL_AUTO_ROWSTRIDE);
/* rotate row buffers */ /* rotate row buffers */
temprow = lastrow; lastrow = thisrow; temprow = lastrow; lastrow = thisrow;
thisrow = nextrow; nextrow = temprow; thisrow = nextrow; nextrow = temprow;
@ -978,28 +996,49 @@ nlfilter (GimpDrawable *drawable,
/* last row */ /* last row */
memcpy (nextrow - bpp, thisrow - bpp, exrowsize); memcpy (nextrow - bpp, thisrow - bpp, exrowsize);
nlfiltRow (lastrow, thisrow, nextrow, dstbuf, width, bpp, filtno); nlfiltRow (lastrow, thisrow, nextrow, dstbuf, width, bpp, filtno);
gimp_pixel_rgn_set_row (&dstPr, dstbuf, x1, y2 - 1, width);
gegl_buffer_set (dest_buffer, GEGL_RECTANGLE (x1, y2 - 1, width, 1), 0,
format, dstbuf,
GEGL_AUTO_ROWSTRIDE);
g_free (srcbuf); g_free (srcbuf);
g_free (dstbuf); g_free (dstbuf);
if (preview) if (preview)
{ {
gimp_drawable_preview_draw_region (GIMP_DRAWABLE_PREVIEW (preview), guchar *buf = g_new (guchar, width * height * bpp);
&dstPr);
gegl_buffer_get (dest_buffer, GEGL_RECTANGLE (x1, y1, width, height), 1.0,
format, buf,
GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
gimp_preview_draw_buffer (GIMP_PREVIEW (preview), buf, width * bpp);
g_free (buf);
} }
else
g_object_unref (src_buffer);
g_object_unref (dest_buffer);
if (! preview)
{ {
gimp_progress_update (1.0); gimp_progress_update (1.0);
gimp_drawable_flush (drawable);
gimp_drawable_merge_shadow (drawable->drawable_id, TRUE); gimp_drawable_merge_shadow (drawable_id, TRUE);
gimp_drawable_update (drawable->drawable_id, x1, y1, width, height); gimp_drawable_update (drawable_id, x1, y1, width, height);
gimp_displays_flush (); gimp_displays_flush ();
} }
} }
static void
nlfilter_preview (gpointer drawable_id,
GimpPreview *preview)
{
nlfilter (GPOINTER_TO_INT (drawable_id), preview);
}
static gboolean static gboolean
nlfilter_dialog (GimpDrawable *drawable) nlfilter_dialog (gint32 drawable_id)
{ {
GtkWidget *dialog; GtkWidget *dialog;
GtkWidget *main_vbox; GtkWidget *main_vbox;
@ -1036,13 +1075,13 @@ nlfilter_dialog (GimpDrawable *drawable)
main_vbox, TRUE, TRUE, 0); main_vbox, TRUE, TRUE, 0);
gtk_widget_show (main_vbox); gtk_widget_show (main_vbox);
preview = gimp_drawable_preview_new_from_drawable_id (drawable->drawable_id); preview = gimp_drawable_preview_new_from_drawable_id (drawable_id);
gtk_box_pack_start (GTK_BOX (main_vbox), preview, TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX (main_vbox), preview, TRUE, TRUE, 0);
gtk_widget_show (preview); gtk_widget_show (preview);
g_signal_connect_swapped (preview, "invalidated", g_signal_connect_swapped (preview, "invalidated",
G_CALLBACK (nlfilter), G_CALLBACK (nlfilter_preview),
drawable); GINT_TO_POINTER (drawable_id));
frame = gimp_int_radio_group_new (TRUE, _("Filter"), frame = gimp_int_radio_group_new (TRUE, _("Filter"),
G_CALLBACK (gimp_radio_button_update), G_CALLBACK (gimp_radio_button_update),

View File

@ -72,7 +72,7 @@
'mail' => { ui => 1, optional => 1 }, 'mail' => { ui => 1, optional => 1 },
'max-rgb' => { ui => 1 }, 'max-rgb' => { ui => 1 },
'newsprint' => { ui => 1 }, 'newsprint' => { ui => 1 },
'nl-filter' => { ui => 1 }, 'nl-filter' => { ui => 1, gegl => 1 },
'oilify' => { ui => 1 }, 'oilify' => { ui => 1 },
'photocopy' => { ui => 1 }, 'photocopy' => { ui => 1 },
'plugin-browser' => { ui => 1 }, 'plugin-browser' => { ui => 1 },