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