1 /* GIMP - The GNU Image Manipulation Program
2 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3 *
4 * gimpcolorbalanceconfig.c
5 * Copyright (C) 2007 Michael Natterer <mitch@gimp.org>
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
21 #include "config.h"
22
23 #include <cairo.h>
24 #include <gegl.h>
25 #include <gdk-pixbuf/gdk-pixbuf.h>
26
27 #include "libgimpcolor/gimpcolor.h"
28 #include "libgimpmath/gimpmath.h"
29 #include "libgimpconfig/gimpconfig.h"
30
31 #include "operations-types.h"
32
33 #include "gimpcolorbalanceconfig.h"
34
35 #include "gimp-intl.h"
36
37
38 enum
39 {
40 PROP_0,
41 PROP_RANGE,
42 PROP_CYAN_RED,
43 PROP_MAGENTA_GREEN,
44 PROP_YELLOW_BLUE,
45 PROP_PRESERVE_LUMINOSITY
46 };
47
48
49 static void gimp_color_balance_config_iface_init (GimpConfigInterface *iface);
50
51 static void gimp_color_balance_config_get_property (GObject *object,
52 guint property_id,
53 GValue *value,
54 GParamSpec *pspec);
55 static void gimp_color_balance_config_set_property (GObject *object,
56 guint property_id,
57 const GValue *value,
58 GParamSpec *pspec);
59
60 static gboolean gimp_color_balance_config_serialize (GimpConfig *config,
61 GimpConfigWriter *writer,
62 gpointer data);
63 static gboolean gimp_color_balance_config_deserialize (GimpConfig *config,
64 GScanner *scanner,
65 gint nest_level,
66 gpointer data);
67 static gboolean gimp_color_balance_config_equal (GimpConfig *a,
68 GimpConfig *b);
69 static void gimp_color_balance_config_reset (GimpConfig *config);
70 static gboolean gimp_color_balance_config_copy (GimpConfig *src,
71 GimpConfig *dest,
72 GParamFlags flags);
73
74
G_DEFINE_TYPE_WITH_CODE(GimpColorBalanceConfig,gimp_color_balance_config,GIMP_TYPE_OPERATION_SETTINGS,G_IMPLEMENT_INTERFACE (GIMP_TYPE_CONFIG,gimp_color_balance_config_iface_init))75 G_DEFINE_TYPE_WITH_CODE (GimpColorBalanceConfig, gimp_color_balance_config,
76 GIMP_TYPE_OPERATION_SETTINGS,
77 G_IMPLEMENT_INTERFACE (GIMP_TYPE_CONFIG,
78 gimp_color_balance_config_iface_init))
79
80 #define parent_class gimp_color_balance_config_parent_class
81
82
83 static void
84 gimp_color_balance_config_class_init (GimpColorBalanceConfigClass *klass)
85 {
86 GObjectClass *object_class = G_OBJECT_CLASS (klass);
87 GimpViewableClass *viewable_class = GIMP_VIEWABLE_CLASS (klass);
88
89 object_class->set_property = gimp_color_balance_config_set_property;
90 object_class->get_property = gimp_color_balance_config_get_property;
91
92 viewable_class->default_icon_name = "gimp-tool-color-balance";
93
94 GIMP_CONFIG_PROP_ENUM (object_class, PROP_RANGE,
95 "range",
96 _("Range"),
97 _("The affected range"),
98 GIMP_TYPE_TRANSFER_MODE,
99 GIMP_TRANSFER_MIDTONES, 0);
100
101 GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_CYAN_RED,
102 "cyan-red",
103 _("Cyan-Red"),
104 _("Cyan-Red"),
105 -1.0, 1.0, 0.0, 0);
106
107 GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_MAGENTA_GREEN,
108 "magenta-green",
109 _("Magenta-Green"),
110 _("Magenta-Green"),
111 -1.0, 1.0, 0.0, 0);
112
113 GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_YELLOW_BLUE,
114 "yellow-blue",
115 _("Yellow-Blue"),
116 _("Yellow-Blue"),
117 -1.0, 1.0, 0.0, 0);
118
119 GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_PRESERVE_LUMINOSITY,
120 "preserve-luminosity",
121 _("Preserve Luminosity"),
122 _("Preserve Luminosity"),
123 TRUE, 0);
124 }
125
126 static void
gimp_color_balance_config_iface_init(GimpConfigInterface * iface)127 gimp_color_balance_config_iface_init (GimpConfigInterface *iface)
128 {
129 iface->serialize = gimp_color_balance_config_serialize;
130 iface->deserialize = gimp_color_balance_config_deserialize;
131 iface->equal = gimp_color_balance_config_equal;
132 iface->reset = gimp_color_balance_config_reset;
133 iface->copy = gimp_color_balance_config_copy;
134 }
135
136 static void
gimp_color_balance_config_init(GimpColorBalanceConfig * self)137 gimp_color_balance_config_init (GimpColorBalanceConfig *self)
138 {
139 gimp_config_reset (GIMP_CONFIG (self));
140 }
141
142 static void
gimp_color_balance_config_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)143 gimp_color_balance_config_get_property (GObject *object,
144 guint property_id,
145 GValue *value,
146 GParamSpec *pspec)
147 {
148 GimpColorBalanceConfig *self = GIMP_COLOR_BALANCE_CONFIG (object);
149
150 switch (property_id)
151 {
152 case PROP_RANGE:
153 g_value_set_enum (value, self->range);
154 break;
155
156 case PROP_CYAN_RED:
157 g_value_set_double (value, self->cyan_red[self->range]);
158 break;
159
160 case PROP_MAGENTA_GREEN:
161 g_value_set_double (value, self->magenta_green[self->range]);
162 break;
163
164 case PROP_YELLOW_BLUE:
165 g_value_set_double (value, self->yellow_blue[self->range]);
166 break;
167
168 case PROP_PRESERVE_LUMINOSITY:
169 g_value_set_boolean (value, self->preserve_luminosity);
170 break;
171
172 default:
173 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
174 break;
175 }
176 }
177
178 static void
gimp_color_balance_config_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)179 gimp_color_balance_config_set_property (GObject *object,
180 guint property_id,
181 const GValue *value,
182 GParamSpec *pspec)
183 {
184 GimpColorBalanceConfig *self = GIMP_COLOR_BALANCE_CONFIG (object);
185
186 switch (property_id)
187 {
188 case PROP_RANGE:
189 self->range = g_value_get_enum (value);
190 g_object_notify (object, "cyan-red");
191 g_object_notify (object, "magenta-green");
192 g_object_notify (object, "yellow-blue");
193 break;
194
195 case PROP_CYAN_RED:
196 self->cyan_red[self->range] = g_value_get_double (value);
197 break;
198
199 case PROP_MAGENTA_GREEN:
200 self->magenta_green[self->range] = g_value_get_double (value);
201 break;
202
203 case PROP_YELLOW_BLUE:
204 self->yellow_blue[self->range] = g_value_get_double (value);
205 break;
206
207 case PROP_PRESERVE_LUMINOSITY:
208 self->preserve_luminosity = g_value_get_boolean (value);
209 break;
210
211 default:
212 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
213 break;
214 }
215 }
216
217 static gboolean
gimp_color_balance_config_serialize(GimpConfig * config,GimpConfigWriter * writer,gpointer data)218 gimp_color_balance_config_serialize (GimpConfig *config,
219 GimpConfigWriter *writer,
220 gpointer data)
221 {
222 GimpColorBalanceConfig *bc_config = GIMP_COLOR_BALANCE_CONFIG (config);
223 GimpTransferMode range;
224 GimpTransferMode old_range;
225 gboolean success = TRUE;
226
227 if (! gimp_operation_settings_config_serialize_base (config, writer, data))
228 return FALSE;
229
230 old_range = bc_config->range;
231
232 for (range = GIMP_TRANSFER_SHADOWS;
233 range <= GIMP_TRANSFER_HIGHLIGHTS;
234 range++)
235 {
236 bc_config->range = range;
237
238 success = (gimp_config_serialize_property_by_name (config,
239 "range",
240 writer) &&
241 gimp_config_serialize_property_by_name (config,
242 "cyan-red",
243 writer) &&
244 gimp_config_serialize_property_by_name (config,
245 "magenta-green",
246 writer) &&
247 gimp_config_serialize_property_by_name (config,
248 "yellow-blue",
249 writer));
250
251 if (! success)
252 break;
253 }
254
255 if (success)
256 success = gimp_config_serialize_property_by_name (config,
257 "preserve-luminosity",
258 writer);
259
260 bc_config->range = old_range;
261
262 return success;
263 }
264
265 static gboolean
gimp_color_balance_config_deserialize(GimpConfig * config,GScanner * scanner,gint nest_level,gpointer data)266 gimp_color_balance_config_deserialize (GimpConfig *config,
267 GScanner *scanner,
268 gint nest_level,
269 gpointer data)
270 {
271 GimpColorBalanceConfig *cb_config = GIMP_COLOR_BALANCE_CONFIG (config);
272 GimpTransferMode old_range;
273 gboolean success = TRUE;
274
275 old_range = cb_config->range;
276
277 success = gimp_config_deserialize_properties (config, scanner, nest_level);
278
279 g_object_set (config, "range", old_range, NULL);
280
281 return success;
282 }
283
284 static gboolean
gimp_color_balance_config_equal(GimpConfig * a,GimpConfig * b)285 gimp_color_balance_config_equal (GimpConfig *a,
286 GimpConfig *b)
287 {
288 GimpColorBalanceConfig *config_a = GIMP_COLOR_BALANCE_CONFIG (a);
289 GimpColorBalanceConfig *config_b = GIMP_COLOR_BALANCE_CONFIG (b);
290 GimpTransferMode range;
291
292 if (! gimp_operation_settings_config_equal_base (a, b))
293 return FALSE;
294
295 for (range = GIMP_TRANSFER_SHADOWS;
296 range <= GIMP_TRANSFER_HIGHLIGHTS;
297 range++)
298 {
299 if (config_a->cyan_red[range] != config_b->cyan_red[range] ||
300 config_a->magenta_green[range] != config_b->magenta_green[range] ||
301 config_a->yellow_blue[range] != config_b->yellow_blue[range])
302 return FALSE;
303 }
304
305 /* don't compare "range" */
306
307 if (config_a->preserve_luminosity != config_b->preserve_luminosity)
308 return FALSE;
309
310 return TRUE;
311 }
312
313 static void
gimp_color_balance_config_reset(GimpConfig * config)314 gimp_color_balance_config_reset (GimpConfig *config)
315 {
316 GimpColorBalanceConfig *cb_config = GIMP_COLOR_BALANCE_CONFIG (config);
317 GimpTransferMode range;
318
319 gimp_operation_settings_config_reset_base (config);
320
321 for (range = GIMP_TRANSFER_SHADOWS;
322 range <= GIMP_TRANSFER_HIGHLIGHTS;
323 range++)
324 {
325 cb_config->range = range;
326 gimp_color_balance_config_reset_range (cb_config);
327 }
328
329 gimp_config_reset_property (G_OBJECT (config), "range");
330 gimp_config_reset_property (G_OBJECT (config), "preserve-luminosity");
331 }
332
333 static gboolean
gimp_color_balance_config_copy(GimpConfig * src,GimpConfig * dest,GParamFlags flags)334 gimp_color_balance_config_copy (GimpConfig *src,
335 GimpConfig *dest,
336 GParamFlags flags)
337 {
338 GimpColorBalanceConfig *src_config = GIMP_COLOR_BALANCE_CONFIG (src);
339 GimpColorBalanceConfig *dest_config = GIMP_COLOR_BALANCE_CONFIG (dest);
340 GimpTransferMode range;
341
342 if (! gimp_operation_settings_config_copy_base (src, dest, flags))
343 return FALSE;
344
345 for (range = GIMP_TRANSFER_SHADOWS;
346 range <= GIMP_TRANSFER_HIGHLIGHTS;
347 range++)
348 {
349 dest_config->cyan_red[range] = src_config->cyan_red[range];
350 dest_config->magenta_green[range] = src_config->magenta_green[range];
351 dest_config->yellow_blue[range] = src_config->yellow_blue[range];
352 }
353
354 g_object_notify (G_OBJECT (dest), "cyan-red");
355 g_object_notify (G_OBJECT (dest), "magenta-green");
356 g_object_notify (G_OBJECT (dest), "yellow-blue");
357
358 dest_config->range = src_config->range;
359 dest_config->preserve_luminosity = src_config->preserve_luminosity;
360
361 g_object_notify (G_OBJECT (dest), "range");
362 g_object_notify (G_OBJECT (dest), "preserve-luminosity");
363
364 return TRUE;
365 }
366
367
368 /* public functions */
369
370 void
gimp_color_balance_config_reset_range(GimpColorBalanceConfig * config)371 gimp_color_balance_config_reset_range (GimpColorBalanceConfig *config)
372 {
373 g_return_if_fail (GIMP_IS_COLOR_BALANCE_CONFIG (config));
374
375 g_object_freeze_notify (G_OBJECT (config));
376
377 gimp_config_reset_property (G_OBJECT (config), "cyan-red");
378 gimp_config_reset_property (G_OBJECT (config), "magenta-green");
379 gimp_config_reset_property (G_OBJECT (config), "yellow-blue");
380
381 g_object_thaw_notify (G_OBJECT (config));
382 }
383