2 dcraw.c -- Dave Coffin's raw photo decoder
3 Copyright 1997-2012 by Dave Coffin, dcoffin a cybercom o net
5 This is a command-line ANSI C program to convert raw photos from
6 any digital camera on any computer running any operating system.
8 No license is required to download and use dcraw.c. However,
9 to lawfully redistribute dcraw, you must either (a) offer, at
10 no extra charge, full source code* for all executable files
11 containing RESTRICTED functions, (b) distribute this code under
12 the GPL Version 2 or later, (c) remove all RESTRICTED functions,
13 re-implement them, or copy them from an earlier, unrestricted
14 Revision of dcraw.c, or (d) purchase a license from the author.
16 The functions that process Foveon images have been RESTRICTED
17 since Revision 1.237. All other code remains free for all uses.
19 *If you have not modified dcraw.c in any way, a link to my
20 homepage qualifies as "full source code".
23 $Date: 2012/12/23 19:25:36 $
26 #define DCRAW_VERSION "9.17"
31 #define _USE_MATH_DEFINES
43 #include <sys/types.h>
56 #include <jasper/jasper.h> /* Decode RED camera movies */
59 #include <jpeglib.h> /* Decode compressed Kodak DC120 photos */
60 #endif /* and Adobe Lossy DNGs */
62 #include <lcms.h> /* Support color profiles */
66 #define _(String) gettext(String)
68 #define _(String) (String)
71 #if defined(DJGPP) || defined(__MINGW32__)
75 #define fgetc getc_unlocked
81 #include <sys/utime.h>
83 #pragma comment(lib, "ws2_32.lib")
84 #define snprintf _snprintf
85 #define strcasecmp stricmp
86 #define strncasecmp strnicmp
87 typedef __int64 INT64;
88 typedef unsigned __int64 UINT64;
92 #include <netinet/in.h>
93 typedef long long INT64;
94 typedef unsigned long long UINT64;
98 #error Please compile dcraw.c by itself.
99 #error Do not link it with ljpeg_decode.
103 #define LONG_BIT (8 * sizeof (long))
107 #define uchar unsigned char
110 #define ushort unsigned short
114 All global variables are defined here, and all functions that
115 access them are prefixed with "CLASS". Note that a thread-safe
116 C++ class cannot have non-const static local variables.
120 char dcraw_info[1024];
123 float dcraw_matrix[9];
134 char cdesc[5], desc[512], make[64], model[64], model2[64], artist[64];
135 float flash_used, canon_ev, iso_speed, shutter, aperture, focal_len;
137 unsigned shot_order, kodak_cbpp, filters, exif_cfa, unique_id;
138 off_t strip_offset, data_offset;
139 off_t thumb_offset, meta_offset, profile_offset;
140 unsigned thumb_length, meta_length, profile_length;
141 unsigned thumb_misc, *oprof, fuji_layout, shot_select=0, multi_out=0;
142 unsigned tiff_nifds, tiff_samples, tiff_bps, tiff_compress;
143 unsigned black, cblack[4], maximum, mix_green, raw_color, zero_is_bad;
144 unsigned zero_after_ff, is_raw, dng_version, is_foveon, data_error;
145 unsigned tile_width, tile_length, gpsdata[32], load_flags;
146 ushort raw_height, raw_width, height, width, top_margin, left_margin;
147 ushort shrink, iheight, iwidth, fuji_width, thumb_width, thumb_height;
148 ushort *raw_image, (*image)[4];
149 ushort white[8][8], curve[0x10000], cr2_slice[3], sraw_mul[4];
152 static int mask[8][4], flip, tiff_flip, colors;
155 double pixel_aspect, aber[4]={1,1,1,1}, gamm[6]={ 0.45,4.5,0,0,0,0 };
156 float bright=1, user_mul[4]={0,0,0,0}, threshold=0;
157 int half_size=0, four_color_rgb=0, document_mode=0, highlight=0;
158 int verbose=0, use_auto_wb=0, use_camera_wb=0, use_camera_matrix=-1;
159 int output_color=1, output_bps=8, output_tiff=0, med_passes=0;
160 int no_auto_bright=0;
161 unsigned greybox[4] = { 0, 0, UINT_MAX, UINT_MAX };
162 float cam_mul[4], pre_mul[4], cmatrix[3][4], rgb_cam[3][4];
163 const double xyz_rgb[3][3] = { /* XYZ from RGB */
164 { 0.412453, 0.357580, 0.180423 },
165 { 0.212671, 0.715160, 0.072169 },
166 { 0.019334, 0.119193, 0.950227 } };
167 const float d65_white[3] = { 0.950456, 1, 1.088754 };
168 int histogram[4][0x2000];
169 void (*write_thumb)(), (*write_fun)();
170 void (*load_raw)(), (*thumb_load_raw)();
174 struct decode *branch[2];
176 } first_decode[2048], *second_decode, *free_decode;
179 int width, height, bps, comp, phint, offset, flip, samples, bytes;
180 int tile_width, tile_length;
184 int format, key_off, black, black_off, split_col, tag_21a;
190 #define FORC(cnt) for (c=0; c < cnt; c++)
191 #define FORC3 FORC(3)
192 #define FORC4 FORC(4)
193 #define FORCC FORC(colors)
195 #define SQR(x) ((x)*(x))
196 #define ABS(x) (((int)(x) ^ ((int)(x) >> 31)) - ((int)(x) >> 31))
197 #define MIN(a,b) ((a) < (b) ? (a) : (b))
198 #define MAX(a,b) ((a) > (b) ? (a) : (b))
199 #define LIM(x,min,max) MAX(min,MIN(x,max))
200 #define ULIM(x,y,z) ((y) < (z) ? LIM(x,y,z) : LIM(x,z,y))
201 #define CLIP(x) LIM(x,0,65535)
202 #define SWAP(a,b) { a=a+b; b=a-b; a=a-b; }
205 In order to inline this calculation, I make the risky
206 assumption that all filter patterns can be described
207 by a repeating pattern of eight rows and two columns
209 Do not use the FC or BAYER macros with the Leaf CatchLight,
210 because its pattern is 16x16, not 2x8.
212 Return values are either 0/1/2/3 = G/M/C/Y or 0/1/2/3 = R/G1/B/G2
214 PowerShot 600 PowerShot A50 PowerShot Pro70 Pro90 & G1
215 0xe1e4e1e4: 0x1b4e4b1e: 0x1e4b4e1b: 0xb4b4b4b4:
217 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5
218 0 G M G M G M 0 C Y C Y C Y 0 Y C Y C Y C 0 G M G M G M
219 1 C Y C Y C Y 1 M G M G M G 1 M G M G M G 1 Y C Y C Y C
220 2 M G M G M G 2 Y C Y C Y C 2 C Y C Y C Y
221 3 C Y C Y C Y 3 G M G M G M 3 G M G M G M
222 4 C Y C Y C Y 4 Y C Y C Y C
223 PowerShot A5 5 G M G M G M 5 G M G M G M
224 0x1e4e1e4e: 6 Y C Y C Y C 6 C Y C Y C Y
225 7 M G M G M G 7 M G M G M G
232 All RGB cameras use one of these Bayer grids:
234 0x16161616: 0x61616161: 0x49494949: 0x94949494:
236 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5
237 0 B G B G B G 0 G R G R G R 0 G B G B G B 0 R G R G R G
238 1 G R G R G R 1 B G B G B G 1 R G R G R G 1 G B G B G B
239 2 B G B G B G 2 G R G R G R 2 G B G B G B 2 R G R G R G
240 3 G R G R G R 3 B G B G B G 3 R G R G R G 3 G B G B G B
243 #define RAW(row,col) \
244 raw_image[(row)*raw_width+(col)]
246 #define FC(row,col) \
247 (filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)
249 #define BAYER(row,col) \
250 image[((row) >> shrink)*iwidth + ((col) >> shrink)][FC(row,col)]
252 #define BAYER2(row,col) \
253 image[((row) >> shrink)*iwidth + ((col) >> shrink)][fcol(row,col)]
255 int CLASS fcol (int row, int col)
257 static const char filter[16][16] =
258 { { 2,1,1,3,2,3,2,0,3,2,3,0,1,2,1,0 },
259 { 0,3,0,2,0,1,3,1,0,1,1,2,0,3,3,2 },
260 { 2,3,3,2,3,1,1,3,3,1,2,1,2,0,0,3 },
261 { 0,1,0,1,0,2,0,2,2,0,3,0,1,3,2,1 },
262 { 3,1,1,2,0,1,0,2,1,3,1,3,0,1,3,0 },
263 { 2,0,0,3,3,2,3,1,2,0,2,0,3,2,2,1 },
264 { 2,3,3,1,2,1,2,1,2,1,1,2,3,0,0,1 },
265 { 1,0,0,2,3,0,0,3,0,3,0,3,2,1,2,3 },
266 { 2,3,3,1,1,2,1,0,3,2,3,0,2,3,1,3 },
267 { 1,0,2,0,3,0,3,2,0,1,1,2,0,1,0,2 },
268 { 0,1,1,3,3,2,2,1,1,3,3,0,2,1,3,2 },
269 { 2,3,2,0,0,1,3,0,2,0,1,2,3,0,1,0 },
270 { 1,3,1,2,3,2,3,2,0,2,0,1,1,0,3,0 },
271 { 0,2,0,3,1,0,0,1,1,3,3,2,3,2,2,1 },
272 { 2,1,3,2,3,1,2,1,0,3,0,2,0,2,0,2 },
273 { 0,3,1,0,0,2,0,3,2,1,3,1,1,3,1,3 } };
274 static const char filter2[6][6] =
282 if (filters == 1) return filter[(row+top_margin)&15][(col+left_margin)&15];
283 if (filters == 2) return filter2[(row+6) % 6][(col+6) % 6];
288 char *my_memmem (char *haystack, size_t haystacklen,
289 char *needle, size_t needlelen)
292 for (c = haystack; c <= haystack + haystacklen - needlelen; c++)
293 if (!memcmp (c, needle, needlelen))
297 #define memmem my_memmem
300 void CLASS merror (void *ptr, const char *where)
303 fprintf (stderr,_("%s: Out of memory in %s\n"), ifname, where);
304 longjmp (failure, 1);
310 fprintf (stderr, "%s: ", ifname);
312 fprintf (stderr,_("Unexpected end of file\n"));
314 fprintf (stderr,_("Corrupt data near 0x%llx\n"), (INT64) ftello(ifp));
319 ushort CLASS sget2 (uchar *s)
321 if (order == 0x4949) /* "II" means little-endian */
322 return s[0] | s[1] << 8;
323 else /* "MM" means big-endian */
324 return s[0] << 8 | s[1];
329 uchar str[2] = { 0xff,0xff };
330 fread (str, 1, 2, ifp);
334 unsigned CLASS sget4 (uchar *s)
337 return s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24;
339 return s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3];
341 #define sget4(s) sget4((uchar *)s)
343 unsigned CLASS get4()
345 uchar str[4] = { 0xff,0xff,0xff,0xff };
346 fread (str, 1, 4, ifp);
350 unsigned CLASS getint (int type)
352 return type == 3 ? get2() : get4();
355 float CLASS int_to_float (int i)
357 union { int i; float f; } u;
362 double CLASS getreal (int type)
364 union { char c[8]; double d; } u;
368 case 3: return (unsigned short) get2();
369 case 4: return (unsigned int) get4();
370 case 5: u.d = (unsigned int) get4();
371 return u.d / (unsigned int) get4();
372 case 8: return (signed short) get2();
373 case 9: return (signed int) get4();
374 case 10: u.d = (signed int) get4();
375 return u.d / (signed int) get4();
376 case 11: return int_to_float (get4());
378 rev = 7 * ((order == 0x4949) == (ntohs(0x1234) == 0x1234));
379 for (i=0; i < 8; i++)
380 u.c[i ^ rev] = fgetc(ifp);
382 default: return fgetc(ifp);
386 void CLASS read_shorts (ushort *pixel, int count)
388 if (fread (pixel, 2, count, ifp) < count) derror();
389 if ((order == 0x4949) == (ntohs(0x1234) == 0x1234))
390 swab (pixel, pixel, count*2);
393 void CLASS canon_600_fixed_wb (int temp)
395 static const short mul[4][5] = {
396 { 667, 358,397,565,452 },
397 { 731, 390,367,499,517 },
398 { 1119, 396,348,448,537 },
399 { 1399, 485,431,508,688 } };
404 if (*mul[lo] <= temp) break;
405 for (hi=0; hi < 3; hi++)
406 if (*mul[hi] >= temp) break;
408 frac = (float) (temp - *mul[lo]) / (*mul[hi] - *mul[lo]);
409 for (i=1; i < 5; i++)
410 pre_mul[i-1] = 1 / (frac * mul[hi][i] + (1-frac) * mul[lo][i]);
413 /* Return values: 0 = white 1 = near white 2 = not white */
414 int CLASS canon_600_color (int ratio[2], int mar)
416 int clipped=0, target, miss;
420 { ratio[1] = -104; clipped = 1; }
422 { ratio[1] = 12; clipped = 1; }
424 if (ratio[1] < -264 || ratio[1] > 461) return 2;
426 { ratio[1] = -50; clipped = 1; }
428 { ratio[1] = 307; clipped = 1; }
430 target = flash_used || ratio[1] < 197
431 ? -38 - (398 * ratio[1] >> 10)
432 : -123 + (48 * ratio[1] >> 10);
433 if (target - mar <= ratio[0] &&
434 target + 20 >= ratio[0] && !clipped) return 0;
435 miss = target - ratio[0];
436 if (abs(miss) >= mar*4) return 2;
437 if (miss < -20) miss = -20;
438 if (miss > mar) miss = mar;
439 ratio[0] = target - miss;
443 void CLASS canon_600_auto_wb()
445 int mar, row, col, i, j, st, count[] = { 0,0 };
446 int test[8], total[2][8], ratio[2][2], stat[2];
448 memset (&total, 0, sizeof total);
450 if (i < 10) mar = 150;
451 else if (i > 12) mar = 20;
452 else mar = 280 - 20 * i;
453 if (flash_used) mar = 80;
454 for (row=14; row < height-14; row+=4)
455 for (col=10; col < width; col+=2) {
456 for (i=0; i < 8; i++)
457 test[(i & 4) + FC(row+(i >> 1),col+(i & 1))] =
458 BAYER(row+(i >> 1),col+(i & 1));
459 for (i=0; i < 8; i++)
460 if (test[i] < 150 || test[i] > 1500) goto next;
461 for (i=0; i < 4; i++)
462 if (abs(test[i] - test[i+4]) > 50) goto next;
463 for (i=0; i < 2; i++) {
464 for (j=0; j < 4; j+=2)
465 ratio[i][j >> 1] = ((test[i*4+j+1]-test[i*4+j]) << 10) / test[i*4+j];
466 stat[i] = canon_600_color (ratio[i], mar);
468 if ((st = stat[0] | stat[1]) > 1) goto next;
469 for (i=0; i < 2; i++)
471 for (j=0; j < 2; j++)
472 test[i*4+j*2+1] = test[i*4+j*2] * (0x400 + ratio[i][j]) >> 10;
473 for (i=0; i < 8; i++)
474 total[st][i] += test[i];
478 if (count[0] | count[1]) {
479 st = count[0]*200 < count[1];
480 for (i=0; i < 4; i++)
481 pre_mul[i] = 1.0 / (total[st][i] + total[st][i+4]);
485 void CLASS canon_600_coeff()
487 static const short table[6][12] = {
488 { -190,702,-1878,2390, 1861,-1349,905,-393, -432,944,2617,-2105 },
489 { -1203,1715,-1136,1648, 1388,-876,267,245, -1641,2153,3921,-3409 },
490 { -615,1127,-1563,2075, 1437,-925,509,3, -756,1268,2519,-2007 },
491 { -190,702,-1886,2398, 2153,-1641,763,-251, -452,964,3040,-2528 },
492 { -190,702,-1878,2390, 1861,-1349,905,-393, -432,944,2617,-2105 },
493 { -807,1319,-1785,2297, 1388,-876,769,-257, -230,742,2067,-1555 } };
497 mc = pre_mul[1] / pre_mul[2];
498 yc = pre_mul[3] / pre_mul[2];
499 if (mc > 1 && mc <= 1.28 && yc < 0.8789) t=1;
500 if (mc > 1.28 && mc <= 2) {
501 if (yc < 0.8789) t=3;
502 else if (yc <= 2) t=4;
505 for (raw_color = i=0; i < 3; i++)
506 FORCC rgb_cam[i][c] = table[t][i*4 + c] / 1024.0;
509 void CLASS canon_600_load_raw()
511 uchar data[1120], *dp;
515 for (irow=row=0; irow < height; irow++) {
516 if (fread (data, 1, 1120, ifp) < 1120) derror();
517 pix = raw_image + row*raw_width;
518 for (dp=data; dp < data+1120; dp+=10, pix+=8) {
519 pix[0] = (dp[0] << 2) + (dp[1] >> 6 );
520 pix[1] = (dp[2] << 2) + (dp[1] >> 4 & 3);
521 pix[2] = (dp[3] << 2) + (dp[1] >> 2 & 3);
522 pix[3] = (dp[4] << 2) + (dp[1] & 3);
523 pix[4] = (dp[5] << 2) + (dp[9] & 3);
524 pix[5] = (dp[6] << 2) + (dp[9] >> 2 & 3);
525 pix[6] = (dp[7] << 2) + (dp[9] >> 4 & 3);
526 pix[7] = (dp[8] << 2) + (dp[9] >> 6 );
528 if ((row+=2) > height) row = 1;
532 void CLASS canon_600_correct()
535 static const short mul[4][2] =
536 { { 1141,1145 }, { 1128,1109 }, { 1178,1149 }, { 1128,1109 } };
538 for (row=0; row < height; row++)
539 for (col=0; col < width; col++) {
540 if ((val = BAYER(row,col) - black) < 0) val = 0;
541 val = val * mul[row & 3][col & 1] >> 9;
542 BAYER(row,col) = val;
544 canon_600_fixed_wb(1311);
547 maximum = (0x3ff - black) * 1109 >> 9;
551 int CLASS canon_s2is()
555 for (row=0; row < 100; row++) {
556 fseek (ifp, row*3340 + 3284, SEEK_SET);
557 if (getc(ifp) > 15) return 1;
563 getbits(-1) initializes the buffer
564 getbits(n) where 0 <= n <= 25 returns an n-bit integer
566 unsigned CLASS getbithuff (int nbits, ushort *huff)
568 static unsigned bitbuf=0;
569 static int vbits=0, reset=0;
573 return bitbuf = vbits = reset = 0;
574 if (nbits == 0 || vbits < 0) return 0;
575 while (!reset && vbits < nbits && (c = fgetc(ifp)) != EOF &&
576 !(reset = zero_after_ff && c == 0xff && fgetc(ifp))) {
577 bitbuf = (bitbuf << 8) + (uchar) c;
580 c = bitbuf << (32-vbits) >> (32-nbits);
582 vbits -= huff[c] >> 8;
586 if (vbits < 0) derror();
590 #define getbits(n) getbithuff(n,0)
591 #define gethuff(h) getbithuff(*h,h+1)
594 Construct a decode tree according the specification in *source.
595 The first 16 bytes specify how many codes should be 1-bit, 2-bit
596 3-bit, etc. Bytes after that are the leaf values.
598 For example, if the source is
600 { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0,
601 0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff },
619 ushort * CLASS make_decoder_ref (const uchar **source)
621 int max, len, h, i, j;
625 count = (*source += 16) - 17;
626 for (max=16; max && !count[max]; max--);
627 huff = (ushort *) calloc (1 + (1 << max), sizeof *huff);
628 merror (huff, "make_decoder()");
630 for (h=len=1; len <= max; len++)
631 for (i=0; i < count[len]; i++, ++*source)
632 for (j=0; j < 1 << (max-len); j++)
634 huff[h++] = len << 8 | **source;
638 ushort * CLASS make_decoder (const uchar *source)
640 return make_decoder_ref (&source);
643 void CLASS crw_init_tables (unsigned table, ushort *huff[2])
645 static const uchar first_tree[3][29] = {
646 { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0,
647 0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff },
648 { 0,2,2,3,1,1,1,1,2,0,0,0,0,0,0,0,
649 0x03,0x02,0x04,0x01,0x05,0x00,0x06,0x07,0x09,0x08,0x0a,0x0b,0xff },
650 { 0,0,6,3,1,1,2,0,0,0,0,0,0,0,0,0,
651 0x06,0x05,0x07,0x04,0x08,0x03,0x09,0x02,0x00,0x0a,0x01,0x0b,0xff },
653 static const uchar second_tree[3][180] = {
654 { 0,2,2,2,1,4,2,1,2,5,1,1,0,0,0,139,
655 0x03,0x04,0x02,0x05,0x01,0x06,0x07,0x08,
656 0x12,0x13,0x11,0x14,0x09,0x15,0x22,0x00,0x21,0x16,0x0a,0xf0,
657 0x23,0x17,0x24,0x31,0x32,0x18,0x19,0x33,0x25,0x41,0x34,0x42,
658 0x35,0x51,0x36,0x37,0x38,0x29,0x79,0x26,0x1a,0x39,0x56,0x57,
659 0x28,0x27,0x52,0x55,0x58,0x43,0x76,0x59,0x77,0x54,0x61,0xf9,
660 0x71,0x78,0x75,0x96,0x97,0x49,0xb7,0x53,0xd7,0x74,0xb6,0x98,
661 0x47,0x48,0x95,0x69,0x99,0x91,0xfa,0xb8,0x68,0xb5,0xb9,0xd6,
662 0xf7,0xd8,0x67,0x46,0x45,0x94,0x89,0xf8,0x81,0xd5,0xf6,0xb4,
663 0x88,0xb1,0x2a,0x44,0x72,0xd9,0x87,0x66,0xd4,0xf5,0x3a,0xa7,
664 0x73,0xa9,0xa8,0x86,0x62,0xc7,0x65,0xc8,0xc9,0xa1,0xf4,0xd1,
665 0xe9,0x5a,0x92,0x85,0xa6,0xe7,0x93,0xe8,0xc1,0xc6,0x7a,0x64,
666 0xe1,0x4a,0x6a,0xe6,0xb3,0xf1,0xd3,0xa5,0x8a,0xb2,0x9a,0xba,
667 0x84,0xa4,0x63,0xe5,0xc5,0xf3,0xd2,0xc4,0x82,0xaa,0xda,0xe4,
668 0xf2,0xca,0x83,0xa3,0xa2,0xc3,0xea,0xc2,0xe2,0xe3,0xff,0xff },
669 { 0,2,2,1,4,1,4,1,3,3,1,0,0,0,0,140,
670 0x02,0x03,0x01,0x04,0x05,0x12,0x11,0x06,
671 0x13,0x07,0x08,0x14,0x22,0x09,0x21,0x00,0x23,0x15,0x31,0x32,
672 0x0a,0x16,0xf0,0x24,0x33,0x41,0x42,0x19,0x17,0x25,0x18,0x51,
673 0x34,0x43,0x52,0x29,0x35,0x61,0x39,0x71,0x62,0x36,0x53,0x26,
674 0x38,0x1a,0x37,0x81,0x27,0x91,0x79,0x55,0x45,0x28,0x72,0x59,
675 0xa1,0xb1,0x44,0x69,0x54,0x58,0xd1,0xfa,0x57,0xe1,0xf1,0xb9,
676 0x49,0x47,0x63,0x6a,0xf9,0x56,0x46,0xa8,0x2a,0x4a,0x78,0x99,
677 0x3a,0x75,0x74,0x86,0x65,0xc1,0x76,0xb6,0x96,0xd6,0x89,0x85,
678 0xc9,0xf5,0x95,0xb4,0xc7,0xf7,0x8a,0x97,0xb8,0x73,0xb7,0xd8,
679 0xd9,0x87,0xa7,0x7a,0x48,0x82,0x84,0xea,0xf4,0xa6,0xc5,0x5a,
680 0x94,0xa4,0xc6,0x92,0xc3,0x68,0xb5,0xc8,0xe4,0xe5,0xe6,0xe9,
681 0xa2,0xa3,0xe3,0xc2,0x66,0x67,0x93,0xaa,0xd4,0xd5,0xe7,0xf8,
682 0x88,0x9a,0xd7,0x77,0xc4,0x64,0xe2,0x98,0xa5,0xca,0xda,0xe8,
683 0xf3,0xf6,0xa9,0xb2,0xb3,0xf2,0xd2,0x83,0xba,0xd3,0xff,0xff },
684 { 0,0,6,2,1,3,3,2,5,1,2,2,8,10,0,117,
685 0x04,0x05,0x03,0x06,0x02,0x07,0x01,0x08,
686 0x09,0x12,0x13,0x14,0x11,0x15,0x0a,0x16,0x17,0xf0,0x00,0x22,
687 0x21,0x18,0x23,0x19,0x24,0x32,0x31,0x25,0x33,0x38,0x37,0x34,
688 0x35,0x36,0x39,0x79,0x57,0x58,0x59,0x28,0x56,0x78,0x27,0x41,
689 0x29,0x77,0x26,0x42,0x76,0x99,0x1a,0x55,0x98,0x97,0xf9,0x48,
690 0x54,0x96,0x89,0x47,0xb7,0x49,0xfa,0x75,0x68,0xb6,0x67,0x69,
691 0xb9,0xb8,0xd8,0x52,0xd7,0x88,0xb5,0x74,0x51,0x46,0xd9,0xf8,
692 0x3a,0xd6,0x87,0x45,0x7a,0x95,0xd5,0xf6,0x86,0xb4,0xa9,0x94,
693 0x53,0x2a,0xa8,0x43,0xf5,0xf7,0xd4,0x66,0xa7,0x5a,0x44,0x8a,
694 0xc9,0xe8,0xc8,0xe7,0x9a,0x6a,0x73,0x4a,0x61,0xc7,0xf4,0xc6,
695 0x65,0xe9,0x72,0xe6,0x71,0x91,0x93,0xa6,0xda,0x92,0x85,0x62,
696 0xf3,0xc5,0xb2,0xa4,0x84,0xba,0x64,0xa5,0xb3,0xd2,0x81,0xe5,
697 0xd3,0xaa,0xc4,0xca,0xf2,0xb1,0xe4,0xd1,0x83,0x63,0xea,0xc3,
698 0xe2,0x82,0xf1,0xa3,0xc2,0xa1,0xc1,0xe3,0xa2,0xe1,0xff,0xff }
700 if (table > 2) table = 2;
701 huff[0] = make_decoder ( first_tree[table]);
702 huff[1] = make_decoder (second_tree[table]);
706 Return 0 if the image starts with compressed data,
707 1 if it starts with uncompressed low-order bits.
709 In Canon compressed data, 0xff is always followed by 0x00.
711 int CLASS canon_has_lowbits()
716 fseek (ifp, 0, SEEK_SET);
717 fread (test, 1, sizeof test, ifp);
718 for (i=540; i < sizeof test - 1; i++)
719 if (test[i] == 0xff) {
720 if (test[i+1]) return 1;
726 void CLASS canon_load_raw()
728 ushort *pixel, *prow, *huff[2];
729 int nblocks, lowbits, i, c, row, r, save, val;
730 int block, diffbuf[64], leaf, len, diff, carry=0, pnum=0, base[2];
732 crw_init_tables (tiff_compress, huff);
733 lowbits = canon_has_lowbits();
734 if (!lowbits) maximum = 0x3ff;
735 fseek (ifp, 540 + lowbits*raw_height*raw_width/4, SEEK_SET);
738 for (row=0; row < raw_height; row+=8) {
739 pixel = raw_image + row*raw_width;
740 nblocks = MIN (8, raw_height-row) * raw_width >> 6;
741 for (block=0; block < nblocks; block++) {
742 memset (diffbuf, 0, sizeof diffbuf);
743 for (i=0; i < 64; i++ ) {
744 leaf = gethuff(huff[i > 0]);
745 if (leaf == 0 && i) break;
746 if (leaf == 0xff) continue;
749 if (len == 0) continue;
751 if ((diff & (1 << (len-1))) == 0)
752 diff -= (1 << len) - 1;
753 if (i < 64) diffbuf[i] = diff;
757 for (i=0; i < 64; i++ ) {
758 if (pnum++ % raw_width == 0)
759 base[0] = base[1] = 512;
760 if ((pixel[(block << 6) + i] = base[i & 1] += diffbuf[i]) >> 10)
766 fseek (ifp, 26 + row*raw_width/4, SEEK_SET);
767 for (prow=pixel, i=0; i < raw_width*2; i++) {
769 for (r=0; r < 8; r+=2, prow++) {
770 val = (*prow << 2) + ((c >> r) & 3);
771 if (raw_width == 2672 && val < 512) val += 2;
775 fseek (ifp, save, SEEK_SET);
778 FORC(2) free (huff[c]);
782 Not a full implementation of Lossless JPEG, just
783 enough to decode Canon, Kodak and Adobe DNG images.
786 int bits, high, wide, clrs, sraw, psv, restart, vpred[6];
787 ushort *huff[6], *free[4], *row;
790 int CLASS ljpeg_start (struct jhead *jh, int info_only)
796 memset (jh, 0, sizeof *jh);
797 jh->restart = INT_MAX;
798 fread (data, 2, 1, ifp);
799 if (data[1] != 0xd8) return 0;
801 fread (data, 2, 2, ifp);
802 tag = data[0] << 8 | data[1];
803 len = (data[2] << 8 | data[3]) - 2;
804 if (tag <= 0xff00) return 0;
805 fread (data, 1, len, ifp);
808 jh->sraw = ((data[7] >> 4) * (data[7] & 15) - 1) & 3;
811 jh->high = data[1] << 8 | data[2];
812 jh->wide = data[3] << 8 | data[4];
813 jh->clrs = data[5] + jh->sraw;
814 if (len == 9 && !dng_version) getc(ifp);
817 if (info_only) break;
818 for (dp = data; dp < data+len && (c = *dp++) < 4; )
819 jh->free[c] = jh->huff[c] = make_decoder_ref (&dp);
822 jh->psv = data[1+data[0]*2];
823 jh->bits -= data[3+data[0]*2] & 15;
826 jh->restart = data[0] << 8 | data[1];
828 } while (tag != 0xffda);
829 if (info_only) return 1;
830 FORC(5) if (!jh->huff[c+1]) jh->huff[c+1] = jh->huff[c];
832 FORC(4) jh->huff[2+c] = jh->huff[1];
833 FORC(jh->sraw) jh->huff[1+c] = jh->huff[0];
835 jh->row = (ushort *) calloc (jh->wide*jh->clrs, 4);
836 merror (jh->row, "ljpeg_start()");
837 return zero_after_ff = 1;
840 void CLASS ljpeg_end (struct jhead *jh)
843 FORC4 if (jh->free[c]) free (jh->free[c]);
847 int CLASS ljpeg_diff (ushort *huff)
852 if (len == 16 && (!dng_version || dng_version >= 0x1010000))
855 if ((diff & (1 << (len-1))) == 0)
856 diff -= (1 << len) - 1;
860 ushort * CLASS ljpeg_row (int jrow, struct jhead *jh)
862 int col, c, diff, pred, spred=0;
863 ushort mark=0, *row[3];
865 if (jrow * jh->wide % jh->restart == 0) {
866 FORC(6) jh->vpred[c] = 1 << (jh->bits-1);
868 fseek (ifp, -2, SEEK_CUR);
869 do mark = (mark << 8) + (c = fgetc(ifp));
870 while (c != EOF && mark >> 4 != 0xffd);
874 FORC3 row[c] = jh->row + jh->wide*jh->clrs*((jrow+c) & 1);
875 for (col=0; col < jh->wide; col++)
877 diff = ljpeg_diff (jh->huff[c]);
878 if (jh->sraw && c <= jh->sraw && (col | c))
880 else if (col) pred = row[0][-jh->clrs];
881 else pred = (jh->vpred[c] += diff) - diff;
882 if (jrow && col) switch (jh->psv) {
884 case 2: pred = row[1][0]; break;
885 case 3: pred = row[1][-jh->clrs]; break;
886 case 4: pred = pred + row[1][0] - row[1][-jh->clrs]; break;
887 case 5: pred = pred + ((row[1][0] - row[1][-jh->clrs]) >> 1); break;
888 case 6: pred = row[1][0] + ((pred - row[1][-jh->clrs]) >> 1); break;
889 case 7: pred = (pred + row[1][0]) >> 1; break;
892 if ((**row = pred + diff) >> jh->bits) derror();
893 if (c <= jh->sraw) spred = **row;
899 void CLASS lossless_jpeg_load_raw()
901 int jwide, jrow, jcol, val, jidx, i, j, row=0, col=0;
905 if (!ljpeg_start (&jh, 0)) return;
906 jwide = jh.wide * jh.clrs;
908 for (jrow=0; jrow < jh.high; jrow++) {
909 rp = ljpeg_row (jrow, &jh);
911 row = jrow & 1 ? height-1-jrow/2 : jrow/2;
912 for (jcol=0; jcol < jwide; jcol++) {
915 jidx = jrow*jwide + jcol;
916 i = jidx / (cr2_slice[1]*jh.high);
917 if ((j = i >= cr2_slice[0]))
919 jidx -= i * (cr2_slice[1]*jh.high);
920 row = jidx / cr2_slice[1+j];
921 col = jidx % cr2_slice[1+j] + i*cr2_slice[1];
923 if (raw_width == 3984 && (col -= 2) < 0)
924 col += (row--,raw_width);
925 if (row >= 0) RAW(row,col) = val;
926 if (++col >= raw_width)
933 void CLASS canon_sraw_load_raw()
936 short *rp=0, (*ip)[4];
937 int jwide, slice, scol, ecol, row, col, jrow=0, jcol=0, pix[3], c;
938 int v[3]={0,0,0}, ver, hue;
941 if (!ljpeg_start (&jh, 0)) return;
942 jwide = (jh.wide >>= 1) * jh.clrs;
944 for (ecol=slice=0; slice <= cr2_slice[0]; slice++) {
946 ecol += cr2_slice[1] * 2 / jh.clrs;
947 if (!cr2_slice[0] || ecol > raw_width-1) ecol = raw_width & -2;
948 for (row=0; row < height; row += (jh.clrs >> 1) - 1) {
949 ip = (short (*)[4]) image + row*width;
950 for (col=scol; col < ecol; col+=2, jcol+=jh.clrs) {
951 if ((jcol %= jwide) == 0)
952 rp = (short *) ljpeg_row (jrow++, &jh);
953 if (col >= width) continue;
955 ip[col + (c >> 1)*width + (c & 1)][0] = rp[jcol+c];
956 ip[col][1] = rp[jcol+jh.clrs-2] - 16384;
957 ip[col][2] = rp[jcol+jh.clrs-1] - 16384;
961 for (cp=model2; *cp && !isdigit(*cp); cp++);
962 sscanf (cp, "%d.%d.%d", v, v+1, v+2);
963 ver = (v[0]*1000 + v[1])*1000 + v[2];
964 hue = (jh.sraw+1) << 2;
965 if (unique_id >= 0x80000281 || (unique_id == 0x80000218 && ver > 1000006))
967 ip = (short (*)[4]) image;
969 for (row=0; row < height; row++, ip+=width) {
970 if (row & (jh.sraw >> 1))
971 for (col=0; col < width; col+=2)
972 for (c=1; c < 3; c++)
974 ip[col][c] = ip[col-width][c];
975 else ip[col][c] = (ip[col-width][c] + ip[col+width][c] + 1) >> 1;
976 for (col=1; col < width; col+=2)
977 for (c=1; c < 3; c++)
979 ip[col][c] = ip[col-1][c];
980 else ip[col][c] = (ip[col-1][c] + ip[col+1][c] + 1) >> 1;
982 for ( ; rp < ip[0]; rp+=4) {
983 if (unique_id == 0x80000218 ||
984 unique_id == 0x80000250 ||
985 unique_id == 0x80000261 ||
986 unique_id == 0x80000281 ||
987 unique_id == 0x80000287) {
988 rp[1] = (rp[1] << 2) + hue;
989 rp[2] = (rp[2] << 2) + hue;
990 pix[0] = rp[0] + (( 50*rp[1] + 22929*rp[2]) >> 14);
991 pix[1] = rp[0] + ((-5640*rp[1] - 11751*rp[2]) >> 14);
992 pix[2] = rp[0] + ((29040*rp[1] - 101*rp[2]) >> 14);
994 if (unique_id < 0x80000218) rp[0] -= 512;
995 pix[0] = rp[0] + rp[2];
996 pix[2] = rp[0] + rp[1];
997 pix[1] = rp[0] + ((-778*rp[1] - (rp[2] << 11)) >> 12);
999 FORC3 rp[c] = CLIP(pix[c] * sraw_mul[c] >> 10);
1005 void CLASS adobe_copy_pixel (unsigned row, unsigned col, ushort **rp)
1009 if (is_raw == 2 && shot_select) (*rp)++;
1011 if (row < raw_height && col < raw_width)
1012 RAW(row,col) = curve[**rp];
1015 if (row < height && col < width)
1017 image[row*width+col][c] = curve[(*rp)[c]];
1018 *rp += tiff_samples;
1020 if (is_raw == 2 && shot_select) (*rp)--;
1023 void CLASS lossless_dng_load_raw()
1025 unsigned save, trow=0, tcol=0, jwide, jrow, jcol, row, col;
1029 while (trow < raw_height) {
1031 if (tile_length < INT_MAX)
1032 fseek (ifp, get4(), SEEK_SET);
1033 if (!ljpeg_start (&jh, 0)) break;
1035 if (filters) jwide *= jh.clrs;
1037 for (row=col=jrow=0; jrow < jh.high; jrow++) {
1038 rp = ljpeg_row (jrow, &jh);
1039 for (jcol=0; jcol < jwide; jcol++) {
1040 adobe_copy_pixel (trow+row, tcol+col, &rp);
1041 if (++col >= tile_width || col >= raw_width)
1042 row += 1 + (col = 0);
1045 fseek (ifp, save+4, SEEK_SET);
1046 if ((tcol += tile_width) >= raw_width)
1047 trow += tile_length + (tcol = 0);
1052 void CLASS packed_dng_load_raw()
1057 pixel = (ushort *) calloc (raw_width * tiff_samples, sizeof *pixel);
1058 merror (pixel, "packed_dng_load_raw()");
1059 for (row=0; row < raw_height; row++) {
1061 read_shorts (pixel, raw_width * tiff_samples);
1064 for (col=0; col < raw_width * tiff_samples; col++)
1065 pixel[col] = getbits(tiff_bps);
1067 for (rp=pixel, col=0; col < raw_width; col++)
1068 adobe_copy_pixel (row, col, &rp);
1073 void CLASS pentax_load_raw()
1075 ushort bit[2][15], huff[4097];
1076 int dep, row, col, diff, c, i;
1077 ushort vpred[2][2] = {{0,0},{0,0}}, hpred[2];
1079 fseek (ifp, meta_offset, SEEK_SET);
1080 dep = (get2() + 12) & 15;
1081 fseek (ifp, 12, SEEK_CUR);
1082 FORC(dep) bit[0][c] = get2();
1083 FORC(dep) bit[1][c] = fgetc(ifp);
1085 for (i=bit[0][c]; i <= ((bit[0][c]+(4096 >> bit[1][c])-1) & 4095); )
1086 huff[++i] = bit[1][c] << 8 | c;
1088 fseek (ifp, data_offset, SEEK_SET);
1090 for (row=0; row < raw_height; row++)
1091 for (col=0; col < raw_width; col++) {
1092 diff = ljpeg_diff (huff);
1093 if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
1094 else hpred[col & 1] += diff;
1095 RAW(row,col) = hpred[col & 1];
1096 if (hpred[col & 1] >> tiff_bps) derror();
1100 void CLASS nikon_load_raw()
1102 static const uchar nikon_tree[][32] = {
1103 { 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0, /* 12-bit lossy */
1104 5,4,3,6,2,7,1,0,8,9,11,10,12 },
1105 { 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0, /* 12-bit lossy after split */
1106 0x39,0x5a,0x38,0x27,0x16,5,4,3,2,1,0,11,12,12 },
1107 { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0, /* 12-bit lossless */
1108 5,4,6,3,7,2,8,1,9,0,10,11,12 },
1109 { 0,1,4,3,1,1,1,1,1,2,0,0,0,0,0,0, /* 14-bit lossy */
1110 5,6,4,7,8,3,9,2,1,0,10,11,12,13,14 },
1111 { 0,1,5,1,1,1,1,1,1,1,2,0,0,0,0,0, /* 14-bit lossy after split */
1112 8,0x5c,0x4b,0x3a,0x29,7,6,5,4,3,2,1,0,13,14 },
1113 { 0,1,4,2,2,3,1,2,0,0,0,0,0,0,0,0, /* 14-bit lossless */
1114 7,6,8,5,9,4,10,3,11,12,2,0,1,13,14 } };
1115 ushort *huff, ver0, ver1, vpred[2][2], hpred[2], csize;
1116 int i, min, max, step=0, tree=0, split=0, row, col, len, shl, diff;
1118 fseek (ifp, meta_offset, SEEK_SET);
1121 if (ver0 == 0x49 || ver1 == 0x58)
1122 fseek (ifp, 2110, SEEK_CUR);
1123 if (ver0 == 0x46) tree = 2;
1124 if (tiff_bps == 14) tree += 3;
1125 read_shorts (vpred[0], 4);
1126 max = 1 << tiff_bps & 0x7fff;
1127 if ((csize = get2()) > 1)
1128 step = max / (csize-1);
1129 if (ver0 == 0x44 && ver1 == 0x20 && step > 0) {
1130 for (i=0; i < csize; i++)
1131 curve[i*step] = get2();
1132 for (i=0; i < max; i++)
1133 curve[i] = ( curve[i-i%step]*(step-i%step) +
1134 curve[i-i%step+step]*(i%step) ) / step;
1135 fseek (ifp, meta_offset+562, SEEK_SET);
1137 } else if (ver0 != 0x46 && csize <= 0x4001)
1138 read_shorts (curve, max=csize);
1139 while (curve[max-2] == curve[max-1]) max--;
1140 huff = make_decoder (nikon_tree[tree]);
1141 fseek (ifp, data_offset, SEEK_SET);
1143 for (min=row=0; row < height; row++) {
1144 if (split && row == split) {
1146 huff = make_decoder (nikon_tree[tree+1]);
1147 max += (min = 16) << 1;
1149 for (col=0; col < raw_width; col++) {
1153 diff = ((getbits(len-shl) << 1) + 1) << shl >> 1;
1154 if ((diff & (1 << (len-1))) == 0)
1155 diff -= (1 << len) - !shl;
1156 if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
1157 else hpred[col & 1] += diff;
1158 if ((ushort)(hpred[col & 1] + min) >= max) derror();
1159 RAW(row,col) = curve[LIM((short)hpred[col & 1],0,0x3fff)];
1166 Returns 1 for a Coolpix 995, 0 for anything else.
1168 int CLASS nikon_e995()
1171 const uchar often[] = { 0x00, 0x55, 0xaa, 0xff };
1173 memset (histo, 0, sizeof histo);
1174 fseek (ifp, -2000, SEEK_END);
1175 for (i=0; i < 2000; i++)
1176 histo[fgetc(ifp)]++;
1177 for (i=0; i < 4; i++)
1178 if (histo[often[i]] < 200)
1184 Returns 1 for a Coolpix 2100, 0 for anything else.
1186 int CLASS nikon_e2100()
1191 fseek (ifp, 0, SEEK_SET);
1192 for (i=0; i < 1024; i++) {
1193 fread (t, 1, 12, ifp);
1194 if (((t[2] & t[4] & t[7] & t[9]) >> 4
1195 & t[1] & t[6] & t[8] & t[11] & 3) != 3)
1201 void CLASS nikon_3700()
1205 static const struct {
1207 char make[12], model[15];
1209 { 0x00, "PENTAX", "Optio 33WR" },
1210 { 0x03, "NIKON", "E3200" },
1211 { 0x32, "NIKON", "E3700" },
1212 { 0x33, "OLYMPUS", "C740UZ" } };
1214 fseek (ifp, 3072, SEEK_SET);
1215 fread (dp, 1, 24, ifp);
1216 bits = (dp[8] & 3) << 4 | (dp[20] & 3);
1217 for (i=0; i < sizeof table / sizeof *table; i++)
1218 if (bits == table[i].bits) {
1219 strcpy (make, table[i].make );
1220 strcpy (model, table[i].model);
1225 Separates a Minolta DiMAGE Z2 from a Nikon E4300.
1227 int CLASS minolta_z2()
1232 fseek (ifp, -sizeof tail, SEEK_END);
1233 fread (tail, 1, sizeof tail, ifp);
1234 for (nz=i=0; i < sizeof tail; i++)
1239 void CLASS jpeg_thumb();
1241 void CLASS ppm_thumb()
1244 thumb_length = thumb_width*thumb_height*3;
1245 thumb = (char *) malloc (thumb_length);
1246 merror (thumb, "ppm_thumb()");
1247 fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
1248 fread (thumb, 1, thumb_length, ifp);
1249 fwrite (thumb, 1, thumb_length, ofp);
1253 void CLASS ppm16_thumb()
1257 thumb_length = thumb_width*thumb_height*3;
1258 thumb = (char *) calloc (thumb_length,2);
1259 merror (thumb, "ppm16_thumb()");
1260 read_shorts ((ushort *) thumb, thumb_length);
1261 for (i=0; i < thumb_length; i++)
1262 thumb[i] = ((ushort *) thumb)[i] >> 8;
1263 fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
1264 fwrite (thumb, 1, thumb_length, ofp);
1268 void CLASS layer_thumb()
1271 char *thumb, map[][4] = { "012","102" };
1273 colors = thumb_misc >> 5 & 7;
1274 thumb_length = thumb_width*thumb_height;
1275 thumb = (char *) calloc (colors, thumb_length);
1276 merror (thumb, "layer_thumb()");
1277 fprintf (ofp, "P%d\n%d %d\n255\n",
1278 5 + (colors >> 1), thumb_width, thumb_height);
1279 fread (thumb, thumb_length, colors, ifp);
1280 for (i=0; i < thumb_length; i++)
1281 FORCC putc (thumb[i+thumb_length*(map[thumb_misc >> 8][c]-'0')], ofp);
1285 void CLASS rollei_thumb()
1290 thumb_length = thumb_width * thumb_height;
1291 thumb = (ushort *) calloc (thumb_length, 2);
1292 merror (thumb, "rollei_thumb()");
1293 fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
1294 read_shorts (thumb, thumb_length);
1295 for (i=0; i < thumb_length; i++) {
1296 putc (thumb[i] << 3, ofp);
1297 putc (thumb[i] >> 5 << 2, ofp);
1298 putc (thumb[i] >> 11 << 3, ofp);
1303 void CLASS rollei_load_raw()
1306 unsigned iten=0, isix, i, buffer=0, todo[16];
1308 isix = raw_width * raw_height * 5 / 8;
1309 while (fread (pixel, 1, 10, ifp) == 10) {
1310 for (i=0; i < 10; i+=2) {
1312 todo[i+1] = pixel[i] << 8 | pixel[i+1];
1313 buffer = pixel[i] >> 2 | buffer << 6;
1315 for ( ; i < 16; i+=2) {
1317 todo[i+1] = buffer >> (14-i)*5;
1319 for (i=0; i < 16; i+=2)
1320 raw_image[todo[i]] = (todo[i+1] & 0x3ff);
1325 int CLASS raw (unsigned row, unsigned col)
1327 return (row < raw_height && col < raw_width) ? RAW(row,col) : 0;
1330 void CLASS phase_one_flat_field (int is_float, int nc)
1333 unsigned wide, y, x, c, rend, cend, row, col;
1334 float *mrow, num, mult[4];
1336 read_shorts (head, 8);
1337 wide = head[2] / head[4];
1338 mrow = (float *) calloc (nc*wide, sizeof *mrow);
1339 merror (mrow, "phase_one_flat_field()");
1340 for (y=0; y < head[3] / head[5]; y++) {
1341 for (x=0; x < wide; x++)
1342 for (c=0; c < nc; c+=2) {
1343 num = is_float ? getreal(11) : get2()/32768.0;
1344 if (y==0) mrow[c*wide+x] = num;
1345 else mrow[(c+1)*wide+x] = (num - mrow[c*wide+x]) / head[5];
1348 rend = head[1] + y*head[5];
1349 for (row = rend-head[5]; row < raw_height && row < rend; row++) {
1350 for (x=1; x < wide; x++) {
1351 for (c=0; c < nc; c+=2) {
1352 mult[c] = mrow[c*wide+x-1];
1353 mult[c+1] = (mrow[c*wide+x] - mult[c]) / head[4];
1355 cend = head[0] + x*head[4];
1356 for (col = cend-head[4]; col < raw_width && col < cend; col++) {
1357 c = nc > 2 ? FC(row-top_margin,col-left_margin) : 0;
1359 c = RAW(row,col) * mult[c];
1360 RAW(row,col) = LIM(c,0,65535);
1362 for (c=0; c < nc; c+=2)
1363 mult[c] += mult[c+1];
1366 for (x=0; x < wide; x++)
1367 for (c=0; c < nc; c+=2)
1368 mrow[c*wide+x] += mrow[(c+1)*wide+x];
1374 void CLASS phase_one_correct()
1376 unsigned entries, tag, data, save, col, row, type;
1377 int len, i, j, k, cip, val[4], dev[4], sum, max;
1378 int head[9], diff, mindiff=INT_MAX, off_412=0;
1379 static const signed char dir[12][2] =
1380 { {-1,-1}, {-1,1}, {1,-1}, {1,1}, {-2,0}, {0,-2}, {0,2}, {2,0},
1381 {-2,-2}, {-2,2}, {2,-2}, {2,2} };
1382 float poly[8], num, cfrac, frac, mult[2], *yval[2];
1385 if (half_size || !meta_length) return;
1386 if (verbose) fprintf (stderr,_("Phase One correction...\n"));
1387 fseek (ifp, meta_offset, SEEK_SET);
1389 fseek (ifp, 6, SEEK_CUR);
1390 fseek (ifp, meta_offset+get4(), SEEK_SET);
1391 entries = get4(); get4();
1397 fseek (ifp, meta_offset+data, SEEK_SET);
1398 if (tag == 0x419) { /* Polynomial curve */
1399 for (get4(), i=0; i < 8; i++)
1400 poly[i] = getreal(11);
1401 poly[3] += (ph1.tag_210 - poly[7]) * poly[6] + 1;
1402 for (i=0; i < 0x10000; i++) {
1403 num = (poly[5]*i + poly[3])*i + poly[1];
1404 curve[i] = LIM(num,0,65535);
1405 } goto apply; /* apply to right half */
1406 } else if (tag == 0x41a) { /* Polynomial curve */
1407 for (i=0; i < 4; i++)
1408 poly[i] = getreal(11);
1409 for (i=0; i < 0x10000; i++) {
1410 for (num=0, j=4; j--; )
1411 num = num * i + poly[j];
1412 curve[i] = LIM(num+i,0,65535);
1413 } apply: /* apply to whole image */
1414 for (row=0; row < raw_height; row++)
1415 for (col = (tag & 1)*ph1.split_col; col < raw_width; col++)
1416 RAW(row,col) = curve[RAW(row,col)];
1417 } else if (tag == 0x400) { /* Sensor defects */
1418 while ((len -= 8) >= 0) {
1421 type = get2(); get2();
1422 if (col >= raw_width) continue;
1423 if (type == 131) /* Bad column */
1424 for (row=0; row < raw_height; row++)
1425 if (FC(row-top_margin,col-left_margin) == 1) {
1426 for (sum=i=0; i < 4; i++)
1427 sum += val[i] = raw (row+dir[i][0], col+dir[i][1]);
1428 for (max=i=0; i < 4; i++) {
1429 dev[i] = abs((val[i] << 2) - sum);
1430 if (dev[max] < dev[i]) max = i;
1432 RAW(row,col) = (sum - val[max])/3.0 + 0.5;
1434 for (sum=0, i=8; i < 12; i++)
1435 sum += raw (row+dir[i][0], col+dir[i][1]);
1436 RAW(row,col) = 0.5 + sum * 0.0732233 +
1437 (raw(row,col-2) + raw(row,col+2)) * 0.3535534;
1439 else if (type == 129) { /* Bad pixel */
1440 if (row >= raw_height) continue;
1441 j = (FC(row-top_margin,col-left_margin) != 1) * 4;
1442 for (sum=0, i=j; i < j+8; i++)
1443 sum += raw (row+dir[i][0], col+dir[i][1]);
1444 RAW(row,col) = (sum + 4) >> 3;
1447 } else if (tag == 0x401) { /* All-color flat fields */
1448 phase_one_flat_field (1, 2);
1449 } else if (tag == 0x416 || tag == 0x410) {
1450 phase_one_flat_field (0, 2);
1451 } else if (tag == 0x40b) { /* Red+blue flat field */
1452 phase_one_flat_field (0, 4);
1453 } else if (tag == 0x412) {
1454 fseek (ifp, 36, SEEK_CUR);
1455 diff = abs (get2() - ph1.tag_21a);
1456 if (mindiff > diff) {
1458 off_412 = ftell(ifp) - 38;
1461 fseek (ifp, save, SEEK_SET);
1464 fseek (ifp, off_412, SEEK_SET);
1465 for (i=0; i < 9; i++) head[i] = get4() & 0x7fff;
1466 yval[0] = (float *) calloc (head[1]*head[3] + head[2]*head[4], 6);
1467 merror (yval[0], "phase_one_correct()");
1468 yval[1] = (float *) (yval[0] + head[1]*head[3]);
1469 xval[0] = (ushort *) (yval[1] + head[2]*head[4]);
1470 xval[1] = (ushort *) (xval[0] + head[1]*head[3]);
1472 for (i=0; i < 2; i++)
1473 for (j=0; j < head[i+1]*head[i+3]; j++)
1474 yval[i][j] = getreal(11);
1475 for (i=0; i < 2; i++)
1476 for (j=0; j < head[i+1]*head[i+3]; j++)
1477 xval[i][j] = get2();
1478 for (row=0; row < raw_height; row++)
1479 for (col=0; col < raw_width; col++) {
1480 cfrac = (float) col * head[3] / raw_width;
1481 cfrac -= cip = cfrac;
1482 num = RAW(row,col) * 0.5;
1483 for (i=cip; i < cip+2; i++) {
1484 for (k=j=0; j < head[1]; j++)
1485 if (num < xval[0][k = head[1]*i+j]) break;
1486 frac = (j == 0 || j == head[1]) ? 0 :
1487 (xval[0][k] - num) / (xval[0][k] - xval[0][k-1]);
1488 mult[i-cip] = yval[0][k-1] * frac + yval[0][k] * (1-frac);
1490 i = ((mult[0] * (1-cfrac) + mult[1] * cfrac) * row + num) * 2;
1491 RAW(row,col) = LIM(i,0,65535);
1497 void CLASS phase_one_load_raw()
1500 ushort akey, bkey, mask;
1502 fseek (ifp, ph1.key_off, SEEK_SET);
1505 mask = ph1.format == 1 ? 0x5555:0x1354;
1506 fseek (ifp, data_offset, SEEK_SET);
1507 read_shorts (raw_image, raw_width*raw_height);
1509 for (i=0; i < raw_width*raw_height; i+=2) {
1510 a = raw_image[i+0] ^ akey;
1511 b = raw_image[i+1] ^ bkey;
1512 raw_image[i+0] = (a & mask) | (b & ~mask);
1513 raw_image[i+1] = (b & mask) | (a & ~mask);
1517 unsigned CLASS ph1_bithuff (int nbits, ushort *huff)
1519 static UINT64 bitbuf=0;
1524 return bitbuf = vbits = 0;
1525 if (nbits == 0) return 0;
1526 if (vbits < nbits) {
1527 bitbuf = bitbuf << 32 | get4();
1530 c = bitbuf << (64-vbits) >> (64-nbits);
1532 vbits -= huff[c] >> 8;
1533 return (uchar) huff[c];
1538 #define ph1_bits(n) ph1_bithuff(n,0)
1539 #define ph1_huff(h) ph1_bithuff(*h,h+1)
1541 void CLASS phase_one_load_raw_c()
1543 static const int length[] = { 8,7,6,9,11,10,5,12,14,13 };
1544 int *offset, len[2], pred[2], row, col, i, j;
1548 pixel = (ushort *) calloc (raw_width + raw_height*4, 2);
1549 merror (pixel, "phase_one_load_raw_c()");
1550 offset = (int *) (pixel + raw_width);
1551 fseek (ifp, strip_offset, SEEK_SET);
1552 for (row=0; row < raw_height; row++)
1553 offset[row] = get4();
1554 black = (short (*)[2]) offset + raw_height;
1555 fseek (ifp, ph1.black_off, SEEK_SET);
1557 read_shorts ((ushort *) black[0], raw_height*2);
1558 for (i=0; i < 256; i++)
1559 curve[i] = i*i / 3.969 + 0.5;
1560 for (row=0; row < raw_height; row++) {
1561 fseek (ifp, data_offset + offset[row], SEEK_SET);
1563 pred[0] = pred[1] = 0;
1564 for (col=0; col < raw_width; col++) {
1565 if (col >= (raw_width & -8))
1566 len[0] = len[1] = 14;
1567 else if ((col & 7) == 0)
1568 for (i=0; i < 2; i++) {
1569 for (j=0; j < 5 && !ph1_bits(1); j++);
1570 if (j--) len[i] = length[j*2 + ph1_bits(1)];
1572 if ((i = len[col & 1]) == 14)
1573 pixel[col] = pred[col & 1] = ph1_bits(16);
1575 pixel[col] = pred[col & 1] += ph1_bits(i) + 1 - (1 << (i - 1));
1576 if (pred[col & 1] >> 16) derror();
1577 if (ph1.format == 5 && pixel[col] < 256)
1578 pixel[col] = curve[pixel[col]];
1580 for (col=0; col < raw_width; col++) {
1581 i = (pixel[col] << 2) - ph1.black + black[row][col >= ph1.split_col];
1582 if (i > 0) RAW(row,col) = i;
1586 maximum = 0xfffc - ph1.black;
1589 void CLASS hasselblad_load_raw()
1592 int row, col, pred[2], len[2], diff, c;
1594 if (!ljpeg_start (&jh, 0)) return;
1597 for (row=0; row < raw_height; row++) {
1598 pred[0] = pred[1] = 0x8000 + load_flags;
1599 for (col=0; col < raw_width; col+=2) {
1600 FORC(2) len[c] = ph1_huff(jh.huff[0]);
1602 diff = ph1_bits(len[c]);
1603 if ((diff & (1 << (len[c]-1))) == 0)
1604 diff -= (1 << len[c]) - 1;
1605 if (diff == 65535) diff = -32768;
1606 RAW(row,col+c) = pred[c] += diff;
1614 void CLASS leaf_hdr_load_raw()
1617 unsigned tile=0, r, c, row, col;
1620 pixel = (ushort *) calloc (raw_width, sizeof *pixel);
1621 merror (pixel, "leaf_hdr_load_raw()");
1624 for (r=0; r < raw_height; r++) {
1625 if (r % tile_length == 0) {
1626 fseek (ifp, data_offset + 4*tile++, SEEK_SET);
1627 fseek (ifp, get4(), SEEK_SET);
1629 if (filters && c != shot_select) continue;
1630 if (filters) pixel = raw_image + r*raw_width;
1631 read_shorts (pixel, raw_width);
1632 if (!filters && (row = r - top_margin) < height)
1633 for (col=0; col < width; col++)
1634 image[row*width+col][c] = pixel[col+left_margin];
1643 void CLASS unpacked_load_raw()
1645 int row, col, bits=0;
1647 while (1 << ++bits < maximum);
1648 read_shorts (raw_image, raw_width*raw_height);
1649 for (row=0; row < raw_height; row++)
1650 for (col=0; col < raw_width; col++)
1651 if ((RAW(row,col) >>= load_flags) >> bits
1652 && (unsigned) (row-top_margin) < height
1653 && (unsigned) (col-left_margin) < width) derror();
1656 void CLASS sinar_4shot_load_raw()
1659 unsigned shot, row, col, r, c;
1661 if ((shot = shot_select) || half_size) {
1663 if (shot > 3) shot = 3;
1664 fseek (ifp, data_offset + shot*4, SEEK_SET);
1665 fseek (ifp, get4(), SEEK_SET);
1666 unpacked_load_raw();
1672 image = (ushort (*)[4])
1673 calloc ((iheight=height)*(iwidth=width), sizeof *image);
1674 merror (image, "sinar_4shot_load_raw()");
1675 pixel = (ushort *) calloc (raw_width, sizeof *pixel);
1676 merror (pixel, "sinar_4shot_load_raw()");
1677 for (shot=0; shot < 4; shot++) {
1678 fseek (ifp, data_offset + shot*4, SEEK_SET);
1679 fseek (ifp, get4(), SEEK_SET);
1680 for (row=0; row < raw_height; row++) {
1681 read_shorts (pixel, raw_width);
1682 if ((r = row-top_margin - (shot >> 1 & 1)) >= height) continue;
1683 for (col=0; col < raw_width; col++) {
1684 if ((c = col-left_margin - (shot & 1)) >= width) continue;
1685 image[r*width+c][FC(row,col)] = pixel[col];
1690 shrink = filters = 0;
1693 void CLASS imacon_full_load_raw()
1697 for (row=0; row < height; row++)
1698 for (col=0; col < width; col++)
1699 read_shorts (image[row*width+col], 3);
1702 void CLASS packed_load_raw()
1704 int vbits=0, bwide, pwide, rbits, bite, half, irow, row, col, val, i;
1707 if (raw_width * 8 >= width * tiff_bps) /* Is raw_width in bytes? */
1708 pwide = (bwide = raw_width) * 8 / tiff_bps;
1709 else bwide = (pwide = raw_width) * tiff_bps / 8;
1710 rbits = bwide * 8 - pwide * tiff_bps;
1711 if (load_flags & 1) bwide = bwide * 16 / 15;
1712 bite = 8 + (load_flags & 24);
1713 half = (raw_height+1) >> 1;
1714 for (irow=0; irow < raw_height; irow++) {
1716 if (load_flags & 2 &&
1717 (row = irow % half * 2 + irow / half) == 1 &&
1719 if (vbits=0, tiff_compress)
1720 fseek (ifp, data_offset - (-half*bwide & -2048), SEEK_SET);
1722 fseek (ifp, 0, SEEK_END);
1723 fseek (ifp, ftell(ifp) >> 3 << 2, SEEK_SET);
1726 for (col=0; col < pwide; col++) {
1727 for (vbits -= tiff_bps; vbits < 0; vbits += bite) {
1729 for (i=0; i < bite; i+=8)
1730 bitbuf |= (unsigned) (fgetc(ifp) << i);
1732 val = bitbuf << (64-tiff_bps-vbits) >> (64-tiff_bps);
1733 RAW(row,col ^ (load_flags >> 6)) = val;
1734 if (load_flags & 1 && (col % 10) == 9 &&
1735 fgetc(ifp) && col < width+left_margin) derror();
1741 void CLASS nokia_load_raw()
1744 int rev, dwide, row, col, c;
1746 rev = 3 * (order == 0x4949);
1747 dwide = raw_width * 5 / 4;
1748 data = (uchar *) malloc (dwide*2);
1749 merror (data, "nokia_load_raw()");
1750 for (row=0; row < raw_height; row++) {
1751 if (fread (data+dwide, 1, dwide, ifp) < dwide) derror();
1752 FORC(dwide) data[c] = data[dwide+(c ^ rev)];
1753 for (dp=data, col=0; col < raw_width; dp+=5, col+=4)
1754 FORC4 RAW(row,col+c) = (dp[c] << 2) | (dp[4] >> (c << 1) & 3);
1760 unsigned CLASS pana_bits (int nbits)
1762 static uchar buf[0x4000];
1766 if (!nbits) return vbits=0;
1768 fread (buf+load_flags, 1, 0x4000-load_flags, ifp);
1769 fread (buf, 1, load_flags, ifp);
1771 vbits = (vbits - nbits) & 0x1ffff;
1772 byte = vbits >> 3 ^ 0x3ff0;
1773 return (buf[byte] | buf[byte+1] << 8) >> (vbits & 7) & ~(-1 << nbits);
1776 void CLASS panasonic_load_raw()
1778 int row, col, i, j, sh=0, pred[2], nonz[2];
1781 for (row=0; row < height; row++)
1782 for (col=0; col < raw_width; col++) {
1783 if ((i = col % 14) == 0)
1784 pred[0] = pred[1] = nonz[0] = nonz[1] = 0;
1785 if (i % 3 == 2) sh = 4 >> (3 - pana_bits(2));
1787 if ((j = pana_bits(8))) {
1788 if ((pred[i & 1] -= 0x80 << sh) < 0 || sh == 4)
1789 pred[i & 1] &= ~(-1 << sh);
1790 pred[i & 1] += j << sh;
1792 } else if ((nonz[i & 1] = pana_bits(8)) || i > 11)
1793 pred[i & 1] = nonz[i & 1] << 4 | pana_bits(4);
1794 if ((RAW(row,col) = pred[col & 1]) > 4098 && col < width) derror();
1798 void CLASS olympus_load_raw()
1801 int row, col, nbits, sign, low, high, i, c, w, n, nw;
1802 int acarry[2][3], *carry, pred, diff;
1806 FORC(2048 >> i) huff[++n] = (i+1) << 8 | i;
1807 fseek (ifp, 7, SEEK_CUR);
1809 for (row=0; row < height; row++) {
1810 memset (acarry, 0, sizeof acarry);
1811 for (col=0; col < raw_width; col++) {
1812 carry = acarry[col & 1];
1813 i = 2 * (carry[2] < 3);
1814 for (nbits=2+i; (ushort) carry[0] >> (nbits+i); nbits++);
1815 low = (sign = getbits(3)) & 3;
1816 sign = sign << 29 >> 31;
1817 if ((high = getbithuff(12,huff)) == 12)
1818 high = getbits(16-nbits) >> 1;
1819 carry[0] = (high << nbits) | getbits(nbits);
1820 diff = (carry[0] ^ sign) + carry[1];
1821 carry[1] = (diff*3 + carry[1]) >> 5;
1822 carry[2] = carry[0] > 16 ? 0 : carry[2]+1;
1823 if (col >= width) continue;
1824 if (row < 2 && col < 2) pred = 0;
1825 else if (row < 2) pred = RAW(row,col-2);
1826 else if (col < 2) pred = RAW(row-2,col);
1830 nw = RAW(row-2,col-2);
1831 if ((w < nw && nw < n) || (n < nw && nw < w)) {
1832 if (ABS(w-nw) > 32 || ABS(n-nw) > 32)
1834 else pred = (w + n) >> 1;
1835 } else pred = ABS(w-nw) > ABS(n-nw) ? w : n;
1837 if ((RAW(row,col) = pred + ((diff << 2) | low)) >> 12) derror();
1842 void CLASS minolta_rd175_load_raw()
1845 unsigned irow, box, row, col;
1847 for (irow=0; irow < 1481; irow++) {
1848 if (fread (pixel, 1, 768, ifp) < 768) derror();
1850 row = irow % 82 * 12 + ((box < 12) ? box | 1 : (box-12)*2);
1852 case 1477: case 1479: continue;
1853 case 1476: row = 984; break;
1854 case 1480: row = 985; break;
1855 case 1478: row = 985; box = 1;
1857 if ((box < 12) && (box & 1)) {
1858 for (col=0; col < 1533; col++, row ^= 1)
1859 if (col != 1) RAW(row,col) = (col+1) & 2 ?
1860 pixel[col/2-1] + pixel[col/2+1] : pixel[col/2] << 1;
1861 RAW(row,1) = pixel[1] << 1;
1862 RAW(row,1533) = pixel[765] << 1;
1864 for (col=row & 1; col < 1534; col+=2)
1865 RAW(row,col) = pixel[col/2] << 1;
1867 maximum = 0xff << 1;
1870 void CLASS quicktake_100_load_raw()
1872 uchar pixel[484][644];
1873 static const short gstep[16] =
1874 { -89,-60,-44,-32,-22,-15,-8,-2,2,8,15,22,32,44,60,89 };
1875 static const short rstep[6][4] =
1876 { { -3,-1,1,3 }, { -5,-1,1,5 }, { -8,-2,2,8 },
1877 { -13,-3,3,13 }, { -19,-4,4,19 }, { -28,-6,6,28 } };
1878 static const short curve[256] =
1879 { 0,1,2,3,4,5,6,7,8,9,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,
1880 28,29,30,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,53,
1881 54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,74,75,76,77,78,
1882 79,80,81,82,83,84,86,88,90,92,94,97,99,101,103,105,107,110,112,114,116,
1883 118,120,123,125,127,129,131,134,136,138,140,142,144,147,149,151,153,155,
1884 158,160,162,164,166,168,171,173,175,177,179,181,184,186,188,190,192,195,
1885 197,199,201,203,205,208,210,212,214,216,218,221,223,226,230,235,239,244,
1886 248,252,257,261,265,270,274,278,283,287,291,296,300,305,309,313,318,322,
1887 326,331,335,339,344,348,352,357,361,365,370,374,379,383,387,392,396,400,
1888 405,409,413,418,422,426,431,435,440,444,448,453,457,461,466,470,474,479,
1889 483,487,492,496,500,508,519,531,542,553,564,575,587,598,609,620,631,643,
1890 654,665,676,687,698,710,721,732,743,754,766,777,788,799,810,822,833,844,
1891 855,866,878,889,900,911,922,933,945,956,967,978,989,1001,1012,1023 };
1892 int rb, row, col, sharp, val=0;
1895 memset (pixel, 0x80, sizeof pixel);
1896 for (row=2; row < height+2; row++) {
1897 for (col=2+(row & 1); col < width+2; col+=2) {
1898 val = ((pixel[row-1][col-1] + 2*pixel[row-1][col+1] +
1899 pixel[row][col-2]) >> 2) + gstep[getbits(4)];
1900 pixel[row][col] = val = LIM(val,0,255);
1902 pixel[row][col-2] = pixel[row+1][~row & 1] = val;
1904 pixel[row-1][col+1] = pixel[row-1][col+3] = val;
1906 pixel[row][col] = val;
1908 for (rb=0; rb < 2; rb++)
1909 for (row=2+rb; row < height+2; row+=2)
1910 for (col=3-(row & 1); col < width+2; col+=2) {
1911 if (row < 4 || col < 4) sharp = 2;
1913 val = ABS(pixel[row-2][col] - pixel[row][col-2])
1914 + ABS(pixel[row-2][col] - pixel[row-2][col-2])
1915 + ABS(pixel[row][col-2] - pixel[row-2][col-2]);
1916 sharp = val < 4 ? 0 : val < 8 ? 1 : val < 16 ? 2 :
1917 val < 32 ? 3 : val < 48 ? 4 : 5;
1919 val = ((pixel[row-2][col] + pixel[row][col-2]) >> 1)
1920 + rstep[sharp][getbits(2)];
1921 pixel[row][col] = val = LIM(val,0,255);
1922 if (row < 4) pixel[row-2][col+2] = val;
1923 if (col < 4) pixel[row+2][col-2] = val;
1925 for (row=2; row < height+2; row++)
1926 for (col=3-(row & 1); col < width+2; col+=2) {
1927 val = ((pixel[row][col-1] + (pixel[row][col] << 2) +
1928 pixel[row][col+1]) >> 1) - 0x100;
1929 pixel[row][col] = LIM(val,0,255);
1931 for (row=0; row < height; row++)
1932 for (col=0; col < width; col++)
1933 RAW(row,col) = curve[pixel[row+2][col+2]];
1937 #define radc_token(tree) ((signed char) getbithuff(8,huff[tree]))
1939 #define FORYX for (y=1; y < 3; y++) for (x=col+1; x >= col; x--)
1941 #define PREDICTOR (c ? (buf[c][y-1][x] + buf[c][y][x+1]) / 2 \
1942 : (buf[c][y-1][x+1] + 2*buf[c][y-1][x] + buf[c][y][x+1]) / 4)
1944 void CLASS kodak_radc_load_raw()
1946 static const char src[] = {
1947 1,1, 2,3, 3,4, 4,2, 5,7, 6,5, 7,6, 7,8,
1948 1,0, 2,1, 3,3, 4,4, 5,2, 6,7, 7,6, 8,5, 8,8,
1949 2,1, 2,3, 3,0, 3,2, 3,4, 4,6, 5,5, 6,7, 6,8,
1950 2,0, 2,1, 2,3, 3,2, 4,4, 5,6, 6,7, 7,5, 7,8,
1951 2,1, 2,4, 3,0, 3,2, 3,3, 4,7, 5,5, 6,6, 6,8,
1952 2,3, 3,1, 3,2, 3,4, 3,5, 3,6, 4,7, 5,0, 5,8,
1953 2,3, 2,6, 3,0, 3,1, 4,4, 4,5, 4,7, 5,2, 5,8,
1954 2,4, 2,7, 3,3, 3,6, 4,1, 4,2, 4,5, 5,0, 5,8,
1955 2,6, 3,1, 3,3, 3,5, 3,7, 3,8, 4,0, 5,2, 5,4,
1956 2,0, 2,1, 3,2, 3,3, 4,4, 4,5, 5,6, 5,7, 4,8,
1959 2,-17, 2,-5, 2,5, 2,17,
1960 2,-7, 2,2, 2,9, 2,18,
1961 2,-18, 2,-9, 2,-2, 2,7,
1962 2,-28, 2,28, 3,-49, 3,-9, 3,9, 4,49, 5,-79, 5,79,
1963 2,-1, 2,13, 2,26, 3,39, 4,-16, 5,55, 6,-37, 6,76,
1964 2,-26, 2,-13, 2,1, 3,-39, 4,16, 5,-55, 6,-76, 6,37
1966 ushort huff[19][256];
1967 int row, col, tree, nreps, rep, step, i, c, s, r, x, y, val;
1968 short last[3] = { 16,16,16 }, mul[3], buf[3][3][386], *bp;
1969 static const ushort pt[] =
1970 { 0,0, 1280,1344, 2320,3616, 3328,8000, 4095,16383, 65535,16383 };
1972 for (i=2; i < 12; i+=2)
1973 for (c=pt[i-2]; c <= pt[i]; c++)
1975 (c-pt[i-2]) / (pt[i]-pt[i-2]) * (pt[i+1]-pt[i-1]) + pt[i-1] + 0.5;
1976 for (s=i=0; i < sizeof src; i+=2)
1978 huff[0][s++] = src[i] << 8 | (uchar) src[i+1];
1979 s = kodak_cbpp == 243 ? 2 : 3;
1980 FORC(256) huff[18][c] = (8-s) << 8 | c >> s << s | 1 << (s-1);
1982 for ( bp=&buf[0][0][0],i=sizeof(buf)/sizeof(*bp); --i>=0; ++bp )
1984 for (row=0; row < height; row+=4) {
1985 FORC3 mul[c] = getbits(6);
1987 val = ((0x1000000/last[c] + 0x7ff) >> 12) * mul[c];
1988 s = val > 65564 ? 10:12;
1991 for (i=0; i < sizeof(buf[0])/sizeof(short); i++)
1992 for ( bp=&buf[c][0][0],i=sizeof(buf[0])/sizeof(*bp); --i>=0; ++bp )
1993 *bp = (*bp * val + x) >> s;
1995 for (r=0; r <= !c; r++) {
1996 buf[c][1][width/2] = buf[c][2][width/2] = mul[c] << 7;
1997 for (tree=1, col=width/2; col > 0; ) {
1998 if ((tree = radc_token(tree))) {
2001 FORYX buf[c][y][x] = (uchar) radc_token(18) * mul[c];
2003 FORYX buf[c][y][x] = radc_token(tree+10) * 16 + PREDICTOR;
2006 nreps = (col > 2) ? radc_token(9) + 1 : 1;
2007 for (rep=0; rep < 8 && rep < nreps && col > 0; rep++) {
2009 FORYX buf[c][y][x] = PREDICTOR;
2011 step = radc_token(10) << 4;
2012 FORYX buf[c][y][x] += step;
2015 } while (nreps == 9);
2017 for (y=0; y < 2; y++)
2018 for (x=0; x < width/2; x++) {
2019 val = (buf[c][y+1][x] << 4) / mul[c];
2020 if (val < 0) val = 0;
2021 if (c) RAW(row+y*2+c-1,x*2+2-c) = val;
2022 else RAW(row+r*2+y,x*2+y) = val;
2024 memcpy (buf[c][0]+!c, buf[c][2], sizeof buf[c][0]-2*!c);
2027 for (y=row; y < row+4; y++)
2028 for (x=0; x < width; x++)
2031 s = x+1 < width ? x+1 : x-1;
2032 val = (RAW(y,x)-2048)*2 + (RAW(y,r)+RAW(y,s))/2;
2033 if (val < 0) val = 0;
2037 for (i=0; i < height*width; i++)
2038 raw_image[i] = curve[raw_image[i]];
2046 void CLASS kodak_jpeg_load_raw() {}
2047 void CLASS lossy_dng_load_raw() {}
2051 fill_input_buffer (j_decompress_ptr cinfo)
2053 static uchar jpeg_buffer[4096];
2056 nbytes = fread (jpeg_buffer, 1, 4096, ifp);
2057 swab (jpeg_buffer, jpeg_buffer, nbytes);
2058 cinfo->src->next_input_byte = jpeg_buffer;
2059 cinfo->src->bytes_in_buffer = nbytes;
2063 void CLASS kodak_jpeg_load_raw()
2065 struct jpeg_decompress_struct cinfo;
2066 struct jpeg_error_mgr jerr;
2068 JSAMPLE (*pixel)[3];
2071 cinfo.err = jpeg_std_error (&jerr);
2072 jpeg_create_decompress (&cinfo);
2073 jpeg_stdio_src (&cinfo, ifp);
2074 cinfo.src->fill_input_buffer = fill_input_buffer;
2075 jpeg_read_header (&cinfo, TRUE);
2076 jpeg_start_decompress (&cinfo);
2077 if ((cinfo.output_width != width ) ||
2078 (cinfo.output_height*2 != height ) ||
2079 (cinfo.output_components != 3 )) {
2080 fprintf (stderr,_("%s: incorrect JPEG dimensions\n"), ifname);
2081 jpeg_destroy_decompress (&cinfo);
2082 longjmp (failure, 3);
2084 buf = (*cinfo.mem->alloc_sarray)
2085 ((j_common_ptr) &cinfo, JPOOL_IMAGE, width*3, 1);
2087 while (cinfo.output_scanline < cinfo.output_height) {
2088 row = cinfo.output_scanline * 2;
2089 jpeg_read_scanlines (&cinfo, buf, 1);
2090 pixel = (JSAMPLE (*)[3]) buf[0];
2091 for (col=0; col < width; col+=2) {
2092 RAW(row+0,col+0) = pixel[col+0][1] << 1;
2093 RAW(row+1,col+1) = pixel[col+1][1] << 1;
2094 RAW(row+0,col+1) = pixel[col][0] + pixel[col+1][0];
2095 RAW(row+1,col+0) = pixel[col][2] + pixel[col+1][2];
2098 jpeg_finish_decompress (&cinfo);
2099 jpeg_destroy_decompress (&cinfo);
2100 maximum = 0xff << 1;
2103 void CLASS lossy_dng_load_raw()
2105 struct jpeg_decompress_struct cinfo;
2106 struct jpeg_error_mgr jerr;
2108 JSAMPLE (*pixel)[3];
2109 unsigned sorder=order, ntags, opcode, deg, i, j, c;
2110 unsigned save=data_offset-4, trow=0, tcol=0, row, col;
2111 ushort curve[3][256];
2112 double coeff[9], tot;
2114 fseek (ifp, meta_offset, SEEK_SET);
2118 opcode = get4(); get4(); get4();
2120 { fseek (ifp, get4(), SEEK_CUR); continue; }
2121 fseek (ifp, 20, SEEK_CUR);
2122 if ((c = get4()) > 2) break;
2123 fseek (ifp, 12, SEEK_CUR);
2124 if ((deg = get4()) > 8) break;
2125 for (i=0; i <= deg && i < 9; i++)
2126 coeff[i] = getreal(12);
2127 for (i=0; i < 256; i++) {
2128 for (tot=j=0; j <= deg; j++)
2129 tot += coeff[j] * pow(i/255.0, j);
2130 curve[c][i] = tot*0xffff;
2134 cinfo.err = jpeg_std_error (&jerr);
2135 jpeg_create_decompress (&cinfo);
2136 while (trow < raw_height) {
2137 fseek (ifp, save+=4, SEEK_SET);
2138 if (tile_length < INT_MAX)
2139 fseek (ifp, get4(), SEEK_SET);
2140 jpeg_stdio_src (&cinfo, ifp);
2141 jpeg_read_header (&cinfo, TRUE);
2142 jpeg_start_decompress (&cinfo);
2143 buf = (*cinfo.mem->alloc_sarray)
2144 ((j_common_ptr) &cinfo, JPOOL_IMAGE, cinfo.output_width*3, 1);
2145 while (cinfo.output_scanline < cinfo.output_height &&
2146 (row = trow + cinfo.output_scanline) < height) {
2147 jpeg_read_scanlines (&cinfo, buf, 1);
2148 pixel = (JSAMPLE (*)[3]) buf[0];
2149 for (col=0; col < cinfo.output_width && tcol+col < width; col++) {
2150 FORC3 image[row*width+tcol+col][c] = curve[c][pixel[col][c]];
2153 jpeg_abort_decompress (&cinfo);
2154 if ((tcol += tile_width) >= raw_width)
2155 trow += tile_length + (tcol = 0);
2157 jpeg_destroy_decompress (&cinfo);
2162 void CLASS kodak_dc120_load_raw()
2164 static const int mul[4] = { 162, 192, 187, 92 };
2165 static const int add[4] = { 0, 636, 424, 212 };
2167 int row, shift, col;
2169 for (row=0; row < height; row++) {
2170 if (fread (pixel, 1, 848, ifp) < 848) derror();
2171 shift = row * mul[row & 3] + add[row & 3];
2172 for (col=0; col < width; col++)
2173 RAW(row,col) = (ushort) pixel[(col + shift) % 848];
2178 void CLASS eight_bit_load_raw()
2183 pixel = (uchar *) calloc (raw_width, sizeof *pixel);
2184 merror (pixel, "eight_bit_load_raw()");
2185 for (row=0; row < raw_height; row++) {
2186 if (fread (pixel, 1, raw_width, ifp) < raw_width) derror();
2187 for (col=0; col < raw_width; col++)
2188 RAW(row,col) = curve[pixel[col]];
2191 maximum = curve[0xff];
2194 void CLASS kodak_yrgb_load_raw()
2197 int row, col, y, cb, cr, rgb[3], c;
2199 pixel = (uchar *) calloc (raw_width, 3*sizeof *pixel);
2200 merror (pixel, "kodak_yrgb_load_raw()");
2201 for (row=0; row < height; row++) {
2203 if (fread (pixel, raw_width, 3, ifp) < 3) derror();
2204 for (col=0; col < raw_width; col++) {
2205 y = pixel[width*2*(row & 1) + col];
2206 cb = pixel[width + (col & -2)] - 128;
2207 cr = pixel[width + (col & -2)+1] - 128;
2208 rgb[1] = y-((cb + cr + 2) >> 2);
2209 rgb[2] = rgb[1] + cb;
2210 rgb[0] = rgb[1] + cr;
2211 FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,255)];
2215 maximum = curve[0xff];
2218 void CLASS kodak_262_load_raw()
2220 static const uchar kodak_tree[2][26] =
2221 { { 0,1,5,1,1,2,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9 },
2222 { 0,3,1,1,1,1,1,2,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9 } };
2225 int *strip, ns, c, row, col, chess, pi=0, pi1, pi2, pred, val;
2227 FORC(2) huff[c] = make_decoder (kodak_tree[c]);
2228 ns = (raw_height+63) >> 5;
2229 pixel = (uchar *) malloc (raw_width*32 + ns*4);
2230 merror (pixel, "kodak_262_load_raw()");
2231 strip = (int *) (pixel + raw_width*32);
2233 FORC(ns) strip[c] = get4();
2234 for (row=0; row < raw_height; row++) {
2235 if ((row & 31) == 0) {
2236 fseek (ifp, strip[row >> 5], SEEK_SET);
2240 for (col=0; col < raw_width; col++) {
2241 chess = (row + col) & 1;
2242 pi1 = chess ? pi-2 : pi-raw_width-1;
2243 pi2 = chess ? pi-2*raw_width : pi-raw_width+1;
2244 if (col <= chess) pi1 = -1;
2245 if (pi1 < 0) pi1 = pi2;
2246 if (pi2 < 0) pi2 = pi1;
2247 if (pi1 < 0 && col > 1) pi1 = pi2 = pi-2;
2248 pred = (pi1 < 0) ? 0 : (pixel[pi1] + pixel[pi2]) >> 1;
2249 pixel[pi] = val = pred + ljpeg_diff (huff[chess]);
2250 if (val >> 8) derror();
2251 val = curve[pixel[pi++]];
2256 FORC(2) free (huff[c]);
2259 int CLASS kodak_65000_decode (short *out, int bsize)
2264 int save, bits=0, i, j, len, diff;
2267 bsize = (bsize + 3) & -4;
2268 for (i=0; i < bsize; i+=2) {
2270 if ((blen[i ] = c & 15) > 12 ||
2271 (blen[i+1] = c >> 4) > 12 ) {
2272 fseek (ifp, save, SEEK_SET);
2273 for (i=0; i < bsize; i+=8) {
2274 read_shorts (raw, 6);
2275 out[i ] = raw[0] >> 12 << 8 | raw[2] >> 12 << 4 | raw[4] >> 12;
2276 out[i+1] = raw[1] >> 12 << 8 | raw[3] >> 12 << 4 | raw[5] >> 12;
2277 for (j=0; j < 6; j++)
2278 out[i+2+j] = raw[j] & 0xfff;
2283 if ((bsize & 7) == 4) {
2284 bitbuf = fgetc(ifp) << 8;
2285 bitbuf += fgetc(ifp);
2288 for (i=0; i < bsize; i++) {
2291 for (j=0; j < 32; j+=8)
2292 bitbuf += (INT64) fgetc(ifp) << (bits+(j^8));
2295 diff = bitbuf & (0xffff >> (16-len));
2298 if ((diff & (1 << (len-1))) == 0)
2299 diff -= (1 << len) - 1;
2305 void CLASS kodak_65000_load_raw()
2308 int row, col, len, pred[2], ret, i;
2310 for (row=0; row < height; row++)
2311 for (col=0; col < width; col+=256) {
2312 pred[0] = pred[1] = 0;
2313 len = MIN (256, width-col);
2314 ret = kodak_65000_decode (buf, len);
2315 for (i=0; i < len; i++)
2316 if ((RAW(row,col+i) = curve[ret ? buf[i] :
2317 (pred[i & 1] += buf[i])]) >> 12) derror();
2321 void CLASS kodak_ycbcr_load_raw()
2323 short buf[384], *bp;
2324 int row, col, len, c, i, j, k, y[2][2], cb, cr, rgb[3];
2327 for (row=0; row < height; row+=2)
2328 for (col=0; col < width; col+=128) {
2329 len = MIN (128, width-col);
2330 kodak_65000_decode (buf, len*3);
2331 y[0][1] = y[1][1] = cb = cr = 0;
2332 for (bp=buf, i=0; i < len; i+=2, bp+=2) {
2335 rgb[1] = -((cb + cr + 2) >> 2);
2336 rgb[2] = rgb[1] + cb;
2337 rgb[0] = rgb[1] + cr;
2338 for (j=0; j < 2; j++)
2339 for (k=0; k < 2; k++) {
2340 if ((y[j][k] = y[j][k^1] + *bp++) >> 10) derror();
2341 ip = image[(row+j)*width + col+i+k];
2342 FORC3 ip[c] = curve[LIM(y[j][k]+rgb[c], 0, 0xfff)];
2348 void CLASS kodak_rgb_load_raw()
2350 short buf[768], *bp;
2351 int row, col, len, c, i, rgb[3];
2352 ushort *ip=image[0];
2354 if (raw_image) free (raw_image);
2356 for (row=0; row < height; row++)
2357 for (col=0; col < width; col+=256) {
2358 len = MIN (256, width-col);
2359 kodak_65000_decode (buf, len*3);
2360 memset (rgb, 0, sizeof rgb);
2361 for (bp=buf, i=0; i < len; i++, ip+=4)
2362 FORC3 if ((ip[c] = rgb[c] += *bp++) >> 12) derror();
2366 void CLASS kodak_thumb_load_raw()
2369 colors = thumb_misc >> 5;
2370 for (row=0; row < height; row++)
2371 for (col=0; col < width; col++)
2372 read_shorts (image[row*width+col], colors);
2373 maximum = (1 << (thumb_misc & 31)) - 1;
2376 void CLASS sony_decrypt (unsigned *data, int len, int start, int key)
2378 static unsigned pad[128], p;
2381 for (p=0; p < 4; p++)
2382 pad[p] = key = key * 48828125 + 1;
2383 pad[3] = pad[3] << 1 | (pad[0]^pad[2]) >> 31;
2384 for (p=4; p < 127; p++)
2385 pad[p] = (pad[p-4]^pad[p-2]) << 1 | (pad[p-3]^pad[p-1]) >> 31;
2386 for (p=0; p < 127; p++)
2387 pad[p] = htonl(pad[p]);
2390 *data++ ^= pad[p++ & 127] = pad[(p+1) & 127] ^ pad[(p+65) & 127];
2393 void CLASS sony_load_raw()
2397 unsigned i, key, row, col;
2399 fseek (ifp, 200896, SEEK_SET);
2400 fseek (ifp, (unsigned) fgetc(ifp)*4 - 1, SEEK_CUR);
2403 fseek (ifp, 164600, SEEK_SET);
2404 fread (head, 1, 40, ifp);
2405 sony_decrypt ((unsigned int *) head, 10, 1, key);
2406 for (i=26; i-- > 22; )
2407 key = key << 8 | head[i];
2408 fseek (ifp, data_offset, SEEK_SET);
2409 for (row=0; row < raw_height; row++) {
2410 pixel = raw_image + row*raw_width;
2411 if (fread (pixel, 2, raw_width, ifp) < raw_width) derror();
2412 sony_decrypt ((unsigned int *) pixel, raw_width/2, !row, key);
2413 for (col=0; col < raw_width; col++)
2414 if ((pixel[col] = ntohs(pixel[col])) >> 14) derror();
2419 void CLASS sony_arw_load_raw()
2422 static const ushort tab[18] =
2423 { 0xf11,0xf10,0xe0f,0xd0e,0xc0d,0xb0c,0xa0b,0x90a,0x809,
2424 0x708,0x607,0x506,0x405,0x304,0x303,0x300,0x202,0x201 };
2425 int i, c, n, col, row, len, diff, sum=0;
2427 for (n=i=0; i < 18; i++)
2428 FORC(32768 >> (tab[i] >> 8)) huff[n++] = tab[i];
2430 for (col = raw_width; col--; )
2431 for (row=0; row < raw_height+1; row+=2) {
2432 if (row == raw_height) row = 1;
2433 len = getbithuff(15,huff);
2434 diff = getbits(len);
2435 if ((diff & (1 << (len-1))) == 0)
2436 diff -= (1 << len) - 1;
2437 if ((sum += diff) >> 12) derror();
2438 if (row < height) RAW(row,col) = sum;
2442 void CLASS sony_arw2_load_raw()
2446 int row, col, val, max, min, imax, imin, sh, bit, i;
2448 data = (uchar *) malloc (raw_width);
2449 merror (data, "sony_arw2_load_raw()");
2450 for (row=0; row < height; row++) {
2451 fread (data, 1, raw_width, ifp);
2452 for (dp=data, col=0; col < raw_width-30; dp+=16) {
2453 max = 0x7ff & (val = sget4(dp));
2454 min = 0x7ff & val >> 11;
2455 imax = 0x0f & val >> 22;
2456 imin = 0x0f & val >> 26;
2457 for (sh=0; sh < 4 && 0x80 << sh <= max-min; sh++);
2458 for (bit=30, i=0; i < 16; i++)
2459 if (i == imax) pix[i] = max;
2460 else if (i == imin) pix[i] = min;
2462 pix[i] = ((sget2(dp+(bit >> 3)) >> (bit & 7) & 0x7f) << sh) + min;
2463 if (pix[i] > 0x7ff) pix[i] = 0x7ff;
2466 for (i=0; i < 16; i++, col+=2)
2467 RAW(row,col) = curve[pix[i] << 1] >> 2;
2468 col -= col & 1 ? 1:31;
2474 #define HOLE(row) ((holes >> (((row) - raw_height) & 7)) & 1)
2476 /* Kudos to Rich Taylor for figuring out SMaL's compression algorithm. */
2477 void CLASS smal_decode_segment (unsigned seg[2][2], int holes)
2479 uchar hist[3][13] = {
2480 { 7, 7, 0, 0, 63, 55, 47, 39, 31, 23, 15, 7, 0 },
2481 { 7, 7, 0, 0, 63, 55, 47, 39, 31, 23, 15, 7, 0 },
2482 { 3, 3, 0, 0, 63, 47, 31, 15, 0 } };
2483 int low, high=0xff, carry=0, nbits=8;
2484 int pix, s, count, bin, next, i, sym[3];
2485 uchar diff, pred[]={0,0};
2486 ushort data=0, range=0;
2488 fseek (ifp, seg[0][1]+1, SEEK_SET);
2490 for (pix=seg[0][0]; pix < seg[1][0]; pix++) {
2491 for (s=0; s < 3; s++) {
2492 data = data << nbits | getbits(nbits);
2494 carry = (nbits += carry+1) < 1 ? nbits-1 : 0;
2495 while (--nbits >= 0)
2496 if ((data >> nbits & 0xff) == 0xff) break;
2498 data = ((data & ((1 << (nbits-1)) - 1)) << 1) |
2499 ((data + (((data & (1 << (nbits-1)))) << 1)) & (-1 << nbits));
2504 count = ((((data-range+1) & 0xffff) << 2) - 1) / (high >> 4);
2505 for (bin=0; hist[s][bin+5] > count; bin++);
2506 low = hist[s][bin+5] * (high >> 4) >> 2;
2507 if (bin) high = hist[s][bin+4] * (high >> 4) >> 2;
2509 for (nbits=0; high << nbits < 128; nbits++);
2510 range = (range+low) << nbits;
2513 if (++hist[s][2] > hist[s][3]) {
2514 next = (next+1) & hist[s][0];
2515 hist[s][3] = (hist[s][next+4] - hist[s][next+5]) >> 2;
2518 if (hist[s][hist[s][1]+4] - hist[s][hist[s][1]+5] > 1) {
2519 if (bin < hist[s][1])
2520 for (i=bin; i < hist[s][1]; i++) hist[s][i+5]--;
2521 else if (next <= bin)
2522 for (i=hist[s][1]; i < bin; i++) hist[s][i+5]++;
2527 diff = sym[2] << 5 | sym[1] << 2 | (sym[0] & 3);
2529 diff = diff ? -diff : 0x80;
2530 if (ftell(ifp) + 12 >= seg[1][1])
2532 raw_image[pix] = pred[pix & 1] += diff;
2533 if (!(pix & 1) && HOLE(pix / raw_width)) pix += 2;
2538 void CLASS smal_v6_load_raw()
2542 fseek (ifp, 16, SEEK_SET);
2545 seg[1][0] = raw_width * raw_height;
2546 seg[1][1] = INT_MAX;
2547 smal_decode_segment (seg, 0);
2550 int CLASS median4 (int *p)
2552 int min, max, sum, i;
2554 min = max = sum = p[0];
2555 for (i=1; i < 4; i++) {
2557 if (min > p[i]) min = p[i];
2558 if (max < p[i]) max = p[i];
2560 return (sum - min - max) >> 1;
2563 void CLASS fill_holes (int holes)
2565 int row, col, val[4];
2567 for (row=2; row < height-2; row++) {
2568 if (!HOLE(row)) continue;
2569 for (col=1; col < width-1; col+=4) {
2570 val[0] = RAW(row-1,col-1);
2571 val[1] = RAW(row-1,col+1);
2572 val[2] = RAW(row+1,col-1);
2573 val[3] = RAW(row+1,col+1);
2574 RAW(row,col) = median4(val);
2576 for (col=2; col < width-2; col+=4)
2577 if (HOLE(row-2) || HOLE(row+2))
2578 RAW(row,col) = (RAW(row,col-2) + RAW(row,col+2)) >> 1;
2580 val[0] = RAW(row,col-2);
2581 val[1] = RAW(row,col+2);
2582 val[2] = RAW(row-2,col);
2583 val[3] = RAW(row+2,col);
2584 RAW(row,col) = median4(val);
2589 void CLASS smal_v9_load_raw()
2591 unsigned seg[256][2], offset, nseg, holes, i;
2593 fseek (ifp, 67, SEEK_SET);
2596 fseek (ifp, offset, SEEK_SET);
2597 for (i=0; i < nseg*2; i++)
2598 seg[0][i] = get4() + data_offset*(i & 1);
2599 fseek (ifp, 78, SEEK_SET);
2601 fseek (ifp, 88, SEEK_SET);
2602 seg[nseg][0] = raw_height * raw_width;
2603 seg[nseg][1] = get4() + data_offset;
2604 for (i=0; i < nseg; i++)
2605 smal_decode_segment (seg+i, holes);
2606 if (holes) fill_holes (holes);
2609 void CLASS redcine_load_raw()
2620 in = jas_stream_fopen (ifname, "rb");
2621 jas_stream_seek (in, data_offset+20, SEEK_SET);
2622 jimg = jas_image_decode (in, -1, 0);
2623 if (!jimg) longjmp (failure, 3);
2624 jmat = jas_matrix_create (height/2, width/2);
2625 merror (jmat, "redcine_load_raw()");
2626 img = (ushort *) calloc ((height+2)*(width+2), 2);
2627 merror (img, "redcine_load_raw()");
2629 jas_image_readcmpt (jimg, c, 0, 0, width/2, height/2, jmat);
2630 data = jas_matrix_getref (jmat, 0, 0);
2631 for (row = c >> 1; row < height; row+=2)
2632 for (col = c & 1; col < width; col+=2)
2633 img[(row+1)*(width+2)+col+1] = data[(row/2)*(width/2)+col/2];
2635 for (col=1; col <= width; col++) {
2636 img[col] = img[2*(width+2)+col];
2637 img[(height+1)*(width+2)+col] = img[(height-1)*(width+2)+col];
2639 for (row=0; row < height+2; row++) {
2640 img[row*(width+2)] = img[row*(width+2)+2];
2641 img[(row+1)*(width+2)-1] = img[(row+1)*(width+2)-3];
2643 for (row=1; row <= height; row++) {
2644 pix = img + row*(width+2) + (col = 1 + (FC(row,1) & 1));
2645 for ( ; col <= width; col+=2, pix+=2) {
2646 c = (((pix[0] - 0x800) << 3) +
2647 pix[-(width+2)] + pix[width+2] + pix[-1] + pix[1]) >> 2;
2648 pix[0] = LIM(c,0,4095);
2651 for (row=0; row < height; row++)
2652 for (col=0; col < width; col++)
2653 RAW(row,col) = curve[img[(row+1)*(width+2)+col+1]];
2655 jas_matrix_destroy (jmat);
2656 jas_image_destroy (jimg);
2657 jas_stream_close (in);
2661 /* RESTRICTED code starts here */
2663 void CLASS foveon_decoder (unsigned size, unsigned code)
2665 static unsigned huff[1024];
2670 for (i=0; i < size; i++)
2672 memset (first_decode, 0, sizeof first_decode);
2673 free_decode = first_decode;
2675 cur = free_decode++;
2676 if (free_decode > first_decode+2048) {
2677 fprintf (stderr,_("%s: decoder table overflow\n"), ifname);
2678 longjmp (failure, 2);
2681 for (i=0; i < size; i++)
2682 if (huff[i] == code) {
2686 if ((len = code >> 27) > 26) return;
2687 code = (len+1) << 27 | (code & 0x3ffffff) << 1;
2689 cur->branch[0] = free_decode;
2690 foveon_decoder (size, code);
2691 cur->branch[1] = free_decode;
2692 foveon_decoder (size, code+1);
2695 void CLASS foveon_thumb()
2697 unsigned bwide, row, col, bitbuf=0, bit=1, c, i;
2699 struct decode *dindex;
2703 fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
2705 if (bwide < thumb_width*3) return;
2706 buf = (char *) malloc (bwide);
2707 merror (buf, "foveon_thumb()");
2708 for (row=0; row < thumb_height; row++) {
2709 fread (buf, 1, bwide, ifp);
2710 fwrite (buf, 3, thumb_width, ofp);
2715 foveon_decoder (256, 0);
2717 for (row=0; row < thumb_height; row++) {
2718 memset (pred, 0, sizeof pred);
2720 for (bit=col=0; col < thumb_width; col++)
2722 for (dindex=first_decode; dindex->branch[0]; ) {
2723 if ((bit = (bit-1) & 31) == 31)
2724 for (i=0; i < 4; i++)
2725 bitbuf = (bitbuf << 8) + fgetc(ifp);
2726 dindex = dindex->branch[bitbuf >> bit & 1];
2728 pred[c] += dindex->leaf;
2729 fputc (pred[c], ofp);
2734 void CLASS foveon_sd_load_raw()
2736 struct decode *dindex;
2739 int pred[3], row, col, bit=-1, c, i;
2741 read_shorts ((ushort *) diff, 1024);
2742 if (!load_flags) foveon_decoder (1024, 0);
2744 for (row=0; row < height; row++) {
2745 memset (pred, 0, sizeof pred);
2746 if (!bit && !load_flags && atoi(model+2) < 14) get4();
2747 for (col=bit=0; col < width; col++) {
2750 FORC3 pred[2-c] += diff[bitbuf >> c*10 & 0x3ff];
2753 for (dindex=first_decode; dindex->branch[0]; ) {
2754 if ((bit = (bit-1) & 31) == 31)
2755 for (i=0; i < 4; i++)
2756 bitbuf = (bitbuf << 8) + fgetc(ifp);
2757 dindex = dindex->branch[bitbuf >> bit & 1];
2759 pred[c] += diff[dindex->leaf];
2760 if (pred[c] >> 16 && ~pred[c] >> 16) derror();
2762 FORC3 image[row*width+col][c] = pred[c];
2767 void CLASS foveon_huff (ushort *huff)
2769 int i, j, clen, code;
2772 for (i=0; i < 13; i++) {
2775 for (j=0; j < 256 >> clen; )
2776 huff[code+ ++j] = clen << 8 | i;
2781 void CLASS foveon_dp_load_raw()
2783 unsigned c, roff[4], row, col, diff;
2784 ushort huff[258], vpred[2][2], hpred[2];
2786 fseek (ifp, 8, SEEK_CUR);
2789 FORC3 roff[c+1] = -(-(roff[c] + get4()) & -16);
2791 fseek (ifp, data_offset+roff[c], SEEK_SET);
2793 vpred[0][0] = vpred[0][1] = vpred[1][0] = vpred[1][1] = 512;
2794 for (row=0; row < height; row++) {
2795 for (col=0; col < width; col++) {
2796 diff = ljpeg_diff(huff);
2797 if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
2798 else hpred[col & 1] += diff;
2799 image[row*width+col][c] = hpred[col & 1];
2805 void CLASS foveon_load_camf()
2807 unsigned type, wide, high, i, j, row, col, diff;
2808 ushort huff[258], vpred[2][2] = {{512,512},{512,512}}, hpred[2];
2810 fseek (ifp, meta_offset, SEEK_SET);
2811 type = get4(); get4(); get4();
2815 fread (meta_data, 1, meta_length, ifp);
2816 for (i=0; i < meta_length; i++) {
2817 high = (high * 1597 + 51749) % 244944;
2818 wide = high * (INT64) 301593171 >> 24;
2819 meta_data[i] ^= ((((high << 8) - wide) >> 1) + wide) >> 17;
2821 } else if (type == 4) {
2823 meta_data = (char *) malloc (meta_length = wide*high*3/2);
2824 merror (meta_data, "foveon_load_camf()");
2828 for (j=row=0; row < high; row++) {
2829 for (col=0; col < wide; col++) {
2830 diff = ljpeg_diff(huff);
2831 if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
2832 else hpred[col & 1] += diff;
2834 meta_data[j++] = hpred[0] >> 4;
2835 meta_data[j++] = hpred[0] << 4 | hpred[1] >> 8;
2836 meta_data[j++] = hpred[1];
2841 fprintf (stderr,_("%s has unknown CAMF type %d.\n"), ifname, type);
2844 const char * CLASS foveon_camf_param (const char *block, const char *param)
2847 char *pos, *cp, *dp;
2849 for (idx=0; idx < meta_length; idx += sget4(pos+8)) {
2850 pos = meta_data + idx;
2851 if (strncmp (pos, "CMb", 3)) break;
2852 if (pos[3] != 'P') continue;
2853 if (strcmp (block, pos+sget4(pos+12))) continue;
2854 cp = pos + sget4(pos+16);
2856 dp = pos + sget4(cp+4);
2859 if (!strcmp (param, dp+sget4(cp)))
2860 return dp+sget4(cp+4);
2866 void * CLASS foveon_camf_matrix (unsigned dim[3], const char *name)
2868 unsigned i, idx, type, ndim, size, *mat;
2869 char *pos, *cp, *dp;
2872 for (idx=0; idx < meta_length; idx += sget4(pos+8)) {
2873 pos = meta_data + idx;
2874 if (strncmp (pos, "CMb", 3)) break;
2875 if (pos[3] != 'M') continue;
2876 if (strcmp (name, pos+sget4(pos+12))) continue;
2877 dim[0] = dim[1] = dim[2] = 1;
2878 cp = pos + sget4(pos+16);
2880 if ((ndim = sget4(cp+4)) > 3) break;
2881 dp = pos + sget4(cp+8);
2882 for (i=ndim; i--; ) {
2886 if ((dsize = (double) dim[0]*dim[1]*dim[2]) > meta_length/4) break;
2887 mat = (unsigned *) malloc ((size = dsize) * 4);
2888 merror (mat, "foveon_camf_matrix()");
2889 for (i=0; i < size; i++)
2890 if (type && type != 6)
2891 mat[i] = sget4(dp + i*4);
2893 mat[i] = sget4(dp + i*2) & 0xffff;
2896 fprintf (stderr,_("%s: \"%s\" matrix not found!\n"), ifname, name);
2900 int CLASS foveon_fixed (void *ptr, int size, const char *name)
2905 if (!name) return 0;
2906 dp = foveon_camf_matrix (dim, name);
2908 memcpy (ptr, dp, size*4);
2913 float CLASS foveon_avg (short *pix, int range[2], float cfilt)
2916 float val, min=FLT_MAX, max=-FLT_MAX, sum=0;
2918 for (i=range[0]; i <= range[1]; i++) {
2919 sum += val = pix[i*4] + (pix[i*4]-pix[(i-1)*4]) * cfilt;
2920 if (min > val) min = val;
2921 if (max < val) max = val;
2923 if (range[1] - range[0] == 1) return sum/2;
2924 return (sum - min - max) / (range[1] - range[0] - 1);
2927 short * CLASS foveon_make_curve (double max, double mul, double filt)
2933 if (!filt) filt = 0.8;
2934 size = 4*M_PI*max / filt;
2935 if (size == UINT_MAX) size--;
2936 curve = (short *) calloc (size+1, sizeof *curve);
2937 merror (curve, "foveon_make_curve()");
2939 for (i=0; i < size; i++) {
2941 curve[i+1] = (cos(x)+1)/2 * tanh(i*filt/mul) * mul + 0.5;
2946 void CLASS foveon_make_curves
2947 (short **curvep, float dq[3], float div[3], float filt)
2949 double mul[3], max=0;
2952 FORC3 mul[c] = dq[c]/div[c];
2953 FORC3 if (max < mul[c]) max = mul[c];
2954 FORC3 curvep[c] = foveon_make_curve (max, mul[c], filt);
2957 int CLASS foveon_apply_curve (short *curve, int i)
2959 if (abs(i) >= curve[0]) return 0;
2960 return i < 0 ? -curve[1-i] : curve[1+i];
2963 #define image ((short (*)[4]) image)
2965 void CLASS foveon_interpolate()
2967 static const short hood[] = { -1,-1, -1,0, -1,1, 0,-1, 0,1, 1,-1, 1,0, 1,1 };
2968 short *pix, prev[3], *curve[8], (*shrink)[3];
2969 float cfilt=0, ddft[3][3][2], ppm[3][3][3];
2970 float cam_xyz[3][3], correct[3][3], last[3][3], trans[3][3];
2971 float chroma_dq[3], color_dq[3], diag[3][3], div[3];
2972 float (*black)[3], (*sgain)[3], (*sgrow)[3];
2973 float fsum[3], val, frow, num;
2974 int row, col, c, i, j, diff, sgx, irow, sum, min, max, limit;
2975 int dscr[2][2], dstb[4], (*smrow[7])[3], total[4], ipix[3];
2976 int work[3][3], smlast, smred, smred_p=0, dev[3];
2977 int satlev[3], keep[4], active[4];
2978 unsigned dim[3], *badpix;
2979 double dsum=0, trsum[3];
2984 fprintf (stderr,_("Foveon interpolation...\n"));
2987 foveon_fixed (dscr, 4, "DarkShieldColRange");
2988 foveon_fixed (ppm[0][0], 27, "PostPolyMatrix");
2989 foveon_fixed (satlev, 3, "SaturationLevel");
2990 foveon_fixed (keep, 4, "KeepImageArea");
2991 foveon_fixed (active, 4, "ActiveImageArea");
2992 foveon_fixed (chroma_dq, 3, "ChromaDQ");
2993 foveon_fixed (color_dq, 3,
2994 foveon_camf_param ("IncludeBlocks", "ColorDQ") ?
2995 "ColorDQ" : "ColorDQCamRGB");
2996 if (foveon_camf_param ("IncludeBlocks", "ColumnFilter"))
2997 foveon_fixed (&cfilt, 1, "ColumnFilter");
2999 memset (ddft, 0, sizeof ddft);
3000 if (!foveon_camf_param ("IncludeBlocks", "DarkDrift")
3001 || !foveon_fixed (ddft[1][0], 12, "DarkDrift"))
3002 for (i=0; i < 2; i++) {
3003 foveon_fixed (dstb, 4, i ? "DarkShieldBottom":"DarkShieldTop");
3004 for (row = dstb[1]; row <= dstb[3]; row++)
3005 for (col = dstb[0]; col <= dstb[2]; col++)
3006 FORC3 ddft[i+1][c][1] += (short) image[row*width+col][c];
3007 FORC3 ddft[i+1][c][1] /= (dstb[3]-dstb[1]+1) * (dstb[2]-dstb[0]+1);
3010 if (!(cp = foveon_camf_param ("WhiteBalanceIlluminants", model2)))
3011 { fprintf (stderr,_("%s: Invalid white balance \"%s\"\n"), ifname, model2);
3013 foveon_fixed (cam_xyz, 9, cp);
3014 foveon_fixed (correct, 9,
3015 foveon_camf_param ("WhiteBalanceCorrections", model2));
3016 memset (last, 0, sizeof last);
3017 for (i=0; i < 3; i++)
3018 for (j=0; j < 3; j++)
3019 FORC3 last[i][j] += correct[i][c] * cam_xyz[c][j];
3021 #define LAST(x,y) last[(i+x)%3][(c+y)%3]
3022 for (i=0; i < 3; i++)
3023 FORC3 diag[c][i] = LAST(1,1)*LAST(2,2) - LAST(1,2)*LAST(2,1);
3025 FORC3 div[c] = diag[c][0]*0.3127 + diag[c][1]*0.329 + diag[c][2]*0.3583;
3026 sprintf (str, "%sRGBNeutral", model2);
3027 if (foveon_camf_param ("IncludeBlocks", str))
3028 foveon_fixed (div, 3, str);
3030 FORC3 if (num < div[c]) num = div[c];
3031 FORC3 div[c] /= num;
3033 memset (trans, 0, sizeof trans);
3034 for (i=0; i < 3; i++)
3035 for (j=0; j < 3; j++)
3036 FORC3 trans[i][j] += rgb_cam[i][c] * last[c][j] * div[j];
3037 FORC3 trsum[c] = trans[c][0] + trans[c][1] + trans[c][2];
3038 dsum = (6*trsum[0] + 11*trsum[1] + 3*trsum[2]) / 20;
3039 for (i=0; i < 3; i++)
3040 FORC3 last[i][c] = trans[i][c] * dsum / trsum[i];
3041 memset (trans, 0, sizeof trans);
3042 for (i=0; i < 3; i++)
3043 for (j=0; j < 3; j++)
3044 FORC3 trans[i][j] += (i==c ? 32 : -1) * last[c][j] / 30;
3046 foveon_make_curves (curve, color_dq, div, cfilt);
3047 FORC3 chroma_dq[c] /= 3;
3048 foveon_make_curves (curve+3, chroma_dq, div, cfilt);
3049 FORC3 dsum += chroma_dq[c] / div[c];
3050 curve[6] = foveon_make_curve (dsum, dsum, cfilt);
3051 curve[7] = foveon_make_curve (dsum*2, dsum*2, cfilt);
3053 sgain = (float (*)[3]) foveon_camf_matrix (dim, "SpatialGain");
3055 sgrow = (float (*)[3]) calloc (dim[1], sizeof *sgrow);
3056 sgx = (width + dim[1]-2) / (dim[1]-1);
3058 black = (float (*)[3]) calloc (height, sizeof *black);
3059 for (row=0; row < height; row++) {
3060 float *dp0 = &ddft[0][0][0];
3061 float *dp1 = &ddft[1][0][0];
3062 float *dp2 = &ddft[2][0][0];
3063 for( i=6; --i>=0; ++dp0,++dp1,++dp2 )
3064 *dp0 = *dp1 + row / (height-1.0) * (*dp2 - *dp1);
3065 pix = image[row*width];
3066 FORC3 black[row][c] =
3067 ( foveon_avg (image[row*width]+c, dscr[0], cfilt) +
3068 foveon_avg (image[row*width]+c, dscr[1], cfilt) * 3
3069 - ddft[0][c][0] ) / 4 - ddft[0][c][1];
3071 memcpy (black, black+8, sizeof *black*8);
3072 memcpy (black+height-11, black+height-22, 11*sizeof *black);
3073 memcpy (last, black, sizeof last);
3075 for (row=1; row < height-1; row++) {
3076 FORC3 if (last[1][c] > last[0][c]) {
3077 if (last[1][c] > last[2][c])
3078 black[row][c] = (last[0][c] > last[2][c]) ? last[0][c]:last[2][c];
3080 if (last[1][c] < last[2][c])
3081 black[row][c] = (last[0][c] < last[2][c]) ? last[0][c]:last[2][c];
3082 memmove (last, last+1, 2*sizeof last[0]);
3083 memcpy (last[2], black[row+1], sizeof last[2]);
3085 FORC3 black[row][c] = (last[0][c] + last[1][c])/2;
3086 FORC3 black[0][c] = (black[1][c] + black[3][c])/2;
3088 val = 1 - exp(-1/24.0);
3089 memcpy (fsum, black, sizeof fsum);
3090 for (row=1; row < height; row++)
3091 FORC3 fsum[c] += black[row][c] =
3092 (black[row][c] - black[row-1][c])*val + black[row-1][c];
3093 memcpy (last[0], black[height-1], sizeof last[0]);
3094 FORC3 fsum[c] /= height;
3095 for (row = height; row--; )
3096 FORC3 last[0][c] = black[row][c] =
3097 (black[row][c] - fsum[c] - last[0][c])*val + last[0][c];
3099 memset (total, 0, sizeof total);
3100 for (row=2; row < height; row+=4)
3101 for (col=2; col < width; col+=4) {
3102 FORC3 total[c] += (short) image[row*width+col][c];
3105 for (row=0; row < height; row++)
3106 FORC3 black[row][c] += fsum[c]/2 + total[c]/(total[3]*100.0);
3108 for (row=0; row < height; row++) {
3109 float *dp0 = &ddft[0][0][0];
3110 float *dp1 = &ddft[1][0][0];
3111 float *dp2 = &ddft[2][0][0];
3112 for( i=6; --i>=0; ++dp0,++dp1,++dp2 )
3113 *dp0 = *dp1 + row / (height-1.0) * (*dp2 - *dp1);
3114 pix = image[row*width];
3115 memcpy (prev, pix, sizeof prev);
3116 frow = row / (height-1.0) * (dim[2]-1);
3117 if ((irow = frow) == dim[2]-1) irow--;
3119 for (i=0; i < dim[1]; i++)
3120 FORC3 sgrow[i][c] = sgain[ irow *dim[1]+i][c] * (1-frow) +
3121 sgain[(irow+1)*dim[1]+i][c] * frow;
3122 for (col=0; col < width; col++) {
3124 diff = pix[c] - prev[c];
3126 ipix[c] = pix[c] + floor ((diff + (diff*diff >> 14)) * cfilt
3127 - ddft[0][c][1] - ddft[0][c][0] * ((float) col/width - 0.5)
3131 work[0][c] = ipix[c] * ipix[c] >> 14;
3132 work[2][c] = ipix[c] * work[0][c] >> 14;
3133 work[1][2-c] = ipix[(c+1) % 3] * ipix[(c+2) % 3] >> 14;
3136 for (val=i=0; i < 3; i++)
3137 for ( j=0; j < 3; j++)
3138 val += ppm[c][i][j] * work[i][j];
3139 ipix[c] = floor ((ipix[c] + floor(val)) *
3140 ( sgrow[col/sgx ][c] * (sgx - col%sgx) +
3141 sgrow[col/sgx+1][c] * (col%sgx) ) / sgx / div[c]);
3142 if (ipix[c] > 32000) ipix[c] = 32000;
3152 if ((badpix = (unsigned int *) foveon_camf_matrix (dim, "BadPixels"))) {
3153 for (i=0; i < dim[0]; i++) {
3154 col = (badpix[i] >> 8 & 0xfff) - keep[0];
3155 row = (badpix[i] >> 20 ) - keep[1];
3156 if ((unsigned)(row-1) > height-3 || (unsigned)(col-1) > width-3)
3158 memset (fsum, 0, sizeof fsum);
3159 for (sum=j=0; j < 8; j++)
3160 if (badpix[i] & (1 << j)) {
3161 FORC3 fsum[c] += (short)
3162 image[(row+hood[j*2])*width+col+hood[j*2+1]][c];
3165 if (sum) FORC3 image[row*width+col][c] = fsum[c]/sum;
3170 /* Array for 5x5 Gaussian averaging of red values */
3171 smrow[6] = (int (*)[3]) calloc (width*5, sizeof **smrow);
3172 merror (smrow[6], "foveon_interpolate()");
3173 for (i=0; i < 5; i++)
3174 smrow[i] = smrow[6] + i*width;
3176 /* Sharpen the reds against these Gaussian averages */
3177 for (smlast=-1, row=2; row < height-2; row++) {
3178 while (smlast < row+2) {
3179 for (i=0; i < 6; i++)
3180 smrow[(i+5) % 6] = smrow[i];
3181 pix = image[++smlast*width+2];
3182 for (col=2; col < width-2; col++) {
3184 (pix[0]*6 + (pix[-4]+pix[4])*4 + pix[-8]+pix[8] + 8) >> 4;
3188 pix = image[row*width+2];
3189 for (col=2; col < width-2; col++) {
3190 smred = ( 6 * smrow[2][col][0]
3191 + 4 * (smrow[1][col][0] + smrow[3][col][0])
3192 + smrow[0][col][0] + smrow[4][col][0] + 8 ) >> 4;
3195 i = pix[0] + ((pix[0] - ((smred*7 + smred_p) >> 3)) >> 3);
3196 if (i > 32000) i = 32000;
3203 /* Adjust the brighter pixels for better linearity */
3206 i = satlev[c] / div[c];
3207 if (min > i) min = i;
3209 limit = min * 9 >> 4;
3210 for (pix=image[0]; pix < image[height*width]; pix+=4) {
3211 if (pix[0] <= limit || pix[1] <= limit || pix[2] <= limit)
3214 for (c=1; c < 3; c++) {
3215 if (min > pix[c]) min = pix[c];
3216 if (max < pix[c]) max = pix[c];
3218 if (min >= limit*2) {
3219 pix[0] = pix[1] = pix[2] = max;
3221 i = 0x4000 - ((min - limit) << 14) / limit;
3222 i = 0x4000 - (i*i >> 14);
3224 FORC3 pix[c] += (max - pix[c]) * i >> 14;
3228 Because photons that miss one detector often hit another,
3229 the sum R+G+B is much less noisy than the individual colors.
3230 So smooth the hues without smoothing the total.
3232 for (smlast=-1, row=2; row < height-2; row++) {
3233 while (smlast < row+2) {
3234 for (i=0; i < 6; i++)
3235 smrow[(i+5) % 6] = smrow[i];
3236 pix = image[++smlast*width+2];
3237 for (col=2; col < width-2; col++) {
3238 FORC3 smrow[4][col][c] = (pix[c-4]+2*pix[c]+pix[c+4]+2) >> 2;
3242 pix = image[row*width+2];
3243 for (col=2; col < width-2; col++) {
3244 FORC3 dev[c] = -foveon_apply_curve (curve[7], pix[c] -
3245 ((smrow[1][col][c] + 2*smrow[2][col][c] + smrow[3][col][c]) >> 2));
3246 sum = (dev[0] + dev[1] + dev[2]) >> 3;
3247 FORC3 pix[c] += dev[c] - sum;
3251 for (smlast=-1, row=2; row < height-2; row++) {
3252 while (smlast < row+2) {
3253 for (i=0; i < 6; i++)
3254 smrow[(i+5) % 6] = smrow[i];
3255 pix = image[++smlast*width+2];
3256 for (col=2; col < width-2; col++) {
3257 FORC3 smrow[4][col][c] =
3258 (pix[c-8]+pix[c-4]+pix[c]+pix[c+4]+pix[c+8]+2) >> 2;
3262 pix = image[row*width+2];
3263 for (col=2; col < width-2; col++) {
3264 for (total[3]=375, sum=60, c=0; c < 3; c++) {
3265 for (total[c]=i=0; i < 5; i++)
3266 total[c] += smrow[i][col][c];
3267 total[3] += total[c];
3270 if (sum < 0) sum = 0;
3271 j = total[3] > 375 ? (sum << 16) / total[3] : sum * 174;
3272 FORC3 pix[c] += foveon_apply_curve (curve[6],
3273 ((j*total[c] + 0x8000) >> 16) - pix[c]);
3278 /* Transform the image to a different colorspace */
3279 for (pix=image[0]; pix < image[height*width]; pix+=4) {
3280 FORC3 pix[c] -= foveon_apply_curve (curve[c], pix[c]);
3281 sum = (pix[0]+pix[1]+pix[1]+pix[2]) >> 2;
3282 FORC3 pix[c] -= foveon_apply_curve (curve[c], pix[c]-sum);
3284 for (dsum=i=0; i < 3; i++)
3285 dsum += trans[c][i] * pix[i];
3286 if (dsum < 0) dsum = 0;
3287 if (dsum > 24000) dsum = 24000;
3288 ipix[c] = dsum + 0.5;
3290 FORC3 pix[c] = ipix[c];
3293 /* Smooth the image bottom-to-top and save at 1/4 scale */
3294 shrink = (short (*)[3]) calloc ((width/4) * (height/4), sizeof *shrink);
3295 merror (shrink, "foveon_interpolate()");
3296 for (row = height/4; row--; )
3297 for (col=0; col < width/4; col++) {
3298 ipix[0] = ipix[1] = ipix[2] = 0;
3299 for (i=0; i < 4; i++)
3300 for (j=0; j < 4; j++)
3301 FORC3 ipix[c] += image[(row*4+i)*width+col*4+j][c];
3303 if (row+2 > height/4)
3304 shrink[row*(width/4)+col][c] = ipix[c] >> 4;
3306 shrink[row*(width/4)+col][c] =
3307 (shrink[(row+1)*(width/4)+col][c]*1840 + ipix[c]*141 + 2048) >> 12;
3309 /* From the 1/4-scale image, smooth right-to-left */
3310 for (row=0; row < (height & ~3); row++) {
3311 ipix[0] = ipix[1] = ipix[2] = 0;
3313 for (col = width & ~3 ; col--; )
3314 FORC3 smrow[0][col][c] = ipix[c] =
3315 (shrink[(row/4)*(width/4)+col/4][c]*1485 + ipix[c]*6707 + 4096) >> 13;
3317 /* Then smooth left-to-right */
3318 ipix[0] = ipix[1] = ipix[2] = 0;
3319 for (col=0; col < (width & ~3); col++)
3320 FORC3 smrow[1][col][c] = ipix[c] =
3321 (smrow[0][col][c]*1485 + ipix[c]*6707 + 4096) >> 13;
3323 /* Smooth top-to-bottom */
3325 memcpy (smrow[2], smrow[1], sizeof **smrow * width);
3327 for (col=0; col < (width & ~3); col++)
3328 FORC3 smrow[2][col][c] =
3329 (smrow[2][col][c]*6707 + smrow[1][col][c]*1485 + 4096) >> 13;
3331 /* Adjust the chroma toward the smooth values */
3332 for (col=0; col < (width & ~3); col++) {
3333 for (i=j=30, c=0; c < 3; c++) {
3334 i += smrow[2][col][c];
3335 j += image[row*width+col][c];
3338 for (sum=c=0; c < 3; c++) {
3339 ipix[c] = foveon_apply_curve (curve[c+3],
3340 ((smrow[2][col][c] * j + 0x8000) >> 16) - image[row*width+col][c]);
3345 i = image[row*width+col][c] + ipix[c] - sum;
3347 image[row*width+col][c] = i;
3353 for (i=0; i < 8; i++)
3356 /* Trim off the black border */
3357 active[1] -= keep[1];
3359 i = active[2] - active[0];
3360 for (row=0; row < active[3]-active[1]; row++)
3361 memcpy (image[row*i], image[(row+active[1])*width+active[0]],
3368 /* RESTRICTED code ends here */
3370 void CLASS crop_masked_pixels()
3373 unsigned r, c, m, mblack[8], zero, val;
3375 if (load_raw == &CLASS phase_one_load_raw ||
3376 load_raw == &CLASS phase_one_load_raw_c)
3377 phase_one_correct();
3379 for (row=0; row < raw_height-top_margin*2; row++) {
3380 for (col=0; col < fuji_width << !fuji_layout; col++) {
3382 r = fuji_width - 1 - col + (row >> 1);
3383 c = col + ((row+1) >> 1);
3385 r = fuji_width - 1 + row - (col >> 1);
3386 c = row + ((col+1) >> 1);
3388 if (r < height && c < width)
3389 BAYER(r,c) = RAW(row+top_margin,col+left_margin);
3393 for (row=0; row < height; row++)
3394 for (col=0; col < width; col++)
3395 BAYER2(row,col) = RAW(row+top_margin,col+left_margin);
3397 if (mask[0][3]) goto mask_set;
3398 if (load_raw == &CLASS canon_load_raw ||
3399 load_raw == &CLASS lossless_jpeg_load_raw) {
3400 mask[0][1] = mask[1][1] = 2;
3404 if (load_raw == &CLASS canon_600_load_raw ||
3405 load_raw == &CLASS sony_load_raw ||
3406 (load_raw == &CLASS eight_bit_load_raw && strncmp(model,"DC2",3)) ||
3407 load_raw == &CLASS kodak_262_load_raw ||
3408 (load_raw == &CLASS packed_load_raw && (load_flags & 32))) {
3410 mask[0][0] = mask[1][0] = top_margin;
3411 mask[0][2] = mask[1][2] = top_margin+height;
3412 mask[0][3] += left_margin;
3413 mask[1][1] += left_margin+width;
3414 mask[1][3] += raw_width;
3416 if (load_raw == &CLASS nokia_load_raw) {
3417 mask[0][2] = top_margin;
3421 memset (mblack, 0, sizeof mblack);
3422 for (zero=m=0; m < 8; m++)
3423 for (row=mask[m][0]; row < mask[m][2]; row++)
3424 for (col=mask[m][1]; col < mask[m][3]; col++) {
3425 c = FC(row-top_margin,col-left_margin);
3426 mblack[c] += val = RAW(row,col);
3430 if (load_raw == &CLASS canon_600_load_raw && width < raw_width) {
3431 black = (mblack[0]+mblack[1]+mblack[2]+mblack[3]) /
3432 (mblack[4]+mblack[5]+mblack[6]+mblack[7]) - 4;
3433 canon_600_correct();
3434 } else if (zero < mblack[4] && mblack[5] && mblack[6] && mblack[7])
3435 FORC4 cblack[c] = mblack[c] / mblack[4+c];
3438 void CLASS remove_zeroes()
3440 unsigned row, col, tot, n, r, c;
3442 for (row=0; row < height; row++)
3443 for (col=0; col < width; col++)
3444 if (BAYER(row,col) == 0) {
3446 for (r = row-2; r <= row+2; r++)
3447 for (c = col-2; c <= col+2; c++)
3448 if (r < height && c < width &&
3449 FC(r,c) == FC(row,col) && BAYER(r,c))
3450 tot += (n++,BAYER(r,c));
3451 if (n) BAYER(row,col) = tot/n;
3456 Seach from the current directory up to the root looking for
3457 a ".badpixels" file, and fix those pixels now.
3459 void CLASS bad_pixels (const char *cfname)
3462 char *fname, *cp, line[128];
3463 int len, time, row, col, r, c, rad, tot, n, fixed=0;
3465 if (!filters) return;
3467 fp = fopen (cfname, "r");
3469 for (len=32 ; ; len *= 2) {
3470 fname = (char *) malloc (len);
3472 if (getcwd (fname, len-16)) break;
3474 if (errno != ERANGE) return;
3476 #if defined(WIN32) || defined(DJGPP)
3477 if (fname[1] == ':')
3478 memmove (fname, fname+2, len-2);
3479 for (cp=fname; *cp; cp++)
3480 if (*cp == '\\') *cp = '/';
3482 cp = fname + strlen(fname);
3483 if (cp[-1] == '/') cp--;
3484 while (*fname == '/') {
3485 strcpy (cp, "/.badpixels");
3486 if ((fp = fopen (fname, "r"))) break;
3487 if (cp == fname) break;
3488 while (*--cp != '/');
3493 while (fgets (line, 128, fp)) {
3494 cp = strchr (line, '#');
3496 if (sscanf (line, "%d %d %d", &col, &row, &time) != 3) continue;
3497 if ((unsigned) col >= width || (unsigned) row >= height) continue;
3498 if (time > timestamp) continue;
3499 for (tot=n=0, rad=1; rad < 3 && n==0; rad++)
3500 for (r = row-rad; r <= row+rad; r++)
3501 for (c = col-rad; c <= col+rad; c++)
3502 if ((unsigned) r < height && (unsigned) c < width &&
3503 (r != row || c != col) && fcol(r,c) == fcol(row,col)) {
3507 BAYER2(row,col) = tot/n;
3510 fprintf (stderr,_("Fixed dead pixels at:"));
3511 fprintf (stderr, " %d,%d", col, row);
3514 if (fixed) fputc ('\n', stderr);
3518 void CLASS subtract (const char *fname)
3521 int dim[3]={0,0,0}, comment=0, number=0, error=0, nd=0, c, row, col;
3524 if (!(fp = fopen (fname, "rb"))) {
3525 perror (fname); return;
3527 if (fgetc(fp) != 'P' || fgetc(fp) != '5') error = 1;
3528 while (!error && nd < 3 && (c = fgetc(fp)) != EOF) {
3529 if (c == '#') comment = 1;
3530 if (c == '\n') comment = 0;
3531 if (comment) continue;
3532 if (isdigit(c)) number = 1;
3534 if (isdigit(c)) dim[nd] = dim[nd]*10 + c -'0';
3535 else if (isspace(c)) {
3540 if (error || nd < 3) {
3541 fprintf (stderr,_("%s is not a valid PGM file!\n"), fname);
3542 fclose (fp); return;
3543 } else if (dim[0] != width || dim[1] != height || dim[2] != 65535) {
3544 fprintf (stderr,_("%s has the wrong dimensions!\n"), fname);
3545 fclose (fp); return;
3547 pixel = (ushort *) calloc (width, sizeof *pixel);
3548 merror (pixel, "subtract()");
3549 for (row=0; row < height; row++) {
3550 fread (pixel, 2, width, fp);
3551 for (col=0; col < width; col++)
3552 BAYER(row,col) = MAX (BAYER(row,col) - ntohs(pixel[col]), 0);
3556 memset (cblack, 0, sizeof cblack);
3560 void CLASS gamma_curve (double pwr, double ts, int mode, int imax)
3563 double g[6], bnd[2]={0,0}, r;
3567 g[2] = g[3] = g[4] = 0;
3569 if (g[1] && (g[1]-1)*(g[0]-1) <= 0) {
3570 for (i=0; i < 48; i++) {
3571 g[2] = (bnd[0] + bnd[1])/2;
3572 if (g[0]) bnd[(pow(g[2]/g[1],-g[0]) - 1)/g[0] - 1/g[2] > -1] = g[2];
3573 else bnd[g[2]/exp(1-1/g[2]) < g[1]] = g[2];
3576 if (g[0]) g[4] = g[2] * (1/g[0] - 1);
3578 if (g[0]) g[5] = 1 / (g[1]*SQR(g[3])/2 - g[4]*(1 - g[3]) +
3579 (1 - pow(g[3],1+g[0]))*(1 + g[4])/(1 + g[0])) - 1;
3580 else g[5] = 1 / (g[1]*SQR(g[3])/2 + 1
3581 - g[2] - g[3] - g[2]*g[3]*(log(g[3]) - 1)) - 1;
3583 memcpy (gamm, g, sizeof gamm);
3586 for (i=0; i < 0x10000; i++) {
3588 if ((r = (double) i / imax) < 1)
3589 curve[i] = 0x10000 * ( mode
3590 ? (r < g[3] ? r*g[1] : (g[0] ? pow( r,g[0])*(1+g[4])-g[4] : log(r)*g[2]+1))
3591 : (r < g[2] ? r/g[1] : (g[0] ? pow((r+g[4])/(1+g[4]),1/g[0]) : exp((r-1)/g[2]))));
3595 void CLASS pseudoinverse (double (*in)[3], double (*out)[3], int size)
3597 double work[3][6], num;
3600 for (i=0; i < 3; i++) {
3601 for (j=0; j < 6; j++)
3602 work[i][j] = j == i+3;
3603 for (j=0; j < 3; j++)
3604 for (k=0; k < size; k++)
3605 work[i][j] += in[k][i] * in[k][j];
3607 for (i=0; i < 3; i++) {
3609 for (j=0; j < 6; j++)
3611 for (k=0; k < 3; k++) {
3614 for (j=0; j < 6; j++)
3615 work[k][j] -= work[i][j] * num;
3618 for (i=0; i < size; i++)
3619 for (j=0; j < 3; j++)
3620 for (out[i][j]=k=0; k < 3; k++)
3621 out[i][j] += work[j][k+3] * in[i][k];
3624 void CLASS cam_xyz_coeff (double cam_xyz[4][3])
3626 double cam_rgb[4][3], inverse[4][3], num;
3629 for (i=0; i < colors; i++) /* Multiply out XYZ colorspace */
3630 for (j=0; j < 3; j++)
3631 for (cam_rgb[i][j] = k=0; k < 3; k++)
3632 cam_rgb[i][j] += cam_xyz[i][k] * xyz_rgb[k][j];
3634 for (i=0; i < colors; i++) { /* Normalize cam_rgb so that */
3635 for (num=j=0; j < 3; j++) /* cam_rgb * (1,1,1) is (1,1,1,1) */
3636 num += cam_rgb[i][j];
3637 for (j=0; j < 3; j++)
3638 cam_rgb[i][j] /= num;
3639 pre_mul[i] = 1 / num;
3641 pseudoinverse (cam_rgb, inverse, colors);
3642 for (raw_color = i=0; i < 3; i++)
3643 for (j=0; j < colors; j++)
3644 rgb_cam[i][j] = inverse[j][i];
3648 void CLASS colorcheck()
3651 // Coordinates of the GretagMacbeth ColorChecker squares
3652 // width, height, 1st_column, 1st_row
3653 int cut[NSQ][4]; // you must set these
3654 // ColorChecker Chart under 6500-kelvin illumination
3655 static const double gmb_xyY[NSQ][3] = {
3656 { 0.400, 0.350, 10.1 }, // Dark Skin
3657 { 0.377, 0.345, 35.8 }, // Light Skin
3658 { 0.247, 0.251, 19.3 }, // Blue Sky
3659 { 0.337, 0.422, 13.3 }, // Foliage
3660 { 0.265, 0.240, 24.3 }, // Blue Flower
3661 { 0.261, 0.343, 43.1 }, // Bluish Green
3662 { 0.506, 0.407, 30.1 }, // Orange
3663 { 0.211, 0.175, 12.0 }, // Purplish Blue
3664 { 0.453, 0.306, 19.8 }, // Moderate Red
3665 { 0.285, 0.202, 6.6 }, // Purple
3666 { 0.380, 0.489, 44.3 }, // Yellow Green
3667 { 0.473, 0.438, 43.1 }, // Orange Yellow
3668 { 0.187, 0.129, 6.1 }, // Blue
3669 { 0.305, 0.478, 23.4 }, // Green
3670 { 0.539, 0.313, 12.0 }, // Red
3671 { 0.448, 0.470, 59.1 }, // Yellow
3672 { 0.364, 0.233, 19.8 }, // Magenta
3673 { 0.196, 0.252, 19.8 }, // Cyan
3674 { 0.310, 0.316, 90.0 }, // White
3675 { 0.310, 0.316, 59.1 }, // Neutral 8
3676 { 0.310, 0.316, 36.2 }, // Neutral 6.5
3677 { 0.310, 0.316, 19.8 }, // Neutral 5
3678 { 0.310, 0.316, 9.0 }, // Neutral 3.5
3679 { 0.310, 0.316, 3.1 } }; // Black
3680 double gmb_cam[NSQ][4], gmb_xyz[NSQ][3];
3681 double inverse[NSQ][3], cam_xyz[4][3], num;
3682 int c, i, j, k, sq, row, col, count[4];
3684 memset (gmb_cam, 0, sizeof gmb_cam);
3685 for (sq=0; sq < NSQ; sq++) {
3687 for (row=cut[sq][3]; row < cut[sq][3]+cut[sq][1]; row++)
3688 for (col=cut[sq][2]; col < cut[sq][2]+cut[sq][0]; col++) {
3690 if (c >= colors) c -= 2;
3691 gmb_cam[sq][c] += BAYER(row,col);
3694 FORCC gmb_cam[sq][c] = gmb_cam[sq][c]/count[c] - black;
3695 gmb_xyz[sq][0] = gmb_xyY[sq][2] * gmb_xyY[sq][0] / gmb_xyY[sq][1];
3696 gmb_xyz[sq][1] = gmb_xyY[sq][2];
3697 gmb_xyz[sq][2] = gmb_xyY[sq][2] *
3698 (1 - gmb_xyY[sq][0] - gmb_xyY[sq][1]) / gmb_xyY[sq][1];
3700 pseudoinverse (gmb_xyz, inverse, NSQ);
3701 for (i=0; i < colors; i++)
3702 for (j=0; j < 3; j++)
3703 for (cam_xyz[i][j] = k=0; k < NSQ; k++)
3704 cam_xyz[i][j] += gmb_cam[k][i] * inverse[k][j];
3705 cam_xyz_coeff (cam_xyz);
3707 printf (" { \"%s %s\", %d,\n\t{", make, model, black);
3708 num = 10000 / (cam_xyz[1][0] + cam_xyz[1][1] + cam_xyz[1][2]);
3709 FORCC for (j=0; j < 3; j++)
3710 printf ("%c%d", (c | j) ? ',':' ', (int) (cam_xyz[c][j] * num + 0.5));
3717 void CLASS hat_transform (float *temp, float *base, int st, int size, int sc)
3720 for (i=0; i < sc; i++)
3721 temp[i] = 2*base[st*i] + base[st*(sc-i)] + base[st*(i+sc)];
3722 for (; i+sc < size; i++)
3723 temp[i] = 2*base[st*i] + base[st*(i-sc)] + base[st*(i+sc)];
3724 for (; i < size; i++)
3725 temp[i] = 2*base[st*i] + base[st*(i-sc)] + base[st*(2*size-2-(i+sc))];
3728 void CLASS wavelet_denoise()
3730 float *fimg=0, *temp, thold, mul[2], avg, diff;
3731 int scale=1, size, lev, hpass, lpass, row, col, nc, c, i, wlast, blk[2];
3733 static const float noise[] =
3734 { 0.8002,0.2735,0.1202,0.0585,0.0291,0.0152,0.0080,0.0044 };
3736 if (verbose) fprintf (stderr,_("Wavelet denoising...\n"));
3738 while (maximum << scale < 0x10000) scale++;
3739 maximum <<= --scale;
3741 FORC4 cblack[c] <<= scale;
3742 if ((size = iheight*iwidth) < 0x15550000)
3743 fimg = (float *) malloc ((size*3 + iheight + iwidth) * sizeof *fimg);
3744 merror (fimg, "wavelet_denoise()");
3745 temp = fimg + size*3;
3746 if ((nc = colors) == 3 && filters) nc++;
3747 FORC(nc) { /* denoise R,G1,B,G3 individually */
3748 for (i=0; i < size; i++)
3749 fimg[i] = 256 * sqrt(image[i][c] << scale);
3750 for (hpass=lev=0; lev < 5; lev++) {
3751 lpass = size*((lev & 1)+1);
3752 for (row=0; row < iheight; row++) {
3753 hat_transform (temp, fimg+hpass+row*iwidth, 1, iwidth, 1 << lev);
3754 for (col=0; col < iwidth; col++)
3755 fimg[lpass + row*iwidth + col] = temp[col] * 0.25;
3757 for (col=0; col < iwidth; col++) {
3758 hat_transform (temp, fimg+lpass+col, iwidth, iheight, 1 << lev);
3759 for (row=0; row < iheight; row++)
3760 fimg[lpass + row*iwidth + col] = temp[row] * 0.25;
3762 thold = threshold * noise[lev];
3763 for (i=0; i < size; i++) {
3764 fimg[hpass+i] -= fimg[lpass+i];
3765 if (fimg[hpass+i] < -thold) fimg[hpass+i] += thold;
3766 else if (fimg[hpass+i] > thold) fimg[hpass+i] -= thold;
3767 else fimg[hpass+i] = 0;
3768 if (hpass) fimg[i] += fimg[hpass+i];
3772 for (i=0; i < size; i++)
3773 image[i][c] = CLIP(SQR(fimg[i]+fimg[lpass+i])/0x10000);
3775 if (filters && colors == 3) { /* pull G1 and G3 closer together */
3776 for (row=0; row < 2; row++) {
3777 mul[row] = 0.125 * pre_mul[FC(row+1,0) | 1] / pre_mul[FC(row,0) | 1];
3778 blk[row] = cblack[FC(row,0) | 1];
3780 for (i=0; i < 4; i++)
3781 window[i] = (ushort *) fimg + width*i;
3782 for (wlast=-1, row=1; row < height-1; row++) {
3783 while (wlast < row+1) {
3784 for (wlast++, i=0; i < 4; i++)
3785 window[(i+3) & 3] = window[i];
3786 for (col = FC(wlast,1) & 1; col < width; col+=2)
3787 window[2][col] = BAYER(wlast,col);
3789 thold = threshold/512;
3790 for (col = (FC(row,0) & 1)+1; col < width-1; col+=2) {
3791 avg = ( window[0][col-1] + window[0][col+1] +
3792 window[2][col-1] + window[2][col+1] - blk[~row & 1]*4 )
3793 * mul[row & 1] + (window[1][col] + blk[row & 1]) * 0.5;
3794 avg = avg < 0 ? 0 : sqrt(avg);
3795 diff = sqrt(BAYER(row,col)) - avg;
3796 if (diff < -thold) diff += thold;
3797 else if (diff > thold) diff -= thold;
3799 BAYER(row,col) = CLIP(SQR(avg+diff) + 0.5);
3806 void CLASS scale_colors()
3808 unsigned bottom, right, size, row, col, ur, uc, i, x, y, c, sum[8];
3810 double dsum[8], dmin, dmax;
3811 float scale_mul[4], fr, fc;
3812 ushort *img=0, *pix;
3815 memcpy (pre_mul, user_mul, sizeof pre_mul);
3816 if (use_auto_wb || (use_camera_wb && cam_mul[0] == -1)) {
3817 memset (dsum, 0, sizeof dsum);
3818 bottom = MIN (greybox[1]+greybox[3], height);
3819 right = MIN (greybox[0]+greybox[2], width);
3820 for (row=greybox[1]; row < bottom; row += 8)
3821 for (col=greybox[0]; col < right; col += 8) {
3822 memset (sum, 0, sizeof sum);
3823 for (y=row; y < row+8 && y < bottom; y++)
3824 for (x=col; x < col+8 && x < right; x++)
3830 val = image[y*width+x][c];
3831 if (val > maximum-25) goto skip_block;
3832 if ((val -= cblack[c]) < 0) val = 0;
3837 FORC(8) dsum[c] += sum[c];
3840 FORC4 if (dsum[c]) pre_mul[c] = dsum[c+4] / dsum[c];
3842 if (use_camera_wb && cam_mul[0] != -1) {
3843 memset (sum, 0, sizeof sum);
3844 for (row=0; row < 8; row++)
3845 for (col=0; col < 8; col++) {
3847 if ((val = white[row][col] - cblack[c]) > 0)
3851 if (sum[0] && sum[1] && sum[2] && sum[3])
3852 FORC4 pre_mul[c] = (float) sum[c+4] / sum[c];
3853 else if (cam_mul[0] && cam_mul[2])
3854 memcpy (pre_mul, cam_mul, sizeof pre_mul);
3856 fprintf (stderr,_("%s: Cannot use camera white balance.\n"), ifname);
3858 if (pre_mul[3] == 0) pre_mul[3] = colors < 4 ? pre_mul[1] : 1;
3861 if (threshold) wavelet_denoise();
3863 for (dmin=DBL_MAX, dmax=c=0; c < 4; c++) {
3864 if (dmin > pre_mul[c])
3866 if (dmax < pre_mul[c])
3869 if (!highlight) dmax = dmin;
3870 FORC4 scale_mul[c] = (pre_mul[c] /= dmax) * 65535.0 / maximum;
3873 _("Scaling with darkness %d, saturation %d, and\nmultipliers"), dark, sat);
3874 FORC4 fprintf (stderr, " %f", pre_mul[c]);
3875 fputc ('\n', stderr);
3877 size = iheight*iwidth;
3878 for (i=0; i < size*4; i++) {
3881 val -= cblack[i & 3];
3882 val *= scale_mul[i & 3];
3883 image[0][i] = CLIP(val);
3885 if ((aber[0] != 1 || aber[2] != 1) && colors == 3) {
3887 fprintf (stderr,_("Correcting chromatic aberration...\n"));
3888 for (c=0; c < 4; c+=2) {
3889 if (aber[c] == 1) continue;
3890 img = (ushort *) malloc (size * sizeof *img);
3891 merror (img, "scale_colors()");
3892 for (i=0; i < size; i++)
3893 img[i] = image[i][c];
3894 for (row=0; row < iheight; row++) {
3895 ur = fr = (row - iheight*0.5) * aber[c] + iheight*0.5;
3896 if (ur > iheight-2) continue;
3898 for (col=0; col < iwidth; col++) {
3899 uc = fc = (col - iwidth*0.5) * aber[c] + iwidth*0.5;
3900 if (uc > iwidth-2) continue;
3902 pix = img + ur*iwidth + uc;
3903 image[row*iwidth+col][c] =
3904 (pix[ 0]*(1-fc) + pix[ 1]*fc) * (1-fr) +
3905 (pix[iwidth]*(1-fc) + pix[iwidth+1]*fc) * fr;
3913 void CLASS pre_interpolate()
3923 img = (ushort (*)[4]) calloc (height*width, sizeof *img);
3924 merror (img, "pre_interpolate()");
3925 for (row=0; row < height; row++)
3926 for (col=0; col < width; col++) {
3928 img[row*width+col][c] = image[(row >> 1)*iwidth+(col >> 1)][c];
3935 if (filters > 1000 && colors == 3) {
3936 if (four_color_rgb && colors++)
3937 mix_green = !half_size;
3939 for (row = FC(1,0) >> 1; row < height; row+=2)
3940 for (col = FC(row,1) & 1; col < width; col+=2)
3941 image[row*width+col][1] = image[row*width+col][3];
3942 filters &= ~((filters & 0x55555555) << 1);
3945 if (half_size) filters = 0;
3948 void CLASS border_interpolate (int border)
3950 unsigned row, col, y, x, f, c, sum[8];
3952 for (row=0; row < height; row++)
3953 for (col=0; col < width; col++) {
3954 if (col==border && row >= border && row < height-border)
3956 memset (sum, 0, sizeof sum);
3957 for (y=row-1; y != row+2; y++)
3958 for (x=col-1; x != col+2; x++)
3959 if (y < height && x < width) {
3961 sum[f] += image[y*width+x][f];
3965 FORCC if (c != f && sum[c+4])
3966 image[row*width+col][c] = sum[c] / sum[c+4];
3970 void CLASS lin_interpolate()
3972 int code[16][16][32], size=16, *ip, sum[4];
3973 int f, c, i, x, y, row, col, shift, color;
3976 if (verbose) fprintf (stderr,_("Bilinear interpolation...\n"));
3977 if (filters == 2) size = 6;
3978 border_interpolate(1);
3979 for (row=0; row < size; row++)
3980 for (col=0; col < size; col++) {
3981 ip = code[row][col]+1;
3983 memset (sum, 0, sizeof sum);
3984 for (y=-1; y <= 1; y++)
3985 for (x=-1; x <= 1; x++) {
3986 shift = (y==0) + (x==0);
3987 color = fcol(row+y,col+x);
3988 if (color == f) continue;
3989 *ip++ = (width*y + x)*4 + color;
3992 sum[color] += 1 << shift;
3994 code[row][col][0] = (ip - code[row][col]) / 3;
3998 *ip++ = 256 / sum[c];
4001 for (row=1; row < height-1; row++)
4002 for (col=1; col < width-1; col++) {
4003 pix = image[row*width+col];
4004 ip = code[row % size][col % size];
4005 memset (sum, 0, sizeof sum);
4006 for (i=*ip++; i--; ip+=3)
4007 sum[ip[2]] += pix[ip[0]] << ip[1];
4008 for (i=colors; --i; ip+=2)
4009 pix[ip[0]] = sum[ip[0]] * ip[1] >> 8;
4014 This algorithm is officially called:
4016 "Interpolation using a Threshold-based variable number of gradients"
4018 described in http://scien.stanford.edu/pages/labsite/1999/psych221/projects/99/tingchen/algodep/vargra.html
4020 I've extended the basic idea to work with non-Bayer filter arrays.
4021 Gradients are numbered clockwise from NW=0 to W=7.
4023 void CLASS vng_interpolate()
4025 static const signed char *cp, terms[] = {
4026 -2,-2,+0,-1,0,0x01, -2,-2,+0,+0,1,0x01, -2,-1,-1,+0,0,0x01,
4027 -2,-1,+0,-1,0,0x02, -2,-1,+0,+0,0,0x03, -2,-1,+0,+1,1,0x01,
4028 -2,+0,+0,-1,0,0x06, -2,+0,+0,+0,1,0x02, -2,+0,+0,+1,0,0x03,
4029 -2,+1,-1,+0,0,0x04, -2,+1,+0,-1,1,0x04, -2,+1,+0,+0,0,0x06,
4030 -2,+1,+0,+1,0,0x02, -2,+2,+0,+0,1,0x04, -2,+2,+0,+1,0,0x04,
4031 -1,-2,-1,+0,0,0x80, -1,-2,+0,-1,0,0x01, -1,-2,+1,-1,0,0x01,
4032 -1,-2,+1,+0,1,0x01, -1,-1,-1,+1,0,0x88, -1,-1,+1,-2,0,0x40,
4033 -1,-1,+1,-1,0,0x22, -1,-1,+1,+0,0,0x33, -1,-1,+1,+1,1,0x11,
4034 -1,+0,-1,+2,0,0x08, -1,+0,+0,-1,0,0x44, -1,+0,+0,+1,0,0x11,
4035 -1,+0,+1,-2,1,0x40, -1,+0,+1,-1,0,0x66, -1,+0,+1,+0,1,0x22,
4036 -1,+0,+1,+1,0,0x33, -1,+0,+1,+2,1,0x10, -1,+1,+1,-1,1,0x44,
4037 -1,+1,+1,+0,0,0x66, -1,+1,+1,+1,0,0x22, -1,+1,+1,+2,0,0x10,
4038 -1,+2,+0,+1,0,0x04, -1,+2,+1,+0,1,0x04, -1,+2,+1,+1,0,0x04,
4039 +0,-2,+0,+0,1,0x80, +0,-1,+0,+1,1,0x88, +0,-1,+1,-2,0,0x40,
4040 +0,-1,+1,+0,0,0x11, +0,-1,+2,-2,0,0x40, +0,-1,+2,-1,0,0x20,
4041 +0,-1,+2,+0,0,0x30, +0,-1,+2,+1,1,0x10, +0,+0,+0,+2,1,0x08,
4042 +0,+0,+2,-2,1,0x40, +0,+0,+2,-1,0,0x60, +0,+0,+2,+0,1,0x20,
4043 +0,+0,+2,+1,0,0x30, +0,+0,+2,+2,1,0x10, +0,+1,+1,+0,0,0x44,
4044 +0,+1,+1,+2,0,0x10, +0,+1,+2,-1,1,0x40, +0,+1,+2,+0,0,0x60,
4045 +0,+1,+2,+1,0,0x20, +0,+1,+2,+2,0,0x10, +1,-2,+1,+0,0,0x80,
4046 +1,-1,+1,+1,0,0x88, +1,+0,+1,+2,0,0x08, +1,+0,+2,-1,0,0x40,
4048 }, chood[] = { -1,-1, -1,0, -1,+1, 0,+1, +1,+1, +1,0, +1,-1, 0,-1 };
4049 ushort (*brow[5])[4], *pix;
4050 int prow=8, pcol=2, *ip, *code[16][16], gval[8], gmin, gmax, sum[4];
4051 int row, col, x, y, x1, x2, y1, y2, t, weight, grads, color, diag;
4052 int g, diff, thold, num, c;
4055 if (verbose) fprintf (stderr,_("VNG interpolation...\n"));
4057 if (filters == 1) prow = pcol = 16;
4058 if (filters == 2) prow = pcol = 6;
4059 ip = (int *) calloc (prow*pcol, 1280);
4060 merror (ip, "vng_interpolate()");
4061 for (row=0; row < prow; row++) /* Precalculate for VNG */
4062 for (col=0; col < pcol; col++) {
4063 code[row][col] = ip;
4064 for (cp=terms, t=0; t < 64; t++) {
4065 y1 = *cp++; x1 = *cp++;
4066 y2 = *cp++; x2 = *cp++;
4069 color = fcol(row+y1,col+x1);
4070 if (fcol(row+y2,col+x2) != color) continue;
4071 diag = (fcol(row,col+1) == color && fcol(row+1,col) == color) ? 2:1;
4072 if (abs(y1-y2) == diag && abs(x1-x2) == diag) continue;
4073 *ip++ = (y1*width + x1)*4 + color;
4074 *ip++ = (y2*width + x2)*4 + color;
4076 for (g=0; g < 8; g++)
4077 if (grads & 1<<g) *ip++ = g;
4081 for (cp=chood, g=0; g < 8; g++) {
4082 y = *cp++; x = *cp++;
4083 *ip++ = (y*width + x) * 4;
4084 color = fcol(row,col);
4085 if (fcol(row+y,col+x) != color && fcol(row+y*2,col+x*2) == color)
4086 *ip++ = (y*width + x) * 8 + color;
4091 brow[4] = (ushort (*)[4]) calloc (width*3, sizeof **brow);
4092 merror (brow[4], "vng_interpolate()");
4093 for (row=0; row < 3; row++)
4094 brow[row] = brow[4] + row*width;
4095 for (row=2; row < height-2; row++) { /* Do VNG interpolation */
4096 for (col=2; col < width-2; col++) {
4097 pix = image[row*width+col];
4098 ip = code[row % prow][col % pcol];
4099 memset (gval, 0, sizeof gval);
4100 while ((g = ip[0]) != INT_MAX) { /* Calculate gradients */
4101 diff = ABS(pix[g] - pix[ip[1]]) << ip[2];
4102 gval[ip[3]] += diff;
4104 if ((g = ip[-1]) == -1) continue;
4106 while ((g = *ip++) != -1)
4110 gmin = gmax = gval[0]; /* Choose a threshold */
4111 for (g=1; g < 8; g++) {
4112 if (gmin > gval[g]) gmin = gval[g];
4113 if (gmax < gval[g]) gmax = gval[g];
4116 memcpy (brow[2][col], pix, sizeof *image);
4119 thold = gmin + (gmax >> 1);
4120 memset (sum, 0, sizeof sum);
4121 color = fcol(row,col);
4122 for (num=g=0; g < 8; g++,ip+=2) { /* Average the neighbors */
4123 if (gval[g] <= thold) {
4125 if (c == color && ip[1])
4126 sum[c] += (pix[c] + pix[ip[1]]) >> 1;
4128 sum[c] += pix[ip[0] + c];
4132 FORCC { /* Save to buffer */
4135 t += (sum[c] - sum[color]) / num;
4136 brow[2][col][c] = CLIP(t);
4139 if (row > 3) /* Write buffer to image */
4140 memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image);
4141 for (g=0; g < 4; g++)
4142 brow[(g-1) & 3] = brow[g];
4144 memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image);
4145 memcpy (image[(row-1)*width+2], brow[1]+2, (width-4)*sizeof *image);
4151 Patterned Pixel Grouping Interpolation by Alain Desbiolles
4153 void CLASS ppg_interpolate()
4155 int dir[5] = { 1, width, -1, -width, 1 };
4156 int row, col, diff[2], guess[2], c, d, i;
4159 border_interpolate(3);
4160 if (verbose) fprintf (stderr,_("PPG interpolation...\n"));
4162 /* Fill in the green layer with gradients and pattern recognition: */
4163 for (row=3; row < height-3; row++)
4164 for (col=3+(FC(row,3) & 1), c=FC(row,col); col < width-3; col+=2) {
4165 pix = image + row*width+col;
4166 for (i=0; (d=dir[i]) > 0; i++) {
4167 guess[i] = (pix[-d][1] + pix[0][c] + pix[d][1]) * 2
4168 - pix[-2*d][c] - pix[2*d][c];
4169 diff[i] = ( ABS(pix[-2*d][c] - pix[ 0][c]) +
4170 ABS(pix[ 2*d][c] - pix[ 0][c]) +
4171 ABS(pix[ -d][1] - pix[ d][1]) ) * 3 +
4172 ( ABS(pix[ 3*d][1] - pix[ d][1]) +
4173 ABS(pix[-3*d][1] - pix[-d][1]) ) * 2;
4175 d = dir[i = diff[0] > diff[1]];
4176 pix[0][1] = ULIM(guess[i] >> 2, pix[d][1], pix[-d][1]);
4178 /* Calculate red and blue for each green pixel: */
4179 for (row=1; row < height-1; row++)
4180 for (col=1+(FC(row,2) & 1), c=FC(row,col+1); col < width-1; col+=2) {
4181 pix = image + row*width+col;
4182 for (i=0; (d=dir[i]) > 0; c=2-c, i++)
4183 pix[0][c] = CLIP((pix[-d][c] + pix[d][c] + 2*pix[0][1]
4184 - pix[-d][1] - pix[d][1]) >> 1);
4186 /* Calculate blue for red pixels and vice versa: */
4187 for (row=1; row < height-1; row++)
4188 for (col=1+(FC(row,1) & 1), c=2-FC(row,col); col < width-1; col+=2) {
4189 pix = image + row*width+col;
4190 for (i=0; (d=dir[i]+dir[i+1]) > 0; i++) {
4191 diff[i] = ABS(pix[-d][c] - pix[d][c]) +
4192 ABS(pix[-d][1] - pix[0][1]) +
4193 ABS(pix[ d][1] - pix[0][1]);
4194 guess[i] = pix[-d][c] + pix[d][c] + 2*pix[0][1]
4195 - pix[-d][1] - pix[d][1];
4197 if (diff[0] != diff[1])
4198 pix[0][c] = CLIP(guess[diff[0] > diff[1]] >> 1);
4200 pix[0][c] = CLIP((guess[0]+guess[1]) >> 2);
4205 Adaptive Homogeneity-Directed interpolation is based on
4206 the work of Keigo Hirakawa, Thomas Parks, and Paul Lee.
4208 #define TS 256 /* Tile Size */
4210 void CLASS ahd_interpolate()
4212 int i, j, k, top, left, row, col, tr, tc, c, d, val, hm[2];
4213 ushort (*pix)[4], (*rix)[3];
4214 static const int dir[4] = { -1, 1, -TS, TS };
4215 unsigned ldiff[2][4], abdiff[2][4], leps, abeps;
4216 float r, cbrt[0x10000], xyz[3], xyz_cam[3][4];
4217 ushort (*rgb)[TS][TS][3];
4218 short (*lab)[TS][TS][3], (*lix)[3];
4219 char (*homo)[TS][TS], *buffer;
4221 if (verbose) fprintf (stderr,_("AHD interpolation...\n"));
4223 for (i=0; i < 0x10000; i++) {
4225 cbrt[i] = r > 0.008856 ? pow(r,1/3.0) : 7.787*r + 16/116.0;
4227 for (i=0; i < 3; i++)
4228 for (j=0; j < colors; j++)
4229 for (xyz_cam[i][j] = k=0; k < 3; k++)
4230 xyz_cam[i][j] += xyz_rgb[i][k] * rgb_cam[k][j] / d65_white[i];
4232 border_interpolate(5);
4233 buffer = (char *) malloc (26*TS*TS); /* 1664 kB */
4234 merror (buffer, "ahd_interpolate()");
4235 rgb = (ushort(*)[TS][TS][3]) buffer;
4236 lab = (short (*)[TS][TS][3])(buffer + 12*TS*TS);
4237 homo = (char (*)[TS][TS]) (buffer + 24*TS*TS);
4239 for (top=2; top < height-5; top += TS-6)
4240 for (left=2; left < width-5; left += TS-6) {
4242 /* Interpolate green horizontally and vertically: */
4243 for (row = top; row < top+TS && row < height-2; row++) {
4244 col = left + (FC(row,left) & 1);
4245 for (c = FC(row,col); col < left+TS && col < width-2; col+=2) {
4246 pix = image + row*width+col;
4247 val = ((pix[-1][1] + pix[0][c] + pix[1][1]) * 2
4248 - pix[-2][c] - pix[2][c]) >> 2;
4249 rgb[0][row-top][col-left][1] = ULIM(val,pix[-1][1],pix[1][1]);
4250 val = ((pix[-width][1] + pix[0][c] + pix[width][1]) * 2
4251 - pix[-2*width][c] - pix[2*width][c]) >> 2;
4252 rgb[1][row-top][col-left][1] = ULIM(val,pix[-width][1],pix[width][1]);
4255 /* Interpolate red and blue, and convert to CIELab: */
4256 for (d=0; d < 2; d++)
4257 for (row=top+1; row < top+TS-1 && row < height-3; row++)
4258 for (col=left+1; col < left+TS-1 && col < width-3; col++) {
4259 pix = image + row*width+col;
4260 rix = &rgb[d][row-top][col-left];
4261 lix = &lab[d][row-top][col-left];
4262 if ((c = 2 - FC(row,col)) == 1) {
4264 val = pix[0][1] + (( pix[-1][2-c] + pix[1][2-c]
4265 - rix[-1][1] - rix[1][1] ) >> 1);
4266 rix[0][2-c] = CLIP(val);
4267 val = pix[0][1] + (( pix[-width][c] + pix[width][c]
4268 - rix[-TS][1] - rix[TS][1] ) >> 1);
4270 val = rix[0][1] + (( pix[-width-1][c] + pix[-width+1][c]
4271 + pix[+width-1][c] + pix[+width+1][c]
4272 - rix[-TS-1][1] - rix[-TS+1][1]
4273 - rix[+TS-1][1] - rix[+TS+1][1] + 1) >> 2);
4274 rix[0][c] = CLIP(val);
4276 rix[0][c] = pix[0][c];
4277 xyz[0] = xyz[1] = xyz[2] = 0.5;
4279 xyz[0] += xyz_cam[0][c] * rix[0][c];
4280 xyz[1] += xyz_cam[1][c] * rix[0][c];
4281 xyz[2] += xyz_cam[2][c] * rix[0][c];
4283 xyz[0] = cbrt[CLIP((int) xyz[0])];
4284 xyz[1] = cbrt[CLIP((int) xyz[1])];
4285 xyz[2] = cbrt[CLIP((int) xyz[2])];
4286 lix[0][0] = 64 * (116 * xyz[1] - 16);
4287 lix[0][1] = 64 * 500 * (xyz[0] - xyz[1]);
4288 lix[0][2] = 64 * 200 * (xyz[1] - xyz[2]);
4290 /* Build homogeneity maps from the CIELab images: */
4291 memset (homo, 0, 2*TS*TS);
4292 for (row=top+2; row < top+TS-2 && row < height-4; row++) {
4294 for (col=left+2; col < left+TS-2 && col < width-4; col++) {
4296 for (d=0; d < 2; d++) {
4297 lix = &lab[d][tr][tc];
4298 for (i=0; i < 4; i++) {
4299 ldiff[d][i] = ABS(lix[0][0]-lix[dir[i]][0]);
4300 abdiff[d][i] = SQR(lix[0][1]-lix[dir[i]][1])
4301 + SQR(lix[0][2]-lix[dir[i]][2]);
4304 leps = MIN(MAX(ldiff[0][0],ldiff[0][1]),
4305 MAX(ldiff[1][2],ldiff[1][3]));
4306 abeps = MIN(MAX(abdiff[0][0],abdiff[0][1]),
4307 MAX(abdiff[1][2],abdiff[1][3]));
4308 for (d=0; d < 2; d++)
4309 for (i=0; i < 4; i++)
4310 if (ldiff[d][i] <= leps && abdiff[d][i] <= abeps)
4314 /* Combine the most homogenous pixels for the final result: */
4315 for (row=top+3; row < top+TS-3 && row < height-5; row++) {
4317 for (col=left+3; col < left+TS-3 && col < width-5; col++) {
4319 for (d=0; d < 2; d++)
4320 for (hm[d]=0, i=tr-1; i <= tr+1; i++)
4321 for (j=tc-1; j <= tc+1; j++)
4322 hm[d] += homo[d][i][j];
4324 FORC3 image[row*width+col][c] = rgb[hm[1] > hm[0]][tr][tc][c];
4326 FORC3 image[row*width+col][c] =
4327 (rgb[0][tr][tc][c] + rgb[1][tr][tc][c]) >> 1;
4335 void CLASS median_filter()
4338 int pass, c, i, j, k, med[9];
4339 static const uchar opt[] = /* Optimal 9-element median search */
4340 { 1,2, 4,5, 7,8, 0,1, 3,4, 6,7, 1,2, 4,5, 7,8,
4341 0,3, 5,8, 4,7, 3,6, 1,4, 2,5, 4,7, 4,2, 6,4, 4,2 };
4343 for (pass=1; pass <= med_passes; pass++) {
4345 fprintf (stderr,_("Median filter pass %d...\n"), pass);
4346 for (c=0; c < 3; c+=2) {
4347 for (pix = image; pix < image+width*height; pix++)
4348 pix[0][3] = pix[0][c];
4349 for (pix = image+width; pix < image+width*(height-1); pix++) {
4350 if ((pix-image+1) % width < 2) continue;
4351 for (k=0, i = -width; i <= width; i += width)
4352 for (j = i-1; j <= i+1; j++)
4353 med[k++] = pix[j][3] - pix[j][1];
4354 for (i=0; i < sizeof opt; i+=2)
4355 if (med[opt[i]] > med[opt[i+1]])
4356 SWAP (med[opt[i]] , med[opt[i+1]]);
4357 pix[0][c] = CLIP(med[4] + pix[0][1]);
4363 void CLASS blend_highlights()
4365 int clip=INT_MAX, row, col, c, i, j;
4366 static const float trans[2][4][4] =
4367 { { { 1,1,1 }, { 1.7320508,-1.7320508,0 }, { -1,-1,2 } },
4368 { { 1,1,1,1 }, { 1,-1,1,-1 }, { 1,1,-1,-1 }, { 1,-1,-1,1 } } };
4369 static const float itrans[2][4][4] =
4370 { { { 1,0.8660254,-0.5 }, { 1,-0.8660254,-0.5 }, { 1,0,1 } },
4371 { { 1,1,1,1 }, { 1,-1,1,-1 }, { 1,1,-1,-1 }, { 1,-1,-1,1 } } };
4372 float cam[2][4], lab[2][4], sum[2], chratio;
4374 if ((unsigned) (colors-3) > 1) return;
4375 if (verbose) fprintf (stderr,_("Blending highlights...\n"));
4376 FORCC if (clip > (i = 65535*pre_mul[c])) clip = i;
4377 for (row=0; row < height; row++)
4378 for (col=0; col < width; col++) {
4379 FORCC if (image[row*width+col][c] > clip) break;
4380 if (c == colors) continue;
4382 cam[0][c] = image[row*width+col][c];
4383 cam[1][c] = MIN(cam[0][c],clip);
4385 for (i=0; i < 2; i++) {
4386 FORCC for (lab[i][c]=j=0; j < colors; j++)
4387 lab[i][c] += trans[colors-3][c][j] * cam[i][j];
4388 for (sum[i]=0,c=1; c < colors; c++)
4389 sum[i] += SQR(lab[i][c]);
4391 chratio = sqrt(sum[1]/sum[0]);
4392 for (c=1; c < colors; c++)
4393 lab[0][c] *= chratio;
4394 FORCC for (cam[0][c]=j=0; j < colors; j++)
4395 cam[0][c] += itrans[colors-3][c][j] * lab[0][j];
4396 FORCC image[row*width+col][c] = cam[0][c] / colors;
4400 #define SCALE (4 >> shrink)
4401 void CLASS recover_highlights()
4403 float *map, sum, wgt, grow;
4404 int hsat[4], count, spread, change, val, i;
4405 unsigned high, wide, mrow, mcol, row, col, kc, c, d, y, x;
4407 static const signed char dir[8][2] =
4408 { {-1,-1}, {-1,0}, {-1,1}, {0,1}, {1,1}, {1,0}, {1,-1}, {0,-1} };
4410 if (verbose) fprintf (stderr,_("Rebuilding highlights...\n"));
4412 grow = pow (2, 4-highlight);
4413 FORCC hsat[c] = 32000 * pre_mul[c];
4414 for (kc=0, c=1; c < colors; c++)
4415 if (pre_mul[kc] < pre_mul[c]) kc = c;
4416 high = height / SCALE;
4417 wide = width / SCALE;
4418 map = (float *) calloc (high*wide, sizeof *map);
4419 merror (map, "recover_highlights()");
4420 FORCC if (c != kc) {
4421 memset (map, 0, high*wide*sizeof *map);
4422 for (mrow=0; mrow < high; mrow++)
4423 for (mcol=0; mcol < wide; mcol++) {
4424 sum = wgt = count = 0;
4425 for (row = mrow*SCALE; row < (mrow+1)*SCALE; row++)
4426 for (col = mcol*SCALE; col < (mcol+1)*SCALE; col++) {
4427 pixel = image[row*width+col];
4428 if (pixel[c] / hsat[c] == 1 && pixel[kc] > 24000) {
4434 if (count == SCALE*SCALE)
4435 map[mrow*wide+mcol] = sum / wgt;
4437 for (spread = 32/grow; spread--; ) {
4438 for (mrow=0; mrow < high; mrow++)
4439 for (mcol=0; mcol < wide; mcol++) {
4440 if (map[mrow*wide+mcol]) continue;
4442 for (d=0; d < 8; d++) {
4443 y = mrow + dir[d][0];
4444 x = mcol + dir[d][1];
4445 if (y < high && x < wide && map[y*wide+x] > 0) {
4446 sum += (1 + (d & 1)) * map[y*wide+x];
4447 count += 1 + (d & 1);
4451 map[mrow*wide+mcol] = - (sum+grow) / (count+grow);
4453 for (change=i=0; i < high*wide; i++)
4460 for (i=0; i < high*wide; i++)
4461 if (map[i] == 0) map[i] = 1;
4462 for (mrow=0; mrow < high; mrow++)
4463 for (mcol=0; mcol < wide; mcol++) {
4464 for (row = mrow*SCALE; row < (mrow+1)*SCALE; row++)
4465 for (col = mcol*SCALE; col < (mcol+1)*SCALE; col++) {
4466 pixel = image[row*width+col];
4467 if (pixel[c] / hsat[c] > 1) {
4468 val = pixel[kc] * map[mrow*wide+mcol];
4469 if (pixel[c] < val) pixel[c] = CLIP(val);
4478 void CLASS tiff_get (unsigned base,
4479 unsigned *tag, unsigned *type, unsigned *len, unsigned *save)
4484 *save = ftell(ifp) + 4;
4485 if (*len * ("11124811248488"[*type < 14 ? *type:0]-'0') > 4)
4486 fseek (ifp, get4()+base, SEEK_SET);
4489 void CLASS parse_thumb_note (int base, unsigned toff, unsigned tlen)
4491 unsigned entries, tag, type, len, save;
4495 tiff_get (base, &tag, &type, &len, &save);
4496 if (tag == toff) thumb_offset = get4()+base;
4497 if (tag == tlen) thumb_length = get4();
4498 fseek (ifp, save, SEEK_SET);
4502 int CLASS parse_tiff_ifd (int base);
4504 void CLASS parse_makernote (int base, int uptag)
4506 static const uchar xlat[2][256] = {
4507 { 0xc1,0xbf,0x6d,0x0d,0x59,0xc5,0x13,0x9d,0x83,0x61,0x6b,0x4f,0xc7,0x7f,0x3d,0x3d,
4508 0x53,0x59,0xe3,0xc7,0xe9,0x2f,0x95,0xa7,0x95,0x1f,0xdf,0x7f,0x2b,0x29,0xc7,0x0d,
4509 0xdf,0x07,0xef,0x71,0x89,0x3d,0x13,0x3d,0x3b,0x13,0xfb,0x0d,0x89,0xc1,0x65,0x1f,
4510 0xb3,0x0d,0x6b,0x29,0xe3,0xfb,0xef,0xa3,0x6b,0x47,0x7f,0x95,0x35,0xa7,0x47,0x4f,
4511 0xc7,0xf1,0x59,0x95,0x35,0x11,0x29,0x61,0xf1,0x3d,0xb3,0x2b,0x0d,0x43,0x89,0xc1,
4512 0x9d,0x9d,0x89,0x65,0xf1,0xe9,0xdf,0xbf,0x3d,0x7f,0x53,0x97,0xe5,0xe9,0x95,0x17,
4513 0x1d,0x3d,0x8b,0xfb,0xc7,0xe3,0x67,0xa7,0x07,0xf1,0x71,0xa7,0x53,0xb5,0x29,0x89,
4514 0xe5,0x2b,0xa7,0x17,0x29,0xe9,0x4f,0xc5,0x65,0x6d,0x6b,0xef,0x0d,0x89,0x49,0x2f,
4515 0xb3,0x43,0x53,0x65,0x1d,0x49,0xa3,0x13,0x89,0x59,0xef,0x6b,0xef,0x65,0x1d,0x0b,
4516 0x59,0x13,0xe3,0x4f,0x9d,0xb3,0x29,0x43,0x2b,0x07,0x1d,0x95,0x59,0x59,0x47,0xfb,
4517 0xe5,0xe9,0x61,0x47,0x2f,0x35,0x7f,0x17,0x7f,0xef,0x7f,0x95,0x95,0x71,0xd3,0xa3,
4518 0x0b,0x71,0xa3,0xad,0x0b,0x3b,0xb5,0xfb,0xa3,0xbf,0x4f,0x83,0x1d,0xad,0xe9,0x2f,
4519 0x71,0x65,0xa3,0xe5,0x07,0x35,0x3d,0x0d,0xb5,0xe9,0xe5,0x47,0x3b,0x9d,0xef,0x35,
4520 0xa3,0xbf,0xb3,0xdf,0x53,0xd3,0x97,0x53,0x49,0x71,0x07,0x35,0x61,0x71,0x2f,0x43,
4521 0x2f,0x11,0xdf,0x17,0x97,0xfb,0x95,0x3b,0x7f,0x6b,0xd3,0x25,0xbf,0xad,0xc7,0xc5,
4522 0xc5,0xb5,0x8b,0xef,0x2f,0xd3,0x07,0x6b,0x25,0x49,0x95,0x25,0x49,0x6d,0x71,0xc7 },
4523 { 0xa7,0xbc,0xc9,0xad,0x91,0xdf,0x85,0xe5,0xd4,0x78,0xd5,0x17,0x46,0x7c,0x29,0x4c,
4524 0x4d,0x03,0xe9,0x25,0x68,0x11,0x86,0xb3,0xbd,0xf7,0x6f,0x61,0x22,0xa2,0x26,0x34,
4525 0x2a,0xbe,0x1e,0x46,0x14,0x68,0x9d,0x44,0x18,0xc2,0x40,0xf4,0x7e,0x5f,0x1b,0xad,
4526 0x0b,0x94,0xb6,0x67,0xb4,0x0b,0xe1,0xea,0x95,0x9c,0x66,0xdc,0xe7,0x5d,0x6c,0x05,
4527 0xda,0xd5,0xdf,0x7a,0xef,0xf6,0xdb,0x1f,0x82,0x4c,0xc0,0x68,0x47,0xa1,0xbd,0xee,
4528 0x39,0x50,0x56,0x4a,0xdd,0xdf,0xa5,0xf8,0xc6,0xda,0xca,0x90,0xca,0x01,0x42,0x9d,
4529 0x8b,0x0c,0x73,0x43,0x75,0x05,0x94,0xde,0x24,0xb3,0x80,0x34,0xe5,0x2c,0xdc,0x9b,
4530 0x3f,0xca,0x33,0x45,0xd0,0xdb,0x5f,0xf5,0x52,0xc3,0x21,0xda,0xe2,0x22,0x72,0x6b,
4531 0x3e,0xd0,0x5b,0xa8,0x87,0x8c,0x06,0x5d,0x0f,0xdd,0x09,0x19,0x93,0xd0,0xb9,0xfc,
4532 0x8b,0x0f,0x84,0x60,0x33,0x1c,0x9b,0x45,0xf1,0xf0,0xa3,0x94,0x3a,0x12,0x77,0x33,
4533 0x4d,0x44,0x78,0x28,0x3c,0x9e,0xfd,0x65,0x57,0x16,0x94,0x6b,0xfb,0x59,0xd0,0xc8,
4534 0x22,0x36,0xdb,0xd2,0x63,0x98,0x43,0xa1,0x04,0x87,0x86,0xf7,0xa6,0x26,0xbb,0xd6,
4535 0x59,0x4d,0xbf,0x6a,0x2e,0xaa,0x2b,0xef,0xe6,0x78,0xb6,0x4e,0xe0,0x2f,0xdc,0x7c,
4536 0xbe,0x57,0x19,0x32,0x7e,0x2a,0xd0,0xb8,0xba,0x29,0x00,0x3c,0x52,0x7d,0xa8,0x49,
4537 0x3b,0x2d,0xeb,0x25,0x49,0xfa,0xa3,0xaa,0x39,0xa7,0xc5,0xa7,0x50,0x11,0x36,0xfb,
4538 0xc6,0x67,0x4a,0xf5,0xa5,0x12,0x65,0x7e,0xb0,0xdf,0xaf,0x4e,0xb3,0x61,0x7f,0x2f } };
4539 unsigned offset=0, entries, tag, type, len, save, c;
4540 unsigned ver97=0, serial=0, i, wbi=0, wb[4]={0,0,0,0};
4541 uchar buf97[324], ci, cj, ck;
4542 short morder, sorder=order;
4545 The MakerNote might have its own TIFF header (possibly with
4546 its own byte-order!), or it might just be a table.
4548 if (!strcmp(make,"Nokia")) return;
4549 fread (buf, 1, 10, ifp);
4550 if (!strncmp (buf,"KDK" ,3) || /* these aren't TIFF tables */
4551 !strncmp (buf,"VER" ,3) ||
4552 !strncmp (buf,"IIII",4) ||
4553 !strncmp (buf,"MMMM",4)) return;
4554 if (!strncmp (buf,"KC" ,2) || /* Konica KD-400Z, KD-510Z */
4555 !strncmp (buf,"MLY" ,3)) { /* Minolta DiMAGE G series */
4557 while ((i=ftell(ifp)) < data_offset && i < 16384) {
4558 wb[0] = wb[2]; wb[2] = wb[1]; wb[1] = wb[3];
4560 if (wb[1] == 256 && wb[3] == 256 &&
4561 wb[0] > 256 && wb[0] < 640 && wb[2] > 256 && wb[2] < 640)
4562 FORC4 cam_mul[c] = wb[c];
4566 if (!strcmp (buf,"Nikon")) {
4569 if (get2() != 42) goto quit;
4571 fseek (ifp, offset-8, SEEK_CUR);
4572 } else if (!strcmp (buf,"OLYMPUS")) {
4573 base = ftell(ifp)-10;
4574 fseek (ifp, -2, SEEK_CUR);
4575 order = get2(); get2();
4576 } else if (!strncmp (buf,"SONY",4) ||
4577 !strcmp (buf,"Panasonic")) {
4579 } else if (!strncmp (buf,"FUJIFILM",8)) {
4580 base = ftell(ifp)-10;
4582 fseek (ifp, 2, SEEK_CUR);
4583 } else if (!strcmp (buf,"OLYMP") ||
4584 !strcmp (buf,"LEICA") ||
4585 !strcmp (buf,"Ricoh") ||
4586 !strcmp (buf,"EPSON"))
4587 fseek (ifp, -2, SEEK_CUR);
4588 else if (!strcmp (buf,"AOC") ||
4589 !strcmp (buf,"QVC"))
4590 fseek (ifp, -4, SEEK_CUR);
4592 fseek (ifp, -10, SEEK_CUR);
4593 if (!strncmp(make,"SAMSUNG",7))
4597 if (entries > 1000) return;
4601 tiff_get (base, &tag, &type, &len, &save);
4603 if (tag == 2 && strstr(make,"NIKON") && !iso_speed)
4604 iso_speed = (get2(),get2());
4605 if (tag == 4 && len > 26 && len < 35) {
4606 if ((i=(get4(),get2())) != 0x7fff && !iso_speed)
4607 iso_speed = 50 * pow (2, i/32.0 - 4);
4608 if ((i=(get2(),get2())) != 0x7fff && !aperture)
4609 aperture = pow (2, i/64.0);
4610 if ((i=get2()) != 0xffff && !shutter)
4611 shutter = pow (2, (short) i/-32.0);
4612 wbi = (get2(),get2());
4613 shot_order = (get2(),get2());
4615 if ((tag == 4 || tag == 0x114) && !strncmp(make,"KONICA",6)) {
4616 fseek (ifp, tag == 4 ? 140:160, SEEK_CUR);
4618 case 72: flip = 0; break;
4619 case 76: flip = 6; break;
4620 case 82: flip = 5; break;
4623 if (tag == 7 && type == 2 && len > 20)
4624 fgets (model2, 64, ifp);
4625 if (tag == 8 && type == 4)
4626 shot_order = get4();
4627 if (tag == 9 && !strcmp(make,"Canon"))
4628 fread (artist, 64, 1, ifp);
4629 if (tag == 0xc && len == 4) {
4630 cam_mul[0] = getreal(type);
4631 cam_mul[2] = getreal(type);
4633 if (tag == 0xd && type == 7 && get2() == 0xaaaa) {
4634 for (c=i=2; (ushort) c != 0xbbbb && i < len; i++)
4635 c = c << 8 | fgetc(ifp);
4636 while ((i+=4) < len-5)
4637 if (get4() == 257 && (i=len) && (c = (get4(),fgetc(ifp))) < 3)
4638 flip = "065"[c]-'0';
4640 if (tag == 0x10 && type == 4)
4642 if (tag == 0x11 && is_raw && !strncmp(make,"NIKON",5)) {
4643 fseek (ifp, get4()+base, SEEK_SET);
4644 parse_tiff_ifd (base);
4646 if (tag == 0x14 && type == 7) {
4648 fseek (ifp, 1248, SEEK_CUR);
4651 fread (buf, 1, 10, ifp);
4652 if (!strncmp(buf,"NRW ",4)) {
4653 fseek (ifp, strcmp(buf+4,"0100") ? 46:1546, SEEK_CUR);
4654 cam_mul[0] = get4() << 2;
4655 cam_mul[1] = get4() + get4();
4656 cam_mul[2] = get4() << 2;
4659 if (tag == 0x15 && type == 2 && is_raw)
4660 fread (model, 64, 1, ifp);
4661 if (strstr(make,"PENTAX")) {
4662 if (tag == 0x1b) tag = 0x1018;
4663 if (tag == 0x1c) tag = 0x1017;
4666 while ((c = fgetc(ifp)) && c != EOF)
4667 serial = serial*10 + (isdigit(c) ? c - '0' : c % 10);
4668 if (tag == 0x81 && type == 4) {
4669 data_offset = get4();
4670 fseek (ifp, data_offset + 41, SEEK_SET);
4671 raw_height = get2() * 2;
4673 filters = 0x61616161;
4675 if (tag == 0x29 && type == 1) {
4676 c = wbi < 18 ? "012347800000005896"[wbi]-'0' : 0;
4677 fseek (ifp, 8 + c*32, SEEK_CUR);
4678 FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get4();
4680 if ((tag == 0x81 && type == 7) ||
4681 (tag == 0x100 && type == 7) ||
4682 (tag == 0x280 && type == 1)) {
4683 thumb_offset = ftell(ifp);
4686 if (tag == 0x88 && type == 4 && (thumb_offset = get4()))
4687 thumb_offset += base;
4688 if (tag == 0x89 && type == 4)
4689 thumb_length = get4();
4690 if (tag == 0x8c || tag == 0x96)
4691 meta_offset = ftell(ifp);
4693 for (i=0; i < 4; i++)
4694 ver97 = ver97 * 10 + fgetc(ifp)-'0';
4697 fseek (ifp, 68, SEEK_CUR);
4698 FORC4 cam_mul[(c >> 1) | ((c & 1) << 1)] = get2();
4701 fseek (ifp, 6, SEEK_CUR);
4704 fseek (ifp, 16, SEEK_CUR);
4705 FORC4 cam_mul[c] = get2();
4708 if (ver97 != 205) fseek (ifp, 280, SEEK_CUR);
4709 fread (buf97, 324, 1, ifp);
4712 if (tag == 0xa1 && type == 7) {
4714 fseek (ifp, 140, SEEK_CUR);
4715 FORC3 cam_mul[c] = get4();
4717 if (tag == 0xa4 && type == 3) {
4718 fseek (ifp, wbi*48, SEEK_CUR);
4719 FORC3 cam_mul[c] = get2();
4721 if (tag == 0xa7 && (unsigned) (ver97-200) < 17) {
4722 ci = xlat[0][serial & 0xff];
4723 cj = xlat[1][fgetc(ifp)^fgetc(ifp)^fgetc(ifp)^fgetc(ifp)];
4725 for (i=0; i < 324; i++)
4726 buf97[i] ^= (cj += ci * ck++);
4727 i = "66666>666;6A;:;55"[ver97-200] - '0';
4728 FORC4 cam_mul[c ^ (c >> 1) ^ (i & 1)] =
4729 sget2 (buf97 + (i & -2) + c*2);
4731 if (tag == 0x200 && len == 3)
4732 shot_order = (get4(),get4());
4733 if (tag == 0x200 && len == 4)
4734 FORC4 cblack[c ^ c >> 1] = get2();
4735 if (tag == 0x201 && len == 4)
4737 if (tag == 0x220 && type == 7)
4738 meta_offset = ftell(ifp);
4739 if (tag == 0x401 && type == 4 && len == 4)
4740 FORC4 cblack[c ^ c >> 1] = get4();
4741 if (tag == 0xe01) { /* Nikon Capture Note */
4743 fseek (ifp, 22, SEEK_CUR);
4744 for (offset=22; offset+22 < len; offset += 22+i) {
4746 fseek (ifp, 14, SEEK_CUR);
4748 if (tag == 0x76a43207) flip = get2();
4749 else fseek (ifp, i, SEEK_CUR);
4752 if (tag == 0xe80 && len == 256 && type == 7) {
4753 fseek (ifp, 48, SEEK_CUR);
4754 cam_mul[0] = get2() * 508 * 1.078 / 0x10000;
4755 cam_mul[2] = get2() * 382 * 1.173 / 0x10000;
4757 if (tag == 0xf00 && type == 7) {
4759 fseek (ifp, 176, SEEK_CUR);
4760 else if (len == 734 || len == 1502)
4761 fseek (ifp, 148, SEEK_CUR);
4765 if ((tag == 0x1011 && len == 9) || tag == 0x20400200)
4766 for (i=0; i < 3; i++)
4767 FORC3 cmatrix[i][c] = ((short) get2()) / 256.0;
4768 if ((tag == 0x1012 || tag == 0x20400600) && len == 4)
4769 FORC4 cblack[c ^ c >> 1] = get2();
4770 if (tag == 0x1017 || tag == 0x20400100)
4771 cam_mul[0] = get2() / 256.0;
4772 if (tag == 0x1018 || tag == 0x20400100)
4773 cam_mul[2] = get2() / 256.0;
4774 if (tag == 0x2011 && len == 2) {
4777 cam_mul[0] = get2() / 256.0;
4778 cam_mul[2] = get2() / 256.0;
4780 if ((tag | 0x70) == 0x2070 && type == 4)
4781 fseek (ifp, get4()+base, SEEK_SET);
4782 if (tag == 0x2010 && type != 7)
4783 load_raw = &CLASS olympus_load_raw;
4785 parse_thumb_note (base, 257, 258);
4787 parse_makernote (base, 0x2040);
4788 if (tag == 0xb028) {
4789 fseek (ifp, get4()+base, SEEK_SET);
4790 parse_thumb_note (base, 136, 137);
4792 if (tag == 0x4001 && len > 500) {
4793 i = len == 582 ? 50 : len == 653 ? 68 : len == 5120 ? 142 : 126;
4794 fseek (ifp, i, SEEK_CUR);
4796 FORC4 cam_mul[c ^ (c >> 1)] = get2();
4797 i = len >> 3 == 164 ? 112:22;
4798 fseek (ifp, i, SEEK_CUR);
4799 FORC4 sraw_mul[c ^ (c >> 1)] = get2();
4802 FORC4 cam_mul[c ^ (c >> 1)] = get4();
4804 FORC4 cam_mul[c ^ (c >> 1)] -= get4();
4806 fseek (ifp, save, SEEK_SET);
4813 Since the TIFF DateTime string has no timezone information,
4814 assume that the camera's clock was set to Universal Time.
4816 void CLASS get_timestamp (int reversed)
4824 for (i=19; i--; ) str[i] = fgetc(ifp);
4826 fread (str, 19, 1, ifp);
4827 memset (&t, 0, sizeof t);
4828 if (sscanf (str, "%d:%d:%d %d:%d:%d", &t.tm_year, &t.tm_mon,
4829 &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec) != 6)
4835 timestamp = mktime(&t);
4838 void CLASS parse_exif (int base)
4840 unsigned kodak, entries, tag, type, len, save, c;
4843 kodak = !strncmp(make,"EASTMAN",7) && tiff_nifds < 3;
4846 tiff_get (base, &tag, &type, &len, &save);
4848 case 33434: shutter = getreal(type); break;
4849 case 33437: aperture = getreal(type); break;
4850 case 34855: iso_speed = get2(); break;
4852 case 36868: get_timestamp(0); break;
4853 case 37377: if ((expo = -getreal(type)) < 128)
4854 shutter = pow (2, expo); break;
4855 case 37378: aperture = pow (2, getreal(type)/2); break;
4856 case 37386: focal_len = getreal(type); break;
4857 case 37500: parse_makernote (base, 0); break;
4858 case 40962: if (kodak) raw_width = get4(); break;
4859 case 40963: if (kodak) raw_height = get4(); break;
4861 if (get4() == 0x20002)
4862 for (exif_cfa=c=0; c < 8; c+=2)
4863 exif_cfa |= fgetc(ifp) * 0x01010101 << c;
4865 fseek (ifp, save, SEEK_SET);
4869 void CLASS parse_gps (int base)
4871 unsigned entries, tag, type, len, save, c;
4875 tiff_get (base, &tag, &type, &len, &save);
4877 case 1: case 3: case 5:
4878 gpsdata[29+tag/2] = getc(ifp); break;
4879 case 2: case 4: case 7:
4880 FORC(6) gpsdata[tag/3*6+c] = get4(); break;
4882 FORC(2) gpsdata[18+c] = get4(); break;
4884 fgets ((char *) (gpsdata+14+tag/3), MIN(len,12), ifp);
4886 fseek (ifp, save, SEEK_SET);
4890 void CLASS romm_coeff (float romm_cam[3][3])
4892 static const float rgb_romm[3][3] = /* ROMM == Kodak ProPhoto */
4893 { { 2.034193, -0.727420, -0.306766 },
4894 { -0.228811, 1.231729, -0.002922 },
4895 { -0.008565, -0.153273, 1.161839 } };
4898 for (i=0; i < 3; i++)
4899 for (j=0; j < 3; j++)
4900 for (cmatrix[i][j] = k=0; k < 3; k++)
4901 cmatrix[i][j] += rgb_romm[i][k] * romm_cam[k][j];
4904 void CLASS parse_mos (int offset)
4907 int skip, from, i, c, neut[4], planes=0, frot=0;
4908 static const char *mod[] =
4909 { "","DCB2","Volare","Cantare","CMost","Valeo 6","Valeo 11","Valeo 22",
4910 "Valeo 11p","Valeo 17","","Aptus 17","Aptus 22","Aptus 75","Aptus 65",
4911 "Aptus 54S","Aptus 65S","Aptus 75S","AFi 5","AFi 6","AFi 7",
4912 "","","","","","","","","","","","","","","","","","AFi-II 12" };
4913 float romm_cam[3][3];
4915 fseek (ifp, offset, SEEK_SET);
4917 if (get4() != 0x504b5453) break;
4919 fread (data, 1, 40, ifp);
4922 if (!strcmp(data,"JPEG_preview_data")) {
4923 thumb_offset = from;
4924 thumb_length = skip;
4926 if (!strcmp(data,"icc_camera_profile")) {
4927 profile_offset = from;
4928 profile_length = skip;
4930 if (!strcmp(data,"ShootObj_back_type")) {
4931 fscanf (ifp, "%d", &i);
4932 if ((unsigned) i < sizeof mod / sizeof (*mod))
4933 strcpy (model, mod[i]);
4935 if (!strcmp(data,"icc_camera_to_tone_matrix")) {
4936 for (i=0; i < 9; i++)
4937 romm_cam[0][i] = int_to_float(get4());
4938 romm_coeff (romm_cam);
4940 if (!strcmp(data,"CaptProf_color_matrix")) {
4941 for (i=0; i < 9; i++)
4942 fscanf (ifp, "%f", &romm_cam[0][i]);
4943 romm_coeff (romm_cam);
4945 if (!strcmp(data,"CaptProf_number_of_planes"))
4946 fscanf (ifp, "%d", &planes);
4947 if (!strcmp(data,"CaptProf_raw_data_rotation"))
4948 fscanf (ifp, "%d", &flip);
4949 if (!strcmp(data,"CaptProf_mosaic_pattern"))
4951 fscanf (ifp, "%d", &i);
4952 if (i == 1) frot = c ^ (c >> 1);
4954 if (!strcmp(data,"ImgProf_rotation_angle")) {
4955 fscanf (ifp, "%d", &i);
4958 if (!strcmp(data,"NeutObj_neutrals") && !cam_mul[0]) {
4959 FORC4 fscanf (ifp, "%d", neut+c);
4960 FORC3 cam_mul[c] = (float) neut[0] / neut[c+1];
4962 if (!strcmp(data,"Rows_data"))
4963 load_flags = get4();
4965 fseek (ifp, skip+from, SEEK_SET);
4968 filters = (planes == 1) * 0x01010101 *
4969 (uchar) "\x94\x61\x16\x49"[(flip/90 + frot) & 3];
4972 void CLASS linear_table (unsigned len)
4975 if (len > 0x1000) len = 0x1000;
4976 read_shorts (curve, len);
4977 for (i=len; i < 0x1000; i++)
4978 curve[i] = curve[i-1];
4979 maximum = curve[0xfff];
4982 void CLASS parse_kodak_ifd (int base)
4984 unsigned entries, tag, type, len, save;
4985 int i, c, wbi=-2, wbtemp=6500;
4986 float mul[3]={1,1,1}, num;
4987 static const int wbtag[] = { 64037,64040,64039,64041,-1,-1,64042 };
4990 if (entries > 1024) return;
4992 tiff_get (base, &tag, &type, &len, &save);
4993 if (tag == 1020) wbi = getint(type);
4994 if (tag == 1021 && len == 72) { /* WB set in software */
4995 fseek (ifp, 40, SEEK_CUR);
4996 FORC3 cam_mul[c] = 2048.0 / get2();
4999 if (tag == 2118) wbtemp = getint(type);
5000 if (tag == 2130 + wbi)
5001 FORC3 mul[c] = getreal(type);
5002 if (tag == 2140 + wbi && wbi >= 0)
5004 for (num=i=0; i < 4; i++)
5005 num += getreal(type) * pow (wbtemp/100.0, i);
5006 cam_mul[c] = 2048 / (num * mul[c]);
5008 if (tag == 2317) linear_table (len);
5009 if (tag == 6020) iso_speed = getint(type);
5010 if (tag == 64013) wbi = fgetc(ifp);
5011 if ((unsigned) wbi < 7 && tag == wbtag[wbi])
5012 FORC3 cam_mul[c] = get4();
5013 if (tag == 64019) width = getint(type);
5014 if (tag == 64020) height = (getint(type)+1) & -2;
5015 fseek (ifp, save, SEEK_SET);
5019 void CLASS parse_minolta (int base);
5020 int CLASS parse_tiff (int base);
5022 int CLASS parse_tiff_ifd (int base)
5024 unsigned entries, tag, type, len, plen=16, save;
5025 int ifd, use_cm=0, cfa, i, j, c, ima_len=0;
5026 int blrr=1, blrc=1, dblack[] = { 0,0,0,0 };
5027 char software[64], *cbuf, *cp;
5028 uchar cfa_pat[16], cfa_pc[] = { 0,1,2,3 }, tab[256];
5029 double cc[4][4], cm[4][3], cam_xyz[4][3], num;
5030 double ab[]={ 1,1,1,1 }, asn[] = { 0,0,0,0 }, xyz[] = { 1,1,1 };
5031 unsigned sony_curve[] = { 0,0,0,0,0,4095 };
5032 unsigned *buf, sony_offset=0, sony_length=0, sony_key=0;
5036 if (tiff_nifds >= sizeof tiff_ifd / sizeof tiff_ifd[0])
5039 for (j=0; j < 4; j++)
5040 for (i=0; i < 4; i++)
5043 if (entries > 512) return 1;
5045 tiff_get (base, &tag, &type, &len, &save);
5047 case 5: width = get2(); break;
5048 case 6: height = get2(); break;
5049 case 7: width += get2(); break;
5050 case 9: filters = get2(); break;
5052 if (type == 3 && len == 1)
5053 cam_mul[(tag-17)*2] = get2() / 256.0;
5056 if (type == 3) iso_speed = get2();
5058 case 36: case 37: case 38:
5059 cam_mul[tag-0x24] = get2();
5062 if (len < 50 || cam_mul[0]) break;
5063 fseek (ifp, 12, SEEK_CUR);
5064 FORC3 cam_mul[c] = get2();
5067 if (type != 7 || fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) break;
5068 thumb_offset = ftell(ifp) - 2;
5071 case 61440: /* Fuji HS10 table */
5072 parse_tiff_ifd (base);
5074 case 2: case 256: case 61441: /* ImageWidth */
5075 tiff_ifd[ifd].width = getint(type);
5077 case 3: case 257: case 61442: /* ImageHeight */
5078 tiff_ifd[ifd].height = getint(type);
5080 case 258: /* BitsPerSample */
5082 tiff_ifd[ifd].samples = len & 7;
5083 tiff_ifd[ifd].bps = getint(type);
5087 load_raw = &CLASS packed_load_raw;
5088 load_flags = get4() && (filters=0x16161616) ? 24:80;
5090 case 259: /* Compression */
5091 tiff_ifd[ifd].comp = getint(type);
5093 case 262: /* PhotometricInterpretation */
5094 tiff_ifd[ifd].phint = get2();
5096 case 270: /* ImageDescription */
5097 fread (desc, 512, 1, ifp);
5099 case 271: /* Make */
5100 fgets (make, 64, ifp);
5102 case 272: /* Model */
5103 fgets (model, 64, ifp);
5105 case 280: /* Panasonic RW2 offset */
5106 if (type != 4) break;
5107 load_raw = &CLASS panasonic_load_raw;
5108 load_flags = 0x2008;
5109 case 273: /* StripOffset */
5110 case 513: /* JpegIFOffset */
5112 tiff_ifd[ifd].offset = get4()+base;
5113 if (!tiff_ifd[ifd].bps && tiff_ifd[ifd].offset > 0) {
5114 fseek (ifp, tiff_ifd[ifd].offset, SEEK_SET);
5115 if (ljpeg_start (&jh, 1)) {
5116 tiff_ifd[ifd].comp = 6;
5117 tiff_ifd[ifd].width = jh.wide;
5118 tiff_ifd[ifd].height = jh.high;
5119 tiff_ifd[ifd].bps = jh.bits;
5120 tiff_ifd[ifd].samples = jh.clrs;
5121 if (!(jh.sraw || (jh.clrs & 1)))
5122 tiff_ifd[ifd].width *= jh.clrs;
5124 parse_tiff (tiff_ifd[ifd].offset + 12);
5129 case 274: /* Orientation */
5130 tiff_ifd[ifd].flip = "50132467"[get2() & 7]-'0';
5132 case 277: /* SamplesPerPixel */
5133 tiff_ifd[ifd].samples = getint(type) & 7;
5135 case 279: /* StripByteCounts */
5138 tiff_ifd[ifd].bytes = get4();
5141 FORC3 cam_mul[(4-c) % 3] = getint(type);
5143 case 305: case 11: /* Software */
5144 fgets (software, 64, ifp);
5145 if (!strncmp(software,"Adobe",5) ||
5146 !strncmp(software,"dcraw",5) ||
5147 !strncmp(software,"UFRaw",5) ||
5148 !strncmp(software,"Bibble",6) ||
5149 !strncmp(software,"Nikon Scan",10) ||
5150 !strcmp (software,"Digital Photo Professional"))
5153 case 306: /* DateTime */
5156 case 315: /* Artist */
5157 fread (artist, 64, 1, ifp);
5159 case 322: /* TileWidth */
5160 tiff_ifd[ifd].tile_width = getint(type);
5162 case 323: /* TileLength */
5163 tiff_ifd[ifd].tile_length = getint(type);
5165 case 324: /* TileOffsets */
5166 tiff_ifd[ifd].offset = len > 1 ? ftell(ifp) : get4();
5168 load_raw = &CLASS sinar_4shot_load_raw;
5172 case 330: /* SubIFDs */
5173 if (!strcmp(model,"DSLR-A100") && tiff_ifd[ifd].width == 3872) {
5174 load_raw = &CLASS sony_arw_load_raw;
5175 data_offset = get4()+base;
5180 fseek (ifp, get4()+base, SEEK_SET);
5181 if (parse_tiff_ifd (base)) break;
5182 fseek (ifp, i+4, SEEK_SET);
5186 strcpy (make, "Sarnoff");
5190 FORC4 sony_curve[c+1] = get2() >> 2 & 0xfff;
5191 for (i=0; i < 5; i++)
5192 for (j = sony_curve[i]+1; j <= sony_curve[i+1]; j++)
5193 curve[j] = curve[j-1] + (1 << i);
5195 case 29184: sony_offset = get4(); break;
5196 case 29185: sony_length = get4(); break;
5197 case 29217: sony_key = get4(); break;
5199 parse_minolta (ftell(ifp));
5203 FORC4 cam_mul[c ^ (c < 2)] = get2();
5206 FORC4 cam_mul[c] = get2();
5207 i = (cam_mul[1] == 1024 && cam_mul[2] == 1024) << 1;
5208 SWAP (cam_mul[i],cam_mul[i+1])
5210 case 33405: /* Model2 */
5211 fgets (model2, 64, ifp);
5213 case 33422: /* CFAPattern */
5214 case 64777: /* Kodak P-series */
5215 if ((plen=len) > 16) plen = 16;
5216 fread (cfa_pat, 1, plen, ifp);
5217 for (colors=cfa=i=0; i < plen; i++) {
5218 colors += !(cfa & (1 << cfa_pat[i]));
5219 cfa |= 1 << cfa_pat[i];
5221 if (cfa == 070) memcpy (cfa_pc,"\003\004\005",3); /* CMY */
5222 if (cfa == 072) memcpy (cfa_pc,"\005\003\004\001",4); /* GMCY */
5226 fseek (ifp, get4()+base, SEEK_SET);
5227 parse_kodak_ifd (base);
5229 case 33434: /* ExposureTime */
5230 shutter = getreal(type);
5232 case 33437: /* FNumber */
5233 aperture = getreal(type);
5235 case 34306: /* Leaf white balance */
5236 FORC4 cam_mul[c ^ 1] = 4096.0 / get2();
5238 case 34307: /* Leaf CatchLight color matrix */
5239 fread (software, 1, 7, ifp);
5240 if (strncmp(software,"MATRIX",6)) break;
5242 for (raw_color = i=0; i < 3; i++) {
5243 FORC4 fscanf (ifp, "%f", &rgb_cam[i][c^1]);
5244 if (!use_camera_wb) continue;
5246 FORC4 num += rgb_cam[i][c];
5247 FORC4 rgb_cam[i][c] /= num;
5250 case 34310: /* Leaf metadata */
5251 parse_mos (ftell(ifp));
5253 strcpy (make, "Leaf");
5255 case 34665: /* EXIF tag */
5256 fseek (ifp, get4()+base, SEEK_SET);
5259 case 34853: /* GPSInfo tag */
5260 fseek (ifp, get4()+base, SEEK_SET);
5263 case 34675: /* InterColorProfile */
5264 case 50831: /* AsShotICCProfile */
5265 profile_offset = ftell(ifp);
5266 profile_length = len;
5268 case 37122: /* CompressedBitsPerPixel */
5269 kodak_cbpp = get4();
5271 case 37386: /* FocalLength */
5272 focal_len = getreal(type);
5274 case 37393: /* ImageNumber */
5275 shot_order = getint(type);
5277 case 37400: /* old Kodak KDC tag */
5278 for (raw_color = i=0; i < 3; i++) {
5280 FORC3 rgb_cam[i][c] = getreal(type);
5283 case 46275: /* Imacon tags */
5284 strcpy (make, "Imacon");
5285 data_offset = ftell(ifp);
5289 if (!ima_len) break;
5290 fseek (ifp, 38, SEEK_CUR);
5292 fseek (ifp, 40, SEEK_CUR);
5294 raw_height = get4();
5295 left_margin = get4() & 7;
5296 width = raw_width - left_margin - (get4() & 7);
5297 top_margin = get4() & 7;
5298 height = raw_height - top_margin - (get4() & 7);
5299 if (raw_width == 7262) {
5304 fseek (ifp, 52, SEEK_CUR);
5305 FORC3 cam_mul[c] = getreal(11);
5306 fseek (ifp, 114, SEEK_CUR);
5307 flip = (get2() >> 7) * 90;
5308 if (width * height * 6 == ima_len) {
5309 if (flip % 180 == 90) SWAP(width,height);
5311 raw_height = height;
5312 left_margin = top_margin = filters = flip = 0;
5314 sprintf (model, "Ixpress %d-Mp", height*width/1000000);
5315 load_raw = &CLASS imacon_full_load_raw;
5317 if (left_margin & 1) filters = 0x61616161;
5318 load_raw = &CLASS unpacked_load_raw;
5322 case 50454: /* Sinar tag */
5324 if (!(cbuf = (char *) malloc(len))) break;
5325 fread (cbuf, 1, len, ifp);
5326 for (cp = cbuf-1; cp && cp < cbuf+len; cp = strchr(cp,'\n'))
5327 if (!strncmp (++cp,"Neutral ",8))
5328 sscanf (cp+8, "%f %f %f", cam_mul, cam_mul+1, cam_mul+2);
5332 if (!make[0]) strcpy (make, "Hasselblad");
5334 case 50459: /* Hasselblad tag */
5339 fseek (ifp, j+(get2(),get4()), SEEK_SET);
5345 case 50706: /* DNGVersion */
5346 FORC4 dng_version = (dng_version << 8) + fgetc(ifp);
5347 if (!make[0]) strcpy (make, "DNG");
5350 case 50710: /* CFAPlaneColor */
5351 if (len > 4) len = 4;
5353 fread (cfa_pc, 1, colors, ifp);
5355 FORCC tab[cfa_pc[c]] = c;
5358 filters = filters << 2 | tab[cfa_pat[i % plen]];
5360 case 50711: /* CFALayout */
5363 filters = 0x49494949;
5367 case 50712: /* LinearizationTable */
5370 case 50713: /* BlackLevelRepeatDim */
5376 case 50714: /* BlackLevel */
5377 black = getreal(type);
5378 if (!filters || !~filters) break;
5380 dblack[1] = (blrc == 2) ? getreal(type):dblack[0];
5381 dblack[2] = (blrr == 2) ? getreal(type):dblack[0];
5382 dblack[3] = (blrc == 2 && blrr == 2) ? getreal(type):dblack[1];
5384 filters |= ((filters >> 2 & 0x22222222) |
5385 (filters << 2 & 0x88888888)) & filters << 1;
5386 FORC4 cblack[filters >> (c << 1) & 3] = dblack[c];
5389 case 50715: /* BlackLevelDeltaH */
5390 case 50716: /* BlackLevelDeltaV */
5391 for (num=i=0; i < len; i++)
5392 num += getreal(type);
5393 black += num/len + 0.5;
5395 case 50717: /* WhiteLevel */
5396 maximum = getint(type);
5398 case 50718: /* DefaultScale */
5399 pixel_aspect = getreal(type);
5400 pixel_aspect /= getreal(type);
5402 case 50721: /* ColorMatrix1 */
5403 case 50722: /* ColorMatrix2 */
5404 FORCC for (j=0; j < 3; j++)
5405 cm[c][j] = getreal(type);
5408 case 50723: /* CameraCalibration1 */
5409 case 50724: /* CameraCalibration2 */
5410 for (i=0; i < colors; i++)
5411 FORCC cc[i][c] = getreal(type);
5413 case 50727: /* AnalogBalance */
5414 FORCC ab[c] = getreal(type);
5416 case 50728: /* AsShotNeutral */
5417 FORCC asn[c] = getreal(type);
5419 case 50729: /* AsShotWhiteXY */
5420 xyz[0] = getreal(type);
5421 xyz[1] = getreal(type);
5422 xyz[2] = 1 - xyz[0] - xyz[1];
5423 FORC3 xyz[c] /= d65_white[c];
5425 case 50740: /* DNGPrivateData */
5426 if (dng_version) break;
5427 parse_minolta (j = get4()+base);
5428 fseek (ifp, j, SEEK_SET);
5429 parse_tiff_ifd (base);
5432 read_shorts (cr2_slice, 3);
5434 case 50829: /* ActiveArea */
5435 top_margin = getint(type);
5436 left_margin = getint(type);
5437 height = getint(type) - top_margin;
5438 width = getint(type) - left_margin;
5440 case 50830: /* MaskedAreas */
5441 for (i=0; i < len && i < 32; i++)
5442 mask[0][i] = getint(type);
5445 case 51009: /* OpcodeList2 */
5446 meta_offset = ftell(ifp);
5448 case 64772: /* Kodak P-series */
5449 if (len < 13) break;
5450 fseek (ifp, 16, SEEK_CUR);
5451 data_offset = get4();
5452 fseek (ifp, 28, SEEK_CUR);
5453 data_offset += get4();
5454 load_raw = &CLASS packed_load_raw;
5457 if (type == 2) fgets (model2, 64, ifp);
5459 fseek (ifp, save, SEEK_SET);
5461 if (sony_length && (buf = (unsigned *) malloc(sony_length))) {
5462 fseek (ifp, sony_offset, SEEK_SET);
5463 fread (buf, sony_length, 1, ifp);
5464 sony_decrypt (buf, sony_length/4, 1, sony_key);
5466 if ((ifp = tmpfile())) {
5467 fwrite (buf, sony_length, 1, ifp);
5468 fseek (ifp, 0, SEEK_SET);
5469 parse_tiff_ifd (-sony_offset);
5475 for (i=0; i < colors; i++)
5476 FORCC cc[i][c] *= ab[i];
5478 FORCC for (i=0; i < 3; i++)
5479 for (cam_xyz[c][i]=j=0; j < colors; j++)
5480 cam_xyz[c][i] += cc[c][j] * cm[j][i] * xyz[i];
5481 cam_xyz_coeff (cam_xyz);
5485 FORCC cam_mul[c] = 1 / asn[c];
5488 FORCC pre_mul[c] /= cc[c][c];
5492 int CLASS parse_tiff (int base)
5496 fseek (ifp, base, SEEK_SET);
5498 if (order != 0x4949 && order != 0x4d4d) return 0;
5500 while ((doff = get4())) {
5501 fseek (ifp, doff+base, SEEK_SET);
5502 if (parse_tiff_ifd (base)) break;
5507 void CLASS apply_tiff()
5509 int max_samp=0, raw=-1, thm=-1, i;
5514 fseek (ifp, thumb_offset, SEEK_SET);
5515 if (ljpeg_start (&jh, 1)) {
5516 thumb_misc = jh.bits;
5517 thumb_width = jh.wide;
5518 thumb_height = jh.high;
5521 for (i=0; i < tiff_nifds; i++) {
5522 if (max_samp < tiff_ifd[i].samples)
5523 max_samp = tiff_ifd[i].samples;
5524 if (max_samp > 3) max_samp = 3;
5525 if ((tiff_ifd[i].comp != 6 || tiff_ifd[i].samples != 3) &&
5526 (tiff_ifd[i].width | tiff_ifd[i].height) < 0x10000 &&
5527 tiff_ifd[i].width*tiff_ifd[i].height > raw_width*raw_height) {
5528 raw_width = tiff_ifd[i].width;
5529 raw_height = tiff_ifd[i].height;
5530 tiff_bps = tiff_ifd[i].bps;
5531 tiff_compress = tiff_ifd[i].comp;
5532 data_offset = tiff_ifd[i].offset;
5533 tiff_flip = tiff_ifd[i].flip;
5534 tiff_samples = tiff_ifd[i].samples;
5535 tile_width = tiff_ifd[i].tile_width;
5536 tile_length = tiff_ifd[i].tile_length;
5540 if (!tile_width ) tile_width = INT_MAX;
5541 if (!tile_length) tile_length = INT_MAX;
5542 for (i=tiff_nifds; i--; )
5543 if (tiff_ifd[i].flip) tiff_flip = tiff_ifd[i].flip;
5544 if (raw >= 0 && !load_raw)
5545 switch (tiff_compress) {
5547 if (tiff_ifd[raw].bytes == raw_width*raw_height) {
5549 load_raw = &CLASS sony_arw2_load_raw; break;
5551 if (tiff_ifd[raw].bytes*8 != raw_width*raw_height*tiff_bps) {
5553 load_raw = &CLASS sony_arw_load_raw; break;
5559 case 32773: goto slr;
5561 if (tiff_ifd[raw].bytes*5 == raw_width*raw_height*8) {
5566 case 8: load_raw = &CLASS eight_bit_load_raw; break;
5567 case 12: if (tiff_ifd[raw].phint == 2)
5569 load_raw = &CLASS packed_load_raw; break;
5570 case 14: load_flags = 0;
5571 case 16: load_raw = &CLASS unpacked_load_raw; break;
5574 case 6: case 7: case 99:
5575 load_raw = &CLASS lossless_jpeg_load_raw; break;
5577 load_raw = &CLASS kodak_262_load_raw; break;
5579 if ((raw_width+9)/10*16*raw_height == tiff_ifd[raw].bytes) {
5580 load_raw = &CLASS packed_load_raw;
5582 } else if (raw_width*raw_height*2 == tiff_ifd[raw].bytes) {
5583 load_raw = &CLASS unpacked_load_raw;
5587 load_raw = &CLASS nikon_load_raw; break;
5589 load_raw = &CLASS lossy_dng_load_raw; break;
5591 load_raw = &CLASS pentax_load_raw; break;
5593 switch (tiff_ifd[raw].phint) {
5594 case 2: load_raw = &CLASS kodak_rgb_load_raw; filters = 0; break;
5595 case 6: load_raw = &CLASS kodak_ycbcr_load_raw; filters = 0; break;
5596 case 32803: load_raw = &CLASS kodak_65000_load_raw;
5599 default: is_raw = 0;
5602 if ( (tiff_samples == 3 && tiff_ifd[raw].bytes &&
5603 tiff_bps != 14 && tiff_bps != 2048 &&
5604 tiff_compress != 32769 && tiff_compress != 32770)
5605 || (tiff_bps == 8 && !strstr(make,"KODAK") && !strstr(make,"Kodak") &&
5606 !strstr(model2,"DEBUG RAW")))
5608 for (i=0; i < tiff_nifds; i++)
5609 if (i != raw && tiff_ifd[i].samples == max_samp &&
5610 tiff_ifd[i].width * tiff_ifd[i].height / SQR(tiff_ifd[i].bps+1) >
5611 thumb_width * thumb_height / SQR(thumb_misc+1)
5612 && tiff_ifd[i].comp != 34892) {
5613 thumb_width = tiff_ifd[i].width;
5614 thumb_height = tiff_ifd[i].height;
5615 thumb_offset = tiff_ifd[i].offset;
5616 thumb_length = tiff_ifd[i].bytes;
5617 thumb_misc = tiff_ifd[i].bps;
5621 thumb_misc |= tiff_ifd[thm].samples << 5;
5622 switch (tiff_ifd[thm].comp) {
5624 write_thumb = &CLASS layer_thumb;
5627 if (tiff_ifd[thm].bps <= 8)
5628 write_thumb = &CLASS ppm_thumb;
5629 else if (!strcmp(make,"Imacon"))
5630 write_thumb = &CLASS ppm16_thumb;
5632 thumb_load_raw = &CLASS kodak_thumb_load_raw;
5635 thumb_load_raw = tiff_ifd[thm].phint == 6 ?
5636 &CLASS kodak_ycbcr_load_raw : &CLASS kodak_rgb_load_raw;
5641 void CLASS parse_minolta (int base)
5643 int save, tag, len, offset, high=0, wide=0, i, c;
5646 fseek (ifp, base, SEEK_SET);
5647 if (fgetc(ifp) || fgetc(ifp)-'M' || fgetc(ifp)-'R') return;
5648 order = fgetc(ifp) * 0x101;
5649 offset = base + get4() + 8;
5650 while ((save=ftell(ifp)) < offset) {
5651 for (tag=i=0; i < 4; i++)
5652 tag = tag << 8 | fgetc(ifp);
5655 case 0x505244: /* PRD */
5656 fseek (ifp, 8, SEEK_CUR);
5660 case 0x574247: /* WBG */
5662 i = strcmp(model,"DiMAGE A200") ? 0:3;
5663 FORC4 cam_mul[c ^ (c >> 1) ^ i] = get2();
5665 case 0x545457: /* TTW */
5666 parse_tiff (ftell(ifp));
5667 data_offset = offset;
5669 fseek (ifp, save+len+8, SEEK_SET);
5677 Many cameras have a "debug mode" that writes JPEG and raw
5678 at the same time. The raw file has no header, so try to
5679 to open the matching JPEG file and read its metadata.
5681 void CLASS parse_external_jpeg()
5683 const char *file, *ext;
5684 char *jname, *jfile, *jext;
5687 ext = strrchr (ifname, '.');
5688 file = strrchr (ifname, '/');
5689 if (!file) file = strrchr (ifname, '\\');
5690 if (!file) file = ifname-1;
5692 if (!ext || strlen(ext) != 4 || ext-file != 8) return;
5693 jname = (char *) malloc (strlen(ifname) + 1);
5694 merror (jname, "parse_external_jpeg()");
5695 strcpy (jname, ifname);
5696 jfile = file - ifname + jname;
5697 jext = ext - ifname + jname;
5698 if (strcasecmp (ext, ".jpg")) {
5699 strcpy (jext, isupper(ext[1]) ? ".JPG":".jpg");
5700 if (isdigit(*file)) {
5701 memcpy (jfile, file+4, 4);
5702 memcpy (jfile+4, file, 4);
5705 while (isdigit(*--jext)) {
5712 if (strcmp (jname, ifname)) {
5713 if ((ifp = fopen (jname, "rb"))) {
5715 fprintf (stderr,_("Reading metadata from %s ...\n"), jname);
5723 fprintf (stderr,_("Failed to read metadata from %s\n"), jname);
5729 CIFF block 0x1030 contains an 8x8 white sample.
5730 Load this into white[][] for use in scale_colors().
5732 void CLASS ciff_block_1030()
5734 static const ushort key[] = { 0x410, 0x45f3 };
5735 int i, bpp, row, col, vbits=0;
5736 unsigned long bitbuf=0;
5738 if ((get2(),get4()) != 0x80008 || !get4()) return;
5740 if (bpp != 10 && bpp != 12) return;
5741 for (i=row=0; row < 8; row++)
5742 for (col=0; col < 8; col++) {
5744 bitbuf = bitbuf << 16 | (get2() ^ key[i++ & 1]);
5748 bitbuf << (LONG_BIT - vbits) >> (LONG_BIT - bpp);
5754 Parse a CIFF file, better known as Canon CRW format.
5756 void CLASS parse_ciff (int offset, int length)
5758 int tboff, nrecs, c, type, len, save, wbi=-1;
5759 ushort key[] = { 0x410, 0x45f3 };
5761 fseek (ifp, offset+length-4, SEEK_SET);
5762 tboff = get4() + offset;
5763 fseek (ifp, tboff, SEEK_SET);
5765 if (nrecs > 100) return;
5769 save = ftell(ifp) + 4;
5770 fseek (ifp, offset+get4(), SEEK_SET);
5771 if ((((type >> 8) + 8) | 8) == 0x38)
5772 parse_ciff (ftell(ifp), len); /* Parse a sub-table */
5775 fread (artist, 64, 1, ifp);
5776 if (type == 0x080a) {
5777 fread (make, 64, 1, ifp);
5778 fseek (ifp, strlen(make) - 63, SEEK_CUR);
5779 fread (model, 64, 1, ifp);
5781 if (type == 0x1810) {
5782 fseek (ifp, 12, SEEK_CUR);
5785 if (type == 0x1835) /* Get the decoder table */
5786 tiff_compress = get4();
5787 if (type == 0x2007) {
5788 thumb_offset = ftell(ifp);
5791 if (type == 0x1818) {
5792 shutter = pow (2, -int_to_float((get4(),get4())));
5793 aperture = pow (2, int_to_float(get4())/2);
5795 if (type == 0x102a) {
5796 iso_speed = pow (2, (get4(),get2())/32.0 - 4) * 50;
5797 aperture = pow (2, (get2(),(short)get2())/64.0);
5798 shutter = pow (2,-((short)get2())/32.0);
5799 wbi = (get2(),get2());
5800 if (wbi > 17) wbi = 0;
5801 fseek (ifp, 32, SEEK_CUR);
5802 if (shutter > 1e6) shutter = get2()/10.0;
5804 if (type == 0x102c) {
5805 if (get2() > 512) { /* Pro90, G1 */
5806 fseek (ifp, 118, SEEK_CUR);
5807 FORC4 cam_mul[c ^ 2] = get2();
5808 } else { /* G2, S30, S40 */
5809 fseek (ifp, 98, SEEK_CUR);
5810 FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get2();
5813 if (type == 0x0032) {
5814 if (len == 768) { /* EOS D30 */
5815 fseek (ifp, 72, SEEK_CUR);
5816 FORC4 cam_mul[c ^ (c >> 1)] = 1024.0 / get2();
5817 if (!wbi) cam_mul[0] = -1; /* use my auto white balance */
5818 } else if (!cam_mul[0]) {
5819 if (get2() == key[0]) /* Pro1, G6, S60, S70 */
5820 c = (strstr(model,"Pro1") ?
5821 "012346000000000000":"01345:000000006008")[wbi]-'0'+ 2;
5822 else { /* G3, G5, S45, S50 */
5823 c = "023457000000006000"[wbi]-'0';
5824 key[0] = key[1] = 0;
5826 fseek (ifp, 78 + c*8, SEEK_CUR);
5827 FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get2() ^ key[c & 1];
5828 if (!wbi) cam_mul[0] = -1;
5831 if (type == 0x10a9) { /* D60, 10D, 300D, and clones */
5832 if (len > 66) wbi = "0134567028"[wbi]-'0';
5833 fseek (ifp, 2 + wbi*8, SEEK_CUR);
5834 FORC4 cam_mul[c ^ (c >> 1)] = get2();
5836 if (type == 0x1030 && (0x18040 >> wbi & 1))
5837 ciff_block_1030(); /* all that don't have 0x10a9 */
5838 if (type == 0x1031) {
5839 raw_width = (get2(),get2());
5840 raw_height = get2();
5842 if (type == 0x5029) {
5843 focal_len = len >> 16;
5844 if ((len & 0xffff) == 2) focal_len /= 32;
5846 if (type == 0x5813) flash_used = int_to_float(len);
5847 if (type == 0x5814) canon_ev = int_to_float(len);
5848 if (type == 0x5817) shot_order = len;
5849 if (type == 0x5834) unique_id = len;
5850 if (type == 0x580e) timestamp = len;
5851 if (type == 0x180e) timestamp = get4();
5853 if ((type | 0x4000) == 0x580e)
5854 timestamp = mktime (gmtime (×tamp));
5856 fseek (ifp, save, SEEK_SET);
5860 void CLASS parse_rollei()
5862 char line[128], *val;
5865 fseek (ifp, 0, SEEK_SET);
5866 memset (&t, 0, sizeof t);
5868 fgets (line, 128, ifp);
5869 if ((val = strchr(line,'=')))
5872 val = line + strlen(line);
5873 if (!strcmp(line,"DAT"))
5874 sscanf (val, "%d.%d.%d", &t.tm_mday, &t.tm_mon, &t.tm_year);
5875 if (!strcmp(line,"TIM"))
5876 sscanf (val, "%d:%d:%d", &t.tm_hour, &t.tm_min, &t.tm_sec);
5877 if (!strcmp(line,"HDR"))
5878 thumb_offset = atoi(val);
5879 if (!strcmp(line,"X "))
5880 raw_width = atoi(val);
5881 if (!strcmp(line,"Y "))
5882 raw_height = atoi(val);
5883 if (!strcmp(line,"TX "))
5884 thumb_width = atoi(val);
5885 if (!strcmp(line,"TY "))
5886 thumb_height = atoi(val);
5887 } while (strncmp(line,"EOHD",4));
5888 data_offset = thumb_offset + thumb_width * thumb_height * 2;
5892 timestamp = mktime(&t);
5893 strcpy (make, "Rollei");
5894 strcpy (model,"d530flex");
5895 write_thumb = &CLASS rollei_thumb;
5898 void CLASS parse_sinar_ia()
5904 fseek (ifp, 4, SEEK_SET);
5906 fseek (ifp, get4(), SEEK_SET);
5908 off = get4(); get4();
5909 fread (str, 8, 1, ifp);
5910 if (!strcmp(str,"META")) meta_offset = off;
5911 if (!strcmp(str,"THUMB")) thumb_offset = off;
5912 if (!strcmp(str,"RAW0")) data_offset = off;
5914 fseek (ifp, meta_offset+20, SEEK_SET);
5915 fread (make, 64, 1, ifp);
5917 if ((cp = strchr(make,' '))) {
5918 strcpy (model, cp+1);
5922 raw_height = get2();
5923 load_raw = &CLASS unpacked_load_raw;
5924 thumb_width = (get4(),get2());
5925 thumb_height = get2();
5926 write_thumb = &CLASS ppm_thumb;
5930 void CLASS parse_phase_one (int base)
5932 unsigned entries, tag, /*type,*/ len, data, save, i, c;
5933 float romm_cam[3][3], *fp;
5936 memset (&ph1, 0, sizeof ph1);
5937 fseek (ifp, base, SEEK_SET);
5938 order = get4() & 0xffff;
5939 if (get4() >> 8 != 0x526177) return; /* "Raw" */
5940 fseek (ifp, get4()+base, SEEK_SET);
5949 fseek (ifp, base+data, SEEK_SET);
5951 case 0x100: flip = "0653"[data & 3]-'0'; break;
5953 for( i=9,fp=&romm_cam[0][0]; --i>=0; ++fp )
5955 romm_coeff (romm_cam);
5958 FORC3 cam_mul[c] = getreal(11);
5960 case 0x108: raw_width = data; break;
5961 case 0x109: raw_height = data; break;
5962 case 0x10a: left_margin = data; break;
5963 case 0x10b: top_margin = data; break;
5964 case 0x10c: width = data; break;
5965 case 0x10d: height = data; break;
5966 case 0x10e: ph1.format = data; break;
5967 case 0x10f: data_offset = data+base; break;
5968 case 0x110: meta_offset = data+base;
5969 meta_length = len; break;
5970 case 0x112: ph1.key_off = save - 4; break;
5971 case 0x210: ph1.tag_210 = int_to_float(data); break;
5972 case 0x21a: ph1.tag_21a = data; break;
5973 case 0x21c: strip_offset = data+base; break;
5974 case 0x21d: ph1.black = data; break;
5975 case 0x222: ph1.split_col = data; break;
5976 case 0x223: ph1.black_off = data+base; break;
5979 fread (model, 1, 63, ifp);
5980 if ((cp = strstr(model," camera"))) *cp = 0;
5982 fseek (ifp, save, SEEK_SET);
5984 load_raw = ph1.format < 3 ?
5985 &CLASS phase_one_load_raw : &CLASS phase_one_load_raw_c;
5987 strcpy (make, "Phase One");
5988 if (model[0]) return;
5989 switch (raw_height) {
5990 case 2060: strcpy (model,"LightPhase"); break;
5991 case 2682: strcpy (model,"H 10"); break;
5992 case 4128: strcpy (model,"H 20"); break;
5993 case 5488: strcpy (model,"H 25"); break;
5997 void CLASS parse_fuji (int offset)
5999 unsigned entries, tag, len, save, c;
6001 fseek (ifp, offset, SEEK_SET);
6003 if (entries > 255) return;
6009 raw_height = get2();
6011 } else if (tag == 0x121) {
6013 if ((width = get2()) == 4284) width += 3;
6014 } else if (tag == 0x130) {
6015 fuji_layout = fgetc(ifp) >> 7;
6016 fuji_width = !(fgetc(ifp) & 8);
6017 } else if (tag == 0x2ff0) {
6018 FORC4 cam_mul[c ^ 1] = get2();
6019 } else if (tag == 0xc000) {
6022 if ((width = get4()) > 10000) width = get4();
6026 fseek (ifp, save+len, SEEK_SET);
6028 height <<= fuji_layout;
6029 width >>= fuji_layout;
6032 int CLASS parse_jpeg (int offset)
6034 int len, save, hlen, mark;
6036 fseek (ifp, offset, SEEK_SET);
6037 if (fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) return 0;
6039 while (fgetc(ifp) == 0xff && (mark = fgetc(ifp)) != 0xda) {
6043 if (mark == 0xc0 || mark == 0xc3) {
6045 raw_height = get2();
6050 if (get4() == 0x48454150) /* "HEAP" */
6051 parse_ciff (save+hlen, len-hlen);
6052 if (parse_tiff (save+6)) apply_tiff();
6053 fseek (ifp, save+len, SEEK_SET);
6058 void CLASS parse_riff()
6060 unsigned i, size, end;
6061 char tag[4], date[64], month[64];
6062 static const char mon[12][4] =
6063 { "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" };
6067 fread (tag, 4, 1, ifp);
6069 end = ftell(ifp) + size;
6070 if (!memcmp(tag,"RIFF",4) || !memcmp(tag,"LIST",4)) {
6072 while (ftell(ifp)+7 < end)
6074 } else if (!memcmp(tag,"nctg",4)) {
6075 while (ftell(ifp)+7 < end) {
6078 if ((i+1) >> 1 == 10 && size == 20)
6080 else fseek (ifp, size, SEEK_CUR);
6082 } else if (!memcmp(tag,"IDIT",4) && size < 64) {
6083 fread (date, 64, 1, ifp);
6085 memset (&t, 0, sizeof t);
6086 if (sscanf (date, "%*s %s %d %d:%d:%d %d", month, &t.tm_mday,
6087 &t.tm_hour, &t.tm_min, &t.tm_sec, &t.tm_year) == 6) {
6088 for (i=0; i < 12 && strcasecmp(mon[i],month); i++);
6092 timestamp = mktime(&t);
6095 fseek (ifp, size, SEEK_CUR);
6098 void CLASS parse_smal (int offset, int fsize)
6102 fseek (ifp, offset+2, SEEK_SET);
6106 fseek (ifp, 5, SEEK_CUR);
6107 if (get4() != fsize) return;
6108 if (ver > 6) data_offset = get4();
6109 raw_height = height = get2();
6110 raw_width = width = get2();
6111 strcpy (make, "SMaL");
6112 sprintf (model, "v%d %dx%d", ver, width, height);
6113 if (ver == 6) load_raw = &CLASS smal_v6_load_raw;
6114 if (ver == 9) load_raw = &CLASS smal_v9_load_raw;
6117 void CLASS parse_cine()
6119 unsigned off_head, off_setup, off_image, i;
6122 fseek (ifp, 4, SEEK_SET);
6123 is_raw = get2() == 2;
6124 fseek (ifp, 14, SEEK_CUR);
6130 if ((i = get4())) timestamp = i;
6131 fseek (ifp, off_head+4, SEEK_SET);
6133 raw_height = get4();
6134 switch (get2(),get2()) {
6135 case 8: load_raw = &CLASS eight_bit_load_raw; break;
6136 case 16: load_raw = &CLASS unpacked_load_raw;
6138 fseek (ifp, off_setup+792, SEEK_SET);
6139 strcpy (make, "CINE");
6140 sprintf (model, "%d", get4());
6141 fseek (ifp, 12, SEEK_CUR);
6142 switch ((i=get4()) & 0xffffff) {
6143 case 3: filters = 0x94949494; break;
6144 case 4: filters = 0x49494949; break;
6145 default: is_raw = 0;
6147 fseek (ifp, 72, SEEK_CUR);
6148 switch ((get4()+3600) % 360) {
6149 case 270: flip = 4; break;
6150 case 180: flip = 1; break;
6151 case 90: flip = 7; break;
6154 cam_mul[0] = getreal(11);
6155 cam_mul[2] = getreal(11);
6156 maximum = ~(-1 << get4());
6157 fseek (ifp, 668, SEEK_CUR);
6158 shutter = get4()/1000000000.0;
6159 fseek (ifp, off_image, SEEK_SET);
6160 if (shot_select < is_raw)
6161 fseek (ifp, shot_select*8, SEEK_CUR);
6162 data_offset = (INT64) get4() + 8;
6163 data_offset += (INT64) get4() << 32;
6166 void CLASS parse_redcine()
6168 unsigned i, len, rdvo;
6172 fseek (ifp, 52, SEEK_SET);
6175 fseek (ifp, 0, SEEK_END);
6176 fseek (ifp, -(i = ftello(ifp) & 511), SEEK_CUR);
6177 if (get4() != i || get4() != 0x52454f42) {
6178 fprintf (stderr,_("%s: Tail is missing, parsing from head...\n"), ifname);
6179 fseek (ifp, 0, SEEK_SET);
6180 while ((len = get4()) != EOF) {
6181 if (get4() == 0x52454456)
6182 if (is_raw++ == shot_select)
6183 data_offset = ftello(ifp) - 8;
6184 fseek (ifp, len-8, SEEK_CUR);
6188 fseek (ifp, 12, SEEK_CUR);
6190 fseeko (ifp, rdvo+8 + shot_select*4, SEEK_SET);
6191 data_offset = get4();
6195 char * CLASS foveon_gets (int offset, char *str, int len)
6198 fseek (ifp, offset, SEEK_SET);
6199 for (i=0; i < len-1; i++)
6200 if ((str[i] = get2()) == 0) break;
6205 void CLASS parse_foveon()
6207 int entries, img=0, off, len, tag, save, i, wide, high, pent, poff[256][2];
6208 char name[64], value[64];
6210 order = 0x4949; /* Little-endian */
6211 fseek (ifp, 36, SEEK_SET);
6213 fseek (ifp, -4, SEEK_END);
6214 fseek (ifp, get4(), SEEK_SET);
6215 if (get4() != 0x64434553) return; /* SECd */
6216 entries = (get4(),get4());
6222 fseek (ifp, off, SEEK_SET);
6223 if (get4() != (0x20434553 | (tag << 24))) return;
6225 case 0x47414d49: /* IMAG */
6226 case 0x32414d49: /* IMA2 */
6227 fseek (ifp, 8, SEEK_CUR);
6231 if (wide > raw_width && high > raw_height) {
6233 case 5: load_flags = 1;
6234 case 6: load_raw = &CLASS foveon_sd_load_raw; break;
6235 case 30: load_raw = &CLASS foveon_dp_load_raw; break;
6236 default: load_raw = 0;
6240 data_offset = off+28;
6242 fseek (ifp, off+28, SEEK_SET);
6243 if (fgetc(ifp) == 0xff && fgetc(ifp) == 0xd8
6244 && thumb_length < len-28) {
6245 thumb_offset = off+28;
6246 thumb_length = len-28;
6247 write_thumb = &CLASS jpeg_thumb;
6249 if (++img == 2 && !thumb_length) {
6250 thumb_offset = off+24;
6252 thumb_height = high;
6253 write_thumb = &CLASS foveon_thumb;
6256 case 0x464d4143: /* CAMF */
6257 meta_offset = off+8;
6258 meta_length = len-28;
6260 case 0x504f5250: /* PROP */
6261 pent = (get4(),get4());
6262 fseek (ifp, 12, SEEK_CUR);
6264 if ((unsigned) pent > 256) pent=256;
6265 for (i=0; i < pent*2; i++)
6266 poff[0][i] = off + get4()*2;
6267 for (i=0; i < pent; i++) {
6268 foveon_gets (poff[i][0], name, 64);
6269 foveon_gets (poff[i][1], value, 64);
6270 if (!strcmp (name, "ISO"))
6271 iso_speed = atoi(value);
6272 if (!strcmp (name, "CAMMANUF"))
6273 strcpy (make, value);
6274 if (!strcmp (name, "CAMMODEL"))
6275 strcpy (model, value);
6276 if (!strcmp (name, "WB_DESC"))
6277 strcpy (model2, value);
6278 if (!strcmp (name, "TIME"))
6279 timestamp = atoi(value);
6280 if (!strcmp (name, "EXPTIME"))
6281 shutter = atoi(value) / 1000000.0;
6282 if (!strcmp (name, "APERTURE"))
6283 aperture = atof(value);
6284 if (!strcmp (name, "FLENGTH"))
6285 focal_len = atof(value);
6288 timestamp = mktime (gmtime (×tamp));
6291 fseek (ifp, save, SEEK_SET);
6297 All matrices are from Adobe DNG Converter unless otherwise noted.
6299 void CLASS adobe_coeff (const char *make, const char *model)
6301 static const struct {
6303 short black, maximum, trans[12];
6305 { "AGFAPHOTO DC-833m", 0, 0, /* DJC */
6306 { 11438,-3762,-1115,-2409,9914,2497,-1227,2295,5300 } },
6307 { "Apple QuickTake", 0, 0, /* DJC */
6308 { 21392,-5653,-3353,2406,8010,-415,7166,1427,2078 } },
6309 { "Canon EOS D2000", 0, 0,
6310 { 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } },
6311 { "Canon EOS D6000", 0, 0,
6312 { 20482,-7172,-3125,-1033,10410,-285,2542,226,3136 } },
6313 { "Canon EOS D30", 0, 0,
6314 { 9805,-2689,-1312,-5803,13064,3068,-2438,3075,8775 } },
6315 { "Canon EOS D60", 0, 0xfa0,
6316 { 6188,-1341,-890,-7168,14489,2937,-2640,3228,8483 } },
6317 { "Canon EOS 5D Mark III", 0, 0x3c80,
6318 { 6722,-635,-963,-4287,12460,2028,-908,2162,5668 } },
6319 { "Canon EOS 5D Mark II", 0, 0x3cf0,
6320 { 4716,603,-830,-7798,15474,2480,-1496,1937,6651 } },
6321 { "Canon EOS 5D", 0, 0xe6c,
6322 { 6347,-479,-972,-8297,15954,2480,-1968,2131,7649 } },
6323 { "Canon EOS 6D", 0, 0x3c82,
6324 { 7034,-804,-1014,-4420,12564,2058,-851,1994,5758 } },
6325 { "Canon EOS 7D", 0, 0x3510,
6326 { 6844,-996,-856,-3876,11761,2396,-593,1772,6198 } },
6327 { "Canon EOS 10D", 0, 0xfa0,
6328 { 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } },
6329 { "Canon EOS 20Da", 0, 0,
6330 { 14155,-5065,-1382,-6550,14633,2039,-1623,1824,6561 } },
6331 { "Canon EOS 20D", 0, 0xfff,
6332 { 6599,-537,-891,-8071,15783,2424,-1983,2234,7462 } },
6333 { "Canon EOS 30D", 0, 0,
6334 { 6257,-303,-1000,-7880,15621,2396,-1714,1904,7046 } },
6335 { "Canon EOS 40D", 0, 0x3f60,
6336 { 6071,-747,-856,-7653,15365,2441,-2025,2553,7315 } },
6337 { "Canon EOS 50D", 0, 0x3d93,
6338 { 4920,616,-593,-6493,13964,2784,-1774,3178,7005 } },
6339 { "Canon EOS 60D", 0, 0x2ff7,
6340 { 6719,-994,-925,-4408,12426,2211,-887,2129,6051 } },
6341 { "Canon EOS 300D", 0, 0xfa0,
6342 { 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } },
6343 { "Canon EOS 350D", 0, 0xfff,
6344 { 6018,-617,-965,-8645,15881,2975,-1530,1719,7642 } },
6345 { "Canon EOS 400D", 0, 0xe8e,
6346 { 7054,-1501,-990,-8156,15544,2812,-1278,1414,7796 } },
6347 { "Canon EOS 450D", 0, 0x390d,
6348 { 5784,-262,-821,-7539,15064,2672,-1982,2681,7427 } },
6349 { "Canon EOS 500D", 0, 0x3479,
6350 { 4763,712,-646,-6821,14399,2640,-1921,3276,6561 } },
6351 { "Canon EOS 550D", 0, 0x3dd7,
6352 { 6941,-1164,-857,-3825,11597,2534,-416,1540,6039 } },
6353 { "Canon EOS 600D", 0, 0x3510,
6354 { 6461,-907,-882,-4300,12184,2378,-819,1944,5931 } },
6355 { "Canon EOS 650D", 0, 0x354d,
6356 { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } },
6357 { "Canon EOS 1000D", 0, 0xe43,
6358 { 6771,-1139,-977,-7818,15123,2928,-1244,1437,7533 } },
6359 { "Canon EOS 1100D", 0, 0x3510,
6360 { 6444,-904,-893,-4563,12308,2535,-903,2016,6728 } },
6361 { "Canon EOS M", 0, 0,
6362 { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } },
6363 { "Canon EOS-1Ds Mark III", 0, 0x3bb0,
6364 { 5859,-211,-930,-8255,16017,2353,-1732,1887,7448 } },
6365 { "Canon EOS-1Ds Mark II", 0, 0xe80,
6366 { 6517,-602,-867,-8180,15926,2378,-1618,1771,7633 } },
6367 { "Canon EOS-1D Mark IV", 0, 0x3bb0,
6368 { 6014,-220,-795,-4109,12014,2361,-561,1824,5787 } },
6369 { "Canon EOS-1D Mark III", 0, 0x3bb0,
6370 { 6291,-540,-976,-8350,16145,2311,-1714,1858,7326 } },
6371 { "Canon EOS-1D Mark II N", 0, 0xe80,
6372 { 6240,-466,-822,-8180,15825,2500,-1801,1938,8042 } },
6373 { "Canon EOS-1D Mark II", 0, 0xe80,
6374 { 6264,-582,-724,-8312,15948,2504,-1744,1919,8664 } },
6375 { "Canon EOS-1DS", 0, 0xe20,
6376 { 4374,3631,-1743,-7520,15212,2472,-2892,3632,8161 } },
6377 { "Canon EOS-1D X", 0, 0x3c4e,
6378 { 6847,-614,-1014,-4669,12737,2139,-1197,2488,6846 } },
6379 { "Canon EOS-1D", 0, 0xe20,
6380 { 6806,-179,-1020,-8097,16415,1687,-3267,4236,7690 } },
6381 { "Canon EOS", 0, 0,
6382 { 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } },
6383 { "Canon PowerShot A530", 0, 0,
6384 { 0 } }, /* don't want the A5 matrix */
6385 { "Canon PowerShot A50", 0, 0,
6386 { -5300,9846,1776,3436,684,3939,-5540,9879,6200,-1404,11175,217 } },
6387 { "Canon PowerShot A5", 0, 0,
6388 { -4801,9475,1952,2926,1611,4094,-5259,10164,5947,-1554,10883,547 } },
6389 { "Canon PowerShot G10", 0, 0,
6390 { 11093,-3906,-1028,-5047,12492,2879,-1003,1750,5561 } },
6391 { "Canon PowerShot G11", 0, 0,
6392 { 12177,-4817,-1069,-1612,9864,2049,-98,850,4471 } },
6393 { "Canon PowerShot G12", 0, 0,
6394 { 13244,-5501,-1248,-1508,9858,1935,-270,1083,4366 } },
6395 { "Canon PowerShot G15", 0, 0,
6396 { 7474,-2301,-567,-4056,11456,2975,-222,716,4181 } },
6397 { "Canon PowerShot G1 X", 0, 0,
6398 { 7378,-1255,-1043,-4088,12251,2048,-876,1946,5805 } },
6399 { "Canon PowerShot G1", 0, 0,
6400 { -4778,9467,2172,4743,-1141,4344,-5146,9908,6077,-1566,11051,557 } },
6401 { "Canon PowerShot G2", 0, 0,
6402 { 9087,-2693,-1049,-6715,14382,2537,-2291,2819,7790 } },
6403 { "Canon PowerShot G3", 0, 0,
6404 { 9212,-2781,-1073,-6573,14189,2605,-2300,2844,7664 } },
6405 { "Canon PowerShot G5", 0, 0,
6406 { 9757,-2872,-933,-5972,13861,2301,-1622,2328,7212 } },
6407 { "Canon PowerShot G6", 0, 0,
6408 { 9877,-3775,-871,-7613,14807,3072,-1448,1305,7485 } },
6409 { "Canon PowerShot G9", 0, 0,
6410 { 7368,-2141,-598,-5621,13254,2625,-1418,1696,5743 } },
6411 { "Canon PowerShot Pro1", 0, 0,
6412 { 10062,-3522,-999,-7643,15117,2730,-765,817,7323 } },
6413 { "Canon PowerShot Pro70", 34, 0,
6414 { -4155,9818,1529,3939,-25,4522,-5521,9870,6610,-2238,10873,1342 } },
6415 { "Canon PowerShot Pro90", 0, 0,
6416 { -4963,9896,2235,4642,-987,4294,-5162,10011,5859,-1770,11230,577 } },
6417 { "Canon PowerShot S30", 0, 0,
6418 { 10566,-3652,-1129,-6552,14662,2006,-2197,2581,7670 } },
6419 { "Canon PowerShot S40", 0, 0,
6420 { 8510,-2487,-940,-6869,14231,2900,-2318,2829,9013 } },
6421 { "Canon PowerShot S45", 0, 0,
6422 { 8163,-2333,-955,-6682,14174,2751,-2077,2597,8041 } },
6423 { "Canon PowerShot S50", 0, 0,
6424 { 8882,-2571,-863,-6348,14234,2288,-1516,2172,6569 } },
6425 { "Canon PowerShot S60", 0, 0,
6426 { 8795,-2482,-797,-7804,15403,2573,-1422,1996,7082 } },
6427 { "Canon PowerShot S70", 0, 0,
6428 { 9976,-3810,-832,-7115,14463,2906,-901,989,7889 } },
6429 { "Canon PowerShot S90", 0, 0,
6430 { 12374,-5016,-1049,-1677,9902,2078,-83,852,4683 } },
6431 { "Canon PowerShot S95", 0, 0,
6432 { 13440,-5896,-1279,-1236,9598,1931,-180,1001,4651 } },
6433 { "Canon PowerShot S100", 0, 0,
6434 { 7968,-2565,-636,-2873,10697,2513,180,667,4211 } },
6435 { "Canon PowerShot S110", 0, 0,
6436 { 8039,-2643,-654,-3783,11230,2930,-206,690,4194 } },
6437 { "Canon PowerShot SX1 IS", 0, 0,
6438 { 6578,-259,-502,-5974,13030,3309,-308,1058,4970 } },
6439 { "Canon PowerShot SX50 HS", 0, 0,
6440 { 12432,-4753,-1247,-2110,10691,1629,-412,1623,4926 } },
6441 { "Canon PowerShot A470", 0, 0, /* DJC */
6442 { 12513,-4407,-1242,-2680,10276,2405,-878,2215,4734 } },
6443 { "Canon PowerShot A610", 0, 0, /* DJC */
6444 { 15591,-6402,-1592,-5365,13198,2168,-1300,1824,5075 } },
6445 { "Canon PowerShot A620", 0, 0, /* DJC */
6446 { 15265,-6193,-1558,-4125,12116,2010,-888,1639,5220 } },
6447 { "Canon PowerShot A630", 0, 0, /* DJC */
6448 { 14201,-5308,-1757,-6087,14472,1617,-2191,3105,5348 } },
6449 { "Canon PowerShot A640", 0, 0, /* DJC */
6450 { 13124,-5329,-1390,-3602,11658,1944,-1612,2863,4885 } },
6451 { "Canon PowerShot A650", 0, 0, /* DJC */
6452 { 9427,-3036,-959,-2581,10671,1911,-1039,1982,4430 } },
6453 { "Canon PowerShot A720", 0, 0, /* DJC */
6454 { 14573,-5482,-1546,-1266,9799,1468,-1040,1912,3810 } },
6455 { "Canon PowerShot S3 IS", 0, 0, /* DJC */
6456 { 14062,-5199,-1446,-4712,12470,2243,-1286,2028,4836 } },
6457 { "Canon PowerShot SX110 IS", 0, 0, /* DJC */
6458 { 14134,-5576,-1527,-1991,10719,1273,-1158,1929,3581 } },
6459 { "Canon PowerShot SX220", 0, 0, /* DJC */
6460 { 13898,-5076,-1447,-1405,10109,1297,-244,1860,3687 } },
6461 { "CASIO EX-S20", 0, 0, /* DJC */
6462 { 11634,-3924,-1128,-4968,12954,2015,-1588,2648,7206 } },
6463 { "CASIO EX-Z750", 0, 0, /* DJC */
6464 { 10819,-3873,-1099,-4903,13730,1175,-1755,3751,4632 } },
6465 { "CASIO EX-Z10", 128, 0xfff, /* DJC */
6466 { 9790,-3338,-603,-2321,10222,2099,-344,1273,4799 } },
6468 { 3390,480,-500,-800,3610,340,-550,2336,1192 } },
6470 { 3390,480,-500,-800,3610,340,-550,2336,1192 } },
6472 { 20183,-4295,-423,-3940,15330,3985,-280,4870,9800 } },
6473 { "Contax N Digital", 0, 0xf1e,
6474 { 7777,1285,-1053,-9280,16543,2916,-3677,5679,7060 } },
6475 { "EPSON R-D1", 0, 0,
6476 { 6827,-1878,-732,-8429,16012,2564,-704,592,7145 } },
6477 { "FUJIFILM E550", 0, 0,
6478 { 11044,-3888,-1120,-7248,15168,2208,-1531,2277,8069 } },
6479 { "FUJIFILM E900", 0, 0,
6480 { 9183,-2526,-1078,-7461,15071,2574,-2022,2440,8639 } },
6481 { "FUJIFILM F5", 0, 0,
6482 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
6483 { "FUJIFILM F6", 0, 0,
6484 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
6485 { "FUJIFILM F77", 0, 0xfe9,
6486 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
6487 { "FUJIFILM F7", 0, 0,
6488 { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } },
6489 { "FUJIFILM F8", 0, 0,
6490 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
6491 { "FUJIFILM S100FS", 514, 0,
6492 { 11521,-4355,-1065,-6524,13767,3058,-1466,1984,6045 } },
6493 { "FUJIFILM S200EXR", 512, 0x3fff,
6494 { 11401,-4498,-1312,-5088,12751,2613,-838,1568,5941 } },
6495 { "FUJIFILM S20Pro", 0, 0,
6496 { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } },
6497 { "FUJIFILM S2Pro", 128, 0,
6498 { 12492,-4690,-1402,-7033,15423,1647,-1507,2111,7697 } },
6499 { "FUJIFILM S3Pro", 0, 0,
6500 { 11807,-4612,-1294,-8927,16968,1988,-2120,2741,8006 } },
6501 { "FUJIFILM S5Pro", 0, 0,
6502 { 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } },
6503 { "FUJIFILM S5000", 0, 0,
6504 { 8754,-2732,-1019,-7204,15069,2276,-1702,2334,6982 } },
6505 { "FUJIFILM S5100", 0, 0,
6506 { 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } },
6507 { "FUJIFILM S5500", 0, 0,
6508 { 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } },
6509 { "FUJIFILM S5200", 0, 0,
6510 { 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } },
6511 { "FUJIFILM S5600", 0, 0,
6512 { 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } },
6513 { "FUJIFILM S6", 0, 0,
6514 { 12628,-4887,-1401,-6861,14996,1962,-2198,2782,7091 } },
6515 { "FUJIFILM S7000", 0, 0,
6516 { 10190,-3506,-1312,-7153,15051,2238,-2003,2399,7505 } },
6517 { "FUJIFILM S9000", 0, 0,
6518 { 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 } },
6519 { "FUJIFILM S9500", 0, 0,
6520 { 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 } },
6521 { "FUJIFILM S9100", 0, 0,
6522 { 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 } },
6523 { "FUJIFILM S9600", 0, 0,
6524 { 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 } },
6525 { "FUJIFILM IS-1", 0, 0,
6526 { 21461,-10807,-1441,-2332,10599,1999,289,875,7703 } },
6527 { "FUJIFILM IS Pro", 0, 0,
6528 { 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } },
6529 { "FUJIFILM HS10 HS11", 0, 0xf68,
6530 { 12440,-3954,-1183,-1123,9674,1708,-83,1614,4086 } },
6531 { "FUJIFILM HS20EXR", 0, 0,
6532 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
6533 { "FUJIFILM HS3", 0, 0,
6534 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
6535 { "FUJIFILM X100", 0, 0,
6536 { 12161,-4457,-1069,-5034,12874,2400,-795,1724,6904 } },
6537 { "FUJIFILM X10", 0, 0,
6538 { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } },
6539 { "FUJIFILM X-Pro1", 0, 0,
6540 { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } },
6541 { "FUJIFILM X-E1", 0, 0,
6542 { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } },
6543 { "FUJIFILM XF1", 0, 0,
6544 { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } },
6545 { "FUJIFILM X-S1", 0, 0,
6546 { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } },
6547 { "Imacon Ixpress", 0, 0, /* DJC */
6548 { 7025,-1415,-704,-5188,13765,1424,-1248,2742,6038 } },
6549 { "KODAK NC2000", 0, 0,
6550 { 13891,-6055,-803,-465,9919,642,2121,82,1291 } },
6551 { "Kodak DCS315C", 8, 0,
6552 { 17523,-4827,-2510,756,8546,-137,6113,1649,2250 } },
6553 { "Kodak DCS330C", 8, 0,
6554 { 20620,-7572,-2801,-103,10073,-396,3551,-233,2220 } },
6555 { "KODAK DCS420", 0, 0,
6556 { 10868,-1852,-644,-1537,11083,484,2343,628,2216 } },
6557 { "KODAK DCS460", 0, 0,
6558 { 10592,-2206,-967,-1944,11685,230,2206,670,1273 } },
6559 { "KODAK EOSDCS1", 0, 0,
6560 { 10592,-2206,-967,-1944,11685,230,2206,670,1273 } },
6561 { "KODAK EOSDCS3B", 0, 0,
6562 { 9898,-2700,-940,-2478,12219,206,1985,634,1031 } },
6563 { "Kodak DCS520C", 178, 0,
6564 { 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } },
6565 { "Kodak DCS560C", 177, 0,
6566 { 20482,-7172,-3125,-1033,10410,-285,2542,226,3136 } },
6567 { "Kodak DCS620C", 177, 0,
6568 { 23617,-10175,-3149,-2054,11749,-272,2586,-489,3453 } },
6569 { "Kodak DCS620X", 176, 0,
6570 { 13095,-6231,154,12221,-21,-2137,895,4602,2258 } },
6571 { "Kodak DCS660C", 173, 0,
6572 { 18244,-6351,-2739,-791,11193,-521,3711,-129,2802 } },
6573 { "Kodak DCS720X", 0, 0,
6574 { 11775,-5884,950,9556,1846,-1286,-1019,6221,2728 } },
6575 { "Kodak DCS760C", 0, 0,
6576 { 16623,-6309,-1411,-4344,13923,323,2285,274,2926 } },
6577 { "Kodak DCS Pro SLR", 0, 0,
6578 { 5494,2393,-232,-6427,13850,2846,-1876,3997,5445 } },
6579 { "Kodak DCS Pro 14nx", 0, 0,
6580 { 5494,2393,-232,-6427,13850,2846,-1876,3997,5445 } },
6581 { "Kodak DCS Pro 14", 0, 0,
6582 { 7791,3128,-776,-8588,16458,2039,-2455,4006,6198 } },
6583 { "Kodak ProBack645", 0, 0,
6584 { 16414,-6060,-1470,-3555,13037,473,2545,122,4948 } },
6585 { "Kodak ProBack", 0, 0,
6586 { 21179,-8316,-2918,-915,11019,-165,3477,-180,4210 } },
6587 { "KODAK P712", 0, 0,
6588 { 9658,-3314,-823,-5163,12695,2768,-1342,1843,6044 } },
6589 { "KODAK P850", 0, 0xf7c,
6590 { 10511,-3836,-1102,-6946,14587,2558,-1481,1792,6246 } },
6591 { "KODAK P880", 0, 0xfff,
6592 { 12805,-4662,-1376,-7480,15267,2360,-1626,2194,7904 } },
6593 { "KODAK EasyShare Z980", 0, 0,
6594 { 11313,-3559,-1101,-3893,11891,2257,-1214,2398,4908 } },
6595 { "KODAK EasyShare Z981", 0, 0,
6596 { 12729,-4717,-1188,-1367,9187,2582,274,860,4411 } },
6597 { "KODAK EasyShare Z990", 0, 0xfed,
6598 { 11749,-4048,-1309,-1867,10572,1489,-138,1449,4522 } },
6599 { "KODAK EASYSHARE Z1015", 0, 0xef1,
6600 { 11265,-4286,-992,-4694,12343,2647,-1090,1523,5447 } },
6601 { "Leaf CMost", 0, 0,
6602 { 3952,2189,449,-6701,14585,2275,-4536,7349,6536 } },
6603 { "Leaf Valeo 6", 0, 0,
6604 { 3952,2189,449,-6701,14585,2275,-4536,7349,6536 } },
6605 { "Leaf Aptus 54S", 0, 0,
6606 { 8236,1746,-1314,-8251,15953,2428,-3673,5786,5771 } },
6607 { "Leaf Aptus 65", 0, 0,
6608 { 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 } },
6609 { "Leaf Aptus 75", 0, 0,
6610 { 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 } },
6612 { 8236,1746,-1314,-8251,15953,2428,-3673,5786,5771 } },
6613 { "Mamiya ZD", 0, 0,
6614 { 7645,2579,-1363,-8689,16717,2015,-3712,5941,5961 } },
6615 { "Micron 2010", 110, 0, /* DJC */
6616 { 16695,-3761,-2151,155,9682,163,3433,951,4904 } },
6617 { "Minolta DiMAGE 5", 0, 0xf7d,
6618 { 8983,-2942,-963,-6556,14476,2237,-2426,2887,8014 } },
6619 { "Minolta DiMAGE 7Hi", 0, 0xf7d,
6620 { 11368,-3894,-1242,-6521,14358,2339,-2475,3056,7285 } },
6621 { "Minolta DiMAGE 7", 0, 0xf7d,
6622 { 9144,-2777,-998,-6676,14556,2281,-2470,3019,7744 } },
6623 { "Minolta DiMAGE A1", 0, 0xf8b,
6624 { 9274,-2547,-1167,-8220,16323,1943,-2273,2720,8340 } },
6625 { "MINOLTA DiMAGE A200", 0, 0,
6626 { 8560,-2487,-986,-8112,15535,2771,-1209,1324,7743 } },
6627 { "Minolta DiMAGE A2", 0, 0xf8f,
6628 { 9097,-2726,-1053,-8073,15506,2762,-966,981,7763 } },
6629 { "Minolta DiMAGE Z2", 0, 0, /* DJC */
6630 { 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 } },
6631 { "MINOLTA DYNAX 5", 0, 0xffb,
6632 { 10284,-3283,-1086,-7957,15762,2316,-829,882,6644 } },
6633 { "MINOLTA DYNAX 7", 0, 0xffb,
6634 { 10239,-3104,-1099,-8037,15727,2451,-927,925,6871 } },
6635 { "MOTOROLA PIXL", 0, 0, /* DJC */
6636 { 8898,-989,-1033,-3292,11619,1674,-661,3178,5216 } },
6637 { "NIKON D100", 0, 0,
6638 { 5902,-933,-782,-8983,16719,2354,-1402,1455,6464 } },
6639 { "NIKON D1H", 0, 0,
6640 { 7577,-2166,-926,-7454,15592,1934,-2377,2808,8606 } },
6641 { "NIKON D1X", 0, 0,
6642 { 7702,-2245,-975,-9114,17242,1875,-2679,3055,8521 } },
6643 { "NIKON D1", 0, 0, /* multiplied by 2.218750, 1.0, 1.148438 */
6644 { 16772,-4726,-2141,-7611,15713,1972,-2846,3494,9521 } },
6645 { "NIKON D200", 0, 0xfbc,
6646 { 8367,-2248,-763,-8758,16447,2422,-1527,1550,8053 } },
6647 { "NIKON D2H", 0, 0,
6648 { 5710,-901,-615,-8594,16617,2024,-2975,4120,6830 } },
6649 { "NIKON D2X", 0, 0,
6650 { 10231,-2769,-1255,-8301,15900,2552,-797,680,7148 } },
6651 { "NIKON D3000", 0, 0,
6652 { 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } },
6653 { "NIKON D3100", 0, 0,
6654 { 7911,-2167,-813,-5327,13150,2408,-1288,2483,7968 } },
6655 { "NIKON D3200", 0, 0xfb9,
6656 { 7013,-1408,-635,-5268,12902,2640,-1470,2801,7379 } },
6657 { "NIKON D300", 0, 0,
6658 { 9030,-1992,-715,-8465,16302,2255,-2689,3217,8069 } },
6659 { "NIKON D3X", 0, 0,
6660 { 7171,-1986,-648,-8085,15555,2718,-2170,2512,7457 } },
6661 { "NIKON D3S", 0, 0,
6662 { 8828,-2406,-694,-4874,12603,2541,-660,1509,7587 } },
6664 { 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } },
6665 { "NIKON D40X", 0, 0,
6666 { 8819,-2543,-911,-9025,16928,2151,-1329,1213,8449 } },
6667 { "NIKON D40", 0, 0,
6668 { 6992,-1668,-806,-8138,15748,2543,-874,850,7897 } },
6670 { 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } },
6671 { "NIKON D5000", 0, 0xf00,
6672 { 7309,-1403,-519,-8474,16008,2622,-2433,2826,8064 } },
6673 { "NIKON D5100", 0, 0x3de6,
6674 { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } },
6675 { "NIKON D50", 0, 0,
6676 { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } },
6677 { "NIKON D600", 0, 0x3e07,
6678 { 8178,-2245,-609,-4857,12394,2776,-1207,2086,7298 } },
6679 { "NIKON D60", 0, 0,
6680 { 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } },
6681 { "NIKON D7000", 0, 0,
6682 { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } },
6683 { "NIKON D700", 0, 0,
6684 { 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } },
6685 { "NIKON D70", 0, 0,
6686 { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } },
6687 { "NIKON D800", 0, 0,
6688 { 7866,-2108,-555,-4869,12483,2681,-1176,2069,7501 } },
6689 { "NIKON D80", 0, 0,
6690 { 8629,-2410,-883,-9055,16940,2171,-1490,1363,8520 } },
6691 { "NIKON D90", 0, 0xf00,
6692 { 7309,-1403,-519,-8474,16008,2622,-2434,2826,8064 } },
6693 { "NIKON E950", 0, 0x3dd, /* DJC */
6694 { -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } },
6695 { "NIKON E995", 0, 0, /* copied from E5000 */
6696 { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
6697 { "NIKON E2100", 0, 0, /* copied from Z2, new white balance */
6698 { 13142,-4152,-1596,-4655,12374,2282,-1769,2696,6711} },
6699 { "NIKON E2500", 0, 0,
6700 { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
6701 { "NIKON E3200", 0, 0, /* DJC */
6702 { 9846,-2085,-1019,-3278,11109,2170,-774,2134,5745 } },
6703 { "NIKON E4300", 0, 0, /* copied from Minolta DiMAGE Z2 */
6704 { 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 } },
6705 { "NIKON E4500", 0, 0,
6706 { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
6707 { "NIKON E5000", 0, 0,
6708 { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
6709 { "NIKON E5400", 0, 0,
6710 { 9349,-2987,-1001,-7919,15766,2266,-2098,2680,6839 } },
6711 { "NIKON E5700", 0, 0,
6712 { -5368,11478,2368,5537,-113,3148,-4969,10021,5782,778,9028,211 } },
6713 { "NIKON E8400", 0, 0,
6714 { 7842,-2320,-992,-8154,15718,2599,-1098,1342,7560 } },
6715 { "NIKON E8700", 0, 0,
6716 { 8489,-2583,-1036,-8051,15583,2643,-1307,1407,7354 } },
6717 { "NIKON E8800", 0, 0,
6718 { 7971,-2314,-913,-8451,15762,2894,-1442,1520,7610 } },
6719 { "NIKON COOLPIX P6000", 0, 0,
6720 { 9698,-3367,-914,-4706,12584,2368,-837,968,5801 } },
6721 { "NIKON COOLPIX P7000", 0, 0,
6722 { 11432,-3679,-1111,-3169,11239,2202,-791,1380,4455 } },
6723 { "NIKON COOLPIX P7100", 0, 0,
6724 { 11053,-4269,-1024,-1976,10182,2088,-526,1263,4469 } },
6725 { "NIKON COOLPIX P7700", 200, 0,
6726 { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } },
6727 { "NIKON 1 V2", 0, 0,
6728 { 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } },
6730 { 8994,-2667,-865,-4594,12324,2552,-699,1786,6260 } },
6731 { "OLYMPUS C5050", 0, 0,
6732 { 10508,-3124,-1273,-6079,14294,1901,-1653,2306,6237 } },
6733 { "OLYMPUS C5060", 0, 0,
6734 { 10445,-3362,-1307,-7662,15690,2058,-1135,1176,7602 } },
6735 { "OLYMPUS C7070", 0, 0,
6736 { 10252,-3531,-1095,-7114,14850,2436,-1451,1723,6365 } },
6737 { "OLYMPUS C70", 0, 0,
6738 { 10793,-3791,-1146,-7498,15177,2488,-1390,1577,7321 } },
6739 { "OLYMPUS C80", 0, 0,
6740 { 8606,-2509,-1014,-8238,15714,2703,-942,979,7760 } },
6741 { "OLYMPUS E-10", 0, 0xffc,
6742 { 12745,-4500,-1416,-6062,14542,1580,-1934,2256,6603 } },
6743 { "OLYMPUS E-1", 0, 0,
6744 { 11846,-4767,-945,-7027,15878,1089,-2699,4122,8311 } },
6745 { "OLYMPUS E-20", 0, 0xffc,
6746 { 13173,-4732,-1499,-5807,14036,1895,-2045,2452,7142 } },
6747 { "OLYMPUS E-300", 0, 0,
6748 { 7828,-1761,-348,-5788,14071,1830,-2853,4518,6557 } },
6749 { "OLYMPUS E-330", 0, 0,
6750 { 8961,-2473,-1084,-7979,15990,2067,-2319,3035,8249 } },
6751 { "OLYMPUS E-30", 0, 0xfbc,
6752 { 8144,-1861,-1111,-7763,15894,1929,-1865,2542,7607 } },
6753 { "OLYMPUS E-3", 0, 0xf99,
6754 { 9487,-2875,-1115,-7533,15606,2010,-1618,2100,7389 } },
6755 { "OLYMPUS E-400", 0, 0,
6756 { 6169,-1483,-21,-7107,14761,2536,-2904,3580,8568 } },
6757 { "OLYMPUS E-410", 0, 0xf6a,
6758 { 8856,-2582,-1026,-7761,15766,2082,-2009,2575,7469 } },
6759 { "OLYMPUS E-420", 0, 0xfd7,
6760 { 8746,-2425,-1095,-7594,15612,2073,-1780,2309,7416 } },
6761 { "OLYMPUS E-450", 0, 0xfd2,
6762 { 8745,-2425,-1095,-7594,15613,2073,-1780,2309,7416 } },
6763 { "OLYMPUS E-500", 0, 0,
6764 { 8136,-1968,-299,-5481,13742,1871,-2556,4205,6630 } },
6765 { "OLYMPUS E-510", 0, 0xf6a,
6766 { 8785,-2529,-1033,-7639,15624,2112,-1783,2300,7817 } },
6767 { "OLYMPUS E-520", 0, 0xfd2,
6768 { 8344,-2322,-1020,-7596,15635,2048,-1748,2269,7287 } },
6769 { "OLYMPUS E-5", 0, 0xeec,
6770 { 11200,-3783,-1325,-4576,12593,2206,-695,1742,7504 } },
6771 { "OLYMPUS E-600", 0, 0xfaf,
6772 { 8453,-2198,-1092,-7609,15681,2008,-1725,2337,7824 } },
6773 { "OLYMPUS E-620", 0, 0xfaf,
6774 { 8453,-2198,-1092,-7609,15681,2008,-1725,2337,7824 } },
6775 { "OLYMPUS E-P1", 0, 0xffd,
6776 { 8343,-2050,-1021,-7715,15705,2103,-1831,2380,8235 } },
6777 { "OLYMPUS E-P2", 0, 0xffd,
6778 { 8343,-2050,-1021,-7715,15705,2103,-1831,2380,8235 } },
6779 { "OLYMPUS E-P3", 0, 0,
6780 { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } },
6781 { "OLYMPUS E-PL1s", 0, 0,
6782 { 11409,-3872,-1393,-4572,12757,2003,-709,1810,7415 } },
6783 { "OLYMPUS E-PL1", 0, 0,
6784 { 11408,-4289,-1215,-4286,12385,2118,-387,1467,7787 } },
6785 { "OLYMPUS E-PL2", 0, 0,
6786 { 15030,-5552,-1806,-3987,12387,1767,-592,1670,7023 } },
6787 { "OLYMPUS E-PL3", 0, 0,
6788 { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } },
6789 { "OLYMPUS E-PL5", 0, 0xfcb,
6790 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
6791 { "OLYMPUS E-PM1", 0, 0,
6792 { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } },
6793 { "OLYMPUS E-PM2", 0, 0,
6794 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
6795 { "OLYMPUS E-M5", 0, 0xfe1,
6796 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
6797 { "OLYMPUS SP350", 0, 0,
6798 { 12078,-4836,-1069,-6671,14306,2578,-786,939,7418 } },
6799 { "OLYMPUS SP3", 0, 0,
6800 { 11766,-4445,-1067,-6901,14421,2707,-1029,1217,7572 } },
6801 { "OLYMPUS SP500UZ", 0, 0xfff,
6802 { 9493,-3415,-666,-5211,12334,3260,-1548,2262,6482 } },
6803 { "OLYMPUS SP510UZ", 0, 0xffe,
6804 { 10593,-3607,-1010,-5881,13127,3084,-1200,1805,6721 } },
6805 { "OLYMPUS SP550UZ", 0, 0xffe,
6806 { 11597,-4006,-1049,-5432,12799,2957,-1029,1750,6516 } },
6807 { "OLYMPUS SP560UZ", 0, 0xff9,
6808 { 10915,-3677,-982,-5587,12986,2911,-1168,1968,6223 } },
6809 { "OLYMPUS SP570UZ", 0, 0,
6810 { 11522,-4044,-1146,-4736,12172,2904,-988,1829,6039 } },
6811 { "OLYMPUS XZ-1", 0, 0,
6812 { 10901,-4095,-1074,-1141,9208,2293,-62,1417,5158 } },
6813 { "OLYMPUS XZ-2", 0, 0,
6814 { 9777,-3483,-925,-2886,11297,1800,-602,1663,5134 } },
6815 { "PENTAX *ist DL2", 0, 0,
6816 { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
6817 { "PENTAX *ist DL", 0, 0,
6818 { 10829,-2838,-1115,-8339,15817,2696,-837,680,11939 } },
6819 { "PENTAX *ist DS2", 0, 0,
6820 { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
6821 { "PENTAX *ist DS", 0, 0,
6822 { 10371,-2333,-1206,-8688,16231,2602,-1230,1116,11282 } },
6823 { "PENTAX *ist D", 0, 0,
6824 { 9651,-2059,-1189,-8881,16512,2487,-1460,1345,10687 } },
6825 { "PENTAX K10D", 0, 0,
6826 { 9566,-2863,-803,-7170,15172,2112,-818,803,9705 } },
6827 { "PENTAX K1", 0, 0,
6828 { 11095,-3157,-1324,-8377,15834,2720,-1108,947,11688 } },
6829 { "PENTAX K20D", 0, 0,
6830 { 9427,-2714,-868,-7493,16092,1373,-2199,3264,7180 } },
6831 { "PENTAX K200D", 0, 0,
6832 { 9186,-2678,-907,-8693,16517,2260,-1129,1094,8524 } },
6833 { "PENTAX K2000", 0, 0,
6834 { 11057,-3604,-1155,-5152,13046,2329,-282,375,8104 } },
6835 { "PENTAX K-m", 0, 0,
6836 { 11057,-3604,-1155,-5152,13046,2329,-282,375,8104 } },
6837 { "PENTAX K-x", 0, 0,
6838 { 8843,-2837,-625,-5025,12644,2668,-411,1234,7410 } },
6839 { "PENTAX K-r", 0, 0,
6840 { 9895,-3077,-850,-5304,13035,2521,-883,1768,6936 } },
6841 { "PENTAX K-5 II", 0, 0,
6842 { 8170,-2725,-639,-4440,12017,2744,-771,1465,6599 } },
6843 { "PENTAX K-5", 0, 0,
6844 { 8713,-2833,-743,-4342,11900,2772,-722,1543,6247 } },
6845 { "PENTAX K-7", 0, 0,
6846 { 9142,-2947,-678,-8648,16967,1663,-2224,2898,8615 } },
6847 { "PENTAX 645D", 0, 0x3e00,
6848 { 10646,-3593,-1158,-3329,11699,1831,-667,2874,6287 } },
6849 { "Panasonic DMC-FZ8", 0, 0xf7f,
6850 { 8986,-2755,-802,-6341,13575,3077,-1476,2144,6379 } },
6851 { "Panasonic DMC-FZ18", 0, 0,
6852 { 9932,-3060,-935,-5809,13331,2753,-1267,2155,5575 } },
6853 { "Panasonic DMC-FZ28", 15, 0xf96,
6854 { 10109,-3488,-993,-5412,12812,2916,-1305,2140,5543 } },
6855 { "Panasonic DMC-FZ30", 0, 0xf94,
6856 { 10976,-4029,-1141,-7918,15491,2600,-1670,2071,8246 } },
6857 { "Panasonic DMC-FZ3", 143, 0,
6858 { 9938,-2780,-890,-4604,12393,2480,-1117,2304,4620 } },
6859 { "Panasonic DMC-FZ4", 143, 0,
6860 { 13639,-5535,-1371,-1698,9633,2430,316,1152,4108 } },
6861 { "Panasonic DMC-FZ50", 0, 0,
6862 { 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } },
6863 { "LEICA V-LUX1", 0, 0,
6864 { 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } },
6865 { "Panasonic DMC-L10", 15, 0xf96,
6866 { 8025,-1942,-1050,-7920,15904,2100,-2456,3005,7039 } },
6867 { "Panasonic DMC-L1", 0, 0xf7f,
6868 { 8054,-1885,-1025,-8349,16367,2040,-2805,3542,7629 } },
6869 { "LEICA DIGILUX 3", 0, 0xf7f,
6870 { 8054,-1885,-1025,-8349,16367,2040,-2805,3542,7629 } },
6871 { "Panasonic DMC-LC1", 0, 0,
6872 { 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } },
6873 { "LEICA DIGILUX 2", 0, 0,
6874 { 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } },
6875 { "Panasonic DMC-LX1", 0, 0xf7f,
6876 { 10704,-4187,-1230,-8314,15952,2501,-920,945,8927 } },
6877 { "LEICA D-LUX2", 0, 0xf7f,
6878 { 10704,-4187,-1230,-8314,15952,2501,-920,945,8927 } },
6879 { "Panasonic DMC-LX2", 0, 0,
6880 { 8048,-2810,-623,-6450,13519,3272,-1700,2146,7049 } },
6881 { "LEICA D-LUX3", 0, 0,
6882 { 8048,-2810,-623,-6450,13519,3272,-1700,2146,7049 } },
6883 { "Panasonic DMC-LX3", 15, 0,
6884 { 8128,-2668,-655,-6134,13307,3161,-1782,2568,6083 } },
6885 { "LEICA D-LUX 4", 15, 0,
6886 { 8128,-2668,-655,-6134,13307,3161,-1782,2568,6083 } },
6887 { "Panasonic DMC-LX5", 143, 0,
6888 { 10909,-4295,-948,-1333,9306,2399,22,1738,4582 } },
6889 { "LEICA D-LUX 5", 143, 0,
6890 { 10909,-4295,-948,-1333,9306,2399,22,1738,4582 } },
6891 { "Panasonic DMC-LX7", 143, 0,
6892 { 10148,-3743,-991,-2837,11366,1659,-701,1893,4899 } },
6893 { "LEICA D-LUX 6", 143, 0,
6894 { 10148,-3743,-991,-2837,11366,1659,-701,1893,4899 } },
6895 { "Panasonic DMC-FZ100", 143, 0xfff,
6896 { 16197,-6146,-1761,-2393,10765,1869,366,2238,5248 } },
6897 { "LEICA V-LUX 2", 143, 0xfff,
6898 { 16197,-6146,-1761,-2393,10765,1869,366,2238,5248 } },
6899 { "Panasonic DMC-FZ150", 143, 0xfff,
6900 { 11904,-4541,-1189,-2355,10899,1662,-296,1586,4289 } },
6901 { "LEICA V-LUX 3", 143, 0xfff,
6902 { 11904,-4541,-1189,-2355,10899,1662,-296,1586,4289 } },
6903 { "Panasonic DMC-FZ200", 143, 0xfff,
6904 { 8112,-2563,-740,-3730,11784,2197,-941,2075,4933 } },
6905 { "LEICA V-LUX 4", 143, 0xfff,
6906 { 8112,-2563,-740,-3730,11784,2197,-941,2075,4933 } },
6907 { "Panasonic DMC-FX150", 15, 0xfff,
6908 { 9082,-2907,-925,-6119,13377,3058,-1797,2641,5609 } },
6909 { "Panasonic DMC-G10", 0, 0,
6910 { 10113,-3400,-1114,-4765,12683,2317,-377,1437,6710 } },
6911 { "Panasonic DMC-G1", 15, 0xf94,
6912 { 8199,-2065,-1056,-8124,16156,2033,-2458,3022,7220 } },
6913 { "Panasonic DMC-G2", 15, 0xf3c,
6914 { 10113,-3400,-1114,-4765,12683,2317,-377,1437,6710 } },
6915 { "Panasonic DMC-G3", 143, 0xfff,
6916 { 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } },
6917 { "Panasonic DMC-G5", 143, 0xfff,
6918 { 7798,-2562,-740,-3879,11584,2613,-1055,2248,5434 } },
6919 { "Panasonic DMC-GF1", 15, 0xf92,
6920 { 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } },
6921 { "Panasonic DMC-GF2", 143, 0xfff,
6922 { 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } },
6923 { "Panasonic DMC-GF3", 143, 0xfff,
6924 { 9051,-2468,-1204,-5212,13276,2121,-1197,2510,6890 } },
6925 { "Panasonic DMC-GF5", 143, 0xfff,
6926 { 8228,-2945,-660,-3938,11792,2430,-1094,2278,5793 } },
6927 { "Panasonic DMC-GH1", 15, 0xf92,
6928 { 6299,-1466,-532,-6535,13852,2969,-2331,3112,5984 } },
6929 { "Panasonic DMC-GH2", 15, 0xf95,
6930 { 7780,-2410,-806,-3913,11724,2484,-1018,2390,5298 } },
6931 { "Panasonic DMC-GH3", 144, 0,
6932 { 6559,-1752,-491,-3672,11407,2586,-962,1875,5130 } },
6933 { "Panasonic DMC-GX1", 143, 0,
6934 { 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } },
6935 { "Phase One H 20", 0, 0, /* DJC */
6936 { 1313,1855,-109,-6715,15908,808,-327,1840,6020 } },
6937 { "Phase One H 25", 0, 0,
6938 { 2905,732,-237,-8134,16626,1476,-3038,4253,7517 } },
6939 { "Phase One P 2", 0, 0,
6940 { 2905,732,-237,-8134,16626,1476,-3038,4253,7517 } },
6941 { "Phase One P 30", 0, 0,
6942 { 4516,-245,-37,-7020,14976,2173,-3206,4671,7087 } },
6943 { "Phase One P 45", 0, 0,
6944 { 5053,-24,-117,-5684,14076,1702,-2619,4492,5849 } },
6945 { "Phase One P40", 0, 0,
6946 { 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } },
6947 { "Phase One P65", 0, 0,
6948 { 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } },
6949 { "RED ONE", 704, 0xffff, /* DJC */
6950 { 21014,-7891,-2613,-3056,12201,856,-2203,5125,8042 } },
6951 { "SAMSUNG EX1", 0, 0x3e00,
6952 { 8898,-2498,-994,-3144,11328,2066,-760,1381,4576 } },
6953 { "SAMSUNG EX2F", 0, 0x7ff,
6954 { 10648,-3897,-1055,-2022,10573,1668,-492,1611,4742 } },
6955 { "SAMSUNG NX2", 0, 0xfff, /* NX20, NX200, NX210 */
6956 { 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } },
6957 { "SAMSUNG NX1000", 0, 0,
6958 { 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } },
6959 { "SAMSUNG NX", 0, 0, /* NX5, NX10, NX11, NX100 */
6960 { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } },
6961 { "SAMSUNG WB2000", 0, 0xfff,
6962 { 12093,-3557,-1155,-1000,9534,1733,-22,1787,4576 } },
6963 { "SAMSUNG GX-1", 0, 0,
6964 { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
6965 { "SAMSUNG S85", 0, 0xffff, /* DJC */
6966 { 11885,-3968,-1473,-4214,12299,1916,-835,1655,5549 } },
6967 { "Sinar", 0, 0, /* DJC */
6968 { 16442,-2956,-2422,-2877,12128,750,-1136,6066,4559 } },
6969 { "SONY DSC-F828", 0, 0,
6970 { 7924,-1910,-777,-8226,15459,2998,-1517,2199,6818,-7242,11401,3481 } },
6971 { "SONY DSC-R1", 512, 0,
6972 { 8512,-2641,-694,-8042,15670,2526,-1821,2117,7414 } },
6973 { "SONY DSC-V3", 0, 0,
6974 { 7511,-2571,-692,-7894,15088,3060,-948,1111,8128 } },
6975 { "SONY DSC-RX100", 200, 0,
6976 { 8651,-2754,-1057,-3464,12207,1373,-568,1398,4434 } },
6977 { "SONY DSC-RX1", 128, 0,
6978 { 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } },
6979 { "SONY DSLR-A100", 0, 0xfeb,
6980 { 9437,-2811,-774,-8405,16215,2290,-710,596,7181 } },
6981 { "SONY DSLR-A290", 0, 0,
6982 { 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } },
6983 { "SONY DSLR-A2", 0, 0,
6984 { 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } },
6985 { "SONY DSLR-A300", 0, 0,
6986 { 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } },
6987 { "SONY DSLR-A330", 0, 0,
6988 { 9847,-3091,-929,-8485,16346,2225,-714,595,7103 } },
6989 { "SONY DSLR-A350", 0, 0xffc,
6990 { 6038,-1484,-578,-9146,16746,2513,-875,746,7217 } },
6991 { "SONY DSLR-A380", 0, 0,
6992 { 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } },
6993 { "SONY DSLR-A390", 0, 0,
6994 { 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } },
6995 { "SONY DSLR-A450", 128, 0xfeb,
6996 { 4950,-580,-103,-5228,12542,3029,-709,1435,7371 } },
6997 { "SONY DSLR-A580", 128, 0xfeb,
6998 { 5932,-1492,-411,-4813,12285,2856,-741,1524,6739 } },
6999 { "SONY DSLR-A5", 128, 0xfeb,
7000 { 4950,-580,-103,-5228,12542,3029,-709,1435,7371 } },
7001 { "SONY DSLR-A700", 126, 0,
7002 { 5775,-805,-359,-8574,16295,2391,-1943,2341,7249 } },
7003 { "SONY DSLR-A850", 128, 0,
7004 { 5413,-1162,-365,-5665,13098,2866,-608,1179,8440 } },
7005 { "SONY DSLR-A900", 128, 0,
7006 { 5209,-1072,-397,-8845,16120,2919,-1618,1803,8654 } },
7007 { "SONY NEX-5N", 128, 0,
7008 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
7009 { "SONY NEX-5R", 128, 0,
7010 { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } },
7011 { "SONY NEX-3", 138, 0, /* DJC */
7012 { 6907,-1256,-645,-4940,12621,2320,-1710,2581,6230 } },
7013 { "SONY NEX-5", 116, 0, /* DJC */
7014 { 6807,-1350,-342,-4216,11649,2567,-1089,2001,6420 } },
7015 { "SONY NEX-3", 128, 0, /* Adobe */
7016 { 6549,-1550,-436,-4880,12435,2753,-854,1868,6976 } },
7017 { "SONY NEX-5", 128, 0, /* Adobe */
7018 { 6549,-1550,-436,-4880,12435,2753,-854,1868,6976 } },
7019 { "SONY NEX-6", 128, 0,
7020 { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } },
7021 { "SONY NEX-7", 128, 0,
7022 { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } },
7023 { "SONY NEX", 128, 0, /* NEX-C3, NEX-F3 */
7024 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
7025 { "SONY SLT-A33", 128, 0,
7026 { 6069,-1221,-366,-5221,12779,2734,-1024,2066,6834 } },
7027 { "SONY SLT-A35", 128, 0,
7028 { 5986,-1618,-415,-4557,11820,3120,-681,1404,6971 } },
7029 { "SONY SLT-A37", 128, 0,
7030 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
7031 { "SONY SLT-A55", 128, 0,
7032 { 5932,-1492,-411,-4813,12285,2856,-741,1524,6739 } },
7033 { "SONY SLT-A57", 128, 0,
7034 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
7035 { "SONY SLT-A65", 128, 0,
7036 { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } },
7037 { "SONY SLT-A77", 128, 0,
7038 { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } },
7039 { "SONY SLT-A99", 128, 0,
7040 { 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } },
7042 double cam_xyz[4][3];
7046 sprintf (name, "%s %s", make, model);
7047 for (i=0; i < sizeof table / sizeof *table; i++)
7048 if (!strncmp (name, table[i].prefix, strlen(table[i].prefix))) {
7049 if (table[i].black) black = (ushort) table[i].black;
7050 if (table[i].maximum) maximum = (ushort) table[i].maximum;
7051 if (table[i].trans[0]) {
7052 double *dp = &cam_xyz[0][0];
7053 const short *sp = &table[i].trans[0];
7054 for( j=12; --j>=0; ++dp,++sp ) *dp = *sp / 10000.0;
7055 cam_xyz_coeff (cam_xyz);
7061 void CLASS simple_coeff (int index)
7063 static const float table[][12] = {
7064 /* index 0 -- all Foveon cameras */
7065 { 1.4032,-0.2231,-0.1016,-0.5263,1.4816,0.017,-0.0112,0.0183,0.9113 },
7066 /* index 1 -- Kodak DC20 and DC25 */
7067 { 2.25,0.75,-1.75,-0.25,-0.25,0.75,0.75,-0.25,-0.25,-1.75,0.75,2.25 },
7068 /* index 2 -- Logitech Fotoman Pixtura */
7069 { 1.893,-0.418,-0.476,-0.495,1.773,-0.278,-1.017,-0.655,2.672 },
7070 /* index 3 -- Nikon E880, E900, and E990 */
7071 { -1.936280, 1.800443, -1.448486, 2.584324,
7072 1.405365, -0.524955, -0.289090, 0.408680,
7073 -1.204965, 1.082304, 2.941367, -1.818705 }
7077 for (raw_color = i=0; i < 3; i++)
7078 FORCC rgb_cam[i][c] = table[index][i*colors+c];
7081 short CLASS guess_byte_order (int words)
7085 double diff, sum[2] = {0,0};
7087 fread (test[0], 2, 2, ifp);
7088 for (words-=2; words--; ) {
7089 fread (test[t], 2, 1, ifp);
7090 for (msb=0; msb < 2; msb++) {
7091 diff = (test[t^2][msb] << 8 | test[t^2][!msb])
7092 - (test[t ][msb] << 8 | test[t ][!msb]);
7093 sum[msb] += diff*diff;
7097 return sum[0] < sum[1] ? 0x4d4d : 0x4949;
7100 float CLASS find_green (int bps, int bite, int off0, int off1)
7103 int vbits, col, i, c;
7104 ushort img[2][2064];
7108 fseek (ifp, c ? off1:off0, SEEK_SET);
7109 for (vbits=col=0; col < width; col++) {
7110 for (vbits -= bps; vbits < 0; vbits += bite) {
7112 for (i=0; i < bite; i+=8)
7113 bitbuf |= (unsigned) (fgetc(ifp) << i);
7115 img[c][col] = bitbuf << (64-bps-vbits) >> (64-bps);
7119 sum[ c & 1] += ABS(img[0][c]-img[1][c+1]);
7120 sum[~c & 1] += ABS(img[1][c]-img[0][c+1]);
7122 return 100 * log(sum[0]/sum[1]);
7126 Identify which camera created this file, and set global variables
7129 void CLASS identify()
7132 int hlen, flen, fsize, zero_fsize=1, i, c, is_canon;
7135 { 3130, 1743, 4, 0, -6, 0 },
7136 { 3130, 2055, 4, 0, -6, 0 },
7137 { 3130, 2319, 4, 0, -6, 0 },
7138 { 3170, 2103, 18, 0,-42, 20 },
7139 { 3170, 2367, 18, 13,-42,-21 },
7140 { 3177, 2367, 0, 0, -1, 0 },
7141 { 3304, 2458, 0, 0, -1, 0 },
7142 { 3330, 2463, 9, 0, -5, 0 },
7143 { 3330, 2479, 9, 0,-17, 4 },
7144 { 3370, 1899, 15, 0,-44, 20 },
7145 { 3370, 2235, 15, 0,-44, 20 },
7146 { 3370, 2511, 15, 10,-44,-21 },
7147 { 3690, 2751, 3, 0, -8, -3 },
7148 { 3710, 2751, 0, 0, -3, 0 },
7149 { 3724, 2450, 0, 0, 0, -2 },
7150 { 3770, 2487, 17, 0,-44, 19 },
7151 { 3770, 2799, 17, 15,-44,-19 },
7152 { 3880, 2170, 6, 0, -6, 0 },
7153 { 4060, 3018, 0, 0, 0, -2 },
7154 { 4290, 2391, 3, 0, -8, -1 },
7155 { 4330, 2439, 17, 15,-44,-19 },
7156 { 4508, 2962, 0, 0, -3, -4 },
7157 { 4508, 3330, 0, 0, -3, -6 } };
7158 static const struct {
7160 char make[12], model[19], withjpeg;
7162 { 62464, "Kodak", "DC20" ,0 },
7163 { 124928, "Kodak", "DC20" ,0 },
7164 { 1652736, "Kodak", "DCS200" ,0 },
7165 { 4159302, "Kodak", "C330" ,0 },
7166 { 4162462, "Kodak", "C330" ,0 },
7167 { 460800, "Kodak", "C603v" ,0 },
7168 { 614400, "Kodak", "C603v" ,0 },
7169 { 6163328, "Kodak", "C603" ,0 },
7170 { 6166488, "Kodak", "C603" ,0 },
7171 { 9116448, "Kodak", "C603y" ,0 },
7172 { 311696, "ST Micro", "STV680 VGA" ,0 }, /* SPYz */
7173 { 787456, "Creative", "PC-CAM 600" ,0 },
7174 { 1138688, "Minolta", "RD175" ,0 },
7175 { 3840000, "Foculus", "531C" ,0 },
7176 { 307200, "Generic", "640x480" ,0 },
7177 { 786432, "AVT", "F-080C" ,0 },
7178 { 1447680, "AVT", "F-145C" ,0 },
7179 { 1920000, "AVT", "F-201C" ,0 },
7180 { 5067304, "AVT", "F-510C" ,0 },
7181 { 5067316, "AVT", "F-510C" ,0 },
7182 { 10134608, "AVT", "F-510C" ,0 },
7183 { 10134620, "AVT", "F-510C" ,0 },
7184 { 16157136, "AVT", "F-810C" ,0 },
7185 { 1409024, "Sony", "XCD-SX910CR" ,0 },
7186 { 2818048, "Sony", "XCD-SX910CR" ,0 },
7187 { 3884928, "Micron", "2010" ,0 },
7188 { 6624000, "Pixelink", "A782" ,0 },
7189 { 13248000, "Pixelink", "A782" ,0 },
7190 { 6291456, "RoverShot","3320AF" ,0 },
7191 { 6553440, "Canon", "PowerShot A460" ,0 },
7192 { 6653280, "Canon", "PowerShot A530" ,0 },
7193 { 6573120, "Canon", "PowerShot A610" ,0 },
7194 { 9219600, "Canon", "PowerShot A620" ,0 },
7195 { 9243240, "Canon", "PowerShot A470" ,0 },
7196 { 10341600, "Canon", "PowerShot A720 IS",0 },
7197 { 10383120, "Canon", "PowerShot A630" ,0 },
7198 { 12945240, "Canon", "PowerShot A640" ,0 },
7199 { 15636240, "Canon", "PowerShot A650" ,0 },
7200 { 5298000, "Canon", "PowerShot SD300" ,0 },
7201 { 7710960, "Canon", "PowerShot S3 IS" ,0 },
7202 { 15467760, "Canon", "PowerShot SX110 IS",0 },
7203 { 15534576, "Canon", "PowerShot SX120 IS",0 },
7204 { 18653760, "Canon", "PowerShot SX20 IS",0 },
7205 { 19131120, "Canon", "PowerShot SX220 HS",0 },
7206 { 21936096, "Canon", "PowerShot SX30 IS",0 },
7207 { 5939200, "OLYMPUS", "C770UZ" ,0 },
7208 { 1581060, "NIKON", "E900" ,1 }, /* or E900s,E910 */
7209 { 2465792, "NIKON", "E950" ,1 }, /* or E800,E700 */
7210 { 2940928, "NIKON", "E2100" ,1 }, /* or E2500 */
7211 { 4771840, "NIKON", "E990" ,1 }, /* or E995, Oly C3030Z */
7212 { 4775936, "NIKON", "E3700" ,1 }, /* or Optio 33WR */
7213 { 5869568, "NIKON", "E4300" ,1 }, /* or DiMAGE Z2 */
7214 { 5865472, "NIKON", "E4500" ,1 },
7215 { 7438336, "NIKON", "E5000" ,1 }, /* or E5700 */
7216 { 8998912, "NIKON", "COOLPIX S6" ,1 },
7217 { 1976352, "CASIO", "QV-2000UX" ,1 },
7218 { 3217760, "CASIO", "QV-3*00EX" ,1 },
7219 { 6218368, "CASIO", "QV-5700" ,1 },
7220 { 6054400, "CASIO", "QV-R41" ,1 },
7221 { 7530816, "CASIO", "QV-R51" ,1 },
7222 { 7684000, "CASIO", "QV-4000" ,1 },
7223 { 2937856, "CASIO", "EX-S20" ,1 },
7224 { 4948608, "CASIO", "EX-S100" ,1 },
7225 { 7542528, "CASIO", "EX-Z50" ,1 },
7226 { 7562048, "CASIO", "EX-Z500" ,1 },
7227 { 7753344, "CASIO", "EX-Z55" ,1 },
7228 { 7816704, "CASIO", "EX-Z60" ,1 },
7229 { 10843712, "CASIO", "EX-Z75" ,1 },
7230 { 10834368, "CASIO", "EX-Z750" ,1 },
7231 { 12310144, "CASIO", "EX-Z850" ,1 },
7232 { 12489984, "CASIO", "EX-Z8" ,1 },
7233 { 15499264, "CASIO", "EX-Z1050" ,1 },
7234 { 18702336, "CASIO", "EX-ZR100" ,1 },
7235 { 7426656, "CASIO", "EX-P505" ,1 },
7236 { 9313536, "CASIO", "EX-P600" ,1 },
7237 { 10979200, "CASIO", "EX-P700" ,1 },
7238 { 3178560, "PENTAX", "Optio S" ,1 },
7239 { 4841984, "PENTAX", "Optio S" ,1 },
7240 { 6114240, "PENTAX", "Optio S4" ,1 }, /* or S4i, CASIO EX-Z4 */
7241 { 10702848, "PENTAX", "Optio 750Z" ,1 },
7242 { 15980544, "AGFAPHOTO","DC-833m" ,1 },
7243 { 16098048, "SAMSUNG", "S85" ,1 },
7244 { 16215552, "SAMSUNG", "S85" ,1 },
7245 { 20487168, "SAMSUNG", "WB550" ,1 },
7246 { 24000000, "SAMSUNG", "WB550" ,1 },
7247 { 12582980, "Sinar", "" ,0 },
7248 { 33292868, "Sinar", "" ,0 },
7249 { 44390468, "Sinar", "" ,0 } };
7250 static const char *corp[] =
7251 { "Canon", "NIKON", "EPSON", "KODAK", "Kodak", "OLYMPUS", "PENTAX",
7252 "MINOLTA", "Minolta", "Konica", "CASIO", "Sinar", "Phase One",
7253 "SAMSUNG", "Mamiya", "MOTOROLA", "LEICA" };
7255 tiff_flip = flip = filters = -1; /* 0 is valid, so -1 is unknown */
7256 raw_height = raw_width = fuji_width = fuji_layout = cr2_slice[0] = 0;
7257 maximum = height = width = top_margin = left_margin = 0;
7258 cdesc[0] = desc[0] = artist[0] = make[0] = model[0] = model2[0] = 0;
7259 iso_speed = shutter = aperture = focal_len = unique_id = 0;
7261 memset (tiff_ifd, 0, sizeof tiff_ifd);
7262 memset (gpsdata, 0, sizeof gpsdata);
7263 memset (cblack, 0, sizeof cblack);
7264 memset (white, 0, sizeof white);
7265 memset (mask, 0, sizeof mask);
7266 thumb_offset = thumb_length = thumb_width = thumb_height = 0;
7267 load_raw = thumb_load_raw = 0;
7268 write_thumb = &CLASS jpeg_thumb;
7269 data_offset = meta_length = tiff_bps = tiff_compress = 0;
7270 kodak_cbpp = zero_after_ff = dng_version = load_flags = 0;
7271 timestamp = shot_order = tiff_samples = black = is_foveon = 0;
7272 mix_green = profile_length = data_error = zero_is_bad = 0;
7273 pixel_aspect = is_raw = raw_color = 1;
7274 tile_width = tile_length = 0;
7275 for (i=0; i < 4; i++) {
7276 cam_mul[i] = i == 1;
7278 FORC3 cmatrix[c][i] = 0;
7279 FORC3 rgb_cam[c][i] = c == i;
7282 for (i=0; i < 0x10000; i++) curve[i] = i;
7286 fseek (ifp, 0, SEEK_SET);
7287 fread (head, 1, 32, ifp);
7288 fseek (ifp, 0, SEEK_END);
7289 flen = fsize = ftell(ifp);
7290 if ((cp = (char *) memmem (head, 32, "MMMM", 4)) ||
7291 (cp = (char *) memmem (head, 32, "IIII", 4))) {
7292 parse_phase_one (cp-head);
7293 if (cp-head && parse_tiff(0)) apply_tiff();
7294 } else if (order == 0x4949 || order == 0x4d4d) {
7295 if (!memcmp (head+6,"HEAPCCDR",8)) {
7297 parse_ciff (hlen, flen - hlen);
7298 } else if (parse_tiff(0)) apply_tiff();
7299 } else if (!memcmp (head,"\xff\xd8\xff\xe1",4) &&
7300 !memcmp (head+6,"Exif",4)) {
7301 fseek (ifp, 4, SEEK_SET);
7302 data_offset = 4 + get2();
7303 fseek (ifp, data_offset, SEEK_SET);
7304 if (fgetc(ifp) != 0xff)
7307 } else if (!memcmp (head+25,"ARECOYK",7)) {
7308 strcpy (make, "Contax");
7309 strcpy (model,"N Digital");
7310 fseek (ifp, 33, SEEK_SET);
7312 fseek (ifp, 60, SEEK_SET);
7313 FORC4 cam_mul[c ^ (c >> 1)] = get4();
7314 } else if (!strcmp (head, "PXN")) {
7315 strcpy (make, "Logitech");
7316 strcpy (model,"Fotoman Pixtura");
7317 } else if (!strcmp (head, "qktk")) {
7318 strcpy (make, "Apple");
7319 strcpy (model,"QuickTake 100");
7320 load_raw = &CLASS quicktake_100_load_raw;
7321 } else if (!strcmp (head, "qktn")) {
7322 strcpy (make, "Apple");
7323 strcpy (model,"QuickTake 150");
7324 load_raw = &CLASS kodak_radc_load_raw;
7325 } else if (!memcmp (head,"FUJIFILM",8)) {
7326 fseek (ifp, 84, SEEK_SET);
7327 thumb_offset = get4();
7328 thumb_length = get4();
7329 fseek (ifp, 92, SEEK_SET);
7330 parse_fuji (get4());
7331 if (thumb_offset > 120) {
7332 fseek (ifp, 120, SEEK_SET);
7333 is_raw += (i = get4()) && 1;
7334 if (is_raw == 2 && shot_select)
7337 load_raw = &CLASS unpacked_load_raw;
7338 fseek (ifp, 100+28*(shot_select > 0), SEEK_SET);
7339 parse_tiff (data_offset = get4());
7340 parse_tiff (thumb_offset+12);
7342 } else if (!memcmp (head,"RIFF",4)) {
7343 fseek (ifp, 0, SEEK_SET);
7345 } else if (!memcmp (head,"\0\001\0\001\0@",6)) {
7346 fseek (ifp, 6, SEEK_SET);
7347 fread (make, 1, 8, ifp);
7348 fread (model, 1, 8, ifp);
7349 fread (model2, 1, 16, ifp);
7350 data_offset = get2();
7353 raw_height = get2();
7354 load_raw = &CLASS nokia_load_raw;
7355 filters = 0x61616161;
7356 } else if (!memcmp (head,"NOKIARAW",8)) {
7357 strcpy (make, "NOKIA");
7358 strcpy (model, "X2");
7360 fseek (ifp, 300, SEEK_SET);
7361 data_offset = get4();
7365 data_offset += i - width * 5 / 4 * height;
7366 load_raw = &CLASS nokia_load_raw;
7367 filters = 0x61616161;
7368 } else if (!memcmp (head,"ARRI",4)) {
7370 fseek (ifp, 20, SEEK_SET);
7373 strcpy (make, "ARRI");
7374 fseek (ifp, 668, SEEK_SET);
7375 fread (model, 1, 64, ifp);
7377 load_raw = &CLASS packed_load_raw;
7379 filters = 0x61616161;
7380 } else if (!memcmp (head+4,"RED1",4)) {
7381 strcpy (make, "RED");
7382 strcpy (model,"ONE");
7384 load_raw = &CLASS redcine_load_raw;
7385 gamma_curve (1/2.4, 12.92, 1, 4095);
7386 filters = 0x49494949;
7387 } else if (!memcmp (head,"DSC-Image",9))
7389 else if (!memcmp (head,"PWAD",4))
7391 else if (!memcmp (head,"\0MRM",4))
7393 else if (!memcmp (head,"FOVb",4))
7395 else if (!memcmp (head,"CI",2))
7398 for (zero_fsize=i=0; i < sizeof table / sizeof *table; i++)
7399 if (fsize == table[i].fsize) {
7400 strcpy (make, table[i].make );
7401 strcpy (model, table[i].model);
7402 if (table[i].withjpeg)
7403 parse_external_jpeg();
7405 if (zero_fsize) fsize = 0;
7406 if (make[0] == 0) parse_smal (0, flen);
7407 if (make[0] == 0) parse_jpeg (is_raw = 0);
7409 for (i=0; i < sizeof corp / sizeof *corp; i++)
7410 if (strstr (make, corp[i])) /* Simplify company names */
7411 strcpy (make, corp[i]);
7412 if (!strncmp (make,"KODAK",5) &&
7413 ((cp = strstr(model," DIGITAL CAMERA")) ||
7414 (cp = strstr(model," Digital Camera")) ||
7415 (cp = strstr(model,"FILE VERSION"))))
7417 cp = make + strlen(make); /* Remove trailing spaces */
7418 while (*--cp == ' ') *cp = 0;
7419 cp = model + strlen(model);
7420 while (*--cp == ' ') *cp = 0;
7421 i = strlen(make); /* Remove make from model */
7422 if (!strncasecmp (model, make, i) && model[i++] == ' ')
7423 memmove (model, model+i, 64-i);
7424 if (!strncmp (model,"FinePix ",8))
7425 strcpy (model, model+8);
7426 if (!strncmp (model,"Digital Camera ",15))
7427 strcpy (model, model+15);
7428 desc[511] = artist[63] = make[63] = model[63] = model2[63] = 0;
7429 if (!is_raw) goto notraw;
7431 if (!height) height = raw_height;
7432 if (!width) width = raw_width;
7433 if (height == 2624 && width == 3936) /* Pentax K10D and Samsung GX10 */
7434 { height = 2616; width = 3896; }
7435 if (height == 3136 && width == 4864) /* Pentax K20D and Samsung GX20 */
7436 { height = 3124; width = 4688; filters = 0x16161616; }
7437 if (width == 4352 && (!strcmp(model,"K-r") || !strcmp(model,"K-x")))
7438 { width = 4309; filters = 0x16161616; }
7439 if (width >= 4960 && !strncmp(model,"K-5",3))
7440 { left_margin = 10; width = 4950; filters = 0x16161616; }
7441 if (width == 4736 && !strcmp(model,"K-7"))
7442 { height = 3122; width = 4684; filters = 0x16161616; top_margin = 2; }
7443 if (width == 7424 && !strcmp(model,"645D"))
7444 { height = 5502; width = 7328; filters = 0x61616161; top_margin = 29;
7446 if (height == 3014 && width == 4096) /* Ricoh GX200 */
7449 if (filters == UINT_MAX) filters = 0;
7450 if (filters) is_raw = tiff_samples;
7451 else colors = tiff_samples;
7452 if (tiff_compress == 1)
7453 load_raw = &CLASS packed_dng_load_raw;
7454 if (tiff_compress == 7)
7455 load_raw = &CLASS lossless_dng_load_raw;
7458 if ((is_canon = !strcmp(make,"Canon")))
7459 load_raw = memcmp (head+6,"HEAPCCDR",8) ?
7460 &CLASS lossless_jpeg_load_raw : &CLASS canon_load_raw;
7461 if (!strcmp(make,"NIKON")) {
7463 load_raw = &CLASS packed_load_raw;
7464 if (model[0] == 'E')
7465 load_flags |= !data_offset << 2 | 2;
7467 if (!strcmp(make,"CASIO")) {
7468 load_raw = &CLASS packed_load_raw;
7472 /* Set parameters based on camera name (for non-DNG files). */
7475 if (height*2 < width) pixel_aspect = 0.5;
7476 if (height > width) pixel_aspect = 2;
7479 } else if (is_canon && tiff_bps == 15) {
7481 case 3344: width -= 66;
7482 case 3872: width -= 6;
7484 if (height > width) SWAP(height,width);
7486 load_raw = &CLASS canon_sraw_load_raw;
7487 } else if (!strcmp(model,"PowerShot 600")) {
7491 pixel_aspect = 607/628.0;
7493 filters = 0xe1e4e1e4;
7494 load_raw = &CLASS canon_600_load_raw;
7495 } else if (!strcmp(model,"PowerShot A5") ||
7496 !strcmp(model,"PowerShot A5 Zoom")) {
7500 pixel_aspect = 256/235.0;
7502 filters = 0x1e4e1e4e;
7504 } else if (!strcmp(model,"PowerShot A50")) {
7509 filters = 0x1b4e4b1e;
7511 } else if (!strcmp(model,"PowerShot Pro70")) {
7515 filters = 0x1e4b4e1b;
7517 } else if (!strcmp(model,"PowerShot SD300")) {
7525 } else if (!strcmp(model,"PowerShot A460")) {
7533 } else if (!strcmp(model,"PowerShot A530")) {
7541 } else if (!strcmp(model,"PowerShot A610")) {
7542 if (canon_s2is()) strcpy (model+10, "S2 IS");
7550 } else if (!strcmp(model,"PowerShot A620")) {
7558 } else if (!strcmp(model,"PowerShot A470")) {
7566 } else if (!strcmp(model,"PowerShot A720 IS")) {
7574 } else if (!strcmp(model,"PowerShot A630")) {
7582 } else if (!strcmp(model,"PowerShot A640")) {
7590 } else if (!strcmp(model,"PowerShot A650")) {
7598 } else if (!strcmp(model,"PowerShot S3 IS")) {
7607 load_raw = &CLASS packed_load_raw;
7609 if (raw_width > 1600) zero_is_bad = 1;
7610 } else if (!strcmp(model,"PowerShot SX110 IS")) {
7617 load_raw = &CLASS packed_load_raw;
7620 } else if (!strcmp(model,"PowerShot SX120 IS")) {
7627 filters = 0x49494949;
7628 load_raw = &CLASS packed_load_raw;
7631 } else if (!strcmp(model,"PowerShot SX20 IS")) {
7638 load_raw = &CLASS packed_load_raw;
7641 } else if (!strcmp(model,"PowerShot SX220 HS")) {
7646 mask[0][0] = top_margin = 16;
7647 mask[0][2] = top_margin + height;
7648 mask[0][3] = left_margin = 92;
7649 load_raw = &CLASS packed_load_raw;
7652 } else if (!strcmp(model,"PowerShot SX30 IS")) {
7659 filters = 0x16161616;
7660 load_raw = &CLASS packed_load_raw;
7663 } else if (!strcmp(model,"PowerShot Pro90 IS")) {
7666 filters = 0xb4b4b4b4;
7667 } else if (is_canon && raw_width == 2144) {
7672 if (!strcmp(model,"PowerShot G1")) {
7674 filters = 0xb4b4b4b4;
7676 } else if (is_canon && raw_width == 2224) {
7681 } else if (is_canon && raw_width == 2376) {
7686 } else if (is_canon && raw_width == 2672) {
7691 } else if (is_canon && raw_width == 3152) {
7696 if (unique_id == 0x80000170)
7697 adobe_coeff ("Canon","EOS 300D");
7698 } else if (is_canon && raw_width == 3160) {
7703 } else if (is_canon && raw_width == 3344) {
7708 } else if (!strcmp(model,"EOS D2000C")) {
7709 filters = 0x61616161;
7711 } else if (is_canon && raw_width == 3516) {
7714 if (unique_id == 0x80000189)
7715 adobe_coeff ("Canon","EOS 350D");
7717 } else if (is_canon && raw_width == 3596) {
7721 } else if (is_canon && raw_width == 3744) {
7726 if (unique_id > 0x2720000) {
7730 } else if (is_canon && raw_width == 3944) {
7735 } else if (is_canon && raw_width == 3948) {
7739 if (unique_id == 0x80000236)
7740 adobe_coeff ("Canon","EOS 400D");
7741 if (unique_id == 0x80000254)
7742 adobe_coeff ("Canon","EOS 1000D");
7744 } else if (is_canon && raw_width == 3984) {
7749 } else if (is_canon && raw_width == 4104) {
7754 } else if (is_canon && raw_width == 4152) {
7758 } else if (is_canon && raw_width == 4160) {
7763 } else if (is_canon && raw_width == 4176) {
7767 mask[0][0] = top_margin = 17;
7768 mask[0][2] = raw_height;
7770 filters = 0x49494949;
7771 } else if (is_canon && raw_width == 4312) {
7775 if (unique_id == 0x80000176)
7776 adobe_coeff ("Canon","EOS 450D");
7778 } else if (is_canon && raw_width == 4352) {
7781 if (unique_id == 0x80000288)
7782 adobe_coeff ("Canon","EOS 1100D");
7784 } else if (is_canon && raw_width == 4476) {
7788 } else if (is_canon && raw_width == 4480) {
7793 filters = 0x49494949;
7794 } else if (is_canon && raw_width == 4496) {
7799 } else if (is_canon && raw_width == 4832) {
7800 top_margin = unique_id == 0x80000261 ? 51:26;
7802 if (unique_id == 0x80000252)
7803 adobe_coeff ("Canon","EOS 500D");
7805 } else if (is_canon && raw_width == 5108) {
7809 } else if (is_canon && raw_width == 5120) {
7810 height -= top_margin = 45;
7813 } else if (is_canon && raw_width == 5280) {
7816 if (unique_id == 0x80000301)
7817 adobe_coeff ("Canon","EOS 650D");
7819 } else if (is_canon && raw_width == 5344) {
7822 if (unique_id == 0x80000269) {
7826 adobe_coeff ("Canon","EOS-1D X");
7828 if (unique_id == 0x80000270)
7829 adobe_coeff ("Canon","EOS 550D");
7830 if (unique_id == 0x80000286)
7831 adobe_coeff ("Canon","EOS 600D");
7833 } else if (is_canon && raw_width == 5360) {
7837 } else if (is_canon && raw_width == 5568) {
7841 } else if (is_canon && raw_width == 5712) {
7846 } else if (is_canon && raw_width == 5792) {
7850 height -= top_margin;
7851 width -= left_margin;
7852 } else if (is_canon && raw_width == 5920) {
7857 } else if (!strcmp(model,"D1")) {
7858 cam_mul[0] *= 256/527.0;
7859 cam_mul[2] *= 256/317.0;
7860 } else if (!strcmp(model,"D1X")) {
7863 } else if (!strcmp(model,"D40X") ||
7864 !strcmp(model,"D60") ||
7865 !strcmp(model,"D80") ||
7866 !strcmp(model,"D3000")) {
7869 } else if (!strcmp(model,"D3") ||
7870 !strcmp(model,"D3S") ||
7871 !strcmp(model,"D700")) {
7874 } else if (!strcmp(model,"D3100")) {
7877 } else if (!strcmp(model,"D5000") ||
7878 !strcmp(model,"D90")) {
7880 } else if (!strcmp(model,"D5100") ||
7881 !strcmp(model,"D7000")) {
7883 } else if (!strcmp(model,"D3200") ||
7884 !strcmp(model,"D600") ||
7885 !strcmp(model,"D800")) {
7887 } else if (!strcmp(model,"D4")) {
7890 } else if (!strncmp(model,"D40",3) ||
7891 !strncmp(model,"D50",3) ||
7892 !strncmp(model,"D70",3)) {
7894 } else if (!strcmp(model,"D100")) {
7896 raw_width = (width += 3) + 3;
7897 } else if (!strcmp(model,"D200")) {
7900 filters = 0x94949494;
7901 } else if (!strncmp(model,"D2H",3)) {
7904 } else if (!strncmp(model,"D2X",3)) {
7905 if (width == 3264) width -= 32;
7907 } else if (!strncmp(model,"D300",4)) {
7909 } else if (!strcmp(make,"NIKON") && raw_width == 4032) {
7910 adobe_coeff ("NIKON","COOLPIX P7700");
7911 } else if (!strncmp(model,"COOLPIX P",9)) {
7913 filters = 0x94949494;
7914 if (model[9] == '7' && iso_speed >= 400)
7916 } else if (!strncmp(model,"1 ",2)) {
7918 } else if (fsize == 1581060) {
7924 filters = 0x1e1e1e1e;
7926 pre_mul[0] = 1.2085;
7927 pre_mul[1] = 1.0943;
7928 pre_mul[3] = 1.1103;
7930 } else if (fsize == 2465792) {
7935 filters = 0x4b4b4b4b;
7936 adobe_coeff ("NIKON","E950");
7939 load_raw = &CLASS packed_load_raw;
7941 } else if (fsize == 4771840) {
7945 filters = 0xe1e1e1e1;
7946 load_raw = &CLASS packed_load_raw;
7948 if (!timestamp && nikon_e995())
7949 strcpy (model, "E995");
7950 if (strcmp(model,"E995")) {
7951 filters = 0xb4b4b4b4;
7957 } else if (!strcmp(model,"E2100")) {
7958 if (!timestamp && !nikon_e2100()) goto cp_e2500;
7962 } else if (!strcmp(model,"E2500")) {
7964 strcpy (model, "E2500");
7968 filters = 0x4b4b4b4b;
7969 } else if (fsize == 4775936) {
7972 load_raw = &CLASS packed_load_raw;
7974 if (!timestamp) nikon_3700();
7975 if (model[0] == 'E' && atoi(model+1) < 3700)
7976 filters = 0x49494949;
7977 if (!strcmp(model,"Optio 33WR")) {
7979 filters = 0x16161616;
7981 if (make[0] == 'O') {
7982 i = find_green (12, 32, 1188864, 3576832);
7983 c = find_green (12, 32, 2383920, 2387016);
7984 if (abs(i) < abs(c)) {
7988 if (i < 0) filters = 0x61616161;
7990 } else if (fsize == 5869568) {
7993 filters = 0x16161616;
7994 if (!timestamp && minolta_z2()) {
7995 strcpy (make, "Minolta");
7996 strcpy (model,"DiMAGE Z2");
7998 load_raw = &CLASS packed_load_raw;
7999 load_flags = 6 + 24*(make[0] == 'M');
8000 } else if (!strcmp(model,"E4500")) {
8004 filters = 0xb4b4b4b4;
8005 } else if (fsize == 7438336) {
8009 filters = 0xb4b4b4b4;
8010 } else if (fsize == 8998912) {
8014 load_raw = &CLASS packed_load_raw;
8016 } else if (!strcmp(make,"FUJIFILM")) {
8017 if (!strcmp(model+7,"S2Pro")) {
8018 strcpy (model,"S2Pro");
8022 } else if (load_raw != &CLASS packed_load_raw)
8023 maximum = (is_raw == 2 && shot_select) ? 0x2f00 : 0x3e00;
8024 top_margin = (raw_height - height) >> 2 << 1;
8025 left_margin = (raw_width - width ) >> 2 << 1;
8026 if (width == 2848) filters = 0x16161616;
8027 if (width == 3328) {
8031 if (width == 4952) {
8035 if (fuji_layout) raw_width *= is_raw;
8036 } else if (!strcmp(model,"RD175")) {
8040 filters = 0x61616161;
8041 load_raw = &CLASS minolta_rd175_load_raw;
8042 } else if (!strcmp(model,"KD-400Z")) {
8047 } else if (!strcmp(model,"KD-510Z")) {
8049 } else if (!strcasecmp(make,"MINOLTA")) {
8050 load_raw = &CLASS unpacked_load_raw;
8052 if (!strncmp(model,"DiMAGE A",8)) {
8053 if (!strcmp(model,"DiMAGE A200"))
8054 filters = 0x49494949;
8056 load_raw = &CLASS packed_load_raw;
8057 } else if (!strncmp(model,"ALPHA",5) ||
8058 !strncmp(model,"DYNAX",5) ||
8059 !strncmp(model,"MAXXUM",6)) {
8060 sprintf (model+20, "DYNAX %-10s", model+6+(model[0]=='M'));
8061 adobe_coeff (make, model+20);
8062 load_raw = &CLASS packed_load_raw;
8063 } else if (!strncmp(model,"DiMAGE G",8)) {
8064 if (model[8] == '4') {
8067 } else if (model[8] == '5') {
8072 } else if (model[8] == '6') {
8077 filters = 0x61616161;
8079 load_raw = &CLASS unpacked_load_raw;
8083 } else if (!strcmp(model,"*ist D")) {
8084 load_raw = &CLASS unpacked_load_raw;
8086 } else if (!strcmp(model,"*ist DS")) {
8088 } else if (!strcmp(model,"Optio S")) {
8089 if (fsize == 3178560) {
8092 load_raw = &CLASS eight_bit_load_raw;
8099 load_raw = &CLASS packed_load_raw;
8102 } else if (fsize == 6114240) {
8106 load_raw = &CLASS packed_load_raw;
8108 } else if (!strcmp(model,"Optio 750Z")) {
8111 load_raw = &CLASS packed_load_raw;
8113 } else if (!strcmp(model,"DC-833m")) {
8117 filters = 0x61616161;
8118 load_raw = &CLASS unpacked_load_raw;
8120 } else if (!strncmp(model,"S85",3)) {
8123 raw_width = fsize/height/2;
8125 load_raw = &CLASS unpacked_load_raw;
8126 } else if (!strcmp(make,"SAMSUNG") && raw_width == 4704) {
8127 height -= top_margin = 8;
8128 width -= 2 * (left_margin = 8);
8130 } else if (!strcmp(make,"SAMSUNG") && raw_width == 5632) {
8134 width = 5574 - (left_margin = 32 + tiff_bps);
8135 if (tiff_bps == 12) load_flags = 80;
8136 } else if (!strcmp(model,"EX1")) {
8140 if ((width -= 6) > 3682) {
8145 } else if (!strcmp(model,"WB2000")) {
8149 if ((width -= 10) > 3718) {
8154 } else if (fsize == 20487168) {
8158 } else if (fsize == 24000000) {
8162 strcpy (model, "WB550");
8164 load_raw = &CLASS unpacked_load_raw;
8167 } else if (!strcmp(model,"EX2F")) {
8172 filters = 0x49494949;
8173 load_raw = &CLASS unpacked_load_raw;
8174 } else if (!strcmp(model,"STV680 VGA")) {
8177 load_raw = &CLASS eight_bit_load_raw;
8179 filters = 0x16161616;
8181 } else if (!strcmp(model,"N95")) {
8182 height = raw_height - (top_margin = 2);
8183 } else if (!strcmp(model,"531C")) {
8186 load_raw = &CLASS unpacked_load_raw;
8187 filters = 0x49494949;
8188 } else if (!strcmp(model,"640x480")) {
8191 load_raw = &CLASS eight_bit_load_raw;
8192 gamma_curve (0.45, 4.5, 1, 255);
8193 } else if (!strcmp(model,"F-080C")) {
8196 load_raw = &CLASS eight_bit_load_raw;
8197 } else if (!strcmp(model,"F-145C")) {
8200 load_raw = &CLASS eight_bit_load_raw;
8201 } else if (!strcmp(model,"F-201C")) {
8204 load_raw = &CLASS eight_bit_load_raw;
8205 } else if (!strcmp(model,"F-510C")) {
8208 load_raw = fsize < 7500000 ?
8209 &CLASS eight_bit_load_raw : &CLASS unpacked_load_raw;
8210 data_offset = fsize - width*height*(fsize >> 22);
8212 } else if (!strcmp(model,"F-810C")) {
8215 load_raw = &CLASS unpacked_load_raw;
8217 } else if (!strcmp(model,"XCD-SX910CR")) {
8221 filters = 0x49494949;
8223 load_raw = fsize < 2000000 ?
8224 &CLASS eight_bit_load_raw : &CLASS unpacked_load_raw;
8225 } else if (!strcmp(model,"2010")) {
8229 filters = 0x16161616;
8232 load_raw = &CLASS unpacked_load_raw;
8233 } else if (!strcmp(model,"A782")) {
8236 filters = 0x61616161;
8237 load_raw = fsize < 10000000 ?
8238 &CLASS eight_bit_load_raw : &CLASS unpacked_load_raw;
8240 } else if (!strcmp(model,"3320AF")) {
8242 raw_width = width = 2048;
8243 filters = 0x61616161;
8244 load_raw = &CLASS unpacked_load_raw;
8246 fseek (ifp, 0x300000, SEEK_SET);
8247 if ((order = guess_byte_order(0x10000)) == 0x4d4d) {
8248 height -= (top_margin = 16);
8249 width -= (left_margin = 28);
8251 strcpy (make, "ISG");
8254 } else if (!strcmp(make,"Hasselblad")) {
8255 if (load_raw == &CLASS lossless_jpeg_load_raw)
8256 load_raw = &CLASS hasselblad_load_raw;
8257 if (raw_width == 7262) {
8262 filters = 0x61616161;
8263 } else if (raw_width == 7410) {
8268 filters = 0x61616161;
8269 } else if (raw_width == 9044) {
8274 black += load_flags = 256;
8276 } else if (raw_width == 4090) {
8277 strcpy (model, "V96C");
8278 height -= (top_margin = 6);
8279 width -= (left_margin = 3) + 7;
8280 filters = 0x61616161;
8282 } else if (!strcmp(make,"Sinar")) {
8283 if (!memcmp(head,"8BPS",4)) {
8284 fseek (ifp, 14, SEEK_SET);
8287 filters = 0x61616161;
8290 if (!load_raw) load_raw = &CLASS unpacked_load_raw;
8292 } else if (!strcmp(make,"Leaf")) {
8294 fseek (ifp, data_offset, SEEK_SET);
8295 if (ljpeg_start (&jh, 1) && jh.bits == 15)
8297 if (tiff_samples > 1) filters = 0;
8298 if (tiff_samples > 1 || tile_length < raw_height) {
8299 load_raw = &CLASS leaf_hdr_load_raw;
8300 raw_width = tile_width;
8302 if ((width | height) == 2048) {
8303 if (tiff_samples == 1) {
8305 strcpy (cdesc, "RBTG");
8306 strcpy (model, "CatchLight");
8307 top_margin = 8; left_margin = 18; height = 2032; width = 2016;
8309 strcpy (model, "DCB2");
8310 top_margin = 10; left_margin = 16; height = 2028; width = 2022;
8312 } else if (width+height == 3144+2060) {
8313 if (!model[0]) strcpy (model, "Cantare");
8314 if (width > height) {
8315 top_margin = 6; left_margin = 32; height = 2048; width = 3072;
8316 filters = 0x61616161;
8318 left_margin = 6; top_margin = 32; width = 2048; height = 3072;
8319 filters = 0x16161616;
8321 if (!cam_mul[0] || model[0] == 'V') filters = 0;
8322 else is_raw = tiff_samples;
8323 } else if (width == 2116) {
8324 strcpy (model, "Valeo 6");
8325 height -= 2 * (top_margin = 30);
8326 width -= 2 * (left_margin = 55);
8327 filters = 0x49494949;
8328 } else if (width == 3171) {
8329 strcpy (model, "Valeo 6");
8330 height -= 2 * (top_margin = 24);
8331 width -= 2 * (left_margin = 24);
8332 filters = 0x16161616;
8334 } else if (!strcmp(make,"LEICA") || !strcmp(make,"Panasonic")) {
8335 if ((flen - data_offset) / (raw_width*8/7) == raw_height)
8336 load_raw = &CLASS panasonic_load_raw;
8338 load_raw = &CLASS unpacked_load_raw;
8342 if ((height += 12) > raw_height) height = raw_height;
8343 for (i=0; i < sizeof pana / sizeof *pana; i++)
8344 if (raw_width == pana[i][0] && raw_height == pana[i][1]) {
8345 left_margin = pana[i][2];
8346 top_margin = pana[i][3];
8347 width += pana[i][4];
8348 height += pana[i][5];
8350 filters = 0x01010101 * (uchar) "\x94\x61\x49\x16"
8351 [((filters-1) ^ (left_margin & 1) ^ (top_margin << 1)) & 3];
8352 } else if (!strcmp(model,"C770UZ")) {
8355 filters = 0x16161616;
8356 load_raw = &CLASS packed_load_raw;
8358 } else if (!strcmp(make,"OLYMPUS")) {
8359 height += height & 1;
8361 if (width == 4100) width -= 4;
8362 if (width == 4080) width -= 24;
8363 if (load_raw == &CLASS unpacked_load_raw)
8366 if (!strcmp(model,"E-300") ||
8367 !strcmp(model,"E-500")) {
8369 if (load_raw == &CLASS unpacked_load_raw) {
8371 memset (cblack, 0, sizeof cblack);
8373 } else if (!strcmp(model,"E-330")) {
8375 if (load_raw == &CLASS unpacked_load_raw)
8377 } else if (!strcmp(model,"SP550UZ")) {
8378 thumb_length = flen - (thumb_offset = 0xa39800);
8381 } else if (!strcmp(model,"XZ-2")) {
8382 load_raw = &CLASS packed_load_raw;
8385 } else if (!strcmp(model,"N Digital")) {
8388 filters = 0x61616161;
8389 data_offset = 0x1a00;
8390 load_raw = &CLASS packed_load_raw;
8391 } else if (!strcmp(model,"DSC-F828")) {
8395 data_offset = 862144;
8396 load_raw = &CLASS sony_load_raw;
8397 filters = 0x9c9c9c9c;
8399 strcpy (cdesc, "RGBE");
8400 } else if (!strcmp(model,"DSC-V3")) {
8404 data_offset = 787392;
8405 load_raw = &CLASS sony_load_raw;
8406 } else if (!strcmp(make,"SONY") && raw_width == 3984) {
8407 adobe_coeff ("SONY","DSC-R1");
8410 } else if (!strcmp(make,"SONY") && raw_width == 5504) {
8412 } else if (!strcmp(make,"SONY") && raw_width == 6048) {
8414 } else if (!strcmp(model,"DSLR-A100")) {
8415 if (width == 3880) {
8417 width = ++raw_width;
8422 filters = 0x61616161;
8423 } else if (!strcmp(model,"DSLR-A350")) {
8425 } else if (!strcmp(model,"PIXL")) {
8426 height -= top_margin = 4;
8427 width -= left_margin = 32;
8428 gamma_curve (0, 7, 1, 255);
8429 } else if (!strcmp(model,"C603v")) {
8432 if (fsize < 614400 || find_green (16, 16, 3840, 5120) < 25) goto c603v;
8433 strcpy (model,"KAI-0340");
8437 load_raw = &CLASS unpacked_load_raw;
8438 } else if (!strcmp(model,"C603y")) {
8443 load_raw = &CLASS kodak_yrgb_load_raw;
8444 gamma_curve (0, 3.875, 1, 255);
8445 } else if (!strcmp(model,"C603")) {
8446 raw_height = height = 2152;
8447 raw_width = width = 2864;
8449 } else if (!strcmp(model,"C330")) {
8458 if ((data_offset = fsize - raw_height*raw_width)) {
8459 fseek (ifp, 168, SEEK_SET);
8460 read_shorts (curve, 256);
8461 } else gamma_curve (0, 3.875, 1, 255);
8462 load_raw = &CLASS eight_bit_load_raw;
8463 } else if (!strncasecmp(model,"EasyShare",9)) {
8464 data_offset = data_offset < 0x15000 ? 0x15000 : 0x17000;
8465 load_raw = &CLASS packed_load_raw;
8466 } else if (!strcasecmp(make,"KODAK")) {
8467 if (filters == UINT_MAX) filters = 0x61616161;
8468 if (!strncmp(model,"NC2000",6)) {
8471 } else if (!strcmp(model,"EOSDCS3B")) {
8474 } else if (!strcmp(model,"EOSDCS1")) {
8477 } else if (!strcmp(model,"DCS420")) {
8480 } else if (!strncmp(model,"DCS460 ",7)) {
8484 } else if (!strcmp(model,"DCS460A")) {
8489 } else if (!strcmp(model,"DCS660M")) {
8493 } else if (!strcmp(model,"DCS760M")) {
8497 if (!strcmp(model+4,"20X"))
8498 strcpy (cdesc, "MYCY");
8499 if (strstr(model,"DC25")) {
8500 strcpy (model, "DC25");
8501 data_offset = 15424;
8503 if (!strncmp(model,"DC2",3)) {
8504 raw_height = height = 242;
8505 if (flen < 100000) {
8506 raw_width = 256; width = 249;
8507 pixel_aspect = (4.0*height) / (3.0*width);
8509 raw_width = 512; width = 501;
8510 pixel_aspect = (493.0*height) / (373.0*width);
8512 data_offset += raw_width + 1;
8514 filters = 0x8d8d8d8d;
8519 load_raw = &CLASS eight_bit_load_raw;
8520 } else if (!strcmp(model,"40")) {
8521 strcpy (model, "DC40");
8525 load_raw = &CLASS kodak_radc_load_raw;
8526 } else if (strstr(model,"DC50")) {
8527 strcpy (model, "DC50");
8530 data_offset = 19712;
8531 load_raw = &CLASS kodak_radc_load_raw;
8532 } else if (strstr(model,"DC120")) {
8533 strcpy (model, "DC120");
8536 pixel_aspect = height/0.75/width;
8537 load_raw = tiff_compress == 7 ?
8538 &CLASS kodak_jpeg_load_raw : &CLASS kodak_dc120_load_raw;
8539 } else if (!strcmp(model,"DCS200")) {
8542 thumb_offset = 6144;
8544 write_thumb = &CLASS layer_thumb;
8547 data_offset = 79872;
8548 load_raw = &CLASS eight_bit_load_raw;
8551 } else if (!strcmp(model,"Fotoman Pixtura")) {
8555 load_raw = &CLASS kodak_radc_load_raw;
8556 filters = 0x61616161;
8558 } else if (!strncmp(model,"QuickTake",9)) {
8559 if (head[5]) strcpy (model+10, "200");
8560 fseek (ifp, 544, SEEK_SET);
8563 data_offset = (get4(),get2()) == 30 ? 738:736;
8564 if (height > width) {
8566 fseek (ifp, data_offset-6, SEEK_SET);
8567 flip = ~get2() & 3 ? 5:6;
8569 filters = 0x61616161;
8570 } else if (!strcmp(make,"Rollei") && !load_raw) {
8571 switch (raw_width) {
8584 filters = 0x16161616;
8585 load_raw = &CLASS rollei_load_raw;
8586 } else if (!strcmp(model,"PC-CAM 600")) {
8588 data_offset = width = 1024;
8589 filters = 0x49494949;
8590 load_raw = &CLASS eight_bit_load_raw;
8591 } else if (!strcmp(model,"QV-2000UX")) {
8594 data_offset = width * 2;
8595 load_raw = &CLASS eight_bit_load_raw;
8596 } else if (fsize == 3217760) {
8600 load_raw = &CLASS eight_bit_load_raw;
8601 } else if (!strcmp(model,"QV-4000")) {
8604 load_raw = &CLASS unpacked_load_raw;
8606 } else if (!strcmp(model,"QV-5700")) {
8611 } else if (!strcmp(model,"QV-R41")) {
8616 } else if (!strcmp(model,"QV-R51")) {
8620 } else if (!strcmp(model,"EX-S20")) {
8625 } else if (!strcmp(model,"EX-S100")) {
8629 } else if (!strcmp(model,"EX-Z50")) {
8633 } else if (!strcmp(model,"EX-Z500")) {
8637 filters = 0x16161616;
8638 } else if (!strcmp(model,"EX-Z55")) {
8642 } else if (!strcmp(model,"EX-Z60")) {
8646 filters = 0x16161616;
8648 } else if (!strcmp(model,"EX-Z75")) {
8653 } else if (!strcmp(model,"EX-Z750")) {
8658 } else if (!strcmp(model,"EX-Z850")) {
8663 } else if (!strcmp(model,"EX-Z8")) {
8669 } else if (fsize == 15499264) { /* EX-Z1050 or EX-Z1080 */
8673 } else if (!strcmp(model,"EX-ZR100")) {
8678 } else if (!strcmp(model,"EX-P505")) {
8683 } else if (fsize == 9313536) { /* EX-P600 or QV-R61 */
8687 } else if (!strcmp(model,"EX-P700")) {
8693 sprintf (model, "%dx%d", width, height);
8694 if (filters == UINT_MAX) filters = 0x94949494;
8695 if (raw_color) adobe_coeff (make, model);
8696 if (load_raw == &CLASS kodak_radc_load_raw)
8697 if (raw_color) adobe_coeff ("Apple","Quicktake");
8698 if (thumb_offset && !thumb_height) {
8699 fseek (ifp, thumb_offset, SEEK_SET);
8700 if (ljpeg_start (&jh, 1)) {
8701 thumb_width = jh.wide;
8702 thumb_height = jh.high;
8707 fuji_width = width >> !fuji_layout;
8708 if (~fuji_width & 1) filters = 0x49494949;
8709 width = (height >> fuji_layout) + fuji_width;
8713 if (raw_height < height) raw_height = height;
8714 if (raw_width < width ) raw_width = width;
8716 if (!tiff_bps) tiff_bps = 12;
8717 if (!maximum) maximum = (1 << tiff_bps) - 1;
8718 if (!load_raw || height < 22) is_raw = 0;
8720 if (load_raw == &CLASS redcine_load_raw) {
8721 fprintf (stderr,_("%s: You must link dcraw with %s!!\n"),
8722 ifname, "libjasper");
8727 if (load_raw == &CLASS kodak_jpeg_load_raw ||
8728 load_raw == &CLASS lossy_dng_load_raw) {
8729 fprintf (stderr,_("%s: You must link dcraw with %s!!\n"),
8735 strcpy (cdesc, colors == 3 ? "RGBG":"GMCY");
8736 if (!raw_height) raw_height = height;
8737 if (!raw_width ) raw_width = width;
8738 if (filters && colors == 3)
8739 filters |= ((filters >> 2 & 0x22222222) |
8740 (filters << 2 & 0x88888888)) & filters << 1;
8742 if (flip == -1) flip = tiff_flip;
8743 if (flip == -1) flip = 0;
8750 sprintf(dcraw_info, "%d %d", height, width);
8752 sprintf(dcraw_info, "%d %d", width, height);
8756 void CLASS apply_profile (const char *input, const char *output)
8759 cmsHPROFILE hInProfile=0, hOutProfile=0;
8760 cmsHTRANSFORM hTransform;
8764 cmsErrorAction (LCMS_ERROR_SHOW);
8765 if (strcmp (input, "embed"))
8766 hInProfile = cmsOpenProfileFromFile (input, "r");
8767 else if (profile_length) {
8768 prof = (char *) malloc (profile_length);
8769 merror (prof, "apply_profile()");
8770 fseek (ifp, profile_offset, SEEK_SET);
8771 fread (prof, 1, profile_length, ifp);
8772 hInProfile = cmsOpenProfileFromMem (prof, profile_length);
8775 fprintf (stderr,_("%s has no embedded profile.\n"), ifname);
8776 if (!hInProfile) return;
8778 hOutProfile = cmsCreate_sRGBProfile();
8779 else if ((fp = fopen (output, "rb"))) {
8780 fread (&size, 4, 1, fp);
8781 fseek (fp, 0, SEEK_SET);
8782 oprof = (unsigned *) malloc (size = ntohl(size));
8783 merror (oprof, "apply_profile()");
8784 fread (oprof, 1, size, fp);
8786 if (!(hOutProfile = cmsOpenProfileFromMem (oprof, size))) {
8791 fprintf (stderr,_("Cannot open file %s!\n"), output);
8792 if (!hOutProfile) goto quit;
8794 fprintf (stderr,_("Applying color profile...\n"));
8795 hTransform = cmsCreateTransform (hInProfile, TYPE_RGBA_16,
8796 hOutProfile, TYPE_RGBA_16, INTENT_PERCEPTUAL, 0);
8797 cmsDoTransform (hTransform, image, image, width*height);
8798 raw_color = 1; /* Don't use rgb_cam with a profile */
8799 cmsDeleteTransform (hTransform);
8800 cmsCloseProfile (hOutProfile);
8802 cmsCloseProfile (hInProfile);
8806 void CLASS convert_to_rgb()
8808 int row, col, c, i, j, k;
8810 float out[3], out_cam[3][4];
8811 double num, inverse[3][3];
8812 static const double xyzd50_srgb[3][3] =
8813 { { 0.436083, 0.385083, 0.143055 },
8814 { 0.222507, 0.716888, 0.060608 },
8815 { 0.013930, 0.097097, 0.714022 } };
8816 static const double rgb_rgb[3][3] =
8817 { { 1,0,0 }, { 0,1,0 }, { 0,0,1 } };
8818 static const double adobe_rgb[3][3] =
8819 { { 0.715146, 0.284856, 0.000000 },
8820 { 0.000000, 1.000000, 0.000000 },
8821 { 0.000000, 0.041166, 0.958839 } };
8822 static const double wide_rgb[3][3] =
8823 { { 0.593087, 0.404710, 0.002206 },
8824 { 0.095413, 0.843149, 0.061439 },
8825 { 0.011621, 0.069091, 0.919288 } };
8826 static const double prophoto_rgb[3][3] =
8827 { { 0.529317, 0.330092, 0.140588 },
8828 { 0.098368, 0.873465, 0.028169 },
8829 { 0.016879, 0.117663, 0.865457 } };
8830 static const double (*out_rgb[])[3] =
8831 { rgb_rgb, adobe_rgb, wide_rgb, prophoto_rgb, xyz_rgb };
8832 static const char *name[] =
8833 { "sRGB", "Adobe RGB (1998)", "WideGamut D65", "ProPhoto D65", "XYZ" };
8834 static const unsigned phead[] =
8835 { 1024, 0, 0x2100000, 0x6d6e7472, 0x52474220, 0x58595a20, 0, 0, 0,
8836 0x61637370, 0, 0, 0x6e6f6e65, 0, 0, 0, 0, 0xf6d6, 0x10000, 0xd32d };
8838 { 10, 0x63707274, 0, 36, /* cprt */
8839 0x64657363, 0, 40, /* desc */
8840 0x77747074, 0, 20, /* wtpt */
8841 0x626b7074, 0, 20, /* bkpt */
8842 0x72545243, 0, 14, /* rTRC */
8843 0x67545243, 0, 14, /* gTRC */
8844 0x62545243, 0, 14, /* bTRC */
8845 0x7258595a, 0, 20, /* rXYZ */
8846 0x6758595a, 0, 20, /* gXYZ */
8847 0x6258595a, 0, 20 }; /* bXYZ */
8848 static const unsigned pwhite[] = { 0xf351, 0x10000, 0x116cc };
8849 unsigned pcurve[] = { 0x63757276, 0, 1, 0x1000000 };
8851 gamma_curve (gamm[0], gamm[1], 0, 0);
8852 memcpy (out_cam, rgb_cam, sizeof out_cam);
8853 raw_color |= colors == 1 || document_mode ||
8854 output_color < 1 || output_color > 5;
8856 oprof = (unsigned *) calloc (phead[0], 1);
8857 merror (oprof, "convert_to_rgb()");
8858 memcpy (oprof, phead, sizeof phead);
8859 if (output_color == 5) oprof[4] = oprof[5];
8860 oprof[0] = 132 + 12*pbody[0];
8861 for (i=0; i < pbody[0]; i++) {
8862 oprof[oprof[0]/4] = i ? (i > 1 ? 0x58595a20 : 0x64657363) : 0x74657874;
8863 pbody[i*3+2] = oprof[0];
8864 oprof[0] += (pbody[i*3+3] + 3) & -4;
8866 memcpy (oprof+32, pbody, sizeof pbody);
8867 oprof[pbody[5]/4+2] = strlen(name[output_color-1]) + 1;
8868 memcpy ((char *)oprof+pbody[8]+8, pwhite, sizeof pwhite);
8869 pcurve[3] = (short)(256/gamm[5]+0.5) << 16;
8870 for (i=4; i < 7; i++)
8871 memcpy ((char *)oprof+pbody[i*3+2], pcurve, sizeof pcurve);
8872 pseudoinverse ((double (*)[3]) out_rgb[output_color-1], inverse, 3);
8873 for (i=0; i < 3; i++)
8874 for (j=0; j < 3; j++) {
8875 for (num = k=0; k < 3; k++)
8876 num += xyzd50_srgb[i][k] * inverse[j][k];
8877 oprof[pbody[j*3+23]/4+i+2] = num * 0x10000 + 0.5;
8879 for (i=0; i < phead[0]/4; i++)
8880 oprof[i] = htonl(oprof[i]);
8881 strcpy ((char *)oprof+pbody[2]+8, "auto-generated by dcraw");
8882 strcpy ((char *)oprof+pbody[5]+12, name[output_color-1]);
8883 for (i=0; i < 3; i++)
8884 for (j=0; j < colors; j++)
8885 for (out_cam[i][j] = k=0; k < 3; k++)
8886 out_cam[i][j] += out_rgb[output_color-1][i][k] * rgb_cam[k][j];
8889 fprintf (stderr, raw_color ? _("Building histograms...\n") :
8890 _("Converting to %s colorspace...\n"), name[output_color-1]);
8892 memset (histogram, 0, sizeof histogram);
8893 for (img=image[0], row=0; row < height; row++)
8894 for (col=0; col < width; col++, img+=4) {
8896 out[0] = out[1] = out[2] = 0;
8898 out[0] += out_cam[0][c] * img[c];
8899 out[1] += out_cam[1][c] * img[c];
8900 out[2] += out_cam[2][c] * img[c];
8902 FORC3 img[c] = CLIP((int) out[c]);
8904 else if (document_mode)
8905 img[0] = img[fcol(row,col)];
8906 FORCC histogram[c][img[c] >> 3]++;
8908 if (colors == 4 && output_color) colors = 3;
8909 if (document_mode && filters) colors = 1;
8915 // Export color matrix to Cinelerra.
8916 // It can't be applied before interpolation.
8918 for(i = 0; i < 3; i++)
8920 for(j = 0; j < 3; j++)
8921 dcraw_matrix[k++] = rgb_cam[i][j];
8925 void CLASS fuji_rotate()
8931 ushort wide, high, (*img)[4], (*pix)[4];
8933 if (!fuji_width) return;
8935 fprintf (stderr,_("Rotating image 45 degrees...\n"));
8936 fuji_width = (fuji_width - 1 + shrink) >> shrink;
8938 wide = fuji_width / step;
8939 high = (height - fuji_width) / step;
8940 img = (ushort (*)[4]) calloc (wide*high, sizeof *img);
8941 merror (img, "fuji_rotate()");
8943 for (row=0; row < high; row++)
8944 for (col=0; col < wide; col++) {
8945 ur = r = fuji_width + (row-col)*step;
8946 uc = c = (row+col)*step;
8947 if (ur > height-2 || uc > width-2) continue;
8950 pix = image + ur*width + uc;
8951 for (i=0; i < colors; i++)
8952 img[row*wide+col][i] =
8953 (pix[ 0][i]*(1-fc) + pix[ 1][i]*fc) * (1-fr) +
8954 (pix[width][i]*(1-fc) + pix[width+1][i]*fc) * fr;
8963 void CLASS stretch()
8965 ushort newdim, (*img)[4], *pix0, *pix1;
8969 if (pixel_aspect == 1) return;
8970 if (verbose) fprintf (stderr,_("Stretching the image...\n"));
8971 if (pixel_aspect < 1) {
8972 newdim = height / pixel_aspect + 0.5;
8973 img = (ushort (*)[4]) calloc (width*newdim, sizeof *img);
8974 merror (img, "stretch()");
8975 for (rc=row=0; row < newdim; row++, rc+=pixel_aspect) {
8976 frac = rc - (c = rc);
8977 pix0 = pix1 = image[c*width];
8978 if (c+1 < height) pix1 += width*4;
8979 for (col=0; col < width; col++, pix0+=4, pix1+=4)
8980 FORCC img[row*width+col][c] = pix0[c]*(1-frac) + pix1[c]*frac + 0.5;
8984 newdim = width * pixel_aspect + 0.5;
8985 img = (ushort (*)[4]) calloc (height*newdim, sizeof *img);
8986 merror (img, "stretch()");
8987 for (rc=col=0; col < newdim; col++, rc+=1/pixel_aspect) {
8988 frac = rc - (c = rc);
8989 pix0 = pix1 = image[c];
8990 if (c+1 < width) pix1 += 4;
8991 for (row=0; row < height; row++, pix0+=width*4, pix1+=width*4)
8992 FORCC img[row*newdim+col][c] = pix0[c]*(1-frac) + pix1[c]*frac + 0.5;
9000 int CLASS flip_index (int row, int col)
9002 if (flip & 4) SWAP(row,col);
9003 if (flip & 2) row = iheight - 1 - row;
9004 if (flip & 1) col = iwidth - 1 - col;
9005 return row * iwidth + col;
9011 union { char c[4]; short s[2]; int i; } val;
9015 ushort order, magic;
9018 struct tiff_tag tag[23];
9021 struct tiff_tag exif[4];
9023 struct tiff_tag gpst[10];
9027 char desc[512], make[64], model[64], soft[32], date[20], artist[64];
9030 void CLASS tiff_set (ushort *ntag,
9031 ushort tag, ushort type, int count, int val)
9033 struct tiff_tag *tt;
9036 tt = (struct tiff_tag *)(ntag+1) + (*ntag)++;
9040 if (type < 3 && count <= 4)
9041 FORC(4) tt->val.c[c] = val >> (c << 3);
9042 else if (type == 3 && count <= 2)
9043 FORC(2) tt->val.s[c] = val >> (c << 4);
9044 else tt->val.i = val;
9047 #define TOFF(ptr) ((char *)(&(ptr)) - (char *)th)
9049 void CLASS tiff_head (struct tiff_hdr *th, int full)
9054 memset (th, 0, sizeof *th);
9055 th->order = htonl(0x4d4d4949) >> 16;
9059 tiff_set (&th->ntag, 254, 4, 1, 0);
9060 tiff_set (&th->ntag, 256, 4, 1, width);
9061 tiff_set (&th->ntag, 257, 4, 1, height);
9062 tiff_set (&th->ntag, 258, 3, colors, output_bps);
9064 th->tag[th->ntag-1].val.i = TOFF(th->bps);
9065 FORC4 th->bps[c] = output_bps;
9066 tiff_set (&th->ntag, 259, 3, 1, 1);
9067 tiff_set (&th->ntag, 262, 3, 1, 1 + (colors > 1));
9069 tiff_set (&th->ntag, 270, 2, 512, TOFF(th->desc));
9070 tiff_set (&th->ntag, 271, 2, 64, TOFF(th->make));
9071 tiff_set (&th->ntag, 272, 2, 64, TOFF(th->model));
9073 if (oprof) psize = ntohl(oprof[0]);
9074 tiff_set (&th->ntag, 273, 4, 1, sizeof *th + psize);
9075 tiff_set (&th->ntag, 277, 3, 1, colors);
9076 tiff_set (&th->ntag, 278, 4, 1, height);
9077 tiff_set (&th->ntag, 279, 4, 1, height*width*colors*output_bps/8);
9079 tiff_set (&th->ntag, 274, 3, 1, "12435867"[flip]-'0');
9080 tiff_set (&th->ntag, 282, 5, 1, TOFF(th->rat[0]));
9081 tiff_set (&th->ntag, 283, 5, 1, TOFF(th->rat[2]));
9082 tiff_set (&th->ntag, 284, 3, 1, 1);
9083 tiff_set (&th->ntag, 296, 3, 1, 2);
9084 tiff_set (&th->ntag, 305, 2, 32, TOFF(th->soft));
9085 tiff_set (&th->ntag, 306, 2, 20, TOFF(th->date));
9086 tiff_set (&th->ntag, 315, 2, 64, TOFF(th->artist));
9087 tiff_set (&th->ntag, 34665, 4, 1, TOFF(th->nexif));
9088 if (psize) tiff_set (&th->ntag, 34675, 7, psize, sizeof *th);
9089 tiff_set (&th->nexif, 33434, 5, 1, TOFF(th->rat[4]));
9090 tiff_set (&th->nexif, 33437, 5, 1, TOFF(th->rat[6]));
9091 tiff_set (&th->nexif, 34855, 3, 1, iso_speed);
9092 tiff_set (&th->nexif, 37386, 5, 1, TOFF(th->rat[8]));
9094 tiff_set (&th->ntag, 34853, 4, 1, TOFF(th->ngps));
9095 tiff_set (&th->ngps, 0, 1, 4, 0x202);
9096 tiff_set (&th->ngps, 1, 2, 2, gpsdata[29]);
9097 tiff_set (&th->ngps, 2, 5, 3, TOFF(th->gps[0]));
9098 tiff_set (&th->ngps, 3, 2, 2, gpsdata[30]);
9099 tiff_set (&th->ngps, 4, 5, 3, TOFF(th->gps[6]));
9100 tiff_set (&th->ngps, 5, 1, 1, gpsdata[31]);
9101 tiff_set (&th->ngps, 6, 5, 1, TOFF(th->gps[18]));
9102 tiff_set (&th->ngps, 7, 5, 3, TOFF(th->gps[12]));
9103 tiff_set (&th->ngps, 18, 2, 12, TOFF(th->gps[20]));
9104 tiff_set (&th->ngps, 29, 2, 12, TOFF(th->gps[23]));
9105 memcpy (th->gps, gpsdata, sizeof th->gps);
9107 th->rat[0] = th->rat[2] = 300;
9108 th->rat[1] = th->rat[3] = 1;
9109 FORC(6) th->rat[4+c] = 1000000;
9110 th->rat[4] *= shutter;
9111 th->rat[6] *= aperture;
9112 th->rat[8] *= focal_len;
9113 strncpy (th->desc, desc, 512);
9114 strncpy (th->make, make, 64);
9115 strncpy (th->model, model, 64);
9116 strcpy (th->soft, "dcraw v"DCRAW_VERSION);
9117 t = localtime (×tamp);
9118 sprintf (th->date, "%04d:%02d:%02d %02d:%02d:%02d",
9119 t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);
9120 strncpy (th->artist, artist, 64);
9123 void CLASS jpeg_thumb()
9129 thumb = (char *) malloc (thumb_length);
9130 merror (thumb, "jpeg_thumb()");
9131 fread (thumb, 1, thumb_length, ifp);
9134 if (strcmp (thumb+6, "Exif")) {
9135 memcpy (exif, "\xff\xe1 Exif\0\0", 10);
9136 exif[1] = htons (8 + sizeof th);
9137 fwrite (exif, 1, sizeof exif, ofp);
9139 fwrite (&th, 1, sizeof th, ofp);
9141 fwrite (thumb+2, 1, thumb_length-2, ofp);
9145 void CLASS write_ppm_tiff()
9150 int c, row, col, soff, rstep, cstep;
9151 int perc, val, total, white=0x2000;
9153 perc = width * height * 0.01; /* 99th percentile white level */
9154 if (fuji_width) perc /= 2;
9155 if (!((highlight & ~2) || no_auto_bright))
9156 for (white=c=0; c < colors; c++) {
9157 for (val=0x2000, total=0; --val > 32; )
9158 if ((total += histogram[c][val]) > perc) break;
9159 if (white < val) white = val;
9161 gamma_curve (gamm[0], gamm[1], 2, (white << 3)/bright);
9164 if (flip & 4) SWAP(height,width);
9165 ppm = (uchar *) calloc (width, colors*output_bps/8);
9166 ppm2 = (ushort *) ppm;
9167 merror (ppm, "write_ppm_tiff()");
9170 fwrite (&th, sizeof th, 1, ofp);
9172 fwrite (oprof, ntohl(oprof[0]), 1, ofp);
9173 } else if (colors > 3)
9175 "P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLTYPE %s\nENDHDR\n",
9176 width, height, colors, (1 << output_bps)-1, cdesc);
9178 fprintf (ofp, "P%d\n%d %d\n%d\n",
9179 colors/2+5, width, height, (1 << output_bps)-1);
9180 soff = flip_index (0, 0);
9181 cstep = flip_index (0, 1) - soff;
9182 rstep = flip_index (1, 0) - flip_index (0, width);
9183 for (row=0; row < height; row++, soff += rstep) {
9184 for (col=0; col < width; col++, soff += cstep)
9185 if (output_bps == 8)
9186 FORCC ppm [col*colors+c] = curve[image[soff][c]] >> 8;
9187 else FORCC ppm2[col*colors+c] = curve[image[soff][c]];
9188 if (output_bps == 16 && !output_tiff && htons(0x55aa) != 0x55aa)
9189 swab (ppm2, ppm2, width*colors*2);
9190 fwrite (ppm, colors*output_bps/8, width, ofp);
9201 void CLASS write_cinelerra (FILE *ofp)
9206 for (row = 0; row < height; row++)
9208 output = dcraw_data[row];
9212 for (col = 0; col < width; col++)
9214 ushort *pixel = image[row * width + col];
9216 *output++ = (float)pixel[0] / 0xffff;
9217 *output++ = (float)pixel[1] / 0xffff;
9218 *output++ = (float)pixel[2] / 0xffff;
9220 if(dcraw_alpha) *output++ = 1.0;
9225 for (col = 0; col < width; col++)
9227 ushort *pixel = image[row * width + col];
9229 *output++ = (float)pixel[0] / 0xffff;
9230 *output++ = (float)pixel[1] / 0xffff;
9231 *output++ = (float)pixel[2] / 0xffff;
9233 if(dcraw_alpha) *output++ = 1.0;
9252 int CLASS dcraw_main (int argc, const char **argv)
9253 //int CLASS main (int argc, const char **argv)
9256 // Globals must be reset
9262 int arg, status=0, quality, i, c;
9263 int timestamp_only=0, thumbnail_only=0, identify_only=0;
9264 int user_qual=-1, user_black=-1, user_sat=-1, user_flip=-1;
9265 int use_fuji_rotate=1, write_to_stdout=0, read_from_stdin=0;
9266 const char *sp, *bpfile=0, *dark_frame=0, *write_ext;
9267 char opm, opt, *ofname, *cp;
9270 const char *cam_profile=0, *out_profile=0;
9274 putenv ((char *) "TZ=UTC");
9277 setlocale (LC_CTYPE, "");
9278 setlocale (LC_MESSAGES, "");
9279 bindtextdomain ("dcraw", LOCALEDIR);
9280 textdomain ("dcraw");
9284 printf(_("\nRaw photo decoder \"dcraw\" v%s"), DCRAW_VERSION);
9285 printf(_("\nby Dave Coffin, dcoffin a cybercom o net\n"));
9286 printf(_("\nUsage: %s [OPTION]... [FILE]...\n\n"), argv[0]);
9287 puts(_("-v Print verbose messages"));
9288 puts(_("-c Write image data to standard output"));
9289 puts(_("-e Extract embedded thumbnail image"));
9290 puts(_("-i Identify files without decoding them"));
9291 puts(_("-i -v Identify files and show metadata"));
9292 puts(_("-z Change file dates to camera timestamp"));
9293 puts(_("-w Use camera white balance, if possible"));
9294 puts(_("-a Average the whole image for white balance"));
9295 puts(_("-A <x y w h> Average a grey box for white balance"));
9296 puts(_("-r <r g b g> Set custom white balance"));
9297 puts(_("+M/-M Use/don't use an embedded color matrix"));
9298 puts(_("-C <r b> Correct chromatic aberration"));
9299 puts(_("-P <file> Fix the dead pixels listed in this file"));
9300 puts(_("-K <file> Subtract dark frame (16-bit raw PGM)"));
9301 puts(_("-k <num> Set the darkness level"));
9302 puts(_("-S <num> Set the saturation level"));
9303 puts(_("-n <num> Set threshold for wavelet denoising"));
9304 puts(_("-H [0-9] Highlight mode (0=clip, 1=unclip, 2=blend, 3+=rebuild)"));
9305 puts(_("-t [0-7] Flip image (0=none, 3=180, 5=90CCW, 6=90CW)"));
9306 puts(_("-o [0-5] Output colorspace (raw,sRGB,Adobe,Wide,ProPhoto,XYZ)"));
9308 puts(_("-o <file> Apply output ICC profile from file"));
9309 puts(_("-p <file> Apply camera ICC profile from file or \"embed\""));
9311 puts(_("-d Document mode (no color, no interpolation)"));
9312 puts(_("-D Document mode without scaling (totally raw)"));
9313 puts(_("-j Don't stretch or rotate raw pixels"));
9314 puts(_("-W Don't automatically brighten the image"));
9315 puts(_("-b <num> Adjust brightness (default = 1.0)"));
9316 puts(_("-g <p ts> Set custom gamma curve (default = 2.222 4.5)"));
9317 puts(_("-q [0-3] Set the interpolation quality"));
9318 puts(_("-h Half-size color image (twice as fast as \"-q 0\")"));
9319 puts(_("-f Interpolate RGGB as four colors"));
9320 puts(_("-m <num> Apply a 3x3 median filter to R-G and B-G"));
9321 puts(_("-s [0..N-1] Select one raw image or \"all\" from each file"));
9322 puts(_("-6 Write 16-bit instead of 8-bit"));
9323 puts(_("-4 Linear 16-bit, same as \"-6 -W -g 1 1\""));
9324 puts(_("-T Write TIFF instead of PPM"));
9329 for (arg=1; (((opm = argv[arg][0]) - 2) | 2) == '+'; ) {
9330 opt = argv[arg++][1];
9331 if ((cp = (char *) strchr (sp="nbrkStqmHACg", opt)))
9332 for (i=0; i < "114111111422"[cp-sp]-'0'; i++)
9333 if (!isdigit(argv[arg+i][0])) {
9334 fprintf (stderr,_("Non-numeric argument to \"-%c\"\n"), opt);
9338 case 'n': threshold = atof(argv[arg++]); break;
9339 case 'b': bright = atof(argv[arg++]); break;
9341 FORC4 user_mul[c] = atof(argv[arg++]); break;
9342 case 'C': aber[0] = 1 / atof(argv[arg++]);
9343 aber[2] = 1 / atof(argv[arg++]); break;
9344 case 'g': gamm[0] = atof(argv[arg++]);
9345 gamm[1] = atof(argv[arg++]);
9346 if (gamm[0]) gamm[0] = 1/gamm[0]; break;
9347 case 'k': user_black = atoi(argv[arg++]); break;
9348 case 'S': user_sat = atoi(argv[arg++]); break;
9349 case 't': user_flip = atoi(argv[arg++]); break;
9350 case 'q': user_qual = atoi(argv[arg++]); break;
9351 case 'm': med_passes = atoi(argv[arg++]); break;
9352 case 'H': highlight = atoi(argv[arg++]); break;
9354 shot_select = abs(atoi(argv[arg]));
9355 multi_out = !strcmp(argv[arg++],"all");
9358 if (isdigit(argv[arg][0]) && !argv[arg][1])
9359 output_color = atoi(argv[arg++]);
9361 else out_profile = argv[arg++];
9363 case 'p': cam_profile = argv[arg++];
9366 case 'P': bpfile = argv[arg++]; break;
9367 case 'K': dark_frame = argv[arg++]; break;
9368 case 'z': timestamp_only = 1; break;
9369 case 'e': thumbnail_only = 1; break;
9370 case 'i': identify_only = 1; break;
9371 case 'c': write_to_stdout = 1; break;
9372 case 'v': verbose = 1; break;
9373 case 'h': half_size = 1; /* "-h" implies "-f" */
9374 case 'f': four_color_rgb = 1; break;
9375 case 'A': FORC4 greybox[c] = atoi(argv[arg++]);
9376 case 'a': use_auto_wb = 1; break;
9377 case 'w': use_camera_wb = 1; break;
9378 case 'M': use_camera_matrix = (opm == '+'); break;
9379 case 'I': read_from_stdin = 1; break;
9380 case 'E': document_mode++;
9381 case 'D': document_mode++;
9382 case 'd': document_mode++;
9383 case 'j': use_fuji_rotate = 0; break;
9384 case 'W': no_auto_bright = 1; break;
9385 case 'T': output_tiff = 1; break;
9386 case '4': gamm[0] = gamm[1] =
9388 case '6': output_bps = 16; break;
9390 fprintf (stderr,_("Unknown option \"-%c\".\n"), opt);
9394 if (use_camera_matrix < 0)
9395 use_camera_matrix = use_camera_wb;
9397 fprintf (stderr,_("No files to process.\n"));
9400 if (write_to_stdout) {
9404 fprintf (stderr,_("Will not write an image to the terminal!\n"));
9407 #if defined(WIN32) || defined(DJGPP) || defined(__CYGWIN__)
9408 if (setmode(1,O_BINARY) < 0) {
9409 perror ("setmode()");
9414 for ( ; arg < argc; arg++) {
9419 meta_data = ofname = 0;
9421 if (setjmp (failure)) {
9422 if (fileno(ifp) > 2) fclose(ifp);
9423 if (fileno(ofp) > 2) fclose(ofp);
9428 if (!(ifp = fopen (ifname, "rb"))) {
9432 status = (identify(),!is_raw);
9435 switch ((flip+3600) % 360) {
9436 case 270: flip = 5; break;
9437 case 180: flip = 3; break;
9440 if (timestamp_only) {
9441 if ((status = !timestamp))
9442 fprintf (stderr,_("%s has no timestamp.\n"), ifname);
9443 else if (identify_only)
9444 printf ("%10ld%10d %s\n", (long) timestamp, shot_order, ifname);
9447 fprintf (stderr,_("%s time set to %d.\n"), ifname, (int) timestamp);
9448 ut.actime = ut.modtime = timestamp;
9449 utime (ifname, &ut);
9453 write_fun = &CLASS write_ppm_tiff;
9458 write_fun = write_cinelerra;
9463 if (thumbnail_only) {
9464 if ((status = !thumb_offset)) {
9465 fprintf (stderr,_("%s has no thumbnail.\n"), ifname);
9467 } else if (thumb_load_raw) {
9468 load_raw = thumb_load_raw;
9469 data_offset = thumb_offset;
9470 height = thumb_height;
9471 width = thumb_width;
9474 fseek (ifp, thumb_offset, SEEK_SET);
9475 write_fun = write_thumb;
9479 if (load_raw == &CLASS kodak_ycbcr_load_raw) {
9480 height += height & 1;
9483 if (identify_only && verbose && make[0]) {
9484 printf (_("\nFilename: %s\n"), ifname);
9485 printf (_("Timestamp: %s"), ctime(×tamp));
9486 printf (_("Camera: %s %s\n"), make, model);
9488 printf (_("Owner: %s\n"), artist);
9490 printf (_("DNG Version: "));
9491 for (i=24; i >= 0; i -= 8)
9492 printf ("%d%c", dng_version >> i & 255, i ? '.':'\n');
9494 printf (_("ISO speed: %d\n"), (int) iso_speed);
9495 printf (_("Shutter: "));
9496 if (shutter > 0 && shutter < 1)
9497 shutter = (printf ("1/"), 1 / shutter);
9498 printf (_("%0.1f sec\n"), shutter);
9499 printf (_("Aperture: f/%0.1f\n"), aperture);
9500 printf (_("Focal length: %0.1f mm\n"), focal_len);
9501 printf (_("Embedded ICC profile: %s\n"), profile_length ? _("yes"):_("no"));
9502 printf (_("Number of raw images: %d\n"), is_raw);
9503 if (pixel_aspect != 1)
9504 printf (_("Pixel Aspect Ratio: %0.6f\n"), pixel_aspect);
9506 printf (_("Thumb size: %4d x %d\n"), thumb_width, thumb_height);
9507 printf (_("Full size: %4d x %d\n"), raw_width, raw_height);
9513 // else if (!is_raw)
9514 // fprintf (stderr,_("Cannot decode file %s\n"), ifname);
9521 if (!is_raw) goto next;
9522 shrink = filters && (half_size || (!identify_only &&
9523 (threshold || aber[0] != 1 || aber[2] != 1)));
9524 iheight = (height + shrink) >> shrink;
9525 iwidth = (width + shrink) >> shrink;
9526 if (identify_only) {
9528 if (document_mode == 3) {
9529 top_margin = left_margin = fuji_width = 0;
9530 height = raw_height;
9531 if (width <= raw_width * 8 / tiff_bps)
9532 width = raw_width * 8 / tiff_bps;
9533 else width = raw_width;
9535 iheight = (height + shrink) >> shrink;
9536 iwidth = (width + shrink) >> shrink;
9537 if (use_fuji_rotate) {
9539 fuji_width = (fuji_width - 1 + shrink) >> shrink;
9540 iwidth = fuji_width / sqrt(0.5);
9541 iheight = (iheight - fuji_width) / sqrt(0.5);
9543 if (pixel_aspect < 1) iheight = iheight / pixel_aspect + 0.5;
9544 if (pixel_aspect > 1) iwidth = iwidth * pixel_aspect + 0.5;
9548 SWAP(iheight,iwidth);
9549 printf (_("Image size: %4d x %d\n"), width, height);
9550 printf (_("Output size: %4d x %d\n"), iwidth, iheight);
9551 printf (_("Raw colors: %d"), colors);
9553 printf (_("\nFilter pattern: "));
9554 for (i=0; i < 16; i++)
9555 putchar (cdesc[fcol(i >> 1,i & 1)]);
9557 printf (_("\nDaylight multipliers:"));
9558 FORCC printf (" %f", pre_mul[c]);
9559 if (cam_mul[0] > 0) {
9560 printf (_("\nCamera multipliers:"));
9561 FORC4 printf (" %f", cam_mul[c]);
9566 // printf (_("%s is a %s %s image.\n"), ifname, make, model);
9571 if (use_camera_matrix && cmatrix[0][0] > 0.25) {
9572 memcpy (rgb_cam, cmatrix, sizeof cmatrix);
9576 meta_data = (char *) malloc (meta_length);
9577 merror (meta_data, "main()");
9579 if (filters || colors == 1) {
9580 raw_image = (ushort *) calloc ((raw_height+7)*raw_width, 2);
9581 merror (raw_image, "main()");
9583 image = (ushort (*)[4]) calloc (iheight*iwidth, sizeof *image);
9584 merror (image, "main()");
9587 fprintf (stderr,_("Loading %s %s image from %s ...\n"),
9588 make, model, ifname);
9589 if (shot_select >= is_raw)
9590 fprintf (stderr,_("%s: \"-s %d\" requests a nonexistent image!\n"),
9591 ifname, shot_select);
9592 fseeko (ifp, data_offset, SEEK_SET);
9593 if (raw_image && read_from_stdin)
9594 fread (raw_image, 2, raw_height*raw_width, stdin);
9596 if (document_mode == 3) {
9597 top_margin = left_margin = fuji_width = 0;
9598 height = raw_height;
9599 if (width <= raw_width * 8 / tiff_bps)
9600 width = raw_width * 8 / tiff_bps;
9601 else width = raw_width;
9603 iheight = (height + shrink) >> shrink;
9604 iwidth = (width + shrink) >> shrink;
9606 image = (ushort (*)[4]) calloc (iheight*iwidth, sizeof *image);
9607 merror (image, "main()");
9608 crop_masked_pixels();
9611 if (zero_is_bad) remove_zeroes();
9612 bad_pixels (bpfile);
9613 if (dark_frame) subtract (dark_frame);
9614 quality = 2 + !fuji_width;
9615 if (user_qual >= 0) quality = user_qual;
9617 FORC3 if (i > cblack[c]) i = cblack[c];
9618 FORC4 cblack[c] -= i;
9620 if (user_black >= 0) black = user_black;
9621 FORC4 cblack[c] += black;
9622 if (user_sat > 0) maximum = user_sat;
9627 if (document_mode || load_raw == &CLASS foveon_dp_load_raw) {
9628 for (i=0; i < height*width*4; i++)
9629 if ((short) image[0][i] < 0) image[0][i] = 0;
9630 } else foveon_interpolate();
9631 } else if (document_mode < 2)
9634 if (filters && !document_mode) {
9637 else if (quality == 1 || colors > 3 || filters < 1000)
9639 else if (quality == 2)
9641 else ahd_interpolate();
9644 for (colors=3, i=0; i < height*width; i++)
9645 image[i][1] = (image[i][1] + image[i][3]) >> 1;
9646 if (!is_foveon && colors == 3) median_filter();
9647 if (!is_foveon && highlight == 2) blend_highlights();
9648 if (!is_foveon && highlight > 2) recover_highlights();
9649 if (use_fuji_rotate) fuji_rotate();
9651 if (cam_profile) apply_profile (cam_profile, out_profile);
9654 if (use_fuji_rotate) stretch();
9656 if (write_fun == &CLASS jpeg_thumb)
9658 else if (output_tiff && write_fun == &CLASS write_ppm_tiff)
9659 write_ext = ".tiff";
9661 write_ext = ".pgm\0.ppm\0.ppm\0.pam" + colors*5-5;
9662 ofname = (char *) malloc (strlen(ifname) + 64);
9663 merror (ofname, "main()");
9664 if (write_to_stdout)
9665 strcpy (ofname,_("standard output"));
9667 strcpy (ofname, ifname);
9668 if ((cp = strrchr (ofname, '.'))) *cp = 0;
9670 sprintf (ofname+strlen(ofname), "_%0*d",
9671 snprintf(0,0,"%d",is_raw-1), shot_select);
9673 strcat (ofname, ".thumb");
9674 strcat (ofname, write_ext);
9675 ofp = fopen (ofname, "wb");
9683 fprintf (stderr,_("Writing data to %s ...\n"), ofname);
9686 if (ofp != stdout) fclose(ofp);
9688 if (meta_data) free (meta_data);
9689 if (ofname) free (ofname);
9690 if (oprof) free (oprof);
9691 if (image) free (image);
9693 if (++shot_select < is_raw) arg--;
9694 else shot_select = 0;