~ubuntu-branches/ubuntu/jaunty/gimp/jaunty-security

« back to all changes in this revision

Viewing changes to app/tools/gimplevelstool.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2008-10-06 13:30:41 UTC
  • mto: This revision was merged to the branch mainline in revision 35.
  • Revision ID: james.westby@ubuntu.com-20081006133041-3panbkcanaymfsmp
Tags: upstream-2.6.0
ImportĀ upstreamĀ versionĀ 2.6.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 
19
19
#include "config.h"
20
20
 
21
 
#include <stdio.h>
22
 
#include <stdlib.h>
23
 
#include <string.h>
24
21
#include <errno.h>
25
22
 
 
23
#include <glib/gstdio.h>
 
24
#include <gegl.h>
26
25
#include <gtk/gtk.h>
27
26
 
 
27
#include "libgimpbase/gimpbase.h"
28
28
#include "libgimpmath/gimpmath.h"
29
 
#include "libgimpcolor/gimpcolor.h"
30
29
#include "libgimpconfig/gimpconfig.h"
31
30
#include "libgimpwidgets/gimpwidgets.h"
32
31
 
36
35
#include "base/gimplut.h"
37
36
#include "base/levels.h"
38
37
 
 
38
#include "gegl/gimplevelsconfig.h"
 
39
#include "gegl/gimpoperationlevels.h"
 
40
 
39
41
#include "core/gimpdrawable.h"
40
42
#include "core/gimpdrawable-histogram.h"
41
43
#include "core/gimpimage.h"
42
 
#include "core/gimpimagemap.h"
43
44
 
44
45
#include "widgets/gimpcolorbar.h"
 
46
#include "widgets/gimphandlebar.h"
45
47
#include "widgets/gimphelp-ids.h"
46
48
#include "widgets/gimphistogramview.h"
 
49
#include "widgets/gimpwidgets-constructors.h"
47
50
 
48
51
#include "display/gimpdisplay.h"
49
52
 
50
53
#include "gimphistogramoptions.h"
51
54
#include "gimplevelstool.h"
52
 
#include "gimptoolcontrol.h"
53
55
 
54
56
#include "gimp-intl.h"
55
57
 
56
58
 
57
 
#define LOW_INPUT        (1 << 0)
58
 
#define GAMMA            (1 << 1)
59
 
#define HIGH_INPUT       (1 << 2)
60
 
#define LOW_OUTPUT       (1 << 3)
61
 
#define HIGH_OUTPUT      (1 << 4)
62
 
#define INPUT_LEVELS     (1 << 5)
63
 
#define OUTPUT_LEVELS    (1 << 6)
64
 
#define INPUT_SLIDERS    (1 << 7)
65
 
#define OUTPUT_SLIDERS   (1 << 8)
66
 
#define ALL_CHANNELS     (1 << 9)
67
 
#define ALL              0xFFF
68
 
 
69
 
#define HISTOGRAM_WIDTH   256
70
 
#define GRADIENT_HEIGHT   12
71
 
#define CONTROL_HEIGHT    8
72
 
 
73
 
#define LEVELS_EVENT_MASK  (GDK_BUTTON_PRESS_MASK   | \
74
 
                            GDK_BUTTON_RELEASE_MASK | \
75
 
                            GDK_BUTTON_MOTION_MASK)
 
59
#define PICK_LOW_INPUT    (1 << 0)
 
60
#define PICK_GAMMA        (1 << 1)
 
61
#define PICK_HIGH_INPUT   (1 << 2)
 
62
#define PICK_ALL_CHANNELS (1 << 8)
 
63
 
 
64
#define HISTOGRAM_WIDTH    256
 
65
#define GRADIENT_HEIGHT     12
 
66
#define CONTROL_HEIGHT      10
76
67
 
77
68
 
78
69
/*  local function prototypes  */
79
70
 
80
 
static void     gimp_levels_tool_finalize       (GObject           *object);
81
 
 
82
 
static gboolean gimp_levels_tool_initialize     (GimpTool          *tool,
83
 
                                                 GimpDisplay       *display,
84
 
                                                 GError           **error);
85
 
 
86
 
static void     gimp_levels_tool_color_picked   (GimpColorTool     *color_tool,
87
 
                                                 GimpColorPickState pick_state,
88
 
                                                 GimpImageType      sample_type,
89
 
                                                 GimpRGB           *color,
90
 
                                                 gint               color_index);
91
 
 
92
 
static void     gimp_levels_tool_map            (GimpImageMapTool  *image_map_tool);
93
 
static void     gimp_levels_tool_dialog         (GimpImageMapTool  *image_map_tool);
94
 
static void     gimp_levels_tool_dialog_unmap   (GtkWidget         *dialog,
95
 
                                                 GimpLevelsTool    *tool);
96
 
static void     gimp_levels_tool_reset          (GimpImageMapTool  *image_map_tool);
97
 
static gboolean gimp_levels_tool_settings_load  (GimpImageMapTool  *image_mao_tool,
98
 
                                                 gpointer           fp,
99
 
                                                 GError           **error);
100
 
static gboolean gimp_levels_tool_settings_save  (GimpImageMapTool  *image_map_tool,
101
 
                                                 gpointer           fp);
102
 
 
103
 
static void     levels_update                        (GimpLevelsTool *tool,
104
 
                                                      guint           update);
105
 
static void     levels_channel_callback              (GtkWidget      *widget,
106
 
                                                      GimpLevelsTool *tool);
107
 
static void     levels_channel_reset_callback        (GtkWidget      *widget,
108
 
                                                      GimpLevelsTool *tool);
109
 
 
110
 
static gboolean levels_menu_sensitivity              (gint            value,
111
 
                                                      gpointer        data);
112
 
 
113
 
static void     levels_stretch_callback              (GtkWidget      *widget,
114
 
                                                      GimpLevelsTool *tool);
115
 
static void     levels_low_input_adjustment_update   (GtkAdjustment  *adjustment,
116
 
                                                      GimpLevelsTool *tool);
117
 
static void     levels_gamma_adjustment_update       (GtkAdjustment  *adjustment,
118
 
                                                      GimpLevelsTool *tool);
119
 
static void     levels_high_input_adjustment_update  (GtkAdjustment  *adjustment,
120
 
                                                      GimpLevelsTool *tool);
121
 
static void     levels_low_output_adjustment_update  (GtkAdjustment  *adjustment,
122
 
                                                      GimpLevelsTool *tool);
123
 
static void     levels_high_output_adjustment_update (GtkAdjustment  *adjustment,
124
 
                                                      GimpLevelsTool *tool);
125
 
static void     levels_input_picker_toggled          (GtkWidget      *widget,
126
 
                                                      GimpLevelsTool *tool);
127
 
 
128
 
static gint     levels_input_area_event              (GtkWidget      *widget,
129
 
                                                      GdkEvent       *event,
130
 
                                                      GimpLevelsTool *tool);
131
 
static gboolean levels_input_area_expose             (GtkWidget      *widget,
132
 
                                                      GdkEventExpose *event,
133
 
                                                      GimpLevelsTool *tool);
134
 
 
135
 
static gint     levels_output_area_event             (GtkWidget      *widget,
136
 
                                                      GdkEvent       *event,
137
 
                                                      GimpLevelsTool *tool);
138
 
static gboolean levels_output_area_expose            (GtkWidget      *widget,
139
 
                                                      GdkEventExpose *event,
140
 
                                                      GimpLevelsTool *tool);
 
71
static void       gimp_levels_tool_finalize       (GObject           *object);
 
72
 
 
73
static gboolean   gimp_levels_tool_initialize     (GimpTool          *tool,
 
74
                                                   GimpDisplay       *display,
 
75
                                                   GError           **error);
 
76
 
 
77
static void       gimp_levels_tool_color_picked   (GimpColorTool     *color_tool,
 
78
                                                   GimpColorPickState pick_state,
 
79
                                                   GimpImageType      sample_type,
 
80
                                                   GimpRGB           *color,
 
81
                                                   gint               color_index);
 
82
 
 
83
static GeglNode * gimp_levels_tool_get_operation  (GimpImageMapTool  *im_tool,
 
84
                                                   GObject          **config);
 
85
static void       gimp_levels_tool_map            (GimpImageMapTool  *im_tool);
 
86
static void       gimp_levels_tool_dialog         (GimpImageMapTool  *im_tool);
 
87
static void       gimp_levels_tool_dialog_unmap   (GtkWidget         *dialog,
 
88
                                                   GimpLevelsTool    *tool);
 
89
static void       gimp_levels_tool_reset          (GimpImageMapTool  *im_tool);
 
90
static gboolean   gimp_levels_tool_settings_import(GimpImageMapTool  *im_tool,
 
91
                                                   const gchar       *filename,
 
92
                                                   GError           **error);
 
93
static gboolean   gimp_levels_tool_settings_export(GimpImageMapTool  *im_tool,
 
94
                                                   const gchar       *filename,
 
95
                                                   GError           **error);
 
96
 
 
97
static void       gimp_levels_tool_config_notify  (GObject           *object,
 
98
                                                   GParamSpec        *pspec,
 
99
                                                   GimpLevelsTool    *tool);
 
100
 
 
101
static void       levels_update_input_bar         (GimpLevelsTool    *tool);
 
102
 
 
103
static void       levels_channel_callback         (GtkWidget         *widget,
 
104
                                                   GimpLevelsTool    *tool);
 
105
static void       levels_channel_reset_callback   (GtkWidget         *widget,
 
106
                                                   GimpLevelsTool    *tool);
 
107
 
 
108
static gboolean   levels_menu_sensitivity         (gint               value,
 
109
                                                   gpointer           data);
 
110
 
 
111
static void       levels_stretch_callback         (GtkWidget         *widget,
 
112
                                                   GimpLevelsTool    *tool);
 
113
static void       levels_low_input_changed        (GtkAdjustment     *adjustment,
 
114
                                                   GimpLevelsTool    *tool);
 
115
static void       levels_gamma_changed            (GtkAdjustment     *adjustment,
 
116
                                                   GimpLevelsTool    *tool);
 
117
static void       levels_linear_gamma_changed     (GtkAdjustment     *adjustment,
 
118
                                                   GimpLevelsTool    *tool);
 
119
static void       levels_high_input_changed       (GtkAdjustment     *adjustment,
 
120
                                                   GimpLevelsTool    *tool);
 
121
static void       levels_low_output_changed       (GtkAdjustment     *adjustment,
 
122
                                                   GimpLevelsTool    *tool);
 
123
static void       levels_high_output_changed      (GtkAdjustment     *adjustment,
 
124
                                                   GimpLevelsTool    *tool);
 
125
static void       levels_input_picker_toggled     (GtkWidget         *widget,
 
126
                                                   GimpLevelsTool    *tool);
 
127
 
 
128
static void       levels_to_curves_callback       (GtkWidget         *widget,
 
129
                                                   GimpLevelsTool    *tool);
141
130
 
142
131
 
143
132
G_DEFINE_TYPE (GimpLevelsTool, gimp_levels_tool, GIMP_TYPE_IMAGE_MAP_TOOL)
170
159
  GimpColorToolClass    *color_tool_class = GIMP_COLOR_TOOL_CLASS (klass);
171
160
  GimpImageMapToolClass *im_tool_class    = GIMP_IMAGE_MAP_TOOL_CLASS (klass);
172
161
 
173
 
  object_class->finalize           = gimp_levels_tool_finalize;
174
 
 
175
 
  tool_class->initialize           = gimp_levels_tool_initialize;
176
 
 
177
 
  color_tool_class->picked         = gimp_levels_tool_color_picked;
178
 
 
179
 
  im_tool_class->shell_desc        = _("Adjust Color Levels");
180
 
  im_tool_class->settings_name     = "levels";
181
 
  im_tool_class->load_dialog_title = _("Load Levels");
182
 
  im_tool_class->load_button_tip   = _("Load levels settings from file");
183
 
  im_tool_class->save_dialog_title = _("Save Levels");
184
 
  im_tool_class->save_button_tip   = _("Save levels settings to file");
185
 
 
186
 
  im_tool_class->map               = gimp_levels_tool_map;
187
 
  im_tool_class->dialog            = gimp_levels_tool_dialog;
188
 
  im_tool_class->reset             = gimp_levels_tool_reset;
189
 
  im_tool_class->settings_load     = gimp_levels_tool_settings_load;
190
 
  im_tool_class->settings_save     = gimp_levels_tool_settings_save;
 
162
  object_class->finalize             = gimp_levels_tool_finalize;
 
163
 
 
164
  tool_class->initialize             = gimp_levels_tool_initialize;
 
165
 
 
166
  color_tool_class->picked           = gimp_levels_tool_color_picked;
 
167
 
 
168
  im_tool_class->shell_desc          = _("Adjust Color Levels");
 
169
  im_tool_class->settings_name       = "levels";
 
170
  im_tool_class->import_dialog_title = _("Import Levels");
 
171
  im_tool_class->export_dialog_title = _("Export Levels");
 
172
 
 
173
  im_tool_class->get_operation       = gimp_levels_tool_get_operation;
 
174
  im_tool_class->map                 = gimp_levels_tool_map;
 
175
  im_tool_class->dialog              = gimp_levels_tool_dialog;
 
176
  im_tool_class->reset               = gimp_levels_tool_reset;
 
177
  im_tool_class->settings_import     = gimp_levels_tool_settings_import;
 
178
  im_tool_class->settings_export     = gimp_levels_tool_settings_export;
191
179
}
192
180
 
193
181
static void
194
182
gimp_levels_tool_init (GimpLevelsTool *tool)
195
183
{
 
184
  GimpImageMapTool *im_tool = GIMP_IMAGE_MAP_TOOL (tool);
 
185
 
196
186
  tool->lut           = gimp_lut_new ();
197
 
  tool->levels        = g_slice_new0 (Levels);
198
 
  tool->hist          = NULL;
199
 
  tool->channel       = GIMP_HISTOGRAM_VALUE;
 
187
  tool->histogram     = gimp_histogram_new ();
200
188
  tool->active_picker = NULL;
201
189
 
202
 
  levels_init (tool->levels);
 
190
  im_tool->apply_func = (GimpImageMapApplyFunc) gimp_lut_process;
 
191
  im_tool->apply_data = tool->lut;
203
192
}
204
193
 
205
194
static void
208
197
  GimpLevelsTool *tool = GIMP_LEVELS_TOOL (object);
209
198
 
210
199
  gimp_lut_free (tool->lut);
211
 
  g_slice_free (Levels, tool->levels);
212
200
 
213
 
  if (tool->hist)
 
201
  if (tool->histogram)
214
202
    {
215
 
      gimp_histogram_free (tool->hist);
216
 
      tool->hist = NULL;
 
203
      gimp_histogram_unref (tool->histogram);
 
204
      tool->histogram = NULL;
217
205
    }
218
206
 
219
207
  G_OBJECT_CLASS (parent_class)->finalize (object);
237
225
      return FALSE;
238
226
    }
239
227
 
240
 
  if (! l_tool->hist)
241
 
    l_tool->hist = gimp_histogram_new ();
242
 
 
243
 
  levels_init (l_tool->levels);
244
 
 
245
 
  l_tool->channel = GIMP_HISTOGRAM_VALUE;
246
 
  l_tool->color   = gimp_drawable_is_rgb (drawable);
247
 
  l_tool->alpha   = gimp_drawable_has_alpha (drawable);
 
228
  gimp_config_reset (GIMP_CONFIG (l_tool->config));
248
229
 
249
230
  if (l_tool->active_picker)
250
231
    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (l_tool->active_picker),
253
234
  GIMP_TOOL_CLASS (parent_class)->initialize (tool, display, error);
254
235
 
255
236
  gimp_int_combo_box_set_sensitivity (GIMP_INT_COMBO_BOX (l_tool->channel_menu),
256
 
                                      levels_menu_sensitivity, l_tool, NULL);
257
 
 
258
 
  gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (l_tool->channel_menu),
259
 
                                 l_tool->channel);
260
 
 
261
 
  /* FIXME: hack */
262
 
  if (! l_tool->color)
263
 
    l_tool->channel = (l_tool->channel == GIMP_HISTOGRAM_ALPHA) ? 1 : 0;
264
 
 
265
 
  levels_update (l_tool, ALL);
266
 
 
267
 
  gimp_drawable_calculate_histogram (drawable, l_tool->hist);
268
 
  gimp_histogram_view_set_histogram (GIMP_HISTOGRAM_VIEW (l_tool->hist_view),
269
 
                                     l_tool->hist);
 
237
                                      levels_menu_sensitivity, drawable, NULL);
 
238
 
 
239
  gimp_drawable_calculate_histogram (drawable, l_tool->histogram);
 
240
  gimp_histogram_view_set_histogram (GIMP_HISTOGRAM_VIEW (l_tool->histogram_view),
 
241
                                     l_tool->histogram);
270
242
 
271
243
  return TRUE;
272
244
}
273
245
 
 
246
static GeglNode *
 
247
gimp_levels_tool_get_operation (GimpImageMapTool  *im_tool,
 
248
                                GObject          **config)
 
249
{
 
250
  GimpLevelsTool *tool = GIMP_LEVELS_TOOL (im_tool);
 
251
  GeglNode       *node;
 
252
 
 
253
  node = g_object_new (GEGL_TYPE_NODE,
 
254
                       "operation", "gimp-levels",
 
255
                       NULL);
 
256
 
 
257
  tool->config = g_object_new (GIMP_TYPE_LEVELS_CONFIG, NULL);
 
258
 
 
259
  *config = G_OBJECT (tool->config);
 
260
 
 
261
  g_signal_connect_object (tool->config, "notify",
 
262
                           G_CALLBACK (gimp_levels_tool_config_notify),
 
263
                           G_OBJECT (tool), 0);
 
264
 
 
265
  gegl_node_set (node,
 
266
                 "config", tool->config,
 
267
                 NULL);
 
268
 
 
269
  return node;
 
270
}
 
271
 
274
272
static void
275
273
gimp_levels_tool_map (GimpImageMapTool *image_map_tool)
276
274
{
277
 
  GimpLevelsTool *tool = GIMP_LEVELS_TOOL (image_map_tool);
278
 
 
279
 
  gimp_image_map_apply (image_map_tool->image_map,
280
 
                        (GimpImageMapApplyFunc) gimp_lut_process,
281
 
                        tool->lut);
 
275
  GimpLevelsTool *tool     = GIMP_LEVELS_TOOL (image_map_tool);
 
276
  GimpDrawable   *drawable = image_map_tool->drawable;
 
277
  Levels          levels;
 
278
 
 
279
  gimp_levels_config_to_cruft (tool->config, &levels,
 
280
                               gimp_drawable_is_rgb (drawable));
 
281
 
 
282
  gimp_lut_setup (tool->lut,
 
283
                  (GimpLutFunc) levels_lut_func,
 
284
                  &levels,
 
285
                  gimp_drawable_bytes (drawable));
282
286
}
283
287
 
284
288
 
286
290
/*  Levels dialog  */
287
291
/*******************/
288
292
 
289
 
 
290
293
static GtkWidget *
291
294
gimp_levels_tool_color_picker_new (GimpLevelsTool *tool,
292
295
                                   guint           value)
298
301
 
299
302
  switch (value & 0xF)
300
303
    {
301
 
    case LOW_INPUT:
 
304
    case PICK_LOW_INPUT:
302
305
      stock_id = GIMP_STOCK_COLOR_PICKER_BLACK;
303
306
      help     = _("Pick black point");
304
307
      break;
305
 
    case GAMMA:
 
308
    case PICK_GAMMA:
306
309
      stock_id = GIMP_STOCK_COLOR_PICKER_GRAY;
307
310
      help     = _("Pick gray point");
308
311
      break;
309
 
    case HIGH_INPUT:
 
312
    case PICK_HIGH_INPUT:
310
313
      stock_id = GIMP_STOCK_COLOR_PICKER_WHITE;
311
314
      help     = _("Pick white point");
312
315
      break;
326
329
  gimp_help_set_help_data (button, help, NULL);
327
330
 
328
331
  g_object_set_data (G_OBJECT (button),
329
 
                     "pick_value", GUINT_TO_POINTER (value));
 
332
                     "pick-value", GUINT_TO_POINTER (value));
330
333
  g_signal_connect (button, "toggled",
331
334
                    G_CALLBACK (levels_input_picker_toggled),
332
335
                    tool);
337
340
static void
338
341
gimp_levels_tool_dialog (GimpImageMapTool *image_map_tool)
339
342
{
340
 
  GimpLevelsTool  *tool         = GIMP_LEVELS_TOOL (image_map_tool);
341
 
  GimpToolOptions *tool_options = GIMP_TOOL_GET_OPTIONS (image_map_tool);
342
 
  GtkListStore    *store;
343
 
  GtkWidget       *vbox;
344
 
  GtkWidget       *vbox2;
345
 
  GtkWidget       *vbox3;
346
 
  GtkWidget       *hbox;
347
 
  GtkWidget       *hbox2;
348
 
  GtkWidget       *label;
349
 
  GtkWidget       *menu;
350
 
  GtkWidget       *frame;
351
 
  GtkWidget       *hbbox;
352
 
  GtkWidget       *button;
353
 
  GtkWidget       *spinbutton;
354
 
  GtkWidget       *bar;
355
 
  GtkObject       *data;
356
 
  gint             border;
 
343
  GimpLevelsTool   *tool         = GIMP_LEVELS_TOOL (image_map_tool);
 
344
  GimpToolOptions  *tool_options = GIMP_TOOL_GET_OPTIONS (image_map_tool);
 
345
  GimpLevelsConfig *config       = tool->config;
 
346
  GtkListStore     *store;
 
347
  GtkSizeGroup     *label_group;
 
348
  GtkWidget        *main_vbox;
 
349
  GtkWidget        *vbox;
 
350
  GtkWidget        *vbox2;
 
351
  GtkWidget        *vbox3;
 
352
  GtkWidget        *hbox;
 
353
  GtkWidget        *hbox2;
 
354
  GtkWidget        *label;
 
355
  GtkWidget        *menu;
 
356
  GtkWidget        *frame;
 
357
  GtkWidget        *hbbox;
 
358
  GtkWidget        *button;
 
359
  GtkWidget        *spinbutton;
 
360
  GtkWidget        *bar;
 
361
  GtkObject        *data;
 
362
  gint              border;
357
363
 
358
 
  vbox = image_map_tool->main_vbox;
 
364
  main_vbox   = gimp_image_map_tool_dialog_get_vbox (image_map_tool);
 
365
  label_group = gimp_image_map_tool_dialog_get_label_group (image_map_tool);
359
366
 
360
367
  /*  The option menu for selecting channels  */
361
368
  hbox = gtk_hbox_new (FALSE, 6);
362
 
  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
 
369
  gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, FALSE, 0);
363
370
  gtk_widget_show (hbox);
364
371
 
365
372
  label = gtk_label_new_with_mnemonic (_("Cha_nnel:"));
366
373
  gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
367
374
  gtk_widget_show (label);
368
375
 
 
376
  gtk_size_group_add_widget (label_group, label);
 
377
 
369
378
  store = gimp_enum_store_new_with_range (GIMP_TYPE_HISTOGRAM_CHANNEL,
370
379
                                          GIMP_HISTOGRAM_VALUE,
371
380
                                          GIMP_HISTOGRAM_ALPHA);
400
409
 
401
410
  /*  Input levels frame  */
402
411
  frame = gimp_frame_new (_("Input Levels"));
 
412
  gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0);
 
413
  gtk_widget_show (frame);
 
414
 
 
415
  vbox = gtk_vbox_new (FALSE, 2);
 
416
  gtk_container_add (GTK_CONTAINER (frame), vbox);
 
417
  gtk_widget_show (vbox);
 
418
 
 
419
  frame = gtk_frame_new (NULL);
 
420
  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
403
421
  gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, 0);
404
422
  gtk_widget_show (frame);
405
423
 
406
 
  vbox2 = gtk_vbox_new (FALSE, 2);
 
424
  vbox2 = gtk_vbox_new (FALSE, 0);
407
425
  gtk_container_add (GTK_CONTAINER (frame), vbox2);
408
426
  gtk_widget_show (vbox2);
409
427
 
410
 
  frame = gtk_frame_new (NULL);
411
 
  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
412
 
  gtk_box_pack_start (GTK_BOX (vbox2), frame, TRUE, TRUE, 0);
413
 
  gtk_widget_show (frame);
414
 
 
415
 
  tool->hist_view = gimp_histogram_view_new (FALSE);
416
 
  gtk_container_add (GTK_CONTAINER (frame), tool->hist_view);
417
 
  gtk_widget_show (GTK_WIDGET (tool->hist_view));
 
428
  tool->histogram_view = gimp_histogram_view_new (FALSE);
 
429
  gtk_box_pack_start (GTK_BOX (vbox2), tool->histogram_view, TRUE, TRUE, 0);
 
430
  gtk_widget_show (GTK_WIDGET (tool->histogram_view));
418
431
 
419
432
  gimp_histogram_options_connect_view (GIMP_HISTOGRAM_OPTIONS (tool_options),
420
 
                                       GIMP_HISTOGRAM_VIEW (tool->hist_view));
421
 
 
422
 
  g_object_get (tool->hist_view, "border-width", &border, NULL);
423
 
 
424
 
  frame = gtk_frame_new (NULL);
425
 
  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
426
 
  gtk_box_pack_start (GTK_BOX (vbox2), frame, FALSE, FALSE, 0);
427
 
  gtk_widget_show (frame);
428
 
 
429
 
  tool->input_area = gtk_event_box_new ();
430
 
  gtk_widget_set_size_request (tool->input_area, -1,
431
 
                               GRADIENT_HEIGHT + CONTROL_HEIGHT);
432
 
  gtk_widget_add_events (tool->input_area, LEVELS_EVENT_MASK);
433
 
  gtk_container_add (GTK_CONTAINER (frame), tool->input_area);
434
 
  gtk_widget_show (tool->input_area);
435
 
 
436
 
  g_signal_connect (tool->input_area, "event",
437
 
                    G_CALLBACK (levels_input_area_event),
438
 
                    tool);
439
 
  g_signal_connect_after (tool->input_area, "expose-event",
440
 
                          G_CALLBACK (levels_input_area_expose),
441
 
                          tool);
 
433
                                       GIMP_HISTOGRAM_VIEW (tool->histogram_view));
 
434
 
 
435
  g_object_get (tool->histogram_view, "border-width", &border, NULL);
442
436
 
443
437
  vbox3 = gtk_vbox_new (FALSE, 0);
444
 
  gtk_container_add (GTK_CONTAINER (tool->input_area), vbox3);
 
438
  gtk_container_set_border_width (GTK_CONTAINER (vbox3), border);
 
439
  gtk_box_pack_start (GTK_BOX (vbox2), vbox3, FALSE, FALSE, 0);
445
440
  gtk_widget_show (vbox3);
446
441
 
447
 
  tool->input_bar = g_object_new (GIMP_TYPE_COLOR_BAR,
448
 
                                  "xpad", border,
449
 
                                  "ypad", 0,
450
 
                                  NULL);
 
442
  tool->input_bar = g_object_new (GIMP_TYPE_COLOR_BAR, NULL);
451
443
  gtk_widget_set_size_request (tool->input_bar, -1, GRADIENT_HEIGHT / 2);
452
444
  gtk_box_pack_start (GTK_BOX (vbox3), tool->input_bar, FALSE, FALSE, 0);
453
445
  gtk_widget_show (tool->input_bar);
454
446
 
455
 
  bar = g_object_new (GIMP_TYPE_COLOR_BAR,
456
 
                      "xpad", border,
457
 
                      "ypad", 0,
458
 
                      NULL);
 
447
  bar = g_object_new (GIMP_TYPE_COLOR_BAR, NULL);
459
448
  gtk_widget_set_size_request (bar, -1, GRADIENT_HEIGHT / 2);
460
449
  gtk_box_pack_start (GTK_BOX (vbox3), bar, FALSE, FALSE, 0);
461
450
  gtk_widget_show (bar);
462
451
 
 
452
  tool->input_sliders = g_object_new (GIMP_TYPE_HANDLE_BAR, NULL);
 
453
  gtk_widget_set_size_request (tool->input_sliders, -1, CONTROL_HEIGHT);
 
454
  gtk_box_pack_start (GTK_BOX (vbox3), tool->input_sliders, FALSE, FALSE, 0);
 
455
  gtk_widget_show (tool->input_sliders);
 
456
 
 
457
  g_signal_connect_swapped (tool->input_bar, "button-press-event",
 
458
                            G_CALLBACK (GTK_WIDGET_GET_CLASS (tool->input_sliders)->button_press_event),
 
459
                            tool->input_sliders);
 
460
 
 
461
  g_signal_connect_swapped (tool->input_bar, "button-release-event",
 
462
                            G_CALLBACK (GTK_WIDGET_GET_CLASS (tool->input_sliders)->button_release_event),
 
463
                            tool->input_sliders);
 
464
 
 
465
  g_signal_connect_swapped (tool->input_bar, "motion-notify-event",
 
466
                            G_CALLBACK (GTK_WIDGET_GET_CLASS (tool->input_sliders)->motion_notify_event),
 
467
                            tool->input_sliders);
 
468
 
 
469
  g_signal_connect_swapped (bar, "button-press-event",
 
470
                            G_CALLBACK (GTK_WIDGET_GET_CLASS (tool->input_sliders)->button_press_event),
 
471
                            tool->input_sliders);
 
472
 
 
473
  g_signal_connect_swapped (bar, "button-release-event",
 
474
                            G_CALLBACK (GTK_WIDGET_GET_CLASS (tool->input_sliders)->button_release_event),
 
475
                            tool->input_sliders);
 
476
 
 
477
  g_signal_connect_swapped (bar, "motion-notify-event",
 
478
                            G_CALLBACK (GTK_WIDGET_GET_CLASS (tool->input_sliders)->motion_notify_event),
 
479
                            tool->input_sliders);
 
480
 
463
481
  /*  Horizontal box for input levels spinbuttons  */
464
482
  hbox = gtk_hbox_new (FALSE, 6);
465
 
  gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, FALSE, 0);
 
483
  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
466
484
  gtk_widget_show (hbox);
467
485
 
468
486
  /*  low input spin  */
470
488
  gtk_box_pack_start (GTK_BOX (hbox), hbox2, FALSE, FALSE, 0);
471
489
  gtk_widget_show (hbox2);
472
490
 
473
 
  button = gimp_levels_tool_color_picker_new (tool, LOW_INPUT);
 
491
  button = gimp_levels_tool_color_picker_new (tool, PICK_LOW_INPUT);
474
492
  gtk_box_pack_start (GTK_BOX (hbox2), button, FALSE, FALSE, 0);
475
493
  gtk_widget_show (button);
476
494
 
477
 
  spinbutton = gimp_spin_button_new (&data, 0, 0, 255, 1, 10, 10, 0.5, 0);
 
495
  spinbutton = gimp_spin_button_new (&data,
 
496
                                     config->low_input[config->channel] * 255.0,
 
497
                                     0, 255, 1, 10, 0, 0.5, 0);
478
498
  gtk_box_pack_start (GTK_BOX (hbox2), spinbutton, FALSE, FALSE, 0);
479
499
  gtk_widget_show (spinbutton);
480
500
 
481
501
  tool->low_input = GTK_ADJUSTMENT (data);
482
502
  g_signal_connect (tool->low_input, "value-changed",
483
 
                    G_CALLBACK (levels_low_input_adjustment_update),
 
503
                    G_CALLBACK (levels_low_input_changed),
484
504
                    tool);
485
505
 
 
506
  gimp_handle_bar_set_adjustment (GIMP_HANDLE_BAR (tool->input_sliders), 0,
 
507
                                  tool->low_input);
 
508
 
486
509
  /*  input gamma spin  */
487
 
  spinbutton = gimp_spin_button_new (&data, 1, 0.1, 10, 0.01, 0.1, 1, 0.5, 2);
 
510
  spinbutton = gimp_spin_button_new (&data,
 
511
                                     config->gamma[config->channel],
 
512
                                     0.1, 10, 0.01, 0.1, 0, 0.5, 2);
488
513
  gtk_box_pack_start (GTK_BOX (hbox), spinbutton, TRUE, FALSE, 0);
489
514
  gimp_help_set_help_data (spinbutton, _("Gamma"), NULL);
490
515
  gtk_widget_show (spinbutton);
491
516
 
492
517
  tool->gamma = GTK_ADJUSTMENT (data);
493
518
  g_signal_connect (tool->gamma, "value-changed",
494
 
                    G_CALLBACK (levels_gamma_adjustment_update),
495
 
                    tool);
 
519
                    G_CALLBACK (levels_gamma_changed),
 
520
                    tool);
 
521
 
 
522
  tool->gamma_linear = GTK_ADJUSTMENT (gtk_adjustment_new (127, 0, 255,
 
523
                                                           0.1, 1.0, 0.0));
 
524
  g_signal_connect (tool->gamma_linear, "value-changed",
 
525
                    G_CALLBACK (levels_linear_gamma_changed),
 
526
                    tool);
 
527
 
 
528
  gimp_handle_bar_set_adjustment (GIMP_HANDLE_BAR (tool->input_sliders), 1,
 
529
                                  tool->gamma_linear);
 
530
  g_object_unref (tool->gamma_linear);
496
531
 
497
532
  /*  high input spin  */
498
533
  hbox2 = gtk_hbox_new (FALSE, 2);
499
534
  gtk_box_pack_end (GTK_BOX (hbox), hbox2, FALSE, FALSE, 0);
500
535
  gtk_widget_show (hbox2);
501
536
 
502
 
  button = gimp_levels_tool_color_picker_new (tool, HIGH_INPUT);
 
537
  button = gimp_levels_tool_color_picker_new (tool, PICK_HIGH_INPUT);
503
538
  gtk_box_pack_start (GTK_BOX (hbox2), button, FALSE, FALSE, 0);
504
539
  gtk_widget_show (button);
505
540
 
506
 
  spinbutton = gimp_spin_button_new (&data, 255, 0, 255, 1, 10, 10, 0.5, 0);
 
541
  spinbutton = gimp_spin_button_new (&data,
 
542
                                     config->high_input[config->channel] * 255.0,
 
543
                                     0, 255, 1, 10, 0, 0.5, 0);
507
544
  gtk_box_pack_start (GTK_BOX (hbox2), spinbutton, FALSE, FALSE, 0);
508
545
  gtk_widget_show (spinbutton);
509
546
 
510
547
  tool->high_input = GTK_ADJUSTMENT (data);
511
548
  g_signal_connect (tool->high_input, "value-changed",
512
 
                    G_CALLBACK (levels_high_input_adjustment_update),
 
549
                    G_CALLBACK (levels_high_input_changed),
513
550
                    tool);
514
551
 
 
552
  gimp_handle_bar_set_adjustment (GIMP_HANDLE_BAR (tool->input_sliders), 2,
 
553
                                  tool->high_input);
 
554
 
515
555
  /*  Output levels frame  */
516
556
  frame = gimp_frame_new (_("Output Levels"));
 
557
  gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
 
558
  gtk_widget_show (frame);
 
559
 
 
560
  vbox = gtk_vbox_new (FALSE, 4);
 
561
  gtk_container_add (GTK_CONTAINER (frame), vbox);
 
562
  gtk_widget_show (vbox);
 
563
 
 
564
  frame = gtk_frame_new (NULL);
 
565
  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
517
566
  gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
518
567
  gtk_widget_show (frame);
519
568
 
520
 
  vbox2 = gtk_vbox_new (FALSE, 4);
 
569
  vbox2 = gtk_vbox_new (FALSE, 0);
 
570
  gtk_container_set_border_width (GTK_CONTAINER (vbox2), border);
521
571
  gtk_container_add (GTK_CONTAINER (frame), vbox2);
522
572
  gtk_widget_show (vbox2);
523
573
 
524
 
  frame = gtk_frame_new (NULL);
525
 
  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
526
 
  gtk_box_pack_start (GTK_BOX (vbox2), frame, FALSE, FALSE, 0);
527
 
  gtk_widget_show (frame);
528
 
 
529
 
  tool->output_area = gtk_event_box_new ();
530
 
  gtk_widget_set_size_request (tool->output_area, -1,
531
 
                               GRADIENT_HEIGHT + CONTROL_HEIGHT);
532
 
  gtk_widget_add_events (bar, LEVELS_EVENT_MASK);
533
 
  gtk_container_add (GTK_CONTAINER (frame), tool->output_area);
534
 
  gtk_widget_show (tool->output_area);
535
 
 
536
 
  g_signal_connect (tool->output_area, "event",
537
 
                    G_CALLBACK (levels_output_area_event),
538
 
                    tool);
539
 
  g_signal_connect_after (tool->output_area, "expose-event",
540
 
                          G_CALLBACK (levels_output_area_expose),
541
 
                          tool);
542
 
 
543
 
  vbox3 = gtk_vbox_new (FALSE, 0);
544
 
  gtk_container_add (GTK_CONTAINER (tool->output_area), vbox3);
545
 
  gtk_widget_show (vbox3);
546
 
 
547
 
  tool->output_bar = g_object_new (GIMP_TYPE_COLOR_BAR,
548
 
                                   "xpad", border,
549
 
                                   "ypad", 0,
550
 
                                   NULL);
 
574
  tool->output_bar = g_object_new (GIMP_TYPE_COLOR_BAR, NULL);
551
575
  gtk_widget_set_size_request (tool->output_bar, -1, GRADIENT_HEIGHT);
552
 
  gtk_box_pack_start (GTK_BOX (vbox3), tool->output_bar, FALSE, FALSE, 0);
 
576
  gtk_box_pack_start (GTK_BOX (vbox2), tool->output_bar, FALSE, FALSE, 0);
553
577
  gtk_widget_show (tool->output_bar);
554
578
 
 
579
  tool->output_sliders = g_object_new (GIMP_TYPE_HANDLE_BAR, NULL);
 
580
  gtk_widget_set_size_request (tool->output_sliders, -1, CONTROL_HEIGHT);
 
581
  gtk_box_pack_start (GTK_BOX (vbox2), tool->output_sliders, FALSE, FALSE, 0);
 
582
  gtk_widget_show (tool->output_sliders);
 
583
 
 
584
  g_signal_connect_swapped (tool->output_bar, "button-press-event",
 
585
                            G_CALLBACK (GTK_WIDGET_GET_CLASS (tool->output_sliders)->button_press_event),
 
586
                            tool->output_sliders);
 
587
 
 
588
  g_signal_connect_swapped (tool->output_bar, "button-release-event",
 
589
                            G_CALLBACK (GTK_WIDGET_GET_CLASS (tool->output_sliders)->button_release_event),
 
590
                            tool->output_sliders);
 
591
 
 
592
  g_signal_connect_swapped (tool->output_bar, "motion-notify-event",
 
593
                            G_CALLBACK (GTK_WIDGET_GET_CLASS (tool->output_sliders)->motion_notify_event),
 
594
                            tool->output_sliders);
 
595
 
555
596
  /*  Horizontal box for levels spin widgets  */
556
597
  hbox = gtk_hbox_new (FALSE, 6);
557
 
  gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, FALSE, 0);
 
598
  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
558
599
  gtk_widget_show (hbox);
559
600
 
560
601
  /*  low output spin  */
561
 
  spinbutton = gimp_spin_button_new (&data, 0, 0, 255, 1, 10, 10, 0.5, 0);
 
602
  spinbutton = gimp_spin_button_new (&data,
 
603
                                     config->low_output[config->channel] * 255.0,
 
604
                                     0, 255, 1, 10, 0, 0.5, 0);
562
605
  gtk_box_pack_start (GTK_BOX (hbox), spinbutton, FALSE, FALSE, 0);
563
606
  gtk_widget_show (spinbutton);
564
607
 
565
608
  tool->low_output = GTK_ADJUSTMENT (data);
566
609
  g_signal_connect (tool->low_output, "value-changed",
567
 
                    G_CALLBACK (levels_low_output_adjustment_update),
 
610
                    G_CALLBACK (levels_low_output_changed),
568
611
                    tool);
569
612
 
 
613
  gimp_handle_bar_set_adjustment (GIMP_HANDLE_BAR (tool->output_sliders), 0,
 
614
                                  tool->low_output);
 
615
 
570
616
  /*  high output spin  */
571
 
  spinbutton = gimp_spin_button_new (&data, 255, 0, 255, 1, 10, 10, 0.5, 0);
 
617
  spinbutton = gimp_spin_button_new (&data,
 
618
                                     config->high_output[config->channel] * 255.0,
 
619
                                     0, 255, 1, 10, 0, 0.5, 0);
572
620
  gtk_box_pack_end (GTK_BOX (hbox), spinbutton, FALSE, FALSE, 0);
573
621
  gtk_widget_show (spinbutton);
574
622
 
575
623
  tool->high_output = GTK_ADJUSTMENT (data);
576
624
  g_signal_connect (tool->high_output, "value-changed",
577
 
                    G_CALLBACK (levels_high_output_adjustment_update),
 
625
                    G_CALLBACK (levels_high_output_changed),
578
626
                    tool);
579
627
 
580
 
 
 
628
  gimp_handle_bar_set_adjustment (GIMP_HANDLE_BAR (tool->output_sliders), 2,
 
629
                                  tool->high_output);
 
630
 
 
631
 
 
632
  /*  all channels frame  */
581
633
  frame = gimp_frame_new (_("All Channels"));
582
 
  gtk_box_pack_end (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
 
634
  gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
583
635
  gtk_widget_show (frame);
584
636
 
585
 
  hbox = gtk_hbox_new (FALSE, 0);
 
637
  hbox = gtk_hbox_new (FALSE, 6);
586
638
  gtk_container_add (GTK_CONTAINER (frame), hbox);
587
639
  gtk_widget_show (hbox);
588
640
 
589
 
  hbbox = gtk_hbutton_box_new ();
590
 
  gtk_box_set_spacing (GTK_BOX (hbbox), 4);
591
 
  gtk_box_pack_start (GTK_BOX (hbox), hbbox, FALSE, FALSE, 0);
592
 
  gtk_widget_show (hbbox);
593
 
 
594
 
  gtk_box_pack_start (GTK_BOX (hbbox), image_map_tool->load_button,
595
 
                      FALSE, FALSE, 0);
596
 
  gtk_widget_show (image_map_tool->load_button);
597
 
 
598
 
  gtk_box_pack_start (GTK_BOX (hbbox), image_map_tool->save_button,
599
 
                      FALSE, FALSE, 0);
600
 
  gtk_widget_show (image_map_tool->save_button);
601
 
 
602
641
  hbbox = gtk_hbox_new (FALSE, 6);
603
642
  gtk_box_pack_end (GTK_BOX (hbox), hbbox, FALSE, FALSE, 0);
604
643
  gtk_widget_show (hbbox);
613
652
                    tool);
614
653
 
615
654
  button = gimp_levels_tool_color_picker_new (tool,
616
 
                                              LOW_INPUT | ALL_CHANNELS);
617
 
  gtk_box_pack_start (GTK_BOX (hbbox), button, FALSE, FALSE, 0);
618
 
  gtk_widget_show (button);
619
 
 
620
 
  button = gimp_levels_tool_color_picker_new (tool, GAMMA | ALL_CHANNELS);
621
 
  gtk_box_pack_start (GTK_BOX (hbbox), button, FALSE, FALSE, 0);
622
 
  gtk_widget_show (button);
623
 
 
624
 
  button = gimp_levels_tool_color_picker_new (tool,
625
 
                                              HIGH_INPUT | ALL_CHANNELS);
 
655
                                              PICK_LOW_INPUT | PICK_ALL_CHANNELS);
 
656
  gtk_box_pack_start (GTK_BOX (hbbox), button, FALSE, FALSE, 0);
 
657
  gtk_widget_show (button);
 
658
 
 
659
  button = gimp_levels_tool_color_picker_new (tool,
 
660
                                              PICK_GAMMA | PICK_ALL_CHANNELS);
 
661
  gtk_box_pack_start (GTK_BOX (hbbox), button, FALSE, FALSE, 0);
 
662
  gtk_widget_show (button);
 
663
 
 
664
  button = gimp_levels_tool_color_picker_new (tool,
 
665
                                              PICK_HIGH_INPUT | PICK_ALL_CHANNELS);
626
666
  gtk_box_pack_start (GTK_BOX (hbbox), button, FALSE, FALSE, 0);
627
667
  gtk_widget_show (button);
628
668
 
629
669
  g_signal_connect (image_map_tool->shell, "unmap",
630
670
                    G_CALLBACK (gimp_levels_tool_dialog_unmap),
631
671
                    tool);
 
672
 
 
673
  button = gimp_stock_button_new (GIMP_STOCK_TOOL_CURVES,
 
674
                                  _("Edit these Settings as Curves"));
 
675
  gtk_box_pack_start (GTK_BOX (main_vbox), button, FALSE, FALSE, 0);
 
676
  gtk_widget_show (button);
 
677
 
 
678
  g_signal_connect (button, "clicked",
 
679
                    G_CALLBACK (levels_to_curves_callback),
 
680
                    tool);
 
681
 
 
682
  gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (tool->channel_menu),
 
683
                                 config->channel);
632
684
}
633
685
 
634
686
static void
643
695
static void
644
696
gimp_levels_tool_reset (GimpImageMapTool *image_map_tool)
645
697
{
646
 
  GimpLevelsTool *tool = GIMP_LEVELS_TOOL (image_map_tool);
647
 
 
648
 
  levels_init (tool->levels);
649
 
  levels_update (tool, ALL);
650
 
}
651
 
 
652
 
static gboolean
653
 
gimp_levels_tool_settings_load (GimpImageMapTool  *image_map_tool,
654
 
                                gpointer           fp,
655
 
                                GError           **error)
656
 
{
657
 
  GimpLevelsTool *tool = GIMP_LEVELS_TOOL (image_map_tool);
658
 
  FILE           *file = fp;
659
 
  gint            low_input[5];
660
 
  gint            high_input[5];
661
 
  gint            low_output[5];
662
 
  gint            high_output[5];
663
 
  gdouble         gamma[5];
664
 
  gint            i, fields;
665
 
  gchar           buf[50];
666
 
  gchar          *nptr;
667
 
 
668
 
  if (! fgets (buf, sizeof (buf), file) ||
669
 
      strcmp (buf, "# GIMP Levels File\n") != 0)
670
 
    {
671
 
      g_set_error (error, GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_PARSE,
672
 
                   _("not a GIMP Levels file"));
673
 
      return FALSE;
674
 
    }
675
 
 
676
 
  for (i = 0; i < 5; i++)
677
 
    {
678
 
      fields = fscanf (file, "%d %d %d %d ",
679
 
                       &low_input[i],
680
 
                       &high_input[i],
681
 
                       &low_output[i],
682
 
                       &high_output[i]);
683
 
 
684
 
      if (fields != 4)
685
 
        goto error;
686
 
 
687
 
      if (! fgets (buf, 50, file))
688
 
        goto error;
689
 
 
690
 
      gamma[i] = g_ascii_strtod (buf, &nptr);
691
 
 
692
 
      if (buf == nptr || errno == ERANGE)
693
 
        goto error;
694
 
    }
695
 
 
696
 
  for (i = 0; i < 5; i++)
697
 
    {
698
 
      tool->levels->low_input[i]   = low_input[i];
699
 
      tool->levels->high_input[i]  = high_input[i];
700
 
      tool->levels->low_output[i]  = low_output[i];
701
 
      tool->levels->high_output[i] = high_output[i];
702
 
      tool->levels->gamma[i]       = gamma[i];
703
 
    }
704
 
 
705
 
  levels_update (tool, ALL);
706
 
 
707
 
  return TRUE;
708
 
 
709
 
 error:
710
 
  g_set_error (error, GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_PARSE,
711
 
               _("parse error"));
712
 
  return FALSE;
713
 
}
714
 
 
715
 
static gboolean
716
 
gimp_levels_tool_settings_save (GimpImageMapTool *image_map_tool,
717
 
                                gpointer          fp)
718
 
{
719
 
  GimpLevelsTool *tool = GIMP_LEVELS_TOOL (image_map_tool);
720
 
  FILE           *file = fp;
721
 
  gint            i;
722
 
 
723
 
  fprintf (file, "# GIMP Levels File\n");
724
 
 
725
 
  for (i = 0; i < 5; i++)
726
 
    {
727
 
      gchar buf[G_ASCII_DTOSTR_BUF_SIZE];
728
 
 
729
 
      fprintf (file, "%d %d %d %d %s\n",
730
 
               tool->levels->low_input[i],
731
 
               tool->levels->high_input[i],
732
 
               tool->levels->low_output[i],
733
 
               tool->levels->high_output[i],
734
 
               g_ascii_formatd (buf, G_ASCII_DTOSTR_BUF_SIZE, "%f",
735
 
                                tool->levels->gamma[i]));
736
 
    }
737
 
 
738
 
  return TRUE;
739
 
}
740
 
 
741
 
static void
742
 
levels_draw_slider (GtkWidget *widget,
743
 
                    GdkGC     *border_gc,
744
 
                    GdkGC     *fill_gc,
745
 
                    gint       xpos)
746
 
{
747
 
  gint y;
748
 
 
749
 
  for (y = 0; y < CONTROL_HEIGHT; y++)
750
 
    gdk_draw_line (widget->window, fill_gc,
751
 
                   xpos - y / 2, GRADIENT_HEIGHT + y,
752
 
                   xpos + y / 2, GRADIENT_HEIGHT + y);
753
 
 
754
 
  gdk_draw_line (widget->window, border_gc,
755
 
                 xpos,
756
 
                 GRADIENT_HEIGHT,
757
 
                 xpos - (CONTROL_HEIGHT - 1) / 2,
758
 
                 GRADIENT_HEIGHT + CONTROL_HEIGHT - 1);
759
 
 
760
 
  gdk_draw_line (widget->window, border_gc,
761
 
                 xpos,
762
 
                 GRADIENT_HEIGHT,
763
 
                 xpos + (CONTROL_HEIGHT - 1) / 2,
764
 
                 GRADIENT_HEIGHT + CONTROL_HEIGHT - 1);
765
 
 
766
 
  gdk_draw_line (widget->window, border_gc,
767
 
                 xpos - (CONTROL_HEIGHT - 1) / 2,
768
 
                 GRADIENT_HEIGHT + CONTROL_HEIGHT - 1,
769
 
                 xpos + (CONTROL_HEIGHT - 1) / 2,
770
 
                 GRADIENT_HEIGHT + CONTROL_HEIGHT - 1);
771
 
}
772
 
 
773
 
static void
774
 
levels_update (GimpLevelsTool *tool,
775
 
               guint           update)
776
 
{
777
 
  GimpHistogramChannel channel;
778
 
 
779
 
  if (tool->color)
780
 
    {
781
 
      channel = tool->channel;
 
698
  GimpLevelsTool       *tool    = GIMP_LEVELS_TOOL (image_map_tool);
 
699
  GimpHistogramChannel  channel = tool->config->channel;
 
700
 
 
701
  g_object_freeze_notify (image_map_tool->config);
 
702
 
 
703
  if (image_map_tool->default_config)
 
704
    {
 
705
      gimp_config_copy (GIMP_CONFIG (image_map_tool->default_config),
 
706
                        GIMP_CONFIG (image_map_tool->config),
 
707
                        0);
782
708
    }
783
709
  else
784
710
    {
785
 
      /* FIXME: hack */
786
 
      if (tool->channel == 1)
787
 
        channel = GIMP_HISTOGRAM_ALPHA;
788
 
      else
789
 
        channel = GIMP_HISTOGRAM_VALUE;
790
 
    }
791
 
 
792
 
  /*  Recalculate the transfer arrays  */
793
 
  levels_calculate_transfers (tool->levels);
794
 
 
795
 
  /* set up the lut */
796
 
  if (GIMP_IMAGE_MAP_TOOL (tool)->drawable)
797
 
    gimp_lut_setup (tool->lut,
798
 
                    (GimpLutFunc) levels_lut_func,
799
 
                    tool->levels,
800
 
                    gimp_drawable_bytes (GIMP_IMAGE_MAP_TOOL (tool)->drawable));
801
 
 
802
 
  if (update & LOW_INPUT)
803
 
    gtk_adjustment_set_value (tool->low_input,
804
 
                              tool->levels->low_input[tool->channel]);
805
 
 
806
 
  if (update & GAMMA)
807
 
    gtk_adjustment_set_value (tool->gamma,
808
 
                              tool->levels->gamma[tool->channel]);
809
 
 
810
 
  if (update & HIGH_INPUT)
811
 
    gtk_adjustment_set_value (tool->high_input,
812
 
                              tool->levels->high_input[tool->channel]);
813
 
 
814
 
  if (update & LOW_OUTPUT)
815
 
    gtk_adjustment_set_value (tool->low_output,
816
 
                              tool->levels->low_output[tool->channel]);
817
 
 
818
 
  if (update & HIGH_OUTPUT)
819
 
    gtk_adjustment_set_value (tool->high_output,
820
 
                              tool->levels->high_output[tool->channel]);
821
 
 
822
 
  if (update & INPUT_LEVELS)
823
 
    {
824
 
      switch (channel)
825
 
        {
826
 
        case GIMP_HISTOGRAM_VALUE:
827
 
        case GIMP_HISTOGRAM_ALPHA:
828
 
        case GIMP_HISTOGRAM_RGB:
829
 
          gimp_color_bar_set_buffers (GIMP_COLOR_BAR (tool->input_bar),
830
 
                                      tool->levels->input[tool->channel],
831
 
                                      tool->levels->input[tool->channel],
832
 
                                      tool->levels->input[tool->channel]);
833
 
          break;
834
 
 
835
 
        case GIMP_HISTOGRAM_RED:
836
 
        case GIMP_HISTOGRAM_GREEN:
837
 
        case GIMP_HISTOGRAM_BLUE:
838
 
          gimp_color_bar_set_buffers (GIMP_COLOR_BAR (tool->input_bar),
839
 
                                      tool->levels->input[GIMP_HISTOGRAM_RED],
840
 
                                      tool->levels->input[GIMP_HISTOGRAM_GREEN],
841
 
                                      tool->levels->input[GIMP_HISTOGRAM_BLUE]);
842
 
          break;
843
 
        }
844
 
    }
845
 
 
846
 
  if (update & OUTPUT_LEVELS)
847
 
    {
848
 
      gimp_color_bar_set_channel (GIMP_COLOR_BAR (tool->output_bar), channel);
849
 
    }
850
 
 
851
 
  if (update & INPUT_SLIDERS)
852
 
    {
853
 
      gtk_widget_queue_draw (tool->input_area);
854
 
    }
855
 
 
856
 
  if (update & OUTPUT_SLIDERS)
857
 
    {
858
 
      gtk_widget_queue_draw (tool->output_area);
 
711
      gimp_config_reset (GIMP_CONFIG (image_map_tool->config));
 
712
    }
 
713
 
 
714
  g_object_set (tool->config,
 
715
                "channel", channel,
 
716
                NULL);
 
717
 
 
718
  g_object_thaw_notify (image_map_tool->config);
 
719
}
 
720
 
 
721
static gboolean
 
722
gimp_levels_tool_settings_import (GimpImageMapTool  *image_map_tool,
 
723
                                  const gchar       *filename,
 
724
                                  GError           **error)
 
725
{
 
726
  GimpLevelsTool *tool = GIMP_LEVELS_TOOL (image_map_tool);
 
727
  FILE           *file;
 
728
  gboolean        success;
 
729
 
 
730
  file = g_fopen (filename, "rt");
 
731
 
 
732
  if (! file)
 
733
    {
 
734
      g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
 
735
                   _("Could not open '%s' for reading: %s"),
 
736
                   gimp_filename_to_utf8 (filename),
 
737
                   g_strerror (errno));
 
738
      return FALSE;
 
739
    }
 
740
 
 
741
  success = gimp_levels_config_load_cruft (tool->config, file, error);
 
742
 
 
743
  fclose (file);
 
744
 
 
745
  return success;
 
746
}
 
747
 
 
748
static gboolean
 
749
gimp_levels_tool_settings_export (GimpImageMapTool  *image_map_tool,
 
750
                                  const gchar       *filename,
 
751
                                  GError           **error)
 
752
{
 
753
  GimpLevelsTool *tool = GIMP_LEVELS_TOOL (image_map_tool);
 
754
  FILE           *file;
 
755
  gboolean        success;
 
756
 
 
757
  file = g_fopen (filename, "wt");
 
758
 
 
759
  if (! file)
 
760
    {
 
761
      g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
 
762
                   _("Could not open '%s' for writing: %s"),
 
763
                   gimp_filename_to_utf8 (filename),
 
764
                   g_strerror (errno));
 
765
      return FALSE;
 
766
    }
 
767
 
 
768
  success = gimp_levels_config_save_cruft (tool->config, file, error);
 
769
 
 
770
  fclose (file);
 
771
 
 
772
  return success;
 
773
}
 
774
 
 
775
static void
 
776
gimp_levels_tool_config_notify (GObject        *object,
 
777
                                GParamSpec     *pspec,
 
778
                                GimpLevelsTool *tool)
 
779
{
 
780
  GimpLevelsConfig *config = GIMP_LEVELS_CONFIG (object);
 
781
 
 
782
  if (! tool->low_input)
 
783
    return;
 
784
 
 
785
  if (! strcmp (pspec->name, "channel"))
 
786
    {
 
787
      gimp_histogram_view_set_channel (GIMP_HISTOGRAM_VIEW (tool->histogram_view),
 
788
                                       config->channel);
 
789
      gimp_color_bar_set_channel (GIMP_COLOR_BAR (tool->output_bar),
 
790
                                  config->channel);
 
791
      gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (tool->channel_menu),
 
792
                                     config->channel);
 
793
    }
 
794
  else if (! strcmp (pspec->name, "gamma")     ||
 
795
           ! strcmp (pspec->name, "low-input") ||
 
796
           ! strcmp (pspec->name, "high-input"))
 
797
    {
 
798
      tool->low_input->upper    = 255;
 
799
      tool->high_input->lower   = 0;
 
800
      tool->gamma_linear->lower = 0;
 
801
      tool->gamma_linear->upper = 255;
 
802
 
 
803
      gtk_adjustment_set_value (tool->low_input,
 
804
                                config->low_input[config->channel]  * 255.0);
 
805
      gtk_adjustment_set_value (tool->gamma,
 
806
                                config->gamma[config->channel]);
 
807
      gtk_adjustment_set_value (tool->high_input,
 
808
                                config->high_input[config->channel] * 255.0);
 
809
 
 
810
      tool->low_input->upper    = gtk_adjustment_get_value (tool->high_input);
 
811
      tool->high_input->lower   = gtk_adjustment_get_value (tool->low_input);
 
812
      tool->gamma_linear->lower = gtk_adjustment_get_value (tool->low_input);
 
813
      tool->gamma_linear->upper = gtk_adjustment_get_value (tool->high_input);
 
814
      gtk_adjustment_changed (tool->low_input);
 
815
      gtk_adjustment_changed (tool->high_input);
 
816
      gtk_adjustment_changed (tool->gamma_linear);
 
817
 
 
818
      levels_update_input_bar (tool);
 
819
    }
 
820
  else if (! strcmp (pspec->name, "low-output"))
 
821
    {
 
822
      gtk_adjustment_set_value (tool->low_output,
 
823
                                config->low_output[config->channel] * 255.0);
 
824
    }
 
825
  else if (! strcmp (pspec->name, "high-output"))
 
826
    {
 
827
      gtk_adjustment_set_value (tool->high_output,
 
828
                                config->high_output[config->channel] * 255.0);
 
829
    }
 
830
 
 
831
  gimp_image_map_tool_preview (GIMP_IMAGE_MAP_TOOL (tool));
 
832
}
 
833
 
 
834
static void
 
835
levels_update_input_bar (GimpLevelsTool *tool)
 
836
{
 
837
  GimpLevelsConfig *config = tool->config;
 
838
 
 
839
  switch (config->channel)
 
840
    {
 
841
    case GIMP_HISTOGRAM_VALUE:
 
842
    case GIMP_HISTOGRAM_ALPHA:
 
843
    case GIMP_HISTOGRAM_RGB:
 
844
      {
 
845
        guchar v[256];
 
846
        gint   i;
 
847
 
 
848
        for (i = 0; i < 256; i++)
 
849
          {
 
850
            v[i] = gimp_operation_levels_map_input (config,
 
851
                                                    config->channel,
 
852
                                                    i / 255.0) * 255.999;
 
853
          }
 
854
 
 
855
        gimp_color_bar_set_buffers (GIMP_COLOR_BAR (tool->input_bar),
 
856
                                    v, v, v);
 
857
      }
 
858
      break;
 
859
 
 
860
    case GIMP_HISTOGRAM_RED:
 
861
    case GIMP_HISTOGRAM_GREEN:
 
862
    case GIMP_HISTOGRAM_BLUE:
 
863
      {
 
864
        guchar r[256];
 
865
        guchar g[256];
 
866
        guchar b[256];
 
867
        gint   i;
 
868
 
 
869
        for (i = 0; i < 256; i++)
 
870
          {
 
871
            r[i] = gimp_operation_levels_map_input (config,
 
872
                                                    GIMP_HISTOGRAM_RED,
 
873
                                                    i / 255.0) * 255.999;
 
874
            g[i] = gimp_operation_levels_map_input (config,
 
875
                                                    GIMP_HISTOGRAM_GREEN,
 
876
                                                    i / 255.0) * 255.999;
 
877
            b[i] = gimp_operation_levels_map_input (config,
 
878
                                                    GIMP_HISTOGRAM_BLUE,
 
879
                                                    i / 255.0) * 255.999;
 
880
          }
 
881
 
 
882
        gimp_color_bar_set_buffers (GIMP_COLOR_BAR (tool->input_bar),
 
883
                                    r, g, b);
 
884
      }
 
885
      break;
859
886
    }
860
887
}
861
888
 
865
892
{
866
893
  gint value;
867
894
 
868
 
  if (gimp_int_combo_box_get_active (GIMP_INT_COMBO_BOX (widget), &value))
 
895
  if (gimp_int_combo_box_get_active (GIMP_INT_COMBO_BOX (widget), &value) &&
 
896
      tool->config->channel != value)
869
897
    {
870
 
      tool->channel = value;
871
 
      gimp_histogram_view_set_channel (GIMP_HISTOGRAM_VIEW (tool->hist_view),
872
 
                                       tool->channel);
873
 
 
874
 
      /* FIXME: hack */
875
 
      if (! tool->color)
876
 
        tool->channel = (tool->channel == GIMP_HISTOGRAM_ALPHA) ? 1 : 0;
877
 
 
878
 
      levels_update (tool, ALL);
 
898
      g_object_set (tool->config,
 
899
                    "channel", value,
 
900
                    NULL);
879
901
    }
880
902
}
881
903
 
883
905
levels_channel_reset_callback (GtkWidget      *widget,
884
906
                               GimpLevelsTool *tool)
885
907
{
886
 
  levels_channel_reset (tool->levels, tool->channel);
887
 
  levels_update (tool, ALL);
888
 
 
889
 
  gimp_image_map_tool_preview (GIMP_IMAGE_MAP_TOOL (tool));
 
908
  gimp_levels_config_reset_channel (tool->config);
890
909
}
891
910
 
892
911
static gboolean
893
912
levels_menu_sensitivity (gint      value,
894
913
                         gpointer  data)
895
914
{
896
 
  GimpLevelsTool       *tool    = GIMP_LEVELS_TOOL (data);
897
 
  GimpHistogramChannel  channel = value;
 
915
  GimpDrawable         *drawable = GIMP_DRAWABLE (data);
 
916
  GimpHistogramChannel  channel  = value;
898
917
 
899
918
  switch (channel)
900
919
    {
904
923
    case GIMP_HISTOGRAM_RED:
905
924
    case GIMP_HISTOGRAM_GREEN:
906
925
    case GIMP_HISTOGRAM_BLUE:
907
 
      return tool->color;
 
926
      return gimp_drawable_is_rgb (drawable);
908
927
 
909
928
    case GIMP_HISTOGRAM_ALPHA:
910
 
      return tool->alpha;
 
929
      return gimp_drawable_has_alpha (drawable);
911
930
 
912
931
    case GIMP_HISTOGRAM_RGB:
913
932
      return FALSE;
918
937
 
919
938
static void
920
939
levels_stretch_callback (GtkWidget      *widget,
 
940
                         GimpLevelsTool *tool)
 
941
{
 
942
  GimpDrawable *drawable = GIMP_IMAGE_MAP_TOOL (tool)->drawable;
 
943
 
 
944
  gimp_levels_config_stretch (tool->config, tool->histogram,
 
945
                              gimp_drawable_is_rgb (drawable));
 
946
}
 
947
 
 
948
static void
 
949
levels_linear_gamma_update (GimpLevelsTool *tool)
 
950
{
 
951
  gdouble low_input  = gtk_adjustment_get_value (tool->low_input);
 
952
  gdouble high_input = gtk_adjustment_get_value (tool->high_input);
 
953
  gdouble delta, mid, tmp, value;
 
954
 
 
955
  delta = (high_input - low_input) / 2.0;
 
956
  mid   = low_input + delta;
 
957
  tmp   = log10 (1.0 / tool->config->gamma[tool->config->channel]);
 
958
  value = mid + delta * tmp;
 
959
 
 
960
  gtk_adjustment_set_value (tool->gamma_linear, value);
 
961
}
 
962
 
 
963
static void
 
964
levels_linear_gamma_changed (GtkAdjustment  *adjustment,
 
965
                             GimpLevelsTool *tool)
 
966
{
 
967
  gdouble low_input  = gtk_adjustment_get_value (tool->low_input);
 
968
  gdouble high_input = gtk_adjustment_get_value (tool->high_input);
 
969
  gdouble delta, mid, tmp, value;
 
970
 
 
971
  delta = (high_input - low_input) / 2.0;
 
972
 
 
973
  if (delta >= 0.5)
 
974
    {
 
975
      mid   = low_input + delta;
 
976
      tmp   = (gtk_adjustment_get_value (adjustment) - mid) / delta;
 
977
      value = 1.0 / pow (10, tmp);
 
978
 
 
979
      /*  round the gamma value to the nearest 1/100th  */
 
980
      value = floor (value * 100 + 0.5) / 100.0;
 
981
 
 
982
      gtk_adjustment_set_value (tool->gamma, value);
 
983
    }
 
984
}
 
985
 
 
986
static void
 
987
levels_low_input_changed (GtkAdjustment  *adjustment,
 
988
                          GimpLevelsTool *tool)
 
989
{
 
990
  GimpLevelsConfig *config = tool->config;
 
991
  gint              value  = ROUND (gtk_adjustment_get_value (adjustment));
 
992
 
 
993
  tool->high_input->lower   = value;
 
994
  tool->gamma_linear->lower = value;
 
995
  gtk_adjustment_changed (tool->high_input);
 
996
  gtk_adjustment_changed (tool->gamma_linear);
 
997
 
 
998
  if (config->low_input[config->channel] != value / 255.0)
 
999
    {
 
1000
      g_object_set (config,
 
1001
                    "low-input", value / 255.0,
 
1002
                    NULL);
 
1003
    }
 
1004
 
 
1005
  levels_linear_gamma_update (tool);
 
1006
}
 
1007
 
 
1008
static void
 
1009
levels_gamma_changed (GtkAdjustment  *adjustment,
921
1010
                      GimpLevelsTool *tool)
922
1011
{
923
 
  levels_stretch (tool->levels, tool->hist, tool->color);
924
 
  levels_update (tool, ALL);
925
 
 
926
 
  gimp_image_map_tool_preview (GIMP_IMAGE_MAP_TOOL (tool));
927
 
}
928
 
 
929
 
static void
930
 
levels_low_input_adjustment_update (GtkAdjustment  *adjustment,
931
 
                                    GimpLevelsTool *tool)
932
 
{
933
 
  gint value = ROUND (adjustment->value);
934
 
 
935
 
  value = CLAMP (value, 0, tool->levels->high_input[tool->channel]);
936
 
 
937
 
  /*  enforce a consistent displayed value (low_input <= high_input)  */
938
 
  gtk_adjustment_set_value (adjustment, value);
939
 
 
940
 
  if (tool->levels->low_input[tool->channel] != value)
941
 
    {
942
 
      tool->levels->low_input[tool->channel] = value;
943
 
      levels_update (tool, INPUT_LEVELS | INPUT_SLIDERS);
944
 
 
945
 
      gimp_image_map_tool_preview (GIMP_IMAGE_MAP_TOOL (tool));
946
 
    }
947
 
}
948
 
 
949
 
static void
950
 
levels_gamma_adjustment_update (GtkAdjustment  *adjustment,
951
 
                                GimpLevelsTool *tool)
952
 
{
953
 
  if (tool->levels->gamma[tool->channel] != adjustment->value)
954
 
    {
955
 
      tool->levels->gamma[tool->channel] = adjustment->value;
956
 
      levels_update (tool, INPUT_LEVELS | INPUT_SLIDERS);
957
 
 
958
 
      gimp_image_map_tool_preview (GIMP_IMAGE_MAP_TOOL (tool));
959
 
    }
960
 
}
961
 
 
962
 
static void
963
 
levels_high_input_adjustment_update (GtkAdjustment  *adjustment,
964
 
                                     GimpLevelsTool *tool)
965
 
{
966
 
  gint value = ROUND (adjustment->value);
967
 
 
968
 
  value = CLAMP (value, tool->levels->low_input[tool->channel], 255);
969
 
 
970
 
  /*  enforce a consistent displayed value (high_input >= low_input)  */
971
 
  gtk_adjustment_set_value (adjustment, value);
972
 
 
973
 
  if (tool->levels->high_input[tool->channel] != value)
974
 
    {
975
 
      tool->levels->high_input[tool->channel] = value;
976
 
      levels_update (tool, INPUT_LEVELS | INPUT_SLIDERS);
977
 
 
978
 
      gimp_image_map_tool_preview (GIMP_IMAGE_MAP_TOOL (tool));
979
 
    }
980
 
}
981
 
 
982
 
static void
983
 
levels_low_output_adjustment_update (GtkAdjustment  *adjustment,
984
 
                                     GimpLevelsTool *tool)
985
 
{
986
 
  gint value = ROUND (adjustment->value);
987
 
 
988
 
  if (tool->levels->low_output[tool->channel] != value)
989
 
    {
990
 
      tool->levels->low_output[tool->channel] = value;
991
 
      levels_update (tool, OUTPUT_LEVELS | OUTPUT_SLIDERS);
992
 
 
993
 
      gimp_image_map_tool_preview (GIMP_IMAGE_MAP_TOOL (tool));
994
 
    }
995
 
}
996
 
 
997
 
static void
998
 
levels_high_output_adjustment_update (GtkAdjustment  *adjustment,
999
 
                                      GimpLevelsTool *tool)
1000
 
{
1001
 
  gint value = ROUND (adjustment->value);
1002
 
 
1003
 
  if (tool->levels->high_output[tool->channel] != value)
1004
 
    {
1005
 
      tool->levels->high_output[tool->channel] = value;
1006
 
      levels_update (tool, OUTPUT_LEVELS | OUTPUT_SLIDERS);
1007
 
 
1008
 
      gimp_image_map_tool_preview (GIMP_IMAGE_MAP_TOOL (tool));
 
1012
  GimpLevelsConfig *config = tool->config;
 
1013
  gdouble           value  = gtk_adjustment_get_value (adjustment);
 
1014
 
 
1015
  if (config->gamma[config->channel] != value)
 
1016
    {
 
1017
      g_object_set (config,
 
1018
                    "gamma", value,
 
1019
                    NULL);
 
1020
    }
 
1021
 
 
1022
  levels_linear_gamma_update (tool);
 
1023
}
 
1024
 
 
1025
static void
 
1026
levels_high_input_changed (GtkAdjustment  *adjustment,
 
1027
                           GimpLevelsTool *tool)
 
1028
{
 
1029
  GimpLevelsConfig *config = tool->config;
 
1030
  gint              value  = ROUND (gtk_adjustment_get_value (adjustment));
 
1031
 
 
1032
  tool->low_input->upper    = value;
 
1033
  tool->gamma_linear->upper = value;
 
1034
  gtk_adjustment_changed (tool->low_input);
 
1035
  gtk_adjustment_changed (tool->gamma_linear);
 
1036
 
 
1037
  if (config->high_input[config->channel] != value / 255.0)
 
1038
    {
 
1039
      g_object_set (config,
 
1040
                    "high-input", value / 255.0,
 
1041
                    NULL);
 
1042
    }
 
1043
 
 
1044
  levels_linear_gamma_update (tool);
 
1045
}
 
1046
 
 
1047
static void
 
1048
levels_low_output_changed (GtkAdjustment  *adjustment,
 
1049
                           GimpLevelsTool *tool)
 
1050
{
 
1051
  GimpLevelsConfig *config = tool->config;
 
1052
  gint              value  = ROUND (gtk_adjustment_get_value (adjustment));
 
1053
 
 
1054
  if (config->low_output[config->channel] != value / 255.0)
 
1055
    {
 
1056
      g_object_set (config,
 
1057
                    "low-output", value / 255.0,
 
1058
                    NULL);
 
1059
    }
 
1060
}
 
1061
 
 
1062
static void
 
1063
levels_high_output_changed (GtkAdjustment  *adjustment,
 
1064
                            GimpLevelsTool *tool)
 
1065
{
 
1066
  GimpLevelsConfig *config = tool->config;
 
1067
  gint              value  = ROUND (gtk_adjustment_get_value (adjustment));
 
1068
 
 
1069
  if (config->high_output[config->channel] != value / 255.0)
 
1070
    {
 
1071
      g_object_set (config,
 
1072
                    "high-output", value / 255.0,
 
1073
                    NULL);
1009
1074
    }
1010
1075
}
1011
1076
 
1034
1099
    }
1035
1100
}
1036
1101
 
1037
 
static gboolean
1038
 
levels_input_area_event (GtkWidget      *widget,
1039
 
                         GdkEvent       *event,
1040
 
                         GimpLevelsTool *tool)
1041
 
{
1042
 
  GdkEventButton *bevent;
1043
 
  GdkEventMotion *mevent;
1044
 
  gint            x, distance;
1045
 
  gint            i;
1046
 
  gboolean        update = FALSE;
1047
 
 
1048
 
  switch (event->type)
1049
 
    {
1050
 
    case GDK_BUTTON_PRESS:
1051
 
      bevent = (GdkEventButton *) event;
1052
 
 
1053
 
      distance = G_MAXINT;
1054
 
      for (i = 0; i < 3; i++)
1055
 
        if (fabs (bevent->x - tool->slider_pos[i]) < distance)
1056
 
          {
1057
 
            tool->active_slider = i;
1058
 
            distance = fabs (bevent->x - tool->slider_pos[i]);
1059
 
          }
1060
 
 
1061
 
      x = bevent->x;
1062
 
      update = TRUE;
1063
 
      break;
1064
 
 
1065
 
    case GDK_BUTTON_RELEASE:
1066
 
      switch (tool->active_slider)
1067
 
        {
1068
 
        case 0:  /*  low input  */
1069
 
          levels_update (tool, LOW_INPUT | GAMMA);
1070
 
          break;
1071
 
        case 1:  /*  gamma  */
1072
 
          levels_update (tool, GAMMA);
1073
 
          break;
1074
 
        case 2:  /*  high input  */
1075
 
          levels_update (tool, HIGH_INPUT | GAMMA);
1076
 
          break;
1077
 
        }
1078
 
 
1079
 
      gimp_image_map_tool_preview (GIMP_IMAGE_MAP_TOOL (tool));
1080
 
      break;
1081
 
 
1082
 
    case GDK_MOTION_NOTIFY:
1083
 
      mevent = (GdkEventMotion *) event;
1084
 
      gdk_window_get_pointer (widget->window, &x, NULL, NULL);
1085
 
      update = TRUE;
1086
 
      break;
1087
 
 
1088
 
    default:
1089
 
      break;
1090
 
    }
1091
 
 
1092
 
  if (update)
1093
 
    {
1094
 
      gdouble  delta, mid, tmp;
1095
 
      gint     width;
1096
 
      gint     border;
1097
 
 
1098
 
      g_object_get (tool->hist_view, "border-width", &border, NULL);
1099
 
 
1100
 
      width = widget->allocation.width - 2 * border;
1101
 
 
1102
 
      if (width < 1)
1103
 
        return FALSE;
1104
 
 
1105
 
      switch (tool->active_slider)
1106
 
        {
1107
 
        case 0:  /*  low input  */
1108
 
          tool->levels->low_input[tool->channel] =
1109
 
            ((gdouble) (x - border) / (gdouble) width) * 255.0;
1110
 
 
1111
 
          tool->levels->low_input[tool->channel] =
1112
 
            CLAMP (tool->levels->low_input[tool->channel],
1113
 
                   0, tool->levels->high_input[tool->channel]);
1114
 
          break;
1115
 
 
1116
 
        case 1:  /*  gamma  */
1117
 
          delta = (gdouble) (tool->slider_pos[2] - tool->slider_pos[0]) / 2.0;
1118
 
          mid   = tool->slider_pos[0] + delta;
1119
 
 
1120
 
          x   = CLAMP (x, tool->slider_pos[0], tool->slider_pos[2]);
1121
 
          tmp = (gdouble) (x - mid) / delta;
1122
 
 
1123
 
          tool->levels->gamma[tool->channel] = 1.0 / pow (10, tmp);
1124
 
 
1125
 
          /*  round the gamma value to the nearest 1/100th  */
1126
 
          tool->levels->gamma[tool->channel] =
1127
 
            floor (tool->levels->gamma[tool->channel] * 100 + 0.5) / 100.0;
1128
 
          break;
1129
 
 
1130
 
        case 2:  /*  high input  */
1131
 
          tool->levels->high_input[tool->channel] =
1132
 
            ((gdouble) (x - border) / (gdouble) width) * 255.0;
1133
 
 
1134
 
          tool->levels->high_input[tool->channel] =
1135
 
            CLAMP (tool->levels->high_input[tool->channel],
1136
 
                   tool->levels->low_input[tool->channel], 255);
1137
 
          break;
1138
 
        }
1139
 
 
1140
 
      levels_update (tool, INPUT_SLIDERS | INPUT_LEVELS);
1141
 
    }
1142
 
 
1143
 
  return FALSE;
1144
 
}
1145
 
 
1146
 
 
1147
 
static gboolean
1148
 
levels_input_area_expose (GtkWidget      *widget,
1149
 
                          GdkEventExpose *event,
1150
 
                          GimpLevelsTool *tool)
1151
 
{
1152
 
  Levels  *levels = tool->levels;
1153
 
  gint     width  = widget->allocation.width;
1154
 
  gdouble  delta, mid, tmp;
1155
 
  gint     border;
1156
 
 
1157
 
  g_object_get (tool->hist_view, "border-width", &border, NULL);
1158
 
 
1159
 
  width -= 2 * border;
1160
 
 
1161
 
  tool->slider_pos[0] = ROUND ((gdouble) width *
1162
 
                               levels->low_input[tool->channel] /
1163
 
                               256.0) + border;
1164
 
 
1165
 
  tool->slider_pos[2] = ROUND ((gdouble) width *
1166
 
                               levels->high_input[tool->channel] /
1167
 
                               256.0) + border;
1168
 
 
1169
 
  delta = (gdouble) (tool->slider_pos[2] - tool->slider_pos[0]) / 2.0;
1170
 
  mid   = tool->slider_pos[0] + delta;
1171
 
  tmp   = log10 (1.0 / levels->gamma[tool->channel]);
1172
 
 
1173
 
  tool->slider_pos[1] = ROUND (mid + delta * tmp) + border;
1174
 
 
1175
 
  levels_draw_slider (widget,
1176
 
                      widget->style->black_gc,
1177
 
                      widget->style->black_gc,
1178
 
                      tool->slider_pos[0]);
1179
 
  levels_draw_slider (widget,
1180
 
                      widget->style->black_gc,
1181
 
                      widget->style->dark_gc[GTK_STATE_NORMAL],
1182
 
                      tool->slider_pos[1]);
1183
 
  levels_draw_slider (widget,
1184
 
                      widget->style->black_gc,
1185
 
                      widget->style->white_gc,
1186
 
                      tool->slider_pos[2]);
1187
 
 
1188
 
  return FALSE;
1189
 
}
1190
 
 
1191
 
static gboolean
1192
 
levels_output_area_event (GtkWidget      *widget,
1193
 
                          GdkEvent       *event,
1194
 
                          GimpLevelsTool *tool)
1195
 
{
1196
 
  GdkEventButton *bevent;
1197
 
  GdkEventMotion *mevent;
1198
 
  gint            x, distance;
1199
 
  gint            i;
1200
 
  gboolean        update = FALSE;
1201
 
 
1202
 
  switch (event->type)
1203
 
    {
1204
 
    case GDK_BUTTON_PRESS:
1205
 
      bevent = (GdkEventButton *) event;
1206
 
 
1207
 
      distance = G_MAXINT;
1208
 
      for (i = 3; i < 5; i++)
1209
 
        if (fabs (bevent->x - tool->slider_pos[i]) < distance)
1210
 
          {
1211
 
            tool->active_slider = i;
1212
 
            distance = fabs (bevent->x - tool->slider_pos[i]);
1213
 
          }
1214
 
 
1215
 
      x = bevent->x;
1216
 
      update = TRUE;
1217
 
      break;
1218
 
 
1219
 
    case GDK_BUTTON_RELEASE:
1220
 
      switch (tool->active_slider)
1221
 
        {
1222
 
        case 3:  /*  low output  */
1223
 
          levels_update (tool, LOW_OUTPUT);
1224
 
          break;
1225
 
        case 4:  /*  high output  */
1226
 
          levels_update (tool, HIGH_OUTPUT);
1227
 
          break;
1228
 
        }
1229
 
 
1230
 
      gimp_image_map_tool_preview (GIMP_IMAGE_MAP_TOOL (tool));
1231
 
      break;
1232
 
 
1233
 
    case GDK_MOTION_NOTIFY:
1234
 
      mevent = (GdkEventMotion *) event;
1235
 
      gdk_window_get_pointer (widget->window, &x, NULL, NULL);
1236
 
      update = TRUE;
1237
 
      break;
1238
 
 
1239
 
    default:
1240
 
      break;
1241
 
    }
1242
 
 
1243
 
  if (update)
1244
 
    {
1245
 
      gint  width;
1246
 
      gint  border;
1247
 
 
1248
 
      g_object_get (tool->hist_view, "border-width", &border, NULL);
1249
 
 
1250
 
      width = widget->allocation.width - 2 * border;
1251
 
 
1252
 
      if (width < 1)
1253
 
        return FALSE;
1254
 
 
1255
 
      switch (tool->active_slider)
1256
 
        {
1257
 
        case 3:  /*  low output  */
1258
 
          tool->levels->low_output[tool->channel] =
1259
 
            ((gdouble) (x - border) / (gdouble) width) * 255.0;
1260
 
 
1261
 
          tool->levels->low_output[tool->channel] =
1262
 
            CLAMP (tool->levels->low_output[tool->channel], 0, 255);
1263
 
          break;
1264
 
 
1265
 
        case 4:  /*  high output  */
1266
 
          tool->levels->high_output[tool->channel] =
1267
 
            ((gdouble) (x - border) / (gdouble) width) * 255.0;
1268
 
 
1269
 
          tool->levels->high_output[tool->channel] =
1270
 
            CLAMP (tool->levels->high_output[tool->channel], 0, 255);
1271
 
          break;
1272
 
        }
1273
 
 
1274
 
      levels_update (tool, OUTPUT_SLIDERS);
1275
 
    }
1276
 
 
1277
 
  return FALSE;
1278
 
}
1279
 
 
1280
 
static gboolean
1281
 
levels_output_area_expose (GtkWidget      *widget,
1282
 
                           GdkEventExpose *event,
1283
 
                           GimpLevelsTool *tool)
1284
 
{
1285
 
  Levels  *levels = tool->levels;
1286
 
  gint     width  = widget->allocation.width;
1287
 
  gint     border;
1288
 
 
1289
 
  g_object_get (tool->hist_view, "border-width", &border, NULL);
1290
 
 
1291
 
  width -= 2 * border;
1292
 
 
1293
 
  tool->slider_pos[3] = ROUND ((gdouble) width *
1294
 
                               levels->low_output[tool->channel] /
1295
 
                               256.0) + border;
1296
 
 
1297
 
  tool->slider_pos[4] = ROUND ((gdouble) width *
1298
 
                               levels->high_output[tool->channel] /
1299
 
                               256.0) + border;
1300
 
 
1301
 
  levels_draw_slider (widget,
1302
 
                      widget->style->black_gc,
1303
 
                      widget->style->black_gc,
1304
 
                      tool->slider_pos[3]);
1305
 
  levels_draw_slider (widget,
1306
 
                      widget->style->black_gc,
1307
 
                      widget->style->white_gc,
1308
 
                      tool->slider_pos[4]);
1309
 
 
1310
 
  return FALSE;
1311
 
}
1312
 
 
1313
1102
static void
1314
 
levels_input_adjust_by_color (Levels               *levels,
 
1103
levels_input_adjust_by_color (GimpLevelsConfig     *config,
1315
1104
                              guint                 value,
1316
1105
                              GimpHistogramChannel  channel,
1317
 
                              guchar               *color)
 
1106
                              const GimpRGB        *color)
1318
1107
{
1319
1108
  switch (value & 0xF)
1320
1109
    {
1321
 
    case LOW_INPUT:
1322
 
      levels_adjust_by_colors (levels, channel, color, NULL, NULL);
1323
 
      break;
1324
 
    case GAMMA:
1325
 
      levels_adjust_by_colors (levels, channel, NULL, color, NULL);
1326
 
      break;
1327
 
    case HIGH_INPUT:
1328
 
      levels_adjust_by_colors (levels, channel, NULL, NULL, color);
 
1110
    case PICK_LOW_INPUT:
 
1111
      gimp_levels_config_adjust_by_colors (config, channel, color, NULL, NULL);
 
1112
      break;
 
1113
    case PICK_GAMMA:
 
1114
      gimp_levels_config_adjust_by_colors (config, channel, NULL, color, NULL);
 
1115
      break;
 
1116
    case PICK_HIGH_INPUT:
 
1117
      gimp_levels_config_adjust_by_colors (config, channel, NULL, NULL, color);
1329
1118
      break;
1330
1119
    default:
1331
1120
      break;
1340
1129
                               gint                color_index)
1341
1130
{
1342
1131
  GimpLevelsTool *tool = GIMP_LEVELS_TOOL (color_tool);
1343
 
  guchar          col[5];
1344
1132
  guint           value;
1345
1133
 
1346
 
  gimp_rgba_get_uchar (color,
1347
 
                       col + RED_PIX,
1348
 
                       col + GREEN_PIX,
1349
 
                       col + BLUE_PIX,
1350
 
                       col + ALPHA_PIX);
1351
 
 
1352
1134
  value = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (tool->active_picker),
1353
 
                                               "pick_value"));
 
1135
                                               "pick-value"));
1354
1136
 
1355
 
  if (value & ALL_CHANNELS && GIMP_IMAGE_TYPE_IS_RGB (sample_type))
 
1137
  if (value & PICK_ALL_CHANNELS && GIMP_IMAGE_TYPE_IS_RGB (sample_type))
1356
1138
    {
1357
1139
      GimpHistogramChannel  channel;
1358
1140
 
1359
1141
      /*  first reset the value channel  */
1360
1142
      switch (value & 0xF)
1361
1143
        {
1362
 
        case LOW_INPUT:
1363
 
          tool->levels->low_input[GIMP_HISTOGRAM_VALUE] = 0;
1364
 
          break;
1365
 
        case GAMMA:
1366
 
          tool->levels->gamma[GIMP_HISTOGRAM_VALUE] = 1.0;
1367
 
          break;
1368
 
        case HIGH_INPUT:
1369
 
          tool->levels->high_input[GIMP_HISTOGRAM_VALUE] = 255;
 
1144
        case PICK_LOW_INPUT:
 
1145
          tool->config->low_input[GIMP_HISTOGRAM_VALUE] = 0.0;
 
1146
          break;
 
1147
        case PICK_GAMMA:
 
1148
          tool->config->gamma[GIMP_HISTOGRAM_VALUE] = 1.0;
 
1149
          break;
 
1150
        case PICK_HIGH_INPUT:
 
1151
          tool->config->high_input[GIMP_HISTOGRAM_VALUE] = 1.0;
1370
1152
          break;
1371
1153
        default:
1372
1154
          break;
1377
1159
           channel <= GIMP_HISTOGRAM_BLUE;
1378
1160
           channel++)
1379
1161
        {
1380
 
          levels_input_adjust_by_color (tool->levels,
1381
 
                                        value, channel, col);
 
1162
          levels_input_adjust_by_color (tool->config,
 
1163
                                        value, channel, color);
1382
1164
        }
1383
1165
    }
1384
1166
  else
1385
1167
    {
1386
 
      levels_input_adjust_by_color (tool->levels,
1387
 
                                    value, tool->channel, col);
 
1168
      levels_input_adjust_by_color (tool->config,
 
1169
                                    value, tool->config->channel, color);
1388
1170
    }
1389
 
 
1390
 
  levels_update (tool, ALL);
1391
 
 
1392
 
  gimp_image_map_tool_preview (GIMP_IMAGE_MAP_TOOL (tool));
 
1171
}
 
1172
 
 
1173
static void
 
1174
levels_to_curves_callback (GtkWidget      *widget,
 
1175
                           GimpLevelsTool *tool)
 
1176
{
 
1177
  GimpCurvesConfig *curves;
 
1178
 
 
1179
  curves = gimp_levels_config_to_curves_config (tool->config);
 
1180
 
 
1181
  gimp_image_map_tool_edit_as (GIMP_IMAGE_MAP_TOOL (tool),
 
1182
                               "gimp-curves-tool",
 
1183
                               GIMP_CONFIG (curves));
 
1184
 
 
1185
  g_object_unref (curves);
1393
1186
}