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; }
198 In order to inline this calculation, I make the risky
199 assumption that all filter patterns can be described
200 by a repeating pattern of eight rows and two columns
202 Do not use the FC or BAYER macros with the Leaf CatchLight,
203 because its pattern is 16x16, not 2x8.
205 Return values are either 0/1/2/3 = G/M/C/Y or 0/1/2/3 = R/G1/B/G2
207 PowerShot 600 PowerShot A50 PowerShot Pro70 Pro90 & G1
208 0xe1e4e1e4: 0x1b4e4b1e: 0x1e4b4e1b: 0xb4b4b4b4:
210 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5
211 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
212 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
213 2 M G M G M G 2 Y C Y C Y C 2 C Y C Y C Y
214 3 C Y C Y C Y 3 G M G M G M 3 G M G M G M
215 4 C Y C Y C Y 4 Y C Y C Y C
216 PowerShot A5 5 G M G M G M 5 G M G M G M
217 0x1e4e1e4e: 6 Y C Y C Y C 6 C Y C Y C Y
218 7 M G M G M G 7 M G M G M G
225 All RGB cameras use one of these Bayer grids:
227 0x16161616: 0x61616161: 0x49494949: 0x94949494:
229 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5
230 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
231 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
232 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
233 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
236 #define RAW(row,col) \
237 raw_image[(row)*raw_width+(col)]
239 #define FC(row,col) \
240 (filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)
242 #define BAYER(row,col) \
243 image[((row) >> shrink)*iwidth + ((col) >> shrink)][FC(row,col)]
245 #define BAYER2(row,col) \
246 image[((row) >> shrink)*iwidth + ((col) >> shrink)][fcol(row,col)]
248 int CLASS fcol (int row, int col)
250 static const char filter[16][16] =
251 { { 2,1,1,3,2,3,2,0,3,2,3,0,1,2,1,0 },
252 { 0,3,0,2,0,1,3,1,0,1,1,2,0,3,3,2 },
253 { 2,3,3,2,3,1,1,3,3,1,2,1,2,0,0,3 },
254 { 0,1,0,1,0,2,0,2,2,0,3,0,1,3,2,1 },
255 { 3,1,1,2,0,1,0,2,1,3,1,3,0,1,3,0 },
256 { 2,0,0,3,3,2,3,1,2,0,2,0,3,2,2,1 },
257 { 2,3,3,1,2,1,2,1,2,1,1,2,3,0,0,1 },
258 { 1,0,0,2,3,0,0,3,0,3,0,3,2,1,2,3 },
259 { 2,3,3,1,1,2,1,0,3,2,3,0,2,3,1,3 },
260 { 1,0,2,0,3,0,3,2,0,1,1,2,0,1,0,2 },
261 { 0,1,1,3,3,2,2,1,1,3,3,0,2,1,3,2 },
262 { 2,3,2,0,0,1,3,0,2,0,1,2,3,0,1,0 },
263 { 1,3,1,2,3,2,3,2,0,2,0,1,1,0,3,0 },
264 { 0,2,0,3,1,0,0,1,1,3,3,2,3,2,2,1 },
265 { 2,1,3,2,3,1,2,1,0,3,0,2,0,2,0,2 },
266 { 0,3,1,0,0,2,0,3,2,1,3,1,1,3,1,3 } };
268 if (filters == 1) return filter[(row+top_margin)&15][(col+left_margin)&15];
269 if (filters == 9) return xtrans[(row+6) % 6][(col+6) % 6];
278 aber[0]=1; aber[1]=1; aber[2]=1; aber[3]=1;
279 gamm[0]=0.45; gamm[1]=4.5; gamm[2]=0; gamm[3]=0; gamm[4]=0; gamm[5]=0;
281 user_mul[0]=0; user_mul[1]=0; user_mul[2]=0; user_mul[3]=0;
296 greybox[0]=0; greybox[1]=0; greybox[2]=UINT_MAX; greybox[3]=UINT_MAX;
300 char *my_memmem (char *haystack, size_t haystacklen,
301 char *needle, size_t needlelen)
304 for (c = haystack; c <= haystack + haystacklen - needlelen; c++)
305 if (!memcmp (c, needle, needlelen))
309 #define memmem my_memmem
310 char *my_strcasestr (char *haystack, const char *needle)
313 for (c = haystack; *c; c++)
314 if (!strncasecmp(c, needle, strlen(needle)))
318 #define strcasestr my_strcasestr
321 void CLASS merror (void *ptr, const char *where)
324 fprintf (stderr,_("%s: Out of memory in %s\n"), ifname, where);
325 longjmp (failure, 1);
331 fprintf (stderr, "%s: ", ifname);
333 fprintf (stderr,_("Unexpected end of file\n"));
335 fprintf (stderr,_("Corrupt data near 0x%llx\n"), (INT64) ftello(ifp));
340 ushort CLASS sget2 (uchar *s)
342 if (order == 0x4949) /* "II" means little-endian */
343 return s[0] | s[1] << 8;
344 else /* "MM" means big-endian */
345 return s[0] << 8 | s[1];
350 uchar str[2] = { 0xff,0xff };
351 fread (str, 1, 2, ifp);
355 unsigned CLASS sget4 (uchar *s)
358 return s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24;
360 return s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3];
362 #define sget4(s) sget4((uchar *)s)
364 unsigned CLASS get4()
366 uchar str[4] = { 0xff,0xff,0xff,0xff };
367 fread (str, 1, 4, ifp);
371 unsigned CLASS getint (int type)
373 return type == 3 ? get2() : get4();
376 float CLASS int_to_float (int i)
378 union { int i; float f; } u;
383 double CLASS getreal (int type)
385 union { char c[8]; double d; } u;
389 case 3: return (unsigned short) get2();
390 case 4: return (unsigned int) get4();
391 case 5: u.d = (unsigned int) get4();
392 return u.d / (unsigned int) get4();
393 case 8: return (signed short) get2();
394 case 9: return (signed int) get4();
395 case 10: u.d = (signed int) get4();
396 return u.d / (signed int) get4();
397 case 11: return int_to_float (get4());
399 rev = 7 * ((order == 0x4949) == (ntohs(0x1234) == 0x1234));
400 for (i=0; i < 8; i++)
401 u.c[i ^ rev] = fgetc(ifp);
403 default: return fgetc(ifp);
407 void CLASS read_shorts (ushort *pixel, int count)
409 if (fread (pixel, 2, count, ifp) < count) derror();
410 if ((order == 0x4949) == (ntohs(0x1234) == 0x1234))
411 swab (pixel, pixel, count*2);
414 void CLASS cubic_spline (const int *x_, const int *y_, const int len)
416 float **A, *b, *c, *d, *x, *y;
419 A = (float **) calloc (((2*len + 4)*sizeof **A + sizeof *A), 2*len);
421 A[0] = (float *) (A + 2*len);
422 for (i = 1; i < 2*len; i++)
423 A[i] = A[0] + 2*len*i;
424 y = len + (x = i + (d = i + (c = i + (b = A[0] + i*i))));
425 for (i = 0; i < len; i++) {
426 x[i] = x_[i] / 65535.0;
427 y[i] = y_[i] / 65535.0;
429 for (i = len-1; i > 0; i--) {
430 b[i] = (y[i] - y[i-1]) / (x[i] - x[i-1]);
431 d[i-1] = x[i] - x[i-1];
433 for (i = 1; i < len-1; i++) {
434 A[i][i] = 2 * (d[i-1] + d[i]);
439 A[i][len-1] = 6 * (b[i+1] - b[i]);
441 for(i = 1; i < len-2; i++) {
442 float v = A[i+1][i] / A[i][i];
443 for(j = 1; j <= len-1; j++)
444 A[i+1][j] -= v * A[i][j];
446 for(i = len-2; i > 0; i--) {
448 for(j = i; j <= len-2; j++)
450 c[i] = (A[i][len-1] - acc) / A[i][i];
452 for (i = 0; i < 0x10000; i++) {
453 float x_out = (float)(i / 65535.0);
455 for (j = 0; j < len-1; j++) {
456 if (x[j] <= x_out && x_out <= x[j+1]) {
457 float v = x_out - x[j];
459 ((y[j+1] - y[j]) / d[j] - (2 * d[j] * c[j] + c[j+1] * d[j])/6) * v
460 + (c[j] * 0.5) * v*v + ((c[j+1] - c[j]) / (6 * d[j])) * v*v*v;
463 curve[i] = y_out < 0.0 ? 0 : (y_out >= 1.0 ? 65535 :
464 (ushort)(y_out * 65535.0 + 0.5));
469 void CLASS canon_600_fixed_wb (int temp)
471 static const short mul[4][5] = {
472 { 667, 358,397,565,452 },
473 { 731, 390,367,499,517 },
474 { 1119, 396,348,448,537 },
475 { 1399, 485,431,508,688 } };
480 if (*mul[lo] <= temp) break;
481 for (hi=0; hi < 3; hi++)
482 if (*mul[hi] >= temp) break;
484 frac = (float) (temp - *mul[lo]) / (*mul[hi] - *mul[lo]);
485 for (i=1; i < 5; i++)
486 pre_mul[i-1] = 1 / (frac * mul[hi][i] + (1-frac) * mul[lo][i]);
489 /* Return values: 0 = white 1 = near white 2 = not white */
490 int CLASS canon_600_color (int ratio[2], int mar)
492 int clipped=0, target, miss;
496 { ratio[1] = -104; clipped = 1; }
498 { ratio[1] = 12; clipped = 1; }
500 if (ratio[1] < -264 || ratio[1] > 461) return 2;
502 { ratio[1] = -50; clipped = 1; }
504 { ratio[1] = 307; clipped = 1; }
506 target = flash_used || ratio[1] < 197
507 ? -38 - (398 * ratio[1] >> 10)
508 : -123 + (48 * ratio[1] >> 10);
509 if (target - mar <= ratio[0] &&
510 target + 20 >= ratio[0] && !clipped) return 0;
511 miss = target - ratio[0];
512 if (abs(miss) >= mar*4) return 2;
513 if (miss < -20) miss = -20;
514 if (miss > mar) miss = mar;
515 ratio[0] = target - miss;
519 void CLASS canon_600_auto_wb()
521 int mar, row, col, i, j, st, count[] = { 0,0 };
522 int test[8], total[2][8], ratio[2][2], stat[2];
524 memset (&total, 0, sizeof total);
526 if (i < 10) mar = 150;
527 else if (i > 12) mar = 20;
528 else mar = 280 - 20 * i;
529 if (flash_used) mar = 80;
530 for (row=14; row < height-14; row+=4)
531 for (col=10; col < width; col+=2) {
532 for (i=0; i < 8; i++)
533 test[(i & 4) + FC(row+(i >> 1),col+(i & 1))] =
534 BAYER(row+(i >> 1),col+(i & 1));
535 for (i=0; i < 8; i++)
536 if (test[i] < 150 || test[i] > 1500) goto next;
537 for (i=0; i < 4; i++)
538 if (abs(test[i] - test[i+4]) > 50) goto next;
539 for (i=0; i < 2; i++) {
540 for (j=0; j < 4; j+=2)
541 ratio[i][j >> 1] = ((test[i*4+j+1]-test[i*4+j]) << 10) / test[i*4+j];
542 stat[i] = canon_600_color (ratio[i], mar);
544 if ((st = stat[0] | stat[1]) > 1) goto next;
545 for (i=0; i < 2; i++)
547 for (j=0; j < 2; j++)
548 test[i*4+j*2+1] = test[i*4+j*2] * (0x400 + ratio[i][j]) >> 10;
549 for (i=0; i < 8; i++)
550 total[st][i] += test[i];
554 if (count[0] | count[1]) {
555 st = count[0]*200 < count[1];
556 for (i=0; i < 4; i++)
557 pre_mul[i] = 1.0 / (total[st][i] + total[st][i+4]);
561 void CLASS canon_600_coeff()
563 static const short table[6][12] = {
564 { -190,702,-1878,2390, 1861,-1349,905,-393, -432,944,2617,-2105 },
565 { -1203,1715,-1136,1648, 1388,-876,267,245, -1641,2153,3921,-3409 },
566 { -615,1127,-1563,2075, 1437,-925,509,3, -756,1268,2519,-2007 },
567 { -190,702,-1886,2398, 2153,-1641,763,-251, -452,964,3040,-2528 },
568 { -190,702,-1878,2390, 1861,-1349,905,-393, -432,944,2617,-2105 },
569 { -807,1319,-1785,2297, 1388,-876,769,-257, -230,742,2067,-1555 } };
573 mc = pre_mul[1] / pre_mul[2];
574 yc = pre_mul[3] / pre_mul[2];
575 if (mc > 1 && mc <= 1.28 && yc < 0.8789) t=1;
576 if (mc > 1.28 && mc <= 2) {
577 if (yc < 0.8789) t=3;
578 else if (yc <= 2) t=4;
581 for (raw_color = i=0; i < 3; i++)
582 FORCC rgb_cam[i][c] = table[t][i*4 + c] / 1024.0;
585 void CLASS canon_600_load_raw()
587 uchar data[1120], *dp;
591 for (irow=row=0; irow < height; irow++) {
592 if (fread (data, 1, 1120, ifp) < 1120) derror();
593 pix = raw_image + row*raw_width;
594 for (dp=data; dp < data+1120; dp+=10, pix+=8) {
595 pix[0] = (dp[0] << 2) + (dp[1] >> 6 );
596 pix[1] = (dp[2] << 2) + (dp[1] >> 4 & 3);
597 pix[2] = (dp[3] << 2) + (dp[1] >> 2 & 3);
598 pix[3] = (dp[4] << 2) + (dp[1] & 3);
599 pix[4] = (dp[5] << 2) + (dp[9] & 3);
600 pix[5] = (dp[6] << 2) + (dp[9] >> 2 & 3);
601 pix[6] = (dp[7] << 2) + (dp[9] >> 4 & 3);
602 pix[7] = (dp[8] << 2) + (dp[9] >> 6 );
604 if ((row+=2) > height) row = 1;
608 void CLASS canon_600_correct()
611 static const short mul[4][2] =
612 { { 1141,1145 }, { 1128,1109 }, { 1178,1149 }, { 1128,1109 } };
614 for (row=0; row < height; row++)
615 for (col=0; col < width; col++) {
616 if ((val = BAYER(row,col) - black) < 0) val = 0;
617 val = val * mul[row & 3][col & 1] >> 9;
618 BAYER(row,col) = val;
620 canon_600_fixed_wb(1311);
623 maximum = (0x3ff - black) * 1109 >> 9;
627 int CLASS canon_s2is()
631 for (row=0; row < 100; row++) {
632 fseek (ifp, row*3340 + 3284, SEEK_SET);
633 if (getc(ifp) > 15) return 1;
638 unsigned CLASS getbithuff (int nbits, ushort *huff)
640 static unsigned bitbuf=0;
641 static int vbits=0, reset=0;
644 if (nbits > 25) return 0;
646 return bitbuf = vbits = reset = 0;
647 if (nbits == 0 || vbits < 0) return 0;
648 while (!reset && vbits < nbits && (c = fgetc(ifp)) != EOF &&
649 !(reset = zero_after_ff && c == 0xff && fgetc(ifp))) {
650 bitbuf = (bitbuf << 8) + (uchar) c;
653 c = bitbuf << (32-vbits) >> (32-nbits);
655 vbits -= huff[c] >> 8;
659 if (vbits < 0) derror();
663 #define getbits(n) getbithuff(n,0)
664 #define gethuff(h) getbithuff(*h,h+1)
667 Construct a decode tree according the specification in *source.
668 The first 16 bytes specify how many codes should be 1-bit, 2-bit
669 3-bit, etc. Bytes after that are the leaf values.
671 For example, if the source is
673 { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0,
674 0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff },
692 ushort * CLASS make_decoder_ref (const uchar **source)
694 int max, len, h, i, j;
698 count = (*source += 16) - 17;
699 for (max=16; max && !count[max]; max--);
700 huff = (ushort *) calloc (1 + (1 << max), sizeof *huff);
701 merror (huff, "make_decoder()");
703 for (h=len=1; len <= max; len++)
704 for (i=0; i < count[len]; i++, ++*source)
705 for (j=0; j < 1 << (max-len); j++)
707 huff[h++] = len << 8 | **source;
711 ushort * CLASS make_decoder (const uchar *source)
713 return make_decoder_ref (&source);
716 void CLASS crw_init_tables (unsigned table, ushort *huff[2])
718 static const uchar first_tree[3][29] = {
719 { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0,
720 0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff },
721 { 0,2,2,3,1,1,1,1,2,0,0,0,0,0,0,0,
722 0x03,0x02,0x04,0x01,0x05,0x00,0x06,0x07,0x09,0x08,0x0a,0x0b,0xff },
723 { 0,0,6,3,1,1,2,0,0,0,0,0,0,0,0,0,
724 0x06,0x05,0x07,0x04,0x08,0x03,0x09,0x02,0x00,0x0a,0x01,0x0b,0xff },
726 static const uchar second_tree[3][180] = {
727 { 0,2,2,2,1,4,2,1,2,5,1,1,0,0,0,139,
728 0x03,0x04,0x02,0x05,0x01,0x06,0x07,0x08,
729 0x12,0x13,0x11,0x14,0x09,0x15,0x22,0x00,0x21,0x16,0x0a,0xf0,
730 0x23,0x17,0x24,0x31,0x32,0x18,0x19,0x33,0x25,0x41,0x34,0x42,
731 0x35,0x51,0x36,0x37,0x38,0x29,0x79,0x26,0x1a,0x39,0x56,0x57,
732 0x28,0x27,0x52,0x55,0x58,0x43,0x76,0x59,0x77,0x54,0x61,0xf9,
733 0x71,0x78,0x75,0x96,0x97,0x49,0xb7,0x53,0xd7,0x74,0xb6,0x98,
734 0x47,0x48,0x95,0x69,0x99,0x91,0xfa,0xb8,0x68,0xb5,0xb9,0xd6,
735 0xf7,0xd8,0x67,0x46,0x45,0x94,0x89,0xf8,0x81,0xd5,0xf6,0xb4,
736 0x88,0xb1,0x2a,0x44,0x72,0xd9,0x87,0x66,0xd4,0xf5,0x3a,0xa7,
737 0x73,0xa9,0xa8,0x86,0x62,0xc7,0x65,0xc8,0xc9,0xa1,0xf4,0xd1,
738 0xe9,0x5a,0x92,0x85,0xa6,0xe7,0x93,0xe8,0xc1,0xc6,0x7a,0x64,
739 0xe1,0x4a,0x6a,0xe6,0xb3,0xf1,0xd3,0xa5,0x8a,0xb2,0x9a,0xba,
740 0x84,0xa4,0x63,0xe5,0xc5,0xf3,0xd2,0xc4,0x82,0xaa,0xda,0xe4,
741 0xf2,0xca,0x83,0xa3,0xa2,0xc3,0xea,0xc2,0xe2,0xe3,0xff,0xff },
742 { 0,2,2,1,4,1,4,1,3,3,1,0,0,0,0,140,
743 0x02,0x03,0x01,0x04,0x05,0x12,0x11,0x06,
744 0x13,0x07,0x08,0x14,0x22,0x09,0x21,0x00,0x23,0x15,0x31,0x32,
745 0x0a,0x16,0xf0,0x24,0x33,0x41,0x42,0x19,0x17,0x25,0x18,0x51,
746 0x34,0x43,0x52,0x29,0x35,0x61,0x39,0x71,0x62,0x36,0x53,0x26,
747 0x38,0x1a,0x37,0x81,0x27,0x91,0x79,0x55,0x45,0x28,0x72,0x59,
748 0xa1,0xb1,0x44,0x69,0x54,0x58,0xd1,0xfa,0x57,0xe1,0xf1,0xb9,
749 0x49,0x47,0x63,0x6a,0xf9,0x56,0x46,0xa8,0x2a,0x4a,0x78,0x99,
750 0x3a,0x75,0x74,0x86,0x65,0xc1,0x76,0xb6,0x96,0xd6,0x89,0x85,
751 0xc9,0xf5,0x95,0xb4,0xc7,0xf7,0x8a,0x97,0xb8,0x73,0xb7,0xd8,
752 0xd9,0x87,0xa7,0x7a,0x48,0x82,0x84,0xea,0xf4,0xa6,0xc5,0x5a,
753 0x94,0xa4,0xc6,0x92,0xc3,0x68,0xb5,0xc8,0xe4,0xe5,0xe6,0xe9,
754 0xa2,0xa3,0xe3,0xc2,0x66,0x67,0x93,0xaa,0xd4,0xd5,0xe7,0xf8,
755 0x88,0x9a,0xd7,0x77,0xc4,0x64,0xe2,0x98,0xa5,0xca,0xda,0xe8,
756 0xf3,0xf6,0xa9,0xb2,0xb3,0xf2,0xd2,0x83,0xba,0xd3,0xff,0xff },
757 { 0,0,6,2,1,3,3,2,5,1,2,2,8,10,0,117,
758 0x04,0x05,0x03,0x06,0x02,0x07,0x01,0x08,
759 0x09,0x12,0x13,0x14,0x11,0x15,0x0a,0x16,0x17,0xf0,0x00,0x22,
760 0x21,0x18,0x23,0x19,0x24,0x32,0x31,0x25,0x33,0x38,0x37,0x34,
761 0x35,0x36,0x39,0x79,0x57,0x58,0x59,0x28,0x56,0x78,0x27,0x41,
762 0x29,0x77,0x26,0x42,0x76,0x99,0x1a,0x55,0x98,0x97,0xf9,0x48,
763 0x54,0x96,0x89,0x47,0xb7,0x49,0xfa,0x75,0x68,0xb6,0x67,0x69,
764 0xb9,0xb8,0xd8,0x52,0xd7,0x88,0xb5,0x74,0x51,0x46,0xd9,0xf8,
765 0x3a,0xd6,0x87,0x45,0x7a,0x95,0xd5,0xf6,0x86,0xb4,0xa9,0x94,
766 0x53,0x2a,0xa8,0x43,0xf5,0xf7,0xd4,0x66,0xa7,0x5a,0x44,0x8a,
767 0xc9,0xe8,0xc8,0xe7,0x9a,0x6a,0x73,0x4a,0x61,0xc7,0xf4,0xc6,
768 0x65,0xe9,0x72,0xe6,0x71,0x91,0x93,0xa6,0xda,0x92,0x85,0x62,
769 0xf3,0xc5,0xb2,0xa4,0x84,0xba,0x64,0xa5,0xb3,0xd2,0x81,0xe5,
770 0xd3,0xaa,0xc4,0xca,0xf2,0xb1,0xe4,0xd1,0x83,0x63,0xea,0xc3,
771 0xe2,0x82,0xf1,0xa3,0xc2,0xa1,0xc1,0xe3,0xa2,0xe1,0xff,0xff }
773 if (table > 2) table = 2;
774 huff[0] = make_decoder ( first_tree[table]);
775 huff[1] = make_decoder (second_tree[table]);
779 Return 0 if the image starts with compressed data,
780 1 if it starts with uncompressed low-order bits.
782 In Canon compressed data, 0xff is always followed by 0x00.
784 int CLASS canon_has_lowbits()
789 fseek (ifp, 0, SEEK_SET);
790 fread (test, 1, sizeof test, ifp);
791 for (i=540; i < sizeof test - 1; i++)
792 if (test[i] == 0xff) {
793 if (test[i+1]) return 1;
799 void CLASS canon_load_raw()
801 ushort *pixel, *prow, *huff[2];
802 int nblocks, lowbits, i, c, row, r, save, val;
803 int block, diffbuf[64], leaf, len, diff, carry=0, pnum=0, base[2];
805 crw_init_tables (tiff_compress, huff);
806 lowbits = canon_has_lowbits();
807 if (!lowbits) maximum = 0x3ff;
808 fseek (ifp, 540 + lowbits*raw_height*raw_width/4, SEEK_SET);
811 for (row=0; row < raw_height; row+=8) {
812 pixel = raw_image + row*raw_width;
813 nblocks = MIN (8, raw_height-row) * raw_width >> 6;
814 for (block=0; block < nblocks; block++) {
815 memset (diffbuf, 0, sizeof diffbuf);
816 for (i=0; i < 64; i++ ) {
817 leaf = gethuff(huff[i > 0]);
818 if (leaf == 0 && i) break;
819 if (leaf == 0xff) continue;
822 if (len == 0) continue;
824 if ((diff & (1 << (len-1))) == 0)
825 diff -= (1 << len) - 1;
826 if (i < 64) diffbuf[i] = diff;
830 for (i=0; i < 64; i++ ) {
831 if (pnum++ % raw_width == 0)
832 base[0] = base[1] = 512;
833 if ((pixel[(block << 6) + i] = base[i & 1] += diffbuf[i]) >> 10)
839 fseek (ifp, 26 + row*raw_width/4, SEEK_SET);
840 for (prow=pixel, i=0; i < raw_width*2; i++) {
842 for (r=0; r < 8; r+=2, prow++) {
843 val = (*prow << 2) + ((c >> r) & 3);
844 if (raw_width == 2672 && val < 512) val += 2;
848 fseek (ifp, save, SEEK_SET);
851 FORC(2) free (huff[c]);
855 int algo, bits, high, wide, clrs, sraw, psv, restart, vpred[6];
856 ushort quant[64], idct[64], *huff[20], *free[20], *row;
859 int CLASS ljpeg_start (struct jhead *jh, int info_only)
865 memset (jh, 0, sizeof *jh);
866 jh->restart = INT_MAX;
867 if ((fgetc(ifp),fgetc(ifp)) != 0xd8) return 0;
869 if (!fread (data, 2, 2, ifp)) return 0;
870 tag = data[0] << 8 | data[1];
871 len = (data[2] << 8 | data[3]) - 2;
872 if (tag <= 0xff00) return 0;
873 fread (data, 1, len, ifp);
876 jh->sraw = ((data[7] >> 4) * (data[7] & 15) - 1) & 3;
879 jh->algo = tag & 0xff;
881 jh->high = data[1] << 8 | data[2];
882 jh->wide = data[3] << 8 | data[4];
883 jh->clrs = data[5] + jh->sraw;
884 if (len == 9 && !dng_version) getc(ifp);
887 if (info_only) break;
888 for (dp = data; dp < data+len && !((c = *dp++) & -20); )
889 jh->free[c] = jh->huff[c] = make_decoder_ref (&dp);
892 jh->psv = data[1+data[0]*2];
893 jh->bits -= data[3+data[0]*2] & 15;
896 FORC(64) jh->quant[c] = data[c*2+1] << 8 | data[c*2+2];
899 jh->restart = data[0] << 8 | data[1];
901 } while (tag != 0xffda);
902 if (jh->bits > 16 || jh->clrs > 6 ||
903 !jh->bits || !jh->high || !jh->wide || !jh->clrs) return 0;
904 if (info_only) return 1;
905 if (!jh->huff[0]) return 0;
906 FORC(19) if (!jh->huff[c+1]) jh->huff[c+1] = jh->huff[c];
908 FORC(4) jh->huff[2+c] = jh->huff[1];
909 FORC(jh->sraw) jh->huff[1+c] = jh->huff[0];
911 jh->row = (ushort *) calloc (jh->wide*jh->clrs, 4);
912 merror (jh->row, "ljpeg_start()");
913 return zero_after_ff = 1;
916 void CLASS ljpeg_end (struct jhead *jh)
919 FORC4 if (jh->free[c]) free (jh->free[c]);
923 int CLASS ljpeg_diff (ushort *huff)
928 if (len == 16 && (!dng_version || dng_version >= 0x1010000))
931 if ((diff & (1 << (len-1))) == 0)
932 diff -= (1 << len) - 1;
936 ushort * CLASS ljpeg_row (int jrow, struct jhead *jh)
938 int col, c, diff, pred, spred=0;
939 ushort mark=0, *row[3];
941 if (jrow * jh->wide % jh->restart == 0) {
942 FORC(6) jh->vpred[c] = 1 << (jh->bits-1);
944 fseek (ifp, -2, SEEK_CUR);
945 do mark = (mark << 8) + (c = fgetc(ifp));
946 while (c != EOF && mark >> 4 != 0xffd);
950 FORC3 row[c] = jh->row + jh->wide*jh->clrs*((jrow+c) & 1);
951 for (col=0; col < jh->wide; col++)
953 diff = ljpeg_diff (jh->huff[c]);
954 if (jh->sraw && c <= jh->sraw && (col | c))
956 else if (col) pred = row[0][-jh->clrs];
957 else pred = (jh->vpred[c] += diff) - diff;
958 if (jrow && col) switch (jh->psv) {
960 case 2: pred = row[1][0]; break;
961 case 3: pred = row[1][-jh->clrs]; break;
962 case 4: pred = pred + row[1][0] - row[1][-jh->clrs]; break;
963 case 5: pred = pred + ((row[1][0] - row[1][-jh->clrs]) >> 1); break;
964 case 6: pred = row[1][0] + ((pred - row[1][-jh->clrs]) >> 1); break;
965 case 7: pred = (pred + row[1][0]) >> 1; break;
968 if ((**row = pred + diff) >> jh->bits) derror();
969 if (c <= jh->sraw) spred = **row;
975 void CLASS lossless_jpeg_load_raw()
977 int jwide, jrow, jcol, val, jidx, i, j, row=0, col=0;
981 if (!ljpeg_start (&jh, 0)) return;
982 jwide = jh.wide * jh.clrs;
984 for (jrow=0; jrow < jh.high; jrow++) {
985 rp = ljpeg_row (jrow, &jh);
987 row = jrow & 1 ? height-1-jrow/2 : jrow/2;
988 for (jcol=0; jcol < jwide; jcol++) {
991 jidx = jrow*jwide + jcol;
992 i = jidx / (cr2_slice[1]*raw_height);
993 if ((j = i >= cr2_slice[0]))
995 jidx -= i * (cr2_slice[1]*raw_height);
996 row = jidx / cr2_slice[1+j];
997 col = jidx % cr2_slice[1+j] + i*cr2_slice[1];
999 if (raw_width == 3984 && (col -= 2) < 0)
1000 col += (row--,raw_width);
1001 if ((unsigned) row < raw_height) RAW(row,col) = val;
1002 if (++col >= raw_width)
1009 void CLASS canon_sraw_load_raw()
1012 short *rp=0, (*ip)[4];
1013 int jwide, slice, scol, ecol, row, col, jrow=0, jcol=0, pix[3], c;
1014 int v[3]={0,0,0}, ver, hue;
1017 if (!ljpeg_start (&jh, 0) || jh.clrs < 4) return;
1018 jwide = (jh.wide >>= 1) * jh.clrs;
1020 for (ecol=slice=0; slice <= cr2_slice[0]; slice++) {
1022 ecol += cr2_slice[1] * 2 / jh.clrs;
1023 if (!cr2_slice[0] || ecol > raw_width-1) ecol = raw_width & -2;
1024 for (row=0; row < height; row += (jh.clrs >> 1) - 1) {
1025 ip = (short (*)[4]) image + row*width;
1026 for (col=scol; col < ecol; col+=2, jcol+=jh.clrs) {
1027 if ((jcol %= jwide) == 0)
1028 rp = (short *) ljpeg_row (jrow++, &jh);
1029 if (col >= width) continue;
1031 ip[col + (c >> 1)*width + (c & 1)][0] = rp[jcol+c];
1032 ip[col][1] = rp[jcol+jh.clrs-2] - 16384;
1033 ip[col][2] = rp[jcol+jh.clrs-1] - 16384;
1037 for (cp=model2; *cp && !isdigit(*cp); cp++);
1038 sscanf (cp, "%d.%d.%d", v, v+1, v+2);
1039 ver = (v[0]*1000 + v[1])*1000 + v[2];
1040 hue = (jh.sraw+1) << 2;
1041 if (unique_id >= 0x80000281 || (unique_id == 0x80000218 && ver > 1000006))
1043 ip = (short (*)[4]) image;
1045 for (row=0; row < height; row++, ip+=width) {
1046 if (row & (jh.sraw >> 1)) { //CINELERRA
1047 for (col=0; col < width; col+=2)
1048 for (c=1; c < 3; c++)
1049 if (row == height-1)
1050 ip[col][c] = ip[col-width][c];
1051 else ip[col][c] = (ip[col-width][c] + ip[col+width][c] + 1) >> 1;
1053 for (col=1; col < width; col+=2)
1054 for (c=1; c < 3; c++)
1056 ip[col][c] = ip[col-1][c];
1057 else ip[col][c] = (ip[col-1][c] + ip[col+1][c] + 1) >> 1;
1059 for ( ; rp < ip[0]; rp+=4) {
1060 if (unique_id == 0x80000218 ||
1061 unique_id == 0x80000250 ||
1062 unique_id == 0x80000261 ||
1063 unique_id == 0x80000281 ||
1064 unique_id == 0x80000287) {
1065 rp[1] = (rp[1] << 2) + hue;
1066 rp[2] = (rp[2] << 2) + hue;
1067 pix[0] = rp[0] + (( 50*rp[1] + 22929*rp[2]) >> 14);
1068 pix[1] = rp[0] + ((-5640*rp[1] - 11751*rp[2]) >> 14);
1069 pix[2] = rp[0] + ((29040*rp[1] - 101*rp[2]) >> 14);
1071 if (unique_id < 0x80000218) rp[0] -= 512;
1072 pix[0] = rp[0] + rp[2];
1073 pix[2] = rp[0] + rp[1];
1074 pix[1] = rp[0] + ((-778*rp[1] - (rp[2] << 11)) >> 12);
1076 FORC3 rp[c] = CLIP(pix[c] * sraw_mul[c] >> 10);
1082 void CLASS adobe_copy_pixel (unsigned row, unsigned col, ushort **rp)
1086 if (tiff_samples == 2 && shot_select) (*rp)++;
1088 if (row < raw_height && col < raw_width)
1089 RAW(row,col) = curve[**rp];
1090 *rp += tiff_samples;
1092 if (row < height && col < width)
1094 image[row*width+col][c] = curve[(*rp)[c]];
1095 *rp += tiff_samples;
1097 if (tiff_samples == 2 && shot_select) (*rp)--;
1100 void CLASS ljpeg_idct (struct jhead *jh)
1102 int c, i, j, len, skip, coef;
1103 float work[3][8][8];
1104 static float cs[106] = { 0 };
1105 static const uchar zigzag[80] =
1106 { 0, 1, 8,16, 9, 2, 3,10,17,24,32,25,18,11, 4, 5,12,19,26,33,
1107 40,48,41,34,27,20,13, 6, 7,14,21,28,35,42,49,56,57,50,43,36,
1108 29,22,15,23,30,37,44,51,58,59,52,45,38,31,39,46,53,60,61,54,
1109 47,55,62,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63 };
1112 FORC(106) cs[c] = cos((c & 31)*M_PI/16)/2;
1113 memset (work, 0, sizeof work);
1114 work[0][0][0] = jh->vpred[0] += ljpeg_diff (jh->huff[0]) * jh->quant[0];
1115 for (i=1; i < 64; i++ ) {
1116 len = gethuff (jh->huff[16]);
1117 i += skip = len >> 4;
1118 if (!(len &= 15) && skip < 15) break;
1119 coef = getbits(len);
1120 if ((coef & (1 << (len-1))) == 0)
1121 coef -= (1 << len) - 1;
1122 ((float *)work)[zigzag[i]] = coef * jh->quant[i];
1124 FORC(8) work[0][0][c] *= M_SQRT1_2;
1125 FORC(8) work[0][c][0] *= M_SQRT1_2;
1126 for (i=0; i < 8; i++)
1127 for (j=0; j < 8; j++)
1128 FORC(8) work[1][i][j] += work[0][i][c] * cs[(j*2+1)*c];
1129 for (i=0; i < 8; i++)
1130 for (j=0; j < 8; j++)
1131 FORC(8) work[2][i][j] += work[1][c][j] * cs[(i*2+1)*c];
1133 FORC(64) jh->idct[c] = CLIP(((float *)work[2])[c]+0.5);
1136 void CLASS lossless_dng_load_raw()
1138 unsigned save, trow=0, tcol=0, jwide, jrow, jcol, row, col, i, j;
1142 while (trow < raw_height) {
1144 if (tile_length < INT_MAX)
1145 fseek (ifp, get4(), SEEK_SET);
1146 if (!ljpeg_start (&jh, 0)) break;
1148 if (filters) jwide *= jh.clrs;
1149 jwide /= MIN (is_raw, tiff_samples);
1152 jh.vpred[0] = 16384;
1154 for (jrow=0; jrow+7 < jh.high; jrow += 8) {
1155 for (jcol=0; jcol+7 < jh.wide; jcol += 8) {
1158 row = trow + jcol/tile_width + jrow*2;
1159 col = tcol + jcol%tile_width;
1160 for (i=0; i < 16; i+=2)
1161 for (j=0; j < 8; j++)
1162 adobe_copy_pixel (row+i, col+j, &rp);
1167 for (row=col=jrow=0; jrow < jh.high; jrow++) {
1168 rp = ljpeg_row (jrow, &jh);
1169 for (jcol=0; jcol < jwide; jcol++) {
1170 adobe_copy_pixel (trow+row, tcol+col, &rp);
1171 if (++col >= tile_width || col >= raw_width)
1172 row += 1 + (col = 0);
1176 fseek (ifp, save+4, SEEK_SET);
1177 if ((tcol += tile_width) >= raw_width)
1178 trow += tile_length + (tcol = 0);
1183 void CLASS packed_dng_load_raw()
1188 pixel = (ushort *) calloc (raw_width, tiff_samples*sizeof *pixel);
1189 merror (pixel, "packed_dng_load_raw()");
1190 for (row=0; row < raw_height; row++) {
1192 read_shorts (pixel, raw_width * tiff_samples);
1195 for (col=0; col < raw_width * tiff_samples; col++)
1196 pixel[col] = getbits(tiff_bps);
1198 for (rp=pixel, col=0; col < raw_width; col++)
1199 adobe_copy_pixel (row, col, &rp);
1204 void CLASS pentax_load_raw()
1206 ushort bit[2][15], huff[4097];
1207 int dep, row, col, diff, c, i;
1208 ushort vpred[2][2] = {{0,0},{0,0}}, hpred[2];
1210 fseek (ifp, meta_offset, SEEK_SET);
1211 dep = (get2() + 12) & 15;
1212 fseek (ifp, 12, SEEK_CUR);
1213 FORC(dep) bit[0][c] = get2();
1214 FORC(dep) bit[1][c] = fgetc(ifp);
1216 for (i=bit[0][c]; i <= ((bit[0][c]+(4096 >> bit[1][c])-1) & 4095); )
1217 huff[++i] = bit[1][c] << 8 | c;
1219 fseek (ifp, data_offset, SEEK_SET);
1221 for (row=0; row < raw_height; row++)
1222 for (col=0; col < raw_width; col++) {
1223 diff = ljpeg_diff (huff);
1224 if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
1225 else hpred[col & 1] += diff;
1226 RAW(row,col) = hpred[col & 1];
1227 if (hpred[col & 1] >> tiff_bps) derror();
1231 void CLASS nikon_load_raw()
1233 static const uchar nikon_tree[][32] = {
1234 { 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0, /* 12-bit lossy */
1235 5,4,3,6,2,7,1,0,8,9,11,10,12 },
1236 { 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0, /* 12-bit lossy after split */
1237 0x39,0x5a,0x38,0x27,0x16,5,4,3,2,1,0,11,12,12 },
1238 { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0, /* 12-bit lossless */
1239 5,4,6,3,7,2,8,1,9,0,10,11,12 },
1240 { 0,1,4,3,1,1,1,1,1,2,0,0,0,0,0,0, /* 14-bit lossy */
1241 5,6,4,7,8,3,9,2,1,0,10,11,12,13,14 },
1242 { 0,1,5,1,1,1,1,1,1,1,2,0,0,0,0,0, /* 14-bit lossy after split */
1243 8,0x5c,0x4b,0x3a,0x29,7,6,5,4,3,2,1,0,13,14 },
1244 { 0,1,4,2,2,3,1,2,0,0,0,0,0,0,0,0, /* 14-bit lossless */
1245 7,6,8,5,9,4,10,3,11,12,2,0,1,13,14 } };
1246 ushort *huff, ver0, ver1, vpred[2][2], hpred[2], csize;
1247 int i, min, max, step=0, tree=0, split=0, row, col, len, shl, diff;
1249 fseek (ifp, meta_offset, SEEK_SET);
1252 if (ver0 == 0x49 || ver1 == 0x58)
1253 fseek (ifp, 2110, SEEK_CUR);
1254 if (ver0 == 0x46) tree = 2;
1255 if (tiff_bps == 14) tree += 3;
1256 read_shorts (vpred[0], 4);
1257 max = 1 << tiff_bps & 0x7fff;
1258 if ((csize = get2()) > 1)
1259 step = max / (csize-1);
1260 if (ver0 == 0x44 && ver1 == 0x20 && step > 0) {
1261 for (i=0; i < csize; i++)
1262 curve[i*step] = get2();
1263 for (i=0; i < max; i++)
1264 curve[i] = ( curve[i-i%step]*(step-i%step) +
1265 curve[i-i%step+step]*(i%step) ) / step;
1266 fseek (ifp, meta_offset+562, SEEK_SET);
1268 } else if (ver0 != 0x46 && csize <= 0x4001)
1269 read_shorts (curve, max=csize);
1270 while (curve[max-2] == curve[max-1]) max--;
1271 huff = make_decoder (nikon_tree[tree]);
1272 fseek (ifp, data_offset, SEEK_SET);
1274 for (min=row=0; row < height; row++) {
1275 if (split && row == split) {
1277 huff = make_decoder (nikon_tree[tree+1]);
1278 max += (min = 16) << 1;
1280 for (col=0; col < raw_width; col++) {
1284 diff = ((getbits(len-shl) << 1) + 1) << shl >> 1;
1285 if ((diff & (1 << (len-1))) == 0)
1286 diff -= (1 << len) - !shl;
1287 if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
1288 else hpred[col & 1] += diff;
1289 if ((ushort)(hpred[col & 1] + min) >= max) derror();
1290 RAW(row,col) = curve[LIM((short)hpred[col & 1],0,0x3fff)];
1296 void CLASS nikon_yuv_load_raw()
1298 int row, col, yuv[4], rgb[3], b, c;
1301 for (row=0; row < raw_height; row++)
1302 for (col=0; col < raw_width; col++) {
1303 if (!(b = col & 1)) {
1305 FORC(6) bitbuf |= (UINT64) fgetc(ifp) << c*8;
1306 FORC(4) yuv[c] = (bitbuf >> c*12 & 0xfff) - (c >> 1 << 11);
1308 rgb[0] = yuv[b] + 1.370705*yuv[3];
1309 rgb[1] = yuv[b] - 0.337633*yuv[2] - 0.698001*yuv[3];
1310 rgb[2] = yuv[b] + 1.732446*yuv[2];
1311 FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,0xfff)] / cam_mul[c];
1316 Returns 1 for a Coolpix 995, 0 for anything else.
1318 int CLASS nikon_e995()
1321 const uchar often[] = { 0x00, 0x55, 0xaa, 0xff };
1323 memset (histo, 0, sizeof histo);
1324 fseek (ifp, -2000, SEEK_END);
1325 for (i=0; i < 2000; i++)
1326 histo[fgetc(ifp)]++;
1327 for (i=0; i < 4; i++)
1328 if (histo[often[i]] < 200)
1334 Returns 1 for a Coolpix 2100, 0 for anything else.
1336 int CLASS nikon_e2100()
1341 fseek (ifp, 0, SEEK_SET);
1342 for (i=0; i < 1024; i++) {
1343 fread (t, 1, 12, ifp);
1344 if (((t[2] & t[4] & t[7] & t[9]) >> 4
1345 & t[1] & t[6] & t[8] & t[11] & 3) != 3)
1351 void CLASS nikon_3700()
1355 static const struct {
1357 char make[12], model[15];
1359 { 0x00, "Pentax", "Optio 33WR" },
1360 { 0x03, "Nikon", "E3200" },
1361 { 0x32, "Nikon", "E3700" },
1362 { 0x33, "Olympus", "C740UZ" } };
1364 fseek (ifp, 3072, SEEK_SET);
1365 fread (dp, 1, 24, ifp);
1366 bits = (dp[8] & 3) << 4 | (dp[20] & 3);
1367 for (i=0; i < sizeof table / sizeof *table; i++)
1368 if (bits == table[i].bits) {
1369 strcpy (make, table[i].make );
1370 strcpy (model, table[i].model);
1375 Separates a Minolta DiMAGE Z2 from a Nikon E4300.
1377 int CLASS minolta_z2()
1382 fseek (ifp, -sizeof tail, SEEK_END);
1383 fread (tail, 1, sizeof tail, ifp);
1384 for (nz=i=0; i < sizeof tail; i++)
1389 void CLASS jpeg_thumb();
1391 void CLASS ppm_thumb()
1394 thumb_length = thumb_width*thumb_height*3;
1395 thumb = (char *) malloc (thumb_length);
1396 merror (thumb, "ppm_thumb()");
1397 fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
1398 fread (thumb, 1, thumb_length, ifp);
1399 fwrite (thumb, 1, thumb_length, ofp);
1403 void CLASS ppm16_thumb()
1407 thumb_length = thumb_width*thumb_height*3;
1408 thumb = (char *) calloc (thumb_length, 2);
1409 merror (thumb, "ppm16_thumb()");
1410 read_shorts ((ushort *) thumb, thumb_length);
1411 for (i=0; i < thumb_length; i++)
1412 thumb[i] = ((ushort *) thumb)[i] >> 8;
1413 fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
1414 fwrite (thumb, 1, thumb_length, ofp);
1418 void CLASS layer_thumb()
1421 char *thumb, map[][4] = { "012","102" };
1423 colors = thumb_misc >> 5 & 7;
1424 thumb_length = thumb_width*thumb_height;
1425 thumb = (char *) calloc (colors, thumb_length);
1426 merror (thumb, "layer_thumb()");
1427 fprintf (ofp, "P%d\n%d %d\n255\n",
1428 5 + (colors >> 1), thumb_width, thumb_height);
1429 fread (thumb, thumb_length, colors, ifp);
1430 for (i=0; i < thumb_length; i++)
1431 FORCC putc (thumb[i+thumb_length*(map[thumb_misc >> 8][c]-'0')], ofp);
1435 void CLASS rollei_thumb()
1440 thumb_length = thumb_width * thumb_height;
1441 thumb = (ushort *) calloc (thumb_length, 2);
1442 merror (thumb, "rollei_thumb()");
1443 fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
1444 read_shorts (thumb, thumb_length);
1445 for (i=0; i < thumb_length; i++) {
1446 putc (thumb[i] << 3, ofp);
1447 putc (thumb[i] >> 5 << 2, ofp);
1448 putc (thumb[i] >> 11 << 3, ofp);
1453 void CLASS rollei_load_raw()
1456 unsigned iten=0, isix, i, buffer=0, todo[16];
1458 isix = raw_width * raw_height * 5 / 8;
1459 while (fread (pixel, 1, 10, ifp) == 10) {
1460 for (i=0; i < 10; i+=2) {
1462 todo[i+1] = pixel[i] << 8 | pixel[i+1];
1463 buffer = pixel[i] >> 2 | buffer << 6;
1465 for ( ; i < 16; i+=2) {
1467 todo[i+1] = buffer >> (14-i)*5;
1469 for (i=0; i < 16; i+=2)
1470 raw_image[todo[i]] = (todo[i+1] & 0x3ff);
1475 int CLASS raw (unsigned row, unsigned col)
1477 return (row < raw_height && col < raw_width) ? RAW(row,col) : 0;
1480 void CLASS phase_one_flat_field (int is_float, int nc)
1483 unsigned wide, high, y, x, c, rend, cend, row, col;
1484 float *mrow, num, mult[4];
1486 read_shorts (head, 8);
1487 if (head[2] * head[3] * head[4] * head[5] == 0) return;
1488 wide = head[2] / head[4] + (head[2] % head[4] != 0);
1489 high = head[3] / head[5] + (head[3] % head[5] != 0);
1490 mrow = (float *) calloc (nc*wide, sizeof *mrow);
1491 merror (mrow, "phase_one_flat_field()");
1492 for (y=0; y < high; y++) {
1493 for (x=0; x < wide; x++)
1494 for (c=0; c < nc; c+=2) {
1495 num = is_float ? getreal(11) : get2()/32768.0;
1496 if (y==0) mrow[c*wide+x] = num;
1497 else mrow[(c+1)*wide+x] = (num - mrow[c*wide+x]) / head[5];
1500 rend = head[1] + y*head[5];
1501 for (row = rend-head[5];
1502 row < raw_height && row < rend &&
1503 row < head[1]+head[3]-head[5]; row++) {
1504 for (x=1; x < wide; x++) {
1505 for (c=0; c < nc; c+=2) {
1506 mult[c] = mrow[c*wide+x-1];
1507 mult[c+1] = (mrow[c*wide+x] - mult[c]) / head[4];
1509 cend = head[0] + x*head[4];
1510 for (col = cend-head[4];
1512 col < cend && col < head[0]+head[2]-head[4]; col++) {
1513 c = nc > 2 ? FC(row-top_margin,col-left_margin) : 0;
1515 c = RAW(row,col) * mult[c];
1516 RAW(row,col) = LIM(c,0,65535);
1518 for (c=0; c < nc; c+=2)
1519 mult[c] += mult[c+1];
1522 for (x=0; x < wide; x++)
1523 for (c=0; c < nc; c+=2)
1524 mrow[c*wide+x] += mrow[(c+1)*wide+x];
1530 void CLASS phase_one_correct()
1532 unsigned entries, tag, data, save, col, row, type;
1533 int len, i, j, k, cip, val[4], dev[4], sum, max;
1534 int head[9], diff, mindiff=INT_MAX, off_412=0;
1535 static const signed char dir[12][2] =
1536 { {-1,-1}, {-1,1}, {1,-1}, {1,1}, {-2,0}, {0,-2}, {0,2}, {2,0},
1537 {-2,-2}, {-2,2}, {2,-2}, {2,2} };
1538 float poly[8], num, cfrac, frac, mult[2], *yval[2];
1540 int qmult_applied = 0, qlin_applied = 0;
1542 if (half_size || !meta_length) return;
1543 if (verbose) fprintf (stderr,_("Phase One correction...\n"));
1544 fseek (ifp, meta_offset, SEEK_SET);
1546 fseek (ifp, 6, SEEK_CUR);
1547 fseek (ifp, meta_offset+get4(), SEEK_SET);
1548 entries = get4(); get4();
1554 fseek (ifp, meta_offset+data, SEEK_SET);
1555 if (tag == 0x419) { /* Polynomial curve */
1556 for (get4(), i=0; i < 8; i++)
1557 poly[i] = getreal(11);
1558 poly[3] += (ph1.tag_210 - poly[7]) * poly[6] + 1;
1559 for (i=0; i < 0x10000; i++) {
1560 num = (poly[5]*i + poly[3])*i + poly[1];
1561 curve[i] = LIM(num,0,65535);
1562 } goto apply; /* apply to right half */
1563 } else if (tag == 0x41a) { /* Polynomial curve */
1564 for (i=0; i < 4; i++)
1565 poly[i] = getreal(11);
1566 for (i=0; i < 0x10000; i++) {
1567 for (num=0, j=4; j--; )
1568 num = num * i + poly[j];
1569 curve[i] = LIM(num+i,0,65535);
1570 } apply: /* apply to whole image */
1571 for (row=0; row < raw_height; row++)
1572 for (col = (tag & 1)*ph1.split_col; col < raw_width; col++)
1573 RAW(row,col) = curve[RAW(row,col)];
1574 } else if (tag == 0x400) { /* Sensor defects */
1575 while ((len -= 8) >= 0) {
1578 type = get2(); get2();
1579 if (col >= raw_width) continue;
1580 if (type == 131 || type == 137) /* Bad column */
1581 for (row=0; row < raw_height; row++)
1582 if (FC(row-top_margin,col-left_margin) == 1) {
1583 for (sum=i=0; i < 4; i++)
1584 sum += val[i] = raw (row+dir[i][0], col+dir[i][1]);
1585 for (max=i=0; i < 4; i++) {
1586 dev[i] = abs((val[i] << 2) - sum);
1587 if (dev[max] < dev[i]) max = i;
1589 RAW(row,col) = (sum - val[max])/3.0 + 0.5;
1591 for (sum=0, i=8; i < 12; i++)
1592 sum += raw (row+dir[i][0], col+dir[i][1]);
1593 RAW(row,col) = 0.5 + sum * 0.0732233 +
1594 (raw(row,col-2) + raw(row,col+2)) * 0.3535534;
1596 else if (type == 129) { /* Bad pixel */
1597 if (row >= raw_height) continue;
1598 j = (FC(row-top_margin,col-left_margin) != 1) * 4;
1599 for (sum=0, i=j; i < j+8; i++)
1600 sum += raw (row+dir[i][0], col+dir[i][1]);
1601 RAW(row,col) = (sum + 4) >> 3;
1604 } else if (tag == 0x401) { /* All-color flat fields */
1605 phase_one_flat_field (1, 2);
1606 } else if (tag == 0x416 || tag == 0x410) {
1607 phase_one_flat_field (0, 2);
1608 } else if (tag == 0x40b) { /* Red+blue flat field */
1609 phase_one_flat_field (0, 4);
1610 } else if (tag == 0x412) {
1611 fseek (ifp, 36, SEEK_CUR);
1612 diff = abs (get2() - ph1.tag_21a);
1613 if (mindiff > diff) {
1615 off_412 = ftell(ifp) - 38;
1617 } else if (tag == 0x41f && !qlin_applied) { /* Quadrant linearization */
1618 ushort lc[2][2][16], ref[16];
1620 for (qr = 0; qr < 2; qr++)
1621 for (qc = 0; qc < 2; qc++)
1622 for (i = 0; i < 16; i++)
1623 lc[qr][qc][i] = get4();
1624 for (i = 0; i < 16; i++) {
1626 for (qr = 0; qr < 2; qr++)
1627 for (qc = 0; qc < 2; qc++)
1629 ref[i] = (v + 2) >> 2;
1631 for (qr = 0; qr < 2; qr++) {
1632 for (qc = 0; qc < 2; qc++) {
1634 for (i = 0; i < 16; i++) {
1635 cx[1+i] = lc[qr][qc][i];
1639 cx[17] = cf[17] = ((unsigned) ref[15] * 65535) / lc[qr][qc][15];
1640 cx[18] = cf[18] = 65535;
1641 cubic_spline(cx, cf, 19);
1642 for (row = (qr ? ph1.split_row : 0);
1643 row < (qr ? raw_height : ph1.split_row); row++)
1644 for (col = (qc ? ph1.split_col : 0);
1645 col < (qc ? raw_width : ph1.split_col); col++)
1646 RAW(row,col) = curve[RAW(row,col)];
1650 } else if (tag == 0x41e && !qmult_applied) { /* Quadrant multipliers */
1651 float qmult[2][2] = { { 1, 1 }, { 1, 1 } };
1652 get4(); get4(); get4(); get4();
1653 qmult[0][0] = 1.0 + getreal(11);
1654 get4(); get4(); get4(); get4(); get4();
1655 qmult[0][1] = 1.0 + getreal(11);
1656 get4(); get4(); get4();
1657 qmult[1][0] = 1.0 + getreal(11);
1658 get4(); get4(); get4();
1659 qmult[1][1] = 1.0 + getreal(11);
1660 for (row=0; row < raw_height; row++)
1661 for (col=0; col < raw_width; col++) {
1662 i = qmult[row >= ph1.split_row][col >= ph1.split_col] * RAW(row,col);
1663 RAW(row,col) = LIM(i,0,65535);
1666 } else if (tag == 0x431 && !qmult_applied) { /* Quadrant combined */
1667 ushort lc[2][2][7], ref[7];
1669 for (i = 0; i < 7; i++)
1671 for (qr = 0; qr < 2; qr++)
1672 for (qc = 0; qc < 2; qc++)
1673 for (i = 0; i < 7; i++)
1674 lc[qr][qc][i] = get4();
1675 for (qr = 0; qr < 2; qr++) {
1676 for (qc = 0; qc < 2; qc++) {
1678 for (i = 0; i < 7; i++) {
1680 cf[1+i] = ((unsigned) ref[i] * lc[qr][qc][i]) / 10000;
1683 cx[8] = cf[8] = 65535;
1684 cubic_spline(cx, cf, 9);
1685 for (row = (qr ? ph1.split_row : 0);
1686 row < (qr ? raw_height : ph1.split_row); row++)
1687 for (col = (qc ? ph1.split_col : 0);
1688 col < (qc ? raw_width : ph1.split_col); col++)
1689 RAW(row,col) = curve[RAW(row,col)];
1695 fseek (ifp, save, SEEK_SET);
1698 fseek (ifp, off_412, SEEK_SET);
1699 for (i=0; i < 9; i++) head[i] = get4() & 0x7fff;
1700 yval[0] = (float *) calloc (head[1]*head[3] + head[2]*head[4], 6);
1701 merror (yval[0], "phase_one_correct()");
1702 yval[1] = (float *) (yval[0] + head[1]*head[3]);
1703 xval[0] = (ushort *) (yval[1] + head[2]*head[4]);
1704 xval[1] = (ushort *) (xval[0] + head[1]*head[3]);
1706 for (i=0; i < 2; i++)
1707 for (j=0; j < head[i+1]*head[i+3]; j++)
1708 yval[i][j] = getreal(11);
1709 for (i=0; i < 2; i++)
1710 for (j=0; j < head[i+1]*head[i+3]; j++)
1711 xval[i][j] = get2();
1712 for (row=0; row < raw_height; row++)
1713 for (col=0; col < raw_width; col++) {
1714 cfrac = (float) col * head[3] / raw_width;
1715 cfrac -= cip = cfrac;
1716 num = RAW(row,col) * 0.5;
1717 for (i=cip; i < cip+2; i++) {
1718 for (k=j=0; j < head[1]; j++)
1719 if (num < xval[0][k = head[1]*i+j]) break;
1720 frac = (j == 0 || j == head[1]) ? 0 :
1721 (xval[0][k] - num) / (xval[0][k] - xval[0][k-1]);
1722 mult[i-cip] = yval[0][k-1] * frac + yval[0][k] * (1-frac);
1724 i = ((mult[0] * (1-cfrac) + mult[1] * cfrac) * row + num) * 2;
1725 RAW(row,col) = LIM(i,0,65535);
1731 void CLASS phase_one_load_raw()
1734 ushort akey, bkey, mask;
1736 fseek (ifp, ph1.key_off, SEEK_SET);
1739 mask = ph1.format == 1 ? 0x5555:0x1354;
1740 fseek (ifp, data_offset, SEEK_SET);
1741 read_shorts (raw_image, raw_width*raw_height);
1743 for (i=0; i < raw_width*raw_height; i+=2) {
1744 a = raw_image[i+0] ^ akey;
1745 b = raw_image[i+1] ^ bkey;
1746 raw_image[i+0] = (a & mask) | (b & ~mask);
1747 raw_image[i+1] = (b & mask) | (a & ~mask);
1751 unsigned CLASS ph1_bithuff (int nbits, ushort *huff)
1753 static UINT64 bitbuf=0;
1758 return bitbuf = vbits = 0;
1759 if (nbits == 0) return 0;
1760 if (vbits < nbits) {
1761 bitbuf = bitbuf << 32 | get4();
1764 c = bitbuf << (64-vbits) >> (64-nbits);
1766 vbits -= huff[c] >> 8;
1767 return (uchar) huff[c];
1772 #define ph1_bits(n) ph1_bithuff(n,0)
1773 #define ph1_huff(h) ph1_bithuff(*h,h+1)
1775 void CLASS phase_one_load_raw_c()
1777 static const int length[] = { 8,7,6,9,11,10,5,12,14,13 };
1778 int *offset, len[2], pred[2], row, col, i, j;
1780 short (*cblack)[2], (*rblack)[2];
1782 pixel = (ushort *) calloc (raw_width*3 + raw_height*4, 2);
1783 merror (pixel, "phase_one_load_raw_c()");
1784 offset = (int *) (pixel + raw_width);
1785 fseek (ifp, strip_offset, SEEK_SET);
1786 for (row=0; row < raw_height; row++)
1787 offset[row] = get4();
1788 cblack = (short (*)[2]) (offset + raw_height);
1789 fseek (ifp, ph1.black_col, SEEK_SET);
1791 read_shorts ((ushort *) cblack[0], raw_height*2);
1792 rblack = cblack + raw_height;
1793 fseek (ifp, ph1.black_row, SEEK_SET);
1795 read_shorts ((ushort *) rblack[0], raw_width*2);
1796 for (i=0; i < 256; i++)
1797 curve[i] = i*i / 3.969 + 0.5;
1798 for (row=0; row < raw_height; row++) {
1799 fseek (ifp, data_offset + offset[row], SEEK_SET);
1801 pred[0] = pred[1] = 0;
1802 for (col=0; col < raw_width; col++) {
1803 if (col >= (raw_width & -8))
1804 len[0] = len[1] = 14;
1805 else if ((col & 7) == 0)
1806 for (i=0; i < 2; i++) {
1807 for (j=0; j < 5 && !ph1_bits(1); j++);
1808 if (j--) len[i] = length[j*2 + ph1_bits(1)];
1810 if ((i = len[col & 1]) == 14)
1811 pixel[col] = pred[col & 1] = ph1_bits(16);
1813 pixel[col] = pred[col & 1] += ph1_bits(i) + 1 - (1 << (i - 1));
1814 if (pred[col & 1] >> 16) derror();
1815 if (ph1.format == 5 && pixel[col] < 256)
1816 pixel[col] = curve[pixel[col]];
1818 for (col=0; col < raw_width; col++) {
1819 i = (pixel[col] << 2*(ph1.format != 8)) - ph1.black
1820 + cblack[row][col >= ph1.split_col]
1821 + rblack[col][row >= ph1.split_row];
1822 if (i > 0) RAW(row,col) = i;
1826 maximum = 0xfffc - ph1.black;
1829 void CLASS hasselblad_load_raw()
1832 int shot, row, col, *back[5], len[2], diff[12], pred, sh, f, s, c;
1833 unsigned upix, urow, ucol;
1836 if (!ljpeg_start (&jh, 0)) return;
1839 back[4] = (int *) calloc (raw_width, 3*sizeof **back);
1840 merror (back[4], "hasselblad_load_raw()");
1841 FORC3 back[c] = back[4] + c*raw_width;
1842 cblack[6] >>= sh = tiff_samples > 1;
1843 shot = LIM(shot_select, 1, tiff_samples) - 1;
1844 for (row=0; row < raw_height; row++) {
1845 FORC4 back[(c+3) & 3] = back[c];
1846 for (col=0; col < raw_width; col+=2) {
1847 for (s=0; s < tiff_samples*2; s+=2) {
1848 FORC(2) len[c] = ph1_huff(jh.huff[0]);
1850 diff[s+c] = ph1_bits(len[c]);
1851 if ((diff[s+c] & (1 << (len[c]-1))) == 0)
1852 diff[s+c] -= (1 << len[c]) - 1;
1853 if (diff[s+c] == 65535) diff[s+c] = -32768;
1856 for (s=col; s < col+2; s++) {
1857 pred = 0x8000 + load_flags;
1858 if (col) pred = back[2][s-2];
1859 if (col && row > 1) switch (jh.psv) {
1860 case 11: pred += back[0][s]/2 - back[0][s-2]/2; break;
1862 f = (row & 1)*3 ^ ((col+s) & 1);
1863 FORC (tiff_samples) {
1864 pred += diff[(s & 1)*tiff_samples+c];
1865 upix = pred >> sh & 0xffff;
1866 if (raw_image && c == shot)
1869 urow = row-top_margin + (c & 1);
1870 ucol = col-left_margin - ((c >> 1) & 1);
1871 ip = &image[urow*width+ucol][f];
1872 if (urow < height && ucol < width)
1873 *ip = c < 4 ? upix : (*ip + upix) >> 1;
1882 if (image) mix_green = 1;
1885 void CLASS leaf_hdr_load_raw()
1888 unsigned tile=0, r, c, row, col;
1891 pixel = (ushort *) calloc (raw_width, sizeof *pixel);
1892 merror (pixel, "leaf_hdr_load_raw()");
1895 for (r=0; r < raw_height; r++) {
1896 if (r % tile_length == 0) {
1897 fseek (ifp, data_offset + 4*tile++, SEEK_SET);
1898 fseek (ifp, get4(), SEEK_SET);
1900 if (filters && c != shot_select) continue;
1901 if (filters) pixel = raw_image + r*raw_width;
1902 read_shorts (pixel, raw_width);
1903 if (!filters && (row = r - top_margin) < height)
1904 for (col=0; col < width; col++)
1905 image[row*width+col][c] = pixel[col+left_margin];
1914 void CLASS unpacked_load_raw()
1916 int row, col, bits=0;
1918 while (1 << ++bits < maximum);
1919 read_shorts (raw_image, raw_width*raw_height);
1920 for (row=0; row < raw_height; row++)
1921 for (col=0; col < raw_width; col++)
1922 if ((RAW(row,col) >>= load_flags) >> bits
1923 && (unsigned) (row-top_margin) < height
1924 && (unsigned) (col-left_margin) < width) derror();
1927 void CLASS sinar_4shot_load_raw()
1930 unsigned shot, row, col, r, c;
1933 shot = LIM (shot_select, 1, 4) - 1;
1934 fseek (ifp, data_offset + shot*4, SEEK_SET);
1935 fseek (ifp, get4(), SEEK_SET);
1936 unpacked_load_raw();
1939 pixel = (ushort *) calloc (raw_width, sizeof *pixel);
1940 merror (pixel, "sinar_4shot_load_raw()");
1941 for (shot=0; shot < 4; shot++) {
1942 fseek (ifp, data_offset + shot*4, SEEK_SET);
1943 fseek (ifp, get4(), SEEK_SET);
1944 for (row=0; row < raw_height; row++) {
1945 read_shorts (pixel, raw_width);
1946 if ((r = row-top_margin - (shot >> 1 & 1)) >= height) continue;
1947 for (col=0; col < raw_width; col++) {
1948 if ((c = col-left_margin - (shot & 1)) >= width) continue;
1949 image[r*width+c][(row & 1)*3 ^ (~col & 1)] = pixel[col];
1957 void CLASS imacon_full_load_raw()
1962 for (row=0; row < height; row++)
1963 for (col=0; col < width; col++)
1964 read_shorts (image[row*width+col], 3);
1967 void CLASS packed_load_raw()
1969 int vbits=0, bwide, rbits, bite, half, irow, row, col, val, i;
1972 bwide = raw_width * tiff_bps / 8;
1973 bwide += bwide & load_flags >> 7;
1974 rbits = bwide * 8 - raw_width * tiff_bps;
1975 if (load_flags & 1) bwide = bwide * 16 / 15;
1976 bite = 8 + (load_flags & 24);
1977 half = (raw_height+1) >> 1;
1978 for (irow=0; irow < raw_height; irow++) {
1980 if (load_flags & 2 &&
1981 (row = irow % half * 2 + irow / half) == 1 &&
1983 if (vbits=0, tiff_compress)
1984 fseek (ifp, data_offset - (-half*bwide & -2048), SEEK_SET);
1986 fseek (ifp, 0, SEEK_END);
1987 fseek (ifp, ftell(ifp) >> 3 << 2, SEEK_SET);
1990 for (col=0; col < raw_width; col++) {
1991 for (vbits -= tiff_bps; vbits < 0; vbits += bite) {
1993 for (i=0; i < bite; i+=8)
1994 bitbuf |= (unsigned) (fgetc(ifp) << i);
1996 val = bitbuf << (64-tiff_bps-vbits) >> (64-tiff_bps);
1997 RAW(row,col ^ (load_flags >> 6 & 1)) = val;
1998 if (load_flags & 1 && (col % 10) == 9 && fgetc(ifp) &&
1999 row < height+top_margin && col < width+left_margin) derror();
2005 void CLASS nokia_load_raw()
2008 int rev, dwide, row, col, c;
2011 rev = 3 * (order == 0x4949);
2012 dwide = (raw_width * 5 + 1) / 4;
2013 data = (uchar *) malloc (dwide*2);
2014 merror (data, "nokia_load_raw()");
2015 for (row=0; row < raw_height; row++) {
2016 if (fread (data+dwide, 1, dwide, ifp) < dwide) derror();
2017 FORC(dwide) data[c] = data[dwide+(c ^ rev)];
2018 for (dp=data, col=0; col < raw_width; dp+=5, col+=4)
2019 FORC4 RAW(row,col+c) = (dp[c] << 2) | (dp[4] >> (c << 1) & 3);
2023 if (strcmp(make,"OmniVision")) return;
2026 sum[ c & 1] += SQR(RAW(row,c)-RAW(row+1,c+1));
2027 sum[~c & 1] += SQR(RAW(row+1,c)-RAW(row,c+1));
2029 if (sum[1] > sum[0]) filters = 0x4b4b4b4b;
2032 void CLASS canon_rmf_load_raw()
2034 int row, col, bits, orow, ocol, c;
2036 for (row=0; row < raw_height; row++)
2037 for (col=0; col < raw_width-2; col+=3) {
2041 if ((ocol = col+c-4) < 0) {
2043 if ((orow -= 2) < 0)
2046 RAW(orow,ocol) = curve[bits >> (10*c+2) & 0x3ff];
2049 maximum = curve[0x3ff];
2052 unsigned CLASS pana_bits (int nbits)
2054 static uchar buf[0x4000];
2058 if (!nbits) return vbits=0;
2060 fread (buf+load_flags, 1, 0x4000-load_flags, ifp);
2061 fread (buf, 1, load_flags, ifp);
2063 vbits = (vbits - nbits) & 0x1ffff;
2064 byte = vbits >> 3 ^ 0x3ff0;
2065 return (buf[byte] | buf[byte+1] << 8) >> (vbits & 7) & ~(-1 << nbits);
2068 void CLASS panasonic_load_raw()
2070 int row, col, i, j, sh=0, pred[2], nonz[2];
2073 for (row=0; row < height; row++)
2074 for (col=0; col < raw_width; col++) {
2075 if ((i = col % 14) == 0)
2076 pred[0] = pred[1] = nonz[0] = nonz[1] = 0;
2077 if (i % 3 == 2) sh = 4 >> (3 - pana_bits(2));
2079 if ((j = pana_bits(8))) {
2080 if ((pred[i & 1] -= 0x80 << sh) < 0 || sh == 4)
2081 pred[i & 1] &= ~(-1 << sh);
2082 pred[i & 1] += j << sh;
2084 } else if ((nonz[i & 1] = pana_bits(8)) || i > 11)
2085 pred[i & 1] = nonz[i & 1] << 4 | pana_bits(4);
2086 if ((RAW(row,col) = pred[col & 1]) > 4098 && col < width) derror();
2090 void CLASS olympus_load_raw()
2093 int row, col, nbits, sign, low, high, i, c, w, n, nw;
2094 int acarry[2][3], *carry, pred, diff;
2098 FORC(2048 >> i) huff[++n] = (i+1) << 8 | i;
2099 fseek (ifp, 7, SEEK_CUR);
2101 for (row=0; row < height; row++) {
2102 memset (acarry, 0, sizeof acarry);
2103 for (col=0; col < raw_width; col++) {
2104 carry = acarry[col & 1];
2105 i = 2 * (carry[2] < 3);
2106 for (nbits=2+i; (ushort) carry[0] >> (nbits+i); nbits++);
2107 low = (sign = getbits(3)) & 3;
2108 sign = sign << 29 >> 31;
2109 if ((high = getbithuff(12,huff)) == 12)
2110 high = getbits(16-nbits) >> 1;
2111 carry[0] = (high << nbits) | getbits(nbits);
2112 diff = (carry[0] ^ sign) + carry[1];
2113 carry[1] = (diff*3 + carry[1]) >> 5;
2114 carry[2] = carry[0] > 16 ? 0 : carry[2]+1;
2115 if (col >= width) continue;
2116 if (row < 2 && col < 2) pred = 0;
2117 else if (row < 2) pred = RAW(row,col-2);
2118 else if (col < 2) pred = RAW(row-2,col);
2122 nw = RAW(row-2,col-2);
2123 if ((w < nw && nw < n) || (n < nw && nw < w)) {
2124 if (ABS(w-nw) > 32 || ABS(n-nw) > 32)
2126 else pred = (w + n) >> 1;
2127 } else pred = ABS(w-nw) > ABS(n-nw) ? w : n;
2129 if ((RAW(row,col) = pred + ((diff << 2) | low)) >> 12) derror();
2134 void CLASS minolta_rd175_load_raw()
2137 unsigned irow, box, row, col;
2139 for (irow=0; irow < 1481; irow++) {
2140 if (fread (pixel, 1, 768, ifp) < 768) derror();
2142 row = irow % 82 * 12 + ((box < 12) ? box | 1 : (box-12)*2);
2144 case 1477: case 1479: continue;
2145 case 1476: row = 984; break;
2146 case 1480: row = 985; break;
2147 case 1478: row = 985; box = 1;
2149 if ((box < 12) && (box & 1)) {
2150 for (col=0; col < 1533; col++, row ^= 1)
2151 if (col != 1) RAW(row,col) = (col+1) & 2 ?
2152 pixel[col/2-1] + pixel[col/2+1] : pixel[col/2] << 1;
2153 RAW(row,1) = pixel[1] << 1;
2154 RAW(row,1533) = pixel[765] << 1;
2156 for (col=row & 1; col < 1534; col+=2)
2157 RAW(row,col) = pixel[col/2] << 1;
2159 maximum = 0xff << 1;
2162 void CLASS quicktake_100_load_raw()
2164 uchar pixel[484][644];
2165 static const short gstep[16] =
2166 { -89,-60,-44,-32,-22,-15,-8,-2,2,8,15,22,32,44,60,89 };
2167 static const short rstep[6][4] =
2168 { { -3,-1,1,3 }, { -5,-1,1,5 }, { -8,-2,2,8 },
2169 { -13,-3,3,13 }, { -19,-4,4,19 }, { -28,-6,6,28 } };
2170 static const short curve[256] =
2171 { 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,
2172 28,29,30,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,53,
2173 54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,74,75,76,77,78,
2174 79,80,81,82,83,84,86,88,90,92,94,97,99,101,103,105,107,110,112,114,116,
2175 118,120,123,125,127,129,131,134,136,138,140,142,144,147,149,151,153,155,
2176 158,160,162,164,166,168,171,173,175,177,179,181,184,186,188,190,192,195,
2177 197,199,201,203,205,208,210,212,214,216,218,221,223,226,230,235,239,244,
2178 248,252,257,261,265,270,274,278,283,287,291,296,300,305,309,313,318,322,
2179 326,331,335,339,344,348,352,357,361,365,370,374,379,383,387,392,396,400,
2180 405,409,413,418,422,426,431,435,440,444,448,453,457,461,466,470,474,479,
2181 483,487,492,496,500,508,519,531,542,553,564,575,587,598,609,620,631,643,
2182 654,665,676,687,698,710,721,732,743,754,766,777,788,799,810,822,833,844,
2183 855,866,878,889,900,911,922,933,945,956,967,978,989,1001,1012,1023 };
2184 int rb, row, col, sharp, val=0;
2187 memset (pixel, 0x80, sizeof pixel);
2188 for (row=2; row < height+2; row++) {
2189 for (col=2+(row & 1); col < width+2; col+=2) {
2190 val = ((pixel[row-1][col-1] + 2*pixel[row-1][col+1] +
2191 pixel[row][col-2]) >> 2) + gstep[getbits(4)];
2192 pixel[row][col] = val = LIM(val,0,255);
2194 pixel[row][col-2] = pixel[row+1][~row & 1] = val;
2196 pixel[row-1][col+1] = pixel[row-1][col+3] = val;
2198 pixel[row][col] = val;
2200 for (rb=0; rb < 2; rb++)
2201 for (row=2+rb; row < height+2; row+=2)
2202 for (col=3-(row & 1); col < width+2; col+=2) {
2203 if (row < 4 || col < 4) sharp = 2;
2205 val = ABS(pixel[row-2][col] - pixel[row][col-2])
2206 + ABS(pixel[row-2][col] - pixel[row-2][col-2])
2207 + ABS(pixel[row][col-2] - pixel[row-2][col-2]);
2208 sharp = val < 4 ? 0 : val < 8 ? 1 : val < 16 ? 2 :
2209 val < 32 ? 3 : val < 48 ? 4 : 5;
2211 val = ((pixel[row-2][col] + pixel[row][col-2]) >> 1)
2212 + rstep[sharp][getbits(2)];
2213 pixel[row][col] = val = LIM(val,0,255);
2214 if (row < 4) pixel[row-2][col+2] = val;
2215 if (col < 4) pixel[row+2][col-2] = val;
2217 for (row=2; row < height+2; row++)
2218 for (col=3-(row & 1); col < width+2; col+=2) {
2219 val = ((pixel[row][col-1] + (pixel[row][col] << 2) +
2220 pixel[row][col+1]) >> 1) - 0x100;
2221 pixel[row][col] = LIM(val,0,255);
2223 for (row=0; row < height; row++)
2224 for (col=0; col < width; col++)
2225 RAW(row,col) = curve[pixel[row+2][col+2]];
2229 #define radc_token(tree) ((signed char) getbithuff(8,huff[tree]))
2231 #define FORYX for (y=1; y < 3; y++) for (x=col+1; x >= col; x--)
2233 #define PREDICTOR (c ? (buf[c][y-1][x] + buf[c][y][x+1]) / 2 \
2234 : (buf[c][y-1][x+1] + 2*buf[c][y-1][x] + buf[c][y][x+1]) / 4)
2236 void CLASS kodak_radc_load_raw()
2238 static const char src[] = {
2239 1,1, 2,3, 3,4, 4,2, 5,7, 6,5, 7,6, 7,8,
2240 1,0, 2,1, 3,3, 4,4, 5,2, 6,7, 7,6, 8,5, 8,8,
2241 2,1, 2,3, 3,0, 3,2, 3,4, 4,6, 5,5, 6,7, 6,8,
2242 2,0, 2,1, 2,3, 3,2, 4,4, 5,6, 6,7, 7,5, 7,8,
2243 2,1, 2,4, 3,0, 3,2, 3,3, 4,7, 5,5, 6,6, 6,8,
2244 2,3, 3,1, 3,2, 3,4, 3,5, 3,6, 4,7, 5,0, 5,8,
2245 2,3, 2,6, 3,0, 3,1, 4,4, 4,5, 4,7, 5,2, 5,8,
2246 2,4, 2,7, 3,3, 3,6, 4,1, 4,2, 4,5, 5,0, 5,8,
2247 2,6, 3,1, 3,3, 3,5, 3,7, 3,8, 4,0, 5,2, 5,4,
2248 2,0, 2,1, 3,2, 3,3, 4,4, 4,5, 5,6, 5,7, 4,8,
2251 2,-17, 2,-5, 2,5, 2,17,
2252 2,-7, 2,2, 2,9, 2,18,
2253 2,-18, 2,-9, 2,-2, 2,7,
2254 2,-28, 2,28, 3,-49, 3,-9, 3,9, 4,49, 5,-79, 5,79,
2255 2,-1, 2,13, 2,26, 3,39, 4,-16, 5,55, 6,-37, 6,76,
2256 2,-26, 2,-13, 2,1, 3,-39, 4,16, 5,-55, 6,-76, 6,37
2258 ushort huff[19][256];
2259 int row, col, tree, nreps, rep, step, i, c, s, r, x, y, val;
2260 short last[3] = { 16,16,16 }, mul[3], buf[3][3][386];
2261 static const ushort pt[] =
2262 { 0,0, 1280,1344, 2320,3616, 3328,8000, 4095,16383, 65535,16383 };
2264 for (i=2; i < 12; i+=2)
2265 for (c=pt[i-2]; c <= pt[i]; c++)
2267 (c-pt[i-2]) / (pt[i]-pt[i-2]) * (pt[i+1]-pt[i-1]) + pt[i-1] + 0.5;
2268 for (s=i=0; i < sizeof src; i+=2)
2270 ((ushort *)huff)[s++] = src[i] << 8 | (uchar) src[i+1];
2271 s = kodak_cbpp == 243 ? 2 : 3;
2272 FORC(256) huff[18][c] = (8-s) << 8 | c >> s << s | 1 << (s-1);
2274 for (i=0; i < sizeof(buf)/sizeof(short); i++)
2275 ((short *)buf)[i] = 2048;
2276 for (row=0; row < height; row+=4) {
2277 FORC3 mul[c] = getbits(6);
2279 val = ((0x1000000/last[c] + 0x7ff) >> 12) * mul[c];
2280 s = val > 65564 ? 10:12;
2283 for (i=0; i < sizeof(buf[0])/sizeof(short); i++)
2284 ((short *)buf[c])[i] = (((short *)buf[c])[i] * val + x) >> s;
2286 for (r=0; r <= !c; r++) {
2287 buf[c][1][width/2] = buf[c][2][width/2] = mul[c] << 7;
2288 for (tree=1, col=width/2; col > 0; ) {
2289 if ((tree = radc_token(tree))) {
2292 FORYX buf[c][y][x] = (uchar) radc_token(18) * mul[c];
2294 FORYX buf[c][y][x] = radc_token(tree+10) * 16 + PREDICTOR;
2297 nreps = (col > 2) ? radc_token(9) + 1 : 1;
2298 for (rep=0; rep < 8 && rep < nreps && col > 0; rep++) {
2300 FORYX buf[c][y][x] = PREDICTOR;
2302 step = radc_token(10) << 4;
2303 FORYX buf[c][y][x] += step;
2306 } while (nreps == 9);
2308 for (y=0; y < 2; y++)
2309 for (x=0; x < width/2; x++) {
2310 val = (buf[c][y+1][x] << 4) / mul[c];
2311 if (val < 0) val = 0;
2312 if (c) RAW(row+y*2+c-1,x*2+2-c) = val;
2313 else RAW(row+r*2+y,x*2+y) = val;
2315 memcpy (buf[c][0]+!c, buf[c][2], sizeof buf[c][0]-2*!c);
2318 for (y=row; y < row+4; y++)
2319 for (x=0; x < width; x++)
2322 s = x+1 < width ? x+1 : x-1;
2323 val = (RAW(y,x)-2048)*2 + (RAW(y,r)+RAW(y,s))/2;
2324 if (val < 0) val = 0;
2328 for (i=0; i < height*width; i++)
2329 raw_image[i] = curve[raw_image[i]];
2337 void CLASS kodak_jpeg_load_raw() {}
2338 void CLASS lossy_dng_load_raw() {}
2342 fill_input_buffer (j_decompress_ptr cinfo)
2344 static uchar jpeg_buffer[4096];
2347 nbytes = fread (jpeg_buffer, 1, 4096, ifp);
2348 swab (jpeg_buffer, jpeg_buffer, nbytes);
2349 cinfo->src->next_input_byte = jpeg_buffer;
2350 cinfo->src->bytes_in_buffer = nbytes;
2354 void CLASS kodak_jpeg_load_raw()
2356 struct jpeg_decompress_struct cinfo;
2357 struct jpeg_error_mgr jerr;
2359 JSAMPLE (*pixel)[3];
2362 cinfo.err = jpeg_std_error (&jerr);
2363 jpeg_create_decompress (&cinfo);
2364 jpeg_stdio_src (&cinfo, ifp);
2365 cinfo.src->fill_input_buffer = fill_input_buffer;
2366 jpeg_read_header (&cinfo, TRUE);
2367 jpeg_start_decompress (&cinfo);
2368 if ((cinfo.output_width != width ) ||
2369 (cinfo.output_height*2 != height ) ||
2370 (cinfo.output_components != 3 )) {
2371 fprintf (stderr,_("%s: incorrect JPEG dimensions\n"), ifname);
2372 jpeg_destroy_decompress (&cinfo);
2373 longjmp (failure, 3);
2375 buf = (*cinfo.mem->alloc_sarray)
2376 ((j_common_ptr) &cinfo, JPOOL_IMAGE, width*3, 1);
2378 while (cinfo.output_scanline < cinfo.output_height) {
2379 row = cinfo.output_scanline * 2;
2380 jpeg_read_scanlines (&cinfo, buf, 1);
2381 pixel = (JSAMPLE (*)[3]) buf[0];
2382 for (col=0; col < width; col+=2) {
2383 RAW(row+0,col+0) = pixel[col+0][1] << 1;
2384 RAW(row+1,col+1) = pixel[col+1][1] << 1;
2385 RAW(row+0,col+1) = pixel[col][0] + pixel[col+1][0];
2386 RAW(row+1,col+0) = pixel[col][2] + pixel[col+1][2];
2389 jpeg_finish_decompress (&cinfo);
2390 jpeg_destroy_decompress (&cinfo);
2391 maximum = 0xff << 1;
2394 void CLASS gamma_curve (double pwr, double ts, int mode, int imax);
2396 void CLASS lossy_dng_load_raw()
2398 struct jpeg_decompress_struct cinfo;
2399 struct jpeg_error_mgr jerr;
2401 JSAMPLE (*pixel)[3];
2402 unsigned sorder=order, ntags, opcode, deg, i, j, c;
2403 unsigned save=data_offset-4, trow=0, tcol=0, row, col;
2405 double coeff[9], tot;
2408 fseek (ifp, meta_offset, SEEK_SET);
2412 opcode = get4(); get4(); get4();
2414 { fseek (ifp, get4(), SEEK_CUR); continue; }
2415 fseek (ifp, 20, SEEK_CUR);
2416 if ((c = get4()) > 2) break;
2417 fseek (ifp, 12, SEEK_CUR);
2418 if ((deg = get4()) > 8) break;
2419 for (i=0; i <= deg && i < 9; i++)
2420 coeff[i] = getreal(12);
2421 for (i=0; i < 256; i++) {
2422 for (tot=j=0; j <= deg; j++)
2423 tot += coeff[j] * pow(i/255.0, j);
2424 cur[c][i] = tot*0xffff;
2429 gamma_curve (1/2.4, 12.92, 1, 255);
2430 FORC3 memcpy (cur[c], curve, sizeof cur[0]);
2432 cinfo.err = jpeg_std_error (&jerr);
2433 jpeg_create_decompress (&cinfo);
2434 while (trow < raw_height) {
2435 fseek (ifp, save+=4, SEEK_SET);
2436 if (tile_length < INT_MAX)
2437 fseek (ifp, get4(), SEEK_SET);
2438 jpeg_stdio_src (&cinfo, ifp);
2439 jpeg_read_header (&cinfo, TRUE);
2440 jpeg_start_decompress (&cinfo);
2441 buf = (*cinfo.mem->alloc_sarray)
2442 ((j_common_ptr) &cinfo, JPOOL_IMAGE, cinfo.output_width*3, 1);
2443 while (cinfo.output_scanline < cinfo.output_height &&
2444 (row = trow + cinfo.output_scanline) < height) {
2445 jpeg_read_scanlines (&cinfo, buf, 1);
2446 pixel = (JSAMPLE (*)[3]) buf[0];
2447 for (col=0; col < cinfo.output_width && tcol+col < width; col++) {
2448 FORC3 image[row*width+tcol+col][c] = cur[c][pixel[col][c]];
2451 jpeg_abort_decompress (&cinfo);
2452 if ((tcol += tile_width) >= raw_width)
2453 trow += tile_length + (tcol = 0);
2455 jpeg_destroy_decompress (&cinfo);
2460 void CLASS kodak_dc120_load_raw()
2462 static const int mul[4] = { 162, 192, 187, 92 };
2463 static const int add[4] = { 0, 636, 424, 212 };
2465 int row, shift, col;
2467 for (row=0; row < height; row++) {
2468 if (fread (pixel, 1, 848, ifp) < 848) derror();
2469 shift = row * mul[row & 3] + add[row & 3];
2470 for (col=0; col < width; col++)
2471 RAW(row,col) = (ushort) pixel[(col + shift) % 848];
2476 void CLASS eight_bit_load_raw()
2481 pixel = (uchar *) calloc (raw_width, sizeof *pixel);
2482 merror (pixel, "eight_bit_load_raw()");
2483 for (row=0; row < raw_height; row++) {
2484 if (fread (pixel, 1, raw_width, ifp) < raw_width) derror();
2485 for (col=0; col < raw_width; col++)
2486 RAW(row,col) = curve[pixel[col]];
2489 maximum = curve[0xff];
2492 void CLASS kodak_c330_load_raw()
2495 int row, col, y, cb, cr, rgb[3], c;
2497 pixel = (uchar *) calloc (raw_width, 2*sizeof *pixel);
2498 merror (pixel, "kodak_c330_load_raw()");
2499 for (row=0; row < height; row++) {
2500 if (fread (pixel, raw_width, 2, ifp) < 2) derror();
2501 if (load_flags && (row & 31) == 31)
2502 fseek (ifp, raw_width*32, SEEK_CUR);
2503 for (col=0; col < width; col++) {
2505 cb = pixel[(col*2 & -4) | 1] - 128;
2506 cr = pixel[(col*2 & -4) | 3] - 128;
2507 rgb[1] = y - ((cb + cr + 2) >> 2);
2508 rgb[2] = rgb[1] + cb;
2509 rgb[0] = rgb[1] + cr;
2510 FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,255)];
2514 maximum = curve[0xff];
2517 void CLASS kodak_c603_load_raw()
2520 int row, col, y, cb, cr, rgb[3], c;
2522 pixel = (uchar *) calloc (raw_width, 3*sizeof *pixel);
2523 merror (pixel, "kodak_c603_load_raw()");
2524 for (row=0; row < height; row++) {
2526 if (fread (pixel, raw_width, 3, ifp) < 3) derror();
2527 for (col=0; col < width; col++) {
2528 y = pixel[width*2*(row & 1) + col];
2529 cb = pixel[width + (col & -2)] - 128;
2530 cr = pixel[width + (col & -2)+1] - 128;
2531 rgb[1] = y - ((cb + cr + 2) >> 2);
2532 rgb[2] = rgb[1] + cb;
2533 rgb[0] = rgb[1] + cr;
2534 FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,255)];
2538 maximum = curve[0xff];
2541 void CLASS kodak_262_load_raw()
2543 static const uchar kodak_tree[2][26] =
2544 { { 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 },
2545 { 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 } };
2548 int *strip, ns, c, row, col, chess, pi=0, pi1, pi2, pred, val;
2550 FORC(2) huff[c] = make_decoder (kodak_tree[c]);
2551 ns = (raw_height+63) >> 5;
2552 pixel = (uchar *) malloc (raw_width*32 + ns*4);
2553 merror (pixel, "kodak_262_load_raw()");
2554 strip = (int *) (pixel + raw_width*32);
2556 FORC(ns) strip[c] = get4();
2557 for (row=0; row < raw_height; row++) {
2558 if ((row & 31) == 0) {
2559 fseek (ifp, strip[row >> 5], SEEK_SET);
2563 for (col=0; col < raw_width; col++) {
2564 chess = (row + col) & 1;
2565 pi1 = chess ? pi-2 : pi-raw_width-1;
2566 pi2 = chess ? pi-2*raw_width : pi-raw_width+1;
2567 if (col <= chess) pi1 = -1;
2568 if (pi1 < 0) pi1 = pi2;
2569 if (pi2 < 0) pi2 = pi1;
2570 if (pi1 < 0 && col > 1) pi1 = pi2 = pi-2;
2571 pred = (pi1 < 0) ? 0 : (pixel[pi1] + pixel[pi2]) >> 1;
2572 pixel[pi] = val = pred + ljpeg_diff (huff[chess]);
2573 if (val >> 8) derror();
2574 val = curve[pixel[pi++]];
2579 FORC(2) free (huff[c]);
2582 int CLASS kodak_65000_decode (short *out, int bsize)
2587 int save, bits=0, i, j, len, diff;
2590 bsize = (bsize + 3) & -4;
2591 for (i=0; i < bsize; i+=2) {
2593 if ((blen[i ] = c & 15) > 12 ||
2594 (blen[i+1] = c >> 4) > 12 ) {
2595 fseek (ifp, save, SEEK_SET);
2596 for (i=0; i < bsize; i+=8) {
2597 read_shorts (raw, 6);
2598 out[i ] = raw[0] >> 12 << 8 | raw[2] >> 12 << 4 | raw[4] >> 12;
2599 out[i+1] = raw[1] >> 12 << 8 | raw[3] >> 12 << 4 | raw[5] >> 12;
2600 for (j=0; j < 6; j++)
2601 out[i+2+j] = raw[j] & 0xfff;
2606 if ((bsize & 7) == 4) {
2607 bitbuf = fgetc(ifp) << 8;
2608 bitbuf += fgetc(ifp);
2611 for (i=0; i < bsize; i++) {
2614 for (j=0; j < 32; j+=8)
2615 bitbuf += (INT64) fgetc(ifp) << (bits+(j^8));
2618 diff = bitbuf & (0xffff >> (16-len));
2621 if ((diff & (1 << (len-1))) == 0)
2622 diff -= (1 << len) - 1;
2628 void CLASS kodak_65000_load_raw()
2631 int row, col, len, pred[2], ret, i;
2633 for (row=0; row < height; row++)
2634 for (col=0; col < width; col+=256) {
2635 pred[0] = pred[1] = 0;
2636 len = MIN (256, width-col);
2637 ret = kodak_65000_decode (buf, len);
2638 for (i=0; i < len; i++)
2639 if ((RAW(row,col+i) = curve[ret ? buf[i] :
2640 (pred[i & 1] += buf[i])]) >> 12) derror();
2644 void CLASS kodak_ycbcr_load_raw()
2646 short buf[384], *bp;
2647 int row, col, len, c, i, j, k, y[2][2], cb, cr, rgb[3];
2651 for (row=0; row < height; row+=2)
2652 for (col=0; col < width; col+=128) {
2653 len = MIN (128, width-col);
2654 kodak_65000_decode (buf, len*3);
2655 y[0][1] = y[1][1] = cb = cr = 0;
2656 for (bp=buf, i=0; i < len; i+=2, bp+=2) {
2659 rgb[1] = -((cb + cr + 2) >> 2);
2660 rgb[2] = rgb[1] + cb;
2661 rgb[0] = rgb[1] + cr;
2662 for (j=0; j < 2; j++)
2663 for (k=0; k < 2; k++) {
2664 if ((y[j][k] = y[j][k^1] + *bp++) >> 10) derror();
2665 ip = image[(row+j)*width + col+i+k];
2666 FORC3 ip[c] = curve[LIM(y[j][k]+rgb[c], 0, 0xfff)];
2672 void CLASS kodak_rgb_load_raw()
2674 short buf[768], *bp;
2675 int row, col, len, c, i, rgb[3];
2676 ushort *ip=image[0];
2678 for (row=0; row < height; row++)
2679 for (col=0; col < width; col+=256) {
2680 len = MIN (256, width-col);
2681 kodak_65000_decode (buf, len*3);
2682 memset (rgb, 0, sizeof rgb);
2683 for (bp=buf, i=0; i < len; i++, ip+=4)
2684 FORC3 if ((ip[c] = rgb[c] += *bp++) >> 12) derror();
2688 void CLASS kodak_thumb_load_raw()
2691 colors = thumb_misc >> 5;
2692 for (row=0; row < height; row++)
2693 for (col=0; col < width; col++)
2694 read_shorts (image[row*width+col], colors);
2695 maximum = (1 << (thumb_misc & 31)) - 1;
2698 void CLASS sony_decrypt (unsigned *data, int len, int start, int key)
2700 static unsigned pad[128], p;
2703 for (p=0; p < 4; p++)
2704 pad[p] = key = key * 48828125 + 1;
2705 pad[3] = pad[3] << 1 | (pad[0]^pad[2]) >> 31;
2706 for (p=4; p < 127; p++)
2707 pad[p] = (pad[p-4]^pad[p-2]) << 1 | (pad[p-3]^pad[p-1]) >> 31;
2708 for (p=0; p < 127; p++)
2709 pad[p] = htonl(pad[p]);
2711 while (len-- && p++)
2712 *data++ ^= pad[(p-1) & 127] = pad[p & 127] ^ pad[(p+64) & 127];
2715 void CLASS sony_load_raw()
2719 unsigned i, key, row, col;
2721 fseek (ifp, 200896, SEEK_SET);
2722 fseek (ifp, (unsigned) fgetc(ifp)*4 - 1, SEEK_CUR);
2725 fseek (ifp, 164600, SEEK_SET);
2726 fread (head, 1, 40, ifp);
2727 sony_decrypt ((unsigned *) head, 10, 1, key);
2728 for (i=26; i-- > 22; )
2729 key = key << 8 | head[i];
2730 fseek (ifp, data_offset, SEEK_SET);
2731 for (row=0; row < raw_height; row++) {
2732 pixel = raw_image + row*raw_width;
2733 if (fread (pixel, 2, raw_width, ifp) < raw_width) derror();
2734 sony_decrypt ((unsigned *) pixel, raw_width/2, !row, key);
2735 for (col=0; col < raw_width; col++)
2736 if ((pixel[col] = ntohs(pixel[col])) >> 14) derror();
2741 void CLASS sony_arw_load_raw()
2744 static const ushort tab[18] =
2745 { 0xf11,0xf10,0xe0f,0xd0e,0xc0d,0xb0c,0xa0b,0x90a,0x809,
2746 0x708,0x607,0x506,0x405,0x304,0x303,0x300,0x202,0x201 };
2747 int i, c, n, col, row, sum=0;
2750 for (n=i=0; i < 18; i++)
2751 FORC(32768 >> (tab[i] >> 8)) huff[++n] = tab[i];
2753 for (col = raw_width; col--; )
2754 for (row=0; row < raw_height+1; row+=2) {
2755 if (row == raw_height) row = 1;
2756 if ((sum += ljpeg_diff(huff)) >> 12) derror();
2757 if (row < height) RAW(row,col) = sum;
2761 void CLASS sony_arw2_load_raw()
2765 int row, col, val, max, min, imax, imin, sh, bit, i;
2767 data = (uchar *) malloc (raw_width+1);
2768 merror (data, "sony_arw2_load_raw()");
2769 for (row=0; row < height; row++) {
2770 fread (data, 1, raw_width, ifp);
2771 for (dp=data, col=0; col < raw_width-30; dp+=16) {
2772 max = 0x7ff & (val = sget4(dp));
2773 min = 0x7ff & val >> 11;
2774 imax = 0x0f & val >> 22;
2775 imin = 0x0f & val >> 26;
2776 for (sh=0; sh < 4 && 0x80 << sh <= max-min; sh++);
2777 for (bit=30, i=0; i < 16; i++)
2778 if (i == imax) pix[i] = max;
2779 else if (i == imin) pix[i] = min;
2781 pix[i] = ((sget2(dp+(bit >> 3)) >> (bit & 7) & 0x7f) << sh) + min;
2782 if (pix[i] > 0x7ff) pix[i] = 0x7ff;
2785 for (i=0; i < 16; i++, col+=2)
2786 RAW(row,col) = curve[pix[i] << 1] >> 2;
2787 col -= col & 1 ? 1:31;
2793 void CLASS samsung_load_raw()
2795 int row, col, c, i, dir, op[4], len[4];
2798 for (row=0; row < raw_height; row++) {
2799 fseek (ifp, strip_offset+row*4, SEEK_SET);
2800 fseek (ifp, data_offset+get4(), SEEK_SET);
2802 FORC4 len[c] = row < 2 ? 7:4;
2803 for (col=0; col < raw_width; col+=16) {
2805 FORC4 op[c] = ph1_bits(2);
2806 FORC4 switch (op[c]) {
2807 case 3: len[c] = ph1_bits(4); break;
2808 case 2: len[c]--; break;
2811 for (c=0; c < 16; c+=2) {
2812 i = len[((c & 1) << 1) | (c >> 3)];
2813 RAW(row,col+c) = ((signed) ph1_bits(i) << (32-i) >> (32-i)) +
2814 (dir ? RAW(row+(~c | -2),col+c) : col ? RAW(row,col+(c | -2)) : 128);
2815 if (c == 14) c = -1;
2819 for (row=0; row < raw_height-1; row+=2)
2820 for (col=0; col < raw_width-1; col+=2)
2821 SWAP (RAW(row,col+1), RAW(row+1,col));
2824 void CLASS samsung2_load_raw()
2826 static const ushort tab[14] =
2827 { 0x304,0x307,0x206,0x205,0x403,0x600,0x709,
2828 0x80a,0x90b,0xa0c,0xa0d,0x501,0x408,0x402 };
2829 ushort huff[1026], vpred[2][2] = {{0,0},{0,0}}, hpred[2];
2830 int i, c, n, row, col, diff;
2833 for (n=i=0; i < 14; i++)
2834 FORC(1024 >> (tab[i] >> 8)) huff[++n] = tab[i];
2836 for (row=0; row < raw_height; row++)
2837 for (col=0; col < raw_width; col++) {
2838 diff = ljpeg_diff (huff);
2839 if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
2840 else hpred[col & 1] += diff;
2841 RAW(row,col) = hpred[col & 1];
2842 if (hpred[col & 1] >> tiff_bps) derror();
2846 void CLASS samsung3_load_raw()
2848 int opt, init, mag, pmode, row, tab, col, pred, diff, i, c;
2849 ushort lent[3][2], len[4], *prow[2];
2852 fseek (ifp, 9, SEEK_CUR);
2854 init = (get2(),get2());
2855 for (row=0; row < raw_height; row++) {
2856 fseek (ifp, (data_offset-ftell(ifp)) & 15, SEEK_CUR);
2859 FORC(6) ((ushort *)lent)[c] = row < 2 ? 7:4;
2860 prow[ row & 1] = &RAW(row-1,1-((row & 1) << 1)); // green
2861 prow[~row & 1] = &RAW(row-2,0); // red and blue
2862 for (tab=0; tab+15 < raw_width; tab+=16) {
2863 if (~opt & 4 && !(tab & 63)) {
2865 mag = i < 3 ? mag-'2'+"204"[i] : ph1_bits(12);
2868 pmode = 7 - 4*ph1_bits(1);
2869 else if (!ph1_bits(1))
2870 pmode = ph1_bits(3);
2871 if (opt & 1 || !ph1_bits(1)) {
2872 FORC4 len[c] = ph1_bits(2);
2874 i = ((row & 1) << 1 | (c & 1)) % 3;
2875 len[c] = len[c] < 3 ? lent[i][0]-'1'+"120"[len[c]] : ph1_bits(4);
2876 lent[i][0] = lent[i][1];
2877 lent[i][1] = len[c];
2881 col = tab + (((c & 7) << 1)^(c >> 3)^(row & 1));
2882 pred = (pmode == 7 || row < 2)
2883 ? (tab ? RAW(row,tab-2+(col & 1)) : init)
2884 : (prow[col & 1][col-'4'+"0224468"[pmode]] +
2885 prow[col & 1][col-'4'+"0244668"[pmode]] + 1) >> 1;
2886 diff = ph1_bits (i = len[c >> 2]);
2887 if (diff >> (i-1)) diff -= 1 << i;
2888 diff = diff * (mag*2+1) + mag;
2889 RAW(row,col) = pred + diff;
2895 #define HOLE(row) ((holes >> (((row) - raw_height) & 7)) & 1)
2897 /* Kudos to Rich Taylor for figuring out SMaL's compression algorithm. */
2898 void CLASS smal_decode_segment (unsigned seg[2][2], int holes)
2901 uchar hist[3][18] = {
2902 { 7, 7, 0, 0, 63, 55, 47, 39, 31, 23, 15, 7, 0 },
2903 { 7, 7, 0, 0, 63, 55, 47, 39, 31, 23, 15, 7, 0 },
2904 { 3, 3, 0, 0, 63, 47, 31, 15, 0 } };
2905 int low, high=0xff, carry=0, nbits=8;
2906 int pix, s, count, bin, next, i, sym[3];
2907 uchar diff, pred[]={0,0};
2908 ushort data=0, range=0;
2910 fseek (ifp, seg[0][1]+1, SEEK_SET);
2912 if (seg[1][0] > raw_width*raw_height)
2913 seg[1][0] = raw_width*raw_height;
2914 for (pix=seg[0][0]; pix < seg[1][0]; pix++) {
2915 for (s=0; s < 3; s++) {
2916 data = data << nbits | getbits(nbits);
2918 carry = (nbits += carry+1) < 1 ? nbits-1 : 0;
2919 while (--nbits >= 0)
2920 if ((data >> nbits & 0xff) == 0xff) break;
2922 data = ((data & ((1 << (nbits-1)) - 1)) << 1) |
2923 ((data + (((data & (1 << (nbits-1)))) << 1)) & (-1 << nbits));
2928 count = ((((data-range+1) & 0xffff) << 2) - 1) / (high >> 4);
2929 for (bin=0; hist[s][bin+5] > count; bin++);
2930 low = hist[s][bin+5] * (high >> 4) >> 2;
2931 if (bin) high = hist[s][bin+4] * (high >> 4) >> 2;
2933 for (nbits=0; high << nbits < 128; nbits++);
2934 range = (range+low) << nbits;
2937 if (++hist[s][2] > hist[s][3]) {
2938 next = (next+1) & hist[s][0];
2939 hist[s][3] = (hist[s][next+4] - hist[s][next+5]) >> 2;
2942 if (hist[s][hist[s][1]+4] - hist[s][hist[s][1]+5] > 1) {
2943 if (bin < hist[s][1])
2944 for (i=bin; i < hist[s][1]; i++) hist[s][i+5]--;
2945 else if (next <= bin)
2946 for (i=hist[s][1]; i < bin; i++) hist[s][i+5]++;
2951 diff = sym[2] << 5 | sym[1] << 2 | (sym[0] & 3);
2953 diff = diff ? -diff : 0x80;
2954 if (ftell(ifp) + 12 >= seg[1][1])
2956 raw_image[pix] = pred[pix & 1] += diff;
2957 if (!(pix & 1) && HOLE(pix / raw_width)) pix += 2;
2962 void CLASS smal_v6_load_raw()
2966 fseek (ifp, 16, SEEK_SET);
2969 seg[1][0] = raw_width * raw_height;
2970 seg[1][1] = INT_MAX;
2971 smal_decode_segment (seg, 0);
2974 int CLASS median4 (int *p)
2976 int min, max, sum, i;
2978 min = max = sum = p[0];
2979 for (i=1; i < 4; i++) {
2981 if (min > p[i]) min = p[i];
2982 if (max < p[i]) max = p[i];
2984 return (sum - min - max) >> 1;
2987 void CLASS fill_holes (int holes)
2989 int row, col, val[4];
2991 for (row=2; row < height-2; row++) {
2992 if (!HOLE(row)) continue;
2993 for (col=1; col < width-1; col+=4) {
2994 val[0] = RAW(row-1,col-1);
2995 val[1] = RAW(row-1,col+1);
2996 val[2] = RAW(row+1,col-1);
2997 val[3] = RAW(row+1,col+1);
2998 RAW(row,col) = median4(val);
3000 for (col=2; col < width-2; col+=4)
3001 if (HOLE(row-2) || HOLE(row+2))
3002 RAW(row,col) = (RAW(row,col-2) + RAW(row,col+2)) >> 1;
3004 val[0] = RAW(row,col-2);
3005 val[1] = RAW(row,col+2);
3006 val[2] = RAW(row-2,col);
3007 val[3] = RAW(row+2,col);
3008 RAW(row,col) = median4(val);
3013 void CLASS smal_v9_load_raw()
3015 unsigned seg[256][2], offset, nseg, holes, i;
3017 fseek (ifp, 67, SEEK_SET);
3019 nseg = (uchar) fgetc(ifp);
3020 fseek (ifp, offset, SEEK_SET);
3021 for (i=0; i < nseg*2; i++)
3022 ((unsigned *)seg)[i] = get4() + data_offset*(i & 1);
3023 fseek (ifp, 78, SEEK_SET);
3025 fseek (ifp, 88, SEEK_SET);
3026 seg[nseg][0] = raw_height * raw_width;
3027 seg[nseg][1] = get4() + data_offset;
3028 for (i=0; i < nseg; i++)
3029 smal_decode_segment (seg+i, holes);
3030 if (holes) fill_holes (holes);
3033 void CLASS redcine_load_raw()
3044 in = jas_stream_fopen (ifname, "rb");
3045 jas_stream_seek (in, data_offset+20, SEEK_SET);
3046 jimg = jas_image_decode (in, -1, 0);
3047 if (!jimg) longjmp (failure, 3);
3048 jmat = jas_matrix_create (height/2, width/2);
3049 merror (jmat, "redcine_load_raw()");
3050 img = (ushort *) calloc ((height+2), (width+2)*2);
3051 merror (img, "redcine_load_raw()");
3053 jas_image_readcmpt (jimg, c, 0, 0, width/2, height/2, jmat);
3054 data = jas_matrix_getref (jmat, 0, 0);
3055 for (row = c >> 1; row < height; row+=2)
3056 for (col = c & 1; col < width; col+=2)
3057 img[(row+1)*(width+2)+col+1] = data[(row/2)*(width/2)+col/2];
3059 for (col=1; col <= width; col++) {
3060 img[col] = img[2*(width+2)+col];
3061 img[(height+1)*(width+2)+col] = img[(height-1)*(width+2)+col];
3063 for (row=0; row < height+2; row++) {
3064 img[row*(width+2)] = img[row*(width+2)+2];
3065 img[(row+1)*(width+2)-1] = img[(row+1)*(width+2)-3];
3067 for (row=1; row <= height; row++) {
3068 pix = img + row*(width+2) + (col = 1 + (FC(row,1) & 1));
3069 for ( ; col <= width; col+=2, pix+=2) {
3070 c = (((pix[0] - 0x800) << 3) +
3071 pix[-(width+2)] + pix[width+2] + pix[-1] + pix[1]) >> 2;
3072 pix[0] = LIM(c,0,4095);
3075 for (row=0; row < height; row++)
3076 for (col=0; col < width; col++)
3077 RAW(row,col) = curve[img[(row+1)*(width+2)+col+1]];
3079 jas_matrix_destroy (jmat);
3080 jas_image_destroy (jimg);
3081 jas_stream_close (in);
3085 /* RESTRICTED code starts here */
3087 void CLASS foveon_decoder (unsigned size, unsigned code)
3089 static unsigned huff[1024];
3094 for (i=0; i < size; i++)
3096 memset (first_decode, 0, sizeof first_decode);
3097 free_decode = first_decode;
3099 cur = free_decode++;
3100 if (free_decode > first_decode+2048) {
3101 fprintf (stderr,_("%s: decoder table overflow\n"), ifname);
3102 longjmp (failure, 2);
3105 for (i=0; i < size; i++)
3106 if (huff[i] == code) {
3110 if ((len = code >> 27) > 26) return;
3111 code = (len+1) << 27 | (code & 0x3ffffff) << 1;
3113 cur->branch[0] = free_decode;
3114 foveon_decoder (size, code);
3115 cur->branch[1] = free_decode;
3116 foveon_decoder (size, code+1);
3119 void CLASS foveon_thumb()
3121 unsigned bwide, row, col, bitbuf=0, bit=1, c, i;
3123 struct decode *dindex;
3127 fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
3129 if (bwide < thumb_width*3) return;
3130 buf = (char *) malloc (bwide);
3131 merror (buf, "foveon_thumb()");
3132 for (row=0; row < thumb_height; row++) {
3133 fread (buf, 1, bwide, ifp);
3134 fwrite (buf, 3, thumb_width, ofp);
3139 foveon_decoder (256, 0);
3141 for (row=0; row < thumb_height; row++) {
3142 memset (pred, 0, sizeof pred);
3144 for (bit=col=0; col < thumb_width; col++)
3146 for (dindex=first_decode; dindex->branch[0]; ) {
3147 if ((bit = (bit-1) & 31) == 31)
3148 for (i=0; i < 4; i++)
3149 bitbuf = (bitbuf << 8) + fgetc(ifp);
3150 dindex = dindex->branch[bitbuf >> bit & 1];
3152 pred[c] += dindex->leaf;
3153 fputc (pred[c], ofp);
3158 void CLASS foveon_sd_load_raw()
3160 struct decode *dindex;
3163 int pred[3], row, col, bit=-1, c, i;
3165 read_shorts ((ushort *) diff, 1024);
3166 if (!load_flags) foveon_decoder (1024, 0);
3168 for (row=0; row < height; row++) {
3169 memset (pred, 0, sizeof pred);
3170 if (!bit && !load_flags && atoi(model+2) < 14) get4();
3171 for (col=bit=0; col < width; col++) {
3174 FORC3 pred[2-c] += diff[bitbuf >> c*10 & 0x3ff];
3177 for (dindex=first_decode; dindex->branch[0]; ) {
3178 if ((bit = (bit-1) & 31) == 31)
3179 for (i=0; i < 4; i++)
3180 bitbuf = (bitbuf << 8) + fgetc(ifp);
3181 dindex = dindex->branch[bitbuf >> bit & 1];
3183 pred[c] += diff[dindex->leaf];
3184 if (pred[c] >> 16 && ~pred[c] >> 16) derror();
3186 FORC3 image[row*width+col][c] = pred[c];
3191 void CLASS foveon_huff (ushort *huff)
3193 int i, j, clen, code;
3196 for (i=0; i < 13; i++) {
3199 for (j=0; j < 256 >> clen; )
3200 huff[code+ ++j] = clen << 8 | i;
3205 void CLASS foveon_dp_load_raw()
3207 unsigned c, roff[4], row, col, diff;
3208 ushort huff[512], vpred[2][2], hpred[2];
3210 fseek (ifp, 8, SEEK_CUR);
3213 FORC3 roff[c+1] = -(-(roff[c] + get4()) & -16);
3215 fseek (ifp, data_offset+roff[c], SEEK_SET);
3217 vpred[0][0] = vpred[0][1] = vpred[1][0] = vpred[1][1] = 512;
3218 for (row=0; row < height; row++) {
3219 for (col=0; col < width; col++) {
3220 diff = ljpeg_diff(huff);
3221 if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
3222 else hpred[col & 1] += diff;
3223 image[row*width+col][c] = hpred[col & 1];
3229 void CLASS foveon_load_camf()
3231 unsigned type, wide, high, i, j, row, col, diff;
3232 ushort huff[258], vpred[2][2] = {{512,512},{512,512}}, hpred[2];
3234 fseek (ifp, meta_offset, SEEK_SET);
3235 type = get4(); get4(); get4();
3239 fread (meta_data, 1, meta_length, ifp);
3240 for (i=0; i < meta_length; i++) {
3241 high = (high * 1597 + 51749) % 244944;
3242 wide = high * (INT64) 301593171 >> 24;
3243 meta_data[i] ^= ((((high << 8) - wide) >> 1) + wide) >> 17;
3245 } else if (type == 4) {
3247 meta_data = (char *) malloc (meta_length = wide*high*3/2);
3248 merror (meta_data, "foveon_load_camf()");
3252 for (j=row=0; row < high; row++) {
3253 for (col=0; col < wide; col++) {
3254 diff = ljpeg_diff(huff);
3255 if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
3256 else hpred[col & 1] += diff;
3258 meta_data[j++] = hpred[0] >> 4;
3259 meta_data[j++] = hpred[0] << 4 | hpred[1] >> 8;
3260 meta_data[j++] = hpred[1];
3265 fprintf (stderr,_("%s has unknown CAMF type %d.\n"), ifname, type);
3268 const char * CLASS foveon_camf_param (const char *block, const char *param)
3271 char *pos, *cp, *dp;
3273 for (idx=0; idx < meta_length; idx += sget4(pos+8)) {
3274 pos = meta_data + idx;
3275 if (strncmp (pos, "CMb", 3)) break;
3276 if (pos[3] != 'P') continue;
3277 if (strcmp (block, pos+sget4(pos+12))) continue;
3278 cp = pos + sget4(pos+16);
3280 dp = pos + sget4(cp+4);
3283 if (!strcmp (param, dp+sget4(cp)))
3284 return dp+sget4(cp+4);
3290 void * CLASS foveon_camf_matrix (unsigned dim[3], const char *name)
3292 unsigned i, idx, type, ndim, size, *mat;
3293 char *pos, *cp, *dp;
3296 for (idx=0; idx < meta_length; idx += sget4(pos+8)) {
3297 pos = meta_data + idx;
3298 if (strncmp (pos, "CMb", 3)) break;
3299 if (pos[3] != 'M') continue;
3300 if (strcmp (name, pos+sget4(pos+12))) continue;
3301 dim[0] = dim[1] = dim[2] = 1;
3302 cp = pos + sget4(pos+16);
3304 if ((ndim = sget4(cp+4)) > 3) break;
3305 dp = pos + sget4(cp+8);
3306 for (i=ndim; i--; ) {
3310 if ((dsize = (double) dim[0]*dim[1]*dim[2]) > meta_length/4) break;
3311 mat = (unsigned *) malloc ((size = dsize) * 4);
3312 merror (mat, "foveon_camf_matrix()");
3313 for (i=0; i < size; i++)
3314 if (type && type != 6)
3315 mat[i] = sget4(dp + i*4);
3317 mat[i] = sget4(dp + i*2) & 0xffff;
3320 fprintf (stderr,_("%s: \"%s\" matrix not found!\n"), ifname, name);
3324 int CLASS foveon_fixed (void *ptr, int size, const char *name)
3329 memset (ptr, 0, size*4);
3330 if (!name) return 0;
3331 dp = foveon_camf_matrix (dim, name);
3333 memcpy (ptr, dp, size*4);
3338 float CLASS foveon_avg (short *pix, int range[2], float cfilt)
3341 float val, min=FLT_MAX, max=-FLT_MAX, sum=0;
3343 for (i=range[0]; i <= range[1]; i++) {
3344 sum += val = pix[i*4] + (pix[i*4]-pix[(i-1)*4]) * cfilt;
3345 if (min > val) min = val;
3346 if (max < val) max = val;
3348 if (range[1] - range[0] == 1) return sum/2;
3349 return (sum - min - max) / (range[1] - range[0] - 1);
3352 short * CLASS foveon_make_curve (double max, double mul, double filt)
3358 if (!filt) filt = 0.8;
3359 size = 4*M_PI*max / filt;
3360 if (size == UINT_MAX) size--;
3361 curve = (short *) calloc (size+1, sizeof *curve);
3362 merror (curve, "foveon_make_curve()");
3364 for (i=0; i < size; i++) {
3366 curve[i+1] = (cos(x)+1)/2 * tanh(i*filt/mul) * mul + 0.5;
3371 void CLASS foveon_make_curves
3372 (short **curvep, float dq[3], float div[3], float filt)
3374 double mul[3], max=0;
3377 FORC3 mul[c] = dq[c]/div[c];
3378 FORC3 if (max < mul[c]) max = mul[c];
3379 FORC3 curvep[c] = foveon_make_curve (max, mul[c], filt);
3382 int CLASS foveon_apply_curve (short *curve, int i)
3384 if (abs(i) >= curve[0]) return 0;
3385 return i < 0 ? -curve[1-i] : curve[1+i];
3388 #define image ((short (*)[4]) image)
3390 void CLASS foveon_interpolate()
3392 static const short hood[] = { -1,-1, -1,0, -1,1, 0,-1, 0,1, 1,-1, 1,0, 1,1 };
3393 short *pix, prev[3], *curve[8], (*shrink)[3];
3394 float cfilt=0, ddft[3][3][2], ppm[3][3][3];
3395 float cam_xyz[3][3], correct[3][3], last[3][3], trans[3][3];
3396 float chroma_dq[3], color_dq[3], diag[3][3], div[3];
3397 float (*black)[3], (*sgain)[3], (*sgrow)[3];
3398 float fsum[3], val, frow, num;
3399 int row, col, c, i, j, diff, sgx, irow, sum, min, max, limit;
3400 int dscr[2][2], dstb[4], (*smrow[7])[3], total[4], ipix[3];
3401 int work[3][3], smlast, smred, smred_p=0, dev[3];
3402 int satlev[3], keep[4], active[4];
3403 unsigned dim[3], *badpix;
3404 double dsum=0, trsum[3];
3409 fprintf (stderr,_("Foveon interpolation...\n"));
3412 foveon_fixed (dscr, 4, "DarkShieldColRange");
3413 foveon_fixed (ppm[0][0], 27, "PostPolyMatrix");
3414 foveon_fixed (satlev, 3, "SaturationLevel");
3415 foveon_fixed (keep, 4, "KeepImageArea");
3416 foveon_fixed (active, 4, "ActiveImageArea");
3417 foveon_fixed (chroma_dq, 3, "ChromaDQ");
3418 foveon_fixed (color_dq, 3,
3419 foveon_camf_param ("IncludeBlocks", "ColorDQ") ?
3420 "ColorDQ" : "ColorDQCamRGB");
3421 if (foveon_camf_param ("IncludeBlocks", "ColumnFilter"))
3422 foveon_fixed (&cfilt, 1, "ColumnFilter");
3424 memset (ddft, 0, sizeof ddft);
3425 if (!foveon_camf_param ("IncludeBlocks", "DarkDrift")
3426 || !foveon_fixed (ddft[1][0], 12, "DarkDrift"))
3427 for (i=0; i < 2; i++) {
3428 foveon_fixed (dstb, 4, i ? "DarkShieldBottom":"DarkShieldTop");
3429 for (row = dstb[1]; row <= dstb[3]; row++)
3430 for (col = dstb[0]; col <= dstb[2]; col++)
3431 FORC3 ddft[i+1][c][1] += (short) image[row*width+col][c];
3432 FORC3 ddft[i+1][c][1] /= (dstb[3]-dstb[1]+1) * (dstb[2]-dstb[0]+1);
3435 if (!(cp = foveon_camf_param ("WhiteBalanceIlluminants", model2)))
3436 { fprintf (stderr,_("%s: Invalid white balance \"%s\"\n"), ifname, model2);
3438 foveon_fixed (cam_xyz, 9, cp);
3439 foveon_fixed (correct, 9,
3440 foveon_camf_param ("WhiteBalanceCorrections", model2));
3441 memset (last, 0, sizeof last);
3442 for (i=0; i < 3; i++)
3443 for (j=0; j < 3; j++)
3444 FORC3 last[i][j] += correct[i][c] * cam_xyz[c][j];
3446 #define LAST(x,y) last[(i+x)%3][(c+y)%3]
3447 for (i=0; i < 3; i++)
3448 FORC3 diag[c][i] = LAST(1,1)*LAST(2,2) - LAST(1,2)*LAST(2,1);
3450 FORC3 div[c] = diag[c][0]*0.3127 + diag[c][1]*0.329 + diag[c][2]*0.3583;
3451 sprintf (str, "%sRGBNeutral", model2);
3452 if (foveon_camf_param ("IncludeBlocks", str))
3453 foveon_fixed (div, 3, str);
3455 FORC3 if (num < div[c]) num = div[c];
3456 FORC3 div[c] /= num;
3458 memset (trans, 0, sizeof trans);
3459 for (i=0; i < 3; i++)
3460 for (j=0; j < 3; j++)
3461 FORC3 trans[i][j] += rgb_cam[i][c] * last[c][j] * div[j];
3462 FORC3 trsum[c] = trans[c][0] + trans[c][1] + trans[c][2];
3463 dsum = (6*trsum[0] + 11*trsum[1] + 3*trsum[2]) / 20;
3464 for (i=0; i < 3; i++)
3465 FORC3 last[i][c] = trans[i][c] * dsum / trsum[i];
3466 memset (trans, 0, sizeof trans);
3467 for (i=0; i < 3; i++)
3468 for (j=0; j < 3; j++)
3469 FORC3 trans[i][j] += (i==c ? 32 : -1) * last[c][j] / 30;
3471 foveon_make_curves (curve, color_dq, div, cfilt);
3472 FORC3 chroma_dq[c] /= 3;
3473 foveon_make_curves (curve+3, chroma_dq, div, cfilt);
3474 FORC3 dsum += chroma_dq[c] / div[c];
3475 curve[6] = foveon_make_curve (dsum, dsum, cfilt);
3476 curve[7] = foveon_make_curve (dsum*2, dsum*2, cfilt);
3478 sgain = (float (*)[3]) foveon_camf_matrix (dim, "SpatialGain");
3480 sgrow = (float (*)[3]) calloc (dim[1], sizeof *sgrow);
3481 sgx = (width + dim[1]-2) / (dim[1]-1);
3483 black = (float (*)[3]) calloc (height, sizeof *black);
3484 for (row=0; row < height; row++) {
3485 for (i=0; i < 6; i++)
3486 ((float *)ddft[0])[i] = ((float *)ddft[1])[i] +
3487 row / (height-1.0) * (((float *)ddft[2])[i] - ((float *)ddft[1])[i]);
3488 FORC3 black[row][c] =
3489 ( foveon_avg (image[row*width]+c, dscr[0], cfilt) +
3490 foveon_avg (image[row*width]+c, dscr[1], cfilt) * 3
3491 - ddft[0][c][0] ) / 4 - ddft[0][c][1];
3493 memcpy (black, black+8, sizeof *black*8);
3494 memcpy (black+height-11, black+height-22, 11*sizeof *black);
3495 memcpy (last, black, sizeof last);
3497 for (row=1; row < height-1; row++) {
3498 FORC3 if (last[1][c] > last[0][c]) {
3499 if (last[1][c] > last[2][c])
3500 black[row][c] = (last[0][c] > last[2][c]) ? last[0][c]:last[2][c];
3502 if (last[1][c] < last[2][c])
3503 black[row][c] = (last[0][c] < last[2][c]) ? last[0][c]:last[2][c];
3504 memmove (last, last+1, 2*sizeof last[0]);
3505 memcpy (last[2], black[row+1], sizeof last[2]);
3507 FORC3 black[row][c] = (last[0][c] + last[1][c])/2;
3508 FORC3 black[0][c] = (black[1][c] + black[3][c])/2;
3510 val = 1 - exp(-1/24.0);
3511 memcpy (fsum, black, sizeof fsum);
3512 for (row=1; row < height; row++)
3513 FORC3 fsum[c] += black[row][c] =
3514 (black[row][c] - black[row-1][c])*val + black[row-1][c];
3515 memcpy (last[0], black[height-1], sizeof last[0]);
3516 FORC3 fsum[c] /= height;
3517 for (row = height; row--; )
3518 FORC3 last[0][c] = black[row][c] =
3519 (black[row][c] - fsum[c] - last[0][c])*val + last[0][c];
3521 memset (total, 0, sizeof total);
3522 for (row=2; row < height; row+=4)
3523 for (col=2; col < width; col+=4) {
3524 FORC3 total[c] += (short) image[row*width+col][c];
3527 for (row=0; row < height; row++)
3528 FORC3 black[row][c] += fsum[c]/2 + total[c]/(total[3]*100.0);
3530 for (row=0; row < height; row++) {
3531 for (i=0; i < 6; i++)
3532 ((float *)ddft[0])[i] = ((float *)ddft[1])[i] +
3533 row / (height-1.0) * (((float *)ddft[2])[i] - ((float *)ddft[1])[i]);
3534 pix = image[row*width];
3535 memcpy (prev, pix, sizeof prev);
3536 frow = row / (height-1.0) * (dim[2]-1);
3537 if ((irow = frow) == dim[2]-1) irow--;
3539 for (i=0; i < dim[1]; i++)
3540 FORC3 sgrow[i][c] = sgain[ irow *dim[1]+i][c] * (1-frow) +
3541 sgain[(irow+1)*dim[1]+i][c] * frow;
3542 for (col=0; col < width; col++) {
3544 diff = pix[c] - prev[c];
3546 ipix[c] = pix[c] + floor ((diff + (diff*diff >> 14)) * cfilt
3547 - ddft[0][c][1] - ddft[0][c][0] * ((float) col/width - 0.5)
3551 work[0][c] = ipix[c] * ipix[c] >> 14;
3552 work[2][c] = ipix[c] * work[0][c] >> 14;
3553 work[1][2-c] = ipix[(c+1) % 3] * ipix[(c+2) % 3] >> 14;
3556 for (val=i=0; i < 3; i++)
3557 for ( j=0; j < 3; j++)
3558 val += ppm[c][i][j] * work[i][j];
3559 ipix[c] = floor ((ipix[c] + floor(val)) *
3560 ( sgrow[col/sgx ][c] * (sgx - col%sgx) +
3561 sgrow[col/sgx+1][c] * (col%sgx) ) / sgx / div[c]);
3562 if (ipix[c] > 32000) ipix[c] = 32000;
3572 if ((badpix = (unsigned *) foveon_camf_matrix (dim, "BadPixels"))) {
3573 for (i=0; i < dim[0]; i++) {
3574 col = (badpix[i] >> 8 & 0xfff) - keep[0];
3575 row = (badpix[i] >> 20 ) - keep[1];
3576 if ((unsigned)(row-1) > height-3 || (unsigned)(col-1) > width-3)
3578 memset (fsum, 0, sizeof fsum);
3579 for (sum=j=0; j < 8; j++)
3580 if (badpix[i] & (1 << j)) {
3581 FORC3 fsum[c] += (short)
3582 image[(row+hood[j*2])*width+col+hood[j*2+1]][c];
3585 if (sum) FORC3 image[row*width+col][c] = fsum[c]/sum;
3590 /* Array for 5x5 Gaussian averaging of red values */
3591 smrow[6] = (int (*)[3]) calloc (width*5, sizeof **smrow);
3592 merror (smrow[6], "foveon_interpolate()");
3593 for (i=0; i < 5; i++)
3594 smrow[i] = smrow[6] + i*width;
3596 /* Sharpen the reds against these Gaussian averages */
3597 for (smlast=-1, row=2; row < height-2; row++) {
3598 while (smlast < row+2) {
3599 for (i=0; i < 6; i++)
3600 smrow[(i+5) % 6] = smrow[i];
3601 pix = image[++smlast*width+2];
3602 for (col=2; col < width-2; col++) {
3604 (pix[0]*6 + (pix[-4]+pix[4])*4 + pix[-8]+pix[8] + 8) >> 4;
3608 pix = image[row*width+2];
3609 for (col=2; col < width-2; col++) {
3610 smred = ( 6 * smrow[2][col][0]
3611 + 4 * (smrow[1][col][0] + smrow[3][col][0])
3612 + smrow[0][col][0] + smrow[4][col][0] + 8 ) >> 4;
3615 i = pix[0] + ((pix[0] - ((smred*7 + smred_p) >> 3)) >> 3);
3616 if (i > 32000) i = 32000;
3623 /* Adjust the brighter pixels for better linearity */
3626 i = satlev[c] / div[c];
3627 if (min > i) min = i;
3629 limit = min * 9 >> 4;
3630 for (pix=image[0]; pix < image[height*width]; pix+=4) {
3631 if (pix[0] <= limit || pix[1] <= limit || pix[2] <= limit)
3634 for (c=1; c < 3; c++) {
3635 if (min > pix[c]) min = pix[c];
3636 if (max < pix[c]) max = pix[c];
3638 if (min >= limit*2) {
3639 pix[0] = pix[1] = pix[2] = max;
3641 i = 0x4000 - ((min - limit) << 14) / limit;
3642 i = 0x4000 - (i*i >> 14);
3644 FORC3 pix[c] += (max - pix[c]) * i >> 14;
3648 Because photons that miss one detector often hit another,
3649 the sum R+G+B is much less noisy than the individual colors.
3650 So smooth the hues without smoothing the total.
3652 for (smlast=-1, row=2; row < height-2; row++) {
3653 while (smlast < row+2) {
3654 for (i=0; i < 6; i++)
3655 smrow[(i+5) % 6] = smrow[i];
3656 pix = image[++smlast*width+2];
3657 for (col=2; col < width-2; col++) {
3658 FORC3 smrow[4][col][c] = (pix[c-4]+2*pix[c]+pix[c+4]+2) >> 2;
3662 pix = image[row*width+2];
3663 for (col=2; col < width-2; col++) {
3664 FORC3 dev[c] = -foveon_apply_curve (curve[7], pix[c] -
3665 ((smrow[1][col][c] + 2*smrow[2][col][c] + smrow[3][col][c]) >> 2));
3666 sum = (dev[0] + dev[1] + dev[2]) >> 3;
3667 FORC3 pix[c] += dev[c] - sum;
3671 for (smlast=-1, row=2; row < height-2; row++) {
3672 while (smlast < row+2) {
3673 for (i=0; i < 6; i++)
3674 smrow[(i+5) % 6] = smrow[i];
3675 pix = image[++smlast*width+2];
3676 for (col=2; col < width-2; col++) {
3677 FORC3 smrow[4][col][c] =
3678 (pix[c-8]+pix[c-4]+pix[c]+pix[c+4]+pix[c+8]+2) >> 2;
3682 pix = image[row*width+2];
3683 for (col=2; col < width-2; col++) {
3684 for (total[3]=375, sum=60, c=0; c < 3; c++) {
3685 for (total[c]=i=0; i < 5; i++)
3686 total[c] += smrow[i][col][c];
3687 total[3] += total[c];
3690 if (sum < 0) sum = 0;
3691 j = total[3] > 375 ? (sum << 16) / total[3] : sum * 174;
3692 FORC3 pix[c] += foveon_apply_curve (curve[6],
3693 ((j*total[c] + 0x8000) >> 16) - pix[c]);
3698 /* Transform the image to a different colorspace */
3699 for (pix=image[0]; pix < image[height*width]; pix+=4) {
3700 FORC3 pix[c] -= foveon_apply_curve (curve[c], pix[c]);
3701 sum = (pix[0]+pix[1]+pix[1]+pix[2]) >> 2;
3702 FORC3 pix[c] -= foveon_apply_curve (curve[c], pix[c]-sum);
3704 for (dsum=i=0; i < 3; i++)
3705 dsum += trans[c][i] * pix[i];
3706 if (dsum < 0) dsum = 0;
3707 if (dsum > 24000) dsum = 24000;
3708 ipix[c] = dsum + 0.5;
3710 FORC3 pix[c] = ipix[c];
3713 /* Smooth the image bottom-to-top and save at 1/4 scale */
3714 shrink = (short (*)[3]) calloc ((height/4), (width/4)*sizeof *shrink);
3715 merror (shrink, "foveon_interpolate()");
3716 for (row = height/4; row--; )
3717 for (col=0; col < width/4; col++) {
3718 ipix[0] = ipix[1] = ipix[2] = 0;
3719 for (i=0; i < 4; i++)
3720 for (j=0; j < 4; j++)
3721 FORC3 ipix[c] += image[(row*4+i)*width+col*4+j][c];
3723 if (row+2 > height/4)
3724 shrink[row*(width/4)+col][c] = ipix[c] >> 4;
3726 shrink[row*(width/4)+col][c] =
3727 (shrink[(row+1)*(width/4)+col][c]*1840 + ipix[c]*141 + 2048) >> 12;
3729 /* From the 1/4-scale image, smooth right-to-left */
3730 for (row=0; row < (height & ~3); row++) {
3731 ipix[0] = ipix[1] = ipix[2] = 0;
3733 for (col = width & ~3 ; col--; )
3734 FORC3 smrow[0][col][c] = ipix[c] =
3735 (shrink[(row/4)*(width/4)+col/4][c]*1485 + ipix[c]*6707 + 4096) >> 13;
3737 /* Then smooth left-to-right */
3738 ipix[0] = ipix[1] = ipix[2] = 0;
3739 for (col=0; col < (width & ~3); col++)
3740 FORC3 smrow[1][col][c] = ipix[c] =
3741 (smrow[0][col][c]*1485 + ipix[c]*6707 + 4096) >> 13;
3743 /* Smooth top-to-bottom */
3745 memcpy (smrow[2], smrow[1], sizeof **smrow * width);
3747 for (col=0; col < (width & ~3); col++)
3748 FORC3 smrow[2][col][c] =
3749 (smrow[2][col][c]*6707 + smrow[1][col][c]*1485 + 4096) >> 13;
3751 /* Adjust the chroma toward the smooth values */
3752 for (col=0; col < (width & ~3); col++) {
3753 for (i=j=30, c=0; c < 3; c++) {
3754 i += smrow[2][col][c];
3755 j += image[row*width+col][c];
3758 for (sum=c=0; c < 3; c++) {
3759 ipix[c] = foveon_apply_curve (curve[c+3],
3760 ((smrow[2][col][c] * j + 0x8000) >> 16) - image[row*width+col][c]);
3765 i = image[row*width+col][c] + ipix[c] - sum;
3767 image[row*width+col][c] = i;
3773 for (i=0; i < 8; i++)
3776 /* Trim off the black border */
3777 active[1] -= keep[1];
3779 i = active[2] - active[0];
3780 for (row=0; row < active[3]-active[1]; row++)
3781 memcpy (image[row*i], image[(row+active[1])*width+active[0]],
3788 /* RESTRICTED code ends here */
3790 void CLASS crop_masked_pixels()
3793 unsigned r, c, m, mblack[8], zero, val;
3795 if (load_raw == &CLASS phase_one_load_raw ||
3796 load_raw == &CLASS phase_one_load_raw_c)
3797 phase_one_correct();
3799 for (row=0; row < raw_height-top_margin*2; row++) {
3800 for (col=0; col < fuji_width << !fuji_layout; col++) {
3802 r = fuji_width - 1 - col + (row >> 1);
3803 c = col + ((row+1) >> 1);
3805 r = fuji_width - 1 + row - (col >> 1);
3806 c = row + ((col+1) >> 1);
3808 if (r < height && c < width)
3809 BAYER(r,c) = RAW(row+top_margin,col+left_margin);
3813 for (row=0; row < height; row++)
3814 for (col=0; col < width; col++)
3815 BAYER2(row,col) = RAW(row+top_margin,col+left_margin);
3817 if (mask[0][3] > 0) goto mask_set;
3818 if (load_raw == &CLASS canon_load_raw ||
3819 load_raw == &CLASS lossless_jpeg_load_raw) {
3820 mask[0][1] = mask[1][1] += 2;
3824 if (load_raw == &CLASS canon_600_load_raw ||
3825 load_raw == &CLASS sony_load_raw ||
3826 (load_raw == &CLASS eight_bit_load_raw && strncmp(model,"DC2",3)) ||
3827 load_raw == &CLASS kodak_262_load_raw ||
3828 (load_raw == &CLASS packed_load_raw && (load_flags & 32))) {
3830 mask[0][0] = mask[1][0] = top_margin;
3831 mask[0][2] = mask[1][2] = top_margin+height;
3832 mask[0][3] += left_margin;
3833 mask[1][1] += left_margin+width;
3834 mask[1][3] += raw_width;
3836 if (load_raw == &CLASS nokia_load_raw) {
3837 mask[0][2] = top_margin;
3841 memset (mblack, 0, sizeof mblack);
3842 for (zero=m=0; m < 8; m++)
3843 for (row=MAX(mask[m][0],0); row < MIN(mask[m][2],raw_height); row++)
3844 for (col=MAX(mask[m][1],0); col < MIN(mask[m][3],raw_width); col++) {
3845 c = FC(row-top_margin,col-left_margin);
3846 mblack[c] += val = RAW(row,col);
3850 if (load_raw == &CLASS canon_600_load_raw && width < raw_width) {
3851 black = (mblack[0]+mblack[1]+mblack[2]+mblack[3]) /
3852 (mblack[4]+mblack[5]+mblack[6]+mblack[7]) - 4;
3853 canon_600_correct();
3854 } else if (zero < mblack[4] && mblack[5] && mblack[6] && mblack[7]) {
3855 FORC4 cblack[c] = mblack[c] / mblack[4+c];
3856 cblack[4] = cblack[5] = cblack[6] = 0;
3860 void CLASS remove_zeroes()
3862 unsigned row, col, tot, n, r, c;
3864 for (row=0; row < height; row++)
3865 for (col=0; col < width; col++)
3866 if (BAYER(row,col) == 0) {
3868 for (r = row-2; r <= row+2; r++)
3869 for (c = col-2; c <= col+2; c++)
3870 if (r < height && c < width &&
3871 FC(r,c) == FC(row,col) && BAYER(r,c))
3872 tot += (n++,BAYER(r,c));
3873 if (n) BAYER(row,col) = tot/n;
3878 Seach from the current directory up to the root looking for
3879 a ".badpixels" file, and fix those pixels now.
3881 void CLASS bad_pixels (const char *cfname)
3884 char *fname, *cp, line[128];
3885 int len, time, row, col, r, c, rad, tot, n, fixed=0;
3887 if (!filters) return;
3889 fp = fopen (cfname, "r");
3891 for (len=32 ; ; len *= 2) {
3892 fname = (char *) malloc (len);
3894 if (getcwd (fname, len-16)) break;
3896 if (errno != ERANGE) return;
3898 #if defined(WIN32) || defined(DJGPP)
3899 if (fname[1] == ':')
3900 memmove (fname, fname+2, len-2);
3901 for (cp=fname; *cp; cp++)
3902 if (*cp == '\\') *cp = '/';
3904 cp = fname + strlen(fname);
3905 if (cp[-1] == '/') cp--;
3906 while (*fname == '/') {
3907 strcpy (cp, "/.badpixels");
3908 if ((fp = fopen (fname, "r"))) break;
3909 if (cp == fname) break;
3910 while (*--cp != '/');
3915 while (fgets (line, 128, fp)) {
3916 cp = strchr (line, '#');
3918 if (sscanf (line, "%d %d %d", &col, &row, &time) != 3) continue;
3919 if ((unsigned) col >= width || (unsigned) row >= height) continue;
3920 if (time > timestamp) continue;
3921 for (tot=n=0, rad=1; rad < 3 && n==0; rad++)
3922 for (r = row-rad; r <= row+rad; r++)
3923 for (c = col-rad; c <= col+rad; c++)
3924 if ((unsigned) r < height && (unsigned) c < width &&
3925 (r != row || c != col) && fcol(r,c) == fcol(row,col)) {
3929 BAYER2(row,col) = tot/n;
3932 fprintf (stderr,_("Fixed dead pixels at:"));
3933 fprintf (stderr, " %d,%d", col, row);
3936 if (fixed) fputc ('\n', stderr);
3940 void CLASS subtract (const char *fname)
3943 int dim[3]={0,0,0}, comment=0, number=0, error=0, nd=0, c, row, col;
3946 if (!(fp = fopen (fname, "rb"))) {
3947 perror (fname); return;
3949 if (fgetc(fp) != 'P' || fgetc(fp) != '5') error = 1;
3950 while (!error && nd < 3 && (c = fgetc(fp)) != EOF) {
3951 if (c == '#') comment = 1;
3952 if (c == '\n') comment = 0;
3953 if (comment) continue;
3954 if (isdigit(c)) number = 1;
3956 if (isdigit(c)) dim[nd] = dim[nd]*10 + c -'0';
3957 else if (isspace(c)) {
3962 if (error || nd < 3) {
3963 fprintf (stderr,_("%s is not a valid PGM file!\n"), fname);
3964 fclose (fp); return;
3965 } else if (dim[0] != width || dim[1] != height || dim[2] != 65535) {
3966 fprintf (stderr,_("%s has the wrong dimensions!\n"), fname);
3967 fclose (fp); return;
3969 pixel = (ushort *) calloc (width, sizeof *pixel);
3970 merror (pixel, "subtract()");
3971 for (row=0; row < height; row++) {
3972 fread (pixel, 2, width, fp);
3973 for (col=0; col < width; col++)
3974 BAYER(row,col) = MAX (BAYER(row,col) - ntohs(pixel[col]), 0);
3978 memset (cblack, 0, sizeof cblack);
3982 void CLASS gamma_curve (double pwr, double ts, int mode, int imax)
3985 double g[6], bnd[2]={0,0}, r;
3989 g[2] = g[3] = g[4] = 0;
3991 if (g[1] && (g[1]-1)*(g[0]-1) <= 0) {
3992 for (i=0; i < 48; i++) {
3993 g[2] = (bnd[0] + bnd[1])/2;
3994 if (g[0]) bnd[(pow(g[2]/g[1],-g[0]) - 1)/g[0] - 1/g[2] > -1] = g[2];
3995 else bnd[g[2]/exp(1-1/g[2]) < g[1]] = g[2];
3998 if (g[0]) g[4] = g[2] * (1/g[0] - 1);
4000 if (g[0]) g[5] = 1 / (g[1]*SQR(g[3])/2 - g[4]*(1 - g[3]) +
4001 (1 - pow(g[3],1+g[0]))*(1 + g[4])/(1 + g[0])) - 1;
4002 else g[5] = 1 / (g[1]*SQR(g[3])/2 + 1
4003 - g[2] - g[3] - g[2]*g[3]*(log(g[3]) - 1)) - 1;
4005 memcpy (gamm, g, sizeof gamm);
4008 for (i=0; i < 0x10000; i++) {
4010 if ((r = (double) i / imax) < 1)
4011 curve[i] = 0x10000 * ( mode
4012 ? (r < g[3] ? r*g[1] : (g[0] ? pow( r,g[0])*(1+g[4])-g[4] : log(r)*g[2]+1))
4013 : (r < g[2] ? r/g[1] : (g[0] ? pow((r+g[4])/(1+g[4]),1/g[0]) : exp((r-1)/g[2]))));
4017 void CLASS pseudoinverse (double (*in)[3], double (*out)[3], int size)
4019 double work[3][6], num;
4022 for (i=0; i < 3; i++) {
4023 for (j=0; j < 6; j++)
4024 work[i][j] = j == i+3;
4025 for (j=0; j < 3; j++)
4026 for (k=0; k < size; k++)
4027 work[i][j] += in[k][i] * in[k][j];
4029 for (i=0; i < 3; i++) {
4031 for (j=0; j < 6; j++)
4033 for (k=0; k < 3; k++) {
4036 for (j=0; j < 6; j++)
4037 work[k][j] -= work[i][j] * num;
4040 for (i=0; i < size; i++)
4041 for (j=0; j < 3; j++)
4042 for (out[i][j]=k=0; k < 3; k++)
4043 out[i][j] += work[j][k+3] * in[i][k];
4046 void CLASS cam_xyz_coeff (float rgb_cam[3][4], double cam_xyz[4][3])
4048 double cam_rgb[4][3], inverse[4][3], num;
4051 for (i=0; i < colors; i++) /* Multiply out XYZ colorspace */
4052 for (j=0; j < 3; j++)
4053 for (cam_rgb[i][j] = k=0; k < 3; k++)
4054 cam_rgb[i][j] += cam_xyz[i][k] * xyz_rgb[k][j];
4056 for (i=0; i < colors; i++) { /* Normalize cam_rgb so that */
4057 for (num=j=0; j < 3; j++) /* cam_rgb * (1,1,1) is (1,1,1,1) */
4058 num += cam_rgb[i][j];
4059 for (j=0; j < 3; j++)
4060 cam_rgb[i][j] /= num;
4061 pre_mul[i] = 1 / num;
4063 pseudoinverse (cam_rgb, inverse, colors);
4064 for (i=0; i < 3; i++)
4065 for (j=0; j < colors; j++)
4066 rgb_cam[i][j] = inverse[j][i];
4070 void CLASS colorcheck()
4073 // Coordinates of the GretagMacbeth ColorChecker squares
4074 // width, height, 1st_column, 1st_row
4075 int cut[NSQ][4]; // you must set these
4076 // ColorChecker Chart under 6500-kelvin illumination
4077 static const double gmb_xyY[NSQ][3] = {
4078 { 0.400, 0.350, 10.1 }, // Dark Skin
4079 { 0.377, 0.345, 35.8 }, // Light Skin
4080 { 0.247, 0.251, 19.3 }, // Blue Sky
4081 { 0.337, 0.422, 13.3 }, // Foliage
4082 { 0.265, 0.240, 24.3 }, // Blue Flower
4083 { 0.261, 0.343, 43.1 }, // Bluish Green
4084 { 0.506, 0.407, 30.1 }, // Orange
4085 { 0.211, 0.175, 12.0 }, // Purplish Blue
4086 { 0.453, 0.306, 19.8 }, // Moderate Red
4087 { 0.285, 0.202, 6.6 }, // Purple
4088 { 0.380, 0.489, 44.3 }, // Yellow Green
4089 { 0.473, 0.438, 43.1 }, // Orange Yellow
4090 { 0.187, 0.129, 6.1 }, // Blue
4091 { 0.305, 0.478, 23.4 }, // Green
4092 { 0.539, 0.313, 12.0 }, // Red
4093 { 0.448, 0.470, 59.1 }, // Yellow
4094 { 0.364, 0.233, 19.8 }, // Magenta
4095 { 0.196, 0.252, 19.8 }, // Cyan
4096 { 0.310, 0.316, 90.0 }, // White
4097 { 0.310, 0.316, 59.1 }, // Neutral 8
4098 { 0.310, 0.316, 36.2 }, // Neutral 6.5
4099 { 0.310, 0.316, 19.8 }, // Neutral 5
4100 { 0.310, 0.316, 9.0 }, // Neutral 3.5
4101 { 0.310, 0.316, 3.1 } }; // Black
4102 double gmb_cam[NSQ][4], gmb_xyz[NSQ][3];
4103 double inverse[NSQ][3], cam_xyz[4][3], balance[4], num;
4104 int c, i, j, k, sq, row, col, pass, count[4];
4106 memset (gmb_cam, 0, sizeof gmb_cam);
4107 for (sq=0; sq < NSQ; sq++) {
4109 for (row=cut[sq][3]; row < cut[sq][3]+cut[sq][1]; row++)
4110 for (col=cut[sq][2]; col < cut[sq][2]+cut[sq][0]; col++) {
4112 if (c >= colors) c -= 2;
4113 gmb_cam[sq][c] += BAYER2(row,col);
4114 BAYER2(row,col) = black + (BAYER2(row,col)-black)/2;
4117 FORCC gmb_cam[sq][c] = gmb_cam[sq][c]/count[c] - black;
4118 gmb_xyz[sq][0] = gmb_xyY[sq][2] * gmb_xyY[sq][0] / gmb_xyY[sq][1];
4119 gmb_xyz[sq][1] = gmb_xyY[sq][2];
4120 gmb_xyz[sq][2] = gmb_xyY[sq][2] *
4121 (1 - gmb_xyY[sq][0] - gmb_xyY[sq][1]) / gmb_xyY[sq][1];
4123 pseudoinverse (gmb_xyz, inverse, NSQ);
4124 for (pass=0; pass < 2; pass++) {
4125 for (raw_color = i=0; i < colors; i++)
4126 for (j=0; j < 3; j++)
4127 for (cam_xyz[i][j] = k=0; k < NSQ; k++)
4128 cam_xyz[i][j] += gmb_cam[k][i] * inverse[k][j];
4129 cam_xyz_coeff (rgb_cam, cam_xyz);
4130 FORCC balance[c] = pre_mul[c] * gmb_cam[20][c];
4131 for (sq=0; sq < NSQ; sq++)
4132 FORCC gmb_cam[sq][c] *= balance[c];
4135 printf (" { \"%s %s\", %d,\n\t{", make, model, black);
4136 num = 10000 / (cam_xyz[1][0] + cam_xyz[1][1] + cam_xyz[1][2]);
4137 FORCC for (j=0; j < 3; j++)
4138 printf ("%c%d", (c | j) ? ',':' ', (int) (cam_xyz[c][j] * num + 0.5));
4145 void CLASS hat_transform (float *temp, float *base, int st, int size, int sc)
4148 for (i=0; i < sc; i++)
4149 temp[i] = 2*base[st*i] + base[st*(sc-i)] + base[st*(i+sc)];
4150 for (; i+sc < size; i++)
4151 temp[i] = 2*base[st*i] + base[st*(i-sc)] + base[st*(i+sc)];
4152 for (; i < size; i++)
4153 temp[i] = 2*base[st*i] + base[st*(i-sc)] + base[st*(2*size-2-(i+sc))];
4156 void CLASS wavelet_denoise()
4158 float *fimg=0, *temp, thold, mul[2], avg, diff;
4159 int scale=1, size, lev, hpass, lpass, row, col, nc, c, i, wlast, blk[2];
4161 static const float noise[] =
4162 { 0.8002,0.2735,0.1202,0.0585,0.0291,0.0152,0.0080,0.0044 };
4164 if (verbose) fprintf (stderr,_("Wavelet denoising...\n"));
4166 while (maximum << scale < 0x10000) scale++;
4167 maximum <<= --scale;
4169 FORC4 cblack[c] <<= scale;
4170 if ((size = iheight*iwidth) < 0x15550000)
4171 fimg = (float *) malloc ((size*3 + iheight + iwidth) * sizeof *fimg);
4172 merror (fimg, "wavelet_denoise()");
4173 temp = fimg + size*3;
4174 if ((nc = colors) == 3 && filters) nc++;
4175 FORC(nc) { /* denoise R,G1,B,G3 individually */
4176 for (i=0; i < size; i++)
4177 fimg[i] = 256 * sqrt(image[i][c] << scale);
4178 for (hpass=lev=0; lev < 5; lev++) {
4179 lpass = size*((lev & 1)+1);
4180 for (row=0; row < iheight; row++) {
4181 hat_transform (temp, fimg+hpass+row*iwidth, 1, iwidth, 1 << lev);
4182 for (col=0; col < iwidth; col++)
4183 fimg[lpass + row*iwidth + col] = temp[col] * 0.25;
4185 for (col=0; col < iwidth; col++) {
4186 hat_transform (temp, fimg+lpass+col, iwidth, iheight, 1 << lev);
4187 for (row=0; row < iheight; row++)
4188 fimg[lpass + row*iwidth + col] = temp[row] * 0.25;
4190 thold = threshold * noise[lev];
4191 for (i=0; i < size; i++) {
4192 fimg[hpass+i] -= fimg[lpass+i];
4193 if (fimg[hpass+i] < -thold) fimg[hpass+i] += thold;
4194 else if (fimg[hpass+i] > thold) fimg[hpass+i] -= thold;
4195 else fimg[hpass+i] = 0;
4196 if (hpass) fimg[i] += fimg[hpass+i];
4200 for (i=0; i < size; i++)
4201 image[i][c] = CLIP(SQR(fimg[i]+fimg[lpass+i])/0x10000);
4203 if (filters && colors == 3) { /* pull G1 and G3 closer together */
4204 for (row=0; row < 2; row++) {
4205 mul[row] = 0.125 * pre_mul[FC(row+1,0) | 1] / pre_mul[FC(row,0) | 1];
4206 blk[row] = cblack[FC(row,0) | 1];
4208 for (i=0; i < 4; i++)
4209 window[i] = (ushort *) fimg + width*i;
4210 for (wlast=-1, row=1; row < height-1; row++) {
4211 while (wlast < row+1) {
4212 for (wlast++, i=0; i < 4; i++)
4213 window[(i+3) & 3] = window[i];
4214 for (col = FC(wlast,1) & 1; col < width; col+=2)
4215 window[2][col] = BAYER(wlast,col);
4217 thold = threshold/512;
4218 for (col = (FC(row,0) & 1)+1; col < width-1; col+=2) {
4219 avg = ( window[0][col-1] + window[0][col+1] +
4220 window[2][col-1] + window[2][col+1] - blk[~row & 1]*4 )
4221 * mul[row & 1] + (window[1][col] + blk[row & 1]) * 0.5;
4222 avg = avg < 0 ? 0 : sqrt(avg);
4223 diff = sqrt(BAYER(row,col)) - avg;
4224 if (diff < -thold) diff += thold;
4225 else if (diff > thold) diff -= thold;
4227 BAYER(row,col) = CLIP(SQR(avg+diff) + 0.5);
4234 void CLASS scale_colors()
4236 unsigned bottom, right, size, row, col, ur, uc, i, x, y, c, sum[8];
4238 double dsum[8], dmin, dmax;
4239 float scale_mul[4], fr, fc;
4240 ushort *img=0, *pix;
4243 memcpy (pre_mul, user_mul, sizeof pre_mul);
4244 if (use_auto_wb || (use_camera_wb && cam_mul[0] == -1)) {
4245 memset (dsum, 0, sizeof dsum);
4246 bottom = MIN (greybox[1]+greybox[3], height);
4247 right = MIN (greybox[0]+greybox[2], width);
4248 for (row=greybox[1]; row < bottom; row += 8)
4249 for (col=greybox[0]; col < right; col += 8) {
4250 memset (sum, 0, sizeof sum);
4251 for (y=row; y < row+8 && y < bottom; y++)
4252 for (x=col; x < col+8 && x < right; x++)
4258 val = image[y*width+x][c];
4259 if (val > maximum-25) goto skip_block;
4260 if ((val -= cblack[c]) < 0) val = 0;
4265 FORC(8) dsum[c] += sum[c];
4268 FORC4 if (dsum[c]) pre_mul[c] = dsum[c+4] / dsum[c];
4270 if (use_camera_wb && cam_mul[0] != -1) {
4271 memset (sum, 0, sizeof sum);
4272 for (row=0; row < 8; row++)
4273 for (col=0; col < 8; col++) {
4275 if ((val = white[row][col] - cblack[c]) > 0)
4279 if (sum[0] && sum[1] && sum[2] && sum[3])
4280 FORC4 pre_mul[c] = (float) sum[c+4] / sum[c];
4281 else if (cam_mul[0] && cam_mul[2])
4282 memcpy (pre_mul, cam_mul, sizeof pre_mul);
4284 fprintf (stderr,_("%s: Cannot use camera white balance.\n"), ifname);
4286 if (pre_mul[1] == 0) pre_mul[1] = 1;
4287 if (pre_mul[3] == 0) pre_mul[3] = colors < 4 ? pre_mul[1] : 1;
4290 if (threshold) wavelet_denoise();
4292 for (dmin=DBL_MAX, dmax=c=0; c < 4; c++) {
4293 if (dmin > pre_mul[c])
4295 if (dmax < pre_mul[c])
4298 if (!highlight) dmax = dmin;
4299 FORC4 scale_mul[c] = (pre_mul[c] /= dmax) * 65535.0 / maximum;
4302 _("Scaling with darkness %d, saturation %d, and\nmultipliers"), dark, sat);
4303 FORC4 fprintf (stderr, " %f", pre_mul[c]);
4304 fputc ('\n', stderr);
4306 if (filters > 1000 && (cblack[4]+1)/2 == 1 && (cblack[5]+1)/2 == 1) {
4307 FORC4 cblack[FC(c/2,c%2)] +=
4308 cblack[6 + c/2 % cblack[4] * cblack[5] + c%2 % cblack[5]];
4309 cblack[4] = cblack[5] = 0;
4311 size = iheight*iwidth;
4312 for (i=0; i < size*4; i++) {
4313 if (!(val = ((ushort *)image)[i])) continue;
4314 if (cblack[4] && cblack[5])
4315 val -= cblack[6 + i/4 / iwidth % cblack[4] * cblack[5] +
4316 i/4 % iwidth % cblack[5]];
4317 val -= cblack[i & 3];
4318 val *= scale_mul[i & 3];
4319 ((ushort *)image)[i] = CLIP(val);
4321 if ((aber[0] != 1 || aber[2] != 1) && colors == 3) {
4323 fprintf (stderr,_("Correcting chromatic aberration...\n"));
4324 for (c=0; c < 4; c+=2) {
4325 if (aber[c] == 1) continue;
4326 img = (ushort *) malloc (size * sizeof *img);
4327 merror (img, "scale_colors()");
4328 for (i=0; i < size; i++)
4329 img[i] = image[i][c];
4330 for (row=0; row < iheight; row++) {
4331 ur = fr = (row - iheight*0.5) * aber[c] + iheight*0.5;
4332 if (ur > iheight-2) continue;
4334 for (col=0; col < iwidth; col++) {
4335 uc = fc = (col - iwidth*0.5) * aber[c] + iwidth*0.5;
4336 if (uc > iwidth-2) continue;
4338 pix = img + ur*iwidth + uc;
4339 image[row*iwidth+col][c] =
4340 (pix[ 0]*(1-fc) + pix[ 1]*fc) * (1-fr) +
4341 (pix[iwidth]*(1-fc) + pix[iwidth+1]*fc) * fr;
4349 void CLASS pre_interpolate()
4359 for (row=0; row < 3; row++)
4360 for (col=1; col < 4; col++)
4361 if (!(image[row*width+col][0] | image[row*width+col][2]))
4362 goto break2; break2:
4363 for ( ; row < height; row+=3)
4364 for (col=(col-1)%3+1; col < width-1; col+=3) {
4365 img = image + row*width+col;
4366 for (c=0; c < 3; c+=2)
4367 img[0][c] = (img[-1][c] + img[1][c]) >> 1;
4371 img = (ushort (*)[4]) calloc (height, width*sizeof *img);
4372 merror (img, "pre_interpolate()");
4373 for (row=0; row < height; row++)
4374 for (col=0; col < width; col++) {
4376 img[row*width+col][c] = image[(row >> 1)*iwidth+(col >> 1)][c];
4383 if (filters > 1000 && colors == 3) {
4384 mix_green = four_color_rgb ^ half_size;
4385 if (four_color_rgb | half_size) colors++;
4387 for (row = FC(1,0) >> 1; row < height; row+=2)
4388 for (col = FC(row,1) & 1; col < width; col+=2)
4389 image[row*width+col][1] = image[row*width+col][3];
4390 filters &= ~((filters & 0x55555555) << 1);
4393 if (half_size) filters = 0;
4396 void CLASS border_interpolate (int border)
4398 unsigned row, col, y, x, f, c, sum[8];
4400 for (row=0; row < height; row++)
4401 for (col=0; col < width; col++) {
4402 if (col==border && row >= border && row < height-border)
4404 memset (sum, 0, sizeof sum);
4405 for (y=row-1; y != row+2; y++)
4406 for (x=col-1; x != col+2; x++)
4407 if (y < height && x < width) {
4409 sum[f] += image[y*width+x][f];
4413 FORCC if (c != f && sum[c+4])
4414 image[row*width+col][c] = sum[c] / sum[c+4];
4418 void CLASS lin_interpolate()
4420 int code[16][16][32], size=16, *ip, sum[4];
4421 int f, c, i, x, y, row, col, shift, color;
4424 if (verbose) fprintf (stderr,_("Bilinear interpolation...\n"));
4425 if (filters == 9) size = 6;
4426 border_interpolate(1);
4427 for (row=0; row < size; row++)
4428 for (col=0; col < size; col++) {
4429 ip = code[row][col]+1;
4431 memset (sum, 0, sizeof sum);
4432 for (y=-1; y <= 1; y++)
4433 for (x=-1; x <= 1; x++) {
4434 shift = (y==0) + (x==0);
4435 color = fcol(row+y,col+x);
4436 if (color == f) continue;
4437 *ip++ = (width*y + x)*4 + color;
4440 sum[color] += 1 << shift;
4442 code[row][col][0] = (ip - code[row][col]) / 3;
4446 *ip++ = 256 / sum[c];
4449 for (row=1; row < height-1; row++)
4450 for (col=1; col < width-1; col++) {
4451 pix = image[row*width+col];
4452 ip = code[row % size][col % size];
4453 memset (sum, 0, sizeof sum);
4454 for (i=*ip++; i--; ip+=3)
4455 sum[ip[2]] += pix[ip[0]] << ip[1];
4456 for (i=colors; --i; ip+=2)
4457 pix[ip[0]] = sum[ip[0]] * ip[1] >> 8;
4462 This algorithm is officially called:
4464 "Interpolation using a Threshold-based variable number of gradients"
4466 described in http://scien.stanford.edu/pages/labsite/1999/psych221/projects/99/tingchen/algodep/vargra.html
4468 I've extended the basic idea to work with non-Bayer filter arrays.
4469 Gradients are numbered clockwise from NW=0 to W=7.
4471 void CLASS vng_interpolate()
4473 static const signed char *cp, terms[] = {
4474 -2,-2,+0,-1,0,0x01, -2,-2,+0,+0,1,0x01, -2,-1,-1,+0,0,0x01,
4475 -2,-1,+0,-1,0,0x02, -2,-1,+0,+0,0,0x03, -2,-1,+0,+1,1,0x01,
4476 -2,+0,+0,-1,0,0x06, -2,+0,+0,+0,1,0x02, -2,+0,+0,+1,0,0x03,
4477 -2,+1,-1,+0,0,0x04, -2,+1,+0,-1,1,0x04, -2,+1,+0,+0,0,0x06,
4478 -2,+1,+0,+1,0,0x02, -2,+2,+0,+0,1,0x04, -2,+2,+0,+1,0,0x04,
4479 -1,-2,-1,+0,0,0x80, -1,-2,+0,-1,0,0x01, -1,-2,+1,-1,0,0x01,
4480 -1,-2,+1,+0,1,0x01, -1,-1,-1,+1,0,0x88, -1,-1,+1,-2,0,0x40,
4481 -1,-1,+1,-1,0,0x22, -1,-1,+1,+0,0,0x33, -1,-1,+1,+1,1,0x11,
4482 -1,+0,-1,+2,0,0x08, -1,+0,+0,-1,0,0x44, -1,+0,+0,+1,0,0x11,
4483 -1,+0,+1,-2,1,0x40, -1,+0,+1,-1,0,0x66, -1,+0,+1,+0,1,0x22,
4484 -1,+0,+1,+1,0,0x33, -1,+0,+1,+2,1,0x10, -1,+1,+1,-1,1,0x44,
4485 -1,+1,+1,+0,0,0x66, -1,+1,+1,+1,0,0x22, -1,+1,+1,+2,0,0x10,
4486 -1,+2,+0,+1,0,0x04, -1,+2,+1,+0,1,0x04, -1,+2,+1,+1,0,0x04,
4487 +0,-2,+0,+0,1,0x80, +0,-1,+0,+1,1,0x88, +0,-1,+1,-2,0,0x40,
4488 +0,-1,+1,+0,0,0x11, +0,-1,+2,-2,0,0x40, +0,-1,+2,-1,0,0x20,
4489 +0,-1,+2,+0,0,0x30, +0,-1,+2,+1,1,0x10, +0,+0,+0,+2,1,0x08,
4490 +0,+0,+2,-2,1,0x40, +0,+0,+2,-1,0,0x60, +0,+0,+2,+0,1,0x20,
4491 +0,+0,+2,+1,0,0x30, +0,+0,+2,+2,1,0x10, +0,+1,+1,+0,0,0x44,
4492 +0,+1,+1,+2,0,0x10, +0,+1,+2,-1,1,0x40, +0,+1,+2,+0,0,0x60,
4493 +0,+1,+2,+1,0,0x20, +0,+1,+2,+2,0,0x10, +1,-2,+1,+0,0,0x80,
4494 +1,-1,+1,+1,0,0x88, +1,+0,+1,+2,0,0x08, +1,+0,+2,-1,0,0x40,
4496 }, chood[] = { -1,-1, -1,0, -1,+1, 0,+1, +1,+1, +1,0, +1,-1, 0,-1 };
4497 ushort (*brow[5])[4], *pix;
4498 int prow=8, pcol=2, *ip, *code[16][16], gval[8], gmin, gmax, sum[4];
4499 int row, col, x, y, x1, x2, y1, y2, t, weight, grads, color, diag;
4500 int g, diff, thold, num, c;
4503 if (verbose) fprintf (stderr,_("VNG interpolation...\n"));
4505 if (filters == 1) prow = pcol = 16;
4506 if (filters == 9) prow = pcol = 6;
4507 ip = (int *) calloc (prow*pcol, 1280);
4508 merror (ip, "vng_interpolate()");
4509 for (row=0; row < prow; row++) /* Precalculate for VNG */
4510 for (col=0; col < pcol; col++) {
4511 code[row][col] = ip;
4512 for (cp=terms, t=0; t < 64; t++) {
4513 y1 = *cp++; x1 = *cp++;
4514 y2 = *cp++; x2 = *cp++;
4517 color = fcol(row+y1,col+x1);
4518 if (fcol(row+y2,col+x2) != color) continue;
4519 diag = (fcol(row,col+1) == color && fcol(row+1,col) == color) ? 2:1;
4520 if (abs(y1-y2) == diag && abs(x1-x2) == diag) continue;
4521 *ip++ = (y1*width + x1)*4 + color;
4522 *ip++ = (y2*width + x2)*4 + color;
4524 for (g=0; g < 8; g++)
4525 if (grads & 1<<g) *ip++ = g;
4529 for (cp=chood, g=0; g < 8; g++) {
4530 y = *cp++; x = *cp++;
4531 *ip++ = (y*width + x) * 4;
4532 color = fcol(row,col);
4533 if (fcol(row+y,col+x) != color && fcol(row+y*2,col+x*2) == color)
4534 *ip++ = (y*width + x) * 8 + color;
4539 brow[4] = (ushort (*)[4]) calloc (width*3, sizeof **brow);
4540 merror (brow[4], "vng_interpolate()");
4541 for (row=0; row < 3; row++)
4542 brow[row] = brow[4] + row*width;
4543 for (row=2; row < height-2; row++) { /* Do VNG interpolation */
4544 for (col=2; col < width-2; col++) {
4545 pix = image[row*width+col];
4546 ip = code[row % prow][col % pcol];
4547 memset (gval, 0, sizeof gval);
4548 while ((g = ip[0]) != INT_MAX) { /* Calculate gradients */
4549 diff = ABS(pix[g] - pix[ip[1]]) << ip[2];
4550 gval[ip[3]] += diff;
4552 if ((g = ip[-1]) == -1) continue;
4554 while ((g = *ip++) != -1)
4558 gmin = gmax = gval[0]; /* Choose a threshold */
4559 for (g=1; g < 8; g++) {
4560 if (gmin > gval[g]) gmin = gval[g];
4561 if (gmax < gval[g]) gmax = gval[g];
4564 memcpy (brow[2][col], pix, sizeof *image);
4567 thold = gmin + (gmax >> 1);
4568 memset (sum, 0, sizeof sum);
4569 color = fcol(row,col);
4570 for (num=g=0; g < 8; g++,ip+=2) { /* Average the neighbors */
4571 if (gval[g] <= thold) {
4573 if (c == color && ip[1])
4574 sum[c] += (pix[c] + pix[ip[1]]) >> 1;
4576 sum[c] += pix[ip[0] + c];
4580 FORCC { /* Save to buffer */
4583 t += (sum[c] - sum[color]) / num;
4584 brow[2][col][c] = CLIP(t);
4587 if (row > 3) /* Write buffer to image */
4588 memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image);
4589 for (g=0; g < 4; g++)
4590 brow[(g-1) & 3] = brow[g];
4592 memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image);
4593 memcpy (image[(row-1)*width+2], brow[1]+2, (width-4)*sizeof *image);
4599 Patterned Pixel Grouping Interpolation by Alain Desbiolles
4601 void CLASS ppg_interpolate()
4603 int dir[5] = { 1, width, -1, -width, 1 };
4604 int row, col, diff[2], guess[2], c, d, i;
4607 border_interpolate(3);
4608 if (verbose) fprintf (stderr,_("PPG interpolation...\n"));
4610 /* Fill in the green layer with gradients and pattern recognition: */
4611 for (row=3; row < height-3; row++)
4612 for (col=3+(FC(row,3) & 1), c=FC(row,col); col < width-3; col+=2) {
4613 pix = image + row*width+col;
4614 for (i=0; (d=dir[i]) > 0; i++) {
4615 guess[i] = (pix[-d][1] + pix[0][c] + pix[d][1]) * 2
4616 - pix[-2*d][c] - pix[2*d][c];
4617 diff[i] = ( ABS(pix[-2*d][c] - pix[ 0][c]) +
4618 ABS(pix[ 2*d][c] - pix[ 0][c]) +
4619 ABS(pix[ -d][1] - pix[ d][1]) ) * 3 +
4620 ( ABS(pix[ 3*d][1] - pix[ d][1]) +
4621 ABS(pix[-3*d][1] - pix[-d][1]) ) * 2;
4623 d = dir[i = diff[0] > diff[1]];
4624 pix[0][1] = ULIM(guess[i] >> 2, pix[d][1], pix[-d][1]);
4626 /* Calculate red and blue for each green pixel: */
4627 for (row=1; row < height-1; row++)
4628 for (col=1+(FC(row,2) & 1), c=FC(row,col+1); col < width-1; col+=2) {
4629 pix = image + row*width+col;
4630 for (i=0; (d=dir[i]) > 0; c=2-c, i++)
4631 pix[0][c] = CLIP((pix[-d][c] + pix[d][c] + 2*pix[0][1]
4632 - pix[-d][1] - pix[d][1]) >> 1);
4634 /* Calculate blue for red pixels and vice versa: */
4635 for (row=1; row < height-1; row++)
4636 for (col=1+(FC(row,1) & 1), c=2-FC(row,col); col < width-1; col+=2) {
4637 pix = image + row*width+col;
4638 for (i=0; (d=dir[i]+dir[i+1]) > 0; i++) {
4639 diff[i] = ABS(pix[-d][c] - pix[d][c]) +
4640 ABS(pix[-d][1] - pix[0][1]) +
4641 ABS(pix[ d][1] - pix[0][1]);
4642 guess[i] = pix[-d][c] + pix[d][c] + 2*pix[0][1]
4643 - pix[-d][1] - pix[d][1];
4645 if (diff[0] != diff[1])
4646 pix[0][c] = CLIP(guess[diff[0] > diff[1]] >> 1);
4648 pix[0][c] = CLIP((guess[0]+guess[1]) >> 2);
4652 void CLASS cielab (ushort rgb[3], short lab[3])
4656 static float cbrt[0x10000], xyz_cam[3][4];
4659 for (i=0; i < 0x10000; i++) {
4661 cbrt[i] = r > 0.008856 ? pow(r,1/3.0) : 7.787*r + 16/116.0;
4663 for (i=0; i < 3; i++)
4664 for (j=0; j < colors; j++)
4665 for (xyz_cam[i][j] = k=0; k < 3; k++)
4666 xyz_cam[i][j] += xyz_rgb[i][k] * rgb_cam[k][j] / d65_white[i];
4669 xyz[0] = xyz[1] = xyz[2] = 0.5;
4671 xyz[0] += xyz_cam[0][c] * rgb[c];
4672 xyz[1] += xyz_cam[1][c] * rgb[c];
4673 xyz[2] += xyz_cam[2][c] * rgb[c];
4675 xyz[0] = cbrt[CLIP((int) xyz[0])];
4676 xyz[1] = cbrt[CLIP((int) xyz[1])];
4677 xyz[2] = cbrt[CLIP((int) xyz[2])];
4678 lab[0] = 64 * (116 * xyz[1] - 16);
4679 lab[1] = 64 * 500 * (xyz[0] - xyz[1]);
4680 lab[2] = 64 * 200 * (xyz[1] - xyz[2]);
4683 #define TS 512 /* Tile Size */
4684 #define fcol(row,col) xtrans[(row+6) % 6][(col+6) % 6]
4687 Frank Markesteijn's algorithm for Fuji X-Trans sensors
4689 void CLASS xtrans_interpolate (int passes)
4691 int c, d, f, g, h, i, v, ng, row, col, top, left, mrow, mcol;
4692 int val, ndir, pass, hm[8], avg[4], color[3][8];
4693 static const short orth[12] = { 1,0,0,1,-1,0,0,-1,1,0,0,1 },
4694 patt[2][16] = { { 0,1,0,-1,2,0,-1,0,1,1,1,-1,0,0,0,0 },
4695 { 0,1,0,-2,1,0,-2,0,1,1,-2,-2,1,-1,-1,1 } },
4696 dir[4] = { 1,TS,TS+1,TS-1 };
4697 short allhex[3][3][2][8], *hex;
4699 ushort min, max, sgrow=0, sgcol=0;
4700 ushort (*rgb)[TS][TS][3], (*rix)[3], (*pix)[4];
4701 short (*lab) [TS][3], (*lix)[3];
4702 float (*drv)[TS][TS], diff[6], tr;
4703 char (*homo)[TS][TS], *buffer;
4706 fprintf (stderr,_("%d-pass X-Trans interpolation...\n"), passes);
4709 ndir = 4 << (passes > 1);
4710 buffer = (char *) malloc (TS*TS*(ndir*11+6));
4711 merror (buffer, "xtrans_interpolate()");
4712 rgb = (ushort(*)[TS][TS][3]) buffer;
4713 lab = (short (*) [TS][3])(buffer + TS*TS*(ndir*6));
4714 drv = (float (*)[TS][TS]) (buffer + TS*TS*(ndir*6+6));
4715 homo = (char (*)[TS][TS]) (buffer + TS*TS*(ndir*10+6));
4717 /* Map a green hexagon around each non-green pixel and vice versa: */
4718 for (row=0; row < 3; row++)
4719 for (col=0; col < 3; col++)
4720 for (ng=d=0; d < 10; d+=2) {
4721 g = fcol(row,col) == 1;
4722 if (fcol(row+orth[d],col+orth[d+2]) == 1) ng=0; else ng++;
4723 if (ng == 4) { sgrow = row; sgcol = col; }
4724 if (ng == g+1) FORC(8) {
4725 v = orth[d ]*patt[g][c*2] + orth[d+1]*patt[g][c*2+1];
4726 h = orth[d+2]*patt[g][c*2] + orth[d+3]*patt[g][c*2+1];
4727 allhex[row][col][0][c^(g*2 & d)] = h + v*width;
4728 allhex[row][col][1][c^(g*2 & d)] = h + v*TS;
4732 /* Set green1 and green3 to the minimum and maximum allowed values: */
4733 for (row=2; row < height-2; row++)
4734 for (min=~(max=0), col=2; col < width-2; col++) {
4735 if (fcol(row,col) == 1 && (min=~(max=0))) continue;
4736 pix = image + row*width + col;
4737 hex = allhex[row % 3][col % 3][0];
4739 val = pix[hex[c]][1];
4740 if (min > val) min = val;
4741 if (max < val) max = val;
4745 switch ((row-sgrow) % 3) {
4746 case 1: if (row < height-3) { row++; col--; } break;
4747 case 2: if ((min=~(max=0)) && (col+=2) < width-3 && row > 2) row--;
4751 for (top=3; top < height-19; top += TS-16)
4752 for (left=3; left < width-19; left += TS-16) {
4753 mrow = MIN (top+TS, height-3);
4754 mcol = MIN (left+TS, width-3);
4755 for (row=top; row < mrow; row++)
4756 for (col=left; col < mcol; col++)
4757 memcpy (rgb[0][row-top][col-left], image[row*width+col], 6);
4758 FORC3 memcpy (rgb[c+1], rgb[0], sizeof *rgb);
4760 /* Interpolate green horizontally, vertically, and along both diagonals: */
4761 for (row=top; row < mrow; row++)
4762 for (col=left; col < mcol; col++) {
4763 if ((f = fcol(row,col)) == 1) continue;
4764 pix = image + row*width + col;
4765 hex = allhex[row % 3][col % 3][0];
4766 color[1][0] = 174 * (pix[ hex[1]][1] + pix[ hex[0]][1]) -
4767 46 * (pix[2*hex[1]][1] + pix[2*hex[0]][1]);
4768 color[1][1] = 223 * pix[ hex[3]][1] + pix[ hex[2]][1] * 33 +
4769 92 * (pix[ 0 ][f] - pix[ -hex[2]][f]);
4770 FORC(2) color[1][2+c] =
4771 164 * pix[hex[4+c]][1] + 92 * pix[-2*hex[4+c]][1] + 33 *
4772 (2*pix[0][f] - pix[3*hex[4+c]][f] - pix[-3*hex[4+c]][f]);
4773 FORC4 rgb[c^!((row-sgrow) % 3)][row-top][col-left][1] =
4774 LIM(color[1][c] >> 8,pix[0][1],pix[0][3]);
4777 for (pass=0; pass < passes; pass++) {
4779 memcpy (rgb+=4, buffer, 4*sizeof *rgb);
4781 /* Recalculate green from interpolated values of closer pixels: */
4783 for (row=top+2; row < mrow-2; row++)
4784 for (col=left+2; col < mcol-2; col++) {
4785 if ((f = fcol(row,col)) == 1) continue;
4786 pix = image + row*width + col;
4787 hex = allhex[row % 3][col % 3][1];
4788 for (d=3; d < 6; d++) {
4789 rix = &rgb[(d-2)^!((row-sgrow) % 3)][row-top][col-left];
4790 val = rix[-2*hex[d]][1] + 2*rix[hex[d]][1]
4791 - rix[-2*hex[d]][f] - 2*rix[hex[d]][f] + 3*rix[0][f];
4792 rix[0][1] = LIM(val/3,pix[0][1],pix[0][3]);
4797 /* Interpolate red and blue values for solitary green pixels: */
4798 for (row=(top-sgrow+4)/3*3+sgrow; row < mrow-2; row+=3)
4799 for (col=(left-sgcol+4)/3*3+sgcol; col < mcol-2; col+=3) {
4800 rix = &rgb[0][row-top][col-left];
4801 h = fcol(row,col+1);
4802 memset (diff, 0, sizeof diff);
4803 for (i=1, d=0; d < 6; d++, i^=TS^1, h^=2) {
4804 for (c=0; c < 2; c++, h^=2) {
4805 g = 2*rix[0][1] - rix[i<<c][1] - rix[-i<<c][1];
4806 color[h][d] = g + rix[i<<c][h] + rix[-i<<c][h];
4808 diff[d] += SQR (rix[i<<c][1] - rix[-i<<c][1]
4809 - rix[i<<c][h] + rix[-i<<c][h]) + SQR(g);
4811 if (d > 1 && (d & 1))
4812 if (diff[d-1] < diff[d])
4813 FORC(2) color[c*2][d] = color[c*2][d-1];
4814 if (d < 2 || (d & 1)) {
4815 FORC(2) rix[0][c*2] = CLIP(color[c*2][d]/2);
4821 /* Interpolate red for blue pixels and vice versa: */
4822 for (row=top+3; row < mrow-3; row++)
4823 for (col=left+3; col < mcol-3; col++) {
4824 if ((f = 2-fcol(row,col)) == 1) continue;
4825 rix = &rgb[0][row-top][col-left];
4826 c = (row-sgrow) % 3 ? TS:1;
4827 h = 3 * (c ^ TS ^ 1);
4828 for (d=0; d < 4; d++, rix += TS*TS) {
4829 i = d > 1 || ((d ^ c) & 1) ||
4830 ((ABS(rix[0][1]-rix[c][1])+ABS(rix[0][1]-rix[-c][1])) <
4831 2*(ABS(rix[0][1]-rix[h][1])+ABS(rix[0][1]-rix[-h][1]))) ? c:h;
4832 rix[0][f] = CLIP((rix[i][f] + rix[-i][f] +
4833 2*rix[0][1] - rix[i][1] - rix[-i][1])/2);
4837 /* Fill in red and blue for 2x2 blocks of green: */
4838 for (row=top+2; row < mrow-2; row++) if ((row-sgrow) % 3)
4839 for (col=left+2; col < mcol-2; col++) if ((col-sgcol) % 3) {
4840 rix = &rgb[0][row-top][col-left];
4841 hex = allhex[row % 3][col % 3][1];
4842 for (d=0; d < ndir; d+=2, rix += TS*TS)
4843 if (hex[d] + hex[d+1]) {
4844 g = 3*rix[0][1] - 2*rix[hex[d]][1] - rix[hex[d+1]][1];
4845 for (c=0; c < 4; c+=2) rix[0][c] =
4846 CLIP((g + 2*rix[hex[d]][c] + rix[hex[d+1]][c])/3);
4848 g = 2*rix[0][1] - rix[hex[d]][1] - rix[hex[d+1]][1];
4849 for (c=0; c < 4; c+=2) rix[0][c] =
4850 CLIP((g + rix[hex[d]][c] + rix[hex[d+1]][c])/2);
4854 rgb = (ushort(*)[TS][TS][3]) buffer;
4858 /* Convert to CIELab and differentiate in all directions: */
4859 for (d=0; d < ndir; d++) {
4860 for (row=2; row < mrow-2; row++)
4861 for (col=2; col < mcol-2; col++)
4862 cielab (rgb[d][row][col], lab[row][col]);
4863 for (f=dir[d & 3],row=3; row < mrow-3; row++)
4864 for (col=3; col < mcol-3; col++) {
4865 lix = &lab[row][col];
4866 g = 2*lix[0][0] - lix[f][0] - lix[-f][0];
4867 drv[d][row][col] = SQR(g)
4868 + SQR((2*lix[0][1] - lix[f][1] - lix[-f][1] + g*500/232))
4869 + SQR((2*lix[0][2] - lix[f][2] - lix[-f][2] - g*500/580));
4873 /* Build homogeneity maps from the derivatives: */
4874 memset(homo, 0, ndir*TS*TS);
4875 for (row=4; row < mrow-4; row++)
4876 for (col=4; col < mcol-4; col++) {
4877 for (tr=FLT_MAX, d=0; d < ndir; d++)
4878 if (tr > drv[d][row][col])
4879 tr = drv[d][row][col];
4881 for (d=0; d < ndir; d++)
4882 for (v=-1; v <= 1; v++)
4883 for (h=-1; h <= 1; h++)
4884 if (drv[d][row+v][col+h] <= tr)
4885 homo[d][row][col]++;
4888 /* Average the most homogenous pixels for the final result: */
4889 if (height-top < TS+4) mrow = height-top+2;
4890 if (width-left < TS+4) mcol = width-left+2;
4891 for (row = MIN(top,8); row < mrow-8; row++)
4892 for (col = MIN(left,8); col < mcol-8; col++) {
4893 for (d=0; d < ndir; d++)
4894 for (hm[d]=0, v=-2; v <= 2; v++)
4895 for (h=-2; h <= 2; h++)
4896 hm[d] += homo[d][row+v][col+h];
4897 for (d=0; d < ndir-4; d++)
4898 if (hm[d] < hm[d+4]) hm[d ] = 0; else
4899 if (hm[d] > hm[d+4]) hm[d+4] = 0;
4900 for (max=hm[0],d=1; d < ndir; d++)
4901 if (max < hm[d]) max = hm[d];
4903 memset (avg, 0, sizeof avg);
4904 for (d=0; d < ndir; d++)
4906 FORC3 avg[c] += rgb[d][row][col][c];
4909 FORC3 image[(row+top)*width+col+left][c] = avg[c]/avg[3];
4913 border_interpolate(8);
4918 Adaptive Homogeneity-Directed interpolation is based on
4919 the work of Keigo Hirakawa, Thomas Parks, and Paul Lee.
4921 void CLASS ahd_interpolate()
4923 int i, j, top, left, row, col, tr, tc, c, d, val, hm[2];
4924 static const int dir[4] = { -1, 1, -TS, TS };
4925 unsigned ldiff[2][4], abdiff[2][4], leps, abeps;
4926 ushort (*rgb)[TS][TS][3], (*rix)[3], (*pix)[4];
4927 short (*lab)[TS][TS][3], (*lix)[3];
4928 char (*homo)[TS][TS], *buffer;
4930 if (verbose) fprintf (stderr,_("AHD interpolation...\n"));
4933 border_interpolate(5);
4934 buffer = (char *) malloc (26*TS*TS);
4935 merror (buffer, "ahd_interpolate()");
4936 rgb = (ushort(*)[TS][TS][3]) buffer;
4937 lab = (short (*)[TS][TS][3])(buffer + 12*TS*TS);
4938 homo = (char (*)[TS][TS]) (buffer + 24*TS*TS);
4940 for (top=2; top < height-5; top += TS-6)
4941 for (left=2; left < width-5; left += TS-6) {
4943 /* Interpolate green horizontally and vertically: */
4944 for (row=top; row < top+TS && row < height-2; row++) {
4945 col = left + (FC(row,left) & 1);
4946 for (c = FC(row,col); col < left+TS && col < width-2; col+=2) {
4947 pix = image + row*width+col;
4948 val = ((pix[-1][1] + pix[0][c] + pix[1][1]) * 2
4949 - pix[-2][c] - pix[2][c]) >> 2;
4950 rgb[0][row-top][col-left][1] = ULIM(val,pix[-1][1],pix[1][1]);
4951 val = ((pix[-width][1] + pix[0][c] + pix[width][1]) * 2
4952 - pix[-2*width][c] - pix[2*width][c]) >> 2;
4953 rgb[1][row-top][col-left][1] = ULIM(val,pix[-width][1],pix[width][1]);
4956 /* Interpolate red and blue, and convert to CIELab: */
4957 for (d=0; d < 2; d++)
4958 for (row=top+1; row < top+TS-1 && row < height-3; row++)
4959 for (col=left+1; col < left+TS-1 && col < width-3; col++) {
4960 pix = image + row*width+col;
4961 rix = &rgb[d][row-top][col-left];
4962 lix = &lab[d][row-top][col-left];
4963 if ((c = 2 - FC(row,col)) == 1) {
4965 val = pix[0][1] + (( pix[-1][2-c] + pix[1][2-c]
4966 - rix[-1][1] - rix[1][1] ) >> 1);
4967 rix[0][2-c] = CLIP(val);
4968 val = pix[0][1] + (( pix[-width][c] + pix[width][c]
4969 - rix[-TS][1] - rix[TS][1] ) >> 1);
4971 val = rix[0][1] + (( pix[-width-1][c] + pix[-width+1][c]
4972 + pix[+width-1][c] + pix[+width+1][c]
4973 - rix[-TS-1][1] - rix[-TS+1][1]
4974 - rix[+TS-1][1] - rix[+TS+1][1] + 1) >> 2);
4975 rix[0][c] = CLIP(val);
4977 rix[0][c] = pix[0][c];
4978 cielab (rix[0],lix[0]);
4980 /* Build homogeneity maps from the CIELab images: */
4981 memset (homo, 0, 2*TS*TS);
4982 for (row=top+2; row < top+TS-2 && row < height-4; row++) {
4984 for (col=left+2; col < left+TS-2 && col < width-4; col++) {
4986 for (d=0; d < 2; d++) {
4987 lix = &lab[d][tr][tc];
4988 for (i=0; i < 4; i++) {
4989 ldiff[d][i] = ABS(lix[0][0]-lix[dir[i]][0]);
4990 abdiff[d][i] = SQR(lix[0][1]-lix[dir[i]][1])
4991 + SQR(lix[0][2]-lix[dir[i]][2]);
4994 leps = MIN(MAX(ldiff[0][0],ldiff[0][1]),
4995 MAX(ldiff[1][2],ldiff[1][3]));
4996 abeps = MIN(MAX(abdiff[0][0],abdiff[0][1]),
4997 MAX(abdiff[1][2],abdiff[1][3]));
4998 for (d=0; d < 2; d++)
4999 for (i=0; i < 4; i++)
5000 if (ldiff[d][i] <= leps && abdiff[d][i] <= abeps)
5004 /* Combine the most homogenous pixels for the final result: */
5005 for (row=top+3; row < top+TS-3 && row < height-5; row++) {
5007 for (col=left+3; col < left+TS-3 && col < width-5; col++) {
5009 for (d=0; d < 2; d++)
5010 for (hm[d]=0, i=tr-1; i <= tr+1; i++)
5011 for (j=tc-1; j <= tc+1; j++)
5012 hm[d] += homo[d][i][j];
5014 FORC3 image[row*width+col][c] = rgb[hm[1] > hm[0]][tr][tc][c];
5016 FORC3 image[row*width+col][c] =
5017 (rgb[0][tr][tc][c] + rgb[1][tr][tc][c]) >> 1;
5025 void CLASS median_filter()
5028 int pass, c, i, j, k, med[9];
5029 static const uchar opt[] = /* Optimal 9-element median search */
5030 { 1,2, 4,5, 7,8, 0,1, 3,4, 6,7, 1,2, 4,5, 7,8,
5031 0,3, 5,8, 4,7, 3,6, 1,4, 2,5, 4,7, 4,2, 6,4, 4,2 };
5033 for (pass=1; pass <= med_passes; pass++) {
5035 fprintf (stderr,_("Median filter pass %d...\n"), pass);
5036 for (c=0; c < 3; c+=2) {
5037 for (pix = image; pix < image+width*height; pix++)
5038 pix[0][3] = pix[0][c];
5039 for (pix = image+width; pix < image+width*(height-1); pix++) {
5040 if ((pix-image+1) % width < 2) continue;
5041 for (k=0, i = -width; i <= width; i += width)
5042 for (j = i-1; j <= i+1; j++)
5043 med[k++] = pix[j][3] - pix[j][1];
5044 for (i=0; i < sizeof opt; i+=2)
5045 if (med[opt[i]] > med[opt[i+1]])
5046 SWAP (med[opt[i]] , med[opt[i+1]]);
5047 pix[0][c] = CLIP(med[4] + pix[0][1]);
5053 void CLASS blend_highlights()
5055 int clip=INT_MAX, row, col, c, i, j;
5056 static const float trans[2][4][4] =
5057 { { { 1,1,1 }, { 1.7320508,-1.7320508,0 }, { -1,-1,2 } },
5058 { { 1,1,1,1 }, { 1,-1,1,-1 }, { 1,1,-1,-1 }, { 1,-1,-1,1 } } };
5059 static const float itrans[2][4][4] =
5060 { { { 1,0.8660254,-0.5 }, { 1,-0.8660254,-0.5 }, { 1,0,1 } },
5061 { { 1,1,1,1 }, { 1,-1,1,-1 }, { 1,1,-1,-1 }, { 1,-1,-1,1 } } };
5062 float cam[2][4], lab[2][4], sum[2], chratio;
5064 if ((unsigned) (colors-3) > 1) return;
5065 if (verbose) fprintf (stderr,_("Blending highlights...\n"));
5066 FORCC if (clip > (i = 65535*pre_mul[c])) clip = i;
5067 for (row=0; row < height; row++)
5068 for (col=0; col < width; col++) {
5069 FORCC if (image[row*width+col][c] > clip) break;
5070 if (c == colors) continue;
5072 cam[0][c] = image[row*width+col][c];
5073 cam[1][c] = MIN(cam[0][c],clip);
5075 for (i=0; i < 2; i++) {
5076 FORCC for (lab[i][c]=j=0; j < colors; j++)
5077 lab[i][c] += trans[colors-3][c][j] * cam[i][j];
5078 for (sum[i]=0,c=1; c < colors; c++)
5079 sum[i] += SQR(lab[i][c]);
5081 chratio = sqrt(sum[1]/sum[0]);
5082 for (c=1; c < colors; c++)
5083 lab[0][c] *= chratio;
5084 FORCC for (cam[0][c]=j=0; j < colors; j++)
5085 cam[0][c] += itrans[colors-3][c][j] * lab[0][j];
5086 FORCC image[row*width+col][c] = cam[0][c] / colors;
5090 #define SCALE (4 >> shrink)
5091 void CLASS recover_highlights()
5093 float *map, sum, wgt, grow;
5094 int hsat[4], count, spread, change, val, i;
5095 unsigned high, wide, mrow, mcol, row, col, kc, c, d, y, x;
5097 static const signed char dir[8][2] =
5098 { {-1,-1}, {-1,0}, {-1,1}, {0,1}, {1,1}, {1,0}, {1,-1}, {0,-1} };
5100 if (verbose) fprintf (stderr,_("Rebuilding highlights...\n"));
5102 grow = pow (2, 4-highlight);
5103 FORCC hsat[c] = 32000 * pre_mul[c];
5104 for (kc=0, c=1; c < colors; c++)
5105 if (pre_mul[kc] < pre_mul[c]) kc = c;
5106 high = height / SCALE;
5107 wide = width / SCALE;
5108 map = (float *) calloc (high, wide*sizeof *map);
5109 merror (map, "recover_highlights()");
5110 FORCC if (c != kc) {
5111 memset (map, 0, high*wide*sizeof *map);
5112 for (mrow=0; mrow < high; mrow++)
5113 for (mcol=0; mcol < wide; mcol++) {
5114 sum = wgt = count = 0;
5115 for (row = mrow*SCALE; row < (mrow+1)*SCALE; row++)
5116 for (col = mcol*SCALE; col < (mcol+1)*SCALE; col++) {
5117 pixel = image[row*width+col];
5118 if (pixel[c] / hsat[c] == 1 && pixel[kc] > 24000) {
5124 if (count == SCALE*SCALE)
5125 map[mrow*wide+mcol] = sum / wgt;
5127 for (spread = 32/grow; spread--; ) {
5128 for (mrow=0; mrow < high; mrow++)
5129 for (mcol=0; mcol < wide; mcol++) {
5130 if (map[mrow*wide+mcol]) continue;
5132 for (d=0; d < 8; d++) {
5133 y = mrow + dir[d][0];
5134 x = mcol + dir[d][1];
5135 if (y < high && x < wide && map[y*wide+x] > 0) {
5136 sum += (1 + (d & 1)) * map[y*wide+x];
5137 count += 1 + (d & 1);
5141 map[mrow*wide+mcol] = - (sum+grow) / (count+grow);
5143 for (change=i=0; i < high*wide; i++)
5150 for (i=0; i < high*wide; i++)
5151 if (map[i] == 0) map[i] = 1;
5152 for (mrow=0; mrow < high; mrow++)
5153 for (mcol=0; mcol < wide; mcol++) {
5154 for (row = mrow*SCALE; row < (mrow+1)*SCALE; row++)
5155 for (col = mcol*SCALE; col < (mcol+1)*SCALE; col++) {
5156 pixel = image[row*width+col];
5157 if (pixel[c] / hsat[c] > 1) {
5158 val = pixel[kc] * map[mrow*wide+mcol];
5159 if (pixel[c] < val) pixel[c] = CLIP(val);
5168 void CLASS tiff_get (unsigned base,
5169 unsigned *tag, unsigned *type, unsigned *len, unsigned *save)
5174 *save = ftell(ifp) + 4;
5175 if (*len * ("11124811248484"[*type < 14 ? *type:0]-'0') > 4)
5176 fseek (ifp, get4()+base, SEEK_SET);
5179 void CLASS parse_thumb_note (int base, unsigned toff, unsigned tlen)
5181 unsigned entries, tag, type, len, save;
5185 tiff_get (base, &tag, &type, &len, &save);
5186 if (tag == toff) thumb_offset = get4()+base;
5187 if (tag == tlen) thumb_length = get4();
5188 fseek (ifp, save, SEEK_SET);
5192 int CLASS parse_tiff_ifd (int base);
5194 void CLASS parse_makernote (int base, int uptag)
5196 static const uchar xlat[2][256] = {
5197 { 0xc1,0xbf,0x6d,0x0d,0x59,0xc5,0x13,0x9d,0x83,0x61,0x6b,0x4f,0xc7,0x7f,0x3d,0x3d,
5198 0x53,0x59,0xe3,0xc7,0xe9,0x2f,0x95,0xa7,0x95,0x1f,0xdf,0x7f,0x2b,0x29,0xc7,0x0d,
5199 0xdf,0x07,0xef,0x71,0x89,0x3d,0x13,0x3d,0x3b,0x13,0xfb,0x0d,0x89,0xc1,0x65,0x1f,
5200 0xb3,0x0d,0x6b,0x29,0xe3,0xfb,0xef,0xa3,0x6b,0x47,0x7f,0x95,0x35,0xa7,0x47,0x4f,
5201 0xc7,0xf1,0x59,0x95,0x35,0x11,0x29,0x61,0xf1,0x3d,0xb3,0x2b,0x0d,0x43,0x89,0xc1,
5202 0x9d,0x9d,0x89,0x65,0xf1,0xe9,0xdf,0xbf,0x3d,0x7f,0x53,0x97,0xe5,0xe9,0x95,0x17,
5203 0x1d,0x3d,0x8b,0xfb,0xc7,0xe3,0x67,0xa7,0x07,0xf1,0x71,0xa7,0x53,0xb5,0x29,0x89,
5204 0xe5,0x2b,0xa7,0x17,0x29,0xe9,0x4f,0xc5,0x65,0x6d,0x6b,0xef,0x0d,0x89,0x49,0x2f,
5205 0xb3,0x43,0x53,0x65,0x1d,0x49,0xa3,0x13,0x89,0x59,0xef,0x6b,0xef,0x65,0x1d,0x0b,
5206 0x59,0x13,0xe3,0x4f,0x9d,0xb3,0x29,0x43,0x2b,0x07,0x1d,0x95,0x59,0x59,0x47,0xfb,
5207 0xe5,0xe9,0x61,0x47,0x2f,0x35,0x7f,0x17,0x7f,0xef,0x7f,0x95,0x95,0x71,0xd3,0xa3,
5208 0x0b,0x71,0xa3,0xad,0x0b,0x3b,0xb5,0xfb,0xa3,0xbf,0x4f,0x83,0x1d,0xad,0xe9,0x2f,
5209 0x71,0x65,0xa3,0xe5,0x07,0x35,0x3d,0x0d,0xb5,0xe9,0xe5,0x47,0x3b,0x9d,0xef,0x35,
5210 0xa3,0xbf,0xb3,0xdf,0x53,0xd3,0x97,0x53,0x49,0x71,0x07,0x35,0x61,0x71,0x2f,0x43,
5211 0x2f,0x11,0xdf,0x17,0x97,0xfb,0x95,0x3b,0x7f,0x6b,0xd3,0x25,0xbf,0xad,0xc7,0xc5,
5212 0xc5,0xb5,0x8b,0xef,0x2f,0xd3,0x07,0x6b,0x25,0x49,0x95,0x25,0x49,0x6d,0x71,0xc7 },
5213 { 0xa7,0xbc,0xc9,0xad,0x91,0xdf,0x85,0xe5,0xd4,0x78,0xd5,0x17,0x46,0x7c,0x29,0x4c,
5214 0x4d,0x03,0xe9,0x25,0x68,0x11,0x86,0xb3,0xbd,0xf7,0x6f,0x61,0x22,0xa2,0x26,0x34,
5215 0x2a,0xbe,0x1e,0x46,0x14,0x68,0x9d,0x44,0x18,0xc2,0x40,0xf4,0x7e,0x5f,0x1b,0xad,
5216 0x0b,0x94,0xb6,0x67,0xb4,0x0b,0xe1,0xea,0x95,0x9c,0x66,0xdc,0xe7,0x5d,0x6c,0x05,
5217 0xda,0xd5,0xdf,0x7a,0xef,0xf6,0xdb,0x1f,0x82,0x4c,0xc0,0x68,0x47,0xa1,0xbd,0xee,
5218 0x39,0x50,0x56,0x4a,0xdd,0xdf,0xa5,0xf8,0xc6,0xda,0xca,0x90,0xca,0x01,0x42,0x9d,
5219 0x8b,0x0c,0x73,0x43,0x75,0x05,0x94,0xde,0x24,0xb3,0x80,0x34,0xe5,0x2c,0xdc,0x9b,
5220 0x3f,0xca,0x33,0x45,0xd0,0xdb,0x5f,0xf5,0x52,0xc3,0x21,0xda,0xe2,0x22,0x72,0x6b,
5221 0x3e,0xd0,0x5b,0xa8,0x87,0x8c,0x06,0x5d,0x0f,0xdd,0x09,0x19,0x93,0xd0,0xb9,0xfc,
5222 0x8b,0x0f,0x84,0x60,0x33,0x1c,0x9b,0x45,0xf1,0xf0,0xa3,0x94,0x3a,0x12,0x77,0x33,
5223 0x4d,0x44,0x78,0x28,0x3c,0x9e,0xfd,0x65,0x57,0x16,0x94,0x6b,0xfb,0x59,0xd0,0xc8,
5224 0x22,0x36,0xdb,0xd2,0x63,0x98,0x43,0xa1,0x04,0x87,0x86,0xf7,0xa6,0x26,0xbb,0xd6,
5225 0x59,0x4d,0xbf,0x6a,0x2e,0xaa,0x2b,0xef,0xe6,0x78,0xb6,0x4e,0xe0,0x2f,0xdc,0x7c,
5226 0xbe,0x57,0x19,0x32,0x7e,0x2a,0xd0,0xb8,0xba,0x29,0x00,0x3c,0x52,0x7d,0xa8,0x49,
5227 0x3b,0x2d,0xeb,0x25,0x49,0xfa,0xa3,0xaa,0x39,0xa7,0xc5,0xa7,0x50,0x11,0x36,0xfb,
5228 0xc6,0x67,0x4a,0xf5,0xa5,0x12,0x65,0x7e,0xb0,0xdf,0xaf,0x4e,0xb3,0x61,0x7f,0x2f } };
5229 unsigned offset=0, entries, tag, type, len, save, c;
5230 unsigned ver97=0, serial=0, i, wbi=0, wb[4]={0,0,0,0};
5231 uchar buf97[324], ci, cj, ck;
5232 short morder, sorder=order;
5235 The MakerNote might have its own TIFF header (possibly with
5236 its own byte-order!), or it might just be a table.
5238 if (!strcmp(make,"Nokia")) return;
5239 fread (buf, 1, 10, ifp);
5240 if (!strncmp (buf,"KDK" ,3) || /* these aren't TIFF tables */
5241 !strncmp (buf,"VER" ,3) ||
5242 !strncmp (buf,"IIII",4) ||
5243 !strncmp (buf,"MMMM",4)) return;
5244 if (!strncmp (buf,"KC" ,2) || /* Konica KD-400Z, KD-510Z */
5245 !strncmp (buf,"MLY" ,3)) { /* Minolta DiMAGE G series */
5247 while ((i=ftell(ifp)) < data_offset && i < 16384) {
5248 wb[0] = wb[2]; wb[2] = wb[1]; wb[1] = wb[3];
5250 if (wb[1] == 256 && wb[3] == 256 &&
5251 wb[0] > 256 && wb[0] < 640 && wb[2] > 256 && wb[2] < 640)
5252 FORC4 cam_mul[c] = wb[c];
5256 if (!strcmp (buf,"Nikon")) {
5259 if (get2() != 42) goto quit;
5261 fseek (ifp, offset-8, SEEK_CUR);
5262 } else if (!strcmp (buf,"OLYMPUS") ||
5263 !strcmp (buf,"PENTAX ")) {
5264 base = ftell(ifp)-10;
5265 fseek (ifp, -2, SEEK_CUR);
5267 if (buf[0] == 'O') get2();
5268 } else if (!strncmp (buf,"SONY",4) ||
5269 !strcmp (buf,"Panasonic")) {
5271 } else if (!strncmp (buf,"FUJIFILM",8)) {
5272 base = ftell(ifp)-10;
5274 fseek (ifp, 2, SEEK_CUR);
5275 } else if (!strcmp (buf,"OLYMP") ||
5276 !strcmp (buf,"LEICA") ||
5277 !strcmp (buf,"Ricoh") ||
5278 !strcmp (buf,"EPSON"))
5279 fseek (ifp, -2, SEEK_CUR);
5280 else if (!strcmp (buf,"AOC") ||
5281 !strcmp (buf,"QVC"))
5282 fseek (ifp, -4, SEEK_CUR);
5284 fseek (ifp, -10, SEEK_CUR);
5285 if (!strncmp(make,"SAMSUNG",7))
5289 if (entries > 1000) return;
5293 tiff_get (base, &tag, &type, &len, &save);
5295 if (tag == 2 && strstr(make,"NIKON") && !iso_speed)
5296 iso_speed = (get2(),get2());
5297 if (tag == 4 && len > 26 && len < 35) {
5298 if ((i=(get4(),get2())) != 0x7fff && !iso_speed)
5299 iso_speed = 50 * pow (2, i/32.0 - 4);
5300 if ((i=(get2(),get2())) != 0x7fff && !aperture)
5301 aperture = pow (2, i/64.0);
5302 if ((i=get2()) != 0xffff && !shutter)
5303 shutter = pow (2, (short) i/-32.0);
5304 wbi = (get2(),get2());
5305 shot_order = (get2(),get2());
5307 if ((tag == 4 || tag == 0x114) && !strncmp(make,"KONICA",6)) {
5308 fseek (ifp, tag == 4 ? 140:160, SEEK_CUR);
5310 case 72: flip = 0; break;
5311 case 76: flip = 6; break;
5312 case 82: flip = 5; break;
5315 if (tag == 7 && type == 2 && len > 20)
5316 fgets (model2, 64, ifp);
5317 if (tag == 8 && type == 4)
5318 shot_order = get4();
5319 if (tag == 9 && !strcmp(make,"Canon"))
5320 fread (artist, 64, 1, ifp);
5321 if (tag == 0xc && len == 4)
5322 FORC3 cam_mul[(c << 1 | c >> 1) & 3] = getreal(type);
5323 if (tag == 0xd && type == 7 && get2() == 0xaaaa) {
5324 for (c=i=2; (ushort) c != 0xbbbb && i < len; i++)
5325 c = c << 8 | fgetc(ifp);
5326 while ((i+=4) < len-5)
5327 if (get4() == 257 && (i=len) && (c = (get4(),fgetc(ifp))) < 3)
5328 flip = "065"[c]-'0';
5330 if (tag == 0x10 && type == 4)
5332 if (tag == 0x11 && is_raw && !strncmp(make,"NIKON",5)) {
5333 fseek (ifp, get4()+base, SEEK_SET);
5334 parse_tiff_ifd (base);
5336 if (tag == 0x14 && type == 7) {
5338 fseek (ifp, 1248, SEEK_CUR);
5341 fread (buf, 1, 10, ifp);
5342 if (!strncmp(buf,"NRW ",4)) {
5343 fseek (ifp, strcmp(buf+4,"0100") ? 46:1546, SEEK_CUR);
5344 cam_mul[0] = get4() << 2;
5345 cam_mul[1] = get4() + get4();
5346 cam_mul[2] = get4() << 2;
5349 if (tag == 0x15 && type == 2 && is_raw)
5350 fread (model, 64, 1, ifp);
5351 if (strstr(make,"PENTAX")) {
5352 if (tag == 0x1b) tag = 0x1018;
5353 if (tag == 0x1c) tag = 0x1017;
5356 while ((c = fgetc(ifp)) && c != EOF)
5357 serial = serial*10 + (isdigit(c) ? c - '0' : c % 10);
5358 if (tag == 0x29 && type == 1) {
5359 c = wbi < 18 ? "012347800000005896"[wbi]-'0' : 0;
5360 fseek (ifp, 8 + c*32, SEEK_CUR);
5361 FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get4();
5363 if (tag == 0x3d && type == 3 && len == 4)
5364 FORC4 cblack[c ^ c >> 1] = get2() >> (14-tiff_bps);
5365 if (tag == 0x81 && type == 4) {
5366 data_offset = get4();
5367 fseek (ifp, data_offset + 41, SEEK_SET);
5368 raw_height = get2() * 2;
5370 filters = 0x61616161;
5372 if ((tag == 0x81 && type == 7) ||
5373 (tag == 0x100 && type == 7) ||
5374 (tag == 0x280 && type == 1)) {
5375 thumb_offset = ftell(ifp);
5378 if (tag == 0x88 && type == 4 && (thumb_offset = get4()))
5379 thumb_offset += base;
5380 if (tag == 0x89 && type == 4)
5381 thumb_length = get4();
5382 if (tag == 0x8c || tag == 0x96)
5383 meta_offset = ftell(ifp);
5385 for (i=0; i < 4; i++)
5386 ver97 = ver97 * 10 + fgetc(ifp)-'0';
5389 fseek (ifp, 68, SEEK_CUR);
5390 FORC4 cam_mul[(c >> 1) | ((c & 1) << 1)] = get2();
5393 fseek (ifp, 6, SEEK_CUR);
5394 FORC4 cam_mul[c ^ (c >> 1)] = get2();
5397 fseek (ifp, 16, SEEK_CUR);
5398 FORC4 cam_mul[c] = get2();
5401 if (ver97 != 205) fseek (ifp, 280, SEEK_CUR);
5402 fread (buf97, 324, 1, ifp);
5405 if (tag == 0xa1 && type == 7) {
5407 fseek (ifp, 140, SEEK_CUR);
5408 FORC3 cam_mul[c] = get4();
5410 if (tag == 0xa4 && type == 3) {
5411 fseek (ifp, wbi*48, SEEK_CUR);
5412 FORC3 cam_mul[c] = get2();
5414 if (tag == 0xa7 && (unsigned) (ver97-200) < 17) {
5415 ci = xlat[0][serial & 0xff];
5416 cj = xlat[1][fgetc(ifp)^fgetc(ifp)^fgetc(ifp)^fgetc(ifp)];
5418 for (i=0; i < 324; i++)
5419 buf97[i] ^= (cj += ci * ck++);
5420 i = "66666>666;6A;:;55"[ver97-200] - '0';
5421 FORC4 cam_mul[c ^ (c >> 1) ^ (i & 1)] =
5422 sget2 (buf97 + (i & -2) + c*2);
5424 if (tag == 0x200 && len == 3)
5425 shot_order = (get4(),get4());
5426 if (tag == 0x200 && len == 4)
5427 FORC4 cblack[c ^ c >> 1] = get2();
5428 if (tag == 0x201 && len == 4)
5429 FORC4 cam_mul[c ^ (c >> 1)] = get2();
5430 if (tag == 0x220 && type == 7)
5431 meta_offset = ftell(ifp);
5432 if (tag == 0x401 && type == 4 && len == 4)
5433 FORC4 cblack[c ^ c >> 1] = get4();
5434 if (tag == 0xe01) { /* Nikon Capture Note */
5436 fseek (ifp, 22, SEEK_CUR);
5437 for (offset=22; offset+22 < len; offset += 22+i) {
5439 fseek (ifp, 14, SEEK_CUR);
5441 if (tag == 0x76a43207) flip = get2();
5442 else fseek (ifp, i, SEEK_CUR);
5445 if (tag == 0xe80 && len == 256 && type == 7) {
5446 fseek (ifp, 48, SEEK_CUR);
5447 cam_mul[0] = get2() * 508 * 1.078 / 0x10000;
5448 cam_mul[2] = get2() * 382 * 1.173 / 0x10000;
5450 if (tag == 0xf00 && type == 7) {
5452 fseek (ifp, 176, SEEK_CUR);
5453 else if (len == 734 || len == 1502)
5454 fseek (ifp, 148, SEEK_CUR);
5458 if ((tag == 0x1011 && len == 9) || tag == 0x20400200)
5459 for (i=0; i < 3; i++)
5460 FORC3 cmatrix[i][c] = ((short) get2()) / 256.0;
5461 if ((tag == 0x1012 || tag == 0x20400600) && len == 4)
5462 FORC4 cblack[c ^ c >> 1] = get2();
5463 if (tag == 0x1017 || tag == 0x20400100)
5464 cam_mul[0] = get2() / 256.0;
5465 if (tag == 0x1018 || tag == 0x20400100)
5466 cam_mul[2] = get2() / 256.0;
5467 if (tag == 0x2011 && len == 2) {
5470 cam_mul[0] = get2() / 256.0;
5471 cam_mul[2] = get2() / 256.0;
5473 if ((tag | 0x70) == 0x2070 && (type == 4 || type == 13))
5474 fseek (ifp, get4()+base, SEEK_SET);
5475 if (tag == 0x2020 && !strncmp(buf,"OLYMP",5))
5476 parse_thumb_note (base, 257, 258);
5478 parse_makernote (base, 0x2040);
5479 if (tag == 0xb028) {
5480 fseek (ifp, get4()+base, SEEK_SET);
5481 parse_thumb_note (base, 136, 137);
5483 if (tag == 0x4001 && len > 500) {
5484 i = len == 582 ? 50 : len == 653 ? 68 : len == 5120 ? 142 : 126;
5485 fseek (ifp, i, SEEK_CUR);
5486 FORC4 cam_mul[c ^ (c >> 1)] = get2();
5487 for (i+=18; i <= len; i+=10) {
5489 FORC4 sraw_mul[c ^ (c >> 1)] = get2();
5490 if (sraw_mul[1] == 1170) break;
5493 if (tag == 0x4021 && get4() && get4())
5494 FORC4 cam_mul[c] = 1024;
5496 FORC4 cam_mul[c ^ (c >> 1)] = get4();
5498 FORC4 cam_mul[c ^ (c >> 1)] -= get4();
5502 fseek (ifp, save, SEEK_SET);
5509 Since the TIFF DateTime string has no timezone information,
5510 assume that the camera's clock was set to Universal Time.
5512 void CLASS get_timestamp (int reversed)
5520 for (i=19; i--; ) str[i] = fgetc(ifp);
5522 fread (str, 19, 1, ifp);
5523 memset (&t, 0, sizeof t);
5524 if (sscanf (str, "%d:%d:%d %d:%d:%d", &t.tm_year, &t.tm_mon,
5525 &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec) != 6)
5531 timestamp = mktime(&t);
5534 void CLASS parse_exif (int base)
5536 unsigned kodak, entries, tag, type, len, save, c;
5539 kodak = !strncmp(make,"EASTMAN",7) && tiff_nifds < 3;
5542 tiff_get (base, &tag, &type, &len, &save);
5544 case 33434: tiff_ifd[tiff_nifds-1].shutter =
5545 shutter = getreal(type); break;
5546 case 33437: aperture = getreal(type); break;
5547 case 34855: iso_speed = get2(); break;
5549 case 36868: get_timestamp(0); break;
5550 case 37377: if ((expo = -getreal(type)) < 128)
5551 tiff_ifd[tiff_nifds-1].shutter =
5552 shutter = pow (2, expo); break;
5553 case 37378: aperture = pow (2, getreal(type)/2); break;
5554 case 37386: focal_len = getreal(type); break;
5555 case 37500: parse_makernote (base, 0); break;
5556 case 40962: if (kodak) raw_width = get4(); break;
5557 case 40963: if (kodak) raw_height = get4(); break;
5559 if (get4() == 0x20002)
5560 for (exif_cfa=c=0; c < 8; c+=2)
5561 exif_cfa |= fgetc(ifp) * 0x01010101 << c;
5563 fseek (ifp, save, SEEK_SET);
5567 void CLASS parse_gps (int base)
5569 unsigned entries, tag, type, len, save, c;
5573 tiff_get (base, &tag, &type, &len, &save);
5575 case 1: case 3: case 5:
5576 gpsdata[29+tag/2] = getc(ifp); break;
5577 case 2: case 4: case 7:
5578 FORC(6) gpsdata[tag/3*6+c] = get4(); break;
5580 FORC(2) gpsdata[18+c] = get4(); break;
5582 fgets ((char *) (gpsdata+14+tag/3), MIN(len,12), ifp);
5584 fseek (ifp, save, SEEK_SET);
5588 void CLASS romm_coeff (float romm_cam[3][3])
5590 static const float rgb_romm[3][3] = /* ROMM == Kodak ProPhoto */
5591 { { 2.034193, -0.727420, -0.306766 },
5592 { -0.228811, 1.231729, -0.002922 },
5593 { -0.008565, -0.153273, 1.161839 } };
5596 for (i=0; i < 3; i++)
5597 for (j=0; j < 3; j++)
5598 for (cmatrix[i][j] = k=0; k < 3; k++)
5599 cmatrix[i][j] += rgb_romm[i][k] * romm_cam[k][j];
5602 void CLASS parse_mos (int offset)
5605 int skip, from, i, c, neut[4], planes=0, frot=0;
5606 static const char *mod[] =
5607 { "","DCB2","Volare","Cantare","CMost","Valeo 6","Valeo 11","Valeo 22",
5608 "Valeo 11p","Valeo 17","","Aptus 17","Aptus 22","Aptus 75","Aptus 65",
5609 "Aptus 54S","Aptus 65S","Aptus 75S","AFi 5","AFi 6","AFi 7",
5610 "AFi-II 7","Aptus-II 7","","Aptus-II 6","","","Aptus-II 10","Aptus-II 5",
5611 "","","","","Aptus-II 10R","Aptus-II 8","","Aptus-II 12","","AFi-II 12" };
5612 float romm_cam[3][3];
5614 fseek (ifp, offset, SEEK_SET);
5616 if (get4() != 0x504b5453) break;
5618 fread (data, 1, 40, ifp);
5621 if (!strcmp(data,"JPEG_preview_data")) {
5622 thumb_offset = from;
5623 thumb_length = skip;
5625 if (!strcmp(data,"icc_camera_profile")) {
5626 profile_offset = from;
5627 profile_length = skip;
5629 if (!strcmp(data,"ShootObj_back_type")) {
5630 fscanf (ifp, "%d", &i);
5631 if ((unsigned) i < sizeof mod / sizeof (*mod))
5632 strcpy (model, mod[i]);
5634 if (!strcmp(data,"icc_camera_to_tone_matrix")) {
5635 for (i=0; i < 9; i++)
5636 ((float *)romm_cam)[i] = int_to_float(get4());
5637 romm_coeff (romm_cam);
5639 if (!strcmp(data,"CaptProf_color_matrix")) {
5640 for (i=0; i < 9; i++)
5641 fscanf (ifp, "%f", (float *)romm_cam + i);
5642 romm_coeff (romm_cam);
5644 if (!strcmp(data,"CaptProf_number_of_planes"))
5645 fscanf (ifp, "%d", &planes);
5646 if (!strcmp(data,"CaptProf_raw_data_rotation"))
5647 fscanf (ifp, "%d", &flip);
5648 if (!strcmp(data,"CaptProf_mosaic_pattern"))
5650 fscanf (ifp, "%d", &i);
5651 if (i == 1) frot = c ^ (c >> 1);
5653 if (!strcmp(data,"ImgProf_rotation_angle")) {
5654 fscanf (ifp, "%d", &i);
5657 if (!strcmp(data,"NeutObj_neutrals") && !cam_mul[0]) {
5658 FORC4 fscanf (ifp, "%d", neut+c);
5659 FORC3 cam_mul[c] = (float) neut[0] / neut[c+1];
5661 if (!strcmp(data,"Rows_data"))
5662 load_flags = get4();
5664 fseek (ifp, skip+from, SEEK_SET);
5667 filters = (planes == 1) * 0x01010101 *
5668 (uchar) "\x94\x61\x16\x49"[(flip/90 + frot) & 3];
5671 void CLASS linear_table (unsigned len)
5674 if (len > 0x1000) len = 0x1000;
5675 read_shorts (curve, len);
5676 for (i=len; i < 0x1000; i++)
5677 curve[i] = curve[i-1];
5678 maximum = curve[0xfff];
5681 void CLASS parse_kodak_ifd (int base)
5683 unsigned entries, tag, type, len, save;
5684 int i, c, wbi=-2, wbtemp=6500;
5685 float mul[3]={1,1,1}, num;
5686 static const int wbtag[] = { 64037,64040,64039,64041,-1,-1,64042 };
5689 if (entries > 1024) return;
5691 tiff_get (base, &tag, &type, &len, &save);
5692 if (tag == 1020) wbi = getint(type);
5693 if (tag == 1021 && len == 72) { /* WB set in software */
5694 fseek (ifp, 40, SEEK_CUR);
5695 FORC3 cam_mul[c] = 2048.0 / get2();
5698 if (tag == 2118) wbtemp = getint(type);
5699 if (tag == 2120 + wbi && wbi >= 0)
5700 FORC3 cam_mul[c] = 2048.0 / getreal(type);
5701 if (tag == 2130 + wbi)
5702 FORC3 mul[c] = getreal(type);
5703 if (tag == 2140 + wbi && wbi >= 0)
5705 for (num=i=0; i < 4; i++)
5706 num += getreal(type) * pow (wbtemp/100.0, i);
5707 cam_mul[c] = 2048 / (num * mul[c]);
5709 if (tag == 2317) linear_table (len);
5710 if (tag == 6020) iso_speed = getint(type);
5711 if (tag == 64013) wbi = fgetc(ifp);
5712 if ((unsigned) wbi < 7 && tag == wbtag[wbi])
5713 FORC3 cam_mul[c] = get4();
5714 if (tag == 64019) width = getint(type);
5715 if (tag == 64020) height = (getint(type)+1) & -2;
5716 fseek (ifp, save, SEEK_SET);
5720 void CLASS parse_minolta (int base);
5721 int CLASS parse_tiff (int base);
5723 int CLASS parse_tiff_ifd (int base)
5725 unsigned entries, tag, type, len, plen=16, save;
5726 int ifd, use_cm=0, cfa, i, j, c, ima_len=0;
5727 char software[64], *cbuf, *cp;
5728 uchar cfa_pat[16], cfa_pc[] = { 0,1,2,3 }, tab[256];
5729 double cc[4][4], cm[4][3], cam_xyz[4][3], num;
5730 double ab[]={ 1,1,1,1 }, asn[] = { 0,0,0,0 }, xyz[] = { 1,1,1 };
5731 unsigned sony_curve[] = { 0,0,0,0,0,4095 };
5732 unsigned *buf, sony_offset=0, sony_length=0, sony_key=0;
5736 if (tiff_nifds >= sizeof tiff_ifd / sizeof tiff_ifd[0])
5739 for (j=0; j < 4; j++)
5740 for (i=0; i < 4; i++)
5743 if (entries > 512) return 1;
5745 tiff_get (base, &tag, &type, &len, &save);
5747 case 5: width = get2(); break;
5748 case 6: height = get2(); break;
5749 case 7: width += get2(); break;
5750 case 9: if ((i = get2())) filters = i; break;
5752 if (type == 3 && len == 1)
5753 cam_mul[(tag-17)*2] = get2() / 256.0;
5756 if (type == 3) iso_speed = get2();
5758 case 28: case 29: case 30:
5759 cblack[tag-28] = get2();
5760 cblack[3] = cblack[1];
5762 case 36: case 37: case 38:
5763 cam_mul[tag-36] = get2();
5766 if (len < 50 || cam_mul[0]) break;
5767 fseek (ifp, 12, SEEK_CUR);
5768 FORC3 cam_mul[c] = get2();
5771 if (type != 7 || fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) break;
5772 thumb_offset = ftell(ifp) - 2;
5775 case 61440: /* Fuji HS10 table */
5776 fseek (ifp, get4()+base, SEEK_SET);
5777 parse_tiff_ifd (base);
5779 case 2: case 256: case 61441: /* ImageWidth */
5780 tiff_ifd[ifd].width = getint(type);
5782 case 3: case 257: case 61442: /* ImageHeight */
5783 tiff_ifd[ifd].height = getint(type);
5785 case 258: /* BitsPerSample */
5787 tiff_ifd[ifd].samples = len & 7;
5788 tiff_ifd[ifd].bps = getint(type);
5789 if (tiff_bps < tiff_ifd[ifd].bps)
5790 tiff_bps = tiff_ifd[ifd].bps;
5794 if (tiff_ifd[ifd].bps > 12) break;
5795 load_raw = &CLASS packed_load_raw;
5796 load_flags = get4() ? 24:80;
5798 case 259: /* Compression */
5799 tiff_ifd[ifd].comp = getint(type);
5801 case 262: /* PhotometricInterpretation */
5802 tiff_ifd[ifd].phint = get2();
5804 case 270: /* ImageDescription */
5805 fread (desc, 512, 1, ifp);
5807 case 271: /* Make */
5808 fgets (make, 64, ifp);
5810 case 272: /* Model */
5811 fgets (model, 64, ifp);
5813 case 280: /* Panasonic RW2 offset */
5814 if (type != 4) break;
5815 load_raw = &CLASS panasonic_load_raw;
5816 load_flags = 0x2008;
5817 case 273: /* StripOffset */
5818 case 513: /* JpegIFOffset */
5820 tiff_ifd[ifd].offset = get4()+base;
5821 if (!tiff_ifd[ifd].bps && tiff_ifd[ifd].offset > 0) {
5822 fseek (ifp, tiff_ifd[ifd].offset, SEEK_SET);
5823 if (ljpeg_start (&jh, 1)) {
5824 tiff_ifd[ifd].comp = 6;
5825 tiff_ifd[ifd].width = jh.wide;
5826 tiff_ifd[ifd].height = jh.high;
5827 tiff_ifd[ifd].bps = jh.bits;
5828 tiff_ifd[ifd].samples = jh.clrs;
5829 if (!(jh.sraw || (jh.clrs & 1)))
5830 tiff_ifd[ifd].width *= jh.clrs;
5831 if ((tiff_ifd[ifd].width > 4*tiff_ifd[ifd].height) & ~jh.clrs) {
5832 tiff_ifd[ifd].width /= 2;
5833 tiff_ifd[ifd].height *= 2;
5836 parse_tiff (tiff_ifd[ifd].offset + 12);
5841 case 274: /* Orientation */
5842 tiff_ifd[ifd].flip = "50132467"[get2() & 7]-'0';
5844 case 277: /* SamplesPerPixel */
5845 tiff_ifd[ifd].samples = getint(type) & 7;
5847 case 279: /* StripByteCounts */
5850 tiff_ifd[ifd].bytes = get4();
5853 FORC3 cam_mul[(4-c) % 3] = getint(type);
5855 case 305: case 11: /* Software */
5856 fgets (software, 64, ifp);
5857 if (!strncmp(software,"Adobe",5) ||
5858 !strncmp(software,"dcraw",5) ||
5859 !strncmp(software,"UFRaw",5) ||
5860 !strncmp(software,"Bibble",6) ||
5861 !strncmp(software,"Nikon Scan",10) ||
5862 !strcmp (software,"Digital Photo Professional"))
5865 case 306: /* DateTime */
5868 case 315: /* Artist */
5869 fread (artist, 64, 1, ifp);
5871 case 322: /* TileWidth */
5872 tiff_ifd[ifd].tile_width = getint(type);
5874 case 323: /* TileLength */
5875 tiff_ifd[ifd].tile_length = getint(type);
5877 case 324: /* TileOffsets */
5878 tiff_ifd[ifd].offset = len > 1 ? ftell(ifp) : get4();
5880 tiff_ifd[ifd].tile_width = tiff_ifd[ifd].tile_length = 0;
5882 load_raw = &CLASS sinar_4shot_load_raw;
5886 case 330: /* SubIFDs */
5887 if (!strcmp(model,"DSLR-A100") && tiff_ifd[ifd].width == 3872) {
5888 load_raw = &CLASS sony_arw_load_raw;
5889 data_offset = get4()+base;
5894 fseek (ifp, get4()+base, SEEK_SET);
5895 if (parse_tiff_ifd (base)) break;
5896 fseek (ifp, i+4, SEEK_SET);
5900 strcpy (make, "Sarnoff");
5904 FORC4 sony_curve[c+1] = get2() >> 2 & 0xfff;
5905 for (i=0; i < 5; i++)
5906 for (j = sony_curve[i]+1; j <= sony_curve[i+1]; j++)
5907 curve[j] = curve[j-1] + (1 << i);
5909 case 29184: sony_offset = get4(); break;
5910 case 29185: sony_length = get4(); break;
5911 case 29217: sony_key = get4(); break;
5913 parse_minolta (ftell(ifp));
5917 FORC4 cam_mul[c ^ (c < 2)] = get2();
5920 FORC4 cam_mul[c] = get2();
5921 i = (cam_mul[1] == 1024 && cam_mul[2] == 1024) << 1;
5922 SWAP (cam_mul[i],cam_mul[i+1])
5924 case 33405: /* Model2 */
5925 fgets (model2, 64, ifp);
5927 case 33421: /* CFARepeatPatternDim */
5928 if (get2() == 6 && get2() == 6)
5931 case 33422: /* CFAPattern */
5933 FORC(36) ((char *)xtrans)[c] = fgetc(ifp) & 3;
5936 case 64777: /* Kodak P-series */
5937 if ((plen=len) > 16) plen = 16;
5938 fread (cfa_pat, 1, plen, ifp);
5939 for (colors=cfa=i=0; i < plen && colors < 4; i++) {
5940 colors += !(cfa & (1 << cfa_pat[i]));
5941 cfa |= 1 << cfa_pat[i];
5943 if (cfa == 070) memcpy (cfa_pc,"\003\004\005",3); /* CMY */
5944 if (cfa == 072) memcpy (cfa_pc,"\005\003\004\001",4); /* GMCY */
5948 fseek (ifp, get4()+base, SEEK_SET);
5949 parse_kodak_ifd (base);
5951 case 33434: /* ExposureTime */
5952 tiff_ifd[ifd].shutter = shutter = getreal(type);
5954 case 33437: /* FNumber */
5955 aperture = getreal(type);
5957 case 34306: /* Leaf white balance */
5958 FORC4 cam_mul[c ^ 1] = 4096.0 / get2();
5960 case 34307: /* Leaf CatchLight color matrix */
5961 fread (software, 1, 7, ifp);
5962 if (strncmp(software,"MATRIX",6)) break;
5964 for (raw_color = i=0; i < 3; i++) {
5965 FORC4 fscanf (ifp, "%f", &rgb_cam[i][c^1]);
5966 if (!use_camera_wb) continue;
5968 FORC4 num += rgb_cam[i][c];
5969 FORC4 rgb_cam[i][c] /= num;
5972 case 34310: /* Leaf metadata */
5973 parse_mos (ftell(ifp));
5975 strcpy (make, "Leaf");
5977 case 34665: /* EXIF tag */
5978 fseek (ifp, get4()+base, SEEK_SET);
5981 case 34853: /* GPSInfo tag */
5982 fseek (ifp, get4()+base, SEEK_SET);
5985 case 34675: /* InterColorProfile */
5986 case 50831: /* AsShotICCProfile */
5987 profile_offset = ftell(ifp);
5988 profile_length = len;
5990 case 37122: /* CompressedBitsPerPixel */
5991 kodak_cbpp = get4();
5993 case 37386: /* FocalLength */
5994 focal_len = getreal(type);
5996 case 37393: /* ImageNumber */
5997 shot_order = getint(type);
5999 case 37400: /* old Kodak KDC tag */
6000 for (raw_color = i=0; i < 3; i++) {
6002 FORC3 rgb_cam[i][c] = getreal(type);
6006 strip_offset = get4();
6007 switch (tiff_ifd[ifd].comp) {
6008 case 32770: load_raw = &CLASS samsung_load_raw; break;
6009 case 32772: load_raw = &CLASS samsung2_load_raw; break;
6010 case 32773: load_raw = &CLASS samsung3_load_raw; break;
6013 case 46275: /* Imacon tags */
6014 strcpy (make, "Imacon");
6015 data_offset = ftell(ifp);
6019 if (!ima_len) break;
6020 fseek (ifp, 38, SEEK_CUR);
6022 fseek (ifp, 40, SEEK_CUR);
6024 raw_height = get4();
6025 left_margin = get4() & 7;
6026 width = raw_width - left_margin - (get4() & 7);
6027 top_margin = get4() & 7;
6028 height = raw_height - top_margin - (get4() & 7);
6029 if (raw_width == 7262) {
6034 fseek (ifp, 52, SEEK_CUR);
6035 FORC3 cam_mul[c] = getreal(11);
6036 fseek (ifp, 114, SEEK_CUR);
6037 flip = (get2() >> 7) * 90;
6038 if (width * height * 6 == ima_len) {
6039 if (flip % 180 == 90) SWAP(width,height);
6041 raw_height = height;
6042 left_margin = top_margin = filters = flip = 0;
6044 sprintf (model, "Ixpress %d-Mp", height*width/1000000);
6045 load_raw = &CLASS imacon_full_load_raw;
6047 if (left_margin & 1) filters = 0x61616161;
6048 load_raw = &CLASS unpacked_load_raw;
6052 case 50454: /* Sinar tag */
6054 if (!(cbuf = (char *) malloc(len))) break;
6055 fread (cbuf, 1, len, ifp);
6056 for (cp = cbuf-1; cp && cp < cbuf+len; cp = strchr(cp,'\n'))
6057 if (!strncmp (++cp,"Neutral ",8))
6058 sscanf (cp+8, "%f %f %f", cam_mul, cam_mul+1, cam_mul+2);
6062 if (!make[0]) strcpy (make, "Hasselblad");
6064 case 50459: /* Hasselblad tag */
6069 fseek (ifp, j+(get2(),get4()), SEEK_SET);
6075 case 50706: /* DNGVersion */
6076 FORC4 dng_version = (dng_version << 8) + fgetc(ifp);
6077 if (!make[0]) strcpy (make, "DNG");
6080 case 50708: /* UniqueCameraModel */
6081 if (model[0]) break;
6082 fgets (make, 64, ifp);
6083 if ((cp = strchr(make,' '))) {
6088 case 50710: /* CFAPlaneColor */
6089 if (filters == 9) break;
6090 if (len > 4) len = 4;
6092 fread (cfa_pc, 1, colors, ifp);
6094 FORCC tab[cfa_pc[c]] = c;
6097 filters = filters << 2 | tab[cfa_pat[i % plen]];
6098 filters -= !filters;
6100 case 50711: /* CFALayout */
6101 if (get2() == 2) fuji_width = 1;
6104 case 50712: /* LinearizationTable */
6107 case 50713: /* BlackLevelRepeatDim */
6110 if (cblack[4] * cblack[5] > sizeof cblack / sizeof *cblack - 6)
6111 cblack[4] = cblack[5] = 1;
6114 cblack[4] = cblack[5] = MIN(sqrt(len),64);
6115 case 50714: /* BlackLevel */
6116 if (!(cblack[4] * cblack[5]))
6117 cblack[4] = cblack[5] = 1;
6118 FORC (cblack[4] * cblack[5])
6119 cblack[6+c] = getreal(type);
6122 case 50715: /* BlackLevelDeltaH */
6123 case 50716: /* BlackLevelDeltaV */
6124 for (num=i=0; i < (len & 0xffff); i++)
6125 num += getreal(type);
6126 black += num/len + 0.5;
6128 case 50717: /* WhiteLevel */
6129 maximum = getint(type);
6131 case 50718: /* DefaultScale */
6132 pixel_aspect = getreal(type);
6133 pixel_aspect /= getreal(type);
6135 case 50721: /* ColorMatrix1 */
6136 case 50722: /* ColorMatrix2 */
6137 FORCC for (j=0; j < 3; j++)
6138 cm[c][j] = getreal(type);
6141 case 50723: /* CameraCalibration1 */
6142 case 50724: /* CameraCalibration2 */
6143 for (i=0; i < colors; i++)
6144 FORCC cc[i][c] = getreal(type);
6146 case 50727: /* AnalogBalance */
6147 FORCC ab[c] = getreal(type);
6149 case 50728: /* AsShotNeutral */
6150 FORCC asn[c] = getreal(type);
6152 case 50729: /* AsShotWhiteXY */
6153 xyz[0] = getreal(type);
6154 xyz[1] = getreal(type);
6155 xyz[2] = 1 - xyz[0] - xyz[1];
6156 FORC3 xyz[c] /= d65_white[c];
6158 case 50740: /* DNGPrivateData */
6159 if (dng_version) break;
6160 parse_minolta (j = get4()+base);
6161 fseek (ifp, j, SEEK_SET);
6162 parse_tiff_ifd (base);
6165 read_shorts (cr2_slice, 3);
6167 case 50829: /* ActiveArea */
6168 top_margin = getint(type);
6169 left_margin = getint(type);
6170 height = getint(type) - top_margin;
6171 width = getint(type) - left_margin;
6173 case 50830: /* MaskedAreas */
6174 for (i=0; i < len && i < 32; i++)
6175 ((int *)mask)[i] = getint(type);
6178 case 51009: /* OpcodeList2 */
6179 meta_offset = ftell(ifp);
6181 case 64772: /* Kodak P-series */
6182 if (len < 13) break;
6183 fseek (ifp, 16, SEEK_CUR);
6184 data_offset = get4();
6185 fseek (ifp, 28, SEEK_CUR);
6186 data_offset += get4();
6187 load_raw = &CLASS packed_load_raw;
6190 if (type == 2) fgets (model2, 64, ifp);
6192 fseek (ifp, save, SEEK_SET);
6194 if (sony_length && (buf = (unsigned *) malloc(sony_length))) {
6195 fseek (ifp, sony_offset, SEEK_SET);
6196 fread (buf, sony_length, 1, ifp);
6197 sony_decrypt (buf, sony_length/4, 1, sony_key);
6199 if ((ifp = tmpfile())) {
6200 fwrite (buf, sony_length, 1, ifp);
6201 fseek (ifp, 0, SEEK_SET);
6202 parse_tiff_ifd (-sony_offset);
6208 for (i=0; i < colors; i++)
6209 FORCC cc[i][c] *= ab[i];
6211 FORCC for (i=0; i < 3; i++)
6212 for (cam_xyz[c][i]=j=0; j < colors; j++)
6213 cam_xyz[c][i] += cc[c][j] * cm[j][i] * xyz[i];
6214 cam_xyz_coeff (cmatrix, cam_xyz);
6218 FORCC cam_mul[c] = 1 / asn[c];
6221 FORCC pre_mul[c] /= cc[c][c];
6225 int CLASS parse_tiff (int base)
6229 fseek (ifp, base, SEEK_SET);
6231 if (order != 0x4949 && order != 0x4d4d) return 0;
6233 while ((doff = get4())) {
6234 fseek (ifp, doff+base, SEEK_SET);
6235 if (parse_tiff_ifd (base)) break;
6240 void CLASS apply_tiff()
6242 int max_samp=0, ties=0, os, ns, raw=-1, thm=-1, i;
6247 fseek (ifp, thumb_offset, SEEK_SET);
6248 if (ljpeg_start (&jh, 1)) {
6249 thumb_misc = jh.bits;
6250 thumb_width = jh.wide;
6251 thumb_height = jh.high;
6254 for (i=tiff_nifds; i--; ) {
6255 if (tiff_ifd[i].shutter)
6256 shutter = tiff_ifd[i].shutter;
6257 tiff_ifd[i].shutter = shutter;
6259 for (i=0; i < tiff_nifds; i++) {
6260 if (max_samp < tiff_ifd[i].samples)
6261 max_samp = tiff_ifd[i].samples;
6262 if (max_samp > 3) max_samp = 3;
6263 os = raw_width*raw_height;
6264 ns = tiff_ifd[i].width*tiff_ifd[i].height;
6267 ns *= tiff_ifd[i].bps;
6269 if ((tiff_ifd[i].comp != 6 || tiff_ifd[i].samples != 3) &&
6270 (tiff_ifd[i].width | tiff_ifd[i].height) < 0x10000 &&
6271 ns && ((ns > os && (ties = 1)) ||
6272 (ns == os && shot_select == ties++))) {
6273 raw_width = tiff_ifd[i].width;
6274 raw_height = tiff_ifd[i].height;
6275 tiff_bps = tiff_ifd[i].bps;
6276 tiff_compress = tiff_ifd[i].comp;
6277 data_offset = tiff_ifd[i].offset;
6278 tiff_flip = tiff_ifd[i].flip;
6279 tiff_samples = tiff_ifd[i].samples;
6280 tile_width = tiff_ifd[i].tile_width;
6281 tile_length = tiff_ifd[i].tile_length;
6282 shutter = tiff_ifd[i].shutter;
6286 if (is_raw == 1 && ties) is_raw = ties;
6287 if (!tile_width ) tile_width = INT_MAX;
6288 if (!tile_length) tile_length = INT_MAX;
6289 for (i=tiff_nifds; i--; )
6290 if (tiff_ifd[i].flip) tiff_flip = tiff_ifd[i].flip;
6291 if (raw >= 0 && !load_raw)
6292 switch (tiff_compress) {
6294 if (tiff_ifd[raw].bytes == raw_width*raw_height) {
6296 load_raw = &CLASS sony_arw2_load_raw; break;
6298 if (tiff_ifd[raw].bytes*8 != raw_width*raw_height*tiff_bps) {
6300 load_raw = &CLASS sony_arw_load_raw; break;
6306 case 32773: goto slr;
6308 if (!strncmp(make,"OLYMPUS",7) &&
6309 tiff_ifd[raw].bytes*2 == raw_width*raw_height*3)
6311 if (tiff_ifd[raw].bytes*5 == raw_width*raw_height*8) {
6316 case 8: load_raw = &CLASS eight_bit_load_raw; break;
6317 case 12: if (tiff_ifd[raw].phint == 2)
6319 load_raw = &CLASS packed_load_raw; break;
6320 case 14: load_flags = 0;
6321 case 16: load_raw = &CLASS unpacked_load_raw;
6322 if (!strncmp(make,"OLYMPUS",7) &&
6323 tiff_ifd[raw].bytes*7 > raw_width*raw_height)
6324 load_raw = &CLASS olympus_load_raw;
6327 case 6: case 7: case 99:
6328 load_raw = &CLASS lossless_jpeg_load_raw; break;
6330 load_raw = &CLASS kodak_262_load_raw; break;
6332 if ((raw_width+9)/10*16*raw_height == tiff_ifd[raw].bytes) {
6333 load_raw = &CLASS packed_load_raw;
6335 } else if (raw_width*raw_height*3 == tiff_ifd[raw].bytes*2) {
6336 load_raw = &CLASS packed_load_raw;
6337 if (model[0] == 'N') load_flags = 80;
6338 } else if (raw_width*raw_height*3 == tiff_ifd[raw].bytes) {
6339 load_raw = &CLASS nikon_yuv_load_raw;
6340 gamma_curve (1/2.4, 12.92, 1, 4095);
6341 memset (cblack, 0, sizeof cblack);
6343 } else if (raw_width*raw_height*2 == tiff_ifd[raw].bytes) {
6344 load_raw = &CLASS unpacked_load_raw;
6348 load_raw = &CLASS nikon_load_raw; break;
6350 load_raw = &CLASS pentax_load_raw; break;
6352 switch (tiff_ifd[raw].phint) {
6353 case 2: load_raw = &CLASS kodak_rgb_load_raw; filters = 0; break;
6354 case 6: load_raw = &CLASS kodak_ycbcr_load_raw; filters = 0; break;
6355 case 32803: load_raw = &CLASS kodak_65000_load_raw;
6357 case 32867: case 34892: break;
6358 default: is_raw = 0;
6361 if ( (tiff_samples == 3 && tiff_ifd[raw].bytes && tiff_bps != 14 &&
6362 (tiff_compress & -16) != 32768)
6363 || (tiff_bps == 8 && strncmp(make,"Phase",5) &&
6364 !strcasestr(make,"Kodak") && !strstr(model2,"DEBUG RAW")))
6366 for (i=0; i < tiff_nifds; i++)
6367 if (i != raw && tiff_ifd[i].samples == max_samp &&
6368 tiff_ifd[i].width * tiff_ifd[i].height / (SQR(tiff_ifd[i].bps)+1) >
6369 thumb_width * thumb_height / (SQR(thumb_misc)+1)
6370 && tiff_ifd[i].comp != 34892) {
6371 thumb_width = tiff_ifd[i].width;
6372 thumb_height = tiff_ifd[i].height;
6373 thumb_offset = tiff_ifd[i].offset;
6374 thumb_length = tiff_ifd[i].bytes;
6375 thumb_misc = tiff_ifd[i].bps;
6379 thumb_misc |= tiff_ifd[thm].samples << 5;
6380 switch (tiff_ifd[thm].comp) {
6382 write_thumb = &CLASS layer_thumb;
6385 if (tiff_ifd[thm].bps <= 8)
6386 write_thumb = &CLASS ppm_thumb;
6387 else if (!strcmp(make,"Imacon"))
6388 write_thumb = &CLASS ppm16_thumb;
6390 thumb_load_raw = &CLASS kodak_thumb_load_raw;
6393 thumb_load_raw = tiff_ifd[thm].phint == 6 ?
6394 &CLASS kodak_ycbcr_load_raw : &CLASS kodak_rgb_load_raw;
6399 void CLASS parse_minolta (int base)
6401 int save, tag, len, offset, high=0, wide=0, i, c;
6404 fseek (ifp, base, SEEK_SET);
6405 if (fgetc(ifp) || fgetc(ifp)-'M' || fgetc(ifp)-'R') return;
6406 order = fgetc(ifp) * 0x101;
6407 offset = base + get4() + 8;
6408 while ((save=ftell(ifp)) < offset) {
6409 for (tag=i=0; i < 4; i++)
6410 tag = tag << 8 | fgetc(ifp);
6413 case 0x505244: /* PRD */
6414 fseek (ifp, 8, SEEK_CUR);
6418 case 0x574247: /* WBG */
6420 i = strcmp(model,"DiMAGE A200") ? 0:3;
6421 FORC4 cam_mul[c ^ (c >> 1) ^ i] = get2();
6423 case 0x545457: /* TTW */
6424 parse_tiff (ftell(ifp));
6425 data_offset = offset;
6427 fseek (ifp, save+len+8, SEEK_SET);
6435 Many cameras have a "debug mode" that writes JPEG and raw
6436 at the same time. The raw file has no header, so try to
6437 to open the matching JPEG file and read its metadata.
6439 void CLASS parse_external_jpeg()
6441 const char *file, *ext;
6442 char *jname, *jfile, *jext;
6445 ext = strrchr (ifname, '.');
6446 file = strrchr (ifname, '/');
6447 if (!file) file = strrchr (ifname, '\\');
6448 if (!file) file = ifname-1;
6450 if (!ext || strlen(ext) != 4 || ext-file != 8) return;
6451 jname = (char *) malloc (strlen(ifname) + 1);
6452 merror (jname, "parse_external_jpeg()");
6453 strcpy (jname, ifname);
6454 jfile = file - ifname + jname;
6455 jext = ext - ifname + jname;
6456 if (strcasecmp (ext, ".jpg")) {
6457 strcpy (jext, isupper(ext[1]) ? ".JPG":".jpg");
6458 if (isdigit(*file)) {
6459 memcpy (jfile, file+4, 4);
6460 memcpy (jfile+4, file, 4);
6463 while (isdigit(*--jext)) {
6470 if (strcmp (jname, ifname)) {
6471 if ((ifp = fopen (jname, "rb"))) {
6473 fprintf (stderr,_("Reading metadata from %s ...\n"), jname);
6481 fprintf (stderr,_("Failed to read metadata from %s\n"), jname);
6487 CIFF block 0x1030 contains an 8x8 white sample.
6488 Load this into white[][] for use in scale_colors().
6490 void CLASS ciff_block_1030()
6492 static const ushort key[] = { 0x410, 0x45f3 };
6493 int i, bpp, row, col, vbits=0;
6494 unsigned long bitbuf=0;
6496 if ((get2(),get4()) != 0x80008 || !get4()) return;
6498 if (bpp != 10 && bpp != 12) return;
6499 for (i=row=0; row < 8; row++)
6500 for (col=0; col < 8; col++) {
6502 bitbuf = bitbuf << 16 | (get2() ^ key[i++ & 1]);
6505 white[row][col] = bitbuf >> (vbits -= bpp) & ~(-1 << bpp);
6510 Parse a CIFF file, better known as Canon CRW format.
6512 void CLASS parse_ciff (int offset, int length, int depth)
6514 int tboff, nrecs, c, type, len, save, wbi=-1;
6515 ushort key[] = { 0x410, 0x45f3 };
6517 fseek (ifp, offset+length-4, SEEK_SET);
6518 tboff = get4() + offset;
6519 fseek (ifp, tboff, SEEK_SET);
6521 if ((nrecs | depth) > 127) return;
6525 save = ftell(ifp) + 4;
6526 fseek (ifp, offset+get4(), SEEK_SET);
6527 if ((((type >> 8) + 8) | 8) == 0x38)
6528 parse_ciff (ftell(ifp), len, depth+1); /* Parse a sub-table */
6530 fread (artist, 64, 1, ifp);
6531 if (type == 0x080a) {
6532 fread (make, 64, 1, ifp);
6533 fseek (ifp, strlen(make) - 63, SEEK_CUR);
6534 fread (model, 64, 1, ifp);
6536 if (type == 0x1810) {
6539 pixel_aspect = int_to_float(get4());
6542 if (type == 0x1835) /* Get the decoder table */
6543 tiff_compress = get4();
6544 if (type == 0x2007) {
6545 thumb_offset = ftell(ifp);
6548 if (type == 0x1818) {
6549 shutter = pow (2, -int_to_float((get4(),get4())));
6550 aperture = pow (2, int_to_float(get4())/2);
6552 if (type == 0x102a) {
6553 iso_speed = pow (2, (get4(),get2())/32.0 - 4) * 50;
6554 aperture = pow (2, (get2(),(short)get2())/64.0);
6555 shutter = pow (2,-((short)get2())/32.0);
6556 wbi = (get2(),get2());
6557 if (wbi > 17) wbi = 0;
6558 fseek (ifp, 32, SEEK_CUR);
6559 if (shutter > 1e6) shutter = get2()/10.0;
6561 if (type == 0x102c) {
6562 if (get2() > 512) { /* Pro90, G1 */
6563 fseek (ifp, 118, SEEK_CUR);
6564 FORC4 cam_mul[c ^ 2] = get2();
6565 } else { /* G2, S30, S40 */
6566 fseek (ifp, 98, SEEK_CUR);
6567 FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get2();
6570 if (type == 0x0032) {
6571 if (len == 768) { /* EOS D30 */
6572 fseek (ifp, 72, SEEK_CUR);
6573 FORC4 cam_mul[c ^ (c >> 1)] = 1024.0 / get2();
6574 if (!wbi) cam_mul[0] = -1; /* use my auto white balance */
6575 } else if (!cam_mul[0]) {
6576 if (get2() == key[0]) /* Pro1, G6, S60, S70 */
6577 c = (strstr(model,"Pro1") ?
6578 "012346000000000000":"01345:000000006008")[wbi]-'0'+ 2;
6579 else { /* G3, G5, S45, S50 */
6580 c = "023457000000006000"[wbi]-'0';
6581 key[0] = key[1] = 0;
6583 fseek (ifp, 78 + c*8, SEEK_CUR);
6584 FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get2() ^ key[c & 1];
6585 if (!wbi) cam_mul[0] = -1;
6588 if (type == 0x10a9) { /* D60, 10D, 300D, and clones */
6589 if (len > 66) wbi = "0134567028"[wbi]-'0';
6590 fseek (ifp, 2 + wbi*8, SEEK_CUR);
6591 FORC4 cam_mul[c ^ (c >> 1)] = get2();
6593 if (type == 0x1030 && (0x18040 >> wbi & 1))
6594 ciff_block_1030(); /* all that don't have 0x10a9 */
6595 if (type == 0x1031) {
6596 raw_width = (get2(),get2());
6597 raw_height = get2();
6599 if (type == 0x5029) {
6600 focal_len = len >> 16;
6601 if ((len & 0xffff) == 2) focal_len /= 32;
6603 if (type == 0x5813) flash_used = int_to_float(len);
6604 if (type == 0x5814) canon_ev = int_to_float(len);
6605 if (type == 0x5817) shot_order = len;
6606 if (type == 0x5834) unique_id = len;
6607 if (type == 0x580e) timestamp = len;
6608 if (type == 0x180e) timestamp = get4();
6610 if ((type | 0x4000) == 0x580e)
6611 timestamp = mktime (gmtime (×tamp));
6613 fseek (ifp, save, SEEK_SET);
6617 void CLASS parse_rollei()
6619 char line[128], *val;
6622 fseek (ifp, 0, SEEK_SET);
6623 memset (&t, 0, sizeof t);
6625 fgets (line, 128, ifp);
6626 if ((val = strchr(line,'=')))
6629 val = line + strlen(line);
6630 if (!strcmp(line,"DAT"))
6631 sscanf (val, "%d.%d.%d", &t.tm_mday, &t.tm_mon, &t.tm_year);
6632 if (!strcmp(line,"TIM"))
6633 sscanf (val, "%d:%d:%d", &t.tm_hour, &t.tm_min, &t.tm_sec);
6634 if (!strcmp(line,"HDR"))
6635 thumb_offset = atoi(val);
6636 if (!strcmp(line,"X "))
6637 raw_width = atoi(val);
6638 if (!strcmp(line,"Y "))
6639 raw_height = atoi(val);
6640 if (!strcmp(line,"TX "))
6641 thumb_width = atoi(val);
6642 if (!strcmp(line,"TY "))
6643 thumb_height = atoi(val);
6644 } while (strncmp(line,"EOHD",4));
6645 data_offset = thumb_offset + thumb_width * thumb_height * 2;
6649 timestamp = mktime(&t);
6650 strcpy (make, "Rollei");
6651 strcpy (model,"d530flex");
6652 write_thumb = &CLASS rollei_thumb;
6655 void CLASS parse_sinar_ia()
6661 fseek (ifp, 4, SEEK_SET);
6663 fseek (ifp, get4(), SEEK_SET);
6665 off = get4(); get4();
6666 fread (str, 8, 1, ifp);
6667 if (!strcmp(str,"META")) meta_offset = off;
6668 if (!strcmp(str,"THUMB")) thumb_offset = off;
6669 if (!strcmp(str,"RAW0")) data_offset = off;
6671 fseek (ifp, meta_offset+20, SEEK_SET);
6672 fread (make, 64, 1, ifp);
6674 if ((cp = strchr(make,' '))) {
6675 strcpy (model, cp+1);
6679 raw_height = get2();
6680 load_raw = &CLASS unpacked_load_raw;
6681 thumb_width = (get4(),get2());
6682 thumb_height = get2();
6683 write_thumb = &CLASS ppm_thumb;
6687 void CLASS parse_phase_one (int base)
6690 unsigned entries, tag, /*type,*/ len, data, save, i, c;
6691 float romm_cam[3][3];
6694 memset (&ph1, 0, sizeof ph1);
6695 fseek (ifp, base, SEEK_SET);
6696 order = get4() & 0xffff;
6697 if (get4() >> 8 != 0x526177) return; /* "Raw" */
6698 fseek (ifp, get4()+base, SEEK_SET);
6708 fseek (ifp, base+data, SEEK_SET);
6710 case 0x100: flip = "0653"[data & 3]-'0'; break;
6712 for (i=0; i < 9; i++)
6713 ((float *)romm_cam)[i] = getreal(11);
6714 romm_coeff (romm_cam);
6717 FORC3 cam_mul[c] = getreal(11);
6719 case 0x108: raw_width = data; break;
6720 case 0x109: raw_height = data; break;
6721 case 0x10a: left_margin = data; break;
6722 case 0x10b: top_margin = data; break;
6723 case 0x10c: width = data; break;
6724 case 0x10d: height = data; break;
6725 case 0x10e: ph1.format = data; break;
6726 case 0x10f: data_offset = data+base; break;
6727 case 0x110: meta_offset = data+base;
6728 meta_length = len; break;
6729 case 0x112: ph1.key_off = save - 4; break;
6730 case 0x210: ph1.tag_210 = int_to_float(data); break;
6731 case 0x21a: ph1.tag_21a = data; break;
6732 case 0x21c: strip_offset = data+base; break;
6733 case 0x21d: ph1.black = data; break;
6734 case 0x222: ph1.split_col = data; break;
6735 case 0x223: ph1.black_col = data+base; break;
6736 case 0x224: ph1.split_row = data; break;
6737 case 0x225: ph1.black_row = data+base; break;
6740 fread (model, 1, 63, ifp);
6741 if ((cp = strstr(model," camera"))) *cp = 0;
6743 fseek (ifp, save, SEEK_SET);
6745 load_raw = ph1.format < 3 ?
6746 &CLASS phase_one_load_raw : &CLASS phase_one_load_raw_c;
6748 strcpy (make, "Phase One");
6749 if (model[0]) return;
6750 switch (raw_height) {
6751 case 2060: strcpy (model,"LightPhase"); break;
6752 case 2682: strcpy (model,"H 10"); break;
6753 case 4128: strcpy (model,"H 20"); break;
6754 case 5488: strcpy (model,"H 25"); break;
6758 void CLASS parse_fuji (int offset)
6760 unsigned entries, tag, len, save, c;
6762 fseek (ifp, offset, SEEK_SET);
6764 if (entries > 255) return;
6770 raw_height = get2();
6772 } else if (tag == 0x121) {
6774 if ((width = get2()) == 4284) width += 3;
6775 } else if (tag == 0x130) {
6776 fuji_layout = fgetc(ifp) >> 7;
6777 fuji_width = !(fgetc(ifp) & 8);
6778 } else if (tag == 0x131) {
6780 FORC(36) xtrans_abs[0][35-c] = fgetc(ifp) & 3;
6781 } else if (tag == 0x2ff0) {
6782 FORC4 cam_mul[c ^ 1] = get2();
6783 } else if (tag == 0xc000) {
6786 while ((tag = get4()) > raw_width);
6791 fseek (ifp, save+len, SEEK_SET);
6793 height <<= fuji_layout;
6794 width >>= fuji_layout;
6797 int CLASS parse_jpeg (int offset)
6799 int len, save, hlen, mark;
6801 fseek (ifp, offset, SEEK_SET);
6802 if (fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) return 0;
6804 while (fgetc(ifp) == 0xff && (mark = fgetc(ifp)) != 0xda) {
6808 if (mark == 0xc0 || mark == 0xc3 || mark == 0xc9) {
6810 raw_height = get2();
6815 if (get4() == 0x48454150) /* "HEAP" */
6816 parse_ciff (save+hlen, len-hlen, 0);
6817 if (parse_tiff (save+6)) apply_tiff();
6818 fseek (ifp, save+len, SEEK_SET);
6823 void CLASS parse_riff()
6825 unsigned i, size, end;
6826 char tag[4], date[64], month[64];
6827 static const char mon[12][4] =
6828 { "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" };
6832 fread (tag, 4, 1, ifp);
6834 end = ftell(ifp) + size;
6835 if (!memcmp(tag,"RIFF",4) || !memcmp(tag,"LIST",4)) {
6837 while (ftell(ifp)+7 < end && !feof(ifp))
6839 } else if (!memcmp(tag,"nctg",4)) {
6840 while (ftell(ifp)+7 < end) {
6843 if ((i+1) >> 1 == 10 && size == 20)
6845 else fseek (ifp, size, SEEK_CUR);
6847 } else if (!memcmp(tag,"IDIT",4) && size < 64) {
6848 fread (date, 64, 1, ifp);
6850 memset (&t, 0, sizeof t);
6851 if (sscanf (date, "%*s %s %d %d:%d:%d %d", month, &t.tm_mday,
6852 &t.tm_hour, &t.tm_min, &t.tm_sec, &t.tm_year) == 6) {
6853 for (i=0; i < 12 && strcasecmp(mon[i],month); i++);
6857 timestamp = mktime(&t);
6860 fseek (ifp, size, SEEK_CUR);
6863 void CLASS parse_qt (int end)
6865 unsigned save, size;
6869 while (ftell(ifp)+7 < end) {
6871 if ((size = get4()) < 8) return;
6872 fread (tag, 4, 1, ifp);
6873 if (!memcmp(tag,"moov",4) ||
6874 !memcmp(tag,"udta",4) ||
6875 !memcmp(tag,"CNTH",4))
6876 parse_qt (save+size);
6877 if (!memcmp(tag,"CNDA",4))
6878 parse_jpeg (ftell(ifp));
6879 fseek (ifp, save+size, SEEK_SET);
6883 void CLASS parse_smal (int offset, int fsize)
6887 fseek (ifp, offset+2, SEEK_SET);
6891 fseek (ifp, 5, SEEK_CUR);
6892 if (get4() != fsize) return;
6893 if (ver > 6) data_offset = get4();
6894 raw_height = height = get2();
6895 raw_width = width = get2();
6896 strcpy (make, "SMaL");
6897 sprintf (model, "v%d %dx%d", ver, width, height);
6898 if (ver == 6) load_raw = &CLASS smal_v6_load_raw;
6899 if (ver == 9) load_raw = &CLASS smal_v9_load_raw;
6902 void CLASS parse_cine()
6904 unsigned off_head, off_setup, off_image, i;
6907 fseek (ifp, 4, SEEK_SET);
6908 is_raw = get2() == 2;
6909 fseek (ifp, 14, SEEK_CUR);
6915 if ((i = get4())) timestamp = i;
6916 fseek (ifp, off_head+4, SEEK_SET);
6918 raw_height = get4();
6919 switch (get2(),get2()) {
6920 case 8: load_raw = &CLASS eight_bit_load_raw; break;
6921 case 16: load_raw = &CLASS unpacked_load_raw;
6923 fseek (ifp, off_setup+792, SEEK_SET);
6924 strcpy (make, "CINE");
6925 sprintf (model, "%d", get4());
6926 fseek (ifp, 12, SEEK_CUR);
6927 switch ((i=get4()) & 0xffffff) {
6928 case 3: filters = 0x94949494; break;
6929 case 4: filters = 0x49494949; break;
6930 default: is_raw = 0;
6932 fseek (ifp, 72, SEEK_CUR);
6933 switch ((get4()+3600) % 360) {
6934 case 270: flip = 4; break;
6935 case 180: flip = 1; break;
6936 case 90: flip = 7; break;
6939 cam_mul[0] = getreal(11);
6940 cam_mul[2] = getreal(11);
6941 maximum = ~(-1 << get4());
6942 fseek (ifp, 668, SEEK_CUR);
6943 shutter = get4()/1000000000.0;
6944 fseek (ifp, off_image, SEEK_SET);
6945 if (shot_select < is_raw)
6946 fseek (ifp, shot_select*8, SEEK_CUR);
6947 data_offset = (INT64) get4() + 8;
6948 data_offset += (INT64) get4() << 32;
6951 void CLASS parse_redcine()
6953 unsigned i, len, rdvo;
6957 fseek (ifp, 52, SEEK_SET);
6960 fseek (ifp, 0, SEEK_END);
6961 fseek (ifp, -(i = ftello(ifp) & 511), SEEK_CUR);
6962 if (get4() != i || get4() != 0x52454f42) {
6963 fprintf (stderr,_("%s: Tail is missing, parsing from head...\n"), ifname);
6964 fseek (ifp, 0, SEEK_SET);
6965 while ((len = get4()) != EOF) {
6966 if (get4() == 0x52454456)
6967 if (is_raw++ == shot_select)
6968 data_offset = ftello(ifp) - 8;
6969 fseek (ifp, len-8, SEEK_CUR);
6973 fseek (ifp, 12, SEEK_CUR);
6975 fseeko (ifp, rdvo+8 + shot_select*4, SEEK_SET);
6976 data_offset = get4();
6980 char * CLASS foveon_gets (int offset, char *str, int len)
6983 fseek (ifp, offset, SEEK_SET);
6984 for (i=0; i < len-1; i++)
6985 if ((str[i] = get2()) == 0) break;
6990 void CLASS parse_foveon()
6992 int entries, img=0, off, len, tag, save, i, wide, high, pent, poff[256][2];
6993 char name[64], value[64];
6995 order = 0x4949; /* Little-endian */
6996 fseek (ifp, 36, SEEK_SET);
6998 fseek (ifp, -4, SEEK_END);
6999 fseek (ifp, get4(), SEEK_SET);
7000 if (get4() != 0x64434553) return; /* SECd */
7001 entries = (get4(),get4());
7007 fseek (ifp, off, SEEK_SET);
7008 if (get4() != (0x20434553 | (tag << 24))) return;
7010 case 0x47414d49: /* IMAG */
7011 case 0x32414d49: /* IMA2 */
7012 fseek (ifp, 8, SEEK_CUR);
7016 if (wide > raw_width && high > raw_height) {
7018 case 5: load_flags = 1;
7019 case 6: load_raw = &CLASS foveon_sd_load_raw; break;
7020 case 30: load_raw = &CLASS foveon_dp_load_raw; break;
7021 default: load_raw = 0;
7025 data_offset = off+28;
7028 fseek (ifp, off+28, SEEK_SET);
7029 if (fgetc(ifp) == 0xff && fgetc(ifp) == 0xd8
7030 && thumb_length < len-28) {
7031 thumb_offset = off+28;
7032 thumb_length = len-28;
7033 write_thumb = &CLASS jpeg_thumb;
7035 if (++img == 2 && !thumb_length) {
7036 thumb_offset = off+24;
7038 thumb_height = high;
7039 write_thumb = &CLASS foveon_thumb;
7042 case 0x464d4143: /* CAMF */
7043 meta_offset = off+8;
7044 meta_length = len-28;
7046 case 0x504f5250: /* PROP */
7047 pent = (get4(),get4());
7048 fseek (ifp, 12, SEEK_CUR);
7050 if ((unsigned) pent > 256) pent=256;
7051 for (i=0; i < pent*2; i++)
7052 ((int *)poff)[i] = off + get4()*2;
7053 for (i=0; i < pent; i++) {
7054 foveon_gets (poff[i][0], name, 64);
7055 foveon_gets (poff[i][1], value, 64);
7056 if (!strcmp (name, "ISO"))
7057 iso_speed = atoi(value);
7058 if (!strcmp (name, "CAMMANUF"))
7059 strcpy (make, value);
7060 if (!strcmp (name, "CAMMODEL"))
7061 strcpy (model, value);
7062 if (!strcmp (name, "WB_DESC"))
7063 strcpy (model2, value);
7064 if (!strcmp (name, "TIME"))
7065 timestamp = atoi(value);
7066 if (!strcmp (name, "EXPTIME"))
7067 shutter = atoi(value) / 1000000.0;
7068 if (!strcmp (name, "APERTURE"))
7069 aperture = atof(value);
7070 if (!strcmp (name, "FLENGTH"))
7071 focal_len = atof(value);
7074 timestamp = mktime (gmtime (×tamp));
7077 fseek (ifp, save, SEEK_SET);
7082 All matrices are from Adobe DNG Converter unless otherwise noted.
7084 void CLASS adobe_coeff (const char *make, const char *model)
7086 static const struct {
7088 short black, maximum, trans[12];
7090 { "AgfaPhoto DC-833m", 0, 0, /* DJC */
7091 { 11438,-3762,-1115,-2409,9914,2497,-1227,2295,5300 } },
7092 { "Apple QuickTake", 0, 0, /* DJC */
7093 { 21392,-5653,-3353,2406,8010,-415,7166,1427,2078 } },
7094 { "Canon EOS D2000", 0, 0,
7095 { 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } },
7096 { "Canon EOS D6000", 0, 0,
7097 { 20482,-7172,-3125,-1033,10410,-285,2542,226,3136 } },
7098 { "Canon EOS D30", 0, 0,
7099 { 9805,-2689,-1312,-5803,13064,3068,-2438,3075,8775 } },
7100 { "Canon EOS D60", 0, 0xfa0,
7101 { 6188,-1341,-890,-7168,14489,2937,-2640,3228,8483 } },
7102 { "Canon EOS 5DS", 0, 0x3c96,
7103 { 6250,-711,-808,-5153,12794,2636,-1249,2198,5610 } },
7104 { "Canon EOS 5D Mark III", 0, 0x3c80,
7105 { 6722,-635,-963,-4287,12460,2028,-908,2162,5668 } },
7106 { "Canon EOS 5D Mark II", 0, 0x3cf0,
7107 { 4716,603,-830,-7798,15474,2480,-1496,1937,6651 } },
7108 { "Canon EOS 5D", 0, 0xe6c,
7109 { 6347,-479,-972,-8297,15954,2480,-1968,2131,7649 } },
7110 { "Canon EOS 6D", 0, 0x3c82,
7111 { 7034,-804,-1014,-4420,12564,2058,-851,1994,5758 } },
7112 { "Canon EOS 7D Mark II", 0, 0x3510,
7113 { 7268,-1082,-969,-4186,11839,2663,-825,2029,5839 } },
7114 { "Canon EOS 7D", 0, 0x3510,
7115 { 6844,-996,-856,-3876,11761,2396,-593,1772,6198 } },
7116 { "Canon EOS 10D", 0, 0xfa0,
7117 { 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } },
7118 { "Canon EOS 20Da", 0, 0,
7119 { 14155,-5065,-1382,-6550,14633,2039,-1623,1824,6561 } },
7120 { "Canon EOS 20D", 0, 0xfff,
7121 { 6599,-537,-891,-8071,15783,2424,-1983,2234,7462 } },
7122 { "Canon EOS 30D", 0, 0,
7123 { 6257,-303,-1000,-7880,15621,2396,-1714,1904,7046 } },
7124 { "Canon EOS 40D", 0, 0x3f60,
7125 { 6071,-747,-856,-7653,15365,2441,-2025,2553,7315 } },
7126 { "Canon EOS 50D", 0, 0x3d93,
7127 { 4920,616,-593,-6493,13964,2784,-1774,3178,7005 } },
7128 { "Canon EOS 60D", 0, 0x2ff7,
7129 { 6719,-994,-925,-4408,12426,2211,-887,2129,6051 } },
7130 { "Canon EOS 70D", 0, 0x3bc7,
7131 { 7034,-804,-1014,-4420,12564,2058,-851,1994,5758 } },
7132 { "Canon EOS 80D", 0, 0,
7133 { 7457,-671,-937,-4849,12495,2643,-1213,2354,5492 } },
7134 { "Canon EOS 100D", 0, 0x350f,
7135 { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } },
7136 { "Canon EOS 300D", 0, 0xfa0,
7137 { 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } },
7138 { "Canon EOS 350D", 0, 0xfff,
7139 { 6018,-617,-965,-8645,15881,2975,-1530,1719,7642 } },
7140 { "Canon EOS 400D", 0, 0xe8e,
7141 { 7054,-1501,-990,-8156,15544,2812,-1278,1414,7796 } },
7142 { "Canon EOS 450D", 0, 0x390d,
7143 { 5784,-262,-821,-7539,15064,2672,-1982,2681,7427 } },
7144 { "Canon EOS 500D", 0, 0x3479,
7145 { 4763,712,-646,-6821,14399,2640,-1921,3276,6561 } },
7146 { "Canon EOS 550D", 0, 0x3dd7,
7147 { 6941,-1164,-857,-3825,11597,2534,-416,1540,6039 } },
7148 { "Canon EOS 600D", 0, 0x3510,
7149 { 6461,-907,-882,-4300,12184,2378,-819,1944,5931 } },
7150 { "Canon EOS 650D", 0, 0x354d,
7151 { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } },
7152 { "Canon EOS 700D", 0, 0x3c00,
7153 { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } },
7154 { "Canon EOS 750D", 0, 0x368e,
7155 { 6362,-823,-847,-4426,12109,2616,-743,1857,5635 } },
7156 { "Canon EOS 760D", 0, 0x350f,
7157 { 6362,-823,-847,-4426,12109,2616,-743,1857,5635 } },
7158 { "Canon EOS 1000D", 0, 0xe43,
7159 { 6771,-1139,-977,-7818,15123,2928,-1244,1437,7533 } },
7160 { "Canon EOS 1100D", 0, 0x3510,
7161 { 6444,-904,-893,-4563,12308,2535,-903,2016,6728 } },
7162 { "Canon EOS 1200D", 0, 0x37c2,
7163 { 6461,-907,-882,-4300,12184,2378,-819,1944,5931 } },
7164 { "Canon EOS 1300D", 0, 0x3510,
7165 { 6939,-1016,-866,-4428,12473,2177,-1175,2178,6162 } },
7166 { "Canon EOS M3", 0, 0,
7167 { 6362,-823,-847,-4426,12109,2616,-743,1857,5635 } },
7168 { "Canon EOS M10", 0, 0,
7169 { 6400,-480,-888,-5294,13416,2047,-1296,2203,6137 } },
7170 { "Canon EOS M", 0, 0,
7171 { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } },
7172 { "Canon EOS-1Ds Mark III", 0, 0x3bb0,
7173 { 5859,-211,-930,-8255,16017,2353,-1732,1887,7448 } },
7174 { "Canon EOS-1Ds Mark II", 0, 0xe80,
7175 { 6517,-602,-867,-8180,15926,2378,-1618,1771,7633 } },
7176 { "Canon EOS-1D Mark IV", 0, 0x3bb0,
7177 { 6014,-220,-795,-4109,12014,2361,-561,1824,5787 } },
7178 { "Canon EOS-1D Mark III", 0, 0x3bb0,
7179 { 6291,-540,-976,-8350,16145,2311,-1714,1858,7326 } },
7180 { "Canon EOS-1D Mark II N", 0, 0xe80,
7181 { 6240,-466,-822,-8180,15825,2500,-1801,1938,8042 } },
7182 { "Canon EOS-1D Mark II", 0, 0xe80,
7183 { 6264,-582,-724,-8312,15948,2504,-1744,1919,8664 } },
7184 { "Canon EOS-1DS", 0, 0xe20,
7185 { 4374,3631,-1743,-7520,15212,2472,-2892,3632,8161 } },
7186 { "Canon EOS-1D C", 0, 0x3c4e,
7187 { 6847,-614,-1014,-4669,12737,2139,-1197,2488,6846 } },
7188 { "Canon EOS-1D X Mark II", 0, 0,
7189 { 7596,-978,-967,-4808,12571,2503,-1398,2567,5752 } },
7190 { "Canon EOS-1D X", 0, 0x3c4e,
7191 { 6847,-614,-1014,-4669,12737,2139,-1197,2488,6846 } },
7192 { "Canon EOS-1D", 0, 0xe20,
7193 { 6806,-179,-1020,-8097,16415,1687,-3267,4236,7690 } },
7194 { "Canon EOS C500", 853, 0, /* DJC */
7195 { 17851,-10604,922,-7425,16662,763,-3660,3636,22278 } },
7196 { "Canon PowerShot A530", 0, 0,
7197 { 0 } }, /* don't want the A5 matrix */
7198 { "Canon PowerShot A50", 0, 0,
7199 { -5300,9846,1776,3436,684,3939,-5540,9879,6200,-1404,11175,217 } },
7200 { "Canon PowerShot A5", 0, 0,
7201 { -4801,9475,1952,2926,1611,4094,-5259,10164,5947,-1554,10883,547 } },
7202 { "Canon PowerShot G10", 0, 0,
7203 { 11093,-3906,-1028,-5047,12492,2879,-1003,1750,5561 } },
7204 { "Canon PowerShot G11", 0, 0,
7205 { 12177,-4817,-1069,-1612,9864,2049,-98,850,4471 } },
7206 { "Canon PowerShot G12", 0, 0,
7207 { 13244,-5501,-1248,-1508,9858,1935,-270,1083,4366 } },
7208 { "Canon PowerShot G15", 0, 0,
7209 { 7474,-2301,-567,-4056,11456,2975,-222,716,4181 } },
7210 { "Canon PowerShot G16", 0, 0,
7211 { 8020,-2687,-682,-3704,11879,2052,-965,1921,5556 } },
7212 { "Canon PowerShot G1 X", 0, 0,
7213 { 7378,-1255,-1043,-4088,12251,2048,-876,1946,5805 } },
7214 { "Canon PowerShot G1", 0, 0,
7215 { -4778,9467,2172,4743,-1141,4344,-5146,9908,6077,-1566,11051,557 } },
7216 { "Canon PowerShot G2", 0, 0,
7217 { 9087,-2693,-1049,-6715,14382,2537,-2291,2819,7790 } },
7218 { "Canon PowerShot G3 X", 0, 0,
7219 { 9701,-3857,-921,-3149,11537,1817,-786,1817,5147 } },
7220 { "Canon PowerShot G3", 0, 0,
7221 { 9212,-2781,-1073,-6573,14189,2605,-2300,2844,7664 } },
7222 { "Canon PowerShot G5 X", 0, 0,
7223 { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } },
7224 { "Canon PowerShot G5", 0, 0,
7225 { 9757,-2872,-933,-5972,13861,2301,-1622,2328,7212 } },
7226 { "Canon PowerShot G6", 0, 0,
7227 { 9877,-3775,-871,-7613,14807,3072,-1448,1305,7485 } },
7228 { "Canon PowerShot G7 X", 0, 0,
7229 { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } },
7230 { "Canon PowerShot G9 X", 0, 0,
7231 { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } },
7232 { "Canon PowerShot G9", 0, 0,
7233 { 7368,-2141,-598,-5621,13254,2625,-1418,1696,5743 } },
7234 { "Canon PowerShot Pro1", 0, 0,
7235 { 10062,-3522,-999,-7643,15117,2730,-765,817,7323 } },
7236 { "Canon PowerShot Pro70", 34, 0,
7237 { -4155,9818,1529,3939,-25,4522,-5521,9870,6610,-2238,10873,1342 } },
7238 { "Canon PowerShot Pro90", 0, 0,
7239 { -4963,9896,2235,4642,-987,4294,-5162,10011,5859,-1770,11230,577 } },
7240 { "Canon PowerShot S30", 0, 0,
7241 { 10566,-3652,-1129,-6552,14662,2006,-2197,2581,7670 } },
7242 { "Canon PowerShot S40", 0, 0,
7243 { 8510,-2487,-940,-6869,14231,2900,-2318,2829,9013 } },
7244 { "Canon PowerShot S45", 0, 0,
7245 { 8163,-2333,-955,-6682,14174,2751,-2077,2597,8041 } },
7246 { "Canon PowerShot S50", 0, 0,
7247 { 8882,-2571,-863,-6348,14234,2288,-1516,2172,6569 } },
7248 { "Canon PowerShot S60", 0, 0,
7249 { 8795,-2482,-797,-7804,15403,2573,-1422,1996,7082 } },
7250 { "Canon PowerShot S70", 0, 0,
7251 { 9976,-3810,-832,-7115,14463,2906,-901,989,7889 } },
7252 { "Canon PowerShot S90", 0, 0,
7253 { 12374,-5016,-1049,-1677,9902,2078,-83,852,4683 } },
7254 { "Canon PowerShot S95", 0, 0,
7255 { 13440,-5896,-1279,-1236,9598,1931,-180,1001,4651 } },
7256 { "Canon PowerShot S100", 0, 0,
7257 { 7968,-2565,-636,-2873,10697,2513,180,667,4211 } },
7258 { "Canon PowerShot S110", 0, 0,
7259 { 8039,-2643,-654,-3783,11230,2930,-206,690,4194 } },
7260 { "Canon PowerShot S120", 0, 0,
7261 { 6961,-1685,-695,-4625,12945,1836,-1114,2152,5518 } },
7262 { "Canon PowerShot SX1 IS", 0, 0,
7263 { 6578,-259,-502,-5974,13030,3309,-308,1058,4970 } },
7264 { "Canon PowerShot SX50 HS", 0, 0,
7265 { 12432,-4753,-1247,-2110,10691,1629,-412,1623,4926 } },
7266 { "Canon PowerShot SX60 HS", 0, 0,
7267 { 13161,-5451,-1344,-1989,10654,1531,-47,1271,4955 } },
7268 { "Canon PowerShot A3300", 0, 0, /* DJC */
7269 { 10826,-3654,-1023,-3215,11310,1906,0,999,4960 } },
7270 { "Canon PowerShot A470", 0, 0, /* DJC */
7271 { 12513,-4407,-1242,-2680,10276,2405,-878,2215,4734 } },
7272 { "Canon PowerShot A610", 0, 0, /* DJC */
7273 { 15591,-6402,-1592,-5365,13198,2168,-1300,1824,5075 } },
7274 { "Canon PowerShot A620", 0, 0, /* DJC */
7275 { 15265,-6193,-1558,-4125,12116,2010,-888,1639,5220 } },
7276 { "Canon PowerShot A630", 0, 0, /* DJC */
7277 { 14201,-5308,-1757,-6087,14472,1617,-2191,3105,5348 } },
7278 { "Canon PowerShot A640", 0, 0, /* DJC */
7279 { 13124,-5329,-1390,-3602,11658,1944,-1612,2863,4885 } },
7280 { "Canon PowerShot A650", 0, 0, /* DJC */
7281 { 9427,-3036,-959,-2581,10671,1911,-1039,1982,4430 } },
7282 { "Canon PowerShot A720", 0, 0, /* DJC */
7283 { 14573,-5482,-1546,-1266,9799,1468,-1040,1912,3810 } },
7284 { "Canon PowerShot S3 IS", 0, 0, /* DJC */
7285 { 14062,-5199,-1446,-4712,12470,2243,-1286,2028,4836 } },
7286 { "Canon PowerShot SX110 IS", 0, 0, /* DJC */
7287 { 14134,-5576,-1527,-1991,10719,1273,-1158,1929,3581 } },
7288 { "Canon PowerShot SX220", 0, 0, /* DJC */
7289 { 13898,-5076,-1447,-1405,10109,1297,-244,1860,3687 } },
7290 { "Canon IXUS 160", 0, 0, /* DJC */
7291 { 11657,-3781,-1136,-3544,11262,2283,-160,1219,4700 } },
7292 { "Casio EX-S20", 0, 0, /* DJC */
7293 { 11634,-3924,-1128,-4968,12954,2015,-1588,2648,7206 } },
7294 { "Casio EX-Z750", 0, 0, /* DJC */
7295 { 10819,-3873,-1099,-4903,13730,1175,-1755,3751,4632 } },
7296 { "Casio EX-Z10", 128, 0xfff, /* DJC */
7297 { 9790,-3338,-603,-2321,10222,2099,-344,1273,4799 } },
7299 { 3390,480,-500,-800,3610,340,-550,2336,1192 } },
7301 { 3390,480,-500,-800,3610,340,-550,2336,1192 } },
7303 { 20183,-4295,-423,-3940,15330,3985,-280,4870,9800 } },
7304 { "Contax N Digital", 0, 0xf1e,
7305 { 7777,1285,-1053,-9280,16543,2916,-3677,5679,7060 } },
7307 { 6596,-2079,-562,-4782,13016,1933,-970,1581,5181 } },
7308 { "Epson R-D1", 0, 0,
7309 { 6827,-1878,-732,-8429,16012,2564,-704,592,7145 } },
7310 { "Fujifilm E550", 0, 0,
7311 { 11044,-3888,-1120,-7248,15168,2208,-1531,2277,8069 } },
7312 { "Fujifilm E900", 0, 0,
7313 { 9183,-2526,-1078,-7461,15071,2574,-2022,2440,8639 } },
7314 { "Fujifilm F5", 0, 0,
7315 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
7316 { "Fujifilm F6", 0, 0,
7317 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
7318 { "Fujifilm F77", 0, 0xfe9,
7319 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
7320 { "Fujifilm F7", 0, 0,
7321 { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } },
7322 { "Fujifilm F8", 0, 0,
7323 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
7324 { "Fujifilm S100FS", 514, 0,
7325 { 11521,-4355,-1065,-6524,13767,3058,-1466,1984,6045 } },
7326 { "Fujifilm S1", 0, 0,
7327 { 12297,-4882,-1202,-2106,10691,1623,-88,1312,4790 } },
7328 { "Fujifilm S20Pro", 0, 0,
7329 { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } },
7330 { "Fujifilm S20", 512, 0x3fff,
7331 { 11401,-4498,-1312,-5088,12751,2613,-838,1568,5941 } },
7332 { "Fujifilm S2Pro", 128, 0,
7333 { 12492,-4690,-1402,-7033,15423,1647,-1507,2111,7697 } },
7334 { "Fujifilm S3Pro", 0, 0,
7335 { 11807,-4612,-1294,-8927,16968,1988,-2120,2741,8006 } },
7336 { "Fujifilm S5Pro", 0, 0,
7337 { 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } },
7338 { "Fujifilm S5000", 0, 0,
7339 { 8754,-2732,-1019,-7204,15069,2276,-1702,2334,6982 } },
7340 { "Fujifilm S5100", 0, 0,
7341 { 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } },
7342 { "Fujifilm S5500", 0, 0,
7343 { 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } },
7344 { "Fujifilm S5200", 0, 0,
7345 { 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } },
7346 { "Fujifilm S5600", 0, 0,
7347 { 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } },
7348 { "Fujifilm S6", 0, 0,
7349 { 12628,-4887,-1401,-6861,14996,1962,-2198,2782,7091 } },
7350 { "Fujifilm S7000", 0, 0,
7351 { 10190,-3506,-1312,-7153,15051,2238,-2003,2399,7505 } },
7352 { "Fujifilm S9000", 0, 0,
7353 { 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 } },
7354 { "Fujifilm S9500", 0, 0,
7355 { 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 } },
7356 { "Fujifilm S9100", 0, 0,
7357 { 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 } },
7358 { "Fujifilm S9600", 0, 0,
7359 { 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 } },
7360 { "Fujifilm SL1000", 0, 0,
7361 { 11705,-4262,-1107,-2282,10791,1709,-555,1713,4945 } },
7362 { "Fujifilm IS-1", 0, 0,
7363 { 21461,-10807,-1441,-2332,10599,1999,289,875,7703 } },
7364 { "Fujifilm IS Pro", 0, 0,
7365 { 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } },
7366 { "Fujifilm HS10 HS11", 0, 0xf68,
7367 { 12440,-3954,-1183,-1123,9674,1708,-83,1614,4086 } },
7368 { "Fujifilm HS2", 0, 0,
7369 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
7370 { "Fujifilm HS3", 0, 0,
7371 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
7372 { "Fujifilm HS50EXR", 0, 0,
7373 { 12085,-4727,-953,-3257,11489,2002,-511,2046,4592 } },
7374 { "Fujifilm F900EXR", 0, 0,
7375 { 12085,-4727,-953,-3257,11489,2002,-511,2046,4592 } },
7376 { "Fujifilm X100S", 0, 0,
7377 { 10592,-4262,-1008,-3514,11355,2465,-870,2025,6386 } },
7378 { "Fujifilm X100T", 0, 0,
7379 { 10592,-4262,-1008,-3514,11355,2465,-870,2025,6386 } },
7380 { "Fujifilm X100", 0, 0,
7381 { 12161,-4457,-1069,-5034,12874,2400,-795,1724,6904 } },
7382 { "Fujifilm X10", 0, 0,
7383 { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } },
7384 { "Fujifilm X20", 0, 0,
7385 { 11768,-4971,-1133,-4904,12927,2183,-480,1723,4605 } },
7386 { "Fujifilm X30", 0, 0,
7387 { 12328,-5256,-1144,-4469,12927,1675,-87,1291,4351 } },
7388 { "Fujifilm X70", 0, 0,
7389 { 10450,-4329,-878,-3217,11105,2421,-752,1758,6519 } },
7390 { "Fujifilm X-Pro1", 0, 0,
7391 { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } },
7392 { "Fujifilm X-Pro2", 0, 0,
7393 { 11434,-4948,-1210,-3746,12042,1903,-666,1479,5235 } },
7394 { "Fujifilm X-A1", 0, 0,
7395 { 11086,-4555,-839,-3512,11310,2517,-815,1341,5940 } },
7396 { "Fujifilm X-A2", 0, 0,
7397 { 10763,-4560,-917,-3346,11311,2322,-475,1135,5843 } },
7398 { "Fujifilm X-E1", 0, 0,
7399 { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } },
7400 { "Fujifilm X-E2S", 0, 0,
7401 { 11562,-5118,-961,-3022,11007,2311,-525,1569,6097 } },
7402 { "Fujifilm X-E2", 0, 0,
7403 { 8458,-2451,-855,-4597,12447,2407,-1475,2482,6526 } },
7404 { "Fujifilm X-M1", 0, 0,
7405 { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } },
7406 { "Fujifilm X-S1", 0, 0,
7407 { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } },
7408 { "Fujifilm X-T1", 0, 0, /* also X-T10 */
7409 { 8458,-2451,-855,-4597,12447,2407,-1475,2482,6526 } },
7410 { "Fujifilm XF1", 0, 0,
7411 { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } },
7412 { "Fujifilm XQ", 0, 0, /* XQ1 and XQ2 */
7413 { 9252,-2704,-1064,-5893,14265,1717,-1101,2341,4349 } },
7414 { "Imacon Ixpress", 0, 0, /* DJC */
7415 { 7025,-1415,-704,-5188,13765,1424,-1248,2742,6038 } },
7416 { "Kodak NC2000", 0, 0,
7417 { 13891,-6055,-803,-465,9919,642,2121,82,1291 } },
7418 { "Kodak DCS315C", 8, 0,
7419 { 17523,-4827,-2510,756,8546,-137,6113,1649,2250 } },
7420 { "Kodak DCS330C", 8, 0,
7421 { 20620,-7572,-2801,-103,10073,-396,3551,-233,2220 } },
7422 { "Kodak DCS420", 0, 0,
7423 { 10868,-1852,-644,-1537,11083,484,2343,628,2216 } },
7424 { "Kodak DCS460", 0, 0,
7425 { 10592,-2206,-967,-1944,11685,230,2206,670,1273 } },
7426 { "Kodak EOSDCS1", 0, 0,
7427 { 10592,-2206,-967,-1944,11685,230,2206,670,1273 } },
7428 { "Kodak EOSDCS3B", 0, 0,
7429 { 9898,-2700,-940,-2478,12219,206,1985,634,1031 } },
7430 { "Kodak DCS520C", 178, 0,
7431 { 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } },
7432 { "Kodak DCS560C", 177, 0,
7433 { 20482,-7172,-3125,-1033,10410,-285,2542,226,3136 } },
7434 { "Kodak DCS620C", 177, 0,
7435 { 23617,-10175,-3149,-2054,11749,-272,2586,-489,3453 } },
7436 { "Kodak DCS620X", 176, 0,
7437 { 13095,-6231,154,12221,-21,-2137,895,4602,2258 } },
7438 { "Kodak DCS660C", 173, 0,
7439 { 18244,-6351,-2739,-791,11193,-521,3711,-129,2802 } },
7440 { "Kodak DCS720X", 0, 0,
7441 { 11775,-5884,950,9556,1846,-1286,-1019,6221,2728 } },
7442 { "Kodak DCS760C", 0, 0,
7443 { 16623,-6309,-1411,-4344,13923,323,2285,274,2926 } },
7444 { "Kodak DCS Pro SLR", 0, 0,
7445 { 5494,2393,-232,-6427,13850,2846,-1876,3997,5445 } },
7446 { "Kodak DCS Pro 14nx", 0, 0,
7447 { 5494,2393,-232,-6427,13850,2846,-1876,3997,5445 } },
7448 { "Kodak DCS Pro 14", 0, 0,
7449 { 7791,3128,-776,-8588,16458,2039,-2455,4006,6198 } },
7450 { "Kodak ProBack645", 0, 0,
7451 { 16414,-6060,-1470,-3555,13037,473,2545,122,4948 } },
7452 { "Kodak ProBack", 0, 0,
7453 { 21179,-8316,-2918,-915,11019,-165,3477,-180,4210 } },
7454 { "Kodak P712", 0, 0,
7455 { 9658,-3314,-823,-5163,12695,2768,-1342,1843,6044 } },
7456 { "Kodak P850", 0, 0xf7c,
7457 { 10511,-3836,-1102,-6946,14587,2558,-1481,1792,6246 } },
7458 { "Kodak P880", 0, 0xfff,
7459 { 12805,-4662,-1376,-7480,15267,2360,-1626,2194,7904 } },
7460 { "Kodak EasyShare Z980", 0, 0,
7461 { 11313,-3559,-1101,-3893,11891,2257,-1214,2398,4908 } },
7462 { "Kodak EasyShare Z981", 0, 0,
7463 { 12729,-4717,-1188,-1367,9187,2582,274,860,4411 } },
7464 { "Kodak EasyShare Z990", 0, 0xfed,
7465 { 11749,-4048,-1309,-1867,10572,1489,-138,1449,4522 } },
7466 { "Kodak EASYSHARE Z1015", 0, 0xef1,
7467 { 11265,-4286,-992,-4694,12343,2647,-1090,1523,5447 } },
7468 { "Leaf CMost", 0, 0,
7469 { 3952,2189,449,-6701,14585,2275,-4536,7349,6536 } },
7470 { "Leaf Valeo 6", 0, 0,
7471 { 3952,2189,449,-6701,14585,2275,-4536,7349,6536 } },
7472 { "Leaf Aptus 54S", 0, 0,
7473 { 8236,1746,-1314,-8251,15953,2428,-3673,5786,5771 } },
7474 { "Leaf Aptus 65", 0, 0,
7475 { 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 } },
7476 { "Leaf Aptus 75", 0, 0,
7477 { 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 } },
7479 { 8236,1746,-1314,-8251,15953,2428,-3673,5786,5771 } },
7480 { "Mamiya ZD", 0, 0,
7481 { 7645,2579,-1363,-8689,16717,2015,-3712,5941,5961 } },
7482 { "Micron 2010", 110, 0, /* DJC */
7483 { 16695,-3761,-2151,155,9682,163,3433,951,4904 } },
7484 { "Minolta DiMAGE 5", 0, 0xf7d,
7485 { 8983,-2942,-963,-6556,14476,2237,-2426,2887,8014 } },
7486 { "Minolta DiMAGE 7Hi", 0, 0xf7d,
7487 { 11368,-3894,-1242,-6521,14358,2339,-2475,3056,7285 } },
7488 { "Minolta DiMAGE 7", 0, 0xf7d,
7489 { 9144,-2777,-998,-6676,14556,2281,-2470,3019,7744 } },
7490 { "Minolta DiMAGE A1", 0, 0xf8b,
7491 { 9274,-2547,-1167,-8220,16323,1943,-2273,2720,8340 } },
7492 { "Minolta DiMAGE A200", 0, 0,
7493 { 8560,-2487,-986,-8112,15535,2771,-1209,1324,7743 } },
7494 { "Minolta DiMAGE A2", 0, 0xf8f,
7495 { 9097,-2726,-1053,-8073,15506,2762,-966,981,7763 } },
7496 { "Minolta DiMAGE Z2", 0, 0, /* DJC */
7497 { 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 } },
7498 { "Minolta DYNAX 5", 0, 0xffb,
7499 { 10284,-3283,-1086,-7957,15762,2316,-829,882,6644 } },
7500 { "Minolta DYNAX 7", 0, 0xffb,
7501 { 10239,-3104,-1099,-8037,15727,2451,-927,925,6871 } },
7502 { "Motorola PIXL", 0, 0, /* DJC */
7503 { 8898,-989,-1033,-3292,11619,1674,-661,3178,5216 } },
7504 { "Nikon D100", 0, 0,
7505 { 5902,-933,-782,-8983,16719,2354,-1402,1455,6464 } },
7506 { "Nikon D1H", 0, 0,
7507 { 7577,-2166,-926,-7454,15592,1934,-2377,2808,8606 } },
7508 { "Nikon D1X", 0, 0,
7509 { 7702,-2245,-975,-9114,17242,1875,-2679,3055,8521 } },
7510 { "Nikon D1", 0, 0, /* multiplied by 2.218750, 1.0, 1.148438 */
7511 { 16772,-4726,-2141,-7611,15713,1972,-2846,3494,9521 } },
7512 { "Nikon D200", 0, 0xfbc,
7513 { 8367,-2248,-763,-8758,16447,2422,-1527,1550,8053 } },
7514 { "Nikon D2H", 0, 0,
7515 { 5710,-901,-615,-8594,16617,2024,-2975,4120,6830 } },
7516 { "Nikon D2X", 0, 0,
7517 { 10231,-2769,-1255,-8301,15900,2552,-797,680,7148 } },
7518 { "Nikon D3000", 0, 0,
7519 { 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } },
7520 { "Nikon D3100", 0, 0,
7521 { 7911,-2167,-813,-5327,13150,2408,-1288,2483,7968 } },
7522 { "Nikon D3200", 0, 0xfb9,
7523 { 7013,-1408,-635,-5268,12902,2640,-1470,2801,7379 } },
7524 { "Nikon D3300", 0, 0,
7525 { 6988,-1384,-714,-5631,13410,2447,-1485,2204,7318 } },
7526 { "Nikon D300", 0, 0,
7527 { 9030,-1992,-715,-8465,16302,2255,-2689,3217,8069 } },
7528 { "Nikon D3X", 0, 0,
7529 { 7171,-1986,-648,-8085,15555,2718,-2170,2512,7457 } },
7530 { "Nikon D3S", 0, 0,
7531 { 8828,-2406,-694,-4874,12603,2541,-660,1509,7587 } },
7533 { 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } },
7534 { "Nikon D40X", 0, 0,
7535 { 8819,-2543,-911,-9025,16928,2151,-1329,1213,8449 } },
7536 { "Nikon D40", 0, 0,
7537 { 6992,-1668,-806,-8138,15748,2543,-874,850,7897 } },
7538 { "Nikon D4S", 0, 0,
7539 { 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } },
7541 { 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } },
7543 { 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } },
7544 { "Nikon D5000", 0, 0xf00,
7545 { 7309,-1403,-519,-8474,16008,2622,-2433,2826,8064 } },
7546 { "Nikon D5100", 0, 0x3de6,
7547 { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } },
7548 { "Nikon D5200", 0, 0,
7549 { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } },
7550 { "Nikon D5300", 0, 0,
7551 { 6988,-1384,-714,-5631,13410,2447,-1485,2204,7318 } },
7552 { "Nikon D5500", 0, 0,
7553 { 8821,-2938,-785,-4178,12142,2287,-824,1651,6860 } },
7554 { "Nikon D500", 0, 0,
7555 { 8813,-3210,-1036,-4703,12868,2021,-1054,1940,6129 } },
7556 { "Nikon D50", 0, 0,
7557 { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } },
7559 { 9200,-3522,-992,-5755,13803,2117,-753,1486,6338 } },
7560 { "Nikon D600", 0, 0x3e07,
7561 { 8178,-2245,-609,-4857,12394,2776,-1207,2086,7298 } },
7562 { "Nikon D610", 0, 0,
7563 { 8178,-2245,-609,-4857,12394,2776,-1207,2086,7298 } },
7564 { "Nikon D60", 0, 0,
7565 { 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } },
7566 { "Nikon D7000", 0, 0,
7567 { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } },
7568 { "Nikon D7100", 0, 0,
7569 { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } },
7570 { "Nikon D7200", 0, 0,
7571 { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } },
7572 { "Nikon D750", 0, 0,
7573 { 9020,-2890,-715,-4535,12436,2348,-934,1919,7086 } },
7574 { "Nikon D700", 0, 0,
7575 { 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } },
7576 { "Nikon D70", 0, 0,
7577 { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } },
7578 { "Nikon D810", 0, 0,
7579 { 9369,-3195,-791,-4488,12430,2301,-893,1796,6872 } },
7580 { "Nikon D800", 0, 0,
7581 { 7866,-2108,-555,-4869,12483,2681,-1176,2069,7501 } },
7582 { "Nikon D80", 0, 0,
7583 { 8629,-2410,-883,-9055,16940,2171,-1490,1363,8520 } },
7584 { "Nikon D90", 0, 0xf00,
7585 { 7309,-1403,-519,-8474,16008,2622,-2434,2826,8064 } },
7586 { "Nikon E700", 0, 0x3dd, /* DJC */
7587 { -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } },
7588 { "Nikon E800", 0, 0x3dd, /* DJC */
7589 { -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } },
7590 { "Nikon E950", 0, 0x3dd, /* DJC */
7591 { -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } },
7592 { "Nikon E995", 0, 0, /* copied from E5000 */
7593 { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
7594 { "Nikon E2100", 0, 0, /* copied from Z2, new white balance */
7595 { 13142,-4152,-1596,-4655,12374,2282,-1769,2696,6711} },
7596 { "Nikon E2500", 0, 0,
7597 { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
7598 { "Nikon E3200", 0, 0, /* DJC */
7599 { 9846,-2085,-1019,-3278,11109,2170,-774,2134,5745 } },
7600 { "Nikon E4300", 0, 0, /* copied from Minolta DiMAGE Z2 */
7601 { 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 } },
7602 { "Nikon E4500", 0, 0,
7603 { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
7604 { "Nikon E5000", 0, 0,
7605 { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
7606 { "Nikon E5400", 0, 0,
7607 { 9349,-2987,-1001,-7919,15766,2266,-2098,2680,6839 } },
7608 { "Nikon E5700", 0, 0,
7609 { -5368,11478,2368,5537,-113,3148,-4969,10021,5782,778,9028,211 } },
7610 { "Nikon E8400", 0, 0,
7611 { 7842,-2320,-992,-8154,15718,2599,-1098,1342,7560 } },
7612 { "Nikon E8700", 0, 0,
7613 { 8489,-2583,-1036,-8051,15583,2643,-1307,1407,7354 } },
7614 { "Nikon E8800", 0, 0,
7615 { 7971,-2314,-913,-8451,15762,2894,-1442,1520,7610 } },
7616 { "Nikon COOLPIX A", 0, 0,
7617 { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } },
7618 { "Nikon COOLPIX P330", 200, 0,
7619 { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } },
7620 { "Nikon COOLPIX P340", 200, 0,
7621 { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } },
7622 { "Nikon COOLPIX P6000", 0, 0,
7623 { 9698,-3367,-914,-4706,12584,2368,-837,968,5801 } },
7624 { "Nikon COOLPIX P7000", 0, 0,
7625 { 11432,-3679,-1111,-3169,11239,2202,-791,1380,4455 } },
7626 { "Nikon COOLPIX P7100", 0, 0,
7627 { 11053,-4269,-1024,-1976,10182,2088,-526,1263,4469 } },
7628 { "Nikon COOLPIX P7700", 200, 0,
7629 { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } },
7630 { "Nikon COOLPIX P7800", 200, 0,
7631 { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } },
7632 { "Nikon 1 V3", 0, 0,
7633 { 5958,-1559,-571,-4021,11453,2939,-634,1548,5087 } },
7634 { "Nikon 1 J4", 0, 0,
7635 { 5958,-1559,-571,-4021,11453,2939,-634,1548,5087 } },
7636 { "Nikon 1 J5", 0, 0,
7637 { 7520,-2518,-645,-3844,12102,1945,-913,2249,6835 } },
7638 { "Nikon 1 S2", 200, 0,
7639 { 6612,-1342,-618,-3338,11055,2623,-174,1792,5075 } },
7640 { "Nikon 1 V2", 0, 0,
7641 { 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } },
7642 { "Nikon 1 J3", 0, 0,
7643 { 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } },
7644 { "Nikon 1 AW1", 0, 0,
7645 { 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } },
7646 { "Nikon 1 ", 0, 0, /* J1, J2, S1, V1 */
7647 { 8994,-2667,-865,-4594,12324,2552,-699,1786,6260 } },
7648 { "Olympus AIR A01", 0, 0,
7649 { 8992,-3093,-639,-2563,10721,2122,-437,1270,5473 } },
7650 { "Olympus C5050", 0, 0,
7651 { 10508,-3124,-1273,-6079,14294,1901,-1653,2306,6237 } },
7652 { "Olympus C5060", 0, 0,
7653 { 10445,-3362,-1307,-7662,15690,2058,-1135,1176,7602 } },
7654 { "Olympus C7070", 0, 0,
7655 { 10252,-3531,-1095,-7114,14850,2436,-1451,1723,6365 } },
7656 { "Olympus C70", 0, 0,
7657 { 10793,-3791,-1146,-7498,15177,2488,-1390,1577,7321 } },
7658 { "Olympus C80", 0, 0,
7659 { 8606,-2509,-1014,-8238,15714,2703,-942,979,7760 } },
7660 { "Olympus E-10", 0, 0xffc,
7661 { 12745,-4500,-1416,-6062,14542,1580,-1934,2256,6603 } },
7662 { "Olympus E-1", 0, 0,
7663 { 11846,-4767,-945,-7027,15878,1089,-2699,4122,8311 } },
7664 { "Olympus E-20", 0, 0xffc,
7665 { 13173,-4732,-1499,-5807,14036,1895,-2045,2452,7142 } },
7666 { "Olympus E-300", 0, 0,
7667 { 7828,-1761,-348,-5788,14071,1830,-2853,4518,6557 } },
7668 { "Olympus E-330", 0, 0,
7669 { 8961,-2473,-1084,-7979,15990,2067,-2319,3035,8249 } },
7670 { "Olympus E-30", 0, 0xfbc,
7671 { 8144,-1861,-1111,-7763,15894,1929,-1865,2542,7607 } },
7672 { "Olympus E-3", 0, 0xf99,
7673 { 9487,-2875,-1115,-7533,15606,2010,-1618,2100,7389 } },
7674 { "Olympus E-400", 0, 0,
7675 { 6169,-1483,-21,-7107,14761,2536,-2904,3580,8568 } },
7676 { "Olympus E-410", 0, 0xf6a,
7677 { 8856,-2582,-1026,-7761,15766,2082,-2009,2575,7469 } },
7678 { "Olympus E-420", 0, 0xfd7,
7679 { 8746,-2425,-1095,-7594,15612,2073,-1780,2309,7416 } },
7680 { "Olympus E-450", 0, 0xfd2,
7681 { 8745,-2425,-1095,-7594,15613,2073,-1780,2309,7416 } },
7682 { "Olympus E-500", 0, 0,
7683 { 8136,-1968,-299,-5481,13742,1871,-2556,4205,6630 } },
7684 { "Olympus E-510", 0, 0xf6a,
7685 { 8785,-2529,-1033,-7639,15624,2112,-1783,2300,7817 } },
7686 { "Olympus E-520", 0, 0xfd2,
7687 { 8344,-2322,-1020,-7596,15635,2048,-1748,2269,7287 } },
7688 { "Olympus E-5", 0, 0xeec,
7689 { 11200,-3783,-1325,-4576,12593,2206,-695,1742,7504 } },
7690 { "Olympus E-600", 0, 0xfaf,
7691 { 8453,-2198,-1092,-7609,15681,2008,-1725,2337,7824 } },
7692 { "Olympus E-620", 0, 0xfaf,
7693 { 8453,-2198,-1092,-7609,15681,2008,-1725,2337,7824 } },
7694 { "Olympus E-P1", 0, 0xffd,
7695 { 8343,-2050,-1021,-7715,15705,2103,-1831,2380,8235 } },
7696 { "Olympus E-P2", 0, 0xffd,
7697 { 8343,-2050,-1021,-7715,15705,2103,-1831,2380,8235 } },
7698 { "Olympus E-P3", 0, 0,
7699 { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } },
7700 { "Olympus E-P5", 0, 0,
7701 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
7702 { "Olympus E-PL1s", 0, 0,
7703 { 11409,-3872,-1393,-4572,12757,2003,-709,1810,7415 } },
7704 { "Olympus E-PL1", 0, 0,
7705 { 11408,-4289,-1215,-4286,12385,2118,-387,1467,7787 } },
7706 { "Olympus E-PL2", 0, 0xcf3,
7707 { 15030,-5552,-1806,-3987,12387,1767,-592,1670,7023 } },
7708 { "Olympus E-PL3", 0, 0,
7709 { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } },
7710 { "Olympus E-PL5", 0, 0xfcb,
7711 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
7712 { "Olympus E-PL6", 0, 0,
7713 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
7714 { "Olympus E-PL7", 0, 0,
7715 { 9197,-3190,-659,-2606,10830,2039,-458,1250,5458 } },
7716 { "Olympus E-PM1", 0, 0,
7717 { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } },
7718 { "Olympus E-PM2", 0, 0,
7719 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
7720 { "Olympus E-M10", 0, 0, /* also E-M10 Mark II */
7721 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
7722 { "Olympus E-M1", 0, 0,
7723 { 7687,-1984,-606,-4327,11928,2721,-1381,2339,6452 } },
7724 { "Olympus E-M5MarkII", 0, 0,
7725 { 9422,-3258,-711,-2655,10898,2015,-512,1354,5512 } },
7726 { "Olympus E-M5", 0, 0xfe1,
7727 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
7728 { "Olympus PEN-F", 0, 0,
7729 { 9476,-3182,-765,-2613,10958,1893,-449,1315,5268 } },
7730 { "Olympus SH-2", 0, 0,
7731 { 10156,-3425,-1077,-2611,11177,1624,-385,1592,5080 } },
7732 { "Olympus SP350", 0, 0,
7733 { 12078,-4836,-1069,-6671,14306,2578,-786,939,7418 } },
7734 { "Olympus SP3", 0, 0,
7735 { 11766,-4445,-1067,-6901,14421,2707,-1029,1217,7572 } },
7736 { "Olympus SP500UZ", 0, 0xfff,
7737 { 9493,-3415,-666,-5211,12334,3260,-1548,2262,6482 } },
7738 { "Olympus SP510UZ", 0, 0xffe,
7739 { 10593,-3607,-1010,-5881,13127,3084,-1200,1805,6721 } },
7740 { "Olympus SP550UZ", 0, 0xffe,
7741 { 11597,-4006,-1049,-5432,12799,2957,-1029,1750,6516 } },
7742 { "Olympus SP560UZ", 0, 0xff9,
7743 { 10915,-3677,-982,-5587,12986,2911,-1168,1968,6223 } },
7744 { "Olympus SP570UZ", 0, 0,
7745 { 11522,-4044,-1146,-4736,12172,2904,-988,1829,6039 } },
7746 { "Olympus STYLUS1", 0, 0,
7747 { 8360,-2420,-880,-3928,12353,1739,-1381,2416,5173 } },
7748 { "Olympus TG-4", 0, 0,
7749 { 11426,-4159,-1126,-2066,10678,1593,-120,1327,4998 } },
7750 { "Olympus XZ-10", 0, 0,
7751 { 9777,-3483,-925,-2886,11297,1800,-602,1663,5134 } },
7752 { "Olympus XZ-1", 0, 0,
7753 { 10901,-4095,-1074,-1141,9208,2293,-62,1417,5158 } },
7754 { "Olympus XZ-2", 0, 0,
7755 { 9777,-3483,-925,-2886,11297,1800,-602,1663,5134 } },
7756 { "OmniVision", 0, 0, /* DJC */
7757 { 12782,-4059,-379,-478,9066,1413,1340,1513,5176 } },
7758 { "Pentax *ist DL2", 0, 0,
7759 { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
7760 { "Pentax *ist DL", 0, 0,
7761 { 10829,-2838,-1115,-8339,15817,2696,-837,680,11939 } },
7762 { "Pentax *ist DS2", 0, 0,
7763 { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
7764 { "Pentax *ist DS", 0, 0,
7765 { 10371,-2333,-1206,-8688,16231,2602,-1230,1116,11282 } },
7766 { "Pentax *ist D", 0, 0,
7767 { 9651,-2059,-1189,-8881,16512,2487,-1460,1345,10687 } },
7768 { "Pentax K10D", 0, 0,
7769 { 9566,-2863,-803,-7170,15172,2112,-818,803,9705 } },
7770 { "Pentax K1", 0, 0,
7771 { 11095,-3157,-1324,-8377,15834,2720,-1108,947,11688 } },
7772 { "Pentax K20D", 0, 0,
7773 { 9427,-2714,-868,-7493,16092,1373,-2199,3264,7180 } },
7774 { "Pentax K200D", 0, 0,
7775 { 9186,-2678,-907,-8693,16517,2260,-1129,1094,8524 } },
7776 { "Pentax K2000", 0, 0,
7777 { 11057,-3604,-1155,-5152,13046,2329,-282,375,8104 } },
7778 { "Pentax K-m", 0, 0,
7779 { 11057,-3604,-1155,-5152,13046,2329,-282,375,8104 } },
7780 { "Pentax K-x", 0, 0,
7781 { 8843,-2837,-625,-5025,12644,2668,-411,1234,7410 } },
7782 { "Pentax K-r", 0, 0,
7783 { 9895,-3077,-850,-5304,13035,2521,-883,1768,6936 } },
7784 { "Pentax K-1", 0, 0,
7785 { 8566,-2746,-1201,-3612,12204,1550,-893,1680,6264 } },
7786 { "Pentax K-30", 0, 0,
7787 { 8710,-2632,-1167,-3995,12301,1881,-981,1719,6535 } },
7788 { "Pentax K-3 II", 0, 0,
7789 { 8626,-2607,-1155,-3995,12301,1881,-1039,1822,6925 } },
7790 { "Pentax K-3", 0, 0,
7791 { 7415,-2052,-721,-5186,12788,2682,-1446,2157,6773 } },
7792 { "Pentax K-5 II", 0, 0,
7793 { 8170,-2725,-639,-4440,12017,2744,-771,1465,6599 } },
7794 { "Pentax K-5", 0, 0,
7795 { 8713,-2833,-743,-4342,11900,2772,-722,1543,6247 } },
7796 { "Pentax K-7", 0, 0,
7797 { 9142,-2947,-678,-8648,16967,1663,-2224,2898,8615 } },
7798 { "Pentax K-S1", 0, 0,
7799 { 8512,-3211,-787,-4167,11966,2487,-638,1288,6054 } },
7800 { "Pentax K-S2", 0, 0,
7801 { 8662,-3280,-798,-3928,11771,2444,-586,1232,6054 } },
7802 { "Pentax Q-S1", 0, 0,
7803 { 12995,-5593,-1107,-1879,10139,2027,-64,1233,4919 } },
7804 { "Pentax 645D", 0, 0x3e00,
7805 { 10646,-3593,-1158,-3329,11699,1831,-667,2874,6287 } },
7806 { "Panasonic DMC-CM1", 15, 0,
7807 { 8770,-3194,-820,-2871,11281,1803,-513,1552,4434 } },
7808 { "Panasonic DMC-FZ8", 0, 0xf7f,
7809 { 8986,-2755,-802,-6341,13575,3077,-1476,2144,6379 } },
7810 { "Panasonic DMC-FZ18", 0, 0,
7811 { 9932,-3060,-935,-5809,13331,2753,-1267,2155,5575 } },
7812 { "Panasonic DMC-FZ28", 15, 0xf96,
7813 { 10109,-3488,-993,-5412,12812,2916,-1305,2140,5543 } },
7814 { "Panasonic DMC-FZ330", 15, 0,
7815 { 8378,-2798,-769,-3068,11410,1877,-538,1792,4623 } },
7816 { "Panasonic DMC-FZ300", 15, 0,
7817 { 8378,-2798,-769,-3068,11410,1877,-538,1792,4623 } },
7818 { "Panasonic DMC-FZ30", 0, 0xf94,
7819 { 10976,-4029,-1141,-7918,15491,2600,-1670,2071,8246 } },
7820 { "Panasonic DMC-FZ3", 15, 0,
7821 { 9938,-2780,-890,-4604,12393,2480,-1117,2304,4620 } },
7822 { "Panasonic DMC-FZ4", 15, 0,
7823 { 13639,-5535,-1371,-1698,9633,2430,316,1152,4108 } },
7824 { "Panasonic DMC-FZ50", 0, 0,
7825 { 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } },
7826 { "Panasonic DMC-FZ7", 15, 0,
7827 { 11532,-4324,-1066,-2375,10847,1749,-564,1699,4351 } },
7828 { "Leica V-LUX1", 0, 0,
7829 { 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } },
7830 { "Panasonic DMC-L10", 15, 0xf96,
7831 { 8025,-1942,-1050,-7920,15904,2100,-2456,3005,7039 } },
7832 { "Panasonic DMC-L1", 0, 0xf7f,
7833 { 8054,-1885,-1025,-8349,16367,2040,-2805,3542,7629 } },
7834 { "Leica DIGILUX 3", 0, 0xf7f,
7835 { 8054,-1885,-1025,-8349,16367,2040,-2805,3542,7629 } },
7836 { "Panasonic DMC-LC1", 0, 0,
7837 { 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } },
7838 { "Leica DIGILUX 2", 0, 0,
7839 { 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } },
7840 { "Panasonic DMC-LX100", 15, 0,
7841 { 8844,-3538,-768,-3709,11762,2200,-698,1792,5220 } },
7842 { "Leica D-LUX (Typ 109)", 15, 0,
7843 { 8844,-3538,-768,-3709,11762,2200,-698,1792,5220 } },
7844 { "Panasonic DMC-LF1", 15, 0,
7845 { 9379,-3267,-816,-3227,11560,1881,-926,1928,5340 } },
7846 { "Leica C (Typ 112)", 15, 0,
7847 { 9379,-3267,-816,-3227,11560,1881,-926,1928,5340 } },
7848 { "Panasonic DMC-LX1", 0, 0xf7f,
7849 { 10704,-4187,-1230,-8314,15952,2501,-920,945,8927 } },
7850 { "Leica D-LUX2", 0, 0xf7f,
7851 { 10704,-4187,-1230,-8314,15952,2501,-920,945,8927 } },
7852 { "Panasonic DMC-LX2", 0, 0,
7853 { 8048,-2810,-623,-6450,13519,3272,-1700,2146,7049 } },
7854 { "Leica D-LUX3", 0, 0,
7855 { 8048,-2810,-623,-6450,13519,3272,-1700,2146,7049 } },
7856 { "Panasonic DMC-LX3", 15, 0,
7857 { 8128,-2668,-655,-6134,13307,3161,-1782,2568,6083 } },
7858 { "Leica D-LUX 4", 15, 0,
7859 { 8128,-2668,-655,-6134,13307,3161,-1782,2568,6083 } },
7860 { "Panasonic DMC-LX5", 15, 0,
7861 { 10909,-4295,-948,-1333,9306,2399,22,1738,4582 } },
7862 { "Leica D-LUX 5", 15, 0,
7863 { 10909,-4295,-948,-1333,9306,2399,22,1738,4582 } },
7864 { "Panasonic DMC-LX7", 15, 0,
7865 { 10148,-3743,-991,-2837,11366,1659,-701,1893,4899 } },
7866 { "Leica D-LUX 6", 15, 0,
7867 { 10148,-3743,-991,-2837,11366,1659,-701,1893,4899 } },
7868 { "Panasonic DMC-FZ1000", 15, 0,
7869 { 7830,-2696,-763,-3325,11667,1866,-641,1712,4824 } },
7870 { "Leica V-LUX (Typ 114)", 15, 0,
7871 { 7830,-2696,-763,-3325,11667,1866,-641,1712,4824 } },
7872 { "Panasonic DMC-FZ100", 15, 0xfff,
7873 { 16197,-6146,-1761,-2393,10765,1869,366,2238,5248 } },
7874 { "Leica V-LUX 2", 15, 0xfff,
7875 { 16197,-6146,-1761,-2393,10765,1869,366,2238,5248 } },
7876 { "Panasonic DMC-FZ150", 15, 0xfff,
7877 { 11904,-4541,-1189,-2355,10899,1662,-296,1586,4289 } },
7878 { "Leica V-LUX 3", 15, 0xfff,
7879 { 11904,-4541,-1189,-2355,10899,1662,-296,1586,4289 } },
7880 { "Panasonic DMC-FZ200", 15, 0xfff,
7881 { 8112,-2563,-740,-3730,11784,2197,-941,2075,4933 } },
7882 { "Leica V-LUX 4", 15, 0xfff,
7883 { 8112,-2563,-740,-3730,11784,2197,-941,2075,4933 } },
7884 { "Panasonic DMC-FX150", 15, 0xfff,
7885 { 9082,-2907,-925,-6119,13377,3058,-1797,2641,5609 } },
7886 { "Panasonic DMC-G10", 0, 0,
7887 { 10113,-3400,-1114,-4765,12683,2317,-377,1437,6710 } },
7888 { "Panasonic DMC-G1", 15, 0xf94,
7889 { 8199,-2065,-1056,-8124,16156,2033,-2458,3022,7220 } },
7890 { "Panasonic DMC-G2", 15, 0xf3c,
7891 { 10113,-3400,-1114,-4765,12683,2317,-377,1437,6710 } },
7892 { "Panasonic DMC-G3", 15, 0xfff,
7893 { 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } },
7894 { "Panasonic DMC-G5", 15, 0xfff,
7895 { 7798,-2562,-740,-3879,11584,2613,-1055,2248,5434 } },
7896 { "Panasonic DMC-G6", 15, 0xfff,
7897 { 8294,-2891,-651,-3869,11590,2595,-1183,2267,5352 } },
7898 { "Panasonic DMC-G7", 15, 0xfff,
7899 { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } },
7900 { "Panasonic DMC-GF1", 15, 0xf92,
7901 { 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } },
7902 { "Panasonic DMC-GF2", 15, 0xfff,
7903 { 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } },
7904 { "Panasonic DMC-GF3", 15, 0xfff,
7905 { 9051,-2468,-1204,-5212,13276,2121,-1197,2510,6890 } },
7906 { "Panasonic DMC-GF5", 15, 0xfff,
7907 { 8228,-2945,-660,-3938,11792,2430,-1094,2278,5793 } },
7908 { "Panasonic DMC-GF6", 15, 0,
7909 { 8130,-2801,-946,-3520,11289,2552,-1314,2511,5791 } },
7910 { "Panasonic DMC-GF7", 15, 0,
7911 { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } },
7912 { "Panasonic DMC-GF8", 15, 0,
7913 { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } },
7914 { "Panasonic DMC-GH1", 15, 0xf92,
7915 { 6299,-1466,-532,-6535,13852,2969,-2331,3112,5984 } },
7916 { "Panasonic DMC-GH2", 15, 0xf95,
7917 { 7780,-2410,-806,-3913,11724,2484,-1018,2390,5298 } },
7918 { "Panasonic DMC-GH3", 15, 0,
7919 { 6559,-1752,-491,-3672,11407,2586,-962,1875,5130 } },
7920 { "Panasonic DMC-GH4", 15, 0,
7921 { 7122,-2108,-512,-3155,11201,2231,-541,1423,5045 } },
7922 { "Panasonic DMC-GM1", 15, 0,
7923 { 6770,-1895,-744,-5232,13145,2303,-1664,2691,5703 } },
7924 { "Panasonic DMC-GM5", 15, 0,
7925 { 8238,-3244,-679,-3921,11814,2384,-836,2022,5852 } },
7926 { "Panasonic DMC-GX1", 15, 0,
7927 { 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } },
7928 { "Panasonic DMC-GX7", 15, 0,
7929 { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } },
7930 { "Panasonic DMC-GX8", 15, 0,
7931 { 7564,-2263,-606,-3148,11239,2177,-540,1435,4853 } },
7932 { "Panasonic DMC-TZ1", 15, 0,
7933 { 7790,-2736,-755,-3452,11870,1769,-628,1647,4898 } },
7934 { "Panasonic DMC-ZS1", 15, 0,
7935 { 7790,-2736,-755,-3452,11870,1769,-628,1647,4898 } },
7936 { "Panasonic DMC-TZ6", 15, 0,
7937 { 8607,-2822,-808,-3755,11930,2049,-820,2060,5224 } },
7938 { "Panasonic DMC-ZS4", 15, 0,
7939 { 8607,-2822,-808,-3755,11930,2049,-820,2060,5224 } },
7940 { "Panasonic DMC-TZ7", 15, 0,
7941 { 8802,-3135,-789,-3151,11468,1904,-550,1745,4810 } },
7942 { "Panasonic DMC-ZS5", 15, 0,
7943 { 8802,-3135,-789,-3151,11468,1904,-550,1745,4810 } },
7944 { "Panasonic DMC-TZ8", 15, 0,
7945 { 8550,-2908,-842,-3195,11529,1881,-338,1603,4631 } },
7946 { "Panasonic DMC-ZS6", 15, 0,
7947 { 8550,-2908,-842,-3195,11529,1881,-338,1603,4631 } },
7948 { "Leica S (Typ 007)", 0, 0,
7949 { 6063,-2234,-231,-5210,13787,1500,-1043,2866,6997 } },
7950 { "Leica X", 0, 0, /* X and X-U, both (Typ 113) */
7951 { 7712,-2059,-653,-3882,11494,2726,-710,1332,5958 } },
7952 { "Leica Q (Typ 116)", 0, 0,
7953 { 11865,-4523,-1441,-5423,14458,935,-1587,2687,4830 } },
7954 { "Leica M (Typ 262)", 0, 0,
7955 { 6653,-1486,-611,-4221,13303,929,-881,2416,7226 } },
7956 { "Leica SL (Typ 601)", 0, 0,
7957 { 11865,-4523,-1441,-5423,14458,935,-1587,2687,4830} },
7958 { "Phase One H 20", 0, 0, /* DJC */
7959 { 1313,1855,-109,-6715,15908,808,-327,1840,6020 } },
7960 { "Phase One H 25", 0, 0,
7961 { 2905,732,-237,-8134,16626,1476,-3038,4253,7517 } },
7962 { "Phase One P 2", 0, 0,
7963 { 2905,732,-237,-8134,16626,1476,-3038,4253,7517 } },
7964 { "Phase One P 30", 0, 0,
7965 { 4516,-245,-37,-7020,14976,2173,-3206,4671,7087 } },
7966 { "Phase One P 45", 0, 0,
7967 { 5053,-24,-117,-5684,14076,1702,-2619,4492,5849 } },
7968 { "Phase One P40", 0, 0,
7969 { 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } },
7970 { "Phase One P65", 0, 0,
7971 { 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } },
7972 { "Photron BC2-HD", 0, 0, /* DJC */
7973 { 14603,-4122,-528,-1810,9794,2017,-297,2763,5936 } },
7974 { "Red One", 704, 0xffff, /* DJC */
7975 { 21014,-7891,-2613,-3056,12201,856,-2203,5125,8042 } },
7976 { "Ricoh GR II", 0, 0,
7977 { 4630,-834,-423,-4977,12805,2417,-638,1467,6115 } },
7979 { 3708,-543,-160,-5381,12254,3556,-1471,1929,8234 } },
7980 { "Samsung EX1", 0, 0x3e00,
7981 { 8898,-2498,-994,-3144,11328,2066,-760,1381,4576 } },
7982 { "Samsung EX2F", 0, 0x7ff,
7983 { 10648,-3897,-1055,-2022,10573,1668,-492,1611,4742 } },
7984 { "Samsung EK-GN120", 0, 0,
7985 { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } },
7986 { "Samsung NX mini", 0, 0,
7987 { 5222,-1196,-550,-6540,14649,2009,-1666,2819,5657 } },
7988 { "Samsung NX3300", 0, 0,
7989 { 8060,-2933,-761,-4504,12890,1762,-630,1489,5227 } },
7990 { "Samsung NX3000", 0, 0,
7991 { 8060,-2933,-761,-4504,12890,1762,-630,1489,5227 } },
7992 { "Samsung NX30", 0, 0, /* NX30, NX300, NX300M */
7993 { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } },
7994 { "Samsung NX2000", 0, 0,
7995 { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } },
7996 { "Samsung NX2", 0, 0xfff, /* NX20, NX200, NX210 */
7997 { 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } },
7998 { "Samsung NX1000", 0, 0,
7999 { 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } },
8000 { "Samsung NX1100", 0, 0,
8001 { 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } },
8002 { "Samsung NX11", 0, 0,
8003 { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } },
8004 { "Samsung NX10", 0, 0, /* also NX100 */
8005 { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } },
8006 { "Samsung NX500", 0, 0,
8007 { 10686,-4042,-1052,-3595,13238,276,-464,1259,5931 } },
8008 { "Samsung NX5", 0, 0,
8009 { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } },
8010 { "Samsung NX1", 0, 0,
8011 { 10686,-4042,-1052,-3595,13238,276,-464,1259,5931 } },
8012 { "Samsung WB2000", 0, 0xfff,
8013 { 12093,-3557,-1155,-1000,9534,1733,-22,1787,4576 } },
8014 { "Samsung GX-1", 0, 0,
8015 { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
8016 { "Samsung GX20", 0, 0, /* copied from Pentax K20D */
8017 { 9427,-2714,-868,-7493,16092,1373,-2199,3264,7180 } },
8018 { "Samsung S85", 0, 0, /* DJC */
8019 { 11885,-3968,-1473,-4214,12299,1916,-835,1655,5549 } },
8020 { "Sinar", 0, 0, /* DJC */
8021 { 16442,-2956,-2422,-2877,12128,750,-1136,6066,4559 } },
8022 { "Sony DSC-F828", 0, 0,
8023 { 7924,-1910,-777,-8226,15459,2998,-1517,2199,6818,-7242,11401,3481 } },
8024 { "Sony DSC-R1", 0, 0,
8025 { 8512,-2641,-694,-8042,15670,2526,-1821,2117,7414 } },
8026 { "Sony DSC-V3", 0, 0,
8027 { 7511,-2571,-692,-7894,15088,3060,-948,1111,8128 } },
8028 { "Sony DSC-RX100M", 0, 0, /* M2, M3, and M4 */
8029 { 6596,-2079,-562,-4782,13016,1933,-970,1581,5181 } },
8030 { "Sony DSC-RX100", 0, 0,
8031 { 8651,-2754,-1057,-3464,12207,1373,-568,1398,4434 } },
8032 { "Sony DSC-RX10", 0, 0, /* also RX10M2 */
8033 { 6679,-1825,-745,-5047,13256,1953,-1580,2422,5183 } },
8034 { "Sony DSC-RX1RM2", 0, 0,
8035 { 6629,-1900,-483,-4618,12349,2550,-622,1381,6514 } },
8036 { "Sony DSC-RX1", 0, 0,
8037 { 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } },
8038 { "Sony DSLR-A100", 0, 0xfeb,
8039 { 9437,-2811,-774,-8405,16215,2290,-710,596,7181 } },
8040 { "Sony DSLR-A290", 0, 0,
8041 { 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } },
8042 { "Sony DSLR-A2", 0, 0,
8043 { 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } },
8044 { "Sony DSLR-A300", 0, 0,
8045 { 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } },
8046 { "Sony DSLR-A330", 0, 0,
8047 { 9847,-3091,-929,-8485,16346,2225,-714,595,7103 } },
8048 { "Sony DSLR-A350", 0, 0xffc,
8049 { 6038,-1484,-578,-9146,16746,2513,-875,746,7217 } },
8050 { "Sony DSLR-A380", 0, 0,
8051 { 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } },
8052 { "Sony DSLR-A390", 0, 0,
8053 { 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } },
8054 { "Sony DSLR-A450", 0, 0xfeb,
8055 { 4950,-580,-103,-5228,12542,3029,-709,1435,7371 } },
8056 { "Sony DSLR-A580", 0, 0xfeb,
8057 { 5932,-1492,-411,-4813,12285,2856,-741,1524,6739 } },
8058 { "Sony DSLR-A500", 0, 0xfeb,
8059 { 6046,-1127,-278,-5574,13076,2786,-691,1419,7625 } },
8060 { "Sony DSLR-A5", 0, 0xfeb,
8061 { 4950,-580,-103,-5228,12542,3029,-709,1435,7371 } },
8062 { "Sony DSLR-A700", 0, 0,
8063 { 5775,-805,-359,-8574,16295,2391,-1943,2341,7249 } },
8064 { "Sony DSLR-A850", 0, 0,
8065 { 5413,-1162,-365,-5665,13098,2866,-608,1179,8440 } },
8066 { "Sony DSLR-A900", 0, 0,
8067 { 5209,-1072,-397,-8845,16120,2919,-1618,1803,8654 } },
8068 { "Sony ILCA-68", 0, 0,
8069 { 6435,-1903,-536,-4722,12449,2550,-663,1363,6517 } },
8070 { "Sony ILCA-77M2", 0, 0,
8071 { 5991,-1732,-443,-4100,11989,2381,-704,1467,5992 } },
8072 { "Sony ILCE-6300", 0, 0,
8073 { 5973,-1695,-419,-3826,11797,2293,-639,1398,5789 } },
8074 { "Sony ILCE-7M2", 0, 0,
8075 { 5271,-712,-347,-6153,13653,2763,-1601,2366,7242 } },
8076 { "Sony ILCE-7S", 0, 0, /* also ILCE-7SM2 */
8077 { 5838,-1430,-246,-3497,11477,2297,-748,1885,5778 } },
8078 { "Sony ILCE-7RM2", 0, 0,
8079 { 6629,-1900,-483,-4618,12349,2550,-622,1381,6514 } },
8080 { "Sony ILCE-7R", 0, 0,
8081 { 4913,-541,-202,-6130,13513,2906,-1564,2151,7183 } },
8082 { "Sony ILCE-7", 0, 0,
8083 { 5271,-712,-347,-6153,13653,2763,-1601,2366,7242 } },
8084 { "Sony ILCE", 0, 0, /* 3000, 5000, 5100, 6000, and QX1 */
8085 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
8086 { "Sony NEX-5N", 0, 0,
8087 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
8088 { "Sony NEX-5R", 0, 0,
8089 { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } },
8090 { "Sony NEX-5T", 0, 0,
8091 { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } },
8092 { "Sony NEX-3N", 0, 0,
8093 { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } },
8094 { "Sony NEX-3", 138, 0, /* DJC */
8095 { 6907,-1256,-645,-4940,12621,2320,-1710,2581,6230 } },
8096 { "Sony NEX-5", 116, 0, /* DJC */
8097 { 6807,-1350,-342,-4216,11649,2567,-1089,2001,6420 } },
8098 { "Sony NEX-3", 0, 0, /* Adobe */
8099 { 6549,-1550,-436,-4880,12435,2753,-854,1868,6976 } },
8100 { "Sony NEX-5", 0, 0, /* Adobe */
8101 { 6549,-1550,-436,-4880,12435,2753,-854,1868,6976 } },
8102 { "Sony NEX-6", 0, 0,
8103 { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } },
8104 { "Sony NEX-7", 0, 0,
8105 { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } },
8106 { "Sony NEX", 0, 0, /* NEX-C3, NEX-F3 */
8107 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
8108 { "Sony SLT-A33", 0, 0,
8109 { 6069,-1221,-366,-5221,12779,2734,-1024,2066,6834 } },
8110 { "Sony SLT-A35", 0, 0,
8111 { 5986,-1618,-415,-4557,11820,3120,-681,1404,6971 } },
8112 { "Sony SLT-A37", 0, 0,
8113 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
8114 { "Sony SLT-A55", 0, 0,
8115 { 5932,-1492,-411,-4813,12285,2856,-741,1524,6739 } },
8116 { "Sony SLT-A57", 0, 0,
8117 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
8118 { "Sony SLT-A58", 0, 0,
8119 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
8120 { "Sony SLT-A65", 0, 0,
8121 { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } },
8122 { "Sony SLT-A77", 0, 0,
8123 { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } },
8124 { "Sony SLT-A99", 0, 0,
8125 { 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } },
8127 double cam_xyz[4][3];
8131 sprintf (name, "%s %s", make, model);
8132 for (i=0; i < sizeof table / sizeof *table; i++)
8133 if (!strncmp (name, table[i].prefix, strlen(table[i].prefix))) {
8134 if (table[i].black) black = (ushort) table[i].black;
8135 if (table[i].maximum) maximum = (ushort) table[i].maximum;
8136 if (table[i].trans[0]) {
8137 for (raw_color = j=0; j < 12; j++)
8138 ((double *)cam_xyz)[j] = table[i].trans[j] / 10000.0;
8139 cam_xyz_coeff (rgb_cam, cam_xyz);
8145 void CLASS simple_coeff (int index)
8147 static const float table[][12] = {
8148 /* index 0 -- all Foveon cameras */
8149 { 1.4032,-0.2231,-0.1016,-0.5263,1.4816,0.017,-0.0112,0.0183,0.9113 },
8150 /* index 1 -- Kodak DC20 and DC25 */
8151 { 2.25,0.75,-1.75,-0.25,-0.25,0.75,0.75,-0.25,-0.25,-1.75,0.75,2.25 },
8152 /* index 2 -- Logitech Fotoman Pixtura */
8153 { 1.893,-0.418,-0.476,-0.495,1.773,-0.278,-1.017,-0.655,2.672 },
8154 /* index 3 -- Nikon E880, E900, and E990 */
8155 { -1.936280, 1.800443, -1.448486, 2.584324,
8156 1.405365, -0.524955, -0.289090, 0.408680,
8157 -1.204965, 1.082304, 2.941367, -1.818705 }
8161 for (raw_color = i=0; i < 3; i++)
8162 FORCC rgb_cam[i][c] = table[index][i*colors+c];
8165 short CLASS guess_byte_order (int words)
8169 double diff, sum[2] = {0,0};
8171 fread (test[0], 2, 2, ifp);
8172 for (words-=2; words--; ) {
8173 fread (test[t], 2, 1, ifp);
8174 for (msb=0; msb < 2; msb++) {
8175 diff = (test[t^2][msb] << 8 | test[t^2][!msb])
8176 - (test[t ][msb] << 8 | test[t ][!msb]);
8177 sum[msb] += diff*diff;
8181 return sum[0] < sum[1] ? 0x4d4d : 0x4949;
8184 float CLASS find_green (int bps, int bite, int off0, int off1)
8187 int vbits, col, i, c;
8188 ushort img[2][2064];
8192 fseek (ifp, c ? off1:off0, SEEK_SET);
8193 for (vbits=col=0; col < width; col++) {
8194 for (vbits -= bps; vbits < 0; vbits += bite) {
8196 for (i=0; i < bite; i+=8)
8197 bitbuf |= (unsigned) (fgetc(ifp) << i);
8199 img[c][col] = bitbuf << (64-bps-vbits) >> (64-bps);
8203 sum[ c & 1] += ABS(img[0][c]-img[1][c+1]);
8204 sum[~c & 1] += ABS(img[1][c]-img[0][c+1]);
8206 return 100 * log(sum[0]/sum[1]);
8210 Identify which camera created this file, and set global variables
8213 void CLASS identify()
8215 static const short pana[][6] = {
8216 { 3130, 1743, 4, 0, -6, 0 },
8217 { 3130, 2055, 4, 0, -6, 0 },
8218 { 3130, 2319, 4, 0, -6, 0 },
8219 { 3170, 2103, 18, 0,-42, 20 },
8220 { 3170, 2367, 18, 13,-42,-21 },
8221 { 3177, 2367, 0, 0, -1, 0 },
8222 { 3304, 2458, 0, 0, -1, 0 },
8223 { 3330, 2463, 9, 0, -5, 0 },
8224 { 3330, 2479, 9, 0,-17, 4 },
8225 { 3370, 1899, 15, 0,-44, 20 },
8226 { 3370, 2235, 15, 0,-44, 20 },
8227 { 3370, 2511, 15, 10,-44,-21 },
8228 { 3690, 2751, 3, 0, -8, -3 },
8229 { 3710, 2751, 0, 0, -3, 0 },
8230 { 3724, 2450, 0, 0, 0, -2 },
8231 { 3770, 2487, 17, 0,-44, 19 },
8232 { 3770, 2799, 17, 15,-44,-19 },
8233 { 3880, 2170, 6, 0, -6, 0 },
8234 { 4060, 3018, 0, 0, 0, -2 },
8235 { 4290, 2391, 3, 0, -8, -1 },
8236 { 4330, 2439, 17, 15,-44,-19 },
8237 { 4508, 2962, 0, 0, -3, -4 },
8238 { 4508, 3330, 0, 0, -3, -6 },
8240 static const ushort canon[][11] = {
8241 { 1944, 1416, 0, 0, 48, 0 },
8242 { 2144, 1560, 4, 8, 52, 2, 0, 0, 0, 25 },
8243 { 2224, 1456, 48, 6, 0, 2 },
8244 { 2376, 1728, 12, 6, 52, 2 },
8245 { 2672, 1968, 12, 6, 44, 2 },
8246 { 3152, 2068, 64, 12, 0, 0, 16 },
8247 { 3160, 2344, 44, 12, 4, 4 },
8248 { 3344, 2484, 4, 6, 52, 6 },
8249 { 3516, 2328, 42, 14, 0, 0 },
8250 { 3596, 2360, 74, 12, 0, 0 },
8251 { 3744, 2784, 52, 12, 8, 12 },
8252 { 3944, 2622, 30, 18, 6, 2 },
8253 { 3948, 2622, 42, 18, 0, 2 },
8254 { 3984, 2622, 76, 20, 0, 2, 14 },
8255 { 4104, 3048, 48, 12, 24, 12 },
8256 { 4116, 2178, 4, 2, 0, 0 },
8257 { 4152, 2772, 192, 12, 0, 0 },
8258 { 4160, 3124, 104, 11, 8, 65 },
8259 { 4176, 3062, 96, 17, 8, 0, 0, 16, 0, 7, 0x49 },
8260 { 4192, 3062, 96, 17, 24, 0, 0, 16, 0, 0, 0x49 },
8261 { 4312, 2876, 22, 18, 0, 2 },
8262 { 4352, 2874, 62, 18, 0, 0 },
8263 { 4476, 2954, 90, 34, 0, 0 },
8264 { 4480, 3348, 12, 10, 36, 12, 0, 0, 0, 18, 0x49 },
8265 { 4480, 3366, 80, 50, 0, 0 },
8266 { 4496, 3366, 80, 50, 12, 0 },
8267 { 4768, 3516, 96, 16, 0, 0, 0, 16 },
8268 { 4832, 3204, 62, 26, 0, 0 },
8269 { 4832, 3228, 62, 51, 0, 0 },
8270 { 5108, 3349, 98, 13, 0, 0 },
8271 { 5120, 3318, 142, 45, 62, 0 },
8272 { 5280, 3528, 72, 52, 0, 0 },
8273 { 5344, 3516, 142, 51, 0, 0 },
8274 { 5344, 3584, 126,100, 0, 2 },
8275 { 5360, 3516, 158, 51, 0, 0 },
8276 { 5568, 3708, 72, 38, 0, 0 },
8277 { 5632, 3710, 96, 17, 0, 0, 0, 16, 0, 0, 0x49 },
8278 { 5712, 3774, 62, 20, 10, 2 },
8279 { 5792, 3804, 158, 51, 0, 0 },
8280 { 5920, 3950, 122, 80, 2, 0 },
8281 { 6096, 4056, 72, 34, 0, 0 },
8282 { 6288, 4056, 264, 34, 0, 0 },
8283 { 8896, 5920, 160, 64, 0, 0 },
8285 static const struct {
8289 { 0x168, "EOS 10D" }, { 0x001, "EOS-1D" },
8290 { 0x175, "EOS 20D" }, { 0x174, "EOS-1D Mark II" },
8291 { 0x234, "EOS 30D" }, { 0x232, "EOS-1D Mark II N" },
8292 { 0x190, "EOS 40D" }, { 0x169, "EOS-1D Mark III" },
8293 { 0x261, "EOS 50D" }, { 0x281, "EOS-1D Mark IV" },
8294 { 0x287, "EOS 60D" }, { 0x167, "EOS-1DS" },
8295 { 0x325, "EOS 70D" },
8296 { 0x350, "EOS 80D" }, { 0x328, "EOS-1D X Mark II" },
8297 { 0x170, "EOS 300D" }, { 0x188, "EOS-1Ds Mark II" },
8298 { 0x176, "EOS 450D" }, { 0x215, "EOS-1Ds Mark III" },
8299 { 0x189, "EOS 350D" }, { 0x324, "EOS-1D C" },
8300 { 0x236, "EOS 400D" }, { 0x269, "EOS-1D X" },
8301 { 0x252, "EOS 500D" }, { 0x213, "EOS 5D" },
8302 { 0x270, "EOS 550D" }, { 0x218, "EOS 5D Mark II" },
8303 { 0x286, "EOS 600D" }, { 0x285, "EOS 5D Mark III" },
8304 { 0x301, "EOS 650D" }, { 0x302, "EOS 6D" },
8305 { 0x326, "EOS 700D" }, { 0x250, "EOS 7D" },
8306 { 0x393, "EOS 750D" }, { 0x289, "EOS 7D Mark II" },
8307 { 0x347, "EOS 760D" },
8308 { 0x254, "EOS 1000D" },
8309 { 0x288, "EOS 1100D" },
8310 { 0x327, "EOS 1200D" }, { 0x382, "Canon EOS 5DS" },
8311 { 0x404, "EOS 1300D" }, { 0x401, "Canon EOS 5DS R" },
8312 { 0x346, "EOS 100D" },
8314 { 0x002, "DSC-R1" }, { 0x100, "DSLR-A100" },
8315 { 0x101, "DSLR-A900" }, { 0x102, "DSLR-A700" },
8316 { 0x103, "DSLR-A200" }, { 0x104, "DSLR-A350" },
8317 { 0x105, "DSLR-A300" }, { 0x108, "DSLR-A330" },
8318 { 0x109, "DSLR-A230" }, { 0x10a, "DSLR-A290" },
8319 { 0x10d, "DSLR-A850" }, { 0x111, "DSLR-A550" },
8320 { 0x112, "DSLR-A500" }, { 0x113, "DSLR-A450" },
8321 { 0x116, "NEX-5" }, { 0x117, "NEX-3" },
8322 { 0x118, "SLT-A33" }, { 0x119, "SLT-A55V" },
8323 { 0x11a, "DSLR-A560" }, { 0x11b, "DSLR-A580" },
8324 { 0x11c, "NEX-C3" }, { 0x11d, "SLT-A35" },
8325 { 0x11e, "SLT-A65V" }, { 0x11f, "SLT-A77V" },
8326 { 0x120, "NEX-5N" }, { 0x121, "NEX-7" },
8327 { 0x123, "SLT-A37" }, { 0x124, "SLT-A57" },
8328 { 0x125, "NEX-F3" }, { 0x126, "SLT-A99V" },
8329 { 0x127, "NEX-6" }, { 0x128, "NEX-5R" },
8330 { 0x129, "DSC-RX100" }, { 0x12a, "DSC-RX1" },
8331 { 0x12e, "ILCE-3000" }, { 0x12f, "SLT-A58" },
8332 { 0x131, "NEX-3N" }, { 0x132, "ILCE-7" },
8333 { 0x133, "NEX-5T" }, { 0x134, "DSC-RX100M2" },
8334 { 0x135, "DSC-RX10" }, { 0x136, "DSC-RX1R" },
8335 { 0x137, "ILCE-7R" }, { 0x138, "ILCE-6000" },
8336 { 0x139, "ILCE-5000" }, { 0x13d, "DSC-RX100M3" },
8337 { 0x13e, "ILCE-7S" }, { 0x13f, "ILCA-77M2" },
8338 { 0x153, "ILCE-5100" }, { 0x154, "ILCE-7M2" },
8339 { 0x155, "DSC-RX100M4" },{ 0x156, "DSC-RX10M2" },
8340 { 0x158, "DSC-RX1RM2" }, { 0x15a, "ILCE-QX1" },
8341 { 0x15b, "ILCE-7RM2" }, { 0x15e, "ILCE-7SM2" },
8342 { 0x161, "ILCA-68" }, { 0x165, "ILCE-6300" },
8344 static const struct {
8347 uchar lm, tm, rm, bm, lf, cf, max, flags;
8348 char make[10], model[20];
8351 { 786432,1024, 768, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-080C" },
8352 { 1447680,1392,1040, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-145C" },
8353 { 1920000,1600,1200, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-201C" },
8354 { 5067304,2588,1958, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-510C" },
8355 { 5067316,2588,1958, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-510C",12 },
8356 { 10134608,2588,1958, 0, 0, 0, 0, 9,0x94,0,0,"AVT","F-510C" },
8357 { 10134620,2588,1958, 0, 0, 0, 0, 9,0x94,0,0,"AVT","F-510C",12 },
8358 { 16157136,3272,2469, 0, 0, 0, 0, 9,0x94,0,0,"AVT","F-810C" },
8359 { 15980544,3264,2448, 0, 0, 0, 0, 8,0x61,0,1,"AgfaPhoto","DC-833m" },
8360 { 9631728,2532,1902, 0, 0, 0, 0,96,0x61,0,0,"Alcatel","5035D" },
8361 { 2868726,1384,1036, 0, 0, 0, 0,64,0x49,0,8,"Baumer","TXG14",1078 },
8362 { 5298000,2400,1766,12,12,44, 2,40,0x94,0,2,"Canon","PowerShot SD300" },
8363 { 6553440,2664,1968, 4, 4,44, 4,40,0x94,0,2,"Canon","PowerShot A460" },
8364 { 6573120,2672,1968,12, 8,44, 0,40,0x94,0,2,"Canon","PowerShot A610" },
8365 { 6653280,2672,1992,10, 6,42, 2,40,0x94,0,2,"Canon","PowerShot A530" },
8366 { 7710960,2888,2136,44, 8, 4, 0,40,0x94,0,2,"Canon","PowerShot S3 IS" },
8367 { 9219600,3152,2340,36,12, 4, 0,40,0x94,0,2,"Canon","PowerShot A620" },
8368 { 9243240,3152,2346,12, 7,44,13,40,0x49,0,2,"Canon","PowerShot A470" },
8369 { 10341600,3336,2480, 6, 5,32, 3,40,0x94,0,2,"Canon","PowerShot A720 IS" },
8370 { 10383120,3344,2484,12, 6,44, 6,40,0x94,0,2,"Canon","PowerShot A630" },
8371 { 12945240,3736,2772,12, 6,52, 6,40,0x94,0,2,"Canon","PowerShot A640" },
8372 { 15636240,4104,3048,48,12,24,12,40,0x94,0,2,"Canon","PowerShot A650" },
8373 { 15467760,3720,2772, 6,12,30, 0,40,0x94,0,2,"Canon","PowerShot SX110 IS" },
8374 { 15534576,3728,2778,12, 9,44, 9,40,0x94,0,2,"Canon","PowerShot SX120 IS" },
8375 { 18653760,4080,3048,24,12,24,12,40,0x94,0,2,"Canon","PowerShot SX20 IS" },
8376 { 19131120,4168,3060,92,16, 4, 1,40,0x94,0,2,"Canon","PowerShot SX220 HS" },
8377 { 21936096,4464,3276,25,10,73,12,40,0x16,0,2,"Canon","PowerShot SX30 IS" },
8378 { 24724224,4704,3504, 8,16,56, 8,40,0x94,0,2,"Canon","PowerShot A3300 IS" },
8379 { 30858240,5248,3920, 8,16,56,16,40,0x94,0,2,"Canon","IXUS 160" },
8380 { 1976352,1632,1211, 0, 2, 0, 1, 0,0x94,0,1,"Casio","QV-2000UX" },
8381 { 3217760,2080,1547, 0, 0,10, 1, 0,0x94,0,1,"Casio","QV-3*00EX" },
8382 { 6218368,2585,1924, 0, 0, 9, 0, 0,0x94,0,1,"Casio","QV-5700" },
8383 { 7816704,2867,2181, 0, 0,34,36, 0,0x16,0,1,"Casio","EX-Z60" },
8384 { 2937856,1621,1208, 0, 0, 1, 0, 0,0x94,7,13,"Casio","EX-S20" },
8385 { 4948608,2090,1578, 0, 0,32,34, 0,0x94,7,1,"Casio","EX-S100" },
8386 { 6054400,2346,1720, 2, 0,32, 0, 0,0x94,7,1,"Casio","QV-R41" },
8387 { 7426656,2568,1928, 0, 0, 0, 0, 0,0x94,0,1,"Casio","EX-P505" },
8388 { 7530816,2602,1929, 0, 0,22, 0, 0,0x94,7,1,"Casio","QV-R51" },
8389 { 7542528,2602,1932, 0, 0,32, 0, 0,0x94,7,1,"Casio","EX-Z50" },
8390 { 7562048,2602,1937, 0, 0,25, 0, 0,0x16,7,1,"Casio","EX-Z500" },
8391 { 7753344,2602,1986, 0, 0,32,26, 0,0x94,7,1,"Casio","EX-Z55" },
8392 { 9313536,2858,2172, 0, 0,14,30, 0,0x94,7,1,"Casio","EX-P600" },
8393 { 10834368,3114,2319, 0, 0,27, 0, 0,0x94,0,1,"Casio","EX-Z750" },
8394 { 10843712,3114,2321, 0, 0,25, 0, 0,0x94,0,1,"Casio","EX-Z75" },
8395 { 10979200,3114,2350, 0, 0,32,32, 0,0x94,7,1,"Casio","EX-P700" },
8396 { 12310144,3285,2498, 0, 0, 6,30, 0,0x94,0,1,"Casio","EX-Z850" },
8397 { 12489984,3328,2502, 0, 0,47,35, 0,0x94,0,1,"Casio","EX-Z8" },
8398 { 15499264,3754,2752, 0, 0,82, 0, 0,0x94,0,1,"Casio","EX-Z1050" },
8399 { 18702336,4096,3044, 0, 0,24, 0,80,0x94,7,1,"Casio","EX-ZR100" },
8400 { 7684000,2260,1700, 0, 0, 0, 0,13,0x94,0,1,"Casio","QV-4000" },
8401 { 787456,1024, 769, 0, 1, 0, 0, 0,0x49,0,0,"Creative","PC-CAM 600" },
8402 { 28829184,4384,3288, 0, 0, 0, 0,36,0x61,0,0,"DJI" },
8403 { 15151104,4608,3288, 0, 0, 0, 0, 0,0x94,0,0,"Matrix" },
8404 { 3840000,1600,1200, 0, 0, 0, 0,65,0x49,0,0,"Foculus","531C" },
8405 { 307200, 640, 480, 0, 0, 0, 0, 0,0x94,0,0,"Generic" },
8406 { 62464, 256, 244, 1, 1, 6, 1, 0,0x8d,0,0,"Kodak","DC20" },
8407 { 124928, 512, 244, 1, 1,10, 1, 0,0x8d,0,0,"Kodak","DC20" },
8408 { 1652736,1536,1076, 0,52, 0, 0, 0,0x61,0,0,"Kodak","DCS200" },
8409 { 4159302,2338,1779, 1,33, 1, 2, 0,0x94,0,0,"Kodak","C330" },
8410 { 4162462,2338,1779, 1,33, 1, 2, 0,0x94,0,0,"Kodak","C330",3160 },
8411 { 2247168,1232, 912, 0, 0,16, 0, 0,0x00,0,0,"Kodak","C330" },
8412 { 3370752,1232, 912, 0, 0,16, 0, 0,0x00,0,0,"Kodak","C330" },
8413 { 6163328,2864,2152, 0, 0, 0, 0, 0,0x94,0,0,"Kodak","C603" },
8414 { 6166488,2864,2152, 0, 0, 0, 0, 0,0x94,0,0,"Kodak","C603",3160 },
8415 { 460800, 640, 480, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","C603" },
8416 { 9116448,2848,2134, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","C603" },
8417 { 12241200,4040,3030, 2, 0, 0,13, 0,0x49,0,0,"Kodak","12MP" },
8418 { 12272756,4040,3030, 2, 0, 0,13, 0,0x49,0,0,"Kodak","12MP",31556 },
8419 { 18000000,4000,3000, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","12MP" },
8420 { 614400, 640, 480, 0, 3, 0, 0,64,0x94,0,0,"Kodak","KAI-0340" },
8421 { 15360000,3200,2400, 0, 0, 0, 0,96,0x16,0,0,"Lenovo","A820" },
8422 { 3884928,1608,1207, 0, 0, 0, 0,96,0x16,0,0,"Micron","2010",3212 },
8423 { 1138688,1534, 986, 0, 0, 0, 0, 0,0x61,0,0,"Minolta","RD175",513 },
8424 { 1581060,1305, 969, 0, 0,18, 6, 6,0x1e,4,1,"Nikon","E900" },
8425 { 2465792,1638,1204, 0, 0,22, 1, 6,0x4b,5,1,"Nikon","E950" },
8426 { 2940928,1616,1213, 0, 0, 0, 7,30,0x94,0,1,"Nikon","E2100" },
8427 { 4771840,2064,1541, 0, 0, 0, 1, 6,0xe1,0,1,"Nikon","E990" },
8428 { 4775936,2064,1542, 0, 0, 0, 0,30,0x94,0,1,"Nikon","E3700" },
8429 { 5865472,2288,1709, 0, 0, 0, 1, 6,0xb4,0,1,"Nikon","E4500" },
8430 { 5869568,2288,1710, 0, 0, 0, 0, 6,0x16,0,1,"Nikon","E4300" },
8431 { 7438336,2576,1925, 0, 0, 0, 1, 6,0xb4,0,1,"Nikon","E5000" },
8432 { 8998912,2832,2118, 0, 0, 0, 0,30,0x94,7,1,"Nikon","COOLPIX S6" },
8433 { 5939200,2304,1718, 0, 0, 0, 0,30,0x16,0,0,"Olympus","C770UZ" },
8434 { 3178560,2064,1540, 0, 0, 0, 0, 0,0x94,0,1,"Pentax","Optio S" },
8435 { 4841984,2090,1544, 0, 0,22, 0, 0,0x94,7,1,"Pentax","Optio S" },
8436 { 6114240,2346,1737, 0, 0,22, 0, 0,0x94,7,1,"Pentax","Optio S4" },
8437 { 10702848,3072,2322, 0, 0, 0,21,30,0x94,0,1,"Pentax","Optio 750Z" },
8438 { 4147200,1920,1080, 0, 0, 0, 0, 0,0x49,0,0,"Photron","BC2-HD" },
8439 { 4151666,1920,1080, 0, 0, 0, 0, 0,0x49,0,0,"Photron","BC2-HD",8 },
8440 { 13248000,2208,3000, 0, 0, 0, 0,13,0x61,0,0,"Pixelink","A782" },
8441 { 6291456,2048,1536, 0, 0, 0, 0,96,0x61,0,0,"RoverShot","3320AF" },
8442 { 311696, 644, 484, 0, 0, 0, 0, 0,0x16,0,8,"ST Micro","STV680 VGA" },
8443 { 16098048,3288,2448, 0, 0,24, 0, 9,0x94,0,1,"Samsung","S85" },
8444 { 16215552,3312,2448, 0, 0,48, 0, 9,0x94,0,1,"Samsung","S85" },
8445 { 20487168,3648,2808, 0, 0, 0, 0,13,0x94,5,1,"Samsung","WB550" },
8446 { 24000000,4000,3000, 0, 0, 0, 0,13,0x94,5,1,"Samsung","WB550" },
8447 { 12582980,3072,2048, 0, 0, 0, 0,33,0x61,0,0,"Sinar","",68 },
8448 { 33292868,4080,4080, 0, 0, 0, 0,33,0x61,0,0,"Sinar","",68 },
8449 { 44390468,4080,5440, 0, 0, 0, 0,33,0x61,0,0,"Sinar","",68 },
8450 { 1409024,1376,1024, 0, 0, 1, 0, 0,0x49,0,0,"Sony","XCD-SX910CR" },
8451 { 2818048,1376,1024, 0, 0, 1, 0,97,0x49,0,0,"Sony","XCD-SX910CR" },
8453 static const char *corp[] =
8454 { "AgfaPhoto", "Canon", "Casio", "Epson", "Fujifilm",
8455 "Mamiya", "Minolta", "Motorola", "Kodak", "Konica", "Leica",
8456 "Nikon", "Nokia", "Olympus", "Ricoh", "Pentax", "Phase One",
8457 "Samsung", "Sigma", "Sinar", "Sony" };
8459 int hlen, flen, fsize, zero_fsize=1, i, c;
8462 tiff_flip = flip = filters = UINT_MAX; /* unknown */
8463 raw_height = raw_width = fuji_width = fuji_layout = cr2_slice[0] = 0;
8464 maximum = height = width = top_margin = left_margin = 0;
8465 cdesc[0] = desc[0] = artist[0] = make[0] = model[0] = model2[0] = 0;
8466 iso_speed = shutter = aperture = focal_len = unique_id = 0;
8468 memset (tiff_ifd, 0, sizeof tiff_ifd);
8469 memset (gpsdata, 0, sizeof gpsdata);
8470 memset (cblack, 0, sizeof cblack);
8471 memset (white, 0, sizeof white);
8472 memset (mask, 0, sizeof mask);
8473 thumb_offset = thumb_length = thumb_width = thumb_height = 0;
8474 load_raw = thumb_load_raw = 0;
8475 write_thumb = &CLASS jpeg_thumb;
8476 data_offset = meta_offset = meta_length = tiff_bps = tiff_compress = 0;
8477 kodak_cbpp = zero_after_ff = dng_version = load_flags = 0;
8478 timestamp = shot_order = tiff_samples = black = is_foveon = 0;
8479 mix_green = profile_length = data_error = zero_is_bad = 0;
8480 pixel_aspect = is_raw = raw_color = 1;
8481 tile_width = tile_length = 0;
8482 for (i=0; i < 4; i++) {
8483 cam_mul[i] = i == 1;
8485 FORC3 cmatrix[c][i] = 0;
8486 FORC3 rgb_cam[c][i] = c == i;
8489 for (i=0; i < 0x10000; i++) curve[i] = i;
8493 fseek (ifp, 0, SEEK_SET);
8494 fread (head, 1, 32, ifp);
8495 fseek (ifp, 0, SEEK_END);
8496 flen = fsize = ftell(ifp);
8497 if ((cp = (char *) memmem (head, 32, "MMMM", 4)) ||
8498 (cp = (char *) memmem (head, 32, "IIII", 4))) {
8499 parse_phase_one (cp-head);
8500 if (cp-head && parse_tiff(0)) apply_tiff();
8501 } else if (order == 0x4949 || order == 0x4d4d) {
8502 if (!memcmp (head+6,"HEAPCCDR",8)) {
8504 parse_ciff (hlen, flen-hlen, 0);
8505 load_raw = &CLASS canon_load_raw;
8506 } else if (parse_tiff(0)) apply_tiff();
8507 } else if (!memcmp (head,"\xff\xd8\xff\xe1",4) &&
8508 !memcmp (head+6,"Exif",4)) {
8509 fseek (ifp, 4, SEEK_SET);
8510 data_offset = 4 + get2();
8511 fseek (ifp, data_offset, SEEK_SET);
8512 if (fgetc(ifp) != 0xff)
8515 } else if (!memcmp (head+25,"ARECOYK",7)) {
8516 strcpy (make, "Contax");
8517 strcpy (model,"N Digital");
8518 fseek (ifp, 33, SEEK_SET);
8520 fseek (ifp, 60, SEEK_SET);
8521 FORC4 cam_mul[c ^ (c >> 1)] = get4();
8522 } else if (!strcmp (head, "PXN")) {
8523 strcpy (make, "Logitech");
8524 strcpy (model,"Fotoman Pixtura");
8525 } else if (!strcmp (head, "qktk")) {
8526 strcpy (make, "Apple");
8527 strcpy (model,"QuickTake 100");
8528 load_raw = &CLASS quicktake_100_load_raw;
8529 } else if (!strcmp (head, "qktn")) {
8530 strcpy (make, "Apple");
8531 strcpy (model,"QuickTake 150");
8532 load_raw = &CLASS kodak_radc_load_raw;
8533 } else if (!memcmp (head,"FUJIFILM",8)) {
8534 fseek (ifp, 84, SEEK_SET);
8535 thumb_offset = get4();
8536 thumb_length = get4();
8537 fseek (ifp, 92, SEEK_SET);
8538 parse_fuji (get4());
8539 if (thumb_offset > 120) {
8540 fseek (ifp, 120, SEEK_SET);
8541 is_raw += (i = get4()) && 1;
8542 if (is_raw == 2 && shot_select)
8545 load_raw = &CLASS unpacked_load_raw;
8546 fseek (ifp, 100+28*(shot_select > 0), SEEK_SET);
8547 parse_tiff (data_offset = get4());
8548 parse_tiff (thumb_offset+12);
8550 } else if (!memcmp (head,"RIFF",4)) {
8551 fseek (ifp, 0, SEEK_SET);
8553 } else if (!memcmp (head+4,"ftypqt ",9)) {
8554 fseek (ifp, 0, SEEK_SET);
8557 } else if (!memcmp (head,"\0\001\0\001\0@",6)) {
8558 fseek (ifp, 6, SEEK_SET);
8559 fread (make, 1, 8, ifp);
8560 fread (model, 1, 8, ifp);
8561 fread (model2, 1, 16, ifp);
8562 data_offset = get2();
8565 raw_height = get2();
8566 load_raw = &CLASS nokia_load_raw;
8567 filters = 0x61616161;
8568 } else if (!memcmp (head,"NOKIARAW",8)) {
8569 strcpy (make, "NOKIA");
8571 fseek (ifp, 300, SEEK_SET);
8572 data_offset = get4();
8576 switch (tiff_bps = i*8 / (width * height)) {
8577 case 8: load_raw = &CLASS eight_bit_load_raw; break;
8578 case 10: load_raw = &CLASS nokia_load_raw;
8580 raw_height = height + (top_margin = i / (width * tiff_bps/8) - height);
8582 filters = 0x61616161;
8583 } else if (!memcmp (head,"ARRI",4)) {
8585 fseek (ifp, 20, SEEK_SET);
8588 strcpy (make, "ARRI");
8589 fseek (ifp, 668, SEEK_SET);
8590 fread (model, 1, 64, ifp);
8592 load_raw = &CLASS packed_load_raw;
8594 filters = 0x61616161;
8595 } else if (!memcmp (head,"XPDS",4)) {
8597 fseek (ifp, 0x800, SEEK_SET);
8598 fread (make, 1, 41, ifp);
8599 raw_height = get2();
8601 fseek (ifp, 56, SEEK_CUR);
8602 fread (model, 1, 30, ifp);
8603 data_offset = 0x10000;
8604 load_raw = &CLASS canon_rmf_load_raw;
8605 gamma_curve (0, 12.25, 1, 1023);
8606 } else if (!memcmp (head+4,"RED1",4)) {
8607 strcpy (make, "Red");
8608 strcpy (model,"One");
8610 load_raw = &CLASS redcine_load_raw;
8611 gamma_curve (1/2.4, 12.92, 1, 4095);
8612 filters = 0x49494949;
8613 } else if (!memcmp (head,"DSC-Image",9))
8615 else if (!memcmp (head,"PWAD",4))
8617 else if (!memcmp (head,"\0MRM",4))
8619 else if (!memcmp (head,"FOVb",4))
8621 else if (!memcmp (head,"CI",2))
8624 for (zero_fsize=i=0; i < sizeof table / sizeof *table; i++)
8625 if (fsize == table[i].fsize) {
8626 strcpy (make, table[i].make );
8627 strcpy (model, table[i].model);
8628 flip = table[i].flags >> 2;
8629 zero_is_bad = table[i].flags & 2;
8630 if (table[i].flags & 1)
8631 parse_external_jpeg();
8632 data_offset = table[i].offset;
8633 raw_width = table[i].rw;
8634 raw_height = table[i].rh;
8635 left_margin = table[i].lm;
8636 top_margin = table[i].tm;
8637 width = raw_width - left_margin - table[i].rm;
8638 height = raw_height - top_margin - table[i].bm;
8639 filters = 0x1010101 * table[i].cf;
8640 colors = 4 - !((filters & filters >> 1) & 0x5555);
8641 load_flags = table[i].lf;
8642 switch (tiff_bps = (fsize-data_offset)*8 / (raw_width*raw_height)) {
8644 load_raw = &CLASS minolta_rd175_load_raw; break;
8646 load_raw = &CLASS eight_bit_load_raw; break;
8649 load_raw = &CLASS packed_load_raw; break;
8651 order = 0x4949 | 0x404 * (load_flags & 1);
8652 tiff_bps -= load_flags >> 4;
8653 tiff_bps -= load_flags = load_flags >> 1 & 7;
8654 load_raw = &CLASS unpacked_load_raw;
8656 maximum = (1 << tiff_bps) - (1 << table[i].max);
8658 if (zero_fsize) fsize = 0;
8659 if (make[0] == 0) parse_smal (0, flen);
8662 if (!(strncmp(model,"ov",2) && strncmp(model,"RP_OV",5)) &&
8663 !fseek (ifp, -6404096, SEEK_END) &&
8664 fread (head, 1, 32, ifp) && !strcmp(head,"BRCMn")) {
8665 strcpy (make, "OmniVision");
8666 data_offset = ftell(ifp) + 0x8000-32;
8669 load_raw = &CLASS nokia_load_raw;
8670 filters = 0x16161616;
8674 for (i=0; i < sizeof corp / sizeof *corp; i++)
8675 if (strcasestr (make, corp[i])) /* Simplify company names */
8676 strcpy (make, corp[i]);
8677 if ((!strcmp(make,"Kodak") || !strcmp(make,"Leica")) &&
8678 ((cp = strcasestr(model," DIGITAL CAMERA")) ||
8679 (cp = strstr(model,"FILE VERSION"))))
8681 if (!strncasecmp(model,"PENTAX",6))
8682 strcpy (make, "Pentax");
8683 cp = make + strlen(make); /* Remove trailing spaces */
8684 while (*--cp == ' ') *cp = 0;
8685 cp = model + strlen(model);
8686 while (*--cp == ' ') *cp = 0;
8687 i = strlen(make); /* Remove make from model */
8688 if (!strncasecmp (model, make, i) && model[i++] == ' ')
8689 memmove (model, model+i, 64-i);
8690 if (!strncmp (model,"FinePix ",8))
8691 strcpy (model, model+8);
8692 if (!strncmp (model,"Digital Camera ",15))
8693 strcpy (model, model+15);
8694 desc[511] = artist[63] = make[63] = model[63] = model2[63] = 0;
8695 if (!is_raw) goto notraw;
8697 if (!height) height = raw_height;
8698 if (!width) width = raw_width;
8699 if (height == 2624 && width == 3936) /* Pentax K10D and Samsung GX10 */
8700 { height = 2616; width = 3896; }
8701 if (height == 3136 && width == 4864) /* Pentax K20D and Samsung GX20 */
8702 { height = 3124; width = 4688; filters = 0x16161616; }
8703 if (width == 4352 && (!strcmp(model,"K-r") || !strcmp(model,"K-x")))
8704 { width = 4309; filters = 0x16161616; }
8705 if (width >= 4960 && !strncmp(model,"K-5",3))
8706 { left_margin = 10; width = 4950; filters = 0x16161616; }
8707 if (width == 4736 && !strcmp(model,"K-7"))
8708 { height = 3122; width = 4684; filters = 0x16161616; top_margin = 2; }
8709 if (width == 6080 && !strcmp(model,"K-3"))
8710 { left_margin = 4; width = 6040; }
8711 if (width == 7424 && !strcmp(model,"645D"))
8712 { height = 5502; width = 7328; filters = 0x61616161; top_margin = 29;
8714 if (height == 3014 && width == 4096) /* Ricoh GX200 */
8717 if (filters == UINT_MAX) filters = 0;
8718 if (filters) is_raw *= tiff_samples;
8719 else colors = tiff_samples;
8720 switch (tiff_compress) {
8722 case 1: load_raw = &CLASS packed_dng_load_raw; break;
8723 case 7: load_raw = &CLASS lossless_dng_load_raw; break;
8724 case 34892: load_raw = &CLASS lossy_dng_load_raw; break;
8725 default: load_raw = 0;
8729 if (!strcmp(make,"Canon") && !fsize && tiff_bps != 15) {
8731 load_raw = &CLASS lossless_jpeg_load_raw;
8732 for (i=0; i < sizeof canon / sizeof *canon; i++)
8733 if (raw_width == canon[i][0] && raw_height == canon[i][1]) {
8734 width = raw_width - (left_margin = canon[i][2]);
8735 height = raw_height - (top_margin = canon[i][3]);
8736 width -= canon[i][4];
8737 height -= canon[i][5];
8738 mask[0][1] = canon[i][6];
8739 mask[0][3] = -canon[i][7];
8740 mask[1][1] = canon[i][8];
8741 mask[1][3] = -canon[i][9];
8742 if (canon[i][10]) filters = canon[i][10] * 0x01010101;
8744 if ((unique_id | 0x20000) == 0x2720000) {
8749 for (i=0; i < sizeof unique / sizeof *unique; i++)
8750 if (unique_id == 0x80000000 + unique[i].id) {
8751 adobe_coeff ("Canon", unique[i].model);
8752 if (model[4] == 'K' && strlen(model) == 8)
8753 strcpy (model, unique[i].model);
8755 for (i=0; i < sizeof sonique / sizeof *sonique; i++)
8756 if (unique_id == sonique[i].id)
8757 strcpy (model, sonique[i].model);
8758 if (!strcmp(make,"Nikon")) {
8760 load_raw = &CLASS packed_load_raw;
8761 if (model[0] == 'E')
8762 load_flags |= !data_offset << 2 | 2;
8765 /* Set parameters based on camera name (for non-DNG files). */
8767 if (!strcmp(model,"KAI-0340")
8768 && find_green (16, 16, 3840, 5120) < 25) {
8770 top_margin = filters = 0;
8771 strcpy (model,"C603");
8773 if (!strcmp(make,"Sony") && raw_width > 3888)
8774 black = 128 << (tiff_bps - 12);
8776 if (height*2 < width) pixel_aspect = 0.5;
8777 if (height > width) pixel_aspect = 2;
8780 } else if (!strcmp(make,"Canon") && tiff_bps == 15) {
8782 case 3344: width -= 66;
8783 case 3872: width -= 6;
8785 if (height > width) {
8787 SWAP(raw_height,raw_width);
8789 if (width == 7200 && height == 3888) {
8790 raw_width = width = 6480;
8791 raw_height = height = 4320;
8794 tiff_samples = colors = 3;
8795 load_raw = &CLASS canon_sraw_load_raw;
8796 } else if (!strcmp(model,"PowerShot 600")) {
8801 filters = 0xe1e4e1e4;
8802 load_raw = &CLASS canon_600_load_raw;
8803 } else if (!strcmp(model,"PowerShot A5") ||
8804 !strcmp(model,"PowerShot A5 Zoom")) {
8808 pixel_aspect = 256/235.0;
8809 filters = 0x1e4e1e4e;
8811 } else if (!strcmp(model,"PowerShot A50")) {
8815 filters = 0x1b4e4b1e;
8817 } else if (!strcmp(model,"PowerShot Pro70")) {
8820 filters = 0x1e4b4e1b;
8824 load_raw = &CLASS packed_load_raw;
8826 } else if (!strcmp(model,"PowerShot Pro90 IS") ||
8827 !strcmp(model,"PowerShot G1")) {
8829 filters = 0xb4b4b4b4;
8830 } else if (!strcmp(model,"PowerShot A610")) {
8831 if (canon_s2is()) strcpy (model+10, "S2 IS");
8832 } else if (!strcmp(model,"PowerShot SX220 HS")) {
8834 } else if (!strcmp(model,"EOS D2000C")) {
8835 filters = 0x61616161;
8837 } else if (!strcmp(model,"D1")) {
8838 cam_mul[0] *= 256/527.0;
8839 cam_mul[2] *= 256/317.0;
8840 } else if (!strcmp(model,"D1X")) {
8843 } else if (!strcmp(model,"D40X") ||
8844 !strcmp(model,"D60") ||
8845 !strcmp(model,"D80") ||
8846 !strcmp(model,"D3000")) {
8849 } else if (!strcmp(model,"D3") ||
8850 !strcmp(model,"D3S") ||
8851 !strcmp(model,"D700")) {
8854 } else if (!strcmp(model,"D3100")) {
8857 } else if (!strcmp(model,"D5000") ||
8858 !strcmp(model,"D90")) {
8860 } else if (!strcmp(model,"D5100") ||
8861 !strcmp(model,"D7000") ||
8862 !strcmp(model,"COOLPIX A")) {
8864 } else if (!strcmp(model,"D3200") ||
8865 !strncmp(model,"D6",2) ||
8866 !strncmp(model,"D800",4)) {
8868 } else if (!strcmp(model,"D4") ||
8869 !strcmp(model,"Df")) {
8872 } else if (!strncmp(model,"D40",3) ||
8873 !strncmp(model,"D50",3) ||
8874 !strncmp(model,"D70",3)) {
8876 } else if (!strcmp(model,"D100")) {
8878 raw_width = (width += 3) + 3;
8879 } else if (!strcmp(model,"D200")) {
8882 filters = 0x94949494;
8883 } else if (!strncmp(model,"D2H",3)) {
8886 } else if (!strncmp(model,"D2X",3)) {
8887 if (width == 3264) width -= 32;
8889 } else if (!strncmp(model,"D300",4)) {
8891 } else if (!strncmp(model,"COOLPIX P",9) && raw_width != 4032) {
8893 filters = 0x94949494;
8894 if (model[9] == '7' && iso_speed >= 400)
8896 } else if (!strncmp(model,"1 ",2)) {
8898 } else if (fsize == 1581060) {
8900 pre_mul[0] = 1.2085;
8901 pre_mul[1] = 1.0943;
8902 pre_mul[3] = 1.1103;
8903 } else if (fsize == 3178560) {
8906 } else if (fsize == 4771840) {
8907 if (!timestamp && nikon_e995())
8908 strcpy (model, "E995");
8909 if (strcmp(model,"E995")) {
8910 filters = 0xb4b4b4b4;
8916 } else if (fsize == 2940928) {
8917 if (!timestamp && !nikon_e2100())
8918 strcpy (model,"E2500");
8919 if (!strcmp(model,"E2500")) {
8923 filters = 0x4b4b4b4b;
8925 } else if (fsize == 4775936) {
8926 if (!timestamp) nikon_3700();
8927 if (model[0] == 'E' && atoi(model+1) < 3700)
8928 filters = 0x49494949;
8929 if (!strcmp(model,"Optio 33WR")) {
8931 filters = 0x16161616;
8933 if (make[0] == 'O') {
8934 i = find_green (12, 32, 1188864, 3576832);
8935 c = find_green (12, 32, 2383920, 2387016);
8936 if (abs(i) < abs(c)) {
8940 if (i < 0) filters = 0x61616161;
8942 } else if (fsize == 5869568) {
8943 if (!timestamp && minolta_z2()) {
8944 strcpy (make, "Minolta");
8945 strcpy (model,"DiMAGE Z2");
8947 load_flags = 6 + 24*(make[0] == 'M');
8948 } else if (fsize == 6291456) {
8949 fseek (ifp, 0x300000, SEEK_SET);
8950 if ((order = guess_byte_order(0x10000)) == 0x4d4d) {
8951 height -= (top_margin = 16);
8952 width -= (left_margin = 28);
8954 strcpy (make, "ISG");
8957 } else if (!strcmp(make,"Fujifilm")) {
8958 if (!strcmp(model+7,"S2Pro")) {
8959 strcpy (model,"S2Pro");
8963 } else if (load_raw != &CLASS packed_load_raw)
8964 maximum = (is_raw == 2 && shot_select) ? 0x2f00 : 0x3e00;
8965 top_margin = (raw_height - height) >> 2 << 1;
8966 left_margin = (raw_width - width ) >> 2 << 1;
8967 if (width == 2848 || width == 3664) filters = 0x16161616;
8968 if (width == 4032 || width == 4952 || width == 6032) left_margin = 0;
8969 if (width == 3328 && (width -= 66)) left_margin = 34;
8970 if (width == 4936) left_margin = 4;
8971 if (!strcmp(model,"HS50EXR") ||
8972 !strcmp(model,"F900EXR")) {
8975 filters = 0x16161616;
8977 if (fuji_layout) raw_width *= is_raw;
8979 FORC(36) ((char *)xtrans)[c] =
8980 xtrans_abs[(c/6+top_margin) % 6][(c+left_margin) % 6];
8981 } else if (!strcmp(model,"KD-400Z")) {
8986 } else if (!strcmp(model,"KD-510Z")) {
8988 } else if (!strcasecmp(make,"Minolta")) {
8989 if (!load_raw && (maximum = 0xfff))
8990 load_raw = &CLASS unpacked_load_raw;
8991 if (!strncmp(model,"DiMAGE A",8)) {
8992 if (!strcmp(model,"DiMAGE A200"))
8993 filters = 0x49494949;
8995 load_raw = &CLASS packed_load_raw;
8996 } else if (!strncmp(model,"ALPHA",5) ||
8997 !strncmp(model,"DYNAX",5) ||
8998 !strncmp(model,"MAXXUM",6)) {
8999 sprintf (model+20, "DYNAX %-10s", model+6+(model[0]=='M'));
9000 adobe_coeff (make, model+20);
9001 load_raw = &CLASS packed_load_raw;
9002 } else if (!strncmp(model,"DiMAGE G",8)) {
9003 if (model[8] == '4') {
9006 } else if (model[8] == '5') {
9011 } else if (model[8] == '6') {
9016 filters = 0x61616161;
9018 load_raw = &CLASS unpacked_load_raw;
9022 } else if (!strcmp(model,"*ist D")) {
9023 load_raw = &CLASS unpacked_load_raw;
9025 } else if (!strcmp(model,"*ist DS")) {
9027 } else if (!strcmp(make,"Samsung") && raw_width == 4704) {
9028 height -= top_margin = 8;
9029 width -= 2 * (left_margin = 8);
9031 } else if (!strcmp(make,"Samsung") && raw_height == 3714) {
9032 height -= top_margin = 18;
9033 left_margin = raw_width - (width = 5536);
9034 if (raw_width != 5600)
9035 left_margin = top_margin = 0;
9036 filters = 0x61616161;
9038 } else if (!strcmp(make,"Samsung") && raw_width == 5632) {
9042 width = 5574 - (left_margin = 32 + tiff_bps);
9043 if (tiff_bps == 12) load_flags = 80;
9044 } else if (!strcmp(make,"Samsung") && raw_width == 5664) {
9045 height -= top_margin = 17;
9048 filters = 0x49494949;
9049 } else if (!strcmp(make,"Samsung") && raw_width == 6496) {
9050 filters = 0x61616161;
9051 black = 1 << (tiff_bps - 7);
9052 } else if (!strcmp(model,"EX1")) {
9056 if ((width -= 6) > 3682) {
9061 } else if (!strcmp(model,"WB2000")) {
9065 if ((width -= 10) > 3718) {
9070 } else if (strstr(model,"WB550")) {
9071 strcpy (model, "WB550");
9072 } else if (!strcmp(model,"EX2F")) {
9077 filters = 0x49494949;
9078 load_raw = &CLASS unpacked_load_raw;
9079 } else if (!strcmp(model,"STV680 VGA")) {
9081 } else if (!strcmp(model,"N95")) {
9082 height = raw_height - (top_margin = 2);
9083 } else if (!strcmp(model,"640x480")) {
9084 gamma_curve (0.45, 4.5, 1, 255);
9085 } else if (!strcmp(make,"Hasselblad")) {
9086 if (load_raw == &CLASS lossless_jpeg_load_raw)
9087 load_raw = &CLASS hasselblad_load_raw;
9088 if (raw_width == 7262) {
9093 filters = 0x61616161;
9094 } else if (raw_width == 7410 || raw_width == 8282) {
9099 filters = 0x61616161;
9100 } else if (raw_width == 9044) {
9105 black += load_flags = 256;
9107 } else if (raw_width == 4090) {
9108 strcpy (model, "V96C");
9109 height -= (top_margin = 6);
9110 width -= (left_margin = 3) + 7;
9111 filters = 0x61616161;
9113 if (tiff_samples > 1) {
9114 is_raw = tiff_samples+1;
9115 if (!shot_select && !half_size) filters = 0;
9117 } else if (!strcmp(make,"Sinar")) {
9118 if (!load_raw) load_raw = &CLASS unpacked_load_raw;
9119 if (is_raw > 1 && !shot_select && !half_size) filters = 0;
9121 } else if (!strcmp(make,"Leaf")) {
9123 fseek (ifp, data_offset, SEEK_SET);
9124 if (ljpeg_start (&jh, 1) && jh.bits == 15)
9126 if (tiff_samples > 1) filters = 0;
9127 if (tiff_samples > 1 || tile_length < raw_height) {
9128 load_raw = &CLASS leaf_hdr_load_raw;
9129 raw_width = tile_width;
9131 if ((width | height) == 2048) {
9132 if (tiff_samples == 1) {
9134 strcpy (cdesc, "RBTG");
9135 strcpy (model, "CatchLight");
9136 top_margin = 8; left_margin = 18; height = 2032; width = 2016;
9138 strcpy (model, "DCB2");
9139 top_margin = 10; left_margin = 16; height = 2028; width = 2022;
9141 } else if (width+height == 3144+2060) {
9142 if (!model[0]) strcpy (model, "Cantare");
9143 if (width > height) {
9144 top_margin = 6; left_margin = 32; height = 2048; width = 3072;
9145 filters = 0x61616161;
9147 left_margin = 6; top_margin = 32; width = 2048; height = 3072;
9148 filters = 0x16161616;
9150 if (!cam_mul[0] || model[0] == 'V') filters = 0;
9151 else is_raw = tiff_samples;
9152 } else if (width == 2116) {
9153 strcpy (model, "Valeo 6");
9154 height -= 2 * (top_margin = 30);
9155 width -= 2 * (left_margin = 55);
9156 filters = 0x49494949;
9157 } else if (width == 3171) {
9158 strcpy (model, "Valeo 6");
9159 height -= 2 * (top_margin = 24);
9160 width -= 2 * (left_margin = 24);
9161 filters = 0x16161616;
9163 } else if (!strcmp(make,"Leica") || !strcmp(make,"Panasonic")) {
9164 if ((flen - data_offset) / (raw_width*8/7) == raw_height)
9165 load_raw = &CLASS panasonic_load_raw;
9167 load_raw = &CLASS unpacked_load_raw;
9171 if ((height += 12) > raw_height) height = raw_height;
9172 for (i=0; i < sizeof pana / sizeof *pana; i++)
9173 if (raw_width == pana[i][0] && raw_height == pana[i][1]) {
9174 left_margin = pana[i][2];
9175 top_margin = pana[i][3];
9176 width += pana[i][4];
9177 height += pana[i][5];
9179 filters = 0x01010101 * (uchar) "\x94\x61\x49\x16"
9180 [((filters-1) ^ (left_margin & 1) ^ (top_margin << 1)) & 3];
9181 } else if (!strcmp(model,"C770UZ")) {
9184 filters = 0x16161616;
9185 load_raw = &CLASS packed_load_raw;
9187 } else if (!strcmp(make,"Olympus")) {
9188 height += height & 1;
9189 if (exif_cfa) filters = exif_cfa;
9190 if (width == 4100) width -= 4;
9191 if (width == 4080) width -= 24;
9192 if (width == 9280) { width -= 6; height -= 6; }
9193 if (load_raw == &CLASS unpacked_load_raw)
9196 if (!strcmp(model,"E-300") ||
9197 !strcmp(model,"E-500")) {
9199 if (load_raw == &CLASS unpacked_load_raw) {
9201 memset (cblack, 0, sizeof cblack);
9203 } else if (!strcmp(model,"E-330")) {
9205 if (load_raw == &CLASS unpacked_load_raw)
9207 } else if (!strcmp(model,"SP550UZ")) {
9208 thumb_length = flen - (thumb_offset = 0xa39800);
9211 } else if (!strcmp(model,"TG-4")) {
9214 } else if (!strcmp(model,"N Digital")) {
9217 filters = 0x61616161;
9218 data_offset = 0x1a00;
9219 load_raw = &CLASS packed_load_raw;
9220 } else if (!strcmp(model,"DSC-F828")) {
9224 data_offset = 862144;
9225 load_raw = &CLASS sony_load_raw;
9226 filters = 0x9c9c9c9c;
9228 strcpy (cdesc, "RGBE");
9229 } else if (!strcmp(model,"DSC-V3")) {
9233 data_offset = 787392;
9234 load_raw = &CLASS sony_load_raw;
9235 } else if (!strcmp(make,"Sony") && raw_width == 3984) {
9238 } else if (!strcmp(make,"Sony") && raw_width == 4288) {
9240 } else if (!strcmp(make,"Sony") && raw_width == 4600) {
9241 if (!strcmp(model,"DSLR-A350"))
9244 } else if (!strcmp(make,"Sony") && raw_width == 4928) {
9245 if (height < 3280) width -= 8;
9246 } else if (!strcmp(make,"Sony") && raw_width == 5504) {
9247 width -= height > 3664 ? 8 : 32;
9248 if (!strncmp(model,"DSC",3))
9249 black = 200 << (tiff_bps - 12);
9250 } else if (!strcmp(make,"Sony") && raw_width == 6048) {
9252 if (strstr(model,"RX1") || strstr(model,"A99"))
9254 } else if (!strcmp(make,"Sony") && raw_width == 7392) {
9256 } else if (!strcmp(make,"Sony") && raw_width == 8000) {
9258 if (!strncmp(model,"DSC",3)) {
9260 load_raw = &CLASS unpacked_load_raw;
9263 } else if (!strcmp(model,"DSLR-A100")) {
9264 if (width == 3880) {
9266 width = ++raw_width;
9273 filters = 0x61616161;
9274 } else if (!strcmp(model,"PIXL")) {
9275 height -= top_margin = 4;
9276 width -= left_margin = 32;
9277 gamma_curve (0, 7, 1, 255);
9278 } else if (!strcmp(model,"C603") || !strcmp(model,"C330")
9279 || !strcmp(model,"12MP")) {
9281 if (filters && data_offset) {
9282 fseek (ifp, data_offset < 4096 ? 168 : 5252, SEEK_SET);
9283 read_shorts (curve, 256);
9284 } else gamma_curve (0, 3.875, 1, 255);
9285 load_raw = filters ? &CLASS eight_bit_load_raw :
9286 strcmp(model,"C330") ? &CLASS kodak_c603_load_raw :
9287 &CLASS kodak_c330_load_raw;
9288 load_flags = tiff_bps > 16;
9290 } else if (!strncasecmp(model,"EasyShare",9)) {
9291 data_offset = data_offset < 0x15000 ? 0x15000 : 0x17000;
9292 load_raw = &CLASS packed_load_raw;
9293 } else if (!strcasecmp(make,"Kodak")) {
9294 if (filters == UINT_MAX) filters = 0x61616161;
9295 if (!strncmp(model,"NC2000",6) ||
9296 !strncmp(model,"EOSDCS",6) ||
9297 !strncmp(model,"DCS4",4)) {
9300 if (model[6] == ' ') model[6] = 0;
9301 if (!strcmp(model,"DCS460A")) goto bw;
9302 } else if (!strcmp(model,"DCS660M")) {
9305 } else if (!strcmp(model,"DCS760M")) {
9309 if (!strcmp(model+4,"20X"))
9310 strcpy (cdesc, "MYCY");
9311 if (strstr(model,"DC25")) {
9312 strcpy (model, "DC25");
9313 data_offset = 15424;
9315 if (!strncmp(model,"DC2",3)) {
9316 raw_height = 2 + (height = 242);
9317 if (flen < 100000) {
9318 raw_width = 256; width = 249;
9319 pixel_aspect = (4.0*height) / (3.0*width);
9321 raw_width = 512; width = 501;
9322 pixel_aspect = (493.0*height) / (373.0*width);
9324 top_margin = left_margin = 1;
9326 filters = 0x8d8d8d8d;
9331 load_raw = &CLASS eight_bit_load_raw;
9332 } else if (!strcmp(model,"40")) {
9333 strcpy (model, "DC40");
9337 load_raw = &CLASS kodak_radc_load_raw;
9339 } else if (strstr(model,"DC50")) {
9340 strcpy (model, "DC50");
9343 data_offset = 19712;
9344 load_raw = &CLASS kodak_radc_load_raw;
9345 } else if (strstr(model,"DC120")) {
9346 strcpy (model, "DC120");
9349 pixel_aspect = height/0.75/width;
9350 load_raw = tiff_compress == 7 ?
9351 &CLASS kodak_jpeg_load_raw : &CLASS kodak_dc120_load_raw;
9352 } else if (!strcmp(model,"DCS200")) {
9355 thumb_offset = 6144;
9357 write_thumb = &CLASS layer_thumb;
9360 } else if (!strcmp(model,"Fotoman Pixtura")) {
9364 load_raw = &CLASS kodak_radc_load_raw;
9365 filters = 0x61616161;
9367 } else if (!strncmp(model,"QuickTake",9)) {
9368 if (head[5]) strcpy (model+10, "200");
9369 fseek (ifp, 544, SEEK_SET);
9372 data_offset = (get4(),get2()) == 30 ? 738:736;
9373 if (height > width) {
9375 fseek (ifp, data_offset-6, SEEK_SET);
9376 flip = ~get2() & 3 ? 5:6;
9378 filters = 0x61616161;
9379 } else if (!strcmp(make,"Rollei") && !load_raw) {
9380 switch (raw_width) {
9393 filters = 0x16161616;
9394 load_raw = &CLASS rollei_load_raw;
9397 sprintf (model, "%dx%d", width, height);
9398 if (filters == UINT_MAX) filters = 0x94949494;
9399 if (thumb_offset && !thumb_height) {
9400 fseek (ifp, thumb_offset, SEEK_SET);
9401 if (ljpeg_start (&jh, 1)) {
9402 thumb_width = jh.wide;
9403 thumb_height = jh.high;
9407 if ((use_camera_matrix & (use_camera_wb || dng_version))
9408 && cmatrix[0][0] > 0.125) {
9409 memcpy (rgb_cam, cmatrix, sizeof cmatrix);
9412 if (raw_color) adobe_coeff (make, model);
9413 if (load_raw == &CLASS kodak_radc_load_raw)
9414 if (raw_color) adobe_coeff ("Apple","Quicktake");
9416 fuji_width = width >> !fuji_layout;
9417 filters = fuji_width & 1 ? 0x94949494 : 0x49494949;
9418 width = (height >> fuji_layout) + fuji_width;
9422 if (raw_height < height) raw_height = height;
9423 if (raw_width < width ) raw_width = width;
9425 if (!tiff_bps) tiff_bps = 12;
9426 if (!maximum) maximum = (1 << tiff_bps) - 1;
9427 if (!load_raw || height < 22 || width < 22 ||
9428 tiff_bps > 16 || tiff_samples > 6 || colors > 4)
9431 if (load_raw == &CLASS redcine_load_raw) {
9432 fprintf (stderr,_("%s: You must link dcraw with %s!!\n"),
9433 ifname, "libjasper");
9438 if (load_raw == &CLASS kodak_jpeg_load_raw ||
9439 load_raw == &CLASS lossy_dng_load_raw) {
9440 fprintf (stderr,_("%s: You must link dcraw with %s!!\n"),
9446 strcpy (cdesc, colors == 3 ? "RGBG":"GMCY");
9447 if (!raw_height) raw_height = height;
9448 if (!raw_width ) raw_width = width;
9449 if (filters > 999 && colors == 3)
9450 filters |= ((filters >> 2 & 0x22222222) |
9451 (filters << 2 & 0x88888888)) & filters << 1;
9453 if (flip == UINT_MAX) flip = tiff_flip;
9454 if (flip == UINT_MAX) flip = 0;
9458 sprintf(dcraw_info, "%d %d", height, width);
9460 sprintf(dcraw_info, "%d %d", width, height);
9464 void CLASS apply_profile (const char *input, const char *output)
9467 cmsHPROFILE hInProfile=0, hOutProfile=0;
9468 cmsHTRANSFORM hTransform;
9472 if (strcmp (input, "embed"))
9473 hInProfile = cmsOpenProfileFromFile (input, "r");
9474 else if (profile_length) {
9475 prof = (char *) malloc (profile_length);
9476 merror (prof, "apply_profile()");
9477 fseek (ifp, profile_offset, SEEK_SET);
9478 fread (prof, 1, profile_length, ifp);
9479 hInProfile = cmsOpenProfileFromMem (prof, profile_length);
9482 fprintf (stderr,_("%s has no embedded profile.\n"), ifname);
9483 if (!hInProfile) return;
9485 hOutProfile = cmsCreate_sRGBProfile();
9486 else if ((fp = fopen (output, "rb"))) {
9487 fread (&size, 4, 1, fp);
9488 fseek (fp, 0, SEEK_SET);
9489 oprof = (unsigned *) malloc (size = ntohl(size));
9490 merror (oprof, "apply_profile()");
9491 fread (oprof, 1, size, fp);
9493 if (!(hOutProfile = cmsOpenProfileFromMem (oprof, size))) {
9498 fprintf (stderr,_("Cannot open file %s!\n"), output);
9499 if (!hOutProfile) goto quit;
9501 fprintf (stderr,_("Applying color profile...\n"));
9502 hTransform = cmsCreateTransform (hInProfile, TYPE_RGBA_16,
9503 hOutProfile, TYPE_RGBA_16, INTENT_PERCEPTUAL, 0);
9504 cmsDoTransform (hTransform, image, image, width*height);
9505 raw_color = 1; /* Don't use rgb_cam with a profile */
9506 cmsDeleteTransform (hTransform);
9507 cmsCloseProfile (hOutProfile);
9509 cmsCloseProfile (hInProfile);
9513 void CLASS convert_to_rgb()
9515 int row, col, c, i, j, k;
9517 float out[3], out_cam[3][4];
9518 double num, inverse[3][3];
9519 static const double xyzd50_srgb[3][3] =
9520 { { 0.436083, 0.385083, 0.143055 },
9521 { 0.222507, 0.716888, 0.060608 },
9522 { 0.013930, 0.097097, 0.714022 } };
9523 static const double rgb_rgb[3][3] =
9524 { { 1,0,0 }, { 0,1,0 }, { 0,0,1 } };
9525 static const double adobe_rgb[3][3] =
9526 { { 0.715146, 0.284856, 0.000000 },
9527 { 0.000000, 1.000000, 0.000000 },
9528 { 0.000000, 0.041166, 0.958839 } };
9529 static const double wide_rgb[3][3] =
9530 { { 0.593087, 0.404710, 0.002206 },
9531 { 0.095413, 0.843149, 0.061439 },
9532 { 0.011621, 0.069091, 0.919288 } };
9533 static const double prophoto_rgb[3][3] =
9534 { { 0.529317, 0.330092, 0.140588 },
9535 { 0.098368, 0.873465, 0.028169 },
9536 { 0.016879, 0.117663, 0.865457 } };
9537 static const double aces_rgb[3][3] =
9538 { { 0.432996, 0.375380, 0.189317 },
9539 { 0.089427, 0.816523, 0.102989 },
9540 { 0.019165, 0.118150, 0.941914 } };
9541 static const double (*out_rgb[])[3] =
9542 { rgb_rgb, adobe_rgb, wide_rgb, prophoto_rgb, xyz_rgb, aces_rgb };
9543 static const char *name[] =
9544 { "sRGB", "Adobe RGB (1998)", "WideGamut D65", "ProPhoto D65", "XYZ", "ACES" };
9545 static const unsigned phead[] =
9546 { 1024, 0, 0x2100000, 0x6d6e7472, 0x52474220, 0x58595a20, 0, 0, 0,
9547 0x61637370, 0, 0, 0x6e6f6e65, 0, 0, 0, 0, 0xf6d6, 0x10000, 0xd32d };
9549 { 10, 0x63707274, 0, 36, /* cprt */
9550 0x64657363, 0, 40, /* desc */
9551 0x77747074, 0, 20, /* wtpt */
9552 0x626b7074, 0, 20, /* bkpt */
9553 0x72545243, 0, 14, /* rTRC */
9554 0x67545243, 0, 14, /* gTRC */
9555 0x62545243, 0, 14, /* bTRC */
9556 0x7258595a, 0, 20, /* rXYZ */
9557 0x6758595a, 0, 20, /* gXYZ */
9558 0x6258595a, 0, 20 }; /* bXYZ */
9559 static const unsigned pwhite[] = { 0xf351, 0x10000, 0x116cc };
9560 unsigned pcurve[] = { 0x63757276, 0, 1, 0x1000000 };
9562 gamma_curve (gamm[0], gamm[1], 0, 0);
9563 memcpy (out_cam, rgb_cam, sizeof out_cam);
9564 raw_color |= colors == 1 || document_mode ||
9565 output_color < 1 || output_color > 6;
9567 oprof = (unsigned *) calloc (phead[0], 1);
9568 merror (oprof, "convert_to_rgb()");
9569 memcpy (oprof, phead, sizeof phead);
9570 if (output_color == 5) oprof[4] = oprof[5];
9571 oprof[0] = 132 + 12*pbody[0];
9572 for (i=0; i < pbody[0]; i++) {
9573 oprof[oprof[0]/4] = i ? (i > 1 ? 0x58595a20 : 0x64657363) : 0x74657874;
9574 pbody[i*3+2] = oprof[0];
9575 oprof[0] += (pbody[i*3+3] + 3) & -4;
9577 memcpy (oprof+32, pbody, sizeof pbody);
9578 oprof[pbody[5]/4+2] = strlen(name[output_color-1]) + 1;
9579 memcpy ((char *)oprof+pbody[8]+8, pwhite, sizeof pwhite);
9580 pcurve[3] = (short)(256/gamm[5]+0.5) << 16;
9581 for (i=4; i < 7; i++)
9582 memcpy ((char *)oprof+pbody[i*3+2], pcurve, sizeof pcurve);
9583 pseudoinverse ((double (*)[3]) out_rgb[output_color-1], inverse, 3);
9584 for (i=0; i < 3; i++)
9585 for (j=0; j < 3; j++) {
9586 for (num = k=0; k < 3; k++)
9587 num += xyzd50_srgb[i][k] * inverse[j][k];
9588 oprof[pbody[j*3+23]/4+i+2] = num * 0x10000 + 0.5;
9590 for (i=0; i < phead[0]/4; i++)
9591 oprof[i] = htonl(oprof[i]);
9592 strcpy ((char *)oprof+pbody[2]+8, "auto-generated by dcraw");
9593 strcpy ((char *)oprof+pbody[5]+12, name[output_color-1]);
9594 for (i=0; i < 3; i++)
9595 for (j=0; j < colors; j++)
9596 for (out_cam[i][j] = k=0; k < 3; k++)
9597 out_cam[i][j] += out_rgb[output_color-1][i][k] * rgb_cam[k][j];
9600 fprintf (stderr, raw_color ? _("Building histograms...\n") :
9601 _("Converting to %s colorspace...\n"), name[output_color-1]);
9603 memset (histogram, 0, sizeof histogram);
9604 for (img=image[0], row=0; row < height; row++)
9605 for (col=0; col < width; col++, img+=4) {
9607 out[0] = out[1] = out[2] = 0;
9609 out[0] += out_cam[0][c] * img[c];
9610 out[1] += out_cam[1][c] * img[c];
9611 out[2] += out_cam[2][c] * img[c];
9613 FORC3 img[c] = CLIP((int) out[c]);
9615 else if (document_mode)
9616 img[0] = img[fcol(row,col)];
9617 FORCC histogram[c][img[c] >> 3]++;
9619 if (colors == 4 && output_color) colors = 3;
9620 if (document_mode && filters) colors = 1;
9623 // Export color matrix to Cinelerra.
9624 // It can't be applied before interpolation.
9626 for(i = 0; i < 3; i++) {
9627 for(j = 0; j < 3; j++)
9628 dcraw_matrix[k++] = rgb_cam[i][j];
9633 void CLASS fuji_rotate()
9639 ushort wide, high, (*img)[4], (*pix)[4];
9641 if (!fuji_width) return;
9643 fprintf (stderr,_("Rotating image 45 degrees...\n"));
9644 fuji_width = (fuji_width - 1 + shrink) >> shrink;
9646 wide = fuji_width / step;
9647 high = (height - fuji_width) / step;
9648 img = (ushort (*)[4]) calloc (high, wide*sizeof *img);
9649 merror (img, "fuji_rotate()");
9651 for (row=0; row < high; row++)
9652 for (col=0; col < wide; col++) {
9653 ur = r = fuji_width + (row-col)*step;
9654 uc = c = (row+col)*step;
9655 if (ur > height-2 || uc > width-2) continue;
9658 pix = image + ur*width + uc;
9659 for (i=0; i < colors; i++)
9660 img[row*wide+col][i] =
9661 (pix[ 0][i]*(1-fc) + pix[ 1][i]*fc) * (1-fr) +
9662 (pix[width][i]*(1-fc) + pix[width+1][i]*fc) * fr;
9671 void CLASS stretch()
9673 ushort newdim, (*img)[4], *pix0, *pix1;
9677 if (pixel_aspect == 1) return;
9678 if (verbose) fprintf (stderr,_("Stretching the image...\n"));
9679 if (pixel_aspect < 1) {
9680 newdim = height / pixel_aspect + 0.5;
9681 img = (ushort (*)[4]) calloc (width, newdim*sizeof *img);
9682 merror (img, "stretch()");
9683 for (rc=row=0; row < newdim; row++, rc+=pixel_aspect) {
9684 frac = rc - (c = rc);
9685 pix0 = pix1 = image[c*width];
9686 if (c+1 < height) pix1 += width*4;
9687 for (col=0; col < width; col++, pix0+=4, pix1+=4)
9688 FORCC img[row*width+col][c] = pix0[c]*(1-frac) + pix1[c]*frac + 0.5;
9692 newdim = width * pixel_aspect + 0.5;
9693 img = (ushort (*)[4]) calloc (height, newdim*sizeof *img);
9694 merror (img, "stretch()");
9695 for (rc=col=0; col < newdim; col++, rc+=1/pixel_aspect) {
9696 frac = rc - (c = rc);
9697 pix0 = pix1 = image[c];
9698 if (c+1 < width) pix1 += 4;
9699 for (row=0; row < height; row++, pix0+=width*4, pix1+=width*4)
9700 FORCC img[row*newdim+col][c] = pix0[c]*(1-frac) + pix1[c]*frac + 0.5;
9708 int CLASS flip_index (int row, int col)
9710 if (flip & 4) SWAP(row,col);
9711 if (flip & 2) row = iheight - 1 - row;
9712 if (flip & 1) col = iwidth - 1 - col;
9713 return row * iwidth + col;
9719 union { char c[4]; short s[2]; int i; } val;
9723 ushort order, magic;
9726 struct tiff_tag tag[23];
9729 struct tiff_tag exif[4];
9731 struct tiff_tag gpst[10];
9735 char desc[512], make[64], model[64], soft[32], date[20], artist[64];
9738 void CLASS tiff_set (struct tiff_hdr *th, ushort *ntag,
9739 ushort tag, ushort type, int count, int val)
9741 struct tiff_tag *tt;
9744 tt = (struct tiff_tag *)(ntag+1) + (*ntag)++;
9746 if (type == 1 && count <= 4)
9747 FORC(4) tt->val.c[c] = val >> (c << 3);
9748 else if (type == 2) {
9749 count = strnlen((char *)th + val, count-1) + 1;
9751 FORC(4) tt->val.c[c] = ((char *)th)[val+c];
9752 } else if (type == 3 && count <= 2)
9753 FORC(2) tt->val.s[c] = val >> (c << 4);
9759 #define TOFF(ptr) ((char *)(&(ptr)) - (char *)th)
9761 void CLASS tiff_head (struct tiff_hdr *th, int full)
9766 memset (th, 0, sizeof *th);
9767 th->order = htonl(0x4d4d4949) >> 16;
9770 th->rat[0] = th->rat[2] = 300;
9771 th->rat[1] = th->rat[3] = 1;
9772 FORC(6) th->rat[4+c] = 1000000;
9773 th->rat[4] *= shutter;
9774 th->rat[6] *= aperture;
9775 th->rat[8] *= focal_len;
9776 strncpy (th->desc, desc, 512);
9777 strncpy (th->make, make, 64);
9778 strncpy (th->model, model, 64);
9779 strcpy (th->soft, "dcraw v"DCRAW_VERSION);
9780 t = localtime (×tamp);
9781 sprintf (th->date, "%04d:%02d:%02d %02d:%02d:%02d",
9782 t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);
9783 strncpy (th->artist, artist, 64);
9785 tiff_set (th, &th->ntag, 254, 4, 1, 0);
9786 tiff_set (th, &th->ntag, 256, 4, 1, width);
9787 tiff_set (th, &th->ntag, 257, 4, 1, height);
9788 tiff_set (th, &th->ntag, 258, 3, colors, output_bps);
9790 th->tag[th->ntag-1].val.i = TOFF(th->bps);
9791 FORC4 th->bps[c] = output_bps;
9792 tiff_set (th, &th->ntag, 259, 3, 1, 1);
9793 tiff_set (th, &th->ntag, 262, 3, 1, 1 + (colors > 1));
9795 tiff_set (th, &th->ntag, 270, 2, 512, TOFF(th->desc));
9796 tiff_set (th, &th->ntag, 271, 2, 64, TOFF(th->make));
9797 tiff_set (th, &th->ntag, 272, 2, 64, TOFF(th->model));
9799 if (oprof) psize = ntohl(oprof[0]);
9800 tiff_set (th, &th->ntag, 273, 4, 1, sizeof *th + psize);
9801 tiff_set (th, &th->ntag, 277, 3, 1, colors);
9802 tiff_set (th, &th->ntag, 278, 4, 1, height);
9803 tiff_set (th, &th->ntag, 279, 4, 1, height*width*colors*output_bps/8);
9805 tiff_set (th, &th->ntag, 274, 3, 1, "12435867"[flip]-'0');
9806 tiff_set (th, &th->ntag, 282, 5, 1, TOFF(th->rat[0]));
9807 tiff_set (th, &th->ntag, 283, 5, 1, TOFF(th->rat[2]));
9808 tiff_set (th, &th->ntag, 284, 3, 1, 1);
9809 tiff_set (th, &th->ntag, 296, 3, 1, 2);
9810 tiff_set (th, &th->ntag, 305, 2, 32, TOFF(th->soft));
9811 tiff_set (th, &th->ntag, 306, 2, 20, TOFF(th->date));
9812 tiff_set (th, &th->ntag, 315, 2, 64, TOFF(th->artist));
9813 tiff_set (th, &th->ntag, 34665, 4, 1, TOFF(th->nexif));
9814 if (psize) tiff_set (th, &th->ntag, 34675, 7, psize, sizeof *th);
9815 tiff_set (th, &th->nexif, 33434, 5, 1, TOFF(th->rat[4]));
9816 tiff_set (th, &th->nexif, 33437, 5, 1, TOFF(th->rat[6]));
9817 tiff_set (th, &th->nexif, 34855, 3, 1, iso_speed);
9818 tiff_set (th, &th->nexif, 37386, 5, 1, TOFF(th->rat[8]));
9820 tiff_set (th, &th->ntag, 34853, 4, 1, TOFF(th->ngps));
9821 tiff_set (th, &th->ngps, 0, 1, 4, 0x202);
9822 tiff_set (th, &th->ngps, 1, 2, 2, gpsdata[29]);
9823 tiff_set (th, &th->ngps, 2, 5, 3, TOFF(th->gps[0]));
9824 tiff_set (th, &th->ngps, 3, 2, 2, gpsdata[30]);
9825 tiff_set (th, &th->ngps, 4, 5, 3, TOFF(th->gps[6]));
9826 tiff_set (th, &th->ngps, 5, 1, 1, gpsdata[31]);
9827 tiff_set (th, &th->ngps, 6, 5, 1, TOFF(th->gps[18]));
9828 tiff_set (th, &th->ngps, 7, 5, 3, TOFF(th->gps[12]));
9829 tiff_set (th, &th->ngps, 18, 2, 12, TOFF(th->gps[20]));
9830 tiff_set (th, &th->ngps, 29, 2, 12, TOFF(th->gps[23]));
9831 memcpy (th->gps, gpsdata, sizeof th->gps);
9835 void CLASS jpeg_thumb()
9841 thumb = (char *) malloc (thumb_length);
9842 merror (thumb, "jpeg_thumb()");
9843 fread (thumb, 1, thumb_length, ifp);
9846 if (strcmp (thumb+6, "Exif")) {
9847 memcpy (exif, "\xff\xe1 Exif\0\0", 10);
9848 exif[1] = htons (8 + sizeof th);
9849 fwrite (exif, 1, sizeof exif, ofp);
9851 fwrite (&th, 1, sizeof th, ofp);
9853 fwrite (thumb+2, 1, thumb_length-2, ofp);
9857 void CLASS write_ppm_tiff()
9862 int c, row, col, soff, rstep, cstep;
9863 int perc, val, total, white=0x2000;
9865 perc = width * height * 0.01; /* 99th percentile white level */
9866 if (fuji_width) perc /= 2;
9867 if (!((highlight & ~2) || no_auto_bright))
9868 for (white=c=0; c < colors; c++) {
9869 for (val=0x2000, total=0; --val > 32; )
9870 if ((total += histogram[c][val]) > perc) break;
9871 if (white < val) white = val;
9873 gamma_curve (gamm[0], gamm[1], 2, (white << 3)/bright);
9876 if (flip & 4) SWAP(height,width);
9877 ppm = (uchar *) calloc (width, colors*output_bps/8);
9878 ppm2 = (ushort *) ppm;
9879 merror (ppm, "write_ppm_tiff()");
9882 fwrite (&th, sizeof th, 1, ofp);
9884 fwrite (oprof, ntohl(oprof[0]), 1, ofp);
9885 } else if (colors > 3)
9887 "P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLTYPE %s\nENDHDR\n",
9888 width, height, colors, (1 << output_bps)-1, cdesc);
9890 fprintf (ofp, "P%d\n%d %d\n%d\n",
9891 colors/2+5, width, height, (1 << output_bps)-1);
9892 soff = flip_index (0, 0);
9893 cstep = flip_index (0, 1) - soff;
9894 rstep = flip_index (1, 0) - flip_index (0, width);
9895 for (row=0; row < height; row++, soff += rstep) {
9896 for (col=0; col < width; col++, soff += cstep)
9897 if (output_bps == 8)
9898 FORCC ppm [col*colors+c] = curve[image[soff][c]] >> 8;
9899 else FORCC ppm2[col*colors+c] = curve[image[soff][c]];
9900 if (output_bps == 16 && !output_tiff && htons(0x55aa) != 0x55aa)
9901 swab (ppm2, ppm2, width*colors*2);
9902 fwrite (ppm, colors*output_bps/8, width, ofp);
9908 void CLASS write_cinelerra (FILE *ofp)
9913 for (row = 0; row < height; row++)
9915 output = dcraw_data[row];
9919 for (col = 0; col < width; col++)
9921 ushort *pixel = image[row * width + col];
9923 *output++ = (float)pixel[0] / 0xffff;
9924 *output++ = (float)pixel[1] / 0xffff;
9925 *output++ = (float)pixel[2] / 0xffff;
9927 if(dcraw_alpha) *output++ = 1.0;
9932 for (col = 0; col < width; col++)
9934 ushort *pixel = image[row * width + col];
9936 *output++ = (float)pixel[0] / 0xffff;
9937 *output++ = (float)pixel[1] / 0xffff;
9938 *output++ = (float)pixel[2] / 0xffff;
9940 if(dcraw_alpha) *output++ = 1.0;
9947 int CLASS dcraw_main (int argc, const char **argv)
9949 int arg, status=0, quality, i, c;
9950 int timestamp_only=0, thumbnail_only=0, identify_only=0;
9951 int user_qual=-1, user_black=-1, user_sat=-1, user_flip=-1;
9952 int use_fuji_rotate=1, write_to_stdout=0, read_from_stdin=0;
9953 const char *sp, *bpfile=0, *dark_frame=0, *write_ext;
9954 char opm, opt, *ofname, *cp;
9957 const char *cam_profile=0, *out_profile=0;
9961 reset(); // Globals must be reset
9964 putenv ((char *) "TZ=UTC");
9967 setlocale (LC_CTYPE, "");
9968 setlocale (LC_MESSAGES, "");
9969 bindtextdomain ("dcraw", LOCALEDIR);
9970 textdomain ("dcraw");
9974 printf(_("\nRaw photo decoder \"dcraw\" v%s"), DCRAW_VERSION);
9975 printf(_("\nby Dave Coffin, dcoffin a cybercom o net\n"));
9976 printf(_("\nUsage: %s [OPTION]... [FILE]...\n\n"), argv[0]);
9977 puts(_("-v Print verbose messages"));
9978 puts(_("-c Write image data to standard output"));
9979 puts(_("-e Extract embedded thumbnail image"));
9980 puts(_("-i Identify files without decoding them"));
9981 puts(_("-i -v Identify files and show metadata"));
9982 puts(_("-z Change file dates to camera timestamp"));
9983 puts(_("-w Use camera white balance, if possible"));
9984 puts(_("-a Average the whole image for white balance"));
9985 puts(_("-A <x y w h> Average a grey box for white balance"));
9986 puts(_("-r <r g b g> Set custom white balance"));
9987 puts(_("+M/-M Use/don't use an embedded color matrix"));
9988 puts(_("-C <r b> Correct chromatic aberration"));
9989 puts(_("-P <file> Fix the dead pixels listed in this file"));
9990 puts(_("-K <file> Subtract dark frame (16-bit raw PGM)"));
9991 puts(_("-k <num> Set the darkness level"));
9992 puts(_("-S <num> Set the saturation level"));
9993 puts(_("-n <num> Set threshold for wavelet denoising"));
9994 puts(_("-H [0-9] Highlight mode (0=clip, 1=unclip, 2=blend, 3+=rebuild)"));
9995 puts(_("-t [0-7] Flip image (0=none, 3=180, 5=90CCW, 6=90CW)"));
9996 puts(_("-o [0-6] Output colorspace (raw,sRGB,Adobe,Wide,ProPhoto,XYZ,ACES)"));
9998 puts(_("-o <file> Apply output ICC profile from file"));
9999 puts(_("-p <file> Apply camera ICC profile from file or \"embed\""));
10001 puts(_("-d Document mode (no color, no interpolation)"));
10002 puts(_("-D Document mode without scaling (totally raw)"));
10003 puts(_("-j Don't stretch or rotate raw pixels"));
10004 puts(_("-W Don't automatically brighten the image"));
10005 puts(_("-b <num> Adjust brightness (default = 1.0)"));
10006 puts(_("-g <p ts> Set custom gamma curve (default = 2.222 4.5)"));
10007 puts(_("-q [0-3] Set the interpolation quality"));
10008 puts(_("-h Half-size color image (twice as fast as \"-q 0\")"));
10009 puts(_("-f Interpolate RGGB as four colors"));
10010 puts(_("-m <num> Apply a 3x3 median filter to R-G and B-G"));
10011 puts(_("-s [0..N-1] Select one raw image or \"all\" from each file"));
10012 puts(_("-6 Write 16-bit instead of 8-bit"));
10013 puts(_("-4 Linear 16-bit, same as \"-6 -W -g 1 1\""));
10014 puts(_("-T Write TIFF instead of PPM"));
10019 for (arg=1; (((opm = argv[arg][0]) - 2) | 2) == '+'; ) {
10020 opt = argv[arg++][1];
10021 if ((cp = (char *) strchr (sp="nbrkStqmHACg", opt)))
10022 for (i=0; i < "114111111422"[cp-sp]-'0'; i++)
10023 if (!isdigit(argv[arg+i][0])) {
10024 fprintf (stderr,_("Non-numeric argument to \"-%c\"\n"), opt);
10028 case 'n': threshold = atof(argv[arg++]); break;
10029 case 'b': bright = atof(argv[arg++]); break;
10031 FORC4 user_mul[c] = atof(argv[arg++]); break;
10032 case 'C': aber[0] = 1 / atof(argv[arg++]);
10033 aber[2] = 1 / atof(argv[arg++]); break;
10034 case 'g': gamm[0] = atof(argv[arg++]);
10035 gamm[1] = atof(argv[arg++]);
10036 if (gamm[0]) gamm[0] = 1/gamm[0]; break;
10037 case 'k': user_black = atoi(argv[arg++]); break;
10038 case 'S': user_sat = atoi(argv[arg++]); break;
10039 case 't': user_flip = atoi(argv[arg++]); break;
10040 case 'q': user_qual = atoi(argv[arg++]); break;
10041 case 'm': med_passes = atoi(argv[arg++]); break;
10042 case 'H': highlight = atoi(argv[arg++]); break;
10044 shot_select = abs(atoi(argv[arg]));
10045 multi_out = !strcmp(argv[arg++],"all");
10048 if (isdigit(argv[arg][0]) && !argv[arg][1])
10049 output_color = atoi(argv[arg++]);
10051 else out_profile = argv[arg++];
10053 case 'p': cam_profile = argv[arg++];
10056 case 'P': bpfile = argv[arg++]; break;
10057 case 'K': dark_frame = argv[arg++]; break;
10058 case 'z': timestamp_only = 1; break;
10059 case 'e': thumbnail_only = 1; break;
10060 case 'i': identify_only = 1; break;
10061 case 'c': write_to_stdout = 1; break;
10062 case 'v': verbose = 1; break;
10063 case 'h': half_size = 1; break;
10064 case 'f': four_color_rgb = 1; break;
10065 case 'A': FORC4 greybox[c] = atoi(argv[arg++]);
10066 case 'a': use_auto_wb = 1; break;
10067 case 'w': use_camera_wb = 1; break;
10068 case 'M': use_camera_matrix = 3 * (opm == '+'); break;
10069 case 'I': read_from_stdin = 1; break;
10070 case 'E': document_mode++;
10071 case 'D': document_mode++;
10072 case 'd': document_mode++;
10073 case 'j': use_fuji_rotate = 0; break;
10074 case 'W': no_auto_bright = 1; break;
10075 case 'T': output_tiff = 1; break;
10076 case '4': gamm[0] = gamm[1] =
10077 no_auto_bright = 1;
10078 case '6': output_bps = 16; break;
10080 fprintf (stderr,_("Unknown option \"-%c\".\n"), opt);
10085 fprintf (stderr,_("No files to process.\n"));
10088 if (write_to_stdout) {
10090 if (0 && isatty(1)) {
10091 fprintf (stderr,_("Will not write an image to the terminal!\n"));
10094 #if defined(WIN32) || defined(DJGPP) || defined(__CYGWIN__)
10095 if (setmode(1,O_BINARY) < 0) {
10096 perror ("setmode()");
10101 for ( ; arg < argc; arg++) {
10106 meta_data = ofname = 0;
10108 if (setjmp (failure)) {
10109 if (fileno(ifp) > 2) fclose(ifp);
10110 if (fileno(ofp) > 2) fclose(ofp);
10114 ifname = argv[arg];
10115 if (!(ifp = fopen (ifname, "rb"))) {
10119 status = (identify(),!is_raw);
10120 if (user_flip >= 0)
10122 switch ((flip+3600) % 360) {
10123 case 270: flip = 5; break;
10124 case 180: flip = 3; break;
10127 if (timestamp_only) {
10128 if ((status = !timestamp))
10129 fprintf (stderr,_("%s has no timestamp.\n"), ifname);
10130 else if (identify_only)
10131 printf ("%10ld%10d %s\n", (long) timestamp, shot_order, ifname);
10134 fprintf (stderr,_("%s time set to %d.\n"), ifname, (int) timestamp);
10135 ut.actime = ut.modtime = timestamp;
10136 utime (ifname, &ut);
10141 // write_fun = &CLASS write_ppm_tiff;
10142 write_fun = write_cinelerra;
10144 if (thumbnail_only) {
10145 if ((status = !thumb_offset)) {
10146 fprintf (stderr,_("%s has no thumbnail.\n"), ifname);
10148 } else if (thumb_load_raw) {
10149 load_raw = thumb_load_raw;
10150 data_offset = thumb_offset;
10151 height = thumb_height;
10152 width = thumb_width;
10156 fseek (ifp, thumb_offset, SEEK_SET);
10157 write_fun = write_thumb;
10161 if (load_raw == &CLASS kodak_ycbcr_load_raw) {
10162 height += height & 1;
10163 width += width & 1;
10165 if (identify_only && verbose && make[0]) {
10166 printf (_("\nFilename: %s\n"), ifname);
10167 printf (_("Timestamp: %s"), ctime(×tamp));
10168 printf (_("Camera: %s %s\n"), make, model);
10170 printf (_("Owner: %s\n"), artist);
10172 printf (_("DNG Version: "));
10173 for (i=24; i >= 0; i -= 8)
10174 printf ("%d%c", dng_version >> i & 255, i ? '.':'\n');
10176 printf (_("ISO speed: %d\n"), (int) iso_speed);
10177 printf (_("Shutter: "));
10178 if (shutter > 0 && shutter < 1)
10179 shutter = (printf ("1/"), 1 / shutter);
10180 printf (_("%0.1f sec\n"), shutter);
10181 printf (_("Aperture: f/%0.1f\n"), aperture);
10182 printf (_("Focal length: %0.1f mm\n"), focal_len);
10183 printf (_("Embedded ICC profile: %s\n"), profile_length ? _("yes"):_("no"));
10184 printf (_("Number of raw images: %d\n"), is_raw);
10185 if (pixel_aspect != 1)
10186 printf (_("Pixel Aspect Ratio: %0.6f\n"), pixel_aspect);
10188 printf (_("Thumb size: %4d x %d\n"), thumb_width, thumb_height);
10189 printf (_("Full size: %4d x %d\n"), raw_width, raw_height);
10192 // else if (!is_raw)
10193 // fprintf (stderr,_("Cannot decode file %s\n"), ifname);
10194 if (!is_raw) goto next;
10195 shrink = filters && (half_size || (!identify_only &&
10196 (threshold || aber[0] != 1 || aber[2] != 1)));
10197 iheight = (height + shrink) >> shrink;
10198 iwidth = (width + shrink) >> shrink;
10199 if (identify_only) {
10201 if (document_mode == 3) {
10202 top_margin = left_margin = fuji_width = 0;
10203 height = raw_height;
10206 iheight = (height + shrink) >> shrink;
10207 iwidth = (width + shrink) >> shrink;
10208 if (use_fuji_rotate) {
10210 fuji_width = (fuji_width - 1 + shrink) >> shrink;
10211 iwidth = fuji_width / sqrt(0.5);
10212 iheight = (iheight - fuji_width) / sqrt(0.5);
10214 if (pixel_aspect < 1) iheight = iheight / pixel_aspect + 0.5;
10215 if (pixel_aspect > 1) iwidth = iwidth * pixel_aspect + 0.5;
10219 SWAP(iheight,iwidth);
10220 printf (_("Image size: %4d x %d\n"), width, height);
10221 printf (_("Output size: %4d x %d\n"), iwidth, iheight);
10222 printf (_("Raw colors: %d"), colors);
10224 int fhigh = 2, fwide = 2;
10225 if ((filters ^ (filters >> 8)) & 0xff) fhigh = 4;
10226 if ((filters ^ (filters >> 16)) & 0xffff) fhigh = 8;
10227 if (filters == 1) fhigh = fwide = 16;
10228 if (filters == 9) fhigh = fwide = 6;
10229 printf (_("\nFilter pattern: "));
10230 for (i=0; i < fhigh; i++)
10231 for (c = i && putchar('/') && 0; c < fwide; c++)
10232 putchar (cdesc[fcol(i,c)]);
10234 printf (_("\nDaylight multipliers:"));
10235 FORCC printf (" %f", pre_mul[c]);
10236 if (cam_mul[0] > 0) {
10237 printf (_("\nCamera multipliers:"));
10238 FORC4 printf (" %f", cam_mul[c]);
10244 // printf (_("%s is a %s %s image.\n"), ifname, make, model);
10250 meta_data = (char *) malloc (meta_length);
10251 merror (meta_data, "main()");
10253 if (filters || colors == 1) {
10254 raw_image = (ushort *) calloc ((raw_height+7), raw_width*2);
10255 merror (raw_image, "main()");
10257 image = (ushort (*)[4]) calloc (iheight, iwidth*sizeof *image);
10258 merror (image, "main()");
10261 fprintf (stderr,_("Loading %s %s image from %s ...\n"),
10262 make, model, ifname);
10263 if (shot_select >= is_raw)
10264 fprintf (stderr,_("%s: \"-s %d\" requests a nonexistent image!\n"),
10265 ifname, shot_select);
10266 fseeko (ifp, data_offset, SEEK_SET);
10267 if (raw_image && read_from_stdin)
10268 fread (raw_image, 2, raw_height*raw_width, stdin);
10269 else (*load_raw)();
10270 if (document_mode == 3) {
10271 top_margin = left_margin = fuji_width = 0;
10272 height = raw_height;
10275 iheight = (height + shrink) >> shrink;
10276 iwidth = (width + shrink) >> shrink;
10278 image = (ushort (*)[4]) calloc (iheight, iwidth*sizeof *image);
10279 merror (image, "main()");
10280 crop_masked_pixels();
10283 if (zero_is_bad) remove_zeroes();
10284 bad_pixels (bpfile);
10285 if (dark_frame) subtract (dark_frame);
10286 quality = 2 + !fuji_width;
10287 if (user_qual >= 0) quality = user_qual;
10289 FORC3 if (i > cblack[c]) i = cblack[c];
10290 FORC4 cblack[c] -= i;
10293 FORC (cblack[4] * cblack[5])
10294 if (i > cblack[6+c]) i = cblack[6+c];
10295 FORC (cblack[4] * cblack[5])
10298 if (user_black >= 0) black = user_black;
10299 FORC4 cblack[c] += black;
10300 if (user_sat > 0) maximum = user_sat;
10305 if (document_mode || load_raw == &CLASS foveon_dp_load_raw) {
10306 for (i=0; i < height*width*4; i++)
10307 if ((short) image[0][i] < 0) image[0][i] = 0;
10308 } else foveon_interpolate();
10309 } else if (document_mode < 2)
10312 if (filters && !document_mode) {
10315 else if (quality == 1 || colors > 3)
10317 else if (quality == 2 && filters > 1000)
10319 else if (filters == 9)
10320 xtrans_interpolate (quality*2-3);
10325 for (colors=3, i=0; i < height*width; i++)
10326 image[i][1] = (image[i][1] + image[i][3]) >> 1;
10327 if (!is_foveon && colors == 3) median_filter();
10328 if (!is_foveon && highlight == 2) blend_highlights();
10329 if (!is_foveon && highlight > 2) recover_highlights();
10330 if (use_fuji_rotate) fuji_rotate();
10332 if (cam_profile) apply_profile (cam_profile, out_profile);
10335 if (use_fuji_rotate) stretch();
10337 if (write_fun == &CLASS jpeg_thumb)
10338 write_ext = ".jpg";
10339 else if (output_tiff && write_fun == &CLASS write_ppm_tiff)
10340 write_ext = ".tiff";
10342 write_ext = ".pgm\0.ppm\0.ppm\0.pam" + colors*5-5;
10343 ofname = (char *) malloc (strlen(ifname) + 64);
10344 merror (ofname, "main()");
10345 if (write_to_stdout)
10346 strcpy (ofname,_("standard output"));
10348 strcpy (ofname, ifname);
10349 if ((cp = strrchr (ofname, '.'))) *cp = 0;
10351 sprintf (ofname+strlen(ofname), "_%0*d",
10352 snprintf(0,0,"%d",is_raw-1), shot_select);
10353 if (thumbnail_only)
10354 strcat (ofname, ".thumb");
10355 strcat (ofname, write_ext);
10356 ofp = fopen (ofname, "wb");
10364 fprintf (stderr,_("Writing data to %s ...\n"), ofname);
10367 if (ofp != stdout) fclose(ofp);
10369 if (meta_data) free (meta_data);
10370 if (ofname) free (ofname);
10371 if (oprof) free (oprof);
10372 if (image) free (image);
10374 if (++shot_select < is_raw) arg--;
10375 else shot_select = 0;