From b7cf8506719bf51126361d22e49ffab4dd1ca404 Mon Sep 17 00:00:00 2001 From: Michael Natterer Date: Fri, 19 Jul 2019 17:35:13 +0200 Subject: [PATCH] plug-ins: remove the oilify plug-in and add a PDB compat procedure --- app/pdb/internal-procs.c | 2 +- app/pdb/plug-in-compat-cmds.c | 223 ++++++++ pdb/groups/plug_in_compat.pdb | 165 +++++- plug-ins/common/.gitignore | 2 - plug-ins/common/Makefile.am | 19 - plug-ins/common/gimprc.common | 1 - plug-ins/common/oilify.c | 945 --------------------------------- plug-ins/common/plugin-defs.pl | 1 - po-plug-ins/POTFILES.in | 1 - 9 files changed, 369 insertions(+), 990 deletions(-) delete mode 100644 plug-ins/common/oilify.c diff --git a/app/pdb/internal-procs.c b/app/pdb/internal-procs.c index 113c95cae2..3db3f2bff3 100644 --- a/app/pdb/internal-procs.c +++ b/app/pdb/internal-procs.c @@ -28,7 +28,7 @@ #include "internal-procs.h" -/* 743 procedures registered total */ +/* 745 procedures registered total */ void internal_procs_init (GimpPDB *pdb) diff --git a/app/pdb/plug-in-compat-cmds.c b/app/pdb/plug-in-compat-cmds.c index e381dba867..937d3ca486 100644 --- a/app/pdb/plug-in-compat-cmds.c +++ b/app/pdb/plug-in-compat-cmds.c @@ -2910,6 +2910,115 @@ plug_in_nova_invoker (GimpProcedure *procedure, error ? *error : NULL); } +static GimpValueArray * +plug_in_oilify2_invoker (GimpProcedure *procedure, + Gimp *gimp, + GimpContext *context, + GimpProgress *progress, + const GimpValueArray *args, + GError **error) +{ + gboolean success = TRUE; + GimpDrawable *drawable; + gint32 mask_size; + gint32 mode; + + drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp); + mask_size = g_value_get_int (gimp_value_array_index (args, 3)); + mode = g_value_get_int (gimp_value_array_index (args, 4)); + + if (success) + { + if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, + GIMP_PDB_ITEM_CONTENT, error) && + gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error)) + { + GeglNode *node; + + node = gegl_node_new_child (NULL, + "operation", "gegl:oilify", + "mask-radius", MAX (1, mask_size / 2), + "use-inten", mode ? TRUE : FALSE, + NULL); + + gimp_drawable_apply_operation (drawable, progress, + C_("undo-type", "Oilify"), + node); + g_object_unref (node); + } + else + success = FALSE; + } + + return gimp_procedure_get_return_values (procedure, success, + error ? *error : NULL); +} + +static GimpValueArray * +plug_in_oilify_enhanced2_invoker (GimpProcedure *procedure, + Gimp *gimp, + GimpContext *context, + GimpProgress *progress, + const GimpValueArray *args, + GError **error) +{ + gboolean success = TRUE; + GimpDrawable *drawable; + gint32 mode; + gint32 mask_size; + GimpDrawable *mask_size_map; + gint32 exponent; + GimpDrawable *exponent_map; + + drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp); + mode = g_value_get_int (gimp_value_array_index (args, 3)); + mask_size = g_value_get_int (gimp_value_array_index (args, 4)); + mask_size_map = gimp_value_get_drawable (gimp_value_array_index (args, 5), gimp); + exponent = g_value_get_int (gimp_value_array_index (args, 6)); + exponent_map = gimp_value_get_drawable (gimp_value_array_index (args, 7), gimp); + + if (success) + { + if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, + GIMP_PDB_ITEM_CONTENT, error) && + gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error)) + { + GeglNode *node; + + node = gegl_node_new_child (NULL, + "operation", "gegl:oilify", + "mask-radius", MAX (1, mask_size / 2), + "use-inten", mode ? TRUE : FALSE, + "exponent", exponent, + NULL); + + if (mask_size_map) + { + GeglNode *src_node; + src_node = create_buffer_source_node (node, mask_size_map); + gegl_node_connect_to (src_node, "output", node, "aux"); + } + + if (exponent_map) + { + GeglNode *src_node; + src_node = create_buffer_source_node (node, exponent_map); + gegl_node_connect_to (src_node, "output", node, "aux2"); + } + + gimp_drawable_apply_operation (drawable, progress, + C_("undo-type", "Oilify"), + node); + g_object_unref (node); + } + else + success = FALSE; + } + + return gimp_procedure_get_return_values (procedure, success, + error ? *error : NULL); +} + static GimpValueArray * plug_in_papertile_invoker (GimpProcedure *procedure, Gimp *gimp, @@ -7469,6 +7578,120 @@ register_plug_in_compat_procs (GimpPDB *pdb) gimp_pdb_register_procedure (pdb, procedure); g_object_unref (procedure); + /* + * gimp-plug-in-oilify2 + */ + procedure = gimp_procedure_new (plug_in_oilify2_invoker); + gimp_object_set_static_name (GIMP_OBJECT (procedure), + "plug-in-oilify2"); + gimp_procedure_set_static_strings (procedure, + "plug-in-oilify2", + "Smear colors to simulate an oil painting", + "This function performs the well-known oil-paint effect on the specified drawable.", + "Compatibility procedure. Please see 'gegl:oilify' for credits.", + "Compatibility procedure. Please see 'gegl:oilify' for credits.", + "2019", + NULL); + gimp_procedure_add_argument (procedure, + g_param_spec_enum ("run-mode", + "run mode", + "The run mode", + GIMP_TYPE_RUN_MODE, + GIMP_RUN_INTERACTIVE, + GIMP_PARAM_READWRITE)); + gimp_procedure_add_argument (procedure, + gimp_param_spec_image_id ("image", + "image", + "Input image (unused)", + pdb->gimp, FALSE, + GIMP_PARAM_READWRITE)); + gimp_procedure_add_argument (procedure, + gimp_param_spec_drawable_id ("drawable", + "drawable", + "Input drawable", + pdb->gimp, FALSE, + GIMP_PARAM_READWRITE)); + gimp_procedure_add_argument (procedure, + gimp_param_spec_int32 ("mask-size", + "mask size", + "Oil paint mask size", + 1, 200, 1, + GIMP_PARAM_READWRITE)); + gimp_procedure_add_argument (procedure, + gimp_param_spec_int32 ("mode", + "mode", + "Algorithm { RGB (0), INTENSITY (1) }", + 0, 1, 0, + GIMP_PARAM_READWRITE)); + gimp_pdb_register_procedure (pdb, procedure); + g_object_unref (procedure); + + /* + * gimp-plug-in-oilify-enhanced2 + */ + procedure = gimp_procedure_new (plug_in_oilify_enhanced2_invoker); + gimp_object_set_static_name (GIMP_OBJECT (procedure), + "plug-in-oilify-enhanced2"); + gimp_procedure_set_static_strings (procedure, + "plug-in-oilify-enhanced2", + "Smear colors to simulate an oil painting", + "This function performs the well-known oil-paint effect on the specified drawable.", + "Compatibility procedure. Please see 'gegl:oilify' for credits.", + "Compatibility procedure. Please see 'gegl:oilify' for credits.", + "2019", + NULL); + gimp_procedure_add_argument (procedure, + g_param_spec_enum ("run-mode", + "run mode", + "The run mode", + GIMP_TYPE_RUN_MODE, + GIMP_RUN_INTERACTIVE, + GIMP_PARAM_READWRITE)); + gimp_procedure_add_argument (procedure, + gimp_param_spec_image_id ("image", + "image", + "Input image (unused)", + pdb->gimp, FALSE, + GIMP_PARAM_READWRITE)); + gimp_procedure_add_argument (procedure, + gimp_param_spec_drawable_id ("drawable", + "drawable", + "Input drawable", + pdb->gimp, FALSE, + GIMP_PARAM_READWRITE)); + gimp_procedure_add_argument (procedure, + gimp_param_spec_int32 ("mode", + "mode", + "Algorithm { RGB (0), INTENSITY (1) }", + 0, 1, 0, + GIMP_PARAM_READWRITE)); + gimp_procedure_add_argument (procedure, + gimp_param_spec_int32 ("mask-size", + "mask size", + "Oil paint mask size", + 1, 200, 1, + GIMP_PARAM_READWRITE)); + gimp_procedure_add_argument (procedure, + gimp_param_spec_drawable_id ("mask-size-map", + "mask size map", + "Mask size control map", + pdb->gimp, TRUE, + GIMP_PARAM_READWRITE)); + gimp_procedure_add_argument (procedure, + gimp_param_spec_int32 ("exponent", + "exponent", + "Oil paint exponent", + 1, 20, 1, + GIMP_PARAM_READWRITE)); + gimp_procedure_add_argument (procedure, + gimp_param_spec_drawable_id ("exponent-map", + "exponent map", + "Exponent control map", + pdb->gimp, TRUE, + GIMP_PARAM_READWRITE)); + gimp_pdb_register_procedure (pdb, procedure); + g_object_unref (procedure); + /* * gimp-plug-in-papertile */ diff --git a/pdb/groups/plug_in_compat.pdb b/pdb/groups/plug_in_compat.pdb index 96d9617d29..afe281cacf 100644 --- a/pdb/groups/plug_in_compat.pdb +++ b/pdb/groups/plug_in_compat.pdb @@ -1214,26 +1214,26 @@ HELP $date = '2015'; @inargs = ( - { name => 'run_mode', type => 'enum GimpRunMode', dead => 1, - desc => 'The run mode' }, - { name => 'image', type => 'image', dead => 1, - desc => 'Input image (unused)' }, - { name => 'drawable', type => 'drawable', - desc => 'Input drawable' }, - { name => 'amount_x', type => '-500.0 <= float <= 500.0', - desc => 'Displace multiplier for radial direction' }, - { name => 'amount_y', type => '-500.0 <= float <= 500.0', - desc => 'Displace multiplier for tangent direction' }, - { name => 'do_x', type => 'boolean', - desc => 'Displace in radial direction ?' }, - { name => 'do_y', type => 'boolean', - desc => 'Displace in tangent direction ?' }, - { name => 'displace_map_x', type => 'drawable', - desc => 'Displacement map for radial direction' }, - { name => 'displace_map_y', type => 'drawable', - desc => 'Displacement map for tangent direction' }, - { name => 'displace_type', type => '1 <= int32 <= 3', - desc => 'Edge behavior { WRAP (1), SMEAR (2), BLACK (3) }' } + { name => 'run_mode', type => 'enum GimpRunMode', dead => 1, + desc => 'The run mode' }, + { name => 'image', type => 'image', dead => 1, + desc => 'Input image (unused)' }, + { name => 'drawable', type => 'drawable', + desc => 'Input drawable' }, + { name => 'amount_x', type => '-500.0 <= float <= 500.0', + desc => 'Displace multiplier for radial direction' }, + { name => 'amount_y', type => '-500.0 <= float <= 500.0', + desc => 'Displace multiplier for tangent direction' }, + { name => 'do_x', type => 'boolean', + desc => 'Displace in radial direction ?' }, + { name => 'do_y', type => 'boolean', + desc => 'Displace in tangent direction ?' }, + { name => 'displace_map_x', type => 'drawable', + desc => 'Displacement map for radial direction' }, + { name => 'displace_map_y', type => 'drawable', + desc => 'Displacement map for tangent direction' }, + { name => 'displace_type', type => '1 <= int32 <= 3', + desc => 'Edge behavior { WRAP (1), SMEAR (2), BLACK (3) }' } ); %invoke = ( @@ -2891,6 +2891,129 @@ CODE ); } +sub plug_in_oilify2 { + $blurb = 'Smear colors to simulate an oil painting'; + + $help = <<'HELP'; +This function performs the well-known oil-paint effect on the +specified drawable. +HELP + + &std_pdb_compat('gegl:oilify'); + $date = '2019'; + + @inargs = ( + { name => 'run_mode', type => 'enum GimpRunMode', dead => 1, + desc => 'The run mode' }, + { name => 'image', type => 'image', dead => 1, + desc => 'Input image (unused)' }, + { name => 'drawable', type => 'drawable', + desc => 'Input drawable' }, + { name => 'mask_size', type => '1 <= int32 <= 200', + desc => 'Oil paint mask size' }, + { name => 'mode', type => '0 <= int32 <= 1', + desc => 'Algorithm { RGB (0), INTENSITY (1) }' } + ); + + %invoke = ( + code => <<'CODE' +{ + if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, + GIMP_PDB_ITEM_CONTENT, error) && + gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error)) + { + GeglNode *node; + + node = gegl_node_new_child (NULL, + "operation", "gegl:oilify", + "mask-radius", MAX (1, mask_size / 2), + "use-inten", mode ? TRUE : FALSE, + NULL); + + gimp_drawable_apply_operation (drawable, progress, + C_("undo-type", "Oilify"), + node); + g_object_unref (node); + } + else + success = FALSE; +} +CODE + ); +} + +sub plug_in_oilify_enhanced2 { + $blurb = 'Smear colors to simulate an oil painting'; + + $help = <<'HELP'; +This function performs the well-known oil-paint effect on the +specified drawable. +HELP + + &std_pdb_compat('gegl:oilify'); + $date = '2019'; + + @inargs = ( + { name => 'run_mode', type => 'enum GimpRunMode', dead => 1, + desc => 'The run mode' }, + { name => 'image', type => 'image', dead => 1, + desc => 'Input image (unused)' }, + { name => 'drawable', type => 'drawable', + desc => 'Input drawable' }, + { name => 'mode', type => '0 <= int32 <= 1', + desc => 'Algorithm { RGB (0), INTENSITY (1) }' }, + { name => 'mask_size', type => '1 <= int32 <= 200', + desc => 'Oil paint mask size' }, + { name => 'mask_size_map', type => 'drawable', none_ok => 1, + desc => 'Mask size control map' }, + { name => 'exponent', type => '1 <= int32 <= 20', + desc => 'Oil paint exponent' }, + { name => 'exponent_map', type => 'drawable', none_ok => 1, + desc => 'Exponent control map' } + ); + + %invoke = ( + code => <<'CODE' +{ + if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, + GIMP_PDB_ITEM_CONTENT, error) && + gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error)) + { + GeglNode *node; + + node = gegl_node_new_child (NULL, + "operation", "gegl:oilify", + "mask-radius", MAX (1, mask_size / 2), + "use-inten", mode ? TRUE : FALSE, + "exponent", exponent, + NULL); + + if (mask_size_map) + { + GeglNode *src_node; + src_node = create_buffer_source_node (node, mask_size_map); + gegl_node_connect_to (src_node, "output", node, "aux"); + } + + if (exponent_map) + { + GeglNode *src_node; + src_node = create_buffer_source_node (node, exponent_map); + gegl_node_connect_to (src_node, "output", node, "aux2"); + } + + gimp_drawable_apply_operation (drawable, progress, + C_("undo-type", "Oilify"), + node); + g_object_unref (node); + } + else + success = FALSE; +} +CODE + ); +} + sub plug_in_papertile { $blurb = 'Cut image into paper tiles, and slide them'; @@ -5344,6 +5467,8 @@ CODE plug_in_newsprint plug_in_normalize plug_in_nova + plug_in_oilify2 + plug_in_oilify_enhanced2 plug_in_papertile plug_in_photocopy plug_in_pixelize diff --git a/plug-ins/common/.gitignore b/plug-ins/common/.gitignore index 509f28f5e5..a80516e9aa 100644 --- a/plug-ins/common/.gitignore +++ b/plug-ins/common/.gitignore @@ -124,8 +124,6 @@ /mail.exe /nl-filter /nl-filter.exe -/oilify -/oilify.exe /plugin-browser /plugin-browser.exe /procedure-browser diff --git a/plug-ins/common/Makefile.am b/plug-ins/common/Makefile.am index 63c643e2ae..0d10866721 100644 --- a/plug-ins/common/Makefile.am +++ b/plug-ins/common/Makefile.am @@ -107,7 +107,6 @@ hot_libexecdir = $(gimpplugindir)/plug-ins/hot jigsaw_libexecdir = $(gimpplugindir)/plug-ins/jigsaw mail_libexecdir = $(gimpplugindir)/plug-ins/mail nl_filter_libexecdir = $(gimpplugindir)/plug-ins/nl-filter -oilify_libexecdir = $(gimpplugindir)/plug-ins/oilify plugin_browser_libexecdir = $(gimpplugindir)/plug-ins/plugin-browser procedure_browser_libexecdir = $(gimpplugindir)/plug-ins/procedure-browser qbist_libexecdir = $(gimpplugindir)/plug-ins/qbist @@ -186,7 +185,6 @@ hot_libexec_PROGRAMS = hot jigsaw_libexec_PROGRAMS = jigsaw mail_libexec_PROGRAMS = $(MAIL) nl_filter_libexec_PROGRAMS = nl-filter -oilify_libexec_PROGRAMS = oilify plugin_browser_libexec_PROGRAMS = plugin-browser procedure_browser_libexec_PROGRAMS = procedure-browser qbist_libexec_PROGRAMS = qbist @@ -1337,23 +1335,6 @@ nl_filter_LDADD = \ $(INTLLIBS) \ $(nl_filter_RC) -oilify_SOURCES = \ - oilify.c - -oilify_LDADD = \ - $(libgimpui) \ - $(libgimpwidgets) \ - $(libgimpmodule) \ - $(libgimp) \ - $(libgimpmath) \ - $(libgimpconfig) \ - $(libgimpcolor) \ - $(libgimpbase) \ - $(GTK_LIBS) \ - $(RT_LIBS) \ - $(INTLLIBS) \ - $(oilify_RC) - plugin_browser_SOURCES = \ plugin-browser.c diff --git a/plug-ins/common/gimprc.common b/plug-ins/common/gimprc.common index 83381d99e9..f643c8bc56 100644 --- a/plug-ins/common/gimprc.common +++ b/plug-ins/common/gimprc.common @@ -59,7 +59,6 @@ hot_RC = hot.rc.o jigsaw_RC = jigsaw.rc.o mail_RC = mail.rc.o nl_filter_RC = nl-filter.rc.o -oilify_RC = oilify.rc.o plugin_browser_RC = plugin-browser.rc.o procedure_browser_RC = procedure-browser.rc.o qbist_RC = qbist.rc.o diff --git a/plug-ins/common/oilify.c b/plug-ins/common/oilify.c deleted file mode 100644 index feebc7ab87..0000000000 --- a/plug-ins/common/oilify.c +++ /dev/null @@ -1,945 +0,0 @@ -/* - * This is a plug-in for GIMP. - * - * Copyright (C) 1995 Spencer Kimball and Peter Mattis - * Copyright (C) 1996 Torsten Martinsen - * Copyright (C) 2007 Daniel Richard G. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "config.h" - -#include - -#include -#include -#include - -#include "libgimp/stdplugins-intl.h" - - -#define PLUG_IN_PROC "plug-in-oilify" -#define PLUG_IN_ENHANCED_PROC "plug-in-oilify-enhanced" -#define PLUG_IN_BINARY "oilify" -#define PLUG_IN_ROLE "gimp-oilify" - -#define SCALE_WIDTH 125 -#define HISTSIZE 256 - -#define MODE_RGB 0 -#define MODE_INTEN 1 - - -typedef struct -{ - gdouble mask_size; - gboolean use_mask_size_map; - gint mask_size_map; - gdouble exponent; - gboolean use_exponent_map; - gint exponent_map; - gint mode; -} OilifyVals; - - -/* Declare local functions. - */ -static void query (void); -static void run (const gchar *name, - gint nparams, - const GimpParam *param, - gint *nreturn_vals, - GimpParam **return_vals); - -static void oilify (GimpDrawable *drawable, - GimpPreview *preview); - -static gboolean oilify_dialog (GimpDrawable *drawable); - - -const GimpPlugInInfo PLUG_IN_INFO = -{ - NULL, /* init_proc */ - NULL, /* quit_proc */ - query, /* query_proc */ - run, /* run_proc */ -}; - -static OilifyVals ovals = -{ - 8.0, /* mask size */ - FALSE, /* use mask-size map? */ - -1, /* mask-size map */ - 8.0, /* exponent */ - FALSE, /* use exponent map? */ - -1, /* exponent map */ - MODE_INTEN /* mode */ -}; - - -MAIN () - -static void -query (void) -{ - 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, "mask-size", "Oil paint mask size" }, - { GIMP_PDB_INT32, "mode", "Algorithm { RGB (0), INTENSITY (1) }" } - }; - - static const GimpParamDef args_enhanced[] = - { - { 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, "mode", "Algorithm { RGB (0), INTENSITY (1) }" }, - { GIMP_PDB_INT32, "mask-size", "Oil paint mask size" }, - { GIMP_PDB_DRAWABLE, "mask-size-map", "Mask size control map" }, - { GIMP_PDB_INT32, "exponent", "Oil paint exponent" }, - { GIMP_PDB_DRAWABLE, "exponent-map", "Exponent control map" } - }; - - gimp_install_procedure (PLUG_IN_PROC, - N_("Smear colors to simulate an oil painting"), - "This function performs the well-known oil-paint " - "effect on the specified drawable.", - "Torsten Martinsen", - "Torsten Martinsen", - "1996", - N_("Oili_fy (legacy)..."), - "RGB*, GRAY*", - GIMP_PLUGIN, - G_N_ELEMENTS (args), 0, - args, NULL); - - gimp_plugin_menu_register (PLUG_IN_PROC, "/Filters/Artistic"); - - gimp_install_procedure (PLUG_IN_ENHANCED_PROC, - N_("Smear colors to simulate an oil painting"), - "This function performs the well-known oil-paint " - "effect on the specified drawable.", - "Torsten Martinsen, Daniel Richard G.", - "Torsten Martinsen, Daniel Richard G.", - "2007", - NULL, - "RGB*, GRAY*", - GIMP_PLUGIN, - G_N_ELEMENTS (args_enhanced), 0, - args_enhanced, NULL); -} - -static void -run (const gchar *name, - gint nparams, - const GimpParam *param, - gint *nreturn_vals, - GimpParam **return_vals) -{ - static GimpParam values[1]; - GimpDrawable *drawable; - GimpRunMode run_mode; - GimpPDBStatusType status = GIMP_PDB_SUCCESS; - - INIT_I18N (); - - run_mode = param[0].data.d_int32; - - /* Get the specified drawable */ - drawable = gimp_drawable_get (param[2].data.d_drawable); - gimp_tile_cache_ntiles (2 * drawable->ntile_cols); - - *nreturn_vals = 1; - *return_vals = values; - - values[0].type = GIMP_PDB_STATUS; - values[0].data.d_status = status; - - switch (run_mode) - { - case GIMP_RUN_INTERACTIVE: - /* Possibly retrieve data */ - gimp_get_data (PLUG_IN_PROC, &ovals); - - /* First acquire information with a dialog */ - if (! oilify_dialog (drawable)) - return; - break; - - case GIMP_RUN_NONINTERACTIVE: - /* Interpret the arguments per the name used to invoke us */ - if (! strcmp (name, PLUG_IN_PROC)) - { - if (nparams != 5) - { - status = GIMP_PDB_CALLING_ERROR; - } - else - { - ovals.mask_size = (gdouble) param[3].data.d_int32; - ovals.mode = param[4].data.d_int32; - } - } - else if (! strcmp (name, PLUG_IN_ENHANCED_PROC)) - { - if (nparams < 5 || nparams > 8) - { - status = GIMP_PDB_CALLING_ERROR; - } - else - { - ovals.mode = param[3].data.d_int32; - ovals.mask_size = (gdouble) param[4].data.d_int32; - - if (nparams >= 6) - ovals.mask_size_map = param[5].data.d_int32; - - if (nparams >= 7) - ovals.exponent = (gdouble) param[6].data.d_int32; - - if (nparams == 8) - ovals.exponent_map = param[7].data.d_int32; - - ovals.use_mask_size_map = ovals.mask_size_map >= 0; - ovals.use_exponent_map = ovals.exponent_map >= 0; - - if (ovals.mask_size < 1.0 || - ovals.exponent < 1.0 || - (ovals.mode != MODE_INTEN && ovals.mode != MODE_RGB) || - (ovals.mode == MODE_INTEN && - ! gimp_drawable_is_rgb (drawable->drawable_id))) - { - status = GIMP_PDB_CALLING_ERROR; - } - } - } - break; - - case GIMP_RUN_WITH_LAST_VALS: - /* Possibly retrieve data */ - gimp_get_data (PLUG_IN_PROC, &ovals); - break; - - default: - break; - } - - /* Make sure that the drawable is gray or RGB color */ - if ((status == GIMP_PDB_SUCCESS) && - (gimp_drawable_is_rgb (drawable->drawable_id) || - gimp_drawable_is_gray (drawable->drawable_id))) - { - gimp_progress_init (_("Oil painting")); - - oilify (drawable, NULL); - - if (run_mode != GIMP_RUN_NONINTERACTIVE) - gimp_displays_flush (); - - /* Store data */ - if (run_mode == GIMP_RUN_INTERACTIVE) - gimp_set_data (PLUG_IN_PROC, &ovals, sizeof (OilifyVals)); - } - else - { - /* gimp_message ("oilify: cannot operate on indexed color images"); */ - status = GIMP_PDB_EXECUTION_ERROR; - } - - values[0].data.d_status = status; - - gimp_drawable_detach (drawable); -} - -/* - * Helper function to read a sample from a mask-size/exponent map - */ -static inline gfloat -get_map_value (const guchar *src, - gint bpp) -{ - gfloat value; - - if (bpp >= 3) - value = GIMP_RGB_LUMINANCE (src[0], src[1], src[2]); - else - value = *src; - - if (value < 1.0) - value = 1.0; - - /* value should be in [0,1] */ - value /= 255.0; - - return value; -} - -/* - * This is a special-case form of the powf() function, limited to integer - * exponents. It calculates e.g. x^13 as (x^8)*(x^4)*(x^1). - * - * x can be anything, y must be in [0,255] - */ -static inline gfloat -fast_powf (gfloat x, gint y) -{ - gfloat value; - gfloat x_pow[8]; - guint y_uint = (guint) y; - guint bitmask; - gint i; - - if (y_uint & 0x01) - value = x; - else - value = 1.0; - - x_pow[0] = x; - - for (bitmask = 0x02, i = 1; - bitmask <= y_uint; - bitmask <<= 1, i++) - { - /* x_pow[i] == x_pow[i-1]^2 == x^(2^i) */ - - x_pow[i] = SQR (x_pow[i - 1]); - - if (y_uint & bitmask) - value *= x_pow[i]; - } - - return value; -} - -/* - * For each i in [0, HISTSIZE), hist[i] is the number of occurrences of the - * value i. Return a value in [0, HISTSIZE) weighted heavily toward the - * most frequent values in the histogram. - * - * Assuming that hist_max is the maximum number of occurrences for any - * one value in the histogram, the weight given to each value i is - * - * weight = (hist[i] / hist_max)^exponent - * - * (i.e. the normalized histogram frequency raised to some power) - */ -static inline guchar -weighted_average_value (gint hist[HISTSIZE], gfloat exponent) -{ - gint i; - gint hist_max = 1; - gint exponent_int = 0; - gfloat sum = 0.0; - gfloat div = 1.0e-6; - gint value; - - for (i = 0; i < HISTSIZE; i++) - hist_max = MAX (hist_max, hist[i]); - - if ((exponent - floor (exponent)) < 0.001 && exponent <= 255.0) - exponent_int = (gint) exponent; - - for (i = 0; i < HISTSIZE; i++) - { - gfloat ratio = (gfloat) hist[i] / (gfloat) hist_max; - gfloat weight; - - if (exponent_int) - weight = fast_powf (ratio, exponent_int); - else - weight = pow (ratio, exponent); - - sum += weight * (gfloat) i; - div += weight; - } - - value = (gint) (sum / div); - - return (guchar) CLAMP0255 (value); -} - -/* - * For each i in [0, HISTSIZE), hist[i] is the number of occurrences of - * pixels with intensity i. hist_rgb[][i] is the average color of those - * pixels with intensity i, but with each channel multiplied by hist[i]. - * Write to dest a pixel whose color is a weighted average of all the - * colors in hist_rgb[][], biased heavily toward those with the most - * frequently-occurring intensities (as noted in hist[]). - * - * The weight formula is the same as in weighted_average_value(). - */ -static inline void -weighted_average_color (gint hist[HISTSIZE], - gint hist_rgb[4][HISTSIZE], - gfloat exponent, - guchar *dest, - gint bpp) -{ - gint i, b; - gint hist_max = 1; - gint exponent_int = 0; - gfloat div = 1.0e-6; - gfloat color[4] = { 0.0, 0.0, 0.0, 0.0 }; - - for (i = 0; i < HISTSIZE; i++) - hist_max = MAX (hist_max, hist[i]); - - if ((exponent - floor (exponent)) < 0.001 && exponent <= 255.0) - exponent_int = (gint) exponent; - - for (i = 0; i < HISTSIZE; i++) - { - gfloat ratio = (gfloat) hist[i] / (gfloat) hist_max; - gfloat weight; - - if (exponent_int) - weight = fast_powf (ratio, exponent_int); - else - weight = pow (ratio, exponent); - - if (hist[i] > 0) - for (b = 0; b < bpp; b++) - color[b] += weight * (gfloat) hist_rgb[b][i] / (gfloat) hist[i]; - - div += weight; - } - - for (b = 0; b < bpp; b++) - { - gint c = (gint) (color[b] / div); - - dest[b] = (guchar) CLAMP0255 (c); - } -} - -/* - * For all x and y as requested, replace the pixel at (x,y) - * with a weighted average of the most frequently occurring - * values in a circle of mask_size diameter centered at (x,y). - */ -static void -oilify (GimpDrawable *drawable, - GimpPreview *preview) -{ - gboolean use_inten; - gboolean use_msmap = FALSE; - gboolean use_emap = FALSE; - GimpDrawable *mask_size_map_drawable = NULL; - GimpDrawable *exponent_map_drawable = NULL; - GimpPixelRgn mask_size_map_rgn; - GimpPixelRgn exponent_map_rgn; - gint msmap_bpp = 0; - gint emap_bpp = 0; - GimpPixelRgn dest_rgn; - GimpPixelRgn *regions[3]; - gint n_regions; - gint bpp; - gint *sqr_lut; - gint x1, y1, x2, y2; - gint width, height; - gint Hist[HISTSIZE]; - gint Hist_rgb[4][HISTSIZE]; - gpointer pr; - gint progress, max_progress; - guchar *src_buf; - guchar *src_inten_buf = NULL; - gint i; - - use_inten = (ovals.mode == MODE_INTEN); - - /* Get the selection bounds */ - if (preview) - { - gimp_preview_get_position (preview, &x1, &y1); - gimp_preview_get_size (preview, &width, &height); - - x2 = x1 + width; - y2 = y1 + height; - } - else - { - if (! gimp_drawable_mask_intersect (drawable->drawable_id, - &x1, &y1, &width, &height)) - return; - - x2 = x1 + width; - y2 = y1 + height; - } - - progress = 0; - max_progress = width * height; - - bpp = drawable->bpp; - - /* - * Look-up-table implementation of the square function, for use in the - * VERY TIGHT inner loops - */ - { - gint lut_size = (gint) ovals.mask_size / 2 + 1; - - sqr_lut = g_new (gint, lut_size); - - for (i = 0; i < lut_size; i++) - sqr_lut[i] = SQR (i); - } - - /* Get the map drawables, if applicable */ - - if (ovals.use_mask_size_map && ovals.mask_size_map >= 0) - { - use_msmap = TRUE; - - mask_size_map_drawable = gimp_drawable_get (ovals.mask_size_map); - gimp_pixel_rgn_init (&mask_size_map_rgn, mask_size_map_drawable, - x1, y1, width, height, FALSE, FALSE); - - msmap_bpp = mask_size_map_drawable->bpp; - } - - if (ovals.use_exponent_map && ovals.exponent_map >= 0) - { - use_emap = TRUE; - - exponent_map_drawable = gimp_drawable_get (ovals.exponent_map); - gimp_pixel_rgn_init (&exponent_map_rgn, exponent_map_drawable, - x1, y1, width, height, FALSE, FALSE); - - emap_bpp = exponent_map_drawable->bpp; - } - - gimp_pixel_rgn_init (&dest_rgn, drawable, - x1, y1, width, height, (preview == NULL), TRUE); - - { - GimpPixelRgn src_rgn; - - gimp_pixel_rgn_init (&src_rgn, drawable, - x1, y1, width, height, FALSE, FALSE); - src_buf = g_new (guchar, width * height * bpp); - gimp_pixel_rgn_get_rect (&src_rgn, src_buf, x1, y1, width, height); - } - - /* - * If we're working in intensity mode, then generate a separate intensity - * map of the source image. This way, we can avoid calculating the - * intensity of any given source pixel more than once. - */ - if (use_inten) - { - guchar *src; - guchar *dest; - - src_inten_buf = g_new (guchar, width * height); - - for (i = 0, - src = src_buf, - dest = src_inten_buf - ; - i < (width * height) - ; - i++, - src += bpp, - dest++) - { - *dest = (guchar) GIMP_RGB_LUMINANCE (src[0], src[1], src[2]); - } - } - - n_regions = 0; - regions[n_regions++] = &dest_rgn; - if (use_msmap) - regions[n_regions++] = &mask_size_map_rgn; - if (use_emap) - regions[n_regions++] = &exponent_map_rgn; - - for (pr = gimp_pixel_rgns_register2 (n_regions, regions); - pr != NULL; - pr = gimp_pixel_rgns_process (pr)) - { - gint y; - guchar *dest_row; - guchar *src_msmap_row = NULL; - guchar *src_emap_row = NULL; - - for (y = dest_rgn.y, - dest_row = dest_rgn.data, - src_msmap_row = mask_size_map_rgn.data, /* valid iff use_msmap */ - src_emap_row = exponent_map_rgn.data /* valid iff use_emap */ - ; - y < (gint) (dest_rgn.y + dest_rgn.h) - ; - y++, - dest_row += dest_rgn.rowstride, - src_msmap_row += mask_size_map_rgn.rowstride, /* valid iff use_msmap */ - src_emap_row += exponent_map_rgn.rowstride) /* valid iff use_emap */ - { - gint x; - guchar *dest; - guchar *src_msmap = NULL; - guchar *src_emap = NULL; - - for (x = dest_rgn.x, - dest = dest_row, - src_msmap = src_msmap_row, /* valid iff use_msmap */ - src_emap = src_emap_row /* valid iff use_emap */ - ; - x < (gint) (dest_rgn.x + dest_rgn.w) - ; - x++, - dest += bpp, - src_msmap += msmap_bpp, /* valid iff use_msmap */ - src_emap += emap_bpp) /* valid iff use_emap */ - { - gint radius, radius_squared; - gfloat exponent; - gint mask_x1, mask_y1; - gint mask_x2, mask_y2; - gint mask_y; - gint src_offset; - guchar *src_row; - guchar *src_inten_row = NULL; - - if (use_msmap) - { - gfloat factor = get_map_value (src_msmap, msmap_bpp); - - radius = ROUND (factor * (0.5 * ovals.mask_size)); - } - else - { - radius = (gint) ovals.mask_size / 2; - } - - radius_squared = SQR (radius); - - exponent = ovals.exponent; - if (use_emap) - exponent *= get_map_value (src_emap, emap_bpp); - - if (use_inten) - memset (Hist, 0, sizeof (Hist)); - - memset (Hist_rgb, 0, sizeof (Hist_rgb)); - - mask_x1 = CLAMP ((x - radius), x1, x2); - mask_y1 = CLAMP ((y - radius), y1, y2); - mask_x2 = CLAMP ((x + radius + 1), x1, x2); - mask_y2 = CLAMP ((y + radius + 1), y1, y2); - - src_offset = (mask_y1 - y1) * width + (mask_x1 - x1); - - for (mask_y = mask_y1, - src_row = src_buf + src_offset * bpp, - src_inten_row = src_inten_buf + src_offset /* valid iff use_inten */ - ; - mask_y < mask_y2 - ; - mask_y++, - src_row += width * bpp, - src_inten_row += width) /* valid iff use_inten */ - { - guchar *src; - guchar *src_inten = NULL; - gint dy_squared = sqr_lut[ABS (mask_y - y)]; - gint mask_x; - - for (mask_x = mask_x1, - src = src_row, - src_inten = src_inten_row /* valid iff use_inten */ - ; - mask_x < mask_x2 - ; - mask_x++, - src += bpp, - src_inten++) /* valid iff use_inten */ - { - gint dx_squared = sqr_lut[ABS (mask_x - x)]; - gint b; - - /* Stay inside a circular mask area */ - if ((dx_squared + dy_squared) > radius_squared) - continue; - - if (use_inten) - { - gint inten = *src_inten; - ++Hist[inten]; - for (b = 0; b < bpp; b++) - Hist_rgb[b][inten] += src[b]; - } - else - { - for (b = 0; b < bpp; b++) - ++Hist_rgb[b][src[b]]; - } - - } /* for mask_x */ - } /* for mask_y */ - - if (use_inten) - { - weighted_average_color (Hist, Hist_rgb, exponent, dest, bpp); - } - else - { - gint b; - - for (b = 0; b < bpp; b++) - dest[b] = weighted_average_value (Hist_rgb[b], exponent); - } - - } /* for x */ - } /* for y */ - - if (preview) - { - gimp_drawable_preview_draw_region (GIMP_DRAWABLE_PREVIEW (preview), - &dest_rgn); - } - else - { - progress += dest_rgn.w * dest_rgn.h; - gimp_progress_update ((gdouble) progress / (gdouble) max_progress); - } - } /* for pr */ - - /* Detach from the map drawables */ - if (mask_size_map_drawable) - gimp_drawable_detach (mask_size_map_drawable); - - if (exponent_map_drawable) - gimp_drawable_detach (exponent_map_drawable); - - if (src_inten_buf) - g_free (src_inten_buf); - - g_free (src_buf); - g_free (sqr_lut); - - if (!preview) - { - gimp_progress_update (1.0); - /* Update the oil-painted region */ - gimp_drawable_flush (drawable); - gimp_drawable_merge_shadow (drawable->drawable_id, TRUE); - gimp_drawable_update (drawable->drawable_id, x1, y1, width, height); - } -} - -/* - * Return TRUE iff the specified drawable can be used as a mask-size / - * exponent map with the source image. The map and the image must have the - * same dimensions. - */ -static gboolean -oilify_map_constrain (gint32 image_id G_GNUC_UNUSED, - gint32 drawable_id, - gpointer data) -{ - GimpDrawable *drawable = data; - - return (gimp_drawable_width (drawable_id) == (gint) drawable->width && - gimp_drawable_height (drawable_id) == (gint) drawable->height); -} - -static gint -oilify_dialog (GimpDrawable *drawable) -{ - GtkWidget *dialog; - GtkWidget *main_vbox; - GtkWidget *preview; - GtkWidget *grid; - GtkWidget *toggle; - GtkWidget *combo; - GtkAdjustment *adj; - gboolean can_use_mode_inten; - gboolean ret; - - can_use_mode_inten = gimp_drawable_is_rgb (drawable->drawable_id); - - if (! can_use_mode_inten && ovals.mode == MODE_INTEN) - ovals.mode = MODE_RGB; - - gimp_ui_init (PLUG_IN_BINARY, FALSE); - - dialog = gimp_dialog_new (_("Oilify"), PLUG_IN_ROLE, - NULL, 0, - gimp_standard_help_func, PLUG_IN_PROC, - - _("_Cancel"), GTK_RESPONSE_CANCEL, - _("_OK"), GTK_RESPONSE_OK, - - NULL); - - gimp_dialog_set_alternative_button_order (GTK_DIALOG (dialog), - GTK_RESPONSE_OK, - GTK_RESPONSE_CANCEL, - -1); - - gimp_window_set_transient (GTK_WINDOW (dialog)); - - main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12); - gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12); - gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), - main_vbox, TRUE, TRUE, 0); - gtk_widget_show (main_vbox); - - preview = gimp_drawable_preview_new_from_drawable_id (drawable->drawable_id); - gtk_box_pack_start (GTK_BOX (main_vbox), preview, TRUE, TRUE, 0); - gtk_widget_show (preview); - g_signal_connect_swapped (preview, "invalidated", - G_CALLBACK (oilify), drawable); - - grid = gtk_grid_new (); - gtk_grid_set_row_spacing (GTK_GRID (grid), 6); - gtk_grid_set_column_spacing (GTK_GRID (grid), 6); - gtk_box_pack_start (GTK_BOX (main_vbox), grid, FALSE, FALSE, 0); - gtk_widget_show (grid); - - /* - * Mask-size scale - */ - - adj = gimp_scale_entry_new (GTK_GRID (grid), 0, 0, - _("_Mask size:"), SCALE_WIDTH, 0, - ovals.mask_size, 3.0, 50.0, 1.0, 5.0, 0, - TRUE, 0.0, 0.0, - NULL, NULL); - g_signal_connect (adj, "value-changed", - G_CALLBACK (gimp_double_adjustment_update), - &ovals.mask_size); - g_signal_connect_swapped (adj, "value-changed", - G_CALLBACK (gimp_preview_invalidate), - preview); - - /* - * Mask-size map check button - */ - - toggle = gtk_check_button_new_with_mnemonic (_("Use m_ask-size map:")); - gtk_grid_attach (GTK_GRID (grid), toggle, 0, 1, 3, 1); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), - ovals.use_mask_size_map); - gtk_widget_show (toggle); - - g_signal_connect (toggle, "toggled", - G_CALLBACK (gimp_toggle_button_update), - &ovals.use_mask_size_map); - g_signal_connect_swapped (toggle, "toggled", - G_CALLBACK (gimp_preview_invalidate), - preview); - - /* - * Mask-size map combo - */ - - combo = gimp_drawable_combo_box_new (oilify_map_constrain, drawable); - gimp_int_combo_box_connect (GIMP_INT_COMBO_BOX (combo), ovals.mask_size_map, - G_CALLBACK (gimp_int_combo_box_get_active), - &ovals.mask_size_map); - g_signal_connect_swapped (combo, "changed", - G_CALLBACK (gimp_preview_invalidate), - preview); - - gtk_grid_attach (GTK_GRID (grid), combo, 0, 2, 3, 1); - // GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); - gtk_widget_show (combo); - - g_object_bind_property (toggle, "active", - combo, "sensitive", - G_BINDING_SYNC_CREATE); - - /* - * Exponent scale - */ - - adj = gimp_scale_entry_new (GTK_GRID (grid), 0, 3, - _("_Exponent:"), SCALE_WIDTH, 0, - ovals.exponent, 1.0, 20.0, 1.0, 4.0, 0, - TRUE, 0.0, 0.0, - NULL, NULL); - g_signal_connect (adj, "value-changed", - G_CALLBACK (gimp_double_adjustment_update), - &ovals.exponent); - g_signal_connect_swapped (adj, "value-changed", - G_CALLBACK (gimp_preview_invalidate), - preview); - - /* - * Exponent map check button - */ - - toggle = gtk_check_button_new_with_mnemonic (_("Use e_xponent map:")); - gtk_grid_attach (GTK_GRID (grid), toggle, 0, 4, 3, 1); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), - ovals.use_exponent_map); - gtk_widget_show (toggle); - - g_signal_connect (toggle, "toggled", - G_CALLBACK (gimp_toggle_button_update), - &ovals.use_exponent_map); - g_signal_connect_swapped (toggle, "toggled", - G_CALLBACK (gimp_preview_invalidate), - preview); - - /* - * Exponent map combo - */ - - combo = gimp_drawable_combo_box_new (oilify_map_constrain, drawable); - gimp_int_combo_box_connect (GIMP_INT_COMBO_BOX (combo), ovals.exponent_map, - G_CALLBACK (gimp_int_combo_box_get_active), - &ovals.exponent_map); - g_signal_connect_swapped (combo, "changed", - G_CALLBACK (gimp_preview_invalidate), - preview); - - gtk_grid_attach (GTK_GRID (grid), combo, 0, 5, 3, 1); - // GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); - gtk_widget_show (combo); - - g_object_bind_property (toggle, "active", - combo, "sensitive", - G_BINDING_SYNC_CREATE); - - /* - * Intensity algorithm check button - */ - - toggle = gtk_check_button_new_with_mnemonic (_("_Use intensity algorithm")); - gtk_grid_attach (GTK_GRID (grid), toggle, 0, 6, 3, 1); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), ovals.mode); - gtk_widget_set_sensitive (toggle, can_use_mode_inten); - gtk_widget_show (toggle); - - g_signal_connect (toggle, "toggled", - G_CALLBACK (gimp_toggle_button_update), - &ovals.mode); - g_signal_connect_swapped (toggle, "toggled", - G_CALLBACK (gimp_preview_invalidate), - preview); - - gtk_widget_show (dialog); - - ret = (gimp_dialog_run (GIMP_DIALOG (dialog)) == GTK_RESPONSE_OK); - - gtk_widget_destroy (dialog); - - return ret; -} diff --git a/plug-ins/common/plugin-defs.pl b/plug-ins/common/plugin-defs.pl index 8b3a2c2ae4..91b999f2b3 100644 --- a/plug-ins/common/plugin-defs.pl +++ b/plug-ins/common/plugin-defs.pl @@ -61,7 +61,6 @@ 'jigsaw' => { ui => 1, gegl => 1 }, 'mail' => { ui => 1, optional => 1 }, 'nl-filter' => { ui => 1, gegl => 1 }, - 'oilify' => { ui => 1 }, 'plugin-browser' => { ui => 1 }, 'procedure-browser' => { ui => 1 }, 'qbist' => { ui => 1, gegl => 1 }, diff --git a/po-plug-ins/POTFILES.in b/po-plug-ins/POTFILES.in index 1c3229df75..42c52ee0fd 100644 --- a/po-plug-ins/POTFILES.in +++ b/po-plug-ins/POTFILES.in @@ -65,7 +65,6 @@ plug-ins/common/hot.c plug-ins/common/jigsaw.c plug-ins/common/mail.c plug-ins/common/nl-filter.c -plug-ins/common/oilify.c plug-ins/common/plugin-browser.c plug-ins/common/procedure-browser.c plug-ins/common/qbist.c