1 /* img_process_dialog.c - filter and other transformations dialog class
2 *
3 * Copyright (C) 2001 Patrice St-Gelais
4 * patrstg@users.sourceforge.net
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21 #include "img_process_dialog.h"
22 #include "wind.h"
23 #include "wind_dialog.h"
24 #include "hf_wrapper.h"
25 #include "hf_creation_dialog.h" // For some HF generation dialogs
26 #include "hf_filters.h"
27 #include "subdiv2.h"
28 #include "time.h"
29 #include "craters.h"
30 #include "dialog_utilities.h"
31 #include "../fourier/fft.h"
32 #include "voronoi.h"
33 #include "voronoi_dialog.h"
34
35 #include "../icons/brightness_contrast.xpm"
36 #include "../icons/smooth.xpm"
37 #include "../icons/sharpen.xpm"
38 #include "../icons/threshold.xpm"
39 #include "../icons/revert.xpm"
40 #include "../icons/terraces.xpm"
41 #include "../icons/city.xpm"
42 #include "../icons/waves.xpm"
43 #include "../icons/rotate.xpm"
44 #include "../icons/slide.xpm"
45 #include "../icons/filters.xpm"
46 #include "../icons/noise.xpm"
47 #include "../icons/stretch_compress.xpm"
48 // #include "../icons/dilate.xpm"
49 // #include "../icons/erode.xpm"
50 #include "../icons/mirror_horizontal.xpm"
51 #include "../icons/mirror_vertical.xpm"
52 #include "../icons/merge.xpm"
53 #include "../icons/eroded_ribs.xpm"
54 #include "../icons/math_fn.xpm"
55 #include "../icons/crests.xpm"
56 #include "../icons/craters.xpm"
57 #include "../icons/rain.xpm"
58 #include "../icons/honeycomb.xpm"
59 #include "../icons/oriented_gravity.xpm"
60 #include "../icons/gravity.xpm"
61 #include "../icons/dunes.xpm"
62 #include "../icons/ripples.xpm"
63 #include "../icons/lift_edges.xpm"
64 #include "../icons/voronoi.xpm"
65
66 #define NBPROCESSES 31
67 command_item_struct img_processes[NBPROCESSES] = {
68 { "Processes", "Brightness and contrast","Brightness and contrast" ,0, (gchar **) brightness_contrast_xpm, GDK_LEFT_PTR, brightness_contrast_callb,NULL, NULL,TRUE },
69 { "Processes", "Threshold", "Threshold",0, (gchar **) threshold_xpm, GDK_LEFT_PTR, threshold_callb, NULL, NULL,TRUE },
70 { "Processes", "Revert", "Revert",0, (gchar **) revert_xpm, GDK_LEFT_PTR, revert_callb,NULL, NULL,TRUE },
71 { "Processes", "Mathematical transformations", "Mathematical transformations",0, (gchar **) math_fn_xpm, GDK_LEFT_PTR, math_fn_callb, NULL, NULL,TRUE },
72 { "Processes", "City", "City",0, (gchar **) city_xpm, GDK_LEFT_PTR, city_callb,NULL, NULL,TRUE },
73 { "Processes", "Giant Causeway", "Giant Causeway",0, (gchar **) honeycomb_xpm, GDK_LEFT_PTR, hexagon_callb,NULL, NULL,TRUE },
74 { "Processes", "Terraces", "Terraces",0, (gchar **) terraces_xpm, GDK_LEFT_PTR, terrace_callb,NULL, NULL,TRUE },
75 { "Processes", NULL, NULL, 0, NULL, 0, NULL,NULL, NULL, FALSE }, // Separator
76 { "Processes", "Smooth", "Smooth",0, (gchar **) smooth_xpm, GDK_LEFT_PTR, smooth_callb, NULL, NULL,TRUE },
77 { "Processes", "Sharpen", "Sharpen (increase noise)",0, (gchar **) sharpen_xpm, GDK_LEFT_PTR, sharpen_callb, NULL, NULL,TRUE },
78 { "Processes", "Translate", "Translate",0, (gchar **) slide_xpm, GDK_LEFT_PTR, slide_callb,NULL, NULL,TRUE },
79 { "Processes", "Rotate", "Rotate",0, (gchar **) rotate_xpm, GDK_LEFT_PTR, rotate_callb,NULL, NULL,TRUE },
80 { "Processes", "Stretch", "Stretch and compress",0, (gchar **) stretch_compress_xpm, GDK_LEFT_PTR, stretch_compress_callb,NULL, NULL,TRUE },
81 { "Processes", "Horizontal mirror", "Horizontal mirror",0, (gchar **) mirror_horizontal_xpm, GDK_LEFT_PTR, mirror_horizontal_callb,NULL, NULL,TRUE },
82 { "Processes", "Vertical mirror", "Vertical mirror",0, (gchar **) mirror_vertical_xpm, GDK_LEFT_PTR, mirror_vertical_callb,NULL, NULL,TRUE },
83 { "Processes", NULL, NULL, 0, NULL, 0, NULL,NULL, NULL, FALSE }, // Separator
84 { "Processes", "Noise", "Add noise",0, (gchar **) noise_xpm, GDK_LEFT_PTR, noise_callb, NULL, NULL,TRUE },
85 { "Processes", "Merge", "Merge",0, (gchar **) merge_xpm, GDK_LEFT_PTR, merge_callb, NULL, NULL,TRUE },
86 { "Processes", "Shape filter", "Shape filter",0, (gchar **) filters_xpm, GDK_LEFT_PTR, filter_callb, NULL, NULL,TRUE },
87 { "Processes", "Crests", "Crests",0, (gchar **) crests_xpm, GDK_LEFT_PTR, crests_callb,NULL, NULL,TRUE },
88 { "Processes", "Rain erosion", "Rain erosion",0, (gchar **) rain_xpm, GDK_LEFT_PTR, rain_erosion_callb,NULL, NULL,TRUE },
89 { "Processes", "Whimsical erosion", "Whimsical erosion",0, (gchar **) eroded_ribs_xpm, GDK_LEFT_PTR, whimsical_erosion_callb,NULL, NULL,TRUE },
90 { "Processes", "Craters", "Craters",0, (gchar **) craters_xpm, GDK_LEFT_PTR, craters_erosion_callb,NULL, NULL,TRUE },
91 { "Processes", NULL, NULL, 0, NULL, 0, NULL,NULL, NULL, FALSE }, // Separator
92 { "Processes", "Gravity erosion", "Gravity erosion",0, (gchar **) gravity_xpm, GDK_LEFT_PTR, gravity_callb,NULL, NULL,TRUE },
93 { "Processes", "Oriented gravity erosion", "Oriented gravity erosion",0, (gchar **) oriented_gravity_xpm, GDK_LEFT_PTR, oriented_gravity_callb,NULL, NULL,TRUE },
94 { "Processes", "Dunes", "Dunes",0, (gchar **) dunes_xpm, GDK_LEFT_PTR, dunes_callb,NULL, NULL,TRUE },
95 { "Processes", "Ripples", "Ripples",0, (gchar **) ripples_xpm, GDK_LEFT_PTR, ripples_callb,NULL, NULL,TRUE },
96 { "Processes", "Waves", "Waves",0, (gchar **) waves_xpm, GDK_LEFT_PTR, waves_callb,NULL, NULL,TRUE },
97 { "Processes", "Edges", "Lift edges",0, (gchar **) lift_edges_xpm, GDK_LEFT_PTR, lift_edges_callb,NULL, NULL,TRUE },
98 { "Processes", "Cracks", "Cracks network",0, (gchar **) voronoi_xpm, GDK_LEFT_PTR, voronoi_callb,NULL, NULL,TRUE }
99 };
100
101 // Toolbar for terraces levels
102 // Finally not used... keeping it for doc purpose....
103 /*
104 #define NBLEVELS 7
105 command_item_struct terrace_levels[NBLEVELS] = {
106 "Levels", "65536", "65536", 0, NULL, GDK_LEFT_PTR, terrace_upd,NULL, NULL,TRUE,
107 "Levels", "2", "2", 0, NULL, GDK_LEFT_PTR, terrace_upd,NULL, NULL,FALSE,
108 "Levels", "4", "4", 0, NULL, GDK_LEFT_PTR, terrace_upd,NULL, NULL,FALSE,
109 "Levels", "8", "8", 0, NULL, GDK_LEFT_PTR, terrace_upd,NULL, NULL,FALSE,
110 "Levels", "16", "16", 0, NULL, GDK_LEFT_PTR, terrace_upd,NULL, NULL,FALSE,
111 "Levels", "32", "32", 0, NULL, GDK_LEFT_PTR, terrace_upd,NULL, NULL,FALSE,
112 "Levels", "64", "64", 0, NULL, GDK_LEFT_PTR, terrace_upd,NULL, NULL,FALSE
113 };
114 */
115
116 /************************* CLASS CONSTRUCTOR / DESTRUCTOR *************************/
117
img_struct_new(GtkWidget * img_dialog,gpointer parent_data)118 img_dialog_struct *img_struct_new (GtkWidget *img_dialog, gpointer parent_data) {
119 gint i;
120 img_dialog_struct *img;
121 img = (img_dialog_struct *) x_calloc(sizeof(img_dialog_struct),1, "img_dialog_struct");
122 img->img_dialog = img_dialog;
123 img->set_fn = NULL;
124 img->accept_wdg = NULL;
125 img->current_subdialog = NULL;
126
127 img->br_contr_dialog = NULL;
128 img->br_contr_accept = NULL;
129 img->brightness_level =0;
130 img->contrast_level = 0;
131 img->adj_brightness = NULL;
132 img->adj_contrast = NULL;
133 img->brightness_bound_overflow = TRUE;
134 img->overflow_radio_button = NULL;
135 img->contrast_keep_luminosity_check_box = NULL;
136
137 img->smooth_dialog = NULL;
138 img->smooth_merge = NULL;
139 img->adj_smooth_radius = NULL;
140 img->adj_smooth_box = NULL;
141 img->smooth_radius = 0;
142 img->smooth_direct = FALSE;
143 img->smooth_accept = NULL;
144 img->smooth_wrap = TILING_AUTO;
145
146 img->sharpen_dialog = NULL;
147 img->sharpen_merge = NULL;
148 img->adj_sharpen_radius = NULL;
149 img->adj_sharpen_level = NULL;
150 img->sharpen_radius = 0;
151 img->sharpen_level = 7.5;
152 img->sharpen_accept = NULL;
153 img->sharpen_wrap = TILING_AUTO;
154
155 img->rotate_dialog = NULL;
156 img->adj_rotate = NULL;
157 img->auto_rotate = NULL;
158 img->rotate_overflow_tiling = OVERFLOW_WRAP;
159 img->rotate_overflow_notiling = OVERFLOW_REBOUND;
160 img->rotate_accept = NULL;
161 img->angle = 0;
162
163 img->slide_dialog = NULL;
164 img->adj_slidev = NULL;
165 img->slidev = 0;
166 img->adj_slideh = NULL;
167 img->slideh = 0;
168 img->slide_accept = NULL;
169
170 img->terrace_dialog = NULL;
171 img->terrace_levels = 0;
172 img->terrace_seed = rand();
173 img->terrace_percent_random = 50;
174 img->adj_terrace_levels = NULL;
175 img->adj_terrace_percent_random = NULL;
176 img->terrace_smooth_radius = 0;
177 img->adj_terrace_smooth_radius = NULL;
178 img->terrace_wrap = TILING_AUTO;
179 img->adj_terrace_artifact_radius = NULL;
180 img->terrace_artifact_radius = 0;
181 img->terrace_apply_postprocess = FALSE;
182 img->terrace_accept = NULL;
183 img->terrace_merge = NULL;
184
185 img->threshold_dialog = NULL;
186 img->adj_threshold_min = NULL;
187 img->threshold_min = 0;
188 img->adj_threshold_max = NULL;
189 img->threshold_max = 0xFFFF;
190 img->adj_threshold_percent = NULL;
191 img->threshold_percent = 100;
192 img->threshold_accept = NULL;
193
194 img->revert_dialog = NULL;
195
196 img->city_dialog = NULL;
197 img->adj_skyscraper_width = NULL;
198 img->skyscraper_width = 0;
199 img->adj_skyscraper_width_var = NULL;
200 img->skyscraper_width_var = 0;
201 img->adj_streets_width = NULL;
202 img->streets_width = 0;
203 img->cityscape_merge = NULL;
204 img->cityscape_accept = NULL;
205
206 for (i=0; i<NBWAVES; i++)
207 img->wav_shapes[i] = (shape_type *) NULL;
208 img->wav_dialog = NULL;
209 img->wav_notebook = NULL;
210 img->nb_wav = 0;
211 img->wav_pages = NULL;
212 img->wav_data = NULL;
213 img->wav_accept = NULL;
214 img->wav_direct = TRUE;
215 img->wav_to_calc = TRUE;
216
217 img->fd_struct = NULL;
218 img->filter_accept = NULL;
219
220 img->noise_dialog = NULL;
221 img->noise_accept = NULL;
222 img->noise_level = 0;
223 img->noise_merge = ADD;
224 img->hf_noise = NULL; // hf_wrapper_struct *
225 img->adj_noise_level = NULL;
226 img->noise_to_apply = NULL;
227
228 img->stretch_dialog = NULL;
229 img->stretch_accept = NULL;
230
231 img->hexagon_dialog = NULL;
232 img->hexagon_radius = 2;
233 img->adj_hexagon_radius = NULL;
234 img->hexagon_border = 0;
235 img->adj_hexagon_border = NULL;
236 img->hexagon_smooth_radius = 0;
237 img->adj_hexagon_smooth_radius = NULL;
238 img->hexagon_apply_postprocess = FALSE;
239 img->hexagon_merge = NULL;
240 img->hexagon_accept = NULL;
241
242 img->mirror_vertical_dialog = NULL;
243 img->mirror_horizontal_dialog = NULL;
244
245 img->merge_dialog = NULL;
246 img->merge = NULL;
247 img->merge_accept = NULL;
248 img->hf_to_merge = NULL;
249 img->hf_to_merge_scaled = NULL;
250 img->merge_scaled = FALSE;
251 img->merge_listbox = NULL;
252 img->merge_preview = NULL;
253 img->merging_image_frame = NULL;
254
255 img->math_fn_dialog = NULL;
256 img->math_fn_accept = NULL;
257 img->math_fn = POWER_OP;
258 img->math_fn_param = 1.0;
259 img->adj_math_fn = NULL;
260
261 img->lift_edges_dialog = NULL;
262 img->lift_edges_accept = NULL;
263 img->lift_edges_radius = 20;
264 img->adj_lift_edges_radius = NULL;
265 img->lift_edges_level = 40;
266 img->adj_lift_edges_level = NULL;
267 img->lift_edges_level_dialog = NULL;
268 img->lift_edges_use_black_point = FALSE;
269 img->lift_edges_wrap = TILING_AUTO;
270 img->lift_edges_merge_done = FALSE;
271
272 img->voronoi = voronoi_struct_new_with_defaults ();
273 img->voronoi_dialog = voronoi_dialog_struct_new ();
274
275 // Erosion
276
277 img->rain_erosion = rain_erosion_struct_new (50000, 1, 50, 75, FALSE, 5000, FALSE);
278 img->rain_erosion_dialog = rain_erosion_dialog_struct_new ();
279
280 img->gravity = gravity_struct_new (5, 60);
281 img->gravity_dialog = gravity_dialog_struct_new ();
282
283 img->oriented_gravity = oriented_gravity_struct_new (50, 30, EAST);
284 img->oriented_gravity_dialog = oriented_gravity_dialog_struct_new ();
285
286 img->crests = gravity_struct_new (3, 30);
287 img->crests_dialog = gravity_dialog_struct_new ();
288
289 img->whimsical_erosion = whimsical_erosion_struct_new (6, 2, TRUE);
290 img->whimsical_erosion_dialog = whimsical_erosion_dialog_struct_new ();
291
292 img->craters_erosion = craters_erosion_struct_new (10, 10, 35, 0);
293 img->craters_erosion_dialog = craters_erosion_dialog_struct_new ();
294
295 img->ripples = wind_struct_new(50, 2, 0, 0.4, 4.0, FALSE, 2);
296 img->ripples_dialog = wind_dialog_struct_new(RIPPLES, parent_data);
297
298 img->dunes = wind_struct_new(50, 2, 30, 0.0, 5.0, TRUE, 10);
299 img->dunes_dialog = wind_dialog_struct_new(DUNES, parent_data);
300
301 return img;
302 }
303
img_dialog_free(img_dialog_struct * img)304 void img_dialog_free(img_dialog_struct *img) {
305 // **** Don't forget to free the wav_pages & wav_data lists, plus
306 // the waves_shapes arrarys!
307 gint i;
308 GList *node;
309 if (img) {
310 for (i=0; i<NBWAVES; i++)
311 if (img->wav_shapes[i])
312 x_free(img->wav_shapes[i]);
313 if (img->wav_pages)
314 // This is a list of structs of widgets - no need to free more!
315 g_list_free(img->wav_pages);
316 if (img->wav_data) {
317 for (node = img->wav_data; node; node=node->next) {
318 wave_free((wave_struct *) node->data);
319 }
320 g_list_free(img->wav_data);
321 }
322 if (img->merge_listbox)
323 img_listbox_free(img->merge_listbox);
324 if (img->terrace_merge)
325 x_free(img->terrace_merge);
326 if (img->merge)
327 x_free(img->merge);
328 if (img->smooth_merge)
329 x_free(img->smooth_merge);
330 if (img->hexagon_merge)
331 x_free(img->hexagon_merge);
332 if (img->hf_to_merge_scaled && img->merge_scaled)
333 hf_free(img->hf_to_merge_scaled);
334
335 view_struct_free(img->merge_preview);
336
337 voronoi_dialog_struct_free(img->voronoi_dialog);
338 voronoi_struct_free(img->voronoi);
339 craters_erosion_struct_free(img->craters_erosion);
340 craters_erosion_dialog_struct_free(img->craters_erosion_dialog);
341 gravity_struct_free(img->crests);
342 gravity_dialog_struct_free(img->crests_dialog);
343 rain_erosion_struct_free(img->rain_erosion);
344 rain_erosion_dialog_struct_free(img->rain_erosion_dialog);
345 gravity_struct_free(img->gravity);
346 gravity_dialog_struct_free(img->gravity_dialog);
347 oriented_gravity_struct_free(img->oriented_gravity);
348 oriented_gravity_dialog_struct_free(img->oriented_gravity_dialog);
349 whimsical_erosion_struct_free(img->whimsical_erosion);
350 whimsical_erosion_dialog_struct_free(img->whimsical_erosion_dialog);
351
352 wind_dialog_struct_free(img->ripples_dialog);
353 wind_struct_free(img->ripples);
354 wind_dialog_struct_free(img->dunes_dialog);
355 wind_struct_free(img->dunes);
356
357 x_free(img);
358 }
359 }
360
img_process_dialog_new(GtkWidget * window,GtkTooltips * tooltips,gpointer callb_data)361 GtkWidget * img_process_dialog_new(GtkWidget *window,
362 GtkTooltips *tooltips, gpointer callb_data) {
363 // Initializes the dialog for mofying images
364 // Two parts, from top to bottom:
365 // 1. Toolbar of filters / actions
366 // 2. Options for the current filter / action - given by the specific callback
367
368 GtkWidget *dialog, *hbox;
369 toolbar_struct *tb;
370
371 dialog = gtk_vbox_new(FALSE, DEF_PAD);
372 gtk_widget_show(dialog);
373 hbox = gtk_hbox_new(FALSE, DEF_PAD);
374 gtk_widget_show(hbox);
375 // lbl = gtk_label_new(_("Processes"));
376 // gtk_widget_show(lbl);
377 // gtk_box_pack_start(GTK_BOX(hbox), lbl, FALSE, FALSE, DEF_PAD);
378 // toolbar_struct is a bit overkill for this purpose...
379 tb = multi_toolbar_new(NBPROCESSES, img_processes,
380 tooltips,
381 window,
382 callb_data,
383 GTK_ORIENTATION_HORIZONTAL,
384 GTK_TOOLBAR_ICONS,
385 TRUE);
386 gtk_box_pack_start(GTK_BOX(hbox),
387 align_widget(tb->toolbarwdg,0.5,0.5), TRUE, TRUE, DEF_PAD);
388 x_free(tb);
389
390 gtk_box_pack_start(GTK_BOX(dialog), hbox, FALSE, FALSE, 0);
391 return dialog;
392 }
393
394 /************************* GENERIC FUNCTIONS *************************/
395
accept_callb(GtkWidget * wdg,gpointer data)396 void accept_callb (GtkWidget *wdg, gpointer data) {
397 hf_wrapper_struct *hfw;
398 if (!data)
399 return;
400 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
401 accept_fn (hfw);
402 }
403
reset_callb(GtkWidget * wdg,gpointer data)404 void reset_callb(GtkWidget *wdg, gpointer data) {
405 hf_wrapper_struct *hfw;
406 if (!data)
407 return;
408 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
409 reset_fn (hfw);
410 }
411
reset_accept_buttons_new(gpointer data,GtkWidget ** accept_slot)412 GtkWidget *reset_accept_buttons_new (gpointer data, GtkWidget **accept_slot) {
413
414 GtkWidget *button, *hbox;
415
416 hbox = gtk_hbox_new(FALSE,DEF_PAD);
417 gtk_widget_show(GTK_WIDGET(hbox));
418
419 button = gtk_button_new_with_label (_("Reset"));
420 gtk_signal_connect (GTK_OBJECT (button), "clicked",
421 (GtkSignalFunc) reset_callb, data);
422 gtk_widget_show(button);
423
424 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, DEF_PAD);
425
426 button = gtk_button_new_with_label (_("Accept"));
427 gtk_signal_connect (GTK_OBJECT (button), "clicked",
428 (GtkSignalFunc) accept_callb, data);
429 gtk_widget_show(button);
430 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, DEF_PAD);
431 (*accept_slot) = button;
432 gtk_widget_set_sensitive(button,FALSE);
433
434 return align_widget(hbox,0.5,0.5);
435 }
436
apply_repeat_buttons_new(gpointer data,void (* apply_fn)(GtkWidget *,gpointer),void (* repeat_fn)(GtkWidget *,gpointer))437 GtkWidget *apply_repeat_buttons_new (gpointer data,
438 void (*apply_fn) (GtkWidget *, gpointer),
439 void (*repeat_fn) (GtkWidget *, gpointer) ) {
440
441 GtkWidget *button, *hbox;
442
443 hbox = gtk_hbox_new(FALSE,DEF_PAD);
444 gtk_widget_show(GTK_WIDGET(hbox));
445
446 button = gtk_button_new_with_label (_("Apply"));
447 gtk_signal_connect (GTK_OBJECT (button), "clicked",
448 (GtkSignalFunc) apply_fn, data);
449 gtk_widget_show(button);
450
451 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, DEF_PAD);
452
453 button = gtk_button_new_with_label (_("Repeat"));
454 gtk_signal_connect (GTK_OBJECT (button), "clicked",
455 (GtkSignalFunc) repeat_fn, data);
456 gtk_widget_show(button);
457
458 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, DEF_PAD);
459
460 return align_widget(hbox,0.5,0.5);
461 }
462
merge_n_display(hf_wrapper_struct * hfw,merge_struct * mrg)463 static void merge_n_display (hf_wrapper_struct *hfw,
464 merge_struct *mrg) {
465 // printf("Merge_n_display\n");
466
467 gtk_widget_set_sensitive(GTK_WIDGET( hfw->hf_options->img->accept_wdg),TRUE);
468 (*hfw->if_modified) = TRUE;
469 hfw->if_calculated = TRUE;
470 unset_watch_cursor(hfw);
471 set_merge_buffers (
472 mrg,
473 hfw->hf_struct->tmp_buf,
474 hfw->hf_struct->result_buf,
475 hfw->hf_struct->hf_buf,
476 hfw->hf_struct->max_x,
477 hfw->hf_struct->max_y);
478 simple_merge (mrg);
479 draw_hf (hfw);
480 }
481
482 /************************* BRIGHTNESS - CONTRAST *************************/
483
set_br_contr_defaults(img_dialog_struct * img)484 void set_br_contr_defaults(img_dialog_struct *img) {
485 gtk_adjustment_set_value(
486 GTK_ADJUSTMENT(img->adj_brightness), 0);
487 gtk_adjustment_set_value(
488 GTK_ADJUSTMENT(img->adj_contrast), 0);
489 }
490
calc_br_contrast(hf_wrapper_struct * hfw)491 void calc_br_contrast (hf_wrapper_struct *hfw) {
492 if (!hfw) return;
493 if (hfw->if_calculated)
494 return;
495 hf_brightness_contrast(hfw->hf_struct,
496 hfw->hf_options->img->contrast_level,
497 hfw->hf_options->img->brightness_level,
498 gtk_toggle_button_get_active(
499 GTK_TOGGLE_BUTTON(hfw->hf_options->
500 img->contrast_keep_luminosity_check_box)),
501 hfw->hf_options->img->brightness_bound_overflow );
502 begin_pending_record(hfw,"Brightness and contrast",accept_fn,reset_fn);
503 gtk_widget_set_sensitive(GTK_WIDGET(hfw->hf_options->img->br_contr_accept),TRUE);
504 (*hfw->if_modified) = TRUE;
505 hfw->if_calculated = TRUE;
506 draw_hf(hfw);
507 }
508
repeat_br_contr_callb(GtkWidget * wdg,gpointer data)509 void repeat_br_contr_callb (GtkWidget *wdg, gpointer data) {
510 hf_wrapper_struct *hfw;
511 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
512 if (!hfw) return;
513 commit_pending_record(hfw);
514 hf_backup(hfw->hf_struct);
515 hfw->if_calculated = FALSE;
516 calc_br_contrast(hfw);
517 }
518
contrast_upd(GtkWidget * wdg,gpointer data)519 void contrast_upd(GtkWidget *wdg,gpointer data) {
520 hf_wrapper_struct *hfw;
521 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
522 if (!hfw) return;
523 if (hfw->hf_options->img->contrast_level == (gfloat) GTK_ADJUSTMENT(wdg)->value)
524 return;
525 hfw->hf_options->img->contrast_level = (gfloat) GTK_ADJUSTMENT(wdg)->value;
526 hfw->if_calculated = FALSE;
527 calc_br_contrast(hfw);
528 }
529
brightness_upd(GtkWidget * wdg,gpointer data)530 void brightness_upd(GtkWidget *wdg,gpointer data) {
531 hf_wrapper_struct *hfw;
532 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
533 if (!hfw) return;
534 if (hfw->hf_options->img->brightness_level == (gfloat) GTK_ADJUSTMENT(wdg)->value)
535 return;
536 hfw->hf_options->img->brightness_level = (gfloat) GTK_ADJUSTMENT(wdg)->value;
537 hfw->if_calculated = FALSE;
538 calc_br_contrast(hfw);
539 }
540
auto_br_contrast_callb(GtkWidget * wdg,gpointer data)541 void auto_br_contrast_callb(GtkWidget *wdg,gpointer data) {
542 // Adjust the brightness and contrast so that the HF minimum becomes 0 and the max 0xFFFF
543 hf_wrapper_struct *hfw;
544 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
545 if (!hfw) return;
546 hf_min_max(hfw->hf_struct);
547 if (hfw->hf_struct->min == hfw->hf_struct->max)
548 return;
549
550 hf_auto_contrast(hfw->hf_struct);
551 begin_pending_record(hfw,"Brightness and contrast",accept_fn, reset_fn);
552 gtk_widget_set_sensitive(GTK_WIDGET(hfw->hf_options->img->br_contr_accept),TRUE);
553 (*hfw->if_modified) = TRUE;
554 hfw->if_calculated = TRUE;
555 draw_hf(hfw);
556 }
557
set_overflow_bound(GtkWidget * wdg,gpointer data)558 void set_overflow_bound (GtkWidget *wdg, gpointer data) {
559 // Sets the overflow processing
560 // "flag" is supposed to be TRUE for overflow = bound height,
561 // FALSE for overflow = revert slope.
562 gboolean *flag;
563 if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wdg)))
564 return;
565 flag = (gboolean *) data;
566 (*flag) = TRUE;
567 }
568
set_overflow_revert(GtkWidget * wdg,gpointer data)569 void set_overflow_revert (GtkWidget *wdg, gpointer data) {
570 gboolean *flag;
571 if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wdg)))
572 return;
573 flag = (gboolean *) data;
574 (*flag) = FALSE;
575 }
576
br_contr_dialog_new(img_dialog_struct * img,gpointer data)577 GtkWidget *br_contr_dialog_new(img_dialog_struct *img, gpointer data) {
578 GtkWidget *vbox, *vbox2, *hbox, *frame, *frame2, *button, *scale;
579 GtkObject *adj;
580 GSList *group = NULL;
581
582 frame = options_frame_new("Brightness and contrast");
583
584 vbox = gtk_vbox_new(FALSE,DEF_PAD);
585 gtk_widget_show(vbox);
586 gtk_container_add(GTK_CONTAINER(frame), vbox);
587
588 // ********* BRIGHTNESS
589
590 frame2 = frame_new("Brightness",0.5*DEF_PAD);
591 gtk_box_pack_start(GTK_BOX(vbox), frame2, FALSE, FALSE, 0.5*DEF_PAD);
592
593 vbox2 = gtk_vbox_new(FALSE,0);
594 gtk_widget_show(vbox2);
595
596 gtk_container_add(GTK_CONTAINER(frame2), vbox2);
597
598 adj = gtk_adjustment_new (0, -100, 100, 1, 1, 0.01);
599
600 scale = gtk_hscale_new (GTK_ADJUSTMENT (adj));
601 gtk_scale_set_digits (GTK_SCALE (scale), 0);
602 gtk_box_pack_start (GTK_BOX (vbox2), scale, TRUE, TRUE, DEF_PAD*0.5);
603 gtk_widget_show (scale);
604
605 gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
606 GTK_SIGNAL_FUNC (brightness_upd), data);
607 img->adj_brightness = adj;
608
609 hbox = gtk_hbox_new(FALSE,DEF_PAD);
610 gtk_widget_show(hbox);
611 gtk_box_pack_start(GTK_BOX(vbox2), align_widget(hbox,0.5,0.5), FALSE, FALSE, 0);
612 optimize_on_mouse_click (scale, data);
613 percent_buttons_negative_new (hbox, (gpointer) adj);
614
615 // ********* CONTRAST
616
617 frame2 = frame_new("Contrast",0.5*DEF_PAD);
618 gtk_box_pack_start(GTK_BOX(vbox), frame2, FALSE, FALSE, 0.5*DEF_PAD);
619
620 vbox2 = gtk_vbox_new(FALSE,0);
621 gtk_widget_show(vbox2);
622
623 gtk_container_add(GTK_CONTAINER(frame2), vbox2);
624
625 adj = gtk_adjustment_new (0, -100, 100, 1, 1, 0.01);
626
627 scale = gtk_hscale_new (GTK_ADJUSTMENT (adj));
628 gtk_scale_set_digits (GTK_SCALE (scale), 0);
629 gtk_box_pack_start (GTK_BOX (vbox2), scale, TRUE, TRUE, DEF_PAD*0.5);
630 gtk_widget_show (scale);
631
632 gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
633 GTK_SIGNAL_FUNC (contrast_upd), data);
634 img->adj_contrast = adj;
635
636 hbox = gtk_hbox_new(FALSE,DEF_PAD);
637 gtk_widget_show(hbox);
638 gtk_box_pack_start(GTK_BOX(vbox2), align_widget(hbox,0.5,0.5), FALSE, TRUE, 0);
639 optimize_on_mouse_click (scale, data);
640 percent_buttons_negative_new (hbox, (gpointer) adj);
641
642 // Contrast option: if we try to keep luminosity when decreasing contrast
643 // If not, black stays black
644
645 img->contrast_keep_luminosity_check_box =
646 define_check_button_in_box ("Keep luminosity", vbox2, FALSE,FALSE,0);
647 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (
648 img->contrast_keep_luminosity_check_box ), TRUE);
649
650 // ******** Brightness and contrast option: how we process overflow
651
652 frame2 = frame_new("Overflow processing",0.5*DEF_PAD);
653 gtk_box_pack_start(GTK_BOX(vbox), frame2, FALSE, FALSE, 0.5*DEF_PAD);
654
655 // hbox for radio buttons
656 hbox = gtk_hbox_new(FALSE,0);
657 gtk_widget_show(GTK_WIDGET(hbox));
658 define_radio_button_in_box_with_data (hbox, &group, "Bound height",
659 set_overflow_bound, &img->brightness_bound_overflow,
660 img->brightness_bound_overflow) ;
661 define_radio_button_in_box_with_data (hbox, &group, "Revert slope",
662 set_overflow_revert, &img->brightness_bound_overflow,
663 !img->brightness_bound_overflow) ;
664 gtk_container_add(GTK_CONTAINER(frame2),hbox);
665
666 // ********* CONTROLS
667
668 hbox = gtk_hbox_new(FALSE,DEF_PAD);
669 gtk_widget_show(hbox);
670
671 button = gtk_button_new_with_label (_("Automatic"));
672 gtk_signal_connect (GTK_OBJECT (button), "clicked",
673 (GtkSignalFunc) auto_br_contrast_callb, data);
674 gtk_widget_show(button);
675
676 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, DEF_PAD);
677
678 button = gtk_button_new_with_label (_("Repeat"));
679 gtk_signal_connect (GTK_OBJECT (button), "clicked",
680 (GtkSignalFunc) repeat_br_contr_callb, data);
681 gtk_widget_show(button);
682
683 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, DEF_PAD);
684
685 gtk_box_pack_start (GTK_BOX (vbox), align_widget(hbox,0.5,0.5),
686 FALSE, FALSE, DEF_PAD);
687
688 gtk_box_pack_start (GTK_BOX (vbox), reset_accept_buttons_new (data, &img->br_contr_accept), FALSE, FALSE, DEF_PAD);
689
690 return frame;
691 }
692
brightness_contrast_callb(GtkWidget * wdg,gpointer data)693 void brightness_contrast_callb(GtkWidget *wdg, gpointer data) {
694 hf_wrapper_struct *hfw;
695 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
696 if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wdg))) {
697 hf_commit_or_reset (hfw->hf_options);
698 return;
699 }
700 // This dialog should be the default, so it is supposed to be defined with the parent dialog
701 // if (!hfw->hf_options->img->br_contr_dialog) {
702 // hfw->hf_options->img->br_contr_dialog = br_contr_dialog_new(data);
703 // gtk_container_add(GTK_CONTAINER(hfw->tools_dialog),
704 // hfw->hf_options->img->br_contr_dialog );
705 // }
706 if (hfw->hf_options->img->current_subdialog)
707 gtk_widget_hide(hfw->hf_options->img->current_subdialog);
708 hfw->hf_options->img->current_subdialog = hfw->hf_options->img->br_contr_dialog;
709 hfw->hf_options->img->set_fn = (gpointer) set_br_contr_defaults;
710 // printf("ACCEPT_FN: %d\n",accept_fn);
711 hfw->hf_options->img->accept_wdg = hfw->hf_options->img->br_contr_accept ;
712 gtk_widget_show(hfw->hf_options->img->current_subdialog);
713 }
714
715 /************************* THRESHOLD *************************/
716
set_threshold_defaults(img_dialog_struct * img)717 void set_threshold_defaults(img_dialog_struct *img) {
718 gtk_adjustment_set_value(
719 GTK_ADJUSTMENT(img->adj_threshold_min), 0);
720 gtk_adjustment_set_value(
721 GTK_ADJUSTMENT(img->adj_threshold_max), 0xFFFF);
722 gtk_adjustment_set_value(
723 GTK_ADJUSTMENT(img->adj_threshold_percent), 100);
724 }
725
calc_threshold(hf_wrapper_struct * hfw)726 void calc_threshold (hf_wrapper_struct *hfw) {
727 if (hfw->if_calculated)
728 return;
729 hf_threshold(hfw->hf_struct,
730 hfw->hf_options->img->threshold_min,
731 hfw->hf_options->img->threshold_max,
732 hfw->hf_options->img->threshold_percent );
733 begin_pending_record(hfw,"Threshold",accept_fn,reset_fn);
734 gtk_widget_set_sensitive(GTK_WIDGET(hfw->hf_options->img->threshold_accept),TRUE);
735 (*hfw->if_modified) = TRUE;
736 hfw->if_calculated = TRUE;
737 draw_hf(hfw);
738 }
739
threshold_min_upd(GtkWidget * wdg,gpointer data)740 void threshold_min_upd (GtkWidget *wdg, gpointer data) {
741 hf_wrapper_struct *hfw;
742 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
743 // Level to which we apply the threshold filter
744 if (hfw->hf_options->img->threshold_min == (gint) GTK_ADJUSTMENT(wdg)->value)
745 return;
746 hfw->hf_options->img->threshold_min = (gint) GTK_ADJUSTMENT(wdg)->value;
747 hfw->if_calculated = FALSE;
748 calc_threshold(hfw);
749 }
750
threshold_max_upd(GtkWidget * wdg,gpointer data)751 void threshold_max_upd (GtkWidget *wdg, gpointer data) {
752 hf_wrapper_struct *hfw;
753 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
754 // Level to which we apply the threshold filter
755 if (hfw->hf_options->img->threshold_max == (gint) GTK_ADJUSTMENT(wdg)->value)
756 return;
757 hfw->hf_options->img->threshold_max = (gint) GTK_ADJUSTMENT(wdg)->value;
758 hfw->if_calculated = FALSE;
759 calc_threshold(hfw);
760 }
761
threshold_percent_upd(GtkWidget * wdg,gpointer data)762 void threshold_percent_upd (GtkWidget *wdg, gpointer data) {
763 hf_wrapper_struct *hfw;
764 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
765 // Level to which we apply the threshold filter
766 if (hfw->hf_options->img->threshold_percent == (gint) GTK_ADJUSTMENT(wdg)->value)
767 return;
768 hfw->hf_options->img->threshold_percent = (gint) GTK_ADJUSTMENT(wdg)->value;
769 hfw->if_calculated = FALSE;
770 calc_threshold(hfw);
771 }
772
threshold_dialog_new(gpointer data)773 GtkWidget *threshold_dialog_new(gpointer data) {
774 GtkWidget *vbox, *frame, *table, *scale;
775 GtkObject *adj;
776 hf_wrapper_struct *hfw;
777 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
778
779 frame = options_frame_new("Threshold");
780
781 vbox = gtk_vbox_new(FALSE,DEF_PAD);
782 gtk_widget_show(GTK_WIDGET(vbox));
783
784 table = gtk_table_new(3, 2, FALSE);
785 gtk_widget_show(GTK_WIDGET(table));
786
787 define_label_in_table("Minimum",table,0, 1, 0, 1, DEF_PAD);
788 adj = gtk_adjustment_new (hfw->hf_options->img->threshold_min, 0, 0xFFFF, 10, 1, 0.01);
789 scale = define_scale_in_table(adj,table,1, 2, 0, 1, 0, DEF_PAD);
790 optimize_on_mouse_click (scale, data);
791 gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
792 GTK_SIGNAL_FUNC (threshold_min_upd), data);
793 hfw->hf_options->img->adj_threshold_min = adj;
794
795 define_label_in_table("Maximum",table,0, 1, 1, 2, DEF_PAD);
796 adj = gtk_adjustment_new (hfw->hf_options->img->threshold_max, 0, 0xFFFF, 10, 1, 0.01);
797 scale = define_scale_in_table(adj,table,1, 2, 1, 2, 0, DEF_PAD);
798 optimize_on_mouse_click (scale, data);
799 gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
800 GTK_SIGNAL_FUNC (threshold_max_upd), data);
801 hfw->hf_options->img->adj_threshold_max = adj;
802
803 define_label_in_table("%",table,0, 1, 2, 3, DEF_PAD);
804 adj = gtk_adjustment_new (hfw->hf_options->img->threshold_percent, 0, 100, 1, 1, 0.01);
805 scale = define_scale_in_table(adj,table,1, 2, 2, 3, 0, DEF_PAD);
806 optimize_on_mouse_click (scale, data);
807 gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
808 GTK_SIGNAL_FUNC (threshold_percent_upd), data);
809 hfw->hf_options->img->adj_threshold_percent = adj;
810
811 gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
812
813 gtk_box_pack_start (GTK_BOX (vbox), reset_accept_buttons_new (data, &hfw->hf_options->img->threshold_accept), FALSE, FALSE, DEF_PAD);
814
815 gtk_container_add(GTK_CONTAINER(frame), vbox);
816
817 return frame;
818 }
819
threshold_callb(GtkWidget * wdg,gpointer data)820 void threshold_callb(GtkWidget *wdg, gpointer data) {
821 hf_wrapper_struct *hfw;
822 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
823 if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wdg))) {
824 // When we change options, we commit last changes by backing up
825 // the current buffer into the temp buffer
826 hf_commit_or_reset (hfw->hf_options);
827 return;
828 }
829 if (!hfw->hf_options->img->threshold_dialog) {
830 hfw->hf_options->img->threshold_dialog = threshold_dialog_new(data);
831 gtk_container_add(GTK_CONTAINER(hfw->hf_options->img->img_dialog),
832 hfw->hf_options->img->threshold_dialog );
833 }
834 if (hfw->hf_options->img->current_subdialog)
835 gtk_widget_hide(hfw->hf_options->img->current_subdialog);
836 hfw->hf_options->img->current_subdialog = hfw->hf_options->img->threshold_dialog;
837 hfw->hf_options->img->set_fn = (gpointer) set_threshold_defaults;
838 hfw->hf_options->img->accept_wdg = hfw->hf_options->img->threshold_accept ;
839 gtk_widget_show(hfw->hf_options->img->current_subdialog);
840 }
841
842 /************************* SMOOTH *************************/
843
set_smooth_defaults(img_dialog_struct * img)844 void set_smooth_defaults(img_dialog_struct *img) {
845 gtk_adjustment_set_value(
846 GTK_ADJUSTMENT(img->adj_smooth_radius), 0);
847 gtk_adjustment_set_value(
848 GTK_ADJUSTMENT(img->smooth_merge->adj_mix), 100);
849 reset_merge_buffers (img->smooth_merge->content);
850 }
851
calc_smooth(hf_wrapper_struct * hfw)852 void calc_smooth (hf_wrapper_struct *hfw) {
853 gint t1;
854 gboolean wrap;
855 // printf("Calc_smooth\n");
856 if (hfw->if_calculated)
857 return;
858 if (hfw->hf_struct->max_x>hfw->hf_options->dist_matrix->hf_size)
859 dist_matrix_init(hfw->hf_options->dist_matrix, hfw->hf_struct->max_x);
860 t1 = clock();
861 set_watch_cursor(hfw);
862 switch (hfw->hf_options->img->smooth_wrap) {
863 case TILING_AUTO:
864 wrap = *hfw->tiling_ptr;
865 break;
866 case TILING_YES:
867 wrap = TRUE;
868 break;
869 case TILING_NO:
870 wrap = FALSE;
871 }
872
873 hf_backup(hfw->hf_struct);
874
875 hf_init_result_buf_from_hf (hfw->hf_struct);
876
877 smooth_buf (hfw->hf_struct->result_buf,
878 hfw->hf_struct->max_x,
879 hfw->hf_struct->max_y,
880 hfw->hf_options->img->smooth_radius,
881 hfw->hf_options->dist_matrix,
882 wrap,
883 hfw->hf_options->gauss_list,
884 HF_TYPE_ID);
885
886 // printf("TEMPS DE SMOOTH: %d\n",clock() - t1);
887 begin_pending_record(hfw,"Smooth", accept_fn, reset_fn);
888 merge_n_display (hfw, hfw->hf_options->img->smooth_merge->content);
889 }
890
smooth_radius_upd(GtkWidget * wdg,gpointer data)891 void smooth_radius_upd (GtkWidget *wdg, gpointer data) {
892 hf_wrapper_struct *hfw;
893 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
894 if (hfw->hf_options->img->smooth_radius == (gint) GTK_ADJUSTMENT(wdg)->value)
895 return;
896 hfw->hf_options->img->smooth_radius = (gint) GTK_ADJUSTMENT(wdg)->value;
897 hfw->if_calculated = FALSE;
898 }
899
apply_smooth_callb(GtkWidget * wdg,gpointer data)900 void apply_smooth_callb (GtkWidget *wdg, gpointer data) {
901 hf_wrapper_struct *hfw;
902 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
903 calc_smooth(hfw);
904 }
905
repeat_smooth_callb(GtkWidget * wdg,gpointer data)906 void repeat_smooth_callb (GtkWidget *wdg, gpointer data) {
907 hf_wrapper_struct *hfw;
908 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
909 hfw->if_calculated = FALSE;
910 calc_smooth(hfw);
911 }
912
smooth_dialog_new(gpointer data)913 GtkWidget *smooth_dialog_new(gpointer data) {
914 GtkWidget *vbox, *hbox, *frame, *frame2;
915 GtkObject *adj;
916 hf_wrapper_struct *hfw;
917 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
918
919 frame = options_frame_new("Smooth");
920
921 vbox = gtk_vbox_new(FALSE,DEF_PAD);
922 gtk_widget_show(vbox);
923
924 hbox = gtk_hbox_new(FALSE,DEF_PAD);
925 gtk_widget_show(hbox);
926
927 define_label_in_box("Radius",hbox,FALSE, FALSE,DEF_PAD);
928 adj = gtk_adjustment_new (hfw->hf_options->img->smooth_radius, 0, 100, 1, 1, 0.01);
929 define_scale_in_box(adj,hbox, 0, DEF_PAD);
930 gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
931 GTK_SIGNAL_FUNC (smooth_radius_upd), data);
932 hfw->hf_options->img->adj_smooth_radius = adj;
933
934 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
935
936 /*
937 // Sampling filter box, as a % of radius, for testing purposes...
938 // Better at 150% with "sharp" filter
939 hbox = gtk_hbox_new(FALSE,DEF_PAD);
940 gtk_widget_show(hbox);
941
942 define_label_in_box("BOITE",hbox,TRUE, TRUE,DEF_PAD);
943 adj = gtk_adjustment_new (hfw->hf_options->img->smooth_box, 0, 300, 1, 1, 0.01);
944 define_scale_in_box(adj,hbox, 0, DEF_PAD);
945 gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
946 GTK_SIGNAL_FUNC (smooth_box_upd), data);
947 hfw->hf_options->img->adj_smooth_box = adj;
948
949 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
950 */
951 hbox = tiling_control(&hfw->hf_options->img->smooth_wrap);
952
953 gtk_box_pack_start (GTK_BOX (vbox), align_widget(hbox,0.5,0.5), FALSE, FALSE, DEF_PAD);
954
955 // Merge
956
957 hfw->hf_options->img->smooth_merge = merge_dialog_struct_new( merge_struct_new(data,(gpointer) draw_hf_ptr));
958 hfw->hf_options->img->smooth_merge->content->mix = 100;
959 frame2 = merge_dialog_new(hfw->hf_options->img->smooth_merge,
960 TRUE, hfw->hf_options->tools_window, NULL, NULL, NULL, NULL);
961 gtk_box_pack_start(GTK_BOX(vbox), frame2, FALSE, FALSE, 0);
962 gtk_widget_hide (GTK_WIDGET(hfw->hf_options->img->smooth_merge->main_box));
963
964 gtk_box_pack_start (GTK_BOX (vbox), apply_repeat_buttons_new (data, apply_smooth_callb, repeat_smooth_callb), FALSE, FALSE, DEF_PAD);
965
966 gtk_box_pack_start (GTK_BOX (vbox), reset_accept_buttons_new (data, &hfw->hf_options->img->smooth_accept), FALSE, FALSE, DEF_PAD);
967
968 gtk_container_add(GTK_CONTAINER(frame), vbox);
969
970 return frame;
971 }
972
smooth_callb(GtkWidget * wdg,gpointer data)973 void smooth_callb(GtkWidget *wdg, gpointer data) {
974 hf_wrapper_struct *hfw;
975 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
976 if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wdg))) {
977 hf_commit_or_reset (hfw->hf_options);
978 return;
979 }
980 if (!hfw->hf_options->img->smooth_dialog) {
981 hfw->hf_options->img->smooth_dialog = smooth_dialog_new(data);
982 gtk_container_add(GTK_CONTAINER(hfw->hf_options->img->img_dialog),
983 hfw->hf_options->img->smooth_dialog );
984 }
985 if (hfw->hf_options->img->current_subdialog)
986 gtk_widget_hide(hfw->hf_options->img->current_subdialog);
987 hfw->hf_options->img->current_subdialog = hfw->hf_options->img->smooth_dialog;
988 hfw->hf_options->img->set_fn = (gpointer) set_smooth_defaults;
989 hfw->hf_options->img->accept_wdg = hfw->hf_options->img->smooth_accept ;
990 gtk_widget_show(hfw->hf_options->img->current_subdialog);
991 }
992
993 /************************* SHARPEN (increase noise) *************************/
994
set_sharpen_defaults(img_dialog_struct * img)995 void set_sharpen_defaults(img_dialog_struct *img) {
996 gtk_adjustment_set_value(
997 GTK_ADJUSTMENT(img->adj_sharpen_radius), 0);
998 gtk_adjustment_set_value(
999 GTK_ADJUSTMENT(img->sharpen_merge->adj_mix), 100);
1000 }
1001
calc_sharpen(hf_wrapper_struct * hfw)1002 void calc_sharpen (hf_wrapper_struct *hfw) {
1003 gint t1;
1004 gboolean wrap;
1005 gdouble *v;
1006 if (hfw->if_calculated)
1007 return;
1008 if (!hfw->hf_options->img->sharpen_radius)
1009 return;
1010 t1 = clock();
1011 set_watch_cursor(hfw);
1012 switch (hfw->hf_options->img->sharpen_wrap) {
1013 case TILING_AUTO:
1014 wrap = *hfw->tiling_ptr;
1015 break;
1016 case TILING_YES:
1017 wrap = TRUE;
1018 break;
1019 case TILING_NO:
1020 wrap = FALSE;
1021 }
1022
1023 hf_backup(hfw->hf_struct);
1024
1025 v = create_gaussian_kernel (hfw->hf_options->img->sharpen_radius, CONST_E, 10, ((hfw->hf_options->img->sharpen_level)/100.0) - 0.81, 0.55, FALSE);
1026 hf_convolve (hfw->hf_struct,
1027 hfw->hf_options->img->sharpen_radius,
1028 v, wrap);
1029 x_free(v);
1030
1031 // printf("TEMPS DE SHARPEN: %d\n",clock() - t1);
1032 begin_pending_record(hfw,"Sharpen", accept_fn, reset_fn);
1033
1034 merge_n_display (hfw, hfw->hf_options->img->sharpen_merge->content);
1035 }
1036
sharpen_radius_upd(GtkWidget * wdg,gpointer data)1037 void sharpen_radius_upd (GtkWidget *wdg, gpointer data) {
1038 hf_wrapper_struct *hfw;
1039 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
1040 if (hfw->hf_options->img->sharpen_radius == (gint) GTK_ADJUSTMENT(wdg)->value)
1041 return;
1042 hfw->hf_options->img->sharpen_radius = (gint) GTK_ADJUSTMENT(wdg)->value;
1043 hfw->if_calculated = FALSE;
1044 }
1045
sharpen_level_upd(GtkWidget * wdg,gpointer data)1046 void sharpen_level_upd (GtkWidget *wdg, gpointer data) {
1047 hf_wrapper_struct *hfw;
1048 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
1049 if (hfw->hf_options->img->sharpen_level == (gdouble) GTK_ADJUSTMENT(wdg)->value)
1050 return;
1051 hfw->hf_options->img->sharpen_level = (gdouble) GTK_ADJUSTMENT(wdg)->value;
1052 hfw->if_calculated = FALSE;
1053 }
1054
apply_sharpen_callb(GtkWidget * wdg,gpointer data)1055 void apply_sharpen_callb (GtkWidget *wdg, gpointer data) {
1056 hf_wrapper_struct *hfw;
1057 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
1058 calc_sharpen(hfw);
1059 }
1060
repeat_sharpen_callb(GtkWidget * wdg,gpointer data)1061 void repeat_sharpen_callb (GtkWidget *wdg, gpointer data) {
1062 hf_wrapper_struct *hfw;
1063 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
1064 hf_backup(hfw->hf_struct);
1065 hfw->if_calculated = FALSE;
1066 calc_sharpen(hfw);
1067 }
1068
sharpen_dialog_new(gpointer data)1069 GtkWidget *sharpen_dialog_new(gpointer data) {
1070 GtkWidget *vbox, *hbox, *frame, *frame2;
1071 GtkObject *adj;
1072 hf_wrapper_struct *hfw;
1073 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
1074
1075 frame = options_frame_new("Sharpen (increase noise)");
1076
1077 vbox = gtk_vbox_new(FALSE,DEF_PAD);
1078 gtk_widget_show(vbox);
1079
1080 hbox = gtk_hbox_new(FALSE,DEF_PAD);
1081 gtk_widget_show(hbox);
1082
1083 define_label_in_box("Radius",hbox,FALSE, FALSE,DEF_PAD);
1084 adj = gtk_adjustment_new (hfw->hf_options->img->sharpen_radius, 0, 20, 1, 1, 0.01);
1085 define_scale_in_box(adj,hbox, 0, DEF_PAD);
1086 gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
1087 GTK_SIGNAL_FUNC (sharpen_radius_upd), data);
1088 hfw->hf_options->img->adj_sharpen_radius = adj;
1089
1090 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
1091
1092 hbox = gtk_hbox_new(FALSE,DEF_PAD);
1093 gtk_widget_show(hbox);
1094
1095 define_label_in_box("Level",hbox,FALSE, FALSE,DEF_PAD);
1096 adj = gtk_adjustment_new (hfw->hf_options->img->sharpen_level, 0.0, 10.0, 0.01, 0.01, 0.001);
1097 define_scale_in_box(adj,hbox, 1, DEF_PAD);
1098 gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
1099 GTK_SIGNAL_FUNC (sharpen_level_upd), data);
1100 hfw->hf_options->img->adj_sharpen_level = adj;
1101
1102 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
1103
1104 hbox = tiling_control(&hfw->hf_options->img->sharpen_wrap);
1105
1106 gtk_box_pack_start (GTK_BOX (vbox), align_widget(hbox,0.5,0.5), FALSE, FALSE, DEF_PAD);
1107
1108 // Merge
1109
1110 hfw->hf_options->img->sharpen_merge = merge_dialog_struct_new ( merge_struct_new(data,(gpointer) draw_hf_ptr) );
1111 hfw->hf_options->img->sharpen_merge->content->mix = 100;
1112 frame2 = merge_dialog_new(hfw->hf_options->img->sharpen_merge,
1113 TRUE, hfw->hf_options->tools_window, NULL, NULL, NULL, NULL);
1114 gtk_box_pack_start(GTK_BOX(vbox), frame2, FALSE, FALSE, 0);
1115 gtk_widget_hide (GTK_WIDGET(hfw->hf_options->img->sharpen_merge->main_box));
1116
1117 gtk_box_pack_start (GTK_BOX (vbox), apply_repeat_buttons_new (data, apply_sharpen_callb, repeat_sharpen_callb), FALSE, FALSE, DEF_PAD);
1118
1119 gtk_box_pack_start (GTK_BOX (vbox), reset_accept_buttons_new (data, &hfw->hf_options->img->sharpen_accept), FALSE, FALSE, DEF_PAD);
1120
1121 gtk_container_add(GTK_CONTAINER(frame), vbox);
1122
1123 return frame;
1124 }
1125
sharpen_callb(GtkWidget * wdg,gpointer data)1126 void sharpen_callb(GtkWidget *wdg, gpointer data) {
1127 hf_wrapper_struct *hfw;
1128 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
1129 if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wdg))) {
1130 hf_commit_or_reset (hfw->hf_options);
1131 return;
1132 }
1133 if (!hfw->hf_options->img->sharpen_dialog) {
1134 hfw->hf_options->img->sharpen_dialog = sharpen_dialog_new(data);
1135 gtk_container_add(GTK_CONTAINER(hfw->hf_options->img->img_dialog),
1136 hfw->hf_options->img->sharpen_dialog );
1137 }
1138 if (hfw->hf_options->img->current_subdialog)
1139 gtk_widget_hide(hfw->hf_options->img->current_subdialog);
1140 hfw->hf_options->img->current_subdialog = hfw->hf_options->img->sharpen_dialog;
1141 hfw->hf_options->img->set_fn = (gpointer) set_sharpen_defaults;
1142 hfw->hf_options->img->accept_wdg = hfw->hf_options->img->sharpen_accept ;
1143 gtk_widget_show(hfw->hf_options->img->current_subdialog);
1144 }
1145
1146 /************************* CITYSCAPE *************************/
1147
set_cityscape_defaults(img_dialog_struct * img)1148 void set_cityscape_defaults(img_dialog_struct *img) {
1149 gtk_adjustment_set_value(
1150 GTK_ADJUSTMENT(img->adj_skyscraper_width), 0);
1151 gtk_adjustment_set_value(
1152 GTK_ADJUSTMENT(img->adj_skyscraper_width_var), 0);
1153 gtk_adjustment_set_value(
1154 GTK_ADJUSTMENT(img->adj_streets_width), 0);
1155 gtk_adjustment_set_value(
1156 GTK_ADJUSTMENT(img->cityscape_merge->adj_mix), 100);
1157 }
1158
calc_cityscape(hf_wrapper_struct * hfw)1159 void calc_cityscape (hf_wrapper_struct *hfw) {
1160 if (hfw->if_calculated)
1161 return;
1162 hf_city( hfw->hf_struct,
1163 hfw->hf_options->img->skyscraper_width,
1164 hfw->hf_options->img->skyscraper_width_var,
1165 hfw->hf_options->img->streets_width);
1166 begin_pending_record(hfw,"City",accept_fn, reset_fn);
1167 merge_n_display (hfw, hfw->hf_options->img->cityscape_merge->content);
1168 }
1169
skyscraper_width_upd(GtkWidget * wdg,gpointer data)1170 void skyscraper_width_upd (GtkWidget *wdg, gpointer data) {
1171 hf_wrapper_struct *hfw;
1172 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
1173 if (hfw->hf_options->img->skyscraper_width == (gint) GTK_ADJUSTMENT(wdg)->value)
1174 return;
1175 hfw->hf_options->img->skyscraper_width = (gint) GTK_ADJUSTMENT(wdg)->value;
1176 hfw->if_calculated = FALSE;
1177 calc_cityscape(hfw);
1178 }
1179
skyscraper_width_var_upd(GtkWidget * wdg,gpointer data)1180 void skyscraper_width_var_upd (GtkWidget *wdg, gpointer data) {
1181 // % of skyscraper size variation
1182 hf_wrapper_struct *hfw;
1183 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
1184 if (hfw->hf_options->img->skyscraper_width_var == (gint) GTK_ADJUSTMENT(wdg)->value)
1185 return;
1186 hfw->hf_options->img->skyscraper_width_var = (gint) GTK_ADJUSTMENT(wdg)->value;
1187 hfw->if_calculated = FALSE;
1188 calc_cityscape(hfw);
1189 }
1190
streets_width_upd(GtkWidget * wdg,gpointer data)1191 void streets_width_upd (GtkWidget *wdg, gpointer data) {
1192 // Streets width, as a % of skyscraper size (max. 50%, means 25% of each surrounding sk-scr)
1193 hf_wrapper_struct *hfw;
1194 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
1195 if (hfw->hf_options->img->streets_width == (gint) GTK_ADJUSTMENT(wdg)->value)
1196 return;
1197 hfw->hf_options->img->streets_width = (gint) GTK_ADJUSTMENT(wdg)->value;
1198 hfw->if_calculated = FALSE;
1199 calc_cityscape(hfw);
1200 }
1201
smooth_1_pixel_callb(GtkWidget * wdg,gpointer data)1202 void smooth_1_pixel_callb (GtkWidget *wdg, gpointer data) {
1203 hf_wrapper_struct *hfw;
1204 static gdouble blur_matrix[] = {0.0625,0.125,0.0625,0.125,0.25,0.125,0.0625,0.125,0.0625};
1205 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
1206 begin_pending_record(hfw,"Smooth 1 pixel",accept_fn, reset_fn);
1207 hf_convolve (hfw->hf_struct,1, blur_matrix, FALSE);
1208 gtk_widget_set_sensitive(GTK_WIDGET(hfw->hf_options->img->cityscape_accept),TRUE);
1209 (*hfw->if_modified) = TRUE;
1210 draw_hf(hfw);
1211 }
1212
city_dialog_new(gpointer data)1213 GtkWidget *city_dialog_new(gpointer data) {
1214 GtkWidget *vbox, *frame, *frame2, *button, *table, *scale;
1215 GtkObject *adj;
1216 hf_wrapper_struct *hfw;
1217 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
1218 frame = options_frame_new("City");
1219
1220 vbox = gtk_vbox_new(FALSE,DEF_PAD);
1221 gtk_widget_show(vbox);
1222
1223 table = gtk_table_new(2, 3, FALSE);
1224 gtk_widget_show(GTK_WIDGET(table));
1225
1226 define_label_in_table("Skyscaper width", table, 0, 1, 0, 1, DEF_PAD);
1227
1228 adj = gtk_adjustment_new (hfw->hf_options->img->skyscraper_width, 0, 100, 1, 1, 0.01);
1229 scale = define_scale_in_table(adj,table,1,2,0,1,0, DEF_PAD);
1230 optimize_on_mouse_click (scale, data);
1231 gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
1232 GTK_SIGNAL_FUNC (skyscraper_width_upd), data);
1233 hfw->hf_options->img->adj_skyscraper_width = adj;
1234
1235 define_label_in_table("Streets width",table,0,1,1,2,DEF_PAD);
1236 adj = gtk_adjustment_new (hfw->hf_options->img->skyscraper_width, 0, 50, 1, 1, 0.01);
1237 scale = define_scale_in_table(adj,table,1,2,1,2,0, DEF_PAD);
1238 optimize_on_mouse_click (scale, data);
1239 gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
1240 GTK_SIGNAL_FUNC (streets_width_upd), data);
1241 hfw->hf_options->img->adj_streets_width = adj;
1242
1243 define_label_in_table("Width variation (%)",table,0,1,2,3,DEF_PAD);
1244 adj = gtk_adjustment_new (hfw->hf_options->img->skyscraper_width_var, 0, 100, 1, 1, 0.01);
1245 scale = define_scale_in_table(adj,table,1,2,2,3,0, DEF_PAD);
1246 optimize_on_mouse_click (scale, data);
1247 gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
1248 GTK_SIGNAL_FUNC (skyscraper_width_var_upd), data);
1249 hfw->hf_options->img->adj_skyscraper_width_var = adj;
1250
1251 gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
1252
1253 button = gtk_button_new_with_label (_("Smooth 1 pixel"));
1254 gtk_widget_show(button);
1255 gtk_signal_connect (GTK_OBJECT (button), "clicked",
1256 (GtkSignalFunc) smooth_1_pixel_callb, data);
1257
1258 // Merge
1259
1260 hfw->hf_options->img->cityscape_merge = merge_dialog_struct_new ( merge_struct_new(data, (gpointer) draw_hf_ptr));
1261 hfw->hf_options->img->cityscape_merge->content->mix = 100;
1262 frame2 = merge_dialog_new(hfw->hf_options->img->cityscape_merge,
1263 TRUE, hfw->hf_options->tools_window, NULL, NULL, NULL, NULL);
1264 gtk_box_pack_start(GTK_BOX(vbox), frame2, FALSE, FALSE, 0);
1265 gtk_widget_hide (GTK_WIDGET(hfw->hf_options->img->cityscape_merge->main_box));
1266
1267 gtk_box_pack_start (GTK_BOX (vbox), align_widget(button,0.5,0.5), FALSE, FALSE, DEF_PAD);
1268
1269 gtk_box_pack_start (GTK_BOX (vbox), reset_accept_buttons_new (data, &hfw->hf_options->img->cityscape_accept), FALSE, FALSE, DEF_PAD);
1270
1271 gtk_container_add(GTK_CONTAINER(frame), vbox);
1272
1273 return frame;
1274 }
1275
city_callb(GtkWidget * wdg,gpointer data)1276 void city_callb(GtkWidget *wdg, gpointer data) {
1277 hf_wrapper_struct *hfw;
1278 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
1279 if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wdg))) {
1280 hf_commit_or_reset (hfw->hf_options);
1281 return;
1282 }
1283 if (!hfw->hf_options->img->city_dialog) {
1284 hfw->hf_options->img->city_dialog = city_dialog_new(data);
1285 gtk_container_add(GTK_CONTAINER(hfw->hf_options->img->img_dialog),
1286 hfw->hf_options->img->city_dialog );
1287 }
1288 if (hfw->hf_options->img->current_subdialog)
1289 gtk_widget_hide(hfw->hf_options->img->current_subdialog);
1290 hfw->hf_options->img->current_subdialog = hfw->hf_options->img->city_dialog;
1291 hfw->hf_options->img->set_fn = (gpointer) set_cityscape_defaults;
1292 hfw->hf_options->img->accept_wdg = hfw->hf_options->img->cityscape_accept ;
1293 gtk_widget_show(hfw->hf_options->img->current_subdialog);
1294 }
1295
1296 /************************* TERRACES *************************/
1297
set_terrace_defaults(img_dialog_struct * img)1298 void set_terrace_defaults(img_dialog_struct *img) {
1299 gtk_adjustment_set_value(
1300 GTK_ADJUSTMENT(img->adj_terrace_levels), 0);
1301 gtk_adjustment_set_value(
1302 GTK_ADJUSTMENT(img->terrace_merge->adj_mix), 100);
1303 }
1304
calc_terrace(hf_wrapper_struct * hfw)1305 void calc_terrace (hf_wrapper_struct *hfw) {
1306 gboolean wrap;
1307 if (hfw->if_calculated)
1308 return;
1309 if (hfw->hf_options->img->terrace_smooth_radius)
1310 if (hfw->hf_struct->max_x>hfw->hf_options->dist_matrix->hf_size)
1311 dist_matrix_init(hfw->hf_options->dist_matrix, hfw->hf_struct->max_x);
1312 switch (hfw->hf_options->img->terrace_wrap) {
1313 case TILING_AUTO:
1314 wrap = *hfw->tiling_ptr;
1315 break;
1316 case TILING_YES:
1317 wrap = TRUE;
1318 break;
1319 case TILING_NO:
1320 wrap = FALSE;
1321 }
1322 if (hfw->hf_options->img->terrace_apply_postprocess )
1323 set_watch_cursor(hfw);
1324
1325 hf_terrace(hfw->hf_struct,
1326 hfw->hf_options->img->terrace_levels,
1327 hfw->hf_options->img->terrace_seed,
1328 hfw->hf_options->img->terrace_percent_random,
1329 hfw->hf_options->img->terrace_smooth_radius,
1330 wrap,
1331 hfw->hf_options->dist_matrix,
1332 hfw->hf_options->img->terrace_artifact_radius,
1333 hfw->hf_options->img->terrace_apply_postprocess,
1334 hfw->hf_options->gauss_list);
1335
1336 if (hfw->hf_options->img->terrace_apply_postprocess )
1337 unset_watch_cursor(hfw);
1338 hfw->hf_options->img->terrace_apply_postprocess = FALSE;
1339 begin_pending_record(hfw,"Terraces", accept_fn, reset_fn);
1340 merge_n_display (hfw, hfw->hf_options->img->terrace_merge->content);
1341 }
1342
terrace_levels_upd(GtkWidget * wdg,gpointer data)1343 void terrace_levels_upd (GtkWidget *wdg, gpointer data) {
1344 // Updates the number of terrace levels and displays the HF
1345 hf_wrapper_struct *hfw;
1346 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
1347 if (hfw->hf_options->img->terrace_levels == (gint) GTK_ADJUSTMENT(wdg)->value)
1348 return;
1349 hfw->hf_options->img->terrace_levels = (gint) GTK_ADJUSTMENT(wdg)->value;
1350
1351 if (!hfw->hf_options->img->terrace_levels) {
1352 reset_callb(wdg,data);
1353 return;
1354 }
1355 hfw->if_calculated = FALSE;
1356 calc_terrace(hfw);
1357 }
1358
terrace_percent_random_upd(GtkWidget * wdg,gpointer data)1359 void terrace_percent_random_upd (GtkWidget *wdg, gpointer data) {
1360 // Updates the level of randomness variation of each "step"
1361 hf_wrapper_struct *hfw;
1362 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
1363 if (hfw->hf_options->img->terrace_percent_random == (gint) GTK_ADJUSTMENT(wdg)->value)
1364 return;
1365 hfw->hf_options->img->terrace_percent_random = (gint) GTK_ADJUSTMENT(wdg)->value;
1366 hfw->if_calculated = FALSE;
1367 calc_terrace(hfw);
1368 }
1369
terrace_smooth_radius_upd(GtkWidget * wdg,gpointer data)1370 void terrace_smooth_radius_upd (GtkWidget *wdg, gpointer data) {
1371 hf_wrapper_struct *hfw;
1372 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
1373 if (hfw->hf_options->img->terrace_smooth_radius == (gint) GTK_ADJUSTMENT(wdg)->value)
1374 return;
1375 hfw->hf_options->img->terrace_smooth_radius = (gint) GTK_ADJUSTMENT(wdg)->value;
1376 hfw->if_calculated = FALSE;
1377 // calc_terrace(hfw);
1378 }
1379
terrace_apply_postprocess_callb(GtkWidget * wdg,gpointer data)1380 void terrace_apply_postprocess_callb (GtkWidget *wdg, gpointer data) {
1381 hf_wrapper_struct *hfw;
1382 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
1383 hfw->hf_options->img->terrace_apply_postprocess = TRUE;
1384 hfw->if_calculated = FALSE;
1385 calc_terrace(hfw);
1386 }
1387
change_terrace_seed(GtkWidget * entry,gpointer data)1388 static gint change_terrace_seed(GtkWidget *entry, gpointer data) {
1389 hf_wrapper_struct *hfw;
1390 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
1391 hfw->hf_options->img->terrace_seed =
1392 (unsigned int) atoi((char *)gtk_entry_get_text(GTK_ENTRY(entry)));
1393 hfw->if_calculated = FALSE;
1394 calc_terrace(hfw);
1395 return FALSE;
1396 }
1397
terrace_artifact_radius_upd(GtkWidget * wdg,gpointer data)1398 void terrace_artifact_radius_upd (GtkWidget *wdg, gpointer data) {
1399 hf_wrapper_struct *hfw;
1400 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
1401 if (hfw->hf_options->img->terrace_artifact_radius == (gint) GTK_ADJUSTMENT(wdg)->value)
1402 return;
1403 hfw->hf_options->img->terrace_artifact_radius = (gint) GTK_ADJUSTMENT(wdg)->value;
1404 hfw->if_calculated = FALSE;
1405 // calc_terrace(hfw);
1406 }
1407
terrace_dialog_new(gpointer data)1408 GtkWidget *terrace_dialog_new(gpointer data) {
1409 GtkWidget *vbox, *vbox2, *vbox3, *hbox, *frame, *frame2, *button;
1410 GtkObject *adj;
1411 hf_wrapper_struct *hfw;
1412 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
1413
1414 frame = options_frame_new("Terraces");
1415
1416 vbox = gtk_vbox_new(FALSE,DEF_PAD); // vbox for all options
1417 gtk_widget_show(vbox);
1418 gtk_container_add(GTK_CONTAINER(frame), vbox);
1419
1420 vbox2 = gtk_vbox_new(FALSE,DEF_PAD); // vbox for quantization
1421 gtk_widget_show(vbox2);
1422
1423 hbox = gtk_hbox_new(FALSE,DEF_PAD);
1424 gtk_widget_show(hbox);
1425 define_label_in_box("Levels", hbox,FALSE, FALSE, DEF_PAD);
1426 adj = gtk_adjustment_new (hfw->hf_options->img->terrace_levels, 0, 50, 1, 1, 0.01);
1427 define_scale_in_box(adj, hbox, 0, DEF_PAD);
1428 gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
1429 GTK_SIGNAL_FUNC (terrace_levels_upd), data);
1430 hfw->hf_options->img->adj_terrace_levels = adj;
1431
1432 gtk_box_pack_start(GTK_BOX(vbox2),hbox, TRUE, TRUE, DEF_PAD *0.5);
1433
1434 // Random variation
1435
1436 vbox3 = gtk_vbox_new(FALSE,DEF_PAD);
1437 gtk_widget_show(vbox3);
1438 frame2 = frame_new("Random var.",DEF_PAD*0.5);
1439 gtk_container_add(GTK_CONTAINER(frame2),vbox3);
1440 hbox = gtk_hbox_new(FALSE,DEF_PAD);
1441 gtk_widget_show(hbox);
1442 define_label_in_box("%", hbox,FALSE,FALSE, DEF_PAD);
1443 adj = gtk_adjustment_new (hfw->hf_options->img->terrace_percent_random, 0.0, 100.0, 1.0, 1.0, 0.0);
1444 define_scale_in_box(adj, hbox, 0, DEF_PAD);
1445 gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
1446 GTK_SIGNAL_FUNC (terrace_percent_random_upd), data);
1447 hfw->hf_options->img->adj_terrace_percent_random = adj;
1448 gtk_box_pack_start(GTK_BOX(vbox3), hbox, TRUE, TRUE, DEF_PAD*0.5);
1449 gtk_box_pack_start(GTK_BOX(vbox3),
1450 seed_dialog_new(data, hfw->hf_options->img->terrace_seed, change_terrace_seed),
1451 TRUE, TRUE, DEF_PAD*0.5);
1452
1453 gtk_box_pack_start(GTK_BOX(vbox2), frame2, TRUE, TRUE, DEF_PAD*0.5);
1454
1455 // Main "quantization" frame
1456
1457 frame2 = define_frame_with_hiding_arrows ("Quantization", vbox2, hfw->hf_options->tools_window, TRUE);
1458 gtk_box_pack_start(GTK_BOX(vbox), frame2, TRUE, TRUE, 0); // the main box
1459
1460 /********************** Post-process subdialogs *************************/
1461
1462 vbox2 = gtk_vbox_new(FALSE,DEF_PAD); // vbox for subdialogs
1463 gtk_widget_show(vbox2);
1464
1465 // Terraces' smooth
1466
1467 vbox3 = gtk_vbox_new(FALSE,DEF_PAD);
1468 gtk_widget_show(vbox3);
1469 frame2 = frame_new("Smooth",DEF_PAD*0.5);
1470 gtk_container_add(GTK_CONTAINER(frame2),vbox3);
1471
1472 hbox = gtk_hbox_new(FALSE,DEF_PAD);
1473 gtk_widget_show(hbox);
1474 define_label_in_box("Radius", hbox,FALSE,FALSE, DEF_PAD);
1475 adj = gtk_adjustment_new (hfw->hf_options->img->terrace_smooth_radius, 0.0, 20.0, 1.0, 1.0, 0.0);
1476 define_scale_in_box(adj, hbox, 0, DEF_PAD);
1477 gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
1478 GTK_SIGNAL_FUNC (terrace_smooth_radius_upd), data);
1479 hfw->hf_options->img->adj_terrace_smooth_radius = adj;
1480 gtk_box_pack_start(GTK_BOX(vbox3), hbox, TRUE, TRUE, DEF_PAD*0.5);
1481
1482 // hbox for "wrap" buttons
1483
1484 hbox = tiling_control(&hfw->hf_options->img->terrace_wrap);
1485
1486 gtk_box_pack_start (GTK_BOX (vbox3), align_widget(hbox,0.5,0.5),
1487 FALSE, FALSE, DEF_PAD*0.5);
1488
1489 gtk_box_pack_start(GTK_BOX(vbox2), frame2, TRUE, TRUE, 0);
1490
1491 /********************** Smooth subdialog end ****************************/
1492
1493 // Artifact removal
1494
1495 vbox3 = gtk_vbox_new(FALSE,DEF_PAD);
1496 gtk_widget_show(vbox3);
1497 frame2 = frame_new("Artifact removal",DEF_PAD*0.5);
1498 gtk_container_add(GTK_CONTAINER(frame2),vbox3);
1499
1500 hbox = gtk_hbox_new(FALSE,DEF_PAD);
1501 gtk_widget_show(hbox);
1502
1503 define_label_in_box("Radius", hbox,FALSE,FALSE, DEF_PAD);
1504 adj = gtk_adjustment_new (hfw->hf_options->img->terrace_artifact_radius, 0.0, 20.0, 1.0, 1.0, 0.0);
1505 define_scale_in_box(adj, hbox, 0, DEF_PAD);
1506 gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
1507 GTK_SIGNAL_FUNC (terrace_artifact_radius_upd), data);
1508 hfw->hf_options->img->adj_terrace_artifact_radius = adj;
1509 gtk_box_pack_start(GTK_BOX(vbox3), hbox, TRUE, TRUE, DEF_PAD*0.5);
1510
1511 gtk_box_pack_start(GTK_BOX(vbox2), frame2, TRUE, TRUE, 0);
1512
1513 /********************** Artifact subdialog end ****************************/
1514
1515 button = gtk_button_new_with_label (_("Apply"));
1516 gtk_signal_connect (GTK_OBJECT (button), "clicked",
1517 (GtkSignalFunc) terrace_apply_postprocess_callb, data);
1518 gtk_widget_show(button);
1519
1520 gtk_box_pack_start (GTK_BOX (vbox2), align_widget(button,0.5,0.5),
1521 FALSE, FALSE, DEF_PAD*0.5);
1522
1523 // Post-process frame
1524
1525 frame2 = define_frame_with_hiding_arrows ("Result post-processing", vbox2, hfw->hf_options->tools_window, FALSE);
1526
1527 gtk_box_pack_start(GTK_BOX(vbox), frame2, TRUE, TRUE, 0); // the main box
1528
1529 /********************** Post-process frame end ****************************/
1530
1531 // Merge
1532
1533 hfw->hf_options->img->terrace_merge = merge_dialog_struct_new (merge_struct_new(data, (gpointer) draw_hf_ptr));
1534 hfw->hf_options->img->terrace_merge->content->mix = 100;
1535 frame2 = merge_dialog_new(hfw->hf_options->img->terrace_merge,
1536 TRUE, hfw->hf_options->tools_window, NULL, NULL, NULL, NULL);
1537 gtk_box_pack_start(GTK_BOX(vbox), frame2, FALSE, FALSE, 0);
1538 gtk_widget_hide (GTK_WIDGET(hfw->hf_options->img->terrace_merge->main_box));
1539
1540 // Control buttons
1541
1542 gtk_box_pack_start (GTK_BOX (vbox), reset_accept_buttons_new (data, &hfw->hf_options->img->terrace_accept), FALSE, FALSE, DEF_PAD);
1543
1544 return frame;
1545 }
1546
terrace_callb(GtkWidget * wdg,gpointer data)1547 void terrace_callb(GtkWidget *wdg, gpointer data) {
1548 hf_wrapper_struct *hfw;
1549 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
1550 if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wdg))) {
1551 hf_commit_or_reset (hfw->hf_options);
1552 return;
1553 }
1554 if (!hfw->hf_options->img->terrace_dialog) {
1555 hfw->hf_options->img->terrace_dialog = terrace_dialog_new(data);
1556 gtk_container_add(GTK_CONTAINER(hfw->hf_options->img->img_dialog),
1557 hfw->hf_options->img->terrace_dialog );
1558 }
1559 if (hfw->hf_options->img->current_subdialog)
1560 gtk_widget_hide(hfw->hf_options->img->current_subdialog);
1561 hfw->hf_options->img->current_subdialog = hfw->hf_options->img->terrace_dialog;
1562 hfw->hf_options->img->set_fn = (gpointer) set_terrace_defaults;
1563 hfw->hf_options->img->accept_wdg = hfw->hf_options->img->terrace_accept ;
1564 gtk_widget_show(hfw->hf_options->img->current_subdialog);
1565 }
1566
1567 /************************* REVERT *************************/
1568
revert_dialog_new(gpointer data)1569 GtkWidget *revert_dialog_new(gpointer data) {
1570 GtkWidget *lbl, *frame;
1571 hf_wrapper_struct *hfw;
1572 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
1573 frame = options_frame_new("Revert");
1574 lbl = gtk_label_new(_("No parameters\nfor this operation"));
1575 gtk_widget_show(lbl);
1576 gtk_container_add(GTK_CONTAINER(frame), lbl);
1577 return frame;
1578 }
1579
1580 // gdouble matrix[9] = {1.0, 1.0, 1.0, 1.0, -8.0, 1.0, 1.0, 1.0, 1.0};
1581 // gdouble matrix[9] = {0.5, 0.5, 0.5, 0.5, -4.0, 0.5, 0.5, 0.5, 0.5};
1582 // gdouble matrix[9] = {0.1, 0.1, 0.1, 0.1, -0.8, 0.1, 0.1, 0.1, 0.1};
1583 // gdouble matrix[9] = {-0.1, -0.1, -0.1, -0.1, 1.8, -0.1, -0.1, -0.1, -0.1};
1584
1585 // gdouble matrix[9] = {0.2, 0.2, 0.2, 0.2, -0.6, 0.2, 0.2, 0.2, 0.2};
1586
1587 /*
1588 gdouble matrix[25] = {
1589 -0.1, -0.1, -0.1, -0.1, -0.1,
1590 -0.1, -0.1, -0.1, -0.1, -0.1,
1591 -0.1, -0.1, 5.0, -0.1, -0.1,
1592 -0.1, -0.1, -0.1, -0.1, -0.1,
1593 -0.1, -0.1, -0.1, -0.1, -0.1};
1594
1595 // Kernel for "noising" (sharpening)
1596 gdouble matrix[25] = {
1597 0.1, 0.1, 0.1, 0.1, 0.1,
1598 0.1, 0.2, 0.2, 0.2, 0.1,
1599 0.1, 0.2, -2.2, 0.2, 0.1,
1600 0.1, 0.2, 0.2, 0.2, 0.1,
1601 0.1, 0.1, 0.1, 0.1, 0.1};
1602 */
1603
1604 /*
1605 // Kernels for "noising" (sharpening)
1606 gdouble matrix3[25] = {
1607 0.1, 0.1, 0.1, 0.1, 0.1,
1608 0.1, -0.2, -0.2, -0.2, 0.1,
1609 0.1, -0.2, -2.2, -0.2, 0.1,
1610 0.1, -0.2, -0.2, -0.2, 0.1,
1611 0.1, 0.1, 0.1, 0.1, 0.1};
1612
1613 gdouble matrix1[49] = {
1614 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1,
1615 0.1, 0.2, 0.2, 0.2, 0.2, 0.2, 0.1,
1616 0.1, 0.2, 0.4, 0.4, 0.4, 0.2, 0.1,
1617 0.1, 0.2, 0.4, -8.6, 0.4, 0.2, 0.1,
1618 0.1, 0.2, 0.4, 0.4, 0.4, 0.2, 0.1,
1619 0.1, 0.2, 0.2, 0.2, 0.2, 0.2, 0.1,
1620 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1};
1621 gdouble matrix2[49] = {
1622 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1,
1623 0.1, 0.2, 0.2, 0.2, 0.2, 0.2, 0.1,
1624 0.1, 0.2, -0.2, -0.2, -0.2, 0.2, 0.1,
1625 0.1, 0.2, -0.2, -2.4, -0.2, 0.2, 0.1,
1626 0.1, 0.2, -0.2, -0.2, -0.2, 0.2, 0.1,
1627 0.1, 0.2, 0.2, 0.2, 0.2, 0.2, 0.1,
1628 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1};
1629 gdouble matrix[49] = {
1630 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2,
1631 0.2, -0.1, -0.1, -0.1, -0.1, -0.1, 0.2,
1632 0.2, -0.1, -0.2, -0.2, -0.2, -0.1, 0.2,
1633 0.2, -0.1, -0.2, -2.4, -0.2, -0.1, 0.2,
1634 0.2, -0.1, -0.2, -0.2, -0.2, -0.1, 0.2,
1635 0.2, -0.1, -0.1, -0.1, -0.1, -0.1, 0.2,
1636 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2};
1637 */
1638
revert_callb(GtkWidget * wdg,gpointer data)1639 void revert_callb(GtkWidget *wdg, gpointer data) {
1640
1641 hf_wrapper_struct *hfw;
1642 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
1643
1644 // gint i, min, max;
1645 // gdouble ratio;
1646 // static gboolean flag=TRUE;
1647 // static double complex *dc=NULL, *dci=NULL;
1648 // static gint *gint_buf=NULL;
1649
1650 // printf("Revert_callb\n");
1651 if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wdg))) {
1652 commit_pending_record(hfw);
1653 // hf_backup(hfw->hf_struct); No need the commit the change here, no tmp_buf!
1654 return;
1655 }
1656 if (!hfw->hf_options->img->revert_dialog) {
1657 hfw->hf_options->img->revert_dialog = revert_dialog_new(data);
1658 gtk_container_add(GTK_CONTAINER(hfw->hf_options->img->img_dialog),
1659 hfw->hf_options->img->revert_dialog );
1660 }
1661 if (hfw->hf_options->img->current_subdialog)
1662 gtk_widget_hide(hfw->hf_options->img->current_subdialog);
1663 hfw->hf_options->img->current_subdialog = hfw->hf_options->img->revert_dialog;
1664 gtk_widget_show(hfw->hf_options->img->current_subdialog);
1665 // hf_backup(hfw->hf_struct); // Remove for hf_revert
1666
1667 hf_revert(hfw->hf_struct);
1668
1669 // hf_erode (hfw->hf_struct, 1, matrix);
1670 /*
1671 if (!gint_buf)
1672 gint_buf = (gint *) calloc(sizeof(gint), hfw->hf_struct->max_x * hfw->hf_struct->max_y);
1673 if (flag) {
1674 fourier_struct_init (hfw->hf_options->fourier->fs, (gpointer) hfw->hf_struct->tmp_buf, hfw->hf_struct->max_x, hfw->hf_struct->max_y, HF_TYPE_ID);
1675 fourier_filter_init (hfw->hf_options->fourier->fs->ffs, F_BOX, 5.0, 5.0, 0.0, 0.0, 30.0, 100.0);
1676 fourier_apply_filter (hfw->hf_options->fourier->fs);
1677 convert2module(hfw->hf_options->fourier->fs, (gpointer) hfw->hf_struct->hf_buf, HF_TYPE_ID);
1678 flag=FALSE;
1679 }
1680 else {
1681 fourier_compute_inverse (hfw->hf_options->fourier->fs);
1682 convert_finv (hfw->hf_options->fourier->fs, (gpointer) hfw->hf_struct->hf_buf, HF_TYPE_ID);
1683 flag=TRUE;
1684 }
1685 */
1686
1687 // for (i=0; i<49; i++) {
1688 // *(matrix+i) = *(matrix1+i)*0.1;
1689 // printf("Mat[%d]: %f\n",i,*(matrix+i));
1690 // }
1691
1692 // hf_convolve(hfw->hf_struct, 3, matrix, FALSE);
1693 // write_pixels(hfw->hf_struct,create_site_list (hfw->hf_struct->max_x, hfw->hf_struct->max_y, 20, UNIFORM), 0xFFFF);
1694 // write_pixels(hfw->hf_struct, create_site_list (hfw->hf_struct->max_x, hfw->hf_struct->max_y, 10, CENTERED), 0);
1695 // hf_erode(hfw->hf_struct, 5);
1696
1697 // find_maximum (hfw->hf_struct->tmp_buf, hfw->hf_struct->hf_buf, hfw->hf_struct->max_x, hfw->hf_struct->max_y, 0, 0);
1698
1699 begin_pending_record(hfw,"Revert", accept_fn, reset_fn);
1700 (*hfw->if_modified) = TRUE;
1701 hfw->if_calculated = FALSE;
1702 draw_hf(hfw);
1703 }
1704
1705 /************************************* SHAPE FILTERS *********************************/
1706
accept_filter_fn(hf_wrapper_struct * hfw)1707 void accept_filter_fn (hf_wrapper_struct *hfw) {
1708 accept_fn(hfw);
1709 hfw->apply_filter = FALSE;
1710 }
1711
set_f_defaults(img_dialog_struct * img)1712 void set_f_defaults(img_dialog_struct *img) {
1713 set_filter_defaults(img->fd_struct);
1714 }
1715
calc_shape_filter(hf_wrapper_struct * hfw)1716 void calc_shape_filter (hf_wrapper_struct *hfw) {
1717 // "filter_apply" does not copy tmp_buf to hf_buf, because it was developped for
1718 // the creation process, so we have to refresh hf_buf with tmp_buf before applying it
1719
1720 if (hfw->if_calculated)
1721 return;
1722 if (hfw->hf_struct->tmp_buf)
1723 memcpy(hfw->hf_struct->hf_buf, hfw->hf_struct->tmp_buf,
1724 hfw->hf_struct->max_x*hfw->hf_struct->max_y*sizeof(hf_type));
1725 else
1726 hf_backup(hfw->hf_struct);
1727 gtk_widget_set_sensitive(GTK_WIDGET(hfw->hf_options->img->filter_accept),TRUE);
1728 (*hfw->if_modified) = TRUE;
1729 hfw->if_calculated = TRUE;
1730 // The filter is applied in draw_hf, on the main buffer
1731 draw_hf(hfw);
1732 begin_pending_record(hfw,"Shape filter", accept_filter_fn, reset_fn);
1733 }
1734
img_filter_dialog_new(gpointer data)1735 GtkWidget *img_filter_dialog_new(gpointer data) {
1736 GtkWidget *frame, *vbox, *vbox2;
1737 hf_wrapper_struct *hfw;
1738 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
1739
1740 frame = options_frame_new("Shape filter");
1741
1742 vbox = gtk_vbox_new(FALSE,0);
1743 gtk_widget_show(vbox);
1744
1745 gtk_container_add(GTK_CONTAINER(frame), vbox);
1746
1747 hfw->hf_options->img->fd_struct = filter_toolbar_new (hfw->hf_options->tools_window, hfw->hf_options->tooltips, data);
1748
1749 // Embed the function which applies the filter
1750 hfw->hf_options->img->fd_struct->apply_filter = (gpointer) calc_shape_filter;
1751
1752 vbox2 = gtk_vbox_new(FALSE,0);
1753 gtk_widget_show(vbox2);
1754 gtk_box_pack_start(GTK_BOX(vbox), vbox2, FALSE, FALSE, 0);
1755
1756 // Embed in a vbox; this allows adding optional widgets afterwards
1757
1758 gtk_box_pack_start(GTK_BOX(vbox2), hfw->hf_options->img->fd_struct->filter_dialog, FALSE, FALSE, 0);
1759
1760 hfw->hf_options->img->fd_struct->filter_vbox = vbox2;
1761
1762 // For this one, we must redefine "filter_dialog", which is the dialog
1763 // we show / hide when selecting a new tool in the toolbaox
1764 // (not very elegant... should be improved in the future!)
1765
1766 hfw->hf_options->img->fd_struct->filter_dialog = frame;
1767
1768 // Controls in the main vbox
1769
1770 gtk_box_pack_start (GTK_BOX (vbox), reset_accept_buttons_new (data, &hfw->hf_options->img->filter_accept), FALSE, FALSE, DEF_PAD);
1771
1772 return frame;
1773
1774 }
1775
filter_callb(GtkWidget * wdg,gpointer data)1776 void filter_callb(GtkWidget *wdg, gpointer data) {
1777 hf_wrapper_struct *hfw;
1778 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
1779 if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wdg))) {
1780 hf_commit_or_reset (hfw->hf_options);
1781 return;
1782 }
1783
1784 if (!hfw->hf_options->img->fd_struct) {
1785 gtk_container_add(GTK_CONTAINER(hfw->hf_options->img->img_dialog),
1786 img_filter_dialog_new(data));
1787 }
1788 // Let this dialog become the current filter (for callbacks in hf_filters.c)
1789 hfw->hf_options->fd_struct = hfw->hf_options->img->fd_struct ;
1790 if (hfw->hf_options->img->current_subdialog)
1791 gtk_widget_hide(hfw->hf_options->img->current_subdialog);
1792 hfw->hf_options->img->current_subdialog = hfw->hf_options->img->fd_struct->filter_dialog;
1793 hfw->hf_options->img->set_fn = (gpointer) set_f_defaults;
1794 hfw->hf_options->img->accept_wdg = hfw->hf_options->img->filter_accept;
1795 gtk_widget_show(hfw->hf_options->img->current_subdialog);
1796 }
1797
1798 /************************* NOISE *************************/
1799
set_noise_defaults(img_dialog_struct * img)1800 void set_noise_defaults(img_dialog_struct *img) {
1801
1802 gtk_adjustment_set_value(
1803 GTK_ADJUSTMENT(img->adj_noise_level), 0);
1804 }
1805
calc_noise(hf_wrapper_struct * hfw)1806 void calc_noise (hf_wrapper_struct *hfw) {
1807 // See comments in calc_shape_filter
1808 if (hfw->if_calculated)
1809 return;
1810
1811 if (hfw->hf_struct->tmp_buf)
1812 memcpy(hfw->hf_struct->hf_buf, hfw->hf_struct->tmp_buf,
1813 hfw->hf_struct->max_x*hfw->hf_struct->max_y*sizeof(hf_type));
1814 else
1815 hf_backup(hfw->hf_struct);
1816
1817 if (!hfw->hf_options->img->noise_to_apply)
1818 hfw->hf_options->img->noise_to_apply = hf_new(hfw->hf_struct->max_x);
1819 ((hf_wrapper_struct *)hfw->hf_options->img->hf_noise)->if_calculated = FALSE;
1820
1821 subdiv2(hfw->hf_options->img->noise_to_apply,
1822 ((hf_wrapper_struct *)hfw->hf_options->img->hf_noise)->hf_options->subdiv2_options);
1823 hf_merge(hfw->hf_options->img->noise_to_apply, hfw->hf_struct,
1824 hfw->hf_struct->max_x>>1,
1825 hfw->hf_struct->max_y>>1,
1826 hfw->hf_options->img->noise_merge,
1827 TRUE,
1828 ((gfloat) hfw->hf_options->img->noise_level) / 100.0,
1829 FALSE);
1830 begin_pending_record(hfw,"Noise", accept_fn, reset_fn);
1831 gtk_widget_set_sensitive(GTK_WIDGET(hfw->hf_options->img->noise_accept),TRUE);
1832 (*hfw->if_modified) = TRUE;
1833 hfw->if_calculated = TRUE;
1834 draw_hf(hfw);
1835 }
1836
noise_level_upd(GtkWidget * wdg,gpointer data)1837 void noise_level_upd (GtkWidget *wdg, gpointer data) {
1838 hf_wrapper_struct *hfw;
1839 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
1840 if (hfw->hf_options->img->noise_level == (gint) GTK_ADJUSTMENT(wdg)->value)
1841 return;
1842 hfw->hf_options->img->noise_level = (gint) GTK_ADJUSTMENT(wdg)->value;
1843 hfw->if_calculated = FALSE;
1844 // calc_noise(hfw);
1845 }
1846
add_callb(GtkWidget * wdg,gpointer data)1847 static void add_callb (GtkWidget *wdg, gpointer data) {
1848 hf_wrapper_struct *hfw;
1849 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
1850 if (hfw->hf_options->img->noise_merge == ADD)
1851 return;
1852 hfw->hf_options->img->noise_merge = ADD;
1853 hfw->if_calculated = FALSE;
1854 calc_noise(hfw);
1855 }
1856
subtract_callb(GtkWidget * wdg,gpointer data)1857 static void subtract_callb (GtkWidget *wdg, gpointer data) {
1858 hf_wrapper_struct *hfw;
1859 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
1860 if (hfw->hf_options->img->noise_merge == SUBTRACT)
1861 return;
1862 hfw->hf_options->img->noise_merge = SUBTRACT;
1863 hfw->if_calculated = FALSE;
1864 calc_noise(hfw);
1865 }
multiply_callb(GtkWidget * wdg,gpointer data)1866 static void multiply_callb (GtkWidget *wdg, gpointer data) {
1867 hf_wrapper_struct *hfw;
1868 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
1869 if (hfw->hf_options->img->noise_merge == MULTIPLY)
1870 return;
1871 hfw->hf_options->img->noise_merge = MULTIPLY;
1872 hfw->if_calculated = FALSE;
1873 calc_noise(hfw);
1874 }
1875
apply_noise(gpointer data)1876 static void apply_noise (gpointer data) {
1877 hf_wrapper_struct *hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
1878 hfw->if_calculated = FALSE;
1879 calc_noise(hfw);
1880 }
1881
apply_noise_callb(GtkWidget * wdg,gpointer data)1882 static void apply_noise_callb (GtkWidget *wdg, gpointer data) {
1883 apply_noise (data);
1884 }
apply_noise_event(GtkWidget * wdg,GdkEventButton * event,gpointer data)1885 static gint apply_noise_event (GtkWidget *wdg,GdkEventButton *event, gpointer data) {
1886 apply_noise (data);
1887 return FALSE;
1888 }
1889
noise_dialog_new(gpointer data)1890 GtkWidget *noise_dialog_new (gpointer data) {
1891
1892 GtkWidget *vbox, *hbox, *frame, *button, *vbox2, *merge_toolbar, *wdg, *scale;
1893 static gboolean dummy_flag;
1894 hf_options_struct *hfo;
1895 gint frq[12] = {50,50,50,0,0,0,0,0,0,0,0,0};
1896 hf_wrapper_struct *hfw;
1897 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
1898
1899 frame = options_frame_new_pad("Noise",0);
1900
1901 vbox = gtk_vbox_new(FALSE,0);
1902 gtk_widget_show(GTK_WIDGET(vbox));
1903
1904 hbox = gtk_hbox_new(FALSE,DEF_PAD);
1905 gtk_widget_show(GTK_WIDGET(hbox));
1906
1907 define_label_in_box("%", hbox, FALSE,TRUE, DEF_PAD);
1908 hfw->hf_options->img->adj_noise_level = gtk_adjustment_new (0, 0.0, 100.0, 1.0, 1.0, 0.0);
1909 scale = define_scale_in_box(hfw->hf_options->img->adj_noise_level,hbox,0,DEF_PAD);
1910 g_signal_connect (G_OBJECT (scale), "button_release_event", GTK_SIGNAL_FUNC (apply_noise_event), data);
1911
1912 // Merge mode
1913
1914 define_label_in_box("Merge", hbox, FALSE, FALSE, DEF_PAD *0.5);
1915 merge_toolbar = gtk_toolbar_new ();
1916 gtk_toolbar_set_orientation(GTK_TOOLBAR(merge_toolbar),GTK_ORIENTATION_HORIZONTAL);
1917 gtk_toolbar_set_style(GTK_TOOLBAR(merge_toolbar),GTK_TOOLBAR_TEXT);
1918 gtk_widget_show(GTK_WIDGET(merge_toolbar));
1919 wdg = gtk_toolbar_append_element(GTK_TOOLBAR(merge_toolbar),
1920 GTK_TOOLBAR_CHILD_RADIOBUTTON,NULL,"+",
1921 _("Add"),NULL,NULL,GTK_SIGNAL_FUNC(add_callb),data);
1922 wdg = gtk_toolbar_append_element(GTK_TOOLBAR(merge_toolbar),
1923 GTK_TOOLBAR_CHILD_RADIOBUTTON,wdg,"-",
1924 _("Subtract"),NULL,NULL,GTK_SIGNAL_FUNC(subtract_callb),data);
1925 gtk_toolbar_append_element(GTK_TOOLBAR(merge_toolbar),
1926 GTK_TOOLBAR_CHILD_RADIOBUTTON,wdg,"x",
1927 _("Multiply"),NULL,NULL,GTK_SIGNAL_FUNC(multiply_callb),data);
1928
1929 gtk_box_pack_start(GTK_BOX(hbox),merge_toolbar, TRUE, TRUE, DEF_PAD *0.5);
1930
1931 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, DEF_PAD);
1932
1933 gtk_signal_connect (GTK_OBJECT (hfw->hf_options->img->adj_noise_level), "value_changed",
1934 GTK_SIGNAL_FUNC (noise_level_upd), data);
1935
1936 gtk_container_add(GTK_CONTAINER(frame), vbox);
1937
1938 vbox2 = gtk_vbox_new(FALSE,DEF_PAD);
1939 gtk_widget_show(GTK_WIDGET(vbox2));
1940
1941 gtk_container_add(GTK_CONTAINER(vbox), vbox2);
1942
1943 // We create the HF containing the noise, and the preview area
1944 hfo = hf_options_dialog_new(hfw->hf_options->tools_window,
1945 vbox,
1946 hfw->hf_options->tooltips,
1947 NULL,
1948 &hfw->hf_options->img->hf_noise,
1949 hfw->hf_options->stack,
1950 hfw->hf_options->doc_type,
1951 hfw->hf_options->all_docs,
1952 hfw->hf_options->get_doc_list_from_type);
1953 hfo->hf_size = MAX_NOISE_PREVIEW;
1954
1955 hfw->hf_options->img->hf_noise = hf_wrapper_new(NULL,NULL,vbox2, vbox, hfo,
1956 &dummy_flag, &dummy_flag, NULL, NULL, NULL, NULL, HFNOISE);
1957
1958 // Shared data:
1959 ((hf_wrapper_struct *)hfw->hf_options->img->hf_noise)->hf_options->dist_matrix = hfw->hf_options->dist_matrix;
1960
1961 // Initialize the current HF compute function:
1962 ((hf_wrapper_struct *)hfw->hf_options->img->hf_noise)->hf_options->subdiv2_options =
1963 subdiv2_opt_new(frq, 12);
1964 ((hf_wrapper_struct *)hfw->hf_options->img->hf_noise)->hf_options->subdiv2_options->distribution = 10;
1965 ((hf_wrapper_struct *)hfw->hf_options->img->hf_noise)->hf_options->current_options =
1966 ((hf_wrapper_struct *)hfw->hf_options->img->hf_noise)->hf_options->subdiv2_options;
1967 ((hf_wrapper_struct *)hfw->hf_options->img->hf_noise)->hf_options->subdiv2_dialog =
1968 subdiv2_dialog_new(((hf_wrapper_struct *)hfw->hf_options->img->hf_noise)->hf_options);
1969 ((hf_wrapper_struct *)hfw->hf_options->img->hf_noise)->hf_options->current_dialog =
1970 ((hf_wrapper_struct *)hfw->hf_options->img->hf_noise)->hf_options->subdiv2_dialog;
1971
1972 ((hf_wrapper_struct *)hfw->hf_options->img->hf_noise)->hf_options->current_calculation = (gpointer) subdiv2;
1973
1974
1975 set_dependent_process (((hf_wrapper_struct *)hfw->hf_options->img->hf_noise), apply_noise, data);
1976
1977 // Hide the filter subdialog (not relevant here):
1978 gtk_widget_hide( ((hf_wrapper_struct *)hfw->hf_options->img->hf_noise)->hf_options->creation_fd_struct->filter_dialog);
1979
1980 gtk_container_add(GTK_CONTAINER(vbox),
1981 ((hf_wrapper_struct *)hfw->hf_options->img->hf_noise)->hf_options->subdiv2_dialog);
1982
1983 gtk_box_pack_start (GTK_BOX (vbox), reset_accept_buttons_new (data, &hfw->hf_options->img->noise_accept), FALSE, FALSE, DEF_PAD);
1984
1985 return frame;
1986 }
1987
noise_callb(GtkWidget * wdg,gpointer data)1988 void noise_callb(GtkWidget *wdg, gpointer data) {
1989 // Adding noise == merging a subdivision HF with the current HF
1990 // The subdivision HF contains only higher frequencies (lower heights)
1991 hf_wrapper_struct *hfw;
1992 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
1993 if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wdg))) {
1994 hf_commit_or_reset (hfw->hf_options);
1995 return;
1996 }
1997 if (!hfw->hf_options->img->noise_dialog) {
1998 hfw->hf_options->img->noise_dialog = noise_dialog_new(data);
1999 gtk_container_add(GTK_CONTAINER(hfw->hf_options->img->img_dialog),
2000 hfw->hf_options->img->noise_dialog );
2001 }
2002 if (hfw->hf_options->img->current_subdialog)
2003 gtk_widget_hide(hfw->hf_options->img->current_subdialog);
2004 hfw->hf_options->img->current_subdialog = hfw->hf_options->img->noise_dialog;
2005 hfw->hf_options->img->set_fn = (gpointer) set_noise_defaults;
2006 hfw->hf_options->img->accept_wdg = hfw->hf_options->img->noise_accept;
2007 gtk_widget_show(hfw->hf_options->img->current_subdialog);
2008 }
2009
2010
2011 /************************* MERGE *************************/
2012
compute_merge_preview(hf_struct_type ** hf_ptr,unsigned char * buf8,gint width,gint height)2013 static void compute_merge_preview (hf_struct_type **hf_ptr, unsigned char *buf8, gint width, gint height) {
2014 // A function with a generic prototype for calculating the preview buffer
2015 // Almost the same as hf_16_to_8
2016 // width == height, and width must be a power of 2
2017 // buf8 is already allocated
2018 gint i, j, display_scale;
2019
2020 hf_struct_type *hf = (hf_struct_type *) *hf_ptr;
2021
2022 display_scale = log2i(hf->max_x) - log2i(width) ;
2023
2024 // printf("W -> MAX: %d x %d; display_scale = %d\n",width, hf->max_x, display_scale);
2025 if (display_scale)
2026 for (i = 0; i < width; i++)
2027 for (j = 0; j < height; j++) {
2028 *(buf8 + j*width + i) =
2029 *(hf->hf_buf + (LEFT_SHIFT(i,display_scale)) +
2030 (LEFT_SHIFT(j,display_scale))*hf->max_x) >> 8;
2031 }
2032 else
2033 for (i = 0; i<hf->max_x*hf->max_y; i++)
2034 *(buf8 + i) = *(hf->hf_buf + i) >> 8;
2035 }
2036
set_merge_defaults(img_dialog_struct * img)2037 void set_merge_defaults(img_dialog_struct *img) {
2038 // This function is typically executed when clicking the "accept" button,
2039 // so we must adjust the "mix" scale so that the last result is kept
2040 gtk_adjustment_set_value(
2041 GTK_ADJUSTMENT(img->merge->adj_mix), -100);
2042 gtk_adjustment_set_value(
2043 GTK_ADJUSTMENT(img->merge->adj_source_offset), 0);
2044 gtk_adjustment_set_value(
2045 GTK_ADJUSTMENT(img->merge->adj_result_offset), 0);
2046 }
2047
calc_merge(merge_struct * merge)2048 void calc_merge (merge_struct *merge) {
2049 gint dif;
2050 hf_wrapper_struct *hfw;
2051 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) merge->data;
2052 if (!hfw->hf_struct->tmp_buf) {
2053 hf_backup(hfw->hf_struct);
2054 }
2055 if (hfw->if_calculated)
2056 return;
2057
2058 // printf("*************** MERGE of %d (->%d) ***************\n",hfw->hf_struct, hfw->hf_struct->hf_buf);
2059
2060 // We scale up or down the hf to merge with the current one
2061 // We cannot put this code in the select document to merge callback,
2062 // because we have to redo it when the current document is swapped
2063 // hf_to_merge_scaled has been initialized to its default value in select_merge_callb
2064 if (hfw->hf_options->img->hf_to_merge->max_x != hfw->hf_struct->max_x) {
2065 dif = log2i(hfw->hf_struct->max_x) - log2i(hfw->hf_options->img->hf_to_merge->max_x);
2066 if (hfw->hf_options->img->hf_to_merge_scaled)
2067 hf_free( hfw->hf_options->img->hf_to_merge_scaled);
2068 hfw->hf_options->img->hf_to_merge_scaled =
2069 hf_scale(hfw->hf_options->img->hf_to_merge, dif);
2070 hfw->hf_options->img->merge_scaled = TRUE;
2071 }
2072 set_merge_buffers(merge,
2073 hfw->hf_struct->tmp_buf,
2074 hfw->hf_options->img->hf_to_merge_scaled->hf_buf,
2075 hfw->hf_struct->hf_buf,
2076 hfw->hf_struct->max_x,
2077 hfw->hf_struct->max_y) ;
2078 simple_merge (merge);
2079 begin_pending_record(hfw,"Merge",accept_fn, reset_fn);
2080 gtk_widget_set_sensitive(GTK_WIDGET(hfw->hf_options->img->merge_accept),TRUE);
2081 (*hfw->if_modified) = TRUE;
2082 hfw->if_calculated = TRUE;
2083 draw_hf(hfw);
2084 }
2085
select_merge_callb(GtkWidget * wdg,gpointer data)2086 void select_merge_callb (GtkWidget *wdg, gpointer data) {
2087 gchar *lbl;
2088 GList *node;
2089 hf_wrapper_struct *hfw;
2090 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
2091 gtk_label_get(GTK_LABEL(GTK_BIN(wdg)->child),&lbl);
2092 // Find the HF address from its name:
2093 hfw->hf_options->img->hf_to_merge = NULL;
2094 for (node = hfw->hf_options->doc_list ; node; node = node->next) {
2095 if (!strcmp(lbl,*((hf_wrapper_struct *)node->data)->filename)) {
2096 hfw->hf_options->img->hf_to_merge =
2097 (hf_struct_type *) ((hf_wrapper_struct *) node->data)->hf_struct;
2098 break;
2099 }
2100 }
2101
2102 // We initialize the hf scaled, as a default (it would be scaled in calc_merge, if required)
2103 if (hfw->hf_options->img->hf_to_merge_scaled)
2104 hf_free(hfw->hf_options->img->hf_to_merge_scaled);
2105 hfw->hf_options->img->hf_to_merge_scaled = hf_copy_new(hfw->hf_options->img->hf_to_merge,FALSE);
2106 hfw->hf_options->img->merge_scaled = FALSE;
2107
2108 hfw->if_calculated = FALSE;
2109 calc_merge(hfw->hf_options->img->merge->content);
2110 draw_area(hfw->hf_options->img->merge_preview);
2111 }
2112
simple_merge_dialog_new(gpointer data)2113 GtkWidget *simple_merge_dialog_new(gpointer data) {
2114 GtkWidget *vbox, *vbox2, *frame, *listbox;
2115 hf_wrapper_struct *hfw;
2116 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
2117
2118 frame = options_frame_new("Merge");
2119
2120 vbox = gtk_vbox_new(FALSE,DEF_PAD);
2121 gtk_widget_show(GTK_WIDGET(vbox));
2122
2123 hfw->hf_options->img->merging_image_frame = frame_new ("Merging image selection", DEF_PAD*0.5);
2124 gtk_box_pack_start(GTK_BOX(vbox), hfw->hf_options->img->merging_image_frame, FALSE,FALSE, DEF_PAD*0.5);
2125
2126 listbox = gtk_vbox_new(FALSE,DEF_PAD);
2127 gtk_widget_show(GTK_WIDGET(listbox));
2128 gtk_box_pack_start(GTK_BOX(vbox), listbox, FALSE,FALSE, DEF_PAD*0.5);
2129
2130 hfw->hf_options->img->merge_listbox = img_listbox_new(listbox);
2131 refresh_img_listbox(hfw->hf_options->img->merge_listbox, data, select_merge_callb);
2132
2133 // VBOX2 will contain the preview image
2134 vbox2 = gtk_vbox_new(FALSE,DEF_PAD);
2135 gtk_widget_show(GTK_WIDGET(vbox2));
2136
2137 gtk_container_add(GTK_CONTAINER(vbox), vbox2);
2138
2139 hfw->hf_options->img->merge = merge_dialog_struct_new (merge_struct_new(data, (gpointer) draw_hf_ptr));
2140 gtk_box_pack_start(GTK_BOX(vbox),
2141 merge_dialog_new (hfw->hf_options->img->merge, FALSE,
2142 hfw->hf_options->tools_window,
2143 _("Parameters"), _("Current"), _("Selected"), NULL),
2144 FALSE, FALSE, DEF_PAD * 0.5);
2145
2146 gtk_box_pack_start (GTK_BOX (vbox), reset_accept_buttons_new (data, &hfw->hf_options->img->merge_accept), FALSE, FALSE, DEF_PAD);
2147
2148 // We initialize the merging HF with the current HF for avoiding seg faults
2149 // when the user executes the merge without choosing a HF
2150 hfw->hf_options->img->hf_to_merge = hfw->hf_struct;
2151 hfw->hf_options->img->hf_to_merge_scaled = hf_copy_new(hfw->hf_struct, FALSE);
2152 hfw->hf_options->img->merge_scaled = FALSE;
2153
2154 hfw->hf_options->img->merge_preview =
2155 view_struct_new(MAX_NOISE_PREVIEW,MAX_NOISE_PREVIEW,(gpointer) compute_merge_preview,(gpointer) &hfw->hf_options->img->hf_to_merge);
2156
2157 gtk_box_pack_start(GTK_BOX(vbox2),
2158 align_widget(hfw->hf_options->img->merge_preview->area,0.5,0.5),
2159 TRUE, TRUE, DEF_PAD *0.5);
2160
2161 gtk_container_add(GTK_CONTAINER(frame), vbox);
2162
2163 draw_area (hfw->hf_options->img->merge_preview);
2164 return frame;
2165 }
2166
merge_callb(GtkWidget * wdg,gpointer data)2167 void merge_callb(GtkWidget *wdg, gpointer data) {
2168 hf_wrapper_struct *hfw;
2169 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
2170 if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wdg))) {
2171 // When we change options, we commit last changes by backing up
2172 // the current buffer into the temp buffer
2173 hf_commit_or_reset (hfw->hf_options);
2174 return;
2175 }
2176 if (!hfw->hf_options->img->merge_dialog) {
2177 hfw->hf_options->img->merge_dialog = simple_merge_dialog_new(data);
2178 gtk_container_add(GTK_CONTAINER(hfw->hf_options->img->img_dialog),
2179 hfw->hf_options->img->merge_dialog );
2180 }
2181 else
2182 // refresh_img_listbox from hf_filters_dialog.c
2183 refresh_img_listbox(hfw->hf_options->img->merge_listbox, data, select_merge_callb);
2184
2185 if (hfw->hf_options->img->current_subdialog)
2186 gtk_widget_hide(hfw->hf_options->img->current_subdialog);
2187 hfw->hf_options->img->current_subdialog = hfw->hf_options->img->merge_dialog;
2188 hfw->hf_options->img->set_fn = (gpointer) set_merge_defaults;
2189 hfw->hf_options->img->accept_wdg = hfw->hf_options->img->merge_accept ;
2190 set_merge_defaults(hfw->hf_options->img);
2191 gtk_widget_show(hfw->hf_options->img->current_subdialog);
2192 }
2193
2194
2195 /************************* MATHEMATICAL FUNCTIONS *************************/
2196
apply_math_fn(hf_wrapper_struct * hfw)2197 void apply_math_fn (hf_wrapper_struct *hfw) {
2198 // gint t1;
2199 if (!hfw->hf_struct->tmp_buf)
2200 hf_backup(hfw->hf_struct);
2201 // t1 = clock();
2202 hf_math_fn (hfw->hf_struct,
2203 hfw->hf_options->img->math_fn,
2204 hfw->hf_options->img->math_fn_param );
2205 // printf("TEMPS D'APPLICATION DE LA FONCTION: %d\n",clock() - t1);
2206 begin_pending_record(hfw,"Mathematical transformations", accept_fn, reset_fn);
2207 gtk_widget_set_sensitive(GTK_WIDGET(hfw->hf_options->img->math_fn_accept),TRUE);
2208 (*hfw->if_modified) = TRUE;
2209 hfw->if_calculated = TRUE;
2210 }
2211
apply_math_fn_callb(GtkWidget * wdg,GdkEventButton * event,gpointer data)2212 static gint apply_math_fn_callb (GtkWidget *wdg, GdkEventButton *event, gpointer data) {
2213 hf_wrapper_struct *hfw;
2214 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
2215 // if (hfw->if_calculated)
2216 // return;
2217 apply_math_fn(hfw);
2218 draw_hf(hfw);
2219 return FALSE;
2220 }
2221
apply_math_fn_callb2(GtkWidget * wdg,gpointer data)2222 static gint apply_math_fn_callb2 (GtkWidget *wdg, gpointer data) {
2223 hf_wrapper_struct *hfw;
2224 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
2225 if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wdg)))
2226 return;
2227 // if (hfw->if_calculated)
2228 // return;
2229 apply_math_fn(hfw);
2230 draw_hf(hfw);
2231 return FALSE;
2232 }
2233
2234
set_math_fn_defaults(img_dialog_struct * img)2235 void set_math_fn_defaults(img_dialog_struct *img) {
2236 gtk_adjustment_set_value(
2237 GTK_ADJUSTMENT(img->adj_math_fn), 1.0);
2238 }
2239
repeat_math_fn_callb(GtkWidget * wdg,gpointer data)2240 void repeat_math_fn_callb (GtkWidget *wdg, gpointer data) {
2241 hf_wrapper_struct *hfw;
2242 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
2243 hf_backup(hfw->hf_struct);
2244 hfw->if_calculated = FALSE;
2245 apply_math_fn(hfw);
2246 draw_hf(hfw);
2247 }
2248
math_fn_param_upd(GtkWidget * wdg,gpointer data)2249 void math_fn_param_upd (GtkWidget *wdg, gpointer data) {
2250 hf_wrapper_struct *hfw;
2251 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
2252 if (hfw->hf_options->img->math_fn_param == (gdouble) GTK_ADJUSTMENT(wdg)->value)
2253 return;
2254 hfw->hf_options->img->math_fn_param = (gdouble) GTK_ADJUSTMENT(wdg)->value;
2255 hfw->if_calculated = FALSE;
2256 }
2257
set_power_fn(GtkWidget * wdg,gpointer data)2258 void set_power_fn (GtkWidget *wdg, gpointer data) {
2259 gint *fn;
2260 if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wdg)))
2261 return;
2262 fn = (gint *) data;
2263 (*fn) = POWER_OP;
2264 }
set_base_fn(GtkWidget * wdg,gpointer data)2265 void set_base_fn (GtkWidget *wdg, gpointer data) {
2266 gint *fn;
2267 if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wdg)))
2268 return;
2269 fn = (gint *) data;
2270 (*fn) = BASE_OP;
2271 }
set_log_fn(GtkWidget * wdg,gpointer data)2272 void set_log_fn (GtkWidget *wdg, gpointer data) {
2273 gint *fn;
2274 if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wdg)))
2275 return;
2276 fn = (gint *) data;
2277 (*fn) = LOG_OP;
2278 }
set_sine_fn(GtkWidget * wdg,gpointer data)2279 void set_sine_fn (GtkWidget *wdg, gpointer data) {
2280 gint *fn;
2281 if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wdg)))
2282 return;
2283 fn = (gint *) data;
2284 (*fn) = SINE_OP;
2285 }
math_fn_dialog_new(gpointer data)2286 GtkWidget *math_fn_dialog_new (gpointer data) {
2287
2288 GtkWidget *vbox, *hbox, *frame, *scale, *button;
2289 GSList *group = NULL;
2290 hf_wrapper_struct *hfw;
2291 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
2292
2293 frame = options_frame_new("Mathematical transformations");
2294
2295 vbox = gtk_vbox_new(FALSE,DEF_PAD);
2296 gtk_widget_show(GTK_WIDGET(vbox));
2297
2298 // Radio buttons presenting the functions choice
2299
2300 button = define_radio_button_in_box_with_data (vbox, &group, "Power (height, parameter)",
2301 set_power_fn, &hfw->hf_options->img->math_fn,
2302 (hfw->hf_options->img->math_fn==POWER_OP)) ;
2303 g_signal_connect (G_OBJECT (button), "toggled",
2304 GTK_SIGNAL_FUNC(apply_math_fn_callb2), (gpointer) data);
2305
2306 button = define_radio_button_in_box_with_data (vbox, &group, "Power (parameter, height / max)",
2307 set_base_fn, &hfw->hf_options->img->math_fn,
2308 (hfw->hf_options->img->math_fn==BASE_OP)) ;
2309 g_signal_connect (G_OBJECT (button), "toggled",
2310 GTK_SIGNAL_FUNC(apply_math_fn_callb2), (gpointer) data);
2311
2312 button = define_radio_button_in_box_with_data (vbox, &group, "Log (height)",
2313 set_log_fn, &hfw->hf_options->img->math_fn,
2314 (hfw->hf_options->img->math_fn==LOG_OP)) ;
2315 g_signal_connect (G_OBJECT (button), "toggled",
2316 GTK_SIGNAL_FUNC(apply_math_fn_callb2), (gpointer) data);
2317
2318 button = define_radio_button_in_box_with_data (vbox, &group, "Sine",
2319 set_sine_fn, &hfw->hf_options->img->math_fn,
2320 (hfw->hf_options->img->math_fn==SINE_OP)) ;
2321 g_signal_connect (G_OBJECT (button), "toggled",
2322 GTK_SIGNAL_FUNC(apply_math_fn_callb2), (gpointer) data);
2323
2324 hbox = gtk_hbox_new(FALSE,DEF_PAD);
2325 gtk_widget_show(GTK_WIDGET(hbox));
2326
2327 define_label_in_box("Parameter", hbox, FALSE,TRUE, DEF_PAD);
2328 hfw->hf_options->img->adj_math_fn =
2329 gtk_adjustment_new (hfw->hf_options->img->math_fn_param, 0.0, 10.0, 0.01, 0.01, 0.001);
2330 scale = define_scale_in_box(hfw->hf_options->img->adj_math_fn,hbox,2,DEF_PAD);
2331
2332 gtk_signal_connect (GTK_OBJECT (hfw->hf_options->img->adj_math_fn), "value_changed", GTK_SIGNAL_FUNC (math_fn_param_upd), data);
2333
2334 g_signal_connect (G_OBJECT (scale), "button_release_event",
2335 GTK_SIGNAL_FUNC(apply_math_fn_callb), (gpointer) data);
2336
2337 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
2338
2339 button = gtk_button_new_with_label (_("Repeat"));
2340 gtk_signal_connect (GTK_OBJECT (button), "clicked",
2341 (GtkSignalFunc) repeat_math_fn_callb, data);
2342 gtk_widget_show(button);
2343
2344 gtk_box_pack_start (GTK_BOX (vbox), align_widget(button, 0.5, 0.5), FALSE, FALSE, DEF_PAD);
2345
2346 gtk_box_pack_start (GTK_BOX (vbox), reset_accept_buttons_new (data, &hfw->hf_options->img->math_fn_accept), FALSE, FALSE, DEF_PAD);
2347
2348 gtk_container_add(GTK_CONTAINER(frame), vbox);
2349
2350 return frame;
2351 }
2352
math_fn_callb(GtkWidget * wdg,gpointer data)2353 void math_fn_callb(GtkWidget *wdg, gpointer data) {
2354 hf_wrapper_struct *hfw;
2355 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
2356 if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wdg))) {
2357 hf_commit_or_reset (hfw->hf_options);
2358 return;
2359 }
2360 if (!hfw->hf_options->img->math_fn_dialog) {
2361 hfw->hf_options->img->math_fn_dialog = math_fn_dialog_new(data);
2362 gtk_container_add(GTK_CONTAINER(hfw->hf_options->img->img_dialog),
2363 hfw->hf_options->img->math_fn_dialog );
2364 }
2365 if (hfw->hf_options->img->current_subdialog)
2366 gtk_widget_hide(hfw->hf_options->img->current_subdialog);
2367 hfw->hf_options->img->current_subdialog = hfw->hf_options->img->math_fn_dialog;
2368 hfw->hf_options->img->set_fn = (gpointer) set_math_fn_defaults;
2369 hfw->hf_options->img->accept_wdg = hfw->hf_options->img->math_fn_accept;
2370 gtk_widget_show(hfw->hf_options->img->current_subdialog);
2371 }
2372
2373 /************************* HEXAGONS (GIANT CAUSEWAY) *************************/
2374
hexagon_remove_tiling(hf_wrapper_struct * hfw)2375 void hexagon_remove_tiling (hf_wrapper_struct *hfw) {
2376 if (hfw->tiling_ptr && (hfw->hf_options->img->hexagon_radius>3)) // Do nothing if nothing has been calculated
2377 {
2378 *hfw->tiling_ptr = FALSE;
2379 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(hfw->tiling_wdg), *hfw->tiling_ptr);
2380 }
2381 }
2382
accept_hexagon_fn(hf_wrapper_struct * hfw)2383 void accept_hexagon_fn (hf_wrapper_struct *hfw) {
2384 hexagon_remove_tiling (hfw);
2385 accept_fn(hfw);
2386 }
2387
set_hexagon_defaults(img_dialog_struct * img)2388 void set_hexagon_defaults(img_dialog_struct *img) {
2389 gtk_adjustment_set_value(
2390 GTK_ADJUSTMENT(img->adj_hexagon_radius), 2);
2391 gtk_adjustment_set_value(
2392 GTK_ADJUSTMENT(img->adj_hexagon_border), 0);
2393 gtk_adjustment_set_value(
2394 GTK_ADJUSTMENT(img->hexagon_merge->adj_mix), 100);
2395 }
2396
calc_hexagon(hf_wrapper_struct * hfw)2397 void calc_hexagon (hf_wrapper_struct *hfw) {
2398 if (hfw->if_calculated)
2399 return;
2400 if (hfw->hf_options->img->hexagon_smooth_radius)
2401 if (hfw->hf_struct->max_x>hfw->hf_options->dist_matrix->hf_size)
2402 dist_matrix_init(hfw->hf_options->dist_matrix, hfw->hf_struct->max_x);
2403 hf_hexagon(hfw->hf_struct,
2404 hfw->hf_options->img->hexagon_radius,
2405 hfw->hf_options->img->hexagon_border,
2406 hfw->hf_options->img->hexagon_smooth_radius,
2407 hfw->hf_options->dist_matrix,
2408 hfw->hf_options->img->hexagon_apply_postprocess,
2409 hfw->hf_options->gauss_list);
2410 hfw->hf_options->img->hexagon_apply_postprocess = FALSE;
2411 begin_pending_record(hfw,"Giant Causeway", accept_hexagon_fn, reset_fn);
2412 merge_n_display (hfw, hfw->hf_options->img->hexagon_merge->content);
2413 }
2414
hexagon_radius_upd(GtkWidget * wdg,gpointer data)2415 void hexagon_radius_upd (GtkWidget *wdg, gpointer data) {
2416 // Updates the hexagons radius and displays the HF
2417 hf_wrapper_struct *hfw;
2418 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
2419 if (hfw->hf_options->img->hexagon_radius == (gint) GTK_ADJUSTMENT(wdg)->value)
2420 return;
2421 hfw->hf_options->img->hexagon_radius = (gint) GTK_ADJUSTMENT(wdg)->value;
2422
2423 if (hfw->hf_options->img->hexagon_radius<3) {
2424 reset_callb(wdg,data);
2425 return;
2426 }
2427 hfw->if_calculated = FALSE;
2428 calc_hexagon (hfw);
2429 }
2430
hexagon_border_upd(GtkWidget * wdg,gpointer data)2431 void hexagon_border_upd (GtkWidget *wdg, gpointer data) {
2432 // Updates the hexagons border width and displays the HF
2433 hf_wrapper_struct *hfw;
2434 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
2435 if (hfw->hf_options->img->hexagon_border == (gint) GTK_ADJUSTMENT(wdg)->value)
2436 return;
2437 hfw->hf_options->img->hexagon_border = (gint) GTK_ADJUSTMENT(wdg)->value;
2438 hfw->if_calculated = FALSE;
2439 calc_hexagon (hfw);
2440 }
2441
hexagon_smooth_radius_upd(GtkWidget * wdg,gpointer data)2442 void hexagon_smooth_radius_upd (GtkWidget *wdg, gpointer data) {
2443 hf_wrapper_struct *hfw;
2444 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
2445 if (hfw->hf_options->img->hexagon_smooth_radius == (gint) GTK_ADJUSTMENT(wdg)->value)
2446 return;
2447 hfw->hf_options->img->hexagon_smooth_radius = (gint) GTK_ADJUSTMENT(wdg)->value;
2448 hfw->if_calculated = FALSE;
2449 // calc_hexagon (hfw);
2450 }
2451
hexagon_apply_postprocess_callb(GtkWidget * wdg,gpointer data)2452 void hexagon_apply_postprocess_callb (GtkWidget *wdg, gpointer data) {
2453 hf_wrapper_struct *hfw;
2454 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
2455 hfw->hf_options->img->hexagon_apply_postprocess = TRUE;
2456 hfw->if_calculated = FALSE;
2457 calc_hexagon (hfw);
2458 }
2459
hexagon_remove_tiling_callb(GtkWidget * wdg,gpointer data)2460 void hexagon_remove_tiling_callb (GtkWidget *wdg, gpointer data) {
2461 // The hexagon transform does not preserve the tiling capability
2462 hf_wrapper_struct *hfw;
2463 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
2464 hexagon_remove_tiling (hfw);
2465 }
2466
hexagon_dialog_new(gpointer data)2467 GtkWidget *hexagon_dialog_new(gpointer data) {
2468 GtkWidget *vbox, *vbox2, *vbox3, *hbox, *frame, *frame2, *button, *scale;
2469 GtkObject *adj;
2470 hf_wrapper_struct *hfw;
2471 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
2472
2473 frame = options_frame_new("Giant Causeway");
2474
2475 vbox = gtk_vbox_new(FALSE,DEF_PAD); // vbox for all options
2476 gtk_widget_show(vbox);
2477 gtk_container_add(GTK_CONTAINER(frame), vbox);
2478
2479 vbox2 = gtk_vbox_new(FALSE,DEF_PAD); // vbox for quantization
2480 gtk_widget_show(vbox2);
2481
2482 hbox = gtk_hbox_new(FALSE,DEF_PAD);
2483 gtk_widget_show(hbox);
2484 define_label_in_box("Radius", hbox,FALSE, FALSE, DEF_PAD);
2485 // Important: radius must be even, otherwise we get black pixels (rounding problem)
2486 adj = gtk_adjustment_new (hfw->hf_options->img->hexagon_radius, 2, 100, 2, 2, 0.01);
2487 scale = define_scale_in_box(adj, hbox, 0, DEF_PAD);
2488 optimize_on_mouse_click (scale, data);
2489 gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
2490 GTK_SIGNAL_FUNC (hexagon_radius_upd), data);
2491 hfw->hf_options->img->adj_hexagon_radius = adj;
2492
2493 gtk_box_pack_start(GTK_BOX(vbox2),hbox, TRUE, TRUE, DEF_PAD *0.5);
2494
2495 hbox = gtk_hbox_new(FALSE,DEF_PAD);
2496 gtk_widget_show(hbox);
2497 define_label_in_box("Border", hbox,FALSE, FALSE, DEF_PAD);
2498 adj = gtk_adjustment_new (hfw->hf_options->img->hexagon_border, 0, 10, 1, 1, 0.01);
2499 scale = define_scale_in_box(adj, hbox, 0, DEF_PAD);
2500 optimize_on_mouse_click (scale, data);
2501 gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
2502 GTK_SIGNAL_FUNC (hexagon_border_upd), data);
2503 hfw->hf_options->img->adj_hexagon_border = adj;
2504
2505 gtk_box_pack_start(GTK_BOX(vbox2),hbox, TRUE, TRUE, DEF_PAD *0.5);
2506
2507 // Main "quantization" frame
2508
2509 frame2 = frame_new("Quantization",DEF_PAD*0.5);
2510 gtk_container_add(GTK_CONTAINER(frame2), vbox2);
2511 gtk_box_pack_start(GTK_BOX(vbox), frame2, TRUE, TRUE, 0); // the main box
2512
2513 /********************** Post-process subdialogs *************************/
2514
2515 vbox2 = gtk_vbox_new(FALSE,DEF_PAD); // vbox for subdialogs
2516 gtk_widget_show(vbox2);
2517
2518 // Hexagons' smooth
2519
2520 vbox3 = gtk_vbox_new(FALSE,DEF_PAD); // vbox for subdialogs
2521 gtk_widget_show(vbox3);
2522
2523 frame2 = define_frame_with_hiding_arrows ("Smooth", vbox3, hfw->hf_options->tools_window, FALSE);
2524
2525 hbox = gtk_hbox_new(FALSE,DEF_PAD);
2526 gtk_widget_show(hbox);
2527 define_label_in_box("Radius", hbox,FALSE,FALSE, DEF_PAD);
2528 adj = gtk_adjustment_new (hfw->hf_options->img->hexagon_smooth_radius, 0.0, 20.0, 1.0, 1.0, 0.0);
2529 define_scale_in_box(adj, hbox, 0, DEF_PAD);
2530 gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
2531 GTK_SIGNAL_FUNC (hexagon_smooth_radius_upd), data);
2532 hfw->hf_options->img->adj_hexagon_smooth_radius = adj;
2533
2534 gtk_box_pack_start(GTK_BOX(vbox3), hbox, TRUE, TRUE, DEF_PAD*0.5);
2535
2536 /********************** Smooth subdialog end ****************************/
2537
2538 button = gtk_button_new_with_label (_("Apply"));
2539 gtk_signal_connect (GTK_OBJECT (button), "clicked",
2540 (GtkSignalFunc) hexagon_apply_postprocess_callb, data);
2541 gtk_widget_show(button);
2542
2543 gtk_box_pack_start (GTK_BOX (vbox3), align_widget(button,0.5,0.5), FALSE, FALSE, DEF_PAD*0.5);
2544
2545 gtk_box_pack_start(GTK_BOX(vbox2), frame2, TRUE, TRUE, 0);
2546
2547 // Post-process frame
2548
2549 frame2 = define_frame_with_hiding_arrows ("Result post-processing", vbox2, hfw->hf_options->tools_window, TRUE);
2550
2551 gtk_box_pack_start(GTK_BOX(vbox), frame2, TRUE, TRUE, 0); // the main box
2552
2553 /********************** Post-process frame end ****************************/
2554
2555 // Merge
2556
2557 hfw->hf_options->img->hexagon_merge = merge_dialog_struct_new (merge_struct_new(data, (gpointer) draw_hf_ptr));
2558 hfw->hf_options->img->hexagon_merge->content->mix = 100;
2559 frame2 = merge_dialog_new(hfw->hf_options->img->hexagon_merge,
2560 TRUE, hfw->hf_options->tools_window, NULL, NULL, NULL, NULL);
2561 gtk_box_pack_start(GTK_BOX(vbox2), frame2, FALSE, FALSE, 0);
2562 gtk_widget_hide (GTK_WIDGET(hfw->hf_options->img->hexagon_merge->main_box));
2563
2564 // Control buttons
2565
2566 hbox = gtk_hbox_new(FALSE,DEF_PAD);
2567 gtk_widget_show(GTK_WIDGET(hbox));
2568
2569 button = gtk_button_new_with_label(_("Reset"));
2570 gtk_widget_show(GTK_WIDGET(button));
2571 gtk_signal_connect (GTK_OBJECT (button), "clicked",
2572 (GtkSignalFunc) reset_callb, data);
2573 gtk_box_pack_start (GTK_BOX(hbox), button, FALSE, FALSE, DEF_PAD);
2574
2575 button = gtk_button_new_with_label (_("Accept"));
2576 gtk_signal_connect (GTK_OBJECT (button), "clicked",
2577 (GtkSignalFunc) hexagon_remove_tiling_callb, data);
2578 gtk_signal_connect (GTK_OBJECT (button), "clicked",
2579 (GtkSignalFunc) accept_callb, data);
2580 gtk_widget_show(button);
2581 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, DEF_PAD);
2582 hfw->hf_options->img->hexagon_accept = button;
2583
2584 gtk_box_pack_start (GTK_BOX (vbox), align_widget(hbox,0.5,0.5), FALSE, FALSE, DEF_PAD);
2585
2586 return frame;
2587 }
2588
2589
hexagon_callb(GtkWidget * wdg,gpointer data)2590 void hexagon_callb(GtkWidget *wdg, gpointer data) {
2591 hf_wrapper_struct *hfw;
2592 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
2593 if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wdg))) {
2594 hf_commit_or_reset (hfw->hf_options);
2595 return;
2596 }
2597 if (!hfw->hf_options->img->hexagon_dialog) {
2598 hfw->hf_options->img->hexagon_dialog = hexagon_dialog_new(data);
2599 gtk_container_add(GTK_CONTAINER(hfw->hf_options->img->img_dialog),
2600 hfw->hf_options->img->hexagon_dialog );
2601 }
2602 if (hfw->hf_options->img->current_subdialog)
2603 gtk_widget_hide(hfw->hf_options->img->current_subdialog);
2604 hfw->hf_options->img->current_subdialog = hfw->hf_options->img->hexagon_dialog;
2605 hfw->hf_options->img->set_fn = (gpointer) set_hexagon_defaults;
2606 hfw->hf_options->img->accept_wdg = hfw->hf_options->img->hexagon_accept ;
2607 gtk_widget_show(hfw->hf_options->img->current_subdialog);
2608 }
2609
2610 /************************* LIFT_EDGES *************************/
2611
set_lift_edges_defaults(img_dialog_struct * img)2612 void set_lift_edges_defaults(img_dialog_struct *img) {
2613 // printf("SET_LIFT_EDGES_DEFAULTS\n");
2614 img->lift_edges_merge_done = TRUE;
2615 gtk_adjustment_set_value(
2616 GTK_ADJUSTMENT(img->adj_lift_edges_radius), 20);
2617 // gtk_adjustment_set_value(
2618 // GTK_ADJUSTMENT(img->adj_lift_edges_level), 50);
2619 gtk_widget_hide(GTK_WIDGET(img->lift_edges_level_dialog));
2620 }
2621
calc_lift_edges(hf_wrapper_struct * hfw)2622 void calc_lift_edges (hf_wrapper_struct *hfw) {
2623 gint t1;
2624 gboolean wrap;
2625 // printf("CALC_LIFT_EDGES\n");
2626 if (hfw->if_calculated)
2627 return;
2628 if (hfw->hf_struct->max_x>hfw->hf_options->dist_matrix->hf_size)
2629 dist_matrix_init(hfw->hf_options->dist_matrix, hfw->hf_struct->max_x);
2630 t1 = clock();
2631 set_watch_cursor(hfw);
2632 switch (hfw->hf_options->img->smooth_wrap) {
2633 case TILING_AUTO:
2634 wrap = *hfw->tiling_ptr;
2635 break;
2636 case TILING_YES:
2637 wrap = TRUE;
2638 break;
2639 case TILING_NO:
2640 wrap = FALSE;
2641 }
2642
2643 // Steps:
2644 // 1. Decrease the contrast (keeping the "black point")
2645 // 2. Smooth
2646 // 3. Subtract the smooth result from the lower contrast source
2647 // These 3 steps are done in lift_edges
2648 // 4. Add the subtraction result to the original buffer (before lowering contrast)
2649 hf_min_max(hfw->hf_struct);
2650 hf_backup(hfw->hf_struct);
2651 // We need a second temporary buffer for storing the result
2652 // of the smoothing process before the postprocessing (== merge source with result)
2653 if (!hfw->hf_struct->result_buf) {
2654 hfw->hf_struct->result_buf =
2655 (hf_type *)x_malloc(hfw->hf_struct->max_x*hfw->hf_struct->max_y*sizeof(hf_type), "hf_type (result_buf in calc_lift_edges)");
2656 }
2657 lift_edges (hfw->hf_struct->hf_buf,
2658 hfw->hf_struct->result_buf,
2659 hfw->hf_struct->max_x,
2660 hfw->hf_struct->max_y,
2661 hfw->hf_options->img->lift_edges_radius,
2662 hfw->hf_options->dist_matrix,
2663 wrap,
2664 hfw->hf_options->gauss_list,
2665 hfw->hf_options->img->lift_edges_use_black_point);
2666
2667 // At this point,
2668 // tmp_buf == the original buffer
2669 // result_buf == the buffer with the lifted edges
2670 // hf_buf == the output buffer, to display
2671 // swap_buffers(&hfw->hf_struct->hf_buf,
2672 // &hfw->hf_struct->result_buf);
2673
2674 hfw->hf_options->img->lift_edges_merge_done = FALSE;
2675
2676 merge_lift_edges (hfw->hf_struct, hfw->hf_options->img->lift_edges_level);
2677
2678 gtk_widget_show(GTK_WIDGET(hfw->hf_options->img->lift_edges_level_dialog));
2679
2680 // printf("TEMPS DE REL�VEMENT DES BORDS: %d\n",clock() - t1);
2681 begin_pending_record(hfw,"Lift edges", accept_fn, reset_fn);
2682
2683 unset_watch_cursor(hfw);
2684 (*hfw->if_modified) = TRUE;
2685 hfw->if_calculated = TRUE;
2686 gtk_widget_set_sensitive(GTK_WIDGET( hfw->hf_options->img->accept_wdg),TRUE);
2687 draw_hf (hfw);
2688 }
2689
lift_edges_level_upd(GtkWidget * wdg,gpointer data)2690 void lift_edges_level_upd (GtkWidget *wdg, gpointer data) {
2691 hf_wrapper_struct *hfw;
2692 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
2693 // printf("LIFT_EDGES_LEVEL_UPD!\n");
2694 if (hfw->hf_options->img->lift_edges_level == (gint) GTK_ADJUSTMENT(wdg)->value)
2695 return;
2696 hfw->hf_options->img->lift_edges_level = (gint) GTK_ADJUSTMENT(wdg)->value;
2697
2698 if (hfw->hf_options->img->lift_edges_merge_done)
2699 return;
2700
2701 merge_lift_edges (hfw->hf_struct, hfw->hf_options->img->lift_edges_level);
2702
2703 (*hfw->if_modified) = TRUE;
2704 hfw->if_calculated = TRUE;
2705 draw_hf (hfw);
2706 }
2707
apply_lift_edges_callb(GtkWidget * wdg,gpointer data)2708 void apply_lift_edges_callb (GtkWidget *wdg, gpointer data) {
2709 hf_wrapper_struct *hfw;
2710 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
2711 calc_lift_edges(hfw);
2712 }
2713
repeat_lift_edges_callb(GtkWidget * wdg,gpointer data)2714 void repeat_lift_edges_callb (GtkWidget *wdg, gpointer data) {
2715 hf_wrapper_struct *hfw;
2716 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
2717 hf_backup(hfw->hf_struct);
2718 hfw->if_calculated = FALSE;
2719 calc_lift_edges(hfw);
2720 }
2721
lift_edges_dialog_new(gpointer data)2722 GtkWidget *lift_edges_dialog_new(gpointer data) {
2723 GtkWidget *vbox, *hbox, *frame, *wdg;
2724 GtkObject *adj;
2725 hf_wrapper_struct *hfw;
2726 img_dialog_struct *img;
2727 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
2728 img = hfw->hf_options->img;
2729
2730 frame = options_frame_new("Lift edges");
2731
2732 vbox = gtk_vbox_new(FALSE,DEF_PAD);
2733 gtk_widget_show(vbox);
2734
2735 hbox = gtk_hbox_new(FALSE,DEF_PAD);
2736 gtk_widget_show(hbox);
2737
2738 define_label_in_box("Radius",hbox,FALSE, FALSE,DEF_PAD);
2739 adj = gtk_adjustment_new (img->lift_edges_radius, 0, 100, 1, 1, 0.01);
2740 define_scale_in_box(adj,hbox, 0, DEF_PAD);
2741 gtk_signal_connect (GTK_OBJECT (adj), "value_changed", GTK_SIGNAL_FUNC (gint_adj_callb), (gpointer) &img->lift_edges_radius);
2742 gtk_signal_connect (GTK_OBJECT (adj), "value_changed", GTK_SIGNAL_FUNC (gboolean_set_false), (gpointer) &hfw->if_calculated);
2743 img->adj_lift_edges_radius = adj;
2744 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
2745
2746 hbox = gtk_hbox_new(FALSE,DEF_PAD);
2747 define_label_in_box("Level",hbox,FALSE, FALSE,DEF_PAD);
2748 adj = gtk_adjustment_new (img->lift_edges_level, 0, 100, 1, 1, 0.01);
2749 define_scale_in_box(adj,hbox, 0, DEF_PAD);
2750 gtk_signal_connect (GTK_OBJECT (adj), "value_changed", GTK_SIGNAL_FUNC (lift_edges_level_upd), data);
2751 img->adj_lift_edges_level = adj;
2752 img->lift_edges_level_dialog = hbox;
2753 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
2754
2755 hbox = gtk_hbox_new(FALSE,DEF_PAD);
2756 gtk_widget_show(hbox);
2757
2758 wdg = define_check_button_in_box ("Use a threshold for black", hbox, 0, 0, 0);
2759 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (wdg), img->lift_edges_use_black_point);
2760 gtk_signal_connect (GTK_OBJECT(wdg), "toggled",
2761 GTK_SIGNAL_FUNC(toggle_check_button_callb), (gpointer) &img->lift_edges_use_black_point);
2762
2763 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
2764
2765 hbox = tiling_control(&img->lift_edges_wrap);
2766
2767 gtk_box_pack_start (GTK_BOX (vbox), align_widget(hbox,0.5,0.5), FALSE, FALSE, DEF_PAD);
2768
2769 gtk_box_pack_start (GTK_BOX (vbox), apply_repeat_buttons_new (data, apply_lift_edges_callb, repeat_lift_edges_callb), FALSE, FALSE, DEF_PAD);
2770
2771 gtk_box_pack_start (GTK_BOX (vbox), reset_accept_buttons_new (data, &img->lift_edges_accept), FALSE, FALSE, DEF_PAD);
2772
2773 gtk_container_add(GTK_CONTAINER(frame), vbox);
2774
2775 return frame;
2776 }
2777
lift_edges_callb(GtkWidget * wdg,gpointer data)2778 void lift_edges_callb(GtkWidget *wdg, gpointer data) {
2779 hf_wrapper_struct *hfw;
2780 hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
2781 if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wdg))) {
2782 hf_commit_or_reset (hfw->hf_options);
2783 return;
2784 }
2785 if (!hfw->hf_options->img->lift_edges_dialog) {
2786 hfw->hf_options->img->lift_edges_dialog = lift_edges_dialog_new(data);
2787 gtk_container_add(GTK_CONTAINER(hfw->hf_options->img->img_dialog),
2788 hfw->hf_options->img->lift_edges_dialog );
2789 }
2790 if (hfw->hf_options->img->current_subdialog)
2791 gtk_widget_hide(hfw->hf_options->img->current_subdialog);
2792 hfw->hf_options->img->current_subdialog = hfw->hf_options->img->lift_edges_dialog;
2793 hfw->hf_options->img->set_fn = (gpointer) set_lift_edges_defaults;
2794 hfw->hf_options->img->accept_wdg = hfw->hf_options->img->lift_edges_accept ;
2795 gtk_widget_show(hfw->hf_options->img->current_subdialog);
2796 }
2797