diff --git a/PluginScripts/plugin-heal-selection.py b/PluginScripts/plugin-heal-selection.py old mode 100644 new mode 100755 index f36bfdb..13e783d --- a/PluginScripts/plugin-heal-selection.py +++ b/PluginScripts/plugin-heal-selection.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/python3 ''' Gimp plugin "Heal selection" @@ -26,154 +26,252 @@ http://www.gnu.org/copyleft/gpl.html ''' +import gi +import sys -from gimpfu import * +gi.require_version('Gimp', '3.0') +gi.require_version('GimpUi', '3.0') -# Python 2 gettext.install("resynthesizer", Gimp.locale_directory(), unicode=True) -gettext.install("resynthesizer", Gimp.locale_directory()) +from gi.repository import GLib +from gi.repository import GObject +from gi.repository import Gimp +from gi.repository import GimpUi + +PLUGIN_NAME = 'resynthesizer-heal-selection' +def N_(message): return message +def _(message): return GLib.dgettext(None, message) debug = False -def heal_selection(timg, tdrawable, samplingRadiusParam=50, directionParam=0, orderParam=0): - ''' - Create stencil selection in a temp image to pass as source (corpus) to plugin resynthesizer, - which does the substantive work. - ''' - if pdb.gimp_selection_is_empty(timg): - pdb.gimp_message(_("You must first select a region to heal.")) - return +def dprint(s: str): + if debug: print(s) + +class HealSel (Gimp.PlugIn): + ## GimpPlugIn virtual methods ## + def do_set_i18n(self, procname): + return True, 'gimp30-python', None + + def do_query_procedures(self): + return [PLUGIN_NAME] + + def do_create_procedure(self, name): + if name == PLUGIN_NAME: + procedure: Gimp.ImageProcedure = Gimp.ImageProcedure.new(self, name, + Gimp.PDBProcType.PLUGIN, + self.run, None) + procedure.set_image_types("RGB*, GRAY*") + procedure.set_sensitivity_mask( + Gimp.ProcedureSensitivityMask.DRAWABLE) + procedure.set_documentation(_("resynthesizer heal selection"), + _("heal selection with the resynthesizer algorithm"), + name) + procedure.set_menu_label(_("_heal selection")) + procedure.set_attribution("James Henstridge", + "James Henstridge", + "1999,2007") + procedure.add_menu_path("/Filters/Enhance") + + procedure.add_int_argument( + name="samplingRadiusParam", + nick=_("Sampling radius"), + blurb=_("The sampling radius (in pixels)"), + min=1, + max=1000, + value=50, + flags=GObject.ParamFlags.READWRITE + ) + + direction_choice = Gimp.Choice.new() + + direction_choice.add("all_around", 0, _("All around"), "") + direction_choice.add("sides_only", 1, _("Sides only"), "") + direction_choice.add("above_and_below", 2, + _("Above and below only"), "") + + procedure.add_choice_argument("directionParam", _("Direct_ion"), _("Where to sample pixels from"), + direction_choice, "all_around", GObject.ParamFlags.READWRITE) + order_choice = Gimp.Choice.new() + order_choice.add("random", 0, _("Random"), "") + order_choice.add("inwards", 1, _("Inwards"), "") + order_choice.add("outwards", 2, _("Outwards"), "") + + procedure.add_choice_argument("orderParam", _("Order"), _("The order to fill the selection in"), + order_choice, "random", GObject.ParamFlags.READWRITE) + return procedure + return None + + def run(self, procedure: Gimp.Procedure, run_mode: Gimp.RunMode, image: Gimp.Image, layers, config, data): + if Gimp.Selection.is_empty(image): + Gimp.message("You must first select a region to heal.") + return procedure.new_return_values(Gimp.PDBStatusType.CALLING_ERROR, GLib.Error(None, None, "Select something first.")) + + if run_mode == Gimp.RunMode.INTERACTIVE: + GimpUi.init(PLUGIN_NAME) + dialog = GimpUi.ProcedureDialog(procedure=procedure, config=config) + dialog.fill(None) + if not dialog.run(): + dialog.destroy() + return procedure.new_return_values(Gimp.PDBStatusType.CANCEL, GLib.Error()) + else: + dialog.destroy() + + samplingRadius: int = config.get_property('samplingRadiusParam') + directionParam: str = config.get_property('directionParam') + order: str = config.get_property('orderParam') + + image.undo_group_start() + + # select the bounds of the bottom-most layer. + target_bounds = layers[0].mask_bounds() + + temp: Gimp.Image = image.duplicate() + + if not temp: + raise RuntimeError("Failed duplicate image") - pdb.gimp_image_undo_group_start(timg) + if debug: + try: + disp: Gimp.Display = Gimp.Display.new(image=temp) + Gimp.displays_flush() + except RuntimeError: # thrown if non-interactive + pass + from time import sleep + sleep(2) + + selected_drawables = temp.get_selected_drawables() + if len(selected_drawables) == 0: + raise RuntimeError("No drawables selected.") + + work_drawable: Gimp.Layer = selected_drawables[0] + if not work_drawable: + raise RuntimeError("Failed get active drawable") - targetBounds = tdrawable.mask_bounds + selection: Gimp.Selection = image.get_selection() - # In duplicate image, create the sample (corpus). - # (I tried to use a temporary layer but found it easier to use duplicate image.) - tempImage = pdb.gimp_image_duplicate(timg) - if not tempImage: - raise RuntimeError("Failed duplicate image") + orig_selection: Gimp.Channel = selection.save(temp) + if not selection.grow(temp, samplingRadius): + Gimp.message("Could not grow selection") + return procedure.new_return_values(Gimp.PDBStatusType.EXECUTION_ERROR, GLib.Error(None, None, "couldn't grow the selection somehow.")) - # !!! The drawable can be a mask (grayscale channel), don't restrict to layer. - work_drawable = pdb.gimp_image_get_active_drawable(tempImage) - if not work_drawable: - raise RuntimeError("Failed get active drawable") + # !!! Note that if selection is a bordering ring already, growing expanded it inwards. + # Which is what we want, to make a corpus inwards. + grown_selection: Gimp.Channel = selection.save(temp) + + # Cut hole where the original selection was, so we don't sample from it. + temp.select_item(Gimp.ChannelOps.SUBTRACT, orig_selection) + + # crop the temp image to size of selection to save memory and for directional healing!! + frisketBounds = grown_selection.mask_bounds() + frisketLowerLeftX = frisketBounds.x1 + frisketLowerLeftY = frisketBounds.y1 + frisketUpperRightX = frisketBounds.x2 + frisketUpperRightY = frisketBounds.y2 + + dprint(f"{frisketBounds=}") + + targetLowerLeftX = target_bounds.x1 + targetLowerLeftY = target_bounds.y1 + targetUpperRightX = target_bounds.x2 + targetUpperRightY = target_bounds.y2 - ''' - grow and punch hole, making a frisket iow stencil iow donut - - ''' - orgSelection = pdb.gimp_selection_save(tempImage) # save for later use - pdb.gimp_selection_grow(tempImage, samplingRadiusParam) - # ??? returns None , docs say it returns SUCCESS - - # !!! Note that if selection is a bordering ring already, growing expanded it inwards. - # Which is what we want, to make a corpus inwards. - - grownSelection = pdb.gimp_selection_save(tempImage) - - # Cut hole where the original selection was, so we don't sample from it. - # !!! Note that gimp enums/constants are not prefixed with GIMP_ - pdb.gimp_image_select_item(tempImage, CHANNEL_OP_SUBTRACT, orgSelection) - - ''' - Selection (to be the corpus) is donut or frisket around the original target T - xxx - xTx - xxx - ''' - - # crop the temp image to size of selection to save memory and for directional healing!! - frisketBounds = grownSelection.mask_bounds - frisketLowerLeftX = frisketBounds[0] - frisketLowerLeftY = frisketBounds[1] - frisketUpperRightX = frisketBounds[2] - frisketUpperRightY = frisketBounds[3] - targetLowerLeftX = targetBounds[0] - targetLowerLeftY = targetBounds[1] - targetUpperRightX = targetBounds[2] - targetUpperRightY = targetBounds[3] - - frisketWidth = frisketUpperRightX - frisketLowerLeftX - frisketHeight = frisketUpperRightY - frisketLowerLeftY - - # User's choice of direction affects the corpus shape, and is also passed to resynthesizer plugin - if directionParam == 0: # all around + dprint(f"{target_bounds=}") + + frisketWidth = frisketUpperRightX - frisketLowerLeftX + frisketHeight = frisketUpperRightY - frisketLowerLeftY + + dprint(f"{frisketWidth=}, {frisketHeight=}") + + newWidth, newHeight, newLLX, newLLY = (0, 0, 0, 0) + direction = 0 + # User's choice of direction affects the corpus shape, and is also passed to resynthesizer plugin + if directionParam == 'all_around': # all around + direction = 0 # Crop to the entire frisket - newWidth, newHeight, newLLX, newLLY = ( frisketWidth, frisketHeight, - frisketLowerLeftX, frisketLowerLeftY ) - elif directionParam == 1: # sides + newWidth, newHeight, newLLX, newLLY = ( + frisketWidth, + frisketHeight, + frisketLowerLeftX, + frisketLowerLeftY + ) + elif directionParam == 'sides_only': # sides + direction = 1 # Crop to target height and frisket width: XTX - newWidth, newHeight, newLLX, newLLY = ( frisketWidth, targetUpperRightY-targetLowerLeftY, - frisketLowerLeftX, targetLowerLeftY ) - elif directionParam == 2: # above and below + newWidth, newHeight, newLLX, newLLY = ( + frisketWidth, + targetUpperRightY-targetLowerLeftY, + frisketLowerLeftX, + targetLowerLeftY + ) + elif directionParam == 'above_and_below': # above and below + direction = 2 # X Crop to target width and frisket height # T # X - newWidth, newHeight, newLLX, newLLY = ( targetUpperRightX-targetLowerLeftX, frisketHeight, - targetLowerLeftX, frisketLowerLeftY ) - # Restrict crop to image size (condition of gimp_image_crop) eg when off edge of image - newWidth = min(pdb.gimp_image_width(tempImage) - newLLX, newWidth) - newHeight = min(pdb.gimp_image_height(tempImage) - newLLY, newHeight) - pdb.gimp_image_crop(tempImage, newWidth, newHeight, newLLX, newLLY) - - # Encode two script params into one resynthesizer param. - # use border 1 means fill target in random order - # use border 0 is for texture mapping operations, not used by this script - if not orderParam : + newWidth, newHeight, newLLX, newLLY = ( + targetUpperRightX-targetLowerLeftX, + frisketHeight, + targetLowerLeftX, + frisketLowerLeftY + ) + + dprint(f"{newWidth=} {newHeight=} {newLLX=} {newLLY=}") + + # Restrict crop to image size (condition of gimp_image_crop) eg when off edge of image + newWidth = min(temp.get_width() - newLLX, newWidth) + newHeight = min(temp.get_height() - newLLY, newHeight) + + dprint(f"resized {newWidth=} {newHeight=}") + + temp.crop(newWidth, newHeight, newLLX, newLLY) + + # default, just to declare the value. + useBorder = 1 + + # Encode two script params into one resynthesizer param. + # use border 1 means fill target in random order + # use border 0 is for texture mapping operations, not used by this script + if order == 'random': useBorder = 1 # User wants NO order, ie random filling - elif orderParam == 1 : # Inward to corpus. 2,3,4 - useBorder = directionParam+2 # !!! Offset by 2 to get past the original two boolean values - else: + elif order == 'inwards': # Inward to corpus. 2,3,4 + # !!! Offset by 2 to get past the original two boolean values + useBorder = direction + 2 + else: # Outward from image center. # 5+0=5 outward concentric # 5+1=6 outward from sides # 5+2=7 outward above and below - useBorder = directionParam+5 - - # Note that the old resynthesizer required an inverted selection !! - - if debug: - try: - gimp.Display(tempImage) - gimp.displays_flush() - except RuntimeError: # thrown if non-interactive - pass - from time import sleep - sleep(2) - - # Not necessary to restore image to initial condition of selection, activity, - # the original image should not have been changed, - # and the resynthesizer should only heal, not change selection. - - # Note that the API hasn't changed but use_border param now has more values. - pdb.plug_in_resynthesizer(timg, tdrawable, 0,0, useBorder, work_drawable, -1, -1, 0.0, 0.117, 16, 500) - - # Clean up (comment out to debug) - gimp.delete(tempImage) - pdb.gimp_image_undo_group_end(timg) - - -register( - "python-fu-heal-selection", - N_("Heal the selection from surroundings as if using the heal tool."), - "Requires separate resynthesizer plugin.", - "Lloyd Konneker", - "2009 Lloyd Konneker", # Copyright - "2009", - N_("_Heal selection..."), - "RGB*, GRAY*", - [ - (PF_IMAGE, "image", "Input image", None), - (PF_DRAWABLE, "drawable", "Input drawable", None), - (PF_INT, "samplingRadiusParam", _("Context sampling width (pixels):"), 50), - (PF_OPTION,"directionParam", _("Sample from:"),0,[_("All around"),_("Sides"),_("Above and below")]), - (PF_OPTION, "orderParam", _("Filling order:"), 0, [_("Random"), - _("Inwards towards center"), _("Outwards from center") ]) - ], - [], - heal_selection, - menu="/Filters/Enhance", - domain=("resynthesizer", Gimp.locale_directory()) - ) - -main() + useBorder = direction + 5 + + # Note that the old resynthesizer required an inverted selection !! + + # Not necessary to restore image to initial condition of selection, activity, + # the original image should not have been changed, + # and the resynthesizer should only heal, not change selection. + + # Note that the API hasn't changed but use_border param now has more values. + pdb: Gimp.PDB = Gimp.get_pdb() + pdb_proc: Gimp.Procedure = pdb.lookup_procedure('plug-in-resynthesizer') + pdb_config: Gimp.ProcedureConfig = pdb_proc.create_config() + pdb_config.set_property('run-mode', Gimp.RunMode.NONINTERACTIVE) + pdb_config.set_property('image', image) + # A hacky way to pass in python arrays directly, + # see: https://gitlab.gnome.org/GNOME/gobject-introspection/-/issues/492 + pdb_config.set_core_object_array('drawables', layers) + pdb_config.set_property('h-tile', 0) + pdb_config.set_property('v-tile', 0) + pdb_config.set_property('use-border', useBorder) + pdb_config.set_property('corpus-drawable', work_drawable) + pdb_config.set_property('input-map', None) + pdb_config.set_property('output-map', None) + pdb_config.set_property('map-weight', 0.0) + pdb_config.set_property('autism', 0.117) + pdb_config.set_property('neighbours', 16) + pdb_config.set_property('trys', 500) + pdb_proc.run(pdb_config) + + # Clean up (comment out to debug) + temp.delete() + image.undo_group_end() + return procedure.new_return_values(Gimp.PDBStatusType.SUCCESS, GLib.Error()) + +Gimp.main(HealSel.__gtype__, sys.argv) diff --git a/src/resynth-parameters.h b/src/resynth-parameters.h old mode 100644 new mode 100755 index 4da53ac..95b24a4 --- a/src/resynth-parameters.h +++ b/src/resynth-parameters.h @@ -27,6 +27,9 @@ to the adapter from Gimp to the innermost engine. !!! v2 */ +#if GIMP_MAJOR_VERSION == 2 && GIMP_MINOR_VERSION < 99 + + typedef struct GIMPAdapterParametersStructOld { int h_tile; @@ -281,6 +284,6 @@ set_parameters_to_list( } } - +#endif diff --git a/src/resynthesizer-gui/resynth-gui.c b/src/resynthesizer-gui/resynth-gui.c old mode 100644 new mode 100755 index d03615c..d647b08 --- a/src/resynthesizer-gui/resynth-gui.c +++ b/src/resynthesizer-gui/resynth-gui.c @@ -46,10 +46,11 @@ #include "../resynthesizer/pluginParams.h" #include "../resynth-parameters.h" +#if GIMP_MAJOR_VERSION == 2 && GIMP_MINOR_VERSION < 99 + /* Resynthesizer GUI gtk code: ask user for parameters. */ #include "resynth-gui.h" - static void run( const gchar * name, gint nparams, // !!! Always 3 for INTERACTIVE, not lengthof(param)? @@ -182,3 +183,4 @@ static GimpPlugInInfo PLUG_IN_INFO = { /* Macro to define the usual plugin main function */ MAIN() +#endif \ No newline at end of file diff --git a/src/resynthesizer-gui/resynth-gui.h b/src/resynthesizer-gui/resynth-gui.h old mode 100644 new mode 100755 diff --git a/src/resynthesizer/debug.c b/src/resynthesizer/debug.c old mode 100644 new mode 100755 index dbb2e67..070b500 --- a/src/resynthesizer/debug.c +++ b/src/resynthesizer/debug.c @@ -8,6 +8,6 @@ void debug(const char * message) { - g_printerr(message); - g_printerr("\n"); + g_warning(message); + g_warning("\n"); } diff --git a/src/resynthesizer/drawable.c b/src/resynthesizer/drawable.c old mode 100644 new mode 100755 index 0301fea..a63d9fc --- a/src/resynthesizer/drawable.c +++ b/src/resynthesizer/drawable.c @@ -7,7 +7,7 @@ // hacky test that version is less than 2.99.xx -#if GIMP_MINOR_VERSION < 99 +#if GIMP_MINOR_VERSION < 99 && GIMP_MAJOR_VERSION == 2 gint bpp (GimpDrawable *d) { return d->bpp; } @@ -142,7 +142,7 @@ get_selection(GimpDrawable * d) // selection is a new drawable derived from image of a drawable // TODO this is not right for v3 ?? // return gimp_image_get_selection(gimp_item_get_image(d->drawable_id)); - return gimp_image_get_selection(gimp_item_get_image(d)); + return (GimpDrawable *) gimp_image_get_selection(gimp_item_get_image((GimpItem *)d)); } gboolean diff --git a/src/resynthesizer/plugin.c b/src/resynthesizer/plugin.c old mode 100644 new mode 100755 index b6bf863..2261416 --- a/src/resynthesizer/plugin.c +++ b/src/resynthesizer/plugin.c @@ -7,10 +7,8 @@ #include "debug.h" - - // hacky test that version is less than 2.99.xx -#if GIMP_MINOR_VERSION < 99 +#if GIMP_MAJOR_VERSION == 2 && GIMP_MINOR_VERSION < 99 #include "pluginParams.h" diff --git a/src/resynthesizer/pluginParams.c b/src/resynthesizer/pluginParams.c old mode 100644 new mode 100755 index 9e79818..261a1af --- a/src/resynthesizer/pluginParams.c +++ b/src/resynthesizer/pluginParams.c @@ -10,7 +10,7 @@ // hacky test that version is less than 2.99.xx -#if GIMP_MINOR_VERSION < 99 +#if GIMP_MAJOR_VERSION == 2 && GIMP_MINOR_VERSION < 99 // in v2 gimp API, params are array of GimpParam @@ -79,28 +79,27 @@ CRUFT -// in v3 gimp API, params are a GimpValueArray +// in v3 gimp API, params are passed through a ProcedureConfig gboolean get_engine_specific_parameters( - GimpValueArray *args, // IN + GimpProcedureConfig *args, // IN TGimpAdapterParameters *pluginParameters) // OUT { - // Fails to compile: - // g_assert( args->length() == 10 ); - - // args does not have prefix: run mode, image, drawable - pluginParameters->h_tile = GIMP_VALUES_GET_BOOLEAN (args, 0); - // debug("here"); - pluginParameters->v_tile = GIMP_VALUES_GET_BOOLEAN (args, 1); - pluginParameters->use_border = GIMP_VALUES_GET_INT (args, 2); - pluginParameters->corpus = GIMP_VALUES_GET_DRAWABLE (args, 3); - pluginParameters->input_map = GIMP_VALUES_GET_DRAWABLE (args, 4); - pluginParameters->output_map = GIMP_VALUES_GET_DRAWABLE (args, 5); - pluginParameters->map_weight = GIMP_VALUES_GET_DOUBLE (args, 6); - pluginParameters->autism = GIMP_VALUES_GET_DOUBLE (args, 7); - pluginParameters->neighbours = GIMP_VALUES_GET_INT (args, 8); - pluginParameters->trys = GIMP_VALUES_GET_INT (args, 9); + g_object_get(args, + "h_tile", &pluginParameters->h_tile, + "v_tile", &pluginParameters->v_tile, + "use_border", &pluginParameters->use_border, + "corpus_drawable", &pluginParameters->corpus, + "input_map", &pluginParameters->input_map, + "output_map", &pluginParameters->output_map, + "map_weight", &pluginParameters->map_weight, + "autism", &pluginParameters->autism, + "neighbours", &pluginParameters->neighbours, + "trys", &pluginParameters->trys, + NULL + ); + return TRUE; } diff --git a/src/resynthesizer/pluginParams.h b/src/resynthesizer/pluginParams.h old mode 100644 new mode 100755 index 028f75d..73a2558 --- a/src/resynthesizer/pluginParams.h +++ b/src/resynthesizer/pluginParams.h @@ -29,7 +29,7 @@ typedef struct GIMPAdapterParametersStruct { -#if GIMP_MINOR_VERSION < 99 +#if GIMP_MAJOR_VERSION == 2 && GIMP_MINOR_VERSION < 99 @@ -50,7 +50,7 @@ get_engine_specific_parameters( gboolean get_engine_specific_parameters( - GimpValueArray *args, // IN // <<<<< + GimpProcedureConfig *args, // IN // <<<<< TGimpAdapterParameters *pluginParameters); // OUT diff --git a/src/resynthesizer/resynthPDBv3.h b/src/resynthesizer/resynthPDBv3.h old mode 100644 new mode 100755 index 21f2ec0..9ca4625 --- a/src/resynthesizer/resynthPDBv3.h +++ b/src/resynthesizer/resynthPDBv3.h @@ -72,8 +72,8 @@ static GimpProcedure * resynthesizer_create_procedure (GimpPlugIn *pl static GimpValueArray * resynthesizer_run (GimpProcedure *procedure, GimpRunMode run_mode, GimpImage *image, - GimpDrawable *drawable, - const GimpValueArray *args, + GimpDrawable **drawables, + GimpProcedureConfig *args, gpointer run_data); @@ -124,10 +124,6 @@ resynthesizer_create_procedure (GimpPlugIn *plug_in, // plugin is an engine, without GUI. // No need for image_types, menu_label, icon_name, menu_path - //gimp_procedure_set_image_types (procedure, "RGB GRAY"); - //gimp_procedure_set_menu_label (procedure, N_("Exercise in _C minor")); - //gimp_procedure_set_icon_name (procedure, GIMP_ICON_GEGL); - //gimp_procedure_add_menu_path (procedure, "/Filters/Development/Resynthesizer exercises/"); gimp_procedure_set_documentation (procedure, N_("Resynthesizer engine"), @@ -138,52 +134,52 @@ resynthesizer_create_procedure (GimpPlugIn *plug_in, "Lloyd Konneker", "2021"); - GIMP_PROC_ARG_BOOLEAN (procedure, "h_tile", + gimp_procedure_add_boolean_argument (procedure, "h_tile", "Create image tileable horizontally?", "Boolean", FALSE, G_PARAM_READWRITE); - GIMP_PROC_ARG_BOOLEAN (procedure, "v_tile", + gimp_procedure_add_boolean_argument (procedure, "v_tile", "Create image tileable vertically?", "Boolean", FALSE, G_PARAM_READWRITE); - GIMP_PROC_ARG_INT (procedure, "use_border", + gimp_procedure_add_int_argument (procedure, "use_border", "Enumerated order/directions of synthesis", "See documents.", 0, 100, 1, // TODO what is the real range G_PARAM_READWRITE); - GIMP_PROC_ARG_DRAWABLE (procedure, "corpus_drawable", + gimp_procedure_add_drawable_argument (procedure, "corpus_drawable", "Image to search", "Usually the surroundings of target.", TRUE, G_PARAM_READWRITE); - GIMP_PROC_ARG_DRAWABLE (procedure, "input_map", + gimp_procedure_add_drawable_argument (procedure, "input_map", "Map of weightings for target.", "Same size as target.", TRUE, G_PARAM_READWRITE); - GIMP_PROC_ARG_DRAWABLE (procedure, "output_map", + gimp_procedure_add_drawable_argument (procedure, "output_map", "Map of weightings for corpus.", "Same size as corpus.", TRUE, G_PARAM_READWRITE); - GIMP_PROC_ARG_DOUBLE (procedure, "map_weight", + gimp_procedure_add_double_argument (procedure, "map_weight", "Weighting for any in and out maps", "How much to use maps while matching.", 0.0, 1.0, 0.5, G_PARAM_READWRITE); - GIMP_PROC_ARG_DOUBLE (procedure, "autism", + gimp_procedure_add_double_argument (procedure, "autism", "Sensitivity to outliers of distance measure", "Parameter of distance measure", 0.0, 1.0, 0.117, G_PARAM_READWRITE); - GIMP_PROC_ARG_INT (procedure, "neighbours", + gimp_procedure_add_int_argument (procedure, "neighbours", "Count of pixels in a patch", "More is high quality but slow", 1, 100, 9, G_PARAM_READWRITE); - GIMP_PROC_ARG_INT (procedure, "trys", + gimp_procedure_add_int_argument (procedure, "trys", "Max search probes per pass", "More is high quality but slow", 1, 10000, 200, @@ -204,7 +200,7 @@ resynthesizer_create_procedure (GimpPlugIn *plug_in, static GError * new_gerror_for_resynthesizer_and_string(const char * msg) { - GQuark * domain = g_quark_from_string("Resynthesizer"); + GQuark domain = g_quark_from_string("Resynthesizer"); return g_error_new_literal(domain, 0, msg); } @@ -215,27 +211,24 @@ Adapts to a generic resynthesizer plugin. Liable to change as GIMP plugin API changes. */ // API for Gimp-3.0 - - static GimpValueArray * resynthesizer_run ( GimpProcedure *procedure, GimpRunMode run_mode, GimpImage *image, - GimpDrawable *drawable, - const GimpValueArray *args, + GimpDrawable **drawables, + GimpProcedureConfig *args, gpointer run_data) { + GimpDrawable *drawable = drawables[0]; GimpPDBStatusType status = GIMP_PDB_SUCCESS; const char *result; // inner result const gchar *name = gimp_procedure_get_name (procedure); TGimpAdapterParameters pluginParameters; - // INIT_I18N(); - - // if (! strcmp (name, RECOMPOSE_PROC)) return foo - - if ( ! get_engine_specific_parameters(args, &pluginParameters) ) + if (drawable == NULL) { + result = _("Resynthesizer didn't get an image."); + } else if ( ! get_engine_specific_parameters(args, &pluginParameters) ) result = _("Resynthesizer failed to get parameters."); else result = inner_run( diff --git a/src/resynthesizer/resynthesizer.c b/src/resynthesizer/resynthesizer.c old mode 100644 new mode 100755 index 0ba2c4e..872f84f --- a/src/resynthesizer/resynthesizer.c +++ b/src/resynthesizer/resynthesizer.c @@ -314,7 +314,6 @@ inner_run( #ifdef DEBUG gimp_message_set_handler(1); // To console instead of GUI - start_time = clock(); #endif // internationalization i18n