summaryrefslogtreecommitdiff
path: root/dcraw
diff options
context:
space:
mode:
authorhub <hub>2005-06-28 01:57:48 +0000
committerhub <hub>2005-06-28 01:57:48 +0000
commita8ad974cf918bc82330dc2c16efa7de8292b16d2 (patch)
tree8e84770ba451efd87dd72cc4892210fefc0e6ba0 /dcraw
parent1115febc6d003ad005f7763fd45b7298a3956594 (diff)
new version of dcraw.c,v
Diffstat (limited to 'dcraw')
-rw-r--r--dcraw/dcraw.c,v297
1 files changed, 249 insertions, 48 deletions
diff --git a/dcraw/dcraw.c,v b/dcraw/dcraw.c,v
index 37b208e..703c37e 100644
--- a/dcraw/dcraw.c,v
+++ b/dcraw/dcraw.c,v
@@ -1,10 +1,20 @@
-head 1.263;
+head 1.265;
access;
symbols;
locks; strict;
comment @ * @;
+1.265
+date 2005.06.27.20.22.12; author dcoffin; state Exp;
+branches;
+next 1.264;
+
+1.264
+date 2005.06.27.05.12.08; author dcoffin; state Exp;
+branches;
+next 1.263;
+
1.263
date 2005.06.06.05.32.07; author dcoffin; state Exp;
branches;
@@ -1348,12 +1358,9 @@ desc
@
-1.263
+1.265
log
-@Added the Foculus 503c.
-Don't assume that Nikon D2X/D2Hs files are big-endian.
-Added special auto white balance for the PowerShot 600.
-Fixed camera white balance for the PowerShot G1 and Pro90.
+@Improved support for Phase One files.
@
text
@/*
@@ -1411,11 +1418,13 @@ text
#pragma comment(lib, "ws2_32.lib")
#define strcasecmp stricmp
typedef __int64 INT64;
+typedef __uint64 UINT64;
#else
#include <unistd.h>
#include <utime.h>
#include <netinet/in.h>
typedef long long INT64;
+typedef unsigned long long UINT64;
#endif
#ifdef LJPEG_DECODE
@@ -2535,7 +2544,7 @@ void CLASS phase_one_load_raw()
fseek (ifp, nikon_curve_offset, SEEK_SET);
akey = get2();
bkey = get2();
- mask = model[0] == 'P' ? 0x1354:0x5555;
+ mask = tiff_data_compression == 1 ? 0x5555:0x1354;
fseek (ifp, data_offset + top_margin*raw_width*2, SEEK_SET);
pixel = calloc (raw_width, sizeof *pixel);
merror (pixel, "phase_one_load_raw()");
@@ -2551,6 +2560,55 @@ void CLASS phase_one_load_raw()
BAYER(row,col) = pixel[col+left_margin];
}
free (pixel);
+ maximum = 0xffff;
+}
+
+unsigned CLASS ph1_bits (int nbits)
+{
+ static UINT64 bitbuf=0;
+ static int vbits=0;
+
+ if (nbits == 0)
+ return bitbuf = vbits = 0;
+ if (vbits < nbits) {
+ bitbuf = bitbuf << 32 | (unsigned) get4();
+ vbits += 32;
+ }
+ vbits -= nbits;
+ return bitbuf << (64 - nbits - vbits) >> (64 - nbits);
+}
+
+void CLASS phase_one_load_raw_c()
+{
+ static const int length[] = { 8,7,6,9,11,10,5,12,14,13 };
+ int len[2], pred[2], row, col, ncols, i, j;
+ ushort *pixel;
+
+ ncols = (raw_width + 7) & -8;
+ pixel = calloc (ncols, sizeof *pixel);
+ merror (pixel, "phase_one_load_raw_c()");
+ for (row=0; row < raw_height; row++) {
+ ph1_bits(0);
+ pred[0] = pred[1] = 0;
+ for (col=0; col < ncols; col++) {
+ if (col >= (raw_width & -8))
+ len[0] = len[1] = 14;
+ else if ((col & 7) == 0)
+ for (i=0; i < 2; i++) {
+ for (j=0; j < 5 && !ph1_bits(1); j++);
+ if (j--) len[i] = length[j*2 + ph1_bits(1)];
+ }
+ if ((i = len[col & 1]) == 14)
+ pixel[col] = pred[col & 1] = ph1_bits(16);
+ else
+ pixel[col] = pred[col & 1] += ph1_bits(i) + 1 - (1 << (i - 1));
+ }
+ if ((unsigned) (row-top_margin) < height)
+ for (col=0; col < width; col++)
+ BAYER(row-top_margin,col) = pixel[col+left_margin];
+ }
+ free (pixel);
+ maximum = 0x3fff;
}
void CLASS leaf_load_raw()
@@ -3133,20 +3191,25 @@ void CLASS foveon_load_raw()
struct decode *dindex;
short diff[1024], pred[3];
unsigned huff[1024], bitbuf=0;
- int row, col, bit=-1, c, i;
+ int fixed, row, col, bit=-1, c, i;
+ fixed = get4();
read_shorts (diff, 1024);
- for (i=0; i < 1024; i++)
- huff[i] = get4();
-
- init_decoder();
- foveon_decoder (huff, 0);
-
+ if (!fixed) {
+ for (i=0; i < 1024; i++)
+ huff[i] = get4();
+ init_decoder();
+ foveon_decoder (huff, 0);
+ }
for (row=0; row < height; row++) {
memset (pred, 0, sizeof pred);
- if (!bit) get4();
+ if (!bit && !fixed) get4();
for (col=bit=0; col < width; col++) {
- FORC3 {
+ if (fixed) {
+ bitbuf = get4();
+ FORC3 pred[2-c] += diff[bitbuf >> c*10 & 0x3ff];
+ }
+ else FORC3 {
for (dindex=first_decode; dindex->branch[0]; ) {
if ((bit = (bit-1) & 31) == 31)
for (i=0; i < 4; i++)
@@ -3248,6 +3311,7 @@ short * CLASS foveon_make_curve (double max, double mul, double filt)
int i, size;
double x;
+ if (!filt) filt = 0.8;
size = 4*M_PI*max / filt;
curve = calloc (size+1, sizeof *curve);
merror (curve, "foveon_make_curve()");
@@ -3280,13 +3344,13 @@ void CLASS foveon_interpolate()
{
static const short hood[] = { -1,-1, -1,0, -1,1, 0,-1, 0,1, 1,-1, 1,0, 1,1 };
short *pix, prev[3], *curve[8], (*shrink)[3];
- float cfilt=0.8, ddft[3][3][2], ppm[3][3][3];
+ float cfilt=0, ddft[3][3][2], ppm[3][3][3];
float cam_xyz[3][3], correct[3][3], last[3][3], trans[3][3];
float chroma_dq[3], color_dq[3], diag[3][3], div[3];
float (*black)[3], (*sgain)[3], (*sgrow)[3];
float fsum[3], val, frow, num;
int row, col, c, i, j, diff, sgx, irow, sum, min, max, limit;
- int dim[3], dscr[2][2], (*smrow[7])[3], total[4], ipix[3];
+ int dim[3], dscr[2][2], dstb[4], (*smrow[7])[3], total[4], ipix[3];
int work[3][3], smlast, smred, smred_p=0, dev[3];
int satlev[3], keep[4], active[4];
unsigned *badpix;
@@ -3295,8 +3359,6 @@ void CLASS foveon_interpolate()
foveon_fixed (dscr, 4, "DarkShieldColRange");
foveon_fixed (ppm[0][0], 27, "PostPolyMatrix");
- foveon_fixed (ddft[1][0], 12, "DarkDrift");
- foveon_fixed (&cfilt, 1, "ColumnFilter");
foveon_fixed (satlev, 3, "SaturationLevel");
foveon_fixed (keep, 4, "KeepImageArea");
foveon_fixed (active, 4, "ActiveImageArea");
@@ -3304,6 +3366,19 @@ void CLASS foveon_interpolate()
foveon_fixed (color_dq, 3,
foveon_camf_param ("IncludeBlocks", "ColorDQ") ?
"ColorDQ" : "ColorDQCamRGB");
+ if (foveon_camf_param ("IncludeBlocks", "ColumnFilter"))
+ foveon_fixed (&cfilt, 1, "ColumnFilter");
+
+ memset (ddft, 0, sizeof ddft);
+ if (!foveon_camf_param ("IncludeBlocks", "DarkDrift")
+ || !foveon_fixed (ddft[1][0], 12, "DarkDrift"))
+ for (i=0; i < 2; i++) {
+ foveon_fixed (dstb, 4, i ? "DarkShieldBottom":"DarkShieldTop");
+ for (row = dstb[1]; row <= dstb[3]; row++)
+ for (col = dstb[0]; col <= dstb[2]; col++)
+ FORC3 ddft[i+1][c][1] += (short) image[row*width+col][c];
+ FORC3 ddft[i+1][c][1] /= (dstb[3]-dstb[1]+1) * (dstb[2]-dstb[0]+1);
+ }
if (!(cp = foveon_camf_param ("WhiteBalanceIlluminants", model2)))
{ fprintf (stderr, "%s: Invalid white balance \"%s\"\n", ifname, model2);
@@ -3453,7 +3528,8 @@ void CLASS foveon_interpolate()
memset (fsum, 0, sizeof fsum);
for (sum=j=0; j < 8; j++)
if (badpix[i] & (1 << j)) {
- FORC3 fsum[c] += image[(row+hood[j*2])*width+col+hood[j*2+1]][c];
+ FORC3 fsum[c] += (short)
+ image[(row+hood[j*2])*width+col+hood[j*2+1]][c];
sum++;
}
if (sum) FORC3 image[row*width+col][c] = fsum[c]/sum;
@@ -3495,12 +3571,12 @@ void CLASS foveon_interpolate()
}
/* Adjust the brighter pixels for better linearity */
+ min = 0xffff;
FORC3 {
i = satlev[c] / div[c];
- if (maximum > i) maximum = i;
+ if (min > i) min = i;
}
- clip_max = maximum;
- limit = maximum * 9 >> 4;
+ limit = min * 9 >> 4;
for (pix=image[0]; pix < (short *) image[height*width]; pix+=4) {
if (pix[0] <= limit || pix[1] <= limit || pix[2] <= limit)
continue;
@@ -3509,10 +3585,14 @@ void CLASS foveon_interpolate()
if (min > pix[c]) min = pix[c];
if (max < pix[c]) max = pix[c];
}
- i = 0x4000 - ((min - limit) << 14) / limit;
- i = 0x4000 - (i*i >> 14);
- i = i*i >> 14;
- FORC3 pix[c] += (max - pix[c]) * i >> 14;
+ if (min >= limit*2) {
+ pix[0] = pix[1] = pix[2] = max;
+ } else {
+ i = 0x4000 - ((min - limit) << 14) / limit;
+ i = 0x4000 - (i*i >> 14);
+ i = i*i >> 14;
+ FORC3 pix[c] += (max - pix[c]) * i >> 14;
+ }
}
/*
Because photons that miss one detector often hit another,
@@ -4456,7 +4536,6 @@ int CLASS parse_tiff_ifd (int base, int level)
break;
case 50706: /* DNGVersion */
is_dng = 1;
- if (flip == 7) flip = 4; /* Adobe didn't read the TIFF spec. */
break;
case 50710: /* CFAPlaneColor */
if (len > 4) len = 4;
@@ -4865,8 +4944,10 @@ void CLASS parse_phase_one (int base)
unsigned entries, tag, type, len, data, save, i, c;
char *cp;
- fseek (ifp, base + 8, SEEK_SET);
- fseek (ifp, base + get4(), SEEK_SET);
+ fseek (ifp, base, SEEK_SET);
+ order = get4() & 0xffff;
+ if (get4() >> 8 != 0x526177) return; /* "Raw" */
+ fseek (ifp, base+get4(), SEEK_SET);
entries = get4();
get4();
while (entries--) {
@@ -4892,6 +4973,7 @@ void CLASS parse_phase_one (int base)
case 0x10b: top_margin = data; break;
case 0x10c: width = data; break;
case 0x10d: height = data; break;
+ case 0x10e: tiff_data_compression = data; break;
case 0x10f: data_offset = data+base; break;
case 0x112:
nikon_curve_offset = save - 4; break;
@@ -4902,6 +4984,8 @@ void CLASS parse_phase_one (int base)
}
fseek (ifp, save, SEEK_SET);
}
+ load_raw = tiff_data_compression < 3 ?
+ phase_one_load_raw:phase_one_load_raw_c;
strcpy (make, "Phase One");
if (model[0]) return;
sprintf (model, "%dx%d", width, height);
@@ -4987,7 +5071,7 @@ char * CLASS foveon_gets (int offset, char *str, int len)
void CLASS parse_foveon()
{
- int entries, off, len, tag, save, i, pent, poff[256][2];
+ int entries, off, len, tag, save, i, wide, high, pent, poff[256][2];
char name[64];
order = 0x4949; /* Little-endian */
@@ -5007,11 +5091,15 @@ void CLASS parse_foveon()
if (get4() != (0x20434553 | (tag << 24))) return;
switch (tag) {
case 0x47414d49: /* IMAG */
- if (data_offset) break;
- data_offset = off + 28;
+ case 0x32414d49: /* IMA2 */
fseek (ifp, 12, SEEK_CUR);
- raw_width = get4();
- raw_height = get4();
+ wide = get4();
+ high = get4();
+ if (wide > raw_width && high > raw_height) {
+ raw_width = wide;
+ raw_height = high;
+ data_offset = off + 24;
+ }
break;
case 0x464d4143: /* CAMF */
meta_offset = off + 24;
@@ -5318,6 +5406,7 @@ int CLASS identify (int will_decode)
/* What format is this file? Set make[] if we recognize it. */
+ load_raw = NULL;
raw_height = raw_width = fuji_width = flip = 0;
height = width = top_margin = left_margin = 0;
make[0] = model[0] = model2[0] = 0;
@@ -5345,8 +5434,8 @@ int CLASS identify (int will_decode)
fread (head, 1, 32, ifp);
fseek (ifp, 0, SEEK_END);
fsize = ftell(ifp);
- if ((cp = memmem (head, 32, "MMMMRawT", 8)) ||
- (cp = memmem (head, 32, "IIIITwaR", 8)))
+ if ((cp = memmem (head, 32, "MMMM", 4)) ||
+ (cp = memmem (head, 32, "IIII", 4)))
parse_phase_one (cp-head);
else if (order == 0x4949 || order == 0x4d4d) {
if (!memcmp (head+6, "HEAPCCDR", 8)) {
@@ -5441,10 +5530,6 @@ nucore:
fprintf (stderr, "%s: unsupported file format.\n", ifname);
return 1;
}
-
-/* File format is OK. Do we support this camera? */
-/* Start with some useful defaults: */
-
if ((raw_height | raw_width) < 0)
raw_height = raw_width = 0;
if (!height) height = raw_height;
@@ -5454,7 +5539,6 @@ nucore:
height = width - 1;
ymag = 1;
}
- load_raw = NULL;
if (is_dng) {
strcat (model," DNG");
if (filters == UINT_MAX) filters = 0;
@@ -5481,7 +5565,7 @@ nucore:
if (is_foveon) {
if (height*2 < width) ymag = 2;
- if (width < height) xmag = 2;
+ if (height > width) xmag = 2;
filters = 0;
load_raw = foveon_load_raw;
simple_coeff(0);
@@ -5859,9 +5943,6 @@ konica_400z:
load_raw = unpacked_load_raw;
filters = 0x49494949;
pre_mul[1] = 1.218;
- } else if (!strcmp(make,"Phase One")) {
- load_raw = phase_one_load_raw;
- maximum = 0xffff;
} else if (!strcmp(make,"Imacon")) {
height = 5444;
width = 4080;
@@ -6477,7 +6558,7 @@ int CLASS main (int argc, char **argv)
if (argc == 1)
{
fprintf (stderr,
- "\nRaw Photo Decoder \"dcraw\" v7.30"
+ "\nRaw Photo Decoder \"dcraw\" v7.36"
"\nby Dave Coffin, dcoffin a cybercom o net"
"\n\nUsage: %s [options] file1 file2 ...\n"
"\nValid options:"
@@ -6681,6 +6762,126 @@ cleanup:
@
+1.264
+log
+@Added the Polaroid x530 and Phase One P 25.
+@
+text
+@d1182 1
+a1182 1
+ mask = model[0] == 'P' ? 0x1354:0x5555;
+d3584 1
+a3584 4
+ i = get4();
+ if (i == 0x52617754) load_raw = phase_one_load_raw; /* RawT */
+ if (i == 0x52617743) load_raw = phase_one_load_raw_c; /* RawC */
+ if (!load_raw) return;
+d3611 1
+d3622 2
+d5196 1
+a5196 1
+ "\nRaw Photo Decoder \"dcraw\" v7.35"
+@
+
+
+1.263
+log
+@Added the Foculus 503c.
+Don't assume that Nikon D2X/D2Hs files are big-endian.
+Added special auto white balance for the PowerShot 600.
+Fixed camera white balance for the PowerShot G1 and Pro90.
+@
+text
+@d56 1
+d62 1
+d1198 49
+d1829 1
+a1829 1
+ int row, col, bit=-1, c, i;
+d1831 1
+d1833 6
+a1838 6
+ for (i=0; i < 1024; i++)
+ huff[i] = get4();
+
+ init_decoder();
+ foveon_decoder (huff, 0);
+
+d1841 1
+a1841 1
+ if (!bit) get4();
+d1843 5
+a1847 1
+ FORC3 {
+d1949 1
+d1982 1
+a1982 1
+ float cfilt=0.8, ddft[3][3][2], ppm[3][3][3];
+d1988 1
+a1988 1
+ int dim[3], dscr[2][2], (*smrow[7])[3], total[4], ipix[3];
+a1996 2
+ foveon_fixed (ddft[1][0], 12, "DarkDrift");
+ foveon_fixed (&cfilt, 1, "ColumnFilter");
+d2004 13
+d2166 2
+a2167 1
+ FORC3 fsum[c] += image[(row+hood[j*2])*width+col+hood[j*2+1]][c];
+d2209 1
+d2212 1
+a2212 1
+ if (maximum > i) maximum = i;
+d2214 1
+a2214 2
+ clip_max = maximum;
+ limit = maximum * 9 >> 4;
+d2223 8
+a2230 4
+ i = 0x4000 - ((min - limit) << 14) / limit;
+ i = 0x4000 - (i*i >> 14);
+ i = i*i >> 14;
+ FORC3 pix[c] += (max - pix[c]) * i >> 14;
+a3173 1
+ if (flip == 7) flip = 4; /* Adobe didn't read the TIFF spec. */
+d3582 6
+a3587 1
+ fseek (ifp, base+8, SEEK_SET);
+d3709 1
+a3709 1
+ int entries, off, len, tag, save, i, pent, poff[256][2];
+d3729 1
+a3729 2
+ if (data_offset) break;
+ data_offset = off + 28;
+d3731 7
+a3737 2
+ raw_width = get4();
+ raw_height = get4();
+d4044 1
+d4072 2
+a4073 2
+ if ((cp = memmem (head, 32, "MMMMRawT", 8)) ||
+ (cp = memmem (head, 32, "IIIITwaR", 8)))
+a4167 4
+
+/* File format is OK. Do we support this camera? */
+/* Start with some useful defaults: */
+
+a4176 1
+ load_raw = NULL;
+d4203 1
+a4203 1
+ if (width < height) xmag = 2;
+a4580 3
+ } else if (!strcmp(make,"Phase One")) {
+ load_raw = phase_one_load_raw;
+ maximum = 0xffff;
+d5196 1
+a5196 1
+ "\nRaw Photo Decoder \"dcraw\" v7.30"
+@
+
+
1.262
log
@Added support for the Phase One P 20.