summaryrefslogtreecommitdiff
path: root/dcraw
diff options
context:
space:
mode:
authorHubert Figuiere <hub@figuiere.net>2011-03-22 21:44:58 -0700
committerHubert Figuiere <hub@figuiere.net>2011-03-22 21:44:58 -0700
commit2aeaffd018096d2b6b04aa6b8cafb0c97f1a6f57 (patch)
treeb7fd35bc2f6eada1d6073107c85cf284f2f7ca65 /dcraw
parente0320831058cc0fcc87936e77988cb26eaf282f6 (diff)
update dcraw to revision 1.441
Diffstat (limited to 'dcraw')
-rw-r--r--dcraw/dcraw.c,v1651
1 files changed, 1348 insertions, 303 deletions
diff --git a/dcraw/dcraw.c,v b/dcraw/dcraw.c,v
index b55c27a..4775262 100644
--- a/dcraw/dcraw.c,v
+++ b/dcraw/dcraw.c,v
@@ -1,10 +1,55 @@
-head 1.432;
+head 1.441;
access;
symbols;
locks; strict;
comment @ * @;
+1.441
+date 2011.02.19.04.26.53; author dcoffin; state Exp;
+branches;
+next 1.440;
+
+1.440
+date 2011.01.29.07.43.38; author dcoffin; state Exp;
+branches;
+next 1.439;
+
+1.439
+date 2010.11.11.12.43.11; author dcoffin; state Exp;
+branches;
+next 1.438;
+
+1.438
+date 2010.07.28.21.18.20; author dcoffin; state Exp;
+branches;
+next 1.437;
+
+1.437
+date 2010.06.27.00.23.33; author dcoffin; state Exp;
+branches;
+next 1.436;
+
+1.436
+date 2010.06.14.19.44.30; author dcoffin; state Exp;
+branches;
+next 1.435;
+
+1.435
+date 2010.06.11.07.03.46; author dcoffin; state Exp;
+branches;
+next 1.434;
+
+1.434
+date 2010.05.30.15.57.43; author dcoffin; state Exp;
+branches;
+next 1.433;
+
+1.433
+date 2010.05.28.01.29.41; author dcoffin; state Exp;
+branches;
+next 1.432;
+
1.432
date 2009.12.25.18.51.16; author dcoffin; state Exp;
branches;
@@ -2193,15 +2238,14 @@ desc
@
-1.432
+1.441
log
-@Support the Canon EOS-1D Mark IV and PowerShots G11 and S90.
-Support the Casio EX-Z750, Pentax K-x, Fuji SX200EXR, Sony A550.
+@Support high-ISO images from the Samsung WB2000.
@
text
@/*
dcraw.c -- Dave Coffin's raw photo decoder
- Copyright 1997-2009 by Dave Coffin, dcoffin a cybercom o net
+ Copyright 1997-2010 by Dave Coffin, dcoffin a cybercom o net
This is a command-line ANSI C program to convert raw photos from
any digital camera on any computer running any operating system.
@@ -2224,7 +2268,7 @@ text
$Date$
*/
-#define VERSION "8.99"
+#define VERSION "9.06"
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
@@ -2258,7 +2302,7 @@ text
#else
#define _(String) (String)
#endif
-#ifdef DJGPP
+#if defined(DJGPP) || defined(__MINGW32__)
#define fseeko fseek
#define ftello ftell
#else
@@ -2315,7 +2359,7 @@ off_t thumb_offset, meta_offset, profile_offset;
unsigned thumb_length, meta_length, profile_length;
unsigned thumb_misc, *oprof, fuji_layout, shot_select=0, multi_out=0;
unsigned tiff_nifds, tiff_samples, tiff_bps, tiff_compress;
-unsigned black, maximum, mix_green, raw_color, zero_is_bad;
+unsigned black, cblack[8], maximum, mix_green, raw_color, zero_is_bad;
unsigned zero_after_ff, is_raw, dng_version, is_foveon, data_error;
unsigned tile_width, tile_length, gpsdata[32], load_flags;
ushort raw_height, raw_width, height, width, top_margin, left_margin;
@@ -2368,7 +2412,7 @@ struct ph1 {
#define LIM(x,min,max) MAX(min,MIN(x,max))
#define ULIM(x,y,z) ((y) < (z) ? LIM(x,y,z) : LIM(x,z,y))
#define CLIP(x) LIM(x,0,65535)
-#define SWAP(a,b) { a ^= b; a ^= (b ^= a); }
+#define SWAP(a,b) { a=a+b; b=a-b; a=a-b; }
/*
In order to inline this calculation, I make the risky
@@ -2548,20 +2592,6 @@ void CLASS read_shorts (ushort *pixel, int count)
swab (pixel, pixel, count*2);
}
-void CLASS canon_black (double dark[2], int nblack)
-{
- int c, diff, row, col;
-
- if (!nblack) return;
- FORC(2) dark[c] /= nblack >> 1;
- if ((diff = dark[0] - dark[1]))
- for (row=0; row < height; row++)
- for (col=1; col < width; col+=2)
- BAYER(row,col) += diff;
- dark[1] += diff;
- black = (dark[0] + dark[1] + 1) / 2;
-}
-
void CLASS canon_600_fixed_wb (int temp)
{
static const short mul[4][5] = {
@@ -2914,10 +2944,9 @@ int CLASS canon_has_lowbits()
void CLASS canon_compressed_load_raw()
{
ushort *pixel, *prow, *huff[2];
- int nblocks, lowbits, i, c, row, r, col, save, val, nblack=0;
+ int nblocks, lowbits, i, c, row, r, col, save, val;
unsigned irow, icol;
int block, diffbuf[64], leaf, len, diff, carry=0, pnum=0, base[2];
- double dark[2] = { 0,0 };
crw_init_tables (tiff_compress, huff);
pixel = (ushort *) calloc (raw_width*8, sizeof *pixel);
@@ -2970,16 +2999,17 @@ void CLASS canon_compressed_load_raw()
if (irow >= height) continue;
for (col=0; col < raw_width; col++) {
icol = col - left_margin;
+ c = FC(irow,icol);
if (icol < width)
BAYER(irow,icol) = pixel[r*raw_width+col];
else if (col > 1 && (unsigned) (col-left_margin+2) > width+3)
- dark[icol & 1] += (nblack++,pixel[r*raw_width+col]);
+ cblack[c] += (cblack[4+c]++,pixel[r*raw_width+col]);
}
}
}
free (pixel);
FORC(2) free (huff[c]);
- canon_black (dark, nblack);
+ FORC4 if (cblack[4+c]) cblack[c] /= cblack[4+c];
}
/*
@@ -3102,8 +3132,7 @@ ushort * CLASS ljpeg_row (int jrow, struct jhead *jh)
void CLASS lossless_jpeg_load_raw()
{
- int jwide, jrow, jcol, val, jidx, i, j, row=0, col=0, nblack=0;
- double dark[2] = { 0,0 };
+ int jwide, jrow, jcol, val, jidx, c, i, j, row=0, col=0;
struct jhead jh;
int min=INT_MAX;
ushort *rp;
@@ -3129,18 +3158,19 @@ void CLASS lossless_jpeg_load_raw()
if (raw_width == 3984 && (col -= 2) < 0)
col += (row--,raw_width);
if ((unsigned) (row-top_margin) < height) {
+ c = FC(row-top_margin,col-left_margin);
if ((unsigned) (col-left_margin) < width) {
BAYER(row-top_margin,col-left_margin) = val;
if (min > val) min = val;
} else if (col > 1 && (unsigned) (col-left_margin+2) > width+3)
- dark[(col-left_margin) & 1] += (nblack++,val);
+ cblack[c] += (cblack[4+c]++,val);
}
if (++col >= raw_width)
col = (row++,0);
}
}
ljpeg_end (&jh);
- canon_black (dark, nblack);
+ FORC4 if (cblack[4+c]) cblack[c] /= cblack[4+c];
if (!strcasecmp(make,"KODAK"))
black = min;
}
@@ -3288,14 +3318,16 @@ void CLASS adobe_dng_load_raw_nc()
void CLASS pentax_load_raw()
{
- ushort bit[2][13], huff[4097];
- int row, col, diff, c, i;
+ ushort bit[2][15], huff[4097];
+ int dep, row, col, diff, c, i;
ushort vpred[2][2] = {{0,0},{0,0}}, hpred[2];
fseek (ifp, meta_offset, SEEK_SET);
- FORC(13) bit[0][c] = get2();
- FORC(13) bit[1][c] = fgetc(ifp);
- FORC(13)
+ dep = (get2() + 12) & 15;
+ fseek (ifp, 12, SEEK_CUR);
+ FORC(dep) bit[0][c] = get2();
+ FORC(dep) bit[1][c] = fgetc(ifp);
+ FORC(dep)
for (i=bit[0][c]; i <= ((bit[0][c]+(4096 >> bit[1][c])-1) & 4095); )
huff[++i] = bit[1][c] << 8 | c;
huff[0] = 12;
@@ -3306,9 +3338,10 @@ void CLASS pentax_load_raw()
diff = ljpeg_diff (huff);
if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
else hpred[col & 1] += diff;
- if ((unsigned) (row-top_margin) < height && col < width)
- BAYER(row-top_margin,col) = hpred[col & 1];
- if (hpred[col & 1] >> 12) derror();
+ if ((unsigned) (row-top_margin) < height &&
+ (unsigned) (col-left_margin) < width)
+ BAYER(row-top_margin,col-left_margin) = hpred[col & 1];
+ if (hpred[col & 1] >> tiff_bps) derror();
}
}
@@ -3760,12 +3793,13 @@ void CLASS phase_one_load_raw()
merror (pixel, "phase_one_load_raw()");
for (row=0; row < height; row++) {
read_shorts (pixel, raw_width);
- for (col=0; col < raw_width; col+=2) {
- a = pixel[col+0] ^ akey;
- b = pixel[col+1] ^ bkey;
- pixel[col+0] = (a & mask) | (b & ~mask);
- pixel[col+1] = (b & mask) | (a & ~mask);
- }
+ if (ph1.format)
+ for (col=0; col < raw_width; col+=2) {
+ a = pixel[col+0] ^ akey;
+ b = pixel[col+1] ^ bkey;
+ pixel[col+0] = (a & mask) | (b & ~mask);
+ pixel[col+1] = (b & mask) | (a & ~mask);
+ }
for (col=0; col < width; col++)
BAYER(row,col) = pixel[col+left_margin];
}
@@ -3951,6 +3985,7 @@ void CLASS imacon_full_load_raw()
void CLASS packed_load_raw()
{
int vbits=0, bwide, pwide, rbits, bite, half, irow, row, col, val, i;
+ int zero=0;
UINT64 bitbuf=0;
if (raw_width * 8 >= width * tiff_bps) /* Is raw_width in bytes? */
@@ -3982,9 +4017,11 @@ void CLASS packed_load_raw()
val = bitbuf << (64-tiff_bps-vbits) >> (64-tiff_bps);
i = (col ^ (bite == 24)) - left_margin;
if ((unsigned) i < width)
- BAYER(row,i) = val << (load_flags >> 6);
- else if (load_flags & 32)
+ BAYER(row,i) = val;
+ else if (load_flags & 32) {
black += val;
+ zero += !val;
+ }
if (load_flags & 1 && (col % 10) == 9 &&
fgetc(ifp) && col < width+left_margin) derror();
}
@@ -3992,6 +4029,8 @@ void CLASS packed_load_raw()
}
if (load_flags & 32 && pwide > width)
black /= (pwide - width) * height;
+ if (zero*4 > (pwide - width) * height)
+ black = 0;
}
void CLASS unpacked_load_raw()
@@ -4007,7 +4046,7 @@ void CLASS unpacked_load_raw()
read_shorts (pixel, width);
fseek (ifp, 2*(raw_width - width), SEEK_CUR);
for (col=0; col < width; col++)
- if ((BAYER2(row,col) = pixel[col]) >> bits) derror();
+ if ((BAYER2(row,col) = pixel[col] >> load_flags) >> bits) derror();
}
free (pixel);
}
@@ -4016,14 +4055,16 @@ void CLASS nokia_load_raw()
{
uchar *data, *dp;
ushort *pixel, *pix;
- int dwide, row, c;
+ int rev, dwide, row, c;
+ rev = 3 * (order == 0x4949);
dwide = raw_width * 5 / 4;
data = (uchar *) malloc (dwide + raw_width*2);
merror (data, "nokia_load_raw()");
pixel = (ushort *) (data + dwide);
for (row=0; row < raw_height; row++) {
- if (fread (data, 1, dwide, ifp) < dwide) derror();
+ if (fread (data+dwide, 1, dwide, ifp) < dwide) derror();
+ FORC(dwide) data[c] = data[dwide+(c ^ rev)];
for (dp=data, pix=pixel; pix < pixel+raw_width; dp+=5, pix+=4)
FORC4 pix[c] = (dp[c] << 2) | (dp[4] >> (c << 1) & 3);
if (row < top_margin)
@@ -4702,7 +4743,7 @@ void CLASS sony_arw2_load_raw()
bit += 7;
}
for (i=0; i < 16; i++, col+=2)
- BAYER(row,col) = curve[pix[i] << 1] >> 1;
+ BAYER(row,col) = curve[pix[i] << 1] >> 2;
col -= col & 1 ? 1:31;
}
}
@@ -5593,6 +5634,8 @@ void CLASS subtract (const char *fname)
BAYER(row,col) = MAX (BAYER(row,col) - ntohs(pixel[col]), 0);
}
free (pixel);
+ fclose (fp);
+ memset (cblack, 0, sizeof cblack);
black = 0;
}
@@ -5767,7 +5810,7 @@ void CLASS hat_transform (float *temp, float *base, int st, int size, int sc)
void CLASS wavelet_denoise()
{
float *fimg=0, *temp, thold, mul[2], avg, diff;
- int scale=1, size, lev, hpass, lpass, row, col, nc, c, i, wlast;
+ int scale=1, size, lev, hpass, lpass, row, col, nc, c, i, wlast, blk[2];
ushort *window[4];
static const float noise[] =
{ 0.8002,0.2735,0.1202,0.0585,0.0291,0.0152,0.0080,0.0044 };
@@ -5777,6 +5820,7 @@ void CLASS wavelet_denoise()
while (maximum << scale < 0x10000) scale++;
maximum <<= --scale;
black <<= scale;
+ FORC4 cblack[c] <<= scale;
if ((size = iheight*iwidth) < 0x15550000)
fimg = (float *) malloc ((size*3 + iheight + iwidth) * sizeof *fimg);
merror (fimg, "wavelet_denoise()");
@@ -5811,8 +5855,10 @@ void CLASS wavelet_denoise()
image[i][c] = CLIP(SQR(fimg[i]+fimg[lpass+i])/0x10000);
}
if (filters && colors == 3) { /* pull G1 and G3 closer together */
- for (row=0; row < 2; row++)
+ for (row=0; row < 2; row++) {
mul[row] = 0.125 * pre_mul[FC(row+1,0) | 1] / pre_mul[FC(row,0) | 1];
+ blk[row] = cblack[FC(row,0) | 1];
+ }
for (i=0; i < 4; i++)
window[i] = (ushort *) fimg + width*i;
for (wlast=-1, row=1; row < height-1; row++) {
@@ -5825,8 +5871,8 @@ void CLASS wavelet_denoise()
thold = threshold/512;
for (col = (FC(row,0) & 1)+1; col < width-1; col+=2) {
avg = ( window[0][col-1] + window[0][col+1] +
- window[2][col-1] + window[2][col+1] - black*4 )
- * mul[row & 1] + (window[1][col] - black) * 0.5 + black;
+ window[2][col-1] + window[2][col+1] - blk[~row & 1]*4 )
+ * mul[row & 1] + (window[1][col] + blk[row & 1]) * 0.5;
avg = avg < 0 ? 0 : sqrt(avg);
diff = sqrt(BAYER(row,col)) - avg;
if (diff < -thold) diff += thold;
@@ -5847,6 +5893,7 @@ void CLASS scale_colors()
float scale_mul[4], fr, fc;
ushort *img=0, *pix;
+ FORC4 cblack[c] += black;
if (user_mul[0])
memcpy (pre_mul, user_mul, sizeof pre_mul);
if (use_auto_wb || (use_camera_wb && cam_mul[0] == -1)) {
@@ -5865,7 +5912,7 @@ void CLASS scale_colors()
} else
val = image[y*width+x][c];
if (val > maximum-25) goto skip_block;
- if ((val -= black) < 0) val = 0;
+ if ((val -= cblack[c]) < 0) val = 0;
sum[c] += val;
sum[c+4]++;
if (filters) break;
@@ -5880,7 +5927,7 @@ skip_block: ;
for (row=0; row < 8; row++)
for (col=0; col < 8; col++) {
c = FC(row,col);
- if ((val = white[row][col] - black) > 0)
+ if ((val = white[row][col] - cblack[c]) > 0)
sum[c] += val;
sum[c+4]++;
}
@@ -5914,7 +5961,7 @@ skip_block: ;
for (i=0; i < size*4; i++) {
val = image[0][i];
if (!val) continue;
- val -= black;
+ val -= cblack[i & 3];
val *= scale_mul[i & 3];
image[0][i] = CLIP(val);
}
@@ -6048,7 +6095,7 @@ void CLASS lin_interpolate()
"Interpolation using a Threshold-based variable number of gradients"
- described in http://scien.stanford.edu/class/psych221/projects/99/tingchen/algodep/vargra.html
+ described in http://scien.stanford.edu/pages/labsite/1999/psych221/projects/99/tingchen/algodep/vargra.html
I've extended the basic idea to work with non-Bayer filter arrays.
Gradients are numbered clockwise from NW=0 to W=7.
@@ -6617,8 +6664,11 @@ void CLASS parse_makernote (int base, int uptag)
else if (!strcmp (buf,"AOC") ||
!strcmp (buf,"QVC"))
fseek (ifp, -4, SEEK_CUR);
- else fseek (ifp, -10, SEEK_CUR);
-
+ else {
+ fseek (ifp, -10, SEEK_CUR);
+ if (!strncmp(make,"SAMSUNG",7))
+ base = ftell(ifp);
+ }
entries = get2();
if (entries > 1000) return;
while (entries--) {
@@ -6654,15 +6704,30 @@ void CLASS parse_makernote (int base, int uptag)
cam_mul[0] = getreal(type);
cam_mul[2] = getreal(type);
}
+ if (tag == 0xd && type == 7 && get2() == 0xaaaa) {
+ fread (buf97, 1, sizeof buf97, ifp);
+ i = (uchar *) memmem (buf97, sizeof buf97,"\xbb\xbb",2) - buf97 + 10;
+ if (i < 70 && buf97[i] < 3)
+ flip = "065"[buf97[i]]-'0';
+ }
if (tag == 0x10 && type == 4)
unique_id = get4();
if (tag == 0x11 && is_raw && !strncmp(make,"NIKON",5)) {
fseek (ifp, get4()+base, SEEK_SET);
parse_tiff_ifd (base);
}
- if (tag == 0x14 && len == 2560 && type == 7) {
- fseek (ifp, 1248, SEEK_CUR);
- goto get2_256;
+ if (tag == 0x14 && type == 7) {
+ if (len == 2560) {
+ fseek (ifp, 1248, SEEK_CUR);
+ goto get2_256;
+ }
+ fread (buf, 1, 10, ifp);
+ if (!strncmp(buf,"NRW ",4)) {
+ fseek (ifp, strcmp(buf+4,"0100") ? 46:1546, SEEK_CUR);
+ cam_mul[0] = get4() << 2;
+ cam_mul[1] = get4() + get4();
+ cam_mul[2] = get4() << 2;
+ }
}
if (tag == 0x15 && type == 2 && is_raw)
fread (model, 64, 1, ifp);
@@ -6717,6 +6782,13 @@ void CLASS parse_makernote (int base, int uptag)
fread (buf97, 324, 1, ifp);
}
}
+ if (tag == 0xa1 && type == 7) {
+ type = order;
+ order = 0x4949;
+ fseek (ifp, 140, SEEK_CUR);
+ FORC3 cam_mul[c] = get4();
+ order = type;
+ }
if (tag == 0xa4 && type == 3) {
fseek (ifp, wbi*48, SEEK_CUR);
FORC3 cam_mul[c] = get2();
@@ -6734,14 +6806,13 @@ void CLASS parse_makernote (int base, int uptag)
if (tag == 0x200 && len == 3)
shot_order = (get4(),get4());
if (tag == 0x200 && len == 4)
- black = (get2()+get2()+get2()+get2())/4;
+ FORC4 cblack[c ^ c >> 1] = get2();
if (tag == 0x201 && len == 4)
goto get2_rggb;
- if (tag == 0x220 && len == 53)
- meta_offset = ftell(ifp) + 14;
- if (tag == 0x401 && type == 4 && len == 4) {
- black = (get4()+get4()+get4()+get4())/4;
- }
+ if (tag == 0x220 && type == 7)
+ meta_offset = ftell(ifp);
+ if (tag == 0x401 && type == 4 && len == 4)
+ FORC4 cblack[c ^ c >> 1] = get4();
if (tag == 0xe01) { /* Nikon Capture Note */
type = order;
order = 0x4949;
@@ -6772,8 +6843,7 @@ void CLASS parse_makernote (int base, int uptag)
for (i=0; i < 3; i++)
FORC3 cmatrix[i][c] = ((short) get2()) / 256.0;
if ((tag == 0x1012 || tag == 0x20400600) && len == 4)
- for (black = i=0; i < 4; i++)
- black += get2() << 2;
+ FORC4 cblack[c ^ c >> 1] = get2();
if (tag == 0x1017 || tag == 0x20400100)
cam_mul[0] = get2() / 256.0;
if (tag == 0x1018 || tag == 0x20400100)
@@ -6793,7 +6863,7 @@ get2_256:
if (tag == 0x2040)
parse_makernote (base, 0x2040);
if (tag == 0xb028) {
- fseek (ifp, get4(), SEEK_SET);
+ fseek (ifp, get4()+base, SEEK_SET);
parse_thumb_note (base, 136, 137);
}
if (tag == 0x4001 && len > 500) {
@@ -6804,6 +6874,10 @@ get2_rggb:
fseek (ifp, 22, SEEK_CUR);
FORC4 sraw_mul[c ^ (c >> 1)] = get2();
}
+ if (tag == 0xa021)
+ FORC4 cam_mul[c ^ (c >> 1)] = get4();
+ if (tag == 0xa028)
+ FORC4 cam_mul[c ^ (c >> 1)] -= get4();
next:
fseek (ifp, save, SEEK_SET);
}
@@ -6832,6 +6906,7 @@ void CLASS get_timestamp (int reversed)
return;
t.tm_year -= 1900;
t.tm_mon -= 1;
+ t.tm_isdst = -1;
if (mktime(&t) > 0)
timestamp = mktime(&t);
}
@@ -6841,7 +6916,7 @@ void CLASS parse_exif (int base)
unsigned kodak, entries, tag, type, len, save, c;
double expo;
- kodak = !strncmp(make,"EASTMAN",7);
+ kodak = !strncmp(make,"EASTMAN",7) && tiff_nifds < 3;
entries = get2();
while (entries--) {
tiff_get (base, &tag, &type, &len, &save);
@@ -6982,7 +7057,7 @@ void CLASS parse_kodak_ifd (int base)
unsigned entries, tag, type, len, save;
int i, c, wbi=-2, wbtemp=6500;
float mul[3]={1,1,1}, num;
- static const int wbtag[]={ 0xfa25,0xfa28,0xfa27,0xfa29,-1,-1,0xfa2a };
+ static const int wbtag[] = { 64037,64040,64039,64041,-1,-1,64042 };
entries = get2();
if (entries > 1024) return;
@@ -7005,22 +7080,26 @@ void CLASS parse_kodak_ifd (int base)
}
if (tag == 2317) linear_table (len);
if (tag == 6020) iso_speed = getint(type);
- if (tag == 0xfa0d) wbi = fgetc(ifp);
+ if (tag == 64013) wbi = fgetc(ifp);
if ((unsigned) wbi < 7 && tag == wbtag[wbi])
FORC3 cam_mul[c] = get4();
+ if (tag == 64019) width = getint(type);
+ if (tag == 64020) height = (getint(type)+1) & -2;
fseek (ifp, save, SEEK_SET);
}
}
void CLASS parse_minolta (int base);
+int CLASS parse_tiff (int base);
int CLASS parse_tiff_ifd (int base)
{
unsigned entries, tag, type, len, plen=16, save;
int ifd, use_cm=0, cfa, i, j, c, ima_len=0;
+ int blrr=1, blrc=1, dblack[] = { 0,0,0,0 };
char software[64], *cbuf, *cp;
uchar cfa_pat[16], cfa_pc[] = { 0,1,2,3 }, tab[256];
- double dblack, cc[4][4], cm[4][3], cam_xyz[4][3], num;
+ double cc[4][4], cm[4][3], cam_xyz[4][3], num;
double ab[]={ 1,1,1,1 }, asn[] = { 0,0,0,0 }, xyz[] = { 1,1,1 };
unsigned sony_curve[] = { 0,0,0,0,0,4095 };
unsigned *buf, sony_offset=0, sony_length=0, sony_key=0;
@@ -7038,6 +7117,10 @@ int CLASS parse_tiff_ifd (int base)
while (entries--) {
tiff_get (base, &tag, &type, &len, &save);
switch (tag) {
+ case 5: width = get2(); break;
+ case 6: height = get2(); break;
+ case 7: width += get2(); break;
+ case 9: filters = get2(); break;
case 17: case 18:
if (type == 3 && len == 1)
cam_mul[(tag-17)*2] = get2() / 256.0;
@@ -7058,15 +7141,19 @@ int CLASS parse_tiff_ifd (int base)
thumb_offset = ftell(ifp) - 2;
thumb_length = len;
break;
- case 2: case 256: /* ImageWidth */
+ case 61440: /* Fuji HS10 table */
+ parse_tiff_ifd (base);
+ break;
+ case 2: case 256: case 61441: /* ImageWidth */
tiff_ifd[ifd].width = getint(type);
break;
- case 3: case 257: /* ImageHeight */
+ case 3: case 257: case 61442: /* ImageHeight */
tiff_ifd[ifd].height = getint(type);
break;
case 258: /* BitsPerSample */
+ case 61443:
tiff_ifd[ifd].samples = len & 7;
- tiff_ifd[ifd].bps = get2();
+ tiff_ifd[ifd].bps = getint(type);
break;
case 259: /* Compression */
tiff_ifd[ifd].comp = get2();
@@ -7088,16 +7175,22 @@ int CLASS parse_tiff_ifd (int base)
load_raw = &CLASS panasonic_load_raw;
load_flags = 0x2008;
case 273: /* StripOffset */
- case 513:
+ case 513: /* JpegIFOffset */
+ case 61447:
tiff_ifd[ifd].offset = get4()+base;
- if (!tiff_ifd[ifd].bps) {
+ if (!tiff_ifd[ifd].bps && tiff_ifd[ifd].offset > 0) {
fseek (ifp, tiff_ifd[ifd].offset, SEEK_SET);
if (ljpeg_start (&jh, 1)) {
tiff_ifd[ifd].comp = 6;
- tiff_ifd[ifd].width = jh.wide << (jh.clrs == 2);
+ tiff_ifd[ifd].width = jh.wide;
tiff_ifd[ifd].height = jh.high;
tiff_ifd[ifd].bps = jh.bits;
tiff_ifd[ifd].samples = jh.clrs;
+ if (!(jh.sraw || (jh.clrs & 1)))
+ tiff_ifd[ifd].width *= jh.clrs;
+ i = order;
+ parse_tiff (tiff_ifd[ifd].offset + 12);
+ order = i;
}
}
break;
@@ -7109,8 +7202,12 @@ int CLASS parse_tiff_ifd (int base)
break;
case 279: /* StripByteCounts */
case 514:
+ case 61448:
tiff_ifd[ifd].bytes = get4();
break;
+ case 61454:
+ FORC3 cam_mul[(4-c) % 3] = getint(type);
+ break;
case 305: case 11: /* Software */
fgets (software, 64, ifp);
if (!strncmp(software,"Adobe",5) ||
@@ -7174,7 +7271,9 @@ int CLASS parse_tiff_ifd (int base)
FORC4 cam_mul[c ^ (c < 2)] = get2();
break;
case 29459:
- FORC4 cam_mul[c ^ (c >> 1)] = get2();
+ FORC4 cam_mul[c] = get2();
+ i = (cam_mul[1] == 1024 && cam_mul[2] == 1024) << 1;
+ SWAP (cam_mul[i],cam_mul[i+1])
break;
case 33405: /* Model2 */
fgets (model2, 64, ifp);
@@ -7332,12 +7431,30 @@ guess_cfa_pc:
case 50712: /* LinearizationTable */
linear_table (len);
break;
+ case 50713: /* BlackLevelRepeatDim */
+ blrr = get2();
+ blrc = get2();
+ break;
+ case 61450:
+ blrr = blrc = 2;
case 50714: /* BlackLevel */
+ black = getreal(type);
+ if (!filters || !~filters) break;
+ dblack[0] = black;
+ dblack[1] = (blrc == 2) ? getreal(type):dblack[0];
+ dblack[2] = (blrr == 2) ? getreal(type):dblack[0];
+ dblack[3] = (blrc == 2 && blrr == 2) ? getreal(type):dblack[1];
+ if (colors == 3)
+ filters |= ((filters >> 2 & 0x22222222) |
+ (filters << 2 & 0x88888888)) & filters << 1;
+ FORC4 cblack[filters >> (c << 1) & 3] = dblack[c];
+ black = 0;
+ break;
case 50715: /* BlackLevelDeltaH */
case 50716: /* BlackLevelDeltaV */
- for (dblack=i=0; i < len; i++)
- dblack += getreal(type);
- black += dblack/len + 0.5;
+ for (num=i=0; i < len; i++)
+ num += getreal(type);
+ black += num/len + 0.5;
break;
case 50717: /* WhiteLevel */
maximum = getint(type);
@@ -7428,21 +7545,26 @@ guess_cfa_pc:
return 0;
}
-void CLASS parse_tiff (int base)
+int CLASS parse_tiff (int base)
{
- int doff, max_samp=0, raw=-1, thm=-1, i;
- struct jhead jh;
+ int doff;
fseek (ifp, base, SEEK_SET);
order = get2();
- if (order != 0x4949 && order != 0x4d4d) return;
+ if (order != 0x4949 && order != 0x4d4d) return 0;
get2();
- memset (tiff_ifd, 0, sizeof tiff_ifd);
- tiff_nifds = 0;
while ((doff = get4())) {
fseek (ifp, doff+base, SEEK_SET);
if (parse_tiff_ifd (base)) break;
}
+ return 1;
+}
+
+void CLASS apply_tiff()
+{
+ int max_samp=0, raw=-1, thm=-1, i;
+ struct jhead jh;
+
thumb_misc = 16;
if (thumb_offset) {
fseek (ifp, thumb_offset, SEEK_SET);
@@ -7469,8 +7591,8 @@ void CLASS parse_tiff (int base)
raw = i;
}
}
- fuji_width *= (raw_width+1)/2;
- if (tiff_ifd[0].flip) tiff_flip = tiff_ifd[0].flip;
+ for (i=tiff_nifds; i--; )
+ if (tiff_ifd[i].flip) tiff_flip = tiff_ifd[i].flip;
if (raw >= 0 && !load_raw)
switch (tiff_compress) {
case 0: case 1:
@@ -7485,9 +7607,8 @@ void CLASS parse_tiff (int base)
}
if (tiff_ifd[raw].bytes*5 == raw_width*raw_height*8) {
tiff_bps = 12;
- maximum = 0xffff;
load_raw = &CLASS packed_load_raw;
- load_flags = 273;
+ load_flags = 17;
}
break;
case 6: case 7: case 99:
@@ -7503,9 +7624,10 @@ void CLASS parse_tiff (int base)
raw_height += 8;
load_raw = &CLASS sony_arw_load_raw; break;
}
- load_flags = 79;
+ load_flags = 15;
case 32769:
load_flags++;
+ case 32770:
case 32773:
load_raw = &CLASS packed_load_raw; break;
case 34713:
@@ -7939,6 +8061,11 @@ void CLASS parse_fuji (int offset)
FORC4 cam_mul[c ^ 1] = get2();
fseek (ifp, save+len, SEEK_SET);
}
+ if (!raw_height) {
+ filters = 0x16161616;
+ load_raw = &CLASS packed_load_raw;
+ load_flags = 24;
+ }
height <<= fuji_layout;
width >>= fuji_layout;
}
@@ -7963,7 +8090,7 @@ int CLASS parse_jpeg (int offset)
hlen = get4();
if (get4() == 0x48454150) /* "HEAP" */
parse_ciff (save+hlen, len-hlen);
- parse_tiff (save+6);
+ if (parse_tiff (save+6)) apply_tiff();
fseek (ifp, save+len, SEEK_SET);
}
return 1;
@@ -8212,6 +8339,8 @@ void CLASS adobe_coeff (const char *make, const char *model)
{ 6071,-747,-856,-7653,15365,2441,-2025,2553,7315 } },
{ "Canon EOS 50D", 0, 0x3d93,
{ 4920,616,-593,-6493,13964,2784,-1774,3178,7005 } },
+ { "Canon EOS 60D", 0, 0x2ff7,
+ { 6719,-994,-925,-4408,12426,2211,-887,2129,6051 } },
{ "Canon EOS 300D", 0, 0xfa0,
{ 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } },
{ "Canon EOS 350D", 0, 0xfff,
@@ -8222,6 +8351,8 @@ void CLASS adobe_coeff (const char *make, const char *model)
{ 5784,-262,-821,-7539,15064,2672,-1982,2681,7427 } },
{ "Canon EOS 500D", 0, 0x3479,
{ 4763,712,-646,-6821,14399,2640,-1921,3276,6561 } },
+ { "Canon EOS 550D", 0, 0x3dd7,
+ { 6941,-1164,-857,-3825,11597,2534,-416,1540,6039 } },
{ "Canon EOS 1000D", 0, 0xe43,
{ 6771,-1139,-977,-7818,15123,2928,-1244,1437,7533 } },
{ "Canon EOS-1Ds Mark III", 0, 0x3bb0,
@@ -8243,7 +8374,7 @@ void CLASS adobe_coeff (const char *make, const char *model)
{ "Canon EOS", 0, 0,
{ 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } },
{ "Canon PowerShot A530", 0, 0,
- { 0 } }, /* don't want the A5 matrix */
+ { 0 } }, /* don't want the A5 matrix */
{ "Canon PowerShot A50", 0, 0,
{ -5300,9846,1776,3436,684,3939,-5540,9879,6200,-1404,11175,217 } },
{ "Canon PowerShot A5", 0, 0,
@@ -8252,6 +8383,8 @@ void CLASS adobe_coeff (const char *make, const char *model)
{ 11093,-3906,-1028,-5047,12492,2879,-1003,1750,5561 } },
{ "Canon PowerShot G11", 0, 0,
{ 12177,-4817,-1069,-1612,9864,2049,-98,850,4471 } },
+ { "Canon PowerShot G12", 0, 0,
+ { 13244,-5501,-1248,-1508,9858,1935,-270,1083,4366 } },
{ "Canon PowerShot G1", 0, 0,
{ -4778,9467,2172,4743,-1141,4344,-5146,9908,6077,-1566,11051,557 } },
{ "Canon PowerShot G2", 0, 0,
@@ -8284,6 +8417,8 @@ void CLASS adobe_coeff (const char *make, const char *model)
{ 9976,-3810,-832,-7115,14463,2906,-901,989,7889 } },
{ "Canon PowerShot S90", 0, 0,
{ 12374,-5016,-1049,-1677,9902,2078,-83,852,4683 } },
+ { "Canon PowerShot S95", 0, 0,
+ { 13440,-5896,-1279,-1236,9598,1931,-180,1001,4651 } },
{ "Canon PowerShot A470", 0, 0, /* DJC */
{ 12513,-4407,-1242,-2680,10276,2405,-878,2215,4734 } },
{ "Canon PowerShot A610", 0, 0, /* DJC */
@@ -8308,6 +8443,8 @@ void CLASS adobe_coeff (const char *make, const char *model)
{ 11634,-3924,-1128,-4968,12954,2015,-1588,2648,7206 } },
{ "CASIO EX-Z750", 0, 0, /* DJC */
{ 10819,-3873,-1099,-4903,13730,1175,-1755,3751,4632 } },
+ { "CASIO EX-Z10", 128, 0xfff, /* DJC */
+ { 9790,-3338,-603,-2321,10222,2099,-344,1273,4799 } },
{ "CINE 650", 0, 0,
{ 3390,480,-500,-800,3610,340,-550,2336,1192 } },
{ "CINE 660", 0, 0,
@@ -8328,6 +8465,8 @@ void CLASS adobe_coeff (const char *make, const char *model)
{ 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } },
{ "FUJIFILM FinePix S100FS", 514, 0,
{ 11521,-4355,-1065,-6524,13767,3058,-1466,1984,6045 } },
+ { "FUJIFILM FinePix S200EXR", 512, 0x3fff,
+ { 0 } },
{ "FUJIFILM FinePix S20Pro", 0, 0,
{ 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } },
{ "FUJIFILM FinePix S2Pro", 128, 0,
@@ -8338,9 +8477,9 @@ void CLASS adobe_coeff (const char *make, const char *model)
{ 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } },
{ "FUJIFILM FinePix S5000", 0, 0,
{ 8754,-2732,-1019,-7204,15069,2276,-1702,2334,6982 } },
- { "FUJIFILM FinePix S5100", 0, 0x3e00,
+ { "FUJIFILM FinePix S5100", 0, 0,
{ 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } },
- { "FUJIFILM FinePix S5500", 0, 0x3e00,
+ { "FUJIFILM FinePix S5500", 0, 0,
{ 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } },
{ "FUJIFILM FinePix S5200", 0, 0,
{ 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } },
@@ -8362,6 +8501,8 @@ void CLASS adobe_coeff (const char *make, const char *model)
{ 21461,-10807,-1441,-2332,10599,1999,289,875,7703 } },
{ "FUJIFILM IS Pro", 0, 0,
{ 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } },
+ { "FUJIFILM FinePix HS10 HS11", 0, 0xf68,
+ { 12440,-3954,-1183,-1123,9674,1708,-83,1614,4086 } },
{ "Imacon Ixpress", 0, 0, /* DJC */
{ 7025,-1415,-704,-5188,13765,1424,-1248,2742,6038 } },
{ "KODAK NC2000", 0, 0,
@@ -8410,6 +8551,8 @@ void CLASS adobe_coeff (const char *make, const char *model)
{ 12805,-4662,-1376,-7480,15267,2360,-1626,2194,7904 } },
{ "KODAK EasyShare Z980", 0, 0,
{ 11313,-3559,-1101,-3893,11891,2257,-1214,2398,4908 } },
+ { "KODAK EasyShare Z981", 0, 0,
+ { 12729,-4717,-1188,-1367,9187,2582,274,860,4411 } },
{ "KODAK EASYSHARE Z1015", 0, 0xef1,
{ 11265,-4286,-992,-4694,12343,2647,-1090,1523,5447 } },
{ "Leaf CMost", 0, 0,
@@ -8464,6 +8607,8 @@ void CLASS adobe_coeff (const char *make, const char *model)
{ 10231,-2769,-1255,-8301,15900,2552,-797,680,7148 } },
{ "NIKON D3000", 0, 0,
{ 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } },
+ { "NIKON D3100", 0, 0,
+ { 7911,-2167,-813,-5327,13150,2408,-1288,2483,7968 } },
{ "NIKON D300", 0, 0,
{ 9030,-1992,-715,-8465,16302,2255,-2689,3217,8069 } },
{ "NIKON D3X", 0, 0,
@@ -8482,6 +8627,8 @@ void CLASS adobe_coeff (const char *make, const char *model)
{ 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } },
{ "NIKON D60", 0, 0,
{ 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } },
+ { "NIKON D7000", 0, 0,
+ { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } },
{ "NIKON D700", 0, 0,
{ 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } },
{ "NIKON D70", 0, 0,
@@ -8498,6 +8645,8 @@ void CLASS adobe_coeff (const char *make, const char *model)
{ 13142,-4152,-1596,-4655,12374,2282,-1769,2696,6711} },
{ "NIKON E2500", 0, 0,
{ -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
+ { "NIKON E3200", 0, 0, /* DJC */
+ { 9846,-2085,-1019,-3278,11109,2170,-774,2134,5745 } },
{ "NIKON E4300", 0, 0, /* copied from Minolta DiMAGE Z2 */
{ 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 } },
{ "NIKON E4500", 0, 0,
@@ -8516,6 +8665,8 @@ void CLASS adobe_coeff (const char *make, const char *model)
{ 7971,-2314,-913,-8451,15762,2894,-1442,1520,7610 } },
{ "NIKON COOLPIX P6000", 0, 0,
{ 9698,-3367,-914,-4706,12584,2368,-837,968,5801 } },
+ { "NIKON COOLPIX P7000", 0, 0,
+ { 11432,-3679,-1111,-3169,11239,2202,-791,1380,4455 } },
{ "OLYMPUS C5050", 0, 0,
{ 10508,-3124,-1273,-6079,14294,1901,-1653,2306,6237 } },
{ "OLYMPUS C5060", 0, 0,
@@ -8526,11 +8677,11 @@ void CLASS adobe_coeff (const char *make, const char *model)
{ 10793,-3791,-1146,-7498,15177,2488,-1390,1577,7321 } },
{ "OLYMPUS C80", 0, 0,
{ 8606,-2509,-1014,-8238,15714,2703,-942,979,7760 } },
- { "OLYMPUS E-10", 0, 0xffc0,
+ { "OLYMPUS E-10", 0, 0xffc,
{ 12745,-4500,-1416,-6062,14542,1580,-1934,2256,6603 } },
- { "OLYMPUS E-1", 0, 0xfff0,
+ { "OLYMPUS E-1", 0, 0,
{ 11846,-4767,-945,-7027,15878,1089,-2699,4122,8311 } },
- { "OLYMPUS E-20", 0, 0xffc0,
+ { "OLYMPUS E-20", 0, 0xffc,
{ 13173,-4732,-1499,-5807,14036,1895,-2045,2452,7142 } },
{ "OLYMPUS E-300", 0, 0,
{ 7828,-1761,-348,-5788,14071,1830,-2853,4518,6557 } },
@@ -8540,7 +8691,7 @@ void CLASS adobe_coeff (const char *make, const char *model)
{ 8144,-1861,-1111,-7763,15894,1929,-1865,2542,7607 } },
{ "OLYMPUS E-3", 0, 0xf99,
{ 9487,-2875,-1115,-7533,15606,2010,-1618,2100,7389 } },
- { "OLYMPUS E-400", 0, 0xfff0,
+ { "OLYMPUS E-400", 0, 0,
{ 6169,-1483,-21,-7107,14761,2536,-2904,3580,8568 } },
{ "OLYMPUS E-410", 0, 0xf6a,
{ 8856,-2582,-1026,-7761,15766,2082,-2009,2575,7469 } },
@@ -8548,16 +8699,24 @@ void CLASS adobe_coeff (const char *make, const char *model)
{ 8746,-2425,-1095,-7594,15612,2073,-1780,2309,7416 } },
{ "OLYMPUS E-450", 0, 0xfd2,
{ 8745,-2425,-1095,-7594,15613,2073,-1780,2309,7416 } },
- { "OLYMPUS E-500", 0, 0xfff0,
+ { "OLYMPUS E-500", 0, 0,
{ 8136,-1968,-299,-5481,13742,1871,-2556,4205,6630 } },
{ "OLYMPUS E-510", 0, 0xf6a,
{ 8785,-2529,-1033,-7639,15624,2112,-1783,2300,7817 } },
{ "OLYMPUS E-520", 0, 0xfd2,
{ 8344,-2322,-1020,-7596,15635,2048,-1748,2269,7287 } },
- { "OLYMPUS E-620", 0, 0xfb9,
+ { "OLYMPUS E-5", 0, 0,
+ { 11200,-3783,-1325,-4576,12593,2206,-695,1742,7504 } },
+ { "OLYMPUS E-600", 0, 0xfaf,
+ { 8453,-2198,-1092,-7609,15681,2008,-1725,2337,7824 } },
+ { "OLYMPUS E-620", 0, 0xfaf,
{ 8453,-2198,-1092,-7609,15681,2008,-1725,2337,7824 } },
{ "OLYMPUS E-P1", 0, 0xffd,
{ 8343,-2050,-1021,-7715,15705,2103,-1831,2380,8235 } },
+ { "OLYMPUS E-P2", 0, 0xffd,
+ { 8343,-2050,-1021,-7715,15705,2103,-1831,2380,8235 } },
+ { "OLYMPUS E-PL1", 0, 0,
+ { 11408,-4289,-1215,-4286,12385,2118,-387,1467,7787 } },
{ "OLYMPUS SP350", 0, 0,
{ 12078,-4836,-1069,-6671,14306,2578,-786,939,7418 } },
{ "OLYMPUS SP3", 0, 0,
@@ -8596,40 +8755,72 @@ void CLASS adobe_coeff (const char *make, const char *model)
{ 11057,-3604,-1155,-5152,13046,2329,-282,375,8104 } },
{ "PENTAX K-x", 0, 0,
{ 8843,-2837,-625,-5025,12644,2668,-411,1234,7410 } },
+ { "PENTAX K-r", 0, 0,
+ { 9895,-3077,-850,-5304,13035,2521,-883,1768,6936 } },
+ { "PENTAX K-5", 0, 0,
+ { 8713,-2833,-743,-4342,11900,2772,-722,1543,6247 } },
{ "PENTAX K-7", 0, 0,
{ 9142,-2947,-678,-8648,16967,1663,-2224,2898,8615 } },
- { "Panasonic DMC-FZ8", 0, 0xf7f0,
+ { "PENTAX 645D", 0, 0x3e00,
+ { 10646,-3593,-1158,-3329,11699,1831,-667,2874,6287 } },
+ { "Panasonic DMC-FZ8", 0, 0xf7f,
{ 8986,-2755,-802,-6341,13575,3077,-1476,2144,6379 } },
{ "Panasonic DMC-FZ18", 0, 0,
{ 9932,-3060,-935,-5809,13331,2753,-1267,2155,5575 } },
- { "Panasonic DMC-FZ28", 15, 0xfff,
+ { "Panasonic DMC-FZ28", 15, 0xf96,
{ 10109,-3488,-993,-5412,12812,2916,-1305,2140,5543 } },
- { "Panasonic DMC-FZ30", 0, 0xf94c,
+ { "Panasonic DMC-FZ30", 0, 0xf94,
{ 10976,-4029,-1141,-7918,15491,2600,-1670,2071,8246 } },
- { "Panasonic DMC-FZ35", 147, 0xfff,
+ { "Panasonic DMC-FZ3", 143, 0,
{ 9938,-2780,-890,-4604,12393,2480,-1117,2304,4620 } },
- { "Panasonic DMC-FZ50", 0, 0xfff0, /* aka "LEICA V-LUX1" */
+ { "Panasonic DMC-FZ40", 143, 0,
+ { 13639,-5535,-1371,-1698,9633,2430,316,1152,4108 } },
+ { "Panasonic DMC-FZ50", 0, 0,
+ { 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } },
+ { "LEICA V-LUX1", 0, 0,
{ 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } },
{ "Panasonic DMC-L10", 15, 0xf96,
{ 8025,-1942,-1050,-7920,15904,2100,-2456,3005,7039 } },
- { "Panasonic DMC-L1", 0, 0xf7fc, /* aka "LEICA DIGILUX 3" */
+ { "Panasonic DMC-L1", 0, 0xf7f,
{ 8054,-1885,-1025,-8349,16367,2040,-2805,3542,7629 } },
- { "Panasonic DMC-LC1", 0, 0, /* aka "LEICA DIGILUX 2" */
+ { "LEICA DIGILUX 3", 0, 0xf7f,
+ { 8054,-1885,-1025,-8349,16367,2040,-2805,3542,7629 } },
+ { "Panasonic DMC-LC1", 0, 0,
{ 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } },
- { "Panasonic DMC-LX1", 0, 0xf7f0, /* aka "LEICA D-LUX2" */
+ { "LEICA DIGILUX 2", 0, 0,
+ { 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } },
+ { "Panasonic DMC-LX1", 0, 0xf7f,
{ 10704,-4187,-1230,-8314,15952,2501,-920,945,8927 } },
- { "Panasonic DMC-LX2", 0, 0, /* aka "LEICA D-LUX3" */
+ { "LEICA D-LUX2", 0, 0xf7f,
+ { 10704,-4187,-1230,-8314,15952,2501,-920,945,8927 } },
+ { "Panasonic DMC-LX2", 0, 0,
{ 8048,-2810,-623,-6450,13519,3272,-1700,2146,7049 } },
- { "Panasonic DMC-LX3", 15, 0xfff, /* aka "LEICA D-LUX4" */
+ { "LEICA D-LUX3", 0, 0,
+ { 8048,-2810,-623,-6450,13519,3272,-1700,2146,7049 } },
+ { "Panasonic DMC-LX3", 15, 0,
+ { 8128,-2668,-655,-6134,13307,3161,-1782,2568,6083 } },
+ { "LEICA D-LUX4", 15, 0,
{ 8128,-2668,-655,-6134,13307,3161,-1782,2568,6083 } },
+ { "Panasonic DMC-LX5", 143, 0,
+ { 10909,-4295,-948,-1333,9306,2399,22,1738,4582 } },
+ { "Panasonic DMC-FZ100", 143, 0xfff,
+ { 16197,-6146,-1761,-2393,10765,1869,366,2238,5248 } },
{ "Panasonic DMC-FX150", 15, 0xfff,
{ 9082,-2907,-925,-6119,13377,3058,-1797,2641,5609 } },
- { "Panasonic DMC-G1", 15, 0xfff,
+ { "Panasonic DMC-G10", 0, 0,
+ { 10113,-3400,-1114,-4765,12683,2317,-377,1437,6710 } },
+ { "Panasonic DMC-G1", 15, 0xf94,
{ 8199,-2065,-1056,-8124,16156,2033,-2458,3022,7220 } },
+ { "Panasonic DMC-G2", 15, 0xf3c,
+ { 10113,-3400,-1114,-4765,12683,2317,-377,1437,6710 } },
{ "Panasonic DMC-GF1", 15, 0xf92,
{ 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } },
+ { "Panasonic DMC-GF2", 143, 0xfff,
+ { 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } },
{ "Panasonic DMC-GH1", 15, 0xf92,
{ 6299,-1466,-532,-6535,13852,2969,-2331,3112,5984 } },
+ { "Panasonic DMC-GH2", 15, 0xf95,
+ { 7780,-2410,-806,-3913,11724,2484,-1018,2390,5298 } },
{ "Phase One H 20", 0, 0, /* DJC */
{ 1313,1855,-109,-6715,15908,808,-327,1840,6020 } },
{ "Phase One P 2", 0, 0,
@@ -8638,11 +8829,17 @@ void CLASS adobe_coeff (const char *make, const char *model)
{ 4516,-245,-37,-7020,14976,2173,-3206,4671,7087 } },
{ "Phase One P 45", 0, 0,
{ 5053,-24,-117,-5684,14076,1702,-2619,4492,5849 } },
- { "Phase One P65", 0, 0, /* DJC */
- { 8522,1268,-1916,-7706,16350,1358,-2397,4344,4923 } },
+ { "Phase One P65", 0, 0,
+ { 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 } },
+ { "SAMSUNG EX1", 0, 0x3e00,
+ { 8898,-2498,-994,-3144,11328,2066,-760,1381,4576 } },
+ { "SAMSUNG NX10", 0, 0,
+ { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } },
+ { "SAMSUNG WB2000", 0, 0xfff,
+ { 12093,-3557,-1155,-1000,9534,1733,-22,1787,4576 } },
{ "SAMSUNG GX-1", 0, 0,
{ 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
- { "SAMSUNG S85", 0, 0, /* DJC */
+ { "SAMSUNG S85", 0, 0xffff, /* DJC */
{ 11885,-3968,-1473,-4214,12299,1916,-835,1655,5549 } },
{ "Sinar", 0, 0, /* DJC */
{ 16442,-2956,-2422,-2877,12128,750,-1136,6066,4559 } },
@@ -8654,9 +8851,7 @@ void CLASS adobe_coeff (const char *make, const char *model)
{ 7511,-2571,-692,-7894,15088,3060,-948,1111,8128 } },
{ "SONY DSLR-A100", 0, 0xfeb,
{ 9437,-2811,-774,-8405,16215,2290,-710,596,7181 } },
- { "SONY DSLR-A200", 0, 0,
- { 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } },
- { "SONY DSLR-A230", 0, 0, /* copied */
+ { "SONY DSLR-A2", 0, 0,
{ 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } },
{ "SONY DSLR-A300", 0, 0,
{ 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } },
@@ -8666,14 +8861,28 @@ void CLASS adobe_coeff (const char *make, const char *model)
{ 6038,-1484,-578,-9146,16746,2513,-875,746,7217 } },
{ "SONY DSLR-A380", 0, 0,
{ 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } },
- { "SONY DSLR-A5", 254, 0x1ffe,
+ { "SONY DSLR-A450", 128, 0xfeb,
{ 4950,-580,-103,-5228,12542,3029,-709,1435,7371 } },
- { "SONY DSLR-A700", 254, 0x1ffe,
+ { "SONY DSLR-A580", 128, 0xfeb,
+ { 5932,-1492,-411,-4813,12285,2856,-741,1524,6739 } },
+ { "SONY DSLR-A5", 128, 0xfeb,
+ { 4950,-580,-103,-5228,12542,3029,-709,1435,7371 } },
+ { "SONY DSLR-A700", 126, 0,
{ 5775,-805,-359,-8574,16295,2391,-1943,2341,7249 } },
- { "SONY DSLR-A850", 256, 0x1ffe,
+ { "SONY DSLR-A850", 128, 0,
{ 5413,-1162,-365,-5665,13098,2866,-608,1179,8440 } },
- { "SONY DSLR-A900", 254, 0x1ffe,
- { 5209,-1072,-397,-8845,16120,2919,-1618,1803,8654 } }
+ { "SONY DSLR-A900", 128, 0,
+ { 5209,-1072,-397,-8845,16120,2919,-1618,1803,8654 } },
+ { "SONY NEX-3", 138, 0, /* DJC */
+ { 6907,-1256,-645,-4940,12621,2320,-1710,2581,6230 } },
+ { "SONY NEX-5", 116, 0, /* DJC */
+ { 6807,-1350,-342,-4216,11649,2567,-1089,2001,6420 } },
+ { "SONY NEX", 128, 0, /* Adobe's matrix */
+ { 6549,-1550,-436,-4880,12435,2753,-854,1868,6976 } },
+ { "SONY SLT-A33", 128, 0,
+ { 6069,-1221,-366,-5221,12779,2734,-1024,2066,6834 } },
+ { "SONY SLT-A55", 128, 0,
+ { 5932,-1492,-411,-4813,12285,2856,-741,1524,6739 } }
};
double cam_xyz[4][3];
char name[130];
@@ -8764,8 +8973,32 @@ float CLASS find_green (int bps, int bite, int off0, int off1)
void CLASS identify()
{
char head[32], *cp;
- int hlen, fsize, i, c, is_canon;
+ int hlen, flen, fsize, zero_fsize=1, i, c, is_canon;
struct jhead jh;
+ short pana[][6] = {
+ { 3130, 1743, 4, 0, -6, 0 },
+ { 3130, 2055, 4, 0, -6, 0 },
+ { 3130, 2319, 4, 0, -6, 0 },
+ { 3170, 2103, 18, 0,-42, 20 },
+ { 3170, 2367, 18, 13,-42,-21 },
+ { 3177, 2367, 0, 0, -1, 0 },
+ { 3304, 2458, 0, 0, -1, 0 },
+ { 3330, 2463, 9, 0, -5, 0 },
+ { 3330, 2479, 9, 0,-17, 4 },
+ { 3370, 1899, 15, 0,-44, 20 },
+ { 3370, 2235, 15, 0,-44, 20 },
+ { 3370, 2511, 15, 10,-44,-21 },
+ { 3690, 2751, 3, 0, -8, -3 },
+ { 3710, 2751, 0, 0, -3, 0 },
+ { 3724, 2450, 0, 0, 0, -2 },
+ { 3770, 2487, 17, 0,-44, 19 },
+ { 3770, 2799, 17, 15,-44,-19 },
+ { 3880, 2170, 6, 0, -6, 0 },
+ { 4060, 3018, 0, 0, 0, -2 },
+ { 4290, 2391, 3, 0, -8, -1 },
+ { 4330, 2439, 17, 15,-44,-19 },
+ { 4508, 2962, 0, 0, -3, -4 },
+ { 4508, 3330, 0, 0, -3, -6 } };
static const struct {
int fsize;
char make[12], model[19], withjpeg;
@@ -8788,7 +9021,9 @@ void CLASS identify()
{ 1447680, "AVT", "F-145C" ,0 },
{ 1920000, "AVT", "F-201C" ,0 },
{ 5067304, "AVT", "F-510C" ,0 },
+ { 5067316, "AVT", "F-510C" ,0 },
{ 10134608, "AVT", "F-510C" ,0 },
+ { 10134620, "AVT", "F-510C" ,0 },
{ 16157136, "AVT", "F-810C" ,0 },
{ 1409024, "Sony", "XCD-SX910CR" ,0 },
{ 2818048, "Sony", "XCD-SX910CR" ,0 },
@@ -8801,13 +9036,15 @@ void CLASS identify()
{ 6573120, "Canon", "PowerShot A610" ,0 },
{ 9219600, "Canon", "PowerShot A620" ,0 },
{ 9243240, "Canon", "PowerShot A470" ,0 },
- { 10341600, "Canon", "PowerShot A720" ,0 },
+ { 10341600, "Canon", "PowerShot A720 IS",0 },
{ 10383120, "Canon", "PowerShot A630" ,0 },
{ 12945240, "Canon", "PowerShot A640" ,0 },
{ 15636240, "Canon", "PowerShot A650" ,0 },
{ 5298000, "Canon", "PowerShot SD300" ,0 },
{ 7710960, "Canon", "PowerShot S3 IS" ,0 },
{ 15467760, "Canon", "PowerShot SX110 IS",0 },
+ { 15534576, "Canon", "PowerShot SX120 IS",0 },
+ { 18653760, "Canon", "PowerShot SX20 IS",0 },
{ 5939200, "OLYMPUS", "C770UZ" ,0 },
{ 1581060, "NIKON", "E900" ,1 }, /* or E900s,E910 */
{ 2465792, "NIKON", "E950" ,1 }, /* or E800,E700 */
@@ -8832,6 +9069,7 @@ void CLASS identify()
{ 10843712, "CASIO", "EX-Z75" ,1 },
{ 10834368, "CASIO", "EX-Z750" ,1 },
{ 12310144, "CASIO", "EX-Z850" ,1 },
+ { 15499264, "CASIO", "EX-Z1050" ,1 },
{ 7426656, "CASIO", "EX-P505" ,1 },
{ 9313536, "CASIO", "EX-P600" ,1 },
{ 10979200, "CASIO", "EX-P700" ,1 },
@@ -8842,6 +9080,8 @@ void CLASS identify()
{ 15980544, "AGFAPHOTO","DC-833m" ,1 },
{ 16098048, "SAMSUNG", "S85" ,1 },
{ 16215552, "SAMSUNG", "S85" ,1 },
+ { 20487168, "SAMSUNG", "WB550" ,1 },
+ { 24000000, "SAMSUNG", "WB550" ,1 },
{ 12582980, "Sinar", "" ,0 },
{ 33292868, "Sinar", "" ,0 },
{ 44390468, "Sinar", "" ,0 } };
@@ -8855,7 +9095,10 @@ void CLASS identify()
maximum = height = width = top_margin = left_margin = 0;
cdesc[0] = desc[0] = artist[0] = make[0] = model[0] = model2[0] = 0;
iso_speed = shutter = aperture = focal_len = unique_id = 0;
+ tiff_nifds = 0;
+ memset (tiff_ifd, 0, sizeof tiff_ifd);
memset (gpsdata, 0, sizeof gpsdata);
+ memset (cblack, 0, sizeof cblack);
memset (white, 0, sizeof white);
thumb_offset = thumb_length = thumb_width = thumb_height = 0;
load_raw = thumb_load_raw = 0;
@@ -8880,18 +9123,16 @@ void CLASS identify()
fseek (ifp, 0, SEEK_SET);
fread (head, 1, 32, ifp);
fseek (ifp, 0, SEEK_END);
- fsize = ftell(ifp);
+ flen = fsize = ftell(ifp);
if ((cp = (char *) memmem (head, 32, "MMMM", 4)) ||
(cp = (char *) memmem (head, 32, "IIII", 4))) {
parse_phase_one (cp-head);
- if (cp-head) parse_tiff(0);
+ if (cp-head && parse_tiff(0)) apply_tiff();
} else if (order == 0x4949 || order == 0x4d4d) {
if (!memcmp (head+6,"HEAPCCDR",8)) {
data_offset = hlen;
- parse_ciff (hlen, fsize - hlen);
- } else {
- parse_tiff(0);
- }
+ parse_ciff (hlen, flen - hlen);
+ } else if (parse_tiff(0)) apply_tiff();
} else if (!memcmp (head,"\xff\xd8\xff\xe1",4) &&
!memcmp (head+6,"Exif",4)) {
fseek (ifp, 4, SEEK_SET);
@@ -8929,8 +9170,9 @@ void CLASS identify()
parse_fuji (i);
}
fseek (ifp, 100, SEEK_SET);
- data_offset = get4();
+ parse_tiff (data_offset = get4());
parse_tiff (thumb_offset+12);
+ apply_tiff();
} else if (!memcmp (head,"RIFF",4)) {
fseek (ifp, 0, SEEK_SET);
parse_riff();
@@ -8945,6 +9187,18 @@ void CLASS identify()
raw_height = get2();
load_raw = &CLASS nokia_load_raw;
filters = 0x61616161;
+ } else if (!memcmp (head,"NOKIARAW",8)) {
+ strcpy (make, "NOKIA");
+ strcpy (model, "X2");
+ order = 0x4949;
+ fseek (ifp, 300, SEEK_SET);
+ data_offset = get4();
+ i = get4();
+ width = get2();
+ height = get2();
+ data_offset += i - width * 5 / 4 * height;
+ load_raw = &CLASS nokia_load_raw;
+ filters = 0x61616161;
} else if (!memcmp (head,"DSC-Image",9))
parse_rollei();
else if (!memcmp (head,"PWAD",4))
@@ -8956,14 +9210,15 @@ void CLASS identify()
else if (!memcmp (head,"CI",2))
parse_cine();
else
- for (i=0; i < sizeof table / sizeof *table; i++)
+ for (zero_fsize=i=0; i < sizeof table / sizeof *table; i++)
if (fsize == table[i].fsize) {
strcpy (make, table[i].make );
strcpy (model, table[i].model);
if (table[i].withjpeg)
parse_external_jpeg();
}
- if (make[0] == 0) parse_smal (0, fsize);
+ if (zero_fsize) fsize = 0;
+ if (make[0] == 0) parse_smal (0, flen);
if (make[0] == 0) parse_jpeg (is_raw = 0);
for (i=0; i < sizeof corp / sizeof *corp; i++)
@@ -8989,17 +9244,24 @@ void CLASS identify()
if (!height) height = raw_height;
if (!width) width = raw_width;
if (fuji_width) {
+ fuji_width = (raw_width+1)/2;
width = height + fuji_width;
height = width - 1;
pixel_aspect = 1;
}
if (height == 2624 && width == 3936) /* Pentax K10D and Samsung GX10 */
{ height = 2616; width = 3896; }
- if (height == 3136 && width == 4864) /* Pentax K20D */
- { height = 3124; width = 4688; }
- if (height == 3136 && width == 4736) /* Pentax K-7 */
- { height = 3122; width = 4684;
- top_margin = 2; filters = 0x16161616; }
+ if (height == 3136 && width == 4864) /* Pentax K20D and Samsung GX20 */
+ { height = 3124; width = 4688; filters = 0x16161616; }
+ if (!strcmp(model,"K-r") || !strcmp(model,"K-x"))
+ { width = 4309; filters = 0x16161616; }
+ if (!strcmp(model,"K-5"))
+ { left_margin = 10; width = 4950; filters = 0x16161616; }
+ if (!strcmp(model,"K-7"))
+ { height = 3122; width = 4684; filters = 0x16161616; top_margin = 2; }
+ if (!strcmp(model,"645D"))
+ { height = 5502; width = 7328; filters = 0x61616161; top_margin = 29;
+ left_margin = 48; }
if (height == 3014 && width == 4096) /* Ricoh GX200 */
width = 4014;
if (dng_version) {
@@ -9120,7 +9382,7 @@ void CLASS identify()
top_margin = 6;
left_margin = 12;
goto canon_a5;
- } else if (!strcmp(model,"PowerShot A720")) {
+ } else if (!strcmp(model,"PowerShot A720 IS")) {
height = 2472;
width = 3298;
raw_height = 2480;
@@ -9174,6 +9436,27 @@ canon_a5:
load_raw = &CLASS packed_load_raw;
load_flags = 40;
zero_is_bad = 1;
+ } else if (!strcmp(model,"PowerShot SX120 IS")) {
+ height = 2742;
+ width = 3664;
+ raw_height = 2778;
+ raw_width = 3728;
+ top_margin = 18;
+ left_margin = 16;
+ filters = 0x49494949;
+ load_raw = &CLASS packed_load_raw;
+ load_flags = 40;
+ zero_is_bad = 1;
+ } else if (!strcmp(model,"PowerShot SX20 IS")) {
+ height = 3024;
+ width = 4032;
+ raw_height = 3048;
+ raw_width = 4080;
+ top_margin = 12;
+ left_margin = 24;
+ load_raw = &CLASS packed_load_raw;
+ load_flags = 40;
+ zero_is_bad = 1;
} else if (!strcmp(model,"PowerShot Pro90 IS")) {
width = 1896;
colors = 4;
@@ -9237,6 +9520,10 @@ canon_a5:
width = 3684;
top_margin = 16;
left_margin = 8;
+ if (unique_id > 0x2720000) {
+ top_margin = 12;
+ left_margin = 52;
+ }
} else if (is_canon && raw_width == 3944) {
height = 2602;
width = 3908;
@@ -9282,27 +9569,29 @@ canon_a5:
top_margin = 10;
left_margin = 12;
filters = 0x49494949;
- } else if (is_canon && raw_width == 1208) {
+ } else if (is_canon && raw_width == 4832) {
top_margin = unique_id == 0x80000261 ? 51:26;
left_margin = 62;
- raw_width = width *= 4;
if (unique_id == 0x80000252)
adobe_coeff ("Canon","EOS 500D");
goto canon_cr2;
- } else if (is_canon && raw_width == 1280) {
+ } else if (is_canon && raw_width == 5120) {
height -= top_margin = 45;
left_margin = 142;
- raw_width *= 4;
width = 4916;
- } else if (is_canon && raw_width == 1340) {
+ } else if (is_canon && raw_width == 5344) {
+ top_margin = 51;
+ left_margin = 142;
+ if (unique_id == 0x80000270)
+ adobe_coeff ("Canon","EOS 550D");
+ goto canon_cr2;
+ } else if (is_canon && raw_width == 5360) {
top_margin = 51;
left_margin = 158;
- raw_width = width *= 4;
goto canon_cr2;
- } else if (is_canon && raw_width == 1448) {
+ } else if (is_canon && raw_width == 5792) {
top_margin = 51;
left_margin = 158;
- raw_width = width *= 4;
goto canon_cr2;
} else if (is_canon && raw_width == 5108) {
top_margin = 13;
@@ -9334,6 +9623,11 @@ canon_cr2:
left_margin = 2;
} else if (!strcmp(model,"D5000")) {
width -= 42;
+ } else if (!strcmp(model,"D7000")) {
+ width -= 44;
+ } else if (!strcmp(model,"D3100")) {
+ width -= 28;
+ left_margin = 6;
} else if (!strncmp(model,"D40",3) ||
!strncmp(model,"D50",3) ||
!strncmp(model,"D70",3)) {
@@ -9358,7 +9652,7 @@ canon_cr2:
else width -= 8;
} else if (!strncmp(model,"D300",4)) {
width -= 32;
- } else if (!strcmp(model,"COOLPIX P6000")) {
+ } else if (!strncmp(model,"COOLPIX P",9)) {
load_flags = 24;
filters = 0x94949494;
} else if (fsize == 1581060) {
@@ -9425,8 +9719,8 @@ cp_e2500:
filters = 0x16161616;
}
if (make[0] == 'O') {
- i = find_green (12, 32, 0, fsize/2);
- c = find_green (12, 32, 0, 3096);
+ i = find_green (12, 32, 1188864, 3576832);
+ c = find_green (12, 32, 2383920, 2387016);
if (abs(i) < abs(c)) {
SWAP(i,c);
load_flags = 24;
@@ -9465,7 +9759,7 @@ cp_e2500:
height = 2144;
width = 2880;
flip = 6;
- } else
+ } else if (load_raw != &CLASS packed_load_raw)
maximum = 0x3e00;
if (is_raw == 2 && shot_select)
maximum = 0x2f00;
@@ -9532,11 +9826,6 @@ konica_400z:
data_error = -1;
} else if (!strcmp(model,"*ist DS")) {
height -= 2;
- } else if (!strcmp(model,"K20D")) {
- filters = 0x16161616;
- } else if (!strcmp(model,"K-x")) {
- width = 4309;
- filters = 0x16161616;
} else if (!strcmp(model,"Optio S")) {
if (fsize == 3178560) {
height = 1540;
@@ -9575,7 +9864,41 @@ konica_400z:
raw_width = fsize/height/2;
order = 0x4d4d;
load_raw = &CLASS unpacked_load_raw;
- maximum = 0xffff;
+ } else if (!strcmp(model,"NX10")) {
+ height -= top_margin = 4;
+ width -= 2 * (left_margin = 8);
+ load_flags = 32;
+ } else if (!strcmp(model,"EX1")) {
+ order = 0x4949;
+ height -= 20;
+ top_margin = 2;
+ if ((width -= 6) > 3682) {
+ height -= 10;
+ width -= 46;
+ top_margin = 8;
+ }
+ } else if (!strcmp(model,"WB2000")) {
+ order = 0x4949;
+ height -= 3;
+ top_margin = 2;
+ if ((width -= 10) > 3718) {
+ height -= 28;
+ width -= 56;
+ top_margin = 8;
+ }
+ } else if (fsize == 20487168) {
+ height = 2808;
+ width = 3648;
+ goto wb550;
+ } else if (fsize == 24000000) {
+ height = 3000;
+ width = 4000;
+wb550:
+ strcpy (model, "WB550");
+ order = 0x4d4d;
+ load_raw = &CLASS unpacked_load_raw;
+ load_flags = 6;
+ maximum = 0x3df;
} else if (!strcmp(model,"STV680 VGA")) {
height = 484;
width = 644;
@@ -9607,6 +9930,7 @@ konica_400z:
width = 2588;
load_raw = fsize < 7500000 ?
&CLASS eight_bit_load_raw : &CLASS unpacked_load_raw;
+ data_offset = fsize - width*height*(fsize >> 22);
maximum = 0xfff0;
} else if (!strcmp(model,"F-810C")) {
height = 2469;
@@ -9659,6 +9983,12 @@ konica_400z:
top_margin = 4;
left_margin = 7;
filters = 0x61616161;
+ } else if (raw_width == 7410) {
+ height = 5502;
+ width = 7328;
+ top_margin = 4;
+ left_margin = 41;
+ filters = 0x61616161;
} else if (raw_width == 4090) {
strcpy (model, "V96C");
height -= (top_margin = 6);
@@ -9716,112 +10046,23 @@ konica_400z:
filters = 0x16161616;
}
} else if (!strcmp(make,"LEICA") || !strcmp(make,"Panasonic")) {
- maximum = 0xfff0;
- if ((fsize-data_offset) / (width*8/7) == height)
+ if ((flen - data_offset) / (raw_width*8/7) == raw_height)
load_raw = &CLASS panasonic_load_raw;
- if (!load_raw) load_raw = &CLASS unpacked_load_raw;
- switch (width) {
- case 2568:
- adobe_coeff ("Panasonic","DMC-LC1"); break;
- case 3130:
- left_margin = -14;
- case 3170:
- left_margin += 18;
- width = 3096;
- if (height > 2326) {
- height = 2326;
- top_margin = 13;
- filters = 0x49494949;
- }
- zero_is_bad = 1;
- adobe_coeff ("Panasonic","DMC-FZ8"); break;
- case 3213:
- width -= 27;
- case 3177:
- width -= 10;
- filters = 0x49494949;
- zero_is_bad = 1;
- adobe_coeff ("Panasonic","DMC-L1"); break;
- case 3304:
- width -= 17;
- zero_is_bad = 1;
- adobe_coeff ("Panasonic","DMC-FZ30"); break;
- case 3330:
- width += 43;
- left_margin = -6;
- maximum = 0xf7f0;
- case 3370:
- width -= 82;
- left_margin += 15;
- if (height > 2480)
- height = 2480 - (top_margin = 10);
- filters = 0x49494949;
- zero_is_bad = 1;
- adobe_coeff ("Panasonic","DMC-FZ18"); break;
- case 3690:
- height -= 2;
- left_margin = -14;
- maximum = 0xf7f0;
- case 3770:
- width = 3672;
- if (--height == 2798 && (height = 2760))
- top_margin = 15;
- else filters = 0x49494949;
- left_margin += 17;
- zero_is_bad = 1;
- adobe_coeff ("Panasonic","DMC-FZ50"); break;
- case 3710:
- width = 3682;
- filters = 0x49494949;
- adobe_coeff ("Panasonic","DMC-L10"); break;
- case 3724:
- width -= 14;
- if (height == 2450) height -= 2;
- case 3836:
- width -= 42;
-lx3: filters = 0x16161616;
- if (make[0] != 'P')
- adobe_coeff ("Panasonic","DMC-LX3");
- break;
- case 3880:
- width -= 22;
- left_margin = 6;
- zero_is_bad = 1;
- adobe_coeff ("Panasonic","DMC-LX1"); break;
- case 4060:
- width = 3982;
- if (height == 2250) goto lx3;
- width = 4018;
- filters = 0x16161616;
- if (!strncmp(model,"DMC-FZ3",7)) {
- height -= 2;
- adobe_coeff ("Panasonic","DMC-FZ35"); break;
- }
- filters = 0x49494949;
- if (!strcmp(model,"DMC-GH1")) break;
- zero_is_bad = 1;
- adobe_coeff ("Panasonic","DMC-G1"); break;
- case 4172:
- case 4396:
- width -= 28;
- filters = 0x49494949;
- adobe_coeff ("Panasonic","DMC-GH1"); break;
- case 4290:
- height += 38;
- left_margin = -14;
- filters = 0x49494949;
- case 4330:
- width = 4248;
- if ((height -= 39) == 2400)
- top_margin = 15;
- left_margin += 17;
- adobe_coeff ("Panasonic","DMC-LX2"); break;
- case 4508:
- height -= 6;
- width = 4429;
- filters = 0x16161616;
- adobe_coeff ("Panasonic","DMC-FX150"); break;
+ if (!load_raw) {
+ load_raw = &CLASS unpacked_load_raw;
+ load_flags = 4;
}
+ zero_is_bad = 1;
+ if ((height += 12) > raw_height) height = raw_height;
+ for (i=0; i < sizeof pana / sizeof *pana; i++)
+ if (raw_width == pana[i][0] && raw_height == pana[i][1]) {
+ left_margin = pana[i][2];
+ top_margin = pana[i][3];
+ width += pana[i][4];
+ height += pana[i][5];
+ }
+ filters = 0x01010101 * (uchar) "\x94\x61\x49\x16"
+ [((filters-1) ^ (left_margin & 1) ^ (top_margin << 1)) & 3];
} else if (!strcmp(model,"C770UZ")) {
height = 1718;
width = 2304;
@@ -9832,25 +10073,22 @@ lx3: filters = 0x16161616;
height += height & 1;
filters = exif_cfa;
if (width == 4100) width -= 4;
- if (load_raw == &CLASS olympus_load_raw) {
- tiff_bps = 12;
- black >>= 4;
- } else if (!strcmp(model,"E-10") ||
- !strncmp(model,"E-20",4)) {
- black <<= 2;
- } else if (!strcmp(model,"E-300") ||
- !strcmp(model,"E-500")) {
+ if (load_raw == &CLASS unpacked_load_raw)
+ load_flags = 4;
+ tiff_bps = 12;
+ if (!strcmp(model,"E-300") ||
+ !strcmp(model,"E-500")) {
width -= 20;
if (load_raw == &CLASS unpacked_load_raw) {
- maximum = 0xfc30;
- black = 0;
+ maximum = 0xfc3;
+ memset (cblack, 0, sizeof cblack);
}
} else if (!strcmp(model,"E-330")) {
width -= 30;
if (load_raw == &CLASS unpacked_load_raw)
- maximum = 0xf790;
+ maximum = 0xf79;
} else if (!strcmp(model,"SP550UZ")) {
- thumb_length = fsize - (thumb_offset = 0xa39800);
+ thumb_length = flen - (thumb_offset = 0xa39800);
thumb_height = 480;
thumb_width = 640;
}
@@ -9878,8 +10116,13 @@ lx3: filters = 0x16161616;
width = 3925;
order = 0x4d4d;
} else if (!strcmp(model,"DSLR-A100")) {
- height--;
- width = ++raw_width;
+ if (width == 3880) {
+ height--;
+ width = ++raw_width;
+ } else {
+ order = 0x4d4d;
+ load_flags = 2;
+ }
filters = 0x61616161;
} else if (!strcmp(model,"DSLR-A350")) {
height -= 4;
@@ -9921,14 +10164,7 @@ c603:
read_shorts (curve, 256);
} else gamma_curve (0, 3.875, 1, 255);
load_raw = &CLASS eight_bit_load_raw;
- } else if (!strcmp(model,"EASYSHARE Z1015 IS")) {
- height = 2742;
- width = 3664;
- goto ezshare;
- } else if (!strcmp(model,"EasyShare Z980")) {
- height = 3006;
- width = 4016;
-ezshare:
+ } else if (!strncasecmp(model,"EasyShare",9)) {
data_offset = 0x15000;
load_raw = &CLASS packed_load_raw;
} else if (!strcasecmp(make,"KODAK")) {
@@ -9970,7 +10206,7 @@ ezshare:
}
if (!strncmp(model,"DC2",3)) {
height = 242;
- if (fsize < 100000) {
+ if (flen < 100000) {
raw_width = 256; width = 249;
pixel_aspect = (4.0*height) / (3.0*width);
} else {
@@ -10130,6 +10366,10 @@ ezshare:
width = 3279;
raw_width = 4928;
maximum = 0xfff;
+ } else if (fsize == 15499264) { /* EX-Z1050 or EX-Z1080 */
+ height = 2752;
+ width = 3672;
+ raw_width = 5632;
} else if (!strcmp(model,"EX-P505")) {
height = 1928;
width = 2568;
@@ -10168,16 +10408,12 @@ dng_skip:
}
#endif
if (!cdesc[0])
- strcpy (cdesc, colors == 3 ? "RGB":"GMCY");
+ strcpy (cdesc, colors == 3 ? "RGBG":"GMCY");
if (!raw_height) raw_height = height;
if (!raw_width ) raw_width = width;
if (filters && colors == 3)
- for (i=0; i < 32; i+=4) {
- if ((filters >> i & 15) == 9)
- filters |= 2 << i;
- if ((filters >> i & 15) == 6)
- filters |= 8 << i;
- }
+ filters |= ((filters >> 2 & 0x22222222) |
+ (filters << 2 & 0x88888888)) & filters << 1;
notraw:
if (flip == -1) flip = tiff_flip;
if (flip == -1) flip = 0;
@@ -10532,7 +10768,7 @@ void CLASS tiff_head (struct tiff_hdr *th, int full)
strncpy (th->make, make, 64);
strncpy (th->model, model, 64);
strcpy (th->soft, "dcraw v"VERSION);
- t = gmtime (&timestamp);
+ t = localtime (&timestamp);
sprintf (th->date, "%04d:%02d:%02d %02d:%02d:%02d",
t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);
strncpy (th->artist, artist, 64);
@@ -10847,8 +11083,8 @@ int CLASS main (int argc, const char **argv)
} else if (!is_raw)
fprintf (stderr,_("Cannot decode file %s\n"), ifname);
if (!is_raw) goto next;
- shrink = filters &&
- (half_size || threshold || aber[0] != 1 || aber[2] != 1);
+ shrink = filters && (half_size ||
+ ((threshold || aber[0] != 1 || aber[2] != 1) && !identify_only));
iheight = (height + shrink) >> shrink;
iwidth = (width + shrink) >> shrink;
if (identify_only) {
@@ -10870,7 +11106,6 @@ int CLASS main (int argc, const char **argv)
printf (_("Raw colors: %d"), colors);
if (filters) {
printf (_("\nFilter pattern: "));
- if (!cdesc[3]) cdesc[3] = 'G';
for (i=0; i < 16; i++)
putchar (cdesc[fc(i >> 1,i & 1)]);
}
@@ -10910,6 +11145,10 @@ next:
if (dark_frame) subtract (dark_frame);
quality = 2 + !fuji_width;
if (user_qual >= 0) quality = user_qual;
+ i = cblack[3];
+ FORC3 if (i > cblack[c]) i = cblack[c];
+ FORC4 cblack[c] -= i;
+ black += i;
if (user_black >= 0) black = user_black;
if (user_sat > 0) maximum = user_sat;
#ifdef COLORCHECK
@@ -10986,6 +11225,812 @@ cleanup:
@
+1.440
+log
+@Read correct camera WB from Nikon NRW and Samsung SRW files.
+Copied color matrices from Adobe DNG Converter 6.3.
+@
+text
+@d4936 1
+a4936 1
+ if (!tiff_ifd[ifd].bps) {
+d7628 1
+a7628 1
+ height = 2760;
+d7631 2
+a7632 2
+ height = 2750;
+ width = 3668;
+a7637 1
+ width -= 10;
+d7639 5
+@
+
+
+1.439
+log
+@Support the Nikon D3100 & D7000 & P7000, Panasonic FZ40 & FZ100 & LX5,
+Samsung WB2000, Nokia X2, Canon SX120 & PowerShot G12, Hasselblad H4D,
+Pentax 645D & K-5 & K-r, Sony SLT-A33 & SLT-A55V.
+@
+text
+@d26 1
+a26 1
+#define VERSION "9.05"
+d60 1
+a60 1
+#ifdef DJGPP
+d1551 7
+a1557 6
+ for (col=0; col < raw_width; col+=2) {
+ a = pixel[col+0] ^ akey;
+ b = pixel[col+1] ^ bkey;
+ pixel[col+0] = (a & mask) | (b & ~mask);
+ pixel[col+1] = (b & mask) | (a & ~mask);
+ }
+d1743 1
+d1776 1
+a1776 1
+ else if (load_flags & 32)
+d1778 2
+d1787 2
+d4422 5
+a4426 2
+ else fseek (ifp, -10, SEEK_CUR);
+
+d4474 12
+a4485 3
+ if (tag == 0x14 && len == 2560 && type == 7) {
+ fseek (ifp, 1248, SEEK_CUR);
+ goto get2_256;
+d4632 4
+d4664 1
+d6142 1
+a6142 1
+ { 0 } },
+d6175 2
+d6201 2
+d6365 2
+d6385 2
+a6386 2
+ { "NIKON D7000", 0, 0, /* DJC */
+ { 6629,-2254,-2,-3468,9387,4081,-760,2102,7574 } },
+d6423 2
+d6463 2
+a6464 2
+ { "OLYMPUS E-5", 0, 0, /* DJC */
+ { 10033,-4067,-600,-3784,10494,3291,-923,2594,7744 } },
+d6513 4
+a6516 4
+ { "PENTAX K-r", 0, 0, /* Pentax DNG */
+ { 21746,-6684,-1521,-10014,26601,6573,-1920,3062,19415 } },
+ { "PENTAX K-5", 0, 0, /* Pentax DNG */
+ { 19331,-5842,-2589,-9103,28027,4285,-2216,3884,14767 } },
+d6573 2
+d6577 2
+d6591 1
+a6591 1
+ { "SAMSUNG NX10", 20, 0xea6,
+d6594 1
+a6594 1
+ { 0 } },
+d6621 2
+d7625 1
+d8120 1
+a8120 1
+ } else if (!strcmp(model,"EX-Z1050")) {
+a8123 1
+ maximum = 0xffc;
+d8162 1
+a8162 1
+ strcpy (cdesc, colors == 3 ? "RGB":"GMCY");
+d8522 1
+a8522 1
+ t = gmtime (&timestamp);
+a8859 1
+ if (!cdesc[3]) cdesc[3] = 'G';
+@
+
+
+1.438
+log
+@Fixed rotation for Kodak EasyShare and some Canon EOS photos.
+@
+text
+@d26 1
+a26 1
+#define VERSION "9.04"
+d1076 2
+a1077 2
+ ushort bit[2][13], huff[4097];
+ int row, col, diff, c, i;
+d1081 5
+a1085 3
+ FORC(13) bit[0][c] = get2();
+ FORC(13) bit[1][c] = fgetc(ifp);
+ FORC(13)
+d1096 4
+a1099 3
+ if ((unsigned) (row-top_margin) < height && col < width)
+ BAYER(row-top_margin,col) = hpred[col & 1];
+ if (hpred[col & 1] >> 12) derror();
+d1807 1
+a1807 1
+ int dwide, row, c;
+d1809 1
+d1815 2
+a1816 1
+ if (fread (data, 1, dwide, ifp) < dwide) derror();
+d4522 7
+d4549 2
+a4550 2
+ if (tag == 0x220 && len == 53)
+ meta_offset = ftell(ifp) + 14;
+d4852 4
+d6074 2
+d6118 2
+d6232 2
+a6233 2
+ { "FUJIFILM FinePix HS10 HS11", 0, 0xf68, /* DJC */
+ { 12164,-3169,-1662,-1020,10358,662,-224,2108,3106 } },
+d6356 2
+d6374 2
+d6432 2
+d6482 4
+d6488 2
+d6494 1
+a6494 1
+ { "Panasonic DMC-FZ28", 15, 0xfff,
+d6498 1
+a6498 1
+ { "Panasonic DMC-FZ35", 147, 0xfff,
+d6500 5
+a6504 1
+ { "Panasonic DMC-FZ50", 0, 0xfff, /* aka "LEICA V-LUX1" */
+d6508 3
+a6510 1
+ { "Panasonic DMC-L1", 0, 0x3dff, /* aka "LEICA DIGILUX 3" */
+d6512 1
+a6512 1
+ { "Panasonic DMC-LC1", 0, 0, /* aka "LEICA DIGILUX 2" */
+d6514 5
+a6518 1
+ { "Panasonic DMC-LX1", 0, 0x3dfc, /* aka "LEICA D-LUX2" */
+d6520 3
+a6522 1
+ { "Panasonic DMC-LX2", 0, 0, /* aka "LEICA D-LUX3" */
+d6524 1
+a6524 1
+ { "Panasonic DMC-LX3", 15, 0xfff, /* aka "LEICA D-LUX4" */
+d6526 6
+d6536 1
+a6536 1
+ { "Panasonic DMC-G1", 15, 0xfff,
+d6554 6
+d6562 1
+a6562 1
+ { "SAMSUNG S85", 0, 0, /* DJC */
+d6597 7
+a6603 1
+ { 6807,-1350,-342,-4216,11649,2567,-1089,2001,6420 } }
+d6696 24
+d6764 1
+d6908 12
+d6972 11
+a6982 5
+ if (height == 3136 && width == 4864) /* Pentax K20D */
+ { height = 3124; width = 4688; }
+ if (height == 3136 && width == 4736) /* Pentax K-7 */
+ { height = 3122; width = 4684;
+ top_margin = 2; filters = 0x16161616; }
+d7157 11
+d7241 4
+d7344 5
+d7373 1
+a7373 1
+ } else if (!strcmp(model,"COOLPIX P6000")) {
+a7546 5
+ } else if (!strcmp(model,"K20D")) {
+ filters = 0x16161616;
+ } else if (!strcmp(model,"K-x")) {
+ width = 4309;
+ filters = 0x16161616;
+a7584 1
+ maximum = 0xffff;
+d7597 5
+a7601 1
+ maximum = 0x3e00;
+d7699 6
+d7762 1
+a7762 1
+ if ((flen - data_offset) / (width*8/7) == height)
+d7769 10
+a7778 96
+ switch (width) {
+ case 2568:
+ adobe_coeff ("Panasonic","DMC-LC1"); break;
+ case 3130:
+ left_margin = -14;
+ case 3170:
+ left_margin += 18;
+ width = 3096;
+ if (height > 2326) {
+ height = 2326;
+ top_margin = 13;
+ filters = 0x49494949;
+ }
+ adobe_coeff ("Panasonic","DMC-FZ8"); break;
+ case 3213:
+ width -= 27;
+ case 3177:
+ width -= 10;
+ load_flags = 2;
+ filters = 0x49494949;
+ adobe_coeff ("Panasonic","DMC-L1"); break;
+ case 3304:
+ width -= 17;
+ adobe_coeff ("Panasonic","DMC-FZ30"); break;
+ case 3330:
+ width += 43;
+ left_margin = -6;
+ maximum = 0xf7f;
+ case 3370:
+ width -= 82;
+ left_margin += 15;
+ if (height > 2480)
+ height = 2480 - (top_margin = 10);
+ filters = 0x49494949;
+ adobe_coeff ("Panasonic","DMC-FZ18"); break;
+ case 3690:
+ height -= 2;
+ left_margin = -14;
+ maximum = 0xf7f0;
+ case 3770:
+ width = 3672;
+ if (--height == 2798 && (height = 2760))
+ top_margin = 15;
+ else filters = 0x49494949;
+ left_margin += 17;
+ adobe_coeff ("Panasonic","DMC-FZ50"); break;
+ case 3710:
+ width = 3682;
+ filters = 0x49494949;
+ adobe_coeff ("Panasonic","DMC-L10"); break;
+ case 3724:
+ width -= 14;
+ if (height == 2450) height -= 2;
+ case 3836:
+ width -= 42;
+lx3: filters = 0x16161616;
+ if (make[0] != 'P')
+ adobe_coeff ("Panasonic","DMC-LX3");
+ break;
+ case 3880:
+ width -= 22;
+ left_margin = 6;
+ load_flags = 2;
+ adobe_coeff ("Panasonic","DMC-LX1"); break;
+ case 4060:
+ width = 3982;
+ if (height == 2250) goto lx3;
+ width = 4018;
+ filters = 0x16161616;
+ if (!strncmp(model,"DMC-FZ3",7)) {
+ height -= 2;
+ adobe_coeff ("Panasonic","DMC-FZ35"); break;
+ }
+ filters = 0x49494949;
+ break;
+ case 4172:
+ case 4396:
+ width -= 28;
+ filters = 0x49494949;
+ adobe_coeff ("Panasonic","DMC-GH1"); break;
+ case 4290:
+ height += 38;
+ left_margin = -14;
+ filters = 0x49494949;
+ case 4330:
+ width = 4248;
+ if ((height -= 39) == 2400)
+ top_margin = 15;
+ left_margin += 17;
+ adobe_coeff ("Panasonic","DMC-LX2"); break;
+ case 4508:
+ height -= 6;
+ width = 4429;
+ filters = 0x16161616;
+ adobe_coeff ("Panasonic","DMC-FX150"); break;
+ }
+@
+
+
+1.437
+log
+@Support the Canon SX20 IS.
+Get Fuji HS10 black level from the metadata.
+@
+text
+@d26 1
+a26 1
+#define VERSION "9.03"
+d4448 6
+d4639 1
+a4639 1
+ kodak = !strncmp(make,"EASTMAN",7);
+d4813 1
+d4894 1
+a4894 1
+ case 513:
+d4907 3
+d5264 1
+a5264 1
+void CLASS parse_tiff (int base)
+d5266 1
+a5266 2
+ int doff, max_samp=0, raw=-1, thm=-1, i;
+ struct jhead jh;
+d5270 1
+a5270 1
+ if (order != 0x4949 && order != 0x4d4d) return;
+a5271 2
+ memset (tiff_ifd, 0, sizeof tiff_ifd);
+ tiff_nifds = 0;
+d5276 8
+d5310 2
+a5311 2
+ fuji_width *= (raw_width+1)/2;
+ if (tiff_ifd[0].flip) tiff_flip = tiff_ifd[0].flip;
+d5809 1
+a5809 1
+ parse_tiff (save+6);
+d6671 1
+a6671 1
+ { 10341600, "Canon", "PowerShot A720" ,0 },
+d6729 2
+d6761 1
+a6761 1
+ if (cp-head) parse_tiff(0);
+d6766 1
+a6766 3
+ } else {
+ parse_tiff(0);
+ }
+d6806 1
+d6866 1
+d6998 1
+a6998 1
+ } else if (!strcmp(model,"PowerShot A720")) {
+@
+
+
+1.436
+log
+@Support the Samsung EX1.
+@
+text
+@d26 1
+a26 1
+#define VERSION "9.02"
+d4894 1
+a4894 1
+ tiff_ifd[ifd].width = jh.wide << (jh.clrs == 2);
+d4898 2
+d5144 2
+d6197 2
+a6198 2
+ { "FUJIFILM FinePix HS10 HS11", 79, 0xf68, /* DJC */
+ { 12123,-3090,-1806,-1486,10894,593,-683,2369,3114 } },
+d6663 1
+d7035 10
+d7153 1
+a7153 1
+ } else if (is_canon && raw_width == 1208) {
+a7155 1
+ raw_width = width *= 4;
+d7159 1
+a7159 1
+ } else if (is_canon && raw_width == 1280) {
+a7161 1
+ raw_width *= 4;
+d7163 1
+a7163 1
+ } else if (is_canon && raw_width == 1336) {
+a7165 1
+ raw_width = width *= 4;
+d7169 1
+a7169 1
+ } else if (is_canon && raw_width == 1340) {
+a7171 1
+ raw_width = width *= 4;
+d7173 1
+a7173 1
+ } else if (is_canon && raw_width == 1448) {
+a7175 1
+ raw_width = width *= 4;
+@
+
+
+1.435
+log
+@Support the Sony A450, Kodak Z981, Olympus E-P2, and Panasonic G2 & GF1.
+@
+text
+@d7442 10
+@
+
+
+1.434
+log
+@Built color matrices for the Sony NEX-3 and NEX-5.
+@
+text
+@d26 1
+a26 1
+#define VERSION "9.01"
+d4774 1
+a4774 1
+ static const int wbtag[]={ 0xfa25,0xfa28,0xfa27,0xfa29,-1,-1,0xfa2a };
+d4797 1
+a4797 1
+ if (tag == 0xfa0d) wbi = fgetc(ifp);
+d4800 2
+d5155 6
+d6389 3
+a6391 1
+ { "OLYMPUS E-620", 0, 0xfb9,
+d6395 2
+d6469 1
+a6469 1
+ { "Panasonic DMC-G2", 0, 0,
+d6509 3
+a6511 1
+ { "SONY DSLR-A5", 126, 0,
+d7602 1
+a7615 1
+ zero_is_bad = 1;
+a7622 1
+ zero_is_bad = 1;
+a7625 1
+ zero_is_bad = 1;
+a7636 1
+ zero_is_bad = 1;
+a7647 1
+ zero_is_bad = 1;
+a7665 1
+ zero_is_bad = 1;
+d7677 1
+a7677 3
+ if (!strcmp(model,"DMC-GH1")) break;
+ zero_is_bad = 1;
+ adobe_coeff ("Panasonic","DMC-G1"); break;
+d7800 1
+a7800 8
+ } else if (!strcmp(model,"EASYSHARE Z1015 IS")) {
+ height = 2742;
+ width = 3664;
+ goto ezshare;
+ } else if (!strcmp(model,"EasyShare Z980")) {
+ height = 3006;
+ width = 4016;
+ezshare:
+d8720 2
+a8721 2
+ shrink = filters &&
+ (half_size || threshold || aber[0] != 1 || aber[2] != 1);
+@
+
+
+1.433
+log
+@Support the Samsung WB550 and NX10, Casio EX-Z1050, and Fuji HS10.
+Support the Canon EOS 550D / Digital Rebel T2i / Kiss Digital X4.
+Support A100 images modified by Sony software.
+Split the darkness level into four separate color channels.
+@
+text
+@d26 1
+a26 1
+#define VERSION "9.00"
+d3842 1
+a3842 1
+ described in http://scien.stanford.edu/class/psych221/projects/99/tingchen/algodep/vargra.html
+d6504 5
+a6508 1
+ { 5209,-1072,-397,-8845,16120,2919,-1618,1803,8654 } }
+@
+
+
+1.432
+log
+@Support the Canon EOS-1D Mark IV and PowerShots G11 and S90.
+Support the Casio EX-Z750, Pentax K-x, Fuji S200EXR, Sony A550.
+@
+text
+@d3 1
+a3 1
+ Copyright 1997-2009 by Dave Coffin, dcoffin a cybercom o net
+d26 1
+a26 1
+#define VERSION "8.99"
+d117 1
+a117 1
+unsigned black, maximum, mix_green, raw_color, zero_is_bad;
+d170 1
+a170 1
+#define SWAP(a,b) { a ^= b; a ^= (b ^= a); }
+a349 14
+void CLASS canon_black (double dark[2], int nblack)
+{
+ int c, diff, row, col;
+
+ if (!nblack) return;
+ FORC(2) dark[c] /= nblack >> 1;
+ if ((diff = dark[0] - dark[1]))
+ for (row=0; row < height; row++)
+ for (col=1; col < width; col+=2)
+ BAYER(row,col) += diff;
+ dark[1] += diff;
+ black = (dark[0] + dark[1] + 1) / 2;
+}
+
+d702 1
+a702 1
+ int nblocks, lowbits, i, c, row, r, col, save, val, nblack=0;
+a704 1
+ double dark[2] = { 0,0 };
+d757 1
+d761 1
+a761 1
+ dark[icol & 1] += (nblack++,pixel[r*raw_width+col]);
+d767 1
+a767 1
+ canon_black (dark, nblack);
+d890 1
+a890 2
+ int jwide, jrow, jcol, val, jidx, i, j, row=0, col=0, nblack=0;
+ double dark[2] = { 0,0 };
+d916 1
+d921 1
+a921 1
+ dark[(col-left_margin) & 1] += (nblack++,val);
+d928 1
+a928 1
+ canon_black (dark, nblack);
+d1770 1
+a1770 1
+ BAYER(row,i) = val << (load_flags >> 6);
+d1795 1
+a1795 1
+ if ((BAYER2(row,col) = pixel[col]) >> bits) derror();
+d2490 1
+a2490 1
+ BAYER(row,col) = curve[pix[i] << 1] >> 1;
+d3381 2
+d3557 1
+a3557 1
+ int scale=1, size, lev, hpass, lpass, row, col, nc, c, i, wlast;
+d3567 1
+d3602 1
+a3602 1
+ for (row=0; row < 2; row++)
+d3604 2
+d3618 2
+a3619 2
+ window[2][col-1] + window[2][col+1] - black*4 )
+ * mul[row & 1] + (window[1][col] - black) * 0.5 + black;
+d3640 1
+d3659 1
+a3659 1
+ if ((val -= black) < 0) val = 0;
+d3674 1
+a3674 1
+ if ((val = white[row][col] - black) > 0)
+d3708 1
+a3708 1
+ val -= black;
+d4528 1
+a4528 1
+ black = (get2()+get2()+get2()+get2())/4;
+d4533 2
+a4534 3
+ if (tag == 0x401 && type == 4 && len == 4) {
+ black = (get4()+get4()+get4()+get4())/4;
+ }
+d4565 1
+a4565 2
+ for (black = i=0; i < 4; i++)
+ black += get2() << 2;
+d4585 1
+a4585 1
+ fseek (ifp, get4(), SEEK_SET);
+d4810 1
+d4813 1
+a4813 1
+ double dblack, cc[4][4], cm[4][3], cam_xyz[4][3], num;
+d4851 4
+a4854 1
+ case 2: case 256: /* ImageWidth */
+d4857 1
+a4857 1
+ case 3: case 257: /* ImageHeight */
+d4861 1
+d4863 1
+a4863 1
+ tiff_ifd[ifd].bps = get2();
+d4886 1
+d4907 1
+d4910 3
+d4976 3
+a4978 1
+ FORC4 cam_mul[c ^ (c >> 1)] = get2();
+d5136 4
+d5141 11
+a5151 5
+ case 50715: /* BlackLevelDeltaH */
+ case 50716: /* BlackLevelDeltaV */
+ for (dblack=i=0; i < len; i++)
+ dblack += getreal(type);
+ black += dblack/len + 0.5;
+a5298 1
+ maximum = 0xffff;
+d5300 1
+a5300 1
+ load_flags = 273;
+d5316 1
+a5316 1
+ load_flags = 79;
+d5319 1
+d5753 5
+d6041 2
+d6149 2
+d6161 1
+a6161 1
+ { "FUJIFILM FinePix S5100", 0, 0x3e00,
+d6163 1
+a6163 1
+ { "FUJIFILM FinePix S5500", 0, 0x3e00,
+d6185 2
+d6235 2
+d6353 1
+a6353 1
+ { "OLYMPUS E-10", 0, 0xffc0,
+d6355 1
+a6355 1
+ { "OLYMPUS E-1", 0, 0xfff0,
+d6357 1
+a6357 1
+ { "OLYMPUS E-20", 0, 0xffc0,
+d6367 1
+a6367 1
+ { "OLYMPUS E-400", 0, 0xfff0,
+d6375 1
+a6375 1
+ { "OLYMPUS E-500", 0, 0xfff0,
+d6385 2
+d6427 1
+a6427 1
+ { "Panasonic DMC-FZ8", 0, 0xf7f0,
+d6433 1
+a6433 1
+ { "Panasonic DMC-FZ30", 0, 0xf94c,
+d6437 1
+a6437 1
+ { "Panasonic DMC-FZ50", 0, 0xfff0, /* aka "LEICA V-LUX1" */
+d6441 1
+a6441 1
+ { "Panasonic DMC-L1", 0, 0xf7fc, /* aka "LEICA DIGILUX 3" */
+d6445 1
+a6445 1
+ { "Panasonic DMC-LX1", 0, 0xf7f0, /* aka "LEICA D-LUX2" */
+d6453 2
+d6457 2
+d6471 2
+a6472 2
+ { "Phase One P65", 0, 0, /* DJC */
+ { 8522,1268,-1916,-7706,16350,1358,-2397,4344,4923 } },
+d6487 1
+a6487 3
+ { "SONY DSLR-A200", 0, 0,
+ { 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } },
+ { "SONY DSLR-A230", 0, 0, /* copied */
+d6497 1
+a6497 1
+ { "SONY DSLR-A5", 254, 0x1ffe,
+d6499 1
+a6499 1
+ { "SONY DSLR-A700", 254, 0x1ffe,
+d6501 1
+a6501 1
+ { "SONY DSLR-A850", 256, 0x1ffe,
+d6503 1
+a6503 1
+ { "SONY DSLR-A900", 254, 0x1ffe,
+d6595 1
+a6595 1
+ int hlen, fsize, i, c, is_canon;
+d6619 1
+d6621 1
+d6665 1
+d6676 2
+d6692 1
+d6717 1
+a6717 1
+ fsize = ftell(ifp);
+d6725 1
+a6725 1
+ parse_ciff (hlen, fsize - hlen);
+d6766 1
+a6766 1
+ data_offset = get4();
+d6793 1
+a6793 1
+ for (i=0; i < sizeof table / sizeof *table; i++)
+d6800 2
+a6801 1
+ if (make[0] == 0) parse_smal (0, fsize);
+d7132 7
+d7270 2
+a7271 2
+ i = find_green (12, 32, 0, fsize/2);
+ c = find_green (12, 32, 0, 3096);
+d7310 1
+a7310 1
+ } else
+d7421 16
+d7468 1
+d7578 1
+a7578 2
+ maximum = 0xfff0;
+ if ((fsize-data_offset) / (width*8/7) == height)
+d7580 4
+a7583 1
+ if (!load_raw) load_raw = &CLASS unpacked_load_raw;
+d7603 1
+d7614 1
+a7614 1
+ maximum = 0xf7f0;
+d7651 1
+d7698 5
+a7702 8
+ if (load_raw == &CLASS olympus_load_raw) {
+ tiff_bps = 12;
+ black >>= 4;
+ } else if (!strcmp(model,"E-10") ||
+ !strncmp(model,"E-20",4)) {
+ black <<= 2;
+ } else if (!strcmp(model,"E-300") ||
+ !strcmp(model,"E-500")) {
+d7705 2
+a7706 2
+ maximum = 0xfc30;
+ black = 0;
+d7711 1
+a7711 1
+ maximum = 0xf790;
+d7713 1
+a7713 1
+ thumb_length = fsize - (thumb_offset = 0xa39800);
+d7741 7
+a7747 2
+ height--;
+ width = ++raw_width;
+d7838 1
+a7838 1
+ if (fsize < 100000) {
+d7998 5
+d8045 2
+a8046 6
+ for (i=0; i < 32; i+=4) {
+ if ((filters >> i & 15) == 9)
+ filters |= 2 << i;
+ if ((filters >> i & 15) == 6)
+ filters |= 8 << i;
+ }
+d8779 4
+@
+
+
1.431
log
@Ignore the first data error in a Pentax *ist D file.