diff options
author | hub <hub> | 2005-06-28 01:57:48 +0000 |
---|---|---|
committer | hub <hub> | 2005-06-28 01:57:48 +0000 |
commit | a8ad974cf918bc82330dc2c16efa7de8292b16d2 (patch) | |
tree | 8e84770ba451efd87dd72cc4892210fefc0e6ba0 /dcraw | |
parent | 1115febc6d003ad005f7763fd45b7298a3956594 (diff) |
new version of dcraw.c,v
Diffstat (limited to 'dcraw')
-rw-r--r-- | dcraw/dcraw.c,v | 297 |
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. |