2 dcraw.c -- Dave Coffin's raw photo decoder
3 Copyright 1997-2016 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: 2016/05/10 21:30:43 $
26 #define DCRAW_VERSION "9.27"
31 #define _USE_MATH_DEFINES
43 #include <sys/types.h>
45 #if defined(DJGPP) || defined(__MINGW32__)
49 #define fgetc getc_unlocked
55 #include <sys/utime.h>
57 #pragma comment(lib, "ws2_32.lib")
58 #define snprintf _snprintf
59 #define strcasecmp stricmp
60 #define strncasecmp strnicmp
61 typedef __int64 INT64;
62 typedef unsigned __int64 UINT64;
66 #include <netinet/in.h>
68 typedef int64_t INT64;
69 typedef uint64_t UINT64;
78 #include <jasper/jasper.h> /* Decode Red camera movies */
81 #include <jpeglib.h> /* Decode compressed Kodak DC120 photos */
82 #endif /* and Adobe Lossy DNGs */
84 #include <lcms2.h> /* Support color profiles */
88 #define _(String) gettext(String)
90 #define _(String) (String)
96 All global variables are defined here, and all functions that
97 access them are prefixed with "CLASS". Note that a thread-safe
98 C++ class cannot have non-const static local variables.
101 #define FORC(cnt) for (c=0; c < cnt; c++)
102 #define FORC3 FORC(3)
103 #define FORC4 FORC(4)
104 #define FORCC FORC(colors)
106 #define SQR(x) ((x)*(x))
107 #define ABS(x) (((int)(x) ^ ((int)(x) >> 31)) - ((int)(x) >> 31))
108 #define MIN(a,b) ((a) < (b) ? (a) : (b))
109 #define MAX(a,b) ((a) > (b) ? (a) : (b))
110 #define LIM(x,min,max) MAX(min,MIN(x,max))
111 #define ULIM(x,y,z) ((y) < (z) ? LIM(x,y,z) : LIM(x,z,y))
112 #define CLIP(x) LIM((int)(x),0,65535)
113 #define SWAP(a,b) { a=a+b; b=a-b; a=a-b; }
114 #define ZERO(var) memset(&var, 0, sizeof var)
116 In order to inline this calculation, I make the risky
117 assumption that all filter patterns can be described
118 by a repeating pattern of eight rows and two columns
120 Do not use the FC or BAYER macros with the Leaf CatchLight,
121 because its pattern is 16x16, not 2x8.
123 Return values are either 0/1/2/3 = G/M/C/Y or 0/1/2/3 = R/G1/B/G2
125 PowerShot 600 PowerShot A50 PowerShot Pro70 Pro90 & G1
126 0xe1e4e1e4: 0x1b4e4b1e: 0x1e4b4e1b: 0xb4b4b4b4:
128 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5
129 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
130 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
131 2 M G M G M G 2 Y C Y C Y C 2 C Y C Y C Y
132 3 C Y C Y C Y 3 G M G M G M 3 G M G M G M
133 4 C Y C Y C Y 4 Y C Y C Y C
134 PowerShot A5 5 G M G M G M 5 G M G M G M
135 0x1e4e1e4e: 6 Y C Y C Y C 6 C Y C Y C Y
136 7 M G M G M G 7 M G M G M G
143 All RGB cameras use one of these Bayer grids:
145 0x16161616: 0x61616161: 0x49494949: 0x94949494:
147 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5
148 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
149 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
150 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
151 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
154 #define RAW(row,col) \
155 raw_image[(row)*raw_width+(col)]
157 #define FC(row,col) \
158 (filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)
160 #define BAYER(row,col) \
161 image[((row) >> shrink)*iwidth + ((col) >> shrink)][FC(row,col)]
163 #define BAYER2(row,col) \
164 image[((row) >> shrink)*iwidth + ((col) >> shrink)][fcol(row,col)]
166 int CLASS fcol (int row, int col)
168 static const char filter[16][16] =
169 { { 2,1,1,3,2,3,2,0,3,2,3,0,1,2,1,0 },
170 { 0,3,0,2,0,1,3,1,0,1,1,2,0,3,3,2 },
171 { 2,3,3,2,3,1,1,3,3,1,2,1,2,0,0,3 },
172 { 0,1,0,1,0,2,0,2,2,0,3,0,1,3,2,1 },
173 { 3,1,1,2,0,1,0,2,1,3,1,3,0,1,3,0 },
174 { 2,0,0,3,3,2,3,1,2,0,2,0,3,2,2,1 },
175 { 2,3,3,1,2,1,2,1,2,1,1,2,3,0,0,1 },
176 { 1,0,0,2,3,0,0,3,0,3,0,3,2,1,2,3 },
177 { 2,3,3,1,1,2,1,0,3,2,3,0,2,3,1,3 },
178 { 1,0,2,0,3,0,3,2,0,1,1,2,0,1,0,2 },
179 { 0,1,1,3,3,2,2,1,1,3,3,0,2,1,3,2 },
180 { 2,3,2,0,0,1,3,0,2,0,1,2,3,0,1,0 },
181 { 1,3,1,2,3,2,3,2,0,2,0,1,1,0,3,0 },
182 { 0,2,0,3,1,0,0,1,1,3,3,2,3,2,2,1 },
183 { 2,1,3,2,3,1,2,1,0,3,0,2,0,2,0,2 },
184 { 0,3,1,0,0,2,0,3,2,1,3,1,1,3,1,3 } };
186 if (filters == 1) return filter[(row+top_margin)&15][(col+left_margin)&15];
187 if (filters == 9) return xtrans[(row+6) % 6][(col+6) % 6];
194 DCRaw_data *data = (DCRaw_data *)this;
195 memset(data, 0, sizeof(*data));
196 // non-zero init data
197 aber[0] = aber[1] = aber[2] = aber[3] = 1;
198 gamm[0] = 0.45; gamm[1] = 4.5;
200 use_camera_matrix = 1;
203 greybox[2] = UINT_MAX; greybox[3] = UINT_MAX;
207 char *my_memmem (char *haystack, size_t haystacklen,
208 char *needle, size_t needlelen)
211 for (c = haystack; c <= haystack + haystacklen - needlelen; c++)
212 if (!memcmp (c, needle, needlelen))
216 #define memmem my_memmem
217 char *my_strcasestr (char *haystack, const char *needle)
220 for (c = haystack; *c; c++)
221 if (!strncasecmp(c, needle, strlen(needle)))
225 #define strcasestr my_strcasestr
228 void CLASS merror (void *ptr, const char *where)
231 fprintf (stderr,_("%s: Out of memory in %s\n"), ifname, where);
232 longjmp (failure, 1);
238 fprintf (stderr, "%s: ", ifname);
240 fprintf (stderr,_("Unexpected end of file\n"));
242 fprintf (stderr,_("Corrupt data near 0x%jx\n"), (INT64) ftello(ifp));
247 ushort CLASS sget2 (uchar *s)
249 if (order == 0x4949) /* "II" means little-endian */
250 return s[0] | s[1] << 8;
251 else /* "MM" means big-endian */
252 return s[0] << 8 | s[1];
257 uchar str[2] = { 0xff,0xff };
258 fread (str, 1, 2, ifp);
262 unsigned CLASS sget4 (uchar *s)
265 return s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24;
267 return s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3];
269 #define sget4(s) sget4((uchar *)s)
271 unsigned CLASS get4()
273 uchar str[4] = { 0xff,0xff,0xff,0xff };
274 fread (str, 1, 4, ifp);
278 unsigned CLASS getint (int type)
280 return type == 3 ? get2() : get4();
283 float CLASS int_to_float (int i)
285 union { int i; float f; } u;
290 double CLASS getreal (int type)
292 union { char c[8]; double d; } u;
296 case 3: return (unsigned short) get2();
297 case 4: return (unsigned int) get4();
298 case 5: u.d = (unsigned int) get4();
299 return u.d / (unsigned int) get4();
300 case 8: return (signed short) get2();
301 case 9: return (signed int) get4();
302 case 10: u.d = (signed int) get4();
303 return u.d / (signed int) get4();
304 case 11: return int_to_float (get4());
306 rev = 7 * ((order == 0x4949) == (ntohs(0x1234) == 0x1234));
307 for (i=0; i < 8; i++)
308 u.c[i ^ rev] = fgetc(ifp);
310 default: return fgetc(ifp);
314 void CLASS read_shorts (ushort *pixel, int count)
316 if (fread (pixel, 2, count, ifp) < count) derror();
317 if ((order == 0x4949) == (ntohs(0x1234) == 0x1234))
318 swab (pixel, pixel, count*2);
321 void CLASS cubic_spline (const int *x_, const int *y_, const int len)
323 float **A, *b, *c, *d, *x, *y;
326 A = (float **) calloc (((2*len + 4)*sizeof **A + sizeof *A), 2*len);
328 A[0] = (float *) (A + 2*len);
329 for (i = 1; i < 2*len; i++)
330 A[i] = A[0] + 2*len*i;
331 y = len + (x = i + (d = i + (c = i + (b = A[0] + i*i))));
332 for (i = 0; i < len; i++) {
333 x[i] = x_[i] / 65535.0;
334 y[i] = y_[i] / 65535.0;
336 for (i = len-1; i > 0; i--) {
337 b[i] = (y[i] - y[i-1]) / (x[i] - x[i-1]);
338 d[i-1] = x[i] - x[i-1];
340 for (i = 1; i < len-1; i++) {
341 A[i][i] = 2 * (d[i-1] + d[i]);
346 A[i][len-1] = 6 * (b[i+1] - b[i]);
348 for(i = 1; i < len-2; i++) {
349 float v = A[i+1][i] / A[i][i];
350 for(j = 1; j <= len-1; j++)
351 A[i+1][j] -= v * A[i][j];
353 for(i = len-2; i > 0; i--) {
355 for(j = i; j <= len-2; j++)
357 c[i] = (A[i][len-1] - acc) / A[i][i];
359 for (i = 0; i < 0x10000; i++) {
360 float x_out = (float)(i / 65535.0);
362 for (j = 0; j < len-1; j++) {
363 if (x[j] <= x_out && x_out <= x[j+1]) {
364 float v = x_out - x[j];
366 ((y[j+1] - y[j]) / d[j] - (2 * d[j] * c[j] + c[j+1] * d[j])/6) * v
367 + (c[j] * 0.5) * v*v + ((c[j+1] - c[j]) / (6 * d[j])) * v*v*v;
370 curve[i] = y_out < 0.0 ? 0 : (y_out >= 1.0 ? 65535 :
371 (ushort)(y_out * 65535.0 + 0.5));
376 void CLASS canon_600_fixed_wb (int temp)
378 static const short mul[4][5] = {
379 { 667, 358,397,565,452 },
380 { 731, 390,367,499,517 },
381 { 1119, 396,348,448,537 },
382 { 1399, 485,431,508,688 } };
387 if (*mul[lo] <= temp) break;
388 for (hi=0; hi < 3; hi++)
389 if (*mul[hi] >= temp) break;
391 frac = (float) (temp - *mul[lo]) / (*mul[hi] - *mul[lo]);
392 for (i=1; i < 5; i++)
393 pre_mul[i-1] = 1 / (frac * mul[hi][i] + (1-frac) * mul[lo][i]);
396 /* Return values: 0 = white 1 = near white 2 = not white */
397 int CLASS canon_600_color (int ratio[2], int mar)
399 int clipped=0, target, miss;
403 { ratio[1] = -104; clipped = 1; }
405 { ratio[1] = 12; clipped = 1; }
407 if (ratio[1] < -264 || ratio[1] > 461) return 2;
409 { ratio[1] = -50; clipped = 1; }
411 { ratio[1] = 307; clipped = 1; }
413 target = flash_used || ratio[1] < 197
414 ? -38 - (398 * ratio[1] >> 10)
415 : -123 + (48 * ratio[1] >> 10);
416 if (target - mar <= ratio[0] &&
417 target + 20 >= ratio[0] && !clipped) return 0;
418 miss = target - ratio[0];
419 if (abs(miss) >= mar*4) return 2;
420 if (miss < -20) miss = -20;
421 if (miss > mar) miss = mar;
422 ratio[0] = target - miss;
426 void CLASS canon_600_auto_wb()
428 int mar, row, col, i, j, st, count[] = { 0,0 };
429 int test[8], total[2][8], ratio[2][2], stat[2];
431 memset (&total, 0, sizeof total);
433 if (i < 10) mar = 150;
434 else if (i > 12) mar = 20;
435 else mar = 280 - 20 * i;
436 if (flash_used) mar = 80;
437 for (row=14; row < height-14; row+=4)
438 for (col=10; col < width; col+=2) {
439 for (i=0; i < 8; i++)
440 test[(i & 4) + FC(row+(i >> 1),col+(i & 1))] =
441 BAYER(row+(i >> 1),col+(i & 1));
442 for (i=0; i < 8; i++)
443 if (test[i] < 150 || test[i] > 1500) goto next;
444 for (i=0; i < 4; i++)
445 if (abs(test[i] - test[i+4]) > 50) goto next;
446 for (i=0; i < 2; i++) {
447 for (j=0; j < 4; j+=2)
448 ratio[i][j >> 1] = ((test[i*4+j+1]-test[i*4+j]) << 10) / test[i*4+j];
449 stat[i] = canon_600_color (ratio[i], mar);
451 if ((st = stat[0] | stat[1]) > 1) goto next;
452 for (i=0; i < 2; i++)
454 for (j=0; j < 2; j++)
455 test[i*4+j*2+1] = test[i*4+j*2] * (0x400 + ratio[i][j]) >> 10;
456 for (i=0; i < 8; i++)
457 total[st][i] += test[i];
461 if (count[0] | count[1]) {
462 st = count[0]*200 < count[1];
463 for (i=0; i < 4; i++)
464 pre_mul[i] = 1.0 / (total[st][i] + total[st][i+4]);
468 void CLASS canon_600_coeff()
470 static const short table[6][12] = {
471 { -190,702,-1878,2390, 1861,-1349,905,-393, -432,944,2617,-2105 },
472 { -1203,1715,-1136,1648, 1388,-876,267,245, -1641,2153,3921,-3409 },
473 { -615,1127,-1563,2075, 1437,-925,509,3, -756,1268,2519,-2007 },
474 { -190,702,-1886,2398, 2153,-1641,763,-251, -452,964,3040,-2528 },
475 { -190,702,-1878,2390, 1861,-1349,905,-393, -432,944,2617,-2105 },
476 { -807,1319,-1785,2297, 1388,-876,769,-257, -230,742,2067,-1555 } };
480 mc = pre_mul[1] / pre_mul[2];
481 yc = pre_mul[3] / pre_mul[2];
482 if (mc > 1 && mc <= 1.28 && yc < 0.8789) t=1;
483 if (mc > 1.28 && mc <= 2) {
484 if (yc < 0.8789) t=3;
485 else if (yc <= 2) t=4;
488 for (raw_color = i=0; i < 3; i++)
489 FORCC rgb_cam[i][c] = table[t][i*4 + c] / 1024.0;
492 void CLASS canon_600_load_raw()
494 uchar data[1120], *dp;
498 for (irow=row=0; irow < height; irow++) {
499 if (fread (data, 1, 1120, ifp) < 1120) derror();
500 pix = raw_image + row*raw_width;
501 for (dp=data; dp < data+1120; dp+=10, pix+=8) {
502 pix[0] = (dp[0] << 2) + (dp[1] >> 6 );
503 pix[1] = (dp[2] << 2) + (dp[1] >> 4 & 3);
504 pix[2] = (dp[3] << 2) + (dp[1] >> 2 & 3);
505 pix[3] = (dp[4] << 2) + (dp[1] & 3);
506 pix[4] = (dp[5] << 2) + (dp[9] & 3);
507 pix[5] = (dp[6] << 2) + (dp[9] >> 2 & 3);
508 pix[6] = (dp[7] << 2) + (dp[9] >> 4 & 3);
509 pix[7] = (dp[8] << 2) + (dp[9] >> 6 );
511 if ((row+=2) > height) row = 1;
515 void CLASS canon_600_correct()
518 static const short mul[4][2] =
519 { { 1141,1145 }, { 1128,1109 }, { 1178,1149 }, { 1128,1109 } };
521 for (row=0; row < height; row++)
522 for (col=0; col < width; col++) {
523 if ((val = BAYER(row,col) - black) < 0) val = 0;
524 val = val * mul[row & 3][col & 1] >> 9;
525 BAYER(row,col) = val;
527 canon_600_fixed_wb(1311);
530 maximum = (0x3ff - black) * 1109 >> 9;
534 int CLASS canon_s2is()
538 for (row=0; row < 100; row++) {
539 fseek (ifp, row*3340 + 3284, SEEK_SET);
540 if (getc(ifp) > 15) return 1;
545 unsigned CLASS getbithuff (int nbits, ushort *huff)
551 if (nbits > 25) return 0;
553 return gbh_bitbuf = gbh_vbits = gbh_reset = 0;
554 if (nbits == 0 || gbh_vbits < 0) return 0;
555 bitbuf = gbh_bitbuf; vbits = gbh_vbits; reset = gbh_reset;
556 while (!reset && vbits < nbits && (c = fgetc(ifp)) != EOF &&
557 !(reset = zero_after_ff && c == 0xff && fgetc(ifp))) {
558 bitbuf = (bitbuf << 8) + (uchar) c;
561 c = bitbuf << (32-vbits) >> (32-nbits);
563 vbits -= huff[c] >> 8;
567 if (vbits < 0) derror();
568 gbh_bitbuf = bitbuf; gbh_vbits = vbits; gbh_reset = reset;
572 #define getbits(n) getbithuff(n,0)
573 #define gethuff(h) getbithuff(*h,h+1)
576 Construct a decode tree according the specification in *source.
577 The first 16 bytes specify how many codes should be 1-bit, 2-bit
578 3-bit, etc. Bytes after that are the leaf values.
580 For example, if the source is
582 { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0,
583 0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff },
601 ushort * CLASS make_decoder_ref (const uchar **source)
603 int max, len, h, i, j;
607 count = (*source += 16) - 17;
608 for (max=16; max && !count[max]; max--);
609 huff = (ushort *) calloc (1 + (1 << max), sizeof *huff);
610 merror (huff, "make_decoder()");
612 for (h=len=1; len <= max; len++)
613 for (i=0; i < count[len]; i++, ++*source)
614 for (j=0; j < 1 << (max-len); j++)
616 huff[h++] = len << 8 | **source;
620 ushort * CLASS make_decoder (const uchar *source)
622 return make_decoder_ref (&source);
625 void CLASS crw_init_tables (unsigned table, ushort *huff[2])
627 static const uchar first_tree[3][29] = {
628 { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0,
629 0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff },
630 { 0,2,2,3,1,1,1,1,2,0,0,0,0,0,0,0,
631 0x03,0x02,0x04,0x01,0x05,0x00,0x06,0x07,0x09,0x08,0x0a,0x0b,0xff },
632 { 0,0,6,3,1,1,2,0,0,0,0,0,0,0,0,0,
633 0x06,0x05,0x07,0x04,0x08,0x03,0x09,0x02,0x00,0x0a,0x01,0x0b,0xff },
635 static const uchar second_tree[3][180] = {
636 { 0,2,2,2,1,4,2,1,2,5,1,1,0,0,0,139,
637 0x03,0x04,0x02,0x05,0x01,0x06,0x07,0x08,
638 0x12,0x13,0x11,0x14,0x09,0x15,0x22,0x00,0x21,0x16,0x0a,0xf0,
639 0x23,0x17,0x24,0x31,0x32,0x18,0x19,0x33,0x25,0x41,0x34,0x42,
640 0x35,0x51,0x36,0x37,0x38,0x29,0x79,0x26,0x1a,0x39,0x56,0x57,
641 0x28,0x27,0x52,0x55,0x58,0x43,0x76,0x59,0x77,0x54,0x61,0xf9,
642 0x71,0x78,0x75,0x96,0x97,0x49,0xb7,0x53,0xd7,0x74,0xb6,0x98,
643 0x47,0x48,0x95,0x69,0x99,0x91,0xfa,0xb8,0x68,0xb5,0xb9,0xd6,
644 0xf7,0xd8,0x67,0x46,0x45,0x94,0x89,0xf8,0x81,0xd5,0xf6,0xb4,
645 0x88,0xb1,0x2a,0x44,0x72,0xd9,0x87,0x66,0xd4,0xf5,0x3a,0xa7,
646 0x73,0xa9,0xa8,0x86,0x62,0xc7,0x65,0xc8,0xc9,0xa1,0xf4,0xd1,
647 0xe9,0x5a,0x92,0x85,0xa6,0xe7,0x93,0xe8,0xc1,0xc6,0x7a,0x64,
648 0xe1,0x4a,0x6a,0xe6,0xb3,0xf1,0xd3,0xa5,0x8a,0xb2,0x9a,0xba,
649 0x84,0xa4,0x63,0xe5,0xc5,0xf3,0xd2,0xc4,0x82,0xaa,0xda,0xe4,
650 0xf2,0xca,0x83,0xa3,0xa2,0xc3,0xea,0xc2,0xe2,0xe3,0xff,0xff },
651 { 0,2,2,1,4,1,4,1,3,3,1,0,0,0,0,140,
652 0x02,0x03,0x01,0x04,0x05,0x12,0x11,0x06,
653 0x13,0x07,0x08,0x14,0x22,0x09,0x21,0x00,0x23,0x15,0x31,0x32,
654 0x0a,0x16,0xf0,0x24,0x33,0x41,0x42,0x19,0x17,0x25,0x18,0x51,
655 0x34,0x43,0x52,0x29,0x35,0x61,0x39,0x71,0x62,0x36,0x53,0x26,
656 0x38,0x1a,0x37,0x81,0x27,0x91,0x79,0x55,0x45,0x28,0x72,0x59,
657 0xa1,0xb1,0x44,0x69,0x54,0x58,0xd1,0xfa,0x57,0xe1,0xf1,0xb9,
658 0x49,0x47,0x63,0x6a,0xf9,0x56,0x46,0xa8,0x2a,0x4a,0x78,0x99,
659 0x3a,0x75,0x74,0x86,0x65,0xc1,0x76,0xb6,0x96,0xd6,0x89,0x85,
660 0xc9,0xf5,0x95,0xb4,0xc7,0xf7,0x8a,0x97,0xb8,0x73,0xb7,0xd8,
661 0xd9,0x87,0xa7,0x7a,0x48,0x82,0x84,0xea,0xf4,0xa6,0xc5,0x5a,
662 0x94,0xa4,0xc6,0x92,0xc3,0x68,0xb5,0xc8,0xe4,0xe5,0xe6,0xe9,
663 0xa2,0xa3,0xe3,0xc2,0x66,0x67,0x93,0xaa,0xd4,0xd5,0xe7,0xf8,
664 0x88,0x9a,0xd7,0x77,0xc4,0x64,0xe2,0x98,0xa5,0xca,0xda,0xe8,
665 0xf3,0xf6,0xa9,0xb2,0xb3,0xf2,0xd2,0x83,0xba,0xd3,0xff,0xff },
666 { 0,0,6,2,1,3,3,2,5,1,2,2,8,10,0,117,
667 0x04,0x05,0x03,0x06,0x02,0x07,0x01,0x08,
668 0x09,0x12,0x13,0x14,0x11,0x15,0x0a,0x16,0x17,0xf0,0x00,0x22,
669 0x21,0x18,0x23,0x19,0x24,0x32,0x31,0x25,0x33,0x38,0x37,0x34,
670 0x35,0x36,0x39,0x79,0x57,0x58,0x59,0x28,0x56,0x78,0x27,0x41,
671 0x29,0x77,0x26,0x42,0x76,0x99,0x1a,0x55,0x98,0x97,0xf9,0x48,
672 0x54,0x96,0x89,0x47,0xb7,0x49,0xfa,0x75,0x68,0xb6,0x67,0x69,
673 0xb9,0xb8,0xd8,0x52,0xd7,0x88,0xb5,0x74,0x51,0x46,0xd9,0xf8,
674 0x3a,0xd6,0x87,0x45,0x7a,0x95,0xd5,0xf6,0x86,0xb4,0xa9,0x94,
675 0x53,0x2a,0xa8,0x43,0xf5,0xf7,0xd4,0x66,0xa7,0x5a,0x44,0x8a,
676 0xc9,0xe8,0xc8,0xe7,0x9a,0x6a,0x73,0x4a,0x61,0xc7,0xf4,0xc6,
677 0x65,0xe9,0x72,0xe6,0x71,0x91,0x93,0xa6,0xda,0x92,0x85,0x62,
678 0xf3,0xc5,0xb2,0xa4,0x84,0xba,0x64,0xa5,0xb3,0xd2,0x81,0xe5,
679 0xd3,0xaa,0xc4,0xca,0xf2,0xb1,0xe4,0xd1,0x83,0x63,0xea,0xc3,
680 0xe2,0x82,0xf1,0xa3,0xc2,0xa1,0xc1,0xe3,0xa2,0xe1,0xff,0xff }
682 if (table > 2) table = 2;
683 huff[0] = make_decoder ( first_tree[table]);
684 huff[1] = make_decoder (second_tree[table]);
688 Return 0 if the image starts with compressed data,
689 1 if it starts with uncompressed low-order bits.
691 In Canon compressed data, 0xff is always followed by 0x00.
693 int CLASS canon_has_lowbits()
698 fseek (ifp, 0, SEEK_SET);
699 fread (test, 1, sizeof test, ifp);
700 for (i=540; i < sizeof test - 1; i++)
701 if (test[i] == 0xff) {
702 if (test[i+1]) return 1;
708 void CLASS canon_load_raw()
710 ushort *pixel, *prow, *huff[2];
711 int nblocks, lowbits, i, c, row, r, save, val;
712 int block, diffbuf[64], leaf, len, diff, carry=0, pnum=0, base[2];
714 crw_init_tables (tiff_compress, huff);
715 lowbits = canon_has_lowbits();
716 if (!lowbits) maximum = 0x3ff;
717 fseek (ifp, 540 + lowbits*raw_height*raw_width/4, SEEK_SET);
720 for (row=0; row < raw_height; row+=8) {
721 pixel = raw_image + row*raw_width;
722 nblocks = MIN (8, raw_height-row) * raw_width >> 6;
723 for (block=0; block < nblocks; block++) {
724 memset (diffbuf, 0, sizeof diffbuf);
725 for (i=0; i < 64; i++ ) {
726 leaf = gethuff(huff[i > 0]);
727 if (leaf == 0 && i) break;
728 if (leaf == 0xff) continue;
731 if (len == 0) continue;
733 if ((diff & (1 << (len-1))) == 0)
734 diff -= (1 << len) - 1;
735 if (i < 64) diffbuf[i] = diff;
739 for (i=0; i < 64; i++ ) {
740 if (pnum++ % raw_width == 0)
741 base[0] = base[1] = 512;
742 if ((pixel[(block << 6) + i] = base[i & 1] += diffbuf[i]) >> 10)
748 fseek (ifp, 26 + row*raw_width/4, SEEK_SET);
749 for (prow=pixel, i=0; i < raw_width*2; i++) {
751 for (r=0; r < 8; r+=2, prow++) {
752 val = (*prow << 2) + ((c >> r) & 3);
753 if (raw_width == 2672 && val < 512) val += 2;
757 fseek (ifp, save, SEEK_SET);
760 FORC(2) free (huff[c]);
764 int algo, bits, high, wide, clrs, sraw, psv, restart, vpred[6];
765 ushort quant[64], idct[64], *huff[20], *free[20], *row;
768 int CLASS ljpeg_start (struct jhead *jh, int info_only)
774 memset (jh, 0, sizeof *jh);
775 jh->restart = INT_MAX;
776 if ((fgetc(ifp),fgetc(ifp)) != 0xd8) return 0;
778 if (!fread (data, 2, 2, ifp)) return 0;
779 tag = data[0] << 8 | data[1];
780 len = (data[2] << 8 | data[3]) - 2;
781 if (tag <= 0xff00) return 0;
782 fread (data, 1, len, ifp);
785 jh->sraw = ((data[7] >> 4) * (data[7] & 15) - 1) & 3;
788 jh->algo = tag & 0xff;
790 jh->high = data[1] << 8 | data[2];
791 jh->wide = data[3] << 8 | data[4];
792 jh->clrs = data[5] + jh->sraw;
793 if (len == 9 && !dng_version) getc(ifp);
796 if (info_only) break;
797 for (dp = data; dp < data+len && !((c = *dp++) & -20); )
798 jh->free[c] = jh->huff[c] = make_decoder_ref (&dp);
801 jh->psv = data[1+data[0]*2];
802 jh->bits -= data[3+data[0]*2] & 15;
805 FORC(64) jh->quant[c] = data[c*2+1] << 8 | data[c*2+2];
808 jh->restart = data[0] << 8 | data[1];
810 } while (tag != 0xffda);
811 if (jh->bits > 16 || jh->clrs > 6 ||
812 !jh->bits || !jh->high || !jh->wide || !jh->clrs) return 0;
813 if (info_only) return 1;
814 if (!jh->huff[0]) return 0;
815 FORC(19) if (!jh->huff[c+1]) jh->huff[c+1] = jh->huff[c];
817 FORC(4) jh->huff[2+c] = jh->huff[1];
818 FORC(jh->sraw) jh->huff[1+c] = jh->huff[0];
820 jh->row = (ushort *) calloc (jh->wide*jh->clrs, 4);
821 merror (jh->row, "ljpeg_start()");
822 return zero_after_ff = 1;
825 void CLASS ljpeg_end (struct jhead *jh)
828 FORC4 if (jh->free[c]) free (jh->free[c]);
832 int CLASS ljpeg_diff (ushort *huff)
837 if (len == 16 && (!dng_version || dng_version >= 0x1010000))
840 if ((diff & (1 << (len-1))) == 0)
841 diff -= (1 << len) - 1;
845 ushort * CLASS ljpeg_row (int jrow, struct jhead *jh)
847 int col, c, diff, pred, spred=0;
848 ushort mark=0, *row[3];
850 if (jrow * jh->wide % jh->restart == 0) {
851 FORC(6) jh->vpred[c] = 1 << (jh->bits-1);
853 fseek (ifp, -2, SEEK_CUR);
854 do mark = (mark << 8) + (c = fgetc(ifp));
855 while (c != EOF && mark >> 4 != 0xffd);
859 FORC3 row[c] = jh->row + jh->wide*jh->clrs*((jrow+c) & 1);
860 for (col=0; col < jh->wide; col++)
862 diff = ljpeg_diff (jh->huff[c]);
863 if (jh->sraw && c <= jh->sraw && (col | c))
865 else if (col) pred = row[0][-jh->clrs];
866 else pred = (jh->vpred[c] += diff) - diff;
867 if (jrow && col) switch (jh->psv) {
869 case 2: pred = row[1][0]; break;
870 case 3: pred = row[1][-jh->clrs]; break;
871 case 4: pred = pred + row[1][0] - row[1][-jh->clrs]; break;
872 case 5: pred = pred + ((row[1][0] - row[1][-jh->clrs]) >> 1); break;
873 case 6: pred = row[1][0] + ((pred - row[1][-jh->clrs]) >> 1); break;
874 case 7: pred = (pred + row[1][0]) >> 1; break;
877 if ((**row = pred + diff) >> jh->bits) derror();
878 if (c <= jh->sraw) spred = **row;
884 void CLASS lossless_jpeg_load_raw()
886 int jwide, jrow, jcol, val, jidx, i, j, row=0, col=0;
890 if (!ljpeg_start (&jh, 0)) return;
891 jwide = jh.wide * jh.clrs;
893 for (jrow=0; jrow < jh.high; jrow++) {
894 rp = ljpeg_row (jrow, &jh);
896 row = jrow & 1 ? height-1-jrow/2 : jrow/2;
897 for (jcol=0; jcol < jwide; jcol++) {
900 jidx = jrow*jwide + jcol;
901 i = jidx / (cr2_slice[1]*raw_height);
902 if ((j = i >= cr2_slice[0]))
904 jidx -= i * (cr2_slice[1]*raw_height);
905 row = jidx / cr2_slice[1+j];
906 col = jidx % cr2_slice[1+j] + i*cr2_slice[1];
908 if (raw_width == 3984 && (col -= 2) < 0)
909 col += (row--,raw_width);
910 if ((unsigned) row < raw_height) RAW(row,col) = val;
911 if (++col >= raw_width)
918 void CLASS canon_sraw_load_raw()
921 short *rp=0, (*ip)[4];
922 int jwide, slice, scol, ecol, row, col, jrow=0, jcol=0, pix[3], c;
923 int v[3]={0,0,0}, ver, hue;
926 if (!ljpeg_start (&jh, 0) || jh.clrs < 4) return;
927 jwide = (jh.wide >>= 1) * jh.clrs;
929 for (ecol=slice=0; slice <= cr2_slice[0]; slice++) {
931 ecol += cr2_slice[1] * 2 / jh.clrs;
932 if (!cr2_slice[0] || ecol > raw_width-1) ecol = raw_width & -2;
933 for (row=0; row < height; row += (jh.clrs >> 1) - 1) {
934 ip = (short (*)[4]) image + row*width;
935 for (col=scol; col < ecol; col+=2, jcol+=jh.clrs) {
936 if ((jcol %= jwide) == 0)
937 rp = (short *) ljpeg_row (jrow++, &jh);
938 if (col >= width) continue;
940 ip[col + (c >> 1)*width + (c & 1)][0] = rp[jcol+c];
941 ip[col][1] = rp[jcol+jh.clrs-2] - 16384;
942 ip[col][2] = rp[jcol+jh.clrs-1] - 16384;
946 for (cp=model2; *cp && !isdigit(*cp); cp++);
947 sscanf (cp, "%d.%d.%d", v, v+1, v+2);
948 ver = (v[0]*1000 + v[1])*1000 + v[2];
949 hue = (jh.sraw+1) << 2;
950 if (unique_id >= 0x80000281 || (unique_id == 0x80000218 && ver > 1000006))
952 ip = (short (*)[4]) image;
954 for (row=0; row < height; row++, ip+=width) {
955 if (row & (jh.sraw >> 1)) {
956 for (col=0; col < width; col+=2)
957 for (c=1; c < 3; c++)
959 ip[col][c] = ip[col-width][c];
960 else ip[col][c] = (ip[col-width][c] + ip[col+width][c] + 1) >> 1;
962 for (col=1; col < width; col+=2)
963 for (c=1; c < 3; c++)
965 ip[col][c] = ip[col-1][c];
966 else ip[col][c] = (ip[col-1][c] + ip[col+1][c] + 1) >> 1;
968 for ( ; rp < ip[0]; rp+=4) {
969 if (unique_id == 0x80000218 ||
970 unique_id == 0x80000250 ||
971 unique_id == 0x80000261 ||
972 unique_id == 0x80000281 ||
973 unique_id == 0x80000287) {
974 rp[1] = (rp[1] << 2) + hue;
975 rp[2] = (rp[2] << 2) + hue;
976 pix[0] = rp[0] + (( 50*rp[1] + 22929*rp[2]) >> 14);
977 pix[1] = rp[0] + ((-5640*rp[1] - 11751*rp[2]) >> 14);
978 pix[2] = rp[0] + ((29040*rp[1] - 101*rp[2]) >> 14);
980 if (unique_id < 0x80000218) rp[0] -= 512;
981 pix[0] = rp[0] + rp[2];
982 pix[2] = rp[0] + rp[1];
983 pix[1] = rp[0] + ((-778*rp[1] - (rp[2] << 11)) >> 12);
985 FORC3 rp[c] = CLIP(pix[c] * sraw_mul[c] >> 10);
991 void CLASS adobe_copy_pixel (unsigned row, unsigned col, ushort **rp)
995 if (tiff_samples == 2 && shot_select) (*rp)++;
997 if (row < raw_height && col < raw_width)
998 RAW(row,col) = curve[**rp];
1001 if (row < height && col < width)
1003 image[row*width+col][c] = curve[(*rp)[c]];
1004 *rp += tiff_samples;
1006 if (tiff_samples == 2 && shot_select) (*rp)--;
1009 void CLASS ljpeg_idct (struct jhead *jh)
1011 int c, i, j, len, skip, coef;
1012 float work[3][8][8], *cs = ljpeg_cs;
1013 static const uchar zigzag[80] =
1014 { 0, 1, 8,16, 9, 2, 3,10,17,24,32,25,18,11, 4, 5,12,19,26,33,
1015 40,48,41,34,27,20,13, 6, 7,14,21,28,35,42,49,56,57,50,43,36,
1016 29,22,15,23,30,37,44,51,58,59,52,45,38,31,39,46,53,60,61,54,
1017 47,55,62,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63 };
1020 FORC(106) cs[c] = cos((c & 31)*M_PI/16)/2;
1021 memset (work, 0, sizeof work);
1022 work[0][0][0] = jh->vpred[0] += ljpeg_diff (jh->huff[0]) * jh->quant[0];
1023 for (i=1; i < 64; i++ ) {
1024 len = gethuff (jh->huff[16]);
1025 i += skip = len >> 4;
1026 if (!(len &= 15) && skip < 15) break;
1027 coef = getbits(len);
1028 if ((coef & (1 << (len-1))) == 0)
1029 coef -= (1 << len) - 1;
1030 ((float *)work)[zigzag[i]] = coef * jh->quant[i];
1032 FORC(8) work[0][0][c] *= M_SQRT1_2;
1033 FORC(8) work[0][c][0] *= M_SQRT1_2;
1034 for (i=0; i < 8; i++)
1035 for (j=0; j < 8; j++)
1036 FORC(8) work[1][i][j] += work[0][i][c] * cs[(j*2+1)*c];
1037 for (i=0; i < 8; i++)
1038 for (j=0; j < 8; j++)
1039 FORC(8) work[2][i][j] += work[1][c][j] * cs[(i*2+1)*c];
1041 FORC(64) jh->idct[c] = CLIP(((float *)work[2])[c]+0.5);
1044 void CLASS lossless_dng_load_raw()
1046 unsigned save, trow=0, tcol=0, jwide, jrow, jcol, row, col, i, j;
1050 while (trow < raw_height) {
1052 if (tile_length < INT_MAX)
1053 fseek (ifp, get4(), SEEK_SET);
1054 if (!ljpeg_start (&jh, 0)) break;
1056 if (filters) jwide *= jh.clrs;
1057 jwide /= MIN (is_raw, tiff_samples);
1060 jh.vpred[0] = 16384;
1062 for (jrow=0; jrow+7 < jh.high; jrow += 8) {
1063 for (jcol=0; jcol+7 < jh.wide; jcol += 8) {
1066 row = trow + jcol/tile_width + jrow*2;
1067 col = tcol + jcol%tile_width;
1068 for (i=0; i < 16; i+=2)
1069 for (j=0; j < 8; j++)
1070 adobe_copy_pixel (row+i, col+j, &rp);
1075 for (row=col=jrow=0; jrow < jh.high; jrow++) {
1076 rp = ljpeg_row (jrow, &jh);
1077 for (jcol=0; jcol < jwide; jcol++) {
1078 adobe_copy_pixel (trow+row, tcol+col, &rp);
1079 if (++col >= tile_width || col >= raw_width)
1080 row += 1 + (col = 0);
1084 fseek (ifp, save+4, SEEK_SET);
1085 if ((tcol += tile_width) >= raw_width)
1086 trow += tile_length + (tcol = 0);
1091 void CLASS packed_dng_load_raw()
1096 pixel = (ushort *) calloc (raw_width, tiff_samples*sizeof *pixel);
1097 merror (pixel, "packed_dng_load_raw()");
1098 for (row=0; row < raw_height; row++) {
1100 read_shorts (pixel, raw_width * tiff_samples);
1103 for (col=0; col < raw_width * tiff_samples; col++)
1104 pixel[col] = getbits(tiff_bps);
1106 for (rp=pixel, col=0; col < raw_width; col++)
1107 adobe_copy_pixel (row, col, &rp);
1112 void CLASS pentax_load_raw()
1114 ushort bit[2][15], huff[4097];
1115 int dep, row, col, diff, c, i;
1116 ushort vpred[2][2] = {{0,0},{0,0}}, hpred[2];
1118 fseek (ifp, meta_offset, SEEK_SET);
1119 dep = (get2() + 12) & 15;
1120 fseek (ifp, 12, SEEK_CUR);
1121 FORC(dep) bit[0][c] = get2();
1122 FORC(dep) bit[1][c] = fgetc(ifp);
1124 for (i=bit[0][c]; i <= ((bit[0][c]+(4096 >> bit[1][c])-1) & 4095); )
1125 huff[++i] = bit[1][c] << 8 | c;
1127 fseek (ifp, data_offset, SEEK_SET);
1129 for (row=0; row < raw_height; row++)
1130 for (col=0; col < raw_width; col++) {
1131 diff = ljpeg_diff (huff);
1132 if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
1133 else hpred[col & 1] += diff;
1134 RAW(row,col) = hpred[col & 1];
1135 if (hpred[col & 1] >> tiff_bps) derror();
1139 void CLASS nikon_load_raw()
1141 static const uchar nikon_tree[][32] = {
1142 { 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0, /* 12-bit lossy */
1143 5,4,3,6,2,7,1,0,8,9,11,10,12 },
1144 { 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0, /* 12-bit lossy after split */
1145 0x39,0x5a,0x38,0x27,0x16,5,4,3,2,1,0,11,12,12 },
1146 { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0, /* 12-bit lossless */
1147 5,4,6,3,7,2,8,1,9,0,10,11,12 },
1148 { 0,1,4,3,1,1,1,1,1,2,0,0,0,0,0,0, /* 14-bit lossy */
1149 5,6,4,7,8,3,9,2,1,0,10,11,12,13,14 },
1150 { 0,1,5,1,1,1,1,1,1,1,2,0,0,0,0,0, /* 14-bit lossy after split */
1151 8,0x5c,0x4b,0x3a,0x29,7,6,5,4,3,2,1,0,13,14 },
1152 { 0,1,4,2,2,3,1,2,0,0,0,0,0,0,0,0, /* 14-bit lossless */
1153 7,6,8,5,9,4,10,3,11,12,2,0,1,13,14 } };
1154 ushort *huff, ver0, ver1, vpred[2][2], hpred[2], csize;
1155 int i, min, max, step=0, tree=0, split=0, row, col, len, shl, diff;
1157 fseek (ifp, meta_offset, SEEK_SET);
1160 if (ver0 == 0x49 || ver1 == 0x58)
1161 fseek (ifp, 2110, SEEK_CUR);
1162 if (ver0 == 0x46) tree = 2;
1163 if (tiff_bps == 14) tree += 3;
1164 read_shorts (vpred[0], 4);
1165 max = 1 << tiff_bps & 0x7fff;
1166 if ((csize = get2()) > 1)
1167 step = max / (csize-1);
1168 if (ver0 == 0x44 && ver1 == 0x20 && step > 0) {
1169 for (i=0; i < csize; i++)
1170 curve[i*step] = get2();
1171 for (i=0; i < max; i++)
1172 curve[i] = ( curve[i-i%step]*(step-i%step) +
1173 curve[i-i%step+step]*(i%step) ) / step;
1174 fseek (ifp, meta_offset+562, SEEK_SET);
1176 } else if (ver0 != 0x46 && csize <= 0x4001)
1177 read_shorts (curve, max=csize);
1178 while (curve[max-2] == curve[max-1]) max--;
1179 huff = make_decoder (nikon_tree[tree]);
1180 fseek (ifp, data_offset, SEEK_SET);
1182 for (min=row=0; row < height; row++) {
1183 if (split && row == split) {
1185 huff = make_decoder (nikon_tree[tree+1]);
1186 max += (min = 16) << 1;
1188 for (col=0; col < raw_width; col++) {
1192 diff = ((getbits(len-shl) << 1) + 1) << shl >> 1;
1193 if ((diff & (1 << (len-1))) == 0)
1194 diff -= (1 << len) - !shl;
1195 if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
1196 else hpred[col & 1] += diff;
1197 if ((ushort)(hpred[col & 1] + min) >= max) derror();
1198 RAW(row,col) = curve[LIM((short)hpred[col & 1],0,0x3fff)];
1204 void CLASS nikon_yuv_load_raw()
1206 int row, col, yuv[4], rgb[3], b, c;
1209 for (row=0; row < raw_height; row++)
1210 for (col=0; col < raw_width; col++) {
1211 if (!(b = col & 1)) {
1213 FORC(6) bitbuf |= (UINT64) fgetc(ifp) << c*8;
1214 FORC(4) yuv[c] = (bitbuf >> c*12 & 0xfff) - (c >> 1 << 11);
1216 rgb[0] = yuv[b] + 1.370705*yuv[3];
1217 rgb[1] = yuv[b] - 0.337633*yuv[2] - 0.698001*yuv[3];
1218 rgb[2] = yuv[b] + 1.732446*yuv[2];
1219 FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,0xfff)] / cam_mul[c];
1224 Returns 1 for a Coolpix 995, 0 for anything else.
1226 int CLASS nikon_e995()
1229 const uchar often[] = { 0x00, 0x55, 0xaa, 0xff };
1231 memset (histo, 0, sizeof histo);
1232 fseek (ifp, -2000, SEEK_END);
1233 for (i=0; i < 2000; i++)
1234 histo[fgetc(ifp)]++;
1235 for (i=0; i < 4; i++)
1236 if (histo[often[i]] < 200)
1242 Returns 1 for a Coolpix 2100, 0 for anything else.
1244 int CLASS nikon_e2100()
1249 fseek (ifp, 0, SEEK_SET);
1250 for (i=0; i < 1024; i++) {
1251 fread (t, 1, 12, ifp);
1252 if (((t[2] & t[4] & t[7] & t[9]) >> 4
1253 & t[1] & t[6] & t[8] & t[11] & 3) != 3)
1259 void CLASS nikon_3700()
1263 static const struct {
1265 char make[12], model[15];
1267 { 0x00, "Pentax", "Optio 33WR" },
1268 { 0x03, "Nikon", "E3200" },
1269 { 0x32, "Nikon", "E3700" },
1270 { 0x33, "Olympus", "C740UZ" } };
1272 fseek (ifp, 3072, SEEK_SET);
1273 fread (dp, 1, 24, ifp);
1274 bits = (dp[8] & 3) << 4 | (dp[20] & 3);
1275 for (i=0; i < sizeof table / sizeof *table; i++)
1276 if (bits == table[i].bits) {
1277 strcpy (make, table[i].make );
1278 strcpy (model, table[i].model);
1283 Separates a Minolta DiMAGE Z2 from a Nikon E4300.
1285 int CLASS minolta_z2()
1290 fseek (ifp, -sizeof tail, SEEK_END);
1291 fread (tail, 1, sizeof tail, ifp);
1292 for (nz=i=0; i < sizeof tail; i++)
1297 void CLASS ppm_thumb()
1300 thumb_length = thumb_width*thumb_height*3;
1301 thumb = (char *) malloc (thumb_length);
1302 merror (thumb, "ppm_thumb()");
1303 fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
1304 fread (thumb, 1, thumb_length, ifp);
1305 fwrite (thumb, 1, thumb_length, ofp);
1309 void CLASS ppm16_thumb()
1313 thumb_length = thumb_width*thumb_height*3;
1314 thumb = (char *) calloc (thumb_length, 2);
1315 merror (thumb, "ppm16_thumb()");
1316 read_shorts ((ushort *) thumb, thumb_length);
1317 for (i=0; i < thumb_length; i++)
1318 thumb[i] = ((ushort *) thumb)[i] >> 8;
1319 fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
1320 fwrite (thumb, 1, thumb_length, ofp);
1324 void CLASS layer_thumb()
1327 char *thumb, map[][4] = { "012","102" };
1329 colors = thumb_misc >> 5 & 7;
1330 thumb_length = thumb_width*thumb_height;
1331 thumb = (char *) calloc (colors, thumb_length);
1332 merror (thumb, "layer_thumb()");
1333 fprintf (ofp, "P%d\n%d %d\n255\n",
1334 5 + (colors >> 1), thumb_width, thumb_height);
1335 fread (thumb, thumb_length, colors, ifp);
1336 for (i=0; i < thumb_length; i++)
1337 FORCC putc (thumb[i+thumb_length*(map[thumb_misc >> 8][c]-'0')], ofp);
1341 void CLASS rollei_thumb()
1346 thumb_length = thumb_width * thumb_height;
1347 thumb = (ushort *) calloc (thumb_length, 2);
1348 merror (thumb, "rollei_thumb()");
1349 fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
1350 read_shorts (thumb, thumb_length);
1351 for (i=0; i < thumb_length; i++) {
1352 putc (thumb[i] << 3, ofp);
1353 putc (thumb[i] >> 5 << 2, ofp);
1354 putc (thumb[i] >> 11 << 3, ofp);
1359 void CLASS rollei_load_raw()
1362 unsigned iten=0, isix, i, buffer=0, todo[16];
1364 isix = raw_width * raw_height * 5 / 8;
1365 while (fread (pixel, 1, 10, ifp) == 10) {
1366 for (i=0; i < 10; i+=2) {
1368 todo[i+1] = pixel[i] << 8 | pixel[i+1];
1369 buffer = pixel[i] >> 2 | buffer << 6;
1371 for ( ; i < 16; i+=2) {
1373 todo[i+1] = buffer >> (14-i)*5;
1375 for (i=0; i < 16; i+=2)
1376 raw_image[todo[i]] = (todo[i+1] & 0x3ff);
1381 int CLASS raw (unsigned row, unsigned col)
1383 return (row < raw_height && col < raw_width) ? RAW(row,col) : 0;
1386 void CLASS phase_one_flat_field (int is_float, int nc)
1389 unsigned wide, high, y, x, c, rend, cend, row, col;
1390 float *mrow, num, mult[4];
1392 read_shorts (head, 8);
1393 if (head[2] * head[3] * head[4] * head[5] == 0) return;
1394 wide = head[2] / head[4] + (head[2] % head[4] != 0);
1395 high = head[3] / head[5] + (head[3] % head[5] != 0);
1396 mrow = (float *) calloc (nc*wide, sizeof *mrow);
1397 merror (mrow, "phase_one_flat_field()");
1398 for (y=0; y < high; y++) {
1399 for (x=0; x < wide; x++)
1400 for (c=0; c < nc; c+=2) {
1401 num = is_float ? getreal(11) : get2()/32768.0;
1402 if (y==0) mrow[c*wide+x] = num;
1403 else mrow[(c+1)*wide+x] = (num - mrow[c*wide+x]) / head[5];
1406 rend = head[1] + y*head[5];
1407 for (row = rend-head[5];
1408 row < raw_height && row < rend &&
1409 row < head[1]+head[3]-head[5]; row++) {
1410 for (x=1; x < wide; x++) {
1411 for (c=0; c < nc; c+=2) {
1412 mult[c] = mrow[c*wide+x-1];
1413 mult[c+1] = (mrow[c*wide+x] - mult[c]) / head[4];
1415 cend = head[0] + x*head[4];
1416 for (col = cend-head[4];
1418 col < cend && col < head[0]+head[2]-head[4]; col++) {
1419 c = nc > 2 ? FC(row-top_margin,col-left_margin) : 0;
1421 c = RAW(row,col) * mult[c];
1422 RAW(row,col) = LIM(c,0,65535);
1424 for (c=0; c < nc; c+=2)
1425 mult[c] += mult[c+1];
1428 for (x=0; x < wide; x++)
1429 for (c=0; c < nc; c+=2)
1430 mrow[c*wide+x] += mrow[(c+1)*wide+x];
1436 void CLASS phase_one_correct()
1438 unsigned entries, tag, data, save, col, row, type;
1439 int len, i, j, k, cip, val[4], dev[4], sum, max;
1440 int head[9], diff, mindiff=INT_MAX, off_412=0;
1441 static const signed char dir[12][2] =
1442 { {-1,-1}, {-1,1}, {1,-1}, {1,1}, {-2,0}, {0,-2}, {0,2}, {2,0},
1443 {-2,-2}, {-2,2}, {2,-2}, {2,2} };
1444 float poly[8], num, cfrac, frac, mult[2], *yval[2];
1446 int qmult_applied = 0, qlin_applied = 0;
1448 if (half_size || !meta_length) return;
1449 if (verbose) fprintf (stderr,_("Phase One correction...\n"));
1450 fseek (ifp, meta_offset, SEEK_SET);
1452 fseek (ifp, 6, SEEK_CUR);
1453 fseek (ifp, meta_offset+get4(), SEEK_SET);
1454 entries = get4(); get4();
1460 fseek (ifp, meta_offset+data, SEEK_SET);
1461 if (tag == 0x419) { /* Polynomial curve */
1462 for (get4(), i=0; i < 8; i++)
1463 poly[i] = getreal(11);
1464 poly[3] += (ph1.tag_210 - poly[7]) * poly[6] + 1;
1465 for (i=0; i < 0x10000; i++) {
1466 num = (poly[5]*i + poly[3])*i + poly[1];
1467 curve[i] = LIM(num,0,65535);
1468 } goto apply; /* apply to right half */
1469 } else if (tag == 0x41a) { /* Polynomial curve */
1470 for (i=0; i < 4; i++)
1471 poly[i] = getreal(11);
1472 for (i=0; i < 0x10000; i++) {
1473 for (num=0, j=4; j--; )
1474 num = num * i + poly[j];
1475 curve[i] = LIM(num+i,0,65535);
1476 } apply: /* apply to whole image */
1477 for (row=0; row < raw_height; row++)
1478 for (col = (tag & 1)*ph1.split_col; col < raw_width; col++)
1479 RAW(row,col) = curve[RAW(row,col)];
1480 } else if (tag == 0x400) { /* Sensor defects */
1481 while ((len -= 8) >= 0) {
1484 type = get2(); get2();
1485 if (col >= raw_width) continue;
1486 if (type == 131 || type == 137) /* Bad column */
1487 for (row=0; row < raw_height; row++)
1488 if (FC(row-top_margin,col-left_margin) == 1) {
1489 for (sum=i=0; i < 4; i++)
1490 sum += val[i] = raw (row+dir[i][0], col+dir[i][1]);
1491 for (max=i=0; i < 4; i++) {
1492 dev[i] = abs((val[i] << 2) - sum);
1493 if (dev[max] < dev[i]) max = i;
1495 RAW(row,col) = (sum - val[max])/3.0 + 0.5;
1497 for (sum=0, i=8; i < 12; i++)
1498 sum += raw (row+dir[i][0], col+dir[i][1]);
1499 RAW(row,col) = 0.5 + sum * 0.0732233 +
1500 (raw(row,col-2) + raw(row,col+2)) * 0.3535534;
1502 else if (type == 129) { /* Bad pixel */
1503 if (row >= raw_height) continue;
1504 j = (FC(row-top_margin,col-left_margin) != 1) * 4;
1505 for (sum=0, i=j; i < j+8; i++)
1506 sum += raw (row+dir[i][0], col+dir[i][1]);
1507 RAW(row,col) = (sum + 4) >> 3;
1510 } else if (tag == 0x401) { /* All-color flat fields */
1511 phase_one_flat_field (1, 2);
1512 } else if (tag == 0x416 || tag == 0x410) {
1513 phase_one_flat_field (0, 2);
1514 } else if (tag == 0x40b) { /* Red+blue flat field */
1515 phase_one_flat_field (0, 4);
1516 } else if (tag == 0x412) {
1517 fseek (ifp, 36, SEEK_CUR);
1518 diff = abs (get2() - ph1.tag_21a);
1519 if (mindiff > diff) {
1521 off_412 = ftell(ifp) - 38;
1523 } else if (tag == 0x41f && !qlin_applied) { /* Quadrant linearization */
1524 ushort lc[2][2][16], ref[16];
1526 for (qr = 0; qr < 2; qr++)
1527 for (qc = 0; qc < 2; qc++)
1528 for (i = 0; i < 16; i++)
1529 lc[qr][qc][i] = get4();
1530 for (i = 0; i < 16; i++) {
1532 for (qr = 0; qr < 2; qr++)
1533 for (qc = 0; qc < 2; qc++)
1535 ref[i] = (v + 2) >> 2;
1537 for (qr = 0; qr < 2; qr++) {
1538 for (qc = 0; qc < 2; qc++) {
1540 for (i = 0; i < 16; i++) {
1541 cx[1+i] = lc[qr][qc][i];
1545 cx[17] = cf[17] = ((unsigned) ref[15] * 65535) / lc[qr][qc][15];
1546 cx[18] = cf[18] = 65535;
1547 cubic_spline(cx, cf, 19);
1548 for (row = (qr ? ph1.split_row : 0);
1549 row < (qr ? raw_height : ph1.split_row); row++)
1550 for (col = (qc ? ph1.split_col : 0);
1551 col < (qc ? raw_width : ph1.split_col); col++)
1552 RAW(row,col) = curve[RAW(row,col)];
1556 } else if (tag == 0x41e && !qmult_applied) { /* Quadrant multipliers */
1557 float qmult[2][2] = { { 1, 1 }, { 1, 1 } };
1558 get4(); get4(); get4(); get4();
1559 qmult[0][0] = 1.0 + getreal(11);
1560 get4(); get4(); get4(); get4(); get4();
1561 qmult[0][1] = 1.0 + getreal(11);
1562 get4(); get4(); get4();
1563 qmult[1][0] = 1.0 + getreal(11);
1564 get4(); get4(); get4();
1565 qmult[1][1] = 1.0 + getreal(11);
1566 for (row=0; row < raw_height; row++)
1567 for (col=0; col < raw_width; col++) {
1568 i = qmult[row >= ph1.split_row][col >= ph1.split_col] * RAW(row,col);
1569 RAW(row,col) = LIM(i,0,65535);
1572 } else if (tag == 0x431 && !qmult_applied) { /* Quadrant combined */
1573 ushort lc[2][2][7], ref[7];
1575 for (i = 0; i < 7; i++)
1577 for (qr = 0; qr < 2; qr++)
1578 for (qc = 0; qc < 2; qc++)
1579 for (i = 0; i < 7; i++)
1580 lc[qr][qc][i] = get4();
1581 for (qr = 0; qr < 2; qr++) {
1582 for (qc = 0; qc < 2; qc++) {
1584 for (i = 0; i < 7; i++) {
1586 cf[1+i] = ((unsigned) ref[i] * lc[qr][qc][i]) / 10000;
1589 cx[8] = cf[8] = 65535;
1590 cubic_spline(cx, cf, 9);
1591 for (row = (qr ? ph1.split_row : 0);
1592 row < (qr ? raw_height : ph1.split_row); row++)
1593 for (col = (qc ? ph1.split_col : 0);
1594 col < (qc ? raw_width : ph1.split_col); col++)
1595 RAW(row,col) = curve[RAW(row,col)];
1601 fseek (ifp, save, SEEK_SET);
1604 fseek (ifp, off_412, SEEK_SET);
1605 for (i=0; i < 9; i++) head[i] = get4() & 0x7fff;
1606 yval[0] = (float *) calloc (head[1]*head[3] + head[2]*head[4], 6);
1607 merror (yval[0], "phase_one_correct()");
1608 yval[1] = (float *) (yval[0] + head[1]*head[3]);
1609 xval[0] = (ushort *) (yval[1] + head[2]*head[4]);
1610 xval[1] = (ushort *) (xval[0] + head[1]*head[3]);
1612 for (i=0; i < 2; i++)
1613 for (j=0; j < head[i+1]*head[i+3]; j++)
1614 yval[i][j] = getreal(11);
1615 for (i=0; i < 2; i++)
1616 for (j=0; j < head[i+1]*head[i+3]; j++)
1617 xval[i][j] = get2();
1618 for (row=0; row < raw_height; row++)
1619 for (col=0; col < raw_width; col++) {
1620 cfrac = (float) col * head[3] / raw_width;
1621 cfrac -= cip = cfrac;
1622 num = RAW(row,col) * 0.5;
1623 for (i=cip; i < cip+2; i++) {
1624 for (k=j=0; j < head[1]; j++)
1625 if (num < xval[0][k = head[1]*i+j]) break;
1626 frac = (j == 0 || j == head[1]) ? 0 :
1627 (xval[0][k] - num) / (xval[0][k] - xval[0][k-1]);
1628 mult[i-cip] = yval[0][k-1] * frac + yval[0][k] * (1-frac);
1630 i = ((mult[0] * (1-cfrac) + mult[1] * cfrac) * row + num) * 2;
1631 RAW(row,col) = LIM(i,0,65535);
1637 void CLASS phase_one_load_raw()
1640 ushort akey, bkey, mask;
1642 fseek (ifp, ph1.key_off, SEEK_SET);
1645 mask = ph1.format == 1 ? 0x5555:0x1354;
1646 fseek (ifp, data_offset, SEEK_SET);
1647 read_shorts (raw_image, raw_width*raw_height);
1649 for (i=0; i < raw_width*raw_height; i+=2) {
1650 a = raw_image[i+0] ^ akey;
1651 b = raw_image[i+1] ^ bkey;
1652 raw_image[i+0] = (a & mask) | (b & ~mask);
1653 raw_image[i+1] = (b & mask) | (a & ~mask);
1657 unsigned CLASS ph1_bithuff (int nbits, ushort *huff)
1664 return ph1_bitbuf = ph1_vbits = 0;
1665 if (nbits == 0) return 0;
1666 bitbuf = ph1_bitbuf; vbits = ph1_vbits;
1667 if (vbits < nbits) {
1668 bitbuf = bitbuf << 32 | get4();
1671 c = bitbuf << (64-vbits) >> (64-nbits);
1673 nbits = huff[c] >> 8;
1674 c = (uchar) huff[c];
1677 ph1_bitbuf = bitbuf; ph1_vbits = vbits;
1680 #define ph1_bits(n) ph1_bithuff(n,0)
1681 #define ph1_huff(h) ph1_bithuff(*h,h+1)
1683 void CLASS phase_one_load_raw_c()
1685 static const int length[] = { 8,7,6,9,11,10,5,12,14,13 };
1686 int *offset, len[2], pred[2], row, col, i, j;
1688 short (*cblack)[2], (*rblack)[2];
1690 pixel = (ushort *) calloc (raw_width*3 + raw_height*4, 2);
1691 merror (pixel, "phase_one_load_raw_c()");
1692 offset = (int *) (pixel + raw_width);
1693 fseek (ifp, strip_offset, SEEK_SET);
1694 for (row=0; row < raw_height; row++)
1695 offset[row] = get4();
1696 cblack = (short (*)[2]) (offset + raw_height);
1697 fseek (ifp, ph1.black_col, SEEK_SET);
1699 read_shorts ((ushort *) cblack[0], raw_height*2);
1700 rblack = cblack + raw_height;
1701 fseek (ifp, ph1.black_row, SEEK_SET);
1703 read_shorts ((ushort *) rblack[0], raw_width*2);
1704 for (i=0; i < 256; i++)
1705 curve[i] = i*i / 3.969 + 0.5;
1706 for (row=0; row < raw_height; row++) {
1707 fseek (ifp, data_offset + offset[row], SEEK_SET);
1709 pred[0] = pred[1] = 0;
1710 for (col=0; col < raw_width; col++) {
1711 if (col >= (raw_width & -8))
1712 len[0] = len[1] = 14;
1713 else if ((col & 7) == 0)
1714 for (i=0; i < 2; i++) {
1715 for (j=0; j < 5 && !ph1_bits(1); j++);
1716 if (j--) len[i] = length[j*2 + ph1_bits(1)];
1718 if ((i = len[col & 1]) == 14)
1719 pixel[col] = pred[col & 1] = ph1_bits(16);
1721 pixel[col] = pred[col & 1] += ph1_bits(i) + 1 - (1 << (i - 1));
1722 if (pred[col & 1] >> 16) derror();
1723 if (ph1.format == 5 && pixel[col] < 256)
1724 pixel[col] = curve[pixel[col]];
1726 for (col=0; col < raw_width; col++) {
1727 i = (pixel[col] << 2*(ph1.format != 8)) - ph1.black
1728 + cblack[row][col >= ph1.split_col]
1729 + rblack[col][row >= ph1.split_row];
1730 if (i > 0) RAW(row,col) = i;
1734 maximum = 0xfffc - ph1.black;
1737 void CLASS hasselblad_load_raw()
1740 int shot, row, col, *back[5], len[2], diff[12], pred, sh, f, s, c;
1741 unsigned upix, urow, ucol;
1744 if (!ljpeg_start (&jh, 0)) return;
1747 back[4] = (int *) calloc (raw_width, 3*sizeof **back);
1748 merror (back[4], "hasselblad_load_raw()");
1749 FORC3 back[c] = back[4] + c*raw_width;
1750 cblack[6] >>= sh = tiff_samples > 1;
1751 shot = LIM(shot_select, 1, tiff_samples) - 1;
1752 for (row=0; row < raw_height; row++) {
1753 FORC4 back[(c+3) & 3] = back[c];
1754 for (col=0; col < raw_width; col+=2) {
1755 for (s=0; s < tiff_samples*2; s+=2) {
1756 FORC(2) len[c] = ph1_huff(jh.huff[0]);
1758 diff[s+c] = ph1_bits(len[c]);
1759 if ((diff[s+c] & (1 << (len[c]-1))) == 0)
1760 diff[s+c] -= (1 << len[c]) - 1;
1761 if (diff[s+c] == 65535) diff[s+c] = -32768;
1764 for (s=col; s < col+2; s++) {
1765 pred = 0x8000 + load_flags;
1766 if (col) pred = back[2][s-2];
1767 if (col && row > 1) switch (jh.psv) {
1768 case 11: pred += back[0][s]/2 - back[0][s-2]/2; break;
1770 f = (row & 1)*3 ^ ((col+s) & 1);
1771 FORC (tiff_samples) {
1772 pred += diff[(s & 1)*tiff_samples+c];
1773 upix = pred >> sh & 0xffff;
1774 if (raw_image && c == shot)
1777 urow = row-top_margin + (c & 1);
1778 ucol = col-left_margin - ((c >> 1) & 1);
1779 ip = &image[urow*width+ucol][f];
1780 if (urow < height && ucol < width)
1781 *ip = c < 4 ? upix : (*ip + upix) >> 1;
1790 if (image) mix_green = 1;
1793 void CLASS leaf_hdr_load_raw()
1796 unsigned tile=0, r, c, row, col;
1799 pixel = (ushort *) calloc (raw_width, sizeof *pixel);
1800 merror (pixel, "leaf_hdr_load_raw()");
1803 for (r=0; r < raw_height; r++) {
1804 if (r % tile_length == 0) {
1805 fseek (ifp, data_offset + 4*tile++, SEEK_SET);
1806 fseek (ifp, get4(), SEEK_SET);
1808 if (filters && c != shot_select) continue;
1809 if (filters) pixel = raw_image + r*raw_width;
1810 read_shorts (pixel, raw_width);
1811 if (!filters && (row = r - top_margin) < height)
1812 for (col=0; col < width; col++)
1813 image[row*width+col][c] = pixel[col+left_margin];
1822 void CLASS unpacked_load_raw()
1824 int row, col, bits=0;
1826 while (1 << ++bits < maximum);
1827 read_shorts (raw_image, raw_width*raw_height);
1828 for (row=0; row < raw_height; row++)
1829 for (col=0; col < raw_width; col++)
1830 if ((RAW(row,col) >>= load_flags) >> bits
1831 && (unsigned) (row-top_margin) < height
1832 && (unsigned) (col-left_margin) < width) derror();
1835 void CLASS sinar_4shot_load_raw()
1838 unsigned shot, row, col, r, c;
1841 shot = LIM (shot_select, 1, 4) - 1;
1842 fseek (ifp, data_offset + shot*4, SEEK_SET);
1843 fseek (ifp, get4(), SEEK_SET);
1844 unpacked_load_raw();
1847 pixel = (ushort *) calloc (raw_width, sizeof *pixel);
1848 merror (pixel, "sinar_4shot_load_raw()");
1849 for (shot=0; shot < 4; shot++) {
1850 fseek (ifp, data_offset + shot*4, SEEK_SET);
1851 fseek (ifp, get4(), SEEK_SET);
1852 for (row=0; row < raw_height; row++) {
1853 read_shorts (pixel, raw_width);
1854 if ((r = row-top_margin - (shot >> 1 & 1)) >= height) continue;
1855 for (col=0; col < raw_width; col++) {
1856 if ((c = col-left_margin - (shot & 1)) >= width) continue;
1857 image[r*width+c][(row & 1)*3 ^ (~col & 1)] = pixel[col];
1865 void CLASS imacon_full_load_raw()
1870 for (row=0; row < height; row++)
1871 for (col=0; col < width; col++)
1872 read_shorts (image[row*width+col], 3);
1875 void CLASS packed_load_raw()
1877 int vbits=0, bwide, rbits, bite, half, irow, row, col, val, i;
1880 bwide = raw_width * tiff_bps / 8;
1881 bwide += bwide & load_flags >> 7;
1882 rbits = bwide * 8 - raw_width * tiff_bps;
1883 if (load_flags & 1) bwide = bwide * 16 / 15;
1884 bite = 8 + (load_flags & 24);
1885 half = (raw_height+1) >> 1;
1886 for (irow=0; irow < raw_height; irow++) {
1888 if (load_flags & 2 &&
1889 (row = irow % half * 2 + irow / half) == 1 &&
1891 if (vbits=0, tiff_compress)
1892 fseek (ifp, data_offset - (-half*bwide & -2048), SEEK_SET);
1894 fseek (ifp, 0, SEEK_END);
1895 fseek (ifp, ftell(ifp) >> 3 << 2, SEEK_SET);
1898 for (col=0; col < raw_width; col++) {
1899 for (vbits -= tiff_bps; vbits < 0; vbits += bite) {
1901 for (i=0; i < bite; i+=8)
1902 bitbuf |= (unsigned) (fgetc(ifp) << i);
1904 val = bitbuf << (64-tiff_bps-vbits) >> (64-tiff_bps);
1905 RAW(row,col ^ (load_flags >> 6 & 1)) = val;
1906 if (load_flags & 1 && (col % 10) == 9 && fgetc(ifp) &&
1907 row < height+top_margin && col < width+left_margin) derror();
1913 void CLASS nokia_load_raw()
1916 int rev, dwide, row, col, c;
1919 rev = 3 * (order == 0x4949);
1920 dwide = (raw_width * 5 + 1) / 4;
1921 data = (uchar *) malloc (dwide*2);
1922 merror (data, "nokia_load_raw()");
1923 for (row=0; row < raw_height; row++) {
1924 if (fread (data+dwide, 1, dwide, ifp) < dwide) derror();
1925 FORC(dwide) data[c] = data[dwide+(c ^ rev)];
1926 for (dp=data, col=0; col < raw_width; dp+=5, col+=4)
1927 FORC4 RAW(row,col+c) = (dp[c] << 2) | (dp[4] >> (c << 1) & 3);
1931 if (strcmp(make,"OmniVision")) return;
1934 sum[ c & 1] += SQR(RAW(row,c)-RAW(row+1,c+1));
1935 sum[~c & 1] += SQR(RAW(row+1,c)-RAW(row,c+1));
1937 if (sum[1] > sum[0]) filters = 0x4b4b4b4b;
1940 void CLASS canon_rmf_load_raw()
1942 int row, col, bits, orow, ocol, c;
1944 for (row=0; row < raw_height; row++)
1945 for (col=0; col < raw_width-2; col+=3) {
1949 if ((ocol = col+c-4) < 0) {
1951 if ((orow -= 2) < 0)
1954 RAW(orow,ocol) = curve[bits >> (10*c+2) & 0x3ff];
1957 maximum = curve[0x3ff];
1960 unsigned CLASS pana_bits (int nbits)
1962 uchar *buf = pana_buf;
1963 int vbits = pana_vbits;
1966 if (!nbits) return pana_vbits=0;
1968 fread (buf+load_flags, 1, 0x4000-load_flags, ifp);
1969 fread (buf, 1, load_flags, ifp);
1971 vbits = (vbits - nbits) & 0x1ffff;
1972 byte = vbits >> 3 ^ 0x3ff0;
1974 return (buf[byte] | buf[byte+1] << 8) >> (vbits & 7) & ~(-1 << nbits);
1977 void CLASS panasonic_load_raw()
1979 int row, col, i, j, sh=0, pred[2], nonz[2];
1982 for (row=0; row < height; row++)
1983 for (col=0; col < raw_width; col++) {
1984 if ((i = col % 14) == 0)
1985 pred[0] = pred[1] = nonz[0] = nonz[1] = 0;
1986 if (i % 3 == 2) sh = 4 >> (3 - pana_bits(2));
1988 if ((j = pana_bits(8))) {
1989 if ((pred[i & 1] -= 0x80 << sh) < 0 || sh == 4)
1990 pred[i & 1] &= ~(-1 << sh);
1991 pred[i & 1] += j << sh;
1993 } else if ((nonz[i & 1] = pana_bits(8)) || i > 11)
1994 pred[i & 1] = nonz[i & 1] << 4 | pana_bits(4);
1995 if ((RAW(row,col) = pred[col & 1]) > 4098 && col < width) derror();
1999 void CLASS olympus_load_raw()
2002 int row, col, nbits, sign, low, high, i, c, w, n, nw;
2003 int acarry[2][3], *carry, pred, diff;
2007 FORC(2048 >> i) huff[++n] = (i+1) << 8 | i;
2008 fseek (ifp, 7, SEEK_CUR);
2010 for (row=0; row < height; row++) {
2011 memset (acarry, 0, sizeof acarry);
2012 for (col=0; col < raw_width; col++) {
2013 carry = acarry[col & 1];
2014 i = 2 * (carry[2] < 3);
2015 for (nbits=2+i; (ushort) carry[0] >> (nbits+i); nbits++);
2016 low = (sign = getbits(3)) & 3;
2017 sign = sign << 29 >> 31;
2018 if ((high = getbithuff(12,huff)) == 12)
2019 high = getbits(16-nbits) >> 1;
2020 carry[0] = (high << nbits) | getbits(nbits);
2021 diff = (carry[0] ^ sign) + carry[1];
2022 carry[1] = (diff*3 + carry[1]) >> 5;
2023 carry[2] = carry[0] > 16 ? 0 : carry[2]+1;
2024 if (col >= width) continue;
2025 if (row < 2 && col < 2) pred = 0;
2026 else if (row < 2) pred = RAW(row,col-2);
2027 else if (col < 2) pred = RAW(row-2,col);
2031 nw = RAW(row-2,col-2);
2032 if ((w < nw && nw < n) || (n < nw && nw < w)) {
2033 if (ABS(w-nw) > 32 || ABS(n-nw) > 32)
2035 else pred = (w + n) >> 1;
2036 } else pred = ABS(w-nw) > ABS(n-nw) ? w : n;
2038 if ((RAW(row,col) = pred + ((diff << 2) | low)) >> 12) derror();
2043 void CLASS minolta_rd175_load_raw()
2046 unsigned irow, box, row, col;
2048 for (irow=0; irow < 1481; irow++) {
2049 if (fread (pixel, 1, 768, ifp) < 768) derror();
2051 row = irow % 82 * 12 + ((box < 12) ? box | 1 : (box-12)*2);
2053 case 1477: case 1479: continue;
2054 case 1476: row = 984; break;
2055 case 1480: row = 985; break;
2056 case 1478: row = 985; box = 1;
2058 if ((box < 12) && (box & 1)) {
2059 for (col=0; col < 1533; col++, row ^= 1)
2060 if (col != 1) RAW(row,col) = (col+1) & 2 ?
2061 pixel[col/2-1] + pixel[col/2+1] : pixel[col/2] << 1;
2062 RAW(row,1) = pixel[1] << 1;
2063 RAW(row,1533) = pixel[765] << 1;
2065 for (col=row & 1; col < 1534; col+=2)
2066 RAW(row,col) = pixel[col/2] << 1;
2068 maximum = 0xff << 1;
2071 void CLASS quicktake_100_load_raw()
2073 uchar pixel[484][644];
2074 static const short gstep[16] =
2075 { -89,-60,-44,-32,-22,-15,-8,-2,2,8,15,22,32,44,60,89 };
2076 static const short rstep[6][4] =
2077 { { -3,-1,1,3 }, { -5,-1,1,5 }, { -8,-2,2,8 },
2078 { -13,-3,3,13 }, { -19,-4,4,19 }, { -28,-6,6,28 } };
2079 static const short curve[256] =
2080 { 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,
2081 28,29,30,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,53,
2082 54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,74,75,76,77,78,
2083 79,80,81,82,83,84,86,88,90,92,94,97,99,101,103,105,107,110,112,114,116,
2084 118,120,123,125,127,129,131,134,136,138,140,142,144,147,149,151,153,155,
2085 158,160,162,164,166,168,171,173,175,177,179,181,184,186,188,190,192,195,
2086 197,199,201,203,205,208,210,212,214,216,218,221,223,226,230,235,239,244,
2087 248,252,257,261,265,270,274,278,283,287,291,296,300,305,309,313,318,322,
2088 326,331,335,339,344,348,352,357,361,365,370,374,379,383,387,392,396,400,
2089 405,409,413,418,422,426,431,435,440,444,448,453,457,461,466,470,474,479,
2090 483,487,492,496,500,508,519,531,542,553,564,575,587,598,609,620,631,643,
2091 654,665,676,687,698,710,721,732,743,754,766,777,788,799,810,822,833,844,
2092 855,866,878,889,900,911,922,933,945,956,967,978,989,1001,1012,1023 };
2093 int rb, row, col, sharp, val=0;
2096 memset (pixel, 0x80, sizeof pixel);
2097 for (row=2; row < height+2; row++) {
2098 for (col=2+(row & 1); col < width+2; col+=2) {
2099 val = ((pixel[row-1][col-1] + 2*pixel[row-1][col+1] +
2100 pixel[row][col-2]) >> 2) + gstep[getbits(4)];
2101 pixel[row][col] = val = LIM(val,0,255);
2103 pixel[row][col-2] = pixel[row+1][~row & 1] = val;
2105 pixel[row-1][col+1] = pixel[row-1][col+3] = val;
2107 pixel[row][col] = val;
2109 for (rb=0; rb < 2; rb++)
2110 for (row=2+rb; row < height+2; row+=2)
2111 for (col=3-(row & 1); col < width+2; col+=2) {
2112 if (row < 4 || col < 4) sharp = 2;
2114 val = ABS(pixel[row-2][col] - pixel[row][col-2])
2115 + ABS(pixel[row-2][col] - pixel[row-2][col-2])
2116 + ABS(pixel[row][col-2] - pixel[row-2][col-2]);
2117 sharp = val < 4 ? 0 : val < 8 ? 1 : val < 16 ? 2 :
2118 val < 32 ? 3 : val < 48 ? 4 : 5;
2120 val = ((pixel[row-2][col] + pixel[row][col-2]) >> 1)
2121 + rstep[sharp][getbits(2)];
2122 pixel[row][col] = val = LIM(val,0,255);
2123 if (row < 4) pixel[row-2][col+2] = val;
2124 if (col < 4) pixel[row+2][col-2] = val;
2126 for (row=2; row < height+2; row++)
2127 for (col=3-(row & 1); col < width+2; col+=2) {
2128 val = ((pixel[row][col-1] + (pixel[row][col] << 2) +
2129 pixel[row][col+1]) >> 1) - 0x100;
2130 pixel[row][col] = LIM(val,0,255);
2132 for (row=0; row < height; row++)
2133 for (col=0; col < width; col++)
2134 RAW(row,col) = curve[pixel[row+2][col+2]];
2138 #define radc_token(tree) ((signed char) getbithuff(8,huff[tree]))
2140 #define FORYX for (y=1; y < 3; y++) for (x=col+1; x >= col; x--)
2142 #define PREDICTOR (c ? (buf[c][y-1][x] + buf[c][y][x+1]) / 2 \
2143 : (buf[c][y-1][x+1] + 2*buf[c][y-1][x] + buf[c][y][x+1]) / 4)
2145 void CLASS kodak_radc_load_raw()
2147 static const char src[] = {
2148 1,1, 2,3, 3,4, 4,2, 5,7, 6,5, 7,6, 7,8,
2149 1,0, 2,1, 3,3, 4,4, 5,2, 6,7, 7,6, 8,5, 8,8,
2150 2,1, 2,3, 3,0, 3,2, 3,4, 4,6, 5,5, 6,7, 6,8,
2151 2,0, 2,1, 2,3, 3,2, 4,4, 5,6, 6,7, 7,5, 7,8,
2152 2,1, 2,4, 3,0, 3,2, 3,3, 4,7, 5,5, 6,6, 6,8,
2153 2,3, 3,1, 3,2, 3,4, 3,5, 3,6, 4,7, 5,0, 5,8,
2154 2,3, 2,6, 3,0, 3,1, 4,4, 4,5, 4,7, 5,2, 5,8,
2155 2,4, 2,7, 3,3, 3,6, 4,1, 4,2, 4,5, 5,0, 5,8,
2156 2,6, 3,1, 3,3, 3,5, 3,7, 3,8, 4,0, 5,2, 5,4,
2157 2,0, 2,1, 3,2, 3,3, 4,4, 4,5, 5,6, 5,7, 4,8,
2160 2,-17, 2,-5, 2,5, 2,17,
2161 2,-7, 2,2, 2,9, 2,18,
2162 2,-18, 2,-9, 2,-2, 2,7,
2163 2,-28, 2,28, 3,-49, 3,-9, 3,9, 4,49, 5,-79, 5,79,
2164 2,-1, 2,13, 2,26, 3,39, 4,-16, 5,55, 6,-37, 6,76,
2165 2,-26, 2,-13, 2,1, 3,-39, 4,16, 5,-55, 6,-76, 6,37
2167 ushort huff[19][256];
2168 int row, col, tree, nreps, rep, step, i, c, s, r, x, y, val;
2169 short last[3] = { 16,16,16 }, mul[3], buf[3][3][386];
2170 static const ushort pt[] =
2171 { 0,0, 1280,1344, 2320,3616, 3328,8000, 4095,16383, 65535,16383 };
2173 for (i=2; i < 12; i+=2)
2174 for (c=pt[i-2]; c <= pt[i]; c++)
2176 (c-pt[i-2]) / (pt[i]-pt[i-2]) * (pt[i+1]-pt[i-1]) + pt[i-1] + 0.5;
2177 for (s=i=0; i < sizeof src; i+=2)
2179 ((ushort *)huff)[s++] = src[i] << 8 | (uchar) src[i+1];
2180 s = kodak_cbpp == 243 ? 2 : 3;
2181 FORC(256) huff[18][c] = (8-s) << 8 | c >> s << s | 1 << (s-1);
2183 for (i=0; i < sizeof(buf)/sizeof(short); i++)
2184 ((short *)buf)[i] = 2048;
2185 for (row=0; row < height; row+=4) {
2186 FORC3 mul[c] = getbits(6);
2188 val = ((0x1000000/last[c] + 0x7ff) >> 12) * mul[c];
2189 s = val > 65564 ? 10:12;
2192 for (i=0; i < sizeof(buf[0])/sizeof(short); i++)
2193 ((short *)buf[c])[i] = (((short *)buf[c])[i] * val + x) >> s;
2195 for (r=0; r <= !c; r++) {
2196 buf[c][1][width/2] = buf[c][2][width/2] = mul[c] << 7;
2197 for (tree=1, col=width/2; col > 0; ) {
2198 if ((tree = radc_token(tree))) {
2201 FORYX buf[c][y][x] = (uchar) radc_token(18) * mul[c];
2203 FORYX buf[c][y][x] = radc_token(tree+10) * 16 + PREDICTOR;
2206 nreps = (col > 2) ? radc_token(9) + 1 : 1;
2207 for (rep=0; rep < 8 && rep < nreps && col > 0; rep++) {
2209 FORYX buf[c][y][x] = PREDICTOR;
2211 step = radc_token(10) << 4;
2212 FORYX buf[c][y][x] += step;
2215 } while (nreps == 9);
2217 for (y=0; y < 2; y++)
2218 for (x=0; x < width/2; x++) {
2219 val = (buf[c][y+1][x] << 4) / mul[c];
2220 if (val < 0) val = 0;
2221 if (c) RAW(row+y*2+c-1,x*2+2-c) = val;
2222 else RAW(row+r*2+y,x*2+y) = val;
2224 memcpy (buf[c][0]+!c, buf[c][2], sizeof buf[c][0]-2*!c);
2227 for (y=row; y < row+4; y++)
2228 for (x=0; x < width; x++)
2231 s = x+1 < width ? x+1 : x-1;
2232 val = (RAW(y,x)-2048)*2 + (RAW(y,r)+RAW(y,s))/2;
2233 if (val < 0) val = 0;
2237 for (i=0; i < height*width; i++)
2238 raw_image[i] = curve[raw_image[i]];
2246 void CLASS kodak_jpeg_load_raw() {}
2247 void CLASS lossy_dng_load_raw() {}
2251 fill_input_buffer (j_decompress_ptr cinfo)
2253 static uchar jpeg_buffer[4096];
2256 nbytes = fread (jpeg_buffer, 1, 4096, ifp);
2257 swab (jpeg_buffer, jpeg_buffer, nbytes);
2258 cinfo->src->next_input_byte = jpeg_buffer;
2259 cinfo->src->bytes_in_buffer = nbytes;
2263 void CLASS kodak_jpeg_load_raw()
2265 struct jpeg_decompress_struct cinfo;
2266 struct jpeg_error_mgr jerr;
2268 JSAMPLE (*pixel)[3];
2271 cinfo.err = jpeg_std_error (&jerr);
2272 jpeg_create_decompress (&cinfo);
2273 jpeg_stdio_src (&cinfo, ifp);
2274 cinfo.src->fill_input_buffer = fill_input_buffer;
2275 jpeg_read_header (&cinfo, TRUE);
2276 jpeg_start_decompress (&cinfo);
2277 if ((cinfo.output_width != width ) ||
2278 (cinfo.output_height*2 != height ) ||
2279 (cinfo.output_components != 3 )) {
2280 fprintf (stderr,_("%s: incorrect JPEG dimensions\n"), ifname);
2281 jpeg_destroy_decompress (&cinfo);
2282 longjmp (failure, 3);
2284 buf = (*cinfo.mem->alloc_sarray)
2285 ((j_common_ptr) &cinfo, JPOOL_IMAGE, width*3, 1);
2287 while (cinfo.output_scanline < cinfo.output_height) {
2288 row = cinfo.output_scanline * 2;
2289 jpeg_read_scanlines (&cinfo, buf, 1);
2290 pixel = (JSAMPLE (*)[3]) buf[0];
2291 for (col=0; col < width; col+=2) {
2292 RAW(row+0,col+0) = pixel[col+0][1] << 1;
2293 RAW(row+1,col+1) = pixel[col+1][1] << 1;
2294 RAW(row+0,col+1) = pixel[col][0] + pixel[col+1][0];
2295 RAW(row+1,col+0) = pixel[col][2] + pixel[col+1][2];
2298 jpeg_finish_decompress (&cinfo);
2299 jpeg_destroy_decompress (&cinfo);
2300 maximum = 0xff << 1;
2303 void CLASS gamma_curve (double pwr, double ts, int mode, int imax);
2305 void CLASS lossy_dng_load_raw()
2307 struct jpeg_decompress_struct cinfo;
2308 struct jpeg_error_mgr jerr;
2310 JSAMPLE (*pixel)[3];
2311 unsigned sorder=order, ntags, opcode, deg, i, j, c;
2312 unsigned save=data_offset-4, trow=0, tcol=0, row, col;
2314 double coeff[9], tot;
2317 fseek (ifp, meta_offset, SEEK_SET);
2321 opcode = get4(); get4(); get4();
2323 { fseek (ifp, get4(), SEEK_CUR); continue; }
2324 fseek (ifp, 20, SEEK_CUR);
2325 if ((c = get4()) > 2) break;
2326 fseek (ifp, 12, SEEK_CUR);
2327 if ((deg = get4()) > 8) break;
2328 for (i=0; i <= deg && i < 9; i++)
2329 coeff[i] = getreal(12);
2330 for (i=0; i < 256; i++) {
2331 for (tot=j=0; j <= deg; j++)
2332 tot += coeff[j] * pow(i/255.0, j);
2333 cur[c][i] = tot*0xffff;
2338 gamma_curve (1/2.4, 12.92, 1, 255);
2339 FORC3 memcpy (cur[c], curve, sizeof cur[0]);
2341 cinfo.err = jpeg_std_error (&jerr);
2342 jpeg_create_decompress (&cinfo);
2343 while (trow < raw_height) {
2344 fseek (ifp, save+=4, SEEK_SET);
2345 if (tile_length < INT_MAX)
2346 fseek (ifp, get4(), SEEK_SET);
2347 jpeg_stdio_src (&cinfo, ifp);
2348 jpeg_read_header (&cinfo, TRUE);
2349 jpeg_start_decompress (&cinfo);
2350 buf = (*cinfo.mem->alloc_sarray)
2351 ((j_common_ptr) &cinfo, JPOOL_IMAGE, cinfo.output_width*3, 1);
2352 while (cinfo.output_scanline < cinfo.output_height &&
2353 (row = trow + cinfo.output_scanline) < height) {
2354 jpeg_read_scanlines (&cinfo, buf, 1);
2355 pixel = (JSAMPLE (*)[3]) buf[0];
2356 for (col=0; col < cinfo.output_width && tcol+col < width; col++) {
2357 FORC3 image[row*width+tcol+col][c] = cur[c][pixel[col][c]];
2360 jpeg_abort_decompress (&cinfo);
2361 if ((tcol += tile_width) >= raw_width)
2362 trow += tile_length + (tcol = 0);
2364 jpeg_destroy_decompress (&cinfo);
2369 void CLASS kodak_dc120_load_raw()
2371 static const int mul[4] = { 162, 192, 187, 92 };
2372 static const int add[4] = { 0, 636, 424, 212 };
2374 int row, shift, col;
2376 for (row=0; row < height; row++) {
2377 if (fread (pixel, 1, 848, ifp) < 848) derror();
2378 shift = row * mul[row & 3] + add[row & 3];
2379 for (col=0; col < width; col++)
2380 RAW(row,col) = (ushort) pixel[(col + shift) % 848];
2385 void CLASS eight_bit_load_raw()
2390 pixel = (uchar *) calloc (raw_width, sizeof *pixel);
2391 merror (pixel, "eight_bit_load_raw()");
2392 for (row=0; row < raw_height; row++) {
2393 if (fread (pixel, 1, raw_width, ifp) < raw_width) derror();
2394 for (col=0; col < raw_width; col++)
2395 RAW(row,col) = curve[pixel[col]];
2398 maximum = curve[0xff];
2401 void CLASS kodak_c330_load_raw()
2404 int row, col, y, cb, cr, rgb[3], c;
2406 pixel = (uchar *) calloc (raw_width, 2*sizeof *pixel);
2407 merror (pixel, "kodak_c330_load_raw()");
2408 for (row=0; row < height; row++) {
2409 if (fread (pixel, raw_width, 2, ifp) < 2) derror();
2410 if (load_flags && (row & 31) == 31)
2411 fseek (ifp, raw_width*32, SEEK_CUR);
2412 for (col=0; col < width; col++) {
2414 cb = pixel[(col*2 & -4) | 1] - 128;
2415 cr = pixel[(col*2 & -4) | 3] - 128;
2416 rgb[1] = y - ((cb + cr + 2) >> 2);
2417 rgb[2] = rgb[1] + cb;
2418 rgb[0] = rgb[1] + cr;
2419 FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,255)];
2423 maximum = curve[0xff];
2426 void CLASS kodak_c603_load_raw()
2429 int row, col, y, cb, cr, rgb[3], c;
2431 pixel = (uchar *) calloc (raw_width, 3*sizeof *pixel);
2432 merror (pixel, "kodak_c603_load_raw()");
2433 for (row=0; row < height; row++) {
2435 if (fread (pixel, raw_width, 3, ifp) < 3) derror();
2436 for (col=0; col < width; col++) {
2437 y = pixel[width*2*(row & 1) + col];
2438 cb = pixel[width + (col & -2)] - 128;
2439 cr = pixel[width + (col & -2)+1] - 128;
2440 rgb[1] = y - ((cb + cr + 2) >> 2);
2441 rgb[2] = rgb[1] + cb;
2442 rgb[0] = rgb[1] + cr;
2443 FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,255)];
2447 maximum = curve[0xff];
2450 void CLASS kodak_262_load_raw()
2452 static const uchar kodak_tree[2][26] =
2453 { { 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 },
2454 { 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 } };
2457 int *strip, ns, c, row, col, chess, pi=0, pi1, pi2, pred, val;
2459 FORC(2) huff[c] = make_decoder (kodak_tree[c]);
2460 ns = (raw_height+63) >> 5;
2461 pixel = (uchar *) malloc (raw_width*32 + ns*4);
2462 merror (pixel, "kodak_262_load_raw()");
2463 strip = (int *) (pixel + raw_width*32);
2465 FORC(ns) strip[c] = get4();
2466 for (row=0; row < raw_height; row++) {
2467 if ((row & 31) == 0) {
2468 fseek (ifp, strip[row >> 5], SEEK_SET);
2472 for (col=0; col < raw_width; col++) {
2473 chess = (row + col) & 1;
2474 pi1 = chess ? pi-2 : pi-raw_width-1;
2475 pi2 = chess ? pi-2*raw_width : pi-raw_width+1;
2476 if (col <= chess) pi1 = -1;
2477 if (pi1 < 0) pi1 = pi2;
2478 if (pi2 < 0) pi2 = pi1;
2479 if (pi1 < 0 && col > 1) pi1 = pi2 = pi-2;
2480 pred = (pi1 < 0) ? 0 : (pixel[pi1] + pixel[pi2]) >> 1;
2481 pixel[pi] = val = pred + ljpeg_diff (huff[chess]);
2482 if (val >> 8) derror();
2483 val = curve[pixel[pi++]];
2488 FORC(2) free (huff[c]);
2491 int CLASS kodak_65000_decode (short *out, int bsize)
2496 int save, bits=0, i, j, len, diff;
2499 bsize = (bsize + 3) & -4;
2500 for (i=0; i < bsize; i+=2) {
2502 if ((blen[i ] = c & 15) > 12 ||
2503 (blen[i+1] = c >> 4) > 12 ) {
2504 fseek (ifp, save, SEEK_SET);
2505 for (i=0; i < bsize; i+=8) {
2506 read_shorts (raw, 6);
2507 out[i ] = raw[0] >> 12 << 8 | raw[2] >> 12 << 4 | raw[4] >> 12;
2508 out[i+1] = raw[1] >> 12 << 8 | raw[3] >> 12 << 4 | raw[5] >> 12;
2509 for (j=0; j < 6; j++)
2510 out[i+2+j] = raw[j] & 0xfff;
2515 if ((bsize & 7) == 4) {
2516 bitbuf = fgetc(ifp) << 8;
2517 bitbuf += fgetc(ifp);
2520 for (i=0; i < bsize; i++) {
2523 for (j=0; j < 32; j+=8)
2524 bitbuf += (INT64) fgetc(ifp) << (bits+(j^8));
2527 diff = bitbuf & (0xffff >> (16-len));
2530 if ((diff & (1 << (len-1))) == 0)
2531 diff -= (1 << len) - 1;
2537 void CLASS kodak_65000_load_raw()
2540 int row, col, len, pred[2], ret, i;
2542 for (row=0; row < height; row++)
2543 for (col=0; col < width; col+=256) {
2544 pred[0] = pred[1] = 0;
2545 len = MIN (256, width-col);
2546 ret = kodak_65000_decode (buf, len);
2547 for (i=0; i < len; i++)
2548 if ((RAW(row,col+i) = curve[ret ? buf[i] :
2549 (pred[i & 1] += buf[i])]) >> 12) derror();
2553 void CLASS kodak_ycbcr_load_raw()
2555 short buf[384], *bp;
2556 int row, col, len, c, i, j, k, y[2][2], cb, cr, rgb[3];
2560 for (row=0; row < height; row+=2)
2561 for (col=0; col < width; col+=128) {
2562 len = MIN (128, width-col);
2563 kodak_65000_decode (buf, len*3);
2564 y[0][1] = y[1][1] = cb = cr = 0;
2565 for (bp=buf, i=0; i < len; i+=2, bp+=2) {
2568 rgb[1] = -((cb + cr + 2) >> 2);
2569 rgb[2] = rgb[1] + cb;
2570 rgb[0] = rgb[1] + cr;
2571 for (j=0; j < 2; j++)
2572 for (k=0; k < 2; k++) {
2573 if ((y[j][k] = y[j][k^1] + *bp++) >> 10) derror();
2574 ip = image[(row+j)*width + col+i+k];
2575 FORC3 ip[c] = curve[LIM(y[j][k]+rgb[c], 0, 0xfff)];
2581 void CLASS kodak_rgb_load_raw()
2583 short buf[768], *bp;
2584 int row, col, len, c, i, rgb[3];
2585 ushort *ip=image[0];
2587 for (row=0; row < height; row++)
2588 for (col=0; col < width; col+=256) {
2589 len = MIN (256, width-col);
2590 kodak_65000_decode (buf, len*3);
2591 memset (rgb, 0, sizeof rgb);
2592 for (bp=buf, i=0; i < len; i++, ip+=4)
2593 FORC3 if ((ip[c] = rgb[c] += *bp++) >> 12) derror();
2597 void CLASS kodak_thumb_load_raw()
2600 colors = thumb_misc >> 5;
2601 for (row=0; row < height; row++)
2602 for (col=0; col < width; col++)
2603 read_shorts (image[row*width+col], colors);
2604 maximum = (1 << (thumb_misc & 31)) - 1;
2607 void CLASS sony_decrypt (unsigned *data, int len, int start, int key)
2609 unsigned p = sony_p, *pad = sony_pad;;
2611 for (p=0; p < 4; p++)
2612 pad[p] = key = key * 48828125 + 1;
2613 pad[3] = pad[3] << 1 | (pad[0]^pad[2]) >> 31;
2614 for (p=4; p < 127; p++)
2615 pad[p] = (pad[p-4]^pad[p-2]) << 1 | (pad[p-3]^pad[p-1]) >> 31;
2616 for (p=0; p < 127; p++)
2617 pad[p] = htonl(pad[p]);
2619 while (len-- && p++)
2620 *data++ ^= pad[(p-1) & 127] = pad[p & 127] ^ pad[(p+64) & 127];
2624 void CLASS sony_load_raw()
2628 unsigned i, key, row, col;
2630 fseek (ifp, 200896, SEEK_SET);
2631 fseek (ifp, (unsigned) fgetc(ifp)*4 - 1, SEEK_CUR);
2634 fseek (ifp, 164600, SEEK_SET);
2635 fread (head, 1, 40, ifp);
2636 sony_decrypt ((unsigned *) head, 10, 1, key);
2637 for (i=26; i-- > 22; )
2638 key = key << 8 | head[i];
2639 fseek (ifp, data_offset, SEEK_SET);
2640 for (row=0; row < raw_height; row++) {
2641 pixel = raw_image + row*raw_width;
2642 if (fread (pixel, 2, raw_width, ifp) < raw_width) derror();
2643 sony_decrypt ((unsigned *) pixel, raw_width/2, !row, key);
2644 for (col=0; col < raw_width; col++)
2645 if ((pixel[col] = ntohs(pixel[col])) >> 14) derror();
2650 void CLASS sony_arw_load_raw()
2653 static const ushort tab[18] =
2654 { 0xf11,0xf10,0xe0f,0xd0e,0xc0d,0xb0c,0xa0b,0x90a,0x809,
2655 0x708,0x607,0x506,0x405,0x304,0x303,0x300,0x202,0x201 };
2656 int i, c, n, col, row, sum=0;
2659 for (n=i=0; i < 18; i++)
2660 FORC(32768 >> (tab[i] >> 8)) huff[++n] = tab[i];
2662 for (col = raw_width; col--; )
2663 for (row=0; row < raw_height+1; row+=2) {
2664 if (row == raw_height) row = 1;
2665 if ((sum += ljpeg_diff(huff)) >> 12) derror();
2666 if (row < height) RAW(row,col) = sum;
2670 void CLASS sony_arw2_load_raw()
2674 int row, col, val, max, min, imax, imin, sh, bit, i;
2676 data = (uchar *) malloc (raw_width+1);
2677 merror (data, "sony_arw2_load_raw()");
2678 for (row=0; row < height; row++) {
2679 fread (data, 1, raw_width, ifp);
2680 for (dp=data, col=0; col < raw_width-30; dp+=16) {
2681 max = 0x7ff & (val = sget4(dp));
2682 min = 0x7ff & val >> 11;
2683 imax = 0x0f & val >> 22;
2684 imin = 0x0f & val >> 26;
2685 for (sh=0; sh < 4 && 0x80 << sh <= max-min; sh++);
2686 for (bit=30, i=0; i < 16; i++)
2687 if (i == imax) pix[i] = max;
2688 else if (i == imin) pix[i] = min;
2690 pix[i] = ((sget2(dp+(bit >> 3)) >> (bit & 7) & 0x7f) << sh) + min;
2691 if (pix[i] > 0x7ff) pix[i] = 0x7ff;
2694 for (i=0; i < 16; i++, col+=2)
2695 RAW(row,col) = curve[pix[i] << 1] >> 2;
2696 col -= col & 1 ? 1:31;
2702 void CLASS samsung_load_raw()
2704 int row, col, c, i, dir, op[4], len[4];
2707 for (row=0; row < raw_height; row++) {
2708 fseek (ifp, strip_offset+row*4, SEEK_SET);
2709 fseek (ifp, data_offset+get4(), SEEK_SET);
2711 FORC4 len[c] = row < 2 ? 7:4;
2712 for (col=0; col < raw_width; col+=16) {
2714 FORC4 op[c] = ph1_bits(2);
2715 FORC4 switch (op[c]) {
2716 case 3: len[c] = ph1_bits(4); break;
2717 case 2: len[c]--; break;
2720 for (c=0; c < 16; c+=2) {
2721 i = len[((c & 1) << 1) | (c >> 3)];
2722 RAW(row,col+c) = ((signed) ph1_bits(i) << (32-i) >> (32-i)) +
2723 (dir ? RAW(row+(~c | -2),col+c) : col ? RAW(row,col+(c | -2)) : 128);
2724 if (c == 14) c = -1;
2728 for (row=0; row < raw_height-1; row+=2)
2729 for (col=0; col < raw_width-1; col+=2)
2730 SWAP (RAW(row,col+1), RAW(row+1,col));
2733 void CLASS samsung2_load_raw()
2735 static const ushort tab[14] =
2736 { 0x304,0x307,0x206,0x205,0x403,0x600,0x709,
2737 0x80a,0x90b,0xa0c,0xa0d,0x501,0x408,0x402 };
2738 ushort huff[1026], vpred[2][2] = {{0,0},{0,0}}, hpred[2];
2739 int i, c, n, row, col, diff;
2742 for (n=i=0; i < 14; i++)
2743 FORC(1024 >> (tab[i] >> 8)) huff[++n] = tab[i];
2745 for (row=0; row < raw_height; row++)
2746 for (col=0; col < raw_width; col++) {
2747 diff = ljpeg_diff (huff);
2748 if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
2749 else hpred[col & 1] += diff;
2750 RAW(row,col) = hpred[col & 1];
2751 if (hpred[col & 1] >> tiff_bps) derror();
2755 void CLASS samsung3_load_raw()
2757 int opt, init, mag, pmode, row, tab, col, pred, diff, i, c;
2758 ushort lent[3][2], len[4], *prow[2];
2761 fseek (ifp, 9, SEEK_CUR);
2763 init = (get2(),get2());
2764 for (row=0; row < raw_height; row++) {
2765 fseek (ifp, (data_offset-ftell(ifp)) & 15, SEEK_CUR);
2768 FORC(6) ((ushort *)lent)[c] = row < 2 ? 7:4;
2769 prow[ row & 1] = &RAW(row-1,1-((row & 1) << 1)); // green
2770 prow[~row & 1] = &RAW(row-2,0); // red and blue
2771 for (tab=0; tab+15 < raw_width; tab+=16) {
2772 if (~opt & 4 && !(tab & 63)) {
2774 mag = i < 3 ? mag-'2'+"204"[i] : ph1_bits(12);
2777 pmode = 7 - 4*ph1_bits(1);
2778 else if (!ph1_bits(1))
2779 pmode = ph1_bits(3);
2780 if (opt & 1 || !ph1_bits(1)) {
2781 FORC4 len[c] = ph1_bits(2);
2783 i = ((row & 1) << 1 | (c & 1)) % 3;
2784 len[c] = len[c] < 3 ? lent[i][0]-'1'+"120"[len[c]] : ph1_bits(4);
2785 lent[i][0] = lent[i][1];
2786 lent[i][1] = len[c];
2790 col = tab + (((c & 7) << 1)^(c >> 3)^(row & 1));
2791 pred = (pmode == 7 || row < 2)
2792 ? (tab ? RAW(row,tab-2+(col & 1)) : init)
2793 : (prow[col & 1][col-'4'+"0224468"[pmode]] +
2794 prow[col & 1][col-'4'+"0244668"[pmode]] + 1) >> 1;
2795 diff = ph1_bits (i = len[c >> 2]);
2796 if (diff >> (i-1)) diff -= 1 << i;
2797 diff = diff * (mag*2+1) + mag;
2798 RAW(row,col) = pred + diff;
2804 #define HOLE(row) ((holes >> (((row) - raw_height) & 7)) & 1)
2806 /* Kudos to Rich Taylor for figuring out SMaL's compression algorithm. */
2807 void CLASS smal_decode_segment (unsigned seg[2][2], int holes)
2809 uchar hist[3][18] = {
2810 { 7, 7, 0, 0, 63, 55, 47, 39, 31, 23, 15, 7, 0 },
2811 { 7, 7, 0, 0, 63, 55, 47, 39, 31, 23, 15, 7, 0 },
2812 { 3, 3, 0, 0, 63, 47, 31, 15, 0 } };
2813 int low, high=0xff, carry=0, nbits=8;
2814 int pix, s, count, bin, next, i, sym[3];
2815 uchar diff, pred[]={0,0};
2816 ushort data=0, range=0;
2818 fseek (ifp, seg[0][1]+1, SEEK_SET);
2820 if (seg[1][0] > raw_width*raw_height)
2821 seg[1][0] = raw_width*raw_height;
2822 for (pix=seg[0][0]; pix < seg[1][0]; pix++) {
2823 for (s=0; s < 3; s++) {
2824 data = data << nbits | getbits(nbits);
2826 carry = (nbits += carry+1) < 1 ? nbits-1 : 0;
2827 while (--nbits >= 0)
2828 if ((data >> nbits & 0xff) == 0xff) break;
2830 data = ((data & ((1 << (nbits-1)) - 1)) << 1) |
2831 ((data + (((data & (1 << (nbits-1)))) << 1)) & (-1 << nbits));
2836 count = ((((data-range+1) & 0xffff) << 2) - 1) / (high >> 4);
2837 for (bin=0; hist[s][bin+5] > count; bin++);
2838 low = hist[s][bin+5] * (high >> 4) >> 2;
2839 if (bin) high = hist[s][bin+4] * (high >> 4) >> 2;
2841 for (nbits=0; high << nbits < 128; nbits++);
2842 range = (range+low) << nbits;
2845 if (++hist[s][2] > hist[s][3]) {
2846 next = (next+1) & hist[s][0];
2847 hist[s][3] = (hist[s][next+4] - hist[s][next+5]) >> 2;
2850 if (hist[s][hist[s][1]+4] - hist[s][hist[s][1]+5] > 1) {
2851 if (bin < hist[s][1])
2852 for (i=bin; i < hist[s][1]; i++) hist[s][i+5]--;
2853 else if (next <= bin)
2854 for (i=hist[s][1]; i < bin; i++) hist[s][i+5]++;
2859 diff = sym[2] << 5 | sym[1] << 2 | (sym[0] & 3);
2861 diff = diff ? -diff : 0x80;
2862 if (ftell(ifp) + 12 >= seg[1][1])
2864 raw_image[pix] = pred[pix & 1] += diff;
2865 if (!(pix & 1) && HOLE(pix / raw_width)) pix += 2;
2870 void CLASS smal_v6_load_raw()
2874 fseek (ifp, 16, SEEK_SET);
2877 seg[1][0] = raw_width * raw_height;
2878 seg[1][1] = INT_MAX;
2879 smal_decode_segment (seg, 0);
2882 int CLASS median4 (int *p)
2884 int min, max, sum, i;
2886 min = max = sum = p[0];
2887 for (i=1; i < 4; i++) {
2889 if (min > p[i]) min = p[i];
2890 if (max < p[i]) max = p[i];
2892 return (sum - min - max) >> 1;
2895 void CLASS fill_holes (int holes)
2897 int row, col, val[4];
2899 for (row=2; row < height-2; row++) {
2900 if (!HOLE(row)) continue;
2901 for (col=1; col < width-1; col+=4) {
2902 val[0] = RAW(row-1,col-1);
2903 val[1] = RAW(row-1,col+1);
2904 val[2] = RAW(row+1,col-1);
2905 val[3] = RAW(row+1,col+1);
2906 RAW(row,col) = median4(val);
2908 for (col=2; col < width-2; col+=4)
2909 if (HOLE(row-2) || HOLE(row+2))
2910 RAW(row,col) = (RAW(row,col-2) + RAW(row,col+2)) >> 1;
2912 val[0] = RAW(row,col-2);
2913 val[1] = RAW(row,col+2);
2914 val[2] = RAW(row-2,col);
2915 val[3] = RAW(row+2,col);
2916 RAW(row,col) = median4(val);
2921 void CLASS smal_v9_load_raw()
2923 unsigned seg[256][2], offset, nseg, holes, i;
2925 fseek (ifp, 67, SEEK_SET);
2927 nseg = (uchar) fgetc(ifp);
2928 fseek (ifp, offset, SEEK_SET);
2929 for (i=0; i < nseg*2; i++)
2930 ((unsigned *)seg)[i] = get4() + data_offset*(i & 1);
2931 fseek (ifp, 78, SEEK_SET);
2933 fseek (ifp, 88, SEEK_SET);
2934 seg[nseg][0] = raw_height * raw_width;
2935 seg[nseg][1] = get4() + data_offset;
2936 for (i=0; i < nseg; i++)
2937 smal_decode_segment (seg+i, holes);
2938 if (holes) fill_holes (holes);
2941 void CLASS redcine_load_raw()
2952 in = jas_stream_fopen (ifname, "rb");
2953 jas_stream_seek (in, data_offset+20, SEEK_SET);
2954 jimg = jas_image_decode (in, -1, 0);
2955 if (!jimg) longjmp (failure, 3);
2956 jmat = jas_matrix_create (height/2, width/2);
2957 merror (jmat, "redcine_load_raw()");
2958 img = (ushort *) calloc ((height+2), (width+2)*2);
2959 merror (img, "redcine_load_raw()");
2961 jas_image_readcmpt (jimg, c, 0, 0, width/2, height/2, jmat);
2962 data = jas_matrix_getref (jmat, 0, 0);
2963 for (row = c >> 1; row < height; row+=2)
2964 for (col = c & 1; col < width; col+=2)
2965 img[(row+1)*(width+2)+col+1] = data[(row/2)*(width/2)+col/2];
2967 for (col=1; col <= width; col++) {
2968 img[col] = img[2*(width+2)+col];
2969 img[(height+1)*(width+2)+col] = img[(height-1)*(width+2)+col];
2971 for (row=0; row < height+2; row++) {
2972 img[row*(width+2)] = img[row*(width+2)+2];
2973 img[(row+1)*(width+2)-1] = img[(row+1)*(width+2)-3];
2975 for (row=1; row <= height; row++) {
2976 pix = img + row*(width+2) + (col = 1 + (FC(row,1) & 1));
2977 for ( ; col <= width; col+=2, pix+=2) {
2978 c = (((pix[0] - 0x800) << 3) +
2979 pix[-(width+2)] + pix[width+2] + pix[-1] + pix[1]) >> 2;
2980 pix[0] = LIM(c,0,4095);
2983 for (row=0; row < height; row++)
2984 for (col=0; col < width; col++)
2985 RAW(row,col) = curve[img[(row+1)*(width+2)+col+1]];
2987 jas_matrix_destroy (jmat);
2988 jas_image_destroy (jimg);
2989 jas_stream_close (in);
2993 /* RESTRICTED code starts here */
2995 void CLASS foveon_decoder (unsigned size, unsigned code)
2997 unsigned *huff = fov_huff;
3002 for (i=0; i < size; i++)
3004 memset (first_decode, 0, sizeof first_decode);
3005 free_decode = first_decode;
3007 cur = free_decode++;
3008 if (free_decode > first_decode+2048) {
3009 fprintf (stderr,_("%s: decoder table overflow\n"), ifname);
3010 longjmp (failure, 2);
3013 for (i=0; i < size; i++)
3014 if (huff[i] == code) {
3018 if ((len = code >> 27) > 26) return;
3019 code = (len+1) << 27 | (code & 0x3ffffff) << 1;
3021 cur->branch[0] = free_decode;
3022 foveon_decoder (size, code);
3023 cur->branch[1] = free_decode;
3024 foveon_decoder (size, code+1);
3027 void CLASS foveon_thumb()
3029 unsigned bwide, row, col, bitbuf=0, bit=1, c, i;
3031 struct decode *dindex;
3035 fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
3037 if (bwide < thumb_width*3) return;
3038 buf = (char *) malloc (bwide);
3039 merror (buf, "foveon_thumb()");
3040 for (row=0; row < thumb_height; row++) {
3041 fread (buf, 1, bwide, ifp);
3042 fwrite (buf, 3, thumb_width, ofp);
3047 foveon_decoder (256, 0);
3049 for (row=0; row < thumb_height; row++) {
3050 memset (pred, 0, sizeof pred);
3052 for (bit=col=0; col < thumb_width; col++)
3054 for (dindex=first_decode; dindex->branch[0]; ) {
3055 if ((bit = (bit-1) & 31) == 31)
3056 for (i=0; i < 4; i++)
3057 bitbuf = (bitbuf << 8) + fgetc(ifp);
3058 dindex = dindex->branch[bitbuf >> bit & 1];
3060 pred[c] += dindex->leaf;
3061 fputc (pred[c], ofp);
3066 void CLASS foveon_sd_load_raw()
3068 struct decode *dindex;
3071 int pred[3], row, col, bit=-1, c, i;
3073 read_shorts ((ushort *) diff, 1024);
3074 if (!load_flags) foveon_decoder (1024, 0);
3076 for (row=0; row < height; row++) {
3077 memset (pred, 0, sizeof pred);
3078 if (!bit && !load_flags && atoi(model+2) < 14) get4();
3079 for (col=bit=0; col < width; col++) {
3082 FORC3 pred[2-c] += diff[bitbuf >> c*10 & 0x3ff];
3085 for (dindex=first_decode; dindex->branch[0]; ) {
3086 if ((bit = (bit-1) & 31) == 31)
3087 for (i=0; i < 4; i++)
3088 bitbuf = (bitbuf << 8) + fgetc(ifp);
3089 dindex = dindex->branch[bitbuf >> bit & 1];
3091 pred[c] += diff[dindex->leaf];
3092 if (pred[c] >> 16 && ~pred[c] >> 16) derror();
3094 FORC3 image[row*width+col][c] = pred[c];
3099 void CLASS foveon_huff (ushort *huff)
3101 int i, j, clen, code;
3104 for (i=0; i < 13; i++) {
3107 for (j=0; j < 256 >> clen; )
3108 huff[code+ ++j] = clen << 8 | i;
3113 void CLASS foveon_dp_load_raw()
3115 unsigned c, roff[4], row, col, diff;
3116 ushort huff[512], vpred[2][2], hpred[2];
3118 fseek (ifp, 8, SEEK_CUR);
3121 FORC3 roff[c+1] = -(-(roff[c] + get4()) & -16);
3123 fseek (ifp, data_offset+roff[c], SEEK_SET);
3125 vpred[0][0] = vpred[0][1] = vpred[1][0] = vpred[1][1] = 512;
3126 for (row=0; row < height; row++) {
3127 for (col=0; col < width; col++) {
3128 diff = ljpeg_diff(huff);
3129 if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
3130 else hpred[col & 1] += diff;
3131 image[row*width+col][c] = hpred[col & 1];
3137 void CLASS foveon_load_camf()
3139 unsigned type, wide, high, i, j, row, col, diff;
3140 ushort huff[258], vpred[2][2] = {{512,512},{512,512}}, hpred[2];
3142 fseek (ifp, meta_offset, SEEK_SET);
3143 type = get4(); get4(); get4();
3147 fread (meta_data, 1, meta_length, ifp);
3148 for (i=0; i < meta_length; i++) {
3149 high = (high * 1597 + 51749) % 244944;
3150 wide = high * (INT64) 301593171 >> 24;
3151 meta_data[i] ^= ((((high << 8) - wide) >> 1) + wide) >> 17;
3153 } else if (type == 4) {
3155 meta_data = (char *) malloc (meta_length = wide*high*3/2);
3156 merror (meta_data, "foveon_load_camf()");
3160 for (j=row=0; row < high; row++) {
3161 for (col=0; col < wide; col++) {
3162 diff = ljpeg_diff(huff);
3163 if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
3164 else hpred[col & 1] += diff;
3166 meta_data[j++] = hpred[0] >> 4;
3167 meta_data[j++] = hpred[0] << 4 | hpred[1] >> 8;
3168 meta_data[j++] = hpred[1];
3173 fprintf (stderr,_("%s has unknown CAMF type %d.\n"), ifname, type);
3176 const char * CLASS foveon_camf_param (const char *block, const char *param)
3179 char *pos, *cp, *dp;
3181 for (idx=0; idx < meta_length; idx += sget4(pos+8)) {
3182 pos = meta_data + idx;
3183 if (strncmp (pos, "CMb", 3)) break;
3184 if (pos[3] != 'P') continue;
3185 if (strcmp (block, pos+sget4(pos+12))) continue;
3186 cp = pos + sget4(pos+16);
3188 dp = pos + sget4(cp+4);
3191 if (!strcmp (param, dp+sget4(cp)))
3192 return dp+sget4(cp+4);
3198 void * CLASS foveon_camf_matrix (unsigned dim[3], const char *name)
3200 unsigned i, idx, type, ndim, size, *mat;
3201 char *pos, *cp, *dp;
3204 for (idx=0; idx < meta_length; idx += sget4(pos+8)) {
3205 pos = meta_data + idx;
3206 if (strncmp (pos, "CMb", 3)) break;
3207 if (pos[3] != 'M') continue;
3208 if (strcmp (name, pos+sget4(pos+12))) continue;
3209 dim[0] = dim[1] = dim[2] = 1;
3210 cp = pos + sget4(pos+16);
3212 if ((ndim = sget4(cp+4)) > 3) break;
3213 dp = pos + sget4(cp+8);
3214 for (i=ndim; i--; ) {
3218 if ((dsize = (double) dim[0]*dim[1]*dim[2]) > meta_length/4) break;
3219 mat = (unsigned *) malloc ((size = dsize) * 4);
3220 merror (mat, "foveon_camf_matrix()");
3221 for (i=0; i < size; i++)
3222 if (type && type != 6)
3223 mat[i] = sget4(dp + i*4);
3225 mat[i] = sget4(dp + i*2) & 0xffff;
3228 fprintf (stderr,_("%s: \"%s\" matrix not found!\n"), ifname, name);
3232 int CLASS foveon_fixed (void *ptr, int size, const char *name)
3237 if (!name) return 0;
3238 dp = foveon_camf_matrix (dim, name);
3240 memcpy (ptr, dp, size*4);
3245 float CLASS foveon_avg (short *pix, int range[2], float cfilt)
3248 float val, min=FLT_MAX, max=-FLT_MAX, sum=0;
3250 for (i=range[0]; i <= range[1]; i++) {
3251 sum += val = pix[i*4] + (pix[i*4]-pix[(i-1)*4]) * cfilt;
3252 if (min > val) min = val;
3253 if (max < val) max = val;
3255 if (range[1] - range[0] == 1) return sum/2;
3256 return (sum - min - max) / (range[1] - range[0] - 1);
3259 short * CLASS foveon_make_curve (double max, double mul, double filt)
3265 if (!filt) filt = 0.8;
3266 size = 4*M_PI*max / filt;
3267 if (size == UINT_MAX) size--;
3268 curve = (short *) calloc (size+1, sizeof *curve);
3269 merror (curve, "foveon_make_curve()");
3271 for (i=0; i < size; i++) {
3273 curve[i+1] = (cos(x)+1)/2 * tanh(i*filt/mul) * mul + 0.5;
3278 void CLASS foveon_make_curves
3279 (short **curvep, float dq[3], float div[3], float filt)
3281 double mul[3], max=0;
3284 FORC3 mul[c] = dq[c]/div[c];
3285 FORC3 if (max < mul[c]) max = mul[c];
3286 FORC3 curvep[c] = foveon_make_curve (max, mul[c], filt);
3289 int CLASS foveon_apply_curve (short *curve, int i)
3291 if (abs(i) >= curve[0]) return 0;
3292 return i < 0 ? -curve[1-i] : curve[1+i];
3295 #define image ((short (*)[4]) image)
3297 void CLASS foveon_interpolate()
3299 static const short hood[] = { -1,-1, -1,0, -1,1, 0,-1, 0,1, 1,-1, 1,0, 1,1 };
3300 short *pix, prev[3], *curve[8], (*shrink)[3];
3301 float cfilt=0, ddft[3][3][2], ppm[3][3][3];
3302 float cam_xyz[3][3], correct[3][3], last[3][3], trans[3][3];
3303 float chroma_dq[3], color_dq[3], diag[3][3], div[3];
3304 float (*black)[3], (*sgain)[3], (*sgrow)[3];
3305 float fsum[3], val, frow, num;
3306 int row, col, c, i, j, diff, sgx, irow, sum, min, max, limit;
3307 int dscr[2][2], dstb[4], (*smrow[7])[3], total[4], ipix[3];
3308 int work[3][3], smlast, smred, smred_p=0, dev[3];
3309 int satlev[3], keep[4], active[4];
3310 unsigned dim[3], *badpix;
3311 double dsum=0, trsum[3];
3316 fprintf (stderr,_("Foveon interpolation...\n"));
3319 foveon_fixed (dscr, 4, "DarkShieldColRange");
3320 foveon_fixed (ppm[0][0], 27, "PostPolyMatrix");
3321 foveon_fixed (satlev, 3, "SaturationLevel");
3322 foveon_fixed (keep, 4, "KeepImageArea");
3323 foveon_fixed (active, 4, "ActiveImageArea");
3324 foveon_fixed (chroma_dq, 3, "ChromaDQ");
3325 foveon_fixed (color_dq, 3,
3326 foveon_camf_param ("IncludeBlocks", "ColorDQ") ?
3327 "ColorDQ" : "ColorDQCamRGB");
3328 if (foveon_camf_param ("IncludeBlocks", "ColumnFilter"))
3329 foveon_fixed (&cfilt, 1, "ColumnFilter");
3331 memset (ddft, 0, sizeof ddft);
3332 if (!foveon_camf_param ("IncludeBlocks", "DarkDrift")
3333 || !foveon_fixed (ddft[1][0], 12, "DarkDrift"))
3334 for (i=0; i < 2; i++) {
3335 foveon_fixed (dstb, 4, i ? "DarkShieldBottom":"DarkShieldTop");
3336 for (row = dstb[1]; row <= dstb[3]; row++)
3337 for (col = dstb[0]; col <= dstb[2]; col++)
3338 FORC3 ddft[i+1][c][1] += (short) image[row*width+col][c];
3339 FORC3 ddft[i+1][c][1] /= (dstb[3]-dstb[1]+1) * (dstb[2]-dstb[0]+1);
3342 if (!(cp = foveon_camf_param ("WhiteBalanceIlluminants", model2)))
3343 { fprintf (stderr,_("%s: Invalid white balance \"%s\"\n"), ifname, model2);
3345 foveon_fixed (cam_xyz, 9, cp);
3346 foveon_fixed (correct, 9,
3347 foveon_camf_param ("WhiteBalanceCorrections", model2));
3348 memset (last, 0, sizeof last);
3349 for (i=0; i < 3; i++)
3350 for (j=0; j < 3; j++)
3351 FORC3 last[i][j] += correct[i][c] * cam_xyz[c][j];
3353 #define LAST(x,y) last[(i+x)%3][(c+y)%3]
3354 for (i=0; i < 3; i++)
3355 FORC3 diag[c][i] = LAST(1,1)*LAST(2,2) - LAST(1,2)*LAST(2,1);
3357 FORC3 div[c] = diag[c][0]*0.3127 + diag[c][1]*0.329 + diag[c][2]*0.3583;
3358 sprintf (str, "%sRGBNeutral", model2);
3359 if (foveon_camf_param ("IncludeBlocks", str))
3360 foveon_fixed (div, 3, str);
3362 FORC3 if (num < div[c]) num = div[c];
3363 FORC3 div[c] /= num;
3365 memset (trans, 0, sizeof trans);
3366 for (i=0; i < 3; i++)
3367 for (j=0; j < 3; j++)
3368 FORC3 trans[i][j] += rgb_cam[i][c] * last[c][j] * div[j];
3369 FORC3 trsum[c] = trans[c][0] + trans[c][1] + trans[c][2];
3370 dsum = (6*trsum[0] + 11*trsum[1] + 3*trsum[2]) / 20;
3371 for (i=0; i < 3; i++)
3372 FORC3 last[i][c] = trans[i][c] * dsum / trsum[i];
3373 memset (trans, 0, sizeof trans);
3374 for (i=0; i < 3; i++)
3375 for (j=0; j < 3; j++)
3376 FORC3 trans[i][j] += (i==c ? 32 : -1) * last[c][j] / 30;
3378 foveon_make_curves (curve, color_dq, div, cfilt);
3379 FORC3 chroma_dq[c] /= 3;
3380 foveon_make_curves (curve+3, chroma_dq, div, cfilt);
3381 FORC3 dsum += chroma_dq[c] / div[c];
3382 curve[6] = foveon_make_curve (dsum, dsum, cfilt);
3383 curve[7] = foveon_make_curve (dsum*2, dsum*2, cfilt);
3385 sgain = (float (*)[3]) foveon_camf_matrix (dim, "SpatialGain");
3387 sgrow = (float (*)[3]) calloc (dim[1], sizeof *sgrow);
3388 sgx = (width + dim[1]-2) / (dim[1]-1);
3390 black = (float (*)[3]) calloc (height, sizeof *black);
3391 for (row=0; row < height; row++) {
3392 for (i=0; i < 6; i++)
3393 ((float *)ddft[0])[i] = ((float *)ddft[1])[i] +
3394 row / (height-1.0) * (((float *)ddft[2])[i] - ((float *)ddft[1])[i]);
3395 FORC3 black[row][c] =
3396 ( foveon_avg (image[row*width]+c, dscr[0], cfilt) +
3397 foveon_avg (image[row*width]+c, dscr[1], cfilt) * 3
3398 - ddft[0][c][0] ) / 4 - ddft[0][c][1];
3400 memcpy (black, black+8, sizeof *black*8);
3401 memcpy (black+height-11, black+height-22, 11*sizeof *black);
3402 memcpy (last, black, sizeof last);
3404 for (row=1; row < height-1; row++) {
3405 FORC3 if (last[1][c] > last[0][c]) {
3406 if (last[1][c] > last[2][c])
3407 black[row][c] = (last[0][c] > last[2][c]) ? last[0][c]:last[2][c];
3409 if (last[1][c] < last[2][c])
3410 black[row][c] = (last[0][c] < last[2][c]) ? last[0][c]:last[2][c];
3411 memmove (last, last+1, 2*sizeof last[0]);
3412 memcpy (last[2], black[row+1], sizeof last[2]);
3414 FORC3 black[row][c] = (last[0][c] + last[1][c])/2;
3415 FORC3 black[0][c] = (black[1][c] + black[3][c])/2;
3417 val = 1 - exp(-1/24.0);
3418 memcpy (fsum, black, sizeof fsum);
3419 for (row=1; row < height; row++)
3420 FORC3 fsum[c] += black[row][c] =
3421 (black[row][c] - black[row-1][c])*val + black[row-1][c];
3422 memcpy (last[0], black[height-1], sizeof last[0]);
3423 FORC3 fsum[c] /= height;
3424 for (row = height; row--; )
3425 FORC3 last[0][c] = black[row][c] =
3426 (black[row][c] - fsum[c] - last[0][c])*val + last[0][c];
3428 memset (total, 0, sizeof total);
3429 for (row=2; row < height; row+=4)
3430 for (col=2; col < width; col+=4) {
3431 FORC3 total[c] += (short) image[row*width+col][c];
3434 for (row=0; row < height; row++)
3435 FORC3 black[row][c] += fsum[c]/2 + total[c]/(total[3]*100.0);
3437 for (row=0; row < height; row++) {
3438 for (i=0; i < 6; i++)
3439 ((float *)ddft[0])[i] = ((float *)ddft[1])[i] +
3440 row / (height-1.0) * (((float *)ddft[2])[i] - ((float *)ddft[1])[i]);
3441 pix = image[row*width];
3442 memcpy (prev, pix, sizeof prev);
3443 frow = row / (height-1.0) * (dim[2]-1);
3444 if ((irow = frow) == dim[2]-1) irow--;
3446 for (i=0; i < dim[1]; i++)
3447 FORC3 sgrow[i][c] = sgain[ irow *dim[1]+i][c] * (1-frow) +
3448 sgain[(irow+1)*dim[1]+i][c] * frow;
3449 for (col=0; col < width; col++) {
3451 diff = pix[c] - prev[c];
3453 ipix[c] = pix[c] + floor ((diff + (diff*diff >> 14)) * cfilt
3454 - ddft[0][c][1] - ddft[0][c][0] * ((float) col/width - 0.5)
3458 work[0][c] = ipix[c] * ipix[c] >> 14;
3459 work[2][c] = ipix[c] * work[0][c] >> 14;
3460 work[1][2-c] = ipix[(c+1) % 3] * ipix[(c+2) % 3] >> 14;
3463 for (val=i=0; i < 3; i++)
3464 for ( j=0; j < 3; j++)
3465 val += ppm[c][i][j] * work[i][j];
3466 ipix[c] = floor ((ipix[c] + floor(val)) *
3467 ( sgrow[col/sgx ][c] * (sgx - col%sgx) +
3468 sgrow[col/sgx+1][c] * (col%sgx) ) / sgx / div[c]);
3469 if (ipix[c] > 32000) ipix[c] = 32000;
3479 if ((badpix = (unsigned *) foveon_camf_matrix (dim, "BadPixels"))) {
3480 for (i=0; i < dim[0]; i++) {
3481 col = (badpix[i] >> 8 & 0xfff) - keep[0];
3482 row = (badpix[i] >> 20 ) - keep[1];
3483 if ((unsigned)(row-1) > height-3 || (unsigned)(col-1) > width-3)
3485 memset (fsum, 0, sizeof fsum);
3486 for (sum=j=0; j < 8; j++)
3487 if (badpix[i] & (1 << j)) {
3488 FORC3 fsum[c] += (short)
3489 image[(row+hood[j*2])*width+col+hood[j*2+1]][c];
3492 if (sum) FORC3 image[row*width+col][c] = fsum[c]/sum;
3497 /* Array for 5x5 Gaussian averaging of red values */
3498 smrow[6] = (int (*)[3]) calloc (width*5, sizeof **smrow);
3499 merror (smrow[6], "foveon_interpolate()");
3500 for (i=0; i < 5; i++)
3501 smrow[i] = smrow[6] + i*width;
3503 /* Sharpen the reds against these Gaussian averages */
3504 for (smlast=-1, row=2; row < height-2; row++) {
3505 while (smlast < row+2) {
3506 for (i=0; i < 6; i++)
3507 smrow[(i+5) % 6] = smrow[i];
3508 pix = image[++smlast*width+2];
3509 for (col=2; col < width-2; col++) {
3511 (pix[0]*6 + (pix[-4]+pix[4])*4 + pix[-8]+pix[8] + 8) >> 4;
3515 pix = image[row*width+2];
3516 for (col=2; col < width-2; col++) {
3517 smred = ( 6 * smrow[2][col][0]
3518 + 4 * (smrow[1][col][0] + smrow[3][col][0])
3519 + smrow[0][col][0] + smrow[4][col][0] + 8 ) >> 4;
3522 i = pix[0] + ((pix[0] - ((smred*7 + smred_p) >> 3)) >> 3);
3523 if (i > 32000) i = 32000;
3530 /* Adjust the brighter pixels for better linearity */
3533 i = satlev[c] / div[c];
3534 if (min > i) min = i;
3536 limit = min * 9 >> 4;
3537 for (pix=image[0]; pix < image[height*width]; pix+=4) {
3538 if (pix[0] <= limit || pix[1] <= limit || pix[2] <= limit)
3541 for (c=1; c < 3; c++) {
3542 if (min > pix[c]) min = pix[c];
3543 if (max < pix[c]) max = pix[c];
3545 if (min >= limit*2) {
3546 pix[0] = pix[1] = pix[2] = max;
3548 i = 0x4000 - ((min - limit) << 14) / limit;
3549 i = 0x4000 - (i*i >> 14);
3551 FORC3 pix[c] += (max - pix[c]) * i >> 14;
3555 Because photons that miss one detector often hit another,
3556 the sum R+G+B is much less noisy than the individual colors.
3557 So smooth the hues without smoothing the total.
3559 for (smlast=-1, row=2; row < height-2; row++) {
3560 while (smlast < row+2) {
3561 for (i=0; i < 6; i++)
3562 smrow[(i+5) % 6] = smrow[i];
3563 pix = image[++smlast*width+2];
3564 for (col=2; col < width-2; col++) {
3565 FORC3 smrow[4][col][c] = (pix[c-4]+2*pix[c]+pix[c+4]+2) >> 2;
3569 pix = image[row*width+2];
3570 for (col=2; col < width-2; col++) {
3571 FORC3 dev[c] = -foveon_apply_curve (curve[7], pix[c] -
3572 ((smrow[1][col][c] + 2*smrow[2][col][c] + smrow[3][col][c]) >> 2));
3573 sum = (dev[0] + dev[1] + dev[2]) >> 3;
3574 FORC3 pix[c] += dev[c] - sum;
3578 for (smlast=-1, row=2; row < height-2; row++) {
3579 while (smlast < row+2) {
3580 for (i=0; i < 6; i++)
3581 smrow[(i+5) % 6] = smrow[i];
3582 pix = image[++smlast*width+2];
3583 for (col=2; col < width-2; col++) {
3584 FORC3 smrow[4][col][c] =
3585 (pix[c-8]+pix[c-4]+pix[c]+pix[c+4]+pix[c+8]+2) >> 2;
3589 pix = image[row*width+2];
3590 for (col=2; col < width-2; col++) {
3591 for (total[3]=375, sum=60, c=0; c < 3; c++) {
3592 for (total[c]=i=0; i < 5; i++)
3593 total[c] += smrow[i][col][c];
3594 total[3] += total[c];
3597 if (sum < 0) sum = 0;
3598 j = total[3] > 375 ? (sum << 16) / total[3] : sum * 174;
3599 FORC3 pix[c] += foveon_apply_curve (curve[6],
3600 ((j*total[c] + 0x8000) >> 16) - pix[c]);
3605 /* Transform the image to a different colorspace */
3606 for (pix=image[0]; pix < image[height*width]; pix+=4) {
3607 FORC3 pix[c] -= foveon_apply_curve (curve[c], pix[c]);
3608 sum = (pix[0]+pix[1]+pix[1]+pix[2]) >> 2;
3609 FORC3 pix[c] -= foveon_apply_curve (curve[c], pix[c]-sum);
3611 for (dsum=i=0; i < 3; i++)
3612 dsum += trans[c][i] * pix[i];
3613 if (dsum < 0) dsum = 0;
3614 if (dsum > 24000) dsum = 24000;
3615 ipix[c] = dsum + 0.5;
3617 FORC3 pix[c] = ipix[c];
3620 /* Smooth the image bottom-to-top and save at 1/4 scale */
3621 shrink = (short (*)[3]) calloc ((height/4), (width/4)*sizeof *shrink);
3622 merror (shrink, "foveon_interpolate()");
3623 for (row = height/4; row--; )
3624 for (col=0; col < width/4; col++) {
3625 ipix[0] = ipix[1] = ipix[2] = 0;
3626 for (i=0; i < 4; i++)
3627 for (j=0; j < 4; j++)
3628 FORC3 ipix[c] += image[(row*4+i)*width+col*4+j][c];
3630 if (row+2 > height/4)
3631 shrink[row*(width/4)+col][c] = ipix[c] >> 4;
3633 shrink[row*(width/4)+col][c] =
3634 (shrink[(row+1)*(width/4)+col][c]*1840 + ipix[c]*141 + 2048) >> 12;
3636 /* From the 1/4-scale image, smooth right-to-left */
3637 for (row=0; row < (height & ~3); row++) {
3638 ipix[0] = ipix[1] = ipix[2] = 0;
3640 for (col = width & ~3 ; col--; )
3641 FORC3 smrow[0][col][c] = ipix[c] =
3642 (shrink[(row/4)*(width/4)+col/4][c]*1485 + ipix[c]*6707 + 4096) >> 13;
3644 /* Then smooth left-to-right */
3645 ipix[0] = ipix[1] = ipix[2] = 0;
3646 for (col=0; col < (width & ~3); col++)
3647 FORC3 smrow[1][col][c] = ipix[c] =
3648 (smrow[0][col][c]*1485 + ipix[c]*6707 + 4096) >> 13;
3650 /* Smooth top-to-bottom */
3652 memcpy (smrow[2], smrow[1], sizeof **smrow * width);
3654 for (col=0; col < (width & ~3); col++)
3655 FORC3 smrow[2][col][c] =
3656 (smrow[2][col][c]*6707 + smrow[1][col][c]*1485 + 4096) >> 13;
3658 /* Adjust the chroma toward the smooth values */
3659 for (col=0; col < (width & ~3); col++) {
3660 for (i=j=30, c=0; c < 3; c++) {
3661 i += smrow[2][col][c];
3662 j += image[row*width+col][c];
3665 for (sum=c=0; c < 3; c++) {
3666 ipix[c] = foveon_apply_curve (curve[c+3],
3667 ((smrow[2][col][c] * j + 0x8000) >> 16) - image[row*width+col][c]);
3672 i = image[row*width+col][c] + ipix[c] - sum;
3674 image[row*width+col][c] = i;
3680 for (i=0; i < 8; i++)
3683 /* Trim off the black border */
3684 active[1] -= keep[1];
3686 i = active[2] - active[0];
3687 for (row=0; row < active[3]-active[1]; row++)
3688 memcpy (image[row*i], image[(row+active[1])*width+active[0]],
3695 /* RESTRICTED code ends here */
3697 void CLASS crop_masked_pixels()
3700 unsigned r, c, m, mblack[8], zero, val;
3702 if (load_raw == &CLASS phase_one_load_raw ||
3703 load_raw == &CLASS phase_one_load_raw_c)
3704 phase_one_correct();
3706 for (row=0; row < raw_height-top_margin*2; row++) {
3707 for (col=0; col < fuji_width << !fuji_layout; col++) {
3709 r = fuji_width - 1 - col + (row >> 1);
3710 c = col + ((row+1) >> 1);
3712 r = fuji_width - 1 + row - (col >> 1);
3713 c = row + ((col+1) >> 1);
3715 if (r < height && c < width)
3716 BAYER(r,c) = RAW(row+top_margin,col+left_margin);
3720 for (row=0; row < height; row++)
3721 for (col=0; col < width; col++)
3722 BAYER2(row,col) = RAW(row+top_margin,col+left_margin);
3724 if (mask[0][3] > 0) goto mask_set;
3725 if (load_raw == &CLASS canon_load_raw ||
3726 load_raw == &CLASS lossless_jpeg_load_raw) {
3727 mask[0][1] = mask[1][1] += 2;
3731 if (load_raw == &CLASS canon_600_load_raw ||
3732 load_raw == &CLASS sony_load_raw ||
3733 (load_raw == &CLASS eight_bit_load_raw && strncmp(model,"DC2",3)) ||
3734 load_raw == &CLASS kodak_262_load_raw ||
3735 (load_raw == &CLASS packed_load_raw && (load_flags & 32))) {
3737 mask[0][0] = mask[1][0] = top_margin;
3738 mask[0][2] = mask[1][2] = top_margin+height;
3739 mask[0][3] += left_margin;
3740 mask[1][1] += left_margin+width;
3741 mask[1][3] += raw_width;
3743 if (load_raw == &CLASS nokia_load_raw) {
3744 mask[0][2] = top_margin;
3748 memset (mblack, 0, sizeof mblack);
3749 for (zero=m=0; m < 8; m++)
3750 for (row=MAX(mask[m][0],0); row < MIN(mask[m][2],raw_height); row++)
3751 for (col=MAX(mask[m][1],0); col < MIN(mask[m][3],raw_width); col++) {
3752 c = FC(row-top_margin,col-left_margin);
3753 mblack[c] += val = RAW(row,col);
3757 if (load_raw == &CLASS canon_600_load_raw && width < raw_width) {
3758 black = (mblack[0]+mblack[1]+mblack[2]+mblack[3]) /
3759 (mblack[4]+mblack[5]+mblack[6]+mblack[7]) - 4;
3760 canon_600_correct();
3761 } else if (zero < mblack[4] && mblack[5] && mblack[6] && mblack[7]) {
3762 FORC4 cblack[c] = mblack[c] / mblack[4+c];
3763 cblack[4] = cblack[5] = cblack[6] = 0;
3767 void CLASS remove_zeroes()
3769 unsigned row, col, tot, n, r, c;
3771 for (row=0; row < height; row++)
3772 for (col=0; col < width; col++)
3773 if (BAYER(row,col) == 0) {
3775 for (r = row-2; r <= row+2; r++)
3776 for (c = col-2; c <= col+2; c++)
3777 if (r < height && c < width &&
3778 FC(r,c) == FC(row,col) && BAYER(r,c))
3779 tot += (n++,BAYER(r,c));
3780 if (n) BAYER(row,col) = tot/n;
3785 Seach from the current directory up to the root looking for
3786 a ".badpixels" file, and fix those pixels now.
3788 void CLASS bad_pixels (const char *cfname)
3791 char *fname, *cp, line[128];
3792 int len, time, row, col, r, c, rad, tot, n, fixed=0;
3794 if (!filters) return;
3796 fp = fopen (cfname, "r");
3798 for (len=32 ; ; len *= 2) {
3799 fname = (char *) malloc (len);
3801 if (getcwd (fname, len-16)) break;
3803 if (errno != ERANGE) return;
3805 #if defined(WIN32) || defined(DJGPP)
3806 if (fname[1] == ':')
3807 memmove (fname, fname+2, len-2);
3808 for (cp=fname; *cp; cp++)
3809 if (*cp == '\\') *cp = '/';
3811 cp = fname + strlen(fname);
3812 if (cp[-1] == '/') cp--;
3813 while (*fname == '/') {
3814 strcpy (cp, "/.badpixels");
3815 if ((fp = fopen (fname, "r"))) break;
3816 if (cp == fname) break;
3817 while (*--cp != '/');
3822 while (fgets (line, 128, fp)) {
3823 cp = strchr (line, '#');
3825 if (sscanf (line, "%d %d %d", &col, &row, &time) != 3) continue;
3826 if ((unsigned) col >= width || (unsigned) row >= height) continue;
3827 if (time > timestamp) continue;
3828 for (tot=n=0, rad=1; rad < 3 && n==0; rad++)
3829 for (r = row-rad; r <= row+rad; r++)
3830 for (c = col-rad; c <= col+rad; c++)
3831 if ((unsigned) r < height && (unsigned) c < width &&
3832 (r != row || c != col) && fcol(r,c) == fcol(row,col)) {
3836 BAYER2(row,col) = tot/n;
3839 fprintf (stderr,_("Fixed dead pixels at:"));
3840 fprintf (stderr, " %d,%d", col, row);
3843 if (fixed) fputc ('\n', stderr);
3847 void CLASS subtract (const char *fname)
3850 int dim[3]={0,0,0}, comment=0, number=0, error=0, nd=0, c, row, col;
3853 if (!(fp = fopen (fname, "rb"))) {
3854 perror (fname); return;
3856 if (fgetc(fp) != 'P' || fgetc(fp) != '5') error = 1;
3857 while (!error && nd < 3 && (c = fgetc(fp)) != EOF) {
3858 if (c == '#') comment = 1;
3859 if (c == '\n') comment = 0;
3860 if (comment) continue;
3861 if (isdigit(c)) number = 1;
3863 if (isdigit(c)) dim[nd] = dim[nd]*10 + c -'0';
3864 else if (isspace(c)) {
3869 if (error || nd < 3) {
3870 fprintf (stderr,_("%s is not a valid PGM file!\n"), fname);
3871 fclose (fp); return;
3872 } else if (dim[0] != width || dim[1] != height || dim[2] != 65535) {
3873 fprintf (stderr,_("%s has the wrong dimensions!\n"), fname);
3874 fclose (fp); return;
3876 pixel = (ushort *) calloc (width, sizeof *pixel);
3877 merror (pixel, "subtract()");
3878 for (row=0; row < height; row++) {
3879 fread (pixel, 2, width, fp);
3880 for (col=0; col < width; col++)
3881 BAYER(row,col) = MAX (BAYER(row,col) - ntohs(pixel[col]), 0);
3885 memset (cblack, 0, sizeof cblack);
3889 void CLASS gamma_curve (double pwr, double ts, int mode, int imax)
3892 double g[6], bnd[2]={0,0}, r;
3896 g[2] = g[3] = g[4] = 0;
3898 if (g[1] && (g[1]-1)*(g[0]-1) <= 0) {
3899 for (i=0; i < 48; i++) {
3900 g[2] = (bnd[0] + bnd[1])/2;
3901 if (g[0]) bnd[(pow(g[2]/g[1],-g[0]) - 1)/g[0] - 1/g[2] > -1] = g[2];
3902 else bnd[g[2]/exp(1-1/g[2]) < g[1]] = g[2];
3905 if (g[0]) g[4] = g[2] * (1/g[0] - 1);
3907 if (g[0]) g[5] = 1 / (g[1]*SQR(g[3])/2 - g[4]*(1 - g[3]) +
3908 (1 - pow(g[3],1+g[0]))*(1 + g[4])/(1 + g[0])) - 1;
3909 else g[5] = 1 / (g[1]*SQR(g[3])/2 + 1
3910 - g[2] - g[3] - g[2]*g[3]*(log(g[3]) - 1)) - 1;
3912 memcpy (gamm, g, sizeof gamm);
3915 for (i=0; i < 0x10000; i++) {
3917 if ((r = (double) i / imax) < 1)
3918 curve[i] = 0x10000 * ( mode
3919 ? (r < g[3] ? r*g[1] : (g[0] ? pow( r,g[0])*(1+g[4])-g[4] : log(r)*g[2]+1))
3920 : (r < g[2] ? r/g[1] : (g[0] ? pow((r+g[4])/(1+g[4]),1/g[0]) : exp((r-1)/g[2]))));
3924 void CLASS pseudoinverse (double (*in)[3], double (*out)[3], int size)
3926 double work[3][6], num;
3929 for (i=0; i < 3; i++) {
3930 for (j=0; j < 6; j++)
3931 work[i][j] = j == i+3;
3932 for (j=0; j < 3; j++)
3933 for (k=0; k < size; k++)
3934 work[i][j] += in[k][i] * in[k][j];
3936 for (i=0; i < 3; i++) {
3938 for (j=0; j < 6; j++)
3940 for (k=0; k < 3; k++) {
3943 for (j=0; j < 6; j++)
3944 work[k][j] -= work[i][j] * num;
3947 for (i=0; i < size; i++)
3948 for (j=0; j < 3; j++)
3949 for (out[i][j]=k=0; k < 3; k++)
3950 out[i][j] += work[j][k+3] * in[i][k];
3953 void CLASS cam_xyz_coeff (float rgb_cam[3][4], double cam_xyz[4][3])
3955 double cam_rgb[4][3], inverse[4][3], num;
3958 for (i=0; i < colors; i++) /* Multiply out XYZ colorspace */
3959 for (j=0; j < 3; j++)
3960 for (cam_rgb[i][j] = k=0; k < 3; k++)
3961 cam_rgb[i][j] += cam_xyz[i][k] * xyz_rgb[k][j];
3963 for (i=0; i < colors; i++) { /* Normalize cam_rgb so that */
3964 for (num=j=0; j < 3; j++) /* cam_rgb * (1,1,1) is (1,1,1,1) */
3965 num += cam_rgb[i][j];
3966 for (j=0; j < 3; j++)
3967 cam_rgb[i][j] /= num;
3968 pre_mul[i] = 1 / num;
3970 pseudoinverse (cam_rgb, inverse, colors);
3971 for (i=0; i < 3; i++)
3972 for (j=0; j < colors; j++)
3973 rgb_cam[i][j] = inverse[j][i];
3977 void CLASS colorcheck()
3980 // Coordinates of the GretagMacbeth ColorChecker squares
3981 // width, height, 1st_column, 1st_row
3982 int cut[NSQ][4]; // you must set these
3983 // ColorChecker Chart under 6500-kelvin illumination
3984 static const double gmb_xyY[NSQ][3] = {
3985 { 0.400, 0.350, 10.1 }, // Dark Skin
3986 { 0.377, 0.345, 35.8 }, // Light Skin
3987 { 0.247, 0.251, 19.3 }, // Blue Sky
3988 { 0.337, 0.422, 13.3 }, // Foliage
3989 { 0.265, 0.240, 24.3 }, // Blue Flower
3990 { 0.261, 0.343, 43.1 }, // Bluish Green
3991 { 0.506, 0.407, 30.1 }, // Orange
3992 { 0.211, 0.175, 12.0 }, // Purplish Blue
3993 { 0.453, 0.306, 19.8 }, // Moderate Red
3994 { 0.285, 0.202, 6.6 }, // Purple
3995 { 0.380, 0.489, 44.3 }, // Yellow Green
3996 { 0.473, 0.438, 43.1 }, // Orange Yellow
3997 { 0.187, 0.129, 6.1 }, // Blue
3998 { 0.305, 0.478, 23.4 }, // Green
3999 { 0.539, 0.313, 12.0 }, // Red
4000 { 0.448, 0.470, 59.1 }, // Yellow
4001 { 0.364, 0.233, 19.8 }, // Magenta
4002 { 0.196, 0.252, 19.8 }, // Cyan
4003 { 0.310, 0.316, 90.0 }, // White
4004 { 0.310, 0.316, 59.1 }, // Neutral 8
4005 { 0.310, 0.316, 36.2 }, // Neutral 6.5
4006 { 0.310, 0.316, 19.8 }, // Neutral 5
4007 { 0.310, 0.316, 9.0 }, // Neutral 3.5
4008 { 0.310, 0.316, 3.1 } }; // Black
4009 double gmb_cam[NSQ][4], gmb_xyz[NSQ][3];
4010 double inverse[NSQ][3], cam_xyz[4][3], balance[4], num;
4011 int c, i, j, k, sq, row, col, pass, count[4];
4013 memset (gmb_cam, 0, sizeof gmb_cam);
4014 for (sq=0; sq < NSQ; sq++) {
4016 for (row=cut[sq][3]; row < cut[sq][3]+cut[sq][1]; row++)
4017 for (col=cut[sq][2]; col < cut[sq][2]+cut[sq][0]; col++) {
4019 if (c >= colors) c -= 2;
4020 gmb_cam[sq][c] += BAYER2(row,col);
4021 BAYER2(row,col) = black + (BAYER2(row,col)-black)/2;
4024 FORCC gmb_cam[sq][c] = gmb_cam[sq][c]/count[c] - black;
4025 gmb_xyz[sq][0] = gmb_xyY[sq][2] * gmb_xyY[sq][0] / gmb_xyY[sq][1];
4026 gmb_xyz[sq][1] = gmb_xyY[sq][2];
4027 gmb_xyz[sq][2] = gmb_xyY[sq][2] *
4028 (1 - gmb_xyY[sq][0] - gmb_xyY[sq][1]) / gmb_xyY[sq][1];
4030 pseudoinverse (gmb_xyz, inverse, NSQ);
4031 for (pass=0; pass < 2; pass++) {
4032 for (raw_color = i=0; i < colors; i++)
4033 for (j=0; j < 3; j++)
4034 for (cam_xyz[i][j] = k=0; k < NSQ; k++)
4035 cam_xyz[i][j] += gmb_cam[k][i] * inverse[k][j];
4036 cam_xyz_coeff (rgb_cam, cam_xyz);
4037 FORCC balance[c] = pre_mul[c] * gmb_cam[20][c];
4038 for (sq=0; sq < NSQ; sq++)
4039 FORCC gmb_cam[sq][c] *= balance[c];
4042 printf (" { \"%s %s\", %d,\n\t{", make, model, black);
4043 num = 10000 / (cam_xyz[1][0] + cam_xyz[1][1] + cam_xyz[1][2]);
4044 FORCC for (j=0; j < 3; j++)
4045 printf ("%c%d", (c | j) ? ',':' ', (int) (cam_xyz[c][j] * num + 0.5));
4052 void CLASS hat_transform (float *temp, float *base, int st, int size, int sc)
4055 for (i=0; i < sc; i++)
4056 temp[i] = 2*base[st*i] + base[st*(sc-i)] + base[st*(i+sc)];
4057 for (; i+sc < size; i++)
4058 temp[i] = 2*base[st*i] + base[st*(i-sc)] + base[st*(i+sc)];
4059 for (; i < size; i++)
4060 temp[i] = 2*base[st*i] + base[st*(i-sc)] + base[st*(2*size-2-(i+sc))];
4063 void CLASS wavelet_denoise()
4065 float *fimg=0, *temp, thold, mul[2], avg, diff;
4066 int scale=1, size, lev, hpass, lpass, row, col, nc, c, i, wlast, blk[2];
4068 static const float noise[] =
4069 { 0.8002,0.2735,0.1202,0.0585,0.0291,0.0152,0.0080,0.0044 };
4071 if (verbose) fprintf (stderr,_("Wavelet denoising...\n"));
4073 while (maximum << scale < 0x10000) scale++;
4074 maximum <<= --scale;
4076 FORC4 cblack[c] <<= scale;
4077 if ((size = iheight*iwidth) < 0x15550000)
4078 fimg = (float *) malloc ((size*3 + iheight + iwidth) * sizeof *fimg);
4079 merror (fimg, "wavelet_denoise()");
4080 temp = fimg + size*3;
4081 if ((nc = colors) == 3 && filters) nc++;
4082 FORC(nc) { /* denoise R,G1,B,G3 individually */
4083 for (i=0; i < size; i++)
4084 fimg[i] = 256 * sqrt(image[i][c] << scale);
4085 for (hpass=lev=0; lev < 5; lev++) {
4086 lpass = size*((lev & 1)+1);
4087 for (row=0; row < iheight; row++) {
4088 hat_transform (temp, fimg+hpass+row*iwidth, 1, iwidth, 1 << lev);
4089 for (col=0; col < iwidth; col++)
4090 fimg[lpass + row*iwidth + col] = temp[col] * 0.25;
4092 for (col=0; col < iwidth; col++) {
4093 hat_transform (temp, fimg+lpass+col, iwidth, iheight, 1 << lev);
4094 for (row=0; row < iheight; row++)
4095 fimg[lpass + row*iwidth + col] = temp[row] * 0.25;
4097 thold = threshold * noise[lev];
4098 for (i=0; i < size; i++) {
4099 fimg[hpass+i] -= fimg[lpass+i];
4100 if (fimg[hpass+i] < -thold) fimg[hpass+i] += thold;
4101 else if (fimg[hpass+i] > thold) fimg[hpass+i] -= thold;
4102 else fimg[hpass+i] = 0;
4103 if (hpass) fimg[i] += fimg[hpass+i];
4107 for (i=0; i < size; i++)
4108 image[i][c] = CLIP(SQR(fimg[i]+fimg[lpass+i])/0x10000);
4110 if (filters && colors == 3) { /* pull G1 and G3 closer together */
4111 for (row=0; row < 2; row++) {
4112 mul[row] = 0.125 * pre_mul[FC(row+1,0) | 1] / pre_mul[FC(row,0) | 1];
4113 blk[row] = cblack[FC(row,0) | 1];
4115 for (i=0; i < 4; i++)
4116 window[i] = (ushort *) fimg + width*i;
4117 for (wlast=-1, row=1; row < height-1; row++) {
4118 while (wlast < row+1) {
4119 for (wlast++, i=0; i < 4; i++)
4120 window[(i+3) & 3] = window[i];
4121 for (col = FC(wlast,1) & 1; col < width; col+=2)
4122 window[2][col] = BAYER(wlast,col);
4124 thold = threshold/512;
4125 for (col = (FC(row,0) & 1)+1; col < width-1; col+=2) {
4126 avg = ( window[0][col-1] + window[0][col+1] +
4127 window[2][col-1] + window[2][col+1] - blk[~row & 1]*4 )
4128 * mul[row & 1] + (window[1][col] + blk[row & 1]) * 0.5;
4129 avg = avg < 0 ? 0 : sqrt(avg);
4130 diff = sqrt(BAYER(row,col)) - avg;
4131 if (diff < -thold) diff += thold;
4132 else if (diff > thold) diff -= thold;
4134 BAYER(row,col) = CLIP(SQR(avg+diff) + 0.5);
4141 void CLASS scale_colors()
4143 unsigned bottom, right, size, row, col, ur, uc, i, x, y, c, sum[8];
4145 double dsum[8], dmin, dmax;
4146 float scale_mul[4], fr, fc;
4147 ushort *img=0, *pix;
4150 memcpy (pre_mul, user_mul, sizeof pre_mul);
4151 if (use_auto_wb || (use_camera_wb && cam_mul[0] == -1)) {
4152 memset (dsum, 0, sizeof dsum);
4153 bottom = MIN (greybox[1]+greybox[3], height);
4154 right = MIN (greybox[0]+greybox[2], width);
4155 for (row=greybox[1]; row < bottom; row += 8)
4156 for (col=greybox[0]; col < right; col += 8) {
4157 memset (sum, 0, sizeof sum);
4158 for (y=row; y < row+8 && y < bottom; y++)
4159 for (x=col; x < col+8 && x < right; x++)
4165 val = image[y*width+x][c];
4166 if (val > maximum-25) goto skip_block;
4167 if ((val -= cblack[c]) < 0) val = 0;
4172 FORC(8) dsum[c] += sum[c];
4175 FORC4 if (dsum[c]) pre_mul[c] = dsum[c+4] / dsum[c];
4177 if (use_camera_wb && cam_mul[0] != -1) {
4178 memset (sum, 0, sizeof sum);
4179 for (row=0; row < 8; row++)
4180 for (col=0; col < 8; col++) {
4182 if ((val = white[row][col] - cblack[c]) > 0)
4186 if (sum[0] && sum[1] && sum[2] && sum[3])
4187 FORC4 pre_mul[c] = (float) sum[c+4] / sum[c];
4188 else if (cam_mul[0] && cam_mul[2])
4189 memcpy (pre_mul, cam_mul, sizeof pre_mul);
4191 fprintf (stderr,_("%s: Cannot use camera white balance.\n"), ifname);
4193 if (pre_mul[1] == 0) pre_mul[1] = 1;
4194 if (pre_mul[3] == 0) pre_mul[3] = colors < 4 ? pre_mul[1] : 1;
4197 if (threshold) wavelet_denoise();
4199 for (dmin=DBL_MAX, dmax=c=0; c < 4; c++) {
4200 if (dmin > pre_mul[c])
4202 if (dmax < pre_mul[c])
4205 if (!highlight) dmax = dmin;
4206 FORC4 scale_mul[c] = (pre_mul[c] /= dmax) * 65535.0 / maximum;
4209 _("Scaling with darkness %d, saturation %d, and\nmultipliers"), dark, sat);
4210 FORC4 fprintf (stderr, " %f", pre_mul[c]);
4211 fputc ('\n', stderr);
4213 if (filters > 1000 && (cblack[4]+1)/2 == 1 && (cblack[5]+1)/2 == 1) {
4214 FORC4 cblack[FC(c/2,c%2)] +=
4215 cblack[6 + c/2 % cblack[4] * cblack[5] + c%2 % cblack[5]];
4216 cblack[4] = cblack[5] = 0;
4218 size = iheight*iwidth;
4219 for (i=0; i < size*4; i++) {
4220 if (!(val = ((ushort *)image)[i])) continue;
4221 if (cblack[4] && cblack[5])
4222 val -= cblack[6 + i/4 / iwidth % cblack[4] * cblack[5] +
4223 i/4 % iwidth % cblack[5]];
4224 val -= cblack[i & 3];
4225 val *= scale_mul[i & 3];
4226 ((ushort *)image)[i] = CLIP(val);
4228 if ((aber[0] != 1 || aber[2] != 1) && colors == 3) {
4230 fprintf (stderr,_("Correcting chromatic aberration...\n"));
4231 for (c=0; c < 4; c+=2) {
4232 if (aber[c] == 1) continue;
4233 img = (ushort *) malloc (size * sizeof *img);
4234 merror (img, "scale_colors()");
4235 for (i=0; i < size; i++)
4236 img[i] = image[i][c];
4237 for (row=0; row < iheight; row++) {
4238 ur = fr = (row - iheight*0.5) * aber[c] + iheight*0.5;
4239 if (ur > iheight-2) continue;
4241 for (col=0; col < iwidth; col++) {
4242 uc = fc = (col - iwidth*0.5) * aber[c] + iwidth*0.5;
4243 if (uc > iwidth-2) continue;
4245 pix = img + ur*iwidth + uc;
4246 image[row*iwidth+col][c] =
4247 (pix[ 0]*(1-fc) + pix[ 1]*fc) * (1-fr) +
4248 (pix[iwidth]*(1-fc) + pix[iwidth+1]*fc) * fr;
4256 void CLASS pre_interpolate()
4266 for (row=0; row < 3; row++)
4267 for (col=1; col < 4; col++)
4268 if (!(image[row*width+col][0] | image[row*width+col][2]))
4269 goto break2; break2:
4270 for ( ; row < height; row+=3)
4271 for (col=(col-1)%3+1; col < width-1; col+=3) {
4272 img = image + row*width+col;
4273 for (c=0; c < 3; c+=2)
4274 img[0][c] = (img[-1][c] + img[1][c]) >> 1;
4278 img = (ushort (*)[4]) calloc (height, width*sizeof *img);
4279 merror (img, "pre_interpolate()");
4280 for (row=0; row < height; row++)
4281 for (col=0; col < width; col++) {
4283 img[row*width+col][c] = image[(row >> 1)*iwidth+(col >> 1)][c];
4290 if (filters > 1000 && colors == 3) {
4291 mix_green = four_color_rgb ^ half_size;
4292 if (four_color_rgb | half_size) colors++;
4294 for (row = FC(1,0) >> 1; row < height; row+=2)
4295 for (col = FC(row,1) & 1; col < width; col+=2)
4296 image[row*width+col][1] = image[row*width+col][3];
4297 filters &= ~((filters & 0x55555555) << 1);
4300 if (half_size) filters = 0;
4303 void CLASS border_interpolate (int border)
4305 unsigned row, col, y, x, f, c, sum[8];
4307 for (row=0; row < height; row++)
4308 for (col=0; col < width; col++) {
4309 if (col==border && row >= border && row < height-border)
4311 memset (sum, 0, sizeof sum);
4312 for (y=row-1; y != row+2; y++)
4313 for (x=col-1; x != col+2; x++)
4314 if (y < height && x < width) {
4316 sum[f] += image[y*width+x][f];
4320 FORCC if (c != f && sum[c+4])
4321 image[row*width+col][c] = sum[c] / sum[c+4];
4325 void CLASS lin_interpolate()
4327 int code[16][16][32], size=16, *ip, sum[4];
4328 int f, c, i, x, y, row, col, shift, color;
4331 if (verbose) fprintf (stderr,_("Bilinear interpolation...\n"));
4332 if (filters == 9) size = 6;
4333 border_interpolate(1);
4334 for (row=0; row < size; row++)
4335 for (col=0; col < size; col++) {
4336 ip = code[row][col]+1;
4338 memset (sum, 0, sizeof sum);
4339 for (y=-1; y <= 1; y++)
4340 for (x=-1; x <= 1; x++) {
4341 shift = (y==0) + (x==0);
4342 color = fcol(row+y,col+x);
4343 if (color == f) continue;
4344 *ip++ = (width*y + x)*4 + color;
4347 sum[color] += 1 << shift;
4349 code[row][col][0] = (ip - code[row][col]) / 3;
4353 *ip++ = 256 / sum[c];
4356 for (row=1; row < height-1; row++)
4357 for (col=1; col < width-1; col++) {
4358 pix = image[row*width+col];
4359 ip = code[row % size][col % size];
4360 memset (sum, 0, sizeof sum);
4361 for (i=*ip++; i--; ip+=3)
4362 sum[ip[2]] += pix[ip[0]] << ip[1];
4363 for (i=colors; --i; ip+=2)
4364 pix[ip[0]] = sum[ip[0]] * ip[1] >> 8;
4369 This algorithm is officially called:
4371 "Interpolation using a Threshold-based variable number of gradients"
4373 described in http://scien.stanford.edu/pages/labsite/1999/psych221/projects/99/tingchen/algodep/vargra.html
4375 I've extended the basic idea to work with non-Bayer filter arrays.
4376 Gradients are numbered clockwise from NW=0 to W=7.
4378 void CLASS vng_interpolate()
4380 static const signed char terms[] = {
4381 -2,-2,+0,-1,0,0x01, -2,-2,+0,+0,1,0x01, -2,-1,-1,+0,0,0x01,
4382 -2,-1,+0,-1,0,0x02, -2,-1,+0,+0,0,0x03, -2,-1,+0,+1,1,0x01,
4383 -2,+0,+0,-1,0,0x06, -2,+0,+0,+0,1,0x02, -2,+0,+0,+1,0,0x03,
4384 -2,+1,-1,+0,0,0x04, -2,+1,+0,-1,1,0x04, -2,+1,+0,+0,0,0x06,
4385 -2,+1,+0,+1,0,0x02, -2,+2,+0,+0,1,0x04, -2,+2,+0,+1,0,0x04,
4386 -1,-2,-1,+0,0,0x80, -1,-2,+0,-1,0,0x01, -1,-2,+1,-1,0,0x01,
4387 -1,-2,+1,+0,1,0x01, -1,-1,-1,+1,0,0x88, -1,-1,+1,-2,0,0x40,
4388 -1,-1,+1,-1,0,0x22, -1,-1,+1,+0,0,0x33, -1,-1,+1,+1,1,0x11,
4389 -1,+0,-1,+2,0,0x08, -1,+0,+0,-1,0,0x44, -1,+0,+0,+1,0,0x11,
4390 -1,+0,+1,-2,1,0x40, -1,+0,+1,-1,0,0x66, -1,+0,+1,+0,1,0x22,
4391 -1,+0,+1,+1,0,0x33, -1,+0,+1,+2,1,0x10, -1,+1,+1,-1,1,0x44,
4392 -1,+1,+1,+0,0,0x66, -1,+1,+1,+1,0,0x22, -1,+1,+1,+2,0,0x10,
4393 -1,+2,+0,+1,0,0x04, -1,+2,+1,+0,1,0x04, -1,+2,+1,+1,0,0x04,
4394 +0,-2,+0,+0,1,0x80, +0,-1,+0,+1,1,0x88, +0,-1,+1,-2,0,0x40,
4395 +0,-1,+1,+0,0,0x11, +0,-1,+2,-2,0,0x40, +0,-1,+2,-1,0,0x20,
4396 +0,-1,+2,+0,0,0x30, +0,-1,+2,+1,1,0x10, +0,+0,+0,+2,1,0x08,
4397 +0,+0,+2,-2,1,0x40, +0,+0,+2,-1,0,0x60, +0,+0,+2,+0,1,0x20,
4398 +0,+0,+2,+1,0,0x30, +0,+0,+2,+2,1,0x10, +0,+1,+1,+0,0,0x44,
4399 +0,+1,+1,+2,0,0x10, +0,+1,+2,-1,1,0x40, +0,+1,+2,+0,0,0x60,
4400 +0,+1,+2,+1,0,0x20, +0,+1,+2,+2,0,0x10, +1,-2,+1,+0,0,0x80,
4401 +1,-1,+1,+1,0,0x88, +1,+0,+1,+2,0,0x08, +1,+0,+2,-1,0,0x40,
4403 }, chood[] = { -1,-1, -1,0, -1,+1, 0,+1, +1,+1, +1,0, +1,-1, 0,-1 };
4404 const signed char *cp;
4405 ushort (*brow[5])[4], *pix;
4406 int prow=8, pcol=2, *ip, *code[16][16], gval[8], gmin, gmax, sum[4];
4407 int row, col, x, y, x1, x2, y1, y2, t, weight, grads, color, diag;
4408 int g, diff, thold, num, c;
4411 if (verbose) fprintf (stderr,_("VNG interpolation...\n"));
4413 if (filters == 1) prow = pcol = 16;
4414 if (filters == 9) prow = pcol = 6;
4415 ip = (int *) calloc (prow*pcol, 1280);
4416 merror (ip, "vng_interpolate()");
4417 for (row=0; row < prow; row++) /* Precalculate for VNG */
4418 for (col=0; col < pcol; col++) {
4419 code[row][col] = ip;
4420 for (cp=terms, t=0; t < 64; t++) {
4421 y1 = *cp++; x1 = *cp++;
4422 y2 = *cp++; x2 = *cp++;
4425 color = fcol(row+y1,col+x1);
4426 if (fcol(row+y2,col+x2) != color) continue;
4427 diag = (fcol(row,col+1) == color && fcol(row+1,col) == color) ? 2:1;
4428 if (abs(y1-y2) == diag && abs(x1-x2) == diag) continue;
4429 *ip++ = (y1*width + x1)*4 + color;
4430 *ip++ = (y2*width + x2)*4 + color;
4432 for (g=0; g < 8; g++)
4433 if (grads & 1<<g) *ip++ = g;
4437 for (cp=chood, g=0; g < 8; g++) {
4438 y = *cp++; x = *cp++;
4439 *ip++ = (y*width + x) * 4;
4440 color = fcol(row,col);
4441 if (fcol(row+y,col+x) != color && fcol(row+y*2,col+x*2) == color)
4442 *ip++ = (y*width + x) * 8 + color;
4447 brow[4] = (ushort (*)[4]) calloc (width*3, sizeof **brow);
4448 merror (brow[4], "vng_interpolate()");
4449 for (row=0; row < 3; row++)
4450 brow[row] = brow[4] + row*width;
4451 for (row=2; row < height-2; row++) { /* Do VNG interpolation */
4452 for (col=2; col < width-2; col++) {
4453 pix = image[row*width+col];
4454 ip = code[row % prow][col % pcol];
4455 memset (gval, 0, sizeof gval);
4456 while ((g = ip[0]) != INT_MAX) { /* Calculate gradients */
4457 diff = ABS(pix[g] - pix[ip[1]]) << ip[2];
4458 gval[ip[3]] += diff;
4460 if ((g = ip[-1]) == -1) continue;
4462 while ((g = *ip++) != -1)
4466 gmin = gmax = gval[0]; /* Choose a threshold */
4467 for (g=1; g < 8; g++) {
4468 if (gmin > gval[g]) gmin = gval[g];
4469 if (gmax < gval[g]) gmax = gval[g];
4472 memcpy (brow[2][col], pix, sizeof *image);
4475 thold = gmin + (gmax >> 1);
4476 memset (sum, 0, sizeof sum);
4477 color = fcol(row,col);
4478 for (num=g=0; g < 8; g++,ip+=2) { /* Average the neighbors */
4479 if (gval[g] <= thold) {
4481 if (c == color && ip[1])
4482 sum[c] += (pix[c] + pix[ip[1]]) >> 1;
4484 sum[c] += pix[ip[0] + c];
4488 FORCC { /* Save to buffer */
4491 t += (sum[c] - sum[color]) / num;
4492 brow[2][col][c] = CLIP(t);
4495 if (row > 3) /* Write buffer to image */
4496 memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image);
4497 for (g=0; g < 4; g++)
4498 brow[(g-1) & 3] = brow[g];
4500 memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image);
4501 memcpy (image[(row-1)*width+2], brow[1]+2, (width-4)*sizeof *image);
4507 Patterned Pixel Grouping Interpolation by Alain Desbiolles
4509 void CLASS ppg_interpolate()
4511 int dir[5] = { 1, width, -1, -width, 1 };
4512 int row, col, diff[2], guess[2], c, d, i;
4514 diff[0] = diff[1] = 0;
4516 border_interpolate(3);
4517 if (verbose) fprintf (stderr,_("PPG interpolation...\n"));
4519 /* Fill in the green layer with gradients and pattern recognition: */
4520 for (row=3; row < height-3; row++)
4521 for (col=3+(FC(row,3) & 1), c=FC(row,col); col < width-3; col+=2) {
4522 pix = image + row*width+col;
4523 for (i=0; (d=dir[i]) > 0; i++) {
4524 guess[i] = (pix[-d][1] + pix[0][c] + pix[d][1]) * 2
4525 - pix[-2*d][c] - pix[2*d][c];
4526 diff[i] = ( ABS(pix[-2*d][c] - pix[ 0][c]) +
4527 ABS(pix[ 2*d][c] - pix[ 0][c]) +
4528 ABS(pix[ -d][1] - pix[ d][1]) ) * 3 +
4529 ( ABS(pix[ 3*d][1] - pix[ d][1]) +
4530 ABS(pix[-3*d][1] - pix[-d][1]) ) * 2;
4532 d = dir[i = diff[0] > diff[1]];
4533 pix[0][1] = ULIM(guess[i] >> 2, pix[d][1], pix[-d][1]);
4535 /* Calculate red and blue for each green pixel: */
4536 for (row=1; row < height-1; row++)
4537 for (col=1+(FC(row,2) & 1), c=FC(row,col+1); col < width-1; col+=2) {
4538 pix = image + row*width+col;
4539 for (i=0; (d=dir[i]) > 0; c=2-c, i++)
4540 pix[0][c] = CLIP((pix[-d][c] + pix[d][c] + 2*pix[0][1]
4541 - pix[-d][1] - pix[d][1]) >> 1);
4543 /* Calculate blue for red pixels and vice versa: */
4544 for (row=1; row < height-1; row++)
4545 for (col=1+(FC(row,1) & 1), c=2-FC(row,col); col < width-1; col+=2) {
4546 pix = image + row*width+col;
4547 for (i=0; (d=dir[i]+dir[i+1]) > 0; i++) {
4548 diff[i] = ABS(pix[-d][c] - pix[d][c]) +
4549 ABS(pix[-d][1] - pix[0][1]) +
4550 ABS(pix[ d][1] - pix[0][1]);
4551 guess[i] = pix[-d][c] + pix[d][c] + 2*pix[0][1]
4552 - pix[-d][1] - pix[d][1];
4554 if (diff[0] != diff[1])
4555 pix[0][c] = CLIP(guess[diff[0] > diff[1]] >> 1);
4557 pix[0][c] = CLIP((guess[0]+guess[1]) >> 2);
4561 void CLASS cielab (ushort rgb[3], short lab[3])
4565 float *cbrt = clb_cbrt, (*xyz_cam)[4] = clb_xyz_cam;
4568 for (i=0; i < 0x10000; i++) {
4570 cbrt[i] = r > 0.008856 ? pow(r,1/3.0) : 7.787*r + 16/116.0;
4572 for (i=0; i < 3; i++)
4573 for (j=0; j < colors; j++)
4574 for (xyz_cam[i][j] = k=0; k < 3; k++)
4575 xyz_cam[i][j] += xyz_rgb[i][k] * rgb_cam[k][j] / d65_white[i];
4578 xyz[0] = xyz[1] = xyz[2] = 0.5;
4580 xyz[0] += xyz_cam[0][c] * rgb[c];
4581 xyz[1] += xyz_cam[1][c] * rgb[c];
4582 xyz[2] += xyz_cam[2][c] * rgb[c];
4584 xyz[0] = cbrt[CLIP((int) xyz[0])];
4585 xyz[1] = cbrt[CLIP((int) xyz[1])];
4586 xyz[2] = cbrt[CLIP((int) xyz[2])];
4587 lab[0] = 64 * (116 * xyz[1] - 16);
4588 lab[1] = 64 * 500 * (xyz[0] - xyz[1]);
4589 lab[2] = 64 * 200 * (xyz[1] - xyz[2]);
4592 #define TS 512 /* Tile Size */
4593 #define fcol(row,col) xtrans[(row+6) % 6][(col+6) % 6]
4596 Frank Markesteijn's algorithm for Fuji X-Trans sensors
4598 void CLASS xtrans_interpolate (int passes)
4600 int c, d, f, g, h, i, v, ng, row, col, top, left, mrow, mcol;
4601 int val, ndir, pass, hm[8], avg[4], color[3][8];
4602 static const short orth[12] = { 1,0,0,1,-1,0,0,-1,1,0,0,1 },
4603 patt[2][16] = { { 0,1,0,-1,2,0,-1,0,1,1,1,-1,0,0,0,0 },
4604 { 0,1,0,-2,1,0,-2,0,1,1,-2,-2,1,-1,-1,1 } },
4605 dir[4] = { 1,TS,TS+1,TS-1 };
4606 short allhex[3][3][2][8], *hex;
4608 ushort min, max, sgrow=0, sgcol=0;
4609 ushort (*rgb)[TS][TS][3], (*rix)[3], (*pix)[4];
4610 short (*lab) [TS][3], (*lix)[3];
4611 float (*drv)[TS][TS], diff[6], tr;
4612 char (*homo)[TS][TS], *buffer;
4615 fprintf (stderr,_("%d-pass X-Trans interpolation...\n"), passes);
4618 ndir = 4 << (passes > 1);
4619 buffer = (char *) malloc (TS*TS*(ndir*11+6));
4620 merror (buffer, "xtrans_interpolate()");
4621 rgb = (ushort(*)[TS][TS][3]) buffer;
4622 lab = (short (*) [TS][3])(buffer + TS*TS*(ndir*6));
4623 drv = (float (*)[TS][TS]) (buffer + TS*TS*(ndir*6+6));
4624 homo = (char (*)[TS][TS]) (buffer + TS*TS*(ndir*10+6));
4626 /* Map a green hexagon around each non-green pixel and vice versa: */
4627 for (row=0; row < 3; row++)
4628 for (col=0; col < 3; col++)
4629 for (ng=d=0; d < 10; d+=2) {
4630 g = fcol(row,col) == 1;
4631 if (fcol(row+orth[d],col+orth[d+2]) == 1) ng=0; else ng++;
4632 if (ng == 4) { sgrow = row; sgcol = col; }
4633 if (ng == g+1) FORC(8) {
4634 v = orth[d ]*patt[g][c*2] + orth[d+1]*patt[g][c*2+1];
4635 h = orth[d+2]*patt[g][c*2] + orth[d+3]*patt[g][c*2+1];
4636 allhex[row][col][0][c^(g*2 & d)] = h + v*width;
4637 allhex[row][col][1][c^(g*2 & d)] = h + v*TS;
4641 /* Set green1 and green3 to the minimum and maximum allowed values: */
4642 for (row=2; row < height-2; row++)
4643 for (min=~(max=0), col=2; col < width-2; col++) {
4644 if (fcol(row,col) == 1 && (min=~(max=0))) continue;
4645 pix = image + row*width + col;
4646 hex = allhex[row % 3][col % 3][0];
4648 val = pix[hex[c]][1];
4649 if (min > val) min = val;
4650 if (max < val) max = val;
4654 switch ((row-sgrow) % 3) {
4655 case 1: if (row < height-3) { row++; col--; } break;
4656 case 2: if ((min=~(max=0)) && (col+=2) < width-3 && row > 2) row--;
4660 for (top=3; top < height-19; top += TS-16)
4661 for (left=3; left < width-19; left += TS-16) {
4662 mrow = MIN (top+TS, height-3);
4663 mcol = MIN (left+TS, width-3);
4664 for (row=top; row < mrow; row++)
4665 for (col=left; col < mcol; col++)
4666 memcpy (rgb[0][row-top][col-left], image[row*width+col], 6);
4667 FORC3 memcpy (rgb[c+1], rgb[0], sizeof *rgb);
4669 /* Interpolate green horizontally, vertically, and along both diagonals: */
4670 for (row=top; row < mrow; row++)
4671 for (col=left; col < mcol; col++) {
4672 if ((f = fcol(row,col)) == 1) continue;
4673 pix = image + row*width + col;
4674 hex = allhex[row % 3][col % 3][0];
4675 color[1][0] = 174 * (pix[ hex[1]][1] + pix[ hex[0]][1]) -
4676 46 * (pix[2*hex[1]][1] + pix[2*hex[0]][1]);
4677 color[1][1] = 223 * pix[ hex[3]][1] + pix[ hex[2]][1] * 33 +
4678 92 * (pix[ 0 ][f] - pix[ -hex[2]][f]);
4679 FORC(2) color[1][2+c] =
4680 164 * pix[hex[4+c]][1] + 92 * pix[-2*hex[4+c]][1] + 33 *
4681 (2*pix[0][f] - pix[3*hex[4+c]][f] - pix[-3*hex[4+c]][f]);
4682 FORC4 rgb[c^!((row-sgrow) % 3)][row-top][col-left][1] =
4683 LIM(color[1][c] >> 8,pix[0][1],pix[0][3]);
4686 for (pass=0; pass < passes; pass++) {
4688 memcpy (rgb+=4, buffer, 4*sizeof *rgb);
4690 /* Recalculate green from interpolated values of closer pixels: */
4692 for (row=top+2; row < mrow-2; row++)
4693 for (col=left+2; col < mcol-2; col++) {
4694 if ((f = fcol(row,col)) == 1) continue;
4695 pix = image + row*width + col;
4696 hex = allhex[row % 3][col % 3][1];
4697 for (d=3; d < 6; d++) {
4698 rix = &rgb[(d-2)^!((row-sgrow) % 3)][row-top][col-left];
4699 val = rix[-2*hex[d]][1] + 2*rix[hex[d]][1]
4700 - rix[-2*hex[d]][f] - 2*rix[hex[d]][f] + 3*rix[0][f];
4701 rix[0][1] = LIM(val/3,pix[0][1],pix[0][3]);
4706 /* Interpolate red and blue values for solitary green pixels: */
4707 for (row=(top-sgrow+4)/3*3+sgrow; row < mrow-2; row+=3)
4708 for (col=(left-sgcol+4)/3*3+sgcol; col < mcol-2; col+=3) {
4709 rix = &rgb[0][row-top][col-left];
4710 h = fcol(row,col+1);
4711 memset (diff, 0, sizeof diff);
4712 for (i=1, d=0; d < 6; d++, i^=TS^1, h^=2) {
4713 for (c=0; c < 2; c++, h^=2) {
4714 g = 2*rix[0][1] - rix[i<<c][1] - rix[-i<<c][1];
4715 color[h][d] = g + rix[i<<c][h] + rix[-i<<c][h];
4717 diff[d] += SQR (rix[i<<c][1] - rix[-i<<c][1]
4718 - rix[i<<c][h] + rix[-i<<c][h]) + SQR(g);
4720 if (d > 1 && (d & 1))
4721 if (diff[d-1] < diff[d])
4722 FORC(2) color[c*2][d] = color[c*2][d-1];
4723 if (d < 2 || (d & 1)) {
4724 FORC(2) rix[0][c*2] = CLIP(color[c*2][d]/2);
4730 /* Interpolate red for blue pixels and vice versa: */
4731 for (row=top+3; row < mrow-3; row++)
4732 for (col=left+3; col < mcol-3; col++) {
4733 if ((f = 2-fcol(row,col)) == 1) continue;
4734 rix = &rgb[0][row-top][col-left];
4735 c = (row-sgrow) % 3 ? TS:1;
4736 h = 3 * (c ^ TS ^ 1);
4737 for (d=0; d < 4; d++, rix += TS*TS) {
4738 i = d > 1 || ((d ^ c) & 1) ||
4739 ((ABS(rix[0][1]-rix[c][1])+ABS(rix[0][1]-rix[-c][1])) <
4740 2*(ABS(rix[0][1]-rix[h][1])+ABS(rix[0][1]-rix[-h][1]))) ? c:h;
4741 rix[0][f] = CLIP((rix[i][f] + rix[-i][f] +
4742 2*rix[0][1] - rix[i][1] - rix[-i][1])/2);
4746 /* Fill in red and blue for 2x2 blocks of green: */
4747 for (row=top+2; row < mrow-2; row++) if ((row-sgrow) % 3)
4748 for (col=left+2; col < mcol-2; col++) if ((col-sgcol) % 3) {
4749 rix = &rgb[0][row-top][col-left];
4750 hex = allhex[row % 3][col % 3][1];
4751 for (d=0; d < ndir; d+=2, rix += TS*TS)
4752 if (hex[d] + hex[d+1]) {
4753 g = 3*rix[0][1] - 2*rix[hex[d]][1] - rix[hex[d+1]][1];
4754 for (c=0; c < 4; c+=2) rix[0][c] =
4755 CLIP((g + 2*rix[hex[d]][c] + rix[hex[d+1]][c])/3);
4757 g = 2*rix[0][1] - rix[hex[d]][1] - rix[hex[d+1]][1];
4758 for (c=0; c < 4; c+=2) rix[0][c] =
4759 CLIP((g + rix[hex[d]][c] + rix[hex[d+1]][c])/2);
4763 rgb = (ushort(*)[TS][TS][3]) buffer;
4767 /* Convert to CIELab and differentiate in all directions: */
4768 for (d=0; d < ndir; d++) {
4769 for (row=2; row < mrow-2; row++)
4770 for (col=2; col < mcol-2; col++)
4771 cielab (rgb[d][row][col], lab[row][col]);
4772 for (f=dir[d & 3],row=3; row < mrow-3; row++)
4773 for (col=3; col < mcol-3; col++) {
4774 lix = &lab[row][col];
4775 g = 2*lix[0][0] - lix[f][0] - lix[-f][0];
4776 drv[d][row][col] = SQR(g)
4777 + SQR((2*lix[0][1] - lix[f][1] - lix[-f][1] + g*500/232))
4778 + SQR((2*lix[0][2] - lix[f][2] - lix[-f][2] - g*500/580));
4782 /* Build homogeneity maps from the derivatives: */
4783 memset(homo, 0, ndir*TS*TS);
4784 for (row=4; row < mrow-4; row++)
4785 for (col=4; col < mcol-4; col++) {
4786 for (tr=FLT_MAX, d=0; d < ndir; d++)
4787 if (tr > drv[d][row][col])
4788 tr = drv[d][row][col];
4790 for (d=0; d < ndir; d++)
4791 for (v=-1; v <= 1; v++)
4792 for (h=-1; h <= 1; h++)
4793 if (drv[d][row+v][col+h] <= tr)
4794 homo[d][row][col]++;
4797 /* Average the most homogenous pixels for the final result: */
4798 if (height-top < TS+4) mrow = height-top+2;
4799 if (width-left < TS+4) mcol = width-left+2;
4800 for (row = MIN(top,8); row < mrow-8; row++)
4801 for (col = MIN(left,8); col < mcol-8; col++) {
4802 for (d=0; d < ndir; d++)
4803 for (hm[d]=0, v=-2; v <= 2; v++)
4804 for (h=-2; h <= 2; h++)
4805 hm[d] += homo[d][row+v][col+h];
4806 for (d=0; d < ndir-4; d++)
4807 if (hm[d] < hm[d+4]) hm[d ] = 0; else
4808 if (hm[d] > hm[d+4]) hm[d+4] = 0;
4809 for (max=hm[0],d=1; d < ndir; d++)
4810 if (max < hm[d]) max = hm[d];
4812 memset (avg, 0, sizeof avg);
4813 for (d=0; d < ndir; d++)
4815 FORC3 avg[c] += rgb[d][row][col][c];
4818 FORC3 image[(row+top)*width+col+left][c] = avg[c]/avg[3];
4822 border_interpolate(8);
4827 Adaptive Homogeneity-Directed interpolation is based on
4828 the work of Keigo Hirakawa, Thomas Parks, and Paul Lee.
4830 void CLASS ahd_interpolate()
4832 int i, j, top, left, row, col, tr, tc, c, d, val, hm[2];
4833 static const int dir[4] = { -1, 1, -TS, TS };
4834 unsigned ldiff[2][4], abdiff[2][4], leps, abeps;
4835 ushort (*rgb)[TS][TS][3], (*rix)[3], (*pix)[4];
4836 short (*lab)[TS][TS][3], (*lix)[3];
4837 char (*homo)[TS][TS], *buffer;
4839 if (verbose) fprintf (stderr,_("AHD interpolation...\n"));
4842 border_interpolate(5);
4843 buffer = (char *) malloc (26*TS*TS);
4844 merror (buffer, "ahd_interpolate()");
4845 rgb = (ushort(*)[TS][TS][3]) buffer;
4846 lab = (short (*)[TS][TS][3])(buffer + 12*TS*TS);
4847 homo = (char (*)[TS][TS]) (buffer + 24*TS*TS);
4849 for (top=2; top < height-5; top += TS-6)
4850 for (left=2; left < width-5; left += TS-6) {
4852 /* Interpolate green horizontally and vertically: */
4853 for (row=top; row < top+TS && row < height-2; row++) {
4854 col = left + (FC(row,left) & 1);
4855 for (c = FC(row,col); col < left+TS && col < width-2; col+=2) {
4856 pix = image + row*width+col;
4857 val = ((pix[-1][1] + pix[0][c] + pix[1][1]) * 2
4858 - pix[-2][c] - pix[2][c]) >> 2;
4859 rgb[0][row-top][col-left][1] = ULIM(val,pix[-1][1],pix[1][1]);
4860 val = ((pix[-width][1] + pix[0][c] + pix[width][1]) * 2
4861 - pix[-2*width][c] - pix[2*width][c]) >> 2;
4862 rgb[1][row-top][col-left][1] = ULIM(val,pix[-width][1],pix[width][1]);
4865 /* Interpolate red and blue, and convert to CIELab: */
4866 for (d=0; d < 2; d++)
4867 for (row=top+1; row < top+TS-1 && row < height-3; row++)
4868 for (col=left+1; col < left+TS-1 && col < width-3; col++) {
4869 pix = image + row*width+col;
4870 rix = &rgb[d][row-top][col-left];
4871 lix = &lab[d][row-top][col-left];
4872 if ((c = 2 - FC(row,col)) == 1) {
4874 val = pix[0][1] + (( pix[-1][2-c] + pix[1][2-c]
4875 - rix[-1][1] - rix[1][1] ) >> 1);
4876 rix[0][2-c] = CLIP(val);
4877 val = pix[0][1] + (( pix[-width][c] + pix[width][c]
4878 - rix[-TS][1] - rix[TS][1] ) >> 1);
4880 val = rix[0][1] + (( pix[-width-1][c] + pix[-width+1][c]
4881 + pix[+width-1][c] + pix[+width+1][c]
4882 - rix[-TS-1][1] - rix[-TS+1][1]
4883 - rix[+TS-1][1] - rix[+TS+1][1] + 1) >> 2);
4884 rix[0][c] = CLIP(val);
4886 rix[0][c] = pix[0][c];
4887 cielab (rix[0],lix[0]);
4889 /* Build homogeneity maps from the CIELab images: */
4890 memset (homo, 0, 2*TS*TS);
4891 for (row=top+2; row < top+TS-2 && row < height-4; row++) {
4893 for (col=left+2; col < left+TS-2 && col < width-4; col++) {
4895 for (d=0; d < 2; d++) {
4896 lix = &lab[d][tr][tc];
4897 for (i=0; i < 4; i++) {
4898 ldiff[d][i] = ABS(lix[0][0]-lix[dir[i]][0]);
4899 abdiff[d][i] = SQR(lix[0][1]-lix[dir[i]][1])
4900 + SQR(lix[0][2]-lix[dir[i]][2]);
4903 leps = MIN(MAX(ldiff[0][0],ldiff[0][1]),
4904 MAX(ldiff[1][2],ldiff[1][3]));
4905 abeps = MIN(MAX(abdiff[0][0],abdiff[0][1]),
4906 MAX(abdiff[1][2],abdiff[1][3]));
4907 for (d=0; d < 2; d++)
4908 for (i=0; i < 4; i++)
4909 if (ldiff[d][i] <= leps && abdiff[d][i] <= abeps)
4913 /* Combine the most homogenous pixels for the final result: */
4914 for (row=top+3; row < top+TS-3 && row < height-5; row++) {
4916 for (col=left+3; col < left+TS-3 && col < width-5; col++) {
4918 for (d=0; d < 2; d++)
4919 for (hm[d]=0, i=tr-1; i <= tr+1; i++)
4920 for (j=tc-1; j <= tc+1; j++)
4921 hm[d] += homo[d][i][j];
4923 FORC3 image[row*width+col][c] = rgb[hm[1] > hm[0]][tr][tc][c];
4925 FORC3 image[row*width+col][c] =
4926 (rgb[0][tr][tc][c] + rgb[1][tr][tc][c]) >> 1;
4934 void CLASS median_filter()
4937 int pass, c, i, j, k, med[9];
4938 static const uchar opt[] = /* Optimal 9-element median search */
4939 { 1,2, 4,5, 7,8, 0,1, 3,4, 6,7, 1,2, 4,5, 7,8,
4940 0,3, 5,8, 4,7, 3,6, 1,4, 2,5, 4,7, 4,2, 6,4, 4,2 };
4942 for (pass=1; pass <= med_passes; pass++) {
4944 fprintf (stderr,_("Median filter pass %d...\n"), pass);
4945 for (c=0; c < 3; c+=2) {
4946 for (pix = image; pix < image+width*height; pix++)
4947 pix[0][3] = pix[0][c];
4948 for (pix = image+width; pix < image+width*(height-1); pix++) {
4949 if ((pix-image+1) % width < 2) continue;
4950 for (k=0, i = -width; i <= width; i += width)
4951 for (j = i-1; j <= i+1; j++)
4952 med[k++] = pix[j][3] - pix[j][1];
4953 for (i=0; i < sizeof opt; i+=2)
4954 if (med[opt[i]] > med[opt[i+1]])
4955 SWAP (med[opt[i]] , med[opt[i+1]]);
4956 pix[0][c] = CLIP(med[4] + pix[0][1]);
4962 void CLASS blend_highlights()
4964 int clip=INT_MAX, row, col, c, i, j;
4965 static const float trans[2][4][4] =
4966 { { { 1,1,1 }, { 1.7320508,-1.7320508,0 }, { -1,-1,2 } },
4967 { { 1,1,1,1 }, { 1,-1,1,-1 }, { 1,1,-1,-1 }, { 1,-1,-1,1 } } };
4968 static const float itrans[2][4][4] =
4969 { { { 1,0.8660254,-0.5 }, { 1,-0.8660254,-0.5 }, { 1,0,1 } },
4970 { { 1,1,1,1 }, { 1,-1,1,-1 }, { 1,1,-1,-1 }, { 1,-1,-1,1 } } };
4971 float cam[2][4], lab[2][4], sum[2], chratio;
4973 if ((unsigned) (colors-3) > 1) return;
4974 if (verbose) fprintf (stderr,_("Blending highlights...\n"));
4975 FORCC if (clip > (i = 65535*pre_mul[c])) clip = i;
4976 for (row=0; row < height; row++)
4977 for (col=0; col < width; col++) {
4978 FORCC if (image[row*width+col][c] > clip) break;
4979 if (c == colors) continue;
4981 cam[0][c] = image[row*width+col][c];
4982 cam[1][c] = MIN(cam[0][c],clip);
4984 for (i=0; i < 2; i++) {
4985 FORCC for (lab[i][c]=j=0; j < colors; j++)
4986 lab[i][c] += trans[colors-3][c][j] * cam[i][j];
4987 for (sum[i]=0,c=1; c < colors; c++)
4988 sum[i] += SQR(lab[i][c]);
4990 chratio = sqrt(sum[1]/sum[0]);
4991 for (c=1; c < colors; c++)
4992 lab[0][c] *= chratio;
4993 FORCC for (cam[0][c]=j=0; j < colors; j++)
4994 cam[0][c] += itrans[colors-3][c][j] * lab[0][j];
4995 FORCC image[row*width+col][c] = cam[0][c] / colors;
4999 #define SCALE (4 >> shrink)
5000 void CLASS recover_highlights()
5002 float *map, sum, wgt, grow;
5003 int hsat[4], count, spread, change, val, i;
5004 unsigned high, wide, mrow, mcol, row, col, kc, c, d, y, x;
5006 static const signed char dir[8][2] =
5007 { {-1,-1}, {-1,0}, {-1,1}, {0,1}, {1,1}, {1,0}, {1,-1}, {0,-1} };
5009 if (verbose) fprintf (stderr,_("Rebuilding highlights...\n"));
5011 grow = pow (2, 4-highlight);
5012 FORCC hsat[c] = 32000 * pre_mul[c];
5013 for (kc=0, c=1; c < colors; c++)
5014 if (pre_mul[kc] < pre_mul[c]) kc = c;
5015 high = height / SCALE;
5016 wide = width / SCALE;
5017 map = (float *) calloc (high, wide*sizeof *map);
5018 merror (map, "recover_highlights()");
5019 FORCC if (c != kc) {
5020 memset (map, 0, high*wide*sizeof *map);
5021 for (mrow=0; mrow < high; mrow++)
5022 for (mcol=0; mcol < wide; mcol++) {
5023 sum = wgt = count = 0;
5024 for (row = mrow*SCALE; row < (mrow+1)*SCALE; row++)
5025 for (col = mcol*SCALE; col < (mcol+1)*SCALE; col++) {
5026 pixel = image[row*width+col];
5027 if (pixel[c] / hsat[c] == 1 && pixel[kc] > 24000) {
5033 if (count == SCALE*SCALE)
5034 map[mrow*wide+mcol] = sum / wgt;
5036 for (spread = 32/grow; spread--; ) {
5037 for (mrow=0; mrow < high; mrow++)
5038 for (mcol=0; mcol < wide; mcol++) {
5039 if (map[mrow*wide+mcol]) continue;
5041 for (d=0; d < 8; d++) {
5042 y = mrow + dir[d][0];
5043 x = mcol + dir[d][1];
5044 if (y < high && x < wide && map[y*wide+x] > 0) {
5045 sum += (1 + (d & 1)) * map[y*wide+x];
5046 count += 1 + (d & 1);
5050 map[mrow*wide+mcol] = - (sum+grow) / (count+grow);
5052 for (change=i=0; i < high*wide; i++)
5059 for (i=0; i < high*wide; i++)
5060 if (map[i] == 0) map[i] = 1;
5061 for (mrow=0; mrow < high; mrow++)
5062 for (mcol=0; mcol < wide; mcol++) {
5063 for (row = mrow*SCALE; row < (mrow+1)*SCALE; row++)
5064 for (col = mcol*SCALE; col < (mcol+1)*SCALE; col++) {
5065 pixel = image[row*width+col];
5066 if (pixel[c] / hsat[c] > 1) {
5067 val = pixel[kc] * map[mrow*wide+mcol];
5068 if (pixel[c] < val) pixel[c] = CLIP(val);
5077 void CLASS tiff_get (unsigned base,
5078 unsigned *tag, unsigned *type, unsigned *len, unsigned *save)
5083 *save = ftell(ifp) + 4;
5084 if (*len * ("11124811248484"[*type < 14 ? *type:0]-'0') > 4)
5085 fseek (ifp, get4()+base, SEEK_SET);
5088 void CLASS parse_thumb_note (int base, unsigned toff, unsigned tlen)
5090 unsigned entries, tag, type, len, save;
5094 tiff_get (base, &tag, &type, &len, &save);
5095 if (tag == toff) thumb_offset = get4()+base;
5096 if (tag == tlen) thumb_length = get4();
5097 fseek (ifp, save, SEEK_SET);
5101 void CLASS parse_makernote (int base, int uptag)
5103 static const uchar xlat[2][256] = {
5104 { 0xc1,0xbf,0x6d,0x0d,0x59,0xc5,0x13,0x9d,0x83,0x61,0x6b,0x4f,0xc7,0x7f,0x3d,0x3d,
5105 0x53,0x59,0xe3,0xc7,0xe9,0x2f,0x95,0xa7,0x95,0x1f,0xdf,0x7f,0x2b,0x29,0xc7,0x0d,
5106 0xdf,0x07,0xef,0x71,0x89,0x3d,0x13,0x3d,0x3b,0x13,0xfb,0x0d,0x89,0xc1,0x65,0x1f,
5107 0xb3,0x0d,0x6b,0x29,0xe3,0xfb,0xef,0xa3,0x6b,0x47,0x7f,0x95,0x35,0xa7,0x47,0x4f,
5108 0xc7,0xf1,0x59,0x95,0x35,0x11,0x29,0x61,0xf1,0x3d,0xb3,0x2b,0x0d,0x43,0x89,0xc1,
5109 0x9d,0x9d,0x89,0x65,0xf1,0xe9,0xdf,0xbf,0x3d,0x7f,0x53,0x97,0xe5,0xe9,0x95,0x17,
5110 0x1d,0x3d,0x8b,0xfb,0xc7,0xe3,0x67,0xa7,0x07,0xf1,0x71,0xa7,0x53,0xb5,0x29,0x89,
5111 0xe5,0x2b,0xa7,0x17,0x29,0xe9,0x4f,0xc5,0x65,0x6d,0x6b,0xef,0x0d,0x89,0x49,0x2f,
5112 0xb3,0x43,0x53,0x65,0x1d,0x49,0xa3,0x13,0x89,0x59,0xef,0x6b,0xef,0x65,0x1d,0x0b,
5113 0x59,0x13,0xe3,0x4f,0x9d,0xb3,0x29,0x43,0x2b,0x07,0x1d,0x95,0x59,0x59,0x47,0xfb,
5114 0xe5,0xe9,0x61,0x47,0x2f,0x35,0x7f,0x17,0x7f,0xef,0x7f,0x95,0x95,0x71,0xd3,0xa3,
5115 0x0b,0x71,0xa3,0xad,0x0b,0x3b,0xb5,0xfb,0xa3,0xbf,0x4f,0x83,0x1d,0xad,0xe9,0x2f,
5116 0x71,0x65,0xa3,0xe5,0x07,0x35,0x3d,0x0d,0xb5,0xe9,0xe5,0x47,0x3b,0x9d,0xef,0x35,
5117 0xa3,0xbf,0xb3,0xdf,0x53,0xd3,0x97,0x53,0x49,0x71,0x07,0x35,0x61,0x71,0x2f,0x43,
5118 0x2f,0x11,0xdf,0x17,0x97,0xfb,0x95,0x3b,0x7f,0x6b,0xd3,0x25,0xbf,0xad,0xc7,0xc5,
5119 0xc5,0xb5,0x8b,0xef,0x2f,0xd3,0x07,0x6b,0x25,0x49,0x95,0x25,0x49,0x6d,0x71,0xc7 },
5120 { 0xa7,0xbc,0xc9,0xad,0x91,0xdf,0x85,0xe5,0xd4,0x78,0xd5,0x17,0x46,0x7c,0x29,0x4c,
5121 0x4d,0x03,0xe9,0x25,0x68,0x11,0x86,0xb3,0xbd,0xf7,0x6f,0x61,0x22,0xa2,0x26,0x34,
5122 0x2a,0xbe,0x1e,0x46,0x14,0x68,0x9d,0x44,0x18,0xc2,0x40,0xf4,0x7e,0x5f,0x1b,0xad,
5123 0x0b,0x94,0xb6,0x67,0xb4,0x0b,0xe1,0xea,0x95,0x9c,0x66,0xdc,0xe7,0x5d,0x6c,0x05,
5124 0xda,0xd5,0xdf,0x7a,0xef,0xf6,0xdb,0x1f,0x82,0x4c,0xc0,0x68,0x47,0xa1,0xbd,0xee,
5125 0x39,0x50,0x56,0x4a,0xdd,0xdf,0xa5,0xf8,0xc6,0xda,0xca,0x90,0xca,0x01,0x42,0x9d,
5126 0x8b,0x0c,0x73,0x43,0x75,0x05,0x94,0xde,0x24,0xb3,0x80,0x34,0xe5,0x2c,0xdc,0x9b,
5127 0x3f,0xca,0x33,0x45,0xd0,0xdb,0x5f,0xf5,0x52,0xc3,0x21,0xda,0xe2,0x22,0x72,0x6b,
5128 0x3e,0xd0,0x5b,0xa8,0x87,0x8c,0x06,0x5d,0x0f,0xdd,0x09,0x19,0x93,0xd0,0xb9,0xfc,
5129 0x8b,0x0f,0x84,0x60,0x33,0x1c,0x9b,0x45,0xf1,0xf0,0xa3,0x94,0x3a,0x12,0x77,0x33,
5130 0x4d,0x44,0x78,0x28,0x3c,0x9e,0xfd,0x65,0x57,0x16,0x94,0x6b,0xfb,0x59,0xd0,0xc8,
5131 0x22,0x36,0xdb,0xd2,0x63,0x98,0x43,0xa1,0x04,0x87,0x86,0xf7,0xa6,0x26,0xbb,0xd6,
5132 0x59,0x4d,0xbf,0x6a,0x2e,0xaa,0x2b,0xef,0xe6,0x78,0xb6,0x4e,0xe0,0x2f,0xdc,0x7c,
5133 0xbe,0x57,0x19,0x32,0x7e,0x2a,0xd0,0xb8,0xba,0x29,0x00,0x3c,0x52,0x7d,0xa8,0x49,
5134 0x3b,0x2d,0xeb,0x25,0x49,0xfa,0xa3,0xaa,0x39,0xa7,0xc5,0xa7,0x50,0x11,0x36,0xfb,
5135 0xc6,0x67,0x4a,0xf5,0xa5,0x12,0x65,0x7e,0xb0,0xdf,0xaf,0x4e,0xb3,0x61,0x7f,0x2f } };
5136 unsigned offset=0, entries, tag, type, len, save, c;
5137 unsigned ver97=0, serial=0, i, wbi=0, wb[4]={0,0,0,0};
5138 uchar buf97[324], ci, cj, ck;
5139 short morder, sorder=order;
5142 The MakerNote might have its own TIFF header (possibly with
5143 its own byte-order!), or it might just be a table.
5145 if (!strcmp(make,"Nokia")) return;
5146 fread (buf, 1, 10, ifp);
5147 if (!strncmp (buf,"KDK" ,3) || /* these aren't TIFF tables */
5148 !strncmp (buf,"VER" ,3) ||
5149 !strncmp (buf,"IIII",4) ||
5150 !strncmp (buf,"MMMM",4)) return;
5151 if (!strncmp (buf,"KC" ,2) || /* Konica KD-400Z, KD-510Z */
5152 !strncmp (buf,"MLY" ,3)) { /* Minolta DiMAGE G series */
5154 while ((i=ftell(ifp)) < data_offset && i < 16384) {
5155 wb[0] = wb[2]; wb[2] = wb[1]; wb[1] = wb[3];
5157 if (wb[1] == 256 && wb[3] == 256 &&
5158 wb[0] > 256 && wb[0] < 640 && wb[2] > 256 && wb[2] < 640)
5159 FORC4 cam_mul[c] = wb[c];
5163 if (!strcmp (buf,"Nikon")) {
5166 if (get2() != 42) goto quit;
5168 fseek (ifp, offset-8, SEEK_CUR);
5169 } else if (!strcmp (buf,"OLYMPUS") ||
5170 !strcmp (buf,"PENTAX ")) {
5171 base = ftell(ifp)-10;
5172 fseek (ifp, -2, SEEK_CUR);
5174 if (buf[0] == 'O') get2();
5175 } else if (!strncmp (buf,"SONY",4) ||
5176 !strcmp (buf,"Panasonic")) {
5178 } else if (!strncmp (buf,"FUJIFILM",8)) {
5179 base = ftell(ifp)-10;
5181 fseek (ifp, 2, SEEK_CUR);
5182 } else if (!strcmp (buf,"OLYMP") ||
5183 !strcmp (buf,"LEICA") ||
5184 !strcmp (buf,"Ricoh") ||
5185 !strcmp (buf,"EPSON"))
5186 fseek (ifp, -2, SEEK_CUR);
5187 else if (!strcmp (buf,"AOC") ||
5188 !strcmp (buf,"QVC"))
5189 fseek (ifp, -4, SEEK_CUR);
5191 fseek (ifp, -10, SEEK_CUR);
5192 if (!strncmp(make,"SAMSUNG",7))
5196 if (entries > 1000) return;
5200 tiff_get (base, &tag, &type, &len, &save);
5202 if (tag == 2 && strstr(make,"NIKON") && !iso_speed)
5203 iso_speed = (get2(),get2());
5204 if (tag == 4 && len > 26 && len < 35) {
5205 if ((i=(get4(),get2())) != 0x7fff && !iso_speed)
5206 iso_speed = 50 * pow (2, i/32.0 - 4);
5207 if ((i=(get2(),get2())) != 0x7fff && !aperture)
5208 aperture = pow (2, i/64.0);
5209 if ((i=get2()) != 0xffff && !shutter)
5210 shutter = pow (2, (short) i/-32.0);
5211 wbi = (get2(),get2());
5212 shot_order = (get2(),get2());
5214 if ((tag == 4 || tag == 0x114) && !strncmp(make,"KONICA",6)) {
5215 fseek (ifp, tag == 4 ? 140:160, SEEK_CUR);
5217 case 72: flip = 0; break;
5218 case 76: flip = 6; break;
5219 case 82: flip = 5; break;
5222 if (tag == 7 && type == 2 && len > 20)
5223 fgets (model2, 64, ifp);
5224 if (tag == 8 && type == 4)
5225 shot_order = get4();
5226 if (tag == 9 && !strcmp(make,"Canon"))
5227 fread (artist, 64, 1, ifp);
5228 if (tag == 0xc && len == 4)
5229 FORC3 cam_mul[(c << 1 | c >> 1) & 3] = getreal(type);
5230 if (tag == 0xd && type == 7 && get2() == 0xaaaa) {
5231 for (c=i=2; (ushort) c != 0xbbbb && i < len; i++)
5232 c = c << 8 | fgetc(ifp);
5233 while ((i+=4) < len-5)
5234 if (get4() == 257 && (i=len) && (c = (get4(),fgetc(ifp))) < 3)
5235 flip = "065"[c]-'0';
5237 if (tag == 0x10 && type == 4)
5239 if (tag == 0x11 && is_raw && !strncmp(make,"NIKON",5)) {
5240 fseek (ifp, get4()+base, SEEK_SET);
5241 parse_tiff_ifd (base);
5243 if (tag == 0x14 && type == 7) {
5245 fseek (ifp, 1248, SEEK_CUR);
5248 fread (buf, 1, 10, ifp);
5249 if (!strncmp(buf,"NRW ",4)) {
5250 fseek (ifp, strcmp(buf+4,"0100") ? 46:1546, SEEK_CUR);
5251 cam_mul[0] = get4() << 2;
5252 cam_mul[1] = get4() + get4();
5253 cam_mul[2] = get4() << 2;
5256 if (tag == 0x15 && type == 2 && is_raw)
5257 fread (model, 64, 1, ifp);
5258 if (strstr(make,"PENTAX")) {
5259 if (tag == 0x1b) tag = 0x1018;
5260 if (tag == 0x1c) tag = 0x1017;
5263 while ((c = fgetc(ifp)) && c != EOF)
5264 serial = serial*10 + (isdigit(c) ? c - '0' : c % 10);
5265 if (tag == 0x29 && type == 1) {
5266 c = wbi < 18 ? "012347800000005896"[wbi]-'0' : 0;
5267 fseek (ifp, 8 + c*32, SEEK_CUR);
5268 FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get4();
5270 if (tag == 0x3d && type == 3 && len == 4)
5271 FORC4 cblack[c ^ c >> 1] = get2() >> (14-tiff_bps);
5272 if (tag == 0x81 && type == 4) {
5273 data_offset = get4();
5274 fseek (ifp, data_offset + 41, SEEK_SET);
5275 raw_height = get2() * 2;
5277 filters = 0x61616161;
5279 if ((tag == 0x81 && type == 7) ||
5280 (tag == 0x100 && type == 7) ||
5281 (tag == 0x280 && type == 1)) {
5282 thumb_offset = ftell(ifp);
5285 if (tag == 0x88 && type == 4 && (thumb_offset = get4()))
5286 thumb_offset += base;
5287 if (tag == 0x89 && type == 4)
5288 thumb_length = get4();
5289 if (tag == 0x8c || tag == 0x96)
5290 meta_offset = ftell(ifp);
5292 for (i=0; i < 4; i++)
5293 ver97 = ver97 * 10 + fgetc(ifp)-'0';
5296 fseek (ifp, 68, SEEK_CUR);
5297 FORC4 cam_mul[(c >> 1) | ((c & 1) << 1)] = get2();
5300 fseek (ifp, 6, SEEK_CUR);
5301 FORC4 cam_mul[c ^ (c >> 1)] = get2();
5304 fseek (ifp, 16, SEEK_CUR);
5305 FORC4 cam_mul[c] = get2();
5308 if (ver97 != 205) fseek (ifp, 280, SEEK_CUR);
5309 fread (buf97, 324, 1, ifp);
5312 if (tag == 0xa1 && type == 7) {
5314 fseek (ifp, 140, SEEK_CUR);
5315 FORC3 cam_mul[c] = get4();
5317 if (tag == 0xa4 && type == 3) {
5318 fseek (ifp, wbi*48, SEEK_CUR);
5319 FORC3 cam_mul[c] = get2();
5321 if (tag == 0xa7 && (unsigned) (ver97-200) < 17) {
5322 ci = xlat[0][serial & 0xff];
5323 cj = xlat[1][fgetc(ifp)^fgetc(ifp)^fgetc(ifp)^fgetc(ifp)];
5325 for (i=0; i < 324; i++)
5326 buf97[i] ^= (cj += ci * ck++);
5327 i = "66666>666;6A;:;55"[ver97-200] - '0';
5328 FORC4 cam_mul[c ^ (c >> 1) ^ (i & 1)] =
5329 sget2 (buf97 + (i & -2) + c*2);
5331 if (tag == 0x200 && len == 3)
5332 shot_order = (get4(),get4());
5333 if (tag == 0x200 && len == 4)
5334 FORC4 cblack[c ^ c >> 1] = get2();
5335 if (tag == 0x201 && len == 4)
5336 FORC4 cam_mul[c ^ (c >> 1)] = get2();
5337 if (tag == 0x220 && type == 7)
5338 meta_offset = ftell(ifp);
5339 if (tag == 0x401 && type == 4 && len == 4)
5340 FORC4 cblack[c ^ c >> 1] = get4();
5341 if (tag == 0xe01) { /* Nikon Capture Note */
5343 fseek (ifp, 22, SEEK_CUR);
5344 for (offset=22; offset+22 < len; offset += 22+i) {
5346 fseek (ifp, 14, SEEK_CUR);
5348 if (tag == 0x76a43207) flip = get2();
5349 else fseek (ifp, i, SEEK_CUR);
5352 if (tag == 0xe80 && len == 256 && type == 7) {
5353 fseek (ifp, 48, SEEK_CUR);
5354 cam_mul[0] = get2() * 508 * 1.078 / 0x10000;
5355 cam_mul[2] = get2() * 382 * 1.173 / 0x10000;
5357 if (tag == 0xf00 && type == 7) {
5359 fseek (ifp, 176, SEEK_CUR);
5360 else if (len == 734 || len == 1502)
5361 fseek (ifp, 148, SEEK_CUR);
5365 if ((tag == 0x1011 && len == 9) || tag == 0x20400200)
5366 for (i=0; i < 3; i++)
5367 FORC3 cmatrix[i][c] = ((short) get2()) / 256.0;
5368 if ((tag == 0x1012 || tag == 0x20400600) && len == 4)
5369 FORC4 cblack[c ^ c >> 1] = get2();
5370 if (tag == 0x1017 || tag == 0x20400100)
5371 cam_mul[0] = get2() / 256.0;
5372 if (tag == 0x1018 || tag == 0x20400100)
5373 cam_mul[2] = get2() / 256.0;
5374 if (tag == 0x2011 && len == 2) {
5377 cam_mul[0] = get2() / 256.0;
5378 cam_mul[2] = get2() / 256.0;
5380 if ((tag | 0x70) == 0x2070 && (type == 4 || type == 13))
5381 fseek (ifp, get4()+base, SEEK_SET);
5382 if (tag == 0x2020 && !strncmp(buf,"OLYMP",5))
5383 parse_thumb_note (base, 257, 258);
5385 parse_makernote (base, 0x2040);
5386 if (tag == 0xb028) {
5387 fseek (ifp, get4()+base, SEEK_SET);
5388 parse_thumb_note (base, 136, 137);
5390 if (tag == 0x4001 && len > 500) {
5391 i = len == 582 ? 50 : len == 653 ? 68 : len == 5120 ? 142 : 126;
5392 fseek (ifp, i, SEEK_CUR);
5393 FORC4 cam_mul[c ^ (c >> 1)] = get2();
5394 for (i+=18; i <= len; i+=10) {
5396 FORC4 sraw_mul[c ^ (c >> 1)] = get2();
5397 if (sraw_mul[1] == 1170) break;
5400 if (tag == 0x4021 && get4() && get4())
5401 FORC4 cam_mul[c] = 1024;
5403 FORC4 cam_mul[c ^ (c >> 1)] = get4();
5405 FORC4 cam_mul[c ^ (c >> 1)] -= get4();
5409 fseek (ifp, save, SEEK_SET);
5416 Since the TIFF DateTime string has no timezone information,
5417 assume that the camera's clock was set to Universal Time.
5419 void CLASS get_timestamp (int reversed)
5427 for (i=19; i--; ) str[i] = fgetc(ifp);
5429 fread (str, 19, 1, ifp);
5430 memset (&t, 0, sizeof t);
5431 if (sscanf (str, "%d:%d:%d %d:%d:%d", &t.tm_year, &t.tm_mon,
5432 &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec) != 6)
5438 timestamp = mktime(&t);
5441 void CLASS parse_exif (int base)
5443 unsigned kodak, entries, tag, type, len, save, c;
5446 kodak = !strncmp(make,"EASTMAN",7) && tiff_nifds < 3;
5449 tiff_get (base, &tag, &type, &len, &save);
5451 case 33434: tiff_ifd[tiff_nifds-1].shutter =
5452 shutter = getreal(type); break;
5453 case 33437: aperture = getreal(type); break;
5454 case 34855: iso_speed = get2(); break;
5456 case 36868: get_timestamp(0); break;
5457 case 37377: if ((expo = -getreal(type)) < 128)
5458 tiff_ifd[tiff_nifds-1].shutter =
5459 shutter = pow (2, expo); break;
5460 case 37378: aperture = pow (2, getreal(type)/2); break;
5461 case 37386: focal_len = getreal(type); break;
5462 case 37500: parse_makernote (base, 0); break;
5463 case 40962: if (kodak) raw_width = get4(); break;
5464 case 40963: if (kodak) raw_height = get4(); break;
5466 if (get4() == 0x20002)
5467 for (exif_cfa=c=0; c < 8; c+=2)
5468 exif_cfa |= fgetc(ifp) * 0x01010101 << c;
5470 fseek (ifp, save, SEEK_SET);
5474 void CLASS parse_gps (int base)
5476 unsigned entries, tag, type, len, save, c;
5480 tiff_get (base, &tag, &type, &len, &save);
5482 case 1: case 3: case 5:
5483 gpsdata[29+tag/2] = getc(ifp); break;
5484 case 2: case 4: case 7:
5485 FORC(6) gpsdata[tag/3*6+c] = get4(); break;
5487 FORC(2) gpsdata[18+c] = get4(); break;
5489 fgets ((char *) (gpsdata+14+tag/3), MIN(len,12), ifp);
5491 fseek (ifp, save, SEEK_SET);
5495 void CLASS romm_coeff (float romm_cam[3][3])
5497 static const float rgb_romm[3][3] = /* ROMM == Kodak ProPhoto */
5498 { { 2.034193, -0.727420, -0.306766 },
5499 { -0.228811, 1.231729, -0.002922 },
5500 { -0.008565, -0.153273, 1.161839 } };
5503 for (i=0; i < 3; i++)
5504 for (j=0; j < 3; j++)
5505 for (cmatrix[i][j] = k=0; k < 3; k++)
5506 cmatrix[i][j] += rgb_romm[i][k] * romm_cam[k][j];
5509 void CLASS parse_mos (int offset)
5512 int skip, from, i, c, neut[4], planes=0, frot=0;
5513 static const char *mod[] =
5514 { "","DCB2","Volare","Cantare","CMost","Valeo 6","Valeo 11","Valeo 22",
5515 "Valeo 11p","Valeo 17","","Aptus 17","Aptus 22","Aptus 75","Aptus 65",
5516 "Aptus 54S","Aptus 65S","Aptus 75S","AFi 5","AFi 6","AFi 7",
5517 "AFi-II 7","Aptus-II 7","","Aptus-II 6","","","Aptus-II 10","Aptus-II 5",
5518 "","","","","Aptus-II 10R","Aptus-II 8","","Aptus-II 12","","AFi-II 12" };
5519 float romm_cam[3][3];
5521 fseek (ifp, offset, SEEK_SET);
5523 if (get4() != 0x504b5453) break;
5525 fread (data, 1, 40, ifp);
5528 if (!strcmp(data,"JPEG_preview_data")) {
5529 thumb_offset = from;
5530 thumb_length = skip;
5532 if (!strcmp(data,"icc_camera_profile")) {
5533 profile_offset = from;
5534 profile_length = skip;
5536 if (!strcmp(data,"ShootObj_back_type")) {
5537 fscanf (ifp, "%d", &i);
5538 if ((unsigned) i < sizeof mod / sizeof (*mod))
5539 strcpy (model, mod[i]);
5541 if (!strcmp(data,"icc_camera_to_tone_matrix")) {
5542 for (i=0; i < 9; i++)
5543 ((float *)romm_cam)[i] = int_to_float(get4());
5544 romm_coeff (romm_cam);
5546 if (!strcmp(data,"CaptProf_color_matrix")) {
5547 for (i=0; i < 9; i++)
5548 fscanf (ifp, "%f", (float *)romm_cam + i);
5549 romm_coeff (romm_cam);
5551 if (!strcmp(data,"CaptProf_number_of_planes"))
5552 fscanf (ifp, "%d", &planes);
5553 if (!strcmp(data,"CaptProf_raw_data_rotation"))
5554 fscanf (ifp, "%d", &flip);
5555 if (!strcmp(data,"CaptProf_mosaic_pattern"))
5557 fscanf (ifp, "%d", &i);
5558 if (i == 1) frot = c ^ (c >> 1);
5560 if (!strcmp(data,"ImgProf_rotation_angle")) {
5561 fscanf (ifp, "%d", &i);
5564 if (!strcmp(data,"NeutObj_neutrals") && !cam_mul[0]) {
5565 FORC4 fscanf (ifp, "%d", neut+c);
5566 FORC3 cam_mul[c] = (float) neut[0] / neut[c+1];
5568 if (!strcmp(data,"Rows_data"))
5569 load_flags = get4();
5571 fseek (ifp, skip+from, SEEK_SET);
5574 filters = (planes == 1) * 0x01010101 *
5575 (uchar) "\x94\x61\x16\x49"[(flip/90 + frot) & 3];
5578 void CLASS linear_table (unsigned len)
5581 if (len > 0x1000) len = 0x1000;
5582 read_shorts (curve, len);
5583 for (i=len; i < 0x1000; i++)
5584 curve[i] = curve[i-1];
5585 maximum = curve[0xfff];
5588 void CLASS parse_kodak_ifd (int base)
5590 unsigned entries, tag, type, len, save;
5591 int i, c, wbi=-2, wbtemp=6500;
5592 float mul[3]={1,1,1}, num;
5593 static const int wbtag[] = { 64037,64040,64039,64041,-1,-1,64042 };
5596 if (entries > 1024) return;
5598 tiff_get (base, &tag, &type, &len, &save);
5599 if (tag == 1020) wbi = getint(type);
5600 if (tag == 1021 && len == 72) { /* WB set in software */
5601 fseek (ifp, 40, SEEK_CUR);
5602 FORC3 cam_mul[c] = 2048.0 / get2();
5605 if (tag == 2118) wbtemp = getint(type);
5606 if (tag == 2120 + wbi && wbi >= 0)
5607 FORC3 cam_mul[c] = 2048.0 / getreal(type);
5608 if (tag == 2130 + wbi)
5609 FORC3 mul[c] = getreal(type);
5610 if (tag == 2140 + wbi && wbi >= 0)
5612 for (num=i=0; i < 4; i++)
5613 num += getreal(type) * pow (wbtemp/100.0, i);
5614 cam_mul[c] = 2048 / (num * mul[c]);
5616 if (tag == 2317) linear_table (len);
5617 if (tag == 6020) iso_speed = getint(type);
5618 if (tag == 64013) wbi = fgetc(ifp);
5619 if ((unsigned) wbi < 7 && tag == wbtag[wbi])
5620 FORC3 cam_mul[c] = get4();
5621 if (tag == 64019) width = getint(type);
5622 if (tag == 64020) height = (getint(type)+1) & -2;
5623 fseek (ifp, save, SEEK_SET);
5627 int CLASS parse_tiff_ifd (int base)
5629 unsigned entries, tag, type, len, plen=16, save;
5630 int ifd, use_cm=0, cfa, i, j, c, ima_len=0;
5631 char software[64], *cbuf, *cp;
5632 uchar cfa_pat[16], cfa_pc[] = { 0,1,2,3 }, tab[256];
5633 double cc[4][4], cm[4][3], cam_xyz[4][3], num;
5634 double ab[]={ 1,1,1,1 }, asn[] = { 0,0,0,0 }, xyz[] = { 1,1,1 };
5635 unsigned sony_curve[] = { 0,0,0,0,0,4095 };
5636 unsigned *buf, sony_offset=0, sony_length=0, sony_key=0;
5640 if (tiff_nifds >= sizeof tiff_ifd / sizeof tiff_ifd[0])
5643 for (j=0; j < 4; j++)
5644 for (i=0; i < 4; i++)
5647 if (entries > 512) return 1;
5649 tiff_get (base, &tag, &type, &len, &save);
5651 case 5: width = get2(); break;
5652 case 6: height = get2(); break;
5653 case 7: width += get2(); break;
5654 case 9: if ((i = get2())) filters = i; break;
5656 if (type == 3 && len == 1)
5657 cam_mul[(tag-17)*2] = get2() / 256.0;
5660 if (type == 3) iso_speed = get2();
5662 case 28: case 29: case 30:
5663 cblack[tag-28] = get2();
5664 cblack[3] = cblack[1];
5666 case 36: case 37: case 38:
5667 cam_mul[tag-36] = get2();
5670 if (len < 50 || cam_mul[0]) break;
5671 fseek (ifp, 12, SEEK_CUR);
5672 FORC3 cam_mul[c] = get2();
5675 if (type != 7 || fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) break;
5676 thumb_offset = ftell(ifp) - 2;
5679 case 61440: /* Fuji HS10 table */
5680 fseek (ifp, get4()+base, SEEK_SET);
5681 parse_tiff_ifd (base);
5683 case 2: case 256: case 61441: /* ImageWidth */
5684 tiff_ifd[ifd].width = getint(type);
5686 case 3: case 257: case 61442: /* ImageHeight */
5687 tiff_ifd[ifd].height = getint(type);
5689 case 258: /* BitsPerSample */
5691 tiff_ifd[ifd].samples = len & 7;
5692 tiff_ifd[ifd].bps = getint(type);
5693 if (tiff_bps < tiff_ifd[ifd].bps)
5694 tiff_bps = tiff_ifd[ifd].bps;
5698 if (tiff_ifd[ifd].bps > 12) break;
5699 load_raw = &CLASS packed_load_raw;
5700 load_flags = get4() ? 24:80;
5702 case 259: /* Compression */
5703 tiff_ifd[ifd].comp = getint(type);
5705 case 262: /* PhotometricInterpretation */
5706 tiff_ifd[ifd].phint = get2();
5708 case 270: /* ImageDescription */
5709 fread (desc, 512, 1, ifp);
5711 case 271: /* Make */
5712 fgets (make, 64, ifp);
5714 case 272: /* Model */
5715 fgets (model, 64, ifp);
5717 case 280: /* Panasonic RW2 offset */
5718 if (type != 4) break;
5719 load_raw = &CLASS panasonic_load_raw;
5720 load_flags = 0x2008;
5721 case 273: /* StripOffset */
5722 case 513: /* JpegIFOffset */
5724 tiff_ifd[ifd].offset = get4()+base;
5725 if (!tiff_ifd[ifd].bps && tiff_ifd[ifd].offset > 0) {
5726 fseek (ifp, tiff_ifd[ifd].offset, SEEK_SET);
5727 if (ljpeg_start (&jh, 1)) {
5728 tiff_ifd[ifd].comp = 6;
5729 tiff_ifd[ifd].width = jh.wide;
5730 tiff_ifd[ifd].height = jh.high;
5731 tiff_ifd[ifd].bps = jh.bits;
5732 tiff_ifd[ifd].samples = jh.clrs;
5733 if (!(jh.sraw || (jh.clrs & 1)))
5734 tiff_ifd[ifd].width *= jh.clrs;
5735 if ((tiff_ifd[ifd].width > 4*tiff_ifd[ifd].height) & ~jh.clrs) {
5736 tiff_ifd[ifd].width /= 2;
5737 tiff_ifd[ifd].height *= 2;
5740 parse_tiff (tiff_ifd[ifd].offset + 12);
5745 case 274: /* Orientation */
5746 tiff_ifd[ifd].flip = "50132467"[get2() & 7]-'0';
5748 case 277: /* SamplesPerPixel */
5749 tiff_ifd[ifd].samples = getint(type) & 7;
5751 case 279: /* StripByteCounts */
5754 tiff_ifd[ifd].bytes = get4();
5757 FORC3 cam_mul[(4-c) % 3] = getint(type);
5759 case 305: case 11: /* Software */
5760 fgets (software, 64, ifp);
5761 if (!strncmp(software,"Adobe",5) ||
5762 !strncmp(software,"dcraw",5) ||
5763 !strncmp(software,"UFRaw",5) ||
5764 !strncmp(software,"Bibble",6) ||
5765 !strncmp(software,"Nikon Scan",10) ||
5766 !strcmp (software,"Digital Photo Professional"))
5769 case 306: /* DateTime */
5772 case 315: /* Artist */
5773 fread (artist, 64, 1, ifp);
5775 case 322: /* TileWidth */
5776 tiff_ifd[ifd].tile_width = getint(type);
5778 case 323: /* TileLength */
5779 tiff_ifd[ifd].tile_length = getint(type);
5781 case 324: /* TileOffsets */
5782 tiff_ifd[ifd].offset = len > 1 ? ftell(ifp) : get4();
5784 tiff_ifd[ifd].tile_width = tiff_ifd[ifd].tile_length = 0;
5786 load_raw = &CLASS sinar_4shot_load_raw;
5790 case 330: /* SubIFDs */
5791 if (!strcmp(model,"DSLR-A100") && tiff_ifd[ifd].width == 3872) {
5792 load_raw = &CLASS sony_arw_load_raw;
5793 data_offset = get4()+base;
5798 fseek (ifp, get4()+base, SEEK_SET);
5799 if (parse_tiff_ifd (base)) break;
5800 fseek (ifp, i+4, SEEK_SET);
5804 strcpy (make, "Sarnoff");
5808 FORC4 sony_curve[c+1] = get2() >> 2 & 0xfff;
5809 for (i=0; i < 5; i++)
5810 for (j = sony_curve[i]+1; j <= sony_curve[i+1]; j++)
5811 curve[j] = curve[j-1] + (1 << i);
5813 case 29184: sony_offset = get4(); break;
5814 case 29185: sony_length = get4(); break;
5815 case 29217: sony_key = get4(); break;
5817 parse_minolta (ftell(ifp));
5821 FORC4 cam_mul[c ^ (c < 2)] = get2();
5824 FORC4 cam_mul[c] = get2();
5825 i = (cam_mul[1] == 1024 && cam_mul[2] == 1024) << 1;
5826 SWAP (cam_mul[i],cam_mul[i+1])
5828 case 33405: /* Model2 */
5829 fgets (model2, 64, ifp);
5831 case 33421: /* CFARepeatPatternDim */
5832 if (get2() == 6 && get2() == 6)
5835 case 33422: /* CFAPattern */
5837 FORC(36) ((char *)xtrans)[c] = fgetc(ifp) & 3;
5840 case 64777: /* Kodak P-series */
5841 if ((plen=len) > 16) plen = 16;
5842 fread (cfa_pat, 1, plen, ifp);
5843 for (colors=cfa=i=0; i < plen && colors < 4; i++) {
5844 colors += !(cfa & (1 << cfa_pat[i]));
5845 cfa |= 1 << cfa_pat[i];
5847 if (cfa == 070) memcpy (cfa_pc,"\003\004\005",3); /* CMY */
5848 if (cfa == 072) memcpy (cfa_pc,"\005\003\004\001",4); /* GMCY */
5852 fseek (ifp, get4()+base, SEEK_SET);
5853 parse_kodak_ifd (base);
5855 case 33434: /* ExposureTime */
5856 tiff_ifd[ifd].shutter = shutter = getreal(type);
5858 case 33437: /* FNumber */
5859 aperture = getreal(type);
5861 case 34306: /* Leaf white balance */
5862 FORC4 cam_mul[c ^ 1] = 4096.0 / get2();
5864 case 34307: /* Leaf CatchLight color matrix */
5865 fread (software, 1, 7, ifp);
5866 if (strncmp(software,"MATRIX",6)) break;
5868 for (raw_color = i=0; i < 3; i++) {
5869 FORC4 fscanf (ifp, "%f", &rgb_cam[i][c^1]);
5870 if (!use_camera_wb) continue;
5872 FORC4 num += rgb_cam[i][c];
5873 FORC4 rgb_cam[i][c] /= num;
5876 case 34310: /* Leaf metadata */
5877 parse_mos (ftell(ifp));
5879 strcpy (make, "Leaf");
5881 case 34665: /* EXIF tag */
5882 fseek (ifp, get4()+base, SEEK_SET);
5885 case 34853: /* GPSInfo tag */
5886 fseek (ifp, get4()+base, SEEK_SET);
5889 case 34675: /* InterColorProfile */
5890 case 50831: /* AsShotICCProfile */
5891 profile_offset = ftell(ifp);
5892 profile_length = len;
5894 case 37122: /* CompressedBitsPerPixel */
5895 kodak_cbpp = get4();
5897 case 37386: /* FocalLength */
5898 focal_len = getreal(type);
5900 case 37393: /* ImageNumber */
5901 shot_order = getint(type);
5903 case 37400: /* old Kodak KDC tag */
5904 for (raw_color = i=0; i < 3; i++) {
5906 FORC3 rgb_cam[i][c] = getreal(type);
5910 strip_offset = get4();
5911 switch (tiff_ifd[ifd].comp) {
5912 case 32770: load_raw = &CLASS samsung_load_raw; break;
5913 case 32772: load_raw = &CLASS samsung2_load_raw; break;
5914 case 32773: load_raw = &CLASS samsung3_load_raw; break;
5917 case 46275: /* Imacon tags */
5918 strcpy (make, "Imacon");
5919 data_offset = ftell(ifp);
5923 if (!ima_len) break;
5924 fseek (ifp, 38, SEEK_CUR);
5926 fseek (ifp, 40, SEEK_CUR);
5928 raw_height = get4();
5929 left_margin = get4() & 7;
5930 width = raw_width - left_margin - (get4() & 7);
5931 top_margin = get4() & 7;
5932 height = raw_height - top_margin - (get4() & 7);
5933 if (raw_width == 7262) {
5938 fseek (ifp, 52, SEEK_CUR);
5939 FORC3 cam_mul[c] = getreal(11);
5940 fseek (ifp, 114, SEEK_CUR);
5941 flip = (get2() >> 7) * 90;
5942 if (width * height * 6 == ima_len) {
5943 if (flip % 180 == 90) SWAP(width,height);
5945 raw_height = height;
5946 left_margin = top_margin = filters = flip = 0;
5948 sprintf (model, "Ixpress %d-Mp", height*width/1000000);
5949 load_raw = &CLASS imacon_full_load_raw;
5951 if (left_margin & 1) filters = 0x61616161;
5952 load_raw = &CLASS unpacked_load_raw;
5956 case 50454: /* Sinar tag */
5958 if (!(cbuf = (char *) malloc(len))) break;
5959 fread (cbuf, 1, len, ifp);
5960 for (cp = cbuf-1; cp && cp < cbuf+len; cp = strchr(cp,'\n'))
5961 if (!strncmp (++cp,"Neutral ",8))
5962 sscanf (cp+8, "%f %f %f", cam_mul, cam_mul+1, cam_mul+2);
5966 if (!make[0]) strcpy (make, "Hasselblad");
5968 case 50459: /* Hasselblad tag */
5973 fseek (ifp, j+(get2(),get4()), SEEK_SET);
5979 case 50706: /* DNGVersion */
5980 FORC4 dng_version = (dng_version << 8) + fgetc(ifp);
5981 if (!make[0]) strcpy (make, "DNG");
5984 case 50708: /* UniqueCameraModel */
5985 if (model[0]) break;
5986 fgets (make, 64, ifp);
5987 if ((cp = strchr(make,' '))) {
5992 case 50710: /* CFAPlaneColor */
5993 if (filters == 9) break;
5994 if (len > 4) len = 4;
5996 fread (cfa_pc, 1, colors, ifp);
5998 FORCC tab[cfa_pc[c]] = c;
6001 filters = filters << 2 | tab[cfa_pat[i % plen]];
6002 filters -= !filters;
6004 case 50711: /* CFALayout */
6005 if (get2() == 2) fuji_width = 1;
6008 case 50712: /* LinearizationTable */
6011 case 50713: /* BlackLevelRepeatDim */
6014 if (cblack[4] * cblack[5] > sizeof cblack / sizeof *cblack - 6)
6015 cblack[4] = cblack[5] = 1;
6018 cblack[4] = cblack[5] = MIN(sqrt(len),64);
6019 case 50714: /* BlackLevel */
6020 if (!(cblack[4] * cblack[5]))
6021 cblack[4] = cblack[5] = 1;
6022 FORC (cblack[4] * cblack[5])
6023 cblack[6+c] = getreal(type);
6026 case 50715: /* BlackLevelDeltaH */
6027 case 50716: /* BlackLevelDeltaV */
6028 for (num=i=0; i < (len & 0xffff); i++)
6029 num += getreal(type);
6030 black += num/len + 0.5;
6032 case 50717: /* WhiteLevel */
6033 maximum = getint(type);
6035 case 50718: /* DefaultScale */
6036 pixel_aspect = getreal(type);
6037 pixel_aspect /= getreal(type);
6039 case 50721: /* ColorMatrix1 */
6040 case 50722: /* ColorMatrix2 */
6041 FORCC for (j=0; j < 3; j++)
6042 cm[c][j] = getreal(type);
6045 case 50723: /* CameraCalibration1 */
6046 case 50724: /* CameraCalibration2 */
6047 for (i=0; i < colors; i++)
6048 FORCC cc[i][c] = getreal(type);
6050 case 50727: /* AnalogBalance */
6051 FORCC ab[c] = getreal(type);
6053 case 50728: /* AsShotNeutral */
6054 FORCC asn[c] = getreal(type);
6056 case 50729: /* AsShotWhiteXY */
6057 xyz[0] = getreal(type);
6058 xyz[1] = getreal(type);
6059 xyz[2] = 1 - xyz[0] - xyz[1];
6060 FORC3 xyz[c] /= d65_white[c];
6062 case 50740: /* DNGPrivateData */
6063 if (dng_version) break;
6064 parse_minolta (j = get4()+base);
6065 fseek (ifp, j, SEEK_SET);
6066 parse_tiff_ifd (base);
6069 read_shorts (cr2_slice, 3);
6071 case 50829: /* ActiveArea */
6072 top_margin = getint(type);
6073 left_margin = getint(type);
6074 height = getint(type) - top_margin;
6075 width = getint(type) - left_margin;
6077 case 50830: /* MaskedAreas */
6078 for (i=0; i < len && i < 32; i++)
6079 ((int *)mask)[i] = getint(type);
6082 case 51009: /* OpcodeList2 */
6083 meta_offset = ftell(ifp);
6085 case 64772: /* Kodak P-series */
6086 if (len < 13) break;
6087 fseek (ifp, 16, SEEK_CUR);
6088 data_offset = get4();
6089 fseek (ifp, 28, SEEK_CUR);
6090 data_offset += get4();
6091 load_raw = &CLASS packed_load_raw;
6094 if (type == 2) fgets (model2, 64, ifp);
6096 fseek (ifp, save, SEEK_SET);
6098 if (sony_length && (buf = (unsigned *) malloc(sony_length))) {
6099 fseek (ifp, sony_offset, SEEK_SET);
6100 fread (buf, sony_length, 1, ifp);
6101 sony_decrypt (buf, sony_length/4, 1, sony_key);
6103 if ((ifp = tmpfile())) {
6104 fwrite (buf, sony_length, 1, ifp);
6105 fseek (ifp, 0, SEEK_SET);
6106 parse_tiff_ifd (-sony_offset);
6112 for (i=0; i < colors; i++)
6113 FORCC cc[i][c] *= ab[i];
6115 FORCC for (i=0; i < 3; i++)
6116 for (cam_xyz[c][i]=j=0; j < colors; j++)
6117 cam_xyz[c][i] += cc[c][j] * cm[j][i] * xyz[i];
6118 cam_xyz_coeff (cmatrix, cam_xyz);
6122 FORCC cam_mul[c] = 1 / asn[c];
6125 FORCC pre_mul[c] /= cc[c][c];
6129 int CLASS parse_tiff (int base)
6133 fseek (ifp, base, SEEK_SET);
6135 if (order != 0x4949 && order != 0x4d4d) return 0;
6137 while ((doff = get4())) {
6138 fseek (ifp, doff+base, SEEK_SET);
6139 if (parse_tiff_ifd (base)) break;
6144 void CLASS apply_tiff()
6146 int max_samp=0, ties=0, os, ns, raw=-1, thm=-1, i;
6151 fseek (ifp, thumb_offset, SEEK_SET);
6152 if (ljpeg_start (&jh, 1)) {
6153 thumb_misc = jh.bits;
6154 thumb_width = jh.wide;
6155 thumb_height = jh.high;
6158 for (i=tiff_nifds; i--; ) {
6159 if (tiff_ifd[i].shutter)
6160 shutter = tiff_ifd[i].shutter;
6161 tiff_ifd[i].shutter = shutter;
6163 for (i=0; i < tiff_nifds; i++) {
6164 if (max_samp < tiff_ifd[i].samples)
6165 max_samp = tiff_ifd[i].samples;
6166 if (max_samp > 3) max_samp = 3;
6167 os = raw_width*raw_height;
6168 ns = tiff_ifd[i].width*tiff_ifd[i].height;
6171 ns *= tiff_ifd[i].bps;
6173 if ((tiff_ifd[i].comp != 6 || tiff_ifd[i].samples != 3) &&
6174 (tiff_ifd[i].width | tiff_ifd[i].height) < 0x10000 &&
6175 ns && ((ns > os && (ties = 1)) ||
6176 (ns == os && shot_select == ties++))) {
6177 raw_width = tiff_ifd[i].width;
6178 raw_height = tiff_ifd[i].height;
6179 tiff_bps = tiff_ifd[i].bps;
6180 tiff_compress = tiff_ifd[i].comp;
6181 data_offset = tiff_ifd[i].offset;
6182 tiff_flip = tiff_ifd[i].flip;
6183 tiff_samples = tiff_ifd[i].samples;
6184 tile_width = tiff_ifd[i].tile_width;
6185 tile_length = tiff_ifd[i].tile_length;
6186 shutter = tiff_ifd[i].shutter;
6190 if (is_raw == 1 && ties) is_raw = ties;
6191 if (!tile_width ) tile_width = INT_MAX;
6192 if (!tile_length) tile_length = INT_MAX;
6193 for (i=tiff_nifds; i--; )
6194 if (tiff_ifd[i].flip) tiff_flip = tiff_ifd[i].flip;
6195 if (raw >= 0 && !load_raw)
6196 switch (tiff_compress) {
6198 if (tiff_ifd[raw].bytes == raw_width*raw_height) {
6200 load_raw = &CLASS sony_arw2_load_raw; break;
6202 if (tiff_ifd[raw].bytes*8 != raw_width*raw_height*tiff_bps) {
6204 load_raw = &CLASS sony_arw_load_raw; break;
6210 case 32773: goto slr;
6212 if (!strncmp(make,"OLYMPUS",7) &&
6213 tiff_ifd[raw].bytes*2 == raw_width*raw_height*3)
6215 if (tiff_ifd[raw].bytes*5 == raw_width*raw_height*8) {
6220 case 8: load_raw = &CLASS eight_bit_load_raw; break;
6221 case 12: if (tiff_ifd[raw].phint == 2)
6223 load_raw = &CLASS packed_load_raw; break;
6224 case 14: load_flags = 0;
6225 case 16: load_raw = &CLASS unpacked_load_raw;
6226 if (!strncmp(make,"OLYMPUS",7) &&
6227 tiff_ifd[raw].bytes*7 > raw_width*raw_height)
6228 load_raw = &CLASS olympus_load_raw;
6231 case 6: case 7: case 99:
6232 load_raw = &CLASS lossless_jpeg_load_raw; break;
6234 load_raw = &CLASS kodak_262_load_raw; break;
6236 if ((raw_width+9)/10*16*raw_height == tiff_ifd[raw].bytes) {
6237 load_raw = &CLASS packed_load_raw;
6239 } else if (raw_width*raw_height*3 == tiff_ifd[raw].bytes*2) {
6240 load_raw = &CLASS packed_load_raw;
6241 if (model[0] == 'N') load_flags = 80;
6242 } else if (raw_width*raw_height*3 == tiff_ifd[raw].bytes) {
6243 load_raw = &CLASS nikon_yuv_load_raw;
6244 gamma_curve (1/2.4, 12.92, 1, 4095);
6245 memset (cblack, 0, sizeof cblack);
6247 } else if (raw_width*raw_height*2 == tiff_ifd[raw].bytes) {
6248 load_raw = &CLASS unpacked_load_raw;
6252 load_raw = &CLASS nikon_load_raw; break;
6254 load_raw = &CLASS pentax_load_raw; break;
6256 switch (tiff_ifd[raw].phint) {
6257 case 2: load_raw = &CLASS kodak_rgb_load_raw; filters = 0; break;
6258 case 6: load_raw = &CLASS kodak_ycbcr_load_raw; filters = 0; break;
6259 case 32803: load_raw = &CLASS kodak_65000_load_raw;
6261 case 32867: case 34892: break;
6262 default: is_raw = 0;
6265 if ( (tiff_samples == 3 && tiff_ifd[raw].bytes && tiff_bps != 14 &&
6266 (tiff_compress & -16) != 32768)
6267 || (tiff_bps == 8 && strncmp(make,"Phase",5) &&
6268 !strcasestr(make,"Kodak") && !strstr(model2,"DEBUG RAW")))
6270 for (i=0; i < tiff_nifds; i++)
6271 if (i != raw && tiff_ifd[i].samples == max_samp &&
6272 tiff_ifd[i].width * tiff_ifd[i].height / (SQR(tiff_ifd[i].bps)+1) >
6273 thumb_width * thumb_height / (SQR(thumb_misc)+1)
6274 && tiff_ifd[i].comp != 34892) {
6275 thumb_width = tiff_ifd[i].width;
6276 thumb_height = tiff_ifd[i].height;
6277 thumb_offset = tiff_ifd[i].offset;
6278 thumb_length = tiff_ifd[i].bytes;
6279 thumb_misc = tiff_ifd[i].bps;
6283 thumb_misc |= tiff_ifd[thm].samples << 5;
6284 switch (tiff_ifd[thm].comp) {
6286 write_thumb = &CLASS layer_thumb;
6289 if (tiff_ifd[thm].bps <= 8)
6290 write_thumb = &CLASS ppm_thumb;
6291 else if (!strcmp(make,"Imacon"))
6292 write_thumb = &CLASS ppm16_thumb;
6294 thumb_load_raw = &CLASS kodak_thumb_load_raw;
6297 thumb_load_raw = tiff_ifd[thm].phint == 6 ?
6298 &CLASS kodak_ycbcr_load_raw : &CLASS kodak_rgb_load_raw;
6303 void CLASS parse_minolta (int base)
6305 int save, tag, len, offset, high=0, wide=0, i, c;
6308 fseek (ifp, base, SEEK_SET);
6309 if (fgetc(ifp) || fgetc(ifp)-'M' || fgetc(ifp)-'R') return;
6310 order = fgetc(ifp) * 0x101;
6311 offset = base + get4() + 8;
6312 while ((save=ftell(ifp)) < offset) {
6313 for (tag=i=0; i < 4; i++)
6314 tag = tag << 8 | fgetc(ifp);
6317 case 0x505244: /* PRD */
6318 fseek (ifp, 8, SEEK_CUR);
6322 case 0x574247: /* WBG */
6324 i = strcmp(model,"DiMAGE A200") ? 0:3;
6325 FORC4 cam_mul[c ^ (c >> 1) ^ i] = get2();
6327 case 0x545457: /* TTW */
6328 parse_tiff (ftell(ifp));
6329 data_offset = offset;
6331 fseek (ifp, save+len+8, SEEK_SET);
6339 Many cameras have a "debug mode" that writes JPEG and raw
6340 at the same time. The raw file has no header, so try to
6341 to open the matching JPEG file and read its metadata.
6343 void CLASS parse_external_jpeg()
6345 const char *file, *ext;
6346 char *jname, *jfile, *jext;
6349 ext = strrchr (ifname, '.');
6350 file = strrchr (ifname, '/');
6351 if (!file) file = strrchr (ifname, '\\');
6352 if (!file) file = ifname-1;
6354 if (!ext || strlen(ext) != 4 || ext-file != 8) return;
6355 jname = (char *) malloc (strlen(ifname) + 1);
6356 merror (jname, "parse_external_jpeg()");
6357 strcpy (jname, ifname);
6358 jfile = file - ifname + jname;
6359 jext = ext - ifname + jname;
6360 if (strcasecmp (ext, ".jpg")) {
6361 strcpy (jext, isupper(ext[1]) ? ".JPG":".jpg");
6362 if (isdigit(*file)) {
6363 memcpy (jfile, file+4, 4);
6364 memcpy (jfile+4, file, 4);
6367 while (isdigit(*--jext)) {
6374 if (strcmp (jname, ifname)) {
6375 if ((ifp = fopen (jname, "rb"))) {
6377 fprintf (stderr,_("Reading metadata from %s ...\n"), jname);
6385 fprintf (stderr,_("Failed to read metadata from %s\n"), jname);
6391 CIFF block 0x1030 contains an 8x8 white sample.
6392 Load this into white[][] for use in scale_colors().
6394 void CLASS ciff_block_1030()
6396 static const ushort key[] = { 0x410, 0x45f3 };
6397 int i, bpp, row, col, vbits=0;
6398 unsigned long bitbuf=0;
6400 if ((get2(),get4()) != 0x80008 || !get4()) return;
6402 if (bpp != 10 && bpp != 12) return;
6403 for (i=row=0; row < 8; row++)
6404 for (col=0; col < 8; col++) {
6406 bitbuf = bitbuf << 16 | (get2() ^ key[i++ & 1]);
6409 white[row][col] = bitbuf >> (vbits -= bpp) & ~(-1 << bpp);
6414 Parse a CIFF file, better known as Canon CRW format.
6416 void CLASS parse_ciff (int offset, int length, int depth)
6418 int tboff, nrecs, c, type, len, save, wbi=-1;
6419 ushort key[] = { 0x410, 0x45f3 };
6421 fseek (ifp, offset+length-4, SEEK_SET);
6422 tboff = get4() + offset;
6423 fseek (ifp, tboff, SEEK_SET);
6425 if ((nrecs | depth) > 127) return;
6429 save = ftell(ifp) + 4;
6430 fseek (ifp, offset+get4(), SEEK_SET);
6431 if ((((type >> 8) + 8) | 8) == 0x38)
6432 parse_ciff (ftell(ifp), len, depth+1); /* Parse a sub-table */
6434 fread (artist, 64, 1, ifp);
6435 if (type == 0x080a) {
6436 fread (make, 64, 1, ifp);
6437 fseek (ifp, strlen(make) - 63, SEEK_CUR);
6438 fread (model, 64, 1, ifp);
6440 if (type == 0x1810) {
6443 pixel_aspect = int_to_float(get4());
6446 if (type == 0x1835) /* Get the decoder table */
6447 tiff_compress = get4();
6448 if (type == 0x2007) {
6449 thumb_offset = ftell(ifp);
6452 if (type == 0x1818) {
6453 shutter = pow (2, -int_to_float((get4(),get4())));
6454 aperture = pow (2, int_to_float(get4())/2);
6456 if (type == 0x102a) {
6457 iso_speed = pow (2, (get4(),get2())/32.0 - 4) * 50;
6458 aperture = pow (2, (get2(),(short)get2())/64.0);
6459 shutter = pow (2,-((short)get2())/32.0);
6460 wbi = (get2(),get2());
6461 if (wbi > 17) wbi = 0;
6462 fseek (ifp, 32, SEEK_CUR);
6463 if (shutter > 1e6) shutter = get2()/10.0;
6465 if (type == 0x102c) {
6466 if (get2() > 512) { /* Pro90, G1 */
6467 fseek (ifp, 118, SEEK_CUR);
6468 FORC4 cam_mul[c ^ 2] = get2();
6469 } else { /* G2, S30, S40 */
6470 fseek (ifp, 98, SEEK_CUR);
6471 FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get2();
6474 if (type == 0x0032) {
6475 if (len == 768) { /* EOS D30 */
6476 fseek (ifp, 72, SEEK_CUR);
6477 FORC4 cam_mul[c ^ (c >> 1)] = 1024.0 / get2();
6478 if (!wbi) cam_mul[0] = -1; /* use my auto white balance */
6479 } else if (!cam_mul[0]) {
6480 if (get2() == key[0]) /* Pro1, G6, S60, S70 */
6481 c = (strstr(model,"Pro1") ?
6482 "012346000000000000":"01345:000000006008")[wbi]-'0'+ 2;
6483 else { /* G3, G5, S45, S50 */
6484 c = "023457000000006000"[wbi]-'0';
6485 key[0] = key[1] = 0;
6487 fseek (ifp, 78 + c*8, SEEK_CUR);
6488 FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get2() ^ key[c & 1];
6489 if (!wbi) cam_mul[0] = -1;
6492 if (type == 0x10a9) { /* D60, 10D, 300D, and clones */
6493 if (len > 66) wbi = "0134567028"[wbi]-'0';
6494 fseek (ifp, 2 + wbi*8, SEEK_CUR);
6495 FORC4 cam_mul[c ^ (c >> 1)] = get2();
6497 if (type == 0x1030 && (0x18040 >> wbi & 1))
6498 ciff_block_1030(); /* all that don't have 0x10a9 */
6499 if (type == 0x1031) {
6500 raw_width = (get2(),get2());
6501 raw_height = get2();
6503 if (type == 0x5029) {
6504 focal_len = len >> 16;
6505 if ((len & 0xffff) == 2) focal_len /= 32;
6507 if (type == 0x5813) flash_used = int_to_float(len);
6508 if (type == 0x5814) canon_ev = int_to_float(len);
6509 if (type == 0x5817) shot_order = len;
6510 if (type == 0x5834) unique_id = len;
6511 if (type == 0x580e) timestamp = len;
6512 if (type == 0x180e) timestamp = get4();
6514 if ((type | 0x4000) == 0x580e)
6515 timestamp = mktime (gmtime (×tamp));
6517 fseek (ifp, save, SEEK_SET);
6521 void CLASS parse_rollei()
6523 char line[128], *val;
6526 fseek (ifp, 0, SEEK_SET);
6527 memset (&t, 0, sizeof t);
6529 fgets (line, 128, ifp);
6530 if ((val = strchr(line,'=')))
6533 val = line + strlen(line);
6534 if (!strcmp(line,"DAT"))
6535 sscanf (val, "%d.%d.%d", &t.tm_mday, &t.tm_mon, &t.tm_year);
6536 if (!strcmp(line,"TIM"))
6537 sscanf (val, "%d:%d:%d", &t.tm_hour, &t.tm_min, &t.tm_sec);
6538 if (!strcmp(line,"HDR"))
6539 thumb_offset = atoi(val);
6540 if (!strcmp(line,"X "))
6541 raw_width = atoi(val);
6542 if (!strcmp(line,"Y "))
6543 raw_height = atoi(val);
6544 if (!strcmp(line,"TX "))
6545 thumb_width = atoi(val);
6546 if (!strcmp(line,"TY "))
6547 thumb_height = atoi(val);
6548 } while (strncmp(line,"EOHD",4));
6549 data_offset = thumb_offset + thumb_width * thumb_height * 2;
6553 timestamp = mktime(&t);
6554 strcpy (make, "Rollei");
6555 strcpy (model,"d530flex");
6556 write_thumb = &CLASS rollei_thumb;
6559 void CLASS parse_sinar_ia()
6565 fseek (ifp, 4, SEEK_SET);
6567 fseek (ifp, get4(), SEEK_SET);
6569 off = get4(); get4();
6570 fread (str, 8, 1, ifp);
6571 if (!strcmp(str,"META")) meta_offset = off;
6572 if (!strcmp(str,"THUMB")) thumb_offset = off;
6573 if (!strcmp(str,"RAW0")) data_offset = off;
6575 fseek (ifp, meta_offset+20, SEEK_SET);
6576 fread (make, 64, 1, ifp);
6578 if ((cp = strchr(make,' '))) {
6579 strcpy (model, cp+1);
6583 raw_height = get2();
6584 load_raw = &CLASS unpacked_load_raw;
6585 thumb_width = (get4(),get2());
6586 thumb_height = get2();
6587 write_thumb = &CLASS ppm_thumb;
6591 void CLASS parse_phase_one (int base)
6594 unsigned entries, tag, /*type,*/ len, data, save, i, c;
6595 float romm_cam[3][3];
6598 memset (&ph1, 0, sizeof ph1);
6599 fseek (ifp, base, SEEK_SET);
6600 order = get4() & 0xffff;
6601 if (get4() >> 8 != 0x526177) return; /* "Raw" */
6602 fseek (ifp, get4()+base, SEEK_SET);
6612 fseek (ifp, base+data, SEEK_SET);
6614 case 0x100: flip = "0653"[data & 3]-'0'; break;
6616 for (i=0; i < 9; i++)
6617 ((float *)romm_cam)[i] = getreal(11);
6618 romm_coeff (romm_cam);
6621 FORC3 cam_mul[c] = getreal(11);
6623 case 0x108: raw_width = data; break;
6624 case 0x109: raw_height = data; break;
6625 case 0x10a: left_margin = data; break;
6626 case 0x10b: top_margin = data; break;
6627 case 0x10c: width = data; break;
6628 case 0x10d: height = data; break;
6629 case 0x10e: ph1.format = data; break;
6630 case 0x10f: data_offset = data+base; break;
6631 case 0x110: meta_offset = data+base;
6632 meta_length = len; break;
6633 case 0x112: ph1.key_off = save - 4; break;
6634 case 0x210: ph1.tag_210 = int_to_float(data); break;
6635 case 0x21a: ph1.tag_21a = data; break;
6636 case 0x21c: strip_offset = data+base; break;
6637 case 0x21d: ph1.black = data; break;
6638 case 0x222: ph1.split_col = data; break;
6639 case 0x223: ph1.black_col = data+base; break;
6640 case 0x224: ph1.split_row = data; break;
6641 case 0x225: ph1.black_row = data+base; break;
6644 fread (model, 1, 63, ifp);
6645 if ((cp = strstr(model," camera"))) *cp = 0;
6647 fseek (ifp, save, SEEK_SET);
6649 load_raw = ph1.format < 3 ?
6650 &CLASS phase_one_load_raw : &CLASS phase_one_load_raw_c;
6652 strcpy (make, "Phase One");
6653 if (model[0]) return;
6654 switch (raw_height) {
6655 case 2060: strcpy (model,"LightPhase"); break;
6656 case 2682: strcpy (model,"H 10"); break;
6657 case 4128: strcpy (model,"H 20"); break;
6658 case 5488: strcpy (model,"H 25"); break;
6662 void CLASS parse_fuji (int offset)
6664 unsigned entries, tag, len, save, c;
6666 fseek (ifp, offset, SEEK_SET);
6668 if (entries > 255) return;
6674 raw_height = get2();
6676 } else if (tag == 0x121) {
6678 if ((width = get2()) == 4284) width += 3;
6679 } else if (tag == 0x130) {
6680 fuji_layout = fgetc(ifp) >> 7;
6681 fuji_width = !(fgetc(ifp) & 8);
6682 } else if (tag == 0x131) {
6684 FORC(36) xtrans_abs[0][35-c] = fgetc(ifp) & 3;
6685 } else if (tag == 0x2ff0) {
6686 FORC4 cam_mul[c ^ 1] = get2();
6687 } else if (tag == 0xc000) {
6690 while ((tag = get4()) > raw_width);
6695 fseek (ifp, save+len, SEEK_SET);
6697 height <<= fuji_layout;
6698 width >>= fuji_layout;
6701 int CLASS parse_jpeg (int offset)
6703 int len, save, hlen, mark;
6705 fseek (ifp, offset, SEEK_SET);
6706 if (fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) return 0;
6708 while (fgetc(ifp) == 0xff && (mark = fgetc(ifp)) != 0xda) {
6712 if (mark == 0xc0 || mark == 0xc3 || mark == 0xc9) {
6714 raw_height = get2();
6719 if (get4() == 0x48454150) /* "HEAP" */
6720 parse_ciff (save+hlen, len-hlen, 0);
6721 if (parse_tiff (save+6)) apply_tiff();
6722 fseek (ifp, save+len, SEEK_SET);
6727 void CLASS parse_riff()
6729 unsigned i, size, end;
6730 char tag[4], date[64], month[64];
6731 static const char mon[12][4] =
6732 { "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" };
6736 fread (tag, 4, 1, ifp);
6738 end = ftell(ifp) + size;
6739 if (!memcmp(tag,"RIFF",4) || !memcmp(tag,"LIST",4)) {
6741 while (ftell(ifp)+7 < end && !feof(ifp))
6743 } else if (!memcmp(tag,"nctg",4)) {
6744 while (ftell(ifp)+7 < end) {
6747 if ((i+1) >> 1 == 10 && size == 20)
6749 else fseek (ifp, size, SEEK_CUR);
6751 } else if (!memcmp(tag,"IDIT",4) && size < 64) {
6752 fread (date, 64, 1, ifp);
6754 memset (&t, 0, sizeof t);
6755 if (sscanf (date, "%*s %s %d %d:%d:%d %d", month, &t.tm_mday,
6756 &t.tm_hour, &t.tm_min, &t.tm_sec, &t.tm_year) == 6) {
6757 for (i=0; i < 12 && strcasecmp(mon[i],month); i++);
6761 timestamp = mktime(&t);
6764 fseek (ifp, size, SEEK_CUR);
6767 void CLASS parse_qt (int end)
6769 unsigned save, size;
6773 while (ftell(ifp)+7 < end) {
6775 if ((size = get4()) < 8) return;
6776 fread (tag, 4, 1, ifp);
6777 if (!memcmp(tag,"moov",4) ||
6778 !memcmp(tag,"udta",4) ||
6779 !memcmp(tag,"CNTH",4))
6780 parse_qt (save+size);
6781 if (!memcmp(tag,"CNDA",4))
6782 parse_jpeg (ftell(ifp));
6783 fseek (ifp, save+size, SEEK_SET);
6787 void CLASS parse_smal (int offset, int fsize)
6791 fseek (ifp, offset+2, SEEK_SET);
6795 fseek (ifp, 5, SEEK_CUR);
6796 if (get4() != fsize) return;
6797 if (ver > 6) data_offset = get4();
6798 raw_height = height = get2();
6799 raw_width = width = get2();
6800 strcpy (make, "SMaL");
6801 sprintf (model, "v%d %dx%d", ver, width, height);
6802 if (ver == 6) load_raw = &CLASS smal_v6_load_raw;
6803 if (ver == 9) load_raw = &CLASS smal_v9_load_raw;
6806 void CLASS parse_cine()
6808 unsigned off_head, off_setup, off_image, i;
6811 fseek (ifp, 4, SEEK_SET);
6812 is_raw = get2() == 2;
6813 fseek (ifp, 14, SEEK_CUR);
6819 if ((i = get4())) timestamp = i;
6820 fseek (ifp, off_head+4, SEEK_SET);
6822 raw_height = get4();
6823 switch (get2(),get2()) {
6824 case 8: load_raw = &CLASS eight_bit_load_raw; break;
6825 case 16: load_raw = &CLASS unpacked_load_raw;
6827 fseek (ifp, off_setup+792, SEEK_SET);
6828 strcpy (make, "CINE");
6829 sprintf (model, "%d", get4());
6830 fseek (ifp, 12, SEEK_CUR);
6831 switch ((i=get4()) & 0xffffff) {
6832 case 3: filters = 0x94949494; break;
6833 case 4: filters = 0x49494949; break;
6834 default: is_raw = 0;
6836 fseek (ifp, 72, SEEK_CUR);
6837 switch ((get4()+3600) % 360) {
6838 case 270: flip = 4; break;
6839 case 180: flip = 1; break;
6840 case 90: flip = 7; break;
6843 cam_mul[0] = getreal(11);
6844 cam_mul[2] = getreal(11);
6845 maximum = ~(-1 << get4());
6846 fseek (ifp, 668, SEEK_CUR);
6847 shutter = get4()/1000000000.0;
6848 fseek (ifp, off_image, SEEK_SET);
6849 if (shot_select < is_raw)
6850 fseek (ifp, shot_select*8, SEEK_CUR);
6851 data_offset = (INT64) get4() + 8;
6852 data_offset += (INT64) get4() << 32;
6855 void CLASS parse_redcine()
6857 unsigned i, len, rdvo;
6861 fseek (ifp, 52, SEEK_SET);
6864 fseek (ifp, 0, SEEK_END);
6865 fseek (ifp, -(i = ftello(ifp) & 511), SEEK_CUR);
6866 if (get4() != i || get4() != 0x52454f42) {
6867 fprintf (stderr,_("%s: Tail is missing, parsing from head...\n"), ifname);
6868 fseek (ifp, 0, SEEK_SET);
6869 while ((len = get4()) != EOF) {
6870 if (get4() == 0x52454456)
6871 if (is_raw++ == shot_select)
6872 data_offset = ftello(ifp) - 8;
6873 fseek (ifp, len-8, SEEK_CUR);
6877 fseek (ifp, 12, SEEK_CUR);
6879 fseeko (ifp, rdvo+8 + shot_select*4, SEEK_SET);
6880 data_offset = get4();
6884 char * CLASS foveon_gets (int offset, char *str, int len)
6887 fseek (ifp, offset, SEEK_SET);
6888 for (i=0; i < len-1; i++)
6889 if ((str[i] = get2()) == 0) break;
6894 void CLASS parse_foveon()
6896 int entries, img=0, off, len, tag, save, i, wide, high, pent, poff[256][2];
6897 char name[64], value[64];
6899 order = 0x4949; /* Little-endian */
6900 fseek (ifp, 36, SEEK_SET);
6902 fseek (ifp, -4, SEEK_END);
6903 fseek (ifp, get4(), SEEK_SET);
6904 if (get4() != 0x64434553) return; /* SECd */
6905 entries = (get4(),get4());
6911 fseek (ifp, off, SEEK_SET);
6912 if (get4() != (0x20434553 | (tag << 24))) return;
6914 case 0x47414d49: /* IMAG */
6915 case 0x32414d49: /* IMA2 */
6916 fseek (ifp, 8, SEEK_CUR);
6920 if (wide > raw_width && high > raw_height) {
6922 case 5: load_flags = 1;
6923 case 6: load_raw = &CLASS foveon_sd_load_raw; break;
6924 case 30: load_raw = &CLASS foveon_dp_load_raw; break;
6925 default: load_raw = 0;
6929 data_offset = off+28;
6932 fseek (ifp, off+28, SEEK_SET);
6933 if (fgetc(ifp) == 0xff && fgetc(ifp) == 0xd8
6934 && thumb_length < len-28) {
6935 thumb_offset = off+28;
6936 thumb_length = len-28;
6937 write_thumb = &CLASS jpeg_thumb;
6939 if (++img == 2 && !thumb_length) {
6940 thumb_offset = off+24;
6942 thumb_height = high;
6943 write_thumb = &CLASS foveon_thumb;
6946 case 0x464d4143: /* CAMF */
6947 meta_offset = off+8;
6948 meta_length = len-28;
6950 case 0x504f5250: /* PROP */
6951 pent = (get4(),get4());
6952 fseek (ifp, 12, SEEK_CUR);
6954 if ((unsigned) pent > 256) pent=256;
6955 for (i=0; i < pent*2; i++)
6956 ((int *)poff)[i] = off + get4()*2;
6957 for (i=0; i < pent; i++) {
6958 foveon_gets (poff[i][0], name, 64);
6959 foveon_gets (poff[i][1], value, 64);
6960 if (!strcmp (name, "ISO"))
6961 iso_speed = atoi(value);
6962 if (!strcmp (name, "CAMMANUF"))
6963 strcpy (make, value);
6964 if (!strcmp (name, "CAMMODEL"))
6965 strcpy (model, value);
6966 if (!strcmp (name, "WB_DESC"))
6967 strcpy (model2, value);
6968 if (!strcmp (name, "TIME"))
6969 timestamp = atoi(value);
6970 if (!strcmp (name, "EXPTIME"))
6971 shutter = atoi(value) / 1000000.0;
6972 if (!strcmp (name, "APERTURE"))
6973 aperture = atof(value);
6974 if (!strcmp (name, "FLENGTH"))
6975 focal_len = atof(value);
6978 timestamp = mktime (gmtime (×tamp));
6981 fseek (ifp, save, SEEK_SET);
6986 All matrices are from Adobe DNG Converter unless otherwise noted.
6988 void CLASS adobe_coeff (const char *make, const char *model)
6990 static const struct {
6992 short black, maximum, trans[12];
6994 { "AgfaPhoto DC-833m", 0, 0, /* DJC */
6995 { 11438,-3762,-1115,-2409,9914,2497,-1227,2295,5300 } },
6996 { "Apple QuickTake", 0, 0, /* DJC */
6997 { 21392,-5653,-3353,2406,8010,-415,7166,1427,2078 } },
6998 { "Canon EOS D2000", 0, 0,
6999 { 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } },
7000 { "Canon EOS D6000", 0, 0,
7001 { 20482,-7172,-3125,-1033,10410,-285,2542,226,3136 } },
7002 { "Canon EOS D30", 0, 0,
7003 { 9805,-2689,-1312,-5803,13064,3068,-2438,3075,8775 } },
7004 { "Canon EOS D60", 0, 0xfa0,
7005 { 6188,-1341,-890,-7168,14489,2937,-2640,3228,8483 } },
7006 { "Canon EOS 5DS", 0, 0x3c96,
7007 { 6250,-711,-808,-5153,12794,2636,-1249,2198,5610 } },
7008 { "Canon EOS 5D Mark III", 0, 0x3c80,
7009 { 6722,-635,-963,-4287,12460,2028,-908,2162,5668 } },
7010 { "Canon EOS 5D Mark II", 0, 0x3cf0,
7011 { 4716,603,-830,-7798,15474,2480,-1496,1937,6651 } },
7012 { "Canon EOS 5D", 0, 0xe6c,
7013 { 6347,-479,-972,-8297,15954,2480,-1968,2131,7649 } },
7014 { "Canon EOS 6D", 0, 0x3c82,
7015 { 7034,-804,-1014,-4420,12564,2058,-851,1994,5758 } },
7016 { "Canon EOS 7D Mark II", 0, 0x3510,
7017 { 7268,-1082,-969,-4186,11839,2663,-825,2029,5839 } },
7018 { "Canon EOS 7D", 0, 0x3510,
7019 { 6844,-996,-856,-3876,11761,2396,-593,1772,6198 } },
7020 { "Canon EOS 10D", 0, 0xfa0,
7021 { 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } },
7022 { "Canon EOS 20Da", 0, 0,
7023 { 14155,-5065,-1382,-6550,14633,2039,-1623,1824,6561 } },
7024 { "Canon EOS 20D", 0, 0xfff,
7025 { 6599,-537,-891,-8071,15783,2424,-1983,2234,7462 } },
7026 { "Canon EOS 30D", 0, 0,
7027 { 6257,-303,-1000,-7880,15621,2396,-1714,1904,7046 } },
7028 { "Canon EOS 40D", 0, 0x3f60,
7029 { 6071,-747,-856,-7653,15365,2441,-2025,2553,7315 } },
7030 { "Canon EOS 50D", 0, 0x3d93,
7031 { 4920,616,-593,-6493,13964,2784,-1774,3178,7005 } },
7032 { "Canon EOS 60D", 0, 0x2ff7,
7033 { 6719,-994,-925,-4408,12426,2211,-887,2129,6051 } },
7034 { "Canon EOS 70D", 0, 0x3bc7,
7035 { 7034,-804,-1014,-4420,12564,2058,-851,1994,5758 } },
7036 { "Canon EOS 80D", 0, 0,
7037 { 7457,-671,-937,-4849,12495,2643,-1213,2354,5492 } },
7038 { "Canon EOS 100D", 0, 0x350f,
7039 { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } },
7040 { "Canon EOS 300D", 0, 0xfa0,
7041 { 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } },
7042 { "Canon EOS 350D", 0, 0xfff,
7043 { 6018,-617,-965,-8645,15881,2975,-1530,1719,7642 } },
7044 { "Canon EOS 400D", 0, 0xe8e,
7045 { 7054,-1501,-990,-8156,15544,2812,-1278,1414,7796 } },
7046 { "Canon EOS 450D", 0, 0x390d,
7047 { 5784,-262,-821,-7539,15064,2672,-1982,2681,7427 } },
7048 { "Canon EOS 500D", 0, 0x3479,
7049 { 4763,712,-646,-6821,14399,2640,-1921,3276,6561 } },
7050 { "Canon EOS 550D", 0, 0x3dd7,
7051 { 6941,-1164,-857,-3825,11597,2534,-416,1540,6039 } },
7052 { "Canon EOS 600D", 0, 0x3510,
7053 { 6461,-907,-882,-4300,12184,2378,-819,1944,5931 } },
7054 { "Canon EOS 650D", 0, 0x354d,
7055 { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } },
7056 { "Canon EOS 700D", 0, 0x3c00,
7057 { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } },
7058 { "Canon EOS 750D", 0, 0x368e,
7059 { 6362,-823,-847,-4426,12109,2616,-743,1857,5635 } },
7060 { "Canon EOS 760D", 0, 0x350f,
7061 { 6362,-823,-847,-4426,12109,2616,-743,1857,5635 } },
7062 { "Canon EOS 1000D", 0, 0xe43,
7063 { 6771,-1139,-977,-7818,15123,2928,-1244,1437,7533 } },
7064 { "Canon EOS 1100D", 0, 0x3510,
7065 { 6444,-904,-893,-4563,12308,2535,-903,2016,6728 } },
7066 { "Canon EOS 1200D", 0, 0x37c2,
7067 { 6461,-907,-882,-4300,12184,2378,-819,1944,5931 } },
7068 { "Canon EOS 1300D", 0, 0x3510,
7069 { 6939,-1016,-866,-4428,12473,2177,-1175,2178,6162 } },
7070 { "Canon EOS M3", 0, 0,
7071 { 6362,-823,-847,-4426,12109,2616,-743,1857,5635 } },
7072 { "Canon EOS M10", 0, 0,
7073 { 6400,-480,-888,-5294,13416,2047,-1296,2203,6137 } },
7074 { "Canon EOS M", 0, 0,
7075 { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } },
7076 { "Canon EOS-1Ds Mark III", 0, 0x3bb0,
7077 { 5859,-211,-930,-8255,16017,2353,-1732,1887,7448 } },
7078 { "Canon EOS-1Ds Mark II", 0, 0xe80,
7079 { 6517,-602,-867,-8180,15926,2378,-1618,1771,7633 } },
7080 { "Canon EOS-1D Mark IV", 0, 0x3bb0,
7081 { 6014,-220,-795,-4109,12014,2361,-561,1824,5787 } },
7082 { "Canon EOS-1D Mark III", 0, 0x3bb0,
7083 { 6291,-540,-976,-8350,16145,2311,-1714,1858,7326 } },
7084 { "Canon EOS-1D Mark II N", 0, 0xe80,
7085 { 6240,-466,-822,-8180,15825,2500,-1801,1938,8042 } },
7086 { "Canon EOS-1D Mark II", 0, 0xe80,
7087 { 6264,-582,-724,-8312,15948,2504,-1744,1919,8664 } },
7088 { "Canon EOS-1DS", 0, 0xe20,
7089 { 4374,3631,-1743,-7520,15212,2472,-2892,3632,8161 } },
7090 { "Canon EOS-1D C", 0, 0x3c4e,
7091 { 6847,-614,-1014,-4669,12737,2139,-1197,2488,6846 } },
7092 { "Canon EOS-1D X Mark II", 0, 0,
7093 { 7596,-978,-967,-4808,12571,2503,-1398,2567,5752 } },
7094 { "Canon EOS-1D X", 0, 0x3c4e,
7095 { 6847,-614,-1014,-4669,12737,2139,-1197,2488,6846 } },
7096 { "Canon EOS-1D", 0, 0xe20,
7097 { 6806,-179,-1020,-8097,16415,1687,-3267,4236,7690 } },
7098 { "Canon EOS C500", 853, 0, /* DJC */
7099 { 17851,-10604,922,-7425,16662,763,-3660,3636,22278 } },
7100 { "Canon PowerShot A530", 0, 0,
7101 { 0 } }, /* don't want the A5 matrix */
7102 { "Canon PowerShot A50", 0, 0,
7103 { -5300,9846,1776,3436,684,3939,-5540,9879,6200,-1404,11175,217 } },
7104 { "Canon PowerShot A5", 0, 0,
7105 { -4801,9475,1952,2926,1611,4094,-5259,10164,5947,-1554,10883,547 } },
7106 { "Canon PowerShot G10", 0, 0,
7107 { 11093,-3906,-1028,-5047,12492,2879,-1003,1750,5561 } },
7108 { "Canon PowerShot G11", 0, 0,
7109 { 12177,-4817,-1069,-1612,9864,2049,-98,850,4471 } },
7110 { "Canon PowerShot G12", 0, 0,
7111 { 13244,-5501,-1248,-1508,9858,1935,-270,1083,4366 } },
7112 { "Canon PowerShot G15", 0, 0,
7113 { 7474,-2301,-567,-4056,11456,2975,-222,716,4181 } },
7114 { "Canon PowerShot G16", 0, 0,
7115 { 8020,-2687,-682,-3704,11879,2052,-965,1921,5556 } },
7116 { "Canon PowerShot G1 X", 0, 0,
7117 { 7378,-1255,-1043,-4088,12251,2048,-876,1946,5805 } },
7118 { "Canon PowerShot G1", 0, 0,
7119 { -4778,9467,2172,4743,-1141,4344,-5146,9908,6077,-1566,11051,557 } },
7120 { "Canon PowerShot G2", 0, 0,
7121 { 9087,-2693,-1049,-6715,14382,2537,-2291,2819,7790 } },
7122 { "Canon PowerShot G3 X", 0, 0,
7123 { 9701,-3857,-921,-3149,11537,1817,-786,1817,5147 } },
7124 { "Canon PowerShot G3", 0, 0,
7125 { 9212,-2781,-1073,-6573,14189,2605,-2300,2844,7664 } },
7126 { "Canon PowerShot G5 X", 0, 0,
7127 { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } },
7128 { "Canon PowerShot G5", 0, 0,
7129 { 9757,-2872,-933,-5972,13861,2301,-1622,2328,7212 } },
7130 { "Canon PowerShot G6", 0, 0,
7131 { 9877,-3775,-871,-7613,14807,3072,-1448,1305,7485 } },
7132 { "Canon PowerShot G7 X", 0, 0,
7133 { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } },
7134 { "Canon PowerShot G9 X", 0, 0,
7135 { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } },
7136 { "Canon PowerShot G9", 0, 0,
7137 { 7368,-2141,-598,-5621,13254,2625,-1418,1696,5743 } },
7138 { "Canon PowerShot Pro1", 0, 0,
7139 { 10062,-3522,-999,-7643,15117,2730,-765,817,7323 } },
7140 { "Canon PowerShot Pro70", 34, 0,
7141 { -4155,9818,1529,3939,-25,4522,-5521,9870,6610,-2238,10873,1342 } },
7142 { "Canon PowerShot Pro90", 0, 0,
7143 { -4963,9896,2235,4642,-987,4294,-5162,10011,5859,-1770,11230,577 } },
7144 { "Canon PowerShot S30", 0, 0,
7145 { 10566,-3652,-1129,-6552,14662,2006,-2197,2581,7670 } },
7146 { "Canon PowerShot S40", 0, 0,
7147 { 8510,-2487,-940,-6869,14231,2900,-2318,2829,9013 } },
7148 { "Canon PowerShot S45", 0, 0,
7149 { 8163,-2333,-955,-6682,14174,2751,-2077,2597,8041 } },
7150 { "Canon PowerShot S50", 0, 0,
7151 { 8882,-2571,-863,-6348,14234,2288,-1516,2172,6569 } },
7152 { "Canon PowerShot S60", 0, 0,
7153 { 8795,-2482,-797,-7804,15403,2573,-1422,1996,7082 } },
7154 { "Canon PowerShot S70", 0, 0,
7155 { 9976,-3810,-832,-7115,14463,2906,-901,989,7889 } },
7156 { "Canon PowerShot S90", 0, 0,
7157 { 12374,-5016,-1049,-1677,9902,2078,-83,852,4683 } },
7158 { "Canon PowerShot S95", 0, 0,
7159 { 13440,-5896,-1279,-1236,9598,1931,-180,1001,4651 } },
7160 { "Canon PowerShot S100", 0, 0,
7161 { 7968,-2565,-636,-2873,10697,2513,180,667,4211 } },
7162 { "Canon PowerShot S110", 0, 0,
7163 { 8039,-2643,-654,-3783,11230,2930,-206,690,4194 } },
7164 { "Canon PowerShot S120", 0, 0,
7165 { 6961,-1685,-695,-4625,12945,1836,-1114,2152,5518 } },
7166 { "Canon PowerShot SX1 IS", 0, 0,
7167 { 6578,-259,-502,-5974,13030,3309,-308,1058,4970 } },
7168 { "Canon PowerShot SX50 HS", 0, 0,
7169 { 12432,-4753,-1247,-2110,10691,1629,-412,1623,4926 } },
7170 { "Canon PowerShot SX60 HS", 0, 0,
7171 { 13161,-5451,-1344,-1989,10654,1531,-47,1271,4955 } },
7172 { "Canon PowerShot A3300", 0, 0, /* DJC */
7173 { 10826,-3654,-1023,-3215,11310,1906,0,999,4960 } },
7174 { "Canon PowerShot A470", 0, 0, /* DJC */
7175 { 12513,-4407,-1242,-2680,10276,2405,-878,2215,4734 } },
7176 { "Canon PowerShot A610", 0, 0, /* DJC */
7177 { 15591,-6402,-1592,-5365,13198,2168,-1300,1824,5075 } },
7178 { "Canon PowerShot A620", 0, 0, /* DJC */
7179 { 15265,-6193,-1558,-4125,12116,2010,-888,1639,5220 } },
7180 { "Canon PowerShot A630", 0, 0, /* DJC */
7181 { 14201,-5308,-1757,-6087,14472,1617,-2191,3105,5348 } },
7182 { "Canon PowerShot A640", 0, 0, /* DJC */
7183 { 13124,-5329,-1390,-3602,11658,1944,-1612,2863,4885 } },
7184 { "Canon PowerShot A650", 0, 0, /* DJC */
7185 { 9427,-3036,-959,-2581,10671,1911,-1039,1982,4430 } },
7186 { "Canon PowerShot A720", 0, 0, /* DJC */
7187 { 14573,-5482,-1546,-1266,9799,1468,-1040,1912,3810 } },
7188 { "Canon PowerShot S3 IS", 0, 0, /* DJC */
7189 { 14062,-5199,-1446,-4712,12470,2243,-1286,2028,4836 } },
7190 { "Canon PowerShot SX110 IS", 0, 0, /* DJC */
7191 { 14134,-5576,-1527,-1991,10719,1273,-1158,1929,3581 } },
7192 { "Canon PowerShot SX220", 0, 0, /* DJC */
7193 { 13898,-5076,-1447,-1405,10109,1297,-244,1860,3687 } },
7194 { "Canon IXUS 160", 0, 0, /* DJC */
7195 { 11657,-3781,-1136,-3544,11262,2283,-160,1219,4700 } },
7196 { "Casio EX-S20", 0, 0, /* DJC */
7197 { 11634,-3924,-1128,-4968,12954,2015,-1588,2648,7206 } },
7198 { "Casio EX-Z750", 0, 0, /* DJC */
7199 { 10819,-3873,-1099,-4903,13730,1175,-1755,3751,4632 } },
7200 { "Casio EX-Z10", 128, 0xfff, /* DJC */
7201 { 9790,-3338,-603,-2321,10222,2099,-344,1273,4799 } },
7203 { 3390,480,-500,-800,3610,340,-550,2336,1192 } },
7205 { 3390,480,-500,-800,3610,340,-550,2336,1192 } },
7207 { 20183,-4295,-423,-3940,15330,3985,-280,4870,9800 } },
7208 { "Contax N Digital", 0, 0xf1e,
7209 { 7777,1285,-1053,-9280,16543,2916,-3677,5679,7060 } },
7211 { 6596,-2079,-562,-4782,13016,1933,-970,1581,5181 } },
7212 { "Epson R-D1", 0, 0,
7213 { 6827,-1878,-732,-8429,16012,2564,-704,592,7145 } },
7214 { "Fujifilm E550", 0, 0,
7215 { 11044,-3888,-1120,-7248,15168,2208,-1531,2277,8069 } },
7216 { "Fujifilm E900", 0, 0,
7217 { 9183,-2526,-1078,-7461,15071,2574,-2022,2440,8639 } },
7218 { "Fujifilm F5", 0, 0,
7219 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
7220 { "Fujifilm F6", 0, 0,
7221 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
7222 { "Fujifilm F77", 0, 0xfe9,
7223 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
7224 { "Fujifilm F7", 0, 0,
7225 { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } },
7226 { "Fujifilm F8", 0, 0,
7227 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
7228 { "Fujifilm S100FS", 514, 0,
7229 { 11521,-4355,-1065,-6524,13767,3058,-1466,1984,6045 } },
7230 { "Fujifilm S1", 0, 0,
7231 { 12297,-4882,-1202,-2106,10691,1623,-88,1312,4790 } },
7232 { "Fujifilm S20Pro", 0, 0,
7233 { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } },
7234 { "Fujifilm S20", 512, 0x3fff,
7235 { 11401,-4498,-1312,-5088,12751,2613,-838,1568,5941 } },
7236 { "Fujifilm S2Pro", 128, 0,
7237 { 12492,-4690,-1402,-7033,15423,1647,-1507,2111,7697 } },
7238 { "Fujifilm S3Pro", 0, 0,
7239 { 11807,-4612,-1294,-8927,16968,1988,-2120,2741,8006 } },
7240 { "Fujifilm S5Pro", 0, 0,
7241 { 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } },
7242 { "Fujifilm S5000", 0, 0,
7243 { 8754,-2732,-1019,-7204,15069,2276,-1702,2334,6982 } },
7244 { "Fujifilm S5100", 0, 0,
7245 { 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } },
7246 { "Fujifilm S5500", 0, 0,
7247 { 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } },
7248 { "Fujifilm S5200", 0, 0,
7249 { 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } },
7250 { "Fujifilm S5600", 0, 0,
7251 { 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } },
7252 { "Fujifilm S6", 0, 0,
7253 { 12628,-4887,-1401,-6861,14996,1962,-2198,2782,7091 } },
7254 { "Fujifilm S7000", 0, 0,
7255 { 10190,-3506,-1312,-7153,15051,2238,-2003,2399,7505 } },
7256 { "Fujifilm S9000", 0, 0,
7257 { 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 } },
7258 { "Fujifilm S9500", 0, 0,
7259 { 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 } },
7260 { "Fujifilm S9100", 0, 0,
7261 { 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 } },
7262 { "Fujifilm S9600", 0, 0,
7263 { 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 } },
7264 { "Fujifilm SL1000", 0, 0,
7265 { 11705,-4262,-1107,-2282,10791,1709,-555,1713,4945 } },
7266 { "Fujifilm IS-1", 0, 0,
7267 { 21461,-10807,-1441,-2332,10599,1999,289,875,7703 } },
7268 { "Fujifilm IS Pro", 0, 0,
7269 { 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } },
7270 { "Fujifilm HS10 HS11", 0, 0xf68,
7271 { 12440,-3954,-1183,-1123,9674,1708,-83,1614,4086 } },
7272 { "Fujifilm HS2", 0, 0,
7273 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
7274 { "Fujifilm HS3", 0, 0,
7275 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
7276 { "Fujifilm HS50EXR", 0, 0,
7277 { 12085,-4727,-953,-3257,11489,2002,-511,2046,4592 } },
7278 { "Fujifilm F900EXR", 0, 0,
7279 { 12085,-4727,-953,-3257,11489,2002,-511,2046,4592 } },
7280 { "Fujifilm X100S", 0, 0,
7281 { 10592,-4262,-1008,-3514,11355,2465,-870,2025,6386 } },
7282 { "Fujifilm X100T", 0, 0,
7283 { 10592,-4262,-1008,-3514,11355,2465,-870,2025,6386 } },
7284 { "Fujifilm X100", 0, 0,
7285 { 12161,-4457,-1069,-5034,12874,2400,-795,1724,6904 } },
7286 { "Fujifilm X10", 0, 0,
7287 { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } },
7288 { "Fujifilm X20", 0, 0,
7289 { 11768,-4971,-1133,-4904,12927,2183,-480,1723,4605 } },
7290 { "Fujifilm X30", 0, 0,
7291 { 12328,-5256,-1144,-4469,12927,1675,-87,1291,4351 } },
7292 { "Fujifilm X70", 0, 0,
7293 { 10450,-4329,-878,-3217,11105,2421,-752,1758,6519 } },
7294 { "Fujifilm X-Pro1", 0, 0,
7295 { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } },
7296 { "Fujifilm X-Pro2", 0, 0,
7297 { 11434,-4948,-1210,-3746,12042,1903,-666,1479,5235 } },
7298 { "Fujifilm X-A1", 0, 0,
7299 { 11086,-4555,-839,-3512,11310,2517,-815,1341,5940 } },
7300 { "Fujifilm X-A2", 0, 0,
7301 { 10763,-4560,-917,-3346,11311,2322,-475,1135,5843 } },
7302 { "Fujifilm X-E1", 0, 0,
7303 { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } },
7304 { "Fujifilm X-E2S", 0, 0,
7305 { 11562,-5118,-961,-3022,11007,2311,-525,1569,6097 } },
7306 { "Fujifilm X-E2", 0, 0,
7307 { 8458,-2451,-855,-4597,12447,2407,-1475,2482,6526 } },
7308 { "Fujifilm X-M1", 0, 0,
7309 { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } },
7310 { "Fujifilm X-S1", 0, 0,
7311 { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } },
7312 { "Fujifilm X-T1", 0, 0, /* also X-T10 */
7313 { 8458,-2451,-855,-4597,12447,2407,-1475,2482,6526 } },
7314 { "Fujifilm XF1", 0, 0,
7315 { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } },
7316 { "Fujifilm XQ", 0, 0, /* XQ1 and XQ2 */
7317 { 9252,-2704,-1064,-5893,14265,1717,-1101,2341,4349 } },
7318 { "Imacon Ixpress", 0, 0, /* DJC */
7319 { 7025,-1415,-704,-5188,13765,1424,-1248,2742,6038 } },
7320 { "Kodak NC2000", 0, 0,
7321 { 13891,-6055,-803,-465,9919,642,2121,82,1291 } },
7322 { "Kodak DCS315C", 8, 0,
7323 { 17523,-4827,-2510,756,8546,-137,6113,1649,2250 } },
7324 { "Kodak DCS330C", 8, 0,
7325 { 20620,-7572,-2801,-103,10073,-396,3551,-233,2220 } },
7326 { "Kodak DCS420", 0, 0,
7327 { 10868,-1852,-644,-1537,11083,484,2343,628,2216 } },
7328 { "Kodak DCS460", 0, 0,
7329 { 10592,-2206,-967,-1944,11685,230,2206,670,1273 } },
7330 { "Kodak EOSDCS1", 0, 0,
7331 { 10592,-2206,-967,-1944,11685,230,2206,670,1273 } },
7332 { "Kodak EOSDCS3B", 0, 0,
7333 { 9898,-2700,-940,-2478,12219,206,1985,634,1031 } },
7334 { "Kodak DCS520C", 178, 0,
7335 { 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } },
7336 { "Kodak DCS560C", 177, 0,
7337 { 20482,-7172,-3125,-1033,10410,-285,2542,226,3136 } },
7338 { "Kodak DCS620C", 177, 0,
7339 { 23617,-10175,-3149,-2054,11749,-272,2586,-489,3453 } },
7340 { "Kodak DCS620X", 176, 0,
7341 { 13095,-6231,154,12221,-21,-2137,895,4602,2258 } },
7342 { "Kodak DCS660C", 173, 0,
7343 { 18244,-6351,-2739,-791,11193,-521,3711,-129,2802 } },
7344 { "Kodak DCS720X", 0, 0,
7345 { 11775,-5884,950,9556,1846,-1286,-1019,6221,2728 } },
7346 { "Kodak DCS760C", 0, 0,
7347 { 16623,-6309,-1411,-4344,13923,323,2285,274,2926 } },
7348 { "Kodak DCS Pro SLR", 0, 0,
7349 { 5494,2393,-232,-6427,13850,2846,-1876,3997,5445 } },
7350 { "Kodak DCS Pro 14nx", 0, 0,
7351 { 5494,2393,-232,-6427,13850,2846,-1876,3997,5445 } },
7352 { "Kodak DCS Pro 14", 0, 0,
7353 { 7791,3128,-776,-8588,16458,2039,-2455,4006,6198 } },
7354 { "Kodak ProBack645", 0, 0,
7355 { 16414,-6060,-1470,-3555,13037,473,2545,122,4948 } },
7356 { "Kodak ProBack", 0, 0,
7357 { 21179,-8316,-2918,-915,11019,-165,3477,-180,4210 } },
7358 { "Kodak P712", 0, 0,
7359 { 9658,-3314,-823,-5163,12695,2768,-1342,1843,6044 } },
7360 { "Kodak P850", 0, 0xf7c,
7361 { 10511,-3836,-1102,-6946,14587,2558,-1481,1792,6246 } },
7362 { "Kodak P880", 0, 0xfff,
7363 { 12805,-4662,-1376,-7480,15267,2360,-1626,2194,7904 } },
7364 { "Kodak EasyShare Z980", 0, 0,
7365 { 11313,-3559,-1101,-3893,11891,2257,-1214,2398,4908 } },
7366 { "Kodak EasyShare Z981", 0, 0,
7367 { 12729,-4717,-1188,-1367,9187,2582,274,860,4411 } },
7368 { "Kodak EasyShare Z990", 0, 0xfed,
7369 { 11749,-4048,-1309,-1867,10572,1489,-138,1449,4522 } },
7370 { "Kodak EASYSHARE Z1015", 0, 0xef1,
7371 { 11265,-4286,-992,-4694,12343,2647,-1090,1523,5447 } },
7372 { "Leaf CMost", 0, 0,
7373 { 3952,2189,449,-6701,14585,2275,-4536,7349,6536 } },
7374 { "Leaf Valeo 6", 0, 0,
7375 { 3952,2189,449,-6701,14585,2275,-4536,7349,6536 } },
7376 { "Leaf Aptus 54S", 0, 0,
7377 { 8236,1746,-1314,-8251,15953,2428,-3673,5786,5771 } },
7378 { "Leaf Aptus 65", 0, 0,
7379 { 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 } },
7380 { "Leaf Aptus 75", 0, 0,
7381 { 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 } },
7383 { 8236,1746,-1314,-8251,15953,2428,-3673,5786,5771 } },
7384 { "Mamiya ZD", 0, 0,
7385 { 7645,2579,-1363,-8689,16717,2015,-3712,5941,5961 } },
7386 { "Micron 2010", 110, 0, /* DJC */
7387 { 16695,-3761,-2151,155,9682,163,3433,951,4904 } },
7388 { "Minolta DiMAGE 5", 0, 0xf7d,
7389 { 8983,-2942,-963,-6556,14476,2237,-2426,2887,8014 } },
7390 { "Minolta DiMAGE 7Hi", 0, 0xf7d,
7391 { 11368,-3894,-1242,-6521,14358,2339,-2475,3056,7285 } },
7392 { "Minolta DiMAGE 7", 0, 0xf7d,
7393 { 9144,-2777,-998,-6676,14556,2281,-2470,3019,7744 } },
7394 { "Minolta DiMAGE A1", 0, 0xf8b,
7395 { 9274,-2547,-1167,-8220,16323,1943,-2273,2720,8340 } },
7396 { "Minolta DiMAGE A200", 0, 0,
7397 { 8560,-2487,-986,-8112,15535,2771,-1209,1324,7743 } },
7398 { "Minolta DiMAGE A2", 0, 0xf8f,
7399 { 9097,-2726,-1053,-8073,15506,2762,-966,981,7763 } },
7400 { "Minolta DiMAGE Z2", 0, 0, /* DJC */
7401 { 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 } },
7402 { "Minolta DYNAX 5", 0, 0xffb,
7403 { 10284,-3283,-1086,-7957,15762,2316,-829,882,6644 } },
7404 { "Minolta DYNAX 7", 0, 0xffb,
7405 { 10239,-3104,-1099,-8037,15727,2451,-927,925,6871 } },
7406 { "Motorola PIXL", 0, 0, /* DJC */
7407 { 8898,-989,-1033,-3292,11619,1674,-661,3178,5216 } },
7408 { "Nikon D100", 0, 0,
7409 { 5902,-933,-782,-8983,16719,2354,-1402,1455,6464 } },
7410 { "Nikon D1H", 0, 0,
7411 { 7577,-2166,-926,-7454,15592,1934,-2377,2808,8606 } },
7412 { "Nikon D1X", 0, 0,
7413 { 7702,-2245,-975,-9114,17242,1875,-2679,3055,8521 } },
7414 { "Nikon D1", 0, 0, /* multiplied by 2.218750, 1.0, 1.148438 */
7415 { 16772,-4726,-2141,-7611,15713,1972,-2846,3494,9521 } },
7416 { "Nikon D200", 0, 0xfbc,
7417 { 8367,-2248,-763,-8758,16447,2422,-1527,1550,8053 } },
7418 { "Nikon D2H", 0, 0,
7419 { 5710,-901,-615,-8594,16617,2024,-2975,4120,6830 } },
7420 { "Nikon D2X", 0, 0,
7421 { 10231,-2769,-1255,-8301,15900,2552,-797,680,7148 } },
7422 { "Nikon D3000", 0, 0,
7423 { 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } },
7424 { "Nikon D3100", 0, 0,
7425 { 7911,-2167,-813,-5327,13150,2408,-1288,2483,7968 } },
7426 { "Nikon D3200", 0, 0xfb9,
7427 { 7013,-1408,-635,-5268,12902,2640,-1470,2801,7379 } },
7428 { "Nikon D3300", 0, 0,
7429 { 6988,-1384,-714,-5631,13410,2447,-1485,2204,7318 } },
7430 { "Nikon D300", 0, 0,
7431 { 9030,-1992,-715,-8465,16302,2255,-2689,3217,8069 } },
7432 { "Nikon D3X", 0, 0,
7433 { 7171,-1986,-648,-8085,15555,2718,-2170,2512,7457 } },
7434 { "Nikon D3S", 0, 0,
7435 { 8828,-2406,-694,-4874,12603,2541,-660,1509,7587 } },
7437 { 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } },
7438 { "Nikon D40X", 0, 0,
7439 { 8819,-2543,-911,-9025,16928,2151,-1329,1213,8449 } },
7440 { "Nikon D40", 0, 0,
7441 { 6992,-1668,-806,-8138,15748,2543,-874,850,7897 } },
7442 { "Nikon D4S", 0, 0,
7443 { 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } },
7445 { 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } },
7447 { 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } },
7448 { "Nikon D5000", 0, 0xf00,
7449 { 7309,-1403,-519,-8474,16008,2622,-2433,2826,8064 } },
7450 { "Nikon D5100", 0, 0x3de6,
7451 { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } },
7452 { "Nikon D5200", 0, 0,
7453 { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } },
7454 { "Nikon D5300", 0, 0,
7455 { 6988,-1384,-714,-5631,13410,2447,-1485,2204,7318 } },
7456 { "Nikon D5500", 0, 0,
7457 { 8821,-2938,-785,-4178,12142,2287,-824,1651,6860 } },
7458 { "Nikon D500", 0, 0,
7459 { 8813,-3210,-1036,-4703,12868,2021,-1054,1940,6129 } },
7460 { "Nikon D50", 0, 0,
7461 { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } },
7463 { 9200,-3522,-992,-5755,13803,2117,-753,1486,6338 } },
7464 { "Nikon D600", 0, 0x3e07,
7465 { 8178,-2245,-609,-4857,12394,2776,-1207,2086,7298 } },
7466 { "Nikon D610", 0, 0,
7467 { 8178,-2245,-609,-4857,12394,2776,-1207,2086,7298 } },
7468 { "Nikon D60", 0, 0,
7469 { 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } },
7470 { "Nikon D7000", 0, 0,
7471 { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } },
7472 { "Nikon D7100", 0, 0,
7473 { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } },
7474 { "Nikon D7200", 0, 0,
7475 { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } },
7476 { "Nikon D750", 0, 0,
7477 { 9020,-2890,-715,-4535,12436,2348,-934,1919,7086 } },
7478 { "Nikon D700", 0, 0,
7479 { 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } },
7480 { "Nikon D70", 0, 0,
7481 { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } },
7482 { "Nikon D810", 0, 0,
7483 { 9369,-3195,-791,-4488,12430,2301,-893,1796,6872 } },
7484 { "Nikon D800", 0, 0,
7485 { 7866,-2108,-555,-4869,12483,2681,-1176,2069,7501 } },
7486 { "Nikon D80", 0, 0,
7487 { 8629,-2410,-883,-9055,16940,2171,-1490,1363,8520 } },
7488 { "Nikon D90", 0, 0xf00,
7489 { 7309,-1403,-519,-8474,16008,2622,-2434,2826,8064 } },
7490 { "Nikon E700", 0, 0x3dd, /* DJC */
7491 { -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } },
7492 { "Nikon E800", 0, 0x3dd, /* DJC */
7493 { -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } },
7494 { "Nikon E950", 0, 0x3dd, /* DJC */
7495 { -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } },
7496 { "Nikon E995", 0, 0, /* copied from E5000 */
7497 { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
7498 { "Nikon E2100", 0, 0, /* copied from Z2, new white balance */
7499 { 13142,-4152,-1596,-4655,12374,2282,-1769,2696,6711} },
7500 { "Nikon E2500", 0, 0,
7501 { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
7502 { "Nikon E3200", 0, 0, /* DJC */
7503 { 9846,-2085,-1019,-3278,11109,2170,-774,2134,5745 } },
7504 { "Nikon E4300", 0, 0, /* copied from Minolta DiMAGE Z2 */
7505 { 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 } },
7506 { "Nikon E4500", 0, 0,
7507 { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
7508 { "Nikon E5000", 0, 0,
7509 { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
7510 { "Nikon E5400", 0, 0,
7511 { 9349,-2987,-1001,-7919,15766,2266,-2098,2680,6839 } },
7512 { "Nikon E5700", 0, 0,
7513 { -5368,11478,2368,5537,-113,3148,-4969,10021,5782,778,9028,211 } },
7514 { "Nikon E8400", 0, 0,
7515 { 7842,-2320,-992,-8154,15718,2599,-1098,1342,7560 } },
7516 { "Nikon E8700", 0, 0,
7517 { 8489,-2583,-1036,-8051,15583,2643,-1307,1407,7354 } },
7518 { "Nikon E8800", 0, 0,
7519 { 7971,-2314,-913,-8451,15762,2894,-1442,1520,7610 } },
7520 { "Nikon COOLPIX A", 0, 0,
7521 { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } },
7522 { "Nikon COOLPIX P330", 200, 0,
7523 { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } },
7524 { "Nikon COOLPIX P340", 200, 0,
7525 { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } },
7526 { "Nikon COOLPIX P6000", 0, 0,
7527 { 9698,-3367,-914,-4706,12584,2368,-837,968,5801 } },
7528 { "Nikon COOLPIX P7000", 0, 0,
7529 { 11432,-3679,-1111,-3169,11239,2202,-791,1380,4455 } },
7530 { "Nikon COOLPIX P7100", 0, 0,
7531 { 11053,-4269,-1024,-1976,10182,2088,-526,1263,4469 } },
7532 { "Nikon COOLPIX P7700", 200, 0,
7533 { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } },
7534 { "Nikon COOLPIX P7800", 200, 0,
7535 { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } },
7536 { "Nikon 1 V3", 0, 0,
7537 { 5958,-1559,-571,-4021,11453,2939,-634,1548,5087 } },
7538 { "Nikon 1 J4", 0, 0,
7539 { 5958,-1559,-571,-4021,11453,2939,-634,1548,5087 } },
7540 { "Nikon 1 J5", 0, 0,
7541 { 7520,-2518,-645,-3844,12102,1945,-913,2249,6835 } },
7542 { "Nikon 1 S2", 200, 0,
7543 { 6612,-1342,-618,-3338,11055,2623,-174,1792,5075 } },
7544 { "Nikon 1 V2", 0, 0,
7545 { 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } },
7546 { "Nikon 1 J3", 0, 0,
7547 { 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } },
7548 { "Nikon 1 AW1", 0, 0,
7549 { 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } },
7550 { "Nikon 1 ", 0, 0, /* J1, J2, S1, V1 */
7551 { 8994,-2667,-865,-4594,12324,2552,-699,1786,6260 } },
7552 { "Olympus AIR A01", 0, 0,
7553 { 8992,-3093,-639,-2563,10721,2122,-437,1270,5473 } },
7554 { "Olympus C5050", 0, 0,
7555 { 10508,-3124,-1273,-6079,14294,1901,-1653,2306,6237 } },
7556 { "Olympus C5060", 0, 0,
7557 { 10445,-3362,-1307,-7662,15690,2058,-1135,1176,7602 } },
7558 { "Olympus C7070", 0, 0,
7559 { 10252,-3531,-1095,-7114,14850,2436,-1451,1723,6365 } },
7560 { "Olympus C70", 0, 0,
7561 { 10793,-3791,-1146,-7498,15177,2488,-1390,1577,7321 } },
7562 { "Olympus C80", 0, 0,
7563 { 8606,-2509,-1014,-8238,15714,2703,-942,979,7760 } },
7564 { "Olympus E-10", 0, 0xffc,
7565 { 12745,-4500,-1416,-6062,14542,1580,-1934,2256,6603 } },
7566 { "Olympus E-1", 0, 0,
7567 { 11846,-4767,-945,-7027,15878,1089,-2699,4122,8311 } },
7568 { "Olympus E-20", 0, 0xffc,
7569 { 13173,-4732,-1499,-5807,14036,1895,-2045,2452,7142 } },
7570 { "Olympus E-300", 0, 0,
7571 { 7828,-1761,-348,-5788,14071,1830,-2853,4518,6557 } },
7572 { "Olympus E-330", 0, 0,
7573 { 8961,-2473,-1084,-7979,15990,2067,-2319,3035,8249 } },
7574 { "Olympus E-30", 0, 0xfbc,
7575 { 8144,-1861,-1111,-7763,15894,1929,-1865,2542,7607 } },
7576 { "Olympus E-3", 0, 0xf99,
7577 { 9487,-2875,-1115,-7533,15606,2010,-1618,2100,7389 } },
7578 { "Olympus E-400", 0, 0,
7579 { 6169,-1483,-21,-7107,14761,2536,-2904,3580,8568 } },
7580 { "Olympus E-410", 0, 0xf6a,
7581 { 8856,-2582,-1026,-7761,15766,2082,-2009,2575,7469 } },
7582 { "Olympus E-420", 0, 0xfd7,
7583 { 8746,-2425,-1095,-7594,15612,2073,-1780,2309,7416 } },
7584 { "Olympus E-450", 0, 0xfd2,
7585 { 8745,-2425,-1095,-7594,15613,2073,-1780,2309,7416 } },
7586 { "Olympus E-500", 0, 0,
7587 { 8136,-1968,-299,-5481,13742,1871,-2556,4205,6630 } },
7588 { "Olympus E-510", 0, 0xf6a,
7589 { 8785,-2529,-1033,-7639,15624,2112,-1783,2300,7817 } },
7590 { "Olympus E-520", 0, 0xfd2,
7591 { 8344,-2322,-1020,-7596,15635,2048,-1748,2269,7287 } },
7592 { "Olympus E-5", 0, 0xeec,
7593 { 11200,-3783,-1325,-4576,12593,2206,-695,1742,7504 } },
7594 { "Olympus E-600", 0, 0xfaf,
7595 { 8453,-2198,-1092,-7609,15681,2008,-1725,2337,7824 } },
7596 { "Olympus E-620", 0, 0xfaf,
7597 { 8453,-2198,-1092,-7609,15681,2008,-1725,2337,7824 } },
7598 { "Olympus E-P1", 0, 0xffd,
7599 { 8343,-2050,-1021,-7715,15705,2103,-1831,2380,8235 } },
7600 { "Olympus E-P2", 0, 0xffd,
7601 { 8343,-2050,-1021,-7715,15705,2103,-1831,2380,8235 } },
7602 { "Olympus E-P3", 0, 0,
7603 { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } },
7604 { "Olympus E-P5", 0, 0,
7605 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
7606 { "Olympus E-PL1s", 0, 0,
7607 { 11409,-3872,-1393,-4572,12757,2003,-709,1810,7415 } },
7608 { "Olympus E-PL1", 0, 0,
7609 { 11408,-4289,-1215,-4286,12385,2118,-387,1467,7787 } },
7610 { "Olympus E-PL2", 0, 0xcf3,
7611 { 15030,-5552,-1806,-3987,12387,1767,-592,1670,7023 } },
7612 { "Olympus E-PL3", 0, 0,
7613 { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } },
7614 { "Olympus E-PL5", 0, 0xfcb,
7615 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
7616 { "Olympus E-PL6", 0, 0,
7617 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
7618 { "Olympus E-PL7", 0, 0,
7619 { 9197,-3190,-659,-2606,10830,2039,-458,1250,5458 } },
7620 { "Olympus E-PM1", 0, 0,
7621 { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } },
7622 { "Olympus E-PM2", 0, 0,
7623 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
7624 { "Olympus E-M10", 0, 0, /* also E-M10 Mark II */
7625 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
7626 { "Olympus E-M1", 0, 0,
7627 { 7687,-1984,-606,-4327,11928,2721,-1381,2339,6452 } },
7628 { "Olympus E-M5MarkII", 0, 0,
7629 { 9422,-3258,-711,-2655,10898,2015,-512,1354,5512 } },
7630 { "Olympus E-M5", 0, 0xfe1,
7631 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
7632 { "Olympus PEN-F", 0, 0,
7633 { 9476,-3182,-765,-2613,10958,1893,-449,1315,5268 } },
7634 { "Olympus SH-2", 0, 0,
7635 { 10156,-3425,-1077,-2611,11177,1624,-385,1592,5080 } },
7636 { "Olympus SP350", 0, 0,
7637 { 12078,-4836,-1069,-6671,14306,2578,-786,939,7418 } },
7638 { "Olympus SP3", 0, 0,
7639 { 11766,-4445,-1067,-6901,14421,2707,-1029,1217,7572 } },
7640 { "Olympus SP500UZ", 0, 0xfff,
7641 { 9493,-3415,-666,-5211,12334,3260,-1548,2262,6482 } },
7642 { "Olympus SP510UZ", 0, 0xffe,
7643 { 10593,-3607,-1010,-5881,13127,3084,-1200,1805,6721 } },
7644 { "Olympus SP550UZ", 0, 0xffe,
7645 { 11597,-4006,-1049,-5432,12799,2957,-1029,1750,6516 } },
7646 { "Olympus SP560UZ", 0, 0xff9,
7647 { 10915,-3677,-982,-5587,12986,2911,-1168,1968,6223 } },
7648 { "Olympus SP570UZ", 0, 0,
7649 { 11522,-4044,-1146,-4736,12172,2904,-988,1829,6039 } },
7650 { "Olympus STYLUS1", 0, 0,
7651 { 8360,-2420,-880,-3928,12353,1739,-1381,2416,5173 } },
7652 { "Olympus TG-4", 0, 0,
7653 { 11426,-4159,-1126,-2066,10678,1593,-120,1327,4998 } },
7654 { "Olympus XZ-10", 0, 0,
7655 { 9777,-3483,-925,-2886,11297,1800,-602,1663,5134 } },
7656 { "Olympus XZ-1", 0, 0,
7657 { 10901,-4095,-1074,-1141,9208,2293,-62,1417,5158 } },
7658 { "Olympus XZ-2", 0, 0,
7659 { 9777,-3483,-925,-2886,11297,1800,-602,1663,5134 } },
7660 { "OmniVision", 0, 0, /* DJC */
7661 { 12782,-4059,-379,-478,9066,1413,1340,1513,5176 } },
7662 { "Pentax *ist DL2", 0, 0,
7663 { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
7664 { "Pentax *ist DL", 0, 0,
7665 { 10829,-2838,-1115,-8339,15817,2696,-837,680,11939 } },
7666 { "Pentax *ist DS2", 0, 0,
7667 { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
7668 { "Pentax *ist DS", 0, 0,
7669 { 10371,-2333,-1206,-8688,16231,2602,-1230,1116,11282 } },
7670 { "Pentax *ist D", 0, 0,
7671 { 9651,-2059,-1189,-8881,16512,2487,-1460,1345,10687 } },
7672 { "Pentax K10D", 0, 0,
7673 { 9566,-2863,-803,-7170,15172,2112,-818,803,9705 } },
7674 { "Pentax K1", 0, 0,
7675 { 11095,-3157,-1324,-8377,15834,2720,-1108,947,11688 } },
7676 { "Pentax K20D", 0, 0,
7677 { 9427,-2714,-868,-7493,16092,1373,-2199,3264,7180 } },
7678 { "Pentax K200D", 0, 0,
7679 { 9186,-2678,-907,-8693,16517,2260,-1129,1094,8524 } },
7680 { "Pentax K2000", 0, 0,
7681 { 11057,-3604,-1155,-5152,13046,2329,-282,375,8104 } },
7682 { "Pentax K-m", 0, 0,
7683 { 11057,-3604,-1155,-5152,13046,2329,-282,375,8104 } },
7684 { "Pentax K-x", 0, 0,
7685 { 8843,-2837,-625,-5025,12644,2668,-411,1234,7410 } },
7686 { "Pentax K-r", 0, 0,
7687 { 9895,-3077,-850,-5304,13035,2521,-883,1768,6936 } },
7688 { "Pentax K-1", 0, 0,
7689 { 8566,-2746,-1201,-3612,12204,1550,-893,1680,6264 } },
7690 { "Pentax K-30", 0, 0,
7691 { 8710,-2632,-1167,-3995,12301,1881,-981,1719,6535 } },
7692 { "Pentax K-3 II", 0, 0,
7693 { 8626,-2607,-1155,-3995,12301,1881,-1039,1822,6925 } },
7694 { "Pentax K-3", 0, 0,
7695 { 7415,-2052,-721,-5186,12788,2682,-1446,2157,6773 } },
7696 { "Pentax K-5 II", 0, 0,
7697 { 8170,-2725,-639,-4440,12017,2744,-771,1465,6599 } },
7698 { "Pentax K-5", 0, 0,
7699 { 8713,-2833,-743,-4342,11900,2772,-722,1543,6247 } },
7700 { "Pentax K-7", 0, 0,
7701 { 9142,-2947,-678,-8648,16967,1663,-2224,2898,8615 } },
7702 { "Pentax K-S1", 0, 0,
7703 { 8512,-3211,-787,-4167,11966,2487,-638,1288,6054 } },
7704 { "Pentax K-S2", 0, 0,
7705 { 8662,-3280,-798,-3928,11771,2444,-586,1232,6054 } },
7706 { "Pentax Q-S1", 0, 0,
7707 { 12995,-5593,-1107,-1879,10139,2027,-64,1233,4919 } },
7708 { "Pentax 645D", 0, 0x3e00,
7709 { 10646,-3593,-1158,-3329,11699,1831,-667,2874,6287 } },
7710 { "Panasonic DMC-CM1", 15, 0,
7711 { 8770,-3194,-820,-2871,11281,1803,-513,1552,4434 } },
7712 { "Panasonic DMC-FZ8", 0, 0xf7f,
7713 { 8986,-2755,-802,-6341,13575,3077,-1476,2144,6379 } },
7714 { "Panasonic DMC-FZ18", 0, 0,
7715 { 9932,-3060,-935,-5809,13331,2753,-1267,2155,5575 } },
7716 { "Panasonic DMC-FZ28", 15, 0xf96,
7717 { 10109,-3488,-993,-5412,12812,2916,-1305,2140,5543 } },
7718 { "Panasonic DMC-FZ330", 15, 0,
7719 { 8378,-2798,-769,-3068,11410,1877,-538,1792,4623 } },
7720 { "Panasonic DMC-FZ300", 15, 0,
7721 { 8378,-2798,-769,-3068,11410,1877,-538,1792,4623 } },
7722 { "Panasonic DMC-FZ30", 0, 0xf94,
7723 { 10976,-4029,-1141,-7918,15491,2600,-1670,2071,8246 } },
7724 { "Panasonic DMC-FZ3", 15, 0,
7725 { 9938,-2780,-890,-4604,12393,2480,-1117,2304,4620 } },
7726 { "Panasonic DMC-FZ4", 15, 0,
7727 { 13639,-5535,-1371,-1698,9633,2430,316,1152,4108 } },
7728 { "Panasonic DMC-FZ50", 0, 0,
7729 { 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } },
7730 { "Panasonic DMC-FZ7", 15, 0,
7731 { 11532,-4324,-1066,-2375,10847,1749,-564,1699,4351 } },
7732 { "Leica V-LUX1", 0, 0,
7733 { 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } },
7734 { "Panasonic DMC-L10", 15, 0xf96,
7735 { 8025,-1942,-1050,-7920,15904,2100,-2456,3005,7039 } },
7736 { "Panasonic DMC-L1", 0, 0xf7f,
7737 { 8054,-1885,-1025,-8349,16367,2040,-2805,3542,7629 } },
7738 { "Leica DIGILUX 3", 0, 0xf7f,
7739 { 8054,-1885,-1025,-8349,16367,2040,-2805,3542,7629 } },
7740 { "Panasonic DMC-LC1", 0, 0,
7741 { 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } },
7742 { "Leica DIGILUX 2", 0, 0,
7743 { 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } },
7744 { "Panasonic DMC-LX100", 15, 0,
7745 { 8844,-3538,-768,-3709,11762,2200,-698,1792,5220 } },
7746 { "Leica D-LUX (Typ 109)", 15, 0,
7747 { 8844,-3538,-768,-3709,11762,2200,-698,1792,5220 } },
7748 { "Panasonic DMC-LF1", 15, 0,
7749 { 9379,-3267,-816,-3227,11560,1881,-926,1928,5340 } },
7750 { "Leica C (Typ 112)", 15, 0,
7751 { 9379,-3267,-816,-3227,11560,1881,-926,1928,5340 } },
7752 { "Panasonic DMC-LX1", 0, 0xf7f,
7753 { 10704,-4187,-1230,-8314,15952,2501,-920,945,8927 } },
7754 { "Leica D-LUX2", 0, 0xf7f,
7755 { 10704,-4187,-1230,-8314,15952,2501,-920,945,8927 } },
7756 { "Panasonic DMC-LX2", 0, 0,
7757 { 8048,-2810,-623,-6450,13519,3272,-1700,2146,7049 } },
7758 { "Leica D-LUX3", 0, 0,
7759 { 8048,-2810,-623,-6450,13519,3272,-1700,2146,7049 } },
7760 { "Panasonic DMC-LX3", 15, 0,
7761 { 8128,-2668,-655,-6134,13307,3161,-1782,2568,6083 } },
7762 { "Leica D-LUX 4", 15, 0,
7763 { 8128,-2668,-655,-6134,13307,3161,-1782,2568,6083 } },
7764 { "Panasonic DMC-LX5", 15, 0,
7765 { 10909,-4295,-948,-1333,9306,2399,22,1738,4582 } },
7766 { "Leica D-LUX 5", 15, 0,
7767 { 10909,-4295,-948,-1333,9306,2399,22,1738,4582 } },
7768 { "Panasonic DMC-LX7", 15, 0,
7769 { 10148,-3743,-991,-2837,11366,1659,-701,1893,4899 } },
7770 { "Leica D-LUX 6", 15, 0,
7771 { 10148,-3743,-991,-2837,11366,1659,-701,1893,4899 } },
7772 { "Panasonic DMC-FZ1000", 15, 0,
7773 { 7830,-2696,-763,-3325,11667,1866,-641,1712,4824 } },
7774 { "Leica V-LUX (Typ 114)", 15, 0,
7775 { 7830,-2696,-763,-3325,11667,1866,-641,1712,4824 } },
7776 { "Panasonic DMC-FZ100", 15, 0xfff,
7777 { 16197,-6146,-1761,-2393,10765,1869,366,2238,5248 } },
7778 { "Leica V-LUX 2", 15, 0xfff,
7779 { 16197,-6146,-1761,-2393,10765,1869,366,2238,5248 } },
7780 { "Panasonic DMC-FZ150", 15, 0xfff,
7781 { 11904,-4541,-1189,-2355,10899,1662,-296,1586,4289 } },
7782 { "Leica V-LUX 3", 15, 0xfff,
7783 { 11904,-4541,-1189,-2355,10899,1662,-296,1586,4289 } },
7784 { "Panasonic DMC-FZ200", 15, 0xfff,
7785 { 8112,-2563,-740,-3730,11784,2197,-941,2075,4933 } },
7786 { "Leica V-LUX 4", 15, 0xfff,
7787 { 8112,-2563,-740,-3730,11784,2197,-941,2075,4933 } },
7788 { "Panasonic DMC-FX150", 15, 0xfff,
7789 { 9082,-2907,-925,-6119,13377,3058,-1797,2641,5609 } },
7790 { "Panasonic DMC-G10", 0, 0,
7791 { 10113,-3400,-1114,-4765,12683,2317,-377,1437,6710 } },
7792 { "Panasonic DMC-G1", 15, 0xf94,
7793 { 8199,-2065,-1056,-8124,16156,2033,-2458,3022,7220 } },
7794 { "Panasonic DMC-G2", 15, 0xf3c,
7795 { 10113,-3400,-1114,-4765,12683,2317,-377,1437,6710 } },
7796 { "Panasonic DMC-G3", 15, 0xfff,
7797 { 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } },
7798 { "Panasonic DMC-G5", 15, 0xfff,
7799 { 7798,-2562,-740,-3879,11584,2613,-1055,2248,5434 } },
7800 { "Panasonic DMC-G6", 15, 0xfff,
7801 { 8294,-2891,-651,-3869,11590,2595,-1183,2267,5352 } },
7802 { "Panasonic DMC-G7", 15, 0xfff,
7803 { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } },
7804 { "Panasonic DMC-GF1", 15, 0xf92,
7805 { 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } },
7806 { "Panasonic DMC-GF2", 15, 0xfff,
7807 { 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } },
7808 { "Panasonic DMC-GF3", 15, 0xfff,
7809 { 9051,-2468,-1204,-5212,13276,2121,-1197,2510,6890 } },
7810 { "Panasonic DMC-GF5", 15, 0xfff,
7811 { 8228,-2945,-660,-3938,11792,2430,-1094,2278,5793 } },
7812 { "Panasonic DMC-GF6", 15, 0,
7813 { 8130,-2801,-946,-3520,11289,2552,-1314,2511,5791 } },
7814 { "Panasonic DMC-GF7", 15, 0,
7815 { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } },
7816 { "Panasonic DMC-GF8", 15, 0,
7817 { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } },
7818 { "Panasonic DMC-GH1", 15, 0xf92,
7819 { 6299,-1466,-532,-6535,13852,2969,-2331,3112,5984 } },
7820 { "Panasonic DMC-GH2", 15, 0xf95,
7821 { 7780,-2410,-806,-3913,11724,2484,-1018,2390,5298 } },
7822 { "Panasonic DMC-GH3", 15, 0,
7823 { 6559,-1752,-491,-3672,11407,2586,-962,1875,5130 } },
7824 { "Panasonic DMC-GH4", 15, 0,
7825 { 7122,-2108,-512,-3155,11201,2231,-541,1423,5045 } },
7826 { "Panasonic DMC-GM1", 15, 0,
7827 { 6770,-1895,-744,-5232,13145,2303,-1664,2691,5703 } },
7828 { "Panasonic DMC-GM5", 15, 0,
7829 { 8238,-3244,-679,-3921,11814,2384,-836,2022,5852 } },
7830 { "Panasonic DMC-GX1", 15, 0,
7831 { 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } },
7832 { "Panasonic DMC-GX7", 15, 0,
7833 { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } },
7834 { "Panasonic DMC-GX8", 15, 0,
7835 { 7564,-2263,-606,-3148,11239,2177,-540,1435,4853 } },
7836 { "Panasonic DMC-TZ1", 15, 0,
7837 { 7790,-2736,-755,-3452,11870,1769,-628,1647,4898 } },
7838 { "Panasonic DMC-ZS1", 15, 0,
7839 { 7790,-2736,-755,-3452,11870,1769,-628,1647,4898 } },
7840 { "Panasonic DMC-TZ6", 15, 0,
7841 { 8607,-2822,-808,-3755,11930,2049,-820,2060,5224 } },
7842 { "Panasonic DMC-ZS4", 15, 0,
7843 { 8607,-2822,-808,-3755,11930,2049,-820,2060,5224 } },
7844 { "Panasonic DMC-TZ7", 15, 0,
7845 { 8802,-3135,-789,-3151,11468,1904,-550,1745,4810 } },
7846 { "Panasonic DMC-ZS5", 15, 0,
7847 { 8802,-3135,-789,-3151,11468,1904,-550,1745,4810 } },
7848 { "Panasonic DMC-TZ8", 15, 0,
7849 { 8550,-2908,-842,-3195,11529,1881,-338,1603,4631 } },
7850 { "Panasonic DMC-ZS6", 15, 0,
7851 { 8550,-2908,-842,-3195,11529,1881,-338,1603,4631 } },
7852 { "Leica S (Typ 007)", 0, 0,
7853 { 6063,-2234,-231,-5210,13787,1500,-1043,2866,6997 } },
7854 { "Leica X", 0, 0, /* X and X-U, both (Typ 113) */
7855 { 7712,-2059,-653,-3882,11494,2726,-710,1332,5958 } },
7856 { "Leica Q (Typ 116)", 0, 0,
7857 { 11865,-4523,-1441,-5423,14458,935,-1587,2687,4830 } },
7858 { "Leica M (Typ 262)", 0, 0,
7859 { 6653,-1486,-611,-4221,13303,929,-881,2416,7226 } },
7860 { "Leica SL (Typ 601)", 0, 0,
7861 { 11865,-4523,-1441,-5423,14458,935,-1587,2687,4830} },
7862 { "Phase One H 20", 0, 0, /* DJC */
7863 { 1313,1855,-109,-6715,15908,808,-327,1840,6020 } },
7864 { "Phase One H 25", 0, 0,
7865 { 2905,732,-237,-8134,16626,1476,-3038,4253,7517 } },
7866 { "Phase One P 2", 0, 0,
7867 { 2905,732,-237,-8134,16626,1476,-3038,4253,7517 } },
7868 { "Phase One P 30", 0, 0,
7869 { 4516,-245,-37,-7020,14976,2173,-3206,4671,7087 } },
7870 { "Phase One P 45", 0, 0,
7871 { 5053,-24,-117,-5684,14076,1702,-2619,4492,5849 } },
7872 { "Phase One P40", 0, 0,
7873 { 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } },
7874 { "Phase One P65", 0, 0,
7875 { 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } },
7876 { "Photron BC2-HD", 0, 0, /* DJC */
7877 { 14603,-4122,-528,-1810,9794,2017,-297,2763,5936 } },
7878 { "Red One", 704, 0xffff, /* DJC */
7879 { 21014,-7891,-2613,-3056,12201,856,-2203,5125,8042 } },
7880 { "Ricoh GR II", 0, 0,
7881 { 4630,-834,-423,-4977,12805,2417,-638,1467,6115 } },
7883 { 3708,-543,-160,-5381,12254,3556,-1471,1929,8234 } },
7884 { "Samsung EX1", 0, 0x3e00,
7885 { 8898,-2498,-994,-3144,11328,2066,-760,1381,4576 } },
7886 { "Samsung EX2F", 0, 0x7ff,
7887 { 10648,-3897,-1055,-2022,10573,1668,-492,1611,4742 } },
7888 { "Samsung EK-GN120", 0, 0,
7889 { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } },
7890 { "Samsung NX mini", 0, 0,
7891 { 5222,-1196,-550,-6540,14649,2009,-1666,2819,5657 } },
7892 { "Samsung NX3300", 0, 0,
7893 { 8060,-2933,-761,-4504,12890,1762,-630,1489,5227 } },
7894 { "Samsung NX3000", 0, 0,
7895 { 8060,-2933,-761,-4504,12890,1762,-630,1489,5227 } },
7896 { "Samsung NX30", 0, 0, /* NX30, NX300, NX300M */
7897 { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } },
7898 { "Samsung NX2000", 0, 0,
7899 { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } },
7900 { "Samsung NX2", 0, 0xfff, /* NX20, NX200, NX210 */
7901 { 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } },
7902 { "Samsung NX1000", 0, 0,
7903 { 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } },
7904 { "Samsung NX1100", 0, 0,
7905 { 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } },
7906 { "Samsung NX11", 0, 0,
7907 { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } },
7908 { "Samsung NX10", 0, 0, /* also NX100 */
7909 { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } },
7910 { "Samsung NX500", 0, 0,
7911 { 10686,-4042,-1052,-3595,13238,276,-464,1259,5931 } },
7912 { "Samsung NX5", 0, 0,
7913 { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } },
7914 { "Samsung NX1", 0, 0,
7915 { 10686,-4042,-1052,-3595,13238,276,-464,1259,5931 } },
7916 { "Samsung WB2000", 0, 0xfff,
7917 { 12093,-3557,-1155,-1000,9534,1733,-22,1787,4576 } },
7918 { "Samsung GX-1", 0, 0,
7919 { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
7920 { "Samsung GX20", 0, 0, /* copied from Pentax K20D */
7921 { 9427,-2714,-868,-7493,16092,1373,-2199,3264,7180 } },
7922 { "Samsung S85", 0, 0, /* DJC */
7923 { 11885,-3968,-1473,-4214,12299,1916,-835,1655,5549 } },
7924 { "Sinar", 0, 0, /* DJC */
7925 { 16442,-2956,-2422,-2877,12128,750,-1136,6066,4559 } },
7926 { "Sony DSC-F828", 0, 0,
7927 { 7924,-1910,-777,-8226,15459,2998,-1517,2199,6818,-7242,11401,3481 } },
7928 { "Sony DSC-R1", 0, 0,
7929 { 8512,-2641,-694,-8042,15670,2526,-1821,2117,7414 } },
7930 { "Sony DSC-V3", 0, 0,
7931 { 7511,-2571,-692,-7894,15088,3060,-948,1111,8128 } },
7932 { "Sony DSC-RX100M", 0, 0, /* M2, M3, and M4 */
7933 { 6596,-2079,-562,-4782,13016,1933,-970,1581,5181 } },
7934 { "Sony DSC-RX100", 0, 0,
7935 { 8651,-2754,-1057,-3464,12207,1373,-568,1398,4434 } },
7936 { "Sony DSC-RX10", 0, 0, /* also RX10M2 */
7937 { 6679,-1825,-745,-5047,13256,1953,-1580,2422,5183 } },
7938 { "Sony DSC-RX1RM2", 0, 0,
7939 { 6629,-1900,-483,-4618,12349,2550,-622,1381,6514 } },
7940 { "Sony DSC-RX1", 0, 0,
7941 { 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } },
7942 { "Sony DSLR-A100", 0, 0xfeb,
7943 { 9437,-2811,-774,-8405,16215,2290,-710,596,7181 } },
7944 { "Sony DSLR-A290", 0, 0,
7945 { 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } },
7946 { "Sony DSLR-A2", 0, 0,
7947 { 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } },
7948 { "Sony DSLR-A300", 0, 0,
7949 { 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } },
7950 { "Sony DSLR-A330", 0, 0,
7951 { 9847,-3091,-929,-8485,16346,2225,-714,595,7103 } },
7952 { "Sony DSLR-A350", 0, 0xffc,
7953 { 6038,-1484,-578,-9146,16746,2513,-875,746,7217 } },
7954 { "Sony DSLR-A380", 0, 0,
7955 { 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } },
7956 { "Sony DSLR-A390", 0, 0,
7957 { 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } },
7958 { "Sony DSLR-A450", 0, 0xfeb,
7959 { 4950,-580,-103,-5228,12542,3029,-709,1435,7371 } },
7960 { "Sony DSLR-A580", 0, 0xfeb,
7961 { 5932,-1492,-411,-4813,12285,2856,-741,1524,6739 } },
7962 { "Sony DSLR-A500", 0, 0xfeb,
7963 { 6046,-1127,-278,-5574,13076,2786,-691,1419,7625 } },
7964 { "Sony DSLR-A5", 0, 0xfeb,
7965 { 4950,-580,-103,-5228,12542,3029,-709,1435,7371 } },
7966 { "Sony DSLR-A700", 0, 0,
7967 { 5775,-805,-359,-8574,16295,2391,-1943,2341,7249 } },
7968 { "Sony DSLR-A850", 0, 0,
7969 { 5413,-1162,-365,-5665,13098,2866,-608,1179,8440 } },
7970 { "Sony DSLR-A900", 0, 0,
7971 { 5209,-1072,-397,-8845,16120,2919,-1618,1803,8654 } },
7972 { "Sony ILCA-68", 0, 0,
7973 { 6435,-1903,-536,-4722,12449,2550,-663,1363,6517 } },
7974 { "Sony ILCA-77M2", 0, 0,
7975 { 5991,-1732,-443,-4100,11989,2381,-704,1467,5992 } },
7976 { "Sony ILCE-6300", 0, 0,
7977 { 5973,-1695,-419,-3826,11797,2293,-639,1398,5789 } },
7978 { "Sony ILCE-7M2", 0, 0,
7979 { 5271,-712,-347,-6153,13653,2763,-1601,2366,7242 } },
7980 { "Sony ILCE-7S", 0, 0, /* also ILCE-7SM2 */
7981 { 5838,-1430,-246,-3497,11477,2297,-748,1885,5778 } },
7982 { "Sony ILCE-7RM2", 0, 0,
7983 { 6629,-1900,-483,-4618,12349,2550,-622,1381,6514 } },
7984 { "Sony ILCE-7R", 0, 0,
7985 { 4913,-541,-202,-6130,13513,2906,-1564,2151,7183 } },
7986 { "Sony ILCE-7", 0, 0,
7987 { 5271,-712,-347,-6153,13653,2763,-1601,2366,7242 } },
7988 { "Sony ILCE", 0, 0, /* 3000, 5000, 5100, 6000, and QX1 */
7989 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
7990 { "Sony NEX-5N", 0, 0,
7991 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
7992 { "Sony NEX-5R", 0, 0,
7993 { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } },
7994 { "Sony NEX-5T", 0, 0,
7995 { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } },
7996 { "Sony NEX-3N", 0, 0,
7997 { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } },
7998 { "Sony NEX-3", 138, 0, /* DJC */
7999 { 6907,-1256,-645,-4940,12621,2320,-1710,2581,6230 } },
8000 { "Sony NEX-5", 116, 0, /* DJC */
8001 { 6807,-1350,-342,-4216,11649,2567,-1089,2001,6420 } },
8002 { "Sony NEX-3", 0, 0, /* Adobe */
8003 { 6549,-1550,-436,-4880,12435,2753,-854,1868,6976 } },
8004 { "Sony NEX-5", 0, 0, /* Adobe */
8005 { 6549,-1550,-436,-4880,12435,2753,-854,1868,6976 } },
8006 { "Sony NEX-6", 0, 0,
8007 { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } },
8008 { "Sony NEX-7", 0, 0,
8009 { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } },
8010 { "Sony NEX", 0, 0, /* NEX-C3, NEX-F3 */
8011 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
8012 { "Sony SLT-A33", 0, 0,
8013 { 6069,-1221,-366,-5221,12779,2734,-1024,2066,6834 } },
8014 { "Sony SLT-A35", 0, 0,
8015 { 5986,-1618,-415,-4557,11820,3120,-681,1404,6971 } },
8016 { "Sony SLT-A37", 0, 0,
8017 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
8018 { "Sony SLT-A55", 0, 0,
8019 { 5932,-1492,-411,-4813,12285,2856,-741,1524,6739 } },
8020 { "Sony SLT-A57", 0, 0,
8021 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
8022 { "Sony SLT-A58", 0, 0,
8023 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
8024 { "Sony SLT-A65", 0, 0,
8025 { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } },
8026 { "Sony SLT-A77", 0, 0,
8027 { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } },
8028 { "Sony SLT-A99", 0, 0,
8029 { 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } },
8031 double cam_xyz[4][3];
8035 sprintf (name, "%s %s", make, model);
8036 for (i=0; i < sizeof table / sizeof *table; i++)
8037 if (!strncmp (name, table[i].prefix, strlen(table[i].prefix))) {
8038 if (table[i].black) black = (ushort) table[i].black;
8039 if (table[i].maximum) maximum = (ushort) table[i].maximum;
8040 if (table[i].trans[0]) {
8041 for (raw_color = j=0; j < 12; j++)
8042 ((double *)cam_xyz)[j] = table[i].trans[j] / 10000.0;
8043 cam_xyz_coeff (rgb_cam, cam_xyz);
8049 void CLASS simple_coeff (int index)
8051 static const float table[][12] = {
8052 /* index 0 -- all Foveon cameras */
8053 { 1.4032,-0.2231,-0.1016,-0.5263,1.4816,0.017,-0.0112,0.0183,0.9113 },
8054 /* index 1 -- Kodak DC20 and DC25 */
8055 { 2.25,0.75,-1.75,-0.25,-0.25,0.75,0.75,-0.25,-0.25,-1.75,0.75,2.25 },
8056 /* index 2 -- Logitech Fotoman Pixtura */
8057 { 1.893,-0.418,-0.476,-0.495,1.773,-0.278,-1.017,-0.655,2.672 },
8058 /* index 3 -- Nikon E880, E900, and E990 */
8059 { -1.936280, 1.800443, -1.448486, 2.584324,
8060 1.405365, -0.524955, -0.289090, 0.408680,
8061 -1.204965, 1.082304, 2.941367, -1.818705 }
8065 for (raw_color = i=0; i < 3; i++)
8066 FORCC rgb_cam[i][c] = table[index][i*colors+c];
8069 short CLASS guess_byte_order (int words)
8073 double diff, sum[2] = {0,0};
8075 fread (test[0], 2, 2, ifp);
8076 for (words-=2; words--; ) {
8077 fread (test[t], 2, 1, ifp);
8078 for (msb=0; msb < 2; msb++) {
8079 diff = (test[t^2][msb] << 8 | test[t^2][!msb])
8080 - (test[t ][msb] << 8 | test[t ][!msb]);
8081 sum[msb] += diff*diff;
8085 return sum[0] < sum[1] ? 0x4d4d : 0x4949;
8088 float CLASS find_green (int bps, int bite, int off0, int off1)
8091 int vbits, col, i, c;
8092 ushort img[2][2064];
8096 fseek (ifp, c ? off1:off0, SEEK_SET);
8097 for (vbits=col=0; col < width; col++) {
8098 for (vbits -= bps; vbits < 0; vbits += bite) {
8100 for (i=0; i < bite; i+=8)
8101 bitbuf |= (unsigned) (fgetc(ifp) << i);
8103 img[c][col] = bitbuf << (64-bps-vbits) >> (64-bps);
8107 sum[ c & 1] += ABS(img[0][c]-img[1][c+1]);
8108 sum[~c & 1] += ABS(img[1][c]-img[0][c+1]);
8110 return 100 * log(sum[0]/sum[1]);
8114 Identify which camera created this file, and set global variables
8117 void CLASS identify()
8119 static const short pana[][6] = {
8120 { 3130, 1743, 4, 0, -6, 0 },
8121 { 3130, 2055, 4, 0, -6, 0 },
8122 { 3130, 2319, 4, 0, -6, 0 },
8123 { 3170, 2103, 18, 0,-42, 20 },
8124 { 3170, 2367, 18, 13,-42,-21 },
8125 { 3177, 2367, 0, 0, -1, 0 },
8126 { 3304, 2458, 0, 0, -1, 0 },
8127 { 3330, 2463, 9, 0, -5, 0 },
8128 { 3330, 2479, 9, 0,-17, 4 },
8129 { 3370, 1899, 15, 0,-44, 20 },
8130 { 3370, 2235, 15, 0,-44, 20 },
8131 { 3370, 2511, 15, 10,-44,-21 },
8132 { 3690, 2751, 3, 0, -8, -3 },
8133 { 3710, 2751, 0, 0, -3, 0 },
8134 { 3724, 2450, 0, 0, 0, -2 },
8135 { 3770, 2487, 17, 0,-44, 19 },
8136 { 3770, 2799, 17, 15,-44,-19 },
8137 { 3880, 2170, 6, 0, -6, 0 },
8138 { 4060, 3018, 0, 0, 0, -2 },
8139 { 4290, 2391, 3, 0, -8, -1 },
8140 { 4330, 2439, 17, 15,-44,-19 },
8141 { 4508, 2962, 0, 0, -3, -4 },
8142 { 4508, 3330, 0, 0, -3, -6 },
8144 static const ushort canon[][11] = {
8145 { 1944, 1416, 0, 0, 48, 0 },
8146 { 2144, 1560, 4, 8, 52, 2, 0, 0, 0, 25 },
8147 { 2224, 1456, 48, 6, 0, 2 },
8148 { 2376, 1728, 12, 6, 52, 2 },
8149 { 2672, 1968, 12, 6, 44, 2 },
8150 { 3152, 2068, 64, 12, 0, 0, 16 },
8151 { 3160, 2344, 44, 12, 4, 4 },
8152 { 3344, 2484, 4, 6, 52, 6 },
8153 { 3516, 2328, 42, 14, 0, 0 },
8154 { 3596, 2360, 74, 12, 0, 0 },
8155 { 3744, 2784, 52, 12, 8, 12 },
8156 { 3944, 2622, 30, 18, 6, 2 },
8157 { 3948, 2622, 42, 18, 0, 2 },
8158 { 3984, 2622, 76, 20, 0, 2, 14 },
8159 { 4104, 3048, 48, 12, 24, 12 },
8160 { 4116, 2178, 4, 2, 0, 0 },
8161 { 4152, 2772, 192, 12, 0, 0 },
8162 { 4160, 3124, 104, 11, 8, 65 },
8163 { 4176, 3062, 96, 17, 8, 0, 0, 16, 0, 7, 0x49 },
8164 { 4192, 3062, 96, 17, 24, 0, 0, 16, 0, 0, 0x49 },
8165 { 4312, 2876, 22, 18, 0, 2 },
8166 { 4352, 2874, 62, 18, 0, 0 },
8167 { 4476, 2954, 90, 34, 0, 0 },
8168 { 4480, 3348, 12, 10, 36, 12, 0, 0, 0, 18, 0x49 },
8169 { 4480, 3366, 80, 50, 0, 0 },
8170 { 4496, 3366, 80, 50, 12, 0 },
8171 { 4768, 3516, 96, 16, 0, 0, 0, 16 },
8172 { 4832, 3204, 62, 26, 0, 0 },
8173 { 4832, 3228, 62, 51, 0, 0 },
8174 { 5108, 3349, 98, 13, 0, 0 },
8175 { 5120, 3318, 142, 45, 62, 0 },
8176 { 5280, 3528, 72, 52, 0, 0 },
8177 { 5344, 3516, 142, 51, 0, 0 },
8178 { 5344, 3584, 126,100, 0, 2 },
8179 { 5360, 3516, 158, 51, 0, 0 },
8180 { 5568, 3708, 72, 38, 0, 0 },
8181 { 5632, 3710, 96, 17, 0, 0, 0, 16, 0, 0, 0x49 },
8182 { 5712, 3774, 62, 20, 10, 2 },
8183 { 5792, 3804, 158, 51, 0, 0 },
8184 { 5920, 3950, 122, 80, 2, 0 },
8185 { 6096, 4056, 72, 34, 0, 0 },
8186 { 6288, 4056, 264, 34, 0, 0 },
8187 { 8896, 5920, 160, 64, 0, 0 },
8189 static const struct {
8193 { 0x168, "EOS 10D" }, { 0x001, "EOS-1D" },
8194 { 0x175, "EOS 20D" }, { 0x174, "EOS-1D Mark II" },
8195 { 0x234, "EOS 30D" }, { 0x232, "EOS-1D Mark II N" },
8196 { 0x190, "EOS 40D" }, { 0x169, "EOS-1D Mark III" },
8197 { 0x261, "EOS 50D" }, { 0x281, "EOS-1D Mark IV" },
8198 { 0x287, "EOS 60D" }, { 0x167, "EOS-1DS" },
8199 { 0x325, "EOS 70D" },
8200 { 0x350, "EOS 80D" }, { 0x328, "EOS-1D X Mark II" },
8201 { 0x170, "EOS 300D" }, { 0x188, "EOS-1Ds Mark II" },
8202 { 0x176, "EOS 450D" }, { 0x215, "EOS-1Ds Mark III" },
8203 { 0x189, "EOS 350D" }, { 0x324, "EOS-1D C" },
8204 { 0x236, "EOS 400D" }, { 0x269, "EOS-1D X" },
8205 { 0x252, "EOS 500D" }, { 0x213, "EOS 5D" },
8206 { 0x270, "EOS 550D" }, { 0x218, "EOS 5D Mark II" },
8207 { 0x286, "EOS 600D" }, { 0x285, "EOS 5D Mark III" },
8208 { 0x301, "EOS 650D" }, { 0x302, "EOS 6D" },
8209 { 0x326, "EOS 700D" }, { 0x250, "EOS 7D" },
8210 { 0x393, "EOS 750D" }, { 0x289, "EOS 7D Mark II" },
8211 { 0x347, "EOS 760D" },
8212 { 0x254, "EOS 1000D" },
8213 { 0x288, "EOS 1100D" },
8214 { 0x327, "EOS 1200D" }, { 0x382, "Canon EOS 5DS" },
8215 { 0x404, "EOS 1300D" }, { 0x401, "Canon EOS 5DS R" },
8216 { 0x346, "EOS 100D" },
8218 { 0x002, "DSC-R1" }, { 0x100, "DSLR-A100" },
8219 { 0x101, "DSLR-A900" }, { 0x102, "DSLR-A700" },
8220 { 0x103, "DSLR-A200" }, { 0x104, "DSLR-A350" },
8221 { 0x105, "DSLR-A300" }, { 0x108, "DSLR-A330" },
8222 { 0x109, "DSLR-A230" }, { 0x10a, "DSLR-A290" },
8223 { 0x10d, "DSLR-A850" }, { 0x111, "DSLR-A550" },
8224 { 0x112, "DSLR-A500" }, { 0x113, "DSLR-A450" },
8225 { 0x116, "NEX-5" }, { 0x117, "NEX-3" },
8226 { 0x118, "SLT-A33" }, { 0x119, "SLT-A55V" },
8227 { 0x11a, "DSLR-A560" }, { 0x11b, "DSLR-A580" },
8228 { 0x11c, "NEX-C3" }, { 0x11d, "SLT-A35" },
8229 { 0x11e, "SLT-A65V" }, { 0x11f, "SLT-A77V" },
8230 { 0x120, "NEX-5N" }, { 0x121, "NEX-7" },
8231 { 0x123, "SLT-A37" }, { 0x124, "SLT-A57" },
8232 { 0x125, "NEX-F3" }, { 0x126, "SLT-A99V" },
8233 { 0x127, "NEX-6" }, { 0x128, "NEX-5R" },
8234 { 0x129, "DSC-RX100" }, { 0x12a, "DSC-RX1" },
8235 { 0x12e, "ILCE-3000" }, { 0x12f, "SLT-A58" },
8236 { 0x131, "NEX-3N" }, { 0x132, "ILCE-7" },
8237 { 0x133, "NEX-5T" }, { 0x134, "DSC-RX100M2" },
8238 { 0x135, "DSC-RX10" }, { 0x136, "DSC-RX1R" },
8239 { 0x137, "ILCE-7R" }, { 0x138, "ILCE-6000" },
8240 { 0x139, "ILCE-5000" }, { 0x13d, "DSC-RX100M3" },
8241 { 0x13e, "ILCE-7S" }, { 0x13f, "ILCA-77M2" },
8242 { 0x153, "ILCE-5100" }, { 0x154, "ILCE-7M2" },
8243 { 0x155, "DSC-RX100M4" },{ 0x156, "DSC-RX10M2" },
8244 { 0x158, "DSC-RX1RM2" }, { 0x15a, "ILCE-QX1" },
8245 { 0x15b, "ILCE-7RM2" }, { 0x15e, "ILCE-7SM2" },
8246 { 0x161, "ILCA-68" }, { 0x165, "ILCE-6300" },
8248 static const struct {
8251 uchar lm, tm, rm, bm, lf, cf, max, flags;
8252 char make[10], model[20];
8255 { 786432,1024, 768, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-080C" },
8256 { 1447680,1392,1040, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-145C" },
8257 { 1920000,1600,1200, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-201C" },
8258 { 5067304,2588,1958, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-510C" },
8259 { 5067316,2588,1958, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-510C",12 },
8260 { 10134608,2588,1958, 0, 0, 0, 0, 9,0x94,0,0,"AVT","F-510C" },
8261 { 10134620,2588,1958, 0, 0, 0, 0, 9,0x94,0,0,"AVT","F-510C",12 },
8262 { 16157136,3272,2469, 0, 0, 0, 0, 9,0x94,0,0,"AVT","F-810C" },
8263 { 15980544,3264,2448, 0, 0, 0, 0, 8,0x61,0,1,"AgfaPhoto","DC-833m" },
8264 { 9631728,2532,1902, 0, 0, 0, 0,96,0x61,0,0,"Alcatel","5035D" },
8265 { 2868726,1384,1036, 0, 0, 0, 0,64,0x49,0,8,"Baumer","TXG14",1078 },
8266 { 5298000,2400,1766,12,12,44, 2,40,0x94,0,2,"Canon","PowerShot SD300" },
8267 { 6553440,2664,1968, 4, 4,44, 4,40,0x94,0,2,"Canon","PowerShot A460" },
8268 { 6573120,2672,1968,12, 8,44, 0,40,0x94,0,2,"Canon","PowerShot A610" },
8269 { 6653280,2672,1992,10, 6,42, 2,40,0x94,0,2,"Canon","PowerShot A530" },
8270 { 7710960,2888,2136,44, 8, 4, 0,40,0x94,0,2,"Canon","PowerShot S3 IS" },
8271 { 9219600,3152,2340,36,12, 4, 0,40,0x94,0,2,"Canon","PowerShot A620" },
8272 { 9243240,3152,2346,12, 7,44,13,40,0x49,0,2,"Canon","PowerShot A470" },
8273 { 10341600,3336,2480, 6, 5,32, 3,40,0x94,0,2,"Canon","PowerShot A720 IS" },
8274 { 10383120,3344,2484,12, 6,44, 6,40,0x94,0,2,"Canon","PowerShot A630" },
8275 { 12945240,3736,2772,12, 6,52, 6,40,0x94,0,2,"Canon","PowerShot A640" },
8276 { 15636240,4104,3048,48,12,24,12,40,0x94,0,2,"Canon","PowerShot A650" },
8277 { 15467760,3720,2772, 6,12,30, 0,40,0x94,0,2,"Canon","PowerShot SX110 IS" },
8278 { 15534576,3728,2778,12, 9,44, 9,40,0x94,0,2,"Canon","PowerShot SX120 IS" },
8279 { 18653760,4080,3048,24,12,24,12,40,0x94,0,2,"Canon","PowerShot SX20 IS" },
8280 { 19131120,4168,3060,92,16, 4, 1,40,0x94,0,2,"Canon","PowerShot SX220 HS" },
8281 { 21936096,4464,3276,25,10,73,12,40,0x16,0,2,"Canon","PowerShot SX30 IS" },
8282 { 24724224,4704,3504, 8,16,56, 8,40,0x94,0,2,"Canon","PowerShot A3300 IS" },
8283 { 30858240,5248,3920, 8,16,56,16,40,0x94,0,2,"Canon","IXUS 160" },
8284 { 1976352,1632,1211, 0, 2, 0, 1, 0,0x94,0,1,"Casio","QV-2000UX" },
8285 { 3217760,2080,1547, 0, 0,10, 1, 0,0x94,0,1,"Casio","QV-3*00EX" },
8286 { 6218368,2585,1924, 0, 0, 9, 0, 0,0x94,0,1,"Casio","QV-5700" },
8287 { 7816704,2867,2181, 0, 0,34,36, 0,0x16,0,1,"Casio","EX-Z60" },
8288 { 2937856,1621,1208, 0, 0, 1, 0, 0,0x94,7,13,"Casio","EX-S20" },
8289 { 4948608,2090,1578, 0, 0,32,34, 0,0x94,7,1,"Casio","EX-S100" },
8290 { 6054400,2346,1720, 2, 0,32, 0, 0,0x94,7,1,"Casio","QV-R41" },
8291 { 7426656,2568,1928, 0, 0, 0, 0, 0,0x94,0,1,"Casio","EX-P505" },
8292 { 7530816,2602,1929, 0, 0,22, 0, 0,0x94,7,1,"Casio","QV-R51" },
8293 { 7542528,2602,1932, 0, 0,32, 0, 0,0x94,7,1,"Casio","EX-Z50" },
8294 { 7562048,2602,1937, 0, 0,25, 0, 0,0x16,7,1,"Casio","EX-Z500" },
8295 { 7753344,2602,1986, 0, 0,32,26, 0,0x94,7,1,"Casio","EX-Z55" },
8296 { 9313536,2858,2172, 0, 0,14,30, 0,0x94,7,1,"Casio","EX-P600" },
8297 { 10834368,3114,2319, 0, 0,27, 0, 0,0x94,0,1,"Casio","EX-Z750" },
8298 { 10843712,3114,2321, 0, 0,25, 0, 0,0x94,0,1,"Casio","EX-Z75" },
8299 { 10979200,3114,2350, 0, 0,32,32, 0,0x94,7,1,"Casio","EX-P700" },
8300 { 12310144,3285,2498, 0, 0, 6,30, 0,0x94,0,1,"Casio","EX-Z850" },
8301 { 12489984,3328,2502, 0, 0,47,35, 0,0x94,0,1,"Casio","EX-Z8" },
8302 { 15499264,3754,2752, 0, 0,82, 0, 0,0x94,0,1,"Casio","EX-Z1050" },
8303 { 18702336,4096,3044, 0, 0,24, 0,80,0x94,7,1,"Casio","EX-ZR100" },
8304 { 7684000,2260,1700, 0, 0, 0, 0,13,0x94,0,1,"Casio","QV-4000" },
8305 { 787456,1024, 769, 0, 1, 0, 0, 0,0x49,0,0,"Creative","PC-CAM 600" },
8306 { 28829184,4384,3288, 0, 0, 0, 0,36,0x61,0,0,"DJI" },
8307 { 15151104,4608,3288, 0, 0, 0, 0, 0,0x94,0,0,"Matrix" },
8308 { 3840000,1600,1200, 0, 0, 0, 0,65,0x49,0,0,"Foculus","531C" },
8309 { 307200, 640, 480, 0, 0, 0, 0, 0,0x94,0,0,"Generic" },
8310 { 62464, 256, 244, 1, 1, 6, 1, 0,0x8d,0,0,"Kodak","DC20" },
8311 { 124928, 512, 244, 1, 1,10, 1, 0,0x8d,0,0,"Kodak","DC20" },
8312 { 1652736,1536,1076, 0,52, 0, 0, 0,0x61,0,0,"Kodak","DCS200" },
8313 { 4159302,2338,1779, 1,33, 1, 2, 0,0x94,0,0,"Kodak","C330" },
8314 { 4162462,2338,1779, 1,33, 1, 2, 0,0x94,0,0,"Kodak","C330",3160 },
8315 { 2247168,1232, 912, 0, 0,16, 0, 0,0x00,0,0,"Kodak","C330" },
8316 { 3370752,1232, 912, 0, 0,16, 0, 0,0x00,0,0,"Kodak","C330" },
8317 { 6163328,2864,2152, 0, 0, 0, 0, 0,0x94,0,0,"Kodak","C603" },
8318 { 6166488,2864,2152, 0, 0, 0, 0, 0,0x94,0,0,"Kodak","C603",3160 },
8319 { 460800, 640, 480, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","C603" },
8320 { 9116448,2848,2134, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","C603" },
8321 { 12241200,4040,3030, 2, 0, 0,13, 0,0x49,0,0,"Kodak","12MP" },
8322 { 12272756,4040,3030, 2, 0, 0,13, 0,0x49,0,0,"Kodak","12MP",31556 },
8323 { 18000000,4000,3000, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","12MP" },
8324 { 614400, 640, 480, 0, 3, 0, 0,64,0x94,0,0,"Kodak","KAI-0340" },
8325 { 15360000,3200,2400, 0, 0, 0, 0,96,0x16,0,0,"Lenovo","A820" },
8326 { 3884928,1608,1207, 0, 0, 0, 0,96,0x16,0,0,"Micron","2010",3212 },
8327 { 1138688,1534, 986, 0, 0, 0, 0, 0,0x61,0,0,"Minolta","RD175",513 },
8328 { 1581060,1305, 969, 0, 0,18, 6, 6,0x1e,4,1,"Nikon","E900" },
8329 { 2465792,1638,1204, 0, 0,22, 1, 6,0x4b,5,1,"Nikon","E950" },
8330 { 2940928,1616,1213, 0, 0, 0, 7,30,0x94,0,1,"Nikon","E2100" },
8331 { 4771840,2064,1541, 0, 0, 0, 1, 6,0xe1,0,1,"Nikon","E990" },
8332 { 4775936,2064,1542, 0, 0, 0, 0,30,0x94,0,1,"Nikon","E3700" },
8333 { 5865472,2288,1709, 0, 0, 0, 1, 6,0xb4,0,1,"Nikon","E4500" },
8334 { 5869568,2288,1710, 0, 0, 0, 0, 6,0x16,0,1,"Nikon","E4300" },
8335 { 7438336,2576,1925, 0, 0, 0, 1, 6,0xb4,0,1,"Nikon","E5000" },
8336 { 8998912,2832,2118, 0, 0, 0, 0,30,0x94,7,1,"Nikon","COOLPIX S6" },
8337 { 5939200,2304,1718, 0, 0, 0, 0,30,0x16,0,0,"Olympus","C770UZ" },
8338 { 3178560,2064,1540, 0, 0, 0, 0, 0,0x94,0,1,"Pentax","Optio S" },
8339 { 4841984,2090,1544, 0, 0,22, 0, 0,0x94,7,1,"Pentax","Optio S" },
8340 { 6114240,2346,1737, 0, 0,22, 0, 0,0x94,7,1,"Pentax","Optio S4" },
8341 { 10702848,3072,2322, 0, 0, 0,21,30,0x94,0,1,"Pentax","Optio 750Z" },
8342 { 4147200,1920,1080, 0, 0, 0, 0, 0,0x49,0,0,"Photron","BC2-HD" },
8343 { 4151666,1920,1080, 0, 0, 0, 0, 0,0x49,0,0,"Photron","BC2-HD",8 },
8344 { 13248000,2208,3000, 0, 0, 0, 0,13,0x61,0,0,"Pixelink","A782" },
8345 { 6291456,2048,1536, 0, 0, 0, 0,96,0x61,0,0,"RoverShot","3320AF" },
8346 { 311696, 644, 484, 0, 0, 0, 0, 0,0x16,0,8,"ST Micro","STV680 VGA" },
8347 { 16098048,3288,2448, 0, 0,24, 0, 9,0x94,0,1,"Samsung","S85" },
8348 { 16215552,3312,2448, 0, 0,48, 0, 9,0x94,0,1,"Samsung","S85" },
8349 { 20487168,3648,2808, 0, 0, 0, 0,13,0x94,5,1,"Samsung","WB550" },
8350 { 24000000,4000,3000, 0, 0, 0, 0,13,0x94,5,1,"Samsung","WB550" },
8351 { 12582980,3072,2048, 0, 0, 0, 0,33,0x61,0,0,"Sinar","",68 },
8352 { 33292868,4080,4080, 0, 0, 0, 0,33,0x61,0,0,"Sinar","",68 },
8353 { 44390468,4080,5440, 0, 0, 0, 0,33,0x61,0,0,"Sinar","",68 },
8354 { 1409024,1376,1024, 0, 0, 1, 0, 0,0x49,0,0,"Sony","XCD-SX910CR" },
8355 { 2818048,1376,1024, 0, 0, 1, 0,97,0x49,0,0,"Sony","XCD-SX910CR" },
8357 static const char *corp[] =
8358 { "AgfaPhoto", "Canon", "Casio", "Epson", "Fujifilm",
8359 "Mamiya", "Minolta", "Motorola", "Kodak", "Konica", "Leica",
8360 "Nikon", "Nokia", "Olympus", "Ricoh", "Pentax", "Phase One",
8361 "Samsung", "Sigma", "Sinar", "Sony" };
8363 int hlen, flen, fsize, zero_fsize=1, i, c;
8366 tiff_flip = flip = filters = UINT_MAX; /* unknown */
8367 raw_height = raw_width = fuji_width = fuji_layout = cr2_slice[0] = 0;
8368 maximum = height = width = top_margin = left_margin = 0;
8369 cdesc[0] = desc[0] = artist[0] = make[0] = model[0] = model2[0] = 0;
8370 iso_speed = shutter = aperture = focal_len = unique_id = 0;
8372 memset (tiff_ifd, 0, sizeof tiff_ifd);
8373 memset (gpsdata, 0, sizeof gpsdata);
8374 memset (cblack, 0, sizeof cblack);
8375 memset (white, 0, sizeof white);
8376 memset (mask, 0, sizeof mask);
8377 thumb_offset = thumb_length = thumb_width = thumb_height = 0;
8378 load_raw = thumb_load_raw = 0;
8379 write_thumb = &CLASS jpeg_thumb;
8380 data_offset = meta_offset = meta_length = tiff_bps = tiff_compress = 0;
8381 kodak_cbpp = zero_after_ff = dng_version = load_flags = 0;
8382 timestamp = shot_order = tiff_samples = black = is_foveon = 0;
8383 mix_green = profile_length = data_error = zero_is_bad = 0;
8384 pixel_aspect = is_raw = raw_color = 1;
8385 tile_width = tile_length = 0;
8386 for (i=0; i < 4; i++) {
8387 cam_mul[i] = i == 1;
8389 FORC3 cmatrix[c][i] = 0;
8390 FORC3 rgb_cam[c][i] = c == i;
8393 for (i=0; i < 0x10000; i++) curve[i] = i;
8397 fseek (ifp, 0, SEEK_SET);
8398 fread (head, 1, 32, ifp);
8399 fseek (ifp, 0, SEEK_END);
8400 flen = fsize = ftell(ifp);
8401 if ((cp = (char *) memmem (head, 32, "MMMM", 4)) ||
8402 (cp = (char *) memmem (head, 32, "IIII", 4))) {
8403 parse_phase_one (cp-head);
8404 if (cp-head && parse_tiff(0)) apply_tiff();
8405 } else if (order == 0x4949 || order == 0x4d4d) {
8406 if (!memcmp (head+6,"HEAPCCDR",8)) {
8408 parse_ciff (hlen, flen-hlen, 0);
8409 load_raw = &CLASS canon_load_raw;
8410 } else if (parse_tiff(0)) apply_tiff();
8411 } else if (!memcmp (head,"\xff\xd8\xff\xe1",4) &&
8412 !memcmp (head+6,"Exif",4)) {
8413 fseek (ifp, 4, SEEK_SET);
8414 data_offset = 4 + get2();
8415 fseek (ifp, data_offset, SEEK_SET);
8416 if (fgetc(ifp) != 0xff)
8419 } else if (!memcmp (head+25,"ARECOYK",7)) {
8420 strcpy (make, "Contax");
8421 strcpy (model,"N Digital");
8422 fseek (ifp, 33, SEEK_SET);
8424 fseek (ifp, 60, SEEK_SET);
8425 FORC4 cam_mul[c ^ (c >> 1)] = get4();
8426 } else if (!strcmp (head, "PXN")) {
8427 strcpy (make, "Logitech");
8428 strcpy (model,"Fotoman Pixtura");
8429 } else if (!strcmp (head, "qktk")) {
8430 strcpy (make, "Apple");
8431 strcpy (model,"QuickTake 100");
8432 load_raw = &CLASS quicktake_100_load_raw;
8433 } else if (!strcmp (head, "qktn")) {
8434 strcpy (make, "Apple");
8435 strcpy (model,"QuickTake 150");
8436 load_raw = &CLASS kodak_radc_load_raw;
8437 } else if (!memcmp (head,"FUJIFILM",8)) {
8438 fseek (ifp, 84, SEEK_SET);
8439 thumb_offset = get4();
8440 thumb_length = get4();
8441 fseek (ifp, 92, SEEK_SET);
8442 parse_fuji (get4());
8443 if (thumb_offset > 120) {
8444 fseek (ifp, 120, SEEK_SET);
8445 is_raw += (i = get4()) && 1;
8446 if (is_raw == 2 && shot_select)
8449 load_raw = &CLASS unpacked_load_raw;
8450 fseek (ifp, 100+28*(shot_select > 0), SEEK_SET);
8451 parse_tiff (data_offset = get4());
8452 parse_tiff (thumb_offset+12);
8454 } else if (!memcmp (head,"RIFF",4)) {
8455 fseek (ifp, 0, SEEK_SET);
8457 } else if (!memcmp (head+4,"ftypqt ",9)) {
8458 fseek (ifp, 0, SEEK_SET);
8461 } else if (!memcmp (head,"\0\001\0\001\0@",6)) {
8462 fseek (ifp, 6, SEEK_SET);
8463 fread (make, 1, 8, ifp);
8464 fread (model, 1, 8, ifp);
8465 fread (model2, 1, 16, ifp);
8466 data_offset = get2();
8469 raw_height = get2();
8470 load_raw = &CLASS nokia_load_raw;
8471 filters = 0x61616161;
8472 } else if (!memcmp (head,"NOKIARAW",8)) {
8473 strcpy (make, "NOKIA");
8475 fseek (ifp, 300, SEEK_SET);
8476 data_offset = get4();
8480 switch (tiff_bps = i*8 / (width * height)) {
8481 case 8: load_raw = &CLASS eight_bit_load_raw; break;
8482 case 10: load_raw = &CLASS nokia_load_raw;
8484 raw_height = height + (top_margin = i / (width * tiff_bps/8) - height);
8486 filters = 0x61616161;
8487 } else if (!memcmp (head,"ARRI",4)) {
8489 fseek (ifp, 20, SEEK_SET);
8492 strcpy (make, "ARRI");
8493 fseek (ifp, 668, SEEK_SET);
8494 fread (model, 1, 64, ifp);
8496 load_raw = &CLASS packed_load_raw;
8498 filters = 0x61616161;
8499 } else if (!memcmp (head,"XPDS",4)) {
8501 fseek (ifp, 0x800, SEEK_SET);
8502 fread (make, 1, 41, ifp);
8503 raw_height = get2();
8505 fseek (ifp, 56, SEEK_CUR);
8506 fread (model, 1, 30, ifp);
8507 data_offset = 0x10000;
8508 load_raw = &CLASS canon_rmf_load_raw;
8509 gamma_curve (0, 12.25, 1, 1023);
8510 } else if (!memcmp (head+4,"RED1",4)) {
8511 strcpy (make, "Red");
8512 strcpy (model,"One");
8514 load_raw = &CLASS redcine_load_raw;
8515 gamma_curve (1/2.4, 12.92, 1, 4095);
8516 filters = 0x49494949;
8517 } else if (!memcmp (head,"DSC-Image",9))
8519 else if (!memcmp (head,"PWAD",4))
8521 else if (!memcmp (head,"\0MRM",4))
8523 else if (!memcmp (head,"FOVb",4))
8525 else if (!memcmp (head,"CI",2))
8528 for (zero_fsize=i=0; i < sizeof table / sizeof *table; i++)
8529 if (fsize == table[i].fsize) {
8530 strcpy (make, table[i].make );
8531 strcpy (model, table[i].model);
8532 flip = table[i].flags >> 2;
8533 zero_is_bad = table[i].flags & 2;
8534 if (table[i].flags & 1)
8535 parse_external_jpeg();
8536 data_offset = table[i].offset;
8537 raw_width = table[i].rw;
8538 raw_height = table[i].rh;
8539 left_margin = table[i].lm;
8540 top_margin = table[i].tm;
8541 width = raw_width - left_margin - table[i].rm;
8542 height = raw_height - top_margin - table[i].bm;
8543 filters = 0x1010101 * table[i].cf;
8544 colors = 4 - !((filters & filters >> 1) & 0x5555);
8545 load_flags = table[i].lf;
8546 switch (tiff_bps = (fsize-data_offset)*8 / (raw_width*raw_height)) {
8548 load_raw = &CLASS minolta_rd175_load_raw; break;
8550 load_raw = &CLASS eight_bit_load_raw; break;
8553 load_raw = &CLASS packed_load_raw; break;
8555 order = 0x4949 | 0x404 * (load_flags & 1);
8556 tiff_bps -= load_flags >> 4;
8557 tiff_bps -= load_flags = load_flags >> 1 & 7;
8558 load_raw = &CLASS unpacked_load_raw;
8560 maximum = (1 << tiff_bps) - (1 << table[i].max);
8562 if (zero_fsize) fsize = 0;
8563 if (make[0] == 0) parse_smal (0, flen);
8566 if (!(strncmp(model,"ov",2) && strncmp(model,"RP_OV",5)) &&
8567 !fseek (ifp, -6404096, SEEK_END) &&
8568 fread (head, 1, 32, ifp) && !strcmp(head,"BRCMn")) {
8569 strcpy (make, "OmniVision");
8570 data_offset = ftell(ifp) + 0x8000-32;
8573 load_raw = &CLASS nokia_load_raw;
8574 filters = 0x16161616;
8578 for (i=0; i < sizeof corp / sizeof *corp; i++)
8579 if (strcasestr (make, corp[i])) /* Simplify company names */
8580 strcpy (make, corp[i]);
8581 if ((!strcmp(make,"Kodak") || !strcmp(make,"Leica")) &&
8582 ((cp = strcasestr(model," DIGITAL CAMERA")) ||
8583 (cp = strstr(model,"FILE VERSION"))))
8585 if (!strncasecmp(model,"PENTAX",6))
8586 strcpy (make, "Pentax");
8587 cp = make + strlen(make); /* Remove trailing spaces */
8588 while (*--cp == ' ') *cp = 0;
8589 cp = model + strlen(model);
8590 while (*--cp == ' ') *cp = 0;
8591 i = strlen(make); /* Remove make from model */
8592 if (!strncasecmp (model, make, i) && model[i++] == ' ')
8593 memmove (model, model+i, 64-i);
8594 if (!strncmp (model,"FinePix ",8))
8595 strcpy (model, model+8);
8596 if (!strncmp (model,"Digital Camera ",15))
8597 strcpy (model, model+15);
8598 desc[511] = artist[63] = make[63] = model[63] = model2[63] = 0;
8599 if (!is_raw) goto notraw;
8601 if (!height) height = raw_height;
8602 if (!width) width = raw_width;
8603 if (height == 2624 && width == 3936) /* Pentax K10D and Samsung GX10 */
8604 { height = 2616; width = 3896; }
8605 if (height == 3136 && width == 4864) /* Pentax K20D and Samsung GX20 */
8606 { height = 3124; width = 4688; filters = 0x16161616; }
8607 if (width == 4352 && (!strcmp(model,"K-r") || !strcmp(model,"K-x")))
8608 { width = 4309; filters = 0x16161616; }
8609 if (width >= 4960 && !strncmp(model,"K-5",3))
8610 { left_margin = 10; width = 4950; filters = 0x16161616; }
8611 if (width == 4736 && !strcmp(model,"K-7"))
8612 { height = 3122; width = 4684; filters = 0x16161616; top_margin = 2; }
8613 if (width == 6080 && !strcmp(model,"K-3"))
8614 { left_margin = 4; width = 6040; }
8615 if (width == 7424 && !strcmp(model,"645D"))
8616 { height = 5502; width = 7328; filters = 0x61616161; top_margin = 29;
8618 if (height == 3014 && width == 4096) /* Ricoh GX200 */
8621 if (filters == UINT_MAX) filters = 0;
8622 if (filters) is_raw *= tiff_samples;
8623 else colors = tiff_samples;
8624 switch (tiff_compress) {
8626 case 1: load_raw = &CLASS packed_dng_load_raw; break;
8627 case 7: load_raw = &CLASS lossless_dng_load_raw; break;
8628 case 34892: load_raw = &CLASS lossy_dng_load_raw; break;
8629 default: load_raw = 0;
8633 if (!strcmp(make,"Canon") && !fsize && tiff_bps != 15) {
8635 load_raw = &CLASS lossless_jpeg_load_raw;
8636 for (i=0; i < sizeof canon / sizeof *canon; i++)
8637 if (raw_width == canon[i][0] && raw_height == canon[i][1]) {
8638 width = raw_width - (left_margin = canon[i][2]);
8639 height = raw_height - (top_margin = canon[i][3]);
8640 width -= canon[i][4];
8641 height -= canon[i][5];
8642 mask[0][1] = canon[i][6];
8643 mask[0][3] = -canon[i][7];
8644 mask[1][1] = canon[i][8];
8645 mask[1][3] = -canon[i][9];
8646 if (canon[i][10]) filters = canon[i][10] * 0x01010101;
8648 if ((unique_id | 0x20000) == 0x2720000) {
8653 for (i=0; i < sizeof unique / sizeof *unique; i++)
8654 if (unique_id == 0x80000000 + unique[i].id) {
8655 adobe_coeff ("Canon", unique[i].model);
8656 if (model[4] == 'K' && strlen(model) == 8)
8657 strcpy (model, unique[i].model);
8659 for (i=0; i < sizeof sonique / sizeof *sonique; i++)
8660 if (unique_id == sonique[i].id)
8661 strcpy (model, sonique[i].model);
8662 if (!strcmp(make,"Nikon")) {
8664 load_raw = &CLASS packed_load_raw;
8665 if (model[0] == 'E')
8666 load_flags |= !data_offset << 2 | 2;
8669 /* Set parameters based on camera name (for non-DNG files). */
8671 if (!strcmp(model,"KAI-0340")
8672 && find_green (16, 16, 3840, 5120) < 25) {
8674 top_margin = filters = 0;
8675 strcpy (model,"C603");
8677 if (!strcmp(make,"Sony") && raw_width > 3888)
8678 black = 128 << (tiff_bps - 12);
8680 if (height*2 < width) pixel_aspect = 0.5;
8681 if (height > width) pixel_aspect = 2;
8684 } else if (!strcmp(make,"Canon") && tiff_bps == 15) {
8686 case 3344: width -= 66;
8687 case 3872: width -= 6;
8689 if (height > width) {
8691 SWAP(raw_height,raw_width);
8693 if (width == 7200 && height == 3888) {
8694 raw_width = width = 6480;
8695 raw_height = height = 4320;
8698 tiff_samples = colors = 3;
8699 load_raw = &CLASS canon_sraw_load_raw;
8700 } else if (!strcmp(model,"PowerShot 600")) {
8705 filters = 0xe1e4e1e4;
8706 load_raw = &CLASS canon_600_load_raw;
8707 } else if (!strcmp(model,"PowerShot A5") ||
8708 !strcmp(model,"PowerShot A5 Zoom")) {
8712 pixel_aspect = 256/235.0;
8713 filters = 0x1e4e1e4e;
8715 } else if (!strcmp(model,"PowerShot A50")) {
8719 filters = 0x1b4e4b1e;
8721 } else if (!strcmp(model,"PowerShot Pro70")) {
8724 filters = 0x1e4b4e1b;
8728 load_raw = &CLASS packed_load_raw;
8730 } else if (!strcmp(model,"PowerShot Pro90 IS") ||
8731 !strcmp(model,"PowerShot G1")) {
8733 filters = 0xb4b4b4b4;
8734 } else if (!strcmp(model,"PowerShot A610")) {
8735 if (canon_s2is()) strcpy (model+10, "S2 IS");
8736 } else if (!strcmp(model,"PowerShot SX220 HS")) {
8738 } else if (!strcmp(model,"EOS D2000C")) {
8739 filters = 0x61616161;
8741 } else if (!strcmp(model,"D1")) {
8742 cam_mul[0] *= 256/527.0;
8743 cam_mul[2] *= 256/317.0;
8744 } else if (!strcmp(model,"D1X")) {
8747 } else if (!strcmp(model,"D40X") ||
8748 !strcmp(model,"D60") ||
8749 !strcmp(model,"D80") ||
8750 !strcmp(model,"D3000")) {
8753 } else if (!strcmp(model,"D3") ||
8754 !strcmp(model,"D3S") ||
8755 !strcmp(model,"D700")) {
8758 } else if (!strcmp(model,"D3100")) {
8761 } else if (!strcmp(model,"D5000") ||
8762 !strcmp(model,"D90")) {
8764 } else if (!strcmp(model,"D5100") ||
8765 !strcmp(model,"D7000") ||
8766 !strcmp(model,"COOLPIX A")) {
8768 } else if (!strcmp(model,"D3200") ||
8769 !strncmp(model,"D6",2) ||
8770 !strncmp(model,"D800",4)) {
8772 } else if (!strcmp(model,"D4") ||
8773 !strcmp(model,"Df")) {
8776 } else if (!strncmp(model,"D40",3) ||
8777 !strncmp(model,"D50",3) ||
8778 !strncmp(model,"D70",3)) {
8780 } else if (!strcmp(model,"D100")) {
8782 raw_width = (width += 3) + 3;
8783 } else if (!strcmp(model,"D200")) {
8786 filters = 0x94949494;
8787 } else if (!strncmp(model,"D2H",3)) {
8790 } else if (!strncmp(model,"D2X",3)) {
8791 if (width == 3264) width -= 32;
8793 } else if (!strncmp(model,"D300",4)) {
8795 } else if (!strncmp(model,"COOLPIX P",9) && raw_width != 4032) {
8797 filters = 0x94949494;
8798 if (model[9] == '7' && iso_speed >= 400)
8800 } else if (!strncmp(model,"1 ",2)) {
8802 } else if (fsize == 1581060) {
8804 pre_mul[0] = 1.2085;
8805 pre_mul[1] = 1.0943;
8806 pre_mul[3] = 1.1103;
8807 } else if (fsize == 3178560) {
8810 } else if (fsize == 4771840) {
8811 if (!timestamp && nikon_e995())
8812 strcpy (model, "E995");
8813 if (strcmp(model,"E995")) {
8814 filters = 0xb4b4b4b4;
8820 } else if (fsize == 2940928) {
8821 if (!timestamp && !nikon_e2100())
8822 strcpy (model,"E2500");
8823 if (!strcmp(model,"E2500")) {
8827 filters = 0x4b4b4b4b;
8829 } else if (fsize == 4775936) {
8830 if (!timestamp) nikon_3700();
8831 if (model[0] == 'E' && atoi(model+1) < 3700)
8832 filters = 0x49494949;
8833 if (!strcmp(model,"Optio 33WR")) {
8835 filters = 0x16161616;
8837 if (make[0] == 'O') {
8838 i = find_green (12, 32, 1188864, 3576832);
8839 c = find_green (12, 32, 2383920, 2387016);
8840 if (abs(i) < abs(c)) {
8844 if (i < 0) filters = 0x61616161;
8846 } else if (fsize == 5869568) {
8847 if (!timestamp && minolta_z2()) {
8848 strcpy (make, "Minolta");
8849 strcpy (model,"DiMAGE Z2");
8851 load_flags = 6 + 24*(make[0] == 'M');
8852 } else if (fsize == 6291456) {
8853 fseek (ifp, 0x300000, SEEK_SET);
8854 if ((order = guess_byte_order(0x10000)) == 0x4d4d) {
8855 height -= (top_margin = 16);
8856 width -= (left_margin = 28);
8858 strcpy (make, "ISG");
8861 } else if (!strcmp(make,"Fujifilm")) {
8862 if (!strcmp(model+7,"S2Pro")) {
8863 strcpy (model,"S2Pro");
8867 } else if (load_raw != &CLASS packed_load_raw)
8868 maximum = (is_raw == 2 && shot_select) ? 0x2f00 : 0x3e00;
8869 top_margin = (raw_height - height) >> 2 << 1;
8870 left_margin = (raw_width - width ) >> 2 << 1;
8871 if (width == 2848 || width == 3664) filters = 0x16161616;
8872 if (width == 4032 || width == 4952 || width == 6032) left_margin = 0;
8873 if (width == 3328 && (width -= 66)) left_margin = 34;
8874 if (width == 4936) left_margin = 4;
8875 if (!strcmp(model,"HS50EXR") ||
8876 !strcmp(model,"F900EXR")) {
8879 filters = 0x16161616;
8881 if (fuji_layout) raw_width *= is_raw;
8883 FORC(36) ((char *)xtrans)[c] =
8884 xtrans_abs[(c/6+top_margin) % 6][(c+left_margin) % 6];
8885 } else if (!strcmp(model,"KD-400Z")) {
8890 } else if (!strcmp(model,"KD-510Z")) {
8892 } else if (!strcasecmp(make,"Minolta")) {
8893 if (!load_raw && (maximum = 0xfff))
8894 load_raw = &CLASS unpacked_load_raw;
8895 if (!strncmp(model,"DiMAGE A",8)) {
8896 if (!strcmp(model,"DiMAGE A200"))
8897 filters = 0x49494949;
8899 load_raw = &CLASS packed_load_raw;
8900 } else if (!strncmp(model,"ALPHA",5) ||
8901 !strncmp(model,"DYNAX",5) ||
8902 !strncmp(model,"MAXXUM",6)) {
8903 sprintf (model+20, "DYNAX %-10s", model+6+(model[0]=='M'));
8904 adobe_coeff (make, model+20);
8905 load_raw = &CLASS packed_load_raw;
8906 } else if (!strncmp(model,"DiMAGE G",8)) {
8907 if (model[8] == '4') {
8910 } else if (model[8] == '5') {
8915 } else if (model[8] == '6') {
8920 filters = 0x61616161;
8922 load_raw = &CLASS unpacked_load_raw;
8926 } else if (!strcmp(model,"*ist D")) {
8927 load_raw = &CLASS unpacked_load_raw;
8929 } else if (!strcmp(model,"*ist DS")) {
8931 } else if (!strcmp(make,"Samsung") && raw_width == 4704) {
8932 height -= top_margin = 8;
8933 width -= 2 * (left_margin = 8);
8935 } else if (!strcmp(make,"Samsung") && raw_height == 3714) {
8936 height -= top_margin = 18;
8937 left_margin = raw_width - (width = 5536);
8938 if (raw_width != 5600)
8939 left_margin = top_margin = 0;
8940 filters = 0x61616161;
8942 } else if (!strcmp(make,"Samsung") && raw_width == 5632) {
8946 width = 5574 - (left_margin = 32 + tiff_bps);
8947 if (tiff_bps == 12) load_flags = 80;
8948 } else if (!strcmp(make,"Samsung") && raw_width == 5664) {
8949 height -= top_margin = 17;
8952 filters = 0x49494949;
8953 } else if (!strcmp(make,"Samsung") && raw_width == 6496) {
8954 filters = 0x61616161;
8955 black = 1 << (tiff_bps - 7);
8956 } else if (!strcmp(model,"EX1")) {
8960 if ((width -= 6) > 3682) {
8965 } else if (!strcmp(model,"WB2000")) {
8969 if ((width -= 10) > 3718) {
8974 } else if (strstr(model,"WB550")) {
8975 strcpy (model, "WB550");
8976 } else if (!strcmp(model,"EX2F")) {
8981 filters = 0x49494949;
8982 load_raw = &CLASS unpacked_load_raw;
8983 } else if (!strcmp(model,"STV680 VGA")) {
8985 } else if (!strcmp(model,"N95")) {
8986 height = raw_height - (top_margin = 2);
8987 } else if (!strcmp(model,"640x480")) {
8988 gamma_curve (0.45, 4.5, 1, 255);
8989 } else if (!strcmp(make,"Hasselblad")) {
8990 if (load_raw == &CLASS lossless_jpeg_load_raw)
8991 load_raw = &CLASS hasselblad_load_raw;
8992 if (raw_width == 7262) {
8997 filters = 0x61616161;
8998 } else if (raw_width == 7410 || raw_width == 8282) {
9003 filters = 0x61616161;
9004 } else if (raw_width == 9044) {
9009 black += load_flags = 256;
9011 } else if (raw_width == 4090) {
9012 strcpy (model, "V96C");
9013 height -= (top_margin = 6);
9014 width -= (left_margin = 3) + 7;
9015 filters = 0x61616161;
9017 if (tiff_samples > 1) {
9018 is_raw = tiff_samples+1;
9019 if (!shot_select && !half_size) filters = 0;
9021 } else if (!strcmp(make,"Sinar")) {
9022 if (!load_raw) load_raw = &CLASS unpacked_load_raw;
9023 if (is_raw > 1 && !shot_select && !half_size) filters = 0;
9025 } else if (!strcmp(make,"Leaf")) {
9027 fseek (ifp, data_offset, SEEK_SET);
9028 if (ljpeg_start (&jh, 1) && jh.bits == 15)
9030 if (tiff_samples > 1) filters = 0;
9031 if (tiff_samples > 1 || tile_length < raw_height) {
9032 load_raw = &CLASS leaf_hdr_load_raw;
9033 raw_width = tile_width;
9035 if ((width | height) == 2048) {
9036 if (tiff_samples == 1) {
9038 strcpy (cdesc, "RBTG");
9039 strcpy (model, "CatchLight");
9040 top_margin = 8; left_margin = 18; height = 2032; width = 2016;
9042 strcpy (model, "DCB2");
9043 top_margin = 10; left_margin = 16; height = 2028; width = 2022;
9045 } else if (width+height == 3144+2060) {
9046 if (!model[0]) strcpy (model, "Cantare");
9047 if (width > height) {
9048 top_margin = 6; left_margin = 32; height = 2048; width = 3072;
9049 filters = 0x61616161;
9051 left_margin = 6; top_margin = 32; width = 2048; height = 3072;
9052 filters = 0x16161616;
9054 if (!cam_mul[0] || model[0] == 'V') filters = 0;
9055 else is_raw = tiff_samples;
9056 } else if (width == 2116) {
9057 strcpy (model, "Valeo 6");
9058 height -= 2 * (top_margin = 30);
9059 width -= 2 * (left_margin = 55);
9060 filters = 0x49494949;
9061 } else if (width == 3171) {
9062 strcpy (model, "Valeo 6");
9063 height -= 2 * (top_margin = 24);
9064 width -= 2 * (left_margin = 24);
9065 filters = 0x16161616;
9067 } else if (!strcmp(make,"Leica") || !strcmp(make,"Panasonic")) {
9068 if ((flen - data_offset) / (raw_width*8/7) == raw_height)
9069 load_raw = &CLASS panasonic_load_raw;
9071 load_raw = &CLASS unpacked_load_raw;
9075 if ((height += 12) > raw_height) height = raw_height;
9076 for (i=0; i < sizeof pana / sizeof *pana; i++)
9077 if (raw_width == pana[i][0] && raw_height == pana[i][1]) {
9078 left_margin = pana[i][2];
9079 top_margin = pana[i][3];
9080 width += pana[i][4];
9081 height += pana[i][5];
9083 filters = 0x01010101 * (uchar) "\x94\x61\x49\x16"
9084 [((filters-1) ^ (left_margin & 1) ^ (top_margin << 1)) & 3];
9085 } else if (!strcmp(model,"C770UZ")) {
9088 filters = 0x16161616;
9089 load_raw = &CLASS packed_load_raw;
9091 } else if (!strcmp(make,"Olympus")) {
9092 height += height & 1;
9093 if (exif_cfa) filters = exif_cfa;
9094 if (width == 4100) width -= 4;
9095 if (width == 4080) width -= 24;
9096 if (width == 9280) { width -= 6; height -= 6; }
9097 if (load_raw == &CLASS unpacked_load_raw)
9100 if (!strcmp(model,"E-300") ||
9101 !strcmp(model,"E-500")) {
9103 if (load_raw == &CLASS unpacked_load_raw) {
9105 memset (cblack, 0, sizeof cblack);
9107 } else if (!strcmp(model,"E-330")) {
9109 if (load_raw == &CLASS unpacked_load_raw)
9111 } else if (!strcmp(model,"SP550UZ")) {
9112 thumb_length = flen - (thumb_offset = 0xa39800);
9115 } else if (!strcmp(model,"TG-4")) {
9118 } else if (!strcmp(model,"N Digital")) {
9121 filters = 0x61616161;
9122 data_offset = 0x1a00;
9123 load_raw = &CLASS packed_load_raw;
9124 } else if (!strcmp(model,"DSC-F828")) {
9128 data_offset = 862144;
9129 load_raw = &CLASS sony_load_raw;
9130 filters = 0x9c9c9c9c;
9132 strcpy (cdesc, "RGBE");
9133 } else if (!strcmp(model,"DSC-V3")) {
9137 data_offset = 787392;
9138 load_raw = &CLASS sony_load_raw;
9139 } else if (!strcmp(make,"Sony") && raw_width == 3984) {
9142 } else if (!strcmp(make,"Sony") && raw_width == 4288) {
9144 } else if (!strcmp(make,"Sony") && raw_width == 4600) {
9145 if (!strcmp(model,"DSLR-A350"))
9148 } else if (!strcmp(make,"Sony") && raw_width == 4928) {
9149 if (height < 3280) width -= 8;
9150 } else if (!strcmp(make,"Sony") && raw_width == 5504) {
9151 width -= height > 3664 ? 8 : 32;
9152 if (!strncmp(model,"DSC",3))
9153 black = 200 << (tiff_bps - 12);
9154 } else if (!strcmp(make,"Sony") && raw_width == 6048) {
9156 if (strstr(model,"RX1") || strstr(model,"A99"))
9158 } else if (!strcmp(make,"Sony") && raw_width == 7392) {
9160 } else if (!strcmp(make,"Sony") && raw_width == 8000) {
9162 if (!strncmp(model,"DSC",3)) {
9164 load_raw = &CLASS unpacked_load_raw;
9167 } else if (!strcmp(model,"DSLR-A100")) {
9168 if (width == 3880) {
9170 width = ++raw_width;
9177 filters = 0x61616161;
9178 } else if (!strcmp(model,"PIXL")) {
9179 height -= top_margin = 4;
9180 width -= left_margin = 32;
9181 gamma_curve (0, 7, 1, 255);
9182 } else if (!strcmp(model,"C603") || !strcmp(model,"C330")
9183 || !strcmp(model,"12MP")) {
9185 if (filters && data_offset) {
9186 fseek (ifp, data_offset < 4096 ? 168 : 5252, SEEK_SET);
9187 read_shorts (curve, 256);
9188 } else gamma_curve (0, 3.875, 1, 255);
9189 load_raw = filters ? &CLASS eight_bit_load_raw :
9190 strcmp(model,"C330") ? &CLASS kodak_c603_load_raw :
9191 &CLASS kodak_c330_load_raw;
9192 load_flags = tiff_bps > 16;
9194 } else if (!strncasecmp(model,"EasyShare",9)) {
9195 data_offset = data_offset < 0x15000 ? 0x15000 : 0x17000;
9196 load_raw = &CLASS packed_load_raw;
9197 } else if (!strcasecmp(make,"Kodak")) {
9198 if (filters == UINT_MAX) filters = 0x61616161;
9199 if (!strncmp(model,"NC2000",6) ||
9200 !strncmp(model,"EOSDCS",6) ||
9201 !strncmp(model,"DCS4",4)) {
9204 if (model[6] == ' ') model[6] = 0;
9205 if (!strcmp(model,"DCS460A")) goto bw;
9206 } else if (!strcmp(model,"DCS660M")) {
9209 } else if (!strcmp(model,"DCS760M")) {
9213 if (!strcmp(model+4,"20X"))
9214 strcpy (cdesc, "MYCY");
9215 if (strstr(model,"DC25")) {
9216 strcpy (model, "DC25");
9217 data_offset = 15424;
9219 if (!strncmp(model,"DC2",3)) {
9220 raw_height = 2 + (height = 242);
9221 if (flen < 100000) {
9222 raw_width = 256; width = 249;
9223 pixel_aspect = (4.0*height) / (3.0*width);
9225 raw_width = 512; width = 501;
9226 pixel_aspect = (493.0*height) / (373.0*width);
9228 top_margin = left_margin = 1;
9230 filters = 0x8d8d8d8d;
9235 load_raw = &CLASS eight_bit_load_raw;
9236 } else if (!strcmp(model,"40")) {
9237 strcpy (model, "DC40");
9241 load_raw = &CLASS kodak_radc_load_raw;
9243 } else if (strstr(model,"DC50")) {
9244 strcpy (model, "DC50");
9247 data_offset = 19712;
9248 load_raw = &CLASS kodak_radc_load_raw;
9249 } else if (strstr(model,"DC120")) {
9250 strcpy (model, "DC120");
9253 pixel_aspect = height/0.75/width;
9254 load_raw = tiff_compress == 7 ?
9255 &CLASS kodak_jpeg_load_raw : &CLASS kodak_dc120_load_raw;
9256 } else if (!strcmp(model,"DCS200")) {
9259 thumb_offset = 6144;
9261 write_thumb = &CLASS layer_thumb;
9264 } else if (!strcmp(model,"Fotoman Pixtura")) {
9268 load_raw = &CLASS kodak_radc_load_raw;
9269 filters = 0x61616161;
9271 } else if (!strncmp(model,"QuickTake",9)) {
9272 if (head[5]) strcpy (model+10, "200");
9273 fseek (ifp, 544, SEEK_SET);
9276 data_offset = (get4(),get2()) == 30 ? 738:736;
9277 if (height > width) {
9279 fseek (ifp, data_offset-6, SEEK_SET);
9280 flip = ~get2() & 3 ? 5:6;
9282 filters = 0x61616161;
9283 } else if (!strcmp(make,"Rollei") && !load_raw) {
9284 switch (raw_width) {
9297 filters = 0x16161616;
9298 load_raw = &CLASS rollei_load_raw;
9301 sprintf (model, "%dx%d", width, height);
9302 if (filters == UINT_MAX) filters = 0x94949494;
9303 if (thumb_offset && !thumb_height) {
9304 fseek (ifp, thumb_offset, SEEK_SET);
9305 if (ljpeg_start (&jh, 1)) {
9306 thumb_width = jh.wide;
9307 thumb_height = jh.high;
9311 if ((use_camera_matrix & (use_camera_wb || dng_version))
9312 && cmatrix[0][0] > 0.125) {
9313 memcpy (rgb_cam, cmatrix, sizeof cmatrix);
9316 if (raw_color) adobe_coeff (make, model);
9317 if (load_raw == &CLASS kodak_radc_load_raw)
9318 if (raw_color) adobe_coeff ("Apple","Quicktake");
9320 fuji_width = width >> !fuji_layout;
9321 filters = fuji_width & 1 ? 0x94949494 : 0x49494949;
9322 width = (height >> fuji_layout) + fuji_width;
9326 if (raw_height < height) raw_height = height;
9327 if (raw_width < width ) raw_width = width;
9329 if (!tiff_bps) tiff_bps = 12;
9330 if (!maximum) maximum = (1 << tiff_bps) - 1;
9331 if (!load_raw || height < 22 || width < 22 ||
9332 tiff_bps > 16 || tiff_samples > 6 || colors > 4)
9335 if (load_raw == &CLASS redcine_load_raw) {
9336 fprintf (stderr,_("%s: You must link dcraw with %s!!\n"),
9337 ifname, "libjasper");
9342 if (load_raw == &CLASS kodak_jpeg_load_raw ||
9343 load_raw == &CLASS lossy_dng_load_raw) {
9344 fprintf (stderr,_("%s: You must link dcraw with %s!!\n"),
9350 strcpy (cdesc, colors == 3 ? "RGBG":"GMCY");
9351 if (!raw_height) raw_height = height;
9352 if (!raw_width ) raw_width = width;
9353 if (filters > 999 && colors == 3)
9354 filters |= ((filters >> 2 & 0x22222222) |
9355 (filters << 2 & 0x88888888)) & filters << 1;
9357 if (flip == UINT_MAX) flip = tiff_flip;
9358 if (flip == UINT_MAX) flip = 0;
9361 { unsigned flp = flip;
9362 switch ((flp+3600) % 360) {
9363 case 270: flp = 5; break;
9364 case 180: flp = 3; break;
9368 sprintf(info, "%d %d", height, width);
9370 sprintf(info, "%d %d", width, height); }
9374 void CLASS apply_profile (const char *input, const char *output)
9377 cmsHPROFILE hInProfile=0, hOutProfile=0;
9378 cmsHTRANSFORM hTransform;
9382 if (strcmp (input, "embed"))
9383 hInProfile = cmsOpenProfileFromFile (input, "r");
9384 else if (profile_length) {
9385 prof = (char *) malloc (profile_length);
9386 merror (prof, "apply_profile()");
9387 fseek (ifp, profile_offset, SEEK_SET);
9388 fread (prof, 1, profile_length, ifp);
9389 hInProfile = cmsOpenProfileFromMem (prof, profile_length);
9392 fprintf (stderr,_("%s has no embedded profile.\n"), ifname);
9393 if (!hInProfile) return;
9395 hOutProfile = cmsCreate_sRGBProfile();
9396 else if ((fp = fopen (output, "rb"))) {
9397 fread (&size, 4, 1, fp);
9398 fseek (fp, 0, SEEK_SET);
9399 oprof = (unsigned *) malloc (size = ntohl(size));
9400 merror (oprof, "apply_profile()");
9401 fread (oprof, 1, size, fp);
9403 if (!(hOutProfile = cmsOpenProfileFromMem (oprof, size))) {
9408 fprintf (stderr,_("Cannot open file %s!\n"), output);
9409 if (!hOutProfile) goto quit;
9411 fprintf (stderr,_("Applying color profile...\n"));
9412 hTransform = cmsCreateTransform (hInProfile, TYPE_RGBA_16,
9413 hOutProfile, TYPE_RGBA_16, INTENT_PERCEPTUAL, 0);
9414 cmsDoTransform (hTransform, image, image, width*height);
9415 raw_color = 1; /* Don't use rgb_cam with a profile */
9416 cmsDeleteTransform (hTransform);
9417 cmsCloseProfile (hOutProfile);
9419 cmsCloseProfile (hInProfile);
9423 void CLASS convert_to_rgb()
9425 int row, col, c, i, j, k;
9427 float out[3], out_cam[3][4];
9428 double num, inverse[3][3];
9429 static const double xyzd50_srgb[3][3] =
9430 { { 0.436083, 0.385083, 0.143055 },
9431 { 0.222507, 0.716888, 0.060608 },
9432 { 0.013930, 0.097097, 0.714022 } };
9433 static const double rgb_rgb[3][3] =
9434 { { 1,0,0 }, { 0,1,0 }, { 0,0,1 } };
9435 static const double adobe_rgb[3][3] =
9436 { { 0.715146, 0.284856, 0.000000 },
9437 { 0.000000, 1.000000, 0.000000 },
9438 { 0.000000, 0.041166, 0.958839 } };
9439 static const double wide_rgb[3][3] =
9440 { { 0.593087, 0.404710, 0.002206 },
9441 { 0.095413, 0.843149, 0.061439 },
9442 { 0.011621, 0.069091, 0.919288 } };
9443 static const double prophoto_rgb[3][3] =
9444 { { 0.529317, 0.330092, 0.140588 },
9445 { 0.098368, 0.873465, 0.028169 },
9446 { 0.016879, 0.117663, 0.865457 } };
9447 static const double aces_rgb[3][3] =
9448 { { 0.432996, 0.375380, 0.189317 },
9449 { 0.089427, 0.816523, 0.102989 },
9450 { 0.019165, 0.118150, 0.941914 } };
9451 static const double (*out_rgb[])[3] =
9452 { rgb_rgb, adobe_rgb, wide_rgb, prophoto_rgb, xyz_rgb, aces_rgb };
9453 static const char *name[] =
9454 { "sRGB", "Adobe RGB (1998)", "WideGamut D65", "ProPhoto D65", "XYZ", "ACES" };
9455 static const unsigned phead[] =
9456 { 1024, 0, 0x2100000, 0x6d6e7472, 0x52474220, 0x58595a20, 0, 0, 0,
9457 0x61637370, 0, 0, 0x6e6f6e65, 0, 0, 0, 0, 0xf6d6, 0x10000, 0xd32d };
9459 { 10, 0x63707274, 0, 36, /* cprt */
9460 0x64657363, 0, 40, /* desc */
9461 0x77747074, 0, 20, /* wtpt */
9462 0x626b7074, 0, 20, /* bkpt */
9463 0x72545243, 0, 14, /* rTRC */
9464 0x67545243, 0, 14, /* gTRC */
9465 0x62545243, 0, 14, /* bTRC */
9466 0x7258595a, 0, 20, /* rXYZ */
9467 0x6758595a, 0, 20, /* gXYZ */
9468 0x6258595a, 0, 20 }; /* bXYZ */
9469 static const unsigned pwhite[] = { 0xf351, 0x10000, 0x116cc };
9470 unsigned pcurve[] = { 0x63757276, 0, 1, 0x1000000 };
9472 gamma_curve (gamm[0], gamm[1], 0, 0);
9473 memcpy (out_cam, rgb_cam, sizeof out_cam);
9474 raw_color |= colors == 1 || document_mode ||
9475 output_color < 1 || output_color > 6;
9477 oprof = (unsigned *) calloc (phead[0], 1);
9478 merror (oprof, "convert_to_rgb()");
9479 memcpy (oprof, phead, sizeof phead);
9480 if (output_color == 5) oprof[4] = oprof[5];
9481 oprof[0] = 132 + 12*pbody[0];
9482 for (i=0; i < pbody[0]; i++) {
9483 oprof[oprof[0]/4] = i ? (i > 1 ? 0x58595a20 : 0x64657363) : 0x74657874;
9484 pbody[i*3+2] = oprof[0];
9485 oprof[0] += (pbody[i*3+3] + 3) & -4;
9487 memcpy (oprof+32, pbody, sizeof pbody);
9488 oprof[pbody[5]/4+2] = strlen(name[output_color-1]) + 1;
9489 memcpy ((char *)oprof+pbody[8]+8, pwhite, sizeof pwhite);
9490 pcurve[3] = (short)(256/gamm[5]+0.5) << 16;
9491 for (i=4; i < 7; i++)
9492 memcpy ((char *)oprof+pbody[i*3+2], pcurve, sizeof pcurve);
9493 pseudoinverse ((double (*)[3]) out_rgb[output_color-1], inverse, 3);
9494 for (i=0; i < 3; i++)
9495 for (j=0; j < 3; j++) {
9496 for (num = k=0; k < 3; k++)
9497 num += xyzd50_srgb[i][k] * inverse[j][k];
9498 oprof[pbody[j*3+23]/4+i+2] = num * 0x10000 + 0.5;
9500 for (i=0; i < phead[0]/4; i++)
9501 oprof[i] = htonl(oprof[i]);
9502 strcpy ((char *)oprof+pbody[2]+8, "auto-generated by dcraw");
9503 strcpy ((char *)oprof+pbody[5]+12, name[output_color-1]);
9504 for (i=0; i < 3; i++)
9505 for (j=0; j < colors; j++)
9506 for (out_cam[i][j] = k=0; k < 3; k++)
9507 out_cam[i][j] += out_rgb[output_color-1][i][k] * rgb_cam[k][j];
9510 fprintf (stderr, raw_color ? _("Building histograms...\n") :
9511 _("Converting to %s colorspace...\n"), name[output_color-1]);
9513 memset (histogram, 0, sizeof histogram);
9514 for (img=image[0], row=0; row < height; row++)
9515 for (col=0; col < width; col++, img+=4) {
9517 out[0] = out[1] = out[2] = 0;
9519 out[0] += out_cam[0][c] * img[c];
9520 out[1] += out_cam[1][c] * img[c];
9521 out[2] += out_cam[2][c] * img[c];
9523 FORC3 img[c] = CLIP((int) out[c]);
9525 else if (document_mode)
9526 img[0] = img[fcol(row,col)];
9527 FORCC histogram[c][img[c] >> 3]++;
9529 if (colors == 4 && output_color) colors = 3;
9530 if (document_mode && filters) colors = 1;
9533 // Export color matrix to Cinelerra.
9534 // It can't be applied before interpolation.
9536 for(i = 0; i < 3; i++) {
9537 for(j = 0; j < 3; j++)
9538 matrix[k++] = rgb_cam[i][j];
9543 void CLASS fuji_rotate()
9549 ushort wide, high, (*img)[4], (*pix)[4];
9551 if (!fuji_width) return;
9553 fprintf (stderr,_("Rotating image 45 degrees...\n"));
9554 fuji_width = (fuji_width - 1 + shrink) >> shrink;
9556 wide = fuji_width / step;
9557 high = (height - fuji_width) / step;
9558 img = (ushort (*)[4]) calloc (high, wide*sizeof *img);
9559 merror (img, "fuji_rotate()");
9561 for (row=0; row < high; row++)
9562 for (col=0; col < wide; col++) {
9563 ur = r = fuji_width + (row-col)*step;
9564 uc = c = (row+col)*step;
9565 if (ur > height-2 || uc > width-2) continue;
9568 pix = image + ur*width + uc;
9569 for (i=0; i < colors; i++)
9570 img[row*wide+col][i] =
9571 (pix[ 0][i]*(1-fc) + pix[ 1][i]*fc) * (1-fr) +
9572 (pix[width][i]*(1-fc) + pix[width+1][i]*fc) * fr;
9581 void CLASS stretch()
9583 ushort newdim, (*img)[4], *pix0, *pix1;
9587 if (pixel_aspect == 1) return;
9588 if (verbose) fprintf (stderr,_("Stretching the image...\n"));
9589 if (pixel_aspect < 1) {
9590 newdim = height / pixel_aspect + 0.5;
9591 img = (ushort (*)[4]) calloc (width, newdim*sizeof *img);
9592 merror (img, "stretch()");
9593 for (rc=row=0; row < newdim; row++, rc+=pixel_aspect) {
9594 frac = rc - (c = rc);
9595 pix0 = pix1 = image[c*width];
9596 if (c+1 < height) pix1 += width*4;
9597 for (col=0; col < width; col++, pix0+=4, pix1+=4)
9598 FORCC img[row*width+col][c] = pix0[c]*(1-frac) + pix1[c]*frac + 0.5;
9602 newdim = width * pixel_aspect + 0.5;
9603 img = (ushort (*)[4]) calloc (height, newdim*sizeof *img);
9604 merror (img, "stretch()");
9605 for (rc=col=0; col < newdim; col++, rc+=1/pixel_aspect) {
9606 frac = rc - (c = rc);
9607 pix0 = pix1 = image[c];
9608 if (c+1 < width) pix1 += 4;
9609 for (row=0; row < height; row++, pix0+=width*4, pix1+=width*4)
9610 FORCC img[row*newdim+col][c] = pix0[c]*(1-frac) + pix1[c]*frac + 0.5;
9618 int CLASS flip_index (int row, int col)
9620 if (flip & 4) SWAP(row,col);
9621 if (flip & 2) row = iheight - 1 - row;
9622 if (flip & 1) col = iwidth - 1 - col;
9623 return row * iwidth + col;
9629 union { char c[4]; short s[2]; int i; } val;
9633 ushort order, magic;
9636 struct tiff_tag tag[23];
9639 struct tiff_tag exif[4];
9641 struct tiff_tag gpst[10];
9645 char desc[512], make[64], model[64], soft[32], date[20], artist[64];
9648 void CLASS tiff_set (struct tiff_hdr *th, ushort *ntag,
9649 ushort tag, ushort type, int count, int val)
9651 struct tiff_tag *tt;
9654 tt = (struct tiff_tag *)(ntag+1) + (*ntag)++;
9656 if (type == 1 && count <= 4)
9657 FORC(4) tt->val.c[c] = val >> (c << 3);
9658 else if (type == 2) {
9659 count = strnlen((char *)th + val, count-1) + 1;
9661 FORC(4) tt->val.c[c] = ((char *)th)[val+c];
9662 } else if (type == 3 && count <= 2)
9663 FORC(2) tt->val.s[c] = val >> (c << 4);
9669 #define TOFF(ptr) ((char *)(&(ptr)) - (char *)th)
9671 void CLASS tiff_head (struct tiff_hdr *th, int full)
9676 memset (th, 0, sizeof *th);
9677 th->order = htonl(0x4d4d4949) >> 16;
9680 th->rat[0] = th->rat[2] = 300;
9681 th->rat[1] = th->rat[3] = 1;
9682 FORC(6) th->rat[4+c] = 1000000;
9683 th->rat[4] *= shutter;
9684 th->rat[6] *= aperture;
9685 th->rat[8] *= focal_len;
9686 strncpy (th->desc, desc, 512);
9687 strncpy (th->make, make, 64);
9688 strncpy (th->model, model, 64);
9689 strcpy (th->soft, "dcraw v" DCRAW_VERSION);
9690 t = localtime (×tamp);
9691 sprintf (th->date, "%04d:%02d:%02d %02d:%02d:%02d",
9692 t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);
9693 strncpy (th->artist, artist, 64);
9695 tiff_set (th, &th->ntag, 254, 4, 1, 0);
9696 tiff_set (th, &th->ntag, 256, 4, 1, width);
9697 tiff_set (th, &th->ntag, 257, 4, 1, height);
9698 tiff_set (th, &th->ntag, 258, 3, colors, output_bps);
9700 th->tag[th->ntag-1].val.i = TOFF(th->bps);
9701 FORC4 th->bps[c] = output_bps;
9702 tiff_set (th, &th->ntag, 259, 3, 1, 1);
9703 tiff_set (th, &th->ntag, 262, 3, 1, 1 + (colors > 1));
9705 tiff_set (th, &th->ntag, 270, 2, 512, TOFF(th->desc));
9706 tiff_set (th, &th->ntag, 271, 2, 64, TOFF(th->make));
9707 tiff_set (th, &th->ntag, 272, 2, 64, TOFF(th->model));
9709 if (oprof) psize = ntohl(oprof[0]);
9710 tiff_set (th, &th->ntag, 273, 4, 1, sizeof *th + psize);
9711 tiff_set (th, &th->ntag, 277, 3, 1, colors);
9712 tiff_set (th, &th->ntag, 278, 4, 1, height);
9713 tiff_set (th, &th->ntag, 279, 4, 1, height*width*colors*output_bps/8);
9715 tiff_set (th, &th->ntag, 274, 3, 1, "12435867"[flip]-'0');
9716 tiff_set (th, &th->ntag, 282, 5, 1, TOFF(th->rat[0]));
9717 tiff_set (th, &th->ntag, 283, 5, 1, TOFF(th->rat[2]));
9718 tiff_set (th, &th->ntag, 284, 3, 1, 1);
9719 tiff_set (th, &th->ntag, 296, 3, 1, 2);
9720 tiff_set (th, &th->ntag, 305, 2, 32, TOFF(th->soft));
9721 tiff_set (th, &th->ntag, 306, 2, 20, TOFF(th->date));
9722 tiff_set (th, &th->ntag, 315, 2, 64, TOFF(th->artist));
9723 tiff_set (th, &th->ntag, 34665, 4, 1, TOFF(th->nexif));
9724 if (psize) tiff_set (th, &th->ntag, 34675, 7, psize, sizeof *th);
9725 tiff_set (th, &th->nexif, 33434, 5, 1, TOFF(th->rat[4]));
9726 tiff_set (th, &th->nexif, 33437, 5, 1, TOFF(th->rat[6]));
9727 tiff_set (th, &th->nexif, 34855, 3, 1, iso_speed);
9728 tiff_set (th, &th->nexif, 37386, 5, 1, TOFF(th->rat[8]));
9730 tiff_set (th, &th->ntag, 34853, 4, 1, TOFF(th->ngps));
9731 tiff_set (th, &th->ngps, 0, 1, 4, 0x202);
9732 tiff_set (th, &th->ngps, 1, 2, 2, gpsdata[29]);
9733 tiff_set (th, &th->ngps, 2, 5, 3, TOFF(th->gps[0]));
9734 tiff_set (th, &th->ngps, 3, 2, 2, gpsdata[30]);
9735 tiff_set (th, &th->ngps, 4, 5, 3, TOFF(th->gps[6]));
9736 tiff_set (th, &th->ngps, 5, 1, 1, gpsdata[31]);
9737 tiff_set (th, &th->ngps, 6, 5, 1, TOFF(th->gps[18]));
9738 tiff_set (th, &th->ngps, 7, 5, 3, TOFF(th->gps[12]));
9739 tiff_set (th, &th->ngps, 18, 2, 12, TOFF(th->gps[20]));
9740 tiff_set (th, &th->ngps, 29, 2, 12, TOFF(th->gps[23]));
9741 memcpy (th->gps, gpsdata, sizeof th->gps);
9745 void CLASS jpeg_thumb()
9751 thumb = (char *) malloc (thumb_length);
9752 merror (thumb, "jpeg_thumb()");
9753 fread (thumb, 1, thumb_length, ifp);
9756 if (strcmp (thumb+6, "Exif")) {
9757 memcpy (exif, "\xff\xe1 Exif\0\0", 10);
9758 exif[1] = htons (8 + sizeof th);
9759 fwrite (exif, 1, sizeof exif, ofp);
9761 fwrite (&th, 1, sizeof th, ofp);
9763 fwrite (thumb+2, 1, thumb_length-2, ofp);
9767 void CLASS write_ppm_tiff()
9772 int c, row, col, soff, rstep, cstep;
9773 int perc, val, total, white=0x2000;
9775 perc = width * height * 0.01; /* 99th percentile white level */
9776 if (fuji_width) perc /= 2;
9777 if (!((highlight & ~2) || no_auto_bright))
9778 for (white=c=0; c < colors; c++) {
9779 for (val=0x2000, total=0; --val > 32; )
9780 if ((total += histogram[c][val]) > perc) break;
9781 if (white < val) white = val;
9783 gamma_curve (gamm[0], gamm[1], 2, (white << 3)/bright);
9786 if (flip & 4) SWAP(height,width);
9787 ppm = (uchar *) calloc (width, colors*output_bps/8);
9788 ppm2 = (ushort *) ppm;
9789 merror (ppm, "write_ppm_tiff()");
9792 fwrite (&th, sizeof th, 1, ofp);
9794 fwrite (oprof, ntohl(oprof[0]), 1, ofp);
9795 } else if (colors > 3)
9797 "P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLTYPE %s\nENDHDR\n",
9798 width, height, colors, (1 << output_bps)-1, cdesc);
9800 fprintf (ofp, "P%d\n%d %d\n%d\n",
9801 colors/2+5, width, height, (1 << output_bps)-1);
9802 soff = flip_index (0, 0);
9803 cstep = flip_index (0, 1) - soff;
9804 rstep = flip_index (1, 0) - flip_index (0, width);
9805 for (row=0; row < height; row++, soff += rstep) {
9806 for (col=0; col < width; col++, soff += cstep)
9807 if (output_bps == 8)
9808 FORCC ppm [col*colors+c] = curve[image[soff][c]] >> 8;
9809 else FORCC ppm2[col*colors+c] = curve[image[soff][c]];
9810 if (output_bps == 16 && !output_tiff && htons(0x55aa) != 0x55aa)
9811 swab (ppm2, ppm2, width*colors*2);
9812 fwrite (ppm, colors*output_bps/8, width, ofp);
9818 void CLASS write_cinelerra()
9820 int c, row, col, soff, cstep, rstep;
9821 float scale = 1. / 0xffff;
9822 iheight = height; iwidth = width;
9823 if( (flip & 4) != 0 ) SWAP(height,width);
9824 soff = flip_index(0, 0);
9825 cstep = flip_index(0, 1) - soff;
9826 rstep = flip_index(1, 0) - flip_index(0, width);
9827 if( document_mode ) {
9828 for( row=0; row<height; ++row, soff += rstep ) {
9829 float *output = data[row];
9830 for( col=0; col<width; ++col, soff += cstep ) {
9831 ushort *pixel = image[soff];
9832 FORC3 *output++ = (float)*pixel++ * scale;
9833 if( alpha ) *output++ = 1.0;
9838 int val, total, white=0x2000;
9839 int perc = width * height * 0.01; /* 99th percentile white level */
9840 if( fuji_width ) perc /= 2;
9841 if( !((highlight & ~2) || no_auto_bright) ) {
9842 for( white=c=0; c < colors; ++c ) {
9843 for( val=0x2000, total=0; --val > 32; )
9844 if( (total += histogram[c][val]) > perc ) break;
9845 if( white < val ) white = val;
9848 gamma_curve(gamm[0], gamm[1], 2, (white << 3)/bright);
9849 for( row=0; row<height; ++row, soff += rstep ) {
9850 float *output = data[row];
9851 for( col=0; col<width; ++col, soff += cstep ) {
9852 ushort *pixel = image[soff];
9853 FORC3 *output++ = (float)curve[*pixel++] * scale;
9854 if( alpha ) *output++ = 1.0;
9861 int CLASS main (int argc, const char **argv)
9863 int arg, status=0, quality, i, c;
9864 int timestamp_only=0, thumbnail_only=0, identify_only=0;
9865 int user_qual=-1, user_black=-1, user_sat=-1, user_flip=-1;
9866 int use_fuji_rotate=1, write_to_stdout=0, read_from_stdin=0;
9867 const char *sp, *bpfile=0, *dark_frame=0, *write_ext;
9868 char opm, opt, *ofname, *cp;
9871 const char *cam_profile=0, *out_profile=0;
9875 reset(); // Globals must be reset
9878 putenv ((char *) "TZ=UTC");
9881 setlocale (LC_CTYPE, "");
9882 setlocale (LC_MESSAGES, "");
9883 bindtextdomain ("dcraw", LOCALEDIR);
9884 textdomain ("dcraw");
9888 printf(_("\nRaw photo decoder \"dcraw\" v%s"), DCRAW_VERSION);
9889 printf(_("\nby Dave Coffin, dcoffin a cybercom o net\n"));
9890 printf(_("\nUsage: %s [OPTION]... [FILE]...\n\n"), argv[0]);
9891 puts(_("-v Print verbose messages"));
9892 puts(_("-c Write image data to standard output"));
9893 puts(_("-e Extract embedded thumbnail image"));
9894 puts(_("-i Identify files without decoding them"));
9895 puts(_("-i -v Identify files and show metadata"));
9896 puts(_("-z Change file dates to camera timestamp"));
9897 puts(_("-w Use camera white balance, if possible"));
9898 puts(_("-a Average the whole image for white balance"));
9899 puts(_("-A <x y w h> Average a grey box for white balance"));
9900 puts(_("-r <r g b g> Set custom white balance"));
9901 puts(_("+M/-M Use/don't use an embedded color matrix"));
9902 puts(_("-C <r b> Correct chromatic aberration"));
9903 puts(_("-P <file> Fix the dead pixels listed in this file"));
9904 puts(_("-K <file> Subtract dark frame (16-bit raw PGM)"));
9905 puts(_("-k <num> Set the darkness level"));
9906 puts(_("-S <num> Set the saturation level"));
9907 puts(_("-n <num> Set threshold for wavelet denoising"));
9908 puts(_("-H [0-9] Highlight mode (0=clip, 1=unclip, 2=blend, 3+=rebuild)"));
9909 puts(_("-t [0-7] Flip image (0=none, 3=180, 5=90CCW, 6=90CW)"));
9910 puts(_("-o [0-6] Output colorspace (raw,sRGB,Adobe,Wide,ProPhoto,XYZ,ACES)"));
9912 puts(_("-o <file> Apply output ICC profile from file"));
9913 puts(_("-p <file> Apply camera ICC profile from file or \"embed\""));
9915 puts(_("-d Document mode (no color, no interpolation)"));
9916 puts(_("-D Document mode without scaling (totally raw)"));
9917 puts(_("-j Don't stretch or rotate raw pixels"));
9918 puts(_("-W Don't automatically brighten the image"));
9919 puts(_("-b <num> Adjust brightness (default = 1.0)"));
9920 puts(_("-g <p ts> Set custom gamma curve (default = 2.222 4.5)"));
9921 puts(_("-q [0-3] Set the interpolation quality"));
9922 puts(_("-h Half-size color image (twice as fast as \"-q 0\")"));
9923 puts(_("-f Interpolate RGGB as four colors"));
9924 puts(_("-m <num> Apply a 3x3 median filter to R-G and B-G"));
9925 puts(_("-s [0..N-1] Select one raw image or \"all\" from each file"));
9926 puts(_("-6 Write 16-bit instead of 8-bit"));
9927 puts(_("-4 Linear 16-bit, same as \"-6 -W -g 1 1\""));
9928 puts(_("-T Write TIFF instead of PPM"));
9933 for (arg=1; (((opm = argv[arg][0]) - 2) | 2) == '+'; ) {
9934 opt = argv[arg++][1];
9935 if ((cp = (char *) strchr (sp="nbrkStqmHACg", opt)))
9936 for (i=0; i < "114111111422"[cp-sp]-'0'; i++)
9937 if (!isdigit(argv[arg+i][0])) {
9938 fprintf (stderr,_("Non-numeric argument to \"-%c\"\n"), opt);
9942 case 'n': threshold = atof(argv[arg++]); break;
9943 case 'b': bright = atof(argv[arg++]); break;
9945 FORC4 user_mul[c] = atof(argv[arg++]); break;
9946 case 'C': aber[0] = 1 / atof(argv[arg++]);
9947 aber[2] = 1 / atof(argv[arg++]); break;
9948 case 'g': gamm[0] = atof(argv[arg++]);
9949 gamm[1] = atof(argv[arg++]);
9950 if (gamm[0]) gamm[0] = 1/gamm[0]; break;
9951 case 'k': user_black = atoi(argv[arg++]); break;
9952 case 'S': user_sat = atoi(argv[arg++]); break;
9953 case 't': user_flip = atoi(argv[arg++]); break;
9954 case 'q': user_qual = atoi(argv[arg++]); break;
9955 case 'm': med_passes = atoi(argv[arg++]); break;
9956 case 'H': highlight = atoi(argv[arg++]); break;
9958 shot_select = abs(atoi(argv[arg]));
9959 multi_out = !strcmp(argv[arg++],"all");
9962 if (isdigit(argv[arg][0]) && !argv[arg][1])
9963 output_color = atoi(argv[arg++]);
9965 else out_profile = argv[arg++];
9967 case 'p': cam_profile = argv[arg++];
9970 case 'P': bpfile = argv[arg++]; break;
9971 case 'K': dark_frame = argv[arg++]; break;
9972 case 'z': timestamp_only = 1; break;
9973 case 'e': thumbnail_only = 1; break;
9974 case 'i': identify_only = 1; break;
9975 case 'c': write_to_stdout = 1; break;
9976 case 'v': verbose = 1; break;
9977 case 'h': half_size = 1; break;
9978 case 'f': four_color_rgb = 1; break;
9979 case 'A': FORC4 greybox[c] = atoi(argv[arg++]);
9980 case 'a': use_auto_wb = 1; break;
9981 case 'w': use_camera_wb = 1; break;
9982 case 'M': use_camera_matrix = 3 * (opm == '+'); break;
9983 case 'I': read_from_stdin = 1; break;
9984 case 'E': document_mode++;
9985 case 'D': document_mode++;
9986 case 'd': document_mode++;
9987 case 'j': use_fuji_rotate = 0; break;
9988 case 'W': no_auto_bright = 1; break;
9989 case 'T': output_tiff = 1; break;
9990 case '4': gamm[0] = gamm[1] =
9992 case '6': output_bps = 16; break;
9994 fprintf (stderr,_("Unknown option \"-%c\".\n"), opt);
9999 fprintf (stderr,_("No files to process.\n"));
10002 if (write_to_stdout) {
10004 if (0 && isatty(1)) {
10005 fprintf (stderr,_("Will not write an image to the terminal!\n"));
10008 #if defined(WIN32) || defined(DJGPP) || defined(__CYGWIN__)
10009 if (setmode(1,O_BINARY) < 0) {
10010 perror ("setmode()");
10015 for ( ; arg < argc; arg++) {
10020 meta_data = ofname = 0;
10022 if (setjmp (failure)) {
10023 if (fileno(ifp) > 2) fclose(ifp);
10024 if (fileno(ofp) > 2) fclose(ofp);
10028 ifname = argv[arg];
10029 if (!(ifp = fopen (ifname, "rb"))) {
10033 status = (identify(),!is_raw);
10034 if (user_flip >= 0)
10036 switch ((flip+3600) % 360) {
10037 case 270: flip = 5; break;
10038 case 180: flip = 3; break;
10041 if (timestamp_only) {
10042 if ((status = !timestamp))
10043 fprintf (stderr,_("%s has no timestamp.\n"), ifname);
10044 else if (identify_only)
10045 printf ("%10ld%10d %s\n", (long) timestamp, shot_order, ifname);
10048 fprintf (stderr,_("%s time set to %d.\n"), ifname, (int) timestamp);
10049 ut.actime = ut.modtime = timestamp;
10050 utime (ifname, &ut);
10055 // write_fun = &CLASS write_ppm_tiff;
10056 write_fun = &CLASS write_cinelerra;
10058 if (thumbnail_only) {
10059 if ((status = !thumb_offset)) {
10060 fprintf (stderr,_("%s has no thumbnail.\n"), ifname);
10062 } else if (thumb_load_raw) {
10063 load_raw = thumb_load_raw;
10064 data_offset = thumb_offset;
10065 height = thumb_height;
10066 width = thumb_width;
10070 fseek (ifp, thumb_offset, SEEK_SET);
10071 write_fun = write_thumb;
10075 if (load_raw == &CLASS kodak_ycbcr_load_raw) {
10076 height += height & 1;
10077 width += width & 1;
10079 if (identify_only && verbose && make[0]) {
10080 printf (_("\nFilename: %s\n"), ifname);
10081 printf (_("Timestamp: %s"), ctime(×tamp));
10082 printf (_("Camera: %s %s\n"), make, model);
10084 printf (_("Owner: %s\n"), artist);
10086 printf (_("DNG Version: "));
10087 for (i=24; i >= 0; i -= 8)
10088 printf ("%d%c", dng_version >> i & 255, i ? '.':'\n');
10090 printf (_("ISO speed: %d\n"), (int) iso_speed);
10091 printf (_("Shutter: "));
10092 if (shutter > 0 && shutter < 1)
10093 shutter = (printf ("1/"), 1 / shutter);
10094 printf (_("%0.1f sec\n"), shutter);
10095 printf (_("Aperture: f/%0.1f\n"), aperture);
10096 printf (_("Focal length: %0.1f mm\n"), focal_len);
10097 printf (_("Embedded ICC profile: %s\n"), profile_length ? _("yes"):_("no"));
10098 printf (_("Number of raw images: %d\n"), is_raw);
10099 if (pixel_aspect != 1)
10100 printf (_("Pixel Aspect Ratio: %0.6f\n"), pixel_aspect);
10102 printf (_("Thumb size: %4d x %d\n"), thumb_width, thumb_height);
10103 printf (_("Full size: %4d x %d\n"), raw_width, raw_height);
10106 // else if (!is_raw)
10107 // fprintf (stderr,_("Cannot decode file %s\n"), ifname);
10108 if (!is_raw) goto next;
10109 shrink = filters && (half_size || (!identify_only &&
10110 (threshold || aber[0] != 1 || aber[2] != 1)));
10111 iheight = (height + shrink) >> shrink;
10112 iwidth = (width + shrink) >> shrink;
10113 if (identify_only) {
10115 if (document_mode == 3) {
10116 top_margin = left_margin = fuji_width = 0;
10117 height = raw_height;
10120 iheight = (height + shrink) >> shrink;
10121 iwidth = (width + shrink) >> shrink;
10122 if (use_fuji_rotate) {
10124 fuji_width = (fuji_width - 1 + shrink) >> shrink;
10125 iwidth = fuji_width / sqrt(0.5);
10126 iheight = (iheight - fuji_width) / sqrt(0.5);
10128 if (pixel_aspect < 1) iheight = iheight / pixel_aspect + 0.5;
10129 if (pixel_aspect > 1) iwidth = iwidth * pixel_aspect + 0.5;
10133 SWAP(iheight,iwidth);
10134 printf (_("Image size: %4d x %d\n"), width, height);
10135 printf (_("Output size: %4d x %d\n"), iwidth, iheight);
10136 printf (_("Raw colors: %d"), colors);
10138 int fhigh = 2, fwide = 2;
10139 if ((filters ^ (filters >> 8)) & 0xff) fhigh = 4;
10140 if ((filters ^ (filters >> 16)) & 0xffff) fhigh = 8;
10141 if (filters == 1) fhigh = fwide = 16;
10142 if (filters == 9) fhigh = fwide = 6;
10143 printf (_("\nFilter pattern: "));
10144 for (i=0; i < fhigh; i++)
10145 for (c = i && putchar('/') && 0; c < fwide; c++)
10146 putchar (cdesc[fcol(i,c)]);
10148 printf (_("\nDaylight multipliers:"));
10149 FORCC printf (" %f", pre_mul[c]);
10150 if (cam_mul[0] > 0) {
10151 printf (_("\nCamera multipliers:"));
10152 FORC4 printf (" %f", cam_mul[c]);
10158 // printf (_("%s is a %s %s image.\n"), ifname, make, model);
10164 meta_data = (char *) malloc (meta_length);
10165 merror (meta_data, "main()");
10167 if (filters || colors == 1) {
10168 raw_image = (ushort *) calloc ((raw_height+7), raw_width*2);
10169 merror (raw_image, "main()");
10171 image = (ushort (*)[4]) calloc (iheight, iwidth*sizeof *image);
10172 merror (image, "main()");
10175 fprintf (stderr,_("Loading %s %s image from %s ...\n"),
10176 make, model, ifname);
10177 if (shot_select >= is_raw)
10178 fprintf (stderr,_("%s: \"-s %d\" requests a nonexistent image!\n"),
10179 ifname, shot_select);
10180 fseeko (ifp, data_offset, SEEK_SET);
10181 if (raw_image && read_from_stdin)
10182 fread (raw_image, 2, raw_height*raw_width, stdin);
10184 (this->*load_raw)();
10185 if (document_mode == 3) {
10186 top_margin = left_margin = fuji_width = 0;
10187 height = raw_height;
10190 iheight = (height + shrink) >> shrink;
10191 iwidth = (width + shrink) >> shrink;
10193 image = (ushort (*)[4]) calloc (iheight, iwidth*sizeof *image);
10194 merror (image, "main()");
10195 crop_masked_pixels();
10198 if (zero_is_bad) remove_zeroes();
10199 bad_pixels (bpfile);
10200 if (dark_frame) subtract (dark_frame);
10201 quality = 2 + !fuji_width;
10202 if (user_qual >= 0) quality = user_qual;
10204 FORC3 if (i > cblack[c]) i = cblack[c];
10205 FORC4 cblack[c] -= i;
10208 FORC (cblack[4] * cblack[5])
10209 if (i > cblack[6+c]) i = cblack[6+c];
10210 FORC (cblack[4] * cblack[5])
10213 if (user_black >= 0) black = user_black;
10214 FORC4 cblack[c] += black;
10215 if (user_sat > 0) maximum = user_sat;
10220 if (document_mode || load_raw == &CLASS foveon_dp_load_raw) {
10221 for (i=0; i < height*width*4; i++)
10222 if ((short) image[0][i] < 0) image[0][i] = 0;
10223 } else foveon_interpolate();
10224 } else if (document_mode < 2)
10227 if (filters && !document_mode) {
10230 else if (quality == 1 || colors > 3)
10232 else if (quality == 2 && filters > 1000)
10234 else if (filters == 9)
10235 xtrans_interpolate (quality*2-3);
10240 for (colors=3, i=0; i < height*width; i++)
10241 image[i][1] = (image[i][1] + image[i][3]) >> 1;
10242 if (!is_foveon && colors == 3) median_filter();
10243 if (!is_foveon && highlight == 2) blend_highlights();
10244 if (!is_foveon && highlight > 2) recover_highlights();
10245 if (use_fuji_rotate) fuji_rotate();
10247 if (cam_profile) apply_profile (cam_profile, out_profile);
10250 if (use_fuji_rotate) stretch();
10252 if (write_fun == &CLASS jpeg_thumb)
10253 write_ext = ".jpg";
10254 else if (output_tiff && write_fun == &CLASS write_ppm_tiff)
10255 write_ext = ".tiff";
10257 write_ext = ".pgm\0.ppm\0.ppm\0.pam" + colors*5-5;
10258 ofname = (char *) malloc (strlen(ifname) + 64);
10259 merror (ofname, "main()");
10260 if (write_to_stdout)
10261 strcpy (ofname,_("standard output"));
10263 strcpy (ofname, ifname);
10264 if ((cp = strrchr (ofname, '.'))) *cp = 0;
10266 sprintf (ofname+strlen(ofname), "_%0*d",
10267 snprintf(0,0,"%d",is_raw-1), shot_select);
10268 if (thumbnail_only)
10269 strcat (ofname, ".thumb");
10270 strcat (ofname, write_ext);
10271 ofp = fopen (ofname, "wb");
10279 fprintf (stderr,_("Writing data to %s ...\n"), ofname);
10280 (this->*write_fun)();
10282 if (ofp != stdout) fclose(ofp);
10284 if (meta_data) free (meta_data);
10285 if (ofname) free (ofname);
10286 if (oprof) free (oprof);
10287 if (image) free (image);
10289 if (++shot_select < is_raw) arg--;
10290 else shot_select = 0;