d2/align, d2/image_rw: following recent migration *_map_* -> eval, replace SET_*...
[Ale.git] / d2 / image_rw.h
Commit [+] Author Date Line Data
30afe4b6 dhilvert2005-01-07 06:42:00 +00001// Copyright 2002 David Hilvert <dhilvert@auricle.dyndns.org>,
2// <dhilvert@ugcs.caltech.edu>
3
4/* This file is part of the Anti-Lamenessing Engine.
5
6 The Anti-Lamenessing Engine is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
70932f40 David Hilvert2007-07-19 21:14:00 +00008 the Free Software Foundation; either version 3 of the License, or
30afe4b6 dhilvert2005-01-07 06:42:00 +00009 (at your option) any later version.
10
11 The Anti-Lamenessing Engine 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 the Anti-Lamenessing Engine; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19*/
20
21/*
22 * image_rw.h: Read and write images.
23 */
24
25
26#ifndef __image_rw_h__
27#define __image_rw_h__
28
29#include "image.h"
46f9776a dhilvert2005-01-07 06:44:00 +000030#include "image_ale_real.h"
31#include "image_bayer_ale_real.h"
aab588ef David Hilvert2008-10-19 06:44:40 +000032#include "image_accel.h"
30afe4b6 dhilvert2005-01-07 06:42:00 +000033#include "ppm.h"
34#include "exposure/exposure.h"
35#include "exposure/exposure_default.h"
36
37class image_rw {
38
39 /*
40 * Private data members
41 */
42
43 /*
44 * PPM type
45 *
46 * 0 = No type selected
47 * 1 = PPM Raw
48 * 2 = PPM Plain
49 */
50 static int ppm_type;
51
52 /*
53 * Bit depth
54 */
55 static unsigned int num_bits;
56 static unsigned int mcv;
57
58 /*
561693b7 dhilvert2005-12-17 19:48:00 +000059 * Nearest-neighbor defined value radius.
60 */
61 static double nn_defined_radius;
62
63 /*
30afe4b6 dhilvert2005-01-07 06:42:00 +000064 * Input and output exposure models
65 */
1adb31c9 dhilvert2005-01-07 06:45:00 +000066 static exposure **input_exposure;
30afe4b6 dhilvert2005-01-07 06:42:00 +000067 static exposure *output_exposure;
46f9776a dhilvert2005-01-07 06:44:00 +000068 static int exposure_scale;
69
70 /*
71 * Default bayer pattern
72 */
1adb31c9 dhilvert2005-01-07 06:45:00 +000073 static unsigned int bayer_default;
74
75 /*
76 * Image-specific bayer patterns.
77 */
78 static unsigned int *bayer_specific;
30afe4b6 dhilvert2005-01-07 06:42:00 +000079
80 /*
81 * Pointer to the output filename
82 */
83 static const char *output_filename;
84
85 /*
86 * Variables relating to input image files and image data structures.
87 */
88 static const char **filenames;
46f9776a dhilvert2005-01-07 06:44:00 +000089 static unsigned int file_count;
11eef435 David Hilvert2009-05-05 23:30:46 +000090 static ale_image *images;
30afe4b6 dhilvert2005-01-07 06:42:00 +000091 static int *files_open;
92
93 /*
94 * The most recently closed image number.
95 */
96 static int latest_close_num;
97
98 /*
91e5ac67
DH
David Hilvert2007-05-04 02:09:00 +000099 * Actual cache size.
100 */
101 static double cache_size;
102
103 /*
104 * Number of cached files.
105 */
106 static unsigned int cache_count;
30afe4b6 dhilvert2005-01-07 06:42:00 +0000107
108 /*
109 * Private methods to init and shut down the file reader.
110 */
111
112 /*
113 * Initialize the image file handler
114 */
115 static void init_image() {
116#ifdef USE_MAGICK
117 InitializeMagick("ale");
118#endif
119 }
120
121 /*
122 * Destroy the image file handler
123 */
124 static void destroy_image() {
125#ifdef USE_MAGICK
126 DestroyMagick();
127#endif
128 }
129
85d4c604 David Hilvert2009-05-29 01:59:59 +0000130 static ale_image read_image_im(const char *filename, exposure *exp, const char *name,
b1a86246 David Hilvert2008-07-02 04:45:08 +0000131 unsigned int bayer, int init_reference_gain) {
91510fab David Hilvert2009-03-30 19:52:53 +0000132 static int warned = 0;
c5b2f37a David Hilvert2008-08-18 17:33:50 -0500133#ifdef USE_MAGICK
5b090730 David Hilvert2008-09-21 20:09:44 +0000134
91510fab David Hilvert2009-03-30 19:52:53 +0000135 if (MaxRGB < 65535 && mcv == 65535 && !warned) {
c5ab1c56 David Hilvert2009-03-31 08:31:10 +0000136 fprintf(stderr, "\n\n*** Warning: " MagickPackageName " has not been compiled with 16 bit support.\n");
91510fab
DH
David Hilvert2009-03-30 19:52:53 +0000137 fprintf(stderr, "*** Reading input using 8 bits per channel.\n");
138 fprintf(stderr, "*** \n");
139 fprintf(stderr, "*** (To silence this warning, specify option --8bpc)\n\n\n");
140
141 warned = 1;
142 }
5b090730 David Hilvert2008-09-21 20:09:44 +0000143
30afe4b6 dhilvert2005-01-07 06:42:00 +0000144 /*
145 * Patterned after http://www.imagemagick.org/www/api.html
146 * and http://www.imagemagick.org/www/smile.c
147 */
148
149 ExceptionInfo exception;
150 Image *mi;
151 ImageInfo *image_info;
85d4c604
DH
David Hilvert2009-05-29 01:59:59 +0000152 ale_image im;
153 FILE *converted_f = tmpfile();
30afe4b6 dhilvert2005-01-07 06:42:00 +0000154 const PixelPacket *p;
155
156 unsigned int i, j;
157
7f589ee1 David Hilvert2007-07-16 22:35:00 +0000158 ale_real black_level = exp->get_black_level();
13e5484f David Hilvert2007-03-09 17:17:00 +0000159
30afe4b6 dhilvert2005-01-07 06:42:00 +0000160 GetExceptionInfo(&exception);
161 image_info = CloneImageInfo((ImageInfo *) NULL);
162
163 strncpy(image_info->filename, filename, MaxTextExtent);
164 mi = ReadImage(image_info, &exception);
165 if (exception.severity != UndefinedException) {
166 fprintf(stderr, "\n\n");
167 CatchException(&exception);
168 fprintf(stderr, "\n");
169 }
170 if (mi == (Image *) NULL)
171 exit(1);
172
85d4c604
DH
David Hilvert2009-05-29 01:59:59 +0000173 im = ale_new_image(accel::context(),
174 (bayer == IMAGE_BAYER_NONE) ? ALE_IMAGE_RGB : ALE_IMAGE_Y,
3f90494f
DH
David Hilvert2009-06-14 00:40:19 +0000175 (image_info->depth <= 8) ? ALE_TYPE_UINT_8 :
176 ((image_info->depth <= 16) ? ALE_TYPE_UINT_16 :
177 ((image_info->depth <= 32) ? ALE_TYPE_UINT_32 : ALE_TYPE_UINT_64)));
30afe4b6 dhilvert2005-01-07 06:42:00 +0000178
179 for (i = 0; i < mi->rows; i++) {
180 p = AcquireImagePixels(mi, 0, i, mi->columns, 1, &exception);
181
182 if (exception.severity != UndefinedException)
183 CatchException(&exception);
184 if (p == NULL)
185 exit(1);
186
187 for (j = 0; j < mi->columns; j++) {
85d4c604 David Hilvert2009-05-29 01:59:59 +0000188
3f90494f David Hilvert2009-06-14 00:40:19 +0000189 Quantum ival[3] = { p->red, p->green, p->blue };
30afe4b6 dhilvert2005-01-07 06:42:00 +0000190
85d4c604 David Hilvert2009-05-29 01:59:59 +0000191 for (int k = 0; k < 3; k++) {
262e16f5 David Hilvert2007-04-16 21:38:00 +0000192
85d4c604
DH
David Hilvert2009-05-29 01:59:59 +0000193 if (!ale_has_channel(i, j, k, bayer))
194 continue;
195
3f90494f
DH
David Hilvert2009-06-14 00:40:19 +0000196 if (image_info->depth <= 8) {
197 cl_uchar c = ival[k];
198 fwrite(&c, sizeof(cl_uchar), 1, converted_f);
199 } else if (image_info->depth <= 16) {
200 cl_ushort c = ival[k];
201 fwrite(&c, sizeof(cl_ushort), 1, converted_f);
202 } else if (image_info->depth <= 32) {
203 cl_uint c = ival[k];
204 fwrite(&c, sizeof(cl_uint), 1, converted_f);
205 } else if (image_info->depth <= 64) {
206 cl_ulong c = ival[k];
207 fwrite(&c, sizeof(cl_ulong), 1, converted_f);
208 } else {
209 fprintf(stderr, "error: unable to handle image depth %u\n", (unsigned int) image_info->depth);
210 exit(1);
211 }
85d4c604 David Hilvert2009-05-29 01:59:59 +0000212 }
30afe4b6 dhilvert2005-01-07 06:42:00 +0000213
214 p++;
215 }
216 }
217
85d4c604
DH
David Hilvert2009-05-29 01:59:59 +0000218 ale_image_set_file_static(im, mi->columns, mi->rows, converted_f, 0, ppm_void_file_close, converted_f);
219
30afe4b6 dhilvert2005-01-07 06:42:00 +0000220 DestroyImage(mi);
221 DestroyImageInfo(image_info);
222
223 return im;
c5b2f37a
DH
David Hilvert2008-08-18 17:33:50 -0500224#else
225 return NULL;
226#endif
b1a86246
DH
David Hilvert2008-07-02 04:45:08 +0000227 }
228
229public:
230
231 /*
232 * Read an image from a file
233 */
18bf24d9 David Hilvert2009-05-03 21:24:15 +0000234 static ale_image read_image(const char *filename, exposure *exp, const char *name = "file",
b1a86246 David Hilvert2008-07-02 04:45:08 +0000235 unsigned int bayer = IMAGE_BAYER_DEFAULT, int init_reference_gain = 0) {
18bf24d9 David Hilvert2009-05-03 21:24:15 +0000236 ale_image result;
086762a3 David Hilvert2008-07-09 00:06:39 +0000237
b1a86246
DH
David Hilvert2008-07-02 04:45:08 +0000238 if (bayer == IMAGE_BAYER_DEFAULT)
239 bayer = bayer_default;
240
241 if (is_eppm(filename)) {
086762a3 David Hilvert2008-07-09 00:06:39 +0000242 result = read_ppm(filename, exp, bayer, init_reference_gain);
b1a86246
DH
David Hilvert2008-07-02 04:45:08 +0000243 }
244
245#ifdef USE_MAGICK
18bf24d9 David Hilvert2009-05-03 21:24:15 +0000246 result = read_image_im(filename, exp, name, bayer, init_reference_gain);
30afe4b6 dhilvert2005-01-07 06:42:00 +0000247#else
086762a3 David Hilvert2008-07-09 00:06:39 +0000248 result = read_ppm(filename, exp, bayer);
30afe4b6 dhilvert2005-01-07 06:42:00 +0000249#endif
b1a86246 David Hilvert2008-07-02 04:45:08 +0000250
086762a3 David Hilvert2008-07-09 00:06:39 +0000251 return result;
30afe4b6 dhilvert2005-01-07 06:42:00 +0000252 }
253
30afe4b6 dhilvert2005-01-07 06:42:00 +0000254 /*
255 * Initializer.
256 *
257 * Handle FILE_COUNT input files with names in array FILENAMES and
258 * output file OUTPUT_FILENAME. FILENAMES should be an array of char *
259 * that is never freed. OUTPUT_FILENAME should be a char * that is
260 * never freed.
261 *
262 * INPUT_EXPOSURE should be an array of FILE_COUNT exposure objects
263 * that is never freed. OUTPUT_EXPOSURE should be an exposure * that
264 * is never freed.
265 */
46f9776a dhilvert2005-01-07 06:44:00 +0000266 static void init(unsigned int _file_count, const char **_filenames,
1adb31c9 dhilvert2005-01-07 06:45:00 +0000267 const char *_output_filename, exposure **_input_exposure,
30afe4b6 dhilvert2005-01-07 06:42:00 +0000268 exposure *_output_exposure){
269 assert (_file_count > 0);
270
271 init_image();
272
273 filenames = _filenames;
274 file_count = _file_count;
275 output_filename = _output_filename;
276 input_exposure = _input_exposure;
277 output_exposure = _output_exposure;
278
11eef435 David Hilvert2009-05-05 23:30:46 +0000279 images = (ale_image *)malloc(file_count * sizeof(ale_image));
1adb31c9 dhilvert2005-01-07 06:45:00 +0000280 bayer_specific = (unsigned int *)malloc(file_count * sizeof(unsigned int));
30afe4b6 dhilvert2005-01-07 06:42:00 +0000281 files_open = (int *)calloc(file_count, sizeof(int));
282
283 assert (images);
1adb31c9 dhilvert2005-01-07 06:45:00 +0000284 assert (bayer_specific);
30afe4b6 dhilvert2005-01-07 06:42:00 +0000285 assert (files_open);
286
1adb31c9 dhilvert2005-01-07 06:45:00 +0000287 if (!images || !files_open || !bayer_specific) {
30afe4b6 dhilvert2005-01-07 06:42:00 +0000288 fprintf(stderr, "Unable to allocate memory for images.\n");
289 exit(1);
290 }
291
1adb31c9 dhilvert2005-01-07 06:45:00 +0000292 for (unsigned int i = 0; i < file_count; i++)
293 bayer_specific[i] = IMAGE_BAYER_DEFAULT;
294
2cb0ebeb David Hilvert2007-04-16 19:41:00 +0000295 ui::get()->identify_output(output_filename);
30afe4b6 dhilvert2005-01-07 06:42:00 +0000296 }
297
298 static void ppm_plain() {
299 ppm_type = 2;
300 }
301
302 static void ppm_raw() {
303 ppm_type = 1;
304 }
305
306 static void ppm_auto() {
307#ifdef USE_MAGICK
308 ppm_type = 0;
309#else
310 fprintf(stderr, "\n\n*** Error: --auto flag not supported on this build. ***\n"
311 "*** (Hint: Rebuild with IMAGEMAGICK=1) ***\n\n");
312 exit(1);
313#endif
314 }
315
46f9776a dhilvert2005-01-07 06:44:00 +0000316 static void set_default_bayer(unsigned int b) {
1adb31c9 dhilvert2005-01-07 06:45:00 +0000317 bayer_default = b;
318 }
319
320 static void set_specific_bayer(unsigned int index, unsigned int b) {
321 assert (bayer_specific);
322 bayer_specific[index] = b;
46f9776a dhilvert2005-01-07 06:44:00 +0000323 }
324
30afe4b6 dhilvert2005-01-07 06:42:00 +0000325 static void depth16() {
326 num_bits = 16;
327 mcv = 65535;
328 }
329
330 static void depth8() {
331 num_bits = 8;
332 mcv = 255;
333 }
334
335 static void destroy() {
336 assert (file_count > 0);
337 destroy_image();
338 }
339
46f9776a dhilvert2005-01-07 06:44:00 +0000340 static unsigned int count() {
30afe4b6 dhilvert2005-01-07 06:42:00 +0000341 assert (file_count > 0);
342 return file_count;
343 }
344
46f9776a dhilvert2005-01-07 06:44:00 +0000345 static const char *name(unsigned int image) {
30afe4b6 dhilvert2005-01-07 06:42:00 +0000346 assert (image < file_count);
347
348 return filenames[image];
349 }
350
561693b7 dhilvert2005-12-17 19:48:00 +0000351 static void def_nn(double _nn) {
352 nn_defined_radius = _nn;
353 }
354
30afe4b6 dhilvert2005-01-07 06:42:00 +0000355 static const char *output_name() {
356 assert (file_count > 0);
357 return output_filename;
358 }
359
360 /*
361 * Write an image to a file
362 */
ac4577d5 David Hilvert2009-06-14 19:02:25 +0000363 static void write_image(const char *filename, ale_image im, double gamma = 0.45, int rezero = 0, int exp_scale_override = 0, int use_weights = 0) {
91510fab
DH
David Hilvert2009-03-30 19:52:53 +0000364 static int warned = 0;
365
c6351a11 dhilvert2005-10-03 21:20:00 +0000366 /*
367 * Handle ALE-specific magical filenames.
368 */
369
370 if (!strcmp(filename, "dump:")) {
621c5990
DH
David Hilvert2009-06-03 20:25:56 +0000371 FILE *image_data = ale_image_retain_file(im);
372
d8f91b46
DH
David Hilvert2009-06-04 01:08:33 +0000373 int format = ale_image_get_format(im);
374 int type = ale_image_get_type(im);
375
c6351a11 dhilvert2005-10-03 21:20:00 +0000376 fprintf(stderr, "Image dump: ");
621c5990
DH
David Hilvert2009-06-03 20:25:56 +0000377 for (unsigned int i = 0; i < ale_image_get_height(im); i++)
378 for (unsigned int j = 0; j < ale_image_get_width(im); j++) {
379 fprintf(stderr, "(%d, %d): ", i, j);
380
621c5990 David Hilvert2009-06-03 20:25:56 +0000381 fprintf(stderr, "[");
d8f91b46 David Hilvert2009-06-04 01:08:33 +0000382
621c5990 David Hilvert2009-06-03 20:25:56 +0000383 for (unsigned int k = 0; k < ale_image_get_depth(im); k++) {
621c5990 David Hilvert2009-06-03 20:25:56 +0000384
d8f91b46
DH
David Hilvert2009-06-04 01:08:33 +0000385 if (k != 0)
386 fprintf(stderr, " ");
387
621c5990 David Hilvert2009-06-03 20:25:56 +0000388 switch (type) {
4bca2aef
DH
David Hilvert2009-06-14 01:01:47 +0000389 ALE_TYPE_UINT_8: {
390 cl_uchar data;
391 assert(fread(&data, sizeof(cl_uchar), 1, image_data));
392 fprintf(stderr, "%u", (unsigned int) data);
393 break; }
394 ALE_TYPE_UINT_16: {
395 cl_ushort data;
396 assert(fread(&data, sizeof(cl_ushort), 1, image_data));
397 fprintf(stderr, "%u", (unsigned int) data);
398 break; }
399 ALE_TYPE_UINT_32: {
400 cl_uint data;
401 assert(fread(&data, sizeof(cl_uint), 1, image_data));
402 fprintf(stderr, "%u", (unsigned int) data);
403 break; }
404 ALE_TYPE_UINT_64: {
405 cl_ulong data;
406 assert(fread(&data, sizeof(cl_ulong), 1, image_data));
407 fprintf(stderr, "%llu", data);
408 break; }
409 ALE_TYPE_FLOAT_32: {
410 cl_float data;
411 assert(fread(&data, sizeof(cl_float), 1, image_data));
412 fprintf(stderr, "%f", (double) data);
413 break; }
414 ALE_TYPE_FLOAT_64: {
415 double data;
416 assert(fread(&data, sizeof(double), 1, image_data));
417 fprintf(stderr, "%f", data);
418 break; }
621c5990 David Hilvert2009-06-03 20:25:56 +0000419 }
621c5990
DH
David Hilvert2009-06-03 20:25:56 +0000420 }
421 fprintf(stderr, "] ");
c6351a11 dhilvert2005-10-03 21:20:00 +0000422 }
423 fprintf(stderr, "\n");
64145e87 dhilvert2005-12-08 01:07:00 +0000424
621c5990
DH
David Hilvert2009-06-03 20:25:56 +0000425 ale_image_release_file(im, image_data);
426
64145e87 dhilvert2005-12-08 01:07:00 +0000427 return;
c6351a11 dhilvert2005-10-03 21:20:00 +0000428 }
aab588ef David Hilvert2008-10-19 06:44:40 +0000429
c6351a11 dhilvert2005-10-03 21:20:00 +0000430#ifdef USE_MAGICK
66588363
DH
David Hilvert2009-06-04 18:36:47 +0000431 /*
432 * If necessary, adjust mcv to match library limits.
433 */
434
435 if (MaxRGB < 65535 && mcv == 65535) {
436 fprintf(stderr, "\n\n*** Warning: " MagickPackageName " has not been compiled with 16 bit support.\n");
437 fprintf(stderr, "*** Writing output using 8 bits per channel.\n");
438 fprintf(stderr, "*** \n");
439 fprintf(stderr, "*** (To silence this warning, specify option --8bpc)\n\n\n");
440
441 mcv = 255;
442 }
7bb7472e
DH
David Hilvert2009-06-14 00:54:11 +0000443
444 /*
445 * We currently can't handle mcv greater than 65535 here.
446 */
447
448 assert(mcv <= 65535);
449
450 if (mcv > 65535) {
451 fprintf(stderr, "error: I don't know how to produce greater than 16-bit output.\n");
452 exit(1);
453 }
66588363
DH
David Hilvert2009-06-04 18:36:47 +0000454#endif
455
456 /*
457 * Automatic exposure adjustment (don't blow out highlights)
458 */
459 ale_real maxval = 1;
460 ale_real minval = (rezero ? (ale_real) ale_image_minval(im) : (ale_real) 0);
461 if (minval > 0)
462 minval = 0;
463 pixel minval_pixel(minval, minval, minval);
464
465
466 if (exposure_scale || exp_scale_override) {
467 ale_real new_maxval = ale_image_maxval(im);
468
469 if (new_maxval > maxval)
470 maxval = new_maxval;
471 }
472
473 /*
474 * Nearest-neighbor fill.
475 */
476
ac4577d5
DH
David Hilvert2009-06-14 19:02:25 +0000477 ale_image temp_image = use_weights ? ale_image_nn_fill(im, nn_defined_radius)
478 : ale_image_get_weights(im);
66588363
DH
David Hilvert2009-06-04 18:36:47 +0000479
480 /*
ba06f57c David Hilvert2009-06-05 19:54:22 +0000481 * Unlinearize and quantize
66588363
DH
David Hilvert2009-06-04 18:36:47 +0000482 */
483
231104ea
DH
David Hilvert2009-06-05 19:32:59 +0000484 ale_image quantized_image = ale_new_image(accel::context(),
485 ale_image_get_format(temp_image), (mcv > 255) ?
486 ALE_TYPE_UINT_16 : ALE_TYPE_UINT_8);
487
bccf19c9 David Hilvert2009-07-18 19:30:20 +0000488 ale_eval("MAP_PIXEL(%0I, p, CLAMP(pow((GET_PIXEL(%1i, p) - (PIXEL(1, 1, 1) * %2f)) / (%3f - %2f), %4f)) * %5f)",
0d1dc039 David Hilvert2009-07-18 19:20:13 +0000489 quantized_image, temp_image, minval, maxval, gamma, (double) ((mcv > 255) ? 65535 : 255));
3c912486
DH
David Hilvert2009-06-05 19:18:33 +0000490
491 ale_image_release(temp_image);
492
66588363 David Hilvert2009-06-04 18:36:47 +0000493#ifdef USE_MAGICK
c6351a11 dhilvert2005-10-03 21:20:00 +0000494
30afe4b6 dhilvert2005-01-07 06:42:00 +0000495 /*
496 * Patterned after http://www.imagemagick.org/www/api.html
497 * and http://www.imagemagick.org/www/smile.c
498 */
499
500 ExceptionInfo exception;
501 Image *mi;
502 ImageInfo *image_info;
503 PixelPacket *p;
504
505 unsigned int i, j;
506
507 GetExceptionInfo(&exception);
508 image_info = CloneImageInfo((ImageInfo *) NULL);
509 strncpy(image_info->filename, filename, MaxTextExtent);
510
511 mi = AllocateImage(image_info);
512 if (mi == (Image *) NULL)
513 MagickError(ResourceLimitError,
514 "Unable to display image", "MemoryAllocationFailed");
515
13fac00b
DH
David Hilvert2009-06-04 16:26:39 +0000516 mi->columns = ale_image_get_width(im);
517 mi->rows = ale_image_get_height(im);
30afe4b6 dhilvert2005-01-07 06:42:00 +0000518
519 /*
520 * Set the output image depth
521 */
522
66588363 David Hilvert2009-06-04 18:36:47 +0000523 if (mcv < 65535)
30afe4b6 dhilvert2005-01-07 06:42:00 +0000524 mi->depth = 8;
525 else
526 mi->depth = 16;
527
30afe4b6 dhilvert2005-01-07 06:42:00 +0000528 /*
529 * Set compression type
530 */
531
532 if (ppm_type == 2) {
533 mi->compression = NoCompression;
534 image_info->compression = NoCompression;
535 strncpy(mi->magick, "PNM", MaxTextExtent);
536 strncpy(image_info->magick, "PNM", MaxTextExtent);
537 } else if (ppm_type == 1) {
538 strncpy(mi->magick, "PNM", MaxTextExtent);
539 strncpy(image_info->magick, "PNM", MaxTextExtent);
540 }
541
542 /*
66588363 David Hilvert2009-06-04 18:36:47 +0000543 * Write the image
13fac00b
DH
David Hilvert2009-06-04 16:26:39 +0000544 */
545
3c912486 David Hilvert2009-06-05 19:18:33 +0000546 FILE *image_data = ale_image_retain_file(quantized_image);
13fac00b David Hilvert2009-06-04 16:26:39 +0000547
30afe4b6 dhilvert2005-01-07 06:42:00 +0000548 for (i = 0; i < mi->rows; i++) {
549 p = SetImagePixels(mi, 0, i, mi->columns, 1);
550 if (p == NULL)
551 break;
552
553 for (j = 0; j < mi->columns; j++) {
561693b7 dhilvert2005-12-17 19:48:00 +0000554
7bb7472e
DH
David Hilvert2009-06-14 00:54:11 +0000555 cl_ushort val[3];
556
557 for (int k = 0; k < 3; k++) {
558 if (mcv <= 255) {
559 val[k] = fgetc(image_data);
560 } else {
561 assert(fread(&(val[k]), sizeof(cl_ushort), 1, image_data));
562 }
563 }
561693b7 dhilvert2005-12-17 19:48:00 +0000564
7bb7472e
DH
David Hilvert2009-06-14 00:54:11 +0000565 p->red = (Quantum) val[0];
566 p->green = (Quantum) val[1];
567 p->blue = (Quantum) val[2];
30afe4b6 dhilvert2005-01-07 06:42:00 +0000568 p++;
569 }
570
571 if (!SyncImagePixels(mi))
572 break;
573 }
574
3c912486 David Hilvert2009-06-05 19:18:33 +0000575 ale_image_release_file(quantized_image, image_data);
66588363 David Hilvert2009-06-04 18:36:47 +0000576
30afe4b6 dhilvert2005-01-07 06:42:00 +0000577 if (!WriteImage(image_info, mi)) {
578
579 /*
580 * Perhaps file type was unknown? Set to PNM by default.
581 */
582
583 strncpy(mi->magick, "PNM", MaxTextExtent);
584 strncpy(image_info->magick, "PNM", MaxTextExtent);
585
586 if (!WriteImage(image_info, mi)) {
587 fprintf(stderr, "\n\n");
588 CatchException(&mi->exception);
589 fprintf(stderr, "\n");
590 exit(1);
591 }
592 }
593
594 DestroyImage(mi);
595 DestroyImageInfo(image_info);
596#else
3c912486 David Hilvert2009-06-05 19:18:33 +0000597 write_ppm(filename, quantized_image, mcv, ppm_type == 2);
30afe4b6 dhilvert2005-01-07 06:42:00 +0000598#endif
aab588ef David Hilvert2008-10-19 06:44:40 +0000599
3c912486 David Hilvert2009-06-05 19:18:33 +0000600 ale_image_release(quantized_image);
66588363
DH
David Hilvert2009-06-04 18:36:47 +0000601
602
30afe4b6 dhilvert2005-01-07 06:42:00 +0000603 }
604
a93307da David Hilvert2009-06-14 02:00:55 +0000605 static void output(ale_image i) {
30afe4b6 dhilvert2005-01-07 06:42:00 +0000606 assert (file_count > 0);
23f1e86f David Hilvert2009-06-14 02:13:37 +0000607 write_image(output_name(), i, output_exposure->get_gamma());
46f9776a dhilvert2005-01-07 06:44:00 +0000608 }
609
23f1e86f David Hilvert2009-06-14 02:13:37 +0000610 static void vise_write(const char *p, const char *s, ale_image i) {
46f9776a dhilvert2005-01-07 06:44:00 +0000611 static int count = 0;
612 int length = strlen(p) + strlen(s) + 8;
613 char *output_string = (char *) malloc(length * sizeof(char));
614
615 snprintf(output_string, length, "%s%08d%s", p, count, s);
616
23f1e86f David Hilvert2009-06-14 02:13:37 +0000617 write_image(output_string, i, output_exposure->get_gamma());
46f9776a dhilvert2005-01-07 06:44:00 +0000618
619 count++;
30afe4b6 dhilvert2005-01-07 06:42:00 +0000620 }
621
622 static exposure &exp(int n) {
1adb31c9 dhilvert2005-01-07 06:45:00 +0000623 return *input_exposure[n];
30afe4b6 dhilvert2005-01-07 06:42:00 +0000624 }
625
626 static const exposure &const_exp(int n) {
1adb31c9 dhilvert2005-01-07 06:45:00 +0000627 return *input_exposure[n];
30afe4b6 dhilvert2005-01-07 06:42:00 +0000628 }
629
630 static exposure &exp() {
631 return *output_exposure;
632 }
633
46f9776a dhilvert2005-01-07 06:44:00 +0000634 static void exp_scale() {
635 exposure_scale = 1;
636 }
637
638 static void exp_noscale() {
639 exposure_scale = 0;
640 }
641
30afe4b6 dhilvert2005-01-07 06:42:00 +0000642 static const exposure &const_exp() {
643 return *output_exposure;
644 }
645
1adb31c9 dhilvert2005-01-07 06:45:00 +0000646 static const unsigned int bayer(unsigned int n) {
647 if (bayer_specific[n] == IMAGE_BAYER_DEFAULT)
648 return bayer_default;
649 else
650 return bayer_specific[n];
651 }
652
e7b16e3b
DH
David Hilvert2009-05-12 22:57:40 +0000653 static const ale_image open_simple(unsigned int n) {
654 assert (n < file_count);
655
656 return read_image(filenames[n], input_exposure[n], "file", bayer(n), (n == 0));
657 }
658
11eef435 David Hilvert2009-05-05 23:30:46 +0000659 static const ale_image open(unsigned int n) {
30afe4b6 dhilvert2005-01-07 06:42:00 +0000660 assert (n < file_count);
661 assert (!files_open[n]);
662
91e5ac67
DH
David Hilvert2007-05-04 02:09:00 +0000663 files_open[n] = 1;
664
46f9776a dhilvert2005-01-07 06:44:00 +0000665 if (latest_close_num >= 0 && n == (unsigned int) latest_close_num) {
30afe4b6 dhilvert2005-01-07 06:42:00 +0000666 latest_close_num = -1;
91e5ac67
DH
David Hilvert2007-05-04 02:09:00 +0000667 return images[n];
668 }
669
670 if (n < cache_count)
671 return images[n];
30afe4b6 dhilvert2005-01-07 06:42:00 +0000672
91e5ac67 David Hilvert2007-05-04 02:09:00 +0000673 ui::get()->loading_file();
11eef435 David Hilvert2009-05-05 23:30:46 +0000674 ale_image i = read_image(filenames[n], input_exposure[n], "file", bayer(n), (n == 0));
91e5ac67
DH
David Hilvert2007-05-04 02:09:00 +0000675
676 images[n] = i;
30afe4b6 dhilvert2005-01-07 06:42:00 +0000677
30afe4b6 dhilvert2005-01-07 06:42:00 +0000678 return images[n];
679 }
680
51e1d701 dhilvert2006-05-06 03:15:00 +0000681 static void open_all() {
682 for (unsigned int n = 0; n < file_count; n++)
683 open(n);
684 }
685
11eef435 David Hilvert2009-05-05 23:30:46 +0000686 static ale_image get_open(unsigned int n) {
51e1d701 dhilvert2006-05-06 03:15:00 +0000687 assert (files_open[n]);
688 return images[n];
689 }
690
2273bbe7
DH
David Hilvert2009-05-29 20:05:24 +0000691#if 0
692 /*
693 * XXX: as far as I can tell, 'copy' is currently always used
694 * as a kind of 'retain', so that calls to this can probably be
695 * replaced by calls to an appropriate retain method.
696 */
697
11eef435 David Hilvert2009-05-05 23:30:46 +0000698 static ale_image copy(unsigned int n, const char *name) {
30afe4b6 dhilvert2005-01-07 06:42:00 +0000699 assert (n < file_count);
700
701 if (files_open[n])
702 return images[n]->clone(name);
703 else {
3dc20778 dhilvert2005-01-10 23:06:00 +0000704 image *i = read_image(filenames[n], input_exposure[n], name, bayer(n), (n == 0));
30afe4b6 dhilvert2005-01-07 06:42:00 +0000705 return i;
706 }
707 }
2273bbe7
DH
David Hilvert2009-05-29 20:05:24 +0000708#endif
709
710#if 0
711 /*
712 * This method should be replaced by ale_sequence_release_image.
713 */
30afe4b6 dhilvert2005-01-07 06:42:00 +0000714
46f9776a dhilvert2005-01-07 06:44:00 +0000715 static void close(unsigned int image) {
30afe4b6 dhilvert2005-01-07 06:42:00 +0000716 assert (image < file_count);
717 assert (files_open[image]);
718
91e5ac67
DH
David Hilvert2007-05-04 02:09:00 +0000719 files_open[image] = 0;
720
721 if (image < cache_count)
722 return;
723
724 if (image == cache_count) {
e812ee44 David Hilvert2007-10-18 18:24:00 +0000725 double image_size = ((double) images[image]->storage_size()) / pow(2, 20);
91e5ac67
DH
David Hilvert2007-05-04 02:09:00 +0000726
727 if (image_size + cache_size < cache_size_max) {
728 cache_size += image_size;
729 cache_count++;
74c09da8 David Hilvert2007-05-04 12:58:00 +0000730 ui::get()->cache(cache_size, cache_size_max);
91e5ac67 David Hilvert2007-05-04 02:09:00 +0000731 return;
74c09da8
DH
David Hilvert2007-05-04 12:58:00 +0000732 } else {
733 ui::get()->cache_status(0);
91e5ac67
DH
David Hilvert2007-05-04 02:09:00 +0000734 }
735 }
736
30afe4b6 dhilvert2005-01-07 06:42:00 +0000737 if (latest_close_num >= 0)
91e5ac67 David Hilvert2007-05-04 02:09:00 +0000738 delete images[latest_close_num];
30afe4b6 dhilvert2005-01-07 06:42:00 +0000739
91e5ac67 David Hilvert2007-05-04 02:09:00 +0000740 latest_close_num = image;
30afe4b6 dhilvert2005-01-07 06:42:00 +0000741 }
742
51e1d701 dhilvert2006-05-06 03:15:00 +0000743 static void close_all() {
744 for (unsigned int n = 0; n < file_count; n++)
745 close(n);
746 }
2273bbe7 David Hilvert2009-05-29 20:05:24 +0000747#endif
51e1d701 dhilvert2006-05-06 03:15:00 +0000748
30afe4b6 dhilvert2005-01-07 06:42:00 +0000749};
750
751#endif