# 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 . # "Perlized" from C source by Manish Singh 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;