diff --git a/plug-ins/common/Makefile.am b/plug-ins/common/Makefile.am index 349f5758d2..3d89351298 100644 --- a/plug-ins/common/Makefile.am +++ b/plug-ins/common/Makefile.am @@ -592,6 +592,7 @@ despeckle_LDADD = \ $(libgimpcolor) \ $(libgimpbase) \ $(GTK_LIBS) \ + $(GEGL_LIBS) \ $(RT_LIBS) \ $(INTLLIBS) \ $(despeckle_RC) diff --git a/plug-ins/common/despeckle.c b/plug-ins/common/despeckle.c index e987e1b3b7..310062bbef 100644 --- a/plug-ins/common/despeckle.c +++ b/plug-ins/common/despeckle.c @@ -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, "/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++) { diff --git a/plug-ins/common/plugin-defs.pl b/plug-ins/common/plugin-defs.pl index a0d80fcb88..29c8e0ca21 100644 --- a/plug-ins/common/plugin-defs.pl +++ b/plug-ins/common/plugin-defs.pl @@ -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 },