2
dcraw.c -- Dave Coffin's raw photo decoder
3
Copyright 1997-2009 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: 2009/12/25 18:51:16 $
26
#define VERSION "8.99"
31
#define _USE_MATH_DEFINES
43
#include <sys/types.h>
45
NO_JPEG disables decoding of compressed Kodak DC120 files.
46
NO_LCMS disables the "-p" option.
56
#define _(String) gettext(String)
58
#define _(String) (String)
64
#define fgetc getc_unlocked
70
#include <sys/utime.h>
72
#pragma comment(lib, "ws2_32.lib")
73
#define snprintf _snprintf
74
#define strcasecmp stricmp
75
#define strncasecmp strnicmp
76
typedef __int64 INT64;
77
typedef unsigned __int64 UINT64;
81
#include <netinet/in.h>
82
typedef long long INT64;
83
typedef unsigned long long UINT64;
87
#error Please compile dcraw.c by itself.
88
#error Do not link it with ljpeg_decode.
92
#define LONG_BIT (8 * sizeof (long))
96
typedef unsigned char uchar;
97
typedef unsigned short ushort;
100
All global variables are defined here, and all functions that
101
access them are prefixed with "CLASS". Note that a thread-safe
102
C++ class cannot have non-const static local variables.
108
char cdesc[5], desc[512], make[64], model[64], model2[64], artist[64];
109
float flash_used, canon_ev, iso_speed, shutter, aperture, focal_len;
111
unsigned shot_order, kodak_cbpp, filters, exif_cfa, unique_id;
112
off_t strip_offset, data_offset;
113
off_t thumb_offset, meta_offset, profile_offset;
114
unsigned thumb_length, meta_length, profile_length;
115
unsigned thumb_misc, *oprof, fuji_layout, shot_select=0, multi_out=0;
116
unsigned tiff_nifds, tiff_samples, tiff_bps, tiff_compress;
117
unsigned black, maximum, mix_green, raw_color, zero_is_bad;
118
unsigned zero_after_ff, is_raw, dng_version, is_foveon, data_error;
119
unsigned tile_width, tile_length, gpsdata[32], load_flags;
120
ushort raw_height, raw_width, height, width, top_margin, left_margin;
121
ushort shrink, iheight, iwidth, fuji_width, thumb_width, thumb_height;
122
int flip, tiff_flip, colors;
123
double pixel_aspect, aber[4]={1,1,1,1}, gamm[6]={ 0.45,4.5,0,0,0,0 };
124
ushort (*image)[4], white[8][8], curve[0x10000], cr2_slice[3], sraw_mul[4];
125
float bright=1, user_mul[4]={0,0,0,0}, threshold=0;
126
int half_size=0, four_color_rgb=0, document_mode=0, highlight=0;
127
int verbose=0, use_auto_wb=0, use_camera_wb=0, use_camera_matrix=-1;
128
int output_color=1, output_bps=8, output_tiff=0, med_passes=0;
129
int no_auto_bright=0;
130
unsigned greybox[4] = { 0, 0, UINT_MAX, UINT_MAX };
131
float cam_mul[4], pre_mul[4], cmatrix[3][4], rgb_cam[3][4];
132
const double xyz_rgb[3][3] = { /* XYZ from RGB */
133
{ 0.412453, 0.357580, 0.180423 },
134
{ 0.212671, 0.715160, 0.072169 },
135
{ 0.019334, 0.119193, 0.950227 } };
136
const float d65_white[3] = { 0.950456, 1, 1.088754 };
137
int histogram[4][0x2000];
138
void (*write_thumb)(), (*write_fun)();
139
void (*load_raw)(), (*thumb_load_raw)();
143
struct decode *branch[2];
145
} first_decode[2048], *second_decode, *free_decode;
148
int width, height, bps, comp, phint, offset, flip, samples, bytes;
152
int format, key_off, black, black_off, split_col, tag_21a;
158
#define FORC(cnt) for (c=0; c < cnt; c++)
159
#define FORC3 FORC(3)
160
#define FORC4 FORC(4)
161
#define FORCC FORC(colors)
163
#define SQR(x) ((x)*(x))
164
#define ABS(x) (((int)(x) ^ ((int)(x) >> 31)) - ((int)(x) >> 31))
165
#define MIN(a,b) ((a) < (b) ? (a) : (b))
166
#define MAX(a,b) ((a) > (b) ? (a) : (b))
167
#define LIM(x,min,max) MAX(min,MIN(x,max))
168
#define ULIM(x,y,z) ((y) < (z) ? LIM(x,y,z) : LIM(x,z,y))
169
#define CLIP(x) LIM(x,0,65535)
170
#define SWAP(a,b) { a ^= b; a ^= (b ^= a); }
173
In order to inline this calculation, I make the risky
174
assumption that all filter patterns can be described
175
by a repeating pattern of eight rows and two columns
177
Do not use the FC or BAYER macros with the Leaf CatchLight,
178
because its pattern is 16x16, not 2x8.
180
Return values are either 0/1/2/3 = G/M/C/Y or 0/1/2/3 = R/G1/B/G2
182
PowerShot 600 PowerShot A50 PowerShot Pro70 Pro90 & G1
183
0xe1e4e1e4: 0x1b4e4b1e: 0x1e4b4e1b: 0xb4b4b4b4:
185
0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5
186
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
187
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
188
2 M G M G M G 2 Y C Y C Y C 2 C Y C Y C Y
189
3 C Y C Y C Y 3 G M G M G M 3 G M G M G M
190
4 C Y C Y C Y 4 Y C Y C Y C
191
PowerShot A5 5 G M G M G M 5 G M G M G M
192
0x1e4e1e4e: 6 Y C Y C Y C 6 C Y C Y C Y
193
7 M G M G M G 7 M G M G M G
200
All RGB cameras use one of these Bayer grids:
202
0x16161616: 0x61616161: 0x49494949: 0x94949494:
204
0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5
205
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
206
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
207
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
208
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
211
#define FC(row,col) \
212
(filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)
214
#define BAYER(row,col) \
215
image[((row) >> shrink)*iwidth + ((col) >> shrink)][FC(row,col)]
217
#define BAYER2(row,col) \
218
image[((row) >> shrink)*iwidth + ((col) >> shrink)][fc(row,col)]
220
int CLASS fc (int row, int col)
222
static const char filter[16][16] =
223
{ { 2,1,1,3,2,3,2,0,3,2,3,0,1,2,1,0 },
224
{ 0,3,0,2,0,1,3,1,0,1,1,2,0,3,3,2 },
225
{ 2,3,3,2,3,1,1,3,3,1,2,1,2,0,0,3 },
226
{ 0,1,0,1,0,2,0,2,2,0,3,0,1,3,2,1 },
227
{ 3,1,1,2,0,1,0,2,1,3,1,3,0,1,3,0 },
228
{ 2,0,0,3,3,2,3,1,2,0,2,0,3,2,2,1 },
229
{ 2,3,3,1,2,1,2,1,2,1,1,2,3,0,0,1 },
230
{ 1,0,0,2,3,0,0,3,0,3,0,3,2,1,2,3 },
231
{ 2,3,3,1,1,2,1,0,3,2,3,0,2,3,1,3 },
232
{ 1,0,2,0,3,0,3,2,0,1,1,2,0,1,0,2 },
233
{ 0,1,1,3,3,2,2,1,1,3,3,0,2,1,3,2 },
234
{ 2,3,2,0,0,1,3,0,2,0,1,2,3,0,1,0 },
235
{ 1,3,1,2,3,2,3,2,0,2,0,1,1,0,3,0 },
236
{ 0,2,0,3,1,0,0,1,1,3,3,2,3,2,2,1 },
237
{ 2,1,3,2,3,1,2,1,0,3,0,2,0,2,0,2 },
238
{ 0,3,1,0,0,2,0,3,2,1,3,1,1,3,1,3 } };
240
if (filters != 1) return FC(row,col);
241
return filter[(row+top_margin) & 15][(col+left_margin) & 15];
245
char *my_memmem (char *haystack, size_t haystacklen,
246
char *needle, size_t needlelen)
249
for (c = haystack; c <= haystack + haystacklen - needlelen; c++)
250
if (!memcmp (c, needle, needlelen))
254
#define memmem my_memmem
257
void CLASS merror (void *ptr, const char *where)
260
fprintf (stderr,_("%s: Out of memory in %s\n"), ifname, where);
261
longjmp (failure, 1);
267
fprintf (stderr, "%s: ", ifname);
269
fprintf (stderr,_("Unexpected end of file\n"));
271
fprintf (stderr,_("Corrupt data near 0x%llx\n"), (INT64) ftello(ifp));
276
ushort CLASS sget2 (uchar *s)
278
if (order == 0x4949) /* "II" means little-endian */
279
return s[0] | s[1] << 8;
280
else /* "MM" means big-endian */
281
return s[0] << 8 | s[1];
286
uchar str[2] = { 0xff,0xff };
287
fread (str, 1, 2, ifp);
291
unsigned CLASS sget4 (uchar *s)
294
return s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24;
296
return s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3];
298
#define sget4(s) sget4((uchar *)s)
300
unsigned CLASS get4()
302
uchar str[4] = { 0xff,0xff,0xff,0xff };
303
fread (str, 1, 4, ifp);
307
unsigned CLASS getint (int type)
309
return type == 3 ? get2() : get4();
312
float CLASS int_to_float (int i)
314
union { int i; float f; } u;
319
double CLASS getreal (int type)
321
union { char c[8]; double d; } u;
325
case 3: return (unsigned short) get2();
326
case 4: return (unsigned int) get4();
327
case 5: u.d = (unsigned int) get4();
328
return u.d / (unsigned int) get4();
329
case 8: return (signed short) get2();
330
case 9: return (signed int) get4();
331
case 10: u.d = (signed int) get4();
332
return u.d / (signed int) get4();
333
case 11: return int_to_float (get4());
335
rev = 7 * ((order == 0x4949) == (ntohs(0x1234) == 0x1234));
336
for (i=0; i < 8; i++)
337
u.c[i ^ rev] = fgetc(ifp);
339
default: return fgetc(ifp);
343
void CLASS read_shorts (ushort *pixel, int count)
345
if (fread (pixel, 2, count, ifp) < count) derror();
346
if ((order == 0x4949) == (ntohs(0x1234) == 0x1234))
347
swab (pixel, pixel, count*2);
350
void CLASS canon_black (double dark[2], int nblack)
352
int c, diff, row, col;
355
FORC(2) dark[c] /= nblack >> 1;
356
if ((diff = dark[0] - dark[1]))
357
for (row=0; row < height; row++)
358
for (col=1; col < width; col+=2)
359
BAYER(row,col) += diff;
361
black = (dark[0] + dark[1] + 1) / 2;
364
void CLASS canon_600_fixed_wb (int temp)
366
static const short mul[4][5] = {
367
{ 667, 358,397,565,452 },
368
{ 731, 390,367,499,517 },
369
{ 1119, 396,348,448,537 },
370
{ 1399, 485,431,508,688 } };
375
if (*mul[lo] <= temp) break;
376
for (hi=0; hi < 3; hi++)
377
if (*mul[hi] >= temp) break;
379
frac = (float) (temp - *mul[lo]) / (*mul[hi] - *mul[lo]);
380
for (i=1; i < 5; i++)
381
pre_mul[i-1] = 1 / (frac * mul[hi][i] + (1-frac) * mul[lo][i]);
384
/* Return values: 0 = white 1 = near white 2 = not white */
385
int CLASS canon_600_color (int ratio[2], int mar)
387
int clipped=0, target, miss;
391
{ ratio[1] = -104; clipped = 1; }
393
{ ratio[1] = 12; clipped = 1; }
395
if (ratio[1] < -264 || ratio[1] > 461) return 2;
397
{ ratio[1] = -50; clipped = 1; }
399
{ ratio[1] = 307; clipped = 1; }
401
target = flash_used || ratio[1] < 197
402
? -38 - (398 * ratio[1] >> 10)
403
: -123 + (48 * ratio[1] >> 10);
404
if (target - mar <= ratio[0] &&
405
target + 20 >= ratio[0] && !clipped) return 0;
406
miss = target - ratio[0];
407
if (abs(miss) >= mar*4) return 2;
408
if (miss < -20) miss = -20;
409
if (miss > mar) miss = mar;
410
ratio[0] = target - miss;
414
void CLASS canon_600_auto_wb()
416
int mar, row, col, i, j, st, count[] = { 0,0 };
417
int test[8], total[2][8], ratio[2][2], stat[2];
419
memset (&total, 0, sizeof total);
421
if (i < 10) mar = 150;
422
else if (i > 12) mar = 20;
423
else mar = 280 - 20 * i;
424
if (flash_used) mar = 80;
425
for (row=14; row < height-14; row+=4)
426
for (col=10; col < width; col+=2) {
427
for (i=0; i < 8; i++)
428
test[(i & 4) + FC(row+(i >> 1),col+(i & 1))] =
429
BAYER(row+(i >> 1),col+(i & 1));
430
for (i=0; i < 8; i++)
431
if (test[i] < 150 || test[i] > 1500) goto next;
432
for (i=0; i < 4; i++)
433
if (abs(test[i] - test[i+4]) > 50) goto next;
434
for (i=0; i < 2; i++) {
435
for (j=0; j < 4; j+=2)
436
ratio[i][j >> 1] = ((test[i*4+j+1]-test[i*4+j]) << 10) / test[i*4+j];
437
stat[i] = canon_600_color (ratio[i], mar);
439
if ((st = stat[0] | stat[1]) > 1) goto next;
440
for (i=0; i < 2; i++)
442
for (j=0; j < 2; j++)
443
test[i*4+j*2+1] = test[i*4+j*2] * (0x400 + ratio[i][j]) >> 10;
444
for (i=0; i < 8; i++)
445
total[st][i] += test[i];
449
if (count[0] | count[1]) {
450
st = count[0]*200 < count[1];
451
for (i=0; i < 4; i++)
452
pre_mul[i] = 1.0 / (total[st][i] + total[st][i+4]);
456
void CLASS canon_600_coeff()
458
static const short table[6][12] = {
459
{ -190,702,-1878,2390, 1861,-1349,905,-393, -432,944,2617,-2105 },
460
{ -1203,1715,-1136,1648, 1388,-876,267,245, -1641,2153,3921,-3409 },
461
{ -615,1127,-1563,2075, 1437,-925,509,3, -756,1268,2519,-2007 },
462
{ -190,702,-1886,2398, 2153,-1641,763,-251, -452,964,3040,-2528 },
463
{ -190,702,-1878,2390, 1861,-1349,905,-393, -432,944,2617,-2105 },
464
{ -807,1319,-1785,2297, 1388,-876,769,-257, -230,742,2067,-1555 } };
468
mc = pre_mul[1] / pre_mul[2];
469
yc = pre_mul[3] / pre_mul[2];
470
if (mc > 1 && mc <= 1.28 && yc < 0.8789) t=1;
471
if (mc > 1.28 && mc <= 2) {
472
if (yc < 0.8789) t=3;
473
else if (yc <= 2) t=4;
476
for (raw_color = i=0; i < 3; i++)
477
FORCC rgb_cam[i][c] = table[t][i*4 + c] / 1024.0;
480
void CLASS canon_600_load_raw()
482
uchar data[1120], *dp;
483
ushort pixel[896], *pix;
484
int irow, row, col, val;
485
static const short mul[4][2] =
486
{ { 1141,1145 }, { 1128,1109 }, { 1178,1149 }, { 1128,1109 } };
488
for (irow=row=0; irow < height; irow++) {
489
if (fread (data, 1, raw_width*5/4, ifp) < raw_width*5/4) derror();
490
for (dp=data, pix=pixel; dp < data+1120; dp+=10, pix+=8) {
491
pix[0] = (dp[0] << 2) + (dp[1] >> 6 );
492
pix[1] = (dp[2] << 2) + (dp[1] >> 4 & 3);
493
pix[2] = (dp[3] << 2) + (dp[1] >> 2 & 3);
494
pix[3] = (dp[4] << 2) + (dp[1] & 3);
495
pix[4] = (dp[5] << 2) + (dp[9] & 3);
496
pix[5] = (dp[6] << 2) + (dp[9] >> 2 & 3);
497
pix[6] = (dp[7] << 2) + (dp[9] >> 4 & 3);
498
pix[7] = (dp[8] << 2) + (dp[9] >> 6 );
500
for (col=0; col < width; col++)
501
BAYER(row,col) = pixel[col];
502
for (col=width; col < raw_width; col++)
504
if ((row+=2) > height) row = 1;
506
if (raw_width > width)
507
black = black / ((raw_width - width) * height) - 4;
508
for (row=0; row < height; row++)
509
for (col=0; col < width; col++) {
510
if ((val = BAYER(row,col) - black) < 0) val = 0;
511
val = val * mul[row & 3][col & 1] >> 9;
512
BAYER(row,col) = val;
514
canon_600_fixed_wb(1311);
517
maximum = (0x3ff - black) * 1109 >> 9;
521
void CLASS remove_zeroes()
523
unsigned row, col, tot, n, r, c;
525
for (row=0; row < height; row++)
526
for (col=0; col < width; col++)
527
if (BAYER(row,col) == 0) {
529
for (r = row-2; r <= row+2; r++)
530
for (c = col-2; c <= col+2; c++)
531
if (r < height && c < width &&
532
FC(r,c) == FC(row,col) && BAYER(r,c))
533
tot += (n++,BAYER(r,c));
534
if (n) BAYER(row,col) = tot/n;
538
int CLASS canon_s2is()
542
for (row=0; row < 100; row++) {
543
fseek (ifp, row*3340 + 3284, SEEK_SET);
544
if (getc(ifp) > 15) return 1;
550
getbits(-1) initializes the buffer
551
getbits(n) where 0 <= n <= 25 returns an n-bit integer
553
unsigned CLASS getbithuff (int nbits, ushort *huff)
555
static unsigned bitbuf=0;
556
static int vbits=0, reset=0;
560
return bitbuf = vbits = reset = 0;
561
if (nbits == 0 || vbits < 0) return 0;
562
while (!reset && vbits < nbits && (c = fgetc(ifp)) != EOF &&
563
!(reset = zero_after_ff && c == 0xff && fgetc(ifp))) {
564
bitbuf = (bitbuf << 8) + (uchar) c;
567
c = bitbuf << (32-vbits) >> (32-nbits);
569
vbits -= huff[c] >> 8;
573
if (vbits < 0) derror();
577
#define getbits(n) getbithuff(n,0)
578
#define gethuff(h) getbithuff(*h,h+1)
581
Construct a decode tree according the specification in *source.
582
The first 16 bytes specify how many codes should be 1-bit, 2-bit
583
3-bit, etc. Bytes after that are the leaf values.
585
For example, if the source is
587
{ 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0,
588
0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff },
606
ushort * CLASS make_decoder_ref (const uchar **source)
608
int max, len, h, i, j;
612
count = (*source += 16) - 17;
613
for (max=16; max && !count[max]; max--);
614
huff = (ushort *) calloc (1 + (1 << max), sizeof *huff);
615
merror (huff, "make_decoder()");
617
for (h=len=1; len <= max; len++)
618
for (i=0; i < count[len]; i++, ++*source)
619
for (j=0; j < 1 << (max-len); j++)
621
huff[h++] = len << 8 | **source;
625
ushort * CLASS make_decoder (const uchar *source)
627
return make_decoder_ref (&source);
630
void CLASS crw_init_tables (unsigned table, ushort *huff[2])
632
static const uchar first_tree[3][29] = {
633
{ 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0,
634
0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff },
635
{ 0,2,2,3,1,1,1,1,2,0,0,0,0,0,0,0,
636
0x03,0x02,0x04,0x01,0x05,0x00,0x06,0x07,0x09,0x08,0x0a,0x0b,0xff },
637
{ 0,0,6,3,1,1,2,0,0,0,0,0,0,0,0,0,
638
0x06,0x05,0x07,0x04,0x08,0x03,0x09,0x02,0x00,0x0a,0x01,0x0b,0xff },
640
static const uchar second_tree[3][180] = {
641
{ 0,2,2,2,1,4,2,1,2,5,1,1,0,0,0,139,
642
0x03,0x04,0x02,0x05,0x01,0x06,0x07,0x08,
643
0x12,0x13,0x11,0x14,0x09,0x15,0x22,0x00,0x21,0x16,0x0a,0xf0,
644
0x23,0x17,0x24,0x31,0x32,0x18,0x19,0x33,0x25,0x41,0x34,0x42,
645
0x35,0x51,0x36,0x37,0x38,0x29,0x79,0x26,0x1a,0x39,0x56,0x57,
646
0x28,0x27,0x52,0x55,0x58,0x43,0x76,0x59,0x77,0x54,0x61,0xf9,
647
0x71,0x78,0x75,0x96,0x97,0x49,0xb7,0x53,0xd7,0x74,0xb6,0x98,
648
0x47,0x48,0x95,0x69,0x99,0x91,0xfa,0xb8,0x68,0xb5,0xb9,0xd6,
649
0xf7,0xd8,0x67,0x46,0x45,0x94,0x89,0xf8,0x81,0xd5,0xf6,0xb4,
650
0x88,0xb1,0x2a,0x44,0x72,0xd9,0x87,0x66,0xd4,0xf5,0x3a,0xa7,
651
0x73,0xa9,0xa8,0x86,0x62,0xc7,0x65,0xc8,0xc9,0xa1,0xf4,0xd1,
652
0xe9,0x5a,0x92,0x85,0xa6,0xe7,0x93,0xe8,0xc1,0xc6,0x7a,0x64,
653
0xe1,0x4a,0x6a,0xe6,0xb3,0xf1,0xd3,0xa5,0x8a,0xb2,0x9a,0xba,
654
0x84,0xa4,0x63,0xe5,0xc5,0xf3,0xd2,0xc4,0x82,0xaa,0xda,0xe4,
655
0xf2,0xca,0x83,0xa3,0xa2,0xc3,0xea,0xc2,0xe2,0xe3,0xff,0xff },
656
{ 0,2,2,1,4,1,4,1,3,3,1,0,0,0,0,140,
657
0x02,0x03,0x01,0x04,0x05,0x12,0x11,0x06,
658
0x13,0x07,0x08,0x14,0x22,0x09,0x21,0x00,0x23,0x15,0x31,0x32,
659
0x0a,0x16,0xf0,0x24,0x33,0x41,0x42,0x19,0x17,0x25,0x18,0x51,
660
0x34,0x43,0x52,0x29,0x35,0x61,0x39,0x71,0x62,0x36,0x53,0x26,
661
0x38,0x1a,0x37,0x81,0x27,0x91,0x79,0x55,0x45,0x28,0x72,0x59,
662
0xa1,0xb1,0x44,0x69,0x54,0x58,0xd1,0xfa,0x57,0xe1,0xf1,0xb9,
663
0x49,0x47,0x63,0x6a,0xf9,0x56,0x46,0xa8,0x2a,0x4a,0x78,0x99,
664
0x3a,0x75,0x74,0x86,0x65,0xc1,0x76,0xb6,0x96,0xd6,0x89,0x85,
665
0xc9,0xf5,0x95,0xb4,0xc7,0xf7,0x8a,0x97,0xb8,0x73,0xb7,0xd8,
666
0xd9,0x87,0xa7,0x7a,0x48,0x82,0x84,0xea,0xf4,0xa6,0xc5,0x5a,
667
0x94,0xa4,0xc6,0x92,0xc3,0x68,0xb5,0xc8,0xe4,0xe5,0xe6,0xe9,
668
0xa2,0xa3,0xe3,0xc2,0x66,0x67,0x93,0xaa,0xd4,0xd5,0xe7,0xf8,
669
0x88,0x9a,0xd7,0x77,0xc4,0x64,0xe2,0x98,0xa5,0xca,0xda,0xe8,
670
0xf3,0xf6,0xa9,0xb2,0xb3,0xf2,0xd2,0x83,0xba,0xd3,0xff,0xff },
671
{ 0,0,6,2,1,3,3,2,5,1,2,2,8,10,0,117,
672
0x04,0x05,0x03,0x06,0x02,0x07,0x01,0x08,
673
0x09,0x12,0x13,0x14,0x11,0x15,0x0a,0x16,0x17,0xf0,0x00,0x22,
674
0x21,0x18,0x23,0x19,0x24,0x32,0x31,0x25,0x33,0x38,0x37,0x34,
675
0x35,0x36,0x39,0x79,0x57,0x58,0x59,0x28,0x56,0x78,0x27,0x41,
676
0x29,0x77,0x26,0x42,0x76,0x99,0x1a,0x55,0x98,0x97,0xf9,0x48,
677
0x54,0x96,0x89,0x47,0xb7,0x49,0xfa,0x75,0x68,0xb6,0x67,0x69,
678
0xb9,0xb8,0xd8,0x52,0xd7,0x88,0xb5,0x74,0x51,0x46,0xd9,0xf8,
679
0x3a,0xd6,0x87,0x45,0x7a,0x95,0xd5,0xf6,0x86,0xb4,0xa9,0x94,
680
0x53,0x2a,0xa8,0x43,0xf5,0xf7,0xd4,0x66,0xa7,0x5a,0x44,0x8a,
681
0xc9,0xe8,0xc8,0xe7,0x9a,0x6a,0x73,0x4a,0x61,0xc7,0xf4,0xc6,
682
0x65,0xe9,0x72,0xe6,0x71,0x91,0x93,0xa6,0xda,0x92,0x85,0x62,
683
0xf3,0xc5,0xb2,0xa4,0x84,0xba,0x64,0xa5,0xb3,0xd2,0x81,0xe5,
684
0xd3,0xaa,0xc4,0xca,0xf2,0xb1,0xe4,0xd1,0x83,0x63,0xea,0xc3,
685
0xe2,0x82,0xf1,0xa3,0xc2,0xa1,0xc1,0xe3,0xa2,0xe1,0xff,0xff }
687
if (table > 2) table = 2;
688
huff[0] = make_decoder ( first_tree[table]);
689
huff[1] = make_decoder (second_tree[table]);
693
Return 0 if the image starts with compressed data,
694
1 if it starts with uncompressed low-order bits.
696
In Canon compressed data, 0xff is always followed by 0x00.
698
int CLASS canon_has_lowbits()
703
fseek (ifp, 0, SEEK_SET);
704
fread (test, 1, sizeof test, ifp);
705
for (i=540; i < sizeof test - 1; i++)
706
if (test[i] == 0xff) {
707
if (test[i+1]) return 1;
713
void CLASS canon_compressed_load_raw()
715
ushort *pixel, *prow, *huff[2];
716
int nblocks, lowbits, i, c, row, r, col, save, val, nblack=0;
718
int block, diffbuf[64], leaf, len, diff, carry=0, pnum=0, base[2];
719
double dark[2] = { 0,0 };
721
crw_init_tables (tiff_compress, huff);
722
pixel = (ushort *) calloc (raw_width*8, sizeof *pixel);
723
merror (pixel, "canon_compressed_load_raw()");
724
lowbits = canon_has_lowbits();
725
if (!lowbits) maximum = 0x3ff;
726
fseek (ifp, 540 + lowbits*raw_height*raw_width/4, SEEK_SET);
729
for (row=0; row < raw_height; row+=8) {
730
nblocks = MIN (8, raw_height-row) * raw_width >> 6;
731
for (block=0; block < nblocks; block++) {
732
memset (diffbuf, 0, sizeof diffbuf);
733
for (i=0; i < 64; i++ ) {
734
leaf = gethuff(huff[i > 0]);
735
if (leaf == 0 && i) break;
736
if (leaf == 0xff) continue;
739
if (len == 0) continue;
741
if ((diff & (1 << (len-1))) == 0)
742
diff -= (1 << len) - 1;
743
if (i < 64) diffbuf[i] = diff;
747
for (i=0; i < 64; i++ ) {
748
if (pnum++ % raw_width == 0)
749
base[0] = base[1] = 512;
750
if ((pixel[(block << 6) + i] = base[i & 1] += diffbuf[i]) >> 10)
756
fseek (ifp, 26 + row*raw_width/4, SEEK_SET);
757
for (prow=pixel, i=0; i < raw_width*2; i++) {
759
for (r=0; r < 8; r+=2, prow++) {
760
val = (*prow << 2) + ((c >> r) & 3);
761
if (raw_width == 2672 && val < 512) val += 2;
765
fseek (ifp, save, SEEK_SET);
767
for (r=0; r < 8; r++) {
768
irow = row - top_margin + r;
769
if (irow >= height) continue;
770
for (col=0; col < raw_width; col++) {
771
icol = col - left_margin;
773
BAYER(irow,icol) = pixel[r*raw_width+col];
774
else if (col > 1 && (unsigned) (col-left_margin+2) > width+3)
775
dark[icol & 1] += (nblack++,pixel[r*raw_width+col]);
780
FORC(2) free (huff[c]);
781
canon_black (dark, nblack);
785
Not a full implementation of Lossless JPEG, just
786
enough to decode Canon, Kodak and Adobe DNG images.
789
int bits, high, wide, clrs, sraw, psv, restart, vpred[6];
790
ushort *huff[6], *free[4], *row;
793
int CLASS ljpeg_start (struct jhead *jh, int info_only)
799
memset (jh, 0, sizeof *jh);
800
jh->restart = INT_MAX;
801
fread (data, 2, 1, ifp);
802
if (data[1] != 0xd8) return 0;
804
fread (data, 2, 2, ifp);
805
tag = data[0] << 8 | data[1];
806
len = (data[2] << 8 | data[3]) - 2;
807
if (tag <= 0xff00) return 0;
808
fread (data, 1, len, ifp);
811
jh->sraw = ((data[7] >> 4) * (data[7] & 15) - 1) & 3;
814
jh->high = data[1] << 8 | data[2];
815
jh->wide = data[3] << 8 | data[4];
816
jh->clrs = data[5] + jh->sraw;
817
if (len == 9 && !dng_version) getc(ifp);
820
if (info_only) break;
821
for (dp = data; dp < data+len && (c = *dp++) < 4; )
822
jh->free[c] = jh->huff[c] = make_decoder_ref (&dp);
825
jh->psv = data[1+data[0]*2];
826
jh->bits -= data[3+data[0]*2] & 15;
829
jh->restart = data[0] << 8 | data[1];
831
} while (tag != 0xffda);
832
if (info_only) return 1;
833
FORC(5) if (!jh->huff[c+1]) jh->huff[c+1] = jh->huff[c];
835
FORC(4) jh->huff[2+c] = jh->huff[1];
836
FORC(jh->sraw) jh->huff[1+c] = jh->huff[0];
838
jh->row = (ushort *) calloc (jh->wide*jh->clrs, 4);
839
merror (jh->row, "ljpeg_start()");
840
return zero_after_ff = 1;
843
void CLASS ljpeg_end (struct jhead *jh)
846
FORC4 if (jh->free[c]) free (jh->free[c]);
850
int CLASS ljpeg_diff (ushort *huff)
855
if (len == 16 && (!dng_version || dng_version >= 0x1010000))
858
if ((diff & (1 << (len-1))) == 0)
859
diff -= (1 << len) - 1;
863
ushort * CLASS ljpeg_row (int jrow, struct jhead *jh)
865
int col, c, diff, pred, spred=0;
866
ushort mark=0, *row[3];
868
if (jrow * jh->wide % jh->restart == 0) {
869
FORC(6) jh->vpred[c] = 1 << (jh->bits-1);
871
fseek (ifp, -2, SEEK_CUR);
872
do mark = (mark << 8) + (c = fgetc(ifp));
873
while (c != EOF && mark >> 4 != 0xffd);
877
FORC3 row[c] = jh->row + jh->wide*jh->clrs*((jrow+c) & 1);
878
for (col=0; col < jh->wide; col++)
880
diff = ljpeg_diff (jh->huff[c]);
881
if (jh->sraw && c <= jh->sraw && (col | c))
883
else if (col) pred = row[0][-jh->clrs];
884
else pred = (jh->vpred[c] += diff) - diff;
885
if (jrow && col) switch (jh->psv) {
887
case 2: pred = row[1][0]; break;
888
case 3: pred = row[1][-jh->clrs]; break;
889
case 4: pred = pred + row[1][0] - row[1][-jh->clrs]; break;
890
case 5: pred = pred + ((row[1][0] - row[1][-jh->clrs]) >> 1); break;
891
case 6: pred = row[1][0] + ((pred - row[1][-jh->clrs]) >> 1); break;
892
case 7: pred = (pred + row[1][0]) >> 1; break;
895
if ((**row = pred + diff) >> jh->bits) derror();
896
if (c <= jh->sraw) spred = **row;
902
void CLASS lossless_jpeg_load_raw()
904
int jwide, jrow, jcol, val, jidx, i, j, row=0, col=0, nblack=0;
905
double dark[2] = { 0,0 };
910
if (!ljpeg_start (&jh, 0)) return;
911
jwide = jh.wide * jh.clrs;
913
for (jrow=0; jrow < jh.high; jrow++) {
914
rp = ljpeg_row (jrow, &jh);
915
for (jcol=0; jcol < jwide; jcol++) {
918
val = curve[val & 0xfff];
920
jidx = jrow*jwide + jcol;
921
i = jidx / (cr2_slice[1]*jh.high);
922
if ((j = i >= cr2_slice[0]))
924
jidx -= i * (cr2_slice[1]*jh.high);
925
row = jidx / cr2_slice[1+j];
926
col = jidx % cr2_slice[1+j] + i*cr2_slice[1];
928
if (raw_width == 3984 && (col -= 2) < 0)
929
col += (row--,raw_width);
930
if ((unsigned) (row-top_margin) < height) {
931
if ((unsigned) (col-left_margin) < width) {
932
BAYER(row-top_margin,col-left_margin) = val;
933
if (min > val) min = val;
934
} else if (col > 1 && (unsigned) (col-left_margin+2) > width+3)
935
dark[(col-left_margin) & 1] += (nblack++,val);
937
if (++col >= raw_width)
942
canon_black (dark, nblack);
943
if (!strcasecmp(make,"KODAK"))
947
void CLASS canon_sraw_load_raw()
950
short *rp=0, (*ip)[4];
951
int jwide, slice, scol, ecol, row, col, jrow=0, jcol=0, pix[3], c;
952
int v[3]={0,0,0}, ver, hue;
955
if (!ljpeg_start (&jh, 0)) return;
956
jwide = (jh.wide >>= 1) * jh.clrs;
958
for (ecol=slice=0; slice <= cr2_slice[0]; slice++) {
960
ecol += cr2_slice[1] * 2 / jh.clrs;
961
if (!cr2_slice[0] || ecol > raw_width-1) ecol = raw_width & -2;
962
for (row=0; row < height; row += (jh.clrs >> 1) - 1) {
963
ip = (short (*)[4]) image + row*width;
964
for (col=scol; col < ecol; col+=2, jcol+=jh.clrs) {
965
if ((jcol %= jwide) == 0)
966
rp = (short *) ljpeg_row (jrow++, &jh);
967
if (col >= width) continue;
969
ip[col + (c >> 1)*width + (c & 1)][0] = rp[jcol+c];
970
ip[col][1] = rp[jcol+jh.clrs-2] - 16384;
971
ip[col][2] = rp[jcol+jh.clrs-1] - 16384;
975
for (cp=model2; *cp && !isdigit(*cp); cp++);
976
sscanf (cp, "%d.%d.%d", v, v+1, v+2);
977
ver = (v[0]*1000 + v[1])*1000 + v[2];
978
hue = (jh.sraw+1) << 2;
979
if (unique_id == 0x80000218 && ver > 1000006 && ver < 3000000)
981
ip = (short (*)[4]) image;
983
for (row=0; row < height; row++, ip+=width) {
984
if (row & (jh.sraw >> 1))
985
for (col=0; col < width; col+=2)
986
for (c=1; c < 3; c++)
988
ip[col][c] = ip[col-width][c];
989
else ip[col][c] = (ip[col-width][c] + ip[col+width][c] + 1) >> 1;
990
for (col=1; col < width; col+=2)
991
for (c=1; c < 3; c++)
993
ip[col][c] = ip[col-1][c];
994
else ip[col][c] = (ip[col-1][c] + ip[col+1][c] + 1) >> 1;
996
for ( ; rp < ip[0]; rp+=4) {
997
if (unique_id < 0x80000218) {
998
pix[0] = rp[0] + rp[2] - 512;
999
pix[2] = rp[0] + rp[1] - 512;
1000
pix[1] = rp[0] + ((-778*rp[1] - (rp[2] << 11)) >> 12) - 512;
1002
rp[1] = (rp[1] << 2) + hue;
1003
rp[2] = (rp[2] << 2) + hue;
1004
pix[0] = rp[0] + (( 200*rp[1] + 22929*rp[2]) >> 14);
1005
pix[1] = rp[0] + ((-5640*rp[1] - 11751*rp[2]) >> 14);
1006
pix[2] = rp[0] + ((29040*rp[1] - 101*rp[2]) >> 14);
1008
FORC3 rp[c] = CLIP(pix[c] * sraw_mul[c] >> 10);
1014
void CLASS adobe_copy_pixel (int row, int col, ushort **rp)
1018
r = row -= top_margin;
1019
c = col -= left_margin;
1020
if (is_raw == 2 && shot_select) (*rp)++;
1023
r = row + fuji_width - 1 - (col >> 1);
1024
c = row + ((col+1) >> 1);
1026
if (r < height && c < width)
1027
BAYER(r,c) = **rp < 0x1000 ? curve[**rp] : **rp;
1030
if (r < height && c < width)
1032
image[row*width+col][c] = (*rp)[c] < 0x1000 ? curve[(*rp)[c]]:(*rp)[c];
1033
*rp += tiff_samples;
1035
if (is_raw == 2 && shot_select) (*rp)--;
1038
void CLASS adobe_dng_load_raw_lj()
1040
unsigned save, trow=0, tcol=0, jwide, jrow, jcol, row, col;
1044
while (trow < raw_height) {
1046
if (tile_length < INT_MAX)
1047
fseek (ifp, get4(), SEEK_SET);
1048
if (!ljpeg_start (&jh, 0)) break;
1050
if (filters) jwide *= jh.clrs;
1052
for (row=col=jrow=0; jrow < jh.high; jrow++) {
1053
rp = ljpeg_row (jrow, &jh);
1054
for (jcol=0; jcol < jwide; jcol++) {
1055
adobe_copy_pixel (trow+row, tcol+col, &rp);
1056
if (++col >= tile_width || col >= raw_width)
1057
row += 1 + (col = 0);
1060
fseek (ifp, save+4, SEEK_SET);
1061
if ((tcol += tile_width) >= raw_width)
1062
trow += tile_length + (tcol = 0);
1067
void CLASS adobe_dng_load_raw_nc()
1072
pixel = (ushort *) calloc (raw_width * tiff_samples, sizeof *pixel);
1073
merror (pixel, "adobe_dng_load_raw_nc()");
1074
for (row=0; row < raw_height; row++) {
1076
read_shorts (pixel, raw_width * tiff_samples);
1079
for (col=0; col < raw_width * tiff_samples; col++)
1080
pixel[col] = getbits(tiff_bps);
1082
for (rp=pixel, col=0; col < raw_width; col++)
1083
adobe_copy_pixel (row, col, &rp);
1088
void CLASS pentax_load_raw()
1090
ushort bit[2][13], huff[4097];
1091
int row, col, diff, c, i;
1092
ushort vpred[2][2] = {{0,0},{0,0}}, hpred[2];
1094
fseek (ifp, meta_offset, SEEK_SET);
1095
FORC(13) bit[0][c] = get2();
1096
FORC(13) bit[1][c] = fgetc(ifp);
1098
for (i=bit[0][c]; i <= ((bit[0][c]+(4096 >> bit[1][c])-1) & 4095); )
1099
huff[++i] = bit[1][c] << 8 | c;
1101
fseek (ifp, data_offset, SEEK_SET);
1103
for (row=0; row < raw_height; row++)
1104
for (col=0; col < raw_width; col++) {
1105
diff = ljpeg_diff (huff);
1106
if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
1107
else hpred[col & 1] += diff;
1108
if ((unsigned) (row-top_margin) < height && col < width)
1109
BAYER(row-top_margin,col) = hpred[col & 1];
1110
if (hpred[col & 1] >> 12) derror();
1114
void CLASS nikon_compressed_load_raw()
1116
static const uchar nikon_tree[][32] = {
1117
{ 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0, /* 12-bit lossy */
1118
5,4,3,6,2,7,1,0,8,9,11,10,12 },
1119
{ 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0, /* 12-bit lossy after split */
1120
0x39,0x5a,0x38,0x27,0x16,5,4,3,2,1,0,11,12,12 },
1121
{ 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0, /* 12-bit lossless */
1122
5,4,6,3,7,2,8,1,9,0,10,11,12 },
1123
{ 0,1,4,3,1,1,1,1,1,2,0,0,0,0,0,0, /* 14-bit lossy */
1124
5,6,4,7,8,3,9,2,1,0,10,11,12,13,14 },
1125
{ 0,1,5,1,1,1,1,1,1,1,2,0,0,0,0,0, /* 14-bit lossy after split */
1126
8,0x5c,0x4b,0x3a,0x29,7,6,5,4,3,2,1,0,13,14 },
1127
{ 0,1,4,2,2,3,1,2,0,0,0,0,0,0,0,0, /* 14-bit lossless */
1128
7,6,8,5,9,4,10,3,11,12,2,0,1,13,14 } };
1129
ushort *huff, ver0, ver1, vpred[2][2], hpred[2], csize;
1130
int i, min, max, step=0, tree=0, split=0, row, col, len, shl, diff;
1132
fseek (ifp, meta_offset, SEEK_SET);
1135
if (ver0 == 0x49 || ver1 == 0x58)
1136
fseek (ifp, 2110, SEEK_CUR);
1137
if (ver0 == 0x46) tree = 2;
1138
if (tiff_bps == 14) tree += 3;
1139
read_shorts (vpred[0], 4);
1140
max = 1 << tiff_bps & 0x7fff;
1141
if ((csize = get2()) > 1)
1142
step = max / (csize-1);
1143
if (ver0 == 0x44 && ver1 == 0x20 && step > 0) {
1144
for (i=0; i < csize; i++)
1145
curve[i*step] = get2();
1146
for (i=0; i < max; i++)
1147
curve[i] = ( curve[i-i%step]*(step-i%step) +
1148
curve[i-i%step+step]*(i%step) ) / step;
1149
fseek (ifp, meta_offset+562, SEEK_SET);
1151
} else if (ver0 != 0x46 && csize <= 0x4001)
1152
read_shorts (curve, max=csize);
1153
while (curve[max-2] == curve[max-1]) max--;
1154
huff = make_decoder (nikon_tree[tree]);
1155
fseek (ifp, data_offset, SEEK_SET);
1157
for (min=row=0; row < height; row++) {
1158
if (split && row == split) {
1160
huff = make_decoder (nikon_tree[tree+1]);
1161
max += (min = 16) << 1;
1163
for (col=0; col < raw_width; col++) {
1167
diff = ((getbits(len-shl) << 1) + 1) << shl >> 1;
1168
if ((diff & (1 << (len-1))) == 0)
1169
diff -= (1 << len) - !shl;
1170
if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
1171
else hpred[col & 1] += diff;
1172
if ((ushort)(hpred[col & 1] + min) >= max) derror();
1173
if ((unsigned) (col-left_margin) < width)
1174
BAYER(row,col-left_margin) = curve[LIM((short)hpred[col & 1],0,0x3fff)];
1181
Figure out if a NEF file is compressed. These fancy heuristics
1182
are only needed for the D100, thanks to a bug in some cameras
1183
that tags all images as "compressed".
1185
int CLASS nikon_is_compressed()
1190
fseek (ifp, data_offset, SEEK_SET);
1191
fread (test, 1, 256, ifp);
1192
for (i=15; i < 256; i+=16)
1193
if (test[i]) return 1;
1198
Returns 1 for a Coolpix 995, 0 for anything else.
1200
int CLASS nikon_e995()
1203
const uchar often[] = { 0x00, 0x55, 0xaa, 0xff };
1205
memset (histo, 0, sizeof histo);
1206
fseek (ifp, -2000, SEEK_END);
1207
for (i=0; i < 2000; i++)
1208
histo[fgetc(ifp)]++;
1209
for (i=0; i < 4; i++)
1210
if (histo[often[i]] < 200)
1216
Returns 1 for a Coolpix 2100, 0 for anything else.
1218
int CLASS nikon_e2100()
1223
fseek (ifp, 0, SEEK_SET);
1224
for (i=0; i < 1024; i++) {
1225
fread (t, 1, 12, ifp);
1226
if (((t[2] & t[4] & t[7] & t[9]) >> 4
1227
& t[1] & t[6] & t[8] & t[11] & 3) != 3)
1233
void CLASS nikon_3700()
1237
static const struct {
1239
char make[12], model[15];
1241
{ 0x00, "PENTAX", "Optio 33WR" },
1242
{ 0x03, "NIKON", "E3200" },
1243
{ 0x32, "NIKON", "E3700" },
1244
{ 0x33, "OLYMPUS", "C740UZ" } };
1246
fseek (ifp, 3072, SEEK_SET);
1247
fread (dp, 1, 24, ifp);
1248
bits = (dp[8] & 3) << 4 | (dp[20] & 3);
1249
for (i=0; i < sizeof table / sizeof *table; i++)
1250
if (bits == table[i].bits) {
1251
strcpy (make, table[i].make );
1252
strcpy (model, table[i].model);
1257
Separates a Minolta DiMAGE Z2 from a Nikon E4300.
1259
int CLASS minolta_z2()
1264
fseek (ifp, -sizeof tail, SEEK_END);
1265
fread (tail, 1, sizeof tail, ifp);
1266
for (nz=i=0; i < sizeof tail; i++)
1272
The Fuji Super CCD is just a Bayer grid rotated 45 degrees.
1274
void CLASS fuji_load_raw()
1277
int wide, row, col, r, c;
1279
fseek (ifp, (top_margin*raw_width + left_margin) * 2, SEEK_CUR);
1280
wide = fuji_width << !fuji_layout;
1281
pixel = (ushort *) calloc (wide, sizeof *pixel);
1282
merror (pixel, "fuji_load_raw()");
1283
for (row=0; row < raw_height; row++) {
1284
read_shorts (pixel, wide);
1285
fseek (ifp, 2*(raw_width - wide), SEEK_CUR);
1286
for (col=0; col < wide; col++) {
1288
r = fuji_width - 1 - col + (row >> 1);
1289
c = col + ((row+1) >> 1);
1291
r = fuji_width - 1 + row - (col >> 1);
1292
c = row + ((col+1) >> 1);
1294
BAYER(r,c) = pixel[col];
1300
void CLASS jpeg_thumb();
1302
void CLASS ppm_thumb()
1305
thumb_length = thumb_width*thumb_height*3;
1306
thumb = (char *) malloc (thumb_length);
1307
merror (thumb, "ppm_thumb()");
1308
fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
1309
fread (thumb, 1, thumb_length, ifp);
1310
fwrite (thumb, 1, thumb_length, ofp);
1314
void CLASS layer_thumb()
1317
char *thumb, map[][4] = { "012","102" };
1319
colors = thumb_misc >> 5 & 7;
1320
thumb_length = thumb_width*thumb_height;
1321
thumb = (char *) calloc (colors, thumb_length);
1322
merror (thumb, "layer_thumb()");
1323
fprintf (ofp, "P%d\n%d %d\n255\n",
1324
5 + (colors >> 1), thumb_width, thumb_height);
1325
fread (thumb, thumb_length, colors, ifp);
1326
for (i=0; i < thumb_length; i++)
1327
FORCC putc (thumb[i+thumb_length*(map[thumb_misc >> 8][c]-'0')], ofp);
1331
void CLASS rollei_thumb()
1336
thumb_length = thumb_width * thumb_height;
1337
thumb = (ushort *) calloc (thumb_length, 2);
1338
merror (thumb, "rollei_thumb()");
1339
fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
1340
read_shorts (thumb, thumb_length);
1341
for (i=0; i < thumb_length; i++) {
1342
putc (thumb[i] << 3, ofp);
1343
putc (thumb[i] >> 5 << 2, ofp);
1344
putc (thumb[i] >> 11 << 3, ofp);
1349
void CLASS rollei_load_raw()
1352
unsigned iten=0, isix, i, buffer=0, row, col, todo[16];
1354
isix = raw_width * raw_height * 5 / 8;
1355
while (fread (pixel, 1, 10, ifp) == 10) {
1356
for (i=0; i < 10; i+=2) {
1358
todo[i+1] = pixel[i] << 8 | pixel[i+1];
1359
buffer = pixel[i] >> 2 | buffer << 6;
1361
for ( ; i < 16; i+=2) {
1363
todo[i+1] = buffer >> (14-i)*5;
1365
for (i=0; i < 16; i+=2) {
1366
row = todo[i] / raw_width - top_margin;
1367
col = todo[i] % raw_width - left_margin;
1368
if (row < height && col < width)
1369
BAYER(row,col) = (todo[i+1] & 0x3ff);
1375
int CLASS bayer (unsigned row, unsigned col)
1377
return (row < height && col < width) ? BAYER(row,col) : 0;
1380
void CLASS phase_one_flat_field (int is_float, int nc)
1383
unsigned wide, y, x, c, rend, cend, row, col;
1384
float *mrow, num, mult[4];
1386
read_shorts (head, 8);
1387
wide = head[2] / head[4];
1388
mrow = (float *) calloc (nc*wide, sizeof *mrow);
1389
merror (mrow, "phase_one_flat_field()");
1390
for (y=0; y < head[3] / head[5]; y++) {
1391
for (x=0; x < wide; x++)
1392
for (c=0; c < nc; c+=2) {
1393
num = is_float ? getreal(11) : get2()/32768.0;
1394
if (y==0) mrow[c*wide+x] = num;
1395
else mrow[(c+1)*wide+x] = (num - mrow[c*wide+x]) / head[5];
1398
rend = head[1]-top_margin + y*head[5];
1399
for (row = rend-head[5]; row < height && row < rend; row++) {
1400
for (x=1; x < wide; x++) {
1401
for (c=0; c < nc; c+=2) {
1402
mult[c] = mrow[c*wide+x-1];
1403
mult[c+1] = (mrow[c*wide+x] - mult[c]) / head[4];
1405
cend = head[0]-left_margin + x*head[4];
1406
for (col = cend-head[4]; col < width && col < cend; col++) {
1407
c = nc > 2 ? FC(row,col) : 0;
1409
c = BAYER(row,col) * mult[c];
1410
BAYER(row,col) = LIM(c,0,65535);
1412
for (c=0; c < nc; c+=2)
1413
mult[c] += mult[c+1];
1416
for (x=0; x < wide; x++)
1417
for (c=0; c < nc; c+=2)
1418
mrow[c*wide+x] += mrow[(c+1)*wide+x];
1424
void CLASS phase_one_correct()
1426
unsigned entries, tag, data, save, col, row, type;
1427
int len, i, j, k, cip, val[4], dev[4], sum, max;
1428
int head[9], diff, mindiff=INT_MAX, off_412=0;
1429
static const signed char dir[12][2] =
1430
{ {-1,-1}, {-1,1}, {1,-1}, {1,1}, {-2,0}, {0,-2}, {0,2}, {2,0},
1431
{-2,-2}, {-2,2}, {2,-2}, {2,2} };
1432
float poly[8], num, cfrac, frac, mult[2], *yval[2];
1435
if (half_size || !meta_length) return;
1436
if (verbose) fprintf (stderr,_("Phase One correction...\n"));
1437
fseek (ifp, meta_offset, SEEK_SET);
1439
fseek (ifp, 6, SEEK_CUR);
1440
fseek (ifp, meta_offset+get4(), SEEK_SET);
1441
entries = get4(); get4();
1447
fseek (ifp, meta_offset+data, SEEK_SET);
1448
if (tag == 0x419) { /* Polynomial curve */
1449
for (get4(), i=0; i < 8; i++)
1450
poly[i] = getreal(11);
1451
poly[3] += (ph1.tag_210 - poly[7]) * poly[6] + 1;
1452
for (i=0; i < 0x10000; i++) {
1453
num = (poly[5]*i + poly[3])*i + poly[1];
1454
curve[i] = LIM(num,0,65535);
1455
} goto apply; /* apply to right half */
1456
} else if (tag == 0x41a) { /* Polynomial curve */
1457
for (i=0; i < 4; i++)
1458
poly[i] = getreal(11);
1459
for (i=0; i < 0x10000; i++) {
1460
for (num=0, j=4; j--; )
1461
num = num * i + poly[j];
1462
curve[i] = LIM(num+i,0,65535);
1463
} apply: /* apply to whole image */
1464
for (row=0; row < height; row++)
1465
for (col = (tag & 1)*ph1.split_col; col < width; col++)
1466
BAYER(row,col) = curve[BAYER(row,col)];
1467
} else if (tag == 0x400) { /* Sensor defects */
1468
while ((len -= 8) >= 0) {
1469
col = get2() - left_margin;
1470
row = get2() - top_margin;
1471
type = get2(); get2();
1472
if (col >= width) continue;
1473
if (type == 131) /* Bad column */
1474
for (row=0; row < height; row++)
1475
if (FC(row,col) == 1) {
1476
for (sum=i=0; i < 4; i++)
1477
sum += val[i] = bayer (row+dir[i][0], col+dir[i][1]);
1478
for (max=i=0; i < 4; i++) {
1479
dev[i] = abs((val[i] << 2) - sum);
1480
if (dev[max] < dev[i]) max = i;
1482
BAYER(row,col) = (sum - val[max])/3.0 + 0.5;
1484
for (sum=0, i=8; i < 12; i++)
1485
sum += bayer (row+dir[i][0], col+dir[i][1]);
1486
BAYER(row,col) = 0.5 + sum * 0.0732233 +
1487
(bayer(row,col-2) + bayer(row,col+2)) * 0.3535534;
1489
else if (type == 129) { /* Bad pixel */
1490
if (row >= height) continue;
1491
j = (FC(row,col) != 1) * 4;
1492
for (sum=0, i=j; i < j+8; i++)
1493
sum += bayer (row+dir[i][0], col+dir[i][1]);
1494
BAYER(row,col) = (sum + 4) >> 3;
1497
} else if (tag == 0x401) { /* All-color flat fields */
1498
phase_one_flat_field (1, 2);
1499
} else if (tag == 0x416 || tag == 0x410) {
1500
phase_one_flat_field (0, 2);
1501
} else if (tag == 0x40b) { /* Red+blue flat field */
1502
phase_one_flat_field (0, 4);
1503
} else if (tag == 0x412) {
1504
fseek (ifp, 36, SEEK_CUR);
1505
diff = abs (get2() - ph1.tag_21a);
1506
if (mindiff > diff) {
1508
off_412 = ftell(ifp) - 38;
1511
fseek (ifp, save, SEEK_SET);
1514
fseek (ifp, off_412, SEEK_SET);
1515
for (i=0; i < 9; i++) head[i] = get4() & 0x7fff;
1516
yval[0] = (float *) calloc (head[1]*head[3] + head[2]*head[4], 6);
1517
merror (yval[0], "phase_one_correct()");
1518
yval[1] = (float *) (yval[0] + head[1]*head[3]);
1519
xval[0] = (ushort *) (yval[1] + head[2]*head[4]);
1520
xval[1] = (ushort *) (xval[0] + head[1]*head[3]);
1522
for (i=0; i < 2; i++)
1523
for (j=0; j < head[i+1]*head[i+3]; j++)
1524
yval[i][j] = getreal(11);
1525
for (i=0; i < 2; i++)
1526
for (j=0; j < head[i+1]*head[i+3]; j++)
1527
xval[i][j] = get2();
1528
for (row=0; row < height; row++)
1529
for (col=0; col < width; col++) {
1530
cfrac = (float) col * head[3] / raw_width;
1531
cfrac -= cip = cfrac;
1532
num = BAYER(row,col) * 0.5;
1533
for (i=cip; i < cip+2; i++) {
1534
for (k=j=0; j < head[1]; j++)
1535
if (num < xval[0][k = head[1]*i+j]) break;
1536
frac = (j == 0 || j == head[1]) ? 0 :
1537
(xval[0][k] - num) / (xval[0][k] - xval[0][k-1]);
1538
mult[i-cip] = yval[0][k-1] * frac + yval[0][k] * (1-frac);
1540
i = ((mult[0] * (1-cfrac) + mult[1] * cfrac)
1541
* (row + top_margin) + num) * 2;
1542
BAYER(row,col) = LIM(i,0,65535);
1548
void CLASS phase_one_load_raw()
1551
ushort *pixel, akey, bkey, mask;
1553
fseek (ifp, ph1.key_off, SEEK_SET);
1556
mask = ph1.format == 1 ? 0x5555:0x1354;
1557
fseek (ifp, data_offset + top_margin*raw_width*2, SEEK_SET);
1558
pixel = (ushort *) calloc (raw_width, sizeof *pixel);
1559
merror (pixel, "phase_one_load_raw()");
1560
for (row=0; row < height; row++) {
1561
read_shorts (pixel, raw_width);
1562
for (col=0; col < raw_width; col+=2) {
1563
a = pixel[col+0] ^ akey;
1564
b = pixel[col+1] ^ bkey;
1565
pixel[col+0] = (a & mask) | (b & ~mask);
1566
pixel[col+1] = (b & mask) | (a & ~mask);
1568
for (col=0; col < width; col++)
1569
BAYER(row,col) = pixel[col+left_margin];
1572
phase_one_correct();
1575
unsigned CLASS ph1_bithuff (int nbits, ushort *huff)
1577
static UINT64 bitbuf=0;
1582
return bitbuf = vbits = 0;
1583
if (nbits == 0) return 0;
1584
if (vbits < nbits) {
1585
bitbuf = bitbuf << 32 | get4();
1588
c = bitbuf << (64-vbits) >> (64-nbits);
1590
vbits -= huff[c] >> 8;
1591
return (uchar) huff[c];
1596
#define ph1_bits(n) ph1_bithuff(n,0)
1597
#define ph1_huff(h) ph1_bithuff(*h,h+1)
1599
void CLASS phase_one_load_raw_c()
1601
static const int length[] = { 8,7,6,9,11,10,5,12,14,13 };
1602
int *offset, len[2], pred[2], row, col, i, j;
1606
pixel = (ushort *) calloc (raw_width + raw_height*4, 2);
1607
merror (pixel, "phase_one_load_raw_c()");
1608
offset = (int *) (pixel + raw_width);
1609
fseek (ifp, strip_offset, SEEK_SET);
1610
for (row=0; row < raw_height; row++)
1611
offset[row] = get4();
1612
black = (short (*)[2]) offset + raw_height;
1613
fseek (ifp, ph1.black_off, SEEK_SET);
1615
read_shorts ((ushort *) black[0], raw_height*2);
1616
for (i=0; i < 256; i++)
1617
curve[i] = i*i / 3.969 + 0.5;
1618
for (row=0; row < raw_height; row++) {
1619
fseek (ifp, data_offset + offset[row], SEEK_SET);
1621
pred[0] = pred[1] = 0;
1622
for (col=0; col < raw_width; col++) {
1623
if (col >= (raw_width & -8))
1624
len[0] = len[1] = 14;
1625
else if ((col & 7) == 0)
1626
for (i=0; i < 2; i++) {
1627
for (j=0; j < 5 && !ph1_bits(1); j++);
1628
if (j--) len[i] = length[j*2 + ph1_bits(1)];
1630
if ((i = len[col & 1]) == 14)
1631
pixel[col] = pred[col & 1] = ph1_bits(16);
1633
pixel[col] = pred[col & 1] += ph1_bits(i) + 1 - (1 << (i - 1));
1634
if (pred[col & 1] >> 16) derror();
1635
if (ph1.format == 5 && pixel[col] < 256)
1636
pixel[col] = curve[pixel[col]];
1638
if ((unsigned) (row-top_margin) < height)
1639
for (col=0; col < width; col++) {
1640
i = (pixel[col+left_margin] << 2)
1641
- ph1.black + black[row][col >= ph1.split_col];
1642
if (i > 0) BAYER(row-top_margin,col) = i;
1646
phase_one_correct();
1647
maximum = 0xfffc - ph1.black;
1650
void CLASS hasselblad_load_raw()
1653
int row, col, pred[2], len[2], diff, c;
1655
if (!ljpeg_start (&jh, 0)) return;
1658
for (row=-top_margin; row < height; row++) {
1659
pred[0] = pred[1] = 0x8000;
1660
for (col=-left_margin; col < raw_width-left_margin; col+=2) {
1661
FORC(2) len[c] = ph1_huff(jh.huff[0]);
1663
diff = ph1_bits(len[c]);
1664
if ((diff & (1 << (len[c]-1))) == 0)
1665
diff -= (1 << len[c]) - 1;
1666
if (diff == 65535) diff = -32768;
1668
if (row >= 0 && (unsigned)(col+c) < width)
1669
BAYER(row,col+c) = pred[c];
1677
void CLASS leaf_hdr_load_raw()
1680
unsigned tile=0, r, c, row, col;
1682
pixel = (ushort *) calloc (raw_width, sizeof *pixel);
1683
merror (pixel, "leaf_hdr_load_raw()");
1685
for (r=0; r < raw_height; r++) {
1686
if (r % tile_length == 0) {
1687
fseek (ifp, data_offset + 4*tile++, SEEK_SET);
1688
fseek (ifp, get4() + 2*left_margin, SEEK_SET);
1690
if (filters && c != shot_select) continue;
1691
read_shorts (pixel, raw_width);
1692
if ((row = r - top_margin) >= height) continue;
1693
for (col=0; col < width; col++)
1694
if (filters) BAYER(row,col) = pixel[col];
1695
else image[row*width+col][c] = pixel[col];
1704
void CLASS unpacked_load_raw();
1706
void CLASS sinar_4shot_load_raw()
1709
unsigned shot, row, col, r, c;
1711
if ((shot = shot_select) || half_size) {
1713
if (shot > 3) shot = 3;
1714
fseek (ifp, data_offset + shot*4, SEEK_SET);
1715
fseek (ifp, get4(), SEEK_SET);
1716
unpacked_load_raw();
1720
image = (ushort (*)[4])
1721
calloc ((iheight=height)*(iwidth=width), sizeof *image);
1722
merror (image, "sinar_4shot_load_raw()");
1723
pixel = (ushort *) calloc (raw_width, sizeof *pixel);
1724
merror (pixel, "sinar_4shot_load_raw()");
1725
for (shot=0; shot < 4; shot++) {
1726
fseek (ifp, data_offset + shot*4, SEEK_SET);
1727
fseek (ifp, get4(), SEEK_SET);
1728
for (row=0; row < raw_height; row++) {
1729
read_shorts (pixel, raw_width);
1730
if ((r = row-top_margin - (shot >> 1 & 1)) >= height) continue;
1731
for (col=0; col < raw_width; col++) {
1732
if ((c = col-left_margin - (shot & 1)) >= width) continue;
1733
image[r*width+c][FC(row,col)] = pixel[col];
1738
shrink = filters = 0;
1741
void CLASS imacon_full_load_raw()
1745
for (row=0; row < height; row++)
1746
for (col=0; col < width; col++)
1747
read_shorts (image[row*width+col], 3);
1750
void CLASS packed_load_raw()
1752
int vbits=0, bwide, pwide, rbits, bite, half, irow, row, col, val, i;
1755
if (raw_width * 8 >= width * tiff_bps) /* Is raw_width in bytes? */
1756
pwide = (bwide = raw_width) * 8 / tiff_bps;
1757
else bwide = (pwide = raw_width) * tiff_bps / 8;
1758
rbits = bwide * 8 - pwide * tiff_bps;
1759
if (load_flags & 1) bwide = bwide * 16 / 15;
1760
fseek (ifp, top_margin*bwide, SEEK_CUR);
1761
bite = 8 + (load_flags & 24);
1762
half = (height+1) >> 1;
1763
for (irow=0; irow < height; irow++) {
1765
if (load_flags & 2 &&
1766
(row = irow % half * 2 + irow / half) == 1 &&
1768
if (vbits=0, tiff_compress)
1769
fseek (ifp, data_offset - (-half*bwide & -2048), SEEK_SET);
1771
fseek (ifp, 0, SEEK_END);
1772
fseek (ifp, ftell(ifp) >> 3 << 2, SEEK_SET);
1775
for (col=0; col < pwide; col++) {
1776
for (vbits -= tiff_bps; vbits < 0; vbits += bite) {
1778
for (i=0; i < bite; i+=8)
1779
bitbuf |= (unsigned) (fgetc(ifp) << i);
1781
val = bitbuf << (64-tiff_bps-vbits) >> (64-tiff_bps);
1782
i = (col ^ (bite == 24)) - left_margin;
1783
if ((unsigned) i < width)
1784
BAYER(row,i) = val << (load_flags >> 6);
1785
else if (load_flags & 32)
1787
if (load_flags & 1 && (col % 10) == 9 &&
1788
fgetc(ifp) && col < width+left_margin) derror();
1792
if (load_flags & 32 && pwide > width)
1793
black /= (pwide - width) * height;
1796
void CLASS unpacked_load_raw()
1799
int row, col, bits=0;
1801
while (1 << ++bits < maximum);
1802
fseek (ifp, (top_margin*raw_width + left_margin) * 2, SEEK_CUR);
1803
pixel = (ushort *) calloc (width, sizeof *pixel);
1804
merror (pixel, "unpacked_load_raw()");
1805
for (row=0; row < height; row++) {
1806
read_shorts (pixel, width);
1807
fseek (ifp, 2*(raw_width - width), SEEK_CUR);
1808
for (col=0; col < width; col++)
1809
if ((BAYER2(row,col) = pixel[col]) >> bits) derror();
1814
void CLASS nokia_load_raw()
1817
ushort *pixel, *pix;
1820
dwide = raw_width * 5 / 4;
1821
data = (uchar *) malloc (dwide + raw_width*2);
1822
merror (data, "nokia_load_raw()");
1823
pixel = (ushort *) (data + dwide);
1824
for (row=0; row < raw_height; row++) {
1825
if (fread (data, 1, dwide, ifp) < dwide) derror();
1826
for (dp=data, pix=pixel; pix < pixel+raw_width; dp+=5, pix+=4)
1827
FORC4 pix[c] = (dp[c] << 2) | (dp[4] >> (c << 1) & 3);
1828
if (row < top_margin)
1829
FORC(width) black += pixel[c];
1831
FORC(width) BAYER(row-top_margin,c) = pixel[c];
1834
if (top_margin) black /= top_margin * width;
1838
unsigned CLASS pana_bits (int nbits)
1840
static uchar buf[0x4000];
1844
if (!nbits) return vbits=0;
1846
fread (buf+load_flags, 1, 0x4000-load_flags, ifp);
1847
fread (buf, 1, load_flags, ifp);
1849
vbits = (vbits - nbits) & 0x1ffff;
1850
byte = vbits >> 3 ^ 0x3ff0;
1851
return (buf[byte] | buf[byte+1] << 8) >> (vbits & 7) & ~(-1 << nbits);
1854
void CLASS panasonic_load_raw()
1856
int row, col, i, j, sh=0, pred[2], nonz[2];
1859
for (row=0; row < height; row++)
1860
for (col=0; col < raw_width; col++) {
1861
if ((i = col % 14) == 0)
1862
pred[0] = pred[1] = nonz[0] = nonz[1] = 0;
1863
if (i % 3 == 2) sh = 4 >> (3 - pana_bits(2));
1865
if ((j = pana_bits(8))) {
1866
if ((pred[i & 1] -= 0x80 << sh) < 0 || sh == 4)
1867
pred[i & 1] &= ~(-1 << sh);
1868
pred[i & 1] += j << sh;
1870
} else if ((nonz[i & 1] = pana_bits(8)) || i > 11)
1871
pred[i & 1] = nonz[i & 1] << 4 | pana_bits(4);
1873
if ((BAYER(row,col) = pred[col & 1]) > 4098) derror();
1877
void CLASS olympus_load_raw()
1880
int row, col, nbits, sign, low, high, i, c, w, n, nw;
1881
int acarry[2][3], *carry, pred, diff;
1885
FORC(2048 >> i) huff[++n] = (i+1) << 8 | i;
1886
fseek (ifp, 7, SEEK_CUR);
1888
for (row=0; row < height; row++) {
1889
memset (acarry, 0, sizeof acarry);
1890
for (col=0; col < raw_width; col++) {
1891
carry = acarry[col & 1];
1892
i = 2 * (carry[2] < 3);
1893
for (nbits=2+i; (ushort) carry[0] >> (nbits+i); nbits++);
1894
low = (sign = getbits(3)) & 3;
1895
sign = sign << 29 >> 31;
1896
if ((high = getbithuff(12,huff)) == 12)
1897
high = getbits(16-nbits) >> 1;
1898
carry[0] = (high << nbits) | getbits(nbits);
1899
diff = (carry[0] ^ sign) + carry[1];
1900
carry[1] = (diff*3 + carry[1]) >> 5;
1901
carry[2] = carry[0] > 16 ? 0 : carry[2]+1;
1902
if (col >= width) continue;
1903
if (row < 2 && col < 2) pred = 0;
1904
else if (row < 2) pred = BAYER(row,col-2);
1905
else if (col < 2) pred = BAYER(row-2,col);
1907
w = BAYER(row,col-2);
1908
n = BAYER(row-2,col);
1909
nw = BAYER(row-2,col-2);
1910
if ((w < nw && nw < n) || (n < nw && nw < w)) {
1911
if (ABS(w-nw) > 32 || ABS(n-nw) > 32)
1913
else pred = (w + n) >> 1;
1914
} else pred = ABS(w-nw) > ABS(n-nw) ? w : n;
1916
if ((BAYER(row,col) = pred + ((diff << 2) | low)) >> 12) derror();
1921
void CLASS minolta_rd175_load_raw()
1924
unsigned irow, box, row, col;
1926
for (irow=0; irow < 1481; irow++) {
1927
if (fread (pixel, 1, 768, ifp) < 768) derror();
1929
row = irow % 82 * 12 + ((box < 12) ? box | 1 : (box-12)*2);
1931
case 1477: case 1479: continue;
1932
case 1476: row = 984; break;
1933
case 1480: row = 985; break;
1934
case 1478: row = 985; box = 1;
1936
if ((box < 12) && (box & 1)) {
1937
for (col=0; col < 1533; col++, row ^= 1)
1938
if (col != 1) BAYER(row,col) = (col+1) & 2 ?
1939
pixel[col/2-1] + pixel[col/2+1] : pixel[col/2] << 1;
1940
BAYER(row,1) = pixel[1] << 1;
1941
BAYER(row,1533) = pixel[765] << 1;
1943
for (col=row & 1; col < 1534; col+=2)
1944
BAYER(row,col) = pixel[col/2] << 1;
1946
maximum = 0xff << 1;
1949
void CLASS quicktake_100_load_raw()
1951
uchar pixel[484][644];
1952
static const short gstep[16] =
1953
{ -89,-60,-44,-32,-22,-15,-8,-2,2,8,15,22,32,44,60,89 };
1954
static const short rstep[6][4] =
1955
{ { -3,-1,1,3 }, { -5,-1,1,5 }, { -8,-2,2,8 },
1956
{ -13,-3,3,13 }, { -19,-4,4,19 }, { -28,-6,6,28 } };
1957
static const short curve[256] =
1958
{ 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,
1959
28,29,30,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,53,
1960
54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,74,75,76,77,78,
1961
79,80,81,82,83,84,86,88,90,92,94,97,99,101,103,105,107,110,112,114,116,
1962
118,120,123,125,127,129,131,134,136,138,140,142,144,147,149,151,153,155,
1963
158,160,162,164,166,168,171,173,175,177,179,181,184,186,188,190,192,195,
1964
197,199,201,203,205,208,210,212,214,216,218,221,223,226,230,235,239,244,
1965
248,252,257,261,265,270,274,278,283,287,291,296,300,305,309,313,318,322,
1966
326,331,335,339,344,348,352,357,361,365,370,374,379,383,387,392,396,400,
1967
405,409,413,418,422,426,431,435,440,444,448,453,457,461,466,470,474,479,
1968
483,487,492,496,500,508,519,531,542,553,564,575,587,598,609,620,631,643,
1969
654,665,676,687,698,710,721,732,743,754,766,777,788,799,810,822,833,844,
1970
855,866,878,889,900,911,922,933,945,956,967,978,989,1001,1012,1023 };
1971
int rb, row, col, sharp, val=0;
1974
memset (pixel, 0x80, sizeof pixel);
1975
for (row=2; row < height+2; row++) {
1976
for (col=2+(row & 1); col < width+2; col+=2) {
1977
val = ((pixel[row-1][col-1] + 2*pixel[row-1][col+1] +
1978
pixel[row][col-2]) >> 2) + gstep[getbits(4)];
1979
pixel[row][col] = val = LIM(val,0,255);
1981
pixel[row][col-2] = pixel[row+1][~row & 1] = val;
1983
pixel[row-1][col+1] = pixel[row-1][col+3] = val;
1985
pixel[row][col] = val;
1987
for (rb=0; rb < 2; rb++)
1988
for (row=2+rb; row < height+2; row+=2)
1989
for (col=3-(row & 1); col < width+2; col+=2) {
1990
if (row < 4 || col < 4) sharp = 2;
1992
val = ABS(pixel[row-2][col] - pixel[row][col-2])
1993
+ ABS(pixel[row-2][col] - pixel[row-2][col-2])
1994
+ ABS(pixel[row][col-2] - pixel[row-2][col-2]);
1995
sharp = val < 4 ? 0 : val < 8 ? 1 : val < 16 ? 2 :
1996
val < 32 ? 3 : val < 48 ? 4 : 5;
1998
val = ((pixel[row-2][col] + pixel[row][col-2]) >> 1)
1999
+ rstep[sharp][getbits(2)];
2000
pixel[row][col] = val = LIM(val,0,255);
2001
if (row < 4) pixel[row-2][col+2] = val;
2002
if (col < 4) pixel[row+2][col-2] = val;
2004
for (row=2; row < height+2; row++)
2005
for (col=3-(row & 1); col < width+2; col+=2) {
2006
val = ((pixel[row][col-1] + (pixel[row][col] << 2) +
2007
pixel[row][col+1]) >> 1) - 0x100;
2008
pixel[row][col] = LIM(val,0,255);
2010
for (row=0; row < height; row++)
2011
for (col=0; col < width; col++)
2012
BAYER(row,col) = curve[pixel[row+2][col+2]];
2016
#define radc_token(tree) ((signed char) getbithuff(8,huff[tree]))
2018
#define FORYX for (y=1; y < 3; y++) for (x=col+1; x >= col; x--)
2020
#define PREDICTOR (c ? (buf[c][y-1][x] + buf[c][y][x+1]) / 2 \
2021
: (buf[c][y-1][x+1] + 2*buf[c][y-1][x] + buf[c][y][x+1]) / 4)
2023
void CLASS kodak_radc_load_raw()
2025
static const char src[] = {
2026
1,1, 2,3, 3,4, 4,2, 5,7, 6,5, 7,6, 7,8,
2027
1,0, 2,1, 3,3, 4,4, 5,2, 6,7, 7,6, 8,5, 8,8,
2028
2,1, 2,3, 3,0, 3,2, 3,4, 4,6, 5,5, 6,7, 6,8,
2029
2,0, 2,1, 2,3, 3,2, 4,4, 5,6, 6,7, 7,5, 7,8,
2030
2,1, 2,4, 3,0, 3,2, 3,3, 4,7, 5,5, 6,6, 6,8,
2031
2,3, 3,1, 3,2, 3,4, 3,5, 3,6, 4,7, 5,0, 5,8,
2032
2,3, 2,6, 3,0, 3,1, 4,4, 4,5, 4,7, 5,2, 5,8,
2033
2,4, 2,7, 3,3, 3,6, 4,1, 4,2, 4,5, 5,0, 5,8,
2034
2,6, 3,1, 3,3, 3,5, 3,7, 3,8, 4,0, 5,2, 5,4,
2035
2,0, 2,1, 3,2, 3,3, 4,4, 4,5, 5,6, 5,7, 4,8,
2038
2,-17, 2,-5, 2,5, 2,17,
2039
2,-7, 2,2, 2,9, 2,18,
2040
2,-18, 2,-9, 2,-2, 2,7,
2041
2,-28, 2,28, 3,-49, 3,-9, 3,9, 4,49, 5,-79, 5,79,
2042
2,-1, 2,13, 2,26, 3,39, 4,-16, 5,55, 6,-37, 6,76,
2043
2,-26, 2,-13, 2,1, 3,-39, 4,16, 5,-55, 6,-76, 6,37
2045
ushort huff[19][256];
2046
int row, col, tree, nreps, rep, step, i, c, s, r, x, y, val;
2047
short last[3] = { 16,16,16 }, mul[3], buf[3][3][386];
2048
static const ushort pt[] =
2049
{ 0,0, 1280,1344, 2320,3616, 3328,8000, 4095,16383, 65535,16383 };
2051
for (i=2; i < 12; i+=2)
2052
for (c=pt[i-2]; c <= pt[i]; c++)
2054
(c-pt[i-2]) / (pt[i]-pt[i-2]) * (pt[i+1]-pt[i-1]) + pt[i-1] + 0.5;
2055
for (s=i=0; i < sizeof src; i+=2)
2057
huff[0][s++] = src[i] << 8 | (uchar) src[i+1];
2058
s = kodak_cbpp == 243 ? 2 : 3;
2059
FORC(256) huff[18][c] = (8-s) << 8 | c >> s << s | 1 << (s-1);
2061
for (i=0; i < sizeof(buf)/sizeof(short); i++)
2062
buf[0][0][i] = 2048;
2063
for (row=0; row < height; row+=4) {
2064
FORC3 mul[c] = getbits(6);
2066
val = ((0x1000000/last[c] + 0x7ff) >> 12) * mul[c];
2067
s = val > 65564 ? 10:12;
2070
for (i=0; i < sizeof(buf[0])/sizeof(short); i++)
2071
buf[c][0][i] = (buf[c][0][i] * val + x) >> s;
2073
for (r=0; r <= !c; r++) {
2074
buf[c][1][width/2] = buf[c][2][width/2] = mul[c] << 7;
2075
for (tree=1, col=width/2; col > 0; ) {
2076
if ((tree = radc_token(tree))) {
2079
FORYX buf[c][y][x] = (uchar) radc_token(18) * mul[c];
2081
FORYX buf[c][y][x] = radc_token(tree+10) * 16 + PREDICTOR;
2084
nreps = (col > 2) ? radc_token(9) + 1 : 1;
2085
for (rep=0; rep < 8 && rep < nreps && col > 0; rep++) {
2087
FORYX buf[c][y][x] = PREDICTOR;
2089
step = radc_token(10) << 4;
2090
FORYX buf[c][y][x] += step;
2093
} while (nreps == 9);
2095
for (y=0; y < 2; y++)
2096
for (x=0; x < width/2; x++) {
2097
val = (buf[c][y+1][x] << 4) / mul[c];
2098
if (val < 0) val = 0;
2099
if (c) BAYER(row+y*2+c-1,x*2+2-c) = val;
2100
else BAYER(row+r*2+y,x*2+y) = val;
2102
memcpy (buf[c][0]+!c, buf[c][2], sizeof buf[c][0]-2*!c);
2105
for (y=row; y < row+4; y++)
2106
for (x=0; x < width; x++)
2109
s = x+1 < width ? x+1 : x-1;
2110
val = (BAYER(y,x)-2048)*2 + (BAYER(y,r)+BAYER(y,s))/2;
2111
if (val < 0) val = 0;
2115
for (i=0; i < iheight*iwidth*4; i++)
2116
image[0][i] = curve[image[0][i]];
2124
void CLASS kodak_jpeg_load_raw() {}
2128
fill_input_buffer (j_decompress_ptr cinfo)
2130
static uchar jpeg_buffer[4096];
2133
nbytes = fread (jpeg_buffer, 1, 4096, ifp);
2134
swab (jpeg_buffer, jpeg_buffer, nbytes);
2135
cinfo->src->next_input_byte = jpeg_buffer;
2136
cinfo->src->bytes_in_buffer = nbytes;
2140
void CLASS kodak_jpeg_load_raw()
2142
struct jpeg_decompress_struct cinfo;
2143
struct jpeg_error_mgr jerr;
2145
JSAMPLE (*pixel)[3];
2148
cinfo.err = jpeg_std_error (&jerr);
2149
jpeg_create_decompress (&cinfo);
2150
jpeg_stdio_src (&cinfo, ifp);
2151
cinfo.src->fill_input_buffer = fill_input_buffer;
2152
jpeg_read_header (&cinfo, TRUE);
2153
jpeg_start_decompress (&cinfo);
2154
if ((cinfo.output_width != width ) ||
2155
(cinfo.output_height*2 != height ) ||
2156
(cinfo.output_components != 3 )) {
2157
fprintf (stderr,_("%s: incorrect JPEG dimensions\n"), ifname);
2158
jpeg_destroy_decompress (&cinfo);
2159
longjmp (failure, 3);
2161
buf = (*cinfo.mem->alloc_sarray)
2162
((j_common_ptr) &cinfo, JPOOL_IMAGE, width*3, 1);
2164
while (cinfo.output_scanline < cinfo.output_height) {
2165
row = cinfo.output_scanline * 2;
2166
jpeg_read_scanlines (&cinfo, buf, 1);
2167
pixel = (JSAMPLE (*)[3]) buf[0];
2168
for (col=0; col < width; col+=2) {
2169
BAYER(row+0,col+0) = pixel[col+0][1] << 1;
2170
BAYER(row+1,col+1) = pixel[col+1][1] << 1;
2171
BAYER(row+0,col+1) = pixel[col][0] + pixel[col+1][0];
2172
BAYER(row+1,col+0) = pixel[col][2] + pixel[col+1][2];
2175
jpeg_finish_decompress (&cinfo);
2176
jpeg_destroy_decompress (&cinfo);
2177
maximum = 0xff << 1;
2181
void CLASS kodak_dc120_load_raw()
2183
static const int mul[4] = { 162, 192, 187, 92 };
2184
static const int add[4] = { 0, 636, 424, 212 };
2186
int row, shift, col;
2188
for (row=0; row < height; row++) {
2189
if (fread (pixel, 1, 848, ifp) < 848) derror();
2190
shift = row * mul[row & 3] + add[row & 3];
2191
for (col=0; col < width; col++)
2192
BAYER(row,col) = (ushort) pixel[(col + shift) % 848];
2197
void CLASS eight_bit_load_raw()
2200
unsigned row, col, val, lblack=0;
2202
pixel = (uchar *) calloc (raw_width, sizeof *pixel);
2203
merror (pixel, "eight_bit_load_raw()");
2204
fseek (ifp, top_margin*raw_width, SEEK_CUR);
2205
for (row=0; row < height; row++) {
2206
if (fread (pixel, 1, raw_width, ifp) < raw_width) derror();
2207
for (col=0; col < raw_width; col++) {
2208
val = curve[pixel[col]];
2209
if ((unsigned) (col-left_margin) < width)
2210
BAYER(row,col-left_margin) = val;
2215
if (raw_width > width+1)
2216
black = lblack / ((raw_width - width) * height);
2217
if (!strncmp(model,"DC2",3))
2219
maximum = curve[0xff];
2222
void CLASS kodak_yrgb_load_raw()
2225
int row, col, y, cb, cr, rgb[3], c;
2227
pixel = (uchar *) calloc (raw_width, 3*sizeof *pixel);
2228
merror (pixel, "kodak_yrgb_load_raw()");
2229
for (row=0; row < height; row++) {
2231
if (fread (pixel, raw_width, 3, ifp) < 3) derror();
2232
for (col=0; col < raw_width; col++) {
2233
y = pixel[width*2*(row & 1) + col];
2234
cb = pixel[width + (col & -2)] - 128;
2235
cr = pixel[width + (col & -2)+1] - 128;
2236
rgb[1] = y-((cb + cr + 2) >> 2);
2237
rgb[2] = rgb[1] + cb;
2238
rgb[0] = rgb[1] + cr;
2239
FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,255)];
2243
maximum = curve[0xff];
2246
void CLASS kodak_262_load_raw()
2248
static const uchar kodak_tree[2][26] =
2249
{ { 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 },
2250
{ 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 } };
2253
int *strip, ns, c, row, col, chess, pi=0, pi1, pi2, pred, val;
2255
FORC(2) huff[c] = make_decoder (kodak_tree[c]);
2256
ns = (raw_height+63) >> 5;
2257
pixel = (uchar *) malloc (raw_width*32 + ns*4);
2258
merror (pixel, "kodak_262_load_raw()");
2259
strip = (int *) (pixel + raw_width*32);
2261
FORC(ns) strip[c] = get4();
2262
for (row=0; row < raw_height; row++) {
2263
if ((row & 31) == 0) {
2264
fseek (ifp, strip[row >> 5], SEEK_SET);
2268
for (col=0; col < raw_width; col++) {
2269
chess = (row + col) & 1;
2270
pi1 = chess ? pi-2 : pi-raw_width-1;
2271
pi2 = chess ? pi-2*raw_width : pi-raw_width+1;
2272
if (col <= chess) pi1 = -1;
2273
if (pi1 < 0) pi1 = pi2;
2274
if (pi2 < 0) pi2 = pi1;
2275
if (pi1 < 0 && col > 1) pi1 = pi2 = pi-2;
2276
pred = (pi1 < 0) ? 0 : (pixel[pi1] + pixel[pi2]) >> 1;
2277
pixel[pi] = val = pred + ljpeg_diff (huff[chess]);
2278
if (val >> 8) derror();
2279
val = curve[pixel[pi++]];
2280
if ((unsigned) (col-left_margin) < width)
2281
BAYER(row,col-left_margin) = val;
2286
FORC(2) free (huff[c]);
2287
if (raw_width > width)
2288
black /= (raw_width - width) * height;
2291
int CLASS kodak_65000_decode (short *out, int bsize)
2296
int save, bits=0, i, j, len, diff;
2299
bsize = (bsize + 3) & -4;
2300
for (i=0; i < bsize; i+=2) {
2302
if ((blen[i ] = c & 15) > 12 ||
2303
(blen[i+1] = c >> 4) > 12 ) {
2304
fseek (ifp, save, SEEK_SET);
2305
for (i=0; i < bsize; i+=8) {
2306
read_shorts (raw, 6);
2307
out[i ] = raw[0] >> 12 << 8 | raw[2] >> 12 << 4 | raw[4] >> 12;
2308
out[i+1] = raw[1] >> 12 << 8 | raw[3] >> 12 << 4 | raw[5] >> 12;
2309
for (j=0; j < 6; j++)
2310
out[i+2+j] = raw[j] & 0xfff;
2315
if ((bsize & 7) == 4) {
2316
bitbuf = fgetc(ifp) << 8;
2317
bitbuf += fgetc(ifp);
2320
for (i=0; i < bsize; i++) {
2323
for (j=0; j < 32; j+=8)
2324
bitbuf += (INT64) fgetc(ifp) << (bits+(j^8));
2327
diff = bitbuf & (0xffff >> (16-len));
2330
if ((diff & (1 << (len-1))) == 0)
2331
diff -= (1 << len) - 1;
2337
void CLASS kodak_65000_load_raw()
2340
int row, col, len, pred[2], ret, i;
2342
for (row=0; row < height; row++)
2343
for (col=0; col < width; col+=256) {
2344
pred[0] = pred[1] = 0;
2345
len = MIN (256, width-col);
2346
ret = kodak_65000_decode (buf, len);
2347
for (i=0; i < len; i++)
2348
if ((BAYER(row,col+i) = curve[ret ? buf[i] :
2349
(pred[i & 1] += buf[i])]) >> 12) derror();
2353
void CLASS kodak_ycbcr_load_raw()
2355
short buf[384], *bp;
2356
int row, col, len, c, i, j, k, y[2][2], cb, cr, rgb[3];
2359
for (row=0; row < height; row+=2)
2360
for (col=0; col < width; col+=128) {
2361
len = MIN (128, width-col);
2362
kodak_65000_decode (buf, len*3);
2363
y[0][1] = y[1][1] = cb = cr = 0;
2364
for (bp=buf, i=0; i < len; i+=2, bp+=2) {
2367
rgb[1] = -((cb + cr + 2) >> 2);
2368
rgb[2] = rgb[1] + cb;
2369
rgb[0] = rgb[1] + cr;
2370
for (j=0; j < 2; j++)
2371
for (k=0; k < 2; k++) {
2372
if ((y[j][k] = y[j][k^1] + *bp++) >> 10) derror();
2373
ip = image[(row+j)*width + col+i+k];
2374
FORC3 ip[c] = curve[LIM(y[j][k]+rgb[c], 0, 0xfff)];
2380
void CLASS kodak_rgb_load_raw()
2382
short buf[768], *bp;
2383
int row, col, len, c, i, rgb[3];
2384
ushort *ip=image[0];
2386
for (row=0; row < height; row++)
2387
for (col=0; col < width; col+=256) {
2388
len = MIN (256, width-col);
2389
kodak_65000_decode (buf, len*3);
2390
memset (rgb, 0, sizeof rgb);
2391
for (bp=buf, i=0; i < len; i++, ip+=4)
2392
FORC3 if ((ip[c] = rgb[c] += *bp++) >> 12) derror();
2396
void CLASS kodak_thumb_load_raw()
2399
colors = thumb_misc >> 5;
2400
for (row=0; row < height; row++)
2401
for (col=0; col < width; col++)
2402
read_shorts (image[row*width+col], colors);
2403
maximum = (1 << (thumb_misc & 31)) - 1;
2406
void CLASS sony_decrypt (unsigned *data, int len, int start, int key)
2408
static unsigned pad[128], p;
2411
for (p=0; p < 4; p++)
2412
pad[p] = key = key * 48828125 + 1;
2413
pad[3] = pad[3] << 1 | (pad[0]^pad[2]) >> 31;
2414
for (p=4; p < 127; p++)
2415
pad[p] = (pad[p-4]^pad[p-2]) << 1 | (pad[p-3]^pad[p-1]) >> 31;
2416
for (p=0; p < 127; p++)
2417
pad[p] = htonl(pad[p]);
2420
*data++ ^= pad[p++ & 127] = pad[(p+1) & 127] ^ pad[(p+65) & 127];
2423
void CLASS sony_load_raw()
2427
unsigned i, key, row, col;
2429
fseek (ifp, 200896, SEEK_SET);
2430
fseek (ifp, (unsigned) fgetc(ifp)*4 - 1, SEEK_CUR);
2433
fseek (ifp, 164600, SEEK_SET);
2434
fread (head, 1, 40, ifp);
2435
sony_decrypt ((unsigned int *) head, 10, 1, key);
2436
for (i=26; i-- > 22; )
2437
key = key << 8 | head[i];
2438
fseek (ifp, data_offset, SEEK_SET);
2439
pixel = (ushort *) calloc (raw_width, sizeof *pixel);
2440
merror (pixel, "sony_load_raw()");
2441
for (row=0; row < height; row++) {
2442
if (fread (pixel, 2, raw_width, ifp) < raw_width) derror();
2443
sony_decrypt ((unsigned int *) pixel, raw_width/2, !row, key);
2444
for (col=9; col < left_margin; col++)
2445
black += ntohs(pixel[col]);
2446
for (col=0; col < width; col++)
2447
if ((BAYER(row,col) = ntohs(pixel[col+left_margin])) >> 14)
2451
if (left_margin > 9)
2452
black /= (left_margin-9) * height;
2456
void CLASS sony_arw_load_raw()
2459
static const ushort tab[18] =
2460
{ 0xf11,0xf10,0xe0f,0xd0e,0xc0d,0xb0c,0xa0b,0x90a,0x809,
2461
0x708,0x607,0x506,0x405,0x304,0x303,0x300,0x202,0x201 };
2462
int i, c, n, col, row, len, diff, sum=0;
2464
for (n=i=0; i < 18; i++)
2465
FORC(32768 >> (tab[i] >> 8)) huff[n++] = tab[i];
2467
for (col = raw_width; col--; )
2468
for (row=0; row < raw_height+1; row+=2) {
2469
if (row == raw_height) row = 1;
2470
len = getbithuff(15,huff);
2471
diff = getbits(len);
2472
if ((diff & (1 << (len-1))) == 0)
2473
diff -= (1 << len) - 1;
2474
if ((sum += diff) >> 12) derror();
2475
if (row < height) BAYER(row,col) = sum;
2479
void CLASS sony_arw2_load_raw()
2483
int row, col, val, max, min, imax, imin, sh, bit, i;
2485
data = (uchar *) malloc (raw_width);
2486
merror (data, "sony_arw2_load_raw()");
2487
for (row=0; row < height; row++) {
2488
fread (data, 1, raw_width, ifp);
2489
for (dp=data, col=0; col < width-30; dp+=16) {
2490
max = 0x7ff & (val = sget4(dp));
2491
min = 0x7ff & val >> 11;
2492
imax = 0x0f & val >> 22;
2493
imin = 0x0f & val >> 26;
2494
for (sh=0; sh < 4 && 0x80 << sh <= max-min; sh++);
2495
for (bit=30, i=0; i < 16; i++)
2496
if (i == imax) pix[i] = max;
2497
else if (i == imin) pix[i] = min;
2499
pix[i] = ((sget2(dp+(bit >> 3)) >> (bit & 7) & 0x7f) << sh) + min;
2500
if (pix[i] > 0x7ff) pix[i] = 0x7ff;
2503
for (i=0; i < 16; i++, col+=2)
2504
BAYER(row,col) = curve[pix[i] << 1] >> 1;
2505
col -= col & 1 ? 1:31;
2511
#define HOLE(row) ((holes >> (((row) - raw_height) & 7)) & 1)
2513
/* Kudos to Rich Taylor for figuring out SMaL's compression algorithm. */
2514
void CLASS smal_decode_segment (unsigned seg[2][2], int holes)
2516
uchar hist[3][13] = {
2517
{ 7, 7, 0, 0, 63, 55, 47, 39, 31, 23, 15, 7, 0 },
2518
{ 7, 7, 0, 0, 63, 55, 47, 39, 31, 23, 15, 7, 0 },
2519
{ 3, 3, 0, 0, 63, 47, 31, 15, 0 } };
2520
int low, high=0xff, carry=0, nbits=8;
2521
int s, count, bin, next, i, sym[3];
2522
uchar diff, pred[]={0,0};
2523
ushort data=0, range=0;
2524
unsigned pix, row, col;
2526
fseek (ifp, seg[0][1]+1, SEEK_SET);
2528
for (pix=seg[0][0]; pix < seg[1][0]; pix++) {
2529
for (s=0; s < 3; s++) {
2530
data = data << nbits | getbits(nbits);
2532
carry = (nbits += carry+1) < 1 ? nbits-1 : 0;
2533
while (--nbits >= 0)
2534
if ((data >> nbits & 0xff) == 0xff) break;
2536
data = ((data & ((1 << (nbits-1)) - 1)) << 1) |
2537
((data + (((data & (1 << (nbits-1)))) << 1)) & (-1 << nbits));
2542
count = ((((data-range+1) & 0xffff) << 2) - 1) / (high >> 4);
2543
for (bin=0; hist[s][bin+5] > count; bin++);
2544
low = hist[s][bin+5] * (high >> 4) >> 2;
2545
if (bin) high = hist[s][bin+4] * (high >> 4) >> 2;
2547
for (nbits=0; high << nbits < 128; nbits++);
2548
range = (range+low) << nbits;
2551
if (++hist[s][2] > hist[s][3]) {
2552
next = (next+1) & hist[s][0];
2553
hist[s][3] = (hist[s][next+4] - hist[s][next+5]) >> 2;
2556
if (hist[s][hist[s][1]+4] - hist[s][hist[s][1]+5] > 1) {
2557
if (bin < hist[s][1])
2558
for (i=bin; i < hist[s][1]; i++) hist[s][i+5]--;
2559
else if (next <= bin)
2560
for (i=hist[s][1]; i < bin; i++) hist[s][i+5]++;
2565
diff = sym[2] << 5 | sym[1] << 2 | (sym[0] & 3);
2567
diff = diff ? -diff : 0x80;
2568
if (ftell(ifp) + 12 >= seg[1][1])
2570
pred[pix & 1] += diff;
2571
row = pix / raw_width - top_margin;
2572
col = pix % raw_width - left_margin;
2573
if (row < height && col < width)
2574
BAYER(row,col) = pred[pix & 1];
2575
if (!(pix & 1) && HOLE(row)) pix += 2;
2580
void CLASS smal_v6_load_raw()
2584
fseek (ifp, 16, SEEK_SET);
2587
seg[1][0] = raw_width * raw_height;
2588
seg[1][1] = INT_MAX;
2589
smal_decode_segment (seg, 0);
2592
int CLASS median4 (int *p)
2594
int min, max, sum, i;
2596
min = max = sum = p[0];
2597
for (i=1; i < 4; i++) {
2599
if (min > p[i]) min = p[i];
2600
if (max < p[i]) max = p[i];
2602
return (sum - min - max) >> 1;
2605
void CLASS fill_holes (int holes)
2607
int row, col, val[4];
2609
for (row=2; row < height-2; row++) {
2610
if (!HOLE(row)) continue;
2611
for (col=1; col < width-1; col+=4) {
2612
val[0] = BAYER(row-1,col-1);
2613
val[1] = BAYER(row-1,col+1);
2614
val[2] = BAYER(row+1,col-1);
2615
val[3] = BAYER(row+1,col+1);
2616
BAYER(row,col) = median4(val);
2618
for (col=2; col < width-2; col+=4)
2619
if (HOLE(row-2) || HOLE(row+2))
2620
BAYER(row,col) = (BAYER(row,col-2) + BAYER(row,col+2)) >> 1;
2622
val[0] = BAYER(row,col-2);
2623
val[1] = BAYER(row,col+2);
2624
val[2] = BAYER(row-2,col);
2625
val[3] = BAYER(row+2,col);
2626
BAYER(row,col) = median4(val);
2631
void CLASS smal_v9_load_raw()
2633
unsigned seg[256][2], offset, nseg, holes, i;
2635
fseek (ifp, 67, SEEK_SET);
2638
fseek (ifp, offset, SEEK_SET);
2639
for (i=0; i < nseg*2; i++)
2640
seg[0][i] = get4() + data_offset*(i & 1);
2641
fseek (ifp, 78, SEEK_SET);
2643
fseek (ifp, 88, SEEK_SET);
2644
seg[nseg][0] = raw_height * raw_width;
2645
seg[nseg][1] = get4() + data_offset;
2646
for (i=0; i < nseg; i++)
2647
smal_decode_segment (seg+i, holes);
2648
if (holes) fill_holes (holes);
2651
/* RESTRICTED code starts here */
2653
void CLASS foveon_decoder (unsigned size, unsigned code)
2655
static unsigned huff[1024];
2660
for (i=0; i < size; i++)
2662
memset (first_decode, 0, sizeof first_decode);
2663
free_decode = first_decode;
2665
cur = free_decode++;
2666
if (free_decode > first_decode+2048) {
2667
fprintf (stderr,_("%s: decoder table overflow\n"), ifname);
2668
longjmp (failure, 2);
2671
for (i=0; i < size; i++)
2672
if (huff[i] == code) {
2676
if ((len = code >> 27) > 26) return;
2677
code = (len+1) << 27 | (code & 0x3ffffff) << 1;
2679
cur->branch[0] = free_decode;
2680
foveon_decoder (size, code);
2681
cur->branch[1] = free_decode;
2682
foveon_decoder (size, code+1);
2685
void CLASS foveon_thumb()
2687
unsigned bwide, row, col, bitbuf=0, bit=1, c, i;
2689
struct decode *dindex;
2693
fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
2695
if (bwide < thumb_width*3) return;
2696
buf = (char *) malloc (bwide);
2697
merror (buf, "foveon_thumb()");
2698
for (row=0; row < thumb_height; row++) {
2699
fread (buf, 1, bwide, ifp);
2700
fwrite (buf, 3, thumb_width, ofp);
2705
foveon_decoder (256, 0);
2707
for (row=0; row < thumb_height; row++) {
2708
memset (pred, 0, sizeof pred);
2710
for (bit=col=0; col < thumb_width; col++)
2712
for (dindex=first_decode; dindex->branch[0]; ) {
2713
if ((bit = (bit-1) & 31) == 31)
2714
for (i=0; i < 4; i++)
2715
bitbuf = (bitbuf << 8) + fgetc(ifp);
2716
dindex = dindex->branch[bitbuf >> bit & 1];
2718
pred[c] += dindex->leaf;
2719
fputc (pred[c], ofp);
2724
void CLASS foveon_load_camf()
2726
unsigned key, i, val;
2728
fseek (ifp, meta_offset, SEEK_SET);
2730
fread (meta_data, 1, meta_length, ifp);
2731
for (i=0; i < meta_length; i++) {
2732
key = (key * 1597 + 51749) % 244944;
2733
val = key * (INT64) 301593171 >> 24;
2734
meta_data[i] ^= ((((key << 8) - val) >> 1) + val) >> 17;
2738
void CLASS foveon_load_raw()
2740
struct decode *dindex;
2743
int pred[3], fixed, row, col, bit=-1, c, i;
2746
read_shorts ((ushort *) diff, 1024);
2747
if (!fixed) foveon_decoder (1024, 0);
2749
for (row=0; row < height; row++) {
2750
memset (pred, 0, sizeof pred);
2751
if (!bit && !fixed && atoi(model+2) < 14) get4();
2752
for (col=bit=0; col < width; col++) {
2755
FORC3 pred[2-c] += diff[bitbuf >> c*10 & 0x3ff];
2758
for (dindex=first_decode; dindex->branch[0]; ) {
2759
if ((bit = (bit-1) & 31) == 31)
2760
for (i=0; i < 4; i++)
2761
bitbuf = (bitbuf << 8) + fgetc(ifp);
2762
dindex = dindex->branch[bitbuf >> bit & 1];
2764
pred[c] += diff[dindex->leaf];
2765
if (pred[c] >> 16 && ~pred[c] >> 16) derror();
2767
FORC3 image[row*width+col][c] = pred[c];
2771
for (i=0; i < height*width*4; i++)
2772
if ((short) image[0][i] < 0) image[0][i] = 0;
2776
const char * CLASS foveon_camf_param (const char *block, const char *param)
2779
char *pos, *cp, *dp;
2781
for (idx=0; idx < meta_length; idx += sget4(pos+8)) {
2782
pos = meta_data + idx;
2783
if (strncmp (pos, "CMb", 3)) break;
2784
if (pos[3] != 'P') continue;
2785
if (strcmp (block, pos+sget4(pos+12))) continue;
2786
cp = pos + sget4(pos+16);
2788
dp = pos + sget4(cp+4);
2791
if (!strcmp (param, dp+sget4(cp)))
2792
return dp+sget4(cp+4);
2798
void * CLASS foveon_camf_matrix (unsigned dim[3], const char *name)
2800
unsigned i, idx, type, ndim, size, *mat;
2801
char *pos, *cp, *dp;
2804
for (idx=0; idx < meta_length; idx += sget4(pos+8)) {
2805
pos = meta_data + idx;
2806
if (strncmp (pos, "CMb", 3)) break;
2807
if (pos[3] != 'M') continue;
2808
if (strcmp (name, pos+sget4(pos+12))) continue;
2809
dim[0] = dim[1] = dim[2] = 1;
2810
cp = pos + sget4(pos+16);
2812
if ((ndim = sget4(cp+4)) > 3) break;
2813
dp = pos + sget4(cp+8);
2814
for (i=ndim; i--; ) {
2818
if ((dsize = (double) dim[0]*dim[1]*dim[2]) > meta_length/4) break;
2819
mat = (unsigned *) malloc ((size = dsize) * 4);
2820
merror (mat, "foveon_camf_matrix()");
2821
for (i=0; i < size; i++)
2822
if (type && type != 6)
2823
mat[i] = sget4(dp + i*4);
2825
mat[i] = sget4(dp + i*2) & 0xffff;
2828
fprintf (stderr,_("%s: \"%s\" matrix not found!\n"), ifname, name);
2832
int CLASS foveon_fixed (void *ptr, int size, const char *name)
2837
dp = foveon_camf_matrix (dim, name);
2839
memcpy (ptr, dp, size*4);
2844
float CLASS foveon_avg (short *pix, int range[2], float cfilt)
2847
float val, min=FLT_MAX, max=-FLT_MAX, sum=0;
2849
for (i=range[0]; i <= range[1]; i++) {
2850
sum += val = pix[i*4] + (pix[i*4]-pix[(i-1)*4]) * cfilt;
2851
if (min > val) min = val;
2852
if (max < val) max = val;
2854
if (range[1] - range[0] == 1) return sum/2;
2855
return (sum - min - max) / (range[1] - range[0] - 1);
2858
short * CLASS foveon_make_curve (double max, double mul, double filt)
2864
if (!filt) filt = 0.8;
2865
size = 4*M_PI*max / filt;
2866
if (size == UINT_MAX) size--;
2867
curve = (short *) calloc (size+1, sizeof *curve);
2868
merror (curve, "foveon_make_curve()");
2870
for (i=0; i < size; i++) {
2872
curve[i+1] = (cos(x)+1)/2 * tanh(i*filt/mul) * mul + 0.5;
2877
void CLASS foveon_make_curves
2878
(short **curvep, float dq[3], float div[3], float filt)
2880
double mul[3], max=0;
2883
FORC3 mul[c] = dq[c]/div[c];
2884
FORC3 if (max < mul[c]) max = mul[c];
2885
FORC3 curvep[c] = foveon_make_curve (max, mul[c], filt);
2888
int CLASS foveon_apply_curve (short *curve, int i)
2890
if (abs(i) >= curve[0]) return 0;
2891
return i < 0 ? -curve[1-i] : curve[1+i];
2894
#define image ((short (*)[4]) image)
2896
void CLASS foveon_interpolate()
2898
static const short hood[] = { -1,-1, -1,0, -1,1, 0,-1, 0,1, 1,-1, 1,0, 1,1 };
2899
short *pix, prev[3], *curve[8], (*shrink)[3];
2900
float cfilt=0, ddft[3][3][2], ppm[3][3][3];
2901
float cam_xyz[3][3], correct[3][3], last[3][3], trans[3][3];
2902
float chroma_dq[3], color_dq[3], diag[3][3], div[3];
2903
float (*black)[3], (*sgain)[3], (*sgrow)[3];
2904
float fsum[3], val, frow, num;
2905
int row, col, c, i, j, diff, sgx, irow, sum, min, max, limit;
2906
int dscr[2][2], dstb[4], (*smrow[7])[3], total[4], ipix[3];
2907
int work[3][3], smlast, smred, smred_p=0, dev[3];
2908
int satlev[3], keep[4], active[4];
2909
unsigned dim[3], *badpix;
2910
double dsum=0, trsum[3];
2915
fprintf (stderr,_("Foveon interpolation...\n"));
2917
foveon_fixed (dscr, 4, "DarkShieldColRange");
2918
foveon_fixed (ppm[0][0], 27, "PostPolyMatrix");
2919
foveon_fixed (satlev, 3, "SaturationLevel");
2920
foveon_fixed (keep, 4, "KeepImageArea");
2921
foveon_fixed (active, 4, "ActiveImageArea");
2922
foveon_fixed (chroma_dq, 3, "ChromaDQ");
2923
foveon_fixed (color_dq, 3,
2924
foveon_camf_param ("IncludeBlocks", "ColorDQ") ?
2925
"ColorDQ" : "ColorDQCamRGB");
2926
if (foveon_camf_param ("IncludeBlocks", "ColumnFilter"))
2927
foveon_fixed (&cfilt, 1, "ColumnFilter");
2929
memset (ddft, 0, sizeof ddft);
2930
if (!foveon_camf_param ("IncludeBlocks", "DarkDrift")
2931
|| !foveon_fixed (ddft[1][0], 12, "DarkDrift"))
2932
for (i=0; i < 2; i++) {
2933
foveon_fixed (dstb, 4, i ? "DarkShieldBottom":"DarkShieldTop");
2934
for (row = dstb[1]; row <= dstb[3]; row++)
2935
for (col = dstb[0]; col <= dstb[2]; col++)
2936
FORC3 ddft[i+1][c][1] += (short) image[row*width+col][c];
2937
FORC3 ddft[i+1][c][1] /= (dstb[3]-dstb[1]+1) * (dstb[2]-dstb[0]+1);
2940
if (!(cp = foveon_camf_param ("WhiteBalanceIlluminants", model2)))
2941
{ fprintf (stderr,_("%s: Invalid white balance \"%s\"\n"), ifname, model2);
2943
foveon_fixed (cam_xyz, 9, cp);
2944
foveon_fixed (correct, 9,
2945
foveon_camf_param ("WhiteBalanceCorrections", model2));
2946
memset (last, 0, sizeof last);
2947
for (i=0; i < 3; i++)
2948
for (j=0; j < 3; j++)
2949
FORC3 last[i][j] += correct[i][c] * cam_xyz[c][j];
2951
#define LAST(x,y) last[(i+x)%3][(c+y)%3]
2952
for (i=0; i < 3; i++)
2953
FORC3 diag[c][i] = LAST(1,1)*LAST(2,2) - LAST(1,2)*LAST(2,1);
2955
FORC3 div[c] = diag[c][0]*0.3127 + diag[c][1]*0.329 + diag[c][2]*0.3583;
2956
sprintf (str, "%sRGBNeutral", model2);
2957
if (foveon_camf_param ("IncludeBlocks", str))
2958
foveon_fixed (div, 3, str);
2960
FORC3 if (num < div[c]) num = div[c];
2961
FORC3 div[c] /= num;
2963
memset (trans, 0, sizeof trans);
2964
for (i=0; i < 3; i++)
2965
for (j=0; j < 3; j++)
2966
FORC3 trans[i][j] += rgb_cam[i][c] * last[c][j] * div[j];
2967
FORC3 trsum[c] = trans[c][0] + trans[c][1] + trans[c][2];
2968
dsum = (6*trsum[0] + 11*trsum[1] + 3*trsum[2]) / 20;
2969
for (i=0; i < 3; i++)
2970
FORC3 last[i][c] = trans[i][c] * dsum / trsum[i];
2971
memset (trans, 0, sizeof trans);
2972
for (i=0; i < 3; i++)
2973
for (j=0; j < 3; j++)
2974
FORC3 trans[i][j] += (i==c ? 32 : -1) * last[c][j] / 30;
2976
foveon_make_curves (curve, color_dq, div, cfilt);
2977
FORC3 chroma_dq[c] /= 3;
2978
foveon_make_curves (curve+3, chroma_dq, div, cfilt);
2979
FORC3 dsum += chroma_dq[c] / div[c];
2980
curve[6] = foveon_make_curve (dsum, dsum, cfilt);
2981
curve[7] = foveon_make_curve (dsum*2, dsum*2, cfilt);
2983
sgain = (float (*)[3]) foveon_camf_matrix (dim, "SpatialGain");
2985
sgrow = (float (*)[3]) calloc (dim[1], sizeof *sgrow);
2986
sgx = (width + dim[1]-2) / (dim[1]-1);
2988
black = (float (*)[3]) calloc (height, sizeof *black);
2989
for (row=0; row < height; row++) {
2990
for (i=0; i < 6; i++)
2991
ddft[0][0][i] = ddft[1][0][i] +
2992
row / (height-1.0) * (ddft[2][0][i] - ddft[1][0][i]);
2993
FORC3 black[row][c] =
2994
( foveon_avg (image[row*width]+c, dscr[0], cfilt) +
2995
foveon_avg (image[row*width]+c, dscr[1], cfilt) * 3
2996
- ddft[0][c][0] ) / 4 - ddft[0][c][1];
2998
memcpy (black, black+8, sizeof *black*8);
2999
memcpy (black+height-11, black+height-22, 11*sizeof *black);
3000
memcpy (last, black, sizeof last);
3002
for (row=1; row < height-1; row++) {
3003
FORC3 if (last[1][c] > last[0][c]) {
3004
if (last[1][c] > last[2][c])
3005
black[row][c] = (last[0][c] > last[2][c]) ? last[0][c]:last[2][c];
3007
if (last[1][c] < last[2][c])
3008
black[row][c] = (last[0][c] < last[2][c]) ? last[0][c]:last[2][c];
3009
memmove (last, last+1, 2*sizeof last[0]);
3010
memcpy (last[2], black[row+1], sizeof last[2]);
3012
FORC3 black[row][c] = (last[0][c] + last[1][c])/2;
3013
FORC3 black[0][c] = (black[1][c] + black[3][c])/2;
3015
val = 1 - exp(-1/24.0);
3016
memcpy (fsum, black, sizeof fsum);
3017
for (row=1; row < height; row++)
3018
FORC3 fsum[c] += black[row][c] =
3019
(black[row][c] - black[row-1][c])*val + black[row-1][c];
3020
memcpy (last[0], black[height-1], sizeof last[0]);
3021
FORC3 fsum[c] /= height;
3022
for (row = height; row--; )
3023
FORC3 last[0][c] = black[row][c] =
3024
(black[row][c] - fsum[c] - last[0][c])*val + last[0][c];
3026
memset (total, 0, sizeof total);
3027
for (row=2; row < height; row+=4)
3028
for (col=2; col < width; col+=4) {
3029
FORC3 total[c] += (short) image[row*width+col][c];
3032
for (row=0; row < height; row++)
3033
FORC3 black[row][c] += fsum[c]/2 + total[c]/(total[3]*100.0);
3035
for (row=0; row < height; row++) {
3036
for (i=0; i < 6; i++)
3037
ddft[0][0][i] = ddft[1][0][i] +
3038
row / (height-1.0) * (ddft[2][0][i] - ddft[1][0][i]);
3039
pix = image[row*width];
3040
memcpy (prev, pix, sizeof prev);
3041
frow = row / (height-1.0) * (dim[2]-1);
3042
if ((irow = frow) == dim[2]-1) irow--;
3044
for (i=0; i < dim[1]; i++)
3045
FORC3 sgrow[i][c] = sgain[ irow *dim[1]+i][c] * (1-frow) +
3046
sgain[(irow+1)*dim[1]+i][c] * frow;
3047
for (col=0; col < width; col++) {
3049
diff = pix[c] - prev[c];
3051
ipix[c] = pix[c] + floor ((diff + (diff*diff >> 14)) * cfilt
3052
- ddft[0][c][1] - ddft[0][c][0] * ((float) col/width - 0.5)
3056
work[0][c] = ipix[c] * ipix[c] >> 14;
3057
work[2][c] = ipix[c] * work[0][c] >> 14;
3058
work[1][2-c] = ipix[(c+1) % 3] * ipix[(c+2) % 3] >> 14;
3061
for (val=i=0; i < 3; i++)
3062
for ( j=0; j < 3; j++)
3063
val += ppm[c][i][j] * work[i][j];
3064
ipix[c] = floor ((ipix[c] + floor(val)) *
3065
( sgrow[col/sgx ][c] * (sgx - col%sgx) +
3066
sgrow[col/sgx+1][c] * (col%sgx) ) / sgx / div[c]);
3067
if (ipix[c] > 32000) ipix[c] = 32000;
3077
if ((badpix = (unsigned int *) foveon_camf_matrix (dim, "BadPixels"))) {
3078
for (i=0; i < dim[0]; i++) {
3079
col = (badpix[i] >> 8 & 0xfff) - keep[0];
3080
row = (badpix[i] >> 20 ) - keep[1];
3081
if ((unsigned)(row-1) > height-3 || (unsigned)(col-1) > width-3)
3083
memset (fsum, 0, sizeof fsum);
3084
for (sum=j=0; j < 8; j++)
3085
if (badpix[i] & (1 << j)) {
3086
FORC3 fsum[c] += (short)
3087
image[(row+hood[j*2])*width+col+hood[j*2+1]][c];
3090
if (sum) FORC3 image[row*width+col][c] = fsum[c]/sum;
3095
/* Array for 5x5 Gaussian averaging of red values */
3096
smrow[6] = (int (*)[3]) calloc (width*5, sizeof **smrow);
3097
merror (smrow[6], "foveon_interpolate()");
3098
for (i=0; i < 5; i++)
3099
smrow[i] = smrow[6] + i*width;
3101
/* Sharpen the reds against these Gaussian averages */
3102
for (smlast=-1, row=2; row < height-2; row++) {
3103
while (smlast < row+2) {
3104
for (i=0; i < 6; i++)
3105
smrow[(i+5) % 6] = smrow[i];
3106
pix = image[++smlast*width+2];
3107
for (col=2; col < width-2; col++) {
3109
(pix[0]*6 + (pix[-4]+pix[4])*4 + pix[-8]+pix[8] + 8) >> 4;
3113
pix = image[row*width+2];
3114
for (col=2; col < width-2; col++) {
3115
smred = ( 6 * smrow[2][col][0]
3116
+ 4 * (smrow[1][col][0] + smrow[3][col][0])
3117
+ smrow[0][col][0] + smrow[4][col][0] + 8 ) >> 4;
3120
i = pix[0] + ((pix[0] - ((smred*7 + smred_p) >> 3)) >> 3);
3121
if (i > 32000) i = 32000;
3128
/* Adjust the brighter pixels for better linearity */
3131
i = satlev[c] / div[c];
3132
if (min > i) min = i;
3134
limit = min * 9 >> 4;
3135
for (pix=image[0]; pix < image[height*width]; pix+=4) {
3136
if (pix[0] <= limit || pix[1] <= limit || pix[2] <= limit)
3139
for (c=1; c < 3; c++) {
3140
if (min > pix[c]) min = pix[c];
3141
if (max < pix[c]) max = pix[c];
3143
if (min >= limit*2) {
3144
pix[0] = pix[1] = pix[2] = max;
3146
i = 0x4000 - ((min - limit) << 14) / limit;
3147
i = 0x4000 - (i*i >> 14);
3149
FORC3 pix[c] += (max - pix[c]) * i >> 14;
3153
Because photons that miss one detector often hit another,
3154
the sum R+G+B is much less noisy than the individual colors.
3155
So smooth the hues without smoothing the total.
3157
for (smlast=-1, row=2; row < height-2; row++) {
3158
while (smlast < row+2) {
3159
for (i=0; i < 6; i++)
3160
smrow[(i+5) % 6] = smrow[i];
3161
pix = image[++smlast*width+2];
3162
for (col=2; col < width-2; col++) {
3163
FORC3 smrow[4][col][c] = (pix[c-4]+2*pix[c]+pix[c+4]+2) >> 2;
3167
pix = image[row*width+2];
3168
for (col=2; col < width-2; col++) {
3169
FORC3 dev[c] = -foveon_apply_curve (curve[7], pix[c] -
3170
((smrow[1][col][c] + 2*smrow[2][col][c] + smrow[3][col][c]) >> 2));
3171
sum = (dev[0] + dev[1] + dev[2]) >> 3;
3172
FORC3 pix[c] += dev[c] - sum;
3176
for (smlast=-1, row=2; row < height-2; row++) {
3177
while (smlast < row+2) {
3178
for (i=0; i < 6; i++)
3179
smrow[(i+5) % 6] = smrow[i];
3180
pix = image[++smlast*width+2];
3181
for (col=2; col < width-2; col++) {
3182
FORC3 smrow[4][col][c] =
3183
(pix[c-8]+pix[c-4]+pix[c]+pix[c+4]+pix[c+8]+2) >> 2;
3187
pix = image[row*width+2];
3188
for (col=2; col < width-2; col++) {
3189
for (total[3]=375, sum=60, c=0; c < 3; c++) {
3190
for (total[c]=i=0; i < 5; i++)
3191
total[c] += smrow[i][col][c];
3192
total[3] += total[c];
3195
if (sum < 0) sum = 0;
3196
j = total[3] > 375 ? (sum << 16) / total[3] : sum * 174;
3197
FORC3 pix[c] += foveon_apply_curve (curve[6],
3198
((j*total[c] + 0x8000) >> 16) - pix[c]);
3203
/* Transform the image to a different colorspace */
3204
for (pix=image[0]; pix < image[height*width]; pix+=4) {
3205
FORC3 pix[c] -= foveon_apply_curve (curve[c], pix[c]);
3206
sum = (pix[0]+pix[1]+pix[1]+pix[2]) >> 2;
3207
FORC3 pix[c] -= foveon_apply_curve (curve[c], pix[c]-sum);
3209
for (dsum=i=0; i < 3; i++)
3210
dsum += trans[c][i] * pix[i];
3211
if (dsum < 0) dsum = 0;
3212
if (dsum > 24000) dsum = 24000;
3213
ipix[c] = dsum + 0.5;
3215
FORC3 pix[c] = ipix[c];
3218
/* Smooth the image bottom-to-top and save at 1/4 scale */
3219
shrink = (short (*)[3]) calloc ((width/4) * (height/4), sizeof *shrink);
3220
merror (shrink, "foveon_interpolate()");
3221
for (row = height/4; row--; )
3222
for (col=0; col < width/4; col++) {
3223
ipix[0] = ipix[1] = ipix[2] = 0;
3224
for (i=0; i < 4; i++)
3225
for (j=0; j < 4; j++)
3226
FORC3 ipix[c] += image[(row*4+i)*width+col*4+j][c];
3228
if (row+2 > height/4)
3229
shrink[row*(width/4)+col][c] = ipix[c] >> 4;
3231
shrink[row*(width/4)+col][c] =
3232
(shrink[(row+1)*(width/4)+col][c]*1840 + ipix[c]*141 + 2048) >> 12;
3234
/* From the 1/4-scale image, smooth right-to-left */
3235
for (row=0; row < (height & ~3); row++) {
3236
ipix[0] = ipix[1] = ipix[2] = 0;
3238
for (col = width & ~3 ; col--; )
3239
FORC3 smrow[0][col][c] = ipix[c] =
3240
(shrink[(row/4)*(width/4)+col/4][c]*1485 + ipix[c]*6707 + 4096) >> 13;
3242
/* Then smooth left-to-right */
3243
ipix[0] = ipix[1] = ipix[2] = 0;
3244
for (col=0; col < (width & ~3); col++)
3245
FORC3 smrow[1][col][c] = ipix[c] =
3246
(smrow[0][col][c]*1485 + ipix[c]*6707 + 4096) >> 13;
3248
/* Smooth top-to-bottom */
3250
memcpy (smrow[2], smrow[1], sizeof **smrow * width);
3252
for (col=0; col < (width & ~3); col++)
3253
FORC3 smrow[2][col][c] =
3254
(smrow[2][col][c]*6707 + smrow[1][col][c]*1485 + 4096) >> 13;
3256
/* Adjust the chroma toward the smooth values */
3257
for (col=0; col < (width & ~3); col++) {
3258
for (i=j=30, c=0; c < 3; c++) {
3259
i += smrow[2][col][c];
3260
j += image[row*width+col][c];
3263
for (sum=c=0; c < 3; c++) {
3264
ipix[c] = foveon_apply_curve (curve[c+3],
3265
((smrow[2][col][c] * j + 0x8000) >> 16) - image[row*width+col][c]);
3270
i = image[row*width+col][c] + ipix[c] - sum;
3272
image[row*width+col][c] = i;
3278
for (i=0; i < 8; i++)
3281
/* Trim off the black border */
3282
active[1] -= keep[1];
3284
i = active[2] - active[0];
3285
for (row=0; row < active[3]-active[1]; row++)
3286
memcpy (image[row*i], image[(row+active[1])*width+active[0]],
3293
/* RESTRICTED code ends here */
3296
Seach from the current directory up to the root looking for
3297
a ".badpixels" file, and fix those pixels now.
3299
void CLASS bad_pixels (const char *cfname)
3302
char *fname, *cp, line[128];
3303
int len, time, row, col, r, c, rad, tot, n, fixed=0;
3305
if (!filters) return;
3307
fp = fopen (cfname, "r");
3309
for (len=32 ; ; len *= 2) {
3310
fname = (char *) malloc (len);
3312
if (getcwd (fname, len-16)) break;
3314
if (errno != ERANGE) return;
3316
#if defined(WIN32) || defined(DJGPP)
3317
if (fname[1] == ':')
3318
memmove (fname, fname+2, len-2);
3319
for (cp=fname; *cp; cp++)
3320
if (*cp == '\\') *cp = '/';
3322
cp = fname + strlen(fname);
3323
if (cp[-1] == '/') cp--;
3324
while (*fname == '/') {
3325
strcpy (cp, "/.badpixels");
3326
if ((fp = fopen (fname, "r"))) break;
3327
if (cp == fname) break;
3328
while (*--cp != '/');
3333
while (fgets (line, 128, fp)) {
3334
cp = strchr (line, '#');
3336
if (sscanf (line, "%d %d %d", &col, &row, &time) != 3) continue;
3337
if ((unsigned) col >= width || (unsigned) row >= height) continue;
3338
if (time > timestamp) continue;
3339
for (tot=n=0, rad=1; rad < 3 && n==0; rad++)
3340
for (r = row-rad; r <= row+rad; r++)
3341
for (c = col-rad; c <= col+rad; c++)
3342
if ((unsigned) r < height && (unsigned) c < width &&
3343
(r != row || c != col) && fc(r,c) == fc(row,col)) {
3347
BAYER2(row,col) = tot/n;
3350
fprintf (stderr,_("Fixed dead pixels at:"));
3351
fprintf (stderr, " %d,%d", col, row);
3354
if (fixed) fputc ('\n', stderr);
3358
void CLASS subtract (const char *fname)
3361
int dim[3]={0,0,0}, comment=0, number=0, error=0, nd=0, c, row, col;
3364
if (!(fp = fopen (fname, "rb"))) {
3365
perror (fname); return;
3367
if (fgetc(fp) != 'P' || fgetc(fp) != '5') error = 1;
3368
while (!error && nd < 3 && (c = fgetc(fp)) != EOF) {
3369
if (c == '#') comment = 1;
3370
if (c == '\n') comment = 0;
3371
if (comment) continue;
3372
if (isdigit(c)) number = 1;
3374
if (isdigit(c)) dim[nd] = dim[nd]*10 + c -'0';
3375
else if (isspace(c)) {
3380
if (error || nd < 3) {
3381
fprintf (stderr,_("%s is not a valid PGM file!\n"), fname);
3382
fclose (fp); return;
3383
} else if (dim[0] != width || dim[1] != height || dim[2] != 65535) {
3384
fprintf (stderr,_("%s has the wrong dimensions!\n"), fname);
3385
fclose (fp); return;
3387
pixel = (ushort *) calloc (width, sizeof *pixel);
3388
merror (pixel, "subtract()");
3389
for (row=0; row < height; row++) {
3390
fread (pixel, 2, width, fp);
3391
for (col=0; col < width; col++)
3392
BAYER(row,col) = MAX (BAYER(row,col) - ntohs(pixel[col]), 0);
3398
void CLASS gamma_curve (double pwr, double ts, int mode, int imax)
3401
double g[6], bnd[2]={0,0}, r;
3405
g[2] = g[3] = g[4] = 0;
3407
if (g[1] && (g[1]-1)*(g[0]-1) <= 0) {
3408
for (i=0; i < 48; i++) {
3409
g[2] = (bnd[0] + bnd[1])/2;
3410
if (g[0]) bnd[(pow(g[2]/g[1],-g[0]) - 1)/g[0] - 1/g[2] > -1] = g[2];
3411
else bnd[g[2]/exp(1-1/g[2]) < g[1]] = g[2];
3414
if (g[0]) g[4] = g[2] * (1/g[0] - 1);
3416
if (g[0]) g[5] = 1 / (g[1]*SQR(g[3])/2 - g[4]*(1 - g[3]) +
3417
(1 - pow(g[3],1+g[0]))*(1 + g[4])/(1 + g[0])) - 1;
3418
else g[5] = 1 / (g[1]*SQR(g[3])/2 + 1
3419
- g[2] - g[3] - g[2]*g[3]*(log(g[3]) - 1)) - 1;
3421
memcpy (gamm, g, sizeof gamm);
3424
for (i=0; i < 0x10000; i++) {
3426
if ((r = (double) i / imax) < 1)
3427
curve[i] = 0x10000 * ( mode
3428
? (r < g[3] ? r*g[1] : (g[0] ? pow( r,g[0])*(1+g[4])-g[4] : log(r)*g[2]+1))
3429
: (r < g[2] ? r/g[1] : (g[0] ? pow((r+g[4])/(1+g[4]),1/g[0]) : exp((r-1)/g[2]))));
3433
void CLASS pseudoinverse (double (*in)[3], double (*out)[3], int size)
3435
double work[3][6], num;
3438
for (i=0; i < 3; i++) {
3439
for (j=0; j < 6; j++)
3440
work[i][j] = j == i+3;
3441
for (j=0; j < 3; j++)
3442
for (k=0; k < size; k++)
3443
work[i][j] += in[k][i] * in[k][j];
3445
for (i=0; i < 3; i++) {
3447
for (j=0; j < 6; j++)
3449
for (k=0; k < 3; k++) {
3452
for (j=0; j < 6; j++)
3453
work[k][j] -= work[i][j] * num;
3456
for (i=0; i < size; i++)
3457
for (j=0; j < 3; j++)
3458
for (out[i][j]=k=0; k < 3; k++)
3459
out[i][j] += work[j][k+3] * in[i][k];
3462
void CLASS cam_xyz_coeff (double cam_xyz[4][3])
3464
double cam_rgb[4][3], inverse[4][3], num;
3467
for (i=0; i < colors; i++) /* Multiply out XYZ colorspace */
3468
for (j=0; j < 3; j++)
3469
for (cam_rgb[i][j] = k=0; k < 3; k++)
3470
cam_rgb[i][j] += cam_xyz[i][k] * xyz_rgb[k][j];
3472
for (i=0; i < colors; i++) { /* Normalize cam_rgb so that */
3473
for (num=j=0; j < 3; j++) /* cam_rgb * (1,1,1) is (1,1,1,1) */
3474
num += cam_rgb[i][j];
3475
for (j=0; j < 3; j++)
3476
cam_rgb[i][j] /= num;
3477
pre_mul[i] = 1 / num;
3479
pseudoinverse (cam_rgb, inverse, colors);
3480
for (raw_color = i=0; i < 3; i++)
3481
for (j=0; j < colors; j++)
3482
rgb_cam[i][j] = inverse[j][i];
3486
void CLASS colorcheck()
3489
// Coordinates of the GretagMacbeth ColorChecker squares
3490
// width, height, 1st_column, 1st_row
3491
int cut[NSQ][4]; // you must set these
3492
// ColorChecker Chart under 6500-kelvin illumination
3493
static const double gmb_xyY[NSQ][3] = {
3494
{ 0.400, 0.350, 10.1 }, // Dark Skin
3495
{ 0.377, 0.345, 35.8 }, // Light Skin
3496
{ 0.247, 0.251, 19.3 }, // Blue Sky
3497
{ 0.337, 0.422, 13.3 }, // Foliage
3498
{ 0.265, 0.240, 24.3 }, // Blue Flower
3499
{ 0.261, 0.343, 43.1 }, // Bluish Green
3500
{ 0.506, 0.407, 30.1 }, // Orange
3501
{ 0.211, 0.175, 12.0 }, // Purplish Blue
3502
{ 0.453, 0.306, 19.8 }, // Moderate Red
3503
{ 0.285, 0.202, 6.6 }, // Purple
3504
{ 0.380, 0.489, 44.3 }, // Yellow Green
3505
{ 0.473, 0.438, 43.1 }, // Orange Yellow
3506
{ 0.187, 0.129, 6.1 }, // Blue
3507
{ 0.305, 0.478, 23.4 }, // Green
3508
{ 0.539, 0.313, 12.0 }, // Red
3509
{ 0.448, 0.470, 59.1 }, // Yellow
3510
{ 0.364, 0.233, 19.8 }, // Magenta
3511
{ 0.196, 0.252, 19.8 }, // Cyan
3512
{ 0.310, 0.316, 90.0 }, // White
3513
{ 0.310, 0.316, 59.1 }, // Neutral 8
3514
{ 0.310, 0.316, 36.2 }, // Neutral 6.5
3515
{ 0.310, 0.316, 19.8 }, // Neutral 5
3516
{ 0.310, 0.316, 9.0 }, // Neutral 3.5
3517
{ 0.310, 0.316, 3.1 } }; // Black
3518
double gmb_cam[NSQ][4], gmb_xyz[NSQ][3];
3519
double inverse[NSQ][3], cam_xyz[4][3], num;
3520
int c, i, j, k, sq, row, col, count[4];
3522
memset (gmb_cam, 0, sizeof gmb_cam);
3523
for (sq=0; sq < NSQ; sq++) {
3525
for (row=cut[sq][3]; row < cut[sq][3]+cut[sq][1]; row++)
3526
for (col=cut[sq][2]; col < cut[sq][2]+cut[sq][0]; col++) {
3528
if (c >= colors) c -= 2;
3529
gmb_cam[sq][c] += BAYER(row,col);
3532
FORCC gmb_cam[sq][c] = gmb_cam[sq][c]/count[c] - black;
3533
gmb_xyz[sq][0] = gmb_xyY[sq][2] * gmb_xyY[sq][0] / gmb_xyY[sq][1];
3534
gmb_xyz[sq][1] = gmb_xyY[sq][2];
3535
gmb_xyz[sq][2] = gmb_xyY[sq][2] *
3536
(1 - gmb_xyY[sq][0] - gmb_xyY[sq][1]) / gmb_xyY[sq][1];
3538
pseudoinverse (gmb_xyz, inverse, NSQ);
3539
for (i=0; i < colors; i++)
3540
for (j=0; j < 3; j++)
3541
for (cam_xyz[i][j] = k=0; k < NSQ; k++)
3542
cam_xyz[i][j] += gmb_cam[k][i] * inverse[k][j];
3543
cam_xyz_coeff (cam_xyz);
3545
printf (" { \"%s %s\", %d,\n\t{", make, model, black);
3546
num = 10000 / (cam_xyz[1][0] + cam_xyz[1][1] + cam_xyz[1][2]);
3547
FORCC for (j=0; j < 3; j++)
3548
printf ("%c%d", (c | j) ? ',':' ', (int) (cam_xyz[c][j] * num + 0.5));
3555
void CLASS hat_transform (float *temp, float *base, int st, int size, int sc)
3558
for (i=0; i < sc; i++)
3559
temp[i] = 2*base[st*i] + base[st*(sc-i)] + base[st*(i+sc)];
3560
for (; i+sc < size; i++)
3561
temp[i] = 2*base[st*i] + base[st*(i-sc)] + base[st*(i+sc)];
3562
for (; i < size; i++)
3563
temp[i] = 2*base[st*i] + base[st*(i-sc)] + base[st*(2*size-2-(i+sc))];
3566
void CLASS wavelet_denoise()
3568
float *fimg=0, *temp, thold, mul[2], avg, diff;
3569
int scale=1, size, lev, hpass, lpass, row, col, nc, c, i, wlast;
3571
static const float noise[] =
3572
{ 0.8002,0.2735,0.1202,0.0585,0.0291,0.0152,0.0080,0.0044 };
3574
if (verbose) fprintf (stderr,_("Wavelet denoising...\n"));
3576
while (maximum << scale < 0x10000) scale++;
3577
maximum <<= --scale;
3579
if ((size = iheight*iwidth) < 0x15550000)
3580
fimg = (float *) malloc ((size*3 + iheight + iwidth) * sizeof *fimg);
3581
merror (fimg, "wavelet_denoise()");
3582
temp = fimg + size*3;
3583
if ((nc = colors) == 3 && filters) nc++;
3584
FORC(nc) { /* denoise R,G1,B,G3 individually */
3585
for (i=0; i < size; i++)
3586
fimg[i] = 256 * sqrt(image[i][c] << scale);
3587
for (hpass=lev=0; lev < 5; lev++) {
3588
lpass = size*((lev & 1)+1);
3589
for (row=0; row < iheight; row++) {
3590
hat_transform (temp, fimg+hpass+row*iwidth, 1, iwidth, 1 << lev);
3591
for (col=0; col < iwidth; col++)
3592
fimg[lpass + row*iwidth + col] = temp[col] * 0.25;
3594
for (col=0; col < iwidth; col++) {
3595
hat_transform (temp, fimg+lpass+col, iwidth, iheight, 1 << lev);
3596
for (row=0; row < iheight; row++)
3597
fimg[lpass + row*iwidth + col] = temp[row] * 0.25;
3599
thold = threshold * noise[lev];
3600
for (i=0; i < size; i++) {
3601
fimg[hpass+i] -= fimg[lpass+i];
3602
if (fimg[hpass+i] < -thold) fimg[hpass+i] += thold;
3603
else if (fimg[hpass+i] > thold) fimg[hpass+i] -= thold;
3604
else fimg[hpass+i] = 0;
3605
if (hpass) fimg[i] += fimg[hpass+i];
3609
for (i=0; i < size; i++)
3610
image[i][c] = CLIP(SQR(fimg[i]+fimg[lpass+i])/0x10000);
3612
if (filters && colors == 3) { /* pull G1 and G3 closer together */
3613
for (row=0; row < 2; row++)
3614
mul[row] = 0.125 * pre_mul[FC(row+1,0) | 1] / pre_mul[FC(row,0) | 1];
3615
for (i=0; i < 4; i++)
3616
window[i] = (ushort *) fimg + width*i;
3617
for (wlast=-1, row=1; row < height-1; row++) {
3618
while (wlast < row+1) {
3619
for (wlast++, i=0; i < 4; i++)
3620
window[(i+3) & 3] = window[i];
3621
for (col = FC(wlast,1) & 1; col < width; col+=2)
3622
window[2][col] = BAYER(wlast,col);
3624
thold = threshold/512;
3625
for (col = (FC(row,0) & 1)+1; col < width-1; col+=2) {
3626
avg = ( window[0][col-1] + window[0][col+1] +
3627
window[2][col-1] + window[2][col+1] - black*4 )
3628
* mul[row & 1] + (window[1][col] - black) * 0.5 + black;
3629
avg = avg < 0 ? 0 : sqrt(avg);
3630
diff = sqrt(BAYER(row,col)) - avg;
3631
if (diff < -thold) diff += thold;
3632
else if (diff > thold) diff -= thold;
3634
BAYER(row,col) = CLIP(SQR(avg+diff) + 0.5);
3641
void CLASS scale_colors()
3643
unsigned bottom, right, size, row, col, ur, uc, i, x, y, c, sum[8];
3645
double dsum[8], dmin, dmax;
3646
float scale_mul[4], fr, fc;
3647
ushort *img=0, *pix;
3650
memcpy (pre_mul, user_mul, sizeof pre_mul);
3651
if (use_auto_wb || (use_camera_wb && cam_mul[0] == -1)) {
3652
memset (dsum, 0, sizeof dsum);
3653
bottom = MIN (greybox[1]+greybox[3], height);
3654
right = MIN (greybox[0]+greybox[2], width);
3655
for (row=greybox[1]; row < bottom; row += 8)
3656
for (col=greybox[0]; col < right; col += 8) {
3657
memset (sum, 0, sizeof sum);
3658
for (y=row; y < row+8 && y < bottom; y++)
3659
for (x=col; x < col+8 && x < right; x++)
3665
val = image[y*width+x][c];
3666
if (val > maximum-25) goto skip_block;
3667
if ((val -= black) < 0) val = 0;
3672
FORC(8) dsum[c] += sum[c];
3675
FORC4 if (dsum[c]) pre_mul[c] = dsum[c+4] / dsum[c];
3677
if (use_camera_wb && cam_mul[0] != -1) {
3678
memset (sum, 0, sizeof sum);
3679
for (row=0; row < 8; row++)
3680
for (col=0; col < 8; col++) {
3682
if ((val = white[row][col] - black) > 0)
3686
if (sum[0] && sum[1] && sum[2] && sum[3])
3687
FORC4 pre_mul[c] = (float) sum[c+4] / sum[c];
3688
else if (cam_mul[0] && cam_mul[2])
3689
memcpy (pre_mul, cam_mul, sizeof pre_mul);
3691
fprintf (stderr,_("%s: Cannot use camera white balance.\n"), ifname);
3693
if (pre_mul[3] == 0) pre_mul[3] = colors < 4 ? pre_mul[1] : 1;
3696
if (threshold) wavelet_denoise();
3698
for (dmin=DBL_MAX, dmax=c=0; c < 4; c++) {
3699
if (dmin > pre_mul[c])
3701
if (dmax < pre_mul[c])
3704
if (!highlight) dmax = dmin;
3705
FORC4 scale_mul[c] = (pre_mul[c] /= dmax) * 65535.0 / maximum;
3708
_("Scaling with darkness %d, saturation %d, and\nmultipliers"), dark, sat);
3709
FORC4 fprintf (stderr, " %f", pre_mul[c]);
3710
fputc ('\n', stderr);
3712
size = iheight*iwidth;
3713
for (i=0; i < size*4; i++) {
3717
val *= scale_mul[i & 3];
3718
image[0][i] = CLIP(val);
3720
if ((aber[0] != 1 || aber[2] != 1) && colors == 3) {
3722
fprintf (stderr,_("Correcting chromatic aberration...\n"));
3723
for (c=0; c < 4; c+=2) {
3724
if (aber[c] == 1) continue;
3725
img = (ushort *) malloc (size * sizeof *img);
3726
merror (img, "scale_colors()");
3727
for (i=0; i < size; i++)
3728
img[i] = image[i][c];
3729
for (row=0; row < iheight; row++) {
3730
ur = fr = (row - iheight*0.5) * aber[c] + iheight*0.5;
3731
if (ur > iheight-2) continue;
3733
for (col=0; col < iwidth; col++) {
3734
uc = fc = (col - iwidth*0.5) * aber[c] + iwidth*0.5;
3735
if (uc > iwidth-2) continue;
3737
pix = img + ur*iwidth + uc;
3738
image[row*iwidth+col][c] =
3739
(pix[ 0]*(1-fc) + pix[ 1]*fc) * (1-fr) +
3740
(pix[iwidth]*(1-fc) + pix[iwidth+1]*fc) * fr;
3748
void CLASS pre_interpolate()
3758
img = (ushort (*)[4]) calloc (height*width, sizeof *img);
3759
merror (img, "pre_interpolate()");
3760
for (row=0; row < height; row++)
3761
for (col=0; col < width; col++) {
3763
img[row*width+col][c] = image[(row >> 1)*iwidth+(col >> 1)][c];
3770
if (filters && colors == 3) {
3771
if ((mix_green = four_color_rgb)) colors++;
3773
for (row = FC(1,0) >> 1; row < height; row+=2)
3774
for (col = FC(row,1) & 1; col < width; col+=2)
3775
image[row*width+col][1] = image[row*width+col][3];
3776
filters &= ~((filters & 0x55555555) << 1);
3779
if (half_size) filters = 0;
3782
void CLASS border_interpolate (int border)
3784
unsigned row, col, y, x, f, c, sum[8];
3786
for (row=0; row < height; row++)
3787
for (col=0; col < width; col++) {
3788
if (col==border && row >= border && row < height-border)
3790
memset (sum, 0, sizeof sum);
3791
for (y=row-1; y != row+2; y++)
3792
for (x=col-1; x != col+2; x++)
3793
if (y < height && x < width) {
3795
sum[f] += image[y*width+x][f];
3799
FORCC if (c != f && sum[c+4])
3800
image[row*width+col][c] = sum[c] / sum[c+4];
3804
void CLASS lin_interpolate()
3806
int code[16][16][32], *ip, sum[4];
3807
int c, i, x, y, row, col, shift, color;
3810
if (verbose) fprintf (stderr,_("Bilinear interpolation...\n"));
3812
border_interpolate(1);
3813
for (row=0; row < 16; row++)
3814
for (col=0; col < 16; col++) {
3815
ip = code[row][col];
3816
memset (sum, 0, sizeof sum);
3817
for (y=-1; y <= 1; y++)
3818
for (x=-1; x <= 1; x++) {
3819
shift = (y==0) + (x==0);
3820
if (shift == 2) continue;
3821
color = fc(row+y,col+x);
3822
*ip++ = (width*y + x)*4 + color;
3825
sum[color] += 1 << shift;
3828
if (c != fc(row,col)) {
3830
*ip++ = 256 / sum[c];
3833
for (row=1; row < height-1; row++)
3834
for (col=1; col < width-1; col++) {
3835
pix = image[row*width+col];
3836
ip = code[row & 15][col & 15];
3837
memset (sum, 0, sizeof sum);
3838
for (i=8; i--; ip+=3)
3839
sum[ip[2]] += pix[ip[0]] << ip[1];
3840
for (i=colors; --i; ip+=2)
3841
pix[ip[0]] = sum[ip[0]] * ip[1] >> 8;
3846
This algorithm is officially called:
3848
"Interpolation using a Threshold-based variable number of gradients"
3850
described in http://scien.stanford.edu/class/psych221/projects/99/tingchen/algodep/vargra.html
3852
I've extended the basic idea to work with non-Bayer filter arrays.
3853
Gradients are numbered clockwise from NW=0 to W=7.
3855
void CLASS vng_interpolate()
3857
static const signed char *cp, terms[] = {
3858
-2,-2,+0,-1,0,0x01, -2,-2,+0,+0,1,0x01, -2,-1,-1,+0,0,0x01,
3859
-2,-1,+0,-1,0,0x02, -2,-1,+0,+0,0,0x03, -2,-1,+0,+1,1,0x01,
3860
-2,+0,+0,-1,0,0x06, -2,+0,+0,+0,1,0x02, -2,+0,+0,+1,0,0x03,
3861
-2,+1,-1,+0,0,0x04, -2,+1,+0,-1,1,0x04, -2,+1,+0,+0,0,0x06,
3862
-2,+1,+0,+1,0,0x02, -2,+2,+0,+0,1,0x04, -2,+2,+0,+1,0,0x04,
3863
-1,-2,-1,+0,0,0x80, -1,-2,+0,-1,0,0x01, -1,-2,+1,-1,0,0x01,
3864
-1,-2,+1,+0,1,0x01, -1,-1,-1,+1,0,0x88, -1,-1,+1,-2,0,0x40,
3865
-1,-1,+1,-1,0,0x22, -1,-1,+1,+0,0,0x33, -1,-1,+1,+1,1,0x11,
3866
-1,+0,-1,+2,0,0x08, -1,+0,+0,-1,0,0x44, -1,+0,+0,+1,0,0x11,
3867
-1,+0,+1,-2,1,0x40, -1,+0,+1,-1,0,0x66, -1,+0,+1,+0,1,0x22,
3868
-1,+0,+1,+1,0,0x33, -1,+0,+1,+2,1,0x10, -1,+1,+1,-1,1,0x44,
3869
-1,+1,+1,+0,0,0x66, -1,+1,+1,+1,0,0x22, -1,+1,+1,+2,0,0x10,
3870
-1,+2,+0,+1,0,0x04, -1,+2,+1,+0,1,0x04, -1,+2,+1,+1,0,0x04,
3871
+0,-2,+0,+0,1,0x80, +0,-1,+0,+1,1,0x88, +0,-1,+1,-2,0,0x40,
3872
+0,-1,+1,+0,0,0x11, +0,-1,+2,-2,0,0x40, +0,-1,+2,-1,0,0x20,
3873
+0,-1,+2,+0,0,0x30, +0,-1,+2,+1,1,0x10, +0,+0,+0,+2,1,0x08,
3874
+0,+0,+2,-2,1,0x40, +0,+0,+2,-1,0,0x60, +0,+0,+2,+0,1,0x20,
3875
+0,+0,+2,+1,0,0x30, +0,+0,+2,+2,1,0x10, +0,+1,+1,+0,0,0x44,
3876
+0,+1,+1,+2,0,0x10, +0,+1,+2,-1,1,0x40, +0,+1,+2,+0,0,0x60,
3877
+0,+1,+2,+1,0,0x20, +0,+1,+2,+2,0,0x10, +1,-2,+1,+0,0,0x80,
3878
+1,-1,+1,+1,0,0x88, +1,+0,+1,+2,0,0x08, +1,+0,+2,-1,0,0x40,
3880
}, chood[] = { -1,-1, -1,0, -1,+1, 0,+1, +1,+1, +1,0, +1,-1, 0,-1 };
3881
ushort (*brow[5])[4], *pix;
3882
int prow=7, pcol=1, *ip, *code[16][16], gval[8], gmin, gmax, sum[4];
3883
int row, col, x, y, x1, x2, y1, y2, t, weight, grads, color, diag;
3884
int g, diff, thold, num, c;
3887
if (verbose) fprintf (stderr,_("VNG interpolation...\n"));
3889
if (filters == 1) prow = pcol = 15;
3890
ip = (int *) calloc ((prow+1)*(pcol+1), 1280);
3891
merror (ip, "vng_interpolate()");
3892
for (row=0; row <= prow; row++) /* Precalculate for VNG */
3893
for (col=0; col <= pcol; col++) {
3894
code[row][col] = ip;
3895
for (cp=terms, t=0; t < 64; t++) {
3896
y1 = *cp++; x1 = *cp++;
3897
y2 = *cp++; x2 = *cp++;
3900
color = fc(row+y1,col+x1);
3901
if (fc(row+y2,col+x2) != color) continue;
3902
diag = (fc(row,col+1) == color && fc(row+1,col) == color) ? 2:1;
3903
if (abs(y1-y2) == diag && abs(x1-x2) == diag) continue;
3904
*ip++ = (y1*width + x1)*4 + color;
3905
*ip++ = (y2*width + x2)*4 + color;
3907
for (g=0; g < 8; g++)
3908
if (grads & 1<<g) *ip++ = g;
3912
for (cp=chood, g=0; g < 8; g++) {
3913
y = *cp++; x = *cp++;
3914
*ip++ = (y*width + x) * 4;
3915
color = fc(row,col);
3916
if (fc(row+y,col+x) != color && fc(row+y*2,col+x*2) == color)
3917
*ip++ = (y*width + x) * 8 + color;
3922
brow[4] = (ushort (*)[4]) calloc (width*3, sizeof **brow);
3923
merror (brow[4], "vng_interpolate()");
3924
for (row=0; row < 3; row++)
3925
brow[row] = brow[4] + row*width;
3926
for (row=2; row < height-2; row++) { /* Do VNG interpolation */
3927
for (col=2; col < width-2; col++) {
3928
pix = image[row*width+col];
3929
ip = code[row & prow][col & pcol];
3930
memset (gval, 0, sizeof gval);
3931
while ((g = ip[0]) != INT_MAX) { /* Calculate gradients */
3932
diff = ABS(pix[g] - pix[ip[1]]) << ip[2];
3933
gval[ip[3]] += diff;
3935
if ((g = ip[-1]) == -1) continue;
3937
while ((g = *ip++) != -1)
3941
gmin = gmax = gval[0]; /* Choose a threshold */
3942
for (g=1; g < 8; g++) {
3943
if (gmin > gval[g]) gmin = gval[g];
3944
if (gmax < gval[g]) gmax = gval[g];
3947
memcpy (brow[2][col], pix, sizeof *image);
3950
thold = gmin + (gmax >> 1);
3951
memset (sum, 0, sizeof sum);
3952
color = fc(row,col);
3953
for (num=g=0; g < 8; g++,ip+=2) { /* Average the neighbors */
3954
if (gval[g] <= thold) {
3956
if (c == color && ip[1])
3957
sum[c] += (pix[c] + pix[ip[1]]) >> 1;
3959
sum[c] += pix[ip[0] + c];
3963
FORCC { /* Save to buffer */
3966
t += (sum[c] - sum[color]) / num;
3967
brow[2][col][c] = CLIP(t);
3970
if (row > 3) /* Write buffer to image */
3971
memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image);
3972
for (g=0; g < 4; g++)
3973
brow[(g-1) & 3] = brow[g];
3975
memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image);
3976
memcpy (image[(row-1)*width+2], brow[1]+2, (width-4)*sizeof *image);
3982
Patterned Pixel Grouping Interpolation by Alain Desbiolles
3984
void CLASS ppg_interpolate()
3986
int dir[5] = { 1, width, -1, -width, 1 };
3987
int row, col, diff[2], guess[2], c, d, i;
3990
border_interpolate(3);
3991
if (verbose) fprintf (stderr,_("PPG interpolation...\n"));
3993
/* Fill in the green layer with gradients and pattern recognition: */
3994
for (row=3; row < height-3; row++)
3995
for (col=3+(FC(row,3) & 1), c=FC(row,col); col < width-3; col+=2) {
3996
pix = image + row*width+col;
3997
for (i=0; (d=dir[i]) > 0; i++) {
3998
guess[i] = (pix[-d][1] + pix[0][c] + pix[d][1]) * 2
3999
- pix[-2*d][c] - pix[2*d][c];
4000
diff[i] = ( ABS(pix[-2*d][c] - pix[ 0][c]) +
4001
ABS(pix[ 2*d][c] - pix[ 0][c]) +
4002
ABS(pix[ -d][1] - pix[ d][1]) ) * 3 +
4003
( ABS(pix[ 3*d][1] - pix[ d][1]) +
4004
ABS(pix[-3*d][1] - pix[-d][1]) ) * 2;
4006
d = dir[i = diff[0] > diff[1]];
4007
pix[0][1] = ULIM(guess[i] >> 2, pix[d][1], pix[-d][1]);
4009
/* Calculate red and blue for each green pixel: */
4010
for (row=1; row < height-1; row++)
4011
for (col=1+(FC(row,2) & 1), c=FC(row,col+1); col < width-1; col+=2) {
4012
pix = image + row*width+col;
4013
for (i=0; (d=dir[i]) > 0; c=2-c, i++)
4014
pix[0][c] = CLIP((pix[-d][c] + pix[d][c] + 2*pix[0][1]
4015
- pix[-d][1] - pix[d][1]) >> 1);
4017
/* Calculate blue for red pixels and vice versa: */
4018
for (row=1; row < height-1; row++)
4019
for (col=1+(FC(row,1) & 1), c=2-FC(row,col); col < width-1; col+=2) {
4020
pix = image + row*width+col;
4021
for (i=0; (d=dir[i]+dir[i+1]) > 0; i++) {
4022
diff[i] = ABS(pix[-d][c] - pix[d][c]) +
4023
ABS(pix[-d][1] - pix[0][1]) +
4024
ABS(pix[ d][1] - pix[0][1]);
4025
guess[i] = pix[-d][c] + pix[d][c] + 2*pix[0][1]
4026
- pix[-d][1] - pix[d][1];
4028
if (diff[0] != diff[1])
4029
pix[0][c] = CLIP(guess[diff[0] > diff[1]] >> 1);
4031
pix[0][c] = CLIP((guess[0]+guess[1]) >> 2);
4036
Adaptive Homogeneity-Directed interpolation is based on
4037
the work of Keigo Hirakawa, Thomas Parks, and Paul Lee.
4039
#define TS 256 /* Tile Size */
4041
void CLASS ahd_interpolate()
4043
int i, j, k, top, left, row, col, tr, tc, c, d, val, hm[2];
4044
ushort (*pix)[4], (*rix)[3];
4045
static const int dir[4] = { -1, 1, -TS, TS };
4046
unsigned ldiff[2][4], abdiff[2][4], leps, abeps;
4047
float r, cbrt[0x10000], xyz[3], xyz_cam[3][4];
4048
ushort (*rgb)[TS][TS][3];
4049
short (*lab)[TS][TS][3], (*lix)[3];
4050
char (*homo)[TS][TS], *buffer;
4052
if (verbose) fprintf (stderr,_("AHD interpolation...\n"));
4054
for (i=0; i < 0x10000; i++) {
4056
cbrt[i] = r > 0.008856 ? pow(r,1/3.0) : 7.787*r + 16/116.0;
4058
for (i=0; i < 3; i++)
4059
for (j=0; j < colors; j++)
4060
for (xyz_cam[i][j] = k=0; k < 3; k++)
4061
xyz_cam[i][j] += xyz_rgb[i][k] * rgb_cam[k][j] / d65_white[i];
4063
border_interpolate(5);
4064
buffer = (char *) malloc (26*TS*TS); /* 1664 kB */
4065
merror (buffer, "ahd_interpolate()");
4066
rgb = (ushort(*)[TS][TS][3]) buffer;
4067
lab = (short (*)[TS][TS][3])(buffer + 12*TS*TS);
4068
homo = (char (*)[TS][TS]) (buffer + 24*TS*TS);
4070
for (top=2; top < height-5; top += TS-6)
4071
for (left=2; left < width-5; left += TS-6) {
4073
/* Interpolate green horizontally and vertically: */
4074
for (row = top; row < top+TS && row < height-2; row++) {
4075
col = left + (FC(row,left) & 1);
4076
for (c = FC(row,col); col < left+TS && col < width-2; col+=2) {
4077
pix = image + row*width+col;
4078
val = ((pix[-1][1] + pix[0][c] + pix[1][1]) * 2
4079
- pix[-2][c] - pix[2][c]) >> 2;
4080
rgb[0][row-top][col-left][1] = ULIM(val,pix[-1][1],pix[1][1]);
4081
val = ((pix[-width][1] + pix[0][c] + pix[width][1]) * 2
4082
- pix[-2*width][c] - pix[2*width][c]) >> 2;
4083
rgb[1][row-top][col-left][1] = ULIM(val,pix[-width][1],pix[width][1]);
4086
/* Interpolate red and blue, and convert to CIELab: */
4087
for (d=0; d < 2; d++)
4088
for (row=top+1; row < top+TS-1 && row < height-3; row++)
4089
for (col=left+1; col < left+TS-1 && col < width-3; col++) {
4090
pix = image + row*width+col;
4091
rix = &rgb[d][row-top][col-left];
4092
lix = &lab[d][row-top][col-left];
4093
if ((c = 2 - FC(row,col)) == 1) {
4095
val = pix[0][1] + (( pix[-1][2-c] + pix[1][2-c]
4096
- rix[-1][1] - rix[1][1] ) >> 1);
4097
rix[0][2-c] = CLIP(val);
4098
val = pix[0][1] + (( pix[-width][c] + pix[width][c]
4099
- rix[-TS][1] - rix[TS][1] ) >> 1);
4101
val = rix[0][1] + (( pix[-width-1][c] + pix[-width+1][c]
4102
+ pix[+width-1][c] + pix[+width+1][c]
4103
- rix[-TS-1][1] - rix[-TS+1][1]
4104
- rix[+TS-1][1] - rix[+TS+1][1] + 1) >> 2);
4105
rix[0][c] = CLIP(val);
4107
rix[0][c] = pix[0][c];
4108
xyz[0] = xyz[1] = xyz[2] = 0.5;
4110
xyz[0] += xyz_cam[0][c] * rix[0][c];
4111
xyz[1] += xyz_cam[1][c] * rix[0][c];
4112
xyz[2] += xyz_cam[2][c] * rix[0][c];
4114
xyz[0] = cbrt[CLIP((int) xyz[0])];
4115
xyz[1] = cbrt[CLIP((int) xyz[1])];
4116
xyz[2] = cbrt[CLIP((int) xyz[2])];
4117
lix[0][0] = 64 * (116 * xyz[1] - 16);
4118
lix[0][1] = 64 * 500 * (xyz[0] - xyz[1]);
4119
lix[0][2] = 64 * 200 * (xyz[1] - xyz[2]);
4121
/* Build homogeneity maps from the CIELab images: */
4122
memset (homo, 0, 2*TS*TS);
4123
for (row=top+2; row < top+TS-2 && row < height-4; row++) {
4125
for (col=left+2; col < left+TS-2 && col < width-4; col++) {
4127
for (d=0; d < 2; d++) {
4128
lix = &lab[d][tr][tc];
4129
for (i=0; i < 4; i++) {
4130
ldiff[d][i] = ABS(lix[0][0]-lix[dir[i]][0]);
4131
abdiff[d][i] = SQR(lix[0][1]-lix[dir[i]][1])
4132
+ SQR(lix[0][2]-lix[dir[i]][2]);
4135
leps = MIN(MAX(ldiff[0][0],ldiff[0][1]),
4136
MAX(ldiff[1][2],ldiff[1][3]));
4137
abeps = MIN(MAX(abdiff[0][0],abdiff[0][1]),
4138
MAX(abdiff[1][2],abdiff[1][3]));
4139
for (d=0; d < 2; d++)
4140
for (i=0; i < 4; i++)
4141
if (ldiff[d][i] <= leps && abdiff[d][i] <= abeps)
4145
/* Combine the most homogenous pixels for the final result: */
4146
for (row=top+3; row < top+TS-3 && row < height-5; row++) {
4148
for (col=left+3; col < left+TS-3 && col < width-5; col++) {
4150
for (d=0; d < 2; d++)
4151
for (hm[d]=0, i=tr-1; i <= tr+1; i++)
4152
for (j=tc-1; j <= tc+1; j++)
4153
hm[d] += homo[d][i][j];
4155
FORC3 image[row*width+col][c] = rgb[hm[1] > hm[0]][tr][tc][c];
4157
FORC3 image[row*width+col][c] =
4158
(rgb[0][tr][tc][c] + rgb[1][tr][tc][c]) >> 1;
4166
void CLASS median_filter()
4169
int pass, c, i, j, k, med[9];
4170
static const uchar opt[] = /* Optimal 9-element median search */
4171
{ 1,2, 4,5, 7,8, 0,1, 3,4, 6,7, 1,2, 4,5, 7,8,
4172
0,3, 5,8, 4,7, 3,6, 1,4, 2,5, 4,7, 4,2, 6,4, 4,2 };
4174
for (pass=1; pass <= med_passes; pass++) {
4176
fprintf (stderr,_("Median filter pass %d...\n"), pass);
4177
for (c=0; c < 3; c+=2) {
4178
for (pix = image; pix < image+width*height; pix++)
4179
pix[0][3] = pix[0][c];
4180
for (pix = image+width; pix < image+width*(height-1); pix++) {
4181
if ((pix-image+1) % width < 2) continue;
4182
for (k=0, i = -width; i <= width; i += width)
4183
for (j = i-1; j <= i+1; j++)
4184
med[k++] = pix[j][3] - pix[j][1];
4185
for (i=0; i < sizeof opt; i+=2)
4186
if (med[opt[i]] > med[opt[i+1]])
4187
SWAP (med[opt[i]] , med[opt[i+1]]);
4188
pix[0][c] = CLIP(med[4] + pix[0][1]);
4194
void CLASS blend_highlights()
4196
int clip=INT_MAX, row, col, c, i, j;
4197
static const float trans[2][4][4] =
4198
{ { { 1,1,1 }, { 1.7320508,-1.7320508,0 }, { -1,-1,2 } },
4199
{ { 1,1,1,1 }, { 1,-1,1,-1 }, { 1,1,-1,-1 }, { 1,-1,-1,1 } } };
4200
static const float itrans[2][4][4] =
4201
{ { { 1,0.8660254,-0.5 }, { 1,-0.8660254,-0.5 }, { 1,0,1 } },
4202
{ { 1,1,1,1 }, { 1,-1,1,-1 }, { 1,1,-1,-1 }, { 1,-1,-1,1 } } };
4203
float cam[2][4], lab[2][4], sum[2], chratio;
4205
if ((unsigned) (colors-3) > 1) return;
4206
if (verbose) fprintf (stderr,_("Blending highlights...\n"));
4207
FORCC if (clip > (i = 65535*pre_mul[c])) clip = i;
4208
for (row=0; row < height; row++)
4209
for (col=0; col < width; col++) {
4210
FORCC if (image[row*width+col][c] > clip) break;
4211
if (c == colors) continue;
4213
cam[0][c] = image[row*width+col][c];
4214
cam[1][c] = MIN(cam[0][c],clip);
4216
for (i=0; i < 2; i++) {
4217
FORCC for (lab[i][c]=j=0; j < colors; j++)
4218
lab[i][c] += trans[colors-3][c][j] * cam[i][j];
4219
for (sum[i]=0,c=1; c < colors; c++)
4220
sum[i] += SQR(lab[i][c]);
4222
chratio = sqrt(sum[1]/sum[0]);
4223
for (c=1; c < colors; c++)
4224
lab[0][c] *= chratio;
4225
FORCC for (cam[0][c]=j=0; j < colors; j++)
4226
cam[0][c] += itrans[colors-3][c][j] * lab[0][j];
4227
FORCC image[row*width+col][c] = cam[0][c] / colors;
4231
#define SCALE (4 >> shrink)
4232
void CLASS recover_highlights()
4234
float *map, sum, wgt, grow;
4235
int hsat[4], count, spread, change, val, i;
4236
unsigned high, wide, mrow, mcol, row, col, kc, c, d, y, x;
4238
static const signed char dir[8][2] =
4239
{ {-1,-1}, {-1,0}, {-1,1}, {0,1}, {1,1}, {1,0}, {1,-1}, {0,-1} };
4241
if (verbose) fprintf (stderr,_("Rebuilding highlights...\n"));
4243
grow = pow (2, 4-highlight);
4244
FORCC hsat[c] = 32000 * pre_mul[c];
4245
for (kc=0, c=1; c < colors; c++)
4246
if (pre_mul[kc] < pre_mul[c]) kc = c;
4247
high = height / SCALE;
4248
wide = width / SCALE;
4249
map = (float *) calloc (high*wide, sizeof *map);
4250
merror (map, "recover_highlights()");
4251
FORCC if (c != kc) {
4252
memset (map, 0, high*wide*sizeof *map);
4253
for (mrow=0; mrow < high; mrow++)
4254
for (mcol=0; mcol < wide; mcol++) {
4255
sum = wgt = count = 0;
4256
for (row = mrow*SCALE; row < (mrow+1)*SCALE; row++)
4257
for (col = mcol*SCALE; col < (mcol+1)*SCALE; col++) {
4258
pixel = image[row*width+col];
4259
if (pixel[c] / hsat[c] == 1 && pixel[kc] > 24000) {
4265
if (count == SCALE*SCALE)
4266
map[mrow*wide+mcol] = sum / wgt;
4268
for (spread = 32/grow; spread--; ) {
4269
for (mrow=0; mrow < high; mrow++)
4270
for (mcol=0; mcol < wide; mcol++) {
4271
if (map[mrow*wide+mcol]) continue;
4273
for (d=0; d < 8; d++) {
4274
y = mrow + dir[d][0];
4275
x = mcol + dir[d][1];
4276
if (y < high && x < wide && map[y*wide+x] > 0) {
4277
sum += (1 + (d & 1)) * map[y*wide+x];
4278
count += 1 + (d & 1);
4282
map[mrow*wide+mcol] = - (sum+grow) / (count+grow);
4284
for (change=i=0; i < high*wide; i++)
4291
for (i=0; i < high*wide; i++)
4292
if (map[i] == 0) map[i] = 1;
4293
for (mrow=0; mrow < high; mrow++)
4294
for (mcol=0; mcol < wide; mcol++) {
4295
for (row = mrow*SCALE; row < (mrow+1)*SCALE; row++)
4296
for (col = mcol*SCALE; col < (mcol+1)*SCALE; col++) {
4297
pixel = image[row*width+col];
4298
if (pixel[c] / hsat[c] > 1) {
4299
val = pixel[kc] * map[mrow*wide+mcol];
4300
if (pixel[c] < val) pixel[c] = CLIP(val);
4309
void CLASS tiff_get (unsigned base,
4310
unsigned *tag, unsigned *type, unsigned *len, unsigned *save)
4315
*save = ftell(ifp) + 4;
4316
if (*len * ("11124811248488"[*type < 14 ? *type:0]-'0') > 4)
4317
fseek (ifp, get4()+base, SEEK_SET);
4320
void CLASS parse_thumb_note (int base, unsigned toff, unsigned tlen)
4322
unsigned entries, tag, type, len, save;
4326
tiff_get (base, &tag, &type, &len, &save);
4327
if (tag == toff) thumb_offset = get4()+base;
4328
if (tag == tlen) thumb_length = get4();
4329
fseek (ifp, save, SEEK_SET);
4333
int CLASS parse_tiff_ifd (int base);
4335
void CLASS parse_makernote (int base, int uptag)
4337
static const uchar xlat[2][256] = {
4338
{ 0xc1,0xbf,0x6d,0x0d,0x59,0xc5,0x13,0x9d,0x83,0x61,0x6b,0x4f,0xc7,0x7f,0x3d,0x3d,
4339
0x53,0x59,0xe3,0xc7,0xe9,0x2f,0x95,0xa7,0x95,0x1f,0xdf,0x7f,0x2b,0x29,0xc7,0x0d,
4340
0xdf,0x07,0xef,0x71,0x89,0x3d,0x13,0x3d,0x3b,0x13,0xfb,0x0d,0x89,0xc1,0x65,0x1f,
4341
0xb3,0x0d,0x6b,0x29,0xe3,0xfb,0xef,0xa3,0x6b,0x47,0x7f,0x95,0x35,0xa7,0x47,0x4f,
4342
0xc7,0xf1,0x59,0x95,0x35,0x11,0x29,0x61,0xf1,0x3d,0xb3,0x2b,0x0d,0x43,0x89,0xc1,
4343
0x9d,0x9d,0x89,0x65,0xf1,0xe9,0xdf,0xbf,0x3d,0x7f,0x53,0x97,0xe5,0xe9,0x95,0x17,
4344
0x1d,0x3d,0x8b,0xfb,0xc7,0xe3,0x67,0xa7,0x07,0xf1,0x71,0xa7,0x53,0xb5,0x29,0x89,
4345
0xe5,0x2b,0xa7,0x17,0x29,0xe9,0x4f,0xc5,0x65,0x6d,0x6b,0xef,0x0d,0x89,0x49,0x2f,
4346
0xb3,0x43,0x53,0x65,0x1d,0x49,0xa3,0x13,0x89,0x59,0xef,0x6b,0xef,0x65,0x1d,0x0b,
4347
0x59,0x13,0xe3,0x4f,0x9d,0xb3,0x29,0x43,0x2b,0x07,0x1d,0x95,0x59,0x59,0x47,0xfb,
4348
0xe5,0xe9,0x61,0x47,0x2f,0x35,0x7f,0x17,0x7f,0xef,0x7f,0x95,0x95,0x71,0xd3,0xa3,
4349
0x0b,0x71,0xa3,0xad,0x0b,0x3b,0xb5,0xfb,0xa3,0xbf,0x4f,0x83,0x1d,0xad,0xe9,0x2f,
4350
0x71,0x65,0xa3,0xe5,0x07,0x35,0x3d,0x0d,0xb5,0xe9,0xe5,0x47,0x3b,0x9d,0xef,0x35,
4351
0xa3,0xbf,0xb3,0xdf,0x53,0xd3,0x97,0x53,0x49,0x71,0x07,0x35,0x61,0x71,0x2f,0x43,
4352
0x2f,0x11,0xdf,0x17,0x97,0xfb,0x95,0x3b,0x7f,0x6b,0xd3,0x25,0xbf,0xad,0xc7,0xc5,
4353
0xc5,0xb5,0x8b,0xef,0x2f,0xd3,0x07,0x6b,0x25,0x49,0x95,0x25,0x49,0x6d,0x71,0xc7 },
4354
{ 0xa7,0xbc,0xc9,0xad,0x91,0xdf,0x85,0xe5,0xd4,0x78,0xd5,0x17,0x46,0x7c,0x29,0x4c,
4355
0x4d,0x03,0xe9,0x25,0x68,0x11,0x86,0xb3,0xbd,0xf7,0x6f,0x61,0x22,0xa2,0x26,0x34,
4356
0x2a,0xbe,0x1e,0x46,0x14,0x68,0x9d,0x44,0x18,0xc2,0x40,0xf4,0x7e,0x5f,0x1b,0xad,
4357
0x0b,0x94,0xb6,0x67,0xb4,0x0b,0xe1,0xea,0x95,0x9c,0x66,0xdc,0xe7,0x5d,0x6c,0x05,
4358
0xda,0xd5,0xdf,0x7a,0xef,0xf6,0xdb,0x1f,0x82,0x4c,0xc0,0x68,0x47,0xa1,0xbd,0xee,
4359
0x39,0x50,0x56,0x4a,0xdd,0xdf,0xa5,0xf8,0xc6,0xda,0xca,0x90,0xca,0x01,0x42,0x9d,
4360
0x8b,0x0c,0x73,0x43,0x75,0x05,0x94,0xde,0x24,0xb3,0x80,0x34,0xe5,0x2c,0xdc,0x9b,
4361
0x3f,0xca,0x33,0x45,0xd0,0xdb,0x5f,0xf5,0x52,0xc3,0x21,0xda,0xe2,0x22,0x72,0x6b,
4362
0x3e,0xd0,0x5b,0xa8,0x87,0x8c,0x06,0x5d,0x0f,0xdd,0x09,0x19,0x93,0xd0,0xb9,0xfc,
4363
0x8b,0x0f,0x84,0x60,0x33,0x1c,0x9b,0x45,0xf1,0xf0,0xa3,0x94,0x3a,0x12,0x77,0x33,
4364
0x4d,0x44,0x78,0x28,0x3c,0x9e,0xfd,0x65,0x57,0x16,0x94,0x6b,0xfb,0x59,0xd0,0xc8,
4365
0x22,0x36,0xdb,0xd2,0x63,0x98,0x43,0xa1,0x04,0x87,0x86,0xf7,0xa6,0x26,0xbb,0xd6,
4366
0x59,0x4d,0xbf,0x6a,0x2e,0xaa,0x2b,0xef,0xe6,0x78,0xb6,0x4e,0xe0,0x2f,0xdc,0x7c,
4367
0xbe,0x57,0x19,0x32,0x7e,0x2a,0xd0,0xb8,0xba,0x29,0x00,0x3c,0x52,0x7d,0xa8,0x49,
4368
0x3b,0x2d,0xeb,0x25,0x49,0xfa,0xa3,0xaa,0x39,0xa7,0xc5,0xa7,0x50,0x11,0x36,0xfb,
4369
0xc6,0x67,0x4a,0xf5,0xa5,0x12,0x65,0x7e,0xb0,0xdf,0xaf,0x4e,0xb3,0x61,0x7f,0x2f } };
4370
unsigned offset=0, entries, tag, type, len, save, c;
4371
unsigned ver97=0, serial=0, i, wbi=0, wb[4]={0,0,0,0};
4372
uchar buf97[324], ci, cj, ck;
4376
The MakerNote might have its own TIFF header (possibly with
4377
its own byte-order!), or it might just be a table.
4379
fread (buf, 1, 10, ifp);
4380
if (!strncmp (buf,"KDK" ,3) || /* these aren't TIFF tables */
4381
!strncmp (buf,"VER" ,3) ||
4382
!strncmp (buf,"IIII",4) ||
4383
!strncmp (buf,"MMMM",4)) return;
4384
if (!strncmp (buf,"KC" ,2) || /* Konica KD-400Z, KD-510Z */
4385
!strncmp (buf,"MLY" ,3)) { /* Minolta DiMAGE G series */
4387
while ((i=ftell(ifp)) < data_offset && i < 16384) {
4388
wb[0] = wb[2]; wb[2] = wb[1]; wb[1] = wb[3];
4390
if (wb[1] == 256 && wb[3] == 256 &&
4391
wb[0] > 256 && wb[0] < 640 && wb[2] > 256 && wb[2] < 640)
4392
FORC4 cam_mul[c] = wb[c];
4396
if (!strcmp (buf,"Nikon")) {
4399
if (get2() != 42) goto quit;
4401
fseek (ifp, offset-8, SEEK_CUR);
4402
} else if (!strcmp (buf,"OLYMPUS")) {
4403
base = ftell(ifp)-10;
4404
fseek (ifp, -2, SEEK_CUR);
4405
order = get2(); get2();
4406
} else if (!strncmp (buf,"FUJIFILM",8) ||
4407
!strncmp (buf,"SONY",4) ||
4408
!strcmp (buf,"Panasonic")) {
4410
fseek (ifp, 2, SEEK_CUR);
4411
} else if (!strcmp (buf,"OLYMP") ||
4412
!strcmp (buf,"LEICA") ||
4413
!strcmp (buf,"Ricoh") ||
4414
!strcmp (buf,"EPSON"))
4415
fseek (ifp, -2, SEEK_CUR);
4416
else if (!strcmp (buf,"AOC") ||
4417
!strcmp (buf,"QVC"))
4418
fseek (ifp, -4, SEEK_CUR);
4419
else fseek (ifp, -10, SEEK_CUR);
4422
if (entries > 1000) return;
4424
tiff_get (base, &tag, &type, &len, &save);
4426
if (tag == 2 && strstr(make,"NIKON"))
4427
iso_speed = (get2(),get2());
4428
if (tag == 4 && len > 26 && len < 35) {
4429
if ((i=(get4(),get2())) != 0x7fff && !iso_speed)
4430
iso_speed = 50 * pow (2, i/32.0 - 4);
4431
if ((i=(get2(),get2())) != 0x7fff && !aperture)
4432
aperture = pow (2, i/64.0);
4433
if ((i=get2()) != 0xffff && !shutter)
4434
shutter = pow (2, (short) i/-32.0);
4435
wbi = (get2(),get2());
4436
shot_order = (get2(),get2());
4438
if ((tag == 4 || tag == 0x114) && !strncmp(make,"KONICA",6)) {
4439
fseek (ifp, tag == 4 ? 140:160, SEEK_CUR);
4441
case 72: flip = 0; break;
4442
case 76: flip = 6; break;
4443
case 82: flip = 5; break;
4446
if (tag == 7 && type == 2 && len > 20)
4447
fgets (model2, 64, ifp);
4448
if (tag == 8 && type == 4)
4449
shot_order = get4();
4450
if (tag == 9 && !strcmp(make,"Canon"))
4451
fread (artist, 64, 1, ifp);
4452
if (tag == 0xc && len == 4) {
4453
cam_mul[0] = getreal(type);
4454
cam_mul[2] = getreal(type);
4456
if (tag == 0x10 && type == 4)
4458
if (tag == 0x11 && is_raw && !strncmp(make,"NIKON",5)) {
4459
fseek (ifp, get4()+base, SEEK_SET);
4460
parse_tiff_ifd (base);
4462
if (tag == 0x14 && len == 2560 && type == 7) {
4463
fseek (ifp, 1248, SEEK_CUR);
4466
if (tag == 0x15 && type == 2 && is_raw)
4467
fread (model, 64, 1, ifp);
4468
if (strstr(make,"PENTAX")) {
4469
if (tag == 0x1b) tag = 0x1018;
4470
if (tag == 0x1c) tag = 0x1017;
4473
while ((c = fgetc(ifp)) && c != EOF)
4474
serial = serial*10 + (isdigit(c) ? c - '0' : c % 10);
4475
if (tag == 0x81 && type == 4) {
4476
data_offset = get4();
4477
fseek (ifp, data_offset + 41, SEEK_SET);
4478
raw_height = get2() * 2;
4480
filters = 0x61616161;
4482
if (tag == 0x29 && type == 1) {
4483
c = wbi < 18 ? "012347800000005896"[wbi]-'0' : 0;
4484
fseek (ifp, 8 + c*32, SEEK_CUR);
4485
FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get4();
4487
if ((tag == 0x81 && type == 7) ||
4488
(tag == 0x100 && type == 7) ||
4489
(tag == 0x280 && type == 1)) {
4490
thumb_offset = ftell(ifp);
4493
if (tag == 0x88 && type == 4 && (thumb_offset = get4()))
4494
thumb_offset += base;
4495
if (tag == 0x89 && type == 4)
4496
thumb_length = get4();
4497
if (tag == 0x8c || tag == 0x96)
4498
meta_offset = ftell(ifp);
4500
for (i=0; i < 4; i++)
4501
ver97 = ver97 * 10 + fgetc(ifp)-'0';
4504
fseek (ifp, 68, SEEK_CUR);
4505
FORC4 cam_mul[(c >> 1) | ((c & 1) << 1)] = get2();
4508
fseek (ifp, 6, SEEK_CUR);
4511
fseek (ifp, 16, SEEK_CUR);
4512
FORC4 cam_mul[c] = get2();
4515
if (ver97 != 205) fseek (ifp, 280, SEEK_CUR);
4516
fread (buf97, 324, 1, ifp);
4519
if (tag == 0xa4 && type == 3) {
4520
fseek (ifp, wbi*48, SEEK_CUR);
4521
FORC3 cam_mul[c] = get2();
4523
if (tag == 0xa7 && (unsigned) (ver97-200) < 12 && !cam_mul[0]) {
4524
ci = xlat[0][serial & 0xff];
4525
cj = xlat[1][fgetc(ifp)^fgetc(ifp)^fgetc(ifp)^fgetc(ifp)];
4527
for (i=0; i < 324; i++)
4528
buf97[i] ^= (cj += ci * ck++);
4529
i = "66666>666;6A"[ver97-200] - '0';
4530
FORC4 cam_mul[c ^ (c >> 1) ^ (i & 1)] =
4531
sget2 (buf97 + (i & -2) + c*2);
4533
if (tag == 0x200 && len == 3)
4534
shot_order = (get4(),get4());
4535
if (tag == 0x200 && len == 4)
4536
black = (get2()+get2()+get2()+get2())/4;
4537
if (tag == 0x201 && len == 4)
4539
if (tag == 0x220 && len == 53)
4540
meta_offset = ftell(ifp) + 14;
4541
if (tag == 0x401 && type == 4 && len == 4) {
4542
black = (get4()+get4()+get4()+get4())/4;
4544
if (tag == 0xe01) { /* Nikon Capture Note */
4547
fseek (ifp, 22, SEEK_CUR);
4548
for (offset=22; offset+22 < len; offset += 22+i) {
4550
fseek (ifp, 14, SEEK_CUR);
4552
if (tag == 0x76a43207) flip = get2();
4553
else fseek (ifp, i, SEEK_CUR);
4557
if (tag == 0xe80 && len == 256 && type == 7) {
4558
fseek (ifp, 48, SEEK_CUR);
4559
cam_mul[0] = get2() * 508 * 1.078 / 0x10000;
4560
cam_mul[2] = get2() * 382 * 1.173 / 0x10000;
4562
if (tag == 0xf00 && type == 7) {
4564
fseek (ifp, 176, SEEK_CUR);
4565
else if (len == 734 || len == 1502)
4566
fseek (ifp, 148, SEEK_CUR);
4570
if ((tag == 0x1011 && len == 9) || tag == 0x20400200)
4571
for (i=0; i < 3; i++)
4572
FORC3 cmatrix[i][c] = ((short) get2()) / 256.0;
4573
if ((tag == 0x1012 || tag == 0x20400600) && len == 4)
4574
for (black = i=0; i < 4; i++)
4575
black += get2() << 2;
4576
if (tag == 0x1017 || tag == 0x20400100)
4577
cam_mul[0] = get2() / 256.0;
4578
if (tag == 0x1018 || tag == 0x20400100)
4579
cam_mul[2] = get2() / 256.0;
4580
if (tag == 0x2011 && len == 2) {
4583
cam_mul[0] = get2() / 256.0;
4584
cam_mul[2] = get2() / 256.0;
4586
if ((tag | 0x70) == 0x2070 && type == 4)
4587
fseek (ifp, get4()+base, SEEK_SET);
4588
if (tag == 0x2010 && type != 7)
4589
load_raw = &CLASS olympus_load_raw;
4591
parse_thumb_note (base, 257, 258);
4593
parse_makernote (base, 0x2040);
4594
if (tag == 0xb028) {
4595
fseek (ifp, get4(), SEEK_SET);
4596
parse_thumb_note (base, 136, 137);
4598
if (tag == 0x4001 && len > 500) {
4599
i = len == 582 ? 50 : len == 653 ? 68 : len == 5120 ? 142 : 126;
4600
fseek (ifp, i, SEEK_CUR);
4602
FORC4 cam_mul[c ^ (c >> 1)] = get2();
4603
fseek (ifp, 22, SEEK_CUR);
4604
FORC4 sraw_mul[c ^ (c >> 1)] = get2();
4607
fseek (ifp, save, SEEK_SET);
4614
Since the TIFF DateTime string has no timezone information,
4615
assume that the camera's clock was set to Universal Time.
4617
void CLASS get_timestamp (int reversed)
4625
for (i=19; i--; ) str[i] = fgetc(ifp);
4627
fread (str, 19, 1, ifp);
4628
memset (&t, 0, sizeof t);
4629
if (sscanf (str, "%d:%d:%d %d:%d:%d", &t.tm_year, &t.tm_mon,
4630
&t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec) != 6)
4635
timestamp = mktime(&t);
4638
void CLASS parse_exif (int base)
4640
unsigned kodak, entries, tag, type, len, save, c;
4643
kodak = !strncmp(make,"EASTMAN",7);
4646
tiff_get (base, &tag, &type, &len, &save);
4648
case 33434: shutter = getreal(type); break;
4649
case 33437: aperture = getreal(type); break;
4650
case 34855: iso_speed = get2(); break;
4652
case 36868: get_timestamp(0); break;
4653
case 37377: if ((expo = -getreal(type)) < 128)
4654
shutter = pow (2, expo); break;
4655
case 37378: aperture = pow (2, getreal(type)/2); break;
4656
case 37386: focal_len = getreal(type); break;
4657
case 37500: parse_makernote (base, 0); break;
4658
case 40962: if (kodak) raw_width = get4(); break;
4659
case 40963: if (kodak) raw_height = get4(); break;
4661
if (get4() == 0x20002)
4662
for (exif_cfa=c=0; c < 8; c+=2)
4663
exif_cfa |= fgetc(ifp) * 0x01010101 << c;
4665
fseek (ifp, save, SEEK_SET);
4669
void CLASS parse_gps (int base)
4671
unsigned entries, tag, type, len, save, c;
4675
tiff_get (base, &tag, &type, &len, &save);
4677
case 1: case 3: case 5:
4678
gpsdata[29+tag/2] = getc(ifp); break;
4679
case 2: case 4: case 7:
4680
FORC(6) gpsdata[tag/3*6+c] = get4(); break;
4682
FORC(2) gpsdata[18+c] = get4(); break;
4684
fgets ((char *) (gpsdata+14+tag/3), MIN(len,12), ifp);
4686
fseek (ifp, save, SEEK_SET);
4690
void CLASS romm_coeff (float romm_cam[3][3])
4692
static const float rgb_romm[3][3] = /* ROMM == Kodak ProPhoto */
4693
{ { 2.034193, -0.727420, -0.306766 },
4694
{ -0.228811, 1.231729, -0.002922 },
4695
{ -0.008565, -0.153273, 1.161839 } };
4698
for (i=0; i < 3; i++)
4699
for (j=0; j < 3; j++)
4700
for (cmatrix[i][j] = k=0; k < 3; k++)
4701
cmatrix[i][j] += rgb_romm[i][k] * romm_cam[k][j];
4704
void CLASS parse_mos (int offset)
4707
int skip, from, i, c, neut[4], planes=0, frot=0;
4708
static const char *mod[] =
4709
{ "","DCB2","Volare","Cantare","CMost","Valeo 6","Valeo 11","Valeo 22",
4710
"Valeo 11p","Valeo 17","","Aptus 17","Aptus 22","Aptus 75","Aptus 65",
4711
"Aptus 54S","Aptus 65S","Aptus 75S","AFi 5","AFi 6","AFi 7" };
4712
float romm_cam[3][3];
4714
fseek (ifp, offset, SEEK_SET);
4716
if (get4() != 0x504b5453) break;
4718
fread (data, 1, 40, ifp);
4721
if (!strcmp(data,"JPEG_preview_data")) {
4722
thumb_offset = from;
4723
thumb_length = skip;
4725
if (!strcmp(data,"icc_camera_profile")) {
4726
profile_offset = from;
4727
profile_length = skip;
4729
if (!strcmp(data,"ShootObj_back_type")) {
4730
fscanf (ifp, "%d", &i);
4731
if ((unsigned) i < sizeof mod / sizeof (*mod))
4732
strcpy (model, mod[i]);
4734
if (!strcmp(data,"icc_camera_to_tone_matrix")) {
4735
for (i=0; i < 9; i++)
4736
romm_cam[0][i] = int_to_float(get4());
4737
romm_coeff (romm_cam);
4739
if (!strcmp(data,"CaptProf_color_matrix")) {
4740
for (i=0; i < 9; i++)
4741
fscanf (ifp, "%f", &romm_cam[0][i]);
4742
romm_coeff (romm_cam);
4744
if (!strcmp(data,"CaptProf_number_of_planes"))
4745
fscanf (ifp, "%d", &planes);
4746
if (!strcmp(data,"CaptProf_raw_data_rotation"))
4747
fscanf (ifp, "%d", &flip);
4748
if (!strcmp(data,"CaptProf_mosaic_pattern"))
4750
fscanf (ifp, "%d", &i);
4751
if (i == 1) frot = c ^ (c >> 1);
4753
if (!strcmp(data,"ImgProf_rotation_angle")) {
4754
fscanf (ifp, "%d", &i);
4757
if (!strcmp(data,"NeutObj_neutrals") && !cam_mul[0]) {
4758
FORC4 fscanf (ifp, "%d", neut+c);
4759
FORC3 cam_mul[c] = (float) neut[0] / neut[c+1];
4762
fseek (ifp, skip+from, SEEK_SET);
4765
filters = (planes == 1) * 0x01010101 *
4766
(uchar) "\x94\x61\x16\x49"[(flip/90 + frot) & 3];
4769
void CLASS linear_table (unsigned len)
4772
if (len > 0x1000) len = 0x1000;
4773
read_shorts (curve, len);
4774
for (i=len; i < 0x1000; i++)
4775
curve[i] = curve[i-1];
4776
maximum = curve[0xfff];
4779
void CLASS parse_kodak_ifd (int base)
4781
unsigned entries, tag, type, len, save;
4782
int i, c, wbi=-2, wbtemp=6500;
4783
float mul[3]={1,1,1}, num;
4784
static const int wbtag[]={ 0xfa25,0xfa28,0xfa27,0xfa29,-1,-1,0xfa2a };
4787
if (entries > 1024) return;
4789
tiff_get (base, &tag, &type, &len, &save);
4790
if (tag == 1020) wbi = getint(type);
4791
if (tag == 1021 && len == 72) { /* WB set in software */
4792
fseek (ifp, 40, SEEK_CUR);
4793
FORC3 cam_mul[c] = 2048.0 / get2();
4796
if (tag == 2118) wbtemp = getint(type);
4797
if (tag == 2130 + wbi)
4798
FORC3 mul[c] = getreal(type);
4799
if (tag == 2140 + wbi && wbi >= 0)
4801
for (num=i=0; i < 4; i++)
4802
num += getreal(type) * pow (wbtemp/100.0, i);
4803
cam_mul[c] = 2048 / (num * mul[c]);
4805
if (tag == 2317) linear_table (len);
4806
if (tag == 6020) iso_speed = getint(type);
4807
if (tag == 0xfa0d) wbi = fgetc(ifp);
4808
if ((unsigned) wbi < 7 && tag == wbtag[wbi])
4809
FORC3 cam_mul[c] = get4();
4810
fseek (ifp, save, SEEK_SET);
4814
void CLASS parse_minolta (int base);
4816
int CLASS parse_tiff_ifd (int base)
4818
unsigned entries, tag, type, len, plen=16, save;
4819
int ifd, use_cm=0, cfa, i, j, c, ima_len=0;
4820
char software[64], *cbuf, *cp;
4821
uchar cfa_pat[16], cfa_pc[] = { 0,1,2,3 }, tab[256];
4822
double dblack, cc[4][4], cm[4][3], cam_xyz[4][3], num;
4823
double ab[]={ 1,1,1,1 }, asn[] = { 0,0,0,0 }, xyz[] = { 1,1,1 };
4824
unsigned sony_curve[] = { 0,0,0,0,0,4095 };
4825
unsigned *buf, sony_offset=0, sony_length=0, sony_key=0;
4829
if (tiff_nifds >= sizeof tiff_ifd / sizeof tiff_ifd[0])
4832
for (j=0; j < 4; j++)
4833
for (i=0; i < 4; i++)
4836
if (entries > 512) return 1;
4838
tiff_get (base, &tag, &type, &len, &save);
4841
if (type == 3 && len == 1)
4842
cam_mul[(tag-17)*2] = get2() / 256.0;
4845
if (type == 3) iso_speed = get2();
4847
case 36: case 37: case 38:
4848
cam_mul[tag-0x24] = get2();
4851
if (len < 50 || cam_mul[0]) break;
4852
fseek (ifp, 12, SEEK_CUR);
4853
FORC3 cam_mul[c] = get2();
4856
if (type != 7 || fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) break;
4857
thumb_offset = ftell(ifp) - 2;
4860
case 2: case 256: /* ImageWidth */
4861
tiff_ifd[ifd].width = getint(type);
4863
case 3: case 257: /* ImageHeight */
4864
tiff_ifd[ifd].height = getint(type);
4866
case 258: /* BitsPerSample */
4867
tiff_ifd[ifd].samples = len & 7;
4868
tiff_ifd[ifd].bps = get2();
4870
case 259: /* Compression */
4871
tiff_ifd[ifd].comp = get2();
4873
case 262: /* PhotometricInterpretation */
4874
tiff_ifd[ifd].phint = get2();
4876
case 270: /* ImageDescription */
4877
fread (desc, 512, 1, ifp);
4879
case 271: /* Make */
4880
fgets (make, 64, ifp);
4882
case 272: /* Model */
4883
fgets (model, 64, ifp);
4885
case 280: /* Panasonic RW2 offset */
4886
if (type != 4) break;
4887
load_raw = &CLASS panasonic_load_raw;
4888
load_flags = 0x2008;
4889
case 273: /* StripOffset */
4891
tiff_ifd[ifd].offset = get4()+base;
4892
if (!tiff_ifd[ifd].bps) {
4893
fseek (ifp, tiff_ifd[ifd].offset, SEEK_SET);
4894
if (ljpeg_start (&jh, 1)) {
4895
tiff_ifd[ifd].comp = 6;
4896
tiff_ifd[ifd].width = jh.wide << (jh.clrs == 2);
4897
tiff_ifd[ifd].height = jh.high;
4898
tiff_ifd[ifd].bps = jh.bits;
4899
tiff_ifd[ifd].samples = jh.clrs;
4903
case 274: /* Orientation */
4904
tiff_ifd[ifd].flip = "50132467"[get2() & 7]-'0';
4906
case 277: /* SamplesPerPixel */
4907
tiff_ifd[ifd].samples = getint(type) & 7;
4909
case 279: /* StripByteCounts */
4911
tiff_ifd[ifd].bytes = get4();
4913
case 305: case 11: /* Software */
4914
fgets (software, 64, ifp);
4915
if (!strncmp(software,"Adobe",5) ||
4916
!strncmp(software,"dcraw",5) ||
4917
!strncmp(software,"UFRaw",5) ||
4918
!strncmp(software,"Bibble",6) ||
4919
!strncmp(software,"Nikon Scan",10) ||
4920
!strcmp (software,"Digital Photo Professional"))
4923
case 306: /* DateTime */
4926
case 315: /* Artist */
4927
fread (artist, 64, 1, ifp);
4929
case 322: /* TileWidth */
4930
tile_width = getint(type);
4932
case 323: /* TileLength */
4933
tile_length = getint(type);
4935
case 324: /* TileOffsets */
4936
tiff_ifd[ifd].offset = len > 1 ? ftell(ifp) : get4();
4938
load_raw = &CLASS sinar_4shot_load_raw;
4942
case 330: /* SubIFDs */
4943
if (!strcmp(model,"DSLR-A100") && tiff_ifd[ifd].width == 3872) {
4944
load_raw = &CLASS sony_arw_load_raw;
4945
data_offset = get4()+base;
4950
fseek (ifp, get4()+base, SEEK_SET);
4951
if (parse_tiff_ifd (base)) break;
4952
fseek (ifp, i+4, SEEK_SET);
4956
strcpy (make, "Sarnoff");
4960
FORC4 sony_curve[c+1] = get2() >> 2 & 0xfff;
4961
for (i=0; i < 5; i++)
4962
for (j = sony_curve[i]+1; j <= sony_curve[i+1]; j++)
4963
curve[j] = curve[j-1] + (1 << i);
4965
case 29184: sony_offset = get4(); break;
4966
case 29185: sony_length = get4(); break;
4967
case 29217: sony_key = get4(); break;
4969
parse_minolta (ftell(ifp));
4973
FORC4 cam_mul[c ^ (c < 2)] = get2();
4976
FORC4 cam_mul[c ^ (c >> 1)] = get2();
4978
case 33405: /* Model2 */
4979
fgets (model2, 64, ifp);
4981
case 33422: /* CFAPattern */
4982
case 64777: /* Kodak P-series */
4983
if ((plen=len) > 16) plen = 16;
4984
fread (cfa_pat, 1, plen, ifp);
4985
for (colors=cfa=i=0; i < plen; i++) {
4986
colors += !(cfa & (1 << cfa_pat[i]));
4987
cfa |= 1 << cfa_pat[i];
4989
if (cfa == 070) memcpy (cfa_pc,"\003\004\005",3); /* CMY */
4990
if (cfa == 072) memcpy (cfa_pc,"\005\003\004\001",4); /* GMCY */
4994
fseek (ifp, get4()+base, SEEK_SET);
4995
parse_kodak_ifd (base);
4997
case 33434: /* ExposureTime */
4998
shutter = getreal(type);
5000
case 33437: /* FNumber */
5001
aperture = getreal(type);
5003
case 34306: /* Leaf white balance */
5004
FORC4 cam_mul[c ^ 1] = 4096.0 / get2();
5006
case 34307: /* Leaf CatchLight color matrix */
5007
fread (software, 1, 7, ifp);
5008
if (strncmp(software,"MATRIX",6)) break;
5010
for (raw_color = i=0; i < 3; i++) {
5011
FORC4 fscanf (ifp, "%f", &rgb_cam[i][c^1]);
5012
if (!use_camera_wb) continue;
5014
FORC4 num += rgb_cam[i][c];
5015
FORC4 rgb_cam[i][c] /= num;
5018
case 34310: /* Leaf metadata */
5019
parse_mos (ftell(ifp));
5021
strcpy (make, "Leaf");
5023
case 34665: /* EXIF tag */
5024
fseek (ifp, get4()+base, SEEK_SET);
5027
case 34853: /* GPSInfo tag */
5028
fseek (ifp, get4()+base, SEEK_SET);
5031
case 34675: /* InterColorProfile */
5032
case 50831: /* AsShotICCProfile */
5033
profile_offset = ftell(ifp);
5034
profile_length = len;
5036
case 37122: /* CompressedBitsPerPixel */
5037
kodak_cbpp = get4();
5039
case 37386: /* FocalLength */
5040
focal_len = getreal(type);
5042
case 37393: /* ImageNumber */
5043
shot_order = getint(type);
5045
case 37400: /* old Kodak KDC tag */
5046
for (raw_color = i=0; i < 3; i++) {
5048
FORC3 rgb_cam[i][c] = getreal(type);
5051
case 46275: /* Imacon tags */
5052
strcpy (make, "Imacon");
5053
data_offset = ftell(ifp);
5057
if (!ima_len) break;
5058
fseek (ifp, 78, SEEK_CUR);
5060
raw_height = get4();
5061
left_margin = get4() & 7;
5062
width = raw_width - left_margin - (get4() & 7);
5063
top_margin = get4() & 7;
5064
height = raw_height - top_margin - (get4() & 7);
5065
if (raw_width == 7262) {
5070
fseek (ifp, 52, SEEK_CUR);
5071
FORC3 cam_mul[c] = getreal(11);
5072
fseek (ifp, 114, SEEK_CUR);
5073
flip = (get2() >> 7) * 90;
5074
if (width * height * 6 == ima_len) {
5075
if (flip % 180 == 90) SWAP(width,height);
5078
sprintf (model, "Ixpress %d-Mp", height*width/1000000);
5079
load_raw = &CLASS imacon_full_load_raw;
5081
if (left_margin & 1) filters = 0x61616161;
5082
load_raw = &CLASS unpacked_load_raw;
5086
case 50454: /* Sinar tag */
5088
if (!(cbuf = (char *) malloc(len))) break;
5089
fread (cbuf, 1, len, ifp);
5090
for (cp = cbuf-1; cp && cp < cbuf+len; cp = strchr(cp,'\n'))
5091
if (!strncmp (++cp,"Neutral ",8))
5092
sscanf (cp+8, "%f %f %f", cam_mul, cam_mul+1, cam_mul+2);
5096
if (!make[0]) strcpy (make, "Hasselblad");
5098
case 50459: /* Hasselblad tag */
5103
fseek (ifp, j+(get2(),get4()), SEEK_SET);
5109
case 50706: /* DNGVersion */
5110
FORC4 dng_version = (dng_version << 8) + fgetc(ifp);
5111
if (!make[0]) strcpy (make, "DNG");
5114
case 50710: /* CFAPlaneColor */
5115
if (len > 4) len = 4;
5117
fread (cfa_pc, 1, colors, ifp);
5119
FORCC tab[cfa_pc[c]] = c;
5122
filters = filters << 2 | tab[cfa_pat[i % plen]];
5124
case 50711: /* CFALayout */
5127
filters = 0x49494949;
5131
case 50712: /* LinearizationTable */
5134
case 50714: /* BlackLevel */
5135
case 50715: /* BlackLevelDeltaH */
5136
case 50716: /* BlackLevelDeltaV */
5137
for (dblack=i=0; i < len; i++)
5138
dblack += getreal(type);
5139
black += dblack/len + 0.5;
5141
case 50717: /* WhiteLevel */
5142
maximum = getint(type);
5144
case 50718: /* DefaultScale */
5145
pixel_aspect = getreal(type);
5146
pixel_aspect /= getreal(type);
5148
case 50721: /* ColorMatrix1 */
5149
case 50722: /* ColorMatrix2 */
5150
FORCC for (j=0; j < 3; j++)
5151
cm[c][j] = getreal(type);
5154
case 50723: /* CameraCalibration1 */
5155
case 50724: /* CameraCalibration2 */
5156
for (i=0; i < colors; i++)
5157
FORCC cc[i][c] = getreal(type);
5159
case 50727: /* AnalogBalance */
5160
FORCC ab[c] = getreal(type);
5162
case 50728: /* AsShotNeutral */
5163
FORCC asn[c] = getreal(type);
5165
case 50729: /* AsShotWhiteXY */
5166
xyz[0] = getreal(type);
5167
xyz[1] = getreal(type);
5168
xyz[2] = 1 - xyz[0] - xyz[1];
5169
FORC3 xyz[c] /= d65_white[c];
5171
case 50740: /* DNGPrivateData */
5172
if (dng_version) break;
5173
parse_minolta (j = get4()+base);
5174
fseek (ifp, j, SEEK_SET);
5175
parse_tiff_ifd (base);
5178
read_shorts (cr2_slice, 3);
5180
case 50829: /* ActiveArea */
5181
top_margin = getint(type);
5182
left_margin = getint(type);
5183
height = getint(type) - top_margin;
5184
width = getint(type) - left_margin;
5186
case 64772: /* Kodak P-series */
5187
if (len < 13) break;
5188
fseek (ifp, 16, SEEK_CUR);
5189
data_offset = get4();
5190
fseek (ifp, 28, SEEK_CUR);
5191
data_offset += get4();
5192
load_raw = &CLASS packed_load_raw;
5195
if (type == 2) fgets (model2, 64, ifp);
5197
fseek (ifp, save, SEEK_SET);
5199
if (sony_length && (buf = (unsigned *) malloc(sony_length))) {
5200
fseek (ifp, sony_offset, SEEK_SET);
5201
fread (buf, sony_length, 1, ifp);
5202
sony_decrypt (buf, sony_length/4, 1, sony_key);
5204
if ((ifp = tmpfile())) {
5205
fwrite (buf, sony_length, 1, ifp);
5206
fseek (ifp, 0, SEEK_SET);
5207
parse_tiff_ifd (-sony_offset);
5213
for (i=0; i < colors; i++)
5214
FORCC cc[i][c] *= ab[i];
5216
FORCC for (i=0; i < 3; i++)
5217
for (cam_xyz[c][i]=j=0; j < colors; j++)
5218
cam_xyz[c][i] += cc[c][j] * cm[j][i] * xyz[i];
5219
cam_xyz_coeff (cam_xyz);
5223
FORCC cam_mul[c] = 1 / asn[c];
5226
FORCC pre_mul[c] /= cc[c][c];
5230
void CLASS parse_tiff (int base)
5232
int doff, max_samp=0, raw=-1, thm=-1, i;
5235
fseek (ifp, base, SEEK_SET);
5237
if (order != 0x4949 && order != 0x4d4d) return;
5239
memset (tiff_ifd, 0, sizeof tiff_ifd);
5241
while ((doff = get4())) {
5242
fseek (ifp, doff+base, SEEK_SET);
5243
if (parse_tiff_ifd (base)) break;
5247
fseek (ifp, thumb_offset, SEEK_SET);
5248
if (ljpeg_start (&jh, 1)) {
5249
thumb_misc = jh.bits;
5250
thumb_width = jh.wide;
5251
thumb_height = jh.high;
5254
for (i=0; i < tiff_nifds; i++) {
5255
if (max_samp < tiff_ifd[i].samples)
5256
max_samp = tiff_ifd[i].samples;
5257
if (max_samp > 3) max_samp = 3;
5258
if ((tiff_ifd[i].comp != 6 || tiff_ifd[i].samples != 3) &&
5259
(tiff_ifd[i].width | tiff_ifd[i].height) < 0x10000 &&
5260
tiff_ifd[i].width*tiff_ifd[i].height > raw_width*raw_height) {
5261
raw_width = tiff_ifd[i].width;
5262
raw_height = tiff_ifd[i].height;
5263
tiff_bps = tiff_ifd[i].bps;
5264
tiff_compress = tiff_ifd[i].comp;
5265
data_offset = tiff_ifd[i].offset;
5266
tiff_flip = tiff_ifd[i].flip;
5267
tiff_samples = tiff_ifd[i].samples;
5271
fuji_width *= (raw_width+1)/2;
5272
if (tiff_ifd[0].flip) tiff_flip = tiff_ifd[0].flip;
5273
if (raw >= 0 && !load_raw)
5274
switch (tiff_compress) {
5277
case 8: load_raw = &CLASS eight_bit_load_raw; break;
5278
case 12: load_raw = &CLASS packed_load_raw;
5279
if (tiff_ifd[raw].phint == 2)
5281
if (strncmp(make,"PENTAX",6)) break;
5283
case 16: load_raw = &CLASS unpacked_load_raw; break;
5285
if (tiff_ifd[raw].bytes*5 == raw_width*raw_height*8) {
5288
load_raw = &CLASS packed_load_raw;
5292
case 6: case 7: case 99:
5293
load_raw = &CLASS lossless_jpeg_load_raw; break;
5295
load_raw = &CLASS kodak_262_load_raw; break;
5297
if (tiff_ifd[raw].bytes == raw_width*raw_height) {
5299
load_raw = &CLASS sony_arw2_load_raw; break;
5301
if (tiff_ifd[raw].bytes*8 != raw_width*raw_height*tiff_bps) {
5303
load_raw = &CLASS sony_arw_load_raw; break;
5309
load_raw = &CLASS packed_load_raw; break;
5311
load_raw = &CLASS nikon_compressed_load_raw; break;
5313
load_raw = &CLASS pentax_load_raw; break;
5315
switch (tiff_ifd[raw].phint) {
5316
case 2: load_raw = &CLASS kodak_rgb_load_raw; filters = 0; break;
5317
case 6: load_raw = &CLASS kodak_ycbcr_load_raw; filters = 0; break;
5318
case 32803: load_raw = &CLASS kodak_65000_load_raw;
5321
default: is_raw = 0;
5324
if ( (tiff_samples == 3 && tiff_ifd[raw].bytes &&
5325
tiff_bps != 14 && tiff_bps != 2048)
5326
|| (tiff_bps == 8 && !strstr(make,"KODAK") && !strstr(make,"Kodak") &&
5327
!strstr(model2,"DEBUG RAW")))
5329
for (i=0; i < tiff_nifds; i++)
5330
if (i != raw && tiff_ifd[i].samples == max_samp &&
5331
tiff_ifd[i].width * tiff_ifd[i].height / SQR(tiff_ifd[i].bps+1) >
5332
thumb_width * thumb_height / SQR(thumb_misc+1)) {
5333
thumb_width = tiff_ifd[i].width;
5334
thumb_height = tiff_ifd[i].height;
5335
thumb_offset = tiff_ifd[i].offset;
5336
thumb_length = tiff_ifd[i].bytes;
5337
thumb_misc = tiff_ifd[i].bps;
5341
thumb_misc |= tiff_ifd[thm].samples << 5;
5342
switch (tiff_ifd[thm].comp) {
5344
write_thumb = &CLASS layer_thumb;
5347
if (tiff_ifd[thm].bps > 8)
5348
thumb_load_raw = &CLASS kodak_thumb_load_raw;
5350
write_thumb = &CLASS ppm_thumb;
5353
thumb_load_raw = tiff_ifd[thm].phint == 6 ?
5354
&CLASS kodak_ycbcr_load_raw : &CLASS kodak_rgb_load_raw;
5359
void CLASS parse_minolta (int base)
5361
int save, tag, len, offset, high=0, wide=0, i, c;
5364
fseek (ifp, base, SEEK_SET);
5365
if (fgetc(ifp) || fgetc(ifp)-'M' || fgetc(ifp)-'R') return;
5366
order = fgetc(ifp) * 0x101;
5367
offset = base + get4() + 8;
5368
while ((save=ftell(ifp)) < offset) {
5369
for (tag=i=0; i < 4; i++)
5370
tag = tag << 8 | fgetc(ifp);
5373
case 0x505244: /* PRD */
5374
fseek (ifp, 8, SEEK_CUR);
5378
case 0x574247: /* WBG */
5380
i = strcmp(model,"DiMAGE A200") ? 0:3;
5381
FORC4 cam_mul[c ^ (c >> 1) ^ i] = get2();
5383
case 0x545457: /* TTW */
5384
parse_tiff (ftell(ifp));
5385
data_offset = offset;
5387
fseek (ifp, save+len+8, SEEK_SET);
5395
Many cameras have a "debug mode" that writes JPEG and raw
5396
at the same time. The raw file has no header, so try to
5397
to open the matching JPEG file and read its metadata.
5399
void CLASS parse_external_jpeg()
5401
const char *file, *ext;
5402
char *jname, *jfile, *jext;
5405
ext = strrchr (ifname, '.');
5406
file = strrchr (ifname, '/');
5407
if (!file) file = strrchr (ifname, '\\');
5408
if (!file) file = ifname-1;
5410
if (!ext || strlen(ext) != 4 || ext-file != 8) return;
5411
jname = (char *) malloc (strlen(ifname) + 1);
5412
merror (jname, "parse_external_jpeg()");
5413
strcpy (jname, ifname);
5414
jfile = file - ifname + jname;
5415
jext = ext - ifname + jname;
5416
if (strcasecmp (ext, ".jpg")) {
5417
strcpy (jext, isupper(ext[1]) ? ".JPG":".jpg");
5418
if (isdigit(*file)) {
5419
memcpy (jfile, file+4, 4);
5420
memcpy (jfile+4, file, 4);
5423
while (isdigit(*--jext)) {
5430
if (strcmp (jname, ifname)) {
5431
if ((ifp = fopen (jname, "rb"))) {
5433
fprintf (stderr,_("Reading metadata from %s ...\n"), jname);
5441
fprintf (stderr,_("Failed to read metadata from %s\n"), jname);
5447
CIFF block 0x1030 contains an 8x8 white sample.
5448
Load this into white[][] for use in scale_colors().
5450
void CLASS ciff_block_1030()
5452
static const ushort key[] = { 0x410, 0x45f3 };
5453
int i, bpp, row, col, vbits=0;
5454
unsigned long bitbuf=0;
5456
if ((get2(),get4()) != 0x80008 || !get4()) return;
5458
if (bpp != 10 && bpp != 12) return;
5459
for (i=row=0; row < 8; row++)
5460
for (col=0; col < 8; col++) {
5462
bitbuf = bitbuf << 16 | (get2() ^ key[i++ & 1]);
5466
bitbuf << (LONG_BIT - vbits) >> (LONG_BIT - bpp);
5472
Parse a CIFF file, better known as Canon CRW format.
5474
void CLASS parse_ciff (int offset, int length)
5476
int tboff, nrecs, c, type, len, save, wbi=-1;
5477
ushort key[] = { 0x410, 0x45f3 };
5479
fseek (ifp, offset+length-4, SEEK_SET);
5480
tboff = get4() + offset;
5481
fseek (ifp, tboff, SEEK_SET);
5483
if (nrecs > 100) return;
5487
save = ftell(ifp) + 4;
5488
fseek (ifp, offset+get4(), SEEK_SET);
5489
if ((((type >> 8) + 8) | 8) == 0x38)
5490
parse_ciff (ftell(ifp), len); /* Parse a sub-table */
5493
fread (artist, 64, 1, ifp);
5494
if (type == 0x080a) {
5495
fread (make, 64, 1, ifp);
5496
fseek (ifp, strlen(make) - 63, SEEK_CUR);
5497
fread (model, 64, 1, ifp);
5499
if (type == 0x1810) {
5500
fseek (ifp, 12, SEEK_CUR);
5503
if (type == 0x1835) /* Get the decoder table */
5504
tiff_compress = get4();
5505
if (type == 0x2007) {
5506
thumb_offset = ftell(ifp);
5509
if (type == 0x1818) {
5510
shutter = pow (2, -int_to_float((get4(),get4())));
5511
aperture = pow (2, int_to_float(get4())/2);
5513
if (type == 0x102a) {
5514
iso_speed = pow (2, (get4(),get2())/32.0 - 4) * 50;
5515
aperture = pow (2, (get2(),(short)get2())/64.0);
5516
shutter = pow (2,-((short)get2())/32.0);
5517
wbi = (get2(),get2());
5518
if (wbi > 17) wbi = 0;
5519
fseek (ifp, 32, SEEK_CUR);
5520
if (shutter > 1e6) shutter = get2()/10.0;
5522
if (type == 0x102c) {
5523
if (get2() > 512) { /* Pro90, G1 */
5524
fseek (ifp, 118, SEEK_CUR);
5525
FORC4 cam_mul[c ^ 2] = get2();
5526
} else { /* G2, S30, S40 */
5527
fseek (ifp, 98, SEEK_CUR);
5528
FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get2();
5531
if (type == 0x0032) {
5532
if (len == 768) { /* EOS D30 */
5533
fseek (ifp, 72, SEEK_CUR);
5534
FORC4 cam_mul[c ^ (c >> 1)] = 1024.0 / get2();
5535
if (!wbi) cam_mul[0] = -1; /* use my auto white balance */
5536
} else if (!cam_mul[0]) {
5537
if (get2() == key[0]) /* Pro1, G6, S60, S70 */
5538
c = (strstr(model,"Pro1") ?
5539
"012346000000000000":"01345:000000006008")[wbi]-'0'+ 2;
5540
else { /* G3, G5, S45, S50 */
5541
c = "023457000000006000"[wbi]-'0';
5542
key[0] = key[1] = 0;
5544
fseek (ifp, 78 + c*8, SEEK_CUR);
5545
FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get2() ^ key[c & 1];
5546
if (!wbi) cam_mul[0] = -1;
5549
if (type == 0x10a9) { /* D60, 10D, 300D, and clones */
5550
if (len > 66) wbi = "0134567028"[wbi]-'0';
5551
fseek (ifp, 2 + wbi*8, SEEK_CUR);
5552
FORC4 cam_mul[c ^ (c >> 1)] = get2();
5554
if (type == 0x1030 && (0x18040 >> wbi & 1))
5555
ciff_block_1030(); /* all that don't have 0x10a9 */
5556
if (type == 0x1031) {
5557
raw_width = (get2(),get2());
5558
raw_height = get2();
5560
if (type == 0x5029) {
5561
focal_len = len >> 16;
5562
if ((len & 0xffff) == 2) focal_len /= 32;
5564
if (type == 0x5813) flash_used = int_to_float(len);
5565
if (type == 0x5814) canon_ev = int_to_float(len);
5566
if (type == 0x5817) shot_order = len;
5567
if (type == 0x5834) unique_id = len;
5568
if (type == 0x580e) timestamp = len;
5569
if (type == 0x180e) timestamp = get4();
5571
if ((type | 0x4000) == 0x580e)
5572
timestamp = mktime (gmtime (×tamp));
5574
fseek (ifp, save, SEEK_SET);
5578
void CLASS parse_rollei()
5580
char line[128], *val;
5583
fseek (ifp, 0, SEEK_SET);
5584
memset (&t, 0, sizeof t);
5586
fgets (line, 128, ifp);
5587
if ((val = strchr(line,'=')))
5590
val = line + strlen(line);
5591
if (!strcmp(line,"DAT"))
5592
sscanf (val, "%d.%d.%d", &t.tm_mday, &t.tm_mon, &t.tm_year);
5593
if (!strcmp(line,"TIM"))
5594
sscanf (val, "%d:%d:%d", &t.tm_hour, &t.tm_min, &t.tm_sec);
5595
if (!strcmp(line,"HDR"))
5596
thumb_offset = atoi(val);
5597
if (!strcmp(line,"X "))
5598
raw_width = atoi(val);
5599
if (!strcmp(line,"Y "))
5600
raw_height = atoi(val);
5601
if (!strcmp(line,"TX "))
5602
thumb_width = atoi(val);
5603
if (!strcmp(line,"TY "))
5604
thumb_height = atoi(val);
5605
} while (strncmp(line,"EOHD",4));
5606
data_offset = thumb_offset + thumb_width * thumb_height * 2;
5610
timestamp = mktime(&t);
5611
strcpy (make, "Rollei");
5612
strcpy (model,"d530flex");
5613
write_thumb = &CLASS rollei_thumb;
5616
void CLASS parse_sinar_ia()
5622
fseek (ifp, 4, SEEK_SET);
5624
fseek (ifp, get4(), SEEK_SET);
5626
off = get4(); get4();
5627
fread (str, 8, 1, ifp);
5628
if (!strcmp(str,"META")) meta_offset = off;
5629
if (!strcmp(str,"THUMB")) thumb_offset = off;
5630
if (!strcmp(str,"RAW0")) data_offset = off;
5632
fseek (ifp, meta_offset+20, SEEK_SET);
5633
fread (make, 64, 1, ifp);
5635
if ((cp = strchr(make,' '))) {
5636
strcpy (model, cp+1);
5640
raw_height = get2();
5641
load_raw = &CLASS unpacked_load_raw;
5642
thumb_width = (get4(),get2());
5643
thumb_height = get2();
5644
write_thumb = &CLASS ppm_thumb;
5648
void CLASS parse_phase_one (int base)
5650
unsigned entries, tag, type, len, data, save, i, c;
5651
float romm_cam[3][3];
5654
memset (&ph1, 0, sizeof ph1);
5655
fseek (ifp, base, SEEK_SET);
5656
order = get4() & 0xffff;
5657
if (get4() >> 8 != 0x526177) return; /* "Raw" */
5658
fseek (ifp, get4()+base, SEEK_SET);
5667
fseek (ifp, base+data, SEEK_SET);
5669
case 0x100: flip = "0653"[data & 3]-'0'; break;
5671
for (i=0; i < 9; i++)
5672
romm_cam[0][i] = getreal(11);
5673
romm_coeff (romm_cam);
5676
FORC3 cam_mul[c] = getreal(11);
5678
case 0x108: raw_width = data; break;
5679
case 0x109: raw_height = data; break;
5680
case 0x10a: left_margin = data; break;
5681
case 0x10b: top_margin = data; break;
5682
case 0x10c: width = data; break;
5683
case 0x10d: height = data; break;
5684
case 0x10e: ph1.format = data; break;
5685
case 0x10f: data_offset = data+base; break;
5686
case 0x110: meta_offset = data+base;
5687
meta_length = len; break;
5688
case 0x112: ph1.key_off = save - 4; break;
5689
case 0x210: ph1.tag_210 = int_to_float(data); break;
5690
case 0x21a: ph1.tag_21a = data; break;
5691
case 0x21c: strip_offset = data+base; break;
5692
case 0x21d: ph1.black = data; break;
5693
case 0x222: ph1.split_col = data - left_margin; break;
5694
case 0x223: ph1.black_off = data+base; break;
5697
fread (model, 1, 63, ifp);
5698
if ((cp = strstr(model," camera"))) *cp = 0;
5700
fseek (ifp, save, SEEK_SET);
5702
load_raw = ph1.format < 3 ?
5703
&CLASS phase_one_load_raw : &CLASS phase_one_load_raw_c;
5705
strcpy (make, "Phase One");
5706
if (model[0]) return;
5707
switch (raw_height) {
5708
case 2060: strcpy (model,"LightPhase"); break;
5709
case 2682: strcpy (model,"H 10"); break;
5710
case 4128: strcpy (model,"H 20"); break;
5711
case 5488: strcpy (model,"H 25"); break;
5715
void CLASS parse_fuji (int offset)
5717
unsigned entries, tag, len, save, c;
5719
fseek (ifp, offset, SEEK_SET);
5721
if (entries > 255) return;
5727
raw_height = get2();
5729
} else if (tag == 0x121) {
5731
if ((width = get2()) == 4284) width += 3;
5732
} else if (tag == 0x130) {
5733
fuji_layout = fgetc(ifp) >> 7;
5734
load_raw = fgetc(ifp) & 8 ?
5735
&CLASS unpacked_load_raw : &CLASS fuji_load_raw;
5738
FORC4 cam_mul[c ^ 1] = get2();
5739
fseek (ifp, save+len, SEEK_SET);
5741
height <<= fuji_layout;
5742
width >>= fuji_layout;
5745
int CLASS parse_jpeg (int offset)
5747
int len, save, hlen, mark;
5749
fseek (ifp, offset, SEEK_SET);
5750
if (fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) return 0;
5752
while (fgetc(ifp) == 0xff && (mark = fgetc(ifp)) != 0xda) {
5756
if (mark == 0xc0 || mark == 0xc3) {
5758
raw_height = get2();
5763
if (get4() == 0x48454150) /* "HEAP" */
5764
parse_ciff (save+hlen, len-hlen);
5765
parse_tiff (save+6);
5766
fseek (ifp, save+len, SEEK_SET);
5771
void CLASS parse_riff()
5773
unsigned i, size, end;
5774
char tag[4], date[64], month[64];
5775
static const char mon[12][4] =
5776
{ "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" };
5780
fread (tag, 4, 1, ifp);
5782
end = ftell(ifp) + size;
5783
if (!memcmp(tag,"RIFF",4) || !memcmp(tag,"LIST",4)) {
5785
while (ftell(ifp)+7 < end)
5787
} else if (!memcmp(tag,"nctg",4)) {
5788
while (ftell(ifp)+7 < end) {
5791
if ((i+1) >> 1 == 10 && size == 20)
5793
else fseek (ifp, size, SEEK_CUR);
5795
} else if (!memcmp(tag,"IDIT",4) && size < 64) {
5796
fread (date, 64, 1, ifp);
5798
memset (&t, 0, sizeof t);
5799
if (sscanf (date, "%*s %s %d %d:%d:%d %d", month, &t.tm_mday,
5800
&t.tm_hour, &t.tm_min, &t.tm_sec, &t.tm_year) == 6) {
5801
for (i=0; i < 12 && strcasecmp(mon[i],month); i++);
5805
timestamp = mktime(&t);
5808
fseek (ifp, size, SEEK_CUR);
5811
void CLASS parse_smal (int offset, int fsize)
5815
fseek (ifp, offset+2, SEEK_SET);
5819
fseek (ifp, 5, SEEK_CUR);
5820
if (get4() != fsize) return;
5821
if (ver > 6) data_offset = get4();
5822
raw_height = height = get2();
5823
raw_width = width = get2();
5824
strcpy (make, "SMaL");
5825
sprintf (model, "v%d %dx%d", ver, width, height);
5826
if (ver == 6) load_raw = &CLASS smal_v6_load_raw;
5827
if (ver == 9) load_raw = &CLASS smal_v9_load_raw;
5830
void CLASS parse_cine()
5832
unsigned off_head, off_setup, off_image, i;
5835
fseek (ifp, 4, SEEK_SET);
5836
is_raw = get2() == 2;
5837
fseek (ifp, 14, SEEK_CUR);
5843
if ((i = get4())) timestamp = i;
5844
fseek (ifp, off_head+4, SEEK_SET);
5846
raw_height = get4();
5847
switch (get2(),get2()) {
5848
case 8: load_raw = &CLASS eight_bit_load_raw; break;
5849
case 16: load_raw = &CLASS unpacked_load_raw;
5851
fseek (ifp, off_setup+792, SEEK_SET);
5852
strcpy (make, "CINE");
5853
sprintf (model, "%d", get4());
5854
fseek (ifp, 12, SEEK_CUR);
5855
switch ((i=get4()) & 0xffffff) {
5856
case 3: filters = 0x94949494; break;
5857
case 4: filters = 0x49494949; break;
5858
default: is_raw = 0;
5860
fseek (ifp, 72, SEEK_CUR);
5861
switch ((get4()+3600) % 360) {
5862
case 270: flip = 4; break;
5863
case 180: flip = 1; break;
5864
case 90: flip = 7; break;
5867
cam_mul[0] = getreal(11);
5868
cam_mul[2] = getreal(11);
5869
maximum = ~(-1 << get4());
5870
fseek (ifp, 668, SEEK_CUR);
5871
shutter = get4()/1000000000.0;
5872
fseek (ifp, off_image, SEEK_SET);
5873
if (shot_select < is_raw)
5874
fseek (ifp, shot_select*8, SEEK_CUR);
5875
data_offset = (INT64) get4() + 8;
5876
data_offset += (INT64) get4() << 32;
5879
char * CLASS foveon_gets (int offset, char *str, int len)
5882
fseek (ifp, offset, SEEK_SET);
5883
for (i=0; i < len-1; i++)
5884
if ((str[i] = get2()) == 0) break;
5889
void CLASS parse_foveon()
5891
int entries, img=0, off, len, tag, save, i, wide, high, pent, poff[256][2];
5892
char name[64], value[64];
5894
order = 0x4949; /* Little-endian */
5895
fseek (ifp, 36, SEEK_SET);
5897
fseek (ifp, -4, SEEK_END);
5898
fseek (ifp, get4(), SEEK_SET);
5899
if (get4() != 0x64434553) return; /* SECd */
5900
entries = (get4(),get4());
5906
fseek (ifp, off, SEEK_SET);
5907
if (get4() != (0x20434553 | (tag << 24))) return;
5909
case 0x47414d49: /* IMAG */
5910
case 0x32414d49: /* IMA2 */
5911
fseek (ifp, 12, SEEK_CUR);
5914
if (wide > raw_width && high > raw_height) {
5917
data_offset = off+24;
5919
fseek (ifp, off+28, SEEK_SET);
5920
if (fgetc(ifp) == 0xff && fgetc(ifp) == 0xd8
5921
&& thumb_length < len-28) {
5922
thumb_offset = off+28;
5923
thumb_length = len-28;
5924
write_thumb = &CLASS jpeg_thumb;
5926
if (++img == 2 && !thumb_length) {
5927
thumb_offset = off+24;
5929
thumb_height = high;
5930
write_thumb = &CLASS foveon_thumb;
5933
case 0x464d4143: /* CAMF */
5934
meta_offset = off+24;
5935
meta_length = len-28;
5936
if (meta_length > 0x20000)
5937
meta_length = 0x20000;
5939
case 0x504f5250: /* PROP */
5940
pent = (get4(),get4());
5941
fseek (ifp, 12, SEEK_CUR);
5943
if ((unsigned) pent > 256) pent=256;
5944
for (i=0; i < pent*2; i++)
5945
poff[0][i] = off + get4()*2;
5946
for (i=0; i < pent; i++) {
5947
foveon_gets (poff[i][0], name, 64);
5948
foveon_gets (poff[i][1], value, 64);
5949
if (!strcmp (name, "ISO"))
5950
iso_speed = atoi(value);
5951
if (!strcmp (name, "CAMMANUF"))
5952
strcpy (make, value);
5953
if (!strcmp (name, "CAMMODEL"))
5954
strcpy (model, value);
5955
if (!strcmp (name, "WB_DESC"))
5956
strcpy (model2, value);
5957
if (!strcmp (name, "TIME"))
5958
timestamp = atoi(value);
5959
if (!strcmp (name, "EXPTIME"))
5960
shutter = atoi(value) / 1000000.0;
5961
if (!strcmp (name, "APERTURE"))
5962
aperture = atof(value);
5963
if (!strcmp (name, "FLENGTH"))
5964
focal_len = atof(value);
5967
timestamp = mktime (gmtime (×tamp));
5970
fseek (ifp, save, SEEK_SET);
5976
All matrices are from Adobe DNG Converter unless otherwise noted.
5978
void CLASS adobe_coeff (const char *make, const char *model)
5980
static const struct {
5982
short black, maximum, trans[12];
5984
{ "AGFAPHOTO DC-833m", 0, 0, /* DJC */
5985
{ 11438,-3762,-1115,-2409,9914,2497,-1227,2295,5300 } },
5986
{ "Apple QuickTake", 0, 0, /* DJC */
5987
{ 21392,-5653,-3353,2406,8010,-415,7166,1427,2078 } },
5988
{ "Canon EOS D2000", 0, 0,
5989
{ 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } },
5990
{ "Canon EOS D6000", 0, 0,
5991
{ 20482,-7172,-3125,-1033,10410,-285,2542,226,3136 } },
5992
{ "Canon EOS D30", 0, 0,
5993
{ 9805,-2689,-1312,-5803,13064,3068,-2438,3075,8775 } },
5994
{ "Canon EOS D60", 0, 0xfa0,
5995
{ 6188,-1341,-890,-7168,14489,2937,-2640,3228,8483 } },
5996
{ "Canon EOS 5D Mark II", 0, 0x3cf0,
5997
{ 4716,603,-830,-7798,15474,2480,-1496,1937,6651 } },
5998
{ "Canon EOS 5D", 0, 0xe6c,
5999
{ 6347,-479,-972,-8297,15954,2480,-1968,2131,7649 } },
6000
{ "Canon EOS 7D", 0, 0x3510,
6001
{ 6844,-996,-856,-3876,11761,2396,-593,1772,6198 } },
6002
{ "Canon EOS 10D", 0, 0xfa0,
6003
{ 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } },
6004
{ "Canon EOS 20Da", 0, 0,
6005
{ 14155,-5065,-1382,-6550,14633,2039,-1623,1824,6561 } },
6006
{ "Canon EOS 20D", 0, 0xfff,
6007
{ 6599,-537,-891,-8071,15783,2424,-1983,2234,7462 } },
6008
{ "Canon EOS 30D", 0, 0,
6009
{ 6257,-303,-1000,-7880,15621,2396,-1714,1904,7046 } },
6010
{ "Canon EOS 40D", 0, 0x3f60,
6011
{ 6071,-747,-856,-7653,15365,2441,-2025,2553,7315 } },
6012
{ "Canon EOS 50D", 0, 0x3d93,
6013
{ 4920,616,-593,-6493,13964,2784,-1774,3178,7005 } },
6014
{ "Canon EOS 300D", 0, 0xfa0,
6015
{ 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } },
6016
{ "Canon EOS 350D", 0, 0xfff,
6017
{ 6018,-617,-965,-8645,15881,2975,-1530,1719,7642 } },
6018
{ "Canon EOS 400D", 0, 0xe8e,
6019
{ 7054,-1501,-990,-8156,15544,2812,-1278,1414,7796 } },
6020
{ "Canon EOS 450D", 0, 0x390d,
6021
{ 5784,-262,-821,-7539,15064,2672,-1982,2681,7427 } },
6022
{ "Canon EOS 500D", 0, 0x3479,
6023
{ 4763,712,-646,-6821,14399,2640,-1921,3276,6561 } },
6024
{ "Canon EOS 1000D", 0, 0xe43,
6025
{ 6771,-1139,-977,-7818,15123,2928,-1244,1437,7533 } },
6026
{ "Canon EOS-1Ds Mark III", 0, 0x3bb0,
6027
{ 5859,-211,-930,-8255,16017,2353,-1732,1887,7448 } },
6028
{ "Canon EOS-1Ds Mark II", 0, 0xe80,
6029
{ 6517,-602,-867,-8180,15926,2378,-1618,1771,7633 } },
6030
{ "Canon EOS-1D Mark IV", 0, 0x3bb0,
6031
{ 6014,-220,-795,-4109,12014,2361,-561,1824,5787 } },
6032
{ "Canon EOS-1D Mark III", 0, 0x3bb0,
6033
{ 6291,-540,-976,-8350,16145,2311,-1714,1858,7326 } },
6034
{ "Canon EOS-1D Mark II N", 0, 0xe80,
6035
{ 6240,-466,-822,-8180,15825,2500,-1801,1938,8042 } },
6036
{ "Canon EOS-1D Mark II", 0, 0xe80,
6037
{ 6264,-582,-724,-8312,15948,2504,-1744,1919,8664 } },
6038
{ "Canon EOS-1DS", 0, 0xe20,
6039
{ 4374,3631,-1743,-7520,15212,2472,-2892,3632,8161 } },
6040
{ "Canon EOS-1D", 0, 0xe20,
6041
{ 6806,-179,-1020,-8097,16415,1687,-3267,4236,7690 } },
6042
{ "Canon EOS", 0, 0,
6043
{ 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } },
6044
{ "Canon PowerShot A530", 0, 0,
6045
{ 0 } }, /* don't want the A5 matrix */
6046
{ "Canon PowerShot A50", 0, 0,
6047
{ -5300,9846,1776,3436,684,3939,-5540,9879,6200,-1404,11175,217 } },
6048
{ "Canon PowerShot A5", 0, 0,
6049
{ -4801,9475,1952,2926,1611,4094,-5259,10164,5947,-1554,10883,547 } },
6050
{ "Canon PowerShot G10", 0, 0,
6051
{ 11093,-3906,-1028,-5047,12492,2879,-1003,1750,5561 } },
6052
{ "Canon PowerShot G11", 0, 0,
6053
{ 12177,-4817,-1069,-1612,9864,2049,-98,850,4471 } },
6054
{ "Canon PowerShot G1", 0, 0,
6055
{ -4778,9467,2172,4743,-1141,4344,-5146,9908,6077,-1566,11051,557 } },
6056
{ "Canon PowerShot G2", 0, 0,
6057
{ 9087,-2693,-1049,-6715,14382,2537,-2291,2819,7790 } },
6058
{ "Canon PowerShot G3", 0, 0,
6059
{ 9212,-2781,-1073,-6573,14189,2605,-2300,2844,7664 } },
6060
{ "Canon PowerShot G5", 0, 0,
6061
{ 9757,-2872,-933,-5972,13861,2301,-1622,2328,7212 } },
6062
{ "Canon PowerShot G6", 0, 0,
6063
{ 9877,-3775,-871,-7613,14807,3072,-1448,1305,7485 } },
6064
{ "Canon PowerShot G9", 0, 0,
6065
{ 7368,-2141,-598,-5621,13254,2625,-1418,1696,5743 } },
6066
{ "Canon PowerShot Pro1", 0, 0,
6067
{ 10062,-3522,-999,-7643,15117,2730,-765,817,7323 } },
6068
{ "Canon PowerShot Pro70", 34, 0,
6069
{ -4155,9818,1529,3939,-25,4522,-5521,9870,6610,-2238,10873,1342 } },
6070
{ "Canon PowerShot Pro90", 0, 0,
6071
{ -4963,9896,2235,4642,-987,4294,-5162,10011,5859,-1770,11230,577 } },
6072
{ "Canon PowerShot S30", 0, 0,
6073
{ 10566,-3652,-1129,-6552,14662,2006,-2197,2581,7670 } },
6074
{ "Canon PowerShot S40", 0, 0,
6075
{ 8510,-2487,-940,-6869,14231,2900,-2318,2829,9013 } },
6076
{ "Canon PowerShot S45", 0, 0,
6077
{ 8163,-2333,-955,-6682,14174,2751,-2077,2597,8041 } },
6078
{ "Canon PowerShot S50", 0, 0,
6079
{ 8882,-2571,-863,-6348,14234,2288,-1516,2172,6569 } },
6080
{ "Canon PowerShot S60", 0, 0,
6081
{ 8795,-2482,-797,-7804,15403,2573,-1422,1996,7082 } },
6082
{ "Canon PowerShot S70", 0, 0,
6083
{ 9976,-3810,-832,-7115,14463,2906,-901,989,7889 } },
6084
{ "Canon PowerShot S90", 0, 0,
6085
{ 12374,-5016,-1049,-1677,9902,2078,-83,852,4683 } },
6086
{ "Canon PowerShot A470", 0, 0, /* DJC */
6087
{ 12513,-4407,-1242,-2680,10276,2405,-878,2215,4734 } },
6088
{ "Canon PowerShot A610", 0, 0, /* DJC */
6089
{ 15591,-6402,-1592,-5365,13198,2168,-1300,1824,5075 } },
6090
{ "Canon PowerShot A620", 0, 0, /* DJC */
6091
{ 15265,-6193,-1558,-4125,12116,2010,-888,1639,5220 } },
6092
{ "Canon PowerShot A630", 0, 0, /* DJC */
6093
{ 14201,-5308,-1757,-6087,14472,1617,-2191,3105,5348 } },
6094
{ "Canon PowerShot A640", 0, 0, /* DJC */
6095
{ 13124,-5329,-1390,-3602,11658,1944,-1612,2863,4885 } },
6096
{ "Canon PowerShot A650", 0, 0, /* DJC */
6097
{ 9427,-3036,-959,-2581,10671,1911,-1039,1982,4430 } },
6098
{ "Canon PowerShot A720", 0, 0, /* DJC */
6099
{ 14573,-5482,-1546,-1266,9799,1468,-1040,1912,3810 } },
6100
{ "Canon PowerShot S3 IS", 0, 0, /* DJC */
6101
{ 14062,-5199,-1446,-4712,12470,2243,-1286,2028,4836 } },
6102
{ "Canon PowerShot SX1 IS", 0, 0,
6103
{ 6578,-259,-502,-5974,13030,3309,-308,1058,4970 } },
6104
{ "Canon PowerShot SX110 IS", 0, 0, /* DJC */
6105
{ 14134,-5576,-1527,-1991,10719,1273,-1158,1929,3581 } },
6106
{ "CASIO EX-S20", 0, 0, /* DJC */
6107
{ 11634,-3924,-1128,-4968,12954,2015,-1588,2648,7206 } },
6108
{ "CASIO EX-Z750", 0, 0, /* DJC */
6109
{ 10819,-3873,-1099,-4903,13730,1175,-1755,3751,4632 } },
6111
{ 3390,480,-500,-800,3610,340,-550,2336,1192 } },
6113
{ 3390,480,-500,-800,3610,340,-550,2336,1192 } },
6115
{ 20183,-4295,-423,-3940,15330,3985,-280,4870,9800 } },
6116
{ "Contax N Digital", 0, 0xf1e,
6117
{ 7777,1285,-1053,-9280,16543,2916,-3677,5679,7060 } },
6118
{ "EPSON R-D1", 0, 0,
6119
{ 6827,-1878,-732,-8429,16012,2564,-704,592,7145 } },
6120
{ "FUJIFILM FinePix E550", 0, 0,
6121
{ 11044,-3888,-1120,-7248,15168,2208,-1531,2277,8069 } },
6122
{ "FUJIFILM FinePix E900", 0, 0,
6123
{ 9183,-2526,-1078,-7461,15071,2574,-2022,2440,8639 } },
6124
{ "FUJIFILM FinePix F8", 0, 0,
6125
{ 11044,-3888,-1120,-7248,15168,2208,-1531,2277,8069 } },
6126
{ "FUJIFILM FinePix F7", 0, 0,
6127
{ 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } },
6128
{ "FUJIFILM FinePix S100FS", 514, 0,
6129
{ 11521,-4355,-1065,-6524,13767,3058,-1466,1984,6045 } },
6130
{ "FUJIFILM FinePix S20Pro", 0, 0,
6131
{ 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } },
6132
{ "FUJIFILM FinePix S2Pro", 128, 0,
6133
{ 12492,-4690,-1402,-7033,15423,1647,-1507,2111,7697 } },
6134
{ "FUJIFILM FinePix S3Pro", 0, 0,
6135
{ 11807,-4612,-1294,-8927,16968,1988,-2120,2741,8006 } },
6136
{ "FUJIFILM FinePix S5Pro", 0, 0,
6137
{ 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } },
6138
{ "FUJIFILM FinePix S5000", 0, 0,
6139
{ 8754,-2732,-1019,-7204,15069,2276,-1702,2334,6982 } },
6140
{ "FUJIFILM FinePix S5100", 0, 0x3e00,
6141
{ 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } },
6142
{ "FUJIFILM FinePix S5500", 0, 0x3e00,
6143
{ 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } },
6144
{ "FUJIFILM FinePix S5200", 0, 0,
6145
{ 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } },
6146
{ "FUJIFILM FinePix S5600", 0, 0,
6147
{ 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } },
6148
{ "FUJIFILM FinePix S6", 0, 0,
6149
{ 12628,-4887,-1401,-6861,14996,1962,-2198,2782,7091 } },
6150
{ "FUJIFILM FinePix S7000", 0, 0,
6151
{ 10190,-3506,-1312,-7153,15051,2238,-2003,2399,7505 } },
6152
{ "FUJIFILM FinePix S9000", 0, 0,
6153
{ 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 } },
6154
{ "FUJIFILM FinePix S9500", 0, 0,
6155
{ 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 } },
6156
{ "FUJIFILM FinePix S9100", 0, 0,
6157
{ 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 } },
6158
{ "FUJIFILM FinePix S9600", 0, 0,
6159
{ 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 } },
6160
{ "FUJIFILM IS-1", 0, 0,
6161
{ 21461,-10807,-1441,-2332,10599,1999,289,875,7703 } },
6162
{ "FUJIFILM IS Pro", 0, 0,
6163
{ 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } },
6164
{ "Imacon Ixpress", 0, 0, /* DJC */
6165
{ 7025,-1415,-704,-5188,13765,1424,-1248,2742,6038 } },
6166
{ "KODAK NC2000", 0, 0,
6167
{ 13891,-6055,-803,-465,9919,642,2121,82,1291 } },
6168
{ "Kodak DCS315C", 8, 0,
6169
{ 17523,-4827,-2510,756,8546,-137,6113,1649,2250 } },
6170
{ "Kodak DCS330C", 8, 0,
6171
{ 20620,-7572,-2801,-103,10073,-396,3551,-233,2220 } },
6172
{ "KODAK DCS420", 0, 0,
6173
{ 10868,-1852,-644,-1537,11083,484,2343,628,2216 } },
6174
{ "KODAK DCS460", 0, 0,
6175
{ 10592,-2206,-967,-1944,11685,230,2206,670,1273 } },
6176
{ "KODAK EOSDCS1", 0, 0,
6177
{ 10592,-2206,-967,-1944,11685,230,2206,670,1273 } },
6178
{ "KODAK EOSDCS3B", 0, 0,
6179
{ 9898,-2700,-940,-2478,12219,206,1985,634,1031 } },
6180
{ "Kodak DCS520C", 180, 0,
6181
{ 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } },
6182
{ "Kodak DCS560C", 188, 0,
6183
{ 20482,-7172,-3125,-1033,10410,-285,2542,226,3136 } },
6184
{ "Kodak DCS620C", 180, 0,
6185
{ 23617,-10175,-3149,-2054,11749,-272,2586,-489,3453 } },
6186
{ "Kodak DCS620X", 185, 0,
6187
{ 13095,-6231,154,12221,-21,-2137,895,4602,2258 } },
6188
{ "Kodak DCS660C", 214, 0,
6189
{ 18244,-6351,-2739,-791,11193,-521,3711,-129,2802 } },
6190
{ "Kodak DCS720X", 0, 0,
6191
{ 11775,-5884,950,9556,1846,-1286,-1019,6221,2728 } },
6192
{ "Kodak DCS760C", 0, 0,
6193
{ 16623,-6309,-1411,-4344,13923,323,2285,274,2926 } },
6194
{ "Kodak DCS Pro SLR", 0, 0,
6195
{ 5494,2393,-232,-6427,13850,2846,-1876,3997,5445 } },
6196
{ "Kodak DCS Pro 14nx", 0, 0,
6197
{ 5494,2393,-232,-6427,13850,2846,-1876,3997,5445 } },
6198
{ "Kodak DCS Pro 14", 0, 0,
6199
{ 7791,3128,-776,-8588,16458,2039,-2455,4006,6198 } },
6200
{ "Kodak ProBack645", 0, 0,
6201
{ 16414,-6060,-1470,-3555,13037,473,2545,122,4948 } },
6202
{ "Kodak ProBack", 0, 0,
6203
{ 21179,-8316,-2918,-915,11019,-165,3477,-180,4210 } },
6204
{ "KODAK P712", 0, 0,
6205
{ 9658,-3314,-823,-5163,12695,2768,-1342,1843,6044 } },
6206
{ "KODAK P850", 0, 0xf7c,
6207
{ 10511,-3836,-1102,-6946,14587,2558,-1481,1792,6246 } },
6208
{ "KODAK P880", 0, 0xfff,
6209
{ 12805,-4662,-1376,-7480,15267,2360,-1626,2194,7904 } },
6210
{ "KODAK EasyShare Z980", 0, 0,
6211
{ 11313,-3559,-1101,-3893,11891,2257,-1214,2398,4908 } },
6212
{ "KODAK EASYSHARE Z1015", 0, 0xef1,
6213
{ 11265,-4286,-992,-4694,12343,2647,-1090,1523,5447 } },
6214
{ "Leaf CMost", 0, 0,
6215
{ 3952,2189,449,-6701,14585,2275,-4536,7349,6536 } },
6216
{ "Leaf Valeo 6", 0, 0,
6217
{ 3952,2189,449,-6701,14585,2275,-4536,7349,6536 } },
6218
{ "Leaf Aptus 54S", 0, 0,
6219
{ 8236,1746,-1314,-8251,15953,2428,-3673,5786,5771 } },
6220
{ "Leaf Aptus 65", 0, 0,
6221
{ 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 } },
6222
{ "Leaf Aptus 75", 0, 0,
6223
{ 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 } },
6225
{ 8236,1746,-1314,-8251,15953,2428,-3673,5786,5771 } },
6226
{ "Mamiya ZD", 0, 0,
6227
{ 7645,2579,-1363,-8689,16717,2015,-3712,5941,5961 } },
6228
{ "Micron 2010", 110, 0, /* DJC */
6229
{ 16695,-3761,-2151,155,9682,163,3433,951,4904 } },
6230
{ "Minolta DiMAGE 5", 0, 0xf7d,
6231
{ 8983,-2942,-963,-6556,14476,2237,-2426,2887,8014 } },
6232
{ "Minolta DiMAGE 7Hi", 0, 0xf7d,
6233
{ 11368,-3894,-1242,-6521,14358,2339,-2475,3056,7285 } },
6234
{ "Minolta DiMAGE 7", 0, 0xf7d,
6235
{ 9144,-2777,-998,-6676,14556,2281,-2470,3019,7744 } },
6236
{ "Minolta DiMAGE A1", 0, 0xf8b,
6237
{ 9274,-2547,-1167,-8220,16323,1943,-2273,2720,8340 } },
6238
{ "MINOLTA DiMAGE A200", 0, 0,
6239
{ 8560,-2487,-986,-8112,15535,2771,-1209,1324,7743 } },
6240
{ "Minolta DiMAGE A2", 0, 0xf8f,
6241
{ 9097,-2726,-1053,-8073,15506,2762,-966,981,7763 } },
6242
{ "Minolta DiMAGE Z2", 0, 0, /* DJC */
6243
{ 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 } },
6244
{ "MINOLTA DYNAX 5", 0, 0xffb,
6245
{ 10284,-3283,-1086,-7957,15762,2316,-829,882,6644 } },
6246
{ "MINOLTA DYNAX 7", 0, 0xffb,
6247
{ 10239,-3104,-1099,-8037,15727,2451,-927,925,6871 } },
6248
{ "MOTOROLA PIXL", 0, 0, /* DJC */
6249
{ 8898,-989,-1033,-3292,11619,1674,-661,3178,5216 } },
6250
{ "NIKON D100", 0, 0,
6251
{ 5902,-933,-782,-8983,16719,2354,-1402,1455,6464 } },
6252
{ "NIKON D1H", 0, 0,
6253
{ 7577,-2166,-926,-7454,15592,1934,-2377,2808,8606 } },
6254
{ "NIKON D1X", 0, 0,
6255
{ 7702,-2245,-975,-9114,17242,1875,-2679,3055,8521 } },
6256
{ "NIKON D1", 0, 0, /* multiplied by 2.218750, 1.0, 1.148438 */
6257
{ 16772,-4726,-2141,-7611,15713,1972,-2846,3494,9521 } },
6258
{ "NIKON D200", 0, 0xfbc,
6259
{ 8367,-2248,-763,-8758,16447,2422,-1527,1550,8053 } },
6260
{ "NIKON D2H", 0, 0,
6261
{ 5710,-901,-615,-8594,16617,2024,-2975,4120,6830 } },
6262
{ "NIKON D2X", 0, 0,
6263
{ 10231,-2769,-1255,-8301,15900,2552,-797,680,7148 } },
6264
{ "NIKON D3000", 0, 0,
6265
{ 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } },
6266
{ "NIKON D300", 0, 0,
6267
{ 9030,-1992,-715,-8465,16302,2255,-2689,3217,8069 } },
6268
{ "NIKON D3X", 0, 0,
6269
{ 7171,-1986,-648,-8085,15555,2718,-2170,2512,7457 } },
6270
{ "NIKON D3S", 0, 0,
6271
{ 8828,-2406,-694,-4874,12603,2541,-660,1509,7587 } },
6273
{ 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } },
6274
{ "NIKON D40X", 0, 0,
6275
{ 8819,-2543,-911,-9025,16928,2151,-1329,1213,8449 } },
6276
{ "NIKON D40", 0, 0,
6277
{ 6992,-1668,-806,-8138,15748,2543,-874,850,7897 } },
6278
{ "NIKON D5000", 0, 0xf00,
6279
{ 7309,-1403,-519,-8474,16008,2622,-2433,2826,8064 } },
6280
{ "NIKON D50", 0, 0,
6281
{ 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } },
6282
{ "NIKON D60", 0, 0,
6283
{ 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } },
6284
{ "NIKON D700", 0, 0,
6285
{ 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } },
6286
{ "NIKON D70", 0, 0,
6287
{ 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } },
6288
{ "NIKON D80", 0, 0,
6289
{ 8629,-2410,-883,-9055,16940,2171,-1490,1363,8520 } },
6290
{ "NIKON D90", 0, 0xf00,
6291
{ 7309,-1403,-519,-8474,16008,2622,-2434,2826,8064 } },
6292
{ "NIKON E950", 0, 0x3dd, /* DJC */
6293
{ -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } },
6294
{ "NIKON E995", 0, 0, /* copied from E5000 */
6295
{ -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
6296
{ "NIKON E2100", 0, 0, /* copied from Z2, new white balance */
6297
{ 13142,-4152,-1596,-4655,12374,2282,-1769,2696,6711} },
6298
{ "NIKON E2500", 0, 0,
6299
{ -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
6300
{ "NIKON E4300", 0, 0, /* copied from Minolta DiMAGE Z2 */
6301
{ 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 } },
6302
{ "NIKON E4500", 0, 0,
6303
{ -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
6304
{ "NIKON E5000", 0, 0,
6305
{ -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
6306
{ "NIKON E5400", 0, 0,
6307
{ 9349,-2987,-1001,-7919,15766,2266,-2098,2680,6839 } },
6308
{ "NIKON E5700", 0, 0,
6309
{ -5368,11478,2368,5537,-113,3148,-4969,10021,5782,778,9028,211 } },
6310
{ "NIKON E8400", 0, 0,
6311
{ 7842,-2320,-992,-8154,15718,2599,-1098,1342,7560 } },
6312
{ "NIKON E8700", 0, 0,
6313
{ 8489,-2583,-1036,-8051,15583,2643,-1307,1407,7354 } },
6314
{ "NIKON E8800", 0, 0,
6315
{ 7971,-2314,-913,-8451,15762,2894,-1442,1520,7610 } },
6316
{ "NIKON COOLPIX P6000", 0, 0,
6317
{ 9698,-3367,-914,-4706,12584,2368,-837,968,5801 } },
6318
{ "OLYMPUS C5050", 0, 0,
6319
{ 10508,-3124,-1273,-6079,14294,1901,-1653,2306,6237 } },
6320
{ "OLYMPUS C5060", 0, 0,
6321
{ 10445,-3362,-1307,-7662,15690,2058,-1135,1176,7602 } },
6322
{ "OLYMPUS C7070", 0, 0,
6323
{ 10252,-3531,-1095,-7114,14850,2436,-1451,1723,6365 } },
6324
{ "OLYMPUS C70", 0, 0,
6325
{ 10793,-3791,-1146,-7498,15177,2488,-1390,1577,7321 } },
6326
{ "OLYMPUS C80", 0, 0,
6327
{ 8606,-2509,-1014,-8238,15714,2703,-942,979,7760 } },
6328
{ "OLYMPUS E-10", 0, 0xffc0,
6329
{ 12745,-4500,-1416,-6062,14542,1580,-1934,2256,6603 } },
6330
{ "OLYMPUS E-1", 0, 0xfff0,
6331
{ 11846,-4767,-945,-7027,15878,1089,-2699,4122,8311 } },
6332
{ "OLYMPUS E-20", 0, 0xffc0,
6333
{ 13173,-4732,-1499,-5807,14036,1895,-2045,2452,7142 } },
6334
{ "OLYMPUS E-300", 0, 0,
6335
{ 7828,-1761,-348,-5788,14071,1830,-2853,4518,6557 } },
6336
{ "OLYMPUS E-330", 0, 0,
6337
{ 8961,-2473,-1084,-7979,15990,2067,-2319,3035,8249 } },
6338
{ "OLYMPUS E-30", 0, 0xfbc,
6339
{ 8144,-1861,-1111,-7763,15894,1929,-1865,2542,7607 } },
6340
{ "OLYMPUS E-3", 0, 0xf99,
6341
{ 9487,-2875,-1115,-7533,15606,2010,-1618,2100,7389 } },
6342
{ "OLYMPUS E-400", 0, 0xfff0,
6343
{ 6169,-1483,-21,-7107,14761,2536,-2904,3580,8568 } },
6344
{ "OLYMPUS E-410", 0, 0xf6a,
6345
{ 8856,-2582,-1026,-7761,15766,2082,-2009,2575,7469 } },
6346
{ "OLYMPUS E-420", 0, 0xfd7,
6347
{ 8746,-2425,-1095,-7594,15612,2073,-1780,2309,7416 } },
6348
{ "OLYMPUS E-450", 0, 0xfd2,
6349
{ 8745,-2425,-1095,-7594,15613,2073,-1780,2309,7416 } },
6350
{ "OLYMPUS E-500", 0, 0xfff0,
6351
{ 8136,-1968,-299,-5481,13742,1871,-2556,4205,6630 } },
6352
{ "OLYMPUS E-510", 0, 0xf6a,
6353
{ 8785,-2529,-1033,-7639,15624,2112,-1783,2300,7817 } },
6354
{ "OLYMPUS E-520", 0, 0xfd2,
6355
{ 8344,-2322,-1020,-7596,15635,2048,-1748,2269,7287 } },
6356
{ "OLYMPUS E-620", 0, 0xfb9,
6357
{ 8453,-2198,-1092,-7609,15681,2008,-1725,2337,7824 } },
6358
{ "OLYMPUS E-P1", 0, 0xffd,
6359
{ 8343,-2050,-1021,-7715,15705,2103,-1831,2380,8235 } },
6360
{ "OLYMPUS SP350", 0, 0,
6361
{ 12078,-4836,-1069,-6671,14306,2578,-786,939,7418 } },
6362
{ "OLYMPUS SP3", 0, 0,
6363
{ 11766,-4445,-1067,-6901,14421,2707,-1029,1217,7572 } },
6364
{ "OLYMPUS SP500UZ", 0, 0xfff,
6365
{ 9493,-3415,-666,-5211,12334,3260,-1548,2262,6482 } },
6366
{ "OLYMPUS SP510UZ", 0, 0xffe,
6367
{ 10593,-3607,-1010,-5881,13127,3084,-1200,1805,6721 } },
6368
{ "OLYMPUS SP550UZ", 0, 0xffe,
6369
{ 11597,-4006,-1049,-5432,12799,2957,-1029,1750,6516 } },
6370
{ "OLYMPUS SP560UZ", 0, 0xff9,
6371
{ 10915,-3677,-982,-5587,12986,2911,-1168,1968,6223 } },
6372
{ "OLYMPUS SP570UZ", 0, 0,
6373
{ 11522,-4044,-1146,-4736,12172,2904,-988,1829,6039 } },
6374
{ "PENTAX *ist DL2", 0, 0,
6375
{ 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
6376
{ "PENTAX *ist DL", 0, 0,
6377
{ 10829,-2838,-1115,-8339,15817,2696,-837,680,11939 } },
6378
{ "PENTAX *ist DS2", 0, 0,
6379
{ 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
6380
{ "PENTAX *ist DS", 0, 0,
6381
{ 10371,-2333,-1206,-8688,16231,2602,-1230,1116,11282 } },
6382
{ "PENTAX *ist D", 0, 0,
6383
{ 9651,-2059,-1189,-8881,16512,2487,-1460,1345,10687 } },
6384
{ "PENTAX K10D", 0, 0,
6385
{ 9566,-2863,-803,-7170,15172,2112,-818,803,9705 } },
6386
{ "PENTAX K1", 0, 0,
6387
{ 11095,-3157,-1324,-8377,15834,2720,-1108,947,11688 } },
6388
{ "PENTAX K20D", 0, 0,
6389
{ 9427,-2714,-868,-7493,16092,1373,-2199,3264,7180 } },
6390
{ "PENTAX K200D", 0, 0,
6391
{ 9186,-2678,-907,-8693,16517,2260,-1129,1094,8524 } },
6392
{ "PENTAX K2000", 0, 0,
6393
{ 11057,-3604,-1155,-5152,13046,2329,-282,375,8104 } },
6394
{ "PENTAX K-m", 0, 0,
6395
{ 11057,-3604,-1155,-5152,13046,2329,-282,375,8104 } },
6396
{ "PENTAX K-x", 0, 0,
6397
{ 8843,-2837,-625,-5025,12644,2668,-411,1234,7410 } },
6398
{ "PENTAX K-7", 0, 0,
6399
{ 9142,-2947,-678,-8648,16967,1663,-2224,2898,8615 } },
6400
{ "Panasonic DMC-FZ8", 0, 0xf7f0,
6401
{ 8986,-2755,-802,-6341,13575,3077,-1476,2144,6379 } },
6402
{ "Panasonic DMC-FZ18", 0, 0,
6403
{ 9932,-3060,-935,-5809,13331,2753,-1267,2155,5575 } },
6404
{ "Panasonic DMC-FZ28", 15, 0xfff,
6405
{ 10109,-3488,-993,-5412,12812,2916,-1305,2140,5543 } },
6406
{ "Panasonic DMC-FZ30", 0, 0xf94c,
6407
{ 10976,-4029,-1141,-7918,15491,2600,-1670,2071,8246 } },
6408
{ "Panasonic DMC-FZ35", 147, 0xfff,
6409
{ 9938,-2780,-890,-4604,12393,2480,-1117,2304,4620 } },
6410
{ "Panasonic DMC-FZ50", 0, 0xfff0, /* aka "LEICA V-LUX1" */
6411
{ 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } },
6412
{ "Panasonic DMC-L10", 15, 0xf96,
6413
{ 8025,-1942,-1050,-7920,15904,2100,-2456,3005,7039 } },
6414
{ "Panasonic DMC-L1", 0, 0xf7fc, /* aka "LEICA DIGILUX 3" */
6415
{ 8054,-1885,-1025,-8349,16367,2040,-2805,3542,7629 } },
6416
{ "Panasonic DMC-LC1", 0, 0, /* aka "LEICA DIGILUX 2" */
6417
{ 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } },
6418
{ "Panasonic DMC-LX1", 0, 0xf7f0, /* aka "LEICA D-LUX2" */
6419
{ 10704,-4187,-1230,-8314,15952,2501,-920,945,8927 } },
6420
{ "Panasonic DMC-LX2", 0, 0, /* aka "LEICA D-LUX3" */
6421
{ 8048,-2810,-623,-6450,13519,3272,-1700,2146,7049 } },
6422
{ "Panasonic DMC-LX3", 15, 0xfff, /* aka "LEICA D-LUX4" */
6423
{ 8128,-2668,-655,-6134,13307,3161,-1782,2568,6083 } },
6424
{ "Panasonic DMC-FX150", 15, 0xfff,
6425
{ 9082,-2907,-925,-6119,13377,3058,-1797,2641,5609 } },
6426
{ "Panasonic DMC-G1", 15, 0xfff,
6427
{ 8199,-2065,-1056,-8124,16156,2033,-2458,3022,7220 } },
6428
{ "Panasonic DMC-GF1", 15, 0xf92,
6429
{ 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } },
6430
{ "Panasonic DMC-GH1", 15, 0xf92,
6431
{ 6299,-1466,-532,-6535,13852,2969,-2331,3112,5984 } },
6432
{ "Phase One H 20", 0, 0, /* DJC */
6433
{ 1313,1855,-109,-6715,15908,808,-327,1840,6020 } },
6434
{ "Phase One P 2", 0, 0,
6435
{ 2905,732,-237,-8134,16626,1476,-3038,4253,7517 } },
6436
{ "Phase One P 30", 0, 0,
6437
{ 4516,-245,-37,-7020,14976,2173,-3206,4671,7087 } },
6438
{ "Phase One P 45", 0, 0,
6439
{ 5053,-24,-117,-5684,14076,1702,-2619,4492,5849 } },
6440
{ "Phase One P65", 0, 0, /* DJC */
6441
{ 8522,1268,-1916,-7706,16350,1358,-2397,4344,4923 } },
6442
{ "SAMSUNG GX-1", 0, 0,
6443
{ 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
6444
{ "SAMSUNG S85", 0, 0, /* DJC */
6445
{ 11885,-3968,-1473,-4214,12299,1916,-835,1655,5549 } },
6446
{ "Sinar", 0, 0, /* DJC */
6447
{ 16442,-2956,-2422,-2877,12128,750,-1136,6066,4559 } },
6448
{ "SONY DSC-F828", 491, 0,
6449
{ 7924,-1910,-777,-8226,15459,2998,-1517,2199,6818,-7242,11401,3481 } },
6450
{ "SONY DSC-R1", 512, 0,
6451
{ 8512,-2641,-694,-8042,15670,2526,-1821,2117,7414 } },
6452
{ "SONY DSC-V3", 0, 0,
6453
{ 7511,-2571,-692,-7894,15088,3060,-948,1111,8128 } },
6454
{ "SONY DSLR-A100", 0, 0xfeb,
6455
{ 9437,-2811,-774,-8405,16215,2290,-710,596,7181 } },
6456
{ "SONY DSLR-A200", 0, 0,
6457
{ 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } },
6458
{ "SONY DSLR-A230", 0, 0, /* copied */
6459
{ 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } },
6460
{ "SONY DSLR-A300", 0, 0,
6461
{ 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } },
6462
{ "SONY DSLR-A330", 0, 0,
6463
{ 9847,-3091,-929,-8485,16346,2225,-714,595,7103 } },
6464
{ "SONY DSLR-A350", 0, 0xffc,
6465
{ 6038,-1484,-578,-9146,16746,2513,-875,746,7217 } },
6466
{ "SONY DSLR-A380", 0, 0,
6467
{ 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } },
6468
{ "SONY DSLR-A5", 254, 0x1ffe,
6469
{ 4950,-580,-103,-5228,12542,3029,-709,1435,7371 } },
6470
{ "SONY DSLR-A700", 254, 0x1ffe,
6471
{ 5775,-805,-359,-8574,16295,2391,-1943,2341,7249 } },
6472
{ "SONY DSLR-A850", 256, 0x1ffe,
6473
{ 5413,-1162,-365,-5665,13098,2866,-608,1179,8440 } },
6474
{ "SONY DSLR-A900", 254, 0x1ffe,
6475
{ 5209,-1072,-397,-8845,16120,2919,-1618,1803,8654 } }
6477
double cam_xyz[4][3];
6481
sprintf (name, "%s %s", make, model);
6482
for (i=0; i < sizeof table / sizeof *table; i++)
6483
if (!strncmp (name, table[i].prefix, strlen(table[i].prefix))) {
6484
if (table[i].black) black = (ushort) table[i].black;
6485
if (table[i].maximum) maximum = (ushort) table[i].maximum;
6486
if (table[i].trans[0]) {
6487
for (j=0; j < 12; j++)
6488
cam_xyz[0][j] = table[i].trans[j] / 10000.0;
6489
cam_xyz_coeff (cam_xyz);
6495
void CLASS simple_coeff (int index)
6497
static const float table[][12] = {
6498
/* index 0 -- all Foveon cameras */
6499
{ 1.4032,-0.2231,-0.1016,-0.5263,1.4816,0.017,-0.0112,0.0183,0.9113 },
6500
/* index 1 -- Kodak DC20 and DC25 */
6501
{ 2.25,0.75,-1.75,-0.25,-0.25,0.75,0.75,-0.25,-0.25,-1.75,0.75,2.25 },
6502
/* index 2 -- Logitech Fotoman Pixtura */
6503
{ 1.893,-0.418,-0.476,-0.495,1.773,-0.278,-1.017,-0.655,2.672 },
6504
/* index 3 -- Nikon E880, E900, and E990 */
6505
{ -1.936280, 1.800443, -1.448486, 2.584324,
6506
1.405365, -0.524955, -0.289090, 0.408680,
6507
-1.204965, 1.082304, 2.941367, -1.818705 }
6511
for (raw_color = i=0; i < 3; i++)
6512
FORCC rgb_cam[i][c] = table[index][i*colors+c];
6515
short CLASS guess_byte_order (int words)
6519
double diff, sum[2] = {0,0};
6521
fread (test[0], 2, 2, ifp);
6522
for (words-=2; words--; ) {
6523
fread (test[t], 2, 1, ifp);
6524
for (msb=0; msb < 2; msb++) {
6525
diff = (test[t^2][msb] << 8 | test[t^2][!msb])
6526
- (test[t ][msb] << 8 | test[t ][!msb]);
6527
sum[msb] += diff*diff;
6531
return sum[0] < sum[1] ? 0x4d4d : 0x4949;
6534
float CLASS find_green (int bps, int bite, int off0, int off1)
6537
int vbits, col, i, c;
6538
ushort img[2][2064];
6542
fseek (ifp, c ? off1:off0, SEEK_SET);
6543
for (vbits=col=0; col < width; col++) {
6544
for (vbits -= bps; vbits < 0; vbits += bite) {
6546
for (i=0; i < bite; i+=8)
6547
bitbuf |= (unsigned) (fgetc(ifp) << i);
6549
img[c][col] = bitbuf << (64-bps-vbits) >> (64-bps);
6553
sum[ c & 1] += ABS(img[0][c]-img[1][c+1]);
6554
sum[~c & 1] += ABS(img[1][c]-img[0][c+1]);
6556
return 100 * log(sum[0]/sum[1]);
6560
Identify which camera created this file, and set global variables
6563
void CLASS identify()
6566
int hlen, fsize, i, c, is_canon;
6568
static const struct {
6570
char make[12], model[19], withjpeg;
6572
{ 62464, "Kodak", "DC20" ,0 },
6573
{ 124928, "Kodak", "DC20" ,0 },
6574
{ 1652736, "Kodak", "DCS200" ,0 },
6575
{ 4159302, "Kodak", "C330" ,0 },
6576
{ 4162462, "Kodak", "C330" ,0 },
6577
{ 460800, "Kodak", "C603v" ,0 },
6578
{ 614400, "Kodak", "C603v" ,0 },
6579
{ 6163328, "Kodak", "C603" ,0 },
6580
{ 6166488, "Kodak", "C603" ,0 },
6581
{ 9116448, "Kodak", "C603y" ,0 },
6582
{ 311696, "ST Micro", "STV680 VGA" ,0 }, /* SPYz */
6583
{ 787456, "Creative", "PC-CAM 600" ,0 },
6584
{ 1138688, "Minolta", "RD175" ,0 },
6585
{ 3840000, "Foculus", "531C" ,0 },
6586
{ 786432, "AVT", "F-080C" ,0 },
6587
{ 1447680, "AVT", "F-145C" ,0 },
6588
{ 1920000, "AVT", "F-201C" ,0 },
6589
{ 5067304, "AVT", "F-510C" ,0 },
6590
{ 10134608, "AVT", "F-510C" ,0 },
6591
{ 16157136, "AVT", "F-810C" ,0 },
6592
{ 1409024, "Sony", "XCD-SX910CR" ,0 },
6593
{ 2818048, "Sony", "XCD-SX910CR" ,0 },
6594
{ 3884928, "Micron", "2010" ,0 },
6595
{ 6624000, "Pixelink", "A782" ,0 },
6596
{ 13248000, "Pixelink", "A782" ,0 },
6597
{ 6291456, "RoverShot","3320AF" ,0 },
6598
{ 6553440, "Canon", "PowerShot A460" ,0 },
6599
{ 6653280, "Canon", "PowerShot A530" ,0 },
6600
{ 6573120, "Canon", "PowerShot A610" ,0 },
6601
{ 9219600, "Canon", "PowerShot A620" ,0 },
6602
{ 9243240, "Canon", "PowerShot A470" ,0 },
6603
{ 10341600, "Canon", "PowerShot A720" ,0 },
6604
{ 10383120, "Canon", "PowerShot A630" ,0 },
6605
{ 12945240, "Canon", "PowerShot A640" ,0 },
6606
{ 15636240, "Canon", "PowerShot A650" ,0 },
6607
{ 5298000, "Canon", "PowerShot SD300" ,0 },
6608
{ 7710960, "Canon", "PowerShot S3 IS" ,0 },
6609
{ 15467760, "Canon", "PowerShot SX110 IS",0 },
6610
{ 5939200, "OLYMPUS", "C770UZ" ,0 },
6611
{ 1581060, "NIKON", "E900" ,1 }, /* or E900s,E910 */
6612
{ 2465792, "NIKON", "E950" ,1 }, /* or E800,E700 */
6613
{ 2940928, "NIKON", "E2100" ,1 }, /* or E2500 */
6614
{ 4771840, "NIKON", "E990" ,1 }, /* or E995, Oly C3030Z */
6615
{ 4775936, "NIKON", "E3700" ,1 }, /* or Optio 33WR */
6616
{ 5869568, "NIKON", "E4300" ,1 }, /* or DiMAGE Z2 */
6617
{ 5865472, "NIKON", "E4500" ,1 },
6618
{ 7438336, "NIKON", "E5000" ,1 }, /* or E5700 */
6619
{ 8998912, "NIKON", "COOLPIX S6" ,1 },
6620
{ 1976352, "CASIO", "QV-2000UX" ,1 },
6621
{ 3217760, "CASIO", "QV-3*00EX" ,1 },
6622
{ 6218368, "CASIO", "QV-5700" ,1 },
6623
{ 6054400, "CASIO", "QV-R41" ,1 },
6624
{ 7530816, "CASIO", "QV-R51" ,1 },
6625
{ 7684000, "CASIO", "QV-4000" ,1 },
6626
{ 2937856, "CASIO", "EX-S20" ,1 },
6627
{ 4948608, "CASIO", "EX-S100" ,1 },
6628
{ 7542528, "CASIO", "EX-Z50" ,1 },
6629
{ 7753344, "CASIO", "EX-Z55" ,1 },
6630
{ 7816704, "CASIO", "EX-Z60" ,1 },
6631
{ 10843712, "CASIO", "EX-Z75" ,1 },
6632
{ 10834368, "CASIO", "EX-Z750" ,1 },
6633
{ 12310144, "CASIO", "EX-Z850" ,1 },
6634
{ 7426656, "CASIO", "EX-P505" ,1 },
6635
{ 9313536, "CASIO", "EX-P600" ,1 },
6636
{ 10979200, "CASIO", "EX-P700" ,1 },
6637
{ 3178560, "PENTAX", "Optio S" ,1 },
6638
{ 4841984, "PENTAX", "Optio S" ,1 },
6639
{ 6114240, "PENTAX", "Optio S4" ,1 }, /* or S4i, CASIO EX-Z4 */
6640
{ 10702848, "PENTAX", "Optio 750Z" ,1 },
6641
{ 15980544, "AGFAPHOTO","DC-833m" ,1 },
6642
{ 16098048, "SAMSUNG", "S85" ,1 },
6643
{ 16215552, "SAMSUNG", "S85" ,1 },
6644
{ 12582980, "Sinar", "" ,0 },
6645
{ 33292868, "Sinar", "" ,0 },
6646
{ 44390468, "Sinar", "" ,0 } };
6647
static const char *corp[] =
6648
{ "Canon", "NIKON", "EPSON", "KODAK", "Kodak", "OLYMPUS", "PENTAX",
6649
"MINOLTA", "Minolta", "Konica", "CASIO", "Sinar", "Phase One",
6650
"SAMSUNG", "Mamiya", "MOTOROLA" };
6652
tiff_flip = flip = filters = -1; /* 0 is valid, so -1 is unknown */
6653
raw_height = raw_width = fuji_width = fuji_layout = cr2_slice[0] = 0;
6654
maximum = height = width = top_margin = left_margin = 0;
6655
cdesc[0] = desc[0] = artist[0] = make[0] = model[0] = model2[0] = 0;
6656
iso_speed = shutter = aperture = focal_len = unique_id = 0;
6657
memset (gpsdata, 0, sizeof gpsdata);
6658
memset (white, 0, sizeof white);
6659
thumb_offset = thumb_length = thumb_width = thumb_height = 0;
6660
load_raw = thumb_load_raw = 0;
6661
write_thumb = &CLASS jpeg_thumb;
6662
data_offset = meta_length = tiff_bps = tiff_compress = 0;
6663
kodak_cbpp = zero_after_ff = dng_version = load_flags = 0;
6664
timestamp = shot_order = tiff_samples = black = is_foveon = 0;
6665
mix_green = profile_length = data_error = zero_is_bad = 0;
6666
pixel_aspect = is_raw = raw_color = 1;
6667
tile_width = tile_length = INT_MAX;
6668
for (i=0; i < 4; i++) {
6669
cam_mul[i] = i == 1;
6671
FORC3 cmatrix[c][i] = 0;
6672
FORC3 rgb_cam[c][i] = c == i;
6675
for (i=0; i < 0x4000; i++) curve[i] = i;
6679
fseek (ifp, 0, SEEK_SET);
6680
fread (head, 1, 32, ifp);
6681
fseek (ifp, 0, SEEK_END);
6683
if ((cp = (char *) memmem (head, 32, "MMMM", 4)) ||
6684
(cp = (char *) memmem (head, 32, "IIII", 4))) {
6685
parse_phase_one (cp-head);
6686
if (cp-head) parse_tiff(0);
6687
} else if (order == 0x4949 || order == 0x4d4d) {
6688
if (!memcmp (head+6,"HEAPCCDR",8)) {
6690
parse_ciff (hlen, fsize - hlen);
6694
} else if (!memcmp (head,"\xff\xd8\xff\xe1",4) &&
6695
!memcmp (head+6,"Exif",4)) {
6696
fseek (ifp, 4, SEEK_SET);
6697
data_offset = 4 + get2();
6698
fseek (ifp, data_offset, SEEK_SET);
6699
if (fgetc(ifp) != 0xff)
6702
} else if (!memcmp (head+25,"ARECOYK",7)) {
6703
strcpy (make, "Contax");
6704
strcpy (model,"N Digital");
6705
fseek (ifp, 33, SEEK_SET);
6707
fseek (ifp, 60, SEEK_SET);
6708
FORC4 cam_mul[c ^ (c >> 1)] = get4();
6709
} else if (!strcmp (head, "PXN")) {
6710
strcpy (make, "Logitech");
6711
strcpy (model,"Fotoman Pixtura");
6712
} else if (!strcmp (head, "qktk")) {
6713
strcpy (make, "Apple");
6714
strcpy (model,"QuickTake 100");
6715
} else if (!strcmp (head, "qktn")) {
6716
strcpy (make, "Apple");
6717
strcpy (model,"QuickTake 150");
6718
} else if (!memcmp (head,"FUJIFILM",8)) {
6719
fseek (ifp, 84, SEEK_SET);
6720
thumb_offset = get4();
6721
thumb_length = get4();
6722
fseek (ifp, 92, SEEK_SET);
6723
parse_fuji (get4());
6724
if (thumb_offset > 120) {
6725
fseek (ifp, 120, SEEK_SET);
6726
is_raw += (i = get4()) && 1;
6727
if (is_raw == 2 && shot_select)
6730
fseek (ifp, 100, SEEK_SET);
6731
data_offset = get4();
6732
parse_tiff (thumb_offset+12);
6733
} else if (!memcmp (head,"RIFF",4)) {
6734
fseek (ifp, 0, SEEK_SET);
6736
} else if (!memcmp (head,"\0\001\0\001\0@",6)) {
6737
fseek (ifp, 6, SEEK_SET);
6738
fread (make, 1, 8, ifp);
6739
fread (model, 1, 8, ifp);
6740
fread (model2, 1, 16, ifp);
6741
data_offset = get2();
6744
raw_height = get2();
6745
load_raw = &CLASS nokia_load_raw;
6746
filters = 0x61616161;
6747
} else if (!memcmp (head,"DSC-Image",9))
6749
else if (!memcmp (head,"PWAD",4))
6751
else if (!memcmp (head,"\0MRM",4))
6753
else if (!memcmp (head,"FOVb",4))
6755
else if (!memcmp (head,"CI",2))
6758
for (i=0; i < sizeof table / sizeof *table; i++)
6759
if (fsize == table[i].fsize) {
6760
strcpy (make, table[i].make );
6761
strcpy (model, table[i].model);
6762
if (table[i].withjpeg)
6763
parse_external_jpeg();
6765
if (make[0] == 0) parse_smal (0, fsize);
6766
if (make[0] == 0) parse_jpeg (is_raw = 0);
6768
for (i=0; i < sizeof corp / sizeof *corp; i++)
6769
if (strstr (make, corp[i])) /* Simplify company names */
6770
strcpy (make, corp[i]);
6771
if (!strncmp (make,"KODAK",5) &&
6772
((cp = strstr(model," DIGITAL CAMERA")) ||
6773
(cp = strstr(model," Digital Camera")) ||
6774
(cp = strstr(model,"FILE VERSION"))))
6776
cp = make + strlen(make); /* Remove trailing spaces */
6777
while (*--cp == ' ') *cp = 0;
6778
cp = model + strlen(model);
6779
while (*--cp == ' ') *cp = 0;
6780
i = strlen(make); /* Remove make from model */
6781
if (!strncasecmp (model, make, i) && model[i++] == ' ')
6782
memmove (model, model+i, 64-i);
6783
if (!strncmp (model,"Digital Camera ",15))
6784
strcpy (model, model+15);
6785
desc[511] = artist[63] = make[63] = model[63] = model2[63] = 0;
6786
if (!is_raw) goto notraw;
6788
if (!height) height = raw_height;
6789
if (!width) width = raw_width;
6791
width = height + fuji_width;
6795
if (height == 2624 && width == 3936) /* Pentax K10D and Samsung GX10 */
6796
{ height = 2616; width = 3896; }
6797
if (height == 3136 && width == 4864) /* Pentax K20D */
6798
{ height = 3124; width = 4688; }
6799
if (height == 3136 && width == 4736) /* Pentax K-7 */
6800
{ height = 3122; width = 4684;
6801
top_margin = 2; filters = 0x16161616; }
6802
if (height == 3014 && width == 4096) /* Ricoh GX200 */
6805
if (filters == UINT_MAX) filters = 0;
6806
if (filters) is_raw = tiff_samples;
6807
else colors = tiff_samples;
6808
if (tiff_compress == 1)
6809
load_raw = &CLASS adobe_dng_load_raw_nc;
6810
if (tiff_compress == 7)
6811
load_raw = &CLASS adobe_dng_load_raw_lj;
6814
if ((is_canon = !strcmp(make,"Canon")))
6815
load_raw = memcmp (head+6,"HEAPCCDR",8) ?
6816
&CLASS lossless_jpeg_load_raw : &CLASS canon_compressed_load_raw;
6817
if (!strcmp(make,"NIKON")) {
6819
load_raw = &CLASS packed_load_raw;
6820
if (model[0] == 'E')
6821
load_flags |= !data_offset << 2 | 2;
6823
if (!strcmp(make,"CASIO")) {
6824
load_raw = &CLASS packed_load_raw;
6828
/* Set parameters based on camera name (for non-DNG files). */
6831
if (height*2 < width) pixel_aspect = 0.5;
6832
if (height > width) pixel_aspect = 2;
6834
load_raw = &CLASS foveon_load_raw;
6836
} else if (is_canon && tiff_bps == 15) {
6838
case 3344: width -= 66;
6839
case 3872: width -= 6;
6842
load_raw = &CLASS canon_sraw_load_raw;
6843
} else if (!strcmp(model,"PowerShot 600")) {
6847
pixel_aspect = 607/628.0;
6849
filters = 0xe1e4e1e4;
6850
load_raw = &CLASS canon_600_load_raw;
6851
} else if (!strcmp(model,"PowerShot A5") ||
6852
!strcmp(model,"PowerShot A5 Zoom")) {
6856
pixel_aspect = 256/235.0;
6858
filters = 0x1e4e1e4e;
6860
} else if (!strcmp(model,"PowerShot A50")) {
6865
filters = 0x1b4e4b1e;
6867
} else if (!strcmp(model,"PowerShot Pro70")) {
6871
filters = 0x1e4b4e1b;
6873
} else if (!strcmp(model,"PowerShot SD300")) {
6881
} else if (!strcmp(model,"PowerShot A460")) {
6889
} else if (!strcmp(model,"PowerShot A530")) {
6897
} else if (!strcmp(model,"PowerShot A610")) {
6898
if (canon_s2is()) strcpy (model+10, "S2 IS");
6906
} else if (!strcmp(model,"PowerShot A620")) {
6914
} else if (!strcmp(model,"PowerShot A470")) {
6922
} else if (!strcmp(model,"PowerShot A720")) {
6930
} else if (!strcmp(model,"PowerShot A630")) {
6938
} else if (!strcmp(model,"PowerShot A640")) {
6946
} else if (!strcmp(model,"PowerShot A650")) {
6954
} else if (!strcmp(model,"PowerShot S3 IS")) {
6963
load_raw = &CLASS packed_load_raw;
6965
if (raw_width > 1600) zero_is_bad = 1;
6966
} else if (!strcmp(model,"PowerShot SX110 IS")) {
6973
load_raw = &CLASS packed_load_raw;
6976
} else if (!strcmp(model,"PowerShot Pro90 IS")) {
6979
filters = 0xb4b4b4b4;
6980
} else if (is_canon && raw_width == 2144) {
6985
if (!strcmp(model,"PowerShot G1")) {
6987
filters = 0xb4b4b4b4;
6989
} else if (is_canon && raw_width == 2224) {
6994
} else if (is_canon && raw_width == 2376) {
6999
} else if (is_canon && raw_width == 2672) {
7004
} else if (is_canon && raw_width == 3152) {
7009
if (unique_id == 0x80000170)
7010
adobe_coeff ("Canon","EOS 300D");
7011
} else if (is_canon && raw_width == 3160) {
7016
} else if (is_canon && raw_width == 3344) {
7021
} else if (!strcmp(model,"EOS D2000C")) {
7022
filters = 0x61616161;
7024
} else if (is_canon && raw_width == 3516) {
7027
if (unique_id == 0x80000189)
7028
adobe_coeff ("Canon","EOS 350D");
7030
} else if (is_canon && raw_width == 3596) {
7034
} else if (is_canon && raw_width == 3744) {
7039
} else if (is_canon && raw_width == 3944) {
7044
} else if (is_canon && raw_width == 3948) {
7048
if (unique_id == 0x80000236)
7049
adobe_coeff ("Canon","EOS 400D");
7050
if (unique_id == 0x80000254)
7051
adobe_coeff ("Canon","EOS 1000D");
7053
} else if (is_canon && raw_width == 3984) {
7058
} else if (is_canon && raw_width == 4104) {
7063
} else if (is_canon && raw_width == 4152) {
7067
} else if (is_canon && raw_width == 4312) {
7071
if (unique_id == 0x80000176)
7072
adobe_coeff ("Canon","EOS 450D");
7074
} else if (is_canon && raw_width == 4476) {
7078
} else if (is_canon && raw_width == 4480) {
7083
filters = 0x49494949;
7084
} else if (is_canon && raw_width == 1208) {
7085
top_margin = unique_id == 0x80000261 ? 51:26;
7087
raw_width = width *= 4;
7088
if (unique_id == 0x80000252)
7089
adobe_coeff ("Canon","EOS 500D");
7091
} else if (is_canon && raw_width == 1280) {
7092
height -= top_margin = 45;
7096
} else if (is_canon && raw_width == 1340) {
7099
raw_width = width *= 4;
7101
} else if (is_canon && raw_width == 1448) {
7104
raw_width = width *= 4;
7106
} else if (is_canon && raw_width == 5108) {
7110
height -= top_margin;
7111
width -= left_margin;
7112
} else if (is_canon && raw_width == 5712) {
7117
} else if (!strcmp(model,"D1")) {
7118
cam_mul[0] *= 256/527.0;
7119
cam_mul[2] *= 256/317.0;
7120
} else if (!strcmp(model,"D1X")) {
7123
} else if (!strcmp(model,"D40X") ||
7124
!strcmp(model,"D60") ||
7125
!strcmp(model,"D80") ||
7126
!strcmp(model,"D3000")) {
7129
} else if (!strcmp(model,"D3") ||
7130
!strcmp(model,"D3S") ||
7131
!strcmp(model,"D700")) {
7134
} else if (!strcmp(model,"D5000")) {
7136
} else if (!strncmp(model,"D40",3) ||
7137
!strncmp(model,"D50",3) ||
7138
!strncmp(model,"D70",3)) {
7140
} else if (!strcmp(model,"D90")) {
7142
} else if (!strcmp(model,"D100")) {
7143
if (tiff_compress == 34713 && !nikon_is_compressed()) {
7144
load_raw = &CLASS packed_load_raw;
7146
raw_width = (width += 3) + 3;
7148
} else if (!strcmp(model,"D200")) {
7151
filters = 0x94949494;
7152
} else if (!strncmp(model,"D2H",3)) {
7155
} else if (!strncmp(model,"D2X",3)) {
7156
if (width == 3264) width -= 32;
7158
} else if (!strncmp(model,"D300",4)) {
7160
} else if (!strcmp(model,"COOLPIX P6000")) {
7162
filters = 0x94949494;
7163
} else if (fsize == 1581060) {
7169
filters = 0x1e1e1e1e;
7171
pre_mul[0] = 1.2085;
7172
pre_mul[1] = 1.0943;
7173
pre_mul[3] = 1.1103;
7175
} else if (fsize == 2465792) {
7180
filters = 0x4b4b4b4b;
7181
adobe_coeff ("NIKON","E950");
7184
load_raw = &CLASS packed_load_raw;
7186
} else if (fsize == 4771840) {
7190
filters = 0xe1e1e1e1;
7191
load_raw = &CLASS packed_load_raw;
7193
if (!timestamp && nikon_e995())
7194
strcpy (model, "E995");
7195
if (strcmp(model,"E995")) {
7196
filters = 0xb4b4b4b4;
7202
} else if (!strcmp(model,"E2100")) {
7203
if (!timestamp && !nikon_e2100()) goto cp_e2500;
7207
} else if (!strcmp(model,"E2500")) {
7209
strcpy (model, "E2500");
7213
filters = 0x4b4b4b4b;
7214
} else if (fsize == 4775936) {
7217
load_raw = &CLASS packed_load_raw;
7219
if (!timestamp) nikon_3700();
7220
if (model[0] == 'E' && atoi(model+1) < 3700)
7221
filters = 0x49494949;
7222
if (!strcmp(model,"Optio 33WR")) {
7224
filters = 0x16161616;
7226
if (make[0] == 'O') {
7227
i = find_green (12, 32, 0, fsize/2);
7228
c = find_green (12, 32, 0, 3096);
7229
if (abs(i) < abs(c)) {
7233
if (i < 0) filters = 0x61616161;
7235
} else if (fsize == 5869568) {
7238
filters = 0x16161616;
7239
if (!timestamp && minolta_z2()) {
7240
strcpy (make, "Minolta");
7241
strcpy (model,"DiMAGE Z2");
7243
load_raw = &CLASS packed_load_raw;
7244
load_flags = 6 + 24*(make[0] == 'M');
7245
} else if (!strcmp(model,"E4500")) {
7249
filters = 0xb4b4b4b4;
7250
} else if (fsize == 7438336) {
7254
filters = 0xb4b4b4b4;
7255
} else if (fsize == 8998912) {
7259
load_raw = &CLASS packed_load_raw;
7261
} else if (!strcmp(make,"FUJIFILM")) {
7262
if (!strcmp(model+7,"S2Pro")) {
7263
strcpy (model+7," S2Pro");
7269
if (is_raw == 2 && shot_select)
7271
top_margin = (raw_height - height)/2;
7272
left_margin = (raw_width - width )/2;
7274
data_offset += (shot_select > 0) * ( fuji_layout ?
7275
(raw_width *= 2) : raw_height*raw_width*2 );
7276
if (load_raw == &CLASS fuji_load_raw) {
7277
fuji_width = width >> !fuji_layout;
7278
width = (height >> fuji_layout) + fuji_width;
7279
raw_height = height;
7281
if (~fuji_width & 1) filters = 0x49494949;
7283
} else if (!strcmp(model,"RD175")) {
7287
filters = 0x61616161;
7288
load_raw = &CLASS minolta_rd175_load_raw;
7289
} else if (!strcmp(model,"KD-400Z")) {
7294
} else if (!strcmp(model,"KD-510Z")) {
7296
} else if (!strcasecmp(make,"MINOLTA")) {
7297
load_raw = &CLASS unpacked_load_raw;
7299
if (!strncmp(model,"DiMAGE A",8)) {
7300
if (!strcmp(model,"DiMAGE A200"))
7301
filters = 0x49494949;
7303
load_raw = &CLASS packed_load_raw;
7304
} else if (!strncmp(model,"ALPHA",5) ||
7305
!strncmp(model,"DYNAX",5) ||
7306
!strncmp(model,"MAXXUM",6)) {
7307
sprintf (model+20, "DYNAX %-10s", model+6+(model[0]=='M'));
7308
adobe_coeff (make, model+20);
7309
load_raw = &CLASS packed_load_raw;
7310
} else if (!strncmp(model,"DiMAGE G",8)) {
7311
if (model[8] == '4') {
7314
} else if (model[8] == '5') {
7319
} else if (model[8] == '6') {
7324
filters = 0x61616161;
7326
load_raw = &CLASS unpacked_load_raw;
7330
} else if (!strcmp(model,"*ist D")) {
7332
} else if (!strcmp(model,"*ist DS")) {
7334
} else if (!strcmp(model,"K20D")) {
7335
filters = 0x16161616;
7336
} else if (!strcmp(model,"K-x")) {
7338
filters = 0x16161616;
7339
} else if (!strcmp(model,"Optio S")) {
7340
if (fsize == 3178560) {
7343
load_raw = &CLASS eight_bit_load_raw;
7350
load_raw = &CLASS packed_load_raw;
7353
} else if (fsize == 6114240) {
7357
load_raw = &CLASS packed_load_raw;
7359
} else if (!strcmp(model,"Optio 750Z")) {
7362
load_raw = &CLASS packed_load_raw;
7364
} else if (!strcmp(model,"DC-833m")) {
7368
filters = 0x61616161;
7369
load_raw = &CLASS unpacked_load_raw;
7371
} else if (!strncmp(model,"S85",3)) {
7374
raw_width = fsize/height/2;
7376
load_raw = &CLASS unpacked_load_raw;
7378
} else if (!strcmp(model,"STV680 VGA")) {
7381
load_raw = &CLASS eight_bit_load_raw;
7383
filters = 0x16161616;
7385
} else if (!strcmp(model,"N95")) {
7386
height = raw_height - (top_margin = 2);
7387
} else if (!strcmp(model,"531C")) {
7390
load_raw = &CLASS unpacked_load_raw;
7391
filters = 0x49494949;
7392
} else if (!strcmp(model,"F-080C")) {
7395
load_raw = &CLASS eight_bit_load_raw;
7396
} else if (!strcmp(model,"F-145C")) {
7399
load_raw = &CLASS eight_bit_load_raw;
7400
} else if (!strcmp(model,"F-201C")) {
7403
load_raw = &CLASS eight_bit_load_raw;
7404
} else if (!strcmp(model,"F-510C")) {
7407
load_raw = fsize < 7500000 ?
7408
&CLASS eight_bit_load_raw : &CLASS unpacked_load_raw;
7410
} else if (!strcmp(model,"F-810C")) {
7413
load_raw = &CLASS unpacked_load_raw;
7415
} else if (!strcmp(model,"XCD-SX910CR")) {
7419
filters = 0x49494949;
7421
load_raw = fsize < 2000000 ?
7422
&CLASS eight_bit_load_raw : &CLASS unpacked_load_raw;
7423
} else if (!strcmp(model,"2010")) {
7427
filters = 0x16161616;
7430
load_raw = &CLASS unpacked_load_raw;
7431
} else if (!strcmp(model,"A782")) {
7434
filters = 0x61616161;
7435
load_raw = fsize < 10000000 ?
7436
&CLASS eight_bit_load_raw : &CLASS unpacked_load_raw;
7438
} else if (!strcmp(model,"3320AF")) {
7440
raw_width = width = 2048;
7441
filters = 0x61616161;
7442
load_raw = &CLASS unpacked_load_raw;
7444
fseek (ifp, 0x300000, SEEK_SET);
7445
if ((order = guess_byte_order(0x10000)) == 0x4d4d) {
7446
height -= (top_margin = 16);
7447
width -= (left_margin = 28);
7449
strcpy (make, "ISG");
7452
} else if (!strcmp(make,"Hasselblad")) {
7453
if (load_raw == &CLASS lossless_jpeg_load_raw)
7454
load_raw = &CLASS hasselblad_load_raw;
7455
if (raw_width == 7262) {
7460
filters = 0x61616161;
7461
} else if (raw_width == 4090) {
7462
strcpy (model, "V96C");
7463
height -= (top_margin = 6);
7464
width -= (left_margin = 3) + 7;
7465
filters = 0x61616161;
7467
} else if (!strcmp(make,"Sinar")) {
7468
if (!memcmp(head,"8BPS",4)) {
7469
fseek (ifp, 14, SEEK_SET);
7472
filters = 0x61616161;
7475
if (!load_raw) load_raw = &CLASS unpacked_load_raw;
7477
} else if (!strcmp(make,"Leaf")) {
7479
fseek (ifp, data_offset, SEEK_SET);
7480
if (ljpeg_start (&jh, 1) && jh.bits == 15)
7482
if (tiff_samples > 1) filters = 0;
7483
if (tiff_samples > 1 || tile_length < raw_height)
7484
load_raw = &CLASS leaf_hdr_load_raw;
7485
if ((width | height) == 2048) {
7486
if (tiff_samples == 1) {
7488
strcpy (cdesc, "RBTG");
7489
strcpy (model, "CatchLight");
7490
top_margin = 8; left_margin = 18; height = 2032; width = 2016;
7492
strcpy (model, "DCB2");
7493
top_margin = 10; left_margin = 16; height = 2028; width = 2022;
7495
} else if (width+height == 3144+2060) {
7496
if (!model[0]) strcpy (model, "Cantare");
7497
if (width > height) {
7498
top_margin = 6; left_margin = 32; height = 2048; width = 3072;
7499
filters = 0x61616161;
7501
left_margin = 6; top_margin = 32; width = 2048; height = 3072;
7502
filters = 0x16161616;
7504
if (!cam_mul[0] || model[0] == 'V') filters = 0;
7505
else is_raw = tiff_samples;
7506
} else if (width == 2116) {
7507
strcpy (model, "Valeo 6");
7508
height -= 2 * (top_margin = 30);
7509
width -= 2 * (left_margin = 55);
7510
filters = 0x49494949;
7511
} else if (width == 3171) {
7512
strcpy (model, "Valeo 6");
7513
height -= 2 * (top_margin = 24);
7514
width -= 2 * (left_margin = 24);
7515
filters = 0x16161616;
7517
} else if (!strcmp(make,"LEICA") || !strcmp(make,"Panasonic")) {
7519
if ((fsize-data_offset) / (width*8/7) == height)
7520
load_raw = &CLASS panasonic_load_raw;
7521
if (!load_raw) load_raw = &CLASS unpacked_load_raw;
7524
adobe_coeff ("Panasonic","DMC-LC1"); break;
7530
if (height > 2326) {
7533
filters = 0x49494949;
7536
adobe_coeff ("Panasonic","DMC-FZ8"); break;
7541
filters = 0x49494949;
7543
adobe_coeff ("Panasonic","DMC-L1"); break;
7547
adobe_coeff ("Panasonic","DMC-FZ30"); break;
7556
height = 2480 - (top_margin = 10);
7557
filters = 0x49494949;
7559
adobe_coeff ("Panasonic","DMC-FZ18"); break;
7566
if (--height == 2798 && (height = 2760))
7568
else filters = 0x49494949;
7571
adobe_coeff ("Panasonic","DMC-FZ50"); break;
7574
filters = 0x49494949;
7575
adobe_coeff ("Panasonic","DMC-L10"); break;
7578
if (height == 2450) height -= 2;
7581
lx3: filters = 0x16161616;
7583
adobe_coeff ("Panasonic","DMC-LX3");
7589
adobe_coeff ("Panasonic","DMC-LX1"); break;
7592
if (height == 2250) goto lx3;
7594
filters = 0x16161616;
7595
if (!strncmp(model,"DMC-FZ3",7)) {
7597
adobe_coeff ("Panasonic","DMC-FZ35"); break;
7599
filters = 0x49494949;
7600
if (!strcmp(model,"DMC-GH1")) break;
7602
adobe_coeff ("Panasonic","DMC-G1"); break;
7606
filters = 0x49494949;
7607
adobe_coeff ("Panasonic","DMC-GH1"); break;
7611
filters = 0x49494949;
7614
if ((height -= 39) == 2400)
7617
adobe_coeff ("Panasonic","DMC-LX2"); break;
7621
filters = 0x16161616;
7622
adobe_coeff ("Panasonic","DMC-FX150"); break;
7624
} else if (!strcmp(model,"C770UZ")) {
7627
filters = 0x16161616;
7628
load_raw = &CLASS packed_load_raw;
7630
} else if (!strcmp(make,"OLYMPUS")) {
7631
height += height & 1;
7633
if (width == 4100) width -= 4;
7634
if (load_raw == &CLASS olympus_load_raw) {
7637
} else if (!strcmp(model,"E-10") ||
7638
!strncmp(model,"E-20",4)) {
7640
} else if (!strcmp(model,"E-300") ||
7641
!strcmp(model,"E-500")) {
7643
if (load_raw == &CLASS unpacked_load_raw) {
7647
} else if (!strcmp(model,"E-330")) {
7649
if (load_raw == &CLASS unpacked_load_raw)
7651
} else if (!strcmp(model,"SP550UZ")) {
7652
thumb_length = fsize - (thumb_offset = 0xa39800);
7656
} else if (!strcmp(model,"N Digital")) {
7659
filters = 0x61616161;
7660
data_offset = 0x1a00;
7661
load_raw = &CLASS packed_load_raw;
7662
} else if (!strcmp(model,"DSC-F828")) {
7665
data_offset = 862144;
7666
load_raw = &CLASS sony_load_raw;
7667
filters = 0x9c9c9c9c;
7669
strcpy (cdesc, "RGBE");
7670
} else if (!strcmp(model,"DSC-V3")) {
7673
data_offset = 787392;
7674
load_raw = &CLASS sony_load_raw;
7675
} else if (!strcmp(make,"SONY") && raw_width == 3984) {
7676
adobe_coeff ("SONY","DSC-R1");
7679
} else if (!strcmp(model,"DSLR-A100")) {
7681
width = ++raw_width;
7682
filters = 0x61616161;
7683
} else if (!strcmp(model,"DSLR-A350")) {
7685
} else if (!strcmp(model,"PIXL")) {
7686
height -= top_margin = 4;
7687
width -= left_margin = 32;
7688
gamma_curve (0, 7, 1, 255);
7689
} else if (!strcmp(model,"C603v")) {
7692
if (fsize < 614400 || find_green (16, 16, 3840, 5120) < 25) goto c603v;
7693
strcpy (model,"KAI-0340");
7697
load_raw = &CLASS unpacked_load_raw;
7698
} else if (!strcmp(model,"C603y")) {
7703
load_raw = &CLASS kodak_yrgb_load_raw;
7704
gamma_curve (0, 3.875, 1, 255);
7705
} else if (!strcmp(model,"C603")) {
7706
raw_height = height = 2152;
7707
raw_width = width = 2864;
7709
} else if (!strcmp(model,"C330")) {
7718
if ((data_offset = fsize - raw_height*raw_width)) {
7719
fseek (ifp, 168, SEEK_SET);
7720
read_shorts (curve, 256);
7721
} else gamma_curve (0, 3.875, 1, 255);
7722
load_raw = &CLASS eight_bit_load_raw;
7723
} else if (!strcmp(model,"EASYSHARE Z1015 IS")) {
7727
} else if (!strcmp(model,"EasyShare Z980")) {
7731
data_offset = 0x15000;
7732
load_raw = &CLASS packed_load_raw;
7733
} else if (!strcasecmp(make,"KODAK")) {
7734
if (filters == UINT_MAX) filters = 0x61616161;
7735
if (!strncmp(model,"NC2000",6)) {
7738
} else if (!strcmp(model,"EOSDCS3B")) {
7741
} else if (!strcmp(model,"EOSDCS1")) {
7744
} else if (!strcmp(model,"DCS420")) {
7747
} else if (!strncmp(model,"DCS460 ",7)) {
7751
} else if (!strcmp(model,"DCS460A")) {
7756
} else if (!strcmp(model,"DCS660M")) {
7760
} else if (!strcmp(model,"DCS760M")) {
7764
if (!strcmp(model+4,"20X"))
7765
strcpy (cdesc, "MYCY");
7766
if (strstr(model,"DC25")) {
7767
strcpy (model, "DC25");
7768
data_offset = 15424;
7770
if (!strncmp(model,"DC2",3)) {
7772
if (fsize < 100000) {
7773
raw_width = 256; width = 249;
7774
pixel_aspect = (4.0*height) / (3.0*width);
7776
raw_width = 512; width = 501;
7777
pixel_aspect = (493.0*height) / (373.0*width);
7779
data_offset += raw_width + 1;
7781
filters = 0x8d8d8d8d;
7786
load_raw = &CLASS eight_bit_load_raw;
7787
} else if (!strcmp(model,"40")) {
7788
strcpy (model, "DC40");
7792
load_raw = &CLASS kodak_radc_load_raw;
7793
} else if (strstr(model,"DC50")) {
7794
strcpy (model, "DC50");
7797
data_offset = 19712;
7798
load_raw = &CLASS kodak_radc_load_raw;
7799
} else if (strstr(model,"DC120")) {
7800
strcpy (model, "DC120");
7803
pixel_aspect = height/0.75/width;
7804
load_raw = tiff_compress == 7 ?
7805
&CLASS kodak_jpeg_load_raw : &CLASS kodak_dc120_load_raw;
7806
} else if (!strcmp(model,"DCS200")) {
7809
thumb_offset = 6144;
7811
write_thumb = &CLASS layer_thumb;
7814
data_offset = 79872;
7815
load_raw = &CLASS eight_bit_load_raw;
7818
} else if (!strcmp(model,"Fotoman Pixtura")) {
7822
load_raw = &CLASS kodak_radc_load_raw;
7823
filters = 0x61616161;
7825
} else if (!strcmp(model,"QuickTake 100")) {
7826
fseek (ifp, 544, SEEK_SET);
7829
data_offset = (get4(),get2()) == 30 ? 738:736;
7830
if (height > width) {
7832
fseek (ifp, data_offset-6, SEEK_SET);
7833
flip = ~get2() & 3 ? 5:6;
7835
load_raw = &CLASS quicktake_100_load_raw;
7836
filters = 0x61616161;
7837
} else if (!strcmp(model,"QuickTake 150")) {
7838
data_offset = 738 - head[5];
7839
if (head[5]) strcpy (model+10, "200");
7840
load_raw = &CLASS kodak_radc_load_raw;
7843
filters = 0x61616161;
7844
} else if (!strcmp(make,"Rollei") && !load_raw) {
7845
switch (raw_width) {
7858
filters = 0x16161616;
7859
load_raw = &CLASS rollei_load_raw;
7860
} else if (!strcmp(model,"PC-CAM 600")) {
7862
data_offset = width = 1024;
7863
filters = 0x49494949;
7864
load_raw = &CLASS eight_bit_load_raw;
7865
} else if (!strcmp(model,"QV-2000UX")) {
7868
data_offset = width * 2;
7869
load_raw = &CLASS eight_bit_load_raw;
7870
} else if (fsize == 3217760) {
7874
load_raw = &CLASS eight_bit_load_raw;
7875
} else if (!strcmp(model,"QV-4000")) {
7878
load_raw = &CLASS unpacked_load_raw;
7880
} else if (!strcmp(model,"QV-5700")) {
7885
} else if (!strcmp(model,"QV-R41")) {
7890
} else if (!strcmp(model,"QV-R51")) {
7894
} else if (!strcmp(model,"EX-S20")) {
7899
} else if (!strcmp(model,"EX-S100")) {
7903
} else if (!strcmp(model,"EX-Z50")) {
7907
} else if (!strcmp(model,"EX-Z55")) {
7911
} else if (!strcmp(model,"EX-Z60")) {
7915
filters = 0x16161616;
7917
} else if (!strcmp(model,"EX-Z75")) {
7922
} else if (!strcmp(model,"EX-Z750")) {
7927
} else if (!strcmp(model,"EX-Z850")) {
7932
} else if (!strcmp(model,"EX-P505")) {
7937
} else if (fsize == 9313536) { /* EX-P600 or QV-R61 */
7941
} else if (!strcmp(model,"EX-P700")) {
7947
sprintf (model, "%dx%d", width, height);
7948
if (filters == UINT_MAX) filters = 0x94949494;
7949
if (raw_color) adobe_coeff (make, model);
7950
if (load_raw == &CLASS kodak_radc_load_raw)
7951
if (raw_color) adobe_coeff ("Apple","Quicktake");
7952
if (thumb_offset && !thumb_height) {
7953
fseek (ifp, thumb_offset, SEEK_SET);
7954
if (ljpeg_start (&jh, 1)) {
7955
thumb_width = jh.wide;
7956
thumb_height = jh.high;
7960
if (!tiff_bps) tiff_bps = 12;
7961
if (!maximum) maximum = (1 << tiff_bps) - 1;
7962
if (!load_raw || height < 22) is_raw = 0;
7964
if (load_raw == &CLASS kodak_jpeg_load_raw) {
7965
fprintf (stderr,_("%s: You must link dcraw with libjpeg!!\n"), ifname);
7970
strcpy (cdesc, colors == 3 ? "RGB":"GMCY");
7971
if (!raw_height) raw_height = height;
7972
if (!raw_width ) raw_width = width;
7973
if (filters && colors == 3)
7974
for (i=0; i < 32; i+=4) {
7975
if ((filters >> i & 15) == 9)
7977
if ((filters >> i & 15) == 6)
7981
if (flip == -1) flip = tiff_flip;
7982
if (flip == -1) flip = 0;
7986
void CLASS apply_profile (const char *input, const char *output)
7989
cmsHPROFILE hInProfile=0, hOutProfile=0;
7990
cmsHTRANSFORM hTransform;
7994
cmsErrorAction (LCMS_ERROR_SHOW);
7995
if (strcmp (input, "embed"))
7996
hInProfile = cmsOpenProfileFromFile (input, "r");
7997
else if (profile_length) {
7998
prof = (char *) malloc (profile_length);
7999
merror (prof, "apply_profile()");
8000
fseek (ifp, profile_offset, SEEK_SET);
8001
fread (prof, 1, profile_length, ifp);
8002
hInProfile = cmsOpenProfileFromMem (prof, profile_length);
8005
fprintf (stderr,_("%s has no embedded profile.\n"), ifname);
8006
if (!hInProfile) return;
8008
hOutProfile = cmsCreate_sRGBProfile();
8009
else if ((fp = fopen (output, "rb"))) {
8010
fread (&size, 4, 1, fp);
8011
fseek (fp, 0, SEEK_SET);
8012
oprof = (unsigned *) malloc (size = ntohl(size));
8013
merror (oprof, "apply_profile()");
8014
fread (oprof, 1, size, fp);
8016
if (!(hOutProfile = cmsOpenProfileFromMem (oprof, size))) {
8021
fprintf (stderr,_("Cannot open file %s!\n"), output);
8022
if (!hOutProfile) goto quit;
8024
fprintf (stderr,_("Applying color profile...\n"));
8025
hTransform = cmsCreateTransform (hInProfile, TYPE_RGBA_16,
8026
hOutProfile, TYPE_RGBA_16, INTENT_PERCEPTUAL, 0);
8027
cmsDoTransform (hTransform, image, image, width*height);
8028
raw_color = 1; /* Don't use rgb_cam with a profile */
8029
cmsDeleteTransform (hTransform);
8030
cmsCloseProfile (hOutProfile);
8032
cmsCloseProfile (hInProfile);
8036
void CLASS convert_to_rgb()
8038
int row, col, c, i, j, k;
8040
float out[3], out_cam[3][4];
8041
double num, inverse[3][3];
8042
static const double xyzd50_srgb[3][3] =
8043
{ { 0.436083, 0.385083, 0.143055 },
8044
{ 0.222507, 0.716888, 0.060608 },
8045
{ 0.013930, 0.097097, 0.714022 } };
8046
static const double rgb_rgb[3][3] =
8047
{ { 1,0,0 }, { 0,1,0 }, { 0,0,1 } };
8048
static const double adobe_rgb[3][3] =
8049
{ { 0.715146, 0.284856, 0.000000 },
8050
{ 0.000000, 1.000000, 0.000000 },
8051
{ 0.000000, 0.041166, 0.958839 } };
8052
static const double wide_rgb[3][3] =
8053
{ { 0.593087, 0.404710, 0.002206 },
8054
{ 0.095413, 0.843149, 0.061439 },
8055
{ 0.011621, 0.069091, 0.919288 } };
8056
static const double prophoto_rgb[3][3] =
8057
{ { 0.529317, 0.330092, 0.140588 },
8058
{ 0.098368, 0.873465, 0.028169 },
8059
{ 0.016879, 0.117663, 0.865457 } };
8060
static const double (*out_rgb[])[3] =
8061
{ rgb_rgb, adobe_rgb, wide_rgb, prophoto_rgb, xyz_rgb };
8062
static const char *name[] =
8063
{ "sRGB", "Adobe RGB (1998)", "WideGamut D65", "ProPhoto D65", "XYZ" };
8064
static const unsigned phead[] =
8065
{ 1024, 0, 0x2100000, 0x6d6e7472, 0x52474220, 0x58595a20, 0, 0, 0,
8066
0x61637370, 0, 0, 0x6e6f6e65, 0, 0, 0, 0, 0xf6d6, 0x10000, 0xd32d };
8068
{ 10, 0x63707274, 0, 36, /* cprt */
8069
0x64657363, 0, 40, /* desc */
8070
0x77747074, 0, 20, /* wtpt */
8071
0x626b7074, 0, 20, /* bkpt */
8072
0x72545243, 0, 14, /* rTRC */
8073
0x67545243, 0, 14, /* gTRC */
8074
0x62545243, 0, 14, /* bTRC */
8075
0x7258595a, 0, 20, /* rXYZ */
8076
0x6758595a, 0, 20, /* gXYZ */
8077
0x6258595a, 0, 20 }; /* bXYZ */
8078
static const unsigned pwhite[] = { 0xf351, 0x10000, 0x116cc };
8079
unsigned pcurve[] = { 0x63757276, 0, 1, 0x1000000 };
8081
gamma_curve (gamm[0], gamm[1], 0, 0);
8082
memcpy (out_cam, rgb_cam, sizeof out_cam);
8083
raw_color |= colors == 1 || document_mode ||
8084
output_color < 1 || output_color > 5;
8086
oprof = (unsigned *) calloc (phead[0], 1);
8087
merror (oprof, "convert_to_rgb()");
8088
memcpy (oprof, phead, sizeof phead);
8089
if (output_color == 5) oprof[4] = oprof[5];
8090
oprof[0] = 132 + 12*pbody[0];
8091
for (i=0; i < pbody[0]; i++) {
8092
oprof[oprof[0]/4] = i ? (i > 1 ? 0x58595a20 : 0x64657363) : 0x74657874;
8093
pbody[i*3+2] = oprof[0];
8094
oprof[0] += (pbody[i*3+3] + 3) & -4;
8096
memcpy (oprof+32, pbody, sizeof pbody);
8097
oprof[pbody[5]/4+2] = strlen(name[output_color-1]) + 1;
8098
memcpy ((char *)oprof+pbody[8]+8, pwhite, sizeof pwhite);
8099
pcurve[3] = (short)(256/gamm[5]+0.5) << 16;
8100
for (i=4; i < 7; i++)
8101
memcpy ((char *)oprof+pbody[i*3+2], pcurve, sizeof pcurve);
8102
pseudoinverse ((double (*)[3]) out_rgb[output_color-1], inverse, 3);
8103
for (i=0; i < 3; i++)
8104
for (j=0; j < 3; j++) {
8105
for (num = k=0; k < 3; k++)
8106
num += xyzd50_srgb[i][k] * inverse[j][k];
8107
oprof[pbody[j*3+23]/4+i+2] = num * 0x10000 + 0.5;
8109
for (i=0; i < phead[0]/4; i++)
8110
oprof[i] = htonl(oprof[i]);
8111
strcpy ((char *)oprof+pbody[2]+8, "auto-generated by dcraw");
8112
strcpy ((char *)oprof+pbody[5]+12, name[output_color-1]);
8113
for (i=0; i < 3; i++)
8114
for (j=0; j < colors; j++)
8115
for (out_cam[i][j] = k=0; k < 3; k++)
8116
out_cam[i][j] += out_rgb[output_color-1][i][k] * rgb_cam[k][j];
8119
fprintf (stderr, raw_color ? _("Building histograms...\n") :
8120
_("Converting to %s colorspace...\n"), name[output_color-1]);
8122
memset (histogram, 0, sizeof histogram);
8123
for (img=image[0], row=0; row < height; row++)
8124
for (col=0; col < width; col++, img+=4) {
8126
out[0] = out[1] = out[2] = 0;
8128
out[0] += out_cam[0][c] * img[c];
8129
out[1] += out_cam[1][c] * img[c];
8130
out[2] += out_cam[2][c] * img[c];
8132
FORC3 img[c] = CLIP((int) out[c]);
8134
else if (document_mode)
8135
img[0] = img[FC(row,col)];
8136
FORCC histogram[c][img[c] >> 3]++;
8138
if (colors == 4 && output_color) colors = 3;
8139
if (document_mode && filters) colors = 1;
8142
void CLASS fuji_rotate()
8148
ushort wide, high, (*img)[4], (*pix)[4];
8150
if (!fuji_width) return;
8152
fprintf (stderr,_("Rotating image 45 degrees...\n"));
8153
fuji_width = (fuji_width - 1 + shrink) >> shrink;
8155
wide = fuji_width / step;
8156
high = (height - fuji_width) / step;
8157
img = (ushort (*)[4]) calloc (wide*high, sizeof *img);
8158
merror (img, "fuji_rotate()");
8160
for (row=0; row < high; row++)
8161
for (col=0; col < wide; col++) {
8162
ur = r = fuji_width + (row-col)*step;
8163
uc = c = (row+col)*step;
8164
if (ur > height-2 || uc > width-2) continue;
8167
pix = image + ur*width + uc;
8168
for (i=0; i < colors; i++)
8169
img[row*wide+col][i] =
8170
(pix[ 0][i]*(1-fc) + pix[ 1][i]*fc) * (1-fr) +
8171
(pix[width][i]*(1-fc) + pix[width+1][i]*fc) * fr;
8180
void CLASS stretch()
8182
ushort newdim, (*img)[4], *pix0, *pix1;
8186
if (pixel_aspect == 1) return;
8187
if (verbose) fprintf (stderr,_("Stretching the image...\n"));
8188
if (pixel_aspect < 1) {
8189
newdim = height / pixel_aspect + 0.5;
8190
img = (ushort (*)[4]) calloc (width*newdim, sizeof *img);
8191
merror (img, "stretch()");
8192
for (rc=row=0; row < newdim; row++, rc+=pixel_aspect) {
8193
frac = rc - (c = rc);
8194
pix0 = pix1 = image[c*width];
8195
if (c+1 < height) pix1 += width*4;
8196
for (col=0; col < width; col++, pix0+=4, pix1+=4)
8197
FORCC img[row*width+col][c] = pix0[c]*(1-frac) + pix1[c]*frac + 0.5;
8201
newdim = width * pixel_aspect + 0.5;
8202
img = (ushort (*)[4]) calloc (height*newdim, sizeof *img);
8203
merror (img, "stretch()");
8204
for (rc=col=0; col < newdim; col++, rc+=1/pixel_aspect) {
8205
frac = rc - (c = rc);
8206
pix0 = pix1 = image[c];
8207
if (c+1 < width) pix1 += 4;
8208
for (row=0; row < height; row++, pix0+=width*4, pix1+=width*4)
8209
FORCC img[row*newdim+col][c] = pix0[c]*(1-frac) + pix1[c]*frac + 0.5;
8217
int CLASS flip_index (int row, int col)
8219
if (flip & 4) SWAP(row,col);
8220
if (flip & 2) row = iheight - 1 - row;
8221
if (flip & 1) col = iwidth - 1 - col;
8222
return row * iwidth + col;
8228
union { char c[4]; short s[2]; int i; } val;
8232
ushort order, magic;
8235
struct tiff_tag tag[23];
8238
struct tiff_tag exif[4];
8240
struct tiff_tag gpst[10];
8244
char desc[512], make[64], model[64], soft[32], date[20], artist[64];
8247
void CLASS tiff_set (ushort *ntag,
8248
ushort tag, ushort type, int count, int val)
8250
struct tiff_tag *tt;
8253
tt = (struct tiff_tag *)(ntag+1) + (*ntag)++;
8257
if (type < 3 && count <= 4)
8258
FORC(4) tt->val.c[c] = val >> (c << 3);
8259
else if (type == 3 && count <= 2)
8260
FORC(2) tt->val.s[c] = val >> (c << 4);
8261
else tt->val.i = val;
8264
#define TOFF(ptr) ((char *)(&(ptr)) - (char *)th)
8266
void CLASS tiff_head (struct tiff_hdr *th, int full)
8271
memset (th, 0, sizeof *th);
8272
th->order = htonl(0x4d4d4949) >> 16;
8276
tiff_set (&th->ntag, 254, 4, 1, 0);
8277
tiff_set (&th->ntag, 256, 4, 1, width);
8278
tiff_set (&th->ntag, 257, 4, 1, height);
8279
tiff_set (&th->ntag, 258, 3, colors, output_bps);
8281
th->tag[th->ntag-1].val.i = TOFF(th->bps);
8282
FORC4 th->bps[c] = output_bps;
8283
tiff_set (&th->ntag, 259, 3, 1, 1);
8284
tiff_set (&th->ntag, 262, 3, 1, 1 + (colors > 1));
8286
tiff_set (&th->ntag, 270, 2, 512, TOFF(th->desc));
8287
tiff_set (&th->ntag, 271, 2, 64, TOFF(th->make));
8288
tiff_set (&th->ntag, 272, 2, 64, TOFF(th->model));
8290
if (oprof) psize = ntohl(oprof[0]);
8291
tiff_set (&th->ntag, 273, 4, 1, sizeof *th + psize);
8292
tiff_set (&th->ntag, 277, 3, 1, colors);
8293
tiff_set (&th->ntag, 278, 4, 1, height);
8294
tiff_set (&th->ntag, 279, 4, 1, height*width*colors*output_bps/8);
8296
tiff_set (&th->ntag, 274, 3, 1, "12435867"[flip]-'0');
8297
tiff_set (&th->ntag, 282, 5, 1, TOFF(th->rat[0]));
8298
tiff_set (&th->ntag, 283, 5, 1, TOFF(th->rat[2]));
8299
tiff_set (&th->ntag, 284, 3, 1, 1);
8300
tiff_set (&th->ntag, 296, 3, 1, 2);
8301
tiff_set (&th->ntag, 305, 2, 32, TOFF(th->soft));
8302
tiff_set (&th->ntag, 306, 2, 20, TOFF(th->date));
8303
tiff_set (&th->ntag, 315, 2, 64, TOFF(th->artist));
8304
tiff_set (&th->ntag, 34665, 4, 1, TOFF(th->nexif));
8305
if (psize) tiff_set (&th->ntag, 34675, 7, psize, sizeof *th);
8306
tiff_set (&th->nexif, 33434, 5, 1, TOFF(th->rat[4]));
8307
tiff_set (&th->nexif, 33437, 5, 1, TOFF(th->rat[6]));
8308
tiff_set (&th->nexif, 34855, 3, 1, iso_speed);
8309
tiff_set (&th->nexif, 37386, 5, 1, TOFF(th->rat[8]));
8311
tiff_set (&th->ntag, 34853, 4, 1, TOFF(th->ngps));
8312
tiff_set (&th->ngps, 0, 1, 4, 0x202);
8313
tiff_set (&th->ngps, 1, 2, 2, gpsdata[29]);
8314
tiff_set (&th->ngps, 2, 5, 3, TOFF(th->gps[0]));
8315
tiff_set (&th->ngps, 3, 2, 2, gpsdata[30]);
8316
tiff_set (&th->ngps, 4, 5, 3, TOFF(th->gps[6]));
8317
tiff_set (&th->ngps, 5, 1, 1, gpsdata[31]);
8318
tiff_set (&th->ngps, 6, 5, 1, TOFF(th->gps[18]));
8319
tiff_set (&th->ngps, 7, 5, 3, TOFF(th->gps[12]));
8320
tiff_set (&th->ngps, 18, 2, 12, TOFF(th->gps[20]));
8321
tiff_set (&th->ngps, 29, 2, 12, TOFF(th->gps[23]));
8322
memcpy (th->gps, gpsdata, sizeof th->gps);
8324
th->rat[0] = th->rat[2] = 300;
8325
th->rat[1] = th->rat[3] = 1;
8326
FORC(6) th->rat[4+c] = 1000000;
8327
th->rat[4] *= shutter;
8328
th->rat[6] *= aperture;
8329
th->rat[8] *= focal_len;
8330
strncpy (th->desc, desc, 512);
8331
strncpy (th->make, make, 64);
8332
strncpy (th->model, model, 64);
8333
strcpy (th->soft, "dcraw v"VERSION);
8334
t = gmtime (×tamp);
8335
sprintf (th->date, "%04d:%02d:%02d %02d:%02d:%02d",
8336
t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);
8337
strncpy (th->artist, artist, 64);
8340
void CLASS jpeg_thumb()
8346
thumb = (char *) malloc (thumb_length);
8347
merror (thumb, "jpeg_thumb()");
8348
fread (thumb, 1, thumb_length, ifp);
8351
if (strcmp (thumb+6, "Exif")) {
8352
memcpy (exif, "\xff\xe1 Exif\0\0", 10);
8353
exif[1] = htons (8 + sizeof th);
8354
fwrite (exif, 1, sizeof exif, ofp);
8356
fwrite (&th, 1, sizeof th, ofp);
8358
fwrite (thumb+2, 1, thumb_length-2, ofp);
8362
void CLASS write_ppm_tiff()
8367
int c, row, col, soff, rstep, cstep;
8368
int perc, val, total, white=0x2000;
8370
perc = width * height * 0.01; /* 99th percentile white level */
8371
if (fuji_width) perc /= 2;
8372
if (!((highlight & ~2) || no_auto_bright))
8373
for (white=c=0; c < colors; c++) {
8374
for (val=0x2000, total=0; --val > 32; )
8375
if ((total += histogram[c][val]) > perc) break;
8376
if (white < val) white = val;
8378
gamma_curve (gamm[0], gamm[1], 2, (white << 3)/bright);
8381
if (flip & 4) SWAP(height,width);
8382
ppm = (uchar *) calloc (width, colors*output_bps/8);
8383
ppm2 = (ushort *) ppm;
8384
merror (ppm, "write_ppm_tiff()");
8387
fwrite (&th, sizeof th, 1, ofp);
8389
fwrite (oprof, ntohl(oprof[0]), 1, ofp);
8390
} else if (colors > 3)
8392
"P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLTYPE %s\nENDHDR\n",
8393
width, height, colors, (1 << output_bps)-1, cdesc);
8395
fprintf (ofp, "P%d\n%d %d\n%d\n",
8396
colors/2+5, width, height, (1 << output_bps)-1);
8397
soff = flip_index (0, 0);
8398
cstep = flip_index (0, 1) - soff;
8399
rstep = flip_index (1, 0) - flip_index (0, width);
8400
for (row=0; row < height; row++, soff += rstep) {
8401
for (col=0; col < width; col++, soff += cstep)
8402
if (output_bps == 8)
8403
FORCC ppm [col*colors+c] = curve[image[soff][c]] >> 8;
8404
else FORCC ppm2[col*colors+c] = curve[image[soff][c]];
8405
if (output_bps == 16 && !output_tiff && htons(0x55aa) != 0x55aa)
8406
swab (ppm2, ppm2, width*colors*2);
8407
fwrite (ppm, colors*output_bps/8, width, ofp);
8412
int CLASS main (int argc, const char **argv)
8415
int timestamp_only=0, thumbnail_only=0, identify_only=0;
8416
int user_qual=-1, user_black=-1, user_sat=-1, user_flip=-1;
8417
int use_fuji_rotate=1, write_to_stdout=0, quality, i, c;
8418
const char *sp, *bpfile=0, *dark_frame=0, *write_ext;
8419
char opm, opt, *ofname, *cp;
8422
const char *cam_profile=0, *out_profile=0;
8426
putenv ((char *) "TZ=UTC");
8429
setlocale (LC_CTYPE, "");
8430
setlocale (LC_MESSAGES, "");
8431
bindtextdomain ("dcraw", LOCALEDIR);
8432
textdomain ("dcraw");
8436
printf(_("\nRaw photo decoder \"dcraw\" v%s"), VERSION);
8437
printf(_("\nby Dave Coffin, dcoffin a cybercom o net\n"));
8438
printf(_("\nUsage: %s [OPTION]... [FILE]...\n\n"), argv[0]);
8439
puts(_("-v Print verbose messages"));
8440
puts(_("-c Write image data to standard output"));
8441
puts(_("-e Extract embedded thumbnail image"));
8442
puts(_("-i Identify files without decoding them"));
8443
puts(_("-i -v Identify files and show metadata"));
8444
puts(_("-z Change file dates to camera timestamp"));
8445
puts(_("-w Use camera white balance, if possible"));
8446
puts(_("-a Average the whole image for white balance"));
8447
puts(_("-A <x y w h> Average a grey box for white balance"));
8448
puts(_("-r <r g b g> Set custom white balance"));
8449
puts(_("+M/-M Use/don't use an embedded color matrix"));
8450
puts(_("-C <r b> Correct chromatic aberration"));
8451
puts(_("-P <file> Fix the dead pixels listed in this file"));
8452
puts(_("-K <file> Subtract dark frame (16-bit raw PGM)"));
8453
puts(_("-k <num> Set the darkness level"));
8454
puts(_("-S <num> Set the saturation level"));
8455
puts(_("-n <num> Set threshold for wavelet denoising"));
8456
puts(_("-H [0-9] Highlight mode (0=clip, 1=unclip, 2=blend, 3+=rebuild)"));
8457
puts(_("-t [0-7] Flip image (0=none, 3=180, 5=90CCW, 6=90CW)"));
8458
puts(_("-o [0-5] Output colorspace (raw,sRGB,Adobe,Wide,ProPhoto,XYZ)"));
8460
puts(_("-o <file> Apply output ICC profile from file"));
8461
puts(_("-p <file> Apply camera ICC profile from file or \"embed\""));
8463
puts(_("-d Document mode (no color, no interpolation)"));
8464
puts(_("-D Document mode without scaling (totally raw)"));
8465
puts(_("-j Don't stretch or rotate raw pixels"));
8466
puts(_("-W Don't automatically brighten the image"));
8467
puts(_("-b <num> Adjust brightness (default = 1.0)"));
8468
puts(_("-g <p ts> Set custom gamma curve (default = 2.222 4.5)"));
8469
puts(_("-q [0-3] Set the interpolation quality"));
8470
puts(_("-h Half-size color image (twice as fast as \"-q 0\")"));
8471
puts(_("-f Interpolate RGGB as four colors"));
8472
puts(_("-m <num> Apply a 3x3 median filter to R-G and B-G"));
8473
puts(_("-s [0..N-1] Select one raw image or \"all\" from each file"));
8474
puts(_("-6 Write 16-bit instead of 8-bit"));
8475
puts(_("-4 Linear 16-bit, same as \"-6 -W -g 1 1\""));
8476
puts(_("-T Write TIFF instead of PPM"));
8481
for (arg=1; (((opm = argv[arg][0]) - 2) | 2) == '+'; ) {
8482
opt = argv[arg++][1];
8483
if ((cp = (char *) strchr (sp="nbrkStqmHACg", opt)))
8484
for (i=0; i < "114111111422"[cp-sp]-'0'; i++)
8485
if (!isdigit(argv[arg+i][0])) {
8486
fprintf (stderr,_("Non-numeric argument to \"-%c\"\n"), opt);
8490
case 'n': threshold = atof(argv[arg++]); break;
8491
case 'b': bright = atof(argv[arg++]); break;
8493
FORC4 user_mul[c] = atof(argv[arg++]); break;
8494
case 'C': aber[0] = 1 / atof(argv[arg++]);
8495
aber[2] = 1 / atof(argv[arg++]); break;
8496
case 'g': gamm[0] = atof(argv[arg++]);
8497
gamm[1] = atof(argv[arg++]);
8498
if (gamm[0]) gamm[0] = 1/gamm[0]; break;
8499
case 'k': user_black = atoi(argv[arg++]); break;
8500
case 'S': user_sat = atoi(argv[arg++]); break;
8501
case 't': user_flip = atoi(argv[arg++]); break;
8502
case 'q': user_qual = atoi(argv[arg++]); break;
8503
case 'm': med_passes = atoi(argv[arg++]); break;
8504
case 'H': highlight = atoi(argv[arg++]); break;
8506
shot_select = abs(atoi(argv[arg]));
8507
multi_out = !strcmp(argv[arg++],"all");
8510
if (isdigit(argv[arg][0]) && !argv[arg][1])
8511
output_color = atoi(argv[arg++]);
8513
else out_profile = argv[arg++];
8515
case 'p': cam_profile = argv[arg++];
8518
case 'P': bpfile = argv[arg++]; break;
8519
case 'K': dark_frame = argv[arg++]; break;
8520
case 'z': timestamp_only = 1; break;
8521
case 'e': thumbnail_only = 1; break;
8522
case 'i': identify_only = 1; break;
8523
case 'c': write_to_stdout = 1; break;
8524
case 'v': verbose = 1; break;
8525
case 'h': half_size = 1; /* "-h" implies "-f" */
8526
case 'f': four_color_rgb = 1; break;
8527
case 'A': FORC4 greybox[c] = atoi(argv[arg++]);
8528
case 'a': use_auto_wb = 1; break;
8529
case 'w': use_camera_wb = 1; break;
8530
case 'M': use_camera_matrix = (opm == '+'); break;
8532
case 'd': document_mode = 1 + (opt == 'D');
8533
case 'j': use_fuji_rotate = 0; break;
8534
case 'W': no_auto_bright = 1; break;
8535
case 'T': output_tiff = 1; break;
8536
case '4': gamm[0] = gamm[1] =
8538
case '6': output_bps = 16; break;
8540
fprintf (stderr,_("Unknown option \"-%c\".\n"), opt);
8544
if (use_camera_matrix < 0)
8545
use_camera_matrix = use_camera_wb;
8547
fprintf (stderr,_("No files to process.\n"));
8550
if (write_to_stdout) {
8552
fprintf (stderr,_("Will not write an image to the terminal!\n"));
8555
#if defined(WIN32) || defined(DJGPP) || defined(__CYGWIN__)
8556
if (setmode(1,O_BINARY) < 0) {
8557
perror ("setmode()");
8562
for ( ; arg < argc; arg++) {
8566
meta_data = ofname = 0;
8568
if (setjmp (failure)) {
8569
if (fileno(ifp) > 2) fclose(ifp);
8570
if (fileno(ofp) > 2) fclose(ofp);
8575
if (!(ifp = fopen (ifname, "rb"))) {
8579
status = (identify(),!is_raw);
8582
switch ((flip+3600) % 360) {
8583
case 270: flip = 5; break;
8584
case 180: flip = 3; break;
8587
if (timestamp_only) {
8588
if ((status = !timestamp))
8589
fprintf (stderr,_("%s has no timestamp.\n"), ifname);
8590
else if (identify_only)
8591
printf ("%10ld%10d %s\n", (long) timestamp, shot_order, ifname);
8594
fprintf (stderr,_("%s time set to %d.\n"), ifname, (int) timestamp);
8595
ut.actime = ut.modtime = timestamp;
8596
utime (ifname, &ut);
8600
write_fun = &CLASS write_ppm_tiff;
8601
if (thumbnail_only) {
8602
if ((status = !thumb_offset)) {
8603
fprintf (stderr,_("%s has no thumbnail.\n"), ifname);
8605
} else if (thumb_load_raw) {
8606
load_raw = thumb_load_raw;
8607
data_offset = thumb_offset;
8608
height = thumb_height;
8609
width = thumb_width;
8612
fseek (ifp, thumb_offset, SEEK_SET);
8613
write_fun = write_thumb;
8617
if (load_raw == &CLASS kodak_ycbcr_load_raw) {
8618
height += height & 1;
8621
if (identify_only && verbose && make[0]) {
8622
printf (_("\nFilename: %s\n"), ifname);
8623
printf (_("Timestamp: %s"), ctime(×tamp));
8624
printf (_("Camera: %s %s\n"), make, model);
8626
printf (_("Owner: %s\n"), artist);
8628
printf (_("DNG Version: "));
8629
for (i=24; i >= 0; i -= 8)
8630
printf ("%d%c", dng_version >> i & 255, i ? '.':'\n');
8632
printf (_("ISO speed: %d\n"), (int) iso_speed);
8633
printf (_("Shutter: "));
8634
if (shutter > 0 && shutter < 1)
8635
shutter = (printf ("1/"), 1 / shutter);
8636
printf (_("%0.1f sec\n"), shutter);
8637
printf (_("Aperture: f/%0.1f\n"), aperture);
8638
printf (_("Focal length: %0.1f mm\n"), focal_len);
8639
printf (_("Embedded ICC profile: %s\n"), profile_length ? _("yes"):_("no"));
8640
printf (_("Number of raw images: %d\n"), is_raw);
8641
if (pixel_aspect != 1)
8642
printf (_("Pixel Aspect Ratio: %0.6f\n"), pixel_aspect);
8644
printf (_("Thumb size: %4d x %d\n"), thumb_width, thumb_height);
8645
printf (_("Full size: %4d x %d\n"), raw_width, raw_height);
8647
fprintf (stderr,_("Cannot decode file %s\n"), ifname);
8648
if (!is_raw) goto next;
8650
(half_size || threshold || aber[0] != 1 || aber[2] != 1);
8651
iheight = (height + shrink) >> shrink;
8652
iwidth = (width + shrink) >> shrink;
8653
if (identify_only) {
8655
if (use_fuji_rotate) {
8657
fuji_width = (fuji_width - 1 + shrink) >> shrink;
8658
iwidth = fuji_width / sqrt(0.5);
8659
iheight = (iheight - fuji_width) / sqrt(0.5);
8661
if (pixel_aspect < 1) iheight = iheight / pixel_aspect + 0.5;
8662
if (pixel_aspect > 1) iwidth = iwidth * pixel_aspect + 0.5;
8666
SWAP(iheight,iwidth);
8667
printf (_("Image size: %4d x %d\n"), width, height);
8668
printf (_("Output size: %4d x %d\n"), iwidth, iheight);
8669
printf (_("Raw colors: %d"), colors);
8671
printf (_("\nFilter pattern: "));
8672
if (!cdesc[3]) cdesc[3] = 'G';
8673
for (i=0; i < 16; i++)
8674
putchar (cdesc[fc(i >> 1,i & 1)]);
8676
printf (_("\nDaylight multipliers:"));
8677
FORCC printf (" %f", pre_mul[c]);
8678
if (cam_mul[0] > 0) {
8679
printf (_("\nCamera multipliers:"));
8680
FORC4 printf (" %f", cam_mul[c]);
8684
printf (_("%s is a %s %s image.\n"), ifname, make, model);
8689
if (use_camera_matrix && cmatrix[0][0] > 0.25) {
8690
memcpy (rgb_cam, cmatrix, sizeof cmatrix);
8693
image = (ushort (*)[4]) calloc (iheight*iwidth, sizeof *image);
8694
merror (image, "main()");
8696
meta_data = (char *) malloc (meta_length);
8697
merror (meta_data, "main()");
8700
fprintf (stderr,_("Loading %s %s image from %s ...\n"),
8701
make, model, ifname);
8702
if (shot_select >= is_raw)
8703
fprintf (stderr,_("%s: \"-s %d\" requests a nonexistent image!\n"),
8704
ifname, shot_select);
8705
fseeko (ifp, data_offset, SEEK_SET);
8707
if (zero_is_bad) remove_zeroes();
8708
bad_pixels (bpfile);
8709
if (dark_frame) subtract (dark_frame);
8710
quality = 2 + !fuji_width;
8711
if (user_qual >= 0) quality = user_qual;
8712
if (user_black >= 0) black = user_black;
8713
if (user_sat > 0) maximum = user_sat;
8717
if (is_foveon && !document_mode) foveon_interpolate();
8718
if (!is_foveon && document_mode < 2) scale_colors();
8720
if (filters && !document_mode) {
8723
else if (quality == 1 || colors > 3)
8725
else if (quality == 2)
8727
else ahd_interpolate();
8730
for (colors=3, i=0; i < height*width; i++)
8731
image[i][1] = (image[i][1] + image[i][3]) >> 1;
8732
if (!is_foveon && colors == 3) median_filter();
8733
if (!is_foveon && highlight == 2) blend_highlights();
8734
if (!is_foveon && highlight > 2) recover_highlights();
8735
if (use_fuji_rotate) fuji_rotate();
8737
if (cam_profile) apply_profile (cam_profile, out_profile);
8740
if (use_fuji_rotate) stretch();
8742
if (write_fun == &CLASS jpeg_thumb)
8744
else if (output_tiff && write_fun == &CLASS write_ppm_tiff)
8745
write_ext = ".tiff";
8747
write_ext = ".pgm\0.ppm\0.ppm\0.pam" + colors*5-5;
8748
ofname = (char *) malloc (strlen(ifname) + 64);
8749
merror (ofname, "main()");
8750
if (write_to_stdout)
8751
strcpy (ofname,_("standard output"));
8753
strcpy (ofname, ifname);
8754
if ((cp = strrchr (ofname, '.'))) *cp = 0;
8756
sprintf (ofname+strlen(ofname), "_%0*d",
8757
snprintf(0,0,"%d",is_raw-1), shot_select);
8759
strcat (ofname, ".thumb");
8760
strcat (ofname, write_ext);
8761
ofp = fopen (ofname, "wb");
8769
fprintf (stderr,_("Writing data to %s ...\n"), ofname);
8772
if (ofp != stdout) fclose(ofp);
8774
if (meta_data) free (meta_data);
8775
if (ofname) free (ofname);
8776
if (oprof) free (oprof);
8777
if (image) free (image);
8779
if (++shot_select < is_raw) arg--;
8780
else shot_select = 0;