From f4d0c8834a868f162de745d28f92cf6fd0f4b667 Mon Sep 17 00:00:00 2001 From: Michael Natterer Date: Fri, 30 Aug 2019 14:27:33 +0200 Subject: [PATCH] plug-ins: port contrast-retinex to GimpPlugIn --- plug-ins/common/contrast-retinex.c | 237 +++++++++++++++++------------ 1 file changed, 137 insertions(+), 100 deletions(-) diff --git a/plug-ins/common/contrast-retinex.c b/plug-ins/common/contrast-retinex.c index 0b3cb5781d..ad9ed5221e 100644 --- a/plug-ins/common/contrast-retinex.c +++ b/plug-ins/common/contrast-retinex.c @@ -70,17 +70,36 @@ typedef struct } gauss3_coefs; -/* - * 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 _Retinex Retinex; +typedef struct _RetinexClass RetinexClass; + +struct _Retinex +{ + GimpPlugIn parent_instance; +}; + +struct _RetinexClass +{ + GimpPlugInClass parent_class; +}; + + +#define RETINEX_TYPE (retinex_get_type ()) +#define RETINEX (obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RETINEX_TYPE, Retinex)) + +GType retinex_get_type (void) G_GNUC_CONST; + +static GList * retinex_query_procedures (GimpPlugIn *plug_in); +static GimpProcedure * retinex_create_procedure (GimpPlugIn *plug_in, + const gchar *name); + +static GimpValueArray * retinex_run (GimpProcedure *procedure, + GimpRunMode run_mode, + GimpImage *image, + GimpDrawable *drawable, + const GimpValueArray *args, + gpointer run_data); -/* Gimp */ static gboolean retinex_dialog (GimpDrawable *drawable); static void retinex (GimpDrawable *drawable, GimpPreview *preview); @@ -97,9 +116,7 @@ static void compute_mean_var (gfloat *src, gfloat *var, gint size, gint bytes); -/* - * Gauss - */ + static void compute_coefs3 (gauss3_coefs *c, gfloat sigma); @@ -119,9 +136,11 @@ static void MSRCR (guchar *src, gboolean preview_mode); -/* - * Private variables. - */ +G_DEFINE_TYPE (Retinex, retinex, GIMP_TYPE_PLUG_IN) + +GIMP_MAIN (RETINEX_TYPE) + + static RetinexParams rvals = { 240, /* Scale */ @@ -130,111 +149,129 @@ static RetinexParams rvals = 1.2 /* A voir */ }; -static GimpPlugInInfo PLUG_IN_INFO = -{ - NULL, /* init_proc */ - NULL, /* quit_proc */ - query, /* query_proc */ - run, /* run_proc */ -}; - -MAIN () static void -query (void) +retinex_class_init (RetinexClass *klass) { - 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, "scale", "Biggest scale value" }, - { GIMP_PDB_INT32, "nscales", "Number of scales" }, - { GIMP_PDB_INT32, "scales-mode", "Retinex distribution through scales" }, - { GIMP_PDB_FLOAT, "cvar", "Variance value" } - }; + GimpPlugInClass *plug_in_class = GIMP_PLUG_IN_CLASS (klass); - gimp_install_procedure (PLUG_IN_PROC, - N_("Enhance contrast using the Retinex method"), - "The Retinex Image Enhancement Algorithm is an " - "automatic image enhancement method that enhances " - "a digital image in terms of dynamic range " - "compression, color independence from the spectral " - "distribution of the scene illuminant, and " - "color/lightness rendition.", - "Fabien Pelisson", - "Fabien Pelisson", - "2003", - N_("Retine_x..."), - "RGB*", - GIMP_PDB_PROC_TYPE_PLUGIN, - G_N_ELEMENTS (args), 0, - args, NULL); - - gimp_plugin_menu_register (PLUG_IN_PROC, "/Colors/Tone Mapping"); + plug_in_class->query_procedures = retinex_query_procedures; + plug_in_class->create_procedure = retinex_create_procedure; } static void -run (const gchar *name, - gint nparams, - const GimpParam *param, - gint *nreturn_vals, - GimpParam **return_vals) +retinex_init (Retinex *retinex) { - static GimpParam values[1]; - GimpRunMode run_mode; - GimpDrawable *drawable; - gint32 drawable_ID; - GimpPDBStatusType status = GIMP_PDB_SUCCESS; - gint x, y, width, height; +} + +static GList * +retinex_query_procedures (GimpPlugIn *plug_in) +{ + return g_list_append (NULL, g_strdup (PLUG_IN_PROC)); +} + +static GimpProcedure * +retinex_create_procedure (GimpPlugIn *plug_in, + const gchar *name) +{ + GimpProcedure *procedure = NULL; + + if (! strcmp (name, PLUG_IN_PROC)) + { + procedure = gimp_image_procedure_new (plug_in, name, + GIMP_PDB_PROC_TYPE_PLUGIN, + retinex_run, NULL, NULL); + + gimp_procedure_set_image_types (procedure, "RGB*"); + + gimp_procedure_set_menu_label (procedure, N_("Retine_x...")); + gimp_procedure_add_menu_path (procedure, "/Colors/Tone Mapping"); + + gimp_procedure_set_documentation (procedure, + N_("Enhance contrast using the " + "Retinex method"), + "The Retinex Image Enhancement " + "Algorithm is an automatic image " + "enhancement method that enhances " + "a digital image in terms of dynamic " + "range compression, color independence " + "from the spectral distribution of the " + "scene illuminant, and color/lightness " + "rendition.", + name); + gimp_procedure_set_attribution (procedure, + "Fabien Pelisson", + "Fabien Pelisson", + "2003"); + + GIMP_PROC_ARG_INT (procedure, "scale", + "Scale", + "Biggest scale value", + MIN_GAUSSIAN_SCALE, MAX_GAUSSIAN_SCALE, 240, + G_PARAM_READWRITE); + + GIMP_PROC_ARG_INT (procedure, "nscales", + "N scales", + "Number of scales", + 0, MAX_RETINEX_SCALES, 3, + G_PARAM_READWRITE); + + GIMP_PROC_ARG_INT (procedure, "scales-mode", + "Scales mode", + "Retinex distribution through scales", + RETINEX_UNIFORM, RETINEX_HIGH, RETINEX_UNIFORM, + G_PARAM_READWRITE); + + GIMP_PROC_ARG_DOUBLE (procedure, "cvar", + "Cvar", + "Variance value", + 0, 4, 1.2, + G_PARAM_READWRITE); + } + + return procedure; +} + +static GimpValueArray * +retinex_run (GimpProcedure *procedure, + GimpRunMode run_mode, + GimpImage *image, + GimpDrawable *drawable, + const GimpValueArray *args, + gpointer run_data) +{ + gint x, y, width, height; INIT_I18N (); gegl_init (NULL, NULL); - *nreturn_vals = 1; - *return_vals = values; - - values[0].type = GIMP_PDB_STATUS; - values[0].data.d_status = status; - - run_mode = param[0].data.d_int32; - drawable_ID = param[2].data.d_drawable; - drawable = GIMP_DRAWABLE (gimp_item_get_by_id (drawable_ID)); - - if (! gimp_drawable_mask_intersect (drawable, - &x, &y, &width, &height) || + if (! gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height) || width < MIN_GAUSSIAN_SCALE || height < MIN_GAUSSIAN_SCALE) { - status = GIMP_PDB_EXECUTION_ERROR; - values[0].data.d_status = status; - return; + return gimp_procedure_new_return_values (procedure, + GIMP_PDB_EXECUTION_ERROR, + NULL); } switch (run_mode) { case GIMP_RUN_INTERACTIVE: - /* Possibly retrieve data */ gimp_get_data (PLUG_IN_PROC, &rvals); - /* First acquire information with a dialog */ if (! retinex_dialog (drawable)) - return; + { + return gimp_procedure_new_return_values (procedure, + GIMP_PDB_CANCEL, + NULL); + } break; case GIMP_RUN_NONINTERACTIVE: - /* Make sure all the arguments are there! */ - if (nparams != 7) - { - status = GIMP_PDB_CALLING_ERROR; - } - else - { - rvals.scale = (param[3].data.d_int32); - rvals.nscales = (param[4].data.d_int32); - rvals.scales_mode = (param[5].data.d_int32); - rvals.cvar = (param[6].data.d_float); - } + rvals.scale = GIMP_VALUES_GET_INT (args, 0); + rvals.nscales = GIMP_VALUES_GET_INT (args, 1); + rvals.scales_mode = GIMP_VALUES_GET_INT (args, 2); + rvals.cvar = GIMP_VALUES_GET_DOUBLE (args, 3); break; case GIMP_RUN_WITH_LAST_VALS: @@ -245,8 +282,7 @@ run (const gchar *name, break; } - if (status == GIMP_PDB_SUCCESS && - (gimp_drawable_is_rgb (drawable))) + if (gimp_drawable_is_rgb (drawable)) { gimp_progress_init (_("Retinex")); @@ -255,16 +291,17 @@ run (const gchar *name, if (run_mode != GIMP_RUN_NONINTERACTIVE) gimp_displays_flush (); - /* Store data */ if (run_mode == GIMP_RUN_INTERACTIVE) gimp_set_data (PLUG_IN_PROC, &rvals, sizeof (RetinexParams)); } else { - status = GIMP_PDB_EXECUTION_ERROR; + return gimp_procedure_new_return_values (procedure, + GIMP_PDB_EXECUTION_ERROR, + NULL); } - values[0].data.d_status = status; + return gimp_procedure_new_return_values (procedure, GIMP_PDB_SUCCESS, NULL); }