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.
15 $Date: 2004/10/29 01:52:38 $
31 By defining NO_JPEG, you lose only the ability to
32 decode compressed .KDC files from the Kodak DC120.
40 #pragma comment(lib, "ws2_32.lib")
41 #define strcasecmp stricmp
42 typedef __int64 INT64
;
45 #include <netinet/in.h>
46 typedef long long INT64
;
50 #error Please compile dcraw.c by itself.
51 #error Do not link it with ljpeg_decode.
55 #define LONG_BIT (8 * sizeof (long))
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.
74 char dcraw_info
[1024];
81 char *ifname
, make
[64], model
[64], model2
[64];
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
;
91 ushort (*image
)[4], white
[8][8];
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
;
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;
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;
121 struct decode
*branch
[2];
123 } first_decode
[2048], *second_decode
, *free_decode
;
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:
149 PowerShot A5 uses 0x1e4e1e4e:
157 PowerShot A50 uses 0x1b4e4b1e:
169 PowerShot Pro70 uses 0x1e4b4e1b:
181 PowerShots Pro90 and G1 use 0xb4b4b4b4:
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
200 char *memmem (char *haystack
, size_t haystacklen
,
201 char *needle
, size_t needlelen
)
204 for (c
= haystack
; c
<= haystack
+ haystacklen
- needlelen
; c
++)
205 if (!memcmp (c
, needle
, needlelen
))
211 void CLASS
merror (void *ptr
, char *where
)
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
)
228 if (order
== 0x4949) /* "II" means little-endian */
230 else /* "MM" means big-endian */
235 Same for a 4-byte integer.
237 int CLASS
fget4 (FILE *f
)
246 return a
+ (b
<< 8) + (c
<< 16) + (d
<< 24);
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
;
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
++)
275 if ((orow
+=2) > height
)
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
;
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;
319 if (nbits
== 0) return 0;
321 ret
= bitbuf
= vbits
= 0;
323 ret
= bitbuf
<< (LONG_BIT
- vbits
) >> (LONG_BIT
- nbits
);
326 while (vbits
< LONG_BIT
- 7) {
328 bitbuf
= (bitbuf
<< 8) + c
;
329 if (c
== 0xff && zero_after_ff
)
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 },
368 uchar
* CLASS
make_decoder (const uchar
*source
, int level
)
374 if (level
==0) leaf
=0;
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; )
384 cur
->branch
[0] = free_decode
;
385 make_decoder (source
, level
+1);
386 cur
->branch
[1] = free_decode
;
387 make_decoder (source
, level
+1);
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;
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()
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;
485 void CLASS
canon_compressed_load_raw()
487 ushort
*pixel
, *prow
;
488 int lowbits
, shift
, i
, row
, r
, col
, save
, val
;
490 struct decode
*decode
, *dindex
;
491 int block
, diffbuf
[64], leaf
, len
, diff
, carry
=0, pnum
=0, base
[2];
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
);
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)];
511 decode
= second_decode
;
512 if (leaf
== 0 && i
) break;
513 if (leaf
== 0xff) continue;
516 if (len
== 0) continue;
518 if ((diff
& (1 << (len
-1))) == 0)
519 diff
-= (1 << len
) - 1;
520 if (i
< 64) diffbuf
[i
] = diff
;
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
] );
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
++) {
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;
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
;
549 BAYER(irow
,icol
) = pixel
[r
*raw_width
+col
] << shift
;
551 bblack
+= pixel
[r
*raw_width
+col
];
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
++)
566 if (strcasecmp(make
,"KODAK")) return;
568 fseek (ifp
, 12, SEEK_SET
);
569 entries
= fget2(ifp
);
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];
608 if (fget2(ifp
) != 0xffd8) return;
612 len
= fget2(ifp
) - 2;
613 if (tag
<= 0xff00 || len
> 255) return;
614 fread (data
, 1, len
, ifp
);
617 jhigh
= (data
[1] << 8) + data
[2];
618 jwide
=((data
[3] << 8) + data
[4])*2;
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);
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)];
644 if ((diff
& (1 << (len
-1))) == 0)
645 diff
-= (1 << len
) - 1;
648 hpred
[jcol
] = vpred
[jcol
];
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
);
657 row
= jidx
/ 1680 % jhigh
;
658 col
= jidx
% 1680 + i
*1680;
660 jidx
-= 2*1680*jhigh
;
662 col
= jidx
% 1748 + 2*1680;
665 row
= jidx
/ raw_width
;
666 col
= jidx
% raw_width
;
668 if ((unsigned) (row
-top_margin
) >= height
)
670 if ((unsigned) (col
-left_margin
) < width
) {
671 BAYER(row
-top_margin
,col
-left_margin
) = curve
[diff
] << 2;
672 if (min
> curve
[diff
])
675 bblack
+= curve
[diff
];
689 if (raw_width
> width
)
690 black
= (bblack
<< 2) / ((raw_width
- width
) * height
);
691 if (!strcasecmp(make
,"KODAK"))
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
;
703 struct decode
*dindex
;
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
);
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
);
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)];
727 if ((diff
& (1 << (len
-1))) == 0)
728 diff
-= (1 << len
) - 1;
730 i
= 2*(row
& 1) + (col
& 1);
732 hpred
[col
] = vpred
[i
];
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;
744 void CLASS
nikon_load_raw()
746 int irow
, row
, col
, i
;
749 for (irow
=0; irow
< height
; 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
);
759 for (col
=0; col
< raw_width
; col
++) {
761 if ((unsigned) (col
-left_margin
) < width
)
762 BAYER(row
,col
-left_margin
) = i
<< 2;
763 if (tiff_data_compression
== 34713 && (col
% 10) == 9)
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()
779 if (tiff_data_compression
!= 34713)
781 if (strcmp(model
,"D100"))
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;
791 Returns 1 for a Coolpix 990, 0 for a Coolpix 995.
793 int CLASS
nikon_e990()
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
++)
802 for (i
=0; i
< 4; i
++)
803 if (histo
[often
[i
]] > 400)
809 Returns 1 for a Coolpix 2100, 0 for anything else.
811 int CLASS
nikon_e2100()
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)
827 Separates a Minolta DiMAGE Z2 from a Nikon E4300.
829 int CLASS
minolta_z2()
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;
841 void CLASS
nikon_e2100_load_raw()
843 uchar data
[3432], *dp
;
844 ushort pixel
[2288], *pix
;
847 for (row
=0; row
<= height
; row
+=2) {
849 fseek (ifp
, width
==1616 ? 8792:424, SEEK_CUR
);
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()
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
--; )
883 The Fuji Super CCD is just a Bayer grid rotated 45 degrees.
885 void CLASS
fuji_s2_load_raw()
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
)
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()
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];
952 void CLASS
rollei_load_raw()
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) {
961 todo
[i
+1] = pixel
[i
] << 8 | pixel
[i
+1];
962 buffer
= pixel
[i
] >> 2 | buffer
<< 6;
964 for ( ; i
< 16; i
+=2) {
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()
980 ushort pixel
[4134], akey
, bkey
;
982 fseek (ifp
, 8, SEEK_CUR
);
983 fseek (ifp
, fget4(ifp
) + 296, SEEK_CUR
);
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()
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()
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
++)
1029 void CLASS
unpacked_load_raw (int order
, int rsh
)
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
);
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()
1075 for (irow
=0; irow
< height
; irow
++) {
1076 row
= irow
* 2 % height
+ irow
/ (height
/2);
1078 fseek (ifp
, data_offset
- row
*(-width
*height
*3/4 & -2048), SEEK_SET
);
1081 for (col
=0; col
< width
; col
++)
1082 BAYER(row
,col
) = getbits(12) << 2;
1086 void CLASS
eight_bit_load_raw()
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;
1101 void CLASS
casio_qv5700_load_raw()
1103 uchar data
[3232], *dp
;
1104 ushort pixel
[2576], *pix
;
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()
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);
1133 for (dp
=data
, col
=0; col
< width
; col
++, dp
+=2)
1134 BAYER(row
,col
) = (dp
[0] << 2) + (dp
[1] << 10);
1139 const int * CLASS
make_decoder_int (const int *source
, int level
)
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);
1150 cur
->leaf
= source
[1];
1156 int CLASS
radc_token (int tree
)
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,
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);
1187 if (model
[2] == '4')
1188 return (getbits(5) << 3) + 4; /* DC40 */
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];
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;
1219 for (i
=0; i
< sizeof(buf
[0])/sizeof(short); i
++)
1220 buf
[c
][0][i
] = (buf
[c
][0][i
] * val
+ x
) >> s
;
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
))) {
1228 FORYX buf
[c
][y
][x
] = radc_token(tree
+10) * mul
[c
];
1230 FORYX buf
[c
][y
][x
] = radc_token(tree
+10) * 16 + PREDICTOR
;
1233 nreps
= (col
> 2) ? radc_token(9) + 1 : 1;
1234 for (rep
=0; rep
< 8 && rep
< nreps
&& col
> 0; rep
++) {
1236 FORYX buf
[c
][y
][x
] = PREDICTOR
;
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;
1249 BAYER(row
+y
*2+c
-1,x
*2+2-c
) = val
;
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
++)
1259 val
= (BAYER(y
,x
)-2048)*2 + (BAYER(y
,x
-1)+BAYER(y
,x
+1))/2;
1260 if (val
< 0) val
= 0;
1270 void CLASS
kodak_jpeg_load_raw() {}
1274 fill_input_buffer (j_decompress_ptr cinfo
)
1276 static char jpeg_buffer
[4096];
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
;
1286 void CLASS
kodak_jpeg_load_raw()
1288 struct jpeg_decompress_struct cinfo
;
1289 struct jpeg_error_mgr jerr
;
1291 JSAMPLE (*pixel
)[3];
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
);
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 };
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] =
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
);
1363 void CLASS
kodak_easy_load_raw()
1366 ushort curve
[0x1000];
1367 unsigned row
, col
, icol
;
1369 kodak_curve (curve
);
1370 if (raw_width
> width
)
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
;
1379 BAYER(row
,icol
) = (ushort
) curve
[pixel
[col
]] << 2;
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))
1391 void CLASS
kodak_compressed_load_raw()
1394 ushort raw
[6], curve
[0x1000];
1395 unsigned row
, col
, len
, save
, i
, israw
=0, bits
=0, pred
[2];
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;
1407 for (israw
=i
=0; i
< len
; i
+=2) {
1409 if ((blen
[i
+0] = c
& 15) > 12 ||
1410 (blen
[i
+1] = c
>> 4) > 12 )
1413 bitbuf
= bits
= pred
[0] = pred
[1] = 0;
1415 bitbuf
= fgetc(ifp
) << 8;
1416 bitbuf
+= fgetc(ifp
);
1420 fseek (ifp
, save
, SEEK_SET
);
1422 if (israw
) { /* If the data is not compressed */
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;
1431 diff
= raw
[1] >> 12 << 8 | raw
[3] >> 12 << 4 | raw
[5] >> 12;
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));
1443 diff
= bitbuf
& (0xffff >> (16-len
)); /* Pull bits from buffer */
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()
1458 unsigned row
, col
, len
, bits
=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
; ) {
1474 li
= bitbuf
= bits
= y
[1] = y
[3] = cb
= cr
= 0;
1476 bitbuf
= fgetc(ifp
) << 8;
1477 bitbuf
+= fgetc(ifp
);
1481 for (si
=0; si
< 6; si
++) {
1484 for (i
=0; i
< 32; i
+=8)
1485 bitbuf
+= (INT64
) fgetc(ifp
) << (bits
+(i
^8));
1488 diff
= bitbuf
& (0xffff >> (16-len
));
1491 if ((diff
& (1 << (len
-1))) == 0)
1492 diff
-= (1 << len
) - 1;
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];
1501 for (i
=0; i
< 4; i
++) {
1502 ip
= image
[(row
+(i
>> 1))*width
+ col
+(i
& 1)];
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
;
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
]);
1526 *data
++ ^= pad
[p
++ & 127] = pad
[(p
+1) & 127] ^ pad
[(p
+65) & 127];
1529 void CLASS
sony_load_raw()
1533 unsigned i
, key
, row
, col
, icol
;
1536 fseek (ifp
, 200896, SEEK_SET
);
1537 fseek (ifp
, (unsigned) fgetc(ifp
)*4 - 1, SEEK_CUR
);
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
]);
1553 bblack
+= ntohs(pixel
[col
]);
1555 black
= bblack
/ ((3343 - width
) * height
);
1558 void CLASS
sony_rgbe_coeff()
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
];
1572 void CLASS
foveon_decoder (unsigned huff
[1024], unsigned code
)
1577 cur
= free_decode
++;
1578 if (free_decode
> first_decode
+2048) {
1579 fprintf (stderr
, "%s: decoder table overflow\n", ifname
);
1580 longjmp (failure
, 2);
1583 for (i
=0; i
< 1024; i
++)
1584 if (huff
[i
] == code
) {
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
);
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
++)
1631 image
[(row
-top_margin
)*width
+(col
-left_margin
)][c
] = pred
[c
];
1636 int CLASS
apply_curve (int i
, const int *curve
)
1639 return -curve
[curve
[0]]-1;
1642 else if (i
< curve
[0])
1645 return curve
[curve
[0]]+1;
1648 void CLASS
foveon_interpolate()
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 } } },
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 },
1668 0,1,1,2,3,3,4,4,5,5,6,6,6,7,7,7,7,7,7,7 },
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 },
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
},
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
];
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;
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
++) {
1734 (pix
[0]*6 + (pix
[-4]+pix
[4])*4 + pix
[-8]+pix
[8] + 8) >> 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;
1744 i
= pix
[0] + ((pix
[0] - ((smred
*7 + smred_p
) >> 3)) >> 2);
1746 if (i
> 10000) i
= 10000;
1752 /* Limit each color value to the range of its neighbors */
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
++) {
1765 if (min
> j
) min
= j
;
1766 if (max
< j
) max
= j
;
1769 if (*pix
< min
) *pix
= min
;
1770 if (*pix
> max
) *pix
= max
;
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];
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
];
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
);
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;
1822 if (i
> 24000) i
= 24000;
1825 for (c
=0; c
< 3; 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;
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;
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 */
1864 memcpy (smrow
[2], smrow
[1], sizeof **smrow
* width
);
1866 for (col
=0; col
< (width
& ~3); col
++)
1867 for (c
=0; c
< 3; 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
];
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
]);
1884 for (c
=0; c
< 3; c
++) {
1885 i
= image
[row
*width
+col
][c
] + ipix
[c
] - sum
;
1887 image
[row
*width
+col
][c
] = i
;
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()
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
);
1909 if (getcwd (fname
, len
-12)) break;
1911 if (errno
!= ERANGE
) return;
1914 if (fname
[1] == ':')
1915 memmove (fname
, fname
+2, len
-2);
1916 for (cp
=fname
; *cp
; cp
++)
1917 if (*cp
== '\\') *cp
= '/';
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
!= '/');
1929 while (fgets (line
, 128, fp
)) {
1930 cp
= strchr (line
, '#');
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
)) {
1943 BAYER(row
,col
) = tot
/n
;
1946 fprintf (stderr
, "Fixed bad pixels at:");
1947 fprintf (stderr
, " %d,%d", col
, row
);
1950 if (fixed
) fputc ('\n', stderr
);
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) {
1960 if (!fgets(data
, 127, fp
))
1964 status
= sscanf (data
, sequence
, where
);
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];
1997 fgets (line
, 128, fp
);
1998 if (feof(fp
)) break;
1999 cp
= strchr (line
, '#');
2002 if (get_float_parameter(fp
, "gamma:\n", line
,
2003 &gamma_val
, NULL
) == -1)
2006 if (get_float_parameter(fp
, "brightness:\n", line
,
2007 &bright
, NULL
) == -1)
2010 if (get_float_parameter(fp
, "red scale:\n", line
,
2011 &red_scale
, NULL
) == -1)
2014 if (get_float_parameter(fp
, "blue scale:\n", line
,
2015 &blue_scale
, NULL
) == -1)
2018 if (get_float_parameter(fp
, "green scale:\n", line
,
2019 &green_scale
, NULL
) == -1)
2022 if (get_float_parameter(fp
, "juice:\n", line
,
2023 &juice
, NULL
) == -1)
2026 if (get_float_parameter(fp
, "white point fraction:\n", line
,
2027 &white_point_fraction
, NULL
) == -1)
2030 if (get_float_parameter(fp
, "pivot value:\n", line
,
2031 &pivot_value
, NULL
) == -1)
2034 if (get_float_parameter(fp
, "exposure compensation:\n", line
,
2035 &exposure_compensation
, NULL
) == -1)
2038 if (get_float_parameter(fp
, "saturation:\n", line
,
2039 &saturation
, NULL
) == -1)
2042 if (get_float_parameter(fp
, "contrast:\n", line
,
2043 &contrast
, NULL
) == -1)
2046 if (get_int_parameter(fp
, "flip:\n", line
,
2050 if (!strcmp(line
, "color matrix:\n")) {
2052 for (i
=0; i
< 3; i
++) {
2053 fgets (data
, 128, fp
);
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
)) {
2073 if (got_coeff
> 0) {
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
);
2084 coeff
[i
][j
] = my_coeff
[i
][j
] * juice
;
2092 void get_parameters()
2096 const char *default_file
="default.prm", *prm_ext
= ".prm";
2099 fp
= fopen (default_file
, "r");
2101 get_parameter_value (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");
2114 get_parameter_value (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
;
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;
2134 double white_fraction
= 1.0 - white_point_fraction
;
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)
2146 if (white_fraction
> 1)
2148 else if (white_fraction
< 0)
2150 if (use_neutral_wb
) {
2151 for (c
=0; c
< 4; c
++) {
2155 for (c
= 0; c
< 4; c
++) {
2158 clipped_pixels
[c
] = 0;
2160 memset (histogram
, 0, sizeof histogram
);
2161 for (c
=0; c
< 4; c
++) {
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
++) {
2177 val
= image
[row
*width
+col
][c
];
2179 if (use_camera_black
&& val
< black
)
2181 histogram
[val
>> 3]++;
2182 if (val
>= rgb_max
- 100) {
2183 clipped_pixels
[c
]++;
2184 total_clipped_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
;
2205 if (center_weight
) {
2209 if (rgb_max
< abs_max
)
2211 if (black
> abs_min
)
2215 mean
= (total
/ total_pixels
) - black
;
2216 for (c
= 0; c
< 4; c
++) {
2221 for (c
= 0; c
< colors
; c
++)
2223 means
[c
] = (totals
[c
] / pixels
[c
]) - black
;
2226 if (use_auto_wb
|| (use_camera_wb
&& camera_red
== -1)) {
2227 for (c
=0; c
< 4; c
++) {
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
];
2236 if (use_camera_black
&& val
< black
)
2238 if (min
[c
] > val
) min
[c
] = val
;
2239 if (max
[c
] < val
) max
[c
] = val
;
2241 if (val
> rgb_max
-100) continue;
2242 if (val
< 0) val
= 0;
2246 for (dmax
=c
=0; c
< colors
; 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
++) {
2259 if ((val
= white
[row
][col
] - black
) > 0)
2263 for (dmin
=DBL_MAX
, dmax
=c
=0; c
< colors
; c
++) {
2265 if (dmin
> sum
[c
]) dmin
= sum
[c
];
2266 if (dmax
< sum
[c
]) dmax
= sum
[c
];
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;
2276 fprintf (stderr
, "%s: Cannot use camera white balance.\n", ifname
);
2280 for (c
= 0; c
< colors
; c
++) {
2282 total
+= means
[c
] * pixels
[c
] / pre_mul
[c
];
2284 total
/= weighted_total_pixels
;
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
;
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
);
2305 if (pivot_value
> 1)
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
++)
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
);
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
) {
2350 } else if (base
> rgb_max
) {
2351 lut
[c
][i
] = RGB_MAX
;
2354 * Roundoff error may result in this going slightly negative.
2357 double x_base
= 1 - ((base
- x_start
) * scale
);
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
;
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
++)
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
++)
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",
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
++)
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
];
2423 if (use_camera_black
&& val
< black
)
2430 if (val
< 0) val
= 0;
2431 if (val
> rgb_max
) val
= rgb_max
;
2433 image
[row
*width
+col
][c
] = val
;
2435 for (c
= 0; c
< colors
; 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,
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
;
2494 sum
[color
] += 1 << shift
;
2496 for (c
=0; c
< colors
; c
++)
2497 if (c
!= FC(row
,col
)) {
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
);
2522 for (g
=colors
; --g
; )
2525 pix
[c
] = sum
[c
] / *ip
++;
2533 if (quick_interpolate
)
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
++;
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
;
2556 for (g
=0; g
< 8; g
++)
2557 if (grads
& 1<<g
) *ip
++ = g
;
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
;
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]);
2604 if ((g
= ip
[-1]) == -1) continue;
2606 while ((g
= *ip
++) != -1)
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
];
2625 memcpy (brow
[2][col
], pix
, sizeof *image
);
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;
2647 sum
[c
] += pix
[ip
[0] + c
];
2658 for (c
=0; c
< colors
; c
++)
2659 { /* Save to buffer */
2663 t
+= (sum
[c
] - sum
[color
])/num
;
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
);
2701 Interpolation for 1/16 thumbnail file. Just take an average of the
2704 void thm_interpolate()
2706 int row
, col
, x
, y
, c
;
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
);
2735 if (type
== 3 && len
< 3) {
2736 val
= fget2(ifp
); fget2(ifp
);
2740 case 0x100: /* ImageWidth */
2743 case 0x101: /* ImageHeight */
2746 case 0x102: /* Bits per sample */
2748 case 0x103: /* Compression */
2749 tiff_data_compression
= val
;
2751 case 0x106: /* Kodak color format */
2752 kodak_data_compression
= val
;
2754 case 0x111: /* StripOffset */
2759 fseek (ifp
, val
+base
, SEEK_SET
);
2760 data_offset
= fget4(ifp
);
2761 fseek (ifp
, save
, SEEK_SET
);
2764 case 0x115: /* SamplesPerRow */
2766 case 0x116: /* RowsPerStrip */
2768 case 0x117: /* StripByteCounts */
2777 void CLASS
nef_parse_makernote()
2779 int base
=0, offset
=0, entries
, tag
, type
, len
, val
, save
;
2784 The MakerNote might have its own TIFF header (possibly with
2785 its own byte-order!), or it might just be a table.
2788 fread (buf
, 1, 10, ifp
);
2789 if (!strcmp (buf
,"Nikon")) { /* starts with "Nikon\0\2\0\0\0" ? */
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
);
2798 fseek (ifp
, -10, SEEK_CUR
);
2800 entries
= fget2(ifp
);
2805 if (type
== 3) { /* short int */
2806 val
= fget2(ifp
); fget2(ifp
);
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
);
2818 curve_offset
= base
+val
+ 2112;
2820 curve_offset
= base
+val
+ 2;
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;
2843 camera_blue
= val
/ 256.0;
2844 fseek (ifp
, save
, SEEK_SET
);
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()
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)
2863 putenv ("TZ=UTC"); /* Remove this to assume local time */
2864 if ((ts
= mktime(&t
)) > 0)
2868 void CLASS
nef_parse_exif (int base
)
2870 int entries
, tag
, type
, len
, val
, save
;
2872 entries
= fget2(ifp
);
2879 fseek (ifp
, val
+base
, SEEK_SET
);
2880 if (tag
== 0x9003 || tag
== 0x9004)
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
;
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
);
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
);
2909 if (type
== 3 && len
< 3) {
2910 val
= fget2(ifp
); fget2(ifp
);
2914 fseek (ifp
, val
+base
, SEEK_SET
);
2917 //printf("%d %x\n", ftell(ifp), tag);
2921 camera_red
= val
/ 256.0;
2924 camera_blue
= val
/ 256.0;
2926 case 0x100: /* ImageWidth */
2929 case 0x101: /* ImageHeight */
2932 case 0x10f: /* Make tag */
2933 fgets (make
, 64, ifp
);
2935 case 0x110: /* Model tag */
2936 fgets (model
, 64, ifp
);
2938 case 0x111: /* StripOffset */
2940 offset
= fget4(ifp
);
2942 case 0x112: /* Rotation */
2943 flip
= flip_map
[(val
-1) & 7];
2949 case 0x827d: /* Model2 tag */
2950 fgets (model2
, 64, ifp
);
2952 case 0x131: /* Software tag */
2953 fgets (software
, 64, ifp
);
2954 if (!strncmp(software
,"Adobe",5))
2957 case 0x132: /* DateTime tag */
2961 strcpy (make
, "Leaf");
2965 data_offset
= fget4(ifp
);
2969 case 0x14a: /* SubIFD tag */
2970 if (len
> 2 && !strcmp(make
,"Kodak"))
2974 fseek (ifp
, val
+base
, SEEK_SET
);
2975 fseek (ifp
, fget4(ifp
)+base
, SEEK_SET
);
2976 tiff_parse_subifd(base
);
2980 tiff_parse_subifd(base
);
2982 case 0x8769: /* Nikon EXIF tag */
2983 nef_parse_exif(base
);
2987 fseek (ifp
, save
, SEEK_SET
);
2991 if (!strncmp(make
,"OLYMPUS",7)) {
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;
3017 if (fget4(ifp
) != 0x80008) return;
3018 if (fget4(ifp
) == 0) return;
3020 if (bpp
!= 10 && bpp
!= 12) return;
3021 for (i
=row
=0; row
< 8; row
++)
3022 for (col
=0; col
< 8; col
++) {
3024 bitbuf
= bitbuf
<< 16 | (fget2(ifp
) ^ key
[i
++ & 1]);
3028 bitbuf
<< (LONG_BIT
- vbits
) >> (LONG_BIT
- bpp
) << (14-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
);
3047 for (i
= 0; i
< nrecs
; i
++) {
3051 aoff
= offset
+ roff
;
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 ... */
3062 if (((!strcmp(model
,"Canon EOS DIGITAL REBEL") ||
3063 !strcmp(model
,"Canon EOS 300D DIGITAL"))) && wbi
== 6)
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;
3075 fseek (ifp
, aoff
+100, SEEK_SET
);
3076 if (wbi
== 6 && fget4(ifp
) == 0)
3079 fseek (ifp
, aoff
+100, SEEK_SET
);
3084 if (type
== 0x0032) { /* Get white balance (D30 & G3) */
3085 if (!strcmp(model
,"Canon EOS D30")) {
3086 fseek (ifp
, aoff
+72, SEEK_SET
);
3088 camera_red
= fget2(ifp
);
3089 camera_red
= fget2(ifp
) / camera_red
;
3090 camera_blue
= fget2(ifp
);
3091 camera_blue
/= fget2(ifp
);
3093 fseek (ifp
, aoff
+80 + (wbi
< 6 ? remap
[wbi
]*8 : 0), SEEK_SET
);
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
);
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
);
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;
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
;
3149 fseek (ifp
, 0, SEEK_SET
);
3151 fgets (line
, 128, ifp
);
3152 if ((val
= strchr(line
,'=')))
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 "))
3168 if (!strcmp(line
,"TY "))
3170 } while (strncmp(line
,"EOHD",4));
3174 if ((ts
= mktime(&t
)) > 0)
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
);
3189 fseek (ifp
, off2
, SEEK_SET
);
3190 while (fget4(ifp
) != 0x464d4143) /* Search for "CAMF" */
3191 if (feof(ifp
)) return;
3193 fseek (ifp
, off1
+8, SEEK_SET
);
3194 off1
+= (fget4(ifp
)+3) * 8;
3195 len
= (off2
- off1
)/2;
3196 fseek (ifp
, off1
, SEEK_SET
);
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"))
3205 if (!strcmp(bp
,"CAMMODEL"))
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
);
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 }
3225 for (i
=0; i
< 3; i
++)
3226 for (j
=0; j
< 3; j
++)
3227 coeff
[i
][j
] = foveon
[i
][j
] * pre_mul
[i
];
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 } };
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
);
3251 void CLASS
nikon_e950_coeff()
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
];
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 */
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) */
3312 for (g
=0; g
< 4; g
++)
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()
3325 unsigned hlen
, fsize
, i
;
3326 static const struct {
3328 char make
[12], model
[16];
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;
3360 fseek (ifp
, 0, SEEK_SET
);
3361 fread (head
, 1, 32, ifp
);
3362 fseek (ifp
, 0, SEEK_END
);
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)) {
3375 parse_ciff (hlen
, fsize
- hlen
);
3378 if (!strncmp(make
,"NIKON",5) && raw_width
== 0)
3381 } else if (!memcmp (head
, "\0MRM", 4)) {
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)
3401 } else if (!memcmp (head
, "BM", 2)) {
3402 data_offset
= 0x1000;
3404 fseek (ifp
, 38, SEEK_SET
);
3405 if (fget4(ifp
) == 2834 && fget4(ifp
) == 2834) {
3406 strcpy (model
, "BMQ");
3409 } else if (!memcmp (head
, "BR", 2)) {
3410 strcpy (model
, "RAW");
3412 strcpy (make
, "Nucore");
3414 fseek (ifp
, 10, SEEK_SET
);
3415 data_offset
+= fget4(ifp
);
3417 raw_width
= fget4(ifp
);
3418 raw_height
= fget4(ifp
);
3419 if (model
[0] == 'B' && raw_width
== 2597) {
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);
3430 fseek (ifp
, 100, SEEK_SET
);
3431 data_offset
= fget4(ifp
);
3432 } else if (!memcmp (head
, "DSC-Image", 9))
3434 else if (!memcmp (head
, "FOVb", 4))
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
);
3459 // fprintf (stderr, "%s: unsupported file format.\n", ifname);
3463 /* File format is OK. Do we support this camera? */
3464 /* Start with some useful defaults: */
3467 height
= raw_height
;
3469 top_margin
= left_margin
= 0;
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;
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
;
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")) {
3499 filters
= 0xe1e4e1e4;
3500 load_raw
= canon_600_load_raw
;
3503 } else if (!strcmp(model
,"PowerShot A5") ||
3504 !strcmp(model
,"PowerShot A5 Zoom")) {
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")) {
3519 filters
= 0x1b4e4b1e;
3520 load_raw
= canon_a5_load_raw
;
3524 } else if (!strcmp(model
,"PowerShot Pro70")) {
3528 filters
= 0x1e4b4e1b;
3529 load_raw
= canon_a5_load_raw
;
3533 } else if (!strcmp(model
,"PowerShot Pro90 IS")) {
3536 filters
= 0xb4b4b4b4;
3540 } else if (is_canon
&& raw_width
== 2144) {
3545 if (!strcmp(model
,"PowerShot G1")) {
3547 filters
= 0xb4b4b4b4;
3555 } else if (is_canon
&& raw_width
== 2224) {
3562 } else if (is_canon
&& raw_width
== 2376) {
3568 if (write_fun
== write_ppm
) /* Pro users may not want my matrix */
3569 canon_rgb_coeff (0.1);
3571 if (!strcmp(model
,"PowerShot G2") ||
3572 !strcmp(model
,"PowerShot S40")) {
3575 } else { /* G3 and S45 */
3579 } else if (is_canon
&& raw_width
== 2672) {
3586 } else if (is_canon
&& raw_width
== 3152) {
3593 if (!strcmp(model
,"EOS Kiss Digital")) {
3598 } else if (is_canon
&& raw_width
== 3160) {
3605 } else if (is_canon
&& raw_width
== 3344) {
3612 } else if (!strcmp(model
,"EOS-1D")) {
3615 data_offset
= 288912;
3618 } else if (!strcmp(model
,"EOS-1DS")) {
3621 data_offset
= 289168;
3625 } else if (!strcmp(model
,"EOS-1D Mark II") ||
3626 !strcmp(model
,"EOS 20D")) {
3631 height
= raw_height
- top_margin
;
3632 width
= raw_width
- left_margin
;
3633 filters
= 0x94949494;
3636 } else if (!strcmp(model
,"EOS-1Ds Mark II")) {
3641 height
= raw_height
- top_margin
;
3642 width
= raw_width
- left_margin
;
3643 filters
= 0x94949494;
3647 } else if (!strcmp(model
,"EOS D2000C")) {
3650 } else if (!strcmp(model
,"D1")) {
3651 filters
= 0x16161616;
3654 } else if (!strcmp(model
,"D1H")) {
3655 filters
= 0x16161616;
3658 } else if (!strcmp(model
,"D1X")) {
3660 filters
= 0x16161616;
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;
3671 } else if (!strcmp(model
,"D2H")) {
3674 filters
= 0x49494949;
3677 } else if (!strcmp(model
,"D70")) {
3678 filters
= 0x16161616;
3681 } else if (!strcmp(model
,"E950")) {
3684 filters
= 0x4b4b4b4b;
3686 load_raw
= nikon_e950_load_raw
;
3688 pre_mul
[0] = 1.18193;
3689 pre_mul
[2] = 1.16452;
3690 pre_mul
[3] = 1.17250;
3691 } else if (!strcmp(model
,"E990")) {
3696 filters
= 0xb4b4b4b4;
3702 strcpy (model
, "E995");
3703 filters
= 0xe1e1e1e1;
3708 } else if (!strcmp(model
,"E2100")) {
3710 if (nikon_e2100()) {
3712 load_raw
= nikon_e2100_load_raw
;
3716 strcpy (model
, "E2500");
3718 filters
= 0x4b4b4b4b;
3721 } else if (!strcmp(model
,"E4300")) {
3724 filters
= 0x16161616;
3726 strcpy (make
, "Minolta");
3727 strcpy (model
, "DiMAGE Z2");
3728 load_raw
= nikon_e2100_load_raw
;
3730 } else if (!strcmp(model
,"E4500")) {
3733 filters
= 0xb4b4b4b4;
3735 } else if (!strcmp(model
,"E5000") || !strcmp(model
,"E5700")) {
3736 filters
= 0xb4b4b4b4;
3742 } else if (!strcmp(model
,"E5400")) {
3743 filters
= 0x16161616;
3746 } else if (!strcmp(model
,"E8700") ||
3747 !strcmp(model
,"E8800")) {
3748 filters
= 0x16161616;
3751 } else if (!strcmp(model
,"FinePixS2Pro")) {
3754 filters
= 0x61616161;
3755 load_raw
= fuji_s2_load_raw
;
3759 } else if (!strcmp(model
,"FinePix S5000")) {
3762 filters
= 0x49494949;
3763 load_raw
= fuji_s5000_load_raw
;
3767 } else if (!strcmp(model
,"FinePix S7000")) {
3771 } else if (!strcmp(model
,"FinePix E550")) {
3777 filters
= 0x49494949;
3778 load_raw
= fuji_s7000_load_raw
;
3780 } else if (!strcmp(model
,"FinePix F700") ||
3781 !strcmp(model
,"FinePix S20Pro")) {
3784 filters
= 0x49494949;
3785 load_raw
= fuji_f700_load_raw
;
3789 } else if (!strcmp(model
,"Digital Camera KD-400Z")) {
3794 fseek (ifp
, 2032, SEEK_SET
);
3796 } else if (!strcmp(model
,"Digital Camera KD-510Z")) {
3798 fseek (ifp
, 2032, SEEK_SET
);
3800 } else if (!strcasecmp(make
,"MINOLTA")) {
3801 load_raw
= be_low_12_load_raw
;
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') {
3809 fseek (ifp
, 2078, SEEK_SET
);
3812 } else if (model
[8] == '5') {
3814 fseek (ifp
, 1936, SEEK_SET
);
3819 } else if (model
[8] == '6') {
3821 fseek (ifp
, 2030, SEEK_SET
);
3825 filters
= 0x61616161;
3827 load_raw
= be_low_10_load_raw
;
3830 camera_red
= fget2(ifp
);
3831 camera_blue
= fget2(ifp
);
3832 camera_red
/= fget2(ifp
);
3833 camera_blue
/= fget2(ifp
);
3837 } else if (!strcmp(model
,"*ist D")) {
3840 data_offset
= 0x10000;
3841 load_raw
= be_low_12_load_raw
;
3844 } else if (!strcmp(model
,"Optio S")) {
3848 load_raw
= packed_12_load_raw
;
3851 } else if (!strcmp(model
,"Optio S4")) {
3855 load_raw
= packed_12_load_raw
;
3858 } else if (!strcmp(make
,"Phase One")) {
3859 switch (raw_height
) {
3861 strcpy (model
, "LightPhase");
3870 strcpy (model
, "H10");
3877 strcpy (model
, "H20");
3886 strcpy (model
, "H25");
3894 filters
= top_margin
& 1 ? 0x94949494 : 0x49494949;
3895 load_raw
= phase_one_load_raw
;
3897 } else if (!strcmp(model
,"Ixpress")) {
3900 filters
= 0x49494949;
3901 load_raw
= ixpress_load_raw
;
3905 } else if (!strcmp(make
,"Sinar") && !memcmp(head
,"8BPS",4)) {
3906 fseek (ifp
, 14, SEEK_SET
);
3907 height
= fget4(ifp
);
3909 filters
= 0x61616161;
3911 load_raw
= be_16_load_raw
;
3913 } else if (!strcmp(make
,"Leaf")) {
3915 filters
= 0x16161616;
3916 load_raw
= be_16_load_raw
;
3917 pre_mul
[0] = 1.1629;
3918 pre_mul
[2] = 1.3556;
3920 } else if (!strcmp(model
,"DIGILUX 2") || !strcmp(model
,"DMC-LC1")) {
3924 load_raw
= le_high_12_load_raw
;
3927 } else if (!strcmp(model
,"E-1")) {
3928 filters
= 0x61616161;
3929 load_raw
= le_high_12_load_raw
;
3932 } else if (!strcmp(model
,"E-10")) {
3933 load_raw
= be_high_12_load_raw
;
3936 } else if (!strncmp(model
,"E-20",4)) {
3937 load_raw
= be_high_12_load_raw
;
3941 } else if (!strcmp(model
,"C5050Z")) {
3942 filters
= 0x16161616;
3943 load_raw
= olympus_cseries_load_raw
;
3946 } else if (!strcmp(model
,"C5060WZ")) {
3947 load_raw
= olympus_cseries_load_raw
;
3950 } else if (!strcmp(model
,"C8080WZ")) {
3951 filters
= 0x16161616;
3952 load_raw
= olympus_cseries_load_raw
;
3955 } else if (!strcmp(model
,"N DIGITAL")) {
3958 filters
= 0x61616161;
3959 data_offset
= 0x1a00;
3960 load_raw
= packed_12_load_raw
;
3963 } else if (!strcmp(model
,"DSC-F828")) {
3968 load_raw
= sony_load_raw
;
3970 filters
= 0xb4b4b4b4;
3975 } else if (!strcasecmp(make
,"KODAK")) {
3976 filters
= 0x61616161;
3977 if (!strcmp(model
,"NC2000F")) {
3983 } else if (!strcmp(model
,"EOSDCS3B")) {
3988 } else if (!strcmp(model
,"EOSDCS1")) {
3993 } else if (!strcmp(model
,"DCS315C")) {
3997 } else if (!strcmp(model
,"DCS330C")) {
4001 } else if (!strcmp(model
,"DCS420")) {
4006 } else if (!strcmp(model
,"DCS460")) {
4011 } else if (!strcmp(model
,"DCS460A")) {
4016 } else if (!strcmp(model
,"DCS520C")) {
4020 } else if (!strcmp(model
,"DCS560C")) {
4024 } else if (!strcmp(model
,"DCS620C")) {
4028 } else if (!strcmp(model
,"DCS620X")) {
4033 } else if (!strcmp(model
,"DCS660C")) {
4037 } else if (!strcmp(model
,"DCS660M")) {
4041 } else if (!strcmp(model
,"DCS720X")) {
4045 } else if (!strcmp(model
,"DCS760C")) {
4048 } else if (!strcmp(model
,"DCS760M")) {
4051 } else if (!strcmp(model
,"ProBack")) {
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;
4066 } else if (!strcasecmp(model
,"DCS Pro 14nx")) {
4068 pre_mul
[2] = 1.3155;
4069 } else if (!strcasecmp(model
,"DCS Pro SLR/c")) {
4072 } else if (!strcasecmp(model
,"DCS Pro SLR/n")) {
4076 switch (tiff_data_compression
) {
4077 case 0: /* No compression */
4079 load_raw
= kodak_easy_load_raw
;
4081 case 7: /* Lossless JPEG */
4082 load_raw
= lossless_jpeg_load_raw
;
4085 case 65000: /* Kodak DCR compression */
4086 if (kodak_data_compression
== 32803)
4087 load_raw
= kodak_compressed_load_raw
;
4089 load_raw
= kodak_yuv_load_raw
;
4090 height
= (height
+1) & -2;
4091 width
= (width
+1) & -2;
4096 fprintf (stderr
, "%s: %s %s uses unsupported compression method %d.\n",
4097 ifname
, make
, model
, tiff_data_compression
);
4100 if (!strcmp(model
,"DC20")) {
4102 if (fsize
< 100000) {
4109 data_offset
= raw_width
+ 1;
4111 filters
= 0x8d8d8d8d;
4112 kodak_dc20_coeff (0.5);
4116 load_raw
= kodak_easy_load_raw
;
4117 } else if (strstr(model
,"DC25")) {
4118 strcpy (model
, "DC25");
4120 if (fsize
< 100000) {
4123 data_offset
= 15681;
4127 data_offset
= 15937;
4130 filters
= 0xb4b4b4b4;
4131 load_raw
= kodak_easy_load_raw
;
4132 } else if (!strcmp(model
,"Digital Camera 40")) {
4133 strcpy (model
, "DC40");
4137 load_raw
= kodak_radc_load_raw
;
4138 } else if (strstr(model
,"DC50")) {
4139 strcpy (model
, "DC50");
4142 data_offset
= 19712;
4143 load_raw
= kodak_radc_load_raw
;
4144 } else if (strstr(model
,"DC120")) {
4145 strcpy (model
, "DC120");
4148 if (tiff_data_compression
== 7)
4149 load_raw
= kodak_jpeg_load_raw
;
4151 load_raw
= kodak_dc120_load_raw
;
4153 } else if (!strcmp(make
,"Rollei")) {
4154 switch (raw_width
) {
4167 filters
= 0x16161616;
4168 load_raw
= rollei_load_raw
;
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;
4182 load_raw
= foveon_load_raw
;
4186 if (!strcmp(model
,"SD10")) {
4192 } else if (!strcmp(model
,"PC-CAM 600")) {
4194 data_offset
= width
= 1024;
4195 filters
= 0x49494949;
4196 load_raw
= eight_bit_load_raw
;
4199 } else if (!strcmp(model
,"QV-2000UX")) {
4202 data_offset
= width
* 2;
4203 load_raw
= eight_bit_load_raw
;
4204 } else if (!strcmp(model
,"QV-3*00EX")) {
4208 load_raw
= eight_bit_load_raw
;
4209 } else if (!strcmp(model
,"QV-4000")) {
4212 load_raw
= be_high_12_load_raw
;
4213 } else if (!strcmp(model
,"QV-5700")) {
4216 load_raw
= casio_qv5700_load_raw
;
4217 } else if (!strcmp(model
,"EX-P600")) {
4221 load_raw
= packed_12_load_raw
;
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
);
4234 if (load_raw
== kodak_jpeg_load_raw
) {
4235 fprintf (stderr
, "%s: decoder was not linked with libjpeg.\n", ifname
);
4239 if (!raw_height
) raw_height
= height
;
4240 if (!raw_width
) raw_width
= width
;
4241 if (colors
== 4 && !use_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)
4253 if ((filters
>> i
& 15) == 6)
4257 pre_mul
[3] = pre_mul
[1];
4259 for (i
=0; i
< 3; i
++)
4260 coeff
[i
][3] = coeff
[i
][1] /= 2;
4262 fseek (ifp
, data_offset
, SEEK_SET
);
4267 sprintf(dcraw_info
, "%d %d", height
, width
);
4269 sprintf(dcraw_info
, "%d %d", width
, height
);
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;
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
];
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
++)
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) */
4310 for (r
=0; r
< 3; r
++) {
4313 if (rgb
[r
] > rgb_max
)
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
];
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
,
4337 double red
, green
, blue
;
4343 red
= rgb
[0] / (double) rgb_max
;
4344 green
= rgb
[1] / (double) rgb_max
;
4345 blue
= rgb
[2] / (double) rgb_max
;
4355 min
= FMIN(green
, blue
);
4364 min
= FMIN(red
, blue
);
4367 l
= (max
+ min
) / 2.0;
4370 if (delta
< .000001) { /* Suggested by Eugene Anikin <eugene@anikin.com> */
4375 s
= delta
/ (max
+ min
);
4377 s
= delta
/ (2 - max
- min
);
4380 h
= (green
- blue
) / delta
;
4381 else if (maxval
== 1)
4382 h
= 2 + (blue
- red
) / delta
;
4384 h
= 4 + (red
- green
) / delta
;
4397 static inline double hsl_value(double n1
, double n2
, double hue
)
4404 return (n1
+ (n2
- n1
) * hue
);
4408 return (n1
+ (n2
- n1
) * (4.0 - hue
));
4413 static inline void calc_hsl_to_rgb(ushort
*rgb
, double h
, double s
, double l
)
4420 rgb
[0] = l
* (double) rgb_max
;
4421 rgb
[1] = l
* (double) rgb_max
;
4422 rgb
[2] = l
* (double) rgb_max
;
4432 m2
= l
+ s
- (l
* s
);
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
)
4444 else if (adjust
> 1) {
4445 double s1
= sat
* adjust
;
4446 double s2
= 1.0 - ((1.0 - sat
) * (1.0 / adjust
));
4454 static inline double update_contrast(double lum
, double adjust
)
4456 double retval
= lum
;
4459 if (retval
< .00001 && adjust
< .0001)
4462 retval
= .5 - ((.5 - .5 * pow(2 * retval
, adjust
)));
4464 retval
= 1 - retval
;
4468 static inline void do_hsl_adjust(ushort
*rgb
)
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()
4484 int size
, base
, dest
, next
, row
, col
, temp
;
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)))
4498 row
= dest
% height
;
4499 col
= dest
/ height
;
4505 row
= height
- 1 - row
;
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
];
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];
4537 double white_fraction
= 1.0 - white_point_fraction
;
4539 if (white_fraction
> 1)
4541 else if (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;
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
;
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
];
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
);
4582 Write the image to a 48-bpp Photoshop file.
4584 void CLASS
write_psd16 (FILE *ofp
)
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()");
4612 for (row
= trim
; row
< height
-trim
; row
++) {
4613 for (col
= trim
; col
< width
-trim
; col
++) {
4614 rgb
= image
[row
*width
+col
];
4616 for (c
=0; c
< 3; c
++) {
4617 val
= rgb
[c
] * bright
;
4620 pred
[c
*psize
] = htons(val
);
4625 fwrite(buffer
, psize
, 6, ofp
);
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
;
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
];
4654 for (c
=0; c
< 3; c
++) {
4655 val
= rgb
[c
] * bright
;
4658 ppm
[col
-trim
][c
] = htons(val
);
4664 fwrite (ppm
, width
-trim
*2, 6, ofp
);
4676 void CLASS
write_cinelerra (FILE *ofp
)
4678 int row
, col
, c
, val
;
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;
4699 int row
, col
, i
, c
, total
, j
;
4701 float max
, mul
, scale
[0x10000];
4704 double white_fraction
= 1.0 - white_point_fraction
;
4706 if (white_fraction
> 1)
4708 else if (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;
4724 mul
= bright
* 442 / max
;
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
];
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;
4759 void CLASS
write_ppm_16_8(FILE *ofp
)
4768 val
= (double) rgb_max
* bright
;
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
];
4784 for (c
=0; c
< 3; c
++) {
4787 val
= rgb
[c
] * bright
/ divisor
;
4790 ppm
[col
-trim
][c
] = val
;
4793 for (i
=0; i
< ymag
; i
++)
4794 fwrite (ppm
, width
-trim
*2, 3, ofp
);
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";
4812 "\nRaw Photo Decoder \"dcraw\" v6.10"
4813 "\nby Dave Coffin, dcoffin a cybercom o net"
4814 "\n\nUsage: %s [options] file1 file2 ...\n"
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"
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
);
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;
4908 fprintf (stderr
, "Unknown option \"-%c\".\n", opt
);
4915 write_fun
= write_cinelerra
;
4918 fprintf (stderr
, "No files to process.\n");
4921 if (write_to_stdout
) {
4926 if (0 /* isatty(1) */) {
4927 fprintf (stderr
, "Will not write an image to the terminal!\n");
4934 #if defined(WIN32) || defined(DJGPP)
4935 if (setmode(1,O_BINARY
) < 0) {
4936 perror("setmode()");
4942 for ( ; arg
< argc
; arg
++)
4946 if (setjmp (failure
)) {
4947 if (fileno(ifp
) > 2) fclose(ifp
);
4948 if (fileno(ofp
) > 2) fclose(ofp
);
4949 if (image
) free(image
);
4954 if (!(ifp
= fopen (ifname
, "rb"))) {
4958 if ((status
= identify())) {
4965 if (identify_only
) {
4967 // fprintf (stderr, "%s is a %s %s image.\n", ifname, make, model);
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()");
4978 "Loading %s %s image from %s...\n", make
, model
, ifname
);
4986 fprintf (stderr
, "Foveon interpolation...\n");
4987 foveon_interpolate();
4993 if (shrink
) filters
= 0;
4995 if (filters
&& !document_mode
) {
4998 fprintf (stderr
, "%s interpolation...\n",
4999 quick_interpolate
? "Bilinear":"VNG");
5001 // This blends the RGB pattern in the sensor but is too damn slow.
5005 fprintf (stderr
, "Converting to RGB colorspace...\n");
5015 fprintf (stderr
, "Flipping image %c:%c:%c...\n",
5016 flip
& 1 ? 'H':'0', flip
& 2 ? 'V':'0', flip
& 4 ? 'T':'0');
5021 ofname
= malloc (strlen(ifname
) + 16);
5022 merror (ofname
, "main()");
5023 if (write_to_stdout
)
5024 strcpy (ofname
, "standard output");
5026 strcpy (ofname
, ifname
);
5027 if ((cp
= strrchr (ofname
, '.'))) *cp
= 0;
5028 strcat (ofname
, write_ext
);
5029 ofp
= fopen (ofname
, "wb");
5039 fprintf (stderr
, "Writing data to %s...\n", ofname
);