1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * filename: xutils.c *
3 * *
4 * UTIL C-source: Medical Image Conversion Utility *
5 * *
6 * purpose : utility routines *
7 * *
8 * project : (X)MedCon by Erik Nolf *
9 * *
10 * Functions : XMdcMedconQuit() - Quit XMedCon main program *
11 * XMdcMainWidgetsInsensitive()- Make them insensitive *
12 * XMdcMainWidgetsResensitive()- Make them sensitive *
13 * XMdcWidgetCallbackDestroy() - General Destroy callback *
14 * XMdcConfigureXMedcon() - Parse configuration file *
15 * XMdcAskYesNo() - Ask a Yes/No question *
16 * XMdcRunDialog() - Run modal dialog *
17 * XMdcShowWidget() - Our show the widget routine*
18 * XMdcWidgetDestroy() - Destroy widget = NULL *
19 * XMdcSetGbcCorrection() - Set GBC corrected values *
20 * XMdcBuildRgbImage() - Build an RGB image *
21 * XMdcBuildGdkPixbuf() - Build GdkPixbuf out img8 *
22 * XMdcBuildGdkPixbufFI() - Build GdkPixbuf out FI img *
23 * XMdcPreventDelete() - Prevent delete event *
24 * XMdcHandlerToHide() - Hide widget (no delete) *
25 * XMdcFreeRGB() - Free RGB image *
26 * XMdcToggleVisibility() - Toggle widget visibility *
27 * XMdcSetImageScales() - Set width & height scale *
28 * XMdcScaleW() - Scale image width *
29 * XMdcScaleH() - Scale image height *
30 * *
31 * Note : Algoritme for gamma/brightness/contrast correction in *
32 * function XMdcSetGbcCorrection() copied from library *
33 * Imlib by Rasterman *
34 * *
35 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
36 /*
37 */
38
39 /*
40 Copyright (C) 1997-2021 by Erik Nolf
41
42 This program is free software; you can redistribute it and/or modify it
43 under the terms of the GNU General Public License as published by the
44 Free Software Foundation; either version 2, or (at your option) any later
45 version.
46
47 This program is distributed in the hope that it will be useful, but
48 WITHOUT ANY WARRANTY; without even the implied warranty of
49 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
50 Public License for more details.
51
52 You should have received a copy of the GNU General Public License along
53 with this program; if not, write to the Free Software Foundation, Inc.,
54 59 Place - Suite 330, Boston, MA 02111-1307, USA. */
55
56 /****************************************************************************
57 H E A D E R S
58 ****************************************************************************/
59
60 #include "m-depend.h"
61
62 #include <stdio.h>
63 #include <math.h>
64 #ifdef HAVE_STDLIB_H
65 #include <stdlib.h>
66 #endif
67
68 #include "xmedcon.h"
69
70 /****************************************************************************
71 F U N C T I O N S
72 ****************************************************************************/
73
XMdcMedconQuit(GtkWidget * widget,gpointer data)74 void XMdcMedconQuit(GtkWidget *widget, gpointer data)
75 {
76 XMdcFileReset();
77 XMdcFreeMyStuff();
78
79 exit(MDC_OK);
80
81 }
82
XMdcMainWidgetsInsensitive(void)83 void XMdcMainWidgetsInsensitive(void)
84 {
85
86 if (my.viewwindow != NULL)
87 gtk_widget_set_sensitive(my.viewwindow,FALSE);
88 if (my.mainwindow != NULL)
89 gtk_widget_set_sensitive(my.mainwindow,FALSE);
90
91 }
92
XMdcMainWidgetsResensitive(void)93 void XMdcMainWidgetsResensitive(void)
94 {
95
96 if (my.viewwindow != NULL)
97 gtk_widget_set_sensitive(my.viewwindow,TRUE);
98 if (my.mainwindow != NULL)
99 gtk_widget_set_sensitive(my.mainwindow,TRUE);
100
101 }
102
XMdcWidgetCallbackDestroy(GtkWidget * window)103 void XMdcWidgetCallbackDestroy(GtkWidget *window)
104 {
105 gtk_widget_destroy(window); window = NULL;
106 XMdcMainWidgetsResensitive();
107 }
108
XMdcConfigureXMedcon(void)109 void XMdcConfigureXMedcon(void)
110 {
111 char *h;
112
113 MdcDebugPrint("XMDCRC = %s",XMDCRC);
114 MdcDebugPrint("XMDCHELP = %s",XMDCHELP);
115
116 XMEDCONLUT = getenv("XMEDCONLUT");
117 XMEDCONRPI = getenv("XMEDCONRPI");
118
119 #ifdef _WIN32
120 /* try windows Program Files path */
121 sprintf(xmdcstr,"c:\\program files\\xmedcon\\etc\\xmedconrc");
122 if (MdcFileExists(xmdcstr)) {
123 MdcDebugPrint("rc file found in \"Program Files\"");
124 gtk_rc_parse(xmdcstr); return;
125 }
126 #else
127 /* try unixes HOME environment variable */
128 h = getenv("HOME");
129 if (h != NULL) {
130 sprintf(xmdcstr,"%s/.xmedconrc",h);
131 if (MdcFileExists(xmdcstr)) {
132 MdcDebugPrint("rc file found in HOME = %s",xmdcstr);
133 gtk_rc_parse(xmdcstr); return;
134 }
135 }
136 #endif
137
138 /* try XMEDCONRC environment variable */
139 h = getenv("XMEDCONRC");
140 if (h != NULL) {
141 if (MdcFileExists(h)) {
142 MdcDebugPrint("rc file found in XMEDCONRC = %s",h);
143 gtk_rc_parse(h); return;
144 }
145 }
146
147 /* try hardcoded install path */
148 if (MdcFileExists(XMDCRC)) {
149 MdcDebugPrint("rc file found in XMDCRC = %s",XMDCRC);
150 gtk_rc_parse(XMDCRC);
151 }
152
153 }
154
XMdcAskYesNo(GCallback YesFunc,GCallback NoFunc,char * question)155 void XMdcAskYesNo(GCallback YesFunc, GCallback NoFunc, char *question)
156 {
157 GtkWidget *dialog;
158 GtkWidget *label;
159 GtkWidget *button;
160 GtkWidget *action_area;
161 GtkWidget *content_area;
162
163 if (YesFunc == (GCallback)NULL ) return;
164
165 dialog = gtk_dialog_new();
166
167 action_area = gtk_dialog_get_action_area(GTK_DIALOG(dialog));
168 content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
169
170 gtk_container_set_border_width(GTK_CONTAINER(action_area),0);
171
172 g_signal_connect(GTK_OBJECT(dialog),"destroy",
173 G_CALLBACK(gtk_widget_destroy),NULL);
174 gtk_window_set_title(GTK_WINDOW(dialog), "Question");
175 gtk_container_set_border_width(GTK_CONTAINER(dialog),0);
176
177 label = gtk_label_new(question);
178 gtk_misc_set_padding(GTK_MISC(label),30,5);
179 gtk_box_pack_start(GTK_BOX(content_area), label, TRUE, TRUE, 0);
180 gtk_widget_show(label);
181
182 button=gtk_button_new_with_label("Yes");
183 gtk_box_pack_start(GTK_BOX(action_area), button,TRUE,TRUE,0);
184 g_signal_connect_swapped(GTK_OBJECT(button),"clicked",
185 G_CALLBACK(gtk_widget_hide), GTK_OBJECT(dialog));
186 g_signal_connect(GTK_OBJECT(button),"clicked",
187 G_CALLBACK(YesFunc),NULL);
188 g_signal_connect_swapped(GTK_OBJECT(button),"clicked",
189 G_CALLBACK(gtk_widget_destroy), GTK_OBJECT(dialog));
190 gtk_widget_show(button);
191
192 button=gtk_button_new_with_label("No");
193 gtk_box_pack_start(GTK_BOX(action_area), button,TRUE,TRUE,0);
194 if (NoFunc == (GCallback)NULL) {
195 g_signal_connect_swapped(GTK_OBJECT(button),"clicked",
196 G_CALLBACK(gtk_widget_destroy),
197 GTK_OBJECT(dialog));
198 }else{
199 g_signal_connect_swapped(GTK_OBJECT(button),"clicked",
200 G_CALLBACK(gtk_widget_hide), GTK_OBJECT(dialog));
201 g_signal_connect(GTK_OBJECT(button),"clicked",
202 G_CALLBACK(NoFunc),NULL);
203 g_signal_connect_swapped(GTK_OBJECT(button),"clicked",
204 G_CALLBACK(gtk_widget_destroy), GTK_OBJECT(dialog));
205 }
206 gtk_widget_show(button);
207
208 XMdcRunDialog(dialog);
209
210 }
211
XMdcRunDialog(GtkWidget * dialog)212 void XMdcRunDialog(GtkWidget *dialog)
213 {
214 gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER);
215 gtk_dialog_run(GTK_DIALOG(dialog));
216 }
217
XMdcShowWidget(GtkWidget * widget)218 void XMdcShowWidget(GtkWidget *widget)
219 {
220 gtk_window_set_position(GTK_WINDOW(widget), GTK_WIN_POS_MOUSE);
221 gtk_widget_show(widget);
222 }
223
XMdcWidgetDestroy(GtkWidget * widget,gpointer data)224 void XMdcWidgetDestroy(GtkWidget *widget, gpointer data)
225 {
226 MdcDebugPrint("XMdcDestroyWidget()");
227 if (data != NULL) {
228 gtk_widget_destroy(GTK_WIDGET(data)); data = NULL;
229 }
230 }
231
XMdcSetGbcCorrection(ColorModifier * mod)232 void XMdcSetGbcCorrection(ColorModifier *mod)
233 {
234 double g, b, c, ii, v;
235 Uint32 i;
236
237 g = ((double)mod->gamma) / 256.;
238 b = ((double)mod->brightness) / 256.;
239 c = ((double)mod->contrast) / 256.;
240
241 if (g < 0.01) g = 0.01;
242
243 for (i = 0; i < 256; i++) {
244 ii = ((double)i) / 256.;
245 v = ((ii - 0.5) * c) + 0.5 + (b - 1.);
246 if (v > 0) {
247 v = pow(((ii - 0.5) * c) + 0.5 + (b - 1.), 1. / g) * 256.;
248 }else{
249 v = 0.;
250 }
251 if (v > 255.) {
252 v = 255.;
253 }else if (v < 0.) {
254 v = 0.;
255 }
256 mod->vgbc[i] = (guchar)v;
257 }
258
259 }
260
XMdcBuildRgbImage(Uint8 * img8,Int16 type,Uint32 pixels,Uint8 * vgbc)261 Uint8 *XMdcBuildRgbImage(Uint8 *img8, Int16 type, Uint32 pixels, Uint8 *vgbc)
262 {
263 Uint8 *imgRGB, rr, gg, bb;
264 Uint32 pix;
265
266 imgRGB = (Uint8 *)malloc(pixels * 3);
267 if (imgRGB == NULL) return(NULL);
268
269 for (pix=0; pix < pixels; pix++) {
270 if (type == COLRGB) {
271 rr = img8[pix * 3 + 0];
272 gg = img8[pix * 3 + 1];
273 bb = img8[pix * 3 + 2];
274 }else{
275 rr = my.fi->palette[img8[pix] * 3 + 0];
276 gg = my.fi->palette[img8[pix] * 3 + 1];
277 bb = my.fi->palette[img8[pix] * 3 + 2];
278 }
279 imgRGB[pix * 3 + 0] = vgbc[rr];
280 imgRGB[pix * 3 + 1] = vgbc[gg];
281 imgRGB[pix * 3 + 2] = vgbc[bb];
282 }
283
284 return(imgRGB);
285 }
286
XMdcBuildGdkPixbuf(Uint8 * img8,Uint32 w,Uint32 h,Int16 type,Uint8 * vgbc)287 GdkPixbuf *XMdcBuildGdkPixbuf(Uint8 *img8, Uint32 w, Uint32 h, Int16 type, Uint8 *vgbc)
288 {
289 GdkPixbuf *imtmp, *im;
290 Uint8 *imgRGB;
291 Uint32 pixels = w * h;
292 gint rw, rh;
293
294 imgRGB = XMdcBuildRgbImage(img8, type, pixels, vgbc);
295 if (imgRGB == NULL) return(NULL);
296
297 rw = (gint)w; rh = (gint)h;
298
299 imtmp = gdk_pixbuf_new_from_data(imgRGB,GDK_COLORSPACE_RGB,FALSE,8,rw,rh
300 ,(int)(3*w),XMdcFreeRGB,NULL);
301 if (imtmp == NULL) { MdcFree(imgRGB); return(NULL); }
302
303 rw = (gint)XMdcScaleW(w); rh = (gint)XMdcScaleH(h);
304
305 if ((rw != w) || (rh != h)) {
306 im = gdk_pixbuf_scale_simple(imtmp,rw,rh,sRenderSelection.Interp);
307 g_object_unref(imtmp);
308 }else{
309 im = imtmp;
310 }
311
312 return(im);
313 }
314
XMdcBuildGdkPixbufFI(FILEINFO * fi,Uint32 i,Uint8 * vgbc)315 GdkPixbuf *XMdcBuildGdkPixbufFI(FILEINFO *fi,Uint32 i,Uint8 *vgbc)
316 {
317 GdkPixbuf *im;
318 Uint8 *img8;
319 Uint32 w, h;
320 Int16 t;
321
322 w = fi->image[i].width;
323 h = fi->image[i].height;
324 t = fi->image[i].type;
325
326 img8 = MdcGetDisplayImage(fi,i);
327 if (img8 == NULL)
328 XMdcDisplayFatalErr(MDC_BAD_ALLOC,"Couldn't create byte image");
329
330 im = XMdcBuildGdkPixbuf(img8, w, h, t, vgbc);
331
332 MdcFree(img8);
333
334 if (im == NULL) {
335 XMdcDisplayFatalErr(MDC_BAD_ALLOC,"Couldn't create GdkPixbuf");
336 }
337
338 return(im);
339
340 }
341
XMdcPreventDelete(GtkWidget * widget,GdkEvent * event,gpointer data)342 gboolean XMdcPreventDelete(GtkWidget *widget, GdkEvent *event, gpointer data)
343 {
344 return(TRUE);
345 }
346
XMdcHandlerToHide(GtkWidget * widget,GdkEvent * event,gpointer data)347 gboolean XMdcHandlerToHide(GtkWidget *widget, GdkEvent *event, gpointer data)
348 {
349 gtk_widget_hide(widget);
350 return(TRUE);
351 }
352
XMdcFreeRGB(guchar * pixdata,gpointer data)353 void XMdcFreeRGB(guchar *pixdata, gpointer data)
354 {
355 MdcFree(pixdata);
356 }
357
XMdcToggleVisibility(GtkWidget * widget)358 void XMdcToggleVisibility(GtkWidget *widget)
359 {
360 if (gtk_widget_get_visible(widget)) {
361 gtk_widget_hide(widget);
362 }else{
363 gtk_widget_show(widget);
364 }
365 }
366
XMdcSetImageScales(void)367 void XMdcSetImageScales(void)
368 {
369 float ratio_width, ratio_height;
370
371 my.scale_width = 1.; my.scale_height = 1.;
372
373 /* scale to real world sizes */
374
375 if (my.fi->pixdim[1] > my.fi->pixdim[2]) {
376
377 /* width > height -> height is unit */
378 my.scale_width = my.fi->pixdim[1] / my.fi->pixdim[2];
379
380 }else if (my.fi->pixdim[2] > my.fi->pixdim[1]) {
381
382 /* height > width -> width is unit */
383 my.scale_height = my.fi->pixdim[2] / my.fi->pixdim[1];
384
385 }
386
387 /* fit to screen sizes */
388
389 ratio_width = ((float)my.fi->mwidth * my.scale_width)
390 / ((float)gdk_screen_width() - (1.2 * (float)XMDC_FREE_BORDER));
391
392 ratio_height = ((float)my.fi->mheight * my.scale_height)
393 / ((float)gdk_screen_height() - (1.2 * (float)XMDC_FREE_BORDER));
394
395 if ((ratio_width <= 1.) && (ratio_height <= 1.)) return; /* both fit */
396
397 /* needs resizing */
398 if (ratio_width > ratio_height) {
399 /* fit via width */
400 my.scale_width /= ratio_width;
401 my.scale_height /= ratio_width;
402 }else{
403 /* fit via height */
404 my.scale_width /= ratio_height;
405 my.scale_height /= ratio_height;
406 }
407
408 }
409
XMdcScaleW(Uint32 width)410 Uint32 XMdcScaleW(Uint32 width)
411 {
412 Uint32 new_width = width;
413
414 if (my.scale_width != 1.) {
415
416 new_width = (Uint32)((float)width * my.scale_width);
417
418 }
419
420 return(XMdcResize(new_width));
421 }
422
XMdcScaleH(Uint32 height)423 Uint32 XMdcScaleH(Uint32 height)
424 {
425 Uint32 new_height = height;
426
427 if (my.scale_height != 1.) {
428
429 new_height = (Uint32)((float)height * my.scale_height);
430
431 }
432
433 return(XMdcResize(new_height));
434 }
435