1 /* GIMP - The GNU Image Manipulation Program
2  * Copyright (C) 1995-2003 Spencer Kimball and Peter Mattis
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 /* NOTE: This file is auto-generated by pdbgen.pl. */
19 
20 #include "config.h"
21 
22 #include <gegl.h>
23 
24 #include <gdk-pixbuf/gdk-pixbuf.h>
25 
26 #include "libgimpmath/gimpmath.h"
27 
28 #include "libgimpbase/gimpbase.h"
29 
30 #include "pdb-types.h"
31 
32 #include "core/gimp.h"
33 #include "core/gimpdrawable-equalize.h"
34 #include "core/gimpdrawable-histogram.h"
35 #include "core/gimpdrawable-levels.h"
36 #include "core/gimpdrawable-operation.h"
37 #include "core/gimpdrawable.h"
38 #include "core/gimphistogram.h"
39 #include "core/gimpparamspecs.h"
40 #include "operations/gimpbrightnesscontrastconfig.h"
41 #include "operations/gimpcolorbalanceconfig.h"
42 #include "operations/gimpcurvesconfig.h"
43 #include "operations/gimphuesaturationconfig.h"
44 #include "operations/gimplevelsconfig.h"
45 #include "plug-in/gimpplugin.h"
46 #include "plug-in/gimppluginmanager.h"
47 
48 #include "gimppdb.h"
49 #include "gimppdb-utils.h"
50 #include "gimpprocedure.h"
51 #include "internal-procs.h"
52 
53 #include "gimp-intl.h"
54 
55 
56 static GimpValueArray *
drawable_brightness_contrast_invoker(GimpProcedure * procedure,Gimp * gimp,GimpContext * context,GimpProgress * progress,const GimpValueArray * args,GError ** error)57 drawable_brightness_contrast_invoker (GimpProcedure         *procedure,
58                                       Gimp                  *gimp,
59                                       GimpContext           *context,
60                                       GimpProgress          *progress,
61                                       const GimpValueArray  *args,
62                                       GError               **error)
63 {
64   gboolean success = TRUE;
65   GimpDrawable *drawable;
66   gdouble brightness;
67   gdouble contrast;
68 
69   drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
70   brightness = g_value_get_double (gimp_value_array_index (args, 1));
71   contrast = g_value_get_double (gimp_value_array_index (args, 2));
72 
73   if (success)
74     {
75       if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
76                                      GIMP_PDB_ITEM_CONTENT, error) &&
77           gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
78         {
79           GObject *config = g_object_new (GIMP_TYPE_BRIGHTNESS_CONTRAST_CONFIG,
80                                           "brightness", brightness,
81                                           "contrast",   contrast,
82                                           NULL);
83 
84           gimp_drawable_apply_operation_by_name (drawable, progress,
85                                                  C_("undo-type", "Brightness-Contrast"),
86                                                  "gimp:brightness-contrast",
87                                                  config);
88           g_object_unref (config);
89         }
90       else
91         success = FALSE;
92     }
93 
94   return gimp_procedure_get_return_values (procedure, success,
95                                            error ? *error : NULL);
96 }
97 
98 static GimpValueArray *
drawable_color_balance_invoker(GimpProcedure * procedure,Gimp * gimp,GimpContext * context,GimpProgress * progress,const GimpValueArray * args,GError ** error)99 drawable_color_balance_invoker (GimpProcedure         *procedure,
100                                 Gimp                  *gimp,
101                                 GimpContext           *context,
102                                 GimpProgress          *progress,
103                                 const GimpValueArray  *args,
104                                 GError               **error)
105 {
106   gboolean success = TRUE;
107   GimpDrawable *drawable;
108   gint32 transfer_mode;
109   gboolean preserve_lum;
110   gdouble cyan_red;
111   gdouble magenta_green;
112   gdouble yellow_blue;
113 
114   drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
115   transfer_mode = g_value_get_enum (gimp_value_array_index (args, 1));
116   preserve_lum = g_value_get_boolean (gimp_value_array_index (args, 2));
117   cyan_red = g_value_get_double (gimp_value_array_index (args, 3));
118   magenta_green = g_value_get_double (gimp_value_array_index (args, 4));
119   yellow_blue = g_value_get_double (gimp_value_array_index (args, 5));
120 
121   if (success)
122     {
123       if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
124                                      GIMP_PDB_ITEM_CONTENT, error)  &&
125           gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
126         {
127           GObject *config = g_object_new (GIMP_TYPE_COLOR_BALANCE_CONFIG,
128                                           "range",               transfer_mode,
129                                           "preserve-luminosity", preserve_lum,
130                                           NULL);
131 
132           g_object_set (config,
133                         "cyan-red",      cyan_red      / 100.0,
134                         "magenta-green", magenta_green / 100.0,
135                         "yellow-blue",   yellow_blue   / 100.0,
136                         NULL);
137 
138           gimp_drawable_apply_operation_by_name (drawable, progress,
139                                                  C_("undo-type", "Color Balance"),
140                                                  "gimp:color-balance",
141                                                  config);
142           g_object_unref (config);
143         }
144       else
145         success = FALSE;
146     }
147 
148   return gimp_procedure_get_return_values (procedure, success,
149                                            error ? *error : NULL);
150 }
151 
152 static GimpValueArray *
drawable_colorize_hsl_invoker(GimpProcedure * procedure,Gimp * gimp,GimpContext * context,GimpProgress * progress,const GimpValueArray * args,GError ** error)153 drawable_colorize_hsl_invoker (GimpProcedure         *procedure,
154                                Gimp                  *gimp,
155                                GimpContext           *context,
156                                GimpProgress          *progress,
157                                const GimpValueArray  *args,
158                                GError               **error)
159 {
160   gboolean success = TRUE;
161   GimpDrawable *drawable;
162   gdouble hue;
163   gdouble saturation;
164   gdouble lightness;
165 
166   drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
167   hue = g_value_get_double (gimp_value_array_index (args, 1));
168   saturation = g_value_get_double (gimp_value_array_index (args, 2));
169   lightness = g_value_get_double (gimp_value_array_index (args, 3));
170 
171   if (success)
172     {
173       if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
174                                      GIMP_PDB_ITEM_CONTENT, error) &&
175           gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error) &&
176           ! gimp_drawable_is_gray (drawable))
177         {
178           GeglNode *node =
179             gegl_node_new_child (NULL,
180                                  "operation", "gimp:colorize",
181                                  "hue",        hue        / 360.0,
182                                  "saturation", saturation / 100.0,
183                                  "lightness",  lightness  / 100.0,
184                                  NULL);
185 
186           gimp_drawable_apply_operation (drawable, progress,
187                                          C_("undo-type", "Colorize"),
188                                          node);
189           g_object_unref (node);
190         }
191       else
192         success = FALSE;
193     }
194 
195   return gimp_procedure_get_return_values (procedure, success,
196                                            error ? *error : NULL);
197 }
198 
199 static GimpValueArray *
drawable_curves_explicit_invoker(GimpProcedure * procedure,Gimp * gimp,GimpContext * context,GimpProgress * progress,const GimpValueArray * args,GError ** error)200 drawable_curves_explicit_invoker (GimpProcedure         *procedure,
201                                   Gimp                  *gimp,
202                                   GimpContext           *context,
203                                   GimpProgress          *progress,
204                                   const GimpValueArray  *args,
205                                   GError               **error)
206 {
207   gboolean success = TRUE;
208   GimpDrawable *drawable;
209   gint32 channel;
210   gint32 num_values;
211   const gdouble *values;
212 
213   drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
214   channel = g_value_get_enum (gimp_value_array_index (args, 1));
215   num_values = g_value_get_int (gimp_value_array_index (args, 2));
216   values = gimp_value_get_floatarray (gimp_value_array_index (args, 3));
217 
218   if (success)
219     {
220       if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
221                                      GIMP_PDB_ITEM_CONTENT, error) &&
222           gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error) &&
223           (num_values >= 256) &&
224           (num_values <= 4096) &&
225           (gimp_drawable_has_alpha (drawable) || channel != GIMP_HISTOGRAM_ALPHA) &&
226           (! gimp_drawable_is_gray (drawable) ||
227            channel == GIMP_HISTOGRAM_VALUE || channel == GIMP_HISTOGRAM_ALPHA) &&
228           channel != GIMP_HISTOGRAM_LUMINANCE)
229         {
230           GObject *config = gimp_curves_config_new_explicit (channel,
231                                                              values,
232                                                              num_values);
233 
234           gimp_drawable_apply_operation_by_name (drawable, progress,
235                                                  C_("undo-type", "Curves"),
236                                                  "gimp:curves",
237                                                  config);
238           g_object_unref (config);
239         }
240       else
241         success = FALSE;
242     }
243 
244   return gimp_procedure_get_return_values (procedure, success,
245                                            error ? *error : NULL);
246 }
247 
248 static GimpValueArray *
drawable_curves_spline_invoker(GimpProcedure * procedure,Gimp * gimp,GimpContext * context,GimpProgress * progress,const GimpValueArray * args,GError ** error)249 drawable_curves_spline_invoker (GimpProcedure         *procedure,
250                                 Gimp                  *gimp,
251                                 GimpContext           *context,
252                                 GimpProgress          *progress,
253                                 const GimpValueArray  *args,
254                                 GError               **error)
255 {
256   gboolean success = TRUE;
257   GimpDrawable *drawable;
258   gint32 channel;
259   gint32 num_points;
260   const gdouble *points;
261 
262   drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
263   channel = g_value_get_enum (gimp_value_array_index (args, 1));
264   num_points = g_value_get_int (gimp_value_array_index (args, 2));
265   points = gimp_value_get_floatarray (gimp_value_array_index (args, 3));
266 
267   if (success)
268     {
269       if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
270                                      GIMP_PDB_ITEM_CONTENT, error) &&
271           gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error) &&
272           ! (num_points & 1) &&
273           (gimp_drawable_has_alpha (drawable) || channel != GIMP_HISTOGRAM_ALPHA) &&
274           (! gimp_drawable_is_gray (drawable) ||
275            channel == GIMP_HISTOGRAM_VALUE || channel == GIMP_HISTOGRAM_ALPHA) &&
276           channel != GIMP_HISTOGRAM_LUMINANCE)
277         {
278           GObject *config = gimp_curves_config_new_spline (channel,
279                                                            points,
280                                                            num_points / 2);
281 
282           gimp_drawable_apply_operation_by_name (drawable, progress,
283                                                  C_("undo-type", "Curves"),
284                                                  "gimp:curves",
285                                                  config);
286           g_object_unref (config);
287         }
288       else
289         success = FALSE;
290     }
291 
292   return gimp_procedure_get_return_values (procedure, success,
293                                            error ? *error : NULL);
294 }
295 
296 static GimpValueArray *
drawable_desaturate_invoker(GimpProcedure * procedure,Gimp * gimp,GimpContext * context,GimpProgress * progress,const GimpValueArray * args,GError ** error)297 drawable_desaturate_invoker (GimpProcedure         *procedure,
298                              Gimp                  *gimp,
299                              GimpContext           *context,
300                              GimpProgress          *progress,
301                              const GimpValueArray  *args,
302                              GError               **error)
303 {
304   gboolean success = TRUE;
305   GimpDrawable *drawable;
306   gint32 desaturate_mode;
307 
308   drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
309   desaturate_mode = g_value_get_enum (gimp_value_array_index (args, 1));
310 
311   if (success)
312     {
313       if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
314                                      GIMP_PDB_ITEM_CONTENT, error) &&
315           gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error) &&
316           gimp_drawable_is_rgb (drawable))
317         {
318           GeglNode *node =
319             gegl_node_new_child (NULL,
320                                  "operation", "gimp:desaturate",
321                                  "mode",      desaturate_mode,
322                                  NULL);
323 
324           gimp_drawable_apply_operation (drawable, progress,
325                                          C_("undo-type", "Desaturate"),
326                                          node);
327           g_object_unref (node);
328         }
329       else
330         success = FALSE;
331     }
332 
333   return gimp_procedure_get_return_values (procedure, success,
334                                            error ? *error : NULL);
335 }
336 
337 static GimpValueArray *
drawable_equalize_invoker(GimpProcedure * procedure,Gimp * gimp,GimpContext * context,GimpProgress * progress,const GimpValueArray * args,GError ** error)338 drawable_equalize_invoker (GimpProcedure         *procedure,
339                            Gimp                  *gimp,
340                            GimpContext           *context,
341                            GimpProgress          *progress,
342                            const GimpValueArray  *args,
343                            GError               **error)
344 {
345   gboolean success = TRUE;
346   GimpDrawable *drawable;
347   gboolean mask_only;
348 
349   drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
350   mask_only = g_value_get_boolean (gimp_value_array_index (args, 1));
351 
352   if (success)
353     {
354       if (! gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
355                                        GIMP_PDB_ITEM_CONTENT, error) ||
356           ! gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
357         success = FALSE;
358 
359       if (success)
360         gimp_drawable_equalize (drawable, mask_only);
361     }
362 
363   return gimp_procedure_get_return_values (procedure, success,
364                                            error ? *error : NULL);
365 }
366 
367 static GimpValueArray *
drawable_histogram_invoker(GimpProcedure * procedure,Gimp * gimp,GimpContext * context,GimpProgress * progress,const GimpValueArray * args,GError ** error)368 drawable_histogram_invoker (GimpProcedure         *procedure,
369                             Gimp                  *gimp,
370                             GimpContext           *context,
371                             GimpProgress          *progress,
372                             const GimpValueArray  *args,
373                             GError               **error)
374 {
375   gboolean success = TRUE;
376   GimpValueArray *return_vals;
377   GimpDrawable *drawable;
378   gint32 channel;
379   gdouble start_range;
380   gdouble end_range;
381   gdouble mean = 0.0;
382   gdouble std_dev = 0.0;
383   gdouble median = 0.0;
384   gdouble pixels = 0.0;
385   gdouble count = 0.0;
386   gdouble percentile = 0.0;
387 
388   drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
389   channel = g_value_get_enum (gimp_value_array_index (args, 1));
390   start_range = g_value_get_double (gimp_value_array_index (args, 2));
391   end_range = g_value_get_double (gimp_value_array_index (args, 3));
392 
393   if (success)
394     {
395       if (! gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, 0, error) ||
396           (! gimp_drawable_has_alpha (drawable) &&
397            channel == GIMP_HISTOGRAM_ALPHA) ||
398           (gimp_drawable_is_gray (drawable) &&
399            channel != GIMP_HISTOGRAM_VALUE && channel != GIMP_HISTOGRAM_ALPHA))
400         success = FALSE;
401 
402       if (success)
403         {
404           GimpHistogram *histogram;
405           gint           n_bins;
406           gint           start;
407           gboolean       precision_enabled;
408           gboolean       linear;
409           gint           end;
410 
411           precision_enabled =
412             gimp->plug_in_manager->current_plug_in &&
413             gimp_plug_in_precision_enabled (gimp->plug_in_manager->current_plug_in);
414 
415           if (precision_enabled)
416             linear = gimp_drawable_get_linear (drawable);
417           else
418             linear = FALSE;
419 
420           histogram = gimp_histogram_new (linear);
421           gimp_drawable_calculate_histogram (drawable, histogram, FALSE);
422 
423           n_bins = gimp_histogram_n_bins (histogram);
424 
425           start = ROUND (start_range * (n_bins - 1));
426           end   = ROUND (end_range   * (n_bins - 1));
427 
428           mean       = gimp_histogram_get_mean (histogram, channel,
429                                                  start, end);
430           std_dev    = gimp_histogram_get_std_dev (histogram, channel,
431                                                    start, end);
432           median     = gimp_histogram_get_median (histogram, channel,
433                                                   start, end);
434           pixels     = gimp_histogram_get_count (histogram, channel, 0, n_bins - 1);
435           count      = gimp_histogram_get_count (histogram, channel,
436                                                  start, end);
437           percentile = count / pixels;
438 
439           g_object_unref (histogram);
440 
441           if (n_bins == 256 || ! precision_enabled)
442             {
443               mean    *= 255;
444               std_dev *= 255;
445               median  *= 255;
446             }
447         }
448     }
449 
450   return_vals = gimp_procedure_get_return_values (procedure, success,
451                                                   error ? *error : NULL);
452 
453   if (success)
454     {
455       g_value_set_double (gimp_value_array_index (return_vals, 1), mean);
456       g_value_set_double (gimp_value_array_index (return_vals, 2), std_dev);
457       g_value_set_double (gimp_value_array_index (return_vals, 3), median);
458       g_value_set_double (gimp_value_array_index (return_vals, 4), pixels);
459       g_value_set_double (gimp_value_array_index (return_vals, 5), count);
460       g_value_set_double (gimp_value_array_index (return_vals, 6), percentile);
461     }
462 
463   return return_vals;
464 }
465 
466 static GimpValueArray *
drawable_hue_saturation_invoker(GimpProcedure * procedure,Gimp * gimp,GimpContext * context,GimpProgress * progress,const GimpValueArray * args,GError ** error)467 drawable_hue_saturation_invoker (GimpProcedure         *procedure,
468                                  Gimp                  *gimp,
469                                  GimpContext           *context,
470                                  GimpProgress          *progress,
471                                  const GimpValueArray  *args,
472                                  GError               **error)
473 {
474   gboolean success = TRUE;
475   GimpDrawable *drawable;
476   gint32 hue_range;
477   gdouble hue_offset;
478   gdouble lightness;
479   gdouble saturation;
480   gdouble overlap;
481 
482   drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
483   hue_range = g_value_get_enum (gimp_value_array_index (args, 1));
484   hue_offset = g_value_get_double (gimp_value_array_index (args, 2));
485   lightness = g_value_get_double (gimp_value_array_index (args, 3));
486   saturation = g_value_get_double (gimp_value_array_index (args, 4));
487   overlap = g_value_get_double (gimp_value_array_index (args, 5));
488 
489   if (success)
490     {
491       if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
492                                      GIMP_PDB_ITEM_CONTENT, error) &&
493           gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
494         {
495           GObject *config = g_object_new (GIMP_TYPE_HUE_SATURATION_CONFIG,
496                                           "range", hue_range,
497                                           NULL);
498 
499            g_object_set (config,
500                          "hue",        hue_offset / 180.0,
501                          "saturation", saturation / 100.0,
502                          "lightness",  lightness  / 100.0,
503                          "overlap",    overlap / 100.0,
504                          NULL);
505 
506           gimp_drawable_apply_operation_by_name (drawable, progress,
507                                                  C_("undo-type", "Hue-Saturation"),
508                                                  "gimp:hue-saturation",
509                                                  config);
510           g_object_unref (config);
511         }
512       else
513         success = FALSE;
514     }
515 
516   return gimp_procedure_get_return_values (procedure, success,
517                                            error ? *error : NULL);
518 }
519 
520 static GimpValueArray *
drawable_invert_invoker(GimpProcedure * procedure,Gimp * gimp,GimpContext * context,GimpProgress * progress,const GimpValueArray * args,GError ** error)521 drawable_invert_invoker (GimpProcedure         *procedure,
522                          Gimp                  *gimp,
523                          GimpContext           *context,
524                          GimpProgress          *progress,
525                          const GimpValueArray  *args,
526                          GError               **error)
527 {
528   gboolean success = TRUE;
529   GimpDrawable *drawable;
530   gboolean linear;
531 
532   drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
533   linear = g_value_get_boolean (gimp_value_array_index (args, 1));
534 
535   if (success)
536     {
537       if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
538                                      GIMP_PDB_ITEM_CONTENT, error) &&
539           gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
540         {
541           gimp_drawable_apply_operation_by_name (drawable, progress,
542                                                  C_("undo-type", "Invert"),
543                                                  linear ?
544                                                  "gegl:invert-linear" :
545                                                  "gegl:invert-gamma",
546                                                  NULL);
547         }
548       else
549         success = FALSE;
550     }
551 
552   return gimp_procedure_get_return_values (procedure, success,
553                                            error ? *error : NULL);
554 }
555 
556 static GimpValueArray *
drawable_levels_invoker(GimpProcedure * procedure,Gimp * gimp,GimpContext * context,GimpProgress * progress,const GimpValueArray * args,GError ** error)557 drawable_levels_invoker (GimpProcedure         *procedure,
558                          Gimp                  *gimp,
559                          GimpContext           *context,
560                          GimpProgress          *progress,
561                          const GimpValueArray  *args,
562                          GError               **error)
563 {
564   gboolean success = TRUE;
565   GimpDrawable *drawable;
566   gint32 channel;
567   gdouble low_input;
568   gdouble high_input;
569   gboolean clamp_input;
570   gdouble gamma;
571   gdouble low_output;
572   gdouble high_output;
573   gboolean clamp_output;
574 
575   drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
576   channel = g_value_get_enum (gimp_value_array_index (args, 1));
577   low_input = g_value_get_double (gimp_value_array_index (args, 2));
578   high_input = g_value_get_double (gimp_value_array_index (args, 3));
579   clamp_input = g_value_get_boolean (gimp_value_array_index (args, 4));
580   gamma = g_value_get_double (gimp_value_array_index (args, 5));
581   low_output = g_value_get_double (gimp_value_array_index (args, 6));
582   high_output = g_value_get_double (gimp_value_array_index (args, 7));
583   clamp_output = g_value_get_boolean (gimp_value_array_index (args, 8));
584 
585   if (success)
586     {
587       if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
588                                      GIMP_PDB_ITEM_CONTENT, error) &&
589           gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error) &&
590           (gimp_drawable_has_alpha (drawable) || channel != GIMP_HISTOGRAM_ALPHA) &&
591           (! gimp_drawable_is_gray (drawable) ||
592            channel == GIMP_HISTOGRAM_VALUE || channel == GIMP_HISTOGRAM_ALPHA) &&
593           channel != GIMP_HISTOGRAM_LUMINANCE)
594         {
595           GObject *config = g_object_new (GIMP_TYPE_LEVELS_CONFIG,
596                                           "channel", channel,
597                                           NULL);
598 
599           g_object_set (config,
600                         "low-input",    low_input,
601                         "high-input",   high_input,
602                         "clamp-input",  clamp_input,
603                         "gamma",        gamma,
604                         "low-output",   low_output,
605                         "high-output",  high_output,
606                         "clamp-output", clamp_output,
607                         NULL);
608 
609           gimp_drawable_apply_operation_by_name (drawable, progress,
610                                                  C_("undo-type", "Levels"),
611                                                  "gimp:levels",
612                                                  config);
613           g_object_unref (config);
614         }
615       else
616         success = TRUE;
617     }
618 
619   return gimp_procedure_get_return_values (procedure, success,
620                                            error ? *error : NULL);
621 }
622 
623 static GimpValueArray *
drawable_levels_stretch_invoker(GimpProcedure * procedure,Gimp * gimp,GimpContext * context,GimpProgress * progress,const GimpValueArray * args,GError ** error)624 drawable_levels_stretch_invoker (GimpProcedure         *procedure,
625                                  Gimp                  *gimp,
626                                  GimpContext           *context,
627                                  GimpProgress          *progress,
628                                  const GimpValueArray  *args,
629                                  GError               **error)
630 {
631   gboolean success = TRUE;
632   GimpDrawable *drawable;
633 
634   drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
635 
636   if (success)
637     {
638       if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
639                                      GIMP_PDB_ITEM_CONTENT, error) &&
640           gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
641         {
642           gimp_drawable_levels_stretch (drawable, progress);
643         }
644       else
645         success = FALSE;
646     }
647 
648   return gimp_procedure_get_return_values (procedure, success,
649                                            error ? *error : NULL);
650 }
651 
652 static GimpValueArray *
drawable_posterize_invoker(GimpProcedure * procedure,Gimp * gimp,GimpContext * context,GimpProgress * progress,const GimpValueArray * args,GError ** error)653 drawable_posterize_invoker (GimpProcedure         *procedure,
654                             Gimp                  *gimp,
655                             GimpContext           *context,
656                             GimpProgress          *progress,
657                             const GimpValueArray  *args,
658                             GError               **error)
659 {
660   gboolean success = TRUE;
661   GimpDrawable *drawable;
662   gint32 levels;
663 
664   drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
665   levels = g_value_get_int (gimp_value_array_index (args, 1));
666 
667   if (success)
668     {
669       if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
670                                      GIMP_PDB_ITEM_CONTENT, error) &&
671           gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
672         {
673           GeglNode *node =
674             gegl_node_new_child (NULL,
675                                  "operation", "gimp:posterize",
676                                  "levels",    levels,
677                                  NULL);
678 
679           gimp_drawable_apply_operation (drawable, progress,
680                                          C_("undo-type", "Posterize"),
681                                          node);
682           g_object_unref (node);
683         }
684       else
685         success = FALSE;
686     }
687 
688   return gimp_procedure_get_return_values (procedure, success,
689                                            error ? *error : NULL);
690 }
691 
692 static GimpValueArray *
drawable_threshold_invoker(GimpProcedure * procedure,Gimp * gimp,GimpContext * context,GimpProgress * progress,const GimpValueArray * args,GError ** error)693 drawable_threshold_invoker (GimpProcedure         *procedure,
694                             Gimp                  *gimp,
695                             GimpContext           *context,
696                             GimpProgress          *progress,
697                             const GimpValueArray  *args,
698                             GError               **error)
699 {
700   gboolean success = TRUE;
701   GimpDrawable *drawable;
702   gint32 channel;
703   gdouble low_threshold;
704   gdouble high_threshold;
705 
706   drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
707   channel = g_value_get_enum (gimp_value_array_index (args, 1));
708   low_threshold = g_value_get_double (gimp_value_array_index (args, 2));
709   high_threshold = g_value_get_double (gimp_value_array_index (args, 3));
710 
711   if (success)
712     {
713       if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
714                                      GIMP_PDB_ITEM_CONTENT, error) &&
715           gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
716         {
717           GeglNode *node =
718             gegl_node_new_child (NULL,
719                                  "operation", "gimp:threshold",
720                                  "channel",   channel,
721                                  "low",       low_threshold,
722                                  "high",      high_threshold,
723                                  NULL);
724 
725           gimp_drawable_apply_operation (drawable, progress,
726                                          C_("undo-type", "Threshold"),
727                                          node);
728           g_object_unref (node);
729         }
730       else
731         success = FALSE;
732     }
733 
734   return gimp_procedure_get_return_values (procedure, success,
735                                            error ? *error : NULL);
736 }
737 
738 void
register_drawable_color_procs(GimpPDB * pdb)739 register_drawable_color_procs (GimpPDB *pdb)
740 {
741   GimpProcedure *procedure;
742 
743   /*
744    * gimp-drawable-brightness-contrast
745    */
746   procedure = gimp_procedure_new (drawable_brightness_contrast_invoker);
747   gimp_object_set_static_name (GIMP_OBJECT (procedure),
748                                "gimp-drawable-brightness-contrast");
749   gimp_procedure_set_static_strings (procedure,
750                                      "gimp-drawable-brightness-contrast",
751                                      "Modify brightness/contrast in the specified drawable.",
752                                      "This procedures allows the brightness and contrast of the specified drawable to be modified. Both 'brightness' and 'contrast' parameters are defined between -0.5 and 0.5.",
753                                      "Spencer Kimball & Peter Mattis",
754                                      "Spencer Kimball & Peter Mattis",
755                                      "1997",
756                                      NULL);
757   gimp_procedure_add_argument (procedure,
758                                gimp_param_spec_drawable_id ("drawable",
759                                                             "drawable",
760                                                             "The drawable",
761                                                             pdb->gimp, FALSE,
762                                                             GIMP_PARAM_READWRITE));
763   gimp_procedure_add_argument (procedure,
764                                g_param_spec_double ("brightness",
765                                                     "brightness",
766                                                     "Brightness adjustment",
767                                                     -0.5, 0.5, -0.5,
768                                                     GIMP_PARAM_READWRITE));
769   gimp_procedure_add_argument (procedure,
770                                g_param_spec_double ("contrast",
771                                                     "contrast",
772                                                     "Contrast adjustment",
773                                                     -0.5, 0.5, -0.5,
774                                                     GIMP_PARAM_READWRITE));
775   gimp_pdb_register_procedure (pdb, procedure);
776   g_object_unref (procedure);
777 
778   /*
779    * gimp-drawable-color-balance
780    */
781   procedure = gimp_procedure_new (drawable_color_balance_invoker);
782   gimp_object_set_static_name (GIMP_OBJECT (procedure),
783                                "gimp-drawable-color-balance");
784   gimp_procedure_set_static_strings (procedure,
785                                      "gimp-drawable-color-balance",
786                                      "Modify the color balance of the specified drawable.",
787                                      "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.",
788                                      "Spencer Kimball & Peter Mattis",
789                                      "Spencer Kimball & Peter Mattis",
790                                      "1997",
791                                      NULL);
792   gimp_procedure_add_argument (procedure,
793                                gimp_param_spec_drawable_id ("drawable",
794                                                             "drawable",
795                                                             "The drawable",
796                                                             pdb->gimp, FALSE,
797                                                             GIMP_PARAM_READWRITE));
798   gimp_procedure_add_argument (procedure,
799                                g_param_spec_enum ("transfer-mode",
800                                                   "transfer mode",
801                                                   "Transfer mode",
802                                                   GIMP_TYPE_TRANSFER_MODE,
803                                                   GIMP_TRANSFER_SHADOWS,
804                                                   GIMP_PARAM_READWRITE));
805   gimp_procedure_add_argument (procedure,
806                                g_param_spec_boolean ("preserve-lum",
807                                                      "preserve lum",
808                                                      "Preserve luminosity values at each pixel",
809                                                      FALSE,
810                                                      GIMP_PARAM_READWRITE));
811   gimp_procedure_add_argument (procedure,
812                                g_param_spec_double ("cyan-red",
813                                                     "cyan red",
814                                                     "Cyan-Red color balance",
815                                                     -100, 100, -100,
816                                                     GIMP_PARAM_READWRITE));
817   gimp_procedure_add_argument (procedure,
818                                g_param_spec_double ("magenta-green",
819                                                     "magenta green",
820                                                     "Magenta-Green color balance",
821                                                     -100, 100, -100,
822                                                     GIMP_PARAM_READWRITE));
823   gimp_procedure_add_argument (procedure,
824                                g_param_spec_double ("yellow-blue",
825                                                     "yellow blue",
826                                                     "Yellow-Blue color balance",
827                                                     -100, 100, -100,
828                                                     GIMP_PARAM_READWRITE));
829   gimp_pdb_register_procedure (pdb, procedure);
830   g_object_unref (procedure);
831 
832   /*
833    * gimp-drawable-colorize-hsl
834    */
835   procedure = gimp_procedure_new (drawable_colorize_hsl_invoker);
836   gimp_object_set_static_name (GIMP_OBJECT (procedure),
837                                "gimp-drawable-colorize-hsl");
838   gimp_procedure_set_static_strings (procedure,
839                                      "gimp-drawable-colorize-hsl",
840                                      "Render the drawable as a grayscale image seen through a colored glass.",
841                                      "Desaturates the drawable, then tints it with the specified color. This tool is only valid on RGB color images. It will not operate on grayscale drawables.",
842                                      "Sven Neumann <sven@gimp.org>",
843                                      "Sven Neumann",
844                                      "2004",
845                                      NULL);
846   gimp_procedure_add_argument (procedure,
847                                gimp_param_spec_drawable_id ("drawable",
848                                                             "drawable",
849                                                             "The drawable",
850                                                             pdb->gimp, FALSE,
851                                                             GIMP_PARAM_READWRITE));
852   gimp_procedure_add_argument (procedure,
853                                g_param_spec_double ("hue",
854                                                     "hue",
855                                                     "Hue in degrees",
856                                                     0, 360, 0,
857                                                     GIMP_PARAM_READWRITE));
858   gimp_procedure_add_argument (procedure,
859                                g_param_spec_double ("saturation",
860                                                     "saturation",
861                                                     "Saturation in percent",
862                                                     0, 100, 0,
863                                                     GIMP_PARAM_READWRITE));
864   gimp_procedure_add_argument (procedure,
865                                g_param_spec_double ("lightness",
866                                                     "lightness",
867                                                     "Lightness in percent",
868                                                     -100, 100, -100,
869                                                     GIMP_PARAM_READWRITE));
870   gimp_pdb_register_procedure (pdb, procedure);
871   g_object_unref (procedure);
872 
873   /*
874    * gimp-drawable-curves-explicit
875    */
876   procedure = gimp_procedure_new (drawable_curves_explicit_invoker);
877   gimp_object_set_static_name (GIMP_OBJECT (procedure),
878                                "gimp-drawable-curves-explicit");
879   gimp_procedure_set_static_strings (procedure,
880                                      "gimp-drawable-curves-explicit",
881                                      "Modifies the intensity curve(s) for specified drawable.",
882                                      "Modifies the intensity mapping for one channel in the specified drawable. The channel can be either an intensity component, or the value. The 'values' parameter is an array of doubles which explicitly defines how each pixel value in the drawable will be modified. Use the 'gimp-curves-spline' function to modify intensity levels with Catmull Rom splines.",
883                                      "Spencer Kimball & Peter Mattis",
884                                      "Spencer Kimball & Peter Mattis",
885                                      "1995-1996",
886                                      NULL);
887   gimp_procedure_add_argument (procedure,
888                                gimp_param_spec_drawable_id ("drawable",
889                                                             "drawable",
890                                                             "The drawable",
891                                                             pdb->gimp, FALSE,
892                                                             GIMP_PARAM_READWRITE));
893   gimp_procedure_add_argument (procedure,
894                                g_param_spec_enum ("channel",
895                                                   "channel",
896                                                   "The channel to modify",
897                                                   GIMP_TYPE_HISTOGRAM_CHANNEL,
898                                                   GIMP_HISTOGRAM_VALUE,
899                                                   GIMP_PARAM_READWRITE));
900   gimp_procedure_add_argument (procedure,
901                                gimp_param_spec_int32 ("num-values",
902                                                       "num values",
903                                                       "The number of values in the new curve",
904                                                       256, 2096, 256,
905                                                       GIMP_PARAM_READWRITE));
906   gimp_procedure_add_argument (procedure,
907                                gimp_param_spec_float_array ("values",
908                                                             "values",
909                                                             "The explicit curve",
910                                                             GIMP_PARAM_READWRITE));
911   gimp_pdb_register_procedure (pdb, procedure);
912   g_object_unref (procedure);
913 
914   /*
915    * gimp-drawable-curves-spline
916    */
917   procedure = gimp_procedure_new (drawable_curves_spline_invoker);
918   gimp_object_set_static_name (GIMP_OBJECT (procedure),
919                                "gimp-drawable-curves-spline");
920   gimp_procedure_set_static_strings (procedure,
921                                      "gimp-drawable-curves-spline",
922                                      "Modifies the intensity curve(s) for specified drawable.",
923                                      "Modifies the intensity mapping for one channel in the specified drawable. The channel can be either an intensity component, or the value. The 'points' parameter is an array of doubles which define a set of control points which describe a Catmull Rom spline which yields the final intensity curve. Use the 'gimp-curves-explicit' function to explicitly modify intensity levels.",
924                                      "Spencer Kimball & Peter Mattis",
925                                      "Spencer Kimball & Peter Mattis",
926                                      "1995-1996",
927                                      NULL);
928   gimp_procedure_add_argument (procedure,
929                                gimp_param_spec_drawable_id ("drawable",
930                                                             "drawable",
931                                                             "The drawable",
932                                                             pdb->gimp, FALSE,
933                                                             GIMP_PARAM_READWRITE));
934   gimp_procedure_add_argument (procedure,
935                                g_param_spec_enum ("channel",
936                                                   "channel",
937                                                   "The channel to modify",
938                                                   GIMP_TYPE_HISTOGRAM_CHANNEL,
939                                                   GIMP_HISTOGRAM_VALUE,
940                                                   GIMP_PARAM_READWRITE));
941   gimp_procedure_add_argument (procedure,
942                                gimp_param_spec_int32 ("num-points",
943                                                       "num points",
944                                                       "The number of values in the control point array",
945                                                       4, 2048, 4,
946                                                       GIMP_PARAM_READWRITE));
947   gimp_procedure_add_argument (procedure,
948                                gimp_param_spec_float_array ("points",
949                                                             "points",
950                                                             "The spline control points: { cp1.x, cp1.y, cp2.x, cp2.y, ... }",
951                                                             GIMP_PARAM_READWRITE));
952   gimp_pdb_register_procedure (pdb, procedure);
953   g_object_unref (procedure);
954 
955   /*
956    * gimp-drawable-desaturate
957    */
958   procedure = gimp_procedure_new (drawable_desaturate_invoker);
959   gimp_object_set_static_name (GIMP_OBJECT (procedure),
960                                "gimp-drawable-desaturate");
961   gimp_procedure_set_static_strings (procedure,
962                                      "gimp-drawable-desaturate",
963                                      "Desaturate the contents of the specified drawable, with the specified formula.",
964                                      "This procedure desaturates the contents of the specified drawable, with the specified formula. This procedure only works on drawables of type RGB color.",
965                                      "Karine Delvare",
966                                      "Karine Delvare",
967                                      "2005",
968                                      NULL);
969   gimp_procedure_add_argument (procedure,
970                                gimp_param_spec_drawable_id ("drawable",
971                                                             "drawable",
972                                                             "The drawable",
973                                                             pdb->gimp, FALSE,
974                                                             GIMP_PARAM_READWRITE));
975   gimp_procedure_add_argument (procedure,
976                                g_param_spec_enum ("desaturate-mode",
977                                                   "desaturate mode",
978                                                   "The formula to use to desaturate",
979                                                   GIMP_TYPE_DESATURATE_MODE,
980                                                   GIMP_DESATURATE_LIGHTNESS,
981                                                   GIMP_PARAM_READWRITE));
982   gimp_pdb_register_procedure (pdb, procedure);
983   g_object_unref (procedure);
984 
985   /*
986    * gimp-drawable-equalize
987    */
988   procedure = gimp_procedure_new (drawable_equalize_invoker);
989   gimp_object_set_static_name (GIMP_OBJECT (procedure),
990                                "gimp-drawable-equalize");
991   gimp_procedure_set_static_strings (procedure,
992                                      "gimp-drawable-equalize",
993                                      "Equalize the contents of the specified drawable.",
994                                      "This procedure equalizes the contents of the specified drawable. Each intensity channel is equalized independently. The equalized intensity is given as inten' = (255 - inten). The 'mask_only' option specifies whether to adjust only the area of the image within the selection bounds, or the entire image based on the histogram of the selected area. If there is no selection, the entire image is adjusted based on the histogram for the entire image.",
995                                      "Spencer Kimball & Peter Mattis",
996                                      "Spencer Kimball & Peter Mattis",
997                                      "1995-1996",
998                                      NULL);
999   gimp_procedure_add_argument (procedure,
1000                                gimp_param_spec_drawable_id ("drawable",
1001                                                             "drawable",
1002                                                             "The drawable",
1003                                                             pdb->gimp, FALSE,
1004                                                             GIMP_PARAM_READWRITE));
1005   gimp_procedure_add_argument (procedure,
1006                                g_param_spec_boolean ("mask-only",
1007                                                      "mask only",
1008                                                      "Equalization option",
1009                                                      FALSE,
1010                                                      GIMP_PARAM_READWRITE));
1011   gimp_pdb_register_procedure (pdb, procedure);
1012   g_object_unref (procedure);
1013 
1014   /*
1015    * gimp-drawable-histogram
1016    */
1017   procedure = gimp_procedure_new (drawable_histogram_invoker);
1018   gimp_object_set_static_name (GIMP_OBJECT (procedure),
1019                                "gimp-drawable-histogram");
1020   gimp_procedure_set_static_strings (procedure,
1021                                      "gimp-drawable-histogram",
1022                                      "Returns information on the intensity histogram for the specified drawable.",
1023                                      "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-drawable-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.",
1024                                      "Spencer Kimball & Peter Mattis",
1025                                      "Spencer Kimball & Peter Mattis",
1026                                      "1995-1996",
1027                                      NULL);
1028   gimp_procedure_add_argument (procedure,
1029                                gimp_param_spec_drawable_id ("drawable",
1030                                                             "drawable",
1031                                                             "The drawable",
1032                                                             pdb->gimp, FALSE,
1033                                                             GIMP_PARAM_READWRITE));
1034   gimp_procedure_add_argument (procedure,
1035                                g_param_spec_enum ("channel",
1036                                                   "channel",
1037                                                   "The channel to query",
1038                                                   GIMP_TYPE_HISTOGRAM_CHANNEL,
1039                                                   GIMP_HISTOGRAM_VALUE,
1040                                                   GIMP_PARAM_READWRITE));
1041   gimp_procedure_add_argument (procedure,
1042                                g_param_spec_double ("start-range",
1043                                                     "start range",
1044                                                     "Start of the intensity measurement range",
1045                                                     0.0, 1.0, 0.0,
1046                                                     GIMP_PARAM_READWRITE));
1047   gimp_procedure_add_argument (procedure,
1048                                g_param_spec_double ("end-range",
1049                                                     "end range",
1050                                                     "End of the intensity measurement range",
1051                                                     0.0, 1.0, 0.0,
1052                                                     GIMP_PARAM_READWRITE));
1053   gimp_procedure_add_return_value (procedure,
1054                                    g_param_spec_double ("mean",
1055                                                         "mean",
1056                                                         "Mean intensity value",
1057                                                         -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1058                                                         GIMP_PARAM_READWRITE));
1059   gimp_procedure_add_return_value (procedure,
1060                                    g_param_spec_double ("std-dev",
1061                                                         "std dev",
1062                                                         "Standard deviation of intensity values",
1063                                                         -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1064                                                         GIMP_PARAM_READWRITE));
1065   gimp_procedure_add_return_value (procedure,
1066                                    g_param_spec_double ("median",
1067                                                         "median",
1068                                                         "Median intensity value",
1069                                                         -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1070                                                         GIMP_PARAM_READWRITE));
1071   gimp_procedure_add_return_value (procedure,
1072                                    g_param_spec_double ("pixels",
1073                                                         "pixels",
1074                                                         "Alpha-weighted pixel count for entire image",
1075                                                         -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1076                                                         GIMP_PARAM_READWRITE));
1077   gimp_procedure_add_return_value (procedure,
1078                                    g_param_spec_double ("count",
1079                                                         "count",
1080                                                         "Alpha-weighted pixel count for range",
1081                                                         -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1082                                                         GIMP_PARAM_READWRITE));
1083   gimp_procedure_add_return_value (procedure,
1084                                    g_param_spec_double ("percentile",
1085                                                         "percentile",
1086                                                         "Percentile that range falls under",
1087                                                         -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1088                                                         GIMP_PARAM_READWRITE));
1089   gimp_pdb_register_procedure (pdb, procedure);
1090   g_object_unref (procedure);
1091 
1092   /*
1093    * gimp-drawable-hue-saturation
1094    */
1095   procedure = gimp_procedure_new (drawable_hue_saturation_invoker);
1096   gimp_object_set_static_name (GIMP_OBJECT (procedure),
1097                                "gimp-drawable-hue-saturation");
1098   gimp_procedure_set_static_strings (procedure,
1099                                      "gimp-drawable-hue-saturation",
1100                                      "Modify hue, lightness, and saturation in the specified drawable.",
1101                                      "This procedure allows the hue, lightness, and saturation in the specified drawable to be modified. The 'hue-range' parameter provides the capability to limit range of affected hues. The 'overlap' parameter provides blending into neighboring hue channels when rendering.",
1102                                      "Spencer Kimball & Peter Mattis",
1103                                      "Spencer Kimball & Peter Mattis",
1104                                      "1995-1996",
1105                                      NULL);
1106   gimp_procedure_add_argument (procedure,
1107                                gimp_param_spec_drawable_id ("drawable",
1108                                                             "drawable",
1109                                                             "The drawable",
1110                                                             pdb->gimp, FALSE,
1111                                                             GIMP_PARAM_READWRITE));
1112   gimp_procedure_add_argument (procedure,
1113                                g_param_spec_enum ("hue-range",
1114                                                   "hue range",
1115                                                   "Range of affected hues",
1116                                                   GIMP_TYPE_HUE_RANGE,
1117                                                   GIMP_HUE_RANGE_ALL,
1118                                                   GIMP_PARAM_READWRITE));
1119   gimp_procedure_add_argument (procedure,
1120                                g_param_spec_double ("hue-offset",
1121                                                     "hue offset",
1122                                                     "Hue offset in degrees",
1123                                                     -180, 180, -180,
1124                                                     GIMP_PARAM_READWRITE));
1125   gimp_procedure_add_argument (procedure,
1126                                g_param_spec_double ("lightness",
1127                                                     "lightness",
1128                                                     "Lightness modification",
1129                                                     -100, 100, -100,
1130                                                     GIMP_PARAM_READWRITE));
1131   gimp_procedure_add_argument (procedure,
1132                                g_param_spec_double ("saturation",
1133                                                     "saturation",
1134                                                     "Saturation modification",
1135                                                     -100, 100, -100,
1136                                                     GIMP_PARAM_READWRITE));
1137   gimp_procedure_add_argument (procedure,
1138                                g_param_spec_double ("overlap",
1139                                                     "overlap",
1140                                                     "Overlap other hue channels",
1141                                                     0, 100, 0,
1142                                                     GIMP_PARAM_READWRITE));
1143   gimp_pdb_register_procedure (pdb, procedure);
1144   g_object_unref (procedure);
1145 
1146   /*
1147    * gimp-drawable-invert
1148    */
1149   procedure = gimp_procedure_new (drawable_invert_invoker);
1150   gimp_object_set_static_name (GIMP_OBJECT (procedure),
1151                                "gimp-drawable-invert");
1152   gimp_procedure_set_static_strings (procedure,
1153                                      "gimp-drawable-invert",
1154                                      "Invert the contents of the specified drawable.",
1155                                      "This procedure inverts the contents of the specified drawable. Each intensity channel is inverted independently. The inverted intensity is given as inten' = (255 - inten). If 'linear' is TRUE, the drawable is inverted in linear space.",
1156                                      "Spencer Kimball & Peter Mattis",
1157                                      "Spencer Kimball & Peter Mattis",
1158                                      "1995-1996",
1159                                      NULL);
1160   gimp_procedure_add_argument (procedure,
1161                                gimp_param_spec_drawable_id ("drawable",
1162                                                             "drawable",
1163                                                             "The drawable",
1164                                                             pdb->gimp, FALSE,
1165                                                             GIMP_PARAM_READWRITE));
1166   gimp_procedure_add_argument (procedure,
1167                                g_param_spec_boolean ("linear",
1168                                                      "linear",
1169                                                      "Whether to invert in linear space",
1170                                                      FALSE,
1171                                                      GIMP_PARAM_READWRITE));
1172   gimp_pdb_register_procedure (pdb, procedure);
1173   g_object_unref (procedure);
1174 
1175   /*
1176    * gimp-drawable-levels
1177    */
1178   procedure = gimp_procedure_new (drawable_levels_invoker);
1179   gimp_object_set_static_name (GIMP_OBJECT (procedure),
1180                                "gimp-drawable-levels");
1181   gimp_procedure_set_static_strings (procedure,
1182                                      "gimp-drawable-levels",
1183                                      "Modifies intensity levels in the specified drawable.",
1184                                      "This tool allows intensity levels in the specified drawable to be remapped according to a set of parameters. The low/high input levels specify an initial mapping from the source intensities. The gamma value determines how intensities between the low and high input intensities are interpolated. A gamma value of 1.0 results in a linear interpolation. Higher gamma values result in more high-level intensities. Lower gamma values result in more low-level intensities. The low/high output levels constrain the final intensity mapping--that is, no final intensity will be lower than the low output level and no final intensity will be higher than the high output level. This tool is only valid on RGB color and grayscale images.",
1185                                      "Spencer Kimball & Peter Mattis",
1186                                      "Spencer Kimball & Peter Mattis",
1187                                      "1995-1996",
1188                                      NULL);
1189   gimp_procedure_add_argument (procedure,
1190                                gimp_param_spec_drawable_id ("drawable",
1191                                                             "drawable",
1192                                                             "The drawable",
1193                                                             pdb->gimp, FALSE,
1194                                                             GIMP_PARAM_READWRITE));
1195   gimp_procedure_add_argument (procedure,
1196                                g_param_spec_enum ("channel",
1197                                                   "channel",
1198                                                   "The channel to modify",
1199                                                   GIMP_TYPE_HISTOGRAM_CHANNEL,
1200                                                   GIMP_HISTOGRAM_VALUE,
1201                                                   GIMP_PARAM_READWRITE));
1202   gimp_procedure_add_argument (procedure,
1203                                g_param_spec_double ("low-input",
1204                                                     "low input",
1205                                                     "Intensity of lowest input",
1206                                                     0.0, 1.0, 0.0,
1207                                                     GIMP_PARAM_READWRITE));
1208   gimp_procedure_add_argument (procedure,
1209                                g_param_spec_double ("high-input",
1210                                                     "high input",
1211                                                     "Intensity of highest input",
1212                                                     0.0, 1.0, 0.0,
1213                                                     GIMP_PARAM_READWRITE));
1214   gimp_procedure_add_argument (procedure,
1215                                g_param_spec_boolean ("clamp-input",
1216                                                      "clamp input",
1217                                                      "Clamp input values before applying output levels",
1218                                                      FALSE,
1219                                                      GIMP_PARAM_READWRITE));
1220   gimp_procedure_add_argument (procedure,
1221                                g_param_spec_double ("gamma",
1222                                                     "gamma",
1223                                                     "Gamma adjustment factor",
1224                                                     0.1, 10, 0.1,
1225                                                     GIMP_PARAM_READWRITE));
1226   gimp_procedure_add_argument (procedure,
1227                                g_param_spec_double ("low-output",
1228                                                     "low output",
1229                                                     "Intensity of lowest output",
1230                                                     0.0, 1.0, 0.0,
1231                                                     GIMP_PARAM_READWRITE));
1232   gimp_procedure_add_argument (procedure,
1233                                g_param_spec_double ("high-output",
1234                                                     "high output",
1235                                                     "Intensity of highest output",
1236                                                     0.0, 1.0, 0.0,
1237                                                     GIMP_PARAM_READWRITE));
1238   gimp_procedure_add_argument (procedure,
1239                                g_param_spec_boolean ("clamp-output",
1240                                                      "clamp output",
1241                                                      "Clamp final output values",
1242                                                      FALSE,
1243                                                      GIMP_PARAM_READWRITE));
1244   gimp_pdb_register_procedure (pdb, procedure);
1245   g_object_unref (procedure);
1246 
1247   /*
1248    * gimp-drawable-levels-stretch
1249    */
1250   procedure = gimp_procedure_new (drawable_levels_stretch_invoker);
1251   gimp_object_set_static_name (GIMP_OBJECT (procedure),
1252                                "gimp-drawable-levels-stretch");
1253   gimp_procedure_set_static_strings (procedure,
1254                                      "gimp-drawable-levels-stretch",
1255                                      "Automatically modifies intensity levels in the specified drawable.",
1256                                      "This procedure allows intensity levels in the specified drawable to be remapped according to a set of guessed parameters. It is equivalent to clicking the \"Auto\" button in the Levels tool.",
1257                                      "Joao S.O. Bueno, Shawn Willden",
1258                                      "Joao S.O. Bueno, Shawn Willden",
1259                                      "2003",
1260                                      NULL);
1261   gimp_procedure_add_argument (procedure,
1262                                gimp_param_spec_drawable_id ("drawable",
1263                                                             "drawable",
1264                                                             "The drawable",
1265                                                             pdb->gimp, FALSE,
1266                                                             GIMP_PARAM_READWRITE));
1267   gimp_pdb_register_procedure (pdb, procedure);
1268   g_object_unref (procedure);
1269 
1270   /*
1271    * gimp-drawable-posterize
1272    */
1273   procedure = gimp_procedure_new (drawable_posterize_invoker);
1274   gimp_object_set_static_name (GIMP_OBJECT (procedure),
1275                                "gimp-drawable-posterize");
1276   gimp_procedure_set_static_strings (procedure,
1277                                      "gimp-drawable-posterize",
1278                                      "Posterize the specified drawable.",
1279                                      "This procedures reduces the number of shades allows in each intensity channel to the specified 'levels' parameter.",
1280                                      "Spencer Kimball & Peter Mattis",
1281                                      "Spencer Kimball & Peter Mattis",
1282                                      "1997",
1283                                      NULL);
1284   gimp_procedure_add_argument (procedure,
1285                                gimp_param_spec_drawable_id ("drawable",
1286                                                             "drawable",
1287                                                             "The drawable",
1288                                                             pdb->gimp, FALSE,
1289                                                             GIMP_PARAM_READWRITE));
1290   gimp_procedure_add_argument (procedure,
1291                                gimp_param_spec_int32 ("levels",
1292                                                       "levels",
1293                                                       "Levels of posterization",
1294                                                       2, 255, 2,
1295                                                       GIMP_PARAM_READWRITE));
1296   gimp_pdb_register_procedure (pdb, procedure);
1297   g_object_unref (procedure);
1298 
1299   /*
1300    * gimp-drawable-threshold
1301    */
1302   procedure = gimp_procedure_new (drawable_threshold_invoker);
1303   gimp_object_set_static_name (GIMP_OBJECT (procedure),
1304                                "gimp-drawable-threshold");
1305   gimp_procedure_set_static_strings (procedure,
1306                                      "gimp-drawable-threshold",
1307                                      "Threshold the specified drawable.",
1308                                      "This procedures generates a threshold map of the specified drawable. All pixels between the values of 'low_threshold' and 'high_threshold', on the scale of 'channel' are replaced with white, and all other pixels with black.",
1309                                      "Spencer Kimball & Peter Mattis",
1310                                      "Spencer Kimball & Peter Mattis",
1311                                      "1997",
1312                                      NULL);
1313   gimp_procedure_add_argument (procedure,
1314                                gimp_param_spec_drawable_id ("drawable",
1315                                                             "drawable",
1316                                                             "The drawable",
1317                                                             pdb->gimp, FALSE,
1318                                                             GIMP_PARAM_READWRITE));
1319   gimp_procedure_add_argument (procedure,
1320                                g_param_spec_enum ("channel",
1321                                                   "channel",
1322                                                   "The channel to base the threshold on",
1323                                                   GIMP_TYPE_HISTOGRAM_CHANNEL,
1324                                                   GIMP_HISTOGRAM_VALUE,
1325                                                   GIMP_PARAM_READWRITE));
1326   gimp_procedure_add_argument (procedure,
1327                                g_param_spec_double ("low-threshold",
1328                                                     "low threshold",
1329                                                     "The low threshold value",
1330                                                     0.0, 1.0, 0.0,
1331                                                     GIMP_PARAM_READWRITE));
1332   gimp_procedure_add_argument (procedure,
1333                                g_param_spec_double ("high-threshold",
1334                                                     "high threshold",
1335                                                     "The high threshold value",
1336                                                     0.0, 1.0, 0.0,
1337                                                     GIMP_PARAM_READWRITE));
1338   gimp_pdb_register_procedure (pdb, procedure);
1339   g_object_unref (procedure);
1340 }
1341