app, pdb, plug-ins: replace (plug-in-displace).

For plug-in writers reference, these are equivalent:

- (plug-in-displace RUN-NONINTERACTIVE work-image frame-layer
-                   x-displacement y-displacement
-                   TRUE TRUE aux1 aux2 abyss))
+ (let* ((abyss "black")
+        (filter (car (gimp-drawable-filter-new frame-layer "gegl:displace" ""))))
+
+   (if (= edge-type 1) (set! abyss "loop"))
+   (if (= edge-type 2) (set! abyss "clamp"))
+
+   (gimp-drawable-filter-configure filter LAYER-MODE-REPLACE 1.0
+                                   "amount-x" x-displacement "amount-x" y-displacement "abyss-policy" abyss
+                                   "sampler-type" "cubic" "displace-mode" "cartesian")
+   (gimp-drawable-filter-set-aux-input filter "aux" aux1)
+   (gimp-drawable-filter-set-aux-input filter "aux2" aux2)
+   (gimp-drawable-merge-filter frame-layer filter)
+ )

I also changed a test which (I think) was just a no-op since do-x and
do-y were 0 0 (hence FALSE). Therefore the whole filter processing was
ignored. Note though that unlike the rippling animation filter, I
haven't tested the test script.
This commit is contained in:
Jehan 2024-12-17 00:15:04 +01:00
parent c663c8cd2d
commit e2d7cc163e
5 changed files with 23 additions and 337 deletions

View File

@ -30,7 +30,7 @@
#include "internal-procs.h"
/* 720 procedures registered total */
/* 719 procedures registered total */
void
internal_procs_init (GimpPDB *pdb)

View File

@ -220,79 +220,6 @@ bump_map (GimpDrawable *drawable,
return FALSE;
}
static gboolean
displace (GimpDrawable *drawable,
gdouble amount_x,
gdouble amount_y,
gboolean do_x,
gboolean do_y,
GimpDrawable *displace_map_x,
GimpDrawable *displace_map_y,
gint displace_type,
gint displace_mode,
GimpProgress *progress,
GError **error)
{
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))
{
if (do_x || do_y)
{
GeglNode *graph;
GeglNode *node;
GeglAbyssPolicy abyss_policy = GEGL_ABYSS_NONE;
switch (displace_type)
{
case 1:
abyss_policy = GEGL_ABYSS_LOOP;
break;
case 2:
abyss_policy = GEGL_ABYSS_CLAMP;
break;
case 3:
abyss_policy = GEGL_ABYSS_BLACK;
break;
}
node = gegl_node_new_child (NULL,
"operation", "gegl:displace",
"displace_mode", displace_mode,
"sampler_type", GEGL_SAMPLER_CUBIC,
"abyss_policy", abyss_policy,
"amount_x", amount_x,
"amount_y", amount_y,
NULL);
graph = wrap_in_graph (node);
if (do_x)
{
GeglNode *src_node;
src_node = create_buffer_source_node (graph, displace_map_x);
gegl_node_connect (src_node, "output", node, "aux");
}
if (do_y)
{
GeglNode *src_node;
src_node = create_buffer_source_node (graph, displace_map_y);
gegl_node_connect (src_node, "output", node, "aux2");
}
gimp_drawable_apply_operation (drawable, progress,
C_("undo-type", "Displace"),
graph);
g_object_unref (graph);
}
return TRUE;
}
else
return FALSE;
}
static gint
newsprint_color_model (gint colorspace)
{
@ -518,52 +445,6 @@ plug_in_bump_map_invoker (GimpProcedure *procedure,
error ? *error : NULL);
}
static GimpValueArray *
plug_in_displace_invoker (GimpProcedure *procedure,
Gimp *gimp,
GimpContext *context,
GimpProgress *progress,
const GimpValueArray *args,
GError **error)
{
gboolean success = TRUE;
GimpDrawable *drawable;
gdouble amount_x;
gdouble amount_y;
gboolean do_x;
gboolean do_y;
GimpDrawable *displace_map_x;
GimpDrawable *displace_map_y;
gint displace_type;
drawable = g_value_get_object (gimp_value_array_index (args, 2));
amount_x = g_value_get_double (gimp_value_array_index (args, 3));
amount_y = g_value_get_double (gimp_value_array_index (args, 4));
do_x = g_value_get_boolean (gimp_value_array_index (args, 5));
do_y = g_value_get_boolean (gimp_value_array_index (args, 6));
displace_map_x = g_value_get_object (gimp_value_array_index (args, 7));
displace_map_y = g_value_get_object (gimp_value_array_index (args, 8));
displace_type = g_value_get_int (gimp_value_array_index (args, 9));
if (success)
{
success = displace (drawable,
amount_x,
amount_y,
do_x,
do_y,
displace_map_x,
displace_map_y,
displace_type,
0,
progress,
error);
}
return gimp_procedure_get_return_values (procedure, success,
error ? *error : NULL);
}
void
register_plug_in_compat_procs (GimpPDB *pdb)
{
@ -742,82 +623,4 @@ register_plug_in_compat_procs (GimpPDB *pdb)
GIMP_PARAM_READWRITE));
gimp_pdb_register_procedure (pdb, procedure);
g_object_unref (procedure);
/*
* gimp-plug-in-displace
*/
procedure = gimp_procedure_new (plug_in_displace_invoker);
gimp_object_set_static_name (GIMP_OBJECT (procedure),
"plug-in-displace");
gimp_procedure_set_static_help (procedure,
"Displace pixels as indicated by displacement maps",
"Displaces the contents of the specified drawable by the amounts specified by 'amount-x' and 'amount-y' multiplied by the luminance of corresponding pixels in the 'displace-map' drawables.",
NULL);
gimp_procedure_set_static_attribution (procedure,
"Compatibility procedure. Please see 'gegl:displace' for credits.",
"Compatibility procedure. Please see 'gegl:displace' for credits.",
"2015");
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 ("image",
"image",
"Input image (unused)",
FALSE,
GIMP_PARAM_READWRITE));
gimp_procedure_add_argument (procedure,
gimp_param_spec_drawable ("drawable",
"drawable",
"Input drawable",
FALSE,
GIMP_PARAM_READWRITE));
gimp_procedure_add_argument (procedure,
g_param_spec_double ("amount-x",
"amount x",
"Displace multiplier for x direction",
-500.0, 500.0, -500.0,
GIMP_PARAM_READWRITE));
gimp_procedure_add_argument (procedure,
g_param_spec_double ("amount-y",
"amount y",
"Displace multiplier for y direction",
-500.0, 500.0, -500.0,
GIMP_PARAM_READWRITE));
gimp_procedure_add_argument (procedure,
g_param_spec_boolean ("do-x",
"do x",
"Displace in x direction ?",
FALSE,
GIMP_PARAM_READWRITE));
gimp_procedure_add_argument (procedure,
g_param_spec_boolean ("do-y",
"do y",
"Displace in y direction ?",
FALSE,
GIMP_PARAM_READWRITE));
gimp_procedure_add_argument (procedure,
gimp_param_spec_drawable ("displace-map-x",
"displace map x",
"Displacement map for x direction",
FALSE,
GIMP_PARAM_READWRITE));
gimp_procedure_add_argument (procedure,
gimp_param_spec_drawable ("displace-map-y",
"displace map y",
"Displacement map for y direction",
FALSE,
GIMP_PARAM_READWRITE));
gimp_procedure_add_argument (procedure,
g_param_spec_int ("displace-type",
"displace type",
"Edge behavior { WRAP (1), SMEAR (2), BLACK (3) }",
1, 3, 1,
GIMP_PARAM_READWRITE));
gimp_pdb_register_procedure (pdb, procedure);
g_object_unref (procedure);
}

View File

@ -225,60 +225,6 @@ CODE
);
}
sub plug_in_displace {
$blurb = 'Displace pixels as indicated by displacement maps';
$help = <<'HELP';
Displaces the contents of the specified drawable by the amounts specified
by 'amount-x' and 'amount-y' multiplied by the luminance of corresponding
pixels in the 'displace-map' drawables.
HELP
&std_pdb_compat('gegl:displace');
$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 <= double <= 500.0',
desc => 'Displace multiplier for x direction' },
{ name => 'amount_y', type => '-500.0 <= double <= 500.0',
desc => 'Displace multiplier for y direction' },
{ name => 'do_x', type => 'boolean',
desc => 'Displace in x direction ?' },
{ name => 'do_y', type => 'boolean',
desc => 'Displace in y direction ?' },
{ name => 'displace_map_x', type => 'drawable',
desc => 'Displacement map for x direction' },
{ name => 'displace_map_y', type => 'drawable',
desc => 'Displacement map for y direction' },
{ name => 'displace_type', type => '1 <= int32 <= 3',
desc => 'Edge behavior { WRAP (1), SMEAR (2), BLACK (3) }' }
);
%invoke = (
code => <<'CODE'
{
success = displace (drawable,
amount_x,
amount_y,
do_x,
do_y,
displace_map_x,
displace_map_y,
displace_type,
0,
progress,
error);
}
CODE
);
}
# We simplify the GEGL signature, reducing tile width and height to just size
$extra{app}->{code} = <<'CODE';
@ -440,79 +386,6 @@ bump_map (GimpDrawable *drawable,
return FALSE;
}
static gboolean
displace (GimpDrawable *drawable,
gdouble amount_x,
gdouble amount_y,
gboolean do_x,
gboolean do_y,
GimpDrawable *displace_map_x,
GimpDrawable *displace_map_y,
gint displace_type,
gint displace_mode,
GimpProgress *progress,
GError **error)
{
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))
{
if (do_x || do_y)
{
GeglNode *graph;
GeglNode *node;
GeglAbyssPolicy abyss_policy = GEGL_ABYSS_NONE;
switch (displace_type)
{
case 1:
abyss_policy = GEGL_ABYSS_LOOP;
break;
case 2:
abyss_policy = GEGL_ABYSS_CLAMP;
break;
case 3:
abyss_policy = GEGL_ABYSS_BLACK;
break;
}
node = gegl_node_new_child (NULL,
"operation", "gegl:displace",
"displace_mode", displace_mode,
"sampler_type", GEGL_SAMPLER_CUBIC,
"abyss_policy", abyss_policy,
"amount_x", amount_x,
"amount_y", amount_y,
NULL);
graph = wrap_in_graph (node);
if (do_x)
{
GeglNode *src_node;
src_node = create_buffer_source_node (graph, displace_map_x);
gegl_node_connect (src_node, "output", node, "aux");
}
if (do_y)
{
GeglNode *src_node;
src_node = create_buffer_source_node (graph, displace_map_y);
gegl_node_connect (src_node, "output", node, "aux2");
}
gimp_drawable_apply_operation (drawable, progress,
C_("undo-type", "Displace"),
graph);
g_object_unref (graph);
}
return TRUE;
}
else
return FALSE;
}
static gint
newsprint_color_model (gint colorspace)
{
@ -579,8 +452,7 @@ CODE
@procs = qw(plug_in_autocrop
plug_in_autocrop_layer
plug_in_bump_map
plug_in_displace);
plug_in_bump_map);
%exports = (app => [@procs], lib => []);

View File

@ -51,9 +51,19 @@
(number->string (+ 1 (- num-frames
remaining-frames)))
" (replace)"))
(plug-in-displace RUN-NONINTERACTIVE work-image frame-layer
displacement displacement
TRUE TRUE map-layer map-layer (+ edge-type 1))
(let* ((abyss "black")
(filter (car (gimp-drawable-filter-new frame-layer "gegl:displace" ""))))
(if (= edge-type 0) (set! abyss "loop"))
(if (= edge-type 1) (set! abyss "clamp"))
(gimp-drawable-filter-configure filter LAYER-MODE-REPLACE 1.0
"amount-x" displacement "amount-x" displacement "abyss-policy" abyss
"sampler-type" "cubic" "displace-mode" "cartesian")
(gimp-drawable-filter-set-aux-input filter "aux" map-layer)
(gimp-drawable-filter-set-aux-input filter "aux2" map-layer)
(gimp-drawable-merge-filter frame-layer filter)
)
(gimp-item-set-visible frame-layer TRUE))
(gimp-drawable-offset map-layer
TRUE

View File

@ -292,13 +292,14 @@
; These are NOT the declared defaults.
(test! "displace")
(testImageCreator)
(assert `(plug-in-displace
RUN-NONINTERACTIVE ,testImage ,testLayer
0 0 ; x, y default is -500
0 0 ; do displace x, y booleans
,testLayer ,testLayer ; x, y maps
1 ; edge behaviour
))
(let* ((filter (car (gimp-drawable-filter-new ,testLayer "gegl:displace" ""))))
(gimp-drawable-filter-configure filter LAYER-MODE-REPLACE 1.0
"amount-x" 0.0 "amount-x" 0.0 "abyss-policy" "loop"
"sampler-type" "cubic" "displace-mode" "cartesian")
(gimp-drawable-filter-set-aux-input filter "aux" ,testLayer)
(gimp-drawable-filter-set-aux-input filter "aux2" ,testLayer)
(gimp-drawable-merge-filter ,testLayer filter)
)
(gimp-display-new testImage)
(gimp-displays-flush)
)