diff options
author | Hubert Figuiere <hub@figuiere.net> | 2011-03-22 21:44:58 -0700 |
---|---|---|
committer | Hubert Figuiere <hub@figuiere.net> | 2011-03-22 21:44:58 -0700 |
commit | 2aeaffd018096d2b6b04aa6b8cafb0c97f1a6f57 (patch) | |
tree | b7fd35bc2f6eada1d6073107c85cf284f2f7ca65 /dcraw | |
parent | e0320831058cc0fcc87936e77988cb26eaf282f6 (diff) |
update dcraw to revision 1.441
Diffstat (limited to 'dcraw')
-rw-r--r-- | dcraw/dcraw.c,v | 1651 |
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 (×tamp); + t = localtime (×tamp); 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 (×tamp); +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. |