1 /*
2  * This file is part of Siril, an astronomy image processor.
3  * Copyright (C) 2005-2011 Francois Meyer (dulle at free.fr)
4  * Copyright (C) 2012-2021 team free-astro (see more in AUTHORS file)
5  * Reference site is https://free-astro.org/index.php/Siril
6  *
7  * Siril is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * Siril is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with Siril. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 #include <string.h>
22 #include <opencv2/core/version.hpp>
23 
24 #include "core/siril.h"
25 #include "core/proto.h"
26 #include "algos/statistics.h"
27 #include "core/processing.h"
28 #include "core/undo.h"
29 #include "algos/colors.h"
30 #include "opencv/opencv.h"
31 #include "gui/image_display.h"
32 #include "gui/dialogs.h"
33 #include "gui/progress_and_log.h"
34 #include "gui/utils.h"
35 #include "io/single_image.h"
36 #include "gui/message_dialog.h"
37 #include "gui/siril_preview.h"
38 
39 #include "clahe.h"
40 
41 static double clahe_limit_value;
42 static int clahe_tile_size;
43 static gboolean clahe_show_preview;
44 
clahe_startup()45 static void clahe_startup() {
46 	copy_gfit_to_backup();
47 	clahe_limit_value = 2.0;
48 	clahe_tile_size = 8;
49 }
50 
clahe_close(gboolean revert)51 static void clahe_close(gboolean revert) {
52 	set_cursor_waiting(TRUE);
53 	if (revert) {
54 		siril_preview_hide();
55 	} else {
56 		invalidate_stats_from_fit(&gfit);
57 		undo_save_state(get_preview_gfit_backup(),
58 				_("CLAHE (size=%d, clip=%.2f)"), clahe_tile_size, clahe_limit_value);
59 	}
60 	clear_backup();
61 	set_cursor_waiting(FALSE);
62 }
63 
clahe_update_preview()64 static int clahe_update_preview() {
65 	copy_backup_to_gfit();
66 	if (CV_MAJOR_VERSION < 3) {
67 		char *error = siril_log_message(_("Your version of opencv is "
68 				"too old for this feature. Please upgrade your system."));
69 		siril_message_dialog(GTK_MESSAGE_ERROR, _("Upgrade your system"),
70 				error);
71 		return 1;
72 	}
73 
74 	struct CLAHE_data *args = malloc(sizeof(struct CLAHE_data));
75 
76 	set_cursor_waiting(TRUE);
77 
78 	args->fit = &gfit;
79 	args->clip = clahe_limit_value;
80 	args->tileSize = clahe_tile_size;
81 
82 	start_in_new_thread(clahe, args);
83 	return 0;
84 }
85 
clahe(gpointer p)86 gpointer clahe(gpointer p) {
87 	struct CLAHE_data *args = (struct CLAHE_data*) p;
88 
89 	cvClahe(args->fit, args->clip, args->tileSize);
90 
91 	siril_add_idle(end_generic, args);
92 	free(args);
93 	return GINT_TO_POINTER(0);
94 }
95 
apply_clahe_cancel()96 void apply_clahe_cancel() {
97 	clahe_close(TRUE);
98 	siril_close_dialog("CLAHE_dialog");
99 }
100 
101 /** callbacks **/
102 
on_clahe_cancel_clicked(GtkMenuItem * menuitem,gpointer user_data)103 void on_clahe_cancel_clicked(GtkMenuItem *menuitem, gpointer user_data) {
104 	clahe_close(TRUE);
105 	siril_close_dialog("CLAHE_dialog");
106 }
107 
on_CLAHE_dialog_close(GtkDialog * dialog,gpointer user_data)108 void on_CLAHE_dialog_close(GtkDialog *dialog, gpointer user_data) {
109 	clahe_close(TRUE);
110 }
111 
on_clahe_undo_clicked(GtkButton * button,gpointer user_data)112 void on_clahe_undo_clicked(GtkButton *button, gpointer user_data) {
113 	GtkSpinButton *liit_value = GTK_SPIN_BUTTON(lookup_widget("spin_clahe"));
114 	GtkSpinButton *tiles_size = GTK_SPIN_BUTTON(lookup_widget("clahe_tiles_size_spin"));
115 	clahe_limit_value = 2.0;
116 	clahe_tile_size = 8;
117 
118 	set_notify_block(TRUE);
119 	gtk_spin_button_set_value(liit_value, clahe_limit_value);
120 	gtk_spin_button_set_value(tiles_size, clahe_tile_size);
121 	set_notify_block(FALSE);
122 
123 	copy_backup_to_gfit();
124 
125 	/* default parameters transform image, we need to update preview */
126 	update_image *param = malloc(sizeof(update_image));
127 	param->update_preview_fn = clahe_update_preview;
128 	param->show_preview = clahe_show_preview;
129 	notify_update((gpointer) param);
130 }
131 
on_clahe_Apply_clicked(GtkButton * button,gpointer user_data)132 void on_clahe_Apply_clicked(GtkButton *button, gpointer user_data) {
133 	if (clahe_show_preview == FALSE) {
134 		update_image *param = malloc(sizeof(update_image));
135 		param->update_preview_fn = clahe_update_preview;
136 		param->show_preview = TRUE;
137 		notify_update((gpointer) param);
138 	}
139 
140 	clahe_close(FALSE);
141 	siril_close_dialog("CLAHE_dialog");
142 }
143 
on_CLAHE_dialog_show(GtkWidget * widget,gpointer user_data)144 void on_CLAHE_dialog_show(GtkWidget *widget, gpointer user_data) {
145 	clahe_startup();
146 
147 	set_notify_block(TRUE);
148 	gtk_spin_button_set_value(GTK_SPIN_BUTTON(lookup_widget("clahe_tiles_size_spin")), clahe_tile_size);
149 	gtk_spin_button_set_value(GTK_SPIN_BUTTON(lookup_widget("spin_clahe")),	clahe_limit_value);
150 	set_notify_block(FALSE);
151 
152 	clahe_show_preview = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget("clahe_preview")));
153 
154 	/* default parameters transform image, we need to update preview */
155 	update_image *param = malloc(sizeof(update_image));
156 	param->update_preview_fn = clahe_update_preview;
157 	param->show_preview = clahe_show_preview;
158 	notify_update((gpointer) param);
159 }
160 
161 /** adjusters **/
on_spin_clahe_value_changed(GtkSpinButton * button,gpointer user_data)162 void on_spin_clahe_value_changed(GtkSpinButton *button, gpointer user_data) {
163 	clahe_limit_value = gtk_spin_button_get_value(button);
164 	update_image *param = malloc(sizeof(update_image));
165 	param->update_preview_fn = clahe_update_preview;
166 	param->show_preview = clahe_show_preview;
167 	notify_update((gpointer) param);
168 }
169 
on_clahe_tiles_size_spin_value_changed(GtkSpinButton * button,gpointer user_data)170 void on_clahe_tiles_size_spin_value_changed(GtkSpinButton *button, gpointer user_data) {
171 	clahe_tile_size = gtk_spin_button_get_value(button);
172 	update_image *param = malloc(sizeof(update_image));
173 	param->update_preview_fn = clahe_update_preview;
174 	param->show_preview = clahe_show_preview;
175 	notify_update((gpointer) param);
176 }
177 
on_clahe_preview_toggled(GtkToggleButton * button,gpointer user_data)178 void on_clahe_preview_toggled(GtkToggleButton *button, gpointer user_data) {
179 	if (clahe_show_preview == TRUE) {
180 		/* if user click very fast */
181 		waiting_for_thread();
182 		siril_preview_hide();
183 	} else {
184 		copy_gfit_to_backup();
185 
186 		update_image *param = malloc(sizeof(update_image));
187 		param->update_preview_fn = clahe_update_preview;
188 		param->show_preview = TRUE;
189 		notify_update((gpointer) param);
190 	}
191 	clahe_show_preview = !clahe_show_preview;
192 }
193 
194