2 dcraw.c -- Dave Coffin's raw photo decoder
3 Copyright 1997-2012 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: 2012/12/23 19:25:36 $
26 #define DCRAW_VERSION "9.17"
32 #define _USE_MATH_DEFINES
44 #include <sys/types.h>
57 #include <jasper/jasper.h> /* Decode RED camera movies */
60 #include <jpeglib.h> /* Decode compressed Kodak DC120 photos */
61 #endif /* and Adobe Lossy DNGs */
63 #include <lcms.h> /* Support color profiles */
67 #define _(String) gettext(String)
69 #define _(String) (String)
72 #if defined(DJGPP) || defined(__MINGW32__)
76 #define fgetc getc_unlocked
82 #include <sys/utime.h>
84 #pragma comment(lib, "ws2_32.lib")
85 #define snprintf _snprintf
86 #define strcasecmp stricmp
87 #define strncasecmp strnicmp
88 typedef __int64 INT64;
89 typedef unsigned __int64 UINT64;
93 #include <netinet/in.h>
94 typedef long long INT64;
95 typedef unsigned long long UINT64;
99 #error Please compile dcraw.c by itself.
100 #error Do not link it with ljpeg_decode.
104 #define LONG_BIT (8 * sizeof (long))
108 #define uchar unsigned char
111 #define ushort unsigned short
115 All global variables are defined here, and all functions that
116 access them are prefixed with "CLASS". Note that a thread-safe
117 C++ class cannot have non-const static local variables.
121 char dcraw_info[1024];
124 float dcraw_matrix[9];
135 char cdesc[5], desc[512], make[64], model[64], model2[64], artist[64];
136 float flash_used, canon_ev, iso_speed, shutter, aperture, focal_len;
138 unsigned shot_order, kodak_cbpp, filters, exif_cfa, unique_id;
139 off_t strip_offset, data_offset;
140 off_t thumb_offset, meta_offset, profile_offset;
141 unsigned thumb_length, meta_length, profile_length;
142 unsigned thumb_misc, *oprof, fuji_layout, shot_select=0, multi_out=0;
143 unsigned tiff_nifds, tiff_samples, tiff_bps, tiff_compress;
144 unsigned black, cblack[4], maximum, mix_green, raw_color, zero_is_bad;
145 unsigned zero_after_ff, is_raw, dng_version, is_foveon, data_error;
146 unsigned tile_width, tile_length, gpsdata[32], load_flags;
147 ushort raw_height, raw_width, height, width, top_margin, left_margin;
148 ushort shrink, iheight, iwidth, fuji_width, thumb_width, thumb_height;
149 ushort *raw_image, (*image)[4];
150 ushort white[8][8], curve[0x10000], cr2_slice[3], sraw_mul[4];
153 static int mask[8][4], flip, tiff_flip, colors;
156 double pixel_aspect, aber[4]={1,1,1,1}, gamm[6]={ 0.45,4.5,0,0,0,0 };
157 float bright=1, user_mul[4]={0,0,0,0}, threshold=0;
158 int half_size=0, four_color_rgb=0, document_mode=0, highlight=0;
159 int verbose=0, use_auto_wb=0, use_camera_wb=0, use_camera_matrix=-1;
160 int output_color=1, output_bps=8, output_tiff=0, med_passes=0;
161 int no_auto_bright=0;
162 unsigned greybox[4] = { 0, 0, UINT_MAX, UINT_MAX };
163 float cam_mul[4], pre_mul[4], cmatrix[3][4], rgb_cam[3][4];
164 const double xyz_rgb[3][3] = { /* XYZ from RGB */
165 { 0.412453, 0.357580, 0.180423 },
166 { 0.212671, 0.715160, 0.072169 },
167 { 0.019334, 0.119193, 0.950227 } };
168 const float d65_white[3] = { 0.950456, 1, 1.088754 };
169 int histogram[4][0x2000];
170 void (*write_thumb)(), (*write_fun)();
171 void (*load_raw)(), (*thumb_load_raw)();
175 struct decode *branch[2];
177 } first_decode[2048], *second_decode, *free_decode;
180 int width, height, bps, comp, phint, offset, flip, samples, bytes;
181 int tile_width, tile_length;
185 int format, key_off, black, black_off, split_col, tag_21a;
191 #define FORC(cnt) for (c=0; c < cnt; c++)
192 #define FORC3 FORC(3)
193 #define FORC4 FORC(4)
194 #define FORCC FORC(colors)
196 #define SQR(x) ((x)*(x))
197 #define ABS(x) (((int)(x) ^ ((int)(x) >> 31)) - ((int)(x) >> 31))
198 #define MIN(a,b) ((a) < (b) ? (a) : (b))
199 #define MAX(a,b) ((a) > (b) ? (a) : (b))
200 #define LIM(x,min,max) MAX(min,MIN(x,max))
201 #define ULIM(x,y,z) ((y) < (z) ? LIM(x,y,z) : LIM(x,z,y))
202 #define CLIP(x) LIM(x,0,65535)
203 #define SWAP(a,b) { a=a+b; b=a-b; a=a-b; }
206 In order to inline this calculation, I make the risky
207 assumption that all filter patterns can be described
208 by a repeating pattern of eight rows and two columns
210 Do not use the FC or BAYER macros with the Leaf CatchLight,
211 because its pattern is 16x16, not 2x8.
213 Return values are either 0/1/2/3 = G/M/C/Y or 0/1/2/3 = R/G1/B/G2
215 PowerShot 600 PowerShot A50 PowerShot Pro70 Pro90 & G1
216 0xe1e4e1e4: 0x1b4e4b1e: 0x1e4b4e1b: 0xb4b4b4b4:
218 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5
219 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
220 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
221 2 M G M G M G 2 Y C Y C Y C 2 C Y C Y C Y
222 3 C Y C Y C Y 3 G M G M G M 3 G M G M G M
223 4 C Y C Y C Y 4 Y C Y C Y C
224 PowerShot A5 5 G M G M G M 5 G M G M G M
225 0x1e4e1e4e: 6 Y C Y C Y C 6 C Y C Y C Y
226 7 M G M G M G 7 M G M G M G
233 All RGB cameras use one of these Bayer grids:
235 0x16161616: 0x61616161: 0x49494949: 0x94949494:
237 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5
238 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
239 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
240 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
241 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
244 #define RAW(row,col) \
245 raw_image[(row)*raw_width+(col)]
247 #define FC(row,col) \
248 (filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)
250 #define BAYER(row,col) \
251 image[((row) >> shrink)*iwidth + ((col) >> shrink)][FC(row,col)]
253 #define BAYER2(row,col) \
254 image[((row) >> shrink)*iwidth + ((col) >> shrink)][fcol(row,col)]
256 int CLASS fcol (int row, int col)
258 static const char filter[16][16] =
259 { { 2,1,1,3,2,3,2,0,3,2,3,0,1,2,1,0 },
260 { 0,3,0,2,0,1,3,1,0,1,1,2,0,3,3,2 },
261 { 2,3,3,2,3,1,1,3,3,1,2,1,2,0,0,3 },
262 { 0,1,0,1,0,2,0,2,2,0,3,0,1,3,2,1 },
263 { 3,1,1,2,0,1,0,2,1,3,1,3,0,1,3,0 },
264 { 2,0,0,3,3,2,3,1,2,0,2,0,3,2,2,1 },
265 { 2,3,3,1,2,1,2,1,2,1,1,2,3,0,0,1 },
266 { 1,0,0,2,3,0,0,3,0,3,0,3,2,1,2,3 },
267 { 2,3,3,1,1,2,1,0,3,2,3,0,2,3,1,3 },
268 { 1,0,2,0,3,0,3,2,0,1,1,2,0,1,0,2 },
269 { 0,1,1,3,3,2,2,1,1,3,3,0,2,1,3,2 },
270 { 2,3,2,0,0,1,3,0,2,0,1,2,3,0,1,0 },
271 { 1,3,1,2,3,2,3,2,0,2,0,1,1,0,3,0 },
272 { 0,2,0,3,1,0,0,1,1,3,3,2,3,2,2,1 },
273 { 2,1,3,2,3,1,2,1,0,3,0,2,0,2,0,2 },
274 { 0,3,1,0,0,2,0,3,2,1,3,1,1,3,1,3 } };
275 static const char filter2[6][6] =
283 if (filters == 1) return filter[(row+top_margin)&15][(col+left_margin)&15];
284 if (filters == 2) return filter2[(row+6) % 6][(col+6) % 6];
289 char *my_memmem (char *haystack, size_t haystacklen,
290 char *needle, size_t needlelen)
293 for (c = haystack; c <= haystack + haystacklen - needlelen; c++)
294 if (!memcmp (c, needle, needlelen))
298 #define memmem my_memmem
301 void CLASS merror (void *ptr, const char *where)
304 fprintf (stderr,_("%s: Out of memory in %s\n"), ifname, where);
305 longjmp (failure, 1);
311 fprintf (stderr, "%s: ", ifname);
313 fprintf (stderr,_("Unexpected end of file\n"));
315 fprintf (stderr,_("Corrupt data near 0x%llx\n"), (INT64) ftello(ifp));
320 ushort CLASS sget2 (uchar *s)
322 if (order == 0x4949) /* "II" means little-endian */
323 return s[0] | s[1] << 8;
324 else /* "MM" means big-endian */
325 return s[0] << 8 | s[1];
330 uchar str[2] = { 0xff,0xff };
331 fread (str, 1, 2, ifp);
335 unsigned CLASS sget4 (uchar *s)
338 return s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24;
340 return s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3];
342 #define sget4(s) sget4((uchar *)s)
344 unsigned CLASS get4()
346 uchar str[4] = { 0xff,0xff,0xff,0xff };
347 fread (str, 1, 4, ifp);
351 unsigned CLASS getint (int type)
353 return type == 3 ? get2() : get4();
356 float CLASS int_to_float (int i)
358 union { int i; float f; } u;
363 double CLASS getreal (int type)
365 union { char c[8]; double d; } u;
369 case 3: return (unsigned short) get2();
370 case 4: return (unsigned int) get4();
371 case 5: u.d = (unsigned int) get4();
372 return u.d / (unsigned int) get4();
373 case 8: return (signed short) get2();
374 case 9: return (signed int) get4();
375 case 10: u.d = (signed int) get4();
376 return u.d / (signed int) get4();
377 case 11: return int_to_float (get4());
379 rev = 7 * ((order == 0x4949) == (ntohs(0x1234) == 0x1234));
380 for (i=0; i < 8; i++)
381 u.c[i ^ rev] = fgetc(ifp);
383 default: return fgetc(ifp);
387 void CLASS read_shorts (ushort *pixel, int count)
389 if (fread (pixel, 2, count, ifp) < count) derror();
390 if ((order == 0x4949) == (ntohs(0x1234) == 0x1234))
391 swab (pixel, pixel, count*2);
394 void CLASS canon_600_fixed_wb (int temp)
396 static const short mul[4][5] = {
397 { 667, 358,397,565,452 },
398 { 731, 390,367,499,517 },
399 { 1119, 396,348,448,537 },
400 { 1399, 485,431,508,688 } };
405 if (*mul[lo] <= temp) break;
406 for (hi=0; hi < 3; hi++)
407 if (*mul[hi] >= temp) break;
409 frac = (float) (temp - *mul[lo]) / (*mul[hi] - *mul[lo]);
410 for (i=1; i < 5; i++)
411 pre_mul[i-1] = 1 / (frac * mul[hi][i] + (1-frac) * mul[lo][i]);
414 /* Return values: 0 = white 1 = near white 2 = not white */
415 int CLASS canon_600_color (int ratio[2], int mar)
417 int clipped=0, target, miss;
421 { ratio[1] = -104; clipped = 1; }
423 { ratio[1] = 12; clipped = 1; }
425 if (ratio[1] < -264 || ratio[1] > 461) return 2;
427 { ratio[1] = -50; clipped = 1; }
429 { ratio[1] = 307; clipped = 1; }
431 target = flash_used || ratio[1] < 197
432 ? -38 - (398 * ratio[1] >> 10)
433 : -123 + (48 * ratio[1] >> 10);
434 if (target - mar <= ratio[0] &&
435 target + 20 >= ratio[0] && !clipped) return 0;
436 miss = target - ratio[0];
437 if (abs(miss) >= mar*4) return 2;
438 if (miss < -20) miss = -20;
439 if (miss > mar) miss = mar;
440 ratio[0] = target - miss;
444 void CLASS canon_600_auto_wb()
446 int mar, row, col, i, j, st, count[] = { 0,0 };
447 int test[8], total[2][8], ratio[2][2], stat[2];
449 memset (&total, 0, sizeof total);
451 if (i < 10) mar = 150;
452 else if (i > 12) mar = 20;
453 else mar = 280 - 20 * i;
454 if (flash_used) mar = 80;
455 for (row=14; row < height-14; row+=4)
456 for (col=10; col < width; col+=2) {
457 for (i=0; i < 8; i++)
458 test[(i & 4) + FC(row+(i >> 1),col+(i & 1))] =
459 BAYER(row+(i >> 1),col+(i & 1));
460 for (i=0; i < 8; i++)
461 if (test[i] < 150 || test[i] > 1500) goto next;
462 for (i=0; i < 4; i++)
463 if (abs(test[i] - test[i+4]) > 50) goto next;
464 for (i=0; i < 2; i++) {
465 for (j=0; j < 4; j+=2)
466 ratio[i][j >> 1] = ((test[i*4+j+1]-test[i*4+j]) << 10) / test[i*4+j];
467 stat[i] = canon_600_color (ratio[i], mar);
469 if ((st = stat[0] | stat[1]) > 1) goto next;
470 for (i=0; i < 2; i++)
472 for (j=0; j < 2; j++)
473 test[i*4+j*2+1] = test[i*4+j*2] * (0x400 + ratio[i][j]) >> 10;
474 for (i=0; i < 8; i++)
475 total[st][i] += test[i];
479 if (count[0] | count[1]) {
480 st = count[0]*200 < count[1];
481 for (i=0; i < 4; i++)
482 pre_mul[i] = 1.0 / (total[st][i] + total[st][i+4]);
486 void CLASS canon_600_coeff()
488 static const short table[6][12] = {
489 { -190,702,-1878,2390, 1861,-1349,905,-393, -432,944,2617,-2105 },
490 { -1203,1715,-1136,1648, 1388,-876,267,245, -1641,2153,3921,-3409 },
491 { -615,1127,-1563,2075, 1437,-925,509,3, -756,1268,2519,-2007 },
492 { -190,702,-1886,2398, 2153,-1641,763,-251, -452,964,3040,-2528 },
493 { -190,702,-1878,2390, 1861,-1349,905,-393, -432,944,2617,-2105 },
494 { -807,1319,-1785,2297, 1388,-876,769,-257, -230,742,2067,-1555 } };
498 mc = pre_mul[1] / pre_mul[2];
499 yc = pre_mul[3] / pre_mul[2];
500 if (mc > 1 && mc <= 1.28 && yc < 0.8789) t=1;
501 if (mc > 1.28 && mc <= 2) {
502 if (yc < 0.8789) t=3;
503 else if (yc <= 2) t=4;
506 for (raw_color = i=0; i < 3; i++)
507 FORCC rgb_cam[i][c] = table[t][i*4 + c] / 1024.0;
510 void CLASS canon_600_load_raw()
512 uchar data[1120], *dp;
516 for (irow=row=0; irow < height; irow++) {
517 if (fread (data, 1, 1120, ifp) < 1120) derror();
518 pix = raw_image + row*raw_width;
519 for (dp=data; dp < data+1120; dp+=10, pix+=8) {
520 pix[0] = (dp[0] << 2) + (dp[1] >> 6 );
521 pix[1] = (dp[2] << 2) + (dp[1] >> 4 & 3);
522 pix[2] = (dp[3] << 2) + (dp[1] >> 2 & 3);
523 pix[3] = (dp[4] << 2) + (dp[1] & 3);
524 pix[4] = (dp[5] << 2) + (dp[9] & 3);
525 pix[5] = (dp[6] << 2) + (dp[9] >> 2 & 3);
526 pix[6] = (dp[7] << 2) + (dp[9] >> 4 & 3);
527 pix[7] = (dp[8] << 2) + (dp[9] >> 6 );
529 if ((row+=2) > height) row = 1;
533 void CLASS canon_600_correct()
536 static const short mul[4][2] =
537 { { 1141,1145 }, { 1128,1109 }, { 1178,1149 }, { 1128,1109 } };
539 for (row=0; row < height; row++)
540 for (col=0; col < width; col++) {
541 if ((val = BAYER(row,col) - black) < 0) val = 0;
542 val = val * mul[row & 3][col & 1] >> 9;
543 BAYER(row,col) = val;
545 canon_600_fixed_wb(1311);
548 maximum = (0x3ff - black) * 1109 >> 9;
552 int CLASS canon_s2is()
556 for (row=0; row < 100; row++) {
557 fseek (ifp, row*3340 + 3284, SEEK_SET);
558 if (getc(ifp) > 15) return 1;
564 getbits(-1) initializes the buffer
565 getbits(n) where 0 <= n <= 25 returns an n-bit integer
567 unsigned CLASS getbithuff (int nbits, ushort *huff)
569 static unsigned bitbuf=0;
570 static int vbits=0, reset=0;
574 return bitbuf = vbits = reset = 0;
575 if (nbits == 0 || vbits < 0) return 0;
576 while (!reset && vbits < nbits && (c = fgetc(ifp)) != EOF &&
577 !(reset = zero_after_ff && c == 0xff && fgetc(ifp))) {
578 bitbuf = (bitbuf << 8) + (uchar) c;
581 c = bitbuf << (32-vbits) >> (32-nbits);
583 vbits -= huff[c] >> 8;
587 if (vbits < 0) derror();
591 #define getbits(n) getbithuff(n,0)
592 #define gethuff(h) getbithuff(*h,h+1)
595 Construct a decode tree according the specification in *source.
596 The first 16 bytes specify how many codes should be 1-bit, 2-bit
597 3-bit, etc. Bytes after that are the leaf values.
599 For example, if the source is
601 { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0,
602 0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff },
620 ushort * CLASS make_decoder_ref (const uchar **source)
622 int max, len, h, i, j;
626 count = (*source += 16) - 17;
627 for (max=16; max && !count[max]; max--);
628 huff = (ushort *) calloc (1 + (1 << max), sizeof *huff);
629 merror (huff, "make_decoder()");
631 for (h=len=1; len <= max; len++)
632 for (i=0; i < count[len]; i++, ++*source)
633 for (j=0; j < 1 << (max-len); j++)
635 huff[h++] = len << 8 | **source;
639 ushort * CLASS make_decoder (const uchar *source)
641 return make_decoder_ref (&source);
644 void CLASS crw_init_tables (unsigned table, ushort *huff[2])
646 static const uchar first_tree[3][29] = {
647 { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0,
648 0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff },
649 { 0,2,2,3,1,1,1,1,2,0,0,0,0,0,0,0,
650 0x03,0x02,0x04,0x01,0x05,0x00,0x06,0x07,0x09,0x08,0x0a,0x0b,0xff },
651 { 0,0,6,3,1,1,2,0,0,0,0,0,0,0,0,0,
652 0x06,0x05,0x07,0x04,0x08,0x03,0x09,0x02,0x00,0x0a,0x01,0x0b,0xff },
654 static const uchar second_tree[3][180] = {
655 { 0,2,2,2,1,4,2,1,2,5,1,1,0,0,0,139,
656 0x03,0x04,0x02,0x05,0x01,0x06,0x07,0x08,
657 0x12,0x13,0x11,0x14,0x09,0x15,0x22,0x00,0x21,0x16,0x0a,0xf0,
658 0x23,0x17,0x24,0x31,0x32,0x18,0x19,0x33,0x25,0x41,0x34,0x42,
659 0x35,0x51,0x36,0x37,0x38,0x29,0x79,0x26,0x1a,0x39,0x56,0x57,
660 0x28,0x27,0x52,0x55,0x58,0x43,0x76,0x59,0x77,0x54,0x61,0xf9,
661 0x71,0x78,0x75,0x96,0x97,0x49,0xb7,0x53,0xd7,0x74,0xb6,0x98,
662 0x47,0x48,0x95,0x69,0x99,0x91,0xfa,0xb8,0x68,0xb5,0xb9,0xd6,
663 0xf7,0xd8,0x67,0x46,0x45,0x94,0x89,0xf8,0x81,0xd5,0xf6,0xb4,
664 0x88,0xb1,0x2a,0x44,0x72,0xd9,0x87,0x66,0xd4,0xf5,0x3a,0xa7,
665 0x73,0xa9,0xa8,0x86,0x62,0xc7,0x65,0xc8,0xc9,0xa1,0xf4,0xd1,
666 0xe9,0x5a,0x92,0x85,0xa6,0xe7,0x93,0xe8,0xc1,0xc6,0x7a,0x64,
667 0xe1,0x4a,0x6a,0xe6,0xb3,0xf1,0xd3,0xa5,0x8a,0xb2,0x9a,0xba,
668 0x84,0xa4,0x63,0xe5,0xc5,0xf3,0xd2,0xc4,0x82,0xaa,0xda,0xe4,
669 0xf2,0xca,0x83,0xa3,0xa2,0xc3,0xea,0xc2,0xe2,0xe3,0xff,0xff },
670 { 0,2,2,1,4,1,4,1,3,3,1,0,0,0,0,140,
671 0x02,0x03,0x01,0x04,0x05,0x12,0x11,0x06,
672 0x13,0x07,0x08,0x14,0x22,0x09,0x21,0x00,0x23,0x15,0x31,0x32,
673 0x0a,0x16,0xf0,0x24,0x33,0x41,0x42,0x19,0x17,0x25,0x18,0x51,
674 0x34,0x43,0x52,0x29,0x35,0x61,0x39,0x71,0x62,0x36,0x53,0x26,
675 0x38,0x1a,0x37,0x81,0x27,0x91,0x79,0x55,0x45,0x28,0x72,0x59,
676 0xa1,0xb1,0x44,0x69,0x54,0x58,0xd1,0xfa,0x57,0xe1,0xf1,0xb9,
677 0x49,0x47,0x63,0x6a,0xf9,0x56,0x46,0xa8,0x2a,0x4a,0x78,0x99,
678 0x3a,0x75,0x74,0x86,0x65,0xc1,0x76,0xb6,0x96,0xd6,0x89,0x85,
679 0xc9,0xf5,0x95,0xb4,0xc7,0xf7,0x8a,0x97,0xb8,0x73,0xb7,0xd8,
680 0xd9,0x87,0xa7,0x7a,0x48,0x82,0x84,0xea,0xf4,0xa6,0xc5,0x5a,
681 0x94,0xa4,0xc6,0x92,0xc3,0x68,0xb5,0xc8,0xe4,0xe5,0xe6,0xe9,
682 0xa2,0xa3,0xe3,0xc2,0x66,0x67,0x93,0xaa,0xd4,0xd5,0xe7,0xf8,
683 0x88,0x9a,0xd7,0x77,0xc4,0x64,0xe2,0x98,0xa5,0xca,0xda,0xe8,
684 0xf3,0xf6,0xa9,0xb2,0xb3,0xf2,0xd2,0x83,0xba,0xd3,0xff,0xff },
685 { 0,0,6,2,1,3,3,2,5,1,2,2,8,10,0,117,
686 0x04,0x05,0x03,0x06,0x02,0x07,0x01,0x08,
687 0x09,0x12,0x13,0x14,0x11,0x15,0x0a,0x16,0x17,0xf0,0x00,0x22,
688 0x21,0x18,0x23,0x19,0x24,0x32,0x31,0x25,0x33,0x38,0x37,0x34,
689 0x35,0x36,0x39,0x79,0x57,0x58,0x59,0x28,0x56,0x78,0x27,0x41,
690 0x29,0x77,0x26,0x42,0x76,0x99,0x1a,0x55,0x98,0x97,0xf9,0x48,
691 0x54,0x96,0x89,0x47,0xb7,0x49,0xfa,0x75,0x68,0xb6,0x67,0x69,
692 0xb9,0xb8,0xd8,0x52,0xd7,0x88,0xb5,0x74,0x51,0x46,0xd9,0xf8,
693 0x3a,0xd6,0x87,0x45,0x7a,0x95,0xd5,0xf6,0x86,0xb4,0xa9,0x94,
694 0x53,0x2a,0xa8,0x43,0xf5,0xf7,0xd4,0x66,0xa7,0x5a,0x44,0x8a,
695 0xc9,0xe8,0xc8,0xe7,0x9a,0x6a,0x73,0x4a,0x61,0xc7,0xf4,0xc6,
696 0x65,0xe9,0x72,0xe6,0x71,0x91,0x93,0xa6,0xda,0x92,0x85,0x62,
697 0xf3,0xc5,0xb2,0xa4,0x84,0xba,0x64,0xa5,0xb3,0xd2,0x81,0xe5,
698 0xd3,0xaa,0xc4,0xca,0xf2,0xb1,0xe4,0xd1,0x83,0x63,0xea,0xc3,
699 0xe2,0x82,0xf1,0xa3,0xc2,0xa1,0xc1,0xe3,0xa2,0xe1,0xff,0xff }
701 if (table > 2) table = 2;
702 huff[0] = make_decoder ( first_tree[table]);
703 huff[1] = make_decoder (second_tree[table]);
707 Return 0 if the image starts with compressed data,
708 1 if it starts with uncompressed low-order bits.
710 In Canon compressed data, 0xff is always followed by 0x00.
712 int CLASS canon_has_lowbits()
717 fseek (ifp, 0, SEEK_SET);
718 fread (test, 1, sizeof test, ifp);
719 for (i=540; i < sizeof test - 1; i++)
720 if (test[i] == 0xff) {
721 if (test[i+1]) return 1;
727 void CLASS canon_load_raw()
729 ushort *pixel, *prow, *huff[2];
730 int nblocks, lowbits, i, c, row, r, save, val;
731 int block, diffbuf[64], leaf, len, diff, carry=0, pnum=0, base[2];
733 crw_init_tables (tiff_compress, huff);
734 lowbits = canon_has_lowbits();
735 if (!lowbits) maximum = 0x3ff;
736 fseek (ifp, 540 + lowbits*raw_height*raw_width/4, SEEK_SET);
739 for (row=0; row < raw_height; row+=8) {
740 pixel = raw_image + row*raw_width;
741 nblocks = MIN (8, raw_height-row) * raw_width >> 6;
742 for (block=0; block < nblocks; block++) {
743 memset (diffbuf, 0, sizeof diffbuf);
744 for (i=0; i < 64; i++ ) {
745 leaf = gethuff(huff[i > 0]);
746 if (leaf == 0 && i) break;
747 if (leaf == 0xff) continue;
750 if (len == 0) continue;
752 if ((diff & (1 << (len-1))) == 0)
753 diff -= (1 << len) - 1;
754 if (i < 64) diffbuf[i] = diff;
758 for (i=0; i < 64; i++ ) {
759 if (pnum++ % raw_width == 0)
760 base[0] = base[1] = 512;
761 if ((pixel[(block << 6) + i] = base[i & 1] += diffbuf[i]) >> 10)
767 fseek (ifp, 26 + row*raw_width/4, SEEK_SET);
768 for (prow=pixel, i=0; i < raw_width*2; i++) {
770 for (r=0; r < 8; r+=2, prow++) {
771 val = (*prow << 2) + ((c >> r) & 3);
772 if (raw_width == 2672 && val < 512) val += 2;
776 fseek (ifp, save, SEEK_SET);
779 FORC(2) free (huff[c]);
783 Not a full implementation of Lossless JPEG, just
784 enough to decode Canon, Kodak and Adobe DNG images.
787 int bits, high, wide, clrs, sraw, psv, restart, vpred[6];
788 ushort *huff[6], *free[4], *row;
791 int CLASS ljpeg_start (struct jhead *jh, int info_only)
797 memset (jh, 0, sizeof *jh);
798 jh->restart = INT_MAX;
799 fread (data, 2, 1, ifp);
800 if (data[1] != 0xd8) return 0;
802 fread (data, 2, 2, ifp);
803 tag = data[0] << 8 | data[1];
804 len = (data[2] << 8 | data[3]) - 2;
805 if (tag <= 0xff00) return 0;
806 fread (data, 1, len, ifp);
809 jh->sraw = ((data[7] >> 4) * (data[7] & 15) - 1) & 3;
812 jh->high = data[1] << 8 | data[2];
813 jh->wide = data[3] << 8 | data[4];
814 jh->clrs = data[5] + jh->sraw;
815 if (len == 9 && !dng_version) getc(ifp);
818 if (info_only) break;
819 for (dp = data; dp < data+len && (c = *dp++) < 4; )
820 jh->free[c] = jh->huff[c] = make_decoder_ref (&dp);
823 jh->psv = data[1+data[0]*2];
824 jh->bits -= data[3+data[0]*2] & 15;
827 jh->restart = data[0] << 8 | data[1];
829 } while (tag != 0xffda);
830 if (info_only) return 1;
831 FORC(5) if (!jh->huff[c+1]) jh->huff[c+1] = jh->huff[c];
833 FORC(4) jh->huff[2+c] = jh->huff[1];
834 FORC(jh->sraw) jh->huff[1+c] = jh->huff[0];
836 jh->row = (ushort *) calloc (jh->wide*jh->clrs, 4);
837 merror (jh->row, "ljpeg_start()");
838 return zero_after_ff = 1;
841 void CLASS ljpeg_end (struct jhead *jh)
844 FORC4 if (jh->free[c]) free (jh->free[c]);
848 int CLASS ljpeg_diff (ushort *huff)
853 if (len == 16 && (!dng_version || dng_version >= 0x1010000))
856 if ((diff & (1 << (len-1))) == 0)
857 diff -= (1 << len) - 1;
861 ushort * CLASS ljpeg_row (int jrow, struct jhead *jh)
863 int col, c, diff, pred, spred=0;
864 ushort mark=0, *row[3];
866 if (jrow * jh->wide % jh->restart == 0) {
867 FORC(6) jh->vpred[c] = 1 << (jh->bits-1);
869 fseek (ifp, -2, SEEK_CUR);
870 do mark = (mark << 8) + (c = fgetc(ifp));
871 while (c != EOF && mark >> 4 != 0xffd);
875 FORC3 row[c] = jh->row + jh->wide*jh->clrs*((jrow+c) & 1);
876 for (col=0; col < jh->wide; col++)
878 diff = ljpeg_diff (jh->huff[c]);
879 if (jh->sraw && c <= jh->sraw && (col | c))
881 else if (col) pred = row[0][-jh->clrs];
882 else pred = (jh->vpred[c] += diff) - diff;
883 if (jrow && col) switch (jh->psv) {
885 case 2: pred = row[1][0]; break;
886 case 3: pred = row[1][-jh->clrs]; break;
887 case 4: pred = pred + row[1][0] - row[1][-jh->clrs]; break;
888 case 5: pred = pred + ((row[1][0] - row[1][-jh->clrs]) >> 1); break;
889 case 6: pred = row[1][0] + ((pred - row[1][-jh->clrs]) >> 1); break;
890 case 7: pred = (pred + row[1][0]) >> 1; break;
893 if ((**row = pred + diff) >> jh->bits) derror();
894 if (c <= jh->sraw) spred = **row;
900 void CLASS lossless_jpeg_load_raw()
902 int jwide, jrow, jcol, val, jidx, i, j, row=0, col=0;
906 if (!ljpeg_start (&jh, 0)) return;
907 jwide = jh.wide * jh.clrs;
909 for (jrow=0; jrow < jh.high; jrow++) {
910 rp = ljpeg_row (jrow, &jh);
912 row = jrow & 1 ? height-1-jrow/2 : jrow/2;
913 for (jcol=0; jcol < jwide; jcol++) {
916 jidx = jrow*jwide + jcol;
917 i = jidx / (cr2_slice[1]*jh.high);
918 if ((j = i >= cr2_slice[0]))
920 jidx -= i * (cr2_slice[1]*jh.high);
921 row = jidx / cr2_slice[1+j];
922 col = jidx % cr2_slice[1+j] + i*cr2_slice[1];
924 if (raw_width == 3984 && (col -= 2) < 0)
925 col += (row--,raw_width);
926 if (row >= 0) RAW(row,col) = val;
927 if (++col >= raw_width)
934 void CLASS canon_sraw_load_raw()
937 short *rp=0, (*ip)[4];
938 int jwide, slice, scol, ecol, row, col, jrow=0, jcol=0, pix[3], c;
939 int v[3]={0,0,0}, ver, hue;
942 if (!ljpeg_start (&jh, 0)) return;
943 jwide = (jh.wide >>= 1) * jh.clrs;
945 for (ecol=slice=0; slice <= cr2_slice[0]; slice++) {
947 ecol += cr2_slice[1] * 2 / jh.clrs;
948 if (!cr2_slice[0] || ecol > raw_width-1) ecol = raw_width & -2;
949 for (row=0; row < height; row += (jh.clrs >> 1) - 1) {
950 ip = (short (*)[4]) image + row*width;
951 for (col=scol; col < ecol; col+=2, jcol+=jh.clrs) {
952 if ((jcol %= jwide) == 0)
953 rp = (short *) ljpeg_row (jrow++, &jh);
954 if (col >= width) continue;
956 ip[col + (c >> 1)*width + (c & 1)][0] = rp[jcol+c];
957 ip[col][1] = rp[jcol+jh.clrs-2] - 16384;
958 ip[col][2] = rp[jcol+jh.clrs-1] - 16384;
962 for (cp=model2; *cp && !isdigit(*cp); cp++);
963 sscanf (cp, "%d.%d.%d", v, v+1, v+2);
964 ver = (v[0]*1000 + v[1])*1000 + v[2];
965 hue = (jh.sraw+1) << 2;
966 if (unique_id >= 0x80000281 || (unique_id == 0x80000218 && ver > 1000006))
968 ip = (short (*)[4]) image;
970 for (row=0; row < height; row++, ip+=width) {
971 if (row & (jh.sraw >> 1)) {
972 for (col=0; col < width; col+=2)
973 for (c=1; c < 3; c++)
975 ip[col][c] = ip[col-width][c];
976 else ip[col][c] = (ip[col-width][c] + ip[col+width][c] + 1) >> 1;
978 for (col=1; col < width; col+=2)
979 for (c=1; c < 3; c++)
981 ip[col][c] = ip[col-1][c];
982 else ip[col][c] = (ip[col-1][c] + ip[col+1][c] + 1) >> 1;
984 for ( ; rp < ip[0]; rp+=4) {
985 if (unique_id == 0x80000218 ||
986 unique_id == 0x80000250 ||
987 unique_id == 0x80000261 ||
988 unique_id == 0x80000281 ||
989 unique_id == 0x80000287) {
990 rp[1] = (rp[1] << 2) + hue;
991 rp[2] = (rp[2] << 2) + hue;
992 pix[0] = rp[0] + (( 50*rp[1] + 22929*rp[2]) >> 14);
993 pix[1] = rp[0] + ((-5640*rp[1] - 11751*rp[2]) >> 14);
994 pix[2] = rp[0] + ((29040*rp[1] - 101*rp[2]) >> 14);
996 if (unique_id < 0x80000218) rp[0] -= 512;
997 pix[0] = rp[0] + rp[2];
998 pix[2] = rp[0] + rp[1];
999 pix[1] = rp[0] + ((-778*rp[1] - (rp[2] << 11)) >> 12);
1001 FORC3 rp[c] = CLIP(pix[c] * sraw_mul[c] >> 10);
1007 void CLASS adobe_copy_pixel (unsigned row, unsigned col, ushort **rp)
1011 if (is_raw == 2 && shot_select) (*rp)++;
1013 if (row < raw_height && col < raw_width)
1014 RAW(row,col) = curve[**rp];
1017 if (row < height && col < width)
1019 image[row*width+col][c] = curve[(*rp)[c]];
1020 *rp += tiff_samples;
1022 if (is_raw == 2 && shot_select) (*rp)--;
1025 void CLASS lossless_dng_load_raw()
1027 unsigned save, trow=0, tcol=0, jwide, jrow, jcol, row, col;
1031 while (trow < raw_height) {
1033 if (tile_length < INT_MAX)
1034 fseek (ifp, get4(), SEEK_SET);
1035 if (!ljpeg_start (&jh, 0)) break;
1037 if (filters) jwide *= jh.clrs;
1039 for (row=col=jrow=0; jrow < jh.high; jrow++) {
1040 rp = ljpeg_row (jrow, &jh);
1041 for (jcol=0; jcol < jwide; jcol++) {
1042 adobe_copy_pixel (trow+row, tcol+col, &rp);
1043 if (++col >= tile_width || col >= raw_width)
1044 row += 1 + (col = 0);
1047 fseek (ifp, save+4, SEEK_SET);
1048 if ((tcol += tile_width) >= raw_width)
1049 trow += tile_length + (tcol = 0);
1054 void CLASS packed_dng_load_raw()
1059 pixel = (ushort *) calloc (raw_width * tiff_samples, sizeof *pixel);
1060 merror (pixel, "packed_dng_load_raw()");
1061 for (row=0; row < raw_height; row++) {
1063 read_shorts (pixel, raw_width * tiff_samples);
1066 for (col=0; col < raw_width * tiff_samples; col++)
1067 pixel[col] = getbits(tiff_bps);
1069 for (rp=pixel, col=0; col < raw_width; col++)
1070 adobe_copy_pixel (row, col, &rp);
1075 void CLASS pentax_load_raw()
1077 ushort bit[2][15], huff[4097];
1078 int dep, row, col, diff, c, i;
1079 ushort vpred[2][2] = {{0,0},{0,0}}, hpred[2];
1081 fseek (ifp, meta_offset, SEEK_SET);
1082 dep = (get2() + 12) & 15;
1083 fseek (ifp, 12, SEEK_CUR);
1084 FORC(dep) bit[0][c] = get2();
1085 FORC(dep) bit[1][c] = fgetc(ifp);
1087 for (i=bit[0][c]; i <= ((bit[0][c]+(4096 >> bit[1][c])-1) & 4095); )
1088 huff[++i] = bit[1][c] << 8 | c;
1090 fseek (ifp, data_offset, SEEK_SET);
1092 for (row=0; row < raw_height; row++)
1093 for (col=0; col < raw_width; col++) {
1094 diff = ljpeg_diff (huff);
1095 if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
1096 else hpred[col & 1] += diff;
1097 RAW(row,col) = hpred[col & 1];
1098 if (hpred[col & 1] >> tiff_bps) derror();
1102 void CLASS nikon_load_raw()
1104 static const uchar nikon_tree[][32] = {
1105 { 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0, /* 12-bit lossy */
1106 5,4,3,6,2,7,1,0,8,9,11,10,12 },
1107 { 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0, /* 12-bit lossy after split */
1108 0x39,0x5a,0x38,0x27,0x16,5,4,3,2,1,0,11,12,12 },
1109 { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0, /* 12-bit lossless */
1110 5,4,6,3,7,2,8,1,9,0,10,11,12 },
1111 { 0,1,4,3,1,1,1,1,1,2,0,0,0,0,0,0, /* 14-bit lossy */
1112 5,6,4,7,8,3,9,2,1,0,10,11,12,13,14 },
1113 { 0,1,5,1,1,1,1,1,1,1,2,0,0,0,0,0, /* 14-bit lossy after split */
1114 8,0x5c,0x4b,0x3a,0x29,7,6,5,4,3,2,1,0,13,14 },
1115 { 0,1,4,2,2,3,1,2,0,0,0,0,0,0,0,0, /* 14-bit lossless */
1116 7,6,8,5,9,4,10,3,11,12,2,0,1,13,14 } };
1117 ushort *huff, ver0, ver1, vpred[2][2], hpred[2], csize;
1118 int i, min, max, step=0, tree=0, split=0, row, col, len, shl, diff;
1120 fseek (ifp, meta_offset, SEEK_SET);
1123 if (ver0 == 0x49 || ver1 == 0x58)
1124 fseek (ifp, 2110, SEEK_CUR);
1125 if (ver0 == 0x46) tree = 2;
1126 if (tiff_bps == 14) tree += 3;
1127 read_shorts (vpred[0], 4);
1128 max = 1 << tiff_bps & 0x7fff;
1129 if ((csize = get2()) > 1)
1130 step = max / (csize-1);
1131 if (ver0 == 0x44 && ver1 == 0x20 && step > 0) {
1132 for (i=0; i < csize; i++)
1133 curve[i*step] = get2();
1134 for (i=0; i < max; i++)
1135 curve[i] = ( curve[i-i%step]*(step-i%step) +
1136 curve[i-i%step+step]*(i%step) ) / step;
1137 fseek (ifp, meta_offset+562, SEEK_SET);
1139 } else if (ver0 != 0x46 && csize <= 0x4001)
1140 read_shorts (curve, max=csize);
1141 while (curve[max-2] == curve[max-1]) max--;
1142 huff = make_decoder (nikon_tree[tree]);
1143 fseek (ifp, data_offset, SEEK_SET);
1145 for (min=row=0; row < height; row++) {
1146 if (split && row == split) {
1148 huff = make_decoder (nikon_tree[tree+1]);
1149 max += (min = 16) << 1;
1151 for (col=0; col < raw_width; col++) {
1155 diff = ((getbits(len-shl) << 1) + 1) << shl >> 1;
1156 if ((diff & (1 << (len-1))) == 0)
1157 diff -= (1 << len) - !shl;
1158 if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
1159 else hpred[col & 1] += diff;
1160 if ((ushort)(hpred[col & 1] + min) >= max) derror();
1161 RAW(row,col) = curve[LIM((short)hpred[col & 1],0,0x3fff)];
1168 Returns 1 for a Coolpix 995, 0 for anything else.
1170 int CLASS nikon_e995()
1173 const uchar often[] = { 0x00, 0x55, 0xaa, 0xff };
1175 memset (histo, 0, sizeof histo);
1176 fseek (ifp, -2000, SEEK_END);
1177 for (i=0; i < 2000; i++)
1178 histo[fgetc(ifp)]++;
1179 for (i=0; i < 4; i++)
1180 if (histo[often[i]] < 200)
1186 Returns 1 for a Coolpix 2100, 0 for anything else.
1188 int CLASS nikon_e2100()
1193 fseek (ifp, 0, SEEK_SET);
1194 for (i=0; i < 1024; i++) {
1195 fread (t, 1, 12, ifp);
1196 if (((t[2] & t[4] & t[7] & t[9]) >> 4
1197 & t[1] & t[6] & t[8] & t[11] & 3) != 3)
1203 void CLASS nikon_3700()
1207 static const struct {
1209 char make[12], model[15];
1211 { 0x00, "PENTAX", "Optio 33WR" },
1212 { 0x03, "NIKON", "E3200" },
1213 { 0x32, "NIKON", "E3700" },
1214 { 0x33, "OLYMPUS", "C740UZ" } };
1216 fseek (ifp, 3072, SEEK_SET);
1217 fread (dp, 1, 24, ifp);
1218 bits = (dp[8] & 3) << 4 | (dp[20] & 3);
1219 for (i=0; i < sizeof table / sizeof *table; i++)
1220 if (bits == table[i].bits) {
1221 strcpy (make, table[i].make );
1222 strcpy (model, table[i].model);
1227 Separates a Minolta DiMAGE Z2 from a Nikon E4300.
1229 int CLASS minolta_z2()
1234 fseek (ifp, -sizeof tail, SEEK_END);
1235 fread (tail, 1, sizeof tail, ifp);
1236 for (nz=i=0; i < sizeof tail; i++)
1241 void CLASS jpeg_thumb();
1243 void CLASS ppm_thumb()
1246 thumb_length = thumb_width*thumb_height*3;
1247 thumb = (char *) malloc (thumb_length);
1248 merror (thumb, "ppm_thumb()");
1249 fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
1250 fread (thumb, 1, thumb_length, ifp);
1251 fwrite (thumb, 1, thumb_length, ofp);
1255 void CLASS ppm16_thumb()
1259 thumb_length = thumb_width*thumb_height*3;
1260 thumb = (char *) calloc (thumb_length,2);
1261 merror (thumb, "ppm16_thumb()");
1262 read_shorts ((ushort *) thumb, thumb_length);
1263 for (i=0; i < thumb_length; i++)
1264 thumb[i] = ((ushort *) thumb)[i] >> 8;
1265 fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
1266 fwrite (thumb, 1, thumb_length, ofp);
1270 void CLASS layer_thumb()
1273 char *thumb, map[][4] = { "012","102" };
1275 colors = thumb_misc >> 5 & 7;
1276 thumb_length = thumb_width*thumb_height;
1277 thumb = (char *) calloc (colors, thumb_length);
1278 merror (thumb, "layer_thumb()");
1279 fprintf (ofp, "P%d\n%d %d\n255\n",
1280 5 + (colors >> 1), thumb_width, thumb_height);
1281 fread (thumb, thumb_length, colors, ifp);
1282 for (i=0; i < thumb_length; i++)
1283 FORCC putc (thumb[i+thumb_length*(map[thumb_misc >> 8][c]-'0')], ofp);
1287 void CLASS rollei_thumb()
1292 thumb_length = thumb_width * thumb_height;
1293 thumb = (ushort *) calloc (thumb_length, 2);
1294 merror (thumb, "rollei_thumb()");
1295 fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
1296 read_shorts (thumb, thumb_length);
1297 for (i=0; i < thumb_length; i++) {
1298 putc (thumb[i] << 3, ofp);
1299 putc (thumb[i] >> 5 << 2, ofp);
1300 putc (thumb[i] >> 11 << 3, ofp);
1305 void CLASS rollei_load_raw()
1308 unsigned iten=0, isix, i, buffer=0, todo[16];
1310 isix = raw_width * raw_height * 5 / 8;
1311 while (fread (pixel, 1, 10, ifp) == 10) {
1312 for (i=0; i < 10; i+=2) {
1314 todo[i+1] = pixel[i] << 8 | pixel[i+1];
1315 buffer = pixel[i] >> 2 | buffer << 6;
1317 for ( ; i < 16; i+=2) {
1319 todo[i+1] = buffer >> (14-i)*5;
1321 for (i=0; i < 16; i+=2)
1322 raw_image[todo[i]] = (todo[i+1] & 0x3ff);
1327 int CLASS raw (unsigned row, unsigned col)
1329 return (row < raw_height && col < raw_width) ? RAW(row,col) : 0;
1332 void CLASS phase_one_flat_field (int is_float, int nc)
1335 unsigned wide, y, x, c, rend, cend, row, col;
1336 float *mrow, num, mult[4];
1338 read_shorts (head, 8);
1339 wide = head[2] / head[4];
1340 mrow = (float *) calloc (nc*wide, sizeof *mrow);
1341 merror (mrow, "phase_one_flat_field()");
1342 for (y=0; y < head[3] / head[5]; y++) {
1343 for (x=0; x < wide; x++)
1344 for (c=0; c < nc; c+=2) {
1345 num = is_float ? getreal(11) : get2()/32768.0;
1346 if (y==0) mrow[c*wide+x] = num;
1347 else mrow[(c+1)*wide+x] = (num - mrow[c*wide+x]) / head[5];
1350 rend = head[1] + y*head[5];
1351 for (row = rend-head[5]; row < raw_height && row < rend; row++) {
1352 for (x=1; x < wide; x++) {
1353 for (c=0; c < nc; c+=2) {
1354 mult[c] = mrow[c*wide+x-1];
1355 mult[c+1] = (mrow[c*wide+x] - mult[c]) / head[4];
1357 cend = head[0] + x*head[4];
1358 for (col = cend-head[4]; col < raw_width && col < cend; col++) {
1359 c = nc > 2 ? FC(row-top_margin,col-left_margin) : 0;
1361 c = RAW(row,col) * mult[c];
1362 RAW(row,col) = LIM(c,0,65535);
1364 for (c=0; c < nc; c+=2)
1365 mult[c] += mult[c+1];
1368 for (x=0; x < wide; x++)
1369 for (c=0; c < nc; c+=2)
1370 mrow[c*wide+x] += mrow[(c+1)*wide+x];
1376 void CLASS phase_one_correct()
1378 unsigned entries, tag, data, save, col, row, type;
1379 int len, i, j, k, cip, val[4], dev[4], sum, max;
1380 int head[9], diff, mindiff=INT_MAX, off_412=0;
1381 static const signed char dir[12][2] =
1382 { {-1,-1}, {-1,1}, {1,-1}, {1,1}, {-2,0}, {0,-2}, {0,2}, {2,0},
1383 {-2,-2}, {-2,2}, {2,-2}, {2,2} };
1384 float poly[8], num, cfrac, frac, mult[2], *yval[2];
1387 if (half_size || !meta_length) return;
1388 if (verbose) fprintf (stderr,_("Phase One correction...\n"));
1389 fseek (ifp, meta_offset, SEEK_SET);
1391 fseek (ifp, 6, SEEK_CUR);
1392 fseek (ifp, meta_offset+get4(), SEEK_SET);
1393 entries = get4(); get4();
1399 fseek (ifp, meta_offset+data, SEEK_SET);
1400 if (tag == 0x419) { /* Polynomial curve */
1401 for (get4(), i=0; i < 8; i++)
1402 poly[i] = getreal(11);
1403 poly[3] += (ph1.tag_210 - poly[7]) * poly[6] + 1;
1404 for (i=0; i < 0x10000; i++) {
1405 num = (poly[5]*i + poly[3])*i + poly[1];
1406 curve[i] = LIM(num,0,65535);
1407 } goto apply; /* apply to right half */
1408 } else if (tag == 0x41a) { /* Polynomial curve */
1409 for (i=0; i < 4; i++)
1410 poly[i] = getreal(11);
1411 for (i=0; i < 0x10000; i++) {
1412 for (num=0, j=4; j--; )
1413 num = num * i + poly[j];
1414 curve[i] = LIM(num+i,0,65535);
1415 } apply: /* apply to whole image */
1416 for (row=0; row < raw_height; row++)
1417 for (col = (tag & 1)*ph1.split_col; col < raw_width; col++)
1418 RAW(row,col) = curve[RAW(row,col)];
1419 } else if (tag == 0x400) { /* Sensor defects */
1420 while ((len -= 8) >= 0) {
1423 type = get2(); get2();
1424 if (col >= raw_width) continue;
1425 if (type == 131) /* Bad column */
1426 for (row=0; row < raw_height; row++)
1427 if (FC(row-top_margin,col-left_margin) == 1) {
1428 for (sum=i=0; i < 4; i++)
1429 sum += val[i] = raw (row+dir[i][0], col+dir[i][1]);
1430 for (max=i=0; i < 4; i++) {
1431 dev[i] = abs((val[i] << 2) - sum);
1432 if (dev[max] < dev[i]) max = i;
1434 RAW(row,col) = (sum - val[max])/3.0 + 0.5;
1436 for (sum=0, i=8; i < 12; i++)
1437 sum += raw (row+dir[i][0], col+dir[i][1]);
1438 RAW(row,col) = 0.5 + sum * 0.0732233 +
1439 (raw(row,col-2) + raw(row,col+2)) * 0.3535534;
1441 else if (type == 129) { /* Bad pixel */
1442 if (row >= raw_height) continue;
1443 j = (FC(row-top_margin,col-left_margin) != 1) * 4;
1444 for (sum=0, i=j; i < j+8; i++)
1445 sum += raw (row+dir[i][0], col+dir[i][1]);
1446 RAW(row,col) = (sum + 4) >> 3;
1449 } else if (tag == 0x401) { /* All-color flat fields */
1450 phase_one_flat_field (1, 2);
1451 } else if (tag == 0x416 || tag == 0x410) {
1452 phase_one_flat_field (0, 2);
1453 } else if (tag == 0x40b) { /* Red+blue flat field */
1454 phase_one_flat_field (0, 4);
1455 } else if (tag == 0x412) {
1456 fseek (ifp, 36, SEEK_CUR);
1457 diff = abs (get2() - ph1.tag_21a);
1458 if (mindiff > diff) {
1460 off_412 = ftell(ifp) - 38;
1463 fseek (ifp, save, SEEK_SET);
1466 fseek (ifp, off_412, SEEK_SET);
1467 for (i=0; i < 9; i++) head[i] = get4() & 0x7fff;
1468 yval[0] = (float *) calloc (head[1]*head[3] + head[2]*head[4], 6);
1469 merror (yval[0], "phase_one_correct()");
1470 yval[1] = (float *) (yval[0] + head[1]*head[3]);
1471 xval[0] = (ushort *) (yval[1] + head[2]*head[4]);
1472 xval[1] = (ushort *) (xval[0] + head[1]*head[3]);
1474 for (i=0; i < 2; i++)
1475 for (j=0; j < head[i+1]*head[i+3]; j++)
1476 yval[i][j] = getreal(11);
1477 for (i=0; i < 2; i++)
1478 for (j=0; j < head[i+1]*head[i+3]; j++)
1479 xval[i][j] = get2();
1480 for (row=0; row < raw_height; row++)
1481 for (col=0; col < raw_width; col++) {
1482 cfrac = (float) col * head[3] / raw_width;
1483 cfrac -= cip = cfrac;
1484 num = RAW(row,col) * 0.5;
1485 for (i=cip; i < cip+2; i++) {
1486 for (k=j=0; j < head[1]; j++)
1487 if (num < xval[0][k = head[1]*i+j]) break;
1488 frac = (j == 0 || j == head[1]) ? 0 :
1489 (xval[0][k] - num) / (xval[0][k] - xval[0][k-1]);
1490 mult[i-cip] = yval[0][k-1] * frac + yval[0][k] * (1-frac);
1492 i = ((mult[0] * (1-cfrac) + mult[1] * cfrac) * row + num) * 2;
1493 RAW(row,col) = LIM(i,0,65535);
1499 void CLASS phase_one_load_raw()
1502 ushort akey, bkey, mask;
1504 fseek (ifp, ph1.key_off, SEEK_SET);
1507 mask = ph1.format == 1 ? 0x5555:0x1354;
1508 fseek (ifp, data_offset, SEEK_SET);
1509 read_shorts (raw_image, raw_width*raw_height);
1511 for (i=0; i < raw_width*raw_height; i+=2) {
1512 a = raw_image[i+0] ^ akey;
1513 b = raw_image[i+1] ^ bkey;
1514 raw_image[i+0] = (a & mask) | (b & ~mask);
1515 raw_image[i+1] = (b & mask) | (a & ~mask);
1519 unsigned CLASS ph1_bithuff (int nbits, ushort *huff)
1521 static UINT64 bitbuf=0;
1526 return bitbuf = vbits = 0;
1527 if (nbits == 0) return 0;
1528 if (vbits < nbits) {
1529 bitbuf = bitbuf << 32 | get4();
1532 c = bitbuf << (64-vbits) >> (64-nbits);
1534 vbits -= huff[c] >> 8;
1535 return (uchar) huff[c];
1540 #define ph1_bits(n) ph1_bithuff(n,0)
1541 #define ph1_huff(h) ph1_bithuff(*h,h+1)
1543 void CLASS phase_one_load_raw_c()
1545 static const int length[] = { 8,7,6,9,11,10,5,12,14,13 };
1546 int *offset, len[2], pred[2], row, col, i, j;
1550 pixel = (ushort *) calloc (raw_width + raw_height*4, 2);
1551 merror (pixel, "phase_one_load_raw_c()");
1552 offset = (int *) (pixel + raw_width);
1553 fseek (ifp, strip_offset, SEEK_SET);
1554 for (row=0; row < raw_height; row++)
1555 offset[row] = get4();
1556 black = (short (*)[2]) offset + raw_height;
1557 fseek (ifp, ph1.black_off, SEEK_SET);
1559 read_shorts ((ushort *) black[0], raw_height*2);
1560 for (i=0; i < 256; i++)
1561 curve[i] = i*i / 3.969 + 0.5;
1562 for (row=0; row < raw_height; row++) {
1563 fseek (ifp, data_offset + offset[row], SEEK_SET);
1565 pred[0] = pred[1] = 0;
1566 for (col=0; col < raw_width; col++) {
1567 if (col >= (raw_width & -8))
1568 len[0] = len[1] = 14;
1569 else if ((col & 7) == 0)
1570 for (i=0; i < 2; i++) {
1571 for (j=0; j < 5 && !ph1_bits(1); j++);
1572 if (j--) len[i] = length[j*2 + ph1_bits(1)];
1574 if ((i = len[col & 1]) == 14)
1575 pixel[col] = pred[col & 1] = ph1_bits(16);
1577 pixel[col] = pred[col & 1] += ph1_bits(i) + 1 - (1 << (i - 1));
1578 if (pred[col & 1] >> 16) derror();
1579 if (ph1.format == 5 && pixel[col] < 256)
1580 pixel[col] = curve[pixel[col]];
1582 for (col=0; col < raw_width; col++) {
1583 i = (pixel[col] << 2) - ph1.black + black[row][col >= ph1.split_col];
1584 if (i > 0) RAW(row,col) = i;
1588 maximum = 0xfffc - ph1.black;
1591 void CLASS hasselblad_load_raw()
1594 int row, col, pred[2], len[2], diff, c;
1596 if (!ljpeg_start (&jh, 0)) return;
1599 for (row=0; row < raw_height; row++) {
1600 pred[0] = pred[1] = 0x8000 + load_flags;
1601 for (col=0; col < raw_width; col+=2) {
1602 FORC(2) len[c] = ph1_huff(jh.huff[0]);
1604 diff = ph1_bits(len[c]);
1605 if ((diff & (1 << (len[c]-1))) == 0)
1606 diff -= (1 << len[c]) - 1;
1607 if (diff == 65535) diff = -32768;
1608 RAW(row,col+c) = pred[c] += diff;
1616 void CLASS leaf_hdr_load_raw()
1619 unsigned tile=0, r, c, row, col;
1622 pixel = (ushort *) calloc (raw_width, sizeof *pixel);
1623 merror (pixel, "leaf_hdr_load_raw()");
1626 for (r=0; r < raw_height; r++) {
1627 if (r % tile_length == 0) {
1628 fseek (ifp, data_offset + 4*tile++, SEEK_SET);
1629 fseek (ifp, get4(), SEEK_SET);
1631 if (filters && c != shot_select) continue;
1632 if (filters) pixel = raw_image + r*raw_width;
1633 read_shorts (pixel, raw_width);
1634 if (!filters && (row = r - top_margin) < height)
1635 for (col=0; col < width; col++)
1636 image[row*width+col][c] = pixel[col+left_margin];
1645 void CLASS unpacked_load_raw()
1647 int row, col, bits=0;
1649 while (1 << ++bits < maximum);
1650 read_shorts (raw_image, raw_width*raw_height);
1651 for (row=0; row < raw_height; row++)
1652 for (col=0; col < raw_width; col++)
1653 if ((RAW(row,col) >>= load_flags) >> bits
1654 && (unsigned) (row-top_margin) < height
1655 && (unsigned) (col-left_margin) < width) derror();
1658 void CLASS sinar_4shot_load_raw()
1661 unsigned shot, row, col, r, c;
1663 if ((shot = shot_select) || half_size) {
1665 if (shot > 3) shot = 3;
1666 fseek (ifp, data_offset + shot*4, SEEK_SET);
1667 fseek (ifp, get4(), SEEK_SET);
1668 unpacked_load_raw();
1674 image = (ushort (*)[4])
1675 calloc ((iheight=height)*(iwidth=width), sizeof *image);
1676 merror (image, "sinar_4shot_load_raw()");
1677 pixel = (ushort *) calloc (raw_width, sizeof *pixel);
1678 merror (pixel, "sinar_4shot_load_raw()");
1679 for (shot=0; shot < 4; shot++) {
1680 fseek (ifp, data_offset + shot*4, SEEK_SET);
1681 fseek (ifp, get4(), SEEK_SET);
1682 for (row=0; row < raw_height; row++) {
1683 read_shorts (pixel, raw_width);
1684 if ((r = row-top_margin - (shot >> 1 & 1)) >= height) continue;
1685 for (col=0; col < raw_width; col++) {
1686 if ((c = col-left_margin - (shot & 1)) >= width) continue;
1687 image[r*width+c][FC(row,col)] = pixel[col];
1692 shrink = filters = 0;
1695 void CLASS imacon_full_load_raw()
1699 for (row=0; row < height; row++)
1700 for (col=0; col < width; col++)
1701 read_shorts (image[row*width+col], 3);
1704 void CLASS packed_load_raw()
1706 int vbits=0, bwide, pwide, rbits, bite, half, irow, row, col, val, i;
1709 if (raw_width * 8 >= width * tiff_bps) /* Is raw_width in bytes? */
1710 pwide = (bwide = raw_width) * 8 / tiff_bps;
1711 else bwide = (pwide = raw_width) * tiff_bps / 8;
1712 rbits = bwide * 8 - pwide * tiff_bps;
1713 if (load_flags & 1) bwide = bwide * 16 / 15;
1714 bite = 8 + (load_flags & 24);
1715 half = (raw_height+1) >> 1;
1716 for (irow=0; irow < raw_height; irow++) {
1718 if (load_flags & 2 &&
1719 (row = irow % half * 2 + irow / half) == 1 &&
1721 if (vbits=0, tiff_compress)
1722 fseek (ifp, data_offset - (-half*bwide & -2048), SEEK_SET);
1724 fseek (ifp, 0, SEEK_END);
1725 fseek (ifp, ftell(ifp) >> 3 << 2, SEEK_SET);
1728 for (col=0; col < pwide; col++) {
1729 for (vbits -= tiff_bps; vbits < 0; vbits += bite) {
1731 for (i=0; i < bite; i+=8)
1732 bitbuf |= (unsigned) (fgetc(ifp) << i);
1734 val = bitbuf << (64-tiff_bps-vbits) >> (64-tiff_bps);
1735 RAW(row,col ^ (load_flags >> 6)) = val;
1736 if (load_flags & 1 && (col % 10) == 9 &&
1737 fgetc(ifp) && col < width+left_margin) derror();
1743 void CLASS nokia_load_raw()
1746 int rev, dwide, row, col, c;
1748 rev = 3 * (order == 0x4949);
1749 dwide = raw_width * 5 / 4;
1750 data = (uchar *) malloc (dwide*2);
1751 merror (data, "nokia_load_raw()");
1752 for (row=0; row < raw_height; row++) {
1753 if (fread (data+dwide, 1, dwide, ifp) < dwide) derror();
1754 FORC(dwide) data[c] = data[dwide+(c ^ rev)];
1755 for (dp=data, col=0; col < raw_width; dp+=5, col+=4)
1756 FORC4 RAW(row,col+c) = (dp[c] << 2) | (dp[4] >> (c << 1) & 3);
1762 unsigned CLASS pana_bits (int nbits)
1764 static uchar buf[0x4000];
1768 if (!nbits) return vbits=0;
1770 fread (buf+load_flags, 1, 0x4000-load_flags, ifp);
1771 fread (buf, 1, load_flags, ifp);
1773 vbits = (vbits - nbits) & 0x1ffff;
1774 byte = vbits >> 3 ^ 0x3ff0;
1775 return (buf[byte] | buf[byte+1] << 8) >> (vbits & 7) & ~(-1 << nbits);
1778 void CLASS panasonic_load_raw()
1780 int row, col, i, j, sh=0, pred[2], nonz[2];
1783 for (row=0; row < height; row++)
1784 for (col=0; col < raw_width; col++) {
1785 if ((i = col % 14) == 0)
1786 pred[0] = pred[1] = nonz[0] = nonz[1] = 0;
1787 if (i % 3 == 2) sh = 4 >> (3 - pana_bits(2));
1789 if ((j = pana_bits(8))) {
1790 if ((pred[i & 1] -= 0x80 << sh) < 0 || sh == 4)
1791 pred[i & 1] &= ~(-1 << sh);
1792 pred[i & 1] += j << sh;
1794 } else if ((nonz[i & 1] = pana_bits(8)) || i > 11)
1795 pred[i & 1] = nonz[i & 1] << 4 | pana_bits(4);
1796 if ((RAW(row,col) = pred[col & 1]) > 4098 && col < width) derror();
1800 void CLASS olympus_load_raw()
1803 int row, col, nbits, sign, low, high, i, c, w, n, nw;
1804 int acarry[2][3], *carry, pred, diff;
1808 FORC(2048 >> i) huff[++n] = (i+1) << 8 | i;
1809 fseek (ifp, 7, SEEK_CUR);
1811 for (row=0; row < height; row++) {
1812 memset (acarry, 0, sizeof acarry);
1813 for (col=0; col < raw_width; col++) {
1814 carry = acarry[col & 1];
1815 i = 2 * (carry[2] < 3);
1816 for (nbits=2+i; (ushort) carry[0] >> (nbits+i); nbits++);
1817 low = (sign = getbits(3)) & 3;
1818 sign = sign << 29 >> 31;
1819 if ((high = getbithuff(12,huff)) == 12)
1820 high = getbits(16-nbits) >> 1;
1821 carry[0] = (high << nbits) | getbits(nbits);
1822 diff = (carry[0] ^ sign) + carry[1];
1823 carry[1] = (diff*3 + carry[1]) >> 5;
1824 carry[2] = carry[0] > 16 ? 0 : carry[2]+1;
1825 if (col >= width) continue;
1826 if (row < 2 && col < 2) pred = 0;
1827 else if (row < 2) pred = RAW(row,col-2);
1828 else if (col < 2) pred = RAW(row-2,col);
1832 nw = RAW(row-2,col-2);
1833 if ((w < nw && nw < n) || (n < nw && nw < w)) {
1834 if (ABS(w-nw) > 32 || ABS(n-nw) > 32)
1836 else pred = (w + n) >> 1;
1837 } else pred = ABS(w-nw) > ABS(n-nw) ? w : n;
1839 if ((RAW(row,col) = pred + ((diff << 2) | low)) >> 12) derror();
1844 void CLASS minolta_rd175_load_raw()
1847 unsigned irow, box, row, col;
1849 for (irow=0; irow < 1481; irow++) {
1850 if (fread (pixel, 1, 768, ifp) < 768) derror();
1852 row = irow % 82 * 12 + ((box < 12) ? box | 1 : (box-12)*2);
1854 case 1477: case 1479: continue;
1855 case 1476: row = 984; break;
1856 case 1480: row = 985; break;
1857 case 1478: row = 985; box = 1;
1859 if ((box < 12) && (box & 1)) {
1860 for (col=0; col < 1533; col++, row ^= 1)
1861 if (col != 1) RAW(row,col) = (col+1) & 2 ?
1862 pixel[col/2-1] + pixel[col/2+1] : pixel[col/2] << 1;
1863 RAW(row,1) = pixel[1] << 1;
1864 RAW(row,1533) = pixel[765] << 1;
1866 for (col=row & 1; col < 1534; col+=2)
1867 RAW(row,col) = pixel[col/2] << 1;
1869 maximum = 0xff << 1;
1872 void CLASS quicktake_100_load_raw()
1874 uchar pixel[484][644];
1875 static const short gstep[16] =
1876 { -89,-60,-44,-32,-22,-15,-8,-2,2,8,15,22,32,44,60,89 };
1877 static const short rstep[6][4] =
1878 { { -3,-1,1,3 }, { -5,-1,1,5 }, { -8,-2,2,8 },
1879 { -13,-3,3,13 }, { -19,-4,4,19 }, { -28,-6,6,28 } };
1880 static const short curve[256] =
1881 { 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,
1882 28,29,30,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,53,
1883 54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,74,75,76,77,78,
1884 79,80,81,82,83,84,86,88,90,92,94,97,99,101,103,105,107,110,112,114,116,
1885 118,120,123,125,127,129,131,134,136,138,140,142,144,147,149,151,153,155,
1886 158,160,162,164,166,168,171,173,175,177,179,181,184,186,188,190,192,195,
1887 197,199,201,203,205,208,210,212,214,216,218,221,223,226,230,235,239,244,
1888 248,252,257,261,265,270,274,278,283,287,291,296,300,305,309,313,318,322,
1889 326,331,335,339,344,348,352,357,361,365,370,374,379,383,387,392,396,400,
1890 405,409,413,418,422,426,431,435,440,444,448,453,457,461,466,470,474,479,
1891 483,487,492,496,500,508,519,531,542,553,564,575,587,598,609,620,631,643,
1892 654,665,676,687,698,710,721,732,743,754,766,777,788,799,810,822,833,844,
1893 855,866,878,889,900,911,922,933,945,956,967,978,989,1001,1012,1023 };
1894 int rb, row, col, sharp, val=0;
1897 memset (pixel, 0x80, sizeof pixel);
1898 for (row=2; row < height+2; row++) {
1899 for (col=2+(row & 1); col < width+2; col+=2) {
1900 val = ((pixel[row-1][col-1] + 2*pixel[row-1][col+1] +
1901 pixel[row][col-2]) >> 2) + gstep[getbits(4)];
1902 pixel[row][col] = val = LIM(val,0,255);
1904 pixel[row][col-2] = pixel[row+1][~row & 1] = val;
1906 pixel[row-1][col+1] = pixel[row-1][col+3] = val;
1908 pixel[row][col] = val;
1910 for (rb=0; rb < 2; rb++)
1911 for (row=2+rb; row < height+2; row+=2)
1912 for (col=3-(row & 1); col < width+2; col+=2) {
1913 if (row < 4 || col < 4) sharp = 2;
1915 val = ABS(pixel[row-2][col] - pixel[row][col-2])
1916 + ABS(pixel[row-2][col] - pixel[row-2][col-2])
1917 + ABS(pixel[row][col-2] - pixel[row-2][col-2]);
1918 sharp = val < 4 ? 0 : val < 8 ? 1 : val < 16 ? 2 :
1919 val < 32 ? 3 : val < 48 ? 4 : 5;
1921 val = ((pixel[row-2][col] + pixel[row][col-2]) >> 1)
1922 + rstep[sharp][getbits(2)];
1923 pixel[row][col] = val = LIM(val,0,255);
1924 if (row < 4) pixel[row-2][col+2] = val;
1925 if (col < 4) pixel[row+2][col-2] = val;
1927 for (row=2; row < height+2; row++)
1928 for (col=3-(row & 1); col < width+2; col+=2) {
1929 val = ((pixel[row][col-1] + (pixel[row][col] << 2) +
1930 pixel[row][col+1]) >> 1) - 0x100;
1931 pixel[row][col] = LIM(val,0,255);
1933 for (row=0; row < height; row++)
1934 for (col=0; col < width; col++)
1935 RAW(row,col) = curve[pixel[row+2][col+2]];
1939 #define radc_token(tree) ((signed char) getbithuff(8,huff[tree]))
1941 #define FORYX for (y=1; y < 3; y++) for (x=col+1; x >= col; x--)
1943 #define PREDICTOR (c ? (buf[c][y-1][x] + buf[c][y][x+1]) / 2 \
1944 : (buf[c][y-1][x+1] + 2*buf[c][y-1][x] + buf[c][y][x+1]) / 4)
1946 void CLASS kodak_radc_load_raw()
1948 static const char src[] = {
1949 1,1, 2,3, 3,4, 4,2, 5,7, 6,5, 7,6, 7,8,
1950 1,0, 2,1, 3,3, 4,4, 5,2, 6,7, 7,6, 8,5, 8,8,
1951 2,1, 2,3, 3,0, 3,2, 3,4, 4,6, 5,5, 6,7, 6,8,
1952 2,0, 2,1, 2,3, 3,2, 4,4, 5,6, 6,7, 7,5, 7,8,
1953 2,1, 2,4, 3,0, 3,2, 3,3, 4,7, 5,5, 6,6, 6,8,
1954 2,3, 3,1, 3,2, 3,4, 3,5, 3,6, 4,7, 5,0, 5,8,
1955 2,3, 2,6, 3,0, 3,1, 4,4, 4,5, 4,7, 5,2, 5,8,
1956 2,4, 2,7, 3,3, 3,6, 4,1, 4,2, 4,5, 5,0, 5,8,
1957 2,6, 3,1, 3,3, 3,5, 3,7, 3,8, 4,0, 5,2, 5,4,
1958 2,0, 2,1, 3,2, 3,3, 4,4, 4,5, 5,6, 5,7, 4,8,
1961 2,-17, 2,-5, 2,5, 2,17,
1962 2,-7, 2,2, 2,9, 2,18,
1963 2,-18, 2,-9, 2,-2, 2,7,
1964 2,-28, 2,28, 3,-49, 3,-9, 3,9, 4,49, 5,-79, 5,79,
1965 2,-1, 2,13, 2,26, 3,39, 4,-16, 5,55, 6,-37, 6,76,
1966 2,-26, 2,-13, 2,1, 3,-39, 4,16, 5,-55, 6,-76, 6,37
1968 ushort huff[19][256];
1969 int row, col, tree, nreps, rep, step, i, c, s, r, x, y, val;
1970 short last[3] = { 16,16,16 }, mul[3], buf[3][3][386], *bp;
1971 static const ushort pt[] =
1972 { 0,0, 1280,1344, 2320,3616, 3328,8000, 4095,16383, 65535,16383 };
1974 for (i=2; i < 12; i+=2)
1975 for (c=pt[i-2]; c <= pt[i]; c++)
1977 (c-pt[i-2]) / (pt[i]-pt[i-2]) * (pt[i+1]-pt[i-1]) + pt[i-1] + 0.5;
1978 for (s=i=0; i < sizeof src; i+=2)
1980 huff[0][s++] = src[i] << 8 | (uchar) src[i+1];
1981 s = kodak_cbpp == 243 ? 2 : 3;
1982 FORC(256) huff[18][c] = (8-s) << 8 | c >> s << s | 1 << (s-1);
1984 for ( bp=&buf[0][0][0],i=sizeof(buf)/sizeof(*bp); --i>=0; ++bp )
1986 for (row=0; row < height; row+=4) {
1987 FORC3 mul[c] = getbits(6);
1989 val = ((0x1000000/last[c] + 0x7ff) >> 12) * mul[c];
1990 s = val > 65564 ? 10:12;
1993 for (i=0; i < sizeof(buf[0])/sizeof(short); i++)
1994 for ( bp=&buf[c][0][0],i=sizeof(buf[0])/sizeof(*bp); --i>=0; ++bp )
1995 *bp = (*bp * val + x) >> s;
1997 for (r=0; r <= !c; r++) {
1998 buf[c][1][width/2] = buf[c][2][width/2] = mul[c] << 7;
1999 for (tree=1, col=width/2; col > 0; ) {
2000 if ((tree = radc_token(tree))) {
2003 FORYX buf[c][y][x] = (uchar) radc_token(18) * mul[c];
2005 FORYX buf[c][y][x] = radc_token(tree+10) * 16 + PREDICTOR;
2008 nreps = (col > 2) ? radc_token(9) + 1 : 1;
2009 for (rep=0; rep < 8 && rep < nreps && col > 0; rep++) {
2011 FORYX buf[c][y][x] = PREDICTOR;
2013 step = radc_token(10) << 4;
2014 FORYX buf[c][y][x] += step;
2017 } while (nreps == 9);
2019 for (y=0; y < 2; y++)
2020 for (x=0; x < width/2; x++) {
2021 val = (buf[c][y+1][x] << 4) / mul[c];
2022 if (val < 0) val = 0;
2023 if (c) RAW(row+y*2+c-1,x*2+2-c) = val;
2024 else RAW(row+r*2+y,x*2+y) = val;
2026 memcpy (buf[c][0]+!c, buf[c][2], sizeof buf[c][0]-2*!c);
2029 for (y=row; y < row+4; y++)
2030 for (x=0; x < width; x++)
2033 s = x+1 < width ? x+1 : x-1;
2034 val = (RAW(y,x)-2048)*2 + (RAW(y,r)+RAW(y,s))/2;
2035 if (val < 0) val = 0;
2039 for (i=0; i < height*width; i++)
2040 raw_image[i] = curve[raw_image[i]];
2048 void CLASS kodak_jpeg_load_raw() {}
2049 void CLASS lossy_dng_load_raw() {}
2053 fill_input_buffer (j_decompress_ptr cinfo)
2055 static uchar jpeg_buffer[4096];
2058 nbytes = fread (jpeg_buffer, 1, 4096, ifp);
2059 swab (jpeg_buffer, jpeg_buffer, nbytes);
2060 cinfo->src->next_input_byte = jpeg_buffer;
2061 cinfo->src->bytes_in_buffer = nbytes;
2065 void CLASS kodak_jpeg_load_raw()
2067 struct jpeg_decompress_struct cinfo;
2068 struct jpeg_error_mgr jerr;
2070 JSAMPLE (*pixel)[3];
2073 cinfo.err = jpeg_std_error (&jerr);
2074 jpeg_create_decompress (&cinfo);
2075 jpeg_stdio_src (&cinfo, ifp);
2076 cinfo.src->fill_input_buffer = fill_input_buffer;
2077 jpeg_read_header (&cinfo, TRUE);
2078 jpeg_start_decompress (&cinfo);
2079 if ((cinfo.output_width != width ) ||
2080 (cinfo.output_height*2 != height ) ||
2081 (cinfo.output_components != 3 )) {
2082 fprintf (stderr,_("%s: incorrect JPEG dimensions\n"), ifname);
2083 jpeg_destroy_decompress (&cinfo);
2084 longjmp (failure, 3);
2086 buf = (*cinfo.mem->alloc_sarray)
2087 ((j_common_ptr) &cinfo, JPOOL_IMAGE, width*3, 1);
2089 while (cinfo.output_scanline < cinfo.output_height) {
2090 row = cinfo.output_scanline * 2;
2091 jpeg_read_scanlines (&cinfo, buf, 1);
2092 pixel = (JSAMPLE (*)[3]) buf[0];
2093 for (col=0; col < width; col+=2) {
2094 RAW(row+0,col+0) = pixel[col+0][1] << 1;
2095 RAW(row+1,col+1) = pixel[col+1][1] << 1;
2096 RAW(row+0,col+1) = pixel[col][0] + pixel[col+1][0];
2097 RAW(row+1,col+0) = pixel[col][2] + pixel[col+1][2];
2100 jpeg_finish_decompress (&cinfo);
2101 jpeg_destroy_decompress (&cinfo);
2102 maximum = 0xff << 1;
2105 void CLASS lossy_dng_load_raw()
2107 struct jpeg_decompress_struct cinfo;
2108 struct jpeg_error_mgr jerr;
2110 JSAMPLE (*pixel)[3];
2111 unsigned sorder=order, ntags, opcode, deg, i, j, c;
2112 unsigned save=data_offset-4, trow=0, tcol=0, row, col;
2113 ushort curve[3][256];
2114 double coeff[9], tot;
2116 fseek (ifp, meta_offset, SEEK_SET);
2120 opcode = get4(); get4(); get4();
2122 { fseek (ifp, get4(), SEEK_CUR); continue; }
2123 fseek (ifp, 20, SEEK_CUR);
2124 if ((c = get4()) > 2) break;
2125 fseek (ifp, 12, SEEK_CUR);
2126 if ((deg = get4()) > 8) break;
2127 for (i=0; i <= deg && i < 9; i++)
2128 coeff[i] = getreal(12);
2129 for (i=0; i < 256; i++) {
2130 for (tot=j=0; j <= deg; j++)
2131 tot += coeff[j] * pow(i/255.0, j);
2132 curve[c][i] = tot*0xffff;
2136 cinfo.err = jpeg_std_error (&jerr);
2137 jpeg_create_decompress (&cinfo);
2138 while (trow < raw_height) {
2139 fseek (ifp, save+=4, SEEK_SET);
2140 if (tile_length < INT_MAX)
2141 fseek (ifp, get4(), SEEK_SET);
2142 jpeg_stdio_src (&cinfo, ifp);
2143 jpeg_read_header (&cinfo, TRUE);
2144 jpeg_start_decompress (&cinfo);
2145 buf = (*cinfo.mem->alloc_sarray)
2146 ((j_common_ptr) &cinfo, JPOOL_IMAGE, cinfo.output_width*3, 1);
2147 while (cinfo.output_scanline < cinfo.output_height &&
2148 (row = trow + cinfo.output_scanline) < height) {
2149 jpeg_read_scanlines (&cinfo, buf, 1);
2150 pixel = (JSAMPLE (*)[3]) buf[0];
2151 for (col=0; col < cinfo.output_width && tcol+col < width; col++) {
2152 FORC3 image[row*width+tcol+col][c] = curve[c][pixel[col][c]];
2155 jpeg_abort_decompress (&cinfo);
2156 if ((tcol += tile_width) >= raw_width)
2157 trow += tile_length + (tcol = 0);
2159 jpeg_destroy_decompress (&cinfo);
2164 void CLASS kodak_dc120_load_raw()
2166 static const int mul[4] = { 162, 192, 187, 92 };
2167 static const int add[4] = { 0, 636, 424, 212 };
2169 int row, shift, col;
2171 for (row=0; row < height; row++) {
2172 if (fread (pixel, 1, 848, ifp) < 848) derror();
2173 shift = row * mul[row & 3] + add[row & 3];
2174 for (col=0; col < width; col++)
2175 RAW(row,col) = (ushort) pixel[(col + shift) % 848];
2180 void CLASS eight_bit_load_raw()
2185 pixel = (uchar *) calloc (raw_width, sizeof *pixel);
2186 merror (pixel, "eight_bit_load_raw()");
2187 for (row=0; row < raw_height; row++) {
2188 if (fread (pixel, 1, raw_width, ifp) < raw_width) derror();
2189 for (col=0; col < raw_width; col++)
2190 RAW(row,col) = curve[pixel[col]];
2193 maximum = curve[0xff];
2196 void CLASS kodak_yrgb_load_raw()
2199 int row, col, y, cb, cr, rgb[3], c;
2201 pixel = (uchar *) calloc (raw_width, 3*sizeof *pixel);
2202 merror (pixel, "kodak_yrgb_load_raw()");
2203 for (row=0; row < height; row++) {
2205 if (fread (pixel, raw_width, 3, ifp) < 3) derror();
2206 for (col=0; col < raw_width; col++) {
2207 y = pixel[width*2*(row & 1) + col];
2208 cb = pixel[width + (col & -2)] - 128;
2209 cr = pixel[width + (col & -2)+1] - 128;
2210 rgb[1] = y-((cb + cr + 2) >> 2);
2211 rgb[2] = rgb[1] + cb;
2212 rgb[0] = rgb[1] + cr;
2213 FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,255)];
2217 maximum = curve[0xff];
2220 void CLASS kodak_262_load_raw()
2222 static const uchar kodak_tree[2][26] =
2223 { { 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 },
2224 { 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 } };
2227 int *strip, ns, c, row, col, chess, pi=0, pi1, pi2, pred, val;
2229 FORC(2) huff[c] = make_decoder (kodak_tree[c]);
2230 ns = (raw_height+63) >> 5;
2231 pixel = (uchar *) malloc (raw_width*32 + ns*4);
2232 merror (pixel, "kodak_262_load_raw()");
2233 strip = (int *) (pixel + raw_width*32);
2235 FORC(ns) strip[c] = get4();
2236 for (row=0; row < raw_height; row++) {
2237 if ((row & 31) == 0) {
2238 fseek (ifp, strip[row >> 5], SEEK_SET);
2242 for (col=0; col < raw_width; col++) {
2243 chess = (row + col) & 1;
2244 pi1 = chess ? pi-2 : pi-raw_width-1;
2245 pi2 = chess ? pi-2*raw_width : pi-raw_width+1;
2246 if (col <= chess) pi1 = -1;
2247 if (pi1 < 0) pi1 = pi2;
2248 if (pi2 < 0) pi2 = pi1;
2249 if (pi1 < 0 && col > 1) pi1 = pi2 = pi-2;
2250 pred = (pi1 < 0) ? 0 : (pixel[pi1] + pixel[pi2]) >> 1;
2251 pixel[pi] = val = pred + ljpeg_diff (huff[chess]);
2252 if (val >> 8) derror();
2253 val = curve[pixel[pi++]];
2258 FORC(2) free (huff[c]);
2261 int CLASS kodak_65000_decode (short *out, int bsize)
2266 int save, bits=0, i, j, len, diff;
2269 bsize = (bsize + 3) & -4;
2270 for (i=0; i < bsize; i+=2) {
2272 if ((blen[i ] = c & 15) > 12 ||
2273 (blen[i+1] = c >> 4) > 12 ) {
2274 fseek (ifp, save, SEEK_SET);
2275 for (i=0; i < bsize; i+=8) {
2276 read_shorts (raw, 6);
2277 out[i ] = raw[0] >> 12 << 8 | raw[2] >> 12 << 4 | raw[4] >> 12;
2278 out[i+1] = raw[1] >> 12 << 8 | raw[3] >> 12 << 4 | raw[5] >> 12;
2279 for (j=0; j < 6; j++)
2280 out[i+2+j] = raw[j] & 0xfff;
2285 if ((bsize & 7) == 4) {
2286 bitbuf = fgetc(ifp) << 8;
2287 bitbuf += fgetc(ifp);
2290 for (i=0; i < bsize; i++) {
2293 for (j=0; j < 32; j+=8)
2294 bitbuf += (INT64) fgetc(ifp) << (bits+(j^8));
2297 diff = bitbuf & (0xffff >> (16-len));
2300 if ((diff & (1 << (len-1))) == 0)
2301 diff -= (1 << len) - 1;
2307 void CLASS kodak_65000_load_raw()
2310 int row, col, len, pred[2], ret, i;
2312 for (row=0; row < height; row++)
2313 for (col=0; col < width; col+=256) {
2314 pred[0] = pred[1] = 0;
2315 len = MIN (256, width-col);
2316 ret = kodak_65000_decode (buf, len);
2317 for (i=0; i < len; i++)
2318 if ((RAW(row,col+i) = curve[ret ? buf[i] :
2319 (pred[i & 1] += buf[i])]) >> 12) derror();
2323 void CLASS kodak_ycbcr_load_raw()
2325 short buf[384], *bp;
2326 int row, col, len, c, i, j, k, y[2][2], cb, cr, rgb[3];
2329 for (row=0; row < height; row+=2)
2330 for (col=0; col < width; col+=128) {
2331 len = MIN (128, width-col);
2332 kodak_65000_decode (buf, len*3);
2333 y[0][1] = y[1][1] = cb = cr = 0;
2334 for (bp=buf, i=0; i < len; i+=2, bp+=2) {
2337 rgb[1] = -((cb + cr + 2) >> 2);
2338 rgb[2] = rgb[1] + cb;
2339 rgb[0] = rgb[1] + cr;
2340 for (j=0; j < 2; j++)
2341 for (k=0; k < 2; k++) {
2342 if ((y[j][k] = y[j][k^1] + *bp++) >> 10) derror();
2343 ip = image[(row+j)*width + col+i+k];
2344 FORC3 ip[c] = curve[LIM(y[j][k]+rgb[c], 0, 0xfff)];
2350 void CLASS kodak_rgb_load_raw()
2352 short buf[768], *bp;
2353 int row, col, len, c, i, rgb[3];
2354 ushort *ip=image[0];
2356 if (raw_image) free (raw_image);
2358 for (row=0; row < height; row++)
2359 for (col=0; col < width; col+=256) {
2360 len = MIN (256, width-col);
2361 kodak_65000_decode (buf, len*3);
2362 memset (rgb, 0, sizeof rgb);
2363 for (bp=buf, i=0; i < len; i++, ip+=4)
2364 FORC3 if ((ip[c] = rgb[c] += *bp++) >> 12) derror();
2368 void CLASS kodak_thumb_load_raw()
2371 colors = thumb_misc >> 5;
2372 for (row=0; row < height; row++)
2373 for (col=0; col < width; col++)
2374 read_shorts (image[row*width+col], colors);
2375 maximum = (1 << (thumb_misc & 31)) - 1;
2378 void CLASS sony_decrypt (unsigned *data, int len, int start, int key)
2380 static unsigned pad[128], p = 0;
2383 for (p=0; p < 4; p++)
2384 pad[p] = key = key * 48828125 + 1;
2385 pad[3] = pad[3] << 1 | (pad[0]^pad[2]) >> 31;
2386 for (p=4; p < 127; p++)
2387 pad[p] = (pad[p-4]^pad[p-2]) << 1 | (pad[p-3]^pad[p-1]) >> 31;
2388 for (p=0; p < 127; p++)
2389 pad[p] = htonl(pad[p]);
2392 *data++ ^= pad[p & 127] = pad[(p+1) & 127] ^ pad[(p+65) & 127];
2397 void CLASS sony_load_raw()
2401 unsigned i, key, row, col;
2403 fseek (ifp, 200896, SEEK_SET);
2404 fseek (ifp, (unsigned) fgetc(ifp)*4 - 1, SEEK_CUR);
2407 fseek (ifp, 164600, SEEK_SET);
2408 fread (head, 1, 40, ifp);
2409 sony_decrypt ((unsigned int *) head, 10, 1, key);
2410 for (i=26; i-- > 22; )
2411 key = key << 8 | head[i];
2412 fseek (ifp, data_offset, SEEK_SET);
2413 for (row=0; row < raw_height; row++) {
2414 pixel = raw_image + row*raw_width;
2415 if (fread (pixel, 2, raw_width, ifp) < raw_width) derror();
2416 sony_decrypt ((unsigned int *) pixel, raw_width/2, !row, key);
2417 for (col=0; col < raw_width; col++)
2418 if ((pixel[col] = ntohs(pixel[col])) >> 14) derror();
2423 void CLASS sony_arw_load_raw()
2426 static const ushort tab[18] =
2427 { 0xf11,0xf10,0xe0f,0xd0e,0xc0d,0xb0c,0xa0b,0x90a,0x809,
2428 0x708,0x607,0x506,0x405,0x304,0x303,0x300,0x202,0x201 };
2429 int i, c, n, col, row, len, diff, sum=0;
2431 for (n=i=0; i < 18; i++)
2432 FORC(32768 >> (tab[i] >> 8)) huff[n++] = tab[i];
2434 for (col = raw_width; col--; )
2435 for (row=0; row < raw_height+1; row+=2) {
2436 if (row == raw_height) row = 1;
2437 len = getbithuff(15,huff);
2438 diff = getbits(len);
2439 if ((diff & (1 << (len-1))) == 0)
2440 diff -= (1 << len) - 1;
2441 if ((sum += diff) >> 12) derror();
2442 if (row < height) RAW(row,col) = sum;
2446 void CLASS sony_arw2_load_raw()
2450 int row, col, val, max, min, imax, imin, sh, bit, i;
2452 data = (uchar *) malloc (raw_width);
2453 merror (data, "sony_arw2_load_raw()");
2454 for (row=0; row < height; row++) {
2455 fread (data, 1, raw_width, ifp);
2456 for (dp=data, col=0; col < raw_width-30; dp+=16) {
2457 max = 0x7ff & (val = sget4(dp));
2458 min = 0x7ff & val >> 11;
2459 imax = 0x0f & val >> 22;
2460 imin = 0x0f & val >> 26;
2461 for (sh=0; sh < 4 && 0x80 << sh <= max-min; sh++);
2462 for (bit=30, i=0; i < 16; i++)
2463 if (i == imax) pix[i] = max;
2464 else if (i == imin) pix[i] = min;
2466 pix[i] = ((sget2(dp+(bit >> 3)) >> (bit & 7) & 0x7f) << sh) + min;
2467 if (pix[i] > 0x7ff) pix[i] = 0x7ff;
2470 for (i=0; i < 16; i++, col+=2)
2471 RAW(row,col) = curve[pix[i] << 1] >> 2;
2472 col -= col & 1 ? 1:31;
2478 #define HOLE(row) ((holes >> (((row) - raw_height) & 7)) & 1)
2480 /* Kudos to Rich Taylor for figuring out SMaL's compression algorithm. */
2481 void CLASS smal_decode_segment (unsigned seg[2][2], int holes)
2483 uchar hist[3][13] = {
2484 { 7, 7, 0, 0, 63, 55, 47, 39, 31, 23, 15, 7, 0 },
2485 { 7, 7, 0, 0, 63, 55, 47, 39, 31, 23, 15, 7, 0 },
2486 { 3, 3, 0, 0, 63, 47, 31, 15, 0 } };
2487 int low, high=0xff, carry=0, nbits=8;
2488 int pix, s, count, bin, next, i, sym[3];
2489 uchar diff, pred[]={0,0};
2490 ushort data=0, range=0;
2492 fseek (ifp, seg[0][1]+1, SEEK_SET);
2494 for (pix=seg[0][0]; pix < seg[1][0]; pix++) {
2495 for (s=0; s < 3; s++) {
2496 data = data << nbits | getbits(nbits);
2498 carry = (nbits += carry+1) < 1 ? nbits-1 : 0;
2499 while (--nbits >= 0)
2500 if ((data >> nbits & 0xff) == 0xff) break;
2502 data = ((data & ((1 << (nbits-1)) - 1)) << 1) |
2503 ((data + (((data & (1 << (nbits-1)))) << 1)) & (-1 << nbits));
2508 count = ((((data-range+1) & 0xffff) << 2) - 1) / (high >> 4);
2509 for (bin=0; hist[s][bin+5] > count; bin++);
2510 low = hist[s][bin+5] * (high >> 4) >> 2;
2511 if (bin) high = hist[s][bin+4] * (high >> 4) >> 2;
2513 for (nbits=0; high << nbits < 128; nbits++);
2514 range = (range+low) << nbits;
2517 if (++hist[s][2] > hist[s][3]) {
2518 next = (next+1) & hist[s][0];
2519 hist[s][3] = (hist[s][next+4] - hist[s][next+5]) >> 2;
2522 if (hist[s][hist[s][1]+4] - hist[s][hist[s][1]+5] > 1) {
2523 if (bin < hist[s][1])
2524 for (i=bin; i < hist[s][1]; i++) hist[s][i+5]--;
2525 else if (next <= bin)
2526 for (i=hist[s][1]; i < bin; i++) hist[s][i+5]++;
2531 diff = sym[2] << 5 | sym[1] << 2 | (sym[0] & 3);
2533 diff = diff ? -diff : 0x80;
2534 if (ftell(ifp) + 12 >= seg[1][1])
2536 raw_image[pix] = pred[pix & 1] += diff;
2537 if (!(pix & 1) && HOLE(pix / raw_width)) pix += 2;
2542 void CLASS smal_v6_load_raw()
2546 fseek (ifp, 16, SEEK_SET);
2549 seg[1][0] = raw_width * raw_height;
2550 seg[1][1] = INT_MAX;
2551 smal_decode_segment (seg, 0);
2554 int CLASS median4 (int *p)
2556 int min, max, sum, i;
2558 min = max = sum = p[0];
2559 for (i=1; i < 4; i++) {
2561 if (min > p[i]) min = p[i];
2562 if (max < p[i]) max = p[i];
2564 return (sum - min - max) >> 1;
2567 void CLASS fill_holes (int holes)
2569 int row, col, val[4];
2571 for (row=2; row < height-2; row++) {
2572 if (!HOLE(row)) continue;
2573 for (col=1; col < width-1; col+=4) {
2574 val[0] = RAW(row-1,col-1);
2575 val[1] = RAW(row-1,col+1);
2576 val[2] = RAW(row+1,col-1);
2577 val[3] = RAW(row+1,col+1);
2578 RAW(row,col) = median4(val);
2580 for (col=2; col < width-2; col+=4)
2581 if (HOLE(row-2) || HOLE(row+2))
2582 RAW(row,col) = (RAW(row,col-2) + RAW(row,col+2)) >> 1;
2584 val[0] = RAW(row,col-2);
2585 val[1] = RAW(row,col+2);
2586 val[2] = RAW(row-2,col);
2587 val[3] = RAW(row+2,col);
2588 RAW(row,col) = median4(val);
2593 void CLASS smal_v9_load_raw()
2595 unsigned seg[256][2], offset, nseg, holes, i;
2597 fseek (ifp, 67, SEEK_SET);
2600 fseek (ifp, offset, SEEK_SET);
2601 for (i=0; i < nseg*2; i++)
2602 seg[0][i] = get4() + data_offset*(i & 1);
2603 fseek (ifp, 78, SEEK_SET);
2605 fseek (ifp, 88, SEEK_SET);
2606 seg[nseg][0] = raw_height * raw_width;
2607 seg[nseg][1] = get4() + data_offset;
2608 for (i=0; i < nseg; i++)
2609 smal_decode_segment (seg+i, holes);
2610 if (holes) fill_holes (holes);
2613 void CLASS redcine_load_raw()
2624 in = jas_stream_fopen (ifname, "rb");
2625 jas_stream_seek (in, data_offset+20, SEEK_SET);
2626 jimg = jas_image_decode (in, -1, 0);
2627 if (!jimg) longjmp (failure, 3);
2628 jmat = jas_matrix_create (height/2, width/2);
2629 merror (jmat, "redcine_load_raw()");
2630 img = (ushort *) calloc ((height+2)*(width+2), 2);
2631 merror (img, "redcine_load_raw()");
2633 jas_image_readcmpt (jimg, c, 0, 0, width/2, height/2, jmat);
2634 data = jas_matrix_getref (jmat, 0, 0);
2635 for (row = c >> 1; row < height; row+=2)
2636 for (col = c & 1; col < width; col+=2)
2637 img[(row+1)*(width+2)+col+1] = data[(row/2)*(width/2)+col/2];
2639 for (col=1; col <= width; col++) {
2640 img[col] = img[2*(width+2)+col];
2641 img[(height+1)*(width+2)+col] = img[(height-1)*(width+2)+col];
2643 for (row=0; row < height+2; row++) {
2644 img[row*(width+2)] = img[row*(width+2)+2];
2645 img[(row+1)*(width+2)-1] = img[(row+1)*(width+2)-3];
2647 for (row=1; row <= height; row++) {
2648 pix = img + row*(width+2) + (col = 1 + (FC(row,1) & 1));
2649 for ( ; col <= width; col+=2, pix+=2) {
2650 c = (((pix[0] - 0x800) << 3) +
2651 pix[-(width+2)] + pix[width+2] + pix[-1] + pix[1]) >> 2;
2652 pix[0] = LIM(c,0,4095);
2655 for (row=0; row < height; row++)
2656 for (col=0; col < width; col++)
2657 RAW(row,col) = curve[img[(row+1)*(width+2)+col+1]];
2659 jas_matrix_destroy (jmat);
2660 jas_image_destroy (jimg);
2661 jas_stream_close (in);
2665 /* RESTRICTED code starts here */
2667 void CLASS foveon_decoder (unsigned size, unsigned code)
2669 static unsigned huff[1024];
2674 for (i=0; i < size; i++)
2676 memset (first_decode, 0, sizeof first_decode);
2677 free_decode = first_decode;
2679 cur = free_decode++;
2680 if (free_decode > first_decode+2048) {
2681 fprintf (stderr,_("%s: decoder table overflow\n"), ifname);
2682 longjmp (failure, 2);
2685 for (i=0; i < size; i++)
2686 if (huff[i] == code) {
2690 if ((len = code >> 27) > 26) return;
2691 code = (len+1) << 27 | (code & 0x3ffffff) << 1;
2693 cur->branch[0] = free_decode;
2694 foveon_decoder (size, code);
2695 cur->branch[1] = free_decode;
2696 foveon_decoder (size, code+1);
2699 void CLASS foveon_thumb()
2701 unsigned bwide, row, col, bitbuf=0, bit=1, c, i;
2703 struct decode *dindex;
2707 fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
2709 if (bwide < thumb_width*3) return;
2710 buf = (char *) malloc (bwide);
2711 merror (buf, "foveon_thumb()");
2712 for (row=0; row < thumb_height; row++) {
2713 fread (buf, 1, bwide, ifp);
2714 fwrite (buf, 3, thumb_width, ofp);
2719 foveon_decoder (256, 0);
2721 for (row=0; row < thumb_height; row++) {
2722 memset (pred, 0, sizeof pred);
2724 for (bit=col=0; col < thumb_width; col++)
2726 for (dindex=first_decode; dindex->branch[0]; ) {
2727 if ((bit = (bit-1) & 31) == 31)
2728 for (i=0; i < 4; i++)
2729 bitbuf = (bitbuf << 8) + fgetc(ifp);
2730 dindex = dindex->branch[bitbuf >> bit & 1];
2732 pred[c] += dindex->leaf;
2733 fputc (pred[c], ofp);
2738 void CLASS foveon_sd_load_raw()
2740 struct decode *dindex;
2743 int pred[3], row, col, bit=-1, c, i;
2745 read_shorts ((ushort *) diff, 1024);
2746 if (!load_flags) foveon_decoder (1024, 0);
2748 for (row=0; row < height; row++) {
2749 memset (pred, 0, sizeof pred);
2750 if (!bit && !load_flags && atoi(model+2) < 14) get4();
2751 for (col=bit=0; col < width; col++) {
2754 FORC3 pred[2-c] += diff[bitbuf >> c*10 & 0x3ff];
2757 for (dindex=first_decode; dindex->branch[0]; ) {
2758 if ((bit = (bit-1) & 31) == 31)
2759 for (i=0; i < 4; i++)
2760 bitbuf = (bitbuf << 8) + fgetc(ifp);
2761 dindex = dindex->branch[bitbuf >> bit & 1];
2763 pred[c] += diff[dindex->leaf];
2764 if (pred[c] >> 16 && ~pred[c] >> 16) derror();
2766 FORC3 image[row*width+col][c] = pred[c];
2771 void CLASS foveon_huff (ushort *huff)
2773 int i, j, clen, code;
2776 for (i=0; i < 13; i++) {
2779 for (j=0; j < 256 >> clen; )
2780 huff[code+ ++j] = clen << 8 | i;
2785 void CLASS foveon_dp_load_raw()
2787 unsigned c, roff[4], row, col, diff;
2788 ushort huff[258], vpred[2][2], hpred[2];
2790 fseek (ifp, 8, SEEK_CUR);
2793 FORC3 roff[c+1] = -(-(roff[c] + get4()) & -16);
2795 fseek (ifp, data_offset+roff[c], SEEK_SET);
2797 vpred[0][0] = vpred[0][1] = vpred[1][0] = vpred[1][1] = 512;
2798 for (row=0; row < height; row++) {
2799 for (col=0; col < width; col++) {
2800 diff = ljpeg_diff(huff);
2801 if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
2802 else hpred[col & 1] += diff;
2803 image[row*width+col][c] = hpred[col & 1];
2809 void CLASS foveon_load_camf()
2811 unsigned type, wide, high, i, j, row, col, diff;
2812 ushort huff[258], vpred[2][2] = {{512,512},{512,512}}, hpred[2];
2814 fseek (ifp, meta_offset, SEEK_SET);
2815 type = get4(); get4(); get4();
2819 fread (meta_data, 1, meta_length, ifp);
2820 for (i=0; i < meta_length; i++) {
2821 high = (high * 1597 + 51749) % 244944;
2822 wide = high * (INT64) 301593171 >> 24;
2823 meta_data[i] ^= ((((high << 8) - wide) >> 1) + wide) >> 17;
2825 } else if (type == 4) {
2827 meta_data = (char *) malloc (meta_length = wide*high*3/2);
2828 merror (meta_data, "foveon_load_camf()");
2832 for (j=row=0; row < high; row++) {
2833 for (col=0; col < wide; col++) {
2834 diff = ljpeg_diff(huff);
2835 if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
2836 else hpred[col & 1] += diff;
2838 meta_data[j++] = hpred[0] >> 4;
2839 meta_data[j++] = hpred[0] << 4 | hpred[1] >> 8;
2840 meta_data[j++] = hpred[1];
2845 fprintf (stderr,_("%s has unknown CAMF type %d.\n"), ifname, type);
2848 const char * CLASS foveon_camf_param (const char *block, const char *param)
2851 char *pos, *cp, *dp;
2853 for (idx=0; idx < meta_length; idx += sget4(pos+8)) {
2854 pos = meta_data + idx;
2855 if (strncmp (pos, "CMb", 3)) break;
2856 if (pos[3] != 'P') continue;
2857 if (strcmp (block, pos+sget4(pos+12))) continue;
2858 cp = pos + sget4(pos+16);
2860 dp = pos + sget4(cp+4);
2863 if (!strcmp (param, dp+sget4(cp)))
2864 return dp+sget4(cp+4);
2870 void * CLASS foveon_camf_matrix (unsigned dim[3], const char *name)
2872 unsigned i, idx, type, ndim, size, *mat;
2873 char *pos, *cp, *dp;
2876 for (idx=0; idx < meta_length; idx += sget4(pos+8)) {
2877 pos = meta_data + idx;
2878 if (strncmp (pos, "CMb", 3)) break;
2879 if (pos[3] != 'M') continue;
2880 if (strcmp (name, pos+sget4(pos+12))) continue;
2881 dim[0] = dim[1] = dim[2] = 1;
2882 cp = pos + sget4(pos+16);
2884 if ((ndim = sget4(cp+4)) > 3) break;
2885 dp = pos + sget4(cp+8);
2886 for (i=ndim; i--; ) {
2890 if ((dsize = (double) dim[0]*dim[1]*dim[2]) > meta_length/4) break;
2891 mat = (unsigned *) malloc ((size = dsize) * 4);
2892 merror (mat, "foveon_camf_matrix()");
2893 for (i=0; i < size; i++)
2894 if (type && type != 6)
2895 mat[i] = sget4(dp + i*4);
2897 mat[i] = sget4(dp + i*2) & 0xffff;
2900 fprintf (stderr,_("%s: \"%s\" matrix not found!\n"), ifname, name);
2904 int CLASS foveon_fixed (void *ptr, int size, const char *name)
2909 if (!name) return 0;
2910 dp = foveon_camf_matrix (dim, name);
2912 memcpy (ptr, dp, size*4);
2917 float CLASS foveon_avg (short *pix, int range[2], float cfilt)
2920 float val, min=FLT_MAX, max=-FLT_MAX, sum=0;
2922 for (i=range[0]; i <= range[1]; i++) {
2923 sum += val = pix[i*4] + (pix[i*4]-pix[(i-1)*4]) * cfilt;
2924 if (min > val) min = val;
2925 if (max < val) max = val;
2927 if (range[1] - range[0] == 1) return sum/2;
2928 return (sum - min - max) / (range[1] - range[0] - 1);
2931 short * CLASS foveon_make_curve (double max, double mul, double filt)
2937 if (!filt) filt = 0.8;
2938 size = 4*M_PI*max / filt;
2939 if (size == UINT_MAX) size--;
2940 curve = (short *) calloc (size+1, sizeof *curve);
2941 merror (curve, "foveon_make_curve()");
2943 for (i=0; i < size; i++) {
2945 curve[i+1] = (cos(x)+1)/2 * tanh(i*filt/mul) * mul + 0.5;
2950 void CLASS foveon_make_curves
2951 (short **curvep, float dq[3], float div[3], float filt)
2953 double mul[3], max=0;
2956 FORC3 mul[c] = dq[c]/div[c];
2957 FORC3 if (max < mul[c]) max = mul[c];
2958 FORC3 curvep[c] = foveon_make_curve (max, mul[c], filt);
2961 int CLASS foveon_apply_curve (short *curve, int i)
2963 if (abs(i) >= curve[0]) return 0;
2964 return i < 0 ? -curve[1-i] : curve[1+i];
2967 #define image ((short (*)[4]) image)
2969 void CLASS foveon_interpolate()
2971 static const short hood[] = { -1,-1, -1,0, -1,1, 0,-1, 0,1, 1,-1, 1,0, 1,1 };
2972 short *pix, prev[3], *curve[8], (*shrink)[3];
2973 float cfilt=0, ddft[3][3][2], ppm[3][3][3];
2974 float cam_xyz[3][3], correct[3][3], last[3][3], trans[3][3];
2975 float chroma_dq[3], color_dq[3], diag[3][3], div[3];
2976 float (*black)[3], (*sgain)[3], (*sgrow)[3];
2977 float fsum[3], val, frow, num;
2978 int row, col, c, i, j, diff, sgx, irow, sum, min, max, limit;
2979 int dscr[2][2], dstb[4], (*smrow[7])[3], total[4], ipix[3];
2980 int work[3][3], smlast, smred, smred_p=0, dev[3];
2981 int satlev[3], keep[4], active[4];
2982 unsigned dim[3], *badpix;
2983 double dsum=0, trsum[3];
2988 fprintf (stderr,_("Foveon interpolation...\n"));
2991 foveon_fixed (dscr, 4, "DarkShieldColRange");
2992 foveon_fixed (ppm[0][0], 27, "PostPolyMatrix");
2993 foveon_fixed (satlev, 3, "SaturationLevel");
2994 foveon_fixed (keep, 4, "KeepImageArea");
2995 foveon_fixed (active, 4, "ActiveImageArea");
2996 foveon_fixed (chroma_dq, 3, "ChromaDQ");
2997 foveon_fixed (color_dq, 3,
2998 foveon_camf_param ("IncludeBlocks", "ColorDQ") ?
2999 "ColorDQ" : "ColorDQCamRGB");
3000 if (foveon_camf_param ("IncludeBlocks", "ColumnFilter"))
3001 foveon_fixed (&cfilt, 1, "ColumnFilter");
3003 memset (ddft, 0, sizeof ddft);
3004 if (!foveon_camf_param ("IncludeBlocks", "DarkDrift")
3005 || !foveon_fixed (ddft[1][0], 12, "DarkDrift"))
3006 for (i=0; i < 2; i++) {
3007 foveon_fixed (dstb, 4, i ? "DarkShieldBottom":"DarkShieldTop");
3008 for (row = dstb[1]; row <= dstb[3]; row++)
3009 for (col = dstb[0]; col <= dstb[2]; col++)
3010 FORC3 ddft[i+1][c][1] += (short) image[row*width+col][c];
3011 FORC3 ddft[i+1][c][1] /= (dstb[3]-dstb[1]+1) * (dstb[2]-dstb[0]+1);
3014 if (!(cp = foveon_camf_param ("WhiteBalanceIlluminants", model2)))
3015 { fprintf (stderr,_("%s: Invalid white balance \"%s\"\n"), ifname, model2);
3017 foveon_fixed (cam_xyz, 9, cp);
3018 foveon_fixed (correct, 9,
3019 foveon_camf_param ("WhiteBalanceCorrections", model2));
3020 memset (last, 0, sizeof last);
3021 for (i=0; i < 3; i++)
3022 for (j=0; j < 3; j++)
3023 FORC3 last[i][j] += correct[i][c] * cam_xyz[c][j];
3025 #define LAST(x,y) last[(i+x)%3][(c+y)%3]
3026 for (i=0; i < 3; i++)
3027 FORC3 diag[c][i] = LAST(1,1)*LAST(2,2) - LAST(1,2)*LAST(2,1);
3029 FORC3 div[c] = diag[c][0]*0.3127 + diag[c][1]*0.329 + diag[c][2]*0.3583;
3030 sprintf (str, "%sRGBNeutral", model2);
3031 if (foveon_camf_param ("IncludeBlocks", str))
3032 foveon_fixed (div, 3, str);
3034 FORC3 if (num < div[c]) num = div[c];
3035 FORC3 div[c] /= num;
3037 memset (trans, 0, sizeof trans);
3038 for (i=0; i < 3; i++)
3039 for (j=0; j < 3; j++)
3040 FORC3 trans[i][j] += rgb_cam[i][c] * last[c][j] * div[j];
3041 FORC3 trsum[c] = trans[c][0] + trans[c][1] + trans[c][2];
3042 dsum = (6*trsum[0] + 11*trsum[1] + 3*trsum[2]) / 20;
3043 for (i=0; i < 3; i++)
3044 FORC3 last[i][c] = trans[i][c] * dsum / trsum[i];
3045 memset (trans, 0, sizeof trans);
3046 for (i=0; i < 3; i++)
3047 for (j=0; j < 3; j++)
3048 FORC3 trans[i][j] += (i==c ? 32 : -1) * last[c][j] / 30;
3050 foveon_make_curves (curve, color_dq, div, cfilt);
3051 FORC3 chroma_dq[c] /= 3;
3052 foveon_make_curves (curve+3, chroma_dq, div, cfilt);
3053 FORC3 dsum += chroma_dq[c] / div[c];
3054 curve[6] = foveon_make_curve (dsum, dsum, cfilt);
3055 curve[7] = foveon_make_curve (dsum*2, dsum*2, cfilt);
3057 sgain = (float (*)[3]) foveon_camf_matrix (dim, "SpatialGain");
3059 sgrow = (float (*)[3]) calloc (dim[1], sizeof *sgrow);
3060 sgx = (width + dim[1]-2) / (dim[1]-1);
3062 black = (float (*)[3]) calloc (height, sizeof *black);
3063 for (row=0; row < height; row++) {
3064 float *dp0 = &ddft[0][0][0];
3065 float *dp1 = &ddft[1][0][0];
3066 float *dp2 = &ddft[2][0][0];
3067 for( i=6; --i>=0; ++dp0,++dp1,++dp2 )
3068 *dp0 = *dp1 + row / (height-1.0) * (*dp2 - *dp1);
3069 pix = image[row*width];
3070 FORC3 black[row][c] =
3071 ( foveon_avg (image[row*width]+c, dscr[0], cfilt) +
3072 foveon_avg (image[row*width]+c, dscr[1], cfilt) * 3
3073 - ddft[0][c][0] ) / 4 - ddft[0][c][1];
3075 memcpy (black, black+8, sizeof *black*8);
3076 memcpy (black+height-11, black+height-22, 11*sizeof *black);
3077 memcpy (last, black, sizeof last);
3079 for (row=1; row < height-1; row++) {
3080 FORC3 if (last[1][c] > last[0][c]) {
3081 if (last[1][c] > last[2][c])
3082 black[row][c] = (last[0][c] > last[2][c]) ? last[0][c]:last[2][c];
3084 if (last[1][c] < last[2][c])
3085 black[row][c] = (last[0][c] < last[2][c]) ? last[0][c]:last[2][c];
3086 memmove (last, last+1, 2*sizeof last[0]);
3087 memcpy (last[2], black[row+1], sizeof last[2]);
3089 FORC3 black[row][c] = (last[0][c] + last[1][c])/2;
3090 FORC3 black[0][c] = (black[1][c] + black[3][c])/2;
3092 val = 1 - exp(-1/24.0);
3093 memcpy (fsum, black, sizeof fsum);
3094 for (row=1; row < height; row++)
3095 FORC3 fsum[c] += black[row][c] =
3096 (black[row][c] - black[row-1][c])*val + black[row-1][c];
3097 memcpy (last[0], black[height-1], sizeof last[0]);
3098 FORC3 fsum[c] /= height;
3099 for (row = height; row--; )
3100 FORC3 last[0][c] = black[row][c] =
3101 (black[row][c] - fsum[c] - last[0][c])*val + last[0][c];
3103 memset (total, 0, sizeof total);
3104 for (row=2; row < height; row+=4)
3105 for (col=2; col < width; col+=4) {
3106 FORC3 total[c] += (short) image[row*width+col][c];
3109 for (row=0; row < height; row++)
3110 FORC3 black[row][c] += fsum[c]/2 + total[c]/(total[3]*100.0);
3112 for (row=0; row < height; row++) {
3113 float *dp0 = &ddft[0][0][0];
3114 float *dp1 = &ddft[1][0][0];
3115 float *dp2 = &ddft[2][0][0];
3116 for( i=6; --i>=0; ++dp0,++dp1,++dp2 )
3117 *dp0 = *dp1 + row / (height-1.0) * (*dp2 - *dp1);
3118 pix = image[row*width];
3119 memcpy (prev, pix, sizeof prev);
3120 frow = row / (height-1.0) * (dim[2]-1);
3121 if ((irow = frow) == dim[2]-1) irow--;
3123 for (i=0; i < dim[1]; i++)
3124 FORC3 sgrow[i][c] = sgain[ irow *dim[1]+i][c] * (1-frow) +
3125 sgain[(irow+1)*dim[1]+i][c] * frow;
3126 for (col=0; col < width; col++) {
3128 diff = pix[c] - prev[c];
3130 ipix[c] = pix[c] + floor ((diff + (diff*diff >> 14)) * cfilt
3131 - ddft[0][c][1] - ddft[0][c][0] * ((float) col/width - 0.5)
3135 work[0][c] = ipix[c] * ipix[c] >> 14;
3136 work[2][c] = ipix[c] * work[0][c] >> 14;
3137 work[1][2-c] = ipix[(c+1) % 3] * ipix[(c+2) % 3] >> 14;
3140 for (val=i=0; i < 3; i++)
3141 for ( j=0; j < 3; j++)
3142 val += ppm[c][i][j] * work[i][j];
3143 ipix[c] = floor ((ipix[c] + floor(val)) *
3144 ( sgrow[col/sgx ][c] * (sgx - col%sgx) +
3145 sgrow[col/sgx+1][c] * (col%sgx) ) / sgx / div[c]);
3146 if (ipix[c] > 32000) ipix[c] = 32000;
3156 if ((badpix = (unsigned int *) foveon_camf_matrix (dim, "BadPixels"))) {
3157 for (i=0; i < dim[0]; i++) {
3158 col = (badpix[i] >> 8 & 0xfff) - keep[0];
3159 row = (badpix[i] >> 20 ) - keep[1];
3160 if ((unsigned)(row-1) > height-3 || (unsigned)(col-1) > width-3)
3162 memset (fsum, 0, sizeof fsum);
3163 for (sum=j=0; j < 8; j++)
3164 if (badpix[i] & (1 << j)) {
3165 FORC3 fsum[c] += (short)
3166 image[(row+hood[j*2])*width+col+hood[j*2+1]][c];
3169 if (sum) FORC3 image[row*width+col][c] = fsum[c]/sum;
3174 /* Array for 5x5 Gaussian averaging of red values */
3175 smrow[6] = (int (*)[3]) calloc (width*5, sizeof **smrow);
3176 merror (smrow[6], "foveon_interpolate()");
3177 for (i=0; i < 5; i++)
3178 smrow[i] = smrow[6] + i*width;
3180 /* Sharpen the reds against these Gaussian averages */
3181 for (smlast=-1, row=2; row < height-2; row++) {
3182 while (smlast < row+2) {
3183 for (i=0; i < 6; i++)
3184 smrow[(i+5) % 6] = smrow[i];
3185 pix = image[++smlast*width+2];
3186 for (col=2; col < width-2; col++) {
3188 (pix[0]*6 + (pix[-4]+pix[4])*4 + pix[-8]+pix[8] + 8) >> 4;
3192 pix = image[row*width+2];
3193 for (col=2; col < width-2; col++) {
3194 smred = ( 6 * smrow[2][col][0]
3195 + 4 * (smrow[1][col][0] + smrow[3][col][0])
3196 + smrow[0][col][0] + smrow[4][col][0] + 8 ) >> 4;
3199 i = pix[0] + ((pix[0] - ((smred*7 + smred_p) >> 3)) >> 3);
3200 if (i > 32000) i = 32000;
3207 /* Adjust the brighter pixels for better linearity */
3210 i = satlev[c] / div[c];
3211 if (min > i) min = i;
3213 limit = min * 9 >> 4;
3214 for (pix=image[0]; pix < image[height*width]; pix+=4) {
3215 if (pix[0] <= limit || pix[1] <= limit || pix[2] <= limit)
3218 for (c=1; c < 3; c++) {
3219 if (min > pix[c]) min = pix[c];
3220 if (max < pix[c]) max = pix[c];
3222 if (min >= limit*2) {
3223 pix[0] = pix[1] = pix[2] = max;
3225 i = 0x4000 - ((min - limit) << 14) / limit;
3226 i = 0x4000 - (i*i >> 14);
3228 FORC3 pix[c] += (max - pix[c]) * i >> 14;
3232 Because photons that miss one detector often hit another,
3233 the sum R+G+B is much less noisy than the individual colors.
3234 So smooth the hues without smoothing the total.
3236 for (smlast=-1, row=2; row < height-2; row++) {
3237 while (smlast < row+2) {
3238 for (i=0; i < 6; i++)
3239 smrow[(i+5) % 6] = smrow[i];
3240 pix = image[++smlast*width+2];
3241 for (col=2; col < width-2; col++) {
3242 FORC3 smrow[4][col][c] = (pix[c-4]+2*pix[c]+pix[c+4]+2) >> 2;
3246 pix = image[row*width+2];
3247 for (col=2; col < width-2; col++) {
3248 FORC3 dev[c] = -foveon_apply_curve (curve[7], pix[c] -
3249 ((smrow[1][col][c] + 2*smrow[2][col][c] + smrow[3][col][c]) >> 2));
3250 sum = (dev[0] + dev[1] + dev[2]) >> 3;
3251 FORC3 pix[c] += dev[c] - sum;
3255 for (smlast=-1, row=2; row < height-2; row++) {
3256 while (smlast < row+2) {
3257 for (i=0; i < 6; i++)
3258 smrow[(i+5) % 6] = smrow[i];
3259 pix = image[++smlast*width+2];
3260 for (col=2; col < width-2; col++) {
3261 FORC3 smrow[4][col][c] =
3262 (pix[c-8]+pix[c-4]+pix[c]+pix[c+4]+pix[c+8]+2) >> 2;
3266 pix = image[row*width+2];
3267 for (col=2; col < width-2; col++) {
3268 for (total[3]=375, sum=60, c=0; c < 3; c++) {
3269 for (total[c]=i=0; i < 5; i++)
3270 total[c] += smrow[i][col][c];
3271 total[3] += total[c];
3274 if (sum < 0) sum = 0;
3275 j = total[3] > 375 ? (sum << 16) / total[3] : sum * 174;
3276 FORC3 pix[c] += foveon_apply_curve (curve[6],
3277 ((j*total[c] + 0x8000) >> 16) - pix[c]);
3282 /* Transform the image to a different colorspace */
3283 for (pix=image[0]; pix < image[height*width]; pix+=4) {
3284 FORC3 pix[c] -= foveon_apply_curve (curve[c], pix[c]);
3285 sum = (pix[0]+pix[1]+pix[1]+pix[2]) >> 2;
3286 FORC3 pix[c] -= foveon_apply_curve (curve[c], pix[c]-sum);
3288 for (dsum=i=0; i < 3; i++)
3289 dsum += trans[c][i] * pix[i];
3290 if (dsum < 0) dsum = 0;
3291 if (dsum > 24000) dsum = 24000;
3292 ipix[c] = dsum + 0.5;
3294 FORC3 pix[c] = ipix[c];
3297 /* Smooth the image bottom-to-top and save at 1/4 scale */
3298 shrink = (short (*)[3]) calloc ((width/4) * (height/4), sizeof *shrink);
3299 merror (shrink, "foveon_interpolate()");
3300 for (row = height/4; row--; )
3301 for (col=0; col < width/4; col++) {
3302 ipix[0] = ipix[1] = ipix[2] = 0;
3303 for (i=0; i < 4; i++)
3304 for (j=0; j < 4; j++)
3305 FORC3 ipix[c] += image[(row*4+i)*width+col*4+j][c];
3307 if (row+2 > height/4)
3308 shrink[row*(width/4)+col][c] = ipix[c] >> 4;
3310 shrink[row*(width/4)+col][c] =
3311 (shrink[(row+1)*(width/4)+col][c]*1840 + ipix[c]*141 + 2048) >> 12;
3313 /* From the 1/4-scale image, smooth right-to-left */
3314 for (row=0; row < (height & ~3); row++) {
3315 ipix[0] = ipix[1] = ipix[2] = 0;
3317 for (col = width & ~3 ; col--; )
3318 FORC3 smrow[0][col][c] = ipix[c] =
3319 (shrink[(row/4)*(width/4)+col/4][c]*1485 + ipix[c]*6707 + 4096) >> 13;
3321 /* Then smooth left-to-right */
3322 ipix[0] = ipix[1] = ipix[2] = 0;
3323 for (col=0; col < (width & ~3); col++)
3324 FORC3 smrow[1][col][c] = ipix[c] =
3325 (smrow[0][col][c]*1485 + ipix[c]*6707 + 4096) >> 13;
3327 /* Smooth top-to-bottom */
3329 memcpy (smrow[2], smrow[1], sizeof **smrow * width);
3331 for (col=0; col < (width & ~3); col++)
3332 FORC3 smrow[2][col][c] =
3333 (smrow[2][col][c]*6707 + smrow[1][col][c]*1485 + 4096) >> 13;
3335 /* Adjust the chroma toward the smooth values */
3336 for (col=0; col < (width & ~3); col++) {
3337 for (i=j=30, c=0; c < 3; c++) {
3338 i += smrow[2][col][c];
3339 j += image[row*width+col][c];
3342 for (sum=c=0; c < 3; c++) {
3343 ipix[c] = foveon_apply_curve (curve[c+3],
3344 ((smrow[2][col][c] * j + 0x8000) >> 16) - image[row*width+col][c]);
3349 i = image[row*width+col][c] + ipix[c] - sum;
3351 image[row*width+col][c] = i;
3357 for (i=0; i < 8; i++)
3360 /* Trim off the black border */
3361 active[1] -= keep[1];
3363 i = active[2] - active[0];
3364 for (row=0; row < active[3]-active[1]; row++)
3365 memcpy (image[row*i], image[(row+active[1])*width+active[0]],
3372 /* RESTRICTED code ends here */
3374 void CLASS crop_masked_pixels()
3377 unsigned r, c, m, mblack[8], zero, val;
3379 if (load_raw == &CLASS phase_one_load_raw ||
3380 load_raw == &CLASS phase_one_load_raw_c)
3381 phase_one_correct();
3383 for (row=0; row < raw_height-top_margin*2; row++) {
3384 for (col=0; col < fuji_width << !fuji_layout; col++) {
3386 r = fuji_width - 1 - col + (row >> 1);
3387 c = col + ((row+1) >> 1);
3389 r = fuji_width - 1 + row - (col >> 1);
3390 c = row + ((col+1) >> 1);
3392 if (r < height && c < width)
3393 BAYER(r,c) = RAW(row+top_margin,col+left_margin);
3397 for (row=0; row < height; row++)
3398 for (col=0; col < width; col++)
3399 BAYER2(row,col) = RAW(row+top_margin,col+left_margin);
3401 if (mask[0][3]) goto mask_set;
3402 if (load_raw == &CLASS canon_load_raw ||
3403 load_raw == &CLASS lossless_jpeg_load_raw) {
3404 mask[0][1] = mask[1][1] = 2;
3408 if (load_raw == &CLASS canon_600_load_raw ||
3409 load_raw == &CLASS sony_load_raw ||
3410 (load_raw == &CLASS eight_bit_load_raw && strncmp(model,"DC2",3)) ||
3411 load_raw == &CLASS kodak_262_load_raw ||
3412 (load_raw == &CLASS packed_load_raw && (load_flags & 32))) {
3414 mask[0][0] = mask[1][0] = top_margin;
3415 mask[0][2] = mask[1][2] = top_margin+height;
3416 mask[0][3] += left_margin;
3417 mask[1][1] += left_margin+width;
3418 mask[1][3] += raw_width;
3420 if (load_raw == &CLASS nokia_load_raw) {
3421 mask[0][2] = top_margin;
3425 memset (mblack, 0, sizeof mblack);
3426 for (zero=m=0; m < 8; m++)
3427 for (row=mask[m][0]; row < mask[m][2]; row++)
3428 for (col=mask[m][1]; col < mask[m][3]; col++) {
3429 c = FC(row-top_margin,col-left_margin);
3430 mblack[c] += val = RAW(row,col);
3434 if (load_raw == &CLASS canon_600_load_raw && width < raw_width) {
3435 black = (mblack[0]+mblack[1]+mblack[2]+mblack[3]) /
3436 (mblack[4]+mblack[5]+mblack[6]+mblack[7]) - 4;
3437 canon_600_correct();
3438 } else if (zero < mblack[4] && mblack[5] && mblack[6] && mblack[7])
3439 FORC4 cblack[c] = mblack[c] / mblack[4+c];
3442 void CLASS remove_zeroes()
3444 unsigned row, col, tot, n, r, c;
3446 for (row=0; row < height; row++)
3447 for (col=0; col < width; col++)
3448 if (BAYER(row,col) == 0) {
3450 for (r = row-2; r <= row+2; r++)
3451 for (c = col-2; c <= col+2; c++)
3452 if (r < height && c < width &&
3453 FC(r,c) == FC(row,col) && BAYER(r,c))
3454 tot += (n++,BAYER(r,c));
3455 if (n) BAYER(row,col) = tot/n;
3460 Seach from the current directory up to the root looking for
3461 a ".badpixels" file, and fix those pixels now.
3463 void CLASS bad_pixels (const char *cfname)
3466 char *fname, *cp, line[128];
3467 int len, time, row, col, r, c, rad, tot, n, fixed=0;
3469 if (!filters) return;
3471 fp = fopen (cfname, "r");
3473 for (len=32 ; ; len *= 2) {
3474 fname = (char *) malloc (len);
3476 if (getcwd (fname, len-16)) break;
3478 if (errno != ERANGE) return;
3480 #if defined(WIN32) || defined(DJGPP)
3481 if (fname[1] == ':')
3482 memmove (fname, fname+2, len-2);
3483 for (cp=fname; *cp; cp++)
3484 if (*cp == '\\') *cp = '/';
3486 cp = fname + strlen(fname);
3487 if (cp[-1] == '/') cp--;
3488 while (*fname == '/') {
3489 strcpy (cp, "/.badpixels");
3490 if ((fp = fopen (fname, "r"))) break;
3491 if (cp == fname) break;
3492 while (*--cp != '/');
3497 while (fgets (line, 128, fp)) {
3498 cp = strchr (line, '#');
3500 if (sscanf (line, "%d %d %d", &col, &row, &time) != 3) continue;
3501 if ((unsigned) col >= width || (unsigned) row >= height) continue;
3502 if (time > timestamp) continue;
3503 for (tot=n=0, rad=1; rad < 3 && n==0; rad++)
3504 for (r = row-rad; r <= row+rad; r++)
3505 for (c = col-rad; c <= col+rad; c++)
3506 if ((unsigned) r < height && (unsigned) c < width &&
3507 (r != row || c != col) && fcol(r,c) == fcol(row,col)) {
3511 BAYER2(row,col) = tot/n;
3514 fprintf (stderr,_("Fixed dead pixels at:"));
3515 fprintf (stderr, " %d,%d", col, row);
3518 if (fixed) fputc ('\n', stderr);
3522 void CLASS subtract (const char *fname)
3525 int dim[3]={0,0,0}, comment=0, number=0, error=0, nd=0, c, row, col;
3528 if (!(fp = fopen (fname, "rb"))) {
3529 perror (fname); return;
3531 if (fgetc(fp) != 'P' || fgetc(fp) != '5') error = 1;
3532 while (!error && nd < 3 && (c = fgetc(fp)) != EOF) {
3533 if (c == '#') comment = 1;
3534 if (c == '\n') comment = 0;
3535 if (comment) continue;
3536 if (isdigit(c)) number = 1;
3538 if (isdigit(c)) dim[nd] = dim[nd]*10 + c -'0';
3539 else if (isspace(c)) {
3544 if (error || nd < 3) {
3545 fprintf (stderr,_("%s is not a valid PGM file!\n"), fname);
3546 fclose (fp); return;
3547 } else if (dim[0] != width || dim[1] != height || dim[2] != 65535) {
3548 fprintf (stderr,_("%s has the wrong dimensions!\n"), fname);
3549 fclose (fp); return;
3551 pixel = (ushort *) calloc (width, sizeof *pixel);
3552 merror (pixel, "subtract()");
3553 for (row=0; row < height; row++) {
3554 fread (pixel, 2, width, fp);
3555 for (col=0; col < width; col++)
3556 BAYER(row,col) = MAX (BAYER(row,col) - ntohs(pixel[col]), 0);
3560 memset (cblack, 0, sizeof cblack);
3564 void CLASS gamma_curve (double pwr, double ts, int mode, int imax)
3567 double g[6], bnd[2]={0,0}, r;
3571 g[2] = g[3] = g[4] = 0;
3573 if (g[1] && (g[1]-1)*(g[0]-1) <= 0) {
3574 for (i=0; i < 48; i++) {
3575 g[2] = (bnd[0] + bnd[1])/2;
3576 if (g[0]) bnd[(pow(g[2]/g[1],-g[0]) - 1)/g[0] - 1/g[2] > -1] = g[2];
3577 else bnd[g[2]/exp(1-1/g[2]) < g[1]] = g[2];
3580 if (g[0]) g[4] = g[2] * (1/g[0] - 1);
3582 if (g[0]) g[5] = 1 / (g[1]*SQR(g[3])/2 - g[4]*(1 - g[3]) +
3583 (1 - pow(g[3],1+g[0]))*(1 + g[4])/(1 + g[0])) - 1;
3584 else g[5] = 1 / (g[1]*SQR(g[3])/2 + 1
3585 - g[2] - g[3] - g[2]*g[3]*(log(g[3]) - 1)) - 1;
3587 memcpy (gamm, g, sizeof gamm);
3590 for (i=0; i < 0x10000; i++) {
3592 if ((r = (double) i / imax) < 1)
3593 curve[i] = 0x10000 * ( mode
3594 ? (r < g[3] ? r*g[1] : (g[0] ? pow( r,g[0])*(1+g[4])-g[4] : log(r)*g[2]+1))
3595 : (r < g[2] ? r/g[1] : (g[0] ? pow((r+g[4])/(1+g[4]),1/g[0]) : exp((r-1)/g[2]))));
3599 void CLASS pseudoinverse (double (*in)[3], double (*out)[3], int size)
3601 double work[3][6], num;
3604 for (i=0; i < 3; i++) {
3605 for (j=0; j < 6; j++)
3606 work[i][j] = j == i+3;
3607 for (j=0; j < 3; j++)
3608 for (k=0; k < size; k++)
3609 work[i][j] += in[k][i] * in[k][j];
3611 for (i=0; i < 3; i++) {
3613 for (j=0; j < 6; j++)
3615 for (k=0; k < 3; k++) {
3618 for (j=0; j < 6; j++)
3619 work[k][j] -= work[i][j] * num;
3622 for (i=0; i < size; i++)
3623 for (j=0; j < 3; j++)
3624 for (out[i][j]=k=0; k < 3; k++)
3625 out[i][j] += work[j][k+3] * in[i][k];
3628 void CLASS cam_xyz_coeff (double cam_xyz[4][3])
3630 double cam_rgb[4][3], inverse[4][3], num;
3633 for (i=0; i < colors; i++) /* Multiply out XYZ colorspace */
3634 for (j=0; j < 3; j++)
3635 for (cam_rgb[i][j] = k=0; k < 3; k++)
3636 cam_rgb[i][j] += cam_xyz[i][k] * xyz_rgb[k][j];
3638 for (i=0; i < colors; i++) { /* Normalize cam_rgb so that */
3639 for (num=j=0; j < 3; j++) /* cam_rgb * (1,1,1) is (1,1,1,1) */
3640 num += cam_rgb[i][j];
3641 for (j=0; j < 3; j++)
3642 cam_rgb[i][j] /= num;
3643 pre_mul[i] = 1 / num;
3645 pseudoinverse (cam_rgb, inverse, colors);
3646 for (raw_color = i=0; i < 3; i++)
3647 for (j=0; j < colors; j++)
3648 rgb_cam[i][j] = inverse[j][i];
3652 void CLASS colorcheck()
3655 // Coordinates of the GretagMacbeth ColorChecker squares
3656 // width, height, 1st_column, 1st_row
3657 int cut[NSQ][4]; // you must set these
3658 // ColorChecker Chart under 6500-kelvin illumination
3659 static const double gmb_xyY[NSQ][3] = {
3660 { 0.400, 0.350, 10.1 }, // Dark Skin
3661 { 0.377, 0.345, 35.8 }, // Light Skin
3662 { 0.247, 0.251, 19.3 }, // Blue Sky
3663 { 0.337, 0.422, 13.3 }, // Foliage
3664 { 0.265, 0.240, 24.3 }, // Blue Flower
3665 { 0.261, 0.343, 43.1 }, // Bluish Green
3666 { 0.506, 0.407, 30.1 }, // Orange
3667 { 0.211, 0.175, 12.0 }, // Purplish Blue
3668 { 0.453, 0.306, 19.8 }, // Moderate Red
3669 { 0.285, 0.202, 6.6 }, // Purple
3670 { 0.380, 0.489, 44.3 }, // Yellow Green
3671 { 0.473, 0.438, 43.1 }, // Orange Yellow
3672 { 0.187, 0.129, 6.1 }, // Blue
3673 { 0.305, 0.478, 23.4 }, // Green
3674 { 0.539, 0.313, 12.0 }, // Red
3675 { 0.448, 0.470, 59.1 }, // Yellow
3676 { 0.364, 0.233, 19.8 }, // Magenta
3677 { 0.196, 0.252, 19.8 }, // Cyan
3678 { 0.310, 0.316, 90.0 }, // White
3679 { 0.310, 0.316, 59.1 }, // Neutral 8
3680 { 0.310, 0.316, 36.2 }, // Neutral 6.5
3681 { 0.310, 0.316, 19.8 }, // Neutral 5
3682 { 0.310, 0.316, 9.0 }, // Neutral 3.5
3683 { 0.310, 0.316, 3.1 } }; // Black
3684 double gmb_cam[NSQ][4], gmb_xyz[NSQ][3];
3685 double inverse[NSQ][3], cam_xyz[4][3], num;
3686 int c, i, j, k, sq, row, col, count[4];
3688 memset (gmb_cam, 0, sizeof gmb_cam);
3689 for (sq=0; sq < NSQ; sq++) {
3691 for (row=cut[sq][3]; row < cut[sq][3]+cut[sq][1]; row++)
3692 for (col=cut[sq][2]; col < cut[sq][2]+cut[sq][0]; col++) {
3694 if (c >= colors) c -= 2;
3695 gmb_cam[sq][c] += BAYER(row,col);
3698 FORCC gmb_cam[sq][c] = gmb_cam[sq][c]/count[c] - black;
3699 gmb_xyz[sq][0] = gmb_xyY[sq][2] * gmb_xyY[sq][0] / gmb_xyY[sq][1];
3700 gmb_xyz[sq][1] = gmb_xyY[sq][2];
3701 gmb_xyz[sq][2] = gmb_xyY[sq][2] *
3702 (1 - gmb_xyY[sq][0] - gmb_xyY[sq][1]) / gmb_xyY[sq][1];
3704 pseudoinverse (gmb_xyz, inverse, NSQ);
3705 for (i=0; i < colors; i++)
3706 for (j=0; j < 3; j++)
3707 for (cam_xyz[i][j] = k=0; k < NSQ; k++)
3708 cam_xyz[i][j] += gmb_cam[k][i] * inverse[k][j];
3709 cam_xyz_coeff (cam_xyz);
3711 printf (" { \"%s %s\", %d,\n\t{", make, model, black);
3712 num = 10000 / (cam_xyz[1][0] + cam_xyz[1][1] + cam_xyz[1][2]);
3713 FORCC for (j=0; j < 3; j++)
3714 printf ("%c%d", (c | j) ? ',':' ', (int) (cam_xyz[c][j] * num + 0.5));
3721 void CLASS hat_transform (float *temp, float *base, int st, int size, int sc)
3724 for (i=0; i < sc; i++)
3725 temp[i] = 2*base[st*i] + base[st*(sc-i)] + base[st*(i+sc)];
3726 for (; i+sc < size; i++)
3727 temp[i] = 2*base[st*i] + base[st*(i-sc)] + base[st*(i+sc)];
3728 for (; i < size; i++)
3729 temp[i] = 2*base[st*i] + base[st*(i-sc)] + base[st*(2*size-2-(i+sc))];
3732 void CLASS wavelet_denoise()
3734 float *fimg=0, *temp, thold, mul[2], avg, diff;
3735 int scale=1, size, lev, hpass, lpass, row, col, nc, c, i, wlast, blk[2];
3737 static const float noise[] =
3738 { 0.8002,0.2735,0.1202,0.0585,0.0291,0.0152,0.0080,0.0044 };
3740 if (verbose) fprintf (stderr,_("Wavelet denoising...\n"));
3742 while (maximum << scale < 0x10000) scale++;
3743 maximum <<= --scale;
3745 FORC4 cblack[c] <<= scale;
3746 if ((size = iheight*iwidth) < 0x15550000)
3747 fimg = (float *) malloc ((size*3 + iheight + iwidth) * sizeof *fimg);
3748 merror (fimg, "wavelet_denoise()");
3749 temp = fimg + size*3;
3750 if ((nc = colors) == 3 && filters) nc++;
3751 FORC(nc) { /* denoise R,G1,B,G3 individually */
3752 for (i=0; i < size; i++)
3753 fimg[i] = 256 * sqrt(image[i][c] << scale);
3754 for (hpass=lev=0; lev < 5; lev++) {
3755 lpass = size*((lev & 1)+1);
3756 for (row=0; row < iheight; row++) {
3757 hat_transform (temp, fimg+hpass+row*iwidth, 1, iwidth, 1 << lev);
3758 for (col=0; col < iwidth; col++)
3759 fimg[lpass + row*iwidth + col] = temp[col] * 0.25;
3761 for (col=0; col < iwidth; col++) {
3762 hat_transform (temp, fimg+lpass+col, iwidth, iheight, 1 << lev);
3763 for (row=0; row < iheight; row++)
3764 fimg[lpass + row*iwidth + col] = temp[row] * 0.25;
3766 thold = threshold * noise[lev];
3767 for (i=0; i < size; i++) {
3768 fimg[hpass+i] -= fimg[lpass+i];
3769 if (fimg[hpass+i] < -thold) fimg[hpass+i] += thold;
3770 else if (fimg[hpass+i] > thold) fimg[hpass+i] -= thold;
3771 else fimg[hpass+i] = 0;
3772 if (hpass) fimg[i] += fimg[hpass+i];
3776 for (i=0; i < size; i++)
3777 image[i][c] = CLIP(SQR(fimg[i]+fimg[lpass+i])/0x10000);
3779 if (filters && colors == 3) { /* pull G1 and G3 closer together */
3780 for (row=0; row < 2; row++) {
3781 mul[row] = 0.125 * pre_mul[FC(row+1,0) | 1] / pre_mul[FC(row,0) | 1];
3782 blk[row] = cblack[FC(row,0) | 1];
3784 for (i=0; i < 4; i++)
3785 window[i] = (ushort *) fimg + width*i;
3786 for (wlast=-1, row=1; row < height-1; row++) {
3787 while (wlast < row+1) {
3788 for (wlast++, i=0; i < 4; i++)
3789 window[(i+3) & 3] = window[i];
3790 for (col = FC(wlast,1) & 1; col < width; col+=2)
3791 window[2][col] = BAYER(wlast,col);
3793 thold = threshold/512;
3794 for (col = (FC(row,0) & 1)+1; col < width-1; col+=2) {
3795 avg = ( window[0][col-1] + window[0][col+1] +
3796 window[2][col-1] + window[2][col+1] - blk[~row & 1]*4 )
3797 * mul[row & 1] + (window[1][col] + blk[row & 1]) * 0.5;
3798 avg = avg < 0 ? 0 : sqrt(avg);
3799 diff = sqrt(BAYER(row,col)) - avg;
3800 if (diff < -thold) diff += thold;
3801 else if (diff > thold) diff -= thold;
3803 BAYER(row,col) = CLIP(SQR(avg+diff) + 0.5);
3810 void CLASS scale_colors()
3812 unsigned bottom, right, size, row, col, ur, uc, i, x, y, c, sum[8];
3814 double dsum[8], dmin, dmax;
3815 float scale_mul[4], fr, fc;
3816 ushort *img=0, *pix;
3819 memcpy (pre_mul, user_mul, sizeof pre_mul);
3820 if (use_auto_wb || (use_camera_wb && cam_mul[0] == -1)) {
3821 memset (dsum, 0, sizeof dsum);
3822 bottom = MIN (greybox[1]+greybox[3], height);
3823 right = MIN (greybox[0]+greybox[2], width);
3824 for (row=greybox[1]; row < bottom; row += 8)
3825 for (col=greybox[0]; col < right; col += 8) {
3826 memset (sum, 0, sizeof sum);
3827 for (y=row; y < row+8 && y < bottom; y++)
3828 for (x=col; x < col+8 && x < right; x++)
3834 val = image[y*width+x][c];
3835 if (val > maximum-25) goto skip_block;
3836 if ((val -= cblack[c]) < 0) val = 0;
3841 FORC(8) dsum[c] += sum[c];
3844 FORC4 if (dsum[c]) pre_mul[c] = dsum[c+4] / dsum[c];
3846 if (use_camera_wb && cam_mul[0] != -1) {
3847 memset (sum, 0, sizeof sum);
3848 for (row=0; row < 8; row++)
3849 for (col=0; col < 8; col++) {
3851 if ((val = white[row][col] - cblack[c]) > 0)
3855 if (sum[0] && sum[1] && sum[2] && sum[3])
3856 FORC4 pre_mul[c] = (float) sum[c+4] / sum[c];
3857 else if (cam_mul[0] && cam_mul[2])
3858 memcpy (pre_mul, cam_mul, sizeof pre_mul);
3860 fprintf (stderr,_("%s: Cannot use camera white balance.\n"), ifname);
3862 if (pre_mul[3] == 0) pre_mul[3] = colors < 4 ? pre_mul[1] : 1;
3865 if (threshold) wavelet_denoise();
3867 for (dmin=DBL_MAX, dmax=c=0; c < 4; c++) {
3868 if (dmin > pre_mul[c])
3870 if (dmax < pre_mul[c])
3873 if (!highlight) dmax = dmin;
3874 FORC4 scale_mul[c] = (pre_mul[c] /= dmax) * 65535.0 / maximum;
3877 _("Scaling with darkness %d, saturation %d, and\nmultipliers"), dark, sat);
3878 FORC4 fprintf (stderr, " %f", pre_mul[c]);
3879 fputc ('\n', stderr);
3881 size = iheight*iwidth;
3882 for (i=0; i < size*4; i++) {
3885 val -= cblack[i & 3];
3886 val *= scale_mul[i & 3];
3887 image[0][i] = CLIP(val);
3889 if ((aber[0] != 1 || aber[2] != 1) && colors == 3) {
3891 fprintf (stderr,_("Correcting chromatic aberration...\n"));
3892 for (c=0; c < 4; c+=2) {
3893 if (aber[c] == 1) continue;
3894 img = (ushort *) malloc (size * sizeof *img);
3895 merror (img, "scale_colors()");
3896 for (i=0; i < size; i++)
3897 img[i] = image[i][c];
3898 for (row=0; row < iheight; row++) {
3899 ur = fr = (row - iheight*0.5) * aber[c] + iheight*0.5;
3900 if (ur > iheight-2) continue;
3902 for (col=0; col < iwidth; col++) {
3903 uc = fc = (col - iwidth*0.5) * aber[c] + iwidth*0.5;
3904 if (uc > iwidth-2) continue;
3906 pix = img + ur*iwidth + uc;
3907 image[row*iwidth+col][c] =
3908 (pix[ 0]*(1-fc) + pix[ 1]*fc) * (1-fr) +
3909 (pix[iwidth]*(1-fc) + pix[iwidth+1]*fc) * fr;
3917 void CLASS pre_interpolate()
3927 img = (ushort (*)[4]) calloc (height*width, sizeof *img);
3928 merror (img, "pre_interpolate()");
3929 for (row=0; row < height; row++)
3930 for (col=0; col < width; col++) {
3932 img[row*width+col][c] = image[(row >> 1)*iwidth+(col >> 1)][c];
3939 if (filters > 1000 && colors == 3) {
3940 if (four_color_rgb && colors++)
3941 mix_green = !half_size;
3943 for (row = FC(1,0) >> 1; row < height; row+=2)
3944 for (col = FC(row,1) & 1; col < width; col+=2)
3945 image[row*width+col][1] = image[row*width+col][3];
3946 filters &= ~((filters & 0x55555555) << 1);
3949 if (half_size) filters = 0;
3952 void CLASS border_interpolate (int border)
3954 unsigned row, col, y, x, f, c, sum[8];
3956 for (row=0; row < height; row++)
3957 for (col=0; col < width; col++) {
3958 if (col==border && row >= border && row < height-border)
3960 memset (sum, 0, sizeof sum);
3961 for (y=row-1; y != row+2; y++)
3962 for (x=col-1; x != col+2; x++)
3963 if (y < height && x < width) {
3965 sum[f] += image[y*width+x][f];
3969 FORCC if (c != f && sum[c+4])
3970 image[row*width+col][c] = sum[c] / sum[c+4];
3974 void CLASS lin_interpolate()
3976 int code[16][16][32], size=16, *ip, sum[4];
3977 int f, c, i, x, y, row, col, shift, color;
3980 if (verbose) fprintf (stderr,_("Bilinear interpolation...\n"));
3981 if (filters == 2) size = 6;
3982 border_interpolate(1);
3983 for (row=0; row < size; row++)
3984 for (col=0; col < size; col++) {
3985 ip = code[row][col]+1;
3987 memset (sum, 0, sizeof sum);
3988 for (y=-1; y <= 1; y++)
3989 for (x=-1; x <= 1; x++) {
3990 shift = (y==0) + (x==0);
3991 color = fcol(row+y,col+x);
3992 if (color == f) continue;
3993 *ip++ = (width*y + x)*4 + color;
3996 sum[color] += 1 << shift;
3998 code[row][col][0] = (ip - code[row][col]) / 3;
4002 *ip++ = 256 / sum[c];
4005 for (row=1; row < height-1; row++)
4006 for (col=1; col < width-1; col++) {
4007 pix = image[row*width+col];
4008 ip = code[row % size][col % size];
4009 memset (sum, 0, sizeof sum);
4010 for (i=*ip++; i--; ip+=3)
4011 sum[ip[2]] += pix[ip[0]] << ip[1];
4012 for (i=colors; --i; ip+=2)
4013 pix[ip[0]] = sum[ip[0]] * ip[1] >> 8;
4018 This algorithm is officially called:
4020 "Interpolation using a Threshold-based variable number of gradients"
4022 described in http://scien.stanford.edu/pages/labsite/1999/psych221/projects/99/tingchen/algodep/vargra.html
4024 I've extended the basic idea to work with non-Bayer filter arrays.
4025 Gradients are numbered clockwise from NW=0 to W=7.
4027 void CLASS vng_interpolate()
4029 static const signed char *cp, terms[] = {
4030 -2,-2,+0,-1,0,0x01, -2,-2,+0,+0,1,0x01, -2,-1,-1,+0,0,0x01,
4031 -2,-1,+0,-1,0,0x02, -2,-1,+0,+0,0,0x03, -2,-1,+0,+1,1,0x01,
4032 -2,+0,+0,-1,0,0x06, -2,+0,+0,+0,1,0x02, -2,+0,+0,+1,0,0x03,
4033 -2,+1,-1,+0,0,0x04, -2,+1,+0,-1,1,0x04, -2,+1,+0,+0,0,0x06,
4034 -2,+1,+0,+1,0,0x02, -2,+2,+0,+0,1,0x04, -2,+2,+0,+1,0,0x04,
4035 -1,-2,-1,+0,0,0x80, -1,-2,+0,-1,0,0x01, -1,-2,+1,-1,0,0x01,
4036 -1,-2,+1,+0,1,0x01, -1,-1,-1,+1,0,0x88, -1,-1,+1,-2,0,0x40,
4037 -1,-1,+1,-1,0,0x22, -1,-1,+1,+0,0,0x33, -1,-1,+1,+1,1,0x11,
4038 -1,+0,-1,+2,0,0x08, -1,+0,+0,-1,0,0x44, -1,+0,+0,+1,0,0x11,
4039 -1,+0,+1,-2,1,0x40, -1,+0,+1,-1,0,0x66, -1,+0,+1,+0,1,0x22,
4040 -1,+0,+1,+1,0,0x33, -1,+0,+1,+2,1,0x10, -1,+1,+1,-1,1,0x44,
4041 -1,+1,+1,+0,0,0x66, -1,+1,+1,+1,0,0x22, -1,+1,+1,+2,0,0x10,
4042 -1,+2,+0,+1,0,0x04, -1,+2,+1,+0,1,0x04, -1,+2,+1,+1,0,0x04,
4043 +0,-2,+0,+0,1,0x80, +0,-1,+0,+1,1,0x88, +0,-1,+1,-2,0,0x40,
4044 +0,-1,+1,+0,0,0x11, +0,-1,+2,-2,0,0x40, +0,-1,+2,-1,0,0x20,
4045 +0,-1,+2,+0,0,0x30, +0,-1,+2,+1,1,0x10, +0,+0,+0,+2,1,0x08,
4046 +0,+0,+2,-2,1,0x40, +0,+0,+2,-1,0,0x60, +0,+0,+2,+0,1,0x20,
4047 +0,+0,+2,+1,0,0x30, +0,+0,+2,+2,1,0x10, +0,+1,+1,+0,0,0x44,
4048 +0,+1,+1,+2,0,0x10, +0,+1,+2,-1,1,0x40, +0,+1,+2,+0,0,0x60,
4049 +0,+1,+2,+1,0,0x20, +0,+1,+2,+2,0,0x10, +1,-2,+1,+0,0,0x80,
4050 +1,-1,+1,+1,0,0x88, +1,+0,+1,+2,0,0x08, +1,+0,+2,-1,0,0x40,
4052 }, chood[] = { -1,-1, -1,0, -1,+1, 0,+1, +1,+1, +1,0, +1,-1, 0,-1 };
4053 ushort (*brow[5])[4], *pix;
4054 int prow=8, pcol=2, *ip, *code[16][16], gval[8], gmin, gmax, sum[4];
4055 int row, col, x, y, x1, x2, y1, y2, t, weight, grads, color, diag;
4056 int g, diff, thold, num, c;
4059 if (verbose) fprintf (stderr,_("VNG interpolation...\n"));
4061 if (filters == 1) prow = pcol = 16;
4062 if (filters == 2) prow = pcol = 6;
4063 ip = (int *) calloc (prow*pcol, 1280);
4064 merror (ip, "vng_interpolate()");
4065 for (row=0; row < prow; row++) /* Precalculate for VNG */
4066 for (col=0; col < pcol; col++) {
4067 code[row][col] = ip;
4068 for (cp=terms, t=0; t < 64; t++) {
4069 y1 = *cp++; x1 = *cp++;
4070 y2 = *cp++; x2 = *cp++;
4073 color = fcol(row+y1,col+x1);
4074 if (fcol(row+y2,col+x2) != color) continue;
4075 diag = (fcol(row,col+1) == color && fcol(row+1,col) == color) ? 2:1;
4076 if (abs(y1-y2) == diag && abs(x1-x2) == diag) continue;
4077 *ip++ = (y1*width + x1)*4 + color;
4078 *ip++ = (y2*width + x2)*4 + color;
4080 for (g=0; g < 8; g++)
4081 if (grads & 1<<g) *ip++ = g;
4085 for (cp=chood, g=0; g < 8; g++) {
4086 y = *cp++; x = *cp++;
4087 *ip++ = (y*width + x) * 4;
4088 color = fcol(row,col);
4089 if (fcol(row+y,col+x) != color && fcol(row+y*2,col+x*2) == color)
4090 *ip++ = (y*width + x) * 8 + color;
4095 brow[4] = (ushort (*)[4]) calloc (width*3, sizeof **brow);
4096 merror (brow[4], "vng_interpolate()");
4097 for (row=0; row < 3; row++)
4098 brow[row] = brow[4] + row*width;
4099 for (row=2; row < height-2; row++) { /* Do VNG interpolation */
4100 for (col=2; col < width-2; col++) {
4101 pix = image[row*width+col];
4102 ip = code[row % prow][col % pcol];
4103 memset (gval, 0, sizeof gval);
4104 while ((g = ip[0]) != INT_MAX) { /* Calculate gradients */
4105 diff = ABS(pix[g] - pix[ip[1]]) << ip[2];
4106 gval[ip[3]] += diff;
4108 if ((g = ip[-1]) == -1) continue;
4110 while ((g = *ip++) != -1)
4114 gmin = gmax = gval[0]; /* Choose a threshold */
4115 for (g=1; g < 8; g++) {
4116 if (gmin > gval[g]) gmin = gval[g];
4117 if (gmax < gval[g]) gmax = gval[g];
4120 memcpy (brow[2][col], pix, sizeof *image);
4123 thold = gmin + (gmax >> 1);
4124 memset (sum, 0, sizeof sum);
4125 color = fcol(row,col);
4126 for (num=g=0; g < 8; g++,ip+=2) { /* Average the neighbors */
4127 if (gval[g] <= thold) {
4129 if (c == color && ip[1])
4130 sum[c] += (pix[c] + pix[ip[1]]) >> 1;
4132 sum[c] += pix[ip[0] + c];
4136 FORCC { /* Save to buffer */
4139 t += (sum[c] - sum[color]) / num;
4140 brow[2][col][c] = CLIP(t);
4143 if (row > 3) /* Write buffer to image */
4144 memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image);
4145 for (g=0; g < 4; g++)
4146 brow[(g-1) & 3] = brow[g];
4148 memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image);
4149 memcpy (image[(row-1)*width+2], brow[1]+2, (width-4)*sizeof *image);
4155 Patterned Pixel Grouping Interpolation by Alain Desbiolles
4157 void CLASS ppg_interpolate()
4159 int dir[5] = { 1, width, -1, -width, 1 };
4160 int row, col, diff[2], guess[2], c, d, i;
4163 border_interpolate(3);
4164 if (verbose) fprintf (stderr,_("PPG interpolation...\n"));
4166 /* Fill in the green layer with gradients and pattern recognition: */
4167 for (row=3; row < height-3; row++)
4168 for (col=3+(FC(row,3) & 1), c=FC(row,col); col < width-3; col+=2) {
4169 pix = image + row*width+col;
4170 for (i=0; (d=dir[i]) > 0; i++) {
4171 guess[i] = (pix[-d][1] + pix[0][c] + pix[d][1]) * 2
4172 - pix[-2*d][c] - pix[2*d][c];
4173 diff[i] = ( ABS(pix[-2*d][c] - pix[ 0][c]) +
4174 ABS(pix[ 2*d][c] - pix[ 0][c]) +
4175 ABS(pix[ -d][1] - pix[ d][1]) ) * 3 +
4176 ( ABS(pix[ 3*d][1] - pix[ d][1]) +
4177 ABS(pix[-3*d][1] - pix[-d][1]) ) * 2;
4179 d = dir[i = diff[0] > diff[1]];
4180 pix[0][1] = ULIM(guess[i] >> 2, pix[d][1], pix[-d][1]);
4182 /* Calculate red and blue for each green pixel: */
4183 for (row=1; row < height-1; row++)
4184 for (col=1+(FC(row,2) & 1), c=FC(row,col+1); col < width-1; col+=2) {
4185 pix = image + row*width+col;
4186 for (i=0; (d=dir[i]) > 0; c=2-c, i++)
4187 pix[0][c] = CLIP((pix[-d][c] + pix[d][c] + 2*pix[0][1]
4188 - pix[-d][1] - pix[d][1]) >> 1);
4190 /* Calculate blue for red pixels and vice versa: */
4191 for (row=1; row < height-1; row++)
4192 for (col=1+(FC(row,1) & 1), c=2-FC(row,col); col < width-1; col+=2) {
4193 pix = image + row*width+col;
4194 for (i=0; (d=dir[i]+dir[i+1]) > 0; i++) {
4195 diff[i] = ABS(pix[-d][c] - pix[d][c]) +
4196 ABS(pix[-d][1] - pix[0][1]) +
4197 ABS(pix[ d][1] - pix[0][1]);
4198 guess[i] = pix[-d][c] + pix[d][c] + 2*pix[0][1]
4199 - pix[-d][1] - pix[d][1];
4201 if (diff[0] != diff[1])
4202 pix[0][c] = CLIP(guess[diff[0] > diff[1]] >> 1);
4204 pix[0][c] = CLIP((guess[0]+guess[1]) >> 2);
4209 Adaptive Homogeneity-Directed interpolation is based on
4210 the work of Keigo Hirakawa, Thomas Parks, and Paul Lee.
4212 #define TS 256 /* Tile Size */
4214 void CLASS ahd_interpolate()
4216 int i, j, k, top, left, row, col, tr, tc, c, d, val, hm[2];
4217 ushort (*pix)[4], (*rix)[3];
4218 static const int dir[4] = { -1, 1, -TS, TS };
4219 unsigned ldiff[2][4], abdiff[2][4], leps, abeps;
4220 float r, cbrt[0x10000], xyz[3], xyz_cam[3][4];
4221 ushort (*rgb)[TS][TS][3];
4222 short (*lab)[TS][TS][3], (*lix)[3];
4223 char (*homo)[TS][TS], *buffer;
4225 if (verbose) fprintf (stderr,_("AHD interpolation...\n"));
4227 for (i=0; i < 0x10000; i++) {
4229 cbrt[i] = r > 0.008856 ? pow(r,1/3.0) : 7.787*r + 16/116.0;
4231 for (i=0; i < 3; i++)
4232 for (j=0; j < colors; j++)
4233 for (xyz_cam[i][j] = k=0; k < 3; k++)
4234 xyz_cam[i][j] += xyz_rgb[i][k] * rgb_cam[k][j] / d65_white[i];
4236 border_interpolate(5);
4237 buffer = (char *) malloc (26*TS*TS); /* 1664 kB */
4238 merror (buffer, "ahd_interpolate()");
4239 rgb = (ushort(*)[TS][TS][3]) buffer;
4240 lab = (short (*)[TS][TS][3])(buffer + 12*TS*TS);
4241 homo = (char (*)[TS][TS]) (buffer + 24*TS*TS);
4243 for (top=2; top < height-5; top += TS-6)
4244 for (left=2; left < width-5; left += TS-6) {
4246 /* Interpolate green horizontally and vertically: */
4247 for (row = top; row < top+TS && row < height-2; row++) {
4248 col = left + (FC(row,left) & 1);
4249 for (c = FC(row,col); col < left+TS && col < width-2; col+=2) {
4250 pix = image + row*width+col;
4251 val = ((pix[-1][1] + pix[0][c] + pix[1][1]) * 2
4252 - pix[-2][c] - pix[2][c]) >> 2;
4253 rgb[0][row-top][col-left][1] = ULIM(val,pix[-1][1],pix[1][1]);
4254 val = ((pix[-width][1] + pix[0][c] + pix[width][1]) * 2
4255 - pix[-2*width][c] - pix[2*width][c]) >> 2;
4256 rgb[1][row-top][col-left][1] = ULIM(val,pix[-width][1],pix[width][1]);
4259 /* Interpolate red and blue, and convert to CIELab: */
4260 for (d=0; d < 2; d++)
4261 for (row=top+1; row < top+TS-1 && row < height-3; row++)
4262 for (col=left+1; col < left+TS-1 && col < width-3; col++) {
4263 pix = image + row*width+col;
4264 rix = &rgb[d][row-top][col-left];
4265 lix = &lab[d][row-top][col-left];
4266 if ((c = 2 - FC(row,col)) == 1) {
4268 val = pix[0][1] + (( pix[-1][2-c] + pix[1][2-c]
4269 - rix[-1][1] - rix[1][1] ) >> 1);
4270 rix[0][2-c] = CLIP(val);
4271 val = pix[0][1] + (( pix[-width][c] + pix[width][c]
4272 - rix[-TS][1] - rix[TS][1] ) >> 1);
4274 val = rix[0][1] + (( pix[-width-1][c] + pix[-width+1][c]
4275 + pix[+width-1][c] + pix[+width+1][c]
4276 - rix[-TS-1][1] - rix[-TS+1][1]
4277 - rix[+TS-1][1] - rix[+TS+1][1] + 1) >> 2);
4278 rix[0][c] = CLIP(val);
4280 rix[0][c] = pix[0][c];
4281 xyz[0] = xyz[1] = xyz[2] = 0.5;
4283 xyz[0] += xyz_cam[0][c] * rix[0][c];
4284 xyz[1] += xyz_cam[1][c] * rix[0][c];
4285 xyz[2] += xyz_cam[2][c] * rix[0][c];
4287 xyz[0] = cbrt[CLIP((int) xyz[0])];
4288 xyz[1] = cbrt[CLIP((int) xyz[1])];
4289 xyz[2] = cbrt[CLIP((int) xyz[2])];
4290 lix[0][0] = 64 * (116 * xyz[1] - 16);
4291 lix[0][1] = 64 * 500 * (xyz[0] - xyz[1]);
4292 lix[0][2] = 64 * 200 * (xyz[1] - xyz[2]);
4294 /* Build homogeneity maps from the CIELab images: */
4295 memset (homo, 0, 2*TS*TS);
4296 for (row=top+2; row < top+TS-2 && row < height-4; row++) {
4298 for (col=left+2; col < left+TS-2 && col < width-4; col++) {
4300 for (d=0; d < 2; d++) {
4301 lix = &lab[d][tr][tc];
4302 for (i=0; i < 4; i++) {
4303 ldiff[d][i] = ABS(lix[0][0]-lix[dir[i]][0]);
4304 abdiff[d][i] = SQR(lix[0][1]-lix[dir[i]][1])
4305 + SQR(lix[0][2]-lix[dir[i]][2]);
4308 leps = MIN(MAX(ldiff[0][0],ldiff[0][1]),
4309 MAX(ldiff[1][2],ldiff[1][3]));
4310 abeps = MIN(MAX(abdiff[0][0],abdiff[0][1]),
4311 MAX(abdiff[1][2],abdiff[1][3]));
4312 for (d=0; d < 2; d++)
4313 for (i=0; i < 4; i++)
4314 if (ldiff[d][i] <= leps && abdiff[d][i] <= abeps)
4318 /* Combine the most homogenous pixels for the final result: */
4319 for (row=top+3; row < top+TS-3 && row < height-5; row++) {
4321 for (col=left+3; col < left+TS-3 && col < width-5; col++) {
4323 for (d=0; d < 2; d++)
4324 for (hm[d]=0, i=tr-1; i <= tr+1; i++)
4325 for (j=tc-1; j <= tc+1; j++)
4326 hm[d] += homo[d][i][j];
4328 FORC3 image[row*width+col][c] = rgb[hm[1] > hm[0]][tr][tc][c];
4330 FORC3 image[row*width+col][c] =
4331 (rgb[0][tr][tc][c] + rgb[1][tr][tc][c]) >> 1;
4339 void CLASS median_filter()
4342 int pass, c, i, j, k, med[9];
4343 static const uchar opt[] = /* Optimal 9-element median search */
4344 { 1,2, 4,5, 7,8, 0,1, 3,4, 6,7, 1,2, 4,5, 7,8,
4345 0,3, 5,8, 4,7, 3,6, 1,4, 2,5, 4,7, 4,2, 6,4, 4,2 };
4347 for (pass=1; pass <= med_passes; pass++) {
4349 fprintf (stderr,_("Median filter pass %d...\n"), pass);
4350 for (c=0; c < 3; c+=2) {
4351 for (pix = image; pix < image+width*height; pix++)
4352 pix[0][3] = pix[0][c];
4353 for (pix = image+width; pix < image+width*(height-1); pix++) {
4354 if ((pix-image+1) % width < 2) continue;
4355 for (k=0, i = -width; i <= width; i += width)
4356 for (j = i-1; j <= i+1; j++)
4357 med[k++] = pix[j][3] - pix[j][1];
4358 for (i=0; i < sizeof opt; i+=2)
4359 if (med[opt[i]] > med[opt[i+1]])
4360 SWAP (med[opt[i]] , med[opt[i+1]]);
4361 pix[0][c] = CLIP(med[4] + pix[0][1]);
4367 void CLASS blend_highlights()
4369 int clip=INT_MAX, row, col, c, i, j;
4370 static const float trans[2][4][4] =
4371 { { { 1,1,1 }, { 1.7320508,-1.7320508,0 }, { -1,-1,2 } },
4372 { { 1,1,1,1 }, { 1,-1,1,-1 }, { 1,1,-1,-1 }, { 1,-1,-1,1 } } };
4373 static const float itrans[2][4][4] =
4374 { { { 1,0.8660254,-0.5 }, { 1,-0.8660254,-0.5 }, { 1,0,1 } },
4375 { { 1,1,1,1 }, { 1,-1,1,-1 }, { 1,1,-1,-1 }, { 1,-1,-1,1 } } };
4376 float cam[2][4], lab[2][4], sum[2], chratio;
4378 if ((unsigned) (colors-3) > 1) return;
4379 if (verbose) fprintf (stderr,_("Blending highlights...\n"));
4380 FORCC if (clip > (i = 65535*pre_mul[c])) clip = i;
4381 for (row=0; row < height; row++)
4382 for (col=0; col < width; col++) {
4383 FORCC if (image[row*width+col][c] > clip) break;
4384 if (c == colors) continue;
4386 cam[0][c] = image[row*width+col][c];
4387 cam[1][c] = MIN(cam[0][c],clip);
4389 for (i=0; i < 2; i++) {
4390 FORCC for (lab[i][c]=j=0; j < colors; j++)
4391 lab[i][c] += trans[colors-3][c][j] * cam[i][j];
4392 for (sum[i]=0,c=1; c < colors; c++)
4393 sum[i] += SQR(lab[i][c]);
4395 chratio = sqrt(sum[1]/sum[0]);
4396 for (c=1; c < colors; c++)
4397 lab[0][c] *= chratio;
4398 FORCC for (cam[0][c]=j=0; j < colors; j++)
4399 cam[0][c] += itrans[colors-3][c][j] * lab[0][j];
4400 FORCC image[row*width+col][c] = cam[0][c] / colors;
4404 #define SCALE (4 >> shrink)
4405 void CLASS recover_highlights()
4407 float *map, sum, wgt, grow;
4408 int hsat[4], count, spread, change, val, i;
4409 unsigned high, wide, mrow, mcol, row, col, kc, c, d, y, x;
4411 static const signed char dir[8][2] =
4412 { {-1,-1}, {-1,0}, {-1,1}, {0,1}, {1,1}, {1,0}, {1,-1}, {0,-1} };
4414 if (verbose) fprintf (stderr,_("Rebuilding highlights...\n"));
4416 grow = pow (2, 4-highlight);
4417 FORCC hsat[c] = 32000 * pre_mul[c];
4418 for (kc=0, c=1; c < colors; c++)
4419 if (pre_mul[kc] < pre_mul[c]) kc = c;
4420 high = height / SCALE;
4421 wide = width / SCALE;
4422 map = (float *) calloc (high*wide, sizeof *map);
4423 merror (map, "recover_highlights()");
4424 FORCC if (c != kc) {
4425 memset (map, 0, high*wide*sizeof *map);
4426 for (mrow=0; mrow < high; mrow++)
4427 for (mcol=0; mcol < wide; mcol++) {
4428 sum = wgt = count = 0;
4429 for (row = mrow*SCALE; row < (mrow+1)*SCALE; row++)
4430 for (col = mcol*SCALE; col < (mcol+1)*SCALE; col++) {
4431 pixel = image[row*width+col];
4432 if (pixel[c] / hsat[c] == 1 && pixel[kc] > 24000) {
4438 if (count == SCALE*SCALE)
4439 map[mrow*wide+mcol] = sum / wgt;
4441 for (spread = 32/grow; spread--; ) {
4442 for (mrow=0; mrow < high; mrow++)
4443 for (mcol=0; mcol < wide; mcol++) {
4444 if (map[mrow*wide+mcol]) continue;
4446 for (d=0; d < 8; d++) {
4447 y = mrow + dir[d][0];
4448 x = mcol + dir[d][1];
4449 if (y < high && x < wide && map[y*wide+x] > 0) {
4450 sum += (1 + (d & 1)) * map[y*wide+x];
4451 count += 1 + (d & 1);
4455 map[mrow*wide+mcol] = - (sum+grow) / (count+grow);
4457 for (change=i=0; i < high*wide; i++)
4464 for (i=0; i < high*wide; i++)
4465 if (map[i] == 0) map[i] = 1;
4466 for (mrow=0; mrow < high; mrow++)
4467 for (mcol=0; mcol < wide; mcol++) {
4468 for (row = mrow*SCALE; row < (mrow+1)*SCALE; row++)
4469 for (col = mcol*SCALE; col < (mcol+1)*SCALE; col++) {
4470 pixel = image[row*width+col];
4471 if (pixel[c] / hsat[c] > 1) {
4472 val = pixel[kc] * map[mrow*wide+mcol];
4473 if (pixel[c] < val) pixel[c] = CLIP(val);
4482 void CLASS tiff_get (unsigned base,
4483 unsigned *tag, unsigned *type, unsigned *len, unsigned *save)
4488 *save = ftell(ifp) + 4;
4489 if (*len * ("11124811248488"[*type < 14 ? *type:0]-'0') > 4)
4490 fseek (ifp, get4()+base, SEEK_SET);
4493 void CLASS parse_thumb_note (int base, unsigned toff, unsigned tlen)
4495 unsigned entries, tag, type, len, save;
4499 tiff_get (base, &tag, &type, &len, &save);
4500 if (tag == toff) thumb_offset = get4()+base;
4501 if (tag == tlen) thumb_length = get4();
4502 fseek (ifp, save, SEEK_SET);
4506 int CLASS parse_tiff_ifd (int base);
4508 void CLASS parse_makernote (int base, int uptag)
4510 static const uchar xlat[2][256] = {
4511 { 0xc1,0xbf,0x6d,0x0d,0x59,0xc5,0x13,0x9d,0x83,0x61,0x6b,0x4f,0xc7,0x7f,0x3d,0x3d,
4512 0x53,0x59,0xe3,0xc7,0xe9,0x2f,0x95,0xa7,0x95,0x1f,0xdf,0x7f,0x2b,0x29,0xc7,0x0d,
4513 0xdf,0x07,0xef,0x71,0x89,0x3d,0x13,0x3d,0x3b,0x13,0xfb,0x0d,0x89,0xc1,0x65,0x1f,
4514 0xb3,0x0d,0x6b,0x29,0xe3,0xfb,0xef,0xa3,0x6b,0x47,0x7f,0x95,0x35,0xa7,0x47,0x4f,
4515 0xc7,0xf1,0x59,0x95,0x35,0x11,0x29,0x61,0xf1,0x3d,0xb3,0x2b,0x0d,0x43,0x89,0xc1,
4516 0x9d,0x9d,0x89,0x65,0xf1,0xe9,0xdf,0xbf,0x3d,0x7f,0x53,0x97,0xe5,0xe9,0x95,0x17,
4517 0x1d,0x3d,0x8b,0xfb,0xc7,0xe3,0x67,0xa7,0x07,0xf1,0x71,0xa7,0x53,0xb5,0x29,0x89,
4518 0xe5,0x2b,0xa7,0x17,0x29,0xe9,0x4f,0xc5,0x65,0x6d,0x6b,0xef,0x0d,0x89,0x49,0x2f,
4519 0xb3,0x43,0x53,0x65,0x1d,0x49,0xa3,0x13,0x89,0x59,0xef,0x6b,0xef,0x65,0x1d,0x0b,
4520 0x59,0x13,0xe3,0x4f,0x9d,0xb3,0x29,0x43,0x2b,0x07,0x1d,0x95,0x59,0x59,0x47,0xfb,
4521 0xe5,0xe9,0x61,0x47,0x2f,0x35,0x7f,0x17,0x7f,0xef,0x7f,0x95,0x95,0x71,0xd3,0xa3,
4522 0x0b,0x71,0xa3,0xad,0x0b,0x3b,0xb5,0xfb,0xa3,0xbf,0x4f,0x83,0x1d,0xad,0xe9,0x2f,
4523 0x71,0x65,0xa3,0xe5,0x07,0x35,0x3d,0x0d,0xb5,0xe9,0xe5,0x47,0x3b,0x9d,0xef,0x35,
4524 0xa3,0xbf,0xb3,0xdf,0x53,0xd3,0x97,0x53,0x49,0x71,0x07,0x35,0x61,0x71,0x2f,0x43,
4525 0x2f,0x11,0xdf,0x17,0x97,0xfb,0x95,0x3b,0x7f,0x6b,0xd3,0x25,0xbf,0xad,0xc7,0xc5,
4526 0xc5,0xb5,0x8b,0xef,0x2f,0xd3,0x07,0x6b,0x25,0x49,0x95,0x25,0x49,0x6d,0x71,0xc7 },
4527 { 0xa7,0xbc,0xc9,0xad,0x91,0xdf,0x85,0xe5,0xd4,0x78,0xd5,0x17,0x46,0x7c,0x29,0x4c,
4528 0x4d,0x03,0xe9,0x25,0x68,0x11,0x86,0xb3,0xbd,0xf7,0x6f,0x61,0x22,0xa2,0x26,0x34,
4529 0x2a,0xbe,0x1e,0x46,0x14,0x68,0x9d,0x44,0x18,0xc2,0x40,0xf4,0x7e,0x5f,0x1b,0xad,
4530 0x0b,0x94,0xb6,0x67,0xb4,0x0b,0xe1,0xea,0x95,0x9c,0x66,0xdc,0xe7,0x5d,0x6c,0x05,
4531 0xda,0xd5,0xdf,0x7a,0xef,0xf6,0xdb,0x1f,0x82,0x4c,0xc0,0x68,0x47,0xa1,0xbd,0xee,
4532 0x39,0x50,0x56,0x4a,0xdd,0xdf,0xa5,0xf8,0xc6,0xda,0xca,0x90,0xca,0x01,0x42,0x9d,
4533 0x8b,0x0c,0x73,0x43,0x75,0x05,0x94,0xde,0x24,0xb3,0x80,0x34,0xe5,0x2c,0xdc,0x9b,
4534 0x3f,0xca,0x33,0x45,0xd0,0xdb,0x5f,0xf5,0x52,0xc3,0x21,0xda,0xe2,0x22,0x72,0x6b,
4535 0x3e,0xd0,0x5b,0xa8,0x87,0x8c,0x06,0x5d,0x0f,0xdd,0x09,0x19,0x93,0xd0,0xb9,0xfc,
4536 0x8b,0x0f,0x84,0x60,0x33,0x1c,0x9b,0x45,0xf1,0xf0,0xa3,0x94,0x3a,0x12,0x77,0x33,
4537 0x4d,0x44,0x78,0x28,0x3c,0x9e,0xfd,0x65,0x57,0x16,0x94,0x6b,0xfb,0x59,0xd0,0xc8,
4538 0x22,0x36,0xdb,0xd2,0x63,0x98,0x43,0xa1,0x04,0x87,0x86,0xf7,0xa6,0x26,0xbb,0xd6,
4539 0x59,0x4d,0xbf,0x6a,0x2e,0xaa,0x2b,0xef,0xe6,0x78,0xb6,0x4e,0xe0,0x2f,0xdc,0x7c,
4540 0xbe,0x57,0x19,0x32,0x7e,0x2a,0xd0,0xb8,0xba,0x29,0x00,0x3c,0x52,0x7d,0xa8,0x49,
4541 0x3b,0x2d,0xeb,0x25,0x49,0xfa,0xa3,0xaa,0x39,0xa7,0xc5,0xa7,0x50,0x11,0x36,0xfb,
4542 0xc6,0x67,0x4a,0xf5,0xa5,0x12,0x65,0x7e,0xb0,0xdf,0xaf,0x4e,0xb3,0x61,0x7f,0x2f } };
4543 unsigned offset=0, entries, tag, type, len, save, c;
4544 unsigned ver97=0, serial=0, i, wbi=0, wb[4]={0,0,0,0};
4545 uchar buf97[324], ci, cj, ck;
4546 short morder, sorder=order;
4549 The MakerNote might have its own TIFF header (possibly with
4550 its own byte-order!), or it might just be a table.
4552 if (!strcmp(make,"Nokia")) return;
4553 fread (buf, 1, 10, ifp);
4554 if (!strncmp (buf,"KDK" ,3) || /* these aren't TIFF tables */
4555 !strncmp (buf,"VER" ,3) ||
4556 !strncmp (buf,"IIII",4) ||
4557 !strncmp (buf,"MMMM",4)) return;
4558 if (!strncmp (buf,"KC" ,2) || /* Konica KD-400Z, KD-510Z */
4559 !strncmp (buf,"MLY" ,3)) { /* Minolta DiMAGE G series */
4561 while ((i=ftell(ifp)) < data_offset && i < 16384) {
4562 wb[0] = wb[2]; wb[2] = wb[1]; wb[1] = wb[3];
4564 if (wb[1] == 256 && wb[3] == 256 &&
4565 wb[0] > 256 && wb[0] < 640 && wb[2] > 256 && wb[2] < 640)
4566 FORC4 cam_mul[c] = wb[c];
4570 if (!strcmp (buf,"Nikon")) {
4573 if (get2() != 42) goto quit;
4575 fseek (ifp, offset-8, SEEK_CUR);
4576 } else if (!strcmp (buf,"OLYMPUS")) {
4577 base = ftell(ifp)-10;
4578 fseek (ifp, -2, SEEK_CUR);
4579 order = get2(); get2();
4580 } else if (!strncmp (buf,"SONY",4) ||
4581 !strcmp (buf,"Panasonic")) {
4583 } else if (!strncmp (buf,"FUJIFILM",8)) {
4584 base = ftell(ifp)-10;
4586 fseek (ifp, 2, SEEK_CUR);
4587 } else if (!strcmp (buf,"OLYMP") ||
4588 !strcmp (buf,"LEICA") ||
4589 !strcmp (buf,"Ricoh") ||
4590 !strcmp (buf,"EPSON"))
4591 fseek (ifp, -2, SEEK_CUR);
4592 else if (!strcmp (buf,"AOC") ||
4593 !strcmp (buf,"QVC"))
4594 fseek (ifp, -4, SEEK_CUR);
4596 fseek (ifp, -10, SEEK_CUR);
4597 if (!strncmp(make,"SAMSUNG",7))
4601 if (entries > 1000) return;
4605 tiff_get (base, &tag, &type, &len, &save);
4607 if (tag == 2 && strstr(make,"NIKON") && !iso_speed)
4608 iso_speed = (get2(),get2());
4609 if (tag == 4 && len > 26 && len < 35) {
4610 if ((i=(get4(),get2())) != 0x7fff && !iso_speed)
4611 iso_speed = 50 * pow (2, i/32.0 - 4);
4612 if ((i=(get2(),get2())) != 0x7fff && !aperture)
4613 aperture = pow (2, i/64.0);
4614 if ((i=get2()) != 0xffff && !shutter)
4615 shutter = pow (2, (short) i/-32.0);
4616 wbi = (get2(),get2());
4617 shot_order = (get2(),get2());
4619 if ((tag == 4 || tag == 0x114) && !strncmp(make,"KONICA",6)) {
4620 fseek (ifp, tag == 4 ? 140:160, SEEK_CUR);
4622 case 72: flip = 0; break;
4623 case 76: flip = 6; break;
4624 case 82: flip = 5; break;
4627 if (tag == 7 && type == 2 && len > 20)
4628 fgets (model2, 64, ifp);
4629 if (tag == 8 && type == 4)
4630 shot_order = get4();
4631 if (tag == 9 && !strcmp(make,"Canon"))
4632 fread (artist, 64, 1, ifp);
4633 if (tag == 0xc && len == 4) {
4634 cam_mul[0] = getreal(type);
4635 cam_mul[2] = getreal(type);
4637 if (tag == 0xd && type == 7 && get2() == 0xaaaa) {
4638 for (c=i=2; (ushort) c != 0xbbbb && i < len; i++)
4639 c = c << 8 | fgetc(ifp);
4640 while ((i+=4) < len-5)
4641 if (get4() == 257 && (i=len) && (c = (get4(),fgetc(ifp))) < 3)
4642 flip = "065"[c]-'0';
4644 if (tag == 0x10 && type == 4)
4646 if (tag == 0x11 && is_raw && !strncmp(make,"NIKON",5)) {
4647 fseek (ifp, get4()+base, SEEK_SET);
4648 parse_tiff_ifd (base);
4650 if (tag == 0x14 && type == 7) {
4652 fseek (ifp, 1248, SEEK_CUR);
4655 fread (buf, 1, 10, ifp);
4656 if (!strncmp(buf,"NRW ",4)) {
4657 fseek (ifp, strcmp(buf+4,"0100") ? 46:1546, SEEK_CUR);
4658 cam_mul[0] = get4() << 2;
4659 cam_mul[1] = get4() + get4();
4660 cam_mul[2] = get4() << 2;
4663 if (tag == 0x15 && type == 2 && is_raw)
4664 fread (model, 64, 1, ifp);
4665 if (strstr(make,"PENTAX")) {
4666 if (tag == 0x1b) tag = 0x1018;
4667 if (tag == 0x1c) tag = 0x1017;
4670 while ((c = fgetc(ifp)) && c != EOF)
4671 serial = serial*10 + (isdigit(c) ? c - '0' : c % 10);
4672 if (tag == 0x81 && type == 4) {
4673 data_offset = get4();
4674 fseek (ifp, data_offset + 41, SEEK_SET);
4675 raw_height = get2() * 2;
4677 filters = 0x61616161;
4679 if (tag == 0x29 && type == 1) {
4680 c = wbi < 18 ? "012347800000005896"[wbi]-'0' : 0;
4681 fseek (ifp, 8 + c*32, SEEK_CUR);
4682 FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get4();
4684 if ((tag == 0x81 && type == 7) ||
4685 (tag == 0x100 && type == 7) ||
4686 (tag == 0x280 && type == 1)) {
4687 thumb_offset = ftell(ifp);
4690 if (tag == 0x88 && type == 4 && (thumb_offset = get4()))
4691 thumb_offset += base;
4692 if (tag == 0x89 && type == 4)
4693 thumb_length = get4();
4694 if (tag == 0x8c || tag == 0x96)
4695 meta_offset = ftell(ifp);
4697 for (i=0; i < 4; i++)
4698 ver97 = ver97 * 10 + fgetc(ifp)-'0';
4701 fseek (ifp, 68, SEEK_CUR);
4702 FORC4 cam_mul[(c >> 1) | ((c & 1) << 1)] = get2();
4705 fseek (ifp, 6, SEEK_CUR);
4708 fseek (ifp, 16, SEEK_CUR);
4709 FORC4 cam_mul[c] = get2();
4712 if (ver97 != 205) fseek (ifp, 280, SEEK_CUR);
4713 fread (buf97, 324, 1, ifp);
4716 if (tag == 0xa1 && type == 7) {
4718 fseek (ifp, 140, SEEK_CUR);
4719 FORC3 cam_mul[c] = get4();
4721 if (tag == 0xa4 && type == 3) {
4722 fseek (ifp, wbi*48, SEEK_CUR);
4723 FORC3 cam_mul[c] = get2();
4725 if (tag == 0xa7 && (unsigned) (ver97-200) < 17) {
4726 ci = xlat[0][serial & 0xff];
4727 cj = xlat[1][fgetc(ifp)^fgetc(ifp)^fgetc(ifp)^fgetc(ifp)];
4729 for (i=0; i < 324; i++)
4730 buf97[i] ^= (cj += ci * ck++);
4731 i = "66666>666;6A;:;55"[ver97-200] - '0';
4732 FORC4 cam_mul[c ^ (c >> 1) ^ (i & 1)] =
4733 sget2 (buf97 + (i & -2) + c*2);
4735 if (tag == 0x200 && len == 3)
4736 shot_order = (get4(),get4());
4737 if (tag == 0x200 && len == 4)
4738 FORC4 cblack[c ^ c >> 1] = get2();
4739 if (tag == 0x201 && len == 4)
4741 if (tag == 0x220 && type == 7)
4742 meta_offset = ftell(ifp);
4743 if (tag == 0x401 && type == 4 && len == 4)
4744 FORC4 cblack[c ^ c >> 1] = get4();
4745 if (tag == 0xe01) { /* Nikon Capture Note */
4747 fseek (ifp, 22, SEEK_CUR);
4748 for (offset=22; offset+22 < len; offset += 22+i) {
4750 fseek (ifp, 14, SEEK_CUR);
4752 if (tag == 0x76a43207) flip = get2();
4753 else fseek (ifp, i, SEEK_CUR);
4756 if (tag == 0xe80 && len == 256 && type == 7) {
4757 fseek (ifp, 48, SEEK_CUR);
4758 cam_mul[0] = get2() * 508 * 1.078 / 0x10000;
4759 cam_mul[2] = get2() * 382 * 1.173 / 0x10000;
4761 if (tag == 0xf00 && type == 7) {
4763 fseek (ifp, 176, SEEK_CUR);
4764 else if (len == 734 || len == 1502)
4765 fseek (ifp, 148, SEEK_CUR);
4769 if ((tag == 0x1011 && len == 9) || tag == 0x20400200)
4770 for (i=0; i < 3; i++)
4771 FORC3 cmatrix[i][c] = ((short) get2()) / 256.0;
4772 if ((tag == 0x1012 || tag == 0x20400600) && len == 4)
4773 FORC4 cblack[c ^ c >> 1] = get2();
4774 if (tag == 0x1017 || tag == 0x20400100)
4775 cam_mul[0] = get2() / 256.0;
4776 if (tag == 0x1018 || tag == 0x20400100)
4777 cam_mul[2] = get2() / 256.0;
4778 if (tag == 0x2011 && len == 2) {
4781 cam_mul[0] = get2() / 256.0;
4782 cam_mul[2] = get2() / 256.0;
4784 if ((tag | 0x70) == 0x2070 && type == 4)
4785 fseek (ifp, get4()+base, SEEK_SET);
4786 if (tag == 0x2010 && type != 7)
4787 load_raw = &CLASS olympus_load_raw;
4789 parse_thumb_note (base, 257, 258);
4791 parse_makernote (base, 0x2040);
4792 if (tag == 0xb028) {
4793 fseek (ifp, get4()+base, SEEK_SET);
4794 parse_thumb_note (base, 136, 137);
4796 if (tag == 0x4001 && len > 500) {
4797 i = len == 582 ? 50 : len == 653 ? 68 : len == 5120 ? 142 : 126;
4798 fseek (ifp, i, SEEK_CUR);
4800 FORC4 cam_mul[c ^ (c >> 1)] = get2();
4801 i = len >> 3 == 164 ? 112:22;
4802 fseek (ifp, i, SEEK_CUR);
4803 FORC4 sraw_mul[c ^ (c >> 1)] = get2();
4806 FORC4 cam_mul[c ^ (c >> 1)] = get4();
4808 FORC4 cam_mul[c ^ (c >> 1)] -= get4();
4810 fseek (ifp, save, SEEK_SET);
4817 Since the TIFF DateTime string has no timezone information,
4818 assume that the camera's clock was set to Universal Time.
4820 void CLASS get_timestamp (int reversed)
4828 for (i=19; i--; ) str[i] = fgetc(ifp);
4830 fread (str, 19, 1, ifp);
4831 memset (&t, 0, sizeof t);
4832 if (sscanf (str, "%d:%d:%d %d:%d:%d", &t.tm_year, &t.tm_mon,
4833 &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec) != 6)
4839 timestamp = mktime(&t);
4842 void CLASS parse_exif (int base)
4844 unsigned kodak, entries, tag, type, len, save, c;
4847 kodak = !strncmp(make,"EASTMAN",7) && tiff_nifds < 3;
4850 tiff_get (base, &tag, &type, &len, &save);
4852 case 33434: shutter = getreal(type); break;
4853 case 33437: aperture = getreal(type); break;
4854 case 34855: iso_speed = get2(); break;
4856 case 36868: get_timestamp(0); break;
4857 case 37377: if ((expo = -getreal(type)) < 128)
4858 shutter = pow (2, expo); break;
4859 case 37378: aperture = pow (2, getreal(type)/2); break;
4860 case 37386: focal_len = getreal(type); break;
4861 case 37500: parse_makernote (base, 0); break;
4862 case 40962: if (kodak) raw_width = get4(); break;
4863 case 40963: if (kodak) raw_height = get4(); break;
4865 if (get4() == 0x20002)
4866 for (exif_cfa=c=0; c < 8; c+=2)
4867 exif_cfa |= fgetc(ifp) * 0x01010101 << c;
4869 fseek (ifp, save, SEEK_SET);
4873 void CLASS parse_gps (int base)
4875 unsigned entries, tag, type, len, save, c;
4879 tiff_get (base, &tag, &type, &len, &save);
4881 case 1: case 3: case 5:
4882 gpsdata[29+tag/2] = getc(ifp); break;
4883 case 2: case 4: case 7:
4884 FORC(6) gpsdata[tag/3*6+c] = get4(); break;
4886 FORC(2) gpsdata[18+c] = get4(); break;
4888 fgets ((char *) (gpsdata+14+tag/3), MIN(len,12), ifp);
4890 fseek (ifp, save, SEEK_SET);
4894 void CLASS romm_coeff (float romm_cam[3][3])
4896 static const float rgb_romm[3][3] = /* ROMM == Kodak ProPhoto */
4897 { { 2.034193, -0.727420, -0.306766 },
4898 { -0.228811, 1.231729, -0.002922 },
4899 { -0.008565, -0.153273, 1.161839 } };
4902 for (i=0; i < 3; i++)
4903 for (j=0; j < 3; j++)
4904 for (cmatrix[i][j] = k=0; k < 3; k++)
4905 cmatrix[i][j] += rgb_romm[i][k] * romm_cam[k][j];
4908 void CLASS parse_mos (int offset)
4911 int skip, from, i, c, neut[4], planes=0, frot=0;
4912 static const char *mod[] =
4913 { "","DCB2","Volare","Cantare","CMost","Valeo 6","Valeo 11","Valeo 22",
4914 "Valeo 11p","Valeo 17","","Aptus 17","Aptus 22","Aptus 75","Aptus 65",
4915 "Aptus 54S","Aptus 65S","Aptus 75S","AFi 5","AFi 6","AFi 7",
4916 "","","","","","","","","","","","","","","","","","AFi-II 12" };
4917 float romm_cam[3][3];
4919 fseek (ifp, offset, SEEK_SET);
4921 if (get4() != 0x504b5453) break;
4923 fread (data, 1, 40, ifp);
4926 if (!strcmp(data,"JPEG_preview_data")) {
4927 thumb_offset = from;
4928 thumb_length = skip;
4930 if (!strcmp(data,"icc_camera_profile")) {
4931 profile_offset = from;
4932 profile_length = skip;
4934 if (!strcmp(data,"ShootObj_back_type")) {
4935 fscanf (ifp, "%d", &i);
4936 if ((unsigned) i < sizeof mod / sizeof (*mod))
4937 strcpy (model, mod[i]);
4939 if (!strcmp(data,"icc_camera_to_tone_matrix")) {
4940 for (i=0; i < 9; i++)
4941 romm_cam[0][i] = int_to_float(get4());
4942 romm_coeff (romm_cam);
4944 if (!strcmp(data,"CaptProf_color_matrix")) {
4945 for (i=0; i < 9; i++)
4946 fscanf (ifp, "%f", &romm_cam[0][i]);
4947 romm_coeff (romm_cam);
4949 if (!strcmp(data,"CaptProf_number_of_planes"))
4950 fscanf (ifp, "%d", &planes);
4951 if (!strcmp(data,"CaptProf_raw_data_rotation"))
4952 fscanf (ifp, "%d", &flip);
4953 if (!strcmp(data,"CaptProf_mosaic_pattern"))
4955 fscanf (ifp, "%d", &i);
4956 if (i == 1) frot = c ^ (c >> 1);
4958 if (!strcmp(data,"ImgProf_rotation_angle")) {
4959 fscanf (ifp, "%d", &i);
4962 if (!strcmp(data,"NeutObj_neutrals") && !cam_mul[0]) {
4963 FORC4 fscanf (ifp, "%d", neut+c);
4964 FORC3 cam_mul[c] = (float) neut[0] / neut[c+1];
4966 if (!strcmp(data,"Rows_data"))
4967 load_flags = get4();
4969 fseek (ifp, skip+from, SEEK_SET);
4972 filters = (planes == 1) * 0x01010101 *
4973 (uchar) "\x94\x61\x16\x49"[(flip/90 + frot) & 3];
4976 void CLASS linear_table (unsigned len)
4979 if (len > 0x1000) len = 0x1000;
4980 read_shorts (curve, len);
4981 for (i=len; i < 0x1000; i++)
4982 curve[i] = curve[i-1];
4983 maximum = curve[0xfff];
4986 void CLASS parse_kodak_ifd (int base)
4988 unsigned entries, tag, type, len, save;
4989 int i, c, wbi=-2, wbtemp=6500;
4990 float mul[3]={1,1,1}, num;
4991 static const int wbtag[] = { 64037,64040,64039,64041,-1,-1,64042 };
4994 if (entries > 1024) return;
4996 tiff_get (base, &tag, &type, &len, &save);
4997 if (tag == 1020) wbi = getint(type);
4998 if (tag == 1021 && len == 72) { /* WB set in software */
4999 fseek (ifp, 40, SEEK_CUR);
5000 FORC3 cam_mul[c] = 2048.0 / get2();
5003 if (tag == 2118) wbtemp = getint(type);
5004 if (tag == 2130 + wbi)
5005 FORC3 mul[c] = getreal(type);
5006 if (tag == 2140 + wbi && wbi >= 0)
5008 for (num=i=0; i < 4; i++)
5009 num += getreal(type) * pow (wbtemp/100.0, i);
5010 cam_mul[c] = 2048 / (num * mul[c]);
5012 if (tag == 2317) linear_table (len);
5013 if (tag == 6020) iso_speed = getint(type);
5014 if (tag == 64013) wbi = fgetc(ifp);
5015 if ((unsigned) wbi < 7 && tag == wbtag[wbi])
5016 FORC3 cam_mul[c] = get4();
5017 if (tag == 64019) width = getint(type);
5018 if (tag == 64020) height = (getint(type)+1) & -2;
5019 fseek (ifp, save, SEEK_SET);
5023 void CLASS parse_minolta (int base);
5024 int CLASS parse_tiff (int base);
5026 int CLASS parse_tiff_ifd (int base)
5028 unsigned entries, tag, type, len, plen=16, save;
5029 int ifd, use_cm=0, cfa, i, j, c, ima_len=0;
5030 int blrr=1, blrc=1, dblack[] = { 0,0,0,0 };
5031 char software[64], *cbuf, *cp;
5032 uchar cfa_pat[16], cfa_pc[] = { 0,1,2,3 }, tab[256];
5033 double cc[4][4], cm[4][3], cam_xyz[4][3], num;
5034 double ab[]={ 1,1,1,1 }, asn[] = { 0,0,0,0 }, xyz[] = { 1,1,1 };
5035 unsigned sony_curve[] = { 0,0,0,0,0,4095 };
5036 unsigned *buf, sony_offset=0, sony_length=0, sony_key=0;
5040 if (tiff_nifds >= sizeof tiff_ifd / sizeof tiff_ifd[0])
5043 for (j=0; j < 4; j++)
5044 for (i=0; i < 4; i++)
5047 if (entries > 512) return 1;
5049 tiff_get (base, &tag, &type, &len, &save);
5051 case 5: width = get2(); break;
5052 case 6: height = get2(); break;
5053 case 7: width += get2(); break;
5054 case 9: filters = get2(); break;
5056 if (type == 3 && len == 1)
5057 cam_mul[(tag-17)*2] = get2() / 256.0;
5060 if (type == 3) iso_speed = get2();
5062 case 36: case 37: case 38:
5063 cam_mul[tag-0x24] = get2();
5066 if (len < 50 || cam_mul[0]) break;
5067 fseek (ifp, 12, SEEK_CUR);
5068 FORC3 cam_mul[c] = get2();
5071 if (type != 7 || fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) break;
5072 thumb_offset = ftell(ifp) - 2;
5075 case 61440: /* Fuji HS10 table */
5076 parse_tiff_ifd (base);
5078 case 2: case 256: case 61441: /* ImageWidth */
5079 tiff_ifd[ifd].width = getint(type);
5081 case 3: case 257: case 61442: /* ImageHeight */
5082 tiff_ifd[ifd].height = getint(type);
5084 case 258: /* BitsPerSample */
5086 tiff_ifd[ifd].samples = len & 7;
5087 tiff_ifd[ifd].bps = getint(type);
5091 load_raw = &CLASS packed_load_raw;
5092 load_flags = get4() && (filters=0x16161616) ? 24:80;
5094 case 259: /* Compression */
5095 tiff_ifd[ifd].comp = getint(type);
5097 case 262: /* PhotometricInterpretation */
5098 tiff_ifd[ifd].phint = get2();
5100 case 270: /* ImageDescription */
5101 fread (desc, 512, 1, ifp);
5103 case 271: /* Make */
5104 fgets (make, 64, ifp);
5106 case 272: /* Model */
5107 fgets (model, 64, ifp);
5109 case 280: /* Panasonic RW2 offset */
5110 if (type != 4) break;
5111 load_raw = &CLASS panasonic_load_raw;
5112 load_flags = 0x2008;
5113 case 273: /* StripOffset */
5114 case 513: /* JpegIFOffset */
5116 tiff_ifd[ifd].offset = get4()+base;
5117 if (!tiff_ifd[ifd].bps && tiff_ifd[ifd].offset > 0) {
5118 fseek (ifp, tiff_ifd[ifd].offset, SEEK_SET);
5119 if (ljpeg_start (&jh, 1)) {
5120 tiff_ifd[ifd].comp = 6;
5121 tiff_ifd[ifd].width = jh.wide;
5122 tiff_ifd[ifd].height = jh.high;
5123 tiff_ifd[ifd].bps = jh.bits;
5124 tiff_ifd[ifd].samples = jh.clrs;
5125 if (!(jh.sraw || (jh.clrs & 1)))
5126 tiff_ifd[ifd].width *= jh.clrs;
5128 parse_tiff (tiff_ifd[ifd].offset + 12);
5133 case 274: /* Orientation */
5134 tiff_ifd[ifd].flip = "50132467"[get2() & 7]-'0';
5136 case 277: /* SamplesPerPixel */
5137 tiff_ifd[ifd].samples = getint(type) & 7;
5139 case 279: /* StripByteCounts */
5142 tiff_ifd[ifd].bytes = get4();
5145 FORC3 cam_mul[(4-c) % 3] = getint(type);
5147 case 305: case 11: /* Software */
5148 fgets (software, 64, ifp);
5149 if (!strncmp(software,"Adobe",5) ||
5150 !strncmp(software,"dcraw",5) ||
5151 !strncmp(software,"UFRaw",5) ||
5152 !strncmp(software,"Bibble",6) ||
5153 !strncmp(software,"Nikon Scan",10) ||
5154 !strcmp (software,"Digital Photo Professional"))
5157 case 306: /* DateTime */
5160 case 315: /* Artist */
5161 fread (artist, 64, 1, ifp);
5163 case 322: /* TileWidth */
5164 tiff_ifd[ifd].tile_width = getint(type);
5166 case 323: /* TileLength */
5167 tiff_ifd[ifd].tile_length = getint(type);
5169 case 324: /* TileOffsets */
5170 tiff_ifd[ifd].offset = len > 1 ? ftell(ifp) : get4();
5172 load_raw = &CLASS sinar_4shot_load_raw;
5176 case 330: /* SubIFDs */
5177 if (!strcmp(model,"DSLR-A100") && tiff_ifd[ifd].width == 3872) {
5178 load_raw = &CLASS sony_arw_load_raw;
5179 data_offset = get4()+base;
5184 fseek (ifp, get4()+base, SEEK_SET);
5185 if (parse_tiff_ifd (base)) break;
5186 fseek (ifp, i+4, SEEK_SET);
5190 strcpy (make, "Sarnoff");
5194 FORC4 sony_curve[c+1] = get2() >> 2 & 0xfff;
5195 for (i=0; i < 5; i++)
5196 for (j = sony_curve[i]+1; j <= sony_curve[i+1]; j++)
5197 curve[j] = curve[j-1] + (1 << i);
5199 case 29184: sony_offset = get4(); break;
5200 case 29185: sony_length = get4(); break;
5201 case 29217: sony_key = get4(); break;
5203 parse_minolta (ftell(ifp));
5207 FORC4 cam_mul[c ^ (c < 2)] = get2();
5210 FORC4 cam_mul[c] = get2();
5211 i = (cam_mul[1] == 1024 && cam_mul[2] == 1024) << 1;
5212 SWAP (cam_mul[i],cam_mul[i+1])
5214 case 33405: /* Model2 */
5215 fgets (model2, 64, ifp);
5217 case 33422: /* CFAPattern */
5218 case 64777: /* Kodak P-series */
5219 if ((plen=len) > 16) plen = 16;
5220 fread (cfa_pat, 1, plen, ifp);
5221 for (colors=cfa=i=0; i < plen; i++) {
5222 colors += !(cfa & (1 << cfa_pat[i]));
5223 cfa |= 1 << cfa_pat[i];
5225 if (cfa == 070) memcpy (cfa_pc,"\003\004\005",3); /* CMY */
5226 if (cfa == 072) memcpy (cfa_pc,"\005\003\004\001",4); /* GMCY */
5230 fseek (ifp, get4()+base, SEEK_SET);
5231 parse_kodak_ifd (base);
5233 case 33434: /* ExposureTime */
5234 shutter = getreal(type);
5236 case 33437: /* FNumber */
5237 aperture = getreal(type);
5239 case 34306: /* Leaf white balance */
5240 FORC4 cam_mul[c ^ 1] = 4096.0 / get2();
5242 case 34307: /* Leaf CatchLight color matrix */
5243 fread (software, 1, 7, ifp);
5244 if (strncmp(software,"MATRIX",6)) break;
5246 for (raw_color = i=0; i < 3; i++) {
5247 FORC4 fscanf (ifp, "%f", &rgb_cam[i][c^1]);
5248 if (!use_camera_wb) continue;
5250 FORC4 num += rgb_cam[i][c];
5251 FORC4 rgb_cam[i][c] /= num;
5254 case 34310: /* Leaf metadata */
5255 parse_mos (ftell(ifp));
5257 strcpy (make, "Leaf");
5259 case 34665: /* EXIF tag */
5260 fseek (ifp, get4()+base, SEEK_SET);
5263 case 34853: /* GPSInfo tag */
5264 fseek (ifp, get4()+base, SEEK_SET);
5267 case 34675: /* InterColorProfile */
5268 case 50831: /* AsShotICCProfile */
5269 profile_offset = ftell(ifp);
5270 profile_length = len;
5272 case 37122: /* CompressedBitsPerPixel */
5273 kodak_cbpp = get4();
5275 case 37386: /* FocalLength */
5276 focal_len = getreal(type);
5278 case 37393: /* ImageNumber */
5279 shot_order = getint(type);
5281 case 37400: /* old Kodak KDC tag */
5282 for (raw_color = i=0; i < 3; i++) {
5284 FORC3 rgb_cam[i][c] = getreal(type);
5287 case 46275: /* Imacon tags */
5288 strcpy (make, "Imacon");
5289 data_offset = ftell(ifp);
5293 if (!ima_len) break;
5294 fseek (ifp, 38, SEEK_CUR);
5296 fseek (ifp, 40, SEEK_CUR);
5298 raw_height = get4();
5299 left_margin = get4() & 7;
5300 width = raw_width - left_margin - (get4() & 7);
5301 top_margin = get4() & 7;
5302 height = raw_height - top_margin - (get4() & 7);
5303 if (raw_width == 7262) {
5308 fseek (ifp, 52, SEEK_CUR);
5309 FORC3 cam_mul[c] = getreal(11);
5310 fseek (ifp, 114, SEEK_CUR);
5311 flip = (get2() >> 7) * 90;
5312 if (width * height * 6 == ima_len) {
5313 if (flip % 180 == 90) SWAP(width,height);
5315 raw_height = height;
5316 left_margin = top_margin = filters = flip = 0;
5318 sprintf (model, "Ixpress %d-Mp", height*width/1000000);
5319 load_raw = &CLASS imacon_full_load_raw;
5321 if (left_margin & 1) filters = 0x61616161;
5322 load_raw = &CLASS unpacked_load_raw;
5326 case 50454: /* Sinar tag */
5328 if (!(cbuf = (char *) malloc(len))) break;
5329 fread (cbuf, 1, len, ifp);
5330 for (cp = cbuf-1; cp && cp < cbuf+len; cp = strchr(cp,'\n'))
5331 if (!strncmp (++cp,"Neutral ",8))
5332 sscanf (cp+8, "%f %f %f", cam_mul, cam_mul+1, cam_mul+2);
5336 if (!make[0]) strcpy (make, "Hasselblad");
5338 case 50459: /* Hasselblad tag */
5343 fseek (ifp, j+(get2(),get4()), SEEK_SET);
5349 case 50706: /* DNGVersion */
5350 FORC4 dng_version = (dng_version << 8) + fgetc(ifp);
5351 if (!make[0]) strcpy (make, "DNG");
5354 case 50710: /* CFAPlaneColor */
5355 if (len > 4) len = 4;
5357 fread (cfa_pc, 1, colors, ifp);
5359 FORCC tab[cfa_pc[c]] = c;
5362 filters = filters << 2 | tab[cfa_pat[i % plen]];
5364 case 50711: /* CFALayout */
5367 filters = 0x49494949;
5371 case 50712: /* LinearizationTable */
5374 case 50713: /* BlackLevelRepeatDim */
5380 case 50714: /* BlackLevel */
5381 black = getreal(type);
5382 if (!filters || !~filters) break;
5384 dblack[1] = (blrc == 2) ? getreal(type):dblack[0];
5385 dblack[2] = (blrr == 2) ? getreal(type):dblack[0];
5386 dblack[3] = (blrc == 2 && blrr == 2) ? getreal(type):dblack[1];
5388 filters |= ((filters >> 2 & 0x22222222) |
5389 (filters << 2 & 0x88888888)) & filters << 1;
5390 FORC4 cblack[filters >> (c << 1) & 3] = dblack[c];
5393 case 50715: /* BlackLevelDeltaH */
5394 case 50716: /* BlackLevelDeltaV */
5395 for (num=i=0; i < len; i++)
5396 num += getreal(type);
5397 black += num/len + 0.5;
5399 case 50717: /* WhiteLevel */
5400 maximum = getint(type);
5402 case 50718: /* DefaultScale */
5403 pixel_aspect = getreal(type);
5404 pixel_aspect /= getreal(type);
5406 case 50721: /* ColorMatrix1 */
5407 case 50722: /* ColorMatrix2 */
5408 FORCC for (j=0; j < 3; j++)
5409 cm[c][j] = getreal(type);
5412 case 50723: /* CameraCalibration1 */
5413 case 50724: /* CameraCalibration2 */
5414 for (i=0; i < colors; i++)
5415 FORCC cc[i][c] = getreal(type);
5417 case 50727: /* AnalogBalance */
5418 FORCC ab[c] = getreal(type);
5420 case 50728: /* AsShotNeutral */
5421 FORCC asn[c] = getreal(type);
5423 case 50729: /* AsShotWhiteXY */
5424 xyz[0] = getreal(type);
5425 xyz[1] = getreal(type);
5426 xyz[2] = 1 - xyz[0] - xyz[1];
5427 FORC3 xyz[c] /= d65_white[c];
5429 case 50740: /* DNGPrivateData */
5430 if (dng_version) break;
5431 parse_minolta (j = get4()+base);
5432 fseek (ifp, j, SEEK_SET);
5433 parse_tiff_ifd (base);
5436 read_shorts (cr2_slice, 3);
5438 case 50829: /* ActiveArea */
5439 top_margin = getint(type);
5440 left_margin = getint(type);
5441 height = getint(type) - top_margin;
5442 width = getint(type) - left_margin;
5444 case 50830: /* MaskedAreas */
5445 for (i=0; i < len && i < 32; i++)
5446 mask[0][i] = getint(type);
5449 case 51009: /* OpcodeList2 */
5450 meta_offset = ftell(ifp);
5452 case 64772: /* Kodak P-series */
5453 if (len < 13) break;
5454 fseek (ifp, 16, SEEK_CUR);
5455 data_offset = get4();
5456 fseek (ifp, 28, SEEK_CUR);
5457 data_offset += get4();
5458 load_raw = &CLASS packed_load_raw;
5461 if (type == 2) fgets (model2, 64, ifp);
5463 fseek (ifp, save, SEEK_SET);
5465 if (sony_length && (buf = (unsigned *) malloc(sony_length))) {
5466 fseek (ifp, sony_offset, SEEK_SET);
5467 fread (buf, sony_length, 1, ifp);
5468 sony_decrypt (buf, sony_length/4, 1, sony_key);
5470 if ((ifp = tmpfile())) {
5471 fwrite (buf, sony_length, 1, ifp);
5472 fseek (ifp, 0, SEEK_SET);
5473 parse_tiff_ifd (-sony_offset);
5479 for (i=0; i < colors; i++)
5480 FORCC cc[i][c] *= ab[i];
5482 FORCC for (i=0; i < 3; i++)
5483 for (cam_xyz[c][i]=j=0; j < colors; j++)
5484 cam_xyz[c][i] += cc[c][j] * cm[j][i] * xyz[i];
5485 cam_xyz_coeff (cam_xyz);
5489 FORCC cam_mul[c] = 1 / asn[c];
5492 FORCC pre_mul[c] /= cc[c][c];
5496 int CLASS parse_tiff (int base)
5500 fseek (ifp, base, SEEK_SET);
5502 if (order != 0x4949 && order != 0x4d4d) return 0;
5504 while ((doff = get4())) {
5505 fseek (ifp, doff+base, SEEK_SET);
5506 if (parse_tiff_ifd (base)) break;
5511 void CLASS apply_tiff()
5513 int max_samp=0, raw=-1, thm=-1, i;
5518 fseek (ifp, thumb_offset, SEEK_SET);
5519 if (ljpeg_start (&jh, 1)) {
5520 thumb_misc = jh.bits;
5521 thumb_width = jh.wide;
5522 thumb_height = jh.high;
5525 for (i=0; i < tiff_nifds; i++) {
5526 if (max_samp < tiff_ifd[i].samples)
5527 max_samp = tiff_ifd[i].samples;
5528 if (max_samp > 3) max_samp = 3;
5529 if ((tiff_ifd[i].comp != 6 || tiff_ifd[i].samples != 3) &&
5530 (tiff_ifd[i].width | tiff_ifd[i].height) < 0x10000 &&
5531 tiff_ifd[i].width*tiff_ifd[i].height > raw_width*raw_height) {
5532 raw_width = tiff_ifd[i].width;
5533 raw_height = tiff_ifd[i].height;
5534 tiff_bps = tiff_ifd[i].bps;
5535 tiff_compress = tiff_ifd[i].comp;
5536 data_offset = tiff_ifd[i].offset;
5537 tiff_flip = tiff_ifd[i].flip;
5538 tiff_samples = tiff_ifd[i].samples;
5539 tile_width = tiff_ifd[i].tile_width;
5540 tile_length = tiff_ifd[i].tile_length;
5544 if (!tile_width ) tile_width = INT_MAX;
5545 if (!tile_length) tile_length = INT_MAX;
5546 for (i=tiff_nifds; i--; )
5547 if (tiff_ifd[i].flip) tiff_flip = tiff_ifd[i].flip;
5548 if (raw >= 0 && !load_raw)
5549 switch (tiff_compress) {
5551 if (tiff_ifd[raw].bytes == raw_width*raw_height) {
5553 load_raw = &CLASS sony_arw2_load_raw; break;
5555 if (tiff_ifd[raw].bytes*8 != raw_width*raw_height*tiff_bps) {
5557 load_raw = &CLASS sony_arw_load_raw; break;
5563 case 32773: goto slr;
5565 if (tiff_ifd[raw].bytes*5 == raw_width*raw_height*8) {
5570 case 8: load_raw = &CLASS eight_bit_load_raw; break;
5571 case 12: if (tiff_ifd[raw].phint == 2)
5573 load_raw = &CLASS packed_load_raw; break;
5574 case 14: load_flags = 0;
5575 case 16: load_raw = &CLASS unpacked_load_raw; break;
5578 case 6: case 7: case 99:
5579 load_raw = &CLASS lossless_jpeg_load_raw; break;
5581 load_raw = &CLASS kodak_262_load_raw; break;
5583 if ((raw_width+9)/10*16*raw_height == tiff_ifd[raw].bytes) {
5584 load_raw = &CLASS packed_load_raw;
5586 } else if (raw_width*raw_height*2 == tiff_ifd[raw].bytes) {
5587 load_raw = &CLASS unpacked_load_raw;
5591 load_raw = &CLASS nikon_load_raw; break;
5593 load_raw = &CLASS lossy_dng_load_raw; break;
5595 load_raw = &CLASS pentax_load_raw; break;
5597 switch (tiff_ifd[raw].phint) {
5598 case 2: load_raw = &CLASS kodak_rgb_load_raw; filters = 0; break;
5599 case 6: load_raw = &CLASS kodak_ycbcr_load_raw; filters = 0; break;
5600 case 32803: load_raw = &CLASS kodak_65000_load_raw;
5603 default: is_raw = 0;
5606 if ( (tiff_samples == 3 && tiff_ifd[raw].bytes &&
5607 tiff_bps != 14 && tiff_bps != 2048 &&
5608 tiff_compress != 32769 && tiff_compress != 32770)
5609 || (tiff_bps == 8 && !strstr(make,"KODAK") && !strstr(make,"Kodak") &&
5610 !strstr(model2,"DEBUG RAW")))
5612 for (i=0; i < tiff_nifds; i++)
5613 if (i != raw && tiff_ifd[i].samples == max_samp &&
5614 tiff_ifd[i].width * tiff_ifd[i].height / SQR(tiff_ifd[i].bps+1) >
5615 thumb_width * thumb_height / SQR(thumb_misc+1)
5616 && tiff_ifd[i].comp != 34892) {
5617 thumb_width = tiff_ifd[i].width;
5618 thumb_height = tiff_ifd[i].height;
5619 thumb_offset = tiff_ifd[i].offset;
5620 thumb_length = tiff_ifd[i].bytes;
5621 thumb_misc = tiff_ifd[i].bps;
5625 thumb_misc |= tiff_ifd[thm].samples << 5;
5626 switch (tiff_ifd[thm].comp) {
5628 write_thumb = &CLASS layer_thumb;
5631 if (tiff_ifd[thm].bps <= 8)
5632 write_thumb = &CLASS ppm_thumb;
5633 else if (!strcmp(make,"Imacon"))
5634 write_thumb = &CLASS ppm16_thumb;
5636 thumb_load_raw = &CLASS kodak_thumb_load_raw;
5639 thumb_load_raw = tiff_ifd[thm].phint == 6 ?
5640 &CLASS kodak_ycbcr_load_raw : &CLASS kodak_rgb_load_raw;
5645 void CLASS parse_minolta (int base)
5647 int save, tag, len, offset, high=0, wide=0, i, c;
5650 fseek (ifp, base, SEEK_SET);
5651 if (fgetc(ifp) || fgetc(ifp)-'M' || fgetc(ifp)-'R') return;
5652 order = fgetc(ifp) * 0x101;
5653 offset = base + get4() + 8;
5654 while ((save=ftell(ifp)) < offset) {
5655 for (tag=i=0; i < 4; i++)
5656 tag = tag << 8 | fgetc(ifp);
5659 case 0x505244: /* PRD */
5660 fseek (ifp, 8, SEEK_CUR);
5664 case 0x574247: /* WBG */
5666 i = strcmp(model,"DiMAGE A200") ? 0:3;
5667 FORC4 cam_mul[c ^ (c >> 1) ^ i] = get2();
5669 case 0x545457: /* TTW */
5670 parse_tiff (ftell(ifp));
5671 data_offset = offset;
5673 fseek (ifp, save+len+8, SEEK_SET);
5681 Many cameras have a "debug mode" that writes JPEG and raw
5682 at the same time. The raw file has no header, so try to
5683 to open the matching JPEG file and read its metadata.
5685 void CLASS parse_external_jpeg()
5687 const char *file, *ext;
5688 char *jname, *jfile, *jext;
5691 ext = strrchr (ifname, '.');
5692 file = strrchr (ifname, '/');
5693 if (!file) file = strrchr (ifname, '\\');
5694 if (!file) file = ifname-1;
5696 if (!ext || strlen(ext) != 4 || ext-file != 8) return;
5697 jname = (char *) malloc (strlen(ifname) + 1);
5698 merror (jname, "parse_external_jpeg()");
5699 strcpy (jname, ifname);
5700 jfile = file - ifname + jname;
5701 jext = ext - ifname + jname;
5702 if (strcasecmp (ext, ".jpg")) {
5703 strcpy (jext, isupper(ext[1]) ? ".JPG":".jpg");
5704 if (isdigit(*file)) {
5705 memcpy (jfile, file+4, 4);
5706 memcpy (jfile+4, file, 4);
5709 while (isdigit(*--jext)) {
5716 if (strcmp (jname, ifname)) {
5717 if ((ifp = fopen (jname, "rb"))) {
5719 fprintf (stderr,_("Reading metadata from %s ...\n"), jname);
5727 fprintf (stderr,_("Failed to read metadata from %s\n"), jname);
5733 CIFF block 0x1030 contains an 8x8 white sample.
5734 Load this into white[][] for use in scale_colors().
5736 void CLASS ciff_block_1030()
5738 static const ushort key[] = { 0x410, 0x45f3 };
5739 int i, bpp, row, col, vbits=0;
5740 unsigned long bitbuf=0;
5742 if ((get2(),get4()) != 0x80008 || !get4()) return;
5744 if (bpp != 10 && bpp != 12) return;
5745 for (i=row=0; row < 8; row++)
5746 for (col=0; col < 8; col++) {
5748 bitbuf = bitbuf << 16 | (get2() ^ key[i++ & 1]);
5752 bitbuf << (LONG_BIT - vbits) >> (LONG_BIT - bpp);
5758 Parse a CIFF file, better known as Canon CRW format.
5760 void CLASS parse_ciff (int offset, int length)
5762 int tboff, nrecs, c, type, len, save, wbi=-1;
5763 ushort key[] = { 0x410, 0x45f3 };
5765 fseek (ifp, offset+length-4, SEEK_SET);
5766 tboff = get4() + offset;
5767 fseek (ifp, tboff, SEEK_SET);
5769 if (nrecs > 100) return;
5773 save = ftell(ifp) + 4;
5774 fseek (ifp, offset+get4(), SEEK_SET);
5775 if ((((type >> 8) + 8) | 8) == 0x38)
5776 parse_ciff (ftell(ifp), len); /* Parse a sub-table */
5779 fread (artist, 64, 1, ifp);
5780 if (type == 0x080a) {
5781 fread (make, 64, 1, ifp);
5782 fseek (ifp, strlen(make) - 63, SEEK_CUR);
5783 fread (model, 64, 1, ifp);
5785 if (type == 0x1810) {
5786 fseek (ifp, 12, SEEK_CUR);
5789 if (type == 0x1835) /* Get the decoder table */
5790 tiff_compress = get4();
5791 if (type == 0x2007) {
5792 thumb_offset = ftell(ifp);
5795 if (type == 0x1818) {
5796 shutter = pow (2, -int_to_float((get4(),get4())));
5797 aperture = pow (2, int_to_float(get4())/2);
5799 if (type == 0x102a) {
5800 iso_speed = pow (2, (get4(),get2())/32.0 - 4) * 50;
5801 aperture = pow (2, (get2(),(short)get2())/64.0);
5802 shutter = pow (2,-((short)get2())/32.0);
5803 wbi = (get2(),get2());
5804 if (wbi > 17) wbi = 0;
5805 fseek (ifp, 32, SEEK_CUR);
5806 if (shutter > 1e6) shutter = get2()/10.0;
5808 if (type == 0x102c) {
5809 if (get2() > 512) { /* Pro90, G1 */
5810 fseek (ifp, 118, SEEK_CUR);
5811 FORC4 cam_mul[c ^ 2] = get2();
5812 } else { /* G2, S30, S40 */
5813 fseek (ifp, 98, SEEK_CUR);
5814 FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get2();
5817 if (type == 0x0032) {
5818 if (len == 768) { /* EOS D30 */
5819 fseek (ifp, 72, SEEK_CUR);
5820 FORC4 cam_mul[c ^ (c >> 1)] = 1024.0 / get2();
5821 if (!wbi) cam_mul[0] = -1; /* use my auto white balance */
5822 } else if (!cam_mul[0]) {
5823 if (get2() == key[0]) /* Pro1, G6, S60, S70 */
5824 c = (strstr(model,"Pro1") ?
5825 "012346000000000000":"01345:000000006008")[wbi]-'0'+ 2;
5826 else { /* G3, G5, S45, S50 */
5827 c = "023457000000006000"[wbi]-'0';
5828 key[0] = key[1] = 0;
5830 fseek (ifp, 78 + c*8, SEEK_CUR);
5831 FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get2() ^ key[c & 1];
5832 if (!wbi) cam_mul[0] = -1;
5835 if (type == 0x10a9) { /* D60, 10D, 300D, and clones */
5836 if (len > 66) wbi = "0134567028"[wbi]-'0';
5837 fseek (ifp, 2 + wbi*8, SEEK_CUR);
5838 FORC4 cam_mul[c ^ (c >> 1)] = get2();
5840 if (type == 0x1030 && (0x18040 >> wbi & 1))
5841 ciff_block_1030(); /* all that don't have 0x10a9 */
5842 if (type == 0x1031) {
5843 raw_width = (get2(),get2());
5844 raw_height = get2();
5846 if (type == 0x5029) {
5847 focal_len = len >> 16;
5848 if ((len & 0xffff) == 2) focal_len /= 32;
5850 if (type == 0x5813) flash_used = int_to_float(len);
5851 if (type == 0x5814) canon_ev = int_to_float(len);
5852 if (type == 0x5817) shot_order = len;
5853 if (type == 0x5834) unique_id = len;
5854 if (type == 0x580e) timestamp = len;
5855 if (type == 0x180e) timestamp = get4();
5857 if ((type | 0x4000) == 0x580e)
5858 timestamp = mktime (gmtime (×tamp));
5860 fseek (ifp, save, SEEK_SET);
5864 void CLASS parse_rollei()
5866 char line[128], *val;
5869 fseek (ifp, 0, SEEK_SET);
5870 memset (&t, 0, sizeof t);
5872 fgets (line, 128, ifp);
5873 if ((val = strchr(line,'=')))
5876 val = line + strlen(line);
5877 if (!strcmp(line,"DAT"))
5878 sscanf (val, "%d.%d.%d", &t.tm_mday, &t.tm_mon, &t.tm_year);
5879 if (!strcmp(line,"TIM"))
5880 sscanf (val, "%d:%d:%d", &t.tm_hour, &t.tm_min, &t.tm_sec);
5881 if (!strcmp(line,"HDR"))
5882 thumb_offset = atoi(val);
5883 if (!strcmp(line,"X "))
5884 raw_width = atoi(val);
5885 if (!strcmp(line,"Y "))
5886 raw_height = atoi(val);
5887 if (!strcmp(line,"TX "))
5888 thumb_width = atoi(val);
5889 if (!strcmp(line,"TY "))
5890 thumb_height = atoi(val);
5891 } while (strncmp(line,"EOHD",4));
5892 data_offset = thumb_offset + thumb_width * thumb_height * 2;
5896 timestamp = mktime(&t);
5897 strcpy (make, "Rollei");
5898 strcpy (model,"d530flex");
5899 write_thumb = &CLASS rollei_thumb;
5902 void CLASS parse_sinar_ia()
5908 fseek (ifp, 4, SEEK_SET);
5910 fseek (ifp, get4(), SEEK_SET);
5912 off = get4(); get4();
5913 fread (str, 8, 1, ifp);
5914 if (!strcmp(str,"META")) meta_offset = off;
5915 if (!strcmp(str,"THUMB")) thumb_offset = off;
5916 if (!strcmp(str,"RAW0")) data_offset = off;
5918 fseek (ifp, meta_offset+20, SEEK_SET);
5919 fread (make, 64, 1, ifp);
5921 if ((cp = strchr(make,' '))) {
5922 strcpy (model, cp+1);
5926 raw_height = get2();
5927 load_raw = &CLASS unpacked_load_raw;
5928 thumb_width = (get4(),get2());
5929 thumb_height = get2();
5930 write_thumb = &CLASS ppm_thumb;
5934 void CLASS parse_phase_one (int base)
5936 unsigned entries, tag, /*type,*/ len, data, save, i, c;
5937 float romm_cam[3][3], *fp;
5940 memset (&ph1, 0, sizeof ph1);
5941 fseek (ifp, base, SEEK_SET);
5942 order = get4() & 0xffff;
5943 if (get4() >> 8 != 0x526177) return; /* "Raw" */
5944 fseek (ifp, get4()+base, SEEK_SET);
5953 fseek (ifp, base+data, SEEK_SET);
5955 case 0x100: flip = "0653"[data & 3]-'0'; break;
5957 for( i=9,fp=&romm_cam[0][0]; --i>=0; ++fp )
5959 romm_coeff (romm_cam);
5962 FORC3 cam_mul[c] = getreal(11);
5964 case 0x108: raw_width = data; break;
5965 case 0x109: raw_height = data; break;
5966 case 0x10a: left_margin = data; break;
5967 case 0x10b: top_margin = data; break;
5968 case 0x10c: width = data; break;
5969 case 0x10d: height = data; break;
5970 case 0x10e: ph1.format = data; break;
5971 case 0x10f: data_offset = data+base; break;
5972 case 0x110: meta_offset = data+base;
5973 meta_length = len; break;
5974 case 0x112: ph1.key_off = save - 4; break;
5975 case 0x210: ph1.tag_210 = int_to_float(data); break;
5976 case 0x21a: ph1.tag_21a = data; break;
5977 case 0x21c: strip_offset = data+base; break;
5978 case 0x21d: ph1.black = data; break;
5979 case 0x222: ph1.split_col = data; break;
5980 case 0x223: ph1.black_off = data+base; break;
5983 fread (model, 1, 63, ifp);
5984 if ((cp = strstr(model," camera"))) *cp = 0;
5986 fseek (ifp, save, SEEK_SET);
5988 load_raw = ph1.format < 3 ?
5989 &CLASS phase_one_load_raw : &CLASS phase_one_load_raw_c;
5991 strcpy (make, "Phase One");
5992 if (model[0]) return;
5993 switch (raw_height) {
5994 case 2060: strcpy (model,"LightPhase"); break;
5995 case 2682: strcpy (model,"H 10"); break;
5996 case 4128: strcpy (model,"H 20"); break;
5997 case 5488: strcpy (model,"H 25"); break;
6001 void CLASS parse_fuji (int offset)
6003 unsigned entries, tag, len, save, c;
6005 fseek (ifp, offset, SEEK_SET);
6007 if (entries > 255) return;
6013 raw_height = get2();
6015 } else if (tag == 0x121) {
6017 if ((width = get2()) == 4284) width += 3;
6018 } else if (tag == 0x130) {
6019 fuji_layout = fgetc(ifp) >> 7;
6020 fuji_width = !(fgetc(ifp) & 8);
6021 } else if (tag == 0x2ff0) {
6022 FORC4 cam_mul[c ^ 1] = get2();
6023 } else if (tag == 0xc000) {
6026 if ((width = get4()) > 10000) width = get4();
6030 fseek (ifp, save+len, SEEK_SET);
6032 height <<= fuji_layout;
6033 width >>= fuji_layout;
6036 int CLASS parse_jpeg (int offset)
6038 int len, save, hlen, mark;
6040 fseek (ifp, offset, SEEK_SET);
6041 if (fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) return 0;
6043 while (fgetc(ifp) == 0xff && (mark = fgetc(ifp)) != 0xda) {
6047 if (mark == 0xc0 || mark == 0xc3) {
6049 raw_height = get2();
6054 if (get4() == 0x48454150) /* "HEAP" */
6055 parse_ciff (save+hlen, len-hlen);
6056 if (parse_tiff (save+6)) apply_tiff();
6057 fseek (ifp, save+len, SEEK_SET);
6062 void CLASS parse_riff()
6064 unsigned i, size, end;
6065 char tag[4], date[64], month[64];
6066 static const char mon[12][4] =
6067 { "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" };
6071 fread (tag, 4, 1, ifp);
6073 end = ftell(ifp) + size;
6074 if (!memcmp(tag,"RIFF",4) || !memcmp(tag,"LIST",4)) {
6076 while (ftell(ifp)+7 < end)
6078 } else if (!memcmp(tag,"nctg",4)) {
6079 while (ftell(ifp)+7 < end) {
6082 if ((i+1) >> 1 == 10 && size == 20)
6084 else fseek (ifp, size, SEEK_CUR);
6086 } else if (!memcmp(tag,"IDIT",4) && size < 64) {
6087 fread (date, 64, 1, ifp);
6089 memset (&t, 0, sizeof t);
6090 if (sscanf (date, "%*s %s %d %d:%d:%d %d", month, &t.tm_mday,
6091 &t.tm_hour, &t.tm_min, &t.tm_sec, &t.tm_year) == 6) {
6092 for (i=0; i < 12 && strcasecmp(mon[i],month); i++);
6096 timestamp = mktime(&t);
6099 fseek (ifp, size, SEEK_CUR);
6102 void CLASS parse_smal (int offset, int fsize)
6106 fseek (ifp, offset+2, SEEK_SET);
6110 fseek (ifp, 5, SEEK_CUR);
6111 if (get4() != fsize) return;
6112 if (ver > 6) data_offset = get4();
6113 raw_height = height = get2();
6114 raw_width = width = get2();
6115 strcpy (make, "SMaL");
6116 sprintf (model, "v%d %dx%d", ver, width, height);
6117 if (ver == 6) load_raw = &CLASS smal_v6_load_raw;
6118 if (ver == 9) load_raw = &CLASS smal_v9_load_raw;
6121 void CLASS parse_cine()
6123 unsigned off_head, off_setup, off_image, i;
6126 fseek (ifp, 4, SEEK_SET);
6127 is_raw = get2() == 2;
6128 fseek (ifp, 14, SEEK_CUR);
6134 if ((i = get4())) timestamp = i;
6135 fseek (ifp, off_head+4, SEEK_SET);
6137 raw_height = get4();
6138 switch (get2(),get2()) {
6139 case 8: load_raw = &CLASS eight_bit_load_raw; break;
6140 case 16: load_raw = &CLASS unpacked_load_raw;
6142 fseek (ifp, off_setup+792, SEEK_SET);
6143 strcpy (make, "CINE");
6144 sprintf (model, "%d", get4());
6145 fseek (ifp, 12, SEEK_CUR);
6146 switch ((i=get4()) & 0xffffff) {
6147 case 3: filters = 0x94949494; break;
6148 case 4: filters = 0x49494949; break;
6149 default: is_raw = 0;
6151 fseek (ifp, 72, SEEK_CUR);
6152 switch ((get4()+3600) % 360) {
6153 case 270: flip = 4; break;
6154 case 180: flip = 1; break;
6155 case 90: flip = 7; break;
6158 cam_mul[0] = getreal(11);
6159 cam_mul[2] = getreal(11);
6160 maximum = ~(-1 << get4());
6161 fseek (ifp, 668, SEEK_CUR);
6162 shutter = get4()/1000000000.0;
6163 fseek (ifp, off_image, SEEK_SET);
6164 if (shot_select < is_raw)
6165 fseek (ifp, shot_select*8, SEEK_CUR);
6166 data_offset = (INT64) get4() + 8;
6167 data_offset += (INT64) get4() << 32;
6170 void CLASS parse_redcine()
6172 unsigned i, len, rdvo;
6176 fseek (ifp, 52, SEEK_SET);
6179 fseek (ifp, 0, SEEK_END);
6180 fseek (ifp, -(i = ftello(ifp) & 511), SEEK_CUR);
6181 if (get4() != i || get4() != 0x52454f42) {
6182 fprintf (stderr,_("%s: Tail is missing, parsing from head...\n"), ifname);
6183 fseek (ifp, 0, SEEK_SET);
6184 while ((len = get4()) != EOF) {
6185 if (get4() == 0x52454456)
6186 if (is_raw++ == shot_select)
6187 data_offset = ftello(ifp) - 8;
6188 fseek (ifp, len-8, SEEK_CUR);
6192 fseek (ifp, 12, SEEK_CUR);
6194 fseeko (ifp, rdvo+8 + shot_select*4, SEEK_SET);
6195 data_offset = get4();
6199 char * CLASS foveon_gets (int offset, char *str, int len)
6202 fseek (ifp, offset, SEEK_SET);
6203 for (i=0; i < len-1; i++)
6204 if ((str[i] = get2()) == 0) break;
6209 void CLASS parse_foveon()
6211 int entries, img=0, off, len, tag, save, i, wide, high, pent, poff[256][2];
6212 char name[64], value[64];
6214 order = 0x4949; /* Little-endian */
6215 fseek (ifp, 36, SEEK_SET);
6217 fseek (ifp, -4, SEEK_END);
6218 fseek (ifp, get4(), SEEK_SET);
6219 if (get4() != 0x64434553) return; /* SECd */
6220 entries = (get4(),get4());
6226 fseek (ifp, off, SEEK_SET);
6227 if (get4() != (0x20434553 | (tag << 24))) return;
6229 case 0x47414d49: /* IMAG */
6230 case 0x32414d49: /* IMA2 */
6231 fseek (ifp, 8, SEEK_CUR);
6235 if (wide > raw_width && high > raw_height) {
6237 case 5: load_flags = 1;
6238 case 6: load_raw = &CLASS foveon_sd_load_raw; break;
6239 case 30: load_raw = &CLASS foveon_dp_load_raw; break;
6240 default: load_raw = 0;
6244 data_offset = off+28;
6246 fseek (ifp, off+28, SEEK_SET);
6247 if (fgetc(ifp) == 0xff && fgetc(ifp) == 0xd8
6248 && thumb_length < len-28) {
6249 thumb_offset = off+28;
6250 thumb_length = len-28;
6251 write_thumb = &CLASS jpeg_thumb;
6253 if (++img == 2 && !thumb_length) {
6254 thumb_offset = off+24;
6256 thumb_height = high;
6257 write_thumb = &CLASS foveon_thumb;
6260 case 0x464d4143: /* CAMF */
6261 meta_offset = off+8;
6262 meta_length = len-28;
6264 case 0x504f5250: /* PROP */
6265 pent = (get4(),get4());
6266 fseek (ifp, 12, SEEK_CUR);
6268 if ((unsigned) pent > 256) pent=256;
6269 for (i=0; i < pent*2; i++)
6270 poff[0][i] = off + get4()*2;
6271 for (i=0; i < pent; i++) {
6272 foveon_gets (poff[i][0], name, 64);
6273 foveon_gets (poff[i][1], value, 64);
6274 if (!strcmp (name, "ISO"))
6275 iso_speed = atoi(value);
6276 if (!strcmp (name, "CAMMANUF"))
6277 strcpy (make, value);
6278 if (!strcmp (name, "CAMMODEL"))
6279 strcpy (model, value);
6280 if (!strcmp (name, "WB_DESC"))
6281 strcpy (model2, value);
6282 if (!strcmp (name, "TIME"))
6283 timestamp = atoi(value);
6284 if (!strcmp (name, "EXPTIME"))
6285 shutter = atoi(value) / 1000000.0;
6286 if (!strcmp (name, "APERTURE"))
6287 aperture = atof(value);
6288 if (!strcmp (name, "FLENGTH"))
6289 focal_len = atof(value);
6292 timestamp = mktime (gmtime (×tamp));
6295 fseek (ifp, save, SEEK_SET);
6301 All matrices are from Adobe DNG Converter unless otherwise noted.
6303 void CLASS adobe_coeff (const char *make, const char *model)
6305 static const struct {
6307 short black, maximum, trans[12];
6309 { "AGFAPHOTO DC-833m", 0, 0, /* DJC */
6310 { 11438,-3762,-1115,-2409,9914,2497,-1227,2295,5300 } },
6311 { "Apple QuickTake", 0, 0, /* DJC */
6312 { 21392,-5653,-3353,2406,8010,-415,7166,1427,2078 } },
6313 { "Canon EOS D2000", 0, 0,
6314 { 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } },
6315 { "Canon EOS D6000", 0, 0,
6316 { 20482,-7172,-3125,-1033,10410,-285,2542,226,3136 } },
6317 { "Canon EOS D30", 0, 0,
6318 { 9805,-2689,-1312,-5803,13064,3068,-2438,3075,8775 } },
6319 { "Canon EOS D60", 0, 0xfa0,
6320 { 6188,-1341,-890,-7168,14489,2937,-2640,3228,8483 } },
6321 { "Canon EOS 5D Mark III", 0, 0x3c80,
6322 { 6722,-635,-963,-4287,12460,2028,-908,2162,5668 } },
6323 { "Canon EOS 5D Mark II", 0, 0x3cf0,
6324 { 4716,603,-830,-7798,15474,2480,-1496,1937,6651 } },
6325 { "Canon EOS 5D", 0, 0xe6c,
6326 { 6347,-479,-972,-8297,15954,2480,-1968,2131,7649 } },
6327 { "Canon EOS 6D", 0, 0x3c82,
6328 { 7034,-804,-1014,-4420,12564,2058,-851,1994,5758 } },
6329 { "Canon EOS 7D", 0, 0x3510,
6330 { 6844,-996,-856,-3876,11761,2396,-593,1772,6198 } },
6331 { "Canon EOS 10D", 0, 0xfa0,
6332 { 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } },
6333 { "Canon EOS 20Da", 0, 0,
6334 { 14155,-5065,-1382,-6550,14633,2039,-1623,1824,6561 } },
6335 { "Canon EOS 20D", 0, 0xfff,
6336 { 6599,-537,-891,-8071,15783,2424,-1983,2234,7462 } },
6337 { "Canon EOS 30D", 0, 0,
6338 { 6257,-303,-1000,-7880,15621,2396,-1714,1904,7046 } },
6339 { "Canon EOS 40D", 0, 0x3f60,
6340 { 6071,-747,-856,-7653,15365,2441,-2025,2553,7315 } },
6341 { "Canon EOS 50D", 0, 0x3d93,
6342 { 4920,616,-593,-6493,13964,2784,-1774,3178,7005 } },
6343 { "Canon EOS 60D", 0, 0x2ff7,
6344 { 6719,-994,-925,-4408,12426,2211,-887,2129,6051 } },
6345 { "Canon EOS 300D", 0, 0xfa0,
6346 { 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } },
6347 { "Canon EOS 350D", 0, 0xfff,
6348 { 6018,-617,-965,-8645,15881,2975,-1530,1719,7642 } },
6349 { "Canon EOS 400D", 0, 0xe8e,
6350 { 7054,-1501,-990,-8156,15544,2812,-1278,1414,7796 } },
6351 { "Canon EOS 450D", 0, 0x390d,
6352 { 5784,-262,-821,-7539,15064,2672,-1982,2681,7427 } },
6353 { "Canon EOS 500D", 0, 0x3479,
6354 { 4763,712,-646,-6821,14399,2640,-1921,3276,6561 } },
6355 { "Canon EOS 550D", 0, 0x3dd7,
6356 { 6941,-1164,-857,-3825,11597,2534,-416,1540,6039 } },
6357 { "Canon EOS 600D", 0, 0x3510,
6358 { 6461,-907,-882,-4300,12184,2378,-819,1944,5931 } },
6359 { "Canon EOS 650D", 0, 0x354d,
6360 { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } },
6361 { "Canon EOS 1000D", 0, 0xe43,
6362 { 6771,-1139,-977,-7818,15123,2928,-1244,1437,7533 } },
6363 { "Canon EOS 1100D", 0, 0x3510,
6364 { 6444,-904,-893,-4563,12308,2535,-903,2016,6728 } },
6365 { "Canon EOS M", 0, 0,
6366 { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } },
6367 { "Canon EOS-1Ds Mark III", 0, 0x3bb0,
6368 { 5859,-211,-930,-8255,16017,2353,-1732,1887,7448 } },
6369 { "Canon EOS-1Ds Mark II", 0, 0xe80,
6370 { 6517,-602,-867,-8180,15926,2378,-1618,1771,7633 } },
6371 { "Canon EOS-1D Mark IV", 0, 0x3bb0,
6372 { 6014,-220,-795,-4109,12014,2361,-561,1824,5787 } },
6373 { "Canon EOS-1D Mark III", 0, 0x3bb0,
6374 { 6291,-540,-976,-8350,16145,2311,-1714,1858,7326 } },
6375 { "Canon EOS-1D Mark II N", 0, 0xe80,
6376 { 6240,-466,-822,-8180,15825,2500,-1801,1938,8042 } },
6377 { "Canon EOS-1D Mark II", 0, 0xe80,
6378 { 6264,-582,-724,-8312,15948,2504,-1744,1919,8664 } },
6379 { "Canon EOS-1DS", 0, 0xe20,
6380 { 4374,3631,-1743,-7520,15212,2472,-2892,3632,8161 } },
6381 { "Canon EOS-1D X", 0, 0x3c4e,
6382 { 6847,-614,-1014,-4669,12737,2139,-1197,2488,6846 } },
6383 { "Canon EOS-1D", 0, 0xe20,
6384 { 6806,-179,-1020,-8097,16415,1687,-3267,4236,7690 } },
6385 { "Canon EOS", 0, 0,
6386 { 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } },
6387 { "Canon PowerShot A530", 0, 0,
6388 { 0 } }, /* don't want the A5 matrix */
6389 { "Canon PowerShot A50", 0, 0,
6390 { -5300,9846,1776,3436,684,3939,-5540,9879,6200,-1404,11175,217 } },
6391 { "Canon PowerShot A5", 0, 0,
6392 { -4801,9475,1952,2926,1611,4094,-5259,10164,5947,-1554,10883,547 } },
6393 { "Canon PowerShot G10", 0, 0,
6394 { 11093,-3906,-1028,-5047,12492,2879,-1003,1750,5561 } },
6395 { "Canon PowerShot G11", 0, 0,
6396 { 12177,-4817,-1069,-1612,9864,2049,-98,850,4471 } },
6397 { "Canon PowerShot G12", 0, 0,
6398 { 13244,-5501,-1248,-1508,9858,1935,-270,1083,4366 } },
6399 { "Canon PowerShot G15", 0, 0,
6400 { 7474,-2301,-567,-4056,11456,2975,-222,716,4181 } },
6401 { "Canon PowerShot G1 X", 0, 0,
6402 { 7378,-1255,-1043,-4088,12251,2048,-876,1946,5805 } },
6403 { "Canon PowerShot G1", 0, 0,
6404 { -4778,9467,2172,4743,-1141,4344,-5146,9908,6077,-1566,11051,557 } },
6405 { "Canon PowerShot G2", 0, 0,
6406 { 9087,-2693,-1049,-6715,14382,2537,-2291,2819,7790 } },
6407 { "Canon PowerShot G3", 0, 0,
6408 { 9212,-2781,-1073,-6573,14189,2605,-2300,2844,7664 } },
6409 { "Canon PowerShot G5", 0, 0,
6410 { 9757,-2872,-933,-5972,13861,2301,-1622,2328,7212 } },
6411 { "Canon PowerShot G6", 0, 0,
6412 { 9877,-3775,-871,-7613,14807,3072,-1448,1305,7485 } },
6413 { "Canon PowerShot G9", 0, 0,
6414 { 7368,-2141,-598,-5621,13254,2625,-1418,1696,5743 } },
6415 { "Canon PowerShot Pro1", 0, 0,
6416 { 10062,-3522,-999,-7643,15117,2730,-765,817,7323 } },
6417 { "Canon PowerShot Pro70", 34, 0,
6418 { -4155,9818,1529,3939,-25,4522,-5521,9870,6610,-2238,10873,1342 } },
6419 { "Canon PowerShot Pro90", 0, 0,
6420 { -4963,9896,2235,4642,-987,4294,-5162,10011,5859,-1770,11230,577 } },
6421 { "Canon PowerShot S30", 0, 0,
6422 { 10566,-3652,-1129,-6552,14662,2006,-2197,2581,7670 } },
6423 { "Canon PowerShot S40", 0, 0,
6424 { 8510,-2487,-940,-6869,14231,2900,-2318,2829,9013 } },
6425 { "Canon PowerShot S45", 0, 0,
6426 { 8163,-2333,-955,-6682,14174,2751,-2077,2597,8041 } },
6427 { "Canon PowerShot S50", 0, 0,
6428 { 8882,-2571,-863,-6348,14234,2288,-1516,2172,6569 } },
6429 { "Canon PowerShot S60", 0, 0,
6430 { 8795,-2482,-797,-7804,15403,2573,-1422,1996,7082 } },
6431 { "Canon PowerShot S70", 0, 0,
6432 { 9976,-3810,-832,-7115,14463,2906,-901,989,7889 } },
6433 { "Canon PowerShot S90", 0, 0,
6434 { 12374,-5016,-1049,-1677,9902,2078,-83,852,4683 } },
6435 { "Canon PowerShot S95", 0, 0,
6436 { 13440,-5896,-1279,-1236,9598,1931,-180,1001,4651 } },
6437 { "Canon PowerShot S100", 0, 0,
6438 { 7968,-2565,-636,-2873,10697,2513,180,667,4211 } },
6439 { "Canon PowerShot S110", 0, 0,
6440 { 8039,-2643,-654,-3783,11230,2930,-206,690,4194 } },
6441 { "Canon PowerShot SX1 IS", 0, 0,
6442 { 6578,-259,-502,-5974,13030,3309,-308,1058,4970 } },
6443 { "Canon PowerShot SX50 HS", 0, 0,
6444 { 12432,-4753,-1247,-2110,10691,1629,-412,1623,4926 } },
6445 { "Canon PowerShot A470", 0, 0, /* DJC */
6446 { 12513,-4407,-1242,-2680,10276,2405,-878,2215,4734 } },
6447 { "Canon PowerShot A610", 0, 0, /* DJC */
6448 { 15591,-6402,-1592,-5365,13198,2168,-1300,1824,5075 } },
6449 { "Canon PowerShot A620", 0, 0, /* DJC */
6450 { 15265,-6193,-1558,-4125,12116,2010,-888,1639,5220 } },
6451 { "Canon PowerShot A630", 0, 0, /* DJC */
6452 { 14201,-5308,-1757,-6087,14472,1617,-2191,3105,5348 } },
6453 { "Canon PowerShot A640", 0, 0, /* DJC */
6454 { 13124,-5329,-1390,-3602,11658,1944,-1612,2863,4885 } },
6455 { "Canon PowerShot A650", 0, 0, /* DJC */
6456 { 9427,-3036,-959,-2581,10671,1911,-1039,1982,4430 } },
6457 { "Canon PowerShot A720", 0, 0, /* DJC */
6458 { 14573,-5482,-1546,-1266,9799,1468,-1040,1912,3810 } },
6459 { "Canon PowerShot S3 IS", 0, 0, /* DJC */
6460 { 14062,-5199,-1446,-4712,12470,2243,-1286,2028,4836 } },
6461 { "Canon PowerShot SX110 IS", 0, 0, /* DJC */
6462 { 14134,-5576,-1527,-1991,10719,1273,-1158,1929,3581 } },
6463 { "Canon PowerShot SX220", 0, 0, /* DJC */
6464 { 13898,-5076,-1447,-1405,10109,1297,-244,1860,3687 } },
6465 { "CASIO EX-S20", 0, 0, /* DJC */
6466 { 11634,-3924,-1128,-4968,12954,2015,-1588,2648,7206 } },
6467 { "CASIO EX-Z750", 0, 0, /* DJC */
6468 { 10819,-3873,-1099,-4903,13730,1175,-1755,3751,4632 } },
6469 { "CASIO EX-Z10", 128, 0xfff, /* DJC */
6470 { 9790,-3338,-603,-2321,10222,2099,-344,1273,4799 } },
6472 { 3390,480,-500,-800,3610,340,-550,2336,1192 } },
6474 { 3390,480,-500,-800,3610,340,-550,2336,1192 } },
6476 { 20183,-4295,-423,-3940,15330,3985,-280,4870,9800 } },
6477 { "Contax N Digital", 0, 0xf1e,
6478 { 7777,1285,-1053,-9280,16543,2916,-3677,5679,7060 } },
6479 { "EPSON R-D1", 0, 0,
6480 { 6827,-1878,-732,-8429,16012,2564,-704,592,7145 } },
6481 { "FUJIFILM E550", 0, 0,
6482 { 11044,-3888,-1120,-7248,15168,2208,-1531,2277,8069 } },
6483 { "FUJIFILM E900", 0, 0,
6484 { 9183,-2526,-1078,-7461,15071,2574,-2022,2440,8639 } },
6485 { "FUJIFILM F5", 0, 0,
6486 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
6487 { "FUJIFILM F6", 0, 0,
6488 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
6489 { "FUJIFILM F77", 0, 0xfe9,
6490 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
6491 { "FUJIFILM F7", 0, 0,
6492 { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } },
6493 { "FUJIFILM F8", 0, 0,
6494 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
6495 { "FUJIFILM S100FS", 514, 0,
6496 { 11521,-4355,-1065,-6524,13767,3058,-1466,1984,6045 } },
6497 { "FUJIFILM S200EXR", 512, 0x3fff,
6498 { 11401,-4498,-1312,-5088,12751,2613,-838,1568,5941 } },
6499 { "FUJIFILM S20Pro", 0, 0,
6500 { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } },
6501 { "FUJIFILM S2Pro", 128, 0,
6502 { 12492,-4690,-1402,-7033,15423,1647,-1507,2111,7697 } },
6503 { "FUJIFILM S3Pro", 0, 0,
6504 { 11807,-4612,-1294,-8927,16968,1988,-2120,2741,8006 } },
6505 { "FUJIFILM S5Pro", 0, 0,
6506 { 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } },
6507 { "FUJIFILM S5000", 0, 0,
6508 { 8754,-2732,-1019,-7204,15069,2276,-1702,2334,6982 } },
6509 { "FUJIFILM S5100", 0, 0,
6510 { 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } },
6511 { "FUJIFILM S5500", 0, 0,
6512 { 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } },
6513 { "FUJIFILM S5200", 0, 0,
6514 { 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } },
6515 { "FUJIFILM S5600", 0, 0,
6516 { 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } },
6517 { "FUJIFILM S6", 0, 0,
6518 { 12628,-4887,-1401,-6861,14996,1962,-2198,2782,7091 } },
6519 { "FUJIFILM S7000", 0, 0,
6520 { 10190,-3506,-1312,-7153,15051,2238,-2003,2399,7505 } },
6521 { "FUJIFILM S9000", 0, 0,
6522 { 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 } },
6523 { "FUJIFILM S9500", 0, 0,
6524 { 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 } },
6525 { "FUJIFILM S9100", 0, 0,
6526 { 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 } },
6527 { "FUJIFILM S9600", 0, 0,
6528 { 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 } },
6529 { "FUJIFILM IS-1", 0, 0,
6530 { 21461,-10807,-1441,-2332,10599,1999,289,875,7703 } },
6531 { "FUJIFILM IS Pro", 0, 0,
6532 { 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } },
6533 { "FUJIFILM HS10 HS11", 0, 0xf68,
6534 { 12440,-3954,-1183,-1123,9674,1708,-83,1614,4086 } },
6535 { "FUJIFILM HS20EXR", 0, 0,
6536 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
6537 { "FUJIFILM HS3", 0, 0,
6538 { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
6539 { "FUJIFILM X100", 0, 0,
6540 { 12161,-4457,-1069,-5034,12874,2400,-795,1724,6904 } },
6541 { "FUJIFILM X10", 0, 0,
6542 { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } },
6543 { "FUJIFILM X-Pro1", 0, 0,
6544 { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } },
6545 { "FUJIFILM X-E1", 0, 0,
6546 { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } },
6547 { "FUJIFILM XF1", 0, 0,
6548 { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } },
6549 { "FUJIFILM X-S1", 0, 0,
6550 { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } },
6551 { "Imacon Ixpress", 0, 0, /* DJC */
6552 { 7025,-1415,-704,-5188,13765,1424,-1248,2742,6038 } },
6553 { "KODAK NC2000", 0, 0,
6554 { 13891,-6055,-803,-465,9919,642,2121,82,1291 } },
6555 { "Kodak DCS315C", 8, 0,
6556 { 17523,-4827,-2510,756,8546,-137,6113,1649,2250 } },
6557 { "Kodak DCS330C", 8, 0,
6558 { 20620,-7572,-2801,-103,10073,-396,3551,-233,2220 } },
6559 { "KODAK DCS420", 0, 0,
6560 { 10868,-1852,-644,-1537,11083,484,2343,628,2216 } },
6561 { "KODAK DCS460", 0, 0,
6562 { 10592,-2206,-967,-1944,11685,230,2206,670,1273 } },
6563 { "KODAK EOSDCS1", 0, 0,
6564 { 10592,-2206,-967,-1944,11685,230,2206,670,1273 } },
6565 { "KODAK EOSDCS3B", 0, 0,
6566 { 9898,-2700,-940,-2478,12219,206,1985,634,1031 } },
6567 { "Kodak DCS520C", 178, 0,
6568 { 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } },
6569 { "Kodak DCS560C", 177, 0,
6570 { 20482,-7172,-3125,-1033,10410,-285,2542,226,3136 } },
6571 { "Kodak DCS620C", 177, 0,
6572 { 23617,-10175,-3149,-2054,11749,-272,2586,-489,3453 } },
6573 { "Kodak DCS620X", 176, 0,
6574 { 13095,-6231,154,12221,-21,-2137,895,4602,2258 } },
6575 { "Kodak DCS660C", 173, 0,
6576 { 18244,-6351,-2739,-791,11193,-521,3711,-129,2802 } },
6577 { "Kodak DCS720X", 0, 0,
6578 { 11775,-5884,950,9556,1846,-1286,-1019,6221,2728 } },
6579 { "Kodak DCS760C", 0, 0,
6580 { 16623,-6309,-1411,-4344,13923,323,2285,274,2926 } },
6581 { "Kodak DCS Pro SLR", 0, 0,
6582 { 5494,2393,-232,-6427,13850,2846,-1876,3997,5445 } },
6583 { "Kodak DCS Pro 14nx", 0, 0,
6584 { 5494,2393,-232,-6427,13850,2846,-1876,3997,5445 } },
6585 { "Kodak DCS Pro 14", 0, 0,
6586 { 7791,3128,-776,-8588,16458,2039,-2455,4006,6198 } },
6587 { "Kodak ProBack645", 0, 0,
6588 { 16414,-6060,-1470,-3555,13037,473,2545,122,4948 } },
6589 { "Kodak ProBack", 0, 0,
6590 { 21179,-8316,-2918,-915,11019,-165,3477,-180,4210 } },
6591 { "KODAK P712", 0, 0,
6592 { 9658,-3314,-823,-5163,12695,2768,-1342,1843,6044 } },
6593 { "KODAK P850", 0, 0xf7c,
6594 { 10511,-3836,-1102,-6946,14587,2558,-1481,1792,6246 } },
6595 { "KODAK P880", 0, 0xfff,
6596 { 12805,-4662,-1376,-7480,15267,2360,-1626,2194,7904 } },
6597 { "KODAK EasyShare Z980", 0, 0,
6598 { 11313,-3559,-1101,-3893,11891,2257,-1214,2398,4908 } },
6599 { "KODAK EasyShare Z981", 0, 0,
6600 { 12729,-4717,-1188,-1367,9187,2582,274,860,4411 } },
6601 { "KODAK EasyShare Z990", 0, 0xfed,
6602 { 11749,-4048,-1309,-1867,10572,1489,-138,1449,4522 } },
6603 { "KODAK EASYSHARE Z1015", 0, 0xef1,
6604 { 11265,-4286,-992,-4694,12343,2647,-1090,1523,5447 } },
6605 { "Leaf CMost", 0, 0,
6606 { 3952,2189,449,-6701,14585,2275,-4536,7349,6536 } },
6607 { "Leaf Valeo 6", 0, 0,
6608 { 3952,2189,449,-6701,14585,2275,-4536,7349,6536 } },
6609 { "Leaf Aptus 54S", 0, 0,
6610 { 8236,1746,-1314,-8251,15953,2428,-3673,5786,5771 } },
6611 { "Leaf Aptus 65", 0, 0,
6612 { 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 } },
6613 { "Leaf Aptus 75", 0, 0,
6614 { 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 } },
6616 { 8236,1746,-1314,-8251,15953,2428,-3673,5786,5771 } },
6617 { "Mamiya ZD", 0, 0,
6618 { 7645,2579,-1363,-8689,16717,2015,-3712,5941,5961 } },
6619 { "Micron 2010", 110, 0, /* DJC */
6620 { 16695,-3761,-2151,155,9682,163,3433,951,4904 } },
6621 { "Minolta DiMAGE 5", 0, 0xf7d,
6622 { 8983,-2942,-963,-6556,14476,2237,-2426,2887,8014 } },
6623 { "Minolta DiMAGE 7Hi", 0, 0xf7d,
6624 { 11368,-3894,-1242,-6521,14358,2339,-2475,3056,7285 } },
6625 { "Minolta DiMAGE 7", 0, 0xf7d,
6626 { 9144,-2777,-998,-6676,14556,2281,-2470,3019,7744 } },
6627 { "Minolta DiMAGE A1", 0, 0xf8b,
6628 { 9274,-2547,-1167,-8220,16323,1943,-2273,2720,8340 } },
6629 { "MINOLTA DiMAGE A200", 0, 0,
6630 { 8560,-2487,-986,-8112,15535,2771,-1209,1324,7743 } },
6631 { "Minolta DiMAGE A2", 0, 0xf8f,
6632 { 9097,-2726,-1053,-8073,15506,2762,-966,981,7763 } },
6633 { "Minolta DiMAGE Z2", 0, 0, /* DJC */
6634 { 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 } },
6635 { "MINOLTA DYNAX 5", 0, 0xffb,
6636 { 10284,-3283,-1086,-7957,15762,2316,-829,882,6644 } },
6637 { "MINOLTA DYNAX 7", 0, 0xffb,
6638 { 10239,-3104,-1099,-8037,15727,2451,-927,925,6871 } },
6639 { "MOTOROLA PIXL", 0, 0, /* DJC */
6640 { 8898,-989,-1033,-3292,11619,1674,-661,3178,5216 } },
6641 { "NIKON D100", 0, 0,
6642 { 5902,-933,-782,-8983,16719,2354,-1402,1455,6464 } },
6643 { "NIKON D1H", 0, 0,
6644 { 7577,-2166,-926,-7454,15592,1934,-2377,2808,8606 } },
6645 { "NIKON D1X", 0, 0,
6646 { 7702,-2245,-975,-9114,17242,1875,-2679,3055,8521 } },
6647 { "NIKON D1", 0, 0, /* multiplied by 2.218750, 1.0, 1.148438 */
6648 { 16772,-4726,-2141,-7611,15713,1972,-2846,3494,9521 } },
6649 { "NIKON D200", 0, 0xfbc,
6650 { 8367,-2248,-763,-8758,16447,2422,-1527,1550,8053 } },
6651 { "NIKON D2H", 0, 0,
6652 { 5710,-901,-615,-8594,16617,2024,-2975,4120,6830 } },
6653 { "NIKON D2X", 0, 0,
6654 { 10231,-2769,-1255,-8301,15900,2552,-797,680,7148 } },
6655 { "NIKON D3000", 0, 0,
6656 { 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } },
6657 { "NIKON D3100", 0, 0,
6658 { 7911,-2167,-813,-5327,13150,2408,-1288,2483,7968 } },
6659 { "NIKON D3200", 0, 0xfb9,
6660 { 7013,-1408,-635,-5268,12902,2640,-1470,2801,7379 } },
6661 { "NIKON D300", 0, 0,
6662 { 9030,-1992,-715,-8465,16302,2255,-2689,3217,8069 } },
6663 { "NIKON D3X", 0, 0,
6664 { 7171,-1986,-648,-8085,15555,2718,-2170,2512,7457 } },
6665 { "NIKON D3S", 0, 0,
6666 { 8828,-2406,-694,-4874,12603,2541,-660,1509,7587 } },
6668 { 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } },
6669 { "NIKON D40X", 0, 0,
6670 { 8819,-2543,-911,-9025,16928,2151,-1329,1213,8449 } },
6671 { "NIKON D40", 0, 0,
6672 { 6992,-1668,-806,-8138,15748,2543,-874,850,7897 } },
6674 { 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } },
6675 { "NIKON D5000", 0, 0xf00,
6676 { 7309,-1403,-519,-8474,16008,2622,-2433,2826,8064 } },
6677 { "NIKON D5100", 0, 0x3de6,
6678 { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } },
6679 { "NIKON D50", 0, 0,
6680 { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } },
6681 { "NIKON D600", 0, 0x3e07,
6682 { 8178,-2245,-609,-4857,12394,2776,-1207,2086,7298 } },
6683 { "NIKON D60", 0, 0,
6684 { 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } },
6685 { "NIKON D7000", 0, 0,
6686 { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } },
6687 { "NIKON D700", 0, 0,
6688 { 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } },
6689 { "NIKON D70", 0, 0,
6690 { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } },
6691 { "NIKON D800", 0, 0,
6692 { 7866,-2108,-555,-4869,12483,2681,-1176,2069,7501 } },
6693 { "NIKON D80", 0, 0,
6694 { 8629,-2410,-883,-9055,16940,2171,-1490,1363,8520 } },
6695 { "NIKON D90", 0, 0xf00,
6696 { 7309,-1403,-519,-8474,16008,2622,-2434,2826,8064 } },
6697 { "NIKON E950", 0, 0x3dd, /* DJC */
6698 { -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } },
6699 { "NIKON E995", 0, 0, /* copied from E5000 */
6700 { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
6701 { "NIKON E2100", 0, 0, /* copied from Z2, new white balance */
6702 { 13142,-4152,-1596,-4655,12374,2282,-1769,2696,6711} },
6703 { "NIKON E2500", 0, 0,
6704 { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
6705 { "NIKON E3200", 0, 0, /* DJC */
6706 { 9846,-2085,-1019,-3278,11109,2170,-774,2134,5745 } },
6707 { "NIKON E4300", 0, 0, /* copied from Minolta DiMAGE Z2 */
6708 { 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 } },
6709 { "NIKON E4500", 0, 0,
6710 { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
6711 { "NIKON E5000", 0, 0,
6712 { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
6713 { "NIKON E5400", 0, 0,
6714 { 9349,-2987,-1001,-7919,15766,2266,-2098,2680,6839 } },
6715 { "NIKON E5700", 0, 0,
6716 { -5368,11478,2368,5537,-113,3148,-4969,10021,5782,778,9028,211 } },
6717 { "NIKON E8400", 0, 0,
6718 { 7842,-2320,-992,-8154,15718,2599,-1098,1342,7560 } },
6719 { "NIKON E8700", 0, 0,
6720 { 8489,-2583,-1036,-8051,15583,2643,-1307,1407,7354 } },
6721 { "NIKON E8800", 0, 0,
6722 { 7971,-2314,-913,-8451,15762,2894,-1442,1520,7610 } },
6723 { "NIKON COOLPIX P6000", 0, 0,
6724 { 9698,-3367,-914,-4706,12584,2368,-837,968,5801 } },
6725 { "NIKON COOLPIX P7000", 0, 0,
6726 { 11432,-3679,-1111,-3169,11239,2202,-791,1380,4455 } },
6727 { "NIKON COOLPIX P7100", 0, 0,
6728 { 11053,-4269,-1024,-1976,10182,2088,-526,1263,4469 } },
6729 { "NIKON COOLPIX P7700", 200, 0,
6730 { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } },
6731 { "NIKON 1 V2", 0, 0,
6732 { 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } },
6734 { 8994,-2667,-865,-4594,12324,2552,-699,1786,6260 } },
6735 { "OLYMPUS C5050", 0, 0,
6736 { 10508,-3124,-1273,-6079,14294,1901,-1653,2306,6237 } },
6737 { "OLYMPUS C5060", 0, 0,
6738 { 10445,-3362,-1307,-7662,15690,2058,-1135,1176,7602 } },
6739 { "OLYMPUS C7070", 0, 0,
6740 { 10252,-3531,-1095,-7114,14850,2436,-1451,1723,6365 } },
6741 { "OLYMPUS C70", 0, 0,
6742 { 10793,-3791,-1146,-7498,15177,2488,-1390,1577,7321 } },
6743 { "OLYMPUS C80", 0, 0,
6744 { 8606,-2509,-1014,-8238,15714,2703,-942,979,7760 } },
6745 { "OLYMPUS E-10", 0, 0xffc,
6746 { 12745,-4500,-1416,-6062,14542,1580,-1934,2256,6603 } },
6747 { "OLYMPUS E-1", 0, 0,
6748 { 11846,-4767,-945,-7027,15878,1089,-2699,4122,8311 } },
6749 { "OLYMPUS E-20", 0, 0xffc,
6750 { 13173,-4732,-1499,-5807,14036,1895,-2045,2452,7142 } },
6751 { "OLYMPUS E-300", 0, 0,
6752 { 7828,-1761,-348,-5788,14071,1830,-2853,4518,6557 } },
6753 { "OLYMPUS E-330", 0, 0,
6754 { 8961,-2473,-1084,-7979,15990,2067,-2319,3035,8249 } },
6755 { "OLYMPUS E-30", 0, 0xfbc,
6756 { 8144,-1861,-1111,-7763,15894,1929,-1865,2542,7607 } },
6757 { "OLYMPUS E-3", 0, 0xf99,
6758 { 9487,-2875,-1115,-7533,15606,2010,-1618,2100,7389 } },
6759 { "OLYMPUS E-400", 0, 0,
6760 { 6169,-1483,-21,-7107,14761,2536,-2904,3580,8568 } },
6761 { "OLYMPUS E-410", 0, 0xf6a,
6762 { 8856,-2582,-1026,-7761,15766,2082,-2009,2575,7469 } },
6763 { "OLYMPUS E-420", 0, 0xfd7,
6764 { 8746,-2425,-1095,-7594,15612,2073,-1780,2309,7416 } },
6765 { "OLYMPUS E-450", 0, 0xfd2,
6766 { 8745,-2425,-1095,-7594,15613,2073,-1780,2309,7416 } },
6767 { "OLYMPUS E-500", 0, 0,
6768 { 8136,-1968,-299,-5481,13742,1871,-2556,4205,6630 } },
6769 { "OLYMPUS E-510", 0, 0xf6a,
6770 { 8785,-2529,-1033,-7639,15624,2112,-1783,2300,7817 } },
6771 { "OLYMPUS E-520", 0, 0xfd2,
6772 { 8344,-2322,-1020,-7596,15635,2048,-1748,2269,7287 } },
6773 { "OLYMPUS E-5", 0, 0xeec,
6774 { 11200,-3783,-1325,-4576,12593,2206,-695,1742,7504 } },
6775 { "OLYMPUS E-600", 0, 0xfaf,
6776 { 8453,-2198,-1092,-7609,15681,2008,-1725,2337,7824 } },
6777 { "OLYMPUS E-620", 0, 0xfaf,
6778 { 8453,-2198,-1092,-7609,15681,2008,-1725,2337,7824 } },
6779 { "OLYMPUS E-P1", 0, 0xffd,
6780 { 8343,-2050,-1021,-7715,15705,2103,-1831,2380,8235 } },
6781 { "OLYMPUS E-P2", 0, 0xffd,
6782 { 8343,-2050,-1021,-7715,15705,2103,-1831,2380,8235 } },
6783 { "OLYMPUS E-P3", 0, 0,
6784 { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } },
6785 { "OLYMPUS E-PL1s", 0, 0,
6786 { 11409,-3872,-1393,-4572,12757,2003,-709,1810,7415 } },
6787 { "OLYMPUS E-PL1", 0, 0,
6788 { 11408,-4289,-1215,-4286,12385,2118,-387,1467,7787 } },
6789 { "OLYMPUS E-PL2", 0, 0,
6790 { 15030,-5552,-1806,-3987,12387,1767,-592,1670,7023 } },
6791 { "OLYMPUS E-PL3", 0, 0,
6792 { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } },
6793 { "OLYMPUS E-PL5", 0, 0xfcb,
6794 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
6795 { "OLYMPUS E-PM1", 0, 0,
6796 { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } },
6797 { "OLYMPUS E-PM2", 0, 0,
6798 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
6799 { "OLYMPUS E-M5", 0, 0xfe1,
6800 { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
6801 { "OLYMPUS SP350", 0, 0,
6802 { 12078,-4836,-1069,-6671,14306,2578,-786,939,7418 } },
6803 { "OLYMPUS SP3", 0, 0,
6804 { 11766,-4445,-1067,-6901,14421,2707,-1029,1217,7572 } },
6805 { "OLYMPUS SP500UZ", 0, 0xfff,
6806 { 9493,-3415,-666,-5211,12334,3260,-1548,2262,6482 } },
6807 { "OLYMPUS SP510UZ", 0, 0xffe,
6808 { 10593,-3607,-1010,-5881,13127,3084,-1200,1805,6721 } },
6809 { "OLYMPUS SP550UZ", 0, 0xffe,
6810 { 11597,-4006,-1049,-5432,12799,2957,-1029,1750,6516 } },
6811 { "OLYMPUS SP560UZ", 0, 0xff9,
6812 { 10915,-3677,-982,-5587,12986,2911,-1168,1968,6223 } },
6813 { "OLYMPUS SP570UZ", 0, 0,
6814 { 11522,-4044,-1146,-4736,12172,2904,-988,1829,6039 } },
6815 { "OLYMPUS XZ-1", 0, 0,
6816 { 10901,-4095,-1074,-1141,9208,2293,-62,1417,5158 } },
6817 { "OLYMPUS XZ-2", 0, 0,
6818 { 9777,-3483,-925,-2886,11297,1800,-602,1663,5134 } },
6819 { "PENTAX *ist DL2", 0, 0,
6820 { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
6821 { "PENTAX *ist DL", 0, 0,
6822 { 10829,-2838,-1115,-8339,15817,2696,-837,680,11939 } },
6823 { "PENTAX *ist DS2", 0, 0,
6824 { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
6825 { "PENTAX *ist DS", 0, 0,
6826 { 10371,-2333,-1206,-8688,16231,2602,-1230,1116,11282 } },
6827 { "PENTAX *ist D", 0, 0,
6828 { 9651,-2059,-1189,-8881,16512,2487,-1460,1345,10687 } },
6829 { "PENTAX K10D", 0, 0,
6830 { 9566,-2863,-803,-7170,15172,2112,-818,803,9705 } },
6831 { "PENTAX K1", 0, 0,
6832 { 11095,-3157,-1324,-8377,15834,2720,-1108,947,11688 } },
6833 { "PENTAX K20D", 0, 0,
6834 { 9427,-2714,-868,-7493,16092,1373,-2199,3264,7180 } },
6835 { "PENTAX K200D", 0, 0,
6836 { 9186,-2678,-907,-8693,16517,2260,-1129,1094,8524 } },
6837 { "PENTAX K2000", 0, 0,
6838 { 11057,-3604,-1155,-5152,13046,2329,-282,375,8104 } },
6839 { "PENTAX K-m", 0, 0,
6840 { 11057,-3604,-1155,-5152,13046,2329,-282,375,8104 } },
6841 { "PENTAX K-x", 0, 0,
6842 { 8843,-2837,-625,-5025,12644,2668,-411,1234,7410 } },
6843 { "PENTAX K-r", 0, 0,
6844 { 9895,-3077,-850,-5304,13035,2521,-883,1768,6936 } },
6845 { "PENTAX K-5 II", 0, 0,
6846 { 8170,-2725,-639,-4440,12017,2744,-771,1465,6599 } },
6847 { "PENTAX K-5", 0, 0,
6848 { 8713,-2833,-743,-4342,11900,2772,-722,1543,6247 } },
6849 { "PENTAX K-7", 0, 0,
6850 { 9142,-2947,-678,-8648,16967,1663,-2224,2898,8615 } },
6851 { "PENTAX 645D", 0, 0x3e00,
6852 { 10646,-3593,-1158,-3329,11699,1831,-667,2874,6287 } },
6853 { "Panasonic DMC-FZ8", 0, 0xf7f,
6854 { 8986,-2755,-802,-6341,13575,3077,-1476,2144,6379 } },
6855 { "Panasonic DMC-FZ18", 0, 0,
6856 { 9932,-3060,-935,-5809,13331,2753,-1267,2155,5575 } },
6857 { "Panasonic DMC-FZ28", 15, 0xf96,
6858 { 10109,-3488,-993,-5412,12812,2916,-1305,2140,5543 } },
6859 { "Panasonic DMC-FZ30", 0, 0xf94,
6860 { 10976,-4029,-1141,-7918,15491,2600,-1670,2071,8246 } },
6861 { "Panasonic DMC-FZ3", 143, 0,
6862 { 9938,-2780,-890,-4604,12393,2480,-1117,2304,4620 } },
6863 { "Panasonic DMC-FZ4", 143, 0,
6864 { 13639,-5535,-1371,-1698,9633,2430,316,1152,4108 } },
6865 { "Panasonic DMC-FZ50", 0, 0,
6866 { 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } },
6867 { "LEICA V-LUX1", 0, 0,
6868 { 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } },
6869 { "Panasonic DMC-L10", 15, 0xf96,
6870 { 8025,-1942,-1050,-7920,15904,2100,-2456,3005,7039 } },
6871 { "Panasonic DMC-L1", 0, 0xf7f,
6872 { 8054,-1885,-1025,-8349,16367,2040,-2805,3542,7629 } },
6873 { "LEICA DIGILUX 3", 0, 0xf7f,
6874 { 8054,-1885,-1025,-8349,16367,2040,-2805,3542,7629 } },
6875 { "Panasonic DMC-LC1", 0, 0,
6876 { 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } },
6877 { "LEICA DIGILUX 2", 0, 0,
6878 { 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } },
6879 { "Panasonic DMC-LX1", 0, 0xf7f,
6880 { 10704,-4187,-1230,-8314,15952,2501,-920,945,8927 } },
6881 { "LEICA D-LUX2", 0, 0xf7f,
6882 { 10704,-4187,-1230,-8314,15952,2501,-920,945,8927 } },
6883 { "Panasonic DMC-LX2", 0, 0,
6884 { 8048,-2810,-623,-6450,13519,3272,-1700,2146,7049 } },
6885 { "LEICA D-LUX3", 0, 0,
6886 { 8048,-2810,-623,-6450,13519,3272,-1700,2146,7049 } },
6887 { "Panasonic DMC-LX3", 15, 0,
6888 { 8128,-2668,-655,-6134,13307,3161,-1782,2568,6083 } },
6889 { "LEICA D-LUX 4", 15, 0,
6890 { 8128,-2668,-655,-6134,13307,3161,-1782,2568,6083 } },
6891 { "Panasonic DMC-LX5", 143, 0,
6892 { 10909,-4295,-948,-1333,9306,2399,22,1738,4582 } },
6893 { "LEICA D-LUX 5", 143, 0,
6894 { 10909,-4295,-948,-1333,9306,2399,22,1738,4582 } },
6895 { "Panasonic DMC-LX7", 143, 0,
6896 { 10148,-3743,-991,-2837,11366,1659,-701,1893,4899 } },
6897 { "LEICA D-LUX 6", 143, 0,
6898 { 10148,-3743,-991,-2837,11366,1659,-701,1893,4899 } },
6899 { "Panasonic DMC-FZ100", 143, 0xfff,
6900 { 16197,-6146,-1761,-2393,10765,1869,366,2238,5248 } },
6901 { "LEICA V-LUX 2", 143, 0xfff,
6902 { 16197,-6146,-1761,-2393,10765,1869,366,2238,5248 } },
6903 { "Panasonic DMC-FZ150", 143, 0xfff,
6904 { 11904,-4541,-1189,-2355,10899,1662,-296,1586,4289 } },
6905 { "LEICA V-LUX 3", 143, 0xfff,
6906 { 11904,-4541,-1189,-2355,10899,1662,-296,1586,4289 } },
6907 { "Panasonic DMC-FZ200", 143, 0xfff,
6908 { 8112,-2563,-740,-3730,11784,2197,-941,2075,4933 } },
6909 { "LEICA V-LUX 4", 143, 0xfff,
6910 { 8112,-2563,-740,-3730,11784,2197,-941,2075,4933 } },
6911 { "Panasonic DMC-FX150", 15, 0xfff,
6912 { 9082,-2907,-925,-6119,13377,3058,-1797,2641,5609 } },
6913 { "Panasonic DMC-G10", 0, 0,
6914 { 10113,-3400,-1114,-4765,12683,2317,-377,1437,6710 } },
6915 { "Panasonic DMC-G1", 15, 0xf94,
6916 { 8199,-2065,-1056,-8124,16156,2033,-2458,3022,7220 } },
6917 { "Panasonic DMC-G2", 15, 0xf3c,
6918 { 10113,-3400,-1114,-4765,12683,2317,-377,1437,6710 } },
6919 { "Panasonic DMC-G3", 143, 0xfff,
6920 { 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } },
6921 { "Panasonic DMC-G5", 143, 0xfff,
6922 { 7798,-2562,-740,-3879,11584,2613,-1055,2248,5434 } },
6923 { "Panasonic DMC-GF1", 15, 0xf92,
6924 { 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } },
6925 { "Panasonic DMC-GF2", 143, 0xfff,
6926 { 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } },
6927 { "Panasonic DMC-GF3", 143, 0xfff,
6928 { 9051,-2468,-1204,-5212,13276,2121,-1197,2510,6890 } },
6929 { "Panasonic DMC-GF5", 143, 0xfff,
6930 { 8228,-2945,-660,-3938,11792,2430,-1094,2278,5793 } },
6931 { "Panasonic DMC-GH1", 15, 0xf92,
6932 { 6299,-1466,-532,-6535,13852,2969,-2331,3112,5984 } },
6933 { "Panasonic DMC-GH2", 15, 0xf95,
6934 { 7780,-2410,-806,-3913,11724,2484,-1018,2390,5298 } },
6935 { "Panasonic DMC-GH3", 144, 0,
6936 { 6559,-1752,-491,-3672,11407,2586,-962,1875,5130 } },
6937 { "Panasonic DMC-GX1", 143, 0,
6938 { 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } },
6939 { "Phase One H 20", 0, 0, /* DJC */
6940 { 1313,1855,-109,-6715,15908,808,-327,1840,6020 } },
6941 { "Phase One H 25", 0, 0,
6942 { 2905,732,-237,-8134,16626,1476,-3038,4253,7517 } },
6943 { "Phase One P 2", 0, 0,
6944 { 2905,732,-237,-8134,16626,1476,-3038,4253,7517 } },
6945 { "Phase One P 30", 0, 0,
6946 { 4516,-245,-37,-7020,14976,2173,-3206,4671,7087 } },
6947 { "Phase One P 45", 0, 0,
6948 { 5053,-24,-117,-5684,14076,1702,-2619,4492,5849 } },
6949 { "Phase One P40", 0, 0,
6950 { 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } },
6951 { "Phase One P65", 0, 0,
6952 { 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } },
6953 { "RED ONE", 704, 0xffff, /* DJC */
6954 { 21014,-7891,-2613,-3056,12201,856,-2203,5125,8042 } },
6955 { "SAMSUNG EX1", 0, 0x3e00,
6956 { 8898,-2498,-994,-3144,11328,2066,-760,1381,4576 } },
6957 { "SAMSUNG EX2F", 0, 0x7ff,
6958 { 10648,-3897,-1055,-2022,10573,1668,-492,1611,4742 } },
6959 { "SAMSUNG NX2", 0, 0xfff, /* NX20, NX200, NX210 */
6960 { 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } },
6961 { "SAMSUNG NX1000", 0, 0,
6962 { 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } },
6963 { "SAMSUNG NX", 0, 0, /* NX5, NX10, NX11, NX100 */
6964 { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } },
6965 { "SAMSUNG WB2000", 0, 0xfff,
6966 { 12093,-3557,-1155,-1000,9534,1733,-22,1787,4576 } },
6967 { "SAMSUNG GX-1", 0, 0,
6968 { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
6969 { "SAMSUNG S85", 0, 0xffff, /* DJC */
6970 { 11885,-3968,-1473,-4214,12299,1916,-835,1655,5549 } },
6971 { "Sinar", 0, 0, /* DJC */
6972 { 16442,-2956,-2422,-2877,12128,750,-1136,6066,4559 } },
6973 { "SONY DSC-F828", 0, 0,
6974 { 7924,-1910,-777,-8226,15459,2998,-1517,2199,6818,-7242,11401,3481 } },
6975 { "SONY DSC-R1", 512, 0,
6976 { 8512,-2641,-694,-8042,15670,2526,-1821,2117,7414 } },
6977 { "SONY DSC-V3", 0, 0,
6978 { 7511,-2571,-692,-7894,15088,3060,-948,1111,8128 } },
6979 { "SONY DSC-RX100", 200, 0,
6980 { 8651,-2754,-1057,-3464,12207,1373,-568,1398,4434 } },
6981 { "SONY DSC-RX1", 128, 0,
6982 { 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } },
6983 { "SONY DSLR-A100", 0, 0xfeb,
6984 { 9437,-2811,-774,-8405,16215,2290,-710,596,7181 } },
6985 { "SONY DSLR-A290", 0, 0,
6986 { 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } },
6987 { "SONY DSLR-A2", 0, 0,
6988 { 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } },
6989 { "SONY DSLR-A300", 0, 0,
6990 { 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } },
6991 { "SONY DSLR-A330", 0, 0,
6992 { 9847,-3091,-929,-8485,16346,2225,-714,595,7103 } },
6993 { "SONY DSLR-A350", 0, 0xffc,
6994 { 6038,-1484,-578,-9146,16746,2513,-875,746,7217 } },
6995 { "SONY DSLR-A380", 0, 0,
6996 { 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } },
6997 { "SONY DSLR-A390", 0, 0,
6998 { 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } },
6999 { "SONY DSLR-A450", 128, 0xfeb,
7000 { 4950,-580,-103,-5228,12542,3029,-709,1435,7371 } },
7001 { "SONY DSLR-A580", 128, 0xfeb,
7002 { 5932,-1492,-411,-4813,12285,2856,-741,1524,6739 } },
7003 { "SONY DSLR-A5", 128, 0xfeb,
7004 { 4950,-580,-103,-5228,12542,3029,-709,1435,7371 } },
7005 { "SONY DSLR-A700", 126, 0,
7006 { 5775,-805,-359,-8574,16295,2391,-1943,2341,7249 } },
7007 { "SONY DSLR-A850", 128, 0,
7008 { 5413,-1162,-365,-5665,13098,2866,-608,1179,8440 } },
7009 { "SONY DSLR-A900", 128, 0,
7010 { 5209,-1072,-397,-8845,16120,2919,-1618,1803,8654 } },
7011 { "SONY NEX-5N", 128, 0,
7012 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
7013 { "SONY NEX-5R", 128, 0,
7014 { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } },
7015 { "SONY NEX-3", 138, 0, /* DJC */
7016 { 6907,-1256,-645,-4940,12621,2320,-1710,2581,6230 } },
7017 { "SONY NEX-5", 116, 0, /* DJC */
7018 { 6807,-1350,-342,-4216,11649,2567,-1089,2001,6420 } },
7019 { "SONY NEX-3", 128, 0, /* Adobe */
7020 { 6549,-1550,-436,-4880,12435,2753,-854,1868,6976 } },
7021 { "SONY NEX-5", 128, 0, /* Adobe */
7022 { 6549,-1550,-436,-4880,12435,2753,-854,1868,6976 } },
7023 { "SONY NEX-6", 128, 0,
7024 { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } },
7025 { "SONY NEX-7", 128, 0,
7026 { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } },
7027 { "SONY NEX", 128, 0, /* NEX-C3, NEX-F3 */
7028 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
7029 { "SONY SLT-A33", 128, 0,
7030 { 6069,-1221,-366,-5221,12779,2734,-1024,2066,6834 } },
7031 { "SONY SLT-A35", 128, 0,
7032 { 5986,-1618,-415,-4557,11820,3120,-681,1404,6971 } },
7033 { "SONY SLT-A37", 128, 0,
7034 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
7035 { "SONY SLT-A55", 128, 0,
7036 { 5932,-1492,-411,-4813,12285,2856,-741,1524,6739 } },
7037 { "SONY SLT-A57", 128, 0,
7038 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
7039 { "SONY SLT-A65", 128, 0,
7040 { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } },
7041 { "SONY SLT-A77", 128, 0,
7042 { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } },
7043 { "SONY SLT-A99", 128, 0,
7044 { 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } },
7046 double cam_xyz[4][3];
7050 sprintf (name, "%s %s", make, model);
7051 for (i=0; i < sizeof table / sizeof *table; i++)
7052 if (!strncmp (name, table[i].prefix, strlen(table[i].prefix))) {
7053 if (table[i].black) black = (ushort) table[i].black;
7054 if (table[i].maximum) maximum = (ushort) table[i].maximum;
7055 if (table[i].trans[0]) {
7056 double *dp = &cam_xyz[0][0];
7057 const short *sp = &table[i].trans[0];
7058 for( j=12; --j>=0; ++dp,++sp ) *dp = *sp / 10000.0;
7059 cam_xyz_coeff (cam_xyz);
7065 void CLASS simple_coeff (int index)
7067 static const float table[][12] = {
7068 /* index 0 -- all Foveon cameras */
7069 { 1.4032,-0.2231,-0.1016,-0.5263,1.4816,0.017,-0.0112,0.0183,0.9113 },
7070 /* index 1 -- Kodak DC20 and DC25 */
7071 { 2.25,0.75,-1.75,-0.25,-0.25,0.75,0.75,-0.25,-0.25,-1.75,0.75,2.25 },
7072 /* index 2 -- Logitech Fotoman Pixtura */
7073 { 1.893,-0.418,-0.476,-0.495,1.773,-0.278,-1.017,-0.655,2.672 },
7074 /* index 3 -- Nikon E880, E900, and E990 */
7075 { -1.936280, 1.800443, -1.448486, 2.584324,
7076 1.405365, -0.524955, -0.289090, 0.408680,
7077 -1.204965, 1.082304, 2.941367, -1.818705 }
7081 for (raw_color = i=0; i < 3; i++)
7082 FORCC rgb_cam[i][c] = table[index][i*colors+c];
7085 short CLASS guess_byte_order (int words)
7089 double diff, sum[2] = {0,0};
7091 fread (test[0], 2, 2, ifp);
7092 for (words-=2; words--; ) {
7093 fread (test[t], 2, 1, ifp);
7094 for (msb=0; msb < 2; msb++) {
7095 diff = (test[t^2][msb] << 8 | test[t^2][!msb])
7096 - (test[t ][msb] << 8 | test[t ][!msb]);
7097 sum[msb] += diff*diff;
7101 return sum[0] < sum[1] ? 0x4d4d : 0x4949;
7104 float CLASS find_green (int bps, int bite, int off0, int off1)
7107 int vbits, col, i, c;
7108 ushort img[2][2064];
7112 fseek (ifp, c ? off1:off0, SEEK_SET);
7113 for (vbits=col=0; col < width; col++) {
7114 for (vbits -= bps; vbits < 0; vbits += bite) {
7116 for (i=0; i < bite; i+=8)
7117 bitbuf |= (unsigned) (fgetc(ifp) << i);
7119 img[c][col] = bitbuf << (64-bps-vbits) >> (64-bps);
7123 sum[ c & 1] += ABS(img[0][c]-img[1][c+1]);
7124 sum[~c & 1] += ABS(img[1][c]-img[0][c+1]);
7126 return 100 * log(sum[0]/sum[1]);
7130 Identify which camera created this file, and set global variables
7133 void CLASS identify()
7136 int hlen, flen, fsize, zero_fsize=1, i, c, is_canon;
7139 { 3130, 1743, 4, 0, -6, 0 },
7140 { 3130, 2055, 4, 0, -6, 0 },
7141 { 3130, 2319, 4, 0, -6, 0 },
7142 { 3170, 2103, 18, 0,-42, 20 },
7143 { 3170, 2367, 18, 13,-42,-21 },
7144 { 3177, 2367, 0, 0, -1, 0 },
7145 { 3304, 2458, 0, 0, -1, 0 },
7146 { 3330, 2463, 9, 0, -5, 0 },
7147 { 3330, 2479, 9, 0,-17, 4 },
7148 { 3370, 1899, 15, 0,-44, 20 },
7149 { 3370, 2235, 15, 0,-44, 20 },
7150 { 3370, 2511, 15, 10,-44,-21 },
7151 { 3690, 2751, 3, 0, -8, -3 },
7152 { 3710, 2751, 0, 0, -3, 0 },
7153 { 3724, 2450, 0, 0, 0, -2 },
7154 { 3770, 2487, 17, 0,-44, 19 },
7155 { 3770, 2799, 17, 15,-44,-19 },
7156 { 3880, 2170, 6, 0, -6, 0 },
7157 { 4060, 3018, 0, 0, 0, -2 },
7158 { 4290, 2391, 3, 0, -8, -1 },
7159 { 4330, 2439, 17, 15,-44,-19 },
7160 { 4508, 2962, 0, 0, -3, -4 },
7161 { 4508, 3330, 0, 0, -3, -6 } };
7162 static const struct {
7164 char make[12], model[19], withjpeg;
7166 { 62464, "Kodak", "DC20" ,0 },
7167 { 124928, "Kodak", "DC20" ,0 },
7168 { 1652736, "Kodak", "DCS200" ,0 },
7169 { 4159302, "Kodak", "C330" ,0 },
7170 { 4162462, "Kodak", "C330" ,0 },
7171 { 460800, "Kodak", "C603v" ,0 },
7172 { 614400, "Kodak", "C603v" ,0 },
7173 { 6163328, "Kodak", "C603" ,0 },
7174 { 6166488, "Kodak", "C603" ,0 },
7175 { 9116448, "Kodak", "C603y" ,0 },
7176 { 311696, "ST Micro", "STV680 VGA" ,0 }, /* SPYz */
7177 { 787456, "Creative", "PC-CAM 600" ,0 },
7178 { 1138688, "Minolta", "RD175" ,0 },
7179 { 3840000, "Foculus", "531C" ,0 },
7180 { 307200, "Generic", "640x480" ,0 },
7181 { 786432, "AVT", "F-080C" ,0 },
7182 { 1447680, "AVT", "F-145C" ,0 },
7183 { 1920000, "AVT", "F-201C" ,0 },
7184 { 5067304, "AVT", "F-510C" ,0 },
7185 { 5067316, "AVT", "F-510C" ,0 },
7186 { 10134608, "AVT", "F-510C" ,0 },
7187 { 10134620, "AVT", "F-510C" ,0 },
7188 { 16157136, "AVT", "F-810C" ,0 },
7189 { 1409024, "Sony", "XCD-SX910CR" ,0 },
7190 { 2818048, "Sony", "XCD-SX910CR" ,0 },
7191 { 3884928, "Micron", "2010" ,0 },
7192 { 6624000, "Pixelink", "A782" ,0 },
7193 { 13248000, "Pixelink", "A782" ,0 },
7194 { 6291456, "RoverShot","3320AF" ,0 },
7195 { 6553440, "Canon", "PowerShot A460" ,0 },
7196 { 6653280, "Canon", "PowerShot A530" ,0 },
7197 { 6573120, "Canon", "PowerShot A610" ,0 },
7198 { 9219600, "Canon", "PowerShot A620" ,0 },
7199 { 9243240, "Canon", "PowerShot A470" ,0 },
7200 { 10341600, "Canon", "PowerShot A720 IS",0 },
7201 { 10383120, "Canon", "PowerShot A630" ,0 },
7202 { 12945240, "Canon", "PowerShot A640" ,0 },
7203 { 15636240, "Canon", "PowerShot A650" ,0 },
7204 { 5298000, "Canon", "PowerShot SD300" ,0 },
7205 { 7710960, "Canon", "PowerShot S3 IS" ,0 },
7206 { 15467760, "Canon", "PowerShot SX110 IS",0 },
7207 { 15534576, "Canon", "PowerShot SX120 IS",0 },
7208 { 18653760, "Canon", "PowerShot SX20 IS",0 },
7209 { 19131120, "Canon", "PowerShot SX220 HS",0 },
7210 { 21936096, "Canon", "PowerShot SX30 IS",0 },
7211 { 5939200, "OLYMPUS", "C770UZ" ,0 },
7212 { 1581060, "NIKON", "E900" ,1 }, /* or E900s,E910 */
7213 { 2465792, "NIKON", "E950" ,1 }, /* or E800,E700 */
7214 { 2940928, "NIKON", "E2100" ,1 }, /* or E2500 */
7215 { 4771840, "NIKON", "E990" ,1 }, /* or E995, Oly C3030Z */
7216 { 4775936, "NIKON", "E3700" ,1 }, /* or Optio 33WR */
7217 { 5869568, "NIKON", "E4300" ,1 }, /* or DiMAGE Z2 */
7218 { 5865472, "NIKON", "E4500" ,1 },
7219 { 7438336, "NIKON", "E5000" ,1 }, /* or E5700 */
7220 { 8998912, "NIKON", "COOLPIX S6" ,1 },
7221 { 1976352, "CASIO", "QV-2000UX" ,1 },
7222 { 3217760, "CASIO", "QV-3*00EX" ,1 },
7223 { 6218368, "CASIO", "QV-5700" ,1 },
7224 { 6054400, "CASIO", "QV-R41" ,1 },
7225 { 7530816, "CASIO", "QV-R51" ,1 },
7226 { 7684000, "CASIO", "QV-4000" ,1 },
7227 { 2937856, "CASIO", "EX-S20" ,1 },
7228 { 4948608, "CASIO", "EX-S100" ,1 },
7229 { 7542528, "CASIO", "EX-Z50" ,1 },
7230 { 7562048, "CASIO", "EX-Z500" ,1 },
7231 { 7753344, "CASIO", "EX-Z55" ,1 },
7232 { 7816704, "CASIO", "EX-Z60" ,1 },
7233 { 10843712, "CASIO", "EX-Z75" ,1 },
7234 { 10834368, "CASIO", "EX-Z750" ,1 },
7235 { 12310144, "CASIO", "EX-Z850" ,1 },
7236 { 12489984, "CASIO", "EX-Z8" ,1 },
7237 { 15499264, "CASIO", "EX-Z1050" ,1 },
7238 { 18702336, "CASIO", "EX-ZR100" ,1 },
7239 { 7426656, "CASIO", "EX-P505" ,1 },
7240 { 9313536, "CASIO", "EX-P600" ,1 },
7241 { 10979200, "CASIO", "EX-P700" ,1 },
7242 { 3178560, "PENTAX", "Optio S" ,1 },
7243 { 4841984, "PENTAX", "Optio S" ,1 },
7244 { 6114240, "PENTAX", "Optio S4" ,1 }, /* or S4i, CASIO EX-Z4 */
7245 { 10702848, "PENTAX", "Optio 750Z" ,1 },
7246 { 15980544, "AGFAPHOTO","DC-833m" ,1 },
7247 { 16098048, "SAMSUNG", "S85" ,1 },
7248 { 16215552, "SAMSUNG", "S85" ,1 },
7249 { 20487168, "SAMSUNG", "WB550" ,1 },
7250 { 24000000, "SAMSUNG", "WB550" ,1 },
7251 { 12582980, "Sinar", "" ,0 },
7252 { 33292868, "Sinar", "" ,0 },
7253 { 44390468, "Sinar", "" ,0 } };
7254 static const char *corp[] =
7255 { "Canon", "NIKON", "EPSON", "KODAK", "Kodak", "OLYMPUS", "PENTAX",
7256 "MINOLTA", "Minolta", "Konica", "CASIO", "Sinar", "Phase One",
7257 "SAMSUNG", "Mamiya", "MOTOROLA", "LEICA" };
7259 tiff_flip = flip = filters = -1; /* 0 is valid, so -1 is unknown */
7260 raw_height = raw_width = fuji_width = fuji_layout = cr2_slice[0] = 0;
7261 maximum = height = width = top_margin = left_margin = 0;
7262 cdesc[0] = desc[0] = artist[0] = make[0] = model[0] = model2[0] = 0;
7263 iso_speed = shutter = aperture = focal_len = unique_id = 0;
7265 memset (tiff_ifd, 0, sizeof tiff_ifd);
7266 memset (gpsdata, 0, sizeof gpsdata);
7267 memset (cblack, 0, sizeof cblack);
7268 memset (white, 0, sizeof white);
7269 memset (mask, 0, sizeof mask);
7270 thumb_offset = thumb_length = thumb_width = thumb_height = 0;
7271 load_raw = thumb_load_raw = 0;
7272 write_thumb = &CLASS jpeg_thumb;
7273 data_offset = meta_length = tiff_bps = tiff_compress = 0;
7274 kodak_cbpp = zero_after_ff = dng_version = load_flags = 0;
7275 timestamp = shot_order = tiff_samples = black = is_foveon = 0;
7276 mix_green = profile_length = data_error = zero_is_bad = 0;
7277 pixel_aspect = is_raw = raw_color = 1;
7278 tile_width = tile_length = 0;
7279 for (i=0; i < 4; i++) {
7280 cam_mul[i] = i == 1;
7282 FORC3 cmatrix[c][i] = 0;
7283 FORC3 rgb_cam[c][i] = c == i;
7286 for (i=0; i < 0x10000; i++) curve[i] = i;
7290 fseek (ifp, 0, SEEK_SET);
7291 fread (head, 1, 32, ifp);
7292 fseek (ifp, 0, SEEK_END);
7293 flen = fsize = ftell(ifp);
7294 if ((cp = (char *) memmem (head, 32, "MMMM", 4)) ||
7295 (cp = (char *) memmem (head, 32, "IIII", 4))) {
7296 parse_phase_one (cp-head);
7297 if (cp-head && parse_tiff(0)) apply_tiff();
7298 } else if (order == 0x4949 || order == 0x4d4d) {
7299 if (!memcmp (head+6,"HEAPCCDR",8)) {
7301 parse_ciff (hlen, flen - hlen);
7302 } else if (parse_tiff(0)) apply_tiff();
7303 } else if (!memcmp (head,"\xff\xd8\xff\xe1",4) &&
7304 !memcmp (head+6,"Exif",4)) {
7305 fseek (ifp, 4, SEEK_SET);
7306 data_offset = 4 + get2();
7307 fseek (ifp, data_offset, SEEK_SET);
7308 if (fgetc(ifp) != 0xff)
7311 } else if (!memcmp (head+25,"ARECOYK",7)) {
7312 strcpy (make, "Contax");
7313 strcpy (model,"N Digital");
7314 fseek (ifp, 33, SEEK_SET);
7316 fseek (ifp, 60, SEEK_SET);
7317 FORC4 cam_mul[c ^ (c >> 1)] = get4();
7318 } else if (!strcmp (head, "PXN")) {
7319 strcpy (make, "Logitech");
7320 strcpy (model,"Fotoman Pixtura");
7321 } else if (!strcmp (head, "qktk")) {
7322 strcpy (make, "Apple");
7323 strcpy (model,"QuickTake 100");
7324 load_raw = &CLASS quicktake_100_load_raw;
7325 } else if (!strcmp (head, "qktn")) {
7326 strcpy (make, "Apple");
7327 strcpy (model,"QuickTake 150");
7328 load_raw = &CLASS kodak_radc_load_raw;
7329 } else if (!memcmp (head,"FUJIFILM",8)) {
7330 fseek (ifp, 84, SEEK_SET);
7331 thumb_offset = get4();
7332 thumb_length = get4();
7333 fseek (ifp, 92, SEEK_SET);
7334 parse_fuji (get4());
7335 if (thumb_offset > 120) {
7336 fseek (ifp, 120, SEEK_SET);
7337 is_raw += (i = get4()) && 1;
7338 if (is_raw == 2 && shot_select)
7341 load_raw = &CLASS unpacked_load_raw;
7342 fseek (ifp, 100+28*(shot_select > 0), SEEK_SET);
7343 parse_tiff (data_offset = get4());
7344 parse_tiff (thumb_offset+12);
7346 } else if (!memcmp (head,"RIFF",4)) {
7347 fseek (ifp, 0, SEEK_SET);
7349 } else if (!memcmp (head,"\0\001\0\001\0@",6)) {
7350 fseek (ifp, 6, SEEK_SET);
7351 fread (make, 1, 8, ifp);
7352 fread (model, 1, 8, ifp);
7353 fread (model2, 1, 16, ifp);
7354 data_offset = get2();
7357 raw_height = get2();
7358 load_raw = &CLASS nokia_load_raw;
7359 filters = 0x61616161;
7360 } else if (!memcmp (head,"NOKIARAW",8)) {
7361 strcpy (make, "NOKIA");
7362 strcpy (model, "X2");
7364 fseek (ifp, 300, SEEK_SET);
7365 data_offset = get4();
7369 data_offset += i - width * 5 / 4 * height;
7370 load_raw = &CLASS nokia_load_raw;
7371 filters = 0x61616161;
7372 } else if (!memcmp (head,"ARRI",4)) {
7374 fseek (ifp, 20, SEEK_SET);
7377 strcpy (make, "ARRI");
7378 fseek (ifp, 668, SEEK_SET);
7379 fread (model, 1, 64, ifp);
7381 load_raw = &CLASS packed_load_raw;
7383 filters = 0x61616161;
7384 } else if (!memcmp (head+4,"RED1",4)) {
7385 strcpy (make, "RED");
7386 strcpy (model,"ONE");
7388 load_raw = &CLASS redcine_load_raw;
7389 gamma_curve (1/2.4, 12.92, 1, 4095);
7390 filters = 0x49494949;
7391 } else if (!memcmp (head,"DSC-Image",9))
7393 else if (!memcmp (head,"PWAD",4))
7395 else if (!memcmp (head,"\0MRM",4))
7397 else if (!memcmp (head,"FOVb",4))
7399 else if (!memcmp (head,"CI",2))
7402 for (zero_fsize=i=0; i < sizeof table / sizeof *table; i++)
7403 if (fsize == table[i].fsize) {
7404 strcpy (make, table[i].make );
7405 strcpy (model, table[i].model);
7406 if (table[i].withjpeg)
7407 parse_external_jpeg();
7409 if (zero_fsize) fsize = 0;
7410 if (make[0] == 0) parse_smal (0, flen);
7411 if (make[0] == 0) parse_jpeg (is_raw = 0);
7413 for (i=0; i < sizeof corp / sizeof *corp; i++)
7414 if (strstr (make, corp[i])) /* Simplify company names */
7415 strcpy (make, corp[i]);
7416 if (!strncmp (make,"KODAK",5) &&
7417 ((cp = strstr(model," DIGITAL CAMERA")) ||
7418 (cp = strstr(model," Digital Camera")) ||
7419 (cp = strstr(model,"FILE VERSION"))))
7421 cp = make + strlen(make); /* Remove trailing spaces */
7422 while (*--cp == ' ') *cp = 0;
7423 cp = model + strlen(model);
7424 while (*--cp == ' ') *cp = 0;
7425 i = strlen(make); /* Remove make from model */
7426 if (!strncasecmp (model, make, i) && model[i++] == ' ')
7427 memmove (model, model+i, 64-i);
7428 if (!strncmp (model,"FinePix ",8))
7429 strcpy (model, model+8);
7430 if (!strncmp (model,"Digital Camera ",15))
7431 strcpy (model, model+15);
7432 desc[511] = artist[63] = make[63] = model[63] = model2[63] = 0;
7433 if (!is_raw) goto notraw;
7435 if (!height) height = raw_height;
7436 if (!width) width = raw_width;
7437 if (height == 2624 && width == 3936) /* Pentax K10D and Samsung GX10 */
7438 { height = 2616; width = 3896; }
7439 if (height == 3136 && width == 4864) /* Pentax K20D and Samsung GX20 */
7440 { height = 3124; width = 4688; filters = 0x16161616; }
7441 if (width == 4352 && (!strcmp(model,"K-r") || !strcmp(model,"K-x")))
7442 { width = 4309; filters = 0x16161616; }
7443 if (width >= 4960 && !strncmp(model,"K-5",3))
7444 { left_margin = 10; width = 4950; filters = 0x16161616; }
7445 if (width == 4736 && !strcmp(model,"K-7"))
7446 { height = 3122; width = 4684; filters = 0x16161616; top_margin = 2; }
7447 if (width == 7424 && !strcmp(model,"645D"))
7448 { height = 5502; width = 7328; filters = 0x61616161; top_margin = 29;
7450 if (height == 3014 && width == 4096) /* Ricoh GX200 */
7453 if (filters == UINT_MAX) filters = 0;
7454 if (filters) is_raw = tiff_samples;
7455 else colors = tiff_samples;
7456 if (tiff_compress == 1)
7457 load_raw = &CLASS packed_dng_load_raw;
7458 if (tiff_compress == 7)
7459 load_raw = &CLASS lossless_dng_load_raw;
7462 if ((is_canon = !strcmp(make,"Canon")))
7463 load_raw = memcmp (head+6,"HEAPCCDR",8) ?
7464 &CLASS lossless_jpeg_load_raw : &CLASS canon_load_raw;
7465 if (!strcmp(make,"NIKON")) {
7467 load_raw = &CLASS packed_load_raw;
7468 if (model[0] == 'E')
7469 load_flags |= !data_offset << 2 | 2;
7471 if (!strcmp(make,"CASIO")) {
7472 load_raw = &CLASS packed_load_raw;
7476 /* Set parameters based on camera name (for non-DNG files). */
7479 if (height*2 < width) pixel_aspect = 0.5;
7480 if (height > width) pixel_aspect = 2;
7483 } else if (is_canon && tiff_bps == 15) {
7485 case 3344: width -= 66;
7486 case 3872: width -= 6;
7488 if (height > width) SWAP(height,width);
7490 load_raw = &CLASS canon_sraw_load_raw;
7491 } else if (!strcmp(model,"PowerShot 600")) {
7495 pixel_aspect = 607/628.0;
7497 filters = 0xe1e4e1e4;
7498 load_raw = &CLASS canon_600_load_raw;
7499 } else if (!strcmp(model,"PowerShot A5") ||
7500 !strcmp(model,"PowerShot A5 Zoom")) {
7504 pixel_aspect = 256/235.0;
7506 filters = 0x1e4e1e4e;
7508 } else if (!strcmp(model,"PowerShot A50")) {
7513 filters = 0x1b4e4b1e;
7515 } else if (!strcmp(model,"PowerShot Pro70")) {
7519 filters = 0x1e4b4e1b;
7521 } else if (!strcmp(model,"PowerShot SD300")) {
7529 } else if (!strcmp(model,"PowerShot A460")) {
7537 } else if (!strcmp(model,"PowerShot A530")) {
7545 } else if (!strcmp(model,"PowerShot A610")) {
7546 if (canon_s2is()) strcpy (model+10, "S2 IS");
7554 } else if (!strcmp(model,"PowerShot A620")) {
7562 } else if (!strcmp(model,"PowerShot A470")) {
7570 } else if (!strcmp(model,"PowerShot A720 IS")) {
7578 } else if (!strcmp(model,"PowerShot A630")) {
7586 } else if (!strcmp(model,"PowerShot A640")) {
7594 } else if (!strcmp(model,"PowerShot A650")) {
7602 } else if (!strcmp(model,"PowerShot S3 IS")) {
7611 load_raw = &CLASS packed_load_raw;
7613 if (raw_width > 1600) zero_is_bad = 1;
7614 } else if (!strcmp(model,"PowerShot SX110 IS")) {
7621 load_raw = &CLASS packed_load_raw;
7624 } else if (!strcmp(model,"PowerShot SX120 IS")) {
7631 filters = 0x49494949;
7632 load_raw = &CLASS packed_load_raw;
7635 } else if (!strcmp(model,"PowerShot SX20 IS")) {
7642 load_raw = &CLASS packed_load_raw;
7645 } else if (!strcmp(model,"PowerShot SX220 HS")) {
7650 mask[0][0] = top_margin = 16;
7651 mask[0][2] = top_margin + height;
7652 mask[0][3] = left_margin = 92;
7653 load_raw = &CLASS packed_load_raw;
7656 } else if (!strcmp(model,"PowerShot SX30 IS")) {
7663 filters = 0x16161616;
7664 load_raw = &CLASS packed_load_raw;
7667 } else if (!strcmp(model,"PowerShot Pro90 IS")) {
7670 filters = 0xb4b4b4b4;
7671 } else if (is_canon && raw_width == 2144) {
7676 if (!strcmp(model,"PowerShot G1")) {
7678 filters = 0xb4b4b4b4;
7680 } else if (is_canon && raw_width == 2224) {
7685 } else if (is_canon && raw_width == 2376) {
7690 } else if (is_canon && raw_width == 2672) {
7695 } else if (is_canon && raw_width == 3152) {
7700 if (unique_id == 0x80000170)
7701 adobe_coeff ("Canon","EOS 300D");
7702 } else if (is_canon && raw_width == 3160) {
7707 } else if (is_canon && raw_width == 3344) {
7712 } else if (!strcmp(model,"EOS D2000C")) {
7713 filters = 0x61616161;
7715 } else if (is_canon && raw_width == 3516) {
7718 if (unique_id == 0x80000189)
7719 adobe_coeff ("Canon","EOS 350D");
7721 } else if (is_canon && raw_width == 3596) {
7725 } else if (is_canon && raw_width == 3744) {
7730 if (unique_id > 0x2720000) {
7734 } else if (is_canon && raw_width == 3944) {
7739 } else if (is_canon && raw_width == 3948) {
7743 if (unique_id == 0x80000236)
7744 adobe_coeff ("Canon","EOS 400D");
7745 if (unique_id == 0x80000254)
7746 adobe_coeff ("Canon","EOS 1000D");
7748 } else if (is_canon && raw_width == 3984) {
7753 } else if (is_canon && raw_width == 4104) {
7758 } else if (is_canon && raw_width == 4152) {
7762 } else if (is_canon && raw_width == 4160) {
7767 } else if (is_canon && raw_width == 4176) {
7771 mask[0][0] = top_margin = 17;
7772 mask[0][2] = raw_height;
7774 filters = 0x49494949;
7775 } else if (is_canon && raw_width == 4312) {
7779 if (unique_id == 0x80000176)
7780 adobe_coeff ("Canon","EOS 450D");
7782 } else if (is_canon && raw_width == 4352) {
7785 if (unique_id == 0x80000288)
7786 adobe_coeff ("Canon","EOS 1100D");
7788 } else if (is_canon && raw_width == 4476) {
7792 } else if (is_canon && raw_width == 4480) {
7797 filters = 0x49494949;
7798 } else if (is_canon && raw_width == 4496) {
7803 } else if (is_canon && raw_width == 4832) {
7804 top_margin = unique_id == 0x80000261 ? 51:26;
7806 if (unique_id == 0x80000252)
7807 adobe_coeff ("Canon","EOS 500D");
7809 } else if (is_canon && raw_width == 5108) {
7813 } else if (is_canon && raw_width == 5120) {
7814 height -= top_margin = 45;
7817 } else if (is_canon && raw_width == 5280) {
7820 if (unique_id == 0x80000301)
7821 adobe_coeff ("Canon","EOS 650D");
7823 } else if (is_canon && raw_width == 5344) {
7826 if (unique_id == 0x80000269) {
7830 adobe_coeff ("Canon","EOS-1D X");
7832 if (unique_id == 0x80000270)
7833 adobe_coeff ("Canon","EOS 550D");
7834 if (unique_id == 0x80000286)
7835 adobe_coeff ("Canon","EOS 600D");
7837 } else if (is_canon && raw_width == 5360) {
7841 } else if (is_canon && raw_width == 5568) {
7845 } else if (is_canon && raw_width == 5712) {
7850 } else if (is_canon && raw_width == 5792) {
7854 height -= top_margin;
7855 width -= left_margin;
7856 } else if (is_canon && raw_width == 5920) {
7861 } else if (!strcmp(model,"D1")) {
7862 cam_mul[0] *= 256/527.0;
7863 cam_mul[2] *= 256/317.0;
7864 } else if (!strcmp(model,"D1X")) {
7867 } else if (!strcmp(model,"D40X") ||
7868 !strcmp(model,"D60") ||
7869 !strcmp(model,"D80") ||
7870 !strcmp(model,"D3000")) {
7873 } else if (!strcmp(model,"D3") ||
7874 !strcmp(model,"D3S") ||
7875 !strcmp(model,"D700")) {
7878 } else if (!strcmp(model,"D3100")) {
7881 } else if (!strcmp(model,"D5000") ||
7882 !strcmp(model,"D90")) {
7884 } else if (!strcmp(model,"D5100") ||
7885 !strcmp(model,"D7000")) {
7887 } else if (!strcmp(model,"D3200") ||
7888 !strcmp(model,"D600") ||
7889 !strcmp(model,"D800")) {
7891 } else if (!strcmp(model,"D4")) {
7894 } else if (!strncmp(model,"D40",3) ||
7895 !strncmp(model,"D50",3) ||
7896 !strncmp(model,"D70",3)) {
7898 } else if (!strcmp(model,"D100")) {
7900 raw_width = (width += 3) + 3;
7901 } else if (!strcmp(model,"D200")) {
7904 filters = 0x94949494;
7905 } else if (!strncmp(model,"D2H",3)) {
7908 } else if (!strncmp(model,"D2X",3)) {
7909 if (width == 3264) width -= 32;
7911 } else if (!strncmp(model,"D300",4)) {
7913 } else if (!strcmp(make,"NIKON") && raw_width == 4032) {
7914 adobe_coeff ("NIKON","COOLPIX P7700");
7915 } else if (!strncmp(model,"COOLPIX P",9)) {
7917 filters = 0x94949494;
7918 if (model[9] == '7' && iso_speed >= 400)
7920 } else if (!strncmp(model,"1 ",2)) {
7922 } else if (fsize == 1581060) {
7928 filters = 0x1e1e1e1e;
7930 pre_mul[0] = 1.2085;
7931 pre_mul[1] = 1.0943;
7932 pre_mul[3] = 1.1103;
7934 } else if (fsize == 2465792) {
7939 filters = 0x4b4b4b4b;
7940 adobe_coeff ("NIKON","E950");
7943 load_raw = &CLASS packed_load_raw;
7945 } else if (fsize == 4771840) {
7949 filters = 0xe1e1e1e1;
7950 load_raw = &CLASS packed_load_raw;
7952 if (!timestamp && nikon_e995())
7953 strcpy (model, "E995");
7954 if (strcmp(model,"E995")) {
7955 filters = 0xb4b4b4b4;
7961 } else if (!strcmp(model,"E2100")) {
7962 if (!timestamp && !nikon_e2100()) goto cp_e2500;
7966 } else if (!strcmp(model,"E2500")) {
7968 strcpy (model, "E2500");
7972 filters = 0x4b4b4b4b;
7973 } else if (fsize == 4775936) {
7976 load_raw = &CLASS packed_load_raw;
7978 if (!timestamp) nikon_3700();
7979 if (model[0] == 'E' && atoi(model+1) < 3700)
7980 filters = 0x49494949;
7981 if (!strcmp(model,"Optio 33WR")) {
7983 filters = 0x16161616;
7985 if (make[0] == 'O') {
7986 i = find_green (12, 32, 1188864, 3576832);
7987 c = find_green (12, 32, 2383920, 2387016);
7988 if (abs(i) < abs(c)) {
7992 if (i < 0) filters = 0x61616161;
7994 } else if (fsize == 5869568) {
7997 filters = 0x16161616;
7998 if (!timestamp && minolta_z2()) {
7999 strcpy (make, "Minolta");
8000 strcpy (model,"DiMAGE Z2");
8002 load_raw = &CLASS packed_load_raw;
8003 load_flags = 6 + 24*(make[0] == 'M');
8004 } else if (!strcmp(model,"E4500")) {
8008 filters = 0xb4b4b4b4;
8009 } else if (fsize == 7438336) {
8013 filters = 0xb4b4b4b4;
8014 } else if (fsize == 8998912) {
8018 load_raw = &CLASS packed_load_raw;
8020 } else if (!strcmp(make,"FUJIFILM")) {
8021 if (!strcmp(model+7,"S2Pro")) {
8022 strcpy (model,"S2Pro");
8026 } else if (load_raw != &CLASS packed_load_raw)
8027 maximum = (is_raw == 2 && shot_select) ? 0x2f00 : 0x3e00;
8028 top_margin = (raw_height - height) >> 2 << 1;
8029 left_margin = (raw_width - width ) >> 2 << 1;
8030 if (width == 2848) filters = 0x16161616;
8031 if (width == 3328) {
8035 if (width == 4952) {
8039 if (fuji_layout) raw_width *= is_raw;
8040 } else if (!strcmp(model,"RD175")) {
8044 filters = 0x61616161;
8045 load_raw = &CLASS minolta_rd175_load_raw;
8046 } else if (!strcmp(model,"KD-400Z")) {
8051 } else if (!strcmp(model,"KD-510Z")) {
8053 } else if (!strcasecmp(make,"MINOLTA")) {
8054 load_raw = &CLASS unpacked_load_raw;
8056 if (!strncmp(model,"DiMAGE A",8)) {
8057 if (!strcmp(model,"DiMAGE A200"))
8058 filters = 0x49494949;
8060 load_raw = &CLASS packed_load_raw;
8061 } else if (!strncmp(model,"ALPHA",5) ||
8062 !strncmp(model,"DYNAX",5) ||
8063 !strncmp(model,"MAXXUM",6)) {
8064 sprintf (model+20, "DYNAX %-10s", model+6+(model[0]=='M'));
8065 adobe_coeff (make, model+20);
8066 load_raw = &CLASS packed_load_raw;
8067 } else if (!strncmp(model,"DiMAGE G",8)) {
8068 if (model[8] == '4') {
8071 } else if (model[8] == '5') {
8076 } else if (model[8] == '6') {
8081 filters = 0x61616161;
8083 load_raw = &CLASS unpacked_load_raw;
8087 } else if (!strcmp(model,"*ist D")) {
8088 load_raw = &CLASS unpacked_load_raw;
8090 } else if (!strcmp(model,"*ist DS")) {
8092 } else if (!strcmp(model,"Optio S")) {
8093 if (fsize == 3178560) {
8096 load_raw = &CLASS eight_bit_load_raw;
8103 load_raw = &CLASS packed_load_raw;
8106 } else if (fsize == 6114240) {
8110 load_raw = &CLASS packed_load_raw;
8112 } else if (!strcmp(model,"Optio 750Z")) {
8115 load_raw = &CLASS packed_load_raw;
8117 } else if (!strcmp(model,"DC-833m")) {
8121 filters = 0x61616161;
8122 load_raw = &CLASS unpacked_load_raw;
8124 } else if (!strncmp(model,"S85",3)) {
8127 raw_width = fsize/height/2;
8129 load_raw = &CLASS unpacked_load_raw;
8130 } else if (!strcmp(make,"SAMSUNG") && raw_width == 4704) {
8131 height -= top_margin = 8;
8132 width -= 2 * (left_margin = 8);
8134 } else if (!strcmp(make,"SAMSUNG") && raw_width == 5632) {
8138 width = 5574 - (left_margin = 32 + tiff_bps);
8139 if (tiff_bps == 12) load_flags = 80;
8140 } else if (!strcmp(model,"EX1")) {
8144 if ((width -= 6) > 3682) {
8149 } else if (!strcmp(model,"WB2000")) {
8153 if ((width -= 10) > 3718) {
8158 } else if (fsize == 20487168) {
8162 } else if (fsize == 24000000) {
8166 strcpy (model, "WB550");
8168 load_raw = &CLASS unpacked_load_raw;
8171 } else if (!strcmp(model,"EX2F")) {
8176 filters = 0x49494949;
8177 load_raw = &CLASS unpacked_load_raw;
8178 } else if (!strcmp(model,"STV680 VGA")) {
8181 load_raw = &CLASS eight_bit_load_raw;
8183 filters = 0x16161616;
8185 } else if (!strcmp(model,"N95")) {
8186 height = raw_height - (top_margin = 2);
8187 } else if (!strcmp(model,"531C")) {
8190 load_raw = &CLASS unpacked_load_raw;
8191 filters = 0x49494949;
8192 } else if (!strcmp(model,"640x480")) {
8195 load_raw = &CLASS eight_bit_load_raw;
8196 gamma_curve (0.45, 4.5, 1, 255);
8197 } else if (!strcmp(model,"F-080C")) {
8200 load_raw = &CLASS eight_bit_load_raw;
8201 } else if (!strcmp(model,"F-145C")) {
8204 load_raw = &CLASS eight_bit_load_raw;
8205 } else if (!strcmp(model,"F-201C")) {
8208 load_raw = &CLASS eight_bit_load_raw;
8209 } else if (!strcmp(model,"F-510C")) {
8212 load_raw = fsize < 7500000 ?
8213 &CLASS eight_bit_load_raw : &CLASS unpacked_load_raw;
8214 data_offset = fsize - width*height*(fsize >> 22);
8216 } else if (!strcmp(model,"F-810C")) {
8219 load_raw = &CLASS unpacked_load_raw;
8221 } else if (!strcmp(model,"XCD-SX910CR")) {
8225 filters = 0x49494949;
8227 load_raw = fsize < 2000000 ?
8228 &CLASS eight_bit_load_raw : &CLASS unpacked_load_raw;
8229 } else if (!strcmp(model,"2010")) {
8233 filters = 0x16161616;
8236 load_raw = &CLASS unpacked_load_raw;
8237 } else if (!strcmp(model,"A782")) {
8240 filters = 0x61616161;
8241 load_raw = fsize < 10000000 ?
8242 &CLASS eight_bit_load_raw : &CLASS unpacked_load_raw;
8244 } else if (!strcmp(model,"3320AF")) {
8246 raw_width = width = 2048;
8247 filters = 0x61616161;
8248 load_raw = &CLASS unpacked_load_raw;
8250 fseek (ifp, 0x300000, SEEK_SET);
8251 if ((order = guess_byte_order(0x10000)) == 0x4d4d) {
8252 height -= (top_margin = 16);
8253 width -= (left_margin = 28);
8255 strcpy (make, "ISG");
8258 } else if (!strcmp(make,"Hasselblad")) {
8259 if (load_raw == &CLASS lossless_jpeg_load_raw)
8260 load_raw = &CLASS hasselblad_load_raw;
8261 if (raw_width == 7262) {
8266 filters = 0x61616161;
8267 } else if (raw_width == 7410) {
8272 filters = 0x61616161;
8273 } else if (raw_width == 9044) {
8278 black += load_flags = 256;
8280 } else if (raw_width == 4090) {
8281 strcpy (model, "V96C");
8282 height -= (top_margin = 6);
8283 width -= (left_margin = 3) + 7;
8284 filters = 0x61616161;
8286 } else if (!strcmp(make,"Sinar")) {
8287 if (!memcmp(head,"8BPS",4)) {
8288 fseek (ifp, 14, SEEK_SET);
8291 filters = 0x61616161;
8294 if (!load_raw) load_raw = &CLASS unpacked_load_raw;
8296 } else if (!strcmp(make,"Leaf")) {
8298 fseek (ifp, data_offset, SEEK_SET);
8299 if (ljpeg_start (&jh, 1) && jh.bits == 15)
8301 if (tiff_samples > 1) filters = 0;
8302 if (tiff_samples > 1 || tile_length < raw_height) {
8303 load_raw = &CLASS leaf_hdr_load_raw;
8304 raw_width = tile_width;
8306 if ((width | height) == 2048) {
8307 if (tiff_samples == 1) {
8309 strcpy (cdesc, "RBTG");
8310 strcpy (model, "CatchLight");
8311 top_margin = 8; left_margin = 18; height = 2032; width = 2016;
8313 strcpy (model, "DCB2");
8314 top_margin = 10; left_margin = 16; height = 2028; width = 2022;
8316 } else if (width+height == 3144+2060) {
8317 if (!model[0]) strcpy (model, "Cantare");
8318 if (width > height) {
8319 top_margin = 6; left_margin = 32; height = 2048; width = 3072;
8320 filters = 0x61616161;
8322 left_margin = 6; top_margin = 32; width = 2048; height = 3072;
8323 filters = 0x16161616;
8325 if (!cam_mul[0] || model[0] == 'V') filters = 0;
8326 else is_raw = tiff_samples;
8327 } else if (width == 2116) {
8328 strcpy (model, "Valeo 6");
8329 height -= 2 * (top_margin = 30);
8330 width -= 2 * (left_margin = 55);
8331 filters = 0x49494949;
8332 } else if (width == 3171) {
8333 strcpy (model, "Valeo 6");
8334 height -= 2 * (top_margin = 24);
8335 width -= 2 * (left_margin = 24);
8336 filters = 0x16161616;
8338 } else if (!strcmp(make,"LEICA") || !strcmp(make,"Panasonic")) {
8339 if ((flen - data_offset) / (raw_width*8/7) == raw_height)
8340 load_raw = &CLASS panasonic_load_raw;
8342 load_raw = &CLASS unpacked_load_raw;
8346 if ((height += 12) > raw_height) height = raw_height;
8347 for (i=0; i < sizeof pana / sizeof *pana; i++)
8348 if (raw_width == pana[i][0] && raw_height == pana[i][1]) {
8349 left_margin = pana[i][2];
8350 top_margin = pana[i][3];
8351 width += pana[i][4];
8352 height += pana[i][5];
8354 filters = 0x01010101 * (uchar) "\x94\x61\x49\x16"
8355 [((filters-1) ^ (left_margin & 1) ^ (top_margin << 1)) & 3];
8356 } else if (!strcmp(model,"C770UZ")) {
8359 filters = 0x16161616;
8360 load_raw = &CLASS packed_load_raw;
8362 } else if (!strcmp(make,"OLYMPUS")) {
8363 height += height & 1;
8365 if (width == 4100) width -= 4;
8366 if (width == 4080) width -= 24;
8367 if (load_raw == &CLASS unpacked_load_raw)
8370 if (!strcmp(model,"E-300") ||
8371 !strcmp(model,"E-500")) {
8373 if (load_raw == &CLASS unpacked_load_raw) {
8375 memset (cblack, 0, sizeof cblack);
8377 } else if (!strcmp(model,"E-330")) {
8379 if (load_raw == &CLASS unpacked_load_raw)
8381 } else if (!strcmp(model,"SP550UZ")) {
8382 thumb_length = flen - (thumb_offset = 0xa39800);
8385 } else if (!strcmp(model,"XZ-2")) {
8386 load_raw = &CLASS packed_load_raw;
8389 } else if (!strcmp(model,"N Digital")) {
8392 filters = 0x61616161;
8393 data_offset = 0x1a00;
8394 load_raw = &CLASS packed_load_raw;
8395 } else if (!strcmp(model,"DSC-F828")) {
8399 data_offset = 862144;
8400 load_raw = &CLASS sony_load_raw;
8401 filters = 0x9c9c9c9c;
8403 strcpy (cdesc, "RGBE");
8404 } else if (!strcmp(model,"DSC-V3")) {
8408 data_offset = 787392;
8409 load_raw = &CLASS sony_load_raw;
8410 } else if (!strcmp(make,"SONY") && raw_width == 3984) {
8411 adobe_coeff ("SONY","DSC-R1");
8414 } else if (!strcmp(make,"SONY") && raw_width == 5504) {
8416 } else if (!strcmp(make,"SONY") && raw_width == 6048) {
8418 } else if (!strcmp(model,"DSLR-A100")) {
8419 if (width == 3880) {
8421 width = ++raw_width;
8426 filters = 0x61616161;
8427 } else if (!strcmp(model,"DSLR-A350")) {
8429 } else if (!strcmp(model,"PIXL")) {
8430 height -= top_margin = 4;
8431 width -= left_margin = 32;
8432 gamma_curve (0, 7, 1, 255);
8433 } else if (!strcmp(model,"C603v")) {
8436 if (fsize < 614400 || find_green (16, 16, 3840, 5120) < 25) goto c603v;
8437 strcpy (model,"KAI-0340");
8441 load_raw = &CLASS unpacked_load_raw;
8442 } else if (!strcmp(model,"C603y")) {
8447 load_raw = &CLASS kodak_yrgb_load_raw;
8448 gamma_curve (0, 3.875, 1, 255);
8449 } else if (!strcmp(model,"C603")) {
8450 raw_height = height = 2152;
8451 raw_width = width = 2864;
8453 } else if (!strcmp(model,"C330")) {
8462 if ((data_offset = fsize - raw_height*raw_width)) {
8463 fseek (ifp, 168, SEEK_SET);
8464 read_shorts (curve, 256);
8465 } else gamma_curve (0, 3.875, 1, 255);
8466 load_raw = &CLASS eight_bit_load_raw;
8467 } else if (!strncasecmp(model,"EasyShare",9)) {
8468 data_offset = data_offset < 0x15000 ? 0x15000 : 0x17000;
8469 load_raw = &CLASS packed_load_raw;
8470 } else if (!strcasecmp(make,"KODAK")) {
8471 if (filters == UINT_MAX) filters = 0x61616161;
8472 if (!strncmp(model,"NC2000",6)) {
8475 } else if (!strcmp(model,"EOSDCS3B")) {
8478 } else if (!strcmp(model,"EOSDCS1")) {
8481 } else if (!strcmp(model,"DCS420")) {
8484 } else if (!strncmp(model,"DCS460 ",7)) {
8488 } else if (!strcmp(model,"DCS460A")) {
8493 } else if (!strcmp(model,"DCS660M")) {
8497 } else if (!strcmp(model,"DCS760M")) {
8501 if (!strcmp(model+4,"20X"))
8502 strcpy (cdesc, "MYCY");
8503 if (strstr(model,"DC25")) {
8504 strcpy (model, "DC25");
8505 data_offset = 15424;
8507 if (!strncmp(model,"DC2",3)) {
8508 raw_height = height = 242;
8509 if (flen < 100000) {
8510 raw_width = 256; width = 249;
8511 pixel_aspect = (4.0*height) / (3.0*width);
8513 raw_width = 512; width = 501;
8514 pixel_aspect = (493.0*height) / (373.0*width);
8516 data_offset += raw_width + 1;
8518 filters = 0x8d8d8d8d;
8523 load_raw = &CLASS eight_bit_load_raw;
8524 } else if (!strcmp(model,"40")) {
8525 strcpy (model, "DC40");
8529 load_raw = &CLASS kodak_radc_load_raw;
8530 } else if (strstr(model,"DC50")) {
8531 strcpy (model, "DC50");
8534 data_offset = 19712;
8535 load_raw = &CLASS kodak_radc_load_raw;
8536 } else if (strstr(model,"DC120")) {
8537 strcpy (model, "DC120");
8540 pixel_aspect = height/0.75/width;
8541 load_raw = tiff_compress == 7 ?
8542 &CLASS kodak_jpeg_load_raw : &CLASS kodak_dc120_load_raw;
8543 } else if (!strcmp(model,"DCS200")) {
8546 thumb_offset = 6144;
8548 write_thumb = &CLASS layer_thumb;
8551 data_offset = 79872;
8552 load_raw = &CLASS eight_bit_load_raw;
8555 } else if (!strcmp(model,"Fotoman Pixtura")) {
8559 load_raw = &CLASS kodak_radc_load_raw;
8560 filters = 0x61616161;
8562 } else if (!strncmp(model,"QuickTake",9)) {
8563 if (head[5]) strcpy (model+10, "200");
8564 fseek (ifp, 544, SEEK_SET);
8567 data_offset = (get4(),get2()) == 30 ? 738:736;
8568 if (height > width) {
8570 fseek (ifp, data_offset-6, SEEK_SET);
8571 flip = ~get2() & 3 ? 5:6;
8573 filters = 0x61616161;
8574 } else if (!strcmp(make,"Rollei") && !load_raw) {
8575 switch (raw_width) {
8588 filters = 0x16161616;
8589 load_raw = &CLASS rollei_load_raw;
8590 } else if (!strcmp(model,"PC-CAM 600")) {
8592 data_offset = width = 1024;
8593 filters = 0x49494949;
8594 load_raw = &CLASS eight_bit_load_raw;
8595 } else if (!strcmp(model,"QV-2000UX")) {
8598 data_offset = width * 2;
8599 load_raw = &CLASS eight_bit_load_raw;
8600 } else if (fsize == 3217760) {
8604 load_raw = &CLASS eight_bit_load_raw;
8605 } else if (!strcmp(model,"QV-4000")) {
8608 load_raw = &CLASS unpacked_load_raw;
8610 } else if (!strcmp(model,"QV-5700")) {
8615 } else if (!strcmp(model,"QV-R41")) {
8620 } else if (!strcmp(model,"QV-R51")) {
8624 } else if (!strcmp(model,"EX-S20")) {
8629 } else if (!strcmp(model,"EX-S100")) {
8633 } else if (!strcmp(model,"EX-Z50")) {
8637 } else if (!strcmp(model,"EX-Z500")) {
8641 filters = 0x16161616;
8642 } else if (!strcmp(model,"EX-Z55")) {
8646 } else if (!strcmp(model,"EX-Z60")) {
8650 filters = 0x16161616;
8652 } else if (!strcmp(model,"EX-Z75")) {
8657 } else if (!strcmp(model,"EX-Z750")) {
8662 } else if (!strcmp(model,"EX-Z850")) {
8667 } else if (!strcmp(model,"EX-Z8")) {
8673 } else if (fsize == 15499264) { /* EX-Z1050 or EX-Z1080 */
8677 } else if (!strcmp(model,"EX-ZR100")) {
8682 } else if (!strcmp(model,"EX-P505")) {
8687 } else if (fsize == 9313536) { /* EX-P600 or QV-R61 */
8691 } else if (!strcmp(model,"EX-P700")) {
8697 sprintf (model, "%dx%d", width, height);
8698 if (filters == UINT_MAX) filters = 0x94949494;
8699 if (raw_color) adobe_coeff (make, model);
8700 if (load_raw == &CLASS kodak_radc_load_raw)
8701 if (raw_color) adobe_coeff ("Apple","Quicktake");
8702 if (thumb_offset && !thumb_height) {
8703 fseek (ifp, thumb_offset, SEEK_SET);
8704 if (ljpeg_start (&jh, 1)) {
8705 thumb_width = jh.wide;
8706 thumb_height = jh.high;
8711 fuji_width = width >> !fuji_layout;
8712 if (~fuji_width & 1) filters = 0x49494949;
8713 width = (height >> fuji_layout) + fuji_width;
8717 if (raw_height < height) raw_height = height;
8718 if (raw_width < width ) raw_width = width;
8720 if (!tiff_bps) tiff_bps = 12;
8721 if (!maximum) maximum = (1 << tiff_bps) - 1;
8722 if (!load_raw || height < 22) is_raw = 0;
8724 if (load_raw == &CLASS redcine_load_raw) {
8725 fprintf (stderr,_("%s: You must link dcraw with %s!!\n"),
8726 ifname, "libjasper");
8731 if (load_raw == &CLASS kodak_jpeg_load_raw ||
8732 load_raw == &CLASS lossy_dng_load_raw) {
8733 fprintf (stderr,_("%s: You must link dcraw with %s!!\n"),
8739 strcpy (cdesc, colors == 3 ? "RGBG":"GMCY");
8740 if (!raw_height) raw_height = height;
8741 if (!raw_width ) raw_width = width;
8742 if (filters && colors == 3)
8743 filters |= ((filters >> 2 & 0x22222222) |
8744 (filters << 2 & 0x88888888)) & filters << 1;
8746 if (flip == -1) flip = tiff_flip;
8747 if (flip == -1) flip = 0;
8754 sprintf(dcraw_info, "%d %d", height, width);
8756 sprintf(dcraw_info, "%d %d", width, height);
8760 void CLASS apply_profile (const char *input, const char *output)
8763 cmsHPROFILE hInProfile=0, hOutProfile=0;
8764 cmsHTRANSFORM hTransform;
8768 cmsErrorAction (LCMS_ERROR_SHOW);
8769 if (strcmp (input, "embed"))
8770 hInProfile = cmsOpenProfileFromFile (input, "r");
8771 else if (profile_length) {
8772 prof = (char *) malloc (profile_length);
8773 merror (prof, "apply_profile()");
8774 fseek (ifp, profile_offset, SEEK_SET);
8775 fread (prof, 1, profile_length, ifp);
8776 hInProfile = cmsOpenProfileFromMem (prof, profile_length);
8779 fprintf (stderr,_("%s has no embedded profile.\n"), ifname);
8780 if (!hInProfile) return;
8782 hOutProfile = cmsCreate_sRGBProfile();
8783 else if ((fp = fopen (output, "rb"))) {
8784 fread (&size, 4, 1, fp);
8785 fseek (fp, 0, SEEK_SET);
8786 oprof = (unsigned *) malloc (size = ntohl(size));
8787 merror (oprof, "apply_profile()");
8788 fread (oprof, 1, size, fp);
8790 if (!(hOutProfile = cmsOpenProfileFromMem (oprof, size))) {
8795 fprintf (stderr,_("Cannot open file %s!\n"), output);
8796 if (!hOutProfile) goto quit;
8798 fprintf (stderr,_("Applying color profile...\n"));
8799 hTransform = cmsCreateTransform (hInProfile, TYPE_RGBA_16,
8800 hOutProfile, TYPE_RGBA_16, INTENT_PERCEPTUAL, 0);
8801 cmsDoTransform (hTransform, image, image, width*height);
8802 raw_color = 1; /* Don't use rgb_cam with a profile */
8803 cmsDeleteTransform (hTransform);
8804 cmsCloseProfile (hOutProfile);
8806 cmsCloseProfile (hInProfile);
8810 void CLASS convert_to_rgb()
8812 int row, col, c, i, j, k;
8814 float out[3], out_cam[3][4];
8815 double num, inverse[3][3];
8816 static const double xyzd50_srgb[3][3] =
8817 { { 0.436083, 0.385083, 0.143055 },
8818 { 0.222507, 0.716888, 0.060608 },
8819 { 0.013930, 0.097097, 0.714022 } };
8820 static const double rgb_rgb[3][3] =
8821 { { 1,0,0 }, { 0,1,0 }, { 0,0,1 } };
8822 static const double adobe_rgb[3][3] =
8823 { { 0.715146, 0.284856, 0.000000 },
8824 { 0.000000, 1.000000, 0.000000 },
8825 { 0.000000, 0.041166, 0.958839 } };
8826 static const double wide_rgb[3][3] =
8827 { { 0.593087, 0.404710, 0.002206 },
8828 { 0.095413, 0.843149, 0.061439 },
8829 { 0.011621, 0.069091, 0.919288 } };
8830 static const double prophoto_rgb[3][3] =
8831 { { 0.529317, 0.330092, 0.140588 },
8832 { 0.098368, 0.873465, 0.028169 },
8833 { 0.016879, 0.117663, 0.865457 } };
8834 static const double (*out_rgb[])[3] =
8835 { rgb_rgb, adobe_rgb, wide_rgb, prophoto_rgb, xyz_rgb };
8836 static const char *name[] =
8837 { "sRGB", "Adobe RGB (1998)", "WideGamut D65", "ProPhoto D65", "XYZ" };
8838 static const unsigned phead[] =
8839 { 1024, 0, 0x2100000, 0x6d6e7472, 0x52474220, 0x58595a20, 0, 0, 0,
8840 0x61637370, 0, 0, 0x6e6f6e65, 0, 0, 0, 0, 0xf6d6, 0x10000, 0xd32d };
8842 { 10, 0x63707274, 0, 36, /* cprt */
8843 0x64657363, 0, 40, /* desc */
8844 0x77747074, 0, 20, /* wtpt */
8845 0x626b7074, 0, 20, /* bkpt */
8846 0x72545243, 0, 14, /* rTRC */
8847 0x67545243, 0, 14, /* gTRC */
8848 0x62545243, 0, 14, /* bTRC */
8849 0x7258595a, 0, 20, /* rXYZ */
8850 0x6758595a, 0, 20, /* gXYZ */
8851 0x6258595a, 0, 20 }; /* bXYZ */
8852 static const unsigned pwhite[] = { 0xf351, 0x10000, 0x116cc };
8853 unsigned pcurve[] = { 0x63757276, 0, 1, 0x1000000 };
8855 gamma_curve (gamm[0], gamm[1], 0, 0);
8856 memcpy (out_cam, rgb_cam, sizeof out_cam);
8857 raw_color |= colors == 1 || document_mode ||
8858 output_color < 1 || output_color > 5;
8860 oprof = (unsigned *) calloc (phead[0], 1);
8861 merror (oprof, "convert_to_rgb()");
8862 memcpy (oprof, phead, sizeof phead);
8863 if (output_color == 5) oprof[4] = oprof[5];
8864 oprof[0] = 132 + 12*pbody[0];
8865 for (i=0; i < pbody[0]; i++) {
8866 oprof[oprof[0]/4] = i ? (i > 1 ? 0x58595a20 : 0x64657363) : 0x74657874;
8867 pbody[i*3+2] = oprof[0];
8868 oprof[0] += (pbody[i*3+3] + 3) & -4;
8870 memcpy (oprof+32, pbody, sizeof pbody);
8871 oprof[pbody[5]/4+2] = strlen(name[output_color-1]) + 1;
8872 memcpy ((char *)oprof+pbody[8]+8, pwhite, sizeof pwhite);
8873 pcurve[3] = (short)(256/gamm[5]+0.5) << 16;
8874 for (i=4; i < 7; i++)
8875 memcpy ((char *)oprof+pbody[i*3+2], pcurve, sizeof pcurve);
8876 pseudoinverse ((double (*)[3]) out_rgb[output_color-1], inverse, 3);
8877 for (i=0; i < 3; i++)
8878 for (j=0; j < 3; j++) {
8879 for (num = k=0; k < 3; k++)
8880 num += xyzd50_srgb[i][k] * inverse[j][k];
8881 oprof[pbody[j*3+23]/4+i+2] = num * 0x10000 + 0.5;
8883 for (i=0; i < phead[0]/4; i++)
8884 oprof[i] = htonl(oprof[i]);
8885 strcpy ((char *)oprof+pbody[2]+8, "auto-generated by dcraw");
8886 strcpy ((char *)oprof+pbody[5]+12, name[output_color-1]);
8887 for (i=0; i < 3; i++)
8888 for (j=0; j < colors; j++)
8889 for (out_cam[i][j] = k=0; k < 3; k++)
8890 out_cam[i][j] += out_rgb[output_color-1][i][k] * rgb_cam[k][j];
8893 fprintf (stderr, raw_color ? _("Building histograms...\n") :
8894 _("Converting to %s colorspace...\n"), name[output_color-1]);
8896 memset (histogram, 0, sizeof histogram);
8897 for (img=image[0], row=0; row < height; row++)
8898 for (col=0; col < width; col++, img+=4) {
8900 out[0] = out[1] = out[2] = 0;
8902 out[0] += out_cam[0][c] * img[c];
8903 out[1] += out_cam[1][c] * img[c];
8904 out[2] += out_cam[2][c] * img[c];
8906 FORC3 img[c] = CLIP((int) out[c]);
8908 else if (document_mode)
8909 img[0] = img[fcol(row,col)];
8910 FORCC histogram[c][img[c] >> 3]++;
8912 if (colors == 4 && output_color) colors = 3;
8913 if (document_mode && filters) colors = 1;
8919 // Export color matrix to Cinelerra.
8920 // It can't be applied before interpolation.
8922 for(i = 0; i < 3; i++)
8924 for(j = 0; j < 3; j++)
8925 dcraw_matrix[k++] = rgb_cam[i][j];
8929 void CLASS fuji_rotate()
8935 ushort wide, high, (*img)[4], (*pix)[4];
8937 if (!fuji_width) return;
8939 fprintf (stderr,_("Rotating image 45 degrees...\n"));
8940 fuji_width = (fuji_width - 1 + shrink) >> shrink;
8942 wide = fuji_width / step;
8943 high = (height - fuji_width) / step;
8944 img = (ushort (*)[4]) calloc (wide*high, sizeof *img);
8945 merror (img, "fuji_rotate()");
8947 for (row=0; row < high; row++)
8948 for (col=0; col < wide; col++) {
8949 ur = r = fuji_width + (row-col)*step;
8950 uc = c = (row+col)*step;
8951 if (ur > height-2 || uc > width-2) continue;
8954 pix = image + ur*width + uc;
8955 for (i=0; i < colors; i++)
8956 img[row*wide+col][i] =
8957 (pix[ 0][i]*(1-fc) + pix[ 1][i]*fc) * (1-fr) +
8958 (pix[width][i]*(1-fc) + pix[width+1][i]*fc) * fr;
8967 void CLASS stretch()
8969 ushort newdim, (*img)[4], *pix0, *pix1;
8973 if (pixel_aspect == 1) return;
8974 if (verbose) fprintf (stderr,_("Stretching the image...\n"));
8975 if (pixel_aspect < 1) {
8976 newdim = height / pixel_aspect + 0.5;
8977 img = (ushort (*)[4]) calloc (width*newdim, sizeof *img);
8978 merror (img, "stretch()");
8979 for (rc=row=0; row < newdim; row++, rc+=pixel_aspect) {
8980 frac = rc - (c = rc);
8981 pix0 = pix1 = image[c*width];
8982 if (c+1 < height) pix1 += width*4;
8983 for (col=0; col < width; col++, pix0+=4, pix1+=4)
8984 FORCC img[row*width+col][c] = pix0[c]*(1-frac) + pix1[c]*frac + 0.5;
8988 newdim = width * pixel_aspect + 0.5;
8989 img = (ushort (*)[4]) calloc (height*newdim, sizeof *img);
8990 merror (img, "stretch()");
8991 for (rc=col=0; col < newdim; col++, rc+=1/pixel_aspect) {
8992 frac = rc - (c = rc);
8993 pix0 = pix1 = image[c];
8994 if (c+1 < width) pix1 += 4;
8995 for (row=0; row < height; row++, pix0+=width*4, pix1+=width*4)
8996 FORCC img[row*newdim+col][c] = pix0[c]*(1-frac) + pix1[c]*frac + 0.5;
9004 int CLASS flip_index (int row, int col)
9006 if (flip & 4) SWAP(row,col);
9007 if (flip & 2) row = iheight - 1 - row;
9008 if (flip & 1) col = iwidth - 1 - col;
9009 return row * iwidth + col;
9015 union { char c[4]; short s[2]; int i; } val;
9019 ushort order, magic;
9022 struct tiff_tag tag[23];
9025 struct tiff_tag exif[4];
9027 struct tiff_tag gpst[10];
9031 char desc[512], make[64], model[64], soft[32], date[20], artist[64];
9034 void CLASS tiff_set (ushort *ntag,
9035 ushort tag, ushort type, int count, int val)
9037 struct tiff_tag *tt;
9040 tt = (struct tiff_tag *)(ntag+1) + (*ntag)++;
9044 if (type < 3 && count <= 4)
9045 FORC(4) tt->val.c[c] = val >> (c << 3);
9046 else if (type == 3 && count <= 2)
9047 FORC(2) tt->val.s[c] = val >> (c << 4);
9048 else tt->val.i = val;
9051 #define TOFF(ptr) ((char *)(&(ptr)) - (char *)th)
9053 void CLASS tiff_head (struct tiff_hdr *th, int full)
9058 memset (th, 0, sizeof *th);
9059 th->order = htonl(0x4d4d4949) >> 16;
9063 tiff_set (&th->ntag, 254, 4, 1, 0);
9064 tiff_set (&th->ntag, 256, 4, 1, width);
9065 tiff_set (&th->ntag, 257, 4, 1, height);
9066 tiff_set (&th->ntag, 258, 3, colors, output_bps);
9068 th->tag[th->ntag-1].val.i = TOFF(th->bps);
9069 FORC4 th->bps[c] = output_bps;
9070 tiff_set (&th->ntag, 259, 3, 1, 1);
9071 tiff_set (&th->ntag, 262, 3, 1, 1 + (colors > 1));
9073 tiff_set (&th->ntag, 270, 2, 512, TOFF(th->desc));
9074 tiff_set (&th->ntag, 271, 2, 64, TOFF(th->make));
9075 tiff_set (&th->ntag, 272, 2, 64, TOFF(th->model));
9077 if (oprof) psize = ntohl(oprof[0]);
9078 tiff_set (&th->ntag, 273, 4, 1, sizeof *th + psize);
9079 tiff_set (&th->ntag, 277, 3, 1, colors);
9080 tiff_set (&th->ntag, 278, 4, 1, height);
9081 tiff_set (&th->ntag, 279, 4, 1, height*width*colors*output_bps/8);
9083 tiff_set (&th->ntag, 274, 3, 1, "12435867"[flip]-'0');
9084 tiff_set (&th->ntag, 282, 5, 1, TOFF(th->rat[0]));
9085 tiff_set (&th->ntag, 283, 5, 1, TOFF(th->rat[2]));
9086 tiff_set (&th->ntag, 284, 3, 1, 1);
9087 tiff_set (&th->ntag, 296, 3, 1, 2);
9088 tiff_set (&th->ntag, 305, 2, 32, TOFF(th->soft));
9089 tiff_set (&th->ntag, 306, 2, 20, TOFF(th->date));
9090 tiff_set (&th->ntag, 315, 2, 64, TOFF(th->artist));
9091 tiff_set (&th->ntag, 34665, 4, 1, TOFF(th->nexif));
9092 if (psize) tiff_set (&th->ntag, 34675, 7, psize, sizeof *th);
9093 tiff_set (&th->nexif, 33434, 5, 1, TOFF(th->rat[4]));
9094 tiff_set (&th->nexif, 33437, 5, 1, TOFF(th->rat[6]));
9095 tiff_set (&th->nexif, 34855, 3, 1, iso_speed);
9096 tiff_set (&th->nexif, 37386, 5, 1, TOFF(th->rat[8]));
9098 tiff_set (&th->ntag, 34853, 4, 1, TOFF(th->ngps));
9099 tiff_set (&th->ngps, 0, 1, 4, 0x202);
9100 tiff_set (&th->ngps, 1, 2, 2, gpsdata[29]);
9101 tiff_set (&th->ngps, 2, 5, 3, TOFF(th->gps[0]));
9102 tiff_set (&th->ngps, 3, 2, 2, gpsdata[30]);
9103 tiff_set (&th->ngps, 4, 5, 3, TOFF(th->gps[6]));
9104 tiff_set (&th->ngps, 5, 1, 1, gpsdata[31]);
9105 tiff_set (&th->ngps, 6, 5, 1, TOFF(th->gps[18]));
9106 tiff_set (&th->ngps, 7, 5, 3, TOFF(th->gps[12]));
9107 tiff_set (&th->ngps, 18, 2, 12, TOFF(th->gps[20]));
9108 tiff_set (&th->ngps, 29, 2, 12, TOFF(th->gps[23]));
9109 memcpy (th->gps, gpsdata, sizeof th->gps);
9111 th->rat[0] = th->rat[2] = 300;
9112 th->rat[1] = th->rat[3] = 1;
9113 FORC(6) th->rat[4+c] = 1000000;
9114 th->rat[4] *= shutter;
9115 th->rat[6] *= aperture;
9116 th->rat[8] *= focal_len;
9117 strncpy (th->desc, desc, 512);
9118 strncpy (th->make, make, 64);
9119 strncpy (th->model, model, 64);
9120 strcpy (th->soft, "dcraw v"DCRAW_VERSION);
9121 t = localtime (×tamp);
9122 sprintf (th->date, "%04d:%02d:%02d %02d:%02d:%02d",
9123 t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);
9124 strncpy (th->artist, artist, 64);
9127 void CLASS jpeg_thumb()
9133 thumb = (char *) malloc (thumb_length);
9134 merror (thumb, "jpeg_thumb()");
9135 fread (thumb, 1, thumb_length, ifp);
9138 if (strcmp (thumb+6, "Exif")) {
9139 memcpy (exif, "\xff\xe1 Exif\0\0", 10);
9140 exif[1] = htons (8 + sizeof th);
9141 fwrite (exif, 1, sizeof exif, ofp);
9143 fwrite (&th, 1, sizeof th, ofp);
9145 fwrite (thumb+2, 1, thumb_length-2, ofp);
9149 void CLASS write_ppm_tiff()
9154 int c, row, col, soff, rstep, cstep;
9155 int perc, val, total, white=0x2000;
9157 perc = width * height * 0.01; /* 99th percentile white level */
9158 if (fuji_width) perc /= 2;
9159 if (!((highlight & ~2) || no_auto_bright))
9160 for (white=c=0; c < colors; c++) {
9161 for (val=0x2000, total=0; --val > 32; )
9162 if ((total += histogram[c][val]) > perc) break;
9163 if (white < val) white = val;
9165 gamma_curve (gamm[0], gamm[1], 2, (white << 3)/bright);
9168 if (flip & 4) SWAP(height,width);
9169 ppm = (uchar *) calloc (width, colors*output_bps/8);
9170 ppm2 = (ushort *) ppm;
9171 merror (ppm, "write_ppm_tiff()");
9174 fwrite (&th, sizeof th, 1, ofp);
9176 fwrite (oprof, ntohl(oprof[0]), 1, ofp);
9177 } else if (colors > 3)
9179 "P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLTYPE %s\nENDHDR\n",
9180 width, height, colors, (1 << output_bps)-1, cdesc);
9182 fprintf (ofp, "P%d\n%d %d\n%d\n",
9183 colors/2+5, width, height, (1 << output_bps)-1);
9184 soff = flip_index (0, 0);
9185 cstep = flip_index (0, 1) - soff;
9186 rstep = flip_index (1, 0) - flip_index (0, width);
9187 for (row=0; row < height; row++, soff += rstep) {
9188 for (col=0; col < width; col++, soff += cstep)
9189 if (output_bps == 8)
9190 FORCC ppm [col*colors+c] = curve[image[soff][c]] >> 8;
9191 else FORCC ppm2[col*colors+c] = curve[image[soff][c]];
9192 if (output_bps == 16 && !output_tiff && htons(0x55aa) != 0x55aa)
9193 swab (ppm2, ppm2, width*colors*2);
9194 fwrite (ppm, colors*output_bps/8, width, ofp);
9205 void CLASS write_cinelerra (FILE *ofp)
9210 for (row = 0; row < height; row++)
9212 output = dcraw_data[row];
9216 for (col = 0; col < width; col++)
9218 ushort *pixel = image[row * width + col];
9220 *output++ = (float)pixel[0] / 0xffff;
9221 *output++ = (float)pixel[1] / 0xffff;
9222 *output++ = (float)pixel[2] / 0xffff;
9224 if(dcraw_alpha) *output++ = 1.0;
9229 for (col = 0; col < width; col++)
9231 ushort *pixel = image[row * width + col];
9233 *output++ = (float)pixel[0] / 0xffff;
9234 *output++ = (float)pixel[1] / 0xffff;
9235 *output++ = (float)pixel[2] / 0xffff;
9237 if(dcraw_alpha) *output++ = 1.0;
9256 int CLASS dcraw_main (int argc, const char **argv)
9257 //int CLASS main (int argc, const char **argv)
9260 // Globals must be reset
9266 int arg, status=0, quality, i, c;
9267 int timestamp_only=0, thumbnail_only=0, identify_only=0;
9268 int user_qual=-1, user_black=-1, user_sat=-1, user_flip=-1;
9269 int use_fuji_rotate=1, write_to_stdout=0, read_from_stdin=0;
9270 const char *sp, *bpfile=0, *dark_frame=0, *write_ext;
9271 char opm, opt, *ofname, *cp;
9274 const char *cam_profile=0, *out_profile=0;
9278 putenv ((char *) "TZ=UTC");
9281 setlocale (LC_CTYPE, "");
9282 setlocale (LC_MESSAGES, "");
9283 bindtextdomain ("dcraw", LOCALEDIR);
9284 textdomain ("dcraw");
9288 printf(_("\nRaw photo decoder \"dcraw\" v%s"), DCRAW_VERSION);
9289 printf(_("\nby Dave Coffin, dcoffin a cybercom o net\n"));
9290 printf(_("\nUsage: %s [OPTION]... [FILE]...\n\n"), argv[0]);
9291 puts(_("-v Print verbose messages"));
9292 puts(_("-c Write image data to standard output"));
9293 puts(_("-e Extract embedded thumbnail image"));
9294 puts(_("-i Identify files without decoding them"));
9295 puts(_("-i -v Identify files and show metadata"));
9296 puts(_("-z Change file dates to camera timestamp"));
9297 puts(_("-w Use camera white balance, if possible"));
9298 puts(_("-a Average the whole image for white balance"));
9299 puts(_("-A <x y w h> Average a grey box for white balance"));
9300 puts(_("-r <r g b g> Set custom white balance"));
9301 puts(_("+M/-M Use/don't use an embedded color matrix"));
9302 puts(_("-C <r b> Correct chromatic aberration"));
9303 puts(_("-P <file> Fix the dead pixels listed in this file"));
9304 puts(_("-K <file> Subtract dark frame (16-bit raw PGM)"));
9305 puts(_("-k <num> Set the darkness level"));
9306 puts(_("-S <num> Set the saturation level"));
9307 puts(_("-n <num> Set threshold for wavelet denoising"));
9308 puts(_("-H [0-9] Highlight mode (0=clip, 1=unclip, 2=blend, 3+=rebuild)"));
9309 puts(_("-t [0-7] Flip image (0=none, 3=180, 5=90CCW, 6=90CW)"));
9310 puts(_("-o [0-5] Output colorspace (raw,sRGB,Adobe,Wide,ProPhoto,XYZ)"));
9312 puts(_("-o <file> Apply output ICC profile from file"));
9313 puts(_("-p <file> Apply camera ICC profile from file or \"embed\""));
9315 puts(_("-d Document mode (no color, no interpolation)"));
9316 puts(_("-D Document mode without scaling (totally raw)"));
9317 puts(_("-j Don't stretch or rotate raw pixels"));
9318 puts(_("-W Don't automatically brighten the image"));
9319 puts(_("-b <num> Adjust brightness (default = 1.0)"));
9320 puts(_("-g <p ts> Set custom gamma curve (default = 2.222 4.5)"));
9321 puts(_("-q [0-3] Set the interpolation quality"));
9322 puts(_("-h Half-size color image (twice as fast as \"-q 0\")"));
9323 puts(_("-f Interpolate RGGB as four colors"));
9324 puts(_("-m <num> Apply a 3x3 median filter to R-G and B-G"));
9325 puts(_("-s [0..N-1] Select one raw image or \"all\" from each file"));
9326 puts(_("-6 Write 16-bit instead of 8-bit"));
9327 puts(_("-4 Linear 16-bit, same as \"-6 -W -g 1 1\""));
9328 puts(_("-T Write TIFF instead of PPM"));
9333 for (arg=1; (((opm = argv[arg][0]) - 2) | 2) == '+'; ) {
9334 opt = argv[arg++][1];
9335 if ((cp = (char *) strchr (sp="nbrkStqmHACg", opt)))
9336 for (i=0; i < "114111111422"[cp-sp]-'0'; i++)
9337 if (!isdigit(argv[arg+i][0])) {
9338 fprintf (stderr,_("Non-numeric argument to \"-%c\"\n"), opt);
9342 case 'n': threshold = atof(argv[arg++]); break;
9343 case 'b': bright = atof(argv[arg++]); break;
9345 FORC4 user_mul[c] = atof(argv[arg++]); break;
9346 case 'C': aber[0] = 1 / atof(argv[arg++]);
9347 aber[2] = 1 / atof(argv[arg++]); break;
9348 case 'g': gamm[0] = atof(argv[arg++]);
9349 gamm[1] = atof(argv[arg++]);
9350 if (gamm[0]) gamm[0] = 1/gamm[0]; break;
9351 case 'k': user_black = atoi(argv[arg++]); break;
9352 case 'S': user_sat = atoi(argv[arg++]); break;
9353 case 't': user_flip = atoi(argv[arg++]); break;
9354 case 'q': user_qual = atoi(argv[arg++]); break;
9355 case 'm': med_passes = atoi(argv[arg++]); break;
9356 case 'H': highlight = atoi(argv[arg++]); break;
9358 shot_select = abs(atoi(argv[arg]));
9359 multi_out = !strcmp(argv[arg++],"all");
9362 if (isdigit(argv[arg][0]) && !argv[arg][1])
9363 output_color = atoi(argv[arg++]);
9365 else out_profile = argv[arg++];
9367 case 'p': cam_profile = argv[arg++];
9370 case 'P': bpfile = argv[arg++]; break;
9371 case 'K': dark_frame = argv[arg++]; break;
9372 case 'z': timestamp_only = 1; break;
9373 case 'e': thumbnail_only = 1; break;
9374 case 'i': identify_only = 1; break;
9375 case 'c': write_to_stdout = 1; break;
9376 case 'v': verbose = 1; break;
9377 case 'h': half_size = 1; /* "-h" implies "-f" */
9378 case 'f': four_color_rgb = 1; break;
9379 case 'A': FORC4 greybox[c] = atoi(argv[arg++]);
9380 case 'a': use_auto_wb = 1; break;
9381 case 'w': use_camera_wb = 1; break;
9382 case 'M': use_camera_matrix = (opm == '+'); break;
9383 case 'I': read_from_stdin = 1; break;
9384 case 'E': document_mode++;
9385 case 'D': document_mode++;
9386 case 'd': document_mode++;
9387 case 'j': use_fuji_rotate = 0; break;
9388 case 'W': no_auto_bright = 1; break;
9389 case 'T': output_tiff = 1; break;
9390 case '4': gamm[0] = gamm[1] =
9392 case '6': output_bps = 16; break;
9394 fprintf (stderr,_("Unknown option \"-%c\".\n"), opt);
9398 if (use_camera_matrix < 0)
9399 use_camera_matrix = use_camera_wb;
9401 fprintf (stderr,_("No files to process.\n"));
9404 if (write_to_stdout) {
9408 fprintf (stderr,_("Will not write an image to the terminal!\n"));
9411 #if defined(WIN32) || defined(DJGPP) || defined(__CYGWIN__)
9412 if (setmode(1,O_BINARY) < 0) {
9413 perror ("setmode()");
9418 for ( ; arg < argc; arg++) {
9423 meta_data = ofname = 0;
9425 if (setjmp (failure)) {
9426 if (fileno(ifp) > 2) fclose(ifp);
9427 if (fileno(ofp) > 2) fclose(ofp);
9432 if (!(ifp = fopen (ifname, "rb"))) {
9436 status = (identify(),!is_raw);
9439 switch ((flip+3600) % 360) {
9440 case 270: flip = 5; break;
9441 case 180: flip = 3; break;
9444 if (timestamp_only) {
9445 if ((status = !timestamp))
9446 fprintf (stderr,_("%s has no timestamp.\n"), ifname);
9447 else if (identify_only)
9448 printf ("%10ld%10d %s\n", (long) timestamp, shot_order, ifname);
9451 fprintf (stderr,_("%s time set to %d.\n"), ifname, (int) timestamp);
9452 ut.actime = ut.modtime = timestamp;
9453 utime (ifname, &ut);
9457 write_fun = &CLASS write_ppm_tiff;
9462 write_fun = write_cinelerra;
9467 if (thumbnail_only) {
9468 if ((status = !thumb_offset)) {
9469 fprintf (stderr,_("%s has no thumbnail.\n"), ifname);
9471 } else if (thumb_load_raw) {
9472 load_raw = thumb_load_raw;
9473 data_offset = thumb_offset;
9474 height = thumb_height;
9475 width = thumb_width;
9478 fseek (ifp, thumb_offset, SEEK_SET);
9479 write_fun = write_thumb;
9483 if (load_raw == &CLASS kodak_ycbcr_load_raw) {
9484 height += height & 1;
9487 if (identify_only && verbose && make[0]) {
9488 printf (_("\nFilename: %s\n"), ifname);
9489 printf (_("Timestamp: %s"), ctime(×tamp));
9490 printf (_("Camera: %s %s\n"), make, model);
9492 printf (_("Owner: %s\n"), artist);
9494 printf (_("DNG Version: "));
9495 for (i=24; i >= 0; i -= 8)
9496 printf ("%d%c", dng_version >> i & 255, i ? '.':'\n');
9498 printf (_("ISO speed: %d\n"), (int) iso_speed);
9499 printf (_("Shutter: "));
9500 if (shutter > 0 && shutter < 1)
9501 shutter = (printf ("1/"), 1 / shutter);
9502 printf (_("%0.1f sec\n"), shutter);
9503 printf (_("Aperture: f/%0.1f\n"), aperture);
9504 printf (_("Focal length: %0.1f mm\n"), focal_len);
9505 printf (_("Embedded ICC profile: %s\n"), profile_length ? _("yes"):_("no"));
9506 printf (_("Number of raw images: %d\n"), is_raw);
9507 if (pixel_aspect != 1)
9508 printf (_("Pixel Aspect Ratio: %0.6f\n"), pixel_aspect);
9510 printf (_("Thumb size: %4d x %d\n"), thumb_width, thumb_height);
9511 printf (_("Full size: %4d x %d\n"), raw_width, raw_height);
9517 // else if (!is_raw)
9518 // fprintf (stderr,_("Cannot decode file %s\n"), ifname);
9525 if (!is_raw) goto next;
9526 shrink = filters && (half_size || (!identify_only &&
9527 (threshold || aber[0] != 1 || aber[2] != 1)));
9528 iheight = (height + shrink) >> shrink;
9529 iwidth = (width + shrink) >> shrink;
9530 if (identify_only) {
9532 if (document_mode == 3) {
9533 top_margin = left_margin = fuji_width = 0;
9534 height = raw_height;
9535 if (width <= raw_width * 8 / tiff_bps)
9536 width = raw_width * 8 / tiff_bps;
9537 else width = raw_width;
9539 iheight = (height + shrink) >> shrink;
9540 iwidth = (width + shrink) >> shrink;
9541 if (use_fuji_rotate) {
9543 fuji_width = (fuji_width - 1 + shrink) >> shrink;
9544 iwidth = fuji_width / sqrt(0.5);
9545 iheight = (iheight - fuji_width) / sqrt(0.5);
9547 if (pixel_aspect < 1) iheight = iheight / pixel_aspect + 0.5;
9548 if (pixel_aspect > 1) iwidth = iwidth * pixel_aspect + 0.5;
9552 SWAP(iheight,iwidth);
9553 printf (_("Image size: %4d x %d\n"), width, height);
9554 printf (_("Output size: %4d x %d\n"), iwidth, iheight);
9555 printf (_("Raw colors: %d"), colors);
9557 printf (_("\nFilter pattern: "));
9558 for (i=0; i < 16; i++)
9559 putchar (cdesc[fcol(i >> 1,i & 1)]);
9561 printf (_("\nDaylight multipliers:"));
9562 FORCC printf (" %f", pre_mul[c]);
9563 if (cam_mul[0] > 0) {
9564 printf (_("\nCamera multipliers:"));
9565 FORC4 printf (" %f", cam_mul[c]);
9570 // printf (_("%s is a %s %s image.\n"), ifname, make, model);
9575 if (use_camera_matrix && cmatrix[0][0] > 0.25) {
9576 memcpy (rgb_cam, cmatrix, sizeof cmatrix);
9580 meta_data = (char *) malloc (meta_length);
9581 merror (meta_data, "main()");
9583 if (filters || colors == 1) {
9584 raw_image = (ushort *) calloc ((raw_height+7)*raw_width, 2);
9585 merror (raw_image, "main()");
9587 image = (ushort (*)[4]) calloc (iheight*iwidth, sizeof *image);
9588 merror (image, "main()");
9591 fprintf (stderr,_("Loading %s %s image from %s ...\n"),
9592 make, model, ifname);
9593 if (shot_select >= is_raw)
9594 fprintf (stderr,_("%s: \"-s %d\" requests a nonexistent image!\n"),
9595 ifname, shot_select);
9596 fseeko (ifp, data_offset, SEEK_SET);
9597 if (raw_image && read_from_stdin)
9598 fread (raw_image, 2, raw_height*raw_width, stdin);
9600 if (document_mode == 3) {
9601 top_margin = left_margin = fuji_width = 0;
9602 height = raw_height;
9603 if (width <= raw_width * 8 / tiff_bps)
9604 width = raw_width * 8 / tiff_bps;
9605 else width = raw_width;
9607 iheight = (height + shrink) >> shrink;
9608 iwidth = (width + shrink) >> shrink;
9610 image = (ushort (*)[4]) calloc (iheight*iwidth, sizeof *image);
9611 merror (image, "main()");
9612 crop_masked_pixels();
9615 if (zero_is_bad) remove_zeroes();
9616 bad_pixels (bpfile);
9617 if (dark_frame) subtract (dark_frame);
9618 quality = 2 + !fuji_width;
9619 if (user_qual >= 0) quality = user_qual;
9621 FORC3 if (i > cblack[c]) i = cblack[c];
9622 FORC4 cblack[c] -= i;
9624 if (user_black >= 0) black = user_black;
9625 FORC4 cblack[c] += black;
9626 if (user_sat > 0) maximum = user_sat;
9631 if (document_mode || load_raw == &CLASS foveon_dp_load_raw) {
9632 for (i=0; i < height*width*4; i++)
9633 if ((short) image[0][i] < 0) image[0][i] = 0;
9634 } else foveon_interpolate();
9635 } else if (document_mode < 2)
9638 if (filters && !document_mode) {
9641 else if (quality == 1 || colors > 3 || filters < 1000)
9643 else if (quality == 2)
9645 else ahd_interpolate();
9648 for (colors=3, i=0; i < height*width; i++)
9649 image[i][1] = (image[i][1] + image[i][3]) >> 1;
9650 if (!is_foveon && colors == 3) median_filter();
9651 if (!is_foveon && highlight == 2) blend_highlights();
9652 if (!is_foveon && highlight > 2) recover_highlights();
9653 if (use_fuji_rotate) fuji_rotate();
9655 if (cam_profile) apply_profile (cam_profile, out_profile);
9658 if (use_fuji_rotate) stretch();
9660 if (write_fun == &CLASS jpeg_thumb)
9662 else if (output_tiff && write_fun == &CLASS write_ppm_tiff)
9663 write_ext = ".tiff";
9665 write_ext = ".pgm\0.ppm\0.ppm\0.pam" + colors*5-5;
9666 ofname = (char *) malloc (strlen(ifname) + 64);
9667 merror (ofname, "main()");
9668 if (write_to_stdout)
9669 strcpy (ofname,_("standard output"));
9671 strcpy (ofname, ifname);
9672 if ((cp = strrchr (ofname, '.'))) *cp = 0;
9674 sprintf (ofname+strlen(ofname), "_%0*d",
9675 snprintf(0,0,"%d",is_raw-1), shot_select);
9677 strcat (ofname, ".thumb");
9678 strcat (ofname, write_ext);
9679 ofp = fopen (ofname, "wb");
9687 fprintf (stderr,_("Writing data to %s ...\n"), ofname);
9690 if (ofp != stdout) fclose(ofp);
9692 if (meta_data) free (meta_data);
9693 if (ofname) free (ofname);
9694 if (oprof) free (oprof);
9695 if (image) free (image);
9697 if (++shot_select < is_raw) arg--;
9698 else shot_select = 0;