[gimp] plug-ins: port wavelet-decompose
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] plug-ins: port wavelet-decompose
- Date: Thu, 29 Aug 2019 22:23:34 +0000 (UTC)
commit 1ee7cc867a28247a50bc7d06afb51493909ea77b
Author: Michael Natterer <mitch gimp org>
Date: Fri Aug 30 00:23:14 2019 +0200
plug-ins: port wavelet-decompose
plug-ins/common/Makefile.am | 2 -
plug-ins/common/plugin-defs.pl | 2 +-
plug-ins/common/wavelet-decompose.c | 459 +++++++++++++++++++-----------------
3 files changed, 244 insertions(+), 219 deletions(-)
---
diff --git a/plug-ins/common/Makefile.am b/plug-ins/common/Makefile.am
index 25b1f507db..42a86ec66c 100644
--- a/plug-ins/common/Makefile.am
+++ b/plug-ins/common/Makefile.am
@@ -1566,8 +1566,6 @@ warp_LDADD = \
$(INTLLIBS) \
$(warp_RC)
-wavelet_decompose_CPPFLAGS = $(AM_CPPFLAGS) -DGIMP_DEPRECATED_REPLACE_NEW_API
-
wavelet_decompose_SOURCES = \
wavelet-decompose.c
diff --git a/plug-ins/common/plugin-defs.pl b/plug-ins/common/plugin-defs.pl
index 0379451fd9..be31ddaf2f 100644
--- a/plug-ins/common/plugin-defs.pl
+++ b/plug-ins/common/plugin-defs.pl
@@ -71,7 +71,7 @@
'unit-editor' => { ui => 1 },
'van-gogh-lic' => { ui => 1, gegl => 1, old_api => 1 },
'warp' => { ui => 1, gegl => 1, old_api => 1 },
- 'wavelet-decompose' => { ui => 1, gegl => 1, old_api => 1 },
+ 'wavelet-decompose' => { ui => 1, gegl => 1 },
'web-browser' => { ui => 1, ldflags => '$(framework_cocoa)', cppflags => '$(AM_CPPFLAGS)
$(xobjective_c)' },
'web-page' => { ui => 1, optional => 1, libs => 'WEBKIT_LIBS', cflags => 'WEBKIT_CFLAGS' }
);
diff --git a/plug-ins/common/wavelet-decompose.c b/plug-ins/common/wavelet-decompose.c
index 7c9e50eea9..efa673043d 100644
--- a/plug-ins/common/wavelet-decompose.c
+++ b/plug-ins/common/wavelet-decompose.c
@@ -35,105 +35,146 @@
typedef struct
{
- gint scales;
- gint create_group;
- gint create_masks;
+ gint scales;
+ gboolean create_group;
+ gboolean create_masks;
} WaveletDecomposeParams;
-/* Declare local functions.
- */
-static void query (void);
-static void run (const gchar *name,
- gint nparams,
- const GimpParam *param,
- gint *nreturn_vals,
- GimpParam **return_vals);
+typedef struct _Wavelet Wavelet;
+typedef struct _WaveletClass WaveletClass;
-static void wavelet_blur (gint32 drawable_id,
- gint radius);
+struct _Wavelet
+{
+ GimpPlugIn parent_instance;
+};
+struct _WaveletClass
+{
+ GimpPlugInClass parent_class;
+};
-static gboolean wavelet_decompose_dialog (void);
+#define WAVELET_TYPE (wavelet_get_type ())
+#define WAVELET (obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), WAVELET_TYPE, Wavelet))
-/* create a few globals, set default values */
-static WaveletDecomposeParams wavelet_params =
-{
- 5, /* default scales */
- 1, /* create group */
- 0 /* do not add mask by default */
-};
+GType wavelet_get_type (void) G_GNUC_CONST;
+
+static GList * wavelet_query_procedures (GimpPlugIn *plug_in);
+static GimpProcedure * wavelet_create_procedure (GimpPlugIn *plug_in,
+ const gchar *name);
+
+static GimpValueArray * wavelet_run (GimpProcedure *procedure,
+ GimpRunMode run_mode,
+ GimpImage *image,
+ GimpDrawable *drawable,
+ const GimpValueArray *args,
+ gpointer run_data);
+
+static void wavelet_blur (GimpDrawable *drawable,
+ gint radius);
+
+static gboolean wavelet_decompose_dialog (void);
+
+
+G_DEFINE_TYPE (Wavelet, wavelet, GIMP_TYPE_PLUG_IN)
+
+GIMP_MAIN (WAVELET_TYPE)
-const GimpPlugInInfo PLUG_IN_INFO =
+
+static WaveletDecomposeParams wavelet_params =
{
- NULL, /* init_proc */
- NULL, /* quit_proc */
- query, /* query_proc */
- run, /* run_proc */
+ 5, /* default scales */
+ TRUE, /* create group */
+ FALSE /* do not add mask by default */
};
-MAIN ()
+static void
+wavelet_class_init (WaveletClass *klass)
+{
+ GimpPlugInClass *plug_in_class = GIMP_PLUG_IN_CLASS (klass);
+ plug_in_class->query_procedures = wavelet_query_procedures;
+ plug_in_class->create_procedure = wavelet_create_procedure;
+}
static void
-query (void)
+wavelet_init (Wavelet *wavelet)
{
- static const GimpParamDef args[] =
- {
- { GIMP_PDB_INT32, "run-mode", "The run mode { RUN-INTERACTIVE (0), "
- "RUN-NONINTERACTIVE (1) }" },
- { GIMP_PDB_IMAGE, "image", "Input image (unused)" },
- { GIMP_PDB_DRAWABLE, "drawable", "Input drawable" },
- { GIMP_PDB_INT32, "scales", "Number of scales (1-7)" },
- { GIMP_PDB_INT32, "create-group", "Create a layer group to store the "
- "decomposition" },
- { GIMP_PDB_INT32, "create-masks", "Add a layer mask to each scales "
- "layers" }
- };
-
- gimp_install_procedure (PLUG_IN_PROC,
- N_("Wavelet decompose"),
- "Compute and render wavelet scales",
- "Miroslav Talasek <miroslav talasek seznam cz>",
- "Miroslav Talasek <miroslav talasek seznam cz>",
- "19january 2017",
- N_("_Wavelet-decompose..."),
- "RGB*",
- GIMP_PLUGIN,
- G_N_ELEMENTS (args), 0,
- args, NULL);
-
- gimp_plugin_menu_register (PLUG_IN_PROC, "<Image>/Filters/Enhance");
}
-static void
-run (const gchar *name,
- gint nparams,
- const GimpParam *param,
- gint *nreturn_vals,
- GimpParam **return_vals)
+static GList *
+wavelet_query_procedures (GimpPlugIn *plug_in)
{
- static GimpParam values[1];
- GimpPDBStatusType status = GIMP_PDB_SUCCESS;
- gint32 image_id;
- gint32 drawable_id;
- GimpRunMode run_mode;
+ return g_list_append (NULL, g_strdup (PLUG_IN_PROC));
+}
- run_mode = param[0].data.d_int32;
+static GimpProcedure *
+wavelet_create_procedure (GimpPlugIn *plug_in,
+ const gchar *name)
+{
+ GimpProcedure *procedure = NULL;
- INIT_I18N();
- gegl_init (NULL, NULL);
+ if (! strcmp (name, PLUG_IN_PROC))
+ {
+ procedure = gimp_image_procedure_new (plug_in, name, GIMP_PLUGIN,
+ wavelet_run, NULL, NULL);
+
+ gimp_procedure_set_image_types (procedure, "RGB*");
+
+ gimp_procedure_set_menu_label (procedure, N_("_Wavelet-decompose..."));
+ gimp_procedure_add_menu_path (procedure, "<Image>/Filters/Enhance");
+
+ gimp_procedure_set_documentation (procedure,
+ N_("Wavelet decompose"),
+ "Compute and render wavelet scales",
+ name);
+ gimp_procedure_set_attribution (procedure,
+ "Miroslav Talasek <miroslav talasek seznam cz>",
+ "Miroslav Talasek <miroslav talasek seznam cz>",
+ "19january 2017");
+
+ GIMP_PROC_ARG_INT (procedure, "scales",
+ "Scales",
+ "Number of scales",
+ 1, 7, 5,
+ G_PARAM_READWRITE);
+
+ GIMP_PROC_ARG_BOOLEAN (procedure, "create-group",
+ "Create grooup",
+ "Create a layer group to store the "
+ "decomposition",
+ TRUE,
+ G_PARAM_READWRITE);
+
+ GIMP_PROC_ARG_BOOLEAN (procedure, "create-masks",
+ "Create masks",
+ "Add a layer mask to each scales layer",
+ FALSE,
+ G_PARAM_READWRITE);
+ }
- *nreturn_vals = 1;
- *return_vals = values;
+ return procedure;
+}
- values[0].type = GIMP_PDB_STATUS;
- values[0].data.d_status = status;
+static GimpValueArray *
+wavelet_run (GimpProcedure *procedure,
+ GimpRunMode run_mode,
+ GimpImage *image,
+ GimpDrawable *drawable,
+ const GimpValueArray *args,
+ gpointer run_data)
+{
+ GimpLayer **scale_layers;
+ GimpLayer *new_scale;
+ GimpLayer *parent = NULL;
+ GimpLayerMode grain_extract_mode = GIMP_LAYER_MODE_GRAIN_EXTRACT;
+ GimpLayerMode grain_merge_mode = GIMP_LAYER_MODE_GRAIN_MERGE;
+ gint id;
- image_id = param[1].data.d_image;
- drawable_id = param[2].data.d_drawable;
+ INIT_I18N();
+ gegl_init (NULL, NULL);
switch (run_mode)
{
@@ -141,20 +182,15 @@ run (const gchar *name,
gimp_get_data (PLUG_IN_PROC, &wavelet_params);
if (! wavelet_decompose_dialog ())
- return;
+ return gimp_procedure_new_return_values (procedure,
+ GIMP_PDB_CANCEL,
+ NULL);
break;
case GIMP_RUN_NONINTERACTIVE:
- if (nparams != 6)
- {
- status = GIMP_PDB_CALLING_ERROR;
- }
- else
- {
- wavelet_params.scales = param[3].data.d_int32;
- wavelet_params.create_group = param[4].data.d_int32;
- wavelet_params.create_masks = param[5].data.d_int32;
- }
+ wavelet_params.scales = GIMP_VALUES_GET_INT (args, 0);
+ wavelet_params.create_group = GIMP_VALUES_GET_BOOLEAN (args, 1);
+ wavelet_params.create_masks = GIMP_VALUES_GET_BOOLEAN (args, 2);
break;
case GIMP_RUN_WITH_LAST_VALS:
@@ -165,168 +201,159 @@ run (const gchar *name,
break;
}
- if (status == GIMP_PDB_SUCCESS)
- {
- gint32 *scale_ids;
- gint32 new_scale_id;
- gint32 parent_id;
- GimpLayerMode grain_extract_mode = GIMP_LAYER_MODE_GRAIN_EXTRACT;
- GimpLayerMode grain_merge_mode = GIMP_LAYER_MODE_GRAIN_MERGE;
- gint id;
+ gimp_progress_init (_("Wavelet-Decompose"));
- gimp_progress_init (_("Wavelet-Decompose"));
+ gimp_image_undo_group_start (image);
- gimp_image_undo_group_start (image_id);
+ gimp_image_freeze_layers (image);
- gimp_image_freeze_layers (image_id);
+ if (wavelet_params.create_group)
+ {
+ parent = gimp_layer_group_new (image);
+
+ gimp_item_set_name (GIMP_ITEM (parent), _("Decomposition"));
+ gimp_item_set_visible (GIMP_ITEM (parent), FALSE);
+ gimp_image_insert_layer (image, parent,
+ GIMP_LAYER (gimp_item_get_parent (GIMP_ITEM (drawable))),
+ gimp_image_get_item_position (image,
+ GIMP_ITEM (drawable)));
+ }
- if (wavelet_params.create_group)
- {
- gint32 group_id = gimp_layer_group_new (image_id);
- gimp_item_set_name (group_id, _("Decomposition"));
- gimp_item_set_visible (group_id, FALSE);
- gimp_image_insert_layer (image_id, group_id,
- gimp_item_get_parent (drawable_id),
- gimp_image_get_item_position (image_id,
- drawable_id));
- parent_id = group_id;
- }
- else
- parent_id = -1;
-
- scale_ids = g_new (gint32, wavelet_params.scales);
- new_scale_id = gimp_layer_copy (drawable_id);
- gimp_image_insert_layer (image_id, new_scale_id, parent_id,
- gimp_image_get_item_position (image_id,
- drawable_id));
-
- /* the exact result of the grain-extract and grain-merge modes depends on
- * the choice of (gamma-corrected) midpoint intensity value. for the
- * non-legacy modes, the midpoint value is 0.5, which isn't representable
- * exactly using integer precision. for the legacy modes, the midpoint
- * value is 128/255 (i.e., 0x80), which is representable exactly using
- * (gamma-corrected) integer precision. we therefore use the legacy
- * modes when the input image precision is integer, and only use the
- * (preferable) non-legacy modes when the input image precision is
- * floating point.
- *
- * this avoids imperfect reconstruction of the image when using integer
- * precision. see bug #786844.
- */
- switch (gimp_image_get_precision (image_id))
- {
- case GIMP_PRECISION_U8_LINEAR:
- case GIMP_PRECISION_U8_NON_LINEAR:
- case GIMP_PRECISION_U8_PERCEPTUAL:
- case GIMP_PRECISION_U16_LINEAR:
- case GIMP_PRECISION_U16_NON_LINEAR:
- case GIMP_PRECISION_U16_PERCEPTUAL:
- case GIMP_PRECISION_U32_LINEAR:
- case GIMP_PRECISION_U32_NON_LINEAR:
- case GIMP_PRECISION_U32_PERCEPTUAL:
- grain_extract_mode = GIMP_LAYER_MODE_GRAIN_EXTRACT_LEGACY;
- grain_merge_mode = GIMP_LAYER_MODE_GRAIN_MERGE_LEGACY;
- break;
-
- case GIMP_PRECISION_HALF_LINEAR:
- case GIMP_PRECISION_HALF_NON_LINEAR:
- case GIMP_PRECISION_HALF_PERCEPTUAL:
- case GIMP_PRECISION_FLOAT_LINEAR:
- case GIMP_PRECISION_FLOAT_NON_LINEAR:
- case GIMP_PRECISION_FLOAT_PERCEPTUAL:
- case GIMP_PRECISION_DOUBLE_LINEAR:
- case GIMP_PRECISION_DOUBLE_NON_LINEAR:
- case GIMP_PRECISION_DOUBLE_PERCEPTUAL:
- grain_extract_mode = GIMP_LAYER_MODE_GRAIN_EXTRACT;
- grain_merge_mode = GIMP_LAYER_MODE_GRAIN_MERGE;
- break;
- }
+ scale_layers = g_new (GimpLayer *, wavelet_params.scales);
+ new_scale = gimp_layer_copy (GIMP_LAYER (drawable));
+ gimp_image_insert_layer (image, new_scale, parent,
+ gimp_image_get_item_position (image,
+ GIMP_ITEM (drawable)));
+
+ /* the exact result of the grain-extract and grain-merge modes
+ * depends on the choice of (gamma-corrected) midpoint intensity
+ * value. for the non-legacy modes, the midpoint value is 0.5,
+ * which isn't representable exactly using integer precision. for
+ * the legacy modes, the midpoint value is 128/255 (i.e., 0x80),
+ * which is representable exactly using (gamma-corrected) integer
+ * precision. we therefore use the legacy modes when the input
+ * image precision is integer, and only use the (preferable)
+ * non-legacy modes when the input image precision is floating
+ * point.
+ *
+ * this avoids imperfect reconstruction of the image when using
+ * integer precision. see bug #786844.
+ */
+ switch (gimp_image_get_precision (image))
+ {
+ case GIMP_PRECISION_U8_LINEAR:
+ case GIMP_PRECISION_U8_NON_LINEAR:
+ case GIMP_PRECISION_U8_PERCEPTUAL:
+ case GIMP_PRECISION_U16_LINEAR:
+ case GIMP_PRECISION_U16_NON_LINEAR:
+ case GIMP_PRECISION_U16_PERCEPTUAL:
+ case GIMP_PRECISION_U32_LINEAR:
+ case GIMP_PRECISION_U32_NON_LINEAR:
+ case GIMP_PRECISION_U32_PERCEPTUAL:
+ grain_extract_mode = GIMP_LAYER_MODE_GRAIN_EXTRACT_LEGACY;
+ grain_merge_mode = GIMP_LAYER_MODE_GRAIN_MERGE_LEGACY;
+ break;
- for (id = 0 ; id < wavelet_params.scales; ++id)
- {
- gint32 blur_id, tmp_id;
- gchar scale_name[20];
+ case GIMP_PRECISION_HALF_LINEAR:
+ case GIMP_PRECISION_HALF_NON_LINEAR:
+ case GIMP_PRECISION_HALF_PERCEPTUAL:
+ case GIMP_PRECISION_FLOAT_LINEAR:
+ case GIMP_PRECISION_FLOAT_NON_LINEAR:
+ case GIMP_PRECISION_FLOAT_PERCEPTUAL:
+ case GIMP_PRECISION_DOUBLE_LINEAR:
+ case GIMP_PRECISION_DOUBLE_NON_LINEAR:
+ case GIMP_PRECISION_DOUBLE_PERCEPTUAL:
+ grain_extract_mode = GIMP_LAYER_MODE_GRAIN_EXTRACT;
+ grain_merge_mode = GIMP_LAYER_MODE_GRAIN_MERGE;
+ break;
+ }
- gimp_progress_update ((gdouble) id / (gdouble) wavelet_params.scales);
+ for (id = 0 ; id < wavelet_params.scales; id++)
+ {
+ GimpLayer *blur;
+ GimpLayer *tmp;
+ gchar scale_name[20];
- scale_ids[id] = new_scale_id;
+ gimp_progress_update ((gdouble) id / (gdouble) wavelet_params.scales);
- g_snprintf (scale_name, sizeof (scale_name), _("Scale %d"), id + 1);
- gimp_item_set_name (new_scale_id, scale_name);
+ scale_layers[id] = new_scale;
- tmp_id = gimp_layer_copy (new_scale_id);
- gimp_image_insert_layer (image_id, tmp_id, parent_id,
- gimp_image_get_item_position (image_id,
- new_scale_id));
- wavelet_blur (tmp_id, pow(2.0, id));
+ g_snprintf (scale_name, sizeof (scale_name), _("Scale %d"), id + 1);
+ gimp_item_set_name (GIMP_ITEM (new_scale), scale_name);
- blur_id = gimp_layer_copy (tmp_id);
- gimp_image_insert_layer (image_id, blur_id, parent_id,
- gimp_image_get_item_position (image_id,
- tmp_id));
+ tmp = gimp_layer_copy (new_scale);
+ gimp_image_insert_layer (image, tmp, parent,
+ gimp_image_get_item_position (image,
+ GIMP_ITEM (new_scale)));
+ wavelet_blur (GIMP_DRAWABLE (tmp), pow (2.0, id));
- gimp_layer_set_mode (tmp_id, grain_extract_mode);
- new_scale_id = gimp_image_merge_down (image_id, tmp_id,
- GIMP_EXPAND_AS_NECESSARY);
- scale_ids[id] = new_scale_id;
+ blur = gimp_layer_copy (tmp);
+ gimp_image_insert_layer (image, blur, parent,
+ gimp_image_get_item_position (image,
+ GIMP_ITEM (tmp)));
- gimp_item_set_visible (new_scale_id, FALSE);
+ gimp_layer_set_mode (tmp, grain_extract_mode);
+ new_scale = gimp_image_merge_down (image, tmp,
+ GIMP_EXPAND_AS_NECESSARY);
+ scale_layers[id] = new_scale;
- new_scale_id = blur_id;
- }
+ gimp_item_set_visible (GIMP_ITEM (new_scale), FALSE);
+
+ new_scale = blur;
+ }
+
+ gimp_item_set_name (GIMP_ITEM (new_scale), _("Residual"));
- gimp_item_set_name (new_scale_id, _("Residual"));
+ for (id = 0; id < wavelet_params.scales; id++)
+ {
+ gimp_image_reorder_item (image, GIMP_ITEM (scale_layers[id]),
+ GIMP_ITEM (parent),
+ gimp_image_get_item_position (image,
+ GIMP_ITEM (new_scale)));
+ gimp_layer_set_mode (scale_layers[id], grain_merge_mode);
- for (id = 0; id < wavelet_params.scales; id++)
+ if (wavelet_params.create_masks)
{
- gimp_image_reorder_item (image_id, scale_ids[id], parent_id,
- gimp_image_get_item_position (image_id,
- new_scale_id));
- gimp_layer_set_mode (scale_ids[id], grain_merge_mode);
-
- if (wavelet_params.create_masks)
- {
- gint32 mask_id = gimp_layer_create_mask (scale_ids[id],
- GIMP_ADD_MASK_WHITE);
- gimp_layer_add_mask (scale_ids[id], mask_id);
- }
-
- gimp_item_set_visible (scale_ids[id], TRUE);
+ GimpLayerMask *mask = gimp_layer_create_mask (scale_layers[id],
+ GIMP_ADD_MASK_WHITE);
+ gimp_layer_add_mask (scale_layers[id], mask);
}
- if (wavelet_params.create_group)
- gimp_item_set_visible (parent_id, TRUE);
+ gimp_item_set_visible (GIMP_ITEM (scale_layers[id]), TRUE);
+ }
- g_free (scale_ids);
+ if (wavelet_params.create_group)
+ gimp_item_set_visible (GIMP_ITEM (parent), TRUE);
- gimp_image_thaw_layers (image_id);
+ g_free (scale_layers);
- gimp_image_undo_group_end (image_id);
+ gimp_image_thaw_layers (image);
- gimp_progress_update (1.0);
+ gimp_image_undo_group_end (image);
- values[0].data.d_status = status;
- gimp_displays_flush ();
+ gimp_progress_update (1.0);
- /* set data for next use of filter */
- if (run_mode == GIMP_RUN_INTERACTIVE)
- gimp_set_data (PLUG_IN_PROC,
- &wavelet_params, sizeof (WaveletDecomposeParams));
- }
+ gimp_displays_flush ();
+
+ if (run_mode == GIMP_RUN_INTERACTIVE)
+ gimp_set_data (PLUG_IN_PROC,
+ &wavelet_params, sizeof (WaveletDecomposeParams));
gegl_exit ();
+
+ return gimp_procedure_new_return_values (procedure, GIMP_PDB_SUCCESS, NULL);
}
static void
-wavelet_blur (gint32 drawable_id,
- gint radius)
+wavelet_blur (GimpDrawable *drawable,
+ gint radius)
{
gint x, y, width, height;
- if (gimp_drawable_mask_intersect (drawable_id, &x, &y, &width, &height))
+ if (gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
- GeglBuffer *buffer = gimp_drawable_get_buffer (drawable_id);
- GeglBuffer *shadow = gimp_drawable_get_shadow_buffer (drawable_id);
+ GeglBuffer *buffer = gimp_drawable_get_buffer (drawable);
+ GeglBuffer *shadow = gimp_drawable_get_shadow_buffer (drawable);
gegl_render_op (buffer, shadow,
"gegl:wavelet-blur",
@@ -334,8 +361,8 @@ wavelet_blur (gint32 drawable_id,
NULL);
gegl_buffer_flush (shadow);
- gimp_drawable_merge_shadow (drawable_id, FALSE);
- gimp_drawable_update (drawable_id, x, y, width, height);
+ gimp_drawable_merge_shadow (drawable, FALSE);
+ gimp_drawable_update (drawable, x, y, width, height);
g_object_unref (buffer);
g_object_unref (shadow);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]