~ubuntu-branches/ubuntu/breezy/ufraw/breezy-backports

« back to all changes in this revision

Viewing changes to ufraw.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Urlichs
  • Date: 2005-02-13 16:33:49 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20050213163349-yvk9e3l5ks2rlbvt
Tags: 0.4-1
* New Upstream version.
  - Closes:#294195

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * UFRaw - Unidentified Flying Raw converter for digital camera images
 
3
 * by Udi Fuchs
 
4
 *
 
5
 * ufraw.c - The standalone interface to UFRaw.
 
6
 *
 
7
 * UFRaw is licensed under the GNU General Public License.
 
8
 * It uses DCRaw code to do the actual raw decoding.
 
9
 */
 
10
 
 
11
#include <stdio.h>     /* for printf */
 
12
#include <stdlib.h>    /* for exit */
 
13
#include <errno.h>     /* for errno */
 
14
#include <string.h>
 
15
#include <math.h>      /* for isnan */
 
16
#include <getopt.h>
 
17
#include <glib.h>
 
18
#include <gtk/gtk.h>
 
19
#include <locale.h>
 
20
#ifndef NO_TIFF
 
21
#include <tiffio.h>
 
22
#endif
 
23
#ifndef NO_JPEG
 
24
#include <jpeglib.h>
 
25
#include "iccjpeg.h"
 
26
#endif
 
27
#include "ufraw.h"
 
28
#include "ufraw_icon.h"
 
29
 
 
30
#define NULLF -10000
 
31
 
 
32
char helpText[]=
 
33
"UFRaw 0.3 - Unidentified Flying Raw converter for digital camera images.\n"
 
34
"\n"
 
35
"Usage: ufraw [ options ... ] [ raw-image-files ... ]\n"
 
36
"\n"
 
37
"By default UFRaw displays a preview window for each raw image allowing\n"
 
38
"the user to tweak the image parameters before saving. If no raw images\n"
 
39
"are given at the command line, UFRaw will display a file chooser dialog.\n"
 
40
"To process the images with no questions asked (and no preview) use\n"
 
41
"the --batch option. The rest of the options are separated into two groups.\n"
 
42
"The options which are related to the image manipulation are:\n"
 
43
"\n"
 
44
"--wb=camera|auto      White balance setting.\n"
 
45
"--temperature=TEMP    Color temperature in Kelvins (2000 - 7000).\n"
 
46
"--green=GREEN         Green color normalization.\n"
 
47
"--curve=gamma|log|linear|camera\n"
 
48
"                      Type of tone curve to use (default camera if such\n"
 
49
"                      exsists, log otherwise).\n"
 
50
"--[no]unclip          Unclip [clip] highlights.\n"
 
51
"--contrast=CONTRAST   Contrast adjustment (default 1.0).\n"
 
52
"--gamma=GAMMA         Gamma adjustment (default 0.45).\n"
 
53
"--saturation=SAT      Saturation adjustment (default 1.0, 0 for B&W output).\n"
 
54
"--shadow=SHADOW       Suppress enhance shadow details (default 0).\n"
 
55
"--shadow-depth=DEPTH  Define what are shadows (default 0.1).\n"
 
56
"--exposure=EXPOSURE   Exposure correction in EV (default 0).\n"
 
57
"--black-point=BLACK   Set black point (default 0).\n"
 
58
"\n"
 
59
"The options which are related to the final output are:\n"
 
60
"\n"
 
61
"--interpolation=full|four-color|quick|half\n"
 
62
"                      Interpolation algorithm to use (default full).\n"
 
63
"--shrink=FACTOR       Shrink the image by FACTOR (default 1).\n"
 
64
"--out-type=ppm8|ppm16|tiff8|tiff16|jpeg\n"
 
65
"                      Output file formati (default ppm8).\n"
 
66
"--compression=VALUE   JPEG compression (0-100, default 85).\n"
 
67
"--[no]zip             Enable [disable] TIFF zip compression (default nozip).\n"
 
68
"--out-path=PATH       PATH for output file (default use input file's path).\n"
 
69
"--overwrite           Overwrite existing files without asking (default no).\n"
 
70
"\n"
 
71
"UFRaw first reads the setting from the configuration file $HOME/.ufrawrc\n"
 
72
"and then sets the options from the command line. In batch mode, the second\n"
 
73
"group of options is NOT read from the configuration file, and therefore,\n"
 
74
"must be specified explicitly if non-default values are desired.\n"
 
75
"\n"
 
76
"Last, but not least, --help displays this help message and exits.\n";
 
77
 
 
78
int ufraw_saver(GtkWidget *widget, gpointer user_data);
 
79
int ufraw_write_image(image_data *image, char *outFilename);
 
80
void ufraw_chooser(cfg_data *cfg);
 
81
 
 
82
int main (int argc, char **argv)
 
83
{
 
84
    image_data *image;
 
85
    cfg_data cfg;
 
86
    GtkWidget *dummyWindow=NULL;
 
87
    int c;
 
88
    int index=0;
 
89
    char *wbName=NULL;
 
90
    gboolean batch=FALSE, unclip=-1, losslessCompress=-1, overwrite=-1;
 
91
    char *curveName=NULL, *outTypeName=NULL, *outPath=NULL;
 
92
    int curveType;
 
93
    float contrast=NULLF, gamma=NULLF, saturation=NULLF, shadow=NULLF,
 
94
        shadowDepth=NULLF, blackPoint=NULLF, exposure=NULLF,
 
95
        temperature=NULLF, green=NULLF, compression=NULLF;
 
96
    char *interpolationName=NULL;
 
97
    float shrink = NULLF;
 
98
    static struct option options[] = {
 
99
        {"wb", 1, 0, 'w'},
 
100
        {"temperature", 1, 0, 't'},
 
101
        {"green", 1, 0, 'g'},
 
102
        {"curve", 1, 0, 'c'},
 
103
        {"contrast", 1, 0, 'C'},
 
104
        {"gamma", 1, 0, 'G'},
 
105
        {"saturation", 1, 0, 's'},
 
106
        {"shadow", 1, 0, 'S'},
 
107
        {"shadow-depth", 1, 0, 'd'},
 
108
        {"exposure", 1, 0, 'e'},
 
109
        {"black-point", 1, 0, 'k'},
 
110
        {"interpolation", 1, 0, 'i'},
 
111
        {"shrink", 1, 0, 'x'},
 
112
        {"compression", 1, 0, 'j'},
 
113
        {"out-type", 1, 0, 'T'},
 
114
        {"out-path", 1, 0, 'p'},
 
115
/* Binary flags that don't have a value are here at the end */
 
116
        {"batch", 0, 0, 'B'},
 
117
        {"unclip", 0, 0, 'u'},
 
118
        {"nounclip", 0, 0, 'U'},
 
119
        {"zip", 0, 0, 'z'},
 
120
        {"nozip", 0, 0, 'Z'},
 
121
        {"overwrite", 0, 0, 'o'},
 
122
        {"help", 0, 0, 'h'},
 
123
        {0, 0, 0, 0}
 
124
    };
 
125
    void *optPointer[] = { &wbName, &temperature, &green, &curveName,
 
126
        &contrast, &gamma, &saturation, &shadow, &shadowDepth,
 
127
        &exposure, &blackPoint, &interpolationName, &shrink,
 
128
        &compression, &outTypeName, &outPath };
 
129
    const char *locale;
 
130
 
 
131
    locale = setlocale(LC_ALL, "");
 
132
    if ( locale!=NULL &&
 
133
        (!strncmp(locale, "he", 2) || !strncmp(locale, "iw", 2) ||
 
134
        !strncmp(locale, "ar", 2) ||
 
135
        !strncmp(locale, "Hebrew", 6) || !strncmp(locale, "Arabic", 6) ) ) {
 
136
        /* I'm not sure why the following doesn't work (on Windows at least) */
 
137
/*        locale = setlocale(LC_ALL, "en_US");
 
138
        gtk_disable_setlocale(); */
 
139
        /* so I'm using setenv */
 
140
        g_setenv("LC_ALL", "en_US", TRUE);
 
141
    }
 
142
    gtk_init(&argc, &argv);
 
143
    while (1) {
 
144
        c = getopt_long (argc, argv, "", options, &index);
 
145
        if (c == -1) break;
 
146
        switch (c) {
 
147
        case 't':
 
148
        case 'g':
 
149
        case 'C':
 
150
        case 'G':
 
151
        case 's':
 
152
        case 'S':
 
153
        case 'd':
 
154
        case 'e':
 
155
        case 'k':
 
156
        case 'x':
 
157
        case 'j':
 
158
            if (sscanf(optarg, "%f", (float *)optPointer[index])==0){
 
159
                ufraw_message(UFRAW_ERROR,
 
160
                    "ufraw: '%s' is not a valid value for the --%s option.\n",
 
161
                    optarg, options[index].name);
 
162
                exit(1);
 
163
            }
 
164
            break;
 
165
        case 'w':
 
166
        case 'c':
 
167
        case 'i':
 
168
        case 'T':
 
169
        case 'p':
 
170
            *(char **)optPointer[index] = optarg;
 
171
            break;
 
172
        case 'B': batch = TRUE; break;
 
173
        case 'u': unclip = TRUE; break;
 
174
        case 'U': unclip = FALSE; break;
 
175
        case 'o': overwrite = TRUE; break;
 
176
        case 'z':
 
177
#ifdef NO_ZLIB
 
178
            ufraw_message(UFRAW_ERROR,
 
179
                "ufraw: ufraw was build without ZIP support.\n");
 
180
            exit(1);
 
181
#else
 
182
            losslessCompress = TRUE; break;
 
183
#endif
 
184
        case 'Z': losslessCompress = FALSE; break;
 
185
        case 'h':
 
186
            fprintf(stderr, helpText);
 
187
            exit(0);
 
188
        case '?': /* invalid option. Warning printed by getopt() */
 
189
            exit(1);
 
190
        default:
 
191
            ufraw_message(UFRAW_ERROR, "getopt returned "
 
192
                       "character code 0%o ??\n", c);
 
193
            exit(1);
 
194
        }
 
195
    }
 
196
    if (!batch) {
 
197
        dummyWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 
198
        gtk_window_set_icon(GTK_WINDOW(dummyWindow),
 
199
                gdk_pixbuf_new_from_inline(-1, ufraw_icon, FALSE, NULL));
 
200
        ufraw_message_handler(UFRAW_SET_PARENT, (char *)dummyWindow);
 
201
    }
 
202
    ufraw_config(NULL, &cfg);
 
203
    if (outPath!=NULL) {
 
204
        if (g_file_test(outPath, G_FILE_TEST_IS_DIR))
 
205
             g_strlcpy(cfg.outputFilename, outPath, max_path);
 
206
        else {
 
207
            ufraw_message(UFRAW_ERROR, "'%s' is not a valid path.\n", outPath);
 
208
            exit(1);
 
209
        }
 
210
    }
 
211
    if (batch) {
 
212
        /* The save options are always set to default */
 
213
        if (cfg.interpolation!=four_color_interpolation)
 
214
            cfg.interpolation = full_interpolation;
 
215
        cfg.shrink = cfg_default.shrink;
 
216
        cfg.type = cfg_default.type;
 
217
        cfg.compression = cfg_default.compression;
 
218
        cfg.losslessCompress = cfg_default.losslessCompress;
 
219
        /* Disable some of the resetting done in ufraw_config() */
 
220
        cfg.wbLoad = load_preserve;
 
221
        if (temperature!=NULLF || green!=NULLF) cfg.wb = preserve_wb;
 
222
        cfg.curveLoad = load_preserve;
 
223
        if (cfg.exposureLoad!=load_auto ||
 
224
                exposure!=NULLF || blackPoint!=NULLF)
 
225
            cfg.exposureLoad = load_preserve;
 
226
        if (isnan(cfg.exposure) && exposure==NULLF && blackPoint!=NULLF)
 
227
            exposure = cfg_default.exposure;
 
228
        if (outPath==NULL) outPath = "";
 
229
        cfg.overwrite = FALSE;
 
230
    }
 
231
    if (overwrite!=-1) cfg.overwrite = overwrite;
 
232
    if (unclip!=-1) cfg.unclip = unclip;
 
233
    if (losslessCompress!=-1) cfg.losslessCompress = losslessCompress;
 
234
    if (compression!=NULLF) cfg.compression = compression;
 
235
    if (exposure!=NULLF) cfg.exposure = exposure;
 
236
    if (temperature!=NULLF) cfg.temperature = temperature;
 
237
    if (green!=NULLF) cfg.green = green;
 
238
    if (shrink!=NULLF) cfg.shrink = shrink;
 
239
    if (wbName!=NULL) {
 
240
        if (!strcmp(wbName, "camera")) cfg.wb = camera_wb;
 
241
        else if (!strcmp(wbName, "auto")) cfg.wb = auto_wb;
 
242
        else {
 
243
            ufraw_message(UFRAW_ERROR,
 
244
                "'%s' is not a valid white balance option.\n", wbName);
 
245
            exit(1);
 
246
        }
 
247
    }
 
248
    curveType = camera_curve;
 
249
    if (curveName!=NULL) {
 
250
        if (!strcmp(curveName, "gamma")) cfg.curveIndex = gamma_curve;
 
251
        else if (!strcmp(curveName, "log")) cfg.curveIndex = log_curve;
 
252
        else if (!strcmp(curveName, "linear")) cfg.curveIndex=linear_curve;
 
253
        else if (!strcmp(curveName, "camera")) cfg.curveIndex=camera_curve;
 
254
        else {
 
255
            ufraw_message(UFRAW_ERROR,
 
256
                "'%s' is not a valid curve name.\n", curveName);
 
257
            exit(1);
 
258
        }
 
259
    }
 
260
    if (contrast!=NULLF) cfg.curve[cfg.curveIndex].contrast = contrast;
 
261
    if (gamma!=NULLF) cfg.curve[cfg.curveIndex].gamma = gamma;
 
262
    if (saturation!=NULLF) cfg.curve[cfg.curveIndex].saturation=saturation;
 
263
    if (shadow!=NULLF) cfg.curve[cfg.curveIndex].shadow = shadow;
 
264
    if (shadowDepth!=NULLF) cfg.curve[cfg.curveIndex].depth = shadowDepth;
 
265
    if (blackPoint!=NULLF) cfg.curve[cfg.curveIndex].black = blackPoint;
 
266
    if (interpolationName!=NULL) {
 
267
        if (!strcmp(interpolationName, "full"))
 
268
            cfg.interpolation = full_interpolation;
 
269
        else if (!strcmp(interpolationName, "four-color"))
 
270
            cfg.interpolation = four_color_interpolation;
 
271
        else if (!strcmp(interpolationName, "quick"))
 
272
            cfg.interpolation = quick_interpolation;
 
273
        else if (!strcmp(interpolationName, "half"))
 
274
            cfg.interpolation = half_interpolation;
 
275
        else {
 
276
            ufraw_message(UFRAW_ERROR,
 
277
                "'%s' is not a valid interpolation option.\n",
 
278
                interpolationName);
 
279
            exit(1);
 
280
        }
 
281
    }
 
282
    if (outTypeName!=NULL) {
 
283
        if (!strcmp(outTypeName, "ppm8"))
 
284
            cfg.type = ppm8_type;
 
285
        else if (!strcmp(outTypeName, "ppm16"))
 
286
            cfg.type = ppm16_type;
 
287
        else if (!strcmp(outTypeName, "tiff8"))
 
288
#ifdef NO_TIFF
 
289
        {
 
290
            ufraw_message(UFRAW_ERROR,
 
291
                "ufraw was build without TIFF support.\n");
 
292
            exit(1);
 
293
        }
 
294
#else
 
295
        cfg.type = tiff8_type;
 
296
#endif
 
297
        else if (!strcmp(outTypeName, "tiff16"))
 
298
#ifdef NO_TIFF
 
299
        {
 
300
            ufraw_message(UFRAW_ERROR,
 
301
                "ufraw was build without TIFF support.\n");
 
302
            exit(1);
 
303
        }
 
304
#else
 
305
        cfg.type = tiff16_type;
 
306
#endif
 
307
        else if (!strcmp(outTypeName, "jpeg"))
 
308
#ifdef NO_JPEG
 
309
        {
 
310
            ufraw_message(UFRAW_ERROR,
 
311
                "ufraw was build without JPEG support.\n");
 
312
            exit(1);
 
313
        }
 
314
#else
 
315
        cfg.type = jpeg_type;
 
316
#endif
 
317
        else {
 
318
            ufraw_message(UFRAW_ERROR,
 
319
                "'%s' is not a valid output type.\n", outTypeName);
 
320
            exit(1);
 
321
        }
 
322
    }
 
323
    if (optind==argc) {
 
324
        if (batch) ufraw_message(UFRAW_WARNING, 
 
325
                "no input file, nothing to do.\n")
 
326
        else ufraw_chooser(&cfg);
 
327
        exit(0);
 
328
    }
 
329
    for (; optind<argc; optind++) {
 
330
        image = ufraw_open(argv[optind]);
 
331
        if (image==NULL) {
 
332
            ufraw_message(UFRAW_REPORT, NULL);
 
333
            continue;    
 
334
        }
 
335
        ufraw_config(image, &cfg);
 
336
        if (batch) {
 
337
            if (ufraw_load_raw(image, FALSE)!=UFRAW_SUCCESS)
 
338
                continue;
 
339
            ufraw_message(UFRAW_MESSAGE, "loaded %s\n",
 
340
                image->filename);
 
341
            g_strlcpy(cfg.outputFilename, outPath, max_path);
 
342
            if (ufraw_saver(NULL, image)==UFRAW_SUCCESS)
 
343
                ufraw_message(UFRAW_MESSAGE, "saved %s\n", cfg.outputFilename);
 
344
            ufraw_close(image);
 
345
            g_free(image);
 
346
        } else {
 
347
            ufraw_preview(image, FALSE, ufraw_saver);
 
348
        }
 
349
    }
 
350
    if (dummyWindow!=NULL) gtk_widget_destroy(dummyWindow);
 
351
    exit(0);
 
352
}
 
353
 
 
354
void ufraw_radio_button_update(GtkWidget *button, int *valuep)
 
355
{
 
356
    char *filename, newFilename[max_path], *cp;
 
357
    GtkWidget *dialog = gtk_widget_get_ancestor(button, GTK_TYPE_DIALOG);
 
358
    if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)))
 
359
        return;
 
360
    *valuep = (long)g_object_get_data(G_OBJECT(button), "ButtonValue");
 
361
    filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
 
362
    g_strlcpy(newFilename, filename, max_path);
 
363
    g_free(filename);
 
364
    if ( (cp=strrchr(newFilename, '.'))!=NULL) *cp= '\0';
 
365
    g_strlcat(newFilename, file_type[*valuep], max_path);
 
366
    if ( (cp=strrchr(newFilename, '/'))!=NULL) cp++;
 
367
    else if ( (cp=strrchr(newFilename, '\\'))!=NULL) cp++;
 
368
    else cp = newFilename;
 
369
    gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), cp);
 
370
}
 
371
 
 
372
void ufraw_saver_set_type(GtkWidget *widget, cfg_data *cfg)
 
373
{
 
374
    char *filename, *type;
 
375
    filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(widget));
 
376
    type = strrchr(filename, '.');
 
377
    if (type==NULL) {
 
378
        g_free(filename);
 
379
        return;
 
380
    }
 
381
    if (!strcmp(type,".ppm") && cfg->type!=ppm16_type)
 
382
        cfg->type = ppm8_type;
 
383
    if (!strcmp(type,".tif") && cfg->type!=tiff16_type)
 
384
        cfg->type = tiff8_type;
 
385
    if (!strcmp(type,".jpg"))
 
386
        cfg->type = jpeg_type;
 
387
    g_free(filename);
 
388
    gtk_dialog_response(GTK_DIALOG(widget), GTK_RESPONSE_APPLY);
 
389
}
 
390
 
 
391
int ufraw_saver(GtkWidget *widget, gpointer user_data)
 
392
{
 
393
    GtkWindow *parentWindow;
 
394
    GtkFileChooser *fileChooser;
 
395
    GtkWidget *expander, *box, *table, *widg, *button, *overwriteButton;
 
396
    GtkAdjustment *shrinkAdj;
 
397
    GtkComboBox *intCombo;
 
398
    GtkToggleButton *ppmButton, *tiffButton, *jpegButton;
 
399
#if !defined(NO_TIFF) && !defined(NO_ZLIB)
 
400
    GtkWidget *losslessButton;
 
401
#endif
 
402
#ifndef NO_JPEG
 
403
    GtkAdjustment *compressAdj;
 
404
#endif
 
405
    image_data *image = user_data;
 
406
    char *filename, defFilename[max_path], *cp;
 
407
    int status;
 
408
 
 
409
    g_strlcpy(defFilename, image->filename, max_path);
 
410
    if ( (cp=strrchr(defFilename, '.'))!=NULL) *cp= '\0';
 
411
    g_strlcat(defFilename, file_type[image->cfg->type], max_path);
 
412
    if (widget==NULL) {
 
413
        if (strlen(image->cfg->outputFilename)>0) {
 
414
            cp = g_path_get_basename(defFilename);
 
415
            filename = g_build_filename(image->cfg->outputFilename, cp , NULL);
 
416
            g_strlcpy(defFilename, filename, max_path);
 
417
            g_free(filename);
 
418
            g_free(cp);
 
419
        }
 
420
        if (!image->cfg->overwrite) {
 
421
            if (g_file_test(defFilename, G_FILE_TEST_EXISTS)) {
 
422
                char ans;
 
423
                fprintf(stderr, "ufraw: overwrite '%s'? [y/N] ", defFilename);
 
424
                fflush(stderr);
 
425
                scanf("%c", &ans);
 
426
                if (ans!='y' && ans!='Y') return UFRAW_CANCEL;
 
427
            }
 
428
        }
 
429
        return ufraw_write_image(image, defFilename);
 
430
    }
 
431
    parentWindow = GTK_WINDOW(gtk_widget_get_toplevel(widget));
 
432
    fileChooser = GTK_FILE_CHOOSER(gtk_file_chooser_dialog_new(
 
433
            "Save image", parentWindow, GTK_FILE_CHOOSER_ACTION_SAVE,
 
434
            GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
 
435
            GTK_STOCK_SAVE, GTK_RESPONSE_OK, NULL));
 
436
    gtk_dialog_set_default_response(GTK_DIALOG(fileChooser), GTK_RESPONSE_OK);
 
437
    ufraw_message_handler(UFRAW_SET_PARENT, (char *)fileChooser);
 
438
    if (strlen(image->cfg->outputFilename)>0) {
 
439
        if (g_path_is_absolute(image->cfg->outputFilename))
 
440
            gtk_file_chooser_set_current_folder(fileChooser,
 
441
                    image->cfg->outputFilename);
 
442
        else {
 
443
            char *cd = g_get_current_dir();
 
444
            char *fn = g_build_filename(cd, image->cfg->outputFilename, NULL);
 
445
            gtk_file_chooser_set_current_folder(fileChooser, fn);
 
446
            g_free(cd);
 
447
            g_free(fn);
 
448
        }
 
449
    }
 
450
    expander = gtk_expander_new("Output options");
 
451
    gtk_expander_set_expanded(GTK_EXPANDER(expander), TRUE);
 
452
    gtk_file_chooser_set_extra_widget(fileChooser, expander);
 
453
    box = gtk_vbox_new(FALSE, 0);
 
454
    gtk_container_add(GTK_CONTAINER(expander), box);
 
455
    table = gtk_table_new(5, 1, FALSE);
 
456
    gtk_box_pack_start(GTK_BOX(box), table, TRUE, TRUE, 0);
 
457
    if (image->cfg->interpolation==half_interpolation) {
 
458
        image->cfg->interpolation = full_interpolation;
 
459
        if (image->cfg->shrink<2) image->cfg->shrink = 2;
 
460
    }
 
461
    intCombo = GTK_COMBO_BOX(gtk_combo_box_new_text());
 
462
    gtk_combo_box_append_text(intCombo, "Full interpolation");
 
463
    gtk_combo_box_append_text(intCombo, "Four color interpolation");
 
464
    gtk_combo_box_append_text(intCombo, "Quick interpolation");
 
465
    gtk_combo_box_set_active(intCombo, image->cfg->interpolation);
 
466
    gtk_table_attach(GTK_TABLE(table), GTK_WIDGET(intCombo),
 
467
                0, 3, 0, 1, 0, 0, 0, 0);
 
468
    widg = gtk_label_new("Shrink factor");
 
469
    gtk_table_attach(GTK_TABLE(table), widg, 0, 1, 1, 2, 0, 0, 0, 0);
 
470
    shrinkAdj = GTK_ADJUSTMENT(gtk_adjustment_new(image->cfg->shrink,
 
471
            1, 100, 1, 2, 0));
 
472
    widg = gtk_spin_button_new(shrinkAdj, 1, 0);
 
473
    gtk_table_attach(GTK_TABLE(table), widg, 1, 2, 1, 2, 0, 0, 0, 0);
 
474
 
 
475
    gtk_box_pack_start(GTK_BOX(box), gtk_hseparator_new(), TRUE, TRUE, 0);
 
476
    button = gtk_radio_button_new_with_label(NULL, "8-bit ppm");
 
477
    ppmButton = GTK_TOGGLE_BUTTON(button);
 
478
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button),
 
479
            image->cfg->type==ppm8_type);
 
480
    g_object_set_data(G_OBJECT(button), "ButtonValue", (gpointer)ppm8_type);
 
481
    g_signal_connect(G_OBJECT(button), "toggled",
 
482
            G_CALLBACK(ufraw_radio_button_update), &image->cfg->type);
 
483
    gtk_box_pack_start(GTK_BOX(box), button, TRUE, TRUE, 0);
 
484
 
 
485
    button = gtk_radio_button_new_with_label_from_widget(
 
486
            GTK_RADIO_BUTTON(button), "16-bit ppm");
 
487
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button),
 
488
            image->cfg->type==ppm16_type);
 
489
    g_object_set_data(G_OBJECT(button), "ButtonValue", (gpointer)ppm16_type);
 
490
    g_signal_connect(G_OBJECT(button), "toggled",
 
491
            G_CALLBACK(ufraw_radio_button_update), &image->cfg->type);
 
492
    gtk_box_pack_start(GTK_BOX(box), button, TRUE, TRUE, 0);
 
493
#ifndef NO_TIFF
 
494
    gtk_box_pack_start(GTK_BOX(box), gtk_hseparator_new(), TRUE, TRUE, 0);
 
495
    table = gtk_table_new(5, 1, FALSE);
 
496
    gtk_box_pack_start(GTK_BOX(box), table, TRUE, TRUE, 0);
 
497
    button = gtk_radio_button_new_with_label_from_widget(
 
498
            GTK_RADIO_BUTTON(button), "8-bit TIFF");
 
499
    tiffButton = GTK_TOGGLE_BUTTON(button);
 
500
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button),
 
501
            image->cfg->type==tiff8_type);
 
502
    g_object_set_data(G_OBJECT(button), "ButtonValue", (gpointer)tiff8_type);
 
503
    g_signal_connect(G_OBJECT(button), "toggled",
 
504
            G_CALLBACK(ufraw_radio_button_update), &image->cfg->type);
 
505
    gtk_table_attach(GTK_TABLE(table), button, 0, 1, 0, 1, 0, 0, 0, 0);
 
506
    button = gtk_radio_button_new_with_label_from_widget(
 
507
            GTK_RADIO_BUTTON(button), "16-bit TIFF");
 
508
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button),
 
509
            image->cfg->type==tiff16_type);
 
510
    g_object_set_data(G_OBJECT(button), "ButtonValue", (gpointer)tiff16_type);
 
511
    g_signal_connect(G_OBJECT(button), "toggled",
 
512
            G_CALLBACK(ufraw_radio_button_update), &image->cfg->type);
 
513
    gtk_table_attach(GTK_TABLE(table), button, 0, 1, 1, 2, 0, 0, 0, 0);
 
514
#endif /*NO_TIFF*/
 
515
#if !defined(NO_TIFF) && !defined(NO_ZLIB)
 
516
    losslessButton = gtk_check_button_new_with_label("ZIP Compress (lossless)");
 
517
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(losslessButton),
 
518
                    image->cfg->losslessCompress);
 
519
    gtk_table_attach(GTK_TABLE(table), losslessButton, 1, 2, 2, 3, 0, 0, 0, 0);
 
520
#endif
 
521
#ifndef NO_JPEG
 
522
    gtk_box_pack_start(GTK_BOX(box), gtk_hseparator_new(), TRUE, TRUE, 0);
 
523
    table = gtk_table_new(5, 1, FALSE);
 
524
    gtk_box_pack_start(GTK_BOX(box), table, TRUE, TRUE, 0);
 
525
    button = gtk_radio_button_new_with_label_from_widget(
 
526
            GTK_RADIO_BUTTON(button), "JPEG");
 
527
    jpegButton = GTK_TOGGLE_BUTTON(button);
 
528
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button),
 
529
            image->cfg->type==jpeg_type);
 
530
    g_object_set_data(G_OBJECT(button), "ButtonValue", (gpointer)jpeg_type);
 
531
    g_signal_connect(G_OBJECT(button), "toggled",
 
532
            G_CALLBACK(ufraw_radio_button_update), &image->cfg->type);
 
533
    gtk_table_attach(GTK_TABLE(table), button, 0, 1, 0, 1, 0, 0, 0, 0);
 
534
    widg = gtk_label_new("Compression level");
 
535
    gtk_table_attach(GTK_TABLE(table), widg, 1, 2, 1, 2, 0, 0, 0, 0);
 
536
    compressAdj = GTK_ADJUSTMENT(gtk_adjustment_new(image->cfg->compression,
 
537
            0, 100, 5, 10, 0));
 
538
    widg = gtk_hscale_new(compressAdj);
 
539
    gtk_scale_set_draw_value(GTK_SCALE(widg), FALSE);
 
540
    gtk_table_attach(GTK_TABLE(table), widg, 2, 3, 1, 2,
 
541
            GTK_EXPAND|GTK_FILL, 0, 0, 0);
 
542
    widg = gtk_spin_button_new(compressAdj, 5, 0);
 
543
    gtk_table_attach(GTK_TABLE(table), widg, 3, 4, 1, 2, 0, 0, 0, 0);
 
544
#endif /*NO_JPEG*/
 
545
    gtk_box_pack_start(GTK_BOX(box), gtk_hseparator_new(), TRUE, TRUE, 0);
 
546
    overwriteButton = gtk_check_button_new_with_label(
 
547
            "Overwrite existing files without asking");
 
548
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(overwriteButton),
 
549
            image->cfg->overwrite);
 
550
    gtk_box_pack_start(GTK_BOX(box), overwriteButton, TRUE, TRUE, 0);
 
551
    gtk_widget_show_all(expander);
 
552
    if ( (cp=strrchr(defFilename, '/'))!=NULL) cp++;
 
553
    else if ( (cp=strrchr(defFilename, '\\'))!=NULL) cp++;
 
554
    else cp = defFilename;
 
555
    gtk_file_chooser_set_current_name(fileChooser, cp);
 
556
    if (strlen(image->cfg->inputFilename)>0) {
 
557
        char *cp = g_path_get_dirname(image->cfg->inputFilename);
 
558
        if (strcmp(cp,"."))
 
559
        gtk_file_chooser_add_shortcut_folder( fileChooser, cp, NULL);
 
560
        g_free(cp);
 
561
    }
 
562
    g_signal_connect(G_OBJECT(fileChooser), "selection-changed",
 
563
            G_CALLBACK(ufraw_saver_set_type), image->cfg);
 
564
    while(1) {
 
565
        status = gtk_dialog_run(GTK_DIALOG(fileChooser));
 
566
        if (status==GTK_RESPONSE_CANCEL) {
 
567
            gtk_widget_destroy(GTK_WIDGET(fileChooser));
 
568
            ufraw_message_handler(UFRAW_SET_PARENT, (char *)parentWindow);
 
569
            return UFRAW_CANCEL;
 
570
        }
 
571
        if (status==GTK_RESPONSE_APPLY) {
 
572
            gtk_toggle_button_set_active(ppmButton,
 
573
                    image->cfg->type==ppm8_type);
 
574
            gtk_toggle_button_set_active(tiffButton,
 
575
                    image->cfg->type==tiff8_type);
 
576
            gtk_toggle_button_set_active(jpegButton,
 
577
                    image->cfg->type==jpeg_type);
 
578
            continue;
 
579
        }
 
580
        filename = gtk_file_chooser_get_filename(fileChooser);
 
581
        image->cfg->interpolation = gtk_combo_box_get_active(intCombo);
 
582
        image->cfg->shrink = gtk_adjustment_get_value(shrinkAdj);
 
583
        image->cfg->overwrite = gtk_toggle_button_get_active(
 
584
                GTK_TOGGLE_BUTTON(overwriteButton));
 
585
#if !defined(NO_TIFF) && !defined(NO_ZLIB)
 
586
        image->cfg->losslessCompress = gtk_toggle_button_get_active(
 
587
                GTK_TOGGLE_BUTTON(losslessButton));
 
588
#endif
 
589
#ifndef NO_JPEG
 
590
        image->cfg->compression = gtk_adjustment_get_value(compressAdj);
 
591
#endif
 
592
        if (!image->cfg->overwrite && g_file_test(filename, G_FILE_TEST_EXISTS))
 
593
        {
 
594
            GtkWidget *dialog;
 
595
            char message[max_path];
 
596
            int response;
 
597
            dialog = gtk_dialog_new_with_buttons("File exists",
 
598
                GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(fileChooser))),
 
599
                GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
 
600
                GTK_STOCK_NO, GTK_RESPONSE_NO,
 
601
                GTK_STOCK_YES, GTK_RESPONSE_YES, NULL);
 
602
            snprintf(message, max_path,
 
603
                "File '%s' already exists.\nOverwrite?", filename);
 
604
            widg = gtk_label_new(message);
 
605
            gtk_label_set_line_wrap(GTK_LABEL(widg), TRUE);
 
606
            gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), widg);
 
607
            gtk_widget_show_all(dialog);
 
608
            response = gtk_dialog_run(GTK_DIALOG(dialog));
 
609
            gtk_widget_destroy(dialog);
 
610
            if (response!=GTK_RESPONSE_YES)
 
611
                continue;
 
612
        }
 
613
        status = ufraw_write_image(image, filename);
 
614
        g_free(filename);
 
615
        if (status==UFRAW_SUCCESS || status==UFRAW_ABORT_SAVE) {
 
616
            gtk_widget_destroy(GTK_WIDGET(fileChooser));
 
617
            ufraw_message_handler(UFRAW_SET_PARENT, (char *)parentWindow);
 
618
            if (status==UFRAW_SUCCESS)
 
619
                g_object_set_data(G_OBJECT(parentWindow), "WindowResponse",
 
620
                        (gpointer)GTK_RESPONSE_OK);
 
621
            else
 
622
                g_object_set_data(G_OBJECT(parentWindow), "WindowResponse",
 
623
                        (gpointer)GTK_RESPONSE_CANCEL);
 
624
            gtk_main_quit();
 
625
            return UFRAW_SUCCESS;
 
626
        }
 
627
    }
 
628
}
 
629
 
 
630
#ifndef NO_TIFF
 
631
void ufraw_tiff_message(const char *module, const char *fmt, va_list ap)
 
632
{
 
633
    module = module;
 
634
    char buf[max_path];
 
635
    vsnprintf(buf, max_path, fmt, ap);
 
636
    ufraw_message(UFRAW_VERBOSE, buf);
 
637
}
 
638
#endif /*NO_TIFF*/
 
639
 
 
640
#ifndef NO_JPEG
 
641
void ufraw_jpeg_message(j_common_ptr cinfo)
 
642
{
 
643
    ufraw_message(UFRAW_VERBOSE, cinfo->err->jpeg_message_table
 
644
            [cinfo->err->msg_code],
 
645
            cinfo->err->msg_parm.i[0],
 
646
            cinfo->err->msg_parm.i[1],
 
647
            cinfo->err->msg_parm.i[2],
 
648
            cinfo->err->msg_parm.i[3]);
 
649
}
 
650
#endif /*NO_JPEG*/
 
651
 
 
652
int ufraw_write_image(image_data *image, char *outFilename)
 
653
{
 
654
    void *out; /* out is a pointer to FILE or TIFF */
 
655
    int row, rowStride, i, status=UFRAW_SUCCESS;
 
656
    image_type *rawImage;
 
657
    guint8 *pixbuf8=NULL;
 
658
    guint16 *pixbuf16;
 
659
    char *message;
 
660
    message = message;
 
661
    ufraw_message(UFRAW_CLEAN, NULL);
 
662
#ifndef NO_TIFF
 
663
    if (image->cfg->type==tiff8_type || image->cfg->type==tiff16_type) {
 
664
        TIFFSetErrorHandler(ufraw_tiff_message);
 
665
        TIFFSetWarningHandler(ufraw_tiff_message);
 
666
        if ( (out=TIFFOpen(outFilename, "w"))==NULL ) {
 
667
            message=ufraw_message_handler(UFRAW_GET_MESSAGE, NULL);
 
668
            ufraw_message(UFRAW_ERROR, "Error creating file '%s'.\n%s",
 
669
                    outFilename, message);
 
670
            return UFRAW_ERROR;
 
671
        }
 
672
    } else
 
673
#endif
 
674
        if ( (out=fopen(outFilename, "wb"))==NULL) {
 
675
            ufraw_message(UFRAW_ERROR, "Error creating file '%s': %s",
 
676
                    outFilename, g_strerror(errno));
 
677
            return UFRAW_ERROR;
 
678
        }
 
679
    ufraw_convert_image(image, image);
 
680
    ufraw_message(UFRAW_CLEAN, NULL);
 
681
    rowStride = image->width + 2*image->trim;
 
682
    rawImage = image->image + image->trim*rowStride + image->trim;
 
683
    pixbuf16 = g_new(guint16, image->width*3);
 
684
    if (image->cfg->type==ppm8_type) {
 
685
        fprintf(out, "P6\n%d %d\n%d\n", image->width, image->height, 0xFF);
 
686
        pixbuf8 = g_new(guint8, image->width*3);
 
687
        for (row=0; row<image->height; row++) {
 
688
            if (row%100==99)
 
689
                preview_progress("Saving image", 0.5 + 0.5*row/image->height);
 
690
            develope(pixbuf8, rawImage[row*rowStride],
 
691
                    image->developer, 8, pixbuf16, image->width);
 
692
            if ((int)fwrite(pixbuf8, 3, image->width, out)<image->width) {
 
693
                ufraw_message(UFRAW_ERROR, "Error creating file '%s': %s.",
 
694
                        outFilename, g_strerror(errno));
 
695
                status = UFRAW_ABORT_SAVE;
 
696
                break;
 
697
            }
 
698
        }
 
699
    } else if (image->cfg->type==ppm16_type) {
 
700
        fprintf(out, "P6\n%d %d\n%d\n", image->width, image->height, 0xFFFF);
 
701
        for (row=0; row<image->height; row++) {
 
702
            if (row%100==99)
 
703
                preview_progress("Saving image", 0.5 + 0.5*row/image->height);
 
704
            develope(pixbuf16, rawImage[row*rowStride],
 
705
                    image->developer, 16, pixbuf16, image->width);
 
706
            for (i=0; i<3*image->width; i++)
 
707
                pixbuf16[i] = g_htons(pixbuf16[i]);
 
708
            if ((int)fwrite(pixbuf16, 6, image->width, out)<image->width) {
 
709
                ufraw_message(UFRAW_ERROR, "Error creating file '%s': %s.",
 
710
                        outFilename, g_strerror(errno));
 
711
                status = UFRAW_ABORT_SAVE;
 
712
                break;
 
713
            }
 
714
        }
 
715
#ifndef NO_TIFF
 
716
    } else if (image->cfg->type==tiff8_type ||
 
717
            image->cfg->type==tiff16_type) {
 
718
        TIFFSetField(out, TIFFTAG_IMAGEWIDTH, image->width);
 
719
        TIFFSetField(out, TIFFTAG_IMAGELENGTH, image->height);
 
720
        TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
 
721
        TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, 3);
 
722
        if (image->cfg->type==tiff8_type)
 
723
            TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, 8);
 
724
        else
 
725
            TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, 16);
 
726
        TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
 
727
        TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
 
728
#ifndef NO_ZLIB
 
729
        if (image->cfg->losslessCompress) {
 
730
            TIFFSetField(out, TIFFTAG_COMPRESSION, COMPRESSION_DEFLATE);
 
731
            TIFFSetField(out, TIFFTAG_ZIPQUALITY, 9);
 
732
        }
 
733
        else
 
734
#endif
 
735
            TIFFSetField(out, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
 
736
        /* Embed output profile if it is not the internal sRGB*/
 
737
        if (strcmp(image->developer->file[out_profile], "")) {
 
738
            char *buf;
 
739
            int len;
 
740
            if (g_file_get_contents(image->developer->file[out_profile],
 
741
                &buf, &len, NULL)) {
 
742
            TIFFSetField(out, TIFFTAG_ICCPROFILE, len, buf);
 
743
            g_free(buf);
 
744
            } else ufraw_message(UFRAW_WARNING,
 
745
                    "Failed to embed output profile '%s' in '%s'",
 
746
                    image->developer->file[out_profile], outFilename);
 
747
        }
 
748
        TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(out, 0));
 
749
        if (image->cfg->type==tiff8_type) {
 
750
            pixbuf8 = g_new(guint8, image->width*3);
 
751
            for (row=0; row<image->height; row++) {
 
752
                if (row%100==99)
 
753
                    preview_progress("Saving image", 0.5+0.5*row/image->height);
 
754
                develope(pixbuf8, rawImage[row*rowStride],
 
755
                        image->developer, 8, pixbuf16, image->width);
 
756
                if (TIFFWriteScanline(out, pixbuf8, row, 0)<0) {
 
757
                    message=ufraw_message_handler(UFRAW_GET_MESSAGE, NULL);
 
758
                    ufraw_message(UFRAW_ERROR, "Error creating file '%s'.\n%s",
 
759
                            outFilename, message);
 
760
                    status = UFRAW_ABORT_SAVE;
 
761
                    break;
 
762
                }
 
763
            }
 
764
        } else {
 
765
            for (row=0; row<image->height; row++) {
 
766
                if (row%100==99)
 
767
                    preview_progress("Saving image", 0.5+0.5*row/image->height);
 
768
                develope(pixbuf16, rawImage[row*rowStride],
 
769
                        image->developer, 16, pixbuf16, image->width);
 
770
                if (TIFFWriteScanline(out, pixbuf16, row, 0)<0) {
 
771
                    message=ufraw_message_handler(UFRAW_GET_MESSAGE, NULL);
 
772
                    ufraw_message(UFRAW_ERROR, "Error creating file '%s'.\n%s",
 
773
                            outFilename, message);
 
774
                    status = UFRAW_ABORT_SAVE;
 
775
                    break;
 
776
                }
 
777
            }
 
778
        }
 
779
#endif /*NO_TIFF*/
 
780
#ifndef NO_JPEG
 
781
    } else if (image->cfg->type==jpeg_type) {
 
782
        struct jpeg_compress_struct cinfo;
 
783
        struct jpeg_error_mgr jerr;
 
784
 
 
785
        cinfo.err = jpeg_std_error(&jerr);
 
786
        cinfo.err->output_message = ufraw_jpeg_message;
 
787
        cinfo.err->error_exit = ufraw_jpeg_message;
 
788
        jpeg_create_compress(&cinfo);
 
789
        jpeg_stdio_dest(&cinfo, out);
 
790
        cinfo.image_width = image->width;
 
791
        cinfo.image_height = image->height;
 
792
        cinfo.input_components = 3;
 
793
        cinfo.in_color_space = JCS_RGB;
 
794
        jpeg_set_defaults(&cinfo);
 
795
        jpeg_set_quality(&cinfo, image->cfg->compression, TRUE);
 
796
        /* Embed output profile if it is not the internal sRGB*/
 
797
        if (strcmp(image->developer->file[out_profile], "")) {
 
798
            char *buf;
 
799
            int len;
 
800
            if (g_file_get_contents(image->developer->file[out_profile],
 
801
                    &buf, &len, NULL)) {
 
802
                write_icc_profile(&cinfo, buf, len);
 
803
                g_free(buf);
 
804
            } else ufraw_message(UFRAW_WARNING,
 
805
                    "Failed to embed output profile '%s' in '%s'",
 
806
                    image->developer->file[out_profile], outFilename);
 
807
        }
 
808
        jpeg_start_compress(&cinfo, TRUE);
 
809
        message=ufraw_message_handler(UFRAW_GET_MESSAGE, NULL);
 
810
        pixbuf8 = g_new(guint8, image->width*3);
 
811
        for (row=0; row<image->height; row++) {
 
812
            if (row%100==99)
 
813
                preview_progress("Saving image", 0.5 + 0.5*row/image->height);
 
814
            develope(pixbuf8, rawImage[row*rowStride],
 
815
                    image->developer, 8, pixbuf16, image->width);
 
816
            jpeg_write_scanlines(&cinfo, &pixbuf8, 1);
 
817
            message=ufraw_message_handler(UFRAW_GET_MESSAGE, NULL);
 
818
            if (message!=NULL ) break;
 
819
        }
 
820
        if (message==NULL) jpeg_finish_compress(&cinfo);
 
821
        jpeg_destroy_compress(&cinfo);
 
822
        if ( (message=ufraw_message_handler(UFRAW_GET_MESSAGE, NULL))!=NULL) {
 
823
            ufraw_message(UFRAW_ERROR, "Error creating file '%s'.\n%s",
 
824
                    outFilename, message);
 
825
            status = UFRAW_ABORT_SAVE;
 
826
        }
 
827
#endif /*NO_JPEG*/
 
828
    } else {
 
829
        ufraw_message(UFRAW_ERROR,
 
830
                "Error creating file '%s'. Unknown file type %d.",
 
831
                outFilename, image->cfg->type);
 
832
        status = UFRAW_ABORT_SAVE;
 
833
    }
 
834
    g_free(pixbuf16);
 
835
    g_free(pixbuf8);
 
836
#ifndef NO_TIFF
 
837
    if (image->cfg->type==tiff8_type || image->cfg->type==tiff16_type) {
 
838
        TIFFClose(out);
 
839
        if ( (message=ufraw_message_handler(UFRAW_GET_MESSAGE, NULL))!=NULL) {
 
840
            ufraw_message(UFRAW_ERROR, "Error creating file '%s'.\n%s",
 
841
                    outFilename, message);
 
842
            status = UFRAW_ABORT_SAVE;
 
843
        }
 
844
    } else
 
845
#endif
 
846
        fclose(out);
 
847
    if (status==UFRAW_SUCCESS)
 
848
        g_strlcpy(image->cfg->outputFilename, outFilename, max_path);
 
849
    return status;
 
850
}
 
851
 
 
852
void ufraw_chooser(cfg_data *cfg)
 
853
{
 
854
    image_data *image;
 
855
    GtkFileChooser *fileChooser;
 
856
    GSList *list, *saveList;
 
857
    GtkFileFilter *filter;
 
858
    char *filename, *cp;
 
859
    char **extList, **l, ext[max_name];
 
860
 
 
861
    fileChooser = GTK_FILE_CHOOSER(gtk_file_chooser_dialog_new("UFRaw", NULL,
 
862
            GTK_FILE_CHOOSER_ACTION_OPEN,
 
863
            GTK_STOCK_QUIT, GTK_RESPONSE_CANCEL,
 
864
            GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL));
 
865
    gtk_window_set_icon(GTK_WINDOW(fileChooser),
 
866
            gdk_pixbuf_new_from_inline(-1, ufraw_icon, FALSE, NULL));
 
867
    ufraw_message_handler(UFRAW_SET_PARENT, (char *)fileChooser);
 
868
    filter = GTK_FILE_FILTER(gtk_file_filter_new());
 
869
    gtk_file_filter_set_name(filter, "Raw images");
 
870
    extList = g_strsplit(raw_ext, ",", 100);
 
871
    for (l=extList; *l!=NULL; l++)
 
872
        if (strcmp(*l, "jpg") && strcmp(*l, "tif")) {
 
873
            snprintf(ext, max_name, "*.%s", *l);
 
874
            gtk_file_filter_add_pattern(filter, ext);
 
875
            gtk_file_filter_add_pattern(filter, cp=g_ascii_strup(ext,-1));
 
876
            g_free(cp);
 
877
        }
 
878
    g_strfreev(extList);
 
879
    gtk_file_chooser_add_filter(fileChooser, filter);
 
880
    filter = GTK_FILE_FILTER(gtk_file_filter_new());
 
881
    gtk_file_filter_set_name(filter, "Raw jpg's");
 
882
    gtk_file_filter_add_pattern(filter, "*.jpg");
 
883
    gtk_file_filter_add_pattern(filter, "*.JPG");
 
884
    gtk_file_chooser_add_filter(fileChooser, filter);
 
885
    filter = GTK_FILE_FILTER(gtk_file_filter_new());
 
886
    gtk_file_filter_set_name(filter, "Raw tif's");
 
887
    gtk_file_filter_add_pattern(filter, "*.tif");
 
888
    gtk_file_filter_add_pattern(filter, "*.TIF");
 
889
    gtk_file_chooser_add_filter(fileChooser, filter);
 
890
    filter = GTK_FILE_FILTER(gtk_file_filter_new());
 
891
    gtk_file_filter_set_name(filter, "All files");
 
892
    gtk_file_filter_add_pattern(filter, "*");
 
893
    gtk_file_chooser_add_filter(fileChooser, filter);
 
894
    gtk_widget_show(GTK_WIDGET(fileChooser));
 
895
    gtk_file_chooser_set_select_multiple(fileChooser, TRUE);
 
896
    /* Add shortcut to folder of last opened file */
 
897
    if (strlen(cfg->inputFilename)>0) {
 
898
        char *cp = g_path_get_dirname(cfg->inputFilename);
 
899
        gtk_file_chooser_add_shortcut_folder( fileChooser, cp, NULL);
 
900
        g_free(cp);
 
901
    }
 
902
    while (gtk_dialog_run(GTK_DIALOG(fileChooser))==GTK_RESPONSE_ACCEPT) {
 
903
        for(list=saveList=gtk_file_chooser_get_filenames(fileChooser);
 
904
        list!=NULL; list=g_slist_next(list)) {
 
905
            filename = list->data;
 
906
            image = ufraw_open(filename);
 
907
            if (image==NULL) {
 
908
                ufraw_message(UFRAW_REPORT, NULL);
 
909
                continue;
 
910
            }
 
911
            ufraw_config(image, cfg);
 
912
            ufraw_preview(image, FALSE, ufraw_saver);
 
913
            g_free(filename);
 
914
        }
 
915
        g_slist_free(saveList);
 
916
    }
 
917
    gtk_widget_destroy(GTK_WIDGET(fileChooser));
 
918
    ufraw_message_handler(UFRAW_SET_PARENT, NULL);
 
919
}