Hi,
On a GIMP BBS I've heard that script-fu scripts cannot get the
effect of pushing the "Auto" button in the Image->Colors->Levels
dialog. Here is a patch to add the procedure gimp-levels-auto,
an automatic version of gimp-levels. I believe that all
features of the GIMP should be exported to script-fu scripts.
Comments?
--
KAJIYAMA, Tamito <[EMAIL PROTECTED]>
diff -ru gimp-1.2.1.orig/app/color_cmds.c gimp-1.2.1/app/color_cmds.c
--- gimp-1.2.1.orig/app/color_cmds.c Mon Dec 25 01:40:44 2000
+++ gimp-1.2.1/app/color_cmds.c Thu Mar 15 22:15:42 2001
@@ -35,8 +35,11 @@
#include "lut_funcs.h"
#include "threshold.h"
+#include "libgimp/gimpmath.h" /* for fabs() */
+
static ProcRecord brightness_contrast_proc;
static ProcRecord levels_proc;
+static ProcRecord levels_auto_proc;
static ProcRecord posterize_proc;
static ProcRecord desaturate_proc;
static ProcRecord equalize_proc;
@@ -53,6 +56,7 @@
{
procedural_db_register (&brightness_contrast_proc);
procedural_db_register (&levels_proc);
+ procedural_db_register (&levels_auto_proc);
procedural_db_register (&posterize_proc);
procedural_db_register (&desaturate_proc);
procedural_db_register (&equalize_proc);
@@ -308,6 +312,157 @@
NULL,
{ { levels_invoker } }
};
+
+/* levels_auto */
+static Argument *
+levels_auto_invoker (Argument *args)
+{
+ gboolean success = TRUE;
+ GimpDrawable *drawable;
+ gint32 channel;
+ PixelRegion srcPR, destPR;
+ int x1, y1, x2, y2;
+ GimpLut *lut;
+ int i;
+ int low_input[5];
+ int high_input[5];
+ double gamma[5];
+ int low_output[5];
+ int high_output[5];
+ GimpHistogram *hist;
+ gdouble count, new_count, percentage, next_percentage;
+
+ drawable = gimp_drawable_get_ID (args[0].value.pdb_int);
+ if (drawable == NULL)
+ success = FALSE;
+
+ channel = args[1].value.pdb_int;
+ if (channel < VALUE_LUT || channel > ALPHA_LUT)
+ success = FALSE;
+
+ if (success)
+ {
+ if (gimp_drawable_is_indexed (drawable) ||
+ (!gimp_drawable_has_alpha (drawable) && channel == ALPHA_LUT) ||
+ (gimp_drawable_is_gray (drawable) && channel != GRAY_LUT
+ && channel != ALPHA_LUT))
+ success = FALSE;
+ else
+ {
+ for (i = 0; i < 5; i++)
+ {
+ low_input[i] = 0;
+ high_input[i] = 255;
+ low_output[i] = 0;
+ high_output[i] = 255;
+ gamma[i] = 1.0;
+ }
+
+ hist = gimp_histogram_new ();
+ gimp_histogram_calculate_drawable (hist, drawable);
+
+ count = gimp_histogram_get_count (hist, 0, 255);
+
+ if (count == 0.0)
+ {
+ low_input[channel] = 0;
+ high_input[channel] = 0;
+ }
+ else
+ {
+ /* Set the low input */
+ new_count = 0.0;
+ for (i = 0; i < 255; i++)
+ {
+ new_count += gimp_histogram_get_value(hist, channel, i);
+ percentage = new_count / count;
+ next_percentage =
+ (new_count + gimp_histogram_get_value (hist,
+ channel,
+ i + 1)) / count;
+ if (fabs (percentage - 0.006) <
+ fabs (next_percentage - 0.006))
+ {
+ low_input[channel] = i + 1;
+ break;
+ }
+ }
+ /* Set the high input */
+ new_count = 0.0;
+ for (i = 255; i > 0; i--)
+ {
+ new_count += gimp_histogram_get_value(hist, channel, i);
+ percentage = new_count / count;
+ next_percentage =
+ (new_count + gimp_histogram_get_value (hist,
+ channel,
+ i - 1)) / count;
+ if (fabs (percentage - 0.006) <
+ fabs (next_percentage - 0.006))
+ {
+ high_input[channel] = i - 1;
+ break;
+ }
+ }
+ }
+
+ gimp_histogram_free (hist);
+
+ /* setup the lut */
+ lut = levels_lut_new (gamma, low_input, high_input,
+ low_output, high_output,
+ gimp_drawable_bytes (drawable));
+
+ /* The application should occur only within selection bounds */
+ gimp_drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2);
+
+ pixel_region_init (&srcPR, gimp_drawable_data (drawable),
+ x1, y1, (x2 - x1), (y2 - y1), FALSE);
+ pixel_region_init (&destPR, gimp_drawable_shadow (drawable),
+ x1, y1, (x2 - x1), (y2 - y1), TRUE);
+
+ pixel_regions_process_parallel ((p_func) gimp_lut_process, lut, 2,
+ &srcPR, &destPR);
+
+ gimp_lut_free(lut);
+ gimp_drawable_merge_shadow (drawable, TRUE);
+ drawable_update (drawable, x1, y1, (x2 - x1), (y2 - y1));
+ }
+ }
+
+ return procedural_db_return_args (&levels_auto_proc, success);
+}
+
+static ProcArg levels_auto_inargs[] =
+{
+ {
+ PDB_DRAWABLE,
+ "drawable",
+ "The drawable"
+ },
+ {
+ PDB_INT32,
+ "channel",
+ "The channel to modify: { VALUE_LUT (0), RED_LUT (1), GREEN_LUT (2), BLUE_LUT
+(3), ALPHA_LUT (4) }"
+ },
+};
+
+static ProcRecord levels_auto_proc =
+{
+ "gimp_levels_auto",
+ "Modifies intensity levels in the specified drawable.",
+ "This tool automatically adjusts intensity levels in the specified drawable. This
+tool is only valid on RGB color and grayscale images. It will not operate on indexed
+drawables.",
+ "Spencer Kimball & Peter Mattis",
+ "Spencer Kimball & Peter Mattis",
+ "1995-1996",
+ PDB_INTERNAL,
+ 2,
+ levels_auto_inargs,
+ 0,
+ NULL,
+ { { levels_auto_invoker } }
+};
+/* end of levels_auto */
static Argument *
posterize_invoker (Argument *args)
_______________________________________________
Gimp-developer mailing list
[EMAIL PROTECTED]
http://lists.xcf.berkeley.edu/mailman/listinfo/gimp-developer