|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+#include <math.h>
|
|
|
2
|
+#include <iostream>
|
|
|
3
|
+using namespace std;
|
|
|
4
|
+
|
|
|
5
|
+#include <gtk/gtk.h>
|
|
|
6
|
+#include <glib.h>
|
|
|
7
|
+
|
|
|
8
|
+#include "haader.h"
|
|
|
9
|
+#include "image.h"
|
|
|
10
|
+
|
|
|
11
|
+struct Gui {
|
|
|
12
|
+ GtkWidget *window;
|
|
|
13
|
+ GtkWidget *canvas;
|
|
|
14
|
+ haader::HdrImageStack stack;
|
|
|
15
|
+ haader::HdrImage hdr_image;
|
|
|
16
|
+ haader::ResponseFunction response_function;
|
|
|
17
|
+ haader::Image ldr_image;
|
|
|
18
|
+ cairo_surface_t *surface;
|
|
|
19
|
+ double exposure_time;
|
|
|
20
|
+ double compression;
|
|
|
21
|
+};
|
|
|
22
|
+
|
|
|
23
|
+static cairo_surface_t* image_to_cairo_surface(const haader::Image &image) {
|
|
|
24
|
+ unsigned int width = image.get_width();
|
|
|
25
|
+ unsigned int height = image.get_height();
|
|
|
26
|
+ const unsigned char *image_data = image.get_const_image_data();
|
|
|
27
|
+
|
|
|
28
|
+ cairo_surface_t *surf = cairo_image_surface_create(CAIRO_FORMAT_RGB24, width, height);
|
|
|
29
|
+ int stride = cairo_image_surface_get_stride(surf);
|
|
|
30
|
+ unsigned char *surf_data = cairo_image_surface_get_data(surf);
|
|
|
31
|
+
|
|
|
32
|
+ unsigned int i = 0;
|
|
|
33
|
+ unsigned int k = 0;
|
|
|
34
|
+ for (unsigned int y = 0; y < height; y++) {
|
|
|
35
|
+ for (unsigned int x = 0; x < width; x++) {
|
|
|
36
|
+ surf_data[i + x * 4] = image_data[k + x * 3 + 2];
|
|
|
37
|
+ surf_data[i + x * 4 + 1] = image_data[k + x * 3 + 1];
|
|
|
38
|
+ surf_data[i + x * 4 + 2] = image_data[k + x * 3];
|
|
|
39
|
+ }
|
|
|
40
|
+ i += stride;
|
|
|
41
|
+ k += width * 3;
|
|
|
42
|
+ }
|
|
|
43
|
+
|
|
|
44
|
+ return surf;
|
|
|
45
|
+}
|
|
|
46
|
+
|
|
|
47
|
+static void expose(Gui &gui) {
|
|
|
48
|
+ gui.ldr_image = gui.hdr_image.expose(gui.exposure_time, gui.response_function, gui.compression);
|
|
|
49
|
+ if (gui.surface) {
|
|
|
50
|
+ cairo_surface_destroy(gui.surface);
|
|
|
51
|
+ gui.surface = NULL;
|
|
|
52
|
+ }
|
|
|
53
|
+ gui.surface = image_to_cairo_surface(gui.ldr_image);
|
|
|
54
|
+}
|
|
|
55
|
+
|
|
|
56
|
+static gboolean canvas_draw(GtkWidget *widget, cairo_t *cr, gpointer user_data)
|
|
|
57
|
+{
|
|
|
58
|
+ cairo_set_source_rgb(cr, 0.2, 0.2, 0.2);
|
|
|
59
|
+ cairo_paint(cr);
|
|
|
60
|
+
|
|
|
61
|
+ Gui *gui = (Gui*) user_data;
|
|
|
62
|
+ if (gui->surface) {
|
|
|
63
|
+ cairo_set_source_surface(cr, gui->surface, 0, 0);
|
|
|
64
|
+ cairo_paint(cr);
|
|
|
65
|
+ }
|
|
|
66
|
+
|
|
|
67
|
+ return FALSE;
|
|
|
68
|
+}
|
|
|
69
|
+
|
|
|
70
|
+void scale_exposure_changed(GtkRange *range, gpointer user_data) {
|
|
|
71
|
+ Gui *gui = (Gui*) user_data;
|
|
|
72
|
+
|
|
|
73
|
+ gui->exposure_time = pow(2.0, gtk_range_get_value(range));
|
|
|
74
|
+
|
|
|
75
|
+ expose(*gui);
|
|
|
76
|
+
|
|
|
77
|
+ gtk_widget_queue_draw(gui->canvas);
|
|
|
78
|
+}
|
|
|
79
|
+
|
|
|
80
|
+void scale_compression_changed(GtkRange *range, gpointer user_data) {
|
|
|
81
|
+ Gui *gui = (Gui*) user_data;
|
|
|
82
|
+
|
|
|
83
|
+ gui->compression = pow(2.0, gtk_range_get_value(range));
|
|
|
84
|
+
|
|
|
85
|
+ expose(*gui);
|
|
|
86
|
+
|
|
|
87
|
+ gtk_widget_queue_draw(gui->canvas);
|
|
|
88
|
+}
|
|
|
89
|
+
|
|
|
90
|
+void file_select_clicked(GtkButton *button, gpointer user_data) {
|
|
|
91
|
+ Gui *gui = (Gui*) user_data;
|
|
|
92
|
+
|
|
|
93
|
+ GtkWidget *dialog = gtk_file_chooser_dialog_new(
|
|
|
94
|
+ "Open File",
|
|
|
95
|
+ GTK_WINDOW(gui->window),
|
|
|
96
|
+ GTK_FILE_CHOOSER_ACTION_OPEN,
|
|
|
97
|
+ "Cancel",
|
|
|
98
|
+ GTK_RESPONSE_CANCEL,
|
|
|
99
|
+ "Open",
|
|
|
100
|
+ GTK_RESPONSE_ACCEPT,
|
|
|
101
|
+ NULL);
|
|
|
102
|
+
|
|
|
103
|
+ gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER(dialog), true);
|
|
|
104
|
+
|
|
|
105
|
+ int res = gtk_dialog_run(GTK_DIALOG(dialog));
|
|
|
106
|
+ if (res == GTK_RESPONSE_ACCEPT) {
|
|
|
107
|
+ GSList *list = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog));
|
|
|
108
|
+ vector<string> new_list;
|
|
|
109
|
+
|
|
|
110
|
+ GSList *element = list;
|
|
|
111
|
+ while (element != NULL) {
|
|
|
112
|
+ //TODO handle errors
|
|
|
113
|
+ gui->stack.add_from_file_path((const char*)(element->data));
|
|
|
114
|
+ g_free(element->data);
|
|
|
115
|
+ element = g_slist_next(element);
|
|
|
116
|
+ }
|
|
|
117
|
+
|
|
|
118
|
+ g_slist_free(list);
|
|
|
119
|
+ }
|
|
|
120
|
+
|
|
|
121
|
+ // create HDR-image
|
|
|
122
|
+ haader::InverseResponseFunction irf;
|
|
|
123
|
+ if (gui->stack.get_inverse_response_function(irf, 4096)) {
|
|
|
124
|
+ gui->hdr_image = gui->stack.get_hdr_image(irf);
|
|
|
125
|
+ gui->ldr_image = gui->hdr_image.get_log_image();
|
|
|
126
|
+ if (gui->surface) {
|
|
|
127
|
+ cairo_surface_destroy(gui->surface);
|
|
|
128
|
+ gui->surface = NULL;
|
|
|
129
|
+ }
|
|
|
130
|
+ gui->surface = image_to_cairo_surface(gui->ldr_image);
|
|
|
131
|
+ gui->response_function = irf.to_response_function(1024);
|
|
|
132
|
+ }
|
|
|
133
|
+
|
|
|
134
|
+ gtk_widget_queue_draw(gui->canvas);
|
|
|
135
|
+
|
|
|
136
|
+ gtk_widget_destroy (dialog);
|
|
|
137
|
+}
|
|
|
138
|
+
|
|
|
139
|
+int main(int argc, char *argv[])
|
|
|
140
|
+{
|
|
|
141
|
+ gtk_init(&argc, &argv);
|
|
|
142
|
+
|
|
|
143
|
+ Gui gui;
|
|
|
144
|
+ gui.surface = NULL;
|
|
|
145
|
+ gui.exposure_time = 0.0;
|
|
|
146
|
+ gui.compression = 1.0;
|
|
|
147
|
+
|
|
|
148
|
+ gui.window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
|
|
149
|
+ gtk_window_set_title(GTK_WINDOW(gui.window), "haader");
|
|
|
150
|
+ gtk_window_set_default_size(GTK_WINDOW(gui.window), 800, 600);
|
|
|
151
|
+
|
|
|
152
|
+ GtkWidget *file_button = gtk_button_new_with_label("Select files");
|
|
|
153
|
+ gui.canvas = gtk_drawing_area_new();
|
|
|
154
|
+ GtkWidget *scale_exposure = gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, -20.0, 4.0, 0.001);
|
|
|
155
|
+ GtkWidget *scale_compression = gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, -4, 4.0, 0.001);
|
|
|
156
|
+
|
|
|
157
|
+ GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
|
|
|
158
|
+
|
|
|
159
|
+ gtk_container_add(GTK_CONTAINER(gui.window), vbox);
|
|
|
160
|
+ gtk_box_pack_start(GTK_BOX(vbox), file_button, false, false, 0);
|
|
|
161
|
+ gtk_box_pack_start(GTK_BOX(vbox), gui.canvas, true, true, 0);
|
|
|
162
|
+ gtk_box_pack_start(GTK_BOX(vbox), scale_exposure, false, false, 0);
|
|
|
163
|
+ gtk_box_pack_start(GTK_BOX(vbox), scale_compression, false, false, 0);
|
|
|
164
|
+
|
|
|
165
|
+ g_signal_connect(gui.window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
|
|
|
166
|
+ g_signal_connect(gui.canvas, "draw", G_CALLBACK(canvas_draw), &gui);
|
|
|
167
|
+ g_signal_connect(file_button, "clicked", G_CALLBACK(file_select_clicked), &gui);
|
|
|
168
|
+ g_signal_connect(scale_exposure, "value-changed", G_CALLBACK(scale_exposure_changed), &gui);
|
|
|
169
|
+ g_signal_connect(scale_compression, "value-changed", G_CALLBACK(scale_compression_changed), &gui);
|
|
|
170
|
+
|
|
|
171
|
+ gtk_widget_show_all(gui.window);
|
|
|
172
|
+
|
|
|
173
|
+ gtk_main ();
|
|
|
174
|
+
|
|
|
175
|
+ return 0;
|
|
|
176
|
+}
|