2 dcraw.c -- Dave Coffin's raw photo decoder
3 Copyright 1997-2016 by Dave Coffin, dcoffin a cybercom o net
5 This is a command-line ANSI C program to convert raw photos from
6 any digital camera on any computer running any operating system.
8 No license is required to download and use dcraw.c. However,
9 to lawfully redistribute dcraw, you must either (a) offer, at
10 no extra charge, full source code* for all executable files
11 containing RESTRICTED functions, (b) distribute this code under
12 the GPL Version 2 or later, (c) remove all RESTRICTED functions,
13 re-implement them, or copy them from an earlier, unrestricted
14 Revision of dcraw.c, or (d) purchase a license from the author.
16 The functions that process Foveon images have been RESTRICTED
17 since Revision 1.237. All other code remains free for all uses.
19 *If you have not modified dcraw.c in any way, a link to my
20 homepage qualifies as "full source code".
23 $Date: 2016/05/10 21:30:43 $
26 #define DCRAW_VERSION "9.27"
31 #define _USE_MATH_DEFINES
43 #include <sys/types.h>
49 #if defined(DJGPP) || defined(__MINGW32__)
53 #define fgetc getc_unlocked
59 #include <sys/utime.h>
61 #pragma comment(lib, "ws2_32.lib")
62 #define snprintf _snprintf
63 #define strcasecmp stricmp
64 #define strncasecmp strnicmp
65 typedef __int64 INT64;
66 typedef unsigned __int64 UINT64;
70 #include <netinet/in.h>
71 typedef long long INT64;
72 typedef unsigned long long UINT64;
81 #include <jasper/jasper.h> /* Decode Red camera movies */
84 #include <jpeglib.h> /* Decode compressed Kodak DC120 photos */
85 #endif /* and Adobe Lossy DNGs */
87 #include <lcms2.h> /* Support color profiles */
91 #define _(String) gettext(String)
93 #define _(String) (String)
97 #define uchar unsigned char
100 #define ushort unsigned short
104 All global variables are defined here, and all functions that
105 access them are prefixed with "CLASS". Note that a thread-safe
106 C++ class cannot have non-const static local variables.
110 char dcraw_info[1024];
113 float dcraw_matrix[9];
124 static FILE *ifp, *ofp;
126 static const char *ifname;
127 static char *meta_data, xtrans[6][6], xtrans_abs[6][6];
128 static char cdesc[5], desc[512], make[64], model[64], model2[64], artist[64];
129 static float flash_used, canon_ev, iso_speed, shutter, aperture, focal_len;
130 static time_t timestamp;
131 static off_t strip_offset, data_offset;
132 static off_t thumb_offset, meta_offset, profile_offset;
133 static unsigned shot_order, kodak_cbpp, exif_cfa, unique_id;
134 static unsigned thumb_length, meta_length, profile_length;
135 static unsigned thumb_misc, *oprof, fuji_layout;
136 static unsigned tiff_nifds, tiff_samples, tiff_bps, tiff_compress;
137 static unsigned black, maximum, mix_green, raw_color, zero_is_bad;
138 static unsigned zero_after_ff, is_raw, dng_version, is_foveon, data_error;
139 static unsigned tile_width, tile_length, gpsdata[32], load_flags;
140 static unsigned flip, tiff_flip, filters, colors;
141 static ushort raw_height, raw_width, height, width, top_margin, left_margin;
142 static ushort shrink, iheight, iwidth, fuji_width, thumb_width, thumb_height;
143 static ushort *raw_image, (*image)[4], cblack[4102];
144 static ushort white[8][8], curve[0x10000], cr2_slice[3], sraw_mul[4];
146 static unsigned shot_select=0, multi_out=0;
147 static double pixel_aspect, aber[4]={1,1,1,1}, gamm[6]={ 0.45,4.5,0,0,0,0 };
148 static float bright=1, user_mul[4]={0,0,0,0}, threshold=0;
149 static int mask[8][4];
150 static int half_size=0, four_color_rgb=0, document_mode=0, highlight=0;
151 static int verbose=0, use_auto_wb=0, use_camera_wb=0, use_camera_matrix=1;
152 static int output_color=1, output_bps=8, output_tiff=0, med_passes=0;
153 static int no_auto_bright=0;
154 static unsigned greybox[4] = { 0, 0, UINT_MAX, UINT_MAX };
155 static float cam_mul[4], pre_mul[4], cmatrix[3][4], rgb_cam[3][4];
156 static const double xyz_rgb[3][3] = { /* XYZ from RGB */
157 { 0.412453, 0.357580, 0.180423 },
158 { 0.212671, 0.715160, 0.072169 },
159 { 0.019334, 0.119193, 0.950227 } };
160 static const float d65_white[3] = { 0.950456, 1, 1.088754 };
161 static int histogram[4][0x2000];
162 static void (*write_thumb)(), (*write_fun)();
163 static void (*load_raw)(), (*thumb_load_raw)();
164 static jmp_buf failure;
166 static struct decode {
167 struct decode *branch[2];
169 } first_decode[2048], /* *second_decode, CINELERRA */ *free_decode;
171 static struct tiff_ifd {
172 int width, height, bps, comp, phint, offset, flip, samples, bytes;
173 int tile_width, tile_length;
178 int format, key_off, tag_21a;
179 int black, split_col, black_col, split_row, black_row;
183 #define FORC(cnt) for (c=0; c < cnt; c++)
184 #define FORC3 FORC(3)
185 #define FORC4 FORC(4)
186 #define FORCC FORC(colors)
188 #define SQR(x) ((x)*(x))
189 #define ABS(x) (((int)(x) ^ ((int)(x) >> 31)) - ((int)(x) >> 31))
190 #define MIN(a,b) ((a) < (b) ? (a) : (b))
191 #define MAX(a,b) ((a) > (b) ? (a) : (b))
192 #define LIM(x,min,max) MAX(min,MIN(x,max))
193 #define ULIM(x,y,z) ((y) < (z) ? LIM(x,y,z) : LIM(x,z,y))
194 #define CLIP(x) LIM((int)(x),0,65535)
195 #define SWAP(a,b) { a=a+b; b=a-b; a=a-b; }
197 In order to inline this calculation, I make the risky
198 assumption that all filter patterns can be described
199 by a repeating pattern of eight rows and two columns
201 Do not use the FC or BAYER macros with the Leaf CatchLight,
202 because its pattern is 16x16, not 2x8.
204 Return values are either 0/1/2/3 = G/M/C/Y or 0/1/2/3 = R/G1/B/G2
206 PowerShot 600 PowerShot A50 PowerShot Pro70 Pro90 & G1
207 0xe1e4e1e4: 0x1b4e4b1e: 0x1e4b4e1b: 0xb4b4b4b4:
209 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5
210 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
211 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
212 2 M G M G M G 2 Y C Y C Y C 2 C Y C Y C Y
213 3 C Y C Y C Y 3 G M G M G M 3 G M G M G M
214 4 C Y C Y C Y 4 Y C Y C Y C
215 PowerShot A5 5 G M G M G M 5 G M G M G M
216 0x1e4e1e4e: 6 Y C Y C Y C 6 C Y C Y C Y
217 7 M G M G M G 7 M G M G M G
224 All RGB cameras use one of these Bayer grids:
226 0x16161616: 0x61616161: 0x49494949: 0x94949494:
228 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5
229 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
230 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
231 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
232 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
235 #define RAW(row,col) \
236 raw_image[(row)*raw_width+(col)]
238 #define FC(row,col) \
239 (filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)
241 #define BAYER(row,col) \
242 image[((row) >> shrink)*iwidth + ((col) >> shrink)][FC(row,col)]
244 #define BAYER2(row,col) \
245 image[((row) >> shrink)*iwidth + ((col) >> shrink)][fcol(row,col)]
247 int CLASS fcol (int row, int col)
249 static const char filter[16][16] =
250 { { 2,1,1,3,2,3,2,0,3,2,3,0,1,2,1,0 },
251 { 0,3,0,2,0,1,3,1,0,1,1,2,0,3,3,2 },
252 { 2,3,3,2,3,1,1,3,3,1,2,1,2,0,0,3 },
253 { 0,1,0,1,0,2,0,2,2,0,3,0,1,3,2,1 },
254 { 3,1,1,2,0,1,0,2,1,3,1,3,0,1,3,0 },
255 { 2,0,0,3,3,2,3,1,2,0,2,0,3,2,2,1 },
256 { 2,3,3,1,2,1,2,1,2,1,1,2,3,0,0,1 },
257 { 1,0,0,2,3,0,0,3,0,3,0,3,2,1,2,3 },
258 { 2,3,3,1,1,2,1,0,3,2,3,0,2,3,1,3 },
259 { 1,0,2,0,3,0,3,2,0,1,1,2,0,1,0,2 },
260 { 0,1,1,3,3,2,2,1,1,3,3,0,2,1,3,2 },
261 { 2,3,2,0,0,1,3,0,2,0,1,2,3,0,1,0 },
262 { 1,3,1,2,3,2,3,2,0,2,0,1,1,0,3,0 },
263 { 0,2,0,3,1,0,0,1,1,3,3,2,3,2,2,1 },
264 { 2,1,3,2,3,1,2,1,0,3,0,2,0,2,0,2 },
265 { 0,3,1,0,0,2,0,3,2,1,3,1,1,3,1,3 } };
267 if (filters == 1) return filter[(row+top_margin)&15][(col+left_margin)&15];
268 if (filters == 9) return xtrans[(row+6) % 6][(col+6) % 6];
276 #define ZERO(var) memset(&var, 0, sizeof var);
326 memset(pre_mul, 0, sizeof pre_mul);
333 memset(rgb_cam, 0, sizeof rgb_cam);
362 aber[0] = aber[1] = aber[2] = aber[3] = 1;
363 gamm[0] = 0.45; gamm[1] = 4.5; gamm[2] = 0;
364 gamm[3] = 0; gamm[4] = 0; gamm[5] = 0;
375 use_camera_matrix = 1;
381 greybox[0] = 0; greybox[1] = 0;
382 greybox[2] = UINT_MAX; greybox[3] = UINT_MAX;
386 char *my_memmem (char *haystack, size_t haystacklen,
387 char *needle, size_t needlelen)
390 for (c = haystack; c <= haystack + haystacklen - needlelen; c++)
391 if (!memcmp (c, needle, needlelen))
395 #define memmem my_memmem
396 char *my_strcasestr (char *haystack, const char *needle)
399 for (c = haystack; *c; c++)
400 if (!strncasecmp(c, needle, strlen(needle)))
404 #define strcasestr my_strcasestr
407 void CLASS merror (void *ptr, const char *where)
410 fprintf (stderr,_("%s: Out of memory in %s\n"), ifname, where);
411 longjmp (failure, 1);
417 fprintf (stderr, "%s: ", ifname);
419 fprintf (stderr,_("Unexpected end of file\n"));
421 fprintf (stderr,_("Corrupt data near 0x%llx\n"), (INT64) ftello(ifp));
426 ushort CLASS sget2 (uchar *s)
428 if (order == 0x4949) /* "II" means little-endian */
429 return s[0] | s[1] << 8;
430 else /* "MM" means big-endian */
431 return s[0] << 8 | s[1];
436 uchar str[2] = { 0xff,0xff };
437 fread (str, 1, 2, ifp);
441 unsigned CLASS sget4 (uchar *s)
444 return s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24;
446 return s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3];
448 #define sget4(s) sget4((uchar *)s)
450 unsigned CLASS get4()
452 uchar str[4] = { 0xff,0xff,0xff,0xff };
453 fread (str, 1, 4, ifp);
457 unsigned CLASS getint (int type)
459 return type == 3 ? get2() : get4();
462 float CLASS int_to_float (int i)
464 union { int i; float f; } u;
469 double CLASS getreal (int type)
471 union { char c[8]; double d; } u;
475 case 3: return (unsigned short) get2();
476 case 4: return (unsigned int) get4();
477 case 5: u.d = (unsigned int) get4();
478 return u.d / (unsigned int) get4();
479 case 8: return (signed short) get2();
480 case 9: return (signed int) get4();
481 case 10: u.d = (signed int) get4();
482 return u.d / (signed int) get4();
483 case 11: return int_to_float (get4());
485 rev = 7 * ((order == 0x4949) == (ntohs(0x1234) == 0x1234));
486 for (i=0; i < 8; i++)
487 u.c[i ^ rev] = fgetc(ifp);
489 default: return fgetc(ifp);
493 void CLASS read_shorts (ushort *pixel, int count)
495 if (fread (pixel, 2, count, ifp) < count) derror();
496 if ((order == 0x4949) == (ntohs(0x1234) == 0x1234))
497 swab (pixel, pixel, count*2);
500 void CLASS cubic_spline (const int *x_, const int *y_, const int len)
502 float **A, *b, *c, *d, *x, *y;
505 A = (float **) calloc (((2*len + 4)*sizeof **A + sizeof *A), 2*len);
507 A[0] = (float *) (A + 2*len);
508 for (i = 1; i < 2*len; i++)
509 A[i] = A[0] + 2*len*i;
510 y = len + (x = i + (d = i + (c = i + (b = A[0] + i*i))));
511 for (i = 0; i < len; i++) {
512 x[i] = x_[i] / 65535.0;
513 y[i] = y_[i] / 65535.0;
515 for (i = len-1; i > 0; i--) {
516 b[i] = (y[i] - y[i-1]) / (x[i] - x[i-1]);
517 d[i-1] = x[i] - x[i-1];
519 for (i = 1; i < len-1; i++) {
520 A[i][i] = 2 * (d[i-1] + d[i]);
525 A[i][len-1] = 6 * (b[i+1] - b[i]);
527 for(i = 1; i < len-2; i++) {
528 float v = A[i+1][i] / A[i][i];
529 for(j = 1; j <= len-1; j++)
530 A[i+1][j] -= v * A[i][j];
532 for(i = len-2; i > 0; i--) {
534 for(j = i; j <= len-2; j++)
536 c[i] = (A[i][len-1] - acc) / A[i][i];
538 for (i = 0; i < 0x10000; i++) {
539 float x_out = (float)(i / 65535.0);
541 for (j = 0; j < len-1; j++) {
542 if (x[j] <= x_out && x_out <= x[j+1]) {
543 float v = x_out - x[j];
545 ((y[j+1] - y[j]) / d[j] - (2 * d[j] * c[j] + c[j+1] * d[j])/6) * v
546 + (c[j] * 0.5) * v*v + ((c[j+1] - c[j]) / (6 * d[j])) * v*v*v;
549 curve[i] = y_out < 0.0 ? 0 : (y_out >= 1.0 ? 65535 :
550 (ushort)(y_out * 65535.0 + 0.5));
555 void CLASS canon_600_fixed_wb (int temp)
557 static const short mul[4][5] = {
558 { 667, 358,397,565,452 },
559 { 731, 390,367,499,517 },
560 { 1119, 396,348,448,537 },
561 { 1399, 485,431,508,688 } };
566 if (*mul[lo] <= temp) break;
567 for (hi=0; hi < 3; hi++)
568 if (*mul[hi] >= temp) break;
570 frac = (float) (temp - *mul[lo]) / (*mul[hi] - *mul[lo]);
571 for (i=1; i < 5; i++)
572 pre_mul[i-1] = 1 / (frac * mul[hi][i] + (1-frac) * mul[lo][i]);
575 /* Return values: 0 = white 1 = near white 2 = not white */
576 int CLASS canon_600_color (int ratio[2], int mar)
578 int clipped=0, target, miss;
582 { ratio[1] = -104; clipped = 1; }
584 { ratio[1] = 12; clipped = 1; }
586 if (ratio[1] < -264 || ratio[1] > 461) return 2;
588 { ratio[1] = -50; clipped = 1; }
590 { ratio[1] = 307; clipped = 1; }
592 target = flash_used || ratio[1] < 197
593 ? -38 - (398 * ratio[1] >> 10)
594 : -123 + (48 * ratio[1] >> 10);
595 if (target - mar <= ratio[0] &&
596 target + 20 >= ratio[0] && !clipped) return 0;
597 miss = target - ratio[0];
598 if (abs(miss) >= mar*4) return 2;
599 if (miss < -20) miss = -20;
600 if (miss > mar) miss = mar;
601 ratio[0] = target - miss;
605 void CLASS canon_600_auto_wb()
607 int mar, row, col, i, j, st, count[] = { 0,0 };
608 int test[8], total[2][8], ratio[2][2], stat[2];
610 memset (&total, 0, sizeof total);
612 if (i < 10) mar = 150;
613 else if (i > 12) mar = 20;
614 else mar = 280 - 20 * i;
615 if (flash_used) mar = 80;
616 for (row=14; row < height-14; row+=4)
617 for (col=10; col < width; col+=2) {
618 for (i=0; i < 8; i++)
619 test[(i & 4) + FC(row+(i >> 1),col+(i & 1))] =
620 BAYER(row+(i >> 1),col+(i & 1));
621 for (i=0; i < 8; i++)
622 if (test[i] < 150 || test[i] > 1500) goto next;
623 for (i=0; i < 4; i++)
624 if (abs(test[i] - test[i+4]) > 50) goto next;
625 for (i=0; i < 2; i++) {
626 for (j=0; j < 4; j+=2)
627 ratio[i][j >> 1] = ((test[i*4+j+1]-test[i*4+j]) << 10) / test[i*4+j];
628 stat[i] = canon_600_color (ratio[i], mar);
630 if ((st = stat[0] | stat[1]) > 1) goto next;
631 for (i=0; i < 2; i++)
633 for (j=0; j < 2; j++)
634 test[i*4+j*2+1] = test[i*4+j*2] * (0x400 + ratio[i][j]) >> 10;
635 for (i=0; i < 8; i++)
636 total[st][i] += test[i];
640 if (count[0] | count[1]) {
641 st = count[0]*200 < count[1];
642 for (i=0; i < 4; i++)
643 pre_mul[i] = 1.0 / (total[st][i] + total[st][i+4]);
647 void CLASS canon_600_coeff()
649 static const short table[6][12] = {
650 { -190,702,-1878,2390, 1861,-1349,905,-393, -432,944,2617,-2105 },
651 { -1203,1715,-1136,1648, 1388,-876,267,245, -1641,2153,3921,-3409 },
652 { -615,1127,-1563,2075, 1437,-925,509,3, -756,1268,2519,-2007 },
653 { -190,702,-1886,2398, 2153,-1641,763,-251, -452,964,3040,-2528 },
654 { -190,702,-1878,2390, 1861,-1349,905,-393, -432,944,2617,-2105 },
655 { -807,1319,-1785,2297, 1388,-876,769,-257, -230,742,2067,-1555 } };
659 mc = pre_mul[1] / pre_mul[2];
660 yc = pre_mul[3] / pre_mul[2];
661 if (mc > 1 && mc <= 1.28 && yc < 0.8789) t=1;
662 if (mc > 1.28 && mc <= 2) {
663 if (yc < 0.8789) t=3;
664 else if (yc <= 2) t=4;
667 for (raw_color = i=0; i < 3; i++)
668 FORCC rgb_cam[i][c] = table[t][i*4 + c] / 1024.0;
671 void CLASS canon_600_load_raw()
673 uchar data[1120], *dp;
677 for (irow=row=0; irow < height; irow++) {
678 if (fread (data, 1, 1120, ifp) < 1120) derror();
679 pix = raw_image + row*raw_width;
680 for (dp=data; dp < data+1120; dp+=10, pix+=8) {
681 pix[0] = (dp[0] << 2) + (dp[1] >> 6 );
682 pix[1] = (dp[2] << 2) + (dp[1] >> 4 & 3);
683 pix[2] = (dp[3] << 2) + (dp[1] >> 2 & 3);
684 pix[3] = (dp[4] << 2) + (dp[1] & 3);
685 pix[4] = (dp[5] << 2) + (dp[9] & 3);
686 pix[5] = (dp[6] << 2) + (dp[9] >> 2 & 3);
687 pix[6] = (dp[7] << 2) + (dp[9] >> 4 & 3);
688 pix[7] = (dp[8] << 2) + (dp[9] >> 6 );
690 if ((row+=2) > height) row = 1;
694 void CLASS canon_600_correct()
697 static const short mul[4][2] =
698 { { 1141,1145 }, { 1128,1109 }, { 1178,1149 }, { 1128,1109 } };
700 for (row=0; row < height; row++)
701 for (col=0; col < width; col++) {
702 if ((val = BAYER(row,col) - black) < 0) val = 0;
703 val = val * mul[row & 3][col & 1] >> 9;
704 BAYER(row,col) = val;
706 canon_600_fixed_wb(1311);
709 maximum = (0x3ff - black) * 1109 >> 9;
713 int CLASS canon_s2is()
717 for (row=0; row < 100; row++) {
718 fseek (ifp, row*3340 + 3284, SEEK_SET);
719 if (getc(ifp) > 15) return 1;
724 unsigned CLASS getbithuff (int nbits, ushort *huff)
726 static unsigned bitbuf=0;
727 static int vbits=0, reset=0;
730 if (nbits > 25) return 0;
732 return bitbuf = vbits = reset = 0;
733 if (nbits == 0 || vbits < 0) return 0;
734 while (!reset && vbits < nbits && (c = fgetc(ifp)) != EOF &&
735 !(reset = zero_after_ff && c == 0xff && fgetc(ifp))) {
736 bitbuf = (bitbuf << 8) + (uchar) c;
739 c = bitbuf << (32-vbits) >> (32-nbits);
741 vbits -= huff[c] >> 8;
745 if (vbits < 0) derror();
749 #define getbits(n) getbithuff(n,0)
750 #define gethuff(h) getbithuff(*h,h+1)
753 Construct a decode tree according the specification in *source.
754 The first 16 bytes specify how many codes should be 1-bit, 2-bit
755 3-bit, etc. Bytes after that are the leaf values.
757 For example, if the source is
759 { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0,
760 0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff },
778 ushort * CLASS make_decoder_ref (const uchar **source)
780 int max, len, h, i, j;
784 count = (*source += 16) - 17;
785 for (max=16; max && !count[max]; max--);
786 huff = (ushort *) calloc (1 + (1 << max), sizeof *huff);
787 merror (huff, "make_decoder()");
789 for (h=len=1; len <= max; len++)
790 for (i=0; i < count[len]; i++, ++*source)
791 for (j=0; j < 1 << (max-len); j++)
793 huff[h++] = len << 8 | **source;
797 ushort * CLASS make_decoder (const uchar *source)
799 return make_decoder_ref (&source);
802 void CLASS crw_init_tables (unsigned table, ushort *huff[2])
804 static const uchar first_tree[3][29] = {
805 { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0,
806 0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff },
807 { 0,2,2,3,1,1,1,1,2,0,0,0,0,0,0,0,
808 0x03,0x02,0x04,0x01,0x05,0x00,0x06,0x07,0x09,0x08,0x0a,0x0b,0xff },
809 { 0,0,6,3,1,1,2,0,0,0,0,0,0,0,0,0,
810 0x06,0x05,0x07,0x04,0x08,0x03,0x09,0x02,0x00,0x0a,0x01,0x0b,0xff },
812 static const uchar second_tree[3][180] = {
813 { 0,2,2,2,1,4,2,1,2,5,1,1,0,0,0,139,
814 0x03,0x04,0x02,0x05,0x01,0x06,0x07,0x08,
815 0x12,0x13,0x11,0x14,0x09,0x15,0x22,0x00,0x21,0x16,0x0a,0xf0,
816 0x23,0x17,0x24,0x31,0x32,0x18,0x19,0x33,0x25,0x41,0x34,0x42,
817 0x35,0x51,0x36,0x37,0x38,0x29,0x79,0x26,0x1a,0x39,0x56,0x57,
818 0x28,0x27,0x52,0x55,0x58,0x43,0x76,0x59,0x77,0x54,0x61,0xf9,
819 0x71,0x78,0x75,0x96,0x97,0x49,0xb7,0x53,0xd7,0x74,0xb6,0x98,
820 0x47,0x48,0x95,0x69,0x99,0x91,0xfa,0xb8,0x68,0xb5,0xb9,0xd6,
821 0xf7,0xd8,0x67,0x46,0x45,0x94,0x89,0xf8,0x81,0xd5,0xf6,0xb4,
822 0x88,0xb1,0x2a,0x44,0x72,0xd9,0x87,0x66,0xd4,0xf5,0x3a,0xa7,
823 0x73,0xa9,0xa8,0x86,0x62,0xc7,0x65,0xc8,0xc9,0xa1,0xf4,0xd1,
824 0xe9,0x5a,0x92,0x85,0xa6,0xe7,0x93,0xe8,0xc1,0xc6,0x7a,0x64,
825 0xe1,0x4a,0x6a,0xe6,0xb3,0xf1,0xd3,0xa5,0x8a,0xb2,0x9a,0xba,
826 0x84,0xa4,0x63,0xe5,0xc5,0xf3,0xd2,0xc4,0x82,0xaa,0xda,0xe4,
827 0xf2,0xca,0x83,0xa3,0xa2,0xc3,0xea,0xc2,0xe2,0xe3,0xff,0xff },
828 { 0,2,2,1,4,1,4,1,3,3,1,0,0,0,0,140,
829 0x02,0x03,0x01,0x04,0x05,0x12,0x11,0x06,
830 0x13,0x07,0x08,0x14,0x22,0x09,0x21,0x00,0x23,0x15,0x31,0x32,
831 0x0a,0x16,0xf0,0x24,0x33,0x41,0x42,0x19,0x17,0x25,0x18,0x51,
832 0x34,0x43,0x52,0x29,0x35,0x61,0x39,0x71,0x62,0x36,0x53,0x26,
833 0x38,0x1a,0x37,0x81,0x27,0x91,0x79,0x55,0x45,0x28,0x72,0x59,
834 0xa1,0xb1,0x44,0x69,0x54,0x58,0xd1,0xfa,0x57,0xe1,0xf1,0xb9,
835 0x49,0x47,0x63,0x6a,0xf9,0x56,0x46,0xa8,0x2a,0x4a,0x78,0x99,
836 0x3a,0x75,0x74,0x86,0x65,0xc1,0x76,0xb6,0x96,0xd6,0x89,0x85,
837 0xc9,0xf5,0x95,0xb4,0xc7,0xf7,0x8a,0x97,0xb8,0x73,0xb7,0xd8,
838 0xd9,0x87,0xa7,0x7a,0x48,0x82,0x84,0xea,0xf4,0xa6,0xc5,0x5a,
839 0x94,0xa4,0xc6,0x92,0xc3,0x68,0xb5,0xc8,0xe4,0xe5,0xe6,0xe9,
840 0xa2,0xa3,0xe3,0xc2,0x66,0x67,0x93,0xaa,0xd4,0xd5,0xe7,0xf8,
841 0x88,0x9a,0xd7,0x77,0xc4,0x64,0xe2,0x98,0xa5,0xca,0xda,0xe8,
842 0xf3,0xf6,0xa9,0xb2,0xb3,0xf2,0xd2,0x83,0xba,0xd3,0xff,0xff },
843 { 0,0,6,2,1,3,3,2,5,1,2,2,8,10,0,117,
844 0x04,0x05,0x03,0x06,0x02,0x07,0x01,0x08,
845 0x09,0x12,0x13,0x14,0x11,0x15,0x0a,0x16,0x17,0xf0,0x00,0x22,
846 0x21,0x18,0x23,0x19,0x24,0x32,0x31,0x25,0x33,0x38,0x37,0x34,
847 0x35,0x36,0x39,0x79,0x57,0x58,0x59,0x28,0x56,0x78,0x27,0x41,
848 0x29,0x77,0x26,0x42,0x76,0x99,0x1a,0x55,0x98,0x97,0xf9,0x48,
849 0x54,0x96,0x89,0x47,0xb7,0x49,0xfa,0x75,0x68,0xb6,0x67,0x69,
850 0xb9,0xb8,0xd8,0x52,0xd7,0x88,0xb5,0x74,0x51,0x46,0xd9,0xf8,
851 0x3a,0xd6,0x87,0x45,0x7a,0x95,0xd5,0xf6,0x86,0xb4,0xa9,0x94,
852 0x53,0x2a,0xa8,0x43,0xf5,0xf7,0xd4,0x66,0xa7,0x5a,0x44,0x8a,
853 0xc9,0xe8,0xc8,0xe7,0x9a,0x6a,0x73,0x4a,0x61,0xc7,0xf4,0xc6,
854 0x65,0xe9,0x72,0xe6,0x71,0x91,0x93,0xa6,0xda,0x92,0x85,0x62,
855 0xf3,0xc5,0xb2,0xa4,0x84,0xba,0x64,0xa5,0xb3,0xd2,0x81,0xe5,
856 0xd3,0xaa,0xc4,0xca,0xf2,0xb1,0xe4,0xd1,0x83,0x63,0xea,0xc3,
857 0xe2,0x82,0xf1,0xa3,0xc2,0xa1,0xc1,0xe3,0xa2,0xe1,0xff,0xff }
859 if (table > 2) table = 2;
860 huff[0] = make_decoder ( first_tree[table]);
861 huff[1] = make_decoder (second_tree[table]);
865 Return 0 if the image starts with compressed data,
866 1 if it starts with uncompressed low-order bits.
868 In Canon compressed data, 0xff is always followed by 0x00.
870 int CLASS canon_has_lowbits()
875 fseek (ifp, 0, SEEK_SET);
876 fread (test, 1, sizeof test, ifp);
877 for (i=540; i < sizeof test - 1; i++)
878 if (test[i] == 0xff) {
879 if (test[i+1]) return 1;
885 void CLASS canon_load_raw()
887 ushort *pixel, *prow, *huff[2];
888 int nblocks, lowbits, i, c, row, r, save, val;
889 int block, diffbuf[64], leaf, len, diff, carry=0, pnum=0, base[2];
891 crw_init_tables (tiff_compress, huff);
892 lowbits = canon_has_lowbits();
893 if (!lowbits) maximum = 0x3ff;
894 fseek (ifp, 540 + lowbits*raw_height*raw_width/4, SEEK_SET);
897 for (row=0; row < raw_height; row+=8) {
898 pixel = raw_image + row*raw_width;
899 nblocks = MIN (8, raw_height-row) * raw_width >> 6;
900 for (block=0; block < nblocks; block++) {
901 memset (diffbuf, 0, sizeof diffbuf);
902 for (i=0; i < 64; i++ ) {
903 leaf = gethuff(huff[i > 0]);
904 if (leaf == 0 && i) break;
905 if (leaf == 0xff) continue;
908 if (len == 0) continue;
910 if ((diff & (1 << (len-1))) == 0)
911 diff -= (1 << len) - 1;
912 if (i < 64) diffbuf[i] = diff;
916 for (i=0; i < 64; i++ ) {
917 if (pnum++ % raw_width == 0)
918 base[0] = base[1] = 512;
919 if ((pixel[(block << 6) + i] = base[i & 1] += diffbuf[i]) >> 10)
925 fseek (ifp, 26 + row*raw_width/4, SEEK_SET);
926 for (prow=pixel, i=0; i < raw_width*2; i++) {
928 for (r=0; r < 8; r+=2, prow++) {
929 val = (*prow << 2) + ((c >> r) & 3);
930 if (raw_width == 2672 && val < 512) val += 2;
934 fseek (ifp, save, SEEK_SET);
937 FORC(2) free (huff[c]);
941 int algo, bits, high, wide, clrs, sraw, psv, restart, vpred[6];
942 ushort quant[64], idct[64], *huff[20], *free[20], *row;
945 int CLASS ljpeg_start (struct jhead *jh, int info_only)
951 memset (jh, 0, sizeof *jh);
952 jh->restart = INT_MAX;
953 if ((fgetc(ifp),fgetc(ifp)) != 0xd8) return 0;
955 if (!fread (data, 2, 2, ifp)) return 0;
956 tag = data[0] << 8 | data[1];
957 len = (data[2] << 8 | data[3]) - 2;
958 if (tag <= 0xff00) return 0;
959 fread (data, 1, len, ifp);
962 jh->sraw = ((data[7] >> 4) * (data[7] & 15) - 1) & 3;
965 jh->algo = tag & 0xff;
967 jh->high = data[1] << 8 | data[2];
968 jh->wide = data[3] << 8 | data[4];
969 jh->clrs = data[5] + jh->sraw;
970 if (len == 9 && !dng_version) getc(ifp);
973 if (info_only) break;
974 for (dp = data; dp < data+len && !((c = *dp++) & -20); )
975 jh->free[c] = jh->huff[c] = make_decoder_ref (&dp);
978 jh->psv = data[1+data[0]*2];
979 jh->bits -= data[3+data[0]*2] & 15;
982 FORC(64) jh->quant[c] = data[c*2+1] << 8 | data[c*2+2];
985 jh->restart = data[0] << 8 | data[1];
987 } while (tag != 0xffda);
988 if (jh->bits > 16 || jh->clrs > 6 ||
989 !jh->bits || !jh->high || !jh->wide || !jh->clrs) return 0;
990 if (info_only) return 1;
991 if (!jh->huff[0]) return 0;
992 FORC(19) if (!jh->huff[c+1]) jh->huff[c+1] = jh->huff[c];
994 FORC(4) jh->huff[2+c] = jh->huff[1];
995 FORC(jh->sraw) jh->huff[1+c] = jh->huff[0];
997 jh->row = (ushort *) calloc (jh->wide*jh->clrs, 4);
998 merror (jh->row, "ljpeg_start()");
999 return zero_after_ff = 1;
1002 void CLASS ljpeg_end (struct jhead *jh)
1005 FORC4 if (jh->free[c]) free (jh->free[c]);
1009 int CLASS ljpeg_diff (ushort *huff)
1013 len = gethuff(huff);
1014 if (len == 16 && (!dng_version || dng_version >= 0x1010000))
1016 diff = getbits(len);
1017 if ((diff & (1 << (len-1))) == 0)
1018 diff -= (1 << len) - 1;
1022 ushort * CLASS ljpeg_row (int jrow, struct jhead *jh)
1024 int col, c, diff, pred, spred=0;
1025 ushort mark=0, *row[3];
1027 if (jrow * jh->wide % jh->restart == 0) {
1028 FORC(6) jh->vpred[c] = 1 << (jh->bits-1);
1030 fseek (ifp, -2, SEEK_CUR);
1031 do mark = (mark << 8) + (c = fgetc(ifp));
1032 while (c != EOF && mark >> 4 != 0xffd);
1036 FORC3 row[c] = jh->row + jh->wide*jh->clrs*((jrow+c) & 1);
1037 for (col=0; col < jh->wide; col++)
1039 diff = ljpeg_diff (jh->huff[c]);
1040 if (jh->sraw && c <= jh->sraw && (col | c))
1042 else if (col) pred = row[0][-jh->clrs];
1043 else pred = (jh->vpred[c] += diff) - diff;
1044 if (jrow && col) switch (jh->psv) {
1046 case 2: pred = row[1][0]; break;
1047 case 3: pred = row[1][-jh->clrs]; break;
1048 case 4: pred = pred + row[1][0] - row[1][-jh->clrs]; break;
1049 case 5: pred = pred + ((row[1][0] - row[1][-jh->clrs]) >> 1); break;
1050 case 6: pred = row[1][0] + ((pred - row[1][-jh->clrs]) >> 1); break;
1051 case 7: pred = (pred + row[1][0]) >> 1; break;
1054 if ((**row = pred + diff) >> jh->bits) derror();
1055 if (c <= jh->sraw) spred = **row;
1061 void CLASS lossless_jpeg_load_raw()
1063 int jwide, jrow, jcol, val, jidx, i, j, row=0, col=0;
1067 if (!ljpeg_start (&jh, 0)) return;
1068 jwide = jh.wide * jh.clrs;
1070 for (jrow=0; jrow < jh.high; jrow++) {
1071 rp = ljpeg_row (jrow, &jh);
1073 row = jrow & 1 ? height-1-jrow/2 : jrow/2;
1074 for (jcol=0; jcol < jwide; jcol++) {
1077 jidx = jrow*jwide + jcol;
1078 i = jidx / (cr2_slice[1]*raw_height);
1079 if ((j = i >= cr2_slice[0]))
1081 jidx -= i * (cr2_slice[1]*raw_height);
1082 row = jidx / cr2_slice[1+j];
1083 col = jidx % cr2_slice[1+j] + i*cr2_slice[1];
1085 if (raw_width == 3984 && (col -= 2) < 0)
1086 col += (row--,raw_width);
1087 if ((unsigned) row < raw_height) RAW(row,col) = val;
1088 if (++col >= raw_width)
1095 void CLASS canon_sraw_load_raw()
1098 short *rp=0, (*ip)[4];
1099 int jwide, slice, scol, ecol, row, col, jrow=0, jcol=0, pix[3], c;
1100 int v[3]={0,0,0}, ver, hue;
1103 if (!ljpeg_start (&jh, 0) || jh.clrs < 4) return;
1104 jwide = (jh.wide >>= 1) * jh.clrs;
1106 for (ecol=slice=0; slice <= cr2_slice[0]; slice++) {
1108 ecol += cr2_slice[1] * 2 / jh.clrs;
1109 if (!cr2_slice[0] || ecol > raw_width-1) ecol = raw_width & -2;
1110 for (row=0; row < height; row += (jh.clrs >> 1) - 1) {
1111 ip = (short (*)[4]) image + row*width;
1112 for (col=scol; col < ecol; col+=2, jcol+=jh.clrs) {
1113 if ((jcol %= jwide) == 0)
1114 rp = (short *) ljpeg_row (jrow++, &jh);
1115 if (col >= width) continue;
1117 ip[col + (c >> 1)*width + (c & 1)][0] = rp[jcol+c];
1118 ip[col][1] = rp[jcol+jh.clrs-2] - 16384;
1119 ip[col][2] = rp[jcol+jh.clrs-1] - 16384;
1123 for (cp=model2; *cp && !isdigit(*cp); cp++);
1124 sscanf (cp, "%d.%d.%d", v, v+1, v+2);
1125 ver = (v[0]*1000 + v[1])*1000 + v[2];
1126 hue = (jh.sraw+1) << 2;
1127 if (unique_id >= 0x80000281 || (unique_id == 0x80000218 && ver > 1000006))
1129 ip = (short (*)[4]) image;
1131 for (row=0; row < height; row++, ip+=width) {
1132 if (row & (jh.sraw >> 1)) { //CINELERRA
1133 for (col=0; col < width; col+=2)
1134 for (c=1; c < 3; c++)
1135 if (row == height-1)
1136 ip[col][c] = ip[col-width][c];
1137 else ip[col][c] = (ip[col-width][c] + ip[col+width][c] + 1) >> 1;
1139 for (col=1; col < width; col+=2)
1140 for (c=1; c < 3; c++)
1142 ip[col][c] = ip[col-1][c];
1143 else ip[col][c] = (ip[col-1][c] + ip[col+1][c] + 1) >> 1;
1145 for ( ; rp < ip[0]; rp+=4) {
1146 if (unique_id == 0x80000218 ||
1147 unique_id == 0x80000250 ||
1148 unique_id == 0x80000261 ||
1149 unique_id == 0x80000281 ||
1150 unique_id == 0x80000287) {
1151 rp[1] = (rp[1] << 2) + hue;
1152 rp[2] = (rp[2] << 2) + hue;
1153 pix[0] = rp[0] + (( 50*rp[1] + 22929*rp[2]) >> 14);
1154 pix[1] = rp[0] + ((-5640*rp[1] - 11751*rp[2]) >> 14);
1155 pix[2] = rp[0] + ((29040*rp[1] - 101*rp[2]) >> 14);
1157 if (unique_id < 0x80000218) rp[0] -= 512;
1158 pix[0] = rp[0] + rp[2];
1159 pix[2] = rp[0] + rp[1];
1160 pix[1] = rp[0] + ((-778*rp[1] - (rp[2] << 11)) >> 12);
1162 FORC3 rp[c] = CLIP(pix[c] * sraw_mul[c] >> 10);
1168 void CLASS adobe_copy_pixel (unsigned row, unsigned col, ushort **rp)
1172 if (tiff_samples == 2 && shot_select) (*rp)++;
1174 if (row < raw_height && col < raw_width)
1175 RAW(row,col) = curve[**rp];
1176 *rp += tiff_samples;
1178 if (row < height && col < width)
1180 image[row*width+col][c] = curve[(*rp)[c]];
1181 *rp += tiff_samples;
1183 if (tiff_samples == 2 && shot_select) (*rp)--;
1186 void CLASS ljpeg_idct (struct jhead *jh)
1188 int c, i, j, len, skip, coef;
1189 float work[3][8][8];
1190 static float cs[106] = { 0 };
1191 static const uchar zigzag[80] =
1192 { 0, 1, 8,16, 9, 2, 3,10,17,24,32,25,18,11, 4, 5,12,19,26,33,
1193 40,48,41,34,27,20,13, 6, 7,14,21,28,35,42,49,56,57,50,43,36,
1194 29,22,15,23,30,37,44,51,58,59,52,45,38,31,39,46,53,60,61,54,
1195 47,55,62,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63 };
1198 FORC(106) cs[c] = cos((c & 31)*M_PI/16)/2;
1199 memset (work, 0, sizeof work);
1200 work[0][0][0] = jh->vpred[0] += ljpeg_diff (jh->huff[0]) * jh->quant[0];
1201 for (i=1; i < 64; i++ ) {
1202 len = gethuff (jh->huff[16]);
1203 i += skip = len >> 4;
1204 if (!(len &= 15) && skip < 15) break;
1205 coef = getbits(len);
1206 if ((coef & (1 << (len-1))) == 0)
1207 coef -= (1 << len) - 1;
1208 ((float *)work)[zigzag[i]] = coef * jh->quant[i];
1210 FORC(8) work[0][0][c] *= M_SQRT1_2;
1211 FORC(8) work[0][c][0] *= M_SQRT1_2;
1212 for (i=0; i < 8; i++)
1213 for (j=0; j < 8; j++)
1214 FORC(8) work[1][i][j] += work[0][i][c] * cs[(j*2+1)*c];
1215 for (i=0; i < 8; i++)
1216 for (j=0; j < 8; j++)
1217 FORC(8) work[2][i][j] += work[1][c][j] * cs[(i*2+1)*c];
1219 FORC(64) jh->idct[c] = CLIP(((float *)work[2])[c]+0.5);
1222 void CLASS lossless_dng_load_raw()
1224 unsigned save, trow=0, tcol=0, jwide, jrow, jcol, row, col, i, j;
1228 while (trow < raw_height) {
1230 if (tile_length < INT_MAX)
1231 fseek (ifp, get4(), SEEK_SET);
1232 if (!ljpeg_start (&jh, 0)) break;
1234 if (filters) jwide *= jh.clrs;
1235 jwide /= MIN (is_raw, tiff_samples);
1238 jh.vpred[0] = 16384;
1240 for (jrow=0; jrow+7 < jh.high; jrow += 8) {
1241 for (jcol=0; jcol+7 < jh.wide; jcol += 8) {
1244 row = trow + jcol/tile_width + jrow*2;
1245 col = tcol + jcol%tile_width;
1246 for (i=0; i < 16; i+=2)
1247 for (j=0; j < 8; j++)
1248 adobe_copy_pixel (row+i, col+j, &rp);
1253 for (row=col=jrow=0; jrow < jh.high; jrow++) {
1254 rp = ljpeg_row (jrow, &jh);
1255 for (jcol=0; jcol < jwide; jcol++) {
1256 adobe_copy_pixel (trow+row, tcol+col, &rp);
1257 if (++col >= tile_width || col >= raw_width)
1258 row += 1 + (col = 0);
1262 fseek (ifp, save+4, SEEK_SET);
1263 if ((tcol += tile_width) >= raw_width)
1264 trow += tile_length + (tcol = 0);
1269 void CLASS packed_dng_load_raw()
1274 pixel = (ushort *) calloc (raw_width, tiff_samples*sizeof *pixel);
1275 merror (pixel, "packed_dng_load_raw()");
1276 for (row=0; row < raw_height; row++) {
1278 read_shorts (pixel, raw_width * tiff_samples);
1281 for (col=0; col < raw_width * tiff_samples; col++)
1282 pixel[col] = getbits(tiff_bps);
1284 for (rp=pixel, col=0; col < raw_width; col++)
1285 adobe_copy_pixel (row, col, &rp);
1290 void CLASS pentax_load_raw()
1292 ushort bit[2][15], huff[4097];
1293 int dep, row, col, diff, c, i;
1294 ushort vpred[2][2] = {{0,0},{0,0}}, hpred[2];
1296 fseek (ifp, meta_offset, SEEK_SET);
1297 dep = (get2() + 12) & 15;
1298 fseek (ifp, 12, SEEK_CUR);
1299 FORC(dep) bit[0][c] = get2();
1300 FORC(dep) bit[1][c] = fgetc(ifp);
1302 for (i=bit[0][c]; i <= ((bit[0][c]+(4096 >> bit[1][c])-1) & 4095); )
1303 huff[++i] = bit[1][c] << 8 | c;
1305 fseek (ifp, data_offset, SEEK_SET);
1307 for (row=0; row < raw_height; row++)
1308 for (col=0; col < raw_width; col++) {
1309 diff = ljpeg_diff (huff);
1310 if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
1311 else hpred[col & 1] += diff;
1312 RAW(row,col) = hpred[col & 1];
1313 if (hpred[col & 1] >> tiff_bps) derror();
1317 void CLASS nikon_load_raw()
1319 static const uchar nikon_tree[][32] = {
1320 { 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0, /* 12-bit lossy */
1321 5,4,3,6,2,7,1,0,8,9,11,10,12 },
1322 { 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0, /* 12-bit lossy after split */
1323 0x39,0x5a,0x38,0x27,0x16,5,4,3,2,1,0,11,12,12 },
1324 { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0, /* 12-bit lossless */
1325 5,4,6,3,7,2,8,1,9,0,10,11,12 },
1326 { 0,1,4,3,1,1,1,1,1,2,0,0,0,0,0,0, /* 14-bit lossy */
1327 5,6,4,7,8,3,9,2,1,0,10,11,12,13,14 },
1328 { 0,1,5,1,1,1,1,1,1,1,2,0,0,0,0,0, /* 14-bit lossy after split */
1329 8,0x5c,0x4b,0x3a,0x29,7,6,5,4,3,2,1,0,13,14 },
1330 { 0,1,4,2,2,3,1,2,0,0,0,0,0,0,0,0, /* 14-bit lossless */
1331 7,6,8,5,9,4,10,3,11,12,2,0,1,13,14 } };
1332 ushort *huff, ver0, ver1, vpred[2][2], hpred[2], csize;
1333 int i, min, max, step=0, tree=0, split=0, row, col, len, shl, diff;
1335 fseek (ifp, meta_offset, SEEK_SET);
1338 if (ver0 == 0x49 || ver1 == 0x58)
1339 fseek (ifp, 2110, SEEK_CUR);
1340 if (ver0 == 0x46) tree = 2;
1341 if (tiff_bps == 14) tree += 3;
1342 read_shorts (vpred[0], 4);
1343 max = 1 << tiff_bps & 0x7fff;
1344 if ((csize = get2()) > 1)
1345 step = max / (csize-1);
1346 if (ver0 == 0x44 && ver1 == 0x20 && step > 0) {
1347 for (i=0; i < csize; i++)
1348 curve[i*step] = get2();
1349 for (i=0; i < max; i++)
1350 curve[i] = ( curve[i-i%step]*(step-i%step) +
1351 curve[i-i%step+step]*(i%step) ) / step;
1352 fseek (ifp, meta_offset+562, SEEK_SET);
1354 } else if (ver0 != 0x46 && csize <= 0x4001)
1355 read_shorts (curve, max=csize);
1356 while (curve[max-2] == curve[max-1]) max--;
1357 huff = make_decoder (nikon_tree[tree]);
1358 fseek (ifp, data_offset, SEEK_SET);
1360 for (min=row=0; row < height; row++) {
1361 if (split && row == split) {
1363 huff = make_decoder (nikon_tree[tree+1]);
1364 max += (min = 16) << 1;
1366 for (col=0; col < raw_width; col++) {
1370 diff = ((getbits(len-shl) << 1) + 1) << shl >> 1;
1371 if ((diff & (1 << (len-1))) == 0)
1372 diff -= (1 << len) - !shl;
1373 if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
1374 else hpred[col & 1] += diff;
1375 if ((ushort)(hpred[col & 1] + min) >= max) derror();
1376 RAW(row,col) = curve[LIM((short)hpred[col & 1],0,0x3fff)];
1382 void CLASS nikon_yuv_load_raw()
1384 int row, col, yuv[4], rgb[3], b, c;
1387 for (row=0; row < raw_height; row++)
1388 for (col=0; col < raw_width; col++) {
1389 if (!(b = col & 1)) {
1391 FORC(6) bitbuf |= (UINT64) fgetc(ifp) << c*8;
1392 FORC(4) yuv[c] = (bitbuf >> c*12 & 0xfff) - (c >> 1 << 11);
1394 rgb[0] = yuv[b] + 1.370705*yuv[3];
1395 rgb[1] = yuv[b] - 0.337633*yuv[2] - 0.698001*yuv[3];
1396 rgb[2] = yuv[b] + 1.732446*yuv[2];
1397 FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,0xfff)] / cam_mul[c];
1402 Returns 1 for a Coolpix 995, 0 for anything else.
1404 int CLASS nikon_e995()
1407 const uchar often[] = { 0x00, 0x55, 0xaa, 0xff };
1409 memset (histo, 0, sizeof histo);
1410 fseek (ifp, -2000, SEEK_END);
1411 for (i=0; i < 2000; i++)
1412 histo[fgetc(ifp)]++;
1413 for (i=0; i < 4; i++)
1414 if (histo[often[i]] < 200)
1420 Returns 1 for a Coolpix 2100, 0 for anything else.
1422 int CLASS nikon_e2100()
1427 fseek (ifp, 0, SEEK_SET);
1428 for (i=0; i < 1024; i++) {
1429 fread (t, 1, 12, ifp);
1430 if (((t[2] & t[4] & t[7] & t[9]) >> 4
1431 & t[1] & t[6] & t[8] & t[11] & 3) != 3)
1437 void CLASS nikon_3700()
1441 static const struct {
1443 char make[12], model[15];
1445 { 0x00, "Pentax", "Optio 33WR" },
1446 { 0x03, "Nikon", "E3200" },
1447 { 0x32, "Nikon", "E3700" },
1448 { 0x33, "Olympus", "C740UZ" } };
1450 fseek (ifp, 3072, SEEK_SET);
1451 fread (dp, 1, 24, ifp);
1452 bits = (dp[8] & 3) << 4 | (dp[20] & 3);
1453 for (i=0; i < sizeof table / sizeof *table; i++)
1454 if (bits == table[i].bits) {
1455 strcpy (make, table[i].make );
1456 strcpy (model, table[i].model);
1461 Separates a Minolta DiMAGE Z2 from a Nikon E4300.
1463 int CLASS minolta_z2()
1468 fseek (ifp, -sizeof tail, SEEK_END);
1469 fread (tail, 1, sizeof tail, ifp);
1470 for (nz=i=0; i < sizeof tail; i++)
1475 void CLASS jpeg_thumb();
1477 void CLASS ppm_thumb()
1480 thumb_length = thumb_width*thumb_height*3;
1481 thumb = (char *) malloc (thumb_length);
1482 merror (thumb, "ppm_thumb()");
1483 fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
1484 fread (thumb, 1, thumb_length, ifp);
1485 fwrite (thumb, 1, thumb_length, ofp);
1489 void CLASS ppm16_thumb()
1493 thumb_length = thumb_width*thumb_height*3;
1494 thumb = (char *) calloc (thumb_length, 2);
1495 merror (thumb, "ppm16_thumb()");
1496 read_shorts ((ushort *) thumb, thumb_length);
1497 for (i=0; i < thumb_length; i++)
1498 thumb[i] = ((ushort *) thumb)[i] >> 8;
1499 fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
1500 fwrite (thumb, 1, thumb_length, ofp);
1504 void CLASS layer_thumb()
1507 char *thumb, map[][4] = { "012","102" };
1509 colors = thumb_misc >> 5 & 7;
1510 thumb_length = thumb_width*thumb_height;
1511 thumb = (char *) calloc (colors, thumb_length);
1512 merror (thumb, "layer_thumb()");
1513 fprintf (ofp, "P%d\n%d %d\n255\n",
1514 5 + (colors >> 1), thumb_width, thumb_height);
1515 fread (thumb, thumb_length, colors, ifp);
1516 for (i=0; i < thumb_length; i++)
1517 FORCC putc (thumb[i+thumb_length*(map[thumb_misc >> 8][c]-'0')], ofp);
1521 void CLASS rollei_thumb()
1526 thumb_length = thumb_width * thumb_height;
1527 thumb = (ushort *) calloc (thumb_length, 2);
1528 merror (thumb, "rollei_thumb()");
1529 fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
1530 read_shorts (thumb, thumb_length);
1531 for (i=0; i < thumb_length; i++) {
1532 putc (thumb[i] << 3, ofp);
1533 putc (thumb[i] >> 5 << 2, ofp);
1534 putc (thumb[i] >> 11 << 3, ofp);
1539 void CLASS rollei_load_raw()
1542 unsigned iten=0, isix, i, buffer=0, todo[16];
1544 isix = raw_width * raw_height * 5 / 8;
1545 while (fread (pixel, 1, 10, ifp) == 10) {
1546 for (i=0; i < 10; i+=2) {
1548 todo[i+1] = pixel[i] << 8 | pixel[i+1];
1549 buffer = pixel[i] >> 2 | buffer << 6;
1551 for ( ; i < 16; i+=2) {
1553 todo[i+1] = buffer >> (14-i)*5;
1555 for (i=0; i < 16; i+=2)
1556 raw_image[todo[i]] = (todo[i+1] & 0x3ff);
1561 int CLASS raw (unsigned row, unsigned col)
1563 return (row < raw_height && col < raw_width) ? RAW(row,col) : 0;
1566 void CLASS phase_one_flat_field (int is_float, int nc)
1569 unsigned wide, high, y, x, c, rend, cend, row, col;
1570 float *mrow, num, mult[4];
1572 read_shorts (head, 8);
1573 if (head[2] * head[3] * head[4] * head[5] == 0) return;
1574 wide = head[2] / head[4] + (head[2] % head[4] != 0);
1575 high = head[3] / head[5] + (head[3] % head[5] != 0);
1576 mrow = (float *) calloc (nc*wide, sizeof *mrow);
1577 merror (mrow, "phase_one_flat_field()");
1578 for (y=0; y < high; y++) {
1579 for (x=0; x < wide; x++)
1580 for (c=0; c < nc; c+=2) {
1581 num = is_float ? getreal(11) : get2()/32768.0;
1582 if (y==0) mrow[c*wide+x] = num;
1583 else mrow[(c+1)*wide+x] = (num - mrow[c*wide+x]) / head[5];
1586 rend = head[1] + y*head[5];
1587 for (row = rend-head[5];
1588 row < raw_height && row < rend &&
1589 row < head[1]+head[3]-head[5]; row++) {
1590 for (x=1; x < wide; x++) {
1591 for (c=0; c < nc; c+=2) {
1592 mult[c] = mrow[c*wide+x-1];
1593 mult[c+1] = (mrow[c*wide+x] - mult[c]) / head[4];
1595 cend = head[0] + x*head[4];
1596 for (col = cend-head[4];
1598 col < cend && col < head[0]+head[2]-head[4]; col++) {
1599 c = nc > 2 ? FC(row-top_margin,col-left_margin) : 0;
1601 c = RAW(row,col) * mult[c];
1602 RAW(row,col) = LIM(c,0,65535);
1604 for (c=0; c < nc; c+=2)
1605 mult[c] += mult[c+1];
1608 for (x=0; x < wide; x++)
1609 for (c=0; c < nc; c+=2)
1610 mrow[c*wide+x] += mrow[(c+1)*wide+x];
1616 void CLASS phase_one_correct()
1618 unsigned entries, tag, data, save, col, row, type;
1619 int len, i, j, k, cip, val[4], dev[4], sum, max;
1620 int head[9], diff, mindiff=INT_MAX, off_412=0;
1621 static const signed char dir[12][2] =
1622 { {-1,-1}, {-1,1}, {1,-1}, {1,1}, {-2,0}, {0,-2}, {0,2}, {2,0},
1623 {-2,-2}, {-2,2}, {2,-2}, {2,2} };
1624 float poly[8], num, cfrac, frac, mult[2], *yval[2];
1626 int qmult_applied = 0, qlin_applied = 0;
1628 if (half_size || !meta_length) return;
1629 if (verbose) fprintf (stderr,_("Phase One correction...\n"));
1630 fseek (ifp, meta_offset, SEEK_SET);
1632 fseek (ifp, 6, SEEK_CUR);
1633 fseek (ifp, meta_offset+get4(), SEEK_SET);
1634 entries = get4(); get4();
1640 fseek (ifp, meta_offset+data, SEEK_SET);
1641 if (tag == 0x419) { /* Polynomial curve */
1642 for (get4(), i=0; i < 8; i++)
1643 poly[i] = getreal(11);
1644 poly[3] += (ph1.tag_210 - poly[7]) * poly[6] + 1;
1645 for (i=0; i < 0x10000; i++) {
1646 num = (poly[5]*i + poly[3])*i + poly[1];
1647 curve[i] = LIM(num,0,65535);
1648 } goto apply; /* apply to right half */
1649 } else if (tag == 0x41a) { /* Polynomial curve */
1650 for (i=0; i < 4; i++)
1651 poly[i] = getreal(11);
1652 for (i=0; i < 0x10000; i++) {
1653 for (num=0, j=4; j--; )
1654 num = num * i + poly[j];
1655 curve[i] = LIM(num+i,0,65535);
1656 } apply: /* apply to whole image */
1657 for (row=0; row < raw_height; row++)
1658 for (col = (tag & 1)*ph1.split_col; col < raw_width; col++)
1659 RAW(row,col) = curve[RAW(row,col)];
1660 } else if (tag == 0x400) { /* Sensor defects */
1661 while ((len -= 8) >= 0) {
1664 type = get2(); get2();
1665 if (col >= raw_width) continue;
1666 if (type == 131 || type == 137) /* Bad column */
1667 for (row=0; row < raw_height; row++)
1668 if (FC(row-top_margin,col-left_margin) == 1) {
1669 for (sum=i=0; i < 4; i++)
1670 sum += val[i] = raw (row+dir[i][0], col+dir[i][1]);
1671 for (max=i=0; i < 4; i++) {
1672 dev[i] = abs((val[i] << 2) - sum);
1673 if (dev[max] < dev[i]) max = i;
1675 RAW(row,col) = (sum - val[max])/3.0 + 0.5;
1677 for (sum=0, i=8; i < 12; i++)
1678 sum += raw (row+dir[i][0], col+dir[i][1]);
1679 RAW(row,col) = 0.5 + sum * 0.0732233 +
1680 (raw(row,col-2) + raw(row,col+2)) * 0.3535534;
1682 else if (type == 129) { /* Bad pixel */
1683 if (row >= raw_height) continue;
1684 j = (FC(row-top_margin,col-left_margin) != 1) * 4;
1685 for (sum=0, i=j; i < j+8; i++)
1686 sum += raw (row+dir[i][0], col+dir[i][1]);
1687 RAW(row,col) = (sum + 4) >> 3;
1690 } else if (tag == 0x401) { /* All-color flat fields */
1691 phase_one_flat_field (1, 2);
1692 } else if (tag == 0x416 || tag == 0x410) {
1693 phase_one_flat_field (0, 2);
1694 } else if (tag == 0x40b) { /* Red+blue flat field */
1695 phase_one_flat_field (0, 4);
1696 } else if (tag == 0x412) {
1697 fseek (ifp, 36, SEEK_CUR);
1698 diff = abs (get2() - ph1.tag_21a);
1699 if (mindiff > diff) {
1701 off_412 = ftell(ifp) - 38;
1703 } else if (tag == 0x41f && !qlin_applied) { /* Quadrant linearization */
1704 ushort lc[2][2][16], ref[16];
1706 for (qr = 0; qr < 2; qr++)
1707 for (qc = 0; qc < 2; qc++)
1708 for (i = 0; i < 16; i++)
1709 lc[qr][qc][i] = get4();
1710 for (i = 0; i < 16; i++) {
1712 for (qr = 0; qr < 2; qr++)
1713 for (qc = 0; qc < 2; qc++)
1715 ref[i] = (v + 2) >> 2;
1717 for (qr = 0; qr < 2; qr++) {
1718 for (qc = 0; qc < 2; qc++) {
1720 for (i = 0; i < 16; i++) {
1721 cx[1+i] = lc[qr][qc][i];
1725 cx[17] = cf[17] = ((unsigned) ref[15] * 65535) / lc[qr][qc][15];
1726 cx[18] = cf[18] = 65535;
1727 cubic_spline(cx, cf, 19);
1728 for (row = (qr ? ph1.split_row : 0);
1729 row < (qr ? raw_height : ph1.split_row); row++)
1730 for (col = (qc ? ph1.split_col : 0);
1731 col < (qc ? raw_width : ph1.split_col); col++)
1732 RAW(row,col) = curve[RAW(row,col)];
1736 } else if (tag == 0x41e && !qmult_applied) { /* Quadrant multipliers */
1737 float qmult[2][2] = { { 1, 1 }, { 1, 1 } };
1738 get4(); get4(); get4(); get4();
1739 qmult[0][0] = 1.0 + getreal(11);
1740 get4(); get4(); get4(); get4(); get4();
1741 qmult[0][1] = 1.0 + getreal(11);
1742 get4(); get4(); get4();
1743 qmult[1][0] = 1.0 + getreal(11);
1744 get4(); get4(); get4();
1745 qmult[1][1] = 1.0 + getreal(11);
1746 for (row=0; row < raw_height; row++)
1747 for (col=0; col < raw_width; col++) {
1748 i = qmult[row >= ph1.split_row][col >= ph1.split_col] * RAW(row,col);
1749 RAW(row,col) = LIM(i,0,65535);
1752 } else if (tag == 0x431 && !qmult_applied) { /* Quadrant combined */
1753 ushort lc[2][2][7], ref[7];
1755 for (i = 0; i < 7; i++)
1757 for (qr = 0; qr < 2; qr++)
1758 for (qc = 0; qc < 2; qc++)
1759 for (i = 0; i < 7; i++)
1760 lc[qr][qc][i] = get4();
1761 for (qr = 0; qr < 2; qr++) {
1762 for (qc = 0; qc < 2; qc++) {
1764 for (i = 0; i < 7; i++) {
1766 cf[1+i] = ((unsigned) ref[i] * lc[qr][qc][i]) / 10000;
1769 cx[8] = cf[8] = 65535;
1770 cubic_spline(cx, cf, 9);
1771 for (row = (qr ? ph1.split_row : 0);
1772 row < (qr ? raw_height : ph1.split_row); row++)
1773 for (col = (qc ? ph1.split_col : 0);
1774 col < (qc ? raw_width : ph1.split_col); col++)
1775 RAW(row,col) = curve[RAW(row,col)];
1781 fseek (ifp, save, SEEK_SET);
1784 fseek (ifp, off_412, SEEK_SET);
1785 for (i=0; i < 9; i++) head[i] = get4() & 0x7fff;
1786 yval[0] = (float *) calloc (head[1]*head[3] + head[2]*head[4], 6);
1787 merror (yval[0], "phase_one_correct()");
1788 yval[1] = (float *) (yval[0] + head[1]*head[3]);
1789 xval[0] = (ushort *) (yval[1] + head[2]*head[4]);
1790 xval[1] = (ushort *) (xval[0] + head[1]*head[3]);
1792 for (i=0; i < 2; i++)
1793 for (j=0; j < head[i+1]*head[i+3]; j++)
1794 yval[i][j] = getreal(11);
1795 for (i=0; i < 2; i++)
1796 for (j=0; j < head[i+1]*head[i+3]; j++)
1797 xval[i][j] = get2();
1798 for (row=0; row < raw_height; row++)
1799 for (col=0; col < raw_width; col++) {
1800 cfrac = (float) col * head[3] / raw_width;
1801 cfrac -= cip = cfrac;
1802 num = RAW(row,col) * 0.5;
1803 for (i=cip; i < cip+2; i++) {
1804 for (k=j=0; j < head[1]; j++)
1805 if (num < xval[0][k = head[1]*i+j]) break;
1806 frac = (j == 0 || j == head[1]) ? 0 :
1807 (xval[0][k] - num) / (xval[0][k] - xval[0][k-1]);
1808 mult[i-cip] = yval[0][k-1] * frac + yval[0][k] * (1-frac);
1810 i = ((mult[0] * (1-cfrac) + mult[1] * cfrac) * row + num) * 2;
1811 RAW(row,col) = LIM(i,0,65535);
1817 void CLASS phase_one_load_raw()
1820 ushort akey, bkey, mask;
1822 fseek (ifp, ph1.key_off, SEEK_SET);
1825 mask = ph1.format == 1 ? 0x5555:0x1354;
1826 fseek (ifp, data_offset, SEEK_SET);
1827 read_shorts (raw_image, raw_width*raw_height);
1829 for (i=0; i < raw_width*raw_height; i+=2) {
1830 a = raw_image[i+0] ^ akey;
1831 b = raw_image[i+1] ^ bkey;
1832 raw_image[i+0] = (a & mask) | (b & ~mask);
1833 raw_image[i+1] = (b & mask) | (a & ~mask);
1837 unsigned CLASS ph1_bithuff (int nbits, ushort *huff)
1839 static UINT64 bitbuf=0;
1844 return bitbuf = vbits = 0;
1845 if (nbits == 0) return 0;
1846 if (vbits < nbits) {
1847 bitbuf = bitbuf << 32 | get4();
1850 c = bitbuf << (64-vbits) >> (64-nbits);
1852 vbits -= huff[c] >> 8;
1853 return (uchar) huff[c];
1858 #define ph1_bits(n) ph1_bithuff(n,0)
1859 #define ph1_huff(h) ph1_bithuff(*h,h+1)
1861 void CLASS phase_one_load_raw_c()
1863 static const int length[] = { 8,7,6,9,11,10,5,12,14,13 };
1864 int *offset, len[2], pred[2], row, col, i, j;
1866 short (*cblack)[2], (*rblack)[2];
1868 pixel = (ushort *) calloc (raw_width*3 + raw_height*4, 2);
1869 merror (pixel, "phase_one_load_raw_c()");
1870 offset = (int *) (pixel + raw_width);
1871 fseek (ifp, strip_offset, SEEK_SET);
1872 for (row=0; row < raw_height; row++)
1873 offset[row] = get4();
1874 cblack = (short (*)[2]) (offset + raw_height);
1875 fseek (ifp, ph1.black_col, SEEK_SET);
1877 read_shorts ((ushort *) cblack[0], raw_height*2);
1878 rblack = cblack + raw_height;
1879 fseek (ifp, ph1.black_row, SEEK_SET);
1881 read_shorts ((ushort *) rblack[0], raw_width*2);
1882 for (i=0; i < 256; i++)
1883 curve[i] = i*i / 3.969 + 0.5;
1884 for (row=0; row < raw_height; row++) {
1885 fseek (ifp, data_offset + offset[row], SEEK_SET);
1887 pred[0] = pred[1] = 0;
1888 for (col=0; col < raw_width; col++) {
1889 if (col >= (raw_width & -8))
1890 len[0] = len[1] = 14;
1891 else if ((col & 7) == 0)
1892 for (i=0; i < 2; i++) {
1893 for (j=0; j < 5 && !ph1_bits(1); j++);
1894 if (j--) len[i] = length[j*2 + ph1_bits(1)];
1896 if ((i = len[col & 1]) == 14)
1897 pixel[col] = pred[col & 1] = ph1_bits(16);
1899 pixel[col] = pred[col & 1] += ph1_bits(i) + 1 - (1 << (i - 1));
1900 if (pred[col & 1] >> 16) derror();
1901 if (ph1.format == 5 && pixel[col] < 256)
1902 pixel[col] = curve[pixel[col]];
1904 for (col=0; col < raw_width; col++) {
1905 i = (pixel[col] << 2*(ph1.format != 8)) - ph1.black
1906 + cblack[row][col >= ph1.split_col]
1907 + rblack[col][row >= ph1.split_row];
1908 if (i > 0) RAW(row,col) = i;
1912 maximum = 0xfffc - ph1.black;
1915 void CLASS hasselblad_load_raw()
1918 int shot, row, col, *back[5], len[2], diff[12], pred, sh, f, s, c;
1919 unsigned upix, urow, ucol;
1922 if (!ljpeg_start (&jh, 0)) return;
1925 back[4] = (int *) calloc (raw_width, 3*sizeof **back);
1926 merror (back[4], "hasselblad_load_raw()");
1927 FORC3 back[c] = back[4] + c*raw_width;
1928 cblack[6] >>= sh = tiff_samples > 1;
1929 shot = LIM(shot_select, 1, tiff_samples) - 1;
1930 for (row=0; row < raw_height; row++) {
1931 FORC4 back[(c+3) & 3] = back[c];
1932 for (col=0; col < raw_width; col+=2) {
1933 for (s=0; s < tiff_samples*2; s+=2) {
1934 FORC(2) len[c] = ph1_huff(jh.huff[0]);
1936 diff[s+c] = ph1_bits(len[c]);
1937 if ((diff[s+c] & (1 << (len[c]-1))) == 0)
1938 diff[s+c] -= (1 << len[c]) - 1;
1939 if (diff[s+c] == 65535) diff[s+c] = -32768;
1942 for (s=col; s < col+2; s++) {
1943 pred = 0x8000 + load_flags;
1944 if (col) pred = back[2][s-2];
1945 if (col && row > 1) switch (jh.psv) {
1946 case 11: pred += back[0][s]/2 - back[0][s-2]/2; break;
1948 f = (row & 1)*3 ^ ((col+s) & 1);
1949 FORC (tiff_samples) {
1950 pred += diff[(s & 1)*tiff_samples+c];
1951 upix = pred >> sh & 0xffff;
1952 if (raw_image && c == shot)
1955 urow = row-top_margin + (c & 1);
1956 ucol = col-left_margin - ((c >> 1) & 1);
1957 ip = &image[urow*width+ucol][f];
1958 if (urow < height && ucol < width)
1959 *ip = c < 4 ? upix : (*ip + upix) >> 1;
1968 if (image) mix_green = 1;
1971 void CLASS leaf_hdr_load_raw()
1974 unsigned tile=0, r, c, row, col;
1977 pixel = (ushort *) calloc (raw_width, sizeof *pixel);
1978 merror (pixel, "leaf_hdr_load_raw()");
1981 for (r=0; r < raw_height; r++) {
1982 if (r % tile_length == 0) {
1983 fseek (ifp, data_offset + 4*tile++, SEEK_SET);
1984 fseek (ifp, get4(), SEEK_SET);
1986 if (filters && c != shot_select) continue;
1987 if (filters) pixel = raw_image + r*raw_width;
1988 read_shorts (pixel, raw_width);
1989 if (!filters && (row = r - top_margin) < height)
1990 for (col=0; col < width; col++)
1991 image[row*width+col][c] = pixel[col+left_margin];
2000 void CLASS unpacked_load_raw()
2002 int row, col, bits=0;
2004 while (1 << ++bits < maximum);
2005 read_shorts (raw_image, raw_width*raw_height);
2006 for (row=0; row < raw_height; row++)
2007 for (col=0; col < raw_width; col++)
2008 if ((RAW(row,col) >>= load_flags) >> bits
2009 && (unsigned) (row-top_margin) < height
2010 && (unsigned) (col-left_margin) < width) derror();
2013 void CLASS sinar_4shot_load_raw()
2016 unsigned shot, row, col, r, c;
2019 shot = LIM (shot_select, 1, 4) - 1;
2020 fseek (ifp, data_offset + shot*4, SEEK_SET);
2021 fseek (ifp, get4(), SEEK_SET);
2022 unpacked_load_raw();
2025 pixel = (ushort *) calloc (raw_width, sizeof *pixel);
2026 merror (pixel, "sinar_4shot_load_raw()");
2027 for (shot=0; shot < 4; shot++) {
2028 fseek (ifp, data_offset + shot*4, SEEK_SET);
2029 fseek (ifp, get4(), SEEK_SET);
2030 for (row=0; row < raw_height; row++) {
2031 read_shorts (pixel, raw_width);
2032 if ((r = row-top_margin - (shot >> 1 & 1)) >= height) continue;
2033 for (col=0; col < raw_width; col++) {
2034 if ((c = col-left_margin - (shot & 1)) >= width) continue;
2035 image[r*width+c][(row & 1)*3 ^ (~col & 1)] = pixel[col];
2043 void CLASS imacon_full_load_raw()
2048 for (row=0; row < height; row++)
2049 for (col=0; col < width; col++)
2050 read_shorts (image[row*width+col], 3);
2053 void CLASS packed_load_raw()
2055 int vbits=0, bwide, rbits, bite, half, irow, row, col, val, i;
2058 bwide = raw_width * tiff_bps / 8;
2059 bwide += bwide & load_flags >> 7;
2060 rbits = bwide * 8 - raw_width * tiff_bps;
2061 if (load_flags & 1) bwide = bwide * 16 / 15;
2062 bite = 8 + (load_flags & 24);
2063 half = (raw_height+1) >> 1;
2064 for (irow=0; irow < raw_height; irow++) {
2066 if (load_flags & 2 &&
2067 (row = irow % half * 2 + irow / half) == 1 &&
2069 if (vbits=0, tiff_compress)
2070 fseek (ifp, data_offset - (-half*bwide & -2048), SEEK_SET);
2072 fseek (ifp, 0, SEEK_END);
2073 fseek (ifp, ftell(ifp) >> 3 << 2, SEEK_SET);
2076 for (col=0; col < raw_width; col++) {
2077 for (vbits -= tiff_bps; vbits < 0; vbits += bite) {
2079 for (i=0; i < bite; i+=8)
2080 bitbuf |= (unsigned) (fgetc(ifp) << i);
2082 val = bitbuf << (64-tiff_bps-vbits) >> (64-tiff_bps);
2083 RAW(row,col ^ (load_flags >> 6 & 1)) = val;
2084 if (load_flags & 1 && (col % 10) == 9 && fgetc(ifp) &&
2085 row < height+top_margin && col < width+left_margin) derror();
2091 void CLASS nokia_load_raw()
2094 int rev, dwide, row, col, c;
2097 rev = 3 * (order == 0x4949);
2098 dwide = (raw_width * 5 + 1) / 4;
2099 data = (uchar *) malloc (dwide*2);
2100 merror (data, "nokia_load_raw()");
2101 for (row=0; row < raw_height; row++) {
2102 if (fread (data+dwide, 1, dwide, ifp) < dwide) derror();
2103 FORC(dwide) data[c] = data[dwide+(c ^ rev)];
2104 for (dp=data, col=0; col < raw_width; dp+=5, col+=4)
2105 FORC4 RAW(row,col+c) = (dp[c] << 2) | (dp[4] >> (c << 1) & 3);
2109 if (strcmp(make,"OmniVision")) return;
2112 sum[ c & 1] += SQR(RAW(row,c)-RAW(row+1,c+1));
2113 sum[~c & 1] += SQR(RAW(row+1,c)-RAW(row,c+1));
2115 if (sum[1] > sum[0]) filters = 0x4b4b4b4b;
2118 void CLASS canon_rmf_load_raw()
2120 int row, col, bits, orow, ocol, c;
2122 for (row=0; row < raw_height; row++)
2123 for (col=0; col < raw_width-2; col+=3) {
2127 if ((ocol = col+c-4) < 0) {
2129 if ((orow -= 2) < 0)
2132 RAW(orow,ocol) = curve[bits >> (10*c+2) & 0x3ff];
2135 maximum = curve[0x3ff];
2138 unsigned CLASS pana_bits (int nbits)
2140 static uchar buf[0x4000];
2144 if (!nbits) return vbits=0;
2146 fread (buf+load_flags, 1, 0x4000-load_flags, ifp);
2147 fread (buf, 1, load_flags, ifp);
2149 vbits = (vbits - nbits) & 0x1ffff;
2150 byte = vbits >> 3 ^ 0x3ff0;
2151 return (buf[byte] | buf[byte+1] << 8) >> (vbits & 7) & ~(-1 << nbits);
2154 void CLASS panasonic_load_raw()
2156 int row, col, i, j, sh=0, pred[2], nonz[2];
2159 for (row=0; row < height; row++)
2160 for (col=0; col < raw_width; col++) {
2161 if ((i = col % 14) == 0)
2162 pred[0] = pred[1] = nonz[0] = nonz[1] = 0;
2163 if (i % 3 == 2) sh = 4 >> (3 - pana_bits(2));
2165 if ((j = pana_bits(8))) {
2166 if ((pred[i & 1] -= 0x80 << sh) < 0 || sh == 4)
2167 pred[i & 1] &= ~(-1 << sh);
2168 pred[i & 1] += j << sh;
2170 } else if ((nonz[i & 1] = pana_bits(8)) || i > 11)
2171 pred[i & 1] = nonz[i & 1] << 4 | pana_bits(4);
2172 if ((RAW(row,col) = pred[col & 1]) > 4098 && col < width) derror();
2176 void CLASS olympus_load_raw()
2179 int row, col, nbits, sign, low, high, i, c, w, n, nw;
2180 int acarry[2][3], *carry, pred, diff;
2184 FORC(2048 >> i) huff[++n] = (i+1) << 8 | i;
2185 fseek (ifp, 7, SEEK_CUR);
2187 for (row=0; row < height; row++) {
2188 memset (acarry, 0, sizeof acarry);
2189 for (col=0; col < raw_width; col++) {
2190 carry = acarry[col & 1];
2191 i = 2 * (carry[2] < 3);
2192 for (nbits=2+i; (ushort) carry[0] >> (nbits+i); nbits++);
2193 low = (sign = getbits(3)) & 3;
2194 sign = sign << 29 >> 31;
2195 if ((high = getbithuff(12,huff)) == 12)
2196 high = getbits(16-nbits) >> 1;
2197 carry[0] = (high << nbits) | getbits(nbits);
2198 diff = (carry[0] ^ sign) + carry[1];
2199 carry[1] = (diff*3 + carry[1]) >> 5;
2200 carry[2] = carry[0] > 16 ? 0 : carry[2]+1;
2201 if (col >= width) continue;
2202 if (row < 2 && col < 2) pred = 0;
2203 else if (row < 2) pred = RAW(row,col-2);
2204 else if (col < 2) pred = RAW(row-2,col);
2208 nw = RAW(row-2,col-2);
2209 if ((w < nw && nw < n) || (n < nw && nw < w)) {
2210 if (ABS(w-nw) > 32 || ABS(n-nw) > 32)
2212 else pred = (w + n) >> 1;
2213 } else pred = ABS(w-nw) > ABS(n-nw) ? w : n;
2215 if ((RAW(row,col) = pred + ((diff << 2) | low)) >> 12) derror();
2220 void CLASS minolta_rd175_load_raw()
2223 unsigned irow, box, row, col;
2225 for (irow=0; irow < 1481; irow++) {
2226 if (fread (pixel, 1, 768, ifp) < 768) derror();
2228 row = irow % 82 * 12 + ((box < 12) ? box | 1 : (box-12)*2);
2230 case 1477: case 1479: continue;
2231 case 1476: row = 984; break;
2232 case 1480: row = 985; break;
2233 case 1478: row = 985; box = 1;
2235 if ((box < 12) && (box & 1)) {
2236 for (col=0; col < 1533; col++, row ^= 1)
2237 if (col != 1) RAW(row,col) = (col+1) & 2 ?
2238 pixel[col/2-1] + pixel[col/2+1] : pixel[col/2] << 1;
2239 RAW(row,1) = pixel[1] << 1;
2240 RAW(row,1533) = pixel[765] << 1;
2242 for (col=row & 1; col < 1534; col+=2)
2243 RAW(row,col) = pixel[col/2] << 1;
2245 maximum = 0xff << 1;
2248 void CLASS quicktake_100_load_raw()
2250 uchar pixel[484][644];
2251 static const short gstep[16] =
2252 { -89,-60,-44,-32,-22,-15,-8,-2,2,8,15,22,32,44,60,89 };
2253 static const short rstep[6][4] =
2254 { { -3,-1,1,3 }, { -5,-1,1,5 }, { -8,-2,2,8 },
2255 { -13,-3,3,13 }, { -19,-4,4,19 }, { -28,-6,6,28 } };
2256 static const short curve[256] =
2257 { 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,
2258 28,29,30,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,53,
2259 54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,74,75,76,77,78,
2260 79,80,81,82,83,84,86,88,90,92,94,97,99,101,103,105,107,110,112,114,116,
2261 118,120,123,125,127,129,131,134,136,138,140,142,144,147,149,151,153,155,
2262 158,160,162,164,166,168,171,173,175,177,179,181,184,186,188,190,192,195,
2263 197,199,201,203,205,208,210,212,214,216,218,221,223,226,230,235,239,244,
2264 248,252,257,261,265,270,274,278,283,287,291,296,300,305,309,313,318,322,
2265 326,331,335,339,344,348,352,357,361,365,370,374,379,383,387,392,396,400,
2266 405,409,413,418,422,426,431,435,440,444,448,453,457,461,466,470,474,479,
2267 483,487,492,496,500,508,519,531,542,553,564,575,587,598,609,620,631,643,
2268 654,665,676,687,698,710,721,732,743,754,766,777,788,799,810,822,833,844,
2269 855,866,878,889,900,911,922,933,945,956,967,978,989,1001,1012,1023 };
2270 int rb, row, col, sharp, val=0;
2273 memset (pixel, 0x80, sizeof pixel);
2274 for (row=2; row < height+2; row++) {
2275 for (col=2+(row & 1); col < width+2; col+=2) {
2276 val = ((pixel[row-1][col-1] + 2*pixel[row-1][col+1] +
2277 pixel[row][col-2]) >> 2) + gstep[getbits(4)];
2278 pixel[row][col] = val = LIM(val,0,255);
2280 pixel[row][col-2] = pixel[row+1][~row & 1] = val;
2282 pixel[row-1][col+1] = pixel[row-1][col+3] = val;
2284 pixel[row][col] = val;
2286 for (rb=0; rb < 2; rb++)
2287 for (row=2+rb; row < height+2; row+=2)
2288 for (col=3-(row & 1); col < width+2; col+=2) {
2289 if (row < 4 || col < 4) sharp = 2;
2291 val = ABS(pixel[row-2][col] - pixel[row][col-2])
2292 + ABS(pixel[row-2][col] - pixel[row-2][col-2])
2293 + ABS(pixel[row][col-2] - pixel[row-2][col-2]);
2294 sharp = val < 4 ? 0 : val < 8 ? 1 : val < 16 ? 2 :
2295 val < 32 ? 3 : val < 48 ? 4 : 5;
2297 val = ((pixel[row-2][col] + pixel[row][col-2]) >> 1)
2298 + rstep[sharp][getbits(2)];
2299 pixel[row][col] = val = LIM(val,0,255);
2300 if (row < 4) pixel[row-2][col+2] = val;
2301 if (col < 4) pixel[row+2][col-2] = val;
2303 for (row=2; row < height+2; row++)
2304 for (col=3-(row & 1); col < width+2; col+=2) {
2305 val = ((pixel[row][col-1] + (pixel[row][col] << 2) +
2306 pixel[row][col+1]) >> 1) - 0x100;
2307 pixel[row][col] = LIM(val,0,255);
2309 for (row=0; row < height; row++)
2310 for (col=0; col < width; col++)
2311 RAW(row,col) = curve[pixel[row+2][col+2]];
2315 #define radc_token(tree) ((signed char) getbithuff(8,huff[tree]))
2317 #define FORYX for (y=1; y < 3; y++) for (x=col+1; x >= col; x--)
2319 #define PREDICTOR (c ? (buf[c][y-1][x] + buf[c][y][x+1]) / 2 \
2320 : (buf[c][y-1][x+1] + 2*buf[c][y-1][x] + buf[c][y][x+1]) / 4)
2322 void CLASS kodak_radc_load_raw()
2324 static const char src[] = {
2325 1,1, 2,3, 3,4, 4,2, 5,7, 6,5, 7,6, 7,8,
2326 1,0, 2,1, 3,3, 4,4, 5,2, 6,7, 7,6, 8,5, 8,8,
2327 2,1, 2,3, 3,0, 3,2, 3,4, 4,6, 5,5, 6,7, 6,8,
2328 2,0, 2,1, 2,3, 3,2, 4,4, 5,6, 6,7, 7,5, 7,8,
2329 2,1, 2,4, 3,0, 3,2, 3,3, 4,7, 5,5, 6,6, 6,8,
2330 2,3, 3,1, 3,2, 3,4, 3,5, 3,6, 4,7, 5,0, 5,8,
2331 2,3, 2,6, 3,0, 3,1, 4,4, 4,5, 4,7, 5,2, 5,8,
2332 2,4, 2,7, 3,3, 3,6, 4,1, 4,2, 4,5, 5,0, 5,8,
2333 2,6, 3,1, 3,3, 3,5, 3,7, 3,8, 4,0, 5,2, 5,4,
2334 2,0, 2,1, 3,2, 3,3, 4,4, 4,5, 5,6, 5,7, 4,8,
2337 2,-17, 2,-5, 2,5, 2,17,
2338 2,-7, 2,2, 2,9, 2,18,
2339 2,-18, 2,-9, 2,-2, 2,7,
2340 2,-28, 2,28, 3,-49, 3,-9, 3,9, 4,49, 5,-79, 5,79,
2341 2,-1, 2,13, 2,26, 3,39, 4,-16, 5,55, 6,-37, 6,76,
2342 2,-26, 2,-13, 2,1, 3,-39, 4,16, 5,-55, 6,-76, 6,37
2344 ushort huff[19][256];
2345 int row, col, tree, nreps, rep, step, i, c, s, r, x, y, val;
2346 short last[3] = { 16,16,16 }, mul[3], buf[3][3][386];
2347 static const ushort pt[] =
2348 { 0,0, 1280,1344, 2320,3616, 3328,8000, 4095,16383, 65535,16383 };
2350 for (i=2; i < 12; i+=2)
2351 for (c=pt[i-2]; c <= pt[i]; c++)
2353 (c-pt[i-2]) / (pt[i]-pt[i-2]) * (pt[i+1]-pt[i-1]) + pt[i-1] + 0.5;
2354 for (s=i=0; i < sizeof src; i+=2)
2356 ((ushort *)huff)[s++] = src[i] << 8 | (uchar) src[i+1];
2357 s = kodak_cbpp == 243 ? 2 : 3;
2358 FORC(256) huff[18][c] = (8-s) << 8 | c >> s << s | 1 << (s-1);
2360 for (i=0; i < sizeof(buf)/sizeof(short); i++)
2361 ((short *)buf)[i] = 2048;
2362 for (row=0; row < height; row+=4) {
2363 FORC3 mul[c] = getbits(6);
2365 val = ((0x1000000/last[c] + 0x7ff) >> 12) * mul[c];
2366 s = val > 65564 ? 10:12;
2369 for (i=0; i < sizeof(buf[0])/sizeof(short); i++)
2370 ((short *)buf[c])[i] = (((short *)buf[c])[i] * val + x) >> s;
2372 for (r=0; r <= !c; r++) {
2373 buf[c][1][width/2] = buf[c][2][width/2] = mul[c] << 7;
2374 for (tree=1, col=width/2; col > 0; ) {
2375 if ((tree = radc_token(tree))) {
2378 FORYX buf[c][y][x] = (uchar) radc_token(18) * mul[c];
2380 FORYX buf[c][y][x] = radc_token(tree+10) * 16 + PREDICTOR;
2383 nreps = (col > 2) ? radc_token(9) + 1 : 1;
2384 for (rep=0; rep < 8 && rep < nreps && col > 0; rep++) {
2386 FORYX buf[c][y][x] = PREDICTOR;
2388 step = radc_token(10) << 4;
2389 FORYX buf[c][y][x] += step;
2392 } while (nreps == 9);
2394 for (y=0; y < 2; y++)
2395 for (x=0; x < width/2; x++) {
2396 val = (buf[c][y+1][x] << 4) / mul[c];
2397 if (val < 0) val = 0;
2398 if (c) RAW(row+y*2+c-1,x*2+2-c) = val;
2399 else RAW(row+r*2+y,x*2+y) = val;
2401 memcpy (buf[c][0]+!c, buf[c][2], sizeof buf[c][0]-2*!c);
2404 for (y=row; y < row+4; y++)
2405 for (x=0; x < width; x++)
2408 s = x+1 < width ? x+1 : x-1;
2409 val = (RAW(y,x)-2048)*2 + (RAW(y,r)+RAW(y,s))/2;
2410 if (val < 0) val = 0;
2414 for (i=0; i < height*width; i++)
2415 raw_image[i] = curve[raw_image[i]];
2423 void CLASS kodak_jpeg_load_raw() {}
2424 void CLASS lossy_dng_load_raw() {}
2428 fill_input_buffer (j_decompress_ptr cinfo)
2430 static uchar jpeg_buffer[4096];
2433 nbytes = fread (jpeg_buffer, 1, 4096, ifp);
2434 swab (jpeg_buffer, jpeg_buffer, nbytes);
2435 cinfo->src->next_input_byte = jpeg_buffer;
2436 cinfo->src->bytes_in_buffer = nbytes;
2440 void CLASS kodak_jpeg_load_raw()
2442 struct jpeg_decompress_struct cinfo;
2443 struct jpeg_error_mgr jerr;
2445 JSAMPLE (*pixel)[3];
2448 cinfo.err = jpeg_std_error (&jerr);
2449 jpeg_create_decompress (&cinfo);
2450 jpeg_stdio_src (&cinfo, ifp);
2451 cinfo.src->fill_input_buffer = fill_input_buffer;
2452 jpeg_read_header (&cinfo, TRUE);
2453 jpeg_start_decompress (&cinfo);
2454 if ((cinfo.output_width != width ) ||
2455 (cinfo.output_height*2 != height ) ||
2456 (cinfo.output_components != 3 )) {
2457 fprintf (stderr,_("%s: incorrect JPEG dimensions\n"), ifname);
2458 jpeg_destroy_decompress (&cinfo);
2459 longjmp (failure, 3);
2461 buf = (*cinfo.mem->alloc_sarray)
2462 ((j_common_ptr) &cinfo, JPOOL_IMAGE, width*3, 1);
2464 while (cinfo.output_scanline < cinfo.output_height) {
2465 row = cinfo.output_scanline * 2;
2466 jpeg_read_scanlines (&cinfo, buf, 1);
2467 pixel = (JSAMPLE (*)[3]) buf[0];
2468 for (col=0; col < width; col+=2) {
2469 RAW(row+0,col+0) = pixel[col+0][1] << 1;
2470 RAW(row+1,col+1) = pixel[col+1][1] << 1;
2471 RAW(row+0,col+1) = pixel[col][0] + pixel[col+1][0];
2472 RAW(row+1,col+0) = pixel[col][2] + pixel[col+1][2];
2475 jpeg_finish_decompress (&cinfo);
2476 jpeg_destroy_decompress (&cinfo);
2477 maximum = 0xff << 1;
2480 void CLASS gamma_curve (double pwr, double ts, int mode, int imax);
2482 void CLASS lossy_dng_load_raw()
2484 struct jpeg_decompress_struct cinfo;
2485 struct jpeg_error_mgr jerr;
2487 JSAMPLE (*pixel)[3];
2488 unsigned sorder=order, ntags, opcode, deg, i, j, c;
2489 unsigned save=data_offset-4, trow=0, tcol=0, row, col;
2491 double coeff[9], tot;
2494 fseek (ifp, meta_offset, SEEK_SET);
2498 opcode = get4(); get4(); get4();
2500 { fseek (ifp, get4(), SEEK_CUR); continue; }
2501 fseek (ifp, 20, SEEK_CUR);
2502 if ((c = get4()) > 2) break;
2503 fseek (ifp, 12, SEEK_CUR);
2504 if ((deg = get4()) > 8) break;
2505 for (i=0; i <= deg && i < 9; i++)
2506 coeff[i] = getreal(12);
2507 for (i=0; i < 256; i++) {
2508 for (tot=j=0; j <= deg; j++)
2509 tot += coeff[j] * pow(i/255.0, j);
2510 cur[c][i] = tot*0xffff;
2515 gamma_curve (1/2.4, 12.92, 1, 255);
2516 FORC3 memcpy (cur[c], curve, sizeof cur[0]);
2518 cinfo.err = jpeg_std_error (&jerr);
2519 jpeg_create_decompress (&cinfo);
2520 while (trow < raw_height) {
2521 fseek (ifp, save+=4, SEEK_SET);
2522 if (tile_length < INT_MAX)
2523 fseek (ifp, get4(), SEEK_SET);
2524 jpeg_stdio_src (&cinfo, ifp);
2525 jpeg_read_header (&cinfo, TRUE);
2526 jpeg_start_decompress (&cinfo);
2527 buf = (*cinfo.mem->alloc_sarray)
2528 ((j_common_ptr) &cinfo, JPOOL_IMAGE, cinfo.output_width*3, 1);
2529 while (cinfo.output_scanline < cinfo.output_height &&
2530 (row = trow + cinfo.output_scanline) < height) {
2531 jpeg_read_scanlines (&cinfo, buf, 1);
2532 pixel = (JSAMPLE (*)[3]) buf[0];
2533 for (col=0; col < cinfo.output_width && tcol+col < width; col++) {
2534 FORC3 image[row*width+tcol+col][c] = cur[c][pixel[col][c]];
2537 jpeg_abort_decompress (&cinfo);
2538 if ((tcol += tile_width) >= raw_width)
2539 trow += tile_length + (tcol = 0);
2541 jpeg_destroy_decompress (&cinfo);
2546 void CLASS kodak_dc120_load_raw()
2548 static const int mul[4] = { 162, 192, 187, 92 };
2549 static const int add[4] = { 0, 636, 424, 212 };
2551 int row, shift, col;
2553 for (row=0; row < height; row++) {
2554 if (fread (pixel, 1, 848, ifp) < 848) derror();
2555 shift = row * mul[row & 3] + add[row & 3];
2556 for (col=0; col < width; col++)
2557 RAW(row,col) = (ushort) pixel[(col + shift) % 848];
2562 void CLASS eight_bit_load_raw()
2567 pixel = (uchar *) calloc (raw_width, sizeof *pixel);
2568 merror (pixel, "eight_bit_load_raw()");
2569 for (row=0; row < raw_height; row++) {
2570 if (fread (pixel, 1, raw_width, ifp) < raw_width) derror();
2571 for (col=0; col < raw_width; col++)
2572 RAW(row,col) = curve[pixel[col]];
2575 maximum = curve[0xff];
2578 void CLASS kodak_c330_load_raw()
2581 int row, col, y, cb, cr, rgb[3], c;
2583 pixel = (uchar *) calloc (raw_width, 2*sizeof *pixel);
2584 merror (pixel, "kodak_c330_load_raw()");
2585 for (row=0; row < height; row++) {
2586 if (fread (pixel, raw_width, 2, ifp) < 2) derror();
2587 if (load_flags && (row & 31) == 31)
2588 fseek (ifp, raw_width*32, SEEK_CUR);
2589 for (col=0; col < width; col++) {
2591 cb = pixel[(col*2 & -4) | 1] - 128;
2592 cr = pixel[(col*2 & -4) | 3] - 128;
2593 rgb[1] = y - ((cb + cr + 2) >> 2);
2594 rgb[2] = rgb[1] + cb;
2595 rgb[0] = rgb[1] + cr;
2596 FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,255)];
2600 maximum = curve[0xff];
2603 void CLASS kodak_c603_load_raw()
2606 int row, col, y, cb, cr, rgb[3], c;
2608 pixel = (uchar *) calloc (raw_width, 3*sizeof *pixel);
2609 merror (pixel, "kodak_c603_load_raw()");
2610 for (row=0; row < height; row++) {
2612 if (fread (pixel, raw_width, 3, ifp) < 3) derror();
2613 for (col=0; col < width; col++) {
2614 y = pixel[width*2*(row & 1) + col];
2615 cb = pixel[width + (col & -2)] - 128;
2616 cr = pixel[width + (col & -2)+1] - 128;
2617 rgb[1] = y - ((cb + cr + 2) >> 2);
2618 rgb[2] = rgb[1] + cb;
2619 rgb[0] = rgb[1] + cr;
2620 FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,255)];
2624 maximum = curve[0xff];
2627 void CLASS kodak_262_load_raw()
2629 static const uchar kodak_tree[2][26] =
2630 { { 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 },
2631 { 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 } };
2634 int *strip, ns, c, row, col, chess, pi=0, pi1, pi2, pred, val;
2636 FORC(2) huff[c] = make_decoder (kodak_tree[c]);
2637 ns = (raw_height+63) >> 5;
2638 pixel = (uchar *) malloc (raw_width*32 + ns*4);
2639 merror (pixel, "kodak_262_load_raw()");
2640 strip = (int *) (pixel + raw_width*32);
2642 FORC(ns) strip[c] = get4();
2643 for (row=0; row < raw_height; row++) {
2644 if ((row & 31) == 0) {
2645 fseek (ifp, strip[row >> 5], SEEK_SET);
2649 for (col=0; col < raw_width; col++) {
2650 chess = (row + col) & 1;
2651 pi1 = chess ? pi-2 : pi-raw_width-1;
2652 pi2 = chess ? pi-2*raw_width : pi-raw_width+1;
2653 if (col <= chess) pi1 = -1;
2654 if (pi1 < 0) pi1 = pi2;
2655 if (pi2 < 0) pi2 = pi1;
2656 if (pi1 < 0 && col > 1) pi1 = pi2 = pi-2;
2657 pred = (pi1 < 0) ? 0 : (pixel[pi1] + pixel[pi2]) >> 1;
2658 pixel[pi] = val = pred + ljpeg_diff (huff[chess]);
2659 if (val >> 8) derror();
2660 val = curve[pixel[pi++]];
2665 FORC(2) free (huff[c]);
2668 int CLASS kodak_65000_decode (short *out, int bsize)
2673 int save, bits=0, i, j, len, diff;
2676 bsize = (bsize + 3) & -4;
2677 for (i=0; i < bsize; i+=2) {
2679 if ((blen[i ] = c & 15) > 12 ||
2680 (blen[i+1] = c >> 4) > 12 ) {
2681 fseek (ifp, save, SEEK_SET);
2682 for (i=0; i < bsize; i+=8) {
2683 read_shorts (raw, 6);
2684 out[i ] = raw[0] >> 12 << 8 | raw[2] >> 12 << 4 | raw[4] >> 12;
2685 out[i+1] = raw[1] >> 12 << 8 | raw[3] >> 12 << 4 | raw[5] >> 12;
2686 for (j=0; j < 6; j++)
2687 out[i+2+j] = raw[j] & 0xfff;
2692 if ((bsize & 7) == 4) {
2693 bitbuf = fgetc(ifp) << 8;
2694 bitbuf += fgetc(ifp);
2697 for (i=0; i < bsize; i++) {
2700 for (j=0; j < 32; j+=8)
2701 bitbuf += (INT64) fgetc(ifp) << (bits+(j^8));
2704 diff = bitbuf & (0xffff >> (16-len));
2707 if ((diff & (1 << (len-1))) == 0)
2708 diff -= (1 << len) - 1;
2714 void CLASS kodak_65000_load_raw()
2717 int row, col, len, pred[2], ret, i;
2719 for (row=0; row < height; row++)
2720 for (col=0; col < width; col+=256) {
2721 pred[0] = pred[1] = 0;
2722 len = MIN (256, width-col);
2723 ret = kodak_65000_decode (buf, len);
2724 for (i=0; i < len; i++)
2725 if ((RAW(row,col+i) = curve[ret ? buf[i] :
2726 (pred[i & 1] += buf[i])]) >> 12) derror();
2730 void CLASS kodak_ycbcr_load_raw()
2732 short buf[384], *bp;
2733 int row, col, len, c, i, j, k, y[2][2], cb, cr, rgb[3];
2737 for (row=0; row < height; row+=2)
2738 for (col=0; col < width; col+=128) {
2739 len = MIN (128, width-col);
2740 kodak_65000_decode (buf, len*3);
2741 y[0][1] = y[1][1] = cb = cr = 0;
2742 for (bp=buf, i=0; i < len; i+=2, bp+=2) {
2745 rgb[1] = -((cb + cr + 2) >> 2);
2746 rgb[2] = rgb[1] + cb;
2747 rgb[0] = rgb[1] + cr;
2748 for (j=0; j < 2; j++)
2749 for (k=0; k < 2; k++) {
2750 if ((y[j][k] = y[j][k^1] + *bp++) >> 10) derror();
2751 ip = image[(row+j)*width + col+i+k];
2752 FORC3 ip[c] = curve[LIM(y[j][k]+rgb[c], 0, 0xfff)];
2758 void CLASS kodak_rgb_load_raw()
2760 short buf[768], *bp;
2761 int row, col, len, c, i, rgb[3];
2762 ushort *ip=image[0];
2764 for (row=0; row < height; row++)
2765 for (col=0; col < width; col+=256) {
2766 len = MIN (256, width-col);
2767 kodak_65000_decode (buf, len*3);
2768 memset (rgb, 0, sizeof rgb);
2769 for (bp=buf, i=0; i < len; i++, ip+=4)
2770 FORC3 if ((ip[c] = rgb[c] += *bp++) >> 12) derror();
2774 void CLASS kodak_thumb_load_raw()
2777 colors = thumb_misc >> 5;
2778 for (row=0; row < height; row++)
2779 for (col=0; col < width; col++)
2780 read_shorts (image[row*width+col], colors);
2781 maximum = (1 << (thumb_misc & 31)) - 1;
2784 void CLASS sony_decrypt (unsigned *data, int len, int start, int key)
2786 static unsigned pad[128], p;
2789 for (p=0; p < 4; p++)
2790 pad[p] = key = key * 48828125 + 1;
2791 pad[3] = pad[3] << 1 | (pad[0]^pad[2]) >> 31;
2792 for (p=4; p < 127; p++)
2793 pad[p] = (pad[p-4]^pad[p-2]) << 1 | (pad[p-3]^pad[p-1]) >> 31;
2794 for (p=0; p < 127; p++)
2795 pad[p] = htonl(pad[p]);
2797 while (len-- && p++)
2798 *data++ ^= pad[(p-1) & 127] = pad[p & 127] ^ pad[(p+64) & 127];
2801 void CLASS sony_load_raw()
2805 unsigned i, key, row, col;
2807 fseek (ifp, 200896, SEEK_SET);
2808 fseek (ifp, (unsigned) fgetc(ifp)*4 - 1, SEEK_CUR);
2811 fseek (ifp, 164600, SEEK_SET);
2812 fread (head, 1, 40, ifp);
2813 sony_decrypt ((unsigned *) head, 10, 1, key);
2814 for (i=26; i-- > 22; )
2815 key = key << 8 | head[i];
2816 fseek (ifp, data_offset, SEEK_SET);
2817 for (row=0; row < raw_height; row++) {
2818 pixel = raw_image + row*raw_width;
2819 if (fread (pixel, 2, raw_width, ifp) < raw_width) derror();
2820 sony_decrypt ((unsigned *) pixel, raw_width/2, !row, key);
2821 for (col=0; col < raw_width; col++)
2822 if ((pixel[col] = ntohs(pixel[col])) >> 14) derror();
2827 void CLASS sony_arw_load_raw()
2830 static const ushort tab[18] =
2831 { 0xf11,0xf10,0xe0f,0xd0e,0xc0d,0xb0c,0xa0b,0x90a,0x809,
2832 0x708,0x607,0x506,0x405,0x304,0x303,0x300,0x202,0x201 };
2833 int i, c, n, col, row, sum=0;
2836 for (n=i=0; i < 18; i++)
2837 FORC(32768 >> (tab[i] >> 8)) huff[++n] = tab[i];
2839 for (col = raw_width; col--; )
2840 for (row=0; row < raw_height+1; row+=2) {
2841 if (row == raw_height) row = 1;
2842 if ((sum += ljpeg_diff(huff)) >> 12) derror();
2843 if (row < height) RAW(row,col) = sum;
2847 void CLASS sony_arw2_load_raw()
2851 int row, col, val, max, min, imax, imin, sh, bit, i;
2853 data = (uchar *) malloc (raw_width+1);
2854 merror (data, "sony_arw2_load_raw()");
2855 for (row=0; row < height; row++) {
2856 fread (data, 1, raw_width, ifp);
2857 for (dp=data, col=0; col < raw_width-30; dp+=16) {
2858 max = 0x7ff & (val = sget4(dp));
2859 min = 0x7ff & val >> 11;
2860 imax = 0x0f & val >> 22;
2861 imin = 0x0f & val >> 26;
2862 for (sh=0; sh < 4 && 0x80 << sh <= max-min; sh++);
2863 for (bit=30, i=0; i < 16; i++)
2864 if (i == imax) pix[i] = max;
2865 else if (i == imin) pix[i] = min;
2867 pix[i] = ((sget2(dp+(bit >> 3)) >> (bit & 7) & 0x7f) << sh) + min;
2868 if (pix[i] > 0x7ff) pix[i] = 0x7ff;
2871 for (i=0; i < 16; i++, col+=2)
2872 RAW(row,col) = curve[pix[i] << 1] >> 2;
2873 col -= col & 1 ? 1:31;
2879 void CLASS samsung_load_raw()
2881 int row, col, c, i, dir, op[4], len[4];
2884 for (row=0; row < raw_height; row++) {
2885 fseek (ifp, strip_offset+row*4, SEEK_SET);
2886 fseek (ifp, data_offset+get4(), SEEK_SET);
2888 FORC4 len[c] = row < 2 ? 7:4;
2889 for (col=0; col < raw_width; col+=16) {
2891 FORC4 op[c] = ph1_bits(2);
2892 FORC4 switch (op[c]) {
2893 case 3: len[c] = ph1_bits(4); break;
2894 case 2: len[c]--; break;
2897 for (c=0; c < 16; c+=2) {
2898 i = len[((c & 1) << 1) | (c >> 3)];
2899 RAW(row,col+c) = ((signed) ph1_bits(i) << (32-i) >> (32-i)) +
2900 (dir ? RAW(row+(~c | -2),col+c) : col ? RAW(row,col+(c | -2)) : 128);
2901 if (c == 14) c = -1;
2905 for (row=0; row < raw_height-1; row+=2)
2906 for (col=0; col < raw_width-1; col+=2)
2907 SWAP (RAW(row,col+1), RAW(row+1,col));
2910 void CLASS samsung2_load_raw()
2912 static const ushort tab[14] =
2913 { 0x304,0x307,0x206,0x205,0x403,0x600,0x709,
2914 0x80a,0x90b,0xa0c,0xa0d,0x501,0x408,0x402 };
2915 ushort huff[1026], vpred[2][2] = {{0,0},{0,0}}, hpred[2];
2916 int i, c, n, row, col, diff;
2919 for (n=i=0; i < 14; i++)
2920 FORC(1024 >> (tab[i] >> 8)) huff[++n] = tab[i];
2922 for (row=0; row < raw_height; row++)
2923 for (col=0; col < raw_width; col++) {
2924 diff = ljpeg_diff (huff);
2925 if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
2926 else hpred[col & 1] += diff;
2927 RAW(row,col) = hpred[col & 1];
2928 if (hpred[col & 1] >> tiff_bps) derror();
2932 void CLASS samsung3_load_raw()
2934 int opt, init, mag, pmode, row, tab, col, pred, diff, i, c;
2935 ushort lent[3][2], len[4], *prow[2];
2938 fseek (ifp, 9, SEEK_CUR);
2940 init = (get2(),get2());
2941 for (row=0; row < raw_height; row++) {
2942 fseek (ifp, (data_offset-ftell(ifp)) & 15, SEEK_CUR);
2945 FORC(6) ((ushort *)lent)[c] = row < 2 ? 7:4;
2946 prow[ row & 1] = &RAW(row-1,1-((row & 1) << 1)); // green
2947 prow[~row & 1] = &RAW(row-2,0); // red and blue
2948 for (tab=0; tab+15 < raw_width; tab+=16) {
2949 if (~opt & 4 && !(tab & 63)) {
2951 mag = i < 3 ? mag-'2'+"204"[i] : ph1_bits(12);
2954 pmode = 7 - 4*ph1_bits(1);
2955 else if (!ph1_bits(1))
2956 pmode = ph1_bits(3);
2957 if (opt & 1 || !ph1_bits(1)) {
2958 FORC4 len[c] = ph1_bits(2);
2960 i = ((row & 1) << 1 | (c & 1)) % 3;
2961 len[c] = len[c] < 3 ? lent[i][0]-'1'+"120"[len[c]] : ph1_bits(4);
2962 lent[i][0] = lent[i][1];
2963 lent[i][1] = len[c];
2967 col = tab + (((c & 7) << 1)^(c >> 3)^(row & 1));
2968 pred = (pmode == 7 || row < 2)
2969 ? (tab ? RAW(row,tab-2+(col & 1)) : init)
2970 : (prow[col & 1][col-'4'+"0224468"[pmode]] +
2971 prow[col & 1][col-'4'+"0244668"[pmode]] + 1) >> 1;
2972 diff = ph1_bits (i = len[c >> 2]);
2973 if (diff >> (i-1)) diff -= 1 << i;
2974 diff = diff * (mag*2+1) + mag;
2975 RAW(row,col) = pred + diff;
2981 #define HOLE(row) ((holes >> (((row) - raw_height) & 7)) & 1)
2983 /* Kudos to Rich Taylor for figuring out SMaL's compression algorithm. */
2984 void CLASS smal_decode_segment (unsigned seg[2][2], int holes)
2987 uchar hist[3][18] = {
2988 { 7, 7, 0, 0, 63, 55, 47, 39, 31, 23, 15, 7, 0 },
2989 { 7, 7, 0, 0, 63, 55, 47, 39, 31, 23, 15, 7, 0 },
2990 { 3, 3, 0, 0, 63, 47, 31, 15, 0 } };
2991 int low, high=0xff, carry=0, nbits=8;
2992 int pix, s, count, bin, next, i, sym[3];
2993 uchar diff, pred[]={0,0};
2994 ushort data=0, range=0;
2996 fseek (ifp, seg[0][1]+1, SEEK_SET);
2998 if (seg[1][0] > raw_width*raw_height)
2999 seg[1][0] = raw_width*raw_height;
3000 for (pix=seg[0][0]; pix < seg[1][0]; pix++) {
3001 for (s=0; s < 3; s++) {
3002 data = data << nbits | getbits(nbits);
3004 carry = (nbits += carry+1) < 1 ? nbits-1 : 0;
3005 while (--nbits >= 0)
3006 if ((data >> nbits & 0xff) == 0xff) break;
3008 data = ((data & ((1 << (nbits-1)) - 1)) << 1) |
3009 ((data + (((data & (1 << (nbits-1)))) << 1)) & (-1 << nbits));
3014 count = ((((data-range+1) & 0xffff) << 2) - 1) / (high >> 4);
3015 for (bin=0; hist[s][bin+5] > count; bin++);
3016 low = hist[s][bin+5] * (high >> 4) >> 2;
3017 if (bin) high = hist[s][bin+4] * (high >> 4) >> 2;
3019 for (nbits=0; high << nbits < 128; nbits++);
3020 range = (range+low) << nbits;
3023 if (++hist[s][2] > hist[s][3]) {
3024 next = (next+1) & hist[s][0];
3025 hist[s][3] = (hist[s][next+4] - hist[s][next+5]) >> 2;
3028 if (hist[s][hist[s][1]+4] - hist[s][hist[s][1]+5] > 1) {
3029 if (bin < hist[s][1])
3030 for (i=bin; i < hist[s][1]; i++) hist[s][i+5]--;
3031 else if (next <= bin)
3032 for (i=hist[s][1]; i < bin; i++) hist[s][i+5]++;
3037 diff = sym[2] << 5 | sym[1] << 2 | (sym[0] & 3);
3039 diff = diff ? -diff : 0x80;
3040 if (ftell(ifp) + 12 >= seg[1][1])
3042 raw_image[pix] = pred[pix & 1] += diff;
3043 if (!(pix & 1) && HOLE(pix / raw_width)) pix += 2;
3048 void CLASS smal_v6_load_raw()
3052 fseek (ifp, 16, SEEK_SET);
3055 seg[1][0] = raw_width * raw_height;
3056 seg[1][1] = INT_MAX;
3057 smal_decode_segment (seg, 0);
3060 int CLASS median4 (int *p)
3062 int min, max, sum, i;
3064 min = max = sum = p[0];
3065 for (i=1; i < 4; i++) {
3067 if (min > p[i]) min = p[i];
3068 if (max < p[i]) max = p[i];
3070 return (sum - min - max) >> 1;
3073 void CLASS fill_holes (int holes)
3075 int row, col, val[4];
3077 for (row=2; row < height-2; row++) {
3078 if (!HOLE(row)) continue;
3079 for (col=1; col < width-1; col+=4) {
3080 val[0] = RAW(row-1,col-1);
3081 val[1] = RAW(row-1,col+1);
3082 val[2] = RAW(row+1,col-1);
3083 val[3] = RAW(row+1,col+1);
3084 RAW(row,col) = median4(val);
3086 for (col=2; col < width-2; col+=4)
3087 if (HOLE(row-2) || HOLE(row+2))
3088 RAW(row,col) = (RAW(row,col-2) + RAW(row,col+2)) >> 1;
3090 val[0] = RAW(row,col-2);
3091 val[1] = RAW(row,col+2);
3092 val[2] = RAW(row-2,col);
3093 val[3] = RAW(row+2,col);
3094 RAW(row,col) = median4(val);
3099 void CLASS smal_v9_load_raw()
3101 unsigned seg[256][2], offset, nseg, holes, i;
3103 fseek (ifp, 67, SEEK_SET);
3105 nseg = (uchar) fgetc(ifp);
3106 fseek (ifp, offset, SEEK_SET);
3107 for (i=0; i < nseg*2; i++)
3108 ((unsigned *)seg)[i] = get4() + data_offset*(i & 1);
3109 fseek (ifp, 78, SEEK_SET);
3111 fseek (ifp, 88, SEEK_SET);
3112 seg[nseg][0] = raw_height * raw_width;
3113 seg[nseg][1] = get4() + data_offset;
3114 for (i=0; i < nseg; i++)
3115 smal_decode_segment (seg+i, holes);
3116 if (holes) fill_holes (holes);
3119 void CLASS redcine_load_raw()
3130 in = jas_stream_fopen (ifname, "rb");
3131 jas_stream_seek (in, data_offset+20, SEEK_SET);
3132 jimg = jas_image_decode (in, -1, 0);
3133 if (!jimg) longjmp (failure, 3);
3134 jmat = jas_matrix_create (height/2, width/2);
3135 merror (jmat, "redcine_load_raw()");
3136 img = (ushort *) calloc ((height+2), (width+2)*2);
3137 merror (img, "redcine_load_raw()");
3139 jas_image_readcmpt (jimg, c, 0, 0, width/2, height/2, jmat);
3140 data = jas_matrix_getref (jmat, 0, 0);
3141 for (row = c >> 1; row < height; row+=2)
3142 for (col = c & 1; col < width; col+=2)
3143 img[(row+1)*(width+2)+col+1] = data[(row/2)*(width/2)+col/2];
3145 for (col=1; col <= width; col++) {
3146 img[col] = img[2*(width+2)+col];
3147 img[(height+1)*(width+2)+col] = img[(height-1)*(width+2)+col];
3149 for (row=0; row < height+2; row++) {
3150 img[row*(width+2)] = img[row*(width+2)+2];
3151 img[(row+1)*(width+2)-1] = img[(row+1)*(width+2)-3];
3153 for (row=1; row <= height; row++) {
3154 pix = img + row*(width+2) + (col = 1 + (FC(row,1) & 1));
3155 for ( ; col <= width; col+=2, pix+=2) {
3156 c = (((pix[0] - 0x800) << 3) +
3157 pix[-(width+2)] + pix[width+2] + pix[-1] + pix[1]) >> 2;
3158 pix[0] = LIM(c,0,4095);
3161 for (row=0; row < height; row++)
3162 for (col=0; col < width; col++)
3163 RAW(row,col) = curve[img[(row+1)*(width+2)+col+1]];
3165 jas_matrix_destroy (jmat);
3166 jas_image_destroy (jimg);
3167 jas_stream_close (in);
3171 /* RESTRICTED code starts here */
3173 void CLASS foveon_decoder (unsigned size, unsigned code)
3175 static unsigned huff[1024];
3180 for (i=0; i < size; i++)
3182 memset (first_decode, 0, sizeof first_decode);
3183 free_decode = first_decode;
3185 cur = free_decode++;
3186 if (free_decode > first_decode+2048) {
3187 fprintf (stderr,_("%s: decoder table overflow\n"), ifname);
3188 longjmp (failure, 2);
3191 for (i=0; i < size; i++)
3192 if (huff[i] == code) {
3196 if ((len = code >> 27) > 26) return;
3197 code = (len+1) << 27 | (code & 0x3ffffff) << 1;
3199 cur->branch[0] = free_decode;
3200 foveon_decoder (size, code);
3201 cur->branch[1] = free_decode;
3202 foveon_decoder (size, code+1);
3205 void CLASS foveon_thumb()
3207 unsigned bwide, row, col, bitbuf=0, bit=1, c, i;
3209 struct decode *dindex;
3213 fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
3215 if (bwide < thumb_width*3) return;
3216 buf = (char *) malloc (bwide);
3217 merror (buf, "foveon_thumb()");
3218 for (row=0; row < thumb_height; row++) {
3219 fread (buf, 1, bwide, ifp);
3220 fwrite (buf, 3, thumb_width, ofp);
3225 foveon_decoder (256, 0);
3227 for (row=0; row < thumb_height; row++) {
3228 memset (pred, 0, sizeof pred);
3230 for (bit=col=0; col < thumb_width; col++)
3232 for (dindex=first_decode; dindex->branch[0]; ) {
3233 if ((bit = (bit-1) & 31) == 31)
3234 for (i=0; i < 4; i++)
3235 bitbuf = (bitbuf << 8) + fgetc(ifp);
3236 dindex = dindex->branch[bitbuf >> bit & 1];
3238 pred[c] += dindex->leaf;
3239 fputc (pred[c], ofp);
3244 void CLASS foveon_sd_load_raw()
3246 struct decode *dindex;
3249 int pred[3], row, col, bit=-1, c, i;
3251 read_shorts ((ushort *) diff, 1024);
3252 if (!load_flags) foveon_decoder (1024, 0);
3254 for (row=0; row < height; row++) {
3255 memset (pred, 0, sizeof pred);
3256 if (!bit && !load_flags && atoi(model+2) < 14) get4();
3257 for (col=bit=0; col < width; col++) {
3260 FORC3 pred[2-c] += diff[bitbuf >> c*10 & 0x3ff];
3263 for (dindex=first_decode; dindex->branch[0]; ) {
3264 if ((bit = (bit-1) & 31) == 31)
3265 for (i=0; i < 4; i++)
3266 bitbuf = (bitbuf << 8) + fgetc(ifp);
3267 dindex = dindex->branch[bitbuf >> bit & 1];
3269 pred[c] += diff[dindex->leaf];
3270 if (pred[c] >> 16 && ~pred[c] >> 16) derror();
3272 FORC3 image[row*width+col][c] = pred[c];
3277 void CLASS foveon_huff (ushort *huff)
3279 int i, j, clen, code;
3282 for (i=0; i < 13; i++) {
3285 for (j=0; j < 256 >> clen; )
3286 huff[code+ ++j] = clen << 8 | i;
3291 void CLASS foveon_dp_load_raw()
3293 unsigned c, roff[4], row, col, diff;
3294 ushort huff[512], vpred[2][2], hpred[2];
3296 fseek (ifp, 8, SEEK_CUR);
3299 FORC3 roff[c+1] = -(-(roff[c] + get4()) & -16);
3301 fseek (ifp, data_offset+roff[c], SEEK_SET);
3303 vpred[0][0] = vpred[0][1] = vpred[1][0] = vpred[1][1] = 512;
3304 for (row=0; row < height; row++) {
3305 for (col=0; col < width; col++) {
3306 diff = ljpeg_diff(huff);
3307 if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
3308 else hpred[col & 1] += diff;
3309 image[row*width+col][c] = hpred[col & 1];
3315 void CLASS foveon_load_camf()
3317 unsigned type, wide, high, i, j, row, col, diff;
3318 ushort huff[258], vpred[2][2] = {{512,512},{512,512}}, hpred[2];
3320 fseek (ifp, meta_offset, SEEK_SET);
3321 type = get4(); get4(); get4();
3325 fread (meta_data, 1, meta_length, ifp);
3326 for (i=0; i < meta_length; i++) {
3327 high = (high * 1597 + 51749) % 244944;
3328 wide = high * (INT64) 301593171 >> 24;
3329 meta_data[i] ^= ((((high << 8) - wide) >> 1) + wide) >> 17;
3331 } else if (type == 4) {
3333 meta_data = (char *) malloc (meta_length = wide*high*3/2);
3334 merror (meta_data, "foveon_load_camf()");
3338 for (j=row=0; row < high; row++) {
3339 for (col=0; col < wide; col++) {
3340 diff = ljpeg_diff(huff);
3341 if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
3342 else hpred[col & 1] += diff;
3344 meta_data[j++] = hpred[0] >> 4;
3345 meta_data[j++] = hpred[0] << 4 | hpred[1] >> 8;
3346 meta_data[j++] = hpred[1];
3351 fprintf (stderr,_("%s has unknown CAMF type %d.\n"), ifname, type);
3354 const char * CLASS foveon_camf_param (const char *block, const char *param)
3357 char *pos, *cp, *dp;
3359 for (idx=0; idx < meta_length; idx += sget4(pos+8)) {
3360 pos = meta_data + idx;
3361 if (strncmp (pos, "CMb", 3)) break;
3362 if (pos[3] != 'P') continue;
3363 if (strcmp (block, pos+sget4(pos+12))) continue;
3364 cp = pos + sget4(pos+16);
3366 dp = pos + sget4(cp+4);
3369 if (!strcmp (param, dp+sget4(cp)))
3370 return dp+sget4(cp+4);
3376 void * CLASS foveon_camf_matrix (unsigned dim[3], const char *name)
3378 unsigned i, idx, type, ndim, size, *mat;
3379 char *pos, *cp, *dp;
3382 for (idx=0; idx < meta_length; idx += sget4(pos+8)) {
3383 pos = meta_data + idx;
3384 if (strncmp (pos, "CMb", 3)) break;
3385 if (pos[3] != 'M') continue;
3386 if (strcmp (name, pos+sget4(pos+12))) continue;
3387 dim[0] = dim[1] = dim[2] = 1;
3388 cp = pos + sget4(pos+16);
3390 if ((ndim = sget4(cp+4)) > 3) break;
3391 dp = pos + sget4(cp+8);
3392 for (i=ndim; i--; ) {
3396 if ((dsize = (double) dim[0]*dim[1]*dim[2]) > meta_length/4) break;
3397 mat = (unsigned *) malloc ((size = dsize) * 4);
3398 merror (mat, "foveon_camf_matrix()");
3399 for (i=0; i < size; i++)
3400 if (type && type != 6)
3401 mat[i] = sget4(dp + i*4);
3403 mat[i] = sget4(dp + i*2) & 0xffff;
3406 fprintf (stderr,_("%s: \"%s\" matrix not found!\n"), ifname, name);
3410 int CLASS foveon_fixed (void *ptr, int size, const char *name)
3415 if (!name) return 0;
3416 dp = foveon_camf_matrix (dim, name);
3418 memcpy (ptr, dp, size*4);
3423 float CLASS foveon_avg (short *pix, int range[2], float cfilt)
3426 float val, min=FLT_MAX, max=-FLT_MAX, sum=0;
3428 for (i=range[0]; i <= range[1]; i++) {
3429 sum += val = pix[i*4] + (pix[i*4]-pix[(i-1)*4]) * cfilt;
3430 if (min > val) min = val;
3431 if (max < val) max = val;
3433 if (range[1] - range[0] == 1) return sum/2;
3434 return (sum - min - max) / (range[1] - range[0] - 1);
3437 short * CLASS foveon_make_curve (double max, double mul, double filt)
3443 if (!filt) filt = 0.8;
3444 size = 4*M_PI*max / filt;
3445 if (size == UINT_MAX) size--;
3446 curve = (short *) calloc (size+1, sizeof *curve);
3447 merror (curve, "foveon_make_curve()");
3449 for (i=0; i < size; i++) {
3451 curve[i+1] = (cos(x)+1)/2 * tanh(i*filt/mul) * mul + 0.5;
3456 void CLASS foveon_make_curves
3457 (short **curvep, float dq[3], float div[3], float filt)
3459 double mul[3], max=0;
3462 FORC3 mul[c] = dq[c]/div[c];
3463 FORC3 if (max < mul[c]) max = mul[c];
3464 FORC3 curvep[c] = foveon_make_curve (max, mul[c], filt);
3467 int CLASS foveon_apply_curve (short *curve, int i)
3469 if (abs(i) >= curve[0]) return 0;
3470 return i < 0 ? -curve[1-i] : curve[1+i];
3473 #define image ((short (*)[4]) image)
3475 void CLASS foveon_interpolate()
3477 static const short hood[] = { -1,-1, -1,0, -1,1, 0,-1, 0,1, 1,-1, 1,0, 1,1 };
3478 short *pix, prev[3], *curve[8], (*shrink)[3];
3479 float cfilt=0, ddft[3][3][2], ppm[3][3][3];
3480 float cam_xyz[3][3], correct[3][3], last[3][3], trans[3][3];
3481 float chroma_dq[3], color_dq[3], diag[3][3], div[3];
3482 float (*black)[3], (*sgain)[3], (*sgrow)[3];
3483 float fsum[3], val, frow, num;
3484 int row, col, c, i, j, diff, sgx, irow, sum, min, max, limit;
3485 int dscr[2][2], dstb[4], (*smrow[7])[3], total[4], ipix[3];
3486 int work[3][3], smlast, smred, smred_p=0, dev[3];
3487 int satlev[3], keep[4], active[4];
3488 unsigned dim[3], *badpix;
3489 double dsum=0, trsum[3];
3494 fprintf (stderr,_("Foveon interpolation...\n"));
3497 foveon_fixed (dscr, 4, "DarkShieldColRange");
3498 foveon_fixed (ppm[0][0], 27, "PostPolyMatrix");
3499 foveon_fixed (satlev, 3, "SaturationLevel");
3500 foveon_fixed (keep, 4, "KeepImageArea");
3501 foveon_fixed (active, 4, "ActiveImageArea");
3502 foveon_fixed (chroma_dq, 3, "ChromaDQ");
3503 foveon_fixed (color_dq, 3,
3504 foveon_camf_param ("IncludeBlocks", "ColorDQ") ?
3505 "ColorDQ" : "ColorDQCamRGB");
3506 if (foveon_camf_param ("IncludeBlocks", "ColumnFilter"))
3507 foveon_fixed (&cfilt, 1, "ColumnFilter");
3509 memset (ddft, 0, sizeof ddft);
3510 if (!foveon_camf_param ("IncludeBlocks", "DarkDrift")
3511 || !foveon_fixed (ddft[1][0], 12, "DarkDrift"))
3512 for (i=0; i < 2; i++) {
3513 foveon_fixed (dstb, 4, i ? "DarkShieldBottom":"DarkShieldTop");
3514 for (row = dstb[1]; row <= dstb[3]; row++)
3515 for (col = dstb[0]; col <= dstb[2]; col++)
3516 FORC3 ddft[i+1][c][1] += (short) image[row*width+col][c];
3517 FORC3 ddft[i+1][c][1] /= (dstb[3]-dstb[1]+1) * (dstb[2]-dstb[0]+1);
3520 if (!(cp = foveon_camf_param ("WhiteBalanceIlluminants", model2)))
3521 { fprintf (stderr,_("%s: Invalid white balance \"%s\"\n"), ifname, model2);
3523 foveon_fixed (cam_xyz, 9, cp);
3524 foveon_fixed (correct, 9,
3525 foveon_camf_param ("WhiteBalanceCorrections", model2));
3526 memset (last, 0, sizeof last);
3527 for (i=0; i < 3; i++)
3528 for (j=0; j < 3; j++)
3529 FORC3 last[i][j] += correct[i][c] * cam_xyz[c][j];
3531 #define LAST(x,y) last[(i+x)%3][(c+y)%3]
3532 for (i=0; i < 3; i++)
3533 FORC3 diag[c][i] = LAST(1,1)*LAST(2,2) - LAST(1,2)*LAST(2,1);
3535 FORC3 div[c] = diag[c][0]*0.3127 + diag[c][1]*0.329 + diag[c][2]*0.3583;
3536 sprintf (str, "%sRGBNeutral", model2);
3537 if (foveon_camf_param ("IncludeBlocks", str))
3538 foveon_fixed (div, 3, str);
3540 FORC3 if (num < div[c]) num = div[c];
3541 FORC3 div[c] /= num;
3543 memset (trans, 0, sizeof trans);
3544 for (i=0; i < 3; i++)
3545 for (j=0; j < 3; j++)
3546 FORC3 trans[i][j] += rgb_cam[i][c] * last[c][j] * div[j];
3547 FORC3 trsum[c] = trans[c][0] + trans[c][1] + trans[c][2];
3548 dsum = (6*trsum[0] + 11*trsum[1] + 3*trsum[2]) / 20;
3549 for (i=0; i < 3; i++)
3550 FORC3 last[i][c] = trans[i][c] * dsum / trsum[i];
3551 memset (trans, 0, sizeof trans);
3552 for (i=0; i < 3; i++)
3553 for (j=0; j < 3; j++)
3554 FORC3 trans[i][j] += (i==c ? 32 : -1) * last[c][j] / 30;
3556 foveon_make_curves (curve, color_dq, div, cfilt);
3557 FORC3 chroma_dq[c] /= 3;
3558 foveon_make_curves (curve+3, chroma_dq, div, cfilt);
3559 FORC3 dsum += chroma_dq[c] / div[c];
3560 curve[6] = foveon_make_curve (dsum, dsum, cfilt);
3561 curve[7] = foveon_make_curve (dsum*2, dsum*2, cfilt);
3563 sgain = (float (*)[3]) foveon_camf_matrix (dim, "SpatialGain");
3565 sgrow = (float (*)[3]) calloc (dim[1], sizeof *sgrow);
3566 sgx = (width + dim[1]-2) / (dim[1]-1);
3568 black = (float (*)[3]) calloc (height, sizeof *black);
3569 for (row=0; row < height; row++) {
3570 for (i=0; i < 6; i++)
3571 ((float *)ddft[0])[i] = ((float *)ddft[1])[i] +
3572 row / (height-1.0) * (((float *)ddft[2])[i] - ((float *)ddft[1])[i]);
3573 FORC3 black[row][c] =
3574 ( foveon_avg (image[row*width]+c, dscr[0], cfilt) +
3575 foveon_avg (image[row*width]+c, dscr[1], cfilt) * 3
3576 - ddft[0][c][0] ) / 4 - ddft[0][c][1];
3578 memcpy (black, black+8, sizeof *black*8);
3579 memcpy (black+height-11, black+height-22, 11*sizeof *black);
3580 memcpy (last, black, sizeof last);
3582 for (row=1; row < height-1; row++) {
3583 FORC3 if (last[1][c] > last[0][c]) {
3584 if (last[1][c] > last[2][c])
3585 black[row][c] = (last[0][c] > last[2][c]) ? last[0][c]:last[2][c];
3587 if (last[1][c] < last[2][c])
3588 black[row][c] = (last[0][c] < last[2][c]) ? last[0][c]:last[2][c];
3589 memmove (last, last+1, 2*sizeof last[0]);
3590 memcpy (last[2], black[row+1], sizeof last[2]);
3592 FORC3 black[row][c] = (last[0][c] + last[1][c])/2;
3593 FORC3 black[0][c] = (black[1][c] + black[3][c])/2;
3595 val = 1 - exp(-1/24.0);
3596 memcpy (fsum, black, sizeof fsum);
3597 for (row=1; row < height; row++)
3598 FORC3 fsum[c] += black[row][c] =
3599 (black[row][c] - black[row-1][c])*val + black[row-1][c];
3600 memcpy (last[0], black[height-1], sizeof last[0]);
3601 FORC3 fsum[c] /= height;
3602 for (row = height; row--; )
3603 FORC3 last[0][c] = black[row][c] =
3604 (black[row][c] - fsum[c] - last[0][c])*val + last[0][c];
3606 memset (total, 0, sizeof total);
3607 for (row=2; row < height; row+=4)
3608 for (col=2; col < width; col+=4) {
3609 FORC3 total[c] += (short) image[row*width+col][c];
3612 for (row=0; row < height; row++)
3613 FORC3 black[row][c] += fsum[c]/2 + total[c]/(total[3]*100.0);
3615 for (row=0; row < height; row++) {
3616 for (i=0; i < 6; i++)
3617 ((float *)ddft[0])[i] = ((float *)ddft[1])[i] +
3618 row / (height-1.0) * (((float *)ddft[2])[i] - ((float *)ddft[1])[i]);
3619 pix = image[row*width];
3620 memcpy (prev, pix, sizeof prev);
3621 frow = row / (height-1.0) * (dim[2]-1);
3622 if ((irow = frow) == dim[2]-1) irow--;
3624 for (i=0; i < dim[1]; i++)
3625 FORC3 sgrow[i][c] = sgain[ irow *dim[1]+i][c] * (1-frow) +
3626 sgain[(irow+1)*dim[1]+i][c] * frow;
3627 for (col=0; col < width; col++) {
3629 diff = pix[c] - prev[c];
3631 ipix[c] = pix[c] + floor ((diff + (diff*diff >> 14)) * cfilt
3632 - ddft[0][c][1] - ddft[0][c][0] * ((float) col/width - 0.5)
3636 work[0][c] = ipix[c] * ipix[c] >> 14;
3637 work[2][c] = ipix[c] * work[0][c] >> 14;
3638 work[1][2-c] = ipix[(c+1) % 3] * ipix[(c+2) % 3] >> 14;
3641 for (val=i=0; i < 3; i++)
3642 for ( j=0; j < 3; j++)
3643 val += ppm[c][i][j] * work[i][j];
3644 ipix[c] = floor ((ipix[c] + floor(val)) *
3645 ( sgrow[col/sgx ][c] * (sgx - col%sgx) +
3646 sgrow[col/sgx+1][c] * (col%sgx) ) / sgx / div[c]);
3647 if (ipix[c] > 32000) ipix[c] = 32000;
3657 if ((badpix = (unsigned *) foveon_camf_matrix (dim, "BadPixels"))) {
3658 for (i=0; i < dim[0]; i++) {
3659 col = (badpix[i] >> 8 & 0xfff) - keep[0];
3660 row = (badpix[i] >> 20 ) - keep[1];
3661 if ((unsigned)(row-1) > height-3 || (unsigned)(col-1) > width-3)
3663 memset (fsum, 0, sizeof fsum);
3664 for (sum=j=0; j < 8; j++)
3665 if (badpix[i] & (1 << j)) {
3666 FORC3 fsum[c] += (short)
3667 image[(row+hood[j*2])*width+col+hood[j*2+1]][c];
3670 if (sum) FORC3 image[row*width+col][c] = fsum[c]/sum;
3675 /* Array for 5x5 Gaussian averaging of red values */
3676 smrow[6] = (int (*)[3]) calloc (width*5, sizeof **smrow);
3677 merror (smrow[6], "foveon_interpolate()");
3678 for (i=0; i < 5; i++)
3679 smrow[i] = smrow[6] + i*width;
3681 /* Sharpen the reds against these Gaussian averages */
3682 for (smlast=-1, row=2; row < height-2; row++) {
3683 while (smlast < row+2) {
3684 for (i=0; i < 6; i++)
3685 smrow[(i+5) % 6] = smrow[i];
3686 pix = image[++smlast*width+2];
3687 for (col=2; col < width-2; col++) {
3689 (pix[0]*6 + (pix[-4]+pix[4])*4 + pix[-8]+pix[8] + 8) >> 4;
3693 pix = image[row*width+2];
3694 for (col=2; col < width-2; col++) {
3695 smred = ( 6 * smrow[2][col][0]
3696 + 4 * (smrow[1][col][0] + smrow[3][col][0])
3697 + smrow[0][col][0] + smrow[4][col][0] + 8 ) >> 4;
3700 i = pix[0] + ((pix[0] - ((smred*7 + smred_p) >> 3)) >> 3);
3701 if (i > 32000) i = 32000;
3708 /* Adjust the brighter pixels for better linearity */
3711 i = satlev[c] / div[c];
3712 if (min > i) min = i;
3714 limit = min * 9 >> 4;
3715 for (pix=image[0]; pix < image[height*width]; pix+=4) {
3716 if (pix[0] <= limit || pix[1] <= limit || pix[2] <= limit)
3719 for (c=1; c < 3; c++) {
3720 if (min > pix[c]) min = pix[c];
3721 if (max < pix[c]) max = pix[c];
3723 if (min >= limit*2) {
3724 pix[0] = pix[1] = pix[2] = max;
3726 i = 0x4000 - ((min - limit) << 14) / limit;
3727 i = 0x4000 - (i*i >> 14);
3729 FORC3 pix[c] += (max - pix[c]) * i >> 14;
3733 Because photons that miss one detector often hit another,
3734 the sum R+G+B is much less noisy than the individual colors.
3735 So smooth the hues without smoothing the total.
3737 for (smlast=-1, row=2; row < height-2; row++) {
3738 while (smlast < row+2) {
3739 for (i=0; i < 6; i++)
3740 smrow[(i+5) % 6] = smrow[i];
3741 pix = image[++smlast*width+2];
3742 for (col=2; col < width-2; col++) {
3743 FORC3 smrow[4][col][c] = (pix[c-4]+2*pix[c]+pix[c+4]+2) >> 2;
3747 pix = image[row*width+2];
3748 for (col=2; col < width-2; col++) {
3749 FORC3 dev[c] = -foveon_apply_curve (curve[7], pix[c] -
3750 ((smrow[1][col][c] + 2*smrow[2][col][c] + smrow[3][col][c]) >> 2));
3751 sum = (dev[0] + dev[1] + dev[2]) >> 3;
3752 FORC3 pix[c] += dev[c] - sum;
3756 for (smlast=-1, row=2; row < height-2; row++) {
3757 while (smlast < row+2) {
3758 for (i=0; i < 6; i++)
3759 smrow[(i+5) % 6] = smrow[i];
3760 pix = image[++smlast*width+2];
3761 for (col=2; col < width-2; col++) {
3762 FORC3 smrow[4][col][c] =
3763 (pix[c-8]+pix[c-4]+pix[c]+pix[c+4]+pix[c+8]+2) >> 2;
3767 pix = image[row*width+2];
3768 for (col=2; col < width-2; col++) {
3769 for (total[3]=375, sum=60, c=0; c < 3; c++) {
3770 for (total[c]=i=0; i < 5; i++)
3771 total[c] += smrow[i][col][c];
3772 total[3] += total[c];
3775 if (sum < 0) sum = 0;
3776 j = total[3] > 375 ? (sum << 16) / total[3] : sum * 174;
3777 FORC3 pix[c] += foveon_apply_curve (curve[6],
3778 ((j*total[c] + 0x8000) >> 16) - pix[c]);
3783 /* Transform the image to a different colorspace */
3784 for (pix=image[0]; pix < image[height*width]; pix+=4) {
3785 FORC3 pix[c] -= foveon_apply_curve (curve[c], pix[c]);
3786 sum = (pix[0]+pix[1]+pix[1]+pix[2]) >> 2;
3787 FORC3 pix[c] -= foveon_apply_curve (curve[c], pix[c]-sum);
3789 for (dsum=i=0; i < 3; i++)
3790 dsum += trans[c][i] * pix[i];
3791 if (dsum < 0) dsum = 0;
3792 if (dsum > 24000) dsum = 24000;
3793 ipix[c] = dsum + 0.5;
3795 FORC3 pix[c] = ipix[c];
3798 /* Smooth the image bottom-to-top and save at 1/4 scale */
3799 shrink = (short (*)[3]) calloc ((height/4), (width/4)*sizeof *shrink);
3800 merror (shrink, "foveon_interpolate()");
3801 for (row = height/4; row--; )
3802 for (col=0; col < width/4; col++) {
3803 ipix[0] = ipix[1] = ipix[2] = 0;
3804 for (i=0; i < 4; i++)
3805 for (j=0; j < 4; j++)
3806 FORC3 ipix[c] += image[(row*4+i)*width+col*4+j][c];
3808 if (row+2 > height/4)
3809 shrink[row*(width/4)+col][c] = ipix[c] >> 4;
3811 shrink[row*(width/4)+col][c] =
3812 (shrink[(row+1)*(width/4)+col][c]*1840 + ipix[c]*141 + 2048) >> 12;
3814 /* From the 1/4-scale image, smooth right-to-left */
3815 for (row=0; row < (height & ~3); row++) {
3816 ipix[0] = ipix[1] = ipix[2] = 0;
3818 for (col = width & ~3 ; col--; )
3819 FORC3 smrow[0][col][c] = ipix[c] =
3820 (shrink[(row/4)*(width/4)+col/4][c]*1485 + ipix[c]*6707 + 4096) >> 13;
3822 /* Then smooth left-to-right */
3823 ipix[0] = ipix[1] = ipix[2] = 0;
3824 for (col=0; col < (width & ~3); col++)
3825 FORC3 smrow[1][col][c] = ipix[c] =
3826 (smrow[0][col][c]*1485 + ipix[c]*6707 + 4096) >> 13;
3828 /* Smooth top-to-bottom */
3830 memcpy (smrow[2], smrow[1], sizeof **smrow * width);
3832 for (col=0; col < (width & ~3); col++)
3833 FORC3 smrow[2][col][c] =
3834 (smrow[2][col][c]*6707 + smrow[1][col][c]*1485 + 4096) >> 13;
3836 /* Adjust the chroma toward the smooth values */
3837 for (col=0; col < (width & ~3); col++) {
3838 for (i=j=30, c=0; c < 3; c++) {
3839 i += smrow[2][col][c];
3840 j += image[row*width+col][c];
3843 for (sum=c=0; c < 3; c++) {
3844 ipix[c] = foveon_apply_curve (curve[c+3],
3845 ((smrow[2][col][c] * j + 0x8000) >> 16) - image[row*width+col][c]);
3850 i = image[row*width+col][c] + ipix[c] - sum;
3852 image[row*width+col][c] = i;
3858 for (i=0; i < 8; i++)
3861 /* Trim off the black border */
3862 active[1] -= keep[1];
3864 i = active[2] - active[0];
3865 for (row=0; row < active[3]-active[1]; row++)
3866 memcpy (image[row*i], image[(row+active[1])*width+active[0]],
3873 /* RESTRICTED code ends here */
3875 void CLASS crop_masked_pixels()
3878 unsigned r, c, m, mblack[8], zero, val;
3880 if (load_raw == &CLASS phase_one_load_raw ||
3881 load_raw == &CLASS phase_one_load_raw_c)
3882 phase_one_correct();
3884 for (row=0; row < raw_height-top_margin*2; row++) {
3885 for (col=0; col < fuji_width << !fuji_layout; col++) {
3887 r = fuji_width - 1 - col + (row >> 1);
3888 c = col + ((row+1) >> 1);
3890 r = fuji_width - 1 + row - (col >> 1);
3891 c = row + ((col+1) >> 1);
3893 if (r < height && c < width)
3894 BAYER(r,c) = RAW(row+top_margin,col+left_margin);
3898 for (row=0; row < height; row++)
3899 for (col=0; col < width; col++)
3900 BAYER2(row,col) = RAW(row+top_margin,col+left_margin);
3902 if (mask[0][3] > 0) goto mask_set;
3903 if (load_raw == &CLASS canon_load_raw ||
3904 load_raw == &CLASS lossless_jpeg_load_raw) {
3905 mask[0][1] = mask[1][1] += 2;
3909 if (load_raw == &CLASS canon_600_load_raw ||
3910 load_raw == &CLASS sony_load_raw ||
3911 (load_raw == &CLASS eight_bit_load_raw && strncmp(model,"DC2",3)) ||
3912 load_raw == &CLASS kodak_262_load_raw ||
3913 (load_raw == &CLASS packed_load_raw && (load_flags & 32))) {
3915 mask[0][0] = mask[1][0] = top_margin;
3916 mask[0][2] = mask[1][2] = top_margin+height;
3917 mask[0][3] += left_margin;
3918 mask[1][1] += left_margin+width;
3919 mask[1][3] += raw_width;
3921 if (load_raw == &CLASS nokia_load_raw) {
3922 mask[0][2] = top_margin;
3926 memset (mblack, 0, sizeof mblack);
3927 for (zero=m=0; m < 8; m++)
3928 for (row=MAX(mask[m][0],0); row < MIN(mask[m][2],raw_height); row++)
3929 for (col=MAX(mask[m][1],0); col < MIN(mask[m][3],raw_width); col++) {
3930 c = FC(row-top_margin,col-left_margin);
3931 mblack[c] += val = RAW(row,col);
3935 if (load_raw == &CLASS canon_600_load_raw && width < raw_width) {
3936 black = (mblack[0]+mblack[1]+mblack[2]+mblack[3]) /
3937 (mblack[4]+mblack[5]+mblack[6]+mblack[7]) - 4;
3938 canon_600_correct();
3939 } else if (zero < mblack[4] && mblack[5] && mblack[6] && mblack[7]) {
3940 FORC4 cblack[c] = mblack[c] / mblack[4+c];
3941 cblack[4] = cblack[5] = cblack[6] = 0;
3945 void CLASS remove_zeroes()
3947 unsigned row, col, tot, n, r, c;
3949 for (row=0; row < height; row++)
3950 for (col=0; col < width; col++)
3951 if (BAYER(row,col) == 0) {
3953 for (r = row-2; r <= row+2; r++)
3954 for (c = col-2; c <= col+2; c++)
3955 if (r < height && c < width &&
3956 FC(r,c) == FC(row,col) && BAYER(r,c))
3957 tot += (n++,BAYER(r,c));
3958 if (n) BAYER(row,col) = tot/n;
3963 Seach from the current directory up to the root looking for
3964 a ".badpixels" file, and fix those pixels now.
3966 void CLASS bad_pixels (const char *cfname)
3969 char *fname, *cp, line[128];
3970 int len, time, row, col, r, c, rad, tot, n, fixed=0;
3972 if (!filters) return;
3974 fp = fopen (cfname, "r");
3976 for (len=32 ; ; len *= 2) {
3977 fname = (char *) malloc (len);
3979 if (getcwd (fname, len-16)) break;
3981 if (errno != ERANGE) return;
3983 #if defined(WIN32) || defined(DJGPP)
3984 if (fname[1] == ':')
3985 memmove (fname, fname+2, len-2);
3986 for (cp=fname; *cp; cp++)
3987 if (*cp == '\\') *cp = '/';
3989 cp = fname + strlen(fname);
3990 if (cp[-1] == '/') cp--;
3991 while (*fname == '/') {
3992 strcpy (cp, "/.badpixels");
3993 if ((fp = fopen (fname, "r"))) break;
3994 if (cp == fname) break;
3995 while (*--cp != '/');
4000 while (fgets (line, 128, fp)) {
4001 cp = strchr (line, '#');
4003 if (sscanf (line, "%d %d %d", &col, &row, &time) != 3) continue;
4004 if ((unsigned) col >= width || (unsigned) row >= height) continue;
4005 if (time > timestamp) continue;
4006 for (tot=n=0, rad=1; rad < 3 && n==0; rad++)
4007 for (r = row-rad; r <= row+rad; r++)
4008 for (c = col-rad; c <= col+rad; c++)
4009 if ((unsigned) r < height && (unsigned) c < width &&
4010 (r != row || c != col) && fcol(r,c) == fcol(row,col)) {
4014 BAYER2(row,col) = tot/n;
4017 fprintf (stderr,_("Fixed dead pixels at:"));
4018 fprintf (stderr, " %d,%d", col, row);
4021 if (fixed) fputc ('\n', stderr);
4025 void CLASS subtract (const char *fname)
4028 int dim[3]={0,0,0}, comment=0, number=0, error=0, nd=0, c, row, col;
4031 if (!(fp = fopen (fname, "rb"))) {
4032 perror (fname); return;
4034 if (fgetc(fp) != 'P' || fgetc(fp) != '5') error = 1;
4035 while (!error && nd < 3 && (c = fgetc(fp)) != EOF) {
4036 if (c == '#') comment = 1;
4037 if (c == '\n') comment = 0;
4038 if (comment) continue;
4039 if (isdigit(c)) number = 1;
4041 if (isdigit(c)) dim[nd] = dim[nd]*10 + c -'0';
4042 else if (isspace(c)) {
4047 if (error || nd < 3) {
4048 fprintf (stderr,_("%s is not a valid PGM file!\n"), fname);
4049 fclose (fp); return;
4050 } else if (dim[0] != width || dim[1] != height || dim[2] != 65535) {
4051 fprintf (stderr,_("%s has the wrong dimensions!\n"), fname);
4052 fclose (fp); return;
4054 pixel = (ushort *) calloc (width, sizeof *pixel);
4055 merror (pixel, "subtract()");
4056 for (row=0; row < height; row++) {
4057 fread (pixel, 2, width, fp);
4058 for (col=0; col < width; col++)
4059 BAYER(row,col) = MAX (BAYER(row,col) - ntohs(pixel[col]), 0);
4063 memset (cblack, 0, sizeof cblack);
4067 void CLASS gamma_curve (double pwr, double ts, int mode, int imax)
4070 double g[6], bnd[2]={0,0}, r;
4074 g[2] = g[3] = g[4] = 0;
4076 if (g[1] && (g[1]-1)*(g[0]-1) <= 0) {
4077 for (i=0; i < 48; i++) {
4078 g[2] = (bnd[0] + bnd[1])/2;
4079 if (g[0]) bnd[(pow(g[2]/g[1],-g[0]) - 1)/g[0] - 1/g[2] > -1] = g[2];
4080 else bnd[g[2]/exp(1-1/g[2]) < g[1]] = g[2];
4083 if (g[0]) g[4] = g[2] * (1/g[0] - 1);
4085 if (g[0]) g[5] = 1 / (g[1]*SQR(g[3])/2 - g[4]*(1 - g[3]) +
4086 (1 - pow(g[3],1+g[0]))*(1 + g[4])/(1 + g[0])) - 1;
4087 else g[5] = 1 / (g[1]*SQR(g[3])/2 + 1
4088 - g[2] - g[3] - g[2]*g[3]*(log(g[3]) - 1)) - 1;
4090 memcpy (gamm, g, sizeof gamm);
4093 for (i=0; i < 0x10000; i++) {
4095 if ((r = (double) i / imax) < 1)
4096 curve[i] = 0x10000 * ( mode
4097 ? (r < g[3] ? r*g[1] : (g[0] ? pow( r,g[0])*(1+g[4])-g[4] : log(r)*g[2]+1))
4098 : (r < g[2] ? r/g[1] : (g[0] ? pow((r+g[4])/(1+g[4]),1/g[0]) : exp((r-1)/g[2]))));
4102 void CLASS pseudoinverse (double (*in)[3], double (*out)[3], int size)
4104 double work[3][6], num;
4107 for (i=0; i < 3; i++) {
4108 for (j=0; j < 6; j++)
4109 work[i][j] = j == i+3;
4110 for (j=0; j < 3; j++)
4111 for (k=0; k < size; k++)
4112 work[i][j] += in[k][i] * in[k][j];
4114 for (i=0; i < 3; i++) {
4116 for (j=0; j < 6; j++)
4118 for (k=0; k < 3; k++) {
4121 for (j=0; j < 6; j++)
4122 work[k][j] -= work[i][j] * num;
4125 for (i=0; i < size; i++)
4126 for (j=0; j < 3; j++)
4127 for (out[i][j]=k=0; k < 3; k++)
4128 out[i][j] += work[j][k+3] * in[i][k];
4131 void CLASS cam_xyz_coeff (float rgb_cam[3][4], double cam_xyz[4][3])
4133 double cam_rgb[4][3], inverse[4][3], num;
4136 for (i=0; i < colors; i++) /* Multiply out XYZ colorspace */
4137 for (j=0; j < 3; j++)
4138 for (cam_rgb[i][j] = k=0; k < 3; k++)
4139 cam_rgb[i][j] += cam_xyz[i][k] * xyz_rgb[k][j];
4141 for (i=0; i < colors; i++) { /* Normalize cam_rgb so that */
4142 for (num=j=0; j < 3; j++) /* cam_rgb * (1,1,1) is (1,1,1,1) */
4143 num += cam_rgb[i][j];
4144 for (j=0; j < 3; j++)
4145 cam_rgb[i][j] /= num;
4146 pre_mul[i] = 1 / num;
4148 pseudoinverse (cam_rgb, inverse, colors);
4149 for (i=0; i < 3; i++)
4150 for (j=0; j < colors; j++)
4151 rgb_cam[i][j] = inverse[j][i];
4155 void CLASS colorcheck()
4158 // Coordinates of the GretagMacbeth ColorChecker squares
4159 // width, height, 1st_column, 1st_row
4160 int cut[NSQ][4]; // you must set these
4161 // ColorChecker Chart under 6500-kelvin illumination
4162 static const double gmb_xyY[NSQ][3] = {
4163 { 0.400, 0.350, 10.1 }, // Dark Skin
4164 { 0.377, 0.345, 35.8 }, // Light Skin
4165 { 0.247, 0.251, 19.3 }, // Blue Sky
4166 { 0.337, 0.422, 13.3 }, // Foliage
4167 { 0.265, 0.240, 24.3 }, // Blue Flower
4168 { 0.261, 0.343, 43.1 }, // Bluish Green
4169 { 0.506, 0.407, 30.1 }, // Orange
4170 { 0.211, 0.175, 12.0 }, // Purplish Blue
4171 { 0.453, 0.306, 19.8 }, // Moderate Red
4172 { 0.285, 0.202, 6.6 }, // Purple
4173 { 0.380, 0.489, 44.3 }, // Yellow Green
4174 { 0.473, 0.438, 43.1 }, // Orange Yellow
4175 { 0.187, 0.129, 6.1 }, // Blue
4176 { 0.305, 0.478, 23.4 }, // Green
4177 { 0.539, 0.313, 12.0 }, // Red
4178 { 0.448, 0.470, 59.1 }, // Yellow
4179 { 0.364, 0.233, 19.8 }, // Magenta
4180 { 0.196, 0.252, 19.8 }, // Cyan
4181 { 0.310, 0.316, 90.0 }, // White
4182 { 0.310, 0.316, 59.1 }, // Neutral 8
4183 { 0.310, 0.316, 36.2 }, // Neutral 6.5
4184 { 0.310, 0.316, 19.8 }, // Neutral 5
4185 { 0.310, 0.316, 9.0 }, // Neutral 3.5
4186 { 0.310, 0.316, 3.1 } }; // Black
4187 double gmb_cam[NSQ][4], gmb_xyz[NSQ][3];
4188 double inverse[NSQ][3], cam_xyz[4][3], balance[4], num;
4189 int c, i, j, k, sq, row, col, pass, count[4];
4191 memset (gmb_cam, 0, sizeof gmb_cam);
4192 for (sq=0; sq < NSQ; sq++) {
4194 for (row=cut[sq][3]; row < cut[sq][3]+cut[sq][1]; row++)
4195 for (col=cut[sq][2]; col < cut[sq][2]+cut[sq][0]; col++) {
4197 if (c >= colors) c -= 2;
4198 gmb_cam[sq][c] += BAYER2(row,col);
4199 BAYER2(row,col) = black + (BAYER2(row,col)-black)/2;
4202 FORCC gmb_cam[sq][c] = gmb_cam[sq][c]/count[c] - black;
4203 gmb_xyz[sq][0] = gmb_xyY[sq][2] * gmb_xyY[sq][0] / gmb_xyY[sq][1];
4204 gmb_xyz[sq][1] = gmb_xyY[sq][2];
4205 gmb_xyz[sq][2] = gmb_xyY[sq][2] *
4206 (1 - gmb_xyY[sq][0] - gmb_xyY[sq][1]) / gmb_xyY[sq][1];
4208 pseudoinverse (gmb_xyz, inverse, NSQ);
4209 for (pass=0; pass < 2; pass++) {
4210 for (raw_color = i=0; i < colors; i++)
4211 for (j=0; j < 3; j++)
4212 for (cam_xyz[i][j] = k=0; k < NSQ; k++)
4213 cam_xyz[i][j] += gmb_cam[k][i] * inverse[k][j];
4214 cam_xyz_coeff (rgb_cam, cam_xyz);
4215 FORCC balance[c] = pre_mul[c] * gmb_cam[20][c];
4216 for (sq=0; sq < NSQ; sq++)
4217 FORCC gmb_cam[sq][c] *= balance[c];
4220 printf (" { \"%s %s\", %d,\n\t{", make, model, black);
4221 num = 10000 / (cam_xyz[1][0] + cam_xyz[1][1] + cam_xyz[1][2]);
4222 FORCC for (j=0; j < 3; j++)
4223 printf ("%c%d", (c | j) ? ',':' ', (int) (cam_xyz[c][j] * num + 0.5));
4230 void CLASS hat_transform (float *temp, float *base, int st, int size, int sc)
4233 for (i=0; i < sc; i++)
4234 temp[i] = 2*base[st*i] + base[st*(sc-i)] + base[st*(i+sc)];
4235 for (; i+sc < size; i++)
4236 temp[i] = 2*base[st*i] + base[st*(i-sc)] + base[st*(i+sc)];
4237 for (; i < size; i++)
4238 temp[i] = 2*base[st*i] + base[st*(i-sc)] + base[st*(2*size-2-(i+sc))];
4241 void CLASS wavelet_denoise()
4243 float *fimg=0, *temp, thold, mul[2], avg, diff;
4244 int scale=1, size, lev, hpass, lpass, row, col, nc, c, i, wlast, blk[2];
4246 static const float noise[] =
4247 { 0.8002,0.2735,0.1202,0.0585,0.0291,0.0152,0.0080,0.0044 };
4249 if (verbose) fprintf (stderr,_("Wavelet denoising...\n"));
4251 while (maximum << scale < 0x10000) scale++;
4252 maximum <<= --scale;
4254 FORC4 cblack[c] <<= scale;
4255 if ((size = iheight*iwidth) < 0x15550000)
4256 fimg = (float *) malloc ((size*3 + iheight + iwidth) * sizeof *fimg);
4257 merror (fimg, "wavelet_denoise()");
4258 temp = fimg + size*3;
4259 if ((nc = colors) == 3 && filters) nc++;
4260 FORC(nc) { /* denoise R,G1,B,G3 individually */
4261 for (i=0; i < size; i++)
4262 fimg[i] = 256 * sqrt(image[i][c] << scale);
4263 for (hpass=lev=0; lev < 5; lev++) {
4264 lpass = size*((lev & 1)+1);
4265 for (row=0; row < iheight; row++) {
4266 hat_transform (temp, fimg+hpass+row*iwidth, 1, iwidth, 1 << lev);
4267 for (col=0; col < iwidth; col++)
4268 fimg[lpass + row*iwidth + col] = temp[col] * 0.25;
4270 for (col=0; col < iwidth; col++) {
4271 hat_transform (temp, fimg+lpass+col, iwidth, iheight, 1 << lev);
4272 for (row=0; row < iheight; row++)
4273 fimg[lpass + row*iwidth + col] = temp[row] * 0.25;
4275 thold = threshold * noise[lev];
4276 for (i=0; i < size; i++) {
4277 fimg[hpass+i] -= fimg[lpass+i];
4278 if (fimg[hpass+i] < -thold) fimg[hpass+i] += thold;
4279 else if (fimg[hpass+i] > thold) fimg[hpass+i] -= thold;
4280 else fimg[hpass+i] = 0;
4281 if (hpass) fimg[i] += fimg[hpass+i];
4285 for (i=0; i < size; i++)
4286 image[i][c] = CLIP(SQR(fimg[i]+fimg[lpass+i])/0x10000);
4288 if (filters && colors == 3) { /* pull G1 and G3 closer together */
4289 for (row=0; row < 2; row++) {
4290 mul[row] = 0.125 * pre_mul[FC(row+1,0) | 1] / pre_mul[FC(row,0) | 1];
4291 blk[row] = cblack[FC(row,0) | 1];
4293 for (i=0; i < 4; i++)
4294 window[i] = (ushort *) fimg + width*i;
4295 for (wlast=-1, row=1; row < height-1; row++) {
4296 while (wlast < row+1) {
4297 for (wlast++, i=0; i < 4; i++)
4298 window[(i+3) & 3] = window[i];
4299 for (col = FC(wlast,1) & 1; col < width; col+=2)
4300 window[2][col] = BAYER(wlast,col);
4302 thold = threshold/512;
4303 for (col = (FC(row,0) & 1)+1; col < width-1; col+=2) {
4304 avg = ( window[0][col-1] + window[0][col+1] +
4305 window[2][col-1] + window[2][col+1] - blk[~row & 1]*4 )
4306 * mul[row & 1] + (window[1][col] + blk[row & 1]) * 0.5;
4307 avg = avg < 0 ? 0 : sqrt(avg);
4308 diff = sqrt(BAYER(row,col)) - avg;
4309 if (diff < -thold) diff += thold;
4310 else if (diff > thold) diff -= thold;
4312 BAYER(row,col) = CLIP(SQR(avg+diff) + 0.5);
4319 void CLASS scale_colors()
4321 unsigned bottom, right, size, row, col, ur, uc, i, x, y, c, sum[8];
4323 double dsum[8], dmin, dmax;
4324 float scale_mul[4], fr, fc;
4325 ushort *img=0, *pix;
4328 memcpy (pre_mul, user_mul, sizeof pre_mul);
4329 if (use_auto_wb || (use_camera_wb && cam_mul[0] == -1)) {
4330 memset (dsum, 0, sizeof dsum);
4331 bottom = MIN (greybox[1]+greybox[3], height);
4332 right = MIN (greybox[0]+greybox[2], width);
4333 for (row=greybox[1]; row < bottom; row += 8)
4334 for (col=greybox[0]; col < right; col += 8) {
4335 memset (sum, 0, sizeof sum);
4336 for (y=row; y < row+8 && y < bottom; y++)
4337 for (x=col; x < col+8 && x < right; x++)
4343 val = image[y*width+x][c];
4344 if (val > maximum-25) goto skip_block;
4345 if ((val -= cblack[c]) < 0) val = 0;
4350 FORC(8) dsum[c] += sum[c];
4353 FORC4 if (dsum[c]) pre_mul[c] = dsum[c+4] / dsum[c];
4355 if (use_camera_wb && cam_mul[0] != -1) {
4356 memset (sum, 0, sizeof sum);
4357 for (row=0; row < 8; row++)
4358 for (col=0; col < 8; col++) {
4360 if ((val = white[row][col] - cblack[c]) > 0)
4364 if (sum[0] && sum[1] && sum[2] && sum[3])
4365 FORC4 pre_mul[c] = (float) sum[c+4] / sum[c];
4366 else if (cam_mul[0] && cam_mul[2])
4367 memcpy (pre_mul, cam_mul, sizeof pre_mul);
4369 fprintf (stderr,_("%s: Cannot use camera white balance.\n"), ifname);
4371 if (pre_mul[1] == 0) pre_mul[1] = 1;
4372 if (pre_mul[3] == 0) pre_mul[3] = colors < 4 ? pre_mul[1] : 1;
4375 if (threshold) wavelet_denoise();
4377 for (dmin=DBL_MAX, dmax=c=0; c < 4; c++) {
4378 if (dmin > pre_mul[c])
4380 if (dmax < pre_mul[c])
4383 if (!highlight) dmax = dmin;
4384 FORC4 scale_mul[c] = (pre_mul[c] /= dmax) * 65535.0 / maximum;
4387 _("Scaling with darkness %d, saturation %d, and\nmultipliers"), dark, sat);
4388 FORC4 fprintf (stderr, " %f", pre_mul[c]);
4389 fputc ('\n', stderr);
4391 if (filters > 1000 && (cblack[4]+1)/2 == 1 && (cblack[5]+1)/2 == 1) {
4392 FORC4 cblack[FC(c/2,c%2)] +=
4393 cblack[6 + c/2 % cblack[4] * cblack[5] + c%2 % cblack[5]];
4394 cblack[4] = cblack[5] = 0;
4396 size = iheight*iwidth;
4397 for (i=0; i < size*4; i++) {
4398 if (!(val = ((ushort *)image)[i])) continue;
4399 if (cblack[4] && cblack[5])
4400 val -= cblack[6 + i/4 / iwidth % cblack[4] * cblack[5] +
4401 i/4 % iwidth % cblack[5]];
4402 val -= cblack[i & 3];
4403 val *= scale_mul[i & 3];
4404 ((ushort *)image)[i] = CLIP(val);
4406 if ((aber[0] != 1 || aber[2] != 1) && colors == 3) {
4408 fprintf (stderr,_("Correcting chromatic aberration...\n"));
4409 for (c=0; c < 4; c+=2) {
4410 if (aber[c] == 1) continue;
4411 img = (ushort *) malloc (size * sizeof *img);
4412 merror (img, "scale_colors()");
4413 for (i=0; i < size; i++)
4414 img[i] = image[i][c];
4415 for (row=0; row < iheight; row++) {
4416 ur = fr = (row - iheight*0.5) * aber[c] + iheight*0.5;
4417 if (ur > iheight-2) continue;
4419 for (col=0; col < iwidth; col++) {
4420 uc = fc = (col - iwidth*0.5) * aber[c] + iwidth*0.5;
4421 if (uc > iwidth-2) continue;
4423 pix = img + ur*iwidth + uc;
4424 image[row*iwidth+col][c] =
4425 (pix[ 0]*(1-fc) + pix[ 1]*fc) * (1-fr) +
4426 (pix[iwidth]*(1-fc) + pix[iwidth+1]*fc) * fr;
4434 void CLASS pre_interpolate()
4444 for (row=0; row < 3; row++)
4445 for (col=1; col < 4; col++)
4446 if (!(image[row*width+col][0] | image[row*width+col][2]))
4447 goto break2; break2:
4448 for ( ; row < height; row+=3)
4449 for (col=(col-1)%3+1; col < width-1; col+=3) {
4450 img = image + row*width+col;
4451 for (c=0; c < 3; c+=2)
4452 img[0][c] = (img[-1][c] + img[1][c]) >> 1;
4456 img = (ushort (*)[4]) calloc (height, width*sizeof *img);
4457 merror (img, "pre_interpolate()");
4458 for (row=0; row < height; row++)
4459 for (col=0; col < width; col++) {
4461 img[row*width+col][c] = image[(row >> 1)*iwidth+(col >> 1)][c];
4468 if (filters > 1000 && colors == 3) {
4469 mix_green = four_color_rgb ^ half_size;
4470 if (four_color_rgb | half_size) colors++;
4472 for (row = FC(1,0) >> 1; row < height; row+=2)
4473 for (col = FC(row,1) & 1; col < width; col+=2)
4474 image[row*width+col][1] = image[row*width+col][3];
4475 filters &= ~((filters & 0x55555555) << 1);
4478 if (half_size) filters = 0;
4481 void CLASS border_interpolate (int border)
4483 unsigned row, col, y, x, f, c, sum[8];
4485 for (row=0; row < height; row++)
4486 for (col=0; col < width; col++) {
4487 if (col==border && row >= border && row < height-border)
4489 memset (sum, 0, sizeof sum);
4490 for (y=row-1; y != row+2; y++)
4491 for (x=col-1; x != col+2; x++)
4492 if (y < height && x < width) {
4494 sum[f] += image[y*width+x][f];
4498 FORCC if (c != f && sum[c+4])
4499 image[row*width+col][c] = sum[c] / sum[c+4];
4503 void CLASS lin_interpolate()
4505 int code[16][16][32], size=16, *ip, sum[4];
4506 int f, c, i, x, y, row, col, shift, color;
4509 if (verbose) fprintf (stderr,_("Bilinear interpolation...\n"));
4510 if (filters == 9) size = 6;
4511 border_interpolate(1);
4512 for (row=0; row < size; row++)
4513 for (col=0; col < size; col++) {
4514 ip = code[row][col]+1;
4516 memset (sum, 0, sizeof sum);
4517 for (y=-1; y <= 1; y++)
4518 for (x=-1; x <= 1; x++) {
4519 shift = (y==0) + (x==0);
4520 color = fcol(row+y,col+x);
4521 if (color == f) continue;
4522 *ip++ = (width*y + x)*4 + color;
4525 sum[color] += 1 << shift;
4527 code[row][col][0] = (ip - code[row][col]) / 3;
4531 *ip++ = 256 / sum[c];
4534 for (row=1; row < height-1; row++)
4535 for (col=1; col < width-1; col++) {
4536 pix = image[row*width+col];
4537 ip = code[row % size][col % size];
4538 memset (sum, 0, sizeof sum);
4539 for (i=*ip++; i--; ip+=3)
4540 sum[ip[2]] += pix[ip[0]] << ip[1];
4541 for (i=colors; --i; ip+=2)
4542 pix[ip[0]] = sum[ip[0]] * ip[1] >> 8;
4547 This algorithm is officially called:
4549 "Interpolation using a Threshold-based variable number of gradients"
4551 described in http://scien.stanford.edu/pages/labsite/1999/psych221/projects/99/tingchen/algodep/vargra.html
4553 I've extended the basic idea to work with non-Bayer filter arrays.
4554 Gradients are numbered clockwise from NW=0 to W=7.
4556 void CLASS vng_interpolate()
4558 static const signed char *cp, terms[] = {
4559 -2,-2,+0,-1,0,0x01, -2,-2,+0,+0,1,0x01, -2,-1,-1,+0,0,0x01,
4560 -2,-1,+0,-1,0,0x02, -2,-1,+0,+0,0,0x03, -2,-1,+0,+1,1,0x01,
4561 -2,+0,+0,-1,0,0x06, -2,+0,+0,+0,1,0x02, -2,+0,+0,+1,0,0x03,
4562 -2,+1,-1,+0,0,0x04, -2,+1,+0,-1,1,0x04, -2,+1,+0,+0,0,0x06,
4563 -2,+1,+0,+1,0,0x02, -2,+2,+0,+0,1,0x04, -2,+2,+0,+1,0,0x04,
4564 -1,-2,-1,+0,0,0x80, -1,-2,+0,-1,0,0x01, -1,-2,+1,-1,0,0x01,
4565 -1,-2,+1,+0,1,0x01, -1,-1,-1,+1,0,0x88, -1,-1,+1,-2,0,0x40,
4566 -1,-1,+1,-1,0,0x22, -1,-1,+1,+0,0,0x33, -1,-1,+1,+1,1,0x11,
4567 -1,+0,-1,+2,0,0x08, -1,+0,+0,-1,0,0x44, -1,+0,+0,+1,0,0x11,
4568 -1,+0,+1,-2,1,0x40, -1,+0,+1,-1,0,0x66, -1,+0,+1,+0,1,0x22,
4569 -1,+0,+1,+1,0,0x33, -1,+0,+1,+2,1,0x10, -1,+1,+1,-1,1,0x44,
4570 -1,+1,+1,+0,0,0x66, -1,+1,+1,+1,0,0x22, -1,+1,+1,+2,0,0x10,
4571 -1,+2,+0,+1,0,0x04, -1,+2,+1,+0,1,0x04, -1,+2,+1,+1,0,0x04,
4572 +0,-2,+0,+0,1,0x80, +0,-1,+0,+1,1,0x88, +0,-1,+1,-2,0,0x40,
4573 +0,-1,+1,+0,0,0x11, +0,-1,+2,-2,0,0x40, +0,-1,+2,-1,0,0x20,
4574 +0,-1,+2,+0,0,0x30, +0,-1,+2,+1,1,0x10, +0,+0,+0,+2,1,0x08,
4575 +0,+0,+2,-2,1,0x40, +0,+0,+2,-1,0,0x60, +0,+0,+2,+0,1,0x20,
4576 +0,+0,+2,+1,0,0x30, +0,+0,+2,+2,1,0x10, +0,+1,+1,+0,0,0x44,
4577 +0,+1,+1,+2,0,0x10, +0,+1,+2,-1,1,0x40, +0,+1,+2,+0,0,0x60,
4578 +0,+1,+2,+1,0,0x20, +0,+1,+2,+2,0,0x10, +1,-2,+1,+0,0,0x80,
4579 +1,-1,+1,+1,0,0x88, +1,+0,+1,+2,0,0x08, +1,+0,+2,-1,0,0x40,
4581 }, chood[] = { -1,-1, -1,0, -1,+1, 0,+1, +1,+1, +1,0, +1,-1, 0,-1 };
4582 ushort (*brow[5])[4], *pix;
4583 int prow=8, pcol=2, *ip, *code[16][16], gval[8], gmin, gmax, sum[4];
4584 int row, col, x, y, x1, x2, y1, y2, t, weight, grads, color, diag;
4585 int g, diff, thold, num, c;
4588 if (verbose) fprintf (stderr,_("VNG interpolation...\n"));
4590 if (filters == 1) prow = pcol = 16;
4591 if (filters == 9) prow = pcol = 6;
4592 ip = (int *) calloc (prow*pcol, 1280);
4593 merror (ip, "vng_interpolate()");
4594 for (row=0; row < prow; row++) /* Precalculate for VNG */
4595 for (col=0; col < pcol; col++) {
4596 code[row][col] = ip;
4597 for (cp=terms, t=0; t < 64; t++) {
4598 y1 = *cp++; x1 = *cp++;
4599 y2 = *cp++; x2 = *cp++;
4602 color = fcol(row+y1,col+x1);
4603 if (fcol(row+y2,col+x2) != color) continue;
4604 diag = (fcol(row,col+1) == color && fcol(row+1,col) == color) ? 2:1;
4605 if (abs(y1-y2) == diag && abs(x1-x2) == diag) continue;
4606 *ip++ = (y1*width + x1)*4 + color;
4607 *ip++ = (y2*width + x2)*4 + color;
4609 for (g=0; g < 8; g++)
4610 if (grads & 1<<g) *ip++ = g;
4614 for (cp=chood, g=0; g < 8; g++) {
4615 y = *cp++; x = *cp++;
4616 *ip++ = (y*width + x) * 4;
4617 color = fcol(row,col);
4618 if (fcol(row+y,col+x) != color && fcol(row+y*2,col+x*2) == color)
4619 *ip++ = (y*width + x) * 8 + color;
4624 brow[4] = (ushort (*)[4]) calloc (width*3, sizeof **brow);
4625 merror (brow[4], "vng_interpolate()");
4626 for (row=0; row < 3; row++)
4627 brow[row] = brow[4] + row*width;
4628 for (row=2; row < height-2; row++) { /* Do VNG interpolation */
4629 for (col=2; col < width-2; col++) {
4630 pix = image[row*width+col];
4631 ip = code[row % prow][col % pcol];
4632 memset (gval, 0, sizeof gval);
4633 while ((g = ip[0]) != INT_MAX) { /* Calculate gradients */
4634 diff = ABS(pix[g] - pix[ip[1]]) << ip[2];
4635 gval[ip[3]] += diff;
4637 if ((g = ip[-1]) == -1) continue;
4639 while ((g = *ip++) != -1)
4643 gmin = gmax = gval[0]; /* Choose a threshold */
4644 for (g=1; g < 8; g++) {
4645 if (gmin > gval[g]) gmin = gval[g];
4646 if (gmax < gval[g]) gmax = gval[g];
4649 memcpy (brow[2][col], pix, sizeof *image);
4652 thold = gmin + (gmax >> 1);
4653 memset (sum, 0, sizeof sum);
4654 color = fcol(row,col);
4655 for (num=g=0; g < 8; g++,ip+=2) { /* Average the neighbors */
4656 if (gval[g] <= thold) {
4658 if (c == color && ip[1])
4659 sum[c] += (pix[c] + pix[ip[1]]) >> 1;
4661 sum[c] += pix[ip[0] + c];
4665 FORCC { /* Save to buffer */
4668 t += (sum[c] - sum[color]) / num;
4669 brow[2][col][c] = CLIP(t);
4672 if (row > 3) /* Write buffer to image */
4673 memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image);
4674 for (g=0; g < 4; g++)
4675 brow[(g-1) & 3] = brow[g];
4677 memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image);
4678 memcpy (image[(row-1)*width+2], brow[1]+2, (width-4)*sizeof *image);
4684 Patterned Pixel Grouping Interpolation by Alain Desbiolles
4686 void CLASS ppg_interpolate()
4688 int dir[5] = { 1, width, -1, -width, 1 };
4689 int row, col, diff[2], guess[2], c, d, i;
4692 border_interpolate(3);
4693 if (verbose) fprintf (stderr,_("PPG interpolation...\n"));
4695 /* Fill in the green layer with gradients and pattern recognition: */
4696 for (row=3; row < height-3; row++)
4697 for (col=3+(FC(row,3) & 1), c=FC(row,col); col < width-3; col+=2) {
4698 pix = image + row*width+col;
4699 for (i=0; (d=dir[i]) > 0; i++) {
4700 guess[i] = (pix[-d][1] + pix[0][c] + pix[d][1]) * 2
4701 - pix[-2*d][c] - pix[2*d][c];
4702 diff[i] = ( ABS(pix[-2*d][c] - pix[ 0][c]) +
4703 ABS(pix[ 2*d][c] - pix[ 0][c]) +
4704 ABS(pix[ -d][1] - pix[ d][1]) ) * 3 +
4705 ( ABS(pix[ 3*d][1] - pix[ d][1]) +
4706 ABS(pix[-3*d][1] - pix[-d][1]) ) * 2;
4708 d = dir[i = diff[0] > diff[1]];
4709 pix[0][1] = ULIM(guess[i] >> 2, pix[d][1], pix[-d][1]);
4711 /* Calculate red and blue for each green pixel: */
4712 for (row=1; row < height-1; row++)
4713 for (col=1+(FC(row,2) & 1), c=FC(row,col+1); col < width-1; col+=2) {
4714 pix = image + row*width+col;
4715 for (i=0; (d=dir[i]) > 0; c=2-c, i++)
4716 pix[0][c] = CLIP((pix[-d][c] + pix[d][c] + 2*pix[0][1]
4717 - pix[-d][1] - pix[d][1]) >> 1);
4719 /* Calculate blue for red pixels and vice versa: */
4720 for (row=1; row < height-1; row++)
4721 for (col=1+(FC(row,1) & 1), c=2-FC(row,col); col < width-1; col+=2) {
4722 pix = image + row*width+col;
4723 for (i=0; (d=dir[i]+dir[i+1]) > 0; i++) {
4724 diff[i] = ABS(pix[-d][c] - pix[d][c]) +
4725 ABS(pix[-d][1] - pix[0][1]) +
4726 ABS(pix[ d][1] - pix[0][1]);
4727 guess[i] = pix[-d][c] + pix[d][c] + 2*pix[0][1]
4728 - pix[-d][1] - pix[d][1];
4730 if (diff[0] != diff[1])
4731 pix[0][c] = CLIP(guess[diff[0] > diff[1]] >> 1);
4733 pix[0][c] = CLIP((guess[0]+guess[1]) >> 2);
4737 void CLASS cielab (ushort rgb[3], short lab[3])
4741 static float cbrt[0x10000], xyz_cam[3][4];
4744 for (i=0; i < 0x10000; i++) {
4746 cbrt[i] = r > 0.008856 ? pow(r,1/3.0) : 7.787*r + 16/116.0;
4748 for (i=0; i < 3; i++)
4749 for (j=0; j < colors; j++)
4750 for (xyz_cam[i][j] = k=0; k < 3; k++)
4751 xyz_cam[i][j] += xyz_rgb[i][k] * rgb_cam[k][j] / d65_white[i];
4754 xyz[0] = xyz[1] = xyz[2] = 0.5;
4756 xyz[0] += xyz_cam[0][c] * rgb[c];
4757 xyz[1] += xyz_cam[1][c] * rgb[c];
4758 xyz[2] += xyz_cam[2][c] * rgb[c];
4760 xyz[0] = cbrt[CLIP((int) xyz[0])];
4761 xyz[1] = cbrt[CLIP((int) xyz[1])];
4762 xyz[2] = cbrt[CLIP((int) xyz[2])];
4763 lab[0] = 64 * (116 * xyz[1] - 16);
4764 lab[1] = 64 * 500 * (xyz[0] - xyz[1]);
4765 lab[2] = 64 * 200 * (xyz[1] - xyz[2]);
4768 #define TS 512 /* Tile Size */
4769 #define fcol(row,col) xtrans[(row+6) % 6][(col+6) % 6]
4772 Frank Markesteijn's algorithm for Fuji X-Trans sensors
4774 void CLASS xtrans_interpolate (int passes)
4776 int c, d, f, g, h, i, v, ng, row, col, top, left, mrow, mcol;
4777 int val, ndir, pass, hm[8], avg[4], color[3][8];
4778 static const short orth[12] = { 1,0,0,1,-1,0,0,-1,1,0,0,1 },
4779 patt[2][16] = { { 0,1,0,-1,2,0,-1,0,1,1,1,-1,0,0,0,0 },
4780 { 0,1,0,-2,1,0,-2,0,1,1,-2,-2,1,-1,-1,1 } },
4781 dir[4] = { 1,TS,TS+1,TS-1 };
4782 short allhex[3][3][2][8], *hex;
4784 ushort min, max, sgrow=0, sgcol=0;
4785 ushort (*rgb)[TS][TS][3], (*rix)[3], (*pix)[4];
4786 short (*lab) [TS][3], (*lix)[3];
4787 float (*drv)[TS][TS], diff[6], tr;
4788 char (*homo)[TS][TS], *buffer;
4791 fprintf (stderr,_("%d-pass X-Trans interpolation...\n"), passes);
4794 ndir = 4 << (passes > 1);
4795 buffer = (char *) malloc (TS*TS*(ndir*11+6));
4796 merror (buffer, "xtrans_interpolate()");
4797 rgb = (ushort(*)[TS][TS][3]) buffer;
4798 lab = (short (*) [TS][3])(buffer + TS*TS*(ndir*6));
4799 drv = (float (*)[TS][TS]) (buffer + TS*TS*(ndir*6+6));
4800 homo = (char (*)[TS][TS]) (buffer + TS*TS*(ndir*10+6));
4802 /* Map a green hexagon around each non-green pixel and vice versa: */
4803 for (row=0; row < 3; row++)
4804 for (col=0; col < 3; col++)
4805 for (ng=d=0; d < 10; d+=2) {
4806 g = fcol(row,col) == 1;
4807 if (fcol(row+orth[d],col+orth[d+2]) == 1) ng=0; else ng++;
4808 if (ng == 4) { sgrow = row; sgcol = col; }
4809 if (ng == g+1) FORC(8) {
4810 v = orth[d ]*patt[g][c*2] + orth[d+1]*patt[g][c*2+1];
4811 h = orth[d+2]*patt[g][c*2] + orth[d+3]*patt[g][c*2+1];
4812 allhex[row][col][0][c^(g*2 & d)] = h + v*width;
4813 allhex[row][col][1][c^(g*2 & d)] = h + v*TS;
4817 /* Set green1 and green3 to the minimum and maximum allowed values: */
4818 for (row=2; row < height-2; row++)
4819 for (min=~(max=0), col=2; col < width-2; col++) {
4820 if (fcol(row,col) == 1 && (min=~(max=0))) continue;
4821 pix = image + row*width + col;
4822 hex = allhex[row % 3][col % 3][0];
4824 val = pix[hex[c]][1];
4825 if (min > val) min = val;
4826 if (max < val) max = val;
4830 switch ((row-sgrow) % 3) {
4831 case 1: if (row < height-3) { row++; col--; } break;
4832 case 2: if ((min=~(max=0)) && (col+=2) < width-3 && row > 2) row--;
4836 for (top=3; top < height-19; top += TS-16)
4837 for (left=3; left < width-19; left += TS-16) {
4838 mrow = MIN (top+TS, height-3);
4839 mcol = MIN (left+TS, width-3);
4840 for (row=top; row < mrow; row++)
4841 for (col=left; col < mcol; col++)
4842 memcpy (rgb[0][row-top][col-left], image[row*width+col], 6);
4843 FORC3 memcpy (rgb[c+1], rgb[0], sizeof *rgb);
4845 /* Interpolate green horizontally, vertically, and along both diagonals: */
4846 for (row=top; row < mrow; row++)
4847 for (col=left; col < mcol; col++) {
4848 if ((f = fcol(row,col)) == 1) continue;
4849 pix = image + row*width + col;
4850 hex = allhex[row % 3][col % 3][0];
4851 color[1][0] = 174 * (pix[ hex[1]][1] + pix[ hex[0]][1]) -
4852 46 * (pix[2*hex[1]][1] + pix[2*hex[0]][1]);
4853 color[1][1] = 223 * pix[ hex[3]][1] + pix[ hex[2]][1] * 33 +
4854 92 * (pix[ 0 ][f] - pix[ -hex[2]][f]);
4855 FORC(2) color[1][2+c] =
4856 164 * pix[hex[4+c]][1] + 92 * pix[-2*hex[4+c]][1] + 33 *
4857 (2*pix[0][f] - pix[3*hex[4+c]][f] - pix[-3*hex[4+c]][f]);
4858 FORC4 rgb[c^!((row-sgrow) % 3)][row-top][col-left][1] =
4859 LIM(color[1][c] >> 8,pix[0][1],pix[0][3]);
4862 for (pass=0; pass < passes; pass++) {
4864 memcpy (rgb+=4, buffer, 4*sizeof *rgb);
4866 /* Recalculate green from interpolated values of closer pixels: */
4868 for (row=top+2; row < mrow-2; row++)
4869 for (col=left+2; col < mcol-2; col++) {
4870 if ((f = fcol(row,col)) == 1) continue;
4871 pix = image + row*width + col;
4872 hex = allhex[row % 3][col % 3][1];
4873 for (d=3; d < 6; d++) {
4874 rix = &rgb[(d-2)^!((row-sgrow) % 3)][row-top][col-left];
4875 val = rix[-2*hex[d]][1] + 2*rix[hex[d]][1]
4876 - rix[-2*hex[d]][f] - 2*rix[hex[d]][f] + 3*rix[0][f];
4877 rix[0][1] = LIM(val/3,pix[0][1],pix[0][3]);
4882 /* Interpolate red and blue values for solitary green pixels: */
4883 for (row=(top-sgrow+4)/3*3+sgrow; row < mrow-2; row+=3)
4884 for (col=(left-sgcol+4)/3*3+sgcol; col < mcol-2; col+=3) {
4885 rix = &rgb[0][row-top][col-left];
4886 h = fcol(row,col+1);
4887 memset (diff, 0, sizeof diff);
4888 for (i=1, d=0; d < 6; d++, i^=TS^1, h^=2) {
4889 for (c=0; c < 2; c++, h^=2) {
4890 g = 2*rix[0][1] - rix[i<<c][1] - rix[-i<<c][1];
4891 color[h][d] = g + rix[i<<c][h] + rix[-i<<c][h];
4893 diff[d] += SQR (rix[i<<c][1] - rix[-i<<c][1]
4894 - rix[i<<c][h] + rix[-i<<c][h]) + SQR(g);
4896 if (d > 1 && (d & 1))
4897 if (diff[d-1] < diff[d])
4898 FORC(2) color[c*2][d] = color[c*2][d-1];
4899 if (d < 2 || (d & 1)) {
4900 FORC(2) rix[0][c*2] = CLIP(color[c*2][d]/2);
4906 /* Interpolate red for blue pixels and vice versa: */
4907 for (row=top+3; row < mrow-3; row++)
4908 for (col=left+3; col < mcol-3; col++) {
4909 if ((f = 2-fcol(row,col)) == 1) continue;
4910 rix = &rgb[0][row-top][col-left];
4911 c = (row-sgrow) % 3 ? TS:1;
4912 h = 3 * (c ^ TS ^ 1);
4913 for (d=0; d < 4; d++, rix += TS*TS) {
4914 i = d > 1 || ((d ^ c) & 1) ||
4915 ((ABS(rix[0][1]-rix[c][1])+ABS(rix[0][1]-rix[-c][1])) <
4916 2*(ABS(rix[0][1]-rix[h][1])+ABS(rix[0][1]-rix[-h][1]))) ? c:h;
4917 rix[0][f] = CLIP((rix[i][f] + rix[-i][f] +
4918 2*rix[0][1] - rix[i][1] - rix[-i][1])/2);
4922 /* Fill in red and blue for 2x2 blocks of green: */
4923 for (row=top+2; row < mrow-2; row++) if ((row-sgrow) % 3)
4924 for (col=left+2; col < mcol-2; col++) if ((col-sgcol) % 3) {
4925 rix = &rgb[0][row-top][col-left];
4926 hex = allhex[row % 3][col % 3][1];
4927 for (d=0; d < ndir; d+=2, rix += TS*TS)
4928 if (hex[d] + hex[d+1]) {
4929 g = 3*rix[0][1] - 2*rix[hex[d]][1] - rix[hex[d+1]][1];
4930 for (c=0; c < 4; c+=2) rix[0][c] =
4931 CLIP((g + 2*rix[hex[d]][c] + rix[hex[d+1]][c])/3);
4933 g = 2*rix[0][1] - rix[hex[d]][1] - rix[hex[d+1]][1];
4934 for (c=0; c < 4; c+=2) rix[0][c] =
4935 CLIP((g + rix[hex[d]][c] + rix[hex[d+1]][c])/2);
4939 rgb = (ushort(*)[TS][TS][3]) buffer;
4943 /* Convert to CIELab and differentiate in all directions: */
4944 for (d=0; d < ndir; d++) {
4945 for (row=2; row < mrow-2; row++)
4946 for (col=2; col < mcol-2; col++)
4947 cielab (rgb[d][row][col], lab[row][col]);
4948 for (f=dir[d & 3],row=3; row < mrow-3; row++)
4949 for (col=3; col < mcol-3; col++) {
4950 lix = &lab[row][col];
4951 g = 2*lix[0][0] - lix[f][0] - lix[-f][0];
4952 drv[d][row][col] = SQR(g)
4953 + SQR((2*lix[0][1] - lix[f][1] - lix[-f][1] + g*500/232))
4954 + SQR((2*lix[0][2] - lix[f][2] - lix[-f][2] - g*500/580));
4958 /* Build homogeneity maps from the derivatives: */
4959 memset(homo, 0, ndir*TS*TS);
4960 for (row=4; row < mrow-4; row++)
4961 for (col=4; col < mcol-4; col++) {
4962 for (tr=FLT_MAX, d=0; d < ndir; d++)
4963 if (tr > drv[d][row][col])
4964 tr = drv[d][row][col];
4966 for (d=0; d < ndir; d++)
4967 for (v=-1; v <= 1; v++)
4968 for (h=-1; h <= 1; h++)
4969 if (drv[d][row+v][col+h] <= tr)
4970 homo[d][row][col]++;
4973 /* Average the most homogenous pixels for the final result: */
4974 if (height-top < TS+4) mrow = height-top+2;
4975 if (width-left < TS+4) mcol = width-left+2;
4976 for (row = MIN(top,8); row < mrow-8; row++)
4977 for (col = MIN(left,8); col < mcol-8; col++) {
4978 for (d=0; d < ndir; d++)
4979 for (hm[d]=0, v=-2; v <= 2; v++)
4980 for (h=-2; h <= 2; h++)
4981 hm[d] += homo[d][row+v][col+h];
4982 for (d=0; d < ndir-4; d++)
4983 if (hm[d] < hm[d+4]) hm[d ] = 0; else
4984 if (hm[d] > hm[d+4]) hm[d+4] = 0;
4985 for (max=hm[0],d=1; d < ndir; d++)
4986 if (max < hm[d]) max = hm[d];
4988 memset (avg, 0, sizeof avg);
4989 for (d=0; d < ndir; d++)
4991 FORC3 avg[c] += rgb[d][row][col][c];
4994 FORC3 image[(row+top)*width+col+left][c] = avg[c]/avg[3];
4998 border_interpolate(8);
5003 Adaptive Homogeneity-Directed interpolation is based on
5004 the work of Keigo Hirakawa, Thomas Parks, and Paul Lee.
5006 void CLASS ahd_interpolate()
5008 int i, j, top, left, row, col, tr, tc, c, d, val, hm[2];
5009 static const int dir[4] = { -1, 1, -TS, TS };
5010 unsigned ldiff[2][4], abdiff[2][4], leps, abeps;
5011 ushort (*rgb)[TS][TS][3], (*rix)[3], (*pix)[4];
5012 short (*lab)[TS][TS][3], (*lix)[3];
5013 char (*homo)[TS][TS], *buffer;
5015 if (verbose) fprintf (stderr,_("AHD interpolation...\n"));
5018 border_interpolate(5);
5019 buffer = (char *) malloc (26*TS*TS);
5020 merror (buffer, "ahd_interpolate()");
5021 rgb = (ushort(*)[TS][TS][3]) buffer;
5022 lab = (short (*)[TS][TS][3])(buffer + 12*TS*TS);
5023 homo = (char (*)[TS][TS]) (buffer + 24*TS*TS);
5025 for (top=2; top < height-5; top += TS-6)
5026 for (left=2; left < width-5; left += TS-6) {
5028 /* Interpolate green horizontally and vertically: */
5029 for (row=top; row < top+TS && row < height-2; row++) {
5030 col = left + (FC(row,left) & 1);
5031 for (c = FC(row,col); col < left+TS && col < width-2; col+=2) {
5032 pix = image + row*width+col;
5033 val = ((pix[-1][1] + pix[0][c] + pix[1][1]) * 2
5034 - pix[-2][c] - pix[2][c]) >> 2;
5035 rgb[0][row-top][col-left][1] = ULIM(val,pix[-1][1],pix[1][1]);
5036 val = ((pix[-width][1] + pix[0][c] + pix[width][1]) * 2
5037 - pix[-2*width][c] - pix[2*width][c]) >> 2;
5038 rgb[1][row-top][col-left][1] = ULIM(val,pix[-width][1],pix[width][1]);
5041 /* Interpolate red and blue, and convert to CIELab: */
5042 for (d=0; d < 2; d++)
5043 for (row=top+1; row < top+TS-1 && row < height-3; row++)
5044 for (col=left+1; col < left+TS-1 && col < width-3; col++) {
5045 pix = image + row*width+col;
5046 rix = &rgb[d][row-top][col-left];
5047 lix = &lab[d][row-top][col-left];
5048 if ((c = 2 - FC(row,col)) == 1) {
5050 val = pix[0][1] + (( pix[-1][2-c] + pix[1][2-c]
5051 - rix[-1][1] - rix[1][1] ) >> 1);
5052 rix[0][2-c] = CLIP(val);
5053 val = pix[0][1] + (( pix[-width][c] + pix[width][c]
5054 - rix[-TS][1] - rix[TS][1] ) >> 1);
5056 val = rix[0][1] + (( pix[-width-1][c] + pix[-width+1][c]
5057 + pix[+width-1][c] + pix[+width+1][c]
5058 - rix[-TS-1][1] - rix[-TS+1][1]
5059 - rix[+TS-1][1] - rix[+TS+1][1] + 1) >> 2);
5060 rix[0][c] = CLIP(val);
5062 rix[0][c] = pix[0][c];
5063 cielab (rix[0],lix[0]);
5065 /* Build homogeneity maps from the CIELab images: */
5066 memset (homo, 0, 2*TS*TS);
5067 for (row=top+2; row < top+TS-2 && row < height-4; row++) {
5069 for (col=left+2; col < left+TS-2 && col < width-4; col++) {
5071 for (d=0; d < 2; d++) {
5072 lix = &lab[d][tr][tc];
5073 for (i=0; i < 4; i++) {
5074 ldiff[d][i] = ABS(lix[0][0]-lix[dir[i]][0]);
5075 abdiff[d][i] = SQR(lix[0][1]-lix[dir[i]][1])
5076 + SQR(lix[0][2]-lix[dir[i]][2]);
5079 leps = MIN(MAX(ldiff[0][0],ldiff[0][1]),
5080 MAX(ldiff[1][2],ldiff[1][3]));
5081 abeps = MIN(MAX(abdiff[0][0],abdiff[0][1]),
5082 MAX(abdiff[1][2],abdiff[1][3]));
5083 for (d=0; d < 2; d++)
5084 for (i=0; i < 4; i++)
5085 if (ldiff[d][i] <= leps && abdiff[d][i] <= abeps)
5089 /* Combine the most homogenous pixels for the final result: */
5090 for (row=top+3; row < top+TS-3 && row < height-5; row++) {
5092 for (col=left+3; col < left+TS-3 && col < width-5; col++) {
5094 for (d=0; d < 2; d++)
5095 for (hm[d]=0, i=tr-1; i <= tr+1; i++)
5096 for (j=tc-1; j <= tc+1; j++)
5097 hm[d] += homo[d][i][j];
5099 FORC3 image[row*width+col][c] = rgb[hm[1] > hm[0]][tr][tc][c];
5101 FORC3 image[row*width+col][c] =
5102 (rgb[0][tr][tc][c] + rgb[1][tr][tc][c]) >> 1;
5110 void CLASS median_filter()
5113 int pass, c, i, j, k, med[9];
5114 static const uchar opt[] = /* Optimal 9-element median search */
5115 { 1,2, 4,5, 7,8, 0,1, 3,4, 6,7, 1,2, 4,5, 7,8,
5116 0,3, 5,8, 4,7, 3,6, 1,4, 2,5, 4,7, 4,2, 6,4, 4,2 };
5118 for (pass=1; pass <= med_passes; pass++) {
5120 fprintf (stderr,_("Median filter pass %d...\n"), pass);
5121 for (c=0; c < 3; c+=2) {
5122 for (pix = image; pix < image+width*height; pix++)
5123 pix[0][3] = pix[0][c];
5124 for (pix = image+width; pix < image+width*(height-1); pix++) {
5125 if ((pix-image+1) % width < 2) continue;
5126 for (k=0, i = -width; i <= width; i += width)
5127 for (j = i-1; j <= i+1; j++)
5128 med[k++] = pix[j][3] - pix[j][1];
5129 for (i=0; i < sizeof opt; i+=2)
5130 if (med[opt[i]] > med[opt[i+1]])
5131 SWAP (med[opt[i]] , med[opt[i+1]]);
5132 pix[0][c] = CLIP(med[4] + pix[0][1]);
5138 void CLASS blend_highlights()
5140 int clip=INT_MAX, row, col, c, i, j;
5141 static const float trans[2][4][4] =
5142 { { { 1,1,1 }, { 1.7320508,-1.7320508,0 }, { -1,-1,2 } },
5143 { { 1,1,1,1 }, { 1,-1,1,-1 }, { 1,1,-1,-1 }, { 1,-1,-1,1 } } };
5144 static const float itrans[2][4][4] =
5145 { { { 1,0.8660254,-0.5 }, { 1,-0.8660254,-0.5 }, { 1,0,1 } },
5146 { { 1,1,1,1 }, { 1,-1,1,-1 }, { 1,1,-1,-1 }, { 1,-1,-1,1 } } };
5147 float cam[2][4], lab[2][4], sum[2], chratio;
5149 if ((unsigned) (colors-3) > 1) return;
5150 if (verbose) fprintf (stderr,_("Blending highlights...\n"));
5151 FORCC if (clip > (i = 65535*pre_mul[c])) clip = i;
5152 for (row=0; row < height; row++)
5153 for (col=0; col < width; col++) {
5154 FORCC if (image[row*width+col][c] > clip) break;
5155 if (c == colors) continue;
5157 cam[0][c] = image[row*width+col][c];
5158 cam[1][c] = MIN(cam[0][c],clip);
5160 for (i=0; i < 2; i++) {
5161 FORCC for (lab[i][c]=j=0; j < colors; j++)
5162 lab[i][c] += trans[colors-3][c][j] * cam[i][j];
5163 for (sum[i]=0,c=1; c < colors; c++)
5164 sum[i] += SQR(lab[i][c]);
5166 chratio = sqrt(sum[1]/sum[0]);
5167 for (c=1; c < colors; c++)
5168 lab[0][c] *= chratio;
5169 FORCC for (cam[0][c]=j=0; j < colors; j++)
5170 cam[0][c] += itrans[colors-3][c][j] * lab[0][j];
5171 FORCC image[row*width+col][c] = cam[0][c] / colors;
5175 #define SCALE (4 >> shrink)
5176 void CLASS recover_highlights()
5178 float *map, sum, wgt, grow;
5179 int hsat[4], count, spread, change, val, i;
5180 unsigned high, wide, mrow, mcol, row, col, kc, c, d, y, x;
5182 static const signed char dir[8][2] =
5183 { {-1,-1}, {-1,0}, {-1,1}, {0,1}, {1,1}, {1,0}, {1,-1}, {0,-1} };
5185 if (verbose) fprintf (stderr,_("Rebuilding highlights...\n"));
5187 grow = pow (2, 4-highlight);
5188 FORCC hsat[c] = 32000 * pre_mul[c];
5189 for (kc=0, c=1; c < colors; c++)
5190 if (pre_mul[kc] < pre_mul[c]) kc = c;
5191 high = height / SCALE;
5192 wide = width / SCALE;
5193 map = (float *) calloc (high, wide*sizeof *map);
5194 merror (map, "recover_highlights()");
5195 FORCC if (c != kc) {
5196 memset (map, 0, high*wide*sizeof *map);
5197 for (mrow=0; mrow < high; mrow++)
5198 for (mcol=0; mcol < wide; mcol++) {
5199 sum = wgt = count = 0;
5200 for (row = mrow*SCALE; row < (mrow+1)*SCALE; row++)
5201 for (col = mcol*SCALE; col < (mcol+1)*SCALE; col++) {
5202 pixel = image[row*width+col];
5203 if (pixel[c] / hsat[c] == 1 && pixel[kc] > 24000) {
5209 if (count == SCALE*SCALE)
5210 map[mrow*wide+mcol] = sum / wgt;
5212 for (spread = 32/grow; spread--; ) {
5213 for (mrow=0; mrow < high; mrow++)
5214 for (mcol=0; mcol < wide; mcol++) {
5215 if (map[mrow*wide+mcol]) continue;
5217 for (d=0; d < 8; d++) {
5218 y = mrow + dir[d][0];
5219 x = mcol + dir[d][1];
5220 if (y < high && x < wide && map[y*wide+x] > 0) {
5221 sum += (1 + (d & 1)) * map[y*wide+x];
5222 count += 1 + (d & 1);
5226 map[mrow*wide+mcol] = - (sum+grow) / (count+grow);
5228 for (change=i=0; i < high*wide; i++)
5235 for (i=0; i < high*wide; i++)
5236 if (map[i] == 0) map[i] = 1;
5237 for (mrow=0; mrow < high; mrow++)
5238 for (mcol=0; mcol < wide; mcol++) {
5239 for (row = mrow*SCALE; row < (mrow+1)*SCALE; row++)
5240 for (col = mcol*SCALE; col < (mcol+1)*SCALE; col++) {
5241 pixel = image[row*width+col];
5242 if (pixel[c] / hsat[c] > 1) {
5243 val = pixel[kc] * map[mrow*wide+mcol];
5244 if (pixel[c] < val) pixel[c] = CLIP(val);
5253 void CLASS tiff_get (unsigned base,
5254 unsigned *tag, unsigned *type, unsigned *len, unsigned *save)
5259 *save = ftell(ifp) + 4;
5260 if (*len * ("11124811248484"[*type < 14 ? *type:0]-'0') > 4)
5261 fseek (ifp, get4()+base, SEEK_SET);
5264 void CLASS parse_thumb_note (int base, unsigned toff, unsigned tlen)
5266 unsigned entries, tag, type, len, save;
5270 tiff_get (base, &tag, &type, &len, &save);
5271 if (tag == toff) thumb_offset = get4()+base;
5272 if (tag == tlen) thumb_length = get4();
5273 fseek (ifp, save, SEEK_SET);
5277 int CLASS parse_tiff_ifd (int base);
5279 void CLASS parse_makernote (int base, int uptag)
5281 static const uchar xlat[2][256] = {
5282 { 0xc1,0xbf,0x6d,0x0d,0x59,0xc5,0x13,0x9d,0x83,0x61,0x6b,0x4f,0xc7,0x7f,0x3d,0x3d,
5283 0x53,0x59,0xe3,0xc7,0xe9,0x2f,0x95,0xa7,0x95,0x1f,0xdf,0x7f,0x2b,0x29,0xc7,0x0d,
5284 0xdf,0x07,0xef,0x71,0x89,0x3d,0x13,0x3d,0x3b,0x13,0xfb,0x0d,0x89,0xc1,0x65,0x1f,
5285 0xb3,0x0d,0x6b,0x29,0xe3,0xfb,0xef,0xa3,0x6b,0x47,0x7f,0x95,0x35,0xa7,0x47,0x4f,
5286 0xc7,0xf1,0x59,0x95,0x35,0x11,0x29,0x61,0xf1,0x3d,0xb3,0x2b,0x0d,0x43,0x89,0xc1,
5287 0x9d,0x9d,0x89,0x65,0xf1,0xe9,0xdf,0xbf,0x3d,0x7f,0x53,0x97,0xe5,0xe9,0x95,0x17,
5288 0x1d,0x3d,0x8b,0xfb,0xc7,0xe3,0x67,0xa7,0x07,0xf1,0x71,0xa7,0x53,0xb5,0x29,0x89,
5289 0xe5,0x2b,0xa7,0x17,0x29,0xe9,0x4f,0xc5,0x65,0x6d,0x6b,0xef,0x0d,0x89,0x49,0x2f,
5290 0xb3,0x43,0x53,0x65,0x1d,0x49,0xa3,0x13,0x89,0x59,0xef,0x6b,0xef,0x65,0x1d,0x0b,
5291 0x59,0x13,0xe3,0x4f,0x9d,0xb3,0x29,0x43,0x2b,0x07,0x1d,0x95,0x59,0x59,0x47,0xfb,
5292 0xe5,0xe9,0x61,0x47,0x2f,0x35,0x7f,0x17,0x7f,0xef,0x7f,0x95,0x95,0x71,0xd3,0xa3,
5293 0x0b,0x71,0xa3,0xad,0x0b,0x3b,0xb5,0xfb,0xa3,0xbf,0x4f,0x83,0x1d,0xad,0xe9,0x2f,
5294 0x71,0x65,0xa3,0xe5,0x07,0x35,0x3d,0x0d,0xb5,0xe9,0xe5,0x47,0x3b,0x9d,0xef,0x35,
5295 0xa3,0xbf,0xb3,0xdf,0x53,0xd3,0x97,0x53,0x49,0x71,0x07,0x35,0x61,0x71,0x2f,0x43,
5296 0x2f,0x11,0xdf,0x17,0x97,0xfb,0x95,0x3b,0x7f,0x6b,0xd3,0x25,0xbf,0xad,0xc7,0xc5,
5297 0xc5,0xb5,0x8b,0xef,0x2f,0xd3,0x07,0x6b,0x25,0x49,0x95,0x25,0x49,0x6d,0x71,0xc7 },
5298 { 0xa7,0xbc,0xc9,0xad,0x91,0xdf,0x85,0xe5,0xd4,0x78,0xd5,0x17,0x46,0x7c,0x29,0x4c,
5299 0x4d,0x03,0xe9,0x25,0x68,0x11,0x86,0xb3,0xbd,0xf7,0x6f,0x61,0x22,0xa2,0x26,0x34,
5300 0x2a,0xbe,0x1e,0x46,0x14,0x68,0x9d,0x44,0x18,0xc2,0x40,0xf4,0x7e,0x5f,0x1b,0xad,
5301 0x0b,0x94,0xb6,0x67,0xb4,0x0b,0xe1,0xea,0x95,0x9c,0x66,0xdc,0xe7,0x5d,0x6c,0x05,
5302 0xda,0xd5,0xdf,0x7a,0xef,0xf6,0xdb,0x1f,0x82,0x4c,0xc0,0x68,0x47,0xa1,0xbd,0xee,
5303 0x39,0x50,0x56,0x4a,0xdd,0xdf,0xa5,0xf8,0xc6,0xda,0xca,0x90,0xca,0x01,0x42,0x9d,
5304 0x8b,0x0c,0x73,0x43,0x75,0x05,0x94,0xde,0x24,0xb3,0x80,0x34,0xe5,0x2c,0xdc,0x9b,
5305 0x3f,0xca,0x33,0x45,0xd0,0xdb,0x5f,0xf5,0x52,0xc3,0x21,0xda,0xe2,0x22,0x72,0x6b,
5306 0x3e,0xd0,0x5b,0xa8,0x87,0x8c,0x06,0x5d,0x0f,0xdd,0x09,0x19,0x93,0xd0,0xb9,0xfc,
5307 0x8b,0x0f,0x84,0x60,0x33,0x1c,0x9b,0x45,0xf1,0xf0,0xa3,0x94,0x3a,0x12,0x77,0x33,
5308 0x4d,0x44,0x78,0x28,0x3c,0x9e,0xfd,0x65,0x57,0x16,0x94,0x6b,0xfb,0x59,0xd0,0xc8,
5309 0x22,0x36,0xdb,0xd2,0x63,0x98,0x43,0xa1,0x04,0x87,0x86,0xf7,0xa6,0x26,0xbb,0xd6,
5310 0x59,0x4d,0xbf,0x6a,0x2e,0xaa,0x2b,0xef,0xe6,0x78,0xb6,0x4e,0xe0,0x2f,0xdc,0x7c,
5311 0xbe,0x57,0x19,0x32,0x7e,0x2a,0xd0,0xb8,0xba,0x29,0x00,0x3c,0x52,0x7d,0xa8,0x49,
5312 0x3b,0x2d,0xeb,0x25,0x49,0xfa,0xa3,0xaa,0x39,0xa7,0xc5,0xa7,0x50,0x11,0x36,0xfb,
5313 0xc6,0x67,0x4a,0xf5,0xa5,0x12,0x65,0x7e,0xb0,0xdf,0xaf,0x4e,0xb3,0x61,0x7f,0x2f } };
5314 unsigned offset=0, entries, tag, type, len, save, c;
5315 unsigned ver97=0, serial=0, i, wbi=0, wb[4]={0,0,0,0};
5316 uchar buf97[324], ci, cj, ck;
5317 short morder, sorder=order;
5320 The MakerNote might have its own TIFF header (possibly with
5321 its own byte-order!), or it might just be a table.
5323 if (!strcmp(make,"Nokia")) return;
5324 fread (buf, 1, 10, ifp);
5325 if (!strncmp (buf,"KDK" ,3) || /* these aren't TIFF tables */
5326 !strncmp (buf,"VER" ,3) ||
5327 !strncmp (buf,"IIII",4) ||
5328 !strncmp (buf,"MMMM",4)) return;
5329 if (!strncmp (buf,"KC" ,2) || /* Konica KD-400Z, KD-510Z */
5330 !strncmp (buf,"MLY" ,3)) { /* Minolta DiMAGE G series */
5332 while ((i=ftell(ifp)) < data_offset && i < 16384) {
5333 wb[0] = wb[2]; wb[2] = wb[1]; wb[1] = wb[3];
5335 if (wb[1] == 256 && wb[3] == 256 &&
5336 wb[0] > 256 && wb[0] < 640 && wb[2] > 256 && wb[2] < 640)
5337 FORC4 cam_mul[c] = wb[c];
5341 if (!strcmp (buf,"Nikon")) {
5344 if (get2() != 42) goto quit;
5346 fseek (ifp, offset-8, SEEK_CUR);
5347 } else if (!strcmp (buf,"OLYMPUS") ||
5348 !strcmp (buf,"PENTAX ")) {
5349 base = ftell(ifp)-10;
5350 fseek (ifp, -2, SEEK_CUR);
5352 if (buf[0] == 'O') get2();
5353 } else if (!strncmp (buf,"SONY",4) ||
5354 !strcmp (buf,"Panasonic")) {
5356 } else if (!strncmp (buf,"FUJIFILM",8)) {
5357 base = ftell(ifp)-10;
5359 fseek (ifp, 2, SEEK_CUR);
5360 } else if (!strcmp (buf,"OLYMP") ||
5361 !strcmp (buf,"LEICA") ||
5362 !strcmp (buf,"Ricoh") ||
5363 !strcmp (buf,"EPSON"))
5364 fseek (ifp, -2, SEEK_CUR);
5365 else if (!strcmp (buf,"AOC") ||
5366 !strcmp (buf,"QVC"))
5367 fseek (ifp, -4, SEEK_CUR);
5369 fseek (ifp, -10, SEEK_CUR);
5370 if (!strncmp(make,"SAMSUNG",7))
5374 if (entries > 1000) return;
5378 tiff_get (base, &tag, &type, &len, &save);
5380 if (tag == 2 && strstr(make,"NIKON") && !iso_speed)
5381 iso_speed = (get2(),get2());
5382 if (tag == 4 && len > 26 && len < 35) {
5383 if ((i=(get4(),get2())) != 0x7fff && !iso_speed)
5384 iso_speed = 50 * pow (2, i/32.0 - 4);
5385 if ((i=(get2(),get2())) != 0x7fff && !aperture)
5386 aperture = pow (2, i/64.0);
5387 if ((i=get2()) != 0xffff && !shutter)
5388 shutter = pow (2, (short) i/-32.0);
5389 wbi = (get2(),get2());
5390 shot_order = (get2(),get2());
5392 if ((tag == 4 || tag == 0x114) && !strncmp(make,"KONICA",6)) {
5393 fseek (ifp, tag == 4 ? 140:160, SEEK_CUR);
5395 case 72: flip = 0; break;
5396 case 76: flip = 6; break;
5397 case 82: flip = 5; break;
5400 if (tag == 7 && type == 2 && len > 20)
5401 fgets (model2, 64, ifp);
5402 if (tag == 8 && type == 4)
5403 shot_order = get4();
5404 if (tag == 9 && !strcmp(make,"Canon"))
5405 fread (artist, 64, 1, ifp);
5406 if (tag == 0xc && len == 4)
5407 FORC3 cam_mul[(c << 1 | c >> 1) & 3] = getreal(type);
5408 if (tag == 0xd && type == 7 && get2() == 0xaaaa) {
5409 for (c=i=2; (ushort) c != 0xbbbb && i < len; i++)
5410 c = c << 8 | fgetc(ifp);
5411 while ((i+=4) < len-5)
5412 if (get4() == 257 && (i=len) && (c = (get4(),fgetc(ifp))) < 3)
5413 flip = "065"[c]-'0';
5415 if (tag == 0x10 && type == 4)
5417 if (tag == 0x11 && is_raw && !strncmp(make,"NIKON",5)) {
5418 fseek (ifp, get4()+base, SEEK_SET);
5419 parse_tiff_ifd (base);
5421 if (tag == 0x14 && type == 7) {
5423 fseek (ifp, 1248, SEEK_CUR);
5426 fread (buf, 1, 10, ifp);
5427 if (!strncmp(buf,"NRW ",4)) {
5428 fseek (ifp, strcmp(buf+4,"0100") ? 46:1546, SEEK_CUR);
5429 cam_mul[0] = get4() << 2;
5430 cam_mul[1] = get4() + get4();
5431 cam_mul[2] = get4() << 2;
5434 if (tag == 0x15 && type == 2 && is_raw)
5435 fread (model, 64, 1, ifp);
5436 if (strstr(make,"PENTAX")) {
5437 if (tag == 0x1b) tag = 0x1018;
5438 if (tag == 0x1c) tag = 0x1017;
5441 while ((c = fgetc(ifp)) && c != EOF)
5442 serial = serial*10 + (isdigit(c) ? c - '0' : c % 10);
5443 if (tag == 0x29 && type == 1) {
5444 c = wbi < 18 ? "012347800000005896"[wbi]-'0' : 0;
5445 fseek (ifp, 8 + c*32, SEEK_CUR);
5446 FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get4();
5448 if (tag == 0x3d && type == 3 && len == 4)
5449 FORC4 cblack[c ^ c >> 1] = get2() >> (14-tiff_bps);
5450 if (tag == 0x81 && type == 4) {
5451 data_offset = get4();
5452 fseek (ifp, data_offset + 41, SEEK_SET);
5453 raw_height = get2() * 2;
5455 filters = 0x61616161;
5457 if ((tag == 0x81 && type == 7) ||
5458 (tag == 0x100 && type == 7) ||
5459 (tag == 0x280 && type == 1)) {
5460 thumb_offset = ftell(ifp);
5463 if (tag == 0x88 && type == 4 && (thumb_offset = get4()))
5464 thumb_offset += base;
5465 if (tag == 0x89 && type == 4)
5466 thumb_length = get4();
5467 if (tag == 0x8c || tag == 0x96)
5468 meta_offset = ftell(ifp);
5470 for (i=0; i < 4; i++)
5471 ver97 = ver97 * 10 + fgetc(ifp)-'0';
5474 fseek (ifp, 68, SEEK_CUR);
5475 FORC4 cam_mul[(c >> 1) | ((c & 1) << 1)] = get2();
5478 fseek (ifp, 6, SEEK_CUR);
5479 FORC4 cam_mul[c ^ (c >> 1)] = get2();
5482 fseek (ifp, 16, SEEK_CUR);
5483 FORC4 cam_mul[c] = get2();
5486 if (ver97 != 205) fseek (ifp, 280, SEEK_CUR);
5487 fread (buf97, 324, 1, ifp);
5490 if (tag == 0xa1 && type == 7) {
5492 fseek (ifp, 140, SEEK_CUR);
5493 FORC3 cam_mul[c] = get4();
5495 if (tag == 0xa4 && type == 3) {
5496 fseek (ifp, wbi*48, SEEK_CUR);
5497 FORC3 cam_mul[c] = get2();
5499 if (tag == 0xa7 && (unsigned) (ver97-200) < 17) {
5500 ci = xlat[0][serial & 0xff];
5501 cj = xlat[1][fgetc(ifp)^fgetc(ifp)^fgetc(ifp)^fgetc(ifp)];
5503 for (i=0; i < 324; i++)
5504 buf97[i] ^= (cj += ci * ck++);
5505 i = "66666>666;6A;:;55"[ver97-200] - '0';
5506 FORC4 cam_mul[c ^ (c >> 1) ^ (i & 1)] =
5507 sget2 (buf97 + (i & -2) + c*2);
5509 if (tag == 0x200 && len == 3)
5510 shot_order = (get4(),get4());
5511 if (tag == 0x200 && len == 4)
5512 FORC4 cblack[c ^ c >> 1] = get2();
5513 if (tag == 0x201 && len == 4)
5514 FORC4 cam_mul[c ^ (c >> 1)] = get2();
5515 if (tag == 0x220 && type == 7)
5516 meta_offset = ftell(ifp);
5517 if (tag == 0x401 && type == 4 && len == 4)
5518 FORC4 cblack[c ^ c >> 1] = get4();
5519 if (tag == 0xe01) { /* Nikon Capture Note */
5521 fseek (ifp, 22, SEEK_CUR);
5522 for (offset=22; offset+22 < len; offset += 22+i) {
5524 fseek (ifp, 14, SEEK_CUR);
5526 if (tag == 0x76a43207) flip = get2();
5527 else fseek (ifp, i, SEEK_CUR);
5530 if (tag == 0xe80 && len == 256 && type == 7) {
5531 fseek (ifp, 48, SEEK_CUR);
5532 cam_mul[0] = get2() * 508 * 1.078 / 0x10000;
5533 cam_mul[2] = get2() * 382 * 1.173 / 0x10000;
5535 if (tag == 0xf00 && type == 7) {
5537 fseek (ifp, 176, SEEK_CUR);
5538 else if (len == 734 || len == 1502)
5539 fseek (ifp, 148, SEEK_CUR);
5543 if ((tag == 0x1011 && len == 9) || tag == 0x20400200)
5544 for (i=0; i < 3; i++)
5545 FORC3 cmatrix[i][c] = ((short) get2()) / 256.0;
5546 if ((tag == 0x1012 || tag == 0x20400600) && len == 4)
5547 FORC4 cblack[c ^ c >> 1] = get2();
5548 if (tag == 0x1017 || tag == 0x20400100)
5549 cam_mul[0] = get2() / 256.0;
5550 if (tag == 0x1018 || tag == 0x20400100)
5551 cam_mul[2] = get2() / 256.0;
5552 if (tag == 0x2011 && len == 2) {
5555 cam_mul[0] = get2() / 256.0;
5556 cam_mul[2] = get2() / 256.0;
5558 if ((tag | 0x70) == 0x2070 && (type == 4 || type == 13))
5559 fseek (ifp, get4()+base, SEEK_SET);
5560 if (tag == 0x2020 && !strncmp(buf,"OLYMP",5))
5561 parse_thumb_note (base, 257, 258);
5563 parse_makernote (base, 0x2040);
5564 if (tag == 0xb028) {
5565 fseek (ifp, get4()+base, SEEK_SET);
5566 parse_thumb_note (base, 136, 137);
5568 if (tag == 0x4001 && len > 500) {
5569 i = len == 582 ? 50 : len == 653 ? 68 : len == 5120 ? 142 : 126;
5570 fseek (ifp, i, SEEK_CUR);
5571 FORC4 cam_mul[c ^ (c >> 1)] = get2();
5572 for (i+=18; i <= len; i+=10) {
5574 FORC4 sraw_mul[c ^ (c >> 1)] = get2();
5575 if (sraw_mul[1] == 1170) break;
5578 if (tag == 0x4021 && get4() && get4())
5579 FORC4 cam_mul[c] = 1024;
5581 FORC4 cam_mul[c ^ (c >> 1)] = get4();
5583 FORC4 cam_mul[c ^ (c >> 1)] -= get4();
5587 fseek (ifp, save, SEEK_SET);
5594 Since the TIFF DateTime string has no timezone information,
5595 assume that the camera's clock was set to Universal Time.
5597 void CLASS get_timestamp (int reversed)
5605 for (i=19; i--; ) str[i] = fgetc(ifp);
5607 fread (str, 19, 1, ifp);
5608 memset (&t, 0, sizeof t);
5609 if (sscanf (str, "%d:%d:%d %d:%d:%d", &t.tm_year, &t.tm_mon,
5610 &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec) != 6)
5616 timestamp = mktime(&t);
5619 void CLASS parse_exif (int base)
5621 unsigned kodak, entries, tag, type, len, save, c;
5624 kodak = !strncmp(make,"EASTMAN",7) && tiff_nifds < 3;
5627 tiff_get (base, &tag, &type, &len, &save);
5629 case 33434: tiff_ifd[tiff_nifds-1].shutter =
5630 shutter = getreal(type); break;
5631 case 33437: aperture = getreal(type); break;
5632 case 34855: iso_speed = get2(); break;
5634 case 36868: get_timestamp(0); break;
5635 case 37377: if ((expo = -getreal(type)) < 128)
5636 tiff_ifd[tiff_nifds-1].shutter =
5637 shutter = pow (2, expo); break;
5638 case 37378: aperture = pow (2, getreal(type)/2); break;
5639 case 37386: focal_len = getreal(type); break;
5640 case 37500: parse_makernote (base, 0); break;
5641 case 40962: if (kodak) raw_width = get4(); break;
5642 case 40963: if (kodak) raw_height = get4(); break;
5644 if (get4() == 0x20002)
5645 for (exif_cfa=c=0; c < 8; c+=2)
5646 exif_cfa |= fgetc(ifp) * 0x01010101 << c;
5648 fseek (ifp, save, SEEK_SET);
5652 void CLASS parse_gps (int base)
5654 unsigned entries, tag, type, len, save, c;
5658 tiff_get (base, &tag, &type, &len, &save);
5660 case 1: case 3: case 5:
5661 gpsdata[29+tag/2] = getc(ifp); break;
5662 case 2: case 4: case 7:
5663 FORC(6) gpsdata[tag/3*6+c] = get4(); break;
5665 FORC(2) gpsdata[18+c] = get4(); break;
5667 fgets ((char *) (gpsdata+14+tag/3), MIN(len,12), ifp);
5669 fseek (ifp, save, SEEK_SET);
5673 void CLASS romm_coeff (float romm_cam[3][3])
5675 static const float rgb_romm[3][3] = /* ROMM == Kodak ProPhoto */
5676 { { 2.034193, -0.727420, -0.306766 },
5677 { -0.228811, 1.231729, -0.002922 },
5678 { -0.008565, -0.153273, 1.161839 } };
5681 for (i=0; i < 3; i++)
5682 for (j=0; j < 3; j++)
5683 for (cmatrix[i][j] = k=0; k < 3; k++)
5684 cmatrix[i][j] += rgb_romm[i][k] * romm_cam[k][j];
5687 void CLASS parse_mos (int offset)
5690 int skip, from, i, c, neut[4], planes=0, frot=0;
5691 static const char *mod[] =
5692 { "","DCB2","Volare","Cantare","CMost","Valeo 6","Valeo 11","Valeo 22",
5693 "Valeo 11p","Valeo 17","","Aptus 17","Aptus 22","Aptus 75","Aptus 65",
5694 "Aptus 54S","Aptus 65S","Aptus 75S","AFi 5","AFi 6","AFi 7",
5695 "AFi-II 7","Aptus-II 7","","Aptus-II 6","","","Aptus-II 10","Aptus-II 5",
5696 "","","","","Aptus-II 10R","Aptus-II 8","","Aptus-II 12","","AFi-II 12" };
5697 float romm_cam[3][3];
5699 fseek (ifp, offset, SEEK_SET);
5701 if (get4() != 0x504b5453) break;
5703 fread (data, 1, 40, ifp);
5706 if (!strcmp(data,"JPEG_preview_data")) {
5707 thumb_offset = from;
5708 thumb_length = skip;
5710 if (!strcmp(data,"icc_camera_profile")) {
5711 profile_offset = from;
5712 profile_length = skip;
5714 if (!strcmp(data,"ShootObj_back_type")) {
5715 fscanf (ifp, "%d", &i);
5716 if ((unsigned) i < sizeof mod / sizeof (*mod))
5717 strcpy (model, mod[i]);
5719 if (!strcmp(data,"icc_camera_to_tone_matrix")) {
5720 for (i=0; i < 9; i++)
5721 ((float *)romm_cam)[i] = int_to_float(get4());
5722 romm_coeff (romm_cam);
5724 if (!strcmp(data,"CaptProf_color_matrix")) {
5725 for (i=0; i < 9; i++)
5726 fscanf (ifp, "%f", (float *)romm_cam + i);
5727 romm_coeff (romm_cam);
5729 if (!strcmp(data,"CaptProf_number_of_planes"))
5730 fscanf (ifp, "%d", &planes);
5731 if (!strcmp(data,"CaptProf_raw_data_rotation"))
5732 fscanf (ifp, "%d", &flip);
5733 if (!strcmp(data,"CaptProf_mosaic_pattern"))
5735 fscanf (ifp, "%d", &i);
5736 if (i == 1) frot = c ^ (c >> 1);
5738 if (!strcmp(data,"ImgProf_rotation_angle")) {
5739 fscanf (ifp, "%d", &i);
5742 if (!strcmp(data,"NeutObj_neutrals") && !cam_mul[0]) {
5743 FORC4 fscanf (ifp, "%d", neut+c);
5744 FORC3 cam_mul[c] = (float) neut[0] / neut[c+1];
5746 if (!strcmp(data,"Rows_data"))
5747 load_flags = get4();
5749 fseek (ifp, skip+from, SEEK_SET);
5752 filters = (planes == 1) * 0x01010101 *
5753 (uchar) "\x94\x61\x16\x49"[(flip/90 + frot) & 3];
5756 void CLASS linear_table (unsigned len)
5759 if (len > 0x1000) len = 0x1000;
5760 read_shorts (curve, len);
5761 for (i=len; i < 0x1000; i++)
5762 curve[i] = curve[i-1];
5763 maximum = curve[0xfff];
5766 void CLASS parse_kodak_ifd (int base)
5768 unsigned entries, tag, type, len, save;
5769 int i, c, wbi=-2, wbtemp=6500;
5770 float mul[3]={1,1,1}, num;
5771 static const int wbtag[] = { 64037,64040,64039,64041,-1,-1,64042 };
5774 if (entries > 1024) return;
5776 tiff_get (base, &tag, &type, &len, &save);
5777 if (tag == 1020) wbi = getint(type);
5778 if (tag == 1021 && len == 72) { /* WB set in software */
5779 fseek (ifp, 40, SEEK_CUR);
5780 FORC3 cam_mul[c] = 2048.0 / get2();
5783 if (tag == 2118) wbtemp = getint(type);
5784 if (tag == 2120 + wbi && wbi >= 0)
5785 FORC3 cam_mul[c] = 2048.0 / getreal(type);
5786 if (tag == 2130 + wbi)
5787 FORC3 mul[c] = getreal(type);
5788 if (tag == 2140 + wbi && wbi >= 0)
5790 for (num=i=0; i < 4; i++)
5791 num += getreal(type) * pow (wbtemp/100.0, i);
5792 cam_mul[c] = 2048 / (num * mul[c]);
5794 if (tag == 2317) linear_table (len);
5795 if (tag == 6020) iso_speed = getint(type);
5796 if (tag == 64013) wbi = fgetc(ifp);
5797 if ((unsigned) wbi < 7 && tag == wbtag[wbi])
5798 FORC3 cam_mul[c] = get4();
5799 if (tag == 64019) width = getint(type);
5800 if (tag == 64020) height = (getint(type)+1) & -2;
5801 fseek (ifp, save, SEEK_SET);
5805 void CLASS parse_minolta (int base);
5806 int CLASS parse_tiff (int base);
5808 int CLASS parse_tiff_ifd (int base)
5810 unsigned entries, tag, type, len, plen=16, save;
5811 int ifd, use_cm=0, cfa, i, j, c, ima_len=0;
5812 char software[64], *cbuf, *cp;
5813 uchar cfa_pat[16], cfa_pc[] = { 0,1,2,3 }, tab[256];
5814 double cc[4][4], cm[4][3], cam_xyz[4][3], num;
5815 double ab[]={ 1,1,1,1 }, asn[] = { 0,0,0,0 }, xyz[] = { 1,1,1 };
5816 unsigned sony_curve[] = { 0,0,0,0,0,4095 };
5817 unsigned *buf, sony_offset=0, sony_length=0, sony_key=0;
5821 if (tiff_nifds >= sizeof tiff_ifd / sizeof tiff_ifd[0])
5824 for (j=0; j < 4; j++)
5825 for (i=0; i < 4; i++)
5828 if (entries > 512) return 1;
5830 tiff_get (base, &tag, &type, &len, &save);
5832 case 5: width = get2(); break;
5833 case 6: height = get2(); break;
5834 case 7: width += get2(); break;
5835 case 9: if ((i = get2())) filters = i; break;
5837 if (type == 3 && len == 1)
5838 cam_mul[(tag-17)*2] = get2() / 256.0;
5841 if (type == 3) iso_speed = get2();
5843 case 28: case 29: case 30:
5844 cblack[tag-28] = get2();
5845 cblack[3] = cblack[1];
5847 case 36: case 37: case 38:
5848 cam_mul[tag-36] = get2();
5851 if (len < 50 || cam_mul[0]) break;
5852 fseek (ifp, 12, SEEK_CUR);
5853 FORC3 cam_mul[c] = get2();
5856 if (type != 7 || fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) break;
5857 thumb_offset = ftell(ifp) - 2;
5860 case 61440: /* Fuji HS10 table */
5861 fseek (ifp, get4()+base, SEEK_SET);
5862 parse_tiff_ifd (base);
5864 case 2: case 256: case 61441: /* ImageWidth */
5865 tiff_ifd[ifd].width = getint(type);
5867 case 3: case 257: case 61442: /* ImageHeight */
5868 tiff_ifd[ifd].height = getint(type);
5870 case 258: /* BitsPerSample */
5872 tiff_ifd[ifd].samples = len & 7;
5873 tiff_ifd[ifd].bps = getint(type);
5874 if (tiff_bps < tiff_ifd[ifd].bps)
5875 tiff_bps = tiff_ifd[ifd].bps;
5879 if (tiff_ifd[ifd].bps > 12) break;
5880 load_raw = &CLASS packed_load_raw;
5881 load_flags = get4() ? 24:80;
5883 case 259: /* Compression */
5884 tiff_ifd[ifd].comp = getint(type);
5886 case 262: /* PhotometricInterpretation */
5887 tiff_ifd[ifd].phint = get2();
5889 case 270: /* ImageDescription */
5890 fread (desc, 512, 1, ifp);
5892 case 271: /* Make */
5893 fgets (make, 64, ifp);
5895 case 272: /* Model */
5896 fgets (model, 64, ifp);
5898 case 280: /* Panasonic RW2 offset */
5899 if (type != 4) break;
5900 load_raw = &CLASS panasonic_load_raw;
5901 load_flags = 0x2008;
5902 case 273: /* StripOffset */
5903 case 513: /* JpegIFOffset */
5905 tiff_ifd[ifd].offset = get4()+base;
5906 if (!tiff_ifd[ifd].bps && tiff_ifd[ifd].offset > 0) {
5907 fseek (ifp, tiff_ifd[ifd].offset, SEEK_SET);
5908 if (ljpeg_start (&jh, 1)) {
5909 tiff_ifd[ifd].comp = 6;
5910 tiff_ifd[ifd].width = jh.wide;
5911 tiff_ifd[ifd].height = jh.high;
5912 tiff_ifd[ifd].bps = jh.bits;
5913 tiff_ifd[ifd].samples = jh.clrs;
5914 if (!(jh.sraw || (jh.clrs & 1)))
5915 tiff_ifd[ifd].width *= jh.clrs;
5916 if ((tiff_ifd[ifd].width > 4*tiff_ifd[ifd].height) & ~jh.clrs) {
5917 tiff_ifd[ifd].width /= 2;
5918 tiff_ifd[ifd].height *= 2;
5921 parse_tiff (tiff_ifd[ifd].offset + 12);
5926 case 274: /* Orientation */
5927 tiff_ifd[ifd].flip = "50132467"[get2() & 7]-'0';
5929 case 277: /* SamplesPerPixel */
5930 tiff_ifd[ifd].samples = getint(type) & 7;
5932 case 279: /* StripByteCounts */
5935 tiff_ifd[ifd].bytes = get4();
5938 FORC3 cam_mul[(4-c) % 3] = getint(type);
5940 case 305: case 11: /* Software */
5941 fgets (software, 64, ifp);
5942 if (!strncmp(software,"Adobe",5) ||
5943 !strncmp(software,"dcraw",5) ||
5944 !strncmp(software,"UFRaw",5) ||
5945 !strncmp(software,"Bibble",6) ||
5946 !strncmp(software,"Nikon Scan",10) ||
5947 !strcmp (software,"Digital Photo Professional"))
5950 case 306: /* DateTime */
5953 case 315: /* Artist */
5954 fread (artist, 64, 1, ifp);
5956 case 322: /* TileWidth */
5957 tiff_ifd[ifd].tile_width = getint(type);
5959 case 323: /* TileLength */
5960 tiff_ifd[ifd].tile_length = getint(type);
5962 case 324: /* TileOffsets */
5963 tiff_ifd[ifd].offset = len > 1 ? ftell(ifp) : get4();
5965 tiff_ifd[ifd].tile_width = tiff_ifd[ifd].tile_length = 0;
5967 load_raw = &CLASS sinar_4shot_load_raw;
5971 case 330: /* SubIFDs */
5972 if (!strcmp(model,"DSLR-A100") && tiff_ifd[ifd].width == 3872) {
5973 load_raw = &CLASS sony_arw_load_raw;
5974 data_offset = get4()+base;
5979 fseek (ifp, get4()+base, SEEK_SET);
5980 if (parse_tiff_ifd (base)) break;
5981 fseek (ifp, i+4, SEEK_SET);
5985 strcpy (make, "Sarnoff");
5989 FORC4 sony_curve[c+1] = get2() >> 2 & 0xfff;
5990 for (i=0; i < 5; i++)
5991 for (j = sony_curve[i]+1; j <= sony_curve[i+1]; j++)
5992 curve[j] = curve[j-1] + (1 << i);
5994 case 29184: sony_offset = get4(); break;
5995 case 29185: sony_length = get4(); break;
5996 case 29217: sony_key = get4(); break;
5998 parse_minolta (ftell(ifp));
6002 FORC4 cam_mul[c ^ (c < 2)] = get2();
6005 FORC4 cam_mul[c] = get2();
6006 i = (cam_mul[1] == 1024 && cam_mul[2] == 1024) << 1;
6007 SWAP (cam_mul[i],cam_mul[i+1])
6009 case 33405: /* Model2 */
6010 fgets (model2, 64, ifp);
6012 case 33421: /* CFARepeatPatternDim */
6013 if (get2() == 6 && get2() == 6)
6016 case 33422: /* CFAPattern */
6018 FORC(36) ((char *)xtrans)[c] = fgetc(ifp) & 3;
6021 case 64777: /* Kodak P-series */
6022 if ((plen=len) > 16) plen = 16;
6023 fread (cfa_pat, 1, plen, ifp);
6024 for (colors=cfa=i=0; i < plen && colors < 4; i++) {
6025 colors += !(cfa & (1 << cfa_pat[i]));
6026 cfa |= 1 << cfa_pat[i];
6028 if (cfa == 070) memcpy (cfa_pc,"\003\004\005",3); /* CMY */
6029 if (cfa == 072) memcpy (cfa_pc,"\005\003\004\001",4); /* GMCY */
6033 fseek (ifp, get4()+base, SEEK_SET);
6034 parse_kodak_ifd (base);
6036 case 33434: /* ExposureTime */
6037 tiff_ifd[ifd].shutter = shutter = getreal(type);
6039 case 33437: /* FNumber */
6040 aperture = getreal(type);
6042 case 34306: /* Leaf white balance */
6043 FORC4 cam_mul[c ^ 1] = 4096.0 / get2();
6045 case 34307: /* Leaf CatchLight color matrix */
6046 fread (software, 1, 7, ifp);
6047 if (strncmp(software,"MATRIX",6)) break;
6049 for (raw_color = i=0; i < 3; i++) {
6050 FORC4 fscanf (ifp, "%f", &rgb_cam[i][c^1]);
6051 if (!use_camera_wb) continue;
6053 FORC4 num += rgb_cam[i][c];
6054 FORC4 rgb_cam[i][c] /= num;
6057 case 34310: /* Leaf metadata */
6058 parse_mos (ftell(ifp));
6060 strcpy (make, "Leaf");
6062 case 34665: /* EXIF tag */
6063 fseek (ifp, get4()+base, SEEK_SET);
6066 case 34853: /* GPSInfo tag */
6067 fseek (ifp, get4()+base, SEEK_SET);
6070 case 34675: /* InterColorProfile */
6071 case 50831: /* AsShotICCProfile */
6072 profile_offset = ftell(ifp);
6073 profile_length = len;
6075 case 37122: /* CompressedBitsPerPixel */
6076 kodak_cbpp = get4();
6078 case 37386: /* FocalLength */
6079 focal_len = getreal(type);
6081 case 37393: /* ImageNumber */
6082 shot_order = getint(type);
6084 case 37400: /* old Kodak KDC tag */
6085 for (raw_color = i=0; i < 3; i++) {
6087 FORC3 rgb_cam[i][c] = getreal(type);
6091 strip_offset = get4();
6092 switch (tiff_ifd[ifd].comp) {
6093 case 32770: load_raw = &CLASS samsung_load_raw; break;
6094 case 32772: load_raw = &CLASS samsung2_load_raw; break;
6095 case 32773: load_raw = &CLASS samsung3_load_raw; break;
6098 case 46275: /* Imacon tags */
6099 strcpy (make, "Imacon");
6100 data_offset = ftell(ifp);
6104 if (!ima_len) break;
6105 fseek (ifp, 38, SEEK_CUR);
6107 fseek (ifp, 40, SEEK_CUR);
6109 raw_height = get4();
6110 left_margin = get4() & 7;
6111 width = raw_width - left_margin - (get4() & 7);
6112 top_margin = get4() & 7;
6113 height = raw_height - top_margin - (get4() & 7);
6114 if (raw_width == 7262) {
6119 fseek (ifp, 52, SEEK_CUR);
6120 FORC3 cam_mul[c] = getreal(11);
6121 fseek (ifp, 114, SEEK_CUR);
6122 flip = (get2() >> 7) * 90;
6123 if (width * height * 6 == ima_len) {
6124 if (flip % 180 == 90) SWAP(width,height);
6126 raw_height = height;
6127 left_margin = top_margin = filters = flip = 0;
6129 sprintf (model, "Ixpress %d-Mp", height*width/1000000);
6130 load_raw = &CLASS imacon_full_load_raw;
6132 if (left_margin & 1) filters = 0x61616161;
6133 load_raw = &CLASS unpacked_load_raw;
6137 case 50454: /* Sinar tag */
6139 if (!(cbuf = (char *) malloc(len))) break;
6140 fread (cbuf, 1, len, ifp);
6141 for (cp = cbuf-1; cp && cp < cbuf+len; cp = strchr(cp,'\n'))
6142 if (!strncmp (++cp,"Neutral ",8))
6143 sscanf (cp+8, "%f %f %f", cam_mul, cam_mul+1, cam_mul+2);
6147 if (!make[0]) strcpy (make, "Hasselblad");
6149 case 50459: /* Hasselblad tag */
6154 fseek (ifp, j+(get2(),get4()), SEEK_SET);
6160 case 50706: /* DNGVersion */
6161 FORC4 dng_version = (dng_version << 8) + fgetc(ifp);
6162 if (!make[0]) strcpy (make, "DNG");
6165 case 50708: /* UniqueCameraModel */
6166 if (model[0]) break;
6167 fgets (make, 64, ifp);
6168 if ((cp = strchr(make,' '))) {
6173 case 50710: /* CFAPlaneColor */
6174 if (filters == 9) break;
6175 if (len > 4) len = 4;
6177 fread (cfa_pc, 1, colors, ifp);
6179 FORCC tab[cfa_pc[c]] = c;
6182 filters = filters << 2 | tab[cfa_pat[i % plen]];
6183 filters -= !filters;
6185 case 50711: /* CFALayout */
6186 if (get2() == 2) fuji_width = 1;
6189 case 50712: /* LinearizationTable */
6192 case 50713: /* BlackLevelRepeatDim */
6195 if (cblack[4] * cblack[5] > sizeof cblack / sizeof *cblack - 6)
6196 cblack[4] = cblack[5] = 1;
6199 cblack[4] = cblack[5] = MIN(sqrt(len),64);
6200 case 50714: /* BlackLevel */
6201 if (!(cblack[4] * cblack[5]))
6202 cblack[4] = cblack[5] = 1;
6203 FORC (cblack[4] * cblack[5])
6204 cblack[6+c] = getreal(type);
6207 case 50715: /* BlackLevelDeltaH */
6208 case 50716: /* BlackLevelDeltaV */
6209 for (num=i=0; i < (len & 0xffff); i++)
6210 num += getreal(type);
6211 black += num/len + 0.5;
6213 case 50717: /* WhiteLevel */
6214 maximum = getint(type);
6216 case 50718: /* DefaultScale */
6217 pixel_aspect = getreal(type);
6218 pixel_aspect /= getreal(type);
6220 case 50721: /* ColorMatrix1 */
6221 case 50722: /* ColorMatrix2 */
6222 FORCC for (j=0; j < 3; j++)
6223 cm[c][j] = getreal(type);
6226 case 50723: /* CameraCalibration1 */
6227 case 50724: /* CameraCalibration2 */
6228 for (i=0; i < colors; i++)
6229 FORCC cc[i][c] = getreal(type);
6231 case 50727: /* AnalogBalance */
6232 FORCC ab[c] = getreal(type);
6234 case 50728: /* AsShotNeutral */
6235 FORCC asn[c] = getreal(type);
6237 case 50729: /* AsShotWhiteXY */
6238 xyz[0] = getreal(type);
6239 xyz[1] = getreal(type);
6240 xyz[2] = 1 - xyz[0] - xyz[1];
6241 FORC3 xyz[c] /= d65_white[c];
6243 case 50740: /* DNGPrivateData */
6244 if (dng_version) break;
6245 parse_minolta (j = get4()+base);
6246 fseek (ifp, j, SEEK_SET);
6247 parse_tiff_ifd (base);
6250 read_shorts (cr2_slice, 3);
6252 case 50829: /* ActiveArea */
6253 top_margin = getint(type);
6254 left_margin = getint(type);
6255 height = getint(type) - top_margin;
6256 width = getint(type) - left_margin;
6258 case 50830: /* MaskedAreas */
6259 for (i=0; i < len && i < 32; i++)
6260 ((int *)mask)[i] = getint(type);
6263 case 51009: /* OpcodeList2 */
6264 meta_offset = ftell(ifp);
6266 case 64772: /* Kodak P-series */
6267 if (len < 13) break;
6268 fseek (ifp, 16, SEEK_CUR);
6269 data_offset = get4();
6270 fseek (ifp, 28, SEEK_CUR);
6271 data_offset += get4();
6272 load_raw = &CLASS packed_load_raw;
6275 if (type == 2) fgets (model2, 64, ifp);
6277 fseek (ifp, save, SEEK_SET);
6279 if (sony_length && (buf = (unsigned *) malloc(sony_length))) {
6280 fseek (ifp, sony_offset, SEEK_SET);
6281 fread (buf, sony_length, 1, ifp);
6282 sony_decrypt (buf, sony_length/4, 1, sony_key);
6284 if ((ifp = tmpfile())) {
6285 fwrite (buf, sony_length, 1, ifp);
6286 fseek (ifp, 0, SEEK_SET);
6287 parse_tiff_ifd (-sony_offset);
6293 for (i=0; i < colors; i++)
6294 FORCC cc[i][c] *= ab[i];
6296 FORCC for (i=0; i < 3; i++)
6297 for (cam_xyz[c][i]=j=0; j < colors; j++)
6298 cam_xyz[c][i] += cc[c][j] * cm[j][i] * xyz[i];
6299 cam_xyz_coeff (cmatrix, cam_xyz);
6303 FORCC cam_mul[c] = 1 / asn[c];
6306 FORCC pre_mul[c] /= cc[c][c];
6310 int CLASS parse_tiff (int base)
6314 fseek (ifp, base, SEEK_SET);
6316 if (order != 0x4949 && order != 0x4d4d) return 0;
6318 while ((doff = get4())) {
6319 fseek (ifp, doff+base, SEEK_SET);
6320 if (parse_tiff_ifd (base)) break;
6325 void CLASS apply_tiff()
6327 int max_samp=0, ties=0, os, ns, raw=-1, thm=-1, i;
6332 fseek (ifp, thumb_offset, SEEK_SET);
6333 if (ljpeg_start (&jh, 1)) {
6334 thumb_misc = jh.bits;
6335 thumb_width = jh.wide;
6336 thumb_height = jh.high;
6339 for (i=tiff_nifds; i--; ) {
6340 if (tiff_ifd[i].shutter)
6341 shutter = tiff_ifd[i].shutter;
6342 tiff_ifd[i].shutter = shutter;
6344 for (i=0; i < tiff_nifds; i++) {
6345 if (max_samp < tiff_ifd[i].samples)
6346 max_samp = tiff_ifd[i].samples;
6347 if (max_samp > 3) max_samp = 3;
6348 os = raw_width*raw_height;
6349 ns = tiff_ifd[i].width*tiff_ifd[i].height;
6352 ns *= tiff_ifd[i].bps;
6354 if ((tiff_ifd[i].comp != 6 || tiff_ifd[i].samples != 3) &&
6355 (tiff_ifd[i].width | tiff_ifd[i].height) < 0x10000 &&
6356 ns && ((ns > os && (ties = 1)) ||
6357 (ns == os && shot_select == ties++))) {
6358 raw_width = tiff_ifd[i].width;
6359 raw_height = tiff_ifd[i].height;
6360 tiff_bps = tiff_ifd[i].bps;
6361 tiff_compress = tiff_ifd[i].comp;
6362 data_offset = tiff_ifd[i].offset;
6363 tiff_flip = tiff_ifd[i].flip;
6364 tiff_samples = tiff_ifd[i].samples;
6365 tile_width = tiff_ifd[i].tile_width;
6366 tile_length = tiff_ifd[i].tile_length;
6367 shutter = tiff_ifd[i].shutter;
6371 if (is_raw == 1 && ties) is_raw = ties;
6372 if (!tile_width ) tile_width = INT_MAX;
6373 if (!tile_length) tile_length = INT_MAX;
6374 for (i=tiff_nifds; i--; )
6375 if (tiff_ifd[i].flip) tiff_flip = tiff_ifd[i].flip;
6376 if (raw >= 0 && !load_raw)
6377 switch (tiff_compress) {
6379 if (tiff_ifd[raw].bytes == raw_width*raw_height) {
6381 load_raw = &CLASS sony_arw2_load_raw; break;
6383 if (tiff_ifd[raw].bytes*8 != raw_width*raw_height*tiff_bps) {
6385 load_raw = &CLASS sony_arw_load_raw; break;
6391 case 32773: goto slr;
6393 if (!strncmp(make,"OLYMPUS",7) &&
6394 tiff_ifd[raw].bytes*2 == raw_width*raw_height*3)
6396 if (tiff_ifd[raw].bytes*5 == raw_width*raw_height*8) {
6401 case 8: load_raw = &CLASS eight_bit_load_raw; break;
6402 case 12: if (tiff_ifd[raw].phint == 2)
6404 load_raw = &CLASS packed_load_raw; break;
6405 case 14: load_flags = 0;
6406 case 16: load_raw = &CLASS unpacked_load_raw;
6407 if (!strncmp(make,"OLYMPUS",7) &&
6408 tiff_ifd[raw].bytes*7 > raw_width*raw_height)
6409 load_raw = &CLASS olympus_load_raw;
6412 case 6: case 7: case 99:
6413 load_raw = &CLASS lossless_jpeg_load_raw; break;
6415 load_raw = &CLASS kodak_262_load_raw; break;
6417 if ((raw_width+9)/10*16*raw_height == tiff_ifd[raw].bytes) {
6418 load_raw = &CLASS packed_load_raw;
6420 } else if (raw_width*raw_height*3 == tiff_ifd[raw].bytes*2) {
6421 load_raw = &CLASS packed_load_raw;
6422 if (model[0] == 'N') load_flags = 80;
6423 } else if (raw_width*raw_height*3 == tiff_ifd[raw].bytes) {
6424 load_raw = &CLASS nikon_yuv_load_raw;
6425 gamma_curve (1/2.4, 12.92, 1, 4095);
6426 memset (cblack, 0, sizeof cblack);
6428 } else if (raw_width*raw_height*2 == tiff_ifd[raw].bytes) {
6429 load_raw = &CLASS unpacked_load_raw;
6433 load_raw = &CLASS nikon_load_raw; break;
6435 load_raw = &CLASS pentax_load_raw; break;
6437 switch (tiff_ifd[raw].phint) {
6438 case 2: load_raw = &CLASS kodak_rgb_load_raw; filters = 0; break;
6439 case 6: load_raw = &CLASS kodak_ycbcr_load_raw; filters = 0; break;
6440 case 32803: load_raw = &CLASS kodak_65000_load_raw;
6442 case 32867: case 34892: break;
6443 default: is_raw = 0;
6446 if ( (tiff_samples == 3 && tiff_ifd[raw].bytes && tiff_bps != 14 &&
6447 (tiff_compress & -16) != 32768)
6448 || (tiff_bps == 8 && strncmp(make,"Phase",5) &&
6449 !strcasestr(make,"Kodak") && !strstr(model2,"DEBUG RAW")))
6451 for (i=0; i < tiff_nifds; i++)
6452 if (i != raw && tiff_ifd[i].samples == max_samp &&
6453 tiff_ifd[i].width * tiff_ifd[i].height / (SQR(tiff_ifd[i].bps)+1) >
6454 thumb_width * thumb_height / (SQR(thumb_misc)+1)
6455 && tiff_ifd[i].comp != 34892) {
6456 thumb_width = tiff_ifd[i].width;
6457 thumb_height = tiff_ifd[i].height;
6458 thumb_offset = tiff_ifd[i].offset;
6459 thumb_length = tiff_ifd[i].bytes;
6460 thumb_misc = tiff_ifd[i].bps;
6464 thumb_misc |= tiff_ifd[thm].samples << 5;
6465 switch (tiff_ifd[thm].comp) {
6467 write_thumb = &CLASS layer_thumb;
6470 if (tiff_ifd[thm].bps <= 8)
6471 write_thumb = &CLASS ppm_thumb;
6472 else if (!strcmp(make,"Imacon"))
6473 write_thumb = &CLASS ppm16_thumb;
6475 thumb_load_raw = &CLASS kodak_thumb_load_raw;
6478 thumb_load_raw = tiff_ifd[thm].phint == 6 ?
6479 &CLASS kodak_ycbcr_load_raw : &CLASS kodak_rgb_load_raw;
6484 void CLASS parse_minolta (int base)
6486 int save, tag, len, offset, high=0, wide=0, i, c;
6489 fseek (ifp, base, SEEK_SET);
6490 if (fgetc(ifp) || fgetc(ifp)-'M' || fgetc(ifp)-'R') return;
6491 order = fgetc(ifp) * 0x101;
6492 offset = base + get4() + 8;
6493 while ((save=ftell(ifp)) < offset) {
6494 for (tag=i=0; i < 4; i++)
6495 tag = tag << 8 | fgetc(ifp);
6498 case 0x505244: /* PRD */
6499 fseek (ifp, 8, SEEK_CUR);
6503 case 0x574247: /* WBG */
6505 i = strcmp(model,"DiMAGE A200") ? 0:3;
6506 FORC4 cam_mul[c ^ (c >> 1) ^ i] = get2();
6508 case 0x545457: /* TTW */
6509 parse_tiff (ftell(ifp));
6510 data_offset = offset;
6512 fseek (ifp, save+len+8, SEEK_SET);
6520 Many cameras have a "debug mode" that writes JPEG and raw
6521 at the same time. The raw file has no header, so try to
6522 to open the matching JPEG file and read its metadata.
6524 void CLASS parse_external_jpeg()
6526 const char *file, *ext;
6527 char *jname, *jfile, *jext;
6530 ext = strrchr (ifname, '.');
6531 file = strrchr (ifname, '/');
6532 if (!file) file = strrchr (ifname, '\\');
6533 if (!file) file = ifname-1;
6535 if (!ext || strlen(ext) != 4 || ext-file != 8) return;
6536 jname = (char *) malloc (strlen(ifname) + 1);
6537 merror (jname, "parse_external_jpeg()");
6538 strcpy (jname, ifname);
6539 jfile = file - ifname + jname;
6540 jext = ext - ifname + jname;
6541 if (strcasecmp (ext, ".jpg")) {
6542 strcpy (jext, isupper(ext[1]) ? ".JPG":".jpg");
6543 if (isdigit(*file)) {
6544 memcpy (jfile, file+4, 4);
6545 memcpy (jfile+4, file, 4);
6548 while (isdigit(*--jext)) {
6555 if (strcmp (jname, ifname)) {
6556 if ((ifp = fopen (jname, "rb"))) {
6558 fprintf (stderr,_("Reading metadata from %s ...\n"), jname);
6566 fprintf (stderr,_("Failed to read metadata from %s\n"), jname);
6572 CIFF block 0x1030 contains an 8x8 white sample.
6573 Load this into white[][] for use in scale_colors().
6575 void CLASS ciff_block_1030()
6577 static const ushort key[] = { 0x410, 0x45f3 };
6578 int i, bpp, row, col, vbits=0;
6579 unsigned long bitbuf=0;
6581 if ((get2(),get4()) != 0x80008 || !get4()) return;
6583 if (bpp != 10 && bpp != 12) return;
6584 for (i=row=0; row < 8; row++)
6585 for (col=0; col < 8; col++) {
6587 bitbuf = bitbuf << 16 | (get2() ^ key[i++ & 1]);
6590 white[row][col] = bitbuf >> (vbits -= bpp) & ~(-1 << bpp);
6595 Parse a CIFF file, better known as Canon CRW format.
6597 void CLASS parse_ciff (int offset, int length, int depth)
6599 int tboff, nrecs, c, type, len, save, wbi=-1;
6600 ushort key[] = { 0x410, 0x45f3 };
6602 fseek (ifp, offset+length-4, SEEK_SET);
6603 tboff = get4() + offset;
6604 fseek (ifp, tboff, SEEK_SET);
6606 if ((nrecs | depth) > 127) return;
6610 save = ftell(ifp) + 4;
6611 fseek (ifp, offset+get4(), SEEK_SET);
6612 if ((((type >> 8) + 8) | 8) == 0x38)
6613 parse_ciff (ftell(ifp), len, depth+1); /* Parse a sub-table */
6615 fread (artist, 64, 1, ifp);
6616 if (type == 0x080a) {
6617 fread (make, 64, 1, ifp);
6618 fseek (ifp, strlen(make) - 63, SEEK_CUR);
6619 fread (model, 64, 1, ifp);
6621 if (type == 0x1810) {
6624 pixel_aspect = int_to_float(get4());
6627 if (type == 0x1835) /* Get the decoder table */
6628 tiff_compress = get4();
6629 if (type == 0x2007) {
6630 thumb_offset = ftell(ifp);
6633 if (type == 0x1818) {
6634 shutter = pow (2, -int_to_float((get4(),get4())));
6635 aperture = pow (2, int_to_float(get4())/2);
6637 if (type == 0x102a) {
6638 iso_speed = pow (2, (get4(),get2())/32.0 - 4) * 50;
6639 aperture = pow (2, (get2(),(short)get2())/64.0);
6640 shutter = pow (2,-((short)get2())/32.0);
6641 wbi = (get2(),get2());
6642 if (wbi > 17) wbi = 0;
6643 fseek (ifp, 32, SEEK_CUR);
6644 if (shutter > 1e6) shutter = get2()/10.0;
6646 if (type == 0x102c) {
6647 if (get2() > 512) { /* Pro90, G1 */
6648 fseek (ifp, 118, SEEK_CUR);
6649 FORC4 cam_mul[c ^ 2] = get2();
6650 } else { /* G2, S30, S40 */
6651 fseek (ifp, 98, SEEK_CUR);
6652 FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get2();
6655 if (type == 0x0032) {
6656 if (len == 768) { /* EOS D30 */
6657 fseek (ifp, 72, SEEK_CUR);
6658 FORC4 cam_mul[c ^ (c >> 1)] = 1024.0 / get2();
6659 if (!wbi) cam_mul[0] = -1; /* use my auto white balance */
6660 } else if (!cam_mul[0]) {
6661 if (get2() == key[0]) /* Pro1, G6, S60, S70 */
6662 c = (strstr(model,"Pro1") ?
6663 "012346000000000000":"01345:000000006008")[wbi]-'0'+ 2;
6664 else { /* G3, G5, S45, S50 */
6665 c = "023457000000006000"[wbi]-'0';
6666 key[0] = key[1] = 0;
6668 fseek (ifp, 78 + c*8, SEEK_CUR);
6669 FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get2() ^ key[c & 1];
6670 if (!wbi) cam_mul[0] = -1;
6673 if (type == 0x10a9) { /* D60, 10D, 300D, and clones */
6674 if (len > 66) wbi = "0134567028"[wbi]-'0';
6675 fseek (ifp, 2 + wbi*8, SEEK_CUR);
6676 FORC4 cam_mul[c ^ (c >> 1)] = get2();
6678 if (type == 0x1030 && (0x18040 >> wbi & 1))
6679 ciff_block_1030(); /* all that don't have 0x10a9 */
6680 if (type == 0x1031) {
6681 raw_width = (get2(),get2());
6682 raw_height = get2();
6684 if (type == 0x5029) {
6685 focal_len = len >> 16;
6686 if ((len & 0xffff) == 2) focal_len /= 32;
6688 if (type == 0x5813) flash_used = int_to_float(len);
6689 if (type == 0x5814) canon_ev = int_to_float(len);
6690 if (type == 0x5817) shot_order = len;
6691 if (type == 0x5834) unique_id = len;
6692 if (type == 0x580e) timestamp = len;
6693 if (type == 0x180e) timestamp = get4();
6695 if ((type | 0x4000) == 0x580e)
6696 timestamp = mktime (gmtime (×tamp));
6698 fseek (ifp, save, SEEK_SET);
6702 void CLASS parse_rollei()
6704 char line[128], *val;
6707 fseek (ifp, 0, SEEK_SET);
6708 memset (&t, 0, sizeof t);
6710 fgets (line, 128, ifp);
6711 if ((val = strchr(line,'=')))
6714 val = line + strlen(line);
6715 if (!strcmp(line,"DAT"))
6716 sscanf (val, "%d.%d.%d", &t.tm_mday, &t.tm_mon, &t.tm_year);
6717 if (!strcmp(line,"TIM"))
6718 sscanf (val, "%d:%d:%d", &t.tm_hour, &t.tm_min, &t.tm_sec);
6719 if (!strcmp(line,"HDR"))
6720 thumb_offset = atoi(val);
6721 if (!strcmp(line,"X "))
6722 raw_width = atoi(val);
6723 if (!strcmp(line,"Y "))
6724 raw_height = atoi(val);
6725 if (!strcmp(line,"TX "))
6726 thumb_width = atoi(val);
6727 if (!strcmp(line,"TY "))
6728 thumb_height = atoi(val);
6729 } while (strncmp(line,"EOHD",4));
6730 data_offset = thumb_offset + thumb_width * thumb_height * 2;
6734 timestamp = mktime(&t);
6735 strcpy (make, "Rollei");
6736 strcpy (model,"d530flex");
6737 write_thumb = &CLASS rollei_thumb;
6740 void CLASS parse_sinar_ia()
6746 fseek (ifp, 4, SEEK_SET);
6748 fseek (ifp, get4(), SEEK_SET);
6750 off = get4(); get4();
6751 fread (str, 8, 1, ifp);
6752 if (!strcmp(str,"META")) meta_offset = off;
6753 if (!strcmp(str,"THUMB")) thumb_offset = off;
6754 if (!strcmp(str,"RAW0")) data_offset = off;
6756 fseek (ifp, meta_offset+20, SEEK_SET);
6757 fread (make, 64, 1, ifp);
6759 if ((cp = strchr(make,' '))) {
6760 strcpy (model, cp+1);
6764 raw_height = get2();
6765 load_raw = &CLASS unpacked_load_raw;
6766 thumb_width = (get4(),get2());
6767 thumb_height = get2();
6768 write_thumb = &CLASS ppm_thumb;
6772 void CLASS parse_phase_one (int base)
6775 unsigned entries, tag, /*type,*/ len, data, save, i, c;
6776 float romm_cam[3][3];
6779 memset (&ph1, 0, sizeof ph1);
6780 fseek (ifp, base, SEEK_SET);
6781 order = get4() & 0xffff;
6782 if (get4() >> 8 != 0x526177) return; /* "Raw" */
6783 fseek (ifp, get4()+base, SEEK_SET);
6793 fseek (ifp, base+data, SEEK_SET);
6795 case 0x100: flip = "0653"[data & 3]-'0'; break;
6797 for (i=0; i < 9; i++)
6798 ((float *)romm_cam)[i] = getreal(11);
6799 romm_coeff (romm_cam);
6802 FORC3 cam_mul[c] = getreal(11);
6804 case 0x108: raw_width = data; break;
6805 case 0x109: raw_height = data; break;
6806 case 0x10a: left_margin = data; break;
6807 case 0x10b: top_margin = data; break;
6808 case 0x10c: width = data; break;
6809 case 0x10d: height = data; break;
6810 case 0x10e: ph1.format = data; break;
6811 case 0x10f: data_offset = data+base; break;
6812 case 0x110: meta_offset = data+base;
6813 meta_length = len; break;
6814 case 0x112: ph1.key_off = save - 4; break;
6815 case 0x210: ph1.tag_210 = int_to_float(data); break;
6816 case 0x21a: ph1.tag_21a = data; break;
6817 case 0x21c: strip_offset = data+base; break;
6818 case 0x21d: ph1.black = data; break;
6819 case 0x222: ph1.split_col = data; break;
6820 case 0x223: ph1.black_col = data+base; break;
6821 case 0x224: ph1.split_row = data; break;
6822 case 0x225: ph1.black_row = data+base; break;
6825 fread (model, 1, 63, ifp);
6826 if ((cp = strstr(model," camera"))) *cp = 0;
6828 fseek (ifp, save, SEEK_SET);
6830 load_raw = ph1.format < 3 ?
6831 &CLASS phase_one_load_raw : &CLASS phase_one_load_raw_c;
6833 strcpy (make, "Phase One");
6834 if (model[0]) return;
6835 switch (raw_height) {
6836 case 2060: strcpy (model,"LightPhase"); break;
6837 case 2682: strcpy (model,"H 10"); break;
6838 case 4128: strcpy (model,"H 20"); break;
6839 case 5488: strcpy (model,"H 25"); break;
6843 void CLASS parse_fuji (int offset)
6845 unsigned entries, tag, len, save, c;
6847 fseek (ifp, offset, SEEK_SET);
6849 if (entries > 255) return;
6855 raw_height = get2();
6857 } else if (tag == 0x121) {
6859 if ((width = get2()) == 4284) width += 3;
6860 } else if (tag == 0x130) {
6861 fuji_layout = fgetc(ifp) >> 7;
6862 fuji_width = !(fgetc(ifp) & 8);
6863 } else if (tag == 0x131) {
6865 FORC(36) xtrans_abs[0][35-c] = fgetc(ifp) & 3;
6866 } else if (tag == 0x2ff0) {
6867 FORC4 cam_mul[c ^ 1] = get2();
6868 } else if (tag == 0xc000) {
6871 while ((tag = get4()) > raw_width);
6876 fseek (ifp, save+len, SEEK_SET);
6878 height <<= fuji_layout;
6879 width >>= fuji_layout;
6882 int CLASS parse_jpeg (int offset)
6884 int len, save, hlen, mark;
6886 fseek (ifp, offset, SEEK_SET);
6887 if (fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) return 0;
6889 while (fgetc(ifp) == 0xff && (mark = fgetc(ifp)) != 0xda) {
6893 if (mark == 0xc0 || mark == 0xc3 || mark == 0xc9) {
6895 raw_height = get2();
6900 if (get4() == 0x48454150) /* "HEAP" */
6901 parse_ciff (save+hlen, len-hlen, 0);
6902 if (parse_tiff (save+6)) apply_tiff();
6903 fseek (ifp, save+len, SEEK_SET);
6908 void CLASS parse_riff()
6910 unsigned i, size, end;
6911 char tag[4], date[64], month[64];
6912 static const char mon[12][4] =
6913 { "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" };
6917 fread (tag, 4, 1, ifp);
6919 end = ftell(ifp) + size;
6920 if (!memcmp(tag,"RIFF",4) || !memcmp(tag,"LIST",4)) {
6922 while (ftell(ifp)+7 < end && !feof(ifp))
6924 } else if (!memcmp(tag,"nctg",4)) {
6925 while (ftell(ifp)+7 < end) {
6928 if ((i+1) >> 1 == 10 && size == 20)
6930 else fseek (ifp, size, SEEK_CUR);
6932 } else if (!memcmp(tag,"IDIT",4) && size < 64) {
6933 fread (date, 64, 1, ifp);
6935 memset (&t, 0, sizeof t);
6936 if (sscanf (date, "%*s %s %d %d:%d:%d %d", month, &t.tm_mday,
6937 &t.tm_hour, &t.tm_min, &t.tm_sec, &t.tm_year) == 6) {
6938 for (i=0; i < 12 && strcasecmp(mon[i],month); i++);
6942 timestamp = mktime(&t);
6945 fseek (ifp, size, SEEK_CUR);
6948 void CLASS parse_qt (int end)
6950 unsigned save, size;
6954 while (ftell(ifp)+7 < end) {
6956 if ((size = get4()) < 8) return;
6957 fread (tag, 4, 1, ifp);
6958 if (!memcmp(tag,"moov",4) ||
6959 !memcmp(tag,"udta",4) ||
6960 !memcmp(tag,"CNTH",4))
6961 parse_qt (save+size);
6962 if (!memcmp(tag,"CNDA",4))
6963 parse_jpeg (ftell(ifp));
6964 fseek (ifp, save+size, SEEK_SET);
6968 void CLASS parse_smal (int offset, int fsize)
6972 fseek (ifp, offset+2, SEEK_SET);
6976 fseek (ifp, 5, SEEK_CUR);
6977 if (get4() != fsize) return;
6978 if (ver > 6) data_offset = get4();
6979 raw_height = height = get2();
6980 raw_width = width = get2();
6981 strcpy (make, "SMaL");
6982 sprintf (model, "v%d %dx%d", ver, width, height);
6983 if (ver == 6) load_raw = &CLASS smal_v6_load_raw;
6984 if (ver == 9) load_raw = &CLASS smal_v9_load_raw;
6987 void CLASS parse_cine()
6989 unsigned off_head, off_setup, off_image, i;
6992 fseek (ifp, 4, SEEK_SET);
6993 is_raw = get2() == 2;
6994 fseek (ifp, 14, SEEK_CUR);
7000 if ((i = get4())) timestamp = i;
7001 fseek (ifp, off_head+4, SEEK_SET);
7003 raw_height = get4();
7004 switch (get2(),get2()) {
7005 case 8: load_raw = &CLASS eight_bit_load_raw; break;
7006 case 16: load_raw = &CLASS unpacked_load_raw;
7008 fseek (ifp, off_setup+792, SEEK_SET);
7009 strcpy (make, "CINE");
7010 sprintf (model, "%d", get4());
7011 fseek (ifp, 12, SEEK_CUR);
7012 switch ((i=get4()) & 0xffffff) {
7013 case 3: filters = 0x94949494; break;
7014 case 4: filters = 0x49494949; break;
7015 default: is_raw = 0;
7017 fseek (ifp, 72, SEEK_CUR);
7018 switch ((get4()+3600) % 360) {
7019 case 270: flip = 4; break;
7020 case 180: flip = 1; break;
7021 case 90: flip = 7; break;
7024 cam_mul[0] = getreal(11);
7025 cam_mul[2] = getreal(11);
7026 maximum = ~(-1 << get4());
7027 fseek (ifp, 668, SEEK_CUR);
7028 shutter = get4()/1000000000.0;
7029 fseek (ifp, off_image, SEEK_SET);
7030 if (shot_select < is_raw)
7031 fseek (ifp, shot_select*8, SEEK_CUR);
7032 data_offset = (INT64) get4() + 8;
7033 data_offset += (INT64) get4() << 32;
7036 void CLASS parse_redcine()
7038 unsigned i, len, rdvo;
7042 fseek (ifp, 52, SEEK_SET);
7045 fseek (ifp, 0, SEEK_END);
7046 fseek (ifp, -(i = ftello(ifp) & 511), SEEK_CUR);
7047 if (get4() != i || get4() != 0x52454f42) {
7048 fprintf (stderr,_("%s: Tail is missing, parsing from head...\n"), ifname);
7049 fseek (ifp, 0, SEEK_SET);
7050 while ((len = get4()) != EOF) {
7051 if (get4() == 0x52454456)
7052 if (is_raw++ == shot_select)
7053 data_offset = ftello(ifp) - 8;
7054 fseek (ifp, len-8, SEEK_CUR);
7058 fseek (ifp, 12, SEEK_CUR);
7060 fseeko (ifp, rdvo+8 + shot_select*4, SEEK_SET);
7061 data_offset = get4();
7065 char * CLASS foveon_gets (int offset, char *str, int len)
7068 fseek (ifp, offset, SEEK_SET);
7069 for (i=0; i < len-1; i++)
7070 if ((str[i] = get2()) == 0) break;
7075 void CLASS parse_foveon()
7077 int entries, img=0, off, len, tag, save, i, wide, high, pent, poff[256][2];
7078 char name[64], value[64];
7080 order = 0x4949; /* Little-endian */
7081 fseek (ifp, 36, SEEK_SET);
7083 fseek (ifp, -4, SEEK_END);
7084 fseek (ifp, get4(), SEEK_SET);
7085 if (get4() != 0x64434553) return; /* SECd */
7086 entries = (get4(),get4());
7092 fseek (ifp, off, SEEK_SET);
7093 if (get4() != (0x20434553 | (tag << 24))) return;
7095 case 0x47414d49: /* IMAG */
7096 case 0x32414d49: /* IMA2 */
7097 fseek (ifp, 8, SEEK_CUR);
7101 if (wide > raw_width && high > raw_height) {
7103 case 5: load_flags = 1;
7104 case 6: load_raw = &CLASS foveon_sd_load_raw; break;
7105 case 30: load_raw = &CLASS foveon_dp_load_raw; break;
7106 default: load_raw = 0;
7110 data_offset = off+28;
7113 fseek (ifp, off+28, SEEK_SET);
7114 if (fgetc(ifp) == 0xff && fgetc(ifp) == 0xd8
7115 && thumb_length < len-28) {
7116 thumb_offset = off+28;
7117 thumb_length = len-28;
7118 write_thumb = &CLASS jpeg_thumb;
7120 if (++img == 2 && !thumb_length) {
7121 thumb_offset = off+24;
7123 thumb_height = high;
7124 write_thumb = &CLASS foveon_thumb;
7127 case 0x464d4143: /* CAMF */
7128 meta_offset = off+8;
7129 meta_length = len-28;
7131 case 0x504f5250: /* PROP */
7132 pent = (get4(),get4());
7133 fseek (ifp, 12, SEEK_CUR);
7135 if ((unsigned) pent > 256) pent=256;
7136 for (i=0; i < pent*2; i++)
7137 ((int *)poff)[i] = off + get4()*2;
7138 for (i=0; i < pent; i++) {
7139 foveon_gets (poff[i][0], name, 64);
7140 foveon_gets (poff[i][1], value, 64);
7141 if (!strcmp (name, "ISO"))
7142 iso_speed = atoi(value);
7143 if (!strcmp (name, "CAMMANUF"))
7144 strcpy (make, value);
7145 if (!strcmp (name, "CAMMODEL"))
7146 strcpy (model, value);
7147 if (!strcmp (name, "WB_DESC"))
7148 strcpy (model2, value);
7149 if (!strcmp (name, "TIME"))
7150 timestamp = atoi(value);
7151 if (!strcmp (name, "EXPTIME"))
7152 shutter = atoi(value) / 1000000.0;
7153 if (!strcmp (name, "APERTURE"))
7154 aperture = atof(value);
7155 if (!strcmp (name, "FLENGTH"))
7156 focal_len = atof(value);
7159 timestamp = mktime (gmtime (×tamp));
7162 fseek (ifp, save, SEEK_SET);
7167 All matrices are from Adobe DNG Converter unless otherwise noted.
7169 void CLASS adobe_coeff (const char *make, const char *model)
7171 static const struct {
7173 short black, maximum, trans[12];
7175 { "AgfaPhoto DC-833m", 0, 0, /* DJC */
7176 { 11438,-3762,-1115,-2409,9914,2497,-1227,2295,5300 } },
7177 { "Apple QuickTake", 0, 0, /* DJC */
7178 { 21392,-5653,-3353,2406,8010,-415,7166,1427,2078 } },
7179 { "Canon EOS D2000", 0, 0,
7180 { 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } },
7181 { "Canon EOS D6000", 0, 0,
7182 { 20482,-7172,-3125,-1033,10410,-285,2542,226,3136 } },
7183 { "Canon EOS D30", 0, 0,
7184 { 9805,-2689,-1312,-5803,13064,3068,-2438,3075,8775 } },
7185 { "Canon EOS D60", 0, 0xfa0,
7186 { 6188,-1341,-890,-7168,14489,2937,-2640,3228,8483 } },
7187 { "Canon EOS 5DS", 0, 0x3c96,
7188 { 6250,-711,-808,-5153,12794,2636,-1249,2198,5610 } },
7189 { "Canon EOS 5D Mark III", 0, 0x3c80,
7190 { 6722,-635,-963,-4287,12460,2028,-908,2162,5668 } },
7191 { "Canon EOS 5D Mark II", 0, 0x3cf0,
7192 { 4716,603,-830,-7798,15474,2480,-1496,1937,6651 } },
7193 { "Canon EOS 5D", 0, 0xe6c,
7194 { 6347,-479,-972,-8297,15954,2480,-1968,2131,7649 } },
7195 { "Canon EOS 6D", 0, 0x3c82,
7196 { 7034,-804,-1014,-4420,12564,2058,-851,1994,5758 } },
7197 { "Canon EOS 7D Mark II", 0, 0x3510,
7198 { 7268,-1082,-969,-4186,11839,2663,-825,2029,5839 } },
7199 { "Canon EOS 7D", 0, 0x3510,
7200 { 6844,-996,-856,-3876,11761,2396,-593,1772,6198 } },
7201 { "Canon EOS 10D", 0, 0xfa0,
7202 { 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } },
7203 { "Canon EOS 20Da", 0, 0,
7204 { 14155,-5065,-1382,-6550,14633,2039,-1623,1824,6561 } },
7205 { "Canon EOS 20D", 0, 0xfff,
7206 { 6599,-537,-891,-8071,15783,2424,-1983,2234,7462 } },
7207 { "Canon EOS 30D", 0, 0,
7208 { 6257,-303,-1000,-7880,15621,2396,-1714,1904,7046 } },
7209 { "Canon EOS 40D", 0, 0x3f60,
7210 { 6071,-747,-856,-7653,15365,2441,-2025,2553,7315 } },
7211 { "Canon EOS 50D", 0, 0x3d93,
7212 { 4920,616,-593,-6493,13964,2784,-1774,3178,7005 } },
7213 { "Canon EOS 60D", 0, 0x2ff7,
7214 { 6719,-994,-925,-4408,12426,2211,-887,2129,6051 } },
7215 { "Canon EOS 70D", 0, 0x3bc7,
7216 { 7034,-804,-1014,-4420,12564,2058,-851,1994,5758 } },
7217 { "Canon EOS 80D", 0, 0,
7218 { 7457,-671,-937,-4849,12495,2643,-1213,2354,5492 } },
7219 { "Canon EOS 100D", 0, 0x350f,
7220 { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } },
7221 { "Canon EOS 300D", 0, 0xfa0,
7222 { 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } },
7223 { "Canon EOS 350D", 0, 0xfff,
7224 { 6018,-617,-965,-8645,15881,2975,-1530,1719,7642 } },
7225 { "Canon EOS 400D", 0, 0xe8e,
7226 { 7054,-1501,-990,-8156,15544,2812,-1278,1414,7796 } },
7227 { "Canon EOS 450D", 0, 0x390d,
7228 { 5784,-262,-821,-7539,15064,2672,-1982,2681,7427 } },
7229 { "Canon EOS 500D", 0, 0x3479,
7230 { 4763,712,-646,-6821,14399,2640,-1921,3276,6561 } },
7231 { "Canon EOS 550D", 0, 0x3dd7,
7232 { 6941,-1164,-857,-3825,11597,2534,-416,1540,6039 } },
7233 { "Canon EOS 600D", 0, 0x3510,
7234 { 6461,-907,-882,-4300,12184,2378,-819,1944,5931 } },
7235 { "Canon EOS 650D", 0, 0x354d,
7236 { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } },
7237 { "Canon EOS 700D", 0, 0x3c00,
7238 { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } },
7239 { "Canon EOS 750D", 0, 0x368e,
7240 { 6362,-823,-847,-4426,12109,2616,-743,1857,5635 } },
7241 { "Canon EOS 760D", 0, 0x350f,
7242 { 6362,-823,-847,-4426,12109,2616,-743,1857,5635 } },
7243 { "Canon EOS 1000D", 0, 0xe43,
7244 { 6771,-1139,-977,-7818,15123,2928,-1244,1437,7533 } },
7245 { "Canon EOS 1100D", 0, 0x3510,
7246 { 6444,-904,-893,-4563,12308,2535,-903,2016,6728 } },
7247 { "Canon EOS 1200D", 0, 0x37c2,
7248 { 6461,-907,-882,-4300,12184,2378,-819,1944,5931 } },
7249 { "Canon EOS 1300D", 0, 0x3510,
7250 { 6939,-1016,-866,-4428,12473,2177,-1175,2178,6162 } },
7251 { "Canon EOS M3", 0, 0,
7252 { 6362,-823,-847,-4426,12109,2616,-743,1857,5635 } },
7253 { "Canon EOS M10", 0, 0,
7254 { 6400,-480,-888,-5294,13416,2047,-1296,2203,6137 } },
7255 { "Canon EOS M", 0, 0,
7256 { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } },
7257 { "Canon EOS-1Ds Mark III", 0, 0x3bb0,
7258 { 5859,-211,-930,-8255,16017,2353,-1732,1887,7448 } },
7259 { "Canon EOS-1Ds Mark II", 0, 0xe80,
7260 { 6517,-602,-867,-8180,15926,2378,-1618,1771,7633 } },
7261 { "Canon EOS-1D Mark IV", 0, 0x3bb0,
7262 { 6014,-220,-795,-4109,12014,2361,-561,1824,5787 } },
7263 { "Canon EOS-1D Mark III", 0, 0x3bb0,
7264 { 6291,-540,-976,-8350,16145,2311,-1714,1858,7326 } },
7265 { "Canon EOS-1D Mark II N", 0, 0xe80,
7266 { 6240,-466,-822,-8180,15825,2500,-1801,1938,8042 } },
7267 { "Canon EOS-1D Mark II", 0, 0xe80,
7268 { 6264,-582,-724,-8312,15948,2504,-1744,1919,8664 } },
7269 { "Canon EOS-1DS", 0, 0xe20,
7270 { 4374,3631,-1743,-7520,15212,2472,-2892,3632,8161 } },
7271 { "Canon EOS-1D C", 0, 0x3c4e,
7272 { 6847,-614,-1014,-4669,12737,2139,-1197,2488,6846 } },
7273 { "Canon EOS-1D X Mark II", 0, 0,
7274 { 7596,-978,-967,-4808,12571,2503,-1398,2567,5752 } },
7275 { "Canon EOS-1D X", 0, 0x3c4e,
7276 { 6847,-614,-1014,-4669,12737,2139,-1197,2488,6846 } },
7277 { "Canon EOS-1D", 0, 0xe20,
7278 { 6806,-179,-1020,-8097,16415,1687,-3267,4236,7690 } },
7279 { "Canon EOS C500", 853, 0, /* DJC */
7280 { 17851,-10604,922,-7425,16662,763,-3660,3636,22278 } },
7281 { "Canon PowerShot A530", 0, 0,
7282 { 0 } }, /* don't want the A5 matrix */
7283 { "Canon PowerShot A50", 0, 0,
7284 { -5300,9846,1776,3436,684,3939,-5540,9879,6200,-1404,11175,217 } },
7285 { "Canon PowerShot A5", 0, 0,
7286 { -4801,9475,1952,2926,1611,4094,-5259,10164,5947,-1554,10883,547 } },
7287 { "Canon PowerShot G10", 0, 0,
7288 { 11093,-3906,-1028,-5047,12492,2879,-1003,1750,5561 } },
7289 { "Canon PowerShot G11", 0, 0,
7290 { 12177,-4817,-1069,-1612,9864,2049,-98,850,4471 } },
7291 { "Canon PowerShot G12", 0, 0,
7292 { 13244,-5501,-1248,-1508,9858,1935,-270,1083,4366 } },
7293 { "Canon PowerShot G15", 0, 0,
7294 { 7474,-2301,-567,-4056,11456,2975,-222,716,4181 } },
7295 { "Canon PowerShot G16", 0, 0,
7296 { 8020,-2687,-682,-3704,11879,2052,-965,1921,5556 } },
7297 { "Canon PowerShot G1 X", 0, 0,
7298 { 7378,-1255,-1043,-4088,12251,2048,-876,1946,5805 } },
7299 { "Canon PowerShot G1", 0, 0,
7300 { -4778,9467,2172,4743,-1141,4344,-5146,9908,6077,-1566,11051,557 } },
7301 { "Canon PowerShot G2", 0, 0,
7302 { 9087,-2693,-1049,-6715,14382,2537,-2291,2819,7790 } },
7303 { "Canon PowerShot G3 X", 0, 0,
7304 { 9701,-3857,-921,-3149,11537,1817,-786,1817,5147 } },
7305 { "Canon PowerShot G3", 0, 0,
7306 { 9212,-2781,-1073,-6573,14189,2605,-2300,2844,7664 } },
7307 { "Canon PowerShot G5 X", 0, 0,
7308 { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } },
7309 { "Canon PowerShot G5", 0, 0,
7310 { 9757,-2872,-933,-5972,13861,2301,-1622,2328,7212 } },
7311 { "Canon PowerShot G6", 0, 0,
7312 { 9877,-3775,-871,-7613,14807,3072,-1448,1305,7485 } },
7313 { "Canon PowerShot G7 X", 0, 0,
7314 { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } },
7315 { "Canon PowerShot G9 X", 0, 0,
7316 { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } },
7317 { "Canon PowerShot G9", 0, 0,
7318 { 7368,-2141,-598,-5621,13254,2625,-1418,1696,5743 } },
7319 { "Canon PowerShot Pro1", 0, 0,
7320 { 10062,-3522,-999,-7643,15117,2730,-765,817,7323 } },
7321 { "Canon PowerShot Pro70", 34, 0,
7322 { -4155,9818,1529,3939,-25,4522,-5521,9870,6610,-2238,10873,1342 } },
7323 { "Canon PowerShot Pro90", 0, 0,
7324 { -4963,9896,2235,4642,-987,4294,-5162,10011,5859,-1770,11230,577 } },
7325 { "Canon PowerShot S30", 0, 0,
7326 { 10566,-3652,-1129,-6552,14662,2006,-2197,2581,7670 } },
7327 { "Canon PowerShot S40", 0, 0,
7328 { 8510,-2487,-940,-6869,14231,2900,-2318,2829,9013 } },
7329 { "Canon PowerShot S45", 0, 0,
7330 { 8163,-2333,-955,-6682,14174,2751,-2077,2597,8041 } },
7331 { "Canon PowerShot S50", 0, 0,
7332 { 8882,-2571,-863,-6348,14234,2288,-1516,2172,6569 } },
7333 { "Canon PowerShot S60", 0, 0,
7334 { 8795,-2482,-797,-7804,15403,2573,-1422,1996,7082 } },
7335 { "Canon PowerShot S70", 0, 0,
7336 { 9976,-3810,-832,-7115,14463,2906,-901,989,7889 } },
7337 { "Canon PowerShot S90", 0, 0,
7338 { 12374,-5016,-1049,-1677,9902,2078,-83,852,4683 } },
7339 { "Canon PowerShot S95", 0, 0,
7340 { 13440,-5896,-1279,-1236,9598,1931,-180,1001,4651 } },
7341 { "Canon PowerShot S100", 0, 0,
7342 { 7968,-2565,-636,-2873,10697,2513,180,667,4211 } },
7343 { "Canon PowerShot S110", 0, 0,
7344 { 8039,-2643,-654,-3783,11230,2930,-206,690,4194 } },
7345 { "Canon PowerShot S120", 0, 0,
7346 { 6961,-1685,-695,-4625,12945,1836,-1114,2152,5518 } },
7347 { "Canon PowerShot SX1 IS", 0, 0,
7348 { 6578,-259,-502,-5974,13030,3309,-308,1058,4970 } },
7349 { "Canon PowerShot SX50 HS", 0, 0,
7350 { 12432,-4753,-1247,-2110,10691,1629,-412,1623,4926 } },
7351 { "Canon PowerShot SX60 HS", 0, 0,
7352 { 13161,-5451,-1344,-1989,10654,1531,-47,1271,4955 } },
7353 { "Canon PowerShot A3300", 0, 0, /* DJC */
7354 { 10826,-3654,-1023,-3215,11310,1906,0,999,4960 } },
7355 { "Canon PowerShot A470", 0, 0, /* DJC */
7356 { 12513,-4407,-1242,-2680,10276,2405,-878,2215,4734 } },
7357 { "Canon PowerShot A610", 0, 0, /* DJC */
7358 { 15591,-6402,-1592,-5365,13198,2168,-1300,1824,5075 } },
7359 { "Canon PowerShot A620", 0, 0, /* DJC */
7360 { 15265,-6193,-1558,-4125,12116,2010,-888,1639,5220 } },
7361 { "Canon PowerShot A630", 0, 0, /* DJC */
7362 { 14201,-5308,-1757,-6087,14472,1617,-2191,3105,5348 } },
7363 { "Canon PowerShot A640", 0, 0, /* DJC */
7364 { 13124,-5329,-1390,-3602,11658,1944,-1612,2863,4885 } },
7365 { "Canon PowerShot A650", 0, 0, /* DJC */
7366 { 9427,-3036,-959,-2581,10671,1911,-1039,1982,4430 } },
7367 { "Canon PowerShot A720", 0, 0, /* DJC */
7368 { 14573,-5482,-1546,-1266,9799,1468,-1040,1912,3810 } },
7369 { "Canon PowerShot S3 IS", 0, 0, /* DJC */
7370 { 14062,-5199,-1446,-4712,12470,2243,-1286,2028,4836 } },
7371 { "Canon PowerShot SX110 IS", 0, 0, /* DJC */
7372 { 14134,-5576,-1527,-1991,10719,1273,-1158,1929,3581 } },
7373 { "Canon PowerShot SX220", 0, 0, /* DJC */
7374 { 13898,-5076,-1447,-1405,10109,1297,-244,1860,3687 } },
7375 { "Canon IXUS 160", 0, 0, /* DJC */
7376 { 11657,-3781,-1136,-3544,11262,2283,-160,1219,4700 } },
7377 { "Casio EX-S20", 0, 0, /* DJC */
7378 { 11634,-3924,-1128,-4968,12954,2015,-1588,2648,7206 } },
7379 { "Casio EX-Z750", 0, 0, /* DJC */
7380 { 10819,-3873,-1099,-4903,13730,1175,-1755,3751,4632 } },
7381 { "Casio EX-Z10", 128, 0xfff, /* DJC */
7382 { 9790,-3338,-603,-2321,10222,2099,-344,1273,4799 } },
7384 { 3390,480,-500,-800,3610,340,-550,2336,1192 } },
7386 { 3390,480,-500,-800,3610,340,-550,2336,1192 } },
7388 { 20183,-4295,-423,-3940,15330,3985,-280,4870,9800 } },
7389 { "Contax N Digital", 0, 0xf1e,
7390 { 7777,1285,-1053,-9280,16543,2916,-3677,5679,7060 } },
7392 { 6596,-2079,-562,-4782,13016,1933,-970,1581,5181 } },
7393 { "Epson R-D1", 0, 0,
7394 { 6827,-1878,-732,-8429,16012,2564,-704,592,7145 } },
7395 { "Fujifilm E550", 0, 0,
7396 { 11044,-3888,-1120,-7248,15168,2208,-1531,2277,8069 } },
7397 { "Fujifilm E900", 0, 0,
7398 { 9183,-2526,-1078,-7461,15071,2574,-2022,2440,8639 } },
7399 { "Fujifilm F5", 0, 0,
7400 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
7401 { "Fujifilm F6", 0, 0,
7402 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
7403 { "Fujifilm F77", 0, 0xfe9,
7404 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
7405 { "Fujifilm F7", 0, 0,
7406 { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } },
7407 { "Fujifilm F8", 0, 0,
7408 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
7409 { "Fujifilm S100FS", 514, 0,
7410 { 11521,-4355,-1065,-6524,13767,3058,-1466,1984,6045 } },
7411 { "Fujifilm S1", 0, 0,
7412 { 12297,-4882,-1202,-2106,10691,1623,-88,1312,4790 } },
7413 { "Fujifilm S20Pro", 0, 0,
7414 { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } },
7415 { "Fujifilm S20", 512, 0x3fff,
7416 { 11401,-4498,-1312,-5088,12751,2613,-838,1568,5941 } },
7417 { "Fujifilm S2Pro", 128, 0,
7418 { 12492,-4690,-1402,-7033,15423,1647,-1507,2111,7697 } },
7419 { "Fujifilm S3Pro", 0, 0,
7420 { 11807,-4612,-1294,-8927,16968,1988,-2120,2741,8006 } },
7421 { "Fujifilm S5Pro", 0, 0,
7422 { 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } },
7423 { "Fujifilm S5000", 0, 0,
7424 { 8754,-2732,-1019,-7204,15069,2276,-1702,2334,6982 } },
7425 { "Fujifilm S5100", 0, 0,
7426 { 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } },
7427 { "Fujifilm S5500", 0, 0,
7428 { 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } },
7429 { "Fujifilm S5200", 0, 0,
7430 { 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } },
7431 { "Fujifilm S5600", 0, 0,
7432 { 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } },
7433 { "Fujifilm S6", 0, 0,
7434 { 12628,-4887,-1401,-6861,14996,1962,-2198,2782,7091 } },
7435 { "Fujifilm S7000", 0, 0,
7436 { 10190,-3506,-1312,-7153,15051,2238,-2003,2399,7505 } },
7437 { "Fujifilm S9000", 0, 0,
7438 { 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 } },
7439 { "Fujifilm S9500", 0, 0,
7440 { 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 } },
7441 { "Fujifilm S9100", 0, 0,
7442 { 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 } },
7443 { "Fujifilm S9600", 0, 0,
7444 { 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 } },
7445 { "Fujifilm SL1000", 0, 0,
7446 { 11705,-4262,-1107,-2282,10791,1709,-555,1713,4945 } },
7447 { "Fujifilm IS-1", 0, 0,
7448 { 21461,-10807,-1441,-2332,10599,1999,289,875,7703 } },
7449 { "Fujifilm IS Pro", 0, 0,
7450 { 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } },
7451 { "Fujifilm HS10 HS11", 0, 0xf68,
7452 { 12440,-3954,-1183,-1123,9674,1708,-83,1614,4086 } },
7453 { "Fujifilm HS2", 0, 0,
7454 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
7455 { "Fujifilm HS3", 0, 0,
7456 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
7457 { "Fujifilm HS50EXR", 0, 0,
7458 { 12085,-4727,-953,-3257,11489,2002,-511,2046,4592 } },
7459 { "Fujifilm F900EXR", 0, 0,
7460 { 12085,-4727,-953,-3257,11489,2002,-511,2046,4592 } },
7461 { "Fujifilm X100S", 0, 0,
7462 { 10592,-4262,-1008,-3514,11355,2465,-870,2025,6386 } },
7463 { "Fujifilm X100T", 0, 0,
7464 { 10592,-4262,-1008,-3514,11355,2465,-870,2025,6386 } },
7465 { "Fujifilm X100", 0, 0,
7466 { 12161,-4457,-1069,-5034,12874,2400,-795,1724,6904 } },
7467 { "Fujifilm X10", 0, 0,
7468 { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } },
7469 { "Fujifilm X20", 0, 0,
7470 { 11768,-4971,-1133,-4904,12927,2183,-480,1723,4605 } },
7471 { "Fujifilm X30", 0, 0,
7472 { 12328,-5256,-1144,-4469,12927,1675,-87,1291,4351 } },
7473 { "Fujifilm X70", 0, 0,
7474 { 10450,-4329,-878,-3217,11105,2421,-752,1758,6519 } },
7475 { "Fujifilm X-Pro1", 0, 0,
7476 { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } },
7477 { "Fujifilm X-Pro2", 0, 0,
7478 { 11434,-4948,-1210,-3746,12042,1903,-666,1479,5235 } },
7479 { "Fujifilm X-A1", 0, 0,
7480 { 11086,-4555,-839,-3512,11310,2517,-815,1341,5940 } },
7481 { "Fujifilm X-A2", 0, 0,
7482 { 10763,-4560,-917,-3346,11311,2322,-475,1135,5843 } },
7483 { "Fujifilm X-E1", 0, 0,
7484 { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } },
7485 { "Fujifilm X-E2S", 0, 0,
7486 { 11562,-5118,-961,-3022,11007,2311,-525,1569,6097 } },
7487 { "Fujifilm X-E2", 0, 0,
7488 { 8458,-2451,-855,-4597,12447,2407,-1475,2482,6526 } },
7489 { "Fujifilm X-M1", 0, 0,
7490 { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } },
7491 { "Fujifilm X-S1", 0, 0,
7492 { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } },
7493 { "Fujifilm X-T1", 0, 0, /* also X-T10 */
7494 { 8458,-2451,-855,-4597,12447,2407,-1475,2482,6526 } },
7495 { "Fujifilm XF1", 0, 0,
7496 { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } },
7497 { "Fujifilm XQ", 0, 0, /* XQ1 and XQ2 */
7498 { 9252,-2704,-1064,-5893,14265,1717,-1101,2341,4349 } },
7499 { "Imacon Ixpress", 0, 0, /* DJC */
7500 { 7025,-1415,-704,-5188,13765,1424,-1248,2742,6038 } },
7501 { "Kodak NC2000", 0, 0,
7502 { 13891,-6055,-803,-465,9919,642,2121,82,1291 } },
7503 { "Kodak DCS315C", 8, 0,
7504 { 17523,-4827,-2510,756,8546,-137,6113,1649,2250 } },
7505 { "Kodak DCS330C", 8, 0,
7506 { 20620,-7572,-2801,-103,10073,-396,3551,-233,2220 } },
7507 { "Kodak DCS420", 0, 0,
7508 { 10868,-1852,-644,-1537,11083,484,2343,628,2216 } },
7509 { "Kodak DCS460", 0, 0,
7510 { 10592,-2206,-967,-1944,11685,230,2206,670,1273 } },
7511 { "Kodak EOSDCS1", 0, 0,
7512 { 10592,-2206,-967,-1944,11685,230,2206,670,1273 } },
7513 { "Kodak EOSDCS3B", 0, 0,
7514 { 9898,-2700,-940,-2478,12219,206,1985,634,1031 } },
7515 { "Kodak DCS520C", 178, 0,
7516 { 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } },
7517 { "Kodak DCS560C", 177, 0,
7518 { 20482,-7172,-3125,-1033,10410,-285,2542,226,3136 } },
7519 { "Kodak DCS620C", 177, 0,
7520 { 23617,-10175,-3149,-2054,11749,-272,2586,-489,3453 } },
7521 { "Kodak DCS620X", 176, 0,
7522 { 13095,-6231,154,12221,-21,-2137,895,4602,2258 } },
7523 { "Kodak DCS660C", 173, 0,
7524 { 18244,-6351,-2739,-791,11193,-521,3711,-129,2802 } },
7525 { "Kodak DCS720X", 0, 0,
7526 { 11775,-5884,950,9556,1846,-1286,-1019,6221,2728 } },
7527 { "Kodak DCS760C", 0, 0,
7528 { 16623,-6309,-1411,-4344,13923,323,2285,274,2926 } },
7529 { "Kodak DCS Pro SLR", 0, 0,
7530 { 5494,2393,-232,-6427,13850,2846,-1876,3997,5445 } },
7531 { "Kodak DCS Pro 14nx", 0, 0,
7532 { 5494,2393,-232,-6427,13850,2846,-1876,3997,5445 } },
7533 { "Kodak DCS Pro 14", 0, 0,
7534 { 7791,3128,-776,-8588,16458,2039,-2455,4006,6198 } },
7535 { "Kodak ProBack645", 0, 0,
7536 { 16414,-6060,-1470,-3555,13037,473,2545,122,4948 } },
7537 { "Kodak ProBack", 0, 0,
7538 { 21179,-8316,-2918,-915,11019,-165,3477,-180,4210 } },
7539 { "Kodak P712", 0, 0,
7540 { 9658,-3314,-823,-5163,12695,2768,-1342,1843,6044 } },
7541 { "Kodak P850", 0, 0xf7c,
7542 { 10511,-3836,-1102,-6946,14587,2558,-1481,1792,6246 } },
7543 { "Kodak P880", 0, 0xfff,
7544 { 12805,-4662,-1376,-7480,15267,2360,-1626,2194,7904 } },
7545 { "Kodak EasyShare Z980", 0, 0,
7546 { 11313,-3559,-1101,-3893,11891,2257,-1214,2398,4908 } },
7547 { "Kodak EasyShare Z981", 0, 0,
7548 { 12729,-4717,-1188,-1367,9187,2582,274,860,4411 } },
7549 { "Kodak EasyShare Z990", 0, 0xfed,
7550 { 11749,-4048,-1309,-1867,10572,1489,-138,1449,4522 } },
7551 { "Kodak EASYSHARE Z1015", 0, 0xef1,
7552 { 11265,-4286,-992,-4694,12343,2647,-1090,1523,5447 } },
7553 { "Leaf CMost", 0, 0,
7554 { 3952,2189,449,-6701,14585,2275,-4536,7349,6536 } },
7555 { "Leaf Valeo 6", 0, 0,
7556 { 3952,2189,449,-6701,14585,2275,-4536,7349,6536 } },
7557 { "Leaf Aptus 54S", 0, 0,
7558 { 8236,1746,-1314,-8251,15953,2428,-3673,5786,5771 } },
7559 { "Leaf Aptus 65", 0, 0,
7560 { 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 } },
7561 { "Leaf Aptus 75", 0, 0,
7562 { 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 } },
7564 { 8236,1746,-1314,-8251,15953,2428,-3673,5786,5771 } },
7565 { "Mamiya ZD", 0, 0,
7566 { 7645,2579,-1363,-8689,16717,2015,-3712,5941,5961 } },
7567 { "Micron 2010", 110, 0, /* DJC */
7568 { 16695,-3761,-2151,155,9682,163,3433,951,4904 } },
7569 { "Minolta DiMAGE 5", 0, 0xf7d,
7570 { 8983,-2942,-963,-6556,14476,2237,-2426,2887,8014 } },
7571 { "Minolta DiMAGE 7Hi", 0, 0xf7d,
7572 { 11368,-3894,-1242,-6521,14358,2339,-2475,3056,7285 } },
7573 { "Minolta DiMAGE 7", 0, 0xf7d,
7574 { 9144,-2777,-998,-6676,14556,2281,-2470,3019,7744 } },
7575 { "Minolta DiMAGE A1", 0, 0xf8b,
7576 { 9274,-2547,-1167,-8220,16323,1943,-2273,2720,8340 } },
7577 { "Minolta DiMAGE A200", 0, 0,
7578 { 8560,-2487,-986,-8112,15535,2771,-1209,1324,7743 } },
7579 { "Minolta DiMAGE A2", 0, 0xf8f,
7580 { 9097,-2726,-1053,-8073,15506,2762,-966,981,7763 } },
7581 { "Minolta DiMAGE Z2", 0, 0, /* DJC */
7582 { 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 } },
7583 { "Minolta DYNAX 5", 0, 0xffb,
7584 { 10284,-3283,-1086,-7957,15762,2316,-829,882,6644 } },
7585 { "Minolta DYNAX 7", 0, 0xffb,
7586 { 10239,-3104,-1099,-8037,15727,2451,-927,925,6871 } },
7587 { "Motorola PIXL", 0, 0, /* DJC */
7588 { 8898,-989,-1033,-3292,11619,1674,-661,3178,5216 } },
7589 { "Nikon D100", 0, 0,
7590 { 5902,-933,-782,-8983,16719,2354,-1402,1455,6464 } },
7591 { "Nikon D1H", 0, 0,
7592 { 7577,-2166,-926,-7454,15592,1934,-2377,2808,8606 } },
7593 { "Nikon D1X", 0, 0,
7594 { 7702,-2245,-975,-9114,17242,1875,-2679,3055,8521 } },
7595 { "Nikon D1", 0, 0, /* multiplied by 2.218750, 1.0, 1.148438 */
7596 { 16772,-4726,-2141,-7611,15713,1972,-2846,3494,9521 } },
7597 { "Nikon D200", 0, 0xfbc,
7598 { 8367,-2248,-763,-8758,16447,2422,-1527,1550,8053 } },
7599 { "Nikon D2H", 0, 0,
7600 { 5710,-901,-615,-8594,16617,2024,-2975,4120,6830 } },
7601 { "Nikon D2X", 0, 0,
7602 { 10231,-2769,-1255,-8301,15900,2552,-797,680,7148 } },
7603 { "Nikon D3000", 0, 0,
7604 { 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } },
7605 { "Nikon D3100", 0, 0,
7606 { 7911,-2167,-813,-5327,13150,2408,-1288,2483,7968 } },
7607 { "Nikon D3200", 0, 0xfb9,
7608 { 7013,-1408,-635,-5268,12902,2640,-1470,2801,7379 } },
7609 { "Nikon D3300", 0, 0,
7610 { 6988,-1384,-714,-5631,13410,2447,-1485,2204,7318 } },
7611 { "Nikon D300", 0, 0,
7612 { 9030,-1992,-715,-8465,16302,2255,-2689,3217,8069 } },
7613 { "Nikon D3X", 0, 0,
7614 { 7171,-1986,-648,-8085,15555,2718,-2170,2512,7457 } },
7615 { "Nikon D3S", 0, 0,
7616 { 8828,-2406,-694,-4874,12603,2541,-660,1509,7587 } },
7618 { 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } },
7619 { "Nikon D40X", 0, 0,
7620 { 8819,-2543,-911,-9025,16928,2151,-1329,1213,8449 } },
7621 { "Nikon D40", 0, 0,
7622 { 6992,-1668,-806,-8138,15748,2543,-874,850,7897 } },
7623 { "Nikon D4S", 0, 0,
7624 { 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } },
7626 { 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } },
7628 { 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } },
7629 { "Nikon D5000", 0, 0xf00,
7630 { 7309,-1403,-519,-8474,16008,2622,-2433,2826,8064 } },
7631 { "Nikon D5100", 0, 0x3de6,
7632 { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } },
7633 { "Nikon D5200", 0, 0,
7634 { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } },
7635 { "Nikon D5300", 0, 0,
7636 { 6988,-1384,-714,-5631,13410,2447,-1485,2204,7318 } },
7637 { "Nikon D5500", 0, 0,
7638 { 8821,-2938,-785,-4178,12142,2287,-824,1651,6860 } },
7639 { "Nikon D500", 0, 0,
7640 { 8813,-3210,-1036,-4703,12868,2021,-1054,1940,6129 } },
7641 { "Nikon D50", 0, 0,
7642 { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } },
7644 { 9200,-3522,-992,-5755,13803,2117,-753,1486,6338 } },
7645 { "Nikon D600", 0, 0x3e07,
7646 { 8178,-2245,-609,-4857,12394,2776,-1207,2086,7298 } },
7647 { "Nikon D610", 0, 0,
7648 { 8178,-2245,-609,-4857,12394,2776,-1207,2086,7298 } },
7649 { "Nikon D60", 0, 0,
7650 { 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } },
7651 { "Nikon D7000", 0, 0,
7652 { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } },
7653 { "Nikon D7100", 0, 0,
7654 { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } },
7655 { "Nikon D7200", 0, 0,
7656 { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } },
7657 { "Nikon D750", 0, 0,
7658 { 9020,-2890,-715,-4535,12436,2348,-934,1919,7086 } },
7659 { "Nikon D700", 0, 0,
7660 { 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } },
7661 { "Nikon D70", 0, 0,
7662 { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } },
7663 { "Nikon D810", 0, 0,
7664 { 9369,-3195,-791,-4488,12430,2301,-893,1796,6872 } },
7665 { "Nikon D800", 0, 0,
7666 { 7866,-2108,-555,-4869,12483,2681,-1176,2069,7501 } },
7667 { "Nikon D80", 0, 0,
7668 { 8629,-2410,-883,-9055,16940,2171,-1490,1363,8520 } },
7669 { "Nikon D90", 0, 0xf00,
7670 { 7309,-1403,-519,-8474,16008,2622,-2434,2826,8064 } },
7671 { "Nikon E700", 0, 0x3dd, /* DJC */
7672 { -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } },
7673 { "Nikon E800", 0, 0x3dd, /* DJC */
7674 { -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } },
7675 { "Nikon E950", 0, 0x3dd, /* DJC */
7676 { -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } },
7677 { "Nikon E995", 0, 0, /* copied from E5000 */
7678 { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
7679 { "Nikon E2100", 0, 0, /* copied from Z2, new white balance */
7680 { 13142,-4152,-1596,-4655,12374,2282,-1769,2696,6711} },
7681 { "Nikon E2500", 0, 0,
7682 { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
7683 { "Nikon E3200", 0, 0, /* DJC */
7684 { 9846,-2085,-1019,-3278,11109,2170,-774,2134,5745 } },
7685 { "Nikon E4300", 0, 0, /* copied from Minolta DiMAGE Z2 */
7686 { 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 } },
7687 { "Nikon E4500", 0, 0,
7688 { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
7689 { "Nikon E5000", 0, 0,
7690 { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
7691 { "Nikon E5400", 0, 0,
7692 { 9349,-2987,-1001,-7919,15766,2266,-2098,2680,6839 } },
7693 { "Nikon E5700", 0, 0,
7694 { -5368,11478,2368,5537,-113,3148,-4969,10021,5782,778,9028,211 } },
7695 { "Nikon E8400", 0, 0,
7696 { 7842,-2320,-992,-8154,15718,2599,-1098,1342,7560 } },
7697 { "Nikon E8700", 0, 0,
7698 { 8489,-2583,-1036,-8051,15583,2643,-1307,1407,7354 } },
7699 { "Nikon E8800", 0, 0,
7700 { 7971,-2314,-913,-8451,15762,2894,-1442,1520,7610 } },
7701 { "Nikon COOLPIX A", 0, 0,
7702 { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } },
7703 { "Nikon COOLPIX P330", 200, 0,
7704 { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } },
7705 { "Nikon COOLPIX P340", 200, 0,
7706 { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } },
7707 { "Nikon COOLPIX P6000", 0, 0,
7708 { 9698,-3367,-914,-4706,12584,2368,-837,968,5801 } },
7709 { "Nikon COOLPIX P7000", 0, 0,
7710 { 11432,-3679,-1111,-3169,11239,2202,-791,1380,4455 } },
7711 { "Nikon COOLPIX P7100", 0, 0,
7712 { 11053,-4269,-1024,-1976,10182,2088,-526,1263,4469 } },
7713 { "Nikon COOLPIX P7700", 200, 0,
7714 { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } },
7715 { "Nikon COOLPIX P7800", 200, 0,
7716 { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } },
7717 { "Nikon 1 V3", 0, 0,
7718 { 5958,-1559,-571,-4021,11453,2939,-634,1548,5087 } },
7719 { "Nikon 1 J4", 0, 0,
7720 { 5958,-1559,-571,-4021,11453,2939,-634,1548,5087 } },
7721 { "Nikon 1 J5", 0, 0,
7722 { 7520,-2518,-645,-3844,12102,1945,-913,2249,6835 } },
7723 { "Nikon 1 S2", 200, 0,
7724 { 6612,-1342,-618,-3338,11055,2623,-174,1792,5075 } },
7725 { "Nikon 1 V2", 0, 0,
7726 { 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } },
7727 { "Nikon 1 J3", 0, 0,
7728 { 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } },
7729 { "Nikon 1 AW1", 0, 0,
7730 { 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } },
7731 { "Nikon 1 ", 0, 0, /* J1, J2, S1, V1 */
7732 { 8994,-2667,-865,-4594,12324,2552,-699,1786,6260 } },
7733 { "Olympus AIR A01", 0, 0,
7734 { 8992,-3093,-639,-2563,10721,2122,-437,1270,5473 } },
7735 { "Olympus C5050", 0, 0,
7736 { 10508,-3124,-1273,-6079,14294,1901,-1653,2306,6237 } },
7737 { "Olympus C5060", 0, 0,
7738 { 10445,-3362,-1307,-7662,15690,2058,-1135,1176,7602 } },
7739 { "Olympus C7070", 0, 0,
7740 { 10252,-3531,-1095,-7114,14850,2436,-1451,1723,6365 } },
7741 { "Olympus C70", 0, 0,
7742 { 10793,-3791,-1146,-7498,15177,2488,-1390,1577,7321 } },
7743 { "Olympus C80", 0, 0,
7744 { 8606,-2509,-1014,-8238,15714,2703,-942,979,7760 } },
7745 { "Olympus E-10", 0, 0xffc,
7746 { 12745,-4500,-1416,-6062,14542,1580,-1934,2256,6603 } },
7747 { "Olympus E-1", 0, 0,
7748 { 11846,-4767,-945,-7027,15878,1089,-2699,4122,8311 } },
7749 { "Olympus E-20", 0, 0xffc,
7750 { 13173,-4732,-1499,-5807,14036,1895,-2045,2452,7142 } },
7751 { "Olympus E-300", 0, 0,
7752 { 7828,-1761,-348,-5788,14071,1830,-2853,4518,6557 } },
7753 { "Olympus E-330", 0, 0,
7754 { 8961,-2473,-1084,-7979,15990,2067,-2319,3035,8249 } },
7755 { "Olympus E-30", 0, 0xfbc,
7756 { 8144,-1861,-1111,-7763,15894,1929,-1865,2542,7607 } },
7757 { "Olympus E-3", 0, 0xf99,
7758 { 9487,-2875,-1115,-7533,15606,2010,-1618,2100,7389 } },
7759 { "Olympus E-400", 0, 0,
7760 { 6169,-1483,-21,-7107,14761,2536,-2904,3580,8568 } },
7761 { "Olympus E-410", 0, 0xf6a,
7762 { 8856,-2582,-1026,-7761,15766,2082,-2009,2575,7469 } },
7763 { "Olympus E-420", 0, 0xfd7,
7764 { 8746,-2425,-1095,-7594,15612,2073,-1780,2309,7416 } },
7765 { "Olympus E-450", 0, 0xfd2,
7766 { 8745,-2425,-1095,-7594,15613,2073,-1780,2309,7416 } },
7767 { "Olympus E-500", 0, 0,
7768 { 8136,-1968,-299,-5481,13742,1871,-2556,4205,6630 } },
7769 { "Olympus E-510", 0, 0xf6a,
7770 { 8785,-2529,-1033,-7639,15624,2112,-1783,2300,7817 } },
7771 { "Olympus E-520", 0, 0xfd2,
7772 { 8344,-2322,-1020,-7596,15635,2048,-1748,2269,7287 } },
7773 { "Olympus E-5", 0, 0xeec,
7774 { 11200,-3783,-1325,-4576,12593,2206,-695,1742,7504 } },
7775 { "Olympus E-600", 0, 0xfaf,
7776 { 8453,-2198,-1092,-7609,15681,2008,-1725,2337,7824 } },
7777 { "Olympus E-620", 0, 0xfaf,
7778 { 8453,-2198,-1092,-7609,15681,2008,-1725,2337,7824 } },
7779 { "Olympus E-P1", 0, 0xffd,
7780 { 8343,-2050,-1021,-7715,15705,2103,-1831,2380,8235 } },
7781 { "Olympus E-P2", 0, 0xffd,
7782 { 8343,-2050,-1021,-7715,15705,2103,-1831,2380,8235 } },
7783 { "Olympus E-P3", 0, 0,
7784 { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } },
7785 { "Olympus E-P5", 0, 0,
7786 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
7787 { "Olympus E-PL1s", 0, 0,
7788 { 11409,-3872,-1393,-4572,12757,2003,-709,1810,7415 } },
7789 { "Olympus E-PL1", 0, 0,
7790 { 11408,-4289,-1215,-4286,12385,2118,-387,1467,7787 } },
7791 { "Olympus E-PL2", 0, 0xcf3,
7792 { 15030,-5552,-1806,-3987,12387,1767,-592,1670,7023 } },
7793 { "Olympus E-PL3", 0, 0,
7794 { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } },
7795 { "Olympus E-PL5", 0, 0xfcb,
7796 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
7797 { "Olympus E-PL6", 0, 0,
7798 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
7799 { "Olympus E-PL7", 0, 0,
7800 { 9197,-3190,-659,-2606,10830,2039,-458,1250,5458 } },
7801 { "Olympus E-PM1", 0, 0,
7802 { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } },
7803 { "Olympus E-PM2", 0, 0,
7804 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
7805 { "Olympus E-M10", 0, 0, /* also E-M10 Mark II */
7806 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
7807 { "Olympus E-M1", 0, 0,
7808 { 7687,-1984,-606,-4327,11928,2721,-1381,2339,6452 } },
7809 { "Olympus E-M5MarkII", 0, 0,
7810 { 9422,-3258,-711,-2655,10898,2015,-512,1354,5512 } },
7811 { "Olympus E-M5", 0, 0xfe1,
7812 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
7813 { "Olympus PEN-F", 0, 0,
7814 { 9476,-3182,-765,-2613,10958,1893,-449,1315,5268 } },
7815 { "Olympus SH-2", 0, 0,
7816 { 10156,-3425,-1077,-2611,11177,1624,-385,1592,5080 } },
7817 { "Olympus SP350", 0, 0,
7818 { 12078,-4836,-1069,-6671,14306,2578,-786,939,7418 } },
7819 { "Olympus SP3", 0, 0,
7820 { 11766,-4445,-1067,-6901,14421,2707,-1029,1217,7572 } },
7821 { "Olympus SP500UZ", 0, 0xfff,
7822 { 9493,-3415,-666,-5211,12334,3260,-1548,2262,6482 } },
7823 { "Olympus SP510UZ", 0, 0xffe,
7824 { 10593,-3607,-1010,-5881,13127,3084,-1200,1805,6721 } },
7825 { "Olympus SP550UZ", 0, 0xffe,
7826 { 11597,-4006,-1049,-5432,12799,2957,-1029,1750,6516 } },
7827 { "Olympus SP560UZ", 0, 0xff9,
7828 { 10915,-3677,-982,-5587,12986,2911,-1168,1968,6223 } },
7829 { "Olympus SP570UZ", 0, 0,
7830 { 11522,-4044,-1146,-4736,12172,2904,-988,1829,6039 } },
7831 { "Olympus STYLUS1", 0, 0,
7832 { 8360,-2420,-880,-3928,12353,1739,-1381,2416,5173 } },
7833 { "Olympus TG-4", 0, 0,
7834 { 11426,-4159,-1126,-2066,10678,1593,-120,1327,4998 } },
7835 { "Olympus XZ-10", 0, 0,
7836 { 9777,-3483,-925,-2886,11297,1800,-602,1663,5134 } },
7837 { "Olympus XZ-1", 0, 0,
7838 { 10901,-4095,-1074,-1141,9208,2293,-62,1417,5158 } },
7839 { "Olympus XZ-2", 0, 0,
7840 { 9777,-3483,-925,-2886,11297,1800,-602,1663,5134 } },
7841 { "OmniVision", 0, 0, /* DJC */
7842 { 12782,-4059,-379,-478,9066,1413,1340,1513,5176 } },
7843 { "Pentax *ist DL2", 0, 0,
7844 { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
7845 { "Pentax *ist DL", 0, 0,
7846 { 10829,-2838,-1115,-8339,15817,2696,-837,680,11939 } },
7847 { "Pentax *ist DS2", 0, 0,
7848 { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
7849 { "Pentax *ist DS", 0, 0,
7850 { 10371,-2333,-1206,-8688,16231,2602,-1230,1116,11282 } },
7851 { "Pentax *ist D", 0, 0,
7852 { 9651,-2059,-1189,-8881,16512,2487,-1460,1345,10687 } },
7853 { "Pentax K10D", 0, 0,
7854 { 9566,-2863,-803,-7170,15172,2112,-818,803,9705 } },
7855 { "Pentax K1", 0, 0,
7856 { 11095,-3157,-1324,-8377,15834,2720,-1108,947,11688 } },
7857 { "Pentax K20D", 0, 0,
7858 { 9427,-2714,-868,-7493,16092,1373,-2199,3264,7180 } },
7859 { "Pentax K200D", 0, 0,
7860 { 9186,-2678,-907,-8693,16517,2260,-1129,1094,8524 } },
7861 { "Pentax K2000", 0, 0,
7862 { 11057,-3604,-1155,-5152,13046,2329,-282,375,8104 } },
7863 { "Pentax K-m", 0, 0,
7864 { 11057,-3604,-1155,-5152,13046,2329,-282,375,8104 } },
7865 { "Pentax K-x", 0, 0,
7866 { 8843,-2837,-625,-5025,12644,2668,-411,1234,7410 } },
7867 { "Pentax K-r", 0, 0,
7868 { 9895,-3077,-850,-5304,13035,2521,-883,1768,6936 } },
7869 { "Pentax K-1", 0, 0,
7870 { 8566,-2746,-1201,-3612,12204,1550,-893,1680,6264 } },
7871 { "Pentax K-30", 0, 0,
7872 { 8710,-2632,-1167,-3995,12301,1881,-981,1719,6535 } },
7873 { "Pentax K-3 II", 0, 0,
7874 { 8626,-2607,-1155,-3995,12301,1881,-1039,1822,6925 } },
7875 { "Pentax K-3", 0, 0,
7876 { 7415,-2052,-721,-5186,12788,2682,-1446,2157,6773 } },
7877 { "Pentax K-5 II", 0, 0,
7878 { 8170,-2725,-639,-4440,12017,2744,-771,1465,6599 } },
7879 { "Pentax K-5", 0, 0,
7880 { 8713,-2833,-743,-4342,11900,2772,-722,1543,6247 } },
7881 { "Pentax K-7", 0, 0,
7882 { 9142,-2947,-678,-8648,16967,1663,-2224,2898,8615 } },
7883 { "Pentax K-S1", 0, 0,
7884 { 8512,-3211,-787,-4167,11966,2487,-638,1288,6054 } },
7885 { "Pentax K-S2", 0, 0,
7886 { 8662,-3280,-798,-3928,11771,2444,-586,1232,6054 } },
7887 { "Pentax Q-S1", 0, 0,
7888 { 12995,-5593,-1107,-1879,10139,2027,-64,1233,4919 } },
7889 { "Pentax 645D", 0, 0x3e00,
7890 { 10646,-3593,-1158,-3329,11699,1831,-667,2874,6287 } },
7891 { "Panasonic DMC-CM1", 15, 0,
7892 { 8770,-3194,-820,-2871,11281,1803,-513,1552,4434 } },
7893 { "Panasonic DMC-FZ8", 0, 0xf7f,
7894 { 8986,-2755,-802,-6341,13575,3077,-1476,2144,6379 } },
7895 { "Panasonic DMC-FZ18", 0, 0,
7896 { 9932,-3060,-935,-5809,13331,2753,-1267,2155,5575 } },
7897 { "Panasonic DMC-FZ28", 15, 0xf96,
7898 { 10109,-3488,-993,-5412,12812,2916,-1305,2140,5543 } },
7899 { "Panasonic DMC-FZ330", 15, 0,
7900 { 8378,-2798,-769,-3068,11410,1877,-538,1792,4623 } },
7901 { "Panasonic DMC-FZ300", 15, 0,
7902 { 8378,-2798,-769,-3068,11410,1877,-538,1792,4623 } },
7903 { "Panasonic DMC-FZ30", 0, 0xf94,
7904 { 10976,-4029,-1141,-7918,15491,2600,-1670,2071,8246 } },
7905 { "Panasonic DMC-FZ3", 15, 0,
7906 { 9938,-2780,-890,-4604,12393,2480,-1117,2304,4620 } },
7907 { "Panasonic DMC-FZ4", 15, 0,
7908 { 13639,-5535,-1371,-1698,9633,2430,316,1152,4108 } },
7909 { "Panasonic DMC-FZ50", 0, 0,
7910 { 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } },
7911 { "Panasonic DMC-FZ7", 15, 0,
7912 { 11532,-4324,-1066,-2375,10847,1749,-564,1699,4351 } },
7913 { "Leica V-LUX1", 0, 0,
7914 { 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } },
7915 { "Panasonic DMC-L10", 15, 0xf96,
7916 { 8025,-1942,-1050,-7920,15904,2100,-2456,3005,7039 } },
7917 { "Panasonic DMC-L1", 0, 0xf7f,
7918 { 8054,-1885,-1025,-8349,16367,2040,-2805,3542,7629 } },
7919 { "Leica DIGILUX 3", 0, 0xf7f,
7920 { 8054,-1885,-1025,-8349,16367,2040,-2805,3542,7629 } },
7921 { "Panasonic DMC-LC1", 0, 0,
7922 { 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } },
7923 { "Leica DIGILUX 2", 0, 0,
7924 { 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } },
7925 { "Panasonic DMC-LX100", 15, 0,
7926 { 8844,-3538,-768,-3709,11762,2200,-698,1792,5220 } },
7927 { "Leica D-LUX (Typ 109)", 15, 0,
7928 { 8844,-3538,-768,-3709,11762,2200,-698,1792,5220 } },
7929 { "Panasonic DMC-LF1", 15, 0,
7930 { 9379,-3267,-816,-3227,11560,1881,-926,1928,5340 } },
7931 { "Leica C (Typ 112)", 15, 0,
7932 { 9379,-3267,-816,-3227,11560,1881,-926,1928,5340 } },
7933 { "Panasonic DMC-LX1", 0, 0xf7f,
7934 { 10704,-4187,-1230,-8314,15952,2501,-920,945,8927 } },
7935 { "Leica D-LUX2", 0, 0xf7f,
7936 { 10704,-4187,-1230,-8314,15952,2501,-920,945,8927 } },
7937 { "Panasonic DMC-LX2", 0, 0,
7938 { 8048,-2810,-623,-6450,13519,3272,-1700,2146,7049 } },
7939 { "Leica D-LUX3", 0, 0,
7940 { 8048,-2810,-623,-6450,13519,3272,-1700,2146,7049 } },
7941 { "Panasonic DMC-LX3", 15, 0,
7942 { 8128,-2668,-655,-6134,13307,3161,-1782,2568,6083 } },
7943 { "Leica D-LUX 4", 15, 0,
7944 { 8128,-2668,-655,-6134,13307,3161,-1782,2568,6083 } },
7945 { "Panasonic DMC-LX5", 15, 0,
7946 { 10909,-4295,-948,-1333,9306,2399,22,1738,4582 } },
7947 { "Leica D-LUX 5", 15, 0,
7948 { 10909,-4295,-948,-1333,9306,2399,22,1738,4582 } },
7949 { "Panasonic DMC-LX7", 15, 0,
7950 { 10148,-3743,-991,-2837,11366,1659,-701,1893,4899 } },
7951 { "Leica D-LUX 6", 15, 0,
7952 { 10148,-3743,-991,-2837,11366,1659,-701,1893,4899 } },
7953 { "Panasonic DMC-FZ1000", 15, 0,
7954 { 7830,-2696,-763,-3325,11667,1866,-641,1712,4824 } },
7955 { "Leica V-LUX (Typ 114)", 15, 0,
7956 { 7830,-2696,-763,-3325,11667,1866,-641,1712,4824 } },
7957 { "Panasonic DMC-FZ100", 15, 0xfff,
7958 { 16197,-6146,-1761,-2393,10765,1869,366,2238,5248 } },
7959 { "Leica V-LUX 2", 15, 0xfff,
7960 { 16197,-6146,-1761,-2393,10765,1869,366,2238,5248 } },
7961 { "Panasonic DMC-FZ150", 15, 0xfff,
7962 { 11904,-4541,-1189,-2355,10899,1662,-296,1586,4289 } },
7963 { "Leica V-LUX 3", 15, 0xfff,
7964 { 11904,-4541,-1189,-2355,10899,1662,-296,1586,4289 } },
7965 { "Panasonic DMC-FZ200", 15, 0xfff,
7966 { 8112,-2563,-740,-3730,11784,2197,-941,2075,4933 } },
7967 { "Leica V-LUX 4", 15, 0xfff,
7968 { 8112,-2563,-740,-3730,11784,2197,-941,2075,4933 } },
7969 { "Panasonic DMC-FX150", 15, 0xfff,
7970 { 9082,-2907,-925,-6119,13377,3058,-1797,2641,5609 } },
7971 { "Panasonic DMC-G10", 0, 0,
7972 { 10113,-3400,-1114,-4765,12683,2317,-377,1437,6710 } },
7973 { "Panasonic DMC-G1", 15, 0xf94,
7974 { 8199,-2065,-1056,-8124,16156,2033,-2458,3022,7220 } },
7975 { "Panasonic DMC-G2", 15, 0xf3c,
7976 { 10113,-3400,-1114,-4765,12683,2317,-377,1437,6710 } },
7977 { "Panasonic DMC-G3", 15, 0xfff,
7978 { 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } },
7979 { "Panasonic DMC-G5", 15, 0xfff,
7980 { 7798,-2562,-740,-3879,11584,2613,-1055,2248,5434 } },
7981 { "Panasonic DMC-G6", 15, 0xfff,
7982 { 8294,-2891,-651,-3869,11590,2595,-1183,2267,5352 } },
7983 { "Panasonic DMC-G7", 15, 0xfff,
7984 { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } },
7985 { "Panasonic DMC-GF1", 15, 0xf92,
7986 { 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } },
7987 { "Panasonic DMC-GF2", 15, 0xfff,
7988 { 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } },
7989 { "Panasonic DMC-GF3", 15, 0xfff,
7990 { 9051,-2468,-1204,-5212,13276,2121,-1197,2510,6890 } },
7991 { "Panasonic DMC-GF5", 15, 0xfff,
7992 { 8228,-2945,-660,-3938,11792,2430,-1094,2278,5793 } },
7993 { "Panasonic DMC-GF6", 15, 0,
7994 { 8130,-2801,-946,-3520,11289,2552,-1314,2511,5791 } },
7995 { "Panasonic DMC-GF7", 15, 0,
7996 { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } },
7997 { "Panasonic DMC-GF8", 15, 0,
7998 { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } },
7999 { "Panasonic DMC-GH1", 15, 0xf92,
8000 { 6299,-1466,-532,-6535,13852,2969,-2331,3112,5984 } },
8001 { "Panasonic DMC-GH2", 15, 0xf95,
8002 { 7780,-2410,-806,-3913,11724,2484,-1018,2390,5298 } },
8003 { "Panasonic DMC-GH3", 15, 0,
8004 { 6559,-1752,-491,-3672,11407,2586,-962,1875,5130 } },
8005 { "Panasonic DMC-GH4", 15, 0,
8006 { 7122,-2108,-512,-3155,11201,2231,-541,1423,5045 } },
8007 { "Panasonic DMC-GM1", 15, 0,
8008 { 6770,-1895,-744,-5232,13145,2303,-1664,2691,5703 } },
8009 { "Panasonic DMC-GM5", 15, 0,
8010 { 8238,-3244,-679,-3921,11814,2384,-836,2022,5852 } },
8011 { "Panasonic DMC-GX1", 15, 0,
8012 { 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } },
8013 { "Panasonic DMC-GX7", 15, 0,
8014 { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } },
8015 { "Panasonic DMC-GX8", 15, 0,
8016 { 7564,-2263,-606,-3148,11239,2177,-540,1435,4853 } },
8017 { "Panasonic DMC-TZ1", 15, 0,
8018 { 7790,-2736,-755,-3452,11870,1769,-628,1647,4898 } },
8019 { "Panasonic DMC-ZS1", 15, 0,
8020 { 7790,-2736,-755,-3452,11870,1769,-628,1647,4898 } },
8021 { "Panasonic DMC-TZ6", 15, 0,
8022 { 8607,-2822,-808,-3755,11930,2049,-820,2060,5224 } },
8023 { "Panasonic DMC-ZS4", 15, 0,
8024 { 8607,-2822,-808,-3755,11930,2049,-820,2060,5224 } },
8025 { "Panasonic DMC-TZ7", 15, 0,
8026 { 8802,-3135,-789,-3151,11468,1904,-550,1745,4810 } },
8027 { "Panasonic DMC-ZS5", 15, 0,
8028 { 8802,-3135,-789,-3151,11468,1904,-550,1745,4810 } },
8029 { "Panasonic DMC-TZ8", 15, 0,
8030 { 8550,-2908,-842,-3195,11529,1881,-338,1603,4631 } },
8031 { "Panasonic DMC-ZS6", 15, 0,
8032 { 8550,-2908,-842,-3195,11529,1881,-338,1603,4631 } },
8033 { "Leica S (Typ 007)", 0, 0,
8034 { 6063,-2234,-231,-5210,13787,1500,-1043,2866,6997 } },
8035 { "Leica X", 0, 0, /* X and X-U, both (Typ 113) */
8036 { 7712,-2059,-653,-3882,11494,2726,-710,1332,5958 } },
8037 { "Leica Q (Typ 116)", 0, 0,
8038 { 11865,-4523,-1441,-5423,14458,935,-1587,2687,4830 } },
8039 { "Leica M (Typ 262)", 0, 0,
8040 { 6653,-1486,-611,-4221,13303,929,-881,2416,7226 } },
8041 { "Leica SL (Typ 601)", 0, 0,
8042 { 11865,-4523,-1441,-5423,14458,935,-1587,2687,4830} },
8043 { "Phase One H 20", 0, 0, /* DJC */
8044 { 1313,1855,-109,-6715,15908,808,-327,1840,6020 } },
8045 { "Phase One H 25", 0, 0,
8046 { 2905,732,-237,-8134,16626,1476,-3038,4253,7517 } },
8047 { "Phase One P 2", 0, 0,
8048 { 2905,732,-237,-8134,16626,1476,-3038,4253,7517 } },
8049 { "Phase One P 30", 0, 0,
8050 { 4516,-245,-37,-7020,14976,2173,-3206,4671,7087 } },
8051 { "Phase One P 45", 0, 0,
8052 { 5053,-24,-117,-5684,14076,1702,-2619,4492,5849 } },
8053 { "Phase One P40", 0, 0,
8054 { 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } },
8055 { "Phase One P65", 0, 0,
8056 { 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } },
8057 { "Photron BC2-HD", 0, 0, /* DJC */
8058 { 14603,-4122,-528,-1810,9794,2017,-297,2763,5936 } },
8059 { "Red One", 704, 0xffff, /* DJC */
8060 { 21014,-7891,-2613,-3056,12201,856,-2203,5125,8042 } },
8061 { "Ricoh GR II", 0, 0,
8062 { 4630,-834,-423,-4977,12805,2417,-638,1467,6115 } },
8064 { 3708,-543,-160,-5381,12254,3556,-1471,1929,8234 } },
8065 { "Samsung EX1", 0, 0x3e00,
8066 { 8898,-2498,-994,-3144,11328,2066,-760,1381,4576 } },
8067 { "Samsung EX2F", 0, 0x7ff,
8068 { 10648,-3897,-1055,-2022,10573,1668,-492,1611,4742 } },
8069 { "Samsung EK-GN120", 0, 0,
8070 { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } },
8071 { "Samsung NX mini", 0, 0,
8072 { 5222,-1196,-550,-6540,14649,2009,-1666,2819,5657 } },
8073 { "Samsung NX3300", 0, 0,
8074 { 8060,-2933,-761,-4504,12890,1762,-630,1489,5227 } },
8075 { "Samsung NX3000", 0, 0,
8076 { 8060,-2933,-761,-4504,12890,1762,-630,1489,5227 } },
8077 { "Samsung NX30", 0, 0, /* NX30, NX300, NX300M */
8078 { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } },
8079 { "Samsung NX2000", 0, 0,
8080 { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } },
8081 { "Samsung NX2", 0, 0xfff, /* NX20, NX200, NX210 */
8082 { 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } },
8083 { "Samsung NX1000", 0, 0,
8084 { 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } },
8085 { "Samsung NX1100", 0, 0,
8086 { 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } },
8087 { "Samsung NX11", 0, 0,
8088 { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } },
8089 { "Samsung NX10", 0, 0, /* also NX100 */
8090 { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } },
8091 { "Samsung NX500", 0, 0,
8092 { 10686,-4042,-1052,-3595,13238,276,-464,1259,5931 } },
8093 { "Samsung NX5", 0, 0,
8094 { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } },
8095 { "Samsung NX1", 0, 0,
8096 { 10686,-4042,-1052,-3595,13238,276,-464,1259,5931 } },
8097 { "Samsung WB2000", 0, 0xfff,
8098 { 12093,-3557,-1155,-1000,9534,1733,-22,1787,4576 } },
8099 { "Samsung GX-1", 0, 0,
8100 { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
8101 { "Samsung GX20", 0, 0, /* copied from Pentax K20D */
8102 { 9427,-2714,-868,-7493,16092,1373,-2199,3264,7180 } },
8103 { "Samsung S85", 0, 0, /* DJC */
8104 { 11885,-3968,-1473,-4214,12299,1916,-835,1655,5549 } },
8105 { "Sinar", 0, 0, /* DJC */
8106 { 16442,-2956,-2422,-2877,12128,750,-1136,6066,4559 } },
8107 { "Sony DSC-F828", 0, 0,
8108 { 7924,-1910,-777,-8226,15459,2998,-1517,2199,6818,-7242,11401,3481 } },
8109 { "Sony DSC-R1", 0, 0,
8110 { 8512,-2641,-694,-8042,15670,2526,-1821,2117,7414 } },
8111 { "Sony DSC-V3", 0, 0,
8112 { 7511,-2571,-692,-7894,15088,3060,-948,1111,8128 } },
8113 { "Sony DSC-RX100M", 0, 0, /* M2, M3, and M4 */
8114 { 6596,-2079,-562,-4782,13016,1933,-970,1581,5181 } },
8115 { "Sony DSC-RX100", 0, 0,
8116 { 8651,-2754,-1057,-3464,12207,1373,-568,1398,4434 } },
8117 { "Sony DSC-RX10", 0, 0, /* also RX10M2 */
8118 { 6679,-1825,-745,-5047,13256,1953,-1580,2422,5183 } },
8119 { "Sony DSC-RX1RM2", 0, 0,
8120 { 6629,-1900,-483,-4618,12349,2550,-622,1381,6514 } },
8121 { "Sony DSC-RX1", 0, 0,
8122 { 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } },
8123 { "Sony DSLR-A100", 0, 0xfeb,
8124 { 9437,-2811,-774,-8405,16215,2290,-710,596,7181 } },
8125 { "Sony DSLR-A290", 0, 0,
8126 { 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } },
8127 { "Sony DSLR-A2", 0, 0,
8128 { 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } },
8129 { "Sony DSLR-A300", 0, 0,
8130 { 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } },
8131 { "Sony DSLR-A330", 0, 0,
8132 { 9847,-3091,-929,-8485,16346,2225,-714,595,7103 } },
8133 { "Sony DSLR-A350", 0, 0xffc,
8134 { 6038,-1484,-578,-9146,16746,2513,-875,746,7217 } },
8135 { "Sony DSLR-A380", 0, 0,
8136 { 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } },
8137 { "Sony DSLR-A390", 0, 0,
8138 { 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } },
8139 { "Sony DSLR-A450", 0, 0xfeb,
8140 { 4950,-580,-103,-5228,12542,3029,-709,1435,7371 } },
8141 { "Sony DSLR-A580", 0, 0xfeb,
8142 { 5932,-1492,-411,-4813,12285,2856,-741,1524,6739 } },
8143 { "Sony DSLR-A500", 0, 0xfeb,
8144 { 6046,-1127,-278,-5574,13076,2786,-691,1419,7625 } },
8145 { "Sony DSLR-A5", 0, 0xfeb,
8146 { 4950,-580,-103,-5228,12542,3029,-709,1435,7371 } },
8147 { "Sony DSLR-A700", 0, 0,
8148 { 5775,-805,-359,-8574,16295,2391,-1943,2341,7249 } },
8149 { "Sony DSLR-A850", 0, 0,
8150 { 5413,-1162,-365,-5665,13098,2866,-608,1179,8440 } },
8151 { "Sony DSLR-A900", 0, 0,
8152 { 5209,-1072,-397,-8845,16120,2919,-1618,1803,8654 } },
8153 { "Sony ILCA-68", 0, 0,
8154 { 6435,-1903,-536,-4722,12449,2550,-663,1363,6517 } },
8155 { "Sony ILCA-77M2", 0, 0,
8156 { 5991,-1732,-443,-4100,11989,2381,-704,1467,5992 } },
8157 { "Sony ILCE-6300", 0, 0,
8158 { 5973,-1695,-419,-3826,11797,2293,-639,1398,5789 } },
8159 { "Sony ILCE-7M2", 0, 0,
8160 { 5271,-712,-347,-6153,13653,2763,-1601,2366,7242 } },
8161 { "Sony ILCE-7S", 0, 0, /* also ILCE-7SM2 */
8162 { 5838,-1430,-246,-3497,11477,2297,-748,1885,5778 } },
8163 { "Sony ILCE-7RM2", 0, 0,
8164 { 6629,-1900,-483,-4618,12349,2550,-622,1381,6514 } },
8165 { "Sony ILCE-7R", 0, 0,
8166 { 4913,-541,-202,-6130,13513,2906,-1564,2151,7183 } },
8167 { "Sony ILCE-7", 0, 0,
8168 { 5271,-712,-347,-6153,13653,2763,-1601,2366,7242 } },
8169 { "Sony ILCE", 0, 0, /* 3000, 5000, 5100, 6000, and QX1 */
8170 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
8171 { "Sony NEX-5N", 0, 0,
8172 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
8173 { "Sony NEX-5R", 0, 0,
8174 { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } },
8175 { "Sony NEX-5T", 0, 0,
8176 { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } },
8177 { "Sony NEX-3N", 0, 0,
8178 { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } },
8179 { "Sony NEX-3", 138, 0, /* DJC */
8180 { 6907,-1256,-645,-4940,12621,2320,-1710,2581,6230 } },
8181 { "Sony NEX-5", 116, 0, /* DJC */
8182 { 6807,-1350,-342,-4216,11649,2567,-1089,2001,6420 } },
8183 { "Sony NEX-3", 0, 0, /* Adobe */
8184 { 6549,-1550,-436,-4880,12435,2753,-854,1868,6976 } },
8185 { "Sony NEX-5", 0, 0, /* Adobe */
8186 { 6549,-1550,-436,-4880,12435,2753,-854,1868,6976 } },
8187 { "Sony NEX-6", 0, 0,
8188 { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } },
8189 { "Sony NEX-7", 0, 0,
8190 { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } },
8191 { "Sony NEX", 0, 0, /* NEX-C3, NEX-F3 */
8192 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
8193 { "Sony SLT-A33", 0, 0,
8194 { 6069,-1221,-366,-5221,12779,2734,-1024,2066,6834 } },
8195 { "Sony SLT-A35", 0, 0,
8196 { 5986,-1618,-415,-4557,11820,3120,-681,1404,6971 } },
8197 { "Sony SLT-A37", 0, 0,
8198 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
8199 { "Sony SLT-A55", 0, 0,
8200 { 5932,-1492,-411,-4813,12285,2856,-741,1524,6739 } },
8201 { "Sony SLT-A57", 0, 0,
8202 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
8203 { "Sony SLT-A58", 0, 0,
8204 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
8205 { "Sony SLT-A65", 0, 0,
8206 { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } },
8207 { "Sony SLT-A77", 0, 0,
8208 { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } },
8209 { "Sony SLT-A99", 0, 0,
8210 { 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } },
8212 double cam_xyz[4][3];
8216 sprintf (name, "%s %s", make, model);
8217 for (i=0; i < sizeof table / sizeof *table; i++)
8218 if (!strncmp (name, table[i].prefix, strlen(table[i].prefix))) {
8219 if (table[i].black) black = (ushort) table[i].black;
8220 if (table[i].maximum) maximum = (ushort) table[i].maximum;
8221 if (table[i].trans[0]) {
8222 for (raw_color = j=0; j < 12; j++)
8223 ((double *)cam_xyz)[j] = table[i].trans[j] / 10000.0;
8224 cam_xyz_coeff (rgb_cam, cam_xyz);
8230 void CLASS simple_coeff (int index)
8232 static const float table[][12] = {
8233 /* index 0 -- all Foveon cameras */
8234 { 1.4032,-0.2231,-0.1016,-0.5263,1.4816,0.017,-0.0112,0.0183,0.9113 },
8235 /* index 1 -- Kodak DC20 and DC25 */
8236 { 2.25,0.75,-1.75,-0.25,-0.25,0.75,0.75,-0.25,-0.25,-1.75,0.75,2.25 },
8237 /* index 2 -- Logitech Fotoman Pixtura */
8238 { 1.893,-0.418,-0.476,-0.495,1.773,-0.278,-1.017,-0.655,2.672 },
8239 /* index 3 -- Nikon E880, E900, and E990 */
8240 { -1.936280, 1.800443, -1.448486, 2.584324,
8241 1.405365, -0.524955, -0.289090, 0.408680,
8242 -1.204965, 1.082304, 2.941367, -1.818705 }
8246 for (raw_color = i=0; i < 3; i++)
8247 FORCC rgb_cam[i][c] = table[index][i*colors+c];
8250 short CLASS guess_byte_order (int words)
8254 double diff, sum[2] = {0,0};
8256 fread (test[0], 2, 2, ifp);
8257 for (words-=2; words--; ) {
8258 fread (test[t], 2, 1, ifp);
8259 for (msb=0; msb < 2; msb++) {
8260 diff = (test[t^2][msb] << 8 | test[t^2][!msb])
8261 - (test[t ][msb] << 8 | test[t ][!msb]);
8262 sum[msb] += diff*diff;
8266 return sum[0] < sum[1] ? 0x4d4d : 0x4949;
8269 float CLASS find_green (int bps, int bite, int off0, int off1)
8272 int vbits, col, i, c;
8273 ushort img[2][2064];
8277 fseek (ifp, c ? off1:off0, SEEK_SET);
8278 for (vbits=col=0; col < width; col++) {
8279 for (vbits -= bps; vbits < 0; vbits += bite) {
8281 for (i=0; i < bite; i+=8)
8282 bitbuf |= (unsigned) (fgetc(ifp) << i);
8284 img[c][col] = bitbuf << (64-bps-vbits) >> (64-bps);
8288 sum[ c & 1] += ABS(img[0][c]-img[1][c+1]);
8289 sum[~c & 1] += ABS(img[1][c]-img[0][c+1]);
8291 return 100 * log(sum[0]/sum[1]);
8295 Identify which camera created this file, and set global variables
8298 void CLASS identify()
8300 static const short pana[][6] = {
8301 { 3130, 1743, 4, 0, -6, 0 },
8302 { 3130, 2055, 4, 0, -6, 0 },
8303 { 3130, 2319, 4, 0, -6, 0 },
8304 { 3170, 2103, 18, 0,-42, 20 },
8305 { 3170, 2367, 18, 13,-42,-21 },
8306 { 3177, 2367, 0, 0, -1, 0 },
8307 { 3304, 2458, 0, 0, -1, 0 },
8308 { 3330, 2463, 9, 0, -5, 0 },
8309 { 3330, 2479, 9, 0,-17, 4 },
8310 { 3370, 1899, 15, 0,-44, 20 },
8311 { 3370, 2235, 15, 0,-44, 20 },
8312 { 3370, 2511, 15, 10,-44,-21 },
8313 { 3690, 2751, 3, 0, -8, -3 },
8314 { 3710, 2751, 0, 0, -3, 0 },
8315 { 3724, 2450, 0, 0, 0, -2 },
8316 { 3770, 2487, 17, 0,-44, 19 },
8317 { 3770, 2799, 17, 15,-44,-19 },
8318 { 3880, 2170, 6, 0, -6, 0 },
8319 { 4060, 3018, 0, 0, 0, -2 },
8320 { 4290, 2391, 3, 0, -8, -1 },
8321 { 4330, 2439, 17, 15,-44,-19 },
8322 { 4508, 2962, 0, 0, -3, -4 },
8323 { 4508, 3330, 0, 0, -3, -6 },
8325 static const ushort canon[][11] = {
8326 { 1944, 1416, 0, 0, 48, 0 },
8327 { 2144, 1560, 4, 8, 52, 2, 0, 0, 0, 25 },
8328 { 2224, 1456, 48, 6, 0, 2 },
8329 { 2376, 1728, 12, 6, 52, 2 },
8330 { 2672, 1968, 12, 6, 44, 2 },
8331 { 3152, 2068, 64, 12, 0, 0, 16 },
8332 { 3160, 2344, 44, 12, 4, 4 },
8333 { 3344, 2484, 4, 6, 52, 6 },
8334 { 3516, 2328, 42, 14, 0, 0 },
8335 { 3596, 2360, 74, 12, 0, 0 },
8336 { 3744, 2784, 52, 12, 8, 12 },
8337 { 3944, 2622, 30, 18, 6, 2 },
8338 { 3948, 2622, 42, 18, 0, 2 },
8339 { 3984, 2622, 76, 20, 0, 2, 14 },
8340 { 4104, 3048, 48, 12, 24, 12 },
8341 { 4116, 2178, 4, 2, 0, 0 },
8342 { 4152, 2772, 192, 12, 0, 0 },
8343 { 4160, 3124, 104, 11, 8, 65 },
8344 { 4176, 3062, 96, 17, 8, 0, 0, 16, 0, 7, 0x49 },
8345 { 4192, 3062, 96, 17, 24, 0, 0, 16, 0, 0, 0x49 },
8346 { 4312, 2876, 22, 18, 0, 2 },
8347 { 4352, 2874, 62, 18, 0, 0 },
8348 { 4476, 2954, 90, 34, 0, 0 },
8349 { 4480, 3348, 12, 10, 36, 12, 0, 0, 0, 18, 0x49 },
8350 { 4480, 3366, 80, 50, 0, 0 },
8351 { 4496, 3366, 80, 50, 12, 0 },
8352 { 4768, 3516, 96, 16, 0, 0, 0, 16 },
8353 { 4832, 3204, 62, 26, 0, 0 },
8354 { 4832, 3228, 62, 51, 0, 0 },
8355 { 5108, 3349, 98, 13, 0, 0 },
8356 { 5120, 3318, 142, 45, 62, 0 },
8357 { 5280, 3528, 72, 52, 0, 0 },
8358 { 5344, 3516, 142, 51, 0, 0 },
8359 { 5344, 3584, 126,100, 0, 2 },
8360 { 5360, 3516, 158, 51, 0, 0 },
8361 { 5568, 3708, 72, 38, 0, 0 },
8362 { 5632, 3710, 96, 17, 0, 0, 0, 16, 0, 0, 0x49 },
8363 { 5712, 3774, 62, 20, 10, 2 },
8364 { 5792, 3804, 158, 51, 0, 0 },
8365 { 5920, 3950, 122, 80, 2, 0 },
8366 { 6096, 4056, 72, 34, 0, 0 },
8367 { 6288, 4056, 264, 34, 0, 0 },
8368 { 8896, 5920, 160, 64, 0, 0 },
8370 static const struct {
8374 { 0x168, "EOS 10D" }, { 0x001, "EOS-1D" },
8375 { 0x175, "EOS 20D" }, { 0x174, "EOS-1D Mark II" },
8376 { 0x234, "EOS 30D" }, { 0x232, "EOS-1D Mark II N" },
8377 { 0x190, "EOS 40D" }, { 0x169, "EOS-1D Mark III" },
8378 { 0x261, "EOS 50D" }, { 0x281, "EOS-1D Mark IV" },
8379 { 0x287, "EOS 60D" }, { 0x167, "EOS-1DS" },
8380 { 0x325, "EOS 70D" },
8381 { 0x350, "EOS 80D" }, { 0x328, "EOS-1D X Mark II" },
8382 { 0x170, "EOS 300D" }, { 0x188, "EOS-1Ds Mark II" },
8383 { 0x176, "EOS 450D" }, { 0x215, "EOS-1Ds Mark III" },
8384 { 0x189, "EOS 350D" }, { 0x324, "EOS-1D C" },
8385 { 0x236, "EOS 400D" }, { 0x269, "EOS-1D X" },
8386 { 0x252, "EOS 500D" }, { 0x213, "EOS 5D" },
8387 { 0x270, "EOS 550D" }, { 0x218, "EOS 5D Mark II" },
8388 { 0x286, "EOS 600D" }, { 0x285, "EOS 5D Mark III" },
8389 { 0x301, "EOS 650D" }, { 0x302, "EOS 6D" },
8390 { 0x326, "EOS 700D" }, { 0x250, "EOS 7D" },
8391 { 0x393, "EOS 750D" }, { 0x289, "EOS 7D Mark II" },
8392 { 0x347, "EOS 760D" },
8393 { 0x254, "EOS 1000D" },
8394 { 0x288, "EOS 1100D" },
8395 { 0x327, "EOS 1200D" }, { 0x382, "Canon EOS 5DS" },
8396 { 0x404, "EOS 1300D" }, { 0x401, "Canon EOS 5DS R" },
8397 { 0x346, "EOS 100D" },
8399 { 0x002, "DSC-R1" }, { 0x100, "DSLR-A100" },
8400 { 0x101, "DSLR-A900" }, { 0x102, "DSLR-A700" },
8401 { 0x103, "DSLR-A200" }, { 0x104, "DSLR-A350" },
8402 { 0x105, "DSLR-A300" }, { 0x108, "DSLR-A330" },
8403 { 0x109, "DSLR-A230" }, { 0x10a, "DSLR-A290" },
8404 { 0x10d, "DSLR-A850" }, { 0x111, "DSLR-A550" },
8405 { 0x112, "DSLR-A500" }, { 0x113, "DSLR-A450" },
8406 { 0x116, "NEX-5" }, { 0x117, "NEX-3" },
8407 { 0x118, "SLT-A33" }, { 0x119, "SLT-A55V" },
8408 { 0x11a, "DSLR-A560" }, { 0x11b, "DSLR-A580" },
8409 { 0x11c, "NEX-C3" }, { 0x11d, "SLT-A35" },
8410 { 0x11e, "SLT-A65V" }, { 0x11f, "SLT-A77V" },
8411 { 0x120, "NEX-5N" }, { 0x121, "NEX-7" },
8412 { 0x123, "SLT-A37" }, { 0x124, "SLT-A57" },
8413 { 0x125, "NEX-F3" }, { 0x126, "SLT-A99V" },
8414 { 0x127, "NEX-6" }, { 0x128, "NEX-5R" },
8415 { 0x129, "DSC-RX100" }, { 0x12a, "DSC-RX1" },
8416 { 0x12e, "ILCE-3000" }, { 0x12f, "SLT-A58" },
8417 { 0x131, "NEX-3N" }, { 0x132, "ILCE-7" },
8418 { 0x133, "NEX-5T" }, { 0x134, "DSC-RX100M2" },
8419 { 0x135, "DSC-RX10" }, { 0x136, "DSC-RX1R" },
8420 { 0x137, "ILCE-7R" }, { 0x138, "ILCE-6000" },
8421 { 0x139, "ILCE-5000" }, { 0x13d, "DSC-RX100M3" },
8422 { 0x13e, "ILCE-7S" }, { 0x13f, "ILCA-77M2" },
8423 { 0x153, "ILCE-5100" }, { 0x154, "ILCE-7M2" },
8424 { 0x155, "DSC-RX100M4" },{ 0x156, "DSC-RX10M2" },
8425 { 0x158, "DSC-RX1RM2" }, { 0x15a, "ILCE-QX1" },
8426 { 0x15b, "ILCE-7RM2" }, { 0x15e, "ILCE-7SM2" },
8427 { 0x161, "ILCA-68" }, { 0x165, "ILCE-6300" },
8429 static const struct {
8432 uchar lm, tm, rm, bm, lf, cf, max, flags;
8433 char make[10], model[20];
8436 { 786432,1024, 768, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-080C" },
8437 { 1447680,1392,1040, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-145C" },
8438 { 1920000,1600,1200, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-201C" },
8439 { 5067304,2588,1958, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-510C" },
8440 { 5067316,2588,1958, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-510C",12 },
8441 { 10134608,2588,1958, 0, 0, 0, 0, 9,0x94,0,0,"AVT","F-510C" },
8442 { 10134620,2588,1958, 0, 0, 0, 0, 9,0x94,0,0,"AVT","F-510C",12 },
8443 { 16157136,3272,2469, 0, 0, 0, 0, 9,0x94,0,0,"AVT","F-810C" },
8444 { 15980544,3264,2448, 0, 0, 0, 0, 8,0x61,0,1,"AgfaPhoto","DC-833m" },
8445 { 9631728,2532,1902, 0, 0, 0, 0,96,0x61,0,0,"Alcatel","5035D" },
8446 { 2868726,1384,1036, 0, 0, 0, 0,64,0x49,0,8,"Baumer","TXG14",1078 },
8447 { 5298000,2400,1766,12,12,44, 2,40,0x94,0,2,"Canon","PowerShot SD300" },
8448 { 6553440,2664,1968, 4, 4,44, 4,40,0x94,0,2,"Canon","PowerShot A460" },
8449 { 6573120,2672,1968,12, 8,44, 0,40,0x94,0,2,"Canon","PowerShot A610" },
8450 { 6653280,2672,1992,10, 6,42, 2,40,0x94,0,2,"Canon","PowerShot A530" },
8451 { 7710960,2888,2136,44, 8, 4, 0,40,0x94,0,2,"Canon","PowerShot S3 IS" },
8452 { 9219600,3152,2340,36,12, 4, 0,40,0x94,0,2,"Canon","PowerShot A620" },
8453 { 9243240,3152,2346,12, 7,44,13,40,0x49,0,2,"Canon","PowerShot A470" },
8454 { 10341600,3336,2480, 6, 5,32, 3,40,0x94,0,2,"Canon","PowerShot A720 IS" },
8455 { 10383120,3344,2484,12, 6,44, 6,40,0x94,0,2,"Canon","PowerShot A630" },
8456 { 12945240,3736,2772,12, 6,52, 6,40,0x94,0,2,"Canon","PowerShot A640" },
8457 { 15636240,4104,3048,48,12,24,12,40,0x94,0,2,"Canon","PowerShot A650" },
8458 { 15467760,3720,2772, 6,12,30, 0,40,0x94,0,2,"Canon","PowerShot SX110 IS" },
8459 { 15534576,3728,2778,12, 9,44, 9,40,0x94,0,2,"Canon","PowerShot SX120 IS" },
8460 { 18653760,4080,3048,24,12,24,12,40,0x94,0,2,"Canon","PowerShot SX20 IS" },
8461 { 19131120,4168,3060,92,16, 4, 1,40,0x94,0,2,"Canon","PowerShot SX220 HS" },
8462 { 21936096,4464,3276,25,10,73,12,40,0x16,0,2,"Canon","PowerShot SX30 IS" },
8463 { 24724224,4704,3504, 8,16,56, 8,40,0x94,0,2,"Canon","PowerShot A3300 IS" },
8464 { 30858240,5248,3920, 8,16,56,16,40,0x94,0,2,"Canon","IXUS 160" },
8465 { 1976352,1632,1211, 0, 2, 0, 1, 0,0x94,0,1,"Casio","QV-2000UX" },
8466 { 3217760,2080,1547, 0, 0,10, 1, 0,0x94,0,1,"Casio","QV-3*00EX" },
8467 { 6218368,2585,1924, 0, 0, 9, 0, 0,0x94,0,1,"Casio","QV-5700" },
8468 { 7816704,2867,2181, 0, 0,34,36, 0,0x16,0,1,"Casio","EX-Z60" },
8469 { 2937856,1621,1208, 0, 0, 1, 0, 0,0x94,7,13,"Casio","EX-S20" },
8470 { 4948608,2090,1578, 0, 0,32,34, 0,0x94,7,1,"Casio","EX-S100" },
8471 { 6054400,2346,1720, 2, 0,32, 0, 0,0x94,7,1,"Casio","QV-R41" },
8472 { 7426656,2568,1928, 0, 0, 0, 0, 0,0x94,0,1,"Casio","EX-P505" },
8473 { 7530816,2602,1929, 0, 0,22, 0, 0,0x94,7,1,"Casio","QV-R51" },
8474 { 7542528,2602,1932, 0, 0,32, 0, 0,0x94,7,1,"Casio","EX-Z50" },
8475 { 7562048,2602,1937, 0, 0,25, 0, 0,0x16,7,1,"Casio","EX-Z500" },
8476 { 7753344,2602,1986, 0, 0,32,26, 0,0x94,7,1,"Casio","EX-Z55" },
8477 { 9313536,2858,2172, 0, 0,14,30, 0,0x94,7,1,"Casio","EX-P600" },
8478 { 10834368,3114,2319, 0, 0,27, 0, 0,0x94,0,1,"Casio","EX-Z750" },
8479 { 10843712,3114,2321, 0, 0,25, 0, 0,0x94,0,1,"Casio","EX-Z75" },
8480 { 10979200,3114,2350, 0, 0,32,32, 0,0x94,7,1,"Casio","EX-P700" },
8481 { 12310144,3285,2498, 0, 0, 6,30, 0,0x94,0,1,"Casio","EX-Z850" },
8482 { 12489984,3328,2502, 0, 0,47,35, 0,0x94,0,1,"Casio","EX-Z8" },
8483 { 15499264,3754,2752, 0, 0,82, 0, 0,0x94,0,1,"Casio","EX-Z1050" },
8484 { 18702336,4096,3044, 0, 0,24, 0,80,0x94,7,1,"Casio","EX-ZR100" },
8485 { 7684000,2260,1700, 0, 0, 0, 0,13,0x94,0,1,"Casio","QV-4000" },
8486 { 787456,1024, 769, 0, 1, 0, 0, 0,0x49,0,0,"Creative","PC-CAM 600" },
8487 { 28829184,4384,3288, 0, 0, 0, 0,36,0x61,0,0,"DJI" },
8488 { 15151104,4608,3288, 0, 0, 0, 0, 0,0x94,0,0,"Matrix" },
8489 { 3840000,1600,1200, 0, 0, 0, 0,65,0x49,0,0,"Foculus","531C" },
8490 { 307200, 640, 480, 0, 0, 0, 0, 0,0x94,0,0,"Generic" },
8491 { 62464, 256, 244, 1, 1, 6, 1, 0,0x8d,0,0,"Kodak","DC20" },
8492 { 124928, 512, 244, 1, 1,10, 1, 0,0x8d,0,0,"Kodak","DC20" },
8493 { 1652736,1536,1076, 0,52, 0, 0, 0,0x61,0,0,"Kodak","DCS200" },
8494 { 4159302,2338,1779, 1,33, 1, 2, 0,0x94,0,0,"Kodak","C330" },
8495 { 4162462,2338,1779, 1,33, 1, 2, 0,0x94,0,0,"Kodak","C330",3160 },
8496 { 2247168,1232, 912, 0, 0,16, 0, 0,0x00,0,0,"Kodak","C330" },
8497 { 3370752,1232, 912, 0, 0,16, 0, 0,0x00,0,0,"Kodak","C330" },
8498 { 6163328,2864,2152, 0, 0, 0, 0, 0,0x94,0,0,"Kodak","C603" },
8499 { 6166488,2864,2152, 0, 0, 0, 0, 0,0x94,0,0,"Kodak","C603",3160 },
8500 { 460800, 640, 480, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","C603" },
8501 { 9116448,2848,2134, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","C603" },
8502 { 12241200,4040,3030, 2, 0, 0,13, 0,0x49,0,0,"Kodak","12MP" },
8503 { 12272756,4040,3030, 2, 0, 0,13, 0,0x49,0,0,"Kodak","12MP",31556 },
8504 { 18000000,4000,3000, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","12MP" },
8505 { 614400, 640, 480, 0, 3, 0, 0,64,0x94,0,0,"Kodak","KAI-0340" },
8506 { 15360000,3200,2400, 0, 0, 0, 0,96,0x16,0,0,"Lenovo","A820" },
8507 { 3884928,1608,1207, 0, 0, 0, 0,96,0x16,0,0,"Micron","2010",3212 },
8508 { 1138688,1534, 986, 0, 0, 0, 0, 0,0x61,0,0,"Minolta","RD175",513 },
8509 { 1581060,1305, 969, 0, 0,18, 6, 6,0x1e,4,1,"Nikon","E900" },
8510 { 2465792,1638,1204, 0, 0,22, 1, 6,0x4b,5,1,"Nikon","E950" },
8511 { 2940928,1616,1213, 0, 0, 0, 7,30,0x94,0,1,"Nikon","E2100" },
8512 { 4771840,2064,1541, 0, 0, 0, 1, 6,0xe1,0,1,"Nikon","E990" },
8513 { 4775936,2064,1542, 0, 0, 0, 0,30,0x94,0,1,"Nikon","E3700" },
8514 { 5865472,2288,1709, 0, 0, 0, 1, 6,0xb4,0,1,"Nikon","E4500" },
8515 { 5869568,2288,1710, 0, 0, 0, 0, 6,0x16,0,1,"Nikon","E4300" },
8516 { 7438336,2576,1925, 0, 0, 0, 1, 6,0xb4,0,1,"Nikon","E5000" },
8517 { 8998912,2832,2118, 0, 0, 0, 0,30,0x94,7,1,"Nikon","COOLPIX S6" },
8518 { 5939200,2304,1718, 0, 0, 0, 0,30,0x16,0,0,"Olympus","C770UZ" },
8519 { 3178560,2064,1540, 0, 0, 0, 0, 0,0x94,0,1,"Pentax","Optio S" },
8520 { 4841984,2090,1544, 0, 0,22, 0, 0,0x94,7,1,"Pentax","Optio S" },
8521 { 6114240,2346,1737, 0, 0,22, 0, 0,0x94,7,1,"Pentax","Optio S4" },
8522 { 10702848,3072,2322, 0, 0, 0,21,30,0x94,0,1,"Pentax","Optio 750Z" },
8523 { 4147200,1920,1080, 0, 0, 0, 0, 0,0x49,0,0,"Photron","BC2-HD" },
8524 { 4151666,1920,1080, 0, 0, 0, 0, 0,0x49,0,0,"Photron","BC2-HD",8 },
8525 { 13248000,2208,3000, 0, 0, 0, 0,13,0x61,0,0,"Pixelink","A782" },
8526 { 6291456,2048,1536, 0, 0, 0, 0,96,0x61,0,0,"RoverShot","3320AF" },
8527 { 311696, 644, 484, 0, 0, 0, 0, 0,0x16,0,8,"ST Micro","STV680 VGA" },
8528 { 16098048,3288,2448, 0, 0,24, 0, 9,0x94,0,1,"Samsung","S85" },
8529 { 16215552,3312,2448, 0, 0,48, 0, 9,0x94,0,1,"Samsung","S85" },
8530 { 20487168,3648,2808, 0, 0, 0, 0,13,0x94,5,1,"Samsung","WB550" },
8531 { 24000000,4000,3000, 0, 0, 0, 0,13,0x94,5,1,"Samsung","WB550" },
8532 { 12582980,3072,2048, 0, 0, 0, 0,33,0x61,0,0,"Sinar","",68 },
8533 { 33292868,4080,4080, 0, 0, 0, 0,33,0x61,0,0,"Sinar","",68 },
8534 { 44390468,4080,5440, 0, 0, 0, 0,33,0x61,0,0,"Sinar","",68 },
8535 { 1409024,1376,1024, 0, 0, 1, 0, 0,0x49,0,0,"Sony","XCD-SX910CR" },
8536 { 2818048,1376,1024, 0, 0, 1, 0,97,0x49,0,0,"Sony","XCD-SX910CR" },
8538 static const char *corp[] =
8539 { "AgfaPhoto", "Canon", "Casio", "Epson", "Fujifilm",
8540 "Mamiya", "Minolta", "Motorola", "Kodak", "Konica", "Leica",
8541 "Nikon", "Nokia", "Olympus", "Ricoh", "Pentax", "Phase One",
8542 "Samsung", "Sigma", "Sinar", "Sony" };
8544 int hlen, flen, fsize, zero_fsize=1, i, c;
8547 tiff_flip = flip = filters = UINT_MAX; /* unknown */
8548 raw_height = raw_width = fuji_width = fuji_layout = cr2_slice[0] = 0;
8549 maximum = height = width = top_margin = left_margin = 0;
8550 cdesc[0] = desc[0] = artist[0] = make[0] = model[0] = model2[0] = 0;
8551 iso_speed = shutter = aperture = focal_len = unique_id = 0;
8553 memset (tiff_ifd, 0, sizeof tiff_ifd);
8554 memset (gpsdata, 0, sizeof gpsdata);
8555 memset (cblack, 0, sizeof cblack);
8556 memset (white, 0, sizeof white);
8557 memset (mask, 0, sizeof mask);
8558 thumb_offset = thumb_length = thumb_width = thumb_height = 0;
8559 load_raw = thumb_load_raw = 0;
8560 write_thumb = &CLASS jpeg_thumb;
8561 data_offset = meta_offset = meta_length = tiff_bps = tiff_compress = 0;
8562 kodak_cbpp = zero_after_ff = dng_version = load_flags = 0;
8563 timestamp = shot_order = tiff_samples = black = is_foveon = 0;
8564 mix_green = profile_length = data_error = zero_is_bad = 0;
8565 pixel_aspect = is_raw = raw_color = 1;
8566 tile_width = tile_length = 0;
8567 for (i=0; i < 4; i++) {
8568 cam_mul[i] = i == 1;
8570 FORC3 cmatrix[c][i] = 0;
8571 FORC3 rgb_cam[c][i] = c == i;
8574 for (i=0; i < 0x10000; i++) curve[i] = i;
8578 fseek (ifp, 0, SEEK_SET);
8579 fread (head, 1, 32, ifp);
8580 fseek (ifp, 0, SEEK_END);
8581 flen = fsize = ftell(ifp);
8582 if ((cp = (char *) memmem (head, 32, "MMMM", 4)) ||
8583 (cp = (char *) memmem (head, 32, "IIII", 4))) {
8584 parse_phase_one (cp-head);
8585 if (cp-head && parse_tiff(0)) apply_tiff();
8586 } else if (order == 0x4949 || order == 0x4d4d) {
8587 if (!memcmp (head+6,"HEAPCCDR",8)) {
8589 parse_ciff (hlen, flen-hlen, 0);
8590 load_raw = &CLASS canon_load_raw;
8591 } else if (parse_tiff(0)) apply_tiff();
8592 } else if (!memcmp (head,"\xff\xd8\xff\xe1",4) &&
8593 !memcmp (head+6,"Exif",4)) {
8594 fseek (ifp, 4, SEEK_SET);
8595 data_offset = 4 + get2();
8596 fseek (ifp, data_offset, SEEK_SET);
8597 if (fgetc(ifp) != 0xff)
8600 } else if (!memcmp (head+25,"ARECOYK",7)) {
8601 strcpy (make, "Contax");
8602 strcpy (model,"N Digital");
8603 fseek (ifp, 33, SEEK_SET);
8605 fseek (ifp, 60, SEEK_SET);
8606 FORC4 cam_mul[c ^ (c >> 1)] = get4();
8607 } else if (!strcmp (head, "PXN")) {
8608 strcpy (make, "Logitech");
8609 strcpy (model,"Fotoman Pixtura");
8610 } else if (!strcmp (head, "qktk")) {
8611 strcpy (make, "Apple");
8612 strcpy (model,"QuickTake 100");
8613 load_raw = &CLASS quicktake_100_load_raw;
8614 } else if (!strcmp (head, "qktn")) {
8615 strcpy (make, "Apple");
8616 strcpy (model,"QuickTake 150");
8617 load_raw = &CLASS kodak_radc_load_raw;
8618 } else if (!memcmp (head,"FUJIFILM",8)) {
8619 fseek (ifp, 84, SEEK_SET);
8620 thumb_offset = get4();
8621 thumb_length = get4();
8622 fseek (ifp, 92, SEEK_SET);
8623 parse_fuji (get4());
8624 if (thumb_offset > 120) {
8625 fseek (ifp, 120, SEEK_SET);
8626 is_raw += (i = get4()) && 1;
8627 if (is_raw == 2 && shot_select)
8630 load_raw = &CLASS unpacked_load_raw;
8631 fseek (ifp, 100+28*(shot_select > 0), SEEK_SET);
8632 parse_tiff (data_offset = get4());
8633 parse_tiff (thumb_offset+12);
8635 } else if (!memcmp (head,"RIFF",4)) {
8636 fseek (ifp, 0, SEEK_SET);
8638 } else if (!memcmp (head+4,"ftypqt ",9)) {
8639 fseek (ifp, 0, SEEK_SET);
8642 } else if (!memcmp (head,"\0\001\0\001\0@",6)) {
8643 fseek (ifp, 6, SEEK_SET);
8644 fread (make, 1, 8, ifp);
8645 fread (model, 1, 8, ifp);
8646 fread (model2, 1, 16, ifp);
8647 data_offset = get2();
8650 raw_height = get2();
8651 load_raw = &CLASS nokia_load_raw;
8652 filters = 0x61616161;
8653 } else if (!memcmp (head,"NOKIARAW",8)) {
8654 strcpy (make, "NOKIA");
8656 fseek (ifp, 300, SEEK_SET);
8657 data_offset = get4();
8661 switch (tiff_bps = i*8 / (width * height)) {
8662 case 8: load_raw = &CLASS eight_bit_load_raw; break;
8663 case 10: load_raw = &CLASS nokia_load_raw;
8665 raw_height = height + (top_margin = i / (width * tiff_bps/8) - height);
8667 filters = 0x61616161;
8668 } else if (!memcmp (head,"ARRI",4)) {
8670 fseek (ifp, 20, SEEK_SET);
8673 strcpy (make, "ARRI");
8674 fseek (ifp, 668, SEEK_SET);
8675 fread (model, 1, 64, ifp);
8677 load_raw = &CLASS packed_load_raw;
8679 filters = 0x61616161;
8680 } else if (!memcmp (head,"XPDS",4)) {
8682 fseek (ifp, 0x800, SEEK_SET);
8683 fread (make, 1, 41, ifp);
8684 raw_height = get2();
8686 fseek (ifp, 56, SEEK_CUR);
8687 fread (model, 1, 30, ifp);
8688 data_offset = 0x10000;
8689 load_raw = &CLASS canon_rmf_load_raw;
8690 gamma_curve (0, 12.25, 1, 1023);
8691 } else if (!memcmp (head+4,"RED1",4)) {
8692 strcpy (make, "Red");
8693 strcpy (model,"One");
8695 load_raw = &CLASS redcine_load_raw;
8696 gamma_curve (1/2.4, 12.92, 1, 4095);
8697 filters = 0x49494949;
8698 } else if (!memcmp (head,"DSC-Image",9))
8700 else if (!memcmp (head,"PWAD",4))
8702 else if (!memcmp (head,"\0MRM",4))
8704 else if (!memcmp (head,"FOVb",4))
8706 else if (!memcmp (head,"CI",2))
8709 for (zero_fsize=i=0; i < sizeof table / sizeof *table; i++)
8710 if (fsize == table[i].fsize) {
8711 strcpy (make, table[i].make );
8712 strcpy (model, table[i].model);
8713 flip = table[i].flags >> 2;
8714 zero_is_bad = table[i].flags & 2;
8715 if (table[i].flags & 1)
8716 parse_external_jpeg();
8717 data_offset = table[i].offset;
8718 raw_width = table[i].rw;
8719 raw_height = table[i].rh;
8720 left_margin = table[i].lm;
8721 top_margin = table[i].tm;
8722 width = raw_width - left_margin - table[i].rm;
8723 height = raw_height - top_margin - table[i].bm;
8724 filters = 0x1010101 * table[i].cf;
8725 colors = 4 - !((filters & filters >> 1) & 0x5555);
8726 load_flags = table[i].lf;
8727 switch (tiff_bps = (fsize-data_offset)*8 / (raw_width*raw_height)) {
8729 load_raw = &CLASS minolta_rd175_load_raw; break;
8731 load_raw = &CLASS eight_bit_load_raw; break;
8734 load_raw = &CLASS packed_load_raw; break;
8736 order = 0x4949 | 0x404 * (load_flags & 1);
8737 tiff_bps -= load_flags >> 4;
8738 tiff_bps -= load_flags = load_flags >> 1 & 7;
8739 load_raw = &CLASS unpacked_load_raw;
8741 maximum = (1 << tiff_bps) - (1 << table[i].max);
8743 if (zero_fsize) fsize = 0;
8744 if (make[0] == 0) parse_smal (0, flen);
8747 if (!(strncmp(model,"ov",2) && strncmp(model,"RP_OV",5)) &&
8748 !fseek (ifp, -6404096, SEEK_END) &&
8749 fread (head, 1, 32, ifp) && !strcmp(head,"BRCMn")) {
8750 strcpy (make, "OmniVision");
8751 data_offset = ftell(ifp) + 0x8000-32;
8754 load_raw = &CLASS nokia_load_raw;
8755 filters = 0x16161616;
8759 for (i=0; i < sizeof corp / sizeof *corp; i++)
8760 if (strcasestr (make, corp[i])) /* Simplify company names */
8761 strcpy (make, corp[i]);
8762 if ((!strcmp(make,"Kodak") || !strcmp(make,"Leica")) &&
8763 ((cp = strcasestr(model," DIGITAL CAMERA")) ||
8764 (cp = strstr(model,"FILE VERSION"))))
8766 if (!strncasecmp(model,"PENTAX",6))
8767 strcpy (make, "Pentax");
8768 cp = make + strlen(make); /* Remove trailing spaces */
8769 while (*--cp == ' ') *cp = 0;
8770 cp = model + strlen(model);
8771 while (*--cp == ' ') *cp = 0;
8772 i = strlen(make); /* Remove make from model */
8773 if (!strncasecmp (model, make, i) && model[i++] == ' ')
8774 memmove (model, model+i, 64-i);
8775 if (!strncmp (model,"FinePix ",8))
8776 strcpy (model, model+8);
8777 if (!strncmp (model,"Digital Camera ",15))
8778 strcpy (model, model+15);
8779 desc[511] = artist[63] = make[63] = model[63] = model2[63] = 0;
8780 if (!is_raw) goto notraw;
8782 if (!height) height = raw_height;
8783 if (!width) width = raw_width;
8784 if (height == 2624 && width == 3936) /* Pentax K10D and Samsung GX10 */
8785 { height = 2616; width = 3896; }
8786 if (height == 3136 && width == 4864) /* Pentax K20D and Samsung GX20 */
8787 { height = 3124; width = 4688; filters = 0x16161616; }
8788 if (width == 4352 && (!strcmp(model,"K-r") || !strcmp(model,"K-x")))
8789 { width = 4309; filters = 0x16161616; }
8790 if (width >= 4960 && !strncmp(model,"K-5",3))
8791 { left_margin = 10; width = 4950; filters = 0x16161616; }
8792 if (width == 4736 && !strcmp(model,"K-7"))
8793 { height = 3122; width = 4684; filters = 0x16161616; top_margin = 2; }
8794 if (width == 6080 && !strcmp(model,"K-3"))
8795 { left_margin = 4; width = 6040; }
8796 if (width == 7424 && !strcmp(model,"645D"))
8797 { height = 5502; width = 7328; filters = 0x61616161; top_margin = 29;
8799 if (height == 3014 && width == 4096) /* Ricoh GX200 */
8802 if (filters == UINT_MAX) filters = 0;
8803 if (filters) is_raw *= tiff_samples;
8804 else colors = tiff_samples;
8805 switch (tiff_compress) {
8807 case 1: load_raw = &CLASS packed_dng_load_raw; break;
8808 case 7: load_raw = &CLASS lossless_dng_load_raw; break;
8809 case 34892: load_raw = &CLASS lossy_dng_load_raw; break;
8810 default: load_raw = 0;
8814 if (!strcmp(make,"Canon") && !fsize && tiff_bps != 15) {
8816 load_raw = &CLASS lossless_jpeg_load_raw;
8817 for (i=0; i < sizeof canon / sizeof *canon; i++)
8818 if (raw_width == canon[i][0] && raw_height == canon[i][1]) {
8819 width = raw_width - (left_margin = canon[i][2]);
8820 height = raw_height - (top_margin = canon[i][3]);
8821 width -= canon[i][4];
8822 height -= canon[i][5];
8823 mask[0][1] = canon[i][6];
8824 mask[0][3] = -canon[i][7];
8825 mask[1][1] = canon[i][8];
8826 mask[1][3] = -canon[i][9];
8827 if (canon[i][10]) filters = canon[i][10] * 0x01010101;
8829 if ((unique_id | 0x20000) == 0x2720000) {
8834 for (i=0; i < sizeof unique / sizeof *unique; i++)
8835 if (unique_id == 0x80000000 + unique[i].id) {
8836 adobe_coeff ("Canon", unique[i].model);
8837 if (model[4] == 'K' && strlen(model) == 8)
8838 strcpy (model, unique[i].model);
8840 for (i=0; i < sizeof sonique / sizeof *sonique; i++)
8841 if (unique_id == sonique[i].id)
8842 strcpy (model, sonique[i].model);
8843 if (!strcmp(make,"Nikon")) {
8845 load_raw = &CLASS packed_load_raw;
8846 if (model[0] == 'E')
8847 load_flags |= !data_offset << 2 | 2;
8850 /* Set parameters based on camera name (for non-DNG files). */
8852 if (!strcmp(model,"KAI-0340")
8853 && find_green (16, 16, 3840, 5120) < 25) {
8855 top_margin = filters = 0;
8856 strcpy (model,"C603");
8858 if (!strcmp(make,"Sony") && raw_width > 3888)
8859 black = 128 << (tiff_bps - 12);
8861 if (height*2 < width) pixel_aspect = 0.5;
8862 if (height > width) pixel_aspect = 2;
8865 } else if (!strcmp(make,"Canon") && tiff_bps == 15) {
8867 case 3344: width -= 66;
8868 case 3872: width -= 6;
8870 if (height > width) {
8872 SWAP(raw_height,raw_width);
8874 if (width == 7200 && height == 3888) {
8875 raw_width = width = 6480;
8876 raw_height = height = 4320;
8879 tiff_samples = colors = 3;
8880 load_raw = &CLASS canon_sraw_load_raw;
8881 } else if (!strcmp(model,"PowerShot 600")) {
8886 filters = 0xe1e4e1e4;
8887 load_raw = &CLASS canon_600_load_raw;
8888 } else if (!strcmp(model,"PowerShot A5") ||
8889 !strcmp(model,"PowerShot A5 Zoom")) {
8893 pixel_aspect = 256/235.0;
8894 filters = 0x1e4e1e4e;
8896 } else if (!strcmp(model,"PowerShot A50")) {
8900 filters = 0x1b4e4b1e;
8902 } else if (!strcmp(model,"PowerShot Pro70")) {
8905 filters = 0x1e4b4e1b;
8909 load_raw = &CLASS packed_load_raw;
8911 } else if (!strcmp(model,"PowerShot Pro90 IS") ||
8912 !strcmp(model,"PowerShot G1")) {
8914 filters = 0xb4b4b4b4;
8915 } else if (!strcmp(model,"PowerShot A610")) {
8916 if (canon_s2is()) strcpy (model+10, "S2 IS");
8917 } else if (!strcmp(model,"PowerShot SX220 HS")) {
8919 } else if (!strcmp(model,"EOS D2000C")) {
8920 filters = 0x61616161;
8922 } else if (!strcmp(model,"D1")) {
8923 cam_mul[0] *= 256/527.0;
8924 cam_mul[2] *= 256/317.0;
8925 } else if (!strcmp(model,"D1X")) {
8928 } else if (!strcmp(model,"D40X") ||
8929 !strcmp(model,"D60") ||
8930 !strcmp(model,"D80") ||
8931 !strcmp(model,"D3000")) {
8934 } else if (!strcmp(model,"D3") ||
8935 !strcmp(model,"D3S") ||
8936 !strcmp(model,"D700")) {
8939 } else if (!strcmp(model,"D3100")) {
8942 } else if (!strcmp(model,"D5000") ||
8943 !strcmp(model,"D90")) {
8945 } else if (!strcmp(model,"D5100") ||
8946 !strcmp(model,"D7000") ||
8947 !strcmp(model,"COOLPIX A")) {
8949 } else if (!strcmp(model,"D3200") ||
8950 !strncmp(model,"D6",2) ||
8951 !strncmp(model,"D800",4)) {
8953 } else if (!strcmp(model,"D4") ||
8954 !strcmp(model,"Df")) {
8957 } else if (!strncmp(model,"D40",3) ||
8958 !strncmp(model,"D50",3) ||
8959 !strncmp(model,"D70",3)) {
8961 } else if (!strcmp(model,"D100")) {
8963 raw_width = (width += 3) + 3;
8964 } else if (!strcmp(model,"D200")) {
8967 filters = 0x94949494;
8968 } else if (!strncmp(model,"D2H",3)) {
8971 } else if (!strncmp(model,"D2X",3)) {
8972 if (width == 3264) width -= 32;
8974 } else if (!strncmp(model,"D300",4)) {
8976 } else if (!strncmp(model,"COOLPIX P",9) && raw_width != 4032) {
8978 filters = 0x94949494;
8979 if (model[9] == '7' && iso_speed >= 400)
8981 } else if (!strncmp(model,"1 ",2)) {
8983 } else if (fsize == 1581060) {
8985 pre_mul[0] = 1.2085;
8986 pre_mul[1] = 1.0943;
8987 pre_mul[3] = 1.1103;
8988 } else if (fsize == 3178560) {
8991 } else if (fsize == 4771840) {
8992 if (!timestamp && nikon_e995())
8993 strcpy (model, "E995");
8994 if (strcmp(model,"E995")) {
8995 filters = 0xb4b4b4b4;
9001 } else if (fsize == 2940928) {
9002 if (!timestamp && !nikon_e2100())
9003 strcpy (model,"E2500");
9004 if (!strcmp(model,"E2500")) {
9008 filters = 0x4b4b4b4b;
9010 } else if (fsize == 4775936) {
9011 if (!timestamp) nikon_3700();
9012 if (model[0] == 'E' && atoi(model+1) < 3700)
9013 filters = 0x49494949;
9014 if (!strcmp(model,"Optio 33WR")) {
9016 filters = 0x16161616;
9018 if (make[0] == 'O') {
9019 i = find_green (12, 32, 1188864, 3576832);
9020 c = find_green (12, 32, 2383920, 2387016);
9021 if (abs(i) < abs(c)) {
9025 if (i < 0) filters = 0x61616161;
9027 } else if (fsize == 5869568) {
9028 if (!timestamp && minolta_z2()) {
9029 strcpy (make, "Minolta");
9030 strcpy (model,"DiMAGE Z2");
9032 load_flags = 6 + 24*(make[0] == 'M');
9033 } else if (fsize == 6291456) {
9034 fseek (ifp, 0x300000, SEEK_SET);
9035 if ((order = guess_byte_order(0x10000)) == 0x4d4d) {
9036 height -= (top_margin = 16);
9037 width -= (left_margin = 28);
9039 strcpy (make, "ISG");
9042 } else if (!strcmp(make,"Fujifilm")) {
9043 if (!strcmp(model+7,"S2Pro")) {
9044 strcpy (model,"S2Pro");
9048 } else if (load_raw != &CLASS packed_load_raw)
9049 maximum = (is_raw == 2 && shot_select) ? 0x2f00 : 0x3e00;
9050 top_margin = (raw_height - height) >> 2 << 1;
9051 left_margin = (raw_width - width ) >> 2 << 1;
9052 if (width == 2848 || width == 3664) filters = 0x16161616;
9053 if (width == 4032 || width == 4952 || width == 6032) left_margin = 0;
9054 if (width == 3328 && (width -= 66)) left_margin = 34;
9055 if (width == 4936) left_margin = 4;
9056 if (!strcmp(model,"HS50EXR") ||
9057 !strcmp(model,"F900EXR")) {
9060 filters = 0x16161616;
9062 if (fuji_layout) raw_width *= is_raw;
9064 FORC(36) ((char *)xtrans)[c] =
9065 xtrans_abs[(c/6+top_margin) % 6][(c+left_margin) % 6];
9066 } else if (!strcmp(model,"KD-400Z")) {
9071 } else if (!strcmp(model,"KD-510Z")) {
9073 } else if (!strcasecmp(make,"Minolta")) {
9074 if (!load_raw && (maximum = 0xfff))
9075 load_raw = &CLASS unpacked_load_raw;
9076 if (!strncmp(model,"DiMAGE A",8)) {
9077 if (!strcmp(model,"DiMAGE A200"))
9078 filters = 0x49494949;
9080 load_raw = &CLASS packed_load_raw;
9081 } else if (!strncmp(model,"ALPHA",5) ||
9082 !strncmp(model,"DYNAX",5) ||
9083 !strncmp(model,"MAXXUM",6)) {
9084 sprintf (model+20, "DYNAX %-10s", model+6+(model[0]=='M'));
9085 adobe_coeff (make, model+20);
9086 load_raw = &CLASS packed_load_raw;
9087 } else if (!strncmp(model,"DiMAGE G",8)) {
9088 if (model[8] == '4') {
9091 } else if (model[8] == '5') {
9096 } else if (model[8] == '6') {
9101 filters = 0x61616161;
9103 load_raw = &CLASS unpacked_load_raw;
9107 } else if (!strcmp(model,"*ist D")) {
9108 load_raw = &CLASS unpacked_load_raw;
9110 } else if (!strcmp(model,"*ist DS")) {
9112 } else if (!strcmp(make,"Samsung") && raw_width == 4704) {
9113 height -= top_margin = 8;
9114 width -= 2 * (left_margin = 8);
9116 } else if (!strcmp(make,"Samsung") && raw_height == 3714) {
9117 height -= top_margin = 18;
9118 left_margin = raw_width - (width = 5536);
9119 if (raw_width != 5600)
9120 left_margin = top_margin = 0;
9121 filters = 0x61616161;
9123 } else if (!strcmp(make,"Samsung") && raw_width == 5632) {
9127 width = 5574 - (left_margin = 32 + tiff_bps);
9128 if (tiff_bps == 12) load_flags = 80;
9129 } else if (!strcmp(make,"Samsung") && raw_width == 5664) {
9130 height -= top_margin = 17;
9133 filters = 0x49494949;
9134 } else if (!strcmp(make,"Samsung") && raw_width == 6496) {
9135 filters = 0x61616161;
9136 black = 1 << (tiff_bps - 7);
9137 } else if (!strcmp(model,"EX1")) {
9141 if ((width -= 6) > 3682) {
9146 } else if (!strcmp(model,"WB2000")) {
9150 if ((width -= 10) > 3718) {
9155 } else if (strstr(model,"WB550")) {
9156 strcpy (model, "WB550");
9157 } else if (!strcmp(model,"EX2F")) {
9162 filters = 0x49494949;
9163 load_raw = &CLASS unpacked_load_raw;
9164 } else if (!strcmp(model,"STV680 VGA")) {
9166 } else if (!strcmp(model,"N95")) {
9167 height = raw_height - (top_margin = 2);
9168 } else if (!strcmp(model,"640x480")) {
9169 gamma_curve (0.45, 4.5, 1, 255);
9170 } else if (!strcmp(make,"Hasselblad")) {
9171 if (load_raw == &CLASS lossless_jpeg_load_raw)
9172 load_raw = &CLASS hasselblad_load_raw;
9173 if (raw_width == 7262) {
9178 filters = 0x61616161;
9179 } else if (raw_width == 7410 || raw_width == 8282) {
9184 filters = 0x61616161;
9185 } else if (raw_width == 9044) {
9190 black += load_flags = 256;
9192 } else if (raw_width == 4090) {
9193 strcpy (model, "V96C");
9194 height -= (top_margin = 6);
9195 width -= (left_margin = 3) + 7;
9196 filters = 0x61616161;
9198 if (tiff_samples > 1) {
9199 is_raw = tiff_samples+1;
9200 if (!shot_select && !half_size) filters = 0;
9202 } else if (!strcmp(make,"Sinar")) {
9203 if (!load_raw) load_raw = &CLASS unpacked_load_raw;
9204 if (is_raw > 1 && !shot_select && !half_size) filters = 0;
9206 } else if (!strcmp(make,"Leaf")) {
9208 fseek (ifp, data_offset, SEEK_SET);
9209 if (ljpeg_start (&jh, 1) && jh.bits == 15)
9211 if (tiff_samples > 1) filters = 0;
9212 if (tiff_samples > 1 || tile_length < raw_height) {
9213 load_raw = &CLASS leaf_hdr_load_raw;
9214 raw_width = tile_width;
9216 if ((width | height) == 2048) {
9217 if (tiff_samples == 1) {
9219 strcpy (cdesc, "RBTG");
9220 strcpy (model, "CatchLight");
9221 top_margin = 8; left_margin = 18; height = 2032; width = 2016;
9223 strcpy (model, "DCB2");
9224 top_margin = 10; left_margin = 16; height = 2028; width = 2022;
9226 } else if (width+height == 3144+2060) {
9227 if (!model[0]) strcpy (model, "Cantare");
9228 if (width > height) {
9229 top_margin = 6; left_margin = 32; height = 2048; width = 3072;
9230 filters = 0x61616161;
9232 left_margin = 6; top_margin = 32; width = 2048; height = 3072;
9233 filters = 0x16161616;
9235 if (!cam_mul[0] || model[0] == 'V') filters = 0;
9236 else is_raw = tiff_samples;
9237 } else if (width == 2116) {
9238 strcpy (model, "Valeo 6");
9239 height -= 2 * (top_margin = 30);
9240 width -= 2 * (left_margin = 55);
9241 filters = 0x49494949;
9242 } else if (width == 3171) {
9243 strcpy (model, "Valeo 6");
9244 height -= 2 * (top_margin = 24);
9245 width -= 2 * (left_margin = 24);
9246 filters = 0x16161616;
9248 } else if (!strcmp(make,"Leica") || !strcmp(make,"Panasonic")) {
9249 if ((flen - data_offset) / (raw_width*8/7) == raw_height)
9250 load_raw = &CLASS panasonic_load_raw;
9252 load_raw = &CLASS unpacked_load_raw;
9256 if ((height += 12) > raw_height) height = raw_height;
9257 for (i=0; i < sizeof pana / sizeof *pana; i++)
9258 if (raw_width == pana[i][0] && raw_height == pana[i][1]) {
9259 left_margin = pana[i][2];
9260 top_margin = pana[i][3];
9261 width += pana[i][4];
9262 height += pana[i][5];
9264 filters = 0x01010101 * (uchar) "\x94\x61\x49\x16"
9265 [((filters-1) ^ (left_margin & 1) ^ (top_margin << 1)) & 3];
9266 } else if (!strcmp(model,"C770UZ")) {
9269 filters = 0x16161616;
9270 load_raw = &CLASS packed_load_raw;
9272 } else if (!strcmp(make,"Olympus")) {
9273 height += height & 1;
9274 if (exif_cfa) filters = exif_cfa;
9275 if (width == 4100) width -= 4;
9276 if (width == 4080) width -= 24;
9277 if (width == 9280) { width -= 6; height -= 6; }
9278 if (load_raw == &CLASS unpacked_load_raw)
9281 if (!strcmp(model,"E-300") ||
9282 !strcmp(model,"E-500")) {
9284 if (load_raw == &CLASS unpacked_load_raw) {
9286 memset (cblack, 0, sizeof cblack);
9288 } else if (!strcmp(model,"E-330")) {
9290 if (load_raw == &CLASS unpacked_load_raw)
9292 } else if (!strcmp(model,"SP550UZ")) {
9293 thumb_length = flen - (thumb_offset = 0xa39800);
9296 } else if (!strcmp(model,"TG-4")) {
9299 } else if (!strcmp(model,"N Digital")) {
9302 filters = 0x61616161;
9303 data_offset = 0x1a00;
9304 load_raw = &CLASS packed_load_raw;
9305 } else if (!strcmp(model,"DSC-F828")) {
9309 data_offset = 862144;
9310 load_raw = &CLASS sony_load_raw;
9311 filters = 0x9c9c9c9c;
9313 strcpy (cdesc, "RGBE");
9314 } else if (!strcmp(model,"DSC-V3")) {
9318 data_offset = 787392;
9319 load_raw = &CLASS sony_load_raw;
9320 } else if (!strcmp(make,"Sony") && raw_width == 3984) {
9323 } else if (!strcmp(make,"Sony") && raw_width == 4288) {
9325 } else if (!strcmp(make,"Sony") && raw_width == 4600) {
9326 if (!strcmp(model,"DSLR-A350"))
9329 } else if (!strcmp(make,"Sony") && raw_width == 4928) {
9330 if (height < 3280) width -= 8;
9331 } else if (!strcmp(make,"Sony") && raw_width == 5504) {
9332 width -= height > 3664 ? 8 : 32;
9333 if (!strncmp(model,"DSC",3))
9334 black = 200 << (tiff_bps - 12);
9335 } else if (!strcmp(make,"Sony") && raw_width == 6048) {
9337 if (strstr(model,"RX1") || strstr(model,"A99"))
9339 } else if (!strcmp(make,"Sony") && raw_width == 7392) {
9341 } else if (!strcmp(make,"Sony") && raw_width == 8000) {
9343 if (!strncmp(model,"DSC",3)) {
9345 load_raw = &CLASS unpacked_load_raw;
9348 } else if (!strcmp(model,"DSLR-A100")) {
9349 if (width == 3880) {
9351 width = ++raw_width;
9358 filters = 0x61616161;
9359 } else if (!strcmp(model,"PIXL")) {
9360 height -= top_margin = 4;
9361 width -= left_margin = 32;
9362 gamma_curve (0, 7, 1, 255);
9363 } else if (!strcmp(model,"C603") || !strcmp(model,"C330")
9364 || !strcmp(model,"12MP")) {
9366 if (filters && data_offset) {
9367 fseek (ifp, data_offset < 4096 ? 168 : 5252, SEEK_SET);
9368 read_shorts (curve, 256);
9369 } else gamma_curve (0, 3.875, 1, 255);
9370 load_raw = filters ? &CLASS eight_bit_load_raw :
9371 strcmp(model,"C330") ? &CLASS kodak_c603_load_raw :
9372 &CLASS kodak_c330_load_raw;
9373 load_flags = tiff_bps > 16;
9375 } else if (!strncasecmp(model,"EasyShare",9)) {
9376 data_offset = data_offset < 0x15000 ? 0x15000 : 0x17000;
9377 load_raw = &CLASS packed_load_raw;
9378 } else if (!strcasecmp(make,"Kodak")) {
9379 if (filters == UINT_MAX) filters = 0x61616161;
9380 if (!strncmp(model,"NC2000",6) ||
9381 !strncmp(model,"EOSDCS",6) ||
9382 !strncmp(model,"DCS4",4)) {
9385 if (model[6] == ' ') model[6] = 0;
9386 if (!strcmp(model,"DCS460A")) goto bw;
9387 } else if (!strcmp(model,"DCS660M")) {
9390 } else if (!strcmp(model,"DCS760M")) {
9394 if (!strcmp(model+4,"20X"))
9395 strcpy (cdesc, "MYCY");
9396 if (strstr(model,"DC25")) {
9397 strcpy (model, "DC25");
9398 data_offset = 15424;
9400 if (!strncmp(model,"DC2",3)) {
9401 raw_height = 2 + (height = 242);
9402 if (flen < 100000) {
9403 raw_width = 256; width = 249;
9404 pixel_aspect = (4.0*height) / (3.0*width);
9406 raw_width = 512; width = 501;
9407 pixel_aspect = (493.0*height) / (373.0*width);
9409 top_margin = left_margin = 1;
9411 filters = 0x8d8d8d8d;
9416 load_raw = &CLASS eight_bit_load_raw;
9417 } else if (!strcmp(model,"40")) {
9418 strcpy (model, "DC40");
9422 load_raw = &CLASS kodak_radc_load_raw;
9424 } else if (strstr(model,"DC50")) {
9425 strcpy (model, "DC50");
9428 data_offset = 19712;
9429 load_raw = &CLASS kodak_radc_load_raw;
9430 } else if (strstr(model,"DC120")) {
9431 strcpy (model, "DC120");
9434 pixel_aspect = height/0.75/width;
9435 load_raw = tiff_compress == 7 ?
9436 &CLASS kodak_jpeg_load_raw : &CLASS kodak_dc120_load_raw;
9437 } else if (!strcmp(model,"DCS200")) {
9440 thumb_offset = 6144;
9442 write_thumb = &CLASS layer_thumb;
9445 } else if (!strcmp(model,"Fotoman Pixtura")) {
9449 load_raw = &CLASS kodak_radc_load_raw;
9450 filters = 0x61616161;
9452 } else if (!strncmp(model,"QuickTake",9)) {
9453 if (head[5]) strcpy (model+10, "200");
9454 fseek (ifp, 544, SEEK_SET);
9457 data_offset = (get4(),get2()) == 30 ? 738:736;
9458 if (height > width) {
9460 fseek (ifp, data_offset-6, SEEK_SET);
9461 flip = ~get2() & 3 ? 5:6;
9463 filters = 0x61616161;
9464 } else if (!strcmp(make,"Rollei") && !load_raw) {
9465 switch (raw_width) {
9478 filters = 0x16161616;
9479 load_raw = &CLASS rollei_load_raw;
9482 sprintf (model, "%dx%d", width, height);
9483 if (filters == UINT_MAX) filters = 0x94949494;
9484 if (thumb_offset && !thumb_height) {
9485 fseek (ifp, thumb_offset, SEEK_SET);
9486 if (ljpeg_start (&jh, 1)) {
9487 thumb_width = jh.wide;
9488 thumb_height = jh.high;
9492 if ((use_camera_matrix & (use_camera_wb || dng_version))
9493 && cmatrix[0][0] > 0.125) {
9494 memcpy (rgb_cam, cmatrix, sizeof cmatrix);
9497 if (raw_color) adobe_coeff (make, model);
9498 if (load_raw == &CLASS kodak_radc_load_raw)
9499 if (raw_color) adobe_coeff ("Apple","Quicktake");
9501 fuji_width = width >> !fuji_layout;
9502 filters = fuji_width & 1 ? 0x94949494 : 0x49494949;
9503 width = (height >> fuji_layout) + fuji_width;
9507 if (raw_height < height) raw_height = height;
9508 if (raw_width < width ) raw_width = width;
9510 if (!tiff_bps) tiff_bps = 12;
9511 if (!maximum) maximum = (1 << tiff_bps) - 1;
9512 if (!load_raw || height < 22 || width < 22 ||
9513 tiff_bps > 16 || tiff_samples > 6 || colors > 4)
9516 if (load_raw == &CLASS redcine_load_raw) {
9517 fprintf (stderr,_("%s: You must link dcraw with %s!!\n"),
9518 ifname, "libjasper");
9523 if (load_raw == &CLASS kodak_jpeg_load_raw ||
9524 load_raw == &CLASS lossy_dng_load_raw) {
9525 fprintf (stderr,_("%s: You must link dcraw with %s!!\n"),
9531 strcpy (cdesc, colors == 3 ? "RGBG":"GMCY");
9532 if (!raw_height) raw_height = height;
9533 if (!raw_width ) raw_width = width;
9534 if (filters > 999 && colors == 3)
9535 filters |= ((filters >> 2 & 0x22222222) |
9536 (filters << 2 & 0x88888888)) & filters << 1;
9538 if (flip == UINT_MAX) flip = tiff_flip;
9539 if (flip == UINT_MAX) flip = 0;
9542 { unsigned flp = flip;
9543 switch ((flp+3600) % 360) {
9544 case 270: flp = 5; break;
9545 case 180: flp = 3; break;
9549 sprintf(dcraw_info, "%d %d", height, width);
9551 sprintf(dcraw_info, "%d %d", width, height); }
9555 void CLASS apply_profile (const char *input, const char *output)
9558 cmsHPROFILE hInProfile=0, hOutProfile=0;
9559 cmsHTRANSFORM hTransform;
9563 if (strcmp (input, "embed"))
9564 hInProfile = cmsOpenProfileFromFile (input, "r");
9565 else if (profile_length) {
9566 prof = (char *) malloc (profile_length);
9567 merror (prof, "apply_profile()");
9568 fseek (ifp, profile_offset, SEEK_SET);
9569 fread (prof, 1, profile_length, ifp);
9570 hInProfile = cmsOpenProfileFromMem (prof, profile_length);
9573 fprintf (stderr,_("%s has no embedded profile.\n"), ifname);
9574 if (!hInProfile) return;
9576 hOutProfile = cmsCreate_sRGBProfile();
9577 else if ((fp = fopen (output, "rb"))) {
9578 fread (&size, 4, 1, fp);
9579 fseek (fp, 0, SEEK_SET);
9580 oprof = (unsigned *) malloc (size = ntohl(size));
9581 merror (oprof, "apply_profile()");
9582 fread (oprof, 1, size, fp);
9584 if (!(hOutProfile = cmsOpenProfileFromMem (oprof, size))) {
9589 fprintf (stderr,_("Cannot open file %s!\n"), output);
9590 if (!hOutProfile) goto quit;
9592 fprintf (stderr,_("Applying color profile...\n"));
9593 hTransform = cmsCreateTransform (hInProfile, TYPE_RGBA_16,
9594 hOutProfile, TYPE_RGBA_16, INTENT_PERCEPTUAL, 0);
9595 cmsDoTransform (hTransform, image, image, width*height);
9596 raw_color = 1; /* Don't use rgb_cam with a profile */
9597 cmsDeleteTransform (hTransform);
9598 cmsCloseProfile (hOutProfile);
9600 cmsCloseProfile (hInProfile);
9604 void CLASS convert_to_rgb()
9606 int row, col, c, i, j, k;
9608 float out[3], out_cam[3][4];
9609 double num, inverse[3][3];
9610 static const double xyzd50_srgb[3][3] =
9611 { { 0.436083, 0.385083, 0.143055 },
9612 { 0.222507, 0.716888, 0.060608 },
9613 { 0.013930, 0.097097, 0.714022 } };
9614 static const double rgb_rgb[3][3] =
9615 { { 1,0,0 }, { 0,1,0 }, { 0,0,1 } };
9616 static const double adobe_rgb[3][3] =
9617 { { 0.715146, 0.284856, 0.000000 },
9618 { 0.000000, 1.000000, 0.000000 },
9619 { 0.000000, 0.041166, 0.958839 } };
9620 static const double wide_rgb[3][3] =
9621 { { 0.593087, 0.404710, 0.002206 },
9622 { 0.095413, 0.843149, 0.061439 },
9623 { 0.011621, 0.069091, 0.919288 } };
9624 static const double prophoto_rgb[3][3] =
9625 { { 0.529317, 0.330092, 0.140588 },
9626 { 0.098368, 0.873465, 0.028169 },
9627 { 0.016879, 0.117663, 0.865457 } };
9628 static const double aces_rgb[3][3] =
9629 { { 0.432996, 0.375380, 0.189317 },
9630 { 0.089427, 0.816523, 0.102989 },
9631 { 0.019165, 0.118150, 0.941914 } };
9632 static const double (*out_rgb[])[3] =
9633 { rgb_rgb, adobe_rgb, wide_rgb, prophoto_rgb, xyz_rgb, aces_rgb };
9634 static const char *name[] =
9635 { "sRGB", "Adobe RGB (1998)", "WideGamut D65", "ProPhoto D65", "XYZ", "ACES" };
9636 static const unsigned phead[] =
9637 { 1024, 0, 0x2100000, 0x6d6e7472, 0x52474220, 0x58595a20, 0, 0, 0,
9638 0x61637370, 0, 0, 0x6e6f6e65, 0, 0, 0, 0, 0xf6d6, 0x10000, 0xd32d };
9640 { 10, 0x63707274, 0, 36, /* cprt */
9641 0x64657363, 0, 40, /* desc */
9642 0x77747074, 0, 20, /* wtpt */
9643 0x626b7074, 0, 20, /* bkpt */
9644 0x72545243, 0, 14, /* rTRC */
9645 0x67545243, 0, 14, /* gTRC */
9646 0x62545243, 0, 14, /* bTRC */
9647 0x7258595a, 0, 20, /* rXYZ */
9648 0x6758595a, 0, 20, /* gXYZ */
9649 0x6258595a, 0, 20 }; /* bXYZ */
9650 static const unsigned pwhite[] = { 0xf351, 0x10000, 0x116cc };
9651 unsigned pcurve[] = { 0x63757276, 0, 1, 0x1000000 };
9653 gamma_curve (gamm[0], gamm[1], 0, 0);
9654 memcpy (out_cam, rgb_cam, sizeof out_cam);
9655 raw_color |= colors == 1 || document_mode ||
9656 output_color < 1 || output_color > 6;
9658 oprof = (unsigned *) calloc (phead[0], 1);
9659 merror (oprof, "convert_to_rgb()");
9660 memcpy (oprof, phead, sizeof phead);
9661 if (output_color == 5) oprof[4] = oprof[5];
9662 oprof[0] = 132 + 12*pbody[0];
9663 for (i=0; i < pbody[0]; i++) {
9664 oprof[oprof[0]/4] = i ? (i > 1 ? 0x58595a20 : 0x64657363) : 0x74657874;
9665 pbody[i*3+2] = oprof[0];
9666 oprof[0] += (pbody[i*3+3] + 3) & -4;
9668 memcpy (oprof+32, pbody, sizeof pbody);
9669 oprof[pbody[5]/4+2] = strlen(name[output_color-1]) + 1;
9670 memcpy ((char *)oprof+pbody[8]+8, pwhite, sizeof pwhite);
9671 pcurve[3] = (short)(256/gamm[5]+0.5) << 16;
9672 for (i=4; i < 7; i++)
9673 memcpy ((char *)oprof+pbody[i*3+2], pcurve, sizeof pcurve);
9674 pseudoinverse ((double (*)[3]) out_rgb[output_color-1], inverse, 3);
9675 for (i=0; i < 3; i++)
9676 for (j=0; j < 3; j++) {
9677 for (num = k=0; k < 3; k++)
9678 num += xyzd50_srgb[i][k] * inverse[j][k];
9679 oprof[pbody[j*3+23]/4+i+2] = num * 0x10000 + 0.5;
9681 for (i=0; i < phead[0]/4; i++)
9682 oprof[i] = htonl(oprof[i]);
9683 strcpy ((char *)oprof+pbody[2]+8, "auto-generated by dcraw");
9684 strcpy ((char *)oprof+pbody[5]+12, name[output_color-1]);
9685 for (i=0; i < 3; i++)
9686 for (j=0; j < colors; j++)
9687 for (out_cam[i][j] = k=0; k < 3; k++)
9688 out_cam[i][j] += out_rgb[output_color-1][i][k] * rgb_cam[k][j];
9691 fprintf (stderr, raw_color ? _("Building histograms...\n") :
9692 _("Converting to %s colorspace...\n"), name[output_color-1]);
9694 memset (histogram, 0, sizeof histogram);
9695 for (img=image[0], row=0; row < height; row++)
9696 for (col=0; col < width; col++, img+=4) {
9698 out[0] = out[1] = out[2] = 0;
9700 out[0] += out_cam[0][c] * img[c];
9701 out[1] += out_cam[1][c] * img[c];
9702 out[2] += out_cam[2][c] * img[c];
9704 FORC3 img[c] = CLIP((int) out[c]);
9706 else if (document_mode)
9707 img[0] = img[fcol(row,col)];
9708 FORCC histogram[c][img[c] >> 3]++;
9710 if (colors == 4 && output_color) colors = 3;
9711 if (document_mode && filters) colors = 1;
9714 // Export color matrix to Cinelerra.
9715 // It can't be applied before interpolation.
9717 for(i = 0; i < 3; i++) {
9718 for(j = 0; j < 3; j++)
9719 dcraw_matrix[k++] = rgb_cam[i][j];
9724 void CLASS fuji_rotate()
9730 ushort wide, high, (*img)[4], (*pix)[4];
9732 if (!fuji_width) return;
9734 fprintf (stderr,_("Rotating image 45 degrees...\n"));
9735 fuji_width = (fuji_width - 1 + shrink) >> shrink;
9737 wide = fuji_width / step;
9738 high = (height - fuji_width) / step;
9739 img = (ushort (*)[4]) calloc (high, wide*sizeof *img);
9740 merror (img, "fuji_rotate()");
9742 for (row=0; row < high; row++)
9743 for (col=0; col < wide; col++) {
9744 ur = r = fuji_width + (row-col)*step;
9745 uc = c = (row+col)*step;
9746 if (ur > height-2 || uc > width-2) continue;
9749 pix = image + ur*width + uc;
9750 for (i=0; i < colors; i++)
9751 img[row*wide+col][i] =
9752 (pix[ 0][i]*(1-fc) + pix[ 1][i]*fc) * (1-fr) +
9753 (pix[width][i]*(1-fc) + pix[width+1][i]*fc) * fr;
9762 void CLASS stretch()
9764 ushort newdim, (*img)[4], *pix0, *pix1;
9768 if (pixel_aspect == 1) return;
9769 if (verbose) fprintf (stderr,_("Stretching the image...\n"));
9770 if (pixel_aspect < 1) {
9771 newdim = height / pixel_aspect + 0.5;
9772 img = (ushort (*)[4]) calloc (width, newdim*sizeof *img);
9773 merror (img, "stretch()");
9774 for (rc=row=0; row < newdim; row++, rc+=pixel_aspect) {
9775 frac = rc - (c = rc);
9776 pix0 = pix1 = image[c*width];
9777 if (c+1 < height) pix1 += width*4;
9778 for (col=0; col < width; col++, pix0+=4, pix1+=4)
9779 FORCC img[row*width+col][c] = pix0[c]*(1-frac) + pix1[c]*frac + 0.5;
9783 newdim = width * pixel_aspect + 0.5;
9784 img = (ushort (*)[4]) calloc (height, newdim*sizeof *img);
9785 merror (img, "stretch()");
9786 for (rc=col=0; col < newdim; col++, rc+=1/pixel_aspect) {
9787 frac = rc - (c = rc);
9788 pix0 = pix1 = image[c];
9789 if (c+1 < width) pix1 += 4;
9790 for (row=0; row < height; row++, pix0+=width*4, pix1+=width*4)
9791 FORCC img[row*newdim+col][c] = pix0[c]*(1-frac) + pix1[c]*frac + 0.5;
9799 int CLASS flip_index (int row, int col)
9801 if (flip & 4) SWAP(row,col);
9802 if (flip & 2) row = iheight - 1 - row;
9803 if (flip & 1) col = iwidth - 1 - col;
9804 return row * iwidth + col;
9810 union { char c[4]; short s[2]; int i; } val;
9814 ushort order, magic;
9817 struct tiff_tag tag[23];
9820 struct tiff_tag exif[4];
9822 struct tiff_tag gpst[10];
9826 char desc[512], make[64], model[64], soft[32], date[20], artist[64];
9829 void CLASS tiff_set (struct tiff_hdr *th, ushort *ntag,
9830 ushort tag, ushort type, int count, int val)
9832 struct tiff_tag *tt;
9835 tt = (struct tiff_tag *)(ntag+1) + (*ntag)++;
9837 if (type == 1 && count <= 4)
9838 FORC(4) tt->val.c[c] = val >> (c << 3);
9839 else if (type == 2) {
9840 count = strnlen((char *)th + val, count-1) + 1;
9842 FORC(4) tt->val.c[c] = ((char *)th)[val+c];
9843 } else if (type == 3 && count <= 2)
9844 FORC(2) tt->val.s[c] = val >> (c << 4);
9850 #define TOFF(ptr) ((char *)(&(ptr)) - (char *)th)
9852 void CLASS tiff_head (struct tiff_hdr *th, int full)
9857 memset (th, 0, sizeof *th);
9858 th->order = htonl(0x4d4d4949) >> 16;
9861 th->rat[0] = th->rat[2] = 300;
9862 th->rat[1] = th->rat[3] = 1;
9863 FORC(6) th->rat[4+c] = 1000000;
9864 th->rat[4] *= shutter;
9865 th->rat[6] *= aperture;
9866 th->rat[8] *= focal_len;
9867 strncpy (th->desc, desc, 512);
9868 strncpy (th->make, make, 64);
9869 strncpy (th->model, model, 64);
9870 strcpy (th->soft, "dcraw v"DCRAW_VERSION);
9871 t = localtime (×tamp);
9872 sprintf (th->date, "%04d:%02d:%02d %02d:%02d:%02d",
9873 t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);
9874 strncpy (th->artist, artist, 64);
9876 tiff_set (th, &th->ntag, 254, 4, 1, 0);
9877 tiff_set (th, &th->ntag, 256, 4, 1, width);
9878 tiff_set (th, &th->ntag, 257, 4, 1, height);
9879 tiff_set (th, &th->ntag, 258, 3, colors, output_bps);
9881 th->tag[th->ntag-1].val.i = TOFF(th->bps);
9882 FORC4 th->bps[c] = output_bps;
9883 tiff_set (th, &th->ntag, 259, 3, 1, 1);
9884 tiff_set (th, &th->ntag, 262, 3, 1, 1 + (colors > 1));
9886 tiff_set (th, &th->ntag, 270, 2, 512, TOFF(th->desc));
9887 tiff_set (th, &th->ntag, 271, 2, 64, TOFF(th->make));
9888 tiff_set (th, &th->ntag, 272, 2, 64, TOFF(th->model));
9890 if (oprof) psize = ntohl(oprof[0]);
9891 tiff_set (th, &th->ntag, 273, 4, 1, sizeof *th + psize);
9892 tiff_set (th, &th->ntag, 277, 3, 1, colors);
9893 tiff_set (th, &th->ntag, 278, 4, 1, height);
9894 tiff_set (th, &th->ntag, 279, 4, 1, height*width*colors*output_bps/8);
9896 tiff_set (th, &th->ntag, 274, 3, 1, "12435867"[flip]-'0');
9897 tiff_set (th, &th->ntag, 282, 5, 1, TOFF(th->rat[0]));
9898 tiff_set (th, &th->ntag, 283, 5, 1, TOFF(th->rat[2]));
9899 tiff_set (th, &th->ntag, 284, 3, 1, 1);
9900 tiff_set (th, &th->ntag, 296, 3, 1, 2);
9901 tiff_set (th, &th->ntag, 305, 2, 32, TOFF(th->soft));
9902 tiff_set (th, &th->ntag, 306, 2, 20, TOFF(th->date));
9903 tiff_set (th, &th->ntag, 315, 2, 64, TOFF(th->artist));
9904 tiff_set (th, &th->ntag, 34665, 4, 1, TOFF(th->nexif));
9905 if (psize) tiff_set (th, &th->ntag, 34675, 7, psize, sizeof *th);
9906 tiff_set (th, &th->nexif, 33434, 5, 1, TOFF(th->rat[4]));
9907 tiff_set (th, &th->nexif, 33437, 5, 1, TOFF(th->rat[6]));
9908 tiff_set (th, &th->nexif, 34855, 3, 1, iso_speed);
9909 tiff_set (th, &th->nexif, 37386, 5, 1, TOFF(th->rat[8]));
9911 tiff_set (th, &th->ntag, 34853, 4, 1, TOFF(th->ngps));
9912 tiff_set (th, &th->ngps, 0, 1, 4, 0x202);
9913 tiff_set (th, &th->ngps, 1, 2, 2, gpsdata[29]);
9914 tiff_set (th, &th->ngps, 2, 5, 3, TOFF(th->gps[0]));
9915 tiff_set (th, &th->ngps, 3, 2, 2, gpsdata[30]);
9916 tiff_set (th, &th->ngps, 4, 5, 3, TOFF(th->gps[6]));
9917 tiff_set (th, &th->ngps, 5, 1, 1, gpsdata[31]);
9918 tiff_set (th, &th->ngps, 6, 5, 1, TOFF(th->gps[18]));
9919 tiff_set (th, &th->ngps, 7, 5, 3, TOFF(th->gps[12]));
9920 tiff_set (th, &th->ngps, 18, 2, 12, TOFF(th->gps[20]));
9921 tiff_set (th, &th->ngps, 29, 2, 12, TOFF(th->gps[23]));
9922 memcpy (th->gps, gpsdata, sizeof th->gps);
9926 void CLASS jpeg_thumb()
9932 thumb = (char *) malloc (thumb_length);
9933 merror (thumb, "jpeg_thumb()");
9934 fread (thumb, 1, thumb_length, ifp);
9937 if (strcmp (thumb+6, "Exif")) {
9938 memcpy (exif, "\xff\xe1 Exif\0\0", 10);
9939 exif[1] = htons (8 + sizeof th);
9940 fwrite (exif, 1, sizeof exif, ofp);
9942 fwrite (&th, 1, sizeof th, ofp);
9944 fwrite (thumb+2, 1, thumb_length-2, ofp);
9948 void CLASS write_ppm_tiff()
9953 int c, row, col, soff, rstep, cstep;
9954 int perc, val, total, white=0x2000;
9956 perc = width * height * 0.01; /* 99th percentile white level */
9957 if (fuji_width) perc /= 2;
9958 if (!((highlight & ~2) || no_auto_bright))
9959 for (white=c=0; c < colors; c++) {
9960 for (val=0x2000, total=0; --val > 32; )
9961 if ((total += histogram[c][val]) > perc) break;
9962 if (white < val) white = val;
9964 gamma_curve (gamm[0], gamm[1], 2, (white << 3)/bright);
9967 if (flip & 4) SWAP(height,width);
9968 ppm = (uchar *) calloc (width, colors*output_bps/8);
9969 ppm2 = (ushort *) ppm;
9970 merror (ppm, "write_ppm_tiff()");
9973 fwrite (&th, sizeof th, 1, ofp);
9975 fwrite (oprof, ntohl(oprof[0]), 1, ofp);
9976 } else if (colors > 3)
9978 "P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLTYPE %s\nENDHDR\n",
9979 width, height, colors, (1 << output_bps)-1, cdesc);
9981 fprintf (ofp, "P%d\n%d %d\n%d\n",
9982 colors/2+5, width, height, (1 << output_bps)-1);
9983 soff = flip_index (0, 0);
9984 cstep = flip_index (0, 1) - soff;
9985 rstep = flip_index (1, 0) - flip_index (0, width);
9986 for (row=0; row < height; row++, soff += rstep) {
9987 for (col=0; col < width; col++, soff += cstep)
9988 if (output_bps == 8)
9989 FORCC ppm [col*colors+c] = curve[image[soff][c]] >> 8;
9990 else FORCC ppm2[col*colors+c] = curve[image[soff][c]];
9991 if (output_bps == 16 && !output_tiff && htons(0x55aa) != 0x55aa)
9992 swab (ppm2, ppm2, width*colors*2);
9993 fwrite (ppm, colors*output_bps/8, width, ofp);
9999 void CLASS write_cinelerra()
10001 int c, row, col, soff, cstep, rstep;
10002 float scale = 1. / 0xffff;
10003 iheight = height; iwidth = width;
10004 if( (flip & 4) != 0 ) SWAP(height,width);
10005 soff = flip_index(0, 0);
10006 cstep = flip_index(0, 1) - soff;
10007 rstep = flip_index(1, 0) - flip_index(0, width);
10008 if( document_mode ) {
10009 for( row=0; row<height; ++row, soff += rstep ) {
10010 float *output = dcraw_data[row];
10011 for( col=0; col<width; ++col, soff += cstep ) {
10012 ushort *pixel = image[soff];
10013 FORC3 *output++ = (float)*pixel++ * scale;
10014 if( dcraw_alpha ) *output++ = 1.0;
10019 int val, total, white=0x2000;
10020 int perc = width * height * 0.01; /* 99th percentile white level */
10021 if( fuji_width ) perc /= 2;
10022 if( !((highlight & ~2) || no_auto_bright) ) {
10023 for( white=c=0; c < colors; ++c ) {
10024 for( val=0x2000, total=0; --val > 32; )
10025 if( (total += histogram[c][val]) > perc ) break;
10026 if( white < val ) white = val;
10029 gamma_curve(gamm[0], gamm[1], 2, (white << 3)/bright);
10030 for( row=0; row<height; ++row, soff += rstep ) {
10031 float *output = dcraw_data[row];
10032 for( col=0; col<width; ++col, soff += cstep ) {
10033 ushort *pixel = image[soff];
10034 FORC3 *output++ = (float)curve[*pixel++] * scale;
10035 if( dcraw_alpha ) *output++ = 1.0;
10042 int CLASS dcraw_main (int argc, const char **argv)
10044 int arg, status=0, quality, i, c;
10045 int timestamp_only=0, thumbnail_only=0, identify_only=0;
10046 int user_qual=-1, user_black=-1, user_sat=-1, user_flip=-1;
10047 int use_fuji_rotate=1, write_to_stdout=0, read_from_stdin=0;
10048 const char *sp, *bpfile=0, *dark_frame=0, *write_ext;
10049 char opm, opt, *ofname, *cp;
10052 const char *cam_profile=0, *out_profile=0;
10056 reset(); // Globals must be reset
10059 putenv ((char *) "TZ=UTC");
10062 setlocale (LC_CTYPE, "");
10063 setlocale (LC_MESSAGES, "");
10064 bindtextdomain ("dcraw", LOCALEDIR);
10065 textdomain ("dcraw");
10069 printf(_("\nRaw photo decoder \"dcraw\" v%s"), DCRAW_VERSION);
10070 printf(_("\nby Dave Coffin, dcoffin a cybercom o net\n"));
10071 printf(_("\nUsage: %s [OPTION]... [FILE]...\n\n"), argv[0]);
10072 puts(_("-v Print verbose messages"));
10073 puts(_("-c Write image data to standard output"));
10074 puts(_("-e Extract embedded thumbnail image"));
10075 puts(_("-i Identify files without decoding them"));
10076 puts(_("-i -v Identify files and show metadata"));
10077 puts(_("-z Change file dates to camera timestamp"));
10078 puts(_("-w Use camera white balance, if possible"));
10079 puts(_("-a Average the whole image for white balance"));
10080 puts(_("-A <x y w h> Average a grey box for white balance"));
10081 puts(_("-r <r g b g> Set custom white balance"));
10082 puts(_("+M/-M Use/don't use an embedded color matrix"));
10083 puts(_("-C <r b> Correct chromatic aberration"));
10084 puts(_("-P <file> Fix the dead pixels listed in this file"));
10085 puts(_("-K <file> Subtract dark frame (16-bit raw PGM)"));
10086 puts(_("-k <num> Set the darkness level"));
10087 puts(_("-S <num> Set the saturation level"));
10088 puts(_("-n <num> Set threshold for wavelet denoising"));
10089 puts(_("-H [0-9] Highlight mode (0=clip, 1=unclip, 2=blend, 3+=rebuild)"));
10090 puts(_("-t [0-7] Flip image (0=none, 3=180, 5=90CCW, 6=90CW)"));
10091 puts(_("-o [0-6] Output colorspace (raw,sRGB,Adobe,Wide,ProPhoto,XYZ,ACES)"));
10093 puts(_("-o <file> Apply output ICC profile from file"));
10094 puts(_("-p <file> Apply camera ICC profile from file or \"embed\""));
10096 puts(_("-d Document mode (no color, no interpolation)"));
10097 puts(_("-D Document mode without scaling (totally raw)"));
10098 puts(_("-j Don't stretch or rotate raw pixels"));
10099 puts(_("-W Don't automatically brighten the image"));
10100 puts(_("-b <num> Adjust brightness (default = 1.0)"));
10101 puts(_("-g <p ts> Set custom gamma curve (default = 2.222 4.5)"));
10102 puts(_("-q [0-3] Set the interpolation quality"));
10103 puts(_("-h Half-size color image (twice as fast as \"-q 0\")"));
10104 puts(_("-f Interpolate RGGB as four colors"));
10105 puts(_("-m <num> Apply a 3x3 median filter to R-G and B-G"));
10106 puts(_("-s [0..N-1] Select one raw image or \"all\" from each file"));
10107 puts(_("-6 Write 16-bit instead of 8-bit"));
10108 puts(_("-4 Linear 16-bit, same as \"-6 -W -g 1 1\""));
10109 puts(_("-T Write TIFF instead of PPM"));
10114 for (arg=1; (((opm = argv[arg][0]) - 2) | 2) == '+'; ) {
10115 opt = argv[arg++][1];
10116 if ((cp = (char *) strchr (sp="nbrkStqmHACg", opt)))
10117 for (i=0; i < "114111111422"[cp-sp]-'0'; i++)
10118 if (!isdigit(argv[arg+i][0])) {
10119 fprintf (stderr,_("Non-numeric argument to \"-%c\"\n"), opt);
10123 case 'n': threshold = atof(argv[arg++]); break;
10124 case 'b': bright = atof(argv[arg++]); break;
10126 FORC4 user_mul[c] = atof(argv[arg++]); break;
10127 case 'C': aber[0] = 1 / atof(argv[arg++]);
10128 aber[2] = 1 / atof(argv[arg++]); break;
10129 case 'g': gamm[0] = atof(argv[arg++]);
10130 gamm[1] = atof(argv[arg++]);
10131 if (gamm[0]) gamm[0] = 1/gamm[0]; break;
10132 case 'k': user_black = atoi(argv[arg++]); break;
10133 case 'S': user_sat = atoi(argv[arg++]); break;
10134 case 't': user_flip = atoi(argv[arg++]); break;
10135 case 'q': user_qual = atoi(argv[arg++]); break;
10136 case 'm': med_passes = atoi(argv[arg++]); break;
10137 case 'H': highlight = atoi(argv[arg++]); break;
10139 shot_select = abs(atoi(argv[arg]));
10140 multi_out = !strcmp(argv[arg++],"all");
10143 if (isdigit(argv[arg][0]) && !argv[arg][1])
10144 output_color = atoi(argv[arg++]);
10146 else out_profile = argv[arg++];
10148 case 'p': cam_profile = argv[arg++];
10151 case 'P': bpfile = argv[arg++]; break;
10152 case 'K': dark_frame = argv[arg++]; break;
10153 case 'z': timestamp_only = 1; break;
10154 case 'e': thumbnail_only = 1; break;
10155 case 'i': identify_only = 1; break;
10156 case 'c': write_to_stdout = 1; break;
10157 case 'v': verbose = 1; break;
10158 case 'h': half_size = 1; break;
10159 case 'f': four_color_rgb = 1; break;
10160 case 'A': FORC4 greybox[c] = atoi(argv[arg++]);
10161 case 'a': use_auto_wb = 1; break;
10162 case 'w': use_camera_wb = 1; break;
10163 case 'M': use_camera_matrix = 3 * (opm == '+'); break;
10164 case 'I': read_from_stdin = 1; break;
10165 case 'E': document_mode++;
10166 case 'D': document_mode++;
10167 case 'd': document_mode++;
10168 case 'j': use_fuji_rotate = 0; break;
10169 case 'W': no_auto_bright = 1; break;
10170 case 'T': output_tiff = 1; break;
10171 case '4': gamm[0] = gamm[1] =
10172 no_auto_bright = 1;
10173 case '6': output_bps = 16; break;
10175 fprintf (stderr,_("Unknown option \"-%c\".\n"), opt);
10180 fprintf (stderr,_("No files to process.\n"));
10183 if (write_to_stdout) {
10185 if (0 && isatty(1)) {
10186 fprintf (stderr,_("Will not write an image to the terminal!\n"));
10189 #if defined(WIN32) || defined(DJGPP) || defined(__CYGWIN__)
10190 if (setmode(1,O_BINARY) < 0) {
10191 perror ("setmode()");
10196 for ( ; arg < argc; arg++) {
10201 meta_data = ofname = 0;
10203 if (setjmp (failure)) {
10204 if (fileno(ifp) > 2) fclose(ifp);
10205 if (fileno(ofp) > 2) fclose(ofp);
10209 ifname = argv[arg];
10210 if (!(ifp = fopen (ifname, "rb"))) {
10214 status = (identify(),!is_raw);
10215 if (user_flip >= 0)
10217 switch ((flip+3600) % 360) {
10218 case 270: flip = 5; break;
10219 case 180: flip = 3; break;
10222 if (timestamp_only) {
10223 if ((status = !timestamp))
10224 fprintf (stderr,_("%s has no timestamp.\n"), ifname);
10225 else if (identify_only)
10226 printf ("%10ld%10d %s\n", (long) timestamp, shot_order, ifname);
10229 fprintf (stderr,_("%s time set to %d.\n"), ifname, (int) timestamp);
10230 ut.actime = ut.modtime = timestamp;
10231 utime (ifname, &ut);
10236 // write_fun = &CLASS write_ppm_tiff;
10237 write_fun = &CLASS write_cinelerra;
10239 if (thumbnail_only) {
10240 if ((status = !thumb_offset)) {
10241 fprintf (stderr,_("%s has no thumbnail.\n"), ifname);
10243 } else if (thumb_load_raw) {
10244 load_raw = thumb_load_raw;
10245 data_offset = thumb_offset;
10246 height = thumb_height;
10247 width = thumb_width;
10251 fseek (ifp, thumb_offset, SEEK_SET);
10252 write_fun = write_thumb;
10256 if (load_raw == &CLASS kodak_ycbcr_load_raw) {
10257 height += height & 1;
10258 width += width & 1;
10260 if (identify_only && verbose && make[0]) {
10261 printf (_("\nFilename: %s\n"), ifname);
10262 printf (_("Timestamp: %s"), ctime(×tamp));
10263 printf (_("Camera: %s %s\n"), make, model);
10265 printf (_("Owner: %s\n"), artist);
10267 printf (_("DNG Version: "));
10268 for (i=24; i >= 0; i -= 8)
10269 printf ("%d%c", dng_version >> i & 255, i ? '.':'\n');
10271 printf (_("ISO speed: %d\n"), (int) iso_speed);
10272 printf (_("Shutter: "));
10273 if (shutter > 0 && shutter < 1)
10274 shutter = (printf ("1/"), 1 / shutter);
10275 printf (_("%0.1f sec\n"), shutter);
10276 printf (_("Aperture: f/%0.1f\n"), aperture);
10277 printf (_("Focal length: %0.1f mm\n"), focal_len);
10278 printf (_("Embedded ICC profile: %s\n"), profile_length ? _("yes"):_("no"));
10279 printf (_("Number of raw images: %d\n"), is_raw);
10280 if (pixel_aspect != 1)
10281 printf (_("Pixel Aspect Ratio: %0.6f\n"), pixel_aspect);
10283 printf (_("Thumb size: %4d x %d\n"), thumb_width, thumb_height);
10284 printf (_("Full size: %4d x %d\n"), raw_width, raw_height);
10287 // else if (!is_raw)
10288 // fprintf (stderr,_("Cannot decode file %s\n"), ifname);
10289 if (!is_raw) goto next;
10290 shrink = filters && (half_size || (!identify_only &&
10291 (threshold || aber[0] != 1 || aber[2] != 1)));
10292 iheight = (height + shrink) >> shrink;
10293 iwidth = (width + shrink) >> shrink;
10294 if (identify_only) {
10296 if (document_mode == 3) {
10297 top_margin = left_margin = fuji_width = 0;
10298 height = raw_height;
10301 iheight = (height + shrink) >> shrink;
10302 iwidth = (width + shrink) >> shrink;
10303 if (use_fuji_rotate) {
10305 fuji_width = (fuji_width - 1 + shrink) >> shrink;
10306 iwidth = fuji_width / sqrt(0.5);
10307 iheight = (iheight - fuji_width) / sqrt(0.5);
10309 if (pixel_aspect < 1) iheight = iheight / pixel_aspect + 0.5;
10310 if (pixel_aspect > 1) iwidth = iwidth * pixel_aspect + 0.5;
10314 SWAP(iheight,iwidth);
10315 printf (_("Image size: %4d x %d\n"), width, height);
10316 printf (_("Output size: %4d x %d\n"), iwidth, iheight);
10317 printf (_("Raw colors: %d"), colors);
10319 int fhigh = 2, fwide = 2;
10320 if ((filters ^ (filters >> 8)) & 0xff) fhigh = 4;
10321 if ((filters ^ (filters >> 16)) & 0xffff) fhigh = 8;
10322 if (filters == 1) fhigh = fwide = 16;
10323 if (filters == 9) fhigh = fwide = 6;
10324 printf (_("\nFilter pattern: "));
10325 for (i=0; i < fhigh; i++)
10326 for (c = i && putchar('/') && 0; c < fwide; c++)
10327 putchar (cdesc[fcol(i,c)]);
10329 printf (_("\nDaylight multipliers:"));
10330 FORCC printf (" %f", pre_mul[c]);
10331 if (cam_mul[0] > 0) {
10332 printf (_("\nCamera multipliers:"));
10333 FORC4 printf (" %f", cam_mul[c]);
10339 // printf (_("%s is a %s %s image.\n"), ifname, make, model);
10345 meta_data = (char *) malloc (meta_length);
10346 merror (meta_data, "main()");
10348 if (filters || colors == 1) {
10349 raw_image = (ushort *) calloc ((raw_height+7), raw_width*2);
10350 merror (raw_image, "main()");
10352 image = (ushort (*)[4]) calloc (iheight, iwidth*sizeof *image);
10353 merror (image, "main()");
10356 fprintf (stderr,_("Loading %s %s image from %s ...\n"),
10357 make, model, ifname);
10358 if (shot_select >= is_raw)
10359 fprintf (stderr,_("%s: \"-s %d\" requests a nonexistent image!\n"),
10360 ifname, shot_select);
10361 fseeko (ifp, data_offset, SEEK_SET);
10362 if (raw_image && read_from_stdin)
10363 fread (raw_image, 2, raw_height*raw_width, stdin);
10364 else (*load_raw)();
10365 if (document_mode == 3) {
10366 top_margin = left_margin = fuji_width = 0;
10367 height = raw_height;
10370 iheight = (height + shrink) >> shrink;
10371 iwidth = (width + shrink) >> shrink;
10373 image = (ushort (*)[4]) calloc (iheight, iwidth*sizeof *image);
10374 merror (image, "main()");
10375 crop_masked_pixels();
10378 if (zero_is_bad) remove_zeroes();
10379 bad_pixels (bpfile);
10380 if (dark_frame) subtract (dark_frame);
10381 quality = 2 + !fuji_width;
10382 if (user_qual >= 0) quality = user_qual;
10384 FORC3 if (i > cblack[c]) i = cblack[c];
10385 FORC4 cblack[c] -= i;
10388 FORC (cblack[4] * cblack[5])
10389 if (i > cblack[6+c]) i = cblack[6+c];
10390 FORC (cblack[4] * cblack[5])
10393 if (user_black >= 0) black = user_black;
10394 FORC4 cblack[c] += black;
10395 if (user_sat > 0) maximum = user_sat;
10400 if (document_mode || load_raw == &CLASS foveon_dp_load_raw) {
10401 for (i=0; i < height*width*4; i++)
10402 if ((short) image[0][i] < 0) image[0][i] = 0;
10403 } else foveon_interpolate();
10404 } else if (document_mode < 2)
10407 if (filters && !document_mode) {
10410 else if (quality == 1 || colors > 3)
10412 else if (quality == 2 && filters > 1000)
10414 else if (filters == 9)
10415 xtrans_interpolate (quality*2-3);
10420 for (colors=3, i=0; i < height*width; i++)
10421 image[i][1] = (image[i][1] + image[i][3]) >> 1;
10422 if (!is_foveon && colors == 3) median_filter();
10423 if (!is_foveon && highlight == 2) blend_highlights();
10424 if (!is_foveon && highlight > 2) recover_highlights();
10425 if (use_fuji_rotate) fuji_rotate();
10427 if (cam_profile) apply_profile (cam_profile, out_profile);
10430 if (use_fuji_rotate) stretch();
10432 if (write_fun == &CLASS jpeg_thumb)
10433 write_ext = ".jpg";
10434 else if (output_tiff && write_fun == &CLASS write_ppm_tiff)
10435 write_ext = ".tiff";
10437 write_ext = ".pgm\0.ppm\0.ppm\0.pam" + colors*5-5;
10438 ofname = (char *) malloc (strlen(ifname) + 64);
10439 merror (ofname, "main()");
10440 if (write_to_stdout)
10441 strcpy (ofname,_("standard output"));
10443 strcpy (ofname, ifname);
10444 if ((cp = strrchr (ofname, '.'))) *cp = 0;
10446 sprintf (ofname+strlen(ofname), "_%0*d",
10447 snprintf(0,0,"%d",is_raw-1), shot_select);
10448 if (thumbnail_only)
10449 strcat (ofname, ".thumb");
10450 strcat (ofname, write_ext);
10451 ofp = fopen (ofname, "wb");
10459 fprintf (stderr,_("Writing data to %s ...\n"), ofname);
10462 if (ofp != stdout) fclose(ofp);
10464 if (meta_data) free (meta_data);
10465 if (ofname) free (ofname);
10466 if (oprof) free (oprof);
10467 if (image) free (image);
10469 if (++shot_select < is_raw) arg--;
10470 else shot_select = 0;