2 dcraw.c -- Dave Coffin's raw photo decoder
3 Copyright 1997-2018 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: 2018/06/01 20:36:25 $
26 #define DCRAW_VERSION "9.28"
31 #define _USE_MATH_DEFINES
43 #include <sys/types.h>
45 #if defined(DJGPP) || defined(__MINGW32__)
49 #define fgetc getc_unlocked
55 #include <sys/utime.h>
57 #pragma comment(lib, "ws2_32.lib")
58 #define snprintf _snprintf
59 #define strcasecmp stricmp
60 #define strncasecmp strnicmp
61 typedef __int64 INT64;
62 typedef unsigned __int64 UINT64;
66 #include <netinet/in.h>
68 typedef int64_t INT64;
69 typedef uint64_t UINT64;
78 #include <jasper/jasper.h> /* Decode Red camera movies */
81 #include <jpeglib.h> /* Decode compressed Kodak DC120 photos */
82 #endif /* and Adobe Lossy DNGs */
84 #include <lcms2.h> /* Support color profiles */
88 #define _(String) gettext(String)
90 #define _(String) (String)
96 const double DCRaw_data::xyz_rgb[3][3] = { /* XYZ from RGB */
97 { 0.412453, 0.357580, 0.180423 },
98 { 0.212671, 0.715160, 0.072169 },
99 { 0.019334, 0.119193, 0.950227 } };
100 const float DCRaw_data::d65_white[3] = {
101 0.950456, 1.000000, 1.088754 };
104 All global variables are defined here, and all functions that
105 access them are prefixed with "CLASS". For thread-safety, all
106 non-const static local variables except cbrt[] must be declared
110 #define FORC(cnt) for (c=0; c < cnt; c++)
111 #define FORC3 FORC(3)
112 #define FORC4 FORC(4)
113 #define FORCC FORC(colors)
115 #define SQR(x) ((x)*(x))
116 #define ABS(x) (((int)(x) ^ ((int)(x) >> 31)) - ((int)(x) >> 31))
117 #define MIN(a,b) ((a) < (b) ? (a) : (b))
118 #define MAX(a,b) ((a) > (b) ? (a) : (b))
119 #define LIM(x,min,max) MAX(min,MIN(x,max))
120 #define ULIM(x,y,z) ((y) < (z) ? LIM(x,y,z) : LIM(x,z,y))
121 #define CLIP(x) LIM((int)(x),0,65535)
122 #define SWAP(a,b) { a=a+b; b=a-b; a=a-b; }
123 #define ZERO(var) memset(&var, 0, sizeof var)
125 In order to inline this calculation, I make the risky
126 assumption that all filter patterns can be described
127 by a repeating pattern of eight rows and two columns
129 Do not use the FC or BAYER macros with the Leaf CatchLight,
130 because its pattern is 16x16, not 2x8.
132 Return values are either 0/1/2/3 = G/M/C/Y or 0/1/2/3 = R/G1/B/G2
134 PowerShot 600 PowerShot A50 PowerShot Pro70 Pro90 & G1
135 0xe1e4e1e4: 0x1b4e4b1e: 0x1e4b4e1b: 0xb4b4b4b4:
137 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5
138 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
139 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
140 2 M G M G M G 2 Y C Y C Y C 2 C Y C Y C Y
141 3 C Y C Y C Y 3 G M G M G M 3 G M G M G M
142 4 C Y C Y C Y 4 Y C Y C Y C
143 PowerShot A5 5 G M G M G M 5 G M G M G M
144 0x1e4e1e4e: 6 Y C Y C Y C 6 C Y C Y C Y
145 7 M G M G M G 7 M G M G M G
152 All RGB cameras use one of these Bayer grids:
154 0x16161616: 0x61616161: 0x49494949: 0x94949494:
156 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5
157 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
158 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
159 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
160 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
163 #define RAW(row,col) \
164 raw_image[(row)*raw_width+(col)]
166 #define FC(row,col) \
167 (filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)
169 #define BAYER(row,col) \
170 image[((row) >> shrink)*iwidth + ((col) >> shrink)][FC(row,col)]
172 #define BAYER2(row,col) \
173 image[((row) >> shrink)*iwidth + ((col) >> shrink)][fcol(row,col)]
175 int CLASS fcol (int row, int col)
177 static const char filter[16][16] =
178 { { 2,1,1,3,2,3,2,0,3,2,3,0,1,2,1,0 },
179 { 0,3,0,2,0,1,3,1,0,1,1,2,0,3,3,2 },
180 { 2,3,3,2,3,1,1,3,3,1,2,1,2,0,0,3 },
181 { 0,1,0,1,0,2,0,2,2,0,3,0,1,3,2,1 },
182 { 3,1,1,2,0,1,0,2,1,3,1,3,0,1,3,0 },
183 { 2,0,0,3,3,2,3,1,2,0,2,0,3,2,2,1 },
184 { 2,3,3,1,2,1,2,1,2,1,1,2,3,0,0,1 },
185 { 1,0,0,2,3,0,0,3,0,3,0,3,2,1,2,3 },
186 { 2,3,3,1,1,2,1,0,3,2,3,0,2,3,1,3 },
187 { 1,0,2,0,3,0,3,2,0,1,1,2,0,1,0,2 },
188 { 0,1,1,3,3,2,2,1,1,3,3,0,2,1,3,2 },
189 { 2,3,2,0,0,1,3,0,2,0,1,2,3,0,1,0 },
190 { 1,3,1,2,3,2,3,2,0,2,0,1,1,0,3,0 },
191 { 0,2,0,3,1,0,0,1,1,3,3,2,3,2,2,1 },
192 { 2,1,3,2,3,1,2,1,0,3,0,2,0,2,0,2 },
193 { 0,3,1,0,0,2,0,3,2,1,3,1,1,3,1,3 } };
195 if (filters == 1) return filter[(row+top_margin)&15][(col+left_margin)&15];
196 if (filters == 9) return xtrans[(row+6) % 6][(col+6) % 6];
203 DCRaw_data *data = (DCRaw_data *)this;
204 memset(data, 0, sizeof(*data));
205 // non-zero init data
206 aber[0] = aber[1] = aber[2] = aber[3] = 1;
207 gamm[0] = 0.45; gamm[1] = 4.5;
209 use_camera_matrix = 1;
212 greybox[2] = UINT_MAX; greybox[3] = UINT_MAX;
216 char *my_memmem (char *haystack, size_t haystacklen,
217 char *needle, size_t needlelen)
220 for (c = haystack; c <= haystack + haystacklen - needlelen; c++)
221 if (!memcmp (c, needle, needlelen))
225 #define memmem my_memmem
226 char *my_strcasestr (char *haystack, const char *needle)
229 for (c = haystack; *c; c++)
230 if (!strncasecmp(c, needle, strlen(needle)))
234 #define strcasestr my_strcasestr
237 void CLASS merror (void *ptr, const char *where)
240 fprintf (stderr,_("%s: Out of memory in %s\n"), ifname, where);
241 longjmp (failure, 1);
247 fprintf (stderr, "%s: ", ifname);
249 fprintf (stderr,_("Unexpected end of file\n"));
251 fprintf (stderr,_("Corrupt data near 0x%jx\n"), (INT64) ftello(ifp));
256 ushort CLASS sget2 (uchar *s)
258 if (order == 0x4949) /* "II" means little-endian */
259 return s[0] | s[1] << 8;
260 else /* "MM" means big-endian */
261 return s[0] << 8 | s[1];
266 uchar str[2] = { 0xff,0xff };
267 fread (str, 1, 2, ifp);
271 unsigned CLASS sget4 (uchar *s)
274 return s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24;
276 return s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3];
278 #define sget4(s) sget4((uchar *)s)
280 unsigned CLASS get4()
282 uchar str[4] = { 0xff,0xff,0xff,0xff };
283 fread (str, 1, 4, ifp);
287 unsigned CLASS getint (int type)
289 return type == 3 ? get2() : get4();
292 float CLASS int_to_float (int i)
294 union { int i; float f; } u;
299 double CLASS getreal (int type)
301 union { char c[8]; double d; } u;
305 case 3: return (unsigned short) get2();
306 case 4: return (unsigned int) get4();
307 case 5: u.d = (unsigned int) get4();
308 return u.d / (unsigned int) get4();
309 case 8: return (signed short) get2();
310 case 9: return (signed int) get4();
311 case 10: u.d = (signed int) get4();
312 return u.d / (signed int) get4();
313 case 11: return int_to_float (get4());
315 rev = 7 * ((order == 0x4949) == (ntohs(0x1234) == 0x1234));
316 for (i=0; i < 8; i++)
317 u.c[i ^ rev] = fgetc(ifp);
319 default: return fgetc(ifp);
323 static void swabb(const void *bfrom, void *bto, ssize_t n)
325 const char *from = (const char *) bfrom;
326 char *to = (char *) bto;
329 const char b0 = from[--n], b1 = from[--n];
330 to[n] = b0; to[n + 1] = b1;
334 void CLASS read_shorts (ushort *pixel, int count)
336 if (fread (pixel, 2, count, ifp) < count) derror();
337 if ((order == 0x4949) == (ntohs(0x1234) == 0x1234))
338 swabb(pixel, pixel, count*2);
341 void CLASS cubic_spline (const int *x_, const int *y_, const int len)
343 float **A, *b, *c, *d, *x, *y;
346 A = (float **) calloc (((2*len + 4)*sizeof **A + sizeof *A), 2*len);
348 A[0] = (float *) (A + 2*len);
349 for (i = 1; i < 2*len; i++)
350 A[i] = A[0] + 2*len*i;
351 y = len + (x = i + (d = i + (c = i + (b = A[0] + i*i))));
352 for (i = 0; i < len; i++) {
353 x[i] = x_[i] / 65535.0;
354 y[i] = y_[i] / 65535.0;
356 for (i = len-1; i > 0; i--) {
357 b[i] = (y[i] - y[i-1]) / (x[i] - x[i-1]);
358 d[i-1] = x[i] - x[i-1];
360 for (i = 1; i < len-1; i++) {
361 A[i][i] = 2 * (d[i-1] + d[i]);
366 A[i][len-1] = 6 * (b[i+1] - b[i]);
368 for(i = 1; i < len-2; i++) {
369 float v = A[i+1][i] / A[i][i];
370 for(j = 1; j <= len-1; j++)
371 A[i+1][j] -= v * A[i][j];
373 for(i = len-2; i > 0; i--) {
375 for(j = i; j <= len-2; j++)
377 c[i] = (A[i][len-1] - acc) / A[i][i];
379 for (i = 0; i < 0x10000; i++) {
380 float x_out = (float)(i / 65535.0);
382 for (j = 0; j < len-1; j++) {
383 if (x[j] <= x_out && x_out <= x[j+1]) {
384 float v = x_out - x[j];
386 ((y[j+1] - y[j]) / d[j] - (2 * d[j] * c[j] + c[j+1] * d[j])/6) * v
387 + (c[j] * 0.5) * v*v + ((c[j+1] - c[j]) / (6 * d[j])) * v*v*v;
390 curve[i] = y_out < 0.0 ? 0 : (y_out >= 1.0 ? 65535 :
391 (ushort)(y_out * 65535.0 + 0.5));
396 void CLASS canon_600_fixed_wb (int temp)
398 static const short mul[4][5] = {
399 { 667, 358,397,565,452 },
400 { 731, 390,367,499,517 },
401 { 1119, 396,348,448,537 },
402 { 1399, 485,431,508,688 } };
407 if (*mul[lo] <= temp) break;
408 for (hi=0; hi < 3; hi++)
409 if (*mul[hi] >= temp) break;
411 frac = (float) (temp - *mul[lo]) / (*mul[hi] - *mul[lo]);
412 for (i=1; i < 5; i++)
413 pre_mul[i-1] = 1 / (frac * mul[hi][i] + (1-frac) * mul[lo][i]);
416 /* Return values: 0 = white 1 = near white 2 = not white */
417 int CLASS canon_600_color (int ratio[2], int mar)
419 int clipped=0, target, miss;
423 { ratio[1] = -104; clipped = 1; }
425 { ratio[1] = 12; clipped = 1; }
427 if (ratio[1] < -264 || ratio[1] > 461) return 2;
429 { ratio[1] = -50; clipped = 1; }
431 { ratio[1] = 307; clipped = 1; }
433 target = flash_used || ratio[1] < 197
434 ? -38 - (398 * ratio[1] >> 10)
435 : -123 + (48 * ratio[1] >> 10);
436 if (target - mar <= ratio[0] &&
437 target + 20 >= ratio[0] && !clipped) return 0;
438 miss = target - ratio[0];
439 if (abs(miss) >= mar*4) return 2;
440 if (miss < -20) miss = -20;
441 if (miss > mar) miss = mar;
442 ratio[0] = target - miss;
446 void CLASS canon_600_auto_wb()
448 int mar, row, col, i, j, st, count[] = { 0,0 };
449 int test[8], total[2][8], ratio[2][2], stat[2];
451 memset (&total, 0, sizeof total);
453 if (i < 10) mar = 150;
454 else if (i > 12) mar = 20;
455 else mar = 280 - 20 * i;
456 if (flash_used) mar = 80;
457 for (row=14; row < height-14; row+=4)
458 for (col=10; col < width; col+=2) {
459 for (i=0; i < 8; i++)
460 test[(i & 4) + FC(row+(i >> 1),col+(i & 1))] =
461 BAYER(row+(i >> 1),col+(i & 1));
462 for (i=0; i < 8; i++)
463 if (test[i] < 150 || test[i] > 1500) goto next;
464 for (i=0; i < 4; i++)
465 if (abs(test[i] - test[i+4]) > 50) goto next;
466 for (i=0; i < 2; i++) {
467 for (j=0; j < 4; j+=2)
468 ratio[i][j >> 1] = ((test[i*4+j+1]-test[i*4+j]) << 10) / test[i*4+j];
469 stat[i] = canon_600_color (ratio[i], mar);
471 if ((st = stat[0] | stat[1]) > 1) goto next;
472 for (i=0; i < 2; i++)
474 for (j=0; j < 2; j++)
475 test[i*4+j*2+1] = test[i*4+j*2] * (0x400 + ratio[i][j]) >> 10;
476 for (i=0; i < 8; i++)
477 total[st][i] += test[i];
481 if (count[0] | count[1]) {
482 st = count[0]*200 < count[1];
483 for (i=0; i < 4; i++)
484 pre_mul[i] = 1.0 / (total[st][i] + total[st][i+4]);
488 void CLASS canon_600_coeff()
490 static const short table[6][12] = {
491 { -190,702,-1878,2390, 1861,-1349,905,-393, -432,944,2617,-2105 },
492 { -1203,1715,-1136,1648, 1388,-876,267,245, -1641,2153,3921,-3409 },
493 { -615,1127,-1563,2075, 1437,-925,509,3, -756,1268,2519,-2007 },
494 { -190,702,-1886,2398, 2153,-1641,763,-251, -452,964,3040,-2528 },
495 { -190,702,-1878,2390, 1861,-1349,905,-393, -432,944,2617,-2105 },
496 { -807,1319,-1785,2297, 1388,-876,769,-257, -230,742,2067,-1555 } };
500 mc = pre_mul[1] / pre_mul[2];
501 yc = pre_mul[3] / pre_mul[2];
502 if (mc > 1 && mc <= 1.28 && yc < 0.8789) t=1;
503 if (mc > 1.28 && mc <= 2) {
504 if (yc < 0.8789) t=3;
505 else if (yc <= 2) t=4;
508 for (raw_color = i=0; i < 3; i++)
509 FORCC rgb_cam[i][c] = table[t][i*4 + c] / 1024.0;
512 void CLASS canon_600_load_raw()
514 uchar data[1120], *dp;
518 for (irow=row=0; irow < height; irow++) {
519 if (fread (data, 1, 1120, ifp) < 1120) derror();
520 pix = raw_image + row*raw_width;
521 for (dp=data; dp < data+1120; dp+=10, pix+=8) {
522 pix[0] = (dp[0] << 2) + (dp[1] >> 6 );
523 pix[1] = (dp[2] << 2) + (dp[1] >> 4 & 3);
524 pix[2] = (dp[3] << 2) + (dp[1] >> 2 & 3);
525 pix[3] = (dp[4] << 2) + (dp[1] & 3);
526 pix[4] = (dp[5] << 2) + (dp[9] & 3);
527 pix[5] = (dp[6] << 2) + (dp[9] >> 2 & 3);
528 pix[6] = (dp[7] << 2) + (dp[9] >> 4 & 3);
529 pix[7] = (dp[8] << 2) + (dp[9] >> 6 );
531 if ((row+=2) > height) row = 1;
535 void CLASS canon_600_correct()
538 static const short mul[4][2] =
539 { { 1141,1145 }, { 1128,1109 }, { 1178,1149 }, { 1128,1109 } };
541 for (row=0; row < height; row++)
542 for (col=0; col < width; col++) {
543 if ((val = BAYER(row,col) - black) < 0) val = 0;
544 val = val * mul[row & 3][col & 1] >> 9;
545 BAYER(row,col) = val;
547 canon_600_fixed_wb(1311);
550 maximum = (0x3ff - black) * 1109 >> 9;
554 int CLASS canon_s2is()
558 for (row=0; row < 100; row++) {
559 fseek (ifp, row*3340 + 3284, SEEK_SET);
560 if (getc(ifp) > 15) return 1;
565 unsigned CLASS getbithuff (int nbits, ushort *huff)
571 if (nbits > 25) return 0;
573 return gbh_bitbuf = gbh_vbits = gbh_reset = 0;
574 if (nbits == 0 || gbh_vbits < 0) return 0;
575 bitbuf = gbh_bitbuf; vbits = gbh_vbits; reset = gbh_reset;
576 while (!reset && vbits < nbits && (c = fgetc(ifp)) != EOF &&
577 !(reset = zero_after_ff && c == 0xff && fgetc(ifp))) {
578 bitbuf = (bitbuf << 8) + (uchar) c;
581 c = bitbuf << (32-vbits) >> (32-nbits);
583 vbits -= huff[c] >> 8;
587 if (vbits < 0) derror();
588 gbh_bitbuf = bitbuf; gbh_vbits = vbits; gbh_reset = reset;
592 #define getbits(n) getbithuff(n,0)
593 #define gethuff(h) getbithuff(*h,h+1)
596 Construct a decode tree according the specification in *source.
597 The first 16 bytes specify how many codes should be 1-bit, 2-bit
598 3-bit, etc. Bytes after that are the leaf values.
600 For example, if the source is
602 { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0,
603 0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff },
621 ushort * CLASS make_decoder_ref (const uchar **source)
623 int max, len, h, i, j;
627 count = (*source += 16) - 17;
628 for (max=16; max && !count[max]; max--);
629 huff = (ushort *) calloc (1 + (1 << max), sizeof *huff);
630 merror (huff, "make_decoder()");
632 for (h=len=1; len <= max; len++)
633 for (i=0; i < count[len]; i++, ++*source)
634 for (j=0; j < 1 << (max-len); j++)
636 huff[h++] = len << 8 | **source;
640 ushort * CLASS make_decoder (const uchar *source)
642 return make_decoder_ref (&source);
645 void CLASS crw_init_tables (unsigned table, ushort *huff[2])
647 static const uchar first_tree[3][29] = {
648 { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0,
649 0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff },
650 { 0,2,2,3,1,1,1,1,2,0,0,0,0,0,0,0,
651 0x03,0x02,0x04,0x01,0x05,0x00,0x06,0x07,0x09,0x08,0x0a,0x0b,0xff },
652 { 0,0,6,3,1,1,2,0,0,0,0,0,0,0,0,0,
653 0x06,0x05,0x07,0x04,0x08,0x03,0x09,0x02,0x00,0x0a,0x01,0x0b,0xff },
655 static const uchar second_tree[3][180] = {
656 { 0,2,2,2,1,4,2,1,2,5,1,1,0,0,0,139,
657 0x03,0x04,0x02,0x05,0x01,0x06,0x07,0x08,
658 0x12,0x13,0x11,0x14,0x09,0x15,0x22,0x00,0x21,0x16,0x0a,0xf0,
659 0x23,0x17,0x24,0x31,0x32,0x18,0x19,0x33,0x25,0x41,0x34,0x42,
660 0x35,0x51,0x36,0x37,0x38,0x29,0x79,0x26,0x1a,0x39,0x56,0x57,
661 0x28,0x27,0x52,0x55,0x58,0x43,0x76,0x59,0x77,0x54,0x61,0xf9,
662 0x71,0x78,0x75,0x96,0x97,0x49,0xb7,0x53,0xd7,0x74,0xb6,0x98,
663 0x47,0x48,0x95,0x69,0x99,0x91,0xfa,0xb8,0x68,0xb5,0xb9,0xd6,
664 0xf7,0xd8,0x67,0x46,0x45,0x94,0x89,0xf8,0x81,0xd5,0xf6,0xb4,
665 0x88,0xb1,0x2a,0x44,0x72,0xd9,0x87,0x66,0xd4,0xf5,0x3a,0xa7,
666 0x73,0xa9,0xa8,0x86,0x62,0xc7,0x65,0xc8,0xc9,0xa1,0xf4,0xd1,
667 0xe9,0x5a,0x92,0x85,0xa6,0xe7,0x93,0xe8,0xc1,0xc6,0x7a,0x64,
668 0xe1,0x4a,0x6a,0xe6,0xb3,0xf1,0xd3,0xa5,0x8a,0xb2,0x9a,0xba,
669 0x84,0xa4,0x63,0xe5,0xc5,0xf3,0xd2,0xc4,0x82,0xaa,0xda,0xe4,
670 0xf2,0xca,0x83,0xa3,0xa2,0xc3,0xea,0xc2,0xe2,0xe3,0xff,0xff },
671 { 0,2,2,1,4,1,4,1,3,3,1,0,0,0,0,140,
672 0x02,0x03,0x01,0x04,0x05,0x12,0x11,0x06,
673 0x13,0x07,0x08,0x14,0x22,0x09,0x21,0x00,0x23,0x15,0x31,0x32,
674 0x0a,0x16,0xf0,0x24,0x33,0x41,0x42,0x19,0x17,0x25,0x18,0x51,
675 0x34,0x43,0x52,0x29,0x35,0x61,0x39,0x71,0x62,0x36,0x53,0x26,
676 0x38,0x1a,0x37,0x81,0x27,0x91,0x79,0x55,0x45,0x28,0x72,0x59,
677 0xa1,0xb1,0x44,0x69,0x54,0x58,0xd1,0xfa,0x57,0xe1,0xf1,0xb9,
678 0x49,0x47,0x63,0x6a,0xf9,0x56,0x46,0xa8,0x2a,0x4a,0x78,0x99,
679 0x3a,0x75,0x74,0x86,0x65,0xc1,0x76,0xb6,0x96,0xd6,0x89,0x85,
680 0xc9,0xf5,0x95,0xb4,0xc7,0xf7,0x8a,0x97,0xb8,0x73,0xb7,0xd8,
681 0xd9,0x87,0xa7,0x7a,0x48,0x82,0x84,0xea,0xf4,0xa6,0xc5,0x5a,
682 0x94,0xa4,0xc6,0x92,0xc3,0x68,0xb5,0xc8,0xe4,0xe5,0xe6,0xe9,
683 0xa2,0xa3,0xe3,0xc2,0x66,0x67,0x93,0xaa,0xd4,0xd5,0xe7,0xf8,
684 0x88,0x9a,0xd7,0x77,0xc4,0x64,0xe2,0x98,0xa5,0xca,0xda,0xe8,
685 0xf3,0xf6,0xa9,0xb2,0xb3,0xf2,0xd2,0x83,0xba,0xd3,0xff,0xff },
686 { 0,0,6,2,1,3,3,2,5,1,2,2,8,10,0,117,
687 0x04,0x05,0x03,0x06,0x02,0x07,0x01,0x08,
688 0x09,0x12,0x13,0x14,0x11,0x15,0x0a,0x16,0x17,0xf0,0x00,0x22,
689 0x21,0x18,0x23,0x19,0x24,0x32,0x31,0x25,0x33,0x38,0x37,0x34,
690 0x35,0x36,0x39,0x79,0x57,0x58,0x59,0x28,0x56,0x78,0x27,0x41,
691 0x29,0x77,0x26,0x42,0x76,0x99,0x1a,0x55,0x98,0x97,0xf9,0x48,
692 0x54,0x96,0x89,0x47,0xb7,0x49,0xfa,0x75,0x68,0xb6,0x67,0x69,
693 0xb9,0xb8,0xd8,0x52,0xd7,0x88,0xb5,0x74,0x51,0x46,0xd9,0xf8,
694 0x3a,0xd6,0x87,0x45,0x7a,0x95,0xd5,0xf6,0x86,0xb4,0xa9,0x94,
695 0x53,0x2a,0xa8,0x43,0xf5,0xf7,0xd4,0x66,0xa7,0x5a,0x44,0x8a,
696 0xc9,0xe8,0xc8,0xe7,0x9a,0x6a,0x73,0x4a,0x61,0xc7,0xf4,0xc6,
697 0x65,0xe9,0x72,0xe6,0x71,0x91,0x93,0xa6,0xda,0x92,0x85,0x62,
698 0xf3,0xc5,0xb2,0xa4,0x84,0xba,0x64,0xa5,0xb3,0xd2,0x81,0xe5,
699 0xd3,0xaa,0xc4,0xca,0xf2,0xb1,0xe4,0xd1,0x83,0x63,0xea,0xc3,
700 0xe2,0x82,0xf1,0xa3,0xc2,0xa1,0xc1,0xe3,0xa2,0xe1,0xff,0xff }
702 if (table > 2) table = 2;
703 huff[0] = make_decoder ( first_tree[table]);
704 huff[1] = make_decoder (second_tree[table]);
708 Return 0 if the image starts with compressed data,
709 1 if it starts with uncompressed low-order bits.
711 In Canon compressed data, 0xff is always followed by 0x00.
713 int CLASS canon_has_lowbits()
718 fseek (ifp, 0, SEEK_SET);
719 fread (test, 1, sizeof test, ifp);
720 for (i=540; i < sizeof test - 1; i++)
721 if (test[i] == 0xff) {
722 if (test[i+1]) return 1;
728 void CLASS canon_load_raw()
730 ushort *pixel, *prow, *huff[2];
731 int nblocks, lowbits, i, c, row, r, save, val;
732 int block, diffbuf[64], leaf, len, diff, carry=0, pnum=0, base[2];
734 crw_init_tables (tiff_compress, huff);
735 lowbits = canon_has_lowbits();
736 if (!lowbits) maximum = 0x3ff;
737 fseek (ifp, 540 + lowbits*raw_height*raw_width/4, SEEK_SET);
740 for (row=0; row < raw_height; row+=8) {
741 pixel = raw_image + row*raw_width;
742 nblocks = MIN (8, raw_height-row) * raw_width >> 6;
743 for (block=0; block < nblocks; block++) {
744 memset (diffbuf, 0, sizeof diffbuf);
745 for (i=0; i < 64; i++ ) {
746 leaf = gethuff(huff[i > 0]);
747 if (leaf == 0 && i) break;
748 if (leaf == 0xff) continue;
751 if (len == 0) continue;
753 if ((diff & (1 << (len-1))) == 0)
754 diff -= (1 << len) - 1;
755 if (i < 64) diffbuf[i] = diff;
759 for (i=0; i < 64; i++ ) {
760 if (pnum++ % raw_width == 0)
761 base[0] = base[1] = 512;
762 if ((pixel[(block << 6) + i] = base[i & 1] += diffbuf[i]) >> 10)
768 fseek (ifp, 26 + row*raw_width/4, SEEK_SET);
769 for (prow=pixel, i=0; i < raw_width*2; i++) {
771 for (r=0; r < 8; r+=2, prow++) {
772 val = (*prow << 2) + ((c >> r) & 3);
773 if (raw_width == 2672 && val < 512) val += 2;
777 fseek (ifp, save, SEEK_SET);
780 FORC(2) free (huff[c]);
784 int algo, bits, high, wide, clrs, sraw, psv, restart, vpred[6];
785 ushort quant[64], idct[64], *huff[20], *free[20], *row;
788 int CLASS ljpeg_start (struct jhead *jh, int info_only)
794 memset (jh, 0, sizeof *jh);
795 jh->restart = INT_MAX;
796 if ((fgetc(ifp),fgetc(ifp)) != 0xd8) return 0;
798 if (!fread (data, 2, 2, ifp)) return 0;
799 tag = data[0] << 8 | data[1];
800 len = (data[2] << 8 | data[3]) - 2;
801 if (tag <= 0xff00) return 0;
802 fread (data, 1, len, ifp);
805 jh->sraw = ((data[7] >> 4) * (data[7] & 15) - 1) & 3;
808 jh->algo = tag & 0xff;
810 jh->high = data[1] << 8 | data[2];
811 jh->wide = data[3] << 8 | data[4];
812 jh->clrs = data[5] + jh->sraw;
813 if (len == 9 && !dng_version) getc(ifp);
816 if (info_only) break;
817 for (dp = data; dp < data+len && !((c = *dp++) & -20); )
818 jh->free[c] = jh->huff[c] = make_decoder_ref (&dp);
821 jh->psv = data[1+data[0]*2];
822 jh->bits -= data[3+data[0]*2] & 15;
825 FORC(64) jh->quant[c] = data[c*2+1] << 8 | data[c*2+2];
828 jh->restart = data[0] << 8 | data[1];
830 } while (tag != 0xffda);
831 if (jh->bits > 16 || jh->clrs > 6 ||
832 !jh->bits || !jh->high || !jh->wide || !jh->clrs) return 0;
833 if (info_only) return 1;
834 if (!jh->huff[0]) return 0;
835 FORC(19) if (!jh->huff[c+1]) jh->huff[c+1] = jh->huff[c];
837 FORC(4) jh->huff[2+c] = jh->huff[1];
838 FORC(jh->sraw) jh->huff[1+c] = jh->huff[0];
840 jh->row = (ushort *) calloc (jh->wide*jh->clrs, 4);
841 merror (jh->row, "ljpeg_start()");
842 return zero_after_ff = 1;
845 void CLASS ljpeg_end (struct jhead *jh)
848 FORC4 if (jh->free[c]) free (jh->free[c]);
852 int CLASS ljpeg_diff (ushort *huff)
857 if (len == 16 && (!dng_version || dng_version >= 0x1010000))
860 if ((diff & (1 << (len-1))) == 0)
861 diff -= (1 << len) - 1;
865 ushort * CLASS ljpeg_row (int jrow, struct jhead *jh)
867 int col, c, diff, pred, spred=0;
868 ushort mark=0, *row[3];
870 if (jrow * jh->wide % jh->restart == 0) {
871 FORC(6) jh->vpred[c] = 1 << (jh->bits-1);
873 fseek (ifp, -2, SEEK_CUR);
874 do mark = (mark << 8) + (c = fgetc(ifp));
875 while (c != EOF && mark >> 4 != 0xffd);
879 FORC3 row[c] = jh->row + jh->wide*jh->clrs*((jrow+c) & 1);
880 for (col=0; col < jh->wide; col++)
882 diff = ljpeg_diff (jh->huff[c]);
883 if (jh->sraw && c <= jh->sraw && (col | c))
885 else if (col) pred = row[0][-jh->clrs];
886 else pred = (jh->vpred[c] += diff) - diff;
887 if (jrow && col) switch (jh->psv) {
889 case 2: pred = row[1][0]; break;
890 case 3: pred = row[1][-jh->clrs]; break;
891 case 4: pred = pred + row[1][0] - row[1][-jh->clrs]; break;
892 case 5: pred = pred + ((row[1][0] - row[1][-jh->clrs]) >> 1); break;
893 case 6: pred = row[1][0] + ((pred - row[1][-jh->clrs]) >> 1); break;
894 case 7: pred = (pred + row[1][0]) >> 1; break;
897 if ((**row = pred + diff) >> jh->bits) derror();
898 if (c <= jh->sraw) spred = **row;
904 void CLASS lossless_jpeg_load_raw()
906 int jwide, jrow, jcol, val, jidx, i, j, row=0, col=0;
910 if (!ljpeg_start (&jh, 0)) return;
911 jwide = jh.wide * jh.clrs;
913 for (jrow=0; jrow < jh.high; jrow++) {
914 rp = ljpeg_row (jrow, &jh);
916 row = jrow & 1 ? height-1-jrow/2 : jrow/2;
917 for (jcol=0; jcol < jwide; jcol++) {
920 jidx = jrow*jwide + jcol;
921 i = jidx / (cr2_slice[1]*raw_height);
922 if ((j = i >= cr2_slice[0]))
924 jidx -= i * (cr2_slice[1]*raw_height);
925 row = jidx / cr2_slice[1+j];
926 col = jidx % cr2_slice[1+j] + i*cr2_slice[1];
928 if (raw_width == 3984 && (col -= 2) < 0)
929 col += (row--,raw_width);
930 if ((unsigned) row < raw_height) RAW(row,col) = val;
931 if (++col >= raw_width)
938 void CLASS canon_sraw_load_raw()
941 short *rp=0, (*ip)[4];
942 int jwide, slice, scol, ecol, row, col, jrow=0, jcol=0, pix[3], c;
943 int v[3]={0,0,0}, ver, hue;
946 if (!ljpeg_start (&jh, 0) || jh.clrs < 4) return;
947 jwide = (jh.wide >>= 1) * jh.clrs;
949 for (ecol=slice=0; slice <= cr2_slice[0]; slice++) {
951 ecol += cr2_slice[1] * 2 / jh.clrs;
952 if (!cr2_slice[0] || ecol > raw_width-1) ecol = raw_width & -2;
953 for (row=0; row < height; row += (jh.clrs >> 1) - 1) {
954 ip = (short (*)[4]) image + row*width;
955 for (col=scol; col < ecol; col+=2, jcol+=jh.clrs) {
956 if ((jcol %= jwide) == 0)
957 rp = (short *) ljpeg_row (jrow++, &jh);
958 if (col >= width) continue;
960 ip[col + (c >> 1)*width + (c & 1)][0] = rp[jcol+c];
961 ip[col][1] = rp[jcol+jh.clrs-2] - 16384;
962 ip[col][2] = rp[jcol+jh.clrs-1] - 16384;
966 for (cp=model2; *cp && !isdigit(*cp); cp++);
967 sscanf (cp, "%d.%d.%d", v, v+1, v+2);
968 ver = (v[0]*1000 + v[1])*1000 + v[2];
969 hue = (jh.sraw+1) << 2;
970 if (unique_id >= 0x80000281 || (unique_id == 0x80000218 && ver > 1000006))
972 ip = (short (*)[4]) image;
974 for (row=0; row < height; row++, ip+=width) {
975 if (row & (jh.sraw >> 1)) {
976 for (col=0; col < width; col+=2)
977 for (c=1; c < 3; c++)
979 ip[col][c] = ip[col-width][c];
980 else ip[col][c] = (ip[col-width][c] + ip[col+width][c] + 1) >> 1;
982 for (col=1; col < width; col+=2)
983 for (c=1; c < 3; c++)
985 ip[col][c] = ip[col-1][c];
986 else ip[col][c] = (ip[col-1][c] + ip[col+1][c] + 1) >> 1;
988 for ( ; rp < ip[0]; rp+=4) {
989 if (unique_id == 0x80000218 ||
990 unique_id == 0x80000250 ||
991 unique_id == 0x80000261 ||
992 unique_id == 0x80000281 ||
993 unique_id == 0x80000287) {
994 rp[1] = (rp[1] << 2) + hue;
995 rp[2] = (rp[2] << 2) + hue;
996 pix[0] = rp[0] + (( 50*rp[1] + 22929*rp[2]) >> 14);
997 pix[1] = rp[0] + ((-5640*rp[1] - 11751*rp[2]) >> 14);
998 pix[2] = rp[0] + ((29040*rp[1] - 101*rp[2]) >> 14);
1000 if (unique_id < 0x80000218) rp[0] -= 512;
1001 pix[0] = rp[0] + rp[2];
1002 pix[2] = rp[0] + rp[1];
1003 pix[1] = rp[0] + ((-778*rp[1] - (rp[2] << 11)) >> 12);
1005 FORC3 rp[c] = (int)CLIP(pix[c] * sraw_mul[c] >> 10);
1011 void CLASS adobe_copy_pixel (unsigned row, unsigned col, ushort **rp)
1015 if (tiff_samples == 2 && shot_select) (*rp)++;
1017 if (row < raw_height && col < raw_width)
1018 RAW(row,col) = curve[**rp];
1019 *rp += tiff_samples;
1021 if (row < height && col < width)
1023 image[row*width+col][c] = curve[(*rp)[c]];
1024 *rp += tiff_samples;
1026 if (tiff_samples == 2 && shot_select) (*rp)--;
1029 void CLASS ljpeg_idct (struct jhead *jh)
1031 int c, i, j, len, skip, coef;
1032 float work[3][8][8], *cs = ljpeg_cs;
1033 static const uchar zigzag[80] =
1034 { 0, 1, 8,16, 9, 2, 3,10,17,24,32,25,18,11, 4, 5,12,19,26,33,
1035 40,48,41,34,27,20,13, 6, 7,14,21,28,35,42,49,56,57,50,43,36,
1036 29,22,15,23,30,37,44,51,58,59,52,45,38,31,39,46,53,60,61,54,
1037 47,55,62,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63 };
1040 FORC(106) cs[c] = cos((c & 31)*M_PI/16)/2;
1041 memset (work, 0, sizeof work);
1042 work[0][0][0] = jh->vpred[0] += ljpeg_diff (jh->huff[0]) * jh->quant[0];
1043 for (i=1; i < 64; i++ ) {
1044 len = gethuff (jh->huff[16]);
1045 i += skip = len >> 4;
1046 if (!(len &= 15) && skip < 15) break;
1047 coef = getbits(len);
1048 if ((coef & (1 << (len-1))) == 0)
1049 coef -= (1 << len) - 1;
1050 ((float *)work)[zigzag[i]] = coef * jh->quant[i];
1052 FORC(8) work[0][0][c] *= M_SQRT1_2;
1053 FORC(8) work[0][c][0] *= M_SQRT1_2;
1054 for (i=0; i < 8; i++)
1055 for (j=0; j < 8; j++)
1056 FORC(8) work[1][i][j] += work[0][i][c] * cs[(j*2+1)*c];
1057 for (i=0; i < 8; i++)
1058 for (j=0; j < 8; j++)
1059 FORC(8) work[2][i][j] += work[1][c][j] * cs[(i*2+1)*c];
1061 FORC(64) jh->idct[c] = CLIP(((float *)work[2])[c]+0.5);
1064 void CLASS lossless_dng_load_raw()
1066 unsigned save, trow=0, tcol=0, jwide, jrow, jcol, row, col, i, j;
1070 while (trow < raw_height) {
1072 if (tile_length < INT_MAX)
1073 fseek (ifp, get4(), SEEK_SET);
1074 if (!ljpeg_start (&jh, 0)) break;
1076 if (filters) jwide *= jh.clrs;
1077 jwide /= MIN (is_raw, tiff_samples);
1080 jh.vpred[0] = 16384;
1082 for (jrow=0; jrow+7 < jh.high; jrow += 8) {
1083 for (jcol=0; jcol+7 < jh.wide; jcol += 8) {
1086 row = trow + jcol/tile_width + jrow*2;
1087 col = tcol + jcol%tile_width;
1088 for (i=0; i < 16; i+=2)
1089 for (j=0; j < 8; j++)
1090 adobe_copy_pixel (row+i, col+j, &rp);
1095 for (row=col=jrow=0; jrow < jh.high; jrow++) {
1096 rp = ljpeg_row (jrow, &jh);
1097 for (jcol=0; jcol < jwide; jcol++) {
1098 adobe_copy_pixel (trow+row, tcol+col, &rp);
1099 if (++col >= tile_width || col >= raw_width)
1100 row += 1 + (col = 0);
1104 fseek (ifp, save+4, SEEK_SET);
1105 if ((tcol += tile_width) >= raw_width)
1106 trow += tile_length + (tcol = 0);
1111 void CLASS packed_dng_load_raw()
1116 pixel = (ushort *) calloc (raw_width, tiff_samples*sizeof *pixel);
1117 merror (pixel, "packed_dng_load_raw()");
1118 for (row=0; row < raw_height; row++) {
1120 read_shorts (pixel, raw_width * tiff_samples);
1123 for (col=0; col < raw_width * tiff_samples; col++)
1124 pixel[col] = getbits(tiff_bps);
1126 for (rp=pixel, col=0; col < raw_width; col++)
1127 adobe_copy_pixel (row, col, &rp);
1132 void CLASS pentax_load_raw()
1134 ushort bit[2][15], huff[4097];
1135 int dep, row, col, diff, c, i;
1136 ushort vpred[2][2] = {{0,0},{0,0}}, hpred[2];
1138 fseek (ifp, meta_offset, SEEK_SET);
1139 dep = (get2() + 12) & 15;
1140 fseek (ifp, 12, SEEK_CUR);
1141 FORC(dep) bit[0][c] = get2();
1142 FORC(dep) bit[1][c] = fgetc(ifp);
1144 for (i=bit[0][c]; i <= ((bit[0][c]+(4096 >> bit[1][c])-1) & 4095); )
1145 huff[++i] = bit[1][c] << 8 | c;
1147 fseek (ifp, data_offset, SEEK_SET);
1149 for (row=0; row < raw_height; row++)
1150 for (col=0; col < raw_width; col++) {
1151 diff = ljpeg_diff (huff);
1152 if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
1153 else hpred[col & 1] += diff;
1154 RAW(row,col) = hpred[col & 1];
1155 if (hpred[col & 1] >> tiff_bps) derror();
1159 void CLASS nikon_load_raw()
1161 static const uchar nikon_tree[][32] = {
1162 { 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0, /* 12-bit lossy */
1163 5,4,3,6,2,7,1,0,8,9,11,10,12 },
1164 { 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0, /* 12-bit lossy after split */
1165 0x39,0x5a,0x38,0x27,0x16,5,4,3,2,1,0,11,12,12 },
1166 { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0, /* 12-bit lossless */
1167 5,4,6,3,7,2,8,1,9,0,10,11,12 },
1168 { 0,1,4,3,1,1,1,1,1,2,0,0,0,0,0,0, /* 14-bit lossy */
1169 5,6,4,7,8,3,9,2,1,0,10,11,12,13,14 },
1170 { 0,1,5,1,1,1,1,1,1,1,2,0,0,0,0,0, /* 14-bit lossy after split */
1171 8,0x5c,0x4b,0x3a,0x29,7,6,5,4,3,2,1,0,13,14 },
1172 { 0,1,4,2,2,3,1,2,0,0,0,0,0,0,0,0, /* 14-bit lossless */
1173 7,6,8,5,9,4,10,3,11,12,2,0,1,13,14 } };
1174 ushort *huff, ver0, ver1, vpred[2][2], hpred[2], csize;
1175 int i, min, max, step=0, tree=0, split=0, row, col, len, shl, diff;
1177 fseek (ifp, meta_offset, SEEK_SET);
1180 if (ver0 == 0x49 || ver1 == 0x58)
1181 fseek (ifp, 2110, SEEK_CUR);
1182 if (ver0 == 0x46) tree = 2;
1183 if (tiff_bps == 14) tree += 3;
1184 read_shorts (vpred[0], 4);
1185 max = 1 << tiff_bps & 0x7fff;
1186 if ((csize = get2()) > 1)
1187 step = max / (csize-1);
1188 if (ver0 == 0x44 && ver1 == 0x20 && step > 0) {
1189 for (i=0; i < csize; i++)
1190 curve[i*step] = get2();
1191 for (i=0; i < max; i++)
1192 curve[i] = ( curve[i-i%step]*(step-i%step) +
1193 curve[i-i%step+step]*(i%step) ) / step;
1194 fseek (ifp, meta_offset+562, SEEK_SET);
1196 } else if (ver0 != 0x46 && csize <= 0x4001)
1197 read_shorts (curve, max=csize);
1198 while (curve[max-2] == curve[max-1]) max--;
1199 huff = make_decoder (nikon_tree[tree]);
1200 fseek (ifp, data_offset, SEEK_SET);
1202 for (min=row=0; row < height; row++) {
1203 if (split && row == split) {
1205 huff = make_decoder (nikon_tree[tree+1]);
1206 max += (min = 16) << 1;
1208 for (col=0; col < raw_width; col++) {
1212 diff = ((getbits(len-shl) << 1) + 1) << shl >> 1;
1213 if ((diff & (1 << (len-1))) == 0)
1214 diff -= (1 << len) - !shl;
1215 if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
1216 else hpred[col & 1] += diff;
1217 if ((ushort)(hpred[col & 1] + min) >= max) derror();
1218 RAW(row,col) = curve[LIM((short)hpred[col & 1],0,0x3fff)];
1224 void CLASS nikon_yuv_load_raw()
1226 int row, col, yuv[4], rgb[3], b, c;
1229 for (row=0; row < raw_height; row++)
1230 for (col=0; col < raw_width; col++) {
1231 if (!(b = col & 1)) {
1233 FORC(6) bitbuf |= (UINT64) fgetc(ifp) << c*8;
1234 FORC(4) yuv[c] = (bitbuf >> c*12 & 0xfff) - (c >> 1 << 11);
1236 rgb[0] = yuv[b] + 1.370705*yuv[3];
1237 rgb[1] = yuv[b] - 0.337633*yuv[2] - 0.698001*yuv[3];
1238 rgb[2] = yuv[b] + 1.732446*yuv[2];
1239 FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,0xfff)] / cam_mul[c];
1244 Returns 1 for a Coolpix 995, 0 for anything else.
1246 int CLASS nikon_e995()
1249 const uchar often[] = { 0x00, 0x55, 0xaa, 0xff };
1251 memset (histo, 0, sizeof histo);
1252 fseek (ifp, -2000, SEEK_END);
1253 for (i=0; i < 2000; i++)
1254 histo[fgetc(ifp)]++;
1255 for (i=0; i < 4; i++)
1256 if (histo[often[i]] < 200)
1262 Returns 1 for a Coolpix 2100, 0 for anything else.
1264 int CLASS nikon_e2100()
1269 fseek (ifp, 0, SEEK_SET);
1270 for (i=0; i < 1024; i++) {
1271 fread (t, 1, 12, ifp);
1272 if (((t[2] & t[4] & t[7] & t[9]) >> 4
1273 & t[1] & t[6] & t[8] & t[11] & 3) != 3)
1279 void CLASS nikon_3700()
1283 static const struct {
1285 char make[12], model[15];
1287 { 0x00, "Pentax", "Optio 33WR" },
1288 { 0x03, "Nikon", "E3200" },
1289 { 0x32, "Nikon", "E3700" },
1290 { 0x33, "Olympus", "C740UZ" } };
1292 fseek (ifp, 3072, SEEK_SET);
1293 fread (dp, 1, 24, ifp);
1294 bits = (dp[8] & 3) << 4 | (dp[20] & 3);
1295 for (i=0; i < sizeof table / sizeof *table; i++)
1296 if (bits == table[i].bits) {
1297 strcpy (make, table[i].make );
1298 strcpy (model, table[i].model);
1303 Separates a Minolta DiMAGE Z2 from a Nikon E4300.
1305 int CLASS minolta_z2()
1310 fseek (ifp, -sizeof tail, SEEK_END);
1311 fread (tail, 1, sizeof tail, ifp);
1312 for (nz=i=0; i < sizeof tail; i++)
1317 void CLASS ppm_thumb()
1320 thumb_length = thumb_width*thumb_height*3;
1321 thumb = (char *) malloc (thumb_length);
1322 merror (thumb, "ppm_thumb()");
1323 fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
1324 fread (thumb, 1, thumb_length, ifp);
1325 fwrite (thumb, 1, thumb_length, ofp);
1329 void CLASS ppm16_thumb()
1333 thumb_length = thumb_width*thumb_height*3;
1334 thumb = (char *) calloc (thumb_length, 2);
1335 merror (thumb, "ppm16_thumb()");
1336 read_shorts ((ushort *) thumb, thumb_length);
1337 for (i=0; i < thumb_length; i++)
1338 thumb[i] = ((ushort *) thumb)[i] >> 8;
1339 fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
1340 fwrite (thumb, 1, thumb_length, ofp);
1344 void CLASS layer_thumb()
1347 char *thumb, map[][4] = { "012","102" };
1349 colors = thumb_misc >> 5 & 7;
1350 thumb_length = thumb_width*thumb_height;
1351 thumb = (char *) calloc (colors, thumb_length);
1352 merror (thumb, "layer_thumb()");
1353 fprintf (ofp, "P%d\n%d %d\n255\n",
1354 5 + (colors >> 1), thumb_width, thumb_height);
1355 fread (thumb, thumb_length, colors, ifp);
1356 for (i=0; i < thumb_length; i++)
1357 FORCC putc (thumb[i+thumb_length*(map[thumb_misc >> 8][c]-'0')], ofp);
1361 void CLASS rollei_thumb()
1366 thumb_length = thumb_width * thumb_height;
1367 thumb = (ushort *) calloc (thumb_length, 2);
1368 merror (thumb, "rollei_thumb()");
1369 fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
1370 read_shorts (thumb, thumb_length);
1371 for (i=0; i < thumb_length; i++) {
1372 putc (thumb[i] << 3, ofp);
1373 putc (thumb[i] >> 5 << 2, ofp);
1374 putc (thumb[i] >> 11 << 3, ofp);
1379 void CLASS rollei_load_raw()
1382 unsigned iten=0, isix, i, buffer=0, todo[16];
1384 isix = raw_width * raw_height * 5 / 8;
1385 while (fread (pixel, 1, 10, ifp) == 10) {
1386 for (i=0; i < 10; i+=2) {
1388 todo[i+1] = pixel[i] << 8 | pixel[i+1];
1389 buffer = pixel[i] >> 2 | buffer << 6;
1391 for ( ; i < 16; i+=2) {
1393 todo[i+1] = buffer >> (14-i)*5;
1395 for (i=0; i < 16; i+=2)
1396 raw_image[todo[i]] = (todo[i+1] & 0x3ff);
1401 int CLASS raw (unsigned row, unsigned col)
1403 return (row < raw_height && col < raw_width) ? RAW(row,col) : 0;
1406 void CLASS phase_one_flat_field (int is_float, int nc)
1409 unsigned wide, high, y, x, c, rend, cend, row, col;
1410 float *mrow, num, mult[4];
1412 read_shorts (head, 8);
1413 if (head[2] * head[3] * head[4] * head[5] == 0) return;
1414 wide = head[2] / head[4] + (head[2] % head[4] != 0);
1415 high = head[3] / head[5] + (head[3] % head[5] != 0);
1416 mrow = (float *) calloc (nc*wide, sizeof *mrow);
1417 merror (mrow, "phase_one_flat_field()");
1418 for (y=0; y < high; y++) {
1419 for (x=0; x < wide; x++)
1420 for (c=0; c < nc; c+=2) {
1421 num = is_float ? getreal(11) : get2()/32768.0;
1422 if (y==0) mrow[c*wide+x] = num;
1423 else mrow[(c+1)*wide+x] = (num - mrow[c*wide+x]) / head[5];
1426 rend = head[1] + y*head[5];
1427 for (row = rend-head[5];
1428 row < raw_height && row < rend &&
1429 row < head[1]+head[3]-head[5]; row++) {
1430 for (x=1; x < wide; x++) {
1431 for (c=0; c < nc; c+=2) {
1432 mult[c] = mrow[c*wide+x-1];
1433 mult[c+1] = (mrow[c*wide+x] - mult[c]) / head[4];
1435 cend = head[0] + x*head[4];
1436 for (col = cend-head[4];
1438 col < cend && col < head[0]+head[2]-head[4]; col++) {
1439 c = nc > 2 ? FC(row-top_margin,col-left_margin) : 0;
1441 c = RAW(row,col) * mult[c];
1442 RAW(row,col) = LIM(c,0,65535);
1444 for (c=0; c < nc; c+=2)
1445 mult[c] += mult[c+1];
1448 for (x=0; x < wide; x++)
1449 for (c=0; c < nc; c+=2)
1450 mrow[c*wide+x] += mrow[(c+1)*wide+x];
1456 void CLASS phase_one_correct()
1458 unsigned entries, tag, data, save, col, row, type;
1459 int len, i, j, k, cip, val[4], dev[4], sum, max;
1460 int head[9], diff, mindiff=INT_MAX, off_412=0;
1461 static const signed char dir[12][2] =
1462 { {-1,-1}, {-1,1}, {1,-1}, {1,1}, {-2,0}, {0,-2}, {0,2}, {2,0},
1463 {-2,-2}, {-2,2}, {2,-2}, {2,2} };
1464 float poly[8], num, cfrac, frac, mult[2], *yval[2];
1466 int qmult_applied = 0, qlin_applied = 0;
1468 if (half_size || !meta_length) return;
1469 if (verbose) fprintf (stderr,_("Phase One correction...\n"));
1470 fseek (ifp, meta_offset, SEEK_SET);
1472 fseek (ifp, 6, SEEK_CUR);
1473 fseek (ifp, meta_offset+get4(), SEEK_SET);
1474 entries = get4(); get4();
1480 fseek (ifp, meta_offset+data, SEEK_SET);
1481 if (tag == 0x419) { /* Polynomial curve */
1482 for (get4(), i=0; i < 8; i++)
1483 poly[i] = getreal(11);
1484 poly[3] += (ph1.tag_210 - poly[7]) * poly[6] + 1;
1485 for (i=0; i < 0x10000; i++) {
1486 num = (poly[5]*i + poly[3])*i + poly[1];
1487 curve[i] = LIM(num,0,65535);
1488 } goto apply; /* apply to right half */
1489 } else if (tag == 0x41a) { /* Polynomial curve */
1490 for (i=0; i < 4; i++)
1491 poly[i] = getreal(11);
1492 for (i=0; i < 0x10000; i++) {
1493 for (num=0, j=4; j--; )
1494 num = num * i + poly[j];
1495 curve[i] = LIM(num+i,0,65535);
1496 } apply: /* apply to whole image */
1497 for (row=0; row < raw_height; row++)
1498 for (col = (tag & 1)*ph1.split_col; col < raw_width; col++)
1499 RAW(row,col) = curve[RAW(row,col)];
1500 } else if (tag == 0x400) { /* Sensor defects */
1501 while ((len -= 8) >= 0) {
1504 type = get2(); get2();
1505 if (col >= raw_width) continue;
1506 if (type == 131 || type == 137) /* Bad column */
1507 for (row=0; row < raw_height; row++)
1508 if (FC(row-top_margin,col-left_margin) == 1) {
1509 for (sum=i=0; i < 4; i++)
1510 sum += val[i] = raw (row+dir[i][0], col+dir[i][1]);
1511 for (max=i=0; i < 4; i++) {
1512 dev[i] = abs((val[i] << 2) - sum);
1513 if (dev[max] < dev[i]) max = i;
1515 RAW(row,col) = (sum - val[max])/3.0 + 0.5;
1517 for (sum=0, i=8; i < 12; i++)
1518 sum += raw (row+dir[i][0], col+dir[i][1]);
1519 RAW(row,col) = 0.5 + sum * 0.0732233 +
1520 (raw(row,col-2) + raw(row,col+2)) * 0.3535534;
1522 else if (type == 129) { /* Bad pixel */
1523 if (row >= raw_height) continue;
1524 j = (FC(row-top_margin,col-left_margin) != 1) * 4;
1525 for (sum=0, i=j; i < j+8; i++)
1526 sum += raw (row+dir[i][0], col+dir[i][1]);
1527 RAW(row,col) = (sum + 4) >> 3;
1530 } else if (tag == 0x401) { /* All-color flat fields */
1531 phase_one_flat_field (1, 2);
1532 } else if (tag == 0x416 || tag == 0x410) {
1533 phase_one_flat_field (0, 2);
1534 } else if (tag == 0x40b) { /* Red+blue flat field */
1535 phase_one_flat_field (0, 4);
1536 } else if (tag == 0x412) {
1537 fseek (ifp, 36, SEEK_CUR);
1538 diff = abs (get2() - ph1.tag_21a);
1539 if (mindiff > diff) {
1541 off_412 = ftell(ifp) - 38;
1543 } else if (tag == 0x41f && !qlin_applied) { /* Quadrant linearization */
1544 ushort lc[2][2][16], ref[16];
1546 for (qr = 0; qr < 2; qr++)
1547 for (qc = 0; qc < 2; qc++)
1548 for (i = 0; i < 16; i++)
1549 lc[qr][qc][i] = get4();
1550 for (i = 0; i < 16; i++) {
1552 for (qr = 0; qr < 2; qr++)
1553 for (qc = 0; qc < 2; qc++)
1555 ref[i] = (v + 2) >> 2;
1557 for (qr = 0; qr < 2; qr++) {
1558 for (qc = 0; qc < 2; qc++) {
1560 for (i = 0; i < 16; i++) {
1561 cx[1+i] = lc[qr][qc][i];
1565 cx[17] = cf[17] = ((unsigned) ref[15] * 65535) / lc[qr][qc][15];
1566 cx[18] = cf[18] = 65535;
1567 cubic_spline(cx, cf, 19);
1568 for (row = (qr ? ph1.split_row : 0);
1569 row < (qr ? raw_height : ph1.split_row); row++)
1570 for (col = (qc ? ph1.split_col : 0);
1571 col < (qc ? raw_width : ph1.split_col); col++)
1572 RAW(row,col) = curve[RAW(row,col)];
1576 } else if (tag == 0x41e && !qmult_applied) { /* Quadrant multipliers */
1577 float qmult[2][2] = { { 1, 1 }, { 1, 1 } };
1578 get4(); get4(); get4(); get4();
1579 qmult[0][0] = 1.0 + getreal(11);
1580 get4(); get4(); get4(); get4(); get4();
1581 qmult[0][1] = 1.0 + getreal(11);
1582 get4(); get4(); get4();
1583 qmult[1][0] = 1.0 + getreal(11);
1584 get4(); get4(); get4();
1585 qmult[1][1] = 1.0 + getreal(11);
1586 for (row=0; row < raw_height; row++)
1587 for (col=0; col < raw_width; col++) {
1588 i = qmult[row >= ph1.split_row][col >= ph1.split_col] * RAW(row,col);
1589 RAW(row,col) = LIM(i,0,65535);
1592 } else if (tag == 0x431 && !qmult_applied) { /* Quadrant combined */
1593 ushort lc[2][2][7], ref[7];
1595 for (i = 0; i < 7; i++)
1597 for (qr = 0; qr < 2; qr++)
1598 for (qc = 0; qc < 2; qc++)
1599 for (i = 0; i < 7; i++)
1600 lc[qr][qc][i] = get4();
1601 for (qr = 0; qr < 2; qr++) {
1602 for (qc = 0; qc < 2; qc++) {
1604 for (i = 0; i < 7; i++) {
1606 cf[1+i] = ((unsigned) ref[i] * lc[qr][qc][i]) / 10000;
1609 cx[8] = cf[8] = 65535;
1610 cubic_spline(cx, cf, 9);
1611 for (row = (qr ? ph1.split_row : 0);
1612 row < (qr ? raw_height : ph1.split_row); row++)
1613 for (col = (qc ? ph1.split_col : 0);
1614 col < (qc ? raw_width : ph1.split_col); col++)
1615 RAW(row,col) = curve[RAW(row,col)];
1621 fseek (ifp, save, SEEK_SET);
1624 fseek (ifp, off_412, SEEK_SET);
1625 for (i=0; i < 9; i++) head[i] = get4() & 0x7fff;
1626 yval[0] = (float *) calloc (head[1]*head[3] + head[2]*head[4], 6);
1627 merror (yval[0], "phase_one_correct()");
1628 yval[1] = (float *) (yval[0] + head[1]*head[3]);
1629 xval[0] = (ushort *) (yval[1] + head[2]*head[4]);
1630 xval[1] = (ushort *) (xval[0] + head[1]*head[3]);
1632 for (i=0; i < 2; i++)
1633 for (j=0; j < head[i+1]*head[i+3]; j++)
1634 yval[i][j] = getreal(11);
1635 for (i=0; i < 2; i++)
1636 for (j=0; j < head[i+1]*head[i+3]; j++)
1637 xval[i][j] = get2();
1638 for (row=0; row < raw_height; row++)
1639 for (col=0; col < raw_width; col++) {
1640 cfrac = (float) col * head[3] / raw_width;
1641 cfrac -= cip = cfrac;
1642 num = RAW(row,col) * 0.5;
1643 for (i=cip; i < cip+2; i++) {
1644 for (k=j=0; j < head[1]; j++)
1645 if (num < xval[0][k = head[1]*i+j]) break;
1646 frac = (j == 0 || j == head[1]) ? 0 :
1647 (xval[0][k] - num) / (xval[0][k] - xval[0][k-1]);
1648 mult[i-cip] = yval[0][k-1] * frac + yval[0][k] * (1-frac);
1650 i = ((mult[0] * (1-cfrac) + mult[1] * cfrac) * row + num) * 2;
1651 RAW(row,col) = LIM(i,0,65535);
1657 void CLASS phase_one_load_raw()
1660 ushort akey, bkey, mask;
1662 fseek (ifp, ph1.key_off, SEEK_SET);
1665 mask = ph1.format == 1 ? 0x5555:0x1354;
1666 fseek (ifp, data_offset, SEEK_SET);
1667 read_shorts (raw_image, raw_width*raw_height);
1669 for (i=0; i < raw_width*raw_height; i+=2) {
1670 a = raw_image[i+0] ^ akey;
1671 b = raw_image[i+1] ^ bkey;
1672 raw_image[i+0] = (a & mask) | (b & ~mask);
1673 raw_image[i+1] = (b & mask) | (a & ~mask);
1677 unsigned CLASS ph1_bithuff (int nbits, ushort *huff)
1684 return ph1_bitbuf = ph1_vbits = 0;
1685 if (nbits == 0) return 0;
1686 bitbuf = ph1_bitbuf; vbits = ph1_vbits;
1687 if (vbits < nbits) {
1688 bitbuf = bitbuf << 32 | get4();
1691 c = bitbuf << (64-vbits) >> (64-nbits);
1693 nbits = huff[c] >> 8;
1694 c = (uchar) huff[c];
1697 ph1_bitbuf = bitbuf; ph1_vbits = vbits;
1700 #define ph1_bits(n) ph1_bithuff(n,0)
1701 #define ph1_huff(h) ph1_bithuff(*h,h+1)
1703 void CLASS phase_one_load_raw_c()
1705 static const int length[] = { 8,7,6,9,11,10,5,12,14,13 };
1706 int *offset, len[2], pred[2], row, col, i, j;
1708 short (*cblack)[2], (*rblack)[2];
1710 pixel = (ushort *) calloc (raw_width*3 + raw_height*4, 2);
1711 merror (pixel, "phase_one_load_raw_c()");
1712 offset = (int *) (pixel + raw_width);
1713 fseek (ifp, strip_offset, SEEK_SET);
1714 for (row=0; row < raw_height; row++)
1715 offset[row] = get4();
1716 cblack = (short (*)[2]) (offset + raw_height);
1717 fseek (ifp, ph1.black_col, SEEK_SET);
1719 read_shorts ((ushort *) cblack[0], raw_height*2);
1720 rblack = cblack + raw_height;
1721 fseek (ifp, ph1.black_row, SEEK_SET);
1723 read_shorts ((ushort *) rblack[0], raw_width*2);
1724 for (i=0; i < 256; i++)
1725 curve[i] = i*i / 3.969 + 0.5;
1726 for (row=0; row < raw_height; row++) {
1727 fseek (ifp, data_offset + offset[row], SEEK_SET);
1729 pred[0] = pred[1] = 0;
1730 for (col=0; col < raw_width; col++) {
1731 if (col >= (raw_width & -8))
1732 len[0] = len[1] = 14;
1733 else if ((col & 7) == 0)
1734 for (i=0; i < 2; i++) {
1735 for (j=0; j < 5 && !ph1_bits(1); j++);
1736 if (j--) len[i] = length[j*2 + ph1_bits(1)];
1738 if ((i = len[col & 1]) == 14)
1739 pixel[col] = pred[col & 1] = ph1_bits(16);
1741 pixel[col] = pred[col & 1] += ph1_bits(i) + 1 - (1 << (i - 1));
1742 if (pred[col & 1] >> 16) derror();
1743 if (ph1.format == 5 && pixel[col] < 256)
1744 pixel[col] = curve[pixel[col]];
1746 for (col=0; col < raw_width; col++) {
1747 i = (pixel[col] << 2*(ph1.format != 8)) - ph1.black
1748 + cblack[row][col >= ph1.split_col]
1749 + rblack[col][row >= ph1.split_row];
1750 if (i > 0) RAW(row,col) = i;
1754 maximum = 0xfffc - ph1.black;
1757 void CLASS hasselblad_load_raw()
1760 int shot, row, col, *back[5], len[2], diff[12], pred, sh, f, s, c;
1761 unsigned upix, urow, ucol;
1764 if (!ljpeg_start (&jh, 0)) return;
1767 back[4] = (int *) calloc (raw_width, 3*sizeof **back);
1768 merror (back[4], "hasselblad_load_raw()");
1769 FORC3 back[c] = back[4] + c*raw_width;
1770 cblack[6] >>= sh = tiff_samples > 1;
1771 shot = LIM(shot_select, 1, tiff_samples) - 1;
1772 for (row=0; row < raw_height; row++) {
1773 FORC4 back[(c+3) & 3] = back[c];
1774 for (col=0; col < raw_width; col+=2) {
1775 for (s=0; s < tiff_samples*2; s+=2) {
1776 FORC(2) len[c] = ph1_huff(jh.huff[0]);
1778 diff[s+c] = ph1_bits(len[c]);
1779 if ((diff[s+c] & (1 << (len[c]-1))) == 0)
1780 diff[s+c] -= (1 << len[c]) - 1;
1781 if (diff[s+c] == 65535) diff[s+c] = -32768;
1784 for (s=col; s < col+2; s++) {
1785 pred = 0x8000 + load_flags;
1786 if (col) pred = back[2][s-2];
1787 if (col && row > 1) switch (jh.psv) {
1788 case 11: pred += back[0][s]/2 - back[0][s-2]/2; break;
1790 f = (row & 1)*3 ^ ((col+s) & 1);
1791 FORC (tiff_samples) {
1792 pred += diff[(s & 1)*tiff_samples+c];
1793 upix = pred >> sh & 0xffff;
1794 if (raw_image && c == shot)
1797 urow = row-top_margin + (c & 1);
1798 ucol = col-left_margin - ((c >> 1) & 1);
1799 ip = &image[urow*width+ucol][f];
1800 if (urow < height && ucol < width)
1801 *ip = c < 4 ? upix : (*ip + upix) >> 1;
1810 if (image) mix_green = 1;
1813 void CLASS leaf_hdr_load_raw()
1816 unsigned tile=0, r, c, row, col;
1819 pixel = (ushort *) calloc (raw_width, sizeof *pixel);
1820 merror (pixel, "leaf_hdr_load_raw()");
1823 for (r=0; r < raw_height; r++) {
1824 if (r % tile_length == 0) {
1825 fseek (ifp, data_offset + 4*tile++, SEEK_SET);
1826 fseek (ifp, get4(), SEEK_SET);
1828 if (filters && c != shot_select) continue;
1829 if (filters) pixel = raw_image + r*raw_width;
1830 read_shorts (pixel, raw_width);
1831 if (!filters && (row = r - top_margin) < height)
1832 for (col=0; col < width; col++)
1833 image[row*width+col][c] = pixel[col+left_margin];
1842 void CLASS unpacked_load_raw()
1844 int row, col, bits=0;
1846 while (1 << ++bits < maximum);
1847 read_shorts (raw_image, raw_width*raw_height);
1848 for (row=0; row < raw_height; row++)
1849 for (col=0; col < raw_width; col++)
1850 if ((RAW(row,col) >>= load_flags) >> bits
1851 && (unsigned) (row-top_margin) < height
1852 && (unsigned) (col-left_margin) < width) derror();
1855 void CLASS sinar_4shot_load_raw()
1858 unsigned shot, row, col, r, c;
1861 shot = LIM (shot_select, 1, 4) - 1;
1862 fseek (ifp, data_offset + shot*4, SEEK_SET);
1863 fseek (ifp, get4(), SEEK_SET);
1864 unpacked_load_raw();
1867 pixel = (ushort *) calloc (raw_width, sizeof *pixel);
1868 merror (pixel, "sinar_4shot_load_raw()");
1869 for (shot=0; shot < 4; shot++) {
1870 fseek (ifp, data_offset + shot*4, SEEK_SET);
1871 fseek (ifp, get4(), SEEK_SET);
1872 for (row=0; row < raw_height; row++) {
1873 read_shorts (pixel, raw_width);
1874 if ((r = row-top_margin - (shot >> 1 & 1)) >= height) continue;
1875 for (col=0; col < raw_width; col++) {
1876 if ((c = col-left_margin - (shot & 1)) >= width) continue;
1877 image[r*width+c][(row & 1)*3 ^ (~col & 1)] = pixel[col];
1885 void CLASS imacon_full_load_raw()
1890 for (row=0; row < height; row++)
1891 for (col=0; col < width; col++)
1892 read_shorts (image[row*width+col], 3);
1895 void CLASS packed_load_raw()
1897 int vbits=0, bwide, rbits, bite, half, irow, row, col, val, i;
1900 bwide = raw_width * tiff_bps / 8;
1901 bwide += bwide & load_flags >> 9;
1902 rbits = bwide * 8 - raw_width * tiff_bps;
1903 if (load_flags & 1) bwide = bwide * 16 / 15;
1904 bite = 8 + (load_flags & 56);
1905 half = (raw_height+1) >> 1;
1906 for (irow=0; irow < raw_height; irow++) {
1908 if (load_flags & 2 &&
1909 (row = irow % half * 2 + irow / half) == 1 &&
1911 if (vbits=0, tiff_compress)
1912 fseek (ifp, data_offset - (-half*bwide & -2048), SEEK_SET);
1914 fseek (ifp, 0, SEEK_END);
1915 fseek (ifp, ftell(ifp) >> 3 << 2, SEEK_SET);
1918 for (col=0; col < raw_width; col++) {
1919 for (vbits -= tiff_bps; vbits < 0; vbits += bite) {
1921 for (i=0; i < bite; i+=8)
1922 bitbuf |= ((UINT64) fgetc(ifp) << i);
1924 val = bitbuf << (64-tiff_bps-vbits) >> (64-tiff_bps);
1925 RAW(row,col ^ (load_flags >> 6 & 3)) = val;
1926 if (load_flags & 1 && (col % 10) == 9 && fgetc(ifp) &&
1927 row < height+top_margin && col < width+left_margin) derror();
1933 void CLASS nokia_load_raw()
1936 int rev, dwide, row, col, c;
1939 rev = 3 * (order == 0x4949);
1940 dwide = (raw_width * 5 + 1) / 4;
1941 data = (uchar *) malloc (dwide*2);
1942 merror (data, "nokia_load_raw()");
1943 for (row=0; row < raw_height; row++) {
1944 if (fread (data+dwide, 1, dwide, ifp) < dwide) derror();
1945 FORC(dwide) data[c] = data[dwide+(c ^ rev)];
1946 for (dp=data, col=0; col < raw_width; dp+=5, col+=4)
1947 FORC4 RAW(row,col+c) = (dp[c] << 2) | (dp[4] >> (c << 1) & 3);
1951 if (strcmp(make,"OmniVision")) return;
1954 sum[ c & 1] += SQR(RAW(row,c)-RAW(row+1,c+1));
1955 sum[~c & 1] += SQR(RAW(row+1,c)-RAW(row,c+1));
1957 if (sum[1] > sum[0]) filters = 0x4b4b4b4b;
1960 void CLASS canon_rmf_load_raw()
1962 int row, col, bits, orow, ocol, c;
1964 for (row=0; row < raw_height; row++)
1965 for (col=0; col < raw_width-2; col+=3) {
1969 if ((ocol = col+c-4) < 0) {
1971 if ((orow -= 2) < 0)
1974 RAW(orow,ocol) = curve[bits >> (10*c+2) & 0x3ff];
1977 maximum = curve[0x3ff];
1980 unsigned CLASS pana_bits (int nbits)
1982 uchar *buf = pana_buf;
1983 int vbits = pana_vbits;
1986 if (!nbits) return pana_vbits=0;
1988 fread (buf+load_flags, 1, 0x4000-load_flags, ifp);
1989 fread (buf, 1, load_flags, ifp);
1991 vbits = (vbits - nbits) & 0x1ffff;
1992 byte = vbits >> 3 ^ 0x3ff0;
1994 return (buf[byte] | buf[byte+1] << 8) >> (vbits & 7) & ~(-1 << nbits);
1997 void CLASS panasonic_load_raw()
1999 int row, col, i, j, sh=0, pred[2], nonz[2];
2002 for (row=0; row < height; row++)
2003 for (col=0; col < raw_width; col++) {
2004 if ((i = col % 14) == 0)
2005 pred[0] = pred[1] = nonz[0] = nonz[1] = 0;
2006 if (i % 3 == 2) sh = 4 >> (3 - pana_bits(2));
2008 if ((j = pana_bits(8))) {
2009 if ((pred[i & 1] -= 0x80 << sh) < 0 || sh == 4)
2010 pred[i & 1] &= ~(-1 << sh);
2011 pred[i & 1] += j << sh;
2013 } else if ((nonz[i & 1] = pana_bits(8)) || i > 11)
2014 pred[i & 1] = nonz[i & 1] << 4 | pana_bits(4);
2015 if ((RAW(row,col) = pred[col & 1]) > 4098 && col < width) derror();
2019 void CLASS olympus_load_raw()
2022 int row, col, nbits, sign, low, high, i, c, w, n, nw;
2023 int acarry[2][3], *carry, pred, diff;
2027 FORC(2048 >> i) huff[++n] = (i+1) << 8 | i;
2028 fseek (ifp, 7, SEEK_CUR);
2030 for (row=0; row < height; row++) {
2031 memset (acarry, 0, sizeof acarry);
2032 for (col=0; col < raw_width; col++) {
2033 carry = acarry[col & 1];
2034 i = 2 * (carry[2] < 3);
2035 for (nbits=2+i; (ushort) carry[0] >> (nbits+i); nbits++);
2036 low = (sign = getbits(3)) & 3;
2037 sign = sign << 29 >> 31;
2038 if ((high = getbithuff(12,huff)) == 12)
2039 high = getbits(16-nbits) >> 1;
2040 carry[0] = (high << nbits) | getbits(nbits);
2041 diff = (carry[0] ^ sign) + carry[1];
2042 carry[1] = (diff*3 + carry[1]) >> 5;
2043 carry[2] = carry[0] > 16 ? 0 : carry[2]+1;
2044 if (col >= width) continue;
2045 if (row < 2 && col < 2) pred = 0;
2046 else if (row < 2) pred = RAW(row,col-2);
2047 else if (col < 2) pred = RAW(row-2,col);
2051 nw = RAW(row-2,col-2);
2052 if ((w < nw && nw < n) || (n < nw && nw < w)) {
2053 if (ABS(w-nw) > 32 || ABS(n-nw) > 32)
2055 else pred = (w + n) >> 1;
2056 } else pred = ABS(w-nw) > ABS(n-nw) ? w : n;
2058 if ((RAW(row,col) = pred + ((diff << 2) | low)) >> 12) derror();
2063 void CLASS canon_crx_load_raw()
2067 void CLASS fuji_xtrans_load_raw()
2071 void CLASS minolta_rd175_load_raw()
2074 unsigned irow, box, row, col;
2076 for (irow=0; irow < 1481; irow++) {
2077 if (fread (pixel, 1, 768, ifp) < 768) derror();
2079 row = irow % 82 * 12 + ((box < 12) ? box | 1 : (box-12)*2);
2081 case 1477: case 1479: continue;
2082 case 1476: row = 984; break;
2083 case 1480: row = 985; break;
2084 case 1478: row = 985; box = 1;
2086 if ((box < 12) && (box & 1)) {
2087 for (col=0; col < 1533; col++, row ^= 1)
2088 if (col != 1) RAW(row,col) = (col+1) & 2 ?
2089 pixel[col/2-1] + pixel[col/2+1] : pixel[col/2] << 1;
2090 RAW(row,1) = pixel[1] << 1;
2091 RAW(row,1533) = pixel[765] << 1;
2093 for (col=row & 1; col < 1534; col+=2)
2094 RAW(row,col) = pixel[col/2] << 1;
2096 maximum = 0xff << 1;
2099 void CLASS quicktake_100_load_raw()
2101 uchar pixel[484][644];
2102 static const short gstep[16] =
2103 { -89,-60,-44,-32,-22,-15,-8,-2,2,8,15,22,32,44,60,89 };
2104 static const short rstep[6][4] =
2105 { { -3,-1,1,3 }, { -5,-1,1,5 }, { -8,-2,2,8 },
2106 { -13,-3,3,13 }, { -19,-4,4,19 }, { -28,-6,6,28 } };
2107 static const short curve[256] =
2108 { 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,
2109 28,29,30,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,53,
2110 54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,74,75,76,77,78,
2111 79,80,81,82,83,84,86,88,90,92,94,97,99,101,103,105,107,110,112,114,116,
2112 118,120,123,125,127,129,131,134,136,138,140,142,144,147,149,151,153,155,
2113 158,160,162,164,166,168,171,173,175,177,179,181,184,186,188,190,192,195,
2114 197,199,201,203,205,208,210,212,214,216,218,221,223,226,230,235,239,244,
2115 248,252,257,261,265,270,274,278,283,287,291,296,300,305,309,313,318,322,
2116 326,331,335,339,344,348,352,357,361,365,370,374,379,383,387,392,396,400,
2117 405,409,413,418,422,426,431,435,440,444,448,453,457,461,466,470,474,479,
2118 483,487,492,496,500,508,519,531,542,553,564,575,587,598,609,620,631,643,
2119 654,665,676,687,698,710,721,732,743,754,766,777,788,799,810,822,833,844,
2120 855,866,878,889,900,911,922,933,945,956,967,978,989,1001,1012,1023 };
2121 int rb, row, col, sharp, val=0;
2124 memset (pixel, 0x80, sizeof pixel);
2125 for (row=2; row < height+2; row++) {
2126 for (col=2+(row & 1); col < width+2; col+=2) {
2127 val = ((pixel[row-1][col-1] + 2*pixel[row-1][col+1] +
2128 pixel[row][col-2]) >> 2) + gstep[getbits(4)];
2129 pixel[row][col] = val = LIM(val,0,255);
2131 pixel[row][col-2] = pixel[row+1][~row & 1] = val;
2133 pixel[row-1][col+1] = pixel[row-1][col+3] = val;
2135 pixel[row][col] = val;
2137 for (rb=0; rb < 2; rb++)
2138 for (row=2+rb; row < height+2; row+=2)
2139 for (col=3-(row & 1); col < width+2; col+=2) {
2140 if (row < 4 || col < 4) sharp = 2;
2142 val = ABS(pixel[row-2][col] - pixel[row][col-2])
2143 + ABS(pixel[row-2][col] - pixel[row-2][col-2])
2144 + ABS(pixel[row][col-2] - pixel[row-2][col-2]);
2145 sharp = val < 4 ? 0 : val < 8 ? 1 : val < 16 ? 2 :
2146 val < 32 ? 3 : val < 48 ? 4 : 5;
2148 val = ((pixel[row-2][col] + pixel[row][col-2]) >> 1)
2149 + rstep[sharp][getbits(2)];
2150 pixel[row][col] = val = LIM(val,0,255);
2151 if (row < 4) pixel[row-2][col+2] = val;
2152 if (col < 4) pixel[row+2][col-2] = val;
2154 for (row=2; row < height+2; row++)
2155 for (col=3-(row & 1); col < width+2; col+=2) {
2156 val = ((pixel[row][col-1] + (pixel[row][col] << 2) +
2157 pixel[row][col+1]) >> 1) - 0x100;
2158 pixel[row][col] = LIM(val,0,255);
2160 for (row=0; row < height; row++)
2161 for (col=0; col < width; col++)
2162 RAW(row,col) = curve[pixel[row+2][col+2]];
2166 #define radc_token(tree) ((signed char) getbithuff(8,huff[tree]))
2168 #define FORYX for (y=1; y < 3; y++) for (x=col+1; x >= col; x--)
2170 #define PREDICTOR (c ? (buf[c][y-1][x] + buf[c][y][x+1]) / 2 \
2171 : (buf[c][y-1][x+1] + 2*buf[c][y-1][x] + buf[c][y][x+1]) / 4)
2173 void CLASS kodak_radc_load_raw()
2175 static const char src[] = {
2176 1,1, 2,3, 3,4, 4,2, 5,7, 6,5, 7,6, 7,8,
2177 1,0, 2,1, 3,3, 4,4, 5,2, 6,7, 7,6, 8,5, 8,8,
2178 2,1, 2,3, 3,0, 3,2, 3,4, 4,6, 5,5, 6,7, 6,8,
2179 2,0, 2,1, 2,3, 3,2, 4,4, 5,6, 6,7, 7,5, 7,8,
2180 2,1, 2,4, 3,0, 3,2, 3,3, 4,7, 5,5, 6,6, 6,8,
2181 2,3, 3,1, 3,2, 3,4, 3,5, 3,6, 4,7, 5,0, 5,8,
2182 2,3, 2,6, 3,0, 3,1, 4,4, 4,5, 4,7, 5,2, 5,8,
2183 2,4, 2,7, 3,3, 3,6, 4,1, 4,2, 4,5, 5,0, 5,8,
2184 2,6, 3,1, 3,3, 3,5, 3,7, 3,8, 4,0, 5,2, 5,4,
2185 2,0, 2,1, 3,2, 3,3, 4,4, 4,5, 5,6, 5,7, 4,8,
2188 2,-17, 2,-5, 2,5, 2,17,
2189 2,-7, 2,2, 2,9, 2,18,
2190 2,-18, 2,-9, 2,-2, 2,7,
2191 2,-28, 2,28, 3,-49, 3,-9, 3,9, 4,49, 5,-79, 5,79,
2192 2,-1, 2,13, 2,26, 3,39, 4,-16, 5,55, 6,-37, 6,76,
2193 2,-26, 2,-13, 2,1, 3,-39, 4,16, 5,-55, 6,-76, 6,37
2195 ushort huff[19][256];
2196 int row, col, tree, nreps, rep, step, i, c, s, r, x, y, val;
2197 short last[3] = { 16,16,16 }, mul[3], buf[3][3][386];
2198 static const ushort pt[] =
2199 { 0,0, 1280,1344, 2320,3616, 3328,8000, 4095,16383, 65535,16383 };
2201 for (i=2; i < 12; i+=2)
2202 for (c=pt[i-2]; c <= pt[i]; c++)
2204 (c-pt[i-2]) / (pt[i]-pt[i-2]) * (pt[i+1]-pt[i-1]) + pt[i-1] + 0.5;
2205 for (s=i=0; i < sizeof src; i+=2)
2207 ((ushort *)huff)[s++] = src[i] << 8 | (uchar) src[i+1];
2208 s = kodak_cbpp == 243 ? 2 : 3;
2209 FORC(256) huff[18][c] = (8-s) << 8 | c >> s << s | 1 << (s-1);
2211 for (i=0; i < sizeof(buf)/sizeof(short); i++)
2212 ((short *)buf)[i] = 2048;
2213 for (row=0; row < height; row+=4) {
2214 FORC3 mul[c] = getbits(6);
2216 val = ((0x1000000/last[c] + 0x7ff) >> 12) * mul[c];
2217 s = val > 65564 ? 10:12;
2220 for (i=0; i < sizeof(buf[0])/sizeof(short); i++)
2221 ((short *)buf[c])[i] = (((short *)buf[c])[i] * val + x) >> s;
2223 for (r=0; r <= !c; r++) {
2224 buf[c][1][width/2] = buf[c][2][width/2] = mul[c] << 7;
2225 for (tree=1, col=width/2; col > 0; ) {
2226 if ((tree = radc_token(tree))) {
2229 FORYX buf[c][y][x] = (uchar) radc_token(18) * mul[c];
2231 FORYX buf[c][y][x] = radc_token(tree+10) * 16 + PREDICTOR;
2234 nreps = (col > 2) ? radc_token(9) + 1 : 1;
2235 for (rep=0; rep < 8 && rep < nreps && col > 0; rep++) {
2237 FORYX buf[c][y][x] = PREDICTOR;
2239 step = radc_token(10) << 4;
2240 FORYX buf[c][y][x] += step;
2243 } while (nreps == 9);
2245 for (y=0; y < 2; y++)
2246 for (x=0; x < width/2; x++) {
2247 val = (buf[c][y+1][x] << 4) / mul[c];
2248 if (val < 0) val = 0;
2249 if (c) RAW(row+y*2+c-1,x*2+2-c) = val;
2250 else RAW(row+r*2+y,x*2+y) = val;
2252 memcpy (buf[c][0]+!c, buf[c][2], sizeof buf[c][0]-2*!c);
2255 for (y=row; y < row+4; y++)
2256 for (x=0; x < width; x++)
2259 s = x+1 < width ? x+1 : x-1;
2260 val = (RAW(y,x)-2048)*2 + (RAW(y,r)+RAW(y,s))/2;
2261 if (val < 0) val = 0;
2265 for (i=0; i < height*width; i++)
2266 raw_image[i] = curve[raw_image[i]];
2274 void CLASS kodak_jpeg_load_raw() {}
2275 void CLASS lossy_dng_load_raw() {}
2279 fill_input_buffer (j_decompress_ptr cinfo)
2281 static uchar jpeg_buffer[4096];
2284 nbytes = fread (jpeg_buffer, 1, 4096, ifp);
2285 swabb(jpeg_buffer, jpeg_buffer, nbytes);
2286 cinfo->src->next_input_byte = jpeg_buffer;
2287 cinfo->src->bytes_in_buffer = nbytes;
2291 void CLASS kodak_jpeg_load_raw()
2293 struct jpeg_decompress_struct cinfo;
2294 struct jpeg_error_mgr jerr;
2296 JSAMPLE (*pixel)[3];
2299 cinfo.err = jpeg_std_error (&jerr);
2300 jpeg_create_decompress (&cinfo);
2301 jpeg_stdio_src (&cinfo, ifp);
2302 cinfo.src->fill_input_buffer = fill_input_buffer;
2303 jpeg_read_header (&cinfo, TRUE);
2304 jpeg_start_decompress (&cinfo);
2305 if ((cinfo.output_width != width ) ||
2306 (cinfo.output_height*2 != height ) ||
2307 (cinfo.output_components != 3 )) {
2308 fprintf (stderr,_("%s: incorrect JPEG dimensions\n"), ifname);
2309 jpeg_destroy_decompress (&cinfo);
2310 longjmp (failure, 3);
2312 buf = (*cinfo.mem->alloc_sarray)
2313 ((j_common_ptr) &cinfo, JPOOL_IMAGE, width*3, 1);
2315 while (cinfo.output_scanline < cinfo.output_height) {
2316 row = cinfo.output_scanline * 2;
2317 jpeg_read_scanlines (&cinfo, buf, 1);
2318 pixel = (JSAMPLE (*)[3]) buf[0];
2319 for (col=0; col < width; col+=2) {
2320 RAW(row+0,col+0) = pixel[col+0][1] << 1;
2321 RAW(row+1,col+1) = pixel[col+1][1] << 1;
2322 RAW(row+0,col+1) = pixel[col][0] + pixel[col+1][0];
2323 RAW(row+1,col+0) = pixel[col][2] + pixel[col+1][2];
2326 jpeg_finish_decompress (&cinfo);
2327 jpeg_destroy_decompress (&cinfo);
2328 maximum = 0xff << 1;
2331 void CLASS gamma_curve (double pwr, double ts, int mode, int imax);
2333 void CLASS lossy_dng_load_raw()
2335 struct jpeg_decompress_struct cinfo;
2336 struct jpeg_error_mgr jerr;
2338 JSAMPLE (*pixel)[3];
2339 unsigned sorder=order, ntags, opcode, deg, i, j, c;
2340 unsigned save=data_offset-4, trow=0, tcol=0, row, col;
2342 double coeff[9], tot;
2345 fseek (ifp, meta_offset, SEEK_SET);
2349 opcode = get4(); get4(); get4();
2351 { fseek (ifp, get4(), SEEK_CUR); continue; }
2352 fseek (ifp, 20, SEEK_CUR);
2353 if ((c = get4()) > 2) break;
2354 fseek (ifp, 12, SEEK_CUR);
2355 if ((deg = get4()) > 8) break;
2356 for (i=0; i <= deg && i < 9; i++)
2357 coeff[i] = getreal(12);
2358 for (i=0; i < 256; i++) {
2359 for (tot=j=0; j <= deg; j++)
2360 tot += coeff[j] * pow(i/255.0, j);
2361 cur[c][i] = tot*0xffff;
2366 gamma_curve (1/2.4, 12.92, 1, 255);
2367 FORC3 memcpy (cur[c], curve, sizeof cur[0]);
2369 cinfo.err = jpeg_std_error (&jerr);
2370 jpeg_create_decompress (&cinfo);
2371 while (trow < raw_height) {
2372 fseek (ifp, save+=4, SEEK_SET);
2373 if (tile_length < INT_MAX)
2374 fseek (ifp, get4(), SEEK_SET);
2375 jpeg_stdio_src (&cinfo, ifp);
2376 jpeg_read_header (&cinfo, TRUE);
2377 jpeg_start_decompress (&cinfo);
2378 buf = (*cinfo.mem->alloc_sarray)
2379 ((j_common_ptr) &cinfo, JPOOL_IMAGE, cinfo.output_width*3, 1);
2380 while (cinfo.output_scanline < cinfo.output_height &&
2381 (row = trow + cinfo.output_scanline) < height) {
2382 jpeg_read_scanlines (&cinfo, buf, 1);
2383 pixel = (JSAMPLE (*)[3]) buf[0];
2384 for (col=0; col < cinfo.output_width && tcol+col < width; col++) {
2385 FORC3 image[row*width+tcol+col][c] = cur[c][pixel[col][c]];
2388 jpeg_abort_decompress (&cinfo);
2389 if ((tcol += tile_width) >= raw_width)
2390 trow += tile_length + (tcol = 0);
2392 jpeg_destroy_decompress (&cinfo);
2397 void CLASS kodak_dc120_load_raw()
2399 static const int mul[4] = { 162, 192, 187, 92 };
2400 static const int add[4] = { 0, 636, 424, 212 };
2402 int row, shift, col;
2404 for (row=0; row < height; row++) {
2405 if (fread (pixel, 1, 848, ifp) < 848) derror();
2406 shift = row * mul[row & 3] + add[row & 3];
2407 for (col=0; col < width; col++)
2408 RAW(row,col) = (ushort) pixel[(col + shift) % 848];
2413 void CLASS eight_bit_load_raw()
2418 pixel = (uchar *) calloc (raw_width, sizeof *pixel);
2419 merror (pixel, "eight_bit_load_raw()");
2420 for (row=0; row < raw_height; row++) {
2421 if (fread (pixel, 1, raw_width, ifp) < raw_width) derror();
2422 for (col=0; col < raw_width; col++)
2423 RAW(row,col) = curve[pixel[col]];
2426 maximum = curve[0xff];
2429 void CLASS kodak_c330_load_raw()
2432 int row, col, y, cb, cr, rgb[3], c;
2434 pixel = (uchar *) calloc (raw_width, 2*sizeof *pixel);
2435 merror (pixel, "kodak_c330_load_raw()");
2436 for (row=0; row < height; row++) {
2437 if (fread (pixel, raw_width, 2, ifp) < 2) derror();
2438 if (load_flags && (row & 31) == 31)
2439 fseek (ifp, raw_width*32, SEEK_CUR);
2440 for (col=0; col < width; col++) {
2442 cb = pixel[(col*2 & -4) | 1] - 128;
2443 cr = pixel[(col*2 & -4) | 3] - 128;
2444 rgb[1] = y - ((cb + cr + 2) >> 2);
2445 rgb[2] = rgb[1] + cb;
2446 rgb[0] = rgb[1] + cr;
2447 FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,255)];
2451 maximum = curve[0xff];
2454 void CLASS kodak_c603_load_raw()
2457 int row, col, y, cb, cr, rgb[3], c;
2459 pixel = (uchar *) calloc (raw_width, 3*sizeof *pixel);
2460 merror (pixel, "kodak_c603_load_raw()");
2461 for (row=0; row < height; row++) {
2463 if (fread (pixel, raw_width, 3, ifp) < 3) derror();
2464 for (col=0; col < width; col++) {
2465 y = pixel[width*2*(row & 1) + col];
2466 cb = pixel[width + (col & -2)] - 128;
2467 cr = pixel[width + (col & -2)+1] - 128;
2468 rgb[1] = y - ((cb + cr + 2) >> 2);
2469 rgb[2] = rgb[1] + cb;
2470 rgb[0] = rgb[1] + cr;
2471 FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,255)];
2475 maximum = curve[0xff];
2478 void CLASS kodak_262_load_raw()
2480 static const uchar kodak_tree[2][26] =
2481 { { 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 },
2482 { 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 } };
2485 int *strip, ns, c, row, col, chess, pi=0, pi1, pi2, pred, val;
2487 FORC(2) huff[c] = make_decoder (kodak_tree[c]);
2488 ns = (raw_height+63) >> 5;
2489 pixel = (uchar *) malloc (raw_width*32 + ns*4);
2490 merror (pixel, "kodak_262_load_raw()");
2491 strip = (int *) (pixel + raw_width*32);
2493 FORC(ns) strip[c] = get4();
2494 for (row=0; row < raw_height; row++) {
2495 if ((row & 31) == 0) {
2496 fseek (ifp, strip[row >> 5], SEEK_SET);
2500 for (col=0; col < raw_width; col++) {
2501 chess = (row + col) & 1;
2502 pi1 = chess ? pi-2 : pi-raw_width-1;
2503 pi2 = chess ? pi-2*raw_width : pi-raw_width+1;
2504 if (col <= chess) pi1 = -1;
2505 if (pi1 < 0) pi1 = pi2;
2506 if (pi2 < 0) pi2 = pi1;
2507 if (pi1 < 0 && col > 1) pi1 = pi2 = pi-2;
2508 pred = (pi1 < 0) ? 0 : (pixel[pi1] + pixel[pi2]) >> 1;
2509 pixel[pi] = val = pred + ljpeg_diff (huff[chess]);
2510 if (val >> 8) derror();
2511 val = curve[pixel[pi++]];
2516 FORC(2) free (huff[c]);
2519 int CLASS kodak_65000_decode (short *out, int bsize)
2524 int save, bits=0, i, j, len, diff;
2527 bsize = (bsize + 3) & -4;
2528 for (i=0; i < bsize; i+=2) {
2530 if ((blen[i ] = c & 15) > 12 ||
2531 (blen[i+1] = c >> 4) > 12 ) {
2532 fseek (ifp, save, SEEK_SET);
2533 for (i=0; i < bsize; i+=8) {
2534 read_shorts (raw, 6);
2535 out[i ] = raw[0] >> 12 << 8 | raw[2] >> 12 << 4 | raw[4] >> 12;
2536 out[i+1] = raw[1] >> 12 << 8 | raw[3] >> 12 << 4 | raw[5] >> 12;
2537 for (j=0; j < 6; j++)
2538 out[i+2+j] = raw[j] & 0xfff;
2543 if ((bsize & 7) == 4) {
2544 bitbuf = fgetc(ifp) << 8;
2545 bitbuf += fgetc(ifp);
2548 for (i=0; i < bsize; i++) {
2551 for (j=0; j < 32; j+=8)
2552 bitbuf += (INT64) fgetc(ifp) << (bits+(j^8));
2555 diff = bitbuf & (0xffff >> (16-len));
2558 if ((diff & (1 << (len-1))) == 0)
2559 diff -= (1 << len) - 1;
2565 void CLASS kodak_65000_load_raw()
2568 int row, col, len, pred[2], ret, i;
2570 for (row=0; row < height; row++)
2571 for (col=0; col < width; col+=256) {
2572 pred[0] = pred[1] = 0;
2573 len = MIN (256, width-col);
2574 ret = kodak_65000_decode (buf, len);
2575 for (i=0; i < len; i++)
2576 if ((RAW(row,col+i) = curve[ret ? buf[i] :
2577 (pred[i & 1] += buf[i])]) >> 12) derror();
2581 void CLASS kodak_ycbcr_load_raw()
2583 short buf[384], *bp;
2584 int row, col, len, c, i, j, k, y[2][2], cb, cr, rgb[3];
2588 for (row=0; row < height; row+=2)
2589 for (col=0; col < width; col+=128) {
2590 len = MIN (128, width-col);
2591 kodak_65000_decode (buf, len*3);
2592 y[0][1] = y[1][1] = cb = cr = 0;
2593 for (bp=buf, i=0; i < len; i+=2, bp+=2) {
2596 rgb[1] = -((cb + cr + 2) >> 2);
2597 rgb[2] = rgb[1] + cb;
2598 rgb[0] = rgb[1] + cr;
2599 for (j=0; j < 2; j++)
2600 for (k=0; k < 2; k++) {
2601 if ((y[j][k] = y[j][k^1] + *bp++) >> 10) derror();
2602 ip = image[(row+j)*width + col+i+k];
2603 FORC3 ip[c] = curve[LIM(y[j][k]+rgb[c], 0, 0xfff)];
2609 void CLASS kodak_rgb_load_raw()
2611 short buf[768], *bp;
2612 int row, col, len, c, i, rgb[3];
2613 ushort *ip=image[0];
2615 for (row=0; row < height; row++)
2616 for (col=0; col < width; col+=256) {
2617 len = MIN (256, width-col);
2618 kodak_65000_decode (buf, len*3);
2619 memset (rgb, 0, sizeof rgb);
2620 for (bp=buf, i=0; i < len; i++, ip+=4)
2621 FORC3 if ((ip[c] = rgb[c] += *bp++) >> 12) derror();
2625 void CLASS kodak_thumb_load_raw()
2628 colors = thumb_misc >> 5;
2629 for (row=0; row < height; row++)
2630 for (col=0; col < width; col++)
2631 read_shorts (image[row*width+col], colors);
2632 maximum = (1 << (thumb_misc & 31)) - 1;
2635 void CLASS sony_decrypt (unsigned *data, int len, int start, int key)
2637 unsigned p = sony_p, *pad = sony_pad;;
2639 for (p=0; p < 4; p++)
2640 pad[p] = key = key * 48828125 + 1;
2641 pad[3] = pad[3] << 1 | (pad[0]^pad[2]) >> 31;
2642 for (p=4; p < 127; p++)
2643 pad[p] = (pad[p-4]^pad[p-2]) << 1 | (pad[p-3]^pad[p-1]) >> 31;
2644 for (p=0; p < 127; p++)
2645 pad[p] = htonl(pad[p]);
2647 while (len-- && p++)
2648 *data++ ^= pad[(p-1) & 127] = pad[p & 127] ^ pad[(p+64) & 127];
2652 void CLASS sony_load_raw()
2656 unsigned i, key, row, col;
2658 fseek (ifp, 200896, SEEK_SET);
2659 fseek (ifp, (unsigned) fgetc(ifp)*4 - 1, SEEK_CUR);
2662 fseek (ifp, 164600, SEEK_SET);
2663 fread (head, 1, 40, ifp);
2664 sony_decrypt ((unsigned *) head, 10, 1, key);
2665 for (i=26; i-- > 22; )
2666 key = key << 8 | head[i];
2667 fseek (ifp, data_offset, SEEK_SET);
2668 for (row=0; row < raw_height; row++) {
2669 pixel = raw_image + row*raw_width;
2670 if (fread (pixel, 2, raw_width, ifp) < raw_width) derror();
2671 sony_decrypt ((unsigned *) pixel, raw_width/2, !row, key);
2672 for (col=0; col < raw_width; col++)
2673 if ((pixel[col] = ntohs(pixel[col])) >> 14) derror();
2678 void CLASS sony_arw_load_raw()
2681 static const ushort tab[18] =
2682 { 0xf11,0xf10,0xe0f,0xd0e,0xc0d,0xb0c,0xa0b,0x90a,0x809,
2683 0x708,0x607,0x506,0x405,0x304,0x303,0x300,0x202,0x201 };
2684 int i, c, n, col, row, sum=0;
2687 for (n=i=0; i < 18; i++)
2688 FORC(32768 >> (tab[i] >> 8)) huff[++n] = tab[i];
2690 for (col = raw_width; col--; )
2691 for (row=0; row < raw_height+1; row+=2) {
2692 if (row == raw_height) row = 1;
2693 if ((sum += ljpeg_diff(huff)) >> 12) derror();
2694 if (row < height) RAW(row,col) = sum;
2698 void CLASS sony_arw2_load_raw()
2702 int row, col, val, max, min, imax, imin, sh, bit, i;
2704 data = (uchar *) malloc (raw_width+1);
2705 merror (data, "sony_arw2_load_raw()");
2706 for (row=0; row < height; row++) {
2707 fread (data, 1, raw_width, ifp);
2708 for (dp=data, col=0; col < raw_width-30; dp+=16) {
2709 max = 0x7ff & (val = sget4(dp));
2710 min = 0x7ff & val >> 11;
2711 imax = 0x0f & val >> 22;
2712 imin = 0x0f & val >> 26;
2713 for (sh=0; sh < 4 && 0x80 << sh <= max-min; sh++);
2714 for (bit=30, i=0; i < 16; i++)
2715 if (i == imax) pix[i] = max;
2716 else if (i == imin) pix[i] = min;
2718 pix[i] = ((sget2(dp+(bit >> 3)) >> (bit & 7) & 0x7f) << sh) + min;
2719 if (pix[i] > 0x7ff) pix[i] = 0x7ff;
2722 for (i=0; i < 16; i++, col+=2)
2723 RAW(row,col) = curve[pix[i] << 1] >> 2;
2724 col -= col & 1 ? 1:31;
2730 void CLASS samsung_load_raw()
2732 int row, col, c, i, dir, op[4], len[4];
2735 for (row=0; row < raw_height; row++) {
2736 fseek (ifp, strip_offset+row*4, SEEK_SET);
2737 fseek (ifp, data_offset+get4(), SEEK_SET);
2739 FORC4 len[c] = row < 2 ? 7:4;
2740 for (col=0; col < raw_width; col+=16) {
2742 FORC4 op[c] = ph1_bits(2);
2743 FORC4 switch (op[c]) {
2744 case 3: len[c] = ph1_bits(4); break;
2745 case 2: len[c]--; break;
2748 for (c=0; c < 16; c+=2) {
2749 i = len[((c & 1) << 1) | (c >> 3)];
2750 RAW(row,col+c) = ((signed) ph1_bits(i) << (32-i) >> (32-i)) +
2751 (dir ? RAW(row+(~c | -2),col+c) : col ? RAW(row,col+(c | -2)) : 128);
2752 if (c == 14) c = -1;
2756 for (row=0; row < raw_height-1; row+=2)
2757 for (col=0; col < raw_width-1; col+=2)
2758 SWAP (RAW(row,col+1), RAW(row+1,col));
2761 void CLASS samsung2_load_raw()
2763 static const ushort tab[14] =
2764 { 0x304,0x307,0x206,0x205,0x403,0x600,0x709,
2765 0x80a,0x90b,0xa0c,0xa0d,0x501,0x408,0x402 };
2766 ushort huff[1026], vpred[2][2] = {{0,0},{0,0}}, hpred[2];
2767 int i, c, n, row, col, diff;
2770 for (n=i=0; i < 14; i++)
2771 FORC(1024 >> (tab[i] >> 8)) huff[++n] = tab[i];
2773 for (row=0; row < raw_height; row++)
2774 for (col=0; col < raw_width; col++) {
2775 diff = ljpeg_diff (huff);
2776 if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
2777 else hpred[col & 1] += diff;
2778 RAW(row,col) = hpred[col & 1];
2779 if (hpred[col & 1] >> tiff_bps) derror();
2783 void CLASS samsung3_load_raw()
2785 int opt, init, mag, pmode, row, tab, col, pred, diff, i, c;
2786 ushort lent[3][2], len[4], *prow[2];
2789 fseek (ifp, 9, SEEK_CUR);
2791 init = (get2(),get2());
2792 for (row=0; row < raw_height; row++) {
2793 fseek (ifp, (data_offset-ftell(ifp)) & 15, SEEK_CUR);
2796 FORC(6) ((ushort *)lent)[c] = row < 2 ? 7:4;
2797 prow[ row & 1] = &RAW(row-1,1-((row & 1) << 1)); // green
2798 prow[~row & 1] = &RAW(row-2,0); // red and blue
2799 for (tab=0; tab+15 < raw_width; tab+=16) {
2800 if (~opt & 4 && !(tab & 63)) {
2802 mag = i < 3 ? mag-'2'+"204"[i] : ph1_bits(12);
2805 pmode = 7 - 4*ph1_bits(1);
2806 else if (!ph1_bits(1))
2807 pmode = ph1_bits(3);
2808 if (opt & 1 || !ph1_bits(1)) {
2809 FORC4 len[c] = ph1_bits(2);
2811 i = ((row & 1) << 1 | (c & 1)) % 3;
2812 len[c] = len[c] < 3 ? lent[i][0]-'1'+"120"[len[c]] : ph1_bits(4);
2813 lent[i][0] = lent[i][1];
2814 lent[i][1] = len[c];
2818 col = tab + (((c & 7) << 1)^(c >> 3)^(row & 1));
2819 pred = (pmode == 7 || row < 2)
2820 ? (tab ? RAW(row,tab-2+(col & 1)) : init)
2821 : (prow[col & 1][col-'4'+"0224468"[pmode]] +
2822 prow[col & 1][col-'4'+"0244668"[pmode]] + 1) >> 1;
2823 diff = ph1_bits (i = len[c >> 2]);
2824 if (diff >> (i-1)) diff -= 1 << i;
2825 diff = diff * (mag*2+1) + mag;
2826 RAW(row,col) = pred + diff;
2832 #define HOLE(row) ((holes >> (((row) - raw_height) & 7)) & 1)
2834 /* Kudos to Rich Taylor for figuring out SMaL's compression algorithm. */
2835 void CLASS smal_decode_segment (unsigned seg[2][2], int holes)
2837 uchar hist[3][18] = {
2838 { 7, 7, 0, 0, 63, 55, 47, 39, 31, 23, 15, 7, 0 },
2839 { 7, 7, 0, 0, 63, 55, 47, 39, 31, 23, 15, 7, 0 },
2840 { 3, 3, 0, 0, 63, 47, 31, 15, 0 } };
2841 int low, high=0xff, carry=0, nbits=8;
2842 int pix, s, count, bin, next, i, sym[3];
2843 uchar diff, pred[]={0,0};
2844 ushort data=0, range=0;
2846 fseek (ifp, seg[0][1]+1, SEEK_SET);
2848 if (seg[1][0] > raw_width*raw_height)
2849 seg[1][0] = raw_width*raw_height;
2850 for (pix=seg[0][0]; pix < seg[1][0]; pix++) {
2851 for (s=0; s < 3; s++) {
2852 data = data << nbits | getbits(nbits);
2854 carry = (nbits += carry+1) < 1 ? nbits-1 : 0;
2855 while (--nbits >= 0)
2856 if ((data >> nbits & 0xff) == 0xff) break;
2858 data = ((data & ((1 << (nbits-1)) - 1)) << 1) |
2859 ((data + (((data & (1 << (nbits-1)))) << 1)) & (-1 << nbits));
2864 count = ((((data-range+1) & 0xffff) << 2) - 1) / (high >> 4);
2865 for (bin=0; hist[s][bin+5] > count; bin++);
2866 low = hist[s][bin+5] * (high >> 4) >> 2;
2867 if (bin) high = hist[s][bin+4] * (high >> 4) >> 2;
2869 for (nbits=0; high << nbits < 128; nbits++);
2870 range = (range+low) << nbits;
2873 if (++hist[s][2] > hist[s][3]) {
2874 next = (next+1) & hist[s][0];
2875 hist[s][3] = (hist[s][next+4] - hist[s][next+5]) >> 2;
2878 if (hist[s][hist[s][1]+4] - hist[s][hist[s][1]+5] > 1) {
2879 if (bin < hist[s][1])
2880 for (i=bin; i < hist[s][1]; i++) hist[s][i+5]--;
2881 else if (next <= bin)
2882 for (i=hist[s][1]; i < bin; i++) hist[s][i+5]++;
2887 diff = sym[2] << 5 | sym[1] << 2 | (sym[0] & 3);
2889 diff = diff ? -diff : 0x80;
2890 if (ftell(ifp) + 12 >= seg[1][1])
2892 raw_image[pix] = pred[pix & 1] += diff;
2893 if (!(pix & 1) && HOLE(pix / raw_width)) pix += 2;
2898 void CLASS smal_v6_load_raw()
2902 fseek (ifp, 16, SEEK_SET);
2905 seg[1][0] = raw_width * raw_height;
2906 seg[1][1] = INT_MAX;
2907 smal_decode_segment (seg, 0);
2910 int CLASS median4 (int *p)
2912 int min, max, sum, i;
2914 min = max = sum = p[0];
2915 for (i=1; i < 4; i++) {
2917 if (min > p[i]) min = p[i];
2918 if (max < p[i]) max = p[i];
2920 return (sum - min - max) >> 1;
2923 void CLASS fill_holes (int holes)
2925 int row, col, val[4];
2927 for (row=2; row < height-2; row++) {
2928 if (!HOLE(row)) continue;
2929 for (col=1; col < width-1; col+=4) {
2930 val[0] = RAW(row-1,col-1);
2931 val[1] = RAW(row-1,col+1);
2932 val[2] = RAW(row+1,col-1);
2933 val[3] = RAW(row+1,col+1);
2934 RAW(row,col) = median4(val);
2936 for (col=2; col < width-2; col+=4)
2937 if (HOLE(row-2) || HOLE(row+2))
2938 RAW(row,col) = (RAW(row,col-2) + RAW(row,col+2)) >> 1;
2940 val[0] = RAW(row,col-2);
2941 val[1] = RAW(row,col+2);
2942 val[2] = RAW(row-2,col);
2943 val[3] = RAW(row+2,col);
2944 RAW(row,col) = median4(val);
2949 void CLASS smal_v9_load_raw()
2951 unsigned seg[256][2], offset, nseg, holes, i;
2953 fseek (ifp, 67, SEEK_SET);
2955 nseg = (uchar) fgetc(ifp);
2956 fseek (ifp, offset, SEEK_SET);
2957 for (i=0; i < nseg*2; i++)
2958 ((unsigned *)seg)[i] = get4() + data_offset*(i & 1);
2959 fseek (ifp, 78, SEEK_SET);
2961 fseek (ifp, 88, SEEK_SET);
2962 seg[nseg][0] = raw_height * raw_width;
2963 seg[nseg][1] = get4() + data_offset;
2964 for (i=0; i < nseg; i++)
2965 smal_decode_segment (seg+i, holes);
2966 if (holes) fill_holes (holes);
2969 void CLASS redcine_load_raw()
2980 in = jas_stream_fopen (ifname, "rb");
2981 jas_stream_seek (in, data_offset+20, SEEK_SET);
2982 jimg = jas_image_decode (in, -1, 0);
2983 if (!jimg) longjmp (failure, 3);
2984 jmat = jas_matrix_create (height/2, width/2);
2985 merror (jmat, "redcine_load_raw()");
2986 img = (ushort *) calloc ((height+2), (width+2)*2);
2987 merror (img, "redcine_load_raw()");
2989 jas_image_readcmpt (jimg, c, 0, 0, width/2, height/2, jmat);
2990 data = jas_matrix_getref (jmat, 0, 0);
2991 for (row = c >> 1; row < height; row+=2)
2992 for (col = c & 1; col < width; col+=2)
2993 img[(row+1)*(width+2)+col+1] = data[(row/2)*(width/2)+col/2];
2995 for (col=1; col <= width; col++) {
2996 img[col] = img[2*(width+2)+col];
2997 img[(height+1)*(width+2)+col] = img[(height-1)*(width+2)+col];
2999 for (row=0; row < height+2; row++) {
3000 img[row*(width+2)] = img[row*(width+2)+2];
3001 img[(row+1)*(width+2)-1] = img[(row+1)*(width+2)-3];
3003 for (row=1; row <= height; row++) {
3004 pix = img + row*(width+2) + (col = 1 + (FC(row,1) & 1));
3005 for ( ; col <= width; col+=2, pix+=2) {
3006 c = (((pix[0] - 0x800) << 3) +
3007 pix[-(width+2)] + pix[width+2] + pix[-1] + pix[1]) >> 2;
3008 pix[0] = LIM(c,0,4095);
3011 for (row=0; row < height; row++)
3012 for (col=0; col < width; col++)
3013 RAW(row,col) = curve[img[(row+1)*(width+2)+col+1]];
3015 jas_matrix_destroy (jmat);
3016 jas_image_destroy (jimg);
3017 jas_stream_close (in);
3021 /* RESTRICTED code starts here */
3023 void CLASS foveon_decoder (unsigned size, unsigned code)
3025 unsigned *huff = fov_huff;
3030 for (i=0; i < size; i++)
3032 memset (first_decode, 0, sizeof first_decode);
3033 free_decode = first_decode;
3035 cur = free_decode++;
3036 if (free_decode > first_decode+2048) {
3037 fprintf (stderr,_("%s: decoder table overflow\n"), ifname);
3038 longjmp (failure, 2);
3041 for (i=0; i < size; i++)
3042 if (huff[i] == code) {
3046 if ((len = code >> 27) > 26) return;
3047 code = (len+1) << 27 | (code & 0x3ffffff) << 1;
3049 cur->branch[0] = free_decode;
3050 foveon_decoder (size, code);
3051 cur->branch[1] = free_decode;
3052 foveon_decoder (size, code+1);
3055 void CLASS foveon_thumb()
3057 unsigned bwide, row, col, bitbuf=0, bit=1, c, i;
3059 struct decode *dindex;
3063 fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
3065 if (bwide < thumb_width*3) return;
3066 buf = (char *) malloc (bwide);
3067 merror (buf, "foveon_thumb()");
3068 for (row=0; row < thumb_height; row++) {
3069 fread (buf, 1, bwide, ifp);
3070 fwrite (buf, 3, thumb_width, ofp);
3075 foveon_decoder (256, 0);
3077 for (row=0; row < thumb_height; row++) {
3078 memset (pred, 0, sizeof pred);
3080 for (bit=col=0; col < thumb_width; col++)
3082 for (dindex=first_decode; dindex->branch[0]; ) {
3083 if ((bit = (bit-1) & 31) == 31)
3084 for (i=0; i < 4; i++)
3085 bitbuf = (bitbuf << 8) + fgetc(ifp);
3086 dindex = dindex->branch[bitbuf >> bit & 1];
3088 pred[c] += dindex->leaf;
3089 fputc (pred[c], ofp);
3094 void CLASS foveon_sd_load_raw()
3096 struct decode *dindex;
3099 int pred[3], row, col, bit=-1, c, i;
3101 read_shorts ((ushort *) diff, 1024);
3102 if (!load_flags) foveon_decoder (1024, 0);
3104 for (row=0; row < height; row++) {
3105 memset (pred, 0, sizeof pred);
3106 if (!bit && !load_flags && atoi(model+2) < 14) get4();
3107 for (col=bit=0; col < width; col++) {
3110 FORC3 pred[2-c] += diff[bitbuf >> c*10 & 0x3ff];
3113 for (dindex=first_decode; dindex->branch[0]; ) {
3114 if ((bit = (bit-1) & 31) == 31)
3115 for (i=0; i < 4; i++)
3116 bitbuf = (bitbuf << 8) + fgetc(ifp);
3117 dindex = dindex->branch[bitbuf >> bit & 1];
3119 pred[c] += diff[dindex->leaf];
3120 if (pred[c] >> 16 && ~pred[c] >> 16) derror();
3122 FORC3 image[row*width+col][c] = pred[c];
3127 void CLASS foveon_huff (ushort *huff)
3129 int i, j, clen, code;
3132 for (i=0; i < 13; i++) {
3135 for (j=0; j < 256 >> clen; )
3136 huff[code+ ++j] = clen << 8 | i;
3141 void CLASS foveon_dp_load_raw()
3143 unsigned c, roff[4], row, col, diff;
3144 ushort huff[512], vpred[2][2], hpred[2];
3146 fseek (ifp, 8, SEEK_CUR);
3149 FORC3 roff[c+1] = -(-(roff[c] + get4()) & -16);
3151 fseek (ifp, data_offset+roff[c], SEEK_SET);
3153 vpred[0][0] = vpred[0][1] = vpred[1][0] = vpred[1][1] = 512;
3154 for (row=0; row < height; row++) {
3155 for (col=0; col < width; col++) {
3156 diff = ljpeg_diff(huff);
3157 if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
3158 else hpred[col & 1] += diff;
3159 image[row*width+col][c] = hpred[col & 1];
3165 void CLASS foveon_load_camf()
3167 unsigned type, wide, high, i, j, row, col, diff;
3168 ushort huff[258], vpred[2][2] = {{512,512},{512,512}}, hpred[2];
3170 fseek (ifp, meta_offset, SEEK_SET);
3171 type = get4(); get4(); get4();
3175 fread (meta_data, 1, meta_length, ifp);
3176 for (i=0; i < meta_length; i++) {
3177 high = (high * 1597 + 51749) % 244944;
3178 wide = high * (INT64) 301593171 >> 24;
3179 meta_data[i] ^= ((((high << 8) - wide) >> 1) + wide) >> 17;
3181 } else if (type == 4) {
3183 meta_data = (char *) malloc (meta_length = wide*high*3/2);
3184 merror (meta_data, "foveon_load_camf()");
3188 for (j=row=0; row < high; row++) {
3189 for (col=0; col < wide; col++) {
3190 diff = ljpeg_diff(huff);
3191 if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
3192 else hpred[col & 1] += diff;
3194 meta_data[j++] = hpred[0] >> 4;
3195 meta_data[j++] = hpred[0] << 4 | hpred[1] >> 8;
3196 meta_data[j++] = hpred[1];
3201 fprintf (stderr,_("%s has unknown CAMF type %d.\n"), ifname, type);
3204 const char * CLASS foveon_camf_param (const char *block, const char *param)
3207 char *pos, *cp, *dp;
3209 for (idx=0; idx < meta_length; idx += sget4(pos+8)) {
3210 pos = meta_data + idx;
3211 if (strncmp (pos, "CMb", 3)) break;
3212 if (pos[3] != 'P') continue;
3213 if (strcmp (block, pos+sget4(pos+12))) continue;
3214 cp = pos + sget4(pos+16);
3216 dp = pos + sget4(cp+4);
3219 if (!strcmp (param, dp+sget4(cp)))
3220 return dp+sget4(cp+4);
3226 void * CLASS foveon_camf_matrix (unsigned dim[3], const char *name)
3228 unsigned i, idx, type, ndim, size, *mat;
3229 char *pos, *cp, *dp;
3232 for (idx=0; idx < meta_length; idx += sget4(pos+8)) {
3233 pos = meta_data + idx;
3234 if (strncmp (pos, "CMb", 3)) break;
3235 if (pos[3] != 'M') continue;
3236 if (strcmp (name, pos+sget4(pos+12))) continue;
3237 dim[0] = dim[1] = dim[2] = 1;
3238 cp = pos + sget4(pos+16);
3240 if ((ndim = sget4(cp+4)) > 3) break;
3241 dp = pos + sget4(cp+8);
3242 for (i=ndim; i--; ) {
3246 if ((dsize = (double) dim[0]*dim[1]*dim[2]) > meta_length/4) break;
3247 mat = (unsigned *) malloc ((size = dsize) * 4);
3248 merror (mat, "foveon_camf_matrix()");
3249 for (i=0; i < size; i++)
3250 if (type && type != 6)
3251 mat[i] = sget4(dp + i*4);
3253 mat[i] = sget4(dp + i*2) & 0xffff;
3256 fprintf (stderr,_("%s: \"%s\" matrix not found!\n"), ifname, name);
3260 int CLASS foveon_fixed (void *ptr, int size, const char *name)
3265 if (!name) return 0;
3266 dp = foveon_camf_matrix (dim, name);
3268 memcpy (ptr, dp, size*4);
3273 float CLASS foveon_avg (short *pix, int range[2], float cfilt)
3276 float val, min=FLT_MAX, max=-FLT_MAX, sum=0;
3278 for (i=range[0]; i <= range[1]; i++) {
3279 sum += val = pix[i*4] + (pix[i*4]-pix[(i-1)*4]) * cfilt;
3280 if (min > val) min = val;
3281 if (max < val) max = val;
3283 if (range[1] - range[0] == 1) return sum/2;
3284 return (sum - min - max) / (range[1] - range[0] - 1);
3287 short * CLASS foveon_make_curve (double max, double mul, double filt)
3293 if (!filt) filt = 0.8;
3294 size = 4*M_PI*max / filt;
3295 if (size > INT_MAX-1) size = INT_MAX-1;
3296 curve = (short *) calloc (size+1, sizeof *curve);
3297 merror (curve, "foveon_make_curve()");
3299 for (i=0; i < size; i++) {
3301 curve[i+1] = (cos(x)+1)/2 * tanh(i*filt/mul) * mul + 0.5;
3306 void CLASS foveon_make_curves
3307 (short **curvep, float dq[3], float div[3], float filt)
3309 double mul[3], max=0;
3312 FORC3 mul[c] = dq[c]/div[c];
3313 FORC3 if (max < mul[c]) max = mul[c];
3314 FORC3 curvep[c] = foveon_make_curve (max, mul[c], filt);
3317 int CLASS foveon_apply_curve (short *curve, int i)
3319 if (abs(i) >= curve[0]) return 0;
3320 return i < 0 ? -curve[1-i] : curve[1+i];
3323 #define image ((short (*)[4]) image)
3325 void CLASS foveon_interpolate()
3327 static const short hood[] = { -1,-1, -1,0, -1,1, 0,-1, 0,1, 1,-1, 1,0, 1,1 };
3328 short *pix, prev[3], *curve[8], (*shrink)[3];
3329 float cfilt, ddft[3][3][2], ppm[3][3][3];
3330 float cam_xyz[3][3], correct[3][3], last[3][3], trans[3][3];
3331 float chroma_dq[3], color_dq[3], diag[3][3], div[3];
3332 float (*black)[3], (*sgain)[3], (*sgrow)[3];
3333 float fsum[3], val, frow, num;
3334 int row, col, c, i, j, diff, sgx, irow, sum, min, max, limit;
3335 int dscr[2][2], dstb[4], (*smrow[7])[3], total[4], ipix[3];
3336 int work[3][3], smlast, smred, smred_p, dev[3];
3337 int satlev[3], keep[4], active[4];
3338 unsigned dim[3], *badpix;
3339 double dsum, trsum[3];
3342 // clear local storage
3343 pix = 0; ZERO(prev); ZERO(curve); ZERO(shrink);
3344 cfilt = 0; ZERO(ddft); ZERO(ppm);
3345 ZERO(cam_xyz); ZERO(correct); ZERO(last); ZERO(trans);
3346 ZERO(chroma_dq); ZERO(color_dq); ZERO(diag); ZERO(div);
3347 ZERO(black); ZERO(sgain); ZERO(sgrow);
3348 ZERO(fsum); val = frow = num = 0;
3349 row = col = c = i = j = diff = sgx = irow = sum = min = max = limit = 0;
3350 ZERO(dscr); ZERO(dstb); ZERO(smrow); ZERO(total); ZERO(ipix);
3351 ZERO(work); ZERO(smlast); ZERO(smred); smred_p=0; ZERO(dev);
3352 ZERO(satlev); ZERO(keep); ZERO(active);
3353 ZERO(dim); badpix = 0;
3354 dsum = 0; ZERO(trsum);
3359 fprintf (stderr,_("Foveon interpolation...\n"));
3362 foveon_fixed (dscr, 4, "DarkShieldColRange");
3363 foveon_fixed (ppm[0][0], 27, "PostPolyMatrix");
3364 foveon_fixed (satlev, 3, "SaturationLevel");
3365 foveon_fixed (keep, 4, "KeepImageArea");
3366 foveon_fixed (active, 4, "ActiveImageArea");
3367 foveon_fixed (chroma_dq, 3, "ChromaDQ");
3368 foveon_fixed (color_dq, 3,
3369 foveon_camf_param ("IncludeBlocks", "ColorDQ") ?
3370 "ColorDQ" : "ColorDQCamRGB");
3371 if (foveon_camf_param ("IncludeBlocks", "ColumnFilter"))
3372 foveon_fixed (&cfilt, 1, "ColumnFilter");
3374 memset (ddft, 0, sizeof ddft);
3375 if (!foveon_camf_param ("IncludeBlocks", "DarkDrift")
3376 || !foveon_fixed (ddft[1][0], 12, "DarkDrift"))
3377 for (i=0; i < 2; i++) {
3378 foveon_fixed (dstb, 4, i ? "DarkShieldBottom":"DarkShieldTop");
3379 for (row = dstb[1]; row <= dstb[3]; row++)
3380 for (col = dstb[0]; col <= dstb[2]; col++)
3381 FORC3 ddft[i+1][c][1] += (short) image[row*width+col][c];
3382 FORC3 ddft[i+1][c][1] /= (dstb[3]-dstb[1]+1) * (dstb[2]-dstb[0]+1);
3385 if (!(cp = foveon_camf_param ("WhiteBalanceIlluminants", model2)))
3386 { fprintf (stderr,_("%s: Invalid white balance \"%s\"\n"), ifname, model2);
3388 foveon_fixed (cam_xyz, 9, cp);
3389 foveon_fixed (correct, 9,
3390 foveon_camf_param ("WhiteBalanceCorrections", model2));
3391 memset (last, 0, sizeof last);
3392 for (i=0; i < 3; i++)
3393 for (j=0; j < 3; j++)
3394 FORC3 last[i][j] += correct[i][c] * cam_xyz[c][j];
3396 #define LAST(x,y) last[(i+x)%3][(c+y)%3]
3397 for (i=0; i < 3; i++)
3398 FORC3 diag[c][i] = LAST(1,1)*LAST(2,2) - LAST(1,2)*LAST(2,1);
3400 FORC3 div[c] = diag[c][0]*0.3127 + diag[c][1]*0.329 + diag[c][2]*0.3583;
3401 sprintf (str, "%sRGBNeutral", model2);
3402 if (foveon_camf_param ("IncludeBlocks", str))
3403 foveon_fixed (div, 3, str);
3405 FORC3 if (num < div[c]) num = div[c];
3406 FORC3 div[c] /= num;
3408 memset (trans, 0, sizeof trans);
3409 for (i=0; i < 3; i++)
3410 for (j=0; j < 3; j++)
3411 FORC3 trans[i][j] += rgb_cam[i][c] * last[c][j] * div[j];
3412 FORC3 trsum[c] = trans[c][0] + trans[c][1] + trans[c][2];
3413 dsum = (6*trsum[0] + 11*trsum[1] + 3*trsum[2]) / 20;
3414 for (i=0; i < 3; i++)
3415 FORC3 last[i][c] = trans[i][c] * dsum / trsum[i];
3416 memset (trans, 0, sizeof trans);
3417 for (i=0; i < 3; i++)
3418 for (j=0; j < 3; j++)
3419 FORC3 trans[i][j] += (i==c ? 32 : -1) * last[c][j] / 30;
3421 foveon_make_curves (curve, color_dq, div, cfilt);
3422 FORC3 chroma_dq[c] /= 3;
3423 foveon_make_curves (curve+3, chroma_dq, div, cfilt);
3424 FORC3 dsum += chroma_dq[c] / div[c];
3425 curve[6] = foveon_make_curve (dsum, dsum, cfilt);
3426 curve[7] = foveon_make_curve (dsum*2, dsum*2, cfilt);
3428 sgain = (float (*)[3]) foveon_camf_matrix (dim, "SpatialGain");
3430 sgrow = (float (*)[3]) calloc (dim[1], sizeof *sgrow);
3431 sgx = (width + dim[1]-2) / (dim[1]-1);
3433 black = (float (*)[3]) calloc (height, sizeof *black);
3434 for (row=0; row < height; row++) {
3435 for (i=0; i < 6; i++)
3436 ((float *)ddft[0])[i] = ((float *)ddft[1])[i] +
3437 row / (height-1.0) * (((float *)ddft[2])[i] - ((float *)ddft[1])[i]);
3438 FORC3 black[row][c] =
3439 ( foveon_avg (image[row*width]+c, dscr[0], cfilt) +
3440 foveon_avg (image[row*width]+c, dscr[1], cfilt) * 3
3441 - ddft[0][c][0] ) / 4 - ddft[0][c][1];
3443 memcpy (black, black+8, sizeof *black*8);
3444 memcpy (black+height-11, black+height-22, 11*sizeof *black);
3445 memcpy (last, black, sizeof last);
3447 for (row=1; row < height-1; row++) {
3448 FORC3 if (last[1][c] > last[0][c]) {
3449 if (last[1][c] > last[2][c])
3450 black[row][c] = (last[0][c] > last[2][c]) ? last[0][c]:last[2][c];
3452 if (last[1][c] < last[2][c])
3453 black[row][c] = (last[0][c] < last[2][c]) ? last[0][c]:last[2][c];
3454 memmove (last, last+1, 2*sizeof last[0]);
3455 memcpy (last[2], black[row+1], sizeof last[2]);
3457 FORC3 black[row][c] = (last[0][c] + last[1][c])/2;
3458 FORC3 black[0][c] = (black[1][c] + black[3][c])/2;
3460 val = 1 - exp(-1/24.0);
3461 memcpy (fsum, black, sizeof fsum);
3462 for (row=1; row < height; row++)
3463 FORC3 fsum[c] += black[row][c] =
3464 (black[row][c] - black[row-1][c])*val + black[row-1][c];
3465 memcpy (last[0], black[height-1], sizeof last[0]);
3466 FORC3 fsum[c] /= height;
3467 for (row = height; row--; )
3468 FORC3 last[0][c] = black[row][c] =
3469 (black[row][c] - fsum[c] - last[0][c])*val + last[0][c];
3471 memset (total, 0, sizeof total);
3472 for (row=2; row < height; row+=4)
3473 for (col=2; col < width; col+=4) {
3474 FORC3 total[c] += (short) image[row*width+col][c];
3477 for (row=0; row < height; row++)
3478 FORC3 black[row][c] += fsum[c]/2 + total[c]/(total[3]*100.0);
3480 for (row=0; row < height; row++) {
3481 for (i=0; i < 6; i++)
3482 ((float *)ddft[0])[i] = ((float *)ddft[1])[i] +
3483 row / (height-1.0) * (((float *)ddft[2])[i] - ((float *)ddft[1])[i]);
3484 pix = image[row*width];
3485 memcpy (prev, pix, sizeof prev);
3486 frow = row / (height-1.0) * (dim[2]-1);
3487 if ((irow = frow) == dim[2]-1) irow--;
3489 for (i=0; i < dim[1]; i++)
3490 FORC3 sgrow[i][c] = sgain[ irow *dim[1]+i][c] * (1-frow) +
3491 sgain[(irow+1)*dim[1]+i][c] * frow;
3492 for (col=0; col < width; col++) {
3494 diff = pix[c] - prev[c];
3496 ipix[c] = pix[c] + floor ((diff + (diff*diff >> 14)) * cfilt
3497 - ddft[0][c][1] - ddft[0][c][0] * ((float) col/width - 0.5)
3501 work[0][c] = ipix[c] * ipix[c] >> 14;
3502 work[2][c] = ipix[c] * work[0][c] >> 14;
3503 work[1][2-c] = ipix[(c+1) % 3] * ipix[(c+2) % 3] >> 14;
3506 for (val=i=0; i < 3; i++)
3507 for ( j=0; j < 3; j++)
3508 val += ppm[c][i][j] * work[i][j];
3509 ipix[c] = floor ((ipix[c] + floor(val)) *
3510 ( sgrow[col/sgx ][c] * (sgx - col%sgx) +
3511 sgrow[col/sgx+1][c] * (col%sgx) ) / sgx / div[c]);
3512 if (ipix[c] > 32000) ipix[c] = 32000;
3522 if ((badpix = (unsigned *) foveon_camf_matrix (dim, "BadPixels"))) {
3523 for (i=0; i < dim[0]; i++) {
3524 col = (badpix[i] >> 8 & 0xfff) - keep[0];
3525 row = (badpix[i] >> 20 ) - keep[1];
3526 if ((unsigned)(row-1) > height-3 || (unsigned)(col-1) > width-3)
3528 memset (fsum, 0, sizeof fsum);
3529 for (sum=j=0; j < 8; j++)
3530 if (badpix[i] & (1 << j)) {
3531 FORC3 fsum[c] += (short)
3532 image[(row+hood[j*2])*width+col+hood[j*2+1]][c];
3535 if (sum) FORC3 image[row*width+col][c] = fsum[c]/sum;
3540 /* Array for 5x5 Gaussian averaging of red values */
3541 smrow[6] = (int (*)[3]) calloc (width*5, sizeof **smrow);
3542 merror (smrow[6], "foveon_interpolate()");
3543 for (i=0; i < 5; i++)
3544 smrow[i] = smrow[6] + i*width;
3546 /* Sharpen the reds against these Gaussian averages */
3547 for (smlast=-1, row=2; row < height-2; row++) {
3548 while (smlast < row+2) {
3549 for (i=0; i < 6; i++)
3550 smrow[(i+5) % 6] = smrow[i];
3551 pix = image[++smlast*width+2];
3552 for (col=2; col < width-2; col++) {
3554 (pix[0]*6 + (pix[-4]+pix[4])*4 + pix[-8]+pix[8] + 8) >> 4;
3558 pix = image[row*width+2];
3559 for (col=2; col < width-2; col++) {
3560 smred = ( 6 * smrow[2][col][0]
3561 + 4 * (smrow[1][col][0] + smrow[3][col][0])
3562 + smrow[0][col][0] + smrow[4][col][0] + 8 ) >> 4;
3565 i = pix[0] + ((pix[0] - ((smred*7 + smred_p) >> 3)) >> 3);
3566 if (i > 32000) i = 32000;
3573 /* Adjust the brighter pixels for better linearity */
3576 i = satlev[c] / div[c];
3577 if (min > i) min = i;
3579 limit = min * 9 >> 4;
3580 for (pix=image[0]; pix < image[height*width]; pix+=4) {
3581 if (pix[0] <= limit || pix[1] <= limit || pix[2] <= limit)
3584 for (c=1; c < 3; c++) {
3585 if (min > pix[c]) min = pix[c];
3586 if (max < pix[c]) max = pix[c];
3588 if (min >= limit*2) {
3589 pix[0] = pix[1] = pix[2] = max;
3591 i = 0x4000 - ((min - limit) << 14) / limit;
3592 i = 0x4000 - (i*i >> 14);
3594 FORC3 pix[c] += (max - pix[c]) * i >> 14;
3598 Because photons that miss one detector often hit another,
3599 the sum R+G+B is much less noisy than the individual colors.
3600 So smooth the hues without smoothing the total.
3602 for (smlast=-1, row=2; row < height-2; row++) {
3603 while (smlast < row+2) {
3604 for (i=0; i < 6; i++)
3605 smrow[(i+5) % 6] = smrow[i];
3606 pix = image[++smlast*width+2];
3607 for (col=2; col < width-2; col++) {
3608 FORC3 smrow[4][col][c] = (pix[c-4]+2*pix[c]+pix[c+4]+2) >> 2;
3612 pix = image[row*width+2];
3613 for (col=2; col < width-2; col++) {
3614 FORC3 dev[c] = -foveon_apply_curve (curve[7], pix[c] -
3615 ((smrow[1][col][c] + 2*smrow[2][col][c] + smrow[3][col][c]) >> 2));
3616 sum = (dev[0] + dev[1] + dev[2]) >> 3;
3617 FORC3 pix[c] += dev[c] - sum;
3621 for (smlast=-1, row=2; row < height-2; row++) {
3622 while (smlast < row+2) {
3623 for (i=0; i < 6; i++)
3624 smrow[(i+5) % 6] = smrow[i];
3625 pix = image[++smlast*width+2];
3626 for (col=2; col < width-2; col++) {
3627 FORC3 smrow[4][col][c] =
3628 (pix[c-8]+pix[c-4]+pix[c]+pix[c+4]+pix[c+8]+2) >> 2;
3632 pix = image[row*width+2];
3633 for (col=2; col < width-2; col++) {
3634 for (total[3]=375, sum=60, c=0; c < 3; c++) {
3635 for (total[c]=i=0; i < 5; i++)
3636 total[c] += smrow[i][col][c];
3637 total[3] += total[c];
3640 if (sum < 0) sum = 0;
3641 j = total[3] > 375 ? (sum << 16) / total[3] : sum * 174;
3642 FORC3 pix[c] += foveon_apply_curve (curve[6],
3643 ((j*total[c] + 0x8000) >> 16) - pix[c]);
3648 /* Transform the image to a different colorspace */
3649 for (pix=image[0]; pix < image[height*width]; pix+=4) {
3650 FORC3 pix[c] -= foveon_apply_curve (curve[c], pix[c]);
3651 sum = (pix[0]+pix[1]+pix[1]+pix[2]) >> 2;
3652 FORC3 pix[c] -= foveon_apply_curve (curve[c], pix[c]-sum);
3654 for (dsum=i=0; i < 3; i++)
3655 dsum += trans[c][i] * pix[i];
3656 if (dsum < 0) dsum = 0;
3657 if (dsum > 24000) dsum = 24000;
3658 ipix[c] = dsum + 0.5;
3660 FORC3 pix[c] = ipix[c];
3663 /* Smooth the image bottom-to-top and save at 1/4 scale */
3664 shrink = (short (*)[3]) calloc ((height/4), (width/4)*sizeof *shrink);
3665 merror (shrink, "foveon_interpolate()");
3666 for (row = height/4; row--; )
3667 for (col=0; col < width/4; col++) {
3668 ipix[0] = ipix[1] = ipix[2] = 0;
3669 for (i=0; i < 4; i++)
3670 for (j=0; j < 4; j++)
3671 FORC3 ipix[c] += image[(row*4+i)*width+col*4+j][c];
3673 if (row+2 > height/4)
3674 shrink[row*(width/4)+col][c] = ipix[c] >> 4;
3676 shrink[row*(width/4)+col][c] =
3677 (shrink[(row+1)*(width/4)+col][c]*1840 + ipix[c]*141 + 2048) >> 12;
3679 /* From the 1/4-scale image, smooth right-to-left */
3680 for (row=0; row < (height & ~3); row++) {
3681 ipix[0] = ipix[1] = ipix[2] = 0;
3683 for (col = width & ~3 ; col--; )
3684 FORC3 smrow[0][col][c] = ipix[c] =
3685 (shrink[(row/4)*(width/4)+col/4][c]*1485 + ipix[c]*6707 + 4096) >> 13;
3687 /* Then smooth left-to-right */
3688 ipix[0] = ipix[1] = ipix[2] = 0;
3689 for (col=0; col < (width & ~3); col++)
3690 FORC3 smrow[1][col][c] = ipix[c] =
3691 (smrow[0][col][c]*1485 + ipix[c]*6707 + 4096) >> 13;
3693 /* Smooth top-to-bottom */
3695 memcpy (smrow[2], smrow[1], sizeof **smrow * width);
3697 for (col=0; col < (width & ~3); col++)
3698 FORC3 smrow[2][col][c] =
3699 (smrow[2][col][c]*6707 + smrow[1][col][c]*1485 + 4096) >> 13;
3701 /* Adjust the chroma toward the smooth values */
3702 for (col=0; col < (width & ~3); col++) {
3703 for (i=j=30, c=0; c < 3; c++) {
3704 i += smrow[2][col][c];
3705 j += image[row*width+col][c];
3708 for (sum=c=0; c < 3; c++) {
3709 ipix[c] = foveon_apply_curve (curve[c+3],
3710 ((smrow[2][col][c] * j + 0x8000) >> 16) - image[row*width+col][c]);
3715 i = image[row*width+col][c] + ipix[c] - sum;
3717 image[row*width+col][c] = i;
3723 for (i=0; i < 8; i++)
3726 /* Trim off the black border */
3727 active[1] -= keep[1];
3729 i = active[2] - active[0];
3730 for (row=0; row < active[3]-active[1]; row++)
3731 memcpy (image[row*i], image[(row+active[1])*width+active[0]],
3738 /* RESTRICTED code ends here */
3740 void CLASS crop_masked_pixels()
3743 unsigned r, c, m, mblack[8], zero, val;
3745 if (load_raw == &CLASS phase_one_load_raw ||
3746 load_raw == &CLASS phase_one_load_raw_c)
3747 phase_one_correct();
3749 for (row=0; row < raw_height-top_margin*2; row++) {
3750 for (col=0; col < fuji_width << !fuji_layout; col++) {
3752 r = fuji_width - 1 - col + (row >> 1);
3753 c = col + ((row+1) >> 1);
3755 r = fuji_width - 1 + row - (col >> 1);
3756 c = row + ((col+1) >> 1);
3758 if (r < height && c < width)
3759 BAYER(r,c) = RAW(row+top_margin,col+left_margin);
3763 for (row=0; row < height; row++)
3764 for (col=0; col < width; col++)
3765 BAYER2(row,col) = RAW(row+top_margin,col+left_margin);
3767 if (mask[0][3] > 0) goto mask_set;
3768 if (load_raw == &CLASS canon_load_raw ||
3769 load_raw == &CLASS lossless_jpeg_load_raw) {
3770 mask[0][1] = mask[1][1] += 2;
3774 if (load_raw == &CLASS canon_600_load_raw ||
3775 load_raw == &CLASS sony_load_raw ||
3776 (load_raw == &CLASS eight_bit_load_raw && strncmp(model,"DC2",3)) ||
3777 load_raw == &CLASS kodak_262_load_raw ||
3778 (load_raw == &CLASS packed_load_raw && (load_flags & 256))) {
3780 mask[0][0] = mask[1][0] = top_margin;
3781 mask[0][2] = mask[1][2] = top_margin+height;
3782 mask[0][3] += left_margin;
3783 mask[1][1] += left_margin+width;
3784 mask[1][3] += raw_width;
3786 if (load_raw == &CLASS nokia_load_raw) {
3787 mask[0][2] = top_margin;
3791 memset (mblack, 0, sizeof mblack);
3792 for (zero=m=0; m < 8; m++)
3793 for (row=MAX(mask[m][0],0); row < MIN(mask[m][2],raw_height); row++)
3794 for (col=MAX(mask[m][1],0); col < MIN(mask[m][3],raw_width); col++) {
3795 c = FC(row-top_margin,col-left_margin);
3796 mblack[c] += val = RAW(row,col);
3800 if (load_raw == &CLASS canon_600_load_raw && width < raw_width) {
3801 black = (mblack[0]+mblack[1]+mblack[2]+mblack[3]) /
3802 (mblack[4]+mblack[5]+mblack[6]+mblack[7]) - 4;
3803 canon_600_correct();
3804 } else if (zero < mblack[4] && mblack[5] && mblack[6] && mblack[7]) {
3805 FORC4 cblack[c] = mblack[c] / mblack[4+c];
3806 cblack[4] = cblack[5] = cblack[6] = 0;
3810 void CLASS remove_zeroes()
3812 unsigned row, col, tot, n, r, c;
3814 for (row=0; row < height; row++)
3815 for (col=0; col < width; col++)
3816 if (BAYER(row,col) == 0) {
3818 for (r = row-2; r <= row+2; r++)
3819 for (c = col-2; c <= col+2; c++)
3820 if (r < height && c < width &&
3821 FC(r,c) == FC(row,col) && BAYER(r,c))
3822 tot += (n++,BAYER(r,c));
3823 if (n) BAYER(row,col) = tot/n;
3828 Seach from the current directory up to the root looking for
3829 a ".badpixels" file, and fix those pixels now.
3831 void CLASS bad_pixels (const char *cfname)
3834 char *fname, *cp, line[128];
3835 int len, time, row, col, r, c, rad, tot, n, fixed=0;
3837 if (!filters) return;
3839 fp = fopen (cfname, "r");
3841 for (len=32 ; ; len *= 2) {
3842 fname = (char *) malloc (len);
3844 if (getcwd (fname, len-16)) break;
3846 if (errno != ERANGE) return;
3848 #if defined(WIN32) || defined(DJGPP)
3849 if (fname[1] == ':')
3850 memmove (fname, fname+2, len-2);
3851 for (cp=fname; *cp; cp++)
3852 if (*cp == '\\') *cp = '/';
3854 cp = fname + strlen(fname);
3855 if (cp[-1] == '/') cp--;
3856 while (*fname == '/') {
3857 strcpy (cp, "/.badpixels");
3858 if ((fp = fopen (fname, "r"))) break;
3859 if (cp == fname) break;
3860 while (*--cp != '/');
3865 while (fgets (line, 128, fp)) {
3866 cp = strchr (line, '#');
3868 if (sscanf (line, "%d %d %d", &col, &row, &time) != 3) continue;
3869 if ((unsigned) col >= width || (unsigned) row >= height) continue;
3870 if (time > timestamp) continue;
3871 for (tot=n=0, rad=1; rad < 3 && n==0; rad++)
3872 for (r = row-rad; r <= row+rad; r++)
3873 for (c = col-rad; c <= col+rad; c++)
3874 if ((unsigned) r < height && (unsigned) c < width &&
3875 (r != row || c != col) && fcol(r,c) == fcol(row,col)) {
3879 BAYER2(row,col) = tot/n;
3882 fprintf (stderr,_("Fixed dead pixels at:"));
3883 fprintf (stderr, " %d,%d", col, row);
3886 if (fixed) fputc ('\n', stderr);
3890 void CLASS subtract (const char *fname)
3893 int dim[3]={0,0,0}, comment=0, number=0, error=0, nd=0, c, row, col;
3896 if (!(fp = fopen (fname, "rb"))) {
3897 perror (fname); return;
3899 if (fgetc(fp) != 'P' || fgetc(fp) != '5') error = 1;
3900 while (!error && nd < 3 && (c = fgetc(fp)) != EOF) {
3901 if (c == '#') comment = 1;
3902 if (c == '\n') comment = 0;
3903 if (comment) continue;
3904 if (isdigit(c)) number = 1;
3906 if (isdigit(c)) dim[nd] = dim[nd]*10 + c -'0';
3907 else if (isspace(c)) {
3912 if (error || nd < 3) {
3913 fprintf (stderr,_("%s is not a valid PGM file!\n"), fname);
3914 fclose (fp); return;
3915 } else if (dim[0] != width || dim[1] != height || dim[2] != 65535) {
3916 fprintf (stderr,_("%s has the wrong dimensions!\n"), fname);
3917 fclose (fp); return;
3919 pixel = (ushort *) calloc (width, sizeof *pixel);
3920 merror (pixel, "subtract()");
3921 for (row=0; row < height; row++) {
3922 fread (pixel, 2, width, fp);
3923 for (col=0; col < width; col++)
3924 BAYER(row,col) = MAX (BAYER(row,col) - ntohs(pixel[col]), 0);
3928 memset (cblack, 0, sizeof cblack);
3932 void CLASS gamma_curve (double pwr, double ts, int mode, int imax)
3935 double g[6], bnd[2]={0,0}, r;
3939 g[2] = g[3] = g[4] = 0;
3941 if (g[1] && (g[1]-1)*(g[0]-1) <= 0) {
3942 for (i=0; i < 48; i++) {
3943 g[2] = (bnd[0] + bnd[1])/2;
3944 if (g[0]) bnd[(pow(g[2]/g[1],-g[0]) - 1)/g[0] - 1/g[2] > -1] = g[2];
3945 else bnd[g[2]/exp(1-1/g[2]) < g[1]] = g[2];
3948 if (g[0]) g[4] = g[2] * (1/g[0] - 1);
3950 if (g[0]) g[5] = 1 / (g[1]*SQR(g[3])/2 - g[4]*(1 - g[3]) +
3951 (1 - pow(g[3],1+g[0]))*(1 + g[4])/(1 + g[0])) - 1;
3952 else g[5] = 1 / (g[1]*SQR(g[3])/2 + 1
3953 - g[2] - g[3] - g[2]*g[3]*(log(g[3]) - 1)) - 1;
3955 memcpy (gamm, g, sizeof gamm);
3958 for (i=0; i < 0x10000; i++) {
3960 if ((r = (double) i / imax) < 1)
3961 curve[i] = 0x10000 * ( mode
3962 ? (r < g[3] ? r*g[1] : (g[0] ? pow( r,g[0])*(1+g[4])-g[4] : log(r)*g[2]+1))
3963 : (r < g[2] ? r/g[1] : (g[0] ? pow((r+g[4])/(1+g[4]),1/g[0]) : exp((r-1)/g[2]))));
3967 void CLASS pseudoinverse (double (*in)[3], double (*out)[3], int size)
3969 double work[3][6], num;
3972 for (i=0; i < 3; i++) {
3973 for (j=0; j < 6; j++)
3974 work[i][j] = j == i+3;
3975 for (j=0; j < 3; j++)
3976 for (k=0; k < size; k++)
3977 work[i][j] += in[k][i] * in[k][j];
3979 for (i=0; i < 3; i++) {
3981 for (j=0; j < 6; j++)
3983 for (k=0; k < 3; k++) {
3986 for (j=0; j < 6; j++)
3987 work[k][j] -= work[i][j] * num;
3990 for (i=0; i < size; i++)
3991 for (j=0; j < 3; j++)
3992 for (out[i][j]=k=0; k < 3; k++)
3993 out[i][j] += work[j][k+3] * in[i][k];
3996 void CLASS cam_xyz_coeff (float rgb_cam[3][4], double cam_xyz[4][3])
3998 double cam_rgb[4][3], inverse[4][3], num;
4001 for (i=0; i < colors; i++) /* Multiply out XYZ colorspace */
4002 for (j=0; j < 3; j++)
4003 for (cam_rgb[i][j] = k=0; k < 3; k++)
4004 cam_rgb[i][j] += cam_xyz[i][k] * xyz_rgb[k][j];
4006 for (i=0; i < colors; i++) { /* Normalize cam_rgb so that */
4007 for (num=j=0; j < 3; j++) /* cam_rgb * (1,1,1) is (1,1,1,1) */
4008 num += cam_rgb[i][j];
4009 for (j=0; j < 3; j++)
4010 cam_rgb[i][j] /= num;
4011 pre_mul[i] = 1 / num;
4013 pseudoinverse (cam_rgb, inverse, colors);
4014 for (i=0; i < 3; i++)
4015 for (j=0; j < colors; j++)
4016 rgb_cam[i][j] = inverse[j][i];
4020 void CLASS colorcheck()
4023 // Coordinates of the GretagMacbeth ColorChecker squares
4024 // width, height, 1st_column, 1st_row
4025 int cut[NSQ][4]; // you must set these
4026 // ColorChecker Chart under 6500-kelvin illumination
4027 static const double gmb_xyY[NSQ][3] = {
4028 { 0.400, 0.350, 10.1 }, // Dark Skin
4029 { 0.377, 0.345, 35.8 }, // Light Skin
4030 { 0.247, 0.251, 19.3 }, // Blue Sky
4031 { 0.337, 0.422, 13.3 }, // Foliage
4032 { 0.265, 0.240, 24.3 }, // Blue Flower
4033 { 0.261, 0.343, 43.1 }, // Bluish Green
4034 { 0.506, 0.407, 30.1 }, // Orange
4035 { 0.211, 0.175, 12.0 }, // Purplish Blue
4036 { 0.453, 0.306, 19.8 }, // Moderate Red
4037 { 0.285, 0.202, 6.6 }, // Purple
4038 { 0.380, 0.489, 44.3 }, // Yellow Green
4039 { 0.473, 0.438, 43.1 }, // Orange Yellow
4040 { 0.187, 0.129, 6.1 }, // Blue
4041 { 0.305, 0.478, 23.4 }, // Green
4042 { 0.539, 0.313, 12.0 }, // Red
4043 { 0.448, 0.470, 59.1 }, // Yellow
4044 { 0.364, 0.233, 19.8 }, // Magenta
4045 { 0.196, 0.252, 19.8 }, // Cyan
4046 { 0.310, 0.316, 90.0 }, // White
4047 { 0.310, 0.316, 59.1 }, // Neutral 8
4048 { 0.310, 0.316, 36.2 }, // Neutral 6.5
4049 { 0.310, 0.316, 19.8 }, // Neutral 5
4050 { 0.310, 0.316, 9.0 }, // Neutral 3.5
4051 { 0.310, 0.316, 3.1 } }; // Black
4052 double gmb_cam[NSQ][4], gmb_xyz[NSQ][3];
4053 double inverse[NSQ][3], cam_xyz[4][3], balance[4], num;
4054 int c, i, j, k, sq, row, col, pass, count[4];
4056 memset (gmb_cam, 0, sizeof gmb_cam);
4057 for (sq=0; sq < NSQ; sq++) {
4059 for (row=cut[sq][3]; row < cut[sq][3]+cut[sq][1]; row++)
4060 for (col=cut[sq][2]; col < cut[sq][2]+cut[sq][0]; col++) {
4062 if (c >= colors) c -= 2;
4063 gmb_cam[sq][c] += BAYER2(row,col);
4064 BAYER2(row,col) = black + (BAYER2(row,col)-black)/2;
4067 FORCC gmb_cam[sq][c] = gmb_cam[sq][c]/count[c] - black;
4068 gmb_xyz[sq][0] = gmb_xyY[sq][2] * gmb_xyY[sq][0] / gmb_xyY[sq][1];
4069 gmb_xyz[sq][1] = gmb_xyY[sq][2];
4070 gmb_xyz[sq][2] = gmb_xyY[sq][2] *
4071 (1 - gmb_xyY[sq][0] - gmb_xyY[sq][1]) / gmb_xyY[sq][1];
4073 pseudoinverse (gmb_xyz, inverse, NSQ);
4074 for (pass=0; pass < 2; pass++) {
4075 for (raw_color = i=0; i < colors; i++)
4076 for (j=0; j < 3; j++)
4077 for (cam_xyz[i][j] = k=0; k < NSQ; k++)
4078 cam_xyz[i][j] += gmb_cam[k][i] * inverse[k][j];
4079 cam_xyz_coeff (rgb_cam, cam_xyz);
4080 FORCC balance[c] = pre_mul[c] * gmb_cam[20][c];
4081 for (sq=0; sq < NSQ; sq++)
4082 FORCC gmb_cam[sq][c] *= balance[c];
4085 printf (" { \"%s %s\", %d,\n\t{", make, model, black);
4086 num = 10000 / (cam_xyz[1][0] + cam_xyz[1][1] + cam_xyz[1][2]);
4087 FORCC for (j=0; j < 3; j++)
4088 printf ("%c%d", (c | j) ? ',':' ', (int) (cam_xyz[c][j] * num + 0.5));
4095 void CLASS hat_transform (float *temp, float *base, int st, int size, int sc)
4098 for (i=0; i < sc; i++)
4099 temp[i] = 2*base[st*i] + base[st*(sc-i)] + base[st*(i+sc)];
4100 for (; i+sc < size; i++)
4101 temp[i] = 2*base[st*i] + base[st*(i-sc)] + base[st*(i+sc)];
4102 for (; i < size; i++)
4103 temp[i] = 2*base[st*i] + base[st*(i-sc)] + base[st*(2*size-2-(i+sc))];
4106 void CLASS wavelet_denoise()
4108 float *fimg=0, *temp, thold, mul[2], avg, diff;
4109 int scale=1, size, lev, hpass, lpass, row, col, nc, c, i, wlast, blk[2];
4111 static const float noise[] =
4112 { 0.8002,0.2735,0.1202,0.0585,0.0291,0.0152,0.0080,0.0044 };
4114 if (verbose) fprintf (stderr,_("Wavelet denoising...\n"));
4116 while (maximum << scale < 0x10000) scale++;
4117 maximum <<= --scale;
4119 FORC4 cblack[c] <<= scale;
4120 if ((size = iheight*iwidth) < 0x15550000)
4121 fimg = (float *) malloc ((size*3 + iheight + iwidth) * sizeof *fimg);
4122 merror (fimg, "wavelet_denoise()");
4123 temp = fimg + size*3;
4124 if ((nc = colors) == 3 && filters) nc++;
4125 FORC(nc) { /* denoise R,G1,B,G3 individually */
4126 for (i=0; i < size; i++)
4127 fimg[i] = 256 * sqrt(image[i][c] << scale);
4128 for (hpass=lev=0; lev < 5; lev++) {
4129 lpass = size*((lev & 1)+1);
4130 for (row=0; row < iheight; row++) {
4131 hat_transform (temp, fimg+hpass+row*iwidth, 1, iwidth, 1 << lev);
4132 for (col=0; col < iwidth; col++)
4133 fimg[lpass + row*iwidth + col] = temp[col] * 0.25;
4135 for (col=0; col < iwidth; col++) {
4136 hat_transform (temp, fimg+lpass+col, iwidth, iheight, 1 << lev);
4137 for (row=0; row < iheight; row++)
4138 fimg[lpass + row*iwidth + col] = temp[row] * 0.25;
4140 thold = threshold * noise[lev];
4141 for (i=0; i < size; i++) {
4142 fimg[hpass+i] -= fimg[lpass+i];
4143 if (fimg[hpass+i] < -thold) fimg[hpass+i] += thold;
4144 else if (fimg[hpass+i] > thold) fimg[hpass+i] -= thold;
4145 else fimg[hpass+i] = 0;
4146 if (hpass) fimg[i] += fimg[hpass+i];
4150 for (i=0; i < size; i++)
4151 image[i][c] = CLIP(SQR(fimg[i]+fimg[lpass+i])/0x10000);
4153 if (filters && colors == 3) { /* pull G1 and G3 closer together */
4154 for (row=0; row < 2; row++) {
4155 mul[row] = 0.125 * pre_mul[FC(row+1,0) | 1] / pre_mul[FC(row,0) | 1];
4156 blk[row] = cblack[FC(row,0) | 1];
4158 for (i=0; i < 4; i++)
4159 window[i] = (ushort *) fimg + width*i;
4160 for (wlast=-1, row=1; row < height-1; row++) {
4161 while (wlast < row+1) {
4162 for (wlast++, i=0; i < 4; i++)
4163 window[(i+3) & 3] = window[i];
4164 for (col = FC(wlast,1) & 1; col < width; col+=2)
4165 window[2][col] = BAYER(wlast,col);
4167 thold = threshold/512;
4168 for (col = (FC(row,0) & 1)+1; col < width-1; col+=2) {
4169 avg = ( window[0][col-1] + window[0][col+1] +
4170 window[2][col-1] + window[2][col+1] - blk[~row & 1]*4 )
4171 * mul[row & 1] + (window[1][col] + blk[row & 1]) * 0.5;
4172 avg = avg < 0 ? 0 : sqrt(avg);
4173 diff = sqrt(BAYER(row,col)) - avg;
4174 if (diff < -thold) diff += thold;
4175 else if (diff > thold) diff -= thold;
4177 BAYER(row,col) = CLIP(SQR(avg+diff) + 0.5);
4184 void CLASS scale_colors()
4186 unsigned bottom, right, size, row, col, ur, uc, i, x, y, c, sum[8];
4188 double dsum[8], dmin, dmax;
4189 float scale_mul[4], fr, fc;
4190 ushort *img=0, *pix;
4193 memcpy (pre_mul, user_mul, sizeof pre_mul);
4194 if (use_auto_wb || (use_camera_wb && cam_mul[0] == -1)) {
4195 memset (dsum, 0, sizeof dsum);
4196 bottom = MIN (greybox[1]+greybox[3], height);
4197 right = MIN (greybox[0]+greybox[2], width);
4198 for (row=greybox[1]; row < bottom; row += 8)
4199 for (col=greybox[0]; col < right; col += 8) {
4200 memset (sum, 0, sizeof sum);
4201 for (y=row; y < row+8 && y < bottom; y++)
4202 for (x=col; x < col+8 && x < right; x++)
4208 val = image[y*width+x][c];
4209 if (val > maximum-25) goto skip_block;
4210 if ((val -= cblack[c]) < 0) val = 0;
4215 FORC(8) dsum[c] += sum[c];
4218 FORC4 if (dsum[c]) pre_mul[c] = dsum[c+4] / dsum[c];
4220 if (use_camera_wb && cam_mul[0] != -1) {
4221 memset (sum, 0, sizeof sum);
4222 for (row=0; row < 8; row++)
4223 for (col=0; col < 8; col++) {
4225 if ((val = white[row][col] - cblack[c]) > 0)
4229 if (sum[0] && sum[1] && sum[2] && sum[3])
4230 FORC4 pre_mul[c] = (float) sum[c+4] / sum[c];
4231 else if (cam_mul[0] && cam_mul[2])
4232 memcpy (pre_mul, cam_mul, sizeof pre_mul);
4234 fprintf (stderr,_("%s: Cannot use camera white balance.\n"), ifname);
4236 if (pre_mul[1] == 0) pre_mul[1] = 1;
4237 if (pre_mul[3] == 0) pre_mul[3] = colors < 4 ? pre_mul[1] : 1;
4240 if (threshold) wavelet_denoise();
4242 for (dmin=DBL_MAX, dmax=c=0; c < 4; c++) {
4243 if (dmin > pre_mul[c])
4245 if (dmax < pre_mul[c])
4248 if (!highlight) dmax = dmin;
4249 FORC4 scale_mul[c] = (pre_mul[c] /= dmax) * 65535.0 / maximum;
4252 _("Scaling with darkness %d, saturation %d, and\nmultipliers"), dark, sat);
4253 FORC4 fprintf (stderr, " %f", pre_mul[c]);
4254 fputc ('\n', stderr);
4256 if (filters > 1000 && (cblack[4]+1)/2 == 1 && (cblack[5]+1)/2 == 1) {
4257 FORC4 cblack[FC(c/2,c%2)] +=
4258 cblack[6 + c/2 % cblack[4] * cblack[5] + c%2 % cblack[5]];
4259 cblack[4] = cblack[5] = 0;
4261 size = iheight*iwidth;
4262 for (i=0; i < size*4; i++) {
4263 if (!(val = ((ushort *)image)[i])) continue;
4264 if (cblack[4] && cblack[5])
4265 val -= cblack[6 + i/4 / iwidth % cblack[4] * cblack[5] +
4266 i/4 % iwidth % cblack[5]];
4267 val -= cblack[i & 3];
4268 val *= scale_mul[i & 3];
4269 ((ushort *)image)[i] = CLIP(val);
4271 if ((aber[0] != 1 || aber[2] != 1) && colors == 3) {
4273 fprintf (stderr,_("Correcting chromatic aberration...\n"));
4274 for (c=0; c < 4; c+=2) {
4275 if (aber[c] == 1) continue;
4276 img = (ushort *) malloc (size * sizeof *img);
4277 merror (img, "scale_colors()");
4278 for (i=0; i < size; i++)
4279 img[i] = image[i][c];
4280 for (row=0; row < iheight; row++) {
4281 ur = fr = (row - iheight*0.5) * aber[c] + iheight*0.5;
4282 if (ur > iheight-2) continue;
4284 for (col=0; col < iwidth; col++) {
4285 uc = fc = (col - iwidth*0.5) * aber[c] + iwidth*0.5;
4286 if (uc > iwidth-2) continue;
4288 pix = img + ur*iwidth + uc;
4289 image[row*iwidth+col][c] =
4290 (pix[ 0]*(1-fc) + pix[ 1]*fc) * (1-fr) +
4291 (pix[iwidth]*(1-fc) + pix[iwidth+1]*fc) * fr;
4299 void CLASS pre_interpolate()
4309 for (row=0; row < 3; row++)
4310 for (col=1; col < 4; col++)
4311 if (!(image[row*width+col][0] | image[row*width+col][2]))
4312 goto break2; break2:
4313 for ( ; row < height; row+=3)
4314 for (col=(col-1)%3+1; col < width-1; col+=3) {
4315 img = image + row*width+col;
4316 for (c=0; c < 3; c+=2)
4317 img[0][c] = (img[-1][c] + img[1][c]) >> 1;
4321 img = (ushort (*)[4]) calloc (height, width*sizeof *img);
4322 merror (img, "pre_interpolate()");
4323 for (row=0; row < height; row++)
4324 for (col=0; col < width; col++) {
4326 img[row*width+col][c] = image[(row >> 1)*iwidth+(col >> 1)][c];
4333 if (filters > 1000 && colors == 3) {
4334 mix_green = four_color_rgb ^ half_size;
4335 if (four_color_rgb | half_size) colors++;
4337 for (row = FC(1,0) >> 1; row < height; row+=2)
4338 for (col = FC(row,1) & 1; col < width; col+=2)
4339 image[row*width+col][1] = image[row*width+col][3];
4340 filters &= ~((filters & 0x55555555) << 1);
4343 if (half_size) filters = 0;
4346 void CLASS border_interpolate (int border)
4348 unsigned row, col, y, x, f, c, sum[8];
4350 for (row=0; row < height; row++)
4351 for (col=0; col < width; col++) {
4352 if (col==border && row >= border && row < height-border)
4354 memset (sum, 0, sizeof sum);
4355 for (y=row-1; y != row+2; y++)
4356 for (x=col-1; x != col+2; x++)
4357 if (y < height && x < width) {
4359 sum[f] += image[y*width+x][f];
4363 FORCC if (c != f && sum[c+4])
4364 image[row*width+col][c] = sum[c] / sum[c+4];
4368 void CLASS lin_interpolate()
4370 int code[16][16][32], size=16, *ip, sum[4];
4371 int f, c, i, x, y, row, col, shift, color;
4374 if (verbose) fprintf (stderr,_("Bilinear interpolation...\n"));
4375 if (filters == 9) size = 6;
4376 border_interpolate(1);
4377 for (row=0; row < size; row++)
4378 for (col=0; col < size; col++) {
4379 ip = code[row][col]+1;
4381 memset (sum, 0, sizeof sum);
4382 for (y=-1; y <= 1; y++)
4383 for (x=-1; x <= 1; x++) {
4384 shift = (y==0) + (x==0);
4385 color = fcol(row+y,col+x);
4386 if (color == f) continue;
4387 *ip++ = (width*y + x)*4 + color;
4390 sum[color] += 1 << shift;
4392 code[row][col][0] = (ip - code[row][col]) / 3;
4396 *ip++ = 256 / sum[c];
4399 for (row=1; row < height-1; row++)
4400 for (col=1; col < width-1; col++) {
4401 pix = image[row*width+col];
4402 ip = code[row % size][col % size];
4403 memset (sum, 0, sizeof sum);
4404 for (i=*ip++; i--; ip+=3)
4405 sum[ip[2]] += pix[ip[0]] << ip[1];
4406 for (i=colors; --i; ip+=2)
4407 pix[ip[0]] = sum[ip[0]] * ip[1] >> 8;
4412 This algorithm is officially called:
4414 "Interpolation using a Threshold-based variable number of gradients"
4416 described in http://scien.stanford.edu/pages/labsite/1999/psych221/projects/99/tingchen/algodep/vargra.html
4418 I've extended the basic idea to work with non-Bayer filter arrays.
4419 Gradients are numbered clockwise from NW=0 to W=7.
4421 void CLASS vng_interpolate()
4423 static const signed char terms[] = {
4424 -2,-2,+0,-1,0,0x01, -2,-2,+0,+0,1,0x01, -2,-1,-1,+0,0,0x01,
4425 -2,-1,+0,-1,0,0x02, -2,-1,+0,+0,0,0x03, -2,-1,+0,+1,1,0x01,
4426 -2,+0,+0,-1,0,0x06, -2,+0,+0,+0,1,0x02, -2,+0,+0,+1,0,0x03,
4427 -2,+1,-1,+0,0,0x04, -2,+1,+0,-1,1,0x04, -2,+1,+0,+0,0,0x06,
4428 -2,+1,+0,+1,0,0x02, -2,+2,+0,+0,1,0x04, -2,+2,+0,+1,0,0x04,
4429 -1,-2,-1,+0,0,0x80, -1,-2,+0,-1,0,0x01, -1,-2,+1,-1,0,0x01,
4430 -1,-2,+1,+0,1,0x01, -1,-1,-1,+1,0,0x88, -1,-1,+1,-2,0,0x40,
4431 -1,-1,+1,-1,0,0x22, -1,-1,+1,+0,0,0x33, -1,-1,+1,+1,1,0x11,
4432 -1,+0,-1,+2,0,0x08, -1,+0,+0,-1,0,0x44, -1,+0,+0,+1,0,0x11,
4433 -1,+0,+1,-2,1,0x40, -1,+0,+1,-1,0,0x66, -1,+0,+1,+0,1,0x22,
4434 -1,+0,+1,+1,0,0x33, -1,+0,+1,+2,1,0x10, -1,+1,+1,-1,1,0x44,
4435 -1,+1,+1,+0,0,0x66, -1,+1,+1,+1,0,0x22, -1,+1,+1,+2,0,0x10,
4436 -1,+2,+0,+1,0,0x04, -1,+2,+1,+0,1,0x04, -1,+2,+1,+1,0,0x04,
4437 +0,-2,+0,+0,1,0x80, +0,-1,+0,+1,1,0x88, +0,-1,+1,-2,0,0x40,
4438 +0,-1,+1,+0,0,0x11, +0,-1,+2,-2,0,0x40, +0,-1,+2,-1,0,0x20,
4439 +0,-1,+2,+0,0,0x30, +0,-1,+2,+1,1,0x10, +0,+0,+0,+2,1,0x08,
4440 +0,+0,+2,-2,1,0x40, +0,+0,+2,-1,0,0x60, +0,+0,+2,+0,1,0x20,
4441 +0,+0,+2,+1,0,0x30, +0,+0,+2,+2,1,0x10, +0,+1,+1,+0,0,0x44,
4442 +0,+1,+1,+2,0,0x10, +0,+1,+2,-1,1,0x40, +0,+1,+2,+0,0,0x60,
4443 +0,+1,+2,+1,0,0x20, +0,+1,+2,+2,0,0x10, +1,-2,+1,+0,0,0x80,
4444 +1,-1,+1,+1,0,0x88, +1,+0,+1,+2,0,0x08, +1,+0,+2,-1,0,0x40,
4446 }, chood[] = { -1,-1, -1,0, -1,+1, 0,+1, +1,+1, +1,0, +1,-1, 0,-1 };
4447 const signed char *cp;
4448 ushort (*brow[5])[4], *pix;
4449 int prow=8, pcol=2, *ip, *code[16][16], gval[8], gmin, gmax, sum[4];
4450 int row, col, x, y, x1, x2, y1, y2, t, weight, grads, color, diag;
4451 int g, diff, thold, num, c;
4454 if (verbose) fprintf (stderr,_("VNG interpolation...\n"));
4456 if (filters == 1) prow = pcol = 16;
4457 if (filters == 9) prow = pcol = 6;
4458 ip = (int *) calloc (prow*pcol, 1280);
4459 merror (ip, "vng_interpolate()");
4460 for (row=0; row < prow; row++) /* Precalculate for VNG */
4461 for (col=0; col < pcol; col++) {
4462 code[row][col] = ip;
4463 for (cp=terms, t=0; t < 64; t++) {
4464 y1 = *cp++; x1 = *cp++;
4465 y2 = *cp++; x2 = *cp++;
4468 color = fcol(row+y1,col+x1);
4469 if (fcol(row+y2,col+x2) != color) continue;
4470 diag = (fcol(row,col+1) == color && fcol(row+1,col) == color) ? 2:1;
4471 if (abs(y1-y2) == diag && abs(x1-x2) == diag) continue;
4472 *ip++ = (y1*width + x1)*4 + color;
4473 *ip++ = (y2*width + x2)*4 + color;
4475 for (g=0; g < 8; g++)
4476 if (grads & 1<<g) *ip++ = g;
4480 for (cp=chood, g=0; g < 8; g++) {
4481 y = *cp++; x = *cp++;
4482 *ip++ = (y*width + x) * 4;
4483 color = fcol(row,col);
4484 if (fcol(row+y,col+x) != color && fcol(row+y*2,col+x*2) == color)
4485 *ip++ = (y*width + x) * 8 + color;
4490 brow[4] = (ushort (*)[4]) calloc (width*3, sizeof **brow);
4491 merror (brow[4], "vng_interpolate()");
4492 for (row=0; row < 3; row++)
4493 brow[row] = brow[4] + row*width;
4494 for (row=2; row < height-2; row++) { /* Do VNG interpolation */
4495 for (col=2; col < width-2; col++) {
4496 pix = image[row*width+col];
4497 ip = code[row % prow][col % pcol];
4498 memset (gval, 0, sizeof gval);
4499 while ((g = ip[0]) != INT_MAX) { /* Calculate gradients */
4500 diff = ABS(pix[g] - pix[ip[1]]) << ip[2];
4501 gval[ip[3]] += diff;
4503 if ((g = ip[-1]) == -1) continue;
4505 while ((g = *ip++) != -1)
4509 gmin = gmax = gval[0]; /* Choose a threshold */
4510 for (g=1; g < 8; g++) {
4511 if (gmin > gval[g]) gmin = gval[g];
4512 if (gmax < gval[g]) gmax = gval[g];
4515 memcpy (brow[2][col], pix, sizeof *image);
4518 thold = gmin + (gmax >> 1);
4519 memset (sum, 0, sizeof sum);
4520 color = fcol(row,col);
4521 for (num=g=0; g < 8; g++,ip+=2) { /* Average the neighbors */
4522 if (gval[g] <= thold) {
4524 if (c == color && ip[1])
4525 sum[c] += (pix[c] + pix[ip[1]]) >> 1;
4527 sum[c] += pix[ip[0] + c];
4531 FORCC { /* Save to buffer */
4534 t += (sum[c] - sum[color]) / num;
4535 brow[2][col][c] = CLIP(t);
4538 if (row > 3) /* Write buffer to image */
4539 memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image);
4540 for (g=0; g < 4; g++)
4541 brow[(g-1) & 3] = brow[g];
4543 memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image);
4544 memcpy (image[(row-1)*width+2], brow[1]+2, (width-4)*sizeof *image);
4550 Patterned Pixel Grouping Interpolation by Alain Desbiolles
4552 void CLASS ppg_interpolate()
4554 int dir[5] = { 1, width, -1, -width, 1 };
4555 int row, col, diff[2], guess[2], c, d, i;
4557 diff[0] = diff[1] = 0;
4559 border_interpolate(3);
4560 if (verbose) fprintf (stderr,_("PPG interpolation...\n"));
4562 /* Fill in the green layer with gradients and pattern recognition: */
4563 for (row=3; row < height-3; row++)
4564 for (col=3+(FC(row,3) & 1), c=FC(row,col); col < width-3; col+=2) {
4565 pix = image + row*width+col;
4566 for (i=0; (d=dir[i]) > 0; i++) {
4567 guess[i] = (pix[-d][1] + pix[0][c] + pix[d][1]) * 2
4568 - pix[-2*d][c] - pix[2*d][c];
4569 diff[i] = ( ABS(pix[-2*d][c] - pix[ 0][c]) +
4570 ABS(pix[ 2*d][c] - pix[ 0][c]) +
4571 ABS(pix[ -d][1] - pix[ d][1]) ) * 3 +
4572 ( ABS(pix[ 3*d][1] - pix[ d][1]) +
4573 ABS(pix[-3*d][1] - pix[-d][1]) ) * 2;
4575 d = dir[i = diff[0] > diff[1]];
4576 pix[0][1] = ULIM(guess[i] >> 2, pix[d][1], pix[-d][1]);
4578 /* Calculate red and blue for each green pixel: */
4579 for (row=1; row < height-1; row++)
4580 for (col=1+(FC(row,2) & 1), c=FC(row,col+1); col < width-1; col+=2) {
4581 pix = image + row*width+col;
4582 for (i=0; (d=dir[i]) > 0; c=2-c, i++)
4583 pix[0][c] = CLIP((pix[-d][c] + pix[d][c] + 2*pix[0][1]
4584 - pix[-d][1] - pix[d][1]) >> 1);
4586 /* Calculate blue for red pixels and vice versa: */
4587 for (row=1; row < height-1; row++)
4588 for (col=1+(FC(row,1) & 1), c=2-FC(row,col); col < width-1; col+=2) {
4589 pix = image + row*width+col;
4590 for (i=0; (d=dir[i]+dir[i+1]) > 0; i++) {
4591 diff[i] = ABS(pix[-d][c] - pix[d][c]) +
4592 ABS(pix[-d][1] - pix[0][1]) +
4593 ABS(pix[ d][1] - pix[0][1]);
4594 guess[i] = pix[-d][c] + pix[d][c] + 2*pix[0][1]
4595 - pix[-d][1] - pix[d][1];
4597 if (diff[0] != diff[1])
4598 pix[0][c] = CLIP(guess[diff[0] > diff[1]] >> 1);
4600 pix[0][c] = CLIP((guess[0]+guess[1]) >> 2);
4604 void CLASS cielab (ushort rgb[3], short lab[3])
4608 float *cbrt = clb_cbrt, (*xyz_cam)[4] = clb_xyz_cam;
4611 for (i=0; i < 0x10000; i++) {
4613 cbrt[i] = r > 0.008856 ? pow(r,1/3.0) : 7.787*r + 16/116.0;
4615 for (i=0; i < 3; i++)
4616 for (j=0; j < colors; j++)
4617 for (xyz_cam[i][j] = k=0; k < 3; k++)
4618 xyz_cam[i][j] += xyz_rgb[i][k] * rgb_cam[k][j] / d65_white[i];
4621 xyz[0] = xyz[1] = xyz[2] = 0.5;
4623 xyz[0] += xyz_cam[0][c] * rgb[c];
4624 xyz[1] += xyz_cam[1][c] * rgb[c];
4625 xyz[2] += xyz_cam[2][c] * rgb[c];
4627 xyz[0] = cbrt[CLIP((int) xyz[0])];
4628 xyz[1] = cbrt[CLIP((int) xyz[1])];
4629 xyz[2] = cbrt[CLIP((int) xyz[2])];
4630 lab[0] = 64 * (116 * xyz[1] - 16);
4631 lab[1] = 64 * 500 * (xyz[0] - xyz[1]);
4632 lab[2] = 64 * 200 * (xyz[1] - xyz[2]);
4635 #define TS 512 /* Tile Size */
4636 #define fcol(row,col) xtrans[(row+6) % 6][(col+6) % 6]
4639 Frank Markesteijn's algorithm for Fuji X-Trans sensors
4641 void CLASS xtrans_interpolate (int passes)
4643 int c, d, f, g, h, i, v, ng, row, col, top, left, mrow, mcol;
4644 int val, ndir, pass, hm[8], avg[4], color[3][8];
4645 static const short orth[12] = { 1,0,0,1,-1,0,0,-1,1,0,0,1 },
4646 patt[2][16] = { { 0,1,0,-1,2,0,-1,0,1,1,1,-1,0,0,0,0 },
4647 { 0,1,0,-2,1,0,-2,0,1,1,-2,-2,1,-1,-1,1 } },
4648 dir[4] = { 1,TS,TS+1,TS-1 };
4649 short allhex[3][3][2][8], *hex;
4651 ushort min, max, sgrow=0, sgcol=0;
4652 ushort (*rgb)[TS][TS][3], (*rix)[3], (*pix)[4];
4653 short (*lab) [TS][3], (*lix)[3];
4654 float (*drv)[TS][TS], diff[6], tr;
4655 char (*homo)[TS][TS], *buffer;
4658 fprintf (stderr,_("%d-pass X-Trans interpolation...\n"), passes);
4661 ndir = 4 << (passes > 1);
4662 buffer = (char *) malloc (TS*TS*(ndir*11+6));
4663 merror (buffer, "xtrans_interpolate()");
4664 rgb = (ushort(*)[TS][TS][3]) buffer;
4665 lab = (short (*) [TS][3])(buffer + TS*TS*(ndir*6));
4666 drv = (float (*)[TS][TS]) (buffer + TS*TS*(ndir*6+6));
4667 homo = (char (*)[TS][TS]) (buffer + TS*TS*(ndir*10+6));
4669 /* Map a green hexagon around each non-green pixel and vice versa: */
4670 for (row=0; row < 3; row++)
4671 for (col=0; col < 3; col++)
4672 for (ng=d=0; d < 10; d+=2) {
4673 g = fcol(row,col) == 1;
4674 if (fcol(row+orth[d],col+orth[d+2]) == 1) ng=0; else ng++;
4675 if (ng == 4) { sgrow = row; sgcol = col; }
4676 if (ng == g+1) FORC(8) {
4677 v = orth[d ]*patt[g][c*2] + orth[d+1]*patt[g][c*2+1];
4678 h = orth[d+2]*patt[g][c*2] + orth[d+3]*patt[g][c*2+1];
4679 allhex[row][col][0][c^(g*2 & d)] = h + v*width;
4680 allhex[row][col][1][c^(g*2 & d)] = h + v*TS;
4684 /* Set green1 and green3 to the minimum and maximum allowed values: */
4685 for (row=2; row < height-2; row++)
4686 for (min=~(max=0), col=2; col < width-2; col++) {
4687 if (fcol(row,col) == 1 && (min=~(max=0))) continue;
4688 pix = image + row*width + col;
4689 hex = allhex[row % 3][col % 3][0];
4691 val = pix[hex[c]][1];
4692 if (min > val) min = val;
4693 if (max < val) max = val;
4697 switch ((row-sgrow) % 3) {
4698 case 1: if (row < height-3) { row++; col--; } break;
4699 case 2: if ((min=~(max=0)) && (col+=2) < width-3 && row > 2) row--;
4703 for (top=3; top < height-19; top += TS-16)
4704 for (left=3; left < width-19; left += TS-16) {
4705 mrow = MIN (top+TS, height-3);
4706 mcol = MIN (left+TS, width-3);
4707 for (row=top; row < mrow; row++)
4708 for (col=left; col < mcol; col++)
4709 memcpy (rgb[0][row-top][col-left], image[row*width+col], 6);
4710 FORC3 memcpy (rgb[c+1], rgb[0], sizeof *rgb);
4712 /* Interpolate green horizontally, vertically, and along both diagonals: */
4713 for (row=top; row < mrow; row++)
4714 for (col=left; col < mcol; col++) {
4715 if ((f = fcol(row,col)) == 1) continue;
4716 pix = image + row*width + col;
4717 hex = allhex[row % 3][col % 3][0];
4718 color[1][0] = 174 * (pix[ hex[1]][1] + pix[ hex[0]][1]) -
4719 46 * (pix[2*hex[1]][1] + pix[2*hex[0]][1]);
4720 color[1][1] = 223 * pix[ hex[3]][1] + pix[ hex[2]][1] * 33 +
4721 92 * (pix[ 0 ][f] - pix[ -hex[2]][f]);
4722 FORC(2) color[1][2+c] =
4723 164 * pix[hex[4+c]][1] + 92 * pix[-2*hex[4+c]][1] + 33 *
4724 (2*pix[0][f] - pix[3*hex[4+c]][f] - pix[-3*hex[4+c]][f]);
4725 FORC4 rgb[c^!((row-sgrow) % 3)][row-top][col-left][1] =
4726 LIM(color[1][c] >> 8,pix[0][1],pix[0][3]);
4729 for (pass=0; pass < passes; pass++) {
4731 memcpy (rgb+=4, buffer, 4*sizeof *rgb);
4733 /* Recalculate green from interpolated values of closer pixels: */
4735 for (row=top+2; row < mrow-2; row++)
4736 for (col=left+2; col < mcol-2; col++) {
4737 if ((f = fcol(row,col)) == 1) continue;
4738 pix = image + row*width + col;
4739 hex = allhex[row % 3][col % 3][1];
4740 for (d=3; d < 6; d++) {
4741 rix = &rgb[(d-2)^!((row-sgrow) % 3)][row-top][col-left];
4742 val = rix[-2*hex[d]][1] + 2*rix[hex[d]][1]
4743 - rix[-2*hex[d]][f] - 2*rix[hex[d]][f] + 3*rix[0][f];
4744 rix[0][1] = LIM(val/3,pix[0][1],pix[0][3]);
4749 /* Interpolate red and blue values for solitary green pixels: */
4750 for (row=(top-sgrow+4)/3*3+sgrow; row < mrow-2; row+=3)
4751 for (col=(left-sgcol+4)/3*3+sgcol; col < mcol-2; col+=3) {
4752 rix = &rgb[0][row-top][col-left];
4753 h = fcol(row,col+1);
4754 memset (diff, 0, sizeof diff);
4755 for (i=1, d=0; d < 6; d++, i^=TS^1, h^=2) {
4756 for (c=0; c < 2; c++, h^=2) {
4757 g = 2*rix[0][1] - rix[i<<c][1] - rix[-i<<c][1];
4758 color[h][d] = g + rix[i<<c][h] + rix[-i<<c][h];
4760 diff[d] += SQR (rix[i<<c][1] - rix[-i<<c][1]
4761 - rix[i<<c][h] + rix[-i<<c][h]) + SQR(g);
4763 if (d > 1 && (d & 1))
4764 if (diff[d-1] < diff[d])
4765 FORC(2) color[c*2][d] = color[c*2][d-1];
4766 if (d < 2 || (d & 1)) {
4767 FORC(2) rix[0][c*2] = CLIP(color[c*2][d]/2);
4773 /* Interpolate red for blue pixels and vice versa: */
4774 for (row=top+3; row < mrow-3; row++)
4775 for (col=left+3; col < mcol-3; col++) {
4776 if ((f = 2-fcol(row,col)) == 1) continue;
4777 rix = &rgb[0][row-top][col-left];
4778 c = (row-sgrow) % 3 ? TS:1;
4779 h = 3 * (c ^ TS ^ 1);
4780 for (d=0; d < 4; d++, rix += TS*TS) {
4781 i = d > 1 || ((d ^ c) & 1) ||
4782 ((ABS(rix[0][1]-rix[c][1])+ABS(rix[0][1]-rix[-c][1])) <
4783 2*(ABS(rix[0][1]-rix[h][1])+ABS(rix[0][1]-rix[-h][1]))) ? c:h;
4784 rix[0][f] = CLIP((rix[i][f] + rix[-i][f] +
4785 2*rix[0][1] - rix[i][1] - rix[-i][1])/2);
4789 /* Fill in red and blue for 2x2 blocks of green: */
4790 for (row=top+2; row < mrow-2; row++) if ((row-sgrow) % 3)
4791 for (col=left+2; col < mcol-2; col++) if ((col-sgcol) % 3) {
4792 rix = &rgb[0][row-top][col-left];
4793 hex = allhex[row % 3][col % 3][1];
4794 for (d=0; d < ndir; d+=2, rix += TS*TS)
4795 if (hex[d] + hex[d+1]) {
4796 g = 3*rix[0][1] - 2*rix[hex[d]][1] - rix[hex[d+1]][1];
4797 for (c=0; c < 4; c+=2) rix[0][c] =
4798 CLIP((g + 2*rix[hex[d]][c] + rix[hex[d+1]][c])/3);
4800 g = 2*rix[0][1] - rix[hex[d]][1] - rix[hex[d+1]][1];
4801 for (c=0; c < 4; c+=2) rix[0][c] =
4802 CLIP((g + rix[hex[d]][c] + rix[hex[d+1]][c])/2);
4806 rgb = (ushort(*)[TS][TS][3]) buffer;
4810 /* Convert to CIELab and differentiate in all directions: */
4811 for (d=0; d < ndir; d++) {
4812 for (row=2; row < mrow-2; row++)
4813 for (col=2; col < mcol-2; col++)
4814 cielab (rgb[d][row][col], lab[row][col]);
4815 for (f=dir[d & 3],row=3; row < mrow-3; row++)
4816 for (col=3; col < mcol-3; col++) {
4817 lix = &lab[row][col];
4818 g = 2*lix[0][0] - lix[f][0] - lix[-f][0];
4819 drv[d][row][col] = SQR(g)
4820 + SQR((2*lix[0][1] - lix[f][1] - lix[-f][1] + g*500/232))
4821 + SQR((2*lix[0][2] - lix[f][2] - lix[-f][2] - g*500/580));
4825 /* Build homogeneity maps from the derivatives: */
4826 memset(homo, 0, ndir*TS*TS);
4827 for (row=4; row < mrow-4; row++)
4828 for (col=4; col < mcol-4; col++) {
4829 for (tr=FLT_MAX, d=0; d < ndir; d++)
4830 if (tr > drv[d][row][col])
4831 tr = drv[d][row][col];
4833 for (d=0; d < ndir; d++)
4834 for (v=-1; v <= 1; v++)
4835 for (h=-1; h <= 1; h++)
4836 if (drv[d][row+v][col+h] <= tr)
4837 homo[d][row][col]++;
4840 /* Average the most homogenous pixels for the final result: */
4841 if (height-top < TS+4) mrow = height-top+2;
4842 if (width-left < TS+4) mcol = width-left+2;
4843 for (row = MIN(top,8); row < mrow-8; row++)
4844 for (col = MIN(left,8); col < mcol-8; col++) {
4845 for (d=0; d < ndir; d++)
4846 for (hm[d]=0, v=-2; v <= 2; v++)
4847 for (h=-2; h <= 2; h++)
4848 hm[d] += homo[d][row+v][col+h];
4849 for (d=0; d < ndir-4; d++)
4850 if (hm[d] < hm[d+4]) hm[d ] = 0; else
4851 if (hm[d] > hm[d+4]) hm[d+4] = 0;
4852 for (max=hm[0],d=1; d < ndir; d++)
4853 if (max < hm[d]) max = hm[d];
4855 memset (avg, 0, sizeof avg);
4856 for (d=0; d < ndir; d++)
4858 FORC3 avg[c] += rgb[d][row][col][c];
4861 FORC3 image[(row+top)*width+col+left][c] = avg[c]/avg[3];
4865 border_interpolate(8);
4870 Adaptive Homogeneity-Directed interpolation is based on
4871 the work of Keigo Hirakawa, Thomas Parks, and Paul Lee.
4873 void CLASS ahd_interpolate()
4875 int i, j, top, left, row, col, tr, tc, c, d, val, hm[2];
4876 static const int dir[4] = { -1, 1, -TS, TS };
4877 unsigned ldiff[2][4], abdiff[2][4], leps, abeps;
4878 ushort (*rgb)[TS][TS][3], (*rix)[3], (*pix)[4];
4879 short (*lab)[TS][TS][3], (*lix)[3];
4880 char (*homo)[TS][TS], *buffer;
4882 if (verbose) fprintf (stderr,_("AHD interpolation...\n"));
4885 border_interpolate(5);
4886 buffer = (char *) malloc (26*TS*TS);
4887 merror (buffer, "ahd_interpolate()");
4888 rgb = (ushort(*)[TS][TS][3]) buffer;
4889 lab = (short (*)[TS][TS][3])(buffer + 12*TS*TS);
4890 homo = (char (*)[TS][TS]) (buffer + 24*TS*TS);
4892 for (top=2; top < height-5; top += TS-6)
4893 for (left=2; left < width-5; left += TS-6) {
4895 /* Interpolate green horizontally and vertically: */
4896 for (row=top; row < top+TS && row < height-2; row++) {
4897 col = left + (FC(row,left) & 1);
4898 for (c = FC(row,col); col < left+TS && col < width-2; col+=2) {
4899 pix = image + row*width+col;
4900 val = ((pix[-1][1] + pix[0][c] + pix[1][1]) * 2
4901 - pix[-2][c] - pix[2][c]) >> 2;
4902 rgb[0][row-top][col-left][1] = ULIM(val,pix[-1][1],pix[1][1]);
4903 val = ((pix[-width][1] + pix[0][c] + pix[width][1]) * 2
4904 - pix[-2*width][c] - pix[2*width][c]) >> 2;
4905 rgb[1][row-top][col-left][1] = ULIM(val,pix[-width][1],pix[width][1]);
4908 /* Interpolate red and blue, and convert to CIELab: */
4909 for (d=0; d < 2; d++)
4910 for (row=top+1; row < top+TS-1 && row < height-3; row++)
4911 for (col=left+1; col < left+TS-1 && col < width-3; col++) {
4912 pix = image + row*width+col;
4913 rix = &rgb[d][row-top][col-left];
4914 lix = &lab[d][row-top][col-left];
4915 if ((c = 2 - FC(row,col)) == 1) {
4917 val = pix[0][1] + (( pix[-1][2-c] + pix[1][2-c]
4918 - rix[-1][1] - rix[1][1] ) >> 1);
4919 rix[0][2-c] = CLIP(val);
4920 val = pix[0][1] + (( pix[-width][c] + pix[width][c]
4921 - rix[-TS][1] - rix[TS][1] ) >> 1);
4923 val = rix[0][1] + (( pix[-width-1][c] + pix[-width+1][c]
4924 + pix[+width-1][c] + pix[+width+1][c]
4925 - rix[-TS-1][1] - rix[-TS+1][1]
4926 - rix[+TS-1][1] - rix[+TS+1][1] + 1) >> 2);
4927 rix[0][c] = CLIP(val);
4929 rix[0][c] = pix[0][c];
4930 cielab (rix[0],lix[0]);
4932 /* Build homogeneity maps from the CIELab images: */
4933 memset (homo, 0, 2*TS*TS);
4934 for (row=top+2; row < top+TS-2 && row < height-4; row++) {
4936 for (col=left+2; col < left+TS-2 && col < width-4; col++) {
4938 for (d=0; d < 2; d++) {
4939 lix = &lab[d][tr][tc];
4940 for (i=0; i < 4; i++) {
4941 ldiff[d][i] = ABS(lix[0][0]-lix[dir[i]][0]);
4942 abdiff[d][i] = SQR(lix[0][1]-lix[dir[i]][1])
4943 + SQR(lix[0][2]-lix[dir[i]][2]);
4946 leps = MIN(MAX(ldiff[0][0],ldiff[0][1]),
4947 MAX(ldiff[1][2],ldiff[1][3]));
4948 abeps = MIN(MAX(abdiff[0][0],abdiff[0][1]),
4949 MAX(abdiff[1][2],abdiff[1][3]));
4950 for (d=0; d < 2; d++)
4951 for (i=0; i < 4; i++)
4952 if (ldiff[d][i] <= leps && abdiff[d][i] <= abeps)
4956 /* Combine the most homogenous pixels for the final result: */
4957 for (row=top+3; row < top+TS-3 && row < height-5; row++) {
4959 for (col=left+3; col < left+TS-3 && col < width-5; col++) {
4961 for (d=0; d < 2; d++)
4962 for (hm[d]=0, i=tr-1; i <= tr+1; i++)
4963 for (j=tc-1; j <= tc+1; j++)
4964 hm[d] += homo[d][i][j];
4966 FORC3 image[row*width+col][c] = rgb[hm[1] > hm[0]][tr][tc][c];
4968 FORC3 image[row*width+col][c] =
4969 (rgb[0][tr][tc][c] + rgb[1][tr][tc][c]) >> 1;
4977 void CLASS median_filter()
4980 int pass, c, i, j, k, med[9];
4981 static const uchar opt[] = /* Optimal 9-element median search */
4982 { 1,2, 4,5, 7,8, 0,1, 3,4, 6,7, 1,2, 4,5, 7,8,
4983 0,3, 5,8, 4,7, 3,6, 1,4, 2,5, 4,7, 4,2, 6,4, 4,2 };
4985 for (pass=1; pass <= med_passes; pass++) {
4987 fprintf (stderr,_("Median filter pass %d...\n"), pass);
4988 for (c=0; c < 3; c+=2) {
4989 for (pix = image; pix < image+width*height; pix++)
4990 pix[0][3] = pix[0][c];
4991 for (pix = image+width; pix < image+width*(height-1); pix++) {
4992 if ((pix-image+1) % width < 2) continue;
4993 for (k=0, i = -width; i <= width; i += width)
4994 for (j = i-1; j <= i+1; j++)
4995 med[k++] = pix[j][3] - pix[j][1];
4996 for (i=0; i < sizeof opt; i+=2)
4997 if (med[opt[i]] > med[opt[i+1]])
4998 SWAP (med[opt[i]] , med[opt[i+1]]);
4999 pix[0][c] = CLIP(med[4] + pix[0][1]);
5005 void CLASS blend_highlights()
5007 int clip=INT_MAX, row, col, c, i, j;
5008 static const float trans[2][4][4] =
5009 { { { 1,1,1 }, { 1.7320508,-1.7320508,0 }, { -1,-1,2 } },
5010 { { 1,1,1,1 }, { 1,-1,1,-1 }, { 1,1,-1,-1 }, { 1,-1,-1,1 } } };
5011 static const float itrans[2][4][4] =
5012 { { { 1,0.8660254,-0.5 }, { 1,-0.8660254,-0.5 }, { 1,0,1 } },
5013 { { 1,1,1,1 }, { 1,-1,1,-1 }, { 1,1,-1,-1 }, { 1,-1,-1,1 } } };
5014 float cam[2][4], lab[2][4], sum[2], chratio;
5016 if ((unsigned) (colors-3) > 1) return;
5017 if (verbose) fprintf (stderr,_("Blending highlights...\n"));
5018 FORCC if (clip > (i = 65535*pre_mul[c])) clip = i;
5019 for (row=0; row < height; row++)
5020 for (col=0; col < width; col++) {
5021 FORCC if (image[row*width+col][c] > clip) break;
5022 if (c == colors) continue;
5024 cam[0][c] = image[row*width+col][c];
5025 cam[1][c] = MIN(cam[0][c],clip);
5027 for (i=0; i < 2; i++) {
5028 FORCC for (lab[i][c]=j=0; j < colors; j++)
5029 lab[i][c] += trans[colors-3][c][j] * cam[i][j];
5030 for (sum[i]=0,c=1; c < colors; c++)
5031 sum[i] += SQR(lab[i][c]);
5033 chratio = sqrt(sum[1]/sum[0]);
5034 for (c=1; c < colors; c++)
5035 lab[0][c] *= chratio;
5036 FORCC for (cam[0][c]=j=0; j < colors; j++)
5037 cam[0][c] += itrans[colors-3][c][j] * lab[0][j];
5038 FORCC image[row*width+col][c] = cam[0][c] / colors;
5042 #define SCALE (4 >> shrink)
5043 void CLASS recover_highlights()
5045 float *map, sum, wgt, grow;
5046 int hsat[4], count, spread, change, val, i;
5047 unsigned high, wide, mrow, mcol, row, col, kc, c, d, y, x;
5049 static const signed char dir[8][2] =
5050 { {-1,-1}, {-1,0}, {-1,1}, {0,1}, {1,1}, {1,0}, {1,-1}, {0,-1} };
5052 if (verbose) fprintf (stderr,_("Rebuilding highlights...\n"));
5054 grow = pow (2, 4-highlight);
5055 FORCC hsat[c] = 32000 * pre_mul[c];
5056 for (kc=0, c=1; c < colors; c++)
5057 if (pre_mul[kc] < pre_mul[c]) kc = c;
5058 high = height / SCALE;
5059 wide = width / SCALE;
5060 map = (float *) calloc (high, wide*sizeof *map);
5061 merror (map, "recover_highlights()");
5062 FORCC if (c != kc) {
5063 memset (map, 0, high*wide*sizeof *map);
5064 for (mrow=0; mrow < high; mrow++)
5065 for (mcol=0; mcol < wide; mcol++) {
5066 sum = wgt = count = 0;
5067 for (row = mrow*SCALE; row < (mrow+1)*SCALE; row++)
5068 for (col = mcol*SCALE; col < (mcol+1)*SCALE; col++) {
5069 pixel = image[row*width+col];
5070 if (pixel[c] / hsat[c] == 1 && pixel[kc] > 24000) {
5076 if (count == SCALE*SCALE)
5077 map[mrow*wide+mcol] = sum / wgt;
5079 for (spread = 32/grow; spread--; ) {
5080 for (mrow=0; mrow < high; mrow++)
5081 for (mcol=0; mcol < wide; mcol++) {
5082 if (map[mrow*wide+mcol]) continue;
5084 for (d=0; d < 8; d++) {
5085 y = mrow + dir[d][0];
5086 x = mcol + dir[d][1];
5087 if (y < high && x < wide && map[y*wide+x] > 0) {
5088 sum += (1 + (d & 1)) * map[y*wide+x];
5089 count += 1 + (d & 1);
5093 map[mrow*wide+mcol] = - (sum+grow) / (count+grow);
5095 for (change=i=0; i < high*wide; i++)
5102 for (i=0; i < high*wide; i++)
5103 if (map[i] == 0) map[i] = 1;
5104 for (mrow=0; mrow < high; mrow++)
5105 for (mcol=0; mcol < wide; mcol++) {
5106 for (row = mrow*SCALE; row < (mrow+1)*SCALE; row++)
5107 for (col = mcol*SCALE; col < (mcol+1)*SCALE; col++) {
5108 pixel = image[row*width+col];
5109 if (pixel[c] / hsat[c] > 1) {
5110 val = pixel[kc] * map[mrow*wide+mcol];
5111 if (pixel[c] < val) pixel[c] = CLIP(val);
5120 void CLASS tiff_get (unsigned base,
5121 unsigned *tag, unsigned *type, unsigned *len, unsigned *save)
5126 *save = ftell(ifp) + 4;
5127 if (*len * ("11124811248484"[*type < 14 ? *type:0]-'0') > 4)
5128 fseek (ifp, get4()+base, SEEK_SET);
5131 void CLASS parse_thumb_note (int base, unsigned toff, unsigned tlen)
5133 unsigned entries, tag, type, len, save;
5137 tiff_get (base, &tag, &type, &len, &save);
5138 if (tag == toff) thumb_offset = get4()+base;
5139 if (tag == tlen) thumb_length = get4();
5140 fseek (ifp, save, SEEK_SET);
5144 void CLASS parse_makernote (int base, int uptag)
5146 static const uchar xlat[2][256] = {
5147 { 0xc1,0xbf,0x6d,0x0d,0x59,0xc5,0x13,0x9d,0x83,0x61,0x6b,0x4f,0xc7,0x7f,0x3d,0x3d,
5148 0x53,0x59,0xe3,0xc7,0xe9,0x2f,0x95,0xa7,0x95,0x1f,0xdf,0x7f,0x2b,0x29,0xc7,0x0d,
5149 0xdf,0x07,0xef,0x71,0x89,0x3d,0x13,0x3d,0x3b,0x13,0xfb,0x0d,0x89,0xc1,0x65,0x1f,
5150 0xb3,0x0d,0x6b,0x29,0xe3,0xfb,0xef,0xa3,0x6b,0x47,0x7f,0x95,0x35,0xa7,0x47,0x4f,
5151 0xc7,0xf1,0x59,0x95,0x35,0x11,0x29,0x61,0xf1,0x3d,0xb3,0x2b,0x0d,0x43,0x89,0xc1,
5152 0x9d,0x9d,0x89,0x65,0xf1,0xe9,0xdf,0xbf,0x3d,0x7f,0x53,0x97,0xe5,0xe9,0x95,0x17,
5153 0x1d,0x3d,0x8b,0xfb,0xc7,0xe3,0x67,0xa7,0x07,0xf1,0x71,0xa7,0x53,0xb5,0x29,0x89,
5154 0xe5,0x2b,0xa7,0x17,0x29,0xe9,0x4f,0xc5,0x65,0x6d,0x6b,0xef,0x0d,0x89,0x49,0x2f,
5155 0xb3,0x43,0x53,0x65,0x1d,0x49,0xa3,0x13,0x89,0x59,0xef,0x6b,0xef,0x65,0x1d,0x0b,
5156 0x59,0x13,0xe3,0x4f,0x9d,0xb3,0x29,0x43,0x2b,0x07,0x1d,0x95,0x59,0x59,0x47,0xfb,
5157 0xe5,0xe9,0x61,0x47,0x2f,0x35,0x7f,0x17,0x7f,0xef,0x7f,0x95,0x95,0x71,0xd3,0xa3,
5158 0x0b,0x71,0xa3,0xad,0x0b,0x3b,0xb5,0xfb,0xa3,0xbf,0x4f,0x83,0x1d,0xad,0xe9,0x2f,
5159 0x71,0x65,0xa3,0xe5,0x07,0x35,0x3d,0x0d,0xb5,0xe9,0xe5,0x47,0x3b,0x9d,0xef,0x35,
5160 0xa3,0xbf,0xb3,0xdf,0x53,0xd3,0x97,0x53,0x49,0x71,0x07,0x35,0x61,0x71,0x2f,0x43,
5161 0x2f,0x11,0xdf,0x17,0x97,0xfb,0x95,0x3b,0x7f,0x6b,0xd3,0x25,0xbf,0xad,0xc7,0xc5,
5162 0xc5,0xb5,0x8b,0xef,0x2f,0xd3,0x07,0x6b,0x25,0x49,0x95,0x25,0x49,0x6d,0x71,0xc7 },
5163 { 0xa7,0xbc,0xc9,0xad,0x91,0xdf,0x85,0xe5,0xd4,0x78,0xd5,0x17,0x46,0x7c,0x29,0x4c,
5164 0x4d,0x03,0xe9,0x25,0x68,0x11,0x86,0xb3,0xbd,0xf7,0x6f,0x61,0x22,0xa2,0x26,0x34,
5165 0x2a,0xbe,0x1e,0x46,0x14,0x68,0x9d,0x44,0x18,0xc2,0x40,0xf4,0x7e,0x5f,0x1b,0xad,
5166 0x0b,0x94,0xb6,0x67,0xb4,0x0b,0xe1,0xea,0x95,0x9c,0x66,0xdc,0xe7,0x5d,0x6c,0x05,
5167 0xda,0xd5,0xdf,0x7a,0xef,0xf6,0xdb,0x1f,0x82,0x4c,0xc0,0x68,0x47,0xa1,0xbd,0xee,
5168 0x39,0x50,0x56,0x4a,0xdd,0xdf,0xa5,0xf8,0xc6,0xda,0xca,0x90,0xca,0x01,0x42,0x9d,
5169 0x8b,0x0c,0x73,0x43,0x75,0x05,0x94,0xde,0x24,0xb3,0x80,0x34,0xe5,0x2c,0xdc,0x9b,
5170 0x3f,0xca,0x33,0x45,0xd0,0xdb,0x5f,0xf5,0x52,0xc3,0x21,0xda,0xe2,0x22,0x72,0x6b,
5171 0x3e,0xd0,0x5b,0xa8,0x87,0x8c,0x06,0x5d,0x0f,0xdd,0x09,0x19,0x93,0xd0,0xb9,0xfc,
5172 0x8b,0x0f,0x84,0x60,0x33,0x1c,0x9b,0x45,0xf1,0xf0,0xa3,0x94,0x3a,0x12,0x77,0x33,
5173 0x4d,0x44,0x78,0x28,0x3c,0x9e,0xfd,0x65,0x57,0x16,0x94,0x6b,0xfb,0x59,0xd0,0xc8,
5174 0x22,0x36,0xdb,0xd2,0x63,0x98,0x43,0xa1,0x04,0x87,0x86,0xf7,0xa6,0x26,0xbb,0xd6,
5175 0x59,0x4d,0xbf,0x6a,0x2e,0xaa,0x2b,0xef,0xe6,0x78,0xb6,0x4e,0xe0,0x2f,0xdc,0x7c,
5176 0xbe,0x57,0x19,0x32,0x7e,0x2a,0xd0,0xb8,0xba,0x29,0x00,0x3c,0x52,0x7d,0xa8,0x49,
5177 0x3b,0x2d,0xeb,0x25,0x49,0xfa,0xa3,0xaa,0x39,0xa7,0xc5,0xa7,0x50,0x11,0x36,0xfb,
5178 0xc6,0x67,0x4a,0xf5,0xa5,0x12,0x65,0x7e,0xb0,0xdf,0xaf,0x4e,0xb3,0x61,0x7f,0x2f } };
5179 unsigned offset=0, entries, tag, type, len, save, c;
5180 unsigned ver97=0, serial=0, i, wbi=0, wb[4]={0,0,0,0};
5181 uchar buf97[324], ci, cj, ck;
5182 short morder, sorder=order;
5185 The MakerNote might have its own TIFF header (possibly with
5186 its own byte-order!), or it might just be a table.
5188 if (!strcmp(make,"Nokia")) return;
5189 fread (buf, 1, 10, ifp);
5190 if (!strncmp (buf,"KDK" ,3) || /* these aren't TIFF tables */
5191 !strncmp (buf,"VER" ,3) ||
5192 !strncmp (buf,"IIII",4) ||
5193 !strncmp (buf,"MMMM",4)) return;
5194 if (!strncmp (buf,"KC" ,2) || /* Konica KD-400Z, KD-510Z */
5195 !strncmp (buf,"MLY" ,3)) { /* Minolta DiMAGE G series */
5197 while ((i=ftell(ifp)) < data_offset && i < 16384) {
5198 wb[0] = wb[2]; wb[2] = wb[1]; wb[1] = wb[3];
5200 if (wb[1] == 256 && wb[3] == 256 &&
5201 wb[0] > 256 && wb[0] < 640 && wb[2] > 256 && wb[2] < 640)
5202 FORC4 cam_mul[c] = wb[c];
5206 if (!strcmp (buf,"Nikon")) {
5209 if (get2() != 42) goto quit;
5211 fseek (ifp, offset-8, SEEK_CUR);
5212 } else if (!strcmp (buf,"OLYMPUS") ||
5213 !strcmp (buf,"PENTAX ")) {
5214 base = ftell(ifp)-10;
5215 fseek (ifp, -2, SEEK_CUR);
5217 if (buf[0] == 'O') get2();
5218 } else if (!strncmp (buf,"SONY",4) ||
5219 !strcmp (buf,"Panasonic")) {
5221 } else if (!strncmp (buf,"FUJIFILM",8)) {
5222 base = ftell(ifp)-10;
5224 fseek (ifp, 2, SEEK_CUR);
5225 } else if (!strcmp (buf,"OLYMP") ||
5226 !strcmp (buf,"LEICA") ||
5227 !strcmp (buf,"Ricoh") ||
5228 !strcmp (buf,"EPSON"))
5229 fseek (ifp, -2, SEEK_CUR);
5230 else if (!strcmp (buf,"AOC") ||
5231 !strcmp (buf,"QVC"))
5232 fseek (ifp, -4, SEEK_CUR);
5234 fseek (ifp, -10, SEEK_CUR);
5235 if (!strncmp(make,"SAMSUNG",7))
5239 if (entries > 1000) return;
5243 tiff_get (base, &tag, &type, &len, &save);
5245 if (tag == 2 && strstr(make,"NIKON") && !iso_speed)
5246 iso_speed = (get2(),get2());
5247 if (tag == 4 && len > 26 && len < 35) {
5248 if ((i=(get4(),get2())) != 0x7fff && !iso_speed)
5249 iso_speed = 50 * pow (2, i/32.0 - 4);
5250 if ((i=(get2(),get2())) != 0x7fff && !aperture)
5251 aperture = pow (2, i/64.0);
5252 if ((i=get2()) != 0xffff && !shutter)
5253 shutter = pow (2, (short) i/-32.0);
5254 wbi = (get2(),get2());
5255 shot_order = (get2(),get2());
5257 if ((tag == 4 || tag == 0x114) && !strncmp(make,"KONICA",6)) {
5258 fseek (ifp, tag == 4 ? 140:160, SEEK_CUR);
5260 case 72: flip = 0; break;
5261 case 76: flip = 6; break;
5262 case 82: flip = 5; break;
5265 if (tag == 7 && type == 2 && len > 20)
5266 fgets (model2, 64, ifp);
5267 if (tag == 8 && type == 4)
5268 shot_order = get4();
5269 if (tag == 9 && !strcmp(make,"Canon"))
5270 fread (artist, 64, 1, ifp);
5271 if (tag == 0xc && len == 4)
5272 FORC3 cam_mul[(c << 1 | c >> 1) & 3] = getreal(type);
5273 if (tag == 0xd && type == 7 && get2() == 0xaaaa) {
5274 for (c=i=2; (ushort) c != 0xbbbb && i < len; i++)
5275 c = c << 8 | fgetc(ifp);
5276 while ((i+=4) < len-5)
5277 if (get4() == 257 && (i=len) && (c = (get4(),fgetc(ifp))) < 3)
5278 flip = "065"[c]-'0';
5280 if (tag == 0x10 && type == 4)
5282 if (tag == 0x11 && is_raw && !strncmp(make,"NIKON",5)) {
5283 fseek (ifp, get4()+base, SEEK_SET);
5284 parse_tiff_ifd (base);
5286 if (tag == 0x14 && type == 7) {
5288 fseek (ifp, 1248, SEEK_CUR);
5291 fread (buf, 1, 10, ifp);
5292 if (!strncmp(buf,"NRW ",4)) {
5293 fseek (ifp, strcmp(buf+4,"0100") ? 46:1546, SEEK_CUR);
5294 cam_mul[0] = get4() << 2;
5295 cam_mul[1] = get4() + get4();
5296 cam_mul[2] = get4() << 2;
5299 if (tag == 0x15 && type == 2 && is_raw)
5300 fread (model, 64, 1, ifp);
5301 if (strstr(make,"PENTAX")) {
5302 if (tag == 0x1b) tag = 0x1018;
5303 if (tag == 0x1c) tag = 0x1017;
5306 while ((c = fgetc(ifp)) && c != EOF)
5307 serial = serial*10 + (isdigit(c) ? c - '0' : c % 10);
5308 if (tag == 0x29 && type == 1) {
5309 c = wbi < 18 ? "012347800000005896"[wbi]-'0' : 0;
5310 fseek (ifp, 8 + c*32, SEEK_CUR);
5311 FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get4();
5313 if (tag == 0x3d && type == 3 && len == 4)
5314 FORC4 cblack[c ^ c >> 1] = get2() >> (14-tiff_bps);
5315 if (tag == 0x81 && type == 4) {
5316 data_offset = get4();
5317 fseek (ifp, data_offset + 41, SEEK_SET);
5318 raw_height = get2() * 2;
5320 filters = 0x61616161;
5322 if ((tag == 0x81 && type == 7) ||
5323 (tag == 0x100 && type == 7) ||
5324 (tag == 0x280 && type == 1)) {
5325 thumb_offset = ftell(ifp);
5328 if (tag == 0x88 && type == 4 && (thumb_offset = get4()))
5329 thumb_offset += base;
5330 if (tag == 0x89 && type == 4)
5331 thumb_length = get4();
5332 if (tag == 0x8c || tag == 0x96)
5333 meta_offset = ftell(ifp);
5335 for (i=0; i < 4; i++)
5336 ver97 = ver97 * 10 + fgetc(ifp)-'0';
5339 fseek (ifp, 68, SEEK_CUR);
5340 FORC4 cam_mul[(c >> 1) | ((c & 1) << 1)] = get2();
5343 fseek (ifp, 6, SEEK_CUR);
5344 FORC4 cam_mul[c ^ (c >> 1)] = get2();
5347 fseek (ifp, 16, SEEK_CUR);
5348 FORC4 cam_mul[c] = get2();
5351 if (ver97 != 205) fseek (ifp, 280, SEEK_CUR);
5352 fread (buf97, 324, 1, ifp);
5355 if (tag == 0xa1 && type == 7) {
5357 fseek (ifp, 140, SEEK_CUR);
5358 FORC3 cam_mul[c] = get4();
5360 if (tag == 0xa4 && type == 3) {
5361 fseek (ifp, wbi*48, SEEK_CUR);
5362 FORC3 cam_mul[c] = get2();
5364 if (tag == 0xa7 && (unsigned) (ver97-200) < 17) {
5365 ci = xlat[0][serial & 0xff];
5366 cj = xlat[1][fgetc(ifp)^fgetc(ifp)^fgetc(ifp)^fgetc(ifp)];
5368 for (i=0; i < 324; i++)
5369 buf97[i] ^= (cj += ci * ck++);
5370 i = "66666>666;6A;:;55"[ver97-200] - '0';
5371 FORC4 cam_mul[c ^ (c >> 1) ^ (i & 1)] =
5372 sget2 (buf97 + (i & -2) + c*2);
5374 if (tag == 0x200 && len == 3)
5375 shot_order = (get4(),get4());
5376 if (tag == 0x200 && len == 4)
5377 FORC4 cblack[c ^ c >> 1] = get2();
5378 if (tag == 0x201 && len == 4)
5379 FORC4 cam_mul[c ^ (c >> 1)] = get2();
5380 if (tag == 0x220 && type == 7)
5381 meta_offset = ftell(ifp);
5382 if (tag == 0x401 && type == 4 && len == 4)
5383 FORC4 cblack[c ^ c >> 1] = get4();
5384 if (tag == 0xe01) { /* Nikon Capture Note */
5386 fseek (ifp, 22, SEEK_CUR);
5387 for (offset=22; offset+22 < len; offset += 22+i) {
5389 fseek (ifp, 14, SEEK_CUR);
5391 if (tag == 0x76a43207) flip = get2();
5392 else fseek (ifp, i, SEEK_CUR);
5395 if (tag == 0xe80 && len == 256 && type == 7) {
5396 fseek (ifp, 48, SEEK_CUR);
5397 cam_mul[0] = get2() * 508 * 1.078 / 0x10000;
5398 cam_mul[2] = get2() * 382 * 1.173 / 0x10000;
5400 if (tag == 0xf00 && type == 7) {
5402 fseek (ifp, 176, SEEK_CUR);
5403 else if (len == 734 || len == 1502)
5404 fseek (ifp, 148, SEEK_CUR);
5408 if ((tag == 0x1011 && len == 9) || tag == 0x20400200)
5409 for (i=0; i < 3; i++)
5410 FORC3 cmatrix[i][c] = ((short) get2()) / 256.0;
5411 if ((tag == 0x1012 || tag == 0x20400600) && len == 4)
5412 FORC4 cblack[c ^ c >> 1] = get2();
5413 if (tag == 0x1017 || tag == 0x20400100)
5414 cam_mul[0] = get2() / 256.0;
5415 if (tag == 0x1018 || tag == 0x20400100)
5416 cam_mul[2] = get2() / 256.0;
5417 if (tag == 0x2011 && len == 2) {
5420 cam_mul[0] = get2() / 256.0;
5421 cam_mul[2] = get2() / 256.0;
5423 if ((tag | 0x70) == 0x2070 && (type == 4 || type == 13))
5424 fseek (ifp, get4()+base, SEEK_SET);
5425 if (tag == 0x2020 && !strncmp(buf,"OLYMP",5))
5426 parse_thumb_note (base, 257, 258);
5428 parse_makernote (base, 0x2040);
5429 if (tag == 0xb028) {
5430 fseek (ifp, get4()+base, SEEK_SET);
5431 parse_thumb_note (base, 136, 137);
5433 if (tag == 0x4001 && len > 500) {
5434 i = len == 582 ? 50 : len == 653 ? 68 : len == 5120 ? 142 : 126;
5435 fseek (ifp, i, SEEK_CUR);
5436 FORC4 cam_mul[c ^ (c >> 1)] = get2();
5437 for (i+=18; i <= len; i+=10) {
5439 FORC4 sraw_mul[c ^ (c >> 1)] = get2();
5440 if (sraw_mul[1] == 1170) break;
5443 if (tag == 0x4021 && get4() && get4())
5444 FORC4 cam_mul[c] = 1024;
5446 FORC4 cam_mul[c ^ (c >> 1)] = get4();
5448 FORC4 cam_mul[c ^ (c >> 1)] -= get4();
5452 fseek (ifp, save, SEEK_SET);
5459 Since the TIFF DateTime string has no timezone information,
5460 assume that the camera's clock was set to Universal Time.
5462 void CLASS get_timestamp (int reversed)
5470 for (i=19; i--; ) str[i] = fgetc(ifp);
5472 fread (str, 19, 1, ifp);
5473 memset (&t, 0, sizeof t);
5474 if (sscanf (str, "%d:%d:%d %d:%d:%d", &t.tm_year, &t.tm_mon,
5475 &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec) != 6)
5481 timestamp = mktime(&t);
5484 void CLASS parse_exif (int base)
5486 unsigned kodak, entries, tag, type, len, save, c;
5489 kodak = !strncmp(make,"EASTMAN",7) && tiff_nifds < 3;
5492 tiff_get (base, &tag, &type, &len, &save);
5494 case 33434: tiff_ifd[tiff_nifds-1].shutter =
5495 shutter = getreal(type); break;
5496 case 33437: aperture = getreal(type); break;
5497 case 34855: iso_speed = get2(); break;
5499 case 36868: get_timestamp(0); break;
5500 case 37377: if ((expo = -getreal(type)) < 128)
5501 tiff_ifd[tiff_nifds-1].shutter =
5502 shutter = pow (2, expo); break;
5503 case 37378: aperture = pow (2, getreal(type)/2); break;
5504 case 37386: focal_len = getreal(type); break;
5505 case 37500: parse_makernote (base, 0); break;
5506 case 40962: if (kodak) raw_width = get4(); break;
5507 case 40963: if (kodak) raw_height = get4(); break;
5509 if (get4() == 0x20002)
5510 for (exif_cfa=c=0; c < 8; c+=2)
5511 exif_cfa |= fgetc(ifp) * 0x01010101 << c;
5513 fseek (ifp, save, SEEK_SET);
5517 void CLASS parse_gps (int base)
5519 unsigned entries, tag, type, len, save, c;
5523 tiff_get (base, &tag, &type, &len, &save);
5525 case 1: case 3: case 5:
5526 gpsdata[29+tag/2] = getc(ifp); break;
5527 case 2: case 4: case 7:
5528 FORC(6) gpsdata[tag/3*6+c] = get4(); break;
5530 FORC(2) gpsdata[18+c] = get4(); break;
5532 fgets ((char *) (gpsdata+14+tag/3), MIN(len,12), ifp);
5534 fseek (ifp, save, SEEK_SET);
5538 void CLASS romm_coeff (float romm_cam[3][3])
5540 static const float rgb_romm[3][3] = /* ROMM == Kodak ProPhoto */
5541 { { 2.034193, -0.727420, -0.306766 },
5542 { -0.228811, 1.231729, -0.002922 },
5543 { -0.008565, -0.153273, 1.161839 } };
5546 for (i=0; i < 3; i++)
5547 for (j=0; j < 3; j++)
5548 for (cmatrix[i][j] = k=0; k < 3; k++)
5549 cmatrix[i][j] += rgb_romm[i][k] * romm_cam[k][j];
5552 void CLASS parse_mos (int offset)
5555 int skip, from, i, c, neut[4], planes=0, frot=0;
5556 static const char *mod[] =
5557 { "","DCB2","Volare","Cantare","CMost","Valeo 6","Valeo 11","Valeo 22",
5558 "Valeo 11p","Valeo 17","","Aptus 17","Aptus 22","Aptus 75","Aptus 65",
5559 "Aptus 54S","Aptus 65S","Aptus 75S","AFi 5","AFi 6","AFi 7",
5560 "AFi-II 7","Aptus-II 7","","Aptus-II 6","","","Aptus-II 10","Aptus-II 5",
5561 "","","","","Aptus-II 10R","Aptus-II 8","","Aptus-II 12","","AFi-II 12" };
5562 float romm_cam[3][3];
5564 fseek (ifp, offset, SEEK_SET);
5566 if (get4() != 0x504b5453) break;
5568 fread (data, 1, 40, ifp);
5571 if (!strcmp(data,"JPEG_preview_data")) {
5572 thumb_offset = from;
5573 thumb_length = skip;
5575 if (!strcmp(data,"icc_camera_profile")) {
5576 profile_offset = from;
5577 profile_length = skip;
5579 if (!strcmp(data,"ShootObj_back_type")) {
5580 fscanf (ifp, "%d", &i);
5581 if ((unsigned) i < sizeof mod / sizeof (*mod))
5582 strcpy (model, mod[i]);
5584 if (!strcmp(data,"icc_camera_to_tone_matrix")) {
5585 for (i=0; i < 9; i++)
5586 ((float *)romm_cam)[i] = int_to_float(get4());
5587 romm_coeff (romm_cam);
5589 if (!strcmp(data,"CaptProf_color_matrix")) {
5590 for (i=0; i < 9; i++)
5591 fscanf (ifp, "%f", (float *)romm_cam + i);
5592 romm_coeff (romm_cam);
5594 if (!strcmp(data,"CaptProf_number_of_planes"))
5595 fscanf (ifp, "%d", &planes);
5596 if (!strcmp(data,"CaptProf_raw_data_rotation"))
5597 fscanf (ifp, "%d", &flip);
5598 if (!strcmp(data,"CaptProf_mosaic_pattern"))
5600 fscanf (ifp, "%d", &i);
5601 if (i == 1) frot = c ^ (c >> 1);
5603 if (!strcmp(data,"ImgProf_rotation_angle")) {
5604 fscanf (ifp, "%d", &i);
5607 if (!strcmp(data,"NeutObj_neutrals") && !cam_mul[0]) {
5608 FORC4 fscanf (ifp, "%d", neut+c);
5609 FORC3 cam_mul[c] = (float) neut[0] / neut[c+1];
5611 if (!strcmp(data,"Rows_data"))
5612 load_flags = get4();
5614 fseek (ifp, skip+from, SEEK_SET);
5617 filters = (planes == 1) * 0x01010101 *
5618 (uchar) "\x94\x61\x16\x49"[(flip/90 + frot) & 3];
5621 void CLASS linear_table (unsigned len)
5624 if (len > 0x1000) len = 0x1000;
5625 read_shorts (curve, len);
5626 for (i=len; i < 0x1000; i++)
5627 curve[i] = curve[i-1];
5628 maximum = curve[0xfff];
5631 void CLASS parse_kodak_ifd (int base)
5633 unsigned entries, tag, type, len, save;
5634 int i, c, wbi=-2, wbtemp=6500;
5635 float mul[3]={1,1,1}, num;
5636 static const int wbtag[] = { 64037,64040,64039,64041,-1,-1,64042 };
5639 if (entries > 1024) return;
5641 tiff_get (base, &tag, &type, &len, &save);
5642 if (tag == 1020) wbi = getint(type);
5643 if (tag == 1021 && len == 72) { /* WB set in software */
5644 fseek (ifp, 40, SEEK_CUR);
5645 FORC3 cam_mul[c] = 2048.0 / get2();
5648 if (tag == 2118) wbtemp = getint(type);
5649 if (tag == 2120 + wbi && wbi >= 0)
5650 FORC3 cam_mul[c] = 2048.0 / getreal(type);
5651 if (tag == 2130 + wbi)
5652 FORC3 mul[c] = getreal(type);
5653 if (tag == 2140 + wbi && wbi >= 0)
5655 for (num=i=0; i < 4; i++)
5656 num += getreal(type) * pow (wbtemp/100.0, i);
5657 cam_mul[c] = 2048 / (num * mul[c]);
5659 if (tag == 2317) linear_table (len);
5660 if (tag == 6020) iso_speed = getint(type);
5661 if (tag == 64013) wbi = fgetc(ifp);
5662 if ((unsigned) wbi < 7 && tag == wbtag[wbi])
5663 FORC3 cam_mul[c] = get4();
5664 if (tag == 64019) width = getint(type);
5665 if (tag == 64020) height = (getint(type)+1) & -2;
5666 fseek (ifp, save, SEEK_SET);
5670 int CLASS parse_tiff_ifd (int base)
5672 unsigned entries, tag, type, len, plen=16, save;
5673 int ifd, use_cm=0, cfa, i, j, c, ima_len=0;
5674 char software[64], *cbuf, *cp;
5675 uchar cfa_pat[16], cfa_pc[] = { 0,1,2,3 }, tab[256];
5676 double cc[4][4], cm[4][3], cam_xyz[4][3], num;
5677 double ab[]={ 1,1,1,1 }, asn[] = { 0,0,0,0 }, xyz[] = { 1,1,1 };
5678 unsigned sony_curve[] = { 0,0,0,0,0,4095 };
5679 unsigned *buf, sony_offset=0, sony_length=0, sony_key=0;
5683 if (tiff_nifds >= sizeof tiff_ifd / sizeof tiff_ifd[0])
5686 for (j=0; j < 4; j++)
5687 for (i=0; i < 4; i++)
5690 if (entries > 512) return 1;
5692 tiff_get (base, &tag, &type, &len, &save);
5694 case 5: width = get2(); break;
5695 case 6: height = get2(); break;
5696 case 7: width += get2(); break;
5697 case 9: if ((i = get2())) filters = i; break;
5699 if (type == 3 && len == 1)
5700 cam_mul[(tag-17)*2] = get2() / 256.0;
5703 if (type == 3) iso_speed = get2();
5705 case 28: case 29: case 30:
5706 cblack[tag-28] = get2();
5707 cblack[3] = cblack[1];
5709 case 36: case 37: case 38:
5710 cam_mul[tag-36] = get2();
5713 if (len < 50 || cam_mul[0]) break;
5714 fseek (ifp, 12, SEEK_CUR);
5715 FORC3 cam_mul[c] = get2();
5718 if (type != 7 || fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) break;
5719 thumb_offset = ftell(ifp) - 2;
5722 case 61440: /* Fuji HS10 table */
5723 fseek (ifp, get4()+base, SEEK_SET);
5724 parse_tiff_ifd (base);
5726 case 2: case 256: case 61441: /* ImageWidth */
5727 tiff_ifd[ifd].width = getint(type);
5729 case 3: case 257: case 61442: /* ImageHeight */
5730 tiff_ifd[ifd].height = getint(type);
5732 case 258: /* BitsPerSample */
5734 tiff_ifd[ifd].samples = len & 7;
5735 if ((tiff_ifd[ifd].bps = getint(type)) > 32)
5736 tiff_ifd[ifd].bps = 8;
5737 if (tiff_bps < tiff_ifd[ifd].bps)
5738 tiff_bps = tiff_ifd[ifd].bps;
5742 load_flags = get4() ? 24:80;
5744 case 259: /* Compression */
5745 tiff_ifd[ifd].comp = getint(type);
5747 case 262: /* PhotometricInterpretation */
5748 tiff_ifd[ifd].phint = get2();
5750 case 270: /* ImageDescription */
5751 fread (desc, 512, 1, ifp);
5753 case 271: /* Make */
5754 fgets (make, 64, ifp);
5756 case 272: /* Model */
5757 fgets (model, 64, ifp);
5759 case 280: /* Panasonic RW2 offset */
5760 if (type != 4) break;
5761 load_raw = &CLASS panasonic_load_raw;
5762 load_flags = 0x2008;
5763 case 273: /* StripOffset */
5764 case 513: /* JpegIFOffset */
5766 tiff_ifd[ifd].offset = get4()+base;
5767 if (!tiff_ifd[ifd].bps && tiff_ifd[ifd].offset > 0) {
5768 fseek (ifp, tiff_ifd[ifd].offset, SEEK_SET);
5769 if (ljpeg_start (&jh, 1)) {
5770 tiff_ifd[ifd].comp = 6;
5771 tiff_ifd[ifd].width = jh.wide;
5772 tiff_ifd[ifd].height = jh.high;
5773 tiff_ifd[ifd].bps = jh.bits;
5774 tiff_ifd[ifd].samples = jh.clrs;
5775 if (!(jh.sraw || (jh.clrs & 1)))
5776 tiff_ifd[ifd].width *= jh.clrs;
5777 if ((tiff_ifd[ifd].width > 4*tiff_ifd[ifd].height) & ~jh.clrs) {
5778 tiff_ifd[ifd].width /= 2;
5779 tiff_ifd[ifd].height *= 2;
5782 parse_tiff (tiff_ifd[ifd].offset + 12);
5787 case 274: /* Orientation */
5788 tiff_ifd[ifd].flip = "50132467"[get2() & 7]-'0';
5790 case 277: /* SamplesPerPixel */
5791 tiff_ifd[ifd].samples = getint(type) & 7;
5793 case 279: /* StripByteCounts */
5796 tiff_ifd[ifd].bytes = get4();
5799 FORC3 cam_mul[(4-c) % 3] = getint(type);
5801 case 305: case 11: /* Software */
5802 fgets (software, 64, ifp);
5803 if (!strncmp(software,"Adobe",5) ||
5804 !strncmp(software,"dcraw",5) ||
5805 !strncmp(software,"UFRaw",5) ||
5806 !strncmp(software,"Bibble",6) ||
5807 !strncmp(software,"Nikon Scan",10) ||
5808 !strcmp (software,"Digital Photo Professional"))
5811 case 306: /* DateTime */
5814 case 315: /* Artist */
5815 fread (artist, 64, 1, ifp);
5817 case 322: /* TileWidth */
5818 tiff_ifd[ifd].tile_width = getint(type);
5820 case 323: /* TileLength */
5821 tiff_ifd[ifd].tile_length = getint(type);
5823 case 324: /* TileOffsets */
5824 tiff_ifd[ifd].offset = len > 1 ? ftell(ifp) : get4();
5826 tiff_ifd[ifd].tile_width = tiff_ifd[ifd].tile_length = 0;
5828 load_raw = &CLASS sinar_4shot_load_raw;
5832 case 330: /* SubIFDs */
5833 if (!strcmp(model,"DSLR-A100") && tiff_ifd[ifd].width == 3872) {
5834 load_raw = &CLASS sony_arw_load_raw;
5835 data_offset = get4()+base;
5840 fseek (ifp, get4()+base, SEEK_SET);
5841 if (parse_tiff_ifd (base)) break;
5842 fseek (ifp, i+4, SEEK_SET);
5846 strcpy (make, "Sarnoff");
5850 FORC4 sony_curve[c+1] = get2() >> 2 & 0xfff;
5851 for (i=0; i < 5; i++)
5852 for (j = sony_curve[i]+1; j <= sony_curve[i+1]; j++)
5853 curve[j] = curve[j-1] + (1 << i);
5855 case 29184: sony_offset = get4(); break;
5856 case 29185: sony_length = get4(); break;
5857 case 29217: sony_key = get4(); break;
5859 parse_minolta (ftell(ifp));
5863 FORC4 cam_mul[c ^ (c < 2)] = get2();
5866 FORC4 cam_mul[c] = get2();
5867 i = (cam_mul[1] == 1024 && cam_mul[2] == 1024) << 1;
5868 SWAP (cam_mul[i],cam_mul[i+1])
5870 case 33405: /* Model2 */
5871 fgets (model2, 64, ifp);
5873 case 33421: /* CFARepeatPatternDim */
5874 if (get2() == 6 && get2() == 6)
5877 case 33422: /* CFAPattern */
5879 FORC(36) ((char *)xtrans)[c] = fgetc(ifp) & 3;
5882 case 64777: /* Kodak P-series */
5883 if ((plen=len) > 16) plen = 16;
5884 fread (cfa_pat, 1, plen, ifp);
5885 for (colors=cfa=i=0; i < plen && colors < 4; i++) {
5886 colors += !(cfa & (1 << cfa_pat[i]));
5887 cfa |= 1 << cfa_pat[i];
5889 if (cfa == 070) memcpy (cfa_pc,"\003\004\005",3); /* CMY */
5890 if (cfa == 072) memcpy (cfa_pc,"\005\003\004\001",4); /* GMCY */
5894 fseek (ifp, get4()+base, SEEK_SET);
5895 parse_kodak_ifd (base);
5897 case 33434: /* ExposureTime */
5898 tiff_ifd[ifd].shutter = shutter = getreal(type);
5900 case 33437: /* FNumber */
5901 aperture = getreal(type);
5903 case 34306: /* Leaf white balance */
5904 FORC4 cam_mul[c ^ 1] = 4096.0 / get2();
5906 case 34307: /* Leaf CatchLight color matrix */
5907 fread (software, 1, 7, ifp);
5908 if (strncmp(software,"MATRIX",6)) break;
5910 for (raw_color = i=0; i < 3; i++) {
5911 FORC4 fscanf (ifp, "%f", &rgb_cam[i][c^1]);
5912 if (!use_camera_wb) continue;
5914 FORC4 num += rgb_cam[i][c];
5915 FORC4 rgb_cam[i][c] /= num;
5918 case 34310: /* Leaf metadata */
5919 parse_mos (ftell(ifp));
5921 strcpy (make, "Leaf");
5923 case 34665: /* EXIF tag */
5924 fseek (ifp, get4()+base, SEEK_SET);
5927 case 34853: /* GPSInfo tag */
5928 fseek (ifp, get4()+base, SEEK_SET);
5931 case 34675: /* InterColorProfile */
5932 case 50831: /* AsShotICCProfile */
5933 profile_offset = ftell(ifp);
5934 profile_length = len;
5936 case 37122: /* CompressedBitsPerPixel */
5937 kodak_cbpp = get4();
5939 case 37386: /* FocalLength */
5940 focal_len = getreal(type);
5942 case 37393: /* ImageNumber */
5943 shot_order = getint(type);
5945 case 37400: /* old Kodak KDC tag */
5946 for (raw_color = i=0; i < 3; i++) {
5948 FORC3 rgb_cam[i][c] = getreal(type);
5952 strip_offset = get4();
5953 switch (tiff_ifd[ifd].comp) {
5954 case 32770: load_raw = &CLASS samsung_load_raw; break;
5955 case 32772: load_raw = &CLASS samsung2_load_raw; break;
5956 case 32773: load_raw = &CLASS samsung3_load_raw; break;
5959 case 46275: /* Imacon tags */
5960 strcpy (make, "Imacon");
5961 data_offset = ftell(ifp);
5965 if (!ima_len) break;
5966 fseek (ifp, 38, SEEK_CUR);
5968 fseek (ifp, 40, SEEK_CUR);
5970 raw_height = get4();
5971 left_margin = get4() & 7;
5972 width = raw_width - left_margin - (get4() & 7);
5973 top_margin = get4() & 7;
5974 height = raw_height - top_margin - (get4() & 7);
5975 if (raw_width == 7262) {
5980 fseek (ifp, 52, SEEK_CUR);
5981 FORC3 cam_mul[c] = getreal(11);
5982 fseek (ifp, 114, SEEK_CUR);
5983 flip = (get2() >> 7) * 90;
5984 if (width * height * 6 == ima_len) {
5985 if (flip % 180 == 90) SWAP(width,height);
5987 raw_height = height;
5988 left_margin = top_margin = filters = flip = 0;
5990 sprintf (model, "Ixpress %d-Mp", height*width/1000000);
5991 load_raw = &CLASS imacon_full_load_raw;
5993 if (left_margin & 1) filters = 0x61616161;
5994 load_raw = &CLASS unpacked_load_raw;
5998 case 50454: /* Sinar tag */
6000 if (!(cbuf = (char *) malloc(len))) break;
6001 fread (cbuf, 1, len, ifp);
6002 for (cp = cbuf-1; cp && cp < cbuf+len; cp = strchr(cp,'\n'))
6003 if (!strncmp (++cp,"Neutral ",8))
6004 sscanf (cp+8, "%f %f %f", cam_mul, cam_mul+1, cam_mul+2);
6008 if (!make[0]) strcpy (make, "Hasselblad");
6010 case 50459: /* Hasselblad tag */
6015 fseek (ifp, j+(get2(),get4()), SEEK_SET);
6021 case 50706: /* DNGVersion */
6022 FORC4 dng_version = (dng_version << 8) + fgetc(ifp);
6023 if (!make[0]) strcpy (make, "DNG");
6026 case 50708: /* UniqueCameraModel */
6027 if (model[0]) break;
6028 fgets (make, 64, ifp);
6029 if ((cp = strchr(make,' '))) {
6034 case 50710: /* CFAPlaneColor */
6035 if (filters == 9) break;
6036 if (len > 4) len = 4;
6038 fread (cfa_pc, 1, colors, ifp);
6040 FORCC tab[cfa_pc[c]] = c;
6043 filters = filters << 2 | tab[cfa_pat[i % plen]];
6044 filters -= !filters;
6046 case 50711: /* CFALayout */
6047 if (get2() == 2) fuji_width = 1;
6050 case 50712: /* LinearizationTable */
6053 case 50713: /* BlackLevelRepeatDim */
6056 if (cblack[4] * cblack[5] > sizeof cblack / sizeof *cblack - 6)
6057 cblack[4] = cblack[5] = 1;
6060 cblack[4] = cblack[5] = MIN(sqrt(len),64);
6061 case 50714: /* BlackLevel */
6062 if ((cblack[4] * cblack[5])==0)
6063 cblack[4] = cblack[5] = 1;
6064 FORC (cblack[4] * cblack[5])
6065 cblack[6+c] = getreal(type);
6068 case 50715: /* BlackLevelDeltaH */
6069 case 50716: /* BlackLevelDeltaV */
6070 for (num=i=0; i < (len & 0xffff); i++)
6071 num += getreal(type);
6072 black += num/len + 0.5;
6074 case 50717: /* WhiteLevel */
6075 maximum = getint(type);
6077 case 50718: /* DefaultScale */
6078 pixel_aspect = getreal(type);
6079 pixel_aspect /= getreal(type);
6081 case 50721: /* ColorMatrix1 */
6082 case 50722: /* ColorMatrix2 */
6083 FORCC for (j=0; j < 3; j++)
6084 cm[c][j] = getreal(type);
6087 case 50723: /* CameraCalibration1 */
6088 case 50724: /* CameraCalibration2 */
6089 for (i=0; i < colors; i++)
6090 FORCC cc[i][c] = getreal(type);
6092 case 50727: /* AnalogBalance */
6093 FORCC ab[c] = getreal(type);
6095 case 50728: /* AsShotNeutral */
6096 FORCC asn[c] = getreal(type);
6098 case 50729: /* AsShotWhiteXY */
6099 xyz[0] = getreal(type);
6100 xyz[1] = getreal(type);
6101 xyz[2] = 1 - xyz[0] - xyz[1];
6102 FORC3 xyz[c] /= d65_white[c];
6104 case 50740: /* DNGPrivateData */
6105 if (dng_version) break;
6106 parse_minolta (j = get4()+base);
6107 fseek (ifp, j, SEEK_SET);
6108 parse_tiff_ifd (base);
6111 read_shorts (cr2_slice, 3);
6113 case 50829: /* ActiveArea */
6114 top_margin = getint(type);
6115 left_margin = getint(type);
6116 height = getint(type) - top_margin;
6117 width = getint(type) - left_margin;
6119 case 50830: /* MaskedAreas */
6120 for (i=0; i < len && i < 32; i++)
6121 ((int *)mask)[i] = getint(type);
6124 case 51009: /* OpcodeList2 */
6125 meta_offset = ftell(ifp);
6127 case 64772: /* Kodak P-series */
6128 if (len < 13) break;
6129 fseek (ifp, 16, SEEK_CUR);
6130 data_offset = get4();
6131 fseek (ifp, 28, SEEK_CUR);
6132 data_offset += get4();
6133 load_raw = &CLASS packed_load_raw;
6136 if (type == 2) fgets (model2, 64, ifp);
6138 fseek (ifp, save, SEEK_SET);
6140 if (sony_length && (buf = (unsigned *) malloc(sony_length))) {
6141 fseek (ifp, sony_offset, SEEK_SET);
6142 fread (buf, sony_length, 1, ifp);
6143 sony_decrypt (buf, sony_length/4, 1, sony_key);
6145 if ((ifp = tmpfile())) {
6146 fwrite (buf, sony_length, 1, ifp);
6147 fseek (ifp, 0, SEEK_SET);
6148 parse_tiff_ifd (-sony_offset);
6154 for (i=0; i < colors; i++)
6155 FORCC cc[i][c] *= ab[i];
6157 FORCC for (i=0; i < 3; i++)
6158 for (cam_xyz[c][i]=j=0; j < colors; j++)
6159 cam_xyz[c][i] += cc[c][j] * cm[j][i] * xyz[i];
6160 cam_xyz_coeff (cmatrix, cam_xyz);
6164 FORCC cam_mul[c] = 1 / asn[c];
6167 FORCC pre_mul[c] /= cc[c][c];
6171 int CLASS parse_tiff (int base)
6175 fseek (ifp, base, SEEK_SET);
6177 if (order != 0x4949 && order != 0x4d4d) return 0;
6179 while ((doff = get4())) {
6180 fseek (ifp, doff+base, SEEK_SET);
6181 if (parse_tiff_ifd (base)) break;
6186 void CLASS apply_tiff()
6188 int max_samp=0, ties=0, os, ns, raw=-1, thm=-1, i;
6193 fseek (ifp, thumb_offset, SEEK_SET);
6194 if (ljpeg_start (&jh, 1)) {
6195 thumb_misc = jh.bits;
6196 thumb_width = jh.wide;
6197 thumb_height = jh.high;
6200 for (i=tiff_nifds; i--; ) {
6201 if (tiff_ifd[i].shutter)
6202 shutter = tiff_ifd[i].shutter;
6203 tiff_ifd[i].shutter = shutter;
6205 for (i=0; i < tiff_nifds; i++) {
6206 if (max_samp < tiff_ifd[i].samples)
6207 max_samp = tiff_ifd[i].samples;
6208 if (max_samp > 3) max_samp = 3;
6209 os = raw_width*raw_height;
6210 ns = tiff_ifd[i].width*tiff_ifd[i].height;
6213 ns *= tiff_ifd[i].bps;
6215 if ((tiff_ifd[i].comp != 6 || tiff_ifd[i].samples != 3) &&
6216 (tiff_ifd[i].width | tiff_ifd[i].height) < 0x10000 &&
6217 ns && ((ns > os && (ties = 1)) ||
6218 (ns == os && shot_select == ties++))) {
6219 raw_width = tiff_ifd[i].width;
6220 raw_height = tiff_ifd[i].height;
6221 tiff_bps = tiff_ifd[i].bps;
6222 tiff_compress = tiff_ifd[i].comp;
6223 data_offset = tiff_ifd[i].offset;
6224 tiff_flip = tiff_ifd[i].flip;
6225 tiff_samples = tiff_ifd[i].samples;
6226 tile_width = tiff_ifd[i].tile_width;
6227 tile_length = tiff_ifd[i].tile_length;
6228 shutter = tiff_ifd[i].shutter;
6232 if (is_raw == 1 && ties) is_raw = ties;
6233 if (!tile_width ) tile_width = INT_MAX;
6234 if (!tile_length) tile_length = INT_MAX;
6235 for (i=tiff_nifds; i--; )
6236 if (tiff_ifd[i].flip) tiff_flip = tiff_ifd[i].flip;
6237 if (raw >= 0 && !load_raw)
6238 switch (tiff_compress) {
6240 if (tiff_ifd[raw].bytes == raw_width*raw_height) {
6243 load_raw = &CLASS sony_arw2_load_raw; break;
6245 if (tiff_ifd[raw].bytes*8 != raw_width*raw_height*tiff_bps) {
6247 load_raw = &CLASS sony_arw_load_raw; break;
6253 case 32773: goto slr;
6255 if (!strncmp(make,"OLYMPUS",7) &&
6256 tiff_ifd[raw].bytes*2 == raw_width*raw_height*3)
6258 if (!strcmp(make,"SONY") && tiff_bps < 14 &&
6259 tiff_ifd[raw].bytes == raw_width*raw_height*2)
6261 if (tiff_ifd[raw].bytes*5 == raw_width*raw_height*8) {
6266 case 8: load_raw = &CLASS eight_bit_load_raw; break;
6267 case 12: if (tiff_ifd[raw].phint == 2)
6269 load_raw = &CLASS packed_load_raw; break;
6270 case 14: load_raw = &CLASS packed_load_raw;
6271 if (tiff_ifd[raw].bytes*4 == raw_width*raw_height*7) break;
6273 case 16: load_raw = &CLASS unpacked_load_raw;
6274 if (!strncmp(make,"OLYMPUS",7) &&
6275 tiff_ifd[raw].bytes*7 > raw_width*raw_height)
6276 load_raw = &CLASS olympus_load_raw;
6278 if (filters == 9 && tiff_ifd[raw].bytes*8 < raw_width*raw_height*tiff_bps)
6279 load_raw = &CLASS fuji_xtrans_load_raw;
6281 case 6: case 7: case 99:
6282 load_raw = &CLASS lossless_jpeg_load_raw; break;
6284 load_raw = &CLASS kodak_262_load_raw; break;
6286 if ((raw_width+9)/10*16*raw_height == tiff_ifd[raw].bytes) {
6287 load_raw = &CLASS packed_load_raw;
6289 } else if (raw_width*raw_height*3 == tiff_ifd[raw].bytes*2) {
6290 load_raw = &CLASS packed_load_raw;
6291 if (model[0] == 'N') load_flags = 80;
6292 } else if (raw_width*raw_height*3 == tiff_ifd[raw].bytes) {
6293 load_raw = &CLASS nikon_yuv_load_raw;
6294 gamma_curve (1/2.4, 12.92, 1, 4095);
6295 memset (cblack, 0, sizeof cblack);
6297 } else if (raw_width*raw_height*2 == tiff_ifd[raw].bytes) {
6298 load_raw = &CLASS unpacked_load_raw;
6302 load_raw = &CLASS nikon_load_raw; break;
6304 load_raw = &CLASS pentax_load_raw; break;
6306 switch (tiff_ifd[raw].phint) {
6307 case 2: load_raw = &CLASS kodak_rgb_load_raw; filters = 0; break;
6308 case 6: load_raw = &CLASS kodak_ycbcr_load_raw; filters = 0; break;
6309 case 32803: load_raw = &CLASS kodak_65000_load_raw;
6311 case 32867: case 34892: break;
6312 default: is_raw = 0;
6315 if ( (tiff_samples == 3 && tiff_ifd[raw].bytes && tiff_bps != 14 &&
6316 (tiff_compress & -16) != 32768)
6317 || (tiff_bps == 8 && strncmp(make,"Phase",5) &&
6318 !strcasestr(make,"Kodak") && !strstr(model2,"DEBUG RAW")))
6320 for (i=0; i < tiff_nifds; i++)
6321 if (i != raw && tiff_ifd[i].samples == max_samp &&
6322 tiff_ifd[i].width * tiff_ifd[i].height / (SQR(tiff_ifd[i].bps)+1) >
6323 thumb_width * thumb_height / (SQR(thumb_misc)+1)
6324 && tiff_ifd[i].comp != 34892) {
6325 thumb_width = tiff_ifd[i].width;
6326 thumb_height = tiff_ifd[i].height;
6327 thumb_offset = tiff_ifd[i].offset;
6328 thumb_length = tiff_ifd[i].bytes;
6329 thumb_misc = tiff_ifd[i].bps;
6333 thumb_misc |= tiff_ifd[thm].samples << 5;
6334 switch (tiff_ifd[thm].comp) {
6336 write_thumb = &CLASS layer_thumb;
6339 if (tiff_ifd[thm].bps <= 8)
6340 write_thumb = &CLASS ppm_thumb;
6341 else if (!strcmp(make,"Imacon"))
6342 write_thumb = &CLASS ppm16_thumb;
6344 thumb_load_raw = &CLASS kodak_thumb_load_raw;
6347 thumb_load_raw = tiff_ifd[thm].phint == 6 ?
6348 &CLASS kodak_ycbcr_load_raw : &CLASS kodak_rgb_load_raw;
6353 void CLASS parse_minolta (int base)
6355 int save, tag, len, offset, high=0, wide=0, i, c;
6358 fseek (ifp, base, SEEK_SET);
6359 if (fgetc(ifp) || fgetc(ifp)-'M' || fgetc(ifp)-'R') return;
6360 order = fgetc(ifp) * 0x101;
6361 offset = base + get4() + 8;
6362 while ((save=ftell(ifp)) < offset) {
6363 for (tag=i=0; i < 4; i++)
6364 tag = tag << 8 | fgetc(ifp);
6367 case 0x505244: /* PRD */
6368 fseek (ifp, 8, SEEK_CUR);
6372 case 0x574247: /* WBG */
6374 i = strcmp(model,"DiMAGE A200") ? 0:3;
6375 FORC4 cam_mul[c ^ (c >> 1) ^ i] = get2();
6377 case 0x545457: /* TTW */
6378 parse_tiff (ftell(ifp));
6379 data_offset = offset;
6381 fseek (ifp, save+len+8, SEEK_SET);
6389 Many cameras have a "debug mode" that writes JPEG and raw
6390 at the same time. The raw file has no header, so try to
6391 to open the matching JPEG file and read its metadata.
6393 void CLASS parse_external_jpeg()
6395 const char *file, *ext;
6396 char *jname, *jfile, *jext;
6399 ext = strrchr (ifname, '.');
6400 file = strrchr (ifname, '/');
6401 if (!file) file = strrchr (ifname, '\\');
6402 if (!file) file = ifname-1;
6404 if (!ext || strlen(ext) != 4 || ext-file != 8) return;
6405 jname = (char *) malloc (strlen(ifname) + 1);
6406 merror (jname, "parse_external_jpeg()");
6407 strcpy (jname, ifname);
6408 jfile = file - ifname + jname;
6409 jext = ext - ifname + jname;
6410 if (strcasecmp (ext, ".jpg")) {
6411 strcpy (jext, isupper(ext[1]) ? ".JPG":".jpg");
6412 if (isdigit(*file)) {
6413 memcpy (jfile, file+4, 4);
6414 memcpy (jfile+4, file, 4);
6417 while (isdigit(*--jext)) {
6424 if (strcmp (jname, ifname)) {
6425 if ((ifp = fopen (jname, "rb"))) {
6427 fprintf (stderr,_("Reading metadata from %s ...\n"), jname);
6435 fprintf (stderr,_("Failed to read metadata from %s\n"), jname);
6441 CIFF block 0x1030 contains an 8x8 white sample.
6442 Load this into white[][] for use in scale_colors().
6444 void CLASS ciff_block_1030()
6446 static const ushort key[] = { 0x410, 0x45f3 };
6447 int i, bpp, row, col, vbits=0;
6448 unsigned long bitbuf=0;
6450 if ((get2(),get4()) != 0x80008 || !get4()) return;
6452 if (bpp != 10 && bpp != 12) return;
6453 for (i=row=0; row < 8; row++)
6454 for (col=0; col < 8; col++) {
6456 bitbuf = bitbuf << 16 | (get2() ^ key[i++ & 1]);
6459 white[row][col] = bitbuf >> (vbits -= bpp) & ~(-1 << bpp);
6464 Parse a CIFF file, better known as Canon CRW format.
6466 void CLASS parse_ciff (int offset, int length, int depth)
6468 int tboff, nrecs, c, type, len, save, wbi=-1;
6469 ushort key[] = { 0x410, 0x45f3 };
6471 fseek (ifp, offset+length-4, SEEK_SET);
6472 tboff = get4() + offset;
6473 fseek (ifp, tboff, SEEK_SET);
6475 if ((nrecs | depth) > 127) return;
6479 save = ftell(ifp) + 4;
6480 fseek (ifp, offset+get4(), SEEK_SET);
6481 if ((((type >> 8) + 8) | 8) == 0x38)
6482 parse_ciff (ftell(ifp), len, depth+1); /* Parse a sub-table */
6484 fread (artist, 64, 1, ifp);
6485 if (type == 0x080a) {
6486 fread (make, 64, 1, ifp);
6487 fseek (ifp, strlen(make) - 63, SEEK_CUR);
6488 fread (model, 64, 1, ifp);
6490 if (type == 0x1810) {
6493 pixel_aspect = int_to_float(get4());
6496 if (type == 0x1835) /* Get the decoder table */
6497 tiff_compress = get4();
6498 if (type == 0x2007) {
6499 thumb_offset = ftell(ifp);
6502 if (type == 0x1818) {
6503 shutter = pow (2, -int_to_float((get4(),get4())));
6504 aperture = pow (2, int_to_float(get4())/2);
6506 if (type == 0x102a) {
6507 iso_speed = pow (2, (get4(),get2())/32.0 - 4) * 50;
6508 aperture = pow (2, (get2(),(short)get2())/64.0);
6509 shutter = pow (2,-((short)get2())/32.0);
6510 wbi = (get2(),get2());
6511 if (wbi > 17) wbi = 0;
6512 fseek (ifp, 32, SEEK_CUR);
6513 if (shutter > 1e6) shutter = get2()/10.0;
6515 if (type == 0x102c) {
6516 if (get2() > 512) { /* Pro90, G1 */
6517 fseek (ifp, 118, SEEK_CUR);
6518 FORC4 cam_mul[c ^ 2] = get2();
6519 } else { /* G2, S30, S40 */
6520 fseek (ifp, 98, SEEK_CUR);
6521 FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get2();
6524 if (type == 0x0032) {
6525 if (len == 768) { /* EOS D30 */
6526 fseek (ifp, 72, SEEK_CUR);
6527 FORC4 cam_mul[c ^ (c >> 1)] = 1024.0 / get2();
6528 if (!wbi) cam_mul[0] = -1; /* use my auto white balance */
6529 } else if (!cam_mul[0]) {
6530 if (get2() == key[0]) /* Pro1, G6, S60, S70 */
6531 c = (strstr(model,"Pro1") ?
6532 "012346000000000000":"01345:000000006008")[wbi]-'0'+ 2;
6533 else { /* G3, G5, S45, S50 */
6534 c = "023457000000006000"[wbi]-'0';
6535 key[0] = key[1] = 0;
6537 fseek (ifp, 78 + c*8, SEEK_CUR);
6538 FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get2() ^ key[c & 1];
6539 if (!wbi) cam_mul[0] = -1;
6542 if (type == 0x10a9) { /* D60, 10D, 300D, and clones */
6543 if (len > 66) wbi = "0134567028"[wbi]-'0';
6544 fseek (ifp, 2 + wbi*8, SEEK_CUR);
6545 FORC4 cam_mul[c ^ (c >> 1)] = get2();
6547 if (type == 0x1030 && (0x18040 >> wbi & 1))
6548 ciff_block_1030(); /* all that don't have 0x10a9 */
6549 if (type == 0x1031) {
6550 raw_width = (get2(),get2());
6551 raw_height = get2();
6553 if (type == 0x5029) {
6554 focal_len = len >> 16;
6555 if ((len & 0xffff) == 2) focal_len /= 32;
6557 if (type == 0x5813) flash_used = int_to_float(len);
6558 if (type == 0x5814) canon_ev = int_to_float(len);
6559 if (type == 0x5817) shot_order = len;
6560 if (type == 0x5834) unique_id = len;
6561 if (type == 0x580e) timestamp = len;
6562 if (type == 0x180e) timestamp = get4();
6564 if ((type | 0x4000) == 0x580e)
6565 timestamp = mktime (gmtime (×tamp));
6567 fseek (ifp, save, SEEK_SET);
6571 void CLASS parse_rollei()
6573 char line[128], *val;
6576 fseek (ifp, 0, SEEK_SET);
6577 memset (&t, 0, sizeof t);
6579 fgets (line, 128, ifp);
6580 if ((val = strchr(line,'=')))
6583 val = line + strlen(line);
6584 if (!strcmp(line,"DAT"))
6585 sscanf (val, "%d.%d.%d", &t.tm_mday, &t.tm_mon, &t.tm_year);
6586 if (!strcmp(line,"TIM"))
6587 sscanf (val, "%d:%d:%d", &t.tm_hour, &t.tm_min, &t.tm_sec);
6588 if (!strcmp(line,"HDR"))
6589 thumb_offset = atoi(val);
6590 if (!strcmp(line,"X "))
6591 raw_width = atoi(val);
6592 if (!strcmp(line,"Y "))
6593 raw_height = atoi(val);
6594 if (!strcmp(line,"TX "))
6595 thumb_width = atoi(val);
6596 if (!strcmp(line,"TY "))
6597 thumb_height = atoi(val);
6598 } while (strncmp(line,"EOHD",4));
6599 data_offset = thumb_offset + thumb_width * thumb_height * 2;
6603 timestamp = mktime(&t);
6604 strcpy (make, "Rollei");
6605 strcpy (model,"d530flex");
6606 write_thumb = &CLASS rollei_thumb;
6609 void CLASS parse_sinar_ia()
6615 fseek (ifp, 4, SEEK_SET);
6617 fseek (ifp, get4(), SEEK_SET);
6619 off = get4(); get4();
6620 fread (str, 8, 1, ifp);
6621 if (!strcmp(str,"META")) meta_offset = off;
6622 if (!strcmp(str,"THUMB")) thumb_offset = off;
6623 if (!strcmp(str,"RAW0")) data_offset = off;
6625 fseek (ifp, meta_offset+20, SEEK_SET);
6626 fread (make, 64, 1, ifp);
6628 if ((cp = strchr(make,' '))) {
6629 strcpy (model, cp+1);
6633 raw_height = get2();
6634 load_raw = &CLASS unpacked_load_raw;
6635 thumb_width = (get4(),get2());
6636 thumb_height = get2();
6637 write_thumb = &CLASS ppm_thumb;
6641 void CLASS parse_phase_one (int base)
6644 unsigned entries, tag, /*type,*/ len, data, save, i, c;
6645 float romm_cam[3][3];
6648 memset (&ph1, 0, sizeof ph1);
6649 fseek (ifp, base, SEEK_SET);
6650 order = get4() & 0xffff;
6651 if (get4() >> 8 != 0x526177) return; /* "Raw" */
6652 fseek (ifp, get4()+base, SEEK_SET);
6662 fseek (ifp, base+data, SEEK_SET);
6664 case 0x100: flip = "0653"[data & 3]-'0'; break;
6666 for (i=0; i < 9; i++)
6667 ((float *)romm_cam)[i] = getreal(11);
6668 romm_coeff (romm_cam);
6671 FORC3 cam_mul[c] = getreal(11);
6673 case 0x108: raw_width = data; break;
6674 case 0x109: raw_height = data; break;
6675 case 0x10a: left_margin = data; break;
6676 case 0x10b: top_margin = data; break;
6677 case 0x10c: width = data; break;
6678 case 0x10d: height = data; break;
6679 case 0x10e: ph1.format = data; break;
6680 case 0x10f: data_offset = data+base; break;
6681 case 0x110: meta_offset = data+base;
6682 meta_length = len; break;
6683 case 0x112: ph1.key_off = save - 4; break;
6684 case 0x210: ph1.tag_210 = int_to_float(data); break;
6685 case 0x21a: ph1.tag_21a = data; break;
6686 case 0x21c: strip_offset = data+base; break;
6687 case 0x21d: ph1.black = data; break;
6688 case 0x222: ph1.split_col = data; break;
6689 case 0x223: ph1.black_col = data+base; break;
6690 case 0x224: ph1.split_row = data; break;
6691 case 0x225: ph1.black_row = data+base; break;
6694 fread (model, 1, 63, ifp);
6695 if ((cp = strstr(model," camera"))) *cp = 0;
6697 fseek (ifp, save, SEEK_SET);
6699 load_raw = ph1.format < 3 ?
6700 &CLASS phase_one_load_raw : &CLASS phase_one_load_raw_c;
6702 strcpy (make, "Phase One");
6703 if (model[0]) return;
6704 switch (raw_height) {
6705 case 2060: strcpy (model,"LightPhase"); break;
6706 case 2682: strcpy (model,"H 10"); break;
6707 case 4128: strcpy (model,"H 20"); break;
6708 case 5488: strcpy (model,"H 25"); break;
6712 void CLASS parse_fuji (int offset)
6714 unsigned entries, tag, len, save, c;
6716 fseek (ifp, offset, SEEK_SET);
6718 if (entries > 255) return;
6724 raw_height = get2();
6726 } else if (tag == 0x121) {
6728 if ((width = get2()) == 4284) width += 3;
6729 } else if (tag == 0x130) {
6730 fuji_layout = fgetc(ifp) >> 7;
6731 fuji_width = !(fgetc(ifp) & 8);
6732 } else if (tag == 0x131) {
6734 FORC(36) xtrans_abs[0][35-c] = fgetc(ifp) & 3;
6735 } else if (tag == 0x2ff0) {
6736 FORC4 cam_mul[c ^ 1] = get2();
6737 } else if (tag == 0xc000 && len > 20000) {
6740 while ((tag = get4()) > raw_width);
6745 fseek (ifp, save+len, SEEK_SET);
6747 height <<= fuji_layout;
6748 width >>= fuji_layout;
6751 int CLASS parse_jpeg (int offset)
6753 int len, save, hlen, mark;
6755 fseek (ifp, offset, SEEK_SET);
6756 if (fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) return 0;
6758 while (fgetc(ifp) == 0xff && (mark = fgetc(ifp)) != 0xda) {
6762 if (mark == 0xc0 || mark == 0xc3 || mark == 0xc9) {
6764 raw_height = get2();
6769 if (get4() == 0x48454150) /* "HEAP" */
6770 parse_ciff (save+hlen, len-hlen, 0);
6771 if (parse_tiff (save+6)) apply_tiff();
6772 fseek (ifp, save+len, SEEK_SET);
6777 void CLASS parse_riff()
6779 unsigned i, size, end;
6780 char tag[4], date[64], month[64];
6781 static const char mon[12][4] =
6782 { "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" };
6786 fread (tag, 4, 1, ifp);
6788 end = ftell(ifp) + size;
6789 if (!memcmp(tag,"RIFF",4) || !memcmp(tag,"LIST",4)) {
6791 while (ftell(ifp)+7 < end && !feof(ifp))
6793 } else if (!memcmp(tag,"nctg",4)) {
6794 while (ftell(ifp)+7 < end) {
6797 if ((i+1) >> 1 == 10 && size == 20)
6799 else fseek (ifp, size, SEEK_CUR);
6801 } else if (!memcmp(tag,"IDIT",4) && size < 64) {
6802 fread (date, 64, 1, ifp);
6804 memset (&t, 0, sizeof t);
6805 if (sscanf (date, "%*s %s %d %d:%d:%d %d", month, &t.tm_mday,
6806 &t.tm_hour, &t.tm_min, &t.tm_sec, &t.tm_year) == 6) {
6807 for (i=0; i < 12 && strcasecmp(mon[i],month); i++);
6811 timestamp = mktime(&t);
6814 fseek (ifp, size, SEEK_CUR);
6817 void CLASS parse_crx (int end)
6819 unsigned i, save, size, tag, base;
6820 static int index=0, wide, high, off, len;
6823 while (ftell(ifp)+7 < end) {
6825 if ((size = get4()) < 8) break;
6826 switch (tag = get4()) {
6827 case 0x6d6f6f76: /* moov */
6828 case 0x7472616b: /* trak */
6829 case 0x6d646961: /* mdia */
6830 case 0x6d696e66: /* minf */
6831 case 0x7374626c: /* stbl */
6832 parse_crx (save+size);
6834 case 0x75756964: /* uuid */
6836 case 0xeaf42b5e: fseek (ifp, 8, SEEK_CUR);
6837 case 0x85c0b687: fseek (ifp, 12, SEEK_CUR);
6838 parse_crx (save+size);
6841 case 0x434d5431: /* CMT1 */
6842 case 0x434d5432: /* CMT2 */
6845 fseek (ifp, 6, SEEK_CUR);
6846 tag & 1 ? (void)parse_tiff_ifd (base) : parse_exif (base);
6849 case 0x746b6864: /* tkhd */
6850 fseek (ifp, 12, SEEK_CUR);
6852 fseek (ifp, 58, SEEK_CUR);
6856 case 0x7374737a: /* stsz */
6857 len = (get4(),get4());
6859 case 0x636f3634: /* co64 */
6860 fseek (ifp, 12, SEEK_CUR);
6863 case 1: /* 1 = full size, 2 = 27% size */
6865 thumb_height = high;
6873 load_raw = &CLASS canon_crx_load_raw;
6876 case 0x50525657: /* PRVW */
6877 fseek (ifp, 6, SEEK_CUR);
6879 fseek (ifp, save+size, SEEK_SET);
6883 void CLASS parse_qt (int end)
6885 unsigned save, size;
6889 while (ftell(ifp)+7 < end) {
6891 if ((size = get4()) < 8) return;
6892 fread (tag, 4, 1, ifp);
6893 if (!memcmp(tag,"moov",4) ||
6894 !memcmp(tag,"udta",4) ||
6895 !memcmp(tag,"CNTH",4))
6896 parse_qt (save+size);
6897 if (!memcmp(tag,"CNDA",4))
6898 parse_jpeg (ftell(ifp));
6899 fseek (ifp, save+size, SEEK_SET);
6903 void CLASS parse_smal (int offset, int fsize)
6907 fseek (ifp, offset+2, SEEK_SET);
6911 fseek (ifp, 5, SEEK_CUR);
6912 if (get4() != fsize) return;
6913 if (ver > 6) data_offset = get4();
6914 raw_height = height = get2();
6915 raw_width = width = get2();
6916 strcpy (make, "SMaL");
6917 sprintf (model, "v%d %dx%d", ver, width, height);
6918 if (ver == 6) load_raw = &CLASS smal_v6_load_raw;
6919 if (ver == 9) load_raw = &CLASS smal_v9_load_raw;
6922 void CLASS parse_cine()
6924 unsigned off_head, off_setup, off_image, i;
6927 fseek (ifp, 4, SEEK_SET);
6928 is_raw = get2() == 2;
6929 fseek (ifp, 14, SEEK_CUR);
6935 if ((i = get4())) timestamp = i;
6936 fseek (ifp, off_head+4, SEEK_SET);
6938 raw_height = get4();
6939 switch (get2(),get2()) {
6940 case 8: load_raw = &CLASS eight_bit_load_raw; break;
6941 case 16: load_raw = &CLASS unpacked_load_raw;
6943 fseek (ifp, off_setup+792, SEEK_SET);
6944 strcpy (make, "CINE");
6945 sprintf (model, "%d", get4());
6946 fseek (ifp, 12, SEEK_CUR);
6947 switch ((i=get4()) & 0xffffff) {
6948 case 3: filters = 0x94949494; break;
6949 case 4: filters = 0x49494949; break;
6950 default: is_raw = 0;
6952 fseek (ifp, 72, SEEK_CUR);
6953 switch ((get4()+3600) % 360) {
6954 case 270: flip = 4; break;
6955 case 180: flip = 1; break;
6956 case 90: flip = 7; break;
6959 cam_mul[0] = getreal(11);
6960 cam_mul[2] = getreal(11);
6961 maximum = ~(-1 << get4());
6962 fseek (ifp, 668, SEEK_CUR);
6963 shutter = get4()/1000000000.0;
6964 fseek (ifp, off_image, SEEK_SET);
6965 if (shot_select < is_raw)
6966 fseek (ifp, shot_select*8, SEEK_CUR);
6967 data_offset = (INT64) get4() + 8;
6968 data_offset += (INT64) get4() << 32;
6971 void CLASS parse_redcine()
6973 unsigned i, len, rdvo;
6977 fseek (ifp, 52, SEEK_SET);
6980 fseek (ifp, 0, SEEK_END);
6981 fseek (ifp, -(i = ftello(ifp) & 511), SEEK_CUR);
6982 if (get4() != i || get4() != 0x52454f42) {
6983 fprintf (stderr,_("%s: Tail is missing, parsing from head...\n"), ifname);
6984 fseek (ifp, 0, SEEK_SET);
6985 while ((len = get4()) != EOF) {
6986 if (get4() == 0x52454456)
6987 if (is_raw++ == shot_select)
6988 data_offset = ftello(ifp) - 8;
6989 fseek (ifp, len-8, SEEK_CUR);
6993 fseek (ifp, 12, SEEK_CUR);
6995 fseeko (ifp, rdvo+8 + shot_select*4, SEEK_SET);
6996 data_offset = get4();
7000 char * CLASS foveon_gets (int offset, char *str, int len)
7003 fseek (ifp, offset, SEEK_SET);
7004 for (i=0; i < len-1; i++)
7005 if ((str[i] = get2()) == 0) break;
7010 void CLASS parse_foveon()
7012 int entries, img=0, off, len, tag, save, i, wide, high, pent, poff[256][2];
7013 char name[64], value[64];
7015 order = 0x4949; /* Little-endian */
7016 fseek (ifp, 36, SEEK_SET);
7018 fseek (ifp, -4, SEEK_END);
7019 fseek (ifp, get4(), SEEK_SET);
7020 if (get4() != 0x64434553) return; /* SECd */
7021 entries = (get4(),get4());
7027 fseek (ifp, off, SEEK_SET);
7028 if (get4() != (0x20434553 | (tag << 24))) return;
7030 case 0x47414d49: /* IMAG */
7031 case 0x32414d49: /* IMA2 */
7032 fseek (ifp, 8, SEEK_CUR);
7036 if (wide > raw_width && high > raw_height) {
7038 case 5: load_flags = 1;
7039 case 6: load_raw = &CLASS foveon_sd_load_raw; break;
7040 case 30: load_raw = &CLASS foveon_dp_load_raw; break;
7041 default: load_raw = 0;
7045 data_offset = off+28;
7048 fseek (ifp, off+28, SEEK_SET);
7049 if (fgetc(ifp) == 0xff && fgetc(ifp) == 0xd8
7050 && thumb_length < len-28) {
7051 thumb_offset = off+28;
7052 thumb_length = len-28;
7053 write_thumb = &CLASS jpeg_thumb;
7055 if (++img == 2 && !thumb_length) {
7056 thumb_offset = off+24;
7058 thumb_height = high;
7059 write_thumb = &CLASS foveon_thumb;
7062 case 0x464d4143: /* CAMF */
7063 meta_offset = off+8;
7064 meta_length = len-28;
7066 case 0x504f5250: /* PROP */
7067 pent = (get4(),get4());
7068 fseek (ifp, 12, SEEK_CUR);
7070 if ((unsigned) pent > 256) pent=256;
7071 for (i=0; i < pent*2; i++)
7072 ((int *)poff)[i] = off + get4()*2;
7073 for (i=0; i < pent; i++) {
7074 foveon_gets (poff[i][0], name, 64);
7075 foveon_gets (poff[i][1], value, 64);
7076 if (!strcmp (name, "ISO"))
7077 iso_speed = atoi(value);
7078 if (!strcmp (name, "CAMMANUF"))
7079 strcpy (make, value);
7080 if (!strcmp (name, "CAMMODEL"))
7081 strcpy (model, value);
7082 if (!strcmp (name, "WB_DESC"))
7083 strcpy (model2, value);
7084 if (!strcmp (name, "TIME"))
7085 timestamp = atoi(value);
7086 if (!strcmp (name, "EXPTIME"))
7087 shutter = atoi(value) / 1000000.0;
7088 if (!strcmp (name, "APERTURE"))
7089 aperture = atof(value);
7090 if (!strcmp (name, "FLENGTH"))
7091 focal_len = atof(value);
7094 timestamp = mktime (gmtime (×tamp));
7097 fseek (ifp, save, SEEK_SET);
7102 All matrices are from Adobe DNG Converter unless otherwise noted.
7104 void CLASS adobe_coeff (const char *make, const char *model)
7106 static const struct {
7108 short black, maximum, trans[12];
7110 { "AgfaPhoto DC-833m", 0, 0, /* DJC */
7111 { 11438,-3762,-1115,-2409,9914,2497,-1227,2295,5300 } },
7112 { "Apple QuickTake", 0, 0, /* DJC */
7113 { 21392,-5653,-3353,2406,8010,-415,7166,1427,2078 } },
7114 { "Canon EOS D2000", 0, 0,
7115 { 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } },
7116 { "Canon EOS D6000", 0, 0,
7117 { 20482,-7172,-3125,-1033,10410,-285,2542,226,3136 } },
7118 { "Canon EOS D30", 0, 0,
7119 { 9805,-2689,-1312,-5803,13064,3068,-2438,3075,8775 } },
7120 { "Canon EOS D60", 0, 0xfa0,
7121 { 6188,-1341,-890,-7168,14489,2937,-2640,3228,8483 } },
7122 { "Canon EOS 5DS", 0, 0x3c96,
7123 { 6250,-711,-808,-5153,12794,2636,-1249,2198,5610 } },
7124 { "Canon EOS 5D Mark IV", 0, 0,
7125 { 6446,-366,-864,-4436,12204,2513,-952,2496,6348 } },
7126 { "Canon EOS 5D Mark III", 0, 0x3c80,
7127 { 6722,-635,-963,-4287,12460,2028,-908,2162,5668 } },
7128 { "Canon EOS 5D Mark II", 0, 0x3cf0,
7129 { 4716,603,-830,-7798,15474,2480,-1496,1937,6651 } },
7130 { "Canon EOS 5D", 0, 0xe6c,
7131 { 6347,-479,-972,-8297,15954,2480,-1968,2131,7649 } },
7132 { "Canon EOS 6D Mark II", 0, 0,
7133 { 6875,-970,-932,-4691,12459,2501,-874,1953,5809 } },
7134 { "Canon EOS 6D", 0, 0x3c82,
7135 { 7034,-804,-1014,-4420,12564,2058,-851,1994,5758 } },
7136 { "Canon EOS 7D Mark II", 0, 0x3510,
7137 { 7268,-1082,-969,-4186,11839,2663,-825,2029,5839 } },
7138 { "Canon EOS 7D", 0, 0x3510,
7139 { 6844,-996,-856,-3876,11761,2396,-593,1772,6198 } },
7140 { "Canon EOS 10D", 0, 0xfa0,
7141 { 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } },
7142 { "Canon EOS 20Da", 0, 0,
7143 { 14155,-5065,-1382,-6550,14633,2039,-1623,1824,6561 } },
7144 { "Canon EOS 20D", 0, 0xfff,
7145 { 6599,-537,-891,-8071,15783,2424,-1983,2234,7462 } },
7146 { "Canon EOS 30D", 0, 0,
7147 { 6257,-303,-1000,-7880,15621,2396,-1714,1904,7046 } },
7148 { "Canon EOS 40D", 0, 0x3f60,
7149 { 6071,-747,-856,-7653,15365,2441,-2025,2553,7315 } },
7150 { "Canon EOS 50D", 0, 0x3d93,
7151 { 4920,616,-593,-6493,13964,2784,-1774,3178,7005 } },
7152 { "Canon EOS 60D", 0, 0x2ff7,
7153 { 6719,-994,-925,-4408,12426,2211,-887,2129,6051 } },
7154 { "Canon EOS 70D", 0, 0x3bc7,
7155 { 7034,-804,-1014,-4420,12564,2058,-851,1994,5758 } },
7156 { "Canon EOS 77D", 0, 0,
7157 { 7377,-742,-998,-4235,11981,2549,-673,1918,5538 } },
7158 { "Canon EOS 80D", 0, 0,
7159 { 7457,-671,-937,-4849,12495,2643,-1213,2354,5492 } },
7160 { "Canon EOS 100D", 0, 0x350f,
7161 { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } },
7162 { "Canon EOS 200D", 0, 0,
7163 { 7377,-742,-998,-4235,11981,2549,-673,1918,5538 } },
7164 { "Canon EOS 300D", 0, 0xfa0,
7165 { 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } },
7166 { "Canon EOS 350D", 0, 0xfff,
7167 { 6018,-617,-965,-8645,15881,2975,-1530,1719,7642 } },
7168 { "Canon EOS 400D", 0, 0xe8e,
7169 { 7054,-1501,-990,-8156,15544,2812,-1278,1414,7796 } },
7170 { "Canon EOS 450D", 0, 0x390d,
7171 { 5784,-262,-821,-7539,15064,2672,-1982,2681,7427 } },
7172 { "Canon EOS 500D", 0, 0x3479,
7173 { 4763,712,-646,-6821,14399,2640,-1921,3276,6561 } },
7174 { "Canon EOS 550D", 0, 0x3dd7,
7175 { 6941,-1164,-857,-3825,11597,2534,-416,1540,6039 } },
7176 { "Canon EOS 600D", 0, 0x3510,
7177 { 6461,-907,-882,-4300,12184,2378,-819,1944,5931 } },
7178 { "Canon EOS 650D", 0, 0x354d,
7179 { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } },
7180 { "Canon EOS 700D", 0, 0x3c00,
7181 { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } },
7182 { "Canon EOS 750D", 0, 0x368e,
7183 { 6362,-823,-847,-4426,12109,2616,-743,1857,5635 } },
7184 { "Canon EOS 760D", 0, 0x350f,
7185 { 6362,-823,-847,-4426,12109,2616,-743,1857,5635 } },
7186 { "Canon EOS 800D", 0, 0,
7187 { 6970,-512,-968,-4425,12161,2553,-739,1982,5601 } },
7188 { "Canon EOS 1000D", 0, 0xe43,
7189 { 6771,-1139,-977,-7818,15123,2928,-1244,1437,7533 } },
7190 { "Canon EOS 1100D", 0, 0x3510,
7191 { 6444,-904,-893,-4563,12308,2535,-903,2016,6728 } },
7192 { "Canon EOS 1200D", 0, 0x37c2,
7193 { 6461,-907,-882,-4300,12184,2378,-819,1944,5931 } },
7194 { "Canon EOS 1300D", 0, 0x3510,
7195 { 6939,-1016,-866,-4428,12473,2177,-1175,2178,6162 } },
7196 { "Canon EOS 1500D", 0, 0,
7197 { 8532,-701,-1167,-4095,11879,2508,-797,2424,7010 } },
7198 { "Canon EOS 3000D", 0, 0,
7199 { 6939,-1016,-866,-4428,12473,2177,-1175,2178,6162 } },
7200 { "Canon EOS M6", 0, 0,
7201 { 8532,-701,-1167,-4095,11879,2508,-797,2424,7010 } },
7202 { "Canon EOS M5", 0, 0, /* also M50 */
7203 { 8532,-701,-1167,-4095,11879,2508,-797,2424,7010 } },
7204 { "Canon EOS M3", 0, 0,
7205 { 6362,-823,-847,-4426,12109,2616,-743,1857,5635 } },
7206 { "Canon EOS M100", 0, 0,
7207 { 8532,-701,-1167,-4095,11879,2508,-797,2424,7010 } },
7208 { "Canon EOS M10", 0, 0,
7209 { 6400,-480,-888,-5294,13416,2047,-1296,2203,6137 } },
7210 { "Canon EOS M", 0, 0,
7211 { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } },
7212 { "Canon EOS-1Ds Mark III", 0, 0x3bb0,
7213 { 5859,-211,-930,-8255,16017,2353,-1732,1887,7448 } },
7214 { "Canon EOS-1Ds Mark II", 0, 0xe80,
7215 { 6517,-602,-867,-8180,15926,2378,-1618,1771,7633 } },
7216 { "Canon EOS-1D Mark IV", 0, 0x3bb0,
7217 { 6014,-220,-795,-4109,12014,2361,-561,1824,5787 } },
7218 { "Canon EOS-1D Mark III", 0, 0x3bb0,
7219 { 6291,-540,-976,-8350,16145,2311,-1714,1858,7326 } },
7220 { "Canon EOS-1D Mark II N", 0, 0xe80,
7221 { 6240,-466,-822,-8180,15825,2500,-1801,1938,8042 } },
7222 { "Canon EOS-1D Mark II", 0, 0xe80,
7223 { 6264,-582,-724,-8312,15948,2504,-1744,1919,8664 } },
7224 { "Canon EOS-1DS", 0, 0xe20,
7225 { 4374,3631,-1743,-7520,15212,2472,-2892,3632,8161 } },
7226 { "Canon EOS-1D C", 0, 0x3c4e,
7227 { 6847,-614,-1014,-4669,12737,2139,-1197,2488,6846 } },
7228 { "Canon EOS-1D X Mark II", 0, 0,
7229 { 7596,-978,-967,-4808,12571,2503,-1398,2567,5752 } },
7230 { "Canon EOS-1D X", 0, 0x3c4e,
7231 { 6847,-614,-1014,-4669,12737,2139,-1197,2488,6846 } },
7232 { "Canon EOS-1D", 0, 0xe20,
7233 { 6806,-179,-1020,-8097,16415,1687,-3267,4236,7690 } },
7234 { "Canon EOS C500", 853, 0, /* DJC */
7235 { 17851,-10604,922,-7425,16662,763,-3660,3636,22278 } },
7236 { "Canon PowerShot A530", 0, 0,
7237 { 0 } }, /* don't want the A5 matrix */
7238 { "Canon PowerShot A50", 0, 0,
7239 { -5300,9846,1776,3436,684,3939,-5540,9879,6200,-1404,11175,217 } },
7240 { "Canon PowerShot A5", 0, 0,
7241 { -4801,9475,1952,2926,1611,4094,-5259,10164,5947,-1554,10883,547 } },
7242 { "Canon PowerShot G10", 0, 0,
7243 { 11093,-3906,-1028,-5047,12492,2879,-1003,1750,5561 } },
7244 { "Canon PowerShot G11", 0, 0,
7245 { 12177,-4817,-1069,-1612,9864,2049,-98,850,4471 } },
7246 { "Canon PowerShot G12", 0, 0,
7247 { 13244,-5501,-1248,-1508,9858,1935,-270,1083,4366 } },
7248 { "Canon PowerShot G15", 0, 0,
7249 { 7474,-2301,-567,-4056,11456,2975,-222,716,4181 } },
7250 { "Canon PowerShot G16", 0, 0,
7251 { 8020,-2687,-682,-3704,11879,2052,-965,1921,5556 } },
7252 { "Canon PowerShot G1 X Mark III", 0, 0,
7253 { 8532,-701,-1167,-4095,11879,2508,-797,2424,7010 } },
7254 { "Canon PowerShot G1 X", 0, 0,
7255 { 7378,-1255,-1043,-4088,12251,2048,-876,1946,5805 } },
7256 { "Canon PowerShot G1", 0, 0,
7257 { -4778,9467,2172,4743,-1141,4344,-5146,9908,6077,-1566,11051,557 } },
7258 { "Canon PowerShot G2", 0, 0,
7259 { 9087,-2693,-1049,-6715,14382,2537,-2291,2819,7790 } },
7260 { "Canon PowerShot G3 X", 0, 0,
7261 { 9701,-3857,-921,-3149,11537,1817,-786,1817,5147 } },
7262 { "Canon PowerShot G3", 0, 0,
7263 { 9212,-2781,-1073,-6573,14189,2605,-2300,2844,7664 } },
7264 { "Canon PowerShot G5 X", 0, 0,
7265 { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } },
7266 { "Canon PowerShot G5", 0, 0,
7267 { 9757,-2872,-933,-5972,13861,2301,-1622,2328,7212 } },
7268 { "Canon PowerShot G6", 0, 0,
7269 { 9877,-3775,-871,-7613,14807,3072,-1448,1305,7485 } },
7270 { "Canon PowerShot G7 X", 0, 0,
7271 { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } },
7272 { "Canon PowerShot G9 X Mark II", 0, 0,
7273 { 10056,-4131,-944,-2576,11143,1625,-238,1294,5179 } },
7274 { "Canon PowerShot G9 X", 0, 0,
7275 { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } },
7276 { "Canon PowerShot G9", 0, 0,
7277 { 7368,-2141,-598,-5621,13254,2625,-1418,1696,5743 } },
7278 { "Canon PowerShot Pro1", 0, 0,
7279 { 10062,-3522,-999,-7643,15117,2730,-765,817,7323 } },
7280 { "Canon PowerShot Pro70", 34, 0,
7281 { -4155,9818,1529,3939,-25,4522,-5521,9870,6610,-2238,10873,1342 } },
7282 { "Canon PowerShot Pro90", 0, 0,
7283 { -4963,9896,2235,4642,-987,4294,-5162,10011,5859,-1770,11230,577 } },
7284 { "Canon PowerShot S30", 0, 0,
7285 { 10566,-3652,-1129,-6552,14662,2006,-2197,2581,7670 } },
7286 { "Canon PowerShot S40", 0, 0,
7287 { 8510,-2487,-940,-6869,14231,2900,-2318,2829,9013 } },
7288 { "Canon PowerShot S45", 0, 0,
7289 { 8163,-2333,-955,-6682,14174,2751,-2077,2597,8041 } },
7290 { "Canon PowerShot S50", 0, 0,
7291 { 8882,-2571,-863,-6348,14234,2288,-1516,2172,6569 } },
7292 { "Canon PowerShot S60", 0, 0,
7293 { 8795,-2482,-797,-7804,15403,2573,-1422,1996,7082 } },
7294 { "Canon PowerShot S70", 0, 0,
7295 { 9976,-3810,-832,-7115,14463,2906,-901,989,7889 } },
7296 { "Canon PowerShot S90", 0, 0,
7297 { 12374,-5016,-1049,-1677,9902,2078,-83,852,4683 } },
7298 { "Canon PowerShot S95", 0, 0,
7299 { 13440,-5896,-1279,-1236,9598,1931,-180,1001,4651 } },
7300 { "Canon PowerShot S100", 0, 0,
7301 { 7968,-2565,-636,-2873,10697,2513,180,667,4211 } },
7302 { "Canon PowerShot S110", 0, 0,
7303 { 8039,-2643,-654,-3783,11230,2930,-206,690,4194 } },
7304 { "Canon PowerShot S120", 0, 0,
7305 { 6961,-1685,-695,-4625,12945,1836,-1114,2152,5518 } },
7306 { "Canon PowerShot SX1 IS", 0, 0,
7307 { 6578,-259,-502,-5974,13030,3309,-308,1058,4970 } },
7308 { "Canon PowerShot SX50 HS", 0, 0,
7309 { 12432,-4753,-1247,-2110,10691,1629,-412,1623,4926 } },
7310 { "Canon PowerShot SX60 HS", 0, 0,
7311 { 13161,-5451,-1344,-1989,10654,1531,-47,1271,4955 } },
7312 { "Canon PowerShot A3300", 0, 0, /* DJC */
7313 { 10826,-3654,-1023,-3215,11310,1906,0,999,4960 } },
7314 { "Canon PowerShot A470", 0, 0, /* DJC */
7315 { 12513,-4407,-1242,-2680,10276,2405,-878,2215,4734 } },
7316 { "Canon PowerShot A610", 0, 0, /* DJC */
7317 { 15591,-6402,-1592,-5365,13198,2168,-1300,1824,5075 } },
7318 { "Canon PowerShot A620", 0, 0, /* DJC */
7319 { 15265,-6193,-1558,-4125,12116,2010,-888,1639,5220 } },
7320 { "Canon PowerShot A630", 0, 0, /* DJC */
7321 { 14201,-5308,-1757,-6087,14472,1617,-2191,3105,5348 } },
7322 { "Canon PowerShot A640", 0, 0, /* DJC */
7323 { 13124,-5329,-1390,-3602,11658,1944,-1612,2863,4885 } },
7324 { "Canon PowerShot A650", 0, 0, /* DJC */
7325 { 9427,-3036,-959,-2581,10671,1911,-1039,1982,4430 } },
7326 { "Canon PowerShot A720", 0, 0, /* DJC */
7327 { 14573,-5482,-1546,-1266,9799,1468,-1040,1912,3810 } },
7328 { "Canon PowerShot S3 IS", 0, 0, /* DJC */
7329 { 14062,-5199,-1446,-4712,12470,2243,-1286,2028,4836 } },
7330 { "Canon PowerShot SX110 IS", 0, 0, /* DJC */
7331 { 14134,-5576,-1527,-1991,10719,1273,-1158,1929,3581 } },
7332 { "Canon PowerShot SX220", 0, 0, /* DJC */
7333 { 13898,-5076,-1447,-1405,10109,1297,-244,1860,3687 } },
7334 { "Canon IXUS 160", 0, 0, /* DJC */
7335 { 11657,-3781,-1136,-3544,11262,2283,-160,1219,4700 } },
7336 { "Casio EX-S20", 0, 0, /* DJC */
7337 { 11634,-3924,-1128,-4968,12954,2015,-1588,2648,7206 } },
7338 { "Casio EX-Z750", 0, 0, /* DJC */
7339 { 10819,-3873,-1099,-4903,13730,1175,-1755,3751,4632 } },
7340 { "Casio EX-Z10", 128, 0xfff, /* DJC */
7341 { 9790,-3338,-603,-2321,10222,2099,-344,1273,4799 } },
7343 { 3390,480,-500,-800,3610,340,-550,2336,1192 } },
7345 { 3390,480,-500,-800,3610,340,-550,2336,1192 } },
7347 { 20183,-4295,-423,-3940,15330,3985,-280,4870,9800 } },
7348 { "Contax N Digital", 0, 0xf1e,
7349 { 7777,1285,-1053,-9280,16543,2916,-3677,5679,7060 } },
7351 { 6596,-2079,-562,-4782,13016,1933,-970,1581,5181 } },
7352 { "Epson R-D1", 0, 0,
7353 { 6827,-1878,-732,-8429,16012,2564,-704,592,7145 } },
7354 { "Fujifilm E550", 0, 0,
7355 { 11044,-3888,-1120,-7248,15168,2208,-1531,2277,8069 } },
7356 { "Fujifilm E900", 0, 0,
7357 { 9183,-2526,-1078,-7461,15071,2574,-2022,2440,8639 } },
7358 { "Fujifilm F5", 0, 0,
7359 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
7360 { "Fujifilm F6", 0, 0,
7361 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
7362 { "Fujifilm F77", 0, 0xfe9,
7363 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
7364 { "Fujifilm F7", 0, 0,
7365 { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } },
7366 { "Fujifilm F8", 0, 0,
7367 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
7368 { "Fujifilm GFX 50S", 0, 0,
7369 { 11756,-4754,-874,-3056,11045,2305,-381,1457,6006 } },
7370 { "Fujifilm S100FS", 514, 0,
7371 { 11521,-4355,-1065,-6524,13767,3058,-1466,1984,6045 } },
7372 { "Fujifilm S1", 0, 0,
7373 { 12297,-4882,-1202,-2106,10691,1623,-88,1312,4790 } },
7374 { "Fujifilm S20Pro", 0, 0,
7375 { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } },
7376 { "Fujifilm S20", 512, 0x3fff,
7377 { 11401,-4498,-1312,-5088,12751,2613,-838,1568,5941 } },
7378 { "Fujifilm S2Pro", 128, 0xf15,
7379 { 12492,-4690,-1402,-7033,15423,1647,-1507,2111,7697 } },
7380 { "Fujifilm S3Pro", 0, 0x3dff,
7381 { 11807,-4612,-1294,-8927,16968,1988,-2120,2741,8006 } },
7382 { "Fujifilm S5Pro", 0, 0,
7383 { 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } },
7384 { "Fujifilm S5000", 0, 0,
7385 { 8754,-2732,-1019,-7204,15069,2276,-1702,2334,6982 } },
7386 { "Fujifilm S5100", 0, 0,
7387 { 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } },
7388 { "Fujifilm S5500", 0, 0,
7389 { 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } },
7390 { "Fujifilm S5200", 0, 0,
7391 { 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } },
7392 { "Fujifilm S5600", 0, 0,
7393 { 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } },
7394 { "Fujifilm S6", 0, 0,
7395 { 12628,-4887,-1401,-6861,14996,1962,-2198,2782,7091 } },
7396 { "Fujifilm S7000", 0, 0,
7397 { 10190,-3506,-1312,-7153,15051,2238,-2003,2399,7505 } },
7398 { "Fujifilm S9000", 0, 0,
7399 { 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 } },
7400 { "Fujifilm S9500", 0, 0,
7401 { 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 } },
7402 { "Fujifilm S9100", 0, 0,
7403 { 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 } },
7404 { "Fujifilm S9600", 0, 0,
7405 { 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 } },
7406 { "Fujifilm SL1000", 0, 0,
7407 { 11705,-4262,-1107,-2282,10791,1709,-555,1713,4945 } },
7408 { "Fujifilm IS-1", 0, 0,
7409 { 21461,-10807,-1441,-2332,10599,1999,289,875,7703 } },
7410 { "Fujifilm IS Pro", 0, 0,
7411 { 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } },
7412 { "Fujifilm HS10 HS11", 0, 0xf68,
7413 { 12440,-3954,-1183,-1123,9674,1708,-83,1614,4086 } },
7414 { "Fujifilm HS2", 0, 0xfef,
7415 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
7416 { "Fujifilm HS3", 0, 0,
7417 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
7418 { "Fujifilm HS50EXR", 0, 0,
7419 { 12085,-4727,-953,-3257,11489,2002,-511,2046,4592 } },
7420 { "Fujifilm F900EXR", 0, 0,
7421 { 12085,-4727,-953,-3257,11489,2002,-511,2046,4592 } },
7422 { "Fujifilm X100F", 0, 0,
7423 { 11434,-4948,-1210,-3746,12042,1903,-666,1479,5235 } },
7424 { "Fujifilm X100S", 0, 0,
7425 { 10592,-4262,-1008,-3514,11355,2465,-870,2025,6386 } },
7426 { "Fujifilm X100T", 0, 0,
7427 { 10592,-4262,-1008,-3514,11355,2465,-870,2025,6386 } },
7428 { "Fujifilm X100", 0, 0,
7429 { 12161,-4457,-1069,-5034,12874,2400,-795,1724,6904 } },
7430 { "Fujifilm X10", 0, 0,
7431 { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } },
7432 { "Fujifilm X20", 0, 0,
7433 { 11768,-4971,-1133,-4904,12927,2183,-480,1723,4605 } },
7434 { "Fujifilm X30", 0, 0,
7435 { 12328,-5256,-1144,-4469,12927,1675,-87,1291,4351 } },
7436 { "Fujifilm X70", 0, 0,
7437 { 10450,-4329,-878,-3217,11105,2421,-752,1758,6519 } },
7438 { "Fujifilm X-Pro1", 0, 0,
7439 { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } },
7440 { "Fujifilm X-Pro2", 0, 0,
7441 { 11434,-4948,-1210,-3746,12042,1903,-666,1479,5235 } },
7442 { "Fujifilm X-A10", 0, 0,
7443 { 11540,-4999,-991,-2949,10963,2278,-382,1049,5605 } },
7444 { "Fujifilm X-A20", 0, 0,
7445 { 11540,-4999,-991,-2949,10963,2278,-382,1049,5605 } },
7446 { "Fujifilm X-A1", 0, 0,
7447 { 11086,-4555,-839,-3512,11310,2517,-815,1341,5940 } },
7448 { "Fujifilm X-A2", 0, 0,
7449 { 10763,-4560,-917,-3346,11311,2322,-475,1135,5843 } },
7450 { "Fujifilm X-A3", 0, 0,
7451 { 12407,-5222,-1086,-2971,11116,2120,-294,1029,5284 } },
7452 { "Fujifilm X-A5", 0, 0,
7453 { 11673,-4760,-1041,-3988,12058,2166,-771,1417,5569 } },
7454 { "Fujifilm X-E1", 0, 0,
7455 { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } },
7456 { "Fujifilm X-E2S", 0, 0,
7457 { 11562,-5118,-961,-3022,11007,2311,-525,1569,6097 } },
7458 { "Fujifilm X-E2", 0, 0,
7459 { 8458,-2451,-855,-4597,12447,2407,-1475,2482,6526 } },
7460 { "Fujifilm X-E3", 0, 0,
7461 { 11434,-4948,-1210,-3746,12042,1903,-666,1479,5235 } },
7462 { "Fujifilm X-H1", 0, 0,
7463 { 11434,-4948,-1210,-3746,12042,1903,-666,1479,5235 } },
7464 { "Fujifilm X-M1", 0, 0,
7465 { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } },
7466 { "Fujifilm X-S1", 0, 0,
7467 { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } },
7468 { "Fujifilm X-T1", 0, 0, /* also X-T10 */
7469 { 8458,-2451,-855,-4597,12447,2407,-1475,2482,6526 } },
7470 { "Fujifilm X-T2", 0, 0, /* also X-T20 */
7471 { 11434,-4948,-1210,-3746,12042,1903,-666,1479,5235 } },
7472 { "Fujifilm XF1", 0, 0,
7473 { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } },
7474 { "Fujifilm XQ", 0, 0, /* XQ1 and XQ2 */
7475 { 9252,-2704,-1064,-5893,14265,1717,-1101,2341,4349 } },
7476 { "GoPro HERO5 Black", 0, 0,
7477 { 10344,-4210,-620,-2315,10625,1948,93,1058,5541 } },
7478 { "Imacon Ixpress", 0, 0, /* DJC */
7479 { 7025,-1415,-704,-5188,13765,1424,-1248,2742,6038 } },
7480 { "Kodak NC2000", 0, 0,
7481 { 13891,-6055,-803,-465,9919,642,2121,82,1291 } },
7482 { "Kodak DCS315C", 8, 0,
7483 { 17523,-4827,-2510,756,8546,-137,6113,1649,2250 } },
7484 { "Kodak DCS330C", 8, 0,
7485 { 20620,-7572,-2801,-103,10073,-396,3551,-233,2220 } },
7486 { "Kodak DCS420", 0, 0,
7487 { 10868,-1852,-644,-1537,11083,484,2343,628,2216 } },
7488 { "Kodak DCS460", 0, 0,
7489 { 10592,-2206,-967,-1944,11685,230,2206,670,1273 } },
7490 { "Kodak EOSDCS1", 0, 0,
7491 { 10592,-2206,-967,-1944,11685,230,2206,670,1273 } },
7492 { "Kodak EOSDCS3B", 0, 0,
7493 { 9898,-2700,-940,-2478,12219,206,1985,634,1031 } },
7494 { "Kodak DCS520C", 178, 0,
7495 { 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } },
7496 { "Kodak DCS560C", 177, 0,
7497 { 20482,-7172,-3125,-1033,10410,-285,2542,226,3136 } },
7498 { "Kodak DCS620C", 177, 0,
7499 { 23617,-10175,-3149,-2054,11749,-272,2586,-489,3453 } },
7500 { "Kodak DCS620X", 176, 0,
7501 { 13095,-6231,154,12221,-21,-2137,895,4602,2258 } },
7502 { "Kodak DCS660C", 173, 0,
7503 { 18244,-6351,-2739,-791,11193,-521,3711,-129,2802 } },
7504 { "Kodak DCS720X", 0, 0,
7505 { 11775,-5884,950,9556,1846,-1286,-1019,6221,2728 } },
7506 { "Kodak DCS760C", 0, 0,
7507 { 16623,-6309,-1411,-4344,13923,323,2285,274,2926 } },
7508 { "Kodak DCS Pro SLR", 0, 0,
7509 { 5494,2393,-232,-6427,13850,2846,-1876,3997,5445 } },
7510 { "Kodak DCS Pro 14nx", 0, 0,
7511 { 5494,2393,-232,-6427,13850,2846,-1876,3997,5445 } },
7512 { "Kodak DCS Pro 14", 0, 0,
7513 { 7791,3128,-776,-8588,16458,2039,-2455,4006,6198 } },
7514 { "Kodak ProBack645", 0, 0,
7515 { 16414,-6060,-1470,-3555,13037,473,2545,122,4948 } },
7516 { "Kodak ProBack", 0, 0,
7517 { 21179,-8316,-2918,-915,11019,-165,3477,-180,4210 } },
7518 { "Kodak P712", 0, 0,
7519 { 9658,-3314,-823,-5163,12695,2768,-1342,1843,6044 } },
7520 { "Kodak P850", 0, 0xf7c,
7521 { 10511,-3836,-1102,-6946,14587,2558,-1481,1792,6246 } },
7522 { "Kodak P880", 0, 0xfff,
7523 { 12805,-4662,-1376,-7480,15267,2360,-1626,2194,7904 } },
7524 { "Kodak EasyShare Z980", 0, 0,
7525 { 11313,-3559,-1101,-3893,11891,2257,-1214,2398,4908 } },
7526 { "Kodak EasyShare Z981", 0, 0,
7527 { 12729,-4717,-1188,-1367,9187,2582,274,860,4411 } },
7528 { "Kodak EasyShare Z990", 0, 0xfed,
7529 { 11749,-4048,-1309,-1867,10572,1489,-138,1449,4522 } },
7530 { "Kodak EASYSHARE Z1015", 0, 0xef1,
7531 { 11265,-4286,-992,-4694,12343,2647,-1090,1523,5447 } },
7532 { "Leaf CMost", 0, 0,
7533 { 3952,2189,449,-6701,14585,2275,-4536,7349,6536 } },
7534 { "Leaf Valeo 6", 0, 0,
7535 { 3952,2189,449,-6701,14585,2275,-4536,7349,6536 } },
7536 { "Leaf Aptus 54S", 0, 0,
7537 { 8236,1746,-1314,-8251,15953,2428,-3673,5786,5771 } },
7538 { "Leaf Aptus 65", 0, 0,
7539 { 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 } },
7540 { "Leaf Aptus 75", 0, 0,
7541 { 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 } },
7543 { 8236,1746,-1314,-8251,15953,2428,-3673,5786,5771 } },
7544 { "Mamiya ZD", 0, 0,
7545 { 7645,2579,-1363,-8689,16717,2015,-3712,5941,5961 } },
7546 { "Micron 2010", 110, 0, /* DJC */
7547 { 16695,-3761,-2151,155,9682,163,3433,951,4904 } },
7548 { "Minolta DiMAGE 5", 0, 0xf7d,
7549 { 8983,-2942,-963,-6556,14476,2237,-2426,2887,8014 } },
7550 { "Minolta DiMAGE 7Hi", 0, 0xf7d,
7551 { 11368,-3894,-1242,-6521,14358,2339,-2475,3056,7285 } },
7552 { "Minolta DiMAGE 7", 0, 0xf7d,
7553 { 9144,-2777,-998,-6676,14556,2281,-2470,3019,7744 } },
7554 { "Minolta DiMAGE A1", 0, 0xf8b,
7555 { 9274,-2547,-1167,-8220,16323,1943,-2273,2720,8340 } },
7556 { "Minolta DiMAGE A200", 0, 0,
7557 { 8560,-2487,-986,-8112,15535,2771,-1209,1324,7743 } },
7558 { "Minolta DiMAGE A2", 0, 0xf8f,
7559 { 9097,-2726,-1053,-8073,15506,2762,-966,981,7763 } },
7560 { "Minolta DiMAGE Z2", 0, 0, /* DJC */
7561 { 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 } },
7562 { "Minolta DYNAX 5", 0, 0xffb,
7563 { 10284,-3283,-1086,-7957,15762,2316,-829,882,6644 } },
7564 { "Minolta DYNAX 7", 0, 0xffb,
7565 { 10239,-3104,-1099,-8037,15727,2451,-927,925,6871 } },
7566 { "Motorola PIXL", 0, 0, /* DJC */
7567 { 8898,-989,-1033,-3292,11619,1674,-661,3178,5216 } },
7568 { "Nikon D100", 0, 0,
7569 { 5902,-933,-782,-8983,16719,2354,-1402,1455,6464 } },
7570 { "Nikon D1H", 0, 0,
7571 { 7577,-2166,-926,-7454,15592,1934,-2377,2808,8606 } },
7572 { "Nikon D1X", 0, 0,
7573 { 7702,-2245,-975,-9114,17242,1875,-2679,3055,8521 } },
7574 { "Nikon D1", 0, 0, /* multiplied by 2.218750, 1.0, 1.148438 */
7575 { 16772,-4726,-2141,-7611,15713,1972,-2846,3494,9521 } },
7576 { "Nikon D200", 0, 0xfbc,
7577 { 8367,-2248,-763,-8758,16447,2422,-1527,1550,8053 } },
7578 { "Nikon D2H", 0, 0,
7579 { 5710,-901,-615,-8594,16617,2024,-2975,4120,6830 } },
7580 { "Nikon D2X", 0, 0,
7581 { 10231,-2769,-1255,-8301,15900,2552,-797,680,7148 } },
7582 { "Nikon D3000", 0, 0,
7583 { 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } },
7584 { "Nikon D3100", 0, 0,
7585 { 7911,-2167,-813,-5327,13150,2408,-1288,2483,7968 } },
7586 { "Nikon D3200", 0, 0xfb9,
7587 { 7013,-1408,-635,-5268,12902,2640,-1470,2801,7379 } },
7588 { "Nikon D3300", 0, 0,
7589 { 6988,-1384,-714,-5631,13410,2447,-1485,2204,7318 } },
7590 { "Nikon D3400", 0, 0,
7591 { 6988,-1384,-714,-5631,13410,2447,-1485,2204,7318 } },
7592 { "Nikon D300", 0, 0,
7593 { 9030,-1992,-715,-8465,16302,2255,-2689,3217,8069 } },
7594 { "Nikon D3X", 0, 0,
7595 { 7171,-1986,-648,-8085,15555,2718,-2170,2512,7457 } },
7596 { "Nikon D3S", 0, 0,
7597 { 8828,-2406,-694,-4874,12603,2541,-660,1509,7587 } },
7599 { 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } },
7600 { "Nikon D40X", 0, 0,
7601 { 8819,-2543,-911,-9025,16928,2151,-1329,1213,8449 } },
7602 { "Nikon D40", 0, 0,
7603 { 6992,-1668,-806,-8138,15748,2543,-874,850,7897 } },
7604 { "Nikon D4S", 0, 0,
7605 { 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } },
7607 { 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } },
7609 { 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } },
7610 { "Nikon D5000", 0, 0xf00,
7611 { 7309,-1403,-519,-8474,16008,2622,-2433,2826,8064 } },
7612 { "Nikon D5100", 0, 0x3de6,
7613 { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } },
7614 { "Nikon D5200", 0, 0,
7615 { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } },
7616 { "Nikon D5300", 0, 0,
7617 { 6988,-1384,-714,-5631,13410,2447,-1485,2204,7318 } },
7618 { "Nikon D5500", 0, 0,
7619 { 8821,-2938,-785,-4178,12142,2287,-824,1651,6860 } },
7620 { "Nikon D5600", 0, 0,
7621 { 8821,-2938,-785,-4178,12142,2287,-824,1651,6860 } },
7622 { "Nikon D500", 0, 0,
7623 { 8813,-3210,-1036,-4703,12868,2021,-1054,1940,6129 } },
7624 { "Nikon D50", 0, 0,
7625 { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } },
7627 { 9200,-3522,-992,-5755,13803,2117,-753,1486,6338 } },
7628 { "Nikon D600", 0, 0x3e07,
7629 { 8178,-2245,-609,-4857,12394,2776,-1207,2086,7298 } },
7630 { "Nikon D610", 0, 0,
7631 { 8178,-2245,-609,-4857,12394,2776,-1207,2086,7298 } },
7632 { "Nikon D60", 0, 0,
7633 { 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } },
7634 { "Nikon D7000", 0, 0,
7635 { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } },
7636 { "Nikon D7100", 0, 0,
7637 { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } },
7638 { "Nikon D7200", 0, 0,
7639 { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } },
7640 { "Nikon D7500", 0, 0,
7641 { 8813,-3210,-1036,-4703,12868,2021,-1054,1940,6129 } },
7642 { "Nikon D750", 0, 0,
7643 { 9020,-2890,-715,-4535,12436,2348,-934,1919,7086 } },
7644 { "Nikon D700", 0, 0,
7645 { 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } },
7646 { "Nikon D70", 0, 0,
7647 { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } },
7648 { "Nikon D850", 0, 0,
7649 { 10405,-3755,-1270,-5461,13787,1793,-1040,2015,6785 } },
7650 { "Nikon D810", 0, 0,
7651 { 9369,-3195,-791,-4488,12430,2301,-893,1796,6872 } },
7652 { "Nikon D800", 0, 0,
7653 { 7866,-2108,-555,-4869,12483,2681,-1176,2069,7501 } },
7654 { "Nikon D80", 0, 0,
7655 { 8629,-2410,-883,-9055,16940,2171,-1490,1363,8520 } },
7656 { "Nikon D90", 0, 0xf00,
7657 { 7309,-1403,-519,-8474,16008,2622,-2434,2826,8064 } },
7658 { "Nikon E700", 0, 0x3dd, /* DJC */
7659 { -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } },
7660 { "Nikon E800", 0, 0x3dd, /* DJC */
7661 { -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } },
7662 { "Nikon E950", 0, 0x3dd, /* DJC */
7663 { -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } },
7664 { "Nikon E995", 0, 0, /* copied from E5000 */
7665 { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
7666 { "Nikon E2100", 0, 0, /* copied from Z2, new white balance */
7667 { 13142,-4152,-1596,-4655,12374,2282,-1769,2696,6711} },
7668 { "Nikon E2500", 0, 0,
7669 { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
7670 { "Nikon E3200", 0, 0, /* DJC */
7671 { 9846,-2085,-1019,-3278,11109,2170,-774,2134,5745 } },
7672 { "Nikon E4300", 0, 0, /* copied from Minolta DiMAGE Z2 */
7673 { 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 } },
7674 { "Nikon E4500", 0, 0,
7675 { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
7676 { "Nikon E5000", 0, 0,
7677 { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
7678 { "Nikon E5400", 0, 0,
7679 { 9349,-2987,-1001,-7919,15766,2266,-2098,2680,6839 } },
7680 { "Nikon E5700", 0, 0,
7681 { -5368,11478,2368,5537,-113,3148,-4969,10021,5782,778,9028,211 } },
7682 { "Nikon E8400", 0, 0,
7683 { 7842,-2320,-992,-8154,15718,2599,-1098,1342,7560 } },
7684 { "Nikon E8700", 0, 0,
7685 { 8489,-2583,-1036,-8051,15583,2643,-1307,1407,7354 } },
7686 { "Nikon E8800", 0, 0,
7687 { 7971,-2314,-913,-8451,15762,2894,-1442,1520,7610 } },
7688 { "Nikon COOLPIX A", 0, 0,
7689 { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } },
7690 { "Nikon COOLPIX B700", 200, 0,
7691 { 14387,-6014,-1299,-1357,9975,1616,467,1047,4744 } },
7692 { "Nikon COOLPIX P330", 200, 0,
7693 { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } },
7694 { "Nikon COOLPIX P340", 200, 0,
7695 { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } },
7696 { "Nikon COOLPIX P6000", 0, 0,
7697 { 9698,-3367,-914,-4706,12584,2368,-837,968,5801 } },
7698 { "Nikon COOLPIX P7000", 0, 0,
7699 { 11432,-3679,-1111,-3169,11239,2202,-791,1380,4455 } },
7700 { "Nikon COOLPIX P7100", 0, 0,
7701 { 11053,-4269,-1024,-1976,10182,2088,-526,1263,4469 } },
7702 { "Nikon COOLPIX P7700", 200, 0,
7703 { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } },
7704 { "Nikon COOLPIX P7800", 200, 0,
7705 { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } },
7706 { "Nikon 1 V3", 0, 0,
7707 { 5958,-1559,-571,-4021,11453,2939,-634,1548,5087 } },
7708 { "Nikon 1 J4", 0, 0,
7709 { 5958,-1559,-571,-4021,11453,2939,-634,1548,5087 } },
7710 { "Nikon 1 J5", 0, 0,
7711 { 7520,-2518,-645,-3844,12102,1945,-913,2249,6835 } },
7712 { "Nikon 1 S2", 200, 0,
7713 { 6612,-1342,-618,-3338,11055,2623,-174,1792,5075 } },
7714 { "Nikon 1 V2", 0, 0,
7715 { 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } },
7716 { "Nikon 1 J3", 0, 0,
7717 { 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } },
7718 { "Nikon 1 AW1", 0, 0,
7719 { 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } },
7720 { "Nikon 1 ", 0, 0, /* J1, J2, S1, V1 */
7721 { 8994,-2667,-865,-4594,12324,2552,-699,1786,6260 } },
7722 { "Olympus AIR A01", 0, 0,
7723 { 8992,-3093,-639,-2563,10721,2122,-437,1270,5473 } },
7724 { "Olympus C5050", 0, 0,
7725 { 10508,-3124,-1273,-6079,14294,1901,-1653,2306,6237 } },
7726 { "Olympus C5060", 0, 0,
7727 { 10445,-3362,-1307,-7662,15690,2058,-1135,1176,7602 } },
7728 { "Olympus C7070", 0, 0,
7729 { 10252,-3531,-1095,-7114,14850,2436,-1451,1723,6365 } },
7730 { "Olympus C70", 0, 0,
7731 { 10793,-3791,-1146,-7498,15177,2488,-1390,1577,7321 } },
7732 { "Olympus C80", 0, 0,
7733 { 8606,-2509,-1014,-8238,15714,2703,-942,979,7760 } },
7734 { "Olympus E-10", 0, 0xffc,
7735 { 12745,-4500,-1416,-6062,14542,1580,-1934,2256,6603 } },
7736 { "Olympus E-1", 0, 0,
7737 { 11846,-4767,-945,-7027,15878,1089,-2699,4122,8311 } },
7738 { "Olympus E-20", 0, 0xffc,
7739 { 13173,-4732,-1499,-5807,14036,1895,-2045,2452,7142 } },
7740 { "Olympus E-300", 0, 0,
7741 { 7828,-1761,-348,-5788,14071,1830,-2853,4518,6557 } },
7742 { "Olympus E-330", 0, 0,
7743 { 8961,-2473,-1084,-7979,15990,2067,-2319,3035,8249 } },
7744 { "Olympus E-30", 0, 0xfbc,
7745 { 8144,-1861,-1111,-7763,15894,1929,-1865,2542,7607 } },
7746 { "Olympus E-3", 0, 0xf99,
7747 { 9487,-2875,-1115,-7533,15606,2010,-1618,2100,7389 } },
7748 { "Olympus E-400", 0, 0,
7749 { 6169,-1483,-21,-7107,14761,2536,-2904,3580,8568 } },
7750 { "Olympus E-410", 0, 0xf6a,
7751 { 8856,-2582,-1026,-7761,15766,2082,-2009,2575,7469 } },
7752 { "Olympus E-420", 0, 0xfd7,
7753 { 8746,-2425,-1095,-7594,15612,2073,-1780,2309,7416 } },
7754 { "Olympus E-450", 0, 0xfd2,
7755 { 8745,-2425,-1095,-7594,15613,2073,-1780,2309,7416 } },
7756 { "Olympus E-500", 0, 0,
7757 { 8136,-1968,-299,-5481,13742,1871,-2556,4205,6630 } },
7758 { "Olympus E-510", 0, 0xf6a,
7759 { 8785,-2529,-1033,-7639,15624,2112,-1783,2300,7817 } },
7760 { "Olympus E-520", 0, 0xfd2,
7761 { 8344,-2322,-1020,-7596,15635,2048,-1748,2269,7287 } },
7762 { "Olympus E-5", 0, 0xeec,
7763 { 11200,-3783,-1325,-4576,12593,2206,-695,1742,7504 } },
7764 { "Olympus E-600", 0, 0xfaf,
7765 { 8453,-2198,-1092,-7609,15681,2008,-1725,2337,7824 } },
7766 { "Olympus E-620", 0, 0xfaf,
7767 { 8453,-2198,-1092,-7609,15681,2008,-1725,2337,7824 } },
7768 { "Olympus E-P1", 0, 0xffd,
7769 { 8343,-2050,-1021,-7715,15705,2103,-1831,2380,8235 } },
7770 { "Olympus E-P2", 0, 0xffd,
7771 { 8343,-2050,-1021,-7715,15705,2103,-1831,2380,8235 } },
7772 { "Olympus E-P3", 0, 0,
7773 { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } },
7774 { "Olympus E-P5", 0, 0,
7775 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
7776 { "Olympus E-PL1s", 0, 0,
7777 { 11409,-3872,-1393,-4572,12757,2003,-709,1810,7415 } },
7778 { "Olympus E-PL1", 0, 0,
7779 { 11408,-4289,-1215,-4286,12385,2118,-387,1467,7787 } },
7780 { "Olympus E-PL2", 0, 0xcf3,
7781 { 15030,-5552,-1806,-3987,12387,1767,-592,1670,7023 } },
7782 { "Olympus E-PL3", 0, 0,
7783 { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } },
7784 { "Olympus E-PL5", 0, 0xfcb,
7785 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
7786 { "Olympus E-PL6", 0, 0,
7787 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
7788 { "Olympus E-PL7", 0, 0,
7789 { 9197,-3190,-659,-2606,10830,2039,-458,1250,5458 } },
7790 { "Olympus E-PL8", 0, 0,
7791 { 9197,-3190,-659,-2606,10830,2039,-458,1250,5458 } },
7792 { "Olympus E-PL9", 0, 0,
7793 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
7794 { "Olympus E-PM1", 0, 0,
7795 { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } },
7796 { "Olympus E-PM2", 0, 0,
7797 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
7798 { "Olympus E-M10", 0, 0, /* also E-M10 Mark II & III */
7799 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
7800 { "Olympus E-M1Mark II", 0, 0,
7801 { 9383,-3170,-763,-2457,10702,2020,-384,1236,5552 } },
7802 { "Olympus E-M1", 0, 0,
7803 { 7687,-1984,-606,-4327,11928,2721,-1381,2339,6452 } },
7804 { "Olympus E-M5MarkII", 0, 0,
7805 { 9422,-3258,-711,-2655,10898,2015,-512,1354,5512 } },
7806 { "Olympus E-M5", 0, 0xfe1,
7807 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
7808 { "Olympus PEN-F", 0, 0,
7809 { 9476,-3182,-765,-2613,10958,1893,-449,1315,5268 } },
7810 { "Olympus SH-2", 0, 0,
7811 { 10156,-3425,-1077,-2611,11177,1624,-385,1592,5080 } },
7812 { "Olympus SP350", 0, 0,
7813 { 12078,-4836,-1069,-6671,14306,2578,-786,939,7418 } },
7814 { "Olympus SP3", 0, 0,
7815 { 11766,-4445,-1067,-6901,14421,2707,-1029,1217,7572 } },
7816 { "Olympus SP500UZ", 0, 0xfff,
7817 { 9493,-3415,-666,-5211,12334,3260,-1548,2262,6482 } },
7818 { "Olympus SP510UZ", 0, 0xffe,
7819 { 10593,-3607,-1010,-5881,13127,3084,-1200,1805,6721 } },
7820 { "Olympus SP550UZ", 0, 0xffe,
7821 { 11597,-4006,-1049,-5432,12799,2957,-1029,1750,6516 } },
7822 { "Olympus SP560UZ", 0, 0xff9,
7823 { 10915,-3677,-982,-5587,12986,2911,-1168,1968,6223 } },
7824 { "Olympus SP570UZ", 0, 0,
7825 { 11522,-4044,-1146,-4736,12172,2904,-988,1829,6039 } },
7826 { "Olympus STYLUS1", 0, 0,
7827 { 8360,-2420,-880,-3928,12353,1739,-1381,2416,5173 } },
7828 { "Olympus TG-4", 0, 0,
7829 { 11426,-4159,-1126,-2066,10678,1593,-120,1327,4998 } },
7830 { "Olympus TG-5", 0, 0,
7831 { 10899,-3833,-1082,-2112,10736,1575,-267,1452,5269 } },
7832 { "Olympus XZ-10", 0, 0,
7833 { 9777,-3483,-925,-2886,11297,1800,-602,1663,5134 } },
7834 { "Olympus XZ-1", 0, 0,
7835 { 10901,-4095,-1074,-1141,9208,2293,-62,1417,5158 } },
7836 { "Olympus XZ-2", 0, 0,
7837 { 9777,-3483,-925,-2886,11297,1800,-602,1663,5134 } },
7838 { "OmniVision", 0, 0, /* DJC */
7839 { 12782,-4059,-379,-478,9066,1413,1340,1513,5176 } },
7840 { "Pentax *ist DL2", 0, 0,
7841 { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
7842 { "Pentax *ist DL", 0, 0,
7843 { 10829,-2838,-1115,-8339,15817,2696,-837,680,11939 } },
7844 { "Pentax *ist DS2", 0, 0,
7845 { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
7846 { "Pentax *ist DS", 0, 0,
7847 { 10371,-2333,-1206,-8688,16231,2602,-1230,1116,11282 } },
7848 { "Pentax *ist D", 0, 0,
7849 { 9651,-2059,-1189,-8881,16512,2487,-1460,1345,10687 } },
7850 { "Pentax K10D", 0, 0,
7851 { 9566,-2863,-803,-7170,15172,2112,-818,803,9705 } },
7852 { "Pentax K1", 0, 0,
7853 { 11095,-3157,-1324,-8377,15834,2720,-1108,947,11688 } },
7854 { "Pentax K20D", 0, 0,
7855 { 9427,-2714,-868,-7493,16092,1373,-2199,3264,7180 } },
7856 { "Pentax K200D", 0, 0,
7857 { 9186,-2678,-907,-8693,16517,2260,-1129,1094,8524 } },
7858 { "Pentax K2000", 0, 0,
7859 { 11057,-3604,-1155,-5152,13046,2329,-282,375,8104 } },
7860 { "Pentax K-m", 0, 0,
7861 { 11057,-3604,-1155,-5152,13046,2329,-282,375,8104 } },
7862 { "Pentax K-x", 0, 0,
7863 { 8843,-2837,-625,-5025,12644,2668,-411,1234,7410 } },
7864 { "Pentax K-r", 0, 0,
7865 { 9895,-3077,-850,-5304,13035,2521,-883,1768,6936 } },
7866 { "Pentax K-1", 0, 0,
7867 { 8596,-2981,-639,-4202,12046,2431,-685,1424,6122 } },
7868 { "Pentax K-30", 0, 0,
7869 { 8710,-2632,-1167,-3995,12301,1881,-981,1719,6535 } },
7870 { "Pentax K-3 II", 0, 0,
7871 { 8626,-2607,-1155,-3995,12301,1881,-1039,1822,6925 } },
7872 { "Pentax K-3", 0, 0,
7873 { 7415,-2052,-721,-5186,12788,2682,-1446,2157,6773 } },
7874 { "Pentax K-5 II", 0, 0,
7875 { 8170,-2725,-639,-4440,12017,2744,-771,1465,6599 } },
7876 { "Pentax K-5", 0, 0,
7877 { 8713,-2833,-743,-4342,11900,2772,-722,1543,6247 } },
7878 { "Pentax K-70", 0, 0,
7879 { 8270,-2117,-1299,-4359,12953,1515,-1078,1933,5975 } },
7880 { "Pentax K-7", 0, 0,
7881 { 9142,-2947,-678,-8648,16967,1663,-2224,2898,8615 } },
7882 { "Pentax K-S1", 0, 0,
7883 { 8512,-3211,-787,-4167,11966,2487,-638,1288,6054 } },
7884 { "Pentax K-S2", 0, 0,
7885 { 8662,-3280,-798,-3928,11771,2444,-586,1232,6054 } },
7886 { "Pentax KP", 0, 0,
7887 { 8617,-3228,-1034,-4674,12821,2044,-803,1577,5728 } },
7888 { "Pentax Q-S1", 0, 0,
7889 { 12995,-5593,-1107,-1879,10139,2027,-64,1233,4919 } },
7890 { "Pentax 645D", 0, 0x3e00,
7891 { 10646,-3593,-1158,-3329,11699,1831,-667,2874,6287 } },
7892 { "Panasonic DMC-CM1", 15, 0,
7893 { 8770,-3194,-820,-2871,11281,1803,-513,1552,4434 } },
7894 { "Panasonic DC-FZ80", 0, 0,
7895 { 8550,-2908,-842,-3195,11529,1881,-338,1603,4631 } },
7896 { "Panasonic DMC-FZ8", 0, 0xf7f,
7897 { 8986,-2755,-802,-6341,13575,3077,-1476,2144,6379 } },
7898 { "Panasonic DMC-FZ18", 0, 0,
7899 { 9932,-3060,-935,-5809,13331,2753,-1267,2155,5575 } },
7900 { "Panasonic DMC-FZ28", 15, 0xf96,
7901 { 10109,-3488,-993,-5412,12812,2916,-1305,2140,5543 } },
7902 { "Panasonic DMC-FZ2500", 15, 0,
7903 { 7386,-2443,-743,-3437,11864,1757,-608,1660,4766 } },
7904 { "Panasonic DMC-FZ330", 15, 0,
7905 { 8378,-2798,-769,-3068,11410,1877,-538,1792,4623 } },
7906 { "Panasonic DMC-FZ300", 15, 0,
7907 { 8378,-2798,-769,-3068,11410,1877,-538,1792,4623 } },
7908 { "Panasonic DMC-FZ30", 0, 0xf94,
7909 { 10976,-4029,-1141,-7918,15491,2600,-1670,2071,8246 } },
7910 { "Panasonic DMC-FZ3", 15, 0, /* FZ35, FZ38 */
7911 { 9938,-2780,-890,-4604,12393,2480,-1117,2304,4620 } },
7912 { "Panasonic DMC-FZ4", 15, 0, /* FZ40, FZ45 */
7913 { 13639,-5535,-1371,-1698,9633,2430,316,1152,4108 } },
7914 { "Panasonic DMC-FZ50", 0, 0,
7915 { 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } },
7916 { "Panasonic DMC-FZ7", 15, 0, /* FZ70, FZ72 */
7917 { 11532,-4324,-1066,-2375,10847,1749,-564,1699,4351 } },
7918 { "Leica V-LUX1", 0, 0,
7919 { 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } },
7920 { "Panasonic DMC-L10", 15, 0xf96,
7921 { 8025,-1942,-1050,-7920,15904,2100,-2456,3005,7039 } },
7922 { "Panasonic DMC-L1", 0, 0xf7f,
7923 { 8054,-1885,-1025,-8349,16367,2040,-2805,3542,7629 } },
7924 { "Leica DIGILUX 3", 0, 0xf7f,
7925 { 8054,-1885,-1025,-8349,16367,2040,-2805,3542,7629 } },
7926 { "Panasonic DMC-LC1", 0, 0,
7927 { 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } },
7928 { "Leica DIGILUX 2", 0, 0,
7929 { 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } },
7930 { "Panasonic DMC-LX100", 15, 0,
7931 { 8844,-3538,-768,-3709,11762,2200,-698,1792,5220 } },
7932 { "Leica D-LUX (Typ 109)", 15, 0,
7933 { 8844,-3538,-768,-3709,11762,2200,-698,1792,5220 } },
7934 { "Panasonic DMC-LF1", 15, 0,
7935 { 9379,-3267,-816,-3227,11560,1881,-926,1928,5340 } },
7936 { "Leica C (Typ 112)", 15, 0,
7937 { 9379,-3267,-816,-3227,11560,1881,-926,1928,5340 } },
7938 { "Panasonic DMC-LX1", 0, 0xf7f,
7939 { 10704,-4187,-1230,-8314,15952,2501,-920,945,8927 } },
7940 { "Leica D-LUX2", 0, 0xf7f,
7941 { 10704,-4187,-1230,-8314,15952,2501,-920,945,8927 } },
7942 { "Panasonic DMC-LX2", 0, 0,
7943 { 8048,-2810,-623,-6450,13519,3272,-1700,2146,7049 } },
7944 { "Leica D-LUX3", 0, 0,
7945 { 8048,-2810,-623,-6450,13519,3272,-1700,2146,7049 } },
7946 { "Panasonic DMC-LX3", 15, 0,
7947 { 8128,-2668,-655,-6134,13307,3161,-1782,2568,6083 } },
7948 { "Leica D-LUX 4", 15, 0,
7949 { 8128,-2668,-655,-6134,13307,3161,-1782,2568,6083 } },
7950 { "Panasonic DMC-LX5", 15, 0,
7951 { 10909,-4295,-948,-1333,9306,2399,22,1738,4582 } },
7952 { "Leica D-LUX 5", 15, 0,
7953 { 10909,-4295,-948,-1333,9306,2399,22,1738,4582 } },
7954 { "Panasonic DMC-LX7", 15, 0,
7955 { 10148,-3743,-991,-2837,11366,1659,-701,1893,4899 } },
7956 { "Leica D-LUX 6", 15, 0,
7957 { 10148,-3743,-991,-2837,11366,1659,-701,1893,4899 } },
7958 { "Panasonic DMC-LX9", 15, 0,
7959 { 7790,-2736,-755,-3452,11870,1769,-628,1647,4898 } },
7960 { "Panasonic DMC-FZ1000", 15, 0,
7961 { 7830,-2696,-763,-3325,11667,1866,-641,1712,4824 } },
7962 { "Leica V-LUX (Typ 114)", 15, 0,
7963 { 7830,-2696,-763,-3325,11667,1866,-641,1712,4824 } },
7964 { "Panasonic DMC-FZ100", 15, 0xfff,
7965 { 16197,-6146,-1761,-2393,10765,1869,366,2238,5248 } },
7966 { "Leica V-LUX 2", 15, 0xfff,
7967 { 16197,-6146,-1761,-2393,10765,1869,366,2238,5248 } },
7968 { "Panasonic DMC-FZ150", 15, 0xfff,
7969 { 11904,-4541,-1189,-2355,10899,1662,-296,1586,4289 } },
7970 { "Leica V-LUX 3", 15, 0xfff,
7971 { 11904,-4541,-1189,-2355,10899,1662,-296,1586,4289 } },
7972 { "Panasonic DMC-FZ200", 15, 0xfff,
7973 { 8112,-2563,-740,-3730,11784,2197,-941,2075,4933 } },
7974 { "Leica V-LUX 4", 15, 0xfff,
7975 { 8112,-2563,-740,-3730,11784,2197,-941,2075,4933 } },
7976 { "Panasonic DMC-FX150", 15, 0xfff,
7977 { 9082,-2907,-925,-6119,13377,3058,-1797,2641,5609 } },
7978 { "Panasonic DMC-G10", 0, 0,
7979 { 10113,-3400,-1114,-4765,12683,2317,-377,1437,6710 } },
7980 { "Panasonic DMC-G1", 15, 0xf94,
7981 { 8199,-2065,-1056,-8124,16156,2033,-2458,3022,7220 } },
7982 { "Panasonic DMC-G2", 15, 0xf3c,
7983 { 10113,-3400,-1114,-4765,12683,2317,-377,1437,6710 } },
7984 { "Panasonic DMC-G3", 15, 0xfff,
7985 { 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } },
7986 { "Panasonic DMC-G5", 15, 0xfff,
7987 { 7798,-2562,-740,-3879,11584,2613,-1055,2248,5434 } },
7988 { "Panasonic DMC-G6", 15, 0xfff,
7989 { 8294,-2891,-651,-3869,11590,2595,-1183,2267,5352 } },
7990 { "Panasonic DMC-G7", 15, 0xfff,
7991 { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } },
7992 { "Panasonic DMC-G8", 15, 0xfff, /* G8, G80, G81, G85 */
7993 { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } },
7994 { "Panasonic DC-G9", 15, 0xfff,
7995 { 7685,-2375,-634,-3687,11700,2249,-748,1546,5111 } },
7996 { "Panasonic DMC-GF1", 15, 0xf92,
7997 { 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } },
7998 { "Panasonic DMC-GF2", 15, 0xfff,
7999 { 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } },
8000 { "Panasonic DMC-GF3", 15, 0xfff,
8001 { 9051,-2468,-1204,-5212,13276,2121,-1197,2510,6890 } },
8002 { "Panasonic DMC-GF5", 15, 0xfff,
8003 { 8228,-2945,-660,-3938,11792,2430,-1094,2278,5793 } },
8004 { "Panasonic DMC-GF6", 15, 0,
8005 { 8130,-2801,-946,-3520,11289,2552,-1314,2511,5791 } },
8006 { "Panasonic DMC-GF7", 15, 0,
8007 { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } },
8008 { "Panasonic DMC-GF8", 15, 0,
8009 { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } },
8010 { "Panasonic DC-GF9", 15, 0,
8011 { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } },
8012 { "Panasonic DMC-GH1", 15, 0xf92,
8013 { 6299,-1466,-532,-6535,13852,2969,-2331,3112,5984 } },
8014 { "Panasonic DMC-GH2", 15, 0xf95,
8015 { 7780,-2410,-806,-3913,11724,2484,-1018,2390,5298 } },
8016 { "Panasonic DMC-GH3", 15, 0,
8017 { 6559,-1752,-491,-3672,11407,2586,-962,1875,5130 } },
8018 { "Panasonic DMC-GH4", 15, 0,
8019 { 7122,-2108,-512,-3155,11201,2231,-541,1423,5045 } },
8020 { "Panasonic DC-GH5S", 15, 0,
8021 { 6929,-2355,-708,-4192,12534,1828,-1097,1989,5195 } },
8022 { "Panasonic DC-GH5", 15, 0,
8023 { 7641,-2336,-605,-3218,11299,2187,-485,1338,5121 } },
8024 { "Panasonic DMC-GM1", 15, 0,
8025 { 6770,-1895,-744,-5232,13145,2303,-1664,2691,5703 } },
8026 { "Panasonic DMC-GM5", 15, 0,
8027 { 8238,-3244,-679,-3921,11814,2384,-836,2022,5852 } },
8028 { "Panasonic DMC-GX1", 15, 0,
8029 { 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } },
8030 { "Panasonic DMC-GX7", 15, 0,
8031 { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } },
8032 { "Panasonic DMC-GX85", 15, 0,
8033 { 7771,-3020,-629,-4029,11950,2345,-821,1977,6119 } },
8034 { "Panasonic DMC-GX8", 15, 0,
8035 { 7564,-2263,-606,-3148,11239,2177,-540,1435,4853 } },
8036 { "Panasonic DC-GX9", 15, 0,
8037 { 7564,-2263,-606,-3148,11239,2177,-540,1435,4853 } },
8038 { "Panasonic DMC-ZS100", 15, 0,
8039 { 7790,-2736,-755,-3452,11870,1769,-628,1647,4898 } },
8040 { "Panasonic DC-ZS200", 15, 0,
8041 { 7790,-2736,-755,-3452,11870,1769,-628,1647,4898 } },
8042 { "Panasonic DMC-ZS40", 15, 0,
8043 { 8607,-2822,-808,-3755,11930,2049,-820,2060,5224 } },
8044 { "Panasonic DMC-ZS50", 15, 0,
8045 { 8802,-3135,-789,-3151,11468,1904,-550,1745,4810 } },
8046 { "Panasonic DMC-TZ82", 15, 0,
8047 { 8550,-2908,-842,-3195,11529,1881,-338,1603,4631 } },
8048 { "Panasonic DMC-ZS6", 15, 0,
8049 { 8550,-2908,-842,-3195,11529,1881,-338,1603,4631 } },
8050 { "Panasonic DMC-ZS70", 15, 0,
8051 { 9052,-3117,-883,-3045,11346,1927,-205,1520,4730 } },
8052 { "Leica S (Typ 007)", 0, 0,
8053 { 6063,-2234,-231,-5210,13787,1500,-1043,2866,6997 } },
8054 { "Leica X", 0, 0, /* X and X-U, both (Typ 113) */
8055 { 7712,-2059,-653,-3882,11494,2726,-710,1332,5958 } },
8056 { "Leica Q (Typ 116)", 0, 0,
8057 { 11865,-4523,-1441,-5423,14458,935,-1587,2687,4830 } },
8058 { "Leica M (Typ 262)", 0, 0,
8059 { 6653,-1486,-611,-4221,13303,929,-881,2416,7226 } },
8060 { "Leica SL (Typ 601)", 0, 0,
8061 { 11865,-4523,-1441,-5423,14458,935,-1587,2687,4830 } },
8062 { "Leica TL2", 0, 0,
8063 { 5836,-1626,-647,-5384,13326,2261,-1207,2129,5861 } },
8065 { 5463,-988,-364,-4634,12036,2946,-766,1389,6522 } },
8067 { 7414,-2393,-840,-5127,13180,2138,-1585,2468,5064 } },
8068 { "Leica M10", 0, 0,
8069 { 8249,-2849,-620,-5415,14756,565,-957,3074,6517 } },
8070 { "Phase One H 20", 0, 0, /* DJC */
8071 { 1313,1855,-109,-6715,15908,808,-327,1840,6020 } },
8072 { "Phase One H 25", 0, 0,
8073 { 2905,732,-237,-8134,16626,1476,-3038,4253,7517 } },
8074 { "Phase One P 2", 0, 0,
8075 { 2905,732,-237,-8134,16626,1476,-3038,4253,7517 } },
8076 { "Phase One P 30", 0, 0,
8077 { 4516,-245,-37,-7020,14976,2173,-3206,4671,7087 } },
8078 { "Phase One P 45", 0, 0,
8079 { 5053,-24,-117,-5684,14076,1702,-2619,4492,5849 } },
8080 { "Phase One P40", 0, 0,
8081 { 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } },
8082 { "Phase One P65", 0, 0,
8083 { 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } },
8084 { "Photron BC2-HD", 0, 0, /* DJC */
8085 { 14603,-4122,-528,-1810,9794,2017,-297,2763,5936 } },
8086 { "Red One", 704, 0xffff, /* DJC */
8087 { 21014,-7891,-2613,-3056,12201,856,-2203,5125,8042 } },
8088 { "Ricoh GR II", 0, 0,
8089 { 4630,-834,-423,-4977,12805,2417,-638,1467,6115 } },
8091 { 3708,-543,-160,-5381,12254,3556,-1471,1929,8234 } },
8092 { "Samsung EX1", 0, 0x3e00,
8093 { 8898,-2498,-994,-3144,11328,2066,-760,1381,4576 } },
8094 { "Samsung EX2F", 0, 0x7ff,
8095 { 10648,-3897,-1055,-2022,10573,1668,-492,1611,4742 } },
8096 { "Samsung EK-GN120", 0, 0,
8097 { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } },
8098 { "Samsung NX mini", 0, 0,
8099 { 5222,-1196,-550,-6540,14649,2009,-1666,2819,5657 } },
8100 { "Samsung NX3300", 0, 0,
8101 { 8060,-2933,-761,-4504,12890,1762,-630,1489,5227 } },
8102 { "Samsung NX3000", 0, 0,
8103 { 8060,-2933,-761,-4504,12890,1762,-630,1489,5227 } },
8104 { "Samsung NX30", 0, 0, /* NX30, NX300, NX300M */
8105 { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } },
8106 { "Samsung NX2000", 0, 0,
8107 { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } },
8108 { "Samsung NX2", 0, 0xfff, /* NX20, NX200, NX210 */
8109 { 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } },
8110 { "Samsung NX1000", 0, 0,
8111 { 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } },
8112 { "Samsung NX1100", 0, 0,
8113 { 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } },
8114 { "Samsung NX11", 0, 0,
8115 { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } },
8116 { "Samsung NX10", 0, 0, /* also NX100 */
8117 { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } },
8118 { "Samsung NX500", 0, 0,
8119 { 10686,-4042,-1052,-3595,13238,276,-464,1259,5931 } },
8120 { "Samsung NX5", 0, 0,
8121 { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } },
8122 { "Samsung NX1", 0, 0,
8123 { 10686,-4042,-1052,-3595,13238,276,-464,1259,5931 } },
8124 { "Samsung WB2000", 0, 0xfff,
8125 { 12093,-3557,-1155,-1000,9534,1733,-22,1787,4576 } },
8126 { "Samsung GX-1", 0, 0,
8127 { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
8128 { "Samsung GX20", 0, 0, /* copied from Pentax K20D */
8129 { 9427,-2714,-868,-7493,16092,1373,-2199,3264,7180 } },
8130 { "Samsung S85", 0, 0, /* DJC */
8131 { 11885,-3968,-1473,-4214,12299,1916,-835,1655,5549 } },
8132 { "Sinar", 0, 0, /* DJC */
8133 { 16442,-2956,-2422,-2877,12128,750,-1136,6066,4559 } },
8134 { "Sony DSC-F828", 0, 0,
8135 { 7924,-1910,-777,-8226,15459,2998,-1517,2199,6818,-7242,11401,3481 } },
8136 { "Sony DSC-R1", 0, 0,
8137 { 8512,-2641,-694,-8042,15670,2526,-1821,2117,7414 } },
8138 { "Sony DSC-V3", 0, 0,
8139 { 7511,-2571,-692,-7894,15088,3060,-948,1111,8128 } },
8140 { "Sony DSC-RX100M", 0, 0, /* M2, M3, M4, and M5 */
8141 { 6596,-2079,-562,-4782,13016,1933,-970,1581,5181 } },
8142 { "Sony DSC-RX100", 0, 0,
8143 { 8651,-2754,-1057,-3464,12207,1373,-568,1398,4434 } },
8144 { "Sony DSC-RX10M4", 0, 0,
8145 { 7699,-2566,-629,-2967,11270,1928,-378,1286,4807 } },
8146 { "Sony DSC-RX10", 0, 0, /* also RX10M2, RX10M3 */
8147 { 6679,-1825,-745,-5047,13256,1953,-1580,2422,5183 } },
8148 { "Sony DSC-RX1RM2", 0, 0,
8149 { 6629,-1900,-483,-4618,12349,2550,-622,1381,6514 } },
8150 { "Sony DSC-RX1", 0, 0,
8151 { 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } },
8152 { "Sony DSC-RX0", 200, 0,
8153 { 9396,-3507,-843,-2497,11111,1572,-343,1355,5089 } },
8154 { "Sony DSLR-A100", 0, 0xfeb,
8155 { 9437,-2811,-774,-8405,16215,2290,-710,596,7181 } },
8156 { "Sony DSLR-A290", 0, 0,
8157 { 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } },
8158 { "Sony DSLR-A2", 0, 0,
8159 { 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } },
8160 { "Sony DSLR-A300", 0, 0,
8161 { 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } },
8162 { "Sony DSLR-A330", 0, 0,
8163 { 9847,-3091,-929,-8485,16346,2225,-714,595,7103 } },
8164 { "Sony DSLR-A350", 0, 0xffc,
8165 { 6038,-1484,-578,-9146,16746,2513,-875,746,7217 } },
8166 { "Sony DSLR-A380", 0, 0,
8167 { 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } },
8168 { "Sony DSLR-A390", 0, 0,
8169 { 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } },
8170 { "Sony DSLR-A450", 0, 0xfeb,
8171 { 4950,-580,-103,-5228,12542,3029,-709,1435,7371 } },
8172 { "Sony DSLR-A580", 0, 0xfeb,
8173 { 5932,-1492,-411,-4813,12285,2856,-741,1524,6739 } },
8174 { "Sony DSLR-A500", 0, 0xfeb,
8175 { 6046,-1127,-278,-5574,13076,2786,-691,1419,7625 } },
8176 { "Sony DSLR-A5", 0, 0xfeb,
8177 { 4950,-580,-103,-5228,12542,3029,-709,1435,7371 } },
8178 { "Sony DSLR-A700", 0, 0,
8179 { 5775,-805,-359,-8574,16295,2391,-1943,2341,7249 } },
8180 { "Sony DSLR-A850", 0, 0,
8181 { 5413,-1162,-365,-5665,13098,2866,-608,1179,8440 } },
8182 { "Sony DSLR-A900", 0, 0,
8183 { 5209,-1072,-397,-8845,16120,2919,-1618,1803,8654 } },
8184 { "Sony ILCA-68", 0, 0,
8185 { 6435,-1903,-536,-4722,12449,2550,-663,1363,6517 } },
8186 { "Sony ILCA-77M2", 0, 0,
8187 { 5991,-1732,-443,-4100,11989,2381,-704,1467,5992 } },
8188 { "Sony ILCA-99M2", 0, 0,
8189 { 6660,-1918,-471,-4613,12398,2485,-649,1433,6447 } },
8190 { "Sony ILCE-6", 0, 0, /* 6300, 6500 */
8191 { 5973,-1695,-419,-3826,11797,2293,-639,1398,5789 } },
8192 { "Sony ILCE-7M2", 0, 0,
8193 { 5271,-712,-347,-6153,13653,2763,-1601,2366,7242 } },
8194 { "Sony ILCE-7M3", 0, 0,
8195 { 7374,-2389,-551,-5435,13162,2519,-1006,1795,6552 } },
8196 { "Sony ILCE-7S", 0, 0, /* also ILCE-7SM2 */
8197 { 5838,-1430,-246,-3497,11477,2297,-748,1885,5778 } },
8198 { "Sony ILCE-7RM3", 0, 0,
8199 { 6640,-1847,-503,-5238,13010,2474,-993,1673,6527 } },
8200 { "Sony ILCE-7RM2", 0, 0,
8201 { 6629,-1900,-483,-4618,12349,2550,-622,1381,6514 } },
8202 { "Sony ILCE-7R", 0, 0,
8203 { 4913,-541,-202,-6130,13513,2906,-1564,2151,7183 } },
8204 { "Sony ILCE-7", 0, 0,
8205 { 5271,-712,-347,-6153,13653,2763,-1601,2366,7242 } },
8206 { "Sony ILCE-9", 0, 0,
8207 { 6389,-1703,-378,-4562,12265,2587,-670,1489,6550 } },
8208 { "Sony ILCE", 0, 0, /* 3000, 5000, 5100, 6000, and QX1 */
8209 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
8210 { "Sony NEX-5N", 0, 0,
8211 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
8212 { "Sony NEX-5R", 0, 0,
8213 { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } },
8214 { "Sony NEX-5T", 0, 0,
8215 { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } },
8216 { "Sony NEX-3N", 0, 0,
8217 { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } },
8218 { "Sony NEX-3", 138, 0, /* DJC */
8219 { 6907,-1256,-645,-4940,12621,2320,-1710,2581,6230 } },
8220 { "Sony NEX-5", 116, 0, /* DJC */
8221 { 6807,-1350,-342,-4216,11649,2567,-1089,2001,6420 } },
8222 { "Sony NEX-3", 0, 0, /* Adobe */
8223 { 6549,-1550,-436,-4880,12435,2753,-854,1868,6976 } },
8224 { "Sony NEX-5", 0, 0, /* Adobe */
8225 { 6549,-1550,-436,-4880,12435,2753,-854,1868,6976 } },
8226 { "Sony NEX-6", 0, 0,
8227 { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } },
8228 { "Sony NEX-7", 0, 0,
8229 { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } },
8230 { "Sony NEX", 0, 0, /* NEX-C3, NEX-F3 */
8231 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
8232 { "Sony SLT-A33", 0, 0,
8233 { 6069,-1221,-366,-5221,12779,2734,-1024,2066,6834 } },
8234 { "Sony SLT-A35", 0, 0,
8235 { 5986,-1618,-415,-4557,11820,3120,-681,1404,6971 } },
8236 { "Sony SLT-A37", 0, 0,
8237 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
8238 { "Sony SLT-A55", 0, 0,
8239 { 5932,-1492,-411,-4813,12285,2856,-741,1524,6739 } },
8240 { "Sony SLT-A57", 0, 0,
8241 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
8242 { "Sony SLT-A58", 0, 0,
8243 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
8244 { "Sony SLT-A65", 0, 0,
8245 { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } },
8246 { "Sony SLT-A77", 0, 0,
8247 { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } },
8248 { "Sony SLT-A99", 0, 0,
8249 { 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } },
8251 { 7712,-2059,-653,-3882,11494,2726,-710,1332,5958 } },
8253 double cam_xyz[4][3];
8257 sprintf (name, "%s %s", make, model);
8258 for (i=0; i < sizeof table / sizeof *table; i++)
8259 if (!strncmp (name, table[i].prefix, strlen(table[i].prefix))) {
8260 if (table[i].black) black = (ushort) table[i].black;
8261 if (table[i].maximum) maximum = (ushort) table[i].maximum;
8262 if (table[i].trans[0]) {
8263 for (raw_color = j=0; j < 12; j++)
8264 ((double *)cam_xyz)[j] = table[i].trans[j] / 10000.0;
8265 cam_xyz_coeff (rgb_cam, cam_xyz);
8271 void CLASS simple_coeff (int index)
8273 static const float table[][12] = {
8274 /* index 0 -- all Foveon cameras */
8275 { 1.4032,-0.2231,-0.1016,-0.5263,1.4816,0.017,-0.0112,0.0183,0.9113 },
8276 /* index 1 -- Kodak DC20 and DC25 */
8277 { 2.25,0.75,-1.75,-0.25,-0.25,0.75,0.75,-0.25,-0.25,-1.75,0.75,2.25 },
8278 /* index 2 -- Logitech Fotoman Pixtura */
8279 { 1.893,-0.418,-0.476,-0.495,1.773,-0.278,-1.017,-0.655,2.672 },
8280 /* index 3 -- Nikon E880, E900, and E990 */
8281 { -1.936280, 1.800443, -1.448486, 2.584324,
8282 1.405365, -0.524955, -0.289090, 0.408680,
8283 -1.204965, 1.082304, 2.941367, -1.818705 }
8287 for (raw_color = i=0; i < 3; i++)
8288 FORCC rgb_cam[i][c] = table[index][i*colors+c];
8291 short CLASS guess_byte_order (int words)
8295 double diff, sum[2] = {0,0};
8297 fread (test[0], 2, 2, ifp);
8298 for (words-=2; words--; ) {
8299 fread (test[t], 2, 1, ifp);
8300 for (msb=0; msb < 2; msb++) {
8301 diff = (test[t^2][msb] << 8 | test[t^2][!msb])
8302 - (test[t ][msb] << 8 | test[t ][!msb]);
8303 sum[msb] += diff*diff;
8307 return sum[0] < sum[1] ? 0x4d4d : 0x4949;
8310 float CLASS find_green (int bps, int bite, int off0, int off1)
8313 int vbits, col, i, c;
8314 ushort img[2][2064];
8318 fseek (ifp, c ? off1:off0, SEEK_SET);
8319 for (vbits=col=0; col < width; col++) {
8320 for (vbits -= bps; vbits < 0; vbits += bite) {
8322 for (i=0; i < bite; i+=8)
8323 bitbuf |= (unsigned) (fgetc(ifp) << i);
8325 img[c][col] = bitbuf << (64-bps-vbits) >> (64-bps);
8329 sum[ c & 1] += ABS(img[0][c]-img[1][c+1]);
8330 sum[~c & 1] += ABS(img[1][c]-img[0][c+1]);
8332 return 100 * log(sum[0]/sum[1]);
8336 Identify which camera created this file, and set global variables
8339 void CLASS identify()
8341 static const short pana[][6] = {
8342 { 3130, 1743, 4, 0, -6, 0 },
8343 { 3130, 2055, 4, 0, -6, 0 },
8344 { 3130, 2319, 4, 0, -6, 0 },
8345 { 3170, 2103, 18, 0,-42, 20 },
8346 { 3170, 2367, 18, 13,-42,-21 },
8347 { 3177, 2367, 0, 0, -1, 0 },
8348 { 3304, 2458, 0, 0, -1, 0 },
8349 { 3330, 2463, 9, 0, -5, 0 },
8350 { 3330, 2479, 9, 0,-17, 4 },
8351 { 3370, 1899, 15, 0,-44, 20 },
8352 { 3370, 2235, 15, 0,-44, 20 },
8353 { 3370, 2511, 15, 10,-44,-21 },
8354 { 3690, 2751, 3, 0, -8, -3 },
8355 { 3710, 2751, 0, 0, -3, 0 },
8356 { 3724, 2450, 0, 0, 0, -2 },
8357 { 3770, 2487, 17, 0,-44, 19 },
8358 { 3770, 2799, 17, 15,-44,-19 },
8359 { 3880, 2170, 6, 0, -6, 0 },
8360 { 4060, 3018, 0, 0, 0, -2 },
8361 { 4290, 2391, 3, 0, -8, -1 },
8362 { 4330, 2439, 17, 15,-44,-19 },
8363 { 4508, 2962, 0, 0, -3, -4 },
8364 { 4508, 3330, 0, 0, -3, -6 },
8366 static const ushort canon[][11] = {
8367 { 1944, 1416, 0, 0, 48, 0 },
8368 { 2144, 1560, 4, 8, 52, 2, 0, 0, 0, 25 },
8369 { 2224, 1456, 48, 6, 0, 2 },
8370 { 2376, 1728, 12, 6, 52, 2 },
8371 { 2672, 1968, 12, 6, 44, 2 },
8372 { 3152, 2068, 64, 12, 0, 0, 16 },
8373 { 3160, 2344, 44, 12, 4, 4 },
8374 { 3344, 2484, 4, 6, 52, 6 },
8375 { 3516, 2328, 42, 14, 0, 0 },
8376 { 3596, 2360, 74, 12, 0, 0 },
8377 { 3744, 2784, 52, 12, 8, 12 },
8378 { 3944, 2622, 30, 18, 6, 2 },
8379 { 3948, 2622, 42, 18, 0, 2 },
8380 { 3984, 2622, 76, 20, 0, 2, 14 },
8381 { 4104, 3048, 48, 12, 24, 12 },
8382 { 4116, 2178, 4, 2, 0, 0 },
8383 { 4152, 2772, 192, 12, 0, 0 },
8384 { 4160, 3124, 104, 11, 8, 65 },
8385 { 4176, 3062, 96, 17, 8, 0, 0, 16, 0, 7, 0x49 },
8386 { 4192, 3062, 96, 17, 24, 0, 0, 16, 0, 0, 0x49 },
8387 { 4312, 2876, 22, 18, 0, 2 },
8388 { 4352, 2874, 62, 18, 0, 0 },
8389 { 4476, 2954, 90, 34, 0, 0 },
8390 { 4480, 3348, 12, 10, 36, 12, 0, 0, 0, 18, 0x49 },
8391 { 4480, 3366, 80, 50, 0, 0 },
8392 { 4496, 3366, 80, 50, 12, 0 },
8393 { 4768, 3516, 96, 16, 0, 0, 0, 16 },
8394 { 4832, 3204, 62, 26, 0, 0 },
8395 { 4832, 3228, 62, 51, 0, 0 },
8396 { 5108, 3349, 98, 13, 0, 0 },
8397 { 5120, 3318, 142, 45, 62, 0 },
8398 { 5280, 3528, 72, 52, 0, 0 },
8399 { 5344, 3516, 142, 51, 0, 0 },
8400 { 5344, 3584, 126,100, 0, 2 },
8401 { 5360, 3516, 158, 51, 0, 0 },
8402 { 5568, 3708, 72, 38, 0, 0 },
8403 { 5632, 3710, 96, 17, 0, 0, 0, 16, 0, 0, 0x49 },
8404 { 5712, 3774, 62, 20, 10, 2 },
8405 { 5792, 3804, 158, 51, 0, 0 },
8406 { 5920, 3950, 122, 80, 2, 0 },
8407 { 6096, 4051, 76, 35, 0, 0 },
8408 { 6096, 4056, 72, 34, 0, 0 },
8409 { 6288, 4056, 264, 36, 0, 0 },
8410 { 6384, 4224, 120, 44, 0, 0 },
8411 { 6880, 4544, 136, 42, 0, 0 },
8412 { 8896, 5920, 160, 64, 0, 0 },
8414 static const struct {
8418 { 0x168, "EOS 10D" }, { 0x001, "EOS-1D" },
8419 { 0x175, "EOS 20D" }, { 0x174, "EOS-1D Mark II" },
8420 { 0x234, "EOS 30D" }, { 0x232, "EOS-1D Mark II N" },
8421 { 0x190, "EOS 40D" }, { 0x169, "EOS-1D Mark III" },
8422 { 0x261, "EOS 50D" }, { 0x281, "EOS-1D Mark IV" },
8423 { 0x287, "EOS 60D" }, { 0x167, "EOS-1DS" },
8424 { 0x325, "EOS 70D" },
8425 { 0x408, "EOS 77D" }, { 0x331, "EOS M" },
8426 { 0x350, "EOS 80D" }, { 0x328, "EOS-1D X Mark II" },
8427 { 0x346, "EOS 100D" },
8428 { 0x417, "EOS 200D" },
8429 { 0x170, "EOS 300D" }, { 0x188, "EOS-1Ds Mark II" },
8430 { 0x176, "EOS 450D" }, { 0x215, "EOS-1Ds Mark III" },
8431 { 0x189, "EOS 350D" }, { 0x324, "EOS-1D C" },
8432 { 0x236, "EOS 400D" }, { 0x269, "EOS-1D X" },
8433 { 0x252, "EOS 500D" }, { 0x213, "EOS 5D" },
8434 { 0x270, "EOS 550D" }, { 0x218, "EOS 5D Mark II" },
8435 { 0x286, "EOS 600D" }, { 0x285, "EOS 5D Mark III" },
8436 { 0x301, "EOS 650D" }, { 0x302, "EOS 6D" },
8437 { 0x326, "EOS 700D" }, { 0x250, "EOS 7D" },
8438 { 0x393, "EOS 750D" }, { 0x289, "EOS 7D Mark II" },
8439 { 0x347, "EOS 760D" }, { 0x406, "EOS 6D Mark II" },
8440 { 0x405, "EOS 800D" }, { 0x349, "EOS 5D Mark IV" },
8441 { 0x254, "EOS 1000D" },
8442 { 0x288, "EOS 1100D" },
8443 { 0x327, "EOS 1200D" }, { 0x382, "EOS 5DS" },
8444 { 0x404, "EOS 1300D" }, { 0x401, "EOS 5DS R" },
8445 { 0x422, "EOS 1500D" },
8446 { 0x432, "EOS 3000D" },
8448 { 0x002, "DSC-R1" }, { 0x100, "DSLR-A100" },
8449 { 0x101, "DSLR-A900" }, { 0x102, "DSLR-A700" },
8450 { 0x103, "DSLR-A200" }, { 0x104, "DSLR-A350" },
8451 { 0x105, "DSLR-A300" }, { 0x108, "DSLR-A330" },
8452 { 0x109, "DSLR-A230" }, { 0x10a, "DSLR-A290" },
8453 { 0x10d, "DSLR-A850" }, { 0x111, "DSLR-A550" },
8454 { 0x112, "DSLR-A500" }, { 0x113, "DSLR-A450" },
8455 { 0x116, "NEX-5" }, { 0x117, "NEX-3" },
8456 { 0x118, "SLT-A33" }, { 0x119, "SLT-A55V" },
8457 { 0x11a, "DSLR-A560" }, { 0x11b, "DSLR-A580" },
8458 { 0x11c, "NEX-C3" }, { 0x11d, "SLT-A35" },
8459 { 0x11e, "SLT-A65V" }, { 0x11f, "SLT-A77V" },
8460 { 0x120, "NEX-5N" }, { 0x121, "NEX-7" },
8461 { 0x123, "SLT-A37" }, { 0x124, "SLT-A57" },
8462 { 0x125, "NEX-F3" }, { 0x126, "SLT-A99V" },
8463 { 0x127, "NEX-6" }, { 0x128, "NEX-5R" },
8464 { 0x129, "DSC-RX100" }, { 0x12a, "DSC-RX1" },
8465 { 0x12e, "ILCE-3000" }, { 0x12f, "SLT-A58" },
8466 { 0x131, "NEX-3N" }, { 0x132, "ILCE-7" },
8467 { 0x133, "NEX-5T" }, { 0x134, "DSC-RX100M2" },
8468 { 0x135, "DSC-RX10" }, { 0x136, "DSC-RX1R" },
8469 { 0x137, "ILCE-7R" }, { 0x138, "ILCE-6000" },
8470 { 0x139, "ILCE-5000" }, { 0x13d, "DSC-RX100M3" },
8471 { 0x13e, "ILCE-7S" }, { 0x13f, "ILCA-77M2" },
8472 { 0x153, "ILCE-5100" }, { 0x154, "ILCE-7M2" },
8473 { 0x155, "DSC-RX100M4" },{ 0x156, "DSC-RX10M2" },
8474 { 0x158, "DSC-RX1RM2" }, { 0x15a, "ILCE-QX1" },
8475 { 0x15b, "ILCE-7RM2" }, { 0x15e, "ILCE-7SM2" },
8476 { 0x161, "ILCA-68" }, { 0x162, "ILCA-99M2" },
8477 { 0x163, "DSC-RX10M3" }, { 0x164, "DSC-RX100M5" },
8478 { 0x165, "ILCE-6300" }, { 0x166, "ILCE-9" },
8479 { 0x168, "ILCE-6500" }, { 0x16a, "ILCE-7RM3" },
8480 { 0x16b, "ILCE-7M3" }, { 0x16c, "DSC-RX0" },
8481 { 0x16d, "DSC-RX10M4" },
8483 static const char *orig, panalias[][12] = {
8484 "@DC-FZ80", "DC-FZ82", "DC-FZ85",
8485 "@DC-FZ81", "DC-FZ83",
8486 "@DC-GF9", "DC-GX800", "DC-GX850",
8487 "@DC-GF10", "DC-GF90",
8488 "@DC-GX9", "DC-GX7MK3",
8489 "@DC-ZS70", "DC-TZ90", "DC-TZ91", "DC-TZ92", "DC-TZ93",
8490 "@DMC-FZ40", "DMC-FZ45",
8491 "@DMC-FZ2500", "DMC-FZ2000", "DMC-FZH1",
8492 "@DMC-G8", "DMC-G80", "DMC-G81", "DMC-G85",
8493 "@DMC-GX85", "DMC-GX80", "DMC-GX7MK2",
8494 "@DMC-LX9", "DMC-LX10", "DMC-LX15",
8495 "@DMC-ZS40", "DMC-TZ60", "DMC-TZ61",
8496 "@DMC-ZS50", "DMC-TZ70", "DMC-TZ71",
8497 "@DMC-ZS60", "DMC-TZ80", "DMC-TZ81", "DMC-TZ85",
8498 "@DMC-ZS100", "DMC-ZS110", "DMC-TZ100", "DMC-TZ101", "DMC-TZ110", "DMC-TX1",
8499 "@DC-ZS200", "DC-TX2", "DC-TZ200", "DC-TZ202", "DC-TZ220", "DC-ZS220",
8501 static const struct {
8504 uchar lm, tm, rm, bm, lf, cf, max, flags;
8505 char make[10], model[20];
8508 { 786432,1024, 768, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-080C" },
8509 { 1447680,1392,1040, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-145C" },
8510 { 1920000,1600,1200, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-201C" },
8511 { 5067304,2588,1958, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-510C" },
8512 { 5067316,2588,1958, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-510C",12 },
8513 { 10134608,2588,1958, 0, 0, 0, 0, 9,0x94,0,0,"AVT","F-510C" },
8514 { 10134620,2588,1958, 0, 0, 0, 0, 9,0x94,0,0,"AVT","F-510C",12 },
8515 { 16157136,3272,2469, 0, 0, 0, 0, 9,0x94,0,0,"AVT","F-810C" },
8516 { 15980544,3264,2448, 0, 0, 0, 0, 8,0x61,0,1,"AgfaPhoto","DC-833m" },
8517 { 9631728,2532,1902, 0, 0, 0, 0,96,0x61,0,0,"Alcatel","5035D" },
8518 { 2868726,1384,1036, 0, 0, 0, 0,64,0x49,0,8,"Baumer","TXG14",1078 },
8519 { 5298000,2400,1766,12,12,44, 2, 8,0x94,0,2,"Canon","PowerShot SD300" },
8520 { 6553440,2664,1968, 4, 4,44, 4, 8,0x94,0,2,"Canon","PowerShot A460" },
8521 { 6573120,2672,1968,12, 8,44, 0, 8,0x94,0,2,"Canon","PowerShot A610" },
8522 { 6653280,2672,1992,10, 6,42, 2, 8,0x94,0,2,"Canon","PowerShot A530" },
8523 { 7710960,2888,2136,44, 8, 4, 0, 8,0x94,0,2,"Canon","PowerShot S3 IS" },
8524 { 9219600,3152,2340,36,12, 4, 0, 8,0x94,0,2,"Canon","PowerShot A620" },
8525 { 9243240,3152,2346,12, 7,44,13, 8,0x49,0,2,"Canon","PowerShot A470" },
8526 { 10341600,3336,2480, 6, 5,32, 3, 8,0x94,0,2,"Canon","PowerShot A720 IS" },
8527 { 10383120,3344,2484,12, 6,44, 6, 8,0x94,0,2,"Canon","PowerShot A630" },
8528 { 12945240,3736,2772,12, 6,52, 6, 8,0x94,0,2,"Canon","PowerShot A640" },
8529 { 15636240,4104,3048,48,12,24,12, 8,0x94,0,2,"Canon","PowerShot A650" },
8530 { 15467760,3720,2772, 6,12,30, 0, 8,0x94,0,2,"Canon","PowerShot SX110 IS" },
8531 { 15534576,3728,2778,12, 9,44, 9, 8,0x94,0,2,"Canon","PowerShot SX120 IS" },
8532 { 18653760,4080,3048,24,12,24,12, 8,0x94,0,2,"Canon","PowerShot SX20 IS" },
8533 { 19131120,4168,3060,92,16, 4, 1, 8,0x94,0,2,"Canon","PowerShot SX220 HS" },
8534 { 21936096,4464,3276,25,10,73,12, 8,0x16,0,2,"Canon","PowerShot SX30 IS" },
8535 { 24724224,4704,3504, 8,16,56, 8, 8,0x94,0,2,"Canon","PowerShot A3300 IS" },
8536 { 30858240,5248,3920, 8,16,56,16, 8,0x94,0,2,"Canon","IXUS 160" },
8537 { 1976352,1632,1211, 0, 2, 0, 1, 0,0x94,0,1,"Casio","QV-2000UX" },
8538 { 3217760,2080,1547, 0, 0,10, 1, 0,0x94,0,1,"Casio","QV-3*00EX" },
8539 { 6218368,2585,1924, 0, 0, 9, 0, 0,0x94,0,1,"Casio","QV-5700" },
8540 { 7816704,2867,2181, 0, 0,34,36, 0,0x16,0,1,"Casio","EX-Z60" },
8541 { 2937856,1621,1208, 0, 0, 1, 0, 0,0x94,7,13,"Casio","EX-S20" },
8542 { 4948608,2090,1578, 0, 0,32,34, 0,0x94,7,1,"Casio","EX-S100" },
8543 { 6054400,2346,1720, 2, 0,32, 0, 0,0x94,7,1,"Casio","QV-R41" },
8544 { 7426656,2568,1928, 0, 0, 0, 0, 0,0x94,0,1,"Casio","EX-P505" },
8545 { 7530816,2602,1929, 0, 0,22, 0, 0,0x94,7,1,"Casio","QV-R51" },
8546 { 7542528,2602,1932, 0, 0,32, 0, 0,0x94,7,1,"Casio","EX-Z50" },
8547 { 7562048,2602,1937, 0, 0,25, 0, 0,0x16,7,1,"Casio","EX-Z500" },
8548 { 7753344,2602,1986, 0, 0,32,26, 0,0x94,7,1,"Casio","EX-Z55" },
8549 { 9313536,2858,2172, 0, 0,14,30, 0,0x94,7,1,"Casio","EX-P600" },
8550 { 10834368,3114,2319, 0, 0,27, 0, 0,0x94,0,1,"Casio","EX-Z750" },
8551 { 10843712,3114,2321, 0, 0,25, 0, 0,0x94,0,1,"Casio","EX-Z75" },
8552 { 10979200,3114,2350, 0, 0,32,32, 0,0x94,7,1,"Casio","EX-P700" },
8553 { 12310144,3285,2498, 0, 0, 6,30, 0,0x94,0,1,"Casio","EX-Z850" },
8554 { 12489984,3328,2502, 0, 0,47,35, 0,0x94,0,1,"Casio","EX-Z8" },
8555 { 15499264,3754,2752, 0, 0,82, 0, 0,0x94,0,1,"Casio","EX-Z1050" },
8556 { 18702336,4096,3044, 0, 0,24, 0,80,0x94,7,1,"Casio","EX-ZR100" },
8557 { 7684000,2260,1700, 0, 0, 0, 0,13,0x94,0,1,"Casio","QV-4000" },
8558 { 787456,1024, 769, 0, 1, 0, 0, 0,0x49,0,0,"Creative","PC-CAM 600" },
8559 { 28829184,4384,3288, 0, 0, 0, 0,36,0x61,0,0,"DJI" },
8560 { 15151104,4608,3288, 0, 0, 0, 0, 0,0x94,0,0,"Matrix" },
8561 { 3840000,1600,1200, 0, 0, 0, 0,65,0x49,0,0,"Foculus","531C" },
8562 { 307200, 640, 480, 0, 0, 0, 0, 0,0x94,0,0,"Generic" },
8563 { 62464, 256, 244, 1, 1, 6, 1, 0,0x8d,0,0,"Kodak","DC20" },
8564 { 124928, 512, 244, 1, 1,10, 1, 0,0x8d,0,0,"Kodak","DC20" },
8565 { 1652736,1536,1076, 0,52, 0, 0, 0,0x61,0,0,"Kodak","DCS200" },
8566 { 4159302,2338,1779, 1,33, 1, 2, 0,0x94,0,0,"Kodak","C330" },
8567 { 4162462,2338,1779, 1,33, 1, 2, 0,0x94,0,0,"Kodak","C330",3160 },
8568 { 2247168,1232, 912, 0, 0,16, 0, 0,0x00,0,0,"Kodak","C330" },
8569 { 3370752,1232, 912, 0, 0,16, 0, 0,0x00,0,0,"Kodak","C330" },
8570 { 6163328,2864,2152, 0, 0, 0, 0, 0,0x94,0,0,"Kodak","C603" },
8571 { 6166488,2864,2152, 0, 0, 0, 0, 0,0x94,0,0,"Kodak","C603",3160 },
8572 { 460800, 640, 480, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","C603" },
8573 { 9116448,2848,2134, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","C603" },
8574 { 12241200,4040,3030, 2, 0, 0,13, 0,0x49,0,0,"Kodak","12MP" },
8575 { 12272756,4040,3030, 2, 0, 0,13, 0,0x49,0,0,"Kodak","12MP",31556 },
8576 { 18000000,4000,3000, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","12MP" },
8577 { 614400, 640, 480, 0, 3, 0, 0,64,0x94,0,0,"Kodak","KAI-0340" },
8578 { 15360000,3200,2400, 0, 0, 0, 0,96,0x16,0,0,"Lenovo","A820" },
8579 { 3884928,1608,1207, 0, 0, 0, 0,96,0x16,0,0,"Micron","2010",3212 },
8580 { 1138688,1534, 986, 0, 0, 0, 0, 0,0x61,0,0,"Minolta","RD175",513 },
8581 { 1581060,1305, 969, 0, 0,18, 6, 6,0x1e,4,1,"Nikon","E900" },
8582 { 2465792,1638,1204, 0, 0,22, 1, 6,0x4b,5,1,"Nikon","E950" },
8583 { 2940928,1616,1213, 0, 0, 0, 7,30,0x94,0,1,"Nikon","E2100" },
8584 { 4771840,2064,1541, 0, 0, 0, 1, 6,0xe1,0,1,"Nikon","E990" },
8585 { 4775936,2064,1542, 0, 0, 0, 0,30,0x94,0,1,"Nikon","E3700" },
8586 { 5865472,2288,1709, 0, 0, 0, 1, 6,0xb4,0,1,"Nikon","E4500" },
8587 { 5869568,2288,1710, 0, 0, 0, 0, 6,0x16,0,1,"Nikon","E4300" },
8588 { 7438336,2576,1925, 0, 0, 0, 1, 6,0xb4,0,1,"Nikon","E5000" },
8589 { 8998912,2832,2118, 0, 0, 0, 0,30,0x94,7,1,"Nikon","COOLPIX S6" },
8590 { 5939200,2304,1718, 0, 0, 0, 0,30,0x16,0,0,"Olympus","C770UZ" },
8591 { 3178560,2064,1540, 0, 0, 0, 0, 0,0x94,0,1,"Pentax","Optio S" },
8592 { 4841984,2090,1544, 0, 0,22, 0, 0,0x94,7,1,"Pentax","Optio S" },
8593 { 6114240,2346,1737, 0, 0,22, 0, 0,0x94,7,1,"Pentax","Optio S4" },
8594 { 10702848,3072,2322, 0, 0, 0,21,30,0x94,0,1,"Pentax","Optio 750Z" },
8595 { 4147200,1920,1080, 0, 0, 0, 0, 0,0x49,0,0,"Photron","BC2-HD" },
8596 { 4151666,1920,1080, 0, 0, 0, 0, 0,0x49,0,0,"Photron","BC2-HD",8 },
8597 { 13248000,2208,3000, 0, 0, 0, 0,13,0x61,0,0,"Pixelink","A782" },
8598 { 6291456,2048,1536, 0, 0, 0, 0,96,0x61,0,0,"RoverShot","3320AF" },
8599 { 311696, 644, 484, 0, 0, 0, 0, 0,0x16,0,8,"ST Micro","STV680 VGA" },
8600 { 16098048,3288,2448, 0, 0,24, 0, 9,0x94,0,1,"Samsung","S85" },
8601 { 16215552,3312,2448, 0, 0,48, 0, 9,0x94,0,1,"Samsung","S85" },
8602 { 20487168,3648,2808, 0, 0, 0, 0,13,0x94,5,1,"Samsung","WB550" },
8603 { 24000000,4000,3000, 0, 0, 0, 0,13,0x94,5,1,"Samsung","WB550" },
8604 { 12582980,3072,2048, 0, 0, 0, 0,33,0x61,0,0,"Sinar","",68 },
8605 { 33292868,4080,4080, 0, 0, 0, 0,33,0x61,0,0,"Sinar","",68 },
8606 { 44390468,4080,5440, 0, 0, 0, 0,33,0x61,0,0,"Sinar","",68 },
8607 { 1409024,1376,1024, 0, 0, 1, 0, 0,0x49,0,0,"Sony","XCD-SX910CR" },
8608 { 2818048,1376,1024, 0, 0, 1, 0,97,0x49,0,0,"Sony","XCD-SX910CR" },
8609 { 17496000,4320,3240, 0, 0, 0,0,224,0x94,0,0,"Xiro","Xplorer V" },
8611 static const char *corp[] =
8612 { "AgfaPhoto", "Canon", "Casio", "Epson", "Fujifilm",
8613 "Mamiya", "Minolta", "Motorola", "Kodak", "Konica", "Leica",
8614 "Nikon", "Nokia", "Olympus", "Ricoh", "Pentax", "Phase One",
8615 "Samsung", "Sigma", "Sinar", "Sony", "YI" };
8617 int hlen, flen, fsize, zero_fsize=1, i, c;
8620 tiff_flip = flip = filters = UINT_MAX; /* unknown */
8621 raw_height = raw_width = fuji_width = fuji_layout = cr2_slice[0] = 0;
8622 maximum = height = width = top_margin = left_margin = 0;
8623 cdesc[0] = desc[0] = artist[0] = make[0] = model[0] = model2[0] = 0;
8624 iso_speed = shutter = aperture = focal_len = unique_id = 0;
8626 memset (tiff_ifd, 0, sizeof tiff_ifd);
8627 memset (gpsdata, 0, sizeof gpsdata);
8628 memset (cblack, 0, sizeof cblack);
8629 memset (white, 0, sizeof white);
8630 memset (mask, 0, sizeof mask);
8631 thumb_offset = thumb_length = thumb_width = thumb_height = 0;
8632 load_raw = thumb_load_raw = 0;
8633 write_thumb = &CLASS jpeg_thumb;
8634 data_offset = meta_offset = meta_length = tiff_bps = tiff_compress = 0;
8635 kodak_cbpp = zero_after_ff = dng_version = load_flags = 0;
8636 timestamp = shot_order = tiff_samples = black = is_foveon = 0;
8637 mix_green = profile_length = data_error = zero_is_bad = 0;
8638 pixel_aspect = is_raw = raw_color = 1;
8639 tile_width = tile_length = 0;
8640 for (i=0; i < 4; i++) {
8641 cam_mul[i] = i == 1;
8643 FORC3 cmatrix[c][i] = 0;
8644 FORC3 rgb_cam[c][i] = c == i;
8647 for (i=0; i < 0x10000; i++) curve[i] = i;
8651 fseek (ifp, 0, SEEK_SET);
8652 fread (head, 1, 32, ifp);
8653 fseek (ifp, 0, SEEK_END);
8654 flen = fsize = ftell(ifp);
8655 if ((cp = (char *) memmem (head, 32, "MMMM", 4)) ||
8656 (cp = (char *) memmem (head, 32, "IIII", 4))) {
8657 parse_phase_one (cp-head);
8658 if (cp-head && parse_tiff(0)) apply_tiff();
8659 } else if (order == 0x4949 || order == 0x4d4d) {
8660 if (!memcmp (head+6,"HEAPCCDR",8)) {
8662 parse_ciff (hlen, flen-hlen, 0);
8663 load_raw = &CLASS canon_load_raw;
8664 } else if (parse_tiff(0)) apply_tiff();
8665 } else if (!memcmp (head,"\xff\xd8\xff\xe1",4) &&
8666 !memcmp (head+6,"Exif",4)) {
8667 fseek (ifp, 4, SEEK_SET);
8668 data_offset = 4 + get2();
8669 fseek (ifp, data_offset, SEEK_SET);
8670 if (fgetc(ifp) != 0xff)
8673 } else if (!memcmp (head+25,"ARECOYK",7)) {
8674 strcpy (make, "Contax");
8675 strcpy (model,"N Digital");
8676 fseek (ifp, 33, SEEK_SET);
8678 fseek (ifp, 60, SEEK_SET);
8679 FORC4 cam_mul[c ^ (c >> 1)] = get4();
8680 } else if (!strcmp (head, "PXN")) {
8681 strcpy (make, "Logitech");
8682 strcpy (model,"Fotoman Pixtura");
8683 } else if (!strcmp (head, "qktk")) {
8684 strcpy (make, "Apple");
8685 strcpy (model,"QuickTake 100");
8686 load_raw = &CLASS quicktake_100_load_raw;
8687 } else if (!strcmp (head, "qktn")) {
8688 strcpy (make, "Apple");
8689 strcpy (model,"QuickTake 150");
8690 load_raw = &CLASS kodak_radc_load_raw;
8691 } else if (!memcmp (head,"FUJIFILM",8)) {
8692 fseek (ifp, 84, SEEK_SET);
8693 thumb_offset = get4();
8694 thumb_length = get4();
8695 fseek (ifp, 92, SEEK_SET);
8696 parse_fuji (get4());
8697 if (thumb_offset > 120) {
8698 fseek (ifp, 120, SEEK_SET);
8699 is_raw += (i = get4()) ? 1 : 0;
8700 if (is_raw == 2 && shot_select)
8703 fseek (ifp, 100+28*(shot_select > 0), SEEK_SET);
8704 parse_tiff (data_offset = get4());
8705 parse_tiff (thumb_offset+12);
8708 load_raw = &CLASS unpacked_load_raw;
8711 } else if (!memcmp (head,"RIFF",4)) {
8712 fseek (ifp, 0, SEEK_SET);
8714 } else if (!memcmp (head+4,"ftypcrx ",8)) {
8715 fseek (ifp, 0, SEEK_SET);
8717 } else if (!memcmp (head+4,"ftypqt ",9)) {
8718 fseek (ifp, 0, SEEK_SET);
8721 } else if (!memcmp (head,"\0\001\0\001\0@",6)) {
8722 fseek (ifp, 6, SEEK_SET);
8723 fread (make, 1, 8, ifp);
8724 fread (model, 1, 8, ifp);
8725 fread (model2, 1, 16, ifp);
8726 data_offset = get2();
8729 raw_height = get2();
8730 load_raw = &CLASS nokia_load_raw;
8731 filters = 0x61616161;
8732 } else if (!memcmp (head,"NOKIARAW",8)) {
8733 strcpy (make, "NOKIA");
8735 fseek (ifp, 300, SEEK_SET);
8736 data_offset = get4();
8740 switch (tiff_bps = i*8 / (width * height)) {
8741 case 8: load_raw = &CLASS eight_bit_load_raw; break;
8742 case 10: load_raw = &CLASS nokia_load_raw;
8744 raw_height = height + (top_margin = i / (width * tiff_bps/8) - height);
8746 filters = 0x61616161;
8747 } else if (!memcmp (head,"ARRI",4)) {
8749 fseek (ifp, 20, SEEK_SET);
8752 strcpy (make, "ARRI");
8753 fseek (ifp, 668, SEEK_SET);
8754 fread (model, 1, 64, ifp);
8756 load_raw = &CLASS packed_load_raw;
8758 filters = 0x61616161;
8759 } else if (!memcmp (head,"XPDS",4)) {
8761 fseek (ifp, 0x800, SEEK_SET);
8762 fread (make, 1, 41, ifp);
8763 raw_height = get2();
8765 fseek (ifp, 56, SEEK_CUR);
8766 fread (model, 1, 30, ifp);
8767 data_offset = 0x10000;
8768 load_raw = &CLASS canon_rmf_load_raw;
8769 gamma_curve (0, 12.25, 1, 1023);
8770 } else if (!memcmp (head+4,"RED1",4)) {
8771 strcpy (make, "Red");
8772 strcpy (model,"One");
8774 load_raw = &CLASS redcine_load_raw;
8775 gamma_curve (1/2.4, 12.92, 1, 4095);
8776 filters = 0x49494949;
8777 } else if (!memcmp (head,"DSC-Image",9))
8779 else if (!memcmp (head,"PWAD",4))
8781 else if (!memcmp (head,"\0MRM",4))
8783 else if (!memcmp (head,"FOVb",4))
8785 else if (!memcmp (head,"CI",2))
8788 for (zero_fsize=i=0; i < sizeof table / sizeof *table; i++)
8789 if (fsize == table[i].fsize) {
8790 strcpy (make, table[i].make );
8791 strcpy (model, table[i].model);
8792 flip = table[i].flags >> 2;
8793 zero_is_bad = table[i].flags & 2;
8794 if (table[i].flags & 1)
8795 parse_external_jpeg();
8796 data_offset = table[i].offset;
8797 raw_width = table[i].rw;
8798 raw_height = table[i].rh;
8799 left_margin = table[i].lm;
8800 top_margin = table[i].tm;
8801 width = raw_width - left_margin - table[i].rm;
8802 height = raw_height - top_margin - table[i].bm;
8803 filters = 0x1010101 * table[i].cf;
8804 colors = 4 - !((filters & filters >> 1) & 0x5555);
8805 load_flags = table[i].lf;
8806 switch (tiff_bps = (fsize-data_offset)*8 / (raw_width*raw_height)) {
8808 load_raw = &CLASS minolta_rd175_load_raw; break;
8810 load_raw = &CLASS eight_bit_load_raw; break;
8813 if (!strcmp(make,"Canon")) load_flags |= 256;
8814 load_raw = &CLASS packed_load_raw; break;
8816 order = 0x4949 | 0x404 * (load_flags & 1);
8817 tiff_bps -= load_flags >> 4;
8818 tiff_bps -= load_flags = load_flags >> 1 & 7;
8819 load_raw = &CLASS unpacked_load_raw;
8821 maximum = (1 << tiff_bps) - (1 << table[i].max);
8823 if (zero_fsize) fsize = 0;
8824 if (make[0] == 0) parse_smal (0, flen);
8827 if (!(strncmp(model,"ov",2) && strncmp(model,"RP_OV",5)) &&
8828 !fseek (ifp, -6404096, SEEK_END) &&
8829 fread (head, 1, 32, ifp) && !strcmp(head,"BRCMn")) {
8830 strcpy (make, "OmniVision");
8831 data_offset = ftell(ifp) + 0x8000-32;
8834 load_raw = &CLASS nokia_load_raw;
8835 filters = 0x16161616;
8839 for (i=0; i < sizeof corp / sizeof *corp; i++)
8840 if (strcasestr (make, corp[i])) /* Simplify company names */
8841 strcpy (make, corp[i]);
8842 if ((!strcmp(make,"Kodak") || !strcmp(make,"Leica")) &&
8843 ((cp = strcasestr(model," DIGITAL CAMERA")) ||
8844 (cp = strstr(model,"FILE VERSION"))))
8846 if (!strncasecmp(model,"PENTAX",6))
8847 strcpy (make, "Pentax");
8848 cp = make + strlen(make); /* Remove trailing spaces */
8849 while (*--cp == ' ') *cp = 0;
8850 cp = model + strlen(model);
8851 while (*--cp == ' ') *cp = 0;
8852 i = strlen(make); /* Remove make from model */
8853 if (!strncasecmp (model, make, i) && model[i++] == ' ')
8854 memmove (model, model+i, 64-i);
8855 if (!strncmp (model,"FinePix ",8))
8856 strcpy (model, model+8);
8857 if (!strncmp (model,"Digital Camera ",15))
8858 strcpy (model, model+15);
8859 desc[511] = artist[63] = make[63] = model[63] = model2[63] = 0;
8860 if (!is_raw) goto notraw;
8862 if (!height) height = raw_height;
8863 if (!width) width = raw_width;
8864 if (height == 2624 && width == 3936) /* Pentax K10D and Samsung GX10 */
8865 { height = 2616; width = 3896; }
8866 if (height == 3136 && width == 4864) /* Pentax K20D and Samsung GX20 */
8867 { height = 3124; width = 4688; filters = 0x16161616; }
8868 if (raw_height == 2868 && (!strcmp(model,"K-r") || !strcmp(model,"K-x")))
8869 { width = 4309; filters = 0x16161616; }
8870 if (raw_height == 3136 && !strcmp(model,"K-7"))
8871 { height = 3122; width = 4684; filters = 0x16161616; top_margin = 2; }
8872 if (raw_height == 3284 && !strncmp(model,"K-5",3))
8873 { left_margin = 10; width = 4950; filters = 0x16161616; }
8874 if (raw_height == 3300 && !strncmp(model,"K-50",4))
8875 { height = 3288, width = 4952; left_margin = 0; top_margin = 12; }
8876 if (raw_height == 3664 && !strncmp(model,"K-S",3))
8877 { width = 5492; left_margin = 0; }
8878 if (raw_height == 4032 && !strcmp(model,"K-3"))
8879 { height = 4032; width = 6040; left_margin = 4; }
8880 if (raw_height == 4060 && !strcmp(model,"KP"))
8881 { height = 4032; width = 6032; left_margin = 52; top_margin = 28; }
8882 if (raw_height == 4950 && !strcmp(model,"K-1"))
8883 { height = 4932; width = 7380; left_margin = 4; top_margin = 18; }
8884 if (raw_height == 5552 && !strcmp(model,"645D"))
8885 { height = 5502; width = 7328; left_margin = 48; top_margin = 29;
8886 filters = 0x61616161; }
8887 if (height == 3014 && width == 4096) /* Ricoh GX200 */
8890 if (filters == UINT_MAX) filters = 0;
8891 if (filters) is_raw *= tiff_samples;
8892 else colors = tiff_samples;
8893 switch (tiff_compress) {
8895 case 1: load_raw = &CLASS packed_dng_load_raw; break;
8896 case 7: load_raw = &CLASS lossless_dng_load_raw; break;
8897 case 34892: load_raw = &CLASS lossy_dng_load_raw; break;
8898 default: load_raw = 0;
8902 if (!strcmp(make,"Canon") && !fsize && tiff_bps != 15) {
8904 load_raw = &CLASS lossless_jpeg_load_raw;
8905 for (i=0; i < sizeof canon / sizeof *canon; i++)
8906 if (raw_width == canon[i][0] && raw_height == canon[i][1]) {
8907 width = raw_width - (left_margin = canon[i][2]);
8908 height = raw_height - (top_margin = canon[i][3]);
8909 width -= canon[i][4];
8910 height -= canon[i][5];
8911 mask[0][1] = canon[i][6];
8912 mask[0][3] = -canon[i][7];
8913 mask[1][1] = canon[i][8];
8914 mask[1][3] = -canon[i][9];
8915 if (canon[i][10]) filters = canon[i][10] * 0x01010101;
8917 if ((unique_id | 0x20000) == 0x2720000) {
8922 for (i=0; i < sizeof unique / sizeof *unique; i++)
8923 if (unique_id == 0x80000000 + unique[i].id) {
8924 adobe_coeff ("Canon", unique[i].model);
8925 if (model[4] == 'K' && strlen(model) == 8)
8926 strcpy (model, unique[i].model);
8928 for (i=0; i < sizeof sonique / sizeof *sonique; i++)
8929 if (unique_id == sonique[i].id)
8930 strcpy (model, sonique[i].model);
8931 for (i=0; i < sizeof panalias / sizeof *panalias; i++)
8932 if (panalias[i][0] == '@') orig = panalias[i]+1;
8933 else if (!strcmp(model,panalias[i]))
8934 adobe_coeff ("Panasonic", orig);
8935 if (!strcmp(make,"Nikon")) {
8937 load_raw = &CLASS packed_load_raw;
8938 if (model[0] == 'E')
8939 load_flags |= !data_offset << 2 | 2;
8942 /* Set parameters based on camera name (for non-DNG files). */
8944 if (!strcmp(model,"KAI-0340")
8945 && find_green (16, 16, 3840, 5120) < 25) {
8947 top_margin = filters = 0;
8948 strcpy (model,"C603");
8950 if (!strcmp(make,"Sony") && raw_width > 3888)
8951 black = 128 << (tiff_bps - 12);
8953 if (height*2 < width) pixel_aspect = 0.5;
8954 if (height > width) pixel_aspect = 2;
8957 } else if (!strcmp(make,"Canon") && tiff_bps == 15) {
8959 case 3344: width -= 66;
8960 case 3872: width -= 6;
8962 if (height > width) {
8964 SWAP(raw_height,raw_width);
8966 if (width == 7200 && height == 3888) {
8967 raw_width = width = 6480;
8968 raw_height = height = 4320;
8971 tiff_samples = colors = 3;
8972 load_raw = &CLASS canon_sraw_load_raw;
8973 } else if (!strcmp(model,"PowerShot 600")) {
8978 filters = 0xe1e4e1e4;
8979 load_raw = &CLASS canon_600_load_raw;
8980 } else if (!strcmp(model,"PowerShot A5") ||
8981 !strcmp(model,"PowerShot A5 Zoom")) {
8985 pixel_aspect = 256/235.0;
8986 filters = 0x1e4e1e4e;
8988 } else if (!strcmp(model,"PowerShot A50")) {
8992 filters = 0x1b4e4b1e;
8994 } else if (!strcmp(model,"PowerShot Pro70")) {
8997 filters = 0x1e4b4e1b;
9001 load_raw = &CLASS packed_load_raw;
9003 } else if (!strcmp(model,"PowerShot Pro90 IS") ||
9004 !strcmp(model,"PowerShot G1")) {
9006 filters = 0xb4b4b4b4;
9007 } else if (!strcmp(model,"PowerShot A610")) {
9008 if (canon_s2is()) strcpy (model+10, "S2 IS");
9009 } else if (!strcmp(model,"PowerShot SX220 HS")) {
9011 } else if (!strcmp(model,"EOS D2000C")) {
9012 filters = 0x61616161;
9014 } else if (!strcmp(model,"EOS 80D")) {
9017 } else if (!strcmp(model,"D1")) {
9018 cam_mul[0] *= 256/527.0;
9019 cam_mul[2] *= 256/317.0;
9020 } else if (!strcmp(model,"D1X")) {
9023 } else if (!strcmp(model,"D40X") ||
9024 !strcmp(model,"D60") ||
9025 !strcmp(model,"D80") ||
9026 !strcmp(model,"D3000")) {
9029 } else if (!strcmp(model,"D3") ||
9030 !strcmp(model,"D3S") ||
9031 !strcmp(model,"D700")) {
9034 } else if (!strcmp(model,"D3100")) {
9037 } else if (!strcmp(model,"D5000") ||
9038 !strcmp(model,"D90")) {
9040 } else if (!strcmp(model,"D5100") ||
9041 !strcmp(model,"D7000") ||
9042 !strcmp(model,"COOLPIX A")) {
9044 } else if (!strcmp(model,"D3200") ||
9045 !strncmp(model,"D6",2) ||
9046 !strncmp(model,"D800",4)) {
9048 } else if (!strcmp(model,"D4") ||
9049 !strcmp(model,"Df")) {
9052 } else if (!strncmp(model,"D40",3) ||
9053 !strncmp(model,"D50",3) ||
9054 !strncmp(model,"D70",3)) {
9056 } else if (!strcmp(model,"D100")) {
9058 raw_width = (width += 3) + 3;
9059 } else if (!strcmp(model,"D200")) {
9062 filters = 0x94949494;
9063 } else if (!strncmp(model,"D2H",3)) {
9066 } else if (!strncmp(model,"D2X",3)) {
9067 if (width == 3264) width -= 32;
9069 } else if (!strncmp(model,"D300",4)) {
9071 } else if (!strncmp(model,"COOLPIX B",9)) {
9073 } else if (!strncmp(model,"COOLPIX P",9) && raw_width != 4032) {
9075 filters = 0x94949494;
9076 if (model[9] == '7' && iso_speed >= 400)
9078 } else if (!strncmp(model,"1 ",2)) {
9080 } else if (fsize == 1581060) {
9082 pre_mul[0] = 1.2085;
9083 pre_mul[1] = 1.0943;
9084 pre_mul[3] = 1.1103;
9085 } else if (fsize == 3178560) {
9088 } else if (fsize == 4771840) {
9089 if (!timestamp && nikon_e995())
9090 strcpy (model, "E995");
9091 if (strcmp(model,"E995")) {
9092 filters = 0xb4b4b4b4;
9098 } else if (fsize == 2940928) {
9099 if (!timestamp && !nikon_e2100())
9100 strcpy (model,"E2500");
9101 if (!strcmp(model,"E2500")) {
9105 filters = 0x4b4b4b4b;
9107 } else if (fsize == 4775936) {
9108 if (!timestamp) nikon_3700();
9109 if (model[0] == 'E' && atoi(model+1) < 3700)
9110 filters = 0x49494949;
9111 if (!strcmp(model,"Optio 33WR")) {
9113 filters = 0x16161616;
9115 if (make[0] == 'O') {
9116 i = find_green (12, 32, 1188864, 3576832);
9117 c = find_green (12, 32, 2383920, 2387016);
9118 if (abs(i) < abs(c)) {
9122 if (i < 0) filters = 0x61616161;
9124 } else if (fsize == 5869568) {
9125 if (!timestamp && minolta_z2()) {
9126 strcpy (make, "Minolta");
9127 strcpy (model,"DiMAGE Z2");
9129 load_flags = 6 + 24*(make[0] == 'M');
9130 } else if (fsize == 6291456) {
9131 fseek (ifp, 0x300000, SEEK_SET);
9132 if ((order = guess_byte_order(0x10000)) == 0x4d4d) {
9133 height -= (top_margin = 16);
9134 width -= (left_margin = 28);
9136 strcpy (make, "ISG");
9139 } else if (!strcmp(make,"Fujifilm")) {
9140 if (!strcmp(model+7,"S2Pro")) {
9141 strcpy (model,"S2Pro");
9146 top_margin = (raw_height - height) >> 2 << 1;
9147 left_margin = (raw_width - width ) >> 2 << 1;
9148 if (width == 2848 || width == 3664) filters = 0x16161616;
9149 if (width == 4032 || width == 4952 || width == 6032 || width == 8280) left_margin = 0;
9150 if (width == 3328 && (width -= 66)) left_margin = 34;
9151 if (width == 4936) left_margin = 4;
9152 if (!strcmp(model,"HS50EXR") ||
9153 !strcmp(model,"F900EXR")) {
9156 filters = 0x16161616;
9158 if (fuji_layout) raw_width *= is_raw;
9160 FORC(36) ((char *)xtrans)[c] =
9161 xtrans_abs[(c/6+top_margin) % 6][(c+left_margin) % 6];
9162 } else if (!strcmp(model,"KD-400Z")) {
9167 } else if (!strcmp(model,"KD-510Z")) {
9169 } else if (!strcasecmp(make,"Minolta")) {
9170 if (!load_raw && (maximum = 0xfff))
9171 load_raw = &CLASS unpacked_load_raw;
9172 if (!strncmp(model,"DiMAGE A",8)) {
9173 if (!strcmp(model,"DiMAGE A200"))
9174 filters = 0x49494949;
9176 load_raw = &CLASS packed_load_raw;
9177 } else if (!strncmp(model,"ALPHA",5) ||
9178 !strncmp(model,"DYNAX",5) ||
9179 !strncmp(model,"MAXXUM",6)) {
9180 sprintf (model+20, "DYNAX %-10s", model+6+(model[0]=='M'));
9181 adobe_coeff (make, model+20);
9182 load_raw = &CLASS packed_load_raw;
9183 } else if (!strncmp(model,"DiMAGE G",8)) {
9184 if (model[8] == '4') {
9187 } else if (model[8] == '5') {
9192 } else if (model[8] == '6') {
9197 filters = 0x61616161;
9199 load_raw = &CLASS unpacked_load_raw;
9203 } else if (!strcmp(model,"*ist D")) {
9204 load_raw = &CLASS unpacked_load_raw;
9206 } else if (!strcmp(model,"*ist DS")) {
9208 } else if (!strcmp(make,"Samsung") && raw_width == 4704) {
9209 height -= top_margin = 8;
9210 width -= 2 * (left_margin = 8);
9212 } else if (!strcmp(make,"Samsung") && raw_height == 3714) {
9213 height -= top_margin = 18;
9214 left_margin = raw_width - (width = 5536);
9215 if (raw_width != 5600)
9216 left_margin = top_margin = 0;
9217 filters = 0x61616161;
9219 } else if (!strcmp(make,"Samsung") && raw_width == 5632) {
9223 width = 5574 - (left_margin = 32 + tiff_bps);
9224 if (tiff_bps == 12) load_flags = 80;
9225 } else if (!strcmp(make,"Samsung") && raw_width == 5664) {
9226 height -= top_margin = 17;
9229 filters = 0x49494949;
9230 } else if (!strcmp(make,"Samsung") && raw_width == 6496) {
9231 filters = 0x61616161;
9232 black = 1 << (tiff_bps - 7);
9233 } else if (!strcmp(model,"EX1")) {
9237 if ((width -= 6) > 3682) {
9242 } else if (!strcmp(model,"WB2000")) {
9246 if ((width -= 10) > 3718) {
9251 } else if (strstr(model,"WB550")) {
9252 strcpy (model, "WB550");
9253 } else if (!strcmp(model,"EX2F")) {
9258 filters = 0x49494949;
9259 load_raw = &CLASS unpacked_load_raw;
9260 } else if (!strcmp(model,"STV680 VGA")) {
9262 } else if (!strcmp(model,"N95")) {
9263 height = raw_height - (top_margin = 2);
9264 } else if (!strcmp(model,"640x480")) {
9265 gamma_curve (0.45, 4.5, 1, 255);
9266 } else if (!strcmp(make,"Hasselblad")) {
9267 if (load_raw == &CLASS lossless_jpeg_load_raw)
9268 load_raw = &CLASS hasselblad_load_raw;
9269 if (raw_width == 7262) {
9274 filters = 0x61616161;
9275 } else if (raw_width == 7410 || raw_width == 8282) {
9280 filters = 0x61616161;
9281 } else if (raw_width == 8384) {
9286 } else if (raw_width == 9044) {
9291 black += load_flags = 256;
9293 } else if (raw_width == 4090) {
9294 strcpy (model, "V96C");
9295 height -= (top_margin = 6);
9296 width -= (left_margin = 3) + 7;
9297 filters = 0x61616161;
9299 if (tiff_samples > 1) {
9300 is_raw = tiff_samples+1;
9301 if (!shot_select && !half_size) filters = 0;
9303 } else if (!strcmp(make,"Sinar")) {
9304 if (!load_raw) load_raw = &CLASS unpacked_load_raw;
9305 if (is_raw > 1 && !shot_select && !half_size) filters = 0;
9307 } else if (!strcmp(make,"Leaf")) {
9309 fseek (ifp, data_offset, SEEK_SET);
9310 if (ljpeg_start (&jh, 1) && jh.bits == 15)
9312 if (tiff_samples > 1) filters = 0;
9313 if (tiff_samples > 1 || tile_length < raw_height) {
9314 load_raw = &CLASS leaf_hdr_load_raw;
9315 raw_width = tile_width;
9317 if ((width | height) == 2048) {
9318 if (tiff_samples == 1) {
9320 strcpy (cdesc, "RBTG");
9321 strcpy (model, "CatchLight");
9322 top_margin = 8; left_margin = 18; height = 2032; width = 2016;
9324 strcpy (model, "DCB2");
9325 top_margin = 10; left_margin = 16; height = 2028; width = 2022;
9327 } else if (width+height == 3144+2060) {
9328 if (!model[0]) strcpy (model, "Cantare");
9329 if (width > height) {
9330 top_margin = 6; left_margin = 32; height = 2048; width = 3072;
9331 filters = 0x61616161;
9333 left_margin = 6; top_margin = 32; width = 2048; height = 3072;
9334 filters = 0x16161616;
9336 if (!cam_mul[0] || model[0] == 'V') filters = 0;
9337 else is_raw = tiff_samples;
9338 } else if (width == 2116) {
9339 strcpy (model, "Valeo 6");
9340 height -= 2 * (top_margin = 30);
9341 width -= 2 * (left_margin = 55);
9342 filters = 0x49494949;
9343 } else if (width == 3171) {
9344 strcpy (model, "Valeo 6");
9345 height -= 2 * (top_margin = 24);
9346 width -= 2 * (left_margin = 24);
9347 filters = 0x16161616;
9349 } else if (!strcmp(make,"Leica") || !strcmp(make,"Panasonic")) {
9350 if ((flen - data_offset) / (raw_width*8/7) == raw_height)
9351 load_raw = &CLASS panasonic_load_raw;
9353 load_raw = &CLASS unpacked_load_raw;
9357 if ((height += 12) > raw_height) height = raw_height;
9358 for (i=0; i < sizeof pana / sizeof *pana; i++)
9359 if (raw_width == pana[i][0] && raw_height == pana[i][1]) {
9360 left_margin = pana[i][2];
9361 top_margin = pana[i][3];
9362 width += pana[i][4];
9363 height += pana[i][5];
9365 filters = 0x01010101 * (uchar) "\x94\x61\x49\x16"
9366 [((filters-1) ^ (left_margin & 1) ^ (top_margin << 1)) & 3];
9367 } else if (!strcmp(model,"C770UZ")) {
9370 filters = 0x16161616;
9371 load_raw = &CLASS packed_load_raw;
9373 } else if (!strcmp(make,"Olympus")) {
9374 height += height & 1;
9375 if (exif_cfa) filters = exif_cfa;
9376 if (width == 4100) width -= 4;
9377 if (width == 4080) width -= 24;
9378 if (width == 9280) { width -= 6; height -= 6; }
9379 if (load_raw == &CLASS unpacked_load_raw)
9382 if (!strcmp(model,"E-300") ||
9383 !strcmp(model,"E-500")) {
9385 if (load_raw == &CLASS unpacked_load_raw) {
9387 memset (cblack, 0, sizeof cblack);
9389 } else if (!strcmp(model,"E-330")) {
9391 if (load_raw == &CLASS unpacked_load_raw)
9393 } else if (!strcmp(model,"SP550UZ")) {
9394 thumb_length = flen - (thumb_offset = 0xa39800);
9397 } else if (!strcmp(model,"TG-4")) {
9399 } else if (!strcmp(model,"TG-5")) {
9402 } else if (!strcmp(model,"N Digital")) {
9405 filters = 0x61616161;
9406 data_offset = 0x1a00;
9407 load_raw = &CLASS packed_load_raw;
9408 } else if (!strcmp(model,"DSC-F828")) {
9412 data_offset = 862144;
9413 load_raw = &CLASS sony_load_raw;
9414 filters = 0x9c9c9c9c;
9416 strcpy (cdesc, "RGBE");
9417 } else if (!strcmp(model,"DSC-V3")) {
9421 data_offset = 787392;
9422 load_raw = &CLASS sony_load_raw;
9423 } else if (!strcmp(make,"Sony") && raw_width == 3984) {
9426 } else if (!strcmp(make,"Sony") && raw_width == 4288) {
9428 } else if (!strcmp(make,"Sony") && raw_width == 4600) {
9429 if (!strcmp(model,"DSLR-A350"))
9432 } else if (!strcmp(make,"Sony") && raw_width == 4928) {
9433 if (height < 3280) width -= 8;
9434 } else if (!strcmp(make,"Sony") && raw_width == 5504) {
9435 width -= height > 3664 ? 8 : 32;
9436 if (!strncmp(model,"DSC",3))
9437 black = 200 << (tiff_bps - 12);
9438 } else if (!strcmp(make,"Sony") && raw_width == 6048) {
9440 if (strstr(model,"RX1") || strstr(model,"A99"))
9442 } else if (!strcmp(make,"Sony") && raw_width == 7392) {
9444 } else if (!strcmp(make,"Sony") && raw_width == 8000) {
9446 } else if (!strcmp(model,"DSLR-A100")) {
9447 if (width == 3880) {
9449 width = ++raw_width;
9456 filters = 0x61616161;
9457 } else if (!strcmp(model,"PIXL")) {
9458 height -= top_margin = 4;
9459 width -= left_margin = 32;
9460 gamma_curve (0, 7, 1, 255);
9461 } else if (!strcmp(model,"C603") || !strcmp(model,"C330")
9462 || !strcmp(model,"12MP")) {
9464 if (filters && data_offset) {
9465 fseek (ifp, data_offset < 4096 ? 168 : 5252, SEEK_SET);
9466 read_shorts (curve, 256);
9467 } else gamma_curve (0, 3.875, 1, 255);
9468 load_raw = filters ? &CLASS eight_bit_load_raw :
9469 strcmp(model,"C330") ? &CLASS kodak_c603_load_raw :
9470 &CLASS kodak_c330_load_raw;
9471 load_flags = tiff_bps > 16;
9473 } else if (!strncasecmp(model,"EasyShare",9)) {
9474 data_offset = data_offset < 0x15000 ? 0x15000 : 0x17000;
9475 load_raw = &CLASS packed_load_raw;
9476 } else if (!strcasecmp(make,"Kodak")) {
9477 if (filters == UINT_MAX) filters = 0x61616161;
9478 if (!strncmp(model,"NC2000",6) ||
9479 !strncmp(model,"EOSDCS",6) ||
9480 !strncmp(model,"DCS4",4)) {
9483 if (model[6] == ' ') model[6] = 0;
9484 if (!strcmp(model,"DCS460A")) goto bw;
9485 } else if (!strcmp(model,"DCS660M")) {
9488 } else if (!strcmp(model,"DCS760M")) {
9492 if (!strcmp(model+4,"20X"))
9493 strcpy (cdesc, "MYCY");
9494 if (strstr(model,"DC25")) {
9495 strcpy (model, "DC25");
9496 data_offset = 15424;
9498 if (!strncmp(model,"DC2",3)) {
9499 raw_height = 2 + (height = 242);
9500 if (flen < 100000) {
9501 raw_width = 256; width = 249;
9502 pixel_aspect = (4.0*height) / (3.0*width);
9504 raw_width = 512; width = 501;
9505 pixel_aspect = (493.0*height) / (373.0*width);
9507 top_margin = left_margin = 1;
9509 filters = 0x8d8d8d8d;
9514 load_raw = &CLASS eight_bit_load_raw;
9515 } else if (!strcmp(model,"40")) {
9516 strcpy (model, "DC40");
9520 load_raw = &CLASS kodak_radc_load_raw;
9522 } else if (strstr(model,"DC50")) {
9523 strcpy (model, "DC50");
9526 data_offset = 19712;
9527 load_raw = &CLASS kodak_radc_load_raw;
9528 } else if (strstr(model,"DC120")) {
9529 strcpy (model, "DC120");
9532 pixel_aspect = height/0.75/width;
9533 load_raw = tiff_compress == 7 ?
9534 &CLASS kodak_jpeg_load_raw : &CLASS kodak_dc120_load_raw;
9535 } else if (!strcmp(model,"DCS200")) {
9538 thumb_offset = 6144;
9540 write_thumb = &CLASS layer_thumb;
9543 } else if (!strcmp(model,"Fotoman Pixtura")) {
9547 load_raw = &CLASS kodak_radc_load_raw;
9548 filters = 0x61616161;
9550 } else if (!strncmp(model,"QuickTake",9)) {
9551 if (head[5]) strcpy (model+10, "200");
9552 fseek (ifp, 544, SEEK_SET);
9555 data_offset = (get4(),get2()) == 30 ? 738:736;
9556 if (height > width) {
9558 fseek (ifp, data_offset-6, SEEK_SET);
9559 flip = ~get2() & 3 ? 5:6;
9561 filters = 0x61616161;
9562 } else if (!strcmp(make,"Rollei") && !load_raw) {
9563 switch (raw_width) {
9576 filters = 0x16161616;
9577 load_raw = &CLASS rollei_load_raw;
9580 sprintf (model, "%dx%d", width, height);
9581 if (filters == UINT_MAX) filters = 0x94949494;
9582 if (thumb_offset && !thumb_height) {
9583 fseek (ifp, thumb_offset, SEEK_SET);
9584 if (ljpeg_start (&jh, 1)) {
9585 thumb_width = jh.wide;
9586 thumb_height = jh.high;
9590 if ((use_camera_matrix & (use_camera_wb || dng_version))
9591 && cmatrix[0][0] > 0.125) {
9592 memcpy (rgb_cam, cmatrix, sizeof cmatrix);
9595 if (raw_color) adobe_coeff (make, model);
9596 if (load_raw == &CLASS kodak_radc_load_raw)
9597 if (raw_color) adobe_coeff ("Apple","Quicktake");
9599 fuji_width = width >> !fuji_layout;
9600 filters = fuji_width & 1 ? 0x94949494 : 0x49494949;
9601 width = (height >> fuji_layout) + fuji_width;
9605 if (raw_height < height) raw_height = height;
9606 if (raw_width < width ) raw_width = width;
9608 if (!tiff_bps) tiff_bps = 12;
9609 if (!maximum) maximum = (1 << tiff_bps) - 1;
9610 if (!load_raw || height < 22 || width < 22 ||
9611 tiff_bps > 16 || tiff_samples > 6 || colors > 4)
9614 if (load_raw == &CLASS redcine_load_raw) {
9615 fprintf (stderr,_("%s: You must link dcraw with %s!!\n"),
9616 ifname, "libjasper");
9621 if (load_raw == &CLASS kodak_jpeg_load_raw ||
9622 load_raw == &CLASS lossy_dng_load_raw) {
9623 fprintf (stderr,_("%s: You must link dcraw with %s!!\n"),
9629 strcpy (cdesc, colors == 3 ? "RGBG":"GMCY");
9630 if (!raw_height) raw_height = height;
9631 if (!raw_width ) raw_width = width;
9632 if (filters > 999 && colors == 3)
9633 filters |= ((filters >> 2 & 0x22222222) |
9634 (filters << 2 & 0x88888888)) & filters << 1;
9636 if (flip == UINT_MAX) flip = tiff_flip;
9637 if (flip == UINT_MAX) flip = 0;
9640 { unsigned flp = flip;
9641 switch ((flp+3600) % 360) {
9642 case 270: flp = 5; break;
9643 case 180: flp = 3; break;
9647 sprintf(info, "%d %d", height, width);
9649 sprintf(info, "%d %d", width, height); }
9653 void CLASS apply_profile (const char *input, const char *output)
9656 cmsHPROFILE hInProfile=0, hOutProfile=0;
9657 cmsHTRANSFORM hTransform;
9661 if (strcmp (input, "embed"))
9662 hInProfile = cmsOpenProfileFromFile (input, "r");
9663 else if (profile_length) {
9664 prof = (char *) malloc (profile_length);
9665 merror (prof, "apply_profile()");
9666 fseek (ifp, profile_offset, SEEK_SET);
9667 fread (prof, 1, profile_length, ifp);
9668 hInProfile = cmsOpenProfileFromMem (prof, profile_length);
9671 fprintf (stderr,_("%s has no embedded profile.\n"), ifname);
9672 if (!hInProfile) return;
9674 hOutProfile = cmsCreate_sRGBProfile();
9675 else if ((fp = fopen (output, "rb"))) {
9676 fread (&size, 4, 1, fp);
9677 fseek (fp, 0, SEEK_SET);
9678 oprof = (unsigned *) malloc (size = ntohl(size));
9679 merror (oprof, "apply_profile()");
9680 fread (oprof, 1, size, fp);
9682 if (!(hOutProfile = cmsOpenProfileFromMem (oprof, size))) {
9687 fprintf (stderr,_("Cannot open file %s!\n"), output);
9688 if (!hOutProfile) goto quit;
9690 fprintf (stderr,_("Applying color profile...\n"));
9691 hTransform = cmsCreateTransform (hInProfile, TYPE_RGBA_16,
9692 hOutProfile, TYPE_RGBA_16, INTENT_PERCEPTUAL, 0);
9693 cmsDoTransform (hTransform, image, image, width*height);
9694 raw_color = 1; /* Don't use rgb_cam with a profile */
9695 cmsDeleteTransform (hTransform);
9696 cmsCloseProfile (hOutProfile);
9698 cmsCloseProfile (hInProfile);
9702 void CLASS convert_to_rgb()
9704 int row, col, c, i, j, k;
9706 float out[3], out_cam[3][4];
9707 double num, inverse[3][3];
9708 static const double xyzd50_srgb[3][3] =
9709 { { 0.436083, 0.385083, 0.143055 },
9710 { 0.222507, 0.716888, 0.060608 },
9711 { 0.013930, 0.097097, 0.714022 } };
9712 static const double rgb_rgb[3][3] =
9713 { { 1,0,0 }, { 0,1,0 }, { 0,0,1 } };
9714 static const double adobe_rgb[3][3] =
9715 { { 0.715146, 0.284856, 0.000000 },
9716 { 0.000000, 1.000000, 0.000000 },
9717 { 0.000000, 0.041166, 0.958839 } };
9718 static const double wide_rgb[3][3] =
9719 { { 0.593087, 0.404710, 0.002206 },
9720 { 0.095413, 0.843149, 0.061439 },
9721 { 0.011621, 0.069091, 0.919288 } };
9722 static const double prophoto_rgb[3][3] =
9723 { { 0.529317, 0.330092, 0.140588 },
9724 { 0.098368, 0.873465, 0.028169 },
9725 { 0.016879, 0.117663, 0.865457 } };
9726 static const double aces_rgb[3][3] =
9727 { { 0.432996, 0.375380, 0.189317 },
9728 { 0.089427, 0.816523, 0.102989 },
9729 { 0.019165, 0.118150, 0.941914 } };
9730 static const double (*out_rgb[])[3] =
9731 { rgb_rgb, adobe_rgb, wide_rgb, prophoto_rgb, xyz_rgb, aces_rgb };
9732 static const char *name[] =
9733 { "sRGB", "Adobe RGB (1998)", "WideGamut D65", "ProPhoto D65", "XYZ", "ACES" };
9734 static const unsigned phead[] =
9735 { 1024, 0, 0x2100000, 0x6d6e7472, 0x52474220, 0x58595a20, 0, 0, 0,
9736 0x61637370, 0, 0, 0x6e6f6e65, 0, 0, 0, 0, 0xf6d6, 0x10000, 0xd32d };
9738 { 10, 0x63707274, 0, 36, /* cprt */
9739 0x64657363, 0, 40, /* desc */
9740 0x77747074, 0, 20, /* wtpt */
9741 0x626b7074, 0, 20, /* bkpt */
9742 0x72545243, 0, 14, /* rTRC */
9743 0x67545243, 0, 14, /* gTRC */
9744 0x62545243, 0, 14, /* bTRC */
9745 0x7258595a, 0, 20, /* rXYZ */
9746 0x6758595a, 0, 20, /* gXYZ */
9747 0x6258595a, 0, 20 }; /* bXYZ */
9748 static const unsigned pwhite[] = { 0xf351, 0x10000, 0x116cc };
9749 unsigned pcurve[] = { 0x63757276, 0, 1, 0x1000000 };
9751 gamma_curve (gamm[0], gamm[1], 0, 0);
9752 memcpy (out_cam, rgb_cam, sizeof out_cam);
9753 raw_color |= colors == 1 || document_mode ||
9754 output_color < 1 || output_color > 6;
9756 oprof = (unsigned *) calloc (phead[0], 1);
9757 merror (oprof, "convert_to_rgb()");
9758 memcpy (oprof, phead, sizeof phead);
9759 if (output_color == 5) oprof[4] = oprof[5];
9760 oprof[0] = 132 + 12*pbody[0];
9761 for (i=0; i < pbody[0]; i++) {
9762 oprof[oprof[0]/4] = i ? (i > 1 ? 0x58595a20 : 0x64657363) : 0x74657874;
9763 pbody[i*3+2] = oprof[0];
9764 oprof[0] += (pbody[i*3+3] + 3) & -4;
9766 memcpy (oprof+32, pbody, sizeof pbody);
9767 oprof[pbody[5]/4+2] = strlen(name[output_color-1]) + 1;
9768 memcpy ((char *)oprof+pbody[8]+8, pwhite, sizeof pwhite);
9769 pcurve[3] = (short)(256/gamm[5]+0.5) << 16;
9770 for (i=4; i < 7; i++)
9771 memcpy ((char *)oprof+pbody[i*3+2], pcurve, sizeof pcurve);
9772 pseudoinverse ((double (*)[3]) out_rgb[output_color-1], inverse, 3);
9773 for (i=0; i < 3; i++)
9774 for (j=0; j < 3; j++) {
9775 for (num = k=0; k < 3; k++)
9776 num += xyzd50_srgb[i][k] * inverse[j][k];
9777 oprof[pbody[j*3+23]/4+i+2] = num * 0x10000 + 0.5;
9779 for (i=0; i < phead[0]/4; i++)
9780 oprof[i] = htonl(oprof[i]);
9781 strcpy ((char *)oprof+pbody[2]+8, "auto-generated by dcraw");
9782 strcpy ((char *)oprof+pbody[5]+12, name[output_color-1]);
9783 for (i=0; i < 3; i++)
9784 for (j=0; j < colors; j++)
9785 for (out_cam[i][j] = k=0; k < 3; k++)
9786 out_cam[i][j] += out_rgb[output_color-1][i][k] * rgb_cam[k][j];
9789 fprintf (stderr, raw_color ? _("Building histograms...\n") :
9790 _("Converting to %s colorspace...\n"), name[output_color-1]);
9792 memset (histogram, 0, sizeof histogram);
9793 for (img=image[0], row=0; row < height; row++)
9794 for (col=0; col < width; col++, img+=4) {
9796 out[0] = out[1] = out[2] = 0;
9798 out[0] += out_cam[0][c] * img[c];
9799 out[1] += out_cam[1][c] * img[c];
9800 out[2] += out_cam[2][c] * img[c];
9802 FORC3 img[c] = CLIP((int) out[c]);
9804 else if (document_mode)
9805 img[0] = img[fcol(row,col)];
9806 FORCC histogram[c][img[c] >> 3]++;
9808 if (colors == 4 && output_color) colors = 3;
9809 if (document_mode && filters) colors = 1;
9812 // Export color matrix to Cinelerra.
9813 // It can't be applied before interpolation.
9815 for(i = 0; i < 3; i++) {
9816 for(j = 0; j < 3; j++)
9817 matrix[k++] = rgb_cam[i][j];
9822 void CLASS fuji_rotate()
9828 ushort wide, high, (*img)[4], (*pix)[4];
9830 if (!fuji_width) return;
9832 fprintf (stderr,_("Rotating image 45 degrees...\n"));
9833 fuji_width = (fuji_width - 1 + shrink) >> shrink;
9835 wide = fuji_width / step;
9836 high = (height - fuji_width) / step;
9837 img = (ushort (*)[4]) calloc (high, wide*sizeof *img);
9838 merror (img, "fuji_rotate()");
9840 for (row=0; row < high; row++)
9841 for (col=0; col < wide; col++) {
9842 ur = r = fuji_width + (row-col)*step;
9843 uc = c = (row+col)*step;
9844 if (ur > height-2 || uc > width-2) continue;
9847 pix = image + ur*width + uc;
9848 for (i=0; i < colors; i++)
9849 img[row*wide+col][i] =
9850 (pix[ 0][i]*(1-fc) + pix[ 1][i]*fc) * (1-fr) +
9851 (pix[width][i]*(1-fc) + pix[width+1][i]*fc) * fr;
9860 void CLASS stretch()
9862 ushort newdim, (*img)[4], *pix0, *pix1;
9866 if (pixel_aspect == 1) return;
9867 if (verbose) fprintf (stderr,_("Stretching the image...\n"));
9868 if (pixel_aspect < 1) {
9869 newdim = height / pixel_aspect + 0.5;
9870 img = (ushort (*)[4]) calloc (width, newdim*sizeof *img);
9871 merror (img, "stretch()");
9872 for (rc=row=0; row < newdim; row++, rc+=pixel_aspect) {
9873 frac = rc - (c = rc);
9874 pix0 = pix1 = image[c*width];
9875 if (c+1 < height) pix1 += width*4;
9876 for (col=0; col < width; col++, pix0+=4, pix1+=4)
9877 FORCC img[row*width+col][c] = pix0[c]*(1-frac) + pix1[c]*frac + 0.5;
9881 newdim = width * pixel_aspect + 0.5;
9882 img = (ushort (*)[4]) calloc (height, newdim*sizeof *img);
9883 merror (img, "stretch()");
9884 for (rc=col=0; col < newdim; col++, rc+=1/pixel_aspect) {
9885 frac = rc - (c = rc);
9886 pix0 = pix1 = image[c];
9887 if (c+1 < width) pix1 += 4;
9888 for (row=0; row < height; row++, pix0+=width*4, pix1+=width*4)
9889 FORCC img[row*newdim+col][c] = pix0[c]*(1-frac) + pix1[c]*frac + 0.5;
9897 int CLASS flip_index (int row, int col)
9899 if (flip & 4) SWAP(row,col);
9900 if (flip & 2) row = iheight - 1 - row;
9901 if (flip & 1) col = iwidth - 1 - col;
9902 return row * iwidth + col;
9908 union { char c[4]; short s[2]; int i; } val;
9912 ushort order, magic;
9915 struct tiff_tag tag[23];
9918 struct tiff_tag exif[4];
9920 struct tiff_tag gpst[10];
9924 char desc[512], make[64], model[64], soft[32], date[20], artist[64];
9927 void CLASS tiff_set (struct tiff_hdr *th, ushort *ntag,
9928 ushort tag, ushort type, int count, int val)
9930 struct tiff_tag *tt;
9933 tt = (struct tiff_tag *)(ntag+1) + (*ntag)++;
9935 if (type == 1 && count <= 4)
9936 FORC(4) tt->val.c[c] = val >> (c << 3);
9937 else if (type == 2) {
9938 count = strnlen((char *)th + val, count-1) + 1;
9940 FORC(4) tt->val.c[c] = ((char *)th)[val+c];
9941 } else if (type == 3 && count <= 2)
9942 FORC(2) tt->val.s[c] = val >> (c << 4);
9948 #define TOFF(ptr) ((char *)(&(ptr)) - (char *)th)
9950 void CLASS tiff_head (struct tiff_hdr *th, int full)
9955 memset (th, 0, sizeof *th);
9956 th->order = htonl(0x4d4d4949) >> 16;
9959 th->rat[0] = th->rat[2] = 300;
9960 th->rat[1] = th->rat[3] = 1;
9961 FORC(6) th->rat[4+c] = 1000000;
9962 th->rat[4] *= shutter;
9963 th->rat[6] *= aperture;
9964 th->rat[8] *= focal_len;
9965 strncpy (th->desc, desc, 512);
9966 strncpy (th->make, make, 64);
9967 strncpy (th->model, model, 64);
9968 strcpy (th->soft, "dcraw v" DCRAW_VERSION);
9969 t = localtime (×tamp);
9970 sprintf (th->date, "%04d:%02d:%02d %02d:%02d:%02d",
9971 t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);
9972 strncpy (th->artist, artist, 64);
9974 tiff_set (th, &th->ntag, 254, 4, 1, 0);
9975 tiff_set (th, &th->ntag, 256, 4, 1, width);
9976 tiff_set (th, &th->ntag, 257, 4, 1, height);
9977 tiff_set (th, &th->ntag, 258, 3, colors, output_bps);
9979 th->tag[th->ntag-1].val.i = TOFF(th->bps);
9980 FORC4 th->bps[c] = output_bps;
9981 tiff_set (th, &th->ntag, 259, 3, 1, 1);
9982 tiff_set (th, &th->ntag, 262, 3, 1, 1 + (colors > 1));
9984 tiff_set (th, &th->ntag, 270, 2, 512, TOFF(th->desc));
9985 tiff_set (th, &th->ntag, 271, 2, 64, TOFF(th->make));
9986 tiff_set (th, &th->ntag, 272, 2, 64, TOFF(th->model));
9988 if (oprof) psize = ntohl(oprof[0]);
9989 tiff_set (th, &th->ntag, 273, 4, 1, sizeof *th + psize);
9990 tiff_set (th, &th->ntag, 277, 3, 1, colors);
9991 tiff_set (th, &th->ntag, 278, 4, 1, height);
9992 tiff_set (th, &th->ntag, 279, 4, 1, height*width*colors*output_bps/8);
9994 tiff_set (th, &th->ntag, 274, 3, 1, "12435867"[flip]-'0');
9995 tiff_set (th, &th->ntag, 282, 5, 1, TOFF(th->rat[0]));
9996 tiff_set (th, &th->ntag, 283, 5, 1, TOFF(th->rat[2]));
9997 tiff_set (th, &th->ntag, 284, 3, 1, 1);
9998 tiff_set (th, &th->ntag, 296, 3, 1, 2);
9999 tiff_set (th, &th->ntag, 305, 2, 32, TOFF(th->soft));
10000 tiff_set (th, &th->ntag, 306, 2, 20, TOFF(th->date));
10001 tiff_set (th, &th->ntag, 315, 2, 64, TOFF(th->artist));
10002 tiff_set (th, &th->ntag, 34665, 4, 1, TOFF(th->nexif));
10003 if (psize) tiff_set (th, &th->ntag, 34675, 7, psize, sizeof *th);
10004 tiff_set (th, &th->nexif, 33434, 5, 1, TOFF(th->rat[4]));
10005 tiff_set (th, &th->nexif, 33437, 5, 1, TOFF(th->rat[6]));
10006 tiff_set (th, &th->nexif, 34855, 3, 1, iso_speed);
10007 tiff_set (th, &th->nexif, 37386, 5, 1, TOFF(th->rat[8]));
10009 tiff_set (th, &th->ntag, 34853, 4, 1, TOFF(th->ngps));
10010 tiff_set (th, &th->ngps, 0, 1, 4, 0x202);
10011 tiff_set (th, &th->ngps, 1, 2, 2, gpsdata[29]);
10012 tiff_set (th, &th->ngps, 2, 5, 3, TOFF(th->gps[0]));
10013 tiff_set (th, &th->ngps, 3, 2, 2, gpsdata[30]);
10014 tiff_set (th, &th->ngps, 4, 5, 3, TOFF(th->gps[6]));
10015 tiff_set (th, &th->ngps, 5, 1, 1, gpsdata[31]);
10016 tiff_set (th, &th->ngps, 6, 5, 1, TOFF(th->gps[18]));
10017 tiff_set (th, &th->ngps, 7, 5, 3, TOFF(th->gps[12]));
10018 tiff_set (th, &th->ngps, 18, 2, 12, TOFF(th->gps[20]));
10019 tiff_set (th, &th->ngps, 29, 2, 12, TOFF(th->gps[23]));
10020 memcpy (th->gps, gpsdata, sizeof th->gps);
10024 void CLASS jpeg_thumb()
10028 struct tiff_hdr th;
10030 thumb = (char *) malloc (thumb_length);
10031 merror (thumb, "jpeg_thumb()");
10032 fread (thumb, 1, thumb_length, ifp);
10035 if (strcmp (thumb+6, "Exif")) {
10036 memcpy (exif, "\xff\xe1 Exif\0\0", 10);
10037 exif[1] = htons (8 + sizeof th);
10038 fwrite (exif, 1, sizeof exif, ofp);
10039 tiff_head (&th, 0);
10040 fwrite (&th, 1, sizeof th, ofp);
10042 fwrite (thumb+2, 1, thumb_length-2, ofp);
10046 void CLASS write_ppm_tiff()
10048 struct tiff_hdr th;
10051 int c, row, col, soff, rstep, cstep;
10052 int perc, val, total, white=0x2000;
10054 perc = width * height * 0.01; /* 99th percentile white level */
10055 if (fuji_width) perc /= 2;
10056 if (!((highlight & ~2) || no_auto_bright))
10057 for (white=c=0; c < colors; c++) {
10058 for (val=0x2000, total=0; --val > 32; )
10059 if ((total += histogram[c][val]) > perc) break;
10060 if (white < val) white = val;
10062 gamma_curve (gamm[0], gamm[1], 2, (white << 3)/bright);
10065 if (flip & 4) SWAP(height,width);
10066 ppm = (uchar *) calloc (width, colors*output_bps/8);
10067 ppm2 = (ushort *) ppm;
10068 merror (ppm, "write_ppm_tiff()");
10070 tiff_head (&th, 1);
10071 fwrite (&th, sizeof th, 1, ofp);
10073 fwrite (oprof, ntohl(oprof[0]), 1, ofp);
10074 } else if (colors > 3)
10076 "P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLTYPE %s\nENDHDR\n",
10077 width, height, colors, (1 << output_bps)-1, cdesc);
10079 fprintf (ofp, "P%d\n%d %d\n%d\n",
10080 colors/2+5, width, height, (1 << output_bps)-1);
10081 soff = flip_index (0, 0);
10082 cstep = flip_index (0, 1) - soff;
10083 rstep = flip_index (1, 0) - flip_index (0, width);
10084 for (row=0; row < height; row++, soff += rstep) {
10085 for (col=0; col < width; col++, soff += cstep)
10086 if (output_bps == 8)
10087 FORCC ppm [col*colors+c] = curve[image[soff][c]] >> 8;
10088 else FORCC ppm2[col*colors+c] = curve[image[soff][c]];
10089 if (output_bps == 16 && !output_tiff && htons(0x55aa) != 0x55aa)
10090 swabb(ppm2, ppm2, width*colors*2);
10091 fwrite (ppm, colors*output_bps/8, width, ofp);
10097 void CLASS write_cinelerra()
10099 int c, row, col, soff, cstep, rstep;
10100 float scale = 1. / 0xffff;
10101 iheight = height; iwidth = width;
10102 if( (flip & 4) != 0 ) SWAP(height,width);
10103 soff = flip_index(0, 0);
10104 cstep = flip_index(0, 1) - soff;
10105 rstep = flip_index(1, 0) - flip_index(0, width);
10106 if( document_mode ) {
10107 for( row=0; row<height; ++row, soff += rstep ) {
10108 float *output = data[row];
10109 for( col=0; col<width; ++col, soff += cstep ) {
10110 ushort *pixel = image[soff];
10111 FORC3 *output++ = (float)*pixel++ * scale;
10112 if( alpha ) *output++ = 1.0;
10117 int val, total, white=0x2000;
10118 int perc = width * height * 0.01; /* 99th percentile white level */
10119 if( fuji_width ) perc /= 2;
10120 if( !((highlight & ~2) || no_auto_bright) ) {
10121 for( white=c=0; c < colors; ++c ) {
10122 for( val=0x2000, total=0; --val > 32; )
10123 if( (total += histogram[c][val]) > perc ) break;
10124 if( white < val ) white = val;
10127 gamma_curve(gamm[0], gamm[1], 2, (white << 3)/bright);
10128 for( row=0; row<height; ++row, soff += rstep ) {
10129 float *output = data[row];
10130 for( col=0; col<width; ++col, soff += cstep ) {
10131 ushort *pixel = image[soff];
10132 FORC3 *output++ = (float)curve[*pixel++] * scale;
10133 if( alpha ) *output++ = 1.0;
10140 int CLASS main (int argc, const char **argv)
10142 int arg, status=0, quality, i, c;
10143 int timestamp_only=0, thumbnail_only=0, identify_only=0;
10144 int user_qual=-1, user_black=-1, user_sat=-1, user_flip=-1;
10145 int use_fuji_rotate=1, write_to_stdout=0, read_from_stdin=0;
10146 const char *sp, *bpfile=0, *dark_frame=0, *write_ext;
10147 char opm, opt, *ofname, *cp;
10150 const char *cam_profile=0, *out_profile=0;
10154 reset(); // Globals must be reset
10157 // putenv ((char *) "TZ=UTC");
10160 setlocale (LC_CTYPE, "");
10161 setlocale (LC_MESSAGES, "");
10162 bindtextdomain ("dcraw", LOCALEDIR);
10163 textdomain ("dcraw");
10167 printf(_("\nRaw photo decoder \"dcraw\" v%s"), DCRAW_VERSION);
10168 printf(_("\nby Dave Coffin, dcoffin a cybercom o net\n"));
10169 printf(_("\nUsage: %s [OPTION]... [FILE]...\n\n"), argv[0]);
10170 puts(_("-v Print verbose messages"));
10171 puts(_("-c Write image data to standard output"));
10172 puts(_("-e Extract embedded thumbnail image"));
10173 puts(_("-i Identify files without decoding them"));
10174 puts(_("-i -v Identify files and show metadata"));
10175 puts(_("-z Change file dates to camera timestamp"));
10176 puts(_("-w Use camera white balance, if possible"));
10177 puts(_("-a Average the whole image for white balance"));
10178 puts(_("-A <x y w h> Average a grey box for white balance"));
10179 puts(_("-r <r g b g> Set custom white balance"));
10180 puts(_("+M/-M Use/don't use an embedded color matrix"));
10181 puts(_("-C <r b> Correct chromatic aberration"));
10182 puts(_("-P <file> Fix the dead pixels listed in this file"));
10183 puts(_("-K <file> Subtract dark frame (16-bit raw PGM)"));
10184 puts(_("-k <num> Set the darkness level"));
10185 puts(_("-S <num> Set the saturation level"));
10186 puts(_("-n <num> Set threshold for wavelet denoising"));
10187 puts(_("-H [0-9] Highlight mode (0=clip, 1=unclip, 2=blend, 3+=rebuild)"));
10188 puts(_("-t [0-7] Flip image (0=none, 3=180, 5=90CCW, 6=90CW)"));
10189 puts(_("-o [0-6] Output colorspace (raw,sRGB,Adobe,Wide,ProPhoto,XYZ,ACES)"));
10191 puts(_("-o <file> Apply output ICC profile from file"));
10192 puts(_("-p <file> Apply camera ICC profile from file or \"embed\""));
10194 puts(_("-d Document mode (no color, no interpolation)"));
10195 puts(_("-D Document mode without scaling (totally raw)"));
10196 puts(_("-j Don't stretch or rotate raw pixels"));
10197 puts(_("-W Don't automatically brighten the image"));
10198 puts(_("-b <num> Adjust brightness (default = 1.0)"));
10199 puts(_("-g <p ts> Set custom gamma curve (default = 2.222 4.5)"));
10200 puts(_("-q [0-3] Set the interpolation quality"));
10201 puts(_("-h Half-size color image (twice as fast as \"-q 0\")"));
10202 puts(_("-f Interpolate RGGB as four colors"));
10203 puts(_("-m <num> Apply a 3x3 median filter to R-G and B-G"));
10204 puts(_("-s [0..N-1] Select one raw image or \"all\" from each file"));
10205 puts(_("-6 Write 16-bit instead of 8-bit"));
10206 puts(_("-4 Linear 16-bit, same as \"-6 -W -g 1 1\""));
10207 puts(_("-T Write TIFF instead of PPM"));
10212 for (arg=1; (((opm = argv[arg][0]) - 2) | 2) == '+'; ) {
10213 opt = argv[arg++][1];
10214 if ((cp = (char *) strchr (sp="nbrkStqmHACg", opt)))
10215 for (i=0; i < "114111111422"[cp-sp]-'0'; i++)
10216 if (!isdigit(argv[arg+i][0])) {
10217 fprintf (stderr,_("Non-numeric argument to \"-%c\"\n"), opt);
10221 case 'n': threshold = atof(argv[arg++]); break;
10222 case 'b': bright = atof(argv[arg++]); break;
10224 FORC4 user_mul[c] = atof(argv[arg++]); break;
10225 case 'C': aber[0] = 1 / atof(argv[arg++]);
10226 aber[2] = 1 / atof(argv[arg++]); break;
10227 case 'g': gamm[0] = atof(argv[arg++]);
10228 gamm[1] = atof(argv[arg++]);
10229 if (gamm[0]) gamm[0] = 1/gamm[0]; break;
10230 case 'k': user_black = atoi(argv[arg++]); break;
10231 case 'S': user_sat = atoi(argv[arg++]); break;
10232 case 't': user_flip = atoi(argv[arg++]); break;
10233 case 'q': user_qual = atoi(argv[arg++]); break;
10234 case 'm': med_passes = atoi(argv[arg++]); break;
10235 case 'H': highlight = atoi(argv[arg++]); break;
10237 shot_select = abs(atoi(argv[arg]));
10238 multi_out = !strcmp(argv[arg++],"all");
10241 if (isdigit(argv[arg][0]) && !argv[arg][1])
10242 output_color = atoi(argv[arg++]);
10244 else out_profile = argv[arg++];
10246 case 'p': cam_profile = argv[arg++];
10249 case 'P': bpfile = argv[arg++]; break;
10250 case 'K': dark_frame = argv[arg++]; break;
10251 case 'z': timestamp_only = 1; break;
10252 case 'e': thumbnail_only = 1; break;
10253 case 'i': identify_only = 1; break;
10254 case 'c': write_to_stdout = 1; break;
10255 case 'v': verbose = 1; break;
10256 case 'h': half_size = 1; break;
10257 case 'f': four_color_rgb = 1; break;
10258 case 'A': FORC4 greybox[c] = atoi(argv[arg++]);
10259 case 'a': use_auto_wb = 1; break;
10260 case 'w': use_camera_wb = 1; break;
10261 case 'M': use_camera_matrix = 3 * (opm == '+'); break;
10262 case 'I': read_from_stdin = 1; break;
10263 case 'E': document_mode++;
10264 case 'D': document_mode++;
10265 case 'd': document_mode++;
10266 case 'j': use_fuji_rotate = 0; break;
10267 case 'W': no_auto_bright = 1; break;
10268 case 'T': output_tiff = 1; break;
10269 case '4': gamm[0] = gamm[1] =
10270 no_auto_bright = 1;
10271 case '6': output_bps = 16; break;
10273 fprintf (stderr,_("Unknown option \"-%c\".\n"), opt);
10278 fprintf (stderr,_("No files to process.\n"));
10281 if (write_to_stdout) {
10283 if (0 && isatty(1)) {
10284 fprintf (stderr,_("Will not write an image to the terminal!\n"));
10287 #if defined(WIN32) || defined(DJGPP) || defined(__CYGWIN__)
10288 if (setmode(1,O_BINARY) < 0) {
10289 perror ("setmode()");
10294 for ( ; arg < argc; arg++) {
10299 meta_data = ofname = 0;
10301 if (setjmp (failure)) {
10302 if (fileno(ifp) > 2) fclose(ifp);
10303 if (fileno(ofp) > 2) fclose(ofp);
10307 ifname = argv[arg];
10308 if (!(ifp = fopen (ifname, "rb"))) {
10312 status = (identify(),!is_raw);
10313 if (user_flip >= 0)
10315 switch ((flip+3600) % 360) {
10316 case 270: flip = 5; break;
10317 case 180: flip = 3; break;
10320 if (timestamp_only) {
10321 if ((status = !timestamp))
10322 fprintf (stderr,_("%s has no timestamp.\n"), ifname);
10323 else if (identify_only)
10324 printf ("%10ld%10d %s\n", (long) timestamp, shot_order, ifname);
10327 fprintf (stderr,_("%s time set to %d.\n"), ifname, (int) timestamp);
10328 ut.actime = ut.modtime = timestamp;
10329 utime (ifname, &ut);
10334 // write_fun = &CLASS write_ppm_tiff;
10335 write_fun = &CLASS write_cinelerra;
10337 if (thumbnail_only) {
10338 if ((status = !thumb_offset)) {
10339 fprintf (stderr,_("%s has no thumbnail.\n"), ifname);
10341 } else if (thumb_load_raw) {
10342 load_raw = thumb_load_raw;
10343 data_offset = thumb_offset;
10344 height = thumb_height;
10345 width = thumb_width;
10349 fseek (ifp, thumb_offset, SEEK_SET);
10350 write_fun = write_thumb;
10354 if (load_raw == &CLASS kodak_ycbcr_load_raw) {
10355 height += height & 1;
10356 width += width & 1;
10358 if (identify_only && verbose && make[0]) {
10359 printf (_("\nFilename: %s\n"), ifname);
10360 printf (_("Timestamp: %s"), ctime(×tamp));
10361 printf (_("Camera: %s %s\n"), make, model);
10363 printf (_("Owner: %s\n"), artist);
10365 printf (_("DNG Version: "));
10366 for (i=24; i >= 0; i -= 8)
10367 printf ("%d%c", dng_version >> i & 255, i ? '.':'\n');
10369 printf (_("ISO speed: %d\n"), (int) iso_speed);
10370 printf (_("Shutter: "));
10371 if (shutter > 0 && shutter < 1)
10372 shutter = (printf ("1/"), 1 / shutter);
10373 printf (_("%0.1f sec\n"), shutter);
10374 printf (_("Aperture: f/%0.1f\n"), aperture);
10375 printf (_("Focal length: %0.1f mm\n"), focal_len);
10376 printf (_("Embedded ICC profile: %s\n"), profile_length ? _("yes"):_("no"));
10377 printf (_("Number of raw images: %d\n"), is_raw);
10378 if (pixel_aspect != 1)
10379 printf (_("Pixel Aspect Ratio: %0.6f\n"), pixel_aspect);
10381 printf (_("Thumb size: %4d x %d\n"), thumb_width, thumb_height);
10382 printf (_("Full size: %4d x %d\n"), raw_width, raw_height);
10385 // else if (!is_raw)
10386 // fprintf (stderr,_("Cannot decode file %s\n"), ifname);
10387 if (!is_raw) goto next;
10388 shrink = filters && (half_size || (!identify_only &&
10389 (threshold || aber[0] != 1 || aber[2] != 1)));
10390 iheight = (height + shrink) >> shrink;
10391 iwidth = (width + shrink) >> shrink;
10392 if (identify_only) {
10394 if (document_mode == 3) {
10395 top_margin = left_margin = fuji_width = 0;
10396 height = raw_height;
10399 iheight = (height + shrink) >> shrink;
10400 iwidth = (width + shrink) >> shrink;
10401 if (use_fuji_rotate) {
10403 fuji_width = (fuji_width - 1 + shrink) >> shrink;
10404 iwidth = fuji_width / sqrt(0.5);
10405 iheight = (iheight - fuji_width) / sqrt(0.5);
10407 if (pixel_aspect < 1) iheight = iheight / pixel_aspect + 0.5;
10408 if (pixel_aspect > 1) iwidth = iwidth * pixel_aspect + 0.5;
10412 SWAP(iheight,iwidth);
10413 printf (_("Image size: %4d x %d\n"), width, height);
10414 printf (_("Output size: %4d x %d\n"), iwidth, iheight);
10415 printf (_("Raw colors: %d"), colors);
10417 int fhigh = 2, fwide = 2;
10418 if ((filters ^ (filters >> 8)) & 0xff) fhigh = 4;
10419 if ((filters ^ (filters >> 16)) & 0xffff) fhigh = 8;
10420 if (filters == 1) fhigh = fwide = 16;
10421 if (filters == 9) fhigh = fwide = 6;
10422 printf (_("\nFilter pattern: "));
10423 for (i=0; i < fhigh; i++)
10424 for (c = i && putchar('/') && 0; c < fwide; c++)
10425 putchar (cdesc[fcol(i,c)]);
10427 printf (_("\nDaylight multipliers:"));
10428 FORCC printf (" %f", pre_mul[c]);
10429 if (cam_mul[0] > 0) {
10430 printf (_("\nCamera multipliers:"));
10431 FORC4 printf (" %f", cam_mul[c]);
10437 // printf (_("%s is a %s %s image.\n"), ifname, make, model);
10443 meta_data = (char *) malloc (meta_length);
10444 merror (meta_data, "main()");
10446 if (filters || colors == 1) {
10447 raw_image = (ushort *) calloc ((raw_height+7), raw_width*2);
10448 merror (raw_image, "main()");
10450 image = (ushort (*)[4]) calloc (iheight, iwidth*sizeof *image);
10451 merror (image, "main()");
10454 fprintf (stderr,_("Loading %s %s image from %s ...\n"),
10455 make, model, ifname);
10456 if (shot_select >= is_raw)
10457 fprintf (stderr,_("%s: \"-s %d\" requests a nonexistent image!\n"),
10458 ifname, shot_select);
10459 fseeko (ifp, data_offset, SEEK_SET);
10460 if (raw_image && read_from_stdin)
10461 fread (raw_image, 2, raw_height*raw_width, stdin);
10463 (this->*load_raw)();
10464 if (document_mode == 3) {
10465 top_margin = left_margin = fuji_width = 0;
10466 height = raw_height;
10469 iheight = (height + shrink) >> shrink;
10470 iwidth = (width + shrink) >> shrink;
10472 image = (ushort (*)[4]) calloc (iheight, iwidth*sizeof *image);
10473 merror (image, "main()");
10474 crop_masked_pixels();
10477 if (zero_is_bad) remove_zeroes();
10478 bad_pixels (bpfile);
10479 if (dark_frame) subtract (dark_frame);
10480 quality = 2 + !fuji_width;
10481 if (user_qual >= 0) quality = user_qual;
10483 FORC3 if (i > cblack[c]) i = cblack[c];
10484 FORC4 cblack[c] -= i;
10487 FORC (cblack[4] * cblack[5])
10488 if (i > cblack[6+c]) i = cblack[6+c];
10489 FORC (cblack[4] * cblack[5])
10492 if (user_black >= 0) black = user_black;
10493 FORC4 cblack[c] += black;
10494 if (user_sat > 0) maximum = user_sat;
10499 if (document_mode || load_raw == &CLASS foveon_dp_load_raw) {
10500 for (i=0; i < height*width*4; i++)
10501 if ((short) image[0][i] < 0) image[0][i] = 0;
10502 } else foveon_interpolate();
10503 } else if (document_mode < 2)
10506 if (filters && !document_mode) {
10509 else if (quality == 1 || colors > 3)
10511 else if (quality == 2 && filters > 1000)
10513 else if (filters == 9)
10514 xtrans_interpolate (quality*2-3);
10519 for (colors=3, i=0; i < height*width; i++)
10520 image[i][1] = (image[i][1] + image[i][3]) >> 1;
10521 if (!is_foveon && colors == 3) median_filter();
10522 if (!is_foveon && highlight == 2) blend_highlights();
10523 if (!is_foveon && highlight > 2) recover_highlights();
10524 if (use_fuji_rotate) fuji_rotate();
10526 if (cam_profile) apply_profile (cam_profile, out_profile);
10529 if (use_fuji_rotate) stretch();
10531 if (write_fun == &CLASS jpeg_thumb)
10532 write_ext = ".jpg";
10533 else if (output_tiff && write_fun == &CLASS write_ppm_tiff)
10534 write_ext = ".tiff";
10536 write_ext = &".pgm\0.ppm\0.ppm\0.pam"[colors*5-5];
10537 ofname = (char *) malloc (strlen(ifname) + 64);
10538 merror (ofname, "main()");
10539 if (write_to_stdout)
10540 strcpy (ofname,_("standard output"));
10542 strcpy (ofname, ifname);
10543 if ((cp = strrchr (ofname, '.'))) *cp = 0;
10545 sprintf (ofname+strlen(ofname), "_%0*d",
10546 snprintf(0,0,"%d",is_raw-1), shot_select);
10547 if (thumbnail_only)
10548 strcat (ofname, ".thumb");
10549 strcat (ofname, write_ext);
10550 ofp = fopen (ofname, "wb");
10558 fprintf (stderr,_("Writing data to %s ...\n"), ofname);
10559 (this->*write_fun)();
10561 if (ofp != stdout) fclose(ofp);
10563 if (meta_data) free (meta_data);
10564 if (ofname) free (ofname);
10565 if (oprof) free (oprof);
10566 if (image) free (image);
10568 if (++shot_select < is_raw) arg--;
10569 else shot_select = 0;