2 dcraw.c -- Dave Coffin's raw photo decoder
3 Copyright 1997-2016 by Dave Coffin, dcoffin a cybercom o net
5 This is a command-line ANSI C program to convert raw photos from
6 any digital camera on any computer running any operating system.
8 No license is required to download and use dcraw.c. However,
9 to lawfully redistribute dcraw, you must either (a) offer, at
10 no extra charge, full source code* for all executable files
11 containing RESTRICTED functions, (b) distribute this code under
12 the GPL Version 2 or later, (c) remove all RESTRICTED functions,
13 re-implement them, or copy them from an earlier, unrestricted
14 Revision of dcraw.c, or (d) purchase a license from the author.
16 The functions that process Foveon images have been RESTRICTED
17 since Revision 1.237. All other code remains free for all uses.
19 *If you have not modified dcraw.c in any way, a link to my
20 homepage qualifies as "full source code".
23 $Date: 2016/05/10 21:30:43 $
26 #define DCRAW_VERSION "9.27"
31 #define _USE_MATH_DEFINES
43 #include <sys/types.h>
45 #if defined(DJGPP) || defined(__MINGW32__)
49 #define fgetc getc_unlocked
55 #include <sys/utime.h>
57 #pragma comment(lib, "ws2_32.lib")
58 #define snprintf _snprintf
59 #define strcasecmp stricmp
60 #define strncasecmp strnicmp
61 typedef __int64 INT64;
62 typedef unsigned __int64 UINT64;
66 #include <netinet/in.h>
68 typedef int64_t INT64;
69 typedef uint64_t UINT64;
78 #include <jasper/jasper.h> /* Decode Red camera movies */
81 #include <jpeglib.h> /* Decode compressed Kodak DC120 photos */
82 #endif /* and Adobe Lossy DNGs */
84 #include <lcms2.h> /* Support color profiles */
88 #define _(String) gettext(String)
90 #define _(String) (String)
96 All global variables are defined here, and all functions that
97 access them are prefixed with "CLASS". Note that a thread-safe
98 C++ class cannot have non-const static local variables.
101 #define FORC(cnt) for (c=0; c < cnt; c++)
102 #define FORC3 FORC(3)
103 #define FORC4 FORC(4)
104 #define FORCC FORC(colors)
106 #define SQR(x) ((x)*(x))
107 #define ABS(x) (((int)(x) ^ ((int)(x) >> 31)) - ((int)(x) >> 31))
108 #define MIN(a,b) ((a) < (b) ? (a) : (b))
109 #define MAX(a,b) ((a) > (b) ? (a) : (b))
110 #define LIM(x,min,max) MAX(min,MIN(x,max))
111 #define ULIM(x,y,z) ((y) < (z) ? LIM(x,y,z) : LIM(x,z,y))
112 #define CLIP(x) LIM((int)(x),0,65535)
113 #define SWAP(a,b) { a=a+b; b=a-b; a=a-b; }
115 In order to inline this calculation, I make the risky
116 assumption that all filter patterns can be described
117 by a repeating pattern of eight rows and two columns
119 Do not use the FC or BAYER macros with the Leaf CatchLight,
120 because its pattern is 16x16, not 2x8.
122 Return values are either 0/1/2/3 = G/M/C/Y or 0/1/2/3 = R/G1/B/G2
124 PowerShot 600 PowerShot A50 PowerShot Pro70 Pro90 & G1
125 0xe1e4e1e4: 0x1b4e4b1e: 0x1e4b4e1b: 0xb4b4b4b4:
127 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5
128 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
129 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
130 2 M G M G M G 2 Y C Y C Y C 2 C Y C Y C Y
131 3 C Y C Y C Y 3 G M G M G M 3 G M G M G M
132 4 C Y C Y C Y 4 Y C Y C Y C
133 PowerShot A5 5 G M G M G M 5 G M G M G M
134 0x1e4e1e4e: 6 Y C Y C Y C 6 C Y C Y C Y
135 7 M G M G M G 7 M G M G M G
142 All RGB cameras use one of these Bayer grids:
144 0x16161616: 0x61616161: 0x49494949: 0x94949494:
146 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5
147 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
148 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
149 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
150 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
153 #define RAW(row,col) \
154 raw_image[(row)*raw_width+(col)]
156 #define FC(row,col) \
157 (filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)
159 #define BAYER(row,col) \
160 image[((row) >> shrink)*iwidth + ((col) >> shrink)][FC(row,col)]
162 #define BAYER2(row,col) \
163 image[((row) >> shrink)*iwidth + ((col) >> shrink)][fcol(row,col)]
165 int CLASS fcol (int row, int col)
167 static const char filter[16][16] =
168 { { 2,1,1,3,2,3,2,0,3,2,3,0,1,2,1,0 },
169 { 0,3,0,2,0,1,3,1,0,1,1,2,0,3,3,2 },
170 { 2,3,3,2,3,1,1,3,3,1,2,1,2,0,0,3 },
171 { 0,1,0,1,0,2,0,2,2,0,3,0,1,3,2,1 },
172 { 3,1,1,2,0,1,0,2,1,3,1,3,0,1,3,0 },
173 { 2,0,0,3,3,2,3,1,2,0,2,0,3,2,2,1 },
174 { 2,3,3,1,2,1,2,1,2,1,1,2,3,0,0,1 },
175 { 1,0,0,2,3,0,0,3,0,3,0,3,2,1,2,3 },
176 { 2,3,3,1,1,2,1,0,3,2,3,0,2,3,1,3 },
177 { 1,0,2,0,3,0,3,2,0,1,1,2,0,1,0,2 },
178 { 0,1,1,3,3,2,2,1,1,3,3,0,2,1,3,2 },
179 { 2,3,2,0,0,1,3,0,2,0,1,2,3,0,1,0 },
180 { 1,3,1,2,3,2,3,2,0,2,0,1,1,0,3,0 },
181 { 0,2,0,3,1,0,0,1,1,3,3,2,3,2,2,1 },
182 { 2,1,3,2,3,1,2,1,0,3,0,2,0,2,0,2 },
183 { 0,3,1,0,0,2,0,3,2,1,3,1,1,3,1,3 } };
185 if (filters == 1) return filter[(row+top_margin)&15][(col+left_margin)&15];
186 if (filters == 9) return xtrans[(row+6) % 6][(col+6) % 6];
193 #define ZERO(var) memset(&var, 0, sizeof var);
243 memset(pre_mul, 0, sizeof pre_mul);
250 memset(rgb_cam, 0, sizeof rgb_cam);
279 aber[0] = aber[1] = aber[2] = aber[3] = 1;
280 gamm[0] = 0.45; gamm[1] = 4.5; gamm[2] = 0;
281 gamm[3] = 0; gamm[4] = 0; gamm[5] = 0;
292 use_camera_matrix = 1;
298 greybox[0] = 0; greybox[1] = 0;
299 greybox[2] = UINT_MAX; greybox[3] = UINT_MAX;
301 gbh_bitbuf = 0; gbh_vbits = 0; gbh_reset = 0;
302 ph1_bitbuf = 0; ph1_vbits = 0;
304 ZERO(sony_pad); sony_p = 0;
306 ZERO(clb_cbrt); ZERO(clb_xyz_cam);
307 ZERO(pana_buf); pana_vbits = 0;
311 char *my_memmem (char *haystack, size_t haystacklen,
312 char *needle, size_t needlelen)
315 for (c = haystack; c <= haystack + haystacklen - needlelen; c++)
316 if (!memcmp (c, needle, needlelen))
320 #define memmem my_memmem
321 char *my_strcasestr (char *haystack, const char *needle)
324 for (c = haystack; *c; c++)
325 if (!strncasecmp(c, needle, strlen(needle)))
329 #define strcasestr my_strcasestr
332 void CLASS merror (void *ptr, const char *where)
335 fprintf (stderr,_("%s: Out of memory in %s\n"), ifname, where);
336 longjmp (failure, 1);
342 fprintf (stderr, "%s: ", ifname);
344 fprintf (stderr,_("Unexpected end of file\n"));
346 fprintf (stderr,_("Corrupt data near 0x%jx\n"), (INT64) ftello(ifp));
351 ushort CLASS sget2 (uchar *s)
353 if (order == 0x4949) /* "II" means little-endian */
354 return s[0] | s[1] << 8;
355 else /* "MM" means big-endian */
356 return s[0] << 8 | s[1];
361 uchar str[2] = { 0xff,0xff };
362 fread (str, 1, 2, ifp);
366 unsigned CLASS sget4 (uchar *s)
369 return s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24;
371 return s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3];
373 #define sget4(s) sget4((uchar *)s)
375 unsigned CLASS get4()
377 uchar str[4] = { 0xff,0xff,0xff,0xff };
378 fread (str, 1, 4, ifp);
382 unsigned CLASS getint (int type)
384 return type == 3 ? get2() : get4();
387 float CLASS int_to_float (int i)
389 union { int i; float f; } u;
394 double CLASS getreal (int type)
396 union { char c[8]; double d; } u;
400 case 3: return (unsigned short) get2();
401 case 4: return (unsigned int) get4();
402 case 5: u.d = (unsigned int) get4();
403 return u.d / (unsigned int) get4();
404 case 8: return (signed short) get2();
405 case 9: return (signed int) get4();
406 case 10: u.d = (signed int) get4();
407 return u.d / (signed int) get4();
408 case 11: return int_to_float (get4());
410 rev = 7 * ((order == 0x4949) == (ntohs(0x1234) == 0x1234));
411 for (i=0; i < 8; i++)
412 u.c[i ^ rev] = fgetc(ifp);
414 default: return fgetc(ifp);
418 void CLASS read_shorts (ushort *pixel, int count)
420 if (fread (pixel, 2, count, ifp) < count) derror();
421 if ((order == 0x4949) == (ntohs(0x1234) == 0x1234))
422 swab (pixel, pixel, count*2);
425 void CLASS cubic_spline (const int *x_, const int *y_, const int len)
427 float **A, *b, *c, *d, *x, *y;
430 A = (float **) calloc (((2*len + 4)*sizeof **A + sizeof *A), 2*len);
432 A[0] = (float *) (A + 2*len);
433 for (i = 1; i < 2*len; i++)
434 A[i] = A[0] + 2*len*i;
435 y = len + (x = i + (d = i + (c = i + (b = A[0] + i*i))));
436 for (i = 0; i < len; i++) {
437 x[i] = x_[i] / 65535.0;
438 y[i] = y_[i] / 65535.0;
440 for (i = len-1; i > 0; i--) {
441 b[i] = (y[i] - y[i-1]) / (x[i] - x[i-1]);
442 d[i-1] = x[i] - x[i-1];
444 for (i = 1; i < len-1; i++) {
445 A[i][i] = 2 * (d[i-1] + d[i]);
450 A[i][len-1] = 6 * (b[i+1] - b[i]);
452 for(i = 1; i < len-2; i++) {
453 float v = A[i+1][i] / A[i][i];
454 for(j = 1; j <= len-1; j++)
455 A[i+1][j] -= v * A[i][j];
457 for(i = len-2; i > 0; i--) {
459 for(j = i; j <= len-2; j++)
461 c[i] = (A[i][len-1] - acc) / A[i][i];
463 for (i = 0; i < 0x10000; i++) {
464 float x_out = (float)(i / 65535.0);
466 for (j = 0; j < len-1; j++) {
467 if (x[j] <= x_out && x_out <= x[j+1]) {
468 float v = x_out - x[j];
470 ((y[j+1] - y[j]) / d[j] - (2 * d[j] * c[j] + c[j+1] * d[j])/6) * v
471 + (c[j] * 0.5) * v*v + ((c[j+1] - c[j]) / (6 * d[j])) * v*v*v;
474 curve[i] = y_out < 0.0 ? 0 : (y_out >= 1.0 ? 65535 :
475 (ushort)(y_out * 65535.0 + 0.5));
480 void CLASS canon_600_fixed_wb (int temp)
482 static const short mul[4][5] = {
483 { 667, 358,397,565,452 },
484 { 731, 390,367,499,517 },
485 { 1119, 396,348,448,537 },
486 { 1399, 485,431,508,688 } };
491 if (*mul[lo] <= temp) break;
492 for (hi=0; hi < 3; hi++)
493 if (*mul[hi] >= temp) break;
495 frac = (float) (temp - *mul[lo]) / (*mul[hi] - *mul[lo]);
496 for (i=1; i < 5; i++)
497 pre_mul[i-1] = 1 / (frac * mul[hi][i] + (1-frac) * mul[lo][i]);
500 /* Return values: 0 = white 1 = near white 2 = not white */
501 int CLASS canon_600_color (int ratio[2], int mar)
503 int clipped=0, target, miss;
507 { ratio[1] = -104; clipped = 1; }
509 { ratio[1] = 12; clipped = 1; }
511 if (ratio[1] < -264 || ratio[1] > 461) return 2;
513 { ratio[1] = -50; clipped = 1; }
515 { ratio[1] = 307; clipped = 1; }
517 target = flash_used || ratio[1] < 197
518 ? -38 - (398 * ratio[1] >> 10)
519 : -123 + (48 * ratio[1] >> 10);
520 if (target - mar <= ratio[0] &&
521 target + 20 >= ratio[0] && !clipped) return 0;
522 miss = target - ratio[0];
523 if (abs(miss) >= mar*4) return 2;
524 if (miss < -20) miss = -20;
525 if (miss > mar) miss = mar;
526 ratio[0] = target - miss;
530 void CLASS canon_600_auto_wb()
532 int mar, row, col, i, j, st, count[] = { 0,0 };
533 int test[8], total[2][8], ratio[2][2], stat[2];
535 memset (&total, 0, sizeof total);
537 if (i < 10) mar = 150;
538 else if (i > 12) mar = 20;
539 else mar = 280 - 20 * i;
540 if (flash_used) mar = 80;
541 for (row=14; row < height-14; row+=4)
542 for (col=10; col < width; col+=2) {
543 for (i=0; i < 8; i++)
544 test[(i & 4) + FC(row+(i >> 1),col+(i & 1))] =
545 BAYER(row+(i >> 1),col+(i & 1));
546 for (i=0; i < 8; i++)
547 if (test[i] < 150 || test[i] > 1500) goto next;
548 for (i=0; i < 4; i++)
549 if (abs(test[i] - test[i+4]) > 50) goto next;
550 for (i=0; i < 2; i++) {
551 for (j=0; j < 4; j+=2)
552 ratio[i][j >> 1] = ((test[i*4+j+1]-test[i*4+j]) << 10) / test[i*4+j];
553 stat[i] = canon_600_color (ratio[i], mar);
555 if ((st = stat[0] | stat[1]) > 1) goto next;
556 for (i=0; i < 2; i++)
558 for (j=0; j < 2; j++)
559 test[i*4+j*2+1] = test[i*4+j*2] * (0x400 + ratio[i][j]) >> 10;
560 for (i=0; i < 8; i++)
561 total[st][i] += test[i];
565 if (count[0] | count[1]) {
566 st = count[0]*200 < count[1];
567 for (i=0; i < 4; i++)
568 pre_mul[i] = 1.0 / (total[st][i] + total[st][i+4]);
572 void CLASS canon_600_coeff()
574 static const short table[6][12] = {
575 { -190,702,-1878,2390, 1861,-1349,905,-393, -432,944,2617,-2105 },
576 { -1203,1715,-1136,1648, 1388,-876,267,245, -1641,2153,3921,-3409 },
577 { -615,1127,-1563,2075, 1437,-925,509,3, -756,1268,2519,-2007 },
578 { -190,702,-1886,2398, 2153,-1641,763,-251, -452,964,3040,-2528 },
579 { -190,702,-1878,2390, 1861,-1349,905,-393, -432,944,2617,-2105 },
580 { -807,1319,-1785,2297, 1388,-876,769,-257, -230,742,2067,-1555 } };
584 mc = pre_mul[1] / pre_mul[2];
585 yc = pre_mul[3] / pre_mul[2];
586 if (mc > 1 && mc <= 1.28 && yc < 0.8789) t=1;
587 if (mc > 1.28 && mc <= 2) {
588 if (yc < 0.8789) t=3;
589 else if (yc <= 2) t=4;
592 for (raw_color = i=0; i < 3; i++)
593 FORCC rgb_cam[i][c] = table[t][i*4 + c] / 1024.0;
596 void CLASS canon_600_load_raw()
598 uchar data[1120], *dp;
602 for (irow=row=0; irow < height; irow++) {
603 if (fread (data, 1, 1120, ifp) < 1120) derror();
604 pix = raw_image + row*raw_width;
605 for (dp=data; dp < data+1120; dp+=10, pix+=8) {
606 pix[0] = (dp[0] << 2) + (dp[1] >> 6 );
607 pix[1] = (dp[2] << 2) + (dp[1] >> 4 & 3);
608 pix[2] = (dp[3] << 2) + (dp[1] >> 2 & 3);
609 pix[3] = (dp[4] << 2) + (dp[1] & 3);
610 pix[4] = (dp[5] << 2) + (dp[9] & 3);
611 pix[5] = (dp[6] << 2) + (dp[9] >> 2 & 3);
612 pix[6] = (dp[7] << 2) + (dp[9] >> 4 & 3);
613 pix[7] = (dp[8] << 2) + (dp[9] >> 6 );
615 if ((row+=2) > height) row = 1;
619 void CLASS canon_600_correct()
622 static const short mul[4][2] =
623 { { 1141,1145 }, { 1128,1109 }, { 1178,1149 }, { 1128,1109 } };
625 for (row=0; row < height; row++)
626 for (col=0; col < width; col++) {
627 if ((val = BAYER(row,col) - black) < 0) val = 0;
628 val = val * mul[row & 3][col & 1] >> 9;
629 BAYER(row,col) = val;
631 canon_600_fixed_wb(1311);
634 maximum = (0x3ff - black) * 1109 >> 9;
638 int CLASS canon_s2is()
642 for (row=0; row < 100; row++) {
643 fseek (ifp, row*3340 + 3284, SEEK_SET);
644 if (getc(ifp) > 15) return 1;
649 unsigned CLASS getbithuff (int nbits, ushort *huff)
655 if (nbits > 25) return 0;
657 return gbh_bitbuf = gbh_vbits = gbh_reset = 0;
658 if (nbits == 0 || gbh_vbits < 0) return 0;
659 bitbuf = gbh_bitbuf; vbits = gbh_vbits; reset = gbh_reset;
660 while (!reset && vbits < nbits && (c = fgetc(ifp)) != EOF &&
661 !(reset = zero_after_ff && c == 0xff && fgetc(ifp))) {
662 bitbuf = (bitbuf << 8) + (uchar) c;
665 c = bitbuf << (32-vbits) >> (32-nbits);
667 vbits -= huff[c] >> 8;
671 if (vbits < 0) derror();
672 gbh_bitbuf = bitbuf; gbh_vbits = vbits; gbh_reset = reset;
676 #define getbits(n) getbithuff(n,0)
677 #define gethuff(h) getbithuff(*h,h+1)
680 Construct a decode tree according the specification in *source.
681 The first 16 bytes specify how many codes should be 1-bit, 2-bit
682 3-bit, etc. Bytes after that are the leaf values.
684 For example, if the source is
686 { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0,
687 0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff },
705 ushort * CLASS make_decoder_ref (const uchar **source)
707 int max, len, h, i, j;
711 count = (*source += 16) - 17;
712 for (max=16; max && !count[max]; max--);
713 huff = (ushort *) calloc (1 + (1 << max), sizeof *huff);
714 merror (huff, "make_decoder()");
716 for (h=len=1; len <= max; len++)
717 for (i=0; i < count[len]; i++, ++*source)
718 for (j=0; j < 1 << (max-len); j++)
720 huff[h++] = len << 8 | **source;
724 ushort * CLASS make_decoder (const uchar *source)
726 return make_decoder_ref (&source);
729 void CLASS crw_init_tables (unsigned table, ushort *huff[2])
731 static const uchar first_tree[3][29] = {
732 { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0,
733 0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff },
734 { 0,2,2,3,1,1,1,1,2,0,0,0,0,0,0,0,
735 0x03,0x02,0x04,0x01,0x05,0x00,0x06,0x07,0x09,0x08,0x0a,0x0b,0xff },
736 { 0,0,6,3,1,1,2,0,0,0,0,0,0,0,0,0,
737 0x06,0x05,0x07,0x04,0x08,0x03,0x09,0x02,0x00,0x0a,0x01,0x0b,0xff },
739 static const uchar second_tree[3][180] = {
740 { 0,2,2,2,1,4,2,1,2,5,1,1,0,0,0,139,
741 0x03,0x04,0x02,0x05,0x01,0x06,0x07,0x08,
742 0x12,0x13,0x11,0x14,0x09,0x15,0x22,0x00,0x21,0x16,0x0a,0xf0,
743 0x23,0x17,0x24,0x31,0x32,0x18,0x19,0x33,0x25,0x41,0x34,0x42,
744 0x35,0x51,0x36,0x37,0x38,0x29,0x79,0x26,0x1a,0x39,0x56,0x57,
745 0x28,0x27,0x52,0x55,0x58,0x43,0x76,0x59,0x77,0x54,0x61,0xf9,
746 0x71,0x78,0x75,0x96,0x97,0x49,0xb7,0x53,0xd7,0x74,0xb6,0x98,
747 0x47,0x48,0x95,0x69,0x99,0x91,0xfa,0xb8,0x68,0xb5,0xb9,0xd6,
748 0xf7,0xd8,0x67,0x46,0x45,0x94,0x89,0xf8,0x81,0xd5,0xf6,0xb4,
749 0x88,0xb1,0x2a,0x44,0x72,0xd9,0x87,0x66,0xd4,0xf5,0x3a,0xa7,
750 0x73,0xa9,0xa8,0x86,0x62,0xc7,0x65,0xc8,0xc9,0xa1,0xf4,0xd1,
751 0xe9,0x5a,0x92,0x85,0xa6,0xe7,0x93,0xe8,0xc1,0xc6,0x7a,0x64,
752 0xe1,0x4a,0x6a,0xe6,0xb3,0xf1,0xd3,0xa5,0x8a,0xb2,0x9a,0xba,
753 0x84,0xa4,0x63,0xe5,0xc5,0xf3,0xd2,0xc4,0x82,0xaa,0xda,0xe4,
754 0xf2,0xca,0x83,0xa3,0xa2,0xc3,0xea,0xc2,0xe2,0xe3,0xff,0xff },
755 { 0,2,2,1,4,1,4,1,3,3,1,0,0,0,0,140,
756 0x02,0x03,0x01,0x04,0x05,0x12,0x11,0x06,
757 0x13,0x07,0x08,0x14,0x22,0x09,0x21,0x00,0x23,0x15,0x31,0x32,
758 0x0a,0x16,0xf0,0x24,0x33,0x41,0x42,0x19,0x17,0x25,0x18,0x51,
759 0x34,0x43,0x52,0x29,0x35,0x61,0x39,0x71,0x62,0x36,0x53,0x26,
760 0x38,0x1a,0x37,0x81,0x27,0x91,0x79,0x55,0x45,0x28,0x72,0x59,
761 0xa1,0xb1,0x44,0x69,0x54,0x58,0xd1,0xfa,0x57,0xe1,0xf1,0xb9,
762 0x49,0x47,0x63,0x6a,0xf9,0x56,0x46,0xa8,0x2a,0x4a,0x78,0x99,
763 0x3a,0x75,0x74,0x86,0x65,0xc1,0x76,0xb6,0x96,0xd6,0x89,0x85,
764 0xc9,0xf5,0x95,0xb4,0xc7,0xf7,0x8a,0x97,0xb8,0x73,0xb7,0xd8,
765 0xd9,0x87,0xa7,0x7a,0x48,0x82,0x84,0xea,0xf4,0xa6,0xc5,0x5a,
766 0x94,0xa4,0xc6,0x92,0xc3,0x68,0xb5,0xc8,0xe4,0xe5,0xe6,0xe9,
767 0xa2,0xa3,0xe3,0xc2,0x66,0x67,0x93,0xaa,0xd4,0xd5,0xe7,0xf8,
768 0x88,0x9a,0xd7,0x77,0xc4,0x64,0xe2,0x98,0xa5,0xca,0xda,0xe8,
769 0xf3,0xf6,0xa9,0xb2,0xb3,0xf2,0xd2,0x83,0xba,0xd3,0xff,0xff },
770 { 0,0,6,2,1,3,3,2,5,1,2,2,8,10,0,117,
771 0x04,0x05,0x03,0x06,0x02,0x07,0x01,0x08,
772 0x09,0x12,0x13,0x14,0x11,0x15,0x0a,0x16,0x17,0xf0,0x00,0x22,
773 0x21,0x18,0x23,0x19,0x24,0x32,0x31,0x25,0x33,0x38,0x37,0x34,
774 0x35,0x36,0x39,0x79,0x57,0x58,0x59,0x28,0x56,0x78,0x27,0x41,
775 0x29,0x77,0x26,0x42,0x76,0x99,0x1a,0x55,0x98,0x97,0xf9,0x48,
776 0x54,0x96,0x89,0x47,0xb7,0x49,0xfa,0x75,0x68,0xb6,0x67,0x69,
777 0xb9,0xb8,0xd8,0x52,0xd7,0x88,0xb5,0x74,0x51,0x46,0xd9,0xf8,
778 0x3a,0xd6,0x87,0x45,0x7a,0x95,0xd5,0xf6,0x86,0xb4,0xa9,0x94,
779 0x53,0x2a,0xa8,0x43,0xf5,0xf7,0xd4,0x66,0xa7,0x5a,0x44,0x8a,
780 0xc9,0xe8,0xc8,0xe7,0x9a,0x6a,0x73,0x4a,0x61,0xc7,0xf4,0xc6,
781 0x65,0xe9,0x72,0xe6,0x71,0x91,0x93,0xa6,0xda,0x92,0x85,0x62,
782 0xf3,0xc5,0xb2,0xa4,0x84,0xba,0x64,0xa5,0xb3,0xd2,0x81,0xe5,
783 0xd3,0xaa,0xc4,0xca,0xf2,0xb1,0xe4,0xd1,0x83,0x63,0xea,0xc3,
784 0xe2,0x82,0xf1,0xa3,0xc2,0xa1,0xc1,0xe3,0xa2,0xe1,0xff,0xff }
786 if (table > 2) table = 2;
787 huff[0] = make_decoder ( first_tree[table]);
788 huff[1] = make_decoder (second_tree[table]);
792 Return 0 if the image starts with compressed data,
793 1 if it starts with uncompressed low-order bits.
795 In Canon compressed data, 0xff is always followed by 0x00.
797 int CLASS canon_has_lowbits()
802 fseek (ifp, 0, SEEK_SET);
803 fread (test, 1, sizeof test, ifp);
804 for (i=540; i < sizeof test - 1; i++)
805 if (test[i] == 0xff) {
806 if (test[i+1]) return 1;
812 void CLASS canon_load_raw()
814 ushort *pixel, *prow, *huff[2];
815 int nblocks, lowbits, i, c, row, r, save, val;
816 int block, diffbuf[64], leaf, len, diff, carry=0, pnum=0, base[2];
818 crw_init_tables (tiff_compress, huff);
819 lowbits = canon_has_lowbits();
820 if (!lowbits) maximum = 0x3ff;
821 fseek (ifp, 540 + lowbits*raw_height*raw_width/4, SEEK_SET);
824 for (row=0; row < raw_height; row+=8) {
825 pixel = raw_image + row*raw_width;
826 nblocks = MIN (8, raw_height-row) * raw_width >> 6;
827 for (block=0; block < nblocks; block++) {
828 memset (diffbuf, 0, sizeof diffbuf);
829 for (i=0; i < 64; i++ ) {
830 leaf = gethuff(huff[i > 0]);
831 if (leaf == 0 && i) break;
832 if (leaf == 0xff) continue;
835 if (len == 0) continue;
837 if ((diff & (1 << (len-1))) == 0)
838 diff -= (1 << len) - 1;
839 if (i < 64) diffbuf[i] = diff;
843 for (i=0; i < 64; i++ ) {
844 if (pnum++ % raw_width == 0)
845 base[0] = base[1] = 512;
846 if ((pixel[(block << 6) + i] = base[i & 1] += diffbuf[i]) >> 10)
852 fseek (ifp, 26 + row*raw_width/4, SEEK_SET);
853 for (prow=pixel, i=0; i < raw_width*2; i++) {
855 for (r=0; r < 8; r+=2, prow++) {
856 val = (*prow << 2) + ((c >> r) & 3);
857 if (raw_width == 2672 && val < 512) val += 2;
861 fseek (ifp, save, SEEK_SET);
864 FORC(2) free (huff[c]);
868 int algo, bits, high, wide, clrs, sraw, psv, restart, vpred[6];
869 ushort quant[64], idct[64], *huff[20], *free[20], *row;
872 int CLASS ljpeg_start (struct jhead *jh, int info_only)
878 memset (jh, 0, sizeof *jh);
879 jh->restart = INT_MAX;
880 if ((fgetc(ifp),fgetc(ifp)) != 0xd8) return 0;
882 if (!fread (data, 2, 2, ifp)) return 0;
883 tag = data[0] << 8 | data[1];
884 len = (data[2] << 8 | data[3]) - 2;
885 if (tag <= 0xff00) return 0;
886 fread (data, 1, len, ifp);
889 jh->sraw = ((data[7] >> 4) * (data[7] & 15) - 1) & 3;
892 jh->algo = tag & 0xff;
894 jh->high = data[1] << 8 | data[2];
895 jh->wide = data[3] << 8 | data[4];
896 jh->clrs = data[5] + jh->sraw;
897 if (len == 9 && !dng_version) getc(ifp);
900 if (info_only) break;
901 for (dp = data; dp < data+len && !((c = *dp++) & -20); )
902 jh->free[c] = jh->huff[c] = make_decoder_ref (&dp);
905 jh->psv = data[1+data[0]*2];
906 jh->bits -= data[3+data[0]*2] & 15;
909 FORC(64) jh->quant[c] = data[c*2+1] << 8 | data[c*2+2];
912 jh->restart = data[0] << 8 | data[1];
914 } while (tag != 0xffda);
915 if (jh->bits > 16 || jh->clrs > 6 ||
916 !jh->bits || !jh->high || !jh->wide || !jh->clrs) return 0;
917 if (info_only) return 1;
918 if (!jh->huff[0]) return 0;
919 FORC(19) if (!jh->huff[c+1]) jh->huff[c+1] = jh->huff[c];
921 FORC(4) jh->huff[2+c] = jh->huff[1];
922 FORC(jh->sraw) jh->huff[1+c] = jh->huff[0];
924 jh->row = (ushort *) calloc (jh->wide*jh->clrs, 4);
925 merror (jh->row, "ljpeg_start()");
926 return zero_after_ff = 1;
929 void CLASS ljpeg_end (struct jhead *jh)
932 FORC4 if (jh->free[c]) free (jh->free[c]);
936 int CLASS ljpeg_diff (ushort *huff)
941 if (len == 16 && (!dng_version || dng_version >= 0x1010000))
944 if ((diff & (1 << (len-1))) == 0)
945 diff -= (1 << len) - 1;
949 ushort * CLASS ljpeg_row (int jrow, struct jhead *jh)
951 int col, c, diff, pred, spred=0;
952 ushort mark=0, *row[3];
954 if (jrow * jh->wide % jh->restart == 0) {
955 FORC(6) jh->vpred[c] = 1 << (jh->bits-1);
957 fseek (ifp, -2, SEEK_CUR);
958 do mark = (mark << 8) + (c = fgetc(ifp));
959 while (c != EOF && mark >> 4 != 0xffd);
963 FORC3 row[c] = jh->row + jh->wide*jh->clrs*((jrow+c) & 1);
964 for (col=0; col < jh->wide; col++)
966 diff = ljpeg_diff (jh->huff[c]);
967 if (jh->sraw && c <= jh->sraw && (col | c))
969 else if (col) pred = row[0][-jh->clrs];
970 else pred = (jh->vpred[c] += diff) - diff;
971 if (jrow && col) switch (jh->psv) {
973 case 2: pred = row[1][0]; break;
974 case 3: pred = row[1][-jh->clrs]; break;
975 case 4: pred = pred + row[1][0] - row[1][-jh->clrs]; break;
976 case 5: pred = pred + ((row[1][0] - row[1][-jh->clrs]) >> 1); break;
977 case 6: pred = row[1][0] + ((pred - row[1][-jh->clrs]) >> 1); break;
978 case 7: pred = (pred + row[1][0]) >> 1; break;
981 if ((**row = pred + diff) >> jh->bits) derror();
982 if (c <= jh->sraw) spred = **row;
988 void CLASS lossless_jpeg_load_raw()
990 int jwide, jrow, jcol, val, jidx, i, j, row=0, col=0;
994 if (!ljpeg_start (&jh, 0)) return;
995 jwide = jh.wide * jh.clrs;
997 for (jrow=0; jrow < jh.high; jrow++) {
998 rp = ljpeg_row (jrow, &jh);
1000 row = jrow & 1 ? height-1-jrow/2 : jrow/2;
1001 for (jcol=0; jcol < jwide; jcol++) {
1004 jidx = jrow*jwide + jcol;
1005 i = jidx / (cr2_slice[1]*raw_height);
1006 if ((j = i >= cr2_slice[0]))
1008 jidx -= i * (cr2_slice[1]*raw_height);
1009 row = jidx / cr2_slice[1+j];
1010 col = jidx % cr2_slice[1+j] + i*cr2_slice[1];
1012 if (raw_width == 3984 && (col -= 2) < 0)
1013 col += (row--,raw_width);
1014 if ((unsigned) row < raw_height) RAW(row,col) = val;
1015 if (++col >= raw_width)
1022 void CLASS canon_sraw_load_raw()
1025 short *rp=0, (*ip)[4];
1026 int jwide, slice, scol, ecol, row, col, jrow=0, jcol=0, pix[3], c;
1027 int v[3]={0,0,0}, ver, hue;
1030 if (!ljpeg_start (&jh, 0) || jh.clrs < 4) return;
1031 jwide = (jh.wide >>= 1) * jh.clrs;
1033 for (ecol=slice=0; slice <= cr2_slice[0]; slice++) {
1035 ecol += cr2_slice[1] * 2 / jh.clrs;
1036 if (!cr2_slice[0] || ecol > raw_width-1) ecol = raw_width & -2;
1037 for (row=0; row < height; row += (jh.clrs >> 1) - 1) {
1038 ip = (short (*)[4]) image + row*width;
1039 for (col=scol; col < ecol; col+=2, jcol+=jh.clrs) {
1040 if ((jcol %= jwide) == 0)
1041 rp = (short *) ljpeg_row (jrow++, &jh);
1042 if (col >= width) continue;
1044 ip[col + (c >> 1)*width + (c & 1)][0] = rp[jcol+c];
1045 ip[col][1] = rp[jcol+jh.clrs-2] - 16384;
1046 ip[col][2] = rp[jcol+jh.clrs-1] - 16384;
1050 for (cp=model2; *cp && !isdigit(*cp); cp++);
1051 sscanf (cp, "%d.%d.%d", v, v+1, v+2);
1052 ver = (v[0]*1000 + v[1])*1000 + v[2];
1053 hue = (jh.sraw+1) << 2;
1054 if (unique_id >= 0x80000281 || (unique_id == 0x80000218 && ver > 1000006))
1056 ip = (short (*)[4]) image;
1058 for (row=0; row < height; row++, ip+=width) {
1059 if (row & (jh.sraw >> 1)) {
1060 for (col=0; col < width; col+=2)
1061 for (c=1; c < 3; c++)
1062 if (row == height-1)
1063 ip[col][c] = ip[col-width][c];
1064 else ip[col][c] = (ip[col-width][c] + ip[col+width][c] + 1) >> 1;
1066 for (col=1; col < width; col+=2)
1067 for (c=1; c < 3; c++)
1069 ip[col][c] = ip[col-1][c];
1070 else ip[col][c] = (ip[col-1][c] + ip[col+1][c] + 1) >> 1;
1072 for ( ; rp < ip[0]; rp+=4) {
1073 if (unique_id == 0x80000218 ||
1074 unique_id == 0x80000250 ||
1075 unique_id == 0x80000261 ||
1076 unique_id == 0x80000281 ||
1077 unique_id == 0x80000287) {
1078 rp[1] = (rp[1] << 2) + hue;
1079 rp[2] = (rp[2] << 2) + hue;
1080 pix[0] = rp[0] + (( 50*rp[1] + 22929*rp[2]) >> 14);
1081 pix[1] = rp[0] + ((-5640*rp[1] - 11751*rp[2]) >> 14);
1082 pix[2] = rp[0] + ((29040*rp[1] - 101*rp[2]) >> 14);
1084 if (unique_id < 0x80000218) rp[0] -= 512;
1085 pix[0] = rp[0] + rp[2];
1086 pix[2] = rp[0] + rp[1];
1087 pix[1] = rp[0] + ((-778*rp[1] - (rp[2] << 11)) >> 12);
1089 FORC3 rp[c] = CLIP(pix[c] * sraw_mul[c] >> 10);
1095 void CLASS adobe_copy_pixel (unsigned row, unsigned col, ushort **rp)
1099 if (tiff_samples == 2 && shot_select) (*rp)++;
1101 if (row < raw_height && col < raw_width)
1102 RAW(row,col) = curve[**rp];
1103 *rp += tiff_samples;
1105 if (row < height && col < width)
1107 image[row*width+col][c] = curve[(*rp)[c]];
1108 *rp += tiff_samples;
1110 if (tiff_samples == 2 && shot_select) (*rp)--;
1113 void CLASS ljpeg_idct (struct jhead *jh)
1115 int c, i, j, len, skip, coef;
1116 float work[3][8][8], *cs = ljpeg_cs;
1117 static const uchar zigzag[80] =
1118 { 0, 1, 8,16, 9, 2, 3,10,17,24,32,25,18,11, 4, 5,12,19,26,33,
1119 40,48,41,34,27,20,13, 6, 7,14,21,28,35,42,49,56,57,50,43,36,
1120 29,22,15,23,30,37,44,51,58,59,52,45,38,31,39,46,53,60,61,54,
1121 47,55,62,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63 };
1124 FORC(106) cs[c] = cos((c & 31)*M_PI/16)/2;
1125 memset (work, 0, sizeof work);
1126 work[0][0][0] = jh->vpred[0] += ljpeg_diff (jh->huff[0]) * jh->quant[0];
1127 for (i=1; i < 64; i++ ) {
1128 len = gethuff (jh->huff[16]);
1129 i += skip = len >> 4;
1130 if (!(len &= 15) && skip < 15) break;
1131 coef = getbits(len);
1132 if ((coef & (1 << (len-1))) == 0)
1133 coef -= (1 << len) - 1;
1134 ((float *)work)[zigzag[i]] = coef * jh->quant[i];
1136 FORC(8) work[0][0][c] *= M_SQRT1_2;
1137 FORC(8) work[0][c][0] *= M_SQRT1_2;
1138 for (i=0; i < 8; i++)
1139 for (j=0; j < 8; j++)
1140 FORC(8) work[1][i][j] += work[0][i][c] * cs[(j*2+1)*c];
1141 for (i=0; i < 8; i++)
1142 for (j=0; j < 8; j++)
1143 FORC(8) work[2][i][j] += work[1][c][j] * cs[(i*2+1)*c];
1145 FORC(64) jh->idct[c] = CLIP(((float *)work[2])[c]+0.5);
1148 void CLASS lossless_dng_load_raw()
1150 unsigned save, trow=0, tcol=0, jwide, jrow, jcol, row, col, i, j;
1154 while (trow < raw_height) {
1156 if (tile_length < INT_MAX)
1157 fseek (ifp, get4(), SEEK_SET);
1158 if (!ljpeg_start (&jh, 0)) break;
1160 if (filters) jwide *= jh.clrs;
1161 jwide /= MIN (is_raw, tiff_samples);
1164 jh.vpred[0] = 16384;
1166 for (jrow=0; jrow+7 < jh.high; jrow += 8) {
1167 for (jcol=0; jcol+7 < jh.wide; jcol += 8) {
1170 row = trow + jcol/tile_width + jrow*2;
1171 col = tcol + jcol%tile_width;
1172 for (i=0; i < 16; i+=2)
1173 for (j=0; j < 8; j++)
1174 adobe_copy_pixel (row+i, col+j, &rp);
1179 for (row=col=jrow=0; jrow < jh.high; jrow++) {
1180 rp = ljpeg_row (jrow, &jh);
1181 for (jcol=0; jcol < jwide; jcol++) {
1182 adobe_copy_pixel (trow+row, tcol+col, &rp);
1183 if (++col >= tile_width || col >= raw_width)
1184 row += 1 + (col = 0);
1188 fseek (ifp, save+4, SEEK_SET);
1189 if ((tcol += tile_width) >= raw_width)
1190 trow += tile_length + (tcol = 0);
1195 void CLASS packed_dng_load_raw()
1200 pixel = (ushort *) calloc (raw_width, tiff_samples*sizeof *pixel);
1201 merror (pixel, "packed_dng_load_raw()");
1202 for (row=0; row < raw_height; row++) {
1204 read_shorts (pixel, raw_width * tiff_samples);
1207 for (col=0; col < raw_width * tiff_samples; col++)
1208 pixel[col] = getbits(tiff_bps);
1210 for (rp=pixel, col=0; col < raw_width; col++)
1211 adobe_copy_pixel (row, col, &rp);
1216 void CLASS pentax_load_raw()
1218 ushort bit[2][15], huff[4097];
1219 int dep, row, col, diff, c, i;
1220 ushort vpred[2][2] = {{0,0},{0,0}}, hpred[2];
1222 fseek (ifp, meta_offset, SEEK_SET);
1223 dep = (get2() + 12) & 15;
1224 fseek (ifp, 12, SEEK_CUR);
1225 FORC(dep) bit[0][c] = get2();
1226 FORC(dep) bit[1][c] = fgetc(ifp);
1228 for (i=bit[0][c]; i <= ((bit[0][c]+(4096 >> bit[1][c])-1) & 4095); )
1229 huff[++i] = bit[1][c] << 8 | c;
1231 fseek (ifp, data_offset, SEEK_SET);
1233 for (row=0; row < raw_height; row++)
1234 for (col=0; col < raw_width; col++) {
1235 diff = ljpeg_diff (huff);
1236 if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
1237 else hpred[col & 1] += diff;
1238 RAW(row,col) = hpred[col & 1];
1239 if (hpred[col & 1] >> tiff_bps) derror();
1243 void CLASS nikon_load_raw()
1245 static const uchar nikon_tree[][32] = {
1246 { 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0, /* 12-bit lossy */
1247 5,4,3,6,2,7,1,0,8,9,11,10,12 },
1248 { 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0, /* 12-bit lossy after split */
1249 0x39,0x5a,0x38,0x27,0x16,5,4,3,2,1,0,11,12,12 },
1250 { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0, /* 12-bit lossless */
1251 5,4,6,3,7,2,8,1,9,0,10,11,12 },
1252 { 0,1,4,3,1,1,1,1,1,2,0,0,0,0,0,0, /* 14-bit lossy */
1253 5,6,4,7,8,3,9,2,1,0,10,11,12,13,14 },
1254 { 0,1,5,1,1,1,1,1,1,1,2,0,0,0,0,0, /* 14-bit lossy after split */
1255 8,0x5c,0x4b,0x3a,0x29,7,6,5,4,3,2,1,0,13,14 },
1256 { 0,1,4,2,2,3,1,2,0,0,0,0,0,0,0,0, /* 14-bit lossless */
1257 7,6,8,5,9,4,10,3,11,12,2,0,1,13,14 } };
1258 ushort *huff, ver0, ver1, vpred[2][2], hpred[2], csize;
1259 int i, min, max, step=0, tree=0, split=0, row, col, len, shl, diff;
1261 fseek (ifp, meta_offset, SEEK_SET);
1264 if (ver0 == 0x49 || ver1 == 0x58)
1265 fseek (ifp, 2110, SEEK_CUR);
1266 if (ver0 == 0x46) tree = 2;
1267 if (tiff_bps == 14) tree += 3;
1268 read_shorts (vpred[0], 4);
1269 max = 1 << tiff_bps & 0x7fff;
1270 if ((csize = get2()) > 1)
1271 step = max / (csize-1);
1272 if (ver0 == 0x44 && ver1 == 0x20 && step > 0) {
1273 for (i=0; i < csize; i++)
1274 curve[i*step] = get2();
1275 for (i=0; i < max; i++)
1276 curve[i] = ( curve[i-i%step]*(step-i%step) +
1277 curve[i-i%step+step]*(i%step) ) / step;
1278 fseek (ifp, meta_offset+562, SEEK_SET);
1280 } else if (ver0 != 0x46 && csize <= 0x4001)
1281 read_shorts (curve, max=csize);
1282 while (curve[max-2] == curve[max-1]) max--;
1283 huff = make_decoder (nikon_tree[tree]);
1284 fseek (ifp, data_offset, SEEK_SET);
1286 for (min=row=0; row < height; row++) {
1287 if (split && row == split) {
1289 huff = make_decoder (nikon_tree[tree+1]);
1290 max += (min = 16) << 1;
1292 for (col=0; col < raw_width; col++) {
1296 diff = ((getbits(len-shl) << 1) + 1) << shl >> 1;
1297 if ((diff & (1 << (len-1))) == 0)
1298 diff -= (1 << len) - !shl;
1299 if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
1300 else hpred[col & 1] += diff;
1301 if ((ushort)(hpred[col & 1] + min) >= max) derror();
1302 RAW(row,col) = curve[LIM((short)hpred[col & 1],0,0x3fff)];
1308 void CLASS nikon_yuv_load_raw()
1310 int row, col, yuv[4], rgb[3], b, c;
1313 for (row=0; row < raw_height; row++)
1314 for (col=0; col < raw_width; col++) {
1315 if (!(b = col & 1)) {
1317 FORC(6) bitbuf |= (UINT64) fgetc(ifp) << c*8;
1318 FORC(4) yuv[c] = (bitbuf >> c*12 & 0xfff) - (c >> 1 << 11);
1320 rgb[0] = yuv[b] + 1.370705*yuv[3];
1321 rgb[1] = yuv[b] - 0.337633*yuv[2] - 0.698001*yuv[3];
1322 rgb[2] = yuv[b] + 1.732446*yuv[2];
1323 FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,0xfff)] / cam_mul[c];
1328 Returns 1 for a Coolpix 995, 0 for anything else.
1330 int CLASS nikon_e995()
1333 const uchar often[] = { 0x00, 0x55, 0xaa, 0xff };
1335 memset (histo, 0, sizeof histo);
1336 fseek (ifp, -2000, SEEK_END);
1337 for (i=0; i < 2000; i++)
1338 histo[fgetc(ifp)]++;
1339 for (i=0; i < 4; i++)
1340 if (histo[often[i]] < 200)
1346 Returns 1 for a Coolpix 2100, 0 for anything else.
1348 int CLASS nikon_e2100()
1353 fseek (ifp, 0, SEEK_SET);
1354 for (i=0; i < 1024; i++) {
1355 fread (t, 1, 12, ifp);
1356 if (((t[2] & t[4] & t[7] & t[9]) >> 4
1357 & t[1] & t[6] & t[8] & t[11] & 3) != 3)
1363 void CLASS nikon_3700()
1367 static const struct {
1369 char make[12], model[15];
1371 { 0x00, "Pentax", "Optio 33WR" },
1372 { 0x03, "Nikon", "E3200" },
1373 { 0x32, "Nikon", "E3700" },
1374 { 0x33, "Olympus", "C740UZ" } };
1376 fseek (ifp, 3072, SEEK_SET);
1377 fread (dp, 1, 24, ifp);
1378 bits = (dp[8] & 3) << 4 | (dp[20] & 3);
1379 for (i=0; i < sizeof table / sizeof *table; i++)
1380 if (bits == table[i].bits) {
1381 strcpy (make, table[i].make );
1382 strcpy (model, table[i].model);
1387 Separates a Minolta DiMAGE Z2 from a Nikon E4300.
1389 int CLASS minolta_z2()
1394 fseek (ifp, -sizeof tail, SEEK_END);
1395 fread (tail, 1, sizeof tail, ifp);
1396 for (nz=i=0; i < sizeof tail; i++)
1401 void CLASS ppm_thumb()
1404 thumb_length = thumb_width*thumb_height*3;
1405 thumb = (char *) malloc (thumb_length);
1406 merror (thumb, "ppm_thumb()");
1407 fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
1408 fread (thumb, 1, thumb_length, ifp);
1409 fwrite (thumb, 1, thumb_length, ofp);
1413 void CLASS ppm16_thumb()
1417 thumb_length = thumb_width*thumb_height*3;
1418 thumb = (char *) calloc (thumb_length, 2);
1419 merror (thumb, "ppm16_thumb()");
1420 read_shorts ((ushort *) thumb, thumb_length);
1421 for (i=0; i < thumb_length; i++)
1422 thumb[i] = ((ushort *) thumb)[i] >> 8;
1423 fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
1424 fwrite (thumb, 1, thumb_length, ofp);
1428 void CLASS layer_thumb()
1431 char *thumb, map[][4] = { "012","102" };
1433 colors = thumb_misc >> 5 & 7;
1434 thumb_length = thumb_width*thumb_height;
1435 thumb = (char *) calloc (colors, thumb_length);
1436 merror (thumb, "layer_thumb()");
1437 fprintf (ofp, "P%d\n%d %d\n255\n",
1438 5 + (colors >> 1), thumb_width, thumb_height);
1439 fread (thumb, thumb_length, colors, ifp);
1440 for (i=0; i < thumb_length; i++)
1441 FORCC putc (thumb[i+thumb_length*(map[thumb_misc >> 8][c]-'0')], ofp);
1445 void CLASS rollei_thumb()
1450 thumb_length = thumb_width * thumb_height;
1451 thumb = (ushort *) calloc (thumb_length, 2);
1452 merror (thumb, "rollei_thumb()");
1453 fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
1454 read_shorts (thumb, thumb_length);
1455 for (i=0; i < thumb_length; i++) {
1456 putc (thumb[i] << 3, ofp);
1457 putc (thumb[i] >> 5 << 2, ofp);
1458 putc (thumb[i] >> 11 << 3, ofp);
1463 void CLASS rollei_load_raw()
1466 unsigned iten=0, isix, i, buffer=0, todo[16];
1468 isix = raw_width * raw_height * 5 / 8;
1469 while (fread (pixel, 1, 10, ifp) == 10) {
1470 for (i=0; i < 10; i+=2) {
1472 todo[i+1] = pixel[i] << 8 | pixel[i+1];
1473 buffer = pixel[i] >> 2 | buffer << 6;
1475 for ( ; i < 16; i+=2) {
1477 todo[i+1] = buffer >> (14-i)*5;
1479 for (i=0; i < 16; i+=2)
1480 raw_image[todo[i]] = (todo[i+1] & 0x3ff);
1485 int CLASS raw (unsigned row, unsigned col)
1487 return (row < raw_height && col < raw_width) ? RAW(row,col) : 0;
1490 void CLASS phase_one_flat_field (int is_float, int nc)
1493 unsigned wide, high, y, x, c, rend, cend, row, col;
1494 float *mrow, num, mult[4];
1496 read_shorts (head, 8);
1497 if (head[2] * head[3] * head[4] * head[5] == 0) return;
1498 wide = head[2] / head[4] + (head[2] % head[4] != 0);
1499 high = head[3] / head[5] + (head[3] % head[5] != 0);
1500 mrow = (float *) calloc (nc*wide, sizeof *mrow);
1501 merror (mrow, "phase_one_flat_field()");
1502 for (y=0; y < high; y++) {
1503 for (x=0; x < wide; x++)
1504 for (c=0; c < nc; c+=2) {
1505 num = is_float ? getreal(11) : get2()/32768.0;
1506 if (y==0) mrow[c*wide+x] = num;
1507 else mrow[(c+1)*wide+x] = (num - mrow[c*wide+x]) / head[5];
1510 rend = head[1] + y*head[5];
1511 for (row = rend-head[5];
1512 row < raw_height && row < rend &&
1513 row < head[1]+head[3]-head[5]; row++) {
1514 for (x=1; x < wide; x++) {
1515 for (c=0; c < nc; c+=2) {
1516 mult[c] = mrow[c*wide+x-1];
1517 mult[c+1] = (mrow[c*wide+x] - mult[c]) / head[4];
1519 cend = head[0] + x*head[4];
1520 for (col = cend-head[4];
1522 col < cend && col < head[0]+head[2]-head[4]; col++) {
1523 c = nc > 2 ? FC(row-top_margin,col-left_margin) : 0;
1525 c = RAW(row,col) * mult[c];
1526 RAW(row,col) = LIM(c,0,65535);
1528 for (c=0; c < nc; c+=2)
1529 mult[c] += mult[c+1];
1532 for (x=0; x < wide; x++)
1533 for (c=0; c < nc; c+=2)
1534 mrow[c*wide+x] += mrow[(c+1)*wide+x];
1540 void CLASS phase_one_correct()
1542 unsigned entries, tag, data, save, col, row, type;
1543 int len, i, j, k, cip, val[4], dev[4], sum, max;
1544 int head[9], diff, mindiff=INT_MAX, off_412=0;
1545 static const signed char dir[12][2] =
1546 { {-1,-1}, {-1,1}, {1,-1}, {1,1}, {-2,0}, {0,-2}, {0,2}, {2,0},
1547 {-2,-2}, {-2,2}, {2,-2}, {2,2} };
1548 float poly[8], num, cfrac, frac, mult[2], *yval[2];
1550 int qmult_applied = 0, qlin_applied = 0;
1552 if (half_size || !meta_length) return;
1553 if (verbose) fprintf (stderr,_("Phase One correction...\n"));
1554 fseek (ifp, meta_offset, SEEK_SET);
1556 fseek (ifp, 6, SEEK_CUR);
1557 fseek (ifp, meta_offset+get4(), SEEK_SET);
1558 entries = get4(); get4();
1564 fseek (ifp, meta_offset+data, SEEK_SET);
1565 if (tag == 0x419) { /* Polynomial curve */
1566 for (get4(), i=0; i < 8; i++)
1567 poly[i] = getreal(11);
1568 poly[3] += (ph1.tag_210 - poly[7]) * poly[6] + 1;
1569 for (i=0; i < 0x10000; i++) {
1570 num = (poly[5]*i + poly[3])*i + poly[1];
1571 curve[i] = LIM(num,0,65535);
1572 } goto apply; /* apply to right half */
1573 } else if (tag == 0x41a) { /* Polynomial curve */
1574 for (i=0; i < 4; i++)
1575 poly[i] = getreal(11);
1576 for (i=0; i < 0x10000; i++) {
1577 for (num=0, j=4; j--; )
1578 num = num * i + poly[j];
1579 curve[i] = LIM(num+i,0,65535);
1580 } apply: /* apply to whole image */
1581 for (row=0; row < raw_height; row++)
1582 for (col = (tag & 1)*ph1.split_col; col < raw_width; col++)
1583 RAW(row,col) = curve[RAW(row,col)];
1584 } else if (tag == 0x400) { /* Sensor defects */
1585 while ((len -= 8) >= 0) {
1588 type = get2(); get2();
1589 if (col >= raw_width) continue;
1590 if (type == 131 || type == 137) /* Bad column */
1591 for (row=0; row < raw_height; row++)
1592 if (FC(row-top_margin,col-left_margin) == 1) {
1593 for (sum=i=0; i < 4; i++)
1594 sum += val[i] = raw (row+dir[i][0], col+dir[i][1]);
1595 for (max=i=0; i < 4; i++) {
1596 dev[i] = abs((val[i] << 2) - sum);
1597 if (dev[max] < dev[i]) max = i;
1599 RAW(row,col) = (sum - val[max])/3.0 + 0.5;
1601 for (sum=0, i=8; i < 12; i++)
1602 sum += raw (row+dir[i][0], col+dir[i][1]);
1603 RAW(row,col) = 0.5 + sum * 0.0732233 +
1604 (raw(row,col-2) + raw(row,col+2)) * 0.3535534;
1606 else if (type == 129) { /* Bad pixel */
1607 if (row >= raw_height) continue;
1608 j = (FC(row-top_margin,col-left_margin) != 1) * 4;
1609 for (sum=0, i=j; i < j+8; i++)
1610 sum += raw (row+dir[i][0], col+dir[i][1]);
1611 RAW(row,col) = (sum + 4) >> 3;
1614 } else if (tag == 0x401) { /* All-color flat fields */
1615 phase_one_flat_field (1, 2);
1616 } else if (tag == 0x416 || tag == 0x410) {
1617 phase_one_flat_field (0, 2);
1618 } else if (tag == 0x40b) { /* Red+blue flat field */
1619 phase_one_flat_field (0, 4);
1620 } else if (tag == 0x412) {
1621 fseek (ifp, 36, SEEK_CUR);
1622 diff = abs (get2() - ph1.tag_21a);
1623 if (mindiff > diff) {
1625 off_412 = ftell(ifp) - 38;
1627 } else if (tag == 0x41f && !qlin_applied) { /* Quadrant linearization */
1628 ushort lc[2][2][16], ref[16];
1630 for (qr = 0; qr < 2; qr++)
1631 for (qc = 0; qc < 2; qc++)
1632 for (i = 0; i < 16; i++)
1633 lc[qr][qc][i] = get4();
1634 for (i = 0; i < 16; i++) {
1636 for (qr = 0; qr < 2; qr++)
1637 for (qc = 0; qc < 2; qc++)
1639 ref[i] = (v + 2) >> 2;
1641 for (qr = 0; qr < 2; qr++) {
1642 for (qc = 0; qc < 2; qc++) {
1644 for (i = 0; i < 16; i++) {
1645 cx[1+i] = lc[qr][qc][i];
1649 cx[17] = cf[17] = ((unsigned) ref[15] * 65535) / lc[qr][qc][15];
1650 cx[18] = cf[18] = 65535;
1651 cubic_spline(cx, cf, 19);
1652 for (row = (qr ? ph1.split_row : 0);
1653 row < (qr ? raw_height : ph1.split_row); row++)
1654 for (col = (qc ? ph1.split_col : 0);
1655 col < (qc ? raw_width : ph1.split_col); col++)
1656 RAW(row,col) = curve[RAW(row,col)];
1660 } else if (tag == 0x41e && !qmult_applied) { /* Quadrant multipliers */
1661 float qmult[2][2] = { { 1, 1 }, { 1, 1 } };
1662 get4(); get4(); get4(); get4();
1663 qmult[0][0] = 1.0 + getreal(11);
1664 get4(); get4(); get4(); get4(); get4();
1665 qmult[0][1] = 1.0 + getreal(11);
1666 get4(); get4(); get4();
1667 qmult[1][0] = 1.0 + getreal(11);
1668 get4(); get4(); get4();
1669 qmult[1][1] = 1.0 + getreal(11);
1670 for (row=0; row < raw_height; row++)
1671 for (col=0; col < raw_width; col++) {
1672 i = qmult[row >= ph1.split_row][col >= ph1.split_col] * RAW(row,col);
1673 RAW(row,col) = LIM(i,0,65535);
1676 } else if (tag == 0x431 && !qmult_applied) { /* Quadrant combined */
1677 ushort lc[2][2][7], ref[7];
1679 for (i = 0; i < 7; i++)
1681 for (qr = 0; qr < 2; qr++)
1682 for (qc = 0; qc < 2; qc++)
1683 for (i = 0; i < 7; i++)
1684 lc[qr][qc][i] = get4();
1685 for (qr = 0; qr < 2; qr++) {
1686 for (qc = 0; qc < 2; qc++) {
1688 for (i = 0; i < 7; i++) {
1690 cf[1+i] = ((unsigned) ref[i] * lc[qr][qc][i]) / 10000;
1693 cx[8] = cf[8] = 65535;
1694 cubic_spline(cx, cf, 9);
1695 for (row = (qr ? ph1.split_row : 0);
1696 row < (qr ? raw_height : ph1.split_row); row++)
1697 for (col = (qc ? ph1.split_col : 0);
1698 col < (qc ? raw_width : ph1.split_col); col++)
1699 RAW(row,col) = curve[RAW(row,col)];
1705 fseek (ifp, save, SEEK_SET);
1708 fseek (ifp, off_412, SEEK_SET);
1709 for (i=0; i < 9; i++) head[i] = get4() & 0x7fff;
1710 yval[0] = (float *) calloc (head[1]*head[3] + head[2]*head[4], 6);
1711 merror (yval[0], "phase_one_correct()");
1712 yval[1] = (float *) (yval[0] + head[1]*head[3]);
1713 xval[0] = (ushort *) (yval[1] + head[2]*head[4]);
1714 xval[1] = (ushort *) (xval[0] + head[1]*head[3]);
1716 for (i=0; i < 2; i++)
1717 for (j=0; j < head[i+1]*head[i+3]; j++)
1718 yval[i][j] = getreal(11);
1719 for (i=0; i < 2; i++)
1720 for (j=0; j < head[i+1]*head[i+3]; j++)
1721 xval[i][j] = get2();
1722 for (row=0; row < raw_height; row++)
1723 for (col=0; col < raw_width; col++) {
1724 cfrac = (float) col * head[3] / raw_width;
1725 cfrac -= cip = cfrac;
1726 num = RAW(row,col) * 0.5;
1727 for (i=cip; i < cip+2; i++) {
1728 for (k=j=0; j < head[1]; j++)
1729 if (num < xval[0][k = head[1]*i+j]) break;
1730 frac = (j == 0 || j == head[1]) ? 0 :
1731 (xval[0][k] - num) / (xval[0][k] - xval[0][k-1]);
1732 mult[i-cip] = yval[0][k-1] * frac + yval[0][k] * (1-frac);
1734 i = ((mult[0] * (1-cfrac) + mult[1] * cfrac) * row + num) * 2;
1735 RAW(row,col) = LIM(i,0,65535);
1741 void CLASS phase_one_load_raw()
1744 ushort akey, bkey, mask;
1746 fseek (ifp, ph1.key_off, SEEK_SET);
1749 mask = ph1.format == 1 ? 0x5555:0x1354;
1750 fseek (ifp, data_offset, SEEK_SET);
1751 read_shorts (raw_image, raw_width*raw_height);
1753 for (i=0; i < raw_width*raw_height; i+=2) {
1754 a = raw_image[i+0] ^ akey;
1755 b = raw_image[i+1] ^ bkey;
1756 raw_image[i+0] = (a & mask) | (b & ~mask);
1757 raw_image[i+1] = (b & mask) | (a & ~mask);
1761 unsigned CLASS ph1_bithuff (int nbits, ushort *huff)
1768 return ph1_bitbuf = ph1_vbits = 0;
1769 if (nbits == 0) return 0;
1770 bitbuf = ph1_bitbuf; vbits = ph1_vbits;
1771 if (vbits < nbits) {
1772 bitbuf = bitbuf << 32 | get4();
1775 c = bitbuf << (64-vbits) >> (64-nbits);
1777 nbits = huff[c] >> 8;
1778 c = (uchar) huff[c];
1781 ph1_bitbuf = bitbuf; ph1_vbits = vbits;
1784 #define ph1_bits(n) ph1_bithuff(n,0)
1785 #define ph1_huff(h) ph1_bithuff(*h,h+1)
1787 void CLASS phase_one_load_raw_c()
1789 static const int length[] = { 8,7,6,9,11,10,5,12,14,13 };
1790 int *offset, len[2], pred[2], row, col, i, j;
1792 short (*cblack)[2], (*rblack)[2];
1794 pixel = (ushort *) calloc (raw_width*3 + raw_height*4, 2);
1795 merror (pixel, "phase_one_load_raw_c()");
1796 offset = (int *) (pixel + raw_width);
1797 fseek (ifp, strip_offset, SEEK_SET);
1798 for (row=0; row < raw_height; row++)
1799 offset[row] = get4();
1800 cblack = (short (*)[2]) (offset + raw_height);
1801 fseek (ifp, ph1.black_col, SEEK_SET);
1803 read_shorts ((ushort *) cblack[0], raw_height*2);
1804 rblack = cblack + raw_height;
1805 fseek (ifp, ph1.black_row, SEEK_SET);
1807 read_shorts ((ushort *) rblack[0], raw_width*2);
1808 for (i=0; i < 256; i++)
1809 curve[i] = i*i / 3.969 + 0.5;
1810 for (row=0; row < raw_height; row++) {
1811 fseek (ifp, data_offset + offset[row], SEEK_SET);
1813 pred[0] = pred[1] = 0;
1814 for (col=0; col < raw_width; col++) {
1815 if (col >= (raw_width & -8))
1816 len[0] = len[1] = 14;
1817 else if ((col & 7) == 0)
1818 for (i=0; i < 2; i++) {
1819 for (j=0; j < 5 && !ph1_bits(1); j++);
1820 if (j--) len[i] = length[j*2 + ph1_bits(1)];
1822 if ((i = len[col & 1]) == 14)
1823 pixel[col] = pred[col & 1] = ph1_bits(16);
1825 pixel[col] = pred[col & 1] += ph1_bits(i) + 1 - (1 << (i - 1));
1826 if (pred[col & 1] >> 16) derror();
1827 if (ph1.format == 5 && pixel[col] < 256)
1828 pixel[col] = curve[pixel[col]];
1830 for (col=0; col < raw_width; col++) {
1831 i = (pixel[col] << 2*(ph1.format != 8)) - ph1.black
1832 + cblack[row][col >= ph1.split_col]
1833 + rblack[col][row >= ph1.split_row];
1834 if (i > 0) RAW(row,col) = i;
1838 maximum = 0xfffc - ph1.black;
1841 void CLASS hasselblad_load_raw()
1844 int shot, row, col, *back[5], len[2], diff[12], pred, sh, f, s, c;
1845 unsigned upix, urow, ucol;
1848 if (!ljpeg_start (&jh, 0)) return;
1851 back[4] = (int *) calloc (raw_width, 3*sizeof **back);
1852 merror (back[4], "hasselblad_load_raw()");
1853 FORC3 back[c] = back[4] + c*raw_width;
1854 cblack[6] >>= sh = tiff_samples > 1;
1855 shot = LIM(shot_select, 1, tiff_samples) - 1;
1856 for (row=0; row < raw_height; row++) {
1857 FORC4 back[(c+3) & 3] = back[c];
1858 for (col=0; col < raw_width; col+=2) {
1859 for (s=0; s < tiff_samples*2; s+=2) {
1860 FORC(2) len[c] = ph1_huff(jh.huff[0]);
1862 diff[s+c] = ph1_bits(len[c]);
1863 if ((diff[s+c] & (1 << (len[c]-1))) == 0)
1864 diff[s+c] -= (1 << len[c]) - 1;
1865 if (diff[s+c] == 65535) diff[s+c] = -32768;
1868 for (s=col; s < col+2; s++) {
1869 pred = 0x8000 + load_flags;
1870 if (col) pred = back[2][s-2];
1871 if (col && row > 1) switch (jh.psv) {
1872 case 11: pred += back[0][s]/2 - back[0][s-2]/2; break;
1874 f = (row & 1)*3 ^ ((col+s) & 1);
1875 FORC (tiff_samples) {
1876 pred += diff[(s & 1)*tiff_samples+c];
1877 upix = pred >> sh & 0xffff;
1878 if (raw_image && c == shot)
1881 urow = row-top_margin + (c & 1);
1882 ucol = col-left_margin - ((c >> 1) & 1);
1883 ip = &image[urow*width+ucol][f];
1884 if (urow < height && ucol < width)
1885 *ip = c < 4 ? upix : (*ip + upix) >> 1;
1894 if (image) mix_green = 1;
1897 void CLASS leaf_hdr_load_raw()
1900 unsigned tile=0, r, c, row, col;
1903 pixel = (ushort *) calloc (raw_width, sizeof *pixel);
1904 merror (pixel, "leaf_hdr_load_raw()");
1907 for (r=0; r < raw_height; r++) {
1908 if (r % tile_length == 0) {
1909 fseek (ifp, data_offset + 4*tile++, SEEK_SET);
1910 fseek (ifp, get4(), SEEK_SET);
1912 if (filters && c != shot_select) continue;
1913 if (filters) pixel = raw_image + r*raw_width;
1914 read_shorts (pixel, raw_width);
1915 if (!filters && (row = r - top_margin) < height)
1916 for (col=0; col < width; col++)
1917 image[row*width+col][c] = pixel[col+left_margin];
1926 void CLASS unpacked_load_raw()
1928 int row, col, bits=0;
1930 while (1 << ++bits < maximum);
1931 read_shorts (raw_image, raw_width*raw_height);
1932 for (row=0; row < raw_height; row++)
1933 for (col=0; col < raw_width; col++)
1934 if ((RAW(row,col) >>= load_flags) >> bits
1935 && (unsigned) (row-top_margin) < height
1936 && (unsigned) (col-left_margin) < width) derror();
1939 void CLASS sinar_4shot_load_raw()
1942 unsigned shot, row, col, r, c;
1945 shot = LIM (shot_select, 1, 4) - 1;
1946 fseek (ifp, data_offset + shot*4, SEEK_SET);
1947 fseek (ifp, get4(), SEEK_SET);
1948 unpacked_load_raw();
1951 pixel = (ushort *) calloc (raw_width, sizeof *pixel);
1952 merror (pixel, "sinar_4shot_load_raw()");
1953 for (shot=0; shot < 4; shot++) {
1954 fseek (ifp, data_offset + shot*4, SEEK_SET);
1955 fseek (ifp, get4(), SEEK_SET);
1956 for (row=0; row < raw_height; row++) {
1957 read_shorts (pixel, raw_width);
1958 if ((r = row-top_margin - (shot >> 1 & 1)) >= height) continue;
1959 for (col=0; col < raw_width; col++) {
1960 if ((c = col-left_margin - (shot & 1)) >= width) continue;
1961 image[r*width+c][(row & 1)*3 ^ (~col & 1)] = pixel[col];
1969 void CLASS imacon_full_load_raw()
1974 for (row=0; row < height; row++)
1975 for (col=0; col < width; col++)
1976 read_shorts (image[row*width+col], 3);
1979 void CLASS packed_load_raw()
1981 int vbits=0, bwide, rbits, bite, half, irow, row, col, val, i;
1984 bwide = raw_width * tiff_bps / 8;
1985 bwide += bwide & load_flags >> 7;
1986 rbits = bwide * 8 - raw_width * tiff_bps;
1987 if (load_flags & 1) bwide = bwide * 16 / 15;
1988 bite = 8 + (load_flags & 24);
1989 half = (raw_height+1) >> 1;
1990 for (irow=0; irow < raw_height; irow++) {
1992 if (load_flags & 2 &&
1993 (row = irow % half * 2 + irow / half) == 1 &&
1995 if (vbits=0, tiff_compress)
1996 fseek (ifp, data_offset - (-half*bwide & -2048), SEEK_SET);
1998 fseek (ifp, 0, SEEK_END);
1999 fseek (ifp, ftell(ifp) >> 3 << 2, SEEK_SET);
2002 for (col=0; col < raw_width; col++) {
2003 for (vbits -= tiff_bps; vbits < 0; vbits += bite) {
2005 for (i=0; i < bite; i+=8)
2006 bitbuf |= (unsigned) (fgetc(ifp) << i);
2008 val = bitbuf << (64-tiff_bps-vbits) >> (64-tiff_bps);
2009 RAW(row,col ^ (load_flags >> 6 & 1)) = val;
2010 if (load_flags & 1 && (col % 10) == 9 && fgetc(ifp) &&
2011 row < height+top_margin && col < width+left_margin) derror();
2017 void CLASS nokia_load_raw()
2020 int rev, dwide, row, col, c;
2023 rev = 3 * (order == 0x4949);
2024 dwide = (raw_width * 5 + 1) / 4;
2025 data = (uchar *) malloc (dwide*2);
2026 merror (data, "nokia_load_raw()");
2027 for (row=0; row < raw_height; row++) {
2028 if (fread (data+dwide, 1, dwide, ifp) < dwide) derror();
2029 FORC(dwide) data[c] = data[dwide+(c ^ rev)];
2030 for (dp=data, col=0; col < raw_width; dp+=5, col+=4)
2031 FORC4 RAW(row,col+c) = (dp[c] << 2) | (dp[4] >> (c << 1) & 3);
2035 if (strcmp(make,"OmniVision")) return;
2038 sum[ c & 1] += SQR(RAW(row,c)-RAW(row+1,c+1));
2039 sum[~c & 1] += SQR(RAW(row+1,c)-RAW(row,c+1));
2041 if (sum[1] > sum[0]) filters = 0x4b4b4b4b;
2044 void CLASS canon_rmf_load_raw()
2046 int row, col, bits, orow, ocol, c;
2048 for (row=0; row < raw_height; row++)
2049 for (col=0; col < raw_width-2; col+=3) {
2053 if ((ocol = col+c-4) < 0) {
2055 if ((orow -= 2) < 0)
2058 RAW(orow,ocol) = curve[bits >> (10*c+2) & 0x3ff];
2061 maximum = curve[0x3ff];
2064 unsigned CLASS pana_bits (int nbits)
2066 uchar *buf = pana_buf;
2067 int vbits = pana_vbits;
2070 if (!nbits) return pana_vbits=0;
2072 fread (buf+load_flags, 1, 0x4000-load_flags, ifp);
2073 fread (buf, 1, load_flags, ifp);
2075 vbits = (vbits - nbits) & 0x1ffff;
2076 byte = vbits >> 3 ^ 0x3ff0;
2078 return (buf[byte] | buf[byte+1] << 8) >> (vbits & 7) & ~(-1 << nbits);
2081 void CLASS panasonic_load_raw()
2083 int row, col, i, j, sh=0, pred[2], nonz[2];
2086 for (row=0; row < height; row++)
2087 for (col=0; col < raw_width; col++) {
2088 if ((i = col % 14) == 0)
2089 pred[0] = pred[1] = nonz[0] = nonz[1] = 0;
2090 if (i % 3 == 2) sh = 4 >> (3 - pana_bits(2));
2092 if ((j = pana_bits(8))) {
2093 if ((pred[i & 1] -= 0x80 << sh) < 0 || sh == 4)
2094 pred[i & 1] &= ~(-1 << sh);
2095 pred[i & 1] += j << sh;
2097 } else if ((nonz[i & 1] = pana_bits(8)) || i > 11)
2098 pred[i & 1] = nonz[i & 1] << 4 | pana_bits(4);
2099 if ((RAW(row,col) = pred[col & 1]) > 4098 && col < width) derror();
2103 void CLASS olympus_load_raw()
2106 int row, col, nbits, sign, low, high, i, c, w, n, nw;
2107 int acarry[2][3], *carry, pred, diff;
2111 FORC(2048 >> i) huff[++n] = (i+1) << 8 | i;
2112 fseek (ifp, 7, SEEK_CUR);
2114 for (row=0; row < height; row++) {
2115 memset (acarry, 0, sizeof acarry);
2116 for (col=0; col < raw_width; col++) {
2117 carry = acarry[col & 1];
2118 i = 2 * (carry[2] < 3);
2119 for (nbits=2+i; (ushort) carry[0] >> (nbits+i); nbits++);
2120 low = (sign = getbits(3)) & 3;
2121 sign = sign << 29 >> 31;
2122 if ((high = getbithuff(12,huff)) == 12)
2123 high = getbits(16-nbits) >> 1;
2124 carry[0] = (high << nbits) | getbits(nbits);
2125 diff = (carry[0] ^ sign) + carry[1];
2126 carry[1] = (diff*3 + carry[1]) >> 5;
2127 carry[2] = carry[0] > 16 ? 0 : carry[2]+1;
2128 if (col >= width) continue;
2129 if (row < 2 && col < 2) pred = 0;
2130 else if (row < 2) pred = RAW(row,col-2);
2131 else if (col < 2) pred = RAW(row-2,col);
2135 nw = RAW(row-2,col-2);
2136 if ((w < nw && nw < n) || (n < nw && nw < w)) {
2137 if (ABS(w-nw) > 32 || ABS(n-nw) > 32)
2139 else pred = (w + n) >> 1;
2140 } else pred = ABS(w-nw) > ABS(n-nw) ? w : n;
2142 if ((RAW(row,col) = pred + ((diff << 2) | low)) >> 12) derror();
2147 void CLASS minolta_rd175_load_raw()
2150 unsigned irow, box, row, col;
2152 for (irow=0; irow < 1481; irow++) {
2153 if (fread (pixel, 1, 768, ifp) < 768) derror();
2155 row = irow % 82 * 12 + ((box < 12) ? box | 1 : (box-12)*2);
2157 case 1477: case 1479: continue;
2158 case 1476: row = 984; break;
2159 case 1480: row = 985; break;
2160 case 1478: row = 985; box = 1;
2162 if ((box < 12) && (box & 1)) {
2163 for (col=0; col < 1533; col++, row ^= 1)
2164 if (col != 1) RAW(row,col) = (col+1) & 2 ?
2165 pixel[col/2-1] + pixel[col/2+1] : pixel[col/2] << 1;
2166 RAW(row,1) = pixel[1] << 1;
2167 RAW(row,1533) = pixel[765] << 1;
2169 for (col=row & 1; col < 1534; col+=2)
2170 RAW(row,col) = pixel[col/2] << 1;
2172 maximum = 0xff << 1;
2175 void CLASS quicktake_100_load_raw()
2177 uchar pixel[484][644];
2178 static const short gstep[16] =
2179 { -89,-60,-44,-32,-22,-15,-8,-2,2,8,15,22,32,44,60,89 };
2180 static const short rstep[6][4] =
2181 { { -3,-1,1,3 }, { -5,-1,1,5 }, { -8,-2,2,8 },
2182 { -13,-3,3,13 }, { -19,-4,4,19 }, { -28,-6,6,28 } };
2183 static const short curve[256] =
2184 { 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,
2185 28,29,30,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,53,
2186 54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,74,75,76,77,78,
2187 79,80,81,82,83,84,86,88,90,92,94,97,99,101,103,105,107,110,112,114,116,
2188 118,120,123,125,127,129,131,134,136,138,140,142,144,147,149,151,153,155,
2189 158,160,162,164,166,168,171,173,175,177,179,181,184,186,188,190,192,195,
2190 197,199,201,203,205,208,210,212,214,216,218,221,223,226,230,235,239,244,
2191 248,252,257,261,265,270,274,278,283,287,291,296,300,305,309,313,318,322,
2192 326,331,335,339,344,348,352,357,361,365,370,374,379,383,387,392,396,400,
2193 405,409,413,418,422,426,431,435,440,444,448,453,457,461,466,470,474,479,
2194 483,487,492,496,500,508,519,531,542,553,564,575,587,598,609,620,631,643,
2195 654,665,676,687,698,710,721,732,743,754,766,777,788,799,810,822,833,844,
2196 855,866,878,889,900,911,922,933,945,956,967,978,989,1001,1012,1023 };
2197 int rb, row, col, sharp, val=0;
2200 memset (pixel, 0x80, sizeof pixel);
2201 for (row=2; row < height+2; row++) {
2202 for (col=2+(row & 1); col < width+2; col+=2) {
2203 val = ((pixel[row-1][col-1] + 2*pixel[row-1][col+1] +
2204 pixel[row][col-2]) >> 2) + gstep[getbits(4)];
2205 pixel[row][col] = val = LIM(val,0,255);
2207 pixel[row][col-2] = pixel[row+1][~row & 1] = val;
2209 pixel[row-1][col+1] = pixel[row-1][col+3] = val;
2211 pixel[row][col] = val;
2213 for (rb=0; rb < 2; rb++)
2214 for (row=2+rb; row < height+2; row+=2)
2215 for (col=3-(row & 1); col < width+2; col+=2) {
2216 if (row < 4 || col < 4) sharp = 2;
2218 val = ABS(pixel[row-2][col] - pixel[row][col-2])
2219 + ABS(pixel[row-2][col] - pixel[row-2][col-2])
2220 + ABS(pixel[row][col-2] - pixel[row-2][col-2]);
2221 sharp = val < 4 ? 0 : val < 8 ? 1 : val < 16 ? 2 :
2222 val < 32 ? 3 : val < 48 ? 4 : 5;
2224 val = ((pixel[row-2][col] + pixel[row][col-2]) >> 1)
2225 + rstep[sharp][getbits(2)];
2226 pixel[row][col] = val = LIM(val,0,255);
2227 if (row < 4) pixel[row-2][col+2] = val;
2228 if (col < 4) pixel[row+2][col-2] = val;
2230 for (row=2; row < height+2; row++)
2231 for (col=3-(row & 1); col < width+2; col+=2) {
2232 val = ((pixel[row][col-1] + (pixel[row][col] << 2) +
2233 pixel[row][col+1]) >> 1) - 0x100;
2234 pixel[row][col] = LIM(val,0,255);
2236 for (row=0; row < height; row++)
2237 for (col=0; col < width; col++)
2238 RAW(row,col) = curve[pixel[row+2][col+2]];
2242 #define radc_token(tree) ((signed char) getbithuff(8,huff[tree]))
2244 #define FORYX for (y=1; y < 3; y++) for (x=col+1; x >= col; x--)
2246 #define PREDICTOR (c ? (buf[c][y-1][x] + buf[c][y][x+1]) / 2 \
2247 : (buf[c][y-1][x+1] + 2*buf[c][y-1][x] + buf[c][y][x+1]) / 4)
2249 void CLASS kodak_radc_load_raw()
2251 static const char src[] = {
2252 1,1, 2,3, 3,4, 4,2, 5,7, 6,5, 7,6, 7,8,
2253 1,0, 2,1, 3,3, 4,4, 5,2, 6,7, 7,6, 8,5, 8,8,
2254 2,1, 2,3, 3,0, 3,2, 3,4, 4,6, 5,5, 6,7, 6,8,
2255 2,0, 2,1, 2,3, 3,2, 4,4, 5,6, 6,7, 7,5, 7,8,
2256 2,1, 2,4, 3,0, 3,2, 3,3, 4,7, 5,5, 6,6, 6,8,
2257 2,3, 3,1, 3,2, 3,4, 3,5, 3,6, 4,7, 5,0, 5,8,
2258 2,3, 2,6, 3,0, 3,1, 4,4, 4,5, 4,7, 5,2, 5,8,
2259 2,4, 2,7, 3,3, 3,6, 4,1, 4,2, 4,5, 5,0, 5,8,
2260 2,6, 3,1, 3,3, 3,5, 3,7, 3,8, 4,0, 5,2, 5,4,
2261 2,0, 2,1, 3,2, 3,3, 4,4, 4,5, 5,6, 5,7, 4,8,
2264 2,-17, 2,-5, 2,5, 2,17,
2265 2,-7, 2,2, 2,9, 2,18,
2266 2,-18, 2,-9, 2,-2, 2,7,
2267 2,-28, 2,28, 3,-49, 3,-9, 3,9, 4,49, 5,-79, 5,79,
2268 2,-1, 2,13, 2,26, 3,39, 4,-16, 5,55, 6,-37, 6,76,
2269 2,-26, 2,-13, 2,1, 3,-39, 4,16, 5,-55, 6,-76, 6,37
2271 ushort huff[19][256];
2272 int row, col, tree, nreps, rep, step, i, c, s, r, x, y, val;
2273 short last[3] = { 16,16,16 }, mul[3], buf[3][3][386];
2274 static const ushort pt[] =
2275 { 0,0, 1280,1344, 2320,3616, 3328,8000, 4095,16383, 65535,16383 };
2277 for (i=2; i < 12; i+=2)
2278 for (c=pt[i-2]; c <= pt[i]; c++)
2280 (c-pt[i-2]) / (pt[i]-pt[i-2]) * (pt[i+1]-pt[i-1]) + pt[i-1] + 0.5;
2281 for (s=i=0; i < sizeof src; i+=2)
2283 ((ushort *)huff)[s++] = src[i] << 8 | (uchar) src[i+1];
2284 s = kodak_cbpp == 243 ? 2 : 3;
2285 FORC(256) huff[18][c] = (8-s) << 8 | c >> s << s | 1 << (s-1);
2287 for (i=0; i < sizeof(buf)/sizeof(short); i++)
2288 ((short *)buf)[i] = 2048;
2289 for (row=0; row < height; row+=4) {
2290 FORC3 mul[c] = getbits(6);
2292 val = ((0x1000000/last[c] + 0x7ff) >> 12) * mul[c];
2293 s = val > 65564 ? 10:12;
2296 for (i=0; i < sizeof(buf[0])/sizeof(short); i++)
2297 ((short *)buf[c])[i] = (((short *)buf[c])[i] * val + x) >> s;
2299 for (r=0; r <= !c; r++) {
2300 buf[c][1][width/2] = buf[c][2][width/2] = mul[c] << 7;
2301 for (tree=1, col=width/2; col > 0; ) {
2302 if ((tree = radc_token(tree))) {
2305 FORYX buf[c][y][x] = (uchar) radc_token(18) * mul[c];
2307 FORYX buf[c][y][x] = radc_token(tree+10) * 16 + PREDICTOR;
2310 nreps = (col > 2) ? radc_token(9) + 1 : 1;
2311 for (rep=0; rep < 8 && rep < nreps && col > 0; rep++) {
2313 FORYX buf[c][y][x] = PREDICTOR;
2315 step = radc_token(10) << 4;
2316 FORYX buf[c][y][x] += step;
2319 } while (nreps == 9);
2321 for (y=0; y < 2; y++)
2322 for (x=0; x < width/2; x++) {
2323 val = (buf[c][y+1][x] << 4) / mul[c];
2324 if (val < 0) val = 0;
2325 if (c) RAW(row+y*2+c-1,x*2+2-c) = val;
2326 else RAW(row+r*2+y,x*2+y) = val;
2328 memcpy (buf[c][0]+!c, buf[c][2], sizeof buf[c][0]-2*!c);
2331 for (y=row; y < row+4; y++)
2332 for (x=0; x < width; x++)
2335 s = x+1 < width ? x+1 : x-1;
2336 val = (RAW(y,x)-2048)*2 + (RAW(y,r)+RAW(y,s))/2;
2337 if (val < 0) val = 0;
2341 for (i=0; i < height*width; i++)
2342 raw_image[i] = curve[raw_image[i]];
2350 void CLASS kodak_jpeg_load_raw() {}
2351 void CLASS lossy_dng_load_raw() {}
2355 fill_input_buffer (j_decompress_ptr cinfo)
2357 static uchar jpeg_buffer[4096];
2360 nbytes = fread (jpeg_buffer, 1, 4096, ifp);
2361 swab (jpeg_buffer, jpeg_buffer, nbytes);
2362 cinfo->src->next_input_byte = jpeg_buffer;
2363 cinfo->src->bytes_in_buffer = nbytes;
2367 void CLASS kodak_jpeg_load_raw()
2369 struct jpeg_decompress_struct cinfo;
2370 struct jpeg_error_mgr jerr;
2372 JSAMPLE (*pixel)[3];
2375 cinfo.err = jpeg_std_error (&jerr);
2376 jpeg_create_decompress (&cinfo);
2377 jpeg_stdio_src (&cinfo, ifp);
2378 cinfo.src->fill_input_buffer = fill_input_buffer;
2379 jpeg_read_header (&cinfo, TRUE);
2380 jpeg_start_decompress (&cinfo);
2381 if ((cinfo.output_width != width ) ||
2382 (cinfo.output_height*2 != height ) ||
2383 (cinfo.output_components != 3 )) {
2384 fprintf (stderr,_("%s: incorrect JPEG dimensions\n"), ifname);
2385 jpeg_destroy_decompress (&cinfo);
2386 longjmp (failure, 3);
2388 buf = (*cinfo.mem->alloc_sarray)
2389 ((j_common_ptr) &cinfo, JPOOL_IMAGE, width*3, 1);
2391 while (cinfo.output_scanline < cinfo.output_height) {
2392 row = cinfo.output_scanline * 2;
2393 jpeg_read_scanlines (&cinfo, buf, 1);
2394 pixel = (JSAMPLE (*)[3]) buf[0];
2395 for (col=0; col < width; col+=2) {
2396 RAW(row+0,col+0) = pixel[col+0][1] << 1;
2397 RAW(row+1,col+1) = pixel[col+1][1] << 1;
2398 RAW(row+0,col+1) = pixel[col][0] + pixel[col+1][0];
2399 RAW(row+1,col+0) = pixel[col][2] + pixel[col+1][2];
2402 jpeg_finish_decompress (&cinfo);
2403 jpeg_destroy_decompress (&cinfo);
2404 maximum = 0xff << 1;
2407 void CLASS gamma_curve (double pwr, double ts, int mode, int imax);
2409 void CLASS lossy_dng_load_raw()
2411 struct jpeg_decompress_struct cinfo;
2412 struct jpeg_error_mgr jerr;
2414 JSAMPLE (*pixel)[3];
2415 unsigned sorder=order, ntags, opcode, deg, i, j, c;
2416 unsigned save=data_offset-4, trow=0, tcol=0, row, col;
2418 double coeff[9], tot;
2421 fseek (ifp, meta_offset, SEEK_SET);
2425 opcode = get4(); get4(); get4();
2427 { fseek (ifp, get4(), SEEK_CUR); continue; }
2428 fseek (ifp, 20, SEEK_CUR);
2429 if ((c = get4()) > 2) break;
2430 fseek (ifp, 12, SEEK_CUR);
2431 if ((deg = get4()) > 8) break;
2432 for (i=0; i <= deg && i < 9; i++)
2433 coeff[i] = getreal(12);
2434 for (i=0; i < 256; i++) {
2435 for (tot=j=0; j <= deg; j++)
2436 tot += coeff[j] * pow(i/255.0, j);
2437 cur[c][i] = tot*0xffff;
2442 gamma_curve (1/2.4, 12.92, 1, 255);
2443 FORC3 memcpy (cur[c], curve, sizeof cur[0]);
2445 cinfo.err = jpeg_std_error (&jerr);
2446 jpeg_create_decompress (&cinfo);
2447 while (trow < raw_height) {
2448 fseek (ifp, save+=4, SEEK_SET);
2449 if (tile_length < INT_MAX)
2450 fseek (ifp, get4(), SEEK_SET);
2451 jpeg_stdio_src (&cinfo, ifp);
2452 jpeg_read_header (&cinfo, TRUE);
2453 jpeg_start_decompress (&cinfo);
2454 buf = (*cinfo.mem->alloc_sarray)
2455 ((j_common_ptr) &cinfo, JPOOL_IMAGE, cinfo.output_width*3, 1);
2456 while (cinfo.output_scanline < cinfo.output_height &&
2457 (row = trow + cinfo.output_scanline) < height) {
2458 jpeg_read_scanlines (&cinfo, buf, 1);
2459 pixel = (JSAMPLE (*)[3]) buf[0];
2460 for (col=0; col < cinfo.output_width && tcol+col < width; col++) {
2461 FORC3 image[row*width+tcol+col][c] = cur[c][pixel[col][c]];
2464 jpeg_abort_decompress (&cinfo);
2465 if ((tcol += tile_width) >= raw_width)
2466 trow += tile_length + (tcol = 0);
2468 jpeg_destroy_decompress (&cinfo);
2473 void CLASS kodak_dc120_load_raw()
2475 static const int mul[4] = { 162, 192, 187, 92 };
2476 static const int add[4] = { 0, 636, 424, 212 };
2478 int row, shift, col;
2480 for (row=0; row < height; row++) {
2481 if (fread (pixel, 1, 848, ifp) < 848) derror();
2482 shift = row * mul[row & 3] + add[row & 3];
2483 for (col=0; col < width; col++)
2484 RAW(row,col) = (ushort) pixel[(col + shift) % 848];
2489 void CLASS eight_bit_load_raw()
2494 pixel = (uchar *) calloc (raw_width, sizeof *pixel);
2495 merror (pixel, "eight_bit_load_raw()");
2496 for (row=0; row < raw_height; row++) {
2497 if (fread (pixel, 1, raw_width, ifp) < raw_width) derror();
2498 for (col=0; col < raw_width; col++)
2499 RAW(row,col) = curve[pixel[col]];
2502 maximum = curve[0xff];
2505 void CLASS kodak_c330_load_raw()
2508 int row, col, y, cb, cr, rgb[3], c;
2510 pixel = (uchar *) calloc (raw_width, 2*sizeof *pixel);
2511 merror (pixel, "kodak_c330_load_raw()");
2512 for (row=0; row < height; row++) {
2513 if (fread (pixel, raw_width, 2, ifp) < 2) derror();
2514 if (load_flags && (row & 31) == 31)
2515 fseek (ifp, raw_width*32, SEEK_CUR);
2516 for (col=0; col < width; col++) {
2518 cb = pixel[(col*2 & -4) | 1] - 128;
2519 cr = pixel[(col*2 & -4) | 3] - 128;
2520 rgb[1] = y - ((cb + cr + 2) >> 2);
2521 rgb[2] = rgb[1] + cb;
2522 rgb[0] = rgb[1] + cr;
2523 FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,255)];
2527 maximum = curve[0xff];
2530 void CLASS kodak_c603_load_raw()
2533 int row, col, y, cb, cr, rgb[3], c;
2535 pixel = (uchar *) calloc (raw_width, 3*sizeof *pixel);
2536 merror (pixel, "kodak_c603_load_raw()");
2537 for (row=0; row < height; row++) {
2539 if (fread (pixel, raw_width, 3, ifp) < 3) derror();
2540 for (col=0; col < width; col++) {
2541 y = pixel[width*2*(row & 1) + col];
2542 cb = pixel[width + (col & -2)] - 128;
2543 cr = pixel[width + (col & -2)+1] - 128;
2544 rgb[1] = y - ((cb + cr + 2) >> 2);
2545 rgb[2] = rgb[1] + cb;
2546 rgb[0] = rgb[1] + cr;
2547 FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,255)];
2551 maximum = curve[0xff];
2554 void CLASS kodak_262_load_raw()
2556 static const uchar kodak_tree[2][26] =
2557 { { 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 },
2558 { 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 } };
2561 int *strip, ns, c, row, col, chess, pi=0, pi1, pi2, pred, val;
2563 FORC(2) huff[c] = make_decoder (kodak_tree[c]);
2564 ns = (raw_height+63) >> 5;
2565 pixel = (uchar *) malloc (raw_width*32 + ns*4);
2566 merror (pixel, "kodak_262_load_raw()");
2567 strip = (int *) (pixel + raw_width*32);
2569 FORC(ns) strip[c] = get4();
2570 for (row=0; row < raw_height; row++) {
2571 if ((row & 31) == 0) {
2572 fseek (ifp, strip[row >> 5], SEEK_SET);
2576 for (col=0; col < raw_width; col++) {
2577 chess = (row + col) & 1;
2578 pi1 = chess ? pi-2 : pi-raw_width-1;
2579 pi2 = chess ? pi-2*raw_width : pi-raw_width+1;
2580 if (col <= chess) pi1 = -1;
2581 if (pi1 < 0) pi1 = pi2;
2582 if (pi2 < 0) pi2 = pi1;
2583 if (pi1 < 0 && col > 1) pi1 = pi2 = pi-2;
2584 pred = (pi1 < 0) ? 0 : (pixel[pi1] + pixel[pi2]) >> 1;
2585 pixel[pi] = val = pred + ljpeg_diff (huff[chess]);
2586 if (val >> 8) derror();
2587 val = curve[pixel[pi++]];
2592 FORC(2) free (huff[c]);
2595 int CLASS kodak_65000_decode (short *out, int bsize)
2600 int save, bits=0, i, j, len, diff;
2603 bsize = (bsize + 3) & -4;
2604 for (i=0; i < bsize; i+=2) {
2606 if ((blen[i ] = c & 15) > 12 ||
2607 (blen[i+1] = c >> 4) > 12 ) {
2608 fseek (ifp, save, SEEK_SET);
2609 for (i=0; i < bsize; i+=8) {
2610 read_shorts (raw, 6);
2611 out[i ] = raw[0] >> 12 << 8 | raw[2] >> 12 << 4 | raw[4] >> 12;
2612 out[i+1] = raw[1] >> 12 << 8 | raw[3] >> 12 << 4 | raw[5] >> 12;
2613 for (j=0; j < 6; j++)
2614 out[i+2+j] = raw[j] & 0xfff;
2619 if ((bsize & 7) == 4) {
2620 bitbuf = fgetc(ifp) << 8;
2621 bitbuf += fgetc(ifp);
2624 for (i=0; i < bsize; i++) {
2627 for (j=0; j < 32; j+=8)
2628 bitbuf += (INT64) fgetc(ifp) << (bits+(j^8));
2631 diff = bitbuf & (0xffff >> (16-len));
2634 if ((diff & (1 << (len-1))) == 0)
2635 diff -= (1 << len) - 1;
2641 void CLASS kodak_65000_load_raw()
2644 int row, col, len, pred[2], ret, i;
2646 for (row=0; row < height; row++)
2647 for (col=0; col < width; col+=256) {
2648 pred[0] = pred[1] = 0;
2649 len = MIN (256, width-col);
2650 ret = kodak_65000_decode (buf, len);
2651 for (i=0; i < len; i++)
2652 if ((RAW(row,col+i) = curve[ret ? buf[i] :
2653 (pred[i & 1] += buf[i])]) >> 12) derror();
2657 void CLASS kodak_ycbcr_load_raw()
2659 short buf[384], *bp;
2660 int row, col, len, c, i, j, k, y[2][2], cb, cr, rgb[3];
2664 for (row=0; row < height; row+=2)
2665 for (col=0; col < width; col+=128) {
2666 len = MIN (128, width-col);
2667 kodak_65000_decode (buf, len*3);
2668 y[0][1] = y[1][1] = cb = cr = 0;
2669 for (bp=buf, i=0; i < len; i+=2, bp+=2) {
2672 rgb[1] = -((cb + cr + 2) >> 2);
2673 rgb[2] = rgb[1] + cb;
2674 rgb[0] = rgb[1] + cr;
2675 for (j=0; j < 2; j++)
2676 for (k=0; k < 2; k++) {
2677 if ((y[j][k] = y[j][k^1] + *bp++) >> 10) derror();
2678 ip = image[(row+j)*width + col+i+k];
2679 FORC3 ip[c] = curve[LIM(y[j][k]+rgb[c], 0, 0xfff)];
2685 void CLASS kodak_rgb_load_raw()
2687 short buf[768], *bp;
2688 int row, col, len, c, i, rgb[3];
2689 ushort *ip=image[0];
2691 for (row=0; row < height; row++)
2692 for (col=0; col < width; col+=256) {
2693 len = MIN (256, width-col);
2694 kodak_65000_decode (buf, len*3);
2695 memset (rgb, 0, sizeof rgb);
2696 for (bp=buf, i=0; i < len; i++, ip+=4)
2697 FORC3 if ((ip[c] = rgb[c] += *bp++) >> 12) derror();
2701 void CLASS kodak_thumb_load_raw()
2704 colors = thumb_misc >> 5;
2705 for (row=0; row < height; row++)
2706 for (col=0; col < width; col++)
2707 read_shorts (image[row*width+col], colors);
2708 maximum = (1 << (thumb_misc & 31)) - 1;
2711 void CLASS sony_decrypt (unsigned *data, int len, int start, int key)
2713 unsigned p = sony_p, *pad = sony_pad;;
2715 for (p=0; p < 4; p++)
2716 pad[p] = key = key * 48828125 + 1;
2717 pad[3] = pad[3] << 1 | (pad[0]^pad[2]) >> 31;
2718 for (p=4; p < 127; p++)
2719 pad[p] = (pad[p-4]^pad[p-2]) << 1 | (pad[p-3]^pad[p-1]) >> 31;
2720 for (p=0; p < 127; p++)
2721 pad[p] = htonl(pad[p]);
2723 while (len-- && p++)
2724 *data++ ^= pad[(p-1) & 127] = pad[p & 127] ^ pad[(p+64) & 127];
2728 void CLASS sony_load_raw()
2732 unsigned i, key, row, col;
2734 fseek (ifp, 200896, SEEK_SET);
2735 fseek (ifp, (unsigned) fgetc(ifp)*4 - 1, SEEK_CUR);
2738 fseek (ifp, 164600, SEEK_SET);
2739 fread (head, 1, 40, ifp);
2740 sony_decrypt ((unsigned *) head, 10, 1, key);
2741 for (i=26; i-- > 22; )
2742 key = key << 8 | head[i];
2743 fseek (ifp, data_offset, SEEK_SET);
2744 for (row=0; row < raw_height; row++) {
2745 pixel = raw_image + row*raw_width;
2746 if (fread (pixel, 2, raw_width, ifp) < raw_width) derror();
2747 sony_decrypt ((unsigned *) pixel, raw_width/2, !row, key);
2748 for (col=0; col < raw_width; col++)
2749 if ((pixel[col] = ntohs(pixel[col])) >> 14) derror();
2754 void CLASS sony_arw_load_raw()
2757 static const ushort tab[18] =
2758 { 0xf11,0xf10,0xe0f,0xd0e,0xc0d,0xb0c,0xa0b,0x90a,0x809,
2759 0x708,0x607,0x506,0x405,0x304,0x303,0x300,0x202,0x201 };
2760 int i, c, n, col, row, sum=0;
2763 for (n=i=0; i < 18; i++)
2764 FORC(32768 >> (tab[i] >> 8)) huff[++n] = tab[i];
2766 for (col = raw_width; col--; )
2767 for (row=0; row < raw_height+1; row+=2) {
2768 if (row == raw_height) row = 1;
2769 if ((sum += ljpeg_diff(huff)) >> 12) derror();
2770 if (row < height) RAW(row,col) = sum;
2774 void CLASS sony_arw2_load_raw()
2778 int row, col, val, max, min, imax, imin, sh, bit, i;
2780 data = (uchar *) malloc (raw_width+1);
2781 merror (data, "sony_arw2_load_raw()");
2782 for (row=0; row < height; row++) {
2783 fread (data, 1, raw_width, ifp);
2784 for (dp=data, col=0; col < raw_width-30; dp+=16) {
2785 max = 0x7ff & (val = sget4(dp));
2786 min = 0x7ff & val >> 11;
2787 imax = 0x0f & val >> 22;
2788 imin = 0x0f & val >> 26;
2789 for (sh=0; sh < 4 && 0x80 << sh <= max-min; sh++);
2790 for (bit=30, i=0; i < 16; i++)
2791 if (i == imax) pix[i] = max;
2792 else if (i == imin) pix[i] = min;
2794 pix[i] = ((sget2(dp+(bit >> 3)) >> (bit & 7) & 0x7f) << sh) + min;
2795 if (pix[i] > 0x7ff) pix[i] = 0x7ff;
2798 for (i=0; i < 16; i++, col+=2)
2799 RAW(row,col) = curve[pix[i] << 1] >> 2;
2800 col -= col & 1 ? 1:31;
2806 void CLASS samsung_load_raw()
2808 int row, col, c, i, dir, op[4], len[4];
2811 for (row=0; row < raw_height; row++) {
2812 fseek (ifp, strip_offset+row*4, SEEK_SET);
2813 fseek (ifp, data_offset+get4(), SEEK_SET);
2815 FORC4 len[c] = row < 2 ? 7:4;
2816 for (col=0; col < raw_width; col+=16) {
2818 FORC4 op[c] = ph1_bits(2);
2819 FORC4 switch (op[c]) {
2820 case 3: len[c] = ph1_bits(4); break;
2821 case 2: len[c]--; break;
2824 for (c=0; c < 16; c+=2) {
2825 i = len[((c & 1) << 1) | (c >> 3)];
2826 RAW(row,col+c) = ((signed) ph1_bits(i) << (32-i) >> (32-i)) +
2827 (dir ? RAW(row+(~c | -2),col+c) : col ? RAW(row,col+(c | -2)) : 128);
2828 if (c == 14) c = -1;
2832 for (row=0; row < raw_height-1; row+=2)
2833 for (col=0; col < raw_width-1; col+=2)
2834 SWAP (RAW(row,col+1), RAW(row+1,col));
2837 void CLASS samsung2_load_raw()
2839 static const ushort tab[14] =
2840 { 0x304,0x307,0x206,0x205,0x403,0x600,0x709,
2841 0x80a,0x90b,0xa0c,0xa0d,0x501,0x408,0x402 };
2842 ushort huff[1026], vpred[2][2] = {{0,0},{0,0}}, hpred[2];
2843 int i, c, n, row, col, diff;
2846 for (n=i=0; i < 14; i++)
2847 FORC(1024 >> (tab[i] >> 8)) huff[++n] = tab[i];
2849 for (row=0; row < raw_height; row++)
2850 for (col=0; col < raw_width; col++) {
2851 diff = ljpeg_diff (huff);
2852 if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
2853 else hpred[col & 1] += diff;
2854 RAW(row,col) = hpred[col & 1];
2855 if (hpred[col & 1] >> tiff_bps) derror();
2859 void CLASS samsung3_load_raw()
2861 int opt, init, mag, pmode, row, tab, col, pred, diff, i, c;
2862 ushort lent[3][2], len[4], *prow[2];
2865 fseek (ifp, 9, SEEK_CUR);
2867 init = (get2(),get2());
2868 for (row=0; row < raw_height; row++) {
2869 fseek (ifp, (data_offset-ftell(ifp)) & 15, SEEK_CUR);
2872 FORC(6) ((ushort *)lent)[c] = row < 2 ? 7:4;
2873 prow[ row & 1] = &RAW(row-1,1-((row & 1) << 1)); // green
2874 prow[~row & 1] = &RAW(row-2,0); // red and blue
2875 for (tab=0; tab+15 < raw_width; tab+=16) {
2876 if (~opt & 4 && !(tab & 63)) {
2878 mag = i < 3 ? mag-'2'+"204"[i] : ph1_bits(12);
2881 pmode = 7 - 4*ph1_bits(1);
2882 else if (!ph1_bits(1))
2883 pmode = ph1_bits(3);
2884 if (opt & 1 || !ph1_bits(1)) {
2885 FORC4 len[c] = ph1_bits(2);
2887 i = ((row & 1) << 1 | (c & 1)) % 3;
2888 len[c] = len[c] < 3 ? lent[i][0]-'1'+"120"[len[c]] : ph1_bits(4);
2889 lent[i][0] = lent[i][1];
2890 lent[i][1] = len[c];
2894 col = tab + (((c & 7) << 1)^(c >> 3)^(row & 1));
2895 pred = (pmode == 7 || row < 2)
2896 ? (tab ? RAW(row,tab-2+(col & 1)) : init)
2897 : (prow[col & 1][col-'4'+"0224468"[pmode]] +
2898 prow[col & 1][col-'4'+"0244668"[pmode]] + 1) >> 1;
2899 diff = ph1_bits (i = len[c >> 2]);
2900 if (diff >> (i-1)) diff -= 1 << i;
2901 diff = diff * (mag*2+1) + mag;
2902 RAW(row,col) = pred + diff;
2908 #define HOLE(row) ((holes >> (((row) - raw_height) & 7)) & 1)
2910 /* Kudos to Rich Taylor for figuring out SMaL's compression algorithm. */
2911 void CLASS smal_decode_segment (unsigned seg[2][2], int holes)
2913 uchar hist[3][18] = {
2914 { 7, 7, 0, 0, 63, 55, 47, 39, 31, 23, 15, 7, 0 },
2915 { 7, 7, 0, 0, 63, 55, 47, 39, 31, 23, 15, 7, 0 },
2916 { 3, 3, 0, 0, 63, 47, 31, 15, 0 } };
2917 int low, high=0xff, carry=0, nbits=8;
2918 int pix, s, count, bin, next, i, sym[3];
2919 uchar diff, pred[]={0,0};
2920 ushort data=0, range=0;
2922 fseek (ifp, seg[0][1]+1, SEEK_SET);
2924 if (seg[1][0] > raw_width*raw_height)
2925 seg[1][0] = raw_width*raw_height;
2926 for (pix=seg[0][0]; pix < seg[1][0]; pix++) {
2927 for (s=0; s < 3; s++) {
2928 data = data << nbits | getbits(nbits);
2930 carry = (nbits += carry+1) < 1 ? nbits-1 : 0;
2931 while (--nbits >= 0)
2932 if ((data >> nbits & 0xff) == 0xff) break;
2934 data = ((data & ((1 << (nbits-1)) - 1)) << 1) |
2935 ((data + (((data & (1 << (nbits-1)))) << 1)) & (-1 << nbits));
2940 count = ((((data-range+1) & 0xffff) << 2) - 1) / (high >> 4);
2941 for (bin=0; hist[s][bin+5] > count; bin++);
2942 low = hist[s][bin+5] * (high >> 4) >> 2;
2943 if (bin) high = hist[s][bin+4] * (high >> 4) >> 2;
2945 for (nbits=0; high << nbits < 128; nbits++);
2946 range = (range+low) << nbits;
2949 if (++hist[s][2] > hist[s][3]) {
2950 next = (next+1) & hist[s][0];
2951 hist[s][3] = (hist[s][next+4] - hist[s][next+5]) >> 2;
2954 if (hist[s][hist[s][1]+4] - hist[s][hist[s][1]+5] > 1) {
2955 if (bin < hist[s][1])
2956 for (i=bin; i < hist[s][1]; i++) hist[s][i+5]--;
2957 else if (next <= bin)
2958 for (i=hist[s][1]; i < bin; i++) hist[s][i+5]++;
2963 diff = sym[2] << 5 | sym[1] << 2 | (sym[0] & 3);
2965 diff = diff ? -diff : 0x80;
2966 if (ftell(ifp) + 12 >= seg[1][1])
2968 raw_image[pix] = pred[pix & 1] += diff;
2969 if (!(pix & 1) && HOLE(pix / raw_width)) pix += 2;
2974 void CLASS smal_v6_load_raw()
2978 fseek (ifp, 16, SEEK_SET);
2981 seg[1][0] = raw_width * raw_height;
2982 seg[1][1] = INT_MAX;
2983 smal_decode_segment (seg, 0);
2986 int CLASS median4 (int *p)
2988 int min, max, sum, i;
2990 min = max = sum = p[0];
2991 for (i=1; i < 4; i++) {
2993 if (min > p[i]) min = p[i];
2994 if (max < p[i]) max = p[i];
2996 return (sum - min - max) >> 1;
2999 void CLASS fill_holes (int holes)
3001 int row, col, val[4];
3003 for (row=2; row < height-2; row++) {
3004 if (!HOLE(row)) continue;
3005 for (col=1; col < width-1; col+=4) {
3006 val[0] = RAW(row-1,col-1);
3007 val[1] = RAW(row-1,col+1);
3008 val[2] = RAW(row+1,col-1);
3009 val[3] = RAW(row+1,col+1);
3010 RAW(row,col) = median4(val);
3012 for (col=2; col < width-2; col+=4)
3013 if (HOLE(row-2) || HOLE(row+2))
3014 RAW(row,col) = (RAW(row,col-2) + RAW(row,col+2)) >> 1;
3016 val[0] = RAW(row,col-2);
3017 val[1] = RAW(row,col+2);
3018 val[2] = RAW(row-2,col);
3019 val[3] = RAW(row+2,col);
3020 RAW(row,col) = median4(val);
3025 void CLASS smal_v9_load_raw()
3027 unsigned seg[256][2], offset, nseg, holes, i;
3029 fseek (ifp, 67, SEEK_SET);
3031 nseg = (uchar) fgetc(ifp);
3032 fseek (ifp, offset, SEEK_SET);
3033 for (i=0; i < nseg*2; i++)
3034 ((unsigned *)seg)[i] = get4() + data_offset*(i & 1);
3035 fseek (ifp, 78, SEEK_SET);
3037 fseek (ifp, 88, SEEK_SET);
3038 seg[nseg][0] = raw_height * raw_width;
3039 seg[nseg][1] = get4() + data_offset;
3040 for (i=0; i < nseg; i++)
3041 smal_decode_segment (seg+i, holes);
3042 if (holes) fill_holes (holes);
3045 void CLASS redcine_load_raw()
3056 in = jas_stream_fopen (ifname, "rb");
3057 jas_stream_seek (in, data_offset+20, SEEK_SET);
3058 jimg = jas_image_decode (in, -1, 0);
3059 if (!jimg) longjmp (failure, 3);
3060 jmat = jas_matrix_create (height/2, width/2);
3061 merror (jmat, "redcine_load_raw()");
3062 img = (ushort *) calloc ((height+2), (width+2)*2);
3063 merror (img, "redcine_load_raw()");
3065 jas_image_readcmpt (jimg, c, 0, 0, width/2, height/2, jmat);
3066 data = jas_matrix_getref (jmat, 0, 0);
3067 for (row = c >> 1; row < height; row+=2)
3068 for (col = c & 1; col < width; col+=2)
3069 img[(row+1)*(width+2)+col+1] = data[(row/2)*(width/2)+col/2];
3071 for (col=1; col <= width; col++) {
3072 img[col] = img[2*(width+2)+col];
3073 img[(height+1)*(width+2)+col] = img[(height-1)*(width+2)+col];
3075 for (row=0; row < height+2; row++) {
3076 img[row*(width+2)] = img[row*(width+2)+2];
3077 img[(row+1)*(width+2)-1] = img[(row+1)*(width+2)-3];
3079 for (row=1; row <= height; row++) {
3080 pix = img + row*(width+2) + (col = 1 + (FC(row,1) & 1));
3081 for ( ; col <= width; col+=2, pix+=2) {
3082 c = (((pix[0] - 0x800) << 3) +
3083 pix[-(width+2)] + pix[width+2] + pix[-1] + pix[1]) >> 2;
3084 pix[0] = LIM(c,0,4095);
3087 for (row=0; row < height; row++)
3088 for (col=0; col < width; col++)
3089 RAW(row,col) = curve[img[(row+1)*(width+2)+col+1]];
3091 jas_matrix_destroy (jmat);
3092 jas_image_destroy (jimg);
3093 jas_stream_close (in);
3097 /* RESTRICTED code starts here */
3099 void CLASS foveon_decoder (unsigned size, unsigned code)
3101 unsigned *huff = fov_huff;
3106 for (i=0; i < size; i++)
3108 memset (first_decode, 0, sizeof first_decode);
3109 free_decode = first_decode;
3111 cur = free_decode++;
3112 if (free_decode > first_decode+2048) {
3113 fprintf (stderr,_("%s: decoder table overflow\n"), ifname);
3114 longjmp (failure, 2);
3117 for (i=0; i < size; i++)
3118 if (huff[i] == code) {
3122 if ((len = code >> 27) > 26) return;
3123 code = (len+1) << 27 | (code & 0x3ffffff) << 1;
3125 cur->branch[0] = free_decode;
3126 foveon_decoder (size, code);
3127 cur->branch[1] = free_decode;
3128 foveon_decoder (size, code+1);
3131 void CLASS foveon_thumb()
3133 unsigned bwide, row, col, bitbuf=0, bit=1, c, i;
3135 struct decode *dindex;
3139 fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
3141 if (bwide < thumb_width*3) return;
3142 buf = (char *) malloc (bwide);
3143 merror (buf, "foveon_thumb()");
3144 for (row=0; row < thumb_height; row++) {
3145 fread (buf, 1, bwide, ifp);
3146 fwrite (buf, 3, thumb_width, ofp);
3151 foveon_decoder (256, 0);
3153 for (row=0; row < thumb_height; row++) {
3154 memset (pred, 0, sizeof pred);
3156 for (bit=col=0; col < thumb_width; col++)
3158 for (dindex=first_decode; dindex->branch[0]; ) {
3159 if ((bit = (bit-1) & 31) == 31)
3160 for (i=0; i < 4; i++)
3161 bitbuf = (bitbuf << 8) + fgetc(ifp);
3162 dindex = dindex->branch[bitbuf >> bit & 1];
3164 pred[c] += dindex->leaf;
3165 fputc (pred[c], ofp);
3170 void CLASS foveon_sd_load_raw()
3172 struct decode *dindex;
3175 int pred[3], row, col, bit=-1, c, i;
3177 read_shorts ((ushort *) diff, 1024);
3178 if (!load_flags) foveon_decoder (1024, 0);
3180 for (row=0; row < height; row++) {
3181 memset (pred, 0, sizeof pred);
3182 if (!bit && !load_flags && atoi(model+2) < 14) get4();
3183 for (col=bit=0; col < width; col++) {
3186 FORC3 pred[2-c] += diff[bitbuf >> c*10 & 0x3ff];
3189 for (dindex=first_decode; dindex->branch[0]; ) {
3190 if ((bit = (bit-1) & 31) == 31)
3191 for (i=0; i < 4; i++)
3192 bitbuf = (bitbuf << 8) + fgetc(ifp);
3193 dindex = dindex->branch[bitbuf >> bit & 1];
3195 pred[c] += diff[dindex->leaf];
3196 if (pred[c] >> 16 && ~pred[c] >> 16) derror();
3198 FORC3 image[row*width+col][c] = pred[c];
3203 void CLASS foveon_huff (ushort *huff)
3205 int i, j, clen, code;
3208 for (i=0; i < 13; i++) {
3211 for (j=0; j < 256 >> clen; )
3212 huff[code+ ++j] = clen << 8 | i;
3217 void CLASS foveon_dp_load_raw()
3219 unsigned c, roff[4], row, col, diff;
3220 ushort huff[512], vpred[2][2], hpred[2];
3222 fseek (ifp, 8, SEEK_CUR);
3225 FORC3 roff[c+1] = -(-(roff[c] + get4()) & -16);
3227 fseek (ifp, data_offset+roff[c], SEEK_SET);
3229 vpred[0][0] = vpred[0][1] = vpred[1][0] = vpred[1][1] = 512;
3230 for (row=0; row < height; row++) {
3231 for (col=0; col < width; col++) {
3232 diff = ljpeg_diff(huff);
3233 if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
3234 else hpred[col & 1] += diff;
3235 image[row*width+col][c] = hpred[col & 1];
3241 void CLASS foveon_load_camf()
3243 unsigned type, wide, high, i, j, row, col, diff;
3244 ushort huff[258], vpred[2][2] = {{512,512},{512,512}}, hpred[2];
3246 fseek (ifp, meta_offset, SEEK_SET);
3247 type = get4(); get4(); get4();
3251 fread (meta_data, 1, meta_length, ifp);
3252 for (i=0; i < meta_length; i++) {
3253 high = (high * 1597 + 51749) % 244944;
3254 wide = high * (INT64) 301593171 >> 24;
3255 meta_data[i] ^= ((((high << 8) - wide) >> 1) + wide) >> 17;
3257 } else if (type == 4) {
3259 meta_data = (char *) malloc (meta_length = wide*high*3/2);
3260 merror (meta_data, "foveon_load_camf()");
3264 for (j=row=0; row < high; row++) {
3265 for (col=0; col < wide; col++) {
3266 diff = ljpeg_diff(huff);
3267 if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
3268 else hpred[col & 1] += diff;
3270 meta_data[j++] = hpred[0] >> 4;
3271 meta_data[j++] = hpred[0] << 4 | hpred[1] >> 8;
3272 meta_data[j++] = hpred[1];
3277 fprintf (stderr,_("%s has unknown CAMF type %d.\n"), ifname, type);
3280 const char * CLASS foveon_camf_param (const char *block, const char *param)
3283 char *pos, *cp, *dp;
3285 for (idx=0; idx < meta_length; idx += sget4(pos+8)) {
3286 pos = meta_data + idx;
3287 if (strncmp (pos, "CMb", 3)) break;
3288 if (pos[3] != 'P') continue;
3289 if (strcmp (block, pos+sget4(pos+12))) continue;
3290 cp = pos + sget4(pos+16);
3292 dp = pos + sget4(cp+4);
3295 if (!strcmp (param, dp+sget4(cp)))
3296 return dp+sget4(cp+4);
3302 void * CLASS foveon_camf_matrix (unsigned dim[3], const char *name)
3304 unsigned i, idx, type, ndim, size, *mat;
3305 char *pos, *cp, *dp;
3308 for (idx=0; idx < meta_length; idx += sget4(pos+8)) {
3309 pos = meta_data + idx;
3310 if (strncmp (pos, "CMb", 3)) break;
3311 if (pos[3] != 'M') continue;
3312 if (strcmp (name, pos+sget4(pos+12))) continue;
3313 dim[0] = dim[1] = dim[2] = 1;
3314 cp = pos + sget4(pos+16);
3316 if ((ndim = sget4(cp+4)) > 3) break;
3317 dp = pos + sget4(cp+8);
3318 for (i=ndim; i--; ) {
3322 if ((dsize = (double) dim[0]*dim[1]*dim[2]) > meta_length/4) break;
3323 mat = (unsigned *) malloc ((size = dsize) * 4);
3324 merror (mat, "foveon_camf_matrix()");
3325 for (i=0; i < size; i++)
3326 if (type && type != 6)
3327 mat[i] = sget4(dp + i*4);
3329 mat[i] = sget4(dp + i*2) & 0xffff;
3332 fprintf (stderr,_("%s: \"%s\" matrix not found!\n"), ifname, name);
3336 int CLASS foveon_fixed (void *ptr, int size, const char *name)
3341 if (!name) return 0;
3342 dp = foveon_camf_matrix (dim, name);
3344 memcpy (ptr, dp, size*4);
3349 float CLASS foveon_avg (short *pix, int range[2], float cfilt)
3352 float val, min=FLT_MAX, max=-FLT_MAX, sum=0;
3354 for (i=range[0]; i <= range[1]; i++) {
3355 sum += val = pix[i*4] + (pix[i*4]-pix[(i-1)*4]) * cfilt;
3356 if (min > val) min = val;
3357 if (max < val) max = val;
3359 if (range[1] - range[0] == 1) return sum/2;
3360 return (sum - min - max) / (range[1] - range[0] - 1);
3363 short * CLASS foveon_make_curve (double max, double mul, double filt)
3369 if (!filt) filt = 0.8;
3370 size = 4*M_PI*max / filt;
3371 if (size == UINT_MAX) size--;
3372 curve = (short *) calloc (size+1, sizeof *curve);
3373 merror (curve, "foveon_make_curve()");
3375 for (i=0; i < size; i++) {
3377 curve[i+1] = (cos(x)+1)/2 * tanh(i*filt/mul) * mul + 0.5;
3382 void CLASS foveon_make_curves
3383 (short **curvep, float dq[3], float div[3], float filt)
3385 double mul[3], max=0;
3388 FORC3 mul[c] = dq[c]/div[c];
3389 FORC3 if (max < mul[c]) max = mul[c];
3390 FORC3 curvep[c] = foveon_make_curve (max, mul[c], filt);
3393 int CLASS foveon_apply_curve (short *curve, int i)
3395 if (abs(i) >= curve[0]) return 0;
3396 return i < 0 ? -curve[1-i] : curve[1+i];
3399 #define image ((short (*)[4]) image)
3401 void CLASS foveon_interpolate()
3403 static const short hood[] = { -1,-1, -1,0, -1,1, 0,-1, 0,1, 1,-1, 1,0, 1,1 };
3404 short *pix, prev[3], *curve[8], (*shrink)[3];
3405 float cfilt=0, ddft[3][3][2], ppm[3][3][3];
3406 float cam_xyz[3][3], correct[3][3], last[3][3], trans[3][3];
3407 float chroma_dq[3], color_dq[3], diag[3][3], div[3];
3408 float (*black)[3], (*sgain)[3], (*sgrow)[3];
3409 float fsum[3], val, frow, num;
3410 int row, col, c, i, j, diff, sgx, irow, sum, min, max, limit;
3411 int dscr[2][2], dstb[4], (*smrow[7])[3], total[4], ipix[3];
3412 int work[3][3], smlast, smred, smred_p=0, dev[3];
3413 int satlev[3], keep[4], active[4];
3414 unsigned dim[3], *badpix;
3415 double dsum=0, trsum[3];
3420 fprintf (stderr,_("Foveon interpolation...\n"));
3423 foveon_fixed (dscr, 4, "DarkShieldColRange");
3424 foveon_fixed (ppm[0][0], 27, "PostPolyMatrix");
3425 foveon_fixed (satlev, 3, "SaturationLevel");
3426 foveon_fixed (keep, 4, "KeepImageArea");
3427 foveon_fixed (active, 4, "ActiveImageArea");
3428 foveon_fixed (chroma_dq, 3, "ChromaDQ");
3429 foveon_fixed (color_dq, 3,
3430 foveon_camf_param ("IncludeBlocks", "ColorDQ") ?
3431 "ColorDQ" : "ColorDQCamRGB");
3432 if (foveon_camf_param ("IncludeBlocks", "ColumnFilter"))
3433 foveon_fixed (&cfilt, 1, "ColumnFilter");
3435 memset (ddft, 0, sizeof ddft);
3436 if (!foveon_camf_param ("IncludeBlocks", "DarkDrift")
3437 || !foveon_fixed (ddft[1][0], 12, "DarkDrift"))
3438 for (i=0; i < 2; i++) {
3439 foveon_fixed (dstb, 4, i ? "DarkShieldBottom":"DarkShieldTop");
3440 for (row = dstb[1]; row <= dstb[3]; row++)
3441 for (col = dstb[0]; col <= dstb[2]; col++)
3442 FORC3 ddft[i+1][c][1] += (short) image[row*width+col][c];
3443 FORC3 ddft[i+1][c][1] /= (dstb[3]-dstb[1]+1) * (dstb[2]-dstb[0]+1);
3446 if (!(cp = foveon_camf_param ("WhiteBalanceIlluminants", model2)))
3447 { fprintf (stderr,_("%s: Invalid white balance \"%s\"\n"), ifname, model2);
3449 foveon_fixed (cam_xyz, 9, cp);
3450 foveon_fixed (correct, 9,
3451 foveon_camf_param ("WhiteBalanceCorrections", model2));
3452 memset (last, 0, sizeof last);
3453 for (i=0; i < 3; i++)
3454 for (j=0; j < 3; j++)
3455 FORC3 last[i][j] += correct[i][c] * cam_xyz[c][j];
3457 #define LAST(x,y) last[(i+x)%3][(c+y)%3]
3458 for (i=0; i < 3; i++)
3459 FORC3 diag[c][i] = LAST(1,1)*LAST(2,2) - LAST(1,2)*LAST(2,1);
3461 FORC3 div[c] = diag[c][0]*0.3127 + diag[c][1]*0.329 + diag[c][2]*0.3583;
3462 sprintf (str, "%sRGBNeutral", model2);
3463 if (foveon_camf_param ("IncludeBlocks", str))
3464 foveon_fixed (div, 3, str);
3466 FORC3 if (num < div[c]) num = div[c];
3467 FORC3 div[c] /= num;
3469 memset (trans, 0, sizeof trans);
3470 for (i=0; i < 3; i++)
3471 for (j=0; j < 3; j++)
3472 FORC3 trans[i][j] += rgb_cam[i][c] * last[c][j] * div[j];
3473 FORC3 trsum[c] = trans[c][0] + trans[c][1] + trans[c][2];
3474 dsum = (6*trsum[0] + 11*trsum[1] + 3*trsum[2]) / 20;
3475 for (i=0; i < 3; i++)
3476 FORC3 last[i][c] = trans[i][c] * dsum / trsum[i];
3477 memset (trans, 0, sizeof trans);
3478 for (i=0; i < 3; i++)
3479 for (j=0; j < 3; j++)
3480 FORC3 trans[i][j] += (i==c ? 32 : -1) * last[c][j] / 30;
3482 foveon_make_curves (curve, color_dq, div, cfilt);
3483 FORC3 chroma_dq[c] /= 3;
3484 foveon_make_curves (curve+3, chroma_dq, div, cfilt);
3485 FORC3 dsum += chroma_dq[c] / div[c];
3486 curve[6] = foveon_make_curve (dsum, dsum, cfilt);
3487 curve[7] = foveon_make_curve (dsum*2, dsum*2, cfilt);
3489 sgain = (float (*)[3]) foveon_camf_matrix (dim, "SpatialGain");
3491 sgrow = (float (*)[3]) calloc (dim[1], sizeof *sgrow);
3492 sgx = (width + dim[1]-2) / (dim[1]-1);
3494 black = (float (*)[3]) calloc (height, sizeof *black);
3495 for (row=0; row < height; row++) {
3496 for (i=0; i < 6; i++)
3497 ((float *)ddft[0])[i] = ((float *)ddft[1])[i] +
3498 row / (height-1.0) * (((float *)ddft[2])[i] - ((float *)ddft[1])[i]);
3499 FORC3 black[row][c] =
3500 ( foveon_avg (image[row*width]+c, dscr[0], cfilt) +
3501 foveon_avg (image[row*width]+c, dscr[1], cfilt) * 3
3502 - ddft[0][c][0] ) / 4 - ddft[0][c][1];
3504 memcpy (black, black+8, sizeof *black*8);
3505 memcpy (black+height-11, black+height-22, 11*sizeof *black);
3506 memcpy (last, black, sizeof last);
3508 for (row=1; row < height-1; row++) {
3509 FORC3 if (last[1][c] > last[0][c]) {
3510 if (last[1][c] > last[2][c])
3511 black[row][c] = (last[0][c] > last[2][c]) ? last[0][c]:last[2][c];
3513 if (last[1][c] < last[2][c])
3514 black[row][c] = (last[0][c] < last[2][c]) ? last[0][c]:last[2][c];
3515 memmove (last, last+1, 2*sizeof last[0]);
3516 memcpy (last[2], black[row+1], sizeof last[2]);
3518 FORC3 black[row][c] = (last[0][c] + last[1][c])/2;
3519 FORC3 black[0][c] = (black[1][c] + black[3][c])/2;
3521 val = 1 - exp(-1/24.0);
3522 memcpy (fsum, black, sizeof fsum);
3523 for (row=1; row < height; row++)
3524 FORC3 fsum[c] += black[row][c] =
3525 (black[row][c] - black[row-1][c])*val + black[row-1][c];
3526 memcpy (last[0], black[height-1], sizeof last[0]);
3527 FORC3 fsum[c] /= height;
3528 for (row = height; row--; )
3529 FORC3 last[0][c] = black[row][c] =
3530 (black[row][c] - fsum[c] - last[0][c])*val + last[0][c];
3532 memset (total, 0, sizeof total);
3533 for (row=2; row < height; row+=4)
3534 for (col=2; col < width; col+=4) {
3535 FORC3 total[c] += (short) image[row*width+col][c];
3538 for (row=0; row < height; row++)
3539 FORC3 black[row][c] += fsum[c]/2 + total[c]/(total[3]*100.0);
3541 for (row=0; row < height; row++) {
3542 for (i=0; i < 6; i++)
3543 ((float *)ddft[0])[i] = ((float *)ddft[1])[i] +
3544 row / (height-1.0) * (((float *)ddft[2])[i] - ((float *)ddft[1])[i]);
3545 pix = image[row*width];
3546 memcpy (prev, pix, sizeof prev);
3547 frow = row / (height-1.0) * (dim[2]-1);
3548 if ((irow = frow) == dim[2]-1) irow--;
3550 for (i=0; i < dim[1]; i++)
3551 FORC3 sgrow[i][c] = sgain[ irow *dim[1]+i][c] * (1-frow) +
3552 sgain[(irow+1)*dim[1]+i][c] * frow;
3553 for (col=0; col < width; col++) {
3555 diff = pix[c] - prev[c];
3557 ipix[c] = pix[c] + floor ((diff + (diff*diff >> 14)) * cfilt
3558 - ddft[0][c][1] - ddft[0][c][0] * ((float) col/width - 0.5)
3562 work[0][c] = ipix[c] * ipix[c] >> 14;
3563 work[2][c] = ipix[c] * work[0][c] >> 14;
3564 work[1][2-c] = ipix[(c+1) % 3] * ipix[(c+2) % 3] >> 14;
3567 for (val=i=0; i < 3; i++)
3568 for ( j=0; j < 3; j++)
3569 val += ppm[c][i][j] * work[i][j];
3570 ipix[c] = floor ((ipix[c] + floor(val)) *
3571 ( sgrow[col/sgx ][c] * (sgx - col%sgx) +
3572 sgrow[col/sgx+1][c] * (col%sgx) ) / sgx / div[c]);
3573 if (ipix[c] > 32000) ipix[c] = 32000;
3583 if ((badpix = (unsigned *) foveon_camf_matrix (dim, "BadPixels"))) {
3584 for (i=0; i < dim[0]; i++) {
3585 col = (badpix[i] >> 8 & 0xfff) - keep[0];
3586 row = (badpix[i] >> 20 ) - keep[1];
3587 if ((unsigned)(row-1) > height-3 || (unsigned)(col-1) > width-3)
3589 memset (fsum, 0, sizeof fsum);
3590 for (sum=j=0; j < 8; j++)
3591 if (badpix[i] & (1 << j)) {
3592 FORC3 fsum[c] += (short)
3593 image[(row+hood[j*2])*width+col+hood[j*2+1]][c];
3596 if (sum) FORC3 image[row*width+col][c] = fsum[c]/sum;
3601 /* Array for 5x5 Gaussian averaging of red values */
3602 smrow[6] = (int (*)[3]) calloc (width*5, sizeof **smrow);
3603 merror (smrow[6], "foveon_interpolate()");
3604 for (i=0; i < 5; i++)
3605 smrow[i] = smrow[6] + i*width;
3607 /* Sharpen the reds against these Gaussian averages */
3608 for (smlast=-1, row=2; row < height-2; row++) {
3609 while (smlast < row+2) {
3610 for (i=0; i < 6; i++)
3611 smrow[(i+5) % 6] = smrow[i];
3612 pix = image[++smlast*width+2];
3613 for (col=2; col < width-2; col++) {
3615 (pix[0]*6 + (pix[-4]+pix[4])*4 + pix[-8]+pix[8] + 8) >> 4;
3619 pix = image[row*width+2];
3620 for (col=2; col < width-2; col++) {
3621 smred = ( 6 * smrow[2][col][0]
3622 + 4 * (smrow[1][col][0] + smrow[3][col][0])
3623 + smrow[0][col][0] + smrow[4][col][0] + 8 ) >> 4;
3626 i = pix[0] + ((pix[0] - ((smred*7 + smred_p) >> 3)) >> 3);
3627 if (i > 32000) i = 32000;
3634 /* Adjust the brighter pixels for better linearity */
3637 i = satlev[c] / div[c];
3638 if (min > i) min = i;
3640 limit = min * 9 >> 4;
3641 for (pix=image[0]; pix < image[height*width]; pix+=4) {
3642 if (pix[0] <= limit || pix[1] <= limit || pix[2] <= limit)
3645 for (c=1; c < 3; c++) {
3646 if (min > pix[c]) min = pix[c];
3647 if (max < pix[c]) max = pix[c];
3649 if (min >= limit*2) {
3650 pix[0] = pix[1] = pix[2] = max;
3652 i = 0x4000 - ((min - limit) << 14) / limit;
3653 i = 0x4000 - (i*i >> 14);
3655 FORC3 pix[c] += (max - pix[c]) * i >> 14;
3659 Because photons that miss one detector often hit another,
3660 the sum R+G+B is much less noisy than the individual colors.
3661 So smooth the hues without smoothing the total.
3663 for (smlast=-1, row=2; row < height-2; row++) {
3664 while (smlast < row+2) {
3665 for (i=0; i < 6; i++)
3666 smrow[(i+5) % 6] = smrow[i];
3667 pix = image[++smlast*width+2];
3668 for (col=2; col < width-2; col++) {
3669 FORC3 smrow[4][col][c] = (pix[c-4]+2*pix[c]+pix[c+4]+2) >> 2;
3673 pix = image[row*width+2];
3674 for (col=2; col < width-2; col++) {
3675 FORC3 dev[c] = -foveon_apply_curve (curve[7], pix[c] -
3676 ((smrow[1][col][c] + 2*smrow[2][col][c] + smrow[3][col][c]) >> 2));
3677 sum = (dev[0] + dev[1] + dev[2]) >> 3;
3678 FORC3 pix[c] += dev[c] - sum;
3682 for (smlast=-1, row=2; row < height-2; row++) {
3683 while (smlast < row+2) {
3684 for (i=0; i < 6; i++)
3685 smrow[(i+5) % 6] = smrow[i];
3686 pix = image[++smlast*width+2];
3687 for (col=2; col < width-2; col++) {
3688 FORC3 smrow[4][col][c] =
3689 (pix[c-8]+pix[c-4]+pix[c]+pix[c+4]+pix[c+8]+2) >> 2;
3693 pix = image[row*width+2];
3694 for (col=2; col < width-2; col++) {
3695 for (total[3]=375, sum=60, c=0; c < 3; c++) {
3696 for (total[c]=i=0; i < 5; i++)
3697 total[c] += smrow[i][col][c];
3698 total[3] += total[c];
3701 if (sum < 0) sum = 0;
3702 j = total[3] > 375 ? (sum << 16) / total[3] : sum * 174;
3703 FORC3 pix[c] += foveon_apply_curve (curve[6],
3704 ((j*total[c] + 0x8000) >> 16) - pix[c]);
3709 /* Transform the image to a different colorspace */
3710 for (pix=image[0]; pix < image[height*width]; pix+=4) {
3711 FORC3 pix[c] -= foveon_apply_curve (curve[c], pix[c]);
3712 sum = (pix[0]+pix[1]+pix[1]+pix[2]) >> 2;
3713 FORC3 pix[c] -= foveon_apply_curve (curve[c], pix[c]-sum);
3715 for (dsum=i=0; i < 3; i++)
3716 dsum += trans[c][i] * pix[i];
3717 if (dsum < 0) dsum = 0;
3718 if (dsum > 24000) dsum = 24000;
3719 ipix[c] = dsum + 0.5;
3721 FORC3 pix[c] = ipix[c];
3724 /* Smooth the image bottom-to-top and save at 1/4 scale */
3725 shrink = (short (*)[3]) calloc ((height/4), (width/4)*sizeof *shrink);
3726 merror (shrink, "foveon_interpolate()");
3727 for (row = height/4; row--; )
3728 for (col=0; col < width/4; col++) {
3729 ipix[0] = ipix[1] = ipix[2] = 0;
3730 for (i=0; i < 4; i++)
3731 for (j=0; j < 4; j++)
3732 FORC3 ipix[c] += image[(row*4+i)*width+col*4+j][c];
3734 if (row+2 > height/4)
3735 shrink[row*(width/4)+col][c] = ipix[c] >> 4;
3737 shrink[row*(width/4)+col][c] =
3738 (shrink[(row+1)*(width/4)+col][c]*1840 + ipix[c]*141 + 2048) >> 12;
3740 /* From the 1/4-scale image, smooth right-to-left */
3741 for (row=0; row < (height & ~3); row++) {
3742 ipix[0] = ipix[1] = ipix[2] = 0;
3744 for (col = width & ~3 ; col--; )
3745 FORC3 smrow[0][col][c] = ipix[c] =
3746 (shrink[(row/4)*(width/4)+col/4][c]*1485 + ipix[c]*6707 + 4096) >> 13;
3748 /* Then smooth left-to-right */
3749 ipix[0] = ipix[1] = ipix[2] = 0;
3750 for (col=0; col < (width & ~3); col++)
3751 FORC3 smrow[1][col][c] = ipix[c] =
3752 (smrow[0][col][c]*1485 + ipix[c]*6707 + 4096) >> 13;
3754 /* Smooth top-to-bottom */
3756 memcpy (smrow[2], smrow[1], sizeof **smrow * width);
3758 for (col=0; col < (width & ~3); col++)
3759 FORC3 smrow[2][col][c] =
3760 (smrow[2][col][c]*6707 + smrow[1][col][c]*1485 + 4096) >> 13;
3762 /* Adjust the chroma toward the smooth values */
3763 for (col=0; col < (width & ~3); col++) {
3764 for (i=j=30, c=0; c < 3; c++) {
3765 i += smrow[2][col][c];
3766 j += image[row*width+col][c];
3769 for (sum=c=0; c < 3; c++) {
3770 ipix[c] = foveon_apply_curve (curve[c+3],
3771 ((smrow[2][col][c] * j + 0x8000) >> 16) - image[row*width+col][c]);
3776 i = image[row*width+col][c] + ipix[c] - sum;
3778 image[row*width+col][c] = i;
3784 for (i=0; i < 8; i++)
3787 /* Trim off the black border */
3788 active[1] -= keep[1];
3790 i = active[2] - active[0];
3791 for (row=0; row < active[3]-active[1]; row++)
3792 memcpy (image[row*i], image[(row+active[1])*width+active[0]],
3799 /* RESTRICTED code ends here */
3801 void CLASS crop_masked_pixels()
3804 unsigned r, c, m, mblack[8], zero, val;
3806 if (load_raw == &CLASS phase_one_load_raw ||
3807 load_raw == &CLASS phase_one_load_raw_c)
3808 phase_one_correct();
3810 for (row=0; row < raw_height-top_margin*2; row++) {
3811 for (col=0; col < fuji_width << !fuji_layout; col++) {
3813 r = fuji_width - 1 - col + (row >> 1);
3814 c = col + ((row+1) >> 1);
3816 r = fuji_width - 1 + row - (col >> 1);
3817 c = row + ((col+1) >> 1);
3819 if (r < height && c < width)
3820 BAYER(r,c) = RAW(row+top_margin,col+left_margin);
3824 for (row=0; row < height; row++)
3825 for (col=0; col < width; col++)
3826 BAYER2(row,col) = RAW(row+top_margin,col+left_margin);
3828 if (mask[0][3] > 0) goto mask_set;
3829 if (load_raw == &CLASS canon_load_raw ||
3830 load_raw == &CLASS lossless_jpeg_load_raw) {
3831 mask[0][1] = mask[1][1] += 2;
3835 if (load_raw == &CLASS canon_600_load_raw ||
3836 load_raw == &CLASS sony_load_raw ||
3837 (load_raw == &CLASS eight_bit_load_raw && strncmp(model,"DC2",3)) ||
3838 load_raw == &CLASS kodak_262_load_raw ||
3839 (load_raw == &CLASS packed_load_raw && (load_flags & 32))) {
3841 mask[0][0] = mask[1][0] = top_margin;
3842 mask[0][2] = mask[1][2] = top_margin+height;
3843 mask[0][3] += left_margin;
3844 mask[1][1] += left_margin+width;
3845 mask[1][3] += raw_width;
3847 if (load_raw == &CLASS nokia_load_raw) {
3848 mask[0][2] = top_margin;
3852 memset (mblack, 0, sizeof mblack);
3853 for (zero=m=0; m < 8; m++)
3854 for (row=MAX(mask[m][0],0); row < MIN(mask[m][2],raw_height); row++)
3855 for (col=MAX(mask[m][1],0); col < MIN(mask[m][3],raw_width); col++) {
3856 c = FC(row-top_margin,col-left_margin);
3857 mblack[c] += val = RAW(row,col);
3861 if (load_raw == &CLASS canon_600_load_raw && width < raw_width) {
3862 black = (mblack[0]+mblack[1]+mblack[2]+mblack[3]) /
3863 (mblack[4]+mblack[5]+mblack[6]+mblack[7]) - 4;
3864 canon_600_correct();
3865 } else if (zero < mblack[4] && mblack[5] && mblack[6] && mblack[7]) {
3866 FORC4 cblack[c] = mblack[c] / mblack[4+c];
3867 cblack[4] = cblack[5] = cblack[6] = 0;
3871 void CLASS remove_zeroes()
3873 unsigned row, col, tot, n, r, c;
3875 for (row=0; row < height; row++)
3876 for (col=0; col < width; col++)
3877 if (BAYER(row,col) == 0) {
3879 for (r = row-2; r <= row+2; r++)
3880 for (c = col-2; c <= col+2; c++)
3881 if (r < height && c < width &&
3882 FC(r,c) == FC(row,col) && BAYER(r,c))
3883 tot += (n++,BAYER(r,c));
3884 if (n) BAYER(row,col) = tot/n;
3889 Seach from the current directory up to the root looking for
3890 a ".badpixels" file, and fix those pixels now.
3892 void CLASS bad_pixels (const char *cfname)
3895 char *fname, *cp, line[128];
3896 int len, time, row, col, r, c, rad, tot, n, fixed=0;
3898 if (!filters) return;
3900 fp = fopen (cfname, "r");
3902 for (len=32 ; ; len *= 2) {
3903 fname = (char *) malloc (len);
3905 if (getcwd (fname, len-16)) break;
3907 if (errno != ERANGE) return;
3909 #if defined(WIN32) || defined(DJGPP)
3910 if (fname[1] == ':')
3911 memmove (fname, fname+2, len-2);
3912 for (cp=fname; *cp; cp++)
3913 if (*cp == '\\') *cp = '/';
3915 cp = fname + strlen(fname);
3916 if (cp[-1] == '/') cp--;
3917 while (*fname == '/') {
3918 strcpy (cp, "/.badpixels");
3919 if ((fp = fopen (fname, "r"))) break;
3920 if (cp == fname) break;
3921 while (*--cp != '/');
3926 while (fgets (line, 128, fp)) {
3927 cp = strchr (line, '#');
3929 if (sscanf (line, "%d %d %d", &col, &row, &time) != 3) continue;
3930 if ((unsigned) col >= width || (unsigned) row >= height) continue;
3931 if (time > timestamp) continue;
3932 for (tot=n=0, rad=1; rad < 3 && n==0; rad++)
3933 for (r = row-rad; r <= row+rad; r++)
3934 for (c = col-rad; c <= col+rad; c++)
3935 if ((unsigned) r < height && (unsigned) c < width &&
3936 (r != row || c != col) && fcol(r,c) == fcol(row,col)) {
3940 BAYER2(row,col) = tot/n;
3943 fprintf (stderr,_("Fixed dead pixels at:"));
3944 fprintf (stderr, " %d,%d", col, row);
3947 if (fixed) fputc ('\n', stderr);
3951 void CLASS subtract (const char *fname)
3954 int dim[3]={0,0,0}, comment=0, number=0, error=0, nd=0, c, row, col;
3957 if (!(fp = fopen (fname, "rb"))) {
3958 perror (fname); return;
3960 if (fgetc(fp) != 'P' || fgetc(fp) != '5') error = 1;
3961 while (!error && nd < 3 && (c = fgetc(fp)) != EOF) {
3962 if (c == '#') comment = 1;
3963 if (c == '\n') comment = 0;
3964 if (comment) continue;
3965 if (isdigit(c)) number = 1;
3967 if (isdigit(c)) dim[nd] = dim[nd]*10 + c -'0';
3968 else if (isspace(c)) {
3973 if (error || nd < 3) {
3974 fprintf (stderr,_("%s is not a valid PGM file!\n"), fname);
3975 fclose (fp); return;
3976 } else if (dim[0] != width || dim[1] != height || dim[2] != 65535) {
3977 fprintf (stderr,_("%s has the wrong dimensions!\n"), fname);
3978 fclose (fp); return;
3980 pixel = (ushort *) calloc (width, sizeof *pixel);
3981 merror (pixel, "subtract()");
3982 for (row=0; row < height; row++) {
3983 fread (pixel, 2, width, fp);
3984 for (col=0; col < width; col++)
3985 BAYER(row,col) = MAX (BAYER(row,col) - ntohs(pixel[col]), 0);
3989 memset (cblack, 0, sizeof cblack);
3993 void CLASS gamma_curve (double pwr, double ts, int mode, int imax)
3996 double g[6], bnd[2]={0,0}, r;
4000 g[2] = g[3] = g[4] = 0;
4002 if (g[1] && (g[1]-1)*(g[0]-1) <= 0) {
4003 for (i=0; i < 48; i++) {
4004 g[2] = (bnd[0] + bnd[1])/2;
4005 if (g[0]) bnd[(pow(g[2]/g[1],-g[0]) - 1)/g[0] - 1/g[2] > -1] = g[2];
4006 else bnd[g[2]/exp(1-1/g[2]) < g[1]] = g[2];
4009 if (g[0]) g[4] = g[2] * (1/g[0] - 1);
4011 if (g[0]) g[5] = 1 / (g[1]*SQR(g[3])/2 - g[4]*(1 - g[3]) +
4012 (1 - pow(g[3],1+g[0]))*(1 + g[4])/(1 + g[0])) - 1;
4013 else g[5] = 1 / (g[1]*SQR(g[3])/2 + 1
4014 - g[2] - g[3] - g[2]*g[3]*(log(g[3]) - 1)) - 1;
4016 memcpy (gamm, g, sizeof gamm);
4019 for (i=0; i < 0x10000; i++) {
4021 if ((r = (double) i / imax) < 1)
4022 curve[i] = 0x10000 * ( mode
4023 ? (r < g[3] ? r*g[1] : (g[0] ? pow( r,g[0])*(1+g[4])-g[4] : log(r)*g[2]+1))
4024 : (r < g[2] ? r/g[1] : (g[0] ? pow((r+g[4])/(1+g[4]),1/g[0]) : exp((r-1)/g[2]))));
4028 void CLASS pseudoinverse (double (*in)[3], double (*out)[3], int size)
4030 double work[3][6], num;
4033 for (i=0; i < 3; i++) {
4034 for (j=0; j < 6; j++)
4035 work[i][j] = j == i+3;
4036 for (j=0; j < 3; j++)
4037 for (k=0; k < size; k++)
4038 work[i][j] += in[k][i] * in[k][j];
4040 for (i=0; i < 3; i++) {
4042 for (j=0; j < 6; j++)
4044 for (k=0; k < 3; k++) {
4047 for (j=0; j < 6; j++)
4048 work[k][j] -= work[i][j] * num;
4051 for (i=0; i < size; i++)
4052 for (j=0; j < 3; j++)
4053 for (out[i][j]=k=0; k < 3; k++)
4054 out[i][j] += work[j][k+3] * in[i][k];
4057 void CLASS cam_xyz_coeff (float rgb_cam[3][4], double cam_xyz[4][3])
4059 double cam_rgb[4][3], inverse[4][3], num;
4062 for (i=0; i < colors; i++) /* Multiply out XYZ colorspace */
4063 for (j=0; j < 3; j++)
4064 for (cam_rgb[i][j] = k=0; k < 3; k++)
4065 cam_rgb[i][j] += cam_xyz[i][k] * xyz_rgb[k][j];
4067 for (i=0; i < colors; i++) { /* Normalize cam_rgb so that */
4068 for (num=j=0; j < 3; j++) /* cam_rgb * (1,1,1) is (1,1,1,1) */
4069 num += cam_rgb[i][j];
4070 for (j=0; j < 3; j++)
4071 cam_rgb[i][j] /= num;
4072 pre_mul[i] = 1 / num;
4074 pseudoinverse (cam_rgb, inverse, colors);
4075 for (i=0; i < 3; i++)
4076 for (j=0; j < colors; j++)
4077 rgb_cam[i][j] = inverse[j][i];
4081 void CLASS colorcheck()
4084 // Coordinates of the GretagMacbeth ColorChecker squares
4085 // width, height, 1st_column, 1st_row
4086 int cut[NSQ][4]; // you must set these
4087 // ColorChecker Chart under 6500-kelvin illumination
4088 static const double gmb_xyY[NSQ][3] = {
4089 { 0.400, 0.350, 10.1 }, // Dark Skin
4090 { 0.377, 0.345, 35.8 }, // Light Skin
4091 { 0.247, 0.251, 19.3 }, // Blue Sky
4092 { 0.337, 0.422, 13.3 }, // Foliage
4093 { 0.265, 0.240, 24.3 }, // Blue Flower
4094 { 0.261, 0.343, 43.1 }, // Bluish Green
4095 { 0.506, 0.407, 30.1 }, // Orange
4096 { 0.211, 0.175, 12.0 }, // Purplish Blue
4097 { 0.453, 0.306, 19.8 }, // Moderate Red
4098 { 0.285, 0.202, 6.6 }, // Purple
4099 { 0.380, 0.489, 44.3 }, // Yellow Green
4100 { 0.473, 0.438, 43.1 }, // Orange Yellow
4101 { 0.187, 0.129, 6.1 }, // Blue
4102 { 0.305, 0.478, 23.4 }, // Green
4103 { 0.539, 0.313, 12.0 }, // Red
4104 { 0.448, 0.470, 59.1 }, // Yellow
4105 { 0.364, 0.233, 19.8 }, // Magenta
4106 { 0.196, 0.252, 19.8 }, // Cyan
4107 { 0.310, 0.316, 90.0 }, // White
4108 { 0.310, 0.316, 59.1 }, // Neutral 8
4109 { 0.310, 0.316, 36.2 }, // Neutral 6.5
4110 { 0.310, 0.316, 19.8 }, // Neutral 5
4111 { 0.310, 0.316, 9.0 }, // Neutral 3.5
4112 { 0.310, 0.316, 3.1 } }; // Black
4113 double gmb_cam[NSQ][4], gmb_xyz[NSQ][3];
4114 double inverse[NSQ][3], cam_xyz[4][3], balance[4], num;
4115 int c, i, j, k, sq, row, col, pass, count[4];
4117 memset (gmb_cam, 0, sizeof gmb_cam);
4118 for (sq=0; sq < NSQ; sq++) {
4120 for (row=cut[sq][3]; row < cut[sq][3]+cut[sq][1]; row++)
4121 for (col=cut[sq][2]; col < cut[sq][2]+cut[sq][0]; col++) {
4123 if (c >= colors) c -= 2;
4124 gmb_cam[sq][c] += BAYER2(row,col);
4125 BAYER2(row,col) = black + (BAYER2(row,col)-black)/2;
4128 FORCC gmb_cam[sq][c] = gmb_cam[sq][c]/count[c] - black;
4129 gmb_xyz[sq][0] = gmb_xyY[sq][2] * gmb_xyY[sq][0] / gmb_xyY[sq][1];
4130 gmb_xyz[sq][1] = gmb_xyY[sq][2];
4131 gmb_xyz[sq][2] = gmb_xyY[sq][2] *
4132 (1 - gmb_xyY[sq][0] - gmb_xyY[sq][1]) / gmb_xyY[sq][1];
4134 pseudoinverse (gmb_xyz, inverse, NSQ);
4135 for (pass=0; pass < 2; pass++) {
4136 for (raw_color = i=0; i < colors; i++)
4137 for (j=0; j < 3; j++)
4138 for (cam_xyz[i][j] = k=0; k < NSQ; k++)
4139 cam_xyz[i][j] += gmb_cam[k][i] * inverse[k][j];
4140 cam_xyz_coeff (rgb_cam, cam_xyz);
4141 FORCC balance[c] = pre_mul[c] * gmb_cam[20][c];
4142 for (sq=0; sq < NSQ; sq++)
4143 FORCC gmb_cam[sq][c] *= balance[c];
4146 printf (" { \"%s %s\", %d,\n\t{", make, model, black);
4147 num = 10000 / (cam_xyz[1][0] + cam_xyz[1][1] + cam_xyz[1][2]);
4148 FORCC for (j=0; j < 3; j++)
4149 printf ("%c%d", (c | j) ? ',':' ', (int) (cam_xyz[c][j] * num + 0.5));
4156 void CLASS hat_transform (float *temp, float *base, int st, int size, int sc)
4159 for (i=0; i < sc; i++)
4160 temp[i] = 2*base[st*i] + base[st*(sc-i)] + base[st*(i+sc)];
4161 for (; i+sc < size; i++)
4162 temp[i] = 2*base[st*i] + base[st*(i-sc)] + base[st*(i+sc)];
4163 for (; i < size; i++)
4164 temp[i] = 2*base[st*i] + base[st*(i-sc)] + base[st*(2*size-2-(i+sc))];
4167 void CLASS wavelet_denoise()
4169 float *fimg=0, *temp, thold, mul[2], avg, diff;
4170 int scale=1, size, lev, hpass, lpass, row, col, nc, c, i, wlast, blk[2];
4172 static const float noise[] =
4173 { 0.8002,0.2735,0.1202,0.0585,0.0291,0.0152,0.0080,0.0044 };
4175 if (verbose) fprintf (stderr,_("Wavelet denoising...\n"));
4177 while (maximum << scale < 0x10000) scale++;
4178 maximum <<= --scale;
4180 FORC4 cblack[c] <<= scale;
4181 if ((size = iheight*iwidth) < 0x15550000)
4182 fimg = (float *) malloc ((size*3 + iheight + iwidth) * sizeof *fimg);
4183 merror (fimg, "wavelet_denoise()");
4184 temp = fimg + size*3;
4185 if ((nc = colors) == 3 && filters) nc++;
4186 FORC(nc) { /* denoise R,G1,B,G3 individually */
4187 for (i=0; i < size; i++)
4188 fimg[i] = 256 * sqrt(image[i][c] << scale);
4189 for (hpass=lev=0; lev < 5; lev++) {
4190 lpass = size*((lev & 1)+1);
4191 for (row=0; row < iheight; row++) {
4192 hat_transform (temp, fimg+hpass+row*iwidth, 1, iwidth, 1 << lev);
4193 for (col=0; col < iwidth; col++)
4194 fimg[lpass + row*iwidth + col] = temp[col] * 0.25;
4196 for (col=0; col < iwidth; col++) {
4197 hat_transform (temp, fimg+lpass+col, iwidth, iheight, 1 << lev);
4198 for (row=0; row < iheight; row++)
4199 fimg[lpass + row*iwidth + col] = temp[row] * 0.25;
4201 thold = threshold * noise[lev];
4202 for (i=0; i < size; i++) {
4203 fimg[hpass+i] -= fimg[lpass+i];
4204 if (fimg[hpass+i] < -thold) fimg[hpass+i] += thold;
4205 else if (fimg[hpass+i] > thold) fimg[hpass+i] -= thold;
4206 else fimg[hpass+i] = 0;
4207 if (hpass) fimg[i] += fimg[hpass+i];
4211 for (i=0; i < size; i++)
4212 image[i][c] = CLIP(SQR(fimg[i]+fimg[lpass+i])/0x10000);
4214 if (filters && colors == 3) { /* pull G1 and G3 closer together */
4215 for (row=0; row < 2; row++) {
4216 mul[row] = 0.125 * pre_mul[FC(row+1,0) | 1] / pre_mul[FC(row,0) | 1];
4217 blk[row] = cblack[FC(row,0) | 1];
4219 for (i=0; i < 4; i++)
4220 window[i] = (ushort *) fimg + width*i;
4221 for (wlast=-1, row=1; row < height-1; row++) {
4222 while (wlast < row+1) {
4223 for (wlast++, i=0; i < 4; i++)
4224 window[(i+3) & 3] = window[i];
4225 for (col = FC(wlast,1) & 1; col < width; col+=2)
4226 window[2][col] = BAYER(wlast,col);
4228 thold = threshold/512;
4229 for (col = (FC(row,0) & 1)+1; col < width-1; col+=2) {
4230 avg = ( window[0][col-1] + window[0][col+1] +
4231 window[2][col-1] + window[2][col+1] - blk[~row & 1]*4 )
4232 * mul[row & 1] + (window[1][col] + blk[row & 1]) * 0.5;
4233 avg = avg < 0 ? 0 : sqrt(avg);
4234 diff = sqrt(BAYER(row,col)) - avg;
4235 if (diff < -thold) diff += thold;
4236 else if (diff > thold) diff -= thold;
4238 BAYER(row,col) = CLIP(SQR(avg+diff) + 0.5);
4245 void CLASS scale_colors()
4247 unsigned bottom, right, size, row, col, ur, uc, i, x, y, c, sum[8];
4249 double dsum[8], dmin, dmax;
4250 float scale_mul[4], fr, fc;
4251 ushort *img=0, *pix;
4254 memcpy (pre_mul, user_mul, sizeof pre_mul);
4255 if (use_auto_wb || (use_camera_wb && cam_mul[0] == -1)) {
4256 memset (dsum, 0, sizeof dsum);
4257 bottom = MIN (greybox[1]+greybox[3], height);
4258 right = MIN (greybox[0]+greybox[2], width);
4259 for (row=greybox[1]; row < bottom; row += 8)
4260 for (col=greybox[0]; col < right; col += 8) {
4261 memset (sum, 0, sizeof sum);
4262 for (y=row; y < row+8 && y < bottom; y++)
4263 for (x=col; x < col+8 && x < right; x++)
4269 val = image[y*width+x][c];
4270 if (val > maximum-25) goto skip_block;
4271 if ((val -= cblack[c]) < 0) val = 0;
4276 FORC(8) dsum[c] += sum[c];
4279 FORC4 if (dsum[c]) pre_mul[c] = dsum[c+4] / dsum[c];
4281 if (use_camera_wb && cam_mul[0] != -1) {
4282 memset (sum, 0, sizeof sum);
4283 for (row=0; row < 8; row++)
4284 for (col=0; col < 8; col++) {
4286 if ((val = white[row][col] - cblack[c]) > 0)
4290 if (sum[0] && sum[1] && sum[2] && sum[3])
4291 FORC4 pre_mul[c] = (float) sum[c+4] / sum[c];
4292 else if (cam_mul[0] && cam_mul[2])
4293 memcpy (pre_mul, cam_mul, sizeof pre_mul);
4295 fprintf (stderr,_("%s: Cannot use camera white balance.\n"), ifname);
4297 if (pre_mul[1] == 0) pre_mul[1] = 1;
4298 if (pre_mul[3] == 0) pre_mul[3] = colors < 4 ? pre_mul[1] : 1;
4301 if (threshold) wavelet_denoise();
4303 for (dmin=DBL_MAX, dmax=c=0; c < 4; c++) {
4304 if (dmin > pre_mul[c])
4306 if (dmax < pre_mul[c])
4309 if (!highlight) dmax = dmin;
4310 FORC4 scale_mul[c] = (pre_mul[c] /= dmax) * 65535.0 / maximum;
4313 _("Scaling with darkness %d, saturation %d, and\nmultipliers"), dark, sat);
4314 FORC4 fprintf (stderr, " %f", pre_mul[c]);
4315 fputc ('\n', stderr);
4317 if (filters > 1000 && (cblack[4]+1)/2 == 1 && (cblack[5]+1)/2 == 1) {
4318 FORC4 cblack[FC(c/2,c%2)] +=
4319 cblack[6 + c/2 % cblack[4] * cblack[5] + c%2 % cblack[5]];
4320 cblack[4] = cblack[5] = 0;
4322 size = iheight*iwidth;
4323 for (i=0; i < size*4; i++) {
4324 if (!(val = ((ushort *)image)[i])) continue;
4325 if (cblack[4] && cblack[5])
4326 val -= cblack[6 + i/4 / iwidth % cblack[4] * cblack[5] +
4327 i/4 % iwidth % cblack[5]];
4328 val -= cblack[i & 3];
4329 val *= scale_mul[i & 3];
4330 ((ushort *)image)[i] = CLIP(val);
4332 if ((aber[0] != 1 || aber[2] != 1) && colors == 3) {
4334 fprintf (stderr,_("Correcting chromatic aberration...\n"));
4335 for (c=0; c < 4; c+=2) {
4336 if (aber[c] == 1) continue;
4337 img = (ushort *) malloc (size * sizeof *img);
4338 merror (img, "scale_colors()");
4339 for (i=0; i < size; i++)
4340 img[i] = image[i][c];
4341 for (row=0; row < iheight; row++) {
4342 ur = fr = (row - iheight*0.5) * aber[c] + iheight*0.5;
4343 if (ur > iheight-2) continue;
4345 for (col=0; col < iwidth; col++) {
4346 uc = fc = (col - iwidth*0.5) * aber[c] + iwidth*0.5;
4347 if (uc > iwidth-2) continue;
4349 pix = img + ur*iwidth + uc;
4350 image[row*iwidth+col][c] =
4351 (pix[ 0]*(1-fc) + pix[ 1]*fc) * (1-fr) +
4352 (pix[iwidth]*(1-fc) + pix[iwidth+1]*fc) * fr;
4360 void CLASS pre_interpolate()
4370 for (row=0; row < 3; row++)
4371 for (col=1; col < 4; col++)
4372 if (!(image[row*width+col][0] | image[row*width+col][2]))
4373 goto break2; break2:
4374 for ( ; row < height; row+=3)
4375 for (col=(col-1)%3+1; col < width-1; col+=3) {
4376 img = image + row*width+col;
4377 for (c=0; c < 3; c+=2)
4378 img[0][c] = (img[-1][c] + img[1][c]) >> 1;
4382 img = (ushort (*)[4]) calloc (height, width*sizeof *img);
4383 merror (img, "pre_interpolate()");
4384 for (row=0; row < height; row++)
4385 for (col=0; col < width; col++) {
4387 img[row*width+col][c] = image[(row >> 1)*iwidth+(col >> 1)][c];
4394 if (filters > 1000 && colors == 3) {
4395 mix_green = four_color_rgb ^ half_size;
4396 if (four_color_rgb | half_size) colors++;
4398 for (row = FC(1,0) >> 1; row < height; row+=2)
4399 for (col = FC(row,1) & 1; col < width; col+=2)
4400 image[row*width+col][1] = image[row*width+col][3];
4401 filters &= ~((filters & 0x55555555) << 1);
4404 if (half_size) filters = 0;
4407 void CLASS border_interpolate (int border)
4409 unsigned row, col, y, x, f, c, sum[8];
4411 for (row=0; row < height; row++)
4412 for (col=0; col < width; col++) {
4413 if (col==border && row >= border && row < height-border)
4415 memset (sum, 0, sizeof sum);
4416 for (y=row-1; y != row+2; y++)
4417 for (x=col-1; x != col+2; x++)
4418 if (y < height && x < width) {
4420 sum[f] += image[y*width+x][f];
4424 FORCC if (c != f && sum[c+4])
4425 image[row*width+col][c] = sum[c] / sum[c+4];
4429 void CLASS lin_interpolate()
4431 int code[16][16][32], size=16, *ip, sum[4];
4432 int f, c, i, x, y, row, col, shift, color;
4435 if (verbose) fprintf (stderr,_("Bilinear interpolation...\n"));
4436 if (filters == 9) size = 6;
4437 border_interpolate(1);
4438 for (row=0; row < size; row++)
4439 for (col=0; col < size; col++) {
4440 ip = code[row][col]+1;
4442 memset (sum, 0, sizeof sum);
4443 for (y=-1; y <= 1; y++)
4444 for (x=-1; x <= 1; x++) {
4445 shift = (y==0) + (x==0);
4446 color = fcol(row+y,col+x);
4447 if (color == f) continue;
4448 *ip++ = (width*y + x)*4 + color;
4451 sum[color] += 1 << shift;
4453 code[row][col][0] = (ip - code[row][col]) / 3;
4457 *ip++ = 256 / sum[c];
4460 for (row=1; row < height-1; row++)
4461 for (col=1; col < width-1; col++) {
4462 pix = image[row*width+col];
4463 ip = code[row % size][col % size];
4464 memset (sum, 0, sizeof sum);
4465 for (i=*ip++; i--; ip+=3)
4466 sum[ip[2]] += pix[ip[0]] << ip[1];
4467 for (i=colors; --i; ip+=2)
4468 pix[ip[0]] = sum[ip[0]] * ip[1] >> 8;
4473 This algorithm is officially called:
4475 "Interpolation using a Threshold-based variable number of gradients"
4477 described in http://scien.stanford.edu/pages/labsite/1999/psych221/projects/99/tingchen/algodep/vargra.html
4479 I've extended the basic idea to work with non-Bayer filter arrays.
4480 Gradients are numbered clockwise from NW=0 to W=7.
4482 void CLASS vng_interpolate()
4484 static const signed char terms[] = {
4485 -2,-2,+0,-1,0,0x01, -2,-2,+0,+0,1,0x01, -2,-1,-1,+0,0,0x01,
4486 -2,-1,+0,-1,0,0x02, -2,-1,+0,+0,0,0x03, -2,-1,+0,+1,1,0x01,
4487 -2,+0,+0,-1,0,0x06, -2,+0,+0,+0,1,0x02, -2,+0,+0,+1,0,0x03,
4488 -2,+1,-1,+0,0,0x04, -2,+1,+0,-1,1,0x04, -2,+1,+0,+0,0,0x06,
4489 -2,+1,+0,+1,0,0x02, -2,+2,+0,+0,1,0x04, -2,+2,+0,+1,0,0x04,
4490 -1,-2,-1,+0,0,0x80, -1,-2,+0,-1,0,0x01, -1,-2,+1,-1,0,0x01,
4491 -1,-2,+1,+0,1,0x01, -1,-1,-1,+1,0,0x88, -1,-1,+1,-2,0,0x40,
4492 -1,-1,+1,-1,0,0x22, -1,-1,+1,+0,0,0x33, -1,-1,+1,+1,1,0x11,
4493 -1,+0,-1,+2,0,0x08, -1,+0,+0,-1,0,0x44, -1,+0,+0,+1,0,0x11,
4494 -1,+0,+1,-2,1,0x40, -1,+0,+1,-1,0,0x66, -1,+0,+1,+0,1,0x22,
4495 -1,+0,+1,+1,0,0x33, -1,+0,+1,+2,1,0x10, -1,+1,+1,-1,1,0x44,
4496 -1,+1,+1,+0,0,0x66, -1,+1,+1,+1,0,0x22, -1,+1,+1,+2,0,0x10,
4497 -1,+2,+0,+1,0,0x04, -1,+2,+1,+0,1,0x04, -1,+2,+1,+1,0,0x04,
4498 +0,-2,+0,+0,1,0x80, +0,-1,+0,+1,1,0x88, +0,-1,+1,-2,0,0x40,
4499 +0,-1,+1,+0,0,0x11, +0,-1,+2,-2,0,0x40, +0,-1,+2,-1,0,0x20,
4500 +0,-1,+2,+0,0,0x30, +0,-1,+2,+1,1,0x10, +0,+0,+0,+2,1,0x08,
4501 +0,+0,+2,-2,1,0x40, +0,+0,+2,-1,0,0x60, +0,+0,+2,+0,1,0x20,
4502 +0,+0,+2,+1,0,0x30, +0,+0,+2,+2,1,0x10, +0,+1,+1,+0,0,0x44,
4503 +0,+1,+1,+2,0,0x10, +0,+1,+2,-1,1,0x40, +0,+1,+2,+0,0,0x60,
4504 +0,+1,+2,+1,0,0x20, +0,+1,+2,+2,0,0x10, +1,-2,+1,+0,0,0x80,
4505 +1,-1,+1,+1,0,0x88, +1,+0,+1,+2,0,0x08, +1,+0,+2,-1,0,0x40,
4507 }, chood[] = { -1,-1, -1,0, -1,+1, 0,+1, +1,+1, +1,0, +1,-1, 0,-1 };
4508 const signed char *cp;
4509 ushort (*brow[5])[4], *pix;
4510 int prow=8, pcol=2, *ip, *code[16][16], gval[8], gmin, gmax, sum[4];
4511 int row, col, x, y, x1, x2, y1, y2, t, weight, grads, color, diag;
4512 int g, diff, thold, num, c;
4515 if (verbose) fprintf (stderr,_("VNG interpolation...\n"));
4517 if (filters == 1) prow = pcol = 16;
4518 if (filters == 9) prow = pcol = 6;
4519 ip = (int *) calloc (prow*pcol, 1280);
4520 merror (ip, "vng_interpolate()");
4521 for (row=0; row < prow; row++) /* Precalculate for VNG */
4522 for (col=0; col < pcol; col++) {
4523 code[row][col] = ip;
4524 for (cp=terms, t=0; t < 64; t++) {
4525 y1 = *cp++; x1 = *cp++;
4526 y2 = *cp++; x2 = *cp++;
4529 color = fcol(row+y1,col+x1);
4530 if (fcol(row+y2,col+x2) != color) continue;
4531 diag = (fcol(row,col+1) == color && fcol(row+1,col) == color) ? 2:1;
4532 if (abs(y1-y2) == diag && abs(x1-x2) == diag) continue;
4533 *ip++ = (y1*width + x1)*4 + color;
4534 *ip++ = (y2*width + x2)*4 + color;
4536 for (g=0; g < 8; g++)
4537 if (grads & 1<<g) *ip++ = g;
4541 for (cp=chood, g=0; g < 8; g++) {
4542 y = *cp++; x = *cp++;
4543 *ip++ = (y*width + x) * 4;
4544 color = fcol(row,col);
4545 if (fcol(row+y,col+x) != color && fcol(row+y*2,col+x*2) == color)
4546 *ip++ = (y*width + x) * 8 + color;
4551 brow[4] = (ushort (*)[4]) calloc (width*3, sizeof **brow);
4552 merror (brow[4], "vng_interpolate()");
4553 for (row=0; row < 3; row++)
4554 brow[row] = brow[4] + row*width;
4555 for (row=2; row < height-2; row++) { /* Do VNG interpolation */
4556 for (col=2; col < width-2; col++) {
4557 pix = image[row*width+col];
4558 ip = code[row % prow][col % pcol];
4559 memset (gval, 0, sizeof gval);
4560 while ((g = ip[0]) != INT_MAX) { /* Calculate gradients */
4561 diff = ABS(pix[g] - pix[ip[1]]) << ip[2];
4562 gval[ip[3]] += diff;
4564 if ((g = ip[-1]) == -1) continue;
4566 while ((g = *ip++) != -1)
4570 gmin = gmax = gval[0]; /* Choose a threshold */
4571 for (g=1; g < 8; g++) {
4572 if (gmin > gval[g]) gmin = gval[g];
4573 if (gmax < gval[g]) gmax = gval[g];
4576 memcpy (brow[2][col], pix, sizeof *image);
4579 thold = gmin + (gmax >> 1);
4580 memset (sum, 0, sizeof sum);
4581 color = fcol(row,col);
4582 for (num=g=0; g < 8; g++,ip+=2) { /* Average the neighbors */
4583 if (gval[g] <= thold) {
4585 if (c == color && ip[1])
4586 sum[c] += (pix[c] + pix[ip[1]]) >> 1;
4588 sum[c] += pix[ip[0] + c];
4592 FORCC { /* Save to buffer */
4595 t += (sum[c] - sum[color]) / num;
4596 brow[2][col][c] = CLIP(t);
4599 if (row > 3) /* Write buffer to image */
4600 memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image);
4601 for (g=0; g < 4; g++)
4602 brow[(g-1) & 3] = brow[g];
4604 memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image);
4605 memcpy (image[(row-1)*width+2], brow[1]+2, (width-4)*sizeof *image);
4611 Patterned Pixel Grouping Interpolation by Alain Desbiolles
4613 void CLASS ppg_interpolate()
4615 int dir[5] = { 1, width, -1, -width, 1 };
4616 int row, col, diff[2], guess[2], c, d, i;
4618 diff[0] = diff[1] = 0;
4620 border_interpolate(3);
4621 if (verbose) fprintf (stderr,_("PPG interpolation...\n"));
4623 /* Fill in the green layer with gradients and pattern recognition: */
4624 for (row=3; row < height-3; row++)
4625 for (col=3+(FC(row,3) & 1), c=FC(row,col); col < width-3; col+=2) {
4626 pix = image + row*width+col;
4627 for (i=0; (d=dir[i]) > 0; i++) {
4628 guess[i] = (pix[-d][1] + pix[0][c] + pix[d][1]) * 2
4629 - pix[-2*d][c] - pix[2*d][c];
4630 diff[i] = ( ABS(pix[-2*d][c] - pix[ 0][c]) +
4631 ABS(pix[ 2*d][c] - pix[ 0][c]) +
4632 ABS(pix[ -d][1] - pix[ d][1]) ) * 3 +
4633 ( ABS(pix[ 3*d][1] - pix[ d][1]) +
4634 ABS(pix[-3*d][1] - pix[-d][1]) ) * 2;
4636 d = dir[i = diff[0] > diff[1]];
4637 pix[0][1] = ULIM(guess[i] >> 2, pix[d][1], pix[-d][1]);
4639 /* Calculate red and blue for each green pixel: */
4640 for (row=1; row < height-1; row++)
4641 for (col=1+(FC(row,2) & 1), c=FC(row,col+1); col < width-1; col+=2) {
4642 pix = image + row*width+col;
4643 for (i=0; (d=dir[i]) > 0; c=2-c, i++)
4644 pix[0][c] = CLIP((pix[-d][c] + pix[d][c] + 2*pix[0][1]
4645 - pix[-d][1] - pix[d][1]) >> 1);
4647 /* Calculate blue for red pixels and vice versa: */
4648 for (row=1; row < height-1; row++)
4649 for (col=1+(FC(row,1) & 1), c=2-FC(row,col); col < width-1; col+=2) {
4650 pix = image + row*width+col;
4651 for (i=0; (d=dir[i]+dir[i+1]) > 0; i++) {
4652 diff[i] = ABS(pix[-d][c] - pix[d][c]) +
4653 ABS(pix[-d][1] - pix[0][1]) +
4654 ABS(pix[ d][1] - pix[0][1]);
4655 guess[i] = pix[-d][c] + pix[d][c] + 2*pix[0][1]
4656 - pix[-d][1] - pix[d][1];
4658 if (diff[0] != diff[1])
4659 pix[0][c] = CLIP(guess[diff[0] > diff[1]] >> 1);
4661 pix[0][c] = CLIP((guess[0]+guess[1]) >> 2);
4665 void CLASS cielab (ushort rgb[3], short lab[3])
4669 float *cbrt = clb_cbrt, (*xyz_cam)[4] = clb_xyz_cam;
4672 for (i=0; i < 0x10000; i++) {
4674 cbrt[i] = r > 0.008856 ? pow(r,1/3.0) : 7.787*r + 16/116.0;
4676 for (i=0; i < 3; i++)
4677 for (j=0; j < colors; j++)
4678 for (xyz_cam[i][j] = k=0; k < 3; k++)
4679 xyz_cam[i][j] += xyz_rgb[i][k] * rgb_cam[k][j] / d65_white[i];
4682 xyz[0] = xyz[1] = xyz[2] = 0.5;
4684 xyz[0] += xyz_cam[0][c] * rgb[c];
4685 xyz[1] += xyz_cam[1][c] * rgb[c];
4686 xyz[2] += xyz_cam[2][c] * rgb[c];
4688 xyz[0] = cbrt[CLIP((int) xyz[0])];
4689 xyz[1] = cbrt[CLIP((int) xyz[1])];
4690 xyz[2] = cbrt[CLIP((int) xyz[2])];
4691 lab[0] = 64 * (116 * xyz[1] - 16);
4692 lab[1] = 64 * 500 * (xyz[0] - xyz[1]);
4693 lab[2] = 64 * 200 * (xyz[1] - xyz[2]);
4696 #define TS 512 /* Tile Size */
4697 #define fcol(row,col) xtrans[(row+6) % 6][(col+6) % 6]
4700 Frank Markesteijn's algorithm for Fuji X-Trans sensors
4702 void CLASS xtrans_interpolate (int passes)
4704 int c, d, f, g, h, i, v, ng, row, col, top, left, mrow, mcol;
4705 int val, ndir, pass, hm[8], avg[4], color[3][8];
4706 static const short orth[12] = { 1,0,0,1,-1,0,0,-1,1,0,0,1 },
4707 patt[2][16] = { { 0,1,0,-1,2,0,-1,0,1,1,1,-1,0,0,0,0 },
4708 { 0,1,0,-2,1,0,-2,0,1,1,-2,-2,1,-1,-1,1 } },
4709 dir[4] = { 1,TS,TS+1,TS-1 };
4710 short allhex[3][3][2][8], *hex;
4712 ushort min, max, sgrow=0, sgcol=0;
4713 ushort (*rgb)[TS][TS][3], (*rix)[3], (*pix)[4];
4714 short (*lab) [TS][3], (*lix)[3];
4715 float (*drv)[TS][TS], diff[6], tr;
4716 char (*homo)[TS][TS], *buffer;
4719 fprintf (stderr,_("%d-pass X-Trans interpolation...\n"), passes);
4722 ndir = 4 << (passes > 1);
4723 buffer = (char *) malloc (TS*TS*(ndir*11+6));
4724 merror (buffer, "xtrans_interpolate()");
4725 rgb = (ushort(*)[TS][TS][3]) buffer;
4726 lab = (short (*) [TS][3])(buffer + TS*TS*(ndir*6));
4727 drv = (float (*)[TS][TS]) (buffer + TS*TS*(ndir*6+6));
4728 homo = (char (*)[TS][TS]) (buffer + TS*TS*(ndir*10+6));
4730 /* Map a green hexagon around each non-green pixel and vice versa: */
4731 for (row=0; row < 3; row++)
4732 for (col=0; col < 3; col++)
4733 for (ng=d=0; d < 10; d+=2) {
4734 g = fcol(row,col) == 1;
4735 if (fcol(row+orth[d],col+orth[d+2]) == 1) ng=0; else ng++;
4736 if (ng == 4) { sgrow = row; sgcol = col; }
4737 if (ng == g+1) FORC(8) {
4738 v = orth[d ]*patt[g][c*2] + orth[d+1]*patt[g][c*2+1];
4739 h = orth[d+2]*patt[g][c*2] + orth[d+3]*patt[g][c*2+1];
4740 allhex[row][col][0][c^(g*2 & d)] = h + v*width;
4741 allhex[row][col][1][c^(g*2 & d)] = h + v*TS;
4745 /* Set green1 and green3 to the minimum and maximum allowed values: */
4746 for (row=2; row < height-2; row++)
4747 for (min=~(max=0), col=2; col < width-2; col++) {
4748 if (fcol(row,col) == 1 && (min=~(max=0))) continue;
4749 pix = image + row*width + col;
4750 hex = allhex[row % 3][col % 3][0];
4752 val = pix[hex[c]][1];
4753 if (min > val) min = val;
4754 if (max < val) max = val;
4758 switch ((row-sgrow) % 3) {
4759 case 1: if (row < height-3) { row++; col--; } break;
4760 case 2: if ((min=~(max=0)) && (col+=2) < width-3 && row > 2) row--;
4764 for (top=3; top < height-19; top += TS-16)
4765 for (left=3; left < width-19; left += TS-16) {
4766 mrow = MIN (top+TS, height-3);
4767 mcol = MIN (left+TS, width-3);
4768 for (row=top; row < mrow; row++)
4769 for (col=left; col < mcol; col++)
4770 memcpy (rgb[0][row-top][col-left], image[row*width+col], 6);
4771 FORC3 memcpy (rgb[c+1], rgb[0], sizeof *rgb);
4773 /* Interpolate green horizontally, vertically, and along both diagonals: */
4774 for (row=top; row < mrow; row++)
4775 for (col=left; col < mcol; col++) {
4776 if ((f = fcol(row,col)) == 1) continue;
4777 pix = image + row*width + col;
4778 hex = allhex[row % 3][col % 3][0];
4779 color[1][0] = 174 * (pix[ hex[1]][1] + pix[ hex[0]][1]) -
4780 46 * (pix[2*hex[1]][1] + pix[2*hex[0]][1]);
4781 color[1][1] = 223 * pix[ hex[3]][1] + pix[ hex[2]][1] * 33 +
4782 92 * (pix[ 0 ][f] - pix[ -hex[2]][f]);
4783 FORC(2) color[1][2+c] =
4784 164 * pix[hex[4+c]][1] + 92 * pix[-2*hex[4+c]][1] + 33 *
4785 (2*pix[0][f] - pix[3*hex[4+c]][f] - pix[-3*hex[4+c]][f]);
4786 FORC4 rgb[c^!((row-sgrow) % 3)][row-top][col-left][1] =
4787 LIM(color[1][c] >> 8,pix[0][1],pix[0][3]);
4790 for (pass=0; pass < passes; pass++) {
4792 memcpy (rgb+=4, buffer, 4*sizeof *rgb);
4794 /* Recalculate green from interpolated values of closer pixels: */
4796 for (row=top+2; row < mrow-2; row++)
4797 for (col=left+2; col < mcol-2; col++) {
4798 if ((f = fcol(row,col)) == 1) continue;
4799 pix = image + row*width + col;
4800 hex = allhex[row % 3][col % 3][1];
4801 for (d=3; d < 6; d++) {
4802 rix = &rgb[(d-2)^!((row-sgrow) % 3)][row-top][col-left];
4803 val = rix[-2*hex[d]][1] + 2*rix[hex[d]][1]
4804 - rix[-2*hex[d]][f] - 2*rix[hex[d]][f] + 3*rix[0][f];
4805 rix[0][1] = LIM(val/3,pix[0][1],pix[0][3]);
4810 /* Interpolate red and blue values for solitary green pixels: */
4811 for (row=(top-sgrow+4)/3*3+sgrow; row < mrow-2; row+=3)
4812 for (col=(left-sgcol+4)/3*3+sgcol; col < mcol-2; col+=3) {
4813 rix = &rgb[0][row-top][col-left];
4814 h = fcol(row,col+1);
4815 memset (diff, 0, sizeof diff);
4816 for (i=1, d=0; d < 6; d++, i^=TS^1, h^=2) {
4817 for (c=0; c < 2; c++, h^=2) {
4818 g = 2*rix[0][1] - rix[i<<c][1] - rix[-i<<c][1];
4819 color[h][d] = g + rix[i<<c][h] + rix[-i<<c][h];
4821 diff[d] += SQR (rix[i<<c][1] - rix[-i<<c][1]
4822 - rix[i<<c][h] + rix[-i<<c][h]) + SQR(g);
4824 if (d > 1 && (d & 1))
4825 if (diff[d-1] < diff[d])
4826 FORC(2) color[c*2][d] = color[c*2][d-1];
4827 if (d < 2 || (d & 1)) {
4828 FORC(2) rix[0][c*2] = CLIP(color[c*2][d]/2);
4834 /* Interpolate red for blue pixels and vice versa: */
4835 for (row=top+3; row < mrow-3; row++)
4836 for (col=left+3; col < mcol-3; col++) {
4837 if ((f = 2-fcol(row,col)) == 1) continue;
4838 rix = &rgb[0][row-top][col-left];
4839 c = (row-sgrow) % 3 ? TS:1;
4840 h = 3 * (c ^ TS ^ 1);
4841 for (d=0; d < 4; d++, rix += TS*TS) {
4842 i = d > 1 || ((d ^ c) & 1) ||
4843 ((ABS(rix[0][1]-rix[c][1])+ABS(rix[0][1]-rix[-c][1])) <
4844 2*(ABS(rix[0][1]-rix[h][1])+ABS(rix[0][1]-rix[-h][1]))) ? c:h;
4845 rix[0][f] = CLIP((rix[i][f] + rix[-i][f] +
4846 2*rix[0][1] - rix[i][1] - rix[-i][1])/2);
4850 /* Fill in red and blue for 2x2 blocks of green: */
4851 for (row=top+2; row < mrow-2; row++) if ((row-sgrow) % 3)
4852 for (col=left+2; col < mcol-2; col++) if ((col-sgcol) % 3) {
4853 rix = &rgb[0][row-top][col-left];
4854 hex = allhex[row % 3][col % 3][1];
4855 for (d=0; d < ndir; d+=2, rix += TS*TS)
4856 if (hex[d] + hex[d+1]) {
4857 g = 3*rix[0][1] - 2*rix[hex[d]][1] - rix[hex[d+1]][1];
4858 for (c=0; c < 4; c+=2) rix[0][c] =
4859 CLIP((g + 2*rix[hex[d]][c] + rix[hex[d+1]][c])/3);
4861 g = 2*rix[0][1] - rix[hex[d]][1] - rix[hex[d+1]][1];
4862 for (c=0; c < 4; c+=2) rix[0][c] =
4863 CLIP((g + rix[hex[d]][c] + rix[hex[d+1]][c])/2);
4867 rgb = (ushort(*)[TS][TS][3]) buffer;
4871 /* Convert to CIELab and differentiate in all directions: */
4872 for (d=0; d < ndir; d++) {
4873 for (row=2; row < mrow-2; row++)
4874 for (col=2; col < mcol-2; col++)
4875 cielab (rgb[d][row][col], lab[row][col]);
4876 for (f=dir[d & 3],row=3; row < mrow-3; row++)
4877 for (col=3; col < mcol-3; col++) {
4878 lix = &lab[row][col];
4879 g = 2*lix[0][0] - lix[f][0] - lix[-f][0];
4880 drv[d][row][col] = SQR(g)
4881 + SQR((2*lix[0][1] - lix[f][1] - lix[-f][1] + g*500/232))
4882 + SQR((2*lix[0][2] - lix[f][2] - lix[-f][2] - g*500/580));
4886 /* Build homogeneity maps from the derivatives: */
4887 memset(homo, 0, ndir*TS*TS);
4888 for (row=4; row < mrow-4; row++)
4889 for (col=4; col < mcol-4; col++) {
4890 for (tr=FLT_MAX, d=0; d < ndir; d++)
4891 if (tr > drv[d][row][col])
4892 tr = drv[d][row][col];
4894 for (d=0; d < ndir; d++)
4895 for (v=-1; v <= 1; v++)
4896 for (h=-1; h <= 1; h++)
4897 if (drv[d][row+v][col+h] <= tr)
4898 homo[d][row][col]++;
4901 /* Average the most homogenous pixels for the final result: */
4902 if (height-top < TS+4) mrow = height-top+2;
4903 if (width-left < TS+4) mcol = width-left+2;
4904 for (row = MIN(top,8); row < mrow-8; row++)
4905 for (col = MIN(left,8); col < mcol-8; col++) {
4906 for (d=0; d < ndir; d++)
4907 for (hm[d]=0, v=-2; v <= 2; v++)
4908 for (h=-2; h <= 2; h++)
4909 hm[d] += homo[d][row+v][col+h];
4910 for (d=0; d < ndir-4; d++)
4911 if (hm[d] < hm[d+4]) hm[d ] = 0; else
4912 if (hm[d] > hm[d+4]) hm[d+4] = 0;
4913 for (max=hm[0],d=1; d < ndir; d++)
4914 if (max < hm[d]) max = hm[d];
4916 memset (avg, 0, sizeof avg);
4917 for (d=0; d < ndir; d++)
4919 FORC3 avg[c] += rgb[d][row][col][c];
4922 FORC3 image[(row+top)*width+col+left][c] = avg[c]/avg[3];
4926 border_interpolate(8);
4931 Adaptive Homogeneity-Directed interpolation is based on
4932 the work of Keigo Hirakawa, Thomas Parks, and Paul Lee.
4934 void CLASS ahd_interpolate()
4936 int i, j, top, left, row, col, tr, tc, c, d, val, hm[2];
4937 static const int dir[4] = { -1, 1, -TS, TS };
4938 unsigned ldiff[2][4], abdiff[2][4], leps, abeps;
4939 ushort (*rgb)[TS][TS][3], (*rix)[3], (*pix)[4];
4940 short (*lab)[TS][TS][3], (*lix)[3];
4941 char (*homo)[TS][TS], *buffer;
4943 if (verbose) fprintf (stderr,_("AHD interpolation...\n"));
4946 border_interpolate(5);
4947 buffer = (char *) malloc (26*TS*TS);
4948 merror (buffer, "ahd_interpolate()");
4949 rgb = (ushort(*)[TS][TS][3]) buffer;
4950 lab = (short (*)[TS][TS][3])(buffer + 12*TS*TS);
4951 homo = (char (*)[TS][TS]) (buffer + 24*TS*TS);
4953 for (top=2; top < height-5; top += TS-6)
4954 for (left=2; left < width-5; left += TS-6) {
4956 /* Interpolate green horizontally and vertically: */
4957 for (row=top; row < top+TS && row < height-2; row++) {
4958 col = left + (FC(row,left) & 1);
4959 for (c = FC(row,col); col < left+TS && col < width-2; col+=2) {
4960 pix = image + row*width+col;
4961 val = ((pix[-1][1] + pix[0][c] + pix[1][1]) * 2
4962 - pix[-2][c] - pix[2][c]) >> 2;
4963 rgb[0][row-top][col-left][1] = ULIM(val,pix[-1][1],pix[1][1]);
4964 val = ((pix[-width][1] + pix[0][c] + pix[width][1]) * 2
4965 - pix[-2*width][c] - pix[2*width][c]) >> 2;
4966 rgb[1][row-top][col-left][1] = ULIM(val,pix[-width][1],pix[width][1]);
4969 /* Interpolate red and blue, and convert to CIELab: */
4970 for (d=0; d < 2; d++)
4971 for (row=top+1; row < top+TS-1 && row < height-3; row++)
4972 for (col=left+1; col < left+TS-1 && col < width-3; col++) {
4973 pix = image + row*width+col;
4974 rix = &rgb[d][row-top][col-left];
4975 lix = &lab[d][row-top][col-left];
4976 if ((c = 2 - FC(row,col)) == 1) {
4978 val = pix[0][1] + (( pix[-1][2-c] + pix[1][2-c]
4979 - rix[-1][1] - rix[1][1] ) >> 1);
4980 rix[0][2-c] = CLIP(val);
4981 val = pix[0][1] + (( pix[-width][c] + pix[width][c]
4982 - rix[-TS][1] - rix[TS][1] ) >> 1);
4984 val = rix[0][1] + (( pix[-width-1][c] + pix[-width+1][c]
4985 + pix[+width-1][c] + pix[+width+1][c]
4986 - rix[-TS-1][1] - rix[-TS+1][1]
4987 - rix[+TS-1][1] - rix[+TS+1][1] + 1) >> 2);
4988 rix[0][c] = CLIP(val);
4990 rix[0][c] = pix[0][c];
4991 cielab (rix[0],lix[0]);
4993 /* Build homogeneity maps from the CIELab images: */
4994 memset (homo, 0, 2*TS*TS);
4995 for (row=top+2; row < top+TS-2 && row < height-4; row++) {
4997 for (col=left+2; col < left+TS-2 && col < width-4; col++) {
4999 for (d=0; d < 2; d++) {
5000 lix = &lab[d][tr][tc];
5001 for (i=0; i < 4; i++) {
5002 ldiff[d][i] = ABS(lix[0][0]-lix[dir[i]][0]);
5003 abdiff[d][i] = SQR(lix[0][1]-lix[dir[i]][1])
5004 + SQR(lix[0][2]-lix[dir[i]][2]);
5007 leps = MIN(MAX(ldiff[0][0],ldiff[0][1]),
5008 MAX(ldiff[1][2],ldiff[1][3]));
5009 abeps = MIN(MAX(abdiff[0][0],abdiff[0][1]),
5010 MAX(abdiff[1][2],abdiff[1][3]));
5011 for (d=0; d < 2; d++)
5012 for (i=0; i < 4; i++)
5013 if (ldiff[d][i] <= leps && abdiff[d][i] <= abeps)
5017 /* Combine the most homogenous pixels for the final result: */
5018 for (row=top+3; row < top+TS-3 && row < height-5; row++) {
5020 for (col=left+3; col < left+TS-3 && col < width-5; col++) {
5022 for (d=0; d < 2; d++)
5023 for (hm[d]=0, i=tr-1; i <= tr+1; i++)
5024 for (j=tc-1; j <= tc+1; j++)
5025 hm[d] += homo[d][i][j];
5027 FORC3 image[row*width+col][c] = rgb[hm[1] > hm[0]][tr][tc][c];
5029 FORC3 image[row*width+col][c] =
5030 (rgb[0][tr][tc][c] + rgb[1][tr][tc][c]) >> 1;
5038 void CLASS median_filter()
5041 int pass, c, i, j, k, med[9];
5042 static const uchar opt[] = /* Optimal 9-element median search */
5043 { 1,2, 4,5, 7,8, 0,1, 3,4, 6,7, 1,2, 4,5, 7,8,
5044 0,3, 5,8, 4,7, 3,6, 1,4, 2,5, 4,7, 4,2, 6,4, 4,2 };
5046 for (pass=1; pass <= med_passes; pass++) {
5048 fprintf (stderr,_("Median filter pass %d...\n"), pass);
5049 for (c=0; c < 3; c+=2) {
5050 for (pix = image; pix < image+width*height; pix++)
5051 pix[0][3] = pix[0][c];
5052 for (pix = image+width; pix < image+width*(height-1); pix++) {
5053 if ((pix-image+1) % width < 2) continue;
5054 for (k=0, i = -width; i <= width; i += width)
5055 for (j = i-1; j <= i+1; j++)
5056 med[k++] = pix[j][3] - pix[j][1];
5057 for (i=0; i < sizeof opt; i+=2)
5058 if (med[opt[i]] > med[opt[i+1]])
5059 SWAP (med[opt[i]] , med[opt[i+1]]);
5060 pix[0][c] = CLIP(med[4] + pix[0][1]);
5066 void CLASS blend_highlights()
5068 int clip=INT_MAX, row, col, c, i, j;
5069 static const float trans[2][4][4] =
5070 { { { 1,1,1 }, { 1.7320508,-1.7320508,0 }, { -1,-1,2 } },
5071 { { 1,1,1,1 }, { 1,-1,1,-1 }, { 1,1,-1,-1 }, { 1,-1,-1,1 } } };
5072 static const float itrans[2][4][4] =
5073 { { { 1,0.8660254,-0.5 }, { 1,-0.8660254,-0.5 }, { 1,0,1 } },
5074 { { 1,1,1,1 }, { 1,-1,1,-1 }, { 1,1,-1,-1 }, { 1,-1,-1,1 } } };
5075 float cam[2][4], lab[2][4], sum[2], chratio;
5077 if ((unsigned) (colors-3) > 1) return;
5078 if (verbose) fprintf (stderr,_("Blending highlights...\n"));
5079 FORCC if (clip > (i = 65535*pre_mul[c])) clip = i;
5080 for (row=0; row < height; row++)
5081 for (col=0; col < width; col++) {
5082 FORCC if (image[row*width+col][c] > clip) break;
5083 if (c == colors) continue;
5085 cam[0][c] = image[row*width+col][c];
5086 cam[1][c] = MIN(cam[0][c],clip);
5088 for (i=0; i < 2; i++) {
5089 FORCC for (lab[i][c]=j=0; j < colors; j++)
5090 lab[i][c] += trans[colors-3][c][j] * cam[i][j];
5091 for (sum[i]=0,c=1; c < colors; c++)
5092 sum[i] += SQR(lab[i][c]);
5094 chratio = sqrt(sum[1]/sum[0]);
5095 for (c=1; c < colors; c++)
5096 lab[0][c] *= chratio;
5097 FORCC for (cam[0][c]=j=0; j < colors; j++)
5098 cam[0][c] += itrans[colors-3][c][j] * lab[0][j];
5099 FORCC image[row*width+col][c] = cam[0][c] / colors;
5103 #define SCALE (4 >> shrink)
5104 void CLASS recover_highlights()
5106 float *map, sum, wgt, grow;
5107 int hsat[4], count, spread, change, val, i;
5108 unsigned high, wide, mrow, mcol, row, col, kc, c, d, y, x;
5110 static const signed char dir[8][2] =
5111 { {-1,-1}, {-1,0}, {-1,1}, {0,1}, {1,1}, {1,0}, {1,-1}, {0,-1} };
5113 if (verbose) fprintf (stderr,_("Rebuilding highlights...\n"));
5115 grow = pow (2, 4-highlight);
5116 FORCC hsat[c] = 32000 * pre_mul[c];
5117 for (kc=0, c=1; c < colors; c++)
5118 if (pre_mul[kc] < pre_mul[c]) kc = c;
5119 high = height / SCALE;
5120 wide = width / SCALE;
5121 map = (float *) calloc (high, wide*sizeof *map);
5122 merror (map, "recover_highlights()");
5123 FORCC if (c != kc) {
5124 memset (map, 0, high*wide*sizeof *map);
5125 for (mrow=0; mrow < high; mrow++)
5126 for (mcol=0; mcol < wide; mcol++) {
5127 sum = wgt = count = 0;
5128 for (row = mrow*SCALE; row < (mrow+1)*SCALE; row++)
5129 for (col = mcol*SCALE; col < (mcol+1)*SCALE; col++) {
5130 pixel = image[row*width+col];
5131 if (pixel[c] / hsat[c] == 1 && pixel[kc] > 24000) {
5137 if (count == SCALE*SCALE)
5138 map[mrow*wide+mcol] = sum / wgt;
5140 for (spread = 32/grow; spread--; ) {
5141 for (mrow=0; mrow < high; mrow++)
5142 for (mcol=0; mcol < wide; mcol++) {
5143 if (map[mrow*wide+mcol]) continue;
5145 for (d=0; d < 8; d++) {
5146 y = mrow + dir[d][0];
5147 x = mcol + dir[d][1];
5148 if (y < high && x < wide && map[y*wide+x] > 0) {
5149 sum += (1 + (d & 1)) * map[y*wide+x];
5150 count += 1 + (d & 1);
5154 map[mrow*wide+mcol] = - (sum+grow) / (count+grow);
5156 for (change=i=0; i < high*wide; i++)
5163 for (i=0; i < high*wide; i++)
5164 if (map[i] == 0) map[i] = 1;
5165 for (mrow=0; mrow < high; mrow++)
5166 for (mcol=0; mcol < wide; mcol++) {
5167 for (row = mrow*SCALE; row < (mrow+1)*SCALE; row++)
5168 for (col = mcol*SCALE; col < (mcol+1)*SCALE; col++) {
5169 pixel = image[row*width+col];
5170 if (pixel[c] / hsat[c] > 1) {
5171 val = pixel[kc] * map[mrow*wide+mcol];
5172 if (pixel[c] < val) pixel[c] = CLIP(val);
5181 void CLASS tiff_get (unsigned base,
5182 unsigned *tag, unsigned *type, unsigned *len, unsigned *save)
5187 *save = ftell(ifp) + 4;
5188 if (*len * ("11124811248484"[*type < 14 ? *type:0]-'0') > 4)
5189 fseek (ifp, get4()+base, SEEK_SET);
5192 void CLASS parse_thumb_note (int base, unsigned toff, unsigned tlen)
5194 unsigned entries, tag, type, len, save;
5198 tiff_get (base, &tag, &type, &len, &save);
5199 if (tag == toff) thumb_offset = get4()+base;
5200 if (tag == tlen) thumb_length = get4();
5201 fseek (ifp, save, SEEK_SET);
5205 void CLASS parse_makernote (int base, int uptag)
5207 static const uchar xlat[2][256] = {
5208 { 0xc1,0xbf,0x6d,0x0d,0x59,0xc5,0x13,0x9d,0x83,0x61,0x6b,0x4f,0xc7,0x7f,0x3d,0x3d,
5209 0x53,0x59,0xe3,0xc7,0xe9,0x2f,0x95,0xa7,0x95,0x1f,0xdf,0x7f,0x2b,0x29,0xc7,0x0d,
5210 0xdf,0x07,0xef,0x71,0x89,0x3d,0x13,0x3d,0x3b,0x13,0xfb,0x0d,0x89,0xc1,0x65,0x1f,
5211 0xb3,0x0d,0x6b,0x29,0xe3,0xfb,0xef,0xa3,0x6b,0x47,0x7f,0x95,0x35,0xa7,0x47,0x4f,
5212 0xc7,0xf1,0x59,0x95,0x35,0x11,0x29,0x61,0xf1,0x3d,0xb3,0x2b,0x0d,0x43,0x89,0xc1,
5213 0x9d,0x9d,0x89,0x65,0xf1,0xe9,0xdf,0xbf,0x3d,0x7f,0x53,0x97,0xe5,0xe9,0x95,0x17,
5214 0x1d,0x3d,0x8b,0xfb,0xc7,0xe3,0x67,0xa7,0x07,0xf1,0x71,0xa7,0x53,0xb5,0x29,0x89,
5215 0xe5,0x2b,0xa7,0x17,0x29,0xe9,0x4f,0xc5,0x65,0x6d,0x6b,0xef,0x0d,0x89,0x49,0x2f,
5216 0xb3,0x43,0x53,0x65,0x1d,0x49,0xa3,0x13,0x89,0x59,0xef,0x6b,0xef,0x65,0x1d,0x0b,
5217 0x59,0x13,0xe3,0x4f,0x9d,0xb3,0x29,0x43,0x2b,0x07,0x1d,0x95,0x59,0x59,0x47,0xfb,
5218 0xe5,0xe9,0x61,0x47,0x2f,0x35,0x7f,0x17,0x7f,0xef,0x7f,0x95,0x95,0x71,0xd3,0xa3,
5219 0x0b,0x71,0xa3,0xad,0x0b,0x3b,0xb5,0xfb,0xa3,0xbf,0x4f,0x83,0x1d,0xad,0xe9,0x2f,
5220 0x71,0x65,0xa3,0xe5,0x07,0x35,0x3d,0x0d,0xb5,0xe9,0xe5,0x47,0x3b,0x9d,0xef,0x35,
5221 0xa3,0xbf,0xb3,0xdf,0x53,0xd3,0x97,0x53,0x49,0x71,0x07,0x35,0x61,0x71,0x2f,0x43,
5222 0x2f,0x11,0xdf,0x17,0x97,0xfb,0x95,0x3b,0x7f,0x6b,0xd3,0x25,0xbf,0xad,0xc7,0xc5,
5223 0xc5,0xb5,0x8b,0xef,0x2f,0xd3,0x07,0x6b,0x25,0x49,0x95,0x25,0x49,0x6d,0x71,0xc7 },
5224 { 0xa7,0xbc,0xc9,0xad,0x91,0xdf,0x85,0xe5,0xd4,0x78,0xd5,0x17,0x46,0x7c,0x29,0x4c,
5225 0x4d,0x03,0xe9,0x25,0x68,0x11,0x86,0xb3,0xbd,0xf7,0x6f,0x61,0x22,0xa2,0x26,0x34,
5226 0x2a,0xbe,0x1e,0x46,0x14,0x68,0x9d,0x44,0x18,0xc2,0x40,0xf4,0x7e,0x5f,0x1b,0xad,
5227 0x0b,0x94,0xb6,0x67,0xb4,0x0b,0xe1,0xea,0x95,0x9c,0x66,0xdc,0xe7,0x5d,0x6c,0x05,
5228 0xda,0xd5,0xdf,0x7a,0xef,0xf6,0xdb,0x1f,0x82,0x4c,0xc0,0x68,0x47,0xa1,0xbd,0xee,
5229 0x39,0x50,0x56,0x4a,0xdd,0xdf,0xa5,0xf8,0xc6,0xda,0xca,0x90,0xca,0x01,0x42,0x9d,
5230 0x8b,0x0c,0x73,0x43,0x75,0x05,0x94,0xde,0x24,0xb3,0x80,0x34,0xe5,0x2c,0xdc,0x9b,
5231 0x3f,0xca,0x33,0x45,0xd0,0xdb,0x5f,0xf5,0x52,0xc3,0x21,0xda,0xe2,0x22,0x72,0x6b,
5232 0x3e,0xd0,0x5b,0xa8,0x87,0x8c,0x06,0x5d,0x0f,0xdd,0x09,0x19,0x93,0xd0,0xb9,0xfc,
5233 0x8b,0x0f,0x84,0x60,0x33,0x1c,0x9b,0x45,0xf1,0xf0,0xa3,0x94,0x3a,0x12,0x77,0x33,
5234 0x4d,0x44,0x78,0x28,0x3c,0x9e,0xfd,0x65,0x57,0x16,0x94,0x6b,0xfb,0x59,0xd0,0xc8,
5235 0x22,0x36,0xdb,0xd2,0x63,0x98,0x43,0xa1,0x04,0x87,0x86,0xf7,0xa6,0x26,0xbb,0xd6,
5236 0x59,0x4d,0xbf,0x6a,0x2e,0xaa,0x2b,0xef,0xe6,0x78,0xb6,0x4e,0xe0,0x2f,0xdc,0x7c,
5237 0xbe,0x57,0x19,0x32,0x7e,0x2a,0xd0,0xb8,0xba,0x29,0x00,0x3c,0x52,0x7d,0xa8,0x49,
5238 0x3b,0x2d,0xeb,0x25,0x49,0xfa,0xa3,0xaa,0x39,0xa7,0xc5,0xa7,0x50,0x11,0x36,0xfb,
5239 0xc6,0x67,0x4a,0xf5,0xa5,0x12,0x65,0x7e,0xb0,0xdf,0xaf,0x4e,0xb3,0x61,0x7f,0x2f } };
5240 unsigned offset=0, entries, tag, type, len, save, c;
5241 unsigned ver97=0, serial=0, i, wbi=0, wb[4]={0,0,0,0};
5242 uchar buf97[324], ci, cj, ck;
5243 short morder, sorder=order;
5246 The MakerNote might have its own TIFF header (possibly with
5247 its own byte-order!), or it might just be a table.
5249 if (!strcmp(make,"Nokia")) return;
5250 fread (buf, 1, 10, ifp);
5251 if (!strncmp (buf,"KDK" ,3) || /* these aren't TIFF tables */
5252 !strncmp (buf,"VER" ,3) ||
5253 !strncmp (buf,"IIII",4) ||
5254 !strncmp (buf,"MMMM",4)) return;
5255 if (!strncmp (buf,"KC" ,2) || /* Konica KD-400Z, KD-510Z */
5256 !strncmp (buf,"MLY" ,3)) { /* Minolta DiMAGE G series */
5258 while ((i=ftell(ifp)) < data_offset && i < 16384) {
5259 wb[0] = wb[2]; wb[2] = wb[1]; wb[1] = wb[3];
5261 if (wb[1] == 256 && wb[3] == 256 &&
5262 wb[0] > 256 && wb[0] < 640 && wb[2] > 256 && wb[2] < 640)
5263 FORC4 cam_mul[c] = wb[c];
5267 if (!strcmp (buf,"Nikon")) {
5270 if (get2() != 42) goto quit;
5272 fseek (ifp, offset-8, SEEK_CUR);
5273 } else if (!strcmp (buf,"OLYMPUS") ||
5274 !strcmp (buf,"PENTAX ")) {
5275 base = ftell(ifp)-10;
5276 fseek (ifp, -2, SEEK_CUR);
5278 if (buf[0] == 'O') get2();
5279 } else if (!strncmp (buf,"SONY",4) ||
5280 !strcmp (buf,"Panasonic")) {
5282 } else if (!strncmp (buf,"FUJIFILM",8)) {
5283 base = ftell(ifp)-10;
5285 fseek (ifp, 2, SEEK_CUR);
5286 } else if (!strcmp (buf,"OLYMP") ||
5287 !strcmp (buf,"LEICA") ||
5288 !strcmp (buf,"Ricoh") ||
5289 !strcmp (buf,"EPSON"))
5290 fseek (ifp, -2, SEEK_CUR);
5291 else if (!strcmp (buf,"AOC") ||
5292 !strcmp (buf,"QVC"))
5293 fseek (ifp, -4, SEEK_CUR);
5295 fseek (ifp, -10, SEEK_CUR);
5296 if (!strncmp(make,"SAMSUNG",7))
5300 if (entries > 1000) return;
5304 tiff_get (base, &tag, &type, &len, &save);
5306 if (tag == 2 && strstr(make,"NIKON") && !iso_speed)
5307 iso_speed = (get2(),get2());
5308 if (tag == 4 && len > 26 && len < 35) {
5309 if ((i=(get4(),get2())) != 0x7fff && !iso_speed)
5310 iso_speed = 50 * pow (2, i/32.0 - 4);
5311 if ((i=(get2(),get2())) != 0x7fff && !aperture)
5312 aperture = pow (2, i/64.0);
5313 if ((i=get2()) != 0xffff && !shutter)
5314 shutter = pow (2, (short) i/-32.0);
5315 wbi = (get2(),get2());
5316 shot_order = (get2(),get2());
5318 if ((tag == 4 || tag == 0x114) && !strncmp(make,"KONICA",6)) {
5319 fseek (ifp, tag == 4 ? 140:160, SEEK_CUR);
5321 case 72: flip = 0; break;
5322 case 76: flip = 6; break;
5323 case 82: flip = 5; break;
5326 if (tag == 7 && type == 2 && len > 20)
5327 fgets (model2, 64, ifp);
5328 if (tag == 8 && type == 4)
5329 shot_order = get4();
5330 if (tag == 9 && !strcmp(make,"Canon"))
5331 fread (artist, 64, 1, ifp);
5332 if (tag == 0xc && len == 4)
5333 FORC3 cam_mul[(c << 1 | c >> 1) & 3] = getreal(type);
5334 if (tag == 0xd && type == 7 && get2() == 0xaaaa) {
5335 for (c=i=2; (ushort) c != 0xbbbb && i < len; i++)
5336 c = c << 8 | fgetc(ifp);
5337 while ((i+=4) < len-5)
5338 if (get4() == 257 && (i=len) && (c = (get4(),fgetc(ifp))) < 3)
5339 flip = "065"[c]-'0';
5341 if (tag == 0x10 && type == 4)
5343 if (tag == 0x11 && is_raw && !strncmp(make,"NIKON",5)) {
5344 fseek (ifp, get4()+base, SEEK_SET);
5345 parse_tiff_ifd (base);
5347 if (tag == 0x14 && type == 7) {
5349 fseek (ifp, 1248, SEEK_CUR);
5352 fread (buf, 1, 10, ifp);
5353 if (!strncmp(buf,"NRW ",4)) {
5354 fseek (ifp, strcmp(buf+4,"0100") ? 46:1546, SEEK_CUR);
5355 cam_mul[0] = get4() << 2;
5356 cam_mul[1] = get4() + get4();
5357 cam_mul[2] = get4() << 2;
5360 if (tag == 0x15 && type == 2 && is_raw)
5361 fread (model, 64, 1, ifp);
5362 if (strstr(make,"PENTAX")) {
5363 if (tag == 0x1b) tag = 0x1018;
5364 if (tag == 0x1c) tag = 0x1017;
5367 while ((c = fgetc(ifp)) && c != EOF)
5368 serial = serial*10 + (isdigit(c) ? c - '0' : c % 10);
5369 if (tag == 0x29 && type == 1) {
5370 c = wbi < 18 ? "012347800000005896"[wbi]-'0' : 0;
5371 fseek (ifp, 8 + c*32, SEEK_CUR);
5372 FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get4();
5374 if (tag == 0x3d && type == 3 && len == 4)
5375 FORC4 cblack[c ^ c >> 1] = get2() >> (14-tiff_bps);
5376 if (tag == 0x81 && type == 4) {
5377 data_offset = get4();
5378 fseek (ifp, data_offset + 41, SEEK_SET);
5379 raw_height = get2() * 2;
5381 filters = 0x61616161;
5383 if ((tag == 0x81 && type == 7) ||
5384 (tag == 0x100 && type == 7) ||
5385 (tag == 0x280 && type == 1)) {
5386 thumb_offset = ftell(ifp);
5389 if (tag == 0x88 && type == 4 && (thumb_offset = get4()))
5390 thumb_offset += base;
5391 if (tag == 0x89 && type == 4)
5392 thumb_length = get4();
5393 if (tag == 0x8c || tag == 0x96)
5394 meta_offset = ftell(ifp);
5396 for (i=0; i < 4; i++)
5397 ver97 = ver97 * 10 + fgetc(ifp)-'0';
5400 fseek (ifp, 68, SEEK_CUR);
5401 FORC4 cam_mul[(c >> 1) | ((c & 1) << 1)] = get2();
5404 fseek (ifp, 6, SEEK_CUR);
5405 FORC4 cam_mul[c ^ (c >> 1)] = get2();
5408 fseek (ifp, 16, SEEK_CUR);
5409 FORC4 cam_mul[c] = get2();
5412 if (ver97 != 205) fseek (ifp, 280, SEEK_CUR);
5413 fread (buf97, 324, 1, ifp);
5416 if (tag == 0xa1 && type == 7) {
5418 fseek (ifp, 140, SEEK_CUR);
5419 FORC3 cam_mul[c] = get4();
5421 if (tag == 0xa4 && type == 3) {
5422 fseek (ifp, wbi*48, SEEK_CUR);
5423 FORC3 cam_mul[c] = get2();
5425 if (tag == 0xa7 && (unsigned) (ver97-200) < 17) {
5426 ci = xlat[0][serial & 0xff];
5427 cj = xlat[1][fgetc(ifp)^fgetc(ifp)^fgetc(ifp)^fgetc(ifp)];
5429 for (i=0; i < 324; i++)
5430 buf97[i] ^= (cj += ci * ck++);
5431 i = "66666>666;6A;:;55"[ver97-200] - '0';
5432 FORC4 cam_mul[c ^ (c >> 1) ^ (i & 1)] =
5433 sget2 (buf97 + (i & -2) + c*2);
5435 if (tag == 0x200 && len == 3)
5436 shot_order = (get4(),get4());
5437 if (tag == 0x200 && len == 4)
5438 FORC4 cblack[c ^ c >> 1] = get2();
5439 if (tag == 0x201 && len == 4)
5440 FORC4 cam_mul[c ^ (c >> 1)] = get2();
5441 if (tag == 0x220 && type == 7)
5442 meta_offset = ftell(ifp);
5443 if (tag == 0x401 && type == 4 && len == 4)
5444 FORC4 cblack[c ^ c >> 1] = get4();
5445 if (tag == 0xe01) { /* Nikon Capture Note */
5447 fseek (ifp, 22, SEEK_CUR);
5448 for (offset=22; offset+22 < len; offset += 22+i) {
5450 fseek (ifp, 14, SEEK_CUR);
5452 if (tag == 0x76a43207) flip = get2();
5453 else fseek (ifp, i, SEEK_CUR);
5456 if (tag == 0xe80 && len == 256 && type == 7) {
5457 fseek (ifp, 48, SEEK_CUR);
5458 cam_mul[0] = get2() * 508 * 1.078 / 0x10000;
5459 cam_mul[2] = get2() * 382 * 1.173 / 0x10000;
5461 if (tag == 0xf00 && type == 7) {
5463 fseek (ifp, 176, SEEK_CUR);
5464 else if (len == 734 || len == 1502)
5465 fseek (ifp, 148, SEEK_CUR);
5469 if ((tag == 0x1011 && len == 9) || tag == 0x20400200)
5470 for (i=0; i < 3; i++)
5471 FORC3 cmatrix[i][c] = ((short) get2()) / 256.0;
5472 if ((tag == 0x1012 || tag == 0x20400600) && len == 4)
5473 FORC4 cblack[c ^ c >> 1] = get2();
5474 if (tag == 0x1017 || tag == 0x20400100)
5475 cam_mul[0] = get2() / 256.0;
5476 if (tag == 0x1018 || tag == 0x20400100)
5477 cam_mul[2] = get2() / 256.0;
5478 if (tag == 0x2011 && len == 2) {
5481 cam_mul[0] = get2() / 256.0;
5482 cam_mul[2] = get2() / 256.0;
5484 if ((tag | 0x70) == 0x2070 && (type == 4 || type == 13))
5485 fseek (ifp, get4()+base, SEEK_SET);
5486 if (tag == 0x2020 && !strncmp(buf,"OLYMP",5))
5487 parse_thumb_note (base, 257, 258);
5489 parse_makernote (base, 0x2040);
5490 if (tag == 0xb028) {
5491 fseek (ifp, get4()+base, SEEK_SET);
5492 parse_thumb_note (base, 136, 137);
5494 if (tag == 0x4001 && len > 500) {
5495 i = len == 582 ? 50 : len == 653 ? 68 : len == 5120 ? 142 : 126;
5496 fseek (ifp, i, SEEK_CUR);
5497 FORC4 cam_mul[c ^ (c >> 1)] = get2();
5498 for (i+=18; i <= len; i+=10) {
5500 FORC4 sraw_mul[c ^ (c >> 1)] = get2();
5501 if (sraw_mul[1] == 1170) break;
5504 if (tag == 0x4021 && get4() && get4())
5505 FORC4 cam_mul[c] = 1024;
5507 FORC4 cam_mul[c ^ (c >> 1)] = get4();
5509 FORC4 cam_mul[c ^ (c >> 1)] -= get4();
5513 fseek (ifp, save, SEEK_SET);
5520 Since the TIFF DateTime string has no timezone information,
5521 assume that the camera's clock was set to Universal Time.
5523 void CLASS get_timestamp (int reversed)
5531 for (i=19; i--; ) str[i] = fgetc(ifp);
5533 fread (str, 19, 1, ifp);
5534 memset (&t, 0, sizeof t);
5535 if (sscanf (str, "%d:%d:%d %d:%d:%d", &t.tm_year, &t.tm_mon,
5536 &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec) != 6)
5542 timestamp = mktime(&t);
5545 void CLASS parse_exif (int base)
5547 unsigned kodak, entries, tag, type, len, save, c;
5550 kodak = !strncmp(make,"EASTMAN",7) && tiff_nifds < 3;
5553 tiff_get (base, &tag, &type, &len, &save);
5555 case 33434: tiff_ifd[tiff_nifds-1].shutter =
5556 shutter = getreal(type); break;
5557 case 33437: aperture = getreal(type); break;
5558 case 34855: iso_speed = get2(); break;
5560 case 36868: get_timestamp(0); break;
5561 case 37377: if ((expo = -getreal(type)) < 128)
5562 tiff_ifd[tiff_nifds-1].shutter =
5563 shutter = pow (2, expo); break;
5564 case 37378: aperture = pow (2, getreal(type)/2); break;
5565 case 37386: focal_len = getreal(type); break;
5566 case 37500: parse_makernote (base, 0); break;
5567 case 40962: if (kodak) raw_width = get4(); break;
5568 case 40963: if (kodak) raw_height = get4(); break;
5570 if (get4() == 0x20002)
5571 for (exif_cfa=c=0; c < 8; c+=2)
5572 exif_cfa |= fgetc(ifp) * 0x01010101 << c;
5574 fseek (ifp, save, SEEK_SET);
5578 void CLASS parse_gps (int base)
5580 unsigned entries, tag, type, len, save, c;
5584 tiff_get (base, &tag, &type, &len, &save);
5586 case 1: case 3: case 5:
5587 gpsdata[29+tag/2] = getc(ifp); break;
5588 case 2: case 4: case 7:
5589 FORC(6) gpsdata[tag/3*6+c] = get4(); break;
5591 FORC(2) gpsdata[18+c] = get4(); break;
5593 fgets ((char *) (gpsdata+14+tag/3), MIN(len,12), ifp);
5595 fseek (ifp, save, SEEK_SET);
5599 void CLASS romm_coeff (float romm_cam[3][3])
5601 static const float rgb_romm[3][3] = /* ROMM == Kodak ProPhoto */
5602 { { 2.034193, -0.727420, -0.306766 },
5603 { -0.228811, 1.231729, -0.002922 },
5604 { -0.008565, -0.153273, 1.161839 } };
5607 for (i=0; i < 3; i++)
5608 for (j=0; j < 3; j++)
5609 for (cmatrix[i][j] = k=0; k < 3; k++)
5610 cmatrix[i][j] += rgb_romm[i][k] * romm_cam[k][j];
5613 void CLASS parse_mos (int offset)
5616 int skip, from, i, c, neut[4], planes=0, frot=0;
5617 static const char *mod[] =
5618 { "","DCB2","Volare","Cantare","CMost","Valeo 6","Valeo 11","Valeo 22",
5619 "Valeo 11p","Valeo 17","","Aptus 17","Aptus 22","Aptus 75","Aptus 65",
5620 "Aptus 54S","Aptus 65S","Aptus 75S","AFi 5","AFi 6","AFi 7",
5621 "AFi-II 7","Aptus-II 7","","Aptus-II 6","","","Aptus-II 10","Aptus-II 5",
5622 "","","","","Aptus-II 10R","Aptus-II 8","","Aptus-II 12","","AFi-II 12" };
5623 float romm_cam[3][3];
5625 fseek (ifp, offset, SEEK_SET);
5627 if (get4() != 0x504b5453) break;
5629 fread (data, 1, 40, ifp);
5632 if (!strcmp(data,"JPEG_preview_data")) {
5633 thumb_offset = from;
5634 thumb_length = skip;
5636 if (!strcmp(data,"icc_camera_profile")) {
5637 profile_offset = from;
5638 profile_length = skip;
5640 if (!strcmp(data,"ShootObj_back_type")) {
5641 fscanf (ifp, "%d", &i);
5642 if ((unsigned) i < sizeof mod / sizeof (*mod))
5643 strcpy (model, mod[i]);
5645 if (!strcmp(data,"icc_camera_to_tone_matrix")) {
5646 for (i=0; i < 9; i++)
5647 ((float *)romm_cam)[i] = int_to_float(get4());
5648 romm_coeff (romm_cam);
5650 if (!strcmp(data,"CaptProf_color_matrix")) {
5651 for (i=0; i < 9; i++)
5652 fscanf (ifp, "%f", (float *)romm_cam + i);
5653 romm_coeff (romm_cam);
5655 if (!strcmp(data,"CaptProf_number_of_planes"))
5656 fscanf (ifp, "%d", &planes);
5657 if (!strcmp(data,"CaptProf_raw_data_rotation"))
5658 fscanf (ifp, "%d", &flip);
5659 if (!strcmp(data,"CaptProf_mosaic_pattern"))
5661 fscanf (ifp, "%d", &i);
5662 if (i == 1) frot = c ^ (c >> 1);
5664 if (!strcmp(data,"ImgProf_rotation_angle")) {
5665 fscanf (ifp, "%d", &i);
5668 if (!strcmp(data,"NeutObj_neutrals") && !cam_mul[0]) {
5669 FORC4 fscanf (ifp, "%d", neut+c);
5670 FORC3 cam_mul[c] = (float) neut[0] / neut[c+1];
5672 if (!strcmp(data,"Rows_data"))
5673 load_flags = get4();
5675 fseek (ifp, skip+from, SEEK_SET);
5678 filters = (planes == 1) * 0x01010101 *
5679 (uchar) "\x94\x61\x16\x49"[(flip/90 + frot) & 3];
5682 void CLASS linear_table (unsigned len)
5685 if (len > 0x1000) len = 0x1000;
5686 read_shorts (curve, len);
5687 for (i=len; i < 0x1000; i++)
5688 curve[i] = curve[i-1];
5689 maximum = curve[0xfff];
5692 void CLASS parse_kodak_ifd (int base)
5694 unsigned entries, tag, type, len, save;
5695 int i, c, wbi=-2, wbtemp=6500;
5696 float mul[3]={1,1,1}, num;
5697 static const int wbtag[] = { 64037,64040,64039,64041,-1,-1,64042 };
5700 if (entries > 1024) return;
5702 tiff_get (base, &tag, &type, &len, &save);
5703 if (tag == 1020) wbi = getint(type);
5704 if (tag == 1021 && len == 72) { /* WB set in software */
5705 fseek (ifp, 40, SEEK_CUR);
5706 FORC3 cam_mul[c] = 2048.0 / get2();
5709 if (tag == 2118) wbtemp = getint(type);
5710 if (tag == 2120 + wbi && wbi >= 0)
5711 FORC3 cam_mul[c] = 2048.0 / getreal(type);
5712 if (tag == 2130 + wbi)
5713 FORC3 mul[c] = getreal(type);
5714 if (tag == 2140 + wbi && wbi >= 0)
5716 for (num=i=0; i < 4; i++)
5717 num += getreal(type) * pow (wbtemp/100.0, i);
5718 cam_mul[c] = 2048 / (num * mul[c]);
5720 if (tag == 2317) linear_table (len);
5721 if (tag == 6020) iso_speed = getint(type);
5722 if (tag == 64013) wbi = fgetc(ifp);
5723 if ((unsigned) wbi < 7 && tag == wbtag[wbi])
5724 FORC3 cam_mul[c] = get4();
5725 if (tag == 64019) width = getint(type);
5726 if (tag == 64020) height = (getint(type)+1) & -2;
5727 fseek (ifp, save, SEEK_SET);
5731 int CLASS parse_tiff_ifd (int base)
5733 unsigned entries, tag, type, len, plen=16, save;
5734 int ifd, use_cm=0, cfa, i, j, c, ima_len=0;
5735 char software[64], *cbuf, *cp;
5736 uchar cfa_pat[16], cfa_pc[] = { 0,1,2,3 }, tab[256];
5737 double cc[4][4], cm[4][3], cam_xyz[4][3], num;
5738 double ab[]={ 1,1,1,1 }, asn[] = { 0,0,0,0 }, xyz[] = { 1,1,1 };
5739 unsigned sony_curve[] = { 0,0,0,0,0,4095 };
5740 unsigned *buf, sony_offset=0, sony_length=0, sony_key=0;
5744 if (tiff_nifds >= sizeof tiff_ifd / sizeof tiff_ifd[0])
5747 for (j=0; j < 4; j++)
5748 for (i=0; i < 4; i++)
5751 if (entries > 512) return 1;
5753 tiff_get (base, &tag, &type, &len, &save);
5755 case 5: width = get2(); break;
5756 case 6: height = get2(); break;
5757 case 7: width += get2(); break;
5758 case 9: if ((i = get2())) filters = i; break;
5760 if (type == 3 && len == 1)
5761 cam_mul[(tag-17)*2] = get2() / 256.0;
5764 if (type == 3) iso_speed = get2();
5766 case 28: case 29: case 30:
5767 cblack[tag-28] = get2();
5768 cblack[3] = cblack[1];
5770 case 36: case 37: case 38:
5771 cam_mul[tag-36] = get2();
5774 if (len < 50 || cam_mul[0]) break;
5775 fseek (ifp, 12, SEEK_CUR);
5776 FORC3 cam_mul[c] = get2();
5779 if (type != 7 || fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) break;
5780 thumb_offset = ftell(ifp) - 2;
5783 case 61440: /* Fuji HS10 table */
5784 fseek (ifp, get4()+base, SEEK_SET);
5785 parse_tiff_ifd (base);
5787 case 2: case 256: case 61441: /* ImageWidth */
5788 tiff_ifd[ifd].width = getint(type);
5790 case 3: case 257: case 61442: /* ImageHeight */
5791 tiff_ifd[ifd].height = getint(type);
5793 case 258: /* BitsPerSample */
5795 tiff_ifd[ifd].samples = len & 7;
5796 tiff_ifd[ifd].bps = getint(type);
5797 if (tiff_bps < tiff_ifd[ifd].bps)
5798 tiff_bps = tiff_ifd[ifd].bps;
5802 if (tiff_ifd[ifd].bps > 12) break;
5803 load_raw = &CLASS packed_load_raw;
5804 load_flags = get4() ? 24:80;
5806 case 259: /* Compression */
5807 tiff_ifd[ifd].comp = getint(type);
5809 case 262: /* PhotometricInterpretation */
5810 tiff_ifd[ifd].phint = get2();
5812 case 270: /* ImageDescription */
5813 fread (desc, 512, 1, ifp);
5815 case 271: /* Make */
5816 fgets (make, 64, ifp);
5818 case 272: /* Model */
5819 fgets (model, 64, ifp);
5821 case 280: /* Panasonic RW2 offset */
5822 if (type != 4) break;
5823 load_raw = &CLASS panasonic_load_raw;
5824 load_flags = 0x2008;
5825 case 273: /* StripOffset */
5826 case 513: /* JpegIFOffset */
5828 tiff_ifd[ifd].offset = get4()+base;
5829 if (!tiff_ifd[ifd].bps && tiff_ifd[ifd].offset > 0) {
5830 fseek (ifp, tiff_ifd[ifd].offset, SEEK_SET);
5831 if (ljpeg_start (&jh, 1)) {
5832 tiff_ifd[ifd].comp = 6;
5833 tiff_ifd[ifd].width = jh.wide;
5834 tiff_ifd[ifd].height = jh.high;
5835 tiff_ifd[ifd].bps = jh.bits;
5836 tiff_ifd[ifd].samples = jh.clrs;
5837 if (!(jh.sraw || (jh.clrs & 1)))
5838 tiff_ifd[ifd].width *= jh.clrs;
5839 if ((tiff_ifd[ifd].width > 4*tiff_ifd[ifd].height) & ~jh.clrs) {
5840 tiff_ifd[ifd].width /= 2;
5841 tiff_ifd[ifd].height *= 2;
5844 parse_tiff (tiff_ifd[ifd].offset + 12);
5849 case 274: /* Orientation */
5850 tiff_ifd[ifd].flip = "50132467"[get2() & 7]-'0';
5852 case 277: /* SamplesPerPixel */
5853 tiff_ifd[ifd].samples = getint(type) & 7;
5855 case 279: /* StripByteCounts */
5858 tiff_ifd[ifd].bytes = get4();
5861 FORC3 cam_mul[(4-c) % 3] = getint(type);
5863 case 305: case 11: /* Software */
5864 fgets (software, 64, ifp);
5865 if (!strncmp(software,"Adobe",5) ||
5866 !strncmp(software,"dcraw",5) ||
5867 !strncmp(software,"UFRaw",5) ||
5868 !strncmp(software,"Bibble",6) ||
5869 !strncmp(software,"Nikon Scan",10) ||
5870 !strcmp (software,"Digital Photo Professional"))
5873 case 306: /* DateTime */
5876 case 315: /* Artist */
5877 fread (artist, 64, 1, ifp);
5879 case 322: /* TileWidth */
5880 tiff_ifd[ifd].tile_width = getint(type);
5882 case 323: /* TileLength */
5883 tiff_ifd[ifd].tile_length = getint(type);
5885 case 324: /* TileOffsets */
5886 tiff_ifd[ifd].offset = len > 1 ? ftell(ifp) : get4();
5888 tiff_ifd[ifd].tile_width = tiff_ifd[ifd].tile_length = 0;
5890 load_raw = &CLASS sinar_4shot_load_raw;
5894 case 330: /* SubIFDs */
5895 if (!strcmp(model,"DSLR-A100") && tiff_ifd[ifd].width == 3872) {
5896 load_raw = &CLASS sony_arw_load_raw;
5897 data_offset = get4()+base;
5902 fseek (ifp, get4()+base, SEEK_SET);
5903 if (parse_tiff_ifd (base)) break;
5904 fseek (ifp, i+4, SEEK_SET);
5908 strcpy (make, "Sarnoff");
5912 FORC4 sony_curve[c+1] = get2() >> 2 & 0xfff;
5913 for (i=0; i < 5; i++)
5914 for (j = sony_curve[i]+1; j <= sony_curve[i+1]; j++)
5915 curve[j] = curve[j-1] + (1 << i);
5917 case 29184: sony_offset = get4(); break;
5918 case 29185: sony_length = get4(); break;
5919 case 29217: sony_key = get4(); break;
5921 parse_minolta (ftell(ifp));
5925 FORC4 cam_mul[c ^ (c < 2)] = get2();
5928 FORC4 cam_mul[c] = get2();
5929 i = (cam_mul[1] == 1024 && cam_mul[2] == 1024) << 1;
5930 SWAP (cam_mul[i],cam_mul[i+1])
5932 case 33405: /* Model2 */
5933 fgets (model2, 64, ifp);
5935 case 33421: /* CFARepeatPatternDim */
5936 if (get2() == 6 && get2() == 6)
5939 case 33422: /* CFAPattern */
5941 FORC(36) ((char *)xtrans)[c] = fgetc(ifp) & 3;
5944 case 64777: /* Kodak P-series */
5945 if ((plen=len) > 16) plen = 16;
5946 fread (cfa_pat, 1, plen, ifp);
5947 for (colors=cfa=i=0; i < plen && colors < 4; i++) {
5948 colors += !(cfa & (1 << cfa_pat[i]));
5949 cfa |= 1 << cfa_pat[i];
5951 if (cfa == 070) memcpy (cfa_pc,"\003\004\005",3); /* CMY */
5952 if (cfa == 072) memcpy (cfa_pc,"\005\003\004\001",4); /* GMCY */
5956 fseek (ifp, get4()+base, SEEK_SET);
5957 parse_kodak_ifd (base);
5959 case 33434: /* ExposureTime */
5960 tiff_ifd[ifd].shutter = shutter = getreal(type);
5962 case 33437: /* FNumber */
5963 aperture = getreal(type);
5965 case 34306: /* Leaf white balance */
5966 FORC4 cam_mul[c ^ 1] = 4096.0 / get2();
5968 case 34307: /* Leaf CatchLight color matrix */
5969 fread (software, 1, 7, ifp);
5970 if (strncmp(software,"MATRIX",6)) break;
5972 for (raw_color = i=0; i < 3; i++) {
5973 FORC4 fscanf (ifp, "%f", &rgb_cam[i][c^1]);
5974 if (!use_camera_wb) continue;
5976 FORC4 num += rgb_cam[i][c];
5977 FORC4 rgb_cam[i][c] /= num;
5980 case 34310: /* Leaf metadata */
5981 parse_mos (ftell(ifp));
5983 strcpy (make, "Leaf");
5985 case 34665: /* EXIF tag */
5986 fseek (ifp, get4()+base, SEEK_SET);
5989 case 34853: /* GPSInfo tag */
5990 fseek (ifp, get4()+base, SEEK_SET);
5993 case 34675: /* InterColorProfile */
5994 case 50831: /* AsShotICCProfile */
5995 profile_offset = ftell(ifp);
5996 profile_length = len;
5998 case 37122: /* CompressedBitsPerPixel */
5999 kodak_cbpp = get4();
6001 case 37386: /* FocalLength */
6002 focal_len = getreal(type);
6004 case 37393: /* ImageNumber */
6005 shot_order = getint(type);
6007 case 37400: /* old Kodak KDC tag */
6008 for (raw_color = i=0; i < 3; i++) {
6010 FORC3 rgb_cam[i][c] = getreal(type);
6014 strip_offset = get4();
6015 switch (tiff_ifd[ifd].comp) {
6016 case 32770: load_raw = &CLASS samsung_load_raw; break;
6017 case 32772: load_raw = &CLASS samsung2_load_raw; break;
6018 case 32773: load_raw = &CLASS samsung3_load_raw; break;
6021 case 46275: /* Imacon tags */
6022 strcpy (make, "Imacon");
6023 data_offset = ftell(ifp);
6027 if (!ima_len) break;
6028 fseek (ifp, 38, SEEK_CUR);
6030 fseek (ifp, 40, SEEK_CUR);
6032 raw_height = get4();
6033 left_margin = get4() & 7;
6034 width = raw_width - left_margin - (get4() & 7);
6035 top_margin = get4() & 7;
6036 height = raw_height - top_margin - (get4() & 7);
6037 if (raw_width == 7262) {
6042 fseek (ifp, 52, SEEK_CUR);
6043 FORC3 cam_mul[c] = getreal(11);
6044 fseek (ifp, 114, SEEK_CUR);
6045 flip = (get2() >> 7) * 90;
6046 if (width * height * 6 == ima_len) {
6047 if (flip % 180 == 90) SWAP(width,height);
6049 raw_height = height;
6050 left_margin = top_margin = filters = flip = 0;
6052 sprintf (model, "Ixpress %d-Mp", height*width/1000000);
6053 load_raw = &CLASS imacon_full_load_raw;
6055 if (left_margin & 1) filters = 0x61616161;
6056 load_raw = &CLASS unpacked_load_raw;
6060 case 50454: /* Sinar tag */
6062 if (!(cbuf = (char *) malloc(len))) break;
6063 fread (cbuf, 1, len, ifp);
6064 for (cp = cbuf-1; cp && cp < cbuf+len; cp = strchr(cp,'\n'))
6065 if (!strncmp (++cp,"Neutral ",8))
6066 sscanf (cp+8, "%f %f %f", cam_mul, cam_mul+1, cam_mul+2);
6070 if (!make[0]) strcpy (make, "Hasselblad");
6072 case 50459: /* Hasselblad tag */
6077 fseek (ifp, j+(get2(),get4()), SEEK_SET);
6083 case 50706: /* DNGVersion */
6084 FORC4 dng_version = (dng_version << 8) + fgetc(ifp);
6085 if (!make[0]) strcpy (make, "DNG");
6088 case 50708: /* UniqueCameraModel */
6089 if (model[0]) break;
6090 fgets (make, 64, ifp);
6091 if ((cp = strchr(make,' '))) {
6096 case 50710: /* CFAPlaneColor */
6097 if (filters == 9) break;
6098 if (len > 4) len = 4;
6100 fread (cfa_pc, 1, colors, ifp);
6102 FORCC tab[cfa_pc[c]] = c;
6105 filters = filters << 2 | tab[cfa_pat[i % plen]];
6106 filters -= !filters;
6108 case 50711: /* CFALayout */
6109 if (get2() == 2) fuji_width = 1;
6112 case 50712: /* LinearizationTable */
6115 case 50713: /* BlackLevelRepeatDim */
6118 if (cblack[4] * cblack[5] > sizeof cblack / sizeof *cblack - 6)
6119 cblack[4] = cblack[5] = 1;
6122 cblack[4] = cblack[5] = MIN(sqrt(len),64);
6123 case 50714: /* BlackLevel */
6124 if (!(cblack[4] * cblack[5]))
6125 cblack[4] = cblack[5] = 1;
6126 FORC (cblack[4] * cblack[5])
6127 cblack[6+c] = getreal(type);
6130 case 50715: /* BlackLevelDeltaH */
6131 case 50716: /* BlackLevelDeltaV */
6132 for (num=i=0; i < (len & 0xffff); i++)
6133 num += getreal(type);
6134 black += num/len + 0.5;
6136 case 50717: /* WhiteLevel */
6137 maximum = getint(type);
6139 case 50718: /* DefaultScale */
6140 pixel_aspect = getreal(type);
6141 pixel_aspect /= getreal(type);
6143 case 50721: /* ColorMatrix1 */
6144 case 50722: /* ColorMatrix2 */
6145 FORCC for (j=0; j < 3; j++)
6146 cm[c][j] = getreal(type);
6149 case 50723: /* CameraCalibration1 */
6150 case 50724: /* CameraCalibration2 */
6151 for (i=0; i < colors; i++)
6152 FORCC cc[i][c] = getreal(type);
6154 case 50727: /* AnalogBalance */
6155 FORCC ab[c] = getreal(type);
6157 case 50728: /* AsShotNeutral */
6158 FORCC asn[c] = getreal(type);
6160 case 50729: /* AsShotWhiteXY */
6161 xyz[0] = getreal(type);
6162 xyz[1] = getreal(type);
6163 xyz[2] = 1 - xyz[0] - xyz[1];
6164 FORC3 xyz[c] /= d65_white[c];
6166 case 50740: /* DNGPrivateData */
6167 if (dng_version) break;
6168 parse_minolta (j = get4()+base);
6169 fseek (ifp, j, SEEK_SET);
6170 parse_tiff_ifd (base);
6173 read_shorts (cr2_slice, 3);
6175 case 50829: /* ActiveArea */
6176 top_margin = getint(type);
6177 left_margin = getint(type);
6178 height = getint(type) - top_margin;
6179 width = getint(type) - left_margin;
6181 case 50830: /* MaskedAreas */
6182 for (i=0; i < len && i < 32; i++)
6183 ((int *)mask)[i] = getint(type);
6186 case 51009: /* OpcodeList2 */
6187 meta_offset = ftell(ifp);
6189 case 64772: /* Kodak P-series */
6190 if (len < 13) break;
6191 fseek (ifp, 16, SEEK_CUR);
6192 data_offset = get4();
6193 fseek (ifp, 28, SEEK_CUR);
6194 data_offset += get4();
6195 load_raw = &CLASS packed_load_raw;
6198 if (type == 2) fgets (model2, 64, ifp);
6200 fseek (ifp, save, SEEK_SET);
6202 if (sony_length && (buf = (unsigned *) malloc(sony_length))) {
6203 fseek (ifp, sony_offset, SEEK_SET);
6204 fread (buf, sony_length, 1, ifp);
6205 sony_decrypt (buf, sony_length/4, 1, sony_key);
6207 if ((ifp = tmpfile())) {
6208 fwrite (buf, sony_length, 1, ifp);
6209 fseek (ifp, 0, SEEK_SET);
6210 parse_tiff_ifd (-sony_offset);
6216 for (i=0; i < colors; i++)
6217 FORCC cc[i][c] *= ab[i];
6219 FORCC for (i=0; i < 3; i++)
6220 for (cam_xyz[c][i]=j=0; j < colors; j++)
6221 cam_xyz[c][i] += cc[c][j] * cm[j][i] * xyz[i];
6222 cam_xyz_coeff (cmatrix, cam_xyz);
6226 FORCC cam_mul[c] = 1 / asn[c];
6229 FORCC pre_mul[c] /= cc[c][c];
6233 int CLASS parse_tiff (int base)
6237 fseek (ifp, base, SEEK_SET);
6239 if (order != 0x4949 && order != 0x4d4d) return 0;
6241 while ((doff = get4())) {
6242 fseek (ifp, doff+base, SEEK_SET);
6243 if (parse_tiff_ifd (base)) break;
6248 void CLASS apply_tiff()
6250 int max_samp=0, ties=0, os, ns, raw=-1, thm=-1, i;
6255 fseek (ifp, thumb_offset, SEEK_SET);
6256 if (ljpeg_start (&jh, 1)) {
6257 thumb_misc = jh.bits;
6258 thumb_width = jh.wide;
6259 thumb_height = jh.high;
6262 for (i=tiff_nifds; i--; ) {
6263 if (tiff_ifd[i].shutter)
6264 shutter = tiff_ifd[i].shutter;
6265 tiff_ifd[i].shutter = shutter;
6267 for (i=0; i < tiff_nifds; i++) {
6268 if (max_samp < tiff_ifd[i].samples)
6269 max_samp = tiff_ifd[i].samples;
6270 if (max_samp > 3) max_samp = 3;
6271 os = raw_width*raw_height;
6272 ns = tiff_ifd[i].width*tiff_ifd[i].height;
6275 ns *= tiff_ifd[i].bps;
6277 if ((tiff_ifd[i].comp != 6 || tiff_ifd[i].samples != 3) &&
6278 (tiff_ifd[i].width | tiff_ifd[i].height) < 0x10000 &&
6279 ns && ((ns > os && (ties = 1)) ||
6280 (ns == os && shot_select == ties++))) {
6281 raw_width = tiff_ifd[i].width;
6282 raw_height = tiff_ifd[i].height;
6283 tiff_bps = tiff_ifd[i].bps;
6284 tiff_compress = tiff_ifd[i].comp;
6285 data_offset = tiff_ifd[i].offset;
6286 tiff_flip = tiff_ifd[i].flip;
6287 tiff_samples = tiff_ifd[i].samples;
6288 tile_width = tiff_ifd[i].tile_width;
6289 tile_length = tiff_ifd[i].tile_length;
6290 shutter = tiff_ifd[i].shutter;
6294 if (is_raw == 1 && ties) is_raw = ties;
6295 if (!tile_width ) tile_width = INT_MAX;
6296 if (!tile_length) tile_length = INT_MAX;
6297 for (i=tiff_nifds; i--; )
6298 if (tiff_ifd[i].flip) tiff_flip = tiff_ifd[i].flip;
6299 if (raw >= 0 && !load_raw)
6300 switch (tiff_compress) {
6302 if (tiff_ifd[raw].bytes == raw_width*raw_height) {
6304 load_raw = &CLASS sony_arw2_load_raw; break;
6306 if (tiff_ifd[raw].bytes*8 != raw_width*raw_height*tiff_bps) {
6308 load_raw = &CLASS sony_arw_load_raw; break;
6314 case 32773: goto slr;
6316 if (!strncmp(make,"OLYMPUS",7) &&
6317 tiff_ifd[raw].bytes*2 == raw_width*raw_height*3)
6319 if (tiff_ifd[raw].bytes*5 == raw_width*raw_height*8) {
6324 case 8: load_raw = &CLASS eight_bit_load_raw; break;
6325 case 12: if (tiff_ifd[raw].phint == 2)
6327 load_raw = &CLASS packed_load_raw; break;
6328 case 14: load_flags = 0;
6329 case 16: load_raw = &CLASS unpacked_load_raw;
6330 if (!strncmp(make,"OLYMPUS",7) &&
6331 tiff_ifd[raw].bytes*7 > raw_width*raw_height)
6332 load_raw = &CLASS olympus_load_raw;
6335 case 6: case 7: case 99:
6336 load_raw = &CLASS lossless_jpeg_load_raw; break;
6338 load_raw = &CLASS kodak_262_load_raw; break;
6340 if ((raw_width+9)/10*16*raw_height == tiff_ifd[raw].bytes) {
6341 load_raw = &CLASS packed_load_raw;
6343 } else if (raw_width*raw_height*3 == tiff_ifd[raw].bytes*2) {
6344 load_raw = &CLASS packed_load_raw;
6345 if (model[0] == 'N') load_flags = 80;
6346 } else if (raw_width*raw_height*3 == tiff_ifd[raw].bytes) {
6347 load_raw = &CLASS nikon_yuv_load_raw;
6348 gamma_curve (1/2.4, 12.92, 1, 4095);
6349 memset (cblack, 0, sizeof cblack);
6351 } else if (raw_width*raw_height*2 == tiff_ifd[raw].bytes) {
6352 load_raw = &CLASS unpacked_load_raw;
6356 load_raw = &CLASS nikon_load_raw; break;
6358 load_raw = &CLASS pentax_load_raw; break;
6360 switch (tiff_ifd[raw].phint) {
6361 case 2: load_raw = &CLASS kodak_rgb_load_raw; filters = 0; break;
6362 case 6: load_raw = &CLASS kodak_ycbcr_load_raw; filters = 0; break;
6363 case 32803: load_raw = &CLASS kodak_65000_load_raw;
6365 case 32867: case 34892: break;
6366 default: is_raw = 0;
6369 if ( (tiff_samples == 3 && tiff_ifd[raw].bytes && tiff_bps != 14 &&
6370 (tiff_compress & -16) != 32768)
6371 || (tiff_bps == 8 && strncmp(make,"Phase",5) &&
6372 !strcasestr(make,"Kodak") && !strstr(model2,"DEBUG RAW")))
6374 for (i=0; i < tiff_nifds; i++)
6375 if (i != raw && tiff_ifd[i].samples == max_samp &&
6376 tiff_ifd[i].width * tiff_ifd[i].height / (SQR(tiff_ifd[i].bps)+1) >
6377 thumb_width * thumb_height / (SQR(thumb_misc)+1)
6378 && tiff_ifd[i].comp != 34892) {
6379 thumb_width = tiff_ifd[i].width;
6380 thumb_height = tiff_ifd[i].height;
6381 thumb_offset = tiff_ifd[i].offset;
6382 thumb_length = tiff_ifd[i].bytes;
6383 thumb_misc = tiff_ifd[i].bps;
6387 thumb_misc |= tiff_ifd[thm].samples << 5;
6388 switch (tiff_ifd[thm].comp) {
6390 write_thumb = &CLASS layer_thumb;
6393 if (tiff_ifd[thm].bps <= 8)
6394 write_thumb = &CLASS ppm_thumb;
6395 else if (!strcmp(make,"Imacon"))
6396 write_thumb = &CLASS ppm16_thumb;
6398 thumb_load_raw = &CLASS kodak_thumb_load_raw;
6401 thumb_load_raw = tiff_ifd[thm].phint == 6 ?
6402 &CLASS kodak_ycbcr_load_raw : &CLASS kodak_rgb_load_raw;
6407 void CLASS parse_minolta (int base)
6409 int save, tag, len, offset, high=0, wide=0, i, c;
6412 fseek (ifp, base, SEEK_SET);
6413 if (fgetc(ifp) || fgetc(ifp)-'M' || fgetc(ifp)-'R') return;
6414 order = fgetc(ifp) * 0x101;
6415 offset = base + get4() + 8;
6416 while ((save=ftell(ifp)) < offset) {
6417 for (tag=i=0; i < 4; i++)
6418 tag = tag << 8 | fgetc(ifp);
6421 case 0x505244: /* PRD */
6422 fseek (ifp, 8, SEEK_CUR);
6426 case 0x574247: /* WBG */
6428 i = strcmp(model,"DiMAGE A200") ? 0:3;
6429 FORC4 cam_mul[c ^ (c >> 1) ^ i] = get2();
6431 case 0x545457: /* TTW */
6432 parse_tiff (ftell(ifp));
6433 data_offset = offset;
6435 fseek (ifp, save+len+8, SEEK_SET);
6443 Many cameras have a "debug mode" that writes JPEG and raw
6444 at the same time. The raw file has no header, so try to
6445 to open the matching JPEG file and read its metadata.
6447 void CLASS parse_external_jpeg()
6449 const char *file, *ext;
6450 char *jname, *jfile, *jext;
6453 ext = strrchr (ifname, '.');
6454 file = strrchr (ifname, '/');
6455 if (!file) file = strrchr (ifname, '\\');
6456 if (!file) file = ifname-1;
6458 if (!ext || strlen(ext) != 4 || ext-file != 8) return;
6459 jname = (char *) malloc (strlen(ifname) + 1);
6460 merror (jname, "parse_external_jpeg()");
6461 strcpy (jname, ifname);
6462 jfile = file - ifname + jname;
6463 jext = ext - ifname + jname;
6464 if (strcasecmp (ext, ".jpg")) {
6465 strcpy (jext, isupper(ext[1]) ? ".JPG":".jpg");
6466 if (isdigit(*file)) {
6467 memcpy (jfile, file+4, 4);
6468 memcpy (jfile+4, file, 4);
6471 while (isdigit(*--jext)) {
6478 if (strcmp (jname, ifname)) {
6479 if ((ifp = fopen (jname, "rb"))) {
6481 fprintf (stderr,_("Reading metadata from %s ...\n"), jname);
6489 fprintf (stderr,_("Failed to read metadata from %s\n"), jname);
6495 CIFF block 0x1030 contains an 8x8 white sample.
6496 Load this into white[][] for use in scale_colors().
6498 void CLASS ciff_block_1030()
6500 static const ushort key[] = { 0x410, 0x45f3 };
6501 int i, bpp, row, col, vbits=0;
6502 unsigned long bitbuf=0;
6504 if ((get2(),get4()) != 0x80008 || !get4()) return;
6506 if (bpp != 10 && bpp != 12) return;
6507 for (i=row=0; row < 8; row++)
6508 for (col=0; col < 8; col++) {
6510 bitbuf = bitbuf << 16 | (get2() ^ key[i++ & 1]);
6513 white[row][col] = bitbuf >> (vbits -= bpp) & ~(-1 << bpp);
6518 Parse a CIFF file, better known as Canon CRW format.
6520 void CLASS parse_ciff (int offset, int length, int depth)
6522 int tboff, nrecs, c, type, len, save, wbi=-1;
6523 ushort key[] = { 0x410, 0x45f3 };
6525 fseek (ifp, offset+length-4, SEEK_SET);
6526 tboff = get4() + offset;
6527 fseek (ifp, tboff, SEEK_SET);
6529 if ((nrecs | depth) > 127) return;
6533 save = ftell(ifp) + 4;
6534 fseek (ifp, offset+get4(), SEEK_SET);
6535 if ((((type >> 8) + 8) | 8) == 0x38)
6536 parse_ciff (ftell(ifp), len, depth+1); /* Parse a sub-table */
6538 fread (artist, 64, 1, ifp);
6539 if (type == 0x080a) {
6540 fread (make, 64, 1, ifp);
6541 fseek (ifp, strlen(make) - 63, SEEK_CUR);
6542 fread (model, 64, 1, ifp);
6544 if (type == 0x1810) {
6547 pixel_aspect = int_to_float(get4());
6550 if (type == 0x1835) /* Get the decoder table */
6551 tiff_compress = get4();
6552 if (type == 0x2007) {
6553 thumb_offset = ftell(ifp);
6556 if (type == 0x1818) {
6557 shutter = pow (2, -int_to_float((get4(),get4())));
6558 aperture = pow (2, int_to_float(get4())/2);
6560 if (type == 0x102a) {
6561 iso_speed = pow (2, (get4(),get2())/32.0 - 4) * 50;
6562 aperture = pow (2, (get2(),(short)get2())/64.0);
6563 shutter = pow (2,-((short)get2())/32.0);
6564 wbi = (get2(),get2());
6565 if (wbi > 17) wbi = 0;
6566 fseek (ifp, 32, SEEK_CUR);
6567 if (shutter > 1e6) shutter = get2()/10.0;
6569 if (type == 0x102c) {
6570 if (get2() > 512) { /* Pro90, G1 */
6571 fseek (ifp, 118, SEEK_CUR);
6572 FORC4 cam_mul[c ^ 2] = get2();
6573 } else { /* G2, S30, S40 */
6574 fseek (ifp, 98, SEEK_CUR);
6575 FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get2();
6578 if (type == 0x0032) {
6579 if (len == 768) { /* EOS D30 */
6580 fseek (ifp, 72, SEEK_CUR);
6581 FORC4 cam_mul[c ^ (c >> 1)] = 1024.0 / get2();
6582 if (!wbi) cam_mul[0] = -1; /* use my auto white balance */
6583 } else if (!cam_mul[0]) {
6584 if (get2() == key[0]) /* Pro1, G6, S60, S70 */
6585 c = (strstr(model,"Pro1") ?
6586 "012346000000000000":"01345:000000006008")[wbi]-'0'+ 2;
6587 else { /* G3, G5, S45, S50 */
6588 c = "023457000000006000"[wbi]-'0';
6589 key[0] = key[1] = 0;
6591 fseek (ifp, 78 + c*8, SEEK_CUR);
6592 FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get2() ^ key[c & 1];
6593 if (!wbi) cam_mul[0] = -1;
6596 if (type == 0x10a9) { /* D60, 10D, 300D, and clones */
6597 if (len > 66) wbi = "0134567028"[wbi]-'0';
6598 fseek (ifp, 2 + wbi*8, SEEK_CUR);
6599 FORC4 cam_mul[c ^ (c >> 1)] = get2();
6601 if (type == 0x1030 && (0x18040 >> wbi & 1))
6602 ciff_block_1030(); /* all that don't have 0x10a9 */
6603 if (type == 0x1031) {
6604 raw_width = (get2(),get2());
6605 raw_height = get2();
6607 if (type == 0x5029) {
6608 focal_len = len >> 16;
6609 if ((len & 0xffff) == 2) focal_len /= 32;
6611 if (type == 0x5813) flash_used = int_to_float(len);
6612 if (type == 0x5814) canon_ev = int_to_float(len);
6613 if (type == 0x5817) shot_order = len;
6614 if (type == 0x5834) unique_id = len;
6615 if (type == 0x580e) timestamp = len;
6616 if (type == 0x180e) timestamp = get4();
6618 if ((type | 0x4000) == 0x580e)
6619 timestamp = mktime (gmtime (×tamp));
6621 fseek (ifp, save, SEEK_SET);
6625 void CLASS parse_rollei()
6627 char line[128], *val;
6630 fseek (ifp, 0, SEEK_SET);
6631 memset (&t, 0, sizeof t);
6633 fgets (line, 128, ifp);
6634 if ((val = strchr(line,'=')))
6637 val = line + strlen(line);
6638 if (!strcmp(line,"DAT"))
6639 sscanf (val, "%d.%d.%d", &t.tm_mday, &t.tm_mon, &t.tm_year);
6640 if (!strcmp(line,"TIM"))
6641 sscanf (val, "%d:%d:%d", &t.tm_hour, &t.tm_min, &t.tm_sec);
6642 if (!strcmp(line,"HDR"))
6643 thumb_offset = atoi(val);
6644 if (!strcmp(line,"X "))
6645 raw_width = atoi(val);
6646 if (!strcmp(line,"Y "))
6647 raw_height = atoi(val);
6648 if (!strcmp(line,"TX "))
6649 thumb_width = atoi(val);
6650 if (!strcmp(line,"TY "))
6651 thumb_height = atoi(val);
6652 } while (strncmp(line,"EOHD",4));
6653 data_offset = thumb_offset + thumb_width * thumb_height * 2;
6657 timestamp = mktime(&t);
6658 strcpy (make, "Rollei");
6659 strcpy (model,"d530flex");
6660 write_thumb = &CLASS rollei_thumb;
6663 void CLASS parse_sinar_ia()
6669 fseek (ifp, 4, SEEK_SET);
6671 fseek (ifp, get4(), SEEK_SET);
6673 off = get4(); get4();
6674 fread (str, 8, 1, ifp);
6675 if (!strcmp(str,"META")) meta_offset = off;
6676 if (!strcmp(str,"THUMB")) thumb_offset = off;
6677 if (!strcmp(str,"RAW0")) data_offset = off;
6679 fseek (ifp, meta_offset+20, SEEK_SET);
6680 fread (make, 64, 1, ifp);
6682 if ((cp = strchr(make,' '))) {
6683 strcpy (model, cp+1);
6687 raw_height = get2();
6688 load_raw = &CLASS unpacked_load_raw;
6689 thumb_width = (get4(),get2());
6690 thumb_height = get2();
6691 write_thumb = &CLASS ppm_thumb;
6695 void CLASS parse_phase_one (int base)
6698 unsigned entries, tag, /*type,*/ len, data, save, i, c;
6699 float romm_cam[3][3];
6702 memset (&ph1, 0, sizeof ph1);
6703 fseek (ifp, base, SEEK_SET);
6704 order = get4() & 0xffff;
6705 if (get4() >> 8 != 0x526177) return; /* "Raw" */
6706 fseek (ifp, get4()+base, SEEK_SET);
6716 fseek (ifp, base+data, SEEK_SET);
6718 case 0x100: flip = "0653"[data & 3]-'0'; break;
6720 for (i=0; i < 9; i++)
6721 ((float *)romm_cam)[i] = getreal(11);
6722 romm_coeff (romm_cam);
6725 FORC3 cam_mul[c] = getreal(11);
6727 case 0x108: raw_width = data; break;
6728 case 0x109: raw_height = data; break;
6729 case 0x10a: left_margin = data; break;
6730 case 0x10b: top_margin = data; break;
6731 case 0x10c: width = data; break;
6732 case 0x10d: height = data; break;
6733 case 0x10e: ph1.format = data; break;
6734 case 0x10f: data_offset = data+base; break;
6735 case 0x110: meta_offset = data+base;
6736 meta_length = len; break;
6737 case 0x112: ph1.key_off = save - 4; break;
6738 case 0x210: ph1.tag_210 = int_to_float(data); break;
6739 case 0x21a: ph1.tag_21a = data; break;
6740 case 0x21c: strip_offset = data+base; break;
6741 case 0x21d: ph1.black = data; break;
6742 case 0x222: ph1.split_col = data; break;
6743 case 0x223: ph1.black_col = data+base; break;
6744 case 0x224: ph1.split_row = data; break;
6745 case 0x225: ph1.black_row = data+base; break;
6748 fread (model, 1, 63, ifp);
6749 if ((cp = strstr(model," camera"))) *cp = 0;
6751 fseek (ifp, save, SEEK_SET);
6753 load_raw = ph1.format < 3 ?
6754 &CLASS phase_one_load_raw : &CLASS phase_one_load_raw_c;
6756 strcpy (make, "Phase One");
6757 if (model[0]) return;
6758 switch (raw_height) {
6759 case 2060: strcpy (model,"LightPhase"); break;
6760 case 2682: strcpy (model,"H 10"); break;
6761 case 4128: strcpy (model,"H 20"); break;
6762 case 5488: strcpy (model,"H 25"); break;
6766 void CLASS parse_fuji (int offset)
6768 unsigned entries, tag, len, save, c;
6770 fseek (ifp, offset, SEEK_SET);
6772 if (entries > 255) return;
6778 raw_height = get2();
6780 } else if (tag == 0x121) {
6782 if ((width = get2()) == 4284) width += 3;
6783 } else if (tag == 0x130) {
6784 fuji_layout = fgetc(ifp) >> 7;
6785 fuji_width = !(fgetc(ifp) & 8);
6786 } else if (tag == 0x131) {
6788 FORC(36) xtrans_abs[0][35-c] = fgetc(ifp) & 3;
6789 } else if (tag == 0x2ff0) {
6790 FORC4 cam_mul[c ^ 1] = get2();
6791 } else if (tag == 0xc000) {
6794 while ((tag = get4()) > raw_width);
6799 fseek (ifp, save+len, SEEK_SET);
6801 height <<= fuji_layout;
6802 width >>= fuji_layout;
6805 int CLASS parse_jpeg (int offset)
6807 int len, save, hlen, mark;
6809 fseek (ifp, offset, SEEK_SET);
6810 if (fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) return 0;
6812 while (fgetc(ifp) == 0xff && (mark = fgetc(ifp)) != 0xda) {
6816 if (mark == 0xc0 || mark == 0xc3 || mark == 0xc9) {
6818 raw_height = get2();
6823 if (get4() == 0x48454150) /* "HEAP" */
6824 parse_ciff (save+hlen, len-hlen, 0);
6825 if (parse_tiff (save+6)) apply_tiff();
6826 fseek (ifp, save+len, SEEK_SET);
6831 void CLASS parse_riff()
6833 unsigned i, size, end;
6834 char tag[4], date[64], month[64];
6835 static const char mon[12][4] =
6836 { "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" };
6840 fread (tag, 4, 1, ifp);
6842 end = ftell(ifp) + size;
6843 if (!memcmp(tag,"RIFF",4) || !memcmp(tag,"LIST",4)) {
6845 while (ftell(ifp)+7 < end && !feof(ifp))
6847 } else if (!memcmp(tag,"nctg",4)) {
6848 while (ftell(ifp)+7 < end) {
6851 if ((i+1) >> 1 == 10 && size == 20)
6853 else fseek (ifp, size, SEEK_CUR);
6855 } else if (!memcmp(tag,"IDIT",4) && size < 64) {
6856 fread (date, 64, 1, ifp);
6858 memset (&t, 0, sizeof t);
6859 if (sscanf (date, "%*s %s %d %d:%d:%d %d", month, &t.tm_mday,
6860 &t.tm_hour, &t.tm_min, &t.tm_sec, &t.tm_year) == 6) {
6861 for (i=0; i < 12 && strcasecmp(mon[i],month); i++);
6865 timestamp = mktime(&t);
6868 fseek (ifp, size, SEEK_CUR);
6871 void CLASS parse_qt (int end)
6873 unsigned save, size;
6877 while (ftell(ifp)+7 < end) {
6879 if ((size = get4()) < 8) return;
6880 fread (tag, 4, 1, ifp);
6881 if (!memcmp(tag,"moov",4) ||
6882 !memcmp(tag,"udta",4) ||
6883 !memcmp(tag,"CNTH",4))
6884 parse_qt (save+size);
6885 if (!memcmp(tag,"CNDA",4))
6886 parse_jpeg (ftell(ifp));
6887 fseek (ifp, save+size, SEEK_SET);
6891 void CLASS parse_smal (int offset, int fsize)
6895 fseek (ifp, offset+2, SEEK_SET);
6899 fseek (ifp, 5, SEEK_CUR);
6900 if (get4() != fsize) return;
6901 if (ver > 6) data_offset = get4();
6902 raw_height = height = get2();
6903 raw_width = width = get2();
6904 strcpy (make, "SMaL");
6905 sprintf (model, "v%d %dx%d", ver, width, height);
6906 if (ver == 6) load_raw = &CLASS smal_v6_load_raw;
6907 if (ver == 9) load_raw = &CLASS smal_v9_load_raw;
6910 void CLASS parse_cine()
6912 unsigned off_head, off_setup, off_image, i;
6915 fseek (ifp, 4, SEEK_SET);
6916 is_raw = get2() == 2;
6917 fseek (ifp, 14, SEEK_CUR);
6923 if ((i = get4())) timestamp = i;
6924 fseek (ifp, off_head+4, SEEK_SET);
6926 raw_height = get4();
6927 switch (get2(),get2()) {
6928 case 8: load_raw = &CLASS eight_bit_load_raw; break;
6929 case 16: load_raw = &CLASS unpacked_load_raw;
6931 fseek (ifp, off_setup+792, SEEK_SET);
6932 strcpy (make, "CINE");
6933 sprintf (model, "%d", get4());
6934 fseek (ifp, 12, SEEK_CUR);
6935 switch ((i=get4()) & 0xffffff) {
6936 case 3: filters = 0x94949494; break;
6937 case 4: filters = 0x49494949; break;
6938 default: is_raw = 0;
6940 fseek (ifp, 72, SEEK_CUR);
6941 switch ((get4()+3600) % 360) {
6942 case 270: flip = 4; break;
6943 case 180: flip = 1; break;
6944 case 90: flip = 7; break;
6947 cam_mul[0] = getreal(11);
6948 cam_mul[2] = getreal(11);
6949 maximum = ~(-1 << get4());
6950 fseek (ifp, 668, SEEK_CUR);
6951 shutter = get4()/1000000000.0;
6952 fseek (ifp, off_image, SEEK_SET);
6953 if (shot_select < is_raw)
6954 fseek (ifp, shot_select*8, SEEK_CUR);
6955 data_offset = (INT64) get4() + 8;
6956 data_offset += (INT64) get4() << 32;
6959 void CLASS parse_redcine()
6961 unsigned i, len, rdvo;
6965 fseek (ifp, 52, SEEK_SET);
6968 fseek (ifp, 0, SEEK_END);
6969 fseek (ifp, -(i = ftello(ifp) & 511), SEEK_CUR);
6970 if (get4() != i || get4() != 0x52454f42) {
6971 fprintf (stderr,_("%s: Tail is missing, parsing from head...\n"), ifname);
6972 fseek (ifp, 0, SEEK_SET);
6973 while ((len = get4()) != EOF) {
6974 if (get4() == 0x52454456)
6975 if (is_raw++ == shot_select)
6976 data_offset = ftello(ifp) - 8;
6977 fseek (ifp, len-8, SEEK_CUR);
6981 fseek (ifp, 12, SEEK_CUR);
6983 fseeko (ifp, rdvo+8 + shot_select*4, SEEK_SET);
6984 data_offset = get4();
6988 char * CLASS foveon_gets (int offset, char *str, int len)
6991 fseek (ifp, offset, SEEK_SET);
6992 for (i=0; i < len-1; i++)
6993 if ((str[i] = get2()) == 0) break;
6998 void CLASS parse_foveon()
7000 int entries, img=0, off, len, tag, save, i, wide, high, pent, poff[256][2];
7001 char name[64], value[64];
7003 order = 0x4949; /* Little-endian */
7004 fseek (ifp, 36, SEEK_SET);
7006 fseek (ifp, -4, SEEK_END);
7007 fseek (ifp, get4(), SEEK_SET);
7008 if (get4() != 0x64434553) return; /* SECd */
7009 entries = (get4(),get4());
7015 fseek (ifp, off, SEEK_SET);
7016 if (get4() != (0x20434553 | (tag << 24))) return;
7018 case 0x47414d49: /* IMAG */
7019 case 0x32414d49: /* IMA2 */
7020 fseek (ifp, 8, SEEK_CUR);
7024 if (wide > raw_width && high > raw_height) {
7026 case 5: load_flags = 1;
7027 case 6: load_raw = &CLASS foveon_sd_load_raw; break;
7028 case 30: load_raw = &CLASS foveon_dp_load_raw; break;
7029 default: load_raw = 0;
7033 data_offset = off+28;
7036 fseek (ifp, off+28, SEEK_SET);
7037 if (fgetc(ifp) == 0xff && fgetc(ifp) == 0xd8
7038 && thumb_length < len-28) {
7039 thumb_offset = off+28;
7040 thumb_length = len-28;
7041 write_thumb = &CLASS jpeg_thumb;
7043 if (++img == 2 && !thumb_length) {
7044 thumb_offset = off+24;
7046 thumb_height = high;
7047 write_thumb = &CLASS foveon_thumb;
7050 case 0x464d4143: /* CAMF */
7051 meta_offset = off+8;
7052 meta_length = len-28;
7054 case 0x504f5250: /* PROP */
7055 pent = (get4(),get4());
7056 fseek (ifp, 12, SEEK_CUR);
7058 if ((unsigned) pent > 256) pent=256;
7059 for (i=0; i < pent*2; i++)
7060 ((int *)poff)[i] = off + get4()*2;
7061 for (i=0; i < pent; i++) {
7062 foveon_gets (poff[i][0], name, 64);
7063 foveon_gets (poff[i][1], value, 64);
7064 if (!strcmp (name, "ISO"))
7065 iso_speed = atoi(value);
7066 if (!strcmp (name, "CAMMANUF"))
7067 strcpy (make, value);
7068 if (!strcmp (name, "CAMMODEL"))
7069 strcpy (model, value);
7070 if (!strcmp (name, "WB_DESC"))
7071 strcpy (model2, value);
7072 if (!strcmp (name, "TIME"))
7073 timestamp = atoi(value);
7074 if (!strcmp (name, "EXPTIME"))
7075 shutter = atoi(value) / 1000000.0;
7076 if (!strcmp (name, "APERTURE"))
7077 aperture = atof(value);
7078 if (!strcmp (name, "FLENGTH"))
7079 focal_len = atof(value);
7082 timestamp = mktime (gmtime (×tamp));
7085 fseek (ifp, save, SEEK_SET);
7090 All matrices are from Adobe DNG Converter unless otherwise noted.
7092 void CLASS adobe_coeff (const char *make, const char *model)
7094 static const struct {
7096 short black, maximum, trans[12];
7098 { "AgfaPhoto DC-833m", 0, 0, /* DJC */
7099 { 11438,-3762,-1115,-2409,9914,2497,-1227,2295,5300 } },
7100 { "Apple QuickTake", 0, 0, /* DJC */
7101 { 21392,-5653,-3353,2406,8010,-415,7166,1427,2078 } },
7102 { "Canon EOS D2000", 0, 0,
7103 { 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } },
7104 { "Canon EOS D6000", 0, 0,
7105 { 20482,-7172,-3125,-1033,10410,-285,2542,226,3136 } },
7106 { "Canon EOS D30", 0, 0,
7107 { 9805,-2689,-1312,-5803,13064,3068,-2438,3075,8775 } },
7108 { "Canon EOS D60", 0, 0xfa0,
7109 { 6188,-1341,-890,-7168,14489,2937,-2640,3228,8483 } },
7110 { "Canon EOS 5DS", 0, 0x3c96,
7111 { 6250,-711,-808,-5153,12794,2636,-1249,2198,5610 } },
7112 { "Canon EOS 5D Mark III", 0, 0x3c80,
7113 { 6722,-635,-963,-4287,12460,2028,-908,2162,5668 } },
7114 { "Canon EOS 5D Mark II", 0, 0x3cf0,
7115 { 4716,603,-830,-7798,15474,2480,-1496,1937,6651 } },
7116 { "Canon EOS 5D", 0, 0xe6c,
7117 { 6347,-479,-972,-8297,15954,2480,-1968,2131,7649 } },
7118 { "Canon EOS 6D", 0, 0x3c82,
7119 { 7034,-804,-1014,-4420,12564,2058,-851,1994,5758 } },
7120 { "Canon EOS 7D Mark II", 0, 0x3510,
7121 { 7268,-1082,-969,-4186,11839,2663,-825,2029,5839 } },
7122 { "Canon EOS 7D", 0, 0x3510,
7123 { 6844,-996,-856,-3876,11761,2396,-593,1772,6198 } },
7124 { "Canon EOS 10D", 0, 0xfa0,
7125 { 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } },
7126 { "Canon EOS 20Da", 0, 0,
7127 { 14155,-5065,-1382,-6550,14633,2039,-1623,1824,6561 } },
7128 { "Canon EOS 20D", 0, 0xfff,
7129 { 6599,-537,-891,-8071,15783,2424,-1983,2234,7462 } },
7130 { "Canon EOS 30D", 0, 0,
7131 { 6257,-303,-1000,-7880,15621,2396,-1714,1904,7046 } },
7132 { "Canon EOS 40D", 0, 0x3f60,
7133 { 6071,-747,-856,-7653,15365,2441,-2025,2553,7315 } },
7134 { "Canon EOS 50D", 0, 0x3d93,
7135 { 4920,616,-593,-6493,13964,2784,-1774,3178,7005 } },
7136 { "Canon EOS 60D", 0, 0x2ff7,
7137 { 6719,-994,-925,-4408,12426,2211,-887,2129,6051 } },
7138 { "Canon EOS 70D", 0, 0x3bc7,
7139 { 7034,-804,-1014,-4420,12564,2058,-851,1994,5758 } },
7140 { "Canon EOS 80D", 0, 0,
7141 { 7457,-671,-937,-4849,12495,2643,-1213,2354,5492 } },
7142 { "Canon EOS 100D", 0, 0x350f,
7143 { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } },
7144 { "Canon EOS 300D", 0, 0xfa0,
7145 { 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } },
7146 { "Canon EOS 350D", 0, 0xfff,
7147 { 6018,-617,-965,-8645,15881,2975,-1530,1719,7642 } },
7148 { "Canon EOS 400D", 0, 0xe8e,
7149 { 7054,-1501,-990,-8156,15544,2812,-1278,1414,7796 } },
7150 { "Canon EOS 450D", 0, 0x390d,
7151 { 5784,-262,-821,-7539,15064,2672,-1982,2681,7427 } },
7152 { "Canon EOS 500D", 0, 0x3479,
7153 { 4763,712,-646,-6821,14399,2640,-1921,3276,6561 } },
7154 { "Canon EOS 550D", 0, 0x3dd7,
7155 { 6941,-1164,-857,-3825,11597,2534,-416,1540,6039 } },
7156 { "Canon EOS 600D", 0, 0x3510,
7157 { 6461,-907,-882,-4300,12184,2378,-819,1944,5931 } },
7158 { "Canon EOS 650D", 0, 0x354d,
7159 { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } },
7160 { "Canon EOS 700D", 0, 0x3c00,
7161 { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } },
7162 { "Canon EOS 750D", 0, 0x368e,
7163 { 6362,-823,-847,-4426,12109,2616,-743,1857,5635 } },
7164 { "Canon EOS 760D", 0, 0x350f,
7165 { 6362,-823,-847,-4426,12109,2616,-743,1857,5635 } },
7166 { "Canon EOS 1000D", 0, 0xe43,
7167 { 6771,-1139,-977,-7818,15123,2928,-1244,1437,7533 } },
7168 { "Canon EOS 1100D", 0, 0x3510,
7169 { 6444,-904,-893,-4563,12308,2535,-903,2016,6728 } },
7170 { "Canon EOS 1200D", 0, 0x37c2,
7171 { 6461,-907,-882,-4300,12184,2378,-819,1944,5931 } },
7172 { "Canon EOS 1300D", 0, 0x3510,
7173 { 6939,-1016,-866,-4428,12473,2177,-1175,2178,6162 } },
7174 { "Canon EOS M3", 0, 0,
7175 { 6362,-823,-847,-4426,12109,2616,-743,1857,5635 } },
7176 { "Canon EOS M10", 0, 0,
7177 { 6400,-480,-888,-5294,13416,2047,-1296,2203,6137 } },
7178 { "Canon EOS M", 0, 0,
7179 { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } },
7180 { "Canon EOS-1Ds Mark III", 0, 0x3bb0,
7181 { 5859,-211,-930,-8255,16017,2353,-1732,1887,7448 } },
7182 { "Canon EOS-1Ds Mark II", 0, 0xe80,
7183 { 6517,-602,-867,-8180,15926,2378,-1618,1771,7633 } },
7184 { "Canon EOS-1D Mark IV", 0, 0x3bb0,
7185 { 6014,-220,-795,-4109,12014,2361,-561,1824,5787 } },
7186 { "Canon EOS-1D Mark III", 0, 0x3bb0,
7187 { 6291,-540,-976,-8350,16145,2311,-1714,1858,7326 } },
7188 { "Canon EOS-1D Mark II N", 0, 0xe80,
7189 { 6240,-466,-822,-8180,15825,2500,-1801,1938,8042 } },
7190 { "Canon EOS-1D Mark II", 0, 0xe80,
7191 { 6264,-582,-724,-8312,15948,2504,-1744,1919,8664 } },
7192 { "Canon EOS-1DS", 0, 0xe20,
7193 { 4374,3631,-1743,-7520,15212,2472,-2892,3632,8161 } },
7194 { "Canon EOS-1D C", 0, 0x3c4e,
7195 { 6847,-614,-1014,-4669,12737,2139,-1197,2488,6846 } },
7196 { "Canon EOS-1D X Mark II", 0, 0,
7197 { 7596,-978,-967,-4808,12571,2503,-1398,2567,5752 } },
7198 { "Canon EOS-1D X", 0, 0x3c4e,
7199 { 6847,-614,-1014,-4669,12737,2139,-1197,2488,6846 } },
7200 { "Canon EOS-1D", 0, 0xe20,
7201 { 6806,-179,-1020,-8097,16415,1687,-3267,4236,7690 } },
7202 { "Canon EOS C500", 853, 0, /* DJC */
7203 { 17851,-10604,922,-7425,16662,763,-3660,3636,22278 } },
7204 { "Canon PowerShot A530", 0, 0,
7205 { 0 } }, /* don't want the A5 matrix */
7206 { "Canon PowerShot A50", 0, 0,
7207 { -5300,9846,1776,3436,684,3939,-5540,9879,6200,-1404,11175,217 } },
7208 { "Canon PowerShot A5", 0, 0,
7209 { -4801,9475,1952,2926,1611,4094,-5259,10164,5947,-1554,10883,547 } },
7210 { "Canon PowerShot G10", 0, 0,
7211 { 11093,-3906,-1028,-5047,12492,2879,-1003,1750,5561 } },
7212 { "Canon PowerShot G11", 0, 0,
7213 { 12177,-4817,-1069,-1612,9864,2049,-98,850,4471 } },
7214 { "Canon PowerShot G12", 0, 0,
7215 { 13244,-5501,-1248,-1508,9858,1935,-270,1083,4366 } },
7216 { "Canon PowerShot G15", 0, 0,
7217 { 7474,-2301,-567,-4056,11456,2975,-222,716,4181 } },
7218 { "Canon PowerShot G16", 0, 0,
7219 { 8020,-2687,-682,-3704,11879,2052,-965,1921,5556 } },
7220 { "Canon PowerShot G1 X", 0, 0,
7221 { 7378,-1255,-1043,-4088,12251,2048,-876,1946,5805 } },
7222 { "Canon PowerShot G1", 0, 0,
7223 { -4778,9467,2172,4743,-1141,4344,-5146,9908,6077,-1566,11051,557 } },
7224 { "Canon PowerShot G2", 0, 0,
7225 { 9087,-2693,-1049,-6715,14382,2537,-2291,2819,7790 } },
7226 { "Canon PowerShot G3 X", 0, 0,
7227 { 9701,-3857,-921,-3149,11537,1817,-786,1817,5147 } },
7228 { "Canon PowerShot G3", 0, 0,
7229 { 9212,-2781,-1073,-6573,14189,2605,-2300,2844,7664 } },
7230 { "Canon PowerShot G5 X", 0, 0,
7231 { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } },
7232 { "Canon PowerShot G5", 0, 0,
7233 { 9757,-2872,-933,-5972,13861,2301,-1622,2328,7212 } },
7234 { "Canon PowerShot G6", 0, 0,
7235 { 9877,-3775,-871,-7613,14807,3072,-1448,1305,7485 } },
7236 { "Canon PowerShot G7 X", 0, 0,
7237 { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } },
7238 { "Canon PowerShot G9 X", 0, 0,
7239 { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } },
7240 { "Canon PowerShot G9", 0, 0,
7241 { 7368,-2141,-598,-5621,13254,2625,-1418,1696,5743 } },
7242 { "Canon PowerShot Pro1", 0, 0,
7243 { 10062,-3522,-999,-7643,15117,2730,-765,817,7323 } },
7244 { "Canon PowerShot Pro70", 34, 0,
7245 { -4155,9818,1529,3939,-25,4522,-5521,9870,6610,-2238,10873,1342 } },
7246 { "Canon PowerShot Pro90", 0, 0,
7247 { -4963,9896,2235,4642,-987,4294,-5162,10011,5859,-1770,11230,577 } },
7248 { "Canon PowerShot S30", 0, 0,
7249 { 10566,-3652,-1129,-6552,14662,2006,-2197,2581,7670 } },
7250 { "Canon PowerShot S40", 0, 0,
7251 { 8510,-2487,-940,-6869,14231,2900,-2318,2829,9013 } },
7252 { "Canon PowerShot S45", 0, 0,
7253 { 8163,-2333,-955,-6682,14174,2751,-2077,2597,8041 } },
7254 { "Canon PowerShot S50", 0, 0,
7255 { 8882,-2571,-863,-6348,14234,2288,-1516,2172,6569 } },
7256 { "Canon PowerShot S60", 0, 0,
7257 { 8795,-2482,-797,-7804,15403,2573,-1422,1996,7082 } },
7258 { "Canon PowerShot S70", 0, 0,
7259 { 9976,-3810,-832,-7115,14463,2906,-901,989,7889 } },
7260 { "Canon PowerShot S90", 0, 0,
7261 { 12374,-5016,-1049,-1677,9902,2078,-83,852,4683 } },
7262 { "Canon PowerShot S95", 0, 0,
7263 { 13440,-5896,-1279,-1236,9598,1931,-180,1001,4651 } },
7264 { "Canon PowerShot S100", 0, 0,
7265 { 7968,-2565,-636,-2873,10697,2513,180,667,4211 } },
7266 { "Canon PowerShot S110", 0, 0,
7267 { 8039,-2643,-654,-3783,11230,2930,-206,690,4194 } },
7268 { "Canon PowerShot S120", 0, 0,
7269 { 6961,-1685,-695,-4625,12945,1836,-1114,2152,5518 } },
7270 { "Canon PowerShot SX1 IS", 0, 0,
7271 { 6578,-259,-502,-5974,13030,3309,-308,1058,4970 } },
7272 { "Canon PowerShot SX50 HS", 0, 0,
7273 { 12432,-4753,-1247,-2110,10691,1629,-412,1623,4926 } },
7274 { "Canon PowerShot SX60 HS", 0, 0,
7275 { 13161,-5451,-1344,-1989,10654,1531,-47,1271,4955 } },
7276 { "Canon PowerShot A3300", 0, 0, /* DJC */
7277 { 10826,-3654,-1023,-3215,11310,1906,0,999,4960 } },
7278 { "Canon PowerShot A470", 0, 0, /* DJC */
7279 { 12513,-4407,-1242,-2680,10276,2405,-878,2215,4734 } },
7280 { "Canon PowerShot A610", 0, 0, /* DJC */
7281 { 15591,-6402,-1592,-5365,13198,2168,-1300,1824,5075 } },
7282 { "Canon PowerShot A620", 0, 0, /* DJC */
7283 { 15265,-6193,-1558,-4125,12116,2010,-888,1639,5220 } },
7284 { "Canon PowerShot A630", 0, 0, /* DJC */
7285 { 14201,-5308,-1757,-6087,14472,1617,-2191,3105,5348 } },
7286 { "Canon PowerShot A640", 0, 0, /* DJC */
7287 { 13124,-5329,-1390,-3602,11658,1944,-1612,2863,4885 } },
7288 { "Canon PowerShot A650", 0, 0, /* DJC */
7289 { 9427,-3036,-959,-2581,10671,1911,-1039,1982,4430 } },
7290 { "Canon PowerShot A720", 0, 0, /* DJC */
7291 { 14573,-5482,-1546,-1266,9799,1468,-1040,1912,3810 } },
7292 { "Canon PowerShot S3 IS", 0, 0, /* DJC */
7293 { 14062,-5199,-1446,-4712,12470,2243,-1286,2028,4836 } },
7294 { "Canon PowerShot SX110 IS", 0, 0, /* DJC */
7295 { 14134,-5576,-1527,-1991,10719,1273,-1158,1929,3581 } },
7296 { "Canon PowerShot SX220", 0, 0, /* DJC */
7297 { 13898,-5076,-1447,-1405,10109,1297,-244,1860,3687 } },
7298 { "Canon IXUS 160", 0, 0, /* DJC */
7299 { 11657,-3781,-1136,-3544,11262,2283,-160,1219,4700 } },
7300 { "Casio EX-S20", 0, 0, /* DJC */
7301 { 11634,-3924,-1128,-4968,12954,2015,-1588,2648,7206 } },
7302 { "Casio EX-Z750", 0, 0, /* DJC */
7303 { 10819,-3873,-1099,-4903,13730,1175,-1755,3751,4632 } },
7304 { "Casio EX-Z10", 128, 0xfff, /* DJC */
7305 { 9790,-3338,-603,-2321,10222,2099,-344,1273,4799 } },
7307 { 3390,480,-500,-800,3610,340,-550,2336,1192 } },
7309 { 3390,480,-500,-800,3610,340,-550,2336,1192 } },
7311 { 20183,-4295,-423,-3940,15330,3985,-280,4870,9800 } },
7312 { "Contax N Digital", 0, 0xf1e,
7313 { 7777,1285,-1053,-9280,16543,2916,-3677,5679,7060 } },
7315 { 6596,-2079,-562,-4782,13016,1933,-970,1581,5181 } },
7316 { "Epson R-D1", 0, 0,
7317 { 6827,-1878,-732,-8429,16012,2564,-704,592,7145 } },
7318 { "Fujifilm E550", 0, 0,
7319 { 11044,-3888,-1120,-7248,15168,2208,-1531,2277,8069 } },
7320 { "Fujifilm E900", 0, 0,
7321 { 9183,-2526,-1078,-7461,15071,2574,-2022,2440,8639 } },
7322 { "Fujifilm F5", 0, 0,
7323 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
7324 { "Fujifilm F6", 0, 0,
7325 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
7326 { "Fujifilm F77", 0, 0xfe9,
7327 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
7328 { "Fujifilm F7", 0, 0,
7329 { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } },
7330 { "Fujifilm F8", 0, 0,
7331 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
7332 { "Fujifilm S100FS", 514, 0,
7333 { 11521,-4355,-1065,-6524,13767,3058,-1466,1984,6045 } },
7334 { "Fujifilm S1", 0, 0,
7335 { 12297,-4882,-1202,-2106,10691,1623,-88,1312,4790 } },
7336 { "Fujifilm S20Pro", 0, 0,
7337 { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } },
7338 { "Fujifilm S20", 512, 0x3fff,
7339 { 11401,-4498,-1312,-5088,12751,2613,-838,1568,5941 } },
7340 { "Fujifilm S2Pro", 128, 0,
7341 { 12492,-4690,-1402,-7033,15423,1647,-1507,2111,7697 } },
7342 { "Fujifilm S3Pro", 0, 0,
7343 { 11807,-4612,-1294,-8927,16968,1988,-2120,2741,8006 } },
7344 { "Fujifilm S5Pro", 0, 0,
7345 { 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } },
7346 { "Fujifilm S5000", 0, 0,
7347 { 8754,-2732,-1019,-7204,15069,2276,-1702,2334,6982 } },
7348 { "Fujifilm S5100", 0, 0,
7349 { 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } },
7350 { "Fujifilm S5500", 0, 0,
7351 { 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } },
7352 { "Fujifilm S5200", 0, 0,
7353 { 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } },
7354 { "Fujifilm S5600", 0, 0,
7355 { 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } },
7356 { "Fujifilm S6", 0, 0,
7357 { 12628,-4887,-1401,-6861,14996,1962,-2198,2782,7091 } },
7358 { "Fujifilm S7000", 0, 0,
7359 { 10190,-3506,-1312,-7153,15051,2238,-2003,2399,7505 } },
7360 { "Fujifilm S9000", 0, 0,
7361 { 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 } },
7362 { "Fujifilm S9500", 0, 0,
7363 { 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 } },
7364 { "Fujifilm S9100", 0, 0,
7365 { 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 } },
7366 { "Fujifilm S9600", 0, 0,
7367 { 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 } },
7368 { "Fujifilm SL1000", 0, 0,
7369 { 11705,-4262,-1107,-2282,10791,1709,-555,1713,4945 } },
7370 { "Fujifilm IS-1", 0, 0,
7371 { 21461,-10807,-1441,-2332,10599,1999,289,875,7703 } },
7372 { "Fujifilm IS Pro", 0, 0,
7373 { 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } },
7374 { "Fujifilm HS10 HS11", 0, 0xf68,
7375 { 12440,-3954,-1183,-1123,9674,1708,-83,1614,4086 } },
7376 { "Fujifilm HS2", 0, 0,
7377 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
7378 { "Fujifilm HS3", 0, 0,
7379 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
7380 { "Fujifilm HS50EXR", 0, 0,
7381 { 12085,-4727,-953,-3257,11489,2002,-511,2046,4592 } },
7382 { "Fujifilm F900EXR", 0, 0,
7383 { 12085,-4727,-953,-3257,11489,2002,-511,2046,4592 } },
7384 { "Fujifilm X100S", 0, 0,
7385 { 10592,-4262,-1008,-3514,11355,2465,-870,2025,6386 } },
7386 { "Fujifilm X100T", 0, 0,
7387 { 10592,-4262,-1008,-3514,11355,2465,-870,2025,6386 } },
7388 { "Fujifilm X100", 0, 0,
7389 { 12161,-4457,-1069,-5034,12874,2400,-795,1724,6904 } },
7390 { "Fujifilm X10", 0, 0,
7391 { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } },
7392 { "Fujifilm X20", 0, 0,
7393 { 11768,-4971,-1133,-4904,12927,2183,-480,1723,4605 } },
7394 { "Fujifilm X30", 0, 0,
7395 { 12328,-5256,-1144,-4469,12927,1675,-87,1291,4351 } },
7396 { "Fujifilm X70", 0, 0,
7397 { 10450,-4329,-878,-3217,11105,2421,-752,1758,6519 } },
7398 { "Fujifilm X-Pro1", 0, 0,
7399 { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } },
7400 { "Fujifilm X-Pro2", 0, 0,
7401 { 11434,-4948,-1210,-3746,12042,1903,-666,1479,5235 } },
7402 { "Fujifilm X-A1", 0, 0,
7403 { 11086,-4555,-839,-3512,11310,2517,-815,1341,5940 } },
7404 { "Fujifilm X-A2", 0, 0,
7405 { 10763,-4560,-917,-3346,11311,2322,-475,1135,5843 } },
7406 { "Fujifilm X-E1", 0, 0,
7407 { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } },
7408 { "Fujifilm X-E2S", 0, 0,
7409 { 11562,-5118,-961,-3022,11007,2311,-525,1569,6097 } },
7410 { "Fujifilm X-E2", 0, 0,
7411 { 8458,-2451,-855,-4597,12447,2407,-1475,2482,6526 } },
7412 { "Fujifilm X-M1", 0, 0,
7413 { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } },
7414 { "Fujifilm X-S1", 0, 0,
7415 { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } },
7416 { "Fujifilm X-T1", 0, 0, /* also X-T10 */
7417 { 8458,-2451,-855,-4597,12447,2407,-1475,2482,6526 } },
7418 { "Fujifilm XF1", 0, 0,
7419 { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } },
7420 { "Fujifilm XQ", 0, 0, /* XQ1 and XQ2 */
7421 { 9252,-2704,-1064,-5893,14265,1717,-1101,2341,4349 } },
7422 { "Imacon Ixpress", 0, 0, /* DJC */
7423 { 7025,-1415,-704,-5188,13765,1424,-1248,2742,6038 } },
7424 { "Kodak NC2000", 0, 0,
7425 { 13891,-6055,-803,-465,9919,642,2121,82,1291 } },
7426 { "Kodak DCS315C", 8, 0,
7427 { 17523,-4827,-2510,756,8546,-137,6113,1649,2250 } },
7428 { "Kodak DCS330C", 8, 0,
7429 { 20620,-7572,-2801,-103,10073,-396,3551,-233,2220 } },
7430 { "Kodak DCS420", 0, 0,
7431 { 10868,-1852,-644,-1537,11083,484,2343,628,2216 } },
7432 { "Kodak DCS460", 0, 0,
7433 { 10592,-2206,-967,-1944,11685,230,2206,670,1273 } },
7434 { "Kodak EOSDCS1", 0, 0,
7435 { 10592,-2206,-967,-1944,11685,230,2206,670,1273 } },
7436 { "Kodak EOSDCS3B", 0, 0,
7437 { 9898,-2700,-940,-2478,12219,206,1985,634,1031 } },
7438 { "Kodak DCS520C", 178, 0,
7439 { 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } },
7440 { "Kodak DCS560C", 177, 0,
7441 { 20482,-7172,-3125,-1033,10410,-285,2542,226,3136 } },
7442 { "Kodak DCS620C", 177, 0,
7443 { 23617,-10175,-3149,-2054,11749,-272,2586,-489,3453 } },
7444 { "Kodak DCS620X", 176, 0,
7445 { 13095,-6231,154,12221,-21,-2137,895,4602,2258 } },
7446 { "Kodak DCS660C", 173, 0,
7447 { 18244,-6351,-2739,-791,11193,-521,3711,-129,2802 } },
7448 { "Kodak DCS720X", 0, 0,
7449 { 11775,-5884,950,9556,1846,-1286,-1019,6221,2728 } },
7450 { "Kodak DCS760C", 0, 0,
7451 { 16623,-6309,-1411,-4344,13923,323,2285,274,2926 } },
7452 { "Kodak DCS Pro SLR", 0, 0,
7453 { 5494,2393,-232,-6427,13850,2846,-1876,3997,5445 } },
7454 { "Kodak DCS Pro 14nx", 0, 0,
7455 { 5494,2393,-232,-6427,13850,2846,-1876,3997,5445 } },
7456 { "Kodak DCS Pro 14", 0, 0,
7457 { 7791,3128,-776,-8588,16458,2039,-2455,4006,6198 } },
7458 { "Kodak ProBack645", 0, 0,
7459 { 16414,-6060,-1470,-3555,13037,473,2545,122,4948 } },
7460 { "Kodak ProBack", 0, 0,
7461 { 21179,-8316,-2918,-915,11019,-165,3477,-180,4210 } },
7462 { "Kodak P712", 0, 0,
7463 { 9658,-3314,-823,-5163,12695,2768,-1342,1843,6044 } },
7464 { "Kodak P850", 0, 0xf7c,
7465 { 10511,-3836,-1102,-6946,14587,2558,-1481,1792,6246 } },
7466 { "Kodak P880", 0, 0xfff,
7467 { 12805,-4662,-1376,-7480,15267,2360,-1626,2194,7904 } },
7468 { "Kodak EasyShare Z980", 0, 0,
7469 { 11313,-3559,-1101,-3893,11891,2257,-1214,2398,4908 } },
7470 { "Kodak EasyShare Z981", 0, 0,
7471 { 12729,-4717,-1188,-1367,9187,2582,274,860,4411 } },
7472 { "Kodak EasyShare Z990", 0, 0xfed,
7473 { 11749,-4048,-1309,-1867,10572,1489,-138,1449,4522 } },
7474 { "Kodak EASYSHARE Z1015", 0, 0xef1,
7475 { 11265,-4286,-992,-4694,12343,2647,-1090,1523,5447 } },
7476 { "Leaf CMost", 0, 0,
7477 { 3952,2189,449,-6701,14585,2275,-4536,7349,6536 } },
7478 { "Leaf Valeo 6", 0, 0,
7479 { 3952,2189,449,-6701,14585,2275,-4536,7349,6536 } },
7480 { "Leaf Aptus 54S", 0, 0,
7481 { 8236,1746,-1314,-8251,15953,2428,-3673,5786,5771 } },
7482 { "Leaf Aptus 65", 0, 0,
7483 { 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 } },
7484 { "Leaf Aptus 75", 0, 0,
7485 { 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 } },
7487 { 8236,1746,-1314,-8251,15953,2428,-3673,5786,5771 } },
7488 { "Mamiya ZD", 0, 0,
7489 { 7645,2579,-1363,-8689,16717,2015,-3712,5941,5961 } },
7490 { "Micron 2010", 110, 0, /* DJC */
7491 { 16695,-3761,-2151,155,9682,163,3433,951,4904 } },
7492 { "Minolta DiMAGE 5", 0, 0xf7d,
7493 { 8983,-2942,-963,-6556,14476,2237,-2426,2887,8014 } },
7494 { "Minolta DiMAGE 7Hi", 0, 0xf7d,
7495 { 11368,-3894,-1242,-6521,14358,2339,-2475,3056,7285 } },
7496 { "Minolta DiMAGE 7", 0, 0xf7d,
7497 { 9144,-2777,-998,-6676,14556,2281,-2470,3019,7744 } },
7498 { "Minolta DiMAGE A1", 0, 0xf8b,
7499 { 9274,-2547,-1167,-8220,16323,1943,-2273,2720,8340 } },
7500 { "Minolta DiMAGE A200", 0, 0,
7501 { 8560,-2487,-986,-8112,15535,2771,-1209,1324,7743 } },
7502 { "Minolta DiMAGE A2", 0, 0xf8f,
7503 { 9097,-2726,-1053,-8073,15506,2762,-966,981,7763 } },
7504 { "Minolta DiMAGE Z2", 0, 0, /* DJC */
7505 { 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 } },
7506 { "Minolta DYNAX 5", 0, 0xffb,
7507 { 10284,-3283,-1086,-7957,15762,2316,-829,882,6644 } },
7508 { "Minolta DYNAX 7", 0, 0xffb,
7509 { 10239,-3104,-1099,-8037,15727,2451,-927,925,6871 } },
7510 { "Motorola PIXL", 0, 0, /* DJC */
7511 { 8898,-989,-1033,-3292,11619,1674,-661,3178,5216 } },
7512 { "Nikon D100", 0, 0,
7513 { 5902,-933,-782,-8983,16719,2354,-1402,1455,6464 } },
7514 { "Nikon D1H", 0, 0,
7515 { 7577,-2166,-926,-7454,15592,1934,-2377,2808,8606 } },
7516 { "Nikon D1X", 0, 0,
7517 { 7702,-2245,-975,-9114,17242,1875,-2679,3055,8521 } },
7518 { "Nikon D1", 0, 0, /* multiplied by 2.218750, 1.0, 1.148438 */
7519 { 16772,-4726,-2141,-7611,15713,1972,-2846,3494,9521 } },
7520 { "Nikon D200", 0, 0xfbc,
7521 { 8367,-2248,-763,-8758,16447,2422,-1527,1550,8053 } },
7522 { "Nikon D2H", 0, 0,
7523 { 5710,-901,-615,-8594,16617,2024,-2975,4120,6830 } },
7524 { "Nikon D2X", 0, 0,
7525 { 10231,-2769,-1255,-8301,15900,2552,-797,680,7148 } },
7526 { "Nikon D3000", 0, 0,
7527 { 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } },
7528 { "Nikon D3100", 0, 0,
7529 { 7911,-2167,-813,-5327,13150,2408,-1288,2483,7968 } },
7530 { "Nikon D3200", 0, 0xfb9,
7531 { 7013,-1408,-635,-5268,12902,2640,-1470,2801,7379 } },
7532 { "Nikon D3300", 0, 0,
7533 { 6988,-1384,-714,-5631,13410,2447,-1485,2204,7318 } },
7534 { "Nikon D300", 0, 0,
7535 { 9030,-1992,-715,-8465,16302,2255,-2689,3217,8069 } },
7536 { "Nikon D3X", 0, 0,
7537 { 7171,-1986,-648,-8085,15555,2718,-2170,2512,7457 } },
7538 { "Nikon D3S", 0, 0,
7539 { 8828,-2406,-694,-4874,12603,2541,-660,1509,7587 } },
7541 { 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } },
7542 { "Nikon D40X", 0, 0,
7543 { 8819,-2543,-911,-9025,16928,2151,-1329,1213,8449 } },
7544 { "Nikon D40", 0, 0,
7545 { 6992,-1668,-806,-8138,15748,2543,-874,850,7897 } },
7546 { "Nikon D4S", 0, 0,
7547 { 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } },
7549 { 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } },
7551 { 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } },
7552 { "Nikon D5000", 0, 0xf00,
7553 { 7309,-1403,-519,-8474,16008,2622,-2433,2826,8064 } },
7554 { "Nikon D5100", 0, 0x3de6,
7555 { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } },
7556 { "Nikon D5200", 0, 0,
7557 { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } },
7558 { "Nikon D5300", 0, 0,
7559 { 6988,-1384,-714,-5631,13410,2447,-1485,2204,7318 } },
7560 { "Nikon D5500", 0, 0,
7561 { 8821,-2938,-785,-4178,12142,2287,-824,1651,6860 } },
7562 { "Nikon D500", 0, 0,
7563 { 8813,-3210,-1036,-4703,12868,2021,-1054,1940,6129 } },
7564 { "Nikon D50", 0, 0,
7565 { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } },
7567 { 9200,-3522,-992,-5755,13803,2117,-753,1486,6338 } },
7568 { "Nikon D600", 0, 0x3e07,
7569 { 8178,-2245,-609,-4857,12394,2776,-1207,2086,7298 } },
7570 { "Nikon D610", 0, 0,
7571 { 8178,-2245,-609,-4857,12394,2776,-1207,2086,7298 } },
7572 { "Nikon D60", 0, 0,
7573 { 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } },
7574 { "Nikon D7000", 0, 0,
7575 { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } },
7576 { "Nikon D7100", 0, 0,
7577 { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } },
7578 { "Nikon D7200", 0, 0,
7579 { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } },
7580 { "Nikon D750", 0, 0,
7581 { 9020,-2890,-715,-4535,12436,2348,-934,1919,7086 } },
7582 { "Nikon D700", 0, 0,
7583 { 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } },
7584 { "Nikon D70", 0, 0,
7585 { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } },
7586 { "Nikon D810", 0, 0,
7587 { 9369,-3195,-791,-4488,12430,2301,-893,1796,6872 } },
7588 { "Nikon D800", 0, 0,
7589 { 7866,-2108,-555,-4869,12483,2681,-1176,2069,7501 } },
7590 { "Nikon D80", 0, 0,
7591 { 8629,-2410,-883,-9055,16940,2171,-1490,1363,8520 } },
7592 { "Nikon D90", 0, 0xf00,
7593 { 7309,-1403,-519,-8474,16008,2622,-2434,2826,8064 } },
7594 { "Nikon E700", 0, 0x3dd, /* DJC */
7595 { -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } },
7596 { "Nikon E800", 0, 0x3dd, /* DJC */
7597 { -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } },
7598 { "Nikon E950", 0, 0x3dd, /* DJC */
7599 { -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } },
7600 { "Nikon E995", 0, 0, /* copied from E5000 */
7601 { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
7602 { "Nikon E2100", 0, 0, /* copied from Z2, new white balance */
7603 { 13142,-4152,-1596,-4655,12374,2282,-1769,2696,6711} },
7604 { "Nikon E2500", 0, 0,
7605 { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
7606 { "Nikon E3200", 0, 0, /* DJC */
7607 { 9846,-2085,-1019,-3278,11109,2170,-774,2134,5745 } },
7608 { "Nikon E4300", 0, 0, /* copied from Minolta DiMAGE Z2 */
7609 { 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 } },
7610 { "Nikon E4500", 0, 0,
7611 { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
7612 { "Nikon E5000", 0, 0,
7613 { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
7614 { "Nikon E5400", 0, 0,
7615 { 9349,-2987,-1001,-7919,15766,2266,-2098,2680,6839 } },
7616 { "Nikon E5700", 0, 0,
7617 { -5368,11478,2368,5537,-113,3148,-4969,10021,5782,778,9028,211 } },
7618 { "Nikon E8400", 0, 0,
7619 { 7842,-2320,-992,-8154,15718,2599,-1098,1342,7560 } },
7620 { "Nikon E8700", 0, 0,
7621 { 8489,-2583,-1036,-8051,15583,2643,-1307,1407,7354 } },
7622 { "Nikon E8800", 0, 0,
7623 { 7971,-2314,-913,-8451,15762,2894,-1442,1520,7610 } },
7624 { "Nikon COOLPIX A", 0, 0,
7625 { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } },
7626 { "Nikon COOLPIX P330", 200, 0,
7627 { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } },
7628 { "Nikon COOLPIX P340", 200, 0,
7629 { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } },
7630 { "Nikon COOLPIX P6000", 0, 0,
7631 { 9698,-3367,-914,-4706,12584,2368,-837,968,5801 } },
7632 { "Nikon COOLPIX P7000", 0, 0,
7633 { 11432,-3679,-1111,-3169,11239,2202,-791,1380,4455 } },
7634 { "Nikon COOLPIX P7100", 0, 0,
7635 { 11053,-4269,-1024,-1976,10182,2088,-526,1263,4469 } },
7636 { "Nikon COOLPIX P7700", 200, 0,
7637 { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } },
7638 { "Nikon COOLPIX P7800", 200, 0,
7639 { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } },
7640 { "Nikon 1 V3", 0, 0,
7641 { 5958,-1559,-571,-4021,11453,2939,-634,1548,5087 } },
7642 { "Nikon 1 J4", 0, 0,
7643 { 5958,-1559,-571,-4021,11453,2939,-634,1548,5087 } },
7644 { "Nikon 1 J5", 0, 0,
7645 { 7520,-2518,-645,-3844,12102,1945,-913,2249,6835 } },
7646 { "Nikon 1 S2", 200, 0,
7647 { 6612,-1342,-618,-3338,11055,2623,-174,1792,5075 } },
7648 { "Nikon 1 V2", 0, 0,
7649 { 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } },
7650 { "Nikon 1 J3", 0, 0,
7651 { 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } },
7652 { "Nikon 1 AW1", 0, 0,
7653 { 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } },
7654 { "Nikon 1 ", 0, 0, /* J1, J2, S1, V1 */
7655 { 8994,-2667,-865,-4594,12324,2552,-699,1786,6260 } },
7656 { "Olympus AIR A01", 0, 0,
7657 { 8992,-3093,-639,-2563,10721,2122,-437,1270,5473 } },
7658 { "Olympus C5050", 0, 0,
7659 { 10508,-3124,-1273,-6079,14294,1901,-1653,2306,6237 } },
7660 { "Olympus C5060", 0, 0,
7661 { 10445,-3362,-1307,-7662,15690,2058,-1135,1176,7602 } },
7662 { "Olympus C7070", 0, 0,
7663 { 10252,-3531,-1095,-7114,14850,2436,-1451,1723,6365 } },
7664 { "Olympus C70", 0, 0,
7665 { 10793,-3791,-1146,-7498,15177,2488,-1390,1577,7321 } },
7666 { "Olympus C80", 0, 0,
7667 { 8606,-2509,-1014,-8238,15714,2703,-942,979,7760 } },
7668 { "Olympus E-10", 0, 0xffc,
7669 { 12745,-4500,-1416,-6062,14542,1580,-1934,2256,6603 } },
7670 { "Olympus E-1", 0, 0,
7671 { 11846,-4767,-945,-7027,15878,1089,-2699,4122,8311 } },
7672 { "Olympus E-20", 0, 0xffc,
7673 { 13173,-4732,-1499,-5807,14036,1895,-2045,2452,7142 } },
7674 { "Olympus E-300", 0, 0,
7675 { 7828,-1761,-348,-5788,14071,1830,-2853,4518,6557 } },
7676 { "Olympus E-330", 0, 0,
7677 { 8961,-2473,-1084,-7979,15990,2067,-2319,3035,8249 } },
7678 { "Olympus E-30", 0, 0xfbc,
7679 { 8144,-1861,-1111,-7763,15894,1929,-1865,2542,7607 } },
7680 { "Olympus E-3", 0, 0xf99,
7681 { 9487,-2875,-1115,-7533,15606,2010,-1618,2100,7389 } },
7682 { "Olympus E-400", 0, 0,
7683 { 6169,-1483,-21,-7107,14761,2536,-2904,3580,8568 } },
7684 { "Olympus E-410", 0, 0xf6a,
7685 { 8856,-2582,-1026,-7761,15766,2082,-2009,2575,7469 } },
7686 { "Olympus E-420", 0, 0xfd7,
7687 { 8746,-2425,-1095,-7594,15612,2073,-1780,2309,7416 } },
7688 { "Olympus E-450", 0, 0xfd2,
7689 { 8745,-2425,-1095,-7594,15613,2073,-1780,2309,7416 } },
7690 { "Olympus E-500", 0, 0,
7691 { 8136,-1968,-299,-5481,13742,1871,-2556,4205,6630 } },
7692 { "Olympus E-510", 0, 0xf6a,
7693 { 8785,-2529,-1033,-7639,15624,2112,-1783,2300,7817 } },
7694 { "Olympus E-520", 0, 0xfd2,
7695 { 8344,-2322,-1020,-7596,15635,2048,-1748,2269,7287 } },
7696 { "Olympus E-5", 0, 0xeec,
7697 { 11200,-3783,-1325,-4576,12593,2206,-695,1742,7504 } },
7698 { "Olympus E-600", 0, 0xfaf,
7699 { 8453,-2198,-1092,-7609,15681,2008,-1725,2337,7824 } },
7700 { "Olympus E-620", 0, 0xfaf,
7701 { 8453,-2198,-1092,-7609,15681,2008,-1725,2337,7824 } },
7702 { "Olympus E-P1", 0, 0xffd,
7703 { 8343,-2050,-1021,-7715,15705,2103,-1831,2380,8235 } },
7704 { "Olympus E-P2", 0, 0xffd,
7705 { 8343,-2050,-1021,-7715,15705,2103,-1831,2380,8235 } },
7706 { "Olympus E-P3", 0, 0,
7707 { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } },
7708 { "Olympus E-P5", 0, 0,
7709 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
7710 { "Olympus E-PL1s", 0, 0,
7711 { 11409,-3872,-1393,-4572,12757,2003,-709,1810,7415 } },
7712 { "Olympus E-PL1", 0, 0,
7713 { 11408,-4289,-1215,-4286,12385,2118,-387,1467,7787 } },
7714 { "Olympus E-PL2", 0, 0xcf3,
7715 { 15030,-5552,-1806,-3987,12387,1767,-592,1670,7023 } },
7716 { "Olympus E-PL3", 0, 0,
7717 { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } },
7718 { "Olympus E-PL5", 0, 0xfcb,
7719 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
7720 { "Olympus E-PL6", 0, 0,
7721 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
7722 { "Olympus E-PL7", 0, 0,
7723 { 9197,-3190,-659,-2606,10830,2039,-458,1250,5458 } },
7724 { "Olympus E-PM1", 0, 0,
7725 { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } },
7726 { "Olympus E-PM2", 0, 0,
7727 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
7728 { "Olympus E-M10", 0, 0, /* also E-M10 Mark II */
7729 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
7730 { "Olympus E-M1", 0, 0,
7731 { 7687,-1984,-606,-4327,11928,2721,-1381,2339,6452 } },
7732 { "Olympus E-M5MarkII", 0, 0,
7733 { 9422,-3258,-711,-2655,10898,2015,-512,1354,5512 } },
7734 { "Olympus E-M5", 0, 0xfe1,
7735 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
7736 { "Olympus PEN-F", 0, 0,
7737 { 9476,-3182,-765,-2613,10958,1893,-449,1315,5268 } },
7738 { "Olympus SH-2", 0, 0,
7739 { 10156,-3425,-1077,-2611,11177,1624,-385,1592,5080 } },
7740 { "Olympus SP350", 0, 0,
7741 { 12078,-4836,-1069,-6671,14306,2578,-786,939,7418 } },
7742 { "Olympus SP3", 0, 0,
7743 { 11766,-4445,-1067,-6901,14421,2707,-1029,1217,7572 } },
7744 { "Olympus SP500UZ", 0, 0xfff,
7745 { 9493,-3415,-666,-5211,12334,3260,-1548,2262,6482 } },
7746 { "Olympus SP510UZ", 0, 0xffe,
7747 { 10593,-3607,-1010,-5881,13127,3084,-1200,1805,6721 } },
7748 { "Olympus SP550UZ", 0, 0xffe,
7749 { 11597,-4006,-1049,-5432,12799,2957,-1029,1750,6516 } },
7750 { "Olympus SP560UZ", 0, 0xff9,
7751 { 10915,-3677,-982,-5587,12986,2911,-1168,1968,6223 } },
7752 { "Olympus SP570UZ", 0, 0,
7753 { 11522,-4044,-1146,-4736,12172,2904,-988,1829,6039 } },
7754 { "Olympus STYLUS1", 0, 0,
7755 { 8360,-2420,-880,-3928,12353,1739,-1381,2416,5173 } },
7756 { "Olympus TG-4", 0, 0,
7757 { 11426,-4159,-1126,-2066,10678,1593,-120,1327,4998 } },
7758 { "Olympus XZ-10", 0, 0,
7759 { 9777,-3483,-925,-2886,11297,1800,-602,1663,5134 } },
7760 { "Olympus XZ-1", 0, 0,
7761 { 10901,-4095,-1074,-1141,9208,2293,-62,1417,5158 } },
7762 { "Olympus XZ-2", 0, 0,
7763 { 9777,-3483,-925,-2886,11297,1800,-602,1663,5134 } },
7764 { "OmniVision", 0, 0, /* DJC */
7765 { 12782,-4059,-379,-478,9066,1413,1340,1513,5176 } },
7766 { "Pentax *ist DL2", 0, 0,
7767 { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
7768 { "Pentax *ist DL", 0, 0,
7769 { 10829,-2838,-1115,-8339,15817,2696,-837,680,11939 } },
7770 { "Pentax *ist DS2", 0, 0,
7771 { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
7772 { "Pentax *ist DS", 0, 0,
7773 { 10371,-2333,-1206,-8688,16231,2602,-1230,1116,11282 } },
7774 { "Pentax *ist D", 0, 0,
7775 { 9651,-2059,-1189,-8881,16512,2487,-1460,1345,10687 } },
7776 { "Pentax K10D", 0, 0,
7777 { 9566,-2863,-803,-7170,15172,2112,-818,803,9705 } },
7778 { "Pentax K1", 0, 0,
7779 { 11095,-3157,-1324,-8377,15834,2720,-1108,947,11688 } },
7780 { "Pentax K20D", 0, 0,
7781 { 9427,-2714,-868,-7493,16092,1373,-2199,3264,7180 } },
7782 { "Pentax K200D", 0, 0,
7783 { 9186,-2678,-907,-8693,16517,2260,-1129,1094,8524 } },
7784 { "Pentax K2000", 0, 0,
7785 { 11057,-3604,-1155,-5152,13046,2329,-282,375,8104 } },
7786 { "Pentax K-m", 0, 0,
7787 { 11057,-3604,-1155,-5152,13046,2329,-282,375,8104 } },
7788 { "Pentax K-x", 0, 0,
7789 { 8843,-2837,-625,-5025,12644,2668,-411,1234,7410 } },
7790 { "Pentax K-r", 0, 0,
7791 { 9895,-3077,-850,-5304,13035,2521,-883,1768,6936 } },
7792 { "Pentax K-1", 0, 0,
7793 { 8566,-2746,-1201,-3612,12204,1550,-893,1680,6264 } },
7794 { "Pentax K-30", 0, 0,
7795 { 8710,-2632,-1167,-3995,12301,1881,-981,1719,6535 } },
7796 { "Pentax K-3 II", 0, 0,
7797 { 8626,-2607,-1155,-3995,12301,1881,-1039,1822,6925 } },
7798 { "Pentax K-3", 0, 0,
7799 { 7415,-2052,-721,-5186,12788,2682,-1446,2157,6773 } },
7800 { "Pentax K-5 II", 0, 0,
7801 { 8170,-2725,-639,-4440,12017,2744,-771,1465,6599 } },
7802 { "Pentax K-5", 0, 0,
7803 { 8713,-2833,-743,-4342,11900,2772,-722,1543,6247 } },
7804 { "Pentax K-7", 0, 0,
7805 { 9142,-2947,-678,-8648,16967,1663,-2224,2898,8615 } },
7806 { "Pentax K-S1", 0, 0,
7807 { 8512,-3211,-787,-4167,11966,2487,-638,1288,6054 } },
7808 { "Pentax K-S2", 0, 0,
7809 { 8662,-3280,-798,-3928,11771,2444,-586,1232,6054 } },
7810 { "Pentax Q-S1", 0, 0,
7811 { 12995,-5593,-1107,-1879,10139,2027,-64,1233,4919 } },
7812 { "Pentax 645D", 0, 0x3e00,
7813 { 10646,-3593,-1158,-3329,11699,1831,-667,2874,6287 } },
7814 { "Panasonic DMC-CM1", 15, 0,
7815 { 8770,-3194,-820,-2871,11281,1803,-513,1552,4434 } },
7816 { "Panasonic DMC-FZ8", 0, 0xf7f,
7817 { 8986,-2755,-802,-6341,13575,3077,-1476,2144,6379 } },
7818 { "Panasonic DMC-FZ18", 0, 0,
7819 { 9932,-3060,-935,-5809,13331,2753,-1267,2155,5575 } },
7820 { "Panasonic DMC-FZ28", 15, 0xf96,
7821 { 10109,-3488,-993,-5412,12812,2916,-1305,2140,5543 } },
7822 { "Panasonic DMC-FZ330", 15, 0,
7823 { 8378,-2798,-769,-3068,11410,1877,-538,1792,4623 } },
7824 { "Panasonic DMC-FZ300", 15, 0,
7825 { 8378,-2798,-769,-3068,11410,1877,-538,1792,4623 } },
7826 { "Panasonic DMC-FZ30", 0, 0xf94,
7827 { 10976,-4029,-1141,-7918,15491,2600,-1670,2071,8246 } },
7828 { "Panasonic DMC-FZ3", 15, 0,
7829 { 9938,-2780,-890,-4604,12393,2480,-1117,2304,4620 } },
7830 { "Panasonic DMC-FZ4", 15, 0,
7831 { 13639,-5535,-1371,-1698,9633,2430,316,1152,4108 } },
7832 { "Panasonic DMC-FZ50", 0, 0,
7833 { 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } },
7834 { "Panasonic DMC-FZ7", 15, 0,
7835 { 11532,-4324,-1066,-2375,10847,1749,-564,1699,4351 } },
7836 { "Leica V-LUX1", 0, 0,
7837 { 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } },
7838 { "Panasonic DMC-L10", 15, 0xf96,
7839 { 8025,-1942,-1050,-7920,15904,2100,-2456,3005,7039 } },
7840 { "Panasonic DMC-L1", 0, 0xf7f,
7841 { 8054,-1885,-1025,-8349,16367,2040,-2805,3542,7629 } },
7842 { "Leica DIGILUX 3", 0, 0xf7f,
7843 { 8054,-1885,-1025,-8349,16367,2040,-2805,3542,7629 } },
7844 { "Panasonic DMC-LC1", 0, 0,
7845 { 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } },
7846 { "Leica DIGILUX 2", 0, 0,
7847 { 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } },
7848 { "Panasonic DMC-LX100", 15, 0,
7849 { 8844,-3538,-768,-3709,11762,2200,-698,1792,5220 } },
7850 { "Leica D-LUX (Typ 109)", 15, 0,
7851 { 8844,-3538,-768,-3709,11762,2200,-698,1792,5220 } },
7852 { "Panasonic DMC-LF1", 15, 0,
7853 { 9379,-3267,-816,-3227,11560,1881,-926,1928,5340 } },
7854 { "Leica C (Typ 112)", 15, 0,
7855 { 9379,-3267,-816,-3227,11560,1881,-926,1928,5340 } },
7856 { "Panasonic DMC-LX1", 0, 0xf7f,
7857 { 10704,-4187,-1230,-8314,15952,2501,-920,945,8927 } },
7858 { "Leica D-LUX2", 0, 0xf7f,
7859 { 10704,-4187,-1230,-8314,15952,2501,-920,945,8927 } },
7860 { "Panasonic DMC-LX2", 0, 0,
7861 { 8048,-2810,-623,-6450,13519,3272,-1700,2146,7049 } },
7862 { "Leica D-LUX3", 0, 0,
7863 { 8048,-2810,-623,-6450,13519,3272,-1700,2146,7049 } },
7864 { "Panasonic DMC-LX3", 15, 0,
7865 { 8128,-2668,-655,-6134,13307,3161,-1782,2568,6083 } },
7866 { "Leica D-LUX 4", 15, 0,
7867 { 8128,-2668,-655,-6134,13307,3161,-1782,2568,6083 } },
7868 { "Panasonic DMC-LX5", 15, 0,
7869 { 10909,-4295,-948,-1333,9306,2399,22,1738,4582 } },
7870 { "Leica D-LUX 5", 15, 0,
7871 { 10909,-4295,-948,-1333,9306,2399,22,1738,4582 } },
7872 { "Panasonic DMC-LX7", 15, 0,
7873 { 10148,-3743,-991,-2837,11366,1659,-701,1893,4899 } },
7874 { "Leica D-LUX 6", 15, 0,
7875 { 10148,-3743,-991,-2837,11366,1659,-701,1893,4899 } },
7876 { "Panasonic DMC-FZ1000", 15, 0,
7877 { 7830,-2696,-763,-3325,11667,1866,-641,1712,4824 } },
7878 { "Leica V-LUX (Typ 114)", 15, 0,
7879 { 7830,-2696,-763,-3325,11667,1866,-641,1712,4824 } },
7880 { "Panasonic DMC-FZ100", 15, 0xfff,
7881 { 16197,-6146,-1761,-2393,10765,1869,366,2238,5248 } },
7882 { "Leica V-LUX 2", 15, 0xfff,
7883 { 16197,-6146,-1761,-2393,10765,1869,366,2238,5248 } },
7884 { "Panasonic DMC-FZ150", 15, 0xfff,
7885 { 11904,-4541,-1189,-2355,10899,1662,-296,1586,4289 } },
7886 { "Leica V-LUX 3", 15, 0xfff,
7887 { 11904,-4541,-1189,-2355,10899,1662,-296,1586,4289 } },
7888 { "Panasonic DMC-FZ200", 15, 0xfff,
7889 { 8112,-2563,-740,-3730,11784,2197,-941,2075,4933 } },
7890 { "Leica V-LUX 4", 15, 0xfff,
7891 { 8112,-2563,-740,-3730,11784,2197,-941,2075,4933 } },
7892 { "Panasonic DMC-FX150", 15, 0xfff,
7893 { 9082,-2907,-925,-6119,13377,3058,-1797,2641,5609 } },
7894 { "Panasonic DMC-G10", 0, 0,
7895 { 10113,-3400,-1114,-4765,12683,2317,-377,1437,6710 } },
7896 { "Panasonic DMC-G1", 15, 0xf94,
7897 { 8199,-2065,-1056,-8124,16156,2033,-2458,3022,7220 } },
7898 { "Panasonic DMC-G2", 15, 0xf3c,
7899 { 10113,-3400,-1114,-4765,12683,2317,-377,1437,6710 } },
7900 { "Panasonic DMC-G3", 15, 0xfff,
7901 { 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } },
7902 { "Panasonic DMC-G5", 15, 0xfff,
7903 { 7798,-2562,-740,-3879,11584,2613,-1055,2248,5434 } },
7904 { "Panasonic DMC-G6", 15, 0xfff,
7905 { 8294,-2891,-651,-3869,11590,2595,-1183,2267,5352 } },
7906 { "Panasonic DMC-G7", 15, 0xfff,
7907 { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } },
7908 { "Panasonic DMC-GF1", 15, 0xf92,
7909 { 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } },
7910 { "Panasonic DMC-GF2", 15, 0xfff,
7911 { 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } },
7912 { "Panasonic DMC-GF3", 15, 0xfff,
7913 { 9051,-2468,-1204,-5212,13276,2121,-1197,2510,6890 } },
7914 { "Panasonic DMC-GF5", 15, 0xfff,
7915 { 8228,-2945,-660,-3938,11792,2430,-1094,2278,5793 } },
7916 { "Panasonic DMC-GF6", 15, 0,
7917 { 8130,-2801,-946,-3520,11289,2552,-1314,2511,5791 } },
7918 { "Panasonic DMC-GF7", 15, 0,
7919 { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } },
7920 { "Panasonic DMC-GF8", 15, 0,
7921 { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } },
7922 { "Panasonic DMC-GH1", 15, 0xf92,
7923 { 6299,-1466,-532,-6535,13852,2969,-2331,3112,5984 } },
7924 { "Panasonic DMC-GH2", 15, 0xf95,
7925 { 7780,-2410,-806,-3913,11724,2484,-1018,2390,5298 } },
7926 { "Panasonic DMC-GH3", 15, 0,
7927 { 6559,-1752,-491,-3672,11407,2586,-962,1875,5130 } },
7928 { "Panasonic DMC-GH4", 15, 0,
7929 { 7122,-2108,-512,-3155,11201,2231,-541,1423,5045 } },
7930 { "Panasonic DMC-GM1", 15, 0,
7931 { 6770,-1895,-744,-5232,13145,2303,-1664,2691,5703 } },
7932 { "Panasonic DMC-GM5", 15, 0,
7933 { 8238,-3244,-679,-3921,11814,2384,-836,2022,5852 } },
7934 { "Panasonic DMC-GX1", 15, 0,
7935 { 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } },
7936 { "Panasonic DMC-GX7", 15, 0,
7937 { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } },
7938 { "Panasonic DMC-GX8", 15, 0,
7939 { 7564,-2263,-606,-3148,11239,2177,-540,1435,4853 } },
7940 { "Panasonic DMC-TZ1", 15, 0,
7941 { 7790,-2736,-755,-3452,11870,1769,-628,1647,4898 } },
7942 { "Panasonic DMC-ZS1", 15, 0,
7943 { 7790,-2736,-755,-3452,11870,1769,-628,1647,4898 } },
7944 { "Panasonic DMC-TZ6", 15, 0,
7945 { 8607,-2822,-808,-3755,11930,2049,-820,2060,5224 } },
7946 { "Panasonic DMC-ZS4", 15, 0,
7947 { 8607,-2822,-808,-3755,11930,2049,-820,2060,5224 } },
7948 { "Panasonic DMC-TZ7", 15, 0,
7949 { 8802,-3135,-789,-3151,11468,1904,-550,1745,4810 } },
7950 { "Panasonic DMC-ZS5", 15, 0,
7951 { 8802,-3135,-789,-3151,11468,1904,-550,1745,4810 } },
7952 { "Panasonic DMC-TZ8", 15, 0,
7953 { 8550,-2908,-842,-3195,11529,1881,-338,1603,4631 } },
7954 { "Panasonic DMC-ZS6", 15, 0,
7955 { 8550,-2908,-842,-3195,11529,1881,-338,1603,4631 } },
7956 { "Leica S (Typ 007)", 0, 0,
7957 { 6063,-2234,-231,-5210,13787,1500,-1043,2866,6997 } },
7958 { "Leica X", 0, 0, /* X and X-U, both (Typ 113) */
7959 { 7712,-2059,-653,-3882,11494,2726,-710,1332,5958 } },
7960 { "Leica Q (Typ 116)", 0, 0,
7961 { 11865,-4523,-1441,-5423,14458,935,-1587,2687,4830 } },
7962 { "Leica M (Typ 262)", 0, 0,
7963 { 6653,-1486,-611,-4221,13303,929,-881,2416,7226 } },
7964 { "Leica SL (Typ 601)", 0, 0,
7965 { 11865,-4523,-1441,-5423,14458,935,-1587,2687,4830} },
7966 { "Phase One H 20", 0, 0, /* DJC */
7967 { 1313,1855,-109,-6715,15908,808,-327,1840,6020 } },
7968 { "Phase One H 25", 0, 0,
7969 { 2905,732,-237,-8134,16626,1476,-3038,4253,7517 } },
7970 { "Phase One P 2", 0, 0,
7971 { 2905,732,-237,-8134,16626,1476,-3038,4253,7517 } },
7972 { "Phase One P 30", 0, 0,
7973 { 4516,-245,-37,-7020,14976,2173,-3206,4671,7087 } },
7974 { "Phase One P 45", 0, 0,
7975 { 5053,-24,-117,-5684,14076,1702,-2619,4492,5849 } },
7976 { "Phase One P40", 0, 0,
7977 { 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } },
7978 { "Phase One P65", 0, 0,
7979 { 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } },
7980 { "Photron BC2-HD", 0, 0, /* DJC */
7981 { 14603,-4122,-528,-1810,9794,2017,-297,2763,5936 } },
7982 { "Red One", 704, 0xffff, /* DJC */
7983 { 21014,-7891,-2613,-3056,12201,856,-2203,5125,8042 } },
7984 { "Ricoh GR II", 0, 0,
7985 { 4630,-834,-423,-4977,12805,2417,-638,1467,6115 } },
7987 { 3708,-543,-160,-5381,12254,3556,-1471,1929,8234 } },
7988 { "Samsung EX1", 0, 0x3e00,
7989 { 8898,-2498,-994,-3144,11328,2066,-760,1381,4576 } },
7990 { "Samsung EX2F", 0, 0x7ff,
7991 { 10648,-3897,-1055,-2022,10573,1668,-492,1611,4742 } },
7992 { "Samsung EK-GN120", 0, 0,
7993 { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } },
7994 { "Samsung NX mini", 0, 0,
7995 { 5222,-1196,-550,-6540,14649,2009,-1666,2819,5657 } },
7996 { "Samsung NX3300", 0, 0,
7997 { 8060,-2933,-761,-4504,12890,1762,-630,1489,5227 } },
7998 { "Samsung NX3000", 0, 0,
7999 { 8060,-2933,-761,-4504,12890,1762,-630,1489,5227 } },
8000 { "Samsung NX30", 0, 0, /* NX30, NX300, NX300M */
8001 { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } },
8002 { "Samsung NX2000", 0, 0,
8003 { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } },
8004 { "Samsung NX2", 0, 0xfff, /* NX20, NX200, NX210 */
8005 { 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } },
8006 { "Samsung NX1000", 0, 0,
8007 { 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } },
8008 { "Samsung NX1100", 0, 0,
8009 { 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } },
8010 { "Samsung NX11", 0, 0,
8011 { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } },
8012 { "Samsung NX10", 0, 0, /* also NX100 */
8013 { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } },
8014 { "Samsung NX500", 0, 0,
8015 { 10686,-4042,-1052,-3595,13238,276,-464,1259,5931 } },
8016 { "Samsung NX5", 0, 0,
8017 { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } },
8018 { "Samsung NX1", 0, 0,
8019 { 10686,-4042,-1052,-3595,13238,276,-464,1259,5931 } },
8020 { "Samsung WB2000", 0, 0xfff,
8021 { 12093,-3557,-1155,-1000,9534,1733,-22,1787,4576 } },
8022 { "Samsung GX-1", 0, 0,
8023 { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
8024 { "Samsung GX20", 0, 0, /* copied from Pentax K20D */
8025 { 9427,-2714,-868,-7493,16092,1373,-2199,3264,7180 } },
8026 { "Samsung S85", 0, 0, /* DJC */
8027 { 11885,-3968,-1473,-4214,12299,1916,-835,1655,5549 } },
8028 { "Sinar", 0, 0, /* DJC */
8029 { 16442,-2956,-2422,-2877,12128,750,-1136,6066,4559 } },
8030 { "Sony DSC-F828", 0, 0,
8031 { 7924,-1910,-777,-8226,15459,2998,-1517,2199,6818,-7242,11401,3481 } },
8032 { "Sony DSC-R1", 0, 0,
8033 { 8512,-2641,-694,-8042,15670,2526,-1821,2117,7414 } },
8034 { "Sony DSC-V3", 0, 0,
8035 { 7511,-2571,-692,-7894,15088,3060,-948,1111,8128 } },
8036 { "Sony DSC-RX100M", 0, 0, /* M2, M3, and M4 */
8037 { 6596,-2079,-562,-4782,13016,1933,-970,1581,5181 } },
8038 { "Sony DSC-RX100", 0, 0,
8039 { 8651,-2754,-1057,-3464,12207,1373,-568,1398,4434 } },
8040 { "Sony DSC-RX10", 0, 0, /* also RX10M2 */
8041 { 6679,-1825,-745,-5047,13256,1953,-1580,2422,5183 } },
8042 { "Sony DSC-RX1RM2", 0, 0,
8043 { 6629,-1900,-483,-4618,12349,2550,-622,1381,6514 } },
8044 { "Sony DSC-RX1", 0, 0,
8045 { 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } },
8046 { "Sony DSLR-A100", 0, 0xfeb,
8047 { 9437,-2811,-774,-8405,16215,2290,-710,596,7181 } },
8048 { "Sony DSLR-A290", 0, 0,
8049 { 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } },
8050 { "Sony DSLR-A2", 0, 0,
8051 { 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } },
8052 { "Sony DSLR-A300", 0, 0,
8053 { 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } },
8054 { "Sony DSLR-A330", 0, 0,
8055 { 9847,-3091,-929,-8485,16346,2225,-714,595,7103 } },
8056 { "Sony DSLR-A350", 0, 0xffc,
8057 { 6038,-1484,-578,-9146,16746,2513,-875,746,7217 } },
8058 { "Sony DSLR-A380", 0, 0,
8059 { 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } },
8060 { "Sony DSLR-A390", 0, 0,
8061 { 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } },
8062 { "Sony DSLR-A450", 0, 0xfeb,
8063 { 4950,-580,-103,-5228,12542,3029,-709,1435,7371 } },
8064 { "Sony DSLR-A580", 0, 0xfeb,
8065 { 5932,-1492,-411,-4813,12285,2856,-741,1524,6739 } },
8066 { "Sony DSLR-A500", 0, 0xfeb,
8067 { 6046,-1127,-278,-5574,13076,2786,-691,1419,7625 } },
8068 { "Sony DSLR-A5", 0, 0xfeb,
8069 { 4950,-580,-103,-5228,12542,3029,-709,1435,7371 } },
8070 { "Sony DSLR-A700", 0, 0,
8071 { 5775,-805,-359,-8574,16295,2391,-1943,2341,7249 } },
8072 { "Sony DSLR-A850", 0, 0,
8073 { 5413,-1162,-365,-5665,13098,2866,-608,1179,8440 } },
8074 { "Sony DSLR-A900", 0, 0,
8075 { 5209,-1072,-397,-8845,16120,2919,-1618,1803,8654 } },
8076 { "Sony ILCA-68", 0, 0,
8077 { 6435,-1903,-536,-4722,12449,2550,-663,1363,6517 } },
8078 { "Sony ILCA-77M2", 0, 0,
8079 { 5991,-1732,-443,-4100,11989,2381,-704,1467,5992 } },
8080 { "Sony ILCE-6300", 0, 0,
8081 { 5973,-1695,-419,-3826,11797,2293,-639,1398,5789 } },
8082 { "Sony ILCE-7M2", 0, 0,
8083 { 5271,-712,-347,-6153,13653,2763,-1601,2366,7242 } },
8084 { "Sony ILCE-7S", 0, 0, /* also ILCE-7SM2 */
8085 { 5838,-1430,-246,-3497,11477,2297,-748,1885,5778 } },
8086 { "Sony ILCE-7RM2", 0, 0,
8087 { 6629,-1900,-483,-4618,12349,2550,-622,1381,6514 } },
8088 { "Sony ILCE-7R", 0, 0,
8089 { 4913,-541,-202,-6130,13513,2906,-1564,2151,7183 } },
8090 { "Sony ILCE-7", 0, 0,
8091 { 5271,-712,-347,-6153,13653,2763,-1601,2366,7242 } },
8092 { "Sony ILCE", 0, 0, /* 3000, 5000, 5100, 6000, and QX1 */
8093 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
8094 { "Sony NEX-5N", 0, 0,
8095 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
8096 { "Sony NEX-5R", 0, 0,
8097 { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } },
8098 { "Sony NEX-5T", 0, 0,
8099 { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } },
8100 { "Sony NEX-3N", 0, 0,
8101 { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } },
8102 { "Sony NEX-3", 138, 0, /* DJC */
8103 { 6907,-1256,-645,-4940,12621,2320,-1710,2581,6230 } },
8104 { "Sony NEX-5", 116, 0, /* DJC */
8105 { 6807,-1350,-342,-4216,11649,2567,-1089,2001,6420 } },
8106 { "Sony NEX-3", 0, 0, /* Adobe */
8107 { 6549,-1550,-436,-4880,12435,2753,-854,1868,6976 } },
8108 { "Sony NEX-5", 0, 0, /* Adobe */
8109 { 6549,-1550,-436,-4880,12435,2753,-854,1868,6976 } },
8110 { "Sony NEX-6", 0, 0,
8111 { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } },
8112 { "Sony NEX-7", 0, 0,
8113 { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } },
8114 { "Sony NEX", 0, 0, /* NEX-C3, NEX-F3 */
8115 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
8116 { "Sony SLT-A33", 0, 0,
8117 { 6069,-1221,-366,-5221,12779,2734,-1024,2066,6834 } },
8118 { "Sony SLT-A35", 0, 0,
8119 { 5986,-1618,-415,-4557,11820,3120,-681,1404,6971 } },
8120 { "Sony SLT-A37", 0, 0,
8121 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
8122 { "Sony SLT-A55", 0, 0,
8123 { 5932,-1492,-411,-4813,12285,2856,-741,1524,6739 } },
8124 { "Sony SLT-A57", 0, 0,
8125 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
8126 { "Sony SLT-A58", 0, 0,
8127 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
8128 { "Sony SLT-A65", 0, 0,
8129 { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } },
8130 { "Sony SLT-A77", 0, 0,
8131 { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } },
8132 { "Sony SLT-A99", 0, 0,
8133 { 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } },
8135 double cam_xyz[4][3];
8139 sprintf (name, "%s %s", make, model);
8140 for (i=0; i < sizeof table / sizeof *table; i++)
8141 if (!strncmp (name, table[i].prefix, strlen(table[i].prefix))) {
8142 if (table[i].black) black = (ushort) table[i].black;
8143 if (table[i].maximum) maximum = (ushort) table[i].maximum;
8144 if (table[i].trans[0]) {
8145 for (raw_color = j=0; j < 12; j++)
8146 ((double *)cam_xyz)[j] = table[i].trans[j] / 10000.0;
8147 cam_xyz_coeff (rgb_cam, cam_xyz);
8153 void CLASS simple_coeff (int index)
8155 static const float table[][12] = {
8156 /* index 0 -- all Foveon cameras */
8157 { 1.4032,-0.2231,-0.1016,-0.5263,1.4816,0.017,-0.0112,0.0183,0.9113 },
8158 /* index 1 -- Kodak DC20 and DC25 */
8159 { 2.25,0.75,-1.75,-0.25,-0.25,0.75,0.75,-0.25,-0.25,-1.75,0.75,2.25 },
8160 /* index 2 -- Logitech Fotoman Pixtura */
8161 { 1.893,-0.418,-0.476,-0.495,1.773,-0.278,-1.017,-0.655,2.672 },
8162 /* index 3 -- Nikon E880, E900, and E990 */
8163 { -1.936280, 1.800443, -1.448486, 2.584324,
8164 1.405365, -0.524955, -0.289090, 0.408680,
8165 -1.204965, 1.082304, 2.941367, -1.818705 }
8169 for (raw_color = i=0; i < 3; i++)
8170 FORCC rgb_cam[i][c] = table[index][i*colors+c];
8173 short CLASS guess_byte_order (int words)
8177 double diff, sum[2] = {0,0};
8179 fread (test[0], 2, 2, ifp);
8180 for (words-=2; words--; ) {
8181 fread (test[t], 2, 1, ifp);
8182 for (msb=0; msb < 2; msb++) {
8183 diff = (test[t^2][msb] << 8 | test[t^2][!msb])
8184 - (test[t ][msb] << 8 | test[t ][!msb]);
8185 sum[msb] += diff*diff;
8189 return sum[0] < sum[1] ? 0x4d4d : 0x4949;
8192 float CLASS find_green (int bps, int bite, int off0, int off1)
8195 int vbits, col, i, c;
8196 ushort img[2][2064];
8200 fseek (ifp, c ? off1:off0, SEEK_SET);
8201 for (vbits=col=0; col < width; col++) {
8202 for (vbits -= bps; vbits < 0; vbits += bite) {
8204 for (i=0; i < bite; i+=8)
8205 bitbuf |= (unsigned) (fgetc(ifp) << i);
8207 img[c][col] = bitbuf << (64-bps-vbits) >> (64-bps);
8211 sum[ c & 1] += ABS(img[0][c]-img[1][c+1]);
8212 sum[~c & 1] += ABS(img[1][c]-img[0][c+1]);
8214 return 100 * log(sum[0]/sum[1]);
8218 Identify which camera created this file, and set global variables
8221 void CLASS identify()
8223 static const short pana[][6] = {
8224 { 3130, 1743, 4, 0, -6, 0 },
8225 { 3130, 2055, 4, 0, -6, 0 },
8226 { 3130, 2319, 4, 0, -6, 0 },
8227 { 3170, 2103, 18, 0,-42, 20 },
8228 { 3170, 2367, 18, 13,-42,-21 },
8229 { 3177, 2367, 0, 0, -1, 0 },
8230 { 3304, 2458, 0, 0, -1, 0 },
8231 { 3330, 2463, 9, 0, -5, 0 },
8232 { 3330, 2479, 9, 0,-17, 4 },
8233 { 3370, 1899, 15, 0,-44, 20 },
8234 { 3370, 2235, 15, 0,-44, 20 },
8235 { 3370, 2511, 15, 10,-44,-21 },
8236 { 3690, 2751, 3, 0, -8, -3 },
8237 { 3710, 2751, 0, 0, -3, 0 },
8238 { 3724, 2450, 0, 0, 0, -2 },
8239 { 3770, 2487, 17, 0,-44, 19 },
8240 { 3770, 2799, 17, 15,-44,-19 },
8241 { 3880, 2170, 6, 0, -6, 0 },
8242 { 4060, 3018, 0, 0, 0, -2 },
8243 { 4290, 2391, 3, 0, -8, -1 },
8244 { 4330, 2439, 17, 15,-44,-19 },
8245 { 4508, 2962, 0, 0, -3, -4 },
8246 { 4508, 3330, 0, 0, -3, -6 },
8248 static const ushort canon[][11] = {
8249 { 1944, 1416, 0, 0, 48, 0 },
8250 { 2144, 1560, 4, 8, 52, 2, 0, 0, 0, 25 },
8251 { 2224, 1456, 48, 6, 0, 2 },
8252 { 2376, 1728, 12, 6, 52, 2 },
8253 { 2672, 1968, 12, 6, 44, 2 },
8254 { 3152, 2068, 64, 12, 0, 0, 16 },
8255 { 3160, 2344, 44, 12, 4, 4 },
8256 { 3344, 2484, 4, 6, 52, 6 },
8257 { 3516, 2328, 42, 14, 0, 0 },
8258 { 3596, 2360, 74, 12, 0, 0 },
8259 { 3744, 2784, 52, 12, 8, 12 },
8260 { 3944, 2622, 30, 18, 6, 2 },
8261 { 3948, 2622, 42, 18, 0, 2 },
8262 { 3984, 2622, 76, 20, 0, 2, 14 },
8263 { 4104, 3048, 48, 12, 24, 12 },
8264 { 4116, 2178, 4, 2, 0, 0 },
8265 { 4152, 2772, 192, 12, 0, 0 },
8266 { 4160, 3124, 104, 11, 8, 65 },
8267 { 4176, 3062, 96, 17, 8, 0, 0, 16, 0, 7, 0x49 },
8268 { 4192, 3062, 96, 17, 24, 0, 0, 16, 0, 0, 0x49 },
8269 { 4312, 2876, 22, 18, 0, 2 },
8270 { 4352, 2874, 62, 18, 0, 0 },
8271 { 4476, 2954, 90, 34, 0, 0 },
8272 { 4480, 3348, 12, 10, 36, 12, 0, 0, 0, 18, 0x49 },
8273 { 4480, 3366, 80, 50, 0, 0 },
8274 { 4496, 3366, 80, 50, 12, 0 },
8275 { 4768, 3516, 96, 16, 0, 0, 0, 16 },
8276 { 4832, 3204, 62, 26, 0, 0 },
8277 { 4832, 3228, 62, 51, 0, 0 },
8278 { 5108, 3349, 98, 13, 0, 0 },
8279 { 5120, 3318, 142, 45, 62, 0 },
8280 { 5280, 3528, 72, 52, 0, 0 },
8281 { 5344, 3516, 142, 51, 0, 0 },
8282 { 5344, 3584, 126,100, 0, 2 },
8283 { 5360, 3516, 158, 51, 0, 0 },
8284 { 5568, 3708, 72, 38, 0, 0 },
8285 { 5632, 3710, 96, 17, 0, 0, 0, 16, 0, 0, 0x49 },
8286 { 5712, 3774, 62, 20, 10, 2 },
8287 { 5792, 3804, 158, 51, 0, 0 },
8288 { 5920, 3950, 122, 80, 2, 0 },
8289 { 6096, 4056, 72, 34, 0, 0 },
8290 { 6288, 4056, 264, 34, 0, 0 },
8291 { 8896, 5920, 160, 64, 0, 0 },
8293 static const struct {
8297 { 0x168, "EOS 10D" }, { 0x001, "EOS-1D" },
8298 { 0x175, "EOS 20D" }, { 0x174, "EOS-1D Mark II" },
8299 { 0x234, "EOS 30D" }, { 0x232, "EOS-1D Mark II N" },
8300 { 0x190, "EOS 40D" }, { 0x169, "EOS-1D Mark III" },
8301 { 0x261, "EOS 50D" }, { 0x281, "EOS-1D Mark IV" },
8302 { 0x287, "EOS 60D" }, { 0x167, "EOS-1DS" },
8303 { 0x325, "EOS 70D" },
8304 { 0x350, "EOS 80D" }, { 0x328, "EOS-1D X Mark II" },
8305 { 0x170, "EOS 300D" }, { 0x188, "EOS-1Ds Mark II" },
8306 { 0x176, "EOS 450D" }, { 0x215, "EOS-1Ds Mark III" },
8307 { 0x189, "EOS 350D" }, { 0x324, "EOS-1D C" },
8308 { 0x236, "EOS 400D" }, { 0x269, "EOS-1D X" },
8309 { 0x252, "EOS 500D" }, { 0x213, "EOS 5D" },
8310 { 0x270, "EOS 550D" }, { 0x218, "EOS 5D Mark II" },
8311 { 0x286, "EOS 600D" }, { 0x285, "EOS 5D Mark III" },
8312 { 0x301, "EOS 650D" }, { 0x302, "EOS 6D" },
8313 { 0x326, "EOS 700D" }, { 0x250, "EOS 7D" },
8314 { 0x393, "EOS 750D" }, { 0x289, "EOS 7D Mark II" },
8315 { 0x347, "EOS 760D" },
8316 { 0x254, "EOS 1000D" },
8317 { 0x288, "EOS 1100D" },
8318 { 0x327, "EOS 1200D" }, { 0x382, "Canon EOS 5DS" },
8319 { 0x404, "EOS 1300D" }, { 0x401, "Canon EOS 5DS R" },
8320 { 0x346, "EOS 100D" },
8322 { 0x002, "DSC-R1" }, { 0x100, "DSLR-A100" },
8323 { 0x101, "DSLR-A900" }, { 0x102, "DSLR-A700" },
8324 { 0x103, "DSLR-A200" }, { 0x104, "DSLR-A350" },
8325 { 0x105, "DSLR-A300" }, { 0x108, "DSLR-A330" },
8326 { 0x109, "DSLR-A230" }, { 0x10a, "DSLR-A290" },
8327 { 0x10d, "DSLR-A850" }, { 0x111, "DSLR-A550" },
8328 { 0x112, "DSLR-A500" }, { 0x113, "DSLR-A450" },
8329 { 0x116, "NEX-5" }, { 0x117, "NEX-3" },
8330 { 0x118, "SLT-A33" }, { 0x119, "SLT-A55V" },
8331 { 0x11a, "DSLR-A560" }, { 0x11b, "DSLR-A580" },
8332 { 0x11c, "NEX-C3" }, { 0x11d, "SLT-A35" },
8333 { 0x11e, "SLT-A65V" }, { 0x11f, "SLT-A77V" },
8334 { 0x120, "NEX-5N" }, { 0x121, "NEX-7" },
8335 { 0x123, "SLT-A37" }, { 0x124, "SLT-A57" },
8336 { 0x125, "NEX-F3" }, { 0x126, "SLT-A99V" },
8337 { 0x127, "NEX-6" }, { 0x128, "NEX-5R" },
8338 { 0x129, "DSC-RX100" }, { 0x12a, "DSC-RX1" },
8339 { 0x12e, "ILCE-3000" }, { 0x12f, "SLT-A58" },
8340 { 0x131, "NEX-3N" }, { 0x132, "ILCE-7" },
8341 { 0x133, "NEX-5T" }, { 0x134, "DSC-RX100M2" },
8342 { 0x135, "DSC-RX10" }, { 0x136, "DSC-RX1R" },
8343 { 0x137, "ILCE-7R" }, { 0x138, "ILCE-6000" },
8344 { 0x139, "ILCE-5000" }, { 0x13d, "DSC-RX100M3" },
8345 { 0x13e, "ILCE-7S" }, { 0x13f, "ILCA-77M2" },
8346 { 0x153, "ILCE-5100" }, { 0x154, "ILCE-7M2" },
8347 { 0x155, "DSC-RX100M4" },{ 0x156, "DSC-RX10M2" },
8348 { 0x158, "DSC-RX1RM2" }, { 0x15a, "ILCE-QX1" },
8349 { 0x15b, "ILCE-7RM2" }, { 0x15e, "ILCE-7SM2" },
8350 { 0x161, "ILCA-68" }, { 0x165, "ILCE-6300" },
8352 static const struct {
8355 uchar lm, tm, rm, bm, lf, cf, max, flags;
8356 char make[10], model[20];
8359 { 786432,1024, 768, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-080C" },
8360 { 1447680,1392,1040, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-145C" },
8361 { 1920000,1600,1200, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-201C" },
8362 { 5067304,2588,1958, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-510C" },
8363 { 5067316,2588,1958, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-510C",12 },
8364 { 10134608,2588,1958, 0, 0, 0, 0, 9,0x94,0,0,"AVT","F-510C" },
8365 { 10134620,2588,1958, 0, 0, 0, 0, 9,0x94,0,0,"AVT","F-510C",12 },
8366 { 16157136,3272,2469, 0, 0, 0, 0, 9,0x94,0,0,"AVT","F-810C" },
8367 { 15980544,3264,2448, 0, 0, 0, 0, 8,0x61,0,1,"AgfaPhoto","DC-833m" },
8368 { 9631728,2532,1902, 0, 0, 0, 0,96,0x61,0,0,"Alcatel","5035D" },
8369 { 2868726,1384,1036, 0, 0, 0, 0,64,0x49,0,8,"Baumer","TXG14",1078 },
8370 { 5298000,2400,1766,12,12,44, 2,40,0x94,0,2,"Canon","PowerShot SD300" },
8371 { 6553440,2664,1968, 4, 4,44, 4,40,0x94,0,2,"Canon","PowerShot A460" },
8372 { 6573120,2672,1968,12, 8,44, 0,40,0x94,0,2,"Canon","PowerShot A610" },
8373 { 6653280,2672,1992,10, 6,42, 2,40,0x94,0,2,"Canon","PowerShot A530" },
8374 { 7710960,2888,2136,44, 8, 4, 0,40,0x94,0,2,"Canon","PowerShot S3 IS" },
8375 { 9219600,3152,2340,36,12, 4, 0,40,0x94,0,2,"Canon","PowerShot A620" },
8376 { 9243240,3152,2346,12, 7,44,13,40,0x49,0,2,"Canon","PowerShot A470" },
8377 { 10341600,3336,2480, 6, 5,32, 3,40,0x94,0,2,"Canon","PowerShot A720 IS" },
8378 { 10383120,3344,2484,12, 6,44, 6,40,0x94,0,2,"Canon","PowerShot A630" },
8379 { 12945240,3736,2772,12, 6,52, 6,40,0x94,0,2,"Canon","PowerShot A640" },
8380 { 15636240,4104,3048,48,12,24,12,40,0x94,0,2,"Canon","PowerShot A650" },
8381 { 15467760,3720,2772, 6,12,30, 0,40,0x94,0,2,"Canon","PowerShot SX110 IS" },
8382 { 15534576,3728,2778,12, 9,44, 9,40,0x94,0,2,"Canon","PowerShot SX120 IS" },
8383 { 18653760,4080,3048,24,12,24,12,40,0x94,0,2,"Canon","PowerShot SX20 IS" },
8384 { 19131120,4168,3060,92,16, 4, 1,40,0x94,0,2,"Canon","PowerShot SX220 HS" },
8385 { 21936096,4464,3276,25,10,73,12,40,0x16,0,2,"Canon","PowerShot SX30 IS" },
8386 { 24724224,4704,3504, 8,16,56, 8,40,0x94,0,2,"Canon","PowerShot A3300 IS" },
8387 { 30858240,5248,3920, 8,16,56,16,40,0x94,0,2,"Canon","IXUS 160" },
8388 { 1976352,1632,1211, 0, 2, 0, 1, 0,0x94,0,1,"Casio","QV-2000UX" },
8389 { 3217760,2080,1547, 0, 0,10, 1, 0,0x94,0,1,"Casio","QV-3*00EX" },
8390 { 6218368,2585,1924, 0, 0, 9, 0, 0,0x94,0,1,"Casio","QV-5700" },
8391 { 7816704,2867,2181, 0, 0,34,36, 0,0x16,0,1,"Casio","EX-Z60" },
8392 { 2937856,1621,1208, 0, 0, 1, 0, 0,0x94,7,13,"Casio","EX-S20" },
8393 { 4948608,2090,1578, 0, 0,32,34, 0,0x94,7,1,"Casio","EX-S100" },
8394 { 6054400,2346,1720, 2, 0,32, 0, 0,0x94,7,1,"Casio","QV-R41" },
8395 { 7426656,2568,1928, 0, 0, 0, 0, 0,0x94,0,1,"Casio","EX-P505" },
8396 { 7530816,2602,1929, 0, 0,22, 0, 0,0x94,7,1,"Casio","QV-R51" },
8397 { 7542528,2602,1932, 0, 0,32, 0, 0,0x94,7,1,"Casio","EX-Z50" },
8398 { 7562048,2602,1937, 0, 0,25, 0, 0,0x16,7,1,"Casio","EX-Z500" },
8399 { 7753344,2602,1986, 0, 0,32,26, 0,0x94,7,1,"Casio","EX-Z55" },
8400 { 9313536,2858,2172, 0, 0,14,30, 0,0x94,7,1,"Casio","EX-P600" },
8401 { 10834368,3114,2319, 0, 0,27, 0, 0,0x94,0,1,"Casio","EX-Z750" },
8402 { 10843712,3114,2321, 0, 0,25, 0, 0,0x94,0,1,"Casio","EX-Z75" },
8403 { 10979200,3114,2350, 0, 0,32,32, 0,0x94,7,1,"Casio","EX-P700" },
8404 { 12310144,3285,2498, 0, 0, 6,30, 0,0x94,0,1,"Casio","EX-Z850" },
8405 { 12489984,3328,2502, 0, 0,47,35, 0,0x94,0,1,"Casio","EX-Z8" },
8406 { 15499264,3754,2752, 0, 0,82, 0, 0,0x94,0,1,"Casio","EX-Z1050" },
8407 { 18702336,4096,3044, 0, 0,24, 0,80,0x94,7,1,"Casio","EX-ZR100" },
8408 { 7684000,2260,1700, 0, 0, 0, 0,13,0x94,0,1,"Casio","QV-4000" },
8409 { 787456,1024, 769, 0, 1, 0, 0, 0,0x49,0,0,"Creative","PC-CAM 600" },
8410 { 28829184,4384,3288, 0, 0, 0, 0,36,0x61,0,0,"DJI" },
8411 { 15151104,4608,3288, 0, 0, 0, 0, 0,0x94,0,0,"Matrix" },
8412 { 3840000,1600,1200, 0, 0, 0, 0,65,0x49,0,0,"Foculus","531C" },
8413 { 307200, 640, 480, 0, 0, 0, 0, 0,0x94,0,0,"Generic" },
8414 { 62464, 256, 244, 1, 1, 6, 1, 0,0x8d,0,0,"Kodak","DC20" },
8415 { 124928, 512, 244, 1, 1,10, 1, 0,0x8d,0,0,"Kodak","DC20" },
8416 { 1652736,1536,1076, 0,52, 0, 0, 0,0x61,0,0,"Kodak","DCS200" },
8417 { 4159302,2338,1779, 1,33, 1, 2, 0,0x94,0,0,"Kodak","C330" },
8418 { 4162462,2338,1779, 1,33, 1, 2, 0,0x94,0,0,"Kodak","C330",3160 },
8419 { 2247168,1232, 912, 0, 0,16, 0, 0,0x00,0,0,"Kodak","C330" },
8420 { 3370752,1232, 912, 0, 0,16, 0, 0,0x00,0,0,"Kodak","C330" },
8421 { 6163328,2864,2152, 0, 0, 0, 0, 0,0x94,0,0,"Kodak","C603" },
8422 { 6166488,2864,2152, 0, 0, 0, 0, 0,0x94,0,0,"Kodak","C603",3160 },
8423 { 460800, 640, 480, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","C603" },
8424 { 9116448,2848,2134, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","C603" },
8425 { 12241200,4040,3030, 2, 0, 0,13, 0,0x49,0,0,"Kodak","12MP" },
8426 { 12272756,4040,3030, 2, 0, 0,13, 0,0x49,0,0,"Kodak","12MP",31556 },
8427 { 18000000,4000,3000, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","12MP" },
8428 { 614400, 640, 480, 0, 3, 0, 0,64,0x94,0,0,"Kodak","KAI-0340" },
8429 { 15360000,3200,2400, 0, 0, 0, 0,96,0x16,0,0,"Lenovo","A820" },
8430 { 3884928,1608,1207, 0, 0, 0, 0,96,0x16,0,0,"Micron","2010",3212 },
8431 { 1138688,1534, 986, 0, 0, 0, 0, 0,0x61,0,0,"Minolta","RD175",513 },
8432 { 1581060,1305, 969, 0, 0,18, 6, 6,0x1e,4,1,"Nikon","E900" },
8433 { 2465792,1638,1204, 0, 0,22, 1, 6,0x4b,5,1,"Nikon","E950" },
8434 { 2940928,1616,1213, 0, 0, 0, 7,30,0x94,0,1,"Nikon","E2100" },
8435 { 4771840,2064,1541, 0, 0, 0, 1, 6,0xe1,0,1,"Nikon","E990" },
8436 { 4775936,2064,1542, 0, 0, 0, 0,30,0x94,0,1,"Nikon","E3700" },
8437 { 5865472,2288,1709, 0, 0, 0, 1, 6,0xb4,0,1,"Nikon","E4500" },
8438 { 5869568,2288,1710, 0, 0, 0, 0, 6,0x16,0,1,"Nikon","E4300" },
8439 { 7438336,2576,1925, 0, 0, 0, 1, 6,0xb4,0,1,"Nikon","E5000" },
8440 { 8998912,2832,2118, 0, 0, 0, 0,30,0x94,7,1,"Nikon","COOLPIX S6" },
8441 { 5939200,2304,1718, 0, 0, 0, 0,30,0x16,0,0,"Olympus","C770UZ" },
8442 { 3178560,2064,1540, 0, 0, 0, 0, 0,0x94,0,1,"Pentax","Optio S" },
8443 { 4841984,2090,1544, 0, 0,22, 0, 0,0x94,7,1,"Pentax","Optio S" },
8444 { 6114240,2346,1737, 0, 0,22, 0, 0,0x94,7,1,"Pentax","Optio S4" },
8445 { 10702848,3072,2322, 0, 0, 0,21,30,0x94,0,1,"Pentax","Optio 750Z" },
8446 { 4147200,1920,1080, 0, 0, 0, 0, 0,0x49,0,0,"Photron","BC2-HD" },
8447 { 4151666,1920,1080, 0, 0, 0, 0, 0,0x49,0,0,"Photron","BC2-HD",8 },
8448 { 13248000,2208,3000, 0, 0, 0, 0,13,0x61,0,0,"Pixelink","A782" },
8449 { 6291456,2048,1536, 0, 0, 0, 0,96,0x61,0,0,"RoverShot","3320AF" },
8450 { 311696, 644, 484, 0, 0, 0, 0, 0,0x16,0,8,"ST Micro","STV680 VGA" },
8451 { 16098048,3288,2448, 0, 0,24, 0, 9,0x94,0,1,"Samsung","S85" },
8452 { 16215552,3312,2448, 0, 0,48, 0, 9,0x94,0,1,"Samsung","S85" },
8453 { 20487168,3648,2808, 0, 0, 0, 0,13,0x94,5,1,"Samsung","WB550" },
8454 { 24000000,4000,3000, 0, 0, 0, 0,13,0x94,5,1,"Samsung","WB550" },
8455 { 12582980,3072,2048, 0, 0, 0, 0,33,0x61,0,0,"Sinar","",68 },
8456 { 33292868,4080,4080, 0, 0, 0, 0,33,0x61,0,0,"Sinar","",68 },
8457 { 44390468,4080,5440, 0, 0, 0, 0,33,0x61,0,0,"Sinar","",68 },
8458 { 1409024,1376,1024, 0, 0, 1, 0, 0,0x49,0,0,"Sony","XCD-SX910CR" },
8459 { 2818048,1376,1024, 0, 0, 1, 0,97,0x49,0,0,"Sony","XCD-SX910CR" },
8461 static const char *corp[] =
8462 { "AgfaPhoto", "Canon", "Casio", "Epson", "Fujifilm",
8463 "Mamiya", "Minolta", "Motorola", "Kodak", "Konica", "Leica",
8464 "Nikon", "Nokia", "Olympus", "Ricoh", "Pentax", "Phase One",
8465 "Samsung", "Sigma", "Sinar", "Sony" };
8467 int hlen, flen, fsize, zero_fsize=1, i, c;
8470 tiff_flip = flip = filters = UINT_MAX; /* unknown */
8471 raw_height = raw_width = fuji_width = fuji_layout = cr2_slice[0] = 0;
8472 maximum = height = width = top_margin = left_margin = 0;
8473 cdesc[0] = desc[0] = artist[0] = make[0] = model[0] = model2[0] = 0;
8474 iso_speed = shutter = aperture = focal_len = unique_id = 0;
8476 memset (tiff_ifd, 0, sizeof tiff_ifd);
8477 memset (gpsdata, 0, sizeof gpsdata);
8478 memset (cblack, 0, sizeof cblack);
8479 memset (white, 0, sizeof white);
8480 memset (mask, 0, sizeof mask);
8481 thumb_offset = thumb_length = thumb_width = thumb_height = 0;
8482 load_raw = thumb_load_raw = 0;
8483 write_thumb = &CLASS jpeg_thumb;
8484 data_offset = meta_offset = meta_length = tiff_bps = tiff_compress = 0;
8485 kodak_cbpp = zero_after_ff = dng_version = load_flags = 0;
8486 timestamp = shot_order = tiff_samples = black = is_foveon = 0;
8487 mix_green = profile_length = data_error = zero_is_bad = 0;
8488 pixel_aspect = is_raw = raw_color = 1;
8489 tile_width = tile_length = 0;
8490 for (i=0; i < 4; i++) {
8491 cam_mul[i] = i == 1;
8493 FORC3 cmatrix[c][i] = 0;
8494 FORC3 rgb_cam[c][i] = c == i;
8497 for (i=0; i < 0x10000; i++) curve[i] = i;
8501 fseek (ifp, 0, SEEK_SET);
8502 fread (head, 1, 32, ifp);
8503 fseek (ifp, 0, SEEK_END);
8504 flen = fsize = ftell(ifp);
8505 if ((cp = (char *) memmem (head, 32, "MMMM", 4)) ||
8506 (cp = (char *) memmem (head, 32, "IIII", 4))) {
8507 parse_phase_one (cp-head);
8508 if (cp-head && parse_tiff(0)) apply_tiff();
8509 } else if (order == 0x4949 || order == 0x4d4d) {
8510 if (!memcmp (head+6,"HEAPCCDR",8)) {
8512 parse_ciff (hlen, flen-hlen, 0);
8513 load_raw = &CLASS canon_load_raw;
8514 } else if (parse_tiff(0)) apply_tiff();
8515 } else if (!memcmp (head,"\xff\xd8\xff\xe1",4) &&
8516 !memcmp (head+6,"Exif",4)) {
8517 fseek (ifp, 4, SEEK_SET);
8518 data_offset = 4 + get2();
8519 fseek (ifp, data_offset, SEEK_SET);
8520 if (fgetc(ifp) != 0xff)
8523 } else if (!memcmp (head+25,"ARECOYK",7)) {
8524 strcpy (make, "Contax");
8525 strcpy (model,"N Digital");
8526 fseek (ifp, 33, SEEK_SET);
8528 fseek (ifp, 60, SEEK_SET);
8529 FORC4 cam_mul[c ^ (c >> 1)] = get4();
8530 } else if (!strcmp (head, "PXN")) {
8531 strcpy (make, "Logitech");
8532 strcpy (model,"Fotoman Pixtura");
8533 } else if (!strcmp (head, "qktk")) {
8534 strcpy (make, "Apple");
8535 strcpy (model,"QuickTake 100");
8536 load_raw = &CLASS quicktake_100_load_raw;
8537 } else if (!strcmp (head, "qktn")) {
8538 strcpy (make, "Apple");
8539 strcpy (model,"QuickTake 150");
8540 load_raw = &CLASS kodak_radc_load_raw;
8541 } else if (!memcmp (head,"FUJIFILM",8)) {
8542 fseek (ifp, 84, SEEK_SET);
8543 thumb_offset = get4();
8544 thumb_length = get4();
8545 fseek (ifp, 92, SEEK_SET);
8546 parse_fuji (get4());
8547 if (thumb_offset > 120) {
8548 fseek (ifp, 120, SEEK_SET);
8549 is_raw += (i = get4()) && 1;
8550 if (is_raw == 2 && shot_select)
8553 load_raw = &CLASS unpacked_load_raw;
8554 fseek (ifp, 100+28*(shot_select > 0), SEEK_SET);
8555 parse_tiff (data_offset = get4());
8556 parse_tiff (thumb_offset+12);
8558 } else if (!memcmp (head,"RIFF",4)) {
8559 fseek (ifp, 0, SEEK_SET);
8561 } else if (!memcmp (head+4,"ftypqt ",9)) {
8562 fseek (ifp, 0, SEEK_SET);
8565 } else if (!memcmp (head,"\0\001\0\001\0@",6)) {
8566 fseek (ifp, 6, SEEK_SET);
8567 fread (make, 1, 8, ifp);
8568 fread (model, 1, 8, ifp);
8569 fread (model2, 1, 16, ifp);
8570 data_offset = get2();
8573 raw_height = get2();
8574 load_raw = &CLASS nokia_load_raw;
8575 filters = 0x61616161;
8576 } else if (!memcmp (head,"NOKIARAW",8)) {
8577 strcpy (make, "NOKIA");
8579 fseek (ifp, 300, SEEK_SET);
8580 data_offset = get4();
8584 switch (tiff_bps = i*8 / (width * height)) {
8585 case 8: load_raw = &CLASS eight_bit_load_raw; break;
8586 case 10: load_raw = &CLASS nokia_load_raw;
8588 raw_height = height + (top_margin = i / (width * tiff_bps/8) - height);
8590 filters = 0x61616161;
8591 } else if (!memcmp (head,"ARRI",4)) {
8593 fseek (ifp, 20, SEEK_SET);
8596 strcpy (make, "ARRI");
8597 fseek (ifp, 668, SEEK_SET);
8598 fread (model, 1, 64, ifp);
8600 load_raw = &CLASS packed_load_raw;
8602 filters = 0x61616161;
8603 } else if (!memcmp (head,"XPDS",4)) {
8605 fseek (ifp, 0x800, SEEK_SET);
8606 fread (make, 1, 41, ifp);
8607 raw_height = get2();
8609 fseek (ifp, 56, SEEK_CUR);
8610 fread (model, 1, 30, ifp);
8611 data_offset = 0x10000;
8612 load_raw = &CLASS canon_rmf_load_raw;
8613 gamma_curve (0, 12.25, 1, 1023);
8614 } else if (!memcmp (head+4,"RED1",4)) {
8615 strcpy (make, "Red");
8616 strcpy (model,"One");
8618 load_raw = &CLASS redcine_load_raw;
8619 gamma_curve (1/2.4, 12.92, 1, 4095);
8620 filters = 0x49494949;
8621 } else if (!memcmp (head,"DSC-Image",9))
8623 else if (!memcmp (head,"PWAD",4))
8625 else if (!memcmp (head,"\0MRM",4))
8627 else if (!memcmp (head,"FOVb",4))
8629 else if (!memcmp (head,"CI",2))
8632 for (zero_fsize=i=0; i < sizeof table / sizeof *table; i++)
8633 if (fsize == table[i].fsize) {
8634 strcpy (make, table[i].make );
8635 strcpy (model, table[i].model);
8636 flip = table[i].flags >> 2;
8637 zero_is_bad = table[i].flags & 2;
8638 if (table[i].flags & 1)
8639 parse_external_jpeg();
8640 data_offset = table[i].offset;
8641 raw_width = table[i].rw;
8642 raw_height = table[i].rh;
8643 left_margin = table[i].lm;
8644 top_margin = table[i].tm;
8645 width = raw_width - left_margin - table[i].rm;
8646 height = raw_height - top_margin - table[i].bm;
8647 filters = 0x1010101 * table[i].cf;
8648 colors = 4 - !((filters & filters >> 1) & 0x5555);
8649 load_flags = table[i].lf;
8650 switch (tiff_bps = (fsize-data_offset)*8 / (raw_width*raw_height)) {
8652 load_raw = &CLASS minolta_rd175_load_raw; break;
8654 load_raw = &CLASS eight_bit_load_raw; break;
8657 load_raw = &CLASS packed_load_raw; break;
8659 order = 0x4949 | 0x404 * (load_flags & 1);
8660 tiff_bps -= load_flags >> 4;
8661 tiff_bps -= load_flags = load_flags >> 1 & 7;
8662 load_raw = &CLASS unpacked_load_raw;
8664 maximum = (1 << tiff_bps) - (1 << table[i].max);
8666 if (zero_fsize) fsize = 0;
8667 if (make[0] == 0) parse_smal (0, flen);
8670 if (!(strncmp(model,"ov",2) && strncmp(model,"RP_OV",5)) &&
8671 !fseek (ifp, -6404096, SEEK_END) &&
8672 fread (head, 1, 32, ifp) && !strcmp(head,"BRCMn")) {
8673 strcpy (make, "OmniVision");
8674 data_offset = ftell(ifp) + 0x8000-32;
8677 load_raw = &CLASS nokia_load_raw;
8678 filters = 0x16161616;
8682 for (i=0; i < sizeof corp / sizeof *corp; i++)
8683 if (strcasestr (make, corp[i])) /* Simplify company names */
8684 strcpy (make, corp[i]);
8685 if ((!strcmp(make,"Kodak") || !strcmp(make,"Leica")) &&
8686 ((cp = strcasestr(model," DIGITAL CAMERA")) ||
8687 (cp = strstr(model,"FILE VERSION"))))
8689 if (!strncasecmp(model,"PENTAX",6))
8690 strcpy (make, "Pentax");
8691 cp = make + strlen(make); /* Remove trailing spaces */
8692 while (*--cp == ' ') *cp = 0;
8693 cp = model + strlen(model);
8694 while (*--cp == ' ') *cp = 0;
8695 i = strlen(make); /* Remove make from model */
8696 if (!strncasecmp (model, make, i) && model[i++] == ' ')
8697 memmove (model, model+i, 64-i);
8698 if (!strncmp (model,"FinePix ",8))
8699 strcpy (model, model+8);
8700 if (!strncmp (model,"Digital Camera ",15))
8701 strcpy (model, model+15);
8702 desc[511] = artist[63] = make[63] = model[63] = model2[63] = 0;
8703 if (!is_raw) goto notraw;
8705 if (!height) height = raw_height;
8706 if (!width) width = raw_width;
8707 if (height == 2624 && width == 3936) /* Pentax K10D and Samsung GX10 */
8708 { height = 2616; width = 3896; }
8709 if (height == 3136 && width == 4864) /* Pentax K20D and Samsung GX20 */
8710 { height = 3124; width = 4688; filters = 0x16161616; }
8711 if (width == 4352 && (!strcmp(model,"K-r") || !strcmp(model,"K-x")))
8712 { width = 4309; filters = 0x16161616; }
8713 if (width >= 4960 && !strncmp(model,"K-5",3))
8714 { left_margin = 10; width = 4950; filters = 0x16161616; }
8715 if (width == 4736 && !strcmp(model,"K-7"))
8716 { height = 3122; width = 4684; filters = 0x16161616; top_margin = 2; }
8717 if (width == 6080 && !strcmp(model,"K-3"))
8718 { left_margin = 4; width = 6040; }
8719 if (width == 7424 && !strcmp(model,"645D"))
8720 { height = 5502; width = 7328; filters = 0x61616161; top_margin = 29;
8722 if (height == 3014 && width == 4096) /* Ricoh GX200 */
8725 if (filters == UINT_MAX) filters = 0;
8726 if (filters) is_raw *= tiff_samples;
8727 else colors = tiff_samples;
8728 switch (tiff_compress) {
8730 case 1: load_raw = &CLASS packed_dng_load_raw; break;
8731 case 7: load_raw = &CLASS lossless_dng_load_raw; break;
8732 case 34892: load_raw = &CLASS lossy_dng_load_raw; break;
8733 default: load_raw = 0;
8737 if (!strcmp(make,"Canon") && !fsize && tiff_bps != 15) {
8739 load_raw = &CLASS lossless_jpeg_load_raw;
8740 for (i=0; i < sizeof canon / sizeof *canon; i++)
8741 if (raw_width == canon[i][0] && raw_height == canon[i][1]) {
8742 width = raw_width - (left_margin = canon[i][2]);
8743 height = raw_height - (top_margin = canon[i][3]);
8744 width -= canon[i][4];
8745 height -= canon[i][5];
8746 mask[0][1] = canon[i][6];
8747 mask[0][3] = -canon[i][7];
8748 mask[1][1] = canon[i][8];
8749 mask[1][3] = -canon[i][9];
8750 if (canon[i][10]) filters = canon[i][10] * 0x01010101;
8752 if ((unique_id | 0x20000) == 0x2720000) {
8757 for (i=0; i < sizeof unique / sizeof *unique; i++)
8758 if (unique_id == 0x80000000 + unique[i].id) {
8759 adobe_coeff ("Canon", unique[i].model);
8760 if (model[4] == 'K' && strlen(model) == 8)
8761 strcpy (model, unique[i].model);
8763 for (i=0; i < sizeof sonique / sizeof *sonique; i++)
8764 if (unique_id == sonique[i].id)
8765 strcpy (model, sonique[i].model);
8766 if (!strcmp(make,"Nikon")) {
8768 load_raw = &CLASS packed_load_raw;
8769 if (model[0] == 'E')
8770 load_flags |= !data_offset << 2 | 2;
8773 /* Set parameters based on camera name (for non-DNG files). */
8775 if (!strcmp(model,"KAI-0340")
8776 && find_green (16, 16, 3840, 5120) < 25) {
8778 top_margin = filters = 0;
8779 strcpy (model,"C603");
8781 if (!strcmp(make,"Sony") && raw_width > 3888)
8782 black = 128 << (tiff_bps - 12);
8784 if (height*2 < width) pixel_aspect = 0.5;
8785 if (height > width) pixel_aspect = 2;
8788 } else if (!strcmp(make,"Canon") && tiff_bps == 15) {
8790 case 3344: width -= 66;
8791 case 3872: width -= 6;
8793 if (height > width) {
8795 SWAP(raw_height,raw_width);
8797 if (width == 7200 && height == 3888) {
8798 raw_width = width = 6480;
8799 raw_height = height = 4320;
8802 tiff_samples = colors = 3;
8803 load_raw = &CLASS canon_sraw_load_raw;
8804 } else if (!strcmp(model,"PowerShot 600")) {
8809 filters = 0xe1e4e1e4;
8810 load_raw = &CLASS canon_600_load_raw;
8811 } else if (!strcmp(model,"PowerShot A5") ||
8812 !strcmp(model,"PowerShot A5 Zoom")) {
8816 pixel_aspect = 256/235.0;
8817 filters = 0x1e4e1e4e;
8819 } else if (!strcmp(model,"PowerShot A50")) {
8823 filters = 0x1b4e4b1e;
8825 } else if (!strcmp(model,"PowerShot Pro70")) {
8828 filters = 0x1e4b4e1b;
8832 load_raw = &CLASS packed_load_raw;
8834 } else if (!strcmp(model,"PowerShot Pro90 IS") ||
8835 !strcmp(model,"PowerShot G1")) {
8837 filters = 0xb4b4b4b4;
8838 } else if (!strcmp(model,"PowerShot A610")) {
8839 if (canon_s2is()) strcpy (model+10, "S2 IS");
8840 } else if (!strcmp(model,"PowerShot SX220 HS")) {
8842 } else if (!strcmp(model,"EOS D2000C")) {
8843 filters = 0x61616161;
8845 } else if (!strcmp(model,"D1")) {
8846 cam_mul[0] *= 256/527.0;
8847 cam_mul[2] *= 256/317.0;
8848 } else if (!strcmp(model,"D1X")) {
8851 } else if (!strcmp(model,"D40X") ||
8852 !strcmp(model,"D60") ||
8853 !strcmp(model,"D80") ||
8854 !strcmp(model,"D3000")) {
8857 } else if (!strcmp(model,"D3") ||
8858 !strcmp(model,"D3S") ||
8859 !strcmp(model,"D700")) {
8862 } else if (!strcmp(model,"D3100")) {
8865 } else if (!strcmp(model,"D5000") ||
8866 !strcmp(model,"D90")) {
8868 } else if (!strcmp(model,"D5100") ||
8869 !strcmp(model,"D7000") ||
8870 !strcmp(model,"COOLPIX A")) {
8872 } else if (!strcmp(model,"D3200") ||
8873 !strncmp(model,"D6",2) ||
8874 !strncmp(model,"D800",4)) {
8876 } else if (!strcmp(model,"D4") ||
8877 !strcmp(model,"Df")) {
8880 } else if (!strncmp(model,"D40",3) ||
8881 !strncmp(model,"D50",3) ||
8882 !strncmp(model,"D70",3)) {
8884 } else if (!strcmp(model,"D100")) {
8886 raw_width = (width += 3) + 3;
8887 } else if (!strcmp(model,"D200")) {
8890 filters = 0x94949494;
8891 } else if (!strncmp(model,"D2H",3)) {
8894 } else if (!strncmp(model,"D2X",3)) {
8895 if (width == 3264) width -= 32;
8897 } else if (!strncmp(model,"D300",4)) {
8899 } else if (!strncmp(model,"COOLPIX P",9) && raw_width != 4032) {
8901 filters = 0x94949494;
8902 if (model[9] == '7' && iso_speed >= 400)
8904 } else if (!strncmp(model,"1 ",2)) {
8906 } else if (fsize == 1581060) {
8908 pre_mul[0] = 1.2085;
8909 pre_mul[1] = 1.0943;
8910 pre_mul[3] = 1.1103;
8911 } else if (fsize == 3178560) {
8914 } else if (fsize == 4771840) {
8915 if (!timestamp && nikon_e995())
8916 strcpy (model, "E995");
8917 if (strcmp(model,"E995")) {
8918 filters = 0xb4b4b4b4;
8924 } else if (fsize == 2940928) {
8925 if (!timestamp && !nikon_e2100())
8926 strcpy (model,"E2500");
8927 if (!strcmp(model,"E2500")) {
8931 filters = 0x4b4b4b4b;
8933 } else if (fsize == 4775936) {
8934 if (!timestamp) nikon_3700();
8935 if (model[0] == 'E' && atoi(model+1) < 3700)
8936 filters = 0x49494949;
8937 if (!strcmp(model,"Optio 33WR")) {
8939 filters = 0x16161616;
8941 if (make[0] == 'O') {
8942 i = find_green (12, 32, 1188864, 3576832);
8943 c = find_green (12, 32, 2383920, 2387016);
8944 if (abs(i) < abs(c)) {
8948 if (i < 0) filters = 0x61616161;
8950 } else if (fsize == 5869568) {
8951 if (!timestamp && minolta_z2()) {
8952 strcpy (make, "Minolta");
8953 strcpy (model,"DiMAGE Z2");
8955 load_flags = 6 + 24*(make[0] == 'M');
8956 } else if (fsize == 6291456) {
8957 fseek (ifp, 0x300000, SEEK_SET);
8958 if ((order = guess_byte_order(0x10000)) == 0x4d4d) {
8959 height -= (top_margin = 16);
8960 width -= (left_margin = 28);
8962 strcpy (make, "ISG");
8965 } else if (!strcmp(make,"Fujifilm")) {
8966 if (!strcmp(model+7,"S2Pro")) {
8967 strcpy (model,"S2Pro");
8971 } else if (load_raw != &CLASS packed_load_raw)
8972 maximum = (is_raw == 2 && shot_select) ? 0x2f00 : 0x3e00;
8973 top_margin = (raw_height - height) >> 2 << 1;
8974 left_margin = (raw_width - width ) >> 2 << 1;
8975 if (width == 2848 || width == 3664) filters = 0x16161616;
8976 if (width == 4032 || width == 4952 || width == 6032) left_margin = 0;
8977 if (width == 3328 && (width -= 66)) left_margin = 34;
8978 if (width == 4936) left_margin = 4;
8979 if (!strcmp(model,"HS50EXR") ||
8980 !strcmp(model,"F900EXR")) {
8983 filters = 0x16161616;
8985 if (fuji_layout) raw_width *= is_raw;
8987 FORC(36) ((char *)xtrans)[c] =
8988 xtrans_abs[(c/6+top_margin) % 6][(c+left_margin) % 6];
8989 } else if (!strcmp(model,"KD-400Z")) {
8994 } else if (!strcmp(model,"KD-510Z")) {
8996 } else if (!strcasecmp(make,"Minolta")) {
8997 if (!load_raw && (maximum = 0xfff))
8998 load_raw = &CLASS unpacked_load_raw;
8999 if (!strncmp(model,"DiMAGE A",8)) {
9000 if (!strcmp(model,"DiMAGE A200"))
9001 filters = 0x49494949;
9003 load_raw = &CLASS packed_load_raw;
9004 } else if (!strncmp(model,"ALPHA",5) ||
9005 !strncmp(model,"DYNAX",5) ||
9006 !strncmp(model,"MAXXUM",6)) {
9007 sprintf (model+20, "DYNAX %-10s", model+6+(model[0]=='M'));
9008 adobe_coeff (make, model+20);
9009 load_raw = &CLASS packed_load_raw;
9010 } else if (!strncmp(model,"DiMAGE G",8)) {
9011 if (model[8] == '4') {
9014 } else if (model[8] == '5') {
9019 } else if (model[8] == '6') {
9024 filters = 0x61616161;
9026 load_raw = &CLASS unpacked_load_raw;
9030 } else if (!strcmp(model,"*ist D")) {
9031 load_raw = &CLASS unpacked_load_raw;
9033 } else if (!strcmp(model,"*ist DS")) {
9035 } else if (!strcmp(make,"Samsung") && raw_width == 4704) {
9036 height -= top_margin = 8;
9037 width -= 2 * (left_margin = 8);
9039 } else if (!strcmp(make,"Samsung") && raw_height == 3714) {
9040 height -= top_margin = 18;
9041 left_margin = raw_width - (width = 5536);
9042 if (raw_width != 5600)
9043 left_margin = top_margin = 0;
9044 filters = 0x61616161;
9046 } else if (!strcmp(make,"Samsung") && raw_width == 5632) {
9050 width = 5574 - (left_margin = 32 + tiff_bps);
9051 if (tiff_bps == 12) load_flags = 80;
9052 } else if (!strcmp(make,"Samsung") && raw_width == 5664) {
9053 height -= top_margin = 17;
9056 filters = 0x49494949;
9057 } else if (!strcmp(make,"Samsung") && raw_width == 6496) {
9058 filters = 0x61616161;
9059 black = 1 << (tiff_bps - 7);
9060 } else if (!strcmp(model,"EX1")) {
9064 if ((width -= 6) > 3682) {
9069 } else if (!strcmp(model,"WB2000")) {
9073 if ((width -= 10) > 3718) {
9078 } else if (strstr(model,"WB550")) {
9079 strcpy (model, "WB550");
9080 } else if (!strcmp(model,"EX2F")) {
9085 filters = 0x49494949;
9086 load_raw = &CLASS unpacked_load_raw;
9087 } else if (!strcmp(model,"STV680 VGA")) {
9089 } else if (!strcmp(model,"N95")) {
9090 height = raw_height - (top_margin = 2);
9091 } else if (!strcmp(model,"640x480")) {
9092 gamma_curve (0.45, 4.5, 1, 255);
9093 } else if (!strcmp(make,"Hasselblad")) {
9094 if (load_raw == &CLASS lossless_jpeg_load_raw)
9095 load_raw = &CLASS hasselblad_load_raw;
9096 if (raw_width == 7262) {
9101 filters = 0x61616161;
9102 } else if (raw_width == 7410 || raw_width == 8282) {
9107 filters = 0x61616161;
9108 } else if (raw_width == 9044) {
9113 black += load_flags = 256;
9115 } else if (raw_width == 4090) {
9116 strcpy (model, "V96C");
9117 height -= (top_margin = 6);
9118 width -= (left_margin = 3) + 7;
9119 filters = 0x61616161;
9121 if (tiff_samples > 1) {
9122 is_raw = tiff_samples+1;
9123 if (!shot_select && !half_size) filters = 0;
9125 } else if (!strcmp(make,"Sinar")) {
9126 if (!load_raw) load_raw = &CLASS unpacked_load_raw;
9127 if (is_raw > 1 && !shot_select && !half_size) filters = 0;
9129 } else if (!strcmp(make,"Leaf")) {
9131 fseek (ifp, data_offset, SEEK_SET);
9132 if (ljpeg_start (&jh, 1) && jh.bits == 15)
9134 if (tiff_samples > 1) filters = 0;
9135 if (tiff_samples > 1 || tile_length < raw_height) {
9136 load_raw = &CLASS leaf_hdr_load_raw;
9137 raw_width = tile_width;
9139 if ((width | height) == 2048) {
9140 if (tiff_samples == 1) {
9142 strcpy (cdesc, "RBTG");
9143 strcpy (model, "CatchLight");
9144 top_margin = 8; left_margin = 18; height = 2032; width = 2016;
9146 strcpy (model, "DCB2");
9147 top_margin = 10; left_margin = 16; height = 2028; width = 2022;
9149 } else if (width+height == 3144+2060) {
9150 if (!model[0]) strcpy (model, "Cantare");
9151 if (width > height) {
9152 top_margin = 6; left_margin = 32; height = 2048; width = 3072;
9153 filters = 0x61616161;
9155 left_margin = 6; top_margin = 32; width = 2048; height = 3072;
9156 filters = 0x16161616;
9158 if (!cam_mul[0] || model[0] == 'V') filters = 0;
9159 else is_raw = tiff_samples;
9160 } else if (width == 2116) {
9161 strcpy (model, "Valeo 6");
9162 height -= 2 * (top_margin = 30);
9163 width -= 2 * (left_margin = 55);
9164 filters = 0x49494949;
9165 } else if (width == 3171) {
9166 strcpy (model, "Valeo 6");
9167 height -= 2 * (top_margin = 24);
9168 width -= 2 * (left_margin = 24);
9169 filters = 0x16161616;
9171 } else if (!strcmp(make,"Leica") || !strcmp(make,"Panasonic")) {
9172 if ((flen - data_offset) / (raw_width*8/7) == raw_height)
9173 load_raw = &CLASS panasonic_load_raw;
9175 load_raw = &CLASS unpacked_load_raw;
9179 if ((height += 12) > raw_height) height = raw_height;
9180 for (i=0; i < sizeof pana / sizeof *pana; i++)
9181 if (raw_width == pana[i][0] && raw_height == pana[i][1]) {
9182 left_margin = pana[i][2];
9183 top_margin = pana[i][3];
9184 width += pana[i][4];
9185 height += pana[i][5];
9187 filters = 0x01010101 * (uchar) "\x94\x61\x49\x16"
9188 [((filters-1) ^ (left_margin & 1) ^ (top_margin << 1)) & 3];
9189 } else if (!strcmp(model,"C770UZ")) {
9192 filters = 0x16161616;
9193 load_raw = &CLASS packed_load_raw;
9195 } else if (!strcmp(make,"Olympus")) {
9196 height += height & 1;
9197 if (exif_cfa) filters = exif_cfa;
9198 if (width == 4100) width -= 4;
9199 if (width == 4080) width -= 24;
9200 if (width == 9280) { width -= 6; height -= 6; }
9201 if (load_raw == &CLASS unpacked_load_raw)
9204 if (!strcmp(model,"E-300") ||
9205 !strcmp(model,"E-500")) {
9207 if (load_raw == &CLASS unpacked_load_raw) {
9209 memset (cblack, 0, sizeof cblack);
9211 } else if (!strcmp(model,"E-330")) {
9213 if (load_raw == &CLASS unpacked_load_raw)
9215 } else if (!strcmp(model,"SP550UZ")) {
9216 thumb_length = flen - (thumb_offset = 0xa39800);
9219 } else if (!strcmp(model,"TG-4")) {
9222 } else if (!strcmp(model,"N Digital")) {
9225 filters = 0x61616161;
9226 data_offset = 0x1a00;
9227 load_raw = &CLASS packed_load_raw;
9228 } else if (!strcmp(model,"DSC-F828")) {
9232 data_offset = 862144;
9233 load_raw = &CLASS sony_load_raw;
9234 filters = 0x9c9c9c9c;
9236 strcpy (cdesc, "RGBE");
9237 } else if (!strcmp(model,"DSC-V3")) {
9241 data_offset = 787392;
9242 load_raw = &CLASS sony_load_raw;
9243 } else if (!strcmp(make,"Sony") && raw_width == 3984) {
9246 } else if (!strcmp(make,"Sony") && raw_width == 4288) {
9248 } else if (!strcmp(make,"Sony") && raw_width == 4600) {
9249 if (!strcmp(model,"DSLR-A350"))
9252 } else if (!strcmp(make,"Sony") && raw_width == 4928) {
9253 if (height < 3280) width -= 8;
9254 } else if (!strcmp(make,"Sony") && raw_width == 5504) {
9255 width -= height > 3664 ? 8 : 32;
9256 if (!strncmp(model,"DSC",3))
9257 black = 200 << (tiff_bps - 12);
9258 } else if (!strcmp(make,"Sony") && raw_width == 6048) {
9260 if (strstr(model,"RX1") || strstr(model,"A99"))
9262 } else if (!strcmp(make,"Sony") && raw_width == 7392) {
9264 } else if (!strcmp(make,"Sony") && raw_width == 8000) {
9266 if (!strncmp(model,"DSC",3)) {
9268 load_raw = &CLASS unpacked_load_raw;
9271 } else if (!strcmp(model,"DSLR-A100")) {
9272 if (width == 3880) {
9274 width = ++raw_width;
9281 filters = 0x61616161;
9282 } else if (!strcmp(model,"PIXL")) {
9283 height -= top_margin = 4;
9284 width -= left_margin = 32;
9285 gamma_curve (0, 7, 1, 255);
9286 } else if (!strcmp(model,"C603") || !strcmp(model,"C330")
9287 || !strcmp(model,"12MP")) {
9289 if (filters && data_offset) {
9290 fseek (ifp, data_offset < 4096 ? 168 : 5252, SEEK_SET);
9291 read_shorts (curve, 256);
9292 } else gamma_curve (0, 3.875, 1, 255);
9293 load_raw = filters ? &CLASS eight_bit_load_raw :
9294 strcmp(model,"C330") ? &CLASS kodak_c603_load_raw :
9295 &CLASS kodak_c330_load_raw;
9296 load_flags = tiff_bps > 16;
9298 } else if (!strncasecmp(model,"EasyShare",9)) {
9299 data_offset = data_offset < 0x15000 ? 0x15000 : 0x17000;
9300 load_raw = &CLASS packed_load_raw;
9301 } else if (!strcasecmp(make,"Kodak")) {
9302 if (filters == UINT_MAX) filters = 0x61616161;
9303 if (!strncmp(model,"NC2000",6) ||
9304 !strncmp(model,"EOSDCS",6) ||
9305 !strncmp(model,"DCS4",4)) {
9308 if (model[6] == ' ') model[6] = 0;
9309 if (!strcmp(model,"DCS460A")) goto bw;
9310 } else if (!strcmp(model,"DCS660M")) {
9313 } else if (!strcmp(model,"DCS760M")) {
9317 if (!strcmp(model+4,"20X"))
9318 strcpy (cdesc, "MYCY");
9319 if (strstr(model,"DC25")) {
9320 strcpy (model, "DC25");
9321 data_offset = 15424;
9323 if (!strncmp(model,"DC2",3)) {
9324 raw_height = 2 + (height = 242);
9325 if (flen < 100000) {
9326 raw_width = 256; width = 249;
9327 pixel_aspect = (4.0*height) / (3.0*width);
9329 raw_width = 512; width = 501;
9330 pixel_aspect = (493.0*height) / (373.0*width);
9332 top_margin = left_margin = 1;
9334 filters = 0x8d8d8d8d;
9339 load_raw = &CLASS eight_bit_load_raw;
9340 } else if (!strcmp(model,"40")) {
9341 strcpy (model, "DC40");
9345 load_raw = &CLASS kodak_radc_load_raw;
9347 } else if (strstr(model,"DC50")) {
9348 strcpy (model, "DC50");
9351 data_offset = 19712;
9352 load_raw = &CLASS kodak_radc_load_raw;
9353 } else if (strstr(model,"DC120")) {
9354 strcpy (model, "DC120");
9357 pixel_aspect = height/0.75/width;
9358 load_raw = tiff_compress == 7 ?
9359 &CLASS kodak_jpeg_load_raw : &CLASS kodak_dc120_load_raw;
9360 } else if (!strcmp(model,"DCS200")) {
9363 thumb_offset = 6144;
9365 write_thumb = &CLASS layer_thumb;
9368 } else if (!strcmp(model,"Fotoman Pixtura")) {
9372 load_raw = &CLASS kodak_radc_load_raw;
9373 filters = 0x61616161;
9375 } else if (!strncmp(model,"QuickTake",9)) {
9376 if (head[5]) strcpy (model+10, "200");
9377 fseek (ifp, 544, SEEK_SET);
9380 data_offset = (get4(),get2()) == 30 ? 738:736;
9381 if (height > width) {
9383 fseek (ifp, data_offset-6, SEEK_SET);
9384 flip = ~get2() & 3 ? 5:6;
9386 filters = 0x61616161;
9387 } else if (!strcmp(make,"Rollei") && !load_raw) {
9388 switch (raw_width) {
9401 filters = 0x16161616;
9402 load_raw = &CLASS rollei_load_raw;
9405 sprintf (model, "%dx%d", width, height);
9406 if (filters == UINT_MAX) filters = 0x94949494;
9407 if (thumb_offset && !thumb_height) {
9408 fseek (ifp, thumb_offset, SEEK_SET);
9409 if (ljpeg_start (&jh, 1)) {
9410 thumb_width = jh.wide;
9411 thumb_height = jh.high;
9415 if ((use_camera_matrix & (use_camera_wb || dng_version))
9416 && cmatrix[0][0] > 0.125) {
9417 memcpy (rgb_cam, cmatrix, sizeof cmatrix);
9420 if (raw_color) adobe_coeff (make, model);
9421 if (load_raw == &CLASS kodak_radc_load_raw)
9422 if (raw_color) adobe_coeff ("Apple","Quicktake");
9424 fuji_width = width >> !fuji_layout;
9425 filters = fuji_width & 1 ? 0x94949494 : 0x49494949;
9426 width = (height >> fuji_layout) + fuji_width;
9430 if (raw_height < height) raw_height = height;
9431 if (raw_width < width ) raw_width = width;
9433 if (!tiff_bps) tiff_bps = 12;
9434 if (!maximum) maximum = (1 << tiff_bps) - 1;
9435 if (!load_raw || height < 22 || width < 22 ||
9436 tiff_bps > 16 || tiff_samples > 6 || colors > 4)
9439 if (load_raw == &CLASS redcine_load_raw) {
9440 fprintf (stderr,_("%s: You must link dcraw with %s!!\n"),
9441 ifname, "libjasper");
9446 if (load_raw == &CLASS kodak_jpeg_load_raw ||
9447 load_raw == &CLASS lossy_dng_load_raw) {
9448 fprintf (stderr,_("%s: You must link dcraw with %s!!\n"),
9454 strcpy (cdesc, colors == 3 ? "RGBG":"GMCY");
9455 if (!raw_height) raw_height = height;
9456 if (!raw_width ) raw_width = width;
9457 if (filters > 999 && colors == 3)
9458 filters |= ((filters >> 2 & 0x22222222) |
9459 (filters << 2 & 0x88888888)) & filters << 1;
9461 if (flip == UINT_MAX) flip = tiff_flip;
9462 if (flip == UINT_MAX) flip = 0;
9465 { unsigned flp = flip;
9466 switch ((flp+3600) % 360) {
9467 case 270: flp = 5; break;
9468 case 180: flp = 3; break;
9472 sprintf(info, "%d %d", height, width);
9474 sprintf(info, "%d %d", width, height); }
9478 void CLASS apply_profile (const char *input, const char *output)
9481 cmsHPROFILE hInProfile=0, hOutProfile=0;
9482 cmsHTRANSFORM hTransform;
9486 if (strcmp (input, "embed"))
9487 hInProfile = cmsOpenProfileFromFile (input, "r");
9488 else if (profile_length) {
9489 prof = (char *) malloc (profile_length);
9490 merror (prof, "apply_profile()");
9491 fseek (ifp, profile_offset, SEEK_SET);
9492 fread (prof, 1, profile_length, ifp);
9493 hInProfile = cmsOpenProfileFromMem (prof, profile_length);
9496 fprintf (stderr,_("%s has no embedded profile.\n"), ifname);
9497 if (!hInProfile) return;
9499 hOutProfile = cmsCreate_sRGBProfile();
9500 else if ((fp = fopen (output, "rb"))) {
9501 fread (&size, 4, 1, fp);
9502 fseek (fp, 0, SEEK_SET);
9503 oprof = (unsigned *) malloc (size = ntohl(size));
9504 merror (oprof, "apply_profile()");
9505 fread (oprof, 1, size, fp);
9507 if (!(hOutProfile = cmsOpenProfileFromMem (oprof, size))) {
9512 fprintf (stderr,_("Cannot open file %s!\n"), output);
9513 if (!hOutProfile) goto quit;
9515 fprintf (stderr,_("Applying color profile...\n"));
9516 hTransform = cmsCreateTransform (hInProfile, TYPE_RGBA_16,
9517 hOutProfile, TYPE_RGBA_16, INTENT_PERCEPTUAL, 0);
9518 cmsDoTransform (hTransform, image, image, width*height);
9519 raw_color = 1; /* Don't use rgb_cam with a profile */
9520 cmsDeleteTransform (hTransform);
9521 cmsCloseProfile (hOutProfile);
9523 cmsCloseProfile (hInProfile);
9527 void CLASS convert_to_rgb()
9529 int row, col, c, i, j, k;
9531 float out[3], out_cam[3][4];
9532 double num, inverse[3][3];
9533 static const double xyzd50_srgb[3][3] =
9534 { { 0.436083, 0.385083, 0.143055 },
9535 { 0.222507, 0.716888, 0.060608 },
9536 { 0.013930, 0.097097, 0.714022 } };
9537 static const double rgb_rgb[3][3] =
9538 { { 1,0,0 }, { 0,1,0 }, { 0,0,1 } };
9539 static const double adobe_rgb[3][3] =
9540 { { 0.715146, 0.284856, 0.000000 },
9541 { 0.000000, 1.000000, 0.000000 },
9542 { 0.000000, 0.041166, 0.958839 } };
9543 static const double wide_rgb[3][3] =
9544 { { 0.593087, 0.404710, 0.002206 },
9545 { 0.095413, 0.843149, 0.061439 },
9546 { 0.011621, 0.069091, 0.919288 } };
9547 static const double prophoto_rgb[3][3] =
9548 { { 0.529317, 0.330092, 0.140588 },
9549 { 0.098368, 0.873465, 0.028169 },
9550 { 0.016879, 0.117663, 0.865457 } };
9551 static const double aces_rgb[3][3] =
9552 { { 0.432996, 0.375380, 0.189317 },
9553 { 0.089427, 0.816523, 0.102989 },
9554 { 0.019165, 0.118150, 0.941914 } };
9555 static const double (*out_rgb[])[3] =
9556 { rgb_rgb, adobe_rgb, wide_rgb, prophoto_rgb, xyz_rgb, aces_rgb };
9557 static const char *name[] =
9558 { "sRGB", "Adobe RGB (1998)", "WideGamut D65", "ProPhoto D65", "XYZ", "ACES" };
9559 static const unsigned phead[] =
9560 { 1024, 0, 0x2100000, 0x6d6e7472, 0x52474220, 0x58595a20, 0, 0, 0,
9561 0x61637370, 0, 0, 0x6e6f6e65, 0, 0, 0, 0, 0xf6d6, 0x10000, 0xd32d };
9563 { 10, 0x63707274, 0, 36, /* cprt */
9564 0x64657363, 0, 40, /* desc */
9565 0x77747074, 0, 20, /* wtpt */
9566 0x626b7074, 0, 20, /* bkpt */
9567 0x72545243, 0, 14, /* rTRC */
9568 0x67545243, 0, 14, /* gTRC */
9569 0x62545243, 0, 14, /* bTRC */
9570 0x7258595a, 0, 20, /* rXYZ */
9571 0x6758595a, 0, 20, /* gXYZ */
9572 0x6258595a, 0, 20 }; /* bXYZ */
9573 static const unsigned pwhite[] = { 0xf351, 0x10000, 0x116cc };
9574 unsigned pcurve[] = { 0x63757276, 0, 1, 0x1000000 };
9576 gamma_curve (gamm[0], gamm[1], 0, 0);
9577 memcpy (out_cam, rgb_cam, sizeof out_cam);
9578 raw_color |= colors == 1 || document_mode ||
9579 output_color < 1 || output_color > 6;
9581 oprof = (unsigned *) calloc (phead[0], 1);
9582 merror (oprof, "convert_to_rgb()");
9583 memcpy (oprof, phead, sizeof phead);
9584 if (output_color == 5) oprof[4] = oprof[5];
9585 oprof[0] = 132 + 12*pbody[0];
9586 for (i=0; i < pbody[0]; i++) {
9587 oprof[oprof[0]/4] = i ? (i > 1 ? 0x58595a20 : 0x64657363) : 0x74657874;
9588 pbody[i*3+2] = oprof[0];
9589 oprof[0] += (pbody[i*3+3] + 3) & -4;
9591 memcpy (oprof+32, pbody, sizeof pbody);
9592 oprof[pbody[5]/4+2] = strlen(name[output_color-1]) + 1;
9593 memcpy ((char *)oprof+pbody[8]+8, pwhite, sizeof pwhite);
9594 pcurve[3] = (short)(256/gamm[5]+0.5) << 16;
9595 for (i=4; i < 7; i++)
9596 memcpy ((char *)oprof+pbody[i*3+2], pcurve, sizeof pcurve);
9597 pseudoinverse ((double (*)[3]) out_rgb[output_color-1], inverse, 3);
9598 for (i=0; i < 3; i++)
9599 for (j=0; j < 3; j++) {
9600 for (num = k=0; k < 3; k++)
9601 num += xyzd50_srgb[i][k] * inverse[j][k];
9602 oprof[pbody[j*3+23]/4+i+2] = num * 0x10000 + 0.5;
9604 for (i=0; i < phead[0]/4; i++)
9605 oprof[i] = htonl(oprof[i]);
9606 strcpy ((char *)oprof+pbody[2]+8, "auto-generated by dcraw");
9607 strcpy ((char *)oprof+pbody[5]+12, name[output_color-1]);
9608 for (i=0; i < 3; i++)
9609 for (j=0; j < colors; j++)
9610 for (out_cam[i][j] = k=0; k < 3; k++)
9611 out_cam[i][j] += out_rgb[output_color-1][i][k] * rgb_cam[k][j];
9614 fprintf (stderr, raw_color ? _("Building histograms...\n") :
9615 _("Converting to %s colorspace...\n"), name[output_color-1]);
9617 memset (histogram, 0, sizeof histogram);
9618 for (img=image[0], row=0; row < height; row++)
9619 for (col=0; col < width; col++, img+=4) {
9621 out[0] = out[1] = out[2] = 0;
9623 out[0] += out_cam[0][c] * img[c];
9624 out[1] += out_cam[1][c] * img[c];
9625 out[2] += out_cam[2][c] * img[c];
9627 FORC3 img[c] = CLIP((int) out[c]);
9629 else if (document_mode)
9630 img[0] = img[fcol(row,col)];
9631 FORCC histogram[c][img[c] >> 3]++;
9633 if (colors == 4 && output_color) colors = 3;
9634 if (document_mode && filters) colors = 1;
9637 // Export color matrix to Cinelerra.
9638 // It can't be applied before interpolation.
9640 for(i = 0; i < 3; i++) {
9641 for(j = 0; j < 3; j++)
9642 matrix[k++] = rgb_cam[i][j];
9647 void CLASS fuji_rotate()
9653 ushort wide, high, (*img)[4], (*pix)[4];
9655 if (!fuji_width) return;
9657 fprintf (stderr,_("Rotating image 45 degrees...\n"));
9658 fuji_width = (fuji_width - 1 + shrink) >> shrink;
9660 wide = fuji_width / step;
9661 high = (height - fuji_width) / step;
9662 img = (ushort (*)[4]) calloc (high, wide*sizeof *img);
9663 merror (img, "fuji_rotate()");
9665 for (row=0; row < high; row++)
9666 for (col=0; col < wide; col++) {
9667 ur = r = fuji_width + (row-col)*step;
9668 uc = c = (row+col)*step;
9669 if (ur > height-2 || uc > width-2) continue;
9672 pix = image + ur*width + uc;
9673 for (i=0; i < colors; i++)
9674 img[row*wide+col][i] =
9675 (pix[ 0][i]*(1-fc) + pix[ 1][i]*fc) * (1-fr) +
9676 (pix[width][i]*(1-fc) + pix[width+1][i]*fc) * fr;
9685 void CLASS stretch()
9687 ushort newdim, (*img)[4], *pix0, *pix1;
9691 if (pixel_aspect == 1) return;
9692 if (verbose) fprintf (stderr,_("Stretching the image...\n"));
9693 if (pixel_aspect < 1) {
9694 newdim = height / pixel_aspect + 0.5;
9695 img = (ushort (*)[4]) calloc (width, newdim*sizeof *img);
9696 merror (img, "stretch()");
9697 for (rc=row=0; row < newdim; row++, rc+=pixel_aspect) {
9698 frac = rc - (c = rc);
9699 pix0 = pix1 = image[c*width];
9700 if (c+1 < height) pix1 += width*4;
9701 for (col=0; col < width; col++, pix0+=4, pix1+=4)
9702 FORCC img[row*width+col][c] = pix0[c]*(1-frac) + pix1[c]*frac + 0.5;
9706 newdim = width * pixel_aspect + 0.5;
9707 img = (ushort (*)[4]) calloc (height, newdim*sizeof *img);
9708 merror (img, "stretch()");
9709 for (rc=col=0; col < newdim; col++, rc+=1/pixel_aspect) {
9710 frac = rc - (c = rc);
9711 pix0 = pix1 = image[c];
9712 if (c+1 < width) pix1 += 4;
9713 for (row=0; row < height; row++, pix0+=width*4, pix1+=width*4)
9714 FORCC img[row*newdim+col][c] = pix0[c]*(1-frac) + pix1[c]*frac + 0.5;
9722 int CLASS flip_index (int row, int col)
9724 if (flip & 4) SWAP(row,col);
9725 if (flip & 2) row = iheight - 1 - row;
9726 if (flip & 1) col = iwidth - 1 - col;
9727 return row * iwidth + col;
9733 union { char c[4]; short s[2]; int i; } val;
9737 ushort order, magic;
9740 struct tiff_tag tag[23];
9743 struct tiff_tag exif[4];
9745 struct tiff_tag gpst[10];
9749 char desc[512], make[64], model[64], soft[32], date[20], artist[64];
9752 void CLASS tiff_set (struct tiff_hdr *th, ushort *ntag,
9753 ushort tag, ushort type, int count, int val)
9755 struct tiff_tag *tt;
9758 tt = (struct tiff_tag *)(ntag+1) + (*ntag)++;
9760 if (type == 1 && count <= 4)
9761 FORC(4) tt->val.c[c] = val >> (c << 3);
9762 else if (type == 2) {
9763 count = strnlen((char *)th + val, count-1) + 1;
9765 FORC(4) tt->val.c[c] = ((char *)th)[val+c];
9766 } else if (type == 3 && count <= 2)
9767 FORC(2) tt->val.s[c] = val >> (c << 4);
9773 #define TOFF(ptr) ((char *)(&(ptr)) - (char *)th)
9775 void CLASS tiff_head (struct tiff_hdr *th, int full)
9780 memset (th, 0, sizeof *th);
9781 th->order = htonl(0x4d4d4949) >> 16;
9784 th->rat[0] = th->rat[2] = 300;
9785 th->rat[1] = th->rat[3] = 1;
9786 FORC(6) th->rat[4+c] = 1000000;
9787 th->rat[4] *= shutter;
9788 th->rat[6] *= aperture;
9789 th->rat[8] *= focal_len;
9790 strncpy (th->desc, desc, 512);
9791 strncpy (th->make, make, 64);
9792 strncpy (th->model, model, 64);
9793 strcpy (th->soft, "dcraw v" DCRAW_VERSION);
9794 t = localtime (×tamp);
9795 sprintf (th->date, "%04d:%02d:%02d %02d:%02d:%02d",
9796 t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);
9797 strncpy (th->artist, artist, 64);
9799 tiff_set (th, &th->ntag, 254, 4, 1, 0);
9800 tiff_set (th, &th->ntag, 256, 4, 1, width);
9801 tiff_set (th, &th->ntag, 257, 4, 1, height);
9802 tiff_set (th, &th->ntag, 258, 3, colors, output_bps);
9804 th->tag[th->ntag-1].val.i = TOFF(th->bps);
9805 FORC4 th->bps[c] = output_bps;
9806 tiff_set (th, &th->ntag, 259, 3, 1, 1);
9807 tiff_set (th, &th->ntag, 262, 3, 1, 1 + (colors > 1));
9809 tiff_set (th, &th->ntag, 270, 2, 512, TOFF(th->desc));
9810 tiff_set (th, &th->ntag, 271, 2, 64, TOFF(th->make));
9811 tiff_set (th, &th->ntag, 272, 2, 64, TOFF(th->model));
9813 if (oprof) psize = ntohl(oprof[0]);
9814 tiff_set (th, &th->ntag, 273, 4, 1, sizeof *th + psize);
9815 tiff_set (th, &th->ntag, 277, 3, 1, colors);
9816 tiff_set (th, &th->ntag, 278, 4, 1, height);
9817 tiff_set (th, &th->ntag, 279, 4, 1, height*width*colors*output_bps/8);
9819 tiff_set (th, &th->ntag, 274, 3, 1, "12435867"[flip]-'0');
9820 tiff_set (th, &th->ntag, 282, 5, 1, TOFF(th->rat[0]));
9821 tiff_set (th, &th->ntag, 283, 5, 1, TOFF(th->rat[2]));
9822 tiff_set (th, &th->ntag, 284, 3, 1, 1);
9823 tiff_set (th, &th->ntag, 296, 3, 1, 2);
9824 tiff_set (th, &th->ntag, 305, 2, 32, TOFF(th->soft));
9825 tiff_set (th, &th->ntag, 306, 2, 20, TOFF(th->date));
9826 tiff_set (th, &th->ntag, 315, 2, 64, TOFF(th->artist));
9827 tiff_set (th, &th->ntag, 34665, 4, 1, TOFF(th->nexif));
9828 if (psize) tiff_set (th, &th->ntag, 34675, 7, psize, sizeof *th);
9829 tiff_set (th, &th->nexif, 33434, 5, 1, TOFF(th->rat[4]));
9830 tiff_set (th, &th->nexif, 33437, 5, 1, TOFF(th->rat[6]));
9831 tiff_set (th, &th->nexif, 34855, 3, 1, iso_speed);
9832 tiff_set (th, &th->nexif, 37386, 5, 1, TOFF(th->rat[8]));
9834 tiff_set (th, &th->ntag, 34853, 4, 1, TOFF(th->ngps));
9835 tiff_set (th, &th->ngps, 0, 1, 4, 0x202);
9836 tiff_set (th, &th->ngps, 1, 2, 2, gpsdata[29]);
9837 tiff_set (th, &th->ngps, 2, 5, 3, TOFF(th->gps[0]));
9838 tiff_set (th, &th->ngps, 3, 2, 2, gpsdata[30]);
9839 tiff_set (th, &th->ngps, 4, 5, 3, TOFF(th->gps[6]));
9840 tiff_set (th, &th->ngps, 5, 1, 1, gpsdata[31]);
9841 tiff_set (th, &th->ngps, 6, 5, 1, TOFF(th->gps[18]));
9842 tiff_set (th, &th->ngps, 7, 5, 3, TOFF(th->gps[12]));
9843 tiff_set (th, &th->ngps, 18, 2, 12, TOFF(th->gps[20]));
9844 tiff_set (th, &th->ngps, 29, 2, 12, TOFF(th->gps[23]));
9845 memcpy (th->gps, gpsdata, sizeof th->gps);
9849 void CLASS jpeg_thumb()
9855 thumb = (char *) malloc (thumb_length);
9856 merror (thumb, "jpeg_thumb()");
9857 fread (thumb, 1, thumb_length, ifp);
9860 if (strcmp (thumb+6, "Exif")) {
9861 memcpy (exif, "\xff\xe1 Exif\0\0", 10);
9862 exif[1] = htons (8 + sizeof th);
9863 fwrite (exif, 1, sizeof exif, ofp);
9865 fwrite (&th, 1, sizeof th, ofp);
9867 fwrite (thumb+2, 1, thumb_length-2, ofp);
9871 void CLASS write_ppm_tiff()
9876 int c, row, col, soff, rstep, cstep;
9877 int perc, val, total, white=0x2000;
9879 perc = width * height * 0.01; /* 99th percentile white level */
9880 if (fuji_width) perc /= 2;
9881 if (!((highlight & ~2) || no_auto_bright))
9882 for (white=c=0; c < colors; c++) {
9883 for (val=0x2000, total=0; --val > 32; )
9884 if ((total += histogram[c][val]) > perc) break;
9885 if (white < val) white = val;
9887 gamma_curve (gamm[0], gamm[1], 2, (white << 3)/bright);
9890 if (flip & 4) SWAP(height,width);
9891 ppm = (uchar *) calloc (width, colors*output_bps/8);
9892 ppm2 = (ushort *) ppm;
9893 merror (ppm, "write_ppm_tiff()");
9896 fwrite (&th, sizeof th, 1, ofp);
9898 fwrite (oprof, ntohl(oprof[0]), 1, ofp);
9899 } else if (colors > 3)
9901 "P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLTYPE %s\nENDHDR\n",
9902 width, height, colors, (1 << output_bps)-1, cdesc);
9904 fprintf (ofp, "P%d\n%d %d\n%d\n",
9905 colors/2+5, width, height, (1 << output_bps)-1);
9906 soff = flip_index (0, 0);
9907 cstep = flip_index (0, 1) - soff;
9908 rstep = flip_index (1, 0) - flip_index (0, width);
9909 for (row=0; row < height; row++, soff += rstep) {
9910 for (col=0; col < width; col++, soff += cstep)
9911 if (output_bps == 8)
9912 FORCC ppm [col*colors+c] = curve[image[soff][c]] >> 8;
9913 else FORCC ppm2[col*colors+c] = curve[image[soff][c]];
9914 if (output_bps == 16 && !output_tiff && htons(0x55aa) != 0x55aa)
9915 swab (ppm2, ppm2, width*colors*2);
9916 fwrite (ppm, colors*output_bps/8, width, ofp);
9922 void CLASS write_cinelerra()
9924 int c, row, col, soff, cstep, rstep;
9925 float scale = 1. / 0xffff;
9926 iheight = height; iwidth = width;
9927 if( (flip & 4) != 0 ) SWAP(height,width);
9928 soff = flip_index(0, 0);
9929 cstep = flip_index(0, 1) - soff;
9930 rstep = flip_index(1, 0) - flip_index(0, width);
9931 if( document_mode ) {
9932 for( row=0; row<height; ++row, soff += rstep ) {
9933 float *output = data[row];
9934 for( col=0; col<width; ++col, soff += cstep ) {
9935 ushort *pixel = image[soff];
9936 FORC3 *output++ = (float)*pixel++ * scale;
9937 if( alpha ) *output++ = 1.0;
9942 int val, total, white=0x2000;
9943 int perc = width * height * 0.01; /* 99th percentile white level */
9944 if( fuji_width ) perc /= 2;
9945 if( !((highlight & ~2) || no_auto_bright) ) {
9946 for( white=c=0; c < colors; ++c ) {
9947 for( val=0x2000, total=0; --val > 32; )
9948 if( (total += histogram[c][val]) > perc ) break;
9949 if( white < val ) white = val;
9952 gamma_curve(gamm[0], gamm[1], 2, (white << 3)/bright);
9953 for( row=0; row<height; ++row, soff += rstep ) {
9954 float *output = data[row];
9955 for( col=0; col<width; ++col, soff += cstep ) {
9956 ushort *pixel = image[soff];
9957 FORC3 *output++ = (float)curve[*pixel++] * scale;
9958 if( alpha ) *output++ = 1.0;
9965 int CLASS main (int argc, const char **argv)
9967 int arg, status=0, quality, i, c;
9968 int timestamp_only=0, thumbnail_only=0, identify_only=0;
9969 int user_qual=-1, user_black=-1, user_sat=-1, user_flip=-1;
9970 int use_fuji_rotate=1, write_to_stdout=0, read_from_stdin=0;
9971 const char *sp, *bpfile=0, *dark_frame=0, *write_ext;
9972 char opm, opt, *ofname, *cp;
9975 const char *cam_profile=0, *out_profile=0;
9979 reset(); // Globals must be reset
9982 putenv ((char *) "TZ=UTC");
9985 setlocale (LC_CTYPE, "");
9986 setlocale (LC_MESSAGES, "");
9987 bindtextdomain ("dcraw", LOCALEDIR);
9988 textdomain ("dcraw");
9992 printf(_("\nRaw photo decoder \"dcraw\" v%s"), DCRAW_VERSION);
9993 printf(_("\nby Dave Coffin, dcoffin a cybercom o net\n"));
9994 printf(_("\nUsage: %s [OPTION]... [FILE]...\n\n"), argv[0]);
9995 puts(_("-v Print verbose messages"));
9996 puts(_("-c Write image data to standard output"));
9997 puts(_("-e Extract embedded thumbnail image"));
9998 puts(_("-i Identify files without decoding them"));
9999 puts(_("-i -v Identify files and show metadata"));
10000 puts(_("-z Change file dates to camera timestamp"));
10001 puts(_("-w Use camera white balance, if possible"));
10002 puts(_("-a Average the whole image for white balance"));
10003 puts(_("-A <x y w h> Average a grey box for white balance"));
10004 puts(_("-r <r g b g> Set custom white balance"));
10005 puts(_("+M/-M Use/don't use an embedded color matrix"));
10006 puts(_("-C <r b> Correct chromatic aberration"));
10007 puts(_("-P <file> Fix the dead pixels listed in this file"));
10008 puts(_("-K <file> Subtract dark frame (16-bit raw PGM)"));
10009 puts(_("-k <num> Set the darkness level"));
10010 puts(_("-S <num> Set the saturation level"));
10011 puts(_("-n <num> Set threshold for wavelet denoising"));
10012 puts(_("-H [0-9] Highlight mode (0=clip, 1=unclip, 2=blend, 3+=rebuild)"));
10013 puts(_("-t [0-7] Flip image (0=none, 3=180, 5=90CCW, 6=90CW)"));
10014 puts(_("-o [0-6] Output colorspace (raw,sRGB,Adobe,Wide,ProPhoto,XYZ,ACES)"));
10016 puts(_("-o <file> Apply output ICC profile from file"));
10017 puts(_("-p <file> Apply camera ICC profile from file or \"embed\""));
10019 puts(_("-d Document mode (no color, no interpolation)"));
10020 puts(_("-D Document mode without scaling (totally raw)"));
10021 puts(_("-j Don't stretch or rotate raw pixels"));
10022 puts(_("-W Don't automatically brighten the image"));
10023 puts(_("-b <num> Adjust brightness (default = 1.0)"));
10024 puts(_("-g <p ts> Set custom gamma curve (default = 2.222 4.5)"));
10025 puts(_("-q [0-3] Set the interpolation quality"));
10026 puts(_("-h Half-size color image (twice as fast as \"-q 0\")"));
10027 puts(_("-f Interpolate RGGB as four colors"));
10028 puts(_("-m <num> Apply a 3x3 median filter to R-G and B-G"));
10029 puts(_("-s [0..N-1] Select one raw image or \"all\" from each file"));
10030 puts(_("-6 Write 16-bit instead of 8-bit"));
10031 puts(_("-4 Linear 16-bit, same as \"-6 -W -g 1 1\""));
10032 puts(_("-T Write TIFF instead of PPM"));
10037 for (arg=1; (((opm = argv[arg][0]) - 2) | 2) == '+'; ) {
10038 opt = argv[arg++][1];
10039 if ((cp = (char *) strchr (sp="nbrkStqmHACg", opt)))
10040 for (i=0; i < "114111111422"[cp-sp]-'0'; i++)
10041 if (!isdigit(argv[arg+i][0])) {
10042 fprintf (stderr,_("Non-numeric argument to \"-%c\"\n"), opt);
10046 case 'n': threshold = atof(argv[arg++]); break;
10047 case 'b': bright = atof(argv[arg++]); break;
10049 FORC4 user_mul[c] = atof(argv[arg++]); break;
10050 case 'C': aber[0] = 1 / atof(argv[arg++]);
10051 aber[2] = 1 / atof(argv[arg++]); break;
10052 case 'g': gamm[0] = atof(argv[arg++]);
10053 gamm[1] = atof(argv[arg++]);
10054 if (gamm[0]) gamm[0] = 1/gamm[0]; break;
10055 case 'k': user_black = atoi(argv[arg++]); break;
10056 case 'S': user_sat = atoi(argv[arg++]); break;
10057 case 't': user_flip = atoi(argv[arg++]); break;
10058 case 'q': user_qual = atoi(argv[arg++]); break;
10059 case 'm': med_passes = atoi(argv[arg++]); break;
10060 case 'H': highlight = atoi(argv[arg++]); break;
10062 shot_select = abs(atoi(argv[arg]));
10063 multi_out = !strcmp(argv[arg++],"all");
10066 if (isdigit(argv[arg][0]) && !argv[arg][1])
10067 output_color = atoi(argv[arg++]);
10069 else out_profile = argv[arg++];
10071 case 'p': cam_profile = argv[arg++];
10074 case 'P': bpfile = argv[arg++]; break;
10075 case 'K': dark_frame = argv[arg++]; break;
10076 case 'z': timestamp_only = 1; break;
10077 case 'e': thumbnail_only = 1; break;
10078 case 'i': identify_only = 1; break;
10079 case 'c': write_to_stdout = 1; break;
10080 case 'v': verbose = 1; break;
10081 case 'h': half_size = 1; break;
10082 case 'f': four_color_rgb = 1; break;
10083 case 'A': FORC4 greybox[c] = atoi(argv[arg++]);
10084 case 'a': use_auto_wb = 1; break;
10085 case 'w': use_camera_wb = 1; break;
10086 case 'M': use_camera_matrix = 3 * (opm == '+'); break;
10087 case 'I': read_from_stdin = 1; break;
10088 case 'E': document_mode++;
10089 case 'D': document_mode++;
10090 case 'd': document_mode++;
10091 case 'j': use_fuji_rotate = 0; break;
10092 case 'W': no_auto_bright = 1; break;
10093 case 'T': output_tiff = 1; break;
10094 case '4': gamm[0] = gamm[1] =
10095 no_auto_bright = 1;
10096 case '6': output_bps = 16; break;
10098 fprintf (stderr,_("Unknown option \"-%c\".\n"), opt);
10103 fprintf (stderr,_("No files to process.\n"));
10106 if (write_to_stdout) {
10108 if (0 && isatty(1)) {
10109 fprintf (stderr,_("Will not write an image to the terminal!\n"));
10112 #if defined(WIN32) || defined(DJGPP) || defined(__CYGWIN__)
10113 if (setmode(1,O_BINARY) < 0) {
10114 perror ("setmode()");
10119 for ( ; arg < argc; arg++) {
10124 meta_data = ofname = 0;
10126 if (setjmp (failure)) {
10127 if (fileno(ifp) > 2) fclose(ifp);
10128 if (fileno(ofp) > 2) fclose(ofp);
10132 ifname = argv[arg];
10133 if (!(ifp = fopen (ifname, "rb"))) {
10137 status = (identify(),!is_raw);
10138 if (user_flip >= 0)
10140 switch ((flip+3600) % 360) {
10141 case 270: flip = 5; break;
10142 case 180: flip = 3; break;
10145 if (timestamp_only) {
10146 if ((status = !timestamp))
10147 fprintf (stderr,_("%s has no timestamp.\n"), ifname);
10148 else if (identify_only)
10149 printf ("%10ld%10d %s\n", (long) timestamp, shot_order, ifname);
10152 fprintf (stderr,_("%s time set to %d.\n"), ifname, (int) timestamp);
10153 ut.actime = ut.modtime = timestamp;
10154 utime (ifname, &ut);
10159 // write_fun = &CLASS write_ppm_tiff;
10160 write_fun = &CLASS write_cinelerra;
10162 if (thumbnail_only) {
10163 if ((status = !thumb_offset)) {
10164 fprintf (stderr,_("%s has no thumbnail.\n"), ifname);
10166 } else if (thumb_load_raw) {
10167 load_raw = thumb_load_raw;
10168 data_offset = thumb_offset;
10169 height = thumb_height;
10170 width = thumb_width;
10174 fseek (ifp, thumb_offset, SEEK_SET);
10175 write_fun = write_thumb;
10179 if (load_raw == &CLASS kodak_ycbcr_load_raw) {
10180 height += height & 1;
10181 width += width & 1;
10183 if (identify_only && verbose && make[0]) {
10184 printf (_("\nFilename: %s\n"), ifname);
10185 printf (_("Timestamp: %s"), ctime(×tamp));
10186 printf (_("Camera: %s %s\n"), make, model);
10188 printf (_("Owner: %s\n"), artist);
10190 printf (_("DNG Version: "));
10191 for (i=24; i >= 0; i -= 8)
10192 printf ("%d%c", dng_version >> i & 255, i ? '.':'\n');
10194 printf (_("ISO speed: %d\n"), (int) iso_speed);
10195 printf (_("Shutter: "));
10196 if (shutter > 0 && shutter < 1)
10197 shutter = (printf ("1/"), 1 / shutter);
10198 printf (_("%0.1f sec\n"), shutter);
10199 printf (_("Aperture: f/%0.1f\n"), aperture);
10200 printf (_("Focal length: %0.1f mm\n"), focal_len);
10201 printf (_("Embedded ICC profile: %s\n"), profile_length ? _("yes"):_("no"));
10202 printf (_("Number of raw images: %d\n"), is_raw);
10203 if (pixel_aspect != 1)
10204 printf (_("Pixel Aspect Ratio: %0.6f\n"), pixel_aspect);
10206 printf (_("Thumb size: %4d x %d\n"), thumb_width, thumb_height);
10207 printf (_("Full size: %4d x %d\n"), raw_width, raw_height);
10210 // else if (!is_raw)
10211 // fprintf (stderr,_("Cannot decode file %s\n"), ifname);
10212 if (!is_raw) goto next;
10213 shrink = filters && (half_size || (!identify_only &&
10214 (threshold || aber[0] != 1 || aber[2] != 1)));
10215 iheight = (height + shrink) >> shrink;
10216 iwidth = (width + shrink) >> shrink;
10217 if (identify_only) {
10219 if (document_mode == 3) {
10220 top_margin = left_margin = fuji_width = 0;
10221 height = raw_height;
10224 iheight = (height + shrink) >> shrink;
10225 iwidth = (width + shrink) >> shrink;
10226 if (use_fuji_rotate) {
10228 fuji_width = (fuji_width - 1 + shrink) >> shrink;
10229 iwidth = fuji_width / sqrt(0.5);
10230 iheight = (iheight - fuji_width) / sqrt(0.5);
10232 if (pixel_aspect < 1) iheight = iheight / pixel_aspect + 0.5;
10233 if (pixel_aspect > 1) iwidth = iwidth * pixel_aspect + 0.5;
10237 SWAP(iheight,iwidth);
10238 printf (_("Image size: %4d x %d\n"), width, height);
10239 printf (_("Output size: %4d x %d\n"), iwidth, iheight);
10240 printf (_("Raw colors: %d"), colors);
10242 int fhigh = 2, fwide = 2;
10243 if ((filters ^ (filters >> 8)) & 0xff) fhigh = 4;
10244 if ((filters ^ (filters >> 16)) & 0xffff) fhigh = 8;
10245 if (filters == 1) fhigh = fwide = 16;
10246 if (filters == 9) fhigh = fwide = 6;
10247 printf (_("\nFilter pattern: "));
10248 for (i=0; i < fhigh; i++)
10249 for (c = i && putchar('/') && 0; c < fwide; c++)
10250 putchar (cdesc[fcol(i,c)]);
10252 printf (_("\nDaylight multipliers:"));
10253 FORCC printf (" %f", pre_mul[c]);
10254 if (cam_mul[0] > 0) {
10255 printf (_("\nCamera multipliers:"));
10256 FORC4 printf (" %f", cam_mul[c]);
10262 // printf (_("%s is a %s %s image.\n"), ifname, make, model);
10268 meta_data = (char *) malloc (meta_length);
10269 merror (meta_data, "main()");
10271 if (filters || colors == 1) {
10272 raw_image = (ushort *) calloc ((raw_height+7), raw_width*2);
10273 merror (raw_image, "main()");
10275 image = (ushort (*)[4]) calloc (iheight, iwidth*sizeof *image);
10276 merror (image, "main()");
10279 fprintf (stderr,_("Loading %s %s image from %s ...\n"),
10280 make, model, ifname);
10281 if (shot_select >= is_raw)
10282 fprintf (stderr,_("%s: \"-s %d\" requests a nonexistent image!\n"),
10283 ifname, shot_select);
10284 fseeko (ifp, data_offset, SEEK_SET);
10285 if (raw_image && read_from_stdin)
10286 fread (raw_image, 2, raw_height*raw_width, stdin);
10288 (this->*load_raw)();
10289 if (document_mode == 3) {
10290 top_margin = left_margin = fuji_width = 0;
10291 height = raw_height;
10294 iheight = (height + shrink) >> shrink;
10295 iwidth = (width + shrink) >> shrink;
10297 image = (ushort (*)[4]) calloc (iheight, iwidth*sizeof *image);
10298 merror (image, "main()");
10299 crop_masked_pixels();
10302 if (zero_is_bad) remove_zeroes();
10303 bad_pixels (bpfile);
10304 if (dark_frame) subtract (dark_frame);
10305 quality = 2 + !fuji_width;
10306 if (user_qual >= 0) quality = user_qual;
10308 FORC3 if (i > cblack[c]) i = cblack[c];
10309 FORC4 cblack[c] -= i;
10312 FORC (cblack[4] * cblack[5])
10313 if (i > cblack[6+c]) i = cblack[6+c];
10314 FORC (cblack[4] * cblack[5])
10317 if (user_black >= 0) black = user_black;
10318 FORC4 cblack[c] += black;
10319 if (user_sat > 0) maximum = user_sat;
10324 if (document_mode || load_raw == &CLASS foveon_dp_load_raw) {
10325 for (i=0; i < height*width*4; i++)
10326 if ((short) image[0][i] < 0) image[0][i] = 0;
10327 } else foveon_interpolate();
10328 } else if (document_mode < 2)
10331 if (filters && !document_mode) {
10334 else if (quality == 1 || colors > 3)
10336 else if (quality == 2 && filters > 1000)
10338 else if (filters == 9)
10339 xtrans_interpolate (quality*2-3);
10344 for (colors=3, i=0; i < height*width; i++)
10345 image[i][1] = (image[i][1] + image[i][3]) >> 1;
10346 if (!is_foveon && colors == 3) median_filter();
10347 if (!is_foveon && highlight == 2) blend_highlights();
10348 if (!is_foveon && highlight > 2) recover_highlights();
10349 if (use_fuji_rotate) fuji_rotate();
10351 if (cam_profile) apply_profile (cam_profile, out_profile);
10354 if (use_fuji_rotate) stretch();
10356 if (write_fun == &CLASS jpeg_thumb)
10357 write_ext = ".jpg";
10358 else if (output_tiff && write_fun == &CLASS write_ppm_tiff)
10359 write_ext = ".tiff";
10361 write_ext = ".pgm\0.ppm\0.ppm\0.pam" + colors*5-5;
10362 ofname = (char *) malloc (strlen(ifname) + 64);
10363 merror (ofname, "main()");
10364 if (write_to_stdout)
10365 strcpy (ofname,_("standard output"));
10367 strcpy (ofname, ifname);
10368 if ((cp = strrchr (ofname, '.'))) *cp = 0;
10370 sprintf (ofname+strlen(ofname), "_%0*d",
10371 snprintf(0,0,"%d",is_raw-1), shot_select);
10372 if (thumbnail_only)
10373 strcat (ofname, ".thumb");
10374 strcat (ofname, write_ext);
10375 ofp = fopen (ofname, "wb");
10383 fprintf (stderr,_("Writing data to %s ...\n"), ofname);
10384 (this->*write_fun)();
10386 if (ofp != stdout) fclose(ofp);
10388 if (meta_data) free (meta_data);
10389 if (ofname) free (ofname);
10390 if (oprof) free (oprof);
10391 if (image) free (image);
10393 if (++shot_select < is_raw) arg--;
10394 else shot_select = 0;