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 if (!name) return 0;
3330 dp = foveon_camf_matrix (dim, name);
3332 memcpy (ptr, dp, size*4);
3337 float CLASS foveon_avg (short *pix, int range[2], float cfilt)
3340 float val, min=FLT_MAX, max=-FLT_MAX, sum=0;
3342 for (i=range[0]; i <= range[1]; i++) {
3343 sum += val = pix[i*4] + (pix[i*4]-pix[(i-1)*4]) * cfilt;
3344 if (min > val) min = val;
3345 if (max < val) max = val;
3347 if (range[1] - range[0] == 1) return sum/2;
3348 return (sum - min - max) / (range[1] - range[0] - 1);
3351 short * CLASS foveon_make_curve (double max, double mul, double filt)
3357 if (!filt) filt = 0.8;
3358 size = 4*M_PI*max / filt;
3359 if (size == UINT_MAX) size--;
3360 curve = (short *) calloc (size+1, sizeof *curve);
3361 merror (curve, "foveon_make_curve()");
3363 for (i=0; i < size; i++) {
3365 curve[i+1] = (cos(x)+1)/2 * tanh(i*filt/mul) * mul + 0.5;
3370 void CLASS foveon_make_curves
3371 (short **curvep, float dq[3], float div[3], float filt)
3373 double mul[3], max=0;
3376 FORC3 mul[c] = dq[c]/div[c];
3377 FORC3 if (max < mul[c]) max = mul[c];
3378 FORC3 curvep[c] = foveon_make_curve (max, mul[c], filt);
3381 int CLASS foveon_apply_curve (short *curve, int i)
3383 if (abs(i) >= curve[0]) return 0;
3384 return i < 0 ? -curve[1-i] : curve[1+i];
3387 #define image ((short (*)[4]) image)
3389 void CLASS foveon_interpolate()
3391 static const short hood[] = { -1,-1, -1,0, -1,1, 0,-1, 0,1, 1,-1, 1,0, 1,1 };
3392 short *pix, prev[3], *curve[8], (*shrink)[3];
3393 float cfilt=0, ddft[3][3][2], ppm[3][3][3];
3394 float cam_xyz[3][3], correct[3][3], last[3][3], trans[3][3];
3395 float chroma_dq[3], color_dq[3], diag[3][3], div[3];
3396 float (*black)[3], (*sgain)[3], (*sgrow)[3];
3397 float fsum[3], val, frow, num;
3398 int row, col, c, i, j, diff, sgx, irow, sum, min, max, limit;
3399 int dscr[2][2], dstb[4], (*smrow[7])[3], total[4], ipix[3];
3400 int work[3][3], smlast, smred, smred_p=0, dev[3];
3401 int satlev[3], keep[4], active[4];
3402 unsigned dim[3], *badpix;
3403 double dsum=0, trsum[3];
3408 fprintf (stderr,_("Foveon interpolation...\n"));
3411 foveon_fixed (dscr, 4, "DarkShieldColRange");
3412 foveon_fixed (ppm[0][0], 27, "PostPolyMatrix");
3413 foveon_fixed (satlev, 3, "SaturationLevel");
3414 foveon_fixed (keep, 4, "KeepImageArea");
3415 foveon_fixed (active, 4, "ActiveImageArea");
3416 foveon_fixed (chroma_dq, 3, "ChromaDQ");
3417 foveon_fixed (color_dq, 3,
3418 foveon_camf_param ("IncludeBlocks", "ColorDQ") ?
3419 "ColorDQ" : "ColorDQCamRGB");
3420 if (foveon_camf_param ("IncludeBlocks", "ColumnFilter"))
3421 foveon_fixed (&cfilt, 1, "ColumnFilter");
3423 memset (ddft, 0, sizeof ddft);
3424 if (!foveon_camf_param ("IncludeBlocks", "DarkDrift")
3425 || !foveon_fixed (ddft[1][0], 12, "DarkDrift"))
3426 for (i=0; i < 2; i++) {
3427 foveon_fixed (dstb, 4, i ? "DarkShieldBottom":"DarkShieldTop");
3428 for (row = dstb[1]; row <= dstb[3]; row++)
3429 for (col = dstb[0]; col <= dstb[2]; col++)
3430 FORC3 ddft[i+1][c][1] += (short) image[row*width+col][c];
3431 FORC3 ddft[i+1][c][1] /= (dstb[3]-dstb[1]+1) * (dstb[2]-dstb[0]+1);
3434 if (!(cp = foveon_camf_param ("WhiteBalanceIlluminants", model2)))
3435 { fprintf (stderr,_("%s: Invalid white balance \"%s\"\n"), ifname, model2);
3437 foveon_fixed (cam_xyz, 9, cp);
3438 foveon_fixed (correct, 9,
3439 foveon_camf_param ("WhiteBalanceCorrections", model2));
3440 memset (last, 0, sizeof last);
3441 for (i=0; i < 3; i++)
3442 for (j=0; j < 3; j++)
3443 FORC3 last[i][j] += correct[i][c] * cam_xyz[c][j];
3445 #define LAST(x,y) last[(i+x)%3][(c+y)%3]
3446 for (i=0; i < 3; i++)
3447 FORC3 diag[c][i] = LAST(1,1)*LAST(2,2) - LAST(1,2)*LAST(2,1);
3449 FORC3 div[c] = diag[c][0]*0.3127 + diag[c][1]*0.329 + diag[c][2]*0.3583;
3450 sprintf (str, "%sRGBNeutral", model2);
3451 if (foveon_camf_param ("IncludeBlocks", str))
3452 foveon_fixed (div, 3, str);
3454 FORC3 if (num < div[c]) num = div[c];
3455 FORC3 div[c] /= num;
3457 memset (trans, 0, sizeof trans);
3458 for (i=0; i < 3; i++)
3459 for (j=0; j < 3; j++)
3460 FORC3 trans[i][j] += rgb_cam[i][c] * last[c][j] * div[j];
3461 FORC3 trsum[c] = trans[c][0] + trans[c][1] + trans[c][2];
3462 dsum = (6*trsum[0] + 11*trsum[1] + 3*trsum[2]) / 20;
3463 for (i=0; i < 3; i++)
3464 FORC3 last[i][c] = trans[i][c] * dsum / trsum[i];
3465 memset (trans, 0, sizeof trans);
3466 for (i=0; i < 3; i++)
3467 for (j=0; j < 3; j++)
3468 FORC3 trans[i][j] += (i==c ? 32 : -1) * last[c][j] / 30;
3470 foveon_make_curves (curve, color_dq, div, cfilt);
3471 FORC3 chroma_dq[c] /= 3;
3472 foveon_make_curves (curve+3, chroma_dq, div, cfilt);
3473 FORC3 dsum += chroma_dq[c] / div[c];
3474 curve[6] = foveon_make_curve (dsum, dsum, cfilt);
3475 curve[7] = foveon_make_curve (dsum*2, dsum*2, cfilt);
3477 sgain = (float (*)[3]) foveon_camf_matrix (dim, "SpatialGain");
3479 sgrow = (float (*)[3]) calloc (dim[1], sizeof *sgrow);
3480 sgx = (width + dim[1]-2) / (dim[1]-1);
3482 black = (float (*)[3]) calloc (height, sizeof *black);
3483 for (row=0; row < height; row++) {
3484 for (i=0; i < 6; i++)
3485 ((float *)ddft[0])[i] = ((float *)ddft[1])[i] +
3486 row / (height-1.0) * (((float *)ddft[2])[i] - ((float *)ddft[1])[i]);
3487 FORC3 black[row][c] =
3488 ( foveon_avg (image[row*width]+c, dscr[0], cfilt) +
3489 foveon_avg (image[row*width]+c, dscr[1], cfilt) * 3
3490 - ddft[0][c][0] ) / 4 - ddft[0][c][1];
3492 memcpy (black, black+8, sizeof *black*8);
3493 memcpy (black+height-11, black+height-22, 11*sizeof *black);
3494 memcpy (last, black, sizeof last);
3496 for (row=1; row < height-1; row++) {
3497 FORC3 if (last[1][c] > last[0][c]) {
3498 if (last[1][c] > last[2][c])
3499 black[row][c] = (last[0][c] > last[2][c]) ? last[0][c]:last[2][c];
3501 if (last[1][c] < last[2][c])
3502 black[row][c] = (last[0][c] < last[2][c]) ? last[0][c]:last[2][c];
3503 memmove (last, last+1, 2*sizeof last[0]);
3504 memcpy (last[2], black[row+1], sizeof last[2]);
3506 FORC3 black[row][c] = (last[0][c] + last[1][c])/2;
3507 FORC3 black[0][c] = (black[1][c] + black[3][c])/2;
3509 val = 1 - exp(-1/24.0);
3510 memcpy (fsum, black, sizeof fsum);
3511 for (row=1; row < height; row++)
3512 FORC3 fsum[c] += black[row][c] =
3513 (black[row][c] - black[row-1][c])*val + black[row-1][c];
3514 memcpy (last[0], black[height-1], sizeof last[0]);
3515 FORC3 fsum[c] /= height;
3516 for (row = height; row--; )
3517 FORC3 last[0][c] = black[row][c] =
3518 (black[row][c] - fsum[c] - last[0][c])*val + last[0][c];
3520 memset (total, 0, sizeof total);
3521 for (row=2; row < height; row+=4)
3522 for (col=2; col < width; col+=4) {
3523 FORC3 total[c] += (short) image[row*width+col][c];
3526 for (row=0; row < height; row++)
3527 FORC3 black[row][c] += fsum[c]/2 + total[c]/(total[3]*100.0);
3529 for (row=0; row < height; row++) {
3530 for (i=0; i < 6; i++)
3531 ((float *)ddft[0])[i] = ((float *)ddft[1])[i] +
3532 row / (height-1.0) * (((float *)ddft[2])[i] - ((float *)ddft[1])[i]);
3533 pix = image[row*width];
3534 memcpy (prev, pix, sizeof prev);
3535 frow = row / (height-1.0) * (dim[2]-1);
3536 if ((irow = frow) == dim[2]-1) irow--;
3538 for (i=0; i < dim[1]; i++)
3539 FORC3 sgrow[i][c] = sgain[ irow *dim[1]+i][c] * (1-frow) +
3540 sgain[(irow+1)*dim[1]+i][c] * frow;
3541 for (col=0; col < width; col++) {
3543 diff = pix[c] - prev[c];
3545 ipix[c] = pix[c] + floor ((diff + (diff*diff >> 14)) * cfilt
3546 - ddft[0][c][1] - ddft[0][c][0] * ((float) col/width - 0.5)
3550 work[0][c] = ipix[c] * ipix[c] >> 14;
3551 work[2][c] = ipix[c] * work[0][c] >> 14;
3552 work[1][2-c] = ipix[(c+1) % 3] * ipix[(c+2) % 3] >> 14;
3555 for (val=i=0; i < 3; i++)
3556 for ( j=0; j < 3; j++)
3557 val += ppm[c][i][j] * work[i][j];
3558 ipix[c] = floor ((ipix[c] + floor(val)) *
3559 ( sgrow[col/sgx ][c] * (sgx - col%sgx) +
3560 sgrow[col/sgx+1][c] * (col%sgx) ) / sgx / div[c]);
3561 if (ipix[c] > 32000) ipix[c] = 32000;
3571 if ((badpix = (unsigned *) foveon_camf_matrix (dim, "BadPixels"))) {
3572 for (i=0; i < dim[0]; i++) {
3573 col = (badpix[i] >> 8 & 0xfff) - keep[0];
3574 row = (badpix[i] >> 20 ) - keep[1];
3575 if ((unsigned)(row-1) > height-3 || (unsigned)(col-1) > width-3)
3577 memset (fsum, 0, sizeof fsum);
3578 for (sum=j=0; j < 8; j++)
3579 if (badpix[i] & (1 << j)) {
3580 FORC3 fsum[c] += (short)
3581 image[(row+hood[j*2])*width+col+hood[j*2+1]][c];
3584 if (sum) FORC3 image[row*width+col][c] = fsum[c]/sum;
3589 /* Array for 5x5 Gaussian averaging of red values */
3590 smrow[6] = (int (*)[3]) calloc (width*5, sizeof **smrow);
3591 merror (smrow[6], "foveon_interpolate()");
3592 for (i=0; i < 5; i++)
3593 smrow[i] = smrow[6] + i*width;
3595 /* Sharpen the reds against these Gaussian averages */
3596 for (smlast=-1, row=2; row < height-2; row++) {
3597 while (smlast < row+2) {
3598 for (i=0; i < 6; i++)
3599 smrow[(i+5) % 6] = smrow[i];
3600 pix = image[++smlast*width+2];
3601 for (col=2; col < width-2; col++) {
3603 (pix[0]*6 + (pix[-4]+pix[4])*4 + pix[-8]+pix[8] + 8) >> 4;
3607 pix = image[row*width+2];
3608 for (col=2; col < width-2; col++) {
3609 smred = ( 6 * smrow[2][col][0]
3610 + 4 * (smrow[1][col][0] + smrow[3][col][0])
3611 + smrow[0][col][0] + smrow[4][col][0] + 8 ) >> 4;
3614 i = pix[0] + ((pix[0] - ((smred*7 + smred_p) >> 3)) >> 3);
3615 if (i > 32000) i = 32000;
3622 /* Adjust the brighter pixels for better linearity */
3625 i = satlev[c] / div[c];
3626 if (min > i) min = i;
3628 limit = min * 9 >> 4;
3629 for (pix=image[0]; pix < image[height*width]; pix+=4) {
3630 if (pix[0] <= limit || pix[1] <= limit || pix[2] <= limit)
3633 for (c=1; c < 3; c++) {
3634 if (min > pix[c]) min = pix[c];
3635 if (max < pix[c]) max = pix[c];
3637 if (min >= limit*2) {
3638 pix[0] = pix[1] = pix[2] = max;
3640 i = 0x4000 - ((min - limit) << 14) / limit;
3641 i = 0x4000 - (i*i >> 14);
3643 FORC3 pix[c] += (max - pix[c]) * i >> 14;
3647 Because photons that miss one detector often hit another,
3648 the sum R+G+B is much less noisy than the individual colors.
3649 So smooth the hues without smoothing the total.
3651 for (smlast=-1, row=2; row < height-2; row++) {
3652 while (smlast < row+2) {
3653 for (i=0; i < 6; i++)
3654 smrow[(i+5) % 6] = smrow[i];
3655 pix = image[++smlast*width+2];
3656 for (col=2; col < width-2; col++) {
3657 FORC3 smrow[4][col][c] = (pix[c-4]+2*pix[c]+pix[c+4]+2) >> 2;
3661 pix = image[row*width+2];
3662 for (col=2; col < width-2; col++) {
3663 FORC3 dev[c] = -foveon_apply_curve (curve[7], pix[c] -
3664 ((smrow[1][col][c] + 2*smrow[2][col][c] + smrow[3][col][c]) >> 2));
3665 sum = (dev[0] + dev[1] + dev[2]) >> 3;
3666 FORC3 pix[c] += dev[c] - sum;
3670 for (smlast=-1, row=2; row < height-2; row++) {
3671 while (smlast < row+2) {
3672 for (i=0; i < 6; i++)
3673 smrow[(i+5) % 6] = smrow[i];
3674 pix = image[++smlast*width+2];
3675 for (col=2; col < width-2; col++) {
3676 FORC3 smrow[4][col][c] =
3677 (pix[c-8]+pix[c-4]+pix[c]+pix[c+4]+pix[c+8]+2) >> 2;
3681 pix = image[row*width+2];
3682 for (col=2; col < width-2; col++) {
3683 for (total[3]=375, sum=60, c=0; c < 3; c++) {
3684 for (total[c]=i=0; i < 5; i++)
3685 total[c] += smrow[i][col][c];
3686 total[3] += total[c];
3689 if (sum < 0) sum = 0;
3690 j = total[3] > 375 ? (sum << 16) / total[3] : sum * 174;
3691 FORC3 pix[c] += foveon_apply_curve (curve[6],
3692 ((j*total[c] + 0x8000) >> 16) - pix[c]);
3697 /* Transform the image to a different colorspace */
3698 for (pix=image[0]; pix < image[height*width]; pix+=4) {
3699 FORC3 pix[c] -= foveon_apply_curve (curve[c], pix[c]);
3700 sum = (pix[0]+pix[1]+pix[1]+pix[2]) >> 2;
3701 FORC3 pix[c] -= foveon_apply_curve (curve[c], pix[c]-sum);
3703 for (dsum=i=0; i < 3; i++)
3704 dsum += trans[c][i] * pix[i];
3705 if (dsum < 0) dsum = 0;
3706 if (dsum > 24000) dsum = 24000;
3707 ipix[c] = dsum + 0.5;
3709 FORC3 pix[c] = ipix[c];
3712 /* Smooth the image bottom-to-top and save at 1/4 scale */
3713 shrink = (short (*)[3]) calloc ((height/4), (width/4)*sizeof *shrink);
3714 merror (shrink, "foveon_interpolate()");
3715 for (row = height/4; row--; )
3716 for (col=0; col < width/4; col++) {
3717 ipix[0] = ipix[1] = ipix[2] = 0;
3718 for (i=0; i < 4; i++)
3719 for (j=0; j < 4; j++)
3720 FORC3 ipix[c] += image[(row*4+i)*width+col*4+j][c];
3722 if (row+2 > height/4)
3723 shrink[row*(width/4)+col][c] = ipix[c] >> 4;
3725 shrink[row*(width/4)+col][c] =
3726 (shrink[(row+1)*(width/4)+col][c]*1840 + ipix[c]*141 + 2048) >> 12;
3728 /* From the 1/4-scale image, smooth right-to-left */
3729 for (row=0; row < (height & ~3); row++) {
3730 ipix[0] = ipix[1] = ipix[2] = 0;
3732 for (col = width & ~3 ; col--; )
3733 FORC3 smrow[0][col][c] = ipix[c] =
3734 (shrink[(row/4)*(width/4)+col/4][c]*1485 + ipix[c]*6707 + 4096) >> 13;
3736 /* Then smooth left-to-right */
3737 ipix[0] = ipix[1] = ipix[2] = 0;
3738 for (col=0; col < (width & ~3); col++)
3739 FORC3 smrow[1][col][c] = ipix[c] =
3740 (smrow[0][col][c]*1485 + ipix[c]*6707 + 4096) >> 13;
3742 /* Smooth top-to-bottom */
3744 memcpy (smrow[2], smrow[1], sizeof **smrow * width);
3746 for (col=0; col < (width & ~3); col++)
3747 FORC3 smrow[2][col][c] =
3748 (smrow[2][col][c]*6707 + smrow[1][col][c]*1485 + 4096) >> 13;
3750 /* Adjust the chroma toward the smooth values */
3751 for (col=0; col < (width & ~3); col++) {
3752 for (i=j=30, c=0; c < 3; c++) {
3753 i += smrow[2][col][c];
3754 j += image[row*width+col][c];
3757 for (sum=c=0; c < 3; c++) {
3758 ipix[c] = foveon_apply_curve (curve[c+3],
3759 ((smrow[2][col][c] * j + 0x8000) >> 16) - image[row*width+col][c]);
3764 i = image[row*width+col][c] + ipix[c] - sum;
3766 image[row*width+col][c] = i;
3772 for (i=0; i < 8; i++)
3775 /* Trim off the black border */
3776 active[1] -= keep[1];
3778 i = active[2] - active[0];
3779 for (row=0; row < active[3]-active[1]; row++)
3780 memcpy (image[row*i], image[(row+active[1])*width+active[0]],
3787 /* RESTRICTED code ends here */
3789 void CLASS crop_masked_pixels()
3792 unsigned r, c, m, mblack[8], zero, val;
3794 if (load_raw == &CLASS phase_one_load_raw ||
3795 load_raw == &CLASS phase_one_load_raw_c)
3796 phase_one_correct();
3798 for (row=0; row < raw_height-top_margin*2; row++) {
3799 for (col=0; col < fuji_width << !fuji_layout; col++) {
3801 r = fuji_width - 1 - col + (row >> 1);
3802 c = col + ((row+1) >> 1);
3804 r = fuji_width - 1 + row - (col >> 1);
3805 c = row + ((col+1) >> 1);
3807 if (r < height && c < width)
3808 BAYER(r,c) = RAW(row+top_margin,col+left_margin);
3812 for (row=0; row < height; row++)
3813 for (col=0; col < width; col++)
3814 BAYER2(row,col) = RAW(row+top_margin,col+left_margin);
3816 if (mask[0][3] > 0) goto mask_set;
3817 if (load_raw == &CLASS canon_load_raw ||
3818 load_raw == &CLASS lossless_jpeg_load_raw) {
3819 mask[0][1] = mask[1][1] += 2;
3823 if (load_raw == &CLASS canon_600_load_raw ||
3824 load_raw == &CLASS sony_load_raw ||
3825 (load_raw == &CLASS eight_bit_load_raw && strncmp(model,"DC2",3)) ||
3826 load_raw == &CLASS kodak_262_load_raw ||
3827 (load_raw == &CLASS packed_load_raw && (load_flags & 32))) {
3829 mask[0][0] = mask[1][0] = top_margin;
3830 mask[0][2] = mask[1][2] = top_margin+height;
3831 mask[0][3] += left_margin;
3832 mask[1][1] += left_margin+width;
3833 mask[1][3] += raw_width;
3835 if (load_raw == &CLASS nokia_load_raw) {
3836 mask[0][2] = top_margin;
3840 memset (mblack, 0, sizeof mblack);
3841 for (zero=m=0; m < 8; m++)
3842 for (row=MAX(mask[m][0],0); row < MIN(mask[m][2],raw_height); row++)
3843 for (col=MAX(mask[m][1],0); col < MIN(mask[m][3],raw_width); col++) {
3844 c = FC(row-top_margin,col-left_margin);
3845 mblack[c] += val = RAW(row,col);
3849 if (load_raw == &CLASS canon_600_load_raw && width < raw_width) {
3850 black = (mblack[0]+mblack[1]+mblack[2]+mblack[3]) /
3851 (mblack[4]+mblack[5]+mblack[6]+mblack[7]) - 4;
3852 canon_600_correct();
3853 } else if (zero < mblack[4] && mblack[5] && mblack[6] && mblack[7]) {
3854 FORC4 cblack[c] = mblack[c] / mblack[4+c];
3855 cblack[4] = cblack[5] = cblack[6] = 0;
3859 void CLASS remove_zeroes()
3861 unsigned row, col, tot, n, r, c;
3863 for (row=0; row < height; row++)
3864 for (col=0; col < width; col++)
3865 if (BAYER(row,col) == 0) {
3867 for (r = row-2; r <= row+2; r++)
3868 for (c = col-2; c <= col+2; c++)
3869 if (r < height && c < width &&
3870 FC(r,c) == FC(row,col) && BAYER(r,c))
3871 tot += (n++,BAYER(r,c));
3872 if (n) BAYER(row,col) = tot/n;
3877 Seach from the current directory up to the root looking for
3878 a ".badpixels" file, and fix those pixels now.
3880 void CLASS bad_pixels (const char *cfname)
3883 char *fname, *cp, line[128];
3884 int len, time, row, col, r, c, rad, tot, n, fixed=0;
3886 if (!filters) return;
3888 fp = fopen (cfname, "r");
3890 for (len=32 ; ; len *= 2) {
3891 fname = (char *) malloc (len);
3893 if (getcwd (fname, len-16)) break;
3895 if (errno != ERANGE) return;
3897 #if defined(WIN32) || defined(DJGPP)
3898 if (fname[1] == ':')
3899 memmove (fname, fname+2, len-2);
3900 for (cp=fname; *cp; cp++)
3901 if (*cp == '\\') *cp = '/';
3903 cp = fname + strlen(fname);
3904 if (cp[-1] == '/') cp--;
3905 while (*fname == '/') {
3906 strcpy (cp, "/.badpixels");
3907 if ((fp = fopen (fname, "r"))) break;
3908 if (cp == fname) break;
3909 while (*--cp != '/');
3914 while (fgets (line, 128, fp)) {
3915 cp = strchr (line, '#');
3917 if (sscanf (line, "%d %d %d", &col, &row, &time) != 3) continue;
3918 if ((unsigned) col >= width || (unsigned) row >= height) continue;
3919 if (time > timestamp) continue;
3920 for (tot=n=0, rad=1; rad < 3 && n==0; rad++)
3921 for (r = row-rad; r <= row+rad; r++)
3922 for (c = col-rad; c <= col+rad; c++)
3923 if ((unsigned) r < height && (unsigned) c < width &&
3924 (r != row || c != col) && fcol(r,c) == fcol(row,col)) {
3928 BAYER2(row,col) = tot/n;
3931 fprintf (stderr,_("Fixed dead pixels at:"));
3932 fprintf (stderr, " %d,%d", col, row);
3935 if (fixed) fputc ('\n', stderr);
3939 void CLASS subtract (const char *fname)
3942 int dim[3]={0,0,0}, comment=0, number=0, error=0, nd=0, c, row, col;
3945 if (!(fp = fopen (fname, "rb"))) {
3946 perror (fname); return;
3948 if (fgetc(fp) != 'P' || fgetc(fp) != '5') error = 1;
3949 while (!error && nd < 3 && (c = fgetc(fp)) != EOF) {
3950 if (c == '#') comment = 1;
3951 if (c == '\n') comment = 0;
3952 if (comment) continue;
3953 if (isdigit(c)) number = 1;
3955 if (isdigit(c)) dim[nd] = dim[nd]*10 + c -'0';
3956 else if (isspace(c)) {
3961 if (error || nd < 3) {
3962 fprintf (stderr,_("%s is not a valid PGM file!\n"), fname);
3963 fclose (fp); return;
3964 } else if (dim[0] != width || dim[1] != height || dim[2] != 65535) {
3965 fprintf (stderr,_("%s has the wrong dimensions!\n"), fname);
3966 fclose (fp); return;
3968 pixel = (ushort *) calloc (width, sizeof *pixel);
3969 merror (pixel, "subtract()");
3970 for (row=0; row < height; row++) {
3971 fread (pixel, 2, width, fp);
3972 for (col=0; col < width; col++)
3973 BAYER(row,col) = MAX (BAYER(row,col) - ntohs(pixel[col]), 0);
3977 memset (cblack, 0, sizeof cblack);
3981 void CLASS gamma_curve (double pwr, double ts, int mode, int imax)
3984 double g[6], bnd[2]={0,0}, r;
3988 g[2] = g[3] = g[4] = 0;
3990 if (g[1] && (g[1]-1)*(g[0]-1) <= 0) {
3991 for (i=0; i < 48; i++) {
3992 g[2] = (bnd[0] + bnd[1])/2;
3993 if (g[0]) bnd[(pow(g[2]/g[1],-g[0]) - 1)/g[0] - 1/g[2] > -1] = g[2];
3994 else bnd[g[2]/exp(1-1/g[2]) < g[1]] = g[2];
3997 if (g[0]) g[4] = g[2] * (1/g[0] - 1);
3999 if (g[0]) g[5] = 1 / (g[1]*SQR(g[3])/2 - g[4]*(1 - g[3]) +
4000 (1 - pow(g[3],1+g[0]))*(1 + g[4])/(1 + g[0])) - 1;
4001 else g[5] = 1 / (g[1]*SQR(g[3])/2 + 1
4002 - g[2] - g[3] - g[2]*g[3]*(log(g[3]) - 1)) - 1;
4004 memcpy (gamm, g, sizeof gamm);
4007 for (i=0; i < 0x10000; i++) {
4009 if ((r = (double) i / imax) < 1)
4010 curve[i] = 0x10000 * ( mode
4011 ? (r < g[3] ? r*g[1] : (g[0] ? pow( r,g[0])*(1+g[4])-g[4] : log(r)*g[2]+1))
4012 : (r < g[2] ? r/g[1] : (g[0] ? pow((r+g[4])/(1+g[4]),1/g[0]) : exp((r-1)/g[2]))));
4016 void CLASS pseudoinverse (double (*in)[3], double (*out)[3], int size)
4018 double work[3][6], num;
4021 for (i=0; i < 3; i++) {
4022 for (j=0; j < 6; j++)
4023 work[i][j] = j == i+3;
4024 for (j=0; j < 3; j++)
4025 for (k=0; k < size; k++)
4026 work[i][j] += in[k][i] * in[k][j];
4028 for (i=0; i < 3; i++) {
4030 for (j=0; j < 6; j++)
4032 for (k=0; k < 3; k++) {
4035 for (j=0; j < 6; j++)
4036 work[k][j] -= work[i][j] * num;
4039 for (i=0; i < size; i++)
4040 for (j=0; j < 3; j++)
4041 for (out[i][j]=k=0; k < 3; k++)
4042 out[i][j] += work[j][k+3] * in[i][k];
4045 void CLASS cam_xyz_coeff (float rgb_cam[3][4], double cam_xyz[4][3])
4047 double cam_rgb[4][3], inverse[4][3], num;
4050 for (i=0; i < colors; i++) /* Multiply out XYZ colorspace */
4051 for (j=0; j < 3; j++)
4052 for (cam_rgb[i][j] = k=0; k < 3; k++)
4053 cam_rgb[i][j] += cam_xyz[i][k] * xyz_rgb[k][j];
4055 for (i=0; i < colors; i++) { /* Normalize cam_rgb so that */
4056 for (num=j=0; j < 3; j++) /* cam_rgb * (1,1,1) is (1,1,1,1) */
4057 num += cam_rgb[i][j];
4058 for (j=0; j < 3; j++)
4059 cam_rgb[i][j] /= num;
4060 pre_mul[i] = 1 / num;
4062 pseudoinverse (cam_rgb, inverse, colors);
4063 for (i=0; i < 3; i++)
4064 for (j=0; j < colors; j++)
4065 rgb_cam[i][j] = inverse[j][i];
4069 void CLASS colorcheck()
4072 // Coordinates of the GretagMacbeth ColorChecker squares
4073 // width, height, 1st_column, 1st_row
4074 int cut[NSQ][4]; // you must set these
4075 // ColorChecker Chart under 6500-kelvin illumination
4076 static const double gmb_xyY[NSQ][3] = {
4077 { 0.400, 0.350, 10.1 }, // Dark Skin
4078 { 0.377, 0.345, 35.8 }, // Light Skin
4079 { 0.247, 0.251, 19.3 }, // Blue Sky
4080 { 0.337, 0.422, 13.3 }, // Foliage
4081 { 0.265, 0.240, 24.3 }, // Blue Flower
4082 { 0.261, 0.343, 43.1 }, // Bluish Green
4083 { 0.506, 0.407, 30.1 }, // Orange
4084 { 0.211, 0.175, 12.0 }, // Purplish Blue
4085 { 0.453, 0.306, 19.8 }, // Moderate Red
4086 { 0.285, 0.202, 6.6 }, // Purple
4087 { 0.380, 0.489, 44.3 }, // Yellow Green
4088 { 0.473, 0.438, 43.1 }, // Orange Yellow
4089 { 0.187, 0.129, 6.1 }, // Blue
4090 { 0.305, 0.478, 23.4 }, // Green
4091 { 0.539, 0.313, 12.0 }, // Red
4092 { 0.448, 0.470, 59.1 }, // Yellow
4093 { 0.364, 0.233, 19.8 }, // Magenta
4094 { 0.196, 0.252, 19.8 }, // Cyan
4095 { 0.310, 0.316, 90.0 }, // White
4096 { 0.310, 0.316, 59.1 }, // Neutral 8
4097 { 0.310, 0.316, 36.2 }, // Neutral 6.5
4098 { 0.310, 0.316, 19.8 }, // Neutral 5
4099 { 0.310, 0.316, 9.0 }, // Neutral 3.5
4100 { 0.310, 0.316, 3.1 } }; // Black
4101 double gmb_cam[NSQ][4], gmb_xyz[NSQ][3];
4102 double inverse[NSQ][3], cam_xyz[4][3], balance[4], num;
4103 int c, i, j, k, sq, row, col, pass, count[4];
4105 memset (gmb_cam, 0, sizeof gmb_cam);
4106 for (sq=0; sq < NSQ; sq++) {
4108 for (row=cut[sq][3]; row < cut[sq][3]+cut[sq][1]; row++)
4109 for (col=cut[sq][2]; col < cut[sq][2]+cut[sq][0]; col++) {
4111 if (c >= colors) c -= 2;
4112 gmb_cam[sq][c] += BAYER2(row,col);
4113 BAYER2(row,col) = black + (BAYER2(row,col)-black)/2;
4116 FORCC gmb_cam[sq][c] = gmb_cam[sq][c]/count[c] - black;
4117 gmb_xyz[sq][0] = gmb_xyY[sq][2] * gmb_xyY[sq][0] / gmb_xyY[sq][1];
4118 gmb_xyz[sq][1] = gmb_xyY[sq][2];
4119 gmb_xyz[sq][2] = gmb_xyY[sq][2] *
4120 (1 - gmb_xyY[sq][0] - gmb_xyY[sq][1]) / gmb_xyY[sq][1];
4122 pseudoinverse (gmb_xyz, inverse, NSQ);
4123 for (pass=0; pass < 2; pass++) {
4124 for (raw_color = i=0; i < colors; i++)
4125 for (j=0; j < 3; j++)
4126 for (cam_xyz[i][j] = k=0; k < NSQ; k++)
4127 cam_xyz[i][j] += gmb_cam[k][i] * inverse[k][j];
4128 cam_xyz_coeff (rgb_cam, cam_xyz);
4129 FORCC balance[c] = pre_mul[c] * gmb_cam[20][c];
4130 for (sq=0; sq < NSQ; sq++)
4131 FORCC gmb_cam[sq][c] *= balance[c];
4134 printf (" { \"%s %s\", %d,\n\t{", make, model, black);
4135 num = 10000 / (cam_xyz[1][0] + cam_xyz[1][1] + cam_xyz[1][2]);
4136 FORCC for (j=0; j < 3; j++)
4137 printf ("%c%d", (c | j) ? ',':' ', (int) (cam_xyz[c][j] * num + 0.5));
4144 void CLASS hat_transform (float *temp, float *base, int st, int size, int sc)
4147 for (i=0; i < sc; i++)
4148 temp[i] = 2*base[st*i] + base[st*(sc-i)] + base[st*(i+sc)];
4149 for (; i+sc < size; i++)
4150 temp[i] = 2*base[st*i] + base[st*(i-sc)] + base[st*(i+sc)];
4151 for (; i < size; i++)
4152 temp[i] = 2*base[st*i] + base[st*(i-sc)] + base[st*(2*size-2-(i+sc))];
4155 void CLASS wavelet_denoise()
4157 float *fimg=0, *temp, thold, mul[2], avg, diff;
4158 int scale=1, size, lev, hpass, lpass, row, col, nc, c, i, wlast, blk[2];
4160 static const float noise[] =
4161 { 0.8002,0.2735,0.1202,0.0585,0.0291,0.0152,0.0080,0.0044 };
4163 if (verbose) fprintf (stderr,_("Wavelet denoising...\n"));
4165 while (maximum << scale < 0x10000) scale++;
4166 maximum <<= --scale;
4168 FORC4 cblack[c] <<= scale;
4169 if ((size = iheight*iwidth) < 0x15550000)
4170 fimg = (float *) malloc ((size*3 + iheight + iwidth) * sizeof *fimg);
4171 merror (fimg, "wavelet_denoise()");
4172 temp = fimg + size*3;
4173 if ((nc = colors) == 3 && filters) nc++;
4174 FORC(nc) { /* denoise R,G1,B,G3 individually */
4175 for (i=0; i < size; i++)
4176 fimg[i] = 256 * sqrt(image[i][c] << scale);
4177 for (hpass=lev=0; lev < 5; lev++) {
4178 lpass = size*((lev & 1)+1);
4179 for (row=0; row < iheight; row++) {
4180 hat_transform (temp, fimg+hpass+row*iwidth, 1, iwidth, 1 << lev);
4181 for (col=0; col < iwidth; col++)
4182 fimg[lpass + row*iwidth + col] = temp[col] * 0.25;
4184 for (col=0; col < iwidth; col++) {
4185 hat_transform (temp, fimg+lpass+col, iwidth, iheight, 1 << lev);
4186 for (row=0; row < iheight; row++)
4187 fimg[lpass + row*iwidth + col] = temp[row] * 0.25;
4189 thold = threshold * noise[lev];
4190 for (i=0; i < size; i++) {
4191 fimg[hpass+i] -= fimg[lpass+i];
4192 if (fimg[hpass+i] < -thold) fimg[hpass+i] += thold;
4193 else if (fimg[hpass+i] > thold) fimg[hpass+i] -= thold;
4194 else fimg[hpass+i] = 0;
4195 if (hpass) fimg[i] += fimg[hpass+i];
4199 for (i=0; i < size; i++)
4200 image[i][c] = CLIP(SQR(fimg[i]+fimg[lpass+i])/0x10000);
4202 if (filters && colors == 3) { /* pull G1 and G3 closer together */
4203 for (row=0; row < 2; row++) {
4204 mul[row] = 0.125 * pre_mul[FC(row+1,0) | 1] / pre_mul[FC(row,0) | 1];
4205 blk[row] = cblack[FC(row,0) | 1];
4207 for (i=0; i < 4; i++)
4208 window[i] = (ushort *) fimg + width*i;
4209 for (wlast=-1, row=1; row < height-1; row++) {
4210 while (wlast < row+1) {
4211 for (wlast++, i=0; i < 4; i++)
4212 window[(i+3) & 3] = window[i];
4213 for (col = FC(wlast,1) & 1; col < width; col+=2)
4214 window[2][col] = BAYER(wlast,col);
4216 thold = threshold/512;
4217 for (col = (FC(row,0) & 1)+1; col < width-1; col+=2) {
4218 avg = ( window[0][col-1] + window[0][col+1] +
4219 window[2][col-1] + window[2][col+1] - blk[~row & 1]*4 )
4220 * mul[row & 1] + (window[1][col] + blk[row & 1]) * 0.5;
4221 avg = avg < 0 ? 0 : sqrt(avg);
4222 diff = sqrt(BAYER(row,col)) - avg;
4223 if (diff < -thold) diff += thold;
4224 else if (diff > thold) diff -= thold;
4226 BAYER(row,col) = CLIP(SQR(avg+diff) + 0.5);
4233 void CLASS scale_colors()
4235 unsigned bottom, right, size, row, col, ur, uc, i, x, y, c, sum[8];
4237 double dsum[8], dmin, dmax;
4238 float scale_mul[4], fr, fc;
4239 ushort *img=0, *pix;
4242 memcpy (pre_mul, user_mul, sizeof pre_mul);
4243 if (use_auto_wb || (use_camera_wb && cam_mul[0] == -1)) {
4244 memset (dsum, 0, sizeof dsum);
4245 bottom = MIN (greybox[1]+greybox[3], height);
4246 right = MIN (greybox[0]+greybox[2], width);
4247 for (row=greybox[1]; row < bottom; row += 8)
4248 for (col=greybox[0]; col < right; col += 8) {
4249 memset (sum, 0, sizeof sum);
4250 for (y=row; y < row+8 && y < bottom; y++)
4251 for (x=col; x < col+8 && x < right; x++)
4257 val = image[y*width+x][c];
4258 if (val > maximum-25) goto skip_block;
4259 if ((val -= cblack[c]) < 0) val = 0;
4264 FORC(8) dsum[c] += sum[c];
4267 FORC4 if (dsum[c]) pre_mul[c] = dsum[c+4] / dsum[c];
4269 if (use_camera_wb && cam_mul[0] != -1) {
4270 memset (sum, 0, sizeof sum);
4271 for (row=0; row < 8; row++)
4272 for (col=0; col < 8; col++) {
4274 if ((val = white[row][col] - cblack[c]) > 0)
4278 if (sum[0] && sum[1] && sum[2] && sum[3])
4279 FORC4 pre_mul[c] = (float) sum[c+4] / sum[c];
4280 else if (cam_mul[0] && cam_mul[2])
4281 memcpy (pre_mul, cam_mul, sizeof pre_mul);
4283 fprintf (stderr,_("%s: Cannot use camera white balance.\n"), ifname);
4285 if (pre_mul[1] == 0) pre_mul[1] = 1;
4286 if (pre_mul[3] == 0) pre_mul[3] = colors < 4 ? pre_mul[1] : 1;
4289 if (threshold) wavelet_denoise();
4291 for (dmin=DBL_MAX, dmax=c=0; c < 4; c++) {
4292 if (dmin > pre_mul[c])
4294 if (dmax < pre_mul[c])
4297 if (!highlight) dmax = dmin;
4298 FORC4 scale_mul[c] = (pre_mul[c] /= dmax) * 65535.0 / maximum;
4301 _("Scaling with darkness %d, saturation %d, and\nmultipliers"), dark, sat);
4302 FORC4 fprintf (stderr, " %f", pre_mul[c]);
4303 fputc ('\n', stderr);
4305 if (filters > 1000 && (cblack[4]+1)/2 == 1 && (cblack[5]+1)/2 == 1) {
4306 FORC4 cblack[FC(c/2,c%2)] +=
4307 cblack[6 + c/2 % cblack[4] * cblack[5] + c%2 % cblack[5]];
4308 cblack[4] = cblack[5] = 0;
4310 size = iheight*iwidth;
4311 for (i=0; i < size*4; i++) {
4312 if (!(val = ((ushort *)image)[i])) continue;
4313 if (cblack[4] && cblack[5])
4314 val -= cblack[6 + i/4 / iwidth % cblack[4] * cblack[5] +
4315 i/4 % iwidth % cblack[5]];
4316 val -= cblack[i & 3];
4317 val *= scale_mul[i & 3];
4318 ((ushort *)image)[i] = CLIP(val);
4320 if ((aber[0] != 1 || aber[2] != 1) && colors == 3) {
4322 fprintf (stderr,_("Correcting chromatic aberration...\n"));
4323 for (c=0; c < 4; c+=2) {
4324 if (aber[c] == 1) continue;
4325 img = (ushort *) malloc (size * sizeof *img);
4326 merror (img, "scale_colors()");
4327 for (i=0; i < size; i++)
4328 img[i] = image[i][c];
4329 for (row=0; row < iheight; row++) {
4330 ur = fr = (row - iheight*0.5) * aber[c] + iheight*0.5;
4331 if (ur > iheight-2) continue;
4333 for (col=0; col < iwidth; col++) {
4334 uc = fc = (col - iwidth*0.5) * aber[c] + iwidth*0.5;
4335 if (uc > iwidth-2) continue;
4337 pix = img + ur*iwidth + uc;
4338 image[row*iwidth+col][c] =
4339 (pix[ 0]*(1-fc) + pix[ 1]*fc) * (1-fr) +
4340 (pix[iwidth]*(1-fc) + pix[iwidth+1]*fc) * fr;
4348 void CLASS pre_interpolate()
4358 for (row=0; row < 3; row++)
4359 for (col=1; col < 4; col++)
4360 if (!(image[row*width+col][0] | image[row*width+col][2]))
4361 goto break2; break2:
4362 for ( ; row < height; row+=3)
4363 for (col=(col-1)%3+1; col < width-1; col+=3) {
4364 img = image + row*width+col;
4365 for (c=0; c < 3; c+=2)
4366 img[0][c] = (img[-1][c] + img[1][c]) >> 1;
4370 img = (ushort (*)[4]) calloc (height, width*sizeof *img);
4371 merror (img, "pre_interpolate()");
4372 for (row=0; row < height; row++)
4373 for (col=0; col < width; col++) {
4375 img[row*width+col][c] = image[(row >> 1)*iwidth+(col >> 1)][c];
4382 if (filters > 1000 && colors == 3) {
4383 mix_green = four_color_rgb ^ half_size;
4384 if (four_color_rgb | half_size) colors++;
4386 for (row = FC(1,0) >> 1; row < height; row+=2)
4387 for (col = FC(row,1) & 1; col < width; col+=2)
4388 image[row*width+col][1] = image[row*width+col][3];
4389 filters &= ~((filters & 0x55555555) << 1);
4392 if (half_size) filters = 0;
4395 void CLASS border_interpolate (int border)
4397 unsigned row, col, y, x, f, c, sum[8];
4399 for (row=0; row < height; row++)
4400 for (col=0; col < width; col++) {
4401 if (col==border && row >= border && row < height-border)
4403 memset (sum, 0, sizeof sum);
4404 for (y=row-1; y != row+2; y++)
4405 for (x=col-1; x != col+2; x++)
4406 if (y < height && x < width) {
4408 sum[f] += image[y*width+x][f];
4412 FORCC if (c != f && sum[c+4])
4413 image[row*width+col][c] = sum[c] / sum[c+4];
4417 void CLASS lin_interpolate()
4419 int code[16][16][32], size=16, *ip, sum[4];
4420 int f, c, i, x, y, row, col, shift, color;
4423 if (verbose) fprintf (stderr,_("Bilinear interpolation...\n"));
4424 if (filters == 9) size = 6;
4425 border_interpolate(1);
4426 for (row=0; row < size; row++)
4427 for (col=0; col < size; col++) {
4428 ip = code[row][col]+1;
4430 memset (sum, 0, sizeof sum);
4431 for (y=-1; y <= 1; y++)
4432 for (x=-1; x <= 1; x++) {
4433 shift = (y==0) + (x==0);
4434 color = fcol(row+y,col+x);
4435 if (color == f) continue;
4436 *ip++ = (width*y + x)*4 + color;
4439 sum[color] += 1 << shift;
4441 code[row][col][0] = (ip - code[row][col]) / 3;
4445 *ip++ = 256 / sum[c];
4448 for (row=1; row < height-1; row++)
4449 for (col=1; col < width-1; col++) {
4450 pix = image[row*width+col];
4451 ip = code[row % size][col % size];
4452 memset (sum, 0, sizeof sum);
4453 for (i=*ip++; i--; ip+=3)
4454 sum[ip[2]] += pix[ip[0]] << ip[1];
4455 for (i=colors; --i; ip+=2)
4456 pix[ip[0]] = sum[ip[0]] * ip[1] >> 8;
4461 This algorithm is officially called:
4463 "Interpolation using a Threshold-based variable number of gradients"
4465 described in http://scien.stanford.edu/pages/labsite/1999/psych221/projects/99/tingchen/algodep/vargra.html
4467 I've extended the basic idea to work with non-Bayer filter arrays.
4468 Gradients are numbered clockwise from NW=0 to W=7.
4470 void CLASS vng_interpolate()
4472 static const signed char *cp, terms[] = {
4473 -2,-2,+0,-1,0,0x01, -2,-2,+0,+0,1,0x01, -2,-1,-1,+0,0,0x01,
4474 -2,-1,+0,-1,0,0x02, -2,-1,+0,+0,0,0x03, -2,-1,+0,+1,1,0x01,
4475 -2,+0,+0,-1,0,0x06, -2,+0,+0,+0,1,0x02, -2,+0,+0,+1,0,0x03,
4476 -2,+1,-1,+0,0,0x04, -2,+1,+0,-1,1,0x04, -2,+1,+0,+0,0,0x06,
4477 -2,+1,+0,+1,0,0x02, -2,+2,+0,+0,1,0x04, -2,+2,+0,+1,0,0x04,
4478 -1,-2,-1,+0,0,0x80, -1,-2,+0,-1,0,0x01, -1,-2,+1,-1,0,0x01,
4479 -1,-2,+1,+0,1,0x01, -1,-1,-1,+1,0,0x88, -1,-1,+1,-2,0,0x40,
4480 -1,-1,+1,-1,0,0x22, -1,-1,+1,+0,0,0x33, -1,-1,+1,+1,1,0x11,
4481 -1,+0,-1,+2,0,0x08, -1,+0,+0,-1,0,0x44, -1,+0,+0,+1,0,0x11,
4482 -1,+0,+1,-2,1,0x40, -1,+0,+1,-1,0,0x66, -1,+0,+1,+0,1,0x22,
4483 -1,+0,+1,+1,0,0x33, -1,+0,+1,+2,1,0x10, -1,+1,+1,-1,1,0x44,
4484 -1,+1,+1,+0,0,0x66, -1,+1,+1,+1,0,0x22, -1,+1,+1,+2,0,0x10,
4485 -1,+2,+0,+1,0,0x04, -1,+2,+1,+0,1,0x04, -1,+2,+1,+1,0,0x04,
4486 +0,-2,+0,+0,1,0x80, +0,-1,+0,+1,1,0x88, +0,-1,+1,-2,0,0x40,
4487 +0,-1,+1,+0,0,0x11, +0,-1,+2,-2,0,0x40, +0,-1,+2,-1,0,0x20,
4488 +0,-1,+2,+0,0,0x30, +0,-1,+2,+1,1,0x10, +0,+0,+0,+2,1,0x08,
4489 +0,+0,+2,-2,1,0x40, +0,+0,+2,-1,0,0x60, +0,+0,+2,+0,1,0x20,
4490 +0,+0,+2,+1,0,0x30, +0,+0,+2,+2,1,0x10, +0,+1,+1,+0,0,0x44,
4491 +0,+1,+1,+2,0,0x10, +0,+1,+2,-1,1,0x40, +0,+1,+2,+0,0,0x60,
4492 +0,+1,+2,+1,0,0x20, +0,+1,+2,+2,0,0x10, +1,-2,+1,+0,0,0x80,
4493 +1,-1,+1,+1,0,0x88, +1,+0,+1,+2,0,0x08, +1,+0,+2,-1,0,0x40,
4495 }, chood[] = { -1,-1, -1,0, -1,+1, 0,+1, +1,+1, +1,0, +1,-1, 0,-1 };
4496 ushort (*brow[5])[4], *pix;
4497 int prow=8, pcol=2, *ip, *code[16][16], gval[8], gmin, gmax, sum[4];
4498 int row, col, x, y, x1, x2, y1, y2, t, weight, grads, color, diag;
4499 int g, diff, thold, num, c;
4502 if (verbose) fprintf (stderr,_("VNG interpolation...\n"));
4504 if (filters == 1) prow = pcol = 16;
4505 if (filters == 9) prow = pcol = 6;
4506 ip = (int *) calloc (prow*pcol, 1280);
4507 merror (ip, "vng_interpolate()");
4508 for (row=0; row < prow; row++) /* Precalculate for VNG */
4509 for (col=0; col < pcol; col++) {
4510 code[row][col] = ip;
4511 for (cp=terms, t=0; t < 64; t++) {
4512 y1 = *cp++; x1 = *cp++;
4513 y2 = *cp++; x2 = *cp++;
4516 color = fcol(row+y1,col+x1);
4517 if (fcol(row+y2,col+x2) != color) continue;
4518 diag = (fcol(row,col+1) == color && fcol(row+1,col) == color) ? 2:1;
4519 if (abs(y1-y2) == diag && abs(x1-x2) == diag) continue;
4520 *ip++ = (y1*width + x1)*4 + color;
4521 *ip++ = (y2*width + x2)*4 + color;
4523 for (g=0; g < 8; g++)
4524 if (grads & 1<<g) *ip++ = g;
4528 for (cp=chood, g=0; g < 8; g++) {
4529 y = *cp++; x = *cp++;
4530 *ip++ = (y*width + x) * 4;
4531 color = fcol(row,col);
4532 if (fcol(row+y,col+x) != color && fcol(row+y*2,col+x*2) == color)
4533 *ip++ = (y*width + x) * 8 + color;
4538 brow[4] = (ushort (*)[4]) calloc (width*3, sizeof **brow);
4539 merror (brow[4], "vng_interpolate()");
4540 for (row=0; row < 3; row++)
4541 brow[row] = brow[4] + row*width;
4542 for (row=2; row < height-2; row++) { /* Do VNG interpolation */
4543 for (col=2; col < width-2; col++) {
4544 pix = image[row*width+col];
4545 ip = code[row % prow][col % pcol];
4546 memset (gval, 0, sizeof gval);
4547 while ((g = ip[0]) != INT_MAX) { /* Calculate gradients */
4548 diff = ABS(pix[g] - pix[ip[1]]) << ip[2];
4549 gval[ip[3]] += diff;
4551 if ((g = ip[-1]) == -1) continue;
4553 while ((g = *ip++) != -1)
4557 gmin = gmax = gval[0]; /* Choose a threshold */
4558 for (g=1; g < 8; g++) {
4559 if (gmin > gval[g]) gmin = gval[g];
4560 if (gmax < gval[g]) gmax = gval[g];
4563 memcpy (brow[2][col], pix, sizeof *image);
4566 thold = gmin + (gmax >> 1);
4567 memset (sum, 0, sizeof sum);
4568 color = fcol(row,col);
4569 for (num=g=0; g < 8; g++,ip+=2) { /* Average the neighbors */
4570 if (gval[g] <= thold) {
4572 if (c == color && ip[1])
4573 sum[c] += (pix[c] + pix[ip[1]]) >> 1;
4575 sum[c] += pix[ip[0] + c];
4579 FORCC { /* Save to buffer */
4582 t += (sum[c] - sum[color]) / num;
4583 brow[2][col][c] = CLIP(t);
4586 if (row > 3) /* Write buffer to image */
4587 memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image);
4588 for (g=0; g < 4; g++)
4589 brow[(g-1) & 3] = brow[g];
4591 memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image);
4592 memcpy (image[(row-1)*width+2], brow[1]+2, (width-4)*sizeof *image);
4598 Patterned Pixel Grouping Interpolation by Alain Desbiolles
4600 void CLASS ppg_interpolate()
4602 int dir[5] = { 1, width, -1, -width, 1 };
4603 int row, col, diff[2], guess[2], c, d, i;
4606 border_interpolate(3);
4607 if (verbose) fprintf (stderr,_("PPG interpolation...\n"));
4609 /* Fill in the green layer with gradients and pattern recognition: */
4610 for (row=3; row < height-3; row++)
4611 for (col=3+(FC(row,3) & 1), c=FC(row,col); col < width-3; col+=2) {
4612 pix = image + row*width+col;
4613 for (i=0; (d=dir[i]) > 0; i++) {
4614 guess[i] = (pix[-d][1] + pix[0][c] + pix[d][1]) * 2
4615 - pix[-2*d][c] - pix[2*d][c];
4616 diff[i] = ( ABS(pix[-2*d][c] - pix[ 0][c]) +
4617 ABS(pix[ 2*d][c] - pix[ 0][c]) +
4618 ABS(pix[ -d][1] - pix[ d][1]) ) * 3 +
4619 ( ABS(pix[ 3*d][1] - pix[ d][1]) +
4620 ABS(pix[-3*d][1] - pix[-d][1]) ) * 2;
4622 d = dir[i = diff[0] > diff[1]];
4623 pix[0][1] = ULIM(guess[i] >> 2, pix[d][1], pix[-d][1]);
4625 /* Calculate red and blue for each green pixel: */
4626 for (row=1; row < height-1; row++)
4627 for (col=1+(FC(row,2) & 1), c=FC(row,col+1); col < width-1; col+=2) {
4628 pix = image + row*width+col;
4629 for (i=0; (d=dir[i]) > 0; c=2-c, i++)
4630 pix[0][c] = CLIP((pix[-d][c] + pix[d][c] + 2*pix[0][1]
4631 - pix[-d][1] - pix[d][1]) >> 1);
4633 /* Calculate blue for red pixels and vice versa: */
4634 for (row=1; row < height-1; row++)
4635 for (col=1+(FC(row,1) & 1), c=2-FC(row,col); col < width-1; col+=2) {
4636 pix = image + row*width+col;
4637 for (i=0; (d=dir[i]+dir[i+1]) > 0; i++) {
4638 diff[i] = ABS(pix[-d][c] - pix[d][c]) +
4639 ABS(pix[-d][1] - pix[0][1]) +
4640 ABS(pix[ d][1] - pix[0][1]);
4641 guess[i] = pix[-d][c] + pix[d][c] + 2*pix[0][1]
4642 - pix[-d][1] - pix[d][1];
4644 if (diff[0] != diff[1])
4645 pix[0][c] = CLIP(guess[diff[0] > diff[1]] >> 1);
4647 pix[0][c] = CLIP((guess[0]+guess[1]) >> 2);
4651 void CLASS cielab (ushort rgb[3], short lab[3])
4655 static float cbrt[0x10000], xyz_cam[3][4];
4658 for (i=0; i < 0x10000; i++) {
4660 cbrt[i] = r > 0.008856 ? pow(r,1/3.0) : 7.787*r + 16/116.0;
4662 for (i=0; i < 3; i++)
4663 for (j=0; j < colors; j++)
4664 for (xyz_cam[i][j] = k=0; k < 3; k++)
4665 xyz_cam[i][j] += xyz_rgb[i][k] * rgb_cam[k][j] / d65_white[i];
4668 xyz[0] = xyz[1] = xyz[2] = 0.5;
4670 xyz[0] += xyz_cam[0][c] * rgb[c];
4671 xyz[1] += xyz_cam[1][c] * rgb[c];
4672 xyz[2] += xyz_cam[2][c] * rgb[c];
4674 xyz[0] = cbrt[CLIP((int) xyz[0])];
4675 xyz[1] = cbrt[CLIP((int) xyz[1])];
4676 xyz[2] = cbrt[CLIP((int) xyz[2])];
4677 lab[0] = 64 * (116 * xyz[1] - 16);
4678 lab[1] = 64 * 500 * (xyz[0] - xyz[1]);
4679 lab[2] = 64 * 200 * (xyz[1] - xyz[2]);
4682 #define TS 512 /* Tile Size */
4683 #define fcol(row,col) xtrans[(row+6) % 6][(col+6) % 6]
4686 Frank Markesteijn's algorithm for Fuji X-Trans sensors
4688 void CLASS xtrans_interpolate (int passes)
4690 int c, d, f, g, h, i, v, ng, row, col, top, left, mrow, mcol;
4691 int val, ndir, pass, hm[8], avg[4], color[3][8];
4692 static const short orth[12] = { 1,0,0,1,-1,0,0,-1,1,0,0,1 },
4693 patt[2][16] = { { 0,1,0,-1,2,0,-1,0,1,1,1,-1,0,0,0,0 },
4694 { 0,1,0,-2,1,0,-2,0,1,1,-2,-2,1,-1,-1,1 } },
4695 dir[4] = { 1,TS,TS+1,TS-1 };
4696 short allhex[3][3][2][8], *hex;
4698 ushort min, max, sgrow=0, sgcol=0;
4699 ushort (*rgb)[TS][TS][3], (*rix)[3], (*pix)[4];
4700 short (*lab) [TS][3], (*lix)[3];
4701 float (*drv)[TS][TS], diff[6], tr;
4702 char (*homo)[TS][TS], *buffer;
4705 fprintf (stderr,_("%d-pass X-Trans interpolation...\n"), passes);
4708 ndir = 4 << (passes > 1);
4709 buffer = (char *) malloc (TS*TS*(ndir*11+6));
4710 merror (buffer, "xtrans_interpolate()");
4711 rgb = (ushort(*)[TS][TS][3]) buffer;
4712 lab = (short (*) [TS][3])(buffer + TS*TS*(ndir*6));
4713 drv = (float (*)[TS][TS]) (buffer + TS*TS*(ndir*6+6));
4714 homo = (char (*)[TS][TS]) (buffer + TS*TS*(ndir*10+6));
4716 /* Map a green hexagon around each non-green pixel and vice versa: */
4717 for (row=0; row < 3; row++)
4718 for (col=0; col < 3; col++)
4719 for (ng=d=0; d < 10; d+=2) {
4720 g = fcol(row,col) == 1;
4721 if (fcol(row+orth[d],col+orth[d+2]) == 1) ng=0; else ng++;
4722 if (ng == 4) { sgrow = row; sgcol = col; }
4723 if (ng == g+1) FORC(8) {
4724 v = orth[d ]*patt[g][c*2] + orth[d+1]*patt[g][c*2+1];
4725 h = orth[d+2]*patt[g][c*2] + orth[d+3]*patt[g][c*2+1];
4726 allhex[row][col][0][c^(g*2 & d)] = h + v*width;
4727 allhex[row][col][1][c^(g*2 & d)] = h + v*TS;
4731 /* Set green1 and green3 to the minimum and maximum allowed values: */
4732 for (row=2; row < height-2; row++)
4733 for (min=~(max=0), col=2; col < width-2; col++) {
4734 if (fcol(row,col) == 1 && (min=~(max=0))) continue;
4735 pix = image + row*width + col;
4736 hex = allhex[row % 3][col % 3][0];
4738 val = pix[hex[c]][1];
4739 if (min > val) min = val;
4740 if (max < val) max = val;
4744 switch ((row-sgrow) % 3) {
4745 case 1: if (row < height-3) { row++; col--; } break;
4746 case 2: if ((min=~(max=0)) && (col+=2) < width-3 && row > 2) row--;
4750 for (top=3; top < height-19; top += TS-16)
4751 for (left=3; left < width-19; left += TS-16) {
4752 mrow = MIN (top+TS, height-3);
4753 mcol = MIN (left+TS, width-3);
4754 for (row=top; row < mrow; row++)
4755 for (col=left; col < mcol; col++)
4756 memcpy (rgb[0][row-top][col-left], image[row*width+col], 6);
4757 FORC3 memcpy (rgb[c+1], rgb[0], sizeof *rgb);
4759 /* Interpolate green horizontally, vertically, and along both diagonals: */
4760 for (row=top; row < mrow; row++)
4761 for (col=left; col < mcol; col++) {
4762 if ((f = fcol(row,col)) == 1) continue;
4763 pix = image + row*width + col;
4764 hex = allhex[row % 3][col % 3][0];
4765 color[1][0] = 174 * (pix[ hex[1]][1] + pix[ hex[0]][1]) -
4766 46 * (pix[2*hex[1]][1] + pix[2*hex[0]][1]);
4767 color[1][1] = 223 * pix[ hex[3]][1] + pix[ hex[2]][1] * 33 +
4768 92 * (pix[ 0 ][f] - pix[ -hex[2]][f]);
4769 FORC(2) color[1][2+c] =
4770 164 * pix[hex[4+c]][1] + 92 * pix[-2*hex[4+c]][1] + 33 *
4771 (2*pix[0][f] - pix[3*hex[4+c]][f] - pix[-3*hex[4+c]][f]);
4772 FORC4 rgb[c^!((row-sgrow) % 3)][row-top][col-left][1] =
4773 LIM(color[1][c] >> 8,pix[0][1],pix[0][3]);
4776 for (pass=0; pass < passes; pass++) {
4778 memcpy (rgb+=4, buffer, 4*sizeof *rgb);
4780 /* Recalculate green from interpolated values of closer pixels: */
4782 for (row=top+2; row < mrow-2; row++)
4783 for (col=left+2; col < mcol-2; col++) {
4784 if ((f = fcol(row,col)) == 1) continue;
4785 pix = image + row*width + col;
4786 hex = allhex[row % 3][col % 3][1];
4787 for (d=3; d < 6; d++) {
4788 rix = &rgb[(d-2)^!((row-sgrow) % 3)][row-top][col-left];
4789 val = rix[-2*hex[d]][1] + 2*rix[hex[d]][1]
4790 - rix[-2*hex[d]][f] - 2*rix[hex[d]][f] + 3*rix[0][f];
4791 rix[0][1] = LIM(val/3,pix[0][1],pix[0][3]);
4796 /* Interpolate red and blue values for solitary green pixels: */
4797 for (row=(top-sgrow+4)/3*3+sgrow; row < mrow-2; row+=3)
4798 for (col=(left-sgcol+4)/3*3+sgcol; col < mcol-2; col+=3) {
4799 rix = &rgb[0][row-top][col-left];
4800 h = fcol(row,col+1);
4801 memset (diff, 0, sizeof diff);
4802 for (i=1, d=0; d < 6; d++, i^=TS^1, h^=2) {
4803 for (c=0; c < 2; c++, h^=2) {
4804 g = 2*rix[0][1] - rix[i<<c][1] - rix[-i<<c][1];
4805 color[h][d] = g + rix[i<<c][h] + rix[-i<<c][h];
4807 diff[d] += SQR (rix[i<<c][1] - rix[-i<<c][1]
4808 - rix[i<<c][h] + rix[-i<<c][h]) + SQR(g);
4810 if (d > 1 && (d & 1))
4811 if (diff[d-1] < diff[d])
4812 FORC(2) color[c*2][d] = color[c*2][d-1];
4813 if (d < 2 || (d & 1)) {
4814 FORC(2) rix[0][c*2] = CLIP(color[c*2][d]/2);
4820 /* Interpolate red for blue pixels and vice versa: */
4821 for (row=top+3; row < mrow-3; row++)
4822 for (col=left+3; col < mcol-3; col++) {
4823 if ((f = 2-fcol(row,col)) == 1) continue;
4824 rix = &rgb[0][row-top][col-left];
4825 c = (row-sgrow) % 3 ? TS:1;
4826 h = 3 * (c ^ TS ^ 1);
4827 for (d=0; d < 4; d++, rix += TS*TS) {
4828 i = d > 1 || ((d ^ c) & 1) ||
4829 ((ABS(rix[0][1]-rix[c][1])+ABS(rix[0][1]-rix[-c][1])) <
4830 2*(ABS(rix[0][1]-rix[h][1])+ABS(rix[0][1]-rix[-h][1]))) ? c:h;
4831 rix[0][f] = CLIP((rix[i][f] + rix[-i][f] +
4832 2*rix[0][1] - rix[i][1] - rix[-i][1])/2);
4836 /* Fill in red and blue for 2x2 blocks of green: */
4837 for (row=top+2; row < mrow-2; row++) if ((row-sgrow) % 3)
4838 for (col=left+2; col < mcol-2; col++) if ((col-sgcol) % 3) {
4839 rix = &rgb[0][row-top][col-left];
4840 hex = allhex[row % 3][col % 3][1];
4841 for (d=0; d < ndir; d+=2, rix += TS*TS)
4842 if (hex[d] + hex[d+1]) {
4843 g = 3*rix[0][1] - 2*rix[hex[d]][1] - rix[hex[d+1]][1];
4844 for (c=0; c < 4; c+=2) rix[0][c] =
4845 CLIP((g + 2*rix[hex[d]][c] + rix[hex[d+1]][c])/3);
4847 g = 2*rix[0][1] - rix[hex[d]][1] - rix[hex[d+1]][1];
4848 for (c=0; c < 4; c+=2) rix[0][c] =
4849 CLIP((g + rix[hex[d]][c] + rix[hex[d+1]][c])/2);
4853 rgb = (ushort(*)[TS][TS][3]) buffer;
4857 /* Convert to CIELab and differentiate in all directions: */
4858 for (d=0; d < ndir; d++) {
4859 for (row=2; row < mrow-2; row++)
4860 for (col=2; col < mcol-2; col++)
4861 cielab (rgb[d][row][col], lab[row][col]);
4862 for (f=dir[d & 3],row=3; row < mrow-3; row++)
4863 for (col=3; col < mcol-3; col++) {
4864 lix = &lab[row][col];
4865 g = 2*lix[0][0] - lix[f][0] - lix[-f][0];
4866 drv[d][row][col] = SQR(g)
4867 + SQR((2*lix[0][1] - lix[f][1] - lix[-f][1] + g*500/232))
4868 + SQR((2*lix[0][2] - lix[f][2] - lix[-f][2] - g*500/580));
4872 /* Build homogeneity maps from the derivatives: */
4873 memset(homo, 0, ndir*TS*TS);
4874 for (row=4; row < mrow-4; row++)
4875 for (col=4; col < mcol-4; col++) {
4876 for (tr=FLT_MAX, d=0; d < ndir; d++)
4877 if (tr > drv[d][row][col])
4878 tr = drv[d][row][col];
4880 for (d=0; d < ndir; d++)
4881 for (v=-1; v <= 1; v++)
4882 for (h=-1; h <= 1; h++)
4883 if (drv[d][row+v][col+h] <= tr)
4884 homo[d][row][col]++;
4887 /* Average the most homogenous pixels for the final result: */
4888 if (height-top < TS+4) mrow = height-top+2;
4889 if (width-left < TS+4) mcol = width-left+2;
4890 for (row = MIN(top,8); row < mrow-8; row++)
4891 for (col = MIN(left,8); col < mcol-8; col++) {
4892 for (d=0; d < ndir; d++)
4893 for (hm[d]=0, v=-2; v <= 2; v++)
4894 for (h=-2; h <= 2; h++)
4895 hm[d] += homo[d][row+v][col+h];
4896 for (d=0; d < ndir-4; d++)
4897 if (hm[d] < hm[d+4]) hm[d ] = 0; else
4898 if (hm[d] > hm[d+4]) hm[d+4] = 0;
4899 for (max=hm[0],d=1; d < ndir; d++)
4900 if (max < hm[d]) max = hm[d];
4902 memset (avg, 0, sizeof avg);
4903 for (d=0; d < ndir; d++)
4905 FORC3 avg[c] += rgb[d][row][col][c];
4908 FORC3 image[(row+top)*width+col+left][c] = avg[c]/avg[3];
4912 border_interpolate(8);
4917 Adaptive Homogeneity-Directed interpolation is based on
4918 the work of Keigo Hirakawa, Thomas Parks, and Paul Lee.
4920 void CLASS ahd_interpolate()
4922 int i, j, top, left, row, col, tr, tc, c, d, val, hm[2];
4923 static const int dir[4] = { -1, 1, -TS, TS };
4924 unsigned ldiff[2][4], abdiff[2][4], leps, abeps;
4925 ushort (*rgb)[TS][TS][3], (*rix)[3], (*pix)[4];
4926 short (*lab)[TS][TS][3], (*lix)[3];
4927 char (*homo)[TS][TS], *buffer;
4929 if (verbose) fprintf (stderr,_("AHD interpolation...\n"));
4932 border_interpolate(5);
4933 buffer = (char *) malloc (26*TS*TS);
4934 merror (buffer, "ahd_interpolate()");
4935 rgb = (ushort(*)[TS][TS][3]) buffer;
4936 lab = (short (*)[TS][TS][3])(buffer + 12*TS*TS);
4937 homo = (char (*)[TS][TS]) (buffer + 24*TS*TS);
4939 for (top=2; top < height-5; top += TS-6)
4940 for (left=2; left < width-5; left += TS-6) {
4942 /* Interpolate green horizontally and vertically: */
4943 for (row=top; row < top+TS && row < height-2; row++) {
4944 col = left + (FC(row,left) & 1);
4945 for (c = FC(row,col); col < left+TS && col < width-2; col+=2) {
4946 pix = image + row*width+col;
4947 val = ((pix[-1][1] + pix[0][c] + pix[1][1]) * 2
4948 - pix[-2][c] - pix[2][c]) >> 2;
4949 rgb[0][row-top][col-left][1] = ULIM(val,pix[-1][1],pix[1][1]);
4950 val = ((pix[-width][1] + pix[0][c] + pix[width][1]) * 2
4951 - pix[-2*width][c] - pix[2*width][c]) >> 2;
4952 rgb[1][row-top][col-left][1] = ULIM(val,pix[-width][1],pix[width][1]);
4955 /* Interpolate red and blue, and convert to CIELab: */
4956 for (d=0; d < 2; d++)
4957 for (row=top+1; row < top+TS-1 && row < height-3; row++)
4958 for (col=left+1; col < left+TS-1 && col < width-3; col++) {
4959 pix = image + row*width+col;
4960 rix = &rgb[d][row-top][col-left];
4961 lix = &lab[d][row-top][col-left];
4962 if ((c = 2 - FC(row,col)) == 1) {
4964 val = pix[0][1] + (( pix[-1][2-c] + pix[1][2-c]
4965 - rix[-1][1] - rix[1][1] ) >> 1);
4966 rix[0][2-c] = CLIP(val);
4967 val = pix[0][1] + (( pix[-width][c] + pix[width][c]
4968 - rix[-TS][1] - rix[TS][1] ) >> 1);
4970 val = rix[0][1] + (( pix[-width-1][c] + pix[-width+1][c]
4971 + pix[+width-1][c] + pix[+width+1][c]
4972 - rix[-TS-1][1] - rix[-TS+1][1]
4973 - rix[+TS-1][1] - rix[+TS+1][1] + 1) >> 2);
4974 rix[0][c] = CLIP(val);
4976 rix[0][c] = pix[0][c];
4977 cielab (rix[0],lix[0]);
4979 /* Build homogeneity maps from the CIELab images: */
4980 memset (homo, 0, 2*TS*TS);
4981 for (row=top+2; row < top+TS-2 && row < height-4; row++) {
4983 for (col=left+2; col < left+TS-2 && col < width-4; col++) {
4985 for (d=0; d < 2; d++) {
4986 lix = &lab[d][tr][tc];
4987 for (i=0; i < 4; i++) {
4988 ldiff[d][i] = ABS(lix[0][0]-lix[dir[i]][0]);
4989 abdiff[d][i] = SQR(lix[0][1]-lix[dir[i]][1])
4990 + SQR(lix[0][2]-lix[dir[i]][2]);
4993 leps = MIN(MAX(ldiff[0][0],ldiff[0][1]),
4994 MAX(ldiff[1][2],ldiff[1][3]));
4995 abeps = MIN(MAX(abdiff[0][0],abdiff[0][1]),
4996 MAX(abdiff[1][2],abdiff[1][3]));
4997 for (d=0; d < 2; d++)
4998 for (i=0; i < 4; i++)
4999 if (ldiff[d][i] <= leps && abdiff[d][i] <= abeps)
5003 /* Combine the most homogenous pixels for the final result: */
5004 for (row=top+3; row < top+TS-3 && row < height-5; row++) {
5006 for (col=left+3; col < left+TS-3 && col < width-5; col++) {
5008 for (d=0; d < 2; d++)
5009 for (hm[d]=0, i=tr-1; i <= tr+1; i++)
5010 for (j=tc-1; j <= tc+1; j++)
5011 hm[d] += homo[d][i][j];
5013 FORC3 image[row*width+col][c] = rgb[hm[1] > hm[0]][tr][tc][c];
5015 FORC3 image[row*width+col][c] =
5016 (rgb[0][tr][tc][c] + rgb[1][tr][tc][c]) >> 1;
5024 void CLASS median_filter()
5027 int pass, c, i, j, k, med[9];
5028 static const uchar opt[] = /* Optimal 9-element median search */
5029 { 1,2, 4,5, 7,8, 0,1, 3,4, 6,7, 1,2, 4,5, 7,8,
5030 0,3, 5,8, 4,7, 3,6, 1,4, 2,5, 4,7, 4,2, 6,4, 4,2 };
5032 for (pass=1; pass <= med_passes; pass++) {
5034 fprintf (stderr,_("Median filter pass %d...\n"), pass);
5035 for (c=0; c < 3; c+=2) {
5036 for (pix = image; pix < image+width*height; pix++)
5037 pix[0][3] = pix[0][c];
5038 for (pix = image+width; pix < image+width*(height-1); pix++) {
5039 if ((pix-image+1) % width < 2) continue;
5040 for (k=0, i = -width; i <= width; i += width)
5041 for (j = i-1; j <= i+1; j++)
5042 med[k++] = pix[j][3] - pix[j][1];
5043 for (i=0; i < sizeof opt; i+=2)
5044 if (med[opt[i]] > med[opt[i+1]])
5045 SWAP (med[opt[i]] , med[opt[i+1]]);
5046 pix[0][c] = CLIP(med[4] + pix[0][1]);
5052 void CLASS blend_highlights()
5054 int clip=INT_MAX, row, col, c, i, j;
5055 static const float trans[2][4][4] =
5056 { { { 1,1,1 }, { 1.7320508,-1.7320508,0 }, { -1,-1,2 } },
5057 { { 1,1,1,1 }, { 1,-1,1,-1 }, { 1,1,-1,-1 }, { 1,-1,-1,1 } } };
5058 static const float itrans[2][4][4] =
5059 { { { 1,0.8660254,-0.5 }, { 1,-0.8660254,-0.5 }, { 1,0,1 } },
5060 { { 1,1,1,1 }, { 1,-1,1,-1 }, { 1,1,-1,-1 }, { 1,-1,-1,1 } } };
5061 float cam[2][4], lab[2][4], sum[2], chratio;
5063 if ((unsigned) (colors-3) > 1) return;
5064 if (verbose) fprintf (stderr,_("Blending highlights...\n"));
5065 FORCC if (clip > (i = 65535*pre_mul[c])) clip = i;
5066 for (row=0; row < height; row++)
5067 for (col=0; col < width; col++) {
5068 FORCC if (image[row*width+col][c] > clip) break;
5069 if (c == colors) continue;
5071 cam[0][c] = image[row*width+col][c];
5072 cam[1][c] = MIN(cam[0][c],clip);
5074 for (i=0; i < 2; i++) {
5075 FORCC for (lab[i][c]=j=0; j < colors; j++)
5076 lab[i][c] += trans[colors-3][c][j] * cam[i][j];
5077 for (sum[i]=0,c=1; c < colors; c++)
5078 sum[i] += SQR(lab[i][c]);
5080 chratio = sqrt(sum[1]/sum[0]);
5081 for (c=1; c < colors; c++)
5082 lab[0][c] *= chratio;
5083 FORCC for (cam[0][c]=j=0; j < colors; j++)
5084 cam[0][c] += itrans[colors-3][c][j] * lab[0][j];
5085 FORCC image[row*width+col][c] = cam[0][c] / colors;
5089 #define SCALE (4 >> shrink)
5090 void CLASS recover_highlights()
5092 float *map, sum, wgt, grow;
5093 int hsat[4], count, spread, change, val, i;
5094 unsigned high, wide, mrow, mcol, row, col, kc, c, d, y, x;
5096 static const signed char dir[8][2] =
5097 { {-1,-1}, {-1,0}, {-1,1}, {0,1}, {1,1}, {1,0}, {1,-1}, {0,-1} };
5099 if (verbose) fprintf (stderr,_("Rebuilding highlights...\n"));
5101 grow = pow (2, 4-highlight);
5102 FORCC hsat[c] = 32000 * pre_mul[c];
5103 for (kc=0, c=1; c < colors; c++)
5104 if (pre_mul[kc] < pre_mul[c]) kc = c;
5105 high = height / SCALE;
5106 wide = width / SCALE;
5107 map = (float *) calloc (high, wide*sizeof *map);
5108 merror (map, "recover_highlights()");
5109 FORCC if (c != kc) {
5110 memset (map, 0, high*wide*sizeof *map);
5111 for (mrow=0; mrow < high; mrow++)
5112 for (mcol=0; mcol < wide; mcol++) {
5113 sum = wgt = count = 0;
5114 for (row = mrow*SCALE; row < (mrow+1)*SCALE; row++)
5115 for (col = mcol*SCALE; col < (mcol+1)*SCALE; col++) {
5116 pixel = image[row*width+col];
5117 if (pixel[c] / hsat[c] == 1 && pixel[kc] > 24000) {
5123 if (count == SCALE*SCALE)
5124 map[mrow*wide+mcol] = sum / wgt;
5126 for (spread = 32/grow; spread--; ) {
5127 for (mrow=0; mrow < high; mrow++)
5128 for (mcol=0; mcol < wide; mcol++) {
5129 if (map[mrow*wide+mcol]) continue;
5131 for (d=0; d < 8; d++) {
5132 y = mrow + dir[d][0];
5133 x = mcol + dir[d][1];
5134 if (y < high && x < wide && map[y*wide+x] > 0) {
5135 sum += (1 + (d & 1)) * map[y*wide+x];
5136 count += 1 + (d & 1);
5140 map[mrow*wide+mcol] = - (sum+grow) / (count+grow);
5142 for (change=i=0; i < high*wide; i++)
5149 for (i=0; i < high*wide; i++)
5150 if (map[i] == 0) map[i] = 1;
5151 for (mrow=0; mrow < high; mrow++)
5152 for (mcol=0; mcol < wide; mcol++) {
5153 for (row = mrow*SCALE; row < (mrow+1)*SCALE; row++)
5154 for (col = mcol*SCALE; col < (mcol+1)*SCALE; col++) {
5155 pixel = image[row*width+col];
5156 if (pixel[c] / hsat[c] > 1) {
5157 val = pixel[kc] * map[mrow*wide+mcol];
5158 if (pixel[c] < val) pixel[c] = CLIP(val);
5167 void CLASS tiff_get (unsigned base,
5168 unsigned *tag, unsigned *type, unsigned *len, unsigned *save)
5173 *save = ftell(ifp) + 4;
5174 if (*len * ("11124811248484"[*type < 14 ? *type:0]-'0') > 4)
5175 fseek (ifp, get4()+base, SEEK_SET);
5178 void CLASS parse_thumb_note (int base, unsigned toff, unsigned tlen)
5180 unsigned entries, tag, type, len, save;
5184 tiff_get (base, &tag, &type, &len, &save);
5185 if (tag == toff) thumb_offset = get4()+base;
5186 if (tag == tlen) thumb_length = get4();
5187 fseek (ifp, save, SEEK_SET);
5191 int CLASS parse_tiff_ifd (int base);
5193 void CLASS parse_makernote (int base, int uptag)
5195 static const uchar xlat[2][256] = {
5196 { 0xc1,0xbf,0x6d,0x0d,0x59,0xc5,0x13,0x9d,0x83,0x61,0x6b,0x4f,0xc7,0x7f,0x3d,0x3d,
5197 0x53,0x59,0xe3,0xc7,0xe9,0x2f,0x95,0xa7,0x95,0x1f,0xdf,0x7f,0x2b,0x29,0xc7,0x0d,
5198 0xdf,0x07,0xef,0x71,0x89,0x3d,0x13,0x3d,0x3b,0x13,0xfb,0x0d,0x89,0xc1,0x65,0x1f,
5199 0xb3,0x0d,0x6b,0x29,0xe3,0xfb,0xef,0xa3,0x6b,0x47,0x7f,0x95,0x35,0xa7,0x47,0x4f,
5200 0xc7,0xf1,0x59,0x95,0x35,0x11,0x29,0x61,0xf1,0x3d,0xb3,0x2b,0x0d,0x43,0x89,0xc1,
5201 0x9d,0x9d,0x89,0x65,0xf1,0xe9,0xdf,0xbf,0x3d,0x7f,0x53,0x97,0xe5,0xe9,0x95,0x17,
5202 0x1d,0x3d,0x8b,0xfb,0xc7,0xe3,0x67,0xa7,0x07,0xf1,0x71,0xa7,0x53,0xb5,0x29,0x89,
5203 0xe5,0x2b,0xa7,0x17,0x29,0xe9,0x4f,0xc5,0x65,0x6d,0x6b,0xef,0x0d,0x89,0x49,0x2f,
5204 0xb3,0x43,0x53,0x65,0x1d,0x49,0xa3,0x13,0x89,0x59,0xef,0x6b,0xef,0x65,0x1d,0x0b,
5205 0x59,0x13,0xe3,0x4f,0x9d,0xb3,0x29,0x43,0x2b,0x07,0x1d,0x95,0x59,0x59,0x47,0xfb,
5206 0xe5,0xe9,0x61,0x47,0x2f,0x35,0x7f,0x17,0x7f,0xef,0x7f,0x95,0x95,0x71,0xd3,0xa3,
5207 0x0b,0x71,0xa3,0xad,0x0b,0x3b,0xb5,0xfb,0xa3,0xbf,0x4f,0x83,0x1d,0xad,0xe9,0x2f,
5208 0x71,0x65,0xa3,0xe5,0x07,0x35,0x3d,0x0d,0xb5,0xe9,0xe5,0x47,0x3b,0x9d,0xef,0x35,
5209 0xa3,0xbf,0xb3,0xdf,0x53,0xd3,0x97,0x53,0x49,0x71,0x07,0x35,0x61,0x71,0x2f,0x43,
5210 0x2f,0x11,0xdf,0x17,0x97,0xfb,0x95,0x3b,0x7f,0x6b,0xd3,0x25,0xbf,0xad,0xc7,0xc5,
5211 0xc5,0xb5,0x8b,0xef,0x2f,0xd3,0x07,0x6b,0x25,0x49,0x95,0x25,0x49,0x6d,0x71,0xc7 },
5212 { 0xa7,0xbc,0xc9,0xad,0x91,0xdf,0x85,0xe5,0xd4,0x78,0xd5,0x17,0x46,0x7c,0x29,0x4c,
5213 0x4d,0x03,0xe9,0x25,0x68,0x11,0x86,0xb3,0xbd,0xf7,0x6f,0x61,0x22,0xa2,0x26,0x34,
5214 0x2a,0xbe,0x1e,0x46,0x14,0x68,0x9d,0x44,0x18,0xc2,0x40,0xf4,0x7e,0x5f,0x1b,0xad,
5215 0x0b,0x94,0xb6,0x67,0xb4,0x0b,0xe1,0xea,0x95,0x9c,0x66,0xdc,0xe7,0x5d,0x6c,0x05,
5216 0xda,0xd5,0xdf,0x7a,0xef,0xf6,0xdb,0x1f,0x82,0x4c,0xc0,0x68,0x47,0xa1,0xbd,0xee,
5217 0x39,0x50,0x56,0x4a,0xdd,0xdf,0xa5,0xf8,0xc6,0xda,0xca,0x90,0xca,0x01,0x42,0x9d,
5218 0x8b,0x0c,0x73,0x43,0x75,0x05,0x94,0xde,0x24,0xb3,0x80,0x34,0xe5,0x2c,0xdc,0x9b,
5219 0x3f,0xca,0x33,0x45,0xd0,0xdb,0x5f,0xf5,0x52,0xc3,0x21,0xda,0xe2,0x22,0x72,0x6b,
5220 0x3e,0xd0,0x5b,0xa8,0x87,0x8c,0x06,0x5d,0x0f,0xdd,0x09,0x19,0x93,0xd0,0xb9,0xfc,
5221 0x8b,0x0f,0x84,0x60,0x33,0x1c,0x9b,0x45,0xf1,0xf0,0xa3,0x94,0x3a,0x12,0x77,0x33,
5222 0x4d,0x44,0x78,0x28,0x3c,0x9e,0xfd,0x65,0x57,0x16,0x94,0x6b,0xfb,0x59,0xd0,0xc8,
5223 0x22,0x36,0xdb,0xd2,0x63,0x98,0x43,0xa1,0x04,0x87,0x86,0xf7,0xa6,0x26,0xbb,0xd6,
5224 0x59,0x4d,0xbf,0x6a,0x2e,0xaa,0x2b,0xef,0xe6,0x78,0xb6,0x4e,0xe0,0x2f,0xdc,0x7c,
5225 0xbe,0x57,0x19,0x32,0x7e,0x2a,0xd0,0xb8,0xba,0x29,0x00,0x3c,0x52,0x7d,0xa8,0x49,
5226 0x3b,0x2d,0xeb,0x25,0x49,0xfa,0xa3,0xaa,0x39,0xa7,0xc5,0xa7,0x50,0x11,0x36,0xfb,
5227 0xc6,0x67,0x4a,0xf5,0xa5,0x12,0x65,0x7e,0xb0,0xdf,0xaf,0x4e,0xb3,0x61,0x7f,0x2f } };
5228 unsigned offset=0, entries, tag, type, len, save, c;
5229 unsigned ver97=0, serial=0, i, wbi=0, wb[4]={0,0,0,0};
5230 uchar buf97[324], ci, cj, ck;
5231 short morder, sorder=order;
5234 The MakerNote might have its own TIFF header (possibly with
5235 its own byte-order!), or it might just be a table.
5237 if (!strcmp(make,"Nokia")) return;
5238 fread (buf, 1, 10, ifp);
5239 if (!strncmp (buf,"KDK" ,3) || /* these aren't TIFF tables */
5240 !strncmp (buf,"VER" ,3) ||
5241 !strncmp (buf,"IIII",4) ||
5242 !strncmp (buf,"MMMM",4)) return;
5243 if (!strncmp (buf,"KC" ,2) || /* Konica KD-400Z, KD-510Z */
5244 !strncmp (buf,"MLY" ,3)) { /* Minolta DiMAGE G series */
5246 while ((i=ftell(ifp)) < data_offset && i < 16384) {
5247 wb[0] = wb[2]; wb[2] = wb[1]; wb[1] = wb[3];
5249 if (wb[1] == 256 && wb[3] == 256 &&
5250 wb[0] > 256 && wb[0] < 640 && wb[2] > 256 && wb[2] < 640)
5251 FORC4 cam_mul[c] = wb[c];
5255 if (!strcmp (buf,"Nikon")) {
5258 if (get2() != 42) goto quit;
5260 fseek (ifp, offset-8, SEEK_CUR);
5261 } else if (!strcmp (buf,"OLYMPUS") ||
5262 !strcmp (buf,"PENTAX ")) {
5263 base = ftell(ifp)-10;
5264 fseek (ifp, -2, SEEK_CUR);
5266 if (buf[0] == 'O') get2();
5267 } else if (!strncmp (buf,"SONY",4) ||
5268 !strcmp (buf,"Panasonic")) {
5270 } else if (!strncmp (buf,"FUJIFILM",8)) {
5271 base = ftell(ifp)-10;
5273 fseek (ifp, 2, SEEK_CUR);
5274 } else if (!strcmp (buf,"OLYMP") ||
5275 !strcmp (buf,"LEICA") ||
5276 !strcmp (buf,"Ricoh") ||
5277 !strcmp (buf,"EPSON"))
5278 fseek (ifp, -2, SEEK_CUR);
5279 else if (!strcmp (buf,"AOC") ||
5280 !strcmp (buf,"QVC"))
5281 fseek (ifp, -4, SEEK_CUR);
5283 fseek (ifp, -10, SEEK_CUR);
5284 if (!strncmp(make,"SAMSUNG",7))
5288 if (entries > 1000) return;
5292 tiff_get (base, &tag, &type, &len, &save);
5294 if (tag == 2 && strstr(make,"NIKON") && !iso_speed)
5295 iso_speed = (get2(),get2());
5296 if (tag == 4 && len > 26 && len < 35) {
5297 if ((i=(get4(),get2())) != 0x7fff && !iso_speed)
5298 iso_speed = 50 * pow (2, i/32.0 - 4);
5299 if ((i=(get2(),get2())) != 0x7fff && !aperture)
5300 aperture = pow (2, i/64.0);
5301 if ((i=get2()) != 0xffff && !shutter)
5302 shutter = pow (2, (short) i/-32.0);
5303 wbi = (get2(),get2());
5304 shot_order = (get2(),get2());
5306 if ((tag == 4 || tag == 0x114) && !strncmp(make,"KONICA",6)) {
5307 fseek (ifp, tag == 4 ? 140:160, SEEK_CUR);
5309 case 72: flip = 0; break;
5310 case 76: flip = 6; break;
5311 case 82: flip = 5; break;
5314 if (tag == 7 && type == 2 && len > 20)
5315 fgets (model2, 64, ifp);
5316 if (tag == 8 && type == 4)
5317 shot_order = get4();
5318 if (tag == 9 && !strcmp(make,"Canon"))
5319 fread (artist, 64, 1, ifp);
5320 if (tag == 0xc && len == 4)
5321 FORC3 cam_mul[(c << 1 | c >> 1) & 3] = getreal(type);
5322 if (tag == 0xd && type == 7 && get2() == 0xaaaa) {
5323 for (c=i=2; (ushort) c != 0xbbbb && i < len; i++)
5324 c = c << 8 | fgetc(ifp);
5325 while ((i+=4) < len-5)
5326 if (get4() == 257 && (i=len) && (c = (get4(),fgetc(ifp))) < 3)
5327 flip = "065"[c]-'0';
5329 if (tag == 0x10 && type == 4)
5331 if (tag == 0x11 && is_raw && !strncmp(make,"NIKON",5)) {
5332 fseek (ifp, get4()+base, SEEK_SET);
5333 parse_tiff_ifd (base);
5335 if (tag == 0x14 && type == 7) {
5337 fseek (ifp, 1248, SEEK_CUR);
5340 fread (buf, 1, 10, ifp);
5341 if (!strncmp(buf,"NRW ",4)) {
5342 fseek (ifp, strcmp(buf+4,"0100") ? 46:1546, SEEK_CUR);
5343 cam_mul[0] = get4() << 2;
5344 cam_mul[1] = get4() + get4();
5345 cam_mul[2] = get4() << 2;
5348 if (tag == 0x15 && type == 2 && is_raw)
5349 fread (model, 64, 1, ifp);
5350 if (strstr(make,"PENTAX")) {
5351 if (tag == 0x1b) tag = 0x1018;
5352 if (tag == 0x1c) tag = 0x1017;
5355 while ((c = fgetc(ifp)) && c != EOF)
5356 serial = serial*10 + (isdigit(c) ? c - '0' : c % 10);
5357 if (tag == 0x29 && type == 1) {
5358 c = wbi < 18 ? "012347800000005896"[wbi]-'0' : 0;
5359 fseek (ifp, 8 + c*32, SEEK_CUR);
5360 FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get4();
5362 if (tag == 0x3d && type == 3 && len == 4)
5363 FORC4 cblack[c ^ c >> 1] = get2() >> (14-tiff_bps);
5364 if (tag == 0x81 && type == 4) {
5365 data_offset = get4();
5366 fseek (ifp, data_offset + 41, SEEK_SET);
5367 raw_height = get2() * 2;
5369 filters = 0x61616161;
5371 if ((tag == 0x81 && type == 7) ||
5372 (tag == 0x100 && type == 7) ||
5373 (tag == 0x280 && type == 1)) {
5374 thumb_offset = ftell(ifp);
5377 if (tag == 0x88 && type == 4 && (thumb_offset = get4()))
5378 thumb_offset += base;
5379 if (tag == 0x89 && type == 4)
5380 thumb_length = get4();
5381 if (tag == 0x8c || tag == 0x96)
5382 meta_offset = ftell(ifp);
5384 for (i=0; i < 4; i++)
5385 ver97 = ver97 * 10 + fgetc(ifp)-'0';
5388 fseek (ifp, 68, SEEK_CUR);
5389 FORC4 cam_mul[(c >> 1) | ((c & 1) << 1)] = get2();
5392 fseek (ifp, 6, SEEK_CUR);
5393 FORC4 cam_mul[c ^ (c >> 1)] = get2();
5396 fseek (ifp, 16, SEEK_CUR);
5397 FORC4 cam_mul[c] = get2();
5400 if (ver97 != 205) fseek (ifp, 280, SEEK_CUR);
5401 fread (buf97, 324, 1, ifp);
5404 if (tag == 0xa1 && type == 7) {
5406 fseek (ifp, 140, SEEK_CUR);
5407 FORC3 cam_mul[c] = get4();
5409 if (tag == 0xa4 && type == 3) {
5410 fseek (ifp, wbi*48, SEEK_CUR);
5411 FORC3 cam_mul[c] = get2();
5413 if (tag == 0xa7 && (unsigned) (ver97-200) < 17) {
5414 ci = xlat[0][serial & 0xff];
5415 cj = xlat[1][fgetc(ifp)^fgetc(ifp)^fgetc(ifp)^fgetc(ifp)];
5417 for (i=0; i < 324; i++)
5418 buf97[i] ^= (cj += ci * ck++);
5419 i = "66666>666;6A;:;55"[ver97-200] - '0';
5420 FORC4 cam_mul[c ^ (c >> 1) ^ (i & 1)] =
5421 sget2 (buf97 + (i & -2) + c*2);
5423 if (tag == 0x200 && len == 3)
5424 shot_order = (get4(),get4());
5425 if (tag == 0x200 && len == 4)
5426 FORC4 cblack[c ^ c >> 1] = get2();
5427 if (tag == 0x201 && len == 4)
5428 FORC4 cam_mul[c ^ (c >> 1)] = get2();
5429 if (tag == 0x220 && type == 7)
5430 meta_offset = ftell(ifp);
5431 if (tag == 0x401 && type == 4 && len == 4)
5432 FORC4 cblack[c ^ c >> 1] = get4();
5433 if (tag == 0xe01) { /* Nikon Capture Note */
5435 fseek (ifp, 22, SEEK_CUR);
5436 for (offset=22; offset+22 < len; offset += 22+i) {
5438 fseek (ifp, 14, SEEK_CUR);
5440 if (tag == 0x76a43207) flip = get2();
5441 else fseek (ifp, i, SEEK_CUR);
5444 if (tag == 0xe80 && len == 256 && type == 7) {
5445 fseek (ifp, 48, SEEK_CUR);
5446 cam_mul[0] = get2() * 508 * 1.078 / 0x10000;
5447 cam_mul[2] = get2() * 382 * 1.173 / 0x10000;
5449 if (tag == 0xf00 && type == 7) {
5451 fseek (ifp, 176, SEEK_CUR);
5452 else if (len == 734 || len == 1502)
5453 fseek (ifp, 148, SEEK_CUR);
5457 if ((tag == 0x1011 && len == 9) || tag == 0x20400200)
5458 for (i=0; i < 3; i++)
5459 FORC3 cmatrix[i][c] = ((short) get2()) / 256.0;
5460 if ((tag == 0x1012 || tag == 0x20400600) && len == 4)
5461 FORC4 cblack[c ^ c >> 1] = get2();
5462 if (tag == 0x1017 || tag == 0x20400100)
5463 cam_mul[0] = get2() / 256.0;
5464 if (tag == 0x1018 || tag == 0x20400100)
5465 cam_mul[2] = get2() / 256.0;
5466 if (tag == 0x2011 && len == 2) {
5469 cam_mul[0] = get2() / 256.0;
5470 cam_mul[2] = get2() / 256.0;
5472 if ((tag | 0x70) == 0x2070 && (type == 4 || type == 13))
5473 fseek (ifp, get4()+base, SEEK_SET);
5474 if (tag == 0x2020 && !strncmp(buf,"OLYMP",5))
5475 parse_thumb_note (base, 257, 258);
5477 parse_makernote (base, 0x2040);
5478 if (tag == 0xb028) {
5479 fseek (ifp, get4()+base, SEEK_SET);
5480 parse_thumb_note (base, 136, 137);
5482 if (tag == 0x4001 && len > 500) {
5483 i = len == 582 ? 50 : len == 653 ? 68 : len == 5120 ? 142 : 126;
5484 fseek (ifp, i, SEEK_CUR);
5485 FORC4 cam_mul[c ^ (c >> 1)] = get2();
5486 for (i+=18; i <= len; i+=10) {
5488 FORC4 sraw_mul[c ^ (c >> 1)] = get2();
5489 if (sraw_mul[1] == 1170) break;
5492 if (tag == 0x4021 && get4() && get4())
5493 FORC4 cam_mul[c] = 1024;
5495 FORC4 cam_mul[c ^ (c >> 1)] = get4();
5497 FORC4 cam_mul[c ^ (c >> 1)] -= get4();
5501 fseek (ifp, save, SEEK_SET);
5508 Since the TIFF DateTime string has no timezone information,
5509 assume that the camera's clock was set to Universal Time.
5511 void CLASS get_timestamp (int reversed)
5519 for (i=19; i--; ) str[i] = fgetc(ifp);
5521 fread (str, 19, 1, ifp);
5522 memset (&t, 0, sizeof t);
5523 if (sscanf (str, "%d:%d:%d %d:%d:%d", &t.tm_year, &t.tm_mon,
5524 &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec) != 6)
5530 timestamp = mktime(&t);
5533 void CLASS parse_exif (int base)
5535 unsigned kodak, entries, tag, type, len, save, c;
5538 kodak = !strncmp(make,"EASTMAN",7) && tiff_nifds < 3;
5541 tiff_get (base, &tag, &type, &len, &save);
5543 case 33434: tiff_ifd[tiff_nifds-1].shutter =
5544 shutter = getreal(type); break;
5545 case 33437: aperture = getreal(type); break;
5546 case 34855: iso_speed = get2(); break;
5548 case 36868: get_timestamp(0); break;
5549 case 37377: if ((expo = -getreal(type)) < 128)
5550 tiff_ifd[tiff_nifds-1].shutter =
5551 shutter = pow (2, expo); break;
5552 case 37378: aperture = pow (2, getreal(type)/2); break;
5553 case 37386: focal_len = getreal(type); break;
5554 case 37500: parse_makernote (base, 0); break;
5555 case 40962: if (kodak) raw_width = get4(); break;
5556 case 40963: if (kodak) raw_height = get4(); break;
5558 if (get4() == 0x20002)
5559 for (exif_cfa=c=0; c < 8; c+=2)
5560 exif_cfa |= fgetc(ifp) * 0x01010101 << c;
5562 fseek (ifp, save, SEEK_SET);
5566 void CLASS parse_gps (int base)
5568 unsigned entries, tag, type, len, save, c;
5572 tiff_get (base, &tag, &type, &len, &save);
5574 case 1: case 3: case 5:
5575 gpsdata[29+tag/2] = getc(ifp); break;
5576 case 2: case 4: case 7:
5577 FORC(6) gpsdata[tag/3*6+c] = get4(); break;
5579 FORC(2) gpsdata[18+c] = get4(); break;
5581 fgets ((char *) (gpsdata+14+tag/3), MIN(len,12), ifp);
5583 fseek (ifp, save, SEEK_SET);
5587 void CLASS romm_coeff (float romm_cam[3][3])
5589 static const float rgb_romm[3][3] = /* ROMM == Kodak ProPhoto */
5590 { { 2.034193, -0.727420, -0.306766 },
5591 { -0.228811, 1.231729, -0.002922 },
5592 { -0.008565, -0.153273, 1.161839 } };
5595 for (i=0; i < 3; i++)
5596 for (j=0; j < 3; j++)
5597 for (cmatrix[i][j] = k=0; k < 3; k++)
5598 cmatrix[i][j] += rgb_romm[i][k] * romm_cam[k][j];
5601 void CLASS parse_mos (int offset)
5604 int skip, from, i, c, neut[4], planes=0, frot=0;
5605 static const char *mod[] =
5606 { "","DCB2","Volare","Cantare","CMost","Valeo 6","Valeo 11","Valeo 22",
5607 "Valeo 11p","Valeo 17","","Aptus 17","Aptus 22","Aptus 75","Aptus 65",
5608 "Aptus 54S","Aptus 65S","Aptus 75S","AFi 5","AFi 6","AFi 7",
5609 "AFi-II 7","Aptus-II 7","","Aptus-II 6","","","Aptus-II 10","Aptus-II 5",
5610 "","","","","Aptus-II 10R","Aptus-II 8","","Aptus-II 12","","AFi-II 12" };
5611 float romm_cam[3][3];
5613 fseek (ifp, offset, SEEK_SET);
5615 if (get4() != 0x504b5453) break;
5617 fread (data, 1, 40, ifp);
5620 if (!strcmp(data,"JPEG_preview_data")) {
5621 thumb_offset = from;
5622 thumb_length = skip;
5624 if (!strcmp(data,"icc_camera_profile")) {
5625 profile_offset = from;
5626 profile_length = skip;
5628 if (!strcmp(data,"ShootObj_back_type")) {
5629 fscanf (ifp, "%d", &i);
5630 if ((unsigned) i < sizeof mod / sizeof (*mod))
5631 strcpy (model, mod[i]);
5633 if (!strcmp(data,"icc_camera_to_tone_matrix")) {
5634 for (i=0; i < 9; i++)
5635 ((float *)romm_cam)[i] = int_to_float(get4());
5636 romm_coeff (romm_cam);
5638 if (!strcmp(data,"CaptProf_color_matrix")) {
5639 for (i=0; i < 9; i++)
5640 fscanf (ifp, "%f", (float *)romm_cam + i);
5641 romm_coeff (romm_cam);
5643 if (!strcmp(data,"CaptProf_number_of_planes"))
5644 fscanf (ifp, "%d", &planes);
5645 if (!strcmp(data,"CaptProf_raw_data_rotation"))
5646 fscanf (ifp, "%d", &flip);
5647 if (!strcmp(data,"CaptProf_mosaic_pattern"))
5649 fscanf (ifp, "%d", &i);
5650 if (i == 1) frot = c ^ (c >> 1);
5652 if (!strcmp(data,"ImgProf_rotation_angle")) {
5653 fscanf (ifp, "%d", &i);
5656 if (!strcmp(data,"NeutObj_neutrals") && !cam_mul[0]) {
5657 FORC4 fscanf (ifp, "%d", neut+c);
5658 FORC3 cam_mul[c] = (float) neut[0] / neut[c+1];
5660 if (!strcmp(data,"Rows_data"))
5661 load_flags = get4();
5663 fseek (ifp, skip+from, SEEK_SET);
5666 filters = (planes == 1) * 0x01010101 *
5667 (uchar) "\x94\x61\x16\x49"[(flip/90 + frot) & 3];
5670 void CLASS linear_table (unsigned len)
5673 if (len > 0x1000) len = 0x1000;
5674 read_shorts (curve, len);
5675 for (i=len; i < 0x1000; i++)
5676 curve[i] = curve[i-1];
5677 maximum = curve[0xfff];
5680 void CLASS parse_kodak_ifd (int base)
5682 unsigned entries, tag, type, len, save;
5683 int i, c, wbi=-2, wbtemp=6500;
5684 float mul[3]={1,1,1}, num;
5685 static const int wbtag[] = { 64037,64040,64039,64041,-1,-1,64042 };
5688 if (entries > 1024) return;
5690 tiff_get (base, &tag, &type, &len, &save);
5691 if (tag == 1020) wbi = getint(type);
5692 if (tag == 1021 && len == 72) { /* WB set in software */
5693 fseek (ifp, 40, SEEK_CUR);
5694 FORC3 cam_mul[c] = 2048.0 / get2();
5697 if (tag == 2118) wbtemp = getint(type);
5698 if (tag == 2120 + wbi && wbi >= 0)
5699 FORC3 cam_mul[c] = 2048.0 / getreal(type);
5700 if (tag == 2130 + wbi)
5701 FORC3 mul[c] = getreal(type);
5702 if (tag == 2140 + wbi && wbi >= 0)
5704 for (num=i=0; i < 4; i++)
5705 num += getreal(type) * pow (wbtemp/100.0, i);
5706 cam_mul[c] = 2048 / (num * mul[c]);
5708 if (tag == 2317) linear_table (len);
5709 if (tag == 6020) iso_speed = getint(type);
5710 if (tag == 64013) wbi = fgetc(ifp);
5711 if ((unsigned) wbi < 7 && tag == wbtag[wbi])
5712 FORC3 cam_mul[c] = get4();
5713 if (tag == 64019) width = getint(type);
5714 if (tag == 64020) height = (getint(type)+1) & -2;
5715 fseek (ifp, save, SEEK_SET);
5719 void CLASS parse_minolta (int base);
5720 int CLASS parse_tiff (int base);
5722 int CLASS parse_tiff_ifd (int base)
5724 unsigned entries, tag, type, len, plen=16, save;
5725 int ifd, use_cm=0, cfa, i, j, c, ima_len=0;
5726 char software[64], *cbuf, *cp;
5727 uchar cfa_pat[16], cfa_pc[] = { 0,1,2,3 }, tab[256];
5728 double cc[4][4], cm[4][3], cam_xyz[4][3], num;
5729 double ab[]={ 1,1,1,1 }, asn[] = { 0,0,0,0 }, xyz[] = { 1,1,1 };
5730 unsigned sony_curve[] = { 0,0,0,0,0,4095 };
5731 unsigned *buf, sony_offset=0, sony_length=0, sony_key=0;
5735 if (tiff_nifds >= sizeof tiff_ifd / sizeof tiff_ifd[0])
5738 for (j=0; j < 4; j++)
5739 for (i=0; i < 4; i++)
5742 if (entries > 512) return 1;
5744 tiff_get (base, &tag, &type, &len, &save);
5746 case 5: width = get2(); break;
5747 case 6: height = get2(); break;
5748 case 7: width += get2(); break;
5749 case 9: if ((i = get2())) filters = i; break;
5751 if (type == 3 && len == 1)
5752 cam_mul[(tag-17)*2] = get2() / 256.0;
5755 if (type == 3) iso_speed = get2();
5757 case 28: case 29: case 30:
5758 cblack[tag-28] = get2();
5759 cblack[3] = cblack[1];
5761 case 36: case 37: case 38:
5762 cam_mul[tag-36] = get2();
5765 if (len < 50 || cam_mul[0]) break;
5766 fseek (ifp, 12, SEEK_CUR);
5767 FORC3 cam_mul[c] = get2();
5770 if (type != 7 || fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) break;
5771 thumb_offset = ftell(ifp) - 2;
5774 case 61440: /* Fuji HS10 table */
5775 fseek (ifp, get4()+base, SEEK_SET);
5776 parse_tiff_ifd (base);
5778 case 2: case 256: case 61441: /* ImageWidth */
5779 tiff_ifd[ifd].width = getint(type);
5781 case 3: case 257: case 61442: /* ImageHeight */
5782 tiff_ifd[ifd].height = getint(type);
5784 case 258: /* BitsPerSample */
5786 tiff_ifd[ifd].samples = len & 7;
5787 tiff_ifd[ifd].bps = getint(type);
5788 if (tiff_bps < tiff_ifd[ifd].bps)
5789 tiff_bps = tiff_ifd[ifd].bps;
5793 if (tiff_ifd[ifd].bps > 12) break;
5794 load_raw = &CLASS packed_load_raw;
5795 load_flags = get4() ? 24:80;
5797 case 259: /* Compression */
5798 tiff_ifd[ifd].comp = getint(type);
5800 case 262: /* PhotometricInterpretation */
5801 tiff_ifd[ifd].phint = get2();
5803 case 270: /* ImageDescription */
5804 fread (desc, 512, 1, ifp);
5806 case 271: /* Make */
5807 fgets (make, 64, ifp);
5809 case 272: /* Model */
5810 fgets (model, 64, ifp);
5812 case 280: /* Panasonic RW2 offset */
5813 if (type != 4) break;
5814 load_raw = &CLASS panasonic_load_raw;
5815 load_flags = 0x2008;
5816 case 273: /* StripOffset */
5817 case 513: /* JpegIFOffset */
5819 tiff_ifd[ifd].offset = get4()+base;
5820 if (!tiff_ifd[ifd].bps && tiff_ifd[ifd].offset > 0) {
5821 fseek (ifp, tiff_ifd[ifd].offset, SEEK_SET);
5822 if (ljpeg_start (&jh, 1)) {
5823 tiff_ifd[ifd].comp = 6;
5824 tiff_ifd[ifd].width = jh.wide;
5825 tiff_ifd[ifd].height = jh.high;
5826 tiff_ifd[ifd].bps = jh.bits;
5827 tiff_ifd[ifd].samples = jh.clrs;
5828 if (!(jh.sraw || (jh.clrs & 1)))
5829 tiff_ifd[ifd].width *= jh.clrs;
5830 if ((tiff_ifd[ifd].width > 4*tiff_ifd[ifd].height) & ~jh.clrs) {
5831 tiff_ifd[ifd].width /= 2;
5832 tiff_ifd[ifd].height *= 2;
5835 parse_tiff (tiff_ifd[ifd].offset + 12);
5840 case 274: /* Orientation */
5841 tiff_ifd[ifd].flip = "50132467"[get2() & 7]-'0';
5843 case 277: /* SamplesPerPixel */
5844 tiff_ifd[ifd].samples = getint(type) & 7;
5846 case 279: /* StripByteCounts */
5849 tiff_ifd[ifd].bytes = get4();
5852 FORC3 cam_mul[(4-c) % 3] = getint(type);
5854 case 305: case 11: /* Software */
5855 fgets (software, 64, ifp);
5856 if (!strncmp(software,"Adobe",5) ||
5857 !strncmp(software,"dcraw",5) ||
5858 !strncmp(software,"UFRaw",5) ||
5859 !strncmp(software,"Bibble",6) ||
5860 !strncmp(software,"Nikon Scan",10) ||
5861 !strcmp (software,"Digital Photo Professional"))
5864 case 306: /* DateTime */
5867 case 315: /* Artist */
5868 fread (artist, 64, 1, ifp);
5870 case 322: /* TileWidth */
5871 tiff_ifd[ifd].tile_width = getint(type);
5873 case 323: /* TileLength */
5874 tiff_ifd[ifd].tile_length = getint(type);
5876 case 324: /* TileOffsets */
5877 tiff_ifd[ifd].offset = len > 1 ? ftell(ifp) : get4();
5879 tiff_ifd[ifd].tile_width = tiff_ifd[ifd].tile_length = 0;
5881 load_raw = &CLASS sinar_4shot_load_raw;
5885 case 330: /* SubIFDs */
5886 if (!strcmp(model,"DSLR-A100") && tiff_ifd[ifd].width == 3872) {
5887 load_raw = &CLASS sony_arw_load_raw;
5888 data_offset = get4()+base;
5893 fseek (ifp, get4()+base, SEEK_SET);
5894 if (parse_tiff_ifd (base)) break;
5895 fseek (ifp, i+4, SEEK_SET);
5899 strcpy (make, "Sarnoff");
5903 FORC4 sony_curve[c+1] = get2() >> 2 & 0xfff;
5904 for (i=0; i < 5; i++)
5905 for (j = sony_curve[i]+1; j <= sony_curve[i+1]; j++)
5906 curve[j] = curve[j-1] + (1 << i);
5908 case 29184: sony_offset = get4(); break;
5909 case 29185: sony_length = get4(); break;
5910 case 29217: sony_key = get4(); break;
5912 parse_minolta (ftell(ifp));
5916 FORC4 cam_mul[c ^ (c < 2)] = get2();
5919 FORC4 cam_mul[c] = get2();
5920 i = (cam_mul[1] == 1024 && cam_mul[2] == 1024) << 1;
5921 SWAP (cam_mul[i],cam_mul[i+1])
5923 case 33405: /* Model2 */
5924 fgets (model2, 64, ifp);
5926 case 33421: /* CFARepeatPatternDim */
5927 if (get2() == 6 && get2() == 6)
5930 case 33422: /* CFAPattern */
5932 FORC(36) ((char *)xtrans)[c] = fgetc(ifp) & 3;
5935 case 64777: /* Kodak P-series */
5936 if ((plen=len) > 16) plen = 16;
5937 fread (cfa_pat, 1, plen, ifp);
5938 for (colors=cfa=i=0; i < plen && colors < 4; i++) {
5939 colors += !(cfa & (1 << cfa_pat[i]));
5940 cfa |= 1 << cfa_pat[i];
5942 if (cfa == 070) memcpy (cfa_pc,"\003\004\005",3); /* CMY */
5943 if (cfa == 072) memcpy (cfa_pc,"\005\003\004\001",4); /* GMCY */
5947 fseek (ifp, get4()+base, SEEK_SET);
5948 parse_kodak_ifd (base);
5950 case 33434: /* ExposureTime */
5951 tiff_ifd[ifd].shutter = shutter = getreal(type);
5953 case 33437: /* FNumber */
5954 aperture = getreal(type);
5956 case 34306: /* Leaf white balance */
5957 FORC4 cam_mul[c ^ 1] = 4096.0 / get2();
5959 case 34307: /* Leaf CatchLight color matrix */
5960 fread (software, 1, 7, ifp);
5961 if (strncmp(software,"MATRIX",6)) break;
5963 for (raw_color = i=0; i < 3; i++) {
5964 FORC4 fscanf (ifp, "%f", &rgb_cam[i][c^1]);
5965 if (!use_camera_wb) continue;
5967 FORC4 num += rgb_cam[i][c];
5968 FORC4 rgb_cam[i][c] /= num;
5971 case 34310: /* Leaf metadata */
5972 parse_mos (ftell(ifp));
5974 strcpy (make, "Leaf");
5976 case 34665: /* EXIF tag */
5977 fseek (ifp, get4()+base, SEEK_SET);
5980 case 34853: /* GPSInfo tag */
5981 fseek (ifp, get4()+base, SEEK_SET);
5984 case 34675: /* InterColorProfile */
5985 case 50831: /* AsShotICCProfile */
5986 profile_offset = ftell(ifp);
5987 profile_length = len;
5989 case 37122: /* CompressedBitsPerPixel */
5990 kodak_cbpp = get4();
5992 case 37386: /* FocalLength */
5993 focal_len = getreal(type);
5995 case 37393: /* ImageNumber */
5996 shot_order = getint(type);
5998 case 37400: /* old Kodak KDC tag */
5999 for (raw_color = i=0; i < 3; i++) {
6001 FORC3 rgb_cam[i][c] = getreal(type);
6005 strip_offset = get4();
6006 switch (tiff_ifd[ifd].comp) {
6007 case 32770: load_raw = &CLASS samsung_load_raw; break;
6008 case 32772: load_raw = &CLASS samsung2_load_raw; break;
6009 case 32773: load_raw = &CLASS samsung3_load_raw; break;
6012 case 46275: /* Imacon tags */
6013 strcpy (make, "Imacon");
6014 data_offset = ftell(ifp);
6018 if (!ima_len) break;
6019 fseek (ifp, 38, SEEK_CUR);
6021 fseek (ifp, 40, SEEK_CUR);
6023 raw_height = get4();
6024 left_margin = get4() & 7;
6025 width = raw_width - left_margin - (get4() & 7);
6026 top_margin = get4() & 7;
6027 height = raw_height - top_margin - (get4() & 7);
6028 if (raw_width == 7262) {
6033 fseek (ifp, 52, SEEK_CUR);
6034 FORC3 cam_mul[c] = getreal(11);
6035 fseek (ifp, 114, SEEK_CUR);
6036 flip = (get2() >> 7) * 90;
6037 if (width * height * 6 == ima_len) {
6038 if (flip % 180 == 90) SWAP(width,height);
6040 raw_height = height;
6041 left_margin = top_margin = filters = flip = 0;
6043 sprintf (model, "Ixpress %d-Mp", height*width/1000000);
6044 load_raw = &CLASS imacon_full_load_raw;
6046 if (left_margin & 1) filters = 0x61616161;
6047 load_raw = &CLASS unpacked_load_raw;
6051 case 50454: /* Sinar tag */
6053 if (!(cbuf = (char *) malloc(len))) break;
6054 fread (cbuf, 1, len, ifp);
6055 for (cp = cbuf-1; cp && cp < cbuf+len; cp = strchr(cp,'\n'))
6056 if (!strncmp (++cp,"Neutral ",8))
6057 sscanf (cp+8, "%f %f %f", cam_mul, cam_mul+1, cam_mul+2);
6061 if (!make[0]) strcpy (make, "Hasselblad");
6063 case 50459: /* Hasselblad tag */
6068 fseek (ifp, j+(get2(),get4()), SEEK_SET);
6074 case 50706: /* DNGVersion */
6075 FORC4 dng_version = (dng_version << 8) + fgetc(ifp);
6076 if (!make[0]) strcpy (make, "DNG");
6079 case 50708: /* UniqueCameraModel */
6080 if (model[0]) break;
6081 fgets (make, 64, ifp);
6082 if ((cp = strchr(make,' '))) {
6087 case 50710: /* CFAPlaneColor */
6088 if (filters == 9) break;
6089 if (len > 4) len = 4;
6091 fread (cfa_pc, 1, colors, ifp);
6093 FORCC tab[cfa_pc[c]] = c;
6096 filters = filters << 2 | tab[cfa_pat[i % plen]];
6097 filters -= !filters;
6099 case 50711: /* CFALayout */
6100 if (get2() == 2) fuji_width = 1;
6103 case 50712: /* LinearizationTable */
6106 case 50713: /* BlackLevelRepeatDim */
6109 if (cblack[4] * cblack[5] > sizeof cblack / sizeof *cblack - 6)
6110 cblack[4] = cblack[5] = 1;
6113 cblack[4] = cblack[5] = MIN(sqrt(len),64);
6114 case 50714: /* BlackLevel */
6115 if (!(cblack[4] * cblack[5]))
6116 cblack[4] = cblack[5] = 1;
6117 FORC (cblack[4] * cblack[5])
6118 cblack[6+c] = getreal(type);
6121 case 50715: /* BlackLevelDeltaH */
6122 case 50716: /* BlackLevelDeltaV */
6123 for (num=i=0; i < (len & 0xffff); i++)
6124 num += getreal(type);
6125 black += num/len + 0.5;
6127 case 50717: /* WhiteLevel */
6128 maximum = getint(type);
6130 case 50718: /* DefaultScale */
6131 pixel_aspect = getreal(type);
6132 pixel_aspect /= getreal(type);
6134 case 50721: /* ColorMatrix1 */
6135 case 50722: /* ColorMatrix2 */
6136 FORCC for (j=0; j < 3; j++)
6137 cm[c][j] = getreal(type);
6140 case 50723: /* CameraCalibration1 */
6141 case 50724: /* CameraCalibration2 */
6142 for (i=0; i < colors; i++)
6143 FORCC cc[i][c] = getreal(type);
6145 case 50727: /* AnalogBalance */
6146 FORCC ab[c] = getreal(type);
6148 case 50728: /* AsShotNeutral */
6149 FORCC asn[c] = getreal(type);
6151 case 50729: /* AsShotWhiteXY */
6152 xyz[0] = getreal(type);
6153 xyz[1] = getreal(type);
6154 xyz[2] = 1 - xyz[0] - xyz[1];
6155 FORC3 xyz[c] /= d65_white[c];
6157 case 50740: /* DNGPrivateData */
6158 if (dng_version) break;
6159 parse_minolta (j = get4()+base);
6160 fseek (ifp, j, SEEK_SET);
6161 parse_tiff_ifd (base);
6164 read_shorts (cr2_slice, 3);
6166 case 50829: /* ActiveArea */
6167 top_margin = getint(type);
6168 left_margin = getint(type);
6169 height = getint(type) - top_margin;
6170 width = getint(type) - left_margin;
6172 case 50830: /* MaskedAreas */
6173 for (i=0; i < len && i < 32; i++)
6174 ((int *)mask)[i] = getint(type);
6177 case 51009: /* OpcodeList2 */
6178 meta_offset = ftell(ifp);
6180 case 64772: /* Kodak P-series */
6181 if (len < 13) break;
6182 fseek (ifp, 16, SEEK_CUR);
6183 data_offset = get4();
6184 fseek (ifp, 28, SEEK_CUR);
6185 data_offset += get4();
6186 load_raw = &CLASS packed_load_raw;
6189 if (type == 2) fgets (model2, 64, ifp);
6191 fseek (ifp, save, SEEK_SET);
6193 if (sony_length && (buf = (unsigned *) malloc(sony_length))) {
6194 fseek (ifp, sony_offset, SEEK_SET);
6195 fread (buf, sony_length, 1, ifp);
6196 sony_decrypt (buf, sony_length/4, 1, sony_key);
6198 if ((ifp = tmpfile())) {
6199 fwrite (buf, sony_length, 1, ifp);
6200 fseek (ifp, 0, SEEK_SET);
6201 parse_tiff_ifd (-sony_offset);
6207 for (i=0; i < colors; i++)
6208 FORCC cc[i][c] *= ab[i];
6210 FORCC for (i=0; i < 3; i++)
6211 for (cam_xyz[c][i]=j=0; j < colors; j++)
6212 cam_xyz[c][i] += cc[c][j] * cm[j][i] * xyz[i];
6213 cam_xyz_coeff (cmatrix, cam_xyz);
6217 FORCC cam_mul[c] = 1 / asn[c];
6220 FORCC pre_mul[c] /= cc[c][c];
6224 int CLASS parse_tiff (int base)
6228 fseek (ifp, base, SEEK_SET);
6230 if (order != 0x4949 && order != 0x4d4d) return 0;
6232 while ((doff = get4())) {
6233 fseek (ifp, doff+base, SEEK_SET);
6234 if (parse_tiff_ifd (base)) break;
6239 void CLASS apply_tiff()
6241 int max_samp=0, ties=0, os, ns, raw=-1, thm=-1, i;
6246 fseek (ifp, thumb_offset, SEEK_SET);
6247 if (ljpeg_start (&jh, 1)) {
6248 thumb_misc = jh.bits;
6249 thumb_width = jh.wide;
6250 thumb_height = jh.high;
6253 for (i=tiff_nifds; i--; ) {
6254 if (tiff_ifd[i].shutter)
6255 shutter = tiff_ifd[i].shutter;
6256 tiff_ifd[i].shutter = shutter;
6258 for (i=0; i < tiff_nifds; i++) {
6259 if (max_samp < tiff_ifd[i].samples)
6260 max_samp = tiff_ifd[i].samples;
6261 if (max_samp > 3) max_samp = 3;
6262 os = raw_width*raw_height;
6263 ns = tiff_ifd[i].width*tiff_ifd[i].height;
6266 ns *= tiff_ifd[i].bps;
6268 if ((tiff_ifd[i].comp != 6 || tiff_ifd[i].samples != 3) &&
6269 (tiff_ifd[i].width | tiff_ifd[i].height) < 0x10000 &&
6270 ns && ((ns > os && (ties = 1)) ||
6271 (ns == os && shot_select == ties++))) {
6272 raw_width = tiff_ifd[i].width;
6273 raw_height = tiff_ifd[i].height;
6274 tiff_bps = tiff_ifd[i].bps;
6275 tiff_compress = tiff_ifd[i].comp;
6276 data_offset = tiff_ifd[i].offset;
6277 tiff_flip = tiff_ifd[i].flip;
6278 tiff_samples = tiff_ifd[i].samples;
6279 tile_width = tiff_ifd[i].tile_width;
6280 tile_length = tiff_ifd[i].tile_length;
6281 shutter = tiff_ifd[i].shutter;
6285 if (is_raw == 1 && ties) is_raw = ties;
6286 if (!tile_width ) tile_width = INT_MAX;
6287 if (!tile_length) tile_length = INT_MAX;
6288 for (i=tiff_nifds; i--; )
6289 if (tiff_ifd[i].flip) tiff_flip = tiff_ifd[i].flip;
6290 if (raw >= 0 && !load_raw)
6291 switch (tiff_compress) {
6293 if (tiff_ifd[raw].bytes == raw_width*raw_height) {
6295 load_raw = &CLASS sony_arw2_load_raw; break;
6297 if (tiff_ifd[raw].bytes*8 != raw_width*raw_height*tiff_bps) {
6299 load_raw = &CLASS sony_arw_load_raw; break;
6305 case 32773: goto slr;
6307 if (!strncmp(make,"OLYMPUS",7) &&
6308 tiff_ifd[raw].bytes*2 == raw_width*raw_height*3)
6310 if (tiff_ifd[raw].bytes*5 == raw_width*raw_height*8) {
6315 case 8: load_raw = &CLASS eight_bit_load_raw; break;
6316 case 12: if (tiff_ifd[raw].phint == 2)
6318 load_raw = &CLASS packed_load_raw; break;
6319 case 14: load_flags = 0;
6320 case 16: load_raw = &CLASS unpacked_load_raw;
6321 if (!strncmp(make,"OLYMPUS",7) &&
6322 tiff_ifd[raw].bytes*7 > raw_width*raw_height)
6323 load_raw = &CLASS olympus_load_raw;
6326 case 6: case 7: case 99:
6327 load_raw = &CLASS lossless_jpeg_load_raw; break;
6329 load_raw = &CLASS kodak_262_load_raw; break;
6331 if ((raw_width+9)/10*16*raw_height == tiff_ifd[raw].bytes) {
6332 load_raw = &CLASS packed_load_raw;
6334 } else if (raw_width*raw_height*3 == tiff_ifd[raw].bytes*2) {
6335 load_raw = &CLASS packed_load_raw;
6336 if (model[0] == 'N') load_flags = 80;
6337 } else if (raw_width*raw_height*3 == tiff_ifd[raw].bytes) {
6338 load_raw = &CLASS nikon_yuv_load_raw;
6339 gamma_curve (1/2.4, 12.92, 1, 4095);
6340 memset (cblack, 0, sizeof cblack);
6342 } else if (raw_width*raw_height*2 == tiff_ifd[raw].bytes) {
6343 load_raw = &CLASS unpacked_load_raw;
6347 load_raw = &CLASS nikon_load_raw; break;
6349 load_raw = &CLASS pentax_load_raw; break;
6351 switch (tiff_ifd[raw].phint) {
6352 case 2: load_raw = &CLASS kodak_rgb_load_raw; filters = 0; break;
6353 case 6: load_raw = &CLASS kodak_ycbcr_load_raw; filters = 0; break;
6354 case 32803: load_raw = &CLASS kodak_65000_load_raw;
6356 case 32867: case 34892: break;
6357 default: is_raw = 0;
6360 if ( (tiff_samples == 3 && tiff_ifd[raw].bytes && tiff_bps != 14 &&
6361 (tiff_compress & -16) != 32768)
6362 || (tiff_bps == 8 && strncmp(make,"Phase",5) &&
6363 !strcasestr(make,"Kodak") && !strstr(model2,"DEBUG RAW")))
6365 for (i=0; i < tiff_nifds; i++)
6366 if (i != raw && tiff_ifd[i].samples == max_samp &&
6367 tiff_ifd[i].width * tiff_ifd[i].height / (SQR(tiff_ifd[i].bps)+1) >
6368 thumb_width * thumb_height / (SQR(thumb_misc)+1)
6369 && tiff_ifd[i].comp != 34892) {
6370 thumb_width = tiff_ifd[i].width;
6371 thumb_height = tiff_ifd[i].height;
6372 thumb_offset = tiff_ifd[i].offset;
6373 thumb_length = tiff_ifd[i].bytes;
6374 thumb_misc = tiff_ifd[i].bps;
6378 thumb_misc |= tiff_ifd[thm].samples << 5;
6379 switch (tiff_ifd[thm].comp) {
6381 write_thumb = &CLASS layer_thumb;
6384 if (tiff_ifd[thm].bps <= 8)
6385 write_thumb = &CLASS ppm_thumb;
6386 else if (!strcmp(make,"Imacon"))
6387 write_thumb = &CLASS ppm16_thumb;
6389 thumb_load_raw = &CLASS kodak_thumb_load_raw;
6392 thumb_load_raw = tiff_ifd[thm].phint == 6 ?
6393 &CLASS kodak_ycbcr_load_raw : &CLASS kodak_rgb_load_raw;
6398 void CLASS parse_minolta (int base)
6400 int save, tag, len, offset, high=0, wide=0, i, c;
6403 fseek (ifp, base, SEEK_SET);
6404 if (fgetc(ifp) || fgetc(ifp)-'M' || fgetc(ifp)-'R') return;
6405 order = fgetc(ifp) * 0x101;
6406 offset = base + get4() + 8;
6407 while ((save=ftell(ifp)) < offset) {
6408 for (tag=i=0; i < 4; i++)
6409 tag = tag << 8 | fgetc(ifp);
6412 case 0x505244: /* PRD */
6413 fseek (ifp, 8, SEEK_CUR);
6417 case 0x574247: /* WBG */
6419 i = strcmp(model,"DiMAGE A200") ? 0:3;
6420 FORC4 cam_mul[c ^ (c >> 1) ^ i] = get2();
6422 case 0x545457: /* TTW */
6423 parse_tiff (ftell(ifp));
6424 data_offset = offset;
6426 fseek (ifp, save+len+8, SEEK_SET);
6434 Many cameras have a "debug mode" that writes JPEG and raw
6435 at the same time. The raw file has no header, so try to
6436 to open the matching JPEG file and read its metadata.
6438 void CLASS parse_external_jpeg()
6440 const char *file, *ext;
6441 char *jname, *jfile, *jext;
6444 ext = strrchr (ifname, '.');
6445 file = strrchr (ifname, '/');
6446 if (!file) file = strrchr (ifname, '\\');
6447 if (!file) file = ifname-1;
6449 if (!ext || strlen(ext) != 4 || ext-file != 8) return;
6450 jname = (char *) malloc (strlen(ifname) + 1);
6451 merror (jname, "parse_external_jpeg()");
6452 strcpy (jname, ifname);
6453 jfile = file - ifname + jname;
6454 jext = ext - ifname + jname;
6455 if (strcasecmp (ext, ".jpg")) {
6456 strcpy (jext, isupper(ext[1]) ? ".JPG":".jpg");
6457 if (isdigit(*file)) {
6458 memcpy (jfile, file+4, 4);
6459 memcpy (jfile+4, file, 4);
6462 while (isdigit(*--jext)) {
6469 if (strcmp (jname, ifname)) {
6470 if ((ifp = fopen (jname, "rb"))) {
6472 fprintf (stderr,_("Reading metadata from %s ...\n"), jname);
6480 fprintf (stderr,_("Failed to read metadata from %s\n"), jname);
6486 CIFF block 0x1030 contains an 8x8 white sample.
6487 Load this into white[][] for use in scale_colors().
6489 void CLASS ciff_block_1030()
6491 static const ushort key[] = { 0x410, 0x45f3 };
6492 int i, bpp, row, col, vbits=0;
6493 unsigned long bitbuf=0;
6495 if ((get2(),get4()) != 0x80008 || !get4()) return;
6497 if (bpp != 10 && bpp != 12) return;
6498 for (i=row=0; row < 8; row++)
6499 for (col=0; col < 8; col++) {
6501 bitbuf = bitbuf << 16 | (get2() ^ key[i++ & 1]);
6504 white[row][col] = bitbuf >> (vbits -= bpp) & ~(-1 << bpp);
6509 Parse a CIFF file, better known as Canon CRW format.
6511 void CLASS parse_ciff (int offset, int length, int depth)
6513 int tboff, nrecs, c, type, len, save, wbi=-1;
6514 ushort key[] = { 0x410, 0x45f3 };
6516 fseek (ifp, offset+length-4, SEEK_SET);
6517 tboff = get4() + offset;
6518 fseek (ifp, tboff, SEEK_SET);
6520 if ((nrecs | depth) > 127) return;
6524 save = ftell(ifp) + 4;
6525 fseek (ifp, offset+get4(), SEEK_SET);
6526 if ((((type >> 8) + 8) | 8) == 0x38)
6527 parse_ciff (ftell(ifp), len, depth+1); /* Parse a sub-table */
6529 fread (artist, 64, 1, ifp);
6530 if (type == 0x080a) {
6531 fread (make, 64, 1, ifp);
6532 fseek (ifp, strlen(make) - 63, SEEK_CUR);
6533 fread (model, 64, 1, ifp);
6535 if (type == 0x1810) {
6538 pixel_aspect = int_to_float(get4());
6541 if (type == 0x1835) /* Get the decoder table */
6542 tiff_compress = get4();
6543 if (type == 0x2007) {
6544 thumb_offset = ftell(ifp);
6547 if (type == 0x1818) {
6548 shutter = pow (2, -int_to_float((get4(),get4())));
6549 aperture = pow (2, int_to_float(get4())/2);
6551 if (type == 0x102a) {
6552 iso_speed = pow (2, (get4(),get2())/32.0 - 4) * 50;
6553 aperture = pow (2, (get2(),(short)get2())/64.0);
6554 shutter = pow (2,-((short)get2())/32.0);
6555 wbi = (get2(),get2());
6556 if (wbi > 17) wbi = 0;
6557 fseek (ifp, 32, SEEK_CUR);
6558 if (shutter > 1e6) shutter = get2()/10.0;
6560 if (type == 0x102c) {
6561 if (get2() > 512) { /* Pro90, G1 */
6562 fseek (ifp, 118, SEEK_CUR);
6563 FORC4 cam_mul[c ^ 2] = get2();
6564 } else { /* G2, S30, S40 */
6565 fseek (ifp, 98, SEEK_CUR);
6566 FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get2();
6569 if (type == 0x0032) {
6570 if (len == 768) { /* EOS D30 */
6571 fseek (ifp, 72, SEEK_CUR);
6572 FORC4 cam_mul[c ^ (c >> 1)] = 1024.0 / get2();
6573 if (!wbi) cam_mul[0] = -1; /* use my auto white balance */
6574 } else if (!cam_mul[0]) {
6575 if (get2() == key[0]) /* Pro1, G6, S60, S70 */
6576 c = (strstr(model,"Pro1") ?
6577 "012346000000000000":"01345:000000006008")[wbi]-'0'+ 2;
6578 else { /* G3, G5, S45, S50 */
6579 c = "023457000000006000"[wbi]-'0';
6580 key[0] = key[1] = 0;
6582 fseek (ifp, 78 + c*8, SEEK_CUR);
6583 FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get2() ^ key[c & 1];
6584 if (!wbi) cam_mul[0] = -1;
6587 if (type == 0x10a9) { /* D60, 10D, 300D, and clones */
6588 if (len > 66) wbi = "0134567028"[wbi]-'0';
6589 fseek (ifp, 2 + wbi*8, SEEK_CUR);
6590 FORC4 cam_mul[c ^ (c >> 1)] = get2();
6592 if (type == 0x1030 && (0x18040 >> wbi & 1))
6593 ciff_block_1030(); /* all that don't have 0x10a9 */
6594 if (type == 0x1031) {
6595 raw_width = (get2(),get2());
6596 raw_height = get2();
6598 if (type == 0x5029) {
6599 focal_len = len >> 16;
6600 if ((len & 0xffff) == 2) focal_len /= 32;
6602 if (type == 0x5813) flash_used = int_to_float(len);
6603 if (type == 0x5814) canon_ev = int_to_float(len);
6604 if (type == 0x5817) shot_order = len;
6605 if (type == 0x5834) unique_id = len;
6606 if (type == 0x580e) timestamp = len;
6607 if (type == 0x180e) timestamp = get4();
6609 if ((type | 0x4000) == 0x580e)
6610 timestamp = mktime (gmtime (×tamp));
6612 fseek (ifp, save, SEEK_SET);
6616 void CLASS parse_rollei()
6618 char line[128], *val;
6621 fseek (ifp, 0, SEEK_SET);
6622 memset (&t, 0, sizeof t);
6624 fgets (line, 128, ifp);
6625 if ((val = strchr(line,'=')))
6628 val = line + strlen(line);
6629 if (!strcmp(line,"DAT"))
6630 sscanf (val, "%d.%d.%d", &t.tm_mday, &t.tm_mon, &t.tm_year);
6631 if (!strcmp(line,"TIM"))
6632 sscanf (val, "%d:%d:%d", &t.tm_hour, &t.tm_min, &t.tm_sec);
6633 if (!strcmp(line,"HDR"))
6634 thumb_offset = atoi(val);
6635 if (!strcmp(line,"X "))
6636 raw_width = atoi(val);
6637 if (!strcmp(line,"Y "))
6638 raw_height = atoi(val);
6639 if (!strcmp(line,"TX "))
6640 thumb_width = atoi(val);
6641 if (!strcmp(line,"TY "))
6642 thumb_height = atoi(val);
6643 } while (strncmp(line,"EOHD",4));
6644 data_offset = thumb_offset + thumb_width * thumb_height * 2;
6648 timestamp = mktime(&t);
6649 strcpy (make, "Rollei");
6650 strcpy (model,"d530flex");
6651 write_thumb = &CLASS rollei_thumb;
6654 void CLASS parse_sinar_ia()
6660 fseek (ifp, 4, SEEK_SET);
6662 fseek (ifp, get4(), SEEK_SET);
6664 off = get4(); get4();
6665 fread (str, 8, 1, ifp);
6666 if (!strcmp(str,"META")) meta_offset = off;
6667 if (!strcmp(str,"THUMB")) thumb_offset = off;
6668 if (!strcmp(str,"RAW0")) data_offset = off;
6670 fseek (ifp, meta_offset+20, SEEK_SET);
6671 fread (make, 64, 1, ifp);
6673 if ((cp = strchr(make,' '))) {
6674 strcpy (model, cp+1);
6678 raw_height = get2();
6679 load_raw = &CLASS unpacked_load_raw;
6680 thumb_width = (get4(),get2());
6681 thumb_height = get2();
6682 write_thumb = &CLASS ppm_thumb;
6686 void CLASS parse_phase_one (int base)
6689 unsigned entries, tag, /*type,*/ len, data, save, i, c;
6690 float romm_cam[3][3];
6693 memset (&ph1, 0, sizeof ph1);
6694 fseek (ifp, base, SEEK_SET);
6695 order = get4() & 0xffff;
6696 if (get4() >> 8 != 0x526177) return; /* "Raw" */
6697 fseek (ifp, get4()+base, SEEK_SET);
6707 fseek (ifp, base+data, SEEK_SET);
6709 case 0x100: flip = "0653"[data & 3]-'0'; break;
6711 for (i=0; i < 9; i++)
6712 ((float *)romm_cam)[i] = getreal(11);
6713 romm_coeff (romm_cam);
6716 FORC3 cam_mul[c] = getreal(11);
6718 case 0x108: raw_width = data; break;
6719 case 0x109: raw_height = data; break;
6720 case 0x10a: left_margin = data; break;
6721 case 0x10b: top_margin = data; break;
6722 case 0x10c: width = data; break;
6723 case 0x10d: height = data; break;
6724 case 0x10e: ph1.format = data; break;
6725 case 0x10f: data_offset = data+base; break;
6726 case 0x110: meta_offset = data+base;
6727 meta_length = len; break;
6728 case 0x112: ph1.key_off = save - 4; break;
6729 case 0x210: ph1.tag_210 = int_to_float(data); break;
6730 case 0x21a: ph1.tag_21a = data; break;
6731 case 0x21c: strip_offset = data+base; break;
6732 case 0x21d: ph1.black = data; break;
6733 case 0x222: ph1.split_col = data; break;
6734 case 0x223: ph1.black_col = data+base; break;
6735 case 0x224: ph1.split_row = data; break;
6736 case 0x225: ph1.black_row = data+base; break;
6739 fread (model, 1, 63, ifp);
6740 if ((cp = strstr(model," camera"))) *cp = 0;
6742 fseek (ifp, save, SEEK_SET);
6744 load_raw = ph1.format < 3 ?
6745 &CLASS phase_one_load_raw : &CLASS phase_one_load_raw_c;
6747 strcpy (make, "Phase One");
6748 if (model[0]) return;
6749 switch (raw_height) {
6750 case 2060: strcpy (model,"LightPhase"); break;
6751 case 2682: strcpy (model,"H 10"); break;
6752 case 4128: strcpy (model,"H 20"); break;
6753 case 5488: strcpy (model,"H 25"); break;
6757 void CLASS parse_fuji (int offset)
6759 unsigned entries, tag, len, save, c;
6761 fseek (ifp, offset, SEEK_SET);
6763 if (entries > 255) return;
6769 raw_height = get2();
6771 } else if (tag == 0x121) {
6773 if ((width = get2()) == 4284) width += 3;
6774 } else if (tag == 0x130) {
6775 fuji_layout = fgetc(ifp) >> 7;
6776 fuji_width = !(fgetc(ifp) & 8);
6777 } else if (tag == 0x131) {
6779 FORC(36) xtrans_abs[0][35-c] = fgetc(ifp) & 3;
6780 } else if (tag == 0x2ff0) {
6781 FORC4 cam_mul[c ^ 1] = get2();
6782 } else if (tag == 0xc000) {
6785 while ((tag = get4()) > raw_width);
6790 fseek (ifp, save+len, SEEK_SET);
6792 height <<= fuji_layout;
6793 width >>= fuji_layout;
6796 int CLASS parse_jpeg (int offset)
6798 int len, save, hlen, mark;
6800 fseek (ifp, offset, SEEK_SET);
6801 if (fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) return 0;
6803 while (fgetc(ifp) == 0xff && (mark = fgetc(ifp)) != 0xda) {
6807 if (mark == 0xc0 || mark == 0xc3 || mark == 0xc9) {
6809 raw_height = get2();
6814 if (get4() == 0x48454150) /* "HEAP" */
6815 parse_ciff (save+hlen, len-hlen, 0);
6816 if (parse_tiff (save+6)) apply_tiff();
6817 fseek (ifp, save+len, SEEK_SET);
6822 void CLASS parse_riff()
6824 unsigned i, size, end;
6825 char tag[4], date[64], month[64];
6826 static const char mon[12][4] =
6827 { "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" };
6831 fread (tag, 4, 1, ifp);
6833 end = ftell(ifp) + size;
6834 if (!memcmp(tag,"RIFF",4) || !memcmp(tag,"LIST",4)) {
6836 while (ftell(ifp)+7 < end && !feof(ifp))
6838 } else if (!memcmp(tag,"nctg",4)) {
6839 while (ftell(ifp)+7 < end) {
6842 if ((i+1) >> 1 == 10 && size == 20)
6844 else fseek (ifp, size, SEEK_CUR);
6846 } else if (!memcmp(tag,"IDIT",4) && size < 64) {
6847 fread (date, 64, 1, ifp);
6849 memset (&t, 0, sizeof t);
6850 if (sscanf (date, "%*s %s %d %d:%d:%d %d", month, &t.tm_mday,
6851 &t.tm_hour, &t.tm_min, &t.tm_sec, &t.tm_year) == 6) {
6852 for (i=0; i < 12 && strcasecmp(mon[i],month); i++);
6856 timestamp = mktime(&t);
6859 fseek (ifp, size, SEEK_CUR);
6862 void CLASS parse_qt (int end)
6864 unsigned save, size;
6868 while (ftell(ifp)+7 < end) {
6870 if ((size = get4()) < 8) return;
6871 fread (tag, 4, 1, ifp);
6872 if (!memcmp(tag,"moov",4) ||
6873 !memcmp(tag,"udta",4) ||
6874 !memcmp(tag,"CNTH",4))
6875 parse_qt (save+size);
6876 if (!memcmp(tag,"CNDA",4))
6877 parse_jpeg (ftell(ifp));
6878 fseek (ifp, save+size, SEEK_SET);
6882 void CLASS parse_smal (int offset, int fsize)
6886 fseek (ifp, offset+2, SEEK_SET);
6890 fseek (ifp, 5, SEEK_CUR);
6891 if (get4() != fsize) return;
6892 if (ver > 6) data_offset = get4();
6893 raw_height = height = get2();
6894 raw_width = width = get2();
6895 strcpy (make, "SMaL");
6896 sprintf (model, "v%d %dx%d", ver, width, height);
6897 if (ver == 6) load_raw = &CLASS smal_v6_load_raw;
6898 if (ver == 9) load_raw = &CLASS smal_v9_load_raw;
6901 void CLASS parse_cine()
6903 unsigned off_head, off_setup, off_image, i;
6906 fseek (ifp, 4, SEEK_SET);
6907 is_raw = get2() == 2;
6908 fseek (ifp, 14, SEEK_CUR);
6914 if ((i = get4())) timestamp = i;
6915 fseek (ifp, off_head+4, SEEK_SET);
6917 raw_height = get4();
6918 switch (get2(),get2()) {
6919 case 8: load_raw = &CLASS eight_bit_load_raw; break;
6920 case 16: load_raw = &CLASS unpacked_load_raw;
6922 fseek (ifp, off_setup+792, SEEK_SET);
6923 strcpy (make, "CINE");
6924 sprintf (model, "%d", get4());
6925 fseek (ifp, 12, SEEK_CUR);
6926 switch ((i=get4()) & 0xffffff) {
6927 case 3: filters = 0x94949494; break;
6928 case 4: filters = 0x49494949; break;
6929 default: is_raw = 0;
6931 fseek (ifp, 72, SEEK_CUR);
6932 switch ((get4()+3600) % 360) {
6933 case 270: flip = 4; break;
6934 case 180: flip = 1; break;
6935 case 90: flip = 7; break;
6938 cam_mul[0] = getreal(11);
6939 cam_mul[2] = getreal(11);
6940 maximum = ~(-1 << get4());
6941 fseek (ifp, 668, SEEK_CUR);
6942 shutter = get4()/1000000000.0;
6943 fseek (ifp, off_image, SEEK_SET);
6944 if (shot_select < is_raw)
6945 fseek (ifp, shot_select*8, SEEK_CUR);
6946 data_offset = (INT64) get4() + 8;
6947 data_offset += (INT64) get4() << 32;
6950 void CLASS parse_redcine()
6952 unsigned i, len, rdvo;
6956 fseek (ifp, 52, SEEK_SET);
6959 fseek (ifp, 0, SEEK_END);
6960 fseek (ifp, -(i = ftello(ifp) & 511), SEEK_CUR);
6961 if (get4() != i || get4() != 0x52454f42) {
6962 fprintf (stderr,_("%s: Tail is missing, parsing from head...\n"), ifname);
6963 fseek (ifp, 0, SEEK_SET);
6964 while ((len = get4()) != EOF) {
6965 if (get4() == 0x52454456)
6966 if (is_raw++ == shot_select)
6967 data_offset = ftello(ifp) - 8;
6968 fseek (ifp, len-8, SEEK_CUR);
6972 fseek (ifp, 12, SEEK_CUR);
6974 fseeko (ifp, rdvo+8 + shot_select*4, SEEK_SET);
6975 data_offset = get4();
6979 char * CLASS foveon_gets (int offset, char *str, int len)
6982 fseek (ifp, offset, SEEK_SET);
6983 for (i=0; i < len-1; i++)
6984 if ((str[i] = get2()) == 0) break;
6989 void CLASS parse_foveon()
6991 int entries, img=0, off, len, tag, save, i, wide, high, pent, poff[256][2];
6992 char name[64], value[64];
6994 order = 0x4949; /* Little-endian */
6995 fseek (ifp, 36, SEEK_SET);
6997 fseek (ifp, -4, SEEK_END);
6998 fseek (ifp, get4(), SEEK_SET);
6999 if (get4() != 0x64434553) return; /* SECd */
7000 entries = (get4(),get4());
7006 fseek (ifp, off, SEEK_SET);
7007 if (get4() != (0x20434553 | (tag << 24))) return;
7009 case 0x47414d49: /* IMAG */
7010 case 0x32414d49: /* IMA2 */
7011 fseek (ifp, 8, SEEK_CUR);
7015 if (wide > raw_width && high > raw_height) {
7017 case 5: load_flags = 1;
7018 case 6: load_raw = &CLASS foveon_sd_load_raw; break;
7019 case 30: load_raw = &CLASS foveon_dp_load_raw; break;
7020 default: load_raw = 0;
7024 data_offset = off+28;
7027 fseek (ifp, off+28, SEEK_SET);
7028 if (fgetc(ifp) == 0xff && fgetc(ifp) == 0xd8
7029 && thumb_length < len-28) {
7030 thumb_offset = off+28;
7031 thumb_length = len-28;
7032 write_thumb = &CLASS jpeg_thumb;
7034 if (++img == 2 && !thumb_length) {
7035 thumb_offset = off+24;
7037 thumb_height = high;
7038 write_thumb = &CLASS foveon_thumb;
7041 case 0x464d4143: /* CAMF */
7042 meta_offset = off+8;
7043 meta_length = len-28;
7045 case 0x504f5250: /* PROP */
7046 pent = (get4(),get4());
7047 fseek (ifp, 12, SEEK_CUR);
7049 if ((unsigned) pent > 256) pent=256;
7050 for (i=0; i < pent*2; i++)
7051 ((int *)poff)[i] = off + get4()*2;
7052 for (i=0; i < pent; i++) {
7053 foveon_gets (poff[i][0], name, 64);
7054 foveon_gets (poff[i][1], value, 64);
7055 if (!strcmp (name, "ISO"))
7056 iso_speed = atoi(value);
7057 if (!strcmp (name, "CAMMANUF"))
7058 strcpy (make, value);
7059 if (!strcmp (name, "CAMMODEL"))
7060 strcpy (model, value);
7061 if (!strcmp (name, "WB_DESC"))
7062 strcpy (model2, value);
7063 if (!strcmp (name, "TIME"))
7064 timestamp = atoi(value);
7065 if (!strcmp (name, "EXPTIME"))
7066 shutter = atoi(value) / 1000000.0;
7067 if (!strcmp (name, "APERTURE"))
7068 aperture = atof(value);
7069 if (!strcmp (name, "FLENGTH"))
7070 focal_len = atof(value);
7073 timestamp = mktime (gmtime (×tamp));
7076 fseek (ifp, save, SEEK_SET);
7081 All matrices are from Adobe DNG Converter unless otherwise noted.
7083 void CLASS adobe_coeff (const char *make, const char *model)
7085 static const struct {
7087 short black, maximum, trans[12];
7089 { "AgfaPhoto DC-833m", 0, 0, /* DJC */
7090 { 11438,-3762,-1115,-2409,9914,2497,-1227,2295,5300 } },
7091 { "Apple QuickTake", 0, 0, /* DJC */
7092 { 21392,-5653,-3353,2406,8010,-415,7166,1427,2078 } },
7093 { "Canon EOS D2000", 0, 0,
7094 { 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } },
7095 { "Canon EOS D6000", 0, 0,
7096 { 20482,-7172,-3125,-1033,10410,-285,2542,226,3136 } },
7097 { "Canon EOS D30", 0, 0,
7098 { 9805,-2689,-1312,-5803,13064,3068,-2438,3075,8775 } },
7099 { "Canon EOS D60", 0, 0xfa0,
7100 { 6188,-1341,-890,-7168,14489,2937,-2640,3228,8483 } },
7101 { "Canon EOS 5DS", 0, 0x3c96,
7102 { 6250,-711,-808,-5153,12794,2636,-1249,2198,5610 } },
7103 { "Canon EOS 5D Mark III", 0, 0x3c80,
7104 { 6722,-635,-963,-4287,12460,2028,-908,2162,5668 } },
7105 { "Canon EOS 5D Mark II", 0, 0x3cf0,
7106 { 4716,603,-830,-7798,15474,2480,-1496,1937,6651 } },
7107 { "Canon EOS 5D", 0, 0xe6c,
7108 { 6347,-479,-972,-8297,15954,2480,-1968,2131,7649 } },
7109 { "Canon EOS 6D", 0, 0x3c82,
7110 { 7034,-804,-1014,-4420,12564,2058,-851,1994,5758 } },
7111 { "Canon EOS 7D Mark II", 0, 0x3510,
7112 { 7268,-1082,-969,-4186,11839,2663,-825,2029,5839 } },
7113 { "Canon EOS 7D", 0, 0x3510,
7114 { 6844,-996,-856,-3876,11761,2396,-593,1772,6198 } },
7115 { "Canon EOS 10D", 0, 0xfa0,
7116 { 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } },
7117 { "Canon EOS 20Da", 0, 0,
7118 { 14155,-5065,-1382,-6550,14633,2039,-1623,1824,6561 } },
7119 { "Canon EOS 20D", 0, 0xfff,
7120 { 6599,-537,-891,-8071,15783,2424,-1983,2234,7462 } },
7121 { "Canon EOS 30D", 0, 0,
7122 { 6257,-303,-1000,-7880,15621,2396,-1714,1904,7046 } },
7123 { "Canon EOS 40D", 0, 0x3f60,
7124 { 6071,-747,-856,-7653,15365,2441,-2025,2553,7315 } },
7125 { "Canon EOS 50D", 0, 0x3d93,
7126 { 4920,616,-593,-6493,13964,2784,-1774,3178,7005 } },
7127 { "Canon EOS 60D", 0, 0x2ff7,
7128 { 6719,-994,-925,-4408,12426,2211,-887,2129,6051 } },
7129 { "Canon EOS 70D", 0, 0x3bc7,
7130 { 7034,-804,-1014,-4420,12564,2058,-851,1994,5758 } },
7131 { "Canon EOS 80D", 0, 0,
7132 { 7457,-671,-937,-4849,12495,2643,-1213,2354,5492 } },
7133 { "Canon EOS 100D", 0, 0x350f,
7134 { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } },
7135 { "Canon EOS 300D", 0, 0xfa0,
7136 { 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } },
7137 { "Canon EOS 350D", 0, 0xfff,
7138 { 6018,-617,-965,-8645,15881,2975,-1530,1719,7642 } },
7139 { "Canon EOS 400D", 0, 0xe8e,
7140 { 7054,-1501,-990,-8156,15544,2812,-1278,1414,7796 } },
7141 { "Canon EOS 450D", 0, 0x390d,
7142 { 5784,-262,-821,-7539,15064,2672,-1982,2681,7427 } },
7143 { "Canon EOS 500D", 0, 0x3479,
7144 { 4763,712,-646,-6821,14399,2640,-1921,3276,6561 } },
7145 { "Canon EOS 550D", 0, 0x3dd7,
7146 { 6941,-1164,-857,-3825,11597,2534,-416,1540,6039 } },
7147 { "Canon EOS 600D", 0, 0x3510,
7148 { 6461,-907,-882,-4300,12184,2378,-819,1944,5931 } },
7149 { "Canon EOS 650D", 0, 0x354d,
7150 { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } },
7151 { "Canon EOS 700D", 0, 0x3c00,
7152 { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } },
7153 { "Canon EOS 750D", 0, 0x368e,
7154 { 6362,-823,-847,-4426,12109,2616,-743,1857,5635 } },
7155 { "Canon EOS 760D", 0, 0x350f,
7156 { 6362,-823,-847,-4426,12109,2616,-743,1857,5635 } },
7157 { "Canon EOS 1000D", 0, 0xe43,
7158 { 6771,-1139,-977,-7818,15123,2928,-1244,1437,7533 } },
7159 { "Canon EOS 1100D", 0, 0x3510,
7160 { 6444,-904,-893,-4563,12308,2535,-903,2016,6728 } },
7161 { "Canon EOS 1200D", 0, 0x37c2,
7162 { 6461,-907,-882,-4300,12184,2378,-819,1944,5931 } },
7163 { "Canon EOS 1300D", 0, 0x3510,
7164 { 6939,-1016,-866,-4428,12473,2177,-1175,2178,6162 } },
7165 { "Canon EOS M3", 0, 0,
7166 { 6362,-823,-847,-4426,12109,2616,-743,1857,5635 } },
7167 { "Canon EOS M10", 0, 0,
7168 { 6400,-480,-888,-5294,13416,2047,-1296,2203,6137 } },
7169 { "Canon EOS M", 0, 0,
7170 { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } },
7171 { "Canon EOS-1Ds Mark III", 0, 0x3bb0,
7172 { 5859,-211,-930,-8255,16017,2353,-1732,1887,7448 } },
7173 { "Canon EOS-1Ds Mark II", 0, 0xe80,
7174 { 6517,-602,-867,-8180,15926,2378,-1618,1771,7633 } },
7175 { "Canon EOS-1D Mark IV", 0, 0x3bb0,
7176 { 6014,-220,-795,-4109,12014,2361,-561,1824,5787 } },
7177 { "Canon EOS-1D Mark III", 0, 0x3bb0,
7178 { 6291,-540,-976,-8350,16145,2311,-1714,1858,7326 } },
7179 { "Canon EOS-1D Mark II N", 0, 0xe80,
7180 { 6240,-466,-822,-8180,15825,2500,-1801,1938,8042 } },
7181 { "Canon EOS-1D Mark II", 0, 0xe80,
7182 { 6264,-582,-724,-8312,15948,2504,-1744,1919,8664 } },
7183 { "Canon EOS-1DS", 0, 0xe20,
7184 { 4374,3631,-1743,-7520,15212,2472,-2892,3632,8161 } },
7185 { "Canon EOS-1D C", 0, 0x3c4e,
7186 { 6847,-614,-1014,-4669,12737,2139,-1197,2488,6846 } },
7187 { "Canon EOS-1D X Mark II", 0, 0,
7188 { 7596,-978,-967,-4808,12571,2503,-1398,2567,5752 } },
7189 { "Canon EOS-1D X", 0, 0x3c4e,
7190 { 6847,-614,-1014,-4669,12737,2139,-1197,2488,6846 } },
7191 { "Canon EOS-1D", 0, 0xe20,
7192 { 6806,-179,-1020,-8097,16415,1687,-3267,4236,7690 } },
7193 { "Canon EOS C500", 853, 0, /* DJC */
7194 { 17851,-10604,922,-7425,16662,763,-3660,3636,22278 } },
7195 { "Canon PowerShot A530", 0, 0,
7196 { 0 } }, /* don't want the A5 matrix */
7197 { "Canon PowerShot A50", 0, 0,
7198 { -5300,9846,1776,3436,684,3939,-5540,9879,6200,-1404,11175,217 } },
7199 { "Canon PowerShot A5", 0, 0,
7200 { -4801,9475,1952,2926,1611,4094,-5259,10164,5947,-1554,10883,547 } },
7201 { "Canon PowerShot G10", 0, 0,
7202 { 11093,-3906,-1028,-5047,12492,2879,-1003,1750,5561 } },
7203 { "Canon PowerShot G11", 0, 0,
7204 { 12177,-4817,-1069,-1612,9864,2049,-98,850,4471 } },
7205 { "Canon PowerShot G12", 0, 0,
7206 { 13244,-5501,-1248,-1508,9858,1935,-270,1083,4366 } },
7207 { "Canon PowerShot G15", 0, 0,
7208 { 7474,-2301,-567,-4056,11456,2975,-222,716,4181 } },
7209 { "Canon PowerShot G16", 0, 0,
7210 { 8020,-2687,-682,-3704,11879,2052,-965,1921,5556 } },
7211 { "Canon PowerShot G1 X", 0, 0,
7212 { 7378,-1255,-1043,-4088,12251,2048,-876,1946,5805 } },
7213 { "Canon PowerShot G1", 0, 0,
7214 { -4778,9467,2172,4743,-1141,4344,-5146,9908,6077,-1566,11051,557 } },
7215 { "Canon PowerShot G2", 0, 0,
7216 { 9087,-2693,-1049,-6715,14382,2537,-2291,2819,7790 } },
7217 { "Canon PowerShot G3 X", 0, 0,
7218 { 9701,-3857,-921,-3149,11537,1817,-786,1817,5147 } },
7219 { "Canon PowerShot G3", 0, 0,
7220 { 9212,-2781,-1073,-6573,14189,2605,-2300,2844,7664 } },
7221 { "Canon PowerShot G5 X", 0, 0,
7222 { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } },
7223 { "Canon PowerShot G5", 0, 0,
7224 { 9757,-2872,-933,-5972,13861,2301,-1622,2328,7212 } },
7225 { "Canon PowerShot G6", 0, 0,
7226 { 9877,-3775,-871,-7613,14807,3072,-1448,1305,7485 } },
7227 { "Canon PowerShot G7 X", 0, 0,
7228 { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } },
7229 { "Canon PowerShot G9 X", 0, 0,
7230 { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } },
7231 { "Canon PowerShot G9", 0, 0,
7232 { 7368,-2141,-598,-5621,13254,2625,-1418,1696,5743 } },
7233 { "Canon PowerShot Pro1", 0, 0,
7234 { 10062,-3522,-999,-7643,15117,2730,-765,817,7323 } },
7235 { "Canon PowerShot Pro70", 34, 0,
7236 { -4155,9818,1529,3939,-25,4522,-5521,9870,6610,-2238,10873,1342 } },
7237 { "Canon PowerShot Pro90", 0, 0,
7238 { -4963,9896,2235,4642,-987,4294,-5162,10011,5859,-1770,11230,577 } },
7239 { "Canon PowerShot S30", 0, 0,
7240 { 10566,-3652,-1129,-6552,14662,2006,-2197,2581,7670 } },
7241 { "Canon PowerShot S40", 0, 0,
7242 { 8510,-2487,-940,-6869,14231,2900,-2318,2829,9013 } },
7243 { "Canon PowerShot S45", 0, 0,
7244 { 8163,-2333,-955,-6682,14174,2751,-2077,2597,8041 } },
7245 { "Canon PowerShot S50", 0, 0,
7246 { 8882,-2571,-863,-6348,14234,2288,-1516,2172,6569 } },
7247 { "Canon PowerShot S60", 0, 0,
7248 { 8795,-2482,-797,-7804,15403,2573,-1422,1996,7082 } },
7249 { "Canon PowerShot S70", 0, 0,
7250 { 9976,-3810,-832,-7115,14463,2906,-901,989,7889 } },
7251 { "Canon PowerShot S90", 0, 0,
7252 { 12374,-5016,-1049,-1677,9902,2078,-83,852,4683 } },
7253 { "Canon PowerShot S95", 0, 0,
7254 { 13440,-5896,-1279,-1236,9598,1931,-180,1001,4651 } },
7255 { "Canon PowerShot S100", 0, 0,
7256 { 7968,-2565,-636,-2873,10697,2513,180,667,4211 } },
7257 { "Canon PowerShot S110", 0, 0,
7258 { 8039,-2643,-654,-3783,11230,2930,-206,690,4194 } },
7259 { "Canon PowerShot S120", 0, 0,
7260 { 6961,-1685,-695,-4625,12945,1836,-1114,2152,5518 } },
7261 { "Canon PowerShot SX1 IS", 0, 0,
7262 { 6578,-259,-502,-5974,13030,3309,-308,1058,4970 } },
7263 { "Canon PowerShot SX50 HS", 0, 0,
7264 { 12432,-4753,-1247,-2110,10691,1629,-412,1623,4926 } },
7265 { "Canon PowerShot SX60 HS", 0, 0,
7266 { 13161,-5451,-1344,-1989,10654,1531,-47,1271,4955 } },
7267 { "Canon PowerShot A3300", 0, 0, /* DJC */
7268 { 10826,-3654,-1023,-3215,11310,1906,0,999,4960 } },
7269 { "Canon PowerShot A470", 0, 0, /* DJC */
7270 { 12513,-4407,-1242,-2680,10276,2405,-878,2215,4734 } },
7271 { "Canon PowerShot A610", 0, 0, /* DJC */
7272 { 15591,-6402,-1592,-5365,13198,2168,-1300,1824,5075 } },
7273 { "Canon PowerShot A620", 0, 0, /* DJC */
7274 { 15265,-6193,-1558,-4125,12116,2010,-888,1639,5220 } },
7275 { "Canon PowerShot A630", 0, 0, /* DJC */
7276 { 14201,-5308,-1757,-6087,14472,1617,-2191,3105,5348 } },
7277 { "Canon PowerShot A640", 0, 0, /* DJC */
7278 { 13124,-5329,-1390,-3602,11658,1944,-1612,2863,4885 } },
7279 { "Canon PowerShot A650", 0, 0, /* DJC */
7280 { 9427,-3036,-959,-2581,10671,1911,-1039,1982,4430 } },
7281 { "Canon PowerShot A720", 0, 0, /* DJC */
7282 { 14573,-5482,-1546,-1266,9799,1468,-1040,1912,3810 } },
7283 { "Canon PowerShot S3 IS", 0, 0, /* DJC */
7284 { 14062,-5199,-1446,-4712,12470,2243,-1286,2028,4836 } },
7285 { "Canon PowerShot SX110 IS", 0, 0, /* DJC */
7286 { 14134,-5576,-1527,-1991,10719,1273,-1158,1929,3581 } },
7287 { "Canon PowerShot SX220", 0, 0, /* DJC */
7288 { 13898,-5076,-1447,-1405,10109,1297,-244,1860,3687 } },
7289 { "Canon IXUS 160", 0, 0, /* DJC */
7290 { 11657,-3781,-1136,-3544,11262,2283,-160,1219,4700 } },
7291 { "Casio EX-S20", 0, 0, /* DJC */
7292 { 11634,-3924,-1128,-4968,12954,2015,-1588,2648,7206 } },
7293 { "Casio EX-Z750", 0, 0, /* DJC */
7294 { 10819,-3873,-1099,-4903,13730,1175,-1755,3751,4632 } },
7295 { "Casio EX-Z10", 128, 0xfff, /* DJC */
7296 { 9790,-3338,-603,-2321,10222,2099,-344,1273,4799 } },
7298 { 3390,480,-500,-800,3610,340,-550,2336,1192 } },
7300 { 3390,480,-500,-800,3610,340,-550,2336,1192 } },
7302 { 20183,-4295,-423,-3940,15330,3985,-280,4870,9800 } },
7303 { "Contax N Digital", 0, 0xf1e,
7304 { 7777,1285,-1053,-9280,16543,2916,-3677,5679,7060 } },
7306 { 6596,-2079,-562,-4782,13016,1933,-970,1581,5181 } },
7307 { "Epson R-D1", 0, 0,
7308 { 6827,-1878,-732,-8429,16012,2564,-704,592,7145 } },
7309 { "Fujifilm E550", 0, 0,
7310 { 11044,-3888,-1120,-7248,15168,2208,-1531,2277,8069 } },
7311 { "Fujifilm E900", 0, 0,
7312 { 9183,-2526,-1078,-7461,15071,2574,-2022,2440,8639 } },
7313 { "Fujifilm F5", 0, 0,
7314 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
7315 { "Fujifilm F6", 0, 0,
7316 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
7317 { "Fujifilm F77", 0, 0xfe9,
7318 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
7319 { "Fujifilm F7", 0, 0,
7320 { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } },
7321 { "Fujifilm F8", 0, 0,
7322 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
7323 { "Fujifilm S100FS", 514, 0,
7324 { 11521,-4355,-1065,-6524,13767,3058,-1466,1984,6045 } },
7325 { "Fujifilm S1", 0, 0,
7326 { 12297,-4882,-1202,-2106,10691,1623,-88,1312,4790 } },
7327 { "Fujifilm S20Pro", 0, 0,
7328 { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } },
7329 { "Fujifilm S20", 512, 0x3fff,
7330 { 11401,-4498,-1312,-5088,12751,2613,-838,1568,5941 } },
7331 { "Fujifilm S2Pro", 128, 0,
7332 { 12492,-4690,-1402,-7033,15423,1647,-1507,2111,7697 } },
7333 { "Fujifilm S3Pro", 0, 0,
7334 { 11807,-4612,-1294,-8927,16968,1988,-2120,2741,8006 } },
7335 { "Fujifilm S5Pro", 0, 0,
7336 { 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } },
7337 { "Fujifilm S5000", 0, 0,
7338 { 8754,-2732,-1019,-7204,15069,2276,-1702,2334,6982 } },
7339 { "Fujifilm S5100", 0, 0,
7340 { 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } },
7341 { "Fujifilm S5500", 0, 0,
7342 { 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } },
7343 { "Fujifilm S5200", 0, 0,
7344 { 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } },
7345 { "Fujifilm S5600", 0, 0,
7346 { 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } },
7347 { "Fujifilm S6", 0, 0,
7348 { 12628,-4887,-1401,-6861,14996,1962,-2198,2782,7091 } },
7349 { "Fujifilm S7000", 0, 0,
7350 { 10190,-3506,-1312,-7153,15051,2238,-2003,2399,7505 } },
7351 { "Fujifilm S9000", 0, 0,
7352 { 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 } },
7353 { "Fujifilm S9500", 0, 0,
7354 { 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 } },
7355 { "Fujifilm S9100", 0, 0,
7356 { 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 } },
7357 { "Fujifilm S9600", 0, 0,
7358 { 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 } },
7359 { "Fujifilm SL1000", 0, 0,
7360 { 11705,-4262,-1107,-2282,10791,1709,-555,1713,4945 } },
7361 { "Fujifilm IS-1", 0, 0,
7362 { 21461,-10807,-1441,-2332,10599,1999,289,875,7703 } },
7363 { "Fujifilm IS Pro", 0, 0,
7364 { 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } },
7365 { "Fujifilm HS10 HS11", 0, 0xf68,
7366 { 12440,-3954,-1183,-1123,9674,1708,-83,1614,4086 } },
7367 { "Fujifilm HS2", 0, 0,
7368 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
7369 { "Fujifilm HS3", 0, 0,
7370 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
7371 { "Fujifilm HS50EXR", 0, 0,
7372 { 12085,-4727,-953,-3257,11489,2002,-511,2046,4592 } },
7373 { "Fujifilm F900EXR", 0, 0,
7374 { 12085,-4727,-953,-3257,11489,2002,-511,2046,4592 } },
7375 { "Fujifilm X100S", 0, 0,
7376 { 10592,-4262,-1008,-3514,11355,2465,-870,2025,6386 } },
7377 { "Fujifilm X100T", 0, 0,
7378 { 10592,-4262,-1008,-3514,11355,2465,-870,2025,6386 } },
7379 { "Fujifilm X100", 0, 0,
7380 { 12161,-4457,-1069,-5034,12874,2400,-795,1724,6904 } },
7381 { "Fujifilm X10", 0, 0,
7382 { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } },
7383 { "Fujifilm X20", 0, 0,
7384 { 11768,-4971,-1133,-4904,12927,2183,-480,1723,4605 } },
7385 { "Fujifilm X30", 0, 0,
7386 { 12328,-5256,-1144,-4469,12927,1675,-87,1291,4351 } },
7387 { "Fujifilm X70", 0, 0,
7388 { 10450,-4329,-878,-3217,11105,2421,-752,1758,6519 } },
7389 { "Fujifilm X-Pro1", 0, 0,
7390 { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } },
7391 { "Fujifilm X-Pro2", 0, 0,
7392 { 11434,-4948,-1210,-3746,12042,1903,-666,1479,5235 } },
7393 { "Fujifilm X-A1", 0, 0,
7394 { 11086,-4555,-839,-3512,11310,2517,-815,1341,5940 } },
7395 { "Fujifilm X-A2", 0, 0,
7396 { 10763,-4560,-917,-3346,11311,2322,-475,1135,5843 } },
7397 { "Fujifilm X-E1", 0, 0,
7398 { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } },
7399 { "Fujifilm X-E2S", 0, 0,
7400 { 11562,-5118,-961,-3022,11007,2311,-525,1569,6097 } },
7401 { "Fujifilm X-E2", 0, 0,
7402 { 8458,-2451,-855,-4597,12447,2407,-1475,2482,6526 } },
7403 { "Fujifilm X-M1", 0, 0,
7404 { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } },
7405 { "Fujifilm X-S1", 0, 0,
7406 { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } },
7407 { "Fujifilm X-T1", 0, 0, /* also X-T10 */
7408 { 8458,-2451,-855,-4597,12447,2407,-1475,2482,6526 } },
7409 { "Fujifilm XF1", 0, 0,
7410 { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } },
7411 { "Fujifilm XQ", 0, 0, /* XQ1 and XQ2 */
7412 { 9252,-2704,-1064,-5893,14265,1717,-1101,2341,4349 } },
7413 { "Imacon Ixpress", 0, 0, /* DJC */
7414 { 7025,-1415,-704,-5188,13765,1424,-1248,2742,6038 } },
7415 { "Kodak NC2000", 0, 0,
7416 { 13891,-6055,-803,-465,9919,642,2121,82,1291 } },
7417 { "Kodak DCS315C", 8, 0,
7418 { 17523,-4827,-2510,756,8546,-137,6113,1649,2250 } },
7419 { "Kodak DCS330C", 8, 0,
7420 { 20620,-7572,-2801,-103,10073,-396,3551,-233,2220 } },
7421 { "Kodak DCS420", 0, 0,
7422 { 10868,-1852,-644,-1537,11083,484,2343,628,2216 } },
7423 { "Kodak DCS460", 0, 0,
7424 { 10592,-2206,-967,-1944,11685,230,2206,670,1273 } },
7425 { "Kodak EOSDCS1", 0, 0,
7426 { 10592,-2206,-967,-1944,11685,230,2206,670,1273 } },
7427 { "Kodak EOSDCS3B", 0, 0,
7428 { 9898,-2700,-940,-2478,12219,206,1985,634,1031 } },
7429 { "Kodak DCS520C", 178, 0,
7430 { 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } },
7431 { "Kodak DCS560C", 177, 0,
7432 { 20482,-7172,-3125,-1033,10410,-285,2542,226,3136 } },
7433 { "Kodak DCS620C", 177, 0,
7434 { 23617,-10175,-3149,-2054,11749,-272,2586,-489,3453 } },
7435 { "Kodak DCS620X", 176, 0,
7436 { 13095,-6231,154,12221,-21,-2137,895,4602,2258 } },
7437 { "Kodak DCS660C", 173, 0,
7438 { 18244,-6351,-2739,-791,11193,-521,3711,-129,2802 } },
7439 { "Kodak DCS720X", 0, 0,
7440 { 11775,-5884,950,9556,1846,-1286,-1019,6221,2728 } },
7441 { "Kodak DCS760C", 0, 0,
7442 { 16623,-6309,-1411,-4344,13923,323,2285,274,2926 } },
7443 { "Kodak DCS Pro SLR", 0, 0,
7444 { 5494,2393,-232,-6427,13850,2846,-1876,3997,5445 } },
7445 { "Kodak DCS Pro 14nx", 0, 0,
7446 { 5494,2393,-232,-6427,13850,2846,-1876,3997,5445 } },
7447 { "Kodak DCS Pro 14", 0, 0,
7448 { 7791,3128,-776,-8588,16458,2039,-2455,4006,6198 } },
7449 { "Kodak ProBack645", 0, 0,
7450 { 16414,-6060,-1470,-3555,13037,473,2545,122,4948 } },
7451 { "Kodak ProBack", 0, 0,
7452 { 21179,-8316,-2918,-915,11019,-165,3477,-180,4210 } },
7453 { "Kodak P712", 0, 0,
7454 { 9658,-3314,-823,-5163,12695,2768,-1342,1843,6044 } },
7455 { "Kodak P850", 0, 0xf7c,
7456 { 10511,-3836,-1102,-6946,14587,2558,-1481,1792,6246 } },
7457 { "Kodak P880", 0, 0xfff,
7458 { 12805,-4662,-1376,-7480,15267,2360,-1626,2194,7904 } },
7459 { "Kodak EasyShare Z980", 0, 0,
7460 { 11313,-3559,-1101,-3893,11891,2257,-1214,2398,4908 } },
7461 { "Kodak EasyShare Z981", 0, 0,
7462 { 12729,-4717,-1188,-1367,9187,2582,274,860,4411 } },
7463 { "Kodak EasyShare Z990", 0, 0xfed,
7464 { 11749,-4048,-1309,-1867,10572,1489,-138,1449,4522 } },
7465 { "Kodak EASYSHARE Z1015", 0, 0xef1,
7466 { 11265,-4286,-992,-4694,12343,2647,-1090,1523,5447 } },
7467 { "Leaf CMost", 0, 0,
7468 { 3952,2189,449,-6701,14585,2275,-4536,7349,6536 } },
7469 { "Leaf Valeo 6", 0, 0,
7470 { 3952,2189,449,-6701,14585,2275,-4536,7349,6536 } },
7471 { "Leaf Aptus 54S", 0, 0,
7472 { 8236,1746,-1314,-8251,15953,2428,-3673,5786,5771 } },
7473 { "Leaf Aptus 65", 0, 0,
7474 { 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 } },
7475 { "Leaf Aptus 75", 0, 0,
7476 { 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 } },
7478 { 8236,1746,-1314,-8251,15953,2428,-3673,5786,5771 } },
7479 { "Mamiya ZD", 0, 0,
7480 { 7645,2579,-1363,-8689,16717,2015,-3712,5941,5961 } },
7481 { "Micron 2010", 110, 0, /* DJC */
7482 { 16695,-3761,-2151,155,9682,163,3433,951,4904 } },
7483 { "Minolta DiMAGE 5", 0, 0xf7d,
7484 { 8983,-2942,-963,-6556,14476,2237,-2426,2887,8014 } },
7485 { "Minolta DiMAGE 7Hi", 0, 0xf7d,
7486 { 11368,-3894,-1242,-6521,14358,2339,-2475,3056,7285 } },
7487 { "Minolta DiMAGE 7", 0, 0xf7d,
7488 { 9144,-2777,-998,-6676,14556,2281,-2470,3019,7744 } },
7489 { "Minolta DiMAGE A1", 0, 0xf8b,
7490 { 9274,-2547,-1167,-8220,16323,1943,-2273,2720,8340 } },
7491 { "Minolta DiMAGE A200", 0, 0,
7492 { 8560,-2487,-986,-8112,15535,2771,-1209,1324,7743 } },
7493 { "Minolta DiMAGE A2", 0, 0xf8f,
7494 { 9097,-2726,-1053,-8073,15506,2762,-966,981,7763 } },
7495 { "Minolta DiMAGE Z2", 0, 0, /* DJC */
7496 { 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 } },
7497 { "Minolta DYNAX 5", 0, 0xffb,
7498 { 10284,-3283,-1086,-7957,15762,2316,-829,882,6644 } },
7499 { "Minolta DYNAX 7", 0, 0xffb,
7500 { 10239,-3104,-1099,-8037,15727,2451,-927,925,6871 } },
7501 { "Motorola PIXL", 0, 0, /* DJC */
7502 { 8898,-989,-1033,-3292,11619,1674,-661,3178,5216 } },
7503 { "Nikon D100", 0, 0,
7504 { 5902,-933,-782,-8983,16719,2354,-1402,1455,6464 } },
7505 { "Nikon D1H", 0, 0,
7506 { 7577,-2166,-926,-7454,15592,1934,-2377,2808,8606 } },
7507 { "Nikon D1X", 0, 0,
7508 { 7702,-2245,-975,-9114,17242,1875,-2679,3055,8521 } },
7509 { "Nikon D1", 0, 0, /* multiplied by 2.218750, 1.0, 1.148438 */
7510 { 16772,-4726,-2141,-7611,15713,1972,-2846,3494,9521 } },
7511 { "Nikon D200", 0, 0xfbc,
7512 { 8367,-2248,-763,-8758,16447,2422,-1527,1550,8053 } },
7513 { "Nikon D2H", 0, 0,
7514 { 5710,-901,-615,-8594,16617,2024,-2975,4120,6830 } },
7515 { "Nikon D2X", 0, 0,
7516 { 10231,-2769,-1255,-8301,15900,2552,-797,680,7148 } },
7517 { "Nikon D3000", 0, 0,
7518 { 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } },
7519 { "Nikon D3100", 0, 0,
7520 { 7911,-2167,-813,-5327,13150,2408,-1288,2483,7968 } },
7521 { "Nikon D3200", 0, 0xfb9,
7522 { 7013,-1408,-635,-5268,12902,2640,-1470,2801,7379 } },
7523 { "Nikon D3300", 0, 0,
7524 { 6988,-1384,-714,-5631,13410,2447,-1485,2204,7318 } },
7525 { "Nikon D300", 0, 0,
7526 { 9030,-1992,-715,-8465,16302,2255,-2689,3217,8069 } },
7527 { "Nikon D3X", 0, 0,
7528 { 7171,-1986,-648,-8085,15555,2718,-2170,2512,7457 } },
7529 { "Nikon D3S", 0, 0,
7530 { 8828,-2406,-694,-4874,12603,2541,-660,1509,7587 } },
7532 { 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } },
7533 { "Nikon D40X", 0, 0,
7534 { 8819,-2543,-911,-9025,16928,2151,-1329,1213,8449 } },
7535 { "Nikon D40", 0, 0,
7536 { 6992,-1668,-806,-8138,15748,2543,-874,850,7897 } },
7537 { "Nikon D4S", 0, 0,
7538 { 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } },
7540 { 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } },
7542 { 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } },
7543 { "Nikon D5000", 0, 0xf00,
7544 { 7309,-1403,-519,-8474,16008,2622,-2433,2826,8064 } },
7545 { "Nikon D5100", 0, 0x3de6,
7546 { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } },
7547 { "Nikon D5200", 0, 0,
7548 { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } },
7549 { "Nikon D5300", 0, 0,
7550 { 6988,-1384,-714,-5631,13410,2447,-1485,2204,7318 } },
7551 { "Nikon D5500", 0, 0,
7552 { 8821,-2938,-785,-4178,12142,2287,-824,1651,6860 } },
7553 { "Nikon D500", 0, 0,
7554 { 8813,-3210,-1036,-4703,12868,2021,-1054,1940,6129 } },
7555 { "Nikon D50", 0, 0,
7556 { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } },
7558 { 9200,-3522,-992,-5755,13803,2117,-753,1486,6338 } },
7559 { "Nikon D600", 0, 0x3e07,
7560 { 8178,-2245,-609,-4857,12394,2776,-1207,2086,7298 } },
7561 { "Nikon D610", 0, 0,
7562 { 8178,-2245,-609,-4857,12394,2776,-1207,2086,7298 } },
7563 { "Nikon D60", 0, 0,
7564 { 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } },
7565 { "Nikon D7000", 0, 0,
7566 { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } },
7567 { "Nikon D7100", 0, 0,
7568 { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } },
7569 { "Nikon D7200", 0, 0,
7570 { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } },
7571 { "Nikon D750", 0, 0,
7572 { 9020,-2890,-715,-4535,12436,2348,-934,1919,7086 } },
7573 { "Nikon D700", 0, 0,
7574 { 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } },
7575 { "Nikon D70", 0, 0,
7576 { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } },
7577 { "Nikon D810", 0, 0,
7578 { 9369,-3195,-791,-4488,12430,2301,-893,1796,6872 } },
7579 { "Nikon D800", 0, 0,
7580 { 7866,-2108,-555,-4869,12483,2681,-1176,2069,7501 } },
7581 { "Nikon D80", 0, 0,
7582 { 8629,-2410,-883,-9055,16940,2171,-1490,1363,8520 } },
7583 { "Nikon D90", 0, 0xf00,
7584 { 7309,-1403,-519,-8474,16008,2622,-2434,2826,8064 } },
7585 { "Nikon E700", 0, 0x3dd, /* DJC */
7586 { -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } },
7587 { "Nikon E800", 0, 0x3dd, /* DJC */
7588 { -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } },
7589 { "Nikon E950", 0, 0x3dd, /* DJC */
7590 { -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } },
7591 { "Nikon E995", 0, 0, /* copied from E5000 */
7592 { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
7593 { "Nikon E2100", 0, 0, /* copied from Z2, new white balance */
7594 { 13142,-4152,-1596,-4655,12374,2282,-1769,2696,6711} },
7595 { "Nikon E2500", 0, 0,
7596 { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
7597 { "Nikon E3200", 0, 0, /* DJC */
7598 { 9846,-2085,-1019,-3278,11109,2170,-774,2134,5745 } },
7599 { "Nikon E4300", 0, 0, /* copied from Minolta DiMAGE Z2 */
7600 { 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 } },
7601 { "Nikon E4500", 0, 0,
7602 { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
7603 { "Nikon E5000", 0, 0,
7604 { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
7605 { "Nikon E5400", 0, 0,
7606 { 9349,-2987,-1001,-7919,15766,2266,-2098,2680,6839 } },
7607 { "Nikon E5700", 0, 0,
7608 { -5368,11478,2368,5537,-113,3148,-4969,10021,5782,778,9028,211 } },
7609 { "Nikon E8400", 0, 0,
7610 { 7842,-2320,-992,-8154,15718,2599,-1098,1342,7560 } },
7611 { "Nikon E8700", 0, 0,
7612 { 8489,-2583,-1036,-8051,15583,2643,-1307,1407,7354 } },
7613 { "Nikon E8800", 0, 0,
7614 { 7971,-2314,-913,-8451,15762,2894,-1442,1520,7610 } },
7615 { "Nikon COOLPIX A", 0, 0,
7616 { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } },
7617 { "Nikon COOLPIX P330", 200, 0,
7618 { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } },
7619 { "Nikon COOLPIX P340", 200, 0,
7620 { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } },
7621 { "Nikon COOLPIX P6000", 0, 0,
7622 { 9698,-3367,-914,-4706,12584,2368,-837,968,5801 } },
7623 { "Nikon COOLPIX P7000", 0, 0,
7624 { 11432,-3679,-1111,-3169,11239,2202,-791,1380,4455 } },
7625 { "Nikon COOLPIX P7100", 0, 0,
7626 { 11053,-4269,-1024,-1976,10182,2088,-526,1263,4469 } },
7627 { "Nikon COOLPIX P7700", 200, 0,
7628 { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } },
7629 { "Nikon COOLPIX P7800", 200, 0,
7630 { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } },
7631 { "Nikon 1 V3", 0, 0,
7632 { 5958,-1559,-571,-4021,11453,2939,-634,1548,5087 } },
7633 { "Nikon 1 J4", 0, 0,
7634 { 5958,-1559,-571,-4021,11453,2939,-634,1548,5087 } },
7635 { "Nikon 1 J5", 0, 0,
7636 { 7520,-2518,-645,-3844,12102,1945,-913,2249,6835 } },
7637 { "Nikon 1 S2", 200, 0,
7638 { 6612,-1342,-618,-3338,11055,2623,-174,1792,5075 } },
7639 { "Nikon 1 V2", 0, 0,
7640 { 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } },
7641 { "Nikon 1 J3", 0, 0,
7642 { 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } },
7643 { "Nikon 1 AW1", 0, 0,
7644 { 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } },
7645 { "Nikon 1 ", 0, 0, /* J1, J2, S1, V1 */
7646 { 8994,-2667,-865,-4594,12324,2552,-699,1786,6260 } },
7647 { "Olympus AIR A01", 0, 0,
7648 { 8992,-3093,-639,-2563,10721,2122,-437,1270,5473 } },
7649 { "Olympus C5050", 0, 0,
7650 { 10508,-3124,-1273,-6079,14294,1901,-1653,2306,6237 } },
7651 { "Olympus C5060", 0, 0,
7652 { 10445,-3362,-1307,-7662,15690,2058,-1135,1176,7602 } },
7653 { "Olympus C7070", 0, 0,
7654 { 10252,-3531,-1095,-7114,14850,2436,-1451,1723,6365 } },
7655 { "Olympus C70", 0, 0,
7656 { 10793,-3791,-1146,-7498,15177,2488,-1390,1577,7321 } },
7657 { "Olympus C80", 0, 0,
7658 { 8606,-2509,-1014,-8238,15714,2703,-942,979,7760 } },
7659 { "Olympus E-10", 0, 0xffc,
7660 { 12745,-4500,-1416,-6062,14542,1580,-1934,2256,6603 } },
7661 { "Olympus E-1", 0, 0,
7662 { 11846,-4767,-945,-7027,15878,1089,-2699,4122,8311 } },
7663 { "Olympus E-20", 0, 0xffc,
7664 { 13173,-4732,-1499,-5807,14036,1895,-2045,2452,7142 } },
7665 { "Olympus E-300", 0, 0,
7666 { 7828,-1761,-348,-5788,14071,1830,-2853,4518,6557 } },
7667 { "Olympus E-330", 0, 0,
7668 { 8961,-2473,-1084,-7979,15990,2067,-2319,3035,8249 } },
7669 { "Olympus E-30", 0, 0xfbc,
7670 { 8144,-1861,-1111,-7763,15894,1929,-1865,2542,7607 } },
7671 { "Olympus E-3", 0, 0xf99,
7672 { 9487,-2875,-1115,-7533,15606,2010,-1618,2100,7389 } },
7673 { "Olympus E-400", 0, 0,
7674 { 6169,-1483,-21,-7107,14761,2536,-2904,3580,8568 } },
7675 { "Olympus E-410", 0, 0xf6a,
7676 { 8856,-2582,-1026,-7761,15766,2082,-2009,2575,7469 } },
7677 { "Olympus E-420", 0, 0xfd7,
7678 { 8746,-2425,-1095,-7594,15612,2073,-1780,2309,7416 } },
7679 { "Olympus E-450", 0, 0xfd2,
7680 { 8745,-2425,-1095,-7594,15613,2073,-1780,2309,7416 } },
7681 { "Olympus E-500", 0, 0,
7682 { 8136,-1968,-299,-5481,13742,1871,-2556,4205,6630 } },
7683 { "Olympus E-510", 0, 0xf6a,
7684 { 8785,-2529,-1033,-7639,15624,2112,-1783,2300,7817 } },
7685 { "Olympus E-520", 0, 0xfd2,
7686 { 8344,-2322,-1020,-7596,15635,2048,-1748,2269,7287 } },
7687 { "Olympus E-5", 0, 0xeec,
7688 { 11200,-3783,-1325,-4576,12593,2206,-695,1742,7504 } },
7689 { "Olympus E-600", 0, 0xfaf,
7690 { 8453,-2198,-1092,-7609,15681,2008,-1725,2337,7824 } },
7691 { "Olympus E-620", 0, 0xfaf,
7692 { 8453,-2198,-1092,-7609,15681,2008,-1725,2337,7824 } },
7693 { "Olympus E-P1", 0, 0xffd,
7694 { 8343,-2050,-1021,-7715,15705,2103,-1831,2380,8235 } },
7695 { "Olympus E-P2", 0, 0xffd,
7696 { 8343,-2050,-1021,-7715,15705,2103,-1831,2380,8235 } },
7697 { "Olympus E-P3", 0, 0,
7698 { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } },
7699 { "Olympus E-P5", 0, 0,
7700 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
7701 { "Olympus E-PL1s", 0, 0,
7702 { 11409,-3872,-1393,-4572,12757,2003,-709,1810,7415 } },
7703 { "Olympus E-PL1", 0, 0,
7704 { 11408,-4289,-1215,-4286,12385,2118,-387,1467,7787 } },
7705 { "Olympus E-PL2", 0, 0xcf3,
7706 { 15030,-5552,-1806,-3987,12387,1767,-592,1670,7023 } },
7707 { "Olympus E-PL3", 0, 0,
7708 { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } },
7709 { "Olympus E-PL5", 0, 0xfcb,
7710 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
7711 { "Olympus E-PL6", 0, 0,
7712 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
7713 { "Olympus E-PL7", 0, 0,
7714 { 9197,-3190,-659,-2606,10830,2039,-458,1250,5458 } },
7715 { "Olympus E-PM1", 0, 0,
7716 { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } },
7717 { "Olympus E-PM2", 0, 0,
7718 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
7719 { "Olympus E-M10", 0, 0, /* also E-M10 Mark II */
7720 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
7721 { "Olympus E-M1", 0, 0,
7722 { 7687,-1984,-606,-4327,11928,2721,-1381,2339,6452 } },
7723 { "Olympus E-M5MarkII", 0, 0,
7724 { 9422,-3258,-711,-2655,10898,2015,-512,1354,5512 } },
7725 { "Olympus E-M5", 0, 0xfe1,
7726 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
7727 { "Olympus PEN-F", 0, 0,
7728 { 9476,-3182,-765,-2613,10958,1893,-449,1315,5268 } },
7729 { "Olympus SH-2", 0, 0,
7730 { 10156,-3425,-1077,-2611,11177,1624,-385,1592,5080 } },
7731 { "Olympus SP350", 0, 0,
7732 { 12078,-4836,-1069,-6671,14306,2578,-786,939,7418 } },
7733 { "Olympus SP3", 0, 0,
7734 { 11766,-4445,-1067,-6901,14421,2707,-1029,1217,7572 } },
7735 { "Olympus SP500UZ", 0, 0xfff,
7736 { 9493,-3415,-666,-5211,12334,3260,-1548,2262,6482 } },
7737 { "Olympus SP510UZ", 0, 0xffe,
7738 { 10593,-3607,-1010,-5881,13127,3084,-1200,1805,6721 } },
7739 { "Olympus SP550UZ", 0, 0xffe,
7740 { 11597,-4006,-1049,-5432,12799,2957,-1029,1750,6516 } },
7741 { "Olympus SP560UZ", 0, 0xff9,
7742 { 10915,-3677,-982,-5587,12986,2911,-1168,1968,6223 } },
7743 { "Olympus SP570UZ", 0, 0,
7744 { 11522,-4044,-1146,-4736,12172,2904,-988,1829,6039 } },
7745 { "Olympus STYLUS1", 0, 0,
7746 { 8360,-2420,-880,-3928,12353,1739,-1381,2416,5173 } },
7747 { "Olympus TG-4", 0, 0,
7748 { 11426,-4159,-1126,-2066,10678,1593,-120,1327,4998 } },
7749 { "Olympus XZ-10", 0, 0,
7750 { 9777,-3483,-925,-2886,11297,1800,-602,1663,5134 } },
7751 { "Olympus XZ-1", 0, 0,
7752 { 10901,-4095,-1074,-1141,9208,2293,-62,1417,5158 } },
7753 { "Olympus XZ-2", 0, 0,
7754 { 9777,-3483,-925,-2886,11297,1800,-602,1663,5134 } },
7755 { "OmniVision", 0, 0, /* DJC */
7756 { 12782,-4059,-379,-478,9066,1413,1340,1513,5176 } },
7757 { "Pentax *ist DL2", 0, 0,
7758 { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
7759 { "Pentax *ist DL", 0, 0,
7760 { 10829,-2838,-1115,-8339,15817,2696,-837,680,11939 } },
7761 { "Pentax *ist DS2", 0, 0,
7762 { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
7763 { "Pentax *ist DS", 0, 0,
7764 { 10371,-2333,-1206,-8688,16231,2602,-1230,1116,11282 } },
7765 { "Pentax *ist D", 0, 0,
7766 { 9651,-2059,-1189,-8881,16512,2487,-1460,1345,10687 } },
7767 { "Pentax K10D", 0, 0,
7768 { 9566,-2863,-803,-7170,15172,2112,-818,803,9705 } },
7769 { "Pentax K1", 0, 0,
7770 { 11095,-3157,-1324,-8377,15834,2720,-1108,947,11688 } },
7771 { "Pentax K20D", 0, 0,
7772 { 9427,-2714,-868,-7493,16092,1373,-2199,3264,7180 } },
7773 { "Pentax K200D", 0, 0,
7774 { 9186,-2678,-907,-8693,16517,2260,-1129,1094,8524 } },
7775 { "Pentax K2000", 0, 0,
7776 { 11057,-3604,-1155,-5152,13046,2329,-282,375,8104 } },
7777 { "Pentax K-m", 0, 0,
7778 { 11057,-3604,-1155,-5152,13046,2329,-282,375,8104 } },
7779 { "Pentax K-x", 0, 0,
7780 { 8843,-2837,-625,-5025,12644,2668,-411,1234,7410 } },
7781 { "Pentax K-r", 0, 0,
7782 { 9895,-3077,-850,-5304,13035,2521,-883,1768,6936 } },
7783 { "Pentax K-1", 0, 0,
7784 { 8566,-2746,-1201,-3612,12204,1550,-893,1680,6264 } },
7785 { "Pentax K-30", 0, 0,
7786 { 8710,-2632,-1167,-3995,12301,1881,-981,1719,6535 } },
7787 { "Pentax K-3 II", 0, 0,
7788 { 8626,-2607,-1155,-3995,12301,1881,-1039,1822,6925 } },
7789 { "Pentax K-3", 0, 0,
7790 { 7415,-2052,-721,-5186,12788,2682,-1446,2157,6773 } },
7791 { "Pentax K-5 II", 0, 0,
7792 { 8170,-2725,-639,-4440,12017,2744,-771,1465,6599 } },
7793 { "Pentax K-5", 0, 0,
7794 { 8713,-2833,-743,-4342,11900,2772,-722,1543,6247 } },
7795 { "Pentax K-7", 0, 0,
7796 { 9142,-2947,-678,-8648,16967,1663,-2224,2898,8615 } },
7797 { "Pentax K-S1", 0, 0,
7798 { 8512,-3211,-787,-4167,11966,2487,-638,1288,6054 } },
7799 { "Pentax K-S2", 0, 0,
7800 { 8662,-3280,-798,-3928,11771,2444,-586,1232,6054 } },
7801 { "Pentax Q-S1", 0, 0,
7802 { 12995,-5593,-1107,-1879,10139,2027,-64,1233,4919 } },
7803 { "Pentax 645D", 0, 0x3e00,
7804 { 10646,-3593,-1158,-3329,11699,1831,-667,2874,6287 } },
7805 { "Panasonic DMC-CM1", 15, 0,
7806 { 8770,-3194,-820,-2871,11281,1803,-513,1552,4434 } },
7807 { "Panasonic DMC-FZ8", 0, 0xf7f,
7808 { 8986,-2755,-802,-6341,13575,3077,-1476,2144,6379 } },
7809 { "Panasonic DMC-FZ18", 0, 0,
7810 { 9932,-3060,-935,-5809,13331,2753,-1267,2155,5575 } },
7811 { "Panasonic DMC-FZ28", 15, 0xf96,
7812 { 10109,-3488,-993,-5412,12812,2916,-1305,2140,5543 } },
7813 { "Panasonic DMC-FZ330", 15, 0,
7814 { 8378,-2798,-769,-3068,11410,1877,-538,1792,4623 } },
7815 { "Panasonic DMC-FZ300", 15, 0,
7816 { 8378,-2798,-769,-3068,11410,1877,-538,1792,4623 } },
7817 { "Panasonic DMC-FZ30", 0, 0xf94,
7818 { 10976,-4029,-1141,-7918,15491,2600,-1670,2071,8246 } },
7819 { "Panasonic DMC-FZ3", 15, 0,
7820 { 9938,-2780,-890,-4604,12393,2480,-1117,2304,4620 } },
7821 { "Panasonic DMC-FZ4", 15, 0,
7822 { 13639,-5535,-1371,-1698,9633,2430,316,1152,4108 } },
7823 { "Panasonic DMC-FZ50", 0, 0,
7824 { 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } },
7825 { "Panasonic DMC-FZ7", 15, 0,
7826 { 11532,-4324,-1066,-2375,10847,1749,-564,1699,4351 } },
7827 { "Leica V-LUX1", 0, 0,
7828 { 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } },
7829 { "Panasonic DMC-L10", 15, 0xf96,
7830 { 8025,-1942,-1050,-7920,15904,2100,-2456,3005,7039 } },
7831 { "Panasonic DMC-L1", 0, 0xf7f,
7832 { 8054,-1885,-1025,-8349,16367,2040,-2805,3542,7629 } },
7833 { "Leica DIGILUX 3", 0, 0xf7f,
7834 { 8054,-1885,-1025,-8349,16367,2040,-2805,3542,7629 } },
7835 { "Panasonic DMC-LC1", 0, 0,
7836 { 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } },
7837 { "Leica DIGILUX 2", 0, 0,
7838 { 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } },
7839 { "Panasonic DMC-LX100", 15, 0,
7840 { 8844,-3538,-768,-3709,11762,2200,-698,1792,5220 } },
7841 { "Leica D-LUX (Typ 109)", 15, 0,
7842 { 8844,-3538,-768,-3709,11762,2200,-698,1792,5220 } },
7843 { "Panasonic DMC-LF1", 15, 0,
7844 { 9379,-3267,-816,-3227,11560,1881,-926,1928,5340 } },
7845 { "Leica C (Typ 112)", 15, 0,
7846 { 9379,-3267,-816,-3227,11560,1881,-926,1928,5340 } },
7847 { "Panasonic DMC-LX1", 0, 0xf7f,
7848 { 10704,-4187,-1230,-8314,15952,2501,-920,945,8927 } },
7849 { "Leica D-LUX2", 0, 0xf7f,
7850 { 10704,-4187,-1230,-8314,15952,2501,-920,945,8927 } },
7851 { "Panasonic DMC-LX2", 0, 0,
7852 { 8048,-2810,-623,-6450,13519,3272,-1700,2146,7049 } },
7853 { "Leica D-LUX3", 0, 0,
7854 { 8048,-2810,-623,-6450,13519,3272,-1700,2146,7049 } },
7855 { "Panasonic DMC-LX3", 15, 0,
7856 { 8128,-2668,-655,-6134,13307,3161,-1782,2568,6083 } },
7857 { "Leica D-LUX 4", 15, 0,
7858 { 8128,-2668,-655,-6134,13307,3161,-1782,2568,6083 } },
7859 { "Panasonic DMC-LX5", 15, 0,
7860 { 10909,-4295,-948,-1333,9306,2399,22,1738,4582 } },
7861 { "Leica D-LUX 5", 15, 0,
7862 { 10909,-4295,-948,-1333,9306,2399,22,1738,4582 } },
7863 { "Panasonic DMC-LX7", 15, 0,
7864 { 10148,-3743,-991,-2837,11366,1659,-701,1893,4899 } },
7865 { "Leica D-LUX 6", 15, 0,
7866 { 10148,-3743,-991,-2837,11366,1659,-701,1893,4899 } },
7867 { "Panasonic DMC-FZ1000", 15, 0,
7868 { 7830,-2696,-763,-3325,11667,1866,-641,1712,4824 } },
7869 { "Leica V-LUX (Typ 114)", 15, 0,
7870 { 7830,-2696,-763,-3325,11667,1866,-641,1712,4824 } },
7871 { "Panasonic DMC-FZ100", 15, 0xfff,
7872 { 16197,-6146,-1761,-2393,10765,1869,366,2238,5248 } },
7873 { "Leica V-LUX 2", 15, 0xfff,
7874 { 16197,-6146,-1761,-2393,10765,1869,366,2238,5248 } },
7875 { "Panasonic DMC-FZ150", 15, 0xfff,
7876 { 11904,-4541,-1189,-2355,10899,1662,-296,1586,4289 } },
7877 { "Leica V-LUX 3", 15, 0xfff,
7878 { 11904,-4541,-1189,-2355,10899,1662,-296,1586,4289 } },
7879 { "Panasonic DMC-FZ200", 15, 0xfff,
7880 { 8112,-2563,-740,-3730,11784,2197,-941,2075,4933 } },
7881 { "Leica V-LUX 4", 15, 0xfff,
7882 { 8112,-2563,-740,-3730,11784,2197,-941,2075,4933 } },
7883 { "Panasonic DMC-FX150", 15, 0xfff,
7884 { 9082,-2907,-925,-6119,13377,3058,-1797,2641,5609 } },
7885 { "Panasonic DMC-G10", 0, 0,
7886 { 10113,-3400,-1114,-4765,12683,2317,-377,1437,6710 } },
7887 { "Panasonic DMC-G1", 15, 0xf94,
7888 { 8199,-2065,-1056,-8124,16156,2033,-2458,3022,7220 } },
7889 { "Panasonic DMC-G2", 15, 0xf3c,
7890 { 10113,-3400,-1114,-4765,12683,2317,-377,1437,6710 } },
7891 { "Panasonic DMC-G3", 15, 0xfff,
7892 { 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } },
7893 { "Panasonic DMC-G5", 15, 0xfff,
7894 { 7798,-2562,-740,-3879,11584,2613,-1055,2248,5434 } },
7895 { "Panasonic DMC-G6", 15, 0xfff,
7896 { 8294,-2891,-651,-3869,11590,2595,-1183,2267,5352 } },
7897 { "Panasonic DMC-G7", 15, 0xfff,
7898 { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } },
7899 { "Panasonic DMC-GF1", 15, 0xf92,
7900 { 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } },
7901 { "Panasonic DMC-GF2", 15, 0xfff,
7902 { 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } },
7903 { "Panasonic DMC-GF3", 15, 0xfff,
7904 { 9051,-2468,-1204,-5212,13276,2121,-1197,2510,6890 } },
7905 { "Panasonic DMC-GF5", 15, 0xfff,
7906 { 8228,-2945,-660,-3938,11792,2430,-1094,2278,5793 } },
7907 { "Panasonic DMC-GF6", 15, 0,
7908 { 8130,-2801,-946,-3520,11289,2552,-1314,2511,5791 } },
7909 { "Panasonic DMC-GF7", 15, 0,
7910 { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } },
7911 { "Panasonic DMC-GF8", 15, 0,
7912 { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } },
7913 { "Panasonic DMC-GH1", 15, 0xf92,
7914 { 6299,-1466,-532,-6535,13852,2969,-2331,3112,5984 } },
7915 { "Panasonic DMC-GH2", 15, 0xf95,
7916 { 7780,-2410,-806,-3913,11724,2484,-1018,2390,5298 } },
7917 { "Panasonic DMC-GH3", 15, 0,
7918 { 6559,-1752,-491,-3672,11407,2586,-962,1875,5130 } },
7919 { "Panasonic DMC-GH4", 15, 0,
7920 { 7122,-2108,-512,-3155,11201,2231,-541,1423,5045 } },
7921 { "Panasonic DMC-GM1", 15, 0,
7922 { 6770,-1895,-744,-5232,13145,2303,-1664,2691,5703 } },
7923 { "Panasonic DMC-GM5", 15, 0,
7924 { 8238,-3244,-679,-3921,11814,2384,-836,2022,5852 } },
7925 { "Panasonic DMC-GX1", 15, 0,
7926 { 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } },
7927 { "Panasonic DMC-GX7", 15, 0,
7928 { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } },
7929 { "Panasonic DMC-GX8", 15, 0,
7930 { 7564,-2263,-606,-3148,11239,2177,-540,1435,4853 } },
7931 { "Panasonic DMC-TZ1", 15, 0,
7932 { 7790,-2736,-755,-3452,11870,1769,-628,1647,4898 } },
7933 { "Panasonic DMC-ZS1", 15, 0,
7934 { 7790,-2736,-755,-3452,11870,1769,-628,1647,4898 } },
7935 { "Panasonic DMC-TZ6", 15, 0,
7936 { 8607,-2822,-808,-3755,11930,2049,-820,2060,5224 } },
7937 { "Panasonic DMC-ZS4", 15, 0,
7938 { 8607,-2822,-808,-3755,11930,2049,-820,2060,5224 } },
7939 { "Panasonic DMC-TZ7", 15, 0,
7940 { 8802,-3135,-789,-3151,11468,1904,-550,1745,4810 } },
7941 { "Panasonic DMC-ZS5", 15, 0,
7942 { 8802,-3135,-789,-3151,11468,1904,-550,1745,4810 } },
7943 { "Panasonic DMC-TZ8", 15, 0,
7944 { 8550,-2908,-842,-3195,11529,1881,-338,1603,4631 } },
7945 { "Panasonic DMC-ZS6", 15, 0,
7946 { 8550,-2908,-842,-3195,11529,1881,-338,1603,4631 } },
7947 { "Leica S (Typ 007)", 0, 0,
7948 { 6063,-2234,-231,-5210,13787,1500,-1043,2866,6997 } },
7949 { "Leica X", 0, 0, /* X and X-U, both (Typ 113) */
7950 { 7712,-2059,-653,-3882,11494,2726,-710,1332,5958 } },
7951 { "Leica Q (Typ 116)", 0, 0,
7952 { 11865,-4523,-1441,-5423,14458,935,-1587,2687,4830 } },
7953 { "Leica M (Typ 262)", 0, 0,
7954 { 6653,-1486,-611,-4221,13303,929,-881,2416,7226 } },
7955 { "Leica SL (Typ 601)", 0, 0,
7956 { 11865,-4523,-1441,-5423,14458,935,-1587,2687,4830} },
7957 { "Phase One H 20", 0, 0, /* DJC */
7958 { 1313,1855,-109,-6715,15908,808,-327,1840,6020 } },
7959 { "Phase One H 25", 0, 0,
7960 { 2905,732,-237,-8134,16626,1476,-3038,4253,7517 } },
7961 { "Phase One P 2", 0, 0,
7962 { 2905,732,-237,-8134,16626,1476,-3038,4253,7517 } },
7963 { "Phase One P 30", 0, 0,
7964 { 4516,-245,-37,-7020,14976,2173,-3206,4671,7087 } },
7965 { "Phase One P 45", 0, 0,
7966 { 5053,-24,-117,-5684,14076,1702,-2619,4492,5849 } },
7967 { "Phase One P40", 0, 0,
7968 { 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } },
7969 { "Phase One P65", 0, 0,
7970 { 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } },
7971 { "Photron BC2-HD", 0, 0, /* DJC */
7972 { 14603,-4122,-528,-1810,9794,2017,-297,2763,5936 } },
7973 { "Red One", 704, 0xffff, /* DJC */
7974 { 21014,-7891,-2613,-3056,12201,856,-2203,5125,8042 } },
7975 { "Ricoh GR II", 0, 0,
7976 { 4630,-834,-423,-4977,12805,2417,-638,1467,6115 } },
7978 { 3708,-543,-160,-5381,12254,3556,-1471,1929,8234 } },
7979 { "Samsung EX1", 0, 0x3e00,
7980 { 8898,-2498,-994,-3144,11328,2066,-760,1381,4576 } },
7981 { "Samsung EX2F", 0, 0x7ff,
7982 { 10648,-3897,-1055,-2022,10573,1668,-492,1611,4742 } },
7983 { "Samsung EK-GN120", 0, 0,
7984 { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } },
7985 { "Samsung NX mini", 0, 0,
7986 { 5222,-1196,-550,-6540,14649,2009,-1666,2819,5657 } },
7987 { "Samsung NX3300", 0, 0,
7988 { 8060,-2933,-761,-4504,12890,1762,-630,1489,5227 } },
7989 { "Samsung NX3000", 0, 0,
7990 { 8060,-2933,-761,-4504,12890,1762,-630,1489,5227 } },
7991 { "Samsung NX30", 0, 0, /* NX30, NX300, NX300M */
7992 { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } },
7993 { "Samsung NX2000", 0, 0,
7994 { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } },
7995 { "Samsung NX2", 0, 0xfff, /* NX20, NX200, NX210 */
7996 { 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } },
7997 { "Samsung NX1000", 0, 0,
7998 { 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } },
7999 { "Samsung NX1100", 0, 0,
8000 { 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } },
8001 { "Samsung NX11", 0, 0,
8002 { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } },
8003 { "Samsung NX10", 0, 0, /* also NX100 */
8004 { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } },
8005 { "Samsung NX500", 0, 0,
8006 { 10686,-4042,-1052,-3595,13238,276,-464,1259,5931 } },
8007 { "Samsung NX5", 0, 0,
8008 { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } },
8009 { "Samsung NX1", 0, 0,
8010 { 10686,-4042,-1052,-3595,13238,276,-464,1259,5931 } },
8011 { "Samsung WB2000", 0, 0xfff,
8012 { 12093,-3557,-1155,-1000,9534,1733,-22,1787,4576 } },
8013 { "Samsung GX-1", 0, 0,
8014 { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
8015 { "Samsung GX20", 0, 0, /* copied from Pentax K20D */
8016 { 9427,-2714,-868,-7493,16092,1373,-2199,3264,7180 } },
8017 { "Samsung S85", 0, 0, /* DJC */
8018 { 11885,-3968,-1473,-4214,12299,1916,-835,1655,5549 } },
8019 { "Sinar", 0, 0, /* DJC */
8020 { 16442,-2956,-2422,-2877,12128,750,-1136,6066,4559 } },
8021 { "Sony DSC-F828", 0, 0,
8022 { 7924,-1910,-777,-8226,15459,2998,-1517,2199,6818,-7242,11401,3481 } },
8023 { "Sony DSC-R1", 0, 0,
8024 { 8512,-2641,-694,-8042,15670,2526,-1821,2117,7414 } },
8025 { "Sony DSC-V3", 0, 0,
8026 { 7511,-2571,-692,-7894,15088,3060,-948,1111,8128 } },
8027 { "Sony DSC-RX100M", 0, 0, /* M2, M3, and M4 */
8028 { 6596,-2079,-562,-4782,13016,1933,-970,1581,5181 } },
8029 { "Sony DSC-RX100", 0, 0,
8030 { 8651,-2754,-1057,-3464,12207,1373,-568,1398,4434 } },
8031 { "Sony DSC-RX10", 0, 0, /* also RX10M2 */
8032 { 6679,-1825,-745,-5047,13256,1953,-1580,2422,5183 } },
8033 { "Sony DSC-RX1RM2", 0, 0,
8034 { 6629,-1900,-483,-4618,12349,2550,-622,1381,6514 } },
8035 { "Sony DSC-RX1", 0, 0,
8036 { 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } },
8037 { "Sony DSLR-A100", 0, 0xfeb,
8038 { 9437,-2811,-774,-8405,16215,2290,-710,596,7181 } },
8039 { "Sony DSLR-A290", 0, 0,
8040 { 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } },
8041 { "Sony DSLR-A2", 0, 0,
8042 { 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } },
8043 { "Sony DSLR-A300", 0, 0,
8044 { 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } },
8045 { "Sony DSLR-A330", 0, 0,
8046 { 9847,-3091,-929,-8485,16346,2225,-714,595,7103 } },
8047 { "Sony DSLR-A350", 0, 0xffc,
8048 { 6038,-1484,-578,-9146,16746,2513,-875,746,7217 } },
8049 { "Sony DSLR-A380", 0, 0,
8050 { 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } },
8051 { "Sony DSLR-A390", 0, 0,
8052 { 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } },
8053 { "Sony DSLR-A450", 0, 0xfeb,
8054 { 4950,-580,-103,-5228,12542,3029,-709,1435,7371 } },
8055 { "Sony DSLR-A580", 0, 0xfeb,
8056 { 5932,-1492,-411,-4813,12285,2856,-741,1524,6739 } },
8057 { "Sony DSLR-A500", 0, 0xfeb,
8058 { 6046,-1127,-278,-5574,13076,2786,-691,1419,7625 } },
8059 { "Sony DSLR-A5", 0, 0xfeb,
8060 { 4950,-580,-103,-5228,12542,3029,-709,1435,7371 } },
8061 { "Sony DSLR-A700", 0, 0,
8062 { 5775,-805,-359,-8574,16295,2391,-1943,2341,7249 } },
8063 { "Sony DSLR-A850", 0, 0,
8064 { 5413,-1162,-365,-5665,13098,2866,-608,1179,8440 } },
8065 { "Sony DSLR-A900", 0, 0,
8066 { 5209,-1072,-397,-8845,16120,2919,-1618,1803,8654 } },
8067 { "Sony ILCA-68", 0, 0,
8068 { 6435,-1903,-536,-4722,12449,2550,-663,1363,6517 } },
8069 { "Sony ILCA-77M2", 0, 0,
8070 { 5991,-1732,-443,-4100,11989,2381,-704,1467,5992 } },
8071 { "Sony ILCE-6300", 0, 0,
8072 { 5973,-1695,-419,-3826,11797,2293,-639,1398,5789 } },
8073 { "Sony ILCE-7M2", 0, 0,
8074 { 5271,-712,-347,-6153,13653,2763,-1601,2366,7242 } },
8075 { "Sony ILCE-7S", 0, 0, /* also ILCE-7SM2 */
8076 { 5838,-1430,-246,-3497,11477,2297,-748,1885,5778 } },
8077 { "Sony ILCE-7RM2", 0, 0,
8078 { 6629,-1900,-483,-4618,12349,2550,-622,1381,6514 } },
8079 { "Sony ILCE-7R", 0, 0,
8080 { 4913,-541,-202,-6130,13513,2906,-1564,2151,7183 } },
8081 { "Sony ILCE-7", 0, 0,
8082 { 5271,-712,-347,-6153,13653,2763,-1601,2366,7242 } },
8083 { "Sony ILCE", 0, 0, /* 3000, 5000, 5100, 6000, and QX1 */
8084 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
8085 { "Sony NEX-5N", 0, 0,
8086 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
8087 { "Sony NEX-5R", 0, 0,
8088 { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } },
8089 { "Sony NEX-5T", 0, 0,
8090 { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } },
8091 { "Sony NEX-3N", 0, 0,
8092 { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } },
8093 { "Sony NEX-3", 138, 0, /* DJC */
8094 { 6907,-1256,-645,-4940,12621,2320,-1710,2581,6230 } },
8095 { "Sony NEX-5", 116, 0, /* DJC */
8096 { 6807,-1350,-342,-4216,11649,2567,-1089,2001,6420 } },
8097 { "Sony NEX-3", 0, 0, /* Adobe */
8098 { 6549,-1550,-436,-4880,12435,2753,-854,1868,6976 } },
8099 { "Sony NEX-5", 0, 0, /* Adobe */
8100 { 6549,-1550,-436,-4880,12435,2753,-854,1868,6976 } },
8101 { "Sony NEX-6", 0, 0,
8102 { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } },
8103 { "Sony NEX-7", 0, 0,
8104 { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } },
8105 { "Sony NEX", 0, 0, /* NEX-C3, NEX-F3 */
8106 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
8107 { "Sony SLT-A33", 0, 0,
8108 { 6069,-1221,-366,-5221,12779,2734,-1024,2066,6834 } },
8109 { "Sony SLT-A35", 0, 0,
8110 { 5986,-1618,-415,-4557,11820,3120,-681,1404,6971 } },
8111 { "Sony SLT-A37", 0, 0,
8112 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
8113 { "Sony SLT-A55", 0, 0,
8114 { 5932,-1492,-411,-4813,12285,2856,-741,1524,6739 } },
8115 { "Sony SLT-A57", 0, 0,
8116 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
8117 { "Sony SLT-A58", 0, 0,
8118 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
8119 { "Sony SLT-A65", 0, 0,
8120 { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } },
8121 { "Sony SLT-A77", 0, 0,
8122 { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } },
8123 { "Sony SLT-A99", 0, 0,
8124 { 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } },
8126 double cam_xyz[4][3];
8130 sprintf (name, "%s %s", make, model);
8131 for (i=0; i < sizeof table / sizeof *table; i++)
8132 if (!strncmp (name, table[i].prefix, strlen(table[i].prefix))) {
8133 if (table[i].black) black = (ushort) table[i].black;
8134 if (table[i].maximum) maximum = (ushort) table[i].maximum;
8135 if (table[i].trans[0]) {
8136 for (raw_color = j=0; j < 12; j++)
8137 ((double *)cam_xyz)[j] = table[i].trans[j] / 10000.0;
8138 cam_xyz_coeff (rgb_cam, cam_xyz);
8144 void CLASS simple_coeff (int index)
8146 static const float table[][12] = {
8147 /* index 0 -- all Foveon cameras */
8148 { 1.4032,-0.2231,-0.1016,-0.5263,1.4816,0.017,-0.0112,0.0183,0.9113 },
8149 /* index 1 -- Kodak DC20 and DC25 */
8150 { 2.25,0.75,-1.75,-0.25,-0.25,0.75,0.75,-0.25,-0.25,-1.75,0.75,2.25 },
8151 /* index 2 -- Logitech Fotoman Pixtura */
8152 { 1.893,-0.418,-0.476,-0.495,1.773,-0.278,-1.017,-0.655,2.672 },
8153 /* index 3 -- Nikon E880, E900, and E990 */
8154 { -1.936280, 1.800443, -1.448486, 2.584324,
8155 1.405365, -0.524955, -0.289090, 0.408680,
8156 -1.204965, 1.082304, 2.941367, -1.818705 }
8160 for (raw_color = i=0; i < 3; i++)
8161 FORCC rgb_cam[i][c] = table[index][i*colors+c];
8164 short CLASS guess_byte_order (int words)
8168 double diff, sum[2] = {0,0};
8170 fread (test[0], 2, 2, ifp);
8171 for (words-=2; words--; ) {
8172 fread (test[t], 2, 1, ifp);
8173 for (msb=0; msb < 2; msb++) {
8174 diff = (test[t^2][msb] << 8 | test[t^2][!msb])
8175 - (test[t ][msb] << 8 | test[t ][!msb]);
8176 sum[msb] += diff*diff;
8180 return sum[0] < sum[1] ? 0x4d4d : 0x4949;
8183 float CLASS find_green (int bps, int bite, int off0, int off1)
8186 int vbits, col, i, c;
8187 ushort img[2][2064];
8191 fseek (ifp, c ? off1:off0, SEEK_SET);
8192 for (vbits=col=0; col < width; col++) {
8193 for (vbits -= bps; vbits < 0; vbits += bite) {
8195 for (i=0; i < bite; i+=8)
8196 bitbuf |= (unsigned) (fgetc(ifp) << i);
8198 img[c][col] = bitbuf << (64-bps-vbits) >> (64-bps);
8202 sum[ c & 1] += ABS(img[0][c]-img[1][c+1]);
8203 sum[~c & 1] += ABS(img[1][c]-img[0][c+1]);
8205 return 100 * log(sum[0]/sum[1]);
8209 Identify which camera created this file, and set global variables
8212 void CLASS identify()
8214 static const short pana[][6] = {
8215 { 3130, 1743, 4, 0, -6, 0 },
8216 { 3130, 2055, 4, 0, -6, 0 },
8217 { 3130, 2319, 4, 0, -6, 0 },
8218 { 3170, 2103, 18, 0,-42, 20 },
8219 { 3170, 2367, 18, 13,-42,-21 },
8220 { 3177, 2367, 0, 0, -1, 0 },
8221 { 3304, 2458, 0, 0, -1, 0 },
8222 { 3330, 2463, 9, 0, -5, 0 },
8223 { 3330, 2479, 9, 0,-17, 4 },
8224 { 3370, 1899, 15, 0,-44, 20 },
8225 { 3370, 2235, 15, 0,-44, 20 },
8226 { 3370, 2511, 15, 10,-44,-21 },
8227 { 3690, 2751, 3, 0, -8, -3 },
8228 { 3710, 2751, 0, 0, -3, 0 },
8229 { 3724, 2450, 0, 0, 0, -2 },
8230 { 3770, 2487, 17, 0,-44, 19 },
8231 { 3770, 2799, 17, 15,-44,-19 },
8232 { 3880, 2170, 6, 0, -6, 0 },
8233 { 4060, 3018, 0, 0, 0, -2 },
8234 { 4290, 2391, 3, 0, -8, -1 },
8235 { 4330, 2439, 17, 15,-44,-19 },
8236 { 4508, 2962, 0, 0, -3, -4 },
8237 { 4508, 3330, 0, 0, -3, -6 },
8239 static const ushort canon[][11] = {
8240 { 1944, 1416, 0, 0, 48, 0 },
8241 { 2144, 1560, 4, 8, 52, 2, 0, 0, 0, 25 },
8242 { 2224, 1456, 48, 6, 0, 2 },
8243 { 2376, 1728, 12, 6, 52, 2 },
8244 { 2672, 1968, 12, 6, 44, 2 },
8245 { 3152, 2068, 64, 12, 0, 0, 16 },
8246 { 3160, 2344, 44, 12, 4, 4 },
8247 { 3344, 2484, 4, 6, 52, 6 },
8248 { 3516, 2328, 42, 14, 0, 0 },
8249 { 3596, 2360, 74, 12, 0, 0 },
8250 { 3744, 2784, 52, 12, 8, 12 },
8251 { 3944, 2622, 30, 18, 6, 2 },
8252 { 3948, 2622, 42, 18, 0, 2 },
8253 { 3984, 2622, 76, 20, 0, 2, 14 },
8254 { 4104, 3048, 48, 12, 24, 12 },
8255 { 4116, 2178, 4, 2, 0, 0 },
8256 { 4152, 2772, 192, 12, 0, 0 },
8257 { 4160, 3124, 104, 11, 8, 65 },
8258 { 4176, 3062, 96, 17, 8, 0, 0, 16, 0, 7, 0x49 },
8259 { 4192, 3062, 96, 17, 24, 0, 0, 16, 0, 0, 0x49 },
8260 { 4312, 2876, 22, 18, 0, 2 },
8261 { 4352, 2874, 62, 18, 0, 0 },
8262 { 4476, 2954, 90, 34, 0, 0 },
8263 { 4480, 3348, 12, 10, 36, 12, 0, 0, 0, 18, 0x49 },
8264 { 4480, 3366, 80, 50, 0, 0 },
8265 { 4496, 3366, 80, 50, 12, 0 },
8266 { 4768, 3516, 96, 16, 0, 0, 0, 16 },
8267 { 4832, 3204, 62, 26, 0, 0 },
8268 { 4832, 3228, 62, 51, 0, 0 },
8269 { 5108, 3349, 98, 13, 0, 0 },
8270 { 5120, 3318, 142, 45, 62, 0 },
8271 { 5280, 3528, 72, 52, 0, 0 },
8272 { 5344, 3516, 142, 51, 0, 0 },
8273 { 5344, 3584, 126,100, 0, 2 },
8274 { 5360, 3516, 158, 51, 0, 0 },
8275 { 5568, 3708, 72, 38, 0, 0 },
8276 { 5632, 3710, 96, 17, 0, 0, 0, 16, 0, 0, 0x49 },
8277 { 5712, 3774, 62, 20, 10, 2 },
8278 { 5792, 3804, 158, 51, 0, 0 },
8279 { 5920, 3950, 122, 80, 2, 0 },
8280 { 6096, 4056, 72, 34, 0, 0 },
8281 { 6288, 4056, 264, 34, 0, 0 },
8282 { 8896, 5920, 160, 64, 0, 0 },
8284 static const struct {
8288 { 0x168, "EOS 10D" }, { 0x001, "EOS-1D" },
8289 { 0x175, "EOS 20D" }, { 0x174, "EOS-1D Mark II" },
8290 { 0x234, "EOS 30D" }, { 0x232, "EOS-1D Mark II N" },
8291 { 0x190, "EOS 40D" }, { 0x169, "EOS-1D Mark III" },
8292 { 0x261, "EOS 50D" }, { 0x281, "EOS-1D Mark IV" },
8293 { 0x287, "EOS 60D" }, { 0x167, "EOS-1DS" },
8294 { 0x325, "EOS 70D" },
8295 { 0x350, "EOS 80D" }, { 0x328, "EOS-1D X Mark II" },
8296 { 0x170, "EOS 300D" }, { 0x188, "EOS-1Ds Mark II" },
8297 { 0x176, "EOS 450D" }, { 0x215, "EOS-1Ds Mark III" },
8298 { 0x189, "EOS 350D" }, { 0x324, "EOS-1D C" },
8299 { 0x236, "EOS 400D" }, { 0x269, "EOS-1D X" },
8300 { 0x252, "EOS 500D" }, { 0x213, "EOS 5D" },
8301 { 0x270, "EOS 550D" }, { 0x218, "EOS 5D Mark II" },
8302 { 0x286, "EOS 600D" }, { 0x285, "EOS 5D Mark III" },
8303 { 0x301, "EOS 650D" }, { 0x302, "EOS 6D" },
8304 { 0x326, "EOS 700D" }, { 0x250, "EOS 7D" },
8305 { 0x393, "EOS 750D" }, { 0x289, "EOS 7D Mark II" },
8306 { 0x347, "EOS 760D" },
8307 { 0x254, "EOS 1000D" },
8308 { 0x288, "EOS 1100D" },
8309 { 0x327, "EOS 1200D" }, { 0x382, "Canon EOS 5DS" },
8310 { 0x404, "EOS 1300D" }, { 0x401, "Canon EOS 5DS R" },
8311 { 0x346, "EOS 100D" },
8313 { 0x002, "DSC-R1" }, { 0x100, "DSLR-A100" },
8314 { 0x101, "DSLR-A900" }, { 0x102, "DSLR-A700" },
8315 { 0x103, "DSLR-A200" }, { 0x104, "DSLR-A350" },
8316 { 0x105, "DSLR-A300" }, { 0x108, "DSLR-A330" },
8317 { 0x109, "DSLR-A230" }, { 0x10a, "DSLR-A290" },
8318 { 0x10d, "DSLR-A850" }, { 0x111, "DSLR-A550" },
8319 { 0x112, "DSLR-A500" }, { 0x113, "DSLR-A450" },
8320 { 0x116, "NEX-5" }, { 0x117, "NEX-3" },
8321 { 0x118, "SLT-A33" }, { 0x119, "SLT-A55V" },
8322 { 0x11a, "DSLR-A560" }, { 0x11b, "DSLR-A580" },
8323 { 0x11c, "NEX-C3" }, { 0x11d, "SLT-A35" },
8324 { 0x11e, "SLT-A65V" }, { 0x11f, "SLT-A77V" },
8325 { 0x120, "NEX-5N" }, { 0x121, "NEX-7" },
8326 { 0x123, "SLT-A37" }, { 0x124, "SLT-A57" },
8327 { 0x125, "NEX-F3" }, { 0x126, "SLT-A99V" },
8328 { 0x127, "NEX-6" }, { 0x128, "NEX-5R" },
8329 { 0x129, "DSC-RX100" }, { 0x12a, "DSC-RX1" },
8330 { 0x12e, "ILCE-3000" }, { 0x12f, "SLT-A58" },
8331 { 0x131, "NEX-3N" }, { 0x132, "ILCE-7" },
8332 { 0x133, "NEX-5T" }, { 0x134, "DSC-RX100M2" },
8333 { 0x135, "DSC-RX10" }, { 0x136, "DSC-RX1R" },
8334 { 0x137, "ILCE-7R" }, { 0x138, "ILCE-6000" },
8335 { 0x139, "ILCE-5000" }, { 0x13d, "DSC-RX100M3" },
8336 { 0x13e, "ILCE-7S" }, { 0x13f, "ILCA-77M2" },
8337 { 0x153, "ILCE-5100" }, { 0x154, "ILCE-7M2" },
8338 { 0x155, "DSC-RX100M4" },{ 0x156, "DSC-RX10M2" },
8339 { 0x158, "DSC-RX1RM2" }, { 0x15a, "ILCE-QX1" },
8340 { 0x15b, "ILCE-7RM2" }, { 0x15e, "ILCE-7SM2" },
8341 { 0x161, "ILCA-68" }, { 0x165, "ILCE-6300" },
8343 static const struct {
8346 uchar lm, tm, rm, bm, lf, cf, max, flags;
8347 char make[10], model[20];
8350 { 786432,1024, 768, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-080C" },
8351 { 1447680,1392,1040, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-145C" },
8352 { 1920000,1600,1200, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-201C" },
8353 { 5067304,2588,1958, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-510C" },
8354 { 5067316,2588,1958, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-510C",12 },
8355 { 10134608,2588,1958, 0, 0, 0, 0, 9,0x94,0,0,"AVT","F-510C" },
8356 { 10134620,2588,1958, 0, 0, 0, 0, 9,0x94,0,0,"AVT","F-510C",12 },
8357 { 16157136,3272,2469, 0, 0, 0, 0, 9,0x94,0,0,"AVT","F-810C" },
8358 { 15980544,3264,2448, 0, 0, 0, 0, 8,0x61,0,1,"AgfaPhoto","DC-833m" },
8359 { 9631728,2532,1902, 0, 0, 0, 0,96,0x61,0,0,"Alcatel","5035D" },
8360 { 2868726,1384,1036, 0, 0, 0, 0,64,0x49,0,8,"Baumer","TXG14",1078 },
8361 { 5298000,2400,1766,12,12,44, 2,40,0x94,0,2,"Canon","PowerShot SD300" },
8362 { 6553440,2664,1968, 4, 4,44, 4,40,0x94,0,2,"Canon","PowerShot A460" },
8363 { 6573120,2672,1968,12, 8,44, 0,40,0x94,0,2,"Canon","PowerShot A610" },
8364 { 6653280,2672,1992,10, 6,42, 2,40,0x94,0,2,"Canon","PowerShot A530" },
8365 { 7710960,2888,2136,44, 8, 4, 0,40,0x94,0,2,"Canon","PowerShot S3 IS" },
8366 { 9219600,3152,2340,36,12, 4, 0,40,0x94,0,2,"Canon","PowerShot A620" },
8367 { 9243240,3152,2346,12, 7,44,13,40,0x49,0,2,"Canon","PowerShot A470" },
8368 { 10341600,3336,2480, 6, 5,32, 3,40,0x94,0,2,"Canon","PowerShot A720 IS" },
8369 { 10383120,3344,2484,12, 6,44, 6,40,0x94,0,2,"Canon","PowerShot A630" },
8370 { 12945240,3736,2772,12, 6,52, 6,40,0x94,0,2,"Canon","PowerShot A640" },
8371 { 15636240,4104,3048,48,12,24,12,40,0x94,0,2,"Canon","PowerShot A650" },
8372 { 15467760,3720,2772, 6,12,30, 0,40,0x94,0,2,"Canon","PowerShot SX110 IS" },
8373 { 15534576,3728,2778,12, 9,44, 9,40,0x94,0,2,"Canon","PowerShot SX120 IS" },
8374 { 18653760,4080,3048,24,12,24,12,40,0x94,0,2,"Canon","PowerShot SX20 IS" },
8375 { 19131120,4168,3060,92,16, 4, 1,40,0x94,0,2,"Canon","PowerShot SX220 HS" },
8376 { 21936096,4464,3276,25,10,73,12,40,0x16,0,2,"Canon","PowerShot SX30 IS" },
8377 { 24724224,4704,3504, 8,16,56, 8,40,0x94,0,2,"Canon","PowerShot A3300 IS" },
8378 { 30858240,5248,3920, 8,16,56,16,40,0x94,0,2,"Canon","IXUS 160" },
8379 { 1976352,1632,1211, 0, 2, 0, 1, 0,0x94,0,1,"Casio","QV-2000UX" },
8380 { 3217760,2080,1547, 0, 0,10, 1, 0,0x94,0,1,"Casio","QV-3*00EX" },
8381 { 6218368,2585,1924, 0, 0, 9, 0, 0,0x94,0,1,"Casio","QV-5700" },
8382 { 7816704,2867,2181, 0, 0,34,36, 0,0x16,0,1,"Casio","EX-Z60" },
8383 { 2937856,1621,1208, 0, 0, 1, 0, 0,0x94,7,13,"Casio","EX-S20" },
8384 { 4948608,2090,1578, 0, 0,32,34, 0,0x94,7,1,"Casio","EX-S100" },
8385 { 6054400,2346,1720, 2, 0,32, 0, 0,0x94,7,1,"Casio","QV-R41" },
8386 { 7426656,2568,1928, 0, 0, 0, 0, 0,0x94,0,1,"Casio","EX-P505" },
8387 { 7530816,2602,1929, 0, 0,22, 0, 0,0x94,7,1,"Casio","QV-R51" },
8388 { 7542528,2602,1932, 0, 0,32, 0, 0,0x94,7,1,"Casio","EX-Z50" },
8389 { 7562048,2602,1937, 0, 0,25, 0, 0,0x16,7,1,"Casio","EX-Z500" },
8390 { 7753344,2602,1986, 0, 0,32,26, 0,0x94,7,1,"Casio","EX-Z55" },
8391 { 9313536,2858,2172, 0, 0,14,30, 0,0x94,7,1,"Casio","EX-P600" },
8392 { 10834368,3114,2319, 0, 0,27, 0, 0,0x94,0,1,"Casio","EX-Z750" },
8393 { 10843712,3114,2321, 0, 0,25, 0, 0,0x94,0,1,"Casio","EX-Z75" },
8394 { 10979200,3114,2350, 0, 0,32,32, 0,0x94,7,1,"Casio","EX-P700" },
8395 { 12310144,3285,2498, 0, 0, 6,30, 0,0x94,0,1,"Casio","EX-Z850" },
8396 { 12489984,3328,2502, 0, 0,47,35, 0,0x94,0,1,"Casio","EX-Z8" },
8397 { 15499264,3754,2752, 0, 0,82, 0, 0,0x94,0,1,"Casio","EX-Z1050" },
8398 { 18702336,4096,3044, 0, 0,24, 0,80,0x94,7,1,"Casio","EX-ZR100" },
8399 { 7684000,2260,1700, 0, 0, 0, 0,13,0x94,0,1,"Casio","QV-4000" },
8400 { 787456,1024, 769, 0, 1, 0, 0, 0,0x49,0,0,"Creative","PC-CAM 600" },
8401 { 28829184,4384,3288, 0, 0, 0, 0,36,0x61,0,0,"DJI" },
8402 { 15151104,4608,3288, 0, 0, 0, 0, 0,0x94,0,0,"Matrix" },
8403 { 3840000,1600,1200, 0, 0, 0, 0,65,0x49,0,0,"Foculus","531C" },
8404 { 307200, 640, 480, 0, 0, 0, 0, 0,0x94,0,0,"Generic" },
8405 { 62464, 256, 244, 1, 1, 6, 1, 0,0x8d,0,0,"Kodak","DC20" },
8406 { 124928, 512, 244, 1, 1,10, 1, 0,0x8d,0,0,"Kodak","DC20" },
8407 { 1652736,1536,1076, 0,52, 0, 0, 0,0x61,0,0,"Kodak","DCS200" },
8408 { 4159302,2338,1779, 1,33, 1, 2, 0,0x94,0,0,"Kodak","C330" },
8409 { 4162462,2338,1779, 1,33, 1, 2, 0,0x94,0,0,"Kodak","C330",3160 },
8410 { 2247168,1232, 912, 0, 0,16, 0, 0,0x00,0,0,"Kodak","C330" },
8411 { 3370752,1232, 912, 0, 0,16, 0, 0,0x00,0,0,"Kodak","C330" },
8412 { 6163328,2864,2152, 0, 0, 0, 0, 0,0x94,0,0,"Kodak","C603" },
8413 { 6166488,2864,2152, 0, 0, 0, 0, 0,0x94,0,0,"Kodak","C603",3160 },
8414 { 460800, 640, 480, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","C603" },
8415 { 9116448,2848,2134, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","C603" },
8416 { 12241200,4040,3030, 2, 0, 0,13, 0,0x49,0,0,"Kodak","12MP" },
8417 { 12272756,4040,3030, 2, 0, 0,13, 0,0x49,0,0,"Kodak","12MP",31556 },
8418 { 18000000,4000,3000, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","12MP" },
8419 { 614400, 640, 480, 0, 3, 0, 0,64,0x94,0,0,"Kodak","KAI-0340" },
8420 { 15360000,3200,2400, 0, 0, 0, 0,96,0x16,0,0,"Lenovo","A820" },
8421 { 3884928,1608,1207, 0, 0, 0, 0,96,0x16,0,0,"Micron","2010",3212 },
8422 { 1138688,1534, 986, 0, 0, 0, 0, 0,0x61,0,0,"Minolta","RD175",513 },
8423 { 1581060,1305, 969, 0, 0,18, 6, 6,0x1e,4,1,"Nikon","E900" },
8424 { 2465792,1638,1204, 0, 0,22, 1, 6,0x4b,5,1,"Nikon","E950" },
8425 { 2940928,1616,1213, 0, 0, 0, 7,30,0x94,0,1,"Nikon","E2100" },
8426 { 4771840,2064,1541, 0, 0, 0, 1, 6,0xe1,0,1,"Nikon","E990" },
8427 { 4775936,2064,1542, 0, 0, 0, 0,30,0x94,0,1,"Nikon","E3700" },
8428 { 5865472,2288,1709, 0, 0, 0, 1, 6,0xb4,0,1,"Nikon","E4500" },
8429 { 5869568,2288,1710, 0, 0, 0, 0, 6,0x16,0,1,"Nikon","E4300" },
8430 { 7438336,2576,1925, 0, 0, 0, 1, 6,0xb4,0,1,"Nikon","E5000" },
8431 { 8998912,2832,2118, 0, 0, 0, 0,30,0x94,7,1,"Nikon","COOLPIX S6" },
8432 { 5939200,2304,1718, 0, 0, 0, 0,30,0x16,0,0,"Olympus","C770UZ" },
8433 { 3178560,2064,1540, 0, 0, 0, 0, 0,0x94,0,1,"Pentax","Optio S" },
8434 { 4841984,2090,1544, 0, 0,22, 0, 0,0x94,7,1,"Pentax","Optio S" },
8435 { 6114240,2346,1737, 0, 0,22, 0, 0,0x94,7,1,"Pentax","Optio S4" },
8436 { 10702848,3072,2322, 0, 0, 0,21,30,0x94,0,1,"Pentax","Optio 750Z" },
8437 { 4147200,1920,1080, 0, 0, 0, 0, 0,0x49,0,0,"Photron","BC2-HD" },
8438 { 4151666,1920,1080, 0, 0, 0, 0, 0,0x49,0,0,"Photron","BC2-HD",8 },
8439 { 13248000,2208,3000, 0, 0, 0, 0,13,0x61,0,0,"Pixelink","A782" },
8440 { 6291456,2048,1536, 0, 0, 0, 0,96,0x61,0,0,"RoverShot","3320AF" },
8441 { 311696, 644, 484, 0, 0, 0, 0, 0,0x16,0,8,"ST Micro","STV680 VGA" },
8442 { 16098048,3288,2448, 0, 0,24, 0, 9,0x94,0,1,"Samsung","S85" },
8443 { 16215552,3312,2448, 0, 0,48, 0, 9,0x94,0,1,"Samsung","S85" },
8444 { 20487168,3648,2808, 0, 0, 0, 0,13,0x94,5,1,"Samsung","WB550" },
8445 { 24000000,4000,3000, 0, 0, 0, 0,13,0x94,5,1,"Samsung","WB550" },
8446 { 12582980,3072,2048, 0, 0, 0, 0,33,0x61,0,0,"Sinar","",68 },
8447 { 33292868,4080,4080, 0, 0, 0, 0,33,0x61,0,0,"Sinar","",68 },
8448 { 44390468,4080,5440, 0, 0, 0, 0,33,0x61,0,0,"Sinar","",68 },
8449 { 1409024,1376,1024, 0, 0, 1, 0, 0,0x49,0,0,"Sony","XCD-SX910CR" },
8450 { 2818048,1376,1024, 0, 0, 1, 0,97,0x49,0,0,"Sony","XCD-SX910CR" },
8452 static const char *corp[] =
8453 { "AgfaPhoto", "Canon", "Casio", "Epson", "Fujifilm",
8454 "Mamiya", "Minolta", "Motorola", "Kodak", "Konica", "Leica",
8455 "Nikon", "Nokia", "Olympus", "Ricoh", "Pentax", "Phase One",
8456 "Samsung", "Sigma", "Sinar", "Sony" };
8458 int hlen, flen, fsize, zero_fsize=1, i, c;
8461 tiff_flip = flip = filters = UINT_MAX; /* unknown */
8462 raw_height = raw_width = fuji_width = fuji_layout = cr2_slice[0] = 0;
8463 maximum = height = width = top_margin = left_margin = 0;
8464 cdesc[0] = desc[0] = artist[0] = make[0] = model[0] = model2[0] = 0;
8465 iso_speed = shutter = aperture = focal_len = unique_id = 0;
8467 memset (tiff_ifd, 0, sizeof tiff_ifd);
8468 memset (gpsdata, 0, sizeof gpsdata);
8469 memset (cblack, 0, sizeof cblack);
8470 memset (white, 0, sizeof white);
8471 memset (mask, 0, sizeof mask);
8472 thumb_offset = thumb_length = thumb_width = thumb_height = 0;
8473 load_raw = thumb_load_raw = 0;
8474 write_thumb = &CLASS jpeg_thumb;
8475 data_offset = meta_offset = meta_length = tiff_bps = tiff_compress = 0;
8476 kodak_cbpp = zero_after_ff = dng_version = load_flags = 0;
8477 timestamp = shot_order = tiff_samples = black = is_foveon = 0;
8478 mix_green = profile_length = data_error = zero_is_bad = 0;
8479 pixel_aspect = is_raw = raw_color = 1;
8480 tile_width = tile_length = 0;
8481 for (i=0; i < 4; i++) {
8482 cam_mul[i] = i == 1;
8484 FORC3 cmatrix[c][i] = 0;
8485 FORC3 rgb_cam[c][i] = c == i;
8488 for (i=0; i < 0x10000; i++) curve[i] = i;
8492 fseek (ifp, 0, SEEK_SET);
8493 fread (head, 1, 32, ifp);
8494 fseek (ifp, 0, SEEK_END);
8495 flen = fsize = ftell(ifp);
8496 if ((cp = (char *) memmem (head, 32, "MMMM", 4)) ||
8497 (cp = (char *) memmem (head, 32, "IIII", 4))) {
8498 parse_phase_one (cp-head);
8499 if (cp-head && parse_tiff(0)) apply_tiff();
8500 } else if (order == 0x4949 || order == 0x4d4d) {
8501 if (!memcmp (head+6,"HEAPCCDR",8)) {
8503 parse_ciff (hlen, flen-hlen, 0);
8504 load_raw = &CLASS canon_load_raw;
8505 } else if (parse_tiff(0)) apply_tiff();
8506 } else if (!memcmp (head,"\xff\xd8\xff\xe1",4) &&
8507 !memcmp (head+6,"Exif",4)) {
8508 fseek (ifp, 4, SEEK_SET);
8509 data_offset = 4 + get2();
8510 fseek (ifp, data_offset, SEEK_SET);
8511 if (fgetc(ifp) != 0xff)
8514 } else if (!memcmp (head+25,"ARECOYK",7)) {
8515 strcpy (make, "Contax");
8516 strcpy (model,"N Digital");
8517 fseek (ifp, 33, SEEK_SET);
8519 fseek (ifp, 60, SEEK_SET);
8520 FORC4 cam_mul[c ^ (c >> 1)] = get4();
8521 } else if (!strcmp (head, "PXN")) {
8522 strcpy (make, "Logitech");
8523 strcpy (model,"Fotoman Pixtura");
8524 } else if (!strcmp (head, "qktk")) {
8525 strcpy (make, "Apple");
8526 strcpy (model,"QuickTake 100");
8527 load_raw = &CLASS quicktake_100_load_raw;
8528 } else if (!strcmp (head, "qktn")) {
8529 strcpy (make, "Apple");
8530 strcpy (model,"QuickTake 150");
8531 load_raw = &CLASS kodak_radc_load_raw;
8532 } else if (!memcmp (head,"FUJIFILM",8)) {
8533 fseek (ifp, 84, SEEK_SET);
8534 thumb_offset = get4();
8535 thumb_length = get4();
8536 fseek (ifp, 92, SEEK_SET);
8537 parse_fuji (get4());
8538 if (thumb_offset > 120) {
8539 fseek (ifp, 120, SEEK_SET);
8540 is_raw += (i = get4()) && 1;
8541 if (is_raw == 2 && shot_select)
8544 load_raw = &CLASS unpacked_load_raw;
8545 fseek (ifp, 100+28*(shot_select > 0), SEEK_SET);
8546 parse_tiff (data_offset = get4());
8547 parse_tiff (thumb_offset+12);
8549 } else if (!memcmp (head,"RIFF",4)) {
8550 fseek (ifp, 0, SEEK_SET);
8552 } else if (!memcmp (head+4,"ftypqt ",9)) {
8553 fseek (ifp, 0, SEEK_SET);
8556 } else if (!memcmp (head,"\0\001\0\001\0@",6)) {
8557 fseek (ifp, 6, SEEK_SET);
8558 fread (make, 1, 8, ifp);
8559 fread (model, 1, 8, ifp);
8560 fread (model2, 1, 16, ifp);
8561 data_offset = get2();
8564 raw_height = get2();
8565 load_raw = &CLASS nokia_load_raw;
8566 filters = 0x61616161;
8567 } else if (!memcmp (head,"NOKIARAW",8)) {
8568 strcpy (make, "NOKIA");
8570 fseek (ifp, 300, SEEK_SET);
8571 data_offset = get4();
8575 switch (tiff_bps = i*8 / (width * height)) {
8576 case 8: load_raw = &CLASS eight_bit_load_raw; break;
8577 case 10: load_raw = &CLASS nokia_load_raw;
8579 raw_height = height + (top_margin = i / (width * tiff_bps/8) - height);
8581 filters = 0x61616161;
8582 } else if (!memcmp (head,"ARRI",4)) {
8584 fseek (ifp, 20, SEEK_SET);
8587 strcpy (make, "ARRI");
8588 fseek (ifp, 668, SEEK_SET);
8589 fread (model, 1, 64, ifp);
8591 load_raw = &CLASS packed_load_raw;
8593 filters = 0x61616161;
8594 } else if (!memcmp (head,"XPDS",4)) {
8596 fseek (ifp, 0x800, SEEK_SET);
8597 fread (make, 1, 41, ifp);
8598 raw_height = get2();
8600 fseek (ifp, 56, SEEK_CUR);
8601 fread (model, 1, 30, ifp);
8602 data_offset = 0x10000;
8603 load_raw = &CLASS canon_rmf_load_raw;
8604 gamma_curve (0, 12.25, 1, 1023);
8605 } else if (!memcmp (head+4,"RED1",4)) {
8606 strcpy (make, "Red");
8607 strcpy (model,"One");
8609 load_raw = &CLASS redcine_load_raw;
8610 gamma_curve (1/2.4, 12.92, 1, 4095);
8611 filters = 0x49494949;
8612 } else if (!memcmp (head,"DSC-Image",9))
8614 else if (!memcmp (head,"PWAD",4))
8616 else if (!memcmp (head,"\0MRM",4))
8618 else if (!memcmp (head,"FOVb",4))
8620 else if (!memcmp (head,"CI",2))
8623 for (zero_fsize=i=0; i < sizeof table / sizeof *table; i++)
8624 if (fsize == table[i].fsize) {
8625 strcpy (make, table[i].make );
8626 strcpy (model, table[i].model);
8627 flip = table[i].flags >> 2;
8628 zero_is_bad = table[i].flags & 2;
8629 if (table[i].flags & 1)
8630 parse_external_jpeg();
8631 data_offset = table[i].offset;
8632 raw_width = table[i].rw;
8633 raw_height = table[i].rh;
8634 left_margin = table[i].lm;
8635 top_margin = table[i].tm;
8636 width = raw_width - left_margin - table[i].rm;
8637 height = raw_height - top_margin - table[i].bm;
8638 filters = 0x1010101 * table[i].cf;
8639 colors = 4 - !((filters & filters >> 1) & 0x5555);
8640 load_flags = table[i].lf;
8641 switch (tiff_bps = (fsize-data_offset)*8 / (raw_width*raw_height)) {
8643 load_raw = &CLASS minolta_rd175_load_raw; break;
8645 load_raw = &CLASS eight_bit_load_raw; break;
8648 load_raw = &CLASS packed_load_raw; break;
8650 order = 0x4949 | 0x404 * (load_flags & 1);
8651 tiff_bps -= load_flags >> 4;
8652 tiff_bps -= load_flags = load_flags >> 1 & 7;
8653 load_raw = &CLASS unpacked_load_raw;
8655 maximum = (1 << tiff_bps) - (1 << table[i].max);
8657 if (zero_fsize) fsize = 0;
8658 if (make[0] == 0) parse_smal (0, flen);
8661 if (!(strncmp(model,"ov",2) && strncmp(model,"RP_OV",5)) &&
8662 !fseek (ifp, -6404096, SEEK_END) &&
8663 fread (head, 1, 32, ifp) && !strcmp(head,"BRCMn")) {
8664 strcpy (make, "OmniVision");
8665 data_offset = ftell(ifp) + 0x8000-32;
8668 load_raw = &CLASS nokia_load_raw;
8669 filters = 0x16161616;
8673 for (i=0; i < sizeof corp / sizeof *corp; i++)
8674 if (strcasestr (make, corp[i])) /* Simplify company names */
8675 strcpy (make, corp[i]);
8676 if ((!strcmp(make,"Kodak") || !strcmp(make,"Leica")) &&
8677 ((cp = strcasestr(model," DIGITAL CAMERA")) ||
8678 (cp = strstr(model,"FILE VERSION"))))
8680 if (!strncasecmp(model,"PENTAX",6))
8681 strcpy (make, "Pentax");
8682 cp = make + strlen(make); /* Remove trailing spaces */
8683 while (*--cp == ' ') *cp = 0;
8684 cp = model + strlen(model);
8685 while (*--cp == ' ') *cp = 0;
8686 i = strlen(make); /* Remove make from model */
8687 if (!strncasecmp (model, make, i) && model[i++] == ' ')
8688 memmove (model, model+i, 64-i);
8689 if (!strncmp (model,"FinePix ",8))
8690 strcpy (model, model+8);
8691 if (!strncmp (model,"Digital Camera ",15))
8692 strcpy (model, model+15);
8693 desc[511] = artist[63] = make[63] = model[63] = model2[63] = 0;
8694 if (!is_raw) goto notraw;
8696 if (!height) height = raw_height;
8697 if (!width) width = raw_width;
8698 if (height == 2624 && width == 3936) /* Pentax K10D and Samsung GX10 */
8699 { height = 2616; width = 3896; }
8700 if (height == 3136 && width == 4864) /* Pentax K20D and Samsung GX20 */
8701 { height = 3124; width = 4688; filters = 0x16161616; }
8702 if (width == 4352 && (!strcmp(model,"K-r") || !strcmp(model,"K-x")))
8703 { width = 4309; filters = 0x16161616; }
8704 if (width >= 4960 && !strncmp(model,"K-5",3))
8705 { left_margin = 10; width = 4950; filters = 0x16161616; }
8706 if (width == 4736 && !strcmp(model,"K-7"))
8707 { height = 3122; width = 4684; filters = 0x16161616; top_margin = 2; }
8708 if (width == 6080 && !strcmp(model,"K-3"))
8709 { left_margin = 4; width = 6040; }
8710 if (width == 7424 && !strcmp(model,"645D"))
8711 { height = 5502; width = 7328; filters = 0x61616161; top_margin = 29;
8713 if (height == 3014 && width == 4096) /* Ricoh GX200 */
8716 if (filters == UINT_MAX) filters = 0;
8717 if (filters) is_raw *= tiff_samples;
8718 else colors = tiff_samples;
8719 switch (tiff_compress) {
8721 case 1: load_raw = &CLASS packed_dng_load_raw; break;
8722 case 7: load_raw = &CLASS lossless_dng_load_raw; break;
8723 case 34892: load_raw = &CLASS lossy_dng_load_raw; break;
8724 default: load_raw = 0;
8728 if (!strcmp(make,"Canon") && !fsize && tiff_bps != 15) {
8730 load_raw = &CLASS lossless_jpeg_load_raw;
8731 for (i=0; i < sizeof canon / sizeof *canon; i++)
8732 if (raw_width == canon[i][0] && raw_height == canon[i][1]) {
8733 width = raw_width - (left_margin = canon[i][2]);
8734 height = raw_height - (top_margin = canon[i][3]);
8735 width -= canon[i][4];
8736 height -= canon[i][5];
8737 mask[0][1] = canon[i][6];
8738 mask[0][3] = -canon[i][7];
8739 mask[1][1] = canon[i][8];
8740 mask[1][3] = -canon[i][9];
8741 if (canon[i][10]) filters = canon[i][10] * 0x01010101;
8743 if ((unique_id | 0x20000) == 0x2720000) {
8748 for (i=0; i < sizeof unique / sizeof *unique; i++)
8749 if (unique_id == 0x80000000 + unique[i].id) {
8750 adobe_coeff ("Canon", unique[i].model);
8751 if (model[4] == 'K' && strlen(model) == 8)
8752 strcpy (model, unique[i].model);
8754 for (i=0; i < sizeof sonique / sizeof *sonique; i++)
8755 if (unique_id == sonique[i].id)
8756 strcpy (model, sonique[i].model);
8757 if (!strcmp(make,"Nikon")) {
8759 load_raw = &CLASS packed_load_raw;
8760 if (model[0] == 'E')
8761 load_flags |= !data_offset << 2 | 2;
8764 /* Set parameters based on camera name (for non-DNG files). */
8766 if (!strcmp(model,"KAI-0340")
8767 && find_green (16, 16, 3840, 5120) < 25) {
8769 top_margin = filters = 0;
8770 strcpy (model,"C603");
8772 if (!strcmp(make,"Sony") && raw_width > 3888)
8773 black = 128 << (tiff_bps - 12);
8775 if (height*2 < width) pixel_aspect = 0.5;
8776 if (height > width) pixel_aspect = 2;
8779 } else if (!strcmp(make,"Canon") && tiff_bps == 15) {
8781 case 3344: width -= 66;
8782 case 3872: width -= 6;
8784 if (height > width) {
8786 SWAP(raw_height,raw_width);
8788 if (width == 7200 && height == 3888) {
8789 raw_width = width = 6480;
8790 raw_height = height = 4320;
8793 tiff_samples = colors = 3;
8794 load_raw = &CLASS canon_sraw_load_raw;
8795 } else if (!strcmp(model,"PowerShot 600")) {
8800 filters = 0xe1e4e1e4;
8801 load_raw = &CLASS canon_600_load_raw;
8802 } else if (!strcmp(model,"PowerShot A5") ||
8803 !strcmp(model,"PowerShot A5 Zoom")) {
8807 pixel_aspect = 256/235.0;
8808 filters = 0x1e4e1e4e;
8810 } else if (!strcmp(model,"PowerShot A50")) {
8814 filters = 0x1b4e4b1e;
8816 } else if (!strcmp(model,"PowerShot Pro70")) {
8819 filters = 0x1e4b4e1b;
8823 load_raw = &CLASS packed_load_raw;
8825 } else if (!strcmp(model,"PowerShot Pro90 IS") ||
8826 !strcmp(model,"PowerShot G1")) {
8828 filters = 0xb4b4b4b4;
8829 } else if (!strcmp(model,"PowerShot A610")) {
8830 if (canon_s2is()) strcpy (model+10, "S2 IS");
8831 } else if (!strcmp(model,"PowerShot SX220 HS")) {
8833 } else if (!strcmp(model,"EOS D2000C")) {
8834 filters = 0x61616161;
8836 } else if (!strcmp(model,"D1")) {
8837 cam_mul[0] *= 256/527.0;
8838 cam_mul[2] *= 256/317.0;
8839 } else if (!strcmp(model,"D1X")) {
8842 } else if (!strcmp(model,"D40X") ||
8843 !strcmp(model,"D60") ||
8844 !strcmp(model,"D80") ||
8845 !strcmp(model,"D3000")) {
8848 } else if (!strcmp(model,"D3") ||
8849 !strcmp(model,"D3S") ||
8850 !strcmp(model,"D700")) {
8853 } else if (!strcmp(model,"D3100")) {
8856 } else if (!strcmp(model,"D5000") ||
8857 !strcmp(model,"D90")) {
8859 } else if (!strcmp(model,"D5100") ||
8860 !strcmp(model,"D7000") ||
8861 !strcmp(model,"COOLPIX A")) {
8863 } else if (!strcmp(model,"D3200") ||
8864 !strncmp(model,"D6",2) ||
8865 !strncmp(model,"D800",4)) {
8867 } else if (!strcmp(model,"D4") ||
8868 !strcmp(model,"Df")) {
8871 } else if (!strncmp(model,"D40",3) ||
8872 !strncmp(model,"D50",3) ||
8873 !strncmp(model,"D70",3)) {
8875 } else if (!strcmp(model,"D100")) {
8877 raw_width = (width += 3) + 3;
8878 } else if (!strcmp(model,"D200")) {
8881 filters = 0x94949494;
8882 } else if (!strncmp(model,"D2H",3)) {
8885 } else if (!strncmp(model,"D2X",3)) {
8886 if (width == 3264) width -= 32;
8888 } else if (!strncmp(model,"D300",4)) {
8890 } else if (!strncmp(model,"COOLPIX P",9) && raw_width != 4032) {
8892 filters = 0x94949494;
8893 if (model[9] == '7' && iso_speed >= 400)
8895 } else if (!strncmp(model,"1 ",2)) {
8897 } else if (fsize == 1581060) {
8899 pre_mul[0] = 1.2085;
8900 pre_mul[1] = 1.0943;
8901 pre_mul[3] = 1.1103;
8902 } else if (fsize == 3178560) {
8905 } else if (fsize == 4771840) {
8906 if (!timestamp && nikon_e995())
8907 strcpy (model, "E995");
8908 if (strcmp(model,"E995")) {
8909 filters = 0xb4b4b4b4;
8915 } else if (fsize == 2940928) {
8916 if (!timestamp && !nikon_e2100())
8917 strcpy (model,"E2500");
8918 if (!strcmp(model,"E2500")) {
8922 filters = 0x4b4b4b4b;
8924 } else if (fsize == 4775936) {
8925 if (!timestamp) nikon_3700();
8926 if (model[0] == 'E' && atoi(model+1) < 3700)
8927 filters = 0x49494949;
8928 if (!strcmp(model,"Optio 33WR")) {
8930 filters = 0x16161616;
8932 if (make[0] == 'O') {
8933 i = find_green (12, 32, 1188864, 3576832);
8934 c = find_green (12, 32, 2383920, 2387016);
8935 if (abs(i) < abs(c)) {
8939 if (i < 0) filters = 0x61616161;
8941 } else if (fsize == 5869568) {
8942 if (!timestamp && minolta_z2()) {
8943 strcpy (make, "Minolta");
8944 strcpy (model,"DiMAGE Z2");
8946 load_flags = 6 + 24*(make[0] == 'M');
8947 } else if (fsize == 6291456) {
8948 fseek (ifp, 0x300000, SEEK_SET);
8949 if ((order = guess_byte_order(0x10000)) == 0x4d4d) {
8950 height -= (top_margin = 16);
8951 width -= (left_margin = 28);
8953 strcpy (make, "ISG");
8956 } else if (!strcmp(make,"Fujifilm")) {
8957 if (!strcmp(model+7,"S2Pro")) {
8958 strcpy (model,"S2Pro");
8962 } else if (load_raw != &CLASS packed_load_raw)
8963 maximum = (is_raw == 2 && shot_select) ? 0x2f00 : 0x3e00;
8964 top_margin = (raw_height - height) >> 2 << 1;
8965 left_margin = (raw_width - width ) >> 2 << 1;
8966 if (width == 2848 || width == 3664) filters = 0x16161616;
8967 if (width == 4032 || width == 4952 || width == 6032) left_margin = 0;
8968 if (width == 3328 && (width -= 66)) left_margin = 34;
8969 if (width == 4936) left_margin = 4;
8970 if (!strcmp(model,"HS50EXR") ||
8971 !strcmp(model,"F900EXR")) {
8974 filters = 0x16161616;
8976 if (fuji_layout) raw_width *= is_raw;
8978 FORC(36) ((char *)xtrans)[c] =
8979 xtrans_abs[(c/6+top_margin) % 6][(c+left_margin) % 6];
8980 } else if (!strcmp(model,"KD-400Z")) {
8985 } else if (!strcmp(model,"KD-510Z")) {
8987 } else if (!strcasecmp(make,"Minolta")) {
8988 if (!load_raw && (maximum = 0xfff))
8989 load_raw = &CLASS unpacked_load_raw;
8990 if (!strncmp(model,"DiMAGE A",8)) {
8991 if (!strcmp(model,"DiMAGE A200"))
8992 filters = 0x49494949;
8994 load_raw = &CLASS packed_load_raw;
8995 } else if (!strncmp(model,"ALPHA",5) ||
8996 !strncmp(model,"DYNAX",5) ||
8997 !strncmp(model,"MAXXUM",6)) {
8998 sprintf (model+20, "DYNAX %-10s", model+6+(model[0]=='M'));
8999 adobe_coeff (make, model+20);
9000 load_raw = &CLASS packed_load_raw;
9001 } else if (!strncmp(model,"DiMAGE G",8)) {
9002 if (model[8] == '4') {
9005 } else if (model[8] == '5') {
9010 } else if (model[8] == '6') {
9015 filters = 0x61616161;
9017 load_raw = &CLASS unpacked_load_raw;
9021 } else if (!strcmp(model,"*ist D")) {
9022 load_raw = &CLASS unpacked_load_raw;
9024 } else if (!strcmp(model,"*ist DS")) {
9026 } else if (!strcmp(make,"Samsung") && raw_width == 4704) {
9027 height -= top_margin = 8;
9028 width -= 2 * (left_margin = 8);
9030 } else if (!strcmp(make,"Samsung") && raw_height == 3714) {
9031 height -= top_margin = 18;
9032 left_margin = raw_width - (width = 5536);
9033 if (raw_width != 5600)
9034 left_margin = top_margin = 0;
9035 filters = 0x61616161;
9037 } else if (!strcmp(make,"Samsung") && raw_width == 5632) {
9041 width = 5574 - (left_margin = 32 + tiff_bps);
9042 if (tiff_bps == 12) load_flags = 80;
9043 } else if (!strcmp(make,"Samsung") && raw_width == 5664) {
9044 height -= top_margin = 17;
9047 filters = 0x49494949;
9048 } else if (!strcmp(make,"Samsung") && raw_width == 6496) {
9049 filters = 0x61616161;
9050 black = 1 << (tiff_bps - 7);
9051 } else if (!strcmp(model,"EX1")) {
9055 if ((width -= 6) > 3682) {
9060 } else if (!strcmp(model,"WB2000")) {
9064 if ((width -= 10) > 3718) {
9069 } else if (strstr(model,"WB550")) {
9070 strcpy (model, "WB550");
9071 } else if (!strcmp(model,"EX2F")) {
9076 filters = 0x49494949;
9077 load_raw = &CLASS unpacked_load_raw;
9078 } else if (!strcmp(model,"STV680 VGA")) {
9080 } else if (!strcmp(model,"N95")) {
9081 height = raw_height - (top_margin = 2);
9082 } else if (!strcmp(model,"640x480")) {
9083 gamma_curve (0.45, 4.5, 1, 255);
9084 } else if (!strcmp(make,"Hasselblad")) {
9085 if (load_raw == &CLASS lossless_jpeg_load_raw)
9086 load_raw = &CLASS hasselblad_load_raw;
9087 if (raw_width == 7262) {
9092 filters = 0x61616161;
9093 } else if (raw_width == 7410 || raw_width == 8282) {
9098 filters = 0x61616161;
9099 } else if (raw_width == 9044) {
9104 black += load_flags = 256;
9106 } else if (raw_width == 4090) {
9107 strcpy (model, "V96C");
9108 height -= (top_margin = 6);
9109 width -= (left_margin = 3) + 7;
9110 filters = 0x61616161;
9112 if (tiff_samples > 1) {
9113 is_raw = tiff_samples+1;
9114 if (!shot_select && !half_size) filters = 0;
9116 } else if (!strcmp(make,"Sinar")) {
9117 if (!load_raw) load_raw = &CLASS unpacked_load_raw;
9118 if (is_raw > 1 && !shot_select && !half_size) filters = 0;
9120 } else if (!strcmp(make,"Leaf")) {
9122 fseek (ifp, data_offset, SEEK_SET);
9123 if (ljpeg_start (&jh, 1) && jh.bits == 15)
9125 if (tiff_samples > 1) filters = 0;
9126 if (tiff_samples > 1 || tile_length < raw_height) {
9127 load_raw = &CLASS leaf_hdr_load_raw;
9128 raw_width = tile_width;
9130 if ((width | height) == 2048) {
9131 if (tiff_samples == 1) {
9133 strcpy (cdesc, "RBTG");
9134 strcpy (model, "CatchLight");
9135 top_margin = 8; left_margin = 18; height = 2032; width = 2016;
9137 strcpy (model, "DCB2");
9138 top_margin = 10; left_margin = 16; height = 2028; width = 2022;
9140 } else if (width+height == 3144+2060) {
9141 if (!model[0]) strcpy (model, "Cantare");
9142 if (width > height) {
9143 top_margin = 6; left_margin = 32; height = 2048; width = 3072;
9144 filters = 0x61616161;
9146 left_margin = 6; top_margin = 32; width = 2048; height = 3072;
9147 filters = 0x16161616;
9149 if (!cam_mul[0] || model[0] == 'V') filters = 0;
9150 else is_raw = tiff_samples;
9151 } else if (width == 2116) {
9152 strcpy (model, "Valeo 6");
9153 height -= 2 * (top_margin = 30);
9154 width -= 2 * (left_margin = 55);
9155 filters = 0x49494949;
9156 } else if (width == 3171) {
9157 strcpy (model, "Valeo 6");
9158 height -= 2 * (top_margin = 24);
9159 width -= 2 * (left_margin = 24);
9160 filters = 0x16161616;
9162 } else if (!strcmp(make,"Leica") || !strcmp(make,"Panasonic")) {
9163 if ((flen - data_offset) / (raw_width*8/7) == raw_height)
9164 load_raw = &CLASS panasonic_load_raw;
9166 load_raw = &CLASS unpacked_load_raw;
9170 if ((height += 12) > raw_height) height = raw_height;
9171 for (i=0; i < sizeof pana / sizeof *pana; i++)
9172 if (raw_width == pana[i][0] && raw_height == pana[i][1]) {
9173 left_margin = pana[i][2];
9174 top_margin = pana[i][3];
9175 width += pana[i][4];
9176 height += pana[i][5];
9178 filters = 0x01010101 * (uchar) "\x94\x61\x49\x16"
9179 [((filters-1) ^ (left_margin & 1) ^ (top_margin << 1)) & 3];
9180 } else if (!strcmp(model,"C770UZ")) {
9183 filters = 0x16161616;
9184 load_raw = &CLASS packed_load_raw;
9186 } else if (!strcmp(make,"Olympus")) {
9187 height += height & 1;
9188 if (exif_cfa) filters = exif_cfa;
9189 if (width == 4100) width -= 4;
9190 if (width == 4080) width -= 24;
9191 if (width == 9280) { width -= 6; height -= 6; }
9192 if (load_raw == &CLASS unpacked_load_raw)
9195 if (!strcmp(model,"E-300") ||
9196 !strcmp(model,"E-500")) {
9198 if (load_raw == &CLASS unpacked_load_raw) {
9200 memset (cblack, 0, sizeof cblack);
9202 } else if (!strcmp(model,"E-330")) {
9204 if (load_raw == &CLASS unpacked_load_raw)
9206 } else if (!strcmp(model,"SP550UZ")) {
9207 thumb_length = flen - (thumb_offset = 0xa39800);
9210 } else if (!strcmp(model,"TG-4")) {
9213 } else if (!strcmp(model,"N Digital")) {
9216 filters = 0x61616161;
9217 data_offset = 0x1a00;
9218 load_raw = &CLASS packed_load_raw;
9219 } else if (!strcmp(model,"DSC-F828")) {
9223 data_offset = 862144;
9224 load_raw = &CLASS sony_load_raw;
9225 filters = 0x9c9c9c9c;
9227 strcpy (cdesc, "RGBE");
9228 } else if (!strcmp(model,"DSC-V3")) {
9232 data_offset = 787392;
9233 load_raw = &CLASS sony_load_raw;
9234 } else if (!strcmp(make,"Sony") && raw_width == 3984) {
9237 } else if (!strcmp(make,"Sony") && raw_width == 4288) {
9239 } else if (!strcmp(make,"Sony") && raw_width == 4600) {
9240 if (!strcmp(model,"DSLR-A350"))
9243 } else if (!strcmp(make,"Sony") && raw_width == 4928) {
9244 if (height < 3280) width -= 8;
9245 } else if (!strcmp(make,"Sony") && raw_width == 5504) {
9246 width -= height > 3664 ? 8 : 32;
9247 if (!strncmp(model,"DSC",3))
9248 black = 200 << (tiff_bps - 12);
9249 } else if (!strcmp(make,"Sony") && raw_width == 6048) {
9251 if (strstr(model,"RX1") || strstr(model,"A99"))
9253 } else if (!strcmp(make,"Sony") && raw_width == 7392) {
9255 } else if (!strcmp(make,"Sony") && raw_width == 8000) {
9257 if (!strncmp(model,"DSC",3)) {
9259 load_raw = &CLASS unpacked_load_raw;
9262 } else if (!strcmp(model,"DSLR-A100")) {
9263 if (width == 3880) {
9265 width = ++raw_width;
9272 filters = 0x61616161;
9273 } else if (!strcmp(model,"PIXL")) {
9274 height -= top_margin = 4;
9275 width -= left_margin = 32;
9276 gamma_curve (0, 7, 1, 255);
9277 } else if (!strcmp(model,"C603") || !strcmp(model,"C330")
9278 || !strcmp(model,"12MP")) {
9280 if (filters && data_offset) {
9281 fseek (ifp, data_offset < 4096 ? 168 : 5252, SEEK_SET);
9282 read_shorts (curve, 256);
9283 } else gamma_curve (0, 3.875, 1, 255);
9284 load_raw = filters ? &CLASS eight_bit_load_raw :
9285 strcmp(model,"C330") ? &CLASS kodak_c603_load_raw :
9286 &CLASS kodak_c330_load_raw;
9287 load_flags = tiff_bps > 16;
9289 } else if (!strncasecmp(model,"EasyShare",9)) {
9290 data_offset = data_offset < 0x15000 ? 0x15000 : 0x17000;
9291 load_raw = &CLASS packed_load_raw;
9292 } else if (!strcasecmp(make,"Kodak")) {
9293 if (filters == UINT_MAX) filters = 0x61616161;
9294 if (!strncmp(model,"NC2000",6) ||
9295 !strncmp(model,"EOSDCS",6) ||
9296 !strncmp(model,"DCS4",4)) {
9299 if (model[6] == ' ') model[6] = 0;
9300 if (!strcmp(model,"DCS460A")) goto bw;
9301 } else if (!strcmp(model,"DCS660M")) {
9304 } else if (!strcmp(model,"DCS760M")) {
9308 if (!strcmp(model+4,"20X"))
9309 strcpy (cdesc, "MYCY");
9310 if (strstr(model,"DC25")) {
9311 strcpy (model, "DC25");
9312 data_offset = 15424;
9314 if (!strncmp(model,"DC2",3)) {
9315 raw_height = 2 + (height = 242);
9316 if (flen < 100000) {
9317 raw_width = 256; width = 249;
9318 pixel_aspect = (4.0*height) / (3.0*width);
9320 raw_width = 512; width = 501;
9321 pixel_aspect = (493.0*height) / (373.0*width);
9323 top_margin = left_margin = 1;
9325 filters = 0x8d8d8d8d;
9330 load_raw = &CLASS eight_bit_load_raw;
9331 } else if (!strcmp(model,"40")) {
9332 strcpy (model, "DC40");
9336 load_raw = &CLASS kodak_radc_load_raw;
9338 } else if (strstr(model,"DC50")) {
9339 strcpy (model, "DC50");
9342 data_offset = 19712;
9343 load_raw = &CLASS kodak_radc_load_raw;
9344 } else if (strstr(model,"DC120")) {
9345 strcpy (model, "DC120");
9348 pixel_aspect = height/0.75/width;
9349 load_raw = tiff_compress == 7 ?
9350 &CLASS kodak_jpeg_load_raw : &CLASS kodak_dc120_load_raw;
9351 } else if (!strcmp(model,"DCS200")) {
9354 thumb_offset = 6144;
9356 write_thumb = &CLASS layer_thumb;
9359 } else if (!strcmp(model,"Fotoman Pixtura")) {
9363 load_raw = &CLASS kodak_radc_load_raw;
9364 filters = 0x61616161;
9366 } else if (!strncmp(model,"QuickTake",9)) {
9367 if (head[5]) strcpy (model+10, "200");
9368 fseek (ifp, 544, SEEK_SET);
9371 data_offset = (get4(),get2()) == 30 ? 738:736;
9372 if (height > width) {
9374 fseek (ifp, data_offset-6, SEEK_SET);
9375 flip = ~get2() & 3 ? 5:6;
9377 filters = 0x61616161;
9378 } else if (!strcmp(make,"Rollei") && !load_raw) {
9379 switch (raw_width) {
9392 filters = 0x16161616;
9393 load_raw = &CLASS rollei_load_raw;
9396 sprintf (model, "%dx%d", width, height);
9397 if (filters == UINT_MAX) filters = 0x94949494;
9398 if (thumb_offset && !thumb_height) {
9399 fseek (ifp, thumb_offset, SEEK_SET);
9400 if (ljpeg_start (&jh, 1)) {
9401 thumb_width = jh.wide;
9402 thumb_height = jh.high;
9406 if ((use_camera_matrix & (use_camera_wb || dng_version))
9407 && cmatrix[0][0] > 0.125) {
9408 memcpy (rgb_cam, cmatrix, sizeof cmatrix);
9411 if (raw_color) adobe_coeff (make, model);
9412 if (load_raw == &CLASS kodak_radc_load_raw)
9413 if (raw_color) adobe_coeff ("Apple","Quicktake");
9415 fuji_width = width >> !fuji_layout;
9416 filters = fuji_width & 1 ? 0x94949494 : 0x49494949;
9417 width = (height >> fuji_layout) + fuji_width;
9421 if (raw_height < height) raw_height = height;
9422 if (raw_width < width ) raw_width = width;
9424 if (!tiff_bps) tiff_bps = 12;
9425 if (!maximum) maximum = (1 << tiff_bps) - 1;
9426 if (!load_raw || height < 22 || width < 22 ||
9427 tiff_bps > 16 || tiff_samples > 6 || colors > 4)
9430 if (load_raw == &CLASS redcine_load_raw) {
9431 fprintf (stderr,_("%s: You must link dcraw with %s!!\n"),
9432 ifname, "libjasper");
9437 if (load_raw == &CLASS kodak_jpeg_load_raw ||
9438 load_raw == &CLASS lossy_dng_load_raw) {
9439 fprintf (stderr,_("%s: You must link dcraw with %s!!\n"),
9445 strcpy (cdesc, colors == 3 ? "RGBG":"GMCY");
9446 if (!raw_height) raw_height = height;
9447 if (!raw_width ) raw_width = width;
9448 if (filters > 999 && colors == 3)
9449 filters |= ((filters >> 2 & 0x22222222) |
9450 (filters << 2 & 0x88888888)) & filters << 1;
9452 if (flip == UINT_MAX) flip = tiff_flip;
9453 if (flip == UINT_MAX) flip = 0;
9457 sprintf(dcraw_info, "%d %d", height, width);
9459 sprintf(dcraw_info, "%d %d", width, height);
9463 void CLASS apply_profile (const char *input, const char *output)
9466 cmsHPROFILE hInProfile=0, hOutProfile=0;
9467 cmsHTRANSFORM hTransform;
9471 if (strcmp (input, "embed"))
9472 hInProfile = cmsOpenProfileFromFile (input, "r");
9473 else if (profile_length) {
9474 prof = (char *) malloc (profile_length);
9475 merror (prof, "apply_profile()");
9476 fseek (ifp, profile_offset, SEEK_SET);
9477 fread (prof, 1, profile_length, ifp);
9478 hInProfile = cmsOpenProfileFromMem (prof, profile_length);
9481 fprintf (stderr,_("%s has no embedded profile.\n"), ifname);
9482 if (!hInProfile) return;
9484 hOutProfile = cmsCreate_sRGBProfile();
9485 else if ((fp = fopen (output, "rb"))) {
9486 fread (&size, 4, 1, fp);
9487 fseek (fp, 0, SEEK_SET);
9488 oprof = (unsigned *) malloc (size = ntohl(size));
9489 merror (oprof, "apply_profile()");
9490 fread (oprof, 1, size, fp);
9492 if (!(hOutProfile = cmsOpenProfileFromMem (oprof, size))) {
9497 fprintf (stderr,_("Cannot open file %s!\n"), output);
9498 if (!hOutProfile) goto quit;
9500 fprintf (stderr,_("Applying color profile...\n"));
9501 hTransform = cmsCreateTransform (hInProfile, TYPE_RGBA_16,
9502 hOutProfile, TYPE_RGBA_16, INTENT_PERCEPTUAL, 0);
9503 cmsDoTransform (hTransform, image, image, width*height);
9504 raw_color = 1; /* Don't use rgb_cam with a profile */
9505 cmsDeleteTransform (hTransform);
9506 cmsCloseProfile (hOutProfile);
9508 cmsCloseProfile (hInProfile);
9512 void CLASS convert_to_rgb()
9514 int row, col, c, i, j, k;
9516 float out[3], out_cam[3][4];
9517 double num, inverse[3][3];
9518 static const double xyzd50_srgb[3][3] =
9519 { { 0.436083, 0.385083, 0.143055 },
9520 { 0.222507, 0.716888, 0.060608 },
9521 { 0.013930, 0.097097, 0.714022 } };
9522 static const double rgb_rgb[3][3] =
9523 { { 1,0,0 }, { 0,1,0 }, { 0,0,1 } };
9524 static const double adobe_rgb[3][3] =
9525 { { 0.715146, 0.284856, 0.000000 },
9526 { 0.000000, 1.000000, 0.000000 },
9527 { 0.000000, 0.041166, 0.958839 } };
9528 static const double wide_rgb[3][3] =
9529 { { 0.593087, 0.404710, 0.002206 },
9530 { 0.095413, 0.843149, 0.061439 },
9531 { 0.011621, 0.069091, 0.919288 } };
9532 static const double prophoto_rgb[3][3] =
9533 { { 0.529317, 0.330092, 0.140588 },
9534 { 0.098368, 0.873465, 0.028169 },
9535 { 0.016879, 0.117663, 0.865457 } };
9536 static const double aces_rgb[3][3] =
9537 { { 0.432996, 0.375380, 0.189317 },
9538 { 0.089427, 0.816523, 0.102989 },
9539 { 0.019165, 0.118150, 0.941914 } };
9540 static const double (*out_rgb[])[3] =
9541 { rgb_rgb, adobe_rgb, wide_rgb, prophoto_rgb, xyz_rgb, aces_rgb };
9542 static const char *name[] =
9543 { "sRGB", "Adobe RGB (1998)", "WideGamut D65", "ProPhoto D65", "XYZ", "ACES" };
9544 static const unsigned phead[] =
9545 { 1024, 0, 0x2100000, 0x6d6e7472, 0x52474220, 0x58595a20, 0, 0, 0,
9546 0x61637370, 0, 0, 0x6e6f6e65, 0, 0, 0, 0, 0xf6d6, 0x10000, 0xd32d };
9548 { 10, 0x63707274, 0, 36, /* cprt */
9549 0x64657363, 0, 40, /* desc */
9550 0x77747074, 0, 20, /* wtpt */
9551 0x626b7074, 0, 20, /* bkpt */
9552 0x72545243, 0, 14, /* rTRC */
9553 0x67545243, 0, 14, /* gTRC */
9554 0x62545243, 0, 14, /* bTRC */
9555 0x7258595a, 0, 20, /* rXYZ */
9556 0x6758595a, 0, 20, /* gXYZ */
9557 0x6258595a, 0, 20 }; /* bXYZ */
9558 static const unsigned pwhite[] = { 0xf351, 0x10000, 0x116cc };
9559 unsigned pcurve[] = { 0x63757276, 0, 1, 0x1000000 };
9561 gamma_curve (gamm[0], gamm[1], 0, 0);
9562 memcpy (out_cam, rgb_cam, sizeof out_cam);
9563 raw_color |= colors == 1 || document_mode ||
9564 output_color < 1 || output_color > 6;
9566 oprof = (unsigned *) calloc (phead[0], 1);
9567 merror (oprof, "convert_to_rgb()");
9568 memcpy (oprof, phead, sizeof phead);
9569 if (output_color == 5) oprof[4] = oprof[5];
9570 oprof[0] = 132 + 12*pbody[0];
9571 for (i=0; i < pbody[0]; i++) {
9572 oprof[oprof[0]/4] = i ? (i > 1 ? 0x58595a20 : 0x64657363) : 0x74657874;
9573 pbody[i*3+2] = oprof[0];
9574 oprof[0] += (pbody[i*3+3] + 3) & -4;
9576 memcpy (oprof+32, pbody, sizeof pbody);
9577 oprof[pbody[5]/4+2] = strlen(name[output_color-1]) + 1;
9578 memcpy ((char *)oprof+pbody[8]+8, pwhite, sizeof pwhite);
9579 pcurve[3] = (short)(256/gamm[5]+0.5) << 16;
9580 for (i=4; i < 7; i++)
9581 memcpy ((char *)oprof+pbody[i*3+2], pcurve, sizeof pcurve);
9582 pseudoinverse ((double (*)[3]) out_rgb[output_color-1], inverse, 3);
9583 for (i=0; i < 3; i++)
9584 for (j=0; j < 3; j++) {
9585 for (num = k=0; k < 3; k++)
9586 num += xyzd50_srgb[i][k] * inverse[j][k];
9587 oprof[pbody[j*3+23]/4+i+2] = num * 0x10000 + 0.5;
9589 for (i=0; i < phead[0]/4; i++)
9590 oprof[i] = htonl(oprof[i]);
9591 strcpy ((char *)oprof+pbody[2]+8, "auto-generated by dcraw");
9592 strcpy ((char *)oprof+pbody[5]+12, name[output_color-1]);
9593 for (i=0; i < 3; i++)
9594 for (j=0; j < colors; j++)
9595 for (out_cam[i][j] = k=0; k < 3; k++)
9596 out_cam[i][j] += out_rgb[output_color-1][i][k] * rgb_cam[k][j];
9599 fprintf (stderr, raw_color ? _("Building histograms...\n") :
9600 _("Converting to %s colorspace...\n"), name[output_color-1]);
9602 memset (histogram, 0, sizeof histogram);
9603 for (img=image[0], row=0; row < height; row++)
9604 for (col=0; col < width; col++, img+=4) {
9606 out[0] = out[1] = out[2] = 0;
9608 out[0] += out_cam[0][c] * img[c];
9609 out[1] += out_cam[1][c] * img[c];
9610 out[2] += out_cam[2][c] * img[c];
9612 FORC3 img[c] = CLIP((int) out[c]);
9614 else if (document_mode)
9615 img[0] = img[fcol(row,col)];
9616 FORCC histogram[c][img[c] >> 3]++;
9618 if (colors == 4 && output_color) colors = 3;
9619 if (document_mode && filters) colors = 1;
9622 // Export color matrix to Cinelerra.
9623 // It can't be applied before interpolation.
9625 for(i = 0; i < 3; i++) {
9626 for(j = 0; j < 3; j++)
9627 dcraw_matrix[k++] = rgb_cam[i][j];
9632 void CLASS fuji_rotate()
9638 ushort wide, high, (*img)[4], (*pix)[4];
9640 if (!fuji_width) return;
9642 fprintf (stderr,_("Rotating image 45 degrees...\n"));
9643 fuji_width = (fuji_width - 1 + shrink) >> shrink;
9645 wide = fuji_width / step;
9646 high = (height - fuji_width) / step;
9647 img = (ushort (*)[4]) calloc (high, wide*sizeof *img);
9648 merror (img, "fuji_rotate()");
9650 for (row=0; row < high; row++)
9651 for (col=0; col < wide; col++) {
9652 ur = r = fuji_width + (row-col)*step;
9653 uc = c = (row+col)*step;
9654 if (ur > height-2 || uc > width-2) continue;
9657 pix = image + ur*width + uc;
9658 for (i=0; i < colors; i++)
9659 img[row*wide+col][i] =
9660 (pix[ 0][i]*(1-fc) + pix[ 1][i]*fc) * (1-fr) +
9661 (pix[width][i]*(1-fc) + pix[width+1][i]*fc) * fr;
9670 void CLASS stretch()
9672 ushort newdim, (*img)[4], *pix0, *pix1;
9676 if (pixel_aspect == 1) return;
9677 if (verbose) fprintf (stderr,_("Stretching the image...\n"));
9678 if (pixel_aspect < 1) {
9679 newdim = height / pixel_aspect + 0.5;
9680 img = (ushort (*)[4]) calloc (width, newdim*sizeof *img);
9681 merror (img, "stretch()");
9682 for (rc=row=0; row < newdim; row++, rc+=pixel_aspect) {
9683 frac = rc - (c = rc);
9684 pix0 = pix1 = image[c*width];
9685 if (c+1 < height) pix1 += width*4;
9686 for (col=0; col < width; col++, pix0+=4, pix1+=4)
9687 FORCC img[row*width+col][c] = pix0[c]*(1-frac) + pix1[c]*frac + 0.5;
9691 newdim = width * pixel_aspect + 0.5;
9692 img = (ushort (*)[4]) calloc (height, newdim*sizeof *img);
9693 merror (img, "stretch()");
9694 for (rc=col=0; col < newdim; col++, rc+=1/pixel_aspect) {
9695 frac = rc - (c = rc);
9696 pix0 = pix1 = image[c];
9697 if (c+1 < width) pix1 += 4;
9698 for (row=0; row < height; row++, pix0+=width*4, pix1+=width*4)
9699 FORCC img[row*newdim+col][c] = pix0[c]*(1-frac) + pix1[c]*frac + 0.5;
9707 int CLASS flip_index (int row, int col)
9709 if (flip & 4) SWAP(row,col);
9710 if (flip & 2) row = iheight - 1 - row;
9711 if (flip & 1) col = iwidth - 1 - col;
9712 return row * iwidth + col;
9718 union { char c[4]; short s[2]; int i; } val;
9722 ushort order, magic;
9725 struct tiff_tag tag[23];
9728 struct tiff_tag exif[4];
9730 struct tiff_tag gpst[10];
9734 char desc[512], make[64], model[64], soft[32], date[20], artist[64];
9737 void CLASS tiff_set (struct tiff_hdr *th, ushort *ntag,
9738 ushort tag, ushort type, int count, int val)
9740 struct tiff_tag *tt;
9743 tt = (struct tiff_tag *)(ntag+1) + (*ntag)++;
9745 if (type == 1 && count <= 4)
9746 FORC(4) tt->val.c[c] = val >> (c << 3);
9747 else if (type == 2) {
9748 count = strnlen((char *)th + val, count-1) + 1;
9750 FORC(4) tt->val.c[c] = ((char *)th)[val+c];
9751 } else if (type == 3 && count <= 2)
9752 FORC(2) tt->val.s[c] = val >> (c << 4);
9758 #define TOFF(ptr) ((char *)(&(ptr)) - (char *)th)
9760 void CLASS tiff_head (struct tiff_hdr *th, int full)
9765 memset (th, 0, sizeof *th);
9766 th->order = htonl(0x4d4d4949) >> 16;
9769 th->rat[0] = th->rat[2] = 300;
9770 th->rat[1] = th->rat[3] = 1;
9771 FORC(6) th->rat[4+c] = 1000000;
9772 th->rat[4] *= shutter;
9773 th->rat[6] *= aperture;
9774 th->rat[8] *= focal_len;
9775 strncpy (th->desc, desc, 512);
9776 strncpy (th->make, make, 64);
9777 strncpy (th->model, model, 64);
9778 strcpy (th->soft, "dcraw v"DCRAW_VERSION);
9779 t = localtime (×tamp);
9780 sprintf (th->date, "%04d:%02d:%02d %02d:%02d:%02d",
9781 t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);
9782 strncpy (th->artist, artist, 64);
9784 tiff_set (th, &th->ntag, 254, 4, 1, 0);
9785 tiff_set (th, &th->ntag, 256, 4, 1, width);
9786 tiff_set (th, &th->ntag, 257, 4, 1, height);
9787 tiff_set (th, &th->ntag, 258, 3, colors, output_bps);
9789 th->tag[th->ntag-1].val.i = TOFF(th->bps);
9790 FORC4 th->bps[c] = output_bps;
9791 tiff_set (th, &th->ntag, 259, 3, 1, 1);
9792 tiff_set (th, &th->ntag, 262, 3, 1, 1 + (colors > 1));
9794 tiff_set (th, &th->ntag, 270, 2, 512, TOFF(th->desc));
9795 tiff_set (th, &th->ntag, 271, 2, 64, TOFF(th->make));
9796 tiff_set (th, &th->ntag, 272, 2, 64, TOFF(th->model));
9798 if (oprof) psize = ntohl(oprof[0]);
9799 tiff_set (th, &th->ntag, 273, 4, 1, sizeof *th + psize);
9800 tiff_set (th, &th->ntag, 277, 3, 1, colors);
9801 tiff_set (th, &th->ntag, 278, 4, 1, height);
9802 tiff_set (th, &th->ntag, 279, 4, 1, height*width*colors*output_bps/8);
9804 tiff_set (th, &th->ntag, 274, 3, 1, "12435867"[flip]-'0');
9805 tiff_set (th, &th->ntag, 282, 5, 1, TOFF(th->rat[0]));
9806 tiff_set (th, &th->ntag, 283, 5, 1, TOFF(th->rat[2]));
9807 tiff_set (th, &th->ntag, 284, 3, 1, 1);
9808 tiff_set (th, &th->ntag, 296, 3, 1, 2);
9809 tiff_set (th, &th->ntag, 305, 2, 32, TOFF(th->soft));
9810 tiff_set (th, &th->ntag, 306, 2, 20, TOFF(th->date));
9811 tiff_set (th, &th->ntag, 315, 2, 64, TOFF(th->artist));
9812 tiff_set (th, &th->ntag, 34665, 4, 1, TOFF(th->nexif));
9813 if (psize) tiff_set (th, &th->ntag, 34675, 7, psize, sizeof *th);
9814 tiff_set (th, &th->nexif, 33434, 5, 1, TOFF(th->rat[4]));
9815 tiff_set (th, &th->nexif, 33437, 5, 1, TOFF(th->rat[6]));
9816 tiff_set (th, &th->nexif, 34855, 3, 1, iso_speed);
9817 tiff_set (th, &th->nexif, 37386, 5, 1, TOFF(th->rat[8]));
9819 tiff_set (th, &th->ntag, 34853, 4, 1, TOFF(th->ngps));
9820 tiff_set (th, &th->ngps, 0, 1, 4, 0x202);
9821 tiff_set (th, &th->ngps, 1, 2, 2, gpsdata[29]);
9822 tiff_set (th, &th->ngps, 2, 5, 3, TOFF(th->gps[0]));
9823 tiff_set (th, &th->ngps, 3, 2, 2, gpsdata[30]);
9824 tiff_set (th, &th->ngps, 4, 5, 3, TOFF(th->gps[6]));
9825 tiff_set (th, &th->ngps, 5, 1, 1, gpsdata[31]);
9826 tiff_set (th, &th->ngps, 6, 5, 1, TOFF(th->gps[18]));
9827 tiff_set (th, &th->ngps, 7, 5, 3, TOFF(th->gps[12]));
9828 tiff_set (th, &th->ngps, 18, 2, 12, TOFF(th->gps[20]));
9829 tiff_set (th, &th->ngps, 29, 2, 12, TOFF(th->gps[23]));
9830 memcpy (th->gps, gpsdata, sizeof th->gps);
9834 void CLASS jpeg_thumb()
9840 thumb = (char *) malloc (thumb_length);
9841 merror (thumb, "jpeg_thumb()");
9842 fread (thumb, 1, thumb_length, ifp);
9845 if (strcmp (thumb+6, "Exif")) {
9846 memcpy (exif, "\xff\xe1 Exif\0\0", 10);
9847 exif[1] = htons (8 + sizeof th);
9848 fwrite (exif, 1, sizeof exif, ofp);
9850 fwrite (&th, 1, sizeof th, ofp);
9852 fwrite (thumb+2, 1, thumb_length-2, ofp);
9856 void CLASS write_ppm_tiff()
9861 int c, row, col, soff, rstep, cstep;
9862 int perc, val, total, white=0x2000;
9864 perc = width * height * 0.01; /* 99th percentile white level */
9865 if (fuji_width) perc /= 2;
9866 if (!((highlight & ~2) || no_auto_bright))
9867 for (white=c=0; c < colors; c++) {
9868 for (val=0x2000, total=0; --val > 32; )
9869 if ((total += histogram[c][val]) > perc) break;
9870 if (white < val) white = val;
9872 gamma_curve (gamm[0], gamm[1], 2, (white << 3)/bright);
9875 if (flip & 4) SWAP(height,width);
9876 ppm = (uchar *) calloc (width, colors*output_bps/8);
9877 ppm2 = (ushort *) ppm;
9878 merror (ppm, "write_ppm_tiff()");
9881 fwrite (&th, sizeof th, 1, ofp);
9883 fwrite (oprof, ntohl(oprof[0]), 1, ofp);
9884 } else if (colors > 3)
9886 "P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLTYPE %s\nENDHDR\n",
9887 width, height, colors, (1 << output_bps)-1, cdesc);
9889 fprintf (ofp, "P%d\n%d %d\n%d\n",
9890 colors/2+5, width, height, (1 << output_bps)-1);
9891 soff = flip_index (0, 0);
9892 cstep = flip_index (0, 1) - soff;
9893 rstep = flip_index (1, 0) - flip_index (0, width);
9894 for (row=0; row < height; row++, soff += rstep) {
9895 for (col=0; col < width; col++, soff += cstep)
9896 if (output_bps == 8)
9897 FORCC ppm [col*colors+c] = curve[image[soff][c]] >> 8;
9898 else FORCC ppm2[col*colors+c] = curve[image[soff][c]];
9899 if (output_bps == 16 && !output_tiff && htons(0x55aa) != 0x55aa)
9900 swab (ppm2, ppm2, width*colors*2);
9901 fwrite (ppm, colors*output_bps/8, width, ofp);
9907 void CLASS write_cinelerra (FILE *ofp)
9912 for (row = 0; row < height; row++)
9914 output = dcraw_data[row];
9918 for (col = 0; col < width; col++)
9920 ushort *pixel = image[row * width + col];
9922 *output++ = (float)pixel[0] / 0xffff;
9923 *output++ = (float)pixel[1] / 0xffff;
9924 *output++ = (float)pixel[2] / 0xffff;
9926 if(dcraw_alpha) *output++ = 1.0;
9931 for (col = 0; col < width; col++)
9933 ushort *pixel = image[row * width + col];
9935 *output++ = (float)pixel[0] / 0xffff;
9936 *output++ = (float)pixel[1] / 0xffff;
9937 *output++ = (float)pixel[2] / 0xffff;
9939 if(dcraw_alpha) *output++ = 1.0;
9946 int CLASS dcraw_main (int argc, const char **argv)
9948 int arg, status=0, quality, i, c;
9949 int timestamp_only=0, thumbnail_only=0, identify_only=0;
9950 int user_qual=-1, user_black=-1, user_sat=-1, user_flip=-1;
9951 int use_fuji_rotate=1, write_to_stdout=0, read_from_stdin=0;
9952 const char *sp, *bpfile=0, *dark_frame=0, *write_ext;
9953 char opm, opt, *ofname, *cp;
9956 const char *cam_profile=0, *out_profile=0;
9960 reset(); // Globals must be reset
9963 putenv ((char *) "TZ=UTC");
9966 setlocale (LC_CTYPE, "");
9967 setlocale (LC_MESSAGES, "");
9968 bindtextdomain ("dcraw", LOCALEDIR);
9969 textdomain ("dcraw");
9973 printf(_("\nRaw photo decoder \"dcraw\" v%s"), DCRAW_VERSION);
9974 printf(_("\nby Dave Coffin, dcoffin a cybercom o net\n"));
9975 printf(_("\nUsage: %s [OPTION]... [FILE]...\n\n"), argv[0]);
9976 puts(_("-v Print verbose messages"));
9977 puts(_("-c Write image data to standard output"));
9978 puts(_("-e Extract embedded thumbnail image"));
9979 puts(_("-i Identify files without decoding them"));
9980 puts(_("-i -v Identify files and show metadata"));
9981 puts(_("-z Change file dates to camera timestamp"));
9982 puts(_("-w Use camera white balance, if possible"));
9983 puts(_("-a Average the whole image for white balance"));
9984 puts(_("-A <x y w h> Average a grey box for white balance"));
9985 puts(_("-r <r g b g> Set custom white balance"));
9986 puts(_("+M/-M Use/don't use an embedded color matrix"));
9987 puts(_("-C <r b> Correct chromatic aberration"));
9988 puts(_("-P <file> Fix the dead pixels listed in this file"));
9989 puts(_("-K <file> Subtract dark frame (16-bit raw PGM)"));
9990 puts(_("-k <num> Set the darkness level"));
9991 puts(_("-S <num> Set the saturation level"));
9992 puts(_("-n <num> Set threshold for wavelet denoising"));
9993 puts(_("-H [0-9] Highlight mode (0=clip, 1=unclip, 2=blend, 3+=rebuild)"));
9994 puts(_("-t [0-7] Flip image (0=none, 3=180, 5=90CCW, 6=90CW)"));
9995 puts(_("-o [0-6] Output colorspace (raw,sRGB,Adobe,Wide,ProPhoto,XYZ,ACES)"));
9997 puts(_("-o <file> Apply output ICC profile from file"));
9998 puts(_("-p <file> Apply camera ICC profile from file or \"embed\""));
10000 puts(_("-d Document mode (no color, no interpolation)"));
10001 puts(_("-D Document mode without scaling (totally raw)"));
10002 puts(_("-j Don't stretch or rotate raw pixels"));
10003 puts(_("-W Don't automatically brighten the image"));
10004 puts(_("-b <num> Adjust brightness (default = 1.0)"));
10005 puts(_("-g <p ts> Set custom gamma curve (default = 2.222 4.5)"));
10006 puts(_("-q [0-3] Set the interpolation quality"));
10007 puts(_("-h Half-size color image (twice as fast as \"-q 0\")"));
10008 puts(_("-f Interpolate RGGB as four colors"));
10009 puts(_("-m <num> Apply a 3x3 median filter to R-G and B-G"));
10010 puts(_("-s [0..N-1] Select one raw image or \"all\" from each file"));
10011 puts(_("-6 Write 16-bit instead of 8-bit"));
10012 puts(_("-4 Linear 16-bit, same as \"-6 -W -g 1 1\""));
10013 puts(_("-T Write TIFF instead of PPM"));
10018 for (arg=1; (((opm = argv[arg][0]) - 2) | 2) == '+'; ) {
10019 opt = argv[arg++][1];
10020 if ((cp = (char *) strchr (sp="nbrkStqmHACg", opt)))
10021 for (i=0; i < "114111111422"[cp-sp]-'0'; i++)
10022 if (!isdigit(argv[arg+i][0])) {
10023 fprintf (stderr,_("Non-numeric argument to \"-%c\"\n"), opt);
10027 case 'n': threshold = atof(argv[arg++]); break;
10028 case 'b': bright = atof(argv[arg++]); break;
10030 FORC4 user_mul[c] = atof(argv[arg++]); break;
10031 case 'C': aber[0] = 1 / atof(argv[arg++]);
10032 aber[2] = 1 / atof(argv[arg++]); break;
10033 case 'g': gamm[0] = atof(argv[arg++]);
10034 gamm[1] = atof(argv[arg++]);
10035 if (gamm[0]) gamm[0] = 1/gamm[0]; break;
10036 case 'k': user_black = atoi(argv[arg++]); break;
10037 case 'S': user_sat = atoi(argv[arg++]); break;
10038 case 't': user_flip = atoi(argv[arg++]); break;
10039 case 'q': user_qual = atoi(argv[arg++]); break;
10040 case 'm': med_passes = atoi(argv[arg++]); break;
10041 case 'H': highlight = atoi(argv[arg++]); break;
10043 shot_select = abs(atoi(argv[arg]));
10044 multi_out = !strcmp(argv[arg++],"all");
10047 if (isdigit(argv[arg][0]) && !argv[arg][1])
10048 output_color = atoi(argv[arg++]);
10050 else out_profile = argv[arg++];
10052 case 'p': cam_profile = argv[arg++];
10055 case 'P': bpfile = argv[arg++]; break;
10056 case 'K': dark_frame = argv[arg++]; break;
10057 case 'z': timestamp_only = 1; break;
10058 case 'e': thumbnail_only = 1; break;
10059 case 'i': identify_only = 1; break;
10060 case 'c': write_to_stdout = 1; break;
10061 case 'v': verbose = 1; break;
10062 case 'h': half_size = 1; break;
10063 case 'f': four_color_rgb = 1; break;
10064 case 'A': FORC4 greybox[c] = atoi(argv[arg++]);
10065 case 'a': use_auto_wb = 1; break;
10066 case 'w': use_camera_wb = 1; break;
10067 case 'M': use_camera_matrix = 3 * (opm == '+'); break;
10068 case 'I': read_from_stdin = 1; break;
10069 case 'E': document_mode++;
10070 case 'D': document_mode++;
10071 case 'd': document_mode++;
10072 case 'j': use_fuji_rotate = 0; break;
10073 case 'W': no_auto_bright = 1; break;
10074 case 'T': output_tiff = 1; break;
10075 case '4': gamm[0] = gamm[1] =
10076 no_auto_bright = 1;
10077 case '6': output_bps = 16; break;
10079 fprintf (stderr,_("Unknown option \"-%c\".\n"), opt);
10084 fprintf (stderr,_("No files to process.\n"));
10087 if (write_to_stdout) {
10089 if (0 && isatty(1)) {
10090 fprintf (stderr,_("Will not write an image to the terminal!\n"));
10093 #if defined(WIN32) || defined(DJGPP) || defined(__CYGWIN__)
10094 if (setmode(1,O_BINARY) < 0) {
10095 perror ("setmode()");
10100 for ( ; arg < argc; arg++) {
10105 meta_data = ofname = 0;
10107 if (setjmp (failure)) {
10108 if (fileno(ifp) > 2) fclose(ifp);
10109 if (fileno(ofp) > 2) fclose(ofp);
10113 ifname = argv[arg];
10114 if (!(ifp = fopen (ifname, "rb"))) {
10118 status = (identify(),!is_raw);
10119 if (user_flip >= 0)
10121 switch ((flip+3600) % 360) {
10122 case 270: flip = 5; break;
10123 case 180: flip = 3; break;
10126 if (timestamp_only) {
10127 if ((status = !timestamp))
10128 fprintf (stderr,_("%s has no timestamp.\n"), ifname);
10129 else if (identify_only)
10130 printf ("%10ld%10d %s\n", (long) timestamp, shot_order, ifname);
10133 fprintf (stderr,_("%s time set to %d.\n"), ifname, (int) timestamp);
10134 ut.actime = ut.modtime = timestamp;
10135 utime (ifname, &ut);
10140 // write_fun = &CLASS write_ppm_tiff;
10141 write_fun = write_cinelerra;
10143 if (thumbnail_only) {
10144 if ((status = !thumb_offset)) {
10145 fprintf (stderr,_("%s has no thumbnail.\n"), ifname);
10147 } else if (thumb_load_raw) {
10148 load_raw = thumb_load_raw;
10149 data_offset = thumb_offset;
10150 height = thumb_height;
10151 width = thumb_width;
10155 fseek (ifp, thumb_offset, SEEK_SET);
10156 write_fun = write_thumb;
10160 if (load_raw == &CLASS kodak_ycbcr_load_raw) {
10161 height += height & 1;
10162 width += width & 1;
10164 if (identify_only && verbose && make[0]) {
10165 printf (_("\nFilename: %s\n"), ifname);
10166 printf (_("Timestamp: %s"), ctime(×tamp));
10167 printf (_("Camera: %s %s\n"), make, model);
10169 printf (_("Owner: %s\n"), artist);
10171 printf (_("DNG Version: "));
10172 for (i=24; i >= 0; i -= 8)
10173 printf ("%d%c", dng_version >> i & 255, i ? '.':'\n');
10175 printf (_("ISO speed: %d\n"), (int) iso_speed);
10176 printf (_("Shutter: "));
10177 if (shutter > 0 && shutter < 1)
10178 shutter = (printf ("1/"), 1 / shutter);
10179 printf (_("%0.1f sec\n"), shutter);
10180 printf (_("Aperture: f/%0.1f\n"), aperture);
10181 printf (_("Focal length: %0.1f mm\n"), focal_len);
10182 printf (_("Embedded ICC profile: %s\n"), profile_length ? _("yes"):_("no"));
10183 printf (_("Number of raw images: %d\n"), is_raw);
10184 if (pixel_aspect != 1)
10185 printf (_("Pixel Aspect Ratio: %0.6f\n"), pixel_aspect);
10187 printf (_("Thumb size: %4d x %d\n"), thumb_width, thumb_height);
10188 printf (_("Full size: %4d x %d\n"), raw_width, raw_height);
10191 // else if (!is_raw)
10192 // fprintf (stderr,_("Cannot decode file %s\n"), ifname);
10193 if (!is_raw) goto next;
10194 shrink = filters && (half_size || (!identify_only &&
10195 (threshold || aber[0] != 1 || aber[2] != 1)));
10196 iheight = (height + shrink) >> shrink;
10197 iwidth = (width + shrink) >> shrink;
10198 if (identify_only) {
10200 if (document_mode == 3) {
10201 top_margin = left_margin = fuji_width = 0;
10202 height = raw_height;
10205 iheight = (height + shrink) >> shrink;
10206 iwidth = (width + shrink) >> shrink;
10207 if (use_fuji_rotate) {
10209 fuji_width = (fuji_width - 1 + shrink) >> shrink;
10210 iwidth = fuji_width / sqrt(0.5);
10211 iheight = (iheight - fuji_width) / sqrt(0.5);
10213 if (pixel_aspect < 1) iheight = iheight / pixel_aspect + 0.5;
10214 if (pixel_aspect > 1) iwidth = iwidth * pixel_aspect + 0.5;
10218 SWAP(iheight,iwidth);
10219 printf (_("Image size: %4d x %d\n"), width, height);
10220 printf (_("Output size: %4d x %d\n"), iwidth, iheight);
10221 printf (_("Raw colors: %d"), colors);
10223 int fhigh = 2, fwide = 2;
10224 if ((filters ^ (filters >> 8)) & 0xff) fhigh = 4;
10225 if ((filters ^ (filters >> 16)) & 0xffff) fhigh = 8;
10226 if (filters == 1) fhigh = fwide = 16;
10227 if (filters == 9) fhigh = fwide = 6;
10228 printf (_("\nFilter pattern: "));
10229 for (i=0; i < fhigh; i++)
10230 for (c = i && putchar('/') && 0; c < fwide; c++)
10231 putchar (cdesc[fcol(i,c)]);
10233 printf (_("\nDaylight multipliers:"));
10234 FORCC printf (" %f", pre_mul[c]);
10235 if (cam_mul[0] > 0) {
10236 printf (_("\nCamera multipliers:"));
10237 FORC4 printf (" %f", cam_mul[c]);
10243 // printf (_("%s is a %s %s image.\n"), ifname, make, model);
10249 meta_data = (char *) malloc (meta_length);
10250 merror (meta_data, "main()");
10252 if (filters || colors == 1) {
10253 raw_image = (ushort *) calloc ((raw_height+7), raw_width*2);
10254 merror (raw_image, "main()");
10256 image = (ushort (*)[4]) calloc (iheight, iwidth*sizeof *image);
10257 merror (image, "main()");
10260 fprintf (stderr,_("Loading %s %s image from %s ...\n"),
10261 make, model, ifname);
10262 if (shot_select >= is_raw)
10263 fprintf (stderr,_("%s: \"-s %d\" requests a nonexistent image!\n"),
10264 ifname, shot_select);
10265 fseeko (ifp, data_offset, SEEK_SET);
10266 if (raw_image && read_from_stdin)
10267 fread (raw_image, 2, raw_height*raw_width, stdin);
10268 else (*load_raw)();
10269 if (document_mode == 3) {
10270 top_margin = left_margin = fuji_width = 0;
10271 height = raw_height;
10274 iheight = (height + shrink) >> shrink;
10275 iwidth = (width + shrink) >> shrink;
10277 image = (ushort (*)[4]) calloc (iheight, iwidth*sizeof *image);
10278 merror (image, "main()");
10279 crop_masked_pixels();
10282 if (zero_is_bad) remove_zeroes();
10283 bad_pixels (bpfile);
10284 if (dark_frame) subtract (dark_frame);
10285 quality = 2 + !fuji_width;
10286 if (user_qual >= 0) quality = user_qual;
10288 FORC3 if (i > cblack[c]) i = cblack[c];
10289 FORC4 cblack[c] -= i;
10292 FORC (cblack[4] * cblack[5])
10293 if (i > cblack[6+c]) i = cblack[6+c];
10294 FORC (cblack[4] * cblack[5])
10297 if (user_black >= 0) black = user_black;
10298 FORC4 cblack[c] += black;
10299 if (user_sat > 0) maximum = user_sat;
10304 if (document_mode || load_raw == &CLASS foveon_dp_load_raw) {
10305 for (i=0; i < height*width*4; i++)
10306 if ((short) image[0][i] < 0) image[0][i] = 0;
10307 } else foveon_interpolate();
10308 } else if (document_mode < 2)
10311 if (filters && !document_mode) {
10314 else if (quality == 1 || colors > 3)
10316 else if (quality == 2 && filters > 1000)
10318 else if (filters == 9)
10319 xtrans_interpolate (quality*2-3);
10324 for (colors=3, i=0; i < height*width; i++)
10325 image[i][1] = (image[i][1] + image[i][3]) >> 1;
10326 if (!is_foveon && colors == 3) median_filter();
10327 if (!is_foveon && highlight == 2) blend_highlights();
10328 if (!is_foveon && highlight > 2) recover_highlights();
10329 if (use_fuji_rotate) fuji_rotate();
10331 if (cam_profile) apply_profile (cam_profile, out_profile);
10334 if (use_fuji_rotate) stretch();
10336 if (write_fun == &CLASS jpeg_thumb)
10337 write_ext = ".jpg";
10338 else if (output_tiff && write_fun == &CLASS write_ppm_tiff)
10339 write_ext = ".tiff";
10341 write_ext = ".pgm\0.ppm\0.ppm\0.pam" + colors*5-5;
10342 ofname = (char *) malloc (strlen(ifname) + 64);
10343 merror (ofname, "main()");
10344 if (write_to_stdout)
10345 strcpy (ofname,_("standard output"));
10347 strcpy (ofname, ifname);
10348 if ((cp = strrchr (ofname, '.'))) *cp = 0;
10350 sprintf (ofname+strlen(ofname), "_%0*d",
10351 snprintf(0,0,"%d",is_raw-1), shot_select);
10352 if (thumbnail_only)
10353 strcat (ofname, ".thumb");
10354 strcat (ofname, write_ext);
10355 ofp = fopen (ofname, "wb");
10363 fprintf (stderr,_("Writing data to %s ...\n"), ofname);
10366 if (ofp != stdout) fclose(ofp);
10368 if (meta_data) free (meta_data);
10369 if (ofname) free (ofname);
10370 if (oprof) free (oprof);
10371 if (image) free (image);
10373 if (++shot_select < is_raw) arg--;
10374 else shot_select = 0;