r807: Minor fix...
[cinelerra_cv/mob.git] / cinelerra / dcraw.c
blob028f852ff57938925982158837984637aee40e40
1 /*
2 dcraw.c -- Dave Coffin's raw photo decoder
3 Copyright 1997-2004 by Dave Coffin, dcoffin a cybercom o net
5 This is a portable ANSI C program to convert raw image files from
6 any digital camera into PPM format. TIFF and CIFF parsing are
7 based upon public specifications, but no such documentation is
8 available for the raw sensor data, so writing this program has
9 been an immense effort.
11 This code is freely licensed for all uses, commercial and
12 otherwise. Comments, questions, and encouragement are welcome.
14 $Revision: 1.251 $
15 $Date: 2004/10/29 01:52:38 $
18 #define _GNU_SOURCE
19 #include <ctype.h>
20 #include <errno.h>
21 #include <fcntl.h>
22 #include <float.h>
23 #include <limits.h>
24 #include <math.h>
25 #include <setjmp.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <time.h>
31 By defining NO_JPEG, you lose only the ability to
32 decode compressed .KDC files from the Kodak DC120.
34 #ifndef NO_JPEG
35 #include <jpeglib.h>
36 #endif
38 #ifdef WIN32
39 #include <winsock2.h>
40 #pragma comment(lib, "ws2_32.lib")
41 #define strcasecmp stricmp
42 typedef __int64 INT64;
43 #else
44 #include <unistd.h>
45 #include <netinet/in.h>
46 typedef long long INT64;
47 #endif
49 #ifdef LJPEG_DECODE
50 #error Please compile dcraw.c by itself.
51 #error Do not link it with ljpeg_decode.
52 #endif
54 #ifndef LONG_BIT
55 #define LONG_BIT (8 * sizeof (long))
56 #endif
58 #define ushort UshORt
59 typedef unsigned char uchar;
60 typedef unsigned short ushort;
62 #define ABS_MAX ((ushort) -1)
63 #define RGB_MAX ((ushort) -1)
66 All global variables are defined here, and all functions that
67 access them are prefixed with "CLASS". Note that a thread-safe
68 C++ class cannot have non-const static local variables.
73 // Cinelerra
74 char dcraw_info[1024];
75 float **dcraw_data;
76 int dcraw_alpha;
79 FILE *ifp;
80 short order;
81 char *ifname, make[64], model[64], model2[64];
82 time_t timestamp;
83 int data_offset, curve_offset, curve_length;
84 int tiff_data_compression, kodak_data_compression;
85 int raw_height, raw_width, top_margin, left_margin;
86 int height, width, colors, black, rgb_max;
87 int iheight, iwidth, shrink;
88 int is_canon, is_cmy, is_foveon, use_coeff, trim, flip, xmag, ymag;
89 int zero_after_ff;
90 unsigned filters;
91 ushort (*image)[4], white[8][8];
92 void (*load_raw)();
93 float gamma_val=0.6, bright=1.0, red_scale=1.0, blue_scale=1.0;
94 int four_color_rgb=0, document_mode=0, quick_interpolate=0;
95 int verbose=0, use_auto_wb=0, use_camera_wb=0, use_secondary=0;
96 float camera_red, camera_blue;
97 float pre_mul[4], coeff[3][4];
98 float k1=1.5, k2=0.5, juice=0.0;
99 int histogram[0x2000];
100 void write_ppm(FILE *);
103 void (*write_fun)(FILE *) = write_ppm;
106 jmp_buf failure;
108 float green_scale=1.0;
109 float saturation = 1.0;
110 float contrast = 1.0;
111 int autoexposure=0, use_pivot=0, use_neutral_wb=0;
112 int alternate_scale = 0;
113 int center_weight = 0;
114 int use_camera_black = 1;
115 int user_black = -1;
116 float pivot_value = 0.75, exposure_compensation=0.0;
117 unsigned pivot_point[4], pivot_base[4];
118 float white_point_fraction = 0.99;
120 struct decode {
121 struct decode *branch[2];
122 int leaf;
123 } first_decode[2048], *second_decode, *free_decode;
125 #define CLASS
128 In order to inline this calculation, I make the risky
129 assumption that all filter patterns can be described
130 by a repeating pattern of eight rows and two columns
132 Return values are either 0/1/2/3 = G/M/C/Y or 0/1/2/3 = R/G1/B/G2
134 #define FC(row,col) \
135 (filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)
137 #define BAYER(row,col) \
138 image[((row) >> shrink)*iwidth + ((col) >> shrink)][FC(row,col)]
141 PowerShot 600 uses 0xe1e4e1e4:
143 0 1 2 3 4 5
144 0 G M G M G M
145 1 C Y C Y C Y
146 2 M G M G M G
147 3 C Y C Y C Y
149 PowerShot A5 uses 0x1e4e1e4e:
151 0 1 2 3 4 5
152 0 C Y C Y C Y
153 1 G M G M G M
154 2 C Y C Y C Y
155 3 M G M G M G
157 PowerShot A50 uses 0x1b4e4b1e:
159 0 1 2 3 4 5
160 0 C Y C Y C Y
161 1 M G M G M G
162 2 Y C Y C Y C
163 3 G M G M G M
164 4 C Y C Y C Y
165 5 G M G M G M
166 6 Y C Y C Y C
167 7 M G M G M G
169 PowerShot Pro70 uses 0x1e4b4e1b:
171 0 1 2 3 4 5
172 0 Y C Y C Y C
173 1 M G M G M G
174 2 C Y C Y C Y
175 3 G M G M G M
176 4 Y C Y C Y C
177 5 G M G M G M
178 6 C Y C Y C Y
179 7 M G M G M G
181 PowerShots Pro90 and G1 use 0xb4b4b4b4:
183 0 1 2 3 4 5
184 0 G M G M G M
185 1 Y C Y C Y C
187 All RGB cameras use one of these Bayer grids:
189 0x16161616: 0x61616161: 0x49494949: 0x94949494:
191 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5
192 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
193 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
194 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
195 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
199 #ifndef __GLIBC__
200 char *memmem (char *haystack, size_t haystacklen,
201 char *needle, size_t needlelen)
203 char *c;
204 for (c = haystack; c <= haystack + haystacklen - needlelen; c++)
205 if (!memcmp (c, needle, needlelen))
206 return c;
207 return NULL;
209 #endif
211 void CLASS merror (void *ptr, char *where)
213 if (ptr) return;
214 fprintf (stderr, "%s: Out of memory in %s\n", ifname, where);
215 longjmp (failure, 1);
219 Get a 2-byte integer, making no assumptions about CPU byte order.
220 Nor should we assume that the compiler evaluates left-to-right.
222 ushort CLASS fget2 (FILE *f)
224 uchar a, b;
226 a = fgetc(f);
227 b = fgetc(f);
228 if (order == 0x4949) /* "II" means little-endian */
229 return a + (b << 8);
230 else /* "MM" means big-endian */
231 return (a << 8) + b;
235 Same for a 4-byte integer.
237 int CLASS fget4 (FILE *f)
239 uchar a, b, c, d;
241 a = fgetc(f);
242 b = fgetc(f);
243 c = fgetc(f);
244 d = fgetc(f);
245 if (order == 0x4949)
246 return a + (b << 8) + (c << 16) + (d << 24);
247 else
248 return (a << 24) + (b << 16) + (c << 8) + d;
251 void CLASS canon_600_load_raw()
253 uchar data[1120], *dp;
254 ushort pixel[896], *pix;
255 int irow, orow, col;
257 for (irow=orow=0; irow < height; irow++)
259 fread (data, 1120, 1, ifp);
260 for (dp=data, pix=pixel; dp < data+1120; dp+=10, pix+=8)
262 pix[0] = (dp[0] << 2) + (dp[1] >> 6 );
263 pix[1] = (dp[2] << 2) + (dp[1] >> 4 & 3);
264 pix[2] = (dp[3] << 2) + (dp[1] >> 2 & 3);
265 pix[3] = (dp[4] << 2) + (dp[1] & 3);
266 pix[4] = (dp[5] << 2) + (dp[9] & 3);
267 pix[5] = (dp[6] << 2) + (dp[9] >> 2 & 3);
268 pix[6] = (dp[7] << 2) + (dp[9] >> 4 & 3);
269 pix[7] = (dp[8] << 2) + (dp[9] >> 6 );
271 for (col=0; col < width; col++)
272 BAYER(orow,col) = pixel[col] << 4;
273 for (col=width; col < 896; col++)
274 black += pixel[col];
275 if ((orow+=2) > height)
276 orow = 1;
278 black = ((INT64) black << 4) / ((896 - width) * height);
281 void CLASS canon_a5_load_raw()
283 uchar data[1940], *dp;
284 ushort pixel[1552], *pix;
285 int row, col;
287 for (row=0; row < height; row++) {
288 fread (data, raw_width * 10 / 8, 1, ifp);
289 for (dp=data, pix=pixel; pix < pixel+raw_width; dp+=10, pix+=8)
291 pix[0] = (dp[1] << 2) + (dp[0] >> 6);
292 pix[1] = (dp[0] << 4) + (dp[3] >> 4);
293 pix[2] = (dp[3] << 6) + (dp[2] >> 2);
294 pix[3] = (dp[2] << 8) + (dp[5] );
295 pix[4] = (dp[4] << 2) + (dp[7] >> 6);
296 pix[5] = (dp[7] << 4) + (dp[6] >> 4);
297 pix[6] = (dp[6] << 6) + (dp[9] >> 2);
298 pix[7] = (dp[9] << 8) + (dp[8] );
300 for (col=0; col < width; col++)
301 BAYER(row,col) = (pixel[col] & 0x3ff) << 4;
302 for (col=width; col < raw_width; col++)
303 black += pixel[col] & 0x3ff;
305 if (raw_width > width)
306 black = ((INT64) black << 4) / ((raw_width - width) * height);
310 getbits(-1) initializes the buffer
311 getbits(n) where 0 <= n <= 25 returns an n-bit integer
313 unsigned CLASS getbits (int nbits)
315 static unsigned long bitbuf=0;
316 static int vbits=0;
317 unsigned c, ret;
319 if (nbits == 0) return 0;
320 if (nbits == -1)
321 ret = bitbuf = vbits = 0;
322 else {
323 ret = bitbuf << (LONG_BIT - vbits) >> (LONG_BIT - nbits);
324 vbits -= nbits;
326 while (vbits < LONG_BIT - 7) {
327 c = fgetc(ifp);
328 bitbuf = (bitbuf << 8) + c;
329 if (c == 0xff && zero_after_ff)
330 fgetc(ifp);
331 vbits += 8;
333 return ret;
336 void CLASS init_decoder ()
338 memset (first_decode, 0, sizeof first_decode);
339 free_decode = first_decode;
343 Construct a decode tree according the specification in *source.
344 The first 16 bytes specify how many codes should be 1-bit, 2-bit
345 3-bit, etc. Bytes after that are the leaf values.
347 For example, if the source is
349 { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0,
350 0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff },
352 then the code is
354 00 0x04
355 010 0x03
356 011 0x05
357 100 0x06
358 101 0x02
359 1100 0x07
360 1101 0x01
361 11100 0x08
362 11101 0x09
363 11110 0x00
364 111110 0x0a
365 1111110 0x0b
366 1111111 0xff
368 uchar * CLASS make_decoder (const uchar *source, int level)
370 struct decode *cur;
371 static int leaf;
372 int i, next;
374 if (level==0) leaf=0;
375 cur = free_decode++;
376 if (free_decode > first_decode+2048) {
377 fprintf (stderr, "%s: decoder table overflow\n", ifname);
378 longjmp (failure, 2);
380 for (i=next=0; i <= leaf && next < 16; )
381 i += source[next++];
382 if (i > leaf) {
383 if (level < next) {
384 cur->branch[0] = free_decode;
385 make_decoder (source, level+1);
386 cur->branch[1] = free_decode;
387 make_decoder (source, level+1);
388 } else
389 cur->leaf = source[16 + leaf++];
391 return (uchar *) source + 16 + leaf;
394 void CLASS crw_init_tables (unsigned table)
396 static const uchar first_tree[3][29] = {
397 { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0,
398 0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff },
400 { 0,2,2,3,1,1,1,1,2,0,0,0,0,0,0,0,
401 0x03,0x02,0x04,0x01,0x05,0x00,0x06,0x07,0x09,0x08,0x0a,0x0b,0xff },
403 { 0,0,6,3,1,1,2,0,0,0,0,0,0,0,0,0,
404 0x06,0x05,0x07,0x04,0x08,0x03,0x09,0x02,0x00,0x0a,0x01,0x0b,0xff },
407 static const uchar second_tree[3][180] = {
408 { 0,2,2,2,1,4,2,1,2,5,1,1,0,0,0,139,
409 0x03,0x04,0x02,0x05,0x01,0x06,0x07,0x08,
410 0x12,0x13,0x11,0x14,0x09,0x15,0x22,0x00,0x21,0x16,0x0a,0xf0,
411 0x23,0x17,0x24,0x31,0x32,0x18,0x19,0x33,0x25,0x41,0x34,0x42,
412 0x35,0x51,0x36,0x37,0x38,0x29,0x79,0x26,0x1a,0x39,0x56,0x57,
413 0x28,0x27,0x52,0x55,0x58,0x43,0x76,0x59,0x77,0x54,0x61,0xf9,
414 0x71,0x78,0x75,0x96,0x97,0x49,0xb7,0x53,0xd7,0x74,0xb6,0x98,
415 0x47,0x48,0x95,0x69,0x99,0x91,0xfa,0xb8,0x68,0xb5,0xb9,0xd6,
416 0xf7,0xd8,0x67,0x46,0x45,0x94,0x89,0xf8,0x81,0xd5,0xf6,0xb4,
417 0x88,0xb1,0x2a,0x44,0x72,0xd9,0x87,0x66,0xd4,0xf5,0x3a,0xa7,
418 0x73,0xa9,0xa8,0x86,0x62,0xc7,0x65,0xc8,0xc9,0xa1,0xf4,0xd1,
419 0xe9,0x5a,0x92,0x85,0xa6,0xe7,0x93,0xe8,0xc1,0xc6,0x7a,0x64,
420 0xe1,0x4a,0x6a,0xe6,0xb3,0xf1,0xd3,0xa5,0x8a,0xb2,0x9a,0xba,
421 0x84,0xa4,0x63,0xe5,0xc5,0xf3,0xd2,0xc4,0x82,0xaa,0xda,0xe4,
422 0xf2,0xca,0x83,0xa3,0xa2,0xc3,0xea,0xc2,0xe2,0xe3,0xff,0xff },
424 { 0,2,2,1,4,1,4,1,3,3,1,0,0,0,0,140,
425 0x02,0x03,0x01,0x04,0x05,0x12,0x11,0x06,
426 0x13,0x07,0x08,0x14,0x22,0x09,0x21,0x00,0x23,0x15,0x31,0x32,
427 0x0a,0x16,0xf0,0x24,0x33,0x41,0x42,0x19,0x17,0x25,0x18,0x51,
428 0x34,0x43,0x52,0x29,0x35,0x61,0x39,0x71,0x62,0x36,0x53,0x26,
429 0x38,0x1a,0x37,0x81,0x27,0x91,0x79,0x55,0x45,0x28,0x72,0x59,
430 0xa1,0xb1,0x44,0x69,0x54,0x58,0xd1,0xfa,0x57,0xe1,0xf1,0xb9,
431 0x49,0x47,0x63,0x6a,0xf9,0x56,0x46,0xa8,0x2a,0x4a,0x78,0x99,
432 0x3a,0x75,0x74,0x86,0x65,0xc1,0x76,0xb6,0x96,0xd6,0x89,0x85,
433 0xc9,0xf5,0x95,0xb4,0xc7,0xf7,0x8a,0x97,0xb8,0x73,0xb7,0xd8,
434 0xd9,0x87,0xa7,0x7a,0x48,0x82,0x84,0xea,0xf4,0xa6,0xc5,0x5a,
435 0x94,0xa4,0xc6,0x92,0xc3,0x68,0xb5,0xc8,0xe4,0xe5,0xe6,0xe9,
436 0xa2,0xa3,0xe3,0xc2,0x66,0x67,0x93,0xaa,0xd4,0xd5,0xe7,0xf8,
437 0x88,0x9a,0xd7,0x77,0xc4,0x64,0xe2,0x98,0xa5,0xca,0xda,0xe8,
438 0xf3,0xf6,0xa9,0xb2,0xb3,0xf2,0xd2,0x83,0xba,0xd3,0xff,0xff },
440 { 0,0,6,2,1,3,3,2,5,1,2,2,8,10,0,117,
441 0x04,0x05,0x03,0x06,0x02,0x07,0x01,0x08,
442 0x09,0x12,0x13,0x14,0x11,0x15,0x0a,0x16,0x17,0xf0,0x00,0x22,
443 0x21,0x18,0x23,0x19,0x24,0x32,0x31,0x25,0x33,0x38,0x37,0x34,
444 0x35,0x36,0x39,0x79,0x57,0x58,0x59,0x28,0x56,0x78,0x27,0x41,
445 0x29,0x77,0x26,0x42,0x76,0x99,0x1a,0x55,0x98,0x97,0xf9,0x48,
446 0x54,0x96,0x89,0x47,0xb7,0x49,0xfa,0x75,0x68,0xb6,0x67,0x69,
447 0xb9,0xb8,0xd8,0x52,0xd7,0x88,0xb5,0x74,0x51,0x46,0xd9,0xf8,
448 0x3a,0xd6,0x87,0x45,0x7a,0x95,0xd5,0xf6,0x86,0xb4,0xa9,0x94,
449 0x53,0x2a,0xa8,0x43,0xf5,0xf7,0xd4,0x66,0xa7,0x5a,0x44,0x8a,
450 0xc9,0xe8,0xc8,0xe7,0x9a,0x6a,0x73,0x4a,0x61,0xc7,0xf4,0xc6,
451 0x65,0xe9,0x72,0xe6,0x71,0x91,0x93,0xa6,0xda,0x92,0x85,0x62,
452 0xf3,0xc5,0xb2,0xa4,0x84,0xba,0x64,0xa5,0xb3,0xd2,0x81,0xe5,
453 0xd3,0xaa,0xc4,0xca,0xf2,0xb1,0xe4,0xd1,0x83,0x63,0xea,0xc3,
454 0xe2,0x82,0xf1,0xa3,0xc2,0xa1,0xc1,0xe3,0xa2,0xe1,0xff,0xff }
457 if (table > 2) table = 2;
458 init_decoder();
459 make_decoder ( first_tree[table], 0);
460 second_decode = free_decode;
461 make_decoder (second_tree[table], 0);
465 Return 0 if the image starts with compressed data,
466 1 if it starts with uncompressed low-order bits.
468 In Canon compressed data, 0xff is always followed by 0x00.
470 int CLASS canon_has_lowbits()
472 uchar test[0x4000];
473 int ret=1, i;
475 fseek (ifp, 0, SEEK_SET);
476 fread (test, 1, sizeof test, ifp);
477 for (i=540; i < sizeof test - 1; i++)
478 if (test[i] == 0xff) {
479 if (test[i+1]) return 1;
480 ret=0;
482 return ret;
485 void CLASS canon_compressed_load_raw()
487 ushort *pixel, *prow;
488 int lowbits, shift, i, row, r, col, save, val;
489 unsigned irow, icol;
490 struct decode *decode, *dindex;
491 int block, diffbuf[64], leaf, len, diff, carry=0, pnum=0, base[2];
492 uchar c;
493 INT64 bblack=0;
495 pixel = calloc (raw_width*8, sizeof *pixel);
496 merror (pixel, "canon_compressed_load_raw()");
497 lowbits = canon_has_lowbits();
498 shift = 4 - lowbits*2;
499 fseek (ifp, 540 + lowbits*raw_height*raw_width/4, SEEK_SET);
500 zero_after_ff = 1;
501 getbits(-1);
503 for (row = 0; row < raw_height; row += 8) {
504 for (block=0; block < raw_width >> 3; block++) {
505 memset (diffbuf, 0, sizeof diffbuf);
506 decode = first_decode;
507 for (i=0; i < 64; i++ ) {
508 for (dindex=decode; dindex->branch[0]; )
509 dindex = dindex->branch[getbits(1)];
510 leaf = dindex->leaf;
511 decode = second_decode;
512 if (leaf == 0 && i) break;
513 if (leaf == 0xff) continue;
514 i += leaf >> 4;
515 len = leaf & 15;
516 if (len == 0) continue;
517 diff = getbits(len);
518 if ((diff & (1 << (len-1))) == 0)
519 diff -= (1 << len) - 1;
520 if (i < 64) diffbuf[i] = diff;
522 diffbuf[0] += carry;
523 carry = diffbuf[0];
524 for (i=0; i < 64; i++ ) {
525 if (pnum++ % raw_width == 0)
526 base[0] = base[1] = 512;
527 pixel[(block << 6) + i] = ( base[i & 1] += diffbuf[i] );
530 if (lowbits) {
531 save = ftell(ifp); /* Don't lose our place */
532 fseek (ifp, 26 + row*raw_width/4, SEEK_SET);
533 for (prow=pixel, i=0; i < raw_width*2; i++) {
534 c = fgetc(ifp);
535 for (r=0; r < 8; r+=2, prow++) {
536 val = (*prow << 2) + ((c >> r) & 3);
537 if (raw_width == 2672 && val < 512) val += 2;
538 *prow = val;
541 fseek (ifp, save, SEEK_SET);
543 for (r=0; r < 8; r++) {
544 irow = row - top_margin + r;
545 if (irow >= height) continue;
546 for (col = 0; col < raw_width; col++) {
547 icol = col - left_margin;
548 if (icol < width)
549 BAYER(irow,icol) = pixel[r*raw_width+col] << shift;
550 else
551 bblack += pixel[r*raw_width+col];
555 free(pixel);
556 if (raw_width > width)
557 black = (bblack << shift) / ((raw_width - width) * height);
560 void CLASS kodak_curve (ushort *curve)
562 int i, entries, tag, type, len, val;
564 for (i=0; i < 0x1000; i++)
565 curve[i] = i;
566 if (strcasecmp(make,"KODAK")) return;
567 if (!curve_offset) {
568 fseek (ifp, 12, SEEK_SET);
569 entries = fget2(ifp);
570 while (entries--) {
571 tag = fget2(ifp);
572 type = fget2(ifp);
573 len = fget4(ifp);
574 val = fget4(ifp);
575 if (tag == 0x90d) {
576 curve_offset = val;
577 curve_length = len;
581 if (curve_offset) {
582 fseek (ifp, curve_offset, SEEK_SET);
583 for (i=0; i < curve_length; i++)
584 curve[i] = fget2(ifp);
585 for ( ; i < 0x1000; i++)
586 curve[i] = curve[i-1];
587 rgb_max = curve[i-1] << 2;
589 fseek (ifp, data_offset, SEEK_SET);
593 Not a full implementation of Lossless JPEG,
594 just enough to decode Canon and Kodak images.
596 void CLASS lossless_jpeg_load_raw()
598 int tag, len, jhigh=0, jwide=0, jrow, jcol, jidx, diff, i, row, col;
599 uchar data[256], *dp;
600 int vpred[2] = { 0x800, 0x800 }, hpred[2];
601 struct decode *dstart[2], *dindex;
602 ushort curve[0x10000];
603 INT64 bblack=0;
604 int min=INT_MAX;
606 kodak_curve(curve);
607 order = 0x4d4d;
608 if (fget2(ifp) != 0xffd8) return;
610 do {
611 tag = fget2(ifp);
612 len = fget2(ifp) - 2;
613 if (tag <= 0xff00 || len > 255) return;
614 fread (data, 1, len, ifp);
615 switch (tag) {
616 case 0xffc3:
617 jhigh = (data[1] << 8) + data[2];
618 jwide =((data[3] << 8) + data[4])*2;
619 break;
620 case 0xffc4:
621 init_decoder();
622 dstart[0] = dstart[1] = free_decode;
623 for (dp = data; dp < data+len && *dp < 2; ) {
624 dstart[*dp] = free_decode;
625 dp = make_decoder (++dp, 0);
628 } while (tag != 0xffda);
630 zero_after_ff = 1;
631 getbits(-1);
632 for (jrow=0; jrow < jhigh; jrow++)
638 for (jcol=0; jcol < jwide; jcol++)
640 for (dindex = dstart[jcol & 1]; dindex->branch[0]; )
641 dindex = dindex->branch[getbits(1)];
642 len = dindex->leaf;
643 diff = getbits(len);
644 if ((diff & (1 << (len-1))) == 0)
645 diff -= (1 << len) - 1;
646 if (jcol < 2) {
647 vpred[jcol] += diff;
648 hpred[jcol] = vpred[jcol];
649 } else
650 hpred[jcol & 1] += diff;
651 diff = hpred[jcol & 1];
652 if (diff < 0) diff = 0;
653 jidx = jrow*jwide + jcol;
654 if (raw_width == 5108) {
655 i = jidx / (1680*jhigh);
656 if (i < 2) {
657 row = jidx / 1680 % jhigh;
658 col = jidx % 1680 + i*1680;
659 } else {
660 jidx -= 2*1680*jhigh;
661 row = jidx / 1748;
662 col = jidx % 1748 + 2*1680;
664 } else {
665 row = jidx / raw_width;
666 col = jidx % raw_width;
668 if ((unsigned) (row-top_margin) >= height)
669 continue;
670 if ((unsigned) (col-left_margin) < width) {
671 BAYER(row-top_margin,col-left_margin) = curve[diff] << 2;
672 if (min > curve[diff])
673 min = curve[diff];
674 } else
675 bblack += curve[diff];
689 if (raw_width > width)
690 black = (bblack << 2) / ((raw_width - width) * height);
691 if (!strcasecmp(make,"KODAK"))
692 black = min << 2;
695 void CLASS nikon_compressed_load_raw()
697 static const uchar nikon_tree[] = {
698 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0,
699 5,4,3,6,2,7,1,0,8,9,11,10,12
701 int vpred[4], hpred[2], csize, row, col, i, len, diff;
702 ushort *curve;
703 struct decode *dindex;
705 init_decoder();
706 make_decoder (nikon_tree, 0);
708 fseek (ifp, curve_offset, SEEK_SET);
709 for (i=0; i < 4; i++)
710 vpred[i] = fget2(ifp);
711 csize = fget2(ifp);
712 curve = calloc (csize, sizeof *curve);
713 merror (curve, "nikon_compressed_load_raw()");
714 for (i=0; i < csize; i++)
715 curve[i] = fget2(ifp);
717 fseek (ifp, data_offset, SEEK_SET);
718 getbits(-1);
720 for (row=0; row < height; row++)
721 for (col=0; col < raw_width; col++)
723 for (dindex=first_decode; dindex->branch[0]; )
724 dindex = dindex->branch[getbits(1)];
725 len = dindex->leaf;
726 diff = getbits(len);
727 if ((diff & (1 << (len-1))) == 0)
728 diff -= (1 << len) - 1;
729 if (col < 2) {
730 i = 2*(row & 1) + (col & 1);
731 vpred[i] += diff;
732 hpred[col] = vpred[i];
733 } else
734 hpred[col & 1] += diff;
735 if ((unsigned) (col-left_margin) >= width) continue;
736 diff = hpred[col & 1];
737 if (diff < 0) diff = 0;
738 if (diff >= csize) diff = csize-1;
739 BAYER(row,col-left_margin) = curve[diff] << 2;
741 free(curve);
744 void CLASS nikon_load_raw()
746 int irow, row, col, i;
748 getbits(-1);
749 for (irow=0; irow < height; irow++) {
750 row = irow;
751 if (model[0] == 'E') {
752 row = irow * 2 % height + irow / (height/2);
753 if (row == 1 && atoi(model+1) < 5000) {
754 fseek (ifp, 0, SEEK_END);
755 fseek (ifp, ftell(ifp)/2, SEEK_SET);
756 getbits(-1);
759 for (col=0; col < raw_width; col++) {
760 i = getbits(12);
761 if ((unsigned) (col-left_margin) < width)
762 BAYER(row,col-left_margin) = i << 2;
763 if (tiff_data_compression == 34713 && (col % 10) == 9)
764 getbits(8);
770 Figure out if a NEF file is compressed. These fancy heuristics
771 are only needed for the D100, thanks to a bug in some cameras
772 that tags all images as "compressed".
774 int CLASS nikon_is_compressed()
776 uchar test[256];
777 int i;
779 if (tiff_data_compression != 34713)
780 return 0;
781 if (strcmp(model,"D100"))
782 return 1;
783 fseek (ifp, data_offset, SEEK_SET);
784 fread (test, 1, 256, ifp);
785 for (i=15; i < 256; i+=16)
786 if (test[i]) return 1;
787 return 0;
791 Returns 1 for a Coolpix 990, 0 for a Coolpix 995.
793 int CLASS nikon_e990()
795 int i, histo[256];
796 const uchar often[] = { 0x00, 0x55, 0xaa, 0xff };
798 memset (histo, 0, sizeof histo);
799 fseek (ifp, 2064*1540*3/4, SEEK_SET);
800 for (i=0; i < 2000; i++)
801 histo[fgetc(ifp)]++;
802 for (i=0; i < 4; i++)
803 if (histo[often[i]] > 400)
804 return 1;
805 return 0;
809 Returns 1 for a Coolpix 2100, 0 for anything else.
811 int CLASS nikon_e2100()
813 uchar t[12];
814 int i;
816 fseek (ifp, 0, SEEK_SET);
817 for (i=0; i < 1024; i++) {
818 fread (t, 1, 12, ifp);
819 if (((t[2] & t[4] & t[7] & t[9]) >> 4
820 & t[1] & t[6] & t[8] & t[11] & 3) != 3)
821 return 0;
823 return 1;
827 Separates a Minolta DiMAGE Z2 from a Nikon E4300.
829 int CLASS minolta_z2()
831 int i;
832 char tail[424];
834 fseek (ifp, -sizeof tail, SEEK_END);
835 fread (tail, 1, sizeof tail, ifp);
836 for (i=0; i < sizeof tail; i++)
837 if (tail[i]) return 1;
838 return 0;
841 void CLASS nikon_e2100_load_raw()
843 uchar data[3432], *dp;
844 ushort pixel[2288], *pix;
845 int row, col;
847 for (row=0; row <= height; row+=2) {
848 if (row == height) {
849 fseek (ifp, width==1616 ? 8792:424, SEEK_CUR);
850 row = 1;
852 fread (data, 1, width*3/2, ifp);
853 for (dp=data, pix=pixel; pix < pixel+width; dp+=12, pix+=8) {
854 pix[0] = (dp[2] >> 4) + (dp[ 3] << 4);
855 pix[1] = (dp[2] << 8) + dp[ 1];
856 pix[2] = (dp[7] >> 4) + (dp[ 0] << 4);
857 pix[3] = (dp[7] << 8) + dp[ 6];
858 pix[4] = (dp[4] >> 4) + (dp[ 5] << 4);
859 pix[5] = (dp[4] << 8) + dp[11];
860 pix[6] = (dp[9] >> 4) + (dp[10] << 4);
861 pix[7] = (dp[9] << 8) + dp[ 8];
863 for (col=0; col < width; col++)
864 BAYER(row,col) = (pixel[col] & 0xfff) << 2;
868 void CLASS nikon_e950_load_raw()
870 int irow, row, col;
872 getbits(-1);
873 for (irow=0; irow < height; irow++) {
874 row = irow * 2 % height;
875 for (col=0; col < width; col++)
876 BAYER(row,col) = getbits(10) << 4;
877 for (col=28; col--; )
878 getbits(8);
883 The Fuji Super CCD is just a Bayer grid rotated 45 degrees.
885 void CLASS fuji_s2_load_raw()
887 ushort pixel[2944];
888 int row, col, r, c;
890 fseek (ifp, (2944*24+32)*2, SEEK_CUR);
891 for (row=0; row < 2144; row++) {
892 fread (pixel, 2, 2944, ifp);
893 for (col=0; col < 2880; col++) {
894 r = row + ((col+1) >> 1);
895 c = 2143 - row + (col >> 1);
896 BAYER(r,c) = ntohs(pixel[col]) << 2;
901 void CLASS fuji_common_load_raw (int ncol, int icol, int nrow)
903 ushort pixel[2048];
904 int row, col, r, c;
906 for (row=0; row < nrow; row++) {
907 fread (pixel, 2, ncol, ifp);
908 if (ntohs(0xaa55) == 0xaa55) /* data is little-endian */
909 swab (pixel, pixel, ncol*2);
910 for (col=0; col <= icol; col++) {
911 r = icol - col + (row >> 1);
912 c = col + ((row+1) >> 1);
913 BAYER(r,c) = pixel[col] << 2;
918 void CLASS fuji_s5000_load_raw()
920 fseek (ifp, (1472*4+24)*2, SEEK_CUR);
921 fuji_common_load_raw (1472, 1423, 2152);
924 void CLASS fuji_s7000_load_raw()
926 fuji_common_load_raw (2048, 2047, 3080);
930 The Fuji Super CCD SR has two photodiodes for each pixel.
931 The secondary has about 1/16 the sensitivity of the primary,
932 but this ratio may vary.
934 void CLASS fuji_f700_load_raw()
936 ushort pixel[2944];
937 int row, col, r, c, val;
939 for (row=0; row < 2168; row++) {
940 fread (pixel, 2, 2944, ifp);
941 if (ntohs(0xaa55) == 0xaa55) /* data is little-endian */
942 swab (pixel, pixel, 2944*2);
943 for (col=0; col < 1440; col++) {
944 r = 1439 - col + (row >> 1);
945 c = col + ((row+1) >> 1);
946 val = pixel[col+16 + use_secondary*1472];
947 BAYER(r,c) = val;
952 void CLASS rollei_load_raw()
954 uchar pixel[10];
955 unsigned iten=0, isix, i, buffer=0, row, col, todo[16];
957 isix = raw_width * raw_height * 5 / 8;
958 while (fread (pixel, 1, 10, ifp) == 10) {
959 for (i=0; i < 10; i+=2) {
960 todo[i] = iten++;
961 todo[i+1] = pixel[i] << 8 | pixel[i+1];
962 buffer = pixel[i] >> 2 | buffer << 6;
964 for ( ; i < 16; i+=2) {
965 todo[i] = isix++;
966 todo[i+1] = buffer >> (14-i)*5;
968 for (i=0; i < 16; i+=2) {
969 row = todo[i] / raw_width - top_margin;
970 col = todo[i] % raw_width - left_margin;
971 if (row < height && col < width)
972 BAYER(row,col) = (todo[i+1] & 0x3ff) << 4;
977 void CLASS phase_one_load_raw()
979 int row, col, a, b;
980 ushort pixel[4134], akey, bkey;
982 fseek (ifp, 8, SEEK_CUR);
983 fseek (ifp, fget4(ifp) + 296, SEEK_CUR);
984 akey = fget2(ifp);
985 bkey = fget2(ifp);
986 fseek (ifp, data_offset + 12 + top_margin*raw_width*2, SEEK_SET);
987 for (row=0; row < height; row++) {
988 fread (pixel, 2, raw_width, ifp);
989 for (col=0; col < raw_width; col+=2) {
990 a = ntohs(pixel[col+0]) ^ akey;
991 b = ntohs(pixel[col+1]) ^ bkey;
992 pixel[col+0] = (b & 0xaaaa) | (a & 0x5555);
993 pixel[col+1] = (a & 0xaaaa) | (b & 0x5555);
995 for (col=0; col < width; col++)
996 BAYER(row,col) = pixel[col+left_margin];
1000 void CLASS ixpress_load_raw()
1002 ushort pixel[4090];
1003 int row, col;
1005 fseek (ifp, 304 + 6*2*4090, SEEK_SET);
1006 for (row=height; --row >= 0; ) {
1007 fread (pixel, 2, 4090, ifp);
1008 if (ntohs(0xaa55) == 0xaa55) /* data is little-endian */
1009 swab (pixel, pixel, 4090*2);
1010 for (col=0; col < width; col++)
1011 BAYER(row,col) = pixel[width-1-col];
1015 /* For this function only, raw_width is in bytes, not pixels! */
1016 void CLASS packed_12_load_raw()
1018 int row, col;
1020 getbits(-1);
1021 for (row=0; row < height; row++) {
1022 for (col=0; col < width; col++)
1023 BAYER(row,col) = getbits(12) << 2;
1024 for (col = width*3/2; col < raw_width; col++)
1025 getbits(8);
1029 void CLASS unpacked_load_raw (int order, int rsh)
1031 ushort *pixel;
1032 int row, col;
1034 pixel = calloc (raw_width, sizeof *pixel);
1035 merror (pixel, "unpacked_load_raw()");
1036 for (row=0; row < height; row++) {
1037 fread (pixel, 2, raw_width, ifp);
1038 if (order != ntohs(0x55aa))
1039 swab (pixel, pixel, width*2);
1040 for (col=0; col < width; col++)
1041 BAYER(row,col) = pixel[col] << 8 >> (8+rsh);
1043 free(pixel);
1046 void CLASS be_16_load_raw() /* "be" = "big-endian" */
1048 unpacked_load_raw (0x55aa, 0);
1051 void CLASS be_high_12_load_raw()
1053 unpacked_load_raw (0x55aa, 2);
1056 void CLASS be_low_12_load_raw()
1058 unpacked_load_raw (0x55aa,-2);
1061 void CLASS be_low_10_load_raw()
1063 unpacked_load_raw (0x55aa,-4);
1066 void CLASS le_high_12_load_raw() /* "le" = "little-endian" */
1068 unpacked_load_raw (0xaa55, 2);
1071 void CLASS olympus_cseries_load_raw()
1073 int irow, row, col;
1075 for (irow=0; irow < height; irow++) {
1076 row = irow * 2 % height + irow / (height/2);
1077 if (row < 2) {
1078 fseek (ifp, data_offset - row*(-width*height*3/4 & -2048), SEEK_SET);
1079 getbits(-1);
1081 for (col=0; col < width; col++)
1082 BAYER(row,col) = getbits(12) << 2;
1086 void CLASS eight_bit_load_raw()
1088 uchar *pixel;
1089 int row, col;
1091 pixel = calloc (raw_width, sizeof *pixel);
1092 merror (pixel, "eight_bit_load_raw()");
1093 for (row=0; row < height; row++) {
1094 fread (pixel, 1, raw_width, ifp);
1095 for (col=0; col < width; col++)
1096 BAYER(row,col) = pixel[col] << 6;
1098 free (pixel);
1101 void CLASS casio_qv5700_load_raw()
1103 uchar data[3232], *dp;
1104 ushort pixel[2576], *pix;
1105 int row, col;
1107 for (row=0; row < height; row++) {
1108 fread (data, 1, 3232, ifp);
1109 for (dp=data, pix=pixel; dp < data+3220; dp+=5, pix+=4) {
1110 pix[0] = (dp[0] << 2) + (dp[1] >> 6);
1111 pix[1] = (dp[1] << 4) + (dp[2] >> 4);
1112 pix[2] = (dp[2] << 6) + (dp[3] >> 2);
1113 pix[3] = (dp[3] << 8) + (dp[4] );
1115 for (col=0; col < width; col++)
1116 BAYER(row,col) = (pixel[col] & 0x3ff) << 4;
1120 void CLASS nucore_load_raw()
1122 uchar *data, *dp;
1123 int irow, row, col;
1125 data = calloc (width, 2);
1126 merror (data, "nucore_load_raw()");
1127 for (irow=0; irow < height; irow++) {
1128 fread (data, 2, width, ifp);
1129 if (model[0] == 'B' && width == 2598)
1130 row = height - 1 - irow/2 - height/2 * (irow & 1);
1131 else
1132 row = irow;
1133 for (dp=data, col=0; col < width; col++, dp+=2)
1134 BAYER(row,col) = (dp[0] << 2) + (dp[1] << 10);
1136 free(data);
1139 const int * CLASS make_decoder_int (const int *source, int level)
1141 struct decode *cur;
1143 cur = free_decode++;
1144 if (level < source[0]) {
1145 cur->branch[0] = free_decode;
1146 source = make_decoder_int (source, level+1);
1147 cur->branch[1] = free_decode;
1148 source = make_decoder_int (source, level+1);
1149 } else {
1150 cur->leaf = source[1];
1151 source += 2;
1153 return source;
1156 int CLASS radc_token (int tree)
1158 int t;
1159 static struct decode *dstart[18], *dindex;
1160 static const int *s, source[] = {
1161 1,1, 2,3, 3,4, 4,2, 5,7, 6,5, 7,6, 7,8,
1162 1,0, 2,1, 3,3, 4,4, 5,2, 6,7, 7,6, 8,5, 8,8,
1163 2,1, 2,3, 3,0, 3,2, 3,4, 4,6, 5,5, 6,7, 6,8,
1164 2,0, 2,1, 2,3, 3,2, 4,4, 5,6, 6,7, 7,5, 7,8,
1165 2,1, 2,4, 3,0, 3,2, 3,3, 4,7, 5,5, 6,6, 6,8,
1166 2,3, 3,1, 3,2, 3,4, 3,5, 3,6, 4,7, 5,0, 5,8,
1167 2,3, 2,6, 3,0, 3,1, 4,4, 4,5, 4,7, 5,2, 5,8,
1168 2,4, 2,7, 3,3, 3,6, 4,1, 4,2, 4,5, 5,0, 5,8,
1169 2,6, 3,1, 3,3, 3,5, 3,7, 3,8, 4,0, 5,2, 5,4,
1170 2,0, 2,1, 3,2, 3,3, 4,4, 4,5, 5,6, 5,7, 4,8,
1171 1,0, 2,2, 2,-2,
1172 1,-3, 1,3,
1173 2,-17, 2,-5, 2,5, 2,17,
1174 2,-7, 2,2, 2,9, 2,18,
1175 2,-18, 2,-9, 2,-2, 2,7,
1176 2,-28, 2,28, 3,-49, 3,-9, 3,9, 4,49, 5,-79, 5,79,
1177 2,-1, 2,13, 2,26, 3,39, 4,-16, 5,55, 6,-37, 6,76,
1178 2,-26, 2,-13, 2,1, 3,-39, 4,16, 5,-55, 6,-76, 6,37
1181 if (free_decode == first_decode)
1182 for (s=source, t=0; t < 18; t++) {
1183 dstart[t] = free_decode;
1184 s = make_decoder_int (s, 0);
1186 if (tree == 18) {
1187 if (model[2] == '4')
1188 return (getbits(5) << 3) + 4; /* DC40 */
1189 else
1190 return (getbits(6) << 2) + 2; /* DC50 */
1192 for (dindex = dstart[tree]; dindex->branch[0]; )
1193 dindex = dindex->branch[getbits(1)];
1194 return dindex->leaf;
1197 #define FORYX for (y=1; y < 3; y++) for (x=col+1; x >= col; x--)
1199 #define PREDICTOR (c ? (buf[c][y-1][x] + buf[c][y][x+1]) / 2 \
1200 : (buf[c][y-1][x+1] + 2*buf[c][y-1][x] + buf[c][y][x+1]) / 4)
1202 void CLASS kodak_radc_load_raw()
1204 int row, col, tree, nreps, rep, step, i, c, s, r, x, y, val;
1205 short last[3] = { 16,16,16 }, mul[3], buf[3][3][386];
1207 init_decoder();
1208 getbits(-1);
1209 for (i=0; i < sizeof(buf)/sizeof(short); i++)
1210 buf[0][0][i] = 2048;
1211 for (row=0; row < height; row+=4) {
1212 for (i=0; i < 3; i++)
1213 mul[i] = getbits(6);
1214 for (c=0; c < 3; c++) {
1215 val = ((0x1000000/last[c] + 0x7ff) >> 12) * mul[c];
1216 s = val > 65564 ? 10:12;
1217 x = ~(-1 << (s-1));
1218 val <<= 12-s;
1219 for (i=0; i < sizeof(buf[0])/sizeof(short); i++)
1220 buf[c][0][i] = (buf[c][0][i] * val + x) >> s;
1221 last[c] = mul[c];
1222 for (r=0; r <= !c; r++) {
1223 buf[c][1][width/2] = buf[c][2][width/2] = mul[c] << 7;
1224 for (tree=1, col=width/2; col > 0; ) {
1225 if ((tree = radc_token(tree))) {
1226 col -= 2;
1227 if (tree == 8)
1228 FORYX buf[c][y][x] = radc_token(tree+10) * mul[c];
1229 else
1230 FORYX buf[c][y][x] = radc_token(tree+10) * 16 + PREDICTOR;
1231 } else
1232 do {
1233 nreps = (col > 2) ? radc_token(9) + 1 : 1;
1234 for (rep=0; rep < 8 && rep < nreps && col > 0; rep++) {
1235 col -= 2;
1236 FORYX buf[c][y][x] = PREDICTOR;
1237 if (rep & 1) {
1238 step = radc_token(10) << 4;
1239 FORYX buf[c][y][x] += step;
1242 } while (nreps == 9);
1244 for (y=0; y < 2; y++)
1245 for (x=0; x < width/2; x++) {
1246 val = (buf[c][y+1][x] << 4) / mul[c];
1247 if (val < 0) val = 0;
1248 if (c)
1249 BAYER(row+y*2+c-1,x*2+2-c) = val;
1250 else
1251 BAYER(row+r*2+y,x*2+y) = val;
1253 memcpy (buf[c][0]+!c, buf[c][2], sizeof buf[c][0]-2*!c);
1256 for (y=row; y < row+4; y++)
1257 for (x=0; x < width; x++)
1258 if ((x+y) & 1) {
1259 val = (BAYER(y,x)-2048)*2 + (BAYER(y,x-1)+BAYER(y,x+1))/2;
1260 if (val < 0) val = 0;
1261 BAYER(y,x) = val;
1266 #undef FORYX
1267 #undef PREDICTOR
1269 #ifdef NO_JPEG
1270 void CLASS kodak_jpeg_load_raw() {}
1271 #else
1273 METHODDEF(boolean)
1274 fill_input_buffer (j_decompress_ptr cinfo)
1276 static char jpeg_buffer[4096];
1277 size_t nbytes;
1279 nbytes = fread (jpeg_buffer, 1, 4096, ifp);
1280 swab (jpeg_buffer, jpeg_buffer, nbytes);
1281 cinfo->src->next_input_byte = jpeg_buffer;
1282 cinfo->src->bytes_in_buffer = nbytes;
1283 return TRUE;
1286 void CLASS kodak_jpeg_load_raw()
1288 struct jpeg_decompress_struct cinfo;
1289 struct jpeg_error_mgr jerr;
1290 JSAMPARRAY buf;
1291 JSAMPLE (*pixel)[3];
1292 int row, col;
1294 cinfo.err = jpeg_std_error (&jerr);
1295 jpeg_create_decompress (&cinfo);
1296 jpeg_stdio_src (&cinfo, ifp);
1297 cinfo.src->fill_input_buffer = fill_input_buffer;
1298 jpeg_read_header (&cinfo, TRUE);
1299 jpeg_start_decompress (&cinfo);
1300 if ((cinfo.output_width != width ) ||
1301 (cinfo.output_height*2 != height ) ||
1302 (cinfo.output_components != 3 )) {
1303 fprintf (stderr, "%s: incorrect JPEG dimensions\n", ifname);
1304 jpeg_destroy_decompress (&cinfo);
1305 longjmp (failure, 3);
1307 buf = (*cinfo.mem->alloc_sarray)
1308 ((j_common_ptr) &cinfo, JPOOL_IMAGE, width*3, 1);
1310 while (cinfo.output_scanline < cinfo.output_height) {
1311 row = cinfo.output_scanline * 2;
1312 jpeg_read_scanlines (&cinfo, buf, 1);
1313 pixel = (void *) buf[0];
1314 for (col=0; col < width; col+=2) {
1315 BAYER(row+0,col+0) = pixel[col+0][1] << 6;
1316 BAYER(row+1,col+1) = pixel[col+1][1] << 6;
1317 BAYER(row+0,col+1) = (pixel[col][0] + pixel[col+1][0]) << 5;
1318 BAYER(row+1,col+0) = (pixel[col][2] + pixel[col+1][2]) << 5;
1321 jpeg_finish_decompress (&cinfo);
1322 jpeg_destroy_decompress (&cinfo);
1325 #endif
1327 void CLASS kodak_dc120_load_raw()
1329 static const int mul[4] = { 162, 192, 187, 92 };
1330 static const int add[4] = { 0, 636, 424, 212 };
1331 uchar pixel[848];
1332 int row, shift, col;
1334 for (row=0; row < height; row++)
1336 fread (pixel, 848, 1, ifp);
1337 shift = row * mul[row & 3] + add[row & 3];
1338 for (col=0; col < width; col++)
1339 BAYER(row,col) = (ushort) pixel[(col + shift) % 848] << 6;
1343 void CLASS kodak_dc20_coeff (float juice)
1345 static const float my_coeff[3][4] =
1346 { { 2.25, 0.75, -1.75, -0.25 },
1347 { -0.25, 0.75, 0.75, -0.25 },
1348 { -0.25, -1.75, 0.75, 2.25 } };
1349 static const float flat[3][4] =
1350 { { 1, 0, 0, 0 },
1351 { 0, 0.5, 0.5, 0 },
1352 { 0, 0, 0, 1 } };
1353 int r, g;
1355 if (juice != 0) {
1356 for (r=0; r < 3; r++)
1357 for (g=0; g < 4; g++)
1358 coeff[r][g] = my_coeff[r][g] * juice + flat[r][g] * (1-juice);
1359 use_coeff = 1;
1363 void CLASS kodak_easy_load_raw()
1365 uchar *pixel;
1366 ushort curve[0x1000];
1367 unsigned row, col, icol;
1369 kodak_curve (curve);
1370 if (raw_width > width)
1371 black = 0;
1372 pixel = calloc (raw_width, sizeof *pixel);
1373 merror (pixel, "kodak_easy_load_raw()");
1374 for (row=0; row < height; row++) {
1375 fread (pixel, 1, raw_width, ifp);
1376 for (col=0; col < raw_width; col++) {
1377 icol = col - left_margin;
1378 if (icol < width)
1379 BAYER(row,icol) = (ushort) curve[pixel[col]] << 2;
1380 else
1381 black += curve[pixel[col]];
1384 if (raw_width > width)
1385 black = ((INT64) black << 2) / ((raw_width - width) * height);
1386 if (!strncmp(model,"DC2",3))
1387 black = 0;
1388 free(pixel);
1391 void CLASS kodak_compressed_load_raw()
1393 uchar c, blen[256];
1394 ushort raw[6], curve[0x1000];
1395 unsigned row, col, len, save, i, israw=0, bits=0, pred[2];
1396 INT64 bitbuf=0;
1397 int diff;
1399 kodak_curve (curve);
1400 for (row=0; row < height; row++)
1401 for (col=0; col < width; col++)
1403 if ((col & 255) == 0) { /* Get the bit-lengths of the */
1404 len = width - col; /* next 256 pixel values */
1405 if (len > 256) len = 256;
1406 save = ftell(ifp);
1407 for (israw=i=0; i < len; i+=2) {
1408 c = fgetc(ifp);
1409 if ((blen[i+0] = c & 15) > 12 ||
1410 (blen[i+1] = c >> 4) > 12 )
1411 israw = 1;
1413 bitbuf = bits = pred[0] = pred[1] = 0;
1414 if (len % 8 == 4) {
1415 bitbuf = fgetc(ifp) << 8;
1416 bitbuf += fgetc(ifp);
1417 bits = 16;
1419 if (israw)
1420 fseek (ifp, save, SEEK_SET);
1422 if (israw) { /* If the data is not compressed */
1423 switch (col & 7) {
1424 case 0:
1425 fread (raw, 2, 6, ifp);
1426 for (i=0; i < 6; i++)
1427 raw[i] = ntohs(raw[i]);
1428 diff = raw[0] >> 12 << 8 | raw[2] >> 12 << 4 | raw[4] >> 12;
1429 break;
1430 case 1:
1431 diff = raw[1] >> 12 << 8 | raw[3] >> 12 << 4 | raw[5] >> 12;
1432 break;
1433 default:
1434 diff = raw[(col & 7) - 2] & 0xfff;
1436 } else { /* If the data is compressed */
1437 len = blen[col & 255]; /* Number of bits for this pixel */
1438 if (bits < len) { /* Got enough bits in the buffer? */
1439 for (i=0; i < 32; i+=8)
1440 bitbuf += (INT64) fgetc(ifp) << (bits+(i^8));
1441 bits += 32;
1443 diff = bitbuf & (0xffff >> (16-len)); /* Pull bits from buffer */
1444 bitbuf >>= len;
1445 bits -= len;
1446 if ((diff & (1 << (len-1))) == 0)
1447 diff -= (1 << len) - 1;
1448 pred[col & 1] += diff;
1449 diff = pred[col & 1];
1451 BAYER(row,col) = curve[diff] << 2;
1455 void CLASS kodak_yuv_load_raw()
1457 uchar c, blen[384];
1458 unsigned row, col, len, bits=0;
1459 INT64 bitbuf=0;
1460 int i, li=0, si, diff, six[6], y[4], cb=0, cr=0, rgb[3];
1461 ushort *ip, curve[0x1000];
1463 kodak_curve (curve);
1464 for (row=0; row < height; row+=2)
1465 for (col=0; col < width; col+=2) {
1466 if ((col & 127) == 0) {
1467 len = (width - col + 1) * 3 & -4;
1468 if (len > 384) len = 384;
1469 for (i=0; i < len; ) {
1470 c = fgetc(ifp);
1471 blen[i++] = c & 15;
1472 blen[i++] = c >> 4;
1474 li = bitbuf = bits = y[1] = y[3] = cb = cr = 0;
1475 if (len % 8 == 4) {
1476 bitbuf = fgetc(ifp) << 8;
1477 bitbuf += fgetc(ifp);
1478 bits = 16;
1481 for (si=0; si < 6; si++) {
1482 len = blen[li++];
1483 if (bits < len) {
1484 for (i=0; i < 32; i+=8)
1485 bitbuf += (INT64) fgetc(ifp) << (bits+(i^8));
1486 bits += 32;
1488 diff = bitbuf & (0xffff >> (16-len));
1489 bitbuf >>= len;
1490 bits -= len;
1491 if ((diff & (1 << (len-1))) == 0)
1492 diff -= (1 << len) - 1;
1493 six[si] = diff;
1495 y[0] = six[0] + y[1];
1496 y[1] = six[1] + y[0];
1497 y[2] = six[2] + y[3];
1498 y[3] = six[3] + y[2];
1499 cb += six[4];
1500 cr += six[5];
1501 for (i=0; i < 4; i++) {
1502 ip = image[(row+(i >> 1))*width + col+(i & 1)];
1503 rgb[0] = y[i] + cr;
1504 rgb[1] = y[i];
1505 rgb[2] = y[i] + cb;
1506 for (c=0; c < 3; c++)
1507 if (rgb[c] > 0) ip[c] = curve[rgb[c]] << 2;
1512 void CLASS sony_decrypt (unsigned *data, int len, int start, int key)
1514 static unsigned pad[128], p;
1516 if (start) {
1517 for (p=0; p < 4; p++)
1518 pad[p] = key = key * 48828125 + 1;
1519 pad[3] = pad[3] << 1 | (pad[0]^pad[2]) >> 31;
1520 for (p=4; p < 127; p++)
1521 pad[p] = (pad[p-4]^pad[p-2]) << 1 | (pad[p-3]^pad[p-1]) >> 31;
1522 for (p=0; p < 127; p++)
1523 pad[p] = htonl(pad[p]);
1525 while (len--)
1526 *data++ ^= pad[p++ & 127] = pad[(p+1) & 127] ^ pad[(p+65) & 127];
1529 void CLASS sony_load_raw()
1531 uchar head[40];
1532 ushort pixel[3360];
1533 unsigned i, key, row, col, icol;
1534 INT64 bblack=0;
1536 fseek (ifp, 200896, SEEK_SET);
1537 fseek (ifp, (unsigned) fgetc(ifp)*4 - 1, SEEK_CUR);
1538 order = 0x4d4d;
1539 key = fget4(ifp);
1540 fseek (ifp, 164600, SEEK_SET);
1541 fread (head, 1, 40, ifp);
1542 sony_decrypt ((void *) head, 10, 1, key);
1543 for (i=26; i-- > 22; )
1544 key = key << 8 | head[i];
1545 fseek (ifp, 862144, SEEK_SET);
1546 for (row=0; row < height; row++) {
1547 fread (pixel, 2, raw_width, ifp);
1548 sony_decrypt ((void *) pixel, raw_width/2, !row, key);
1549 for (col=0; col < 3343; col++)
1550 if ((icol = col-left_margin) < width)
1551 BAYER(row,icol) = ntohs(pixel[col]);
1552 else
1553 bblack += ntohs(pixel[col]);
1555 black = bblack / ((3343 - width) * height);
1558 void CLASS sony_rgbe_coeff()
1560 int r, g;
1561 static const float my_coeff[3][4] =
1562 { { 1.321918, 0.000000, 0.149829, -0.471747 },
1563 { -0.288764, 1.129213, -0.486517, 0.646067 },
1564 { 0.061336, -0.199343, 1.138007, 0.000000 } };
1566 for (r=0; r < 3; r++)
1567 for (g=0; g < 4; g++)
1568 coeff[r][g] = my_coeff[r][g];
1569 use_coeff = 1;
1572 void CLASS foveon_decoder (unsigned huff[1024], unsigned code)
1574 struct decode *cur;
1575 int i, len;
1577 cur = free_decode++;
1578 if (free_decode > first_decode+2048) {
1579 fprintf (stderr, "%s: decoder table overflow\n", ifname);
1580 longjmp (failure, 2);
1582 if (code) {
1583 for (i=0; i < 1024; i++)
1584 if (huff[i] == code) {
1585 cur->leaf = i;
1586 return;
1589 if ((len = code >> 27) > 26) return;
1590 code = (len+1) << 27 | (code & 0x3ffffff) << 1;
1592 cur->branch[0] = free_decode;
1593 foveon_decoder (huff, code);
1594 cur->branch[1] = free_decode;
1595 foveon_decoder (huff, code+1);
1598 void CLASS foveon_load_raw()
1600 struct decode *dindex;
1601 short diff[1024], pred[3];
1602 unsigned huff[1024], bitbuf=0;
1603 int row, col, bit=-1, c, i;
1605 fseek (ifp, 260, SEEK_SET);
1606 for (i=0; i < 1024; i++)
1607 diff[i] = fget2(ifp);
1608 for (i=0; i < 1024; i++)
1609 huff[i] = fget4(ifp);
1611 init_decoder();
1612 foveon_decoder (huff, 0);
1614 for (row=0; row < raw_height; row++) {
1615 memset (pred, 0, sizeof pred);
1616 if (!bit) fget4(ifp);
1617 for (col=bit=0; col < raw_width; col++) {
1618 for (c=0; c < 3; c++) {
1619 for (dindex=first_decode; dindex->branch[0]; ) {
1620 if ((bit = (bit-1) & 31) == 31)
1621 for (i=0; i < 4; i++)
1622 bitbuf = (bitbuf << 8) + fgetc(ifp);
1623 dindex = dindex->branch[bitbuf >> bit & 1];
1625 pred[c] += diff[dindex->leaf];
1627 if ((unsigned) (row-top_margin) >= height ||
1628 (unsigned) (col-left_margin) >= width ) continue;
1629 for (c=0; c < 3; c++)
1630 if (pred[c] > 0)
1631 image[(row-top_margin)*width+(col-left_margin)][c] = pred[c];
1636 int CLASS apply_curve (int i, const int *curve)
1638 if (i <= -curve[0])
1639 return -curve[curve[0]]-1;
1640 else if (i < 0)
1641 return -curve[1-i];
1642 else if (i < curve[0])
1643 return curve[1+i];
1644 else
1645 return curve[curve[0]]+1;
1648 void CLASS foveon_interpolate()
1650 float mul[3] =
1651 { 1.0321, 1.0, 1.1124 };
1652 static const int weight[3][3][3] =
1653 { { { 4141, 37726, 11265 },
1654 { -30437, 16066, -41102 },
1655 { 326, -413, 362 } },
1656 { { 1770, -1316, 3480 },
1657 { -2139, 213, -4998 },
1658 { -2381, 3496, -2008 } },
1659 { { -3838, -24025, -12968 },
1660 { 20144, -12195, 30272 },
1661 { -631, -2025, 822 } } },
1662 curve1[73] = { 72,
1663 0,1,2,2,3,4,5,6,6,7,8,9,9,10,11,11,12,13,13,14,14,
1664 15,16,16,17,17,18,18,18,19,19,20,20,20,21,21,21,22,
1665 22,22,23,23,23,23,23,24,24,24,24,24,25,25,25,25,25,
1666 25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,26,26 },
1667 curve2[21] = { 20,
1668 0,1,1,2,3,3,4,4,5,5,6,6,6,7,7,7,7,7,7,7 },
1669 curve3[73] = { 72,
1670 0,1,1,2,2,3,4,4,5,5,6,6,7,7,8,8,8,9,9,10,10,10,10,
1671 11,11,11,12,12,12,12,12,12,13,13,13,13,13,13,13,13,
1672 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,
1673 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14 },
1674 curve4[37] = { 36,
1675 0,1,1,2,3,3,4,4,5,6,6,7,7,7,8,8,9,9,9,10,10,10,
1676 11,11,11,11,11,12,12,12,12,12,12,12,12,12 },
1677 curve5[111] = { 110,
1678 0,1,1,2,3,3,4,5,6,6,7,7,8,9,9,10,11,11,12,12,13,13,
1679 14,14,15,15,16,16,17,17,18,18,18,19,19,19,20,20,20,
1680 21,21,21,21,22,22,22,22,22,23,23,23,23,23,24,24,24,24,
1681 24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,26,26,
1682 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,
1683 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26 },
1684 *curves[3] = { curve3, curve4, curve5 },
1685 trans[3][3] =
1686 { { 7576, -2933, 1279 },
1687 { -11594, 29911, -12394 },
1688 { 4000, -18850, 20772 } };
1689 ushort *pix, prev[3], (*shrink)[3];
1690 int row, col, c, i, j, diff, sum, ipix[3], work[3][3], total[4];
1691 int (*smrow[7])[3], smlast, smred, smred_p=0, hood[7], min, max;
1693 /* Sharpen all colors */
1694 for (row=0; row < height; row++) {
1695 pix = image[row*width];
1696 memcpy (prev, pix, sizeof prev);
1697 for (col=0; col < width; col++) {
1698 for (c=0; c < 3; c++) {
1699 diff = pix[c] - prev[c];
1700 prev[c] = pix[c];
1701 ipix[c] = pix[c] + ((diff + (diff*diff >> 14)) * 0x3333 >> 14);
1703 for (c=0; c < 3; c++) {
1704 work[0][c] = ipix[c]*ipix[c] >> 14;
1705 work[2][c] = ipix[c]*work[0][c] >> 14;
1706 work[1][2-c] = ipix[(c+1) % 3] * ipix[(c+2) % 3] >> 14;
1708 for (c=0; c < 3; c++) {
1709 for (sum=i=0; i < 3; i++)
1710 for ( j=0; j < 3; j++)
1711 sum += weight[c][i][j] * work[i][j];
1712 ipix[c] = (ipix[c] + (sum >> 14)) * mul[c];
1713 if (ipix[c] < 0) ipix[c] = 0;
1714 if (ipix[c] > 32000) ipix[c] = 32000;
1715 pix[c] = ipix[c];
1717 pix += 4;
1720 /* Array for 5x5 Gaussian averaging of red values */
1721 smrow[6] = calloc (width*5, sizeof **smrow);
1722 merror (smrow[6], "foveon_interpolate()");
1723 for (i=0; i < 5; i++)
1724 smrow[i] = smrow[6] + i*width;
1726 /* Sharpen the reds against these Gaussian averages */
1727 for (smlast=-1, row=2; row < height-2; row++) {
1728 while (smlast < row+2) {
1729 for (i=0; i < 6; i++)
1730 smrow[(i+5) % 6] = smrow[i];
1731 pix = image[++smlast*width+2];
1732 for (col=2; col < width-2; col++) {
1733 smrow[4][col][0] =
1734 (pix[0]*6 + (pix[-4]+pix[4])*4 + pix[-8]+pix[8] + 8) >> 4;
1735 pix += 4;
1738 pix = image[row*width+2];
1739 for (col=2; col < width-2; col++) {
1740 smred = (smrow[2][col][0]*6 + (smrow[1][col][0]+smrow[3][col][0])*4
1741 + smrow[0][col][0]+smrow[4][col][0] + 8) >> 4;
1742 if (col == 2)
1743 smred_p = smred;
1744 i = pix[0] + ((pix[0] - ((smred*7 + smred_p) >> 3)) >> 2);
1745 if (i < 0) i = 0;
1746 if (i > 10000) i = 10000;
1747 pix[0] = i;
1748 smred_p = smred;
1749 pix += 4;
1752 /* Limit each color value to the range of its neighbors */
1753 hood[0] = 4;
1754 for (i=0; i < 3; i++) {
1755 hood[i+1] = (i-width-1)*4;
1756 hood[i+4] = (i+width-1)*4;
1758 for (row=1; row < height-1; row++) {
1759 pix = image[row*width+1];
1760 memcpy (prev, pix-4, sizeof prev);
1761 for (col=1; col < width-1; col++) {
1762 for (c=0; c < 3; c++) {
1763 for (min=max=prev[c], i=0; i < 7; i++) {
1764 j = pix[hood[i]];
1765 if (min > j) min = j;
1766 if (max < j) max = j;
1768 prev[c] = *pix;
1769 if (*pix < min) *pix = min;
1770 if (*pix > max) *pix = max;
1771 pix++;
1773 pix++;
1777 Because photons that miss one detector often hit another,
1778 the sum R+G+B is much less noisy than the individual colors.
1779 So smooth the hues without smoothing the total.
1781 for (smlast=-1, row=2; row < height-2; row++) {
1782 while (smlast < row+2) {
1783 for (i=0; i < 6; i++)
1784 smrow[(i+5) % 6] = smrow[i];
1785 pix = image[++smlast*width+2];
1786 for (col=2; col < width-2; col++) {
1787 for (c=0; c < 3; c++)
1788 smrow[4][col][c] = pix[c-8]+pix[c-4]+pix[c]+pix[c+4]+pix[c+8];
1789 pix += 4;
1792 pix = image[row*width+2];
1793 for (col=2; col < width-2; col++) {
1794 for (total[3]=1500, sum=60, c=0; c < 3; c++) {
1795 for (total[c]=i=0; i < 5; i++)
1796 total[c] += smrow[i][col][c];
1797 total[3] += total[c];
1798 sum += pix[c];
1800 j = (sum << 16) / total[3];
1801 for (c=0; c < 3; c++) {
1802 i = apply_curve ((total[c] * j >> 16) - pix[c], curve1);
1803 i += pix[c] - 13 - (c==1);
1804 ipix[c] = i - apply_curve (i, curve2);
1806 sum = (ipix[0]+ipix[1]+ipix[1]+ipix[2]) >> 2;
1807 for (c=0; c < 3; c++) {
1808 i = ipix[c] - apply_curve (ipix[c] - sum, curve2);
1809 if (i < 0) i = 0;
1810 pix[c] = i;
1812 pix += 4;
1815 /* Translate the image to a different colorspace */
1816 for (pix=image[0]; pix < image[height*width]; pix+=4) {
1817 for (c=0; c < 3; c++) {
1818 for (i=j=0; j < 3; j++)
1819 i += trans[c][j] * pix[j];
1820 i = (i+0x1000) >> 13;
1821 if (i < 0) i = 0;
1822 if (i > 24000) i = 24000;
1823 ipix[c] = i;
1825 for (c=0; c < 3; c++)
1826 pix[c] = ipix[c];
1828 /* Smooth the image bottom-to-top and save at 1/4 scale */
1829 shrink = calloc ((width/4) * (height/4), sizeof *shrink);
1830 merror (shrink, "foveon_interpolate()");
1831 for (row = height/4; row--; )
1832 for (col=0; col < width/4; col++) {
1833 ipix[0] = ipix[1] = ipix[2] = 0;
1834 for (i=0; i < 4; i++)
1835 for (j=0; j < 4; j++)
1836 for (c=0; c < 3; c++)
1837 ipix[c] += image[(row*4+i)*width+col*4+j][c];
1838 for (c=0; c < 3; c++)
1839 if (row+2 > height/4)
1840 shrink[row*(width/4)+col][c] = ipix[c] >> 4;
1841 else
1842 shrink[row*(width/4)+col][c] =
1843 (shrink[(row+1)*(width/4)+col][c]*1840 + ipix[c]*141) >> 12;
1846 /* From the 1/4-scale image, smooth right-to-left */
1847 for (row=0; row < (height & ~3); row++) {
1848 ipix[0] = ipix[1] = ipix[2] = 0;
1849 if ((row & 3) == 0)
1850 for (col = width & ~3 ; col--; )
1851 for (c=0; c < 3; c++)
1852 smrow[0][col][c] = ipix[c] =
1853 (shrink[(row/4)*(width/4)+col/4][c]*1485 + ipix[c]*6707) >> 13;
1855 /* Then smooth left-to-right */
1856 ipix[0] = ipix[1] = ipix[2] = 0;
1857 for (col=0; col < (width & ~3); col++)
1858 for (c=0; c < 3; c++)
1859 smrow[1][col][c] = ipix[c] =
1860 (smrow[0][col][c]*1485 + ipix[c]*6707) >> 13;
1862 /* Smooth top-to-bottom */
1863 if (row == 0)
1864 memcpy (smrow[2], smrow[1], sizeof **smrow * width);
1865 else
1866 for (col=0; col < (width & ~3); col++)
1867 for (c=0; c < 3; c++)
1868 smrow[2][col][c] =
1869 (smrow[2][col][c]*6707 + smrow[1][col][c]*1485) >> 13;
1871 /* Adjust the chroma toward the smooth values */
1872 for (col=0; col < (width & ~3); col++) {
1873 for (i=j=60, c=0; c < 3; c++) {
1874 i += smrow[2][col][c];
1875 j += image[row*width+col][c];
1877 j = (j << 16) / i;
1878 for (sum=c=0; c < 3; c++) {
1879 i = (smrow[2][col][c] * j >> 16) - image[row*width+col][c];
1880 ipix[c] = apply_curve (i, curves[c]);
1881 sum += ipix[c];
1883 sum >>= 3;
1884 for (c=0; c < 3; c++) {
1885 i = image[row*width+col][c] + ipix[c] - sum;
1886 if (i < 0) i = 0;
1887 image[row*width+col][c] = i;
1891 free(shrink);
1892 free(smrow[6]);
1896 Seach from the current directory up to the root looking for
1897 a ".badpixels" file, and fix those pixels now.
1899 void CLASS bad_pixels()
1901 FILE *fp=NULL;
1902 char *fname, *cp, line[128];
1903 int len, time, row, col, r, c, rad, tot, n, fixed=0;
1905 if (!filters) return;
1906 for (len=16 ; ; len *= 2) {
1907 fname = malloc (len);
1908 if (!fname) return;
1909 if (getcwd (fname, len-12)) break;
1910 free (fname);
1911 if (errno != ERANGE) return;
1913 #ifdef WIN32
1914 if (fname[1] == ':')
1915 memmove (fname, fname+2, len-2);
1916 for (cp=fname; *cp; cp++)
1917 if (*cp == '\\') *cp = '/';
1918 #endif
1919 cp = fname + strlen(fname);
1920 if (cp[-1] == '/') cp--;
1921 while (*fname == '/') {
1922 strcpy (cp, "/.badpixels");
1923 if ((fp = fopen (fname, "r"))) break;
1924 if (cp == fname) break;
1925 while (*--cp != '/');
1927 free (fname);
1928 if (!fp) return;
1929 while (fgets (line, 128, fp)) {
1930 cp = strchr (line, '#');
1931 if (cp) *cp = 0;
1932 if (sscanf (line, "%d %d %d", &col, &row, &time) != 3) continue;
1933 if ((unsigned) col >= width || (unsigned) row >= height) continue;
1934 if (time > timestamp) continue;
1935 for (tot=n=0, rad=1; rad < 3 && n==0; rad++)
1936 for (r = row-rad; r <= row+rad; r++)
1937 for (c = col-rad; c <= col+rad; c++)
1938 if ((unsigned) r < height && (unsigned) c < width &&
1939 (r != row || c != col) && FC(r,c) == FC(row,col)) {
1940 tot += BAYER(r,c);
1941 n++;
1943 BAYER(row,col) = tot/n;
1944 if (verbose) {
1945 if (!fixed++)
1946 fprintf (stderr, "Fixed bad pixels at:");
1947 fprintf (stderr, " %d,%d", col, row);
1950 if (fixed) fputc ('\n', stderr);
1951 fclose (fp);
1954 int CLASS get_generic_parameter(FILE *fp, const char *name, const char *line,
1955 const char *sequence, void *where, int *flag)
1957 if (strcmp(line, name) == 0) {
1958 int status;
1959 char data[128];
1960 if (!fgets(data, 127, fp))
1961 return -1;
1962 if (feof(fp))
1963 return -1;
1964 status = sscanf (data, sequence, where);
1965 if (status != 1)
1966 return -1;
1967 if (flag)
1968 *flag = 1;
1969 return 1;
1970 } else
1971 return 0;
1974 int CLASS get_float_parameter(FILE *fp, const char *name, const char *line,
1975 float *where, int *flag)
1977 return get_generic_parameter(fp, name, line, "%f", where, flag);
1980 int CLASS get_int_parameter(FILE *fp, const char *name, const char *line,
1981 int *where, int *flag)
1983 return get_generic_parameter(fp, name, line, "%d", where, flag);
1987 Get value of parameters from file.
1989 int get_parameter_value(FILE *fp)
1991 char *cp, line[128], data[128];
1992 float my_coeff[3][4];
1993 int i, j;
1994 int got_coeff=0;
1996 while (1) {
1997 fgets (line, 128, fp);
1998 if (feof(fp)) break;
1999 cp = strchr (line, '#');
2000 if (cp) *cp = 0;
2002 if (get_float_parameter(fp, "gamma:\n", line,
2003 &gamma_val, NULL) == -1)
2004 break;
2006 if (get_float_parameter(fp, "brightness:\n", line,
2007 &bright, NULL) == -1)
2008 break;
2010 if (get_float_parameter(fp, "red scale:\n", line,
2011 &red_scale, NULL) == -1)
2012 break;
2014 if (get_float_parameter(fp, "blue scale:\n", line,
2015 &blue_scale, NULL) == -1)
2016 break;
2018 if (get_float_parameter(fp, "green scale:\n", line,
2019 &green_scale, NULL) == -1)
2020 break;
2022 if (get_float_parameter(fp, "juice:\n", line,
2023 &juice, NULL) == -1)
2024 break;
2026 if (get_float_parameter(fp, "white point fraction:\n", line,
2027 &white_point_fraction, NULL) == -1)
2028 break;
2030 if (get_float_parameter(fp, "pivot value:\n", line,
2031 &pivot_value, NULL) == -1)
2032 break;
2034 if (get_float_parameter(fp, "exposure compensation:\n", line,
2035 &exposure_compensation, NULL) == -1)
2036 break;
2038 if (get_float_parameter(fp, "saturation:\n", line,
2039 &saturation, NULL) == -1)
2040 break;
2042 if (get_float_parameter(fp, "contrast:\n", line,
2043 &contrast, NULL) == -1)
2044 break;
2046 if (get_int_parameter(fp, "flip:\n", line,
2047 &flip, NULL) == -1)
2048 break;
2050 if (!strcmp(line, "color matrix:\n")) {
2051 int status = 0;
2052 for (i=0; i < 3; i++) {
2053 fgets (data, 128, fp);
2054 if (feof(fp)) {
2055 got_coeff = 0;
2056 break;
2058 status= sscanf (data, "%f %f %f %f",
2059 &my_coeff[i][0], &my_coeff[i][1],
2060 &my_coeff[i][2], &my_coeff[i][3]);
2061 if (status < 3 || status > 4 ||
2062 (got_coeff > 0 && got_coeff != status)) {
2063 got_coeff = 0;
2064 break;
2066 if (got_coeff == 0)
2067 got_coeff = status;
2072 if (juice != 0.0) {
2073 if (got_coeff > 0) {
2074 if (verbose) {
2075 fprintf (stderr, "Color matrix with juice = %f:\n", juice);
2076 for (i=0; i < 3; i++)
2077 fprintf (stderr, " [%f %f %f %f]\n",
2078 my_coeff[i][0], my_coeff[i][1], my_coeff[i][2], my_coeff[i][3]);
2079 for (i=0; i < 3; i++)
2080 for (j=0; j < got_coeff; j++) {
2081 if (i == j || i == 1 && j == 3)
2082 coeff[i][j] = my_coeff[i][j] * juice + (1-juice);
2083 else
2084 coeff[i][j] = my_coeff[i][j] * juice;
2086 use_coeff = 1;
2092 void get_parameters()
2094 FILE *fp=NULL;
2095 char *fname, *cp;
2096 const char *default_file="default.prm", *prm_ext = ".prm";
2097 int len;
2099 fp = fopen (default_file, "r");
2100 if (fp) {
2101 get_parameter_value (fp);
2102 fclose (fp);
2105 fname = malloc (strlen(ifname) + 16);
2106 merror (fname, "get_parameters()");
2107 strcpy (fname, ifname);
2108 if ((cp = strrchr (fname, '.'))) *cp = 0;
2109 strcat (fname, prm_ext);
2110 fp = fopen (fname, "r");
2111 free (fname);
2112 if (!fp) return;
2114 get_parameter_value (fp);
2115 fclose (fp);
2118 void CLASS scale_colors()
2120 int row, col, c, val;
2121 int min[4], max[4], count[4];
2122 double sum[4], dmin, dmax;
2123 double *x_weights, *y_weights;
2125 int i;
2126 ushort *lut[4];
2127 ushort abs_max = 0;
2128 ushort abs_min = ABS_MAX;
2129 int clipped_pixels[4];
2130 int total_clipped_pixels = 0;
2131 int total_pixels = 0;
2132 int weighted_total_pixels = 0;
2133 double pixels[4];
2134 double white_fraction = 1.0 - white_point_fraction;
2135 double total = 0.0;
2136 double totals[4];
2137 double means[4];
2138 int mean;
2139 float compensation = exp2(exposure_compensation);
2140 double post_mul = 1.0;
2141 double auto_compensation = 1.0;
2142 int original_rgb_max;
2144 if (user_black >= 0)
2145 black = user_black;
2146 if (white_fraction > 1)
2147 white_fraction = 1;
2148 else if (white_fraction < 0)
2149 white_fraction = 0;
2150 if (use_neutral_wb) {
2151 for (c=0; c < 4; c++) {
2152 pre_mul[c] = 1.0;
2155 for (c = 0; c < 4; c++) {
2156 pixels[c] = 0;
2157 totals[c] = 0;
2158 clipped_pixels[c] = 0;
2160 memset (histogram, 0, sizeof histogram);
2161 for (c=0; c < 4; c++) {
2162 min[c] = INT_MAX;
2163 max[c] = count[c] = sum[c] = 0;
2165 if (center_weight) {
2166 x_weights = malloc(sizeof(double) * width);
2167 y_weights = malloc(sizeof(double) * height);
2168 for (row = 0; row < height; row++)
2169 y_weights[row]= exp(-pow(abs((row - (height / 2)) / (height / 4)), 3.0));
2170 for (col = 0; col < width; col++)
2171 x_weights[col] = exp(-pow(abs((col - (width / 2)) / (width / 4)), 3.0));
2173 for (row=0; row < height; row++) {
2174 for (col=0; col < width; col++) {
2175 for (c=0; c < colors; c++) {
2176 double weight = 1;
2177 val = image[row*width+col][c];
2178 if (!val) continue;
2179 if (use_camera_black && val < black)
2180 val = black;
2181 histogram[val >> 3]++;
2182 if (val >= rgb_max - 100) {
2183 clipped_pixels[c]++;
2184 total_clipped_pixels++;
2186 total += val;
2187 total_pixels++;
2188 if (center_weight) {
2189 double x_weight = x_weights[col];
2190 double y_weight = y_weights[row];
2191 weight = x_weight * y_weight;
2193 totals[c] += val * weight;
2194 pixels[c] += weight;
2195 weighted_total_pixels += weight;
2196 if (min[c] > val) min[c] = val;
2197 if (max[c] < val) max[c] = val;
2198 if (val < abs_min)
2199 abs_min = val;
2200 if (val > abs_max)
2201 abs_max = val;
2205 if (center_weight) {
2206 free(x_weights);
2207 free(y_weights);
2209 if (rgb_max < abs_max)
2210 rgb_max = abs_max;
2211 if (black > abs_min)
2212 black = abs_min;
2213 abs_max -= black;
2214 abs_min -= black;
2215 mean = (total / total_pixels) - black;
2216 for (c = 0; c < 4; c++) {
2217 means[c] = 0;
2218 max[c] -= black;
2219 min[c] -= black;
2221 for (c = 0; c < colors; c++)
2222 if (pixels[c])
2223 means[c] = (totals[c] / pixels[c]) - black;
2225 rgb_max -= black;
2226 if (use_auto_wb || (use_camera_wb && camera_red == -1)) {
2227 for (c=0; c < 4; c++) {
2228 min[c] = INT_MAX;
2229 max[c] = count[c] = sum[c] = 0;
2231 for (row=0; row < height; row++)
2232 for (col=0; col < width; col++)
2233 for (c=0; c < colors; c++) {
2234 val = image[row*width+col][c];
2235 if (!val) continue;
2236 if (use_camera_black && val < black)
2237 val = black;
2238 if (min[c] > val) min[c] = val;
2239 if (max[c] < val) max[c] = val;
2240 val -= black;
2241 if (val > rgb_max-100) continue;
2242 if (val < 0) val = 0;
2243 sum[c] += val;
2244 count[c]++;
2246 for (dmax=c=0; c < colors; c++) {
2247 sum[c] /= count[c];
2248 if (dmax < sum[c]) dmax = sum[c];
2250 for (c=0; c < colors; c++)
2251 pre_mul[c] = dmax / sum[c];
2253 if (use_camera_wb && camera_red != -1) {
2254 for (c=0; c < 4; c++)
2255 count[c] = sum[c] = 0;
2256 for (row=0; row < 8; row++)
2257 for (col=0; col < 8; col++) {
2258 c = FC(row,col);
2259 if ((val = white[row][col] - black) > 0)
2260 sum[c] += val;
2261 count[c]++;
2263 for (dmin=DBL_MAX, dmax=c=0; c < colors; c++) {
2264 sum[c] /= count[c];
2265 if (dmin > sum[c]) dmin = sum[c];
2266 if (dmax < sum[c]) dmax = sum[c];
2268 if (dmin > 0)
2269 for (c=0; c < colors; c++)
2270 pre_mul[c] = dmax / sum[c];
2271 else if (camera_red && camera_blue) {
2272 pre_mul[0] = camera_red;
2273 pre_mul[2] = camera_blue;
2274 pre_mul[1] = pre_mul[3] = 1.0;
2275 } else
2276 fprintf (stderr, "%s: Cannot use camera white balance.\n", ifname);
2279 total = 0;
2280 for (c = 0; c < colors; c++) {
2281 if (pixels[c] > 0)
2282 total += means[c] * pixels[c] / pre_mul[c];
2284 total /= weighted_total_pixels;
2286 if (!use_coeff) {
2287 pre_mul[0] *= red_scale;
2288 pre_mul[2] *= blue_scale;
2289 pre_mul[1] *= green_scale;
2290 pre_mul[3] *= green_scale;
2292 for (c = 0; c < 4; c++)
2293 pre_mul[c] *= compensation;
2295 if (autoexposure) {
2296 auto_compensation = .3 / ((double) total / (double) rgb_max);
2297 if (auto_compensation > 4.0) /* Don't overcompensate dark images */
2298 auto_compensation = 4.0 * sqrt(auto_compensation / 4.0);
2299 for (c = 0; c < 4; c++)
2300 pre_mul[c] *= auto_compensation;
2301 if ((auto_compensation * compensation) > 1 && !use_pivot)
2302 pivot_value /= (auto_compensation * compensation);
2303 use_pivot = 1;
2305 if (pivot_value > 1)
2306 use_pivot = 0;
2308 for (c=0; c < 4; c++) {
2309 if (pre_mul[c] < post_mul) {
2310 post_mul = pre_mul[c];
2313 for (c=0; c < 4; c++) {
2314 pre_mul[c] /= post_mul;
2317 for (c = 0; c < 4; c++)
2318 lut[c] = NULL;
2319 if (use_pivot) {
2320 for (c=0; c < c; c++) {
2321 if (pre_mul[c] > 1.0) {
2322 double k = pre_mul[c];
2323 double rescale = 1.0 - (clipped_pixels[c] / pixels[c]);
2324 double start = pivot_value * rescale * rescale;
2325 double start_1 = 1 - start;
2326 double x_start = start / k;
2327 double x_start_1 = 1 - x_start;
2328 double end_slope = alternate_scale ? 1.0 / (3 * k) : 0;
2329 double end_intercept = 1.0 - end_slope;
2330 double end_start = end_intercept + x_start * end_slope;
2331 double end_start_1 = 1.0 - end_start;
2332 double diff = start_1 - end_start_1;
2333 double scale = 1 / x_start_1;
2335 * Choose the exponent so that at 1.0 the first derivative
2336 * of the curve is pre_mul[c].
2338 double expt = ((k - end_slope) * x_start_1 / diff);
2339 if (verbose) {
2340 fprintf(stderr, "Pivot channel %d: k %f start %f x_start %f x_start_1 %f expt %f scale %f end_slope %f end_intercept %f end_start %f end_start_1 %f diff %f\n",
2341 c, k, start, x_start, x_start_1, expt, scale,
2342 end_slope, end_intercept, end_start, end_start_1, diff);
2344 lut[c] = malloc (sizeof(ushort) * 65536);
2345 k = k * RGB_MAX / rgb_max;
2346 for (i = 0; i <= rgb_max; i++) {
2347 double base = i / (double) rgb_max;
2348 if (base <= x_start) {
2349 lut[c][i] = k * i;
2350 } else if (base > rgb_max) {
2351 lut[c][i] = RGB_MAX;
2352 } else {
2354 * Roundoff error may result in this going slightly negative.
2355 * That's bad juju.
2357 double x_base = 1 - ((base - x_start) * scale);
2358 if (x_base < 0)
2359 x_base = 0;
2360 lut[c][i] =
2361 (RGB_MAX *
2362 (end_intercept + (base * end_slope) -
2363 (diff * pow(x_base, expt))));
2369 for (c = 0; c < colors; c++)
2370 pre_mul[c] = pre_mul[c] * RGB_MAX / rgb_max;
2371 original_rgb_max = rgb_max;
2372 rgb_max = RGB_MAX;
2373 if (verbose) {
2374 fprintf (stderr, "Scaling with black=%d, pre_mul[] =", black);
2375 for (c=0; c < colors; c++)
2376 fprintf (stderr, " %f", pre_mul[c]);
2377 fputc ('\n', stderr);
2378 fprintf (stderr, "Maximum level %d (%d, %.2f%%)\n", abs_max,
2379 abs_max * 65536 / original_rgb_max,
2380 100.0 * abs_max / original_rgb_max);
2381 fprintf (stderr, "Minimum level %d (%d, %.2f%%)\n", abs_min,
2382 abs_min * 65536 / original_rgb_max,
2383 100.0 * abs_min / original_rgb_max);
2384 fprintf (stderr, "Mean level %d (%d, %.2f%%)\n", mean,
2385 mean * 65536 / original_rgb_max,
2386 100.0 * mean / original_rgb_max);
2387 fprintf (stderr, "Weighted mean level %f (%f, %.2f%%)\n", total,
2388 total * 65536 / original_rgb_max,
2389 100.0 * total / original_rgb_max);
2390 for (c = 0; c < colors; c++)
2391 if (pixels[c] > 0)
2392 fprintf (stderr, "Mean[%d] level %f (%f, %.2f%%) %.2f pixels\n",
2393 c, means[c], means[c] * 65536 / original_rgb_max,
2394 100.0 * means[c] / original_rgb_max, pixels[c]);
2395 for (c = 0; c < colors; c++)
2396 if (pixels[c] > 0)
2397 fprintf (stderr, "Max[%d] level %d (%d, %.2f%%) %.2f pixels\n",
2398 c, max[c], max[c] * 65536 / original_rgb_max,
2399 100.0 * (double) max[c] / original_rgb_max, pixels[c]);
2400 fprintf (stderr, "Auto exposure compensation %f (%f stops)\n",
2401 auto_compensation,
2402 log(auto_compensation) / log(2));
2403 fprintf (stderr, "Manual exposure compensation %f (%f stops)\n",
2404 compensation, exposure_compensation);
2405 fprintf (stderr, "Total exposure compensation %f (%f stops)\n",
2406 auto_compensation * compensation,
2407 log(auto_compensation * compensation) / log(2));
2408 fprintf (stderr, "Post multiplier %f (%f stops)\n",
2409 post_mul, log(post_mul) / log(2));
2410 fprintf (stderr, "Clipped pixels: %d/%d, %.2f%%\n",
2411 total_clipped_pixels, total_pixels,
2412 (double) total_clipped_pixels / total_pixels * 100);
2413 for (c = 0; c < colors; c++)
2414 if (pixels[c] > 0)
2415 fprintf(stderr, "Clipped[%d] %d (%.2f%%)\n", c, clipped_pixels[c],
2416 100.0 * clipped_pixels[c] / pixels[c]);
2418 for (row=0; row < height; row++)
2419 for (col=0; col < width; col++)
2420 for (c=0; c < colors; c++) {
2421 val = image[row*width+col][c];
2422 if (!val) continue;
2423 if (use_camera_black && val < black)
2424 val = black;
2425 val -= black;
2426 if (lut[c])
2427 val = lut[c][val];
2428 else
2429 val *= pre_mul[c];
2430 if (val < 0) val = 0;
2431 if (val > rgb_max) val = rgb_max;
2432 val *= post_mul;
2433 image[row*width+col][c] = val;
2435 for (c = 0; c < colors; c++) {
2436 if (lut[c])
2437 free(lut[c]);
2442 This algorithm is officially called:
2444 "Interpolation using a Threshold-based variable number of gradients"
2446 described in http://www-ise.stanford.edu/~tingchen/algodep/vargra.html
2448 I've extended the basic idea to work with non-Bayer filter arrays.
2449 Gradients are numbered clockwise from NW=0 to W=7.
2451 void CLASS vng_interpolate()
2453 static const signed char *cp, terms[] = {
2454 -2,-2,+0,-1,0,0x01, -2,-2,+0,+0,1,0x01, -2,-1,-1,+0,0,0x01,
2455 -2,-1,+0,-1,0,0x02, -2,-1,+0,+0,0,0x03, -2,-1,+0,+1,1,0x01,
2456 -2,+0,+0,-1,0,0x06, -2,+0,+0,+0,1,0x02, -2,+0,+0,+1,0,0x03,
2457 -2,+1,-1,+0,0,0x04, -2,+1,+0,-1,1,0x04, -2,+1,+0,+0,0,0x06,
2458 -2,+1,+0,+1,0,0x02, -2,+2,+0,+0,1,0x04, -2,+2,+0,+1,0,0x04,
2459 -1,-2,-1,+0,0,0x80, -1,-2,+0,-1,0,0x01, -1,-2,+1,-1,0,0x01,
2460 -1,-2,+1,+0,1,0x01, -1,-1,-1,+1,0,0x88, -1,-1,+1,-2,0,0x40,
2461 -1,-1,+1,-1,0,0x22, -1,-1,+1,+0,0,0x33, -1,-1,+1,+1,1,0x11,
2462 -1,+0,-1,+2,0,0x08, -1,+0,+0,-1,0,0x44, -1,+0,+0,+1,0,0x11,
2463 -1,+0,+1,-2,1,0x40, -1,+0,+1,-1,0,0x66, -1,+0,+1,+0,1,0x22,
2464 -1,+0,+1,+1,0,0x33, -1,+0,+1,+2,1,0x10, -1,+1,+1,-1,1,0x44,
2465 -1,+1,+1,+0,0,0x66, -1,+1,+1,+1,0,0x22, -1,+1,+1,+2,0,0x10,
2466 -1,+2,+0,+1,0,0x04, -1,+2,+1,+0,1,0x04, -1,+2,+1,+1,0,0x04,
2467 +0,-2,+0,+0,1,0x80, +0,-1,+0,+1,1,0x88, +0,-1,+1,-2,0,0x40,
2468 +0,-1,+1,+0,0,0x11, +0,-1,+2,-2,0,0x40, +0,-1,+2,-1,0,0x20,
2469 +0,-1,+2,+0,0,0x30, +0,-1,+2,+1,1,0x10, +0,+0,+0,+2,1,0x08,
2470 +0,+0,+2,-2,1,0x40, +0,+0,+2,-1,0,0x60, +0,+0,+2,+0,1,0x20,
2471 +0,+0,+2,+1,0,0x30, +0,+0,+2,+2,1,0x10, +0,+1,+1,+0,0,0x44,
2472 +0,+1,+1,+2,0,0x10, +0,+1,+2,-1,1,0x40, +0,+1,+2,+0,0,0x60,
2473 +0,+1,+2,+1,0,0x20, +0,+1,+2,+2,0,0x10, +1,-2,+1,+0,0,0x80,
2474 +1,-1,+1,+1,0,0x88, +1,+0,+1,+2,0,0x08, +1,+0,+2,-1,0,0x40,
2475 +1,+0,+2,+1,0,0x10
2476 }, chood[] = { -1,-1, -1,0, -1,+1, 0,+1, +1,+1, +1,0, +1,-1, 0,-1 };
2477 ushort (*brow[5])[4], *pix;
2478 int code[8][2][320], *ip, gval[8], gmin, gmax, sum[4];
2479 int row, col, shift, x, y, x1, x2, y1, y2, t, weight, grads, color, diag;
2480 int g, diff, thold, num, c;
2482 for (row=0; row < 8; row++) { /* Precalculate for bilinear */
2483 for (col=1; col < 3; col++) {
2484 ip = code[row][col & 1];
2485 memset (sum, 0, sizeof sum);
2486 for (y=-1; y <= 1; y++)
2487 for (x=-1; x <= 1; x++) {
2488 shift = (y==0) + (x==0);
2489 if (shift == 2) continue;
2490 color = FC(row+y,col+x);
2491 *ip++ = (width*y + x)*4 + color;
2492 *ip++ = shift;
2493 *ip++ = color;
2494 sum[color] += 1 << shift;
2496 for (c=0; c < colors; c++)
2497 if (c != FC(row,col)) {
2498 *ip++ = c;
2499 *ip++ = sum[c];
2507 for (row=1; row < height-1; row++)
2508 { /* Do bilinear interpolation */
2509 for (col=1; col < width-1; col++)
2511 pix = image[row*width+col];
2512 ip = code[row & 7][col & 1];
2513 memset (sum, 0, sizeof sum);
2515 for (g=8; g--; )
2517 diff = pix[*ip++];
2518 diff <<= *ip++;
2519 sum[*ip++] += diff;
2522 for (g=colors; --g; )
2524 c = *ip++;
2525 pix[c] = sum[c] / *ip++;
2533 if (quick_interpolate)
2534 return;
2538 for (row=0; row < 8; row++)
2539 { /* Precalculate for VNG */
2540 for (col=0; col < 2; col++)
2542 ip = code[row][col];
2543 for (cp=terms, t=0; t < 64; t++)
2545 y1 = *cp++; x1 = *cp++;
2546 y2 = *cp++; x2 = *cp++;
2547 weight = *cp++;
2548 grads = *cp++;
2549 color = FC(row+y1,col+x1);
2550 if (FC(row+y2,col+x2) != color) continue;
2551 diag = (FC(row,col+1) == color && FC(row+1,col) == color) ? 2:1;
2552 if (abs(y1-y2) == diag && abs(x1-x2) == diag) continue;
2553 *ip++ = (y1*width + x1)*4 + color;
2554 *ip++ = (y2*width + x2)*4 + color;
2555 *ip++ = weight;
2556 for (g=0; g < 8; g++)
2557 if (grads & 1<<g) *ip++ = g;
2558 *ip++ = -1;
2560 *ip++ = INT_MAX;
2561 for (cp=chood, g=0; g < 8; g++) {
2562 y = *cp++; x = *cp++;
2563 *ip++ = (y*width + x) * 4;
2564 color = FC(row,col);
2565 if (FC(row+y,col+x) != color && FC(row+y*2,col+x*2) == color)
2566 *ip++ = (y*width + x) * 8 + color;
2567 else
2568 *ip++ = 0;
2576 brow[4] = calloc (width*3, sizeof **brow);
2577 merror (brow[4], "vng_interpolate()");
2578 for (row=0; row < 3; row++)
2579 brow[row] = brow[4] + row*width;
2581 /* Do VNG interpolation */
2582 for (row=2; row < height-2; row++)
2589 for (col=2; col < width-2; col++)
2593 pix = image[row*width+col];
2594 ip = code[row & 7][col & 1];
2595 memset (gval, 0, sizeof gval);
2598 /* Calculate gradients */
2599 while ((g = ip[0]) != INT_MAX)
2601 num = (diff = pix[g] - pix[ip[1]]) >> 31;
2602 gval[ip[3]] += (diff = ((diff ^ num) - num) << ip[2]);
2603 ip += 5;
2604 if ((g = ip[-1]) == -1) continue;
2605 gval[g] += diff;
2606 while ((g = *ip++) != -1)
2607 gval[g] += diff;
2609 ip++;
2613 gmin = gmax = gval[0]; /* Choose a threshold */
2614 for (g=1; g < 8; g++)
2616 if (gmin > gval[g]) gmin = gval[g];
2617 if (gmax < gval[g]) gmax = gval[g];
2623 if (gmax == 0)
2625 memcpy (brow[2][col], pix, sizeof *image);
2626 continue;
2633 thold = (k1-k2)*gmin + k2*gmax;
2634 memset (sum, 0, sizeof sum);
2635 color = FC(row,col);
2639 for (num=g=0; g < 8; g++,ip+=2)
2640 { /* Average the neighbors */
2641 if (gval[g] <= thold)
2643 for (c=0; c < colors; c++)
2644 if (c == color && ip[1])
2645 sum[c] += (pix[c] + pix[ip[1]]) >> 1;
2646 else
2647 sum[c] += pix[ip[0] + c];
2648 num++;
2658 for (c=0; c < colors; c++)
2659 { /* Save to buffer */
2660 t = pix[color];
2661 if (c != color)
2663 t += (sum[c] - sum[color])/num;
2664 if (t < 0) t = 0;
2665 if (t > rgb_max) t = rgb_max;
2667 brow[2][col][c] = t;
2682 if (row > 3) /* Write buffer to image */
2683 memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image);
2684 for (g=0; g < 4; g++)
2685 brow[(g-1) & 3] = brow[g];
2695 memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image);
2696 memcpy (image[(row-1)*width+2], brow[1]+2, (width-4)*sizeof *image);
2697 free(brow[4]);
2701 Interpolation for 1/16 thumbnail file. Just take an average of the
2702 unit pixels.
2704 void thm_interpolate()
2706 int row, col, x, y, c;
2707 int sum[4];
2709 for (row=0; row < height; row += 4) {
2710 for (col=0; col < width; col += 4) {
2711 memset (sum, 0, sizeof sum);
2712 for (y=0; y < 4; y++){
2713 for (x=0; x< 4; x++){
2714 sum[0] += (image[(row+y)*width+(col+x)][0] >> 2);
2715 sum[1] += (image[(row+y)*width+(col+x)][1] >> 3);
2716 sum[2] += (image[(row+y)*width+(col+x)][2] >> 2);
2719 for (c=0; c < 3; c++)
2720 image[row*width+col][c] = sum[c];
2726 void CLASS tiff_parse_subifd (int base)
2728 int entries, tag, type, len, val, save;
2730 entries = fget2(ifp);
2731 while (entries--) {
2732 tag = fget2(ifp);
2733 type = fget2(ifp);
2734 len = fget4(ifp);
2735 if (type == 3 && len < 3) {
2736 val = fget2(ifp); fget2(ifp);
2737 } else
2738 val = fget4(ifp);
2739 switch (tag) {
2740 case 0x100: /* ImageWidth */
2741 raw_width = val;
2742 break;
2743 case 0x101: /* ImageHeight */
2744 raw_height = val;
2745 break;
2746 case 0x102: /* Bits per sample */
2747 break;
2748 case 0x103: /* Compression */
2749 tiff_data_compression = val;
2750 break;
2751 case 0x106: /* Kodak color format */
2752 kodak_data_compression = val;
2753 break;
2754 case 0x111: /* StripOffset */
2755 if (len == 1)
2756 data_offset = val;
2757 else {
2758 save = ftell(ifp);
2759 fseek (ifp, val+base, SEEK_SET);
2760 data_offset = fget4(ifp);
2761 fseek (ifp, save, SEEK_SET);
2763 break;
2764 case 0x115: /* SamplesPerRow */
2765 break;
2766 case 0x116: /* RowsPerStrip */
2767 break;
2768 case 0x117: /* StripByteCounts */
2769 break;
2770 case 0x123:
2771 curve_offset = val;
2772 curve_length = len;
2777 void CLASS nef_parse_makernote()
2779 int base=0, offset=0, entries, tag, type, len, val, save;
2780 short sorder;
2781 char buf[10];
2784 The MakerNote might have its own TIFF header (possibly with
2785 its own byte-order!), or it might just be a table.
2787 sorder = order;
2788 fread (buf, 1, 10, ifp);
2789 if (!strcmp (buf,"Nikon")) { /* starts with "Nikon\0\2\0\0\0" ? */
2790 base = ftell(ifp);
2791 order = fget2(ifp); /* might differ from file-wide byteorder */
2792 val = fget2(ifp); /* should be 42 decimal */
2793 offset = fget4(ifp);
2794 fseek (ifp, offset-8, SEEK_CUR);
2795 } else if (!strcmp (buf,"OLYMP"))
2796 fseek (ifp, -2, SEEK_CUR);
2797 else
2798 fseek (ifp, -10, SEEK_CUR);
2800 entries = fget2(ifp);
2801 while (entries--) {
2802 tag = fget2(ifp);
2803 type = fget2(ifp);
2804 len = fget4(ifp);
2805 if (type == 3) { /* short int */
2806 val = fget2(ifp); fget2(ifp);
2807 } else
2808 val = fget4(ifp);
2809 save = ftell(ifp);
2810 if (tag == 0xc) {
2811 fseek (ifp, base+val, SEEK_SET);
2812 camera_red = fget4(ifp);
2813 camera_red /= fget4(ifp);
2814 camera_blue = fget4(ifp);
2815 camera_blue/= fget4(ifp);
2817 if (tag == 0x8c)
2818 curve_offset = base+val + 2112;
2819 if (tag == 0x96)
2820 curve_offset = base+val + 2;
2821 if (tag == 0x97) {
2822 if (!strcmp(model,"NIKON D100 ")) {
2823 fseek (ifp, base+val + 72, SEEK_SET);
2824 camera_red = fget2(ifp) / 256.0;
2825 camera_blue = fget2(ifp) / 256.0;
2826 } else if (!strcmp(model,"NIKON D2H")) {
2827 fseek (ifp, base+val + 10, SEEK_SET);
2828 camera_red = fget2(ifp);
2829 camera_red /= fget2(ifp);
2830 camera_blue = fget2(ifp);
2831 camera_blue = fget2(ifp) / camera_blue;
2832 } else if (!strcmp(model,"NIKON D70")) {
2833 fseek (ifp, base+val + 20, SEEK_SET);
2834 camera_red = fget2(ifp);
2835 camera_red /= fget2(ifp);
2836 camera_blue = fget2(ifp);
2837 camera_blue/= fget2(ifp);
2840 if (tag == 0x1017) /* Olympus */
2841 camera_red = val / 256.0;
2842 if (tag == 0x1018)
2843 camera_blue = val / 256.0;
2844 fseek (ifp, save, SEEK_SET);
2846 order = sorder;
2850 Since the TIFF DateTime string has no timezone information,
2851 assume that the camera's clock was set to Universal Time.
2853 void CLASS get_timestamp()
2855 struct tm t;
2856 time_t ts;
2858 if (fscanf (ifp, "%d:%d:%d %d:%d:%d", &t.tm_year, &t.tm_mon,
2859 &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec) != 6)
2860 return;
2861 t.tm_year -= 1900;
2862 t.tm_mon -= 1;
2863 putenv ("TZ=UTC"); /* Remove this to assume local time */
2864 if ((ts = mktime(&t)) > 0)
2865 timestamp = ts;
2868 void CLASS nef_parse_exif (int base)
2870 int entries, tag, type, len, val, save;
2872 entries = fget2(ifp);
2873 while (entries--) {
2874 tag = fget2(ifp);
2875 type = fget2(ifp);
2876 len = fget4(ifp);
2877 val = fget4(ifp);
2878 save = ftell(ifp);
2879 fseek (ifp, val+base, SEEK_SET);
2880 if (tag == 0x9003 || tag == 0x9004)
2881 get_timestamp();
2882 if (tag == 0x927c &&
2883 (!strncmp(make,"NIKON",5) || !strncmp(make,"OLYMPUS",7)))
2884 nef_parse_makernote();
2885 fseek (ifp, save, SEEK_SET);
2890 Parse a TIFF file looking for camera model and decompress offsets.
2892 void CLASS parse_tiff (int base)
2894 int doff, entries, tag, type, len, val, save;
2895 char software[64];
2896 int wide=0, high=0, cr2_offset=0, offset=0;
2897 static const int flip_map[] = { 0,1,3,2,4,6,7,5 };
2899 fseek (ifp, base, SEEK_SET);
2900 order = fget2(ifp);
2901 val = fget2(ifp); /* Should be 42 for standard TIFF */
2902 while ((doff = fget4(ifp))) {
2903 fseek (ifp, doff+base, SEEK_SET);
2904 entries = fget2(ifp);
2905 while (entries--) {
2906 tag = fget2(ifp);
2907 type = fget2(ifp);
2908 len = fget4(ifp);
2909 if (type == 3 && len < 3) {
2910 val = fget2(ifp); fget2(ifp);
2911 } else
2912 val = fget4(ifp);
2913 save = ftell(ifp);
2914 fseek (ifp, val+base, SEEK_SET);
2917 //printf("%d %x\n", ftell(ifp), tag);
2919 switch (tag) {
2920 case 0x11:
2921 camera_red = val / 256.0;
2922 break;
2923 case 0x12:
2924 camera_blue = val / 256.0;
2925 break;
2926 case 0x100: /* ImageWidth */
2927 wide = val;
2928 break;
2929 case 0x101: /* ImageHeight */
2930 high = val;
2931 break;
2932 case 0x10f: /* Make tag */
2933 fgets (make, 64, ifp);
2934 break;
2935 case 0x110: /* Model tag */
2936 fgets (model, 64, ifp);
2937 break;
2938 case 0x111: /* StripOffset */
2939 cr2_offset = val;
2940 offset = fget4(ifp);
2941 break;
2942 case 0x112: /* Rotation */
2943 flip = flip_map[(val-1) & 7];
2944 break;
2945 case 0x123:
2946 curve_offset = val;
2947 curve_length = len;
2948 break;
2949 case 0x827d: /* Model2 tag */
2950 fgets (model2, 64, ifp);
2951 break;
2952 case 0x131: /* Software tag */
2953 fgets (software, 64, ifp);
2954 if (!strncmp(software,"Adobe",5))
2955 make[0] = 0;
2956 break;
2957 case 0x132: /* DateTime tag */
2958 get_timestamp();
2959 break;
2960 case 0x144:
2961 strcpy (make, "Leaf");
2962 raw_width = wide;
2963 raw_height = high;
2964 if (len > 1)
2965 data_offset = fget4(ifp);
2966 else
2967 data_offset = val;
2968 break;
2969 case 0x14a: /* SubIFD tag */
2970 if (len > 2 && !strcmp(make,"Kodak"))
2971 len = 2;
2972 if (len > 1)
2973 while (len--) {
2974 fseek (ifp, val+base, SEEK_SET);
2975 fseek (ifp, fget4(ifp)+base, SEEK_SET);
2976 tiff_parse_subifd(base);
2977 val += 4;
2979 else
2980 tiff_parse_subifd(base);
2981 break;
2982 case 0x8769: /* Nikon EXIF tag */
2983 nef_parse_exif(base);
2984 break;
2987 fseek (ifp, save, SEEK_SET);
2991 if (!strncmp(make,"OLYMPUS",7)) {
2992 make[7] = 0;
2993 raw_width = wide;
2994 raw_height = - (-high & -2);
2995 data_offset = offset;
2997 if (!strcmp(make,"Canon") && strcmp(model,"EOS D2000C"))
2998 data_offset = cr2_offset;
3000 if (make[0] == 0 && wide == 680 && high == 680) {
3001 strcpy (make, "Imacon");
3002 strcpy (model, "Ixpress");
3007 CIFF block 0x1030 contains an 8x8 white sample.
3008 Load this into white[][] for use in scale_colors().
3010 void CLASS ciff_block_1030()
3012 static const ushort key[] = { 0x410, 0x45f3 };
3013 int i, bpp, row, col, vbits=0;
3014 unsigned long bitbuf=0;
3016 fget2(ifp);
3017 if (fget4(ifp) != 0x80008) return;
3018 if (fget4(ifp) == 0) return;
3019 bpp = fget2(ifp);
3020 if (bpp != 10 && bpp != 12) return;
3021 for (i=row=0; row < 8; row++)
3022 for (col=0; col < 8; col++) {
3023 if (vbits < bpp) {
3024 bitbuf = bitbuf << 16 | (fget2(ifp) ^ key[i++ & 1]);
3025 vbits += 16;
3027 white[row][col] =
3028 bitbuf << (LONG_BIT - vbits) >> (LONG_BIT - bpp) << (14-bpp);
3029 vbits -= bpp;
3034 Parse the CIFF structure looking for two pieces of information:
3035 The camera model, and the decode table number.
3037 void CLASS parse_ciff (int offset, int length)
3039 int tboff, nrecs, i, type, len, roff, aoff, save, wbi=-1;
3040 static const int remap[] = { 1,2,3,4,5,1 };
3041 static const int remap_10d[] = { 0,1,3,4,5,6,0,0,2,8 };
3043 fseek (ifp, offset+length-4, SEEK_SET);
3044 tboff = fget4(ifp) + offset;
3045 fseek (ifp, tboff, SEEK_SET);
3046 nrecs = fget2(ifp);
3047 for (i = 0; i < nrecs; i++) {
3048 type = fget2(ifp);
3049 len = fget4(ifp);
3050 roff = fget4(ifp);
3051 aoff = offset + roff;
3052 save = ftell(ifp);
3053 if (type == 0x080a) { /* Get the camera make and model */
3054 fseek (ifp, aoff, SEEK_SET);
3055 fread (make, 64, 1, ifp);
3056 fseek (ifp, aoff+strlen(make)+1, SEEK_SET);
3057 fread (model, 64, 1, ifp);
3059 if (type == 0x102a) { /* Find the White Balance index */
3060 fseek (ifp, aoff+14, SEEK_SET); /* 0=auto, 1=daylight, 2=cloudy ... */
3061 wbi = fget2(ifp);
3062 if (((!strcmp(model,"Canon EOS DIGITAL REBEL") ||
3063 !strcmp(model,"Canon EOS 300D DIGITAL"))) && wbi == 6)
3064 wbi++;
3066 if (type == 0x102c) { /* Get white balance (G2) */
3067 if (!strcmp(model,"Canon PowerShot G1") ||
3068 !strcmp(model,"Canon PowerShot Pro90 IS")) {
3069 fseek (ifp, aoff+120, SEEK_SET);
3070 white[0][1] = fget2(ifp) << 4;
3071 white[0][0] = fget2(ifp) << 4;
3072 white[1][0] = fget2(ifp) << 4;
3073 white[1][1] = fget2(ifp) << 4;
3074 } else {
3075 fseek (ifp, aoff+100, SEEK_SET);
3076 if (wbi == 6 && fget4(ifp) == 0)
3077 wbi = 15;
3078 else {
3079 fseek (ifp, aoff+100, SEEK_SET);
3080 goto common;
3084 if (type == 0x0032) { /* Get white balance (D30 & G3) */
3085 if (!strcmp(model,"Canon EOS D30")) {
3086 fseek (ifp, aoff+72, SEEK_SET);
3087 common:
3088 camera_red = fget2(ifp);
3089 camera_red = fget2(ifp) / camera_red;
3090 camera_blue = fget2(ifp);
3091 camera_blue /= fget2(ifp);
3092 } else {
3093 fseek (ifp, aoff+80 + (wbi < 6 ? remap[wbi]*8 : 0), SEEK_SET);
3094 if (!camera_red)
3095 goto common;
3098 if (type == 0x10a9) { /* Get white balance (D60) */
3099 if (!strcmp(model,"Canon EOS 10D"))
3100 wbi = remap_10d[wbi];
3101 fseek (ifp, aoff+2 + wbi*8, SEEK_SET);
3102 camera_red = fget2(ifp);
3103 camera_red /= fget2(ifp);
3104 camera_blue = fget2(ifp);
3105 camera_blue = fget2(ifp) / camera_blue;
3107 if (type == 0x1030 && wbi > 14) { /* Get white sample */
3108 fseek (ifp, aoff, SEEK_SET);
3109 ciff_block_1030();
3111 if (type == 0x1031) { /* Get the raw width and height */
3112 fseek (ifp, aoff+2, SEEK_SET);
3113 raw_width = fget2(ifp);
3114 raw_height = fget2(ifp);
3116 if (type == 0x180e) { /* Get the timestamp */
3117 fseek (ifp, aoff, SEEK_SET);
3118 timestamp = fget4(ifp);
3120 if (type == 0x580e)
3121 timestamp = len;
3122 if (type == 0x1810) { /* Get the rotation */
3123 fseek (ifp, aoff+12, SEEK_SET);
3124 switch (fget4(ifp)) {
3125 case 270: flip = 5; break;
3126 case 180: flip = 3; break;
3127 case 90: flip = 6;
3130 if (type == 0x1835) { /* Get the decoder table */
3131 fseek (ifp, aoff, SEEK_SET);
3132 crw_init_tables (fget4(ifp));
3134 if (type >> 8 == 0x28 || type >> 8 == 0x30) /* Get sub-tables */
3135 parse_ciff(aoff, len);
3136 fseek (ifp, save, SEEK_SET);
3138 if (wbi == 0 && !strcmp(model,"Canon EOS D30"))
3139 camera_red = -1; /* Use my auto WB for this photo */
3142 void CLASS parse_rollei()
3144 char line[128], *val;
3145 int tx=0, ty=0;
3146 struct tm t;
3147 time_t ts;
3149 fseek (ifp, 0, SEEK_SET);
3150 do {
3151 fgets (line, 128, ifp);
3152 if ((val = strchr(line,'=')))
3153 *val++ = 0;
3154 else
3155 val = line + strlen(line);
3156 if (!strcmp(line,"DAT"))
3157 sscanf (val, "%d.%d.%d", &t.tm_mday, &t.tm_mon, &t.tm_year);
3158 if (!strcmp(line,"TIM"))
3159 sscanf (val, "%d:%d:%d", &t.tm_hour, &t.tm_min, &t.tm_sec);
3160 if (!strcmp(line,"HDR"))
3161 data_offset = atoi(val);
3162 if (!strcmp(line,"X "))
3163 raw_width = atoi(val);
3164 if (!strcmp(line,"Y "))
3165 raw_height = atoi(val);
3166 if (!strcmp(line,"TX "))
3167 tx = atoi(val);
3168 if (!strcmp(line,"TY "))
3169 ty = atoi(val);
3170 } while (strncmp(line,"EOHD",4));
3171 t.tm_year -= 1900;
3172 t.tm_mon -= 1;
3173 putenv ("TZ=");
3174 if ((ts = mktime(&t)) > 0)
3175 timestamp = ts;
3176 data_offset += tx * ty * 2;
3177 strcpy (make, "Rollei");
3178 strcpy (model, "d530flex");
3181 void CLASS parse_foveon()
3183 char *buf, *bp, *np;
3184 int off1, off2, len, i;
3186 order = 0x4949; /* Little-endian */
3187 fseek (ifp, -4, SEEK_END);
3188 off2 = fget4(ifp);
3189 fseek (ifp, off2, SEEK_SET);
3190 while (fget4(ifp) != 0x464d4143) /* Search for "CAMF" */
3191 if (feof(ifp)) return;
3192 off1 = fget4(ifp);
3193 fseek (ifp, off1+8, SEEK_SET);
3194 off1 += (fget4(ifp)+3) * 8;
3195 len = (off2 - off1)/2;
3196 fseek (ifp, off1, SEEK_SET);
3197 buf = malloc (len);
3198 merror (buf, "parse_foveon()");
3199 for (i=0; i < len; i++) /* Convert Unicode to ASCII */
3200 buf[i] = fget2(ifp);
3201 for (bp=buf; bp < buf+len; bp=np) {
3202 np = bp + strlen(bp) + 1;
3203 if (!strcmp(bp,"CAMMANUF"))
3204 strcpy (make, np);
3205 if (!strcmp(bp,"CAMMODEL"))
3206 strcpy (model, np);
3207 if (!strcmp(bp,"TIME"))
3208 timestamp = atoi(np);
3210 fseek (ifp, 248, SEEK_SET);
3211 raw_width = fget4(ifp);
3212 raw_height = fget4(ifp);
3213 free(buf);
3216 void CLASS foveon_coeff()
3218 static const float foveon[3][3] = {
3219 { 2.0343955, -0.727533, -0.3067457 },
3220 { -0.2287194, 1.231793, -0.0028293 },
3221 { -0.0086152, -0.153336, 1.1617814 }
3223 int i, j;
3225 for (i=0; i < 3; i++)
3226 for (j=0; j < 3; j++)
3227 coeff[i][j] = foveon[i][j] * pre_mul[i];
3228 use_coeff = 1;
3232 The grass is always greener in my PowerShot G2 when this
3233 function is called. Use at your own risk!
3235 void CLASS canon_rgb_coeff (float juice)
3237 static const float my_coeff[3][3] =
3238 { { 1.116187, -0.107427, -0.008760 },
3239 { -1.551374, 4.157144, -1.605770 },
3240 { 0.090939, -0.399727, 1.308788 } };
3241 int i, j;
3243 if (juice != 0) {
3244 for (i=0; i < 3; i++)
3245 for (j=0; j < 3; j++)
3246 coeff[i][j] = my_coeff[i][j] * juice + (i==j) * (1-juice);
3247 use_coeff = 1;
3251 void CLASS nikon_e950_coeff()
3253 int r, g;
3254 static const float my_coeff[3][4] =
3255 { { -1.936280, 1.800443, -1.448486, 2.584324 },
3256 { 1.405365, -0.524955, -0.289090, 0.408680 },
3257 { -1.204965, 1.082304, 2.941367, -1.818705 } };
3259 for (r=0; r < 3; r++)
3260 for (g=0; g < 4; g++)
3261 coeff[r][g] = my_coeff[r][g];
3262 use_coeff = 1;
3266 Given a matrix that converts RGB to GMCY, create a matrix to do
3267 the opposite. Only square matrices can be inverted, so I create
3268 four 3x3 matrices by omitting a different GMCY color in each one.
3269 The final coeff[][] matrix is the sum of these four.
3271 void CLASS gmcy_coeff()
3273 static const float gmcy[4][3] = {
3274 /* red green blue */
3275 { 0.11, 0.86, 0.08 }, /* green */
3276 { 0.50, 0.29, 0.51 }, /* magenta */
3277 { 0.11, 0.92, 0.75 }, /* cyan */
3278 { 0.81, 0.98, 0.08 } /* yellow */
3280 double invert[3][6], num;
3281 int ignore, i, j, k, r, g;
3283 memset (coeff, 0, sizeof coeff);
3284 for (ignore=0; ignore < 4; ignore++) {
3285 for (j=0; j < 3; j++) {
3286 g = (j < ignore) ? j : j+1;
3287 for (r=0; r < 3; r++) {
3288 invert[j][r] = gmcy[g][r]; /* 3x3 matrix to invert */
3289 invert[j][r+3] = (r == j); /* Identity matrix */
3292 for (j=0; j < 3; j++) {
3293 num = invert[j][j]; /* Normalize this row */
3294 for (i=0; i < 6; i++)
3295 invert[j][i] /= num;
3296 for (k=0; k < 3; k++) { /* Subtract it from the other rows */
3297 if (k==j) continue;
3298 num = invert[k][j];
3299 for (i=0; i < 6; i++)
3300 invert[k][i] -= invert[j][i] * num;
3303 for (j=0; j < 3; j++) { /* Add the result to coeff[][] */
3304 g = (j < ignore) ? j : j+1;
3305 for (r=0; r < 3; r++)
3306 coeff[r][g] += invert[r][j+3];
3309 for (r=0; r < 3; r++) { /* Normalize such that: */
3310 for (num=g=0; g < 4; g++) /* (1,1,1,1) x coeff = (1,1,1) */
3311 num += coeff[r][g];
3312 for (g=0; g < 4; g++)
3313 coeff[r][g] /= num;
3315 use_coeff = 1;
3319 Identify which camera created this file, and set global variables
3320 accordingly. Return nonzero if the file cannot be decoded.
3322 int CLASS identify()
3324 char head[32], *c;
3325 unsigned hlen, fsize, i;
3326 static const struct {
3327 int fsize;
3328 char make[12], model[16];
3329 } table[] = {
3330 { 62464, "Kodak", "DC20" },
3331 { 124928, "Kodak", "DC20" },
3332 { 2465792, "NIKON", "E950" },
3333 { 2940928, "NIKON", "E2100" },
3334 { 4771840, "NIKON", "E990" },
3335 { 5865472, "NIKON", "E4500" },
3336 { 5869568, "NIKON", "E4300" },
3337 { 787456, "Creative", "PC-CAM 600" },
3338 { 1976352, "Casio", "QV-2000UX" },
3339 { 3217760, "Casio", "QV-3*00EX" },
3340 { 6218368, "Casio", "QV-5700" },
3341 { 7684000, "Casio", "QV-4000" },
3342 { 9313536, "Casio", "EX-P600" },
3343 { 4841984, "Pentax", "Optio S" },
3344 { 6114240, "Pentax", "Optio S4" },
3345 { 12582980, "Sinar", "" } };
3346 static const char *corp[] =
3347 { "Canon", "NIKON", "Kodak", "PENTAX", "MINOLTA", "Minolta", "Konica" };
3349 /* What format is this file? Set make[] if we recognize it. */
3351 raw_height = raw_width = flip = 0;
3352 make[0] = model[0] = model2[0] = 0;
3353 memset (white, 0, sizeof white);
3354 camera_red = camera_blue = timestamp = 0;
3355 data_offset = curve_offset = tiff_data_compression = 0;
3356 zero_after_ff = 0;
3358 order = fget2(ifp);
3359 hlen = fget4(ifp);
3360 fseek (ifp, 0, SEEK_SET);
3361 fread (head, 1, 32, ifp);
3362 fseek (ifp, 0, SEEK_END);
3363 fsize = ftell(ifp);
3364 if ((c = memmem (head, 32, "MMMMRawT", 8))) {
3365 strcpy (make, "Phase One");
3366 data_offset = c - head;
3367 fseek (ifp, data_offset + 8, SEEK_SET);
3368 fseek (ifp, fget4(ifp) + 136, SEEK_CUR);
3369 raw_width = fget4(ifp);
3370 fseek (ifp, 12, SEEK_CUR);
3371 raw_height = fget4(ifp);
3372 } else if (order == 0x4949 || order == 0x4d4d) {
3373 if (!memcmp (head+6, "HEAPCCDR", 8)) {
3374 data_offset = hlen;
3375 parse_ciff (hlen, fsize - hlen);
3376 } else {
3377 parse_tiff(0);
3378 if (!strncmp(make,"NIKON",5) && raw_width == 0)
3379 make[0] = 0;
3381 } else if (!memcmp (head, "\0MRM", 4)) {
3382 parse_tiff(48);
3383 fseek (ifp, 4, SEEK_SET);
3384 data_offset = fget4(ifp) + 8;
3385 fseek (ifp, 24, SEEK_SET);
3386 raw_height = fget2(ifp);
3387 raw_width = fget2(ifp);
3388 fseek (ifp, 12, SEEK_SET); /* PRD */
3389 fseek (ifp, fget4(ifp) + 4, SEEK_CUR); /* TTW */
3390 fseek (ifp, fget4(ifp) + 12, SEEK_CUR); /* WBG */
3391 camera_red = fget2(ifp);
3392 camera_red /= fget2(ifp);
3393 camera_blue = fget2(ifp);
3394 camera_blue = fget2(ifp) / camera_blue;
3395 } else if (!memcmp (head, "\xff\xd8\xff\xe1", 4) &&
3396 !memcmp (head+6, "Exif", 4)) {
3397 fseek (ifp, 4, SEEK_SET);
3398 fseek (ifp, 4 + fget2(ifp), SEEK_SET);
3399 if (fgetc(ifp) != 0xff)
3400 parse_tiff(12);
3401 } else if (!memcmp (head, "BM", 2)) {
3402 data_offset = 0x1000;
3403 order = 0x4949;
3404 fseek (ifp, 38, SEEK_SET);
3405 if (fget4(ifp) == 2834 && fget4(ifp) == 2834) {
3406 strcpy (model, "BMQ");
3407 goto nucore;
3409 } else if (!memcmp (head, "BR", 2)) {
3410 strcpy (model, "RAW");
3411 nucore:
3412 strcpy (make, "Nucore");
3413 order = 0x4949;
3414 fseek (ifp, 10, SEEK_SET);
3415 data_offset += fget4(ifp);
3416 fget4(ifp);
3417 raw_width = fget4(ifp);
3418 raw_height = fget4(ifp);
3419 if (model[0] == 'B' && raw_width == 2597) {
3420 raw_width++;
3421 data_offset -= 0x1000;
3423 } else if (!memcmp (head+25, "ARECOYK", 7)) {
3424 strcpy (make, "CONTAX");
3425 strcpy (model, "N DIGITAL");
3426 } else if (!memcmp (head, "FUJIFILM", 8)) {
3427 fseek (ifp, 84, SEEK_SET);
3428 parse_tiff (fget4(ifp)+12);
3429 order = 0x4d4d;
3430 fseek (ifp, 100, SEEK_SET);
3431 data_offset = fget4(ifp);
3432 } else if (!memcmp (head, "DSC-Image", 9))
3433 parse_rollei();
3434 else if (!memcmp (head, "FOVb", 4))
3435 parse_foveon();
3436 else
3437 for (i=0; i < sizeof table / sizeof *table; i++)
3438 if (fsize == table[i].fsize) {
3439 strcpy (make, table[i].make );
3440 strcpy (model, table[i].model);
3443 for (i=0; i < sizeof corp / sizeof *corp; i++)
3444 if (strstr (make, corp[i])) /* Simplify company names */
3445 strcpy (make, corp[i]);
3446 if (!strncmp (make, "KODAK", 5))
3447 make[16] = model[16] = 0;
3448 c = make + strlen(make); /* Remove trailing spaces */
3449 while (*--c == ' ') *c = 0;
3450 c = model + strlen(model);
3451 while (*--c == ' ') *c = 0;
3452 i = strlen(make); /* Remove make from model */
3453 if (!strncmp (model, make, i++))
3454 memmove (model, model+i, 64-i);
3457 if (make[0] == 0) {
3458 // Cinelerra
3459 // fprintf (stderr, "%s: unsupported file format.\n", ifname);
3460 return 1;
3463 /* File format is OK. Do we support this camera? */
3464 /* Start with some useful defaults: */
3466 load_raw = NULL;
3467 height = raw_height;
3468 width = raw_width;
3469 top_margin = left_margin = 0;
3470 colors = 3;
3471 filters = 0x94949494;
3472 black = is_cmy = is_foveon = use_coeff = 0;
3473 pre_mul[0] = pre_mul[1] = pre_mul[2] = pre_mul[3] = 1;
3474 xmag = ymag = 1;
3475 rgb_max = 0x4000;
3477 /* We'll try to decode anything from Canon or Nikon. */
3479 if ((is_canon = !strcmp(make,"Canon"))) {
3480 canon_rgb_coeff (juice);
3481 if (memcmp (head+6, "HEAPCCDR", 8)) {
3482 filters = 0x61616161;
3483 load_raw = lossless_jpeg_load_raw;
3485 else
3486 if (raw_width)
3488 load_raw = canon_compressed_load_raw;
3491 if (!strcmp(make,"NIKON"))
3492 load_raw = nikon_is_compressed() ?
3493 nikon_compressed_load_raw : nikon_load_raw;
3495 if (!strcmp(model,"PowerShot 600")) {
3496 height = 613;
3497 width = 854;
3498 colors = 4;
3499 filters = 0xe1e4e1e4;
3500 load_raw = canon_600_load_raw;
3501 pre_mul[0] = 1.137;
3502 pre_mul[1] = 1.257;
3503 } else if (!strcmp(model,"PowerShot A5") ||
3504 !strcmp(model,"PowerShot A5 Zoom")) {
3505 height = 776;
3506 width = 960;
3507 raw_width = 992;
3508 colors = 4;
3509 filters = 0x1e4e1e4e;
3510 load_raw = canon_a5_load_raw;
3511 pre_mul[0] = 1.5842;
3512 pre_mul[1] = 1.2966;
3513 pre_mul[2] = 1.0419;
3514 } else if (!strcmp(model,"PowerShot A50")) {
3515 height = 968;
3516 width = 1290;
3517 raw_width = 1320;
3518 colors = 4;
3519 filters = 0x1b4e4b1e;
3520 load_raw = canon_a5_load_raw;
3521 pre_mul[0] = 1.750;
3522 pre_mul[1] = 1.381;
3523 pre_mul[3] = 1.182;
3524 } else if (!strcmp(model,"PowerShot Pro70")) {
3525 height = 1024;
3526 width = 1552;
3527 colors = 4;
3528 filters = 0x1e4b4e1b;
3529 load_raw = canon_a5_load_raw;
3530 pre_mul[0] = 1.389;
3531 pre_mul[1] = 1.343;
3532 pre_mul[3] = 1.034;
3533 } else if (!strcmp(model,"PowerShot Pro90 IS")) {
3534 width = 1896;
3535 colors = 4;
3536 filters = 0xb4b4b4b4;
3537 pre_mul[0] = 1.496;
3538 pre_mul[1] = 1.509;
3539 pre_mul[3] = 1.009;
3540 } else if (is_canon && raw_width == 2144) {
3541 height = 1550;
3542 width = 2088;
3543 top_margin = 8;
3544 left_margin = 4;
3545 if (!strcmp(model,"PowerShot G1")) {
3546 colors = 4;
3547 filters = 0xb4b4b4b4;
3548 pre_mul[0] = 1.446;
3549 pre_mul[1] = 1.405;
3550 pre_mul[2] = 1.016;
3551 } else {
3552 pre_mul[0] = 1.785;
3553 pre_mul[2] = 1.266;
3555 } else if (is_canon && raw_width == 2224) {
3556 height = 1448;
3557 width = 2176;
3558 top_margin = 6;
3559 left_margin = 48;
3560 pre_mul[0] = 1.592;
3561 pre_mul[2] = 1.261;
3562 } else if (is_canon && raw_width == 2376) {
3563 height = 1720;
3564 width = 2312;
3565 top_margin = 6;
3566 left_margin = 12;
3567 #ifdef CUSTOM
3568 if (write_fun == write_ppm) /* Pro users may not want my matrix */
3569 canon_rgb_coeff (0.1);
3570 #endif
3571 if (!strcmp(model,"PowerShot G2") ||
3572 !strcmp(model,"PowerShot S40")) {
3573 pre_mul[0] = 1.965;
3574 pre_mul[2] = 1.208;
3575 } else { /* G3 and S45 */
3576 pre_mul[0] = 1.855;
3577 pre_mul[2] = 1.339;
3579 } else if (is_canon && raw_width == 2672) {
3580 height = 1960;
3581 width = 2616;
3582 top_margin = 6;
3583 left_margin = 12;
3584 pre_mul[0] = 1.895;
3585 pre_mul[2] = 1.403;
3586 } else if (is_canon && raw_width == 3152) {
3587 height = 2056;
3588 width = 3088;
3589 top_margin = 12;
3590 left_margin = 64;
3591 pre_mul[0] = 2.242;
3592 pre_mul[2] = 1.245;
3593 if (!strcmp(model,"EOS Kiss Digital")) {
3594 pre_mul[0] = 1.882;
3595 pre_mul[2] = 1.094;
3597 rgb_max = 16000;
3598 } else if (is_canon && raw_width == 3160) {
3599 height = 2328;
3600 width = 3112;
3601 top_margin = 12;
3602 left_margin = 44;
3603 pre_mul[0] = 1.85;
3604 pre_mul[2] = 1.53;
3605 } else if (is_canon && raw_width == 3344) {
3606 height = 2472;
3607 width = 3288;
3608 top_margin = 6;
3609 left_margin = 4;
3610 pre_mul[0] = 1.621;
3611 pre_mul[2] = 1.528;
3612 } else if (!strcmp(model,"EOS-1D")) {
3613 height = 1662;
3614 width = 2496;
3615 data_offset = 288912;
3616 pre_mul[0] = 1.976;
3617 pre_mul[2] = 1.282;
3618 } else if (!strcmp(model,"EOS-1DS")) {
3619 height = 2718;
3620 width = 4082;
3621 data_offset = 289168;
3622 pre_mul[0] = 1.66;
3623 pre_mul[2] = 1.13;
3624 rgb_max = 14464;
3625 } else if (!strcmp(model,"EOS-1D Mark II") ||
3626 !strcmp(model,"EOS 20D")) {
3627 raw_height = 2360;
3628 raw_width = 3596;
3629 top_margin = 12;
3630 left_margin = 74;
3631 height = raw_height - top_margin;
3632 width = raw_width - left_margin;
3633 filters = 0x94949494;
3634 pre_mul[0] = 1.95;
3635 pre_mul[2] = 1.36;
3636 } else if (!strcmp(model,"EOS-1Ds Mark II")) {
3637 raw_height = 3349;
3638 raw_width = 5108;
3639 top_margin = 13;
3640 left_margin = 98;
3641 height = raw_height - top_margin;
3642 width = raw_width - left_margin;
3643 filters = 0x94949494;
3644 pre_mul[0] = 1.609;
3645 pre_mul[2] = 1.848;
3646 rgb_max = 0x3a00;
3647 } else if (!strcmp(model,"EOS D2000C")) {
3648 black = 800;
3649 pre_mul[2] = 1.25;
3650 } else if (!strcmp(model,"D1")) {
3651 filters = 0x16161616;
3652 pre_mul[0] = 0.838;
3653 pre_mul[2] = 1.095;
3654 } else if (!strcmp(model,"D1H")) {
3655 filters = 0x16161616;
3656 pre_mul[0] = 2.301;
3657 pre_mul[2] = 1.129;
3658 } else if (!strcmp(model,"D1X")) {
3659 width = 4024;
3660 filters = 0x16161616;
3661 ymag = 2;
3662 pre_mul[0] = 1.910;
3663 pre_mul[2] = 1.220;
3664 } else if (!strcmp(model,"D100")) {
3665 if (tiff_data_compression == 34713 && load_raw == nikon_load_raw)
3666 raw_width = (width += 3) + 3;
3667 filters = 0x61616161;
3668 pre_mul[0] = 2.374;
3669 pre_mul[2] = 1.677;
3670 rgb_max = 15632;
3671 } else if (!strcmp(model,"D2H")) {
3672 width = 2482;
3673 left_margin = 6;
3674 filters = 0x49494949;
3675 pre_mul[0] = 2.8;
3676 pre_mul[2] = 1.2;
3677 } else if (!strcmp(model,"D70")) {
3678 filters = 0x16161616;
3679 pre_mul[0] = 2.043;
3680 pre_mul[2] = 1.625;
3681 } else if (!strcmp(model,"E950")) {
3682 height = 1203;
3683 width = 1616;
3684 filters = 0x4b4b4b4b;
3685 colors = 4;
3686 load_raw = nikon_e950_load_raw;
3687 nikon_e950_coeff();
3688 pre_mul[0] = 1.18193;
3689 pre_mul[2] = 1.16452;
3690 pre_mul[3] = 1.17250;
3691 } else if (!strcmp(model,"E990")) {
3692 height = 1540;
3693 width = 2064;
3694 colors = 4;
3695 if (nikon_e990()) {
3696 filters = 0xb4b4b4b4;
3697 nikon_e950_coeff();
3698 pre_mul[0] = 1.196;
3699 pre_mul[1] = 1.246;
3700 pre_mul[2] = 1.018;
3701 } else {
3702 strcpy (model, "E995");
3703 filters = 0xe1e1e1e1;
3704 pre_mul[0] = 1.253;
3705 pre_mul[1] = 1.178;
3706 pre_mul[3] = 1.035;
3708 } else if (!strcmp(model,"E2100")) {
3709 width = 1616;
3710 if (nikon_e2100()) {
3711 height = 1206;
3712 load_raw = nikon_e2100_load_raw;
3713 pre_mul[0] = 1.945;
3714 pre_mul[2] = 1.040;
3715 } else {
3716 strcpy (model, "E2500");
3717 height = 1204;
3718 filters = 0x4b4b4b4b;
3719 goto coolpix;
3721 } else if (!strcmp(model,"E4300")) {
3722 height = 1710;
3723 width = 2288;
3724 filters = 0x16161616;
3725 if (minolta_z2()) {
3726 strcpy (make, "Minolta");
3727 strcpy (model, "DiMAGE Z2");
3728 load_raw = nikon_e2100_load_raw;
3730 } else if (!strcmp(model,"E4500")) {
3731 height = 1708;
3732 width = 2288;
3733 filters = 0xb4b4b4b4;
3734 goto coolpix;
3735 } else if (!strcmp(model,"E5000") || !strcmp(model,"E5700")) {
3736 filters = 0xb4b4b4b4;
3737 coolpix:
3738 colors = 4;
3739 pre_mul[0] = 1.300;
3740 pre_mul[1] = 1.300;
3741 pre_mul[3] = 1.148;
3742 } else if (!strcmp(model,"E5400")) {
3743 filters = 0x16161616;
3744 pre_mul[0] = 1.700;
3745 pre_mul[2] = 1.344;
3746 } else if (!strcmp(model,"E8700") ||
3747 !strcmp(model,"E8800")) {
3748 filters = 0x16161616;
3749 pre_mul[0] = 2.131;
3750 pre_mul[2] = 1.300;
3751 } else if (!strcmp(model,"FinePixS2Pro")) {
3752 height = 3584;
3753 width = 3583;
3754 filters = 0x61616161;
3755 load_raw = fuji_s2_load_raw;
3756 black = 512;
3757 pre_mul[0] = 1.424;
3758 pre_mul[2] = 1.718;
3759 } else if (!strcmp(model,"FinePix S5000")) {
3760 height = 2499;
3761 width = 2500;
3762 filters = 0x49494949;
3763 load_raw = fuji_s5000_load_raw;
3764 pre_mul[0] = 1.639;
3765 pre_mul[2] = 1.438;
3766 rgb_max = 0xf800;
3767 } else if (!strcmp(model,"FinePix S7000")) {
3768 pre_mul[0] = 1.62;
3769 pre_mul[2] = 1.38;
3770 goto fuji_s7000;
3771 } else if (!strcmp(model,"FinePix E550")) {
3772 pre_mul[0] = 1.45;
3773 pre_mul[2] = 1.25;
3774 fuji_s7000:
3775 height = 3587;
3776 width = 3588;
3777 filters = 0x49494949;
3778 load_raw = fuji_s7000_load_raw;
3779 rgb_max = 0xf800;
3780 } else if (!strcmp(model,"FinePix F700") ||
3781 !strcmp(model,"FinePix S20Pro")) {
3782 height = 2523;
3783 width = 2524;
3784 filters = 0x49494949;
3785 load_raw = fuji_f700_load_raw;
3786 pre_mul[0] = 1.639;
3787 pre_mul[2] = 1.438;
3788 rgb_max = 0x3e00;
3789 } else if (!strcmp(model,"Digital Camera KD-400Z")) {
3790 height = 1712;
3791 width = 2312;
3792 raw_width = 2336;
3793 data_offset = 4034;
3794 fseek (ifp, 2032, SEEK_SET);
3795 goto konica_400z;
3796 } else if (!strcmp(model,"Digital Camera KD-510Z")) {
3797 data_offset = 4032;
3798 fseek (ifp, 2032, SEEK_SET);
3799 goto konica_510z;
3800 } else if (!strcasecmp(make,"MINOLTA")) {
3801 load_raw = be_low_12_load_raw;
3802 rgb_max = 15860;
3803 if (!strncmp(model,"DiMAGE A",8)) {
3804 load_raw = packed_12_load_raw;
3805 rgb_max = model[8] == '1' ? 15916:16380;
3806 } else if (!strncmp(model,"DiMAGE G",8)) {
3807 if (model[8] == '4') {
3808 data_offset = 5056;
3809 fseek (ifp, 2078, SEEK_SET);
3810 height = 1716;
3811 width = 2304;
3812 } else if (model[8] == '5') {
3813 data_offset = 4016;
3814 fseek (ifp, 1936, SEEK_SET);
3815 konica_510z:
3816 height = 1956;
3817 width = 2607;
3818 raw_width = 2624;
3819 } else if (model[8] == '6') {
3820 data_offset = 4032;
3821 fseek (ifp, 2030, SEEK_SET);
3822 height = 2136;
3823 width = 2848;
3825 filters = 0x61616161;
3826 konica_400z:
3827 load_raw = be_low_10_load_raw;
3828 rgb_max = 15856;
3829 order = 0x4d4d;
3830 camera_red = fget2(ifp);
3831 camera_blue = fget2(ifp);
3832 camera_red /= fget2(ifp);
3833 camera_blue /= fget2(ifp);
3835 pre_mul[0] = 1.42;
3836 pre_mul[2] = 1.25;
3837 } else if (!strcmp(model,"*ist D")) {
3838 height = 2024;
3839 width = 3040;
3840 data_offset = 0x10000;
3841 load_raw = be_low_12_load_raw;
3842 pre_mul[0] = 1.76;
3843 pre_mul[1] = 1.07;
3844 } else if (!strcmp(model,"Optio S")) {
3845 height = 1544;
3846 width = 2068;
3847 raw_width = 3136;
3848 load_raw = packed_12_load_raw;
3849 pre_mul[0] = 1.506;
3850 pre_mul[2] = 1.152;
3851 } else if (!strcmp(model,"Optio S4")) {
3852 height = 1737;
3853 width = 2324;
3854 raw_width = 3520;
3855 load_raw = packed_12_load_raw;
3856 pre_mul[0] = 1.308;
3857 pre_mul[2] = 1.275;
3858 } else if (!strcmp(make,"Phase One")) {
3859 switch (raw_height) {
3860 case 2060:
3861 strcpy (model, "LightPhase");
3862 height = 2048;
3863 width = 3080;
3864 top_margin = 5;
3865 left_margin = 22;
3866 pre_mul[0] = 1.331;
3867 pre_mul[2] = 1.154;
3868 break;
3869 case 2682:
3870 strcpy (model, "H10");
3871 height = 2672;
3872 width = 4012;
3873 top_margin = 5;
3874 left_margin = 26;
3875 break;
3876 case 4128:
3877 strcpy (model, "H20");
3878 height = 4098;
3879 width = 4098;
3880 top_margin = 20;
3881 left_margin = 26;
3882 pre_mul[0] = 1.963;
3883 pre_mul[2] = 1.430;
3884 break;
3885 case 5488:
3886 strcpy (model, "H25");
3887 height = 5458;
3888 width = 4098;
3889 top_margin = 20;
3890 left_margin = 26;
3891 pre_mul[0] = 2.80;
3892 pre_mul[2] = 1.20;
3894 filters = top_margin & 1 ? 0x94949494 : 0x49494949;
3895 load_raw = phase_one_load_raw;
3896 rgb_max = 0xffff;
3897 } else if (!strcmp(model,"Ixpress")) {
3898 height = 4084;
3899 width = 4080;
3900 filters = 0x49494949;
3901 load_raw = ixpress_load_raw;
3902 pre_mul[0] = 1.963;
3903 pre_mul[2] = 1.430;
3904 rgb_max = 0xffff;
3905 } else if (!strcmp(make,"Sinar") && !memcmp(head,"8BPS",4)) {
3906 fseek (ifp, 14, SEEK_SET);
3907 height = fget4(ifp);
3908 width = fget4(ifp);
3909 filters = 0x61616161;
3910 data_offset = 68;
3911 load_raw = be_16_load_raw;
3912 rgb_max = 0xffff;
3913 } else if (!strcmp(make,"Leaf")) {
3914 if (height > width)
3915 filters = 0x16161616;
3916 load_raw = be_16_load_raw;
3917 pre_mul[0] = 1.1629;
3918 pre_mul[2] = 1.3556;
3919 rgb_max = 0xffff;
3920 } else if (!strcmp(model,"DIGILUX 2") || !strcmp(model,"DMC-LC1")) {
3921 height = 1928;
3922 width = 2568;
3923 data_offset = 1024;
3924 load_raw = le_high_12_load_raw;
3925 pre_mul[0] = 1.883;
3926 pre_mul[2] = 1.367;
3927 } else if (!strcmp(model,"E-1")) {
3928 filters = 0x61616161;
3929 load_raw = le_high_12_load_raw;
3930 pre_mul[0] = 1.57;
3931 pre_mul[2] = 1.48;
3932 } else if (!strcmp(model,"E-10")) {
3933 load_raw = be_high_12_load_raw;
3934 pre_mul[0] = 1.43;
3935 pre_mul[2] = 1.77;
3936 } else if (!strncmp(model,"E-20",4)) {
3937 load_raw = be_high_12_load_raw;
3938 black = 640;
3939 pre_mul[0] = 1.43;
3940 pre_mul[2] = 1.77;
3941 } else if (!strcmp(model,"C5050Z")) {
3942 filters = 0x16161616;
3943 load_raw = olympus_cseries_load_raw;
3944 pre_mul[0] = 1.533;
3945 pre_mul[2] = 1.880;
3946 } else if (!strcmp(model,"C5060WZ")) {
3947 load_raw = olympus_cseries_load_raw;
3948 pre_mul[0] = 2.285;
3949 pre_mul[2] = 1.023;
3950 } else if (!strcmp(model,"C8080WZ")) {
3951 filters = 0x16161616;
3952 load_raw = olympus_cseries_load_raw;
3953 pre_mul[0] = 2.335;
3954 pre_mul[2] = 1.323;
3955 } else if (!strcmp(model,"N DIGITAL")) {
3956 height = 2047;
3957 width = 3072;
3958 filters = 0x61616161;
3959 data_offset = 0x1a00;
3960 load_raw = packed_12_load_raw;
3961 pre_mul[0] = 1.366;
3962 pre_mul[2] = 1.251;
3963 } else if (!strcmp(model,"DSC-F828")) {
3964 height = 2460;
3965 width = 3288;
3966 raw_width = 3360;
3967 left_margin = 5;
3968 load_raw = sony_load_raw;
3969 sony_rgbe_coeff();
3970 filters = 0xb4b4b4b4;
3971 colors = 4;
3972 pre_mul[0] = 1.512;
3973 pre_mul[1] = 1.020;
3974 pre_mul[2] = 1.405;
3975 } else if (!strcasecmp(make,"KODAK")) {
3976 filters = 0x61616161;
3977 if (!strcmp(model,"NC2000F")) {
3978 width -= 4;
3979 left_margin = 1;
3980 curve_length = 176;
3981 pre_mul[0] = 1.509;
3982 pre_mul[2] = 2.686;
3983 } else if (!strcmp(model,"EOSDCS3B")) {
3984 width -= 4;
3985 left_margin = 2;
3986 pre_mul[0] = 1.629;
3987 pre_mul[2] = 2.767;
3988 } else if (!strcmp(model,"EOSDCS1")) {
3989 width -= 4;
3990 left_margin = 2;
3991 pre_mul[0] = 1.386;
3992 pre_mul[2] = 2.405;
3993 } else if (!strcmp(model,"DCS315C")) {
3994 black = 32;
3995 pre_mul[1] = 1.068;
3996 pre_mul[2] = 1.036;
3997 } else if (!strcmp(model,"DCS330C")) {
3998 black = 32;
3999 pre_mul[1] = 1.012;
4000 pre_mul[2] = 1.804;
4001 } else if (!strcmp(model,"DCS420")) {
4002 width -= 4;
4003 left_margin = 2;
4004 pre_mul[0] = 1.327;
4005 pre_mul[2] = 2.074;
4006 } else if (!strcmp(model,"DCS460")) {
4007 width -= 4;
4008 left_margin = 2;
4009 pre_mul[0] = 1.724;
4010 pre_mul[2] = 2.411;
4011 } else if (!strcmp(model,"DCS460A")) {
4012 width -= 4;
4013 left_margin = 2;
4014 colors = 1;
4015 filters = 0;
4016 } else if (!strcmp(model,"DCS520C")) {
4017 black = 720;
4018 pre_mul[0] = 1.006;
4019 pre_mul[2] = 1.858;
4020 } else if (!strcmp(model,"DCS560C")) {
4021 black = 750;
4022 pre_mul[1] = 1.053;
4023 pre_mul[2] = 1.703;
4024 } else if (!strcmp(model,"DCS620C")) {
4025 black = 720;
4026 pre_mul[1] = 1.002;
4027 pre_mul[2] = 1.818;
4028 } else if (!strcmp(model,"DCS620X")) {
4029 black = 740;
4030 pre_mul[0] = 1.486;
4031 pre_mul[2] = 1.280;
4032 is_cmy = 1;
4033 } else if (!strcmp(model,"DCS660C")) {
4034 black = 855;
4035 pre_mul[0] = 1.156;
4036 pre_mul[2] = 1.626;
4037 } else if (!strcmp(model,"DCS660M")) {
4038 black = 855;
4039 colors = 1;
4040 filters = 0;
4041 } else if (!strcmp(model,"DCS720X")) {
4042 pre_mul[0] = 1.35;
4043 pre_mul[2] = 1.18;
4044 is_cmy = 1;
4045 } else if (!strcmp(model,"DCS760C")) {
4046 pre_mul[0] = 1.06;
4047 pre_mul[2] = 1.72;
4048 } else if (!strcmp(model,"DCS760M")) {
4049 colors = 1;
4050 filters = 0;
4051 } else if (!strcmp(model,"ProBack")) {
4052 pre_mul[0] = 1.06;
4053 pre_mul[2] = 1.385;
4054 } else if (!strncmp(model2,"PB645C",6)) {
4055 pre_mul[0] = 1.0497;
4056 pre_mul[2] = 1.3306;
4057 } else if (!strncmp(model2,"PB645H",6)) {
4058 pre_mul[0] = 1.2010;
4059 pre_mul[2] = 1.5061;
4060 } else if (!strncmp(model2,"PB645M",6)) {
4061 pre_mul[0] = 1.01755;
4062 pre_mul[2] = 1.5424;
4063 } else if (!strcasecmp(model,"DCS Pro 14n")) {
4064 pre_mul[1] = 1.0323;
4065 pre_mul[2] = 1.258;
4066 } else if (!strcasecmp(model,"DCS Pro 14nx")) {
4067 pre_mul[0] = 1.336;
4068 pre_mul[2] = 1.3155;
4069 } else if (!strcasecmp(model,"DCS Pro SLR/c")) {
4070 pre_mul[0] = 1.425;
4071 pre_mul[2] = 1.293;
4072 } else if (!strcasecmp(model,"DCS Pro SLR/n")) {
4073 pre_mul[0] = 1.324;
4074 pre_mul[2] = 1.483;
4076 switch (tiff_data_compression) {
4077 case 0: /* No compression */
4078 case 1:
4079 load_raw = kodak_easy_load_raw;
4080 break;
4081 case 7: /* Lossless JPEG */
4082 load_raw = lossless_jpeg_load_raw;
4083 case 32867:
4084 break;
4085 case 65000: /* Kodak DCR compression */
4086 if (kodak_data_compression == 32803)
4087 load_raw = kodak_compressed_load_raw;
4088 else {
4089 load_raw = kodak_yuv_load_raw;
4090 height = (height+1) & -2;
4091 width = (width +1) & -2;
4092 filters = 0;
4094 break;
4095 default:
4096 fprintf (stderr, "%s: %s %s uses unsupported compression method %d.\n",
4097 ifname, make, model, tiff_data_compression);
4098 return 1;
4100 if (!strcmp(model,"DC20")) {
4101 height = 242;
4102 if (fsize < 100000) {
4103 width = 249;
4104 raw_width = 256;
4105 } else {
4106 width = 501;
4107 raw_width = 512;
4109 data_offset = raw_width + 1;
4110 colors = 4;
4111 filters = 0x8d8d8d8d;
4112 kodak_dc20_coeff (0.5);
4113 pre_mul[1] = 1.179;
4114 pre_mul[2] = 1.209;
4115 pre_mul[3] = 1.036;
4116 load_raw = kodak_easy_load_raw;
4117 } else if (strstr(model,"DC25")) {
4118 strcpy (model, "DC25");
4119 height = 242;
4120 if (fsize < 100000) {
4121 width = 249;
4122 raw_width = 256;
4123 data_offset = 15681;
4124 } else {
4125 width = 501;
4126 raw_width = 512;
4127 data_offset = 15937;
4129 colors = 4;
4130 filters = 0xb4b4b4b4;
4131 load_raw = kodak_easy_load_raw;
4132 } else if (!strcmp(model,"Digital Camera 40")) {
4133 strcpy (model, "DC40");
4134 height = 512;
4135 width = 768;
4136 data_offset = 1152;
4137 load_raw = kodak_radc_load_raw;
4138 } else if (strstr(model,"DC50")) {
4139 strcpy (model, "DC50");
4140 height = 512;
4141 width = 768;
4142 data_offset = 19712;
4143 load_raw = kodak_radc_load_raw;
4144 } else if (strstr(model,"DC120")) {
4145 strcpy (model, "DC120");
4146 height = 976;
4147 width = 848;
4148 if (tiff_data_compression == 7)
4149 load_raw = kodak_jpeg_load_raw;
4150 else
4151 load_raw = kodak_dc120_load_raw;
4153 } else if (!strcmp(make,"Rollei")) {
4154 switch (raw_width) {
4155 case 1316:
4156 height = 1030;
4157 width = 1300;
4158 top_margin = 1;
4159 left_margin = 6;
4160 break;
4161 case 2568:
4162 height = 1960;
4163 width = 2560;
4164 top_margin = 2;
4165 left_margin = 8;
4167 filters = 0x16161616;
4168 load_raw = rollei_load_raw;
4169 pre_mul[0] = 1.8;
4170 pre_mul[2] = 1.3;
4171 } else if (!strcmp(make,"SIGMA")) {
4172 switch (raw_height) {
4173 case 763: height = 756; top_margin = 2; break;
4174 case 1531: height = 1514; top_margin = 7; break;
4176 switch (raw_width) {
4177 case 1152: width = 1136; left_margin = 8; break;
4178 case 2304: width = 2271; left_margin = 17; break;
4180 if (height*2 < width) ymag = 2;
4181 filters = 0;
4182 load_raw = foveon_load_raw;
4183 is_foveon = 1;
4184 pre_mul[0] = 1.179;
4185 pre_mul[2] = 0.713;
4186 if (!strcmp(model,"SD10")) {
4187 pre_mul[0] *= 2.07;
4188 pre_mul[2] *= 2.30;
4190 foveon_coeff();
4191 rgb_max = 5600;
4192 } else if (!strcmp(model,"PC-CAM 600")) {
4193 height = 768;
4194 data_offset = width = 1024;
4195 filters = 0x49494949;
4196 load_raw = eight_bit_load_raw;
4197 pre_mul[0] = 1.14;
4198 pre_mul[2] = 2.73;
4199 } else if (!strcmp(model,"QV-2000UX")) {
4200 height = 1208;
4201 width = 1632;
4202 data_offset = width * 2;
4203 load_raw = eight_bit_load_raw;
4204 } else if (!strcmp(model,"QV-3*00EX")) {
4205 height = 1546;
4206 width = 2070;
4207 raw_width = 2080;
4208 load_raw = eight_bit_load_raw;
4209 } else if (!strcmp(model,"QV-4000")) {
4210 height = 1700;
4211 width = 2260;
4212 load_raw = be_high_12_load_raw;
4213 } else if (!strcmp(model,"QV-5700")) {
4214 height = 1924;
4215 width = 2576;
4216 load_raw = casio_qv5700_load_raw;
4217 } else if (!strcmp(model,"EX-P600")) {
4218 height = 2142;
4219 width = 2844;
4220 raw_width = 4288;
4221 load_raw = packed_12_load_raw;
4222 pre_mul[0] = 2.356;
4223 pre_mul[1] = 1.069;
4224 } else if (!strcmp(make,"Nucore")) {
4225 filters = 0x61616161;
4226 load_raw = nucore_load_raw;
4228 if (!load_raw || !height) {
4229 fprintf (stderr, "%s: %s %s is not yet supported.\n",
4230 ifname, make, model);
4231 return 1;
4233 #ifdef NO_JPEG
4234 if (load_raw == kodak_jpeg_load_raw) {
4235 fprintf (stderr, "%s: decoder was not linked with libjpeg.\n", ifname);
4236 return 1;
4238 #endif
4239 if (!raw_height) raw_height = height;
4240 if (!raw_width ) raw_width = width;
4241 if (colors == 4 && !use_coeff)
4242 gmcy_coeff();
4243 if (use_coeff) /* Apply user-selected color balance */
4244 for (i=0; i < colors; i++) {
4245 coeff[0][i] *= red_scale;
4246 coeff[2][i] *= blue_scale;
4247 coeff[1][i] *= green_scale;
4249 if (four_color_rgb && filters && colors == 3) {
4250 for (i=0; i < 32; i+=4) {
4251 if ((filters >> i & 15) == 9)
4252 filters |= 2 << i;
4253 if ((filters >> i & 15) == 6)
4254 filters |= 8 << i;
4256 colors++;
4257 pre_mul[3] = pre_mul[1];
4258 if (use_coeff)
4259 for (i=0; i < 3; i++)
4260 coeff[i][3] = coeff[i][1] /= 2;
4262 fseek (ifp, data_offset, SEEK_SET);
4265 // Cinelerra
4266 if (flip & 4)
4267 sprintf(dcraw_info, "%d %d", height, width);
4268 else
4269 sprintf(dcraw_info, "%d %d", width, height);
4275 return 0;
4279 Convert the entire image to RGB colorspace and build a histogram.
4281 void CLASS convert_to_rgb()
4283 int row, col, r, g, c=0;
4284 ushort *img;
4285 float rgb[3], mag;
4287 if (document_mode)
4288 colors = 1;
4289 memset (histogram, 0, sizeof histogram);
4290 for (row = trim; row < height-trim; row++)
4291 for (col = trim; col < width-trim; col++) {
4292 img = image[row*width+col];
4293 if (document_mode)
4294 c = FC(row,col);
4295 if (colors == 4 && !use_coeff) /* Recombine the greens */
4296 img[1] = (img[1] + img[3]) >> 1;
4297 if (colors == 1) /* RGB from grayscale */
4298 for (r=0; r < 3; r++)
4299 rgb[r] = img[c];
4300 else if (use_coeff) { /* RGB from GMCY or Foveon */
4301 for (r=0; r < 3; r++)
4302 for (rgb[r]=g=0; g < colors; g++)
4303 rgb[r] += img[g] * coeff[r][g];
4304 } else if (is_cmy) { /* RGB from CMY */
4305 rgb[0] = img[0] + img[1] - img[2];
4306 rgb[1] = img[1] + img[2] - img[0];
4307 rgb[2] = img[2] + img[0] - img[1];
4308 } else /* RGB from RGB (easy) */
4309 goto norgb;
4310 for (r=0; r < 3; r++) {
4311 if (rgb[r] < 0)
4312 rgb[r] = 0;
4313 if (rgb[r] > rgb_max)
4314 rgb[r] = rgb_max;
4315 img[r] = rgb[r];
4317 norgb:
4318 // Cinelerra
4319 // if (1 || write_fun == write_ppm) {
4320 if (write_fun == write_ppm) {
4321 for (mag=r=0; r < 3; r++)
4322 mag += (unsigned) img[r]*img[r];
4323 mag = sqrt(mag)/2;
4324 if (mag > 0xffff)
4325 mag = 0xffff;
4326 img[3] = mag;
4327 histogram[img[3] >> 3]++;
4332 #define FMIN(a, b) ((a) < (b) ? (a) : (b))
4334 static inline void calc_rgb_to_hsl(ushort *rgb, double *hue, double *sat,
4335 double *lightness)
4337 double red, green, blue;
4338 double h, s, l;
4339 double min, max;
4340 double delta;
4341 int maxval;
4343 red = rgb[0] / (double) rgb_max;
4344 green = rgb[1] / (double) rgb_max;
4345 blue = rgb[2] / (double) rgb_max;
4347 if (red > green) {
4348 if (red > blue) {
4349 max = red;
4350 maxval = 0;
4351 } else {
4352 max = blue;
4353 maxval = 2;
4355 min = FMIN(green, blue);
4356 } else {
4357 if (green > blue) {
4358 max = green;
4359 maxval = 1;
4360 } else {
4361 max = blue;
4362 maxval = 2;
4364 min = FMIN(red, blue);
4367 l = (max + min) / 2.0;
4368 delta = max - min;
4370 if (delta < .000001) { /* Suggested by Eugene Anikin <eugene@anikin.com> */
4371 s = 0.0;
4372 h = 0.0;
4373 } else {
4374 if (l <= .5)
4375 s = delta / (max + min);
4376 else
4377 s = delta / (2 - max - min);
4379 if (maxval == 0)
4380 h = (green - blue) / delta;
4381 else if (maxval == 1)
4382 h = 2 + (blue - red) / delta;
4383 else
4384 h = 4 + (red - green) / delta;
4386 if (h < 0.0)
4387 h += 6.0;
4388 else if (h > 6.0)
4389 h -= 6.0;
4392 *hue = h;
4393 *sat = s;
4394 *lightness = l;
4397 static inline double hsl_value(double n1, double n2, double hue)
4399 if (hue < 0)
4400 hue += 6.0;
4401 else if (hue > 6)
4402 hue -= 6.0;
4403 if (hue < 1.0)
4404 return (n1 + (n2 - n1) * hue);
4405 else if (hue < 3.0)
4406 return (n2);
4407 else if (hue < 4.0)
4408 return (n1 + (n2 - n1) * (4.0 - hue));
4409 else
4410 return (n1);
4413 static inline void calc_hsl_to_rgb(ushort *rgb, double h, double s, double l)
4415 if (s < .0000001) {
4416 if (l > 1)
4417 l = 1;
4418 else if (l < 0)
4419 l = 0;
4420 rgb[0] = l * (double) rgb_max;
4421 rgb[1] = l * (double) rgb_max;
4422 rgb[2] = l * (double) rgb_max;
4423 } else {
4424 double m1, m2;
4425 double h1, h2;
4426 h1 = h + 2;
4427 h2 = h - 2;
4429 if (l < .5)
4430 m2 = l * (1 + s);
4431 else
4432 m2 = l + s - (l * s);
4433 m1 = (l * 2) - m2;
4434 rgb[0] = (double) rgb_max * hsl_value(m1, m2, h1);
4435 rgb[1] = (double) rgb_max * hsl_value(m1, m2, h);
4436 rgb[2] = (double) rgb_max * hsl_value(m1, m2, h2);
4440 static inline double update_saturation(double sat, double adjust)
4442 if (adjust < 1)
4443 sat *= adjust;
4444 else if (adjust > 1) {
4445 double s1 = sat * adjust;
4446 double s2 = 1.0 - ((1.0 - sat) * (1.0 / adjust));
4447 sat = FMIN(s1, s2);
4449 if (sat > 1)
4450 sat = 1.0;
4451 return sat;
4454 static inline double update_contrast(double lum, double adjust)
4456 double retval = lum;
4457 if (lum >= .5)
4458 retval = 1.0 - lum;
4459 if (retval < .00001 && adjust < .0001)
4460 retval = .5;
4461 else
4462 retval = .5 - ((.5 - .5 * pow(2 * retval, adjust)));
4463 if (lum > .5)
4464 retval = 1 - retval;
4465 return retval;
4468 static inline void do_hsl_adjust(ushort *rgb)
4470 double h, s, l;
4471 if (saturation != 1.0 || contrast != 1.0) {
4472 calc_rgb_to_hsl(rgb, &h, &s, &l);
4473 if (saturation != 1.0)
4474 s = update_saturation(s, saturation);
4475 if (contrast != 1.0)
4476 l = update_contrast(l, contrast);
4477 calc_hsl_to_rgb(rgb, h, s, l);
4481 void CLASS flip_image()
4483 unsigned *flag;
4484 int size, base, dest, next, row, col, temp;
4485 INT64 *img, hold;
4487 img = (INT64 *) image;
4488 size = height * width;
4489 flag = calloc ((size+31) >> 5, sizeof *flag);
4490 merror (flag, "flip_image()");
4491 for (base = 0; base < size; base++) {
4492 if (flag[base >> 5] & (1 << (base & 31)))
4493 continue;
4494 dest = base;
4495 hold = img[base];
4496 while (1) {
4497 if (flip & 4) {
4498 row = dest % height;
4499 col = dest / height;
4500 } else {
4501 row = dest / width;
4502 col = dest % width;
4504 if (flip & 2)
4505 row = height - 1 - row;
4506 if (flip & 1)
4507 col = width - 1 - col;
4508 next = row * width + col;
4509 if (next == base) break;
4510 flag[next >> 5] |= 1 << (next & 31);
4511 img[dest] = img[next];
4512 dest = next;
4514 img[dest] = hold;
4516 free (flag);
4517 if (flip & 4) {
4518 temp = height;
4519 height = width;
4520 width = temp;
4521 temp = ymag;
4522 ymag = xmag;
4523 xmag = temp;
4528 Write the image to a 24-bpp PPM file.
4530 void CLASS write_ppm (FILE *ofp)
4532 int row, col, i, c, val, total;
4533 float max, mul, scale[0x10000];
4534 ushort *rgb;
4535 uchar (*ppm)[3];
4537 double white_fraction = 1.0 - white_point_fraction;
4539 if (white_fraction > 1)
4540 white_fraction = 1;
4541 else if (white_fraction < 0)
4542 white_fraction = 0;
4544 if (strcmp(make, "FUJIFILM") == 0)
4545 white_fraction /= 2;
4547 Set the white point to the 99th percentile
4549 i = width * height * white_fraction;
4550 for (val=0x2000, total=0; --val; )
4551 if ((total += histogram[val]) > i) break;
4552 max = val << 4;
4554 fprintf (ofp, "P6\n%d %d\n255\n",
4555 xmag*(width-trim*2), ymag*(height-trim*2));
4557 ppm = calloc (width-trim*2, 3*xmag);
4558 merror (ppm, "write_ppm()");
4559 mul = bright * 442 / max;
4560 scale[0] = 0;
4561 for (i=1; i < 0x10000; i++)
4562 scale[i] = mul * pow (i*2/max, gamma_val-1);
4564 for (row=trim; row < height-trim; row++) {
4565 for (col=trim; col < width-trim; col++) {
4566 rgb = image[row*width+col];
4567 do_hsl_adjust(rgb);
4568 for (c=0; c < 3; c++) {
4569 val = rgb[c] * scale[rgb[3]];
4570 if (val > 255) val=255;
4571 for (i=0; i < xmag; i++)
4572 ppm[xmag*(col-trim)+i][c] = val;
4575 for (i=0; i < ymag; i++)
4576 fwrite (ppm, width-trim*2, 3*xmag, ofp);
4578 free(ppm);
4582 Write the image to a 48-bpp Photoshop file.
4584 void CLASS write_psd16 (FILE *ofp)
4586 char head[] = {
4587 '8','B','P','S', /* signature */
4588 0,1,0,0,0,0,0,0, /* version and reserved */
4589 0,3, /* number of channels */
4590 0,0,0,0, /* height, big-endian */
4591 0,0,0,0, /* width, big-endian */
4592 0,16, /* 16-bit color */
4593 0,3, /* mode (1=grey, 3=rgb) */
4594 0,0,0,0, /* color mode data */
4595 0,0,0,0, /* image resources */
4596 0,0,0,0, /* layer/mask info */
4597 0,0 /* no compression */
4599 int hw[2], psize, row, col, c, val;
4600 ushort *buffer, *pred, *rgb;
4602 hw[0] = htonl(height-trim*2); /* write the header */
4603 hw[1] = htonl(width-trim*2);
4604 memcpy (head+14, hw, sizeof hw);
4605 fwrite (head, 40, 1, ofp);
4607 psize = (height-trim*2) * (width-trim*2);
4608 buffer = calloc (6, psize);
4609 merror (buffer, "write_psd()");
4610 pred = buffer;
4612 for (row = trim; row < height-trim; row++) {
4613 for (col = trim; col < width-trim; col++) {
4614 rgb = image[row*width+col];
4615 do_hsl_adjust(rgb);
4616 for (c=0; c < 3; c++) {
4617 val = rgb[c] * bright;
4618 if (val > 0xffff)
4619 val = 0xffff;
4620 pred[c*psize] = htons(val);
4622 pred++;
4625 fwrite(buffer, psize, 6, ofp);
4626 free(buffer);
4629 Write the image to a 48-bpp PPM file.
4631 void CLASS write_ppm16 (FILE *ofp)
4633 int row, col, c, val;
4634 ushort *rgb, (*ppm)[3];
4636 val = rgb_max * bright;
4637 if (val < 256)
4638 val = 256;
4639 if (val > 0xffff)
4640 val = 0xffff;
4641 fprintf (ofp, "P6\n%d %d\n%d\n",
4642 width-trim*2, height-trim*2, val);
4644 ppm = calloc (width-trim*2, 6);
4645 merror (ppm, "write_ppm16()");
4647 for (row = trim; row < height-trim; row++) {
4649 for (col = trim; col < width-trim; col++) {
4652 rgb = image[row*width+col];
4653 do_hsl_adjust(rgb);
4654 for (c=0; c < 3; c++) {
4655 val = rgb[c] * bright;
4656 if (val > 0xffff)
4657 val = 0xffff;
4658 ppm[col-trim][c] = htons(val);
4664 fwrite (ppm, width-trim*2, 6, ofp);
4666 free(ppm);
4675 // Cinelerra
4676 void CLASS write_cinelerra (FILE *ofp)
4678 int row, col, c, val;
4679 float *output;
4681 for (row = 0; row < height; row++)
4683 output = dcraw_data[row];
4684 for (col = 0; col < width; col++)
4686 ushort *pixel = image[row * width + col];
4687 for(c = 0; c < 3; c++)
4688 *output++ = (float)pixel[c] / 0xffff;
4689 if(dcraw_alpha) *output++ = 1.0;
4698 #if 0
4699 int row, col, i, c, total, j;
4700 float val;
4701 float max, mul, scale[0x10000];
4702 ushort *rgb;
4704 double white_fraction = 1.0 - white_point_fraction;
4706 if (white_fraction > 1)
4707 white_fraction = 1;
4708 else if (white_fraction < 0)
4709 white_fraction = 0;
4711 if (strcmp(make, "FUJIFILM") == 0)
4712 white_fraction /= 2;
4715 * Set the white point to the 99th percentile
4717 i = width * height * white_fraction;
4718 for (j=0x2000, total=0; --j; )
4720 if ((total += histogram[j]) > i) break;
4722 max = j << 4;
4724 mul = bright * 442 / max;
4725 scale[0] = 0;
4726 for (i=1; i < 0x10000; i++)
4728 scale[i] = mul * pow (i*2/max, gamma_val-1);
4731 for (row=trim; row < height-trim; row++)
4733 float *output = dcraw_data[row];
4734 for (col=trim; col < width-trim; col++)
4736 rgb = image[row*width+col];
4737 do_hsl_adjust(rgb);
4738 for (c=0; c < 3; c++)
4740 val = rgb[c] * scale[rgb[3]];
4741 *output++ = val / 255;
4743 if(dcraw_alpha) *output++ = 1.0;
4747 #endif
4759 void CLASS write_ppm_16_8(FILE *ofp)
4761 int row, col, c, i;
4762 float divisor;
4763 ushort *rgb;
4764 uchar (*ppm)[3];
4765 unsigned val;
4766 unsigned max = 0;
4768 val = (double) rgb_max * bright;
4769 if (val < 256)
4770 val = 256;
4771 if (val > 0xffff)
4772 val = 0xffff;
4773 divisor = 256 * ((double) val / 65536.0);
4774 fprintf (ofp, "P6\n%d %d\n255\n",
4775 width-trim*2, ymag*(height-trim*2));
4777 ppm = calloc (width-trim*2, 3);
4778 merror (ppm, "write_ppm16_8()");
4780 for (row = trim; row < height-trim; row++) {
4781 for (col = trim; col < width-trim; col++) {
4782 rgb = image[row*width+col];
4783 do_hsl_adjust(rgb);
4784 for (c=0; c < 3; c++) {
4785 if (rgb[c] > max)
4786 max = rgb[c];
4787 val = rgb[c] * bright / divisor;
4788 if (val > 0xff)
4789 val = 0xff;
4790 ppm[col-trim][c] = val;
4793 for (i=0; i < ymag; i++)
4794 fwrite (ppm, width-trim*2, 3, ofp);
4796 free(ppm);
4799 // Cinelerra
4800 int CLASS dcraw_main (int argc, char **argv)
4802 int arg, status=0, user_flip=-1;
4803 int identify_only=0, write_to_stdout=0, half_size=0;
4804 char opt, *ofname, *cp;
4805 const char *write_ext = ".ppm";
4806 FILE *ofp = stdout;
4809 if (argc == 1)
4811 fprintf (stderr,
4812 "\nRaw Photo Decoder \"dcraw\" v6.10"
4813 "\nby Dave Coffin, dcoffin a cybercom o net"
4814 "\n\nUsage: %s [options] file1 file2 ...\n"
4815 "\nValid options:"
4816 "\n-i Identify files but don't decode them"
4817 "\n-c Write to standard output"
4818 "\n-v Print verbose messages while decoding"
4819 "\n-f Interpolate RGBG as four colors"
4820 "\n-d Document Mode (no color, no interpolation)"
4821 "\n-q Quick, low-quality color interpolation"
4822 "\n-h Half-size color image (3x faster than -q)"
4823 "\n-s Use secondary pixels (Fuji Super CCD SR only)"
4824 "\n-g <num> Set gamma (0.6 by default, only for 24-bpp output)"
4825 "\n-b <num> Set brightness (1.0 by default)"
4826 "\n-a Use automatic white balance"
4827 "\n-w Use camera white balance, if possible"
4828 "\n-B <num> Use specified black level"
4829 "\n-L Use floating black level"
4830 "\n-n Use neutral (no correction) white balance"
4831 "\n-u Use auto exposure compensation"
4832 "\n-W Use center-weighted metering for exposure compensation"
4833 "\n-T Use alternate scaling to improve contrast in highlights"
4834 "\n-r <num> Set red multiplier (daylight = 1.0)"
4835 "\n-l <num> Set blue multiplier (daylight = 1.0)"
4836 "\n-t [0-7] Flip image (0 = none, 3 = 180, 5 = 90CCW, 6 = 90CW)"
4837 "\n-e <num> Set green multiplier (daylight = 1.0)"
4838 "\n-m <num> Set white point fraction (default 0.99)"
4839 "\n-p <num> Set white point correction start (default none)"
4840 "\n-P <num> Set relative white point correction start (default 0.75)"
4841 "\n-x <num> Set exposure compensation in stops (default 0.00)"
4842 "\n-S <num> Adjust saturation"
4843 "\n-C <num> Adjust contrast"
4844 "\n-k <num> Set interpolation threshold paramater k1\n\t for T = k1*Min + k2 * (Max - Min) (default = 1.5)"
4845 "\n-K <num> Set interpolation threshold paramater k2\n\t for T = k1*Min + k2 * (Max - Min) (default = 0.5)"
4846 "\n-j <num> Set parameter for color matrix"
4847 "\n-1 Write 24-bpp PPM using 16 bit calculation"
4848 "\n-2 Write 24-bpp PPM (default)"
4849 "\n-3 Write 48-bpp PSD (Adobe Photoshop)"
4850 "\n-4 Write 48-bpp PPM"
4851 "\n\n", argv[0]);
4852 return 1;
4855 argv[argc] = "";
4856 for (arg=1; argv[arg][0] == '-'; ) {
4857 opt = argv[arg++][1];
4858 if (strchr ("gbrlempPxSCB", opt) &&
4859 (!isdigit(argv[arg][0]) && argv[arg][0] != '.' &&
4860 (argv[arg][0] != '-' || (!isdigit(argv[arg][1]) &&
4861 argv[arg][1] != '.')))) {
4862 fprintf (stderr, "\"-%c\" requires a numeric argument.\n", opt);
4863 return 1;
4865 switch (opt)
4867 case 'g': gamma_val = atof(argv[arg++]); break;
4868 case 'b': bright = atof(argv[arg++]); break;
4869 case 'r': red_scale = atof(argv[arg++]); break;
4870 case 'l': blue_scale = atof(argv[arg++]); break;
4871 case 't': user_flip = atoi(argv[arg++]); break;
4872 case 'k': k1 = atof(argv[arg++]); break;
4873 case 'K': k2 = atof(argv[arg++]); break;
4874 case 'j': juice = atof(argv[arg++]); break;
4876 case 'e': green_scale = atof(argv[arg++]); break;
4877 case 'm': white_point_fraction = atof(argv[arg++]); break;
4878 case 'P': pivot_value = atof(argv[arg++]); white_point_fraction = 1; break;
4879 case 'p': pivot_value = atof(argv[arg++]); white_point_fraction = 1; use_pivot = 1; break;
4880 case 'x': exposure_compensation = atof(argv[arg++]); break;
4881 case 'S': saturation = atof(argv[arg++]); break;
4882 case 'C': contrast = atof(argv[arg++]); break;
4883 case 'n': use_neutral_wb = 1; break;
4884 case 'u': autoexposure = 1; break;
4885 case 'B': user_black = atoi(argv[arg++]); use_camera_black = 1; break;
4886 case 'L': use_camera_black = 0; break;
4887 case 'T': alternate_scale = 1; white_point_fraction = 1; break;
4889 case 'W': center_weight = 1; break;
4891 case 'i': identify_only = 1; break;
4892 case 'c': write_to_stdout = 1; break;
4893 case 'v': verbose = 1; break;
4894 case 'h': half_size = 1; /* "-h" implies "-f" */
4895 case 'f': four_color_rgb = 1; break;
4896 case 'd': document_mode = 1; break;
4897 case 'q': quick_interpolate = 1; break;
4898 case 'a': use_auto_wb = 1; break;
4899 case 'w': use_camera_wb = 1; break;
4900 case 's': use_secondary = 1; break;
4902 case '1': write_fun = write_ppm_16_8; write_ext = ".ppm"; break;
4903 case '2': write_fun = write_ppm; write_ext = ".ppm"; break;
4904 case '3': write_fun = write_psd16; write_ext = ".psd"; break;
4905 case '4': write_fun = write_ppm16; write_ext = ".ppm"; break;
4907 default:
4908 fprintf (stderr, "Unknown option \"-%c\".\n", opt);
4909 return 1;
4914 // Cinelerra
4915 write_fun = write_cinelerra;
4917 if (arg == argc) {
4918 fprintf (stderr, "No files to process.\n");
4919 return 1;
4921 if (write_to_stdout) {
4925 // Cinelerra
4926 if (0 /* isatty(1) */) {
4927 fprintf (stderr, "Will not write an image to the terminal!\n");
4928 return 1;
4934 #if defined(WIN32) || defined(DJGPP)
4935 if (setmode(1,O_BINARY) < 0) {
4936 perror("setmode()");
4937 return 1;
4939 #endif
4942 for ( ; arg < argc; arg++)
4944 status = 1;
4945 image = NULL;
4946 if (setjmp (failure)) {
4947 if (fileno(ifp) > 2) fclose(ifp);
4948 if (fileno(ofp) > 2) fclose(ofp);
4949 if (image) free(image);
4950 status = 1;
4951 continue;
4953 ifname = argv[arg];
4954 if (!(ifp = fopen (ifname, "rb"))) {
4955 perror (ifname);
4956 continue;
4958 if ((status = identify())) {
4959 fclose(ifp);
4960 continue;
4965 if (identify_only) {
4966 // Cinelerra
4967 // fprintf (stderr, "%s is a %s %s image.\n", ifname, make, model);
4968 fclose(ifp);
4969 continue;
4971 shrink = half_size && filters;
4972 iheight = (height + shrink) >> shrink;
4973 iwidth = (width + shrink) >> shrink;
4974 image = calloc (iheight * iwidth, sizeof *image);
4975 merror (image, "main()");
4976 if (verbose)
4977 fprintf (stderr,
4978 "Loading %s %s image from %s...\n", make, model, ifname);
4979 (*load_raw)();
4980 fclose(ifp);
4981 bad_pixels();
4982 height = iheight;
4983 width = iwidth;
4984 if (is_foveon) {
4985 if (verbose)
4986 fprintf (stderr, "Foveon interpolation...\n");
4987 foveon_interpolate();
4988 } else {
4989 scale_colors();
4993 if (shrink) filters = 0;
4994 trim = 0;
4995 if (filters && !document_mode) {
4996 trim = 1;
4997 if (verbose)
4998 fprintf (stderr, "%s interpolation...\n",
4999 quick_interpolate ? "Bilinear":"VNG");
5000 // Cinelerra
5001 // This blends the RGB pattern in the sensor but is too damn slow.
5002 vng_interpolate();
5004 if (verbose)
5005 fprintf (stderr, "Converting to RGB colorspace...\n");
5008 convert_to_rgb();
5011 if (user_flip >= 0)
5012 flip = user_flip;
5013 if (flip) {
5014 if (verbose)
5015 fprintf (stderr, "Flipping image %c:%c:%c...\n",
5016 flip & 1 ? 'H':'0', flip & 2 ? 'V':'0', flip & 4 ? 'T':'0');
5017 flip_image();
5021 ofname = malloc (strlen(ifname) + 16);
5022 merror (ofname, "main()");
5023 if (write_to_stdout)
5024 strcpy (ofname, "standard output");
5025 else {
5026 strcpy (ofname, ifname);
5027 if ((cp = strrchr (ofname, '.'))) *cp = 0;
5028 strcat (ofname, write_ext);
5029 ofp = fopen (ofname, "wb");
5030 if (!ofp) {
5031 status = 1;
5032 perror(ofname);
5033 goto cleanup;
5038 if (verbose)
5039 fprintf (stderr, "Writing data to %s...\n", ofname);
5040 (*write_fun)(ofp);
5041 if (ofp != stdout)
5042 fclose(ofp);
5043 cleanup:
5044 free(ofname);
5045 free(image);
5047 return status;