gimp/pdb/groups/color.pdb

763 lines
24 KiB
Plaintext

# 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/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
sub brightness_contrast {
&std_pdb_deprecated ('gimp-drawable-brightness-contrast');
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' },
{ name => 'brightness', type => '-127 <= int32 <= 127',
desc => 'Brightness adjustment' },
{ name => 'contrast', type => '-127 <= int32 <= 127',
desc => 'Contrast adjustment' }
);
%invoke = (
headers => [ qw("operations/gimpbrightnesscontrastconfig.h") ],
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))
{
GObject *config = g_object_new (GIMP_TYPE_BRIGHTNESS_CONTRAST_CONFIG,
"brightness", brightness / 127.0,
"contrast", contrast / 127.0,
NULL);
gimp_drawable_apply_operation_by_name (drawable, progress,
C_("undo-type", "Brightness-Contrast"),
"gimp:brightness-contrast",
config);
g_object_unref (config);
}
else
success = FALSE;
}
CODE
);
}
sub levels {
&std_pdb_deprecated ('gimp-drawable-levels');
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' },
{ name => 'channel', type => 'enum GimpHistogramChannel',
desc => 'The channel to modify' },
{ name => 'low_input', type => '0 <= int32 <= 255',
desc => "Intensity of lowest input" },
{ name => 'high_input', type => '0 <= int32 <= 255',
desc => "Intensity of highest input" },
{ name => 'gamma', type => '0.1 <= float <= 10',
desc => 'Gamma adjustment factor' },
{ name => 'low_output', type => '0 <= int32 <= 255',
desc => "Intensity of lowest output" },
{ name => 'high_output', type => '0 <= int32 <= 255',
desc => "Intensity of highest output" }
);
%invoke = (
headers => [ qw("operations/gimplevelsconfig.h") ],
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) &&
channel != GIMP_HISTOGRAM_LUMINANCE &&
(gimp_drawable_has_alpha (drawable) || channel != GIMP_HISTOGRAM_ALPHA) &&
(! gimp_drawable_is_gray (drawable) ||
channel == GIMP_HISTOGRAM_VALUE || channel == GIMP_HISTOGRAM_ALPHA))
{
GObject *config = g_object_new (GIMP_TYPE_LEVELS_CONFIG,
"channel", channel,
NULL);
g_object_set (config,
"low-input", low_input / 255.0,
"high-input", high_input / 255.0,
"clamp-input", TRUE,
"gamma", gamma,
"low-output", low_output / 255.0,
"high-output", high_output / 255.0,
"clamp-input", TRUE,
NULL);
gimp_drawable_apply_operation_by_name (drawable, progress,
C_("undo-type", "Levels"),
"gimp:levels",
config);
g_object_unref (config);
}
else
success = TRUE;
}
CODE
);
}
sub levels_stretch {
&std_pdb_deprecated ('gimp-drawable-levels-stretch');
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' }
);
%invoke = (
headers => [ qw("core/gimpdrawable-levels.h") ],
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))
{
gimp_drawable_levels_stretch (drawable, progress);
}
else
success = FALSE;
}
CODE
);
}
sub levels_auto {
&std_pdb_deprecated ('gimp-drawable-levels-stretch');
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' }
);
%invoke = (
headers => [ qw("core/gimpdrawable-levels.h") ],
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))
{
gimp_drawable_levels_stretch (drawable, progress);
}
else
success = FALSE;
}
CODE
);
}
sub posterize {
&std_pdb_deprecated ('gimp-drawable-posterize');
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' },
{ name => 'levels', type => '2 <= int32 <= 255',
desc => 'Levels of posterization' }
);
%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 =
gegl_node_new_child (NULL,
"operation", "gimp:posterize",
"levels", levels,
NULL);
gimp_drawable_apply_operation (drawable, progress,
C_("undo-type", "Posterize"),
node);
g_object_unref (node);
}
else
success = FALSE;
}
CODE
);
}
sub desaturate {
&std_pdb_deprecated ('gimp-drawable-desaturate');
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' }
);
%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) &&
gimp_drawable_is_rgb (drawable))
{
GeglNode *node =
gegl_node_new_child (NULL,
"operation", "gimp:desaturate",
"mode", GIMP_DESATURATE_LIGHTNESS,
NULL);
gimp_drawable_apply_operation (drawable, progress,
C_("undo-type", "Desaturate"),
node);
g_object_unref (node);
}
else
success = FALSE;
}
CODE
);
}
sub desaturate_full {
&std_pdb_deprecated ('gimp-drawable-desaturate');
$since = '2.4';
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' },
{ name => 'desaturate_mode', type => 'enum GimpDesaturateMode',
desc => 'The formula to use to desaturate' }
);
%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) &&
gimp_drawable_is_rgb (drawable))
{
GeglNode *node =
gegl_node_new_child (NULL,
"operation", "gimp:desaturate",
"mode", desaturate_mode,
NULL);
gimp_drawable_apply_operation (drawable, progress,
C_("undo-type", "Desaturate"),
node);
g_object_unref (node);
}
else
success = FALSE;
}
CODE
);
}
sub equalize {
&std_pdb_deprecated ('gimp-drawable-equalize');
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' },
{ name => 'mask_only', type => 'boolean',
desc => 'Equalization option' }
);
%invoke = (
headers => [ qw("core/gimpdrawable-equalize.h") ],
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))
success = FALSE;
if (success)
gimp_drawable_equalize (drawable, mask_only);
}
CODE
);
}
sub invert {
&std_pdb_deprecated ('gimp-drawable-invert');
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' }
);
%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))
{
gimp_drawable_apply_operation_by_name (drawable, progress,
_("Invert"),
"gegl:invert-gamma",
NULL);
}
else
success = FALSE;
}
CODE
);
}
sub curves_spline {
&std_pdb_deprecated ('gimp-drawable-curves-spline');
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' },
{ name => 'channel', type => 'enum GimpHistogramChannel',
desc => 'The channel to modify' },
{ name => 'control_pts', type => 'int8array',
desc => 'The spline control points: { cp1.x, cp1.y, cp2.x, cp2.y,
... }',
array => { name => 'num_points', type => '4 <= int32 <= 34',
desc => 'The number of values in the control point array' }
}
);
%invoke = (
headers => [ qw("operations/gimpcurvesconfig.h") ],
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) &&
! (num_points & 1) &&
(gimp_drawable_has_alpha (drawable) || channel != GIMP_HISTOGRAM_ALPHA) &&
(! gimp_drawable_is_gray (drawable) ||
channel == GIMP_HISTOGRAM_VALUE || channel == GIMP_HISTOGRAM_ALPHA) &&
channel != GIMP_HISTOGRAM_LUMINANCE)
{
GObject *config = gimp_curves_config_new_spline_cruft (channel,
control_pts,
num_points / 2);
gimp_drawable_apply_operation_by_name (drawable, progress,
C_("undo-type", "Curves"),
"gimp:curves",
config);
g_object_unref (config);
}
else
success = FALSE;
}
CODE
);
}
sub curves_explicit {
&std_pdb_deprecated ('gimp-drawable-curves-explicit');
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' },
{ name => 'channel', type => 'enum GimpHistogramChannel',
desc => 'The channel to modify' },
{ name => 'curve', type => 'int8array',
desc => 'The explicit curve',
array => { name => 'num_bytes',
desc => 'The number of bytes in the new curve (always
256)' } }
);
%invoke = (
headers => [ qw("operations/gimpcurvesconfig.h") ],
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) &&
(num_bytes == 256) &&
(gimp_drawable_has_alpha (drawable) || channel != GIMP_HISTOGRAM_ALPHA) &&
(! gimp_drawable_is_gray (drawable) ||
channel == GIMP_HISTOGRAM_VALUE || channel == GIMP_HISTOGRAM_ALPHA) &&
channel != GIMP_HISTOGRAM_LUMINANCE)
{
GObject *config = gimp_curves_config_new_explicit_cruft (channel,
curve,
num_bytes);
gimp_drawable_apply_operation_by_name (drawable, progress,
C_("undo-type", "Curves"),
"gimp:curves",
config);
g_object_unref (config);
}
else
success = FALSE;
}
CODE
);
}
sub color_balance {
$blurb = 'Modify the color balance of the specified drawable.';
$help = <<'HELP';
Modify the color balance of the specified drawable. There are three axis which
can be modified: cyan-red, magenta-green, and yellow-blue. Negative values
increase the amount of the former, positive values increase the amount of the
latter. Color balance can be controlled with the 'transfer_mode' setting, which
allows shadows, mid-tones, and highlights in an image to be affected
differently. The 'preserve-lum' parameter, if TRUE, ensures that the
luminosity of each pixel remains fixed.
HELP
&std_pdb_misc;
$date = '1997';
$deprecated = 'gimp-drawable-color-color-balance';
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' },
{ name => 'transfer_mode', type => 'enum GimpTransferMode',
desc => 'Transfer mode' },
{ name => 'preserve_lum', type => 'boolean',
desc => 'Preserve luminosity values at each pixel' },
{ name => 'cyan_red', type => '-100 <= float <= 100',
desc => 'Cyan-Red color balance' },
{ name => 'magenta_green', type => '-100 <= float <= 100',
desc => 'Magenta-Green color balance' },
{ name => 'yellow_blue', type => '-100 <= float <= 100',
desc => 'Yellow-Blue color balance' }
);
%invoke = (
headers => [ qw("operations/gimpcolorbalanceconfig.h") ],
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))
{
GObject *config = g_object_new (GIMP_TYPE_COLOR_BALANCE_CONFIG,
"range", transfer_mode,
"preserve-luminosity", preserve_lum,
NULL);
g_object_set (config,
"cyan-red", cyan_red / 100.0,
"magenta-green", magenta_green / 100.0,
"yellow-blue", yellow_blue / 100.0,
NULL);
gimp_drawable_apply_operation_by_name (drawable, progress,
C_("undo-type", "Color Balance"),
"gimp:color-balance",
config);
g_object_unref (config);
}
else
success = FALSE;
}
CODE
);
}
sub colorize {
&std_pdb_deprecated ('gimp-drawable-colorize-hsl');
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' },
{ name => 'hue', type => '0 <= float <= 360',
desc => 'Hue in degrees' },
{ name => 'saturation', type => '0 <= float <= 100',
desc => 'Saturation in percent' },
{ name => 'lightness', type => '-100 <= float <= 100',
desc => 'Lightness in percent' }
);
%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) &&
! gimp_drawable_is_gray (drawable))
{
GeglNode *node =
gegl_node_new_child (NULL,
"operation", "gimp:colorize",
"hue", hue / 360.0,
"saturation", saturation / 100.0,
"lightness", lightness / 100.0,
NULL);
gimp_drawable_apply_operation (drawable, progress,
C_("undo-type", "Colorize"),
node);
g_object_unref (node);
}
else
success = FALSE;
}
CODE
);
}
sub histogram {
$blurb = <<'BLURB';
Returns information on the intensity histogram for the specified drawable.
BLURB
$help = <<'HELP';
This tool makes it possible to gather information about the intensity
histogram of a drawable. A channel to examine is first specified. This
can be either value, red, green, or blue, depending on whether the
drawable is of type color or grayscale. Second, a range of intensities
are specified. The gimp_histogram() function returns statistics based
on the pixels in the drawable that fall under this range of
values. Mean, standard deviation, median, number of pixels, and
percentile are all returned. Additionally, the total count of pixels
in the image is returned. Counts of pixels are weighted by any
associated alpha values and by the current selection mask. That is,
pixels that lie outside an active selection mask will not be
counted. Similarly, pixels with transparent alpha values will not be
counted. The returned mean, std_dev and median are in the range (0..255)
for 8-bit images, or if the plug-in is not precision-aware, and in the
range (0.0..1.0) otherwise.
HELP
&std_pdb_deprecated ('gimp-drawable-histogram');
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' },
{ name => 'channel', type => 'enum GimpHistogramChannel',
desc => 'The channel to modify' },
{ name => 'start_range', type => '0 <= int32 < 256',
desc => 'Start of the intensity measurement range' },
{ name => 'end_range', type => '0 <= int32 < 256',
desc => 'End of the intensity measurement range' }
);
@outargs = (
{ name => 'mean', type => 'float', void_ret => 1,
desc => 'Mean intensity value' },
{ name => 'std_dev', type => 'float',
desc => 'Standard deviation of intensity values' },
{ name => 'median', type => 'float',
desc => 'Median intensity value' },
{ name => 'pixels', type => 'float',
desc => 'Alpha-weighted pixel count for entire image' },
{ name => 'count', type => 'float',
desc => 'Alpha-weighted pixel count for range' },
{ name => 'percentile', type => 'float',
desc => 'Percentile that range falls under' }
);
%invoke = (
headers => [ qw("core/gimpdrawable-histogram.h"
"core/gimphistogram.h") ],
code => <<'CODE'
{
if (! gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, 0, error) ||
(! gimp_drawable_has_alpha (drawable) &&
channel == GIMP_HISTOGRAM_ALPHA) ||
(gimp_drawable_is_gray (drawable) &&
channel != GIMP_HISTOGRAM_VALUE && channel != GIMP_HISTOGRAM_ALPHA))
success = FALSE;
if (success)
{
GimpHistogram *histogram;
gint start = start_range;
gint end = end_range;
gboolean precision_enabled;
gboolean linear;
gint n_bins;
precision_enabled =
gimp->plug_in_manager->current_plug_in &&
gimp_plug_in_precision_enabled (gimp->plug_in_manager->current_plug_in);
if (precision_enabled)
linear = gimp_drawable_get_linear (drawable);
else
linear = FALSE;
histogram = gimp_histogram_new (linear);
gimp_drawable_calculate_histogram (drawable, histogram, FALSE);
n_bins = gimp_histogram_n_bins (histogram);
if (n_bins != 256)
{
start = ROUND ((gdouble) start * (n_bins - 1) / 255);
end = ROUND ((gdouble) end * (n_bins - 1) / 255);
}
mean = gimp_histogram_get_mean (histogram, channel,
start, end);
std_dev = gimp_histogram_get_std_dev (histogram, channel,
start, end);
median = gimp_histogram_get_median (histogram, channel,
start, end);
pixels = gimp_histogram_get_count (histogram, channel, 0, n_bins - 1);
count = gimp_histogram_get_count (histogram, channel,
start, end);
percentile = count / pixels;
g_object_unref (histogram);
if (n_bins == 256 || ! precision_enabled)
{
mean *= 255;
std_dev *= 255;
median *= 255;
}
}
}
CODE
);
}
sub hue_saturation {
&std_pdb_deprecated ('gimp-drawable-hue-saturation');
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' },
{ name => 'hue_range', type => 'enum GimpHueRange',
desc => 'Range of affected hues' },
{ name => 'hue_offset', type => '-180 <= float <= 180',
desc => 'Hue offset in degrees' },
{ name => 'lightness', type => '-100 <= float <= 100',
desc => 'Lightness modification' },
{ name => 'saturation', type => '-100 <= float <= 100',
desc => 'Saturation modification' }
);
%invoke = (
headers => [ qw("operations/gimphuesaturationconfig.h") ],
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))
{
GObject *config = g_object_new (GIMP_TYPE_HUE_SATURATION_CONFIG,
"range", hue_range,
NULL);
g_object_set (config,
"hue", hue_offset / 180.0,
"saturation", saturation / 100.0,
"lightness", lightness / 100.0,
NULL);
gimp_drawable_apply_operation_by_name (drawable, progress,
_("Hue-Saturation"),
"gimp:hue-saturation",
config);
g_object_unref (config);
}
else
success = FALSE;
}
CODE
);
}
sub threshold {
$blurb = 'Threshold the specified drawable.';
$help = <<'HELP';
This procedures generates a threshold map of the specified drawable. All pixels
between the values of 'low_threshold' and 'high_threshold' are replaced with
white, and all other pixels with black.
HELP
&std_pdb_deprecated ('gimp-drawable-threshold');
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' },
{ name => 'low_threshold', type => '0 <= int32 <= 255',
desc => 'The low threshold value' },
{ name => 'high_threshold', type => '0 <= int32 <= 255',
desc => 'The high threshold value' }
);
%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 =
gegl_node_new_child (NULL,
"operation", "gimp:threshold",
"low", low_threshold / 255.0,
"high", high_threshold / 255.0,
NULL);
gimp_drawable_apply_operation (drawable, progress,
C_("undo-type", "Threshold"),
node);
g_object_unref (node);
}
else
success = FALSE;
}
CODE
);
}
@headers = qw("libgimpmath/gimpmath.h"
"core/gimp.h"
"core/gimpdrawable.h"
"core/gimpdrawable-operation.h"
"plug-in/gimpplugin.h"
"plug-in/gimppluginmanager.h"
"gimppdb-utils.h"
"gimp-intl.h");
@procs = qw(brightness_contrast
levels levels_auto levels_stretch
posterize
desaturate desaturate_full
equalize
invert
curves_spline curves_explicit
color_balance
colorize
histogram
hue_saturation
threshold);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Color';
$doc_title = 'gimpcolor';
$doc_short_desc = 'Functions for manipulating color.';
$doc_long_desc = 'Functions for manipulating color, including curves and histograms.';
1;