app, libgimp, pdb: new gimp_drawable_filter_set_aux_input() public API.

It is this way possible to set a drawable as auxiliary input to a filter
in C and GObject-Introspected bindings.

Note that such filters can only be merged, not appended
non-destructively for the time being.
This commit is contained in:
Jehan 2024-12-16 21:45:55 +01:00
parent 1fbd2acc84
commit 6480ba2ad6
9 changed files with 128 additions and 6 deletions

View file

@ -734,12 +734,15 @@ gimp_drawable_filter_update (GimpDrawableFilter *filter,
GimpLayerColorSpace blend_space,
GimpLayerColorSpace composite_space,
GimpLayerCompositeMode composite_mode,
const gchar **auxinputnames,
const GimpDrawable **auxinputs,
GError **error)
{
GParamSpec **pspecs;
gchar *opname;
guint n_pspecs;
gint n_values;
gint n_auxinputs;
gboolean changed = FALSE;
g_return_val_if_fail (GIMP_IS_DRAWABLE_FILTER (filter), FALSE);
@ -755,6 +758,18 @@ gimp_drawable_filter_update (GimpDrawableFilter *filter,
return FALSE;
}
n_auxinputs = 0;
while (auxinputs[n_auxinputs] != NULL)
n_auxinputs++;
if (n_auxinputs != g_strv_length ((gchar **) auxinputnames))
{
g_set_error (error, GIMP_ERROR, GIMP_FAILED,
"%s: the number of aux input names and aux inputs differ.",
G_STRFUNC);
return FALSE;
}
g_object_freeze_notify (G_OBJECT (filter));
gegl_node_get (filter->operation, "operation", &opname, NULL);
@ -881,6 +896,36 @@ gimp_drawable_filter_update (GimpDrawableFilter *filter,
changed = TRUE;
}
if (*error == NULL)
{
for (gint i = 0; auxinputnames[i]; i++)
{
GeglNode *src_node;
GeglBuffer *buffer;
if (! gegl_node_has_pad (filter->operation, auxinputnames[i]))
{
g_set_error (error, GIMP_ERROR, GIMP_FAILED,
/* TODO: localize after string freeze. */
"GEGL operation '%s' has been called with an "
"invalid aux input name '%s'.",
opname, auxinputnames[i]);
break;
}
buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (auxinputs[i]));
g_object_ref (buffer);
src_node = gegl_node_new_child (gegl_node_get_parent (filter->operation),
"operation", "gegl:buffer-source",
"buffer", buffer,
NULL);
g_object_unref (buffer);
gegl_node_connect (src_node, "output", filter->operation, auxinputnames[i]);
}
}
g_object_thaw_notify (G_OBJECT (filter));
g_free (pspecs);

View file

@ -107,6 +107,8 @@ gboolean gimp_drawable_filter_update (GimpDrawableFilter *filter,
GimpLayerColorSpace blend_space,
GimpLayerColorSpace composite_space,
GimpLayerCompositeMode composite_mode,
const gchar **auxinputnames,
const GimpDrawable **auxinputs,
GError **error);
void gimp_drawable_filter_set_opacity (GimpDrawableFilter *filter,
gdouble opacity);

View file

@ -349,6 +349,8 @@ drawable_filter_update_invoker (GimpProcedure *procedure,
gint blend_space;
gint composite_mode;
gint composite_space;
const gchar **auxinputnames;
const GimpDrawable **auxinputs;
filter = g_value_get_object (gimp_value_array_index (args, 0));
propnames = g_value_get_boxed (gimp_value_array_index (args, 1));
@ -358,6 +360,8 @@ drawable_filter_update_invoker (GimpProcedure *procedure,
blend_space = g_value_get_enum (gimp_value_array_index (args, 5));
composite_mode = g_value_get_enum (gimp_value_array_index (args, 6));
composite_space = g_value_get_enum (gimp_value_array_index (args, 7));
auxinputnames = g_value_get_boxed (gimp_value_array_index (args, 8));
auxinputs = g_value_get_boxed (gimp_value_array_index (args, 9));
if (success)
{
@ -365,6 +369,7 @@ drawable_filter_update_invoker (GimpProcedure *procedure,
opacity,
blend_mode, blend_space,
composite_mode, composite_space,
auxinputnames, auxinputs,
error);
}
@ -922,6 +927,18 @@ register_drawable_filter_procs (GimpPDB *pdb)
GIMP_TYPE_LAYER_COLOR_SPACE,
GIMP_LAYER_COLOR_SPACE_AUTO,
GIMP_PARAM_READWRITE));
gimp_procedure_add_argument (procedure,
g_param_spec_boxed ("auxinputnames",
"auxinputnames",
"Array of aux input pads",
G_TYPE_STRV,
GIMP_PARAM_READWRITE));
gimp_procedure_add_argument (procedure,
gimp_param_spec_core_object_array ("auxinputs",
"auxinputs",
"Array of drawables, one per auxinputnames",
GIMP_TYPE_DRAWABLE,
GIMP_PARAM_READWRITE | GIMP_PARAM_NO_VALIDATE));
gimp_pdb_register_procedure (pdb, procedure);
g_object_unref (procedure);

View file

@ -227,6 +227,7 @@ EXPORTS
gimp_drawable_filter_id_is_valid
gimp_drawable_filter_is_valid
gimp_drawable_filter_new
gimp_drawable_filter_set_aux_input
gimp_drawable_filter_set_blend_mode
gimp_drawable_filter_set_opacity
gimp_drawable_filter_set_visible

View file

@ -46,6 +46,8 @@ struct _GimpDrawableFilter
GimpLayerCompositeMode composite_mode;
GimpLayerColorSpace composite_space;
GHashTable *pad_inputs;
GimpDrawableFilterConfig *config;
};
@ -98,6 +100,8 @@ gimp_drawable_filter_init (GimpDrawableFilter *drawable_filter)
drawable_filter->blend_space = GIMP_LAYER_COLOR_SPACE_AUTO;
drawable_filter->composite_mode = GIMP_LAYER_COMPOSITE_AUTO;
drawable_filter->composite_space = GIMP_LAYER_COLOR_SPACE_AUTO;
drawable_filter->pad_inputs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
}
static void
@ -106,6 +110,7 @@ gimp_drawable_filter_finalize (GObject *object)
GimpDrawableFilter *filter = GIMP_DRAWABLE_FILTER (object);
g_clear_object (&filter->config);
g_hash_table_unref (filter->pad_inputs);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@ -254,6 +259,31 @@ gimp_drawable_filter_set_blend_mode (GimpDrawableFilter *filter,
filter->blend_mode = mode;
}
/**
* gimp_drawable_filter_set_aux_input:
* @filter: The drawable's filter.
* @input_pad_name: name of the filter's input pad.
* @input: the drawable to use as auxiliary input.
*
* When a filter has one or several auxiliary inputs, you can use this
* function to set them.
*
* The change is not synced immediately with the core application.
* Use [method@Gimp.Drawable.update] to trigger an actual update.
*
* Since: 3.0
**/
void
gimp_drawable_filter_set_aux_input (GimpDrawableFilter *filter,
const gchar *input_pad_name,
GimpDrawable *input)
{
g_return_if_fail (GIMP_IS_DRAWABLE_FILTER (filter));
g_return_if_fail (GIMP_IS_DRAWABLE (input));
g_hash_table_insert (filter->pad_inputs, (gpointer) g_strdup (input_pad_name), input);
}
/**
* gimp_drawable_filter_get_config:
* @filter: A drawable filter.
@ -352,6 +382,9 @@ gimp_drawable_filter_update (GimpDrawableFilter *filter)
GStrvBuilder *builder = g_strv_builder_new ();
GimpValueArray *values = NULL;
GStrv propnames;
GStrv auxnames;
const GimpDrawable **auxinputs;
guint n_aux;
if (filter->config)
{
@ -387,12 +420,20 @@ gimp_drawable_filter_update (GimpDrawableFilter *filter)
}
propnames = g_strv_builder_end (builder);
auxnames = (GStrv) g_hash_table_get_keys_as_array (filter->pad_inputs, &n_aux);
auxinputs = g_new0 (const GimpDrawable *, n_aux + 1);
for (guint i = 0; auxnames[i]; i++)
auxinputs[i] = g_hash_table_lookup (filter->pad_inputs, auxnames[i]);
_gimp_drawable_filter_update (filter, (const gchar **) propnames, values,
filter->opacity,
filter->blend_mode, filter->blend_space,
filter->composite_mode, filter->composite_space);
filter->composite_mode, filter->composite_space,
(const gchar **) auxnames, auxinputs);
g_strfreev (propnames);
g_strv_builder_unref (builder);
gimp_value_array_unref (values);
g_free (auxnames);
g_free (auxinputs);
}

View file

@ -45,6 +45,9 @@ void gimp_drawable_filter_set_opacity (GimpDrawabl
gdouble opacity);
void gimp_drawable_filter_set_blend_mode (GimpDrawableFilter *filter,
GimpLayerMode mode);
void gimp_drawable_filter_set_aux_input (GimpDrawableFilter *filter,
const gchar *input_pad_name,
GimpDrawable *input);
GimpDrawableFilterConfig * gimp_drawable_filter_get_config (GimpDrawableFilter *filter);

View file

@ -357,6 +357,8 @@ gimp_drawable_filter_get_blend_mode (GimpDrawableFilter *filter)
* @blend_space: The effect blending space.
* @composite_mode: The layer composite mode.
* @composite_space: The effect composite space.
* @auxinputnames: (array zero-terminated=1): Array of aux input pads.
* @auxinputs: (element-type GimpDrawable) (array zero-terminated=1): Array of drawables, one per auxinputnames.
*
* Update the settings of the specified filter.
*
@ -379,7 +381,9 @@ _gimp_drawable_filter_update (GimpDrawableFilter *filter,
GimpLayerMode blend_mode,
GimpLayerColorSpace blend_space,
GimpLayerCompositeMode composite_mode,
GimpLayerColorSpace composite_space)
GimpLayerColorSpace composite_space,
const gchar **auxinputnames,
const GimpDrawable **auxinputs)
{
GimpValueArray *args;
GimpValueArray *return_vals;
@ -394,6 +398,8 @@ _gimp_drawable_filter_update (GimpDrawableFilter *filter,
GIMP_TYPE_LAYER_COLOR_SPACE, blend_space,
GIMP_TYPE_LAYER_COMPOSITE_MODE, composite_mode,
GIMP_TYPE_LAYER_COLOR_SPACE, composite_space,
G_TYPE_STRV, auxinputnames,
GIMP_TYPE_CORE_OBJECT_ARRAY, auxinputs,
G_TYPE_NONE);
return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),

View file

@ -50,7 +50,9 @@ G_GNUC_INTERNAL gboolean _gimp_drawable_filter_update (GimpDraw
GimpLayerMode blend_mode,
GimpLayerColorSpace blend_space,
GimpLayerCompositeMode composite_mode,
GimpLayerColorSpace composite_space);
GimpLayerColorSpace composite_space,
const gchar **auxinputnames,
const GimpDrawable **auxinputs);
G_GNUC_INTERNAL gint _gimp_drawable_filter_get_number_arguments (const gchar *operation_name);
G_GNUC_INTERNAL GParamSpec* _gimp_drawable_filter_get_pspec (const gchar *operation_name,
gint arg_num);

View file

@ -336,6 +336,10 @@ HELP
{ name => 'composite_space', type => 'enum GimpLayerColorSpace',
default => 'GIMP_LAYER_COLOR_SPACE_AUTO',
desc => 'The effect composite space' },
{ name => 'auxinputnames', type => 'strv',
desc => 'Array of aux input pads' },
{ name => 'auxinputs', type => 'drawablearray', no_validate => 1,
desc => 'Array of drawables, one per auxinputnames' },
);
%invoke = (
@ -345,6 +349,7 @@ HELP
opacity,
blend_mode, blend_space,
composite_mode, composite_space,
auxinputnames, auxinputs,
error);
}
CODE