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 const double DCRaw_data::xyz_rgb[3][3] = { /* XYZ from RGB */
97 { 0.412453, 0.357580, 0.180423 },
98 { 0.212671, 0.715160, 0.072169 },
99 { 0.019334, 0.119193, 0.950227 } };
100 const float DCRaw_data::d65_white[3] = {
101 0.950456, 1.000000, 1.088754 };
104 All global variables are defined here, and all functions that
105 access them are prefixed with "CLASS". Note that a thread-safe
106 C++ class cannot have non-const static local variables.
109 #define FORC(cnt) for (c=0; c < cnt; c++)
110 #define FORC3 FORC(3)
111 #define FORC4 FORC(4)
112 #define FORCC FORC(colors)
114 #define SQR(x) ((x)*(x))
115 #define ABS(x) (((int)(x) ^ ((int)(x) >> 31)) - ((int)(x) >> 31))
116 #define MIN(a,b) ((a) < (b) ? (a) : (b))
117 #define MAX(a,b) ((a) > (b) ? (a) : (b))
118 #define LIM(x,min,max) MAX(min,MIN(x,max))
119 #define ULIM(x,y,z) ((y) < (z) ? LIM(x,y,z) : LIM(x,z,y))
120 #define CLIP(x) LIM((int)(x),0,65535)
121 #define SWAP(a,b) { a=a+b; b=a-b; a=a-b; }
122 #define ZERO(var) memset(&var, 0, sizeof var)
124 In order to inline this calculation, I make the risky
125 assumption that all filter patterns can be described
126 by a repeating pattern of eight rows and two columns
128 Do not use the FC or BAYER macros with the Leaf CatchLight,
129 because its pattern is 16x16, not 2x8.
131 Return values are either 0/1/2/3 = G/M/C/Y or 0/1/2/3 = R/G1/B/G2
133 PowerShot 600 PowerShot A50 PowerShot Pro70 Pro90 & G1
134 0xe1e4e1e4: 0x1b4e4b1e: 0x1e4b4e1b: 0xb4b4b4b4:
136 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5
137 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
138 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
139 2 M G M G M G 2 Y C Y C Y C 2 C Y C Y C Y
140 3 C Y C Y C Y 3 G M G M G M 3 G M G M G M
141 4 C Y C Y C Y 4 Y C Y C Y C
142 PowerShot A5 5 G M G M G M 5 G M G M G M
143 0x1e4e1e4e: 6 Y C Y C Y C 6 C Y C Y C Y
144 7 M G M G M G 7 M G M G M G
151 All RGB cameras use one of these Bayer grids:
153 0x16161616: 0x61616161: 0x49494949: 0x94949494:
155 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5
156 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
157 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
158 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
159 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
162 #define RAW(row,col) \
163 raw_image[(row)*raw_width+(col)]
165 #define FC(row,col) \
166 (filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)
168 #define BAYER(row,col) \
169 image[((row) >> shrink)*iwidth + ((col) >> shrink)][FC(row,col)]
171 #define BAYER2(row,col) \
172 image[((row) >> shrink)*iwidth + ((col) >> shrink)][fcol(row,col)]
174 int CLASS fcol (int row, int col)
176 static const char filter[16][16] =
177 { { 2,1,1,3,2,3,2,0,3,2,3,0,1,2,1,0 },
178 { 0,3,0,2,0,1,3,1,0,1,1,2,0,3,3,2 },
179 { 2,3,3,2,3,1,1,3,3,1,2,1,2,0,0,3 },
180 { 0,1,0,1,0,2,0,2,2,0,3,0,1,3,2,1 },
181 { 3,1,1,2,0,1,0,2,1,3,1,3,0,1,3,0 },
182 { 2,0,0,3,3,2,3,1,2,0,2,0,3,2,2,1 },
183 { 2,3,3,1,2,1,2,1,2,1,1,2,3,0,0,1 },
184 { 1,0,0,2,3,0,0,3,0,3,0,3,2,1,2,3 },
185 { 2,3,3,1,1,2,1,0,3,2,3,0,2,3,1,3 },
186 { 1,0,2,0,3,0,3,2,0,1,1,2,0,1,0,2 },
187 { 0,1,1,3,3,2,2,1,1,3,3,0,2,1,3,2 },
188 { 2,3,2,0,0,1,3,0,2,0,1,2,3,0,1,0 },
189 { 1,3,1,2,3,2,3,2,0,2,0,1,1,0,3,0 },
190 { 0,2,0,3,1,0,0,1,1,3,3,2,3,2,2,1 },
191 { 2,1,3,2,3,1,2,1,0,3,0,2,0,2,0,2 },
192 { 0,3,1,0,0,2,0,3,2,1,3,1,1,3,1,3 } };
194 if (filters == 1) return filter[(row+top_margin)&15][(col+left_margin)&15];
195 if (filters == 9) return xtrans[(row+6) % 6][(col+6) % 6];
202 DCRaw_data *data = (DCRaw_data *)this;
203 memset(data, 0, sizeof(*data));
204 // non-zero init data
205 aber[0] = aber[1] = aber[2] = aber[3] = 1;
206 gamm[0] = 0.45; gamm[1] = 4.5;
208 use_camera_matrix = 1;
211 greybox[2] = UINT_MAX; greybox[3] = UINT_MAX;
215 char *my_memmem (char *haystack, size_t haystacklen,
216 char *needle, size_t needlelen)
219 for (c = haystack; c <= haystack + haystacklen - needlelen; c++)
220 if (!memcmp (c, needle, needlelen))
224 #define memmem my_memmem
225 char *my_strcasestr (char *haystack, const char *needle)
228 for (c = haystack; *c; c++)
229 if (!strncasecmp(c, needle, strlen(needle)))
233 #define strcasestr my_strcasestr
236 void CLASS merror (void *ptr, const char *where)
239 fprintf (stderr,_("%s: Out of memory in %s\n"), ifname, where);
240 longjmp (failure, 1);
246 fprintf (stderr, "%s: ", ifname);
248 fprintf (stderr,_("Unexpected end of file\n"));
250 fprintf (stderr,_("Corrupt data near 0x%jx\n"), (INT64) ftello(ifp));
255 ushort CLASS sget2 (uchar *s)
257 if (order == 0x4949) /* "II" means little-endian */
258 return s[0] | s[1] << 8;
259 else /* "MM" means big-endian */
260 return s[0] << 8 | s[1];
265 uchar str[2] = { 0xff,0xff };
266 fread (str, 1, 2, ifp);
270 unsigned CLASS sget4 (uchar *s)
273 return s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24;
275 return s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3];
277 #define sget4(s) sget4((uchar *)s)
279 unsigned CLASS get4()
281 uchar str[4] = { 0xff,0xff,0xff,0xff };
282 fread (str, 1, 4, ifp);
286 unsigned CLASS getint (int type)
288 return type == 3 ? get2() : get4();
291 float CLASS int_to_float (int i)
293 union { int i; float f; } u;
298 double CLASS getreal (int type)
300 union { char c[8]; double d; } u;
304 case 3: return (unsigned short) get2();
305 case 4: return (unsigned int) get4();
306 case 5: u.d = (unsigned int) get4();
307 return u.d / (unsigned int) get4();
308 case 8: return (signed short) get2();
309 case 9: return (signed int) get4();
310 case 10: u.d = (signed int) get4();
311 return u.d / (signed int) get4();
312 case 11: return int_to_float (get4());
314 rev = 7 * ((order == 0x4949) == (ntohs(0x1234) == 0x1234));
315 for (i=0; i < 8; i++)
316 u.c[i ^ rev] = fgetc(ifp);
318 default: return fgetc(ifp);
322 void CLASS read_shorts (ushort *pixel, int count)
324 if (fread (pixel, 2, count, ifp) < count) derror();
325 if ((order == 0x4949) == (ntohs(0x1234) == 0x1234))
326 swab (pixel, pixel, count*2);
329 void CLASS cubic_spline (const int *x_, const int *y_, const int len)
331 float **A, *b, *c, *d, *x, *y;
334 A = (float **) calloc (((2*len + 4)*sizeof **A + sizeof *A), 2*len);
336 A[0] = (float *) (A + 2*len);
337 for (i = 1; i < 2*len; i++)
338 A[i] = A[0] + 2*len*i;
339 y = len + (x = i + (d = i + (c = i + (b = A[0] + i*i))));
340 for (i = 0; i < len; i++) {
341 x[i] = x_[i] / 65535.0;
342 y[i] = y_[i] / 65535.0;
344 for (i = len-1; i > 0; i--) {
345 b[i] = (y[i] - y[i-1]) / (x[i] - x[i-1]);
346 d[i-1] = x[i] - x[i-1];
348 for (i = 1; i < len-1; i++) {
349 A[i][i] = 2 * (d[i-1] + d[i]);
354 A[i][len-1] = 6 * (b[i+1] - b[i]);
356 for(i = 1; i < len-2; i++) {
357 float v = A[i+1][i] / A[i][i];
358 for(j = 1; j <= len-1; j++)
359 A[i+1][j] -= v * A[i][j];
361 for(i = len-2; i > 0; i--) {
363 for(j = i; j <= len-2; j++)
365 c[i] = (A[i][len-1] - acc) / A[i][i];
367 for (i = 0; i < 0x10000; i++) {
368 float x_out = (float)(i / 65535.0);
370 for (j = 0; j < len-1; j++) {
371 if (x[j] <= x_out && x_out <= x[j+1]) {
372 float v = x_out - x[j];
374 ((y[j+1] - y[j]) / d[j] - (2 * d[j] * c[j] + c[j+1] * d[j])/6) * v
375 + (c[j] * 0.5) * v*v + ((c[j+1] - c[j]) / (6 * d[j])) * v*v*v;
378 curve[i] = y_out < 0.0 ? 0 : (y_out >= 1.0 ? 65535 :
379 (ushort)(y_out * 65535.0 + 0.5));
384 void CLASS canon_600_fixed_wb (int temp)
386 static const short mul[4][5] = {
387 { 667, 358,397,565,452 },
388 { 731, 390,367,499,517 },
389 { 1119, 396,348,448,537 },
390 { 1399, 485,431,508,688 } };
395 if (*mul[lo] <= temp) break;
396 for (hi=0; hi < 3; hi++)
397 if (*mul[hi] >= temp) break;
399 frac = (float) (temp - *mul[lo]) / (*mul[hi] - *mul[lo]);
400 for (i=1; i < 5; i++)
401 pre_mul[i-1] = 1 / (frac * mul[hi][i] + (1-frac) * mul[lo][i]);
404 /* Return values: 0 = white 1 = near white 2 = not white */
405 int CLASS canon_600_color (int ratio[2], int mar)
407 int clipped=0, target, miss;
411 { ratio[1] = -104; clipped = 1; }
413 { ratio[1] = 12; clipped = 1; }
415 if (ratio[1] < -264 || ratio[1] > 461) return 2;
417 { ratio[1] = -50; clipped = 1; }
419 { ratio[1] = 307; clipped = 1; }
421 target = flash_used || ratio[1] < 197
422 ? -38 - (398 * ratio[1] >> 10)
423 : -123 + (48 * ratio[1] >> 10);
424 if (target - mar <= ratio[0] &&
425 target + 20 >= ratio[0] && !clipped) return 0;
426 miss = target - ratio[0];
427 if (abs(miss) >= mar*4) return 2;
428 if (miss < -20) miss = -20;
429 if (miss > mar) miss = mar;
430 ratio[0] = target - miss;
434 void CLASS canon_600_auto_wb()
436 int mar, row, col, i, j, st, count[] = { 0,0 };
437 int test[8], total[2][8], ratio[2][2], stat[2];
439 memset (&total, 0, sizeof total);
441 if (i < 10) mar = 150;
442 else if (i > 12) mar = 20;
443 else mar = 280 - 20 * i;
444 if (flash_used) mar = 80;
445 for (row=14; row < height-14; row+=4)
446 for (col=10; col < width; col+=2) {
447 for (i=0; i < 8; i++)
448 test[(i & 4) + FC(row+(i >> 1),col+(i & 1))] =
449 BAYER(row+(i >> 1),col+(i & 1));
450 for (i=0; i < 8; i++)
451 if (test[i] < 150 || test[i] > 1500) goto next;
452 for (i=0; i < 4; i++)
453 if (abs(test[i] - test[i+4]) > 50) goto next;
454 for (i=0; i < 2; i++) {
455 for (j=0; j < 4; j+=2)
456 ratio[i][j >> 1] = ((test[i*4+j+1]-test[i*4+j]) << 10) / test[i*4+j];
457 stat[i] = canon_600_color (ratio[i], mar);
459 if ((st = stat[0] | stat[1]) > 1) goto next;
460 for (i=0; i < 2; i++)
462 for (j=0; j < 2; j++)
463 test[i*4+j*2+1] = test[i*4+j*2] * (0x400 + ratio[i][j]) >> 10;
464 for (i=0; i < 8; i++)
465 total[st][i] += test[i];
469 if (count[0] | count[1]) {
470 st = count[0]*200 < count[1];
471 for (i=0; i < 4; i++)
472 pre_mul[i] = 1.0 / (total[st][i] + total[st][i+4]);
476 void CLASS canon_600_coeff()
478 static const short table[6][12] = {
479 { -190,702,-1878,2390, 1861,-1349,905,-393, -432,944,2617,-2105 },
480 { -1203,1715,-1136,1648, 1388,-876,267,245, -1641,2153,3921,-3409 },
481 { -615,1127,-1563,2075, 1437,-925,509,3, -756,1268,2519,-2007 },
482 { -190,702,-1886,2398, 2153,-1641,763,-251, -452,964,3040,-2528 },
483 { -190,702,-1878,2390, 1861,-1349,905,-393, -432,944,2617,-2105 },
484 { -807,1319,-1785,2297, 1388,-876,769,-257, -230,742,2067,-1555 } };
488 mc = pre_mul[1] / pre_mul[2];
489 yc = pre_mul[3] / pre_mul[2];
490 if (mc > 1 && mc <= 1.28 && yc < 0.8789) t=1;
491 if (mc > 1.28 && mc <= 2) {
492 if (yc < 0.8789) t=3;
493 else if (yc <= 2) t=4;
496 for (raw_color = i=0; i < 3; i++)
497 FORCC rgb_cam[i][c] = table[t][i*4 + c] / 1024.0;
500 void CLASS canon_600_load_raw()
502 uchar data[1120], *dp;
506 for (irow=row=0; irow < height; irow++) {
507 if (fread (data, 1, 1120, ifp) < 1120) derror();
508 pix = raw_image + row*raw_width;
509 for (dp=data; dp < data+1120; dp+=10, pix+=8) {
510 pix[0] = (dp[0] << 2) + (dp[1] >> 6 );
511 pix[1] = (dp[2] << 2) + (dp[1] >> 4 & 3);
512 pix[2] = (dp[3] << 2) + (dp[1] >> 2 & 3);
513 pix[3] = (dp[4] << 2) + (dp[1] & 3);
514 pix[4] = (dp[5] << 2) + (dp[9] & 3);
515 pix[5] = (dp[6] << 2) + (dp[9] >> 2 & 3);
516 pix[6] = (dp[7] << 2) + (dp[9] >> 4 & 3);
517 pix[7] = (dp[8] << 2) + (dp[9] >> 6 );
519 if ((row+=2) > height) row = 1;
523 void CLASS canon_600_correct()
526 static const short mul[4][2] =
527 { { 1141,1145 }, { 1128,1109 }, { 1178,1149 }, { 1128,1109 } };
529 for (row=0; row < height; row++)
530 for (col=0; col < width; col++) {
531 if ((val = BAYER(row,col) - black) < 0) val = 0;
532 val = val * mul[row & 3][col & 1] >> 9;
533 BAYER(row,col) = val;
535 canon_600_fixed_wb(1311);
538 maximum = (0x3ff - black) * 1109 >> 9;
542 int CLASS canon_s2is()
546 for (row=0; row < 100; row++) {
547 fseek (ifp, row*3340 + 3284, SEEK_SET);
548 if (getc(ifp) > 15) return 1;
553 unsigned CLASS getbithuff (int nbits, ushort *huff)
559 if (nbits > 25) return 0;
561 return gbh_bitbuf = gbh_vbits = gbh_reset = 0;
562 if (nbits == 0 || gbh_vbits < 0) return 0;
563 bitbuf = gbh_bitbuf; vbits = gbh_vbits; reset = gbh_reset;
564 while (!reset && vbits < nbits && (c = fgetc(ifp)) != EOF &&
565 !(reset = zero_after_ff && c == 0xff && fgetc(ifp))) {
566 bitbuf = (bitbuf << 8) + (uchar) c;
569 c = bitbuf << (32-vbits) >> (32-nbits);
571 vbits -= huff[c] >> 8;
575 if (vbits < 0) derror();
576 gbh_bitbuf = bitbuf; gbh_vbits = vbits; gbh_reset = reset;
580 #define getbits(n) getbithuff(n,0)
581 #define gethuff(h) getbithuff(*h,h+1)
584 Construct a decode tree according the specification in *source.
585 The first 16 bytes specify how many codes should be 1-bit, 2-bit
586 3-bit, etc. Bytes after that are the leaf values.
588 For example, if the source is
590 { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0,
591 0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff },
609 ushort * CLASS make_decoder_ref (const uchar **source)
611 int max, len, h, i, j;
615 count = (*source += 16) - 17;
616 for (max=16; max && !count[max]; max--);
617 huff = (ushort *) calloc (1 + (1 << max), sizeof *huff);
618 merror (huff, "make_decoder()");
620 for (h=len=1; len <= max; len++)
621 for (i=0; i < count[len]; i++, ++*source)
622 for (j=0; j < 1 << (max-len); j++)
624 huff[h++] = len << 8 | **source;
628 ushort * CLASS make_decoder (const uchar *source)
630 return make_decoder_ref (&source);
633 void CLASS crw_init_tables (unsigned table, ushort *huff[2])
635 static const uchar first_tree[3][29] = {
636 { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0,
637 0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff },
638 { 0,2,2,3,1,1,1,1,2,0,0,0,0,0,0,0,
639 0x03,0x02,0x04,0x01,0x05,0x00,0x06,0x07,0x09,0x08,0x0a,0x0b,0xff },
640 { 0,0,6,3,1,1,2,0,0,0,0,0,0,0,0,0,
641 0x06,0x05,0x07,0x04,0x08,0x03,0x09,0x02,0x00,0x0a,0x01,0x0b,0xff },
643 static const uchar second_tree[3][180] = {
644 { 0,2,2,2,1,4,2,1,2,5,1,1,0,0,0,139,
645 0x03,0x04,0x02,0x05,0x01,0x06,0x07,0x08,
646 0x12,0x13,0x11,0x14,0x09,0x15,0x22,0x00,0x21,0x16,0x0a,0xf0,
647 0x23,0x17,0x24,0x31,0x32,0x18,0x19,0x33,0x25,0x41,0x34,0x42,
648 0x35,0x51,0x36,0x37,0x38,0x29,0x79,0x26,0x1a,0x39,0x56,0x57,
649 0x28,0x27,0x52,0x55,0x58,0x43,0x76,0x59,0x77,0x54,0x61,0xf9,
650 0x71,0x78,0x75,0x96,0x97,0x49,0xb7,0x53,0xd7,0x74,0xb6,0x98,
651 0x47,0x48,0x95,0x69,0x99,0x91,0xfa,0xb8,0x68,0xb5,0xb9,0xd6,
652 0xf7,0xd8,0x67,0x46,0x45,0x94,0x89,0xf8,0x81,0xd5,0xf6,0xb4,
653 0x88,0xb1,0x2a,0x44,0x72,0xd9,0x87,0x66,0xd4,0xf5,0x3a,0xa7,
654 0x73,0xa9,0xa8,0x86,0x62,0xc7,0x65,0xc8,0xc9,0xa1,0xf4,0xd1,
655 0xe9,0x5a,0x92,0x85,0xa6,0xe7,0x93,0xe8,0xc1,0xc6,0x7a,0x64,
656 0xe1,0x4a,0x6a,0xe6,0xb3,0xf1,0xd3,0xa5,0x8a,0xb2,0x9a,0xba,
657 0x84,0xa4,0x63,0xe5,0xc5,0xf3,0xd2,0xc4,0x82,0xaa,0xda,0xe4,
658 0xf2,0xca,0x83,0xa3,0xa2,0xc3,0xea,0xc2,0xe2,0xe3,0xff,0xff },
659 { 0,2,2,1,4,1,4,1,3,3,1,0,0,0,0,140,
660 0x02,0x03,0x01,0x04,0x05,0x12,0x11,0x06,
661 0x13,0x07,0x08,0x14,0x22,0x09,0x21,0x00,0x23,0x15,0x31,0x32,
662 0x0a,0x16,0xf0,0x24,0x33,0x41,0x42,0x19,0x17,0x25,0x18,0x51,
663 0x34,0x43,0x52,0x29,0x35,0x61,0x39,0x71,0x62,0x36,0x53,0x26,
664 0x38,0x1a,0x37,0x81,0x27,0x91,0x79,0x55,0x45,0x28,0x72,0x59,
665 0xa1,0xb1,0x44,0x69,0x54,0x58,0xd1,0xfa,0x57,0xe1,0xf1,0xb9,
666 0x49,0x47,0x63,0x6a,0xf9,0x56,0x46,0xa8,0x2a,0x4a,0x78,0x99,
667 0x3a,0x75,0x74,0x86,0x65,0xc1,0x76,0xb6,0x96,0xd6,0x89,0x85,
668 0xc9,0xf5,0x95,0xb4,0xc7,0xf7,0x8a,0x97,0xb8,0x73,0xb7,0xd8,
669 0xd9,0x87,0xa7,0x7a,0x48,0x82,0x84,0xea,0xf4,0xa6,0xc5,0x5a,
670 0x94,0xa4,0xc6,0x92,0xc3,0x68,0xb5,0xc8,0xe4,0xe5,0xe6,0xe9,
671 0xa2,0xa3,0xe3,0xc2,0x66,0x67,0x93,0xaa,0xd4,0xd5,0xe7,0xf8,
672 0x88,0x9a,0xd7,0x77,0xc4,0x64,0xe2,0x98,0xa5,0xca,0xda,0xe8,
673 0xf3,0xf6,0xa9,0xb2,0xb3,0xf2,0xd2,0x83,0xba,0xd3,0xff,0xff },
674 { 0,0,6,2,1,3,3,2,5,1,2,2,8,10,0,117,
675 0x04,0x05,0x03,0x06,0x02,0x07,0x01,0x08,
676 0x09,0x12,0x13,0x14,0x11,0x15,0x0a,0x16,0x17,0xf0,0x00,0x22,
677 0x21,0x18,0x23,0x19,0x24,0x32,0x31,0x25,0x33,0x38,0x37,0x34,
678 0x35,0x36,0x39,0x79,0x57,0x58,0x59,0x28,0x56,0x78,0x27,0x41,
679 0x29,0x77,0x26,0x42,0x76,0x99,0x1a,0x55,0x98,0x97,0xf9,0x48,
680 0x54,0x96,0x89,0x47,0xb7,0x49,0xfa,0x75,0x68,0xb6,0x67,0x69,
681 0xb9,0xb8,0xd8,0x52,0xd7,0x88,0xb5,0x74,0x51,0x46,0xd9,0xf8,
682 0x3a,0xd6,0x87,0x45,0x7a,0x95,0xd5,0xf6,0x86,0xb4,0xa9,0x94,
683 0x53,0x2a,0xa8,0x43,0xf5,0xf7,0xd4,0x66,0xa7,0x5a,0x44,0x8a,
684 0xc9,0xe8,0xc8,0xe7,0x9a,0x6a,0x73,0x4a,0x61,0xc7,0xf4,0xc6,
685 0x65,0xe9,0x72,0xe6,0x71,0x91,0x93,0xa6,0xda,0x92,0x85,0x62,
686 0xf3,0xc5,0xb2,0xa4,0x84,0xba,0x64,0xa5,0xb3,0xd2,0x81,0xe5,
687 0xd3,0xaa,0xc4,0xca,0xf2,0xb1,0xe4,0xd1,0x83,0x63,0xea,0xc3,
688 0xe2,0x82,0xf1,0xa3,0xc2,0xa1,0xc1,0xe3,0xa2,0xe1,0xff,0xff }
690 if (table > 2) table = 2;
691 huff[0] = make_decoder ( first_tree[table]);
692 huff[1] = make_decoder (second_tree[table]);
696 Return 0 if the image starts with compressed data,
697 1 if it starts with uncompressed low-order bits.
699 In Canon compressed data, 0xff is always followed by 0x00.
701 int CLASS canon_has_lowbits()
706 fseek (ifp, 0, SEEK_SET);
707 fread (test, 1, sizeof test, ifp);
708 for (i=540; i < sizeof test - 1; i++)
709 if (test[i] == 0xff) {
710 if (test[i+1]) return 1;
716 void CLASS canon_load_raw()
718 ushort *pixel, *prow, *huff[2];
719 int nblocks, lowbits, i, c, row, r, save, val;
720 int block, diffbuf[64], leaf, len, diff, carry=0, pnum=0, base[2];
722 crw_init_tables (tiff_compress, huff);
723 lowbits = canon_has_lowbits();
724 if (!lowbits) maximum = 0x3ff;
725 fseek (ifp, 540 + lowbits*raw_height*raw_width/4, SEEK_SET);
728 for (row=0; row < raw_height; row+=8) {
729 pixel = raw_image + row*raw_width;
730 nblocks = MIN (8, raw_height-row) * raw_width >> 6;
731 for (block=0; block < nblocks; block++) {
732 memset (diffbuf, 0, sizeof diffbuf);
733 for (i=0; i < 64; i++ ) {
734 leaf = gethuff(huff[i > 0]);
735 if (leaf == 0 && i) break;
736 if (leaf == 0xff) continue;
739 if (len == 0) continue;
741 if ((diff & (1 << (len-1))) == 0)
742 diff -= (1 << len) - 1;
743 if (i < 64) diffbuf[i] = diff;
747 for (i=0; i < 64; i++ ) {
748 if (pnum++ % raw_width == 0)
749 base[0] = base[1] = 512;
750 if ((pixel[(block << 6) + i] = base[i & 1] += diffbuf[i]) >> 10)
756 fseek (ifp, 26 + row*raw_width/4, SEEK_SET);
757 for (prow=pixel, i=0; i < raw_width*2; i++) {
759 for (r=0; r < 8; r+=2, prow++) {
760 val = (*prow << 2) + ((c >> r) & 3);
761 if (raw_width == 2672 && val < 512) val += 2;
765 fseek (ifp, save, SEEK_SET);
768 FORC(2) free (huff[c]);
772 int algo, bits, high, wide, clrs, sraw, psv, restart, vpred[6];
773 ushort quant[64], idct[64], *huff[20], *free[20], *row;
776 int CLASS ljpeg_start (struct jhead *jh, int info_only)
782 memset (jh, 0, sizeof *jh);
783 jh->restart = INT_MAX;
784 if ((fgetc(ifp),fgetc(ifp)) != 0xd8) return 0;
786 if (!fread (data, 2, 2, ifp)) return 0;
787 tag = data[0] << 8 | data[1];
788 len = (data[2] << 8 | data[3]) - 2;
789 if (tag <= 0xff00) return 0;
790 fread (data, 1, len, ifp);
793 jh->sraw = ((data[7] >> 4) * (data[7] & 15) - 1) & 3;
796 jh->algo = tag & 0xff;
798 jh->high = data[1] << 8 | data[2];
799 jh->wide = data[3] << 8 | data[4];
800 jh->clrs = data[5] + jh->sraw;
801 if (len == 9 && !dng_version) getc(ifp);
804 if (info_only) break;
805 for (dp = data; dp < data+len && !((c = *dp++) & -20); )
806 jh->free[c] = jh->huff[c] = make_decoder_ref (&dp);
809 jh->psv = data[1+data[0]*2];
810 jh->bits -= data[3+data[0]*2] & 15;
813 FORC(64) jh->quant[c] = data[c*2+1] << 8 | data[c*2+2];
816 jh->restart = data[0] << 8 | data[1];
818 } while (tag != 0xffda);
819 if (jh->bits > 16 || jh->clrs > 6 ||
820 !jh->bits || !jh->high || !jh->wide || !jh->clrs) return 0;
821 if (info_only) return 1;
822 if (!jh->huff[0]) return 0;
823 FORC(19) if (!jh->huff[c+1]) jh->huff[c+1] = jh->huff[c];
825 FORC(4) jh->huff[2+c] = jh->huff[1];
826 FORC(jh->sraw) jh->huff[1+c] = jh->huff[0];
828 jh->row = (ushort *) calloc (jh->wide*jh->clrs, 4);
829 merror (jh->row, "ljpeg_start()");
830 return zero_after_ff = 1;
833 void CLASS ljpeg_end (struct jhead *jh)
836 FORC4 if (jh->free[c]) free (jh->free[c]);
840 int CLASS ljpeg_diff (ushort *huff)
845 if (len == 16 && (!dng_version || dng_version >= 0x1010000))
848 if ((diff & (1 << (len-1))) == 0)
849 diff -= (1 << len) - 1;
853 ushort * CLASS ljpeg_row (int jrow, struct jhead *jh)
855 int col, c, diff, pred, spred=0;
856 ushort mark=0, *row[3];
858 if (jrow * jh->wide % jh->restart == 0) {
859 FORC(6) jh->vpred[c] = 1 << (jh->bits-1);
861 fseek (ifp, -2, SEEK_CUR);
862 do mark = (mark << 8) + (c = fgetc(ifp));
863 while (c != EOF && mark >> 4 != 0xffd);
867 FORC3 row[c] = jh->row + jh->wide*jh->clrs*((jrow+c) & 1);
868 for (col=0; col < jh->wide; col++)
870 diff = ljpeg_diff (jh->huff[c]);
871 if (jh->sraw && c <= jh->sraw && (col | c))
873 else if (col) pred = row[0][-jh->clrs];
874 else pred = (jh->vpred[c] += diff) - diff;
875 if (jrow && col) switch (jh->psv) {
877 case 2: pred = row[1][0]; break;
878 case 3: pred = row[1][-jh->clrs]; break;
879 case 4: pred = pred + row[1][0] - row[1][-jh->clrs]; break;
880 case 5: pred = pred + ((row[1][0] - row[1][-jh->clrs]) >> 1); break;
881 case 6: pred = row[1][0] + ((pred - row[1][-jh->clrs]) >> 1); break;
882 case 7: pred = (pred + row[1][0]) >> 1; break;
885 if ((**row = pred + diff) >> jh->bits) derror();
886 if (c <= jh->sraw) spred = **row;
892 void CLASS lossless_jpeg_load_raw()
894 int jwide, jrow, jcol, val, jidx, i, j, row=0, col=0;
898 if (!ljpeg_start (&jh, 0)) return;
899 jwide = jh.wide * jh.clrs;
901 for (jrow=0; jrow < jh.high; jrow++) {
902 rp = ljpeg_row (jrow, &jh);
904 row = jrow & 1 ? height-1-jrow/2 : jrow/2;
905 for (jcol=0; jcol < jwide; jcol++) {
908 jidx = jrow*jwide + jcol;
909 i = jidx / (cr2_slice[1]*raw_height);
910 if ((j = i >= cr2_slice[0]))
912 jidx -= i * (cr2_slice[1]*raw_height);
913 row = jidx / cr2_slice[1+j];
914 col = jidx % cr2_slice[1+j] + i*cr2_slice[1];
916 if (raw_width == 3984 && (col -= 2) < 0)
917 col += (row--,raw_width);
918 if ((unsigned) row < raw_height) RAW(row,col) = val;
919 if (++col >= raw_width)
926 void CLASS canon_sraw_load_raw()
929 short *rp=0, (*ip)[4];
930 int jwide, slice, scol, ecol, row, col, jrow=0, jcol=0, pix[3], c;
931 int v[3]={0,0,0}, ver, hue;
934 if (!ljpeg_start (&jh, 0) || jh.clrs < 4) return;
935 jwide = (jh.wide >>= 1) * jh.clrs;
937 for (ecol=slice=0; slice <= cr2_slice[0]; slice++) {
939 ecol += cr2_slice[1] * 2 / jh.clrs;
940 if (!cr2_slice[0] || ecol > raw_width-1) ecol = raw_width & -2;
941 for (row=0; row < height; row += (jh.clrs >> 1) - 1) {
942 ip = (short (*)[4]) image + row*width;
943 for (col=scol; col < ecol; col+=2, jcol+=jh.clrs) {
944 if ((jcol %= jwide) == 0)
945 rp = (short *) ljpeg_row (jrow++, &jh);
946 if (col >= width) continue;
948 ip[col + (c >> 1)*width + (c & 1)][0] = rp[jcol+c];
949 ip[col][1] = rp[jcol+jh.clrs-2] - 16384;
950 ip[col][2] = rp[jcol+jh.clrs-1] - 16384;
954 for (cp=model2; *cp && !isdigit(*cp); cp++);
955 sscanf (cp, "%d.%d.%d", v, v+1, v+2);
956 ver = (v[0]*1000 + v[1])*1000 + v[2];
957 hue = (jh.sraw+1) << 2;
958 if (unique_id >= 0x80000281 || (unique_id == 0x80000218 && ver > 1000006))
960 ip = (short (*)[4]) image;
962 for (row=0; row < height; row++, ip+=width) {
963 if (row & (jh.sraw >> 1)) {
964 for (col=0; col < width; col+=2)
965 for (c=1; c < 3; c++)
967 ip[col][c] = ip[col-width][c];
968 else ip[col][c] = (ip[col-width][c] + ip[col+width][c] + 1) >> 1;
970 for (col=1; col < width; col+=2)
971 for (c=1; c < 3; c++)
973 ip[col][c] = ip[col-1][c];
974 else ip[col][c] = (ip[col-1][c] + ip[col+1][c] + 1) >> 1;
976 for ( ; rp < ip[0]; rp+=4) {
977 if (unique_id == 0x80000218 ||
978 unique_id == 0x80000250 ||
979 unique_id == 0x80000261 ||
980 unique_id == 0x80000281 ||
981 unique_id == 0x80000287) {
982 rp[1] = (rp[1] << 2) + hue;
983 rp[2] = (rp[2] << 2) + hue;
984 pix[0] = rp[0] + (( 50*rp[1] + 22929*rp[2]) >> 14);
985 pix[1] = rp[0] + ((-5640*rp[1] - 11751*rp[2]) >> 14);
986 pix[2] = rp[0] + ((29040*rp[1] - 101*rp[2]) >> 14);
988 if (unique_id < 0x80000218) rp[0] -= 512;
989 pix[0] = rp[0] + rp[2];
990 pix[2] = rp[0] + rp[1];
991 pix[1] = rp[0] + ((-778*rp[1] - (rp[2] << 11)) >> 12);
993 FORC3 rp[c] = CLIP(pix[c] * sraw_mul[c] >> 10);
999 void CLASS adobe_copy_pixel (unsigned row, unsigned col, ushort **rp)
1003 if (tiff_samples == 2 && shot_select) (*rp)++;
1005 if (row < raw_height && col < raw_width)
1006 RAW(row,col) = curve[**rp];
1007 *rp += tiff_samples;
1009 if (row < height && col < width)
1011 image[row*width+col][c] = curve[(*rp)[c]];
1012 *rp += tiff_samples;
1014 if (tiff_samples == 2 && shot_select) (*rp)--;
1017 void CLASS ljpeg_idct (struct jhead *jh)
1019 int c, i, j, len, skip, coef;
1020 float work[3][8][8], *cs = ljpeg_cs;
1021 static const uchar zigzag[80] =
1022 { 0, 1, 8,16, 9, 2, 3,10,17,24,32,25,18,11, 4, 5,12,19,26,33,
1023 40,48,41,34,27,20,13, 6, 7,14,21,28,35,42,49,56,57,50,43,36,
1024 29,22,15,23,30,37,44,51,58,59,52,45,38,31,39,46,53,60,61,54,
1025 47,55,62,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63 };
1028 FORC(106) cs[c] = cos((c & 31)*M_PI/16)/2;
1029 memset (work, 0, sizeof work);
1030 work[0][0][0] = jh->vpred[0] += ljpeg_diff (jh->huff[0]) * jh->quant[0];
1031 for (i=1; i < 64; i++ ) {
1032 len = gethuff (jh->huff[16]);
1033 i += skip = len >> 4;
1034 if (!(len &= 15) && skip < 15) break;
1035 coef = getbits(len);
1036 if ((coef & (1 << (len-1))) == 0)
1037 coef -= (1 << len) - 1;
1038 ((float *)work)[zigzag[i]] = coef * jh->quant[i];
1040 FORC(8) work[0][0][c] *= M_SQRT1_2;
1041 FORC(8) work[0][c][0] *= M_SQRT1_2;
1042 for (i=0; i < 8; i++)
1043 for (j=0; j < 8; j++)
1044 FORC(8) work[1][i][j] += work[0][i][c] * cs[(j*2+1)*c];
1045 for (i=0; i < 8; i++)
1046 for (j=0; j < 8; j++)
1047 FORC(8) work[2][i][j] += work[1][c][j] * cs[(i*2+1)*c];
1049 FORC(64) jh->idct[c] = CLIP(((float *)work[2])[c]+0.5);
1052 void CLASS lossless_dng_load_raw()
1054 unsigned save, trow=0, tcol=0, jwide, jrow, jcol, row, col, i, j;
1058 while (trow < raw_height) {
1060 if (tile_length < INT_MAX)
1061 fseek (ifp, get4(), SEEK_SET);
1062 if (!ljpeg_start (&jh, 0)) break;
1064 if (filters) jwide *= jh.clrs;
1065 jwide /= MIN (is_raw, tiff_samples);
1068 jh.vpred[0] = 16384;
1070 for (jrow=0; jrow+7 < jh.high; jrow += 8) {
1071 for (jcol=0; jcol+7 < jh.wide; jcol += 8) {
1074 row = trow + jcol/tile_width + jrow*2;
1075 col = tcol + jcol%tile_width;
1076 for (i=0; i < 16; i+=2)
1077 for (j=0; j < 8; j++)
1078 adobe_copy_pixel (row+i, col+j, &rp);
1083 for (row=col=jrow=0; jrow < jh.high; jrow++) {
1084 rp = ljpeg_row (jrow, &jh);
1085 for (jcol=0; jcol < jwide; jcol++) {
1086 adobe_copy_pixel (trow+row, tcol+col, &rp);
1087 if (++col >= tile_width || col >= raw_width)
1088 row += 1 + (col = 0);
1092 fseek (ifp, save+4, SEEK_SET);
1093 if ((tcol += tile_width) >= raw_width)
1094 trow += tile_length + (tcol = 0);
1099 void CLASS packed_dng_load_raw()
1104 pixel = (ushort *) calloc (raw_width, tiff_samples*sizeof *pixel);
1105 merror (pixel, "packed_dng_load_raw()");
1106 for (row=0; row < raw_height; row++) {
1108 read_shorts (pixel, raw_width * tiff_samples);
1111 for (col=0; col < raw_width * tiff_samples; col++)
1112 pixel[col] = getbits(tiff_bps);
1114 for (rp=pixel, col=0; col < raw_width; col++)
1115 adobe_copy_pixel (row, col, &rp);
1120 void CLASS pentax_load_raw()
1122 ushort bit[2][15], huff[4097];
1123 int dep, row, col, diff, c, i;
1124 ushort vpred[2][2] = {{0,0},{0,0}}, hpred[2];
1126 fseek (ifp, meta_offset, SEEK_SET);
1127 dep = (get2() + 12) & 15;
1128 fseek (ifp, 12, SEEK_CUR);
1129 FORC(dep) bit[0][c] = get2();
1130 FORC(dep) bit[1][c] = fgetc(ifp);
1132 for (i=bit[0][c]; i <= ((bit[0][c]+(4096 >> bit[1][c])-1) & 4095); )
1133 huff[++i] = bit[1][c] << 8 | c;
1135 fseek (ifp, data_offset, SEEK_SET);
1137 for (row=0; row < raw_height; row++)
1138 for (col=0; col < raw_width; col++) {
1139 diff = ljpeg_diff (huff);
1140 if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
1141 else hpred[col & 1] += diff;
1142 RAW(row,col) = hpred[col & 1];
1143 if (hpred[col & 1] >> tiff_bps) derror();
1147 void CLASS nikon_load_raw()
1149 static const uchar nikon_tree[][32] = {
1150 { 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0, /* 12-bit lossy */
1151 5,4,3,6,2,7,1,0,8,9,11,10,12 },
1152 { 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0, /* 12-bit lossy after split */
1153 0x39,0x5a,0x38,0x27,0x16,5,4,3,2,1,0,11,12,12 },
1154 { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0, /* 12-bit lossless */
1155 5,4,6,3,7,2,8,1,9,0,10,11,12 },
1156 { 0,1,4,3,1,1,1,1,1,2,0,0,0,0,0,0, /* 14-bit lossy */
1157 5,6,4,7,8,3,9,2,1,0,10,11,12,13,14 },
1158 { 0,1,5,1,1,1,1,1,1,1,2,0,0,0,0,0, /* 14-bit lossy after split */
1159 8,0x5c,0x4b,0x3a,0x29,7,6,5,4,3,2,1,0,13,14 },
1160 { 0,1,4,2,2,3,1,2,0,0,0,0,0,0,0,0, /* 14-bit lossless */
1161 7,6,8,5,9,4,10,3,11,12,2,0,1,13,14 } };
1162 ushort *huff, ver0, ver1, vpred[2][2], hpred[2], csize;
1163 int i, min, max, step=0, tree=0, split=0, row, col, len, shl, diff;
1165 fseek (ifp, meta_offset, SEEK_SET);
1168 if (ver0 == 0x49 || ver1 == 0x58)
1169 fseek (ifp, 2110, SEEK_CUR);
1170 if (ver0 == 0x46) tree = 2;
1171 if (tiff_bps == 14) tree += 3;
1172 read_shorts (vpred[0], 4);
1173 max = 1 << tiff_bps & 0x7fff;
1174 if ((csize = get2()) > 1)
1175 step = max / (csize-1);
1176 if (ver0 == 0x44 && ver1 == 0x20 && step > 0) {
1177 for (i=0; i < csize; i++)
1178 curve[i*step] = get2();
1179 for (i=0; i < max; i++)
1180 curve[i] = ( curve[i-i%step]*(step-i%step) +
1181 curve[i-i%step+step]*(i%step) ) / step;
1182 fseek (ifp, meta_offset+562, SEEK_SET);
1184 } else if (ver0 != 0x46 && csize <= 0x4001)
1185 read_shorts (curve, max=csize);
1186 while (curve[max-2] == curve[max-1]) max--;
1187 huff = make_decoder (nikon_tree[tree]);
1188 fseek (ifp, data_offset, SEEK_SET);
1190 for (min=row=0; row < height; row++) {
1191 if (split && row == split) {
1193 huff = make_decoder (nikon_tree[tree+1]);
1194 max += (min = 16) << 1;
1196 for (col=0; col < raw_width; col++) {
1200 diff = ((getbits(len-shl) << 1) + 1) << shl >> 1;
1201 if ((diff & (1 << (len-1))) == 0)
1202 diff -= (1 << len) - !shl;
1203 if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
1204 else hpred[col & 1] += diff;
1205 if ((ushort)(hpred[col & 1] + min) >= max) derror();
1206 RAW(row,col) = curve[LIM((short)hpred[col & 1],0,0x3fff)];
1212 void CLASS nikon_yuv_load_raw()
1214 int row, col, yuv[4], rgb[3], b, c;
1217 for (row=0; row < raw_height; row++)
1218 for (col=0; col < raw_width; col++) {
1219 if (!(b = col & 1)) {
1221 FORC(6) bitbuf |= (UINT64) fgetc(ifp) << c*8;
1222 FORC(4) yuv[c] = (bitbuf >> c*12 & 0xfff) - (c >> 1 << 11);
1224 rgb[0] = yuv[b] + 1.370705*yuv[3];
1225 rgb[1] = yuv[b] - 0.337633*yuv[2] - 0.698001*yuv[3];
1226 rgb[2] = yuv[b] + 1.732446*yuv[2];
1227 FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,0xfff)] / cam_mul[c];
1232 Returns 1 for a Coolpix 995, 0 for anything else.
1234 int CLASS nikon_e995()
1237 const uchar often[] = { 0x00, 0x55, 0xaa, 0xff };
1239 memset (histo, 0, sizeof histo);
1240 fseek (ifp, -2000, SEEK_END);
1241 for (i=0; i < 2000; i++)
1242 histo[fgetc(ifp)]++;
1243 for (i=0; i < 4; i++)
1244 if (histo[often[i]] < 200)
1250 Returns 1 for a Coolpix 2100, 0 for anything else.
1252 int CLASS nikon_e2100()
1257 fseek (ifp, 0, SEEK_SET);
1258 for (i=0; i < 1024; i++) {
1259 fread (t, 1, 12, ifp);
1260 if (((t[2] & t[4] & t[7] & t[9]) >> 4
1261 & t[1] & t[6] & t[8] & t[11] & 3) != 3)
1267 void CLASS nikon_3700()
1271 static const struct {
1273 char make[12], model[15];
1275 { 0x00, "Pentax", "Optio 33WR" },
1276 { 0x03, "Nikon", "E3200" },
1277 { 0x32, "Nikon", "E3700" },
1278 { 0x33, "Olympus", "C740UZ" } };
1280 fseek (ifp, 3072, SEEK_SET);
1281 fread (dp, 1, 24, ifp);
1282 bits = (dp[8] & 3) << 4 | (dp[20] & 3);
1283 for (i=0; i < sizeof table / sizeof *table; i++)
1284 if (bits == table[i].bits) {
1285 strcpy (make, table[i].make );
1286 strcpy (model, table[i].model);
1291 Separates a Minolta DiMAGE Z2 from a Nikon E4300.
1293 int CLASS minolta_z2()
1298 fseek (ifp, -sizeof tail, SEEK_END);
1299 fread (tail, 1, sizeof tail, ifp);
1300 for (nz=i=0; i < sizeof tail; i++)
1305 void CLASS ppm_thumb()
1308 thumb_length = thumb_width*thumb_height*3;
1309 thumb = (char *) malloc (thumb_length);
1310 merror (thumb, "ppm_thumb()");
1311 fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
1312 fread (thumb, 1, thumb_length, ifp);
1313 fwrite (thumb, 1, thumb_length, ofp);
1317 void CLASS ppm16_thumb()
1321 thumb_length = thumb_width*thumb_height*3;
1322 thumb = (char *) calloc (thumb_length, 2);
1323 merror (thumb, "ppm16_thumb()");
1324 read_shorts ((ushort *) thumb, thumb_length);
1325 for (i=0; i < thumb_length; i++)
1326 thumb[i] = ((ushort *) thumb)[i] >> 8;
1327 fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
1328 fwrite (thumb, 1, thumb_length, ofp);
1332 void CLASS layer_thumb()
1335 char *thumb, map[][4] = { "012","102" };
1337 colors = thumb_misc >> 5 & 7;
1338 thumb_length = thumb_width*thumb_height;
1339 thumb = (char *) calloc (colors, thumb_length);
1340 merror (thumb, "layer_thumb()");
1341 fprintf (ofp, "P%d\n%d %d\n255\n",
1342 5 + (colors >> 1), thumb_width, thumb_height);
1343 fread (thumb, thumb_length, colors, ifp);
1344 for (i=0; i < thumb_length; i++)
1345 FORCC putc (thumb[i+thumb_length*(map[thumb_misc >> 8][c]-'0')], ofp);
1349 void CLASS rollei_thumb()
1354 thumb_length = thumb_width * thumb_height;
1355 thumb = (ushort *) calloc (thumb_length, 2);
1356 merror (thumb, "rollei_thumb()");
1357 fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
1358 read_shorts (thumb, thumb_length);
1359 for (i=0; i < thumb_length; i++) {
1360 putc (thumb[i] << 3, ofp);
1361 putc (thumb[i] >> 5 << 2, ofp);
1362 putc (thumb[i] >> 11 << 3, ofp);
1367 void CLASS rollei_load_raw()
1370 unsigned iten=0, isix, i, buffer=0, todo[16];
1372 isix = raw_width * raw_height * 5 / 8;
1373 while (fread (pixel, 1, 10, ifp) == 10) {
1374 for (i=0; i < 10; i+=2) {
1376 todo[i+1] = pixel[i] << 8 | pixel[i+1];
1377 buffer = pixel[i] >> 2 | buffer << 6;
1379 for ( ; i < 16; i+=2) {
1381 todo[i+1] = buffer >> (14-i)*5;
1383 for (i=0; i < 16; i+=2)
1384 raw_image[todo[i]] = (todo[i+1] & 0x3ff);
1389 int CLASS raw (unsigned row, unsigned col)
1391 return (row < raw_height && col < raw_width) ? RAW(row,col) : 0;
1394 void CLASS phase_one_flat_field (int is_float, int nc)
1397 unsigned wide, high, y, x, c, rend, cend, row, col;
1398 float *mrow, num, mult[4];
1400 read_shorts (head, 8);
1401 if (head[2] * head[3] * head[4] * head[5] == 0) return;
1402 wide = head[2] / head[4] + (head[2] % head[4] != 0);
1403 high = head[3] / head[5] + (head[3] % head[5] != 0);
1404 mrow = (float *) calloc (nc*wide, sizeof *mrow);
1405 merror (mrow, "phase_one_flat_field()");
1406 for (y=0; y < high; y++) {
1407 for (x=0; x < wide; x++)
1408 for (c=0; c < nc; c+=2) {
1409 num = is_float ? getreal(11) : get2()/32768.0;
1410 if (y==0) mrow[c*wide+x] = num;
1411 else mrow[(c+1)*wide+x] = (num - mrow[c*wide+x]) / head[5];
1414 rend = head[1] + y*head[5];
1415 for (row = rend-head[5];
1416 row < raw_height && row < rend &&
1417 row < head[1]+head[3]-head[5]; row++) {
1418 for (x=1; x < wide; x++) {
1419 for (c=0; c < nc; c+=2) {
1420 mult[c] = mrow[c*wide+x-1];
1421 mult[c+1] = (mrow[c*wide+x] - mult[c]) / head[4];
1423 cend = head[0] + x*head[4];
1424 for (col = cend-head[4];
1426 col < cend && col < head[0]+head[2]-head[4]; col++) {
1427 c = nc > 2 ? FC(row-top_margin,col-left_margin) : 0;
1429 c = RAW(row,col) * mult[c];
1430 RAW(row,col) = LIM(c,0,65535);
1432 for (c=0; c < nc; c+=2)
1433 mult[c] += mult[c+1];
1436 for (x=0; x < wide; x++)
1437 for (c=0; c < nc; c+=2)
1438 mrow[c*wide+x] += mrow[(c+1)*wide+x];
1444 void CLASS phase_one_correct()
1446 unsigned entries, tag, data, save, col, row, type;
1447 int len, i, j, k, cip, val[4], dev[4], sum, max;
1448 int head[9], diff, mindiff=INT_MAX, off_412=0;
1449 static const signed char dir[12][2] =
1450 { {-1,-1}, {-1,1}, {1,-1}, {1,1}, {-2,0}, {0,-2}, {0,2}, {2,0},
1451 {-2,-2}, {-2,2}, {2,-2}, {2,2} };
1452 float poly[8], num, cfrac, frac, mult[2], *yval[2];
1454 int qmult_applied = 0, qlin_applied = 0;
1456 if (half_size || !meta_length) return;
1457 if (verbose) fprintf (stderr,_("Phase One correction...\n"));
1458 fseek (ifp, meta_offset, SEEK_SET);
1460 fseek (ifp, 6, SEEK_CUR);
1461 fseek (ifp, meta_offset+get4(), SEEK_SET);
1462 entries = get4(); get4();
1468 fseek (ifp, meta_offset+data, SEEK_SET);
1469 if (tag == 0x419) { /* Polynomial curve */
1470 for (get4(), i=0; i < 8; i++)
1471 poly[i] = getreal(11);
1472 poly[3] += (ph1.tag_210 - poly[7]) * poly[6] + 1;
1473 for (i=0; i < 0x10000; i++) {
1474 num = (poly[5]*i + poly[3])*i + poly[1];
1475 curve[i] = LIM(num,0,65535);
1476 } goto apply; /* apply to right half */
1477 } else if (tag == 0x41a) { /* Polynomial curve */
1478 for (i=0; i < 4; i++)
1479 poly[i] = getreal(11);
1480 for (i=0; i < 0x10000; i++) {
1481 for (num=0, j=4; j--; )
1482 num = num * i + poly[j];
1483 curve[i] = LIM(num+i,0,65535);
1484 } apply: /* apply to whole image */
1485 for (row=0; row < raw_height; row++)
1486 for (col = (tag & 1)*ph1.split_col; col < raw_width; col++)
1487 RAW(row,col) = curve[RAW(row,col)];
1488 } else if (tag == 0x400) { /* Sensor defects */
1489 while ((len -= 8) >= 0) {
1492 type = get2(); get2();
1493 if (col >= raw_width) continue;
1494 if (type == 131 || type == 137) /* Bad column */
1495 for (row=0; row < raw_height; row++)
1496 if (FC(row-top_margin,col-left_margin) == 1) {
1497 for (sum=i=0; i < 4; i++)
1498 sum += val[i] = raw (row+dir[i][0], col+dir[i][1]);
1499 for (max=i=0; i < 4; i++) {
1500 dev[i] = abs((val[i] << 2) - sum);
1501 if (dev[max] < dev[i]) max = i;
1503 RAW(row,col) = (sum - val[max])/3.0 + 0.5;
1505 for (sum=0, i=8; i < 12; i++)
1506 sum += raw (row+dir[i][0], col+dir[i][1]);
1507 RAW(row,col) = 0.5 + sum * 0.0732233 +
1508 (raw(row,col-2) + raw(row,col+2)) * 0.3535534;
1510 else if (type == 129) { /* Bad pixel */
1511 if (row >= raw_height) continue;
1512 j = (FC(row-top_margin,col-left_margin) != 1) * 4;
1513 for (sum=0, i=j; i < j+8; i++)
1514 sum += raw (row+dir[i][0], col+dir[i][1]);
1515 RAW(row,col) = (sum + 4) >> 3;
1518 } else if (tag == 0x401) { /* All-color flat fields */
1519 phase_one_flat_field (1, 2);
1520 } else if (tag == 0x416 || tag == 0x410) {
1521 phase_one_flat_field (0, 2);
1522 } else if (tag == 0x40b) { /* Red+blue flat field */
1523 phase_one_flat_field (0, 4);
1524 } else if (tag == 0x412) {
1525 fseek (ifp, 36, SEEK_CUR);
1526 diff = abs (get2() - ph1.tag_21a);
1527 if (mindiff > diff) {
1529 off_412 = ftell(ifp) - 38;
1531 } else if (tag == 0x41f && !qlin_applied) { /* Quadrant linearization */
1532 ushort lc[2][2][16], ref[16];
1534 for (qr = 0; qr < 2; qr++)
1535 for (qc = 0; qc < 2; qc++)
1536 for (i = 0; i < 16; i++)
1537 lc[qr][qc][i] = get4();
1538 for (i = 0; i < 16; i++) {
1540 for (qr = 0; qr < 2; qr++)
1541 for (qc = 0; qc < 2; qc++)
1543 ref[i] = (v + 2) >> 2;
1545 for (qr = 0; qr < 2; qr++) {
1546 for (qc = 0; qc < 2; qc++) {
1548 for (i = 0; i < 16; i++) {
1549 cx[1+i] = lc[qr][qc][i];
1553 cx[17] = cf[17] = ((unsigned) ref[15] * 65535) / lc[qr][qc][15];
1554 cx[18] = cf[18] = 65535;
1555 cubic_spline(cx, cf, 19);
1556 for (row = (qr ? ph1.split_row : 0);
1557 row < (qr ? raw_height : ph1.split_row); row++)
1558 for (col = (qc ? ph1.split_col : 0);
1559 col < (qc ? raw_width : ph1.split_col); col++)
1560 RAW(row,col) = curve[RAW(row,col)];
1564 } else if (tag == 0x41e && !qmult_applied) { /* Quadrant multipliers */
1565 float qmult[2][2] = { { 1, 1 }, { 1, 1 } };
1566 get4(); get4(); get4(); get4();
1567 qmult[0][0] = 1.0 + getreal(11);
1568 get4(); get4(); get4(); get4(); get4();
1569 qmult[0][1] = 1.0 + getreal(11);
1570 get4(); get4(); get4();
1571 qmult[1][0] = 1.0 + getreal(11);
1572 get4(); get4(); get4();
1573 qmult[1][1] = 1.0 + getreal(11);
1574 for (row=0; row < raw_height; row++)
1575 for (col=0; col < raw_width; col++) {
1576 i = qmult[row >= ph1.split_row][col >= ph1.split_col] * RAW(row,col);
1577 RAW(row,col) = LIM(i,0,65535);
1580 } else if (tag == 0x431 && !qmult_applied) { /* Quadrant combined */
1581 ushort lc[2][2][7], ref[7];
1583 for (i = 0; i < 7; i++)
1585 for (qr = 0; qr < 2; qr++)
1586 for (qc = 0; qc < 2; qc++)
1587 for (i = 0; i < 7; i++)
1588 lc[qr][qc][i] = get4();
1589 for (qr = 0; qr < 2; qr++) {
1590 for (qc = 0; qc < 2; qc++) {
1592 for (i = 0; i < 7; i++) {
1594 cf[1+i] = ((unsigned) ref[i] * lc[qr][qc][i]) / 10000;
1597 cx[8] = cf[8] = 65535;
1598 cubic_spline(cx, cf, 9);
1599 for (row = (qr ? ph1.split_row : 0);
1600 row < (qr ? raw_height : ph1.split_row); row++)
1601 for (col = (qc ? ph1.split_col : 0);
1602 col < (qc ? raw_width : ph1.split_col); col++)
1603 RAW(row,col) = curve[RAW(row,col)];
1609 fseek (ifp, save, SEEK_SET);
1612 fseek (ifp, off_412, SEEK_SET);
1613 for (i=0; i < 9; i++) head[i] = get4() & 0x7fff;
1614 yval[0] = (float *) calloc (head[1]*head[3] + head[2]*head[4], 6);
1615 merror (yval[0], "phase_one_correct()");
1616 yval[1] = (float *) (yval[0] + head[1]*head[3]);
1617 xval[0] = (ushort *) (yval[1] + head[2]*head[4]);
1618 xval[1] = (ushort *) (xval[0] + head[1]*head[3]);
1620 for (i=0; i < 2; i++)
1621 for (j=0; j < head[i+1]*head[i+3]; j++)
1622 yval[i][j] = getreal(11);
1623 for (i=0; i < 2; i++)
1624 for (j=0; j < head[i+1]*head[i+3]; j++)
1625 xval[i][j] = get2();
1626 for (row=0; row < raw_height; row++)
1627 for (col=0; col < raw_width; col++) {
1628 cfrac = (float) col * head[3] / raw_width;
1629 cfrac -= cip = cfrac;
1630 num = RAW(row,col) * 0.5;
1631 for (i=cip; i < cip+2; i++) {
1632 for (k=j=0; j < head[1]; j++)
1633 if (num < xval[0][k = head[1]*i+j]) break;
1634 frac = (j == 0 || j == head[1]) ? 0 :
1635 (xval[0][k] - num) / (xval[0][k] - xval[0][k-1]);
1636 mult[i-cip] = yval[0][k-1] * frac + yval[0][k] * (1-frac);
1638 i = ((mult[0] * (1-cfrac) + mult[1] * cfrac) * row + num) * 2;
1639 RAW(row,col) = LIM(i,0,65535);
1645 void CLASS phase_one_load_raw()
1648 ushort akey, bkey, mask;
1650 fseek (ifp, ph1.key_off, SEEK_SET);
1653 mask = ph1.format == 1 ? 0x5555:0x1354;
1654 fseek (ifp, data_offset, SEEK_SET);
1655 read_shorts (raw_image, raw_width*raw_height);
1657 for (i=0; i < raw_width*raw_height; i+=2) {
1658 a = raw_image[i+0] ^ akey;
1659 b = raw_image[i+1] ^ bkey;
1660 raw_image[i+0] = (a & mask) | (b & ~mask);
1661 raw_image[i+1] = (b & mask) | (a & ~mask);
1665 unsigned CLASS ph1_bithuff (int nbits, ushort *huff)
1672 return ph1_bitbuf = ph1_vbits = 0;
1673 if (nbits == 0) return 0;
1674 bitbuf = ph1_bitbuf; vbits = ph1_vbits;
1675 if (vbits < nbits) {
1676 bitbuf = bitbuf << 32 | get4();
1679 c = bitbuf << (64-vbits) >> (64-nbits);
1681 nbits = huff[c] >> 8;
1682 c = (uchar) huff[c];
1685 ph1_bitbuf = bitbuf; ph1_vbits = vbits;
1688 #define ph1_bits(n) ph1_bithuff(n,0)
1689 #define ph1_huff(h) ph1_bithuff(*h,h+1)
1691 void CLASS phase_one_load_raw_c()
1693 static const int length[] = { 8,7,6,9,11,10,5,12,14,13 };
1694 int *offset, len[2], pred[2], row, col, i, j;
1696 short (*cblack)[2], (*rblack)[2];
1698 pixel = (ushort *) calloc (raw_width*3 + raw_height*4, 2);
1699 merror (pixel, "phase_one_load_raw_c()");
1700 offset = (int *) (pixel + raw_width);
1701 fseek (ifp, strip_offset, SEEK_SET);
1702 for (row=0; row < raw_height; row++)
1703 offset[row] = get4();
1704 cblack = (short (*)[2]) (offset + raw_height);
1705 fseek (ifp, ph1.black_col, SEEK_SET);
1707 read_shorts ((ushort *) cblack[0], raw_height*2);
1708 rblack = cblack + raw_height;
1709 fseek (ifp, ph1.black_row, SEEK_SET);
1711 read_shorts ((ushort *) rblack[0], raw_width*2);
1712 for (i=0; i < 256; i++)
1713 curve[i] = i*i / 3.969 + 0.5;
1714 for (row=0; row < raw_height; row++) {
1715 fseek (ifp, data_offset + offset[row], SEEK_SET);
1717 pred[0] = pred[1] = 0;
1718 for (col=0; col < raw_width; col++) {
1719 if (col >= (raw_width & -8))
1720 len[0] = len[1] = 14;
1721 else if ((col & 7) == 0)
1722 for (i=0; i < 2; i++) {
1723 for (j=0; j < 5 && !ph1_bits(1); j++);
1724 if (j--) len[i] = length[j*2 + ph1_bits(1)];
1726 if ((i = len[col & 1]) == 14)
1727 pixel[col] = pred[col & 1] = ph1_bits(16);
1729 pixel[col] = pred[col & 1] += ph1_bits(i) + 1 - (1 << (i - 1));
1730 if (pred[col & 1] >> 16) derror();
1731 if (ph1.format == 5 && pixel[col] < 256)
1732 pixel[col] = curve[pixel[col]];
1734 for (col=0; col < raw_width; col++) {
1735 i = (pixel[col] << 2*(ph1.format != 8)) - ph1.black
1736 + cblack[row][col >= ph1.split_col]
1737 + rblack[col][row >= ph1.split_row];
1738 if (i > 0) RAW(row,col) = i;
1742 maximum = 0xfffc - ph1.black;
1745 void CLASS hasselblad_load_raw()
1748 int shot, row, col, *back[5], len[2], diff[12], pred, sh, f, s, c;
1749 unsigned upix, urow, ucol;
1752 if (!ljpeg_start (&jh, 0)) return;
1755 back[4] = (int *) calloc (raw_width, 3*sizeof **back);
1756 merror (back[4], "hasselblad_load_raw()");
1757 FORC3 back[c] = back[4] + c*raw_width;
1758 cblack[6] >>= sh = tiff_samples > 1;
1759 shot = LIM(shot_select, 1, tiff_samples) - 1;
1760 for (row=0; row < raw_height; row++) {
1761 FORC4 back[(c+3) & 3] = back[c];
1762 for (col=0; col < raw_width; col+=2) {
1763 for (s=0; s < tiff_samples*2; s+=2) {
1764 FORC(2) len[c] = ph1_huff(jh.huff[0]);
1766 diff[s+c] = ph1_bits(len[c]);
1767 if ((diff[s+c] & (1 << (len[c]-1))) == 0)
1768 diff[s+c] -= (1 << len[c]) - 1;
1769 if (diff[s+c] == 65535) diff[s+c] = -32768;
1772 for (s=col; s < col+2; s++) {
1773 pred = 0x8000 + load_flags;
1774 if (col) pred = back[2][s-2];
1775 if (col && row > 1) switch (jh.psv) {
1776 case 11: pred += back[0][s]/2 - back[0][s-2]/2; break;
1778 f = (row & 1)*3 ^ ((col+s) & 1);
1779 FORC (tiff_samples) {
1780 pred += diff[(s & 1)*tiff_samples+c];
1781 upix = pred >> sh & 0xffff;
1782 if (raw_image && c == shot)
1785 urow = row-top_margin + (c & 1);
1786 ucol = col-left_margin - ((c >> 1) & 1);
1787 ip = &image[urow*width+ucol][f];
1788 if (urow < height && ucol < width)
1789 *ip = c < 4 ? upix : (*ip + upix) >> 1;
1798 if (image) mix_green = 1;
1801 void CLASS leaf_hdr_load_raw()
1804 unsigned tile=0, r, c, row, col;
1807 pixel = (ushort *) calloc (raw_width, sizeof *pixel);
1808 merror (pixel, "leaf_hdr_load_raw()");
1811 for (r=0; r < raw_height; r++) {
1812 if (r % tile_length == 0) {
1813 fseek (ifp, data_offset + 4*tile++, SEEK_SET);
1814 fseek (ifp, get4(), SEEK_SET);
1816 if (filters && c != shot_select) continue;
1817 if (filters) pixel = raw_image + r*raw_width;
1818 read_shorts (pixel, raw_width);
1819 if (!filters && (row = r - top_margin) < height)
1820 for (col=0; col < width; col++)
1821 image[row*width+col][c] = pixel[col+left_margin];
1830 void CLASS unpacked_load_raw()
1832 int row, col, bits=0;
1834 while (1 << ++bits < maximum);
1835 read_shorts (raw_image, raw_width*raw_height);
1836 for (row=0; row < raw_height; row++)
1837 for (col=0; col < raw_width; col++)
1838 if ((RAW(row,col) >>= load_flags) >> bits
1839 && (unsigned) (row-top_margin) < height
1840 && (unsigned) (col-left_margin) < width) derror();
1843 void CLASS sinar_4shot_load_raw()
1846 unsigned shot, row, col, r, c;
1849 shot = LIM (shot_select, 1, 4) - 1;
1850 fseek (ifp, data_offset + shot*4, SEEK_SET);
1851 fseek (ifp, get4(), SEEK_SET);
1852 unpacked_load_raw();
1855 pixel = (ushort *) calloc (raw_width, sizeof *pixel);
1856 merror (pixel, "sinar_4shot_load_raw()");
1857 for (shot=0; shot < 4; shot++) {
1858 fseek (ifp, data_offset + shot*4, SEEK_SET);
1859 fseek (ifp, get4(), SEEK_SET);
1860 for (row=0; row < raw_height; row++) {
1861 read_shorts (pixel, raw_width);
1862 if ((r = row-top_margin - (shot >> 1 & 1)) >= height) continue;
1863 for (col=0; col < raw_width; col++) {
1864 if ((c = col-left_margin - (shot & 1)) >= width) continue;
1865 image[r*width+c][(row & 1)*3 ^ (~col & 1)] = pixel[col];
1873 void CLASS imacon_full_load_raw()
1878 for (row=0; row < height; row++)
1879 for (col=0; col < width; col++)
1880 read_shorts (image[row*width+col], 3);
1883 void CLASS packed_load_raw()
1885 int vbits=0, bwide, rbits, bite, half, irow, row, col, val, i;
1888 bwide = raw_width * tiff_bps / 8;
1889 bwide += bwide & load_flags >> 7;
1890 rbits = bwide * 8 - raw_width * tiff_bps;
1891 if (load_flags & 1) bwide = bwide * 16 / 15;
1892 bite = 8 + (load_flags & 24);
1893 half = (raw_height+1) >> 1;
1894 for (irow=0; irow < raw_height; irow++) {
1896 if (load_flags & 2 &&
1897 (row = irow % half * 2 + irow / half) == 1 &&
1899 if (vbits=0, tiff_compress)
1900 fseek (ifp, data_offset - (-half*bwide & -2048), SEEK_SET);
1902 fseek (ifp, 0, SEEK_END);
1903 fseek (ifp, ftell(ifp) >> 3 << 2, SEEK_SET);
1906 for (col=0; col < raw_width; col++) {
1907 for (vbits -= tiff_bps; vbits < 0; vbits += bite) {
1909 for (i=0; i < bite; i+=8)
1910 bitbuf |= (unsigned) (fgetc(ifp) << i);
1912 val = bitbuf << (64-tiff_bps-vbits) >> (64-tiff_bps);
1913 RAW(row,col ^ (load_flags >> 6 & 1)) = val;
1914 if (load_flags & 1 && (col % 10) == 9 && fgetc(ifp) &&
1915 row < height+top_margin && col < width+left_margin) derror();
1921 void CLASS nokia_load_raw()
1924 int rev, dwide, row, col, c;
1927 rev = 3 * (order == 0x4949);
1928 dwide = (raw_width * 5 + 1) / 4;
1929 data = (uchar *) malloc (dwide*2);
1930 merror (data, "nokia_load_raw()");
1931 for (row=0; row < raw_height; row++) {
1932 if (fread (data+dwide, 1, dwide, ifp) < dwide) derror();
1933 FORC(dwide) data[c] = data[dwide+(c ^ rev)];
1934 for (dp=data, col=0; col < raw_width; dp+=5, col+=4)
1935 FORC4 RAW(row,col+c) = (dp[c] << 2) | (dp[4] >> (c << 1) & 3);
1939 if (strcmp(make,"OmniVision")) return;
1942 sum[ c & 1] += SQR(RAW(row,c)-RAW(row+1,c+1));
1943 sum[~c & 1] += SQR(RAW(row+1,c)-RAW(row,c+1));
1945 if (sum[1] > sum[0]) filters = 0x4b4b4b4b;
1948 void CLASS canon_rmf_load_raw()
1950 int row, col, bits, orow, ocol, c;
1952 for (row=0; row < raw_height; row++)
1953 for (col=0; col < raw_width-2; col+=3) {
1957 if ((ocol = col+c-4) < 0) {
1959 if ((orow -= 2) < 0)
1962 RAW(orow,ocol) = curve[bits >> (10*c+2) & 0x3ff];
1965 maximum = curve[0x3ff];
1968 unsigned CLASS pana_bits (int nbits)
1970 uchar *buf = pana_buf;
1971 int vbits = pana_vbits;
1974 if (!nbits) return pana_vbits=0;
1976 fread (buf+load_flags, 1, 0x4000-load_flags, ifp);
1977 fread (buf, 1, load_flags, ifp);
1979 vbits = (vbits - nbits) & 0x1ffff;
1980 byte = vbits >> 3 ^ 0x3ff0;
1982 return (buf[byte] | buf[byte+1] << 8) >> (vbits & 7) & ~(-1 << nbits);
1985 void CLASS panasonic_load_raw()
1987 int row, col, i, j, sh=0, pred[2], nonz[2];
1990 for (row=0; row < height; row++)
1991 for (col=0; col < raw_width; col++) {
1992 if ((i = col % 14) == 0)
1993 pred[0] = pred[1] = nonz[0] = nonz[1] = 0;
1994 if (i % 3 == 2) sh = 4 >> (3 - pana_bits(2));
1996 if ((j = pana_bits(8))) {
1997 if ((pred[i & 1] -= 0x80 << sh) < 0 || sh == 4)
1998 pred[i & 1] &= ~(-1 << sh);
1999 pred[i & 1] += j << sh;
2001 } else if ((nonz[i & 1] = pana_bits(8)) || i > 11)
2002 pred[i & 1] = nonz[i & 1] << 4 | pana_bits(4);
2003 if ((RAW(row,col) = pred[col & 1]) > 4098 && col < width) derror();
2007 void CLASS olympus_load_raw()
2010 int row, col, nbits, sign, low, high, i, c, w, n, nw;
2011 int acarry[2][3], *carry, pred, diff;
2015 FORC(2048 >> i) huff[++n] = (i+1) << 8 | i;
2016 fseek (ifp, 7, SEEK_CUR);
2018 for (row=0; row < height; row++) {
2019 memset (acarry, 0, sizeof acarry);
2020 for (col=0; col < raw_width; col++) {
2021 carry = acarry[col & 1];
2022 i = 2 * (carry[2] < 3);
2023 for (nbits=2+i; (ushort) carry[0] >> (nbits+i); nbits++);
2024 low = (sign = getbits(3)) & 3;
2025 sign = sign << 29 >> 31;
2026 if ((high = getbithuff(12,huff)) == 12)
2027 high = getbits(16-nbits) >> 1;
2028 carry[0] = (high << nbits) | getbits(nbits);
2029 diff = (carry[0] ^ sign) + carry[1];
2030 carry[1] = (diff*3 + carry[1]) >> 5;
2031 carry[2] = carry[0] > 16 ? 0 : carry[2]+1;
2032 if (col >= width) continue;
2033 if (row < 2 && col < 2) pred = 0;
2034 else if (row < 2) pred = RAW(row,col-2);
2035 else if (col < 2) pred = RAW(row-2,col);
2039 nw = RAW(row-2,col-2);
2040 if ((w < nw && nw < n) || (n < nw && nw < w)) {
2041 if (ABS(w-nw) > 32 || ABS(n-nw) > 32)
2043 else pred = (w + n) >> 1;
2044 } else pred = ABS(w-nw) > ABS(n-nw) ? w : n;
2046 if ((RAW(row,col) = pred + ((diff << 2) | low)) >> 12) derror();
2051 void CLASS minolta_rd175_load_raw()
2054 unsigned irow, box, row, col;
2056 for (irow=0; irow < 1481; irow++) {
2057 if (fread (pixel, 1, 768, ifp) < 768) derror();
2059 row = irow % 82 * 12 + ((box < 12) ? box | 1 : (box-12)*2);
2061 case 1477: case 1479: continue;
2062 case 1476: row = 984; break;
2063 case 1480: row = 985; break;
2064 case 1478: row = 985; box = 1;
2066 if ((box < 12) && (box & 1)) {
2067 for (col=0; col < 1533; col++, row ^= 1)
2068 if (col != 1) RAW(row,col) = (col+1) & 2 ?
2069 pixel[col/2-1] + pixel[col/2+1] : pixel[col/2] << 1;
2070 RAW(row,1) = pixel[1] << 1;
2071 RAW(row,1533) = pixel[765] << 1;
2073 for (col=row & 1; col < 1534; col+=2)
2074 RAW(row,col) = pixel[col/2] << 1;
2076 maximum = 0xff << 1;
2079 void CLASS quicktake_100_load_raw()
2081 uchar pixel[484][644];
2082 static const short gstep[16] =
2083 { -89,-60,-44,-32,-22,-15,-8,-2,2,8,15,22,32,44,60,89 };
2084 static const short rstep[6][4] =
2085 { { -3,-1,1,3 }, { -5,-1,1,5 }, { -8,-2,2,8 },
2086 { -13,-3,3,13 }, { -19,-4,4,19 }, { -28,-6,6,28 } };
2087 static const short curve[256] =
2088 { 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,
2089 28,29,30,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,53,
2090 54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,74,75,76,77,78,
2091 79,80,81,82,83,84,86,88,90,92,94,97,99,101,103,105,107,110,112,114,116,
2092 118,120,123,125,127,129,131,134,136,138,140,142,144,147,149,151,153,155,
2093 158,160,162,164,166,168,171,173,175,177,179,181,184,186,188,190,192,195,
2094 197,199,201,203,205,208,210,212,214,216,218,221,223,226,230,235,239,244,
2095 248,252,257,261,265,270,274,278,283,287,291,296,300,305,309,313,318,322,
2096 326,331,335,339,344,348,352,357,361,365,370,374,379,383,387,392,396,400,
2097 405,409,413,418,422,426,431,435,440,444,448,453,457,461,466,470,474,479,
2098 483,487,492,496,500,508,519,531,542,553,564,575,587,598,609,620,631,643,
2099 654,665,676,687,698,710,721,732,743,754,766,777,788,799,810,822,833,844,
2100 855,866,878,889,900,911,922,933,945,956,967,978,989,1001,1012,1023 };
2101 int rb, row, col, sharp, val=0;
2104 memset (pixel, 0x80, sizeof pixel);
2105 for (row=2; row < height+2; row++) {
2106 for (col=2+(row & 1); col < width+2; col+=2) {
2107 val = ((pixel[row-1][col-1] + 2*pixel[row-1][col+1] +
2108 pixel[row][col-2]) >> 2) + gstep[getbits(4)];
2109 pixel[row][col] = val = LIM(val,0,255);
2111 pixel[row][col-2] = pixel[row+1][~row & 1] = val;
2113 pixel[row-1][col+1] = pixel[row-1][col+3] = val;
2115 pixel[row][col] = val;
2117 for (rb=0; rb < 2; rb++)
2118 for (row=2+rb; row < height+2; row+=2)
2119 for (col=3-(row & 1); col < width+2; col+=2) {
2120 if (row < 4 || col < 4) sharp = 2;
2122 val = ABS(pixel[row-2][col] - pixel[row][col-2])
2123 + ABS(pixel[row-2][col] - pixel[row-2][col-2])
2124 + ABS(pixel[row][col-2] - pixel[row-2][col-2]);
2125 sharp = val < 4 ? 0 : val < 8 ? 1 : val < 16 ? 2 :
2126 val < 32 ? 3 : val < 48 ? 4 : 5;
2128 val = ((pixel[row-2][col] + pixel[row][col-2]) >> 1)
2129 + rstep[sharp][getbits(2)];
2130 pixel[row][col] = val = LIM(val,0,255);
2131 if (row < 4) pixel[row-2][col+2] = val;
2132 if (col < 4) pixel[row+2][col-2] = val;
2134 for (row=2; row < height+2; row++)
2135 for (col=3-(row & 1); col < width+2; col+=2) {
2136 val = ((pixel[row][col-1] + (pixel[row][col] << 2) +
2137 pixel[row][col+1]) >> 1) - 0x100;
2138 pixel[row][col] = LIM(val,0,255);
2140 for (row=0; row < height; row++)
2141 for (col=0; col < width; col++)
2142 RAW(row,col) = curve[pixel[row+2][col+2]];
2146 #define radc_token(tree) ((signed char) getbithuff(8,huff[tree]))
2148 #define FORYX for (y=1; y < 3; y++) for (x=col+1; x >= col; x--)
2150 #define PREDICTOR (c ? (buf[c][y-1][x] + buf[c][y][x+1]) / 2 \
2151 : (buf[c][y-1][x+1] + 2*buf[c][y-1][x] + buf[c][y][x+1]) / 4)
2153 void CLASS kodak_radc_load_raw()
2155 static const char src[] = {
2156 1,1, 2,3, 3,4, 4,2, 5,7, 6,5, 7,6, 7,8,
2157 1,0, 2,1, 3,3, 4,4, 5,2, 6,7, 7,6, 8,5, 8,8,
2158 2,1, 2,3, 3,0, 3,2, 3,4, 4,6, 5,5, 6,7, 6,8,
2159 2,0, 2,1, 2,3, 3,2, 4,4, 5,6, 6,7, 7,5, 7,8,
2160 2,1, 2,4, 3,0, 3,2, 3,3, 4,7, 5,5, 6,6, 6,8,
2161 2,3, 3,1, 3,2, 3,4, 3,5, 3,6, 4,7, 5,0, 5,8,
2162 2,3, 2,6, 3,0, 3,1, 4,4, 4,5, 4,7, 5,2, 5,8,
2163 2,4, 2,7, 3,3, 3,6, 4,1, 4,2, 4,5, 5,0, 5,8,
2164 2,6, 3,1, 3,3, 3,5, 3,7, 3,8, 4,0, 5,2, 5,4,
2165 2,0, 2,1, 3,2, 3,3, 4,4, 4,5, 5,6, 5,7, 4,8,
2168 2,-17, 2,-5, 2,5, 2,17,
2169 2,-7, 2,2, 2,9, 2,18,
2170 2,-18, 2,-9, 2,-2, 2,7,
2171 2,-28, 2,28, 3,-49, 3,-9, 3,9, 4,49, 5,-79, 5,79,
2172 2,-1, 2,13, 2,26, 3,39, 4,-16, 5,55, 6,-37, 6,76,
2173 2,-26, 2,-13, 2,1, 3,-39, 4,16, 5,-55, 6,-76, 6,37
2175 ushort huff[19][256];
2176 int row, col, tree, nreps, rep, step, i, c, s, r, x, y, val;
2177 short last[3] = { 16,16,16 }, mul[3], buf[3][3][386];
2178 static const ushort pt[] =
2179 { 0,0, 1280,1344, 2320,3616, 3328,8000, 4095,16383, 65535,16383 };
2181 for (i=2; i < 12; i+=2)
2182 for (c=pt[i-2]; c <= pt[i]; c++)
2184 (c-pt[i-2]) / (pt[i]-pt[i-2]) * (pt[i+1]-pt[i-1]) + pt[i-1] + 0.5;
2185 for (s=i=0; i < sizeof src; i+=2)
2187 ((ushort *)huff)[s++] = src[i] << 8 | (uchar) src[i+1];
2188 s = kodak_cbpp == 243 ? 2 : 3;
2189 FORC(256) huff[18][c] = (8-s) << 8 | c >> s << s | 1 << (s-1);
2191 for (i=0; i < sizeof(buf)/sizeof(short); i++)
2192 ((short *)buf)[i] = 2048;
2193 for (row=0; row < height; row+=4) {
2194 FORC3 mul[c] = getbits(6);
2196 val = ((0x1000000/last[c] + 0x7ff) >> 12) * mul[c];
2197 s = val > 65564 ? 10:12;
2200 for (i=0; i < sizeof(buf[0])/sizeof(short); i++)
2201 ((short *)buf[c])[i] = (((short *)buf[c])[i] * val + x) >> s;
2203 for (r=0; r <= !c; r++) {
2204 buf[c][1][width/2] = buf[c][2][width/2] = mul[c] << 7;
2205 for (tree=1, col=width/2; col > 0; ) {
2206 if ((tree = radc_token(tree))) {
2209 FORYX buf[c][y][x] = (uchar) radc_token(18) * mul[c];
2211 FORYX buf[c][y][x] = radc_token(tree+10) * 16 + PREDICTOR;
2214 nreps = (col > 2) ? radc_token(9) + 1 : 1;
2215 for (rep=0; rep < 8 && rep < nreps && col > 0; rep++) {
2217 FORYX buf[c][y][x] = PREDICTOR;
2219 step = radc_token(10) << 4;
2220 FORYX buf[c][y][x] += step;
2223 } while (nreps == 9);
2225 for (y=0; y < 2; y++)
2226 for (x=0; x < width/2; x++) {
2227 val = (buf[c][y+1][x] << 4) / mul[c];
2228 if (val < 0) val = 0;
2229 if (c) RAW(row+y*2+c-1,x*2+2-c) = val;
2230 else RAW(row+r*2+y,x*2+y) = val;
2232 memcpy (buf[c][0]+!c, buf[c][2], sizeof buf[c][0]-2*!c);
2235 for (y=row; y < row+4; y++)
2236 for (x=0; x < width; x++)
2239 s = x+1 < width ? x+1 : x-1;
2240 val = (RAW(y,x)-2048)*2 + (RAW(y,r)+RAW(y,s))/2;
2241 if (val < 0) val = 0;
2245 for (i=0; i < height*width; i++)
2246 raw_image[i] = curve[raw_image[i]];
2254 void CLASS kodak_jpeg_load_raw() {}
2255 void CLASS lossy_dng_load_raw() {}
2259 fill_input_buffer (j_decompress_ptr cinfo)
2261 static uchar jpeg_buffer[4096];
2264 nbytes = fread (jpeg_buffer, 1, 4096, ifp);
2265 swab (jpeg_buffer, jpeg_buffer, nbytes);
2266 cinfo->src->next_input_byte = jpeg_buffer;
2267 cinfo->src->bytes_in_buffer = nbytes;
2271 void CLASS kodak_jpeg_load_raw()
2273 struct jpeg_decompress_struct cinfo;
2274 struct jpeg_error_mgr jerr;
2276 JSAMPLE (*pixel)[3];
2279 cinfo.err = jpeg_std_error (&jerr);
2280 jpeg_create_decompress (&cinfo);
2281 jpeg_stdio_src (&cinfo, ifp);
2282 cinfo.src->fill_input_buffer = fill_input_buffer;
2283 jpeg_read_header (&cinfo, TRUE);
2284 jpeg_start_decompress (&cinfo);
2285 if ((cinfo.output_width != width ) ||
2286 (cinfo.output_height*2 != height ) ||
2287 (cinfo.output_components != 3 )) {
2288 fprintf (stderr,_("%s: incorrect JPEG dimensions\n"), ifname);
2289 jpeg_destroy_decompress (&cinfo);
2290 longjmp (failure, 3);
2292 buf = (*cinfo.mem->alloc_sarray)
2293 ((j_common_ptr) &cinfo, JPOOL_IMAGE, width*3, 1);
2295 while (cinfo.output_scanline < cinfo.output_height) {
2296 row = cinfo.output_scanline * 2;
2297 jpeg_read_scanlines (&cinfo, buf, 1);
2298 pixel = (JSAMPLE (*)[3]) buf[0];
2299 for (col=0; col < width; col+=2) {
2300 RAW(row+0,col+0) = pixel[col+0][1] << 1;
2301 RAW(row+1,col+1) = pixel[col+1][1] << 1;
2302 RAW(row+0,col+1) = pixel[col][0] + pixel[col+1][0];
2303 RAW(row+1,col+0) = pixel[col][2] + pixel[col+1][2];
2306 jpeg_finish_decompress (&cinfo);
2307 jpeg_destroy_decompress (&cinfo);
2308 maximum = 0xff << 1;
2311 void CLASS gamma_curve (double pwr, double ts, int mode, int imax);
2313 void CLASS lossy_dng_load_raw()
2315 struct jpeg_decompress_struct cinfo;
2316 struct jpeg_error_mgr jerr;
2318 JSAMPLE (*pixel)[3];
2319 unsigned sorder=order, ntags, opcode, deg, i, j, c;
2320 unsigned save=data_offset-4, trow=0, tcol=0, row, col;
2322 double coeff[9], tot;
2325 fseek (ifp, meta_offset, SEEK_SET);
2329 opcode = get4(); get4(); get4();
2331 { fseek (ifp, get4(), SEEK_CUR); continue; }
2332 fseek (ifp, 20, SEEK_CUR);
2333 if ((c = get4()) > 2) break;
2334 fseek (ifp, 12, SEEK_CUR);
2335 if ((deg = get4()) > 8) break;
2336 for (i=0; i <= deg && i < 9; i++)
2337 coeff[i] = getreal(12);
2338 for (i=0; i < 256; i++) {
2339 for (tot=j=0; j <= deg; j++)
2340 tot += coeff[j] * pow(i/255.0, j);
2341 cur[c][i] = tot*0xffff;
2346 gamma_curve (1/2.4, 12.92, 1, 255);
2347 FORC3 memcpy (cur[c], curve, sizeof cur[0]);
2349 cinfo.err = jpeg_std_error (&jerr);
2350 jpeg_create_decompress (&cinfo);
2351 while (trow < raw_height) {
2352 fseek (ifp, save+=4, SEEK_SET);
2353 if (tile_length < INT_MAX)
2354 fseek (ifp, get4(), SEEK_SET);
2355 jpeg_stdio_src (&cinfo, ifp);
2356 jpeg_read_header (&cinfo, TRUE);
2357 jpeg_start_decompress (&cinfo);
2358 buf = (*cinfo.mem->alloc_sarray)
2359 ((j_common_ptr) &cinfo, JPOOL_IMAGE, cinfo.output_width*3, 1);
2360 while (cinfo.output_scanline < cinfo.output_height &&
2361 (row = trow + cinfo.output_scanline) < height) {
2362 jpeg_read_scanlines (&cinfo, buf, 1);
2363 pixel = (JSAMPLE (*)[3]) buf[0];
2364 for (col=0; col < cinfo.output_width && tcol+col < width; col++) {
2365 FORC3 image[row*width+tcol+col][c] = cur[c][pixel[col][c]];
2368 jpeg_abort_decompress (&cinfo);
2369 if ((tcol += tile_width) >= raw_width)
2370 trow += tile_length + (tcol = 0);
2372 jpeg_destroy_decompress (&cinfo);
2377 void CLASS kodak_dc120_load_raw()
2379 static const int mul[4] = { 162, 192, 187, 92 };
2380 static const int add[4] = { 0, 636, 424, 212 };
2382 int row, shift, col;
2384 for (row=0; row < height; row++) {
2385 if (fread (pixel, 1, 848, ifp) < 848) derror();
2386 shift = row * mul[row & 3] + add[row & 3];
2387 for (col=0; col < width; col++)
2388 RAW(row,col) = (ushort) pixel[(col + shift) % 848];
2393 void CLASS eight_bit_load_raw()
2398 pixel = (uchar *) calloc (raw_width, sizeof *pixel);
2399 merror (pixel, "eight_bit_load_raw()");
2400 for (row=0; row < raw_height; row++) {
2401 if (fread (pixel, 1, raw_width, ifp) < raw_width) derror();
2402 for (col=0; col < raw_width; col++)
2403 RAW(row,col) = curve[pixel[col]];
2406 maximum = curve[0xff];
2409 void CLASS kodak_c330_load_raw()
2412 int row, col, y, cb, cr, rgb[3], c;
2414 pixel = (uchar *) calloc (raw_width, 2*sizeof *pixel);
2415 merror (pixel, "kodak_c330_load_raw()");
2416 for (row=0; row < height; row++) {
2417 if (fread (pixel, raw_width, 2, ifp) < 2) derror();
2418 if (load_flags && (row & 31) == 31)
2419 fseek (ifp, raw_width*32, SEEK_CUR);
2420 for (col=0; col < width; col++) {
2422 cb = pixel[(col*2 & -4) | 1] - 128;
2423 cr = pixel[(col*2 & -4) | 3] - 128;
2424 rgb[1] = y - ((cb + cr + 2) >> 2);
2425 rgb[2] = rgb[1] + cb;
2426 rgb[0] = rgb[1] + cr;
2427 FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,255)];
2431 maximum = curve[0xff];
2434 void CLASS kodak_c603_load_raw()
2437 int row, col, y, cb, cr, rgb[3], c;
2439 pixel = (uchar *) calloc (raw_width, 3*sizeof *pixel);
2440 merror (pixel, "kodak_c603_load_raw()");
2441 for (row=0; row < height; row++) {
2443 if (fread (pixel, raw_width, 3, ifp) < 3) derror();
2444 for (col=0; col < width; col++) {
2445 y = pixel[width*2*(row & 1) + col];
2446 cb = pixel[width + (col & -2)] - 128;
2447 cr = pixel[width + (col & -2)+1] - 128;
2448 rgb[1] = y - ((cb + cr + 2) >> 2);
2449 rgb[2] = rgb[1] + cb;
2450 rgb[0] = rgb[1] + cr;
2451 FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,255)];
2455 maximum = curve[0xff];
2458 void CLASS kodak_262_load_raw()
2460 static const uchar kodak_tree[2][26] =
2461 { { 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 },
2462 { 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 } };
2465 int *strip, ns, c, row, col, chess, pi=0, pi1, pi2, pred, val;
2467 FORC(2) huff[c] = make_decoder (kodak_tree[c]);
2468 ns = (raw_height+63) >> 5;
2469 pixel = (uchar *) malloc (raw_width*32 + ns*4);
2470 merror (pixel, "kodak_262_load_raw()");
2471 strip = (int *) (pixel + raw_width*32);
2473 FORC(ns) strip[c] = get4();
2474 for (row=0; row < raw_height; row++) {
2475 if ((row & 31) == 0) {
2476 fseek (ifp, strip[row >> 5], SEEK_SET);
2480 for (col=0; col < raw_width; col++) {
2481 chess = (row + col) & 1;
2482 pi1 = chess ? pi-2 : pi-raw_width-1;
2483 pi2 = chess ? pi-2*raw_width : pi-raw_width+1;
2484 if (col <= chess) pi1 = -1;
2485 if (pi1 < 0) pi1 = pi2;
2486 if (pi2 < 0) pi2 = pi1;
2487 if (pi1 < 0 && col > 1) pi1 = pi2 = pi-2;
2488 pred = (pi1 < 0) ? 0 : (pixel[pi1] + pixel[pi2]) >> 1;
2489 pixel[pi] = val = pred + ljpeg_diff (huff[chess]);
2490 if (val >> 8) derror();
2491 val = curve[pixel[pi++]];
2496 FORC(2) free (huff[c]);
2499 int CLASS kodak_65000_decode (short *out, int bsize)
2504 int save, bits=0, i, j, len, diff;
2507 bsize = (bsize + 3) & -4;
2508 for (i=0; i < bsize; i+=2) {
2510 if ((blen[i ] = c & 15) > 12 ||
2511 (blen[i+1] = c >> 4) > 12 ) {
2512 fseek (ifp, save, SEEK_SET);
2513 for (i=0; i < bsize; i+=8) {
2514 read_shorts (raw, 6);
2515 out[i ] = raw[0] >> 12 << 8 | raw[2] >> 12 << 4 | raw[4] >> 12;
2516 out[i+1] = raw[1] >> 12 << 8 | raw[3] >> 12 << 4 | raw[5] >> 12;
2517 for (j=0; j < 6; j++)
2518 out[i+2+j] = raw[j] & 0xfff;
2523 if ((bsize & 7) == 4) {
2524 bitbuf = fgetc(ifp) << 8;
2525 bitbuf += fgetc(ifp);
2528 for (i=0; i < bsize; i++) {
2531 for (j=0; j < 32; j+=8)
2532 bitbuf += (INT64) fgetc(ifp) << (bits+(j^8));
2535 diff = bitbuf & (0xffff >> (16-len));
2538 if ((diff & (1 << (len-1))) == 0)
2539 diff -= (1 << len) - 1;
2545 void CLASS kodak_65000_load_raw()
2548 int row, col, len, pred[2], ret, i;
2550 for (row=0; row < height; row++)
2551 for (col=0; col < width; col+=256) {
2552 pred[0] = pred[1] = 0;
2553 len = MIN (256, width-col);
2554 ret = kodak_65000_decode (buf, len);
2555 for (i=0; i < len; i++)
2556 if ((RAW(row,col+i) = curve[ret ? buf[i] :
2557 (pred[i & 1] += buf[i])]) >> 12) derror();
2561 void CLASS kodak_ycbcr_load_raw()
2563 short buf[384], *bp;
2564 int row, col, len, c, i, j, k, y[2][2], cb, cr, rgb[3];
2568 for (row=0; row < height; row+=2)
2569 for (col=0; col < width; col+=128) {
2570 len = MIN (128, width-col);
2571 kodak_65000_decode (buf, len*3);
2572 y[0][1] = y[1][1] = cb = cr = 0;
2573 for (bp=buf, i=0; i < len; i+=2, bp+=2) {
2576 rgb[1] = -((cb + cr + 2) >> 2);
2577 rgb[2] = rgb[1] + cb;
2578 rgb[0] = rgb[1] + cr;
2579 for (j=0; j < 2; j++)
2580 for (k=0; k < 2; k++) {
2581 if ((y[j][k] = y[j][k^1] + *bp++) >> 10) derror();
2582 ip = image[(row+j)*width + col+i+k];
2583 FORC3 ip[c] = curve[LIM(y[j][k]+rgb[c], 0, 0xfff)];
2589 void CLASS kodak_rgb_load_raw()
2591 short buf[768], *bp;
2592 int row, col, len, c, i, rgb[3];
2593 ushort *ip=image[0];
2595 for (row=0; row < height; row++)
2596 for (col=0; col < width; col+=256) {
2597 len = MIN (256, width-col);
2598 kodak_65000_decode (buf, len*3);
2599 memset (rgb, 0, sizeof rgb);
2600 for (bp=buf, i=0; i < len; i++, ip+=4)
2601 FORC3 if ((ip[c] = rgb[c] += *bp++) >> 12) derror();
2605 void CLASS kodak_thumb_load_raw()
2608 colors = thumb_misc >> 5;
2609 for (row=0; row < height; row++)
2610 for (col=0; col < width; col++)
2611 read_shorts (image[row*width+col], colors);
2612 maximum = (1 << (thumb_misc & 31)) - 1;
2615 void CLASS sony_decrypt (unsigned *data, int len, int start, int key)
2617 unsigned p = sony_p, *pad = sony_pad;;
2619 for (p=0; p < 4; p++)
2620 pad[p] = key = key * 48828125 + 1;
2621 pad[3] = pad[3] << 1 | (pad[0]^pad[2]) >> 31;
2622 for (p=4; p < 127; p++)
2623 pad[p] = (pad[p-4]^pad[p-2]) << 1 | (pad[p-3]^pad[p-1]) >> 31;
2624 for (p=0; p < 127; p++)
2625 pad[p] = htonl(pad[p]);
2627 while (len-- && p++)
2628 *data++ ^= pad[(p-1) & 127] = pad[p & 127] ^ pad[(p+64) & 127];
2632 void CLASS sony_load_raw()
2636 unsigned i, key, row, col;
2638 fseek (ifp, 200896, SEEK_SET);
2639 fseek (ifp, (unsigned) fgetc(ifp)*4 - 1, SEEK_CUR);
2642 fseek (ifp, 164600, SEEK_SET);
2643 fread (head, 1, 40, ifp);
2644 sony_decrypt ((unsigned *) head, 10, 1, key);
2645 for (i=26; i-- > 22; )
2646 key = key << 8 | head[i];
2647 fseek (ifp, data_offset, SEEK_SET);
2648 for (row=0; row < raw_height; row++) {
2649 pixel = raw_image + row*raw_width;
2650 if (fread (pixel, 2, raw_width, ifp) < raw_width) derror();
2651 sony_decrypt ((unsigned *) pixel, raw_width/2, !row, key);
2652 for (col=0; col < raw_width; col++)
2653 if ((pixel[col] = ntohs(pixel[col])) >> 14) derror();
2658 void CLASS sony_arw_load_raw()
2661 static const ushort tab[18] =
2662 { 0xf11,0xf10,0xe0f,0xd0e,0xc0d,0xb0c,0xa0b,0x90a,0x809,
2663 0x708,0x607,0x506,0x405,0x304,0x303,0x300,0x202,0x201 };
2664 int i, c, n, col, row, sum=0;
2667 for (n=i=0; i < 18; i++)
2668 FORC(32768 >> (tab[i] >> 8)) huff[++n] = tab[i];
2670 for (col = raw_width; col--; )
2671 for (row=0; row < raw_height+1; row+=2) {
2672 if (row == raw_height) row = 1;
2673 if ((sum += ljpeg_diff(huff)) >> 12) derror();
2674 if (row < height) RAW(row,col) = sum;
2678 void CLASS sony_arw2_load_raw()
2682 int row, col, val, max, min, imax, imin, sh, bit, i;
2684 data = (uchar *) malloc (raw_width+1);
2685 merror (data, "sony_arw2_load_raw()");
2686 for (row=0; row < height; row++) {
2687 fread (data, 1, raw_width, ifp);
2688 for (dp=data, col=0; col < raw_width-30; dp+=16) {
2689 max = 0x7ff & (val = sget4(dp));
2690 min = 0x7ff & val >> 11;
2691 imax = 0x0f & val >> 22;
2692 imin = 0x0f & val >> 26;
2693 for (sh=0; sh < 4 && 0x80 << sh <= max-min; sh++);
2694 for (bit=30, i=0; i < 16; i++)
2695 if (i == imax) pix[i] = max;
2696 else if (i == imin) pix[i] = min;
2698 pix[i] = ((sget2(dp+(bit >> 3)) >> (bit & 7) & 0x7f) << sh) + min;
2699 if (pix[i] > 0x7ff) pix[i] = 0x7ff;
2702 for (i=0; i < 16; i++, col+=2)
2703 RAW(row,col) = curve[pix[i] << 1] >> 2;
2704 col -= col & 1 ? 1:31;
2710 void CLASS samsung_load_raw()
2712 int row, col, c, i, dir, op[4], len[4];
2715 for (row=0; row < raw_height; row++) {
2716 fseek (ifp, strip_offset+row*4, SEEK_SET);
2717 fseek (ifp, data_offset+get4(), SEEK_SET);
2719 FORC4 len[c] = row < 2 ? 7:4;
2720 for (col=0; col < raw_width; col+=16) {
2722 FORC4 op[c] = ph1_bits(2);
2723 FORC4 switch (op[c]) {
2724 case 3: len[c] = ph1_bits(4); break;
2725 case 2: len[c]--; break;
2728 for (c=0; c < 16; c+=2) {
2729 i = len[((c & 1) << 1) | (c >> 3)];
2730 RAW(row,col+c) = ((signed) ph1_bits(i) << (32-i) >> (32-i)) +
2731 (dir ? RAW(row+(~c | -2),col+c) : col ? RAW(row,col+(c | -2)) : 128);
2732 if (c == 14) c = -1;
2736 for (row=0; row < raw_height-1; row+=2)
2737 for (col=0; col < raw_width-1; col+=2)
2738 SWAP (RAW(row,col+1), RAW(row+1,col));
2741 void CLASS samsung2_load_raw()
2743 static const ushort tab[14] =
2744 { 0x304,0x307,0x206,0x205,0x403,0x600,0x709,
2745 0x80a,0x90b,0xa0c,0xa0d,0x501,0x408,0x402 };
2746 ushort huff[1026], vpred[2][2] = {{0,0},{0,0}}, hpred[2];
2747 int i, c, n, row, col, diff;
2750 for (n=i=0; i < 14; i++)
2751 FORC(1024 >> (tab[i] >> 8)) huff[++n] = tab[i];
2753 for (row=0; row < raw_height; row++)
2754 for (col=0; col < raw_width; col++) {
2755 diff = ljpeg_diff (huff);
2756 if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
2757 else hpred[col & 1] += diff;
2758 RAW(row,col) = hpred[col & 1];
2759 if (hpred[col & 1] >> tiff_bps) derror();
2763 void CLASS samsung3_load_raw()
2765 int opt, init, mag, pmode, row, tab, col, pred, diff, i, c;
2766 ushort lent[3][2], len[4], *prow[2];
2769 fseek (ifp, 9, SEEK_CUR);
2771 init = (get2(),get2());
2772 for (row=0; row < raw_height; row++) {
2773 fseek (ifp, (data_offset-ftell(ifp)) & 15, SEEK_CUR);
2776 FORC(6) ((ushort *)lent)[c] = row < 2 ? 7:4;
2777 prow[ row & 1] = &RAW(row-1,1-((row & 1) << 1)); // green
2778 prow[~row & 1] = &RAW(row-2,0); // red and blue
2779 for (tab=0; tab+15 < raw_width; tab+=16) {
2780 if (~opt & 4 && !(tab & 63)) {
2782 mag = i < 3 ? mag-'2'+"204"[i] : ph1_bits(12);
2785 pmode = 7 - 4*ph1_bits(1);
2786 else if (!ph1_bits(1))
2787 pmode = ph1_bits(3);
2788 if (opt & 1 || !ph1_bits(1)) {
2789 FORC4 len[c] = ph1_bits(2);
2791 i = ((row & 1) << 1 | (c & 1)) % 3;
2792 len[c] = len[c] < 3 ? lent[i][0]-'1'+"120"[len[c]] : ph1_bits(4);
2793 lent[i][0] = lent[i][1];
2794 lent[i][1] = len[c];
2798 col = tab + (((c & 7) << 1)^(c >> 3)^(row & 1));
2799 pred = (pmode == 7 || row < 2)
2800 ? (tab ? RAW(row,tab-2+(col & 1)) : init)
2801 : (prow[col & 1][col-'4'+"0224468"[pmode]] +
2802 prow[col & 1][col-'4'+"0244668"[pmode]] + 1) >> 1;
2803 diff = ph1_bits (i = len[c >> 2]);
2804 if (diff >> (i-1)) diff -= 1 << i;
2805 diff = diff * (mag*2+1) + mag;
2806 RAW(row,col) = pred + diff;
2812 #define HOLE(row) ((holes >> (((row) - raw_height) & 7)) & 1)
2814 /* Kudos to Rich Taylor for figuring out SMaL's compression algorithm. */
2815 void CLASS smal_decode_segment (unsigned seg[2][2], int holes)
2817 uchar hist[3][18] = {
2818 { 7, 7, 0, 0, 63, 55, 47, 39, 31, 23, 15, 7, 0 },
2819 { 7, 7, 0, 0, 63, 55, 47, 39, 31, 23, 15, 7, 0 },
2820 { 3, 3, 0, 0, 63, 47, 31, 15, 0 } };
2821 int low, high=0xff, carry=0, nbits=8;
2822 int pix, s, count, bin, next, i, sym[3];
2823 uchar diff, pred[]={0,0};
2824 ushort data=0, range=0;
2826 fseek (ifp, seg[0][1]+1, SEEK_SET);
2828 if (seg[1][0] > raw_width*raw_height)
2829 seg[1][0] = raw_width*raw_height;
2830 for (pix=seg[0][0]; pix < seg[1][0]; pix++) {
2831 for (s=0; s < 3; s++) {
2832 data = data << nbits | getbits(nbits);
2834 carry = (nbits += carry+1) < 1 ? nbits-1 : 0;
2835 while (--nbits >= 0)
2836 if ((data >> nbits & 0xff) == 0xff) break;
2838 data = ((data & ((1 << (nbits-1)) - 1)) << 1) |
2839 ((data + (((data & (1 << (nbits-1)))) << 1)) & (-1 << nbits));
2844 count = ((((data-range+1) & 0xffff) << 2) - 1) / (high >> 4);
2845 for (bin=0; hist[s][bin+5] > count; bin++);
2846 low = hist[s][bin+5] * (high >> 4) >> 2;
2847 if (bin) high = hist[s][bin+4] * (high >> 4) >> 2;
2849 for (nbits=0; high << nbits < 128; nbits++);
2850 range = (range+low) << nbits;
2853 if (++hist[s][2] > hist[s][3]) {
2854 next = (next+1) & hist[s][0];
2855 hist[s][3] = (hist[s][next+4] - hist[s][next+5]) >> 2;
2858 if (hist[s][hist[s][1]+4] - hist[s][hist[s][1]+5] > 1) {
2859 if (bin < hist[s][1])
2860 for (i=bin; i < hist[s][1]; i++) hist[s][i+5]--;
2861 else if (next <= bin)
2862 for (i=hist[s][1]; i < bin; i++) hist[s][i+5]++;
2867 diff = sym[2] << 5 | sym[1] << 2 | (sym[0] & 3);
2869 diff = diff ? -diff : 0x80;
2870 if (ftell(ifp) + 12 >= seg[1][1])
2872 raw_image[pix] = pred[pix & 1] += diff;
2873 if (!(pix & 1) && HOLE(pix / raw_width)) pix += 2;
2878 void CLASS smal_v6_load_raw()
2882 fseek (ifp, 16, SEEK_SET);
2885 seg[1][0] = raw_width * raw_height;
2886 seg[1][1] = INT_MAX;
2887 smal_decode_segment (seg, 0);
2890 int CLASS median4 (int *p)
2892 int min, max, sum, i;
2894 min = max = sum = p[0];
2895 for (i=1; i < 4; i++) {
2897 if (min > p[i]) min = p[i];
2898 if (max < p[i]) max = p[i];
2900 return (sum - min - max) >> 1;
2903 void CLASS fill_holes (int holes)
2905 int row, col, val[4];
2907 for (row=2; row < height-2; row++) {
2908 if (!HOLE(row)) continue;
2909 for (col=1; col < width-1; col+=4) {
2910 val[0] = RAW(row-1,col-1);
2911 val[1] = RAW(row-1,col+1);
2912 val[2] = RAW(row+1,col-1);
2913 val[3] = RAW(row+1,col+1);
2914 RAW(row,col) = median4(val);
2916 for (col=2; col < width-2; col+=4)
2917 if (HOLE(row-2) || HOLE(row+2))
2918 RAW(row,col) = (RAW(row,col-2) + RAW(row,col+2)) >> 1;
2920 val[0] = RAW(row,col-2);
2921 val[1] = RAW(row,col+2);
2922 val[2] = RAW(row-2,col);
2923 val[3] = RAW(row+2,col);
2924 RAW(row,col) = median4(val);
2929 void CLASS smal_v9_load_raw()
2931 unsigned seg[256][2], offset, nseg, holes, i;
2933 fseek (ifp, 67, SEEK_SET);
2935 nseg = (uchar) fgetc(ifp);
2936 fseek (ifp, offset, SEEK_SET);
2937 for (i=0; i < nseg*2; i++)
2938 ((unsigned *)seg)[i] = get4() + data_offset*(i & 1);
2939 fseek (ifp, 78, SEEK_SET);
2941 fseek (ifp, 88, SEEK_SET);
2942 seg[nseg][0] = raw_height * raw_width;
2943 seg[nseg][1] = get4() + data_offset;
2944 for (i=0; i < nseg; i++)
2945 smal_decode_segment (seg+i, holes);
2946 if (holes) fill_holes (holes);
2949 void CLASS redcine_load_raw()
2960 in = jas_stream_fopen (ifname, "rb");
2961 jas_stream_seek (in, data_offset+20, SEEK_SET);
2962 jimg = jas_image_decode (in, -1, 0);
2963 if (!jimg) longjmp (failure, 3);
2964 jmat = jas_matrix_create (height/2, width/2);
2965 merror (jmat, "redcine_load_raw()");
2966 img = (ushort *) calloc ((height+2), (width+2)*2);
2967 merror (img, "redcine_load_raw()");
2969 jas_image_readcmpt (jimg, c, 0, 0, width/2, height/2, jmat);
2970 data = jas_matrix_getref (jmat, 0, 0);
2971 for (row = c >> 1; row < height; row+=2)
2972 for (col = c & 1; col < width; col+=2)
2973 img[(row+1)*(width+2)+col+1] = data[(row/2)*(width/2)+col/2];
2975 for (col=1; col <= width; col++) {
2976 img[col] = img[2*(width+2)+col];
2977 img[(height+1)*(width+2)+col] = img[(height-1)*(width+2)+col];
2979 for (row=0; row < height+2; row++) {
2980 img[row*(width+2)] = img[row*(width+2)+2];
2981 img[(row+1)*(width+2)-1] = img[(row+1)*(width+2)-3];
2983 for (row=1; row <= height; row++) {
2984 pix = img + row*(width+2) + (col = 1 + (FC(row,1) & 1));
2985 for ( ; col <= width; col+=2, pix+=2) {
2986 c = (((pix[0] - 0x800) << 3) +
2987 pix[-(width+2)] + pix[width+2] + pix[-1] + pix[1]) >> 2;
2988 pix[0] = LIM(c,0,4095);
2991 for (row=0; row < height; row++)
2992 for (col=0; col < width; col++)
2993 RAW(row,col) = curve[img[(row+1)*(width+2)+col+1]];
2995 jas_matrix_destroy (jmat);
2996 jas_image_destroy (jimg);
2997 jas_stream_close (in);
3001 /* RESTRICTED code starts here */
3003 void CLASS foveon_decoder (unsigned size, unsigned code)
3005 unsigned *huff = fov_huff;
3010 for (i=0; i < size; i++)
3012 memset (first_decode, 0, sizeof first_decode);
3013 free_decode = first_decode;
3015 cur = free_decode++;
3016 if (free_decode > first_decode+2048) {
3017 fprintf (stderr,_("%s: decoder table overflow\n"), ifname);
3018 longjmp (failure, 2);
3021 for (i=0; i < size; i++)
3022 if (huff[i] == code) {
3026 if ((len = code >> 27) > 26) return;
3027 code = (len+1) << 27 | (code & 0x3ffffff) << 1;
3029 cur->branch[0] = free_decode;
3030 foveon_decoder (size, code);
3031 cur->branch[1] = free_decode;
3032 foveon_decoder (size, code+1);
3035 void CLASS foveon_thumb()
3037 unsigned bwide, row, col, bitbuf=0, bit=1, c, i;
3039 struct decode *dindex;
3043 fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
3045 if (bwide < thumb_width*3) return;
3046 buf = (char *) malloc (bwide);
3047 merror (buf, "foveon_thumb()");
3048 for (row=0; row < thumb_height; row++) {
3049 fread (buf, 1, bwide, ifp);
3050 fwrite (buf, 3, thumb_width, ofp);
3055 foveon_decoder (256, 0);
3057 for (row=0; row < thumb_height; row++) {
3058 memset (pred, 0, sizeof pred);
3060 for (bit=col=0; col < thumb_width; col++)
3062 for (dindex=first_decode; dindex->branch[0]; ) {
3063 if ((bit = (bit-1) & 31) == 31)
3064 for (i=0; i < 4; i++)
3065 bitbuf = (bitbuf << 8) + fgetc(ifp);
3066 dindex = dindex->branch[bitbuf >> bit & 1];
3068 pred[c] += dindex->leaf;
3069 fputc (pred[c], ofp);
3074 void CLASS foveon_sd_load_raw()
3076 struct decode *dindex;
3079 int pred[3], row, col, bit=-1, c, i;
3081 read_shorts ((ushort *) diff, 1024);
3082 if (!load_flags) foveon_decoder (1024, 0);
3084 for (row=0; row < height; row++) {
3085 memset (pred, 0, sizeof pred);
3086 if (!bit && !load_flags && atoi(model+2) < 14) get4();
3087 for (col=bit=0; col < width; col++) {
3090 FORC3 pred[2-c] += diff[bitbuf >> c*10 & 0x3ff];
3093 for (dindex=first_decode; dindex->branch[0]; ) {
3094 if ((bit = (bit-1) & 31) == 31)
3095 for (i=0; i < 4; i++)
3096 bitbuf = (bitbuf << 8) + fgetc(ifp);
3097 dindex = dindex->branch[bitbuf >> bit & 1];
3099 pred[c] += diff[dindex->leaf];
3100 if (pred[c] >> 16 && ~pred[c] >> 16) derror();
3102 FORC3 image[row*width+col][c] = pred[c];
3107 void CLASS foveon_huff (ushort *huff)
3109 int i, j, clen, code;
3112 for (i=0; i < 13; i++) {
3115 for (j=0; j < 256 >> clen; )
3116 huff[code+ ++j] = clen << 8 | i;
3121 void CLASS foveon_dp_load_raw()
3123 unsigned c, roff[4], row, col, diff;
3124 ushort huff[512], vpred[2][2], hpred[2];
3126 fseek (ifp, 8, SEEK_CUR);
3129 FORC3 roff[c+1] = -(-(roff[c] + get4()) & -16);
3131 fseek (ifp, data_offset+roff[c], SEEK_SET);
3133 vpred[0][0] = vpred[0][1] = vpred[1][0] = vpred[1][1] = 512;
3134 for (row=0; row < height; row++) {
3135 for (col=0; col < width; col++) {
3136 diff = ljpeg_diff(huff);
3137 if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
3138 else hpred[col & 1] += diff;
3139 image[row*width+col][c] = hpred[col & 1];
3145 void CLASS foveon_load_camf()
3147 unsigned type, wide, high, i, j, row, col, diff;
3148 ushort huff[258], vpred[2][2] = {{512,512},{512,512}}, hpred[2];
3150 fseek (ifp, meta_offset, SEEK_SET);
3151 type = get4(); get4(); get4();
3155 fread (meta_data, 1, meta_length, ifp);
3156 for (i=0; i < meta_length; i++) {
3157 high = (high * 1597 + 51749) % 244944;
3158 wide = high * (INT64) 301593171 >> 24;
3159 meta_data[i] ^= ((((high << 8) - wide) >> 1) + wide) >> 17;
3161 } else if (type == 4) {
3163 meta_data = (char *) malloc (meta_length = wide*high*3/2);
3164 merror (meta_data, "foveon_load_camf()");
3168 for (j=row=0; row < high; row++) {
3169 for (col=0; col < wide; col++) {
3170 diff = ljpeg_diff(huff);
3171 if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
3172 else hpred[col & 1] += diff;
3174 meta_data[j++] = hpred[0] >> 4;
3175 meta_data[j++] = hpred[0] << 4 | hpred[1] >> 8;
3176 meta_data[j++] = hpred[1];
3181 fprintf (stderr,_("%s has unknown CAMF type %d.\n"), ifname, type);
3184 const char * CLASS foveon_camf_param (const char *block, const char *param)
3187 char *pos, *cp, *dp;
3189 for (idx=0; idx < meta_length; idx += sget4(pos+8)) {
3190 pos = meta_data + idx;
3191 if (strncmp (pos, "CMb", 3)) break;
3192 if (pos[3] != 'P') continue;
3193 if (strcmp (block, pos+sget4(pos+12))) continue;
3194 cp = pos + sget4(pos+16);
3196 dp = pos + sget4(cp+4);
3199 if (!strcmp (param, dp+sget4(cp)))
3200 return dp+sget4(cp+4);
3206 void * CLASS foveon_camf_matrix (unsigned dim[3], const char *name)
3208 unsigned i, idx, type, ndim, size, *mat;
3209 char *pos, *cp, *dp;
3212 for (idx=0; idx < meta_length; idx += sget4(pos+8)) {
3213 pos = meta_data + idx;
3214 if (strncmp (pos, "CMb", 3)) break;
3215 if (pos[3] != 'M') continue;
3216 if (strcmp (name, pos+sget4(pos+12))) continue;
3217 dim[0] = dim[1] = dim[2] = 1;
3218 cp = pos + sget4(pos+16);
3220 if ((ndim = sget4(cp+4)) > 3) break;
3221 dp = pos + sget4(cp+8);
3222 for (i=ndim; i--; ) {
3226 if ((dsize = (double) dim[0]*dim[1]*dim[2]) > meta_length/4) break;
3227 mat = (unsigned *) malloc ((size = dsize) * 4);
3228 merror (mat, "foveon_camf_matrix()");
3229 for (i=0; i < size; i++)
3230 if (type && type != 6)
3231 mat[i] = sget4(dp + i*4);
3233 mat[i] = sget4(dp + i*2) & 0xffff;
3236 fprintf (stderr,_("%s: \"%s\" matrix not found!\n"), ifname, name);
3240 int CLASS foveon_fixed (void *ptr, int size, const char *name)
3245 if (!name) return 0;
3246 dp = foveon_camf_matrix (dim, name);
3248 memcpy (ptr, dp, size*4);
3253 float CLASS foveon_avg (short *pix, int range[2], float cfilt)
3256 float val, min=FLT_MAX, max=-FLT_MAX, sum=0;
3258 for (i=range[0]; i <= range[1]; i++) {
3259 sum += val = pix[i*4] + (pix[i*4]-pix[(i-1)*4]) * cfilt;
3260 if (min > val) min = val;
3261 if (max < val) max = val;
3263 if (range[1] - range[0] == 1) return sum/2;
3264 return (sum - min - max) / (range[1] - range[0] - 1);
3267 short * CLASS foveon_make_curve (double max, double mul, double filt)
3273 if (!filt) filt = 0.8;
3274 size = 4*M_PI*max / filt;
3275 if (size > INT_MAX-1) size = INT_MAX-1;
3276 curve = (short *) calloc (size+1, sizeof *curve);
3277 merror (curve, "foveon_make_curve()");
3279 for (i=0; i < size; i++) {
3281 curve[i+1] = (cos(x)+1)/2 * tanh(i*filt/mul) * mul + 0.5;
3286 void CLASS foveon_make_curves
3287 (short **curvep, float dq[3], float div[3], float filt)
3289 double mul[3], max=0;
3292 FORC3 mul[c] = dq[c]/div[c];
3293 FORC3 if (max < mul[c]) max = mul[c];
3294 FORC3 curvep[c] = foveon_make_curve (max, mul[c], filt);
3297 int CLASS foveon_apply_curve (short *curve, int i)
3299 if (abs(i) >= curve[0]) return 0;
3300 return i < 0 ? -curve[1-i] : curve[1+i];
3303 #define image ((short (*)[4]) image)
3305 void CLASS foveon_interpolate()
3307 static const short hood[] = { -1,-1, -1,0, -1,1, 0,-1, 0,1, 1,-1, 1,0, 1,1 };
3308 short *pix, prev[3], *curve[8], (*shrink)[3];
3309 float cfilt, ddft[3][3][2], ppm[3][3][3];
3310 float cam_xyz[3][3], correct[3][3], last[3][3], trans[3][3];
3311 float chroma_dq[3], color_dq[3], diag[3][3], div[3];
3312 float (*black)[3], (*sgain)[3], (*sgrow)[3];
3313 float fsum[3], val, frow, num;
3314 int row, col, c, i, j, diff, sgx, irow, sum, min, max, limit;
3315 int dscr[2][2], dstb[4], (*smrow[7])[3], total[4], ipix[3];
3316 int work[3][3], smlast, smred, smred_p, dev[3];
3317 int satlev[3], keep[4], active[4];
3318 unsigned dim[3], *badpix;
3319 double dsum, trsum[3];
3322 // clear local storage
3323 pix = 0; ZERO(prev); ZERO(curve); ZERO(shrink);
3324 cfilt = 0; ZERO(ddft); ZERO(ppm);
3325 ZERO(cam_xyz); ZERO(correct); ZERO(last); ZERO(trans);
3326 ZERO(chroma_dq); ZERO(color_dq); ZERO(diag); ZERO(div);
3327 ZERO(black); ZERO(sgain); ZERO(sgrow);
3328 ZERO(fsum); val = frow = num = 0;
3329 row = col = c = i = j = diff = sgx = irow = sum = min = max = limit = 0;
3330 ZERO(dscr); ZERO(dstb); ZERO(smrow); ZERO(total); ZERO(ipix);
3331 ZERO(work); ZERO(smlast); ZERO(smred); smred_p=0; ZERO(dev);
3332 ZERO(satlev); ZERO(keep); ZERO(active);
3333 ZERO(dim); badpix = 0;
3334 dsum = 0; ZERO(trsum);
3339 fprintf (stderr,_("Foveon interpolation...\n"));
3342 foveon_fixed (dscr, 4, "DarkShieldColRange");
3343 foveon_fixed (ppm[0][0], 27, "PostPolyMatrix");
3344 foveon_fixed (satlev, 3, "SaturationLevel");
3345 foveon_fixed (keep, 4, "KeepImageArea");
3346 foveon_fixed (active, 4, "ActiveImageArea");
3347 foveon_fixed (chroma_dq, 3, "ChromaDQ");
3348 foveon_fixed (color_dq, 3,
3349 foveon_camf_param ("IncludeBlocks", "ColorDQ") ?
3350 "ColorDQ" : "ColorDQCamRGB");
3351 if (foveon_camf_param ("IncludeBlocks", "ColumnFilter"))
3352 foveon_fixed (&cfilt, 1, "ColumnFilter");
3354 memset (ddft, 0, sizeof ddft);
3355 if (!foveon_camf_param ("IncludeBlocks", "DarkDrift")
3356 || !foveon_fixed (ddft[1][0], 12, "DarkDrift"))
3357 for (i=0; i < 2; i++) {
3358 foveon_fixed (dstb, 4, i ? "DarkShieldBottom":"DarkShieldTop");
3359 for (row = dstb[1]; row <= dstb[3]; row++)
3360 for (col = dstb[0]; col <= dstb[2]; col++)
3361 FORC3 ddft[i+1][c][1] += (short) image[row*width+col][c];
3362 FORC3 ddft[i+1][c][1] /= (dstb[3]-dstb[1]+1) * (dstb[2]-dstb[0]+1);
3365 if (!(cp = foveon_camf_param ("WhiteBalanceIlluminants", model2)))
3366 { fprintf (stderr,_("%s: Invalid white balance \"%s\"\n"), ifname, model2);
3368 foveon_fixed (cam_xyz, 9, cp);
3369 foveon_fixed (correct, 9,
3370 foveon_camf_param ("WhiteBalanceCorrections", model2));
3371 memset (last, 0, sizeof last);
3372 for (i=0; i < 3; i++)
3373 for (j=0; j < 3; j++)
3374 FORC3 last[i][j] += correct[i][c] * cam_xyz[c][j];
3376 #define LAST(x,y) last[(i+x)%3][(c+y)%3]
3377 for (i=0; i < 3; i++)
3378 FORC3 diag[c][i] = LAST(1,1)*LAST(2,2) - LAST(1,2)*LAST(2,1);
3380 FORC3 div[c] = diag[c][0]*0.3127 + diag[c][1]*0.329 + diag[c][2]*0.3583;
3381 sprintf (str, "%sRGBNeutral", model2);
3382 if (foveon_camf_param ("IncludeBlocks", str))
3383 foveon_fixed (div, 3, str);
3385 FORC3 if (num < div[c]) num = div[c];
3386 FORC3 div[c] /= num;
3388 memset (trans, 0, sizeof trans);
3389 for (i=0; i < 3; i++)
3390 for (j=0; j < 3; j++)
3391 FORC3 trans[i][j] += rgb_cam[i][c] * last[c][j] * div[j];
3392 FORC3 trsum[c] = trans[c][0] + trans[c][1] + trans[c][2];
3393 dsum = (6*trsum[0] + 11*trsum[1] + 3*trsum[2]) / 20;
3394 for (i=0; i < 3; i++)
3395 FORC3 last[i][c] = trans[i][c] * dsum / trsum[i];
3396 memset (trans, 0, sizeof trans);
3397 for (i=0; i < 3; i++)
3398 for (j=0; j < 3; j++)
3399 FORC3 trans[i][j] += (i==c ? 32 : -1) * last[c][j] / 30;
3401 foveon_make_curves (curve, color_dq, div, cfilt);
3402 FORC3 chroma_dq[c] /= 3;
3403 foveon_make_curves (curve+3, chroma_dq, div, cfilt);
3404 FORC3 dsum += chroma_dq[c] / div[c];
3405 curve[6] = foveon_make_curve (dsum, dsum, cfilt);
3406 curve[7] = foveon_make_curve (dsum*2, dsum*2, cfilt);
3408 sgain = (float (*)[3]) foveon_camf_matrix (dim, "SpatialGain");
3410 sgrow = (float (*)[3]) calloc (dim[1], sizeof *sgrow);
3411 sgx = (width + dim[1]-2) / (dim[1]-1);
3413 black = (float (*)[3]) calloc (height, sizeof *black);
3414 for (row=0; row < height; row++) {
3415 for (i=0; i < 6; i++)
3416 ((float *)ddft[0])[i] = ((float *)ddft[1])[i] +
3417 row / (height-1.0) * (((float *)ddft[2])[i] - ((float *)ddft[1])[i]);
3418 FORC3 black[row][c] =
3419 ( foveon_avg (image[row*width]+c, dscr[0], cfilt) +
3420 foveon_avg (image[row*width]+c, dscr[1], cfilt) * 3
3421 - ddft[0][c][0] ) / 4 - ddft[0][c][1];
3423 memcpy (black, black+8, sizeof *black*8);
3424 memcpy (black+height-11, black+height-22, 11*sizeof *black);
3425 memcpy (last, black, sizeof last);
3427 for (row=1; row < height-1; row++) {
3428 FORC3 if (last[1][c] > last[0][c]) {
3429 if (last[1][c] > last[2][c])
3430 black[row][c] = (last[0][c] > last[2][c]) ? last[0][c]:last[2][c];
3432 if (last[1][c] < last[2][c])
3433 black[row][c] = (last[0][c] < last[2][c]) ? last[0][c]:last[2][c];
3434 memmove (last, last+1, 2*sizeof last[0]);
3435 memcpy (last[2], black[row+1], sizeof last[2]);
3437 FORC3 black[row][c] = (last[0][c] + last[1][c])/2;
3438 FORC3 black[0][c] = (black[1][c] + black[3][c])/2;
3440 val = 1 - exp(-1/24.0);
3441 memcpy (fsum, black, sizeof fsum);
3442 for (row=1; row < height; row++)
3443 FORC3 fsum[c] += black[row][c] =
3444 (black[row][c] - black[row-1][c])*val + black[row-1][c];
3445 memcpy (last[0], black[height-1], sizeof last[0]);
3446 FORC3 fsum[c] /= height;
3447 for (row = height; row--; )
3448 FORC3 last[0][c] = black[row][c] =
3449 (black[row][c] - fsum[c] - last[0][c])*val + last[0][c];
3451 memset (total, 0, sizeof total);
3452 for (row=2; row < height; row+=4)
3453 for (col=2; col < width; col+=4) {
3454 FORC3 total[c] += (short) image[row*width+col][c];
3457 for (row=0; row < height; row++)
3458 FORC3 black[row][c] += fsum[c]/2 + total[c]/(total[3]*100.0);
3460 for (row=0; row < height; row++) {
3461 for (i=0; i < 6; i++)
3462 ((float *)ddft[0])[i] = ((float *)ddft[1])[i] +
3463 row / (height-1.0) * (((float *)ddft[2])[i] - ((float *)ddft[1])[i]);
3464 pix = image[row*width];
3465 memcpy (prev, pix, sizeof prev);
3466 frow = row / (height-1.0) * (dim[2]-1);
3467 if ((irow = frow) == dim[2]-1) irow--;
3469 for (i=0; i < dim[1]; i++)
3470 FORC3 sgrow[i][c] = sgain[ irow *dim[1]+i][c] * (1-frow) +
3471 sgain[(irow+1)*dim[1]+i][c] * frow;
3472 for (col=0; col < width; col++) {
3474 diff = pix[c] - prev[c];
3476 ipix[c] = pix[c] + floor ((diff + (diff*diff >> 14)) * cfilt
3477 - ddft[0][c][1] - ddft[0][c][0] * ((float) col/width - 0.5)
3481 work[0][c] = ipix[c] * ipix[c] >> 14;
3482 work[2][c] = ipix[c] * work[0][c] >> 14;
3483 work[1][2-c] = ipix[(c+1) % 3] * ipix[(c+2) % 3] >> 14;
3486 for (val=i=0; i < 3; i++)
3487 for ( j=0; j < 3; j++)
3488 val += ppm[c][i][j] * work[i][j];
3489 ipix[c] = floor ((ipix[c] + floor(val)) *
3490 ( sgrow[col/sgx ][c] * (sgx - col%sgx) +
3491 sgrow[col/sgx+1][c] * (col%sgx) ) / sgx / div[c]);
3492 if (ipix[c] > 32000) ipix[c] = 32000;
3502 if ((badpix = (unsigned *) foveon_camf_matrix (dim, "BadPixels"))) {
3503 for (i=0; i < dim[0]; i++) {
3504 col = (badpix[i] >> 8 & 0xfff) - keep[0];
3505 row = (badpix[i] >> 20 ) - keep[1];
3506 if ((unsigned)(row-1) > height-3 || (unsigned)(col-1) > width-3)
3508 memset (fsum, 0, sizeof fsum);
3509 for (sum=j=0; j < 8; j++)
3510 if (badpix[i] & (1 << j)) {
3511 FORC3 fsum[c] += (short)
3512 image[(row+hood[j*2])*width+col+hood[j*2+1]][c];
3515 if (sum) FORC3 image[row*width+col][c] = fsum[c]/sum;
3520 /* Array for 5x5 Gaussian averaging of red values */
3521 smrow[6] = (int (*)[3]) calloc (width*5, sizeof **smrow);
3522 merror (smrow[6], "foveon_interpolate()");
3523 for (i=0; i < 5; i++)
3524 smrow[i] = smrow[6] + i*width;
3526 /* Sharpen the reds against these Gaussian averages */
3527 for (smlast=-1, row=2; row < height-2; row++) {
3528 while (smlast < row+2) {
3529 for (i=0; i < 6; i++)
3530 smrow[(i+5) % 6] = smrow[i];
3531 pix = image[++smlast*width+2];
3532 for (col=2; col < width-2; col++) {
3534 (pix[0]*6 + (pix[-4]+pix[4])*4 + pix[-8]+pix[8] + 8) >> 4;
3538 pix = image[row*width+2];
3539 for (col=2; col < width-2; col++) {
3540 smred = ( 6 * smrow[2][col][0]
3541 + 4 * (smrow[1][col][0] + smrow[3][col][0])
3542 + smrow[0][col][0] + smrow[4][col][0] + 8 ) >> 4;
3545 i = pix[0] + ((pix[0] - ((smred*7 + smred_p) >> 3)) >> 3);
3546 if (i > 32000) i = 32000;
3553 /* Adjust the brighter pixels for better linearity */
3556 i = satlev[c] / div[c];
3557 if (min > i) min = i;
3559 limit = min * 9 >> 4;
3560 for (pix=image[0]; pix < image[height*width]; pix+=4) {
3561 if (pix[0] <= limit || pix[1] <= limit || pix[2] <= limit)
3564 for (c=1; c < 3; c++) {
3565 if (min > pix[c]) min = pix[c];
3566 if (max < pix[c]) max = pix[c];
3568 if (min >= limit*2) {
3569 pix[0] = pix[1] = pix[2] = max;
3571 i = 0x4000 - ((min - limit) << 14) / limit;
3572 i = 0x4000 - (i*i >> 14);
3574 FORC3 pix[c] += (max - pix[c]) * i >> 14;
3578 Because photons that miss one detector often hit another,
3579 the sum R+G+B is much less noisy than the individual colors.
3580 So smooth the hues without smoothing the total.
3582 for (smlast=-1, row=2; row < height-2; row++) {
3583 while (smlast < row+2) {
3584 for (i=0; i < 6; i++)
3585 smrow[(i+5) % 6] = smrow[i];
3586 pix = image[++smlast*width+2];
3587 for (col=2; col < width-2; col++) {
3588 FORC3 smrow[4][col][c] = (pix[c-4]+2*pix[c]+pix[c+4]+2) >> 2;
3592 pix = image[row*width+2];
3593 for (col=2; col < width-2; col++) {
3594 FORC3 dev[c] = -foveon_apply_curve (curve[7], pix[c] -
3595 ((smrow[1][col][c] + 2*smrow[2][col][c] + smrow[3][col][c]) >> 2));
3596 sum = (dev[0] + dev[1] + dev[2]) >> 3;
3597 FORC3 pix[c] += dev[c] - sum;
3601 for (smlast=-1, row=2; row < height-2; row++) {
3602 while (smlast < row+2) {
3603 for (i=0; i < 6; i++)
3604 smrow[(i+5) % 6] = smrow[i];
3605 pix = image[++smlast*width+2];
3606 for (col=2; col < width-2; col++) {
3607 FORC3 smrow[4][col][c] =
3608 (pix[c-8]+pix[c-4]+pix[c]+pix[c+4]+pix[c+8]+2) >> 2;
3612 pix = image[row*width+2];
3613 for (col=2; col < width-2; col++) {
3614 for (total[3]=375, sum=60, c=0; c < 3; c++) {
3615 for (total[c]=i=0; i < 5; i++)
3616 total[c] += smrow[i][col][c];
3617 total[3] += total[c];
3620 if (sum < 0) sum = 0;
3621 j = total[3] > 375 ? (sum << 16) / total[3] : sum * 174;
3622 FORC3 pix[c] += foveon_apply_curve (curve[6],
3623 ((j*total[c] + 0x8000) >> 16) - pix[c]);
3628 /* Transform the image to a different colorspace */
3629 for (pix=image[0]; pix < image[height*width]; pix+=4) {
3630 FORC3 pix[c] -= foveon_apply_curve (curve[c], pix[c]);
3631 sum = (pix[0]+pix[1]+pix[1]+pix[2]) >> 2;
3632 FORC3 pix[c] -= foveon_apply_curve (curve[c], pix[c]-sum);
3634 for (dsum=i=0; i < 3; i++)
3635 dsum += trans[c][i] * pix[i];
3636 if (dsum < 0) dsum = 0;
3637 if (dsum > 24000) dsum = 24000;
3638 ipix[c] = dsum + 0.5;
3640 FORC3 pix[c] = ipix[c];
3643 /* Smooth the image bottom-to-top and save at 1/4 scale */
3644 shrink = (short (*)[3]) calloc ((height/4), (width/4)*sizeof *shrink);
3645 merror (shrink, "foveon_interpolate()");
3646 for (row = height/4; row--; )
3647 for (col=0; col < width/4; col++) {
3648 ipix[0] = ipix[1] = ipix[2] = 0;
3649 for (i=0; i < 4; i++)
3650 for (j=0; j < 4; j++)
3651 FORC3 ipix[c] += image[(row*4+i)*width+col*4+j][c];
3653 if (row+2 > height/4)
3654 shrink[row*(width/4)+col][c] = ipix[c] >> 4;
3656 shrink[row*(width/4)+col][c] =
3657 (shrink[(row+1)*(width/4)+col][c]*1840 + ipix[c]*141 + 2048) >> 12;
3659 /* From the 1/4-scale image, smooth right-to-left */
3660 for (row=0; row < (height & ~3); row++) {
3661 ipix[0] = ipix[1] = ipix[2] = 0;
3663 for (col = width & ~3 ; col--; )
3664 FORC3 smrow[0][col][c] = ipix[c] =
3665 (shrink[(row/4)*(width/4)+col/4][c]*1485 + ipix[c]*6707 + 4096) >> 13;
3667 /* Then smooth left-to-right */
3668 ipix[0] = ipix[1] = ipix[2] = 0;
3669 for (col=0; col < (width & ~3); col++)
3670 FORC3 smrow[1][col][c] = ipix[c] =
3671 (smrow[0][col][c]*1485 + ipix[c]*6707 + 4096) >> 13;
3673 /* Smooth top-to-bottom */
3675 memcpy (smrow[2], smrow[1], sizeof **smrow * width);
3677 for (col=0; col < (width & ~3); col++)
3678 FORC3 smrow[2][col][c] =
3679 (smrow[2][col][c]*6707 + smrow[1][col][c]*1485 + 4096) >> 13;
3681 /* Adjust the chroma toward the smooth values */
3682 for (col=0; col < (width & ~3); col++) {
3683 for (i=j=30, c=0; c < 3; c++) {
3684 i += smrow[2][col][c];
3685 j += image[row*width+col][c];
3688 for (sum=c=0; c < 3; c++) {
3689 ipix[c] = foveon_apply_curve (curve[c+3],
3690 ((smrow[2][col][c] * j + 0x8000) >> 16) - image[row*width+col][c]);
3695 i = image[row*width+col][c] + ipix[c] - sum;
3697 image[row*width+col][c] = i;
3703 for (i=0; i < 8; i++)
3706 /* Trim off the black border */
3707 active[1] -= keep[1];
3709 i = active[2] - active[0];
3710 for (row=0; row < active[3]-active[1]; row++)
3711 memcpy (image[row*i], image[(row+active[1])*width+active[0]],
3718 /* RESTRICTED code ends here */
3720 void CLASS crop_masked_pixels()
3723 unsigned r, c, m, mblack[8], zero, val;
3725 if (load_raw == &CLASS phase_one_load_raw ||
3726 load_raw == &CLASS phase_one_load_raw_c)
3727 phase_one_correct();
3729 for (row=0; row < raw_height-top_margin*2; row++) {
3730 for (col=0; col < fuji_width << !fuji_layout; col++) {
3732 r = fuji_width - 1 - col + (row >> 1);
3733 c = col + ((row+1) >> 1);
3735 r = fuji_width - 1 + row - (col >> 1);
3736 c = row + ((col+1) >> 1);
3738 if (r < height && c < width)
3739 BAYER(r,c) = RAW(row+top_margin,col+left_margin);
3743 for (row=0; row < height; row++)
3744 for (col=0; col < width; col++)
3745 BAYER2(row,col) = RAW(row+top_margin,col+left_margin);
3747 if (mask[0][3] > 0) goto mask_set;
3748 if (load_raw == &CLASS canon_load_raw ||
3749 load_raw == &CLASS lossless_jpeg_load_raw) {
3750 mask[0][1] = mask[1][1] += 2;
3754 if (load_raw == &CLASS canon_600_load_raw ||
3755 load_raw == &CLASS sony_load_raw ||
3756 (load_raw == &CLASS eight_bit_load_raw && strncmp(model,"DC2",3)) ||
3757 load_raw == &CLASS kodak_262_load_raw ||
3758 (load_raw == &CLASS packed_load_raw && (load_flags & 32))) {
3760 mask[0][0] = mask[1][0] = top_margin;
3761 mask[0][2] = mask[1][2] = top_margin+height;
3762 mask[0][3] += left_margin;
3763 mask[1][1] += left_margin+width;
3764 mask[1][3] += raw_width;
3766 if (load_raw == &CLASS nokia_load_raw) {
3767 mask[0][2] = top_margin;
3771 memset (mblack, 0, sizeof mblack);
3772 for (zero=m=0; m < 8; m++)
3773 for (row=MAX(mask[m][0],0); row < MIN(mask[m][2],raw_height); row++)
3774 for (col=MAX(mask[m][1],0); col < MIN(mask[m][3],raw_width); col++) {
3775 c = FC(row-top_margin,col-left_margin);
3776 mblack[c] += val = RAW(row,col);
3780 if (load_raw == &CLASS canon_600_load_raw && width < raw_width) {
3781 black = (mblack[0]+mblack[1]+mblack[2]+mblack[3]) /
3782 (mblack[4]+mblack[5]+mblack[6]+mblack[7]) - 4;
3783 canon_600_correct();
3784 } else if (zero < mblack[4] && mblack[5] && mblack[6] && mblack[7]) {
3785 FORC4 cblack[c] = mblack[c] / mblack[4+c];
3786 cblack[4] = cblack[5] = cblack[6] = 0;
3790 void CLASS remove_zeroes()
3792 unsigned row, col, tot, n, r, c;
3794 for (row=0; row < height; row++)
3795 for (col=0; col < width; col++)
3796 if (BAYER(row,col) == 0) {
3798 for (r = row-2; r <= row+2; r++)
3799 for (c = col-2; c <= col+2; c++)
3800 if (r < height && c < width &&
3801 FC(r,c) == FC(row,col) && BAYER(r,c))
3802 tot += (n++,BAYER(r,c));
3803 if (n) BAYER(row,col) = tot/n;
3808 Seach from the current directory up to the root looking for
3809 a ".badpixels" file, and fix those pixels now.
3811 void CLASS bad_pixels (const char *cfname)
3814 char *fname, *cp, line[128];
3815 int len, time, row, col, r, c, rad, tot, n, fixed=0;
3817 if (!filters) return;
3819 fp = fopen (cfname, "r");
3821 for (len=32 ; ; len *= 2) {
3822 fname = (char *) malloc (len);
3824 if (getcwd (fname, len-16)) break;
3826 if (errno != ERANGE) return;
3828 #if defined(WIN32) || defined(DJGPP)
3829 if (fname[1] == ':')
3830 memmove (fname, fname+2, len-2);
3831 for (cp=fname; *cp; cp++)
3832 if (*cp == '\\') *cp = '/';
3834 cp = fname + strlen(fname);
3835 if (cp[-1] == '/') cp--;
3836 while (*fname == '/') {
3837 strcpy (cp, "/.badpixels");
3838 if ((fp = fopen (fname, "r"))) break;
3839 if (cp == fname) break;
3840 while (*--cp != '/');
3845 while (fgets (line, 128, fp)) {
3846 cp = strchr (line, '#');
3848 if (sscanf (line, "%d %d %d", &col, &row, &time) != 3) continue;
3849 if ((unsigned) col >= width || (unsigned) row >= height) continue;
3850 if (time > timestamp) continue;
3851 for (tot=n=0, rad=1; rad < 3 && n==0; rad++)
3852 for (r = row-rad; r <= row+rad; r++)
3853 for (c = col-rad; c <= col+rad; c++)
3854 if ((unsigned) r < height && (unsigned) c < width &&
3855 (r != row || c != col) && fcol(r,c) == fcol(row,col)) {
3859 BAYER2(row,col) = tot/n;
3862 fprintf (stderr,_("Fixed dead pixels at:"));
3863 fprintf (stderr, " %d,%d", col, row);
3866 if (fixed) fputc ('\n', stderr);
3870 void CLASS subtract (const char *fname)
3873 int dim[3]={0,0,0}, comment=0, number=0, error=0, nd=0, c, row, col;
3876 if (!(fp = fopen (fname, "rb"))) {
3877 perror (fname); return;
3879 if (fgetc(fp) != 'P' || fgetc(fp) != '5') error = 1;
3880 while (!error && nd < 3 && (c = fgetc(fp)) != EOF) {
3881 if (c == '#') comment = 1;
3882 if (c == '\n') comment = 0;
3883 if (comment) continue;
3884 if (isdigit(c)) number = 1;
3886 if (isdigit(c)) dim[nd] = dim[nd]*10 + c -'0';
3887 else if (isspace(c)) {
3892 if (error || nd < 3) {
3893 fprintf (stderr,_("%s is not a valid PGM file!\n"), fname);
3894 fclose (fp); return;
3895 } else if (dim[0] != width || dim[1] != height || dim[2] != 65535) {
3896 fprintf (stderr,_("%s has the wrong dimensions!\n"), fname);
3897 fclose (fp); return;
3899 pixel = (ushort *) calloc (width, sizeof *pixel);
3900 merror (pixel, "subtract()");
3901 for (row=0; row < height; row++) {
3902 fread (pixel, 2, width, fp);
3903 for (col=0; col < width; col++)
3904 BAYER(row,col) = MAX (BAYER(row,col) - ntohs(pixel[col]), 0);
3908 memset (cblack, 0, sizeof cblack);
3912 void CLASS gamma_curve (double pwr, double ts, int mode, int imax)
3915 double g[6], bnd[2]={0,0}, r;
3919 g[2] = g[3] = g[4] = 0;
3921 if (g[1] && (g[1]-1)*(g[0]-1) <= 0) {
3922 for (i=0; i < 48; i++) {
3923 g[2] = (bnd[0] + bnd[1])/2;
3924 if (g[0]) bnd[(pow(g[2]/g[1],-g[0]) - 1)/g[0] - 1/g[2] > -1] = g[2];
3925 else bnd[g[2]/exp(1-1/g[2]) < g[1]] = g[2];
3928 if (g[0]) g[4] = g[2] * (1/g[0] - 1);
3930 if (g[0]) g[5] = 1 / (g[1]*SQR(g[3])/2 - g[4]*(1 - g[3]) +
3931 (1 - pow(g[3],1+g[0]))*(1 + g[4])/(1 + g[0])) - 1;
3932 else g[5] = 1 / (g[1]*SQR(g[3])/2 + 1
3933 - g[2] - g[3] - g[2]*g[3]*(log(g[3]) - 1)) - 1;
3935 memcpy (gamm, g, sizeof gamm);
3938 for (i=0; i < 0x10000; i++) {
3940 if ((r = (double) i / imax) < 1)
3941 curve[i] = 0x10000 * ( mode
3942 ? (r < g[3] ? r*g[1] : (g[0] ? pow( r,g[0])*(1+g[4])-g[4] : log(r)*g[2]+1))
3943 : (r < g[2] ? r/g[1] : (g[0] ? pow((r+g[4])/(1+g[4]),1/g[0]) : exp((r-1)/g[2]))));
3947 void CLASS pseudoinverse (double (*in)[3], double (*out)[3], int size)
3949 double work[3][6], num;
3952 for (i=0; i < 3; i++) {
3953 for (j=0; j < 6; j++)
3954 work[i][j] = j == i+3;
3955 for (j=0; j < 3; j++)
3956 for (k=0; k < size; k++)
3957 work[i][j] += in[k][i] * in[k][j];
3959 for (i=0; i < 3; i++) {
3961 for (j=0; j < 6; j++)
3963 for (k=0; k < 3; k++) {
3966 for (j=0; j < 6; j++)
3967 work[k][j] -= work[i][j] * num;
3970 for (i=0; i < size; i++)
3971 for (j=0; j < 3; j++)
3972 for (out[i][j]=k=0; k < 3; k++)
3973 out[i][j] += work[j][k+3] * in[i][k];
3976 void CLASS cam_xyz_coeff (float rgb_cam[3][4], double cam_xyz[4][3])
3978 double cam_rgb[4][3], inverse[4][3], num;
3981 for (i=0; i < colors; i++) /* Multiply out XYZ colorspace */
3982 for (j=0; j < 3; j++)
3983 for (cam_rgb[i][j] = k=0; k < 3; k++)
3984 cam_rgb[i][j] += cam_xyz[i][k] * xyz_rgb[k][j];
3986 for (i=0; i < colors; i++) { /* Normalize cam_rgb so that */
3987 for (num=j=0; j < 3; j++) /* cam_rgb * (1,1,1) is (1,1,1,1) */
3988 num += cam_rgb[i][j];
3989 for (j=0; j < 3; j++)
3990 cam_rgb[i][j] /= num;
3991 pre_mul[i] = 1 / num;
3993 pseudoinverse (cam_rgb, inverse, colors);
3994 for (i=0; i < 3; i++)
3995 for (j=0; j < colors; j++)
3996 rgb_cam[i][j] = inverse[j][i];
4000 void CLASS colorcheck()
4003 // Coordinates of the GretagMacbeth ColorChecker squares
4004 // width, height, 1st_column, 1st_row
4005 int cut[NSQ][4]; // you must set these
4006 // ColorChecker Chart under 6500-kelvin illumination
4007 static const double gmb_xyY[NSQ][3] = {
4008 { 0.400, 0.350, 10.1 }, // Dark Skin
4009 { 0.377, 0.345, 35.8 }, // Light Skin
4010 { 0.247, 0.251, 19.3 }, // Blue Sky
4011 { 0.337, 0.422, 13.3 }, // Foliage
4012 { 0.265, 0.240, 24.3 }, // Blue Flower
4013 { 0.261, 0.343, 43.1 }, // Bluish Green
4014 { 0.506, 0.407, 30.1 }, // Orange
4015 { 0.211, 0.175, 12.0 }, // Purplish Blue
4016 { 0.453, 0.306, 19.8 }, // Moderate Red
4017 { 0.285, 0.202, 6.6 }, // Purple
4018 { 0.380, 0.489, 44.3 }, // Yellow Green
4019 { 0.473, 0.438, 43.1 }, // Orange Yellow
4020 { 0.187, 0.129, 6.1 }, // Blue
4021 { 0.305, 0.478, 23.4 }, // Green
4022 { 0.539, 0.313, 12.0 }, // Red
4023 { 0.448, 0.470, 59.1 }, // Yellow
4024 { 0.364, 0.233, 19.8 }, // Magenta
4025 { 0.196, 0.252, 19.8 }, // Cyan
4026 { 0.310, 0.316, 90.0 }, // White
4027 { 0.310, 0.316, 59.1 }, // Neutral 8
4028 { 0.310, 0.316, 36.2 }, // Neutral 6.5
4029 { 0.310, 0.316, 19.8 }, // Neutral 5
4030 { 0.310, 0.316, 9.0 }, // Neutral 3.5
4031 { 0.310, 0.316, 3.1 } }; // Black
4032 double gmb_cam[NSQ][4], gmb_xyz[NSQ][3];
4033 double inverse[NSQ][3], cam_xyz[4][3], balance[4], num;
4034 int c, i, j, k, sq, row, col, pass, count[4];
4036 memset (gmb_cam, 0, sizeof gmb_cam);
4037 for (sq=0; sq < NSQ; sq++) {
4039 for (row=cut[sq][3]; row < cut[sq][3]+cut[sq][1]; row++)
4040 for (col=cut[sq][2]; col < cut[sq][2]+cut[sq][0]; col++) {
4042 if (c >= colors) c -= 2;
4043 gmb_cam[sq][c] += BAYER2(row,col);
4044 BAYER2(row,col) = black + (BAYER2(row,col)-black)/2;
4047 FORCC gmb_cam[sq][c] = gmb_cam[sq][c]/count[c] - black;
4048 gmb_xyz[sq][0] = gmb_xyY[sq][2] * gmb_xyY[sq][0] / gmb_xyY[sq][1];
4049 gmb_xyz[sq][1] = gmb_xyY[sq][2];
4050 gmb_xyz[sq][2] = gmb_xyY[sq][2] *
4051 (1 - gmb_xyY[sq][0] - gmb_xyY[sq][1]) / gmb_xyY[sq][1];
4053 pseudoinverse (gmb_xyz, inverse, NSQ);
4054 for (pass=0; pass < 2; pass++) {
4055 for (raw_color = i=0; i < colors; i++)
4056 for (j=0; j < 3; j++)
4057 for (cam_xyz[i][j] = k=0; k < NSQ; k++)
4058 cam_xyz[i][j] += gmb_cam[k][i] * inverse[k][j];
4059 cam_xyz_coeff (rgb_cam, cam_xyz);
4060 FORCC balance[c] = pre_mul[c] * gmb_cam[20][c];
4061 for (sq=0; sq < NSQ; sq++)
4062 FORCC gmb_cam[sq][c] *= balance[c];
4065 printf (" { \"%s %s\", %d,\n\t{", make, model, black);
4066 num = 10000 / (cam_xyz[1][0] + cam_xyz[1][1] + cam_xyz[1][2]);
4067 FORCC for (j=0; j < 3; j++)
4068 printf ("%c%d", (c | j) ? ',':' ', (int) (cam_xyz[c][j] * num + 0.5));
4075 void CLASS hat_transform (float *temp, float *base, int st, int size, int sc)
4078 for (i=0; i < sc; i++)
4079 temp[i] = 2*base[st*i] + base[st*(sc-i)] + base[st*(i+sc)];
4080 for (; i+sc < size; i++)
4081 temp[i] = 2*base[st*i] + base[st*(i-sc)] + base[st*(i+sc)];
4082 for (; i < size; i++)
4083 temp[i] = 2*base[st*i] + base[st*(i-sc)] + base[st*(2*size-2-(i+sc))];
4086 void CLASS wavelet_denoise()
4088 float *fimg=0, *temp, thold, mul[2], avg, diff;
4089 int scale=1, size, lev, hpass, lpass, row, col, nc, c, i, wlast, blk[2];
4091 static const float noise[] =
4092 { 0.8002,0.2735,0.1202,0.0585,0.0291,0.0152,0.0080,0.0044 };
4094 if (verbose) fprintf (stderr,_("Wavelet denoising...\n"));
4096 while (maximum << scale < 0x10000) scale++;
4097 maximum <<= --scale;
4099 FORC4 cblack[c] <<= scale;
4100 if ((size = iheight*iwidth) < 0x15550000)
4101 fimg = (float *) malloc ((size*3 + iheight + iwidth) * sizeof *fimg);
4102 merror (fimg, "wavelet_denoise()");
4103 temp = fimg + size*3;
4104 if ((nc = colors) == 3 && filters) nc++;
4105 FORC(nc) { /* denoise R,G1,B,G3 individually */
4106 for (i=0; i < size; i++)
4107 fimg[i] = 256 * sqrt(image[i][c] << scale);
4108 for (hpass=lev=0; lev < 5; lev++) {
4109 lpass = size*((lev & 1)+1);
4110 for (row=0; row < iheight; row++) {
4111 hat_transform (temp, fimg+hpass+row*iwidth, 1, iwidth, 1 << lev);
4112 for (col=0; col < iwidth; col++)
4113 fimg[lpass + row*iwidth + col] = temp[col] * 0.25;
4115 for (col=0; col < iwidth; col++) {
4116 hat_transform (temp, fimg+lpass+col, iwidth, iheight, 1 << lev);
4117 for (row=0; row < iheight; row++)
4118 fimg[lpass + row*iwidth + col] = temp[row] * 0.25;
4120 thold = threshold * noise[lev];
4121 for (i=0; i < size; i++) {
4122 fimg[hpass+i] -= fimg[lpass+i];
4123 if (fimg[hpass+i] < -thold) fimg[hpass+i] += thold;
4124 else if (fimg[hpass+i] > thold) fimg[hpass+i] -= thold;
4125 else fimg[hpass+i] = 0;
4126 if (hpass) fimg[i] += fimg[hpass+i];
4130 for (i=0; i < size; i++)
4131 image[i][c] = CLIP(SQR(fimg[i]+fimg[lpass+i])/0x10000);
4133 if (filters && colors == 3) { /* pull G1 and G3 closer together */
4134 for (row=0; row < 2; row++) {
4135 mul[row] = 0.125 * pre_mul[FC(row+1,0) | 1] / pre_mul[FC(row,0) | 1];
4136 blk[row] = cblack[FC(row,0) | 1];
4138 for (i=0; i < 4; i++)
4139 window[i] = (ushort *) fimg + width*i;
4140 for (wlast=-1, row=1; row < height-1; row++) {
4141 while (wlast < row+1) {
4142 for (wlast++, i=0; i < 4; i++)
4143 window[(i+3) & 3] = window[i];
4144 for (col = FC(wlast,1) & 1; col < width; col+=2)
4145 window[2][col] = BAYER(wlast,col);
4147 thold = threshold/512;
4148 for (col = (FC(row,0) & 1)+1; col < width-1; col+=2) {
4149 avg = ( window[0][col-1] + window[0][col+1] +
4150 window[2][col-1] + window[2][col+1] - blk[~row & 1]*4 )
4151 * mul[row & 1] + (window[1][col] + blk[row & 1]) * 0.5;
4152 avg = avg < 0 ? 0 : sqrt(avg);
4153 diff = sqrt(BAYER(row,col)) - avg;
4154 if (diff < -thold) diff += thold;
4155 else if (diff > thold) diff -= thold;
4157 BAYER(row,col) = CLIP(SQR(avg+diff) + 0.5);
4164 void CLASS scale_colors()
4166 unsigned bottom, right, size, row, col, ur, uc, i, x, y, c, sum[8];
4168 double dsum[8], dmin, dmax;
4169 float scale_mul[4], fr, fc;
4170 ushort *img=0, *pix;
4173 memcpy (pre_mul, user_mul, sizeof pre_mul);
4174 if (use_auto_wb || (use_camera_wb && cam_mul[0] == -1)) {
4175 memset (dsum, 0, sizeof dsum);
4176 bottom = MIN (greybox[1]+greybox[3], height);
4177 right = MIN (greybox[0]+greybox[2], width);
4178 for (row=greybox[1]; row < bottom; row += 8)
4179 for (col=greybox[0]; col < right; col += 8) {
4180 memset (sum, 0, sizeof sum);
4181 for (y=row; y < row+8 && y < bottom; y++)
4182 for (x=col; x < col+8 && x < right; x++)
4188 val = image[y*width+x][c];
4189 if (val > maximum-25) goto skip_block;
4190 if ((val -= cblack[c]) < 0) val = 0;
4195 FORC(8) dsum[c] += sum[c];
4198 FORC4 if (dsum[c]) pre_mul[c] = dsum[c+4] / dsum[c];
4200 if (use_camera_wb && cam_mul[0] != -1) {
4201 memset (sum, 0, sizeof sum);
4202 for (row=0; row < 8; row++)
4203 for (col=0; col < 8; col++) {
4205 if ((val = white[row][col] - cblack[c]) > 0)
4209 if (sum[0] && sum[1] && sum[2] && sum[3])
4210 FORC4 pre_mul[c] = (float) sum[c+4] / sum[c];
4211 else if (cam_mul[0] && cam_mul[2])
4212 memcpy (pre_mul, cam_mul, sizeof pre_mul);
4214 fprintf (stderr,_("%s: Cannot use camera white balance.\n"), ifname);
4216 if (pre_mul[1] == 0) pre_mul[1] = 1;
4217 if (pre_mul[3] == 0) pre_mul[3] = colors < 4 ? pre_mul[1] : 1;
4220 if (threshold) wavelet_denoise();
4222 for (dmin=DBL_MAX, dmax=c=0; c < 4; c++) {
4223 if (dmin > pre_mul[c])
4225 if (dmax < pre_mul[c])
4228 if (!highlight) dmax = dmin;
4229 FORC4 scale_mul[c] = (pre_mul[c] /= dmax) * 65535.0 / maximum;
4232 _("Scaling with darkness %d, saturation %d, and\nmultipliers"), dark, sat);
4233 FORC4 fprintf (stderr, " %f", pre_mul[c]);
4234 fputc ('\n', stderr);
4236 if (filters > 1000 && (cblack[4]+1)/2 == 1 && (cblack[5]+1)/2 == 1) {
4237 FORC4 cblack[FC(c/2,c%2)] +=
4238 cblack[6 + c/2 % cblack[4] * cblack[5] + c%2 % cblack[5]];
4239 cblack[4] = cblack[5] = 0;
4241 size = iheight*iwidth;
4242 for (i=0; i < size*4; i++) {
4243 if (!(val = ((ushort *)image)[i])) continue;
4244 if (cblack[4] && cblack[5])
4245 val -= cblack[6 + i/4 / iwidth % cblack[4] * cblack[5] +
4246 i/4 % iwidth % cblack[5]];
4247 val -= cblack[i & 3];
4248 val *= scale_mul[i & 3];
4249 ((ushort *)image)[i] = CLIP(val);
4251 if ((aber[0] != 1 || aber[2] != 1) && colors == 3) {
4253 fprintf (stderr,_("Correcting chromatic aberration...\n"));
4254 for (c=0; c < 4; c+=2) {
4255 if (aber[c] == 1) continue;
4256 img = (ushort *) malloc (size * sizeof *img);
4257 merror (img, "scale_colors()");
4258 for (i=0; i < size; i++)
4259 img[i] = image[i][c];
4260 for (row=0; row < iheight; row++) {
4261 ur = fr = (row - iheight*0.5) * aber[c] + iheight*0.5;
4262 if (ur > iheight-2) continue;
4264 for (col=0; col < iwidth; col++) {
4265 uc = fc = (col - iwidth*0.5) * aber[c] + iwidth*0.5;
4266 if (uc > iwidth-2) continue;
4268 pix = img + ur*iwidth + uc;
4269 image[row*iwidth+col][c] =
4270 (pix[ 0]*(1-fc) + pix[ 1]*fc) * (1-fr) +
4271 (pix[iwidth]*(1-fc) + pix[iwidth+1]*fc) * fr;
4279 void CLASS pre_interpolate()
4289 for (row=0; row < 3; row++)
4290 for (col=1; col < 4; col++)
4291 if (!(image[row*width+col][0] | image[row*width+col][2]))
4292 goto break2; break2:
4293 for ( ; row < height; row+=3)
4294 for (col=(col-1)%3+1; col < width-1; col+=3) {
4295 img = image + row*width+col;
4296 for (c=0; c < 3; c+=2)
4297 img[0][c] = (img[-1][c] + img[1][c]) >> 1;
4301 img = (ushort (*)[4]) calloc (height, width*sizeof *img);
4302 merror (img, "pre_interpolate()");
4303 for (row=0; row < height; row++)
4304 for (col=0; col < width; col++) {
4306 img[row*width+col][c] = image[(row >> 1)*iwidth+(col >> 1)][c];
4313 if (filters > 1000 && colors == 3) {
4314 mix_green = four_color_rgb ^ half_size;
4315 if (four_color_rgb | half_size) colors++;
4317 for (row = FC(1,0) >> 1; row < height; row+=2)
4318 for (col = FC(row,1) & 1; col < width; col+=2)
4319 image[row*width+col][1] = image[row*width+col][3];
4320 filters &= ~((filters & 0x55555555) << 1);
4323 if (half_size) filters = 0;
4326 void CLASS border_interpolate (int border)
4328 unsigned row, col, y, x, f, c, sum[8];
4330 for (row=0; row < height; row++)
4331 for (col=0; col < width; col++) {
4332 if (col==border && row >= border && row < height-border)
4334 memset (sum, 0, sizeof sum);
4335 for (y=row-1; y != row+2; y++)
4336 for (x=col-1; x != col+2; x++)
4337 if (y < height && x < width) {
4339 sum[f] += image[y*width+x][f];
4343 FORCC if (c != f && sum[c+4])
4344 image[row*width+col][c] = sum[c] / sum[c+4];
4348 void CLASS lin_interpolate()
4350 int code[16][16][32], size=16, *ip, sum[4];
4351 int f, c, i, x, y, row, col, shift, color;
4354 if (verbose) fprintf (stderr,_("Bilinear interpolation...\n"));
4355 if (filters == 9) size = 6;
4356 border_interpolate(1);
4357 for (row=0; row < size; row++)
4358 for (col=0; col < size; col++) {
4359 ip = code[row][col]+1;
4361 memset (sum, 0, sizeof sum);
4362 for (y=-1; y <= 1; y++)
4363 for (x=-1; x <= 1; x++) {
4364 shift = (y==0) + (x==0);
4365 color = fcol(row+y,col+x);
4366 if (color == f) continue;
4367 *ip++ = (width*y + x)*4 + color;
4370 sum[color] += 1 << shift;
4372 code[row][col][0] = (ip - code[row][col]) / 3;
4376 *ip++ = 256 / sum[c];
4379 for (row=1; row < height-1; row++)
4380 for (col=1; col < width-1; col++) {
4381 pix = image[row*width+col];
4382 ip = code[row % size][col % size];
4383 memset (sum, 0, sizeof sum);
4384 for (i=*ip++; i--; ip+=3)
4385 sum[ip[2]] += pix[ip[0]] << ip[1];
4386 for (i=colors; --i; ip+=2)
4387 pix[ip[0]] = sum[ip[0]] * ip[1] >> 8;
4392 This algorithm is officially called:
4394 "Interpolation using a Threshold-based variable number of gradients"
4396 described in http://scien.stanford.edu/pages/labsite/1999/psych221/projects/99/tingchen/algodep/vargra.html
4398 I've extended the basic idea to work with non-Bayer filter arrays.
4399 Gradients are numbered clockwise from NW=0 to W=7.
4401 void CLASS vng_interpolate()
4403 static const signed char terms[] = {
4404 -2,-2,+0,-1,0,0x01, -2,-2,+0,+0,1,0x01, -2,-1,-1,+0,0,0x01,
4405 -2,-1,+0,-1,0,0x02, -2,-1,+0,+0,0,0x03, -2,-1,+0,+1,1,0x01,
4406 -2,+0,+0,-1,0,0x06, -2,+0,+0,+0,1,0x02, -2,+0,+0,+1,0,0x03,
4407 -2,+1,-1,+0,0,0x04, -2,+1,+0,-1,1,0x04, -2,+1,+0,+0,0,0x06,
4408 -2,+1,+0,+1,0,0x02, -2,+2,+0,+0,1,0x04, -2,+2,+0,+1,0,0x04,
4409 -1,-2,-1,+0,0,0x80, -1,-2,+0,-1,0,0x01, -1,-2,+1,-1,0,0x01,
4410 -1,-2,+1,+0,1,0x01, -1,-1,-1,+1,0,0x88, -1,-1,+1,-2,0,0x40,
4411 -1,-1,+1,-1,0,0x22, -1,-1,+1,+0,0,0x33, -1,-1,+1,+1,1,0x11,
4412 -1,+0,-1,+2,0,0x08, -1,+0,+0,-1,0,0x44, -1,+0,+0,+1,0,0x11,
4413 -1,+0,+1,-2,1,0x40, -1,+0,+1,-1,0,0x66, -1,+0,+1,+0,1,0x22,
4414 -1,+0,+1,+1,0,0x33, -1,+0,+1,+2,1,0x10, -1,+1,+1,-1,1,0x44,
4415 -1,+1,+1,+0,0,0x66, -1,+1,+1,+1,0,0x22, -1,+1,+1,+2,0,0x10,
4416 -1,+2,+0,+1,0,0x04, -1,+2,+1,+0,1,0x04, -1,+2,+1,+1,0,0x04,
4417 +0,-2,+0,+0,1,0x80, +0,-1,+0,+1,1,0x88, +0,-1,+1,-2,0,0x40,
4418 +0,-1,+1,+0,0,0x11, +0,-1,+2,-2,0,0x40, +0,-1,+2,-1,0,0x20,
4419 +0,-1,+2,+0,0,0x30, +0,-1,+2,+1,1,0x10, +0,+0,+0,+2,1,0x08,
4420 +0,+0,+2,-2,1,0x40, +0,+0,+2,-1,0,0x60, +0,+0,+2,+0,1,0x20,
4421 +0,+0,+2,+1,0,0x30, +0,+0,+2,+2,1,0x10, +0,+1,+1,+0,0,0x44,
4422 +0,+1,+1,+2,0,0x10, +0,+1,+2,-1,1,0x40, +0,+1,+2,+0,0,0x60,
4423 +0,+1,+2,+1,0,0x20, +0,+1,+2,+2,0,0x10, +1,-2,+1,+0,0,0x80,
4424 +1,-1,+1,+1,0,0x88, +1,+0,+1,+2,0,0x08, +1,+0,+2,-1,0,0x40,
4426 }, chood[] = { -1,-1, -1,0, -1,+1, 0,+1, +1,+1, +1,0, +1,-1, 0,-1 };
4427 const signed char *cp;
4428 ushort (*brow[5])[4], *pix;
4429 int prow=8, pcol=2, *ip, *code[16][16], gval[8], gmin, gmax, sum[4];
4430 int row, col, x, y, x1, x2, y1, y2, t, weight, grads, color, diag;
4431 int g, diff, thold, num, c;
4434 if (verbose) fprintf (stderr,_("VNG interpolation...\n"));
4436 if (filters == 1) prow = pcol = 16;
4437 if (filters == 9) prow = pcol = 6;
4438 ip = (int *) calloc (prow*pcol, 1280);
4439 merror (ip, "vng_interpolate()");
4440 for (row=0; row < prow; row++) /* Precalculate for VNG */
4441 for (col=0; col < pcol; col++) {
4442 code[row][col] = ip;
4443 for (cp=terms, t=0; t < 64; t++) {
4444 y1 = *cp++; x1 = *cp++;
4445 y2 = *cp++; x2 = *cp++;
4448 color = fcol(row+y1,col+x1);
4449 if (fcol(row+y2,col+x2) != color) continue;
4450 diag = (fcol(row,col+1) == color && fcol(row+1,col) == color) ? 2:1;
4451 if (abs(y1-y2) == diag && abs(x1-x2) == diag) continue;
4452 *ip++ = (y1*width + x1)*4 + color;
4453 *ip++ = (y2*width + x2)*4 + color;
4455 for (g=0; g < 8; g++)
4456 if (grads & 1<<g) *ip++ = g;
4460 for (cp=chood, g=0; g < 8; g++) {
4461 y = *cp++; x = *cp++;
4462 *ip++ = (y*width + x) * 4;
4463 color = fcol(row,col);
4464 if (fcol(row+y,col+x) != color && fcol(row+y*2,col+x*2) == color)
4465 *ip++ = (y*width + x) * 8 + color;
4470 brow[4] = (ushort (*)[4]) calloc (width*3, sizeof **brow);
4471 merror (brow[4], "vng_interpolate()");
4472 for (row=0; row < 3; row++)
4473 brow[row] = brow[4] + row*width;
4474 for (row=2; row < height-2; row++) { /* Do VNG interpolation */
4475 for (col=2; col < width-2; col++) {
4476 pix = image[row*width+col];
4477 ip = code[row % prow][col % pcol];
4478 memset (gval, 0, sizeof gval);
4479 while ((g = ip[0]) != INT_MAX) { /* Calculate gradients */
4480 diff = ABS(pix[g] - pix[ip[1]]) << ip[2];
4481 gval[ip[3]] += diff;
4483 if ((g = ip[-1]) == -1) continue;
4485 while ((g = *ip++) != -1)
4489 gmin = gmax = gval[0]; /* Choose a threshold */
4490 for (g=1; g < 8; g++) {
4491 if (gmin > gval[g]) gmin = gval[g];
4492 if (gmax < gval[g]) gmax = gval[g];
4495 memcpy (brow[2][col], pix, sizeof *image);
4498 thold = gmin + (gmax >> 1);
4499 memset (sum, 0, sizeof sum);
4500 color = fcol(row,col);
4501 for (num=g=0; g < 8; g++,ip+=2) { /* Average the neighbors */
4502 if (gval[g] <= thold) {
4504 if (c == color && ip[1])
4505 sum[c] += (pix[c] + pix[ip[1]]) >> 1;
4507 sum[c] += pix[ip[0] + c];
4511 FORCC { /* Save to buffer */
4514 t += (sum[c] - sum[color]) / num;
4515 brow[2][col][c] = CLIP(t);
4518 if (row > 3) /* Write buffer to image */
4519 memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image);
4520 for (g=0; g < 4; g++)
4521 brow[(g-1) & 3] = brow[g];
4523 memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image);
4524 memcpy (image[(row-1)*width+2], brow[1]+2, (width-4)*sizeof *image);
4530 Patterned Pixel Grouping Interpolation by Alain Desbiolles
4532 void CLASS ppg_interpolate()
4534 int dir[5] = { 1, width, -1, -width, 1 };
4535 int row, col, diff[2], guess[2], c, d, i;
4537 diff[0] = diff[1] = 0;
4539 border_interpolate(3);
4540 if (verbose) fprintf (stderr,_("PPG interpolation...\n"));
4542 /* Fill in the green layer with gradients and pattern recognition: */
4543 for (row=3; row < height-3; row++)
4544 for (col=3+(FC(row,3) & 1), c=FC(row,col); col < width-3; col+=2) {
4545 pix = image + row*width+col;
4546 for (i=0; (d=dir[i]) > 0; i++) {
4547 guess[i] = (pix[-d][1] + pix[0][c] + pix[d][1]) * 2
4548 - pix[-2*d][c] - pix[2*d][c];
4549 diff[i] = ( ABS(pix[-2*d][c] - pix[ 0][c]) +
4550 ABS(pix[ 2*d][c] - pix[ 0][c]) +
4551 ABS(pix[ -d][1] - pix[ d][1]) ) * 3 +
4552 ( ABS(pix[ 3*d][1] - pix[ d][1]) +
4553 ABS(pix[-3*d][1] - pix[-d][1]) ) * 2;
4555 d = dir[i = diff[0] > diff[1]];
4556 pix[0][1] = ULIM(guess[i] >> 2, pix[d][1], pix[-d][1]);
4558 /* Calculate red and blue for each green pixel: */
4559 for (row=1; row < height-1; row++)
4560 for (col=1+(FC(row,2) & 1), c=FC(row,col+1); col < width-1; col+=2) {
4561 pix = image + row*width+col;
4562 for (i=0; (d=dir[i]) > 0; c=2-c, i++)
4563 pix[0][c] = CLIP((pix[-d][c] + pix[d][c] + 2*pix[0][1]
4564 - pix[-d][1] - pix[d][1]) >> 1);
4566 /* Calculate blue for red pixels and vice versa: */
4567 for (row=1; row < height-1; row++)
4568 for (col=1+(FC(row,1) & 1), c=2-FC(row,col); col < width-1; col+=2) {
4569 pix = image + row*width+col;
4570 for (i=0; (d=dir[i]+dir[i+1]) > 0; i++) {
4571 diff[i] = ABS(pix[-d][c] - pix[d][c]) +
4572 ABS(pix[-d][1] - pix[0][1]) +
4573 ABS(pix[ d][1] - pix[0][1]);
4574 guess[i] = pix[-d][c] + pix[d][c] + 2*pix[0][1]
4575 - pix[-d][1] - pix[d][1];
4577 if (diff[0] != diff[1])
4578 pix[0][c] = CLIP(guess[diff[0] > diff[1]] >> 1);
4580 pix[0][c] = CLIP((guess[0]+guess[1]) >> 2);
4584 void CLASS cielab (ushort rgb[3], short lab[3])
4588 float *cbrt = clb_cbrt, (*xyz_cam)[4] = clb_xyz_cam;
4591 for (i=0; i < 0x10000; i++) {
4593 cbrt[i] = r > 0.008856 ? pow(r,1/3.0) : 7.787*r + 16/116.0;
4595 for (i=0; i < 3; i++)
4596 for (j=0; j < colors; j++)
4597 for (xyz_cam[i][j] = k=0; k < 3; k++)
4598 xyz_cam[i][j] += xyz_rgb[i][k] * rgb_cam[k][j] / d65_white[i];
4601 xyz[0] = xyz[1] = xyz[2] = 0.5;
4603 xyz[0] += xyz_cam[0][c] * rgb[c];
4604 xyz[1] += xyz_cam[1][c] * rgb[c];
4605 xyz[2] += xyz_cam[2][c] * rgb[c];
4607 xyz[0] = cbrt[CLIP((int) xyz[0])];
4608 xyz[1] = cbrt[CLIP((int) xyz[1])];
4609 xyz[2] = cbrt[CLIP((int) xyz[2])];
4610 lab[0] = 64 * (116 * xyz[1] - 16);
4611 lab[1] = 64 * 500 * (xyz[0] - xyz[1]);
4612 lab[2] = 64 * 200 * (xyz[1] - xyz[2]);
4615 #define TS 512 /* Tile Size */
4616 #define fcol(row,col) xtrans[(row+6) % 6][(col+6) % 6]
4619 Frank Markesteijn's algorithm for Fuji X-Trans sensors
4621 void CLASS xtrans_interpolate (int passes)
4623 int c, d, f, g, h, i, v, ng, row, col, top, left, mrow, mcol;
4624 int val, ndir, pass, hm[8], avg[4], color[3][8];
4625 static const short orth[12] = { 1,0,0,1,-1,0,0,-1,1,0,0,1 },
4626 patt[2][16] = { { 0,1,0,-1,2,0,-1,0,1,1,1,-1,0,0,0,0 },
4627 { 0,1,0,-2,1,0,-2,0,1,1,-2,-2,1,-1,-1,1 } },
4628 dir[4] = { 1,TS,TS+1,TS-1 };
4629 short allhex[3][3][2][8], *hex;
4631 ushort min, max, sgrow=0, sgcol=0;
4632 ushort (*rgb)[TS][TS][3], (*rix)[3], (*pix)[4];
4633 short (*lab) [TS][3], (*lix)[3];
4634 float (*drv)[TS][TS], diff[6], tr;
4635 char (*homo)[TS][TS], *buffer;
4638 fprintf (stderr,_("%d-pass X-Trans interpolation...\n"), passes);
4641 ndir = 4 << (passes > 1);
4642 buffer = (char *) malloc (TS*TS*(ndir*11+6));
4643 merror (buffer, "xtrans_interpolate()");
4644 rgb = (ushort(*)[TS][TS][3]) buffer;
4645 lab = (short (*) [TS][3])(buffer + TS*TS*(ndir*6));
4646 drv = (float (*)[TS][TS]) (buffer + TS*TS*(ndir*6+6));
4647 homo = (char (*)[TS][TS]) (buffer + TS*TS*(ndir*10+6));
4649 /* Map a green hexagon around each non-green pixel and vice versa: */
4650 for (row=0; row < 3; row++)
4651 for (col=0; col < 3; col++)
4652 for (ng=d=0; d < 10; d+=2) {
4653 g = fcol(row,col) == 1;
4654 if (fcol(row+orth[d],col+orth[d+2]) == 1) ng=0; else ng++;
4655 if (ng == 4) { sgrow = row; sgcol = col; }
4656 if (ng == g+1) FORC(8) {
4657 v = orth[d ]*patt[g][c*2] + orth[d+1]*patt[g][c*2+1];
4658 h = orth[d+2]*patt[g][c*2] + orth[d+3]*patt[g][c*2+1];
4659 allhex[row][col][0][c^(g*2 & d)] = h + v*width;
4660 allhex[row][col][1][c^(g*2 & d)] = h + v*TS;
4664 /* Set green1 and green3 to the minimum and maximum allowed values: */
4665 for (row=2; row < height-2; row++)
4666 for (min=~(max=0), col=2; col < width-2; col++) {
4667 if (fcol(row,col) == 1 && (min=~(max=0))) continue;
4668 pix = image + row*width + col;
4669 hex = allhex[row % 3][col % 3][0];
4671 val = pix[hex[c]][1];
4672 if (min > val) min = val;
4673 if (max < val) max = val;
4677 switch ((row-sgrow) % 3) {
4678 case 1: if (row < height-3) { row++; col--; } break;
4679 case 2: if ((min=~(max=0)) && (col+=2) < width-3 && row > 2) row--;
4683 for (top=3; top < height-19; top += TS-16)
4684 for (left=3; left < width-19; left += TS-16) {
4685 mrow = MIN (top+TS, height-3);
4686 mcol = MIN (left+TS, width-3);
4687 for (row=top; row < mrow; row++)
4688 for (col=left; col < mcol; col++)
4689 memcpy (rgb[0][row-top][col-left], image[row*width+col], 6);
4690 FORC3 memcpy (rgb[c+1], rgb[0], sizeof *rgb);
4692 /* Interpolate green horizontally, vertically, and along both diagonals: */
4693 for (row=top; row < mrow; row++)
4694 for (col=left; col < mcol; col++) {
4695 if ((f = fcol(row,col)) == 1) continue;
4696 pix = image + row*width + col;
4697 hex = allhex[row % 3][col % 3][0];
4698 color[1][0] = 174 * (pix[ hex[1]][1] + pix[ hex[0]][1]) -
4699 46 * (pix[2*hex[1]][1] + pix[2*hex[0]][1]);
4700 color[1][1] = 223 * pix[ hex[3]][1] + pix[ hex[2]][1] * 33 +
4701 92 * (pix[ 0 ][f] - pix[ -hex[2]][f]);
4702 FORC(2) color[1][2+c] =
4703 164 * pix[hex[4+c]][1] + 92 * pix[-2*hex[4+c]][1] + 33 *
4704 (2*pix[0][f] - pix[3*hex[4+c]][f] - pix[-3*hex[4+c]][f]);
4705 FORC4 rgb[c^!((row-sgrow) % 3)][row-top][col-left][1] =
4706 LIM(color[1][c] >> 8,pix[0][1],pix[0][3]);
4709 for (pass=0; pass < passes; pass++) {
4711 memcpy (rgb+=4, buffer, 4*sizeof *rgb);
4713 /* Recalculate green from interpolated values of closer pixels: */
4715 for (row=top+2; row < mrow-2; row++)
4716 for (col=left+2; col < mcol-2; col++) {
4717 if ((f = fcol(row,col)) == 1) continue;
4718 pix = image + row*width + col;
4719 hex = allhex[row % 3][col % 3][1];
4720 for (d=3; d < 6; d++) {
4721 rix = &rgb[(d-2)^!((row-sgrow) % 3)][row-top][col-left];
4722 val = rix[-2*hex[d]][1] + 2*rix[hex[d]][1]
4723 - rix[-2*hex[d]][f] - 2*rix[hex[d]][f] + 3*rix[0][f];
4724 rix[0][1] = LIM(val/3,pix[0][1],pix[0][3]);
4729 /* Interpolate red and blue values for solitary green pixels: */
4730 for (row=(top-sgrow+4)/3*3+sgrow; row < mrow-2; row+=3)
4731 for (col=(left-sgcol+4)/3*3+sgcol; col < mcol-2; col+=3) {
4732 rix = &rgb[0][row-top][col-left];
4733 h = fcol(row,col+1);
4734 memset (diff, 0, sizeof diff);
4735 for (i=1, d=0; d < 6; d++, i^=TS^1, h^=2) {
4736 for (c=0; c < 2; c++, h^=2) {
4737 g = 2*rix[0][1] - rix[i<<c][1] - rix[-i<<c][1];
4738 color[h][d] = g + rix[i<<c][h] + rix[-i<<c][h];
4740 diff[d] += SQR (rix[i<<c][1] - rix[-i<<c][1]
4741 - rix[i<<c][h] + rix[-i<<c][h]) + SQR(g);
4743 if (d > 1 && (d & 1))
4744 if (diff[d-1] < diff[d])
4745 FORC(2) color[c*2][d] = color[c*2][d-1];
4746 if (d < 2 || (d & 1)) {
4747 FORC(2) rix[0][c*2] = CLIP(color[c*2][d]/2);
4753 /* Interpolate red for blue pixels and vice versa: */
4754 for (row=top+3; row < mrow-3; row++)
4755 for (col=left+3; col < mcol-3; col++) {
4756 if ((f = 2-fcol(row,col)) == 1) continue;
4757 rix = &rgb[0][row-top][col-left];
4758 c = (row-sgrow) % 3 ? TS:1;
4759 h = 3 * (c ^ TS ^ 1);
4760 for (d=0; d < 4; d++, rix += TS*TS) {
4761 i = d > 1 || ((d ^ c) & 1) ||
4762 ((ABS(rix[0][1]-rix[c][1])+ABS(rix[0][1]-rix[-c][1])) <
4763 2*(ABS(rix[0][1]-rix[h][1])+ABS(rix[0][1]-rix[-h][1]))) ? c:h;
4764 rix[0][f] = CLIP((rix[i][f] + rix[-i][f] +
4765 2*rix[0][1] - rix[i][1] - rix[-i][1])/2);
4769 /* Fill in red and blue for 2x2 blocks of green: */
4770 for (row=top+2; row < mrow-2; row++) if ((row-sgrow) % 3)
4771 for (col=left+2; col < mcol-2; col++) if ((col-sgcol) % 3) {
4772 rix = &rgb[0][row-top][col-left];
4773 hex = allhex[row % 3][col % 3][1];
4774 for (d=0; d < ndir; d+=2, rix += TS*TS)
4775 if (hex[d] + hex[d+1]) {
4776 g = 3*rix[0][1] - 2*rix[hex[d]][1] - rix[hex[d+1]][1];
4777 for (c=0; c < 4; c+=2) rix[0][c] =
4778 CLIP((g + 2*rix[hex[d]][c] + rix[hex[d+1]][c])/3);
4780 g = 2*rix[0][1] - rix[hex[d]][1] - rix[hex[d+1]][1];
4781 for (c=0; c < 4; c+=2) rix[0][c] =
4782 CLIP((g + rix[hex[d]][c] + rix[hex[d+1]][c])/2);
4786 rgb = (ushort(*)[TS][TS][3]) buffer;
4790 /* Convert to CIELab and differentiate in all directions: */
4791 for (d=0; d < ndir; d++) {
4792 for (row=2; row < mrow-2; row++)
4793 for (col=2; col < mcol-2; col++)
4794 cielab (rgb[d][row][col], lab[row][col]);
4795 for (f=dir[d & 3],row=3; row < mrow-3; row++)
4796 for (col=3; col < mcol-3; col++) {
4797 lix = &lab[row][col];
4798 g = 2*lix[0][0] - lix[f][0] - lix[-f][0];
4799 drv[d][row][col] = SQR(g)
4800 + SQR((2*lix[0][1] - lix[f][1] - lix[-f][1] + g*500/232))
4801 + SQR((2*lix[0][2] - lix[f][2] - lix[-f][2] - g*500/580));
4805 /* Build homogeneity maps from the derivatives: */
4806 memset(homo, 0, ndir*TS*TS);
4807 for (row=4; row < mrow-4; row++)
4808 for (col=4; col < mcol-4; col++) {
4809 for (tr=FLT_MAX, d=0; d < ndir; d++)
4810 if (tr > drv[d][row][col])
4811 tr = drv[d][row][col];
4813 for (d=0; d < ndir; d++)
4814 for (v=-1; v <= 1; v++)
4815 for (h=-1; h <= 1; h++)
4816 if (drv[d][row+v][col+h] <= tr)
4817 homo[d][row][col]++;
4820 /* Average the most homogenous pixels for the final result: */
4821 if (height-top < TS+4) mrow = height-top+2;
4822 if (width-left < TS+4) mcol = width-left+2;
4823 for (row = MIN(top,8); row < mrow-8; row++)
4824 for (col = MIN(left,8); col < mcol-8; col++) {
4825 for (d=0; d < ndir; d++)
4826 for (hm[d]=0, v=-2; v <= 2; v++)
4827 for (h=-2; h <= 2; h++)
4828 hm[d] += homo[d][row+v][col+h];
4829 for (d=0; d < ndir-4; d++)
4830 if (hm[d] < hm[d+4]) hm[d ] = 0; else
4831 if (hm[d] > hm[d+4]) hm[d+4] = 0;
4832 for (max=hm[0],d=1; d < ndir; d++)
4833 if (max < hm[d]) max = hm[d];
4835 memset (avg, 0, sizeof avg);
4836 for (d=0; d < ndir; d++)
4838 FORC3 avg[c] += rgb[d][row][col][c];
4841 FORC3 image[(row+top)*width+col+left][c] = avg[c]/avg[3];
4845 border_interpolate(8);
4850 Adaptive Homogeneity-Directed interpolation is based on
4851 the work of Keigo Hirakawa, Thomas Parks, and Paul Lee.
4853 void CLASS ahd_interpolate()
4855 int i, j, top, left, row, col, tr, tc, c, d, val, hm[2];
4856 static const int dir[4] = { -1, 1, -TS, TS };
4857 unsigned ldiff[2][4], abdiff[2][4], leps, abeps;
4858 ushort (*rgb)[TS][TS][3], (*rix)[3], (*pix)[4];
4859 short (*lab)[TS][TS][3], (*lix)[3];
4860 char (*homo)[TS][TS], *buffer;
4862 if (verbose) fprintf (stderr,_("AHD interpolation...\n"));
4865 border_interpolate(5);
4866 buffer = (char *) malloc (26*TS*TS);
4867 merror (buffer, "ahd_interpolate()");
4868 rgb = (ushort(*)[TS][TS][3]) buffer;
4869 lab = (short (*)[TS][TS][3])(buffer + 12*TS*TS);
4870 homo = (char (*)[TS][TS]) (buffer + 24*TS*TS);
4872 for (top=2; top < height-5; top += TS-6)
4873 for (left=2; left < width-5; left += TS-6) {
4875 /* Interpolate green horizontally and vertically: */
4876 for (row=top; row < top+TS && row < height-2; row++) {
4877 col = left + (FC(row,left) & 1);
4878 for (c = FC(row,col); col < left+TS && col < width-2; col+=2) {
4879 pix = image + row*width+col;
4880 val = ((pix[-1][1] + pix[0][c] + pix[1][1]) * 2
4881 - pix[-2][c] - pix[2][c]) >> 2;
4882 rgb[0][row-top][col-left][1] = ULIM(val,pix[-1][1],pix[1][1]);
4883 val = ((pix[-width][1] + pix[0][c] + pix[width][1]) * 2
4884 - pix[-2*width][c] - pix[2*width][c]) >> 2;
4885 rgb[1][row-top][col-left][1] = ULIM(val,pix[-width][1],pix[width][1]);
4888 /* Interpolate red and blue, and convert to CIELab: */
4889 for (d=0; d < 2; d++)
4890 for (row=top+1; row < top+TS-1 && row < height-3; row++)
4891 for (col=left+1; col < left+TS-1 && col < width-3; col++) {
4892 pix = image + row*width+col;
4893 rix = &rgb[d][row-top][col-left];
4894 lix = &lab[d][row-top][col-left];
4895 if ((c = 2 - FC(row,col)) == 1) {
4897 val = pix[0][1] + (( pix[-1][2-c] + pix[1][2-c]
4898 - rix[-1][1] - rix[1][1] ) >> 1);
4899 rix[0][2-c] = CLIP(val);
4900 val = pix[0][1] + (( pix[-width][c] + pix[width][c]
4901 - rix[-TS][1] - rix[TS][1] ) >> 1);
4903 val = rix[0][1] + (( pix[-width-1][c] + pix[-width+1][c]
4904 + pix[+width-1][c] + pix[+width+1][c]
4905 - rix[-TS-1][1] - rix[-TS+1][1]
4906 - rix[+TS-1][1] - rix[+TS+1][1] + 1) >> 2);
4907 rix[0][c] = CLIP(val);
4909 rix[0][c] = pix[0][c];
4910 cielab (rix[0],lix[0]);
4912 /* Build homogeneity maps from the CIELab images: */
4913 memset (homo, 0, 2*TS*TS);
4914 for (row=top+2; row < top+TS-2 && row < height-4; row++) {
4916 for (col=left+2; col < left+TS-2 && col < width-4; col++) {
4918 for (d=0; d < 2; d++) {
4919 lix = &lab[d][tr][tc];
4920 for (i=0; i < 4; i++) {
4921 ldiff[d][i] = ABS(lix[0][0]-lix[dir[i]][0]);
4922 abdiff[d][i] = SQR(lix[0][1]-lix[dir[i]][1])
4923 + SQR(lix[0][2]-lix[dir[i]][2]);
4926 leps = MIN(MAX(ldiff[0][0],ldiff[0][1]),
4927 MAX(ldiff[1][2],ldiff[1][3]));
4928 abeps = MIN(MAX(abdiff[0][0],abdiff[0][1]),
4929 MAX(abdiff[1][2],abdiff[1][3]));
4930 for (d=0; d < 2; d++)
4931 for (i=0; i < 4; i++)
4932 if (ldiff[d][i] <= leps && abdiff[d][i] <= abeps)
4936 /* Combine the most homogenous pixels for the final result: */
4937 for (row=top+3; row < top+TS-3 && row < height-5; row++) {
4939 for (col=left+3; col < left+TS-3 && col < width-5; col++) {
4941 for (d=0; d < 2; d++)
4942 for (hm[d]=0, i=tr-1; i <= tr+1; i++)
4943 for (j=tc-1; j <= tc+1; j++)
4944 hm[d] += homo[d][i][j];
4946 FORC3 image[row*width+col][c] = rgb[hm[1] > hm[0]][tr][tc][c];
4948 FORC3 image[row*width+col][c] =
4949 (rgb[0][tr][tc][c] + rgb[1][tr][tc][c]) >> 1;
4957 void CLASS median_filter()
4960 int pass, c, i, j, k, med[9];
4961 static const uchar opt[] = /* Optimal 9-element median search */
4962 { 1,2, 4,5, 7,8, 0,1, 3,4, 6,7, 1,2, 4,5, 7,8,
4963 0,3, 5,8, 4,7, 3,6, 1,4, 2,5, 4,7, 4,2, 6,4, 4,2 };
4965 for (pass=1; pass <= med_passes; pass++) {
4967 fprintf (stderr,_("Median filter pass %d...\n"), pass);
4968 for (c=0; c < 3; c+=2) {
4969 for (pix = image; pix < image+width*height; pix++)
4970 pix[0][3] = pix[0][c];
4971 for (pix = image+width; pix < image+width*(height-1); pix++) {
4972 if ((pix-image+1) % width < 2) continue;
4973 for (k=0, i = -width; i <= width; i += width)
4974 for (j = i-1; j <= i+1; j++)
4975 med[k++] = pix[j][3] - pix[j][1];
4976 for (i=0; i < sizeof opt; i+=2)
4977 if (med[opt[i]] > med[opt[i+1]])
4978 SWAP (med[opt[i]] , med[opt[i+1]]);
4979 pix[0][c] = CLIP(med[4] + pix[0][1]);
4985 void CLASS blend_highlights()
4987 int clip=INT_MAX, row, col, c, i, j;
4988 static const float trans[2][4][4] =
4989 { { { 1,1,1 }, { 1.7320508,-1.7320508,0 }, { -1,-1,2 } },
4990 { { 1,1,1,1 }, { 1,-1,1,-1 }, { 1,1,-1,-1 }, { 1,-1,-1,1 } } };
4991 static const float itrans[2][4][4] =
4992 { { { 1,0.8660254,-0.5 }, { 1,-0.8660254,-0.5 }, { 1,0,1 } },
4993 { { 1,1,1,1 }, { 1,-1,1,-1 }, { 1,1,-1,-1 }, { 1,-1,-1,1 } } };
4994 float cam[2][4], lab[2][4], sum[2], chratio;
4996 if ((unsigned) (colors-3) > 1) return;
4997 if (verbose) fprintf (stderr,_("Blending highlights...\n"));
4998 FORCC if (clip > (i = 65535*pre_mul[c])) clip = i;
4999 for (row=0; row < height; row++)
5000 for (col=0; col < width; col++) {
5001 FORCC if (image[row*width+col][c] > clip) break;
5002 if (c == colors) continue;
5004 cam[0][c] = image[row*width+col][c];
5005 cam[1][c] = MIN(cam[0][c],clip);
5007 for (i=0; i < 2; i++) {
5008 FORCC for (lab[i][c]=j=0; j < colors; j++)
5009 lab[i][c] += trans[colors-3][c][j] * cam[i][j];
5010 for (sum[i]=0,c=1; c < colors; c++)
5011 sum[i] += SQR(lab[i][c]);
5013 chratio = sqrt(sum[1]/sum[0]);
5014 for (c=1; c < colors; c++)
5015 lab[0][c] *= chratio;
5016 FORCC for (cam[0][c]=j=0; j < colors; j++)
5017 cam[0][c] += itrans[colors-3][c][j] * lab[0][j];
5018 FORCC image[row*width+col][c] = cam[0][c] / colors;
5022 #define SCALE (4 >> shrink)
5023 void CLASS recover_highlights()
5025 float *map, sum, wgt, grow;
5026 int hsat[4], count, spread, change, val, i;
5027 unsigned high, wide, mrow, mcol, row, col, kc, c, d, y, x;
5029 static const signed char dir[8][2] =
5030 { {-1,-1}, {-1,0}, {-1,1}, {0,1}, {1,1}, {1,0}, {1,-1}, {0,-1} };
5032 if (verbose) fprintf (stderr,_("Rebuilding highlights...\n"));
5034 grow = pow (2, 4-highlight);
5035 FORCC hsat[c] = 32000 * pre_mul[c];
5036 for (kc=0, c=1; c < colors; c++)
5037 if (pre_mul[kc] < pre_mul[c]) kc = c;
5038 high = height / SCALE;
5039 wide = width / SCALE;
5040 map = (float *) calloc (high, wide*sizeof *map);
5041 merror (map, "recover_highlights()");
5042 FORCC if (c != kc) {
5043 memset (map, 0, high*wide*sizeof *map);
5044 for (mrow=0; mrow < high; mrow++)
5045 for (mcol=0; mcol < wide; mcol++) {
5046 sum = wgt = count = 0;
5047 for (row = mrow*SCALE; row < (mrow+1)*SCALE; row++)
5048 for (col = mcol*SCALE; col < (mcol+1)*SCALE; col++) {
5049 pixel = image[row*width+col];
5050 if (pixel[c] / hsat[c] == 1 && pixel[kc] > 24000) {
5056 if (count == SCALE*SCALE)
5057 map[mrow*wide+mcol] = sum / wgt;
5059 for (spread = 32/grow; spread--; ) {
5060 for (mrow=0; mrow < high; mrow++)
5061 for (mcol=0; mcol < wide; mcol++) {
5062 if (map[mrow*wide+mcol]) continue;
5064 for (d=0; d < 8; d++) {
5065 y = mrow + dir[d][0];
5066 x = mcol + dir[d][1];
5067 if (y < high && x < wide && map[y*wide+x] > 0) {
5068 sum += (1 + (d & 1)) * map[y*wide+x];
5069 count += 1 + (d & 1);
5073 map[mrow*wide+mcol] = - (sum+grow) / (count+grow);
5075 for (change=i=0; i < high*wide; i++)
5082 for (i=0; i < high*wide; i++)
5083 if (map[i] == 0) map[i] = 1;
5084 for (mrow=0; mrow < high; mrow++)
5085 for (mcol=0; mcol < wide; mcol++) {
5086 for (row = mrow*SCALE; row < (mrow+1)*SCALE; row++)
5087 for (col = mcol*SCALE; col < (mcol+1)*SCALE; col++) {
5088 pixel = image[row*width+col];
5089 if (pixel[c] / hsat[c] > 1) {
5090 val = pixel[kc] * map[mrow*wide+mcol];
5091 if (pixel[c] < val) pixel[c] = CLIP(val);
5100 void CLASS tiff_get (unsigned base,
5101 unsigned *tag, unsigned *type, unsigned *len, unsigned *save)
5106 *save = ftell(ifp) + 4;
5107 if (*len * ("11124811248484"[*type < 14 ? *type:0]-'0') > 4)
5108 fseek (ifp, get4()+base, SEEK_SET);
5111 void CLASS parse_thumb_note (int base, unsigned toff, unsigned tlen)
5113 unsigned entries, tag, type, len, save;
5117 tiff_get (base, &tag, &type, &len, &save);
5118 if (tag == toff) thumb_offset = get4()+base;
5119 if (tag == tlen) thumb_length = get4();
5120 fseek (ifp, save, SEEK_SET);
5124 void CLASS parse_makernote (int base, int uptag)
5126 static const uchar xlat[2][256] = {
5127 { 0xc1,0xbf,0x6d,0x0d,0x59,0xc5,0x13,0x9d,0x83,0x61,0x6b,0x4f,0xc7,0x7f,0x3d,0x3d,
5128 0x53,0x59,0xe3,0xc7,0xe9,0x2f,0x95,0xa7,0x95,0x1f,0xdf,0x7f,0x2b,0x29,0xc7,0x0d,
5129 0xdf,0x07,0xef,0x71,0x89,0x3d,0x13,0x3d,0x3b,0x13,0xfb,0x0d,0x89,0xc1,0x65,0x1f,
5130 0xb3,0x0d,0x6b,0x29,0xe3,0xfb,0xef,0xa3,0x6b,0x47,0x7f,0x95,0x35,0xa7,0x47,0x4f,
5131 0xc7,0xf1,0x59,0x95,0x35,0x11,0x29,0x61,0xf1,0x3d,0xb3,0x2b,0x0d,0x43,0x89,0xc1,
5132 0x9d,0x9d,0x89,0x65,0xf1,0xe9,0xdf,0xbf,0x3d,0x7f,0x53,0x97,0xe5,0xe9,0x95,0x17,
5133 0x1d,0x3d,0x8b,0xfb,0xc7,0xe3,0x67,0xa7,0x07,0xf1,0x71,0xa7,0x53,0xb5,0x29,0x89,
5134 0xe5,0x2b,0xa7,0x17,0x29,0xe9,0x4f,0xc5,0x65,0x6d,0x6b,0xef,0x0d,0x89,0x49,0x2f,
5135 0xb3,0x43,0x53,0x65,0x1d,0x49,0xa3,0x13,0x89,0x59,0xef,0x6b,0xef,0x65,0x1d,0x0b,
5136 0x59,0x13,0xe3,0x4f,0x9d,0xb3,0x29,0x43,0x2b,0x07,0x1d,0x95,0x59,0x59,0x47,0xfb,
5137 0xe5,0xe9,0x61,0x47,0x2f,0x35,0x7f,0x17,0x7f,0xef,0x7f,0x95,0x95,0x71,0xd3,0xa3,
5138 0x0b,0x71,0xa3,0xad,0x0b,0x3b,0xb5,0xfb,0xa3,0xbf,0x4f,0x83,0x1d,0xad,0xe9,0x2f,
5139 0x71,0x65,0xa3,0xe5,0x07,0x35,0x3d,0x0d,0xb5,0xe9,0xe5,0x47,0x3b,0x9d,0xef,0x35,
5140 0xa3,0xbf,0xb3,0xdf,0x53,0xd3,0x97,0x53,0x49,0x71,0x07,0x35,0x61,0x71,0x2f,0x43,
5141 0x2f,0x11,0xdf,0x17,0x97,0xfb,0x95,0x3b,0x7f,0x6b,0xd3,0x25,0xbf,0xad,0xc7,0xc5,
5142 0xc5,0xb5,0x8b,0xef,0x2f,0xd3,0x07,0x6b,0x25,0x49,0x95,0x25,0x49,0x6d,0x71,0xc7 },
5143 { 0xa7,0xbc,0xc9,0xad,0x91,0xdf,0x85,0xe5,0xd4,0x78,0xd5,0x17,0x46,0x7c,0x29,0x4c,
5144 0x4d,0x03,0xe9,0x25,0x68,0x11,0x86,0xb3,0xbd,0xf7,0x6f,0x61,0x22,0xa2,0x26,0x34,
5145 0x2a,0xbe,0x1e,0x46,0x14,0x68,0x9d,0x44,0x18,0xc2,0x40,0xf4,0x7e,0x5f,0x1b,0xad,
5146 0x0b,0x94,0xb6,0x67,0xb4,0x0b,0xe1,0xea,0x95,0x9c,0x66,0xdc,0xe7,0x5d,0x6c,0x05,
5147 0xda,0xd5,0xdf,0x7a,0xef,0xf6,0xdb,0x1f,0x82,0x4c,0xc0,0x68,0x47,0xa1,0xbd,0xee,
5148 0x39,0x50,0x56,0x4a,0xdd,0xdf,0xa5,0xf8,0xc6,0xda,0xca,0x90,0xca,0x01,0x42,0x9d,
5149 0x8b,0x0c,0x73,0x43,0x75,0x05,0x94,0xde,0x24,0xb3,0x80,0x34,0xe5,0x2c,0xdc,0x9b,
5150 0x3f,0xca,0x33,0x45,0xd0,0xdb,0x5f,0xf5,0x52,0xc3,0x21,0xda,0xe2,0x22,0x72,0x6b,
5151 0x3e,0xd0,0x5b,0xa8,0x87,0x8c,0x06,0x5d,0x0f,0xdd,0x09,0x19,0x93,0xd0,0xb9,0xfc,
5152 0x8b,0x0f,0x84,0x60,0x33,0x1c,0x9b,0x45,0xf1,0xf0,0xa3,0x94,0x3a,0x12,0x77,0x33,
5153 0x4d,0x44,0x78,0x28,0x3c,0x9e,0xfd,0x65,0x57,0x16,0x94,0x6b,0xfb,0x59,0xd0,0xc8,
5154 0x22,0x36,0xdb,0xd2,0x63,0x98,0x43,0xa1,0x04,0x87,0x86,0xf7,0xa6,0x26,0xbb,0xd6,
5155 0x59,0x4d,0xbf,0x6a,0x2e,0xaa,0x2b,0xef,0xe6,0x78,0xb6,0x4e,0xe0,0x2f,0xdc,0x7c,
5156 0xbe,0x57,0x19,0x32,0x7e,0x2a,0xd0,0xb8,0xba,0x29,0x00,0x3c,0x52,0x7d,0xa8,0x49,
5157 0x3b,0x2d,0xeb,0x25,0x49,0xfa,0xa3,0xaa,0x39,0xa7,0xc5,0xa7,0x50,0x11,0x36,0xfb,
5158 0xc6,0x67,0x4a,0xf5,0xa5,0x12,0x65,0x7e,0xb0,0xdf,0xaf,0x4e,0xb3,0x61,0x7f,0x2f } };
5159 unsigned offset=0, entries, tag, type, len, save, c;
5160 unsigned ver97=0, serial=0, i, wbi=0, wb[4]={0,0,0,0};
5161 uchar buf97[324], ci, cj, ck;
5162 short morder, sorder=order;
5165 The MakerNote might have its own TIFF header (possibly with
5166 its own byte-order!), or it might just be a table.
5168 if (!strcmp(make,"Nokia")) return;
5169 fread (buf, 1, 10, ifp);
5170 if (!strncmp (buf,"KDK" ,3) || /* these aren't TIFF tables */
5171 !strncmp (buf,"VER" ,3) ||
5172 !strncmp (buf,"IIII",4) ||
5173 !strncmp (buf,"MMMM",4)) return;
5174 if (!strncmp (buf,"KC" ,2) || /* Konica KD-400Z, KD-510Z */
5175 !strncmp (buf,"MLY" ,3)) { /* Minolta DiMAGE G series */
5177 while ((i=ftell(ifp)) < data_offset && i < 16384) {
5178 wb[0] = wb[2]; wb[2] = wb[1]; wb[1] = wb[3];
5180 if (wb[1] == 256 && wb[3] == 256 &&
5181 wb[0] > 256 && wb[0] < 640 && wb[2] > 256 && wb[2] < 640)
5182 FORC4 cam_mul[c] = wb[c];
5186 if (!strcmp (buf,"Nikon")) {
5189 if (get2() != 42) goto quit;
5191 fseek (ifp, offset-8, SEEK_CUR);
5192 } else if (!strcmp (buf,"OLYMPUS") ||
5193 !strcmp (buf,"PENTAX ")) {
5194 base = ftell(ifp)-10;
5195 fseek (ifp, -2, SEEK_CUR);
5197 if (buf[0] == 'O') get2();
5198 } else if (!strncmp (buf,"SONY",4) ||
5199 !strcmp (buf,"Panasonic")) {
5201 } else if (!strncmp (buf,"FUJIFILM",8)) {
5202 base = ftell(ifp)-10;
5204 fseek (ifp, 2, SEEK_CUR);
5205 } else if (!strcmp (buf,"OLYMP") ||
5206 !strcmp (buf,"LEICA") ||
5207 !strcmp (buf,"Ricoh") ||
5208 !strcmp (buf,"EPSON"))
5209 fseek (ifp, -2, SEEK_CUR);
5210 else if (!strcmp (buf,"AOC") ||
5211 !strcmp (buf,"QVC"))
5212 fseek (ifp, -4, SEEK_CUR);
5214 fseek (ifp, -10, SEEK_CUR);
5215 if (!strncmp(make,"SAMSUNG",7))
5219 if (entries > 1000) return;
5223 tiff_get (base, &tag, &type, &len, &save);
5225 if (tag == 2 && strstr(make,"NIKON") && !iso_speed)
5226 iso_speed = (get2(),get2());
5227 if (tag == 4 && len > 26 && len < 35) {
5228 if ((i=(get4(),get2())) != 0x7fff && !iso_speed)
5229 iso_speed = 50 * pow (2, i/32.0 - 4);
5230 if ((i=(get2(),get2())) != 0x7fff && !aperture)
5231 aperture = pow (2, i/64.0);
5232 if ((i=get2()) != 0xffff && !shutter)
5233 shutter = pow (2, (short) i/-32.0);
5234 wbi = (get2(),get2());
5235 shot_order = (get2(),get2());
5237 if ((tag == 4 || tag == 0x114) && !strncmp(make,"KONICA",6)) {
5238 fseek (ifp, tag == 4 ? 140:160, SEEK_CUR);
5240 case 72: flip = 0; break;
5241 case 76: flip = 6; break;
5242 case 82: flip = 5; break;
5245 if (tag == 7 && type == 2 && len > 20)
5246 fgets (model2, 64, ifp);
5247 if (tag == 8 && type == 4)
5248 shot_order = get4();
5249 if (tag == 9 && !strcmp(make,"Canon"))
5250 fread (artist, 64, 1, ifp);
5251 if (tag == 0xc && len == 4)
5252 FORC3 cam_mul[(c << 1 | c >> 1) & 3] = getreal(type);
5253 if (tag == 0xd && type == 7 && get2() == 0xaaaa) {
5254 for (c=i=2; (ushort) c != 0xbbbb && i < len; i++)
5255 c = c << 8 | fgetc(ifp);
5256 while ((i+=4) < len-5)
5257 if (get4() == 257 && (i=len) && (c = (get4(),fgetc(ifp))) < 3)
5258 flip = "065"[c]-'0';
5260 if (tag == 0x10 && type == 4)
5262 if (tag == 0x11 && is_raw && !strncmp(make,"NIKON",5)) {
5263 fseek (ifp, get4()+base, SEEK_SET);
5264 parse_tiff_ifd (base);
5266 if (tag == 0x14 && type == 7) {
5268 fseek (ifp, 1248, SEEK_CUR);
5271 fread (buf, 1, 10, ifp);
5272 if (!strncmp(buf,"NRW ",4)) {
5273 fseek (ifp, strcmp(buf+4,"0100") ? 46:1546, SEEK_CUR);
5274 cam_mul[0] = get4() << 2;
5275 cam_mul[1] = get4() + get4();
5276 cam_mul[2] = get4() << 2;
5279 if (tag == 0x15 && type == 2 && is_raw)
5280 fread (model, 64, 1, ifp);
5281 if (strstr(make,"PENTAX")) {
5282 if (tag == 0x1b) tag = 0x1018;
5283 if (tag == 0x1c) tag = 0x1017;
5286 while ((c = fgetc(ifp)) && c != EOF)
5287 serial = serial*10 + (isdigit(c) ? c - '0' : c % 10);
5288 if (tag == 0x29 && type == 1) {
5289 c = wbi < 18 ? "012347800000005896"[wbi]-'0' : 0;
5290 fseek (ifp, 8 + c*32, SEEK_CUR);
5291 FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get4();
5293 if (tag == 0x3d && type == 3 && len == 4)
5294 FORC4 cblack[c ^ c >> 1] = get2() >> (14-tiff_bps);
5295 if (tag == 0x81 && type == 4) {
5296 data_offset = get4();
5297 fseek (ifp, data_offset + 41, SEEK_SET);
5298 raw_height = get2() * 2;
5300 filters = 0x61616161;
5302 if ((tag == 0x81 && type == 7) ||
5303 (tag == 0x100 && type == 7) ||
5304 (tag == 0x280 && type == 1)) {
5305 thumb_offset = ftell(ifp);
5308 if (tag == 0x88 && type == 4 && (thumb_offset = get4()))
5309 thumb_offset += base;
5310 if (tag == 0x89 && type == 4)
5311 thumb_length = get4();
5312 if (tag == 0x8c || tag == 0x96)
5313 meta_offset = ftell(ifp);
5315 for (i=0; i < 4; i++)
5316 ver97 = ver97 * 10 + fgetc(ifp)-'0';
5319 fseek (ifp, 68, SEEK_CUR);
5320 FORC4 cam_mul[(c >> 1) | ((c & 1) << 1)] = get2();
5323 fseek (ifp, 6, SEEK_CUR);
5324 FORC4 cam_mul[c ^ (c >> 1)] = get2();
5327 fseek (ifp, 16, SEEK_CUR);
5328 FORC4 cam_mul[c] = get2();
5331 if (ver97 != 205) fseek (ifp, 280, SEEK_CUR);
5332 fread (buf97, 324, 1, ifp);
5335 if (tag == 0xa1 && type == 7) {
5337 fseek (ifp, 140, SEEK_CUR);
5338 FORC3 cam_mul[c] = get4();
5340 if (tag == 0xa4 && type == 3) {
5341 fseek (ifp, wbi*48, SEEK_CUR);
5342 FORC3 cam_mul[c] = get2();
5344 if (tag == 0xa7 && (unsigned) (ver97-200) < 17) {
5345 ci = xlat[0][serial & 0xff];
5346 cj = xlat[1][fgetc(ifp)^fgetc(ifp)^fgetc(ifp)^fgetc(ifp)];
5348 for (i=0; i < 324; i++)
5349 buf97[i] ^= (cj += ci * ck++);
5350 i = "66666>666;6A;:;55"[ver97-200] - '0';
5351 FORC4 cam_mul[c ^ (c >> 1) ^ (i & 1)] =
5352 sget2 (buf97 + (i & -2) + c*2);
5354 if (tag == 0x200 && len == 3)
5355 shot_order = (get4(),get4());
5356 if (tag == 0x200 && len == 4)
5357 FORC4 cblack[c ^ c >> 1] = get2();
5358 if (tag == 0x201 && len == 4)
5359 FORC4 cam_mul[c ^ (c >> 1)] = get2();
5360 if (tag == 0x220 && type == 7)
5361 meta_offset = ftell(ifp);
5362 if (tag == 0x401 && type == 4 && len == 4)
5363 FORC4 cblack[c ^ c >> 1] = get4();
5364 if (tag == 0xe01) { /* Nikon Capture Note */
5366 fseek (ifp, 22, SEEK_CUR);
5367 for (offset=22; offset+22 < len; offset += 22+i) {
5369 fseek (ifp, 14, SEEK_CUR);
5371 if (tag == 0x76a43207) flip = get2();
5372 else fseek (ifp, i, SEEK_CUR);
5375 if (tag == 0xe80 && len == 256 && type == 7) {
5376 fseek (ifp, 48, SEEK_CUR);
5377 cam_mul[0] = get2() * 508 * 1.078 / 0x10000;
5378 cam_mul[2] = get2() * 382 * 1.173 / 0x10000;
5380 if (tag == 0xf00 && type == 7) {
5382 fseek (ifp, 176, SEEK_CUR);
5383 else if (len == 734 || len == 1502)
5384 fseek (ifp, 148, SEEK_CUR);
5388 if ((tag == 0x1011 && len == 9) || tag == 0x20400200)
5389 for (i=0; i < 3; i++)
5390 FORC3 cmatrix[i][c] = ((short) get2()) / 256.0;
5391 if ((tag == 0x1012 || tag == 0x20400600) && len == 4)
5392 FORC4 cblack[c ^ c >> 1] = get2();
5393 if (tag == 0x1017 || tag == 0x20400100)
5394 cam_mul[0] = get2() / 256.0;
5395 if (tag == 0x1018 || tag == 0x20400100)
5396 cam_mul[2] = get2() / 256.0;
5397 if (tag == 0x2011 && len == 2) {
5400 cam_mul[0] = get2() / 256.0;
5401 cam_mul[2] = get2() / 256.0;
5403 if ((tag | 0x70) == 0x2070 && (type == 4 || type == 13))
5404 fseek (ifp, get4()+base, SEEK_SET);
5405 if (tag == 0x2020 && !strncmp(buf,"OLYMP",5))
5406 parse_thumb_note (base, 257, 258);
5408 parse_makernote (base, 0x2040);
5409 if (tag == 0xb028) {
5410 fseek (ifp, get4()+base, SEEK_SET);
5411 parse_thumb_note (base, 136, 137);
5413 if (tag == 0x4001 && len > 500) {
5414 i = len == 582 ? 50 : len == 653 ? 68 : len == 5120 ? 142 : 126;
5415 fseek (ifp, i, SEEK_CUR);
5416 FORC4 cam_mul[c ^ (c >> 1)] = get2();
5417 for (i+=18; i <= len; i+=10) {
5419 FORC4 sraw_mul[c ^ (c >> 1)] = get2();
5420 if (sraw_mul[1] == 1170) break;
5423 if (tag == 0x4021 && get4() && get4())
5424 FORC4 cam_mul[c] = 1024;
5426 FORC4 cam_mul[c ^ (c >> 1)] = get4();
5428 FORC4 cam_mul[c ^ (c >> 1)] -= get4();
5432 fseek (ifp, save, SEEK_SET);
5439 Since the TIFF DateTime string has no timezone information,
5440 assume that the camera's clock was set to Universal Time.
5442 void CLASS get_timestamp (int reversed)
5450 for (i=19; i--; ) str[i] = fgetc(ifp);
5452 fread (str, 19, 1, ifp);
5453 memset (&t, 0, sizeof t);
5454 if (sscanf (str, "%d:%d:%d %d:%d:%d", &t.tm_year, &t.tm_mon,
5455 &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec) != 6)
5461 timestamp = mktime(&t);
5464 void CLASS parse_exif (int base)
5466 unsigned kodak, entries, tag, type, len, save, c;
5469 kodak = !strncmp(make,"EASTMAN",7) && tiff_nifds < 3;
5472 tiff_get (base, &tag, &type, &len, &save);
5474 case 33434: tiff_ifd[tiff_nifds-1].shutter =
5475 shutter = getreal(type); break;
5476 case 33437: aperture = getreal(type); break;
5477 case 34855: iso_speed = get2(); break;
5479 case 36868: get_timestamp(0); break;
5480 case 37377: if ((expo = -getreal(type)) < 128)
5481 tiff_ifd[tiff_nifds-1].shutter =
5482 shutter = pow (2, expo); break;
5483 case 37378: aperture = pow (2, getreal(type)/2); break;
5484 case 37386: focal_len = getreal(type); break;
5485 case 37500: parse_makernote (base, 0); break;
5486 case 40962: if (kodak) raw_width = get4(); break;
5487 case 40963: if (kodak) raw_height = get4(); break;
5489 if (get4() == 0x20002)
5490 for (exif_cfa=c=0; c < 8; c+=2)
5491 exif_cfa |= fgetc(ifp) * 0x01010101 << c;
5493 fseek (ifp, save, SEEK_SET);
5497 void CLASS parse_gps (int base)
5499 unsigned entries, tag, type, len, save, c;
5503 tiff_get (base, &tag, &type, &len, &save);
5505 case 1: case 3: case 5:
5506 gpsdata[29+tag/2] = getc(ifp); break;
5507 case 2: case 4: case 7:
5508 FORC(6) gpsdata[tag/3*6+c] = get4(); break;
5510 FORC(2) gpsdata[18+c] = get4(); break;
5512 fgets ((char *) (gpsdata+14+tag/3), MIN(len,12), ifp);
5514 fseek (ifp, save, SEEK_SET);
5518 void CLASS romm_coeff (float romm_cam[3][3])
5520 static const float rgb_romm[3][3] = /* ROMM == Kodak ProPhoto */
5521 { { 2.034193, -0.727420, -0.306766 },
5522 { -0.228811, 1.231729, -0.002922 },
5523 { -0.008565, -0.153273, 1.161839 } };
5526 for (i=0; i < 3; i++)
5527 for (j=0; j < 3; j++)
5528 for (cmatrix[i][j] = k=0; k < 3; k++)
5529 cmatrix[i][j] += rgb_romm[i][k] * romm_cam[k][j];
5532 void CLASS parse_mos (int offset)
5535 int skip, from, i, c, neut[4], planes=0, frot=0;
5536 static const char *mod[] =
5537 { "","DCB2","Volare","Cantare","CMost","Valeo 6","Valeo 11","Valeo 22",
5538 "Valeo 11p","Valeo 17","","Aptus 17","Aptus 22","Aptus 75","Aptus 65",
5539 "Aptus 54S","Aptus 65S","Aptus 75S","AFi 5","AFi 6","AFi 7",
5540 "AFi-II 7","Aptus-II 7","","Aptus-II 6","","","Aptus-II 10","Aptus-II 5",
5541 "","","","","Aptus-II 10R","Aptus-II 8","","Aptus-II 12","","AFi-II 12" };
5542 float romm_cam[3][3];
5544 fseek (ifp, offset, SEEK_SET);
5546 if (get4() != 0x504b5453) break;
5548 fread (data, 1, 40, ifp);
5551 if (!strcmp(data,"JPEG_preview_data")) {
5552 thumb_offset = from;
5553 thumb_length = skip;
5555 if (!strcmp(data,"icc_camera_profile")) {
5556 profile_offset = from;
5557 profile_length = skip;
5559 if (!strcmp(data,"ShootObj_back_type")) {
5560 fscanf (ifp, "%d", &i);
5561 if ((unsigned) i < sizeof mod / sizeof (*mod))
5562 strcpy (model, mod[i]);
5564 if (!strcmp(data,"icc_camera_to_tone_matrix")) {
5565 for (i=0; i < 9; i++)
5566 ((float *)romm_cam)[i] = int_to_float(get4());
5567 romm_coeff (romm_cam);
5569 if (!strcmp(data,"CaptProf_color_matrix")) {
5570 for (i=0; i < 9; i++)
5571 fscanf (ifp, "%f", (float *)romm_cam + i);
5572 romm_coeff (romm_cam);
5574 if (!strcmp(data,"CaptProf_number_of_planes"))
5575 fscanf (ifp, "%d", &planes);
5576 if (!strcmp(data,"CaptProf_raw_data_rotation"))
5577 fscanf (ifp, "%d", &flip);
5578 if (!strcmp(data,"CaptProf_mosaic_pattern"))
5580 fscanf (ifp, "%d", &i);
5581 if (i == 1) frot = c ^ (c >> 1);
5583 if (!strcmp(data,"ImgProf_rotation_angle")) {
5584 fscanf (ifp, "%d", &i);
5587 if (!strcmp(data,"NeutObj_neutrals") && !cam_mul[0]) {
5588 FORC4 fscanf (ifp, "%d", neut+c);
5589 FORC3 cam_mul[c] = (float) neut[0] / neut[c+1];
5591 if (!strcmp(data,"Rows_data"))
5592 load_flags = get4();
5594 fseek (ifp, skip+from, SEEK_SET);
5597 filters = (planes == 1) * 0x01010101 *
5598 (uchar) "\x94\x61\x16\x49"[(flip/90 + frot) & 3];
5601 void CLASS linear_table (unsigned len)
5604 if (len > 0x1000) len = 0x1000;
5605 read_shorts (curve, len);
5606 for (i=len; i < 0x1000; i++)
5607 curve[i] = curve[i-1];
5608 maximum = curve[0xfff];
5611 void CLASS parse_kodak_ifd (int base)
5613 unsigned entries, tag, type, len, save;
5614 int i, c, wbi=-2, wbtemp=6500;
5615 float mul[3]={1,1,1}, num;
5616 static const int wbtag[] = { 64037,64040,64039,64041,-1,-1,64042 };
5619 if (entries > 1024) return;
5621 tiff_get (base, &tag, &type, &len, &save);
5622 if (tag == 1020) wbi = getint(type);
5623 if (tag == 1021 && len == 72) { /* WB set in software */
5624 fseek (ifp, 40, SEEK_CUR);
5625 FORC3 cam_mul[c] = 2048.0 / get2();
5628 if (tag == 2118) wbtemp = getint(type);
5629 if (tag == 2120 + wbi && wbi >= 0)
5630 FORC3 cam_mul[c] = 2048.0 / getreal(type);
5631 if (tag == 2130 + wbi)
5632 FORC3 mul[c] = getreal(type);
5633 if (tag == 2140 + wbi && wbi >= 0)
5635 for (num=i=0; i < 4; i++)
5636 num += getreal(type) * pow (wbtemp/100.0, i);
5637 cam_mul[c] = 2048 / (num * mul[c]);
5639 if (tag == 2317) linear_table (len);
5640 if (tag == 6020) iso_speed = getint(type);
5641 if (tag == 64013) wbi = fgetc(ifp);
5642 if ((unsigned) wbi < 7 && tag == wbtag[wbi])
5643 FORC3 cam_mul[c] = get4();
5644 if (tag == 64019) width = getint(type);
5645 if (tag == 64020) height = (getint(type)+1) & -2;
5646 fseek (ifp, save, SEEK_SET);
5650 int CLASS parse_tiff_ifd (int base)
5652 unsigned entries, tag, type, len, plen=16, save;
5653 int ifd, use_cm=0, cfa, i, j, c, ima_len=0;
5654 char software[64], *cbuf, *cp;
5655 uchar cfa_pat[16], cfa_pc[] = { 0,1,2,3 }, tab[256];
5656 double cc[4][4], cm[4][3], cam_xyz[4][3], num;
5657 double ab[]={ 1,1,1,1 }, asn[] = { 0,0,0,0 }, xyz[] = { 1,1,1 };
5658 unsigned sony_curve[] = { 0,0,0,0,0,4095 };
5659 unsigned *buf, sony_offset=0, sony_length=0, sony_key=0;
5663 if (tiff_nifds >= sizeof tiff_ifd / sizeof tiff_ifd[0])
5666 for (j=0; j < 4; j++)
5667 for (i=0; i < 4; i++)
5670 if (entries > 512) return 1;
5672 tiff_get (base, &tag, &type, &len, &save);
5674 case 5: width = get2(); break;
5675 case 6: height = get2(); break;
5676 case 7: width += get2(); break;
5677 case 9: if ((i = get2())) filters = i; break;
5679 if (type == 3 && len == 1)
5680 cam_mul[(tag-17)*2] = get2() / 256.0;
5683 if (type == 3) iso_speed = get2();
5685 case 28: case 29: case 30:
5686 cblack[tag-28] = get2();
5687 cblack[3] = cblack[1];
5689 case 36: case 37: case 38:
5690 cam_mul[tag-36] = get2();
5693 if (len < 50 || cam_mul[0]) break;
5694 fseek (ifp, 12, SEEK_CUR);
5695 FORC3 cam_mul[c] = get2();
5698 if (type != 7 || fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) break;
5699 thumb_offset = ftell(ifp) - 2;
5702 case 61440: /* Fuji HS10 table */
5703 fseek (ifp, get4()+base, SEEK_SET);
5704 parse_tiff_ifd (base);
5706 case 2: case 256: case 61441: /* ImageWidth */
5707 tiff_ifd[ifd].width = getint(type);
5709 case 3: case 257: case 61442: /* ImageHeight */
5710 tiff_ifd[ifd].height = getint(type);
5712 case 258: /* BitsPerSample */
5714 tiff_ifd[ifd].samples = len & 7;
5715 tiff_ifd[ifd].bps = getint(type);
5716 if (tiff_bps < tiff_ifd[ifd].bps)
5717 tiff_bps = tiff_ifd[ifd].bps;
5721 if (tiff_ifd[ifd].bps > 12) break;
5722 load_raw = &CLASS packed_load_raw;
5723 load_flags = get4() ? 24:80;
5725 case 259: /* Compression */
5726 tiff_ifd[ifd].comp = getint(type);
5728 case 262: /* PhotometricInterpretation */
5729 tiff_ifd[ifd].phint = get2();
5731 case 270: /* ImageDescription */
5732 fread (desc, 512, 1, ifp);
5734 case 271: /* Make */
5735 fgets (make, 64, ifp);
5737 case 272: /* Model */
5738 fgets (model, 64, ifp);
5740 case 280: /* Panasonic RW2 offset */
5741 if (type != 4) break;
5742 load_raw = &CLASS panasonic_load_raw;
5743 load_flags = 0x2008;
5744 case 273: /* StripOffset */
5745 case 513: /* JpegIFOffset */
5747 tiff_ifd[ifd].offset = get4()+base;
5748 if (!tiff_ifd[ifd].bps && tiff_ifd[ifd].offset > 0) {
5749 fseek (ifp, tiff_ifd[ifd].offset, SEEK_SET);
5750 if (ljpeg_start (&jh, 1)) {
5751 tiff_ifd[ifd].comp = 6;
5752 tiff_ifd[ifd].width = jh.wide;
5753 tiff_ifd[ifd].height = jh.high;
5754 tiff_ifd[ifd].bps = jh.bits;
5755 tiff_ifd[ifd].samples = jh.clrs;
5756 if (!(jh.sraw || (jh.clrs & 1)))
5757 tiff_ifd[ifd].width *= jh.clrs;
5758 if ((tiff_ifd[ifd].width > 4*tiff_ifd[ifd].height) & ~jh.clrs) {
5759 tiff_ifd[ifd].width /= 2;
5760 tiff_ifd[ifd].height *= 2;
5763 parse_tiff (tiff_ifd[ifd].offset + 12);
5768 case 274: /* Orientation */
5769 tiff_ifd[ifd].flip = "50132467"[get2() & 7]-'0';
5771 case 277: /* SamplesPerPixel */
5772 tiff_ifd[ifd].samples = getint(type) & 7;
5774 case 279: /* StripByteCounts */
5777 tiff_ifd[ifd].bytes = get4();
5780 FORC3 cam_mul[(4-c) % 3] = getint(type);
5782 case 305: case 11: /* Software */
5783 fgets (software, 64, ifp);
5784 if (!strncmp(software,"Adobe",5) ||
5785 !strncmp(software,"dcraw",5) ||
5786 !strncmp(software,"UFRaw",5) ||
5787 !strncmp(software,"Bibble",6) ||
5788 !strncmp(software,"Nikon Scan",10) ||
5789 !strcmp (software,"Digital Photo Professional"))
5792 case 306: /* DateTime */
5795 case 315: /* Artist */
5796 fread (artist, 64, 1, ifp);
5798 case 322: /* TileWidth */
5799 tiff_ifd[ifd].tile_width = getint(type);
5801 case 323: /* TileLength */
5802 tiff_ifd[ifd].tile_length = getint(type);
5804 case 324: /* TileOffsets */
5805 tiff_ifd[ifd].offset = len > 1 ? ftell(ifp) : get4();
5807 tiff_ifd[ifd].tile_width = tiff_ifd[ifd].tile_length = 0;
5809 load_raw = &CLASS sinar_4shot_load_raw;
5813 case 330: /* SubIFDs */
5814 if (!strcmp(model,"DSLR-A100") && tiff_ifd[ifd].width == 3872) {
5815 load_raw = &CLASS sony_arw_load_raw;
5816 data_offset = get4()+base;
5821 fseek (ifp, get4()+base, SEEK_SET);
5822 if (parse_tiff_ifd (base)) break;
5823 fseek (ifp, i+4, SEEK_SET);
5827 strcpy (make, "Sarnoff");
5831 FORC4 sony_curve[c+1] = get2() >> 2 & 0xfff;
5832 for (i=0; i < 5; i++)
5833 for (j = sony_curve[i]+1; j <= sony_curve[i+1]; j++)
5834 curve[j] = curve[j-1] + (1 << i);
5836 case 29184: sony_offset = get4(); break;
5837 case 29185: sony_length = get4(); break;
5838 case 29217: sony_key = get4(); break;
5840 parse_minolta (ftell(ifp));
5844 FORC4 cam_mul[c ^ (c < 2)] = get2();
5847 FORC4 cam_mul[c] = get2();
5848 i = (cam_mul[1] == 1024 && cam_mul[2] == 1024) << 1;
5849 SWAP (cam_mul[i],cam_mul[i+1])
5851 case 33405: /* Model2 */
5852 fgets (model2, 64, ifp);
5854 case 33421: /* CFARepeatPatternDim */
5855 if (get2() == 6 && get2() == 6)
5858 case 33422: /* CFAPattern */
5860 FORC(36) ((char *)xtrans)[c] = fgetc(ifp) & 3;
5863 case 64777: /* Kodak P-series */
5864 if ((plen=len) > 16) plen = 16;
5865 fread (cfa_pat, 1, plen, ifp);
5866 for (colors=cfa=i=0; i < plen && colors < 4; i++) {
5867 colors += !(cfa & (1 << cfa_pat[i]));
5868 cfa |= 1 << cfa_pat[i];
5870 if (cfa == 070) memcpy (cfa_pc,"\003\004\005",3); /* CMY */
5871 if (cfa == 072) memcpy (cfa_pc,"\005\003\004\001",4); /* GMCY */
5875 fseek (ifp, get4()+base, SEEK_SET);
5876 parse_kodak_ifd (base);
5878 case 33434: /* ExposureTime */
5879 tiff_ifd[ifd].shutter = shutter = getreal(type);
5881 case 33437: /* FNumber */
5882 aperture = getreal(type);
5884 case 34306: /* Leaf white balance */
5885 FORC4 cam_mul[c ^ 1] = 4096.0 / get2();
5887 case 34307: /* Leaf CatchLight color matrix */
5888 fread (software, 1, 7, ifp);
5889 if (strncmp(software,"MATRIX",6)) break;
5891 for (raw_color = i=0; i < 3; i++) {
5892 FORC4 fscanf (ifp, "%f", &rgb_cam[i][c^1]);
5893 if (!use_camera_wb) continue;
5895 FORC4 num += rgb_cam[i][c];
5896 FORC4 rgb_cam[i][c] /= num;
5899 case 34310: /* Leaf metadata */
5900 parse_mos (ftell(ifp));
5902 strcpy (make, "Leaf");
5904 case 34665: /* EXIF tag */
5905 fseek (ifp, get4()+base, SEEK_SET);
5908 case 34853: /* GPSInfo tag */
5909 fseek (ifp, get4()+base, SEEK_SET);
5912 case 34675: /* InterColorProfile */
5913 case 50831: /* AsShotICCProfile */
5914 profile_offset = ftell(ifp);
5915 profile_length = len;
5917 case 37122: /* CompressedBitsPerPixel */
5918 kodak_cbpp = get4();
5920 case 37386: /* FocalLength */
5921 focal_len = getreal(type);
5923 case 37393: /* ImageNumber */
5924 shot_order = getint(type);
5926 case 37400: /* old Kodak KDC tag */
5927 for (raw_color = i=0; i < 3; i++) {
5929 FORC3 rgb_cam[i][c] = getreal(type);
5933 strip_offset = get4();
5934 switch (tiff_ifd[ifd].comp) {
5935 case 32770: load_raw = &CLASS samsung_load_raw; break;
5936 case 32772: load_raw = &CLASS samsung2_load_raw; break;
5937 case 32773: load_raw = &CLASS samsung3_load_raw; break;
5940 case 46275: /* Imacon tags */
5941 strcpy (make, "Imacon");
5942 data_offset = ftell(ifp);
5946 if (!ima_len) break;
5947 fseek (ifp, 38, SEEK_CUR);
5949 fseek (ifp, 40, SEEK_CUR);
5951 raw_height = get4();
5952 left_margin = get4() & 7;
5953 width = raw_width - left_margin - (get4() & 7);
5954 top_margin = get4() & 7;
5955 height = raw_height - top_margin - (get4() & 7);
5956 if (raw_width == 7262) {
5961 fseek (ifp, 52, SEEK_CUR);
5962 FORC3 cam_mul[c] = getreal(11);
5963 fseek (ifp, 114, SEEK_CUR);
5964 flip = (get2() >> 7) * 90;
5965 if (width * height * 6 == ima_len) {
5966 if (flip % 180 == 90) SWAP(width,height);
5968 raw_height = height;
5969 left_margin = top_margin = filters = flip = 0;
5971 sprintf (model, "Ixpress %d-Mp", height*width/1000000);
5972 load_raw = &CLASS imacon_full_load_raw;
5974 if (left_margin & 1) filters = 0x61616161;
5975 load_raw = &CLASS unpacked_load_raw;
5979 case 50454: /* Sinar tag */
5981 if (!(cbuf = (char *) malloc(len))) break;
5982 fread (cbuf, 1, len, ifp);
5983 for (cp = cbuf-1; cp && cp < cbuf+len; cp = strchr(cp,'\n'))
5984 if (!strncmp (++cp,"Neutral ",8))
5985 sscanf (cp+8, "%f %f %f", cam_mul, cam_mul+1, cam_mul+2);
5989 if (!make[0]) strcpy (make, "Hasselblad");
5991 case 50459: /* Hasselblad tag */
5996 fseek (ifp, j+(get2(),get4()), SEEK_SET);
6002 case 50706: /* DNGVersion */
6003 FORC4 dng_version = (dng_version << 8) + fgetc(ifp);
6004 if (!make[0]) strcpy (make, "DNG");
6007 case 50708: /* UniqueCameraModel */
6008 if (model[0]) break;
6009 fgets (make, 64, ifp);
6010 if ((cp = strchr(make,' '))) {
6015 case 50710: /* CFAPlaneColor */
6016 if (filters == 9) break;
6017 if (len > 4) len = 4;
6019 fread (cfa_pc, 1, colors, ifp);
6021 FORCC tab[cfa_pc[c]] = c;
6024 filters = filters << 2 | tab[cfa_pat[i % plen]];
6025 filters -= !filters;
6027 case 50711: /* CFALayout */
6028 if (get2() == 2) fuji_width = 1;
6031 case 50712: /* LinearizationTable */
6034 case 50713: /* BlackLevelRepeatDim */
6037 if (cblack[4] * cblack[5] > sizeof cblack / sizeof *cblack - 6)
6038 cblack[4] = cblack[5] = 1;
6041 cblack[4] = cblack[5] = MIN(sqrt(len),64);
6042 case 50714: /* BlackLevel */
6043 if ((cblack[4] * cblack[5])==0)
6044 cblack[4] = cblack[5] = 1;
6045 FORC (cblack[4] * cblack[5])
6046 cblack[6+c] = getreal(type);
6049 case 50715: /* BlackLevelDeltaH */
6050 case 50716: /* BlackLevelDeltaV */
6051 for (num=i=0; i < (len & 0xffff); i++)
6052 num += getreal(type);
6053 black += num/len + 0.5;
6055 case 50717: /* WhiteLevel */
6056 maximum = getint(type);
6058 case 50718: /* DefaultScale */
6059 pixel_aspect = getreal(type);
6060 pixel_aspect /= getreal(type);
6062 case 50721: /* ColorMatrix1 */
6063 case 50722: /* ColorMatrix2 */
6064 FORCC for (j=0; j < 3; j++)
6065 cm[c][j] = getreal(type);
6068 case 50723: /* CameraCalibration1 */
6069 case 50724: /* CameraCalibration2 */
6070 for (i=0; i < colors; i++)
6071 FORCC cc[i][c] = getreal(type);
6073 case 50727: /* AnalogBalance */
6074 FORCC ab[c] = getreal(type);
6076 case 50728: /* AsShotNeutral */
6077 FORCC asn[c] = getreal(type);
6079 case 50729: /* AsShotWhiteXY */
6080 xyz[0] = getreal(type);
6081 xyz[1] = getreal(type);
6082 xyz[2] = 1 - xyz[0] - xyz[1];
6083 FORC3 xyz[c] /= d65_white[c];
6085 case 50740: /* DNGPrivateData */
6086 if (dng_version) break;
6087 parse_minolta (j = get4()+base);
6088 fseek (ifp, j, SEEK_SET);
6089 parse_tiff_ifd (base);
6092 read_shorts (cr2_slice, 3);
6094 case 50829: /* ActiveArea */
6095 top_margin = getint(type);
6096 left_margin = getint(type);
6097 height = getint(type) - top_margin;
6098 width = getint(type) - left_margin;
6100 case 50830: /* MaskedAreas */
6101 for (i=0; i < len && i < 32; i++)
6102 ((int *)mask)[i] = getint(type);
6105 case 51009: /* OpcodeList2 */
6106 meta_offset = ftell(ifp);
6108 case 64772: /* Kodak P-series */
6109 if (len < 13) break;
6110 fseek (ifp, 16, SEEK_CUR);
6111 data_offset = get4();
6112 fseek (ifp, 28, SEEK_CUR);
6113 data_offset += get4();
6114 load_raw = &CLASS packed_load_raw;
6117 if (type == 2) fgets (model2, 64, ifp);
6119 fseek (ifp, save, SEEK_SET);
6121 if (sony_length && (buf = (unsigned *) malloc(sony_length))) {
6122 fseek (ifp, sony_offset, SEEK_SET);
6123 fread (buf, sony_length, 1, ifp);
6124 sony_decrypt (buf, sony_length/4, 1, sony_key);
6126 if ((ifp = tmpfile())) {
6127 fwrite (buf, sony_length, 1, ifp);
6128 fseek (ifp, 0, SEEK_SET);
6129 parse_tiff_ifd (-sony_offset);
6135 for (i=0; i < colors; i++)
6136 FORCC cc[i][c] *= ab[i];
6138 FORCC for (i=0; i < 3; i++)
6139 for (cam_xyz[c][i]=j=0; j < colors; j++)
6140 cam_xyz[c][i] += cc[c][j] * cm[j][i] * xyz[i];
6141 cam_xyz_coeff (cmatrix, cam_xyz);
6145 FORCC cam_mul[c] = 1 / asn[c];
6148 FORCC pre_mul[c] /= cc[c][c];
6152 int CLASS parse_tiff (int base)
6156 fseek (ifp, base, SEEK_SET);
6158 if (order != 0x4949 && order != 0x4d4d) return 0;
6160 while ((doff = get4())) {
6161 fseek (ifp, doff+base, SEEK_SET);
6162 if (parse_tiff_ifd (base)) break;
6167 void CLASS apply_tiff()
6169 int max_samp=0, ties=0, os, ns, raw=-1, thm=-1, i;
6174 fseek (ifp, thumb_offset, SEEK_SET);
6175 if (ljpeg_start (&jh, 1)) {
6176 thumb_misc = jh.bits;
6177 thumb_width = jh.wide;
6178 thumb_height = jh.high;
6181 for (i=tiff_nifds; i--; ) {
6182 if (tiff_ifd[i].shutter)
6183 shutter = tiff_ifd[i].shutter;
6184 tiff_ifd[i].shutter = shutter;
6186 for (i=0; i < tiff_nifds; i++) {
6187 if (max_samp < tiff_ifd[i].samples)
6188 max_samp = tiff_ifd[i].samples;
6189 if (max_samp > 3) max_samp = 3;
6190 os = raw_width*raw_height;
6191 ns = tiff_ifd[i].width*tiff_ifd[i].height;
6194 ns *= tiff_ifd[i].bps;
6196 if ((tiff_ifd[i].comp != 6 || tiff_ifd[i].samples != 3) &&
6197 (tiff_ifd[i].width | tiff_ifd[i].height) < 0x10000 &&
6198 ns && ((ns > os && (ties = 1)) ||
6199 (ns == os && shot_select == ties++))) {
6200 raw_width = tiff_ifd[i].width;
6201 raw_height = tiff_ifd[i].height;
6202 tiff_bps = tiff_ifd[i].bps;
6203 tiff_compress = tiff_ifd[i].comp;
6204 data_offset = tiff_ifd[i].offset;
6205 tiff_flip = tiff_ifd[i].flip;
6206 tiff_samples = tiff_ifd[i].samples;
6207 tile_width = tiff_ifd[i].tile_width;
6208 tile_length = tiff_ifd[i].tile_length;
6209 shutter = tiff_ifd[i].shutter;
6213 if (is_raw == 1 && ties) is_raw = ties;
6214 if (!tile_width ) tile_width = INT_MAX;
6215 if (!tile_length) tile_length = INT_MAX;
6216 for (i=tiff_nifds; i--; )
6217 if (tiff_ifd[i].flip) tiff_flip = tiff_ifd[i].flip;
6218 if (raw >= 0 && !load_raw)
6219 switch (tiff_compress) {
6221 if (tiff_ifd[raw].bytes == raw_width*raw_height) {
6223 load_raw = &CLASS sony_arw2_load_raw; break;
6225 if (tiff_ifd[raw].bytes*8 != raw_width*raw_height*tiff_bps) {
6227 load_raw = &CLASS sony_arw_load_raw; break;
6233 case 32773: goto slr;
6235 if (!strncmp(make,"OLYMPUS",7) &&
6236 tiff_ifd[raw].bytes*2 == raw_width*raw_height*3)
6238 if (tiff_ifd[raw].bytes*5 == raw_width*raw_height*8) {
6243 case 8: load_raw = &CLASS eight_bit_load_raw; break;
6244 case 12: if (tiff_ifd[raw].phint == 2)
6246 load_raw = &CLASS packed_load_raw; break;
6247 case 14: load_flags = 0;
6248 case 16: load_raw = &CLASS unpacked_load_raw;
6249 if (!strncmp(make,"OLYMPUS",7) &&
6250 tiff_ifd[raw].bytes*7 > raw_width*raw_height)
6251 load_raw = &CLASS olympus_load_raw;
6254 case 6: case 7: case 99:
6255 load_raw = &CLASS lossless_jpeg_load_raw; break;
6257 load_raw = &CLASS kodak_262_load_raw; break;
6259 if ((raw_width+9)/10*16*raw_height == tiff_ifd[raw].bytes) {
6260 load_raw = &CLASS packed_load_raw;
6262 } else if (raw_width*raw_height*3 == tiff_ifd[raw].bytes*2) {
6263 load_raw = &CLASS packed_load_raw;
6264 if (model[0] == 'N') load_flags = 80;
6265 } else if (raw_width*raw_height*3 == tiff_ifd[raw].bytes) {
6266 load_raw = &CLASS nikon_yuv_load_raw;
6267 gamma_curve (1/2.4, 12.92, 1, 4095);
6268 memset (cblack, 0, sizeof cblack);
6270 } else if (raw_width*raw_height*2 == tiff_ifd[raw].bytes) {
6271 load_raw = &CLASS unpacked_load_raw;
6275 load_raw = &CLASS nikon_load_raw; break;
6277 load_raw = &CLASS pentax_load_raw; break;
6279 switch (tiff_ifd[raw].phint) {
6280 case 2: load_raw = &CLASS kodak_rgb_load_raw; filters = 0; break;
6281 case 6: load_raw = &CLASS kodak_ycbcr_load_raw; filters = 0; break;
6282 case 32803: load_raw = &CLASS kodak_65000_load_raw;
6284 case 32867: case 34892: break;
6285 default: is_raw = 0;
6288 if ( (tiff_samples == 3 && tiff_ifd[raw].bytes && tiff_bps != 14 &&
6289 (tiff_compress & -16) != 32768)
6290 || (tiff_bps == 8 && strncmp(make,"Phase",5) &&
6291 !strcasestr(make,"Kodak") && !strstr(model2,"DEBUG RAW")))
6293 for (i=0; i < tiff_nifds; i++)
6294 if (i != raw && tiff_ifd[i].samples == max_samp &&
6295 tiff_ifd[i].width * tiff_ifd[i].height / (SQR(tiff_ifd[i].bps)+1) >
6296 thumb_width * thumb_height / (SQR(thumb_misc)+1)
6297 && tiff_ifd[i].comp != 34892) {
6298 thumb_width = tiff_ifd[i].width;
6299 thumb_height = tiff_ifd[i].height;
6300 thumb_offset = tiff_ifd[i].offset;
6301 thumb_length = tiff_ifd[i].bytes;
6302 thumb_misc = tiff_ifd[i].bps;
6306 thumb_misc |= tiff_ifd[thm].samples << 5;
6307 switch (tiff_ifd[thm].comp) {
6309 write_thumb = &CLASS layer_thumb;
6312 if (tiff_ifd[thm].bps <= 8)
6313 write_thumb = &CLASS ppm_thumb;
6314 else if (!strcmp(make,"Imacon"))
6315 write_thumb = &CLASS ppm16_thumb;
6317 thumb_load_raw = &CLASS kodak_thumb_load_raw;
6320 thumb_load_raw = tiff_ifd[thm].phint == 6 ?
6321 &CLASS kodak_ycbcr_load_raw : &CLASS kodak_rgb_load_raw;
6326 void CLASS parse_minolta (int base)
6328 int save, tag, len, offset, high=0, wide=0, i, c;
6331 fseek (ifp, base, SEEK_SET);
6332 if (fgetc(ifp) || fgetc(ifp)-'M' || fgetc(ifp)-'R') return;
6333 order = fgetc(ifp) * 0x101;
6334 offset = base + get4() + 8;
6335 while ((save=ftell(ifp)) < offset) {
6336 for (tag=i=0; i < 4; i++)
6337 tag = tag << 8 | fgetc(ifp);
6340 case 0x505244: /* PRD */
6341 fseek (ifp, 8, SEEK_CUR);
6345 case 0x574247: /* WBG */
6347 i = strcmp(model,"DiMAGE A200") ? 0:3;
6348 FORC4 cam_mul[c ^ (c >> 1) ^ i] = get2();
6350 case 0x545457: /* TTW */
6351 parse_tiff (ftell(ifp));
6352 data_offset = offset;
6354 fseek (ifp, save+len+8, SEEK_SET);
6362 Many cameras have a "debug mode" that writes JPEG and raw
6363 at the same time. The raw file has no header, so try to
6364 to open the matching JPEG file and read its metadata.
6366 void CLASS parse_external_jpeg()
6368 const char *file, *ext;
6369 char *jname, *jfile, *jext;
6372 ext = strrchr (ifname, '.');
6373 file = strrchr (ifname, '/');
6374 if (!file) file = strrchr (ifname, '\\');
6375 if (!file) file = ifname-1;
6377 if (!ext || strlen(ext) != 4 || ext-file != 8) return;
6378 jname = (char *) malloc (strlen(ifname) + 1);
6379 merror (jname, "parse_external_jpeg()");
6380 strcpy (jname, ifname);
6381 jfile = file - ifname + jname;
6382 jext = ext - ifname + jname;
6383 if (strcasecmp (ext, ".jpg")) {
6384 strcpy (jext, isupper(ext[1]) ? ".JPG":".jpg");
6385 if (isdigit(*file)) {
6386 memcpy (jfile, file+4, 4);
6387 memcpy (jfile+4, file, 4);
6390 while (isdigit(*--jext)) {
6397 if (strcmp (jname, ifname)) {
6398 if ((ifp = fopen (jname, "rb"))) {
6400 fprintf (stderr,_("Reading metadata from %s ...\n"), jname);
6408 fprintf (stderr,_("Failed to read metadata from %s\n"), jname);
6414 CIFF block 0x1030 contains an 8x8 white sample.
6415 Load this into white[][] for use in scale_colors().
6417 void CLASS ciff_block_1030()
6419 static const ushort key[] = { 0x410, 0x45f3 };
6420 int i, bpp, row, col, vbits=0;
6421 unsigned long bitbuf=0;
6423 if ((get2(),get4()) != 0x80008 || !get4()) return;
6425 if (bpp != 10 && bpp != 12) return;
6426 for (i=row=0; row < 8; row++)
6427 for (col=0; col < 8; col++) {
6429 bitbuf = bitbuf << 16 | (get2() ^ key[i++ & 1]);
6432 white[row][col] = bitbuf >> (vbits -= bpp) & ~(-1 << bpp);
6437 Parse a CIFF file, better known as Canon CRW format.
6439 void CLASS parse_ciff (int offset, int length, int depth)
6441 int tboff, nrecs, c, type, len, save, wbi=-1;
6442 ushort key[] = { 0x410, 0x45f3 };
6444 fseek (ifp, offset+length-4, SEEK_SET);
6445 tboff = get4() + offset;
6446 fseek (ifp, tboff, SEEK_SET);
6448 if ((nrecs | depth) > 127) return;
6452 save = ftell(ifp) + 4;
6453 fseek (ifp, offset+get4(), SEEK_SET);
6454 if ((((type >> 8) + 8) | 8) == 0x38)
6455 parse_ciff (ftell(ifp), len, depth+1); /* Parse a sub-table */
6457 fread (artist, 64, 1, ifp);
6458 if (type == 0x080a) {
6459 fread (make, 64, 1, ifp);
6460 fseek (ifp, strlen(make) - 63, SEEK_CUR);
6461 fread (model, 64, 1, ifp);
6463 if (type == 0x1810) {
6466 pixel_aspect = int_to_float(get4());
6469 if (type == 0x1835) /* Get the decoder table */
6470 tiff_compress = get4();
6471 if (type == 0x2007) {
6472 thumb_offset = ftell(ifp);
6475 if (type == 0x1818) {
6476 shutter = pow (2, -int_to_float((get4(),get4())));
6477 aperture = pow (2, int_to_float(get4())/2);
6479 if (type == 0x102a) {
6480 iso_speed = pow (2, (get4(),get2())/32.0 - 4) * 50;
6481 aperture = pow (2, (get2(),(short)get2())/64.0);
6482 shutter = pow (2,-((short)get2())/32.0);
6483 wbi = (get2(),get2());
6484 if (wbi > 17) wbi = 0;
6485 fseek (ifp, 32, SEEK_CUR);
6486 if (shutter > 1e6) shutter = get2()/10.0;
6488 if (type == 0x102c) {
6489 if (get2() > 512) { /* Pro90, G1 */
6490 fseek (ifp, 118, SEEK_CUR);
6491 FORC4 cam_mul[c ^ 2] = get2();
6492 } else { /* G2, S30, S40 */
6493 fseek (ifp, 98, SEEK_CUR);
6494 FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get2();
6497 if (type == 0x0032) {
6498 if (len == 768) { /* EOS D30 */
6499 fseek (ifp, 72, SEEK_CUR);
6500 FORC4 cam_mul[c ^ (c >> 1)] = 1024.0 / get2();
6501 if (!wbi) cam_mul[0] = -1; /* use my auto white balance */
6502 } else if (!cam_mul[0]) {
6503 if (get2() == key[0]) /* Pro1, G6, S60, S70 */
6504 c = (strstr(model,"Pro1") ?
6505 "012346000000000000":"01345:000000006008")[wbi]-'0'+ 2;
6506 else { /* G3, G5, S45, S50 */
6507 c = "023457000000006000"[wbi]-'0';
6508 key[0] = key[1] = 0;
6510 fseek (ifp, 78 + c*8, SEEK_CUR);
6511 FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get2() ^ key[c & 1];
6512 if (!wbi) cam_mul[0] = -1;
6515 if (type == 0x10a9) { /* D60, 10D, 300D, and clones */
6516 if (len > 66) wbi = "0134567028"[wbi]-'0';
6517 fseek (ifp, 2 + wbi*8, SEEK_CUR);
6518 FORC4 cam_mul[c ^ (c >> 1)] = get2();
6520 if (type == 0x1030 && (0x18040 >> wbi & 1))
6521 ciff_block_1030(); /* all that don't have 0x10a9 */
6522 if (type == 0x1031) {
6523 raw_width = (get2(),get2());
6524 raw_height = get2();
6526 if (type == 0x5029) {
6527 focal_len = len >> 16;
6528 if ((len & 0xffff) == 2) focal_len /= 32;
6530 if (type == 0x5813) flash_used = int_to_float(len);
6531 if (type == 0x5814) canon_ev = int_to_float(len);
6532 if (type == 0x5817) shot_order = len;
6533 if (type == 0x5834) unique_id = len;
6534 if (type == 0x580e) timestamp = len;
6535 if (type == 0x180e) timestamp = get4();
6537 if ((type | 0x4000) == 0x580e)
6538 timestamp = mktime (gmtime (×tamp));
6540 fseek (ifp, save, SEEK_SET);
6544 void CLASS parse_rollei()
6546 char line[128], *val;
6549 fseek (ifp, 0, SEEK_SET);
6550 memset (&t, 0, sizeof t);
6552 fgets (line, 128, ifp);
6553 if ((val = strchr(line,'=')))
6556 val = line + strlen(line);
6557 if (!strcmp(line,"DAT"))
6558 sscanf (val, "%d.%d.%d", &t.tm_mday, &t.tm_mon, &t.tm_year);
6559 if (!strcmp(line,"TIM"))
6560 sscanf (val, "%d:%d:%d", &t.tm_hour, &t.tm_min, &t.tm_sec);
6561 if (!strcmp(line,"HDR"))
6562 thumb_offset = atoi(val);
6563 if (!strcmp(line,"X "))
6564 raw_width = atoi(val);
6565 if (!strcmp(line,"Y "))
6566 raw_height = atoi(val);
6567 if (!strcmp(line,"TX "))
6568 thumb_width = atoi(val);
6569 if (!strcmp(line,"TY "))
6570 thumb_height = atoi(val);
6571 } while (strncmp(line,"EOHD",4));
6572 data_offset = thumb_offset + thumb_width * thumb_height * 2;
6576 timestamp = mktime(&t);
6577 strcpy (make, "Rollei");
6578 strcpy (model,"d530flex");
6579 write_thumb = &CLASS rollei_thumb;
6582 void CLASS parse_sinar_ia()
6588 fseek (ifp, 4, SEEK_SET);
6590 fseek (ifp, get4(), SEEK_SET);
6592 off = get4(); get4();
6593 fread (str, 8, 1, ifp);
6594 if (!strcmp(str,"META")) meta_offset = off;
6595 if (!strcmp(str,"THUMB")) thumb_offset = off;
6596 if (!strcmp(str,"RAW0")) data_offset = off;
6598 fseek (ifp, meta_offset+20, SEEK_SET);
6599 fread (make, 64, 1, ifp);
6601 if ((cp = strchr(make,' '))) {
6602 strcpy (model, cp+1);
6606 raw_height = get2();
6607 load_raw = &CLASS unpacked_load_raw;
6608 thumb_width = (get4(),get2());
6609 thumb_height = get2();
6610 write_thumb = &CLASS ppm_thumb;
6614 void CLASS parse_phase_one (int base)
6617 unsigned entries, tag, /*type,*/ len, data, save, i, c;
6618 float romm_cam[3][3];
6621 memset (&ph1, 0, sizeof ph1);
6622 fseek (ifp, base, SEEK_SET);
6623 order = get4() & 0xffff;
6624 if (get4() >> 8 != 0x526177) return; /* "Raw" */
6625 fseek (ifp, get4()+base, SEEK_SET);
6635 fseek (ifp, base+data, SEEK_SET);
6637 case 0x100: flip = "0653"[data & 3]-'0'; break;
6639 for (i=0; i < 9; i++)
6640 ((float *)romm_cam)[i] = getreal(11);
6641 romm_coeff (romm_cam);
6644 FORC3 cam_mul[c] = getreal(11);
6646 case 0x108: raw_width = data; break;
6647 case 0x109: raw_height = data; break;
6648 case 0x10a: left_margin = data; break;
6649 case 0x10b: top_margin = data; break;
6650 case 0x10c: width = data; break;
6651 case 0x10d: height = data; break;
6652 case 0x10e: ph1.format = data; break;
6653 case 0x10f: data_offset = data+base; break;
6654 case 0x110: meta_offset = data+base;
6655 meta_length = len; break;
6656 case 0x112: ph1.key_off = save - 4; break;
6657 case 0x210: ph1.tag_210 = int_to_float(data); break;
6658 case 0x21a: ph1.tag_21a = data; break;
6659 case 0x21c: strip_offset = data+base; break;
6660 case 0x21d: ph1.black = data; break;
6661 case 0x222: ph1.split_col = data; break;
6662 case 0x223: ph1.black_col = data+base; break;
6663 case 0x224: ph1.split_row = data; break;
6664 case 0x225: ph1.black_row = data+base; break;
6667 fread (model, 1, 63, ifp);
6668 if ((cp = strstr(model," camera"))) *cp = 0;
6670 fseek (ifp, save, SEEK_SET);
6672 load_raw = ph1.format < 3 ?
6673 &CLASS phase_one_load_raw : &CLASS phase_one_load_raw_c;
6675 strcpy (make, "Phase One");
6676 if (model[0]) return;
6677 switch (raw_height) {
6678 case 2060: strcpy (model,"LightPhase"); break;
6679 case 2682: strcpy (model,"H 10"); break;
6680 case 4128: strcpy (model,"H 20"); break;
6681 case 5488: strcpy (model,"H 25"); break;
6685 void CLASS parse_fuji (int offset)
6687 unsigned entries, tag, len, save, c;
6689 fseek (ifp, offset, SEEK_SET);
6691 if (entries > 255) return;
6697 raw_height = get2();
6699 } else if (tag == 0x121) {
6701 if ((width = get2()) == 4284) width += 3;
6702 } else if (tag == 0x130) {
6703 fuji_layout = fgetc(ifp) >> 7;
6704 fuji_width = !(fgetc(ifp) & 8);
6705 } else if (tag == 0x131) {
6707 FORC(36) xtrans_abs[0][35-c] = fgetc(ifp) & 3;
6708 } else if (tag == 0x2ff0) {
6709 FORC4 cam_mul[c ^ 1] = get2();
6710 } else if (tag == 0xc000) {
6713 while ((tag = get4()) > raw_width);
6718 fseek (ifp, save+len, SEEK_SET);
6720 height <<= fuji_layout;
6721 width >>= fuji_layout;
6724 int CLASS parse_jpeg (int offset)
6726 int len, save, hlen, mark;
6728 fseek (ifp, offset, SEEK_SET);
6729 if (fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) return 0;
6731 while (fgetc(ifp) == 0xff && (mark = fgetc(ifp)) != 0xda) {
6735 if (mark == 0xc0 || mark == 0xc3 || mark == 0xc9) {
6737 raw_height = get2();
6742 if (get4() == 0x48454150) /* "HEAP" */
6743 parse_ciff (save+hlen, len-hlen, 0);
6744 if (parse_tiff (save+6)) apply_tiff();
6745 fseek (ifp, save+len, SEEK_SET);
6750 void CLASS parse_riff()
6752 unsigned i, size, end;
6753 char tag[4], date[64], month[64];
6754 static const char mon[12][4] =
6755 { "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" };
6759 fread (tag, 4, 1, ifp);
6761 end = ftell(ifp) + size;
6762 if (!memcmp(tag,"RIFF",4) || !memcmp(tag,"LIST",4)) {
6764 while (ftell(ifp)+7 < end && !feof(ifp))
6766 } else if (!memcmp(tag,"nctg",4)) {
6767 while (ftell(ifp)+7 < end) {
6770 if ((i+1) >> 1 == 10 && size == 20)
6772 else fseek (ifp, size, SEEK_CUR);
6774 } else if (!memcmp(tag,"IDIT",4) && size < 64) {
6775 fread (date, 64, 1, ifp);
6777 memset (&t, 0, sizeof t);
6778 if (sscanf (date, "%*s %s %d %d:%d:%d %d", month, &t.tm_mday,
6779 &t.tm_hour, &t.tm_min, &t.tm_sec, &t.tm_year) == 6) {
6780 for (i=0; i < 12 && strcasecmp(mon[i],month); i++);
6784 timestamp = mktime(&t);
6787 fseek (ifp, size, SEEK_CUR);
6790 void CLASS parse_qt (int end)
6792 unsigned save, size;
6796 while (ftell(ifp)+7 < end) {
6798 if ((size = get4()) < 8) return;
6799 fread (tag, 4, 1, ifp);
6800 if (!memcmp(tag,"moov",4) ||
6801 !memcmp(tag,"udta",4) ||
6802 !memcmp(tag,"CNTH",4))
6803 parse_qt (save+size);
6804 if (!memcmp(tag,"CNDA",4))
6805 parse_jpeg (ftell(ifp));
6806 fseek (ifp, save+size, SEEK_SET);
6810 void CLASS parse_smal (int offset, int fsize)
6814 fseek (ifp, offset+2, SEEK_SET);
6818 fseek (ifp, 5, SEEK_CUR);
6819 if (get4() != fsize) return;
6820 if (ver > 6) data_offset = get4();
6821 raw_height = height = get2();
6822 raw_width = width = get2();
6823 strcpy (make, "SMaL");
6824 sprintf (model, "v%d %dx%d", ver, width, height);
6825 if (ver == 6) load_raw = &CLASS smal_v6_load_raw;
6826 if (ver == 9) load_raw = &CLASS smal_v9_load_raw;
6829 void CLASS parse_cine()
6831 unsigned off_head, off_setup, off_image, i;
6834 fseek (ifp, 4, SEEK_SET);
6835 is_raw = get2() == 2;
6836 fseek (ifp, 14, SEEK_CUR);
6842 if ((i = get4())) timestamp = i;
6843 fseek (ifp, off_head+4, SEEK_SET);
6845 raw_height = get4();
6846 switch (get2(),get2()) {
6847 case 8: load_raw = &CLASS eight_bit_load_raw; break;
6848 case 16: load_raw = &CLASS unpacked_load_raw;
6850 fseek (ifp, off_setup+792, SEEK_SET);
6851 strcpy (make, "CINE");
6852 sprintf (model, "%d", get4());
6853 fseek (ifp, 12, SEEK_CUR);
6854 switch ((i=get4()) & 0xffffff) {
6855 case 3: filters = 0x94949494; break;
6856 case 4: filters = 0x49494949; break;
6857 default: is_raw = 0;
6859 fseek (ifp, 72, SEEK_CUR);
6860 switch ((get4()+3600) % 360) {
6861 case 270: flip = 4; break;
6862 case 180: flip = 1; break;
6863 case 90: flip = 7; break;
6866 cam_mul[0] = getreal(11);
6867 cam_mul[2] = getreal(11);
6868 maximum = ~(-1 << get4());
6869 fseek (ifp, 668, SEEK_CUR);
6870 shutter = get4()/1000000000.0;
6871 fseek (ifp, off_image, SEEK_SET);
6872 if (shot_select < is_raw)
6873 fseek (ifp, shot_select*8, SEEK_CUR);
6874 data_offset = (INT64) get4() + 8;
6875 data_offset += (INT64) get4() << 32;
6878 void CLASS parse_redcine()
6880 unsigned i, len, rdvo;
6884 fseek (ifp, 52, SEEK_SET);
6887 fseek (ifp, 0, SEEK_END);
6888 fseek (ifp, -(i = ftello(ifp) & 511), SEEK_CUR);
6889 if (get4() != i || get4() != 0x52454f42) {
6890 fprintf (stderr,_("%s: Tail is missing, parsing from head...\n"), ifname);
6891 fseek (ifp, 0, SEEK_SET);
6892 while ((len = get4()) != EOF) {
6893 if (get4() == 0x52454456)
6894 if (is_raw++ == shot_select)
6895 data_offset = ftello(ifp) - 8;
6896 fseek (ifp, len-8, SEEK_CUR);
6900 fseek (ifp, 12, SEEK_CUR);
6902 fseeko (ifp, rdvo+8 + shot_select*4, SEEK_SET);
6903 data_offset = get4();
6907 char * CLASS foveon_gets (int offset, char *str, int len)
6910 fseek (ifp, offset, SEEK_SET);
6911 for (i=0; i < len-1; i++)
6912 if ((str[i] = get2()) == 0) break;
6917 void CLASS parse_foveon()
6919 int entries, img=0, off, len, tag, save, i, wide, high, pent, poff[256][2];
6920 char name[64], value[64];
6922 order = 0x4949; /* Little-endian */
6923 fseek (ifp, 36, SEEK_SET);
6925 fseek (ifp, -4, SEEK_END);
6926 fseek (ifp, get4(), SEEK_SET);
6927 if (get4() != 0x64434553) return; /* SECd */
6928 entries = (get4(),get4());
6934 fseek (ifp, off, SEEK_SET);
6935 if (get4() != (0x20434553 | (tag << 24))) return;
6937 case 0x47414d49: /* IMAG */
6938 case 0x32414d49: /* IMA2 */
6939 fseek (ifp, 8, SEEK_CUR);
6943 if (wide > raw_width && high > raw_height) {
6945 case 5: load_flags = 1;
6946 case 6: load_raw = &CLASS foveon_sd_load_raw; break;
6947 case 30: load_raw = &CLASS foveon_dp_load_raw; break;
6948 default: load_raw = 0;
6952 data_offset = off+28;
6955 fseek (ifp, off+28, SEEK_SET);
6956 if (fgetc(ifp) == 0xff && fgetc(ifp) == 0xd8
6957 && thumb_length < len-28) {
6958 thumb_offset = off+28;
6959 thumb_length = len-28;
6960 write_thumb = &CLASS jpeg_thumb;
6962 if (++img == 2 && !thumb_length) {
6963 thumb_offset = off+24;
6965 thumb_height = high;
6966 write_thumb = &CLASS foveon_thumb;
6969 case 0x464d4143: /* CAMF */
6970 meta_offset = off+8;
6971 meta_length = len-28;
6973 case 0x504f5250: /* PROP */
6974 pent = (get4(),get4());
6975 fseek (ifp, 12, SEEK_CUR);
6977 if ((unsigned) pent > 256) pent=256;
6978 for (i=0; i < pent*2; i++)
6979 ((int *)poff)[i] = off + get4()*2;
6980 for (i=0; i < pent; i++) {
6981 foveon_gets (poff[i][0], name, 64);
6982 foveon_gets (poff[i][1], value, 64);
6983 if (!strcmp (name, "ISO"))
6984 iso_speed = atoi(value);
6985 if (!strcmp (name, "CAMMANUF"))
6986 strcpy (make, value);
6987 if (!strcmp (name, "CAMMODEL"))
6988 strcpy (model, value);
6989 if (!strcmp (name, "WB_DESC"))
6990 strcpy (model2, value);
6991 if (!strcmp (name, "TIME"))
6992 timestamp = atoi(value);
6993 if (!strcmp (name, "EXPTIME"))
6994 shutter = atoi(value) / 1000000.0;
6995 if (!strcmp (name, "APERTURE"))
6996 aperture = atof(value);
6997 if (!strcmp (name, "FLENGTH"))
6998 focal_len = atof(value);
7001 timestamp = mktime (gmtime (×tamp));
7004 fseek (ifp, save, SEEK_SET);
7009 All matrices are from Adobe DNG Converter unless otherwise noted.
7011 void CLASS adobe_coeff (const char *make, const char *model)
7013 static const struct {
7015 short black, maximum, trans[12];
7017 { "AgfaPhoto DC-833m", 0, 0, /* DJC */
7018 { 11438,-3762,-1115,-2409,9914,2497,-1227,2295,5300 } },
7019 { "Apple QuickTake", 0, 0, /* DJC */
7020 { 21392,-5653,-3353,2406,8010,-415,7166,1427,2078 } },
7021 { "Canon EOS D2000", 0, 0,
7022 { 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } },
7023 { "Canon EOS D6000", 0, 0,
7024 { 20482,-7172,-3125,-1033,10410,-285,2542,226,3136 } },
7025 { "Canon EOS D30", 0, 0,
7026 { 9805,-2689,-1312,-5803,13064,3068,-2438,3075,8775 } },
7027 { "Canon EOS D60", 0, 0xfa0,
7028 { 6188,-1341,-890,-7168,14489,2937,-2640,3228,8483 } },
7029 { "Canon EOS 5DS", 0, 0x3c96,
7030 { 6250,-711,-808,-5153,12794,2636,-1249,2198,5610 } },
7031 { "Canon EOS 5D Mark III", 0, 0x3c80,
7032 { 6722,-635,-963,-4287,12460,2028,-908,2162,5668 } },
7033 { "Canon EOS 5D Mark II", 0, 0x3cf0,
7034 { 4716,603,-830,-7798,15474,2480,-1496,1937,6651 } },
7035 { "Canon EOS 5D", 0, 0xe6c,
7036 { 6347,-479,-972,-8297,15954,2480,-1968,2131,7649 } },
7037 { "Canon EOS 6D", 0, 0x3c82,
7038 { 7034,-804,-1014,-4420,12564,2058,-851,1994,5758 } },
7039 { "Canon EOS 7D Mark II", 0, 0x3510,
7040 { 7268,-1082,-969,-4186,11839,2663,-825,2029,5839 } },
7041 { "Canon EOS 7D", 0, 0x3510,
7042 { 6844,-996,-856,-3876,11761,2396,-593,1772,6198 } },
7043 { "Canon EOS 10D", 0, 0xfa0,
7044 { 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } },
7045 { "Canon EOS 20Da", 0, 0,
7046 { 14155,-5065,-1382,-6550,14633,2039,-1623,1824,6561 } },
7047 { "Canon EOS 20D", 0, 0xfff,
7048 { 6599,-537,-891,-8071,15783,2424,-1983,2234,7462 } },
7049 { "Canon EOS 30D", 0, 0,
7050 { 6257,-303,-1000,-7880,15621,2396,-1714,1904,7046 } },
7051 { "Canon EOS 40D", 0, 0x3f60,
7052 { 6071,-747,-856,-7653,15365,2441,-2025,2553,7315 } },
7053 { "Canon EOS 50D", 0, 0x3d93,
7054 { 4920,616,-593,-6493,13964,2784,-1774,3178,7005 } },
7055 { "Canon EOS 60D", 0, 0x2ff7,
7056 { 6719,-994,-925,-4408,12426,2211,-887,2129,6051 } },
7057 { "Canon EOS 70D", 0, 0x3bc7,
7058 { 7034,-804,-1014,-4420,12564,2058,-851,1994,5758 } },
7059 { "Canon EOS 80D", 0, 0,
7060 { 7457,-671,-937,-4849,12495,2643,-1213,2354,5492 } },
7061 { "Canon EOS 100D", 0, 0x350f,
7062 { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } },
7063 { "Canon EOS 300D", 0, 0xfa0,
7064 { 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } },
7065 { "Canon EOS 350D", 0, 0xfff,
7066 { 6018,-617,-965,-8645,15881,2975,-1530,1719,7642 } },
7067 { "Canon EOS 400D", 0, 0xe8e,
7068 { 7054,-1501,-990,-8156,15544,2812,-1278,1414,7796 } },
7069 { "Canon EOS 450D", 0, 0x390d,
7070 { 5784,-262,-821,-7539,15064,2672,-1982,2681,7427 } },
7071 { "Canon EOS 500D", 0, 0x3479,
7072 { 4763,712,-646,-6821,14399,2640,-1921,3276,6561 } },
7073 { "Canon EOS 550D", 0, 0x3dd7,
7074 { 6941,-1164,-857,-3825,11597,2534,-416,1540,6039 } },
7075 { "Canon EOS 600D", 0, 0x3510,
7076 { 6461,-907,-882,-4300,12184,2378,-819,1944,5931 } },
7077 { "Canon EOS 650D", 0, 0x354d,
7078 { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } },
7079 { "Canon EOS 700D", 0, 0x3c00,
7080 { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } },
7081 { "Canon EOS 750D", 0, 0x368e,
7082 { 6362,-823,-847,-4426,12109,2616,-743,1857,5635 } },
7083 { "Canon EOS 760D", 0, 0x350f,
7084 { 6362,-823,-847,-4426,12109,2616,-743,1857,5635 } },
7085 { "Canon EOS 1000D", 0, 0xe43,
7086 { 6771,-1139,-977,-7818,15123,2928,-1244,1437,7533 } },
7087 { "Canon EOS 1100D", 0, 0x3510,
7088 { 6444,-904,-893,-4563,12308,2535,-903,2016,6728 } },
7089 { "Canon EOS 1200D", 0, 0x37c2,
7090 { 6461,-907,-882,-4300,12184,2378,-819,1944,5931 } },
7091 { "Canon EOS 1300D", 0, 0x3510,
7092 { 6939,-1016,-866,-4428,12473,2177,-1175,2178,6162 } },
7093 { "Canon EOS M3", 0, 0,
7094 { 6362,-823,-847,-4426,12109,2616,-743,1857,5635 } },
7095 { "Canon EOS M10", 0, 0,
7096 { 6400,-480,-888,-5294,13416,2047,-1296,2203,6137 } },
7097 { "Canon EOS M", 0, 0,
7098 { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } },
7099 { "Canon EOS-1Ds Mark III", 0, 0x3bb0,
7100 { 5859,-211,-930,-8255,16017,2353,-1732,1887,7448 } },
7101 { "Canon EOS-1Ds Mark II", 0, 0xe80,
7102 { 6517,-602,-867,-8180,15926,2378,-1618,1771,7633 } },
7103 { "Canon EOS-1D Mark IV", 0, 0x3bb0,
7104 { 6014,-220,-795,-4109,12014,2361,-561,1824,5787 } },
7105 { "Canon EOS-1D Mark III", 0, 0x3bb0,
7106 { 6291,-540,-976,-8350,16145,2311,-1714,1858,7326 } },
7107 { "Canon EOS-1D Mark II N", 0, 0xe80,
7108 { 6240,-466,-822,-8180,15825,2500,-1801,1938,8042 } },
7109 { "Canon EOS-1D Mark II", 0, 0xe80,
7110 { 6264,-582,-724,-8312,15948,2504,-1744,1919,8664 } },
7111 { "Canon EOS-1DS", 0, 0xe20,
7112 { 4374,3631,-1743,-7520,15212,2472,-2892,3632,8161 } },
7113 { "Canon EOS-1D C", 0, 0x3c4e,
7114 { 6847,-614,-1014,-4669,12737,2139,-1197,2488,6846 } },
7115 { "Canon EOS-1D X Mark II", 0, 0,
7116 { 7596,-978,-967,-4808,12571,2503,-1398,2567,5752 } },
7117 { "Canon EOS-1D X", 0, 0x3c4e,
7118 { 6847,-614,-1014,-4669,12737,2139,-1197,2488,6846 } },
7119 { "Canon EOS-1D", 0, 0xe20,
7120 { 6806,-179,-1020,-8097,16415,1687,-3267,4236,7690 } },
7121 { "Canon EOS C500", 853, 0, /* DJC */
7122 { 17851,-10604,922,-7425,16662,763,-3660,3636,22278 } },
7123 { "Canon PowerShot A530", 0, 0,
7124 { 0 } }, /* don't want the A5 matrix */
7125 { "Canon PowerShot A50", 0, 0,
7126 { -5300,9846,1776,3436,684,3939,-5540,9879,6200,-1404,11175,217 } },
7127 { "Canon PowerShot A5", 0, 0,
7128 { -4801,9475,1952,2926,1611,4094,-5259,10164,5947,-1554,10883,547 } },
7129 { "Canon PowerShot G10", 0, 0,
7130 { 11093,-3906,-1028,-5047,12492,2879,-1003,1750,5561 } },
7131 { "Canon PowerShot G11", 0, 0,
7132 { 12177,-4817,-1069,-1612,9864,2049,-98,850,4471 } },
7133 { "Canon PowerShot G12", 0, 0,
7134 { 13244,-5501,-1248,-1508,9858,1935,-270,1083,4366 } },
7135 { "Canon PowerShot G15", 0, 0,
7136 { 7474,-2301,-567,-4056,11456,2975,-222,716,4181 } },
7137 { "Canon PowerShot G16", 0, 0,
7138 { 8020,-2687,-682,-3704,11879,2052,-965,1921,5556 } },
7139 { "Canon PowerShot G1 X", 0, 0,
7140 { 7378,-1255,-1043,-4088,12251,2048,-876,1946,5805 } },
7141 { "Canon PowerShot G1", 0, 0,
7142 { -4778,9467,2172,4743,-1141,4344,-5146,9908,6077,-1566,11051,557 } },
7143 { "Canon PowerShot G2", 0, 0,
7144 { 9087,-2693,-1049,-6715,14382,2537,-2291,2819,7790 } },
7145 { "Canon PowerShot G3 X", 0, 0,
7146 { 9701,-3857,-921,-3149,11537,1817,-786,1817,5147 } },
7147 { "Canon PowerShot G3", 0, 0,
7148 { 9212,-2781,-1073,-6573,14189,2605,-2300,2844,7664 } },
7149 { "Canon PowerShot G5 X", 0, 0,
7150 { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } },
7151 { "Canon PowerShot G5", 0, 0,
7152 { 9757,-2872,-933,-5972,13861,2301,-1622,2328,7212 } },
7153 { "Canon PowerShot G6", 0, 0,
7154 { 9877,-3775,-871,-7613,14807,3072,-1448,1305,7485 } },
7155 { "Canon PowerShot G7 X", 0, 0,
7156 { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } },
7157 { "Canon PowerShot G9 X", 0, 0,
7158 { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } },
7159 { "Canon PowerShot G9", 0, 0,
7160 { 7368,-2141,-598,-5621,13254,2625,-1418,1696,5743 } },
7161 { "Canon PowerShot Pro1", 0, 0,
7162 { 10062,-3522,-999,-7643,15117,2730,-765,817,7323 } },
7163 { "Canon PowerShot Pro70", 34, 0,
7164 { -4155,9818,1529,3939,-25,4522,-5521,9870,6610,-2238,10873,1342 } },
7165 { "Canon PowerShot Pro90", 0, 0,
7166 { -4963,9896,2235,4642,-987,4294,-5162,10011,5859,-1770,11230,577 } },
7167 { "Canon PowerShot S30", 0, 0,
7168 { 10566,-3652,-1129,-6552,14662,2006,-2197,2581,7670 } },
7169 { "Canon PowerShot S40", 0, 0,
7170 { 8510,-2487,-940,-6869,14231,2900,-2318,2829,9013 } },
7171 { "Canon PowerShot S45", 0, 0,
7172 { 8163,-2333,-955,-6682,14174,2751,-2077,2597,8041 } },
7173 { "Canon PowerShot S50", 0, 0,
7174 { 8882,-2571,-863,-6348,14234,2288,-1516,2172,6569 } },
7175 { "Canon PowerShot S60", 0, 0,
7176 { 8795,-2482,-797,-7804,15403,2573,-1422,1996,7082 } },
7177 { "Canon PowerShot S70", 0, 0,
7178 { 9976,-3810,-832,-7115,14463,2906,-901,989,7889 } },
7179 { "Canon PowerShot S90", 0, 0,
7180 { 12374,-5016,-1049,-1677,9902,2078,-83,852,4683 } },
7181 { "Canon PowerShot S95", 0, 0,
7182 { 13440,-5896,-1279,-1236,9598,1931,-180,1001,4651 } },
7183 { "Canon PowerShot S100", 0, 0,
7184 { 7968,-2565,-636,-2873,10697,2513,180,667,4211 } },
7185 { "Canon PowerShot S110", 0, 0,
7186 { 8039,-2643,-654,-3783,11230,2930,-206,690,4194 } },
7187 { "Canon PowerShot S120", 0, 0,
7188 { 6961,-1685,-695,-4625,12945,1836,-1114,2152,5518 } },
7189 { "Canon PowerShot SX1 IS", 0, 0,
7190 { 6578,-259,-502,-5974,13030,3309,-308,1058,4970 } },
7191 { "Canon PowerShot SX50 HS", 0, 0,
7192 { 12432,-4753,-1247,-2110,10691,1629,-412,1623,4926 } },
7193 { "Canon PowerShot SX60 HS", 0, 0,
7194 { 13161,-5451,-1344,-1989,10654,1531,-47,1271,4955 } },
7195 { "Canon PowerShot A3300", 0, 0, /* DJC */
7196 { 10826,-3654,-1023,-3215,11310,1906,0,999,4960 } },
7197 { "Canon PowerShot A470", 0, 0, /* DJC */
7198 { 12513,-4407,-1242,-2680,10276,2405,-878,2215,4734 } },
7199 { "Canon PowerShot A610", 0, 0, /* DJC */
7200 { 15591,-6402,-1592,-5365,13198,2168,-1300,1824,5075 } },
7201 { "Canon PowerShot A620", 0, 0, /* DJC */
7202 { 15265,-6193,-1558,-4125,12116,2010,-888,1639,5220 } },
7203 { "Canon PowerShot A630", 0, 0, /* DJC */
7204 { 14201,-5308,-1757,-6087,14472,1617,-2191,3105,5348 } },
7205 { "Canon PowerShot A640", 0, 0, /* DJC */
7206 { 13124,-5329,-1390,-3602,11658,1944,-1612,2863,4885 } },
7207 { "Canon PowerShot A650", 0, 0, /* DJC */
7208 { 9427,-3036,-959,-2581,10671,1911,-1039,1982,4430 } },
7209 { "Canon PowerShot A720", 0, 0, /* DJC */
7210 { 14573,-5482,-1546,-1266,9799,1468,-1040,1912,3810 } },
7211 { "Canon PowerShot S3 IS", 0, 0, /* DJC */
7212 { 14062,-5199,-1446,-4712,12470,2243,-1286,2028,4836 } },
7213 { "Canon PowerShot SX110 IS", 0, 0, /* DJC */
7214 { 14134,-5576,-1527,-1991,10719,1273,-1158,1929,3581 } },
7215 { "Canon PowerShot SX220", 0, 0, /* DJC */
7216 { 13898,-5076,-1447,-1405,10109,1297,-244,1860,3687 } },
7217 { "Canon IXUS 160", 0, 0, /* DJC */
7218 { 11657,-3781,-1136,-3544,11262,2283,-160,1219,4700 } },
7219 { "Casio EX-S20", 0, 0, /* DJC */
7220 { 11634,-3924,-1128,-4968,12954,2015,-1588,2648,7206 } },
7221 { "Casio EX-Z750", 0, 0, /* DJC */
7222 { 10819,-3873,-1099,-4903,13730,1175,-1755,3751,4632 } },
7223 { "Casio EX-Z10", 128, 0xfff, /* DJC */
7224 { 9790,-3338,-603,-2321,10222,2099,-344,1273,4799 } },
7226 { 3390,480,-500,-800,3610,340,-550,2336,1192 } },
7228 { 3390,480,-500,-800,3610,340,-550,2336,1192 } },
7230 { 20183,-4295,-423,-3940,15330,3985,-280,4870,9800 } },
7231 { "Contax N Digital", 0, 0xf1e,
7232 { 7777,1285,-1053,-9280,16543,2916,-3677,5679,7060 } },
7234 { 6596,-2079,-562,-4782,13016,1933,-970,1581,5181 } },
7235 { "Epson R-D1", 0, 0,
7236 { 6827,-1878,-732,-8429,16012,2564,-704,592,7145 } },
7237 { "Fujifilm E550", 0, 0,
7238 { 11044,-3888,-1120,-7248,15168,2208,-1531,2277,8069 } },
7239 { "Fujifilm E900", 0, 0,
7240 { 9183,-2526,-1078,-7461,15071,2574,-2022,2440,8639 } },
7241 { "Fujifilm F5", 0, 0,
7242 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
7243 { "Fujifilm F6", 0, 0,
7244 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
7245 { "Fujifilm F77", 0, 0xfe9,
7246 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
7247 { "Fujifilm F7", 0, 0,
7248 { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } },
7249 { "Fujifilm F8", 0, 0,
7250 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
7251 { "Fujifilm S100FS", 514, 0,
7252 { 11521,-4355,-1065,-6524,13767,3058,-1466,1984,6045 } },
7253 { "Fujifilm S1", 0, 0,
7254 { 12297,-4882,-1202,-2106,10691,1623,-88,1312,4790 } },
7255 { "Fujifilm S20Pro", 0, 0,
7256 { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } },
7257 { "Fujifilm S20", 512, 0x3fff,
7258 { 11401,-4498,-1312,-5088,12751,2613,-838,1568,5941 } },
7259 { "Fujifilm S2Pro", 128, 0,
7260 { 12492,-4690,-1402,-7033,15423,1647,-1507,2111,7697 } },
7261 { "Fujifilm S3Pro", 0, 0,
7262 { 11807,-4612,-1294,-8927,16968,1988,-2120,2741,8006 } },
7263 { "Fujifilm S5Pro", 0, 0,
7264 { 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } },
7265 { "Fujifilm S5000", 0, 0,
7266 { 8754,-2732,-1019,-7204,15069,2276,-1702,2334,6982 } },
7267 { "Fujifilm S5100", 0, 0,
7268 { 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } },
7269 { "Fujifilm S5500", 0, 0,
7270 { 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } },
7271 { "Fujifilm S5200", 0, 0,
7272 { 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } },
7273 { "Fujifilm S5600", 0, 0,
7274 { 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } },
7275 { "Fujifilm S6", 0, 0,
7276 { 12628,-4887,-1401,-6861,14996,1962,-2198,2782,7091 } },
7277 { "Fujifilm S7000", 0, 0,
7278 { 10190,-3506,-1312,-7153,15051,2238,-2003,2399,7505 } },
7279 { "Fujifilm S9000", 0, 0,
7280 { 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 } },
7281 { "Fujifilm S9500", 0, 0,
7282 { 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 } },
7283 { "Fujifilm S9100", 0, 0,
7284 { 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 } },
7285 { "Fujifilm S9600", 0, 0,
7286 { 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 } },
7287 { "Fujifilm SL1000", 0, 0,
7288 { 11705,-4262,-1107,-2282,10791,1709,-555,1713,4945 } },
7289 { "Fujifilm IS-1", 0, 0,
7290 { 21461,-10807,-1441,-2332,10599,1999,289,875,7703 } },
7291 { "Fujifilm IS Pro", 0, 0,
7292 { 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } },
7293 { "Fujifilm HS10 HS11", 0, 0xf68,
7294 { 12440,-3954,-1183,-1123,9674,1708,-83,1614,4086 } },
7295 { "Fujifilm HS2", 0, 0,
7296 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
7297 { "Fujifilm HS3", 0, 0,
7298 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
7299 { "Fujifilm HS50EXR", 0, 0,
7300 { 12085,-4727,-953,-3257,11489,2002,-511,2046,4592 } },
7301 { "Fujifilm F900EXR", 0, 0,
7302 { 12085,-4727,-953,-3257,11489,2002,-511,2046,4592 } },
7303 { "Fujifilm X100S", 0, 0,
7304 { 10592,-4262,-1008,-3514,11355,2465,-870,2025,6386 } },
7305 { "Fujifilm X100T", 0, 0,
7306 { 10592,-4262,-1008,-3514,11355,2465,-870,2025,6386 } },
7307 { "Fujifilm X100", 0, 0,
7308 { 12161,-4457,-1069,-5034,12874,2400,-795,1724,6904 } },
7309 { "Fujifilm X10", 0, 0,
7310 { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } },
7311 { "Fujifilm X20", 0, 0,
7312 { 11768,-4971,-1133,-4904,12927,2183,-480,1723,4605 } },
7313 { "Fujifilm X30", 0, 0,
7314 { 12328,-5256,-1144,-4469,12927,1675,-87,1291,4351 } },
7315 { "Fujifilm X70", 0, 0,
7316 { 10450,-4329,-878,-3217,11105,2421,-752,1758,6519 } },
7317 { "Fujifilm X-Pro1", 0, 0,
7318 { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } },
7319 { "Fujifilm X-Pro2", 0, 0,
7320 { 11434,-4948,-1210,-3746,12042,1903,-666,1479,5235 } },
7321 { "Fujifilm X-A1", 0, 0,
7322 { 11086,-4555,-839,-3512,11310,2517,-815,1341,5940 } },
7323 { "Fujifilm X-A2", 0, 0,
7324 { 10763,-4560,-917,-3346,11311,2322,-475,1135,5843 } },
7325 { "Fujifilm X-E1", 0, 0,
7326 { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } },
7327 { "Fujifilm X-E2S", 0, 0,
7328 { 11562,-5118,-961,-3022,11007,2311,-525,1569,6097 } },
7329 { "Fujifilm X-E2", 0, 0,
7330 { 8458,-2451,-855,-4597,12447,2407,-1475,2482,6526 } },
7331 { "Fujifilm X-M1", 0, 0,
7332 { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } },
7333 { "Fujifilm X-S1", 0, 0,
7334 { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } },
7335 { "Fujifilm X-T1", 0, 0, /* also X-T10 */
7336 { 8458,-2451,-855,-4597,12447,2407,-1475,2482,6526 } },
7337 { "Fujifilm XF1", 0, 0,
7338 { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } },
7339 { "Fujifilm XQ", 0, 0, /* XQ1 and XQ2 */
7340 { 9252,-2704,-1064,-5893,14265,1717,-1101,2341,4349 } },
7341 { "Imacon Ixpress", 0, 0, /* DJC */
7342 { 7025,-1415,-704,-5188,13765,1424,-1248,2742,6038 } },
7343 { "Kodak NC2000", 0, 0,
7344 { 13891,-6055,-803,-465,9919,642,2121,82,1291 } },
7345 { "Kodak DCS315C", 8, 0,
7346 { 17523,-4827,-2510,756,8546,-137,6113,1649,2250 } },
7347 { "Kodak DCS330C", 8, 0,
7348 { 20620,-7572,-2801,-103,10073,-396,3551,-233,2220 } },
7349 { "Kodak DCS420", 0, 0,
7350 { 10868,-1852,-644,-1537,11083,484,2343,628,2216 } },
7351 { "Kodak DCS460", 0, 0,
7352 { 10592,-2206,-967,-1944,11685,230,2206,670,1273 } },
7353 { "Kodak EOSDCS1", 0, 0,
7354 { 10592,-2206,-967,-1944,11685,230,2206,670,1273 } },
7355 { "Kodak EOSDCS3B", 0, 0,
7356 { 9898,-2700,-940,-2478,12219,206,1985,634,1031 } },
7357 { "Kodak DCS520C", 178, 0,
7358 { 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } },
7359 { "Kodak DCS560C", 177, 0,
7360 { 20482,-7172,-3125,-1033,10410,-285,2542,226,3136 } },
7361 { "Kodak DCS620C", 177, 0,
7362 { 23617,-10175,-3149,-2054,11749,-272,2586,-489,3453 } },
7363 { "Kodak DCS620X", 176, 0,
7364 { 13095,-6231,154,12221,-21,-2137,895,4602,2258 } },
7365 { "Kodak DCS660C", 173, 0,
7366 { 18244,-6351,-2739,-791,11193,-521,3711,-129,2802 } },
7367 { "Kodak DCS720X", 0, 0,
7368 { 11775,-5884,950,9556,1846,-1286,-1019,6221,2728 } },
7369 { "Kodak DCS760C", 0, 0,
7370 { 16623,-6309,-1411,-4344,13923,323,2285,274,2926 } },
7371 { "Kodak DCS Pro SLR", 0, 0,
7372 { 5494,2393,-232,-6427,13850,2846,-1876,3997,5445 } },
7373 { "Kodak DCS Pro 14nx", 0, 0,
7374 { 5494,2393,-232,-6427,13850,2846,-1876,3997,5445 } },
7375 { "Kodak DCS Pro 14", 0, 0,
7376 { 7791,3128,-776,-8588,16458,2039,-2455,4006,6198 } },
7377 { "Kodak ProBack645", 0, 0,
7378 { 16414,-6060,-1470,-3555,13037,473,2545,122,4948 } },
7379 { "Kodak ProBack", 0, 0,
7380 { 21179,-8316,-2918,-915,11019,-165,3477,-180,4210 } },
7381 { "Kodak P712", 0, 0,
7382 { 9658,-3314,-823,-5163,12695,2768,-1342,1843,6044 } },
7383 { "Kodak P850", 0, 0xf7c,
7384 { 10511,-3836,-1102,-6946,14587,2558,-1481,1792,6246 } },
7385 { "Kodak P880", 0, 0xfff,
7386 { 12805,-4662,-1376,-7480,15267,2360,-1626,2194,7904 } },
7387 { "Kodak EasyShare Z980", 0, 0,
7388 { 11313,-3559,-1101,-3893,11891,2257,-1214,2398,4908 } },
7389 { "Kodak EasyShare Z981", 0, 0,
7390 { 12729,-4717,-1188,-1367,9187,2582,274,860,4411 } },
7391 { "Kodak EasyShare Z990", 0, 0xfed,
7392 { 11749,-4048,-1309,-1867,10572,1489,-138,1449,4522 } },
7393 { "Kodak EASYSHARE Z1015", 0, 0xef1,
7394 { 11265,-4286,-992,-4694,12343,2647,-1090,1523,5447 } },
7395 { "Leaf CMost", 0, 0,
7396 { 3952,2189,449,-6701,14585,2275,-4536,7349,6536 } },
7397 { "Leaf Valeo 6", 0, 0,
7398 { 3952,2189,449,-6701,14585,2275,-4536,7349,6536 } },
7399 { "Leaf Aptus 54S", 0, 0,
7400 { 8236,1746,-1314,-8251,15953,2428,-3673,5786,5771 } },
7401 { "Leaf Aptus 65", 0, 0,
7402 { 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 } },
7403 { "Leaf Aptus 75", 0, 0,
7404 { 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 } },
7406 { 8236,1746,-1314,-8251,15953,2428,-3673,5786,5771 } },
7407 { "Mamiya ZD", 0, 0,
7408 { 7645,2579,-1363,-8689,16717,2015,-3712,5941,5961 } },
7409 { "Micron 2010", 110, 0, /* DJC */
7410 { 16695,-3761,-2151,155,9682,163,3433,951,4904 } },
7411 { "Minolta DiMAGE 5", 0, 0xf7d,
7412 { 8983,-2942,-963,-6556,14476,2237,-2426,2887,8014 } },
7413 { "Minolta DiMAGE 7Hi", 0, 0xf7d,
7414 { 11368,-3894,-1242,-6521,14358,2339,-2475,3056,7285 } },
7415 { "Minolta DiMAGE 7", 0, 0xf7d,
7416 { 9144,-2777,-998,-6676,14556,2281,-2470,3019,7744 } },
7417 { "Minolta DiMAGE A1", 0, 0xf8b,
7418 { 9274,-2547,-1167,-8220,16323,1943,-2273,2720,8340 } },
7419 { "Minolta DiMAGE A200", 0, 0,
7420 { 8560,-2487,-986,-8112,15535,2771,-1209,1324,7743 } },
7421 { "Minolta DiMAGE A2", 0, 0xf8f,
7422 { 9097,-2726,-1053,-8073,15506,2762,-966,981,7763 } },
7423 { "Minolta DiMAGE Z2", 0, 0, /* DJC */
7424 { 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 } },
7425 { "Minolta DYNAX 5", 0, 0xffb,
7426 { 10284,-3283,-1086,-7957,15762,2316,-829,882,6644 } },
7427 { "Minolta DYNAX 7", 0, 0xffb,
7428 { 10239,-3104,-1099,-8037,15727,2451,-927,925,6871 } },
7429 { "Motorola PIXL", 0, 0, /* DJC */
7430 { 8898,-989,-1033,-3292,11619,1674,-661,3178,5216 } },
7431 { "Nikon D100", 0, 0,
7432 { 5902,-933,-782,-8983,16719,2354,-1402,1455,6464 } },
7433 { "Nikon D1H", 0, 0,
7434 { 7577,-2166,-926,-7454,15592,1934,-2377,2808,8606 } },
7435 { "Nikon D1X", 0, 0,
7436 { 7702,-2245,-975,-9114,17242,1875,-2679,3055,8521 } },
7437 { "Nikon D1", 0, 0, /* multiplied by 2.218750, 1.0, 1.148438 */
7438 { 16772,-4726,-2141,-7611,15713,1972,-2846,3494,9521 } },
7439 { "Nikon D200", 0, 0xfbc,
7440 { 8367,-2248,-763,-8758,16447,2422,-1527,1550,8053 } },
7441 { "Nikon D2H", 0, 0,
7442 { 5710,-901,-615,-8594,16617,2024,-2975,4120,6830 } },
7443 { "Nikon D2X", 0, 0,
7444 { 10231,-2769,-1255,-8301,15900,2552,-797,680,7148 } },
7445 { "Nikon D3000", 0, 0,
7446 { 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } },
7447 { "Nikon D3100", 0, 0,
7448 { 7911,-2167,-813,-5327,13150,2408,-1288,2483,7968 } },
7449 { "Nikon D3200", 0, 0xfb9,
7450 { 7013,-1408,-635,-5268,12902,2640,-1470,2801,7379 } },
7451 { "Nikon D3300", 0, 0,
7452 { 6988,-1384,-714,-5631,13410,2447,-1485,2204,7318 } },
7453 { "Nikon D300", 0, 0,
7454 { 9030,-1992,-715,-8465,16302,2255,-2689,3217,8069 } },
7455 { "Nikon D3X", 0, 0,
7456 { 7171,-1986,-648,-8085,15555,2718,-2170,2512,7457 } },
7457 { "Nikon D3S", 0, 0,
7458 { 8828,-2406,-694,-4874,12603,2541,-660,1509,7587 } },
7460 { 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } },
7461 { "Nikon D40X", 0, 0,
7462 { 8819,-2543,-911,-9025,16928,2151,-1329,1213,8449 } },
7463 { "Nikon D40", 0, 0,
7464 { 6992,-1668,-806,-8138,15748,2543,-874,850,7897 } },
7465 { "Nikon D4S", 0, 0,
7466 { 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } },
7468 { 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } },
7470 { 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } },
7471 { "Nikon D5000", 0, 0xf00,
7472 { 7309,-1403,-519,-8474,16008,2622,-2433,2826,8064 } },
7473 { "Nikon D5100", 0, 0x3de6,
7474 { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } },
7475 { "Nikon D5200", 0, 0,
7476 { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } },
7477 { "Nikon D5300", 0, 0,
7478 { 6988,-1384,-714,-5631,13410,2447,-1485,2204,7318 } },
7479 { "Nikon D5500", 0, 0,
7480 { 8821,-2938,-785,-4178,12142,2287,-824,1651,6860 } },
7481 { "Nikon D500", 0, 0,
7482 { 8813,-3210,-1036,-4703,12868,2021,-1054,1940,6129 } },
7483 { "Nikon D50", 0, 0,
7484 { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } },
7486 { 9200,-3522,-992,-5755,13803,2117,-753,1486,6338 } },
7487 { "Nikon D600", 0, 0x3e07,
7488 { 8178,-2245,-609,-4857,12394,2776,-1207,2086,7298 } },
7489 { "Nikon D610", 0, 0,
7490 { 8178,-2245,-609,-4857,12394,2776,-1207,2086,7298 } },
7491 { "Nikon D60", 0, 0,
7492 { 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } },
7493 { "Nikon D7000", 0, 0,
7494 { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } },
7495 { "Nikon D7100", 0, 0,
7496 { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } },
7497 { "Nikon D7200", 0, 0,
7498 { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } },
7499 { "Nikon D750", 0, 0,
7500 { 9020,-2890,-715,-4535,12436,2348,-934,1919,7086 } },
7501 { "Nikon D700", 0, 0,
7502 { 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } },
7503 { "Nikon D70", 0, 0,
7504 { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } },
7505 { "Nikon D810", 0, 0,
7506 { 9369,-3195,-791,-4488,12430,2301,-893,1796,6872 } },
7507 { "Nikon D800", 0, 0,
7508 { 7866,-2108,-555,-4869,12483,2681,-1176,2069,7501 } },
7509 { "Nikon D80", 0, 0,
7510 { 8629,-2410,-883,-9055,16940,2171,-1490,1363,8520 } },
7511 { "Nikon D90", 0, 0xf00,
7512 { 7309,-1403,-519,-8474,16008,2622,-2434,2826,8064 } },
7513 { "Nikon E700", 0, 0x3dd, /* DJC */
7514 { -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } },
7515 { "Nikon E800", 0, 0x3dd, /* DJC */
7516 { -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } },
7517 { "Nikon E950", 0, 0x3dd, /* DJC */
7518 { -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } },
7519 { "Nikon E995", 0, 0, /* copied from E5000 */
7520 { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
7521 { "Nikon E2100", 0, 0, /* copied from Z2, new white balance */
7522 { 13142,-4152,-1596,-4655,12374,2282,-1769,2696,6711} },
7523 { "Nikon E2500", 0, 0,
7524 { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
7525 { "Nikon E3200", 0, 0, /* DJC */
7526 { 9846,-2085,-1019,-3278,11109,2170,-774,2134,5745 } },
7527 { "Nikon E4300", 0, 0, /* copied from Minolta DiMAGE Z2 */
7528 { 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 } },
7529 { "Nikon E4500", 0, 0,
7530 { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
7531 { "Nikon E5000", 0, 0,
7532 { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
7533 { "Nikon E5400", 0, 0,
7534 { 9349,-2987,-1001,-7919,15766,2266,-2098,2680,6839 } },
7535 { "Nikon E5700", 0, 0,
7536 { -5368,11478,2368,5537,-113,3148,-4969,10021,5782,778,9028,211 } },
7537 { "Nikon E8400", 0, 0,
7538 { 7842,-2320,-992,-8154,15718,2599,-1098,1342,7560 } },
7539 { "Nikon E8700", 0, 0,
7540 { 8489,-2583,-1036,-8051,15583,2643,-1307,1407,7354 } },
7541 { "Nikon E8800", 0, 0,
7542 { 7971,-2314,-913,-8451,15762,2894,-1442,1520,7610 } },
7543 { "Nikon COOLPIX A", 0, 0,
7544 { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } },
7545 { "Nikon COOLPIX P330", 200, 0,
7546 { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } },
7547 { "Nikon COOLPIX P340", 200, 0,
7548 { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } },
7549 { "Nikon COOLPIX P6000", 0, 0,
7550 { 9698,-3367,-914,-4706,12584,2368,-837,968,5801 } },
7551 { "Nikon COOLPIX P7000", 0, 0,
7552 { 11432,-3679,-1111,-3169,11239,2202,-791,1380,4455 } },
7553 { "Nikon COOLPIX P7100", 0, 0,
7554 { 11053,-4269,-1024,-1976,10182,2088,-526,1263,4469 } },
7555 { "Nikon COOLPIX P7700", 200, 0,
7556 { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } },
7557 { "Nikon COOLPIX P7800", 200, 0,
7558 { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } },
7559 { "Nikon 1 V3", 0, 0,
7560 { 5958,-1559,-571,-4021,11453,2939,-634,1548,5087 } },
7561 { "Nikon 1 J4", 0, 0,
7562 { 5958,-1559,-571,-4021,11453,2939,-634,1548,5087 } },
7563 { "Nikon 1 J5", 0, 0,
7564 { 7520,-2518,-645,-3844,12102,1945,-913,2249,6835 } },
7565 { "Nikon 1 S2", 200, 0,
7566 { 6612,-1342,-618,-3338,11055,2623,-174,1792,5075 } },
7567 { "Nikon 1 V2", 0, 0,
7568 { 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } },
7569 { "Nikon 1 J3", 0, 0,
7570 { 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } },
7571 { "Nikon 1 AW1", 0, 0,
7572 { 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } },
7573 { "Nikon 1 ", 0, 0, /* J1, J2, S1, V1 */
7574 { 8994,-2667,-865,-4594,12324,2552,-699,1786,6260 } },
7575 { "Olympus AIR A01", 0, 0,
7576 { 8992,-3093,-639,-2563,10721,2122,-437,1270,5473 } },
7577 { "Olympus C5050", 0, 0,
7578 { 10508,-3124,-1273,-6079,14294,1901,-1653,2306,6237 } },
7579 { "Olympus C5060", 0, 0,
7580 { 10445,-3362,-1307,-7662,15690,2058,-1135,1176,7602 } },
7581 { "Olympus C7070", 0, 0,
7582 { 10252,-3531,-1095,-7114,14850,2436,-1451,1723,6365 } },
7583 { "Olympus C70", 0, 0,
7584 { 10793,-3791,-1146,-7498,15177,2488,-1390,1577,7321 } },
7585 { "Olympus C80", 0, 0,
7586 { 8606,-2509,-1014,-8238,15714,2703,-942,979,7760 } },
7587 { "Olympus E-10", 0, 0xffc,
7588 { 12745,-4500,-1416,-6062,14542,1580,-1934,2256,6603 } },
7589 { "Olympus E-1", 0, 0,
7590 { 11846,-4767,-945,-7027,15878,1089,-2699,4122,8311 } },
7591 { "Olympus E-20", 0, 0xffc,
7592 { 13173,-4732,-1499,-5807,14036,1895,-2045,2452,7142 } },
7593 { "Olympus E-300", 0, 0,
7594 { 7828,-1761,-348,-5788,14071,1830,-2853,4518,6557 } },
7595 { "Olympus E-330", 0, 0,
7596 { 8961,-2473,-1084,-7979,15990,2067,-2319,3035,8249 } },
7597 { "Olympus E-30", 0, 0xfbc,
7598 { 8144,-1861,-1111,-7763,15894,1929,-1865,2542,7607 } },
7599 { "Olympus E-3", 0, 0xf99,
7600 { 9487,-2875,-1115,-7533,15606,2010,-1618,2100,7389 } },
7601 { "Olympus E-400", 0, 0,
7602 { 6169,-1483,-21,-7107,14761,2536,-2904,3580,8568 } },
7603 { "Olympus E-410", 0, 0xf6a,
7604 { 8856,-2582,-1026,-7761,15766,2082,-2009,2575,7469 } },
7605 { "Olympus E-420", 0, 0xfd7,
7606 { 8746,-2425,-1095,-7594,15612,2073,-1780,2309,7416 } },
7607 { "Olympus E-450", 0, 0xfd2,
7608 { 8745,-2425,-1095,-7594,15613,2073,-1780,2309,7416 } },
7609 { "Olympus E-500", 0, 0,
7610 { 8136,-1968,-299,-5481,13742,1871,-2556,4205,6630 } },
7611 { "Olympus E-510", 0, 0xf6a,
7612 { 8785,-2529,-1033,-7639,15624,2112,-1783,2300,7817 } },
7613 { "Olympus E-520", 0, 0xfd2,
7614 { 8344,-2322,-1020,-7596,15635,2048,-1748,2269,7287 } },
7615 { "Olympus E-5", 0, 0xeec,
7616 { 11200,-3783,-1325,-4576,12593,2206,-695,1742,7504 } },
7617 { "Olympus E-600", 0, 0xfaf,
7618 { 8453,-2198,-1092,-7609,15681,2008,-1725,2337,7824 } },
7619 { "Olympus E-620", 0, 0xfaf,
7620 { 8453,-2198,-1092,-7609,15681,2008,-1725,2337,7824 } },
7621 { "Olympus E-P1", 0, 0xffd,
7622 { 8343,-2050,-1021,-7715,15705,2103,-1831,2380,8235 } },
7623 { "Olympus E-P2", 0, 0xffd,
7624 { 8343,-2050,-1021,-7715,15705,2103,-1831,2380,8235 } },
7625 { "Olympus E-P3", 0, 0,
7626 { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } },
7627 { "Olympus E-P5", 0, 0,
7628 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
7629 { "Olympus E-PL1s", 0, 0,
7630 { 11409,-3872,-1393,-4572,12757,2003,-709,1810,7415 } },
7631 { "Olympus E-PL1", 0, 0,
7632 { 11408,-4289,-1215,-4286,12385,2118,-387,1467,7787 } },
7633 { "Olympus E-PL2", 0, 0xcf3,
7634 { 15030,-5552,-1806,-3987,12387,1767,-592,1670,7023 } },
7635 { "Olympus E-PL3", 0, 0,
7636 { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } },
7637 { "Olympus E-PL5", 0, 0xfcb,
7638 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
7639 { "Olympus E-PL6", 0, 0,
7640 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
7641 { "Olympus E-PL7", 0, 0,
7642 { 9197,-3190,-659,-2606,10830,2039,-458,1250,5458 } },
7643 { "Olympus E-PM1", 0, 0,
7644 { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } },
7645 { "Olympus E-PM2", 0, 0,
7646 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
7647 { "Olympus E-M10", 0, 0, /* also E-M10 Mark II */
7648 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
7649 { "Olympus E-M1", 0, 0,
7650 { 7687,-1984,-606,-4327,11928,2721,-1381,2339,6452 } },
7651 { "Olympus E-M5MarkII", 0, 0,
7652 { 9422,-3258,-711,-2655,10898,2015,-512,1354,5512 } },
7653 { "Olympus E-M5", 0, 0xfe1,
7654 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
7655 { "Olympus PEN-F", 0, 0,
7656 { 9476,-3182,-765,-2613,10958,1893,-449,1315,5268 } },
7657 { "Olympus SH-2", 0, 0,
7658 { 10156,-3425,-1077,-2611,11177,1624,-385,1592,5080 } },
7659 { "Olympus SP350", 0, 0,
7660 { 12078,-4836,-1069,-6671,14306,2578,-786,939,7418 } },
7661 { "Olympus SP3", 0, 0,
7662 { 11766,-4445,-1067,-6901,14421,2707,-1029,1217,7572 } },
7663 { "Olympus SP500UZ", 0, 0xfff,
7664 { 9493,-3415,-666,-5211,12334,3260,-1548,2262,6482 } },
7665 { "Olympus SP510UZ", 0, 0xffe,
7666 { 10593,-3607,-1010,-5881,13127,3084,-1200,1805,6721 } },
7667 { "Olympus SP550UZ", 0, 0xffe,
7668 { 11597,-4006,-1049,-5432,12799,2957,-1029,1750,6516 } },
7669 { "Olympus SP560UZ", 0, 0xff9,
7670 { 10915,-3677,-982,-5587,12986,2911,-1168,1968,6223 } },
7671 { "Olympus SP570UZ", 0, 0,
7672 { 11522,-4044,-1146,-4736,12172,2904,-988,1829,6039 } },
7673 { "Olympus STYLUS1", 0, 0,
7674 { 8360,-2420,-880,-3928,12353,1739,-1381,2416,5173 } },
7675 { "Olympus TG-4", 0, 0,
7676 { 11426,-4159,-1126,-2066,10678,1593,-120,1327,4998 } },
7677 { "Olympus XZ-10", 0, 0,
7678 { 9777,-3483,-925,-2886,11297,1800,-602,1663,5134 } },
7679 { "Olympus XZ-1", 0, 0,
7680 { 10901,-4095,-1074,-1141,9208,2293,-62,1417,5158 } },
7681 { "Olympus XZ-2", 0, 0,
7682 { 9777,-3483,-925,-2886,11297,1800,-602,1663,5134 } },
7683 { "OmniVision", 0, 0, /* DJC */
7684 { 12782,-4059,-379,-478,9066,1413,1340,1513,5176 } },
7685 { "Pentax *ist DL2", 0, 0,
7686 { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
7687 { "Pentax *ist DL", 0, 0,
7688 { 10829,-2838,-1115,-8339,15817,2696,-837,680,11939 } },
7689 { "Pentax *ist DS2", 0, 0,
7690 { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
7691 { "Pentax *ist DS", 0, 0,
7692 { 10371,-2333,-1206,-8688,16231,2602,-1230,1116,11282 } },
7693 { "Pentax *ist D", 0, 0,
7694 { 9651,-2059,-1189,-8881,16512,2487,-1460,1345,10687 } },
7695 { "Pentax K10D", 0, 0,
7696 { 9566,-2863,-803,-7170,15172,2112,-818,803,9705 } },
7697 { "Pentax K1", 0, 0,
7698 { 11095,-3157,-1324,-8377,15834,2720,-1108,947,11688 } },
7699 { "Pentax K20D", 0, 0,
7700 { 9427,-2714,-868,-7493,16092,1373,-2199,3264,7180 } },
7701 { "Pentax K200D", 0, 0,
7702 { 9186,-2678,-907,-8693,16517,2260,-1129,1094,8524 } },
7703 { "Pentax K2000", 0, 0,
7704 { 11057,-3604,-1155,-5152,13046,2329,-282,375,8104 } },
7705 { "Pentax K-m", 0, 0,
7706 { 11057,-3604,-1155,-5152,13046,2329,-282,375,8104 } },
7707 { "Pentax K-x", 0, 0,
7708 { 8843,-2837,-625,-5025,12644,2668,-411,1234,7410 } },
7709 { "Pentax K-r", 0, 0,
7710 { 9895,-3077,-850,-5304,13035,2521,-883,1768,6936 } },
7711 { "Pentax K-1", 0, 0,
7712 { 8566,-2746,-1201,-3612,12204,1550,-893,1680,6264 } },
7713 { "Pentax K-30", 0, 0,
7714 { 8710,-2632,-1167,-3995,12301,1881,-981,1719,6535 } },
7715 { "Pentax K-3 II", 0, 0,
7716 { 8626,-2607,-1155,-3995,12301,1881,-1039,1822,6925 } },
7717 { "Pentax K-3", 0, 0,
7718 { 7415,-2052,-721,-5186,12788,2682,-1446,2157,6773 } },
7719 { "Pentax K-5 II", 0, 0,
7720 { 8170,-2725,-639,-4440,12017,2744,-771,1465,6599 } },
7721 { "Pentax K-5", 0, 0,
7722 { 8713,-2833,-743,-4342,11900,2772,-722,1543,6247 } },
7723 { "Pentax K-7", 0, 0,
7724 { 9142,-2947,-678,-8648,16967,1663,-2224,2898,8615 } },
7725 { "Pentax K-S1", 0, 0,
7726 { 8512,-3211,-787,-4167,11966,2487,-638,1288,6054 } },
7727 { "Pentax K-S2", 0, 0,
7728 { 8662,-3280,-798,-3928,11771,2444,-586,1232,6054 } },
7729 { "Pentax Q-S1", 0, 0,
7730 { 12995,-5593,-1107,-1879,10139,2027,-64,1233,4919 } },
7731 { "Pentax 645D", 0, 0x3e00,
7732 { 10646,-3593,-1158,-3329,11699,1831,-667,2874,6287 } },
7733 { "Panasonic DMC-CM1", 15, 0,
7734 { 8770,-3194,-820,-2871,11281,1803,-513,1552,4434 } },
7735 { "Panasonic DMC-FZ8", 0, 0xf7f,
7736 { 8986,-2755,-802,-6341,13575,3077,-1476,2144,6379 } },
7737 { "Panasonic DMC-FZ18", 0, 0,
7738 { 9932,-3060,-935,-5809,13331,2753,-1267,2155,5575 } },
7739 { "Panasonic DMC-FZ28", 15, 0xf96,
7740 { 10109,-3488,-993,-5412,12812,2916,-1305,2140,5543 } },
7741 { "Panasonic DMC-FZ330", 15, 0,
7742 { 8378,-2798,-769,-3068,11410,1877,-538,1792,4623 } },
7743 { "Panasonic DMC-FZ300", 15, 0,
7744 { 8378,-2798,-769,-3068,11410,1877,-538,1792,4623 } },
7745 { "Panasonic DMC-FZ30", 0, 0xf94,
7746 { 10976,-4029,-1141,-7918,15491,2600,-1670,2071,8246 } },
7747 { "Panasonic DMC-FZ3", 15, 0,
7748 { 9938,-2780,-890,-4604,12393,2480,-1117,2304,4620 } },
7749 { "Panasonic DMC-FZ4", 15, 0,
7750 { 13639,-5535,-1371,-1698,9633,2430,316,1152,4108 } },
7751 { "Panasonic DMC-FZ50", 0, 0,
7752 { 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } },
7753 { "Panasonic DMC-FZ7", 15, 0,
7754 { 11532,-4324,-1066,-2375,10847,1749,-564,1699,4351 } },
7755 { "Leica V-LUX1", 0, 0,
7756 { 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } },
7757 { "Panasonic DMC-L10", 15, 0xf96,
7758 { 8025,-1942,-1050,-7920,15904,2100,-2456,3005,7039 } },
7759 { "Panasonic DMC-L1", 0, 0xf7f,
7760 { 8054,-1885,-1025,-8349,16367,2040,-2805,3542,7629 } },
7761 { "Leica DIGILUX 3", 0, 0xf7f,
7762 { 8054,-1885,-1025,-8349,16367,2040,-2805,3542,7629 } },
7763 { "Panasonic DMC-LC1", 0, 0,
7764 { 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } },
7765 { "Leica DIGILUX 2", 0, 0,
7766 { 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } },
7767 { "Panasonic DMC-LX100", 15, 0,
7768 { 8844,-3538,-768,-3709,11762,2200,-698,1792,5220 } },
7769 { "Leica D-LUX (Typ 109)", 15, 0,
7770 { 8844,-3538,-768,-3709,11762,2200,-698,1792,5220 } },
7771 { "Panasonic DMC-LF1", 15, 0,
7772 { 9379,-3267,-816,-3227,11560,1881,-926,1928,5340 } },
7773 { "Leica C (Typ 112)", 15, 0,
7774 { 9379,-3267,-816,-3227,11560,1881,-926,1928,5340 } },
7775 { "Panasonic DMC-LX1", 0, 0xf7f,
7776 { 10704,-4187,-1230,-8314,15952,2501,-920,945,8927 } },
7777 { "Leica D-LUX2", 0, 0xf7f,
7778 { 10704,-4187,-1230,-8314,15952,2501,-920,945,8927 } },
7779 { "Panasonic DMC-LX2", 0, 0,
7780 { 8048,-2810,-623,-6450,13519,3272,-1700,2146,7049 } },
7781 { "Leica D-LUX3", 0, 0,
7782 { 8048,-2810,-623,-6450,13519,3272,-1700,2146,7049 } },
7783 { "Panasonic DMC-LX3", 15, 0,
7784 { 8128,-2668,-655,-6134,13307,3161,-1782,2568,6083 } },
7785 { "Leica D-LUX 4", 15, 0,
7786 { 8128,-2668,-655,-6134,13307,3161,-1782,2568,6083 } },
7787 { "Panasonic DMC-LX5", 15, 0,
7788 { 10909,-4295,-948,-1333,9306,2399,22,1738,4582 } },
7789 { "Leica D-LUX 5", 15, 0,
7790 { 10909,-4295,-948,-1333,9306,2399,22,1738,4582 } },
7791 { "Panasonic DMC-LX7", 15, 0,
7792 { 10148,-3743,-991,-2837,11366,1659,-701,1893,4899 } },
7793 { "Leica D-LUX 6", 15, 0,
7794 { 10148,-3743,-991,-2837,11366,1659,-701,1893,4899 } },
7795 { "Panasonic DMC-FZ1000", 15, 0,
7796 { 7830,-2696,-763,-3325,11667,1866,-641,1712,4824 } },
7797 { "Leica V-LUX (Typ 114)", 15, 0,
7798 { 7830,-2696,-763,-3325,11667,1866,-641,1712,4824 } },
7799 { "Panasonic DMC-FZ100", 15, 0xfff,
7800 { 16197,-6146,-1761,-2393,10765,1869,366,2238,5248 } },
7801 { "Leica V-LUX 2", 15, 0xfff,
7802 { 16197,-6146,-1761,-2393,10765,1869,366,2238,5248 } },
7803 { "Panasonic DMC-FZ150", 15, 0xfff,
7804 { 11904,-4541,-1189,-2355,10899,1662,-296,1586,4289 } },
7805 { "Leica V-LUX 3", 15, 0xfff,
7806 { 11904,-4541,-1189,-2355,10899,1662,-296,1586,4289 } },
7807 { "Panasonic DMC-FZ200", 15, 0xfff,
7808 { 8112,-2563,-740,-3730,11784,2197,-941,2075,4933 } },
7809 { "Leica V-LUX 4", 15, 0xfff,
7810 { 8112,-2563,-740,-3730,11784,2197,-941,2075,4933 } },
7811 { "Panasonic DMC-FX150", 15, 0xfff,
7812 { 9082,-2907,-925,-6119,13377,3058,-1797,2641,5609 } },
7813 { "Panasonic DMC-G10", 0, 0,
7814 { 10113,-3400,-1114,-4765,12683,2317,-377,1437,6710 } },
7815 { "Panasonic DMC-G1", 15, 0xf94,
7816 { 8199,-2065,-1056,-8124,16156,2033,-2458,3022,7220 } },
7817 { "Panasonic DMC-G2", 15, 0xf3c,
7818 { 10113,-3400,-1114,-4765,12683,2317,-377,1437,6710 } },
7819 { "Panasonic DMC-G3", 15, 0xfff,
7820 { 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } },
7821 { "Panasonic DMC-G5", 15, 0xfff,
7822 { 7798,-2562,-740,-3879,11584,2613,-1055,2248,5434 } },
7823 { "Panasonic DMC-G6", 15, 0xfff,
7824 { 8294,-2891,-651,-3869,11590,2595,-1183,2267,5352 } },
7825 { "Panasonic DMC-G7", 15, 0xfff,
7826 { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } },
7827 { "Panasonic DMC-GF1", 15, 0xf92,
7828 { 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } },
7829 { "Panasonic DMC-GF2", 15, 0xfff,
7830 { 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } },
7831 { "Panasonic DMC-GF3", 15, 0xfff,
7832 { 9051,-2468,-1204,-5212,13276,2121,-1197,2510,6890 } },
7833 { "Panasonic DMC-GF5", 15, 0xfff,
7834 { 8228,-2945,-660,-3938,11792,2430,-1094,2278,5793 } },
7835 { "Panasonic DMC-GF6", 15, 0,
7836 { 8130,-2801,-946,-3520,11289,2552,-1314,2511,5791 } },
7837 { "Panasonic DMC-GF7", 15, 0,
7838 { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } },
7839 { "Panasonic DMC-GF8", 15, 0,
7840 { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } },
7841 { "Panasonic DMC-GH1", 15, 0xf92,
7842 { 6299,-1466,-532,-6535,13852,2969,-2331,3112,5984 } },
7843 { "Panasonic DMC-GH2", 15, 0xf95,
7844 { 7780,-2410,-806,-3913,11724,2484,-1018,2390,5298 } },
7845 { "Panasonic DMC-GH3", 15, 0,
7846 { 6559,-1752,-491,-3672,11407,2586,-962,1875,5130 } },
7847 { "Panasonic DMC-GH4", 15, 0,
7848 { 7122,-2108,-512,-3155,11201,2231,-541,1423,5045 } },
7849 { "Panasonic DMC-GM1", 15, 0,
7850 { 6770,-1895,-744,-5232,13145,2303,-1664,2691,5703 } },
7851 { "Panasonic DMC-GM5", 15, 0,
7852 { 8238,-3244,-679,-3921,11814,2384,-836,2022,5852 } },
7853 { "Panasonic DMC-GX1", 15, 0,
7854 { 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } },
7855 { "Panasonic DMC-GX7", 15, 0,
7856 { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } },
7857 { "Panasonic DMC-GX8", 15, 0,
7858 { 7564,-2263,-606,-3148,11239,2177,-540,1435,4853 } },
7859 { "Panasonic DMC-TZ1", 15, 0,
7860 { 7790,-2736,-755,-3452,11870,1769,-628,1647,4898 } },
7861 { "Panasonic DMC-ZS1", 15, 0,
7862 { 7790,-2736,-755,-3452,11870,1769,-628,1647,4898 } },
7863 { "Panasonic DMC-TZ6", 15, 0,
7864 { 8607,-2822,-808,-3755,11930,2049,-820,2060,5224 } },
7865 { "Panasonic DMC-ZS4", 15, 0,
7866 { 8607,-2822,-808,-3755,11930,2049,-820,2060,5224 } },
7867 { "Panasonic DMC-TZ7", 15, 0,
7868 { 8802,-3135,-789,-3151,11468,1904,-550,1745,4810 } },
7869 { "Panasonic DMC-ZS5", 15, 0,
7870 { 8802,-3135,-789,-3151,11468,1904,-550,1745,4810 } },
7871 { "Panasonic DMC-TZ8", 15, 0,
7872 { 8550,-2908,-842,-3195,11529,1881,-338,1603,4631 } },
7873 { "Panasonic DMC-ZS6", 15, 0,
7874 { 8550,-2908,-842,-3195,11529,1881,-338,1603,4631 } },
7875 { "Leica S (Typ 007)", 0, 0,
7876 { 6063,-2234,-231,-5210,13787,1500,-1043,2866,6997 } },
7877 { "Leica X", 0, 0, /* X and X-U, both (Typ 113) */
7878 { 7712,-2059,-653,-3882,11494,2726,-710,1332,5958 } },
7879 { "Leica Q (Typ 116)", 0, 0,
7880 { 11865,-4523,-1441,-5423,14458,935,-1587,2687,4830 } },
7881 { "Leica M (Typ 262)", 0, 0,
7882 { 6653,-1486,-611,-4221,13303,929,-881,2416,7226 } },
7883 { "Leica SL (Typ 601)", 0, 0,
7884 { 11865,-4523,-1441,-5423,14458,935,-1587,2687,4830} },
7885 { "Phase One H 20", 0, 0, /* DJC */
7886 { 1313,1855,-109,-6715,15908,808,-327,1840,6020 } },
7887 { "Phase One H 25", 0, 0,
7888 { 2905,732,-237,-8134,16626,1476,-3038,4253,7517 } },
7889 { "Phase One P 2", 0, 0,
7890 { 2905,732,-237,-8134,16626,1476,-3038,4253,7517 } },
7891 { "Phase One P 30", 0, 0,
7892 { 4516,-245,-37,-7020,14976,2173,-3206,4671,7087 } },
7893 { "Phase One P 45", 0, 0,
7894 { 5053,-24,-117,-5684,14076,1702,-2619,4492,5849 } },
7895 { "Phase One P40", 0, 0,
7896 { 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } },
7897 { "Phase One P65", 0, 0,
7898 { 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } },
7899 { "Photron BC2-HD", 0, 0, /* DJC */
7900 { 14603,-4122,-528,-1810,9794,2017,-297,2763,5936 } },
7901 { "Red One", 704, 0xffff, /* DJC */
7902 { 21014,-7891,-2613,-3056,12201,856,-2203,5125,8042 } },
7903 { "Ricoh GR II", 0, 0,
7904 { 4630,-834,-423,-4977,12805,2417,-638,1467,6115 } },
7906 { 3708,-543,-160,-5381,12254,3556,-1471,1929,8234 } },
7907 { "Samsung EX1", 0, 0x3e00,
7908 { 8898,-2498,-994,-3144,11328,2066,-760,1381,4576 } },
7909 { "Samsung EX2F", 0, 0x7ff,
7910 { 10648,-3897,-1055,-2022,10573,1668,-492,1611,4742 } },
7911 { "Samsung EK-GN120", 0, 0,
7912 { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } },
7913 { "Samsung NX mini", 0, 0,
7914 { 5222,-1196,-550,-6540,14649,2009,-1666,2819,5657 } },
7915 { "Samsung NX3300", 0, 0,
7916 { 8060,-2933,-761,-4504,12890,1762,-630,1489,5227 } },
7917 { "Samsung NX3000", 0, 0,
7918 { 8060,-2933,-761,-4504,12890,1762,-630,1489,5227 } },
7919 { "Samsung NX30", 0, 0, /* NX30, NX300, NX300M */
7920 { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } },
7921 { "Samsung NX2000", 0, 0,
7922 { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } },
7923 { "Samsung NX2", 0, 0xfff, /* NX20, NX200, NX210 */
7924 { 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } },
7925 { "Samsung NX1000", 0, 0,
7926 { 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } },
7927 { "Samsung NX1100", 0, 0,
7928 { 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } },
7929 { "Samsung NX11", 0, 0,
7930 { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } },
7931 { "Samsung NX10", 0, 0, /* also NX100 */
7932 { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } },
7933 { "Samsung NX500", 0, 0,
7934 { 10686,-4042,-1052,-3595,13238,276,-464,1259,5931 } },
7935 { "Samsung NX5", 0, 0,
7936 { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } },
7937 { "Samsung NX1", 0, 0,
7938 { 10686,-4042,-1052,-3595,13238,276,-464,1259,5931 } },
7939 { "Samsung WB2000", 0, 0xfff,
7940 { 12093,-3557,-1155,-1000,9534,1733,-22,1787,4576 } },
7941 { "Samsung GX-1", 0, 0,
7942 { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
7943 { "Samsung GX20", 0, 0, /* copied from Pentax K20D */
7944 { 9427,-2714,-868,-7493,16092,1373,-2199,3264,7180 } },
7945 { "Samsung S85", 0, 0, /* DJC */
7946 { 11885,-3968,-1473,-4214,12299,1916,-835,1655,5549 } },
7947 { "Sinar", 0, 0, /* DJC */
7948 { 16442,-2956,-2422,-2877,12128,750,-1136,6066,4559 } },
7949 { "Sony DSC-F828", 0, 0,
7950 { 7924,-1910,-777,-8226,15459,2998,-1517,2199,6818,-7242,11401,3481 } },
7951 { "Sony DSC-R1", 0, 0,
7952 { 8512,-2641,-694,-8042,15670,2526,-1821,2117,7414 } },
7953 { "Sony DSC-V3", 0, 0,
7954 { 7511,-2571,-692,-7894,15088,3060,-948,1111,8128 } },
7955 { "Sony DSC-RX100M", 0, 0, /* M2, M3, and M4 */
7956 { 6596,-2079,-562,-4782,13016,1933,-970,1581,5181 } },
7957 { "Sony DSC-RX100", 0, 0,
7958 { 8651,-2754,-1057,-3464,12207,1373,-568,1398,4434 } },
7959 { "Sony DSC-RX10", 0, 0, /* also RX10M2 */
7960 { 6679,-1825,-745,-5047,13256,1953,-1580,2422,5183 } },
7961 { "Sony DSC-RX1RM2", 0, 0,
7962 { 6629,-1900,-483,-4618,12349,2550,-622,1381,6514 } },
7963 { "Sony DSC-RX1", 0, 0,
7964 { 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } },
7965 { "Sony DSLR-A100", 0, 0xfeb,
7966 { 9437,-2811,-774,-8405,16215,2290,-710,596,7181 } },
7967 { "Sony DSLR-A290", 0, 0,
7968 { 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } },
7969 { "Sony DSLR-A2", 0, 0,
7970 { 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } },
7971 { "Sony DSLR-A300", 0, 0,
7972 { 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } },
7973 { "Sony DSLR-A330", 0, 0,
7974 { 9847,-3091,-929,-8485,16346,2225,-714,595,7103 } },
7975 { "Sony DSLR-A350", 0, 0xffc,
7976 { 6038,-1484,-578,-9146,16746,2513,-875,746,7217 } },
7977 { "Sony DSLR-A380", 0, 0,
7978 { 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } },
7979 { "Sony DSLR-A390", 0, 0,
7980 { 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } },
7981 { "Sony DSLR-A450", 0, 0xfeb,
7982 { 4950,-580,-103,-5228,12542,3029,-709,1435,7371 } },
7983 { "Sony DSLR-A580", 0, 0xfeb,
7984 { 5932,-1492,-411,-4813,12285,2856,-741,1524,6739 } },
7985 { "Sony DSLR-A500", 0, 0xfeb,
7986 { 6046,-1127,-278,-5574,13076,2786,-691,1419,7625 } },
7987 { "Sony DSLR-A5", 0, 0xfeb,
7988 { 4950,-580,-103,-5228,12542,3029,-709,1435,7371 } },
7989 { "Sony DSLR-A700", 0, 0,
7990 { 5775,-805,-359,-8574,16295,2391,-1943,2341,7249 } },
7991 { "Sony DSLR-A850", 0, 0,
7992 { 5413,-1162,-365,-5665,13098,2866,-608,1179,8440 } },
7993 { "Sony DSLR-A900", 0, 0,
7994 { 5209,-1072,-397,-8845,16120,2919,-1618,1803,8654 } },
7995 { "Sony ILCA-68", 0, 0,
7996 { 6435,-1903,-536,-4722,12449,2550,-663,1363,6517 } },
7997 { "Sony ILCA-77M2", 0, 0,
7998 { 5991,-1732,-443,-4100,11989,2381,-704,1467,5992 } },
7999 { "Sony ILCE-6300", 0, 0,
8000 { 5973,-1695,-419,-3826,11797,2293,-639,1398,5789 } },
8001 { "Sony ILCE-7M2", 0, 0,
8002 { 5271,-712,-347,-6153,13653,2763,-1601,2366,7242 } },
8003 { "Sony ILCE-7S", 0, 0, /* also ILCE-7SM2 */
8004 { 5838,-1430,-246,-3497,11477,2297,-748,1885,5778 } },
8005 { "Sony ILCE-7RM2", 0, 0,
8006 { 6629,-1900,-483,-4618,12349,2550,-622,1381,6514 } },
8007 { "Sony ILCE-7R", 0, 0,
8008 { 4913,-541,-202,-6130,13513,2906,-1564,2151,7183 } },
8009 { "Sony ILCE-7", 0, 0,
8010 { 5271,-712,-347,-6153,13653,2763,-1601,2366,7242 } },
8011 { "Sony ILCE", 0, 0, /* 3000, 5000, 5100, 6000, and QX1 */
8012 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
8013 { "Sony NEX-5N", 0, 0,
8014 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
8015 { "Sony NEX-5R", 0, 0,
8016 { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } },
8017 { "Sony NEX-5T", 0, 0,
8018 { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } },
8019 { "Sony NEX-3N", 0, 0,
8020 { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } },
8021 { "Sony NEX-3", 138, 0, /* DJC */
8022 { 6907,-1256,-645,-4940,12621,2320,-1710,2581,6230 } },
8023 { "Sony NEX-5", 116, 0, /* DJC */
8024 { 6807,-1350,-342,-4216,11649,2567,-1089,2001,6420 } },
8025 { "Sony NEX-3", 0, 0, /* Adobe */
8026 { 6549,-1550,-436,-4880,12435,2753,-854,1868,6976 } },
8027 { "Sony NEX-5", 0, 0, /* Adobe */
8028 { 6549,-1550,-436,-4880,12435,2753,-854,1868,6976 } },
8029 { "Sony NEX-6", 0, 0,
8030 { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } },
8031 { "Sony NEX-7", 0, 0,
8032 { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } },
8033 { "Sony NEX", 0, 0, /* NEX-C3, NEX-F3 */
8034 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
8035 { "Sony SLT-A33", 0, 0,
8036 { 6069,-1221,-366,-5221,12779,2734,-1024,2066,6834 } },
8037 { "Sony SLT-A35", 0, 0,
8038 { 5986,-1618,-415,-4557,11820,3120,-681,1404,6971 } },
8039 { "Sony SLT-A37", 0, 0,
8040 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
8041 { "Sony SLT-A55", 0, 0,
8042 { 5932,-1492,-411,-4813,12285,2856,-741,1524,6739 } },
8043 { "Sony SLT-A57", 0, 0,
8044 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
8045 { "Sony SLT-A58", 0, 0,
8046 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
8047 { "Sony SLT-A65", 0, 0,
8048 { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } },
8049 { "Sony SLT-A77", 0, 0,
8050 { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } },
8051 { "Sony SLT-A99", 0, 0,
8052 { 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } },
8054 double cam_xyz[4][3];
8058 sprintf (name, "%s %s", make, model);
8059 for (i=0; i < sizeof table / sizeof *table; i++)
8060 if (!strncmp (name, table[i].prefix, strlen(table[i].prefix))) {
8061 if (table[i].black) black = (ushort) table[i].black;
8062 if (table[i].maximum) maximum = (ushort) table[i].maximum;
8063 if (table[i].trans[0]) {
8064 for (raw_color = j=0; j < 12; j++)
8065 ((double *)cam_xyz)[j] = table[i].trans[j] / 10000.0;
8066 cam_xyz_coeff (rgb_cam, cam_xyz);
8072 void CLASS simple_coeff (int index)
8074 static const float table[][12] = {
8075 /* index 0 -- all Foveon cameras */
8076 { 1.4032,-0.2231,-0.1016,-0.5263,1.4816,0.017,-0.0112,0.0183,0.9113 },
8077 /* index 1 -- Kodak DC20 and DC25 */
8078 { 2.25,0.75,-1.75,-0.25,-0.25,0.75,0.75,-0.25,-0.25,-1.75,0.75,2.25 },
8079 /* index 2 -- Logitech Fotoman Pixtura */
8080 { 1.893,-0.418,-0.476,-0.495,1.773,-0.278,-1.017,-0.655,2.672 },
8081 /* index 3 -- Nikon E880, E900, and E990 */
8082 { -1.936280, 1.800443, -1.448486, 2.584324,
8083 1.405365, -0.524955, -0.289090, 0.408680,
8084 -1.204965, 1.082304, 2.941367, -1.818705 }
8088 for (raw_color = i=0; i < 3; i++)
8089 FORCC rgb_cam[i][c] = table[index][i*colors+c];
8092 short CLASS guess_byte_order (int words)
8096 double diff, sum[2] = {0,0};
8098 fread (test[0], 2, 2, ifp);
8099 for (words-=2; words--; ) {
8100 fread (test[t], 2, 1, ifp);
8101 for (msb=0; msb < 2; msb++) {
8102 diff = (test[t^2][msb] << 8 | test[t^2][!msb])
8103 - (test[t ][msb] << 8 | test[t ][!msb]);
8104 sum[msb] += diff*diff;
8108 return sum[0] < sum[1] ? 0x4d4d : 0x4949;
8111 float CLASS find_green (int bps, int bite, int off0, int off1)
8114 int vbits, col, i, c;
8115 ushort img[2][2064];
8119 fseek (ifp, c ? off1:off0, SEEK_SET);
8120 for (vbits=col=0; col < width; col++) {
8121 for (vbits -= bps; vbits < 0; vbits += bite) {
8123 for (i=0; i < bite; i+=8)
8124 bitbuf |= (unsigned) (fgetc(ifp) << i);
8126 img[c][col] = bitbuf << (64-bps-vbits) >> (64-bps);
8130 sum[ c & 1] += ABS(img[0][c]-img[1][c+1]);
8131 sum[~c & 1] += ABS(img[1][c]-img[0][c+1]);
8133 return 100 * log(sum[0]/sum[1]);
8137 Identify which camera created this file, and set global variables
8140 void CLASS identify()
8142 static const short pana[][6] = {
8143 { 3130, 1743, 4, 0, -6, 0 },
8144 { 3130, 2055, 4, 0, -6, 0 },
8145 { 3130, 2319, 4, 0, -6, 0 },
8146 { 3170, 2103, 18, 0,-42, 20 },
8147 { 3170, 2367, 18, 13,-42,-21 },
8148 { 3177, 2367, 0, 0, -1, 0 },
8149 { 3304, 2458, 0, 0, -1, 0 },
8150 { 3330, 2463, 9, 0, -5, 0 },
8151 { 3330, 2479, 9, 0,-17, 4 },
8152 { 3370, 1899, 15, 0,-44, 20 },
8153 { 3370, 2235, 15, 0,-44, 20 },
8154 { 3370, 2511, 15, 10,-44,-21 },
8155 { 3690, 2751, 3, 0, -8, -3 },
8156 { 3710, 2751, 0, 0, -3, 0 },
8157 { 3724, 2450, 0, 0, 0, -2 },
8158 { 3770, 2487, 17, 0,-44, 19 },
8159 { 3770, 2799, 17, 15,-44,-19 },
8160 { 3880, 2170, 6, 0, -6, 0 },
8161 { 4060, 3018, 0, 0, 0, -2 },
8162 { 4290, 2391, 3, 0, -8, -1 },
8163 { 4330, 2439, 17, 15,-44,-19 },
8164 { 4508, 2962, 0, 0, -3, -4 },
8165 { 4508, 3330, 0, 0, -3, -6 },
8167 static const ushort canon[][11] = {
8168 { 1944, 1416, 0, 0, 48, 0 },
8169 { 2144, 1560, 4, 8, 52, 2, 0, 0, 0, 25 },
8170 { 2224, 1456, 48, 6, 0, 2 },
8171 { 2376, 1728, 12, 6, 52, 2 },
8172 { 2672, 1968, 12, 6, 44, 2 },
8173 { 3152, 2068, 64, 12, 0, 0, 16 },
8174 { 3160, 2344, 44, 12, 4, 4 },
8175 { 3344, 2484, 4, 6, 52, 6 },
8176 { 3516, 2328, 42, 14, 0, 0 },
8177 { 3596, 2360, 74, 12, 0, 0 },
8178 { 3744, 2784, 52, 12, 8, 12 },
8179 { 3944, 2622, 30, 18, 6, 2 },
8180 { 3948, 2622, 42, 18, 0, 2 },
8181 { 3984, 2622, 76, 20, 0, 2, 14 },
8182 { 4104, 3048, 48, 12, 24, 12 },
8183 { 4116, 2178, 4, 2, 0, 0 },
8184 { 4152, 2772, 192, 12, 0, 0 },
8185 { 4160, 3124, 104, 11, 8, 65 },
8186 { 4176, 3062, 96, 17, 8, 0, 0, 16, 0, 7, 0x49 },
8187 { 4192, 3062, 96, 17, 24, 0, 0, 16, 0, 0, 0x49 },
8188 { 4312, 2876, 22, 18, 0, 2 },
8189 { 4352, 2874, 62, 18, 0, 0 },
8190 { 4476, 2954, 90, 34, 0, 0 },
8191 { 4480, 3348, 12, 10, 36, 12, 0, 0, 0, 18, 0x49 },
8192 { 4480, 3366, 80, 50, 0, 0 },
8193 { 4496, 3366, 80, 50, 12, 0 },
8194 { 4768, 3516, 96, 16, 0, 0, 0, 16 },
8195 { 4832, 3204, 62, 26, 0, 0 },
8196 { 4832, 3228, 62, 51, 0, 0 },
8197 { 5108, 3349, 98, 13, 0, 0 },
8198 { 5120, 3318, 142, 45, 62, 0 },
8199 { 5280, 3528, 72, 52, 0, 0 },
8200 { 5344, 3516, 142, 51, 0, 0 },
8201 { 5344, 3584, 126,100, 0, 2 },
8202 { 5360, 3516, 158, 51, 0, 0 },
8203 { 5568, 3708, 72, 38, 0, 0 },
8204 { 5632, 3710, 96, 17, 0, 0, 0, 16, 0, 0, 0x49 },
8205 { 5712, 3774, 62, 20, 10, 2 },
8206 { 5792, 3804, 158, 51, 0, 0 },
8207 { 5920, 3950, 122, 80, 2, 0 },
8208 { 6096, 4056, 72, 34, 0, 0 },
8209 { 6288, 4056, 264, 34, 0, 0 },
8210 { 8896, 5920, 160, 64, 0, 0 },
8212 static const struct {
8216 { 0x168, "EOS 10D" }, { 0x001, "EOS-1D" },
8217 { 0x175, "EOS 20D" }, { 0x174, "EOS-1D Mark II" },
8218 { 0x234, "EOS 30D" }, { 0x232, "EOS-1D Mark II N" },
8219 { 0x190, "EOS 40D" }, { 0x169, "EOS-1D Mark III" },
8220 { 0x261, "EOS 50D" }, { 0x281, "EOS-1D Mark IV" },
8221 { 0x287, "EOS 60D" }, { 0x167, "EOS-1DS" },
8222 { 0x325, "EOS 70D" },
8223 { 0x350, "EOS 80D" }, { 0x328, "EOS-1D X Mark II" },
8224 { 0x170, "EOS 300D" }, { 0x188, "EOS-1Ds Mark II" },
8225 { 0x176, "EOS 450D" }, { 0x215, "EOS-1Ds Mark III" },
8226 { 0x189, "EOS 350D" }, { 0x324, "EOS-1D C" },
8227 { 0x236, "EOS 400D" }, { 0x269, "EOS-1D X" },
8228 { 0x252, "EOS 500D" }, { 0x213, "EOS 5D" },
8229 { 0x270, "EOS 550D" }, { 0x218, "EOS 5D Mark II" },
8230 { 0x286, "EOS 600D" }, { 0x285, "EOS 5D Mark III" },
8231 { 0x301, "EOS 650D" }, { 0x302, "EOS 6D" },
8232 { 0x326, "EOS 700D" }, { 0x250, "EOS 7D" },
8233 { 0x393, "EOS 750D" }, { 0x289, "EOS 7D Mark II" },
8234 { 0x347, "EOS 760D" },
8235 { 0x254, "EOS 1000D" },
8236 { 0x288, "EOS 1100D" },
8237 { 0x327, "EOS 1200D" }, { 0x382, "Canon EOS 5DS" },
8238 { 0x404, "EOS 1300D" }, { 0x401, "Canon EOS 5DS R" },
8239 { 0x346, "EOS 100D" },
8241 { 0x002, "DSC-R1" }, { 0x100, "DSLR-A100" },
8242 { 0x101, "DSLR-A900" }, { 0x102, "DSLR-A700" },
8243 { 0x103, "DSLR-A200" }, { 0x104, "DSLR-A350" },
8244 { 0x105, "DSLR-A300" }, { 0x108, "DSLR-A330" },
8245 { 0x109, "DSLR-A230" }, { 0x10a, "DSLR-A290" },
8246 { 0x10d, "DSLR-A850" }, { 0x111, "DSLR-A550" },
8247 { 0x112, "DSLR-A500" }, { 0x113, "DSLR-A450" },
8248 { 0x116, "NEX-5" }, { 0x117, "NEX-3" },
8249 { 0x118, "SLT-A33" }, { 0x119, "SLT-A55V" },
8250 { 0x11a, "DSLR-A560" }, { 0x11b, "DSLR-A580" },
8251 { 0x11c, "NEX-C3" }, { 0x11d, "SLT-A35" },
8252 { 0x11e, "SLT-A65V" }, { 0x11f, "SLT-A77V" },
8253 { 0x120, "NEX-5N" }, { 0x121, "NEX-7" },
8254 { 0x123, "SLT-A37" }, { 0x124, "SLT-A57" },
8255 { 0x125, "NEX-F3" }, { 0x126, "SLT-A99V" },
8256 { 0x127, "NEX-6" }, { 0x128, "NEX-5R" },
8257 { 0x129, "DSC-RX100" }, { 0x12a, "DSC-RX1" },
8258 { 0x12e, "ILCE-3000" }, { 0x12f, "SLT-A58" },
8259 { 0x131, "NEX-3N" }, { 0x132, "ILCE-7" },
8260 { 0x133, "NEX-5T" }, { 0x134, "DSC-RX100M2" },
8261 { 0x135, "DSC-RX10" }, { 0x136, "DSC-RX1R" },
8262 { 0x137, "ILCE-7R" }, { 0x138, "ILCE-6000" },
8263 { 0x139, "ILCE-5000" }, { 0x13d, "DSC-RX100M3" },
8264 { 0x13e, "ILCE-7S" }, { 0x13f, "ILCA-77M2" },
8265 { 0x153, "ILCE-5100" }, { 0x154, "ILCE-7M2" },
8266 { 0x155, "DSC-RX100M4" },{ 0x156, "DSC-RX10M2" },
8267 { 0x158, "DSC-RX1RM2" }, { 0x15a, "ILCE-QX1" },
8268 { 0x15b, "ILCE-7RM2" }, { 0x15e, "ILCE-7SM2" },
8269 { 0x161, "ILCA-68" }, { 0x165, "ILCE-6300" },
8271 static const struct {
8274 uchar lm, tm, rm, bm, lf, cf, max, flags;
8275 char make[10], model[20];
8278 { 786432,1024, 768, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-080C" },
8279 { 1447680,1392,1040, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-145C" },
8280 { 1920000,1600,1200, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-201C" },
8281 { 5067304,2588,1958, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-510C" },
8282 { 5067316,2588,1958, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-510C",12 },
8283 { 10134608,2588,1958, 0, 0, 0, 0, 9,0x94,0,0,"AVT","F-510C" },
8284 { 10134620,2588,1958, 0, 0, 0, 0, 9,0x94,0,0,"AVT","F-510C",12 },
8285 { 16157136,3272,2469, 0, 0, 0, 0, 9,0x94,0,0,"AVT","F-810C" },
8286 { 15980544,3264,2448, 0, 0, 0, 0, 8,0x61,0,1,"AgfaPhoto","DC-833m" },
8287 { 9631728,2532,1902, 0, 0, 0, 0,96,0x61,0,0,"Alcatel","5035D" },
8288 { 2868726,1384,1036, 0, 0, 0, 0,64,0x49,0,8,"Baumer","TXG14",1078 },
8289 { 5298000,2400,1766,12,12,44, 2,40,0x94,0,2,"Canon","PowerShot SD300" },
8290 { 6553440,2664,1968, 4, 4,44, 4,40,0x94,0,2,"Canon","PowerShot A460" },
8291 { 6573120,2672,1968,12, 8,44, 0,40,0x94,0,2,"Canon","PowerShot A610" },
8292 { 6653280,2672,1992,10, 6,42, 2,40,0x94,0,2,"Canon","PowerShot A530" },
8293 { 7710960,2888,2136,44, 8, 4, 0,40,0x94,0,2,"Canon","PowerShot S3 IS" },
8294 { 9219600,3152,2340,36,12, 4, 0,40,0x94,0,2,"Canon","PowerShot A620" },
8295 { 9243240,3152,2346,12, 7,44,13,40,0x49,0,2,"Canon","PowerShot A470" },
8296 { 10341600,3336,2480, 6, 5,32, 3,40,0x94,0,2,"Canon","PowerShot A720 IS" },
8297 { 10383120,3344,2484,12, 6,44, 6,40,0x94,0,2,"Canon","PowerShot A630" },
8298 { 12945240,3736,2772,12, 6,52, 6,40,0x94,0,2,"Canon","PowerShot A640" },
8299 { 15636240,4104,3048,48,12,24,12,40,0x94,0,2,"Canon","PowerShot A650" },
8300 { 15467760,3720,2772, 6,12,30, 0,40,0x94,0,2,"Canon","PowerShot SX110 IS" },
8301 { 15534576,3728,2778,12, 9,44, 9,40,0x94,0,2,"Canon","PowerShot SX120 IS" },
8302 { 18653760,4080,3048,24,12,24,12,40,0x94,0,2,"Canon","PowerShot SX20 IS" },
8303 { 19131120,4168,3060,92,16, 4, 1,40,0x94,0,2,"Canon","PowerShot SX220 HS" },
8304 { 21936096,4464,3276,25,10,73,12,40,0x16,0,2,"Canon","PowerShot SX30 IS" },
8305 { 24724224,4704,3504, 8,16,56, 8,40,0x94,0,2,"Canon","PowerShot A3300 IS" },
8306 { 30858240,5248,3920, 8,16,56,16,40,0x94,0,2,"Canon","IXUS 160" },
8307 { 1976352,1632,1211, 0, 2, 0, 1, 0,0x94,0,1,"Casio","QV-2000UX" },
8308 { 3217760,2080,1547, 0, 0,10, 1, 0,0x94,0,1,"Casio","QV-3*00EX" },
8309 { 6218368,2585,1924, 0, 0, 9, 0, 0,0x94,0,1,"Casio","QV-5700" },
8310 { 7816704,2867,2181, 0, 0,34,36, 0,0x16,0,1,"Casio","EX-Z60" },
8311 { 2937856,1621,1208, 0, 0, 1, 0, 0,0x94,7,13,"Casio","EX-S20" },
8312 { 4948608,2090,1578, 0, 0,32,34, 0,0x94,7,1,"Casio","EX-S100" },
8313 { 6054400,2346,1720, 2, 0,32, 0, 0,0x94,7,1,"Casio","QV-R41" },
8314 { 7426656,2568,1928, 0, 0, 0, 0, 0,0x94,0,1,"Casio","EX-P505" },
8315 { 7530816,2602,1929, 0, 0,22, 0, 0,0x94,7,1,"Casio","QV-R51" },
8316 { 7542528,2602,1932, 0, 0,32, 0, 0,0x94,7,1,"Casio","EX-Z50" },
8317 { 7562048,2602,1937, 0, 0,25, 0, 0,0x16,7,1,"Casio","EX-Z500" },
8318 { 7753344,2602,1986, 0, 0,32,26, 0,0x94,7,1,"Casio","EX-Z55" },
8319 { 9313536,2858,2172, 0, 0,14,30, 0,0x94,7,1,"Casio","EX-P600" },
8320 { 10834368,3114,2319, 0, 0,27, 0, 0,0x94,0,1,"Casio","EX-Z750" },
8321 { 10843712,3114,2321, 0, 0,25, 0, 0,0x94,0,1,"Casio","EX-Z75" },
8322 { 10979200,3114,2350, 0, 0,32,32, 0,0x94,7,1,"Casio","EX-P700" },
8323 { 12310144,3285,2498, 0, 0, 6,30, 0,0x94,0,1,"Casio","EX-Z850" },
8324 { 12489984,3328,2502, 0, 0,47,35, 0,0x94,0,1,"Casio","EX-Z8" },
8325 { 15499264,3754,2752, 0, 0,82, 0, 0,0x94,0,1,"Casio","EX-Z1050" },
8326 { 18702336,4096,3044, 0, 0,24, 0,80,0x94,7,1,"Casio","EX-ZR100" },
8327 { 7684000,2260,1700, 0, 0, 0, 0,13,0x94,0,1,"Casio","QV-4000" },
8328 { 787456,1024, 769, 0, 1, 0, 0, 0,0x49,0,0,"Creative","PC-CAM 600" },
8329 { 28829184,4384,3288, 0, 0, 0, 0,36,0x61,0,0,"DJI" },
8330 { 15151104,4608,3288, 0, 0, 0, 0, 0,0x94,0,0,"Matrix" },
8331 { 3840000,1600,1200, 0, 0, 0, 0,65,0x49,0,0,"Foculus","531C" },
8332 { 307200, 640, 480, 0, 0, 0, 0, 0,0x94,0,0,"Generic" },
8333 { 62464, 256, 244, 1, 1, 6, 1, 0,0x8d,0,0,"Kodak","DC20" },
8334 { 124928, 512, 244, 1, 1,10, 1, 0,0x8d,0,0,"Kodak","DC20" },
8335 { 1652736,1536,1076, 0,52, 0, 0, 0,0x61,0,0,"Kodak","DCS200" },
8336 { 4159302,2338,1779, 1,33, 1, 2, 0,0x94,0,0,"Kodak","C330" },
8337 { 4162462,2338,1779, 1,33, 1, 2, 0,0x94,0,0,"Kodak","C330",3160 },
8338 { 2247168,1232, 912, 0, 0,16, 0, 0,0x00,0,0,"Kodak","C330" },
8339 { 3370752,1232, 912, 0, 0,16, 0, 0,0x00,0,0,"Kodak","C330" },
8340 { 6163328,2864,2152, 0, 0, 0, 0, 0,0x94,0,0,"Kodak","C603" },
8341 { 6166488,2864,2152, 0, 0, 0, 0, 0,0x94,0,0,"Kodak","C603",3160 },
8342 { 460800, 640, 480, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","C603" },
8343 { 9116448,2848,2134, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","C603" },
8344 { 12241200,4040,3030, 2, 0, 0,13, 0,0x49,0,0,"Kodak","12MP" },
8345 { 12272756,4040,3030, 2, 0, 0,13, 0,0x49,0,0,"Kodak","12MP",31556 },
8346 { 18000000,4000,3000, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","12MP" },
8347 { 614400, 640, 480, 0, 3, 0, 0,64,0x94,0,0,"Kodak","KAI-0340" },
8348 { 15360000,3200,2400, 0, 0, 0, 0,96,0x16,0,0,"Lenovo","A820" },
8349 { 3884928,1608,1207, 0, 0, 0, 0,96,0x16,0,0,"Micron","2010",3212 },
8350 { 1138688,1534, 986, 0, 0, 0, 0, 0,0x61,0,0,"Minolta","RD175",513 },
8351 { 1581060,1305, 969, 0, 0,18, 6, 6,0x1e,4,1,"Nikon","E900" },
8352 { 2465792,1638,1204, 0, 0,22, 1, 6,0x4b,5,1,"Nikon","E950" },
8353 { 2940928,1616,1213, 0, 0, 0, 7,30,0x94,0,1,"Nikon","E2100" },
8354 { 4771840,2064,1541, 0, 0, 0, 1, 6,0xe1,0,1,"Nikon","E990" },
8355 { 4775936,2064,1542, 0, 0, 0, 0,30,0x94,0,1,"Nikon","E3700" },
8356 { 5865472,2288,1709, 0, 0, 0, 1, 6,0xb4,0,1,"Nikon","E4500" },
8357 { 5869568,2288,1710, 0, 0, 0, 0, 6,0x16,0,1,"Nikon","E4300" },
8358 { 7438336,2576,1925, 0, 0, 0, 1, 6,0xb4,0,1,"Nikon","E5000" },
8359 { 8998912,2832,2118, 0, 0, 0, 0,30,0x94,7,1,"Nikon","COOLPIX S6" },
8360 { 5939200,2304,1718, 0, 0, 0, 0,30,0x16,0,0,"Olympus","C770UZ" },
8361 { 3178560,2064,1540, 0, 0, 0, 0, 0,0x94,0,1,"Pentax","Optio S" },
8362 { 4841984,2090,1544, 0, 0,22, 0, 0,0x94,7,1,"Pentax","Optio S" },
8363 { 6114240,2346,1737, 0, 0,22, 0, 0,0x94,7,1,"Pentax","Optio S4" },
8364 { 10702848,3072,2322, 0, 0, 0,21,30,0x94,0,1,"Pentax","Optio 750Z" },
8365 { 4147200,1920,1080, 0, 0, 0, 0, 0,0x49,0,0,"Photron","BC2-HD" },
8366 { 4151666,1920,1080, 0, 0, 0, 0, 0,0x49,0,0,"Photron","BC2-HD",8 },
8367 { 13248000,2208,3000, 0, 0, 0, 0,13,0x61,0,0,"Pixelink","A782" },
8368 { 6291456,2048,1536, 0, 0, 0, 0,96,0x61,0,0,"RoverShot","3320AF" },
8369 { 311696, 644, 484, 0, 0, 0, 0, 0,0x16,0,8,"ST Micro","STV680 VGA" },
8370 { 16098048,3288,2448, 0, 0,24, 0, 9,0x94,0,1,"Samsung","S85" },
8371 { 16215552,3312,2448, 0, 0,48, 0, 9,0x94,0,1,"Samsung","S85" },
8372 { 20487168,3648,2808, 0, 0, 0, 0,13,0x94,5,1,"Samsung","WB550" },
8373 { 24000000,4000,3000, 0, 0, 0, 0,13,0x94,5,1,"Samsung","WB550" },
8374 { 12582980,3072,2048, 0, 0, 0, 0,33,0x61,0,0,"Sinar","",68 },
8375 { 33292868,4080,4080, 0, 0, 0, 0,33,0x61,0,0,"Sinar","",68 },
8376 { 44390468,4080,5440, 0, 0, 0, 0,33,0x61,0,0,"Sinar","",68 },
8377 { 1409024,1376,1024, 0, 0, 1, 0, 0,0x49,0,0,"Sony","XCD-SX910CR" },
8378 { 2818048,1376,1024, 0, 0, 1, 0,97,0x49,0,0,"Sony","XCD-SX910CR" },
8380 static const char *corp[] =
8381 { "AgfaPhoto", "Canon", "Casio", "Epson", "Fujifilm",
8382 "Mamiya", "Minolta", "Motorola", "Kodak", "Konica", "Leica",
8383 "Nikon", "Nokia", "Olympus", "Ricoh", "Pentax", "Phase One",
8384 "Samsung", "Sigma", "Sinar", "Sony" };
8386 int hlen, flen, fsize, zero_fsize=1, i, c;
8389 tiff_flip = flip = filters = UINT_MAX; /* unknown */
8390 raw_height = raw_width = fuji_width = fuji_layout = cr2_slice[0] = 0;
8391 maximum = height = width = top_margin = left_margin = 0;
8392 cdesc[0] = desc[0] = artist[0] = make[0] = model[0] = model2[0] = 0;
8393 iso_speed = shutter = aperture = focal_len = unique_id = 0;
8395 memset (tiff_ifd, 0, sizeof tiff_ifd);
8396 memset (gpsdata, 0, sizeof gpsdata);
8397 memset (cblack, 0, sizeof cblack);
8398 memset (white, 0, sizeof white);
8399 memset (mask, 0, sizeof mask);
8400 thumb_offset = thumb_length = thumb_width = thumb_height = 0;
8401 load_raw = thumb_load_raw = 0;
8402 write_thumb = &CLASS jpeg_thumb;
8403 data_offset = meta_offset = meta_length = tiff_bps = tiff_compress = 0;
8404 kodak_cbpp = zero_after_ff = dng_version = load_flags = 0;
8405 timestamp = shot_order = tiff_samples = black = is_foveon = 0;
8406 mix_green = profile_length = data_error = zero_is_bad = 0;
8407 pixel_aspect = is_raw = raw_color = 1;
8408 tile_width = tile_length = 0;
8409 for (i=0; i < 4; i++) {
8410 cam_mul[i] = i == 1;
8412 FORC3 cmatrix[c][i] = 0;
8413 FORC3 rgb_cam[c][i] = c == i;
8416 for (i=0; i < 0x10000; i++) curve[i] = i;
8420 fseek (ifp, 0, SEEK_SET);
8421 fread (head, 1, 32, ifp);
8422 fseek (ifp, 0, SEEK_END);
8423 flen = fsize = ftell(ifp);
8424 if ((cp = (char *) memmem (head, 32, "MMMM", 4)) ||
8425 (cp = (char *) memmem (head, 32, "IIII", 4))) {
8426 parse_phase_one (cp-head);
8427 if (cp-head && parse_tiff(0)) apply_tiff();
8428 } else if (order == 0x4949 || order == 0x4d4d) {
8429 if (!memcmp (head+6,"HEAPCCDR",8)) {
8431 parse_ciff (hlen, flen-hlen, 0);
8432 load_raw = &CLASS canon_load_raw;
8433 } else if (parse_tiff(0)) apply_tiff();
8434 } else if (!memcmp (head,"\xff\xd8\xff\xe1",4) &&
8435 !memcmp (head+6,"Exif",4)) {
8436 fseek (ifp, 4, SEEK_SET);
8437 data_offset = 4 + get2();
8438 fseek (ifp, data_offset, SEEK_SET);
8439 if (fgetc(ifp) != 0xff)
8442 } else if (!memcmp (head+25,"ARECOYK",7)) {
8443 strcpy (make, "Contax");
8444 strcpy (model,"N Digital");
8445 fseek (ifp, 33, SEEK_SET);
8447 fseek (ifp, 60, SEEK_SET);
8448 FORC4 cam_mul[c ^ (c >> 1)] = get4();
8449 } else if (!strcmp (head, "PXN")) {
8450 strcpy (make, "Logitech");
8451 strcpy (model,"Fotoman Pixtura");
8452 } else if (!strcmp (head, "qktk")) {
8453 strcpy (make, "Apple");
8454 strcpy (model,"QuickTake 100");
8455 load_raw = &CLASS quicktake_100_load_raw;
8456 } else if (!strcmp (head, "qktn")) {
8457 strcpy (make, "Apple");
8458 strcpy (model,"QuickTake 150");
8459 load_raw = &CLASS kodak_radc_load_raw;
8460 } else if (!memcmp (head,"FUJIFILM",8)) {
8461 fseek (ifp, 84, SEEK_SET);
8462 thumb_offset = get4();
8463 thumb_length = get4();
8464 fseek (ifp, 92, SEEK_SET);
8465 parse_fuji (get4());
8466 if (thumb_offset > 120) {
8467 fseek (ifp, 120, SEEK_SET);
8468 is_raw += (i = get4()) && 1;
8469 if (is_raw == 2 && shot_select)
8472 load_raw = &CLASS unpacked_load_raw;
8473 fseek (ifp, 100+28*(shot_select > 0), SEEK_SET);
8474 parse_tiff (data_offset = get4());
8475 parse_tiff (thumb_offset+12);
8477 } else if (!memcmp (head,"RIFF",4)) {
8478 fseek (ifp, 0, SEEK_SET);
8480 } else if (!memcmp (head+4,"ftypqt ",9)) {
8481 fseek (ifp, 0, SEEK_SET);
8484 } else if (!memcmp (head,"\0\001\0\001\0@",6)) {
8485 fseek (ifp, 6, SEEK_SET);
8486 fread (make, 1, 8, ifp);
8487 fread (model, 1, 8, ifp);
8488 fread (model2, 1, 16, ifp);
8489 data_offset = get2();
8492 raw_height = get2();
8493 load_raw = &CLASS nokia_load_raw;
8494 filters = 0x61616161;
8495 } else if (!memcmp (head,"NOKIARAW",8)) {
8496 strcpy (make, "NOKIA");
8498 fseek (ifp, 300, SEEK_SET);
8499 data_offset = get4();
8503 switch (tiff_bps = i*8 / (width * height)) {
8504 case 8: load_raw = &CLASS eight_bit_load_raw; break;
8505 case 10: load_raw = &CLASS nokia_load_raw;
8507 raw_height = height + (top_margin = i / (width * tiff_bps/8) - height);
8509 filters = 0x61616161;
8510 } else if (!memcmp (head,"ARRI",4)) {
8512 fseek (ifp, 20, SEEK_SET);
8515 strcpy (make, "ARRI");
8516 fseek (ifp, 668, SEEK_SET);
8517 fread (model, 1, 64, ifp);
8519 load_raw = &CLASS packed_load_raw;
8521 filters = 0x61616161;
8522 } else if (!memcmp (head,"XPDS",4)) {
8524 fseek (ifp, 0x800, SEEK_SET);
8525 fread (make, 1, 41, ifp);
8526 raw_height = get2();
8528 fseek (ifp, 56, SEEK_CUR);
8529 fread (model, 1, 30, ifp);
8530 data_offset = 0x10000;
8531 load_raw = &CLASS canon_rmf_load_raw;
8532 gamma_curve (0, 12.25, 1, 1023);
8533 } else if (!memcmp (head+4,"RED1",4)) {
8534 strcpy (make, "Red");
8535 strcpy (model,"One");
8537 load_raw = &CLASS redcine_load_raw;
8538 gamma_curve (1/2.4, 12.92, 1, 4095);
8539 filters = 0x49494949;
8540 } else if (!memcmp (head,"DSC-Image",9))
8542 else if (!memcmp (head,"PWAD",4))
8544 else if (!memcmp (head,"\0MRM",4))
8546 else if (!memcmp (head,"FOVb",4))
8548 else if (!memcmp (head,"CI",2))
8551 for (zero_fsize=i=0; i < sizeof table / sizeof *table; i++)
8552 if (fsize == table[i].fsize) {
8553 strcpy (make, table[i].make );
8554 strcpy (model, table[i].model);
8555 flip = table[i].flags >> 2;
8556 zero_is_bad = table[i].flags & 2;
8557 if (table[i].flags & 1)
8558 parse_external_jpeg();
8559 data_offset = table[i].offset;
8560 raw_width = table[i].rw;
8561 raw_height = table[i].rh;
8562 left_margin = table[i].lm;
8563 top_margin = table[i].tm;
8564 width = raw_width - left_margin - table[i].rm;
8565 height = raw_height - top_margin - table[i].bm;
8566 filters = 0x1010101 * table[i].cf;
8567 colors = 4 - !((filters & filters >> 1) & 0x5555);
8568 load_flags = table[i].lf;
8569 switch (tiff_bps = (fsize-data_offset)*8 / (raw_width*raw_height)) {
8571 load_raw = &CLASS minolta_rd175_load_raw; break;
8573 load_raw = &CLASS eight_bit_load_raw; break;
8576 load_raw = &CLASS packed_load_raw; break;
8578 order = 0x4949 | 0x404 * (load_flags & 1);
8579 tiff_bps -= load_flags >> 4;
8580 tiff_bps -= load_flags = load_flags >> 1 & 7;
8581 load_raw = &CLASS unpacked_load_raw;
8583 maximum = (1 << tiff_bps) - (1 << table[i].max);
8585 if (zero_fsize) fsize = 0;
8586 if (make[0] == 0) parse_smal (0, flen);
8589 if (!(strncmp(model,"ov",2) && strncmp(model,"RP_OV",5)) &&
8590 !fseek (ifp, -6404096, SEEK_END) &&
8591 fread (head, 1, 32, ifp) && !strcmp(head,"BRCMn")) {
8592 strcpy (make, "OmniVision");
8593 data_offset = ftell(ifp) + 0x8000-32;
8596 load_raw = &CLASS nokia_load_raw;
8597 filters = 0x16161616;
8601 for (i=0; i < sizeof corp / sizeof *corp; i++)
8602 if (strcasestr (make, corp[i])) /* Simplify company names */
8603 strcpy (make, corp[i]);
8604 if ((!strcmp(make,"Kodak") || !strcmp(make,"Leica")) &&
8605 ((cp = strcasestr(model," DIGITAL CAMERA")) ||
8606 (cp = strstr(model,"FILE VERSION"))))
8608 if (!strncasecmp(model,"PENTAX",6))
8609 strcpy (make, "Pentax");
8610 cp = make + strlen(make); /* Remove trailing spaces */
8611 while (*--cp == ' ') *cp = 0;
8612 cp = model + strlen(model);
8613 while (*--cp == ' ') *cp = 0;
8614 i = strlen(make); /* Remove make from model */
8615 if (!strncasecmp (model, make, i) && model[i++] == ' ')
8616 memmove (model, model+i, 64-i);
8617 if (!strncmp (model,"FinePix ",8))
8618 strcpy (model, model+8);
8619 if (!strncmp (model,"Digital Camera ",15))
8620 strcpy (model, model+15);
8621 desc[511] = artist[63] = make[63] = model[63] = model2[63] = 0;
8622 if (!is_raw) goto notraw;
8624 if (!height) height = raw_height;
8625 if (!width) width = raw_width;
8626 if (height == 2624 && width == 3936) /* Pentax K10D and Samsung GX10 */
8627 { height = 2616; width = 3896; }
8628 if (height == 3136 && width == 4864) /* Pentax K20D and Samsung GX20 */
8629 { height = 3124; width = 4688; filters = 0x16161616; }
8630 if (width == 4352 && (!strcmp(model,"K-r") || !strcmp(model,"K-x")))
8631 { width = 4309; filters = 0x16161616; }
8632 if (width >= 4960 && !strncmp(model,"K-5",3))
8633 { left_margin = 10; width = 4950; filters = 0x16161616; }
8634 if (width == 4736 && !strcmp(model,"K-7"))
8635 { height = 3122; width = 4684; filters = 0x16161616; top_margin = 2; }
8636 if (width == 6080 && !strcmp(model,"K-3"))
8637 { left_margin = 4; width = 6040; }
8638 if (width == 7424 && !strcmp(model,"645D"))
8639 { height = 5502; width = 7328; filters = 0x61616161; top_margin = 29;
8641 if (height == 3014 && width == 4096) /* Ricoh GX200 */
8644 if (filters == UINT_MAX) filters = 0;
8645 if (filters) is_raw *= tiff_samples;
8646 else colors = tiff_samples;
8647 switch (tiff_compress) {
8649 case 1: load_raw = &CLASS packed_dng_load_raw; break;
8650 case 7: load_raw = &CLASS lossless_dng_load_raw; break;
8651 case 34892: load_raw = &CLASS lossy_dng_load_raw; break;
8652 default: load_raw = 0;
8656 if (!strcmp(make,"Canon") && !fsize && tiff_bps != 15) {
8658 load_raw = &CLASS lossless_jpeg_load_raw;
8659 for (i=0; i < sizeof canon / sizeof *canon; i++)
8660 if (raw_width == canon[i][0] && raw_height == canon[i][1]) {
8661 width = raw_width - (left_margin = canon[i][2]);
8662 height = raw_height - (top_margin = canon[i][3]);
8663 width -= canon[i][4];
8664 height -= canon[i][5];
8665 mask[0][1] = canon[i][6];
8666 mask[0][3] = -canon[i][7];
8667 mask[1][1] = canon[i][8];
8668 mask[1][3] = -canon[i][9];
8669 if (canon[i][10]) filters = canon[i][10] * 0x01010101;
8671 if ((unique_id | 0x20000) == 0x2720000) {
8676 for (i=0; i < sizeof unique / sizeof *unique; i++)
8677 if (unique_id == 0x80000000 + unique[i].id) {
8678 adobe_coeff ("Canon", unique[i].model);
8679 if (model[4] == 'K' && strlen(model) == 8)
8680 strcpy (model, unique[i].model);
8682 for (i=0; i < sizeof sonique / sizeof *sonique; i++)
8683 if (unique_id == sonique[i].id)
8684 strcpy (model, sonique[i].model);
8685 if (!strcmp(make,"Nikon")) {
8687 load_raw = &CLASS packed_load_raw;
8688 if (model[0] == 'E')
8689 load_flags |= !data_offset << 2 | 2;
8692 /* Set parameters based on camera name (for non-DNG files). */
8694 if (!strcmp(model,"KAI-0340")
8695 && find_green (16, 16, 3840, 5120) < 25) {
8697 top_margin = filters = 0;
8698 strcpy (model,"C603");
8700 if (!strcmp(make,"Sony") && raw_width > 3888)
8701 black = 128 << (tiff_bps - 12);
8703 if (height*2 < width) pixel_aspect = 0.5;
8704 if (height > width) pixel_aspect = 2;
8707 } else if (!strcmp(make,"Canon") && tiff_bps == 15) {
8709 case 3344: width -= 66;
8710 case 3872: width -= 6;
8712 if (height > width) {
8714 SWAP(raw_height,raw_width);
8716 if (width == 7200 && height == 3888) {
8717 raw_width = width = 6480;
8718 raw_height = height = 4320;
8721 tiff_samples = colors = 3;
8722 load_raw = &CLASS canon_sraw_load_raw;
8723 } else if (!strcmp(model,"PowerShot 600")) {
8728 filters = 0xe1e4e1e4;
8729 load_raw = &CLASS canon_600_load_raw;
8730 } else if (!strcmp(model,"PowerShot A5") ||
8731 !strcmp(model,"PowerShot A5 Zoom")) {
8735 pixel_aspect = 256/235.0;
8736 filters = 0x1e4e1e4e;
8738 } else if (!strcmp(model,"PowerShot A50")) {
8742 filters = 0x1b4e4b1e;
8744 } else if (!strcmp(model,"PowerShot Pro70")) {
8747 filters = 0x1e4b4e1b;
8751 load_raw = &CLASS packed_load_raw;
8753 } else if (!strcmp(model,"PowerShot Pro90 IS") ||
8754 !strcmp(model,"PowerShot G1")) {
8756 filters = 0xb4b4b4b4;
8757 } else if (!strcmp(model,"PowerShot A610")) {
8758 if (canon_s2is()) strcpy (model+10, "S2 IS");
8759 } else if (!strcmp(model,"PowerShot SX220 HS")) {
8761 } else if (!strcmp(model,"EOS D2000C")) {
8762 filters = 0x61616161;
8764 } else if (!strcmp(model,"D1")) {
8765 cam_mul[0] *= 256/527.0;
8766 cam_mul[2] *= 256/317.0;
8767 } else if (!strcmp(model,"D1X")) {
8770 } else if (!strcmp(model,"D40X") ||
8771 !strcmp(model,"D60") ||
8772 !strcmp(model,"D80") ||
8773 !strcmp(model,"D3000")) {
8776 } else if (!strcmp(model,"D3") ||
8777 !strcmp(model,"D3S") ||
8778 !strcmp(model,"D700")) {
8781 } else if (!strcmp(model,"D3100")) {
8784 } else if (!strcmp(model,"D5000") ||
8785 !strcmp(model,"D90")) {
8787 } else if (!strcmp(model,"D5100") ||
8788 !strcmp(model,"D7000") ||
8789 !strcmp(model,"COOLPIX A")) {
8791 } else if (!strcmp(model,"D3200") ||
8792 !strncmp(model,"D6",2) ||
8793 !strncmp(model,"D800",4)) {
8795 } else if (!strcmp(model,"D4") ||
8796 !strcmp(model,"Df")) {
8799 } else if (!strncmp(model,"D40",3) ||
8800 !strncmp(model,"D50",3) ||
8801 !strncmp(model,"D70",3)) {
8803 } else if (!strcmp(model,"D100")) {
8805 raw_width = (width += 3) + 3;
8806 } else if (!strcmp(model,"D200")) {
8809 filters = 0x94949494;
8810 } else if (!strncmp(model,"D2H",3)) {
8813 } else if (!strncmp(model,"D2X",3)) {
8814 if (width == 3264) width -= 32;
8816 } else if (!strncmp(model,"D300",4)) {
8818 } else if (!strncmp(model,"COOLPIX P",9) && raw_width != 4032) {
8820 filters = 0x94949494;
8821 if (model[9] == '7' && iso_speed >= 400)
8823 } else if (!strncmp(model,"1 ",2)) {
8825 } else if (fsize == 1581060) {
8827 pre_mul[0] = 1.2085;
8828 pre_mul[1] = 1.0943;
8829 pre_mul[3] = 1.1103;
8830 } else if (fsize == 3178560) {
8833 } else if (fsize == 4771840) {
8834 if (!timestamp && nikon_e995())
8835 strcpy (model, "E995");
8836 if (strcmp(model,"E995")) {
8837 filters = 0xb4b4b4b4;
8843 } else if (fsize == 2940928) {
8844 if (!timestamp && !nikon_e2100())
8845 strcpy (model,"E2500");
8846 if (!strcmp(model,"E2500")) {
8850 filters = 0x4b4b4b4b;
8852 } else if (fsize == 4775936) {
8853 if (!timestamp) nikon_3700();
8854 if (model[0] == 'E' && atoi(model+1) < 3700)
8855 filters = 0x49494949;
8856 if (!strcmp(model,"Optio 33WR")) {
8858 filters = 0x16161616;
8860 if (make[0] == 'O') {
8861 i = find_green (12, 32, 1188864, 3576832);
8862 c = find_green (12, 32, 2383920, 2387016);
8863 if (abs(i) < abs(c)) {
8867 if (i < 0) filters = 0x61616161;
8869 } else if (fsize == 5869568) {
8870 if (!timestamp && minolta_z2()) {
8871 strcpy (make, "Minolta");
8872 strcpy (model,"DiMAGE Z2");
8874 load_flags = 6 + 24*(make[0] == 'M');
8875 } else if (fsize == 6291456) {
8876 fseek (ifp, 0x300000, SEEK_SET);
8877 if ((order = guess_byte_order(0x10000)) == 0x4d4d) {
8878 height -= (top_margin = 16);
8879 width -= (left_margin = 28);
8881 strcpy (make, "ISG");
8884 } else if (!strcmp(make,"Fujifilm")) {
8885 if (!strcmp(model+7,"S2Pro")) {
8886 strcpy (model,"S2Pro");
8890 } else if (load_raw != &CLASS packed_load_raw)
8891 maximum = (is_raw == 2 && shot_select) ? 0x2f00 : 0x3e00;
8892 top_margin = (raw_height - height) >> 2 << 1;
8893 left_margin = (raw_width - width ) >> 2 << 1;
8894 if (width == 2848 || width == 3664) filters = 0x16161616;
8895 if (width == 4032 || width == 4952 || width == 6032) left_margin = 0;
8896 if (width == 3328 && (width -= 66)) left_margin = 34;
8897 if (width == 4936) left_margin = 4;
8898 if (!strcmp(model,"HS50EXR") ||
8899 !strcmp(model,"F900EXR")) {
8902 filters = 0x16161616;
8904 if (fuji_layout) raw_width *= is_raw;
8906 FORC(36) ((char *)xtrans)[c] =
8907 xtrans_abs[(c/6+top_margin) % 6][(c+left_margin) % 6];
8908 } else if (!strcmp(model,"KD-400Z")) {
8913 } else if (!strcmp(model,"KD-510Z")) {
8915 } else if (!strcasecmp(make,"Minolta")) {
8916 if (!load_raw && (maximum = 0xfff))
8917 load_raw = &CLASS unpacked_load_raw;
8918 if (!strncmp(model,"DiMAGE A",8)) {
8919 if (!strcmp(model,"DiMAGE A200"))
8920 filters = 0x49494949;
8922 load_raw = &CLASS packed_load_raw;
8923 } else if (!strncmp(model,"ALPHA",5) ||
8924 !strncmp(model,"DYNAX",5) ||
8925 !strncmp(model,"MAXXUM",6)) {
8926 sprintf (model+20, "DYNAX %-10s", model+6+(model[0]=='M'));
8927 adobe_coeff (make, model+20);
8928 load_raw = &CLASS packed_load_raw;
8929 } else if (!strncmp(model,"DiMAGE G",8)) {
8930 if (model[8] == '4') {
8933 } else if (model[8] == '5') {
8938 } else if (model[8] == '6') {
8943 filters = 0x61616161;
8945 load_raw = &CLASS unpacked_load_raw;
8949 } else if (!strcmp(model,"*ist D")) {
8950 load_raw = &CLASS unpacked_load_raw;
8952 } else if (!strcmp(model,"*ist DS")) {
8954 } else if (!strcmp(make,"Samsung") && raw_width == 4704) {
8955 height -= top_margin = 8;
8956 width -= 2 * (left_margin = 8);
8958 } else if (!strcmp(make,"Samsung") && raw_height == 3714) {
8959 height -= top_margin = 18;
8960 left_margin = raw_width - (width = 5536);
8961 if (raw_width != 5600)
8962 left_margin = top_margin = 0;
8963 filters = 0x61616161;
8965 } else if (!strcmp(make,"Samsung") && raw_width == 5632) {
8969 width = 5574 - (left_margin = 32 + tiff_bps);
8970 if (tiff_bps == 12) load_flags = 80;
8971 } else if (!strcmp(make,"Samsung") && raw_width == 5664) {
8972 height -= top_margin = 17;
8975 filters = 0x49494949;
8976 } else if (!strcmp(make,"Samsung") && raw_width == 6496) {
8977 filters = 0x61616161;
8978 black = 1 << (tiff_bps - 7);
8979 } else if (!strcmp(model,"EX1")) {
8983 if ((width -= 6) > 3682) {
8988 } else if (!strcmp(model,"WB2000")) {
8992 if ((width -= 10) > 3718) {
8997 } else if (strstr(model,"WB550")) {
8998 strcpy (model, "WB550");
8999 } else if (!strcmp(model,"EX2F")) {
9004 filters = 0x49494949;
9005 load_raw = &CLASS unpacked_load_raw;
9006 } else if (!strcmp(model,"STV680 VGA")) {
9008 } else if (!strcmp(model,"N95")) {
9009 height = raw_height - (top_margin = 2);
9010 } else if (!strcmp(model,"640x480")) {
9011 gamma_curve (0.45, 4.5, 1, 255);
9012 } else if (!strcmp(make,"Hasselblad")) {
9013 if (load_raw == &CLASS lossless_jpeg_load_raw)
9014 load_raw = &CLASS hasselblad_load_raw;
9015 if (raw_width == 7262) {
9020 filters = 0x61616161;
9021 } else if (raw_width == 7410 || raw_width == 8282) {
9026 filters = 0x61616161;
9027 } else if (raw_width == 9044) {
9032 black += load_flags = 256;
9034 } else if (raw_width == 4090) {
9035 strcpy (model, "V96C");
9036 height -= (top_margin = 6);
9037 width -= (left_margin = 3) + 7;
9038 filters = 0x61616161;
9040 if (tiff_samples > 1) {
9041 is_raw = tiff_samples+1;
9042 if (!shot_select && !half_size) filters = 0;
9044 } else if (!strcmp(make,"Sinar")) {
9045 if (!load_raw) load_raw = &CLASS unpacked_load_raw;
9046 if (is_raw > 1 && !shot_select && !half_size) filters = 0;
9048 } else if (!strcmp(make,"Leaf")) {
9050 fseek (ifp, data_offset, SEEK_SET);
9051 if (ljpeg_start (&jh, 1) && jh.bits == 15)
9053 if (tiff_samples > 1) filters = 0;
9054 if (tiff_samples > 1 || tile_length < raw_height) {
9055 load_raw = &CLASS leaf_hdr_load_raw;
9056 raw_width = tile_width;
9058 if ((width | height) == 2048) {
9059 if (tiff_samples == 1) {
9061 strcpy (cdesc, "RBTG");
9062 strcpy (model, "CatchLight");
9063 top_margin = 8; left_margin = 18; height = 2032; width = 2016;
9065 strcpy (model, "DCB2");
9066 top_margin = 10; left_margin = 16; height = 2028; width = 2022;
9068 } else if (width+height == 3144+2060) {
9069 if (!model[0]) strcpy (model, "Cantare");
9070 if (width > height) {
9071 top_margin = 6; left_margin = 32; height = 2048; width = 3072;
9072 filters = 0x61616161;
9074 left_margin = 6; top_margin = 32; width = 2048; height = 3072;
9075 filters = 0x16161616;
9077 if (!cam_mul[0] || model[0] == 'V') filters = 0;
9078 else is_raw = tiff_samples;
9079 } else if (width == 2116) {
9080 strcpy (model, "Valeo 6");
9081 height -= 2 * (top_margin = 30);
9082 width -= 2 * (left_margin = 55);
9083 filters = 0x49494949;
9084 } else if (width == 3171) {
9085 strcpy (model, "Valeo 6");
9086 height -= 2 * (top_margin = 24);
9087 width -= 2 * (left_margin = 24);
9088 filters = 0x16161616;
9090 } else if (!strcmp(make,"Leica") || !strcmp(make,"Panasonic")) {
9091 if ((flen - data_offset) / (raw_width*8/7) == raw_height)
9092 load_raw = &CLASS panasonic_load_raw;
9094 load_raw = &CLASS unpacked_load_raw;
9098 if ((height += 12) > raw_height) height = raw_height;
9099 for (i=0; i < sizeof pana / sizeof *pana; i++)
9100 if (raw_width == pana[i][0] && raw_height == pana[i][1]) {
9101 left_margin = pana[i][2];
9102 top_margin = pana[i][3];
9103 width += pana[i][4];
9104 height += pana[i][5];
9106 filters = 0x01010101 * (uchar) "\x94\x61\x49\x16"
9107 [((filters-1) ^ (left_margin & 1) ^ (top_margin << 1)) & 3];
9108 } else if (!strcmp(model,"C770UZ")) {
9111 filters = 0x16161616;
9112 load_raw = &CLASS packed_load_raw;
9114 } else if (!strcmp(make,"Olympus")) {
9115 height += height & 1;
9116 if (exif_cfa) filters = exif_cfa;
9117 if (width == 4100) width -= 4;
9118 if (width == 4080) width -= 24;
9119 if (width == 9280) { width -= 6; height -= 6; }
9120 if (load_raw == &CLASS unpacked_load_raw)
9123 if (!strcmp(model,"E-300") ||
9124 !strcmp(model,"E-500")) {
9126 if (load_raw == &CLASS unpacked_load_raw) {
9128 memset (cblack, 0, sizeof cblack);
9130 } else if (!strcmp(model,"E-330")) {
9132 if (load_raw == &CLASS unpacked_load_raw)
9134 } else if (!strcmp(model,"SP550UZ")) {
9135 thumb_length = flen - (thumb_offset = 0xa39800);
9138 } else if (!strcmp(model,"TG-4")) {
9141 } else if (!strcmp(model,"N Digital")) {
9144 filters = 0x61616161;
9145 data_offset = 0x1a00;
9146 load_raw = &CLASS packed_load_raw;
9147 } else if (!strcmp(model,"DSC-F828")) {
9151 data_offset = 862144;
9152 load_raw = &CLASS sony_load_raw;
9153 filters = 0x9c9c9c9c;
9155 strcpy (cdesc, "RGBE");
9156 } else if (!strcmp(model,"DSC-V3")) {
9160 data_offset = 787392;
9161 load_raw = &CLASS sony_load_raw;
9162 } else if (!strcmp(make,"Sony") && raw_width == 3984) {
9165 } else if (!strcmp(make,"Sony") && raw_width == 4288) {
9167 } else if (!strcmp(make,"Sony") && raw_width == 4600) {
9168 if (!strcmp(model,"DSLR-A350"))
9171 } else if (!strcmp(make,"Sony") && raw_width == 4928) {
9172 if (height < 3280) width -= 8;
9173 } else if (!strcmp(make,"Sony") && raw_width == 5504) {
9174 width -= height > 3664 ? 8 : 32;
9175 if (!strncmp(model,"DSC",3))
9176 black = 200 << (tiff_bps - 12);
9177 } else if (!strcmp(make,"Sony") && raw_width == 6048) {
9179 if (strstr(model,"RX1") || strstr(model,"A99"))
9181 } else if (!strcmp(make,"Sony") && raw_width == 7392) {
9183 } else if (!strcmp(make,"Sony") && raw_width == 8000) {
9185 if (!strncmp(model,"DSC",3)) {
9187 load_raw = &CLASS unpacked_load_raw;
9190 } else if (!strcmp(model,"DSLR-A100")) {
9191 if (width == 3880) {
9193 width = ++raw_width;
9200 filters = 0x61616161;
9201 } else if (!strcmp(model,"PIXL")) {
9202 height -= top_margin = 4;
9203 width -= left_margin = 32;
9204 gamma_curve (0, 7, 1, 255);
9205 } else if (!strcmp(model,"C603") || !strcmp(model,"C330")
9206 || !strcmp(model,"12MP")) {
9208 if (filters && data_offset) {
9209 fseek (ifp, data_offset < 4096 ? 168 : 5252, SEEK_SET);
9210 read_shorts (curve, 256);
9211 } else gamma_curve (0, 3.875, 1, 255);
9212 load_raw = filters ? &CLASS eight_bit_load_raw :
9213 strcmp(model,"C330") ? &CLASS kodak_c603_load_raw :
9214 &CLASS kodak_c330_load_raw;
9215 load_flags = tiff_bps > 16;
9217 } else if (!strncasecmp(model,"EasyShare",9)) {
9218 data_offset = data_offset < 0x15000 ? 0x15000 : 0x17000;
9219 load_raw = &CLASS packed_load_raw;
9220 } else if (!strcasecmp(make,"Kodak")) {
9221 if (filters == UINT_MAX) filters = 0x61616161;
9222 if (!strncmp(model,"NC2000",6) ||
9223 !strncmp(model,"EOSDCS",6) ||
9224 !strncmp(model,"DCS4",4)) {
9227 if (model[6] == ' ') model[6] = 0;
9228 if (!strcmp(model,"DCS460A")) goto bw;
9229 } else if (!strcmp(model,"DCS660M")) {
9232 } else if (!strcmp(model,"DCS760M")) {
9236 if (!strcmp(model+4,"20X"))
9237 strcpy (cdesc, "MYCY");
9238 if (strstr(model,"DC25")) {
9239 strcpy (model, "DC25");
9240 data_offset = 15424;
9242 if (!strncmp(model,"DC2",3)) {
9243 raw_height = 2 + (height = 242);
9244 if (flen < 100000) {
9245 raw_width = 256; width = 249;
9246 pixel_aspect = (4.0*height) / (3.0*width);
9248 raw_width = 512; width = 501;
9249 pixel_aspect = (493.0*height) / (373.0*width);
9251 top_margin = left_margin = 1;
9253 filters = 0x8d8d8d8d;
9258 load_raw = &CLASS eight_bit_load_raw;
9259 } else if (!strcmp(model,"40")) {
9260 strcpy (model, "DC40");
9264 load_raw = &CLASS kodak_radc_load_raw;
9266 } else if (strstr(model,"DC50")) {
9267 strcpy (model, "DC50");
9270 data_offset = 19712;
9271 load_raw = &CLASS kodak_radc_load_raw;
9272 } else if (strstr(model,"DC120")) {
9273 strcpy (model, "DC120");
9276 pixel_aspect = height/0.75/width;
9277 load_raw = tiff_compress == 7 ?
9278 &CLASS kodak_jpeg_load_raw : &CLASS kodak_dc120_load_raw;
9279 } else if (!strcmp(model,"DCS200")) {
9282 thumb_offset = 6144;
9284 write_thumb = &CLASS layer_thumb;
9287 } else if (!strcmp(model,"Fotoman Pixtura")) {
9291 load_raw = &CLASS kodak_radc_load_raw;
9292 filters = 0x61616161;
9294 } else if (!strncmp(model,"QuickTake",9)) {
9295 if (head[5]) strcpy (model+10, "200");
9296 fseek (ifp, 544, SEEK_SET);
9299 data_offset = (get4(),get2()) == 30 ? 738:736;
9300 if (height > width) {
9302 fseek (ifp, data_offset-6, SEEK_SET);
9303 flip = ~get2() & 3 ? 5:6;
9305 filters = 0x61616161;
9306 } else if (!strcmp(make,"Rollei") && !load_raw) {
9307 switch (raw_width) {
9320 filters = 0x16161616;
9321 load_raw = &CLASS rollei_load_raw;
9324 sprintf (model, "%dx%d", width, height);
9325 if (filters == UINT_MAX) filters = 0x94949494;
9326 if (thumb_offset && !thumb_height) {
9327 fseek (ifp, thumb_offset, SEEK_SET);
9328 if (ljpeg_start (&jh, 1)) {
9329 thumb_width = jh.wide;
9330 thumb_height = jh.high;
9334 if ((use_camera_matrix & (use_camera_wb || dng_version))
9335 && cmatrix[0][0] > 0.125) {
9336 memcpy (rgb_cam, cmatrix, sizeof cmatrix);
9339 if (raw_color) adobe_coeff (make, model);
9340 if (load_raw == &CLASS kodak_radc_load_raw)
9341 if (raw_color) adobe_coeff ("Apple","Quicktake");
9343 fuji_width = width >> !fuji_layout;
9344 filters = fuji_width & 1 ? 0x94949494 : 0x49494949;
9345 width = (height >> fuji_layout) + fuji_width;
9349 if (raw_height < height) raw_height = height;
9350 if (raw_width < width ) raw_width = width;
9352 if (!tiff_bps) tiff_bps = 12;
9353 if (!maximum) maximum = (1 << tiff_bps) - 1;
9354 if (!load_raw || height < 22 || width < 22 ||
9355 tiff_bps > 16 || tiff_samples > 6 || colors > 4)
9358 if (load_raw == &CLASS redcine_load_raw) {
9359 fprintf (stderr,_("%s: You must link dcraw with %s!!\n"),
9360 ifname, "libjasper");
9365 if (load_raw == &CLASS kodak_jpeg_load_raw ||
9366 load_raw == &CLASS lossy_dng_load_raw) {
9367 fprintf (stderr,_("%s: You must link dcraw with %s!!\n"),
9373 strcpy (cdesc, colors == 3 ? "RGBG":"GMCY");
9374 if (!raw_height) raw_height = height;
9375 if (!raw_width ) raw_width = width;
9376 if (filters > 999 && colors == 3)
9377 filters |= ((filters >> 2 & 0x22222222) |
9378 (filters << 2 & 0x88888888)) & filters << 1;
9380 if (flip == UINT_MAX) flip = tiff_flip;
9381 if (flip == UINT_MAX) flip = 0;
9384 { unsigned flp = flip;
9385 switch ((flp+3600) % 360) {
9386 case 270: flp = 5; break;
9387 case 180: flp = 3; break;
9391 sprintf(info, "%d %d", height, width);
9393 sprintf(info, "%d %d", width, height); }
9397 void CLASS apply_profile (const char *input, const char *output)
9400 cmsHPROFILE hInProfile=0, hOutProfile=0;
9401 cmsHTRANSFORM hTransform;
9405 if (strcmp (input, "embed"))
9406 hInProfile = cmsOpenProfileFromFile (input, "r");
9407 else if (profile_length) {
9408 prof = (char *) malloc (profile_length);
9409 merror (prof, "apply_profile()");
9410 fseek (ifp, profile_offset, SEEK_SET);
9411 fread (prof, 1, profile_length, ifp);
9412 hInProfile = cmsOpenProfileFromMem (prof, profile_length);
9415 fprintf (stderr,_("%s has no embedded profile.\n"), ifname);
9416 if (!hInProfile) return;
9418 hOutProfile = cmsCreate_sRGBProfile();
9419 else if ((fp = fopen (output, "rb"))) {
9420 fread (&size, 4, 1, fp);
9421 fseek (fp, 0, SEEK_SET);
9422 oprof = (unsigned *) malloc (size = ntohl(size));
9423 merror (oprof, "apply_profile()");
9424 fread (oprof, 1, size, fp);
9426 if (!(hOutProfile = cmsOpenProfileFromMem (oprof, size))) {
9431 fprintf (stderr,_("Cannot open file %s!\n"), output);
9432 if (!hOutProfile) goto quit;
9434 fprintf (stderr,_("Applying color profile...\n"));
9435 hTransform = cmsCreateTransform (hInProfile, TYPE_RGBA_16,
9436 hOutProfile, TYPE_RGBA_16, INTENT_PERCEPTUAL, 0);
9437 cmsDoTransform (hTransform, image, image, width*height);
9438 raw_color = 1; /* Don't use rgb_cam with a profile */
9439 cmsDeleteTransform (hTransform);
9440 cmsCloseProfile (hOutProfile);
9442 cmsCloseProfile (hInProfile);
9446 void CLASS convert_to_rgb()
9448 int row, col, c, i, j, k;
9450 float out[3], out_cam[3][4];
9451 double num, inverse[3][3];
9452 static const double xyzd50_srgb[3][3] =
9453 { { 0.436083, 0.385083, 0.143055 },
9454 { 0.222507, 0.716888, 0.060608 },
9455 { 0.013930, 0.097097, 0.714022 } };
9456 static const double rgb_rgb[3][3] =
9457 { { 1,0,0 }, { 0,1,0 }, { 0,0,1 } };
9458 static const double adobe_rgb[3][3] =
9459 { { 0.715146, 0.284856, 0.000000 },
9460 { 0.000000, 1.000000, 0.000000 },
9461 { 0.000000, 0.041166, 0.958839 } };
9462 static const double wide_rgb[3][3] =
9463 { { 0.593087, 0.404710, 0.002206 },
9464 { 0.095413, 0.843149, 0.061439 },
9465 { 0.011621, 0.069091, 0.919288 } };
9466 static const double prophoto_rgb[3][3] =
9467 { { 0.529317, 0.330092, 0.140588 },
9468 { 0.098368, 0.873465, 0.028169 },
9469 { 0.016879, 0.117663, 0.865457 } };
9470 static const double aces_rgb[3][3] =
9471 { { 0.432996, 0.375380, 0.189317 },
9472 { 0.089427, 0.816523, 0.102989 },
9473 { 0.019165, 0.118150, 0.941914 } };
9474 static const double (*out_rgb[])[3] =
9475 { rgb_rgb, adobe_rgb, wide_rgb, prophoto_rgb, xyz_rgb, aces_rgb };
9476 static const char *name[] =
9477 { "sRGB", "Adobe RGB (1998)", "WideGamut D65", "ProPhoto D65", "XYZ", "ACES" };
9478 static const unsigned phead[] =
9479 { 1024, 0, 0x2100000, 0x6d6e7472, 0x52474220, 0x58595a20, 0, 0, 0,
9480 0x61637370, 0, 0, 0x6e6f6e65, 0, 0, 0, 0, 0xf6d6, 0x10000, 0xd32d };
9482 { 10, 0x63707274, 0, 36, /* cprt */
9483 0x64657363, 0, 40, /* desc */
9484 0x77747074, 0, 20, /* wtpt */
9485 0x626b7074, 0, 20, /* bkpt */
9486 0x72545243, 0, 14, /* rTRC */
9487 0x67545243, 0, 14, /* gTRC */
9488 0x62545243, 0, 14, /* bTRC */
9489 0x7258595a, 0, 20, /* rXYZ */
9490 0x6758595a, 0, 20, /* gXYZ */
9491 0x6258595a, 0, 20 }; /* bXYZ */
9492 static const unsigned pwhite[] = { 0xf351, 0x10000, 0x116cc };
9493 unsigned pcurve[] = { 0x63757276, 0, 1, 0x1000000 };
9495 gamma_curve (gamm[0], gamm[1], 0, 0);
9496 memcpy (out_cam, rgb_cam, sizeof out_cam);
9497 raw_color |= colors == 1 || document_mode ||
9498 output_color < 1 || output_color > 6;
9500 oprof = (unsigned *) calloc (phead[0], 1);
9501 merror (oprof, "convert_to_rgb()");
9502 memcpy (oprof, phead, sizeof phead);
9503 if (output_color == 5) oprof[4] = oprof[5];
9504 oprof[0] = 132 + 12*pbody[0];
9505 for (i=0; i < pbody[0]; i++) {
9506 oprof[oprof[0]/4] = i ? (i > 1 ? 0x58595a20 : 0x64657363) : 0x74657874;
9507 pbody[i*3+2] = oprof[0];
9508 oprof[0] += (pbody[i*3+3] + 3) & -4;
9510 memcpy (oprof+32, pbody, sizeof pbody);
9511 oprof[pbody[5]/4+2] = strlen(name[output_color-1]) + 1;
9512 memcpy ((char *)oprof+pbody[8]+8, pwhite, sizeof pwhite);
9513 pcurve[3] = (short)(256/gamm[5]+0.5) << 16;
9514 for (i=4; i < 7; i++)
9515 memcpy ((char *)oprof+pbody[i*3+2], pcurve, sizeof pcurve);
9516 pseudoinverse ((double (*)[3]) out_rgb[output_color-1], inverse, 3);
9517 for (i=0; i < 3; i++)
9518 for (j=0; j < 3; j++) {
9519 for (num = k=0; k < 3; k++)
9520 num += xyzd50_srgb[i][k] * inverse[j][k];
9521 oprof[pbody[j*3+23]/4+i+2] = num * 0x10000 + 0.5;
9523 for (i=0; i < phead[0]/4; i++)
9524 oprof[i] = htonl(oprof[i]);
9525 strcpy ((char *)oprof+pbody[2]+8, "auto-generated by dcraw");
9526 strcpy ((char *)oprof+pbody[5]+12, name[output_color-1]);
9527 for (i=0; i < 3; i++)
9528 for (j=0; j < colors; j++)
9529 for (out_cam[i][j] = k=0; k < 3; k++)
9530 out_cam[i][j] += out_rgb[output_color-1][i][k] * rgb_cam[k][j];
9533 fprintf (stderr, raw_color ? _("Building histograms...\n") :
9534 _("Converting to %s colorspace...\n"), name[output_color-1]);
9536 memset (histogram, 0, sizeof histogram);
9537 for (img=image[0], row=0; row < height; row++)
9538 for (col=0; col < width; col++, img+=4) {
9540 out[0] = out[1] = out[2] = 0;
9542 out[0] += out_cam[0][c] * img[c];
9543 out[1] += out_cam[1][c] * img[c];
9544 out[2] += out_cam[2][c] * img[c];
9546 FORC3 img[c] = CLIP((int) out[c]);
9548 else if (document_mode)
9549 img[0] = img[fcol(row,col)];
9550 FORCC histogram[c][img[c] >> 3]++;
9552 if (colors == 4 && output_color) colors = 3;
9553 if (document_mode && filters) colors = 1;
9556 // Export color matrix to Cinelerra.
9557 // It can't be applied before interpolation.
9559 for(i = 0; i < 3; i++) {
9560 for(j = 0; j < 3; j++)
9561 matrix[k++] = rgb_cam[i][j];
9566 void CLASS fuji_rotate()
9572 ushort wide, high, (*img)[4], (*pix)[4];
9574 if (!fuji_width) return;
9576 fprintf (stderr,_("Rotating image 45 degrees...\n"));
9577 fuji_width = (fuji_width - 1 + shrink) >> shrink;
9579 wide = fuji_width / step;
9580 high = (height - fuji_width) / step;
9581 img = (ushort (*)[4]) calloc (high, wide*sizeof *img);
9582 merror (img, "fuji_rotate()");
9584 for (row=0; row < high; row++)
9585 for (col=0; col < wide; col++) {
9586 ur = r = fuji_width + (row-col)*step;
9587 uc = c = (row+col)*step;
9588 if (ur > height-2 || uc > width-2) continue;
9591 pix = image + ur*width + uc;
9592 for (i=0; i < colors; i++)
9593 img[row*wide+col][i] =
9594 (pix[ 0][i]*(1-fc) + pix[ 1][i]*fc) * (1-fr) +
9595 (pix[width][i]*(1-fc) + pix[width+1][i]*fc) * fr;
9604 void CLASS stretch()
9606 ushort newdim, (*img)[4], *pix0, *pix1;
9610 if (pixel_aspect == 1) return;
9611 if (verbose) fprintf (stderr,_("Stretching the image...\n"));
9612 if (pixel_aspect < 1) {
9613 newdim = height / pixel_aspect + 0.5;
9614 img = (ushort (*)[4]) calloc (width, newdim*sizeof *img);
9615 merror (img, "stretch()");
9616 for (rc=row=0; row < newdim; row++, rc+=pixel_aspect) {
9617 frac = rc - (c = rc);
9618 pix0 = pix1 = image[c*width];
9619 if (c+1 < height) pix1 += width*4;
9620 for (col=0; col < width; col++, pix0+=4, pix1+=4)
9621 FORCC img[row*width+col][c] = pix0[c]*(1-frac) + pix1[c]*frac + 0.5;
9625 newdim = width * pixel_aspect + 0.5;
9626 img = (ushort (*)[4]) calloc (height, newdim*sizeof *img);
9627 merror (img, "stretch()");
9628 for (rc=col=0; col < newdim; col++, rc+=1/pixel_aspect) {
9629 frac = rc - (c = rc);
9630 pix0 = pix1 = image[c];
9631 if (c+1 < width) pix1 += 4;
9632 for (row=0; row < height; row++, pix0+=width*4, pix1+=width*4)
9633 FORCC img[row*newdim+col][c] = pix0[c]*(1-frac) + pix1[c]*frac + 0.5;
9641 int CLASS flip_index (int row, int col)
9643 if (flip & 4) SWAP(row,col);
9644 if (flip & 2) row = iheight - 1 - row;
9645 if (flip & 1) col = iwidth - 1 - col;
9646 return row * iwidth + col;
9652 union { char c[4]; short s[2]; int i; } val;
9656 ushort order, magic;
9659 struct tiff_tag tag[23];
9662 struct tiff_tag exif[4];
9664 struct tiff_tag gpst[10];
9668 char desc[512], make[64], model[64], soft[32], date[20], artist[64];
9671 void CLASS tiff_set (struct tiff_hdr *th, ushort *ntag,
9672 ushort tag, ushort type, int count, int val)
9674 struct tiff_tag *tt;
9677 tt = (struct tiff_tag *)(ntag+1) + (*ntag)++;
9679 if (type == 1 && count <= 4)
9680 FORC(4) tt->val.c[c] = val >> (c << 3);
9681 else if (type == 2) {
9682 count = strnlen((char *)th + val, count-1) + 1;
9684 FORC(4) tt->val.c[c] = ((char *)th)[val+c];
9685 } else if (type == 3 && count <= 2)
9686 FORC(2) tt->val.s[c] = val >> (c << 4);
9692 #define TOFF(ptr) ((char *)(&(ptr)) - (char *)th)
9694 void CLASS tiff_head (struct tiff_hdr *th, int full)
9699 memset (th, 0, sizeof *th);
9700 th->order = htonl(0x4d4d4949) >> 16;
9703 th->rat[0] = th->rat[2] = 300;
9704 th->rat[1] = th->rat[3] = 1;
9705 FORC(6) th->rat[4+c] = 1000000;
9706 th->rat[4] *= shutter;
9707 th->rat[6] *= aperture;
9708 th->rat[8] *= focal_len;
9709 strncpy (th->desc, desc, 512);
9710 strncpy (th->make, make, 64);
9711 strncpy (th->model, model, 64);
9712 strcpy (th->soft, "dcraw v" DCRAW_VERSION);
9713 t = localtime (×tamp);
9714 sprintf (th->date, "%04d:%02d:%02d %02d:%02d:%02d",
9715 t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);
9716 strncpy (th->artist, artist, 64);
9718 tiff_set (th, &th->ntag, 254, 4, 1, 0);
9719 tiff_set (th, &th->ntag, 256, 4, 1, width);
9720 tiff_set (th, &th->ntag, 257, 4, 1, height);
9721 tiff_set (th, &th->ntag, 258, 3, colors, output_bps);
9723 th->tag[th->ntag-1].val.i = TOFF(th->bps);
9724 FORC4 th->bps[c] = output_bps;
9725 tiff_set (th, &th->ntag, 259, 3, 1, 1);
9726 tiff_set (th, &th->ntag, 262, 3, 1, 1 + (colors > 1));
9728 tiff_set (th, &th->ntag, 270, 2, 512, TOFF(th->desc));
9729 tiff_set (th, &th->ntag, 271, 2, 64, TOFF(th->make));
9730 tiff_set (th, &th->ntag, 272, 2, 64, TOFF(th->model));
9732 if (oprof) psize = ntohl(oprof[0]);
9733 tiff_set (th, &th->ntag, 273, 4, 1, sizeof *th + psize);
9734 tiff_set (th, &th->ntag, 277, 3, 1, colors);
9735 tiff_set (th, &th->ntag, 278, 4, 1, height);
9736 tiff_set (th, &th->ntag, 279, 4, 1, height*width*colors*output_bps/8);
9738 tiff_set (th, &th->ntag, 274, 3, 1, "12435867"[flip]-'0');
9739 tiff_set (th, &th->ntag, 282, 5, 1, TOFF(th->rat[0]));
9740 tiff_set (th, &th->ntag, 283, 5, 1, TOFF(th->rat[2]));
9741 tiff_set (th, &th->ntag, 284, 3, 1, 1);
9742 tiff_set (th, &th->ntag, 296, 3, 1, 2);
9743 tiff_set (th, &th->ntag, 305, 2, 32, TOFF(th->soft));
9744 tiff_set (th, &th->ntag, 306, 2, 20, TOFF(th->date));
9745 tiff_set (th, &th->ntag, 315, 2, 64, TOFF(th->artist));
9746 tiff_set (th, &th->ntag, 34665, 4, 1, TOFF(th->nexif));
9747 if (psize) tiff_set (th, &th->ntag, 34675, 7, psize, sizeof *th);
9748 tiff_set (th, &th->nexif, 33434, 5, 1, TOFF(th->rat[4]));
9749 tiff_set (th, &th->nexif, 33437, 5, 1, TOFF(th->rat[6]));
9750 tiff_set (th, &th->nexif, 34855, 3, 1, iso_speed);
9751 tiff_set (th, &th->nexif, 37386, 5, 1, TOFF(th->rat[8]));
9753 tiff_set (th, &th->ntag, 34853, 4, 1, TOFF(th->ngps));
9754 tiff_set (th, &th->ngps, 0, 1, 4, 0x202);
9755 tiff_set (th, &th->ngps, 1, 2, 2, gpsdata[29]);
9756 tiff_set (th, &th->ngps, 2, 5, 3, TOFF(th->gps[0]));
9757 tiff_set (th, &th->ngps, 3, 2, 2, gpsdata[30]);
9758 tiff_set (th, &th->ngps, 4, 5, 3, TOFF(th->gps[6]));
9759 tiff_set (th, &th->ngps, 5, 1, 1, gpsdata[31]);
9760 tiff_set (th, &th->ngps, 6, 5, 1, TOFF(th->gps[18]));
9761 tiff_set (th, &th->ngps, 7, 5, 3, TOFF(th->gps[12]));
9762 tiff_set (th, &th->ngps, 18, 2, 12, TOFF(th->gps[20]));
9763 tiff_set (th, &th->ngps, 29, 2, 12, TOFF(th->gps[23]));
9764 memcpy (th->gps, gpsdata, sizeof th->gps);
9768 void CLASS jpeg_thumb()
9774 thumb = (char *) malloc (thumb_length);
9775 merror (thumb, "jpeg_thumb()");
9776 fread (thumb, 1, thumb_length, ifp);
9779 if (strcmp (thumb+6, "Exif")) {
9780 memcpy (exif, "\xff\xe1 Exif\0\0", 10);
9781 exif[1] = htons (8 + sizeof th);
9782 fwrite (exif, 1, sizeof exif, ofp);
9784 fwrite (&th, 1, sizeof th, ofp);
9786 fwrite (thumb+2, 1, thumb_length-2, ofp);
9790 void CLASS write_ppm_tiff()
9795 int c, row, col, soff, rstep, cstep;
9796 int perc, val, total, white=0x2000;
9798 perc = width * height * 0.01; /* 99th percentile white level */
9799 if (fuji_width) perc /= 2;
9800 if (!((highlight & ~2) || no_auto_bright))
9801 for (white=c=0; c < colors; c++) {
9802 for (val=0x2000, total=0; --val > 32; )
9803 if ((total += histogram[c][val]) > perc) break;
9804 if (white < val) white = val;
9806 gamma_curve (gamm[0], gamm[1], 2, (white << 3)/bright);
9809 if (flip & 4) SWAP(height,width);
9810 ppm = (uchar *) calloc (width, colors*output_bps/8);
9811 ppm2 = (ushort *) ppm;
9812 merror (ppm, "write_ppm_tiff()");
9815 fwrite (&th, sizeof th, 1, ofp);
9817 fwrite (oprof, ntohl(oprof[0]), 1, ofp);
9818 } else if (colors > 3)
9820 "P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLTYPE %s\nENDHDR\n",
9821 width, height, colors, (1 << output_bps)-1, cdesc);
9823 fprintf (ofp, "P%d\n%d %d\n%d\n",
9824 colors/2+5, width, height, (1 << output_bps)-1);
9825 soff = flip_index (0, 0);
9826 cstep = flip_index (0, 1) - soff;
9827 rstep = flip_index (1, 0) - flip_index (0, width);
9828 for (row=0; row < height; row++, soff += rstep) {
9829 for (col=0; col < width; col++, soff += cstep)
9830 if (output_bps == 8)
9831 FORCC ppm [col*colors+c] = curve[image[soff][c]] >> 8;
9832 else FORCC ppm2[col*colors+c] = curve[image[soff][c]];
9833 if (output_bps == 16 && !output_tiff && htons(0x55aa) != 0x55aa)
9834 swab (ppm2, ppm2, width*colors*2);
9835 fwrite (ppm, colors*output_bps/8, width, ofp);
9841 void CLASS write_cinelerra()
9843 int c, row, col, soff, cstep, rstep;
9844 float scale = 1. / 0xffff;
9845 iheight = height; iwidth = width;
9846 if( (flip & 4) != 0 ) SWAP(height,width);
9847 soff = flip_index(0, 0);
9848 cstep = flip_index(0, 1) - soff;
9849 rstep = flip_index(1, 0) - flip_index(0, width);
9850 if( document_mode ) {
9851 for( row=0; row<height; ++row, soff += rstep ) {
9852 float *output = data[row];
9853 for( col=0; col<width; ++col, soff += cstep ) {
9854 ushort *pixel = image[soff];
9855 FORC3 *output++ = (float)*pixel++ * scale;
9856 if( alpha ) *output++ = 1.0;
9861 int val, total, white=0x2000;
9862 int perc = width * height * 0.01; /* 99th percentile white level */
9863 if( fuji_width ) perc /= 2;
9864 if( !((highlight & ~2) || no_auto_bright) ) {
9865 for( white=c=0; c < colors; ++c ) {
9866 for( val=0x2000, total=0; --val > 32; )
9867 if( (total += histogram[c][val]) > perc ) break;
9868 if( white < val ) white = val;
9871 gamma_curve(gamm[0], gamm[1], 2, (white << 3)/bright);
9872 for( row=0; row<height; ++row, soff += rstep ) {
9873 float *output = data[row];
9874 for( col=0; col<width; ++col, soff += cstep ) {
9875 ushort *pixel = image[soff];
9876 FORC3 *output++ = (float)curve[*pixel++] * scale;
9877 if( alpha ) *output++ = 1.0;
9884 int CLASS main (int argc, const char **argv)
9886 int arg, status=0, quality, i, c;
9887 int timestamp_only=0, thumbnail_only=0, identify_only=0;
9888 int user_qual=-1, user_black=-1, user_sat=-1, user_flip=-1;
9889 int use_fuji_rotate=1, write_to_stdout=0, read_from_stdin=0;
9890 const char *sp, *bpfile=0, *dark_frame=0, *write_ext;
9891 char opm, opt, *ofname, *cp;
9894 const char *cam_profile=0, *out_profile=0;
9898 reset(); // Globals must be reset
9901 // putenv ((char *) "TZ=UTC");
9904 setlocale (LC_CTYPE, "");
9905 setlocale (LC_MESSAGES, "");
9906 bindtextdomain ("dcraw", LOCALEDIR);
9907 textdomain ("dcraw");
9911 printf(_("\nRaw photo decoder \"dcraw\" v%s"), DCRAW_VERSION);
9912 printf(_("\nby Dave Coffin, dcoffin a cybercom o net\n"));
9913 printf(_("\nUsage: %s [OPTION]... [FILE]...\n\n"), argv[0]);
9914 puts(_("-v Print verbose messages"));
9915 puts(_("-c Write image data to standard output"));
9916 puts(_("-e Extract embedded thumbnail image"));
9917 puts(_("-i Identify files without decoding them"));
9918 puts(_("-i -v Identify files and show metadata"));
9919 puts(_("-z Change file dates to camera timestamp"));
9920 puts(_("-w Use camera white balance, if possible"));
9921 puts(_("-a Average the whole image for white balance"));
9922 puts(_("-A <x y w h> Average a grey box for white balance"));
9923 puts(_("-r <r g b g> Set custom white balance"));
9924 puts(_("+M/-M Use/don't use an embedded color matrix"));
9925 puts(_("-C <r b> Correct chromatic aberration"));
9926 puts(_("-P <file> Fix the dead pixels listed in this file"));
9927 puts(_("-K <file> Subtract dark frame (16-bit raw PGM)"));
9928 puts(_("-k <num> Set the darkness level"));
9929 puts(_("-S <num> Set the saturation level"));
9930 puts(_("-n <num> Set threshold for wavelet denoising"));
9931 puts(_("-H [0-9] Highlight mode (0=clip, 1=unclip, 2=blend, 3+=rebuild)"));
9932 puts(_("-t [0-7] Flip image (0=none, 3=180, 5=90CCW, 6=90CW)"));
9933 puts(_("-o [0-6] Output colorspace (raw,sRGB,Adobe,Wide,ProPhoto,XYZ,ACES)"));
9935 puts(_("-o <file> Apply output ICC profile from file"));
9936 puts(_("-p <file> Apply camera ICC profile from file or \"embed\""));
9938 puts(_("-d Document mode (no color, no interpolation)"));
9939 puts(_("-D Document mode without scaling (totally raw)"));
9940 puts(_("-j Don't stretch or rotate raw pixels"));
9941 puts(_("-W Don't automatically brighten the image"));
9942 puts(_("-b <num> Adjust brightness (default = 1.0)"));
9943 puts(_("-g <p ts> Set custom gamma curve (default = 2.222 4.5)"));
9944 puts(_("-q [0-3] Set the interpolation quality"));
9945 puts(_("-h Half-size color image (twice as fast as \"-q 0\")"));
9946 puts(_("-f Interpolate RGGB as four colors"));
9947 puts(_("-m <num> Apply a 3x3 median filter to R-G and B-G"));
9948 puts(_("-s [0..N-1] Select one raw image or \"all\" from each file"));
9949 puts(_("-6 Write 16-bit instead of 8-bit"));
9950 puts(_("-4 Linear 16-bit, same as \"-6 -W -g 1 1\""));
9951 puts(_("-T Write TIFF instead of PPM"));
9956 for (arg=1; (((opm = argv[arg][0]) - 2) | 2) == '+'; ) {
9957 opt = argv[arg++][1];
9958 if ((cp = (char *) strchr (sp="nbrkStqmHACg", opt)))
9959 for (i=0; i < "114111111422"[cp-sp]-'0'; i++)
9960 if (!isdigit(argv[arg+i][0])) {
9961 fprintf (stderr,_("Non-numeric argument to \"-%c\"\n"), opt);
9965 case 'n': threshold = atof(argv[arg++]); break;
9966 case 'b': bright = atof(argv[arg++]); break;
9968 FORC4 user_mul[c] = atof(argv[arg++]); break;
9969 case 'C': aber[0] = 1 / atof(argv[arg++]);
9970 aber[2] = 1 / atof(argv[arg++]); break;
9971 case 'g': gamm[0] = atof(argv[arg++]);
9972 gamm[1] = atof(argv[arg++]);
9973 if (gamm[0]) gamm[0] = 1/gamm[0]; break;
9974 case 'k': user_black = atoi(argv[arg++]); break;
9975 case 'S': user_sat = atoi(argv[arg++]); break;
9976 case 't': user_flip = atoi(argv[arg++]); break;
9977 case 'q': user_qual = atoi(argv[arg++]); break;
9978 case 'm': med_passes = atoi(argv[arg++]); break;
9979 case 'H': highlight = atoi(argv[arg++]); break;
9981 shot_select = abs(atoi(argv[arg]));
9982 multi_out = !strcmp(argv[arg++],"all");
9985 if (isdigit(argv[arg][0]) && !argv[arg][1])
9986 output_color = atoi(argv[arg++]);
9988 else out_profile = argv[arg++];
9990 case 'p': cam_profile = argv[arg++];
9993 case 'P': bpfile = argv[arg++]; break;
9994 case 'K': dark_frame = argv[arg++]; break;
9995 case 'z': timestamp_only = 1; break;
9996 case 'e': thumbnail_only = 1; break;
9997 case 'i': identify_only = 1; break;
9998 case 'c': write_to_stdout = 1; break;
9999 case 'v': verbose = 1; break;
10000 case 'h': half_size = 1; break;
10001 case 'f': four_color_rgb = 1; break;
10002 case 'A': FORC4 greybox[c] = atoi(argv[arg++]);
10003 case 'a': use_auto_wb = 1; break;
10004 case 'w': use_camera_wb = 1; break;
10005 case 'M': use_camera_matrix = 3 * (opm == '+'); break;
10006 case 'I': read_from_stdin = 1; break;
10007 case 'E': document_mode++;
10008 case 'D': document_mode++;
10009 case 'd': document_mode++;
10010 case 'j': use_fuji_rotate = 0; break;
10011 case 'W': no_auto_bright = 1; break;
10012 case 'T': output_tiff = 1; break;
10013 case '4': gamm[0] = gamm[1] =
10014 no_auto_bright = 1;
10015 case '6': output_bps = 16; break;
10017 fprintf (stderr,_("Unknown option \"-%c\".\n"), opt);
10022 fprintf (stderr,_("No files to process.\n"));
10025 if (write_to_stdout) {
10027 if (0 && isatty(1)) {
10028 fprintf (stderr,_("Will not write an image to the terminal!\n"));
10031 #if defined(WIN32) || defined(DJGPP) || defined(__CYGWIN__)
10032 if (setmode(1,O_BINARY) < 0) {
10033 perror ("setmode()");
10038 for ( ; arg < argc; arg++) {
10043 meta_data = ofname = 0;
10045 if (setjmp (failure)) {
10046 if (fileno(ifp) > 2) fclose(ifp);
10047 if (fileno(ofp) > 2) fclose(ofp);
10051 ifname = argv[arg];
10052 if (!(ifp = fopen (ifname, "rb"))) {
10056 status = (identify(),!is_raw);
10057 if (user_flip >= 0)
10059 switch ((flip+3600) % 360) {
10060 case 270: flip = 5; break;
10061 case 180: flip = 3; break;
10064 if (timestamp_only) {
10065 if ((status = !timestamp))
10066 fprintf (stderr,_("%s has no timestamp.\n"), ifname);
10067 else if (identify_only)
10068 printf ("%10ld%10d %s\n", (long) timestamp, shot_order, ifname);
10071 fprintf (stderr,_("%s time set to %d.\n"), ifname, (int) timestamp);
10072 ut.actime = ut.modtime = timestamp;
10073 utime (ifname, &ut);
10078 // write_fun = &CLASS write_ppm_tiff;
10079 write_fun = &CLASS write_cinelerra;
10081 if (thumbnail_only) {
10082 if ((status = !thumb_offset)) {
10083 fprintf (stderr,_("%s has no thumbnail.\n"), ifname);
10085 } else if (thumb_load_raw) {
10086 load_raw = thumb_load_raw;
10087 data_offset = thumb_offset;
10088 height = thumb_height;
10089 width = thumb_width;
10093 fseek (ifp, thumb_offset, SEEK_SET);
10094 write_fun = write_thumb;
10098 if (load_raw == &CLASS kodak_ycbcr_load_raw) {
10099 height += height & 1;
10100 width += width & 1;
10102 if (identify_only && verbose && make[0]) {
10103 printf (_("\nFilename: %s\n"), ifname);
10104 printf (_("Timestamp: %s"), ctime(×tamp));
10105 printf (_("Camera: %s %s\n"), make, model);
10107 printf (_("Owner: %s\n"), artist);
10109 printf (_("DNG Version: "));
10110 for (i=24; i >= 0; i -= 8)
10111 printf ("%d%c", dng_version >> i & 255, i ? '.':'\n');
10113 printf (_("ISO speed: %d\n"), (int) iso_speed);
10114 printf (_("Shutter: "));
10115 if (shutter > 0 && shutter < 1)
10116 shutter = (printf ("1/"), 1 / shutter);
10117 printf (_("%0.1f sec\n"), shutter);
10118 printf (_("Aperture: f/%0.1f\n"), aperture);
10119 printf (_("Focal length: %0.1f mm\n"), focal_len);
10120 printf (_("Embedded ICC profile: %s\n"), profile_length ? _("yes"):_("no"));
10121 printf (_("Number of raw images: %d\n"), is_raw);
10122 if (pixel_aspect != 1)
10123 printf (_("Pixel Aspect Ratio: %0.6f\n"), pixel_aspect);
10125 printf (_("Thumb size: %4d x %d\n"), thumb_width, thumb_height);
10126 printf (_("Full size: %4d x %d\n"), raw_width, raw_height);
10129 // else if (!is_raw)
10130 // fprintf (stderr,_("Cannot decode file %s\n"), ifname);
10131 if (!is_raw) goto next;
10132 shrink = filters && (half_size || (!identify_only &&
10133 (threshold || aber[0] != 1 || aber[2] != 1)));
10134 iheight = (height + shrink) >> shrink;
10135 iwidth = (width + shrink) >> shrink;
10136 if (identify_only) {
10138 if (document_mode == 3) {
10139 top_margin = left_margin = fuji_width = 0;
10140 height = raw_height;
10143 iheight = (height + shrink) >> shrink;
10144 iwidth = (width + shrink) >> shrink;
10145 if (use_fuji_rotate) {
10147 fuji_width = (fuji_width - 1 + shrink) >> shrink;
10148 iwidth = fuji_width / sqrt(0.5);
10149 iheight = (iheight - fuji_width) / sqrt(0.5);
10151 if (pixel_aspect < 1) iheight = iheight / pixel_aspect + 0.5;
10152 if (pixel_aspect > 1) iwidth = iwidth * pixel_aspect + 0.5;
10156 SWAP(iheight,iwidth);
10157 printf (_("Image size: %4d x %d\n"), width, height);
10158 printf (_("Output size: %4d x %d\n"), iwidth, iheight);
10159 printf (_("Raw colors: %d"), colors);
10161 int fhigh = 2, fwide = 2;
10162 if ((filters ^ (filters >> 8)) & 0xff) fhigh = 4;
10163 if ((filters ^ (filters >> 16)) & 0xffff) fhigh = 8;
10164 if (filters == 1) fhigh = fwide = 16;
10165 if (filters == 9) fhigh = fwide = 6;
10166 printf (_("\nFilter pattern: "));
10167 for (i=0; i < fhigh; i++)
10168 for (c = i && putchar('/') && 0; c < fwide; c++)
10169 putchar (cdesc[fcol(i,c)]);
10171 printf (_("\nDaylight multipliers:"));
10172 FORCC printf (" %f", pre_mul[c]);
10173 if (cam_mul[0] > 0) {
10174 printf (_("\nCamera multipliers:"));
10175 FORC4 printf (" %f", cam_mul[c]);
10181 // printf (_("%s is a %s %s image.\n"), ifname, make, model);
10187 meta_data = (char *) malloc (meta_length);
10188 merror (meta_data, "main()");
10190 if (filters || colors == 1) {
10191 raw_image = (ushort *) calloc ((raw_height+7), raw_width*2);
10192 merror (raw_image, "main()");
10194 image = (ushort (*)[4]) calloc (iheight, iwidth*sizeof *image);
10195 merror (image, "main()");
10198 fprintf (stderr,_("Loading %s %s image from %s ...\n"),
10199 make, model, ifname);
10200 if (shot_select >= is_raw)
10201 fprintf (stderr,_("%s: \"-s %d\" requests a nonexistent image!\n"),
10202 ifname, shot_select);
10203 fseeko (ifp, data_offset, SEEK_SET);
10204 if (raw_image && read_from_stdin)
10205 fread (raw_image, 2, raw_height*raw_width, stdin);
10207 (this->*load_raw)();
10208 if (document_mode == 3) {
10209 top_margin = left_margin = fuji_width = 0;
10210 height = raw_height;
10213 iheight = (height + shrink) >> shrink;
10214 iwidth = (width + shrink) >> shrink;
10216 image = (ushort (*)[4]) calloc (iheight, iwidth*sizeof *image);
10217 merror (image, "main()");
10218 crop_masked_pixels();
10221 if (zero_is_bad) remove_zeroes();
10222 bad_pixels (bpfile);
10223 if (dark_frame) subtract (dark_frame);
10224 quality = 2 + !fuji_width;
10225 if (user_qual >= 0) quality = user_qual;
10227 FORC3 if (i > cblack[c]) i = cblack[c];
10228 FORC4 cblack[c] -= i;
10231 FORC (cblack[4] * cblack[5])
10232 if (i > cblack[6+c]) i = cblack[6+c];
10233 FORC (cblack[4] * cblack[5])
10236 if (user_black >= 0) black = user_black;
10237 FORC4 cblack[c] += black;
10238 if (user_sat > 0) maximum = user_sat;
10243 if (document_mode || load_raw == &CLASS foveon_dp_load_raw) {
10244 for (i=0; i < height*width*4; i++)
10245 if ((short) image[0][i] < 0) image[0][i] = 0;
10246 } else foveon_interpolate();
10247 } else if (document_mode < 2)
10250 if (filters && !document_mode) {
10253 else if (quality == 1 || colors > 3)
10255 else if (quality == 2 && filters > 1000)
10257 else if (filters == 9)
10258 xtrans_interpolate (quality*2-3);
10263 for (colors=3, i=0; i < height*width; i++)
10264 image[i][1] = (image[i][1] + image[i][3]) >> 1;
10265 if (!is_foveon && colors == 3) median_filter();
10266 if (!is_foveon && highlight == 2) blend_highlights();
10267 if (!is_foveon && highlight > 2) recover_highlights();
10268 if (use_fuji_rotate) fuji_rotate();
10270 if (cam_profile) apply_profile (cam_profile, out_profile);
10273 if (use_fuji_rotate) stretch();
10275 if (write_fun == &CLASS jpeg_thumb)
10276 write_ext = ".jpg";
10277 else if (output_tiff && write_fun == &CLASS write_ppm_tiff)
10278 write_ext = ".tiff";
10280 write_ext = ".pgm\0.ppm\0.ppm\0.pam" + colors*5-5;
10281 ofname = (char *) malloc (strlen(ifname) + 64);
10282 merror (ofname, "main()");
10283 if (write_to_stdout)
10284 strcpy (ofname,_("standard output"));
10286 strcpy (ofname, ifname);
10287 if ((cp = strrchr (ofname, '.'))) *cp = 0;
10289 sprintf (ofname+strlen(ofname), "_%0*d",
10290 snprintf(0,0,"%d",is_raw-1), shot_select);
10291 if (thumbnail_only)
10292 strcat (ofname, ".thumb");
10293 strcat (ofname, write_ext);
10294 ofp = fopen (ofname, "wb");
10302 fprintf (stderr,_("Writing data to %s ...\n"), ofname);
10303 (this->*write_fun)();
10305 if (ofp != stdout) fclose(ofp);
10307 if (meta_data) free (meta_data);
10308 if (ofname) free (ofname);
10309 if (oprof) free (oprof);
10310 if (image) free (image);
10312 if (++shot_select < is_raw) arg--;
10313 else shot_select = 0;