Replace the value-invert plug-in by its GEGL counterpart
This commit is contained in:
@ -53,6 +53,12 @@ static const GimpActionEntry drawable_actions[] =
|
||||
G_CALLBACK (drawable_invert_cmd_callback),
|
||||
GIMP_HELP_LAYER_INVERT },
|
||||
|
||||
{ "drawable-value-invert", GIMP_STOCK_GEGL,
|
||||
NC_("drawable-action", "_Value Invert"), NULL,
|
||||
NC_("drawable-action", "Invert the brightness of each pixel"),
|
||||
G_CALLBACK (drawable_value_invert_cmd_callback),
|
||||
GIMP_HELP_LAYER_INVERT },
|
||||
|
||||
{ "drawable-levels-stretch", NULL,
|
||||
NC_("drawable-action", "_White Balance"), NULL,
|
||||
NC_("drawable-action", "Automatic white balance correction"),
|
||||
@ -212,6 +218,7 @@ drawable_actions_update (GimpActionGroup *group,
|
||||
|
||||
SET_SENSITIVE ("drawable-equalize", writable && !children && !is_indexed);
|
||||
SET_SENSITIVE ("drawable-invert", writable && !children);
|
||||
SET_SENSITIVE ("drawable-value-invert", writable && !children);
|
||||
SET_SENSITIVE ("drawable-levels-stretch", writable && !children && is_rgb);
|
||||
SET_SENSITIVE ("drawable-offset", writable && !children);
|
||||
|
||||
|
@ -74,18 +74,8 @@ drawable_invert_cmd_callback (GtkAction *action,
|
||||
GimpImage *image;
|
||||
GimpDrawable *drawable;
|
||||
GimpDisplay *display;
|
||||
GtkWidget *widget;
|
||||
return_if_no_drawable (image, drawable, data);
|
||||
return_if_no_display (display, data);
|
||||
return_if_no_widget (widget, data);
|
||||
|
||||
if (gimp_drawable_is_indexed (drawable))
|
||||
{
|
||||
gimp_message_literal (image->gimp,
|
||||
G_OBJECT (widget), GIMP_MESSAGE_WARNING,
|
||||
_("Invert does not operate on indexed layers."));
|
||||
return;
|
||||
}
|
||||
|
||||
gimp_drawable_apply_operation_by_name (drawable, GIMP_PROGRESS (display),
|
||||
_("Invert"), "gegl:invert",
|
||||
@ -93,6 +83,22 @@ drawable_invert_cmd_callback (GtkAction *action,
|
||||
gimp_image_flush (image);
|
||||
}
|
||||
|
||||
void
|
||||
drawable_value_invert_cmd_callback (GtkAction *action,
|
||||
gpointer data)
|
||||
{
|
||||
GimpImage *image;
|
||||
GimpDrawable *drawable;
|
||||
GimpDisplay *display;
|
||||
return_if_no_drawable (image, drawable, data);
|
||||
return_if_no_display (display, data);
|
||||
|
||||
gimp_drawable_apply_operation_by_name (drawable, GIMP_PROGRESS (display),
|
||||
_("Invert"), "gegl:value-invert",
|
||||
NULL);
|
||||
gimp_image_flush (image);
|
||||
}
|
||||
|
||||
void
|
||||
drawable_levels_stretch_cmd_callback (GtkAction *action,
|
||||
gpointer data)
|
||||
|
@ -23,6 +23,8 @@ void drawable_equalize_cmd_callback (GtkAction *action,
|
||||
gpointer data);
|
||||
void drawable_invert_cmd_callback (GtkAction *action,
|
||||
gpointer data);
|
||||
void drawable_value_invert_cmd_callback (GtkAction *action,
|
||||
gpointer data);
|
||||
void drawable_levels_stretch_cmd_callback (GtkAction *action,
|
||||
gpointer data);
|
||||
void drawable_offset_cmd_callback (GtkAction *action,
|
||||
|
@ -28,7 +28,7 @@
|
||||
#include "internal-procs.h"
|
||||
|
||||
|
||||
/* 666 procedures registered total */
|
||||
/* 667 procedures registered total */
|
||||
|
||||
void
|
||||
internal_procs_init (GimpPDB *pdb)
|
||||
|
@ -169,6 +169,43 @@ plug_in_pixelize2_invoker (GimpProcedure *procedure,
|
||||
error ? *error : NULL);
|
||||
}
|
||||
|
||||
static GValueArray *
|
||||
plug_in_vinvert_invoker (GimpProcedure *procedure,
|
||||
Gimp *gimp,
|
||||
GimpContext *context,
|
||||
GimpProgress *progress,
|
||||
const GValueArray *args,
|
||||
GError **error)
|
||||
{
|
||||
gboolean success = TRUE;
|
||||
GimpDrawable *drawable;
|
||||
|
||||
drawable = gimp_value_get_drawable (&args->values[2], gimp);
|
||||
|
||||
if (success)
|
||||
{
|
||||
if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, TRUE, error) &&
|
||||
gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
|
||||
{
|
||||
GeglNode *node =
|
||||
gegl_node_new_child (NULL,
|
||||
"operation", "gegl:value-invert",
|
||||
NULL);
|
||||
|
||||
gimp_drawable_apply_operation (drawable, progress,
|
||||
C_("undo-type", "Value Invert"),
|
||||
node);
|
||||
|
||||
g_object_unref (node);
|
||||
}
|
||||
else
|
||||
success = FALSE;
|
||||
}
|
||||
|
||||
return gimp_procedure_get_return_values (procedure, success,
|
||||
error ? *error : NULL);
|
||||
}
|
||||
|
||||
void
|
||||
register_plug_in_compat_procs (GimpPDB *pdb)
|
||||
{
|
||||
@ -306,4 +343,40 @@ register_plug_in_compat_procs (GimpPDB *pdb)
|
||||
GIMP_PARAM_READWRITE));
|
||||
gimp_pdb_register_procedure (pdb, procedure);
|
||||
g_object_unref (procedure);
|
||||
|
||||
/*
|
||||
* gimp-plug-in-vinvert
|
||||
*/
|
||||
procedure = gimp_procedure_new (plug_in_vinvert_invoker);
|
||||
gimp_object_set_static_name (GIMP_OBJECT (procedure),
|
||||
"plug-in-vinvert");
|
||||
gimp_procedure_set_static_strings (procedure,
|
||||
"plug-in-vinvert",
|
||||
"Invert the brightness of each pixel",
|
||||
"This function takes an indexed/RGB image and inverts its 'value' in HSV space. The upshot of this is that the color and saturation at any given point remains the same, but its brightness is effectively inverted. Quite strange. Sometimes produces unpleasant color artifacts on images from lossy sources (ie. JPEG).",
|
||||
"Spencer Kimball & Peter Mattis",
|
||||
"Spencer Kimball & Peter Mattis",
|
||||
"1997",
|
||||
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_pdb_register_procedure (pdb, procedure);
|
||||
g_object_unref (procedure);
|
||||
}
|
||||
|
@ -500,6 +500,7 @@
|
||||
<separator />
|
||||
<placeholder name="Invert">
|
||||
<menuitem action="drawable-invert" />
|
||||
<menuitem action="drawable-value-invert" />
|
||||
</placeholder>
|
||||
<separator />
|
||||
<menuitem action="config-use-gegl" />
|
||||
|
2
plug-ins/common/.gitignore
vendored
2
plug-ins/common/.gitignore
vendored
@ -270,8 +270,6 @@
|
||||
/unit-editor.exe
|
||||
/unsharp-mask
|
||||
/unsharp-mask.exe
|
||||
/value-invert
|
||||
/value-invert.exe
|
||||
/value-propagate
|
||||
/value-propagate.exe
|
||||
/van-gogh-lic
|
||||
|
@ -178,7 +178,6 @@ libexec_PROGRAMS = \
|
||||
tile-small \
|
||||
unit-editor \
|
||||
unsharp-mask \
|
||||
value-invert \
|
||||
value-propagate \
|
||||
van-gogh-lic \
|
||||
video \
|
||||
@ -2498,21 +2497,6 @@ unsharp_mask_LDADD = \
|
||||
$(INTLLIBS) \
|
||||
$(unsharp_mask_RC)
|
||||
|
||||
value_invert_SOURCES = \
|
||||
value-invert.c
|
||||
|
||||
value_invert_LDADD = \
|
||||
$(libgimp) \
|
||||
$(libgimpmath) \
|
||||
$(libgimpconfig) \
|
||||
$(libgimpcolor) \
|
||||
$(libgimpbase) \
|
||||
$(CAIRO_LIBS) \
|
||||
$(GDK_PIXBUF_LIBS) \
|
||||
$(RT_LIBS) \
|
||||
$(INTLLIBS) \
|
||||
$(value_invert_RC)
|
||||
|
||||
value_propagate_SOURCES = \
|
||||
value-propagate.c
|
||||
|
||||
|
@ -132,7 +132,6 @@ tile_seamless_RC = tile-seamless.rc.o
|
||||
tile_small_RC = tile-small.rc.o
|
||||
unit_editor_RC = unit-editor.rc.o
|
||||
unsharp_mask_RC = unsharp-mask.rc.o
|
||||
value_invert_RC = value-invert.rc.o
|
||||
value_propagate_RC = value-propagate.rc.o
|
||||
van_gogh_lic_RC = van-gogh-lic.rc.o
|
||||
video_RC = video.rc.o
|
||||
|
@ -133,7 +133,6 @@
|
||||
'tile-small' => { ui => 1 },
|
||||
'unit-editor' => { ui => 1 },
|
||||
'unsharp-mask' => { ui => 1 },
|
||||
'value-invert' => {},
|
||||
'value-propagate' => { ui => 1 },
|
||||
'van-gogh-lic' => { ui => 1 },
|
||||
'video' => { ui => 1 },
|
||||
|
@ -1,313 +0,0 @@
|
||||
/* GIMP - The GNU Image Manipulation Program
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Value-Invert plug-in v1.1 by Adam D. Moss, adam@foxbox.org. 1999/02/27
|
||||
*
|
||||
* RGB<->HSV math optimizations by Mukund Sivaraman <muks@mukund.org>
|
||||
* makes the plug-in 2-3 times faster. Using gimp_pixel_rgns_process()
|
||||
* also makes memory management nicer. June 12, 2006.
|
||||
*
|
||||
* The plug-in only does v = 255 - v; for each pixel in the image, or
|
||||
* each entry in the colormap depending upon the type of image, where 'v'
|
||||
* is the value in HSV color model.
|
||||
*
|
||||
* The plug-in code is optimized towards this, in that it is not a full
|
||||
* RGB->HSV->RGB transform, but shortcuts many of the calculations to
|
||||
* effectively only do v = 255 - v. In fact, hue (0-360) is never
|
||||
* calculated. The shortcuts can be derived from running a set of r, g, b
|
||||
* values through the RGB->HSV transform and then from HSV->RGB and solving
|
||||
* out the redundant portions.
|
||||
*
|
||||
* The plug-in also uses integer code exclusively for the main transform.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <libgimp/gimp.h>
|
||||
|
||||
#include "libgimp/stdplugins-intl.h"
|
||||
|
||||
|
||||
#define PLUG_IN_PROC "plug-in-vinvert"
|
||||
|
||||
|
||||
/* 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 vinvert (GimpDrawable *drawable);
|
||||
static void vinvert_indexed (gint32 image_ID);
|
||||
static void vinvert_render_row (const guchar *src,
|
||||
guchar *dest,
|
||||
gint width,
|
||||
gint bpp);
|
||||
|
||||
|
||||
const GimpPlugInInfo PLUG_IN_INFO =
|
||||
{
|
||||
NULL, /* init_proc */
|
||||
NULL, /* quit_proc */
|
||||
query, /* query_proc */
|
||||
run, /* run_proc */
|
||||
};
|
||||
|
||||
|
||||
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 (used for indexed images)" },
|
||||
{ GIMP_PDB_DRAWABLE, "drawable", "Input drawable" }
|
||||
};
|
||||
|
||||
gimp_install_procedure (PLUG_IN_PROC,
|
||||
N_("Invert the brightness of each pixel"),
|
||||
"This function takes an indexed/RGB image and "
|
||||
"inverts its 'value' in HSV space. The upshot of "
|
||||
"this is that the color and saturation at any given "
|
||||
"point remains the same, but its brightness is "
|
||||
"effectively inverted. Quite strange. Sometimes "
|
||||
"produces unpleasant color artifacts on images from "
|
||||
"lossy sources (ie. JPEG).",
|
||||
"Adam D. Moss (adam@foxbox.org), "
|
||||
"Mukund Sivaraman <muks@mukund.org>",
|
||||
"Adam D. Moss (adam@foxbox.org), "
|
||||
"Mukund Sivaraman <muks@mukund.org>",
|
||||
"27th March 1997, "
|
||||
"12th June 2006",
|
||||
N_("_Value Invert"),
|
||||
"RGB*, INDEXED*",
|
||||
GIMP_PLUGIN,
|
||||
G_N_ELEMENTS (args), 0,
|
||||
args, NULL);
|
||||
|
||||
gimp_plugin_menu_register (PLUG_IN_PROC, "<Image>/Colors/Invert");
|
||||
}
|
||||
|
||||
static void
|
||||
run (const gchar *name,
|
||||
gint nparams,
|
||||
const GimpParam *param,
|
||||
gint *nreturn_vals,
|
||||
GimpParam **return_vals)
|
||||
{
|
||||
static GimpParam values[1];
|
||||
GimpPDBStatusType status = GIMP_PDB_SUCCESS;
|
||||
GimpRunMode run_mode;
|
||||
|
||||
INIT_I18N();
|
||||
|
||||
run_mode = param[0].data.d_int32;
|
||||
|
||||
*nreturn_vals = 1;
|
||||
*return_vals = values;
|
||||
|
||||
values[0].type = GIMP_PDB_STATUS;
|
||||
values[0].data.d_status = status;
|
||||
|
||||
if (strcmp (name, PLUG_IN_PROC) == 0)
|
||||
{
|
||||
GimpDrawable *drawable;
|
||||
gint32 image_ID;
|
||||
|
||||
/* Get the specified drawable */
|
||||
|
||||
drawable = gimp_drawable_get (param[2].data.d_drawable);
|
||||
image_ID = param[1].data.d_image;
|
||||
|
||||
/* Make sure that the drawable is indexed or RGB color */
|
||||
|
||||
if (gimp_drawable_is_rgb (drawable->drawable_id))
|
||||
{
|
||||
vinvert (drawable);
|
||||
|
||||
if (run_mode != GIMP_RUN_NONINTERACTIVE)
|
||||
gimp_displays_flush ();
|
||||
}
|
||||
else if (gimp_drawable_is_indexed (drawable->drawable_id))
|
||||
{
|
||||
vinvert_indexed (image_ID);
|
||||
|
||||
if (run_mode != GIMP_RUN_NONINTERACTIVE)
|
||||
gimp_displays_flush ();
|
||||
}
|
||||
else
|
||||
{
|
||||
status = GIMP_PDB_EXECUTION_ERROR;
|
||||
}
|
||||
|
||||
gimp_drawable_detach (drawable);
|
||||
}
|
||||
else
|
||||
{
|
||||
status = GIMP_PDB_CALLING_ERROR;
|
||||
}
|
||||
|
||||
values[0].data.d_status = status;
|
||||
}
|
||||
|
||||
static void
|
||||
vinvert (GimpDrawable *drawable)
|
||||
{
|
||||
gint x, y, width, height;
|
||||
gdouble total, processed;
|
||||
gint update;
|
||||
gint channels;
|
||||
GimpPixelRgn src_rgn, dest_rgn;
|
||||
guchar *src_row, *dest_row;
|
||||
gint i;
|
||||
gpointer pr;
|
||||
|
||||
if (! gimp_drawable_mask_intersect (drawable->drawable_id,
|
||||
&x, &y, &width, &height))
|
||||
return;
|
||||
|
||||
gimp_progress_init (_("Value Invert"));
|
||||
|
||||
channels = gimp_drawable_bpp (drawable->drawable_id);
|
||||
|
||||
gimp_pixel_rgn_init (&src_rgn, drawable, x, y, width, height, FALSE, FALSE);
|
||||
gimp_pixel_rgn_init (&dest_rgn, drawable, x, y, width, height, TRUE, TRUE);
|
||||
|
||||
total = width * height;
|
||||
processed = 0.0;
|
||||
|
||||
for (pr = gimp_pixel_rgns_register (2, &src_rgn, &dest_rgn), update = 0;
|
||||
pr != NULL;
|
||||
pr = gimp_pixel_rgns_process (pr), update++)
|
||||
{
|
||||
src_row = src_rgn.data;
|
||||
dest_row = dest_rgn.data;
|
||||
|
||||
for (i = 0; i < src_rgn.h; i++)
|
||||
{
|
||||
vinvert_render_row (src_row, dest_row, src_rgn.w, channels);
|
||||
|
||||
src_row += src_rgn.rowstride;
|
||||
dest_row += dest_rgn.rowstride;
|
||||
}
|
||||
|
||||
processed += src_rgn.w * src_rgn.h;
|
||||
update %= 16;
|
||||
|
||||
if (update == 0)
|
||||
gimp_progress_update (processed / total);
|
||||
}
|
||||
|
||||
gimp_progress_update (1.0);
|
||||
|
||||
gimp_drawable_flush (drawable);
|
||||
gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
|
||||
gimp_drawable_update (drawable->drawable_id, x, y, width, height);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
vinvert_indexed (gint32 image_ID)
|
||||
{
|
||||
guchar *cmap;
|
||||
gint ncols;
|
||||
|
||||
cmap = gimp_image_get_colormap (image_ID, &ncols);
|
||||
|
||||
g_return_if_fail (cmap != NULL);
|
||||
|
||||
vinvert_render_row (cmap, cmap, ncols, 3);
|
||||
|
||||
gimp_image_set_colormap (image_ID, cmap, ncols);
|
||||
|
||||
g_free (cmap);
|
||||
}
|
||||
|
||||
static void
|
||||
vinvert_render_row (const guchar *src,
|
||||
guchar *dest,
|
||||
gint width, /* in pixels */
|
||||
gint bpp)
|
||||
{
|
||||
gint j;
|
||||
gint r, g, b;
|
||||
gint value, value2, min;
|
||||
gint delta;
|
||||
|
||||
for (j = 0; j < width; j++)
|
||||
{
|
||||
r = *src++;
|
||||
g = *src++;
|
||||
b = *src++;
|
||||
|
||||
if (r > g)
|
||||
{
|
||||
value = MAX (r, b);
|
||||
min = MIN (g, b);
|
||||
}
|
||||
else
|
||||
{
|
||||
value = MAX (g, b);
|
||||
min = MIN (r, b);
|
||||
}
|
||||
|
||||
delta = value - min;
|
||||
if ((value == 0) || (delta == 0))
|
||||
{
|
||||
r = 255 - value;
|
||||
g = 255 - value;
|
||||
b = 255 - value;
|
||||
}
|
||||
else
|
||||
{
|
||||
value2 = value / 2;
|
||||
|
||||
if (r == value)
|
||||
{
|
||||
r = 255 - r;
|
||||
b = ((r * b) + value2) / value;
|
||||
g = ((r * g) + value2) / value;
|
||||
}
|
||||
else if (g == value)
|
||||
{
|
||||
g = 255 - g;
|
||||
r = ((g * r) + value2) / value;
|
||||
b = ((g * b) + value2) / value;
|
||||
}
|
||||
else
|
||||
{
|
||||
b = 255 - b;
|
||||
g = ((b * g) + value2) / value;
|
||||
r = ((b * r) + value2) / value;
|
||||
}
|
||||
}
|
||||
|
||||
*dest++ = r;
|
||||
*dest++ = g;
|
||||
*dest++ = b;
|
||||
|
||||
if (bpp == 4)
|
||||
*dest++ = *src++;
|
||||
}
|
||||
}
|
@ -165,6 +165,53 @@ CODE
|
||||
);
|
||||
}
|
||||
|
||||
sub plug_in_vinvert {
|
||||
$blurb = 'Invert the brightness of each pixel';
|
||||
|
||||
$help = <<'HELP';
|
||||
This function takes an indexed/RGB image and inverts its 'value' in
|
||||
HSV space. The upshot of this is that the color and saturation at any
|
||||
given point remains the same, but its brightness is effectively
|
||||
inverted. Quite strange. Sometimes produces unpleasant color
|
||||
artifacts on images from lossy sources (ie. JPEG).
|
||||
HELP
|
||||
|
||||
&std_pdb_misc;
|
||||
$date = '1997';
|
||||
|
||||
@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' }
|
||||
);
|
||||
|
||||
%invoke = (
|
||||
code => <<'CODE'
|
||||
{
|
||||
if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, TRUE, error) &&
|
||||
gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
|
||||
{
|
||||
GeglNode *node =
|
||||
gegl_node_new_child (NULL,
|
||||
"operation", "gegl:value-invert",
|
||||
NULL);
|
||||
|
||||
gimp_drawable_apply_operation (drawable, progress,
|
||||
C_("undo-type", "Value Invert"),
|
||||
node);
|
||||
|
||||
g_object_unref (node);
|
||||
}
|
||||
else
|
||||
success = FALSE;
|
||||
}
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@headers = qw("libgimpbase/gimpbase.h"
|
||||
"gegl/gimp-gegl-utils.h"
|
||||
@ -175,7 +222,8 @@ CODE
|
||||
|
||||
@procs = qw(plug_in_colortoalpha
|
||||
plug_in_pixelize
|
||||
plug_in_pixelize2);
|
||||
plug_in_pixelize2
|
||||
plug_in_vinvert);
|
||||
|
||||
%exports = (app => [@procs], lib => []);
|
||||
|
||||
|
Reference in New Issue
Block a user