plug-ins: port despeckle to GEGL, stupid 8-bit port only

This commit is contained in:
Michael Natterer 2019-07-10 15:40:20 +02:00
parent fc89dfb09b
commit c59feead89
3 changed files with 92 additions and 133 deletions

View File

@ -592,6 +592,7 @@ despeckle_LDADD = \
$(libgimpcolor) \
$(libgimpbase) \
$(GTK_LIBS) \
$(GEGL_LIBS) \
$(RT_LIBS) \
$(INTLLIBS) \
$(despeckle_RC)

View File

@ -119,8 +119,8 @@ const GimpPlugInInfo PLUG_IN_INFO =
run /* run */
};
static GtkWidget *preview; /* Preview widget */
static GimpDrawable *drawable = NULL; /* Current drawable */
static GtkWidget *preview; /* Preview widget */
static gint32 drawable_ID = -1; /* Current drawable */
static gint despeckle_vals[4] =
@ -132,15 +132,8 @@ static gint despeckle_vals[4] =
};
/*
* 'main()' - Main entry - just call gimp_main()...
*/
MAIN ()
/*
* 'query()' - Respond to a plug-in query...
*/
static void
query (void)
@ -172,11 +165,6 @@ query (void)
gimp_plugin_menu_register (PLUG_IN_PROC, "<Image>/Filters/Enhance");
}
/*
* 'run()' - Run the filter...
*/
static void
run (const gchar *name,
gint nparams,
@ -185,17 +173,11 @@ run (const gchar *name,
GimpParam **return_vals)
{
GimpRunMode run_mode;
GimpPDBStatusType status;
GimpPDBStatusType status = GIMP_PDB_SUCCESS;
static GimpParam values[1];
INIT_I18N ();
/*
* Initialize parameter data...
*/
status = GIMP_PDB_SUCCESS;
run_mode = param[0].data.d_int32;
gegl_init (NULL, NULL);
values[0].type = GIMP_PDB_STATUS;
values[0].data.d_status = status;
@ -203,30 +185,16 @@ run (const gchar *name,
*nreturn_vals = 1;
*return_vals = values;
/*
* Get drawable information...
*/
drawable = gimp_drawable_get (param[2].data.d_drawable);
/*
* See how we will run
*/
run_mode = param[0].data.d_int32;
drawable_ID = param[2].data.d_drawable;
switch (run_mode)
{
case GIMP_RUN_INTERACTIVE :
/*
* Possibly retrieve data...
*/
gimp_get_data (PLUG_IN_PROC, &despeckle_radius);
/*
* Get information from the dialog...
*/
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))
{
if (! despeckle_dialog ())
return;
@ -234,12 +202,10 @@ run (const gchar *name,
break;
case GIMP_RUN_NONINTERACTIVE:
/*
* Make sure all the arguments are present...
*/
if (nparams < 4 || nparams > 9)
status = GIMP_PDB_CALLING_ERROR;
{
status = GIMP_PDB_CALLING_ERROR;
}
else if (nparams == 4)
{
despeckle_radius = param[3].data.d_int32;
@ -271,11 +237,6 @@ run (const gchar *name,
break;
case GIMP_RUN_WITH_LAST_VALS:
/*
* Possibly retrieve data...
*/
INIT_I18N();
gimp_get_data (PLUG_IN_PROC, despeckle_vals);
break;
@ -284,52 +245,27 @@ run (const gchar *name,
break;
}
/*
* Despeckle the image...
*/
if (status == GIMP_PDB_SUCCESS)
{
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))
{
/*
* Run!
*/
despeckle ();
/*
* If run prevmode is interactive, flush displays...
*/
if (run_mode != GIMP_RUN_NONINTERACTIVE)
gimp_displays_flush ();
/*
* Store data...
*/
if (run_mode == GIMP_RUN_INTERACTIVE)
gimp_set_data (PLUG_IN_PROC,
despeckle_vals, sizeof (despeckle_vals));
}
else
status = GIMP_PDB_EXECUTION_ERROR;
{
status = GIMP_PDB_EXECUTION_ERROR;
}
}
/*
* Reset the current run status...
*/
values[0].data.d_status = status;
/*
* Detach from the drawable...
*/
gimp_drawable_detach (drawable);
}
static inline guchar
@ -384,47 +320,63 @@ pixel_copy (guchar *dest,
static void
despeckle (void)
{
GimpPixelRgn src_rgn; /* Source image region */
GimpPixelRgn dst_rgn;
guchar *src;
guchar *dst;
gint img_bpp;
gint x, y;
gint width, height;
GeglBuffer *src_buffer;
GeglBuffer *dest_buffer;
const Babl *format;
guchar *src;
guchar *dst;
gint img_bpp;
gint x, y;
gint width, height;
img_bpp = gimp_drawable_bpp (drawable->drawable_id);
if (! gimp_drawable_mask_intersect (drawable->drawable_id,
if (! gimp_drawable_mask_intersect (drawable_ID,
&x, &y, &width, &height))
return;
gimp_pixel_rgn_init (&src_rgn, drawable, x, y, width, height, FALSE, FALSE);
gimp_pixel_rgn_init (&dst_rgn, drawable, x, y, width, height, TRUE, TRUE);
if (gimp_drawable_is_rgb (drawable_ID))
{
if (gimp_drawable_has_alpha (drawable_ID))
format = babl_format ("R'G'B'A u8");
else
format = babl_format ("R'G'B' u8");
}
else
{
if (gimp_drawable_has_alpha (drawable_ID))
format = babl_format ("Y'A u8");
else
format = babl_format ("Y' u8");
}
img_bpp = babl_format_get_bytes_per_pixel (format);
src_buffer = gimp_drawable_get_buffer (drawable_ID);
dest_buffer = gimp_drawable_get_shadow_buffer (drawable_ID);
src = g_new (guchar, width * height * img_bpp);
dst = g_new (guchar, width * height * img_bpp);
gimp_pixel_rgn_get_rect (&src_rgn, src, x, y, width, height);
gegl_buffer_get (src_buffer, GEGL_RECTANGLE (x, y, width, height), 1.0,
format, src,
GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
despeckle_median (src, dst, width, height, img_bpp, despeckle_radius, FALSE);
gimp_pixel_rgn_set_rect (&dst_rgn, dst, x, y, width, height);
gegl_buffer_set (dest_buffer, GEGL_RECTANGLE (x, y, width, height), 0,
format, dst,
GEGL_AUTO_ROWSTRIDE);
gimp_drawable_flush (drawable);
gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
gimp_drawable_update (drawable->drawable_id, x, y, width, height);
g_object_unref (src_buffer);
g_object_unref (dest_buffer);
gimp_drawable_merge_shadow (drawable_ID, TRUE);
gimp_drawable_update (drawable_ID, x, y, width, height);
g_free (dst);
g_free (src);
}
/*
* 'despeckle_dialog()' - Popup a dialog window for the filter box size...
*/
static gint
static gboolean
despeckle_dialog (void)
{
GtkWidget *dialog;
@ -460,7 +412,7 @@ despeckle_dialog (void)
main_vbox, TRUE, TRUE, 0);
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_widget_show (preview);
@ -550,61 +502,68 @@ despeckle_dialog (void)
G_CALLBACK (gimp_preview_invalidate),
preview);
/*
* Show it and wait for the user to do something...
*/
gtk_widget_show (dialog);
run = (gimp_dialog_run (GIMP_DIALOG (dialog)) == GTK_RESPONSE_OK);
gtk_widget_destroy (dialog);
/*
* Return ok/cancel...
*/
return run;
}
/*
* 'preview_update()' - Update the preview window.
*/
static void
preview_update (GtkWidget *widget)
{
GimpPixelRgn src_rgn; /* Source image region */
guchar *dst; /* Output image */
GimpPreview *preview; /* The preview widget */
guchar *src; /* Source pixel rows */
gint img_bpp;
gint x1,y1;
gint width, height;
GimpPreview *preview = GIMP_PREVIEW (widget);
GeglBuffer *src_buffer;
const Babl *format;
guchar *dst;
guchar *src;
gint img_bpp;
gint x1,y1;
gint width, height;
preview = GIMP_PREVIEW (widget);
img_bpp = gimp_drawable_bpp (drawable->drawable_id);
if (gimp_drawable_is_rgb (drawable_ID))
{
if (gimp_drawable_has_alpha (drawable_ID))
format = babl_format ("R'G'B'A u8");
else
format = babl_format ("R'G'B' u8");
}
else
{
if (gimp_drawable_has_alpha (drawable_ID))
format = babl_format ("Y'A u8");
else
format = babl_format ("Y' u8");
}
img_bpp = babl_format_get_bytes_per_pixel (format);
gimp_preview_get_size (preview, &width, &height);
gimp_preview_get_position (preview, &x1, &y1);
gimp_pixel_rgn_init (&src_rgn, drawable, x1, y1, width, height, FALSE, FALSE);
src_buffer = gimp_drawable_get_buffer (drawable_ID);
dst = g_new (guchar, width * height * img_bpp);
src = g_new (guchar, width * height * img_bpp);
gimp_pixel_rgn_get_rect (&src_rgn, src, x1, y1, width, height);
gegl_buffer_get (src_buffer, GEGL_RECTANGLE (x1, y1, width, height), 1.0,
format, src,
GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
despeckle_median (src, dst, width, height, img_bpp, despeckle_radius, TRUE);
gimp_preview_draw_buffer (preview, dst, width * img_bpp);
g_object_unref (src_buffer);
g_free (src);
g_free (dst);
}
static void
dialog_adaptive_callback (GtkWidget *widget,
gpointer data)
@ -630,7 +589,6 @@ dialog_recursive_callback (GtkWidget *widget,
}
static inline void
list_add_elem (PixelsList *list,
const guchar *elem)
@ -842,7 +800,6 @@ update_histogram (DespeckleHistogram *hist,
hist->ymax = ymax;
}
static void
despeckle_median (guchar *src,
guchar *dst,
@ -867,7 +824,7 @@ despeckle_median (guchar *src,
max_progress = width * height;
if (! preview)
gimp_progress_init(_("Despeckle"));
gimp_progress_init (_("Despeckle"));
adapt_radius = radius;
for (y = 0; y < height; y++)
@ -887,7 +844,8 @@ despeckle_median (guchar *src,
histogram.ymax = ymax;
add_vals (&histogram,
src, width, bpp,
histogram.xmin, histogram.ymin, histogram.xmax, histogram.ymax);
histogram.xmin, histogram.ymin,
histogram.xmax, histogram.ymax);
for (x = 0; x < width; x++)
{

View File

@ -19,7 +19,7 @@
'curve-bend' => { ui => 1, gegl => 1 },
'decompose' => { ui => 1, gegl => 1 },
'depth-merge' => { ui => 1 },
'despeckle' => { ui => 1 },
'despeckle' => { ui => 1, gegl => 1 },
'destripe' => { ui => 1 },
'edge-dog' => { ui => 1 },
'edge-neon' => { ui => 1 },