From 143cf516d5bed01052860708d35dafbd1f3da970 Mon Sep 17 00:00:00 2001 From: Ingo Date: Sun, 2 Feb 2014 14:56:27 +0100 Subject: [PATCH] Update to dcraw 9.20 Revision: 1.461 --- rtengine/dcraw.c | 273 +++++++++++++++++++++++++++------------- rtengine/dcraw.cc | 289 +++++++++++++++++++++++++++++-------------- rtengine/dcraw.h | 6 +- rtengine/dcraw.patch | 206 ++++++++++++++++-------------- rtengine/rawimage.cc | 21 ++-- 5 files changed, 515 insertions(+), 280 deletions(-) diff --git a/rtengine/dcraw.c b/rtengine/dcraw.c index 32002d76a..059153740 100644 --- a/rtengine/dcraw.c +++ b/rtengine/dcraw.c @@ -1,6 +1,6 @@ /* dcraw.c -- Dave Coffin's raw photo decoder - Copyright 1997-2013 by Dave Coffin, dcoffin a cybercom o net + Copyright 1997-2014 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. @@ -19,11 +19,11 @@ *If you have not modified dcraw.c in any way, a link to my homepage qualifies as "full source code". - $Revision: 1.456 $ - $Date: 2013/06/16 18:01:08 $ + $Revision: 1.461 $ + $Date: 2014/01/31 04:05:31 $ */ -#define DCRAW_VERSION "9.19" +#define DCRAW_VERSION "9.20" #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -80,7 +80,7 @@ typedef unsigned long long UINT64; #include /* Decode compressed Kodak DC120 photos */ #endif /* and Adobe Lossy DNGs */ #ifndef NO_LCMS -#include /* Support color profiles */ +#include /* Support color profiles */ #endif #ifdef LOCALEDIR #include @@ -123,19 +123,19 @@ unsigned shot_order, kodak_cbpp, exif_cfa, unique_id; 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, cblack[4], maximum, mix_green, raw_color, zero_is_bad; +unsigned black, 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; unsigned flip, tiff_flip, filters, colors; ushort raw_height, raw_width, height, width, top_margin, left_margin; ushort shrink, iheight, iwidth, fuji_width, thumb_width, thumb_height; -ushort *raw_image, (*image)[4]; +ushort *raw_image, (*image)[4], cblack[4102]; ushort white[8][8], curve[0x10000], cr2_slice[3], sraw_mul[4]; double pixel_aspect, aber[4]={1,1,1,1}, gamm[6]={ 0.45,4.5,0,0,0,0 }; float bright=1, user_mul[4]={0,0,0,0}, threshold=0; int mask[8][4]; int half_size=0, four_color_rgb=0, document_mode=0, highlight=0; -int verbose=0, use_auto_wb=0, use_camera_wb=0, use_camera_matrix=-1; +int verbose=0, use_auto_wb=0, use_camera_wb=0, use_camera_matrix=1; int output_color=1, output_bps=8, output_tiff=0, med_passes=0; int no_auto_bright=0; unsigned greybox[4] = { 0, 0, UINT_MAX, UINT_MAX }; @@ -1751,10 +1751,10 @@ void CLASS canon_rmf_load_raw() if ((orow -= 2) < 0) orow += raw_height; } - RAW(orow,ocol) = bits >> (10*c+2) & 0x3ff; + RAW(orow,ocol) = curve[bits >> (10*c+2) & 0x3ff]; } } - maximum = 0x3ff; + maximum = curve[0x3ff]; } unsigned CLASS pana_bits (int nbits) @@ -2351,8 +2351,6 @@ void CLASS kodak_rgb_load_raw() int row, col, len, c, i, rgb[3]; ushort *ip=image[0]; - if (raw_image) free (raw_image); - raw_image = 0; for (row=0; row < height; row++) for (col=0; col < width; col+=256) { len = MIN (256, width-col); @@ -2386,8 +2384,8 @@ void CLASS sony_decrypt (unsigned *data, int len, int start, int key) for (p=0; p < 127; p++) pad[p] = htonl(pad[p]); } - while (len--) - *data++ ^= pad[p++ & 127] = pad[(p+1) & 127] ^ pad[(p+65) & 127]; + while (len-- && p++) + *data++ ^= pad[(p-1) & 127] = pad[p & 127] ^ pad[(p+64) & 127]; } void CLASS sony_load_raw() @@ -2445,7 +2443,7 @@ void CLASS sony_arw2_load_raw() ushort pix[16]; int row, col, val, max, min, imax, imin, sh, bit, i; - data = (uchar *) malloc (raw_width); + data = (uchar *) malloc (raw_width+1); merror (data, "sony_arw2_load_raw()"); for (row=0; row < height; row++) { fread (data, 1, raw_width, ifp); @@ -2497,6 +2495,9 @@ void CLASS samsung_load_raw() } } } + for (row=0; row < raw_height-1; row+=2) + for (col=0; col < raw_width-1; col+=2) + SWAP (RAW(row,col+1), RAW(row+1,col)); } #define HOLE(row) ((holes >> (((row) - raw_height) & 7)) & 1) @@ -3417,11 +3418,11 @@ void CLASS crop_masked_pixels() for (col=0; col < width; col++) BAYER2(row,col) = RAW(row+top_margin,col+left_margin); } - if (mask[0][3]) goto mask_set; + if (mask[0][3] > 0) goto mask_set; if (load_raw == &CLASS canon_load_raw || load_raw == &CLASS lossless_jpeg_load_raw) { - mask[0][1] = mask[1][1] = 2; - mask[0][3] = -2; + mask[0][1] = mask[1][1] += 2; + mask[0][3] -= 2; goto sides; } if (load_raw == &CLASS canon_600_load_raw || @@ -3644,7 +3645,7 @@ void CLASS pseudoinverse (double (*in)[3], double (*out)[3], int size) out[i][j] += work[j][k+3] * in[i][k]; } -void CLASS cam_xyz_coeff (double cam_xyz[4][3]) +void CLASS cam_xyz_coeff (float rgb_cam[3][4], double cam_xyz[4][3]) { double cam_rgb[4][3], inverse[4][3], num; int i, j, k; @@ -3662,7 +3663,7 @@ void CLASS cam_xyz_coeff (double cam_xyz[4][3]) pre_mul[i] = 1 / num; } pseudoinverse (cam_rgb, inverse, colors); - for (raw_color = i=0; i < 3; i++) + for (i=0; i < 3; i++) for (j=0; j < colors; j++) rgb_cam[i][j] = inverse[j][i]; } @@ -3721,11 +3722,11 @@ void CLASS colorcheck() (1 - gmb_xyY[sq][0] - gmb_xyY[sq][1]) / gmb_xyY[sq][1]; } pseudoinverse (gmb_xyz, inverse, NSQ); - for (i=0; i < colors; i++) + for (raw_color = i=0; i < colors; i++) for (j=0; j < 3; j++) for (cam_xyz[i][j] = k=0; k < NSQ; k++) cam_xyz[i][j] += gmb_cam[k][i] * inverse[k][j]; - cam_xyz_coeff (cam_xyz); + cam_xyz_coeff (rgb_cam, cam_xyz); if (verbose) { printf (" { \"%s %s\", %d,\n\t{", make, model, black); num = 10000 / (cam_xyz[1][0] + cam_xyz[1][1] + cam_xyz[1][2]); @@ -3898,10 +3899,17 @@ skip_block: ; FORC4 fprintf (stderr, " %f", pre_mul[c]); fputc ('\n', stderr); } + if (filters > 1000 && (cblack[4]+1)/2 == 1 && (cblack[5]+1)/2 == 1) { + FORC4 cblack[FC(c/2,c%2)] += + cblack[6 + c/2 % cblack[4] * cblack[5] + c%2 % cblack[5]]; + cblack[4] = cblack[5] = 0; + } size = iheight*iwidth; for (i=0; i < size*4; i++) { - val = image[0][i]; - if (!val) continue; + if (!(val = image[0][i])) continue; + if (cblack[4] && cblack[5]) + val -= cblack[6 + i/4 / iwidth % cblack[4] * cblack[5] + + i/4 % iwidth % cblack[5]]; val -= cblack[i & 3]; val *= scale_mul[i & 3]; image[0][i] = CLIP(val); @@ -4841,10 +4849,12 @@ void CLASS parse_makernote (int base, int uptag) if (get2() != 42) goto quit; offset = get4(); fseek (ifp, offset-8, SEEK_CUR); - } else if (!strcmp (buf,"OLYMPUS")) { + } else if (!strcmp (buf,"OLYMPUS") || + !strcmp (buf,"PENTAX ")) { base = ftell(ifp)-10; fseek (ifp, -2, SEEK_CUR); - order = get2(); get2(); + order = get2(); + if (buf[0] == 'O') get2(); } else if (!strncmp (buf,"SONY",4) || !strcmp (buf,"Panasonic")) { goto nf; @@ -5177,7 +5187,8 @@ void CLASS parse_mos (int offset) { "","DCB2","Volare","Cantare","CMost","Valeo 6","Valeo 11","Valeo 22", "Valeo 11p","Valeo 17","","Aptus 17","Aptus 22","Aptus 75","Aptus 65", "Aptus 54S","Aptus 65S","Aptus 75S","AFi 5","AFi 6","AFi 7", - "","","","","","","","","","","","","","","","","","AFi-II 12" }; + "Aptus-II 7","","","Aptus-II 6","","","Aptus-II 10","Aptus-II 5", + "","","","","Aptus-II 10R","Aptus-II 8","","Aptus-II 12","","AFi-II 12" }; float romm_cam[3][3]; fseek (ifp, offset, SEEK_SET); @@ -5291,7 +5302,6 @@ 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 cc[4][4], cm[4][3], cam_xyz[4][3], num; @@ -5642,22 +5652,16 @@ guess_cfa_pc: linear_table (len); break; case 50713: /* BlackLevelRepeatDim */ - blrr = get2(); - blrc = get2(); + cblack[4] = get2(); + cblack[5] = get2(); + if (cblack[4] * cblack[5] > sizeof cblack / sizeof *cblack - 6) + cblack[4] = cblack[5] = 1; break; case 61450: - blrr = blrc = 2; + cblack[4] = cblack[5] = MIN(sqrt(len),64); case 50714: /* BlackLevel */ - black = getreal(type); - if ((unsigned)(filters+1) < 1000) 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]; + FORC (cblack[4] * cblack[5]) + cblack[6+c] = getreal(type); black = 0; break; case 50715: /* BlackLevelDeltaH */ @@ -5752,7 +5756,7 @@ guess_cfa_pc: FORCC for (i=0; i < 3; i++) for (cam_xyz[c][i]=j=0; j < colors; j++) cam_xyz[c][i] += cc[c][j] * cm[j][i] * xyz[i]; - cam_xyz_coeff (cam_xyz); + cam_xyz_coeff (cmatrix, cam_xyz); } if (asn[0]) { cam_mul[3] = 0; @@ -6620,6 +6624,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 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 70D", 0, 0x3bc7, + { 7034,-804,-1014,-4420,12564,2058,-851,1994,5758 } }, { "Canon EOS 100D", 0, 0x350f, { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } }, { "Canon EOS 300D", 0, 0xfa0, @@ -6666,6 +6672,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 6847,-614,-1014,-4669,12737,2139,-1197,2488,6846 } }, { "Canon EOS-1D", 0, 0xe20, { 6806,-179,-1020,-8097,16415,1687,-3267,4236,7690 } }, + { "Canon EOS C500", 853, 0, /* DJC */ + { 17851,-10604,922,-7425,16662,763,-3660,3636,22278 } }, { "Canon PowerShot A530", 0, 0, { 0 } }, /* don't want the A5 matrix */ { "Canon PowerShot A50", 0, 0, @@ -6680,6 +6688,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 13244,-5501,-1248,-1508,9858,1935,-270,1083,4366 } }, { "Canon PowerShot G15", 0, 0, { 7474,-2301,-567,-4056,11456,2975,-222,716,4181 } }, + { "Canon PowerShot G16", 0, 0, + { 8020,-2687,-682,-3704,11879,2052,-965,1921,5556 } }, { "Canon PowerShot G1 X", 0, 0, { 7378,-1255,-1043,-4088,12251,2048,-876,1946,5805 } }, { "Canon PowerShot G1", 0, 0, @@ -6720,6 +6730,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 7968,-2565,-636,-2873,10697,2513,180,667,4211 } }, { "Canon PowerShot S110", 0, 0, { 8039,-2643,-654,-3783,11230,2930,-206,690,4194 } }, + { "Canon PowerShot S120", 0, 0, + { 6961,-1685,-695,-4625,12945,1836,-1114,2152,5518 } }, { "Canon PowerShot SX1 IS", 0, 0, { 6578,-259,-502,-5974,13030,3309,-308,1058,4970 } }, { "Canon PowerShot SX50 HS", 0, 0, @@ -6778,10 +6790,10 @@ void CLASS adobe_coeff (const char *make, const char *model) { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, { "Fujifilm S100FS", 514, 0, { 11521,-4355,-1065,-6524,13767,3058,-1466,1984,6045 } }, - { "Fujifilm S200EXR", 512, 0x3fff, - { 11401,-4498,-1312,-5088,12751,2613,-838,1568,5941 } }, { "Fujifilm S20Pro", 0, 0, { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } }, + { "Fujifilm S20", 512, 0x3fff, + { 11401,-4498,-1312,-5088,12751,2613,-838,1568,5941 } }, { "Fujifilm S2Pro", 128, 0, { 12492,-4690,-1402,-7033,15423,1647,-1507,2111,7697 } }, { "Fujifilm S3Pro", 0, 0, @@ -6818,12 +6830,14 @@ void CLASS adobe_coeff (const char *make, const char *model) { 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } }, { "Fujifilm HS10 HS11", 0, 0xf68, { 12440,-3954,-1183,-1123,9674,1708,-83,1614,4086 } }, - { "Fujifilm HS20EXR", 0, 0, + { "Fujifilm HS2", 0, 0, { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, { "Fujifilm HS3", 0, 0, { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, { "Fujifilm HS50EXR", 0, 0, { 12085,-4727,-953,-3257,11489,2002,-511,2046,4592 } }, + { "Fujifilm F900EXR", 0, 0, + { 12085,-4727,-953,-3257,11489,2002,-511,2046,4592 } }, { "Fujifilm X100S", 0, 0, { 10592,-4262,-1008,-3514,11355,2465,-870,2025,6386 } }, { "Fujifilm X100", 0, 0, @@ -6834,12 +6848,20 @@ void CLASS adobe_coeff (const char *make, const char *model) { 11768,-4971,-1133,-4904,12927,2183,-480,1723,4605 } }, { "Fujifilm X-Pro1", 0, 0, { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, + { "Fujifilm X-A1", 0, 0, + { 11086,-4555,-839,-3512,11310,2517,-815,1341,5940 } }, { "Fujifilm X-E1", 0, 0, { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, - { "Fujifilm XF1", 0, 0, - { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } }, + { "Fujifilm X-E2", 0, 0, + { 8458,-2451,-855,-4597,12447,2407,-1475,2482,6526 } }, + { "Fujifilm X-M1", 0, 0, + { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, { "Fujifilm X-S1", 0, 0, { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } }, + { "Fujifilm XF1", 0, 0, + { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } }, + { "Fujifilm XQ1", 0, 0, + { 9252,-2704,-1064,-5893,14265,1717,-1101,2341,4349 } }, { "Imacon Ixpress", 0, 0, /* DJC */ { 7025,-1415,-704,-5188,13765,1424,-1248,2742,6038 } }, { "Kodak NC2000", 0, 0, @@ -6950,6 +6972,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 7911,-2167,-813,-5327,13150,2408,-1288,2483,7968 } }, { "Nikon D3200", 0, 0xfb9, { 7013,-1408,-635,-5268,12902,2640,-1470,2801,7379 } }, + { "Nikon D3300", 147, 0, /* DJC */ + { 6108,-2161,-13,-4091,9871,4220,-1222,2469,7907 } }, { "Nikon D300", 0, 0, { 9030,-1992,-715,-8465,16302,2255,-2689,3217,8069 } }, { "Nikon D3X", 0, 0, @@ -6964,16 +6988,22 @@ void CLASS adobe_coeff (const char *make, const char *model) { 6992,-1668,-806,-8138,15748,2543,-874,850,7897 } }, { "Nikon D4", 0, 0, { 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } }, + { "Nikon Df", 0, 0, + { 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } }, { "Nikon D5000", 0, 0xf00, { 7309,-1403,-519,-8474,16008,2622,-2433,2826,8064 } }, { "Nikon D5100", 0, 0x3de6, { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } }, { "Nikon D5200", 0, 0, { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } }, + { "Nikon D5300", 600, 0, + { 6988,-1384,-714,-5631,13410,2447,-1485,2204,7318 } }, { "Nikon D50", 0, 0, { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } }, { "Nikon D600", 0, 0x3e07, { 8178,-2245,-609,-4857,12394,2776,-1207,2086,7298 } }, + { "Nikon D610", 0, 0, + { 8178,-2245,-609,-4857,12394,2776,-1207,2086,7298 } }, { "Nikon D60", 0, 0, { 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } }, { "Nikon D7000", 0, 0, @@ -7032,10 +7062,14 @@ void CLASS adobe_coeff (const char *make, const char *model) { 11053,-4269,-1024,-1976,10182,2088,-526,1263,4469 } }, { "Nikon COOLPIX P7700", 200, 0, { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } }, + { "Nikon COOLPIX P7800", 200, 0, + { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } }, { "Nikon 1 V2", 0, 0, { 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } }, { "Nikon 1 J3", 0, 0, { 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } }, + { "Nikon 1 AW1", 0, 0, + { 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } }, { "Nikon 1 ", 0, 0, { 8994,-2667,-865,-4594,12324,2552,-699,1786,6260 } }, { "Olympus C5050", 0, 0, @@ -7088,6 +7122,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8343,-2050,-1021,-7715,15705,2103,-1831,2380,8235 } }, { "Olympus E-P3", 0, 0, { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } }, + { "Olympus E-P5", 0, 0, + { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, { "Olympus E-PL1s", 0, 0, { 11409,-3872,-1393,-4572,12757,2003,-709,1810,7415 } }, { "Olympus E-PL1", 0, 0, @@ -7098,10 +7134,14 @@ void CLASS adobe_coeff (const char *make, const char *model) { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } }, { "Olympus E-PL5", 0, 0xfcb, { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, + { "Olympus E-PL6", 0, 0, + { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, { "Olympus E-PM1", 0, 0, { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } }, { "Olympus E-PM2", 0, 0, { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, + { "Olympus E-M1", 0, 0, + { 7687,-1984,-606,-4327,11928,2721,-1381,2339,6452 } }, { "Olympus E-M5", 0, 0xfe1, { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, { "Olympus SP350", 0, 0, @@ -7118,6 +7158,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 10915,-3677,-982,-5587,12986,2911,-1168,1968,6223 } }, { "Olympus SP570UZ", 0, 0, { 11522,-4044,-1146,-4736,12172,2904,-988,1829,6039 } }, + { "Olympus STYLUS1", 0, 0, + { 8360,-2420,-880,-3928,12353,1739,-1381,2416,5173 } }, { "Olympus XZ-10", 0, 0, { 9777,-3483,-925,-2886,11297,1800,-602,1663,5134 } }, { "Olympus XZ-1", 0, 0, @@ -7152,6 +7194,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 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-3", 0, 0, + { 7415,-2052,-721,-5186,12788,2682,-1446,2157,6773 } }, { "Pentax K-5 II", 0, 0, { 8170,-2725,-639,-4440,12017,2744,-771,1465,6599 } }, { "Pentax K-5", 0, 0, @@ -7174,6 +7218,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 13639,-5535,-1371,-1698,9633,2430,316,1152,4108 } }, { "Panasonic DMC-FZ50", 0, 0, { 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } }, + { "Panasonic DMC-FZ7", 144, 0, + { 11532,-4324,-1066,-2375,10847,1749,-564,1699,4351 } }, { "Leica V-LUX1", 0, 0, { 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } }, { "Panasonic DMC-L10", 15, 0xf96, @@ -7186,6 +7232,10 @@ void CLASS adobe_coeff (const char *make, const char *model) { 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } }, { "Leica DIGILUX 2", 0, 0, { 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } }, + { "Panasonic DMC-LF1", 143, 0, + { 9379,-3267,-816,-3227,11560,1881,-926,1928,5340 } }, + { "Leica C (Typ 112)", 143, 0, + { 9379,-3267,-816,-3227,11560,1881,-926,1928,5340 } }, { "Panasonic DMC-LX1", 0, 0xf7f, { 10704,-4187,-1230,-8314,15952,2501,-920,945,8927 } }, { "Leica D-LUX2", 0, 0xf7f, @@ -7230,8 +7280,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } }, { "Panasonic DMC-G5", 143, 0xfff, { 7798,-2562,-740,-3879,11584,2613,-1055,2248,5434 } }, - { "Panasonic DMC-G6", 143, 0xfff, /* DJC */ - { 6395,-2583,-40,-3677,9109,4569,-1502,2806,6431 } }, + { "Panasonic DMC-G6", 142, 0xfff, + { 8294,-2891,-651,-3869,11590,2595,-1183,2267,5352 } }, { "Panasonic DMC-GF1", 15, 0xf92, { 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } }, { "Panasonic DMC-GF2", 143, 0xfff, @@ -7248,8 +7298,14 @@ void CLASS adobe_coeff (const char *make, const char *model) { 7780,-2410,-806,-3913,11724,2484,-1018,2390,5298 } }, { "Panasonic DMC-GH3", 144, 0, { 6559,-1752,-491,-3672,11407,2586,-962,1875,5130 } }, + { "Panasonic DMC-GM1", 143, 0, + { 6770,-1895,-744,-5232,13145,2303,-1664,2691,5703 } }, { "Panasonic DMC-GX1", 143, 0, { 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } }, + { "Panasonic DMC-GX7", 143, 0, + { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } }, + { "Panasonic DMC-TZ61", 143, 0, /* DJC */ + { 6211,-2325,27,-3800,9449,4352,-943,2166,6293 } }, { "Phase One H 20", 0, 0, /* DJC */ { 1313,1855,-109,-6715,15908,808,-327,1840,6020 } }, { "Phase One H 25", 0, 0, @@ -7270,6 +7326,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8898,-2498,-994,-3144,11328,2066,-760,1381,4576 } }, { "Samsung EX2F", 0, 0x7ff, { 10648,-3897,-1055,-2022,10573,1668,-492,1611,4742 } }, + { "Samsung EK-GN120", 0, 0, + { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } }, { "Samsung NX300", 0, 0, { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } }, { "Samsung NX2000", 0, 0, @@ -7286,6 +7344,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 12093,-3557,-1155,-1000,9534,1733,-22,1787,4576 } }, { "Samsung GX-1", 0, 0, { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } }, + { "Samsung GX20", 0, 0, /* copied from Pentax K20D */ + { 9427,-2714,-868,-7493,16092,1373,-2199,3264,7180 } }, { "Samsung S85", 0, 0, /* DJC */ { 11885,-3968,-1473,-4214,12299,1916,-835,1655,5549 } }, { "Sinar", 0, 0, /* DJC */ @@ -7296,8 +7356,12 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8512,-2641,-694,-8042,15670,2526,-1821,2117,7414 } }, { "Sony DSC-V3", 0, 0, { 7511,-2571,-692,-7894,15088,3060,-948,1111,8128 } }, + { "Sony DSC-RX100M2", 200, 0, + { 6596,-2079,-562,-4782,13016,1933,-970,1581,5181 } }, { "Sony DSC-RX100", 200, 0, { 8651,-2754,-1057,-3464,12207,1373,-568,1398,4434 } }, + { "Sony DSC-RX10", 200, 0, + { 6679,-1825,-745,-5047,13256,1953,-1580,2422,5183 } }, { "Sony DSC-RX1", 128, 0, { 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } }, { "Sony DSLR-A100", 0, 0xfeb, @@ -7322,16 +7386,26 @@ void CLASS adobe_coeff (const char *make, const char *model) { 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, + { "Sony DSLR-A700", 128, 0, { 5775,-805,-359,-8574,16295,2391,-1943,2341,7249 } }, { "Sony DSLR-A850", 128, 0, { 5413,-1162,-365,-5665,13098,2866,-608,1179,8440 } }, { "Sony DSLR-A900", 128, 0, { 5209,-1072,-397,-8845,16120,2919,-1618,1803,8654 } }, + { "Sony ILCE-7R", 128, 0, + { 4913,-541,-202,-6130,13513,2906,-1564,2151,7183 } }, + { "Sony ILCE-7", 128, 0, + { 5271,-712,-347,-6153,13653,2763,-1601,2366,7242 } }, + { "Sony ILCE-3000", 128, 0, + { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, + { "Sony ILCE-5000", 128, 0, /* DJC */ + { 4130,-1407,93,-4151,9566,4586,-1035,1976,7000 } }, { "Sony NEX-5N", 128, 0, { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, { "Sony NEX-5R", 128, 0, { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } }, + { "Sony NEX-5T", 128, 0, + { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } }, { "Sony NEX-3N", 128, 0, { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } }, { "Sony NEX-3", 138, 0, /* DJC */ @@ -7377,9 +7451,9 @@ void CLASS adobe_coeff (const char *make, const char *model) if (table[i].black) black = (ushort) table[i].black; if (table[i].maximum) maximum = (ushort) table[i].maximum; if (table[i].trans[0]) { - for (j=0; j < 12; j++) + for (raw_color = j=0; j < 12; j++) cam_xyz[0][j] = table[i].trans[j] / 10000.0; - cam_xyz_coeff (cam_xyz); + cam_xyz_coeff (rgb_cam, cam_xyz); } break; } @@ -7480,13 +7554,13 @@ void CLASS identify() { 4508, 2962, 0, 0, -3, -4 }, { 4508, 3330, 0, 0, -3, -6 }, }; - static const ushort canon[][6] = { + static const ushort canon[][11] = { { 1944, 1416, 0, 0, 48, 0 }, - { 2144, 1560, 4, 8, 52, 2 }, + { 2144, 1560, 4, 8, 52, 2, 0, 0, 0, 25 }, { 2224, 1456, 48, 6, 0, 2 }, { 2376, 1728, 12, 6, 52, 2 }, { 2672, 1968, 12, 6, 44, 2 }, - { 3152, 2068, 64, 12, 0, 0 }, + { 3152, 2068, 64, 12, 0, 0, 16 }, { 3160, 2344, 44, 12, 4, 4 }, { 3344, 2484, 4, 6, 52, 6 }, { 3516, 2328, 42, 14, 0, 0 }, @@ -7494,16 +7568,17 @@ void CLASS identify() { 3744, 2784, 52, 12, 8, 12 }, { 3944, 2622, 30, 18, 6, 2 }, { 3948, 2622, 42, 18, 0, 2 }, - { 3984, 2622, 76, 20, 0, 2 }, + { 3984, 2622, 76, 20, 0, 2, 14 }, { 4104, 3048, 48, 12, 24, 12 }, { 4116, 2178, 4, 2, 0, 0 }, { 4152, 2772, 192, 12, 0, 0 }, { 4160, 3124, 104, 11, 8, 65 }, - { 4176, 3062, 96, 17, 8, 0 }, + { 4176, 3062, 96, 17, 8, 0, 0, 16, 0, 7, 0x49 }, + { 4192, 3062, 96, 17, 24, 0, 0, 16, 0, 0, 0x49 }, { 4312, 2876, 22, 18, 0, 2 }, { 4352, 2874, 62, 18, 0, 0 }, { 4476, 2954, 90, 34, 0, 0 }, - { 4480, 3348, 12, 10, 36, 12 }, + { 4480, 3348, 12, 10, 36, 12, 0, 0, 0, 18, 0x49 }, { 4496, 3366, 80, 50, 12, 0 }, { 4832, 3204, 62, 26, 0, 0 }, { 4832, 3228, 62, 51, 0, 0 }, @@ -7528,6 +7603,7 @@ void CLASS identify() { 0x190, "EOS 40D" }, { 0x169, "EOS-1D Mark III" }, { 0x261, "EOS 50D" }, { 0x281, "EOS-1D Mark IV" }, { 0x287, "EOS 60D" }, { 0x167, "EOS-1DS" }, + { 0x325, "EOS 70D" }, { 0x170, "EOS 300D" }, { 0x188, "EOS-1Ds Mark II" }, { 0x176, "EOS 450D" }, { 0x215, "EOS-1Ds Mark III" }, { 0x189, "EOS 350D" }, { 0x324, "EOS-1D C" }, @@ -7557,6 +7633,7 @@ void CLASS identify() { 10134620,2588,1958, 0, 0, 0, 0, 9,0x94,0,0,"AVT","F-510C",12 }, { 16157136,3272,2469, 0, 0, 0, 0, 9,0x94,0,0,"AVT","F-810C" }, { 15980544,3264,2448, 0, 0, 0, 0, 8,0x61,0,1,"AgfaPhoto","DC-833m" }, + { 9631728,2532,1902, 0, 0, 0, 0,96,0x61,0,0,"Alcatel","5035D" }, { 2868726,1384,1036, 0, 0, 0, 0,64,0x49,0,8,"Baumer","TXG14",1078 }, { 5298000,2400,1766,12,12,44, 2,40,0x94,0,2,"Canon","PowerShot SD300" }, { 6553440,2664,1968, 4, 4,44, 4,40,0x94,0,2,"Canon","PowerShot A460" }, @@ -7572,7 +7649,7 @@ void CLASS identify() { 15467760,3720,2772, 6,12,30, 0,40,0x94,0,2,"Canon","PowerShot SX110 IS" }, { 15534576,3728,2778,12, 9,44, 9,40,0x94,0,2,"Canon","PowerShot SX120 IS" }, { 18653760,4080,3048,24,12,24,12,40,0x94,0,2,"Canon","PowerShot SX20 IS" }, - { 19131120,4168,3060,92,16, 4, 1, 8,0x94,0,2,"Canon","PowerShot SX220 HS" }, + { 19131120,4168,3060,92,16, 4, 1,40,0x94,0,2,"Canon","PowerShot SX220 HS" }, { 21936096,4464,3276,25,10,73,12,40,0x16,0,2,"Canon","PowerShot SX30 IS" }, { 24724224,4704,3504, 8,16,56, 8,40,0x94,0,2,"Canon","PowerShot A3300 IS" }, { 1976352,1632,1211, 0, 2, 0, 1, 0,0x94,0,1,"Casio","QV-2000UX" }, @@ -7597,6 +7674,8 @@ void CLASS identify() { 18702336,4096,3044, 0, 0,24, 0,80,0x94,7,1,"Casio","EX-ZR100" }, { 7684000,2260,1700, 0, 0, 0, 0,13,0x94,0,1,"Casio","QV-4000" }, { 787456,1024, 769, 0, 1, 0, 0, 0,0x49,0,0,"Creative","PC-CAM 600" }, + { 28829184,4384,3288, 0, 0, 0, 0,36,0x61,0,0,"DJI" }, + { 15151104,4608,3288, 0, 0, 0, 0, 0,0x94,0,0,"Matrix" }, { 3840000,1600,1200, 0, 0, 0, 0,65,0x49,0,0,"Foculus","531C" }, { 307200, 640, 480, 0, 0, 0, 0, 0,0x94,0,0,"Generic","640x480" }, { 62464, 256, 244, 1, 1, 6, 1, 0,0x8d,0,0,"Kodak","DC20" }, @@ -7608,6 +7687,9 @@ void CLASS identify() { 6166488,2864,2152, 0, 0, 0, 0, 0,0x94,0,0,"Kodak","C603",3160 }, { 460800, 640, 480, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","C603" }, { 9116448,2848,2134, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","C603" }, + { 12241200,4040,3030, 2, 0, 0,13, 0,0x49,0,0,"Kodak","12MP" }, + { 12272756,4040,3030, 2, 0, 0,13, 0,0x49,0,0,"Kodak","12MP",31556 }, + { 18000000,4000,3000, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","12MP" }, { 614400, 640, 480, 0, 3, 0, 0,64,0x94,0,0,"Kodak","KAI-0340" }, { 3884928,1608,1207, 0, 0, 0, 0,96,0x16,0,0,"Micron","2010",3212 }, { 1138688,1534, 986, 0, 0, 0, 0, 0,0x61,0,0,"Minolta","RD175",513 }, @@ -7751,15 +7833,18 @@ void CLASS identify() 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; + switch (tiff_bps = i*8 / (width * height)) { + case 8: load_raw = &CLASS eight_bit_load_raw; break; + case 10: load_raw = &CLASS nokia_load_raw; + } + raw_height = height + (top_margin = i / (width * tiff_bps/8) - height); + mask[0][3] = 1; filters = 0x61616161; } else if (!memcmp (head,"ARRI",4)) { order = 0x4949; @@ -7783,6 +7868,7 @@ void CLASS identify() fread (model, 1, 30, ifp); data_offset = 0x10000; load_raw = &CLASS canon_rmf_load_raw; + gamma_curve (0, 12.25, 1, 1023); } else if (!memcmp (head+4,"RED1",4)) { strcpy (make, "Red"); strcpy (model,"One"); @@ -7822,7 +7908,7 @@ void CLASS identify() switch (tiff_bps = (fsize-data_offset)*8 / (raw_width*raw_height)) { case 6: load_raw = &CLASS minolta_rd175_load_raw; break; - case 8: + case 8: load_raw = &CLASS eight_bit_load_raw; break; case 10: case 12: load_flags |= 128; @@ -7857,6 +7943,8 @@ void CLASS identify() ((cp = strcasestr(model," DIGITAL CAMERA")) || (cp = strstr(model,"FILE VERSION")))) *cp = 0; + if (!strncasecmp(model,"PENTAX",6)) + strcpy (make, "Pentax"); cp = make + strlen(make); /* Remove trailing spaces */ while (*--cp == ' ') *cp = 0; cp = model + strlen(model); @@ -7883,6 +7971,8 @@ void CLASS identify() { left_margin = 10; width = 4950; filters = 0x16161616; } if (width == 4736 && !strcmp(model,"K-7")) { height = 3122; width = 4684; filters = 0x16161616; top_margin = 2; } + if (width == 6080 && !strcmp(model,"K-3")) + { left_margin = 4; width = 6040; } if (width == 7424 && !strcmp(model,"645D")) { height = 5502; width = 7328; filters = 0x61616161; top_margin = 29; left_margin = 48; } @@ -7909,6 +7999,11 @@ void CLASS identify() height = raw_height - (top_margin = canon[i][3]); width -= canon[i][4]; height -= canon[i][5]; + mask[0][1] = canon[i][6]; + mask[0][3] = -canon[i][7]; + mask[1][1] = canon[i][8]; + mask[1][3] = -canon[i][9]; + if (canon[i][10]) filters = canon[i][10] * 0x01010101; } if ((unique_id | 0x20000) == 0x2720000) { left_margin = 8; @@ -7984,16 +8079,7 @@ canon_a5: } else if (!strcmp(model,"PowerShot A610")) { if (canon_s2is()) strcpy (model+10, "S2 IS"); } else if (!strcmp(model,"PowerShot SX220 HS")) { - mask[0][0] = top_margin = 16; - mask[0][2] = top_margin + height; - mask[0][3] = left_margin = 92; - } else if (!strcmp(model,"PowerShot SX50 HS")) { - mask[0][0] = top_margin = 17; - mask[0][2] = raw_height; - mask[0][3] = 80; - filters = 0x49494949; - } else if (!strcmp(model,"PowerShot G10")) { - filters = 0x49494949; + mask[1][3] = -4; } else if (!strcmp(model,"EOS D2000C")) { filters = 0x61616161; black = curve[200]; @@ -8028,7 +8114,8 @@ canon_a5: !strcmp(model,"D600") || !strncmp(model,"D800",4)) { width -= 46; - } else if (!strcmp(model,"D4")) { + } else if (!strcmp(model,"D4") || + !strcmp(model,"Df")) { width -= 52; left_margin = 2; } else if (!strncmp(model,"D40",3) || @@ -8132,7 +8219,8 @@ canon_a5: if (width == 4032 || width == 4952) left_margin = 0; if (width == 3328 && (width -= 66)) left_margin = 34; if (width == 4936) left_margin = 4; - if (!strcmp(model,"HS50EXR")) { + if (!strcmp(model,"HS50EXR") || + !strcmp(model,"F900EXR")) { width += 2; left_margin = 0; filters = 0x16161616; @@ -8191,7 +8279,8 @@ konica_400z: } else if (!strcmp(make,"Samsung") && raw_height == 3714) { height -= 18; width = 5536; - filters = 0x49494949; + filters = 0x61616161; + colors = 3; } else if (!strcmp(make,"Samsung") && raw_width == 5632) { order = 0x4949; height = 3694; @@ -8396,10 +8485,11 @@ konica_400z: height -= top_margin = 4; width -= left_margin = 32; gamma_curve (0, 7, 1, 255); - } else if (!strcmp(model,"C603") || !strcmp(model,"C330")) { + } else if (!strcmp(model,"C603") || !strcmp(model,"C330") + || !strcmp(model,"12MP")) { order = 0x4949; if (filters && data_offset) { - fseek (ifp, 168, SEEK_SET); + fseek (ifp, data_offset < 4096 ? 168 : 5252, SEEK_SET); read_shorts (curve, 256); } else gamma_curve (0, 3.875, 1, 255); load_raw = filters ? &CLASS eight_bit_load_raw @@ -8527,9 +8617,6 @@ konica_400z: if (!model[0]) sprintf (model, "%dx%d", width, height); if (filters == UINT_MAX) filters = 0x94949494; - if (raw_color) adobe_coeff (make, model); - if (load_raw == &CLASS kodak_radc_load_raw) - if (raw_color) adobe_coeff ("Apple","Quicktake"); if (thumb_offset && !thumb_height) { fseek (ifp, thumb_offset, SEEK_SET); if (ljpeg_start (&jh, 1)) { @@ -8538,6 +8625,14 @@ konica_400z: } } dng_skip: + if ((use_camera_matrix & (use_camera_wb || dng_version)) + && cmatrix[0][0] > 0.125) { + memcpy (rgb_cam, cmatrix, sizeof cmatrix); + raw_color = 0; + } + if (raw_color) adobe_coeff (make, model); + if (load_raw == &CLASS kodak_radc_load_raw) + if (raw_color) adobe_coeff ("Apple","Quicktake"); if (fuji_width) { fuji_width = width >> !fuji_layout; if (~fuji_width & 1) filters = 0x49494949; @@ -8589,7 +8684,6 @@ void CLASS apply_profile (const char *input, const char *output) FILE *fp; unsigned size; - cmsErrorAction (LCMS_ERROR_SHOW); if (strcmp (input, "embed")) hInProfile = cmsOpenProfileFromFile (input, "r"); else if (profile_length) { @@ -9125,7 +9219,7 @@ int CLASS main (int argc, const char **argv) case 'A': FORC4 greybox[c] = atoi(argv[arg++]); case 'a': use_auto_wb = 1; break; case 'w': use_camera_wb = 1; break; - case 'M': use_camera_matrix = (opm == '+'); break; + case 'M': use_camera_matrix = 3 * (opm == '+'); break; case 'I': read_from_stdin = 1; break; case 'E': document_mode++; case 'D': document_mode++; @@ -9141,8 +9235,6 @@ int CLASS main (int argc, const char **argv) return 1; } } - if (use_camera_matrix < 0) - use_camera_matrix = use_camera_wb; if (arg == argc) { fprintf (stderr,_("No files to process.\n")); return 1; @@ -9209,6 +9301,7 @@ int CLASS main (int argc, const char **argv) height = thumb_height; width = thumb_width; filters = 0; + colors = 3; } else { fseek (ifp, thumb_offset, SEEK_SET); write_fun = write_thumb; @@ -9293,10 +9386,6 @@ next: fclose(ifp); continue; } - if (use_camera_matrix && cmatrix[0][0] > 0.25) { - memcpy (rgb_cam, cmatrix, sizeof cmatrix); - raw_color = 0; - } if (meta_length) { meta_data = (char *) malloc (meta_length); merror (meta_data, "main()"); @@ -9340,6 +9429,12 @@ next: FORC3 if (i > cblack[c]) i = cblack[c]; FORC4 cblack[c] -= i; black += i; + i = cblack[6]; + FORC (cblack[4] * cblack[5]) + if (i > cblack[6+c]) i = cblack[6+c]; + FORC (cblack[4] * cblack[5]) + cblack[6+c] -= i; + black += i; if (user_black >= 0) black = user_black; FORC4 cblack[c] += black; if (user_sat > 0) maximum = user_sat; diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index 5e981627b..acf2d1461 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -12,7 +12,7 @@ /* dcraw.c -- Dave Coffin's raw photo decoder - Copyright 1997-2013 by Dave Coffin, dcoffin a cybercom o net + Copyright 1997-2014 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. @@ -31,11 +31,11 @@ *If you have not modified dcraw.c in any way, a link to my homepage qualifies as "full source code". - $Revision: 1.456 $ - $Date: 2013/06/16 18:01:08 $ + $Revision: 1.461 $ + $Date: 2014/01/31 04:05:31 $ */ -#define DCRAW_VERSION "9.19" +#define DCRAW_VERSION "9.20" #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -92,7 +92,7 @@ typedef unsigned long long UINT64; #include /* Decode compressed Kodak DC120 photos */ #endif /* and Adobe Lossy DNGs */ #ifndef NO_LCMS -#include /* Support color profiles */ +#include /* Support color profiles */ #endif #ifdef LOCALEDIR #include @@ -113,13 +113,14 @@ typedef unsigned long long UINT64; #define ushort UshORt typedef unsigned char uchar; typedef unsigned short ushort; - + #include "dcraw.h" /* RT All global variables are defined here, and all functions that access them are prefixed with "CLASS". Note that a thread-safe C++ class cannot have non-const static local variables. -*/ + */ + const double xyz_rgb[3][3] = { // XYZ from RGB { 0.412453, 0.357580, 0.180423 }, { 0.212671, 0.715160, 0.072169 }, @@ -1715,10 +1716,10 @@ void CLASS canon_rmf_load_raw() if ((orow -= 2) < 0) orow += raw_height; } - RAW(orow,ocol) = bits >> (10*c+2) & 0x3ff; + RAW(orow,ocol) = curve[bits >> (10*c+2) & 0x3ff]; } } - maximum = 0x3ff; + maximum = curve[0x3ff]; } unsigned CLASS pana_bits_t::operator() (int nbits) @@ -2315,8 +2316,6 @@ void CLASS kodak_rgb_load_raw() int row, col, len, c, i, rgb[3]; ushort *ip=image[0]; - if (raw_image) free (raw_image); - raw_image = 0; for (row=0; row < height; row++) for (col=0; col < width; col+=256) { len = MIN (256, width-col); @@ -2349,10 +2348,8 @@ void CLASS sony_decrypt_t::operator()(unsigned *data, int len, int start, int ke for (p=0; p < 127; p++) pad[p] = htonl(pad[p]); } - while (len--){ - *data++ ^= pad[p & 127] = pad[(p+1) & 127] ^ pad[(p+65) & 127]; - p++; - } + while (len-- && p++) + *data++ ^= pad[(p-1) & 127] = pad[p & 127] ^ pad[(p+64) & 127]; } void CLASS sony_load_raw() @@ -2410,8 +2407,7 @@ void CLASS sony_arw2_load_raw() ushort pix[16]; int row, col, val, max, min, imax, imin, sh, bit, i; - //data = (uchar *) malloc (raw_width); - data = (uchar *) malloc (raw_width + 1); // RT: added +1 to avoid buffer overrun + data = (uchar *) malloc (raw_width+1); merror (data, "sony_arw2_load_raw()"); for (row=0; row < height; row++) { fread (data, 1, raw_width, ifp); @@ -2465,6 +2461,9 @@ void CLASS samsung_load_raw() } } } + for (row=0; row < raw_height-1; row+=2) + for (col=0; col < raw_width-1; col+=2) + SWAP (RAW(row,col+1), RAW(row+1,col)); } #define HOLE(row) ((holes >> (((row) - raw_height) & 7)) & 1) @@ -3381,15 +3380,18 @@ void CLASS crop_masked_pixels() } } } else { - for (row=0; row < height; row++) - for (col=0; col < width; col++) + +#pragma omp parallel for + for (int row=0; row < height; row++) + for (int col=0; col < width; col++) BAYER2(row,col) = RAW(row+top_margin,col+left_margin); } - if (mask[0][3]) goto mask_set; + + if (mask[0][3] > 0) goto mask_set; if (load_raw == &CLASS canon_load_raw || load_raw == &CLASS lossless_jpeg_load_raw) { - mask[0][1] = mask[1][1] = 2; - mask[0][3] = -2; + mask[0][1] = mask[1][1] += 2; + mask[0][3] -= 2; goto sides; } if (load_raw == &CLASS canon_600_load_raw || @@ -3612,7 +3614,7 @@ void CLASS pseudoinverse (double (*in)[3], double (*out)[3], int size) out[i][j] += work[j][k+3] * in[i][k]; } -void CLASS cam_xyz_coeff (double cam_xyz[4][3]) +void CLASS cam_xyz_coeff (float rgb_cam[3][4], double cam_xyz[4][3]) { double cam_rgb[4][3], inverse[4][3], num; int i, j, k; @@ -3630,7 +3632,7 @@ void CLASS cam_xyz_coeff (double cam_xyz[4][3]) pre_mul[i] = 1 / num; } pseudoinverse (cam_rgb, inverse, colors); - for (raw_color = i=0; i < 3; i++) + for (i=0; i < 3; i++) for (j=0; j < colors; j++) rgb_cam[i][j] = inverse[j][i]; } @@ -3689,11 +3691,11 @@ void CLASS colorcheck() (1 - gmb_xyY[sq][0] - gmb_xyY[sq][1]) / gmb_xyY[sq][1]; } pseudoinverse (gmb_xyz, inverse, NSQ); - for (i=0; i < colors; i++) + for (raw_color = i=0; i < colors; i++) for (j=0; j < 3; j++) for (cam_xyz[i][j] = k=0; k < NSQ; k++) cam_xyz[i][j] += gmb_cam[k][i] * inverse[k][j]; - cam_xyz_coeff (cam_xyz); + cam_xyz_coeff (rgb_cam, cam_xyz); if (verbose) { printf (" { \"%s %s\", %d,\n\t{", make, model, black); num = 10000 / (cam_xyz[1][0] + cam_xyz[1][1] + cam_xyz[1][2]); @@ -3866,10 +3868,17 @@ skip_block: ; FORC4 fprintf (stderr, " %f", pre_mul[c]); fputc ('\n', stderr); } + if (filters > 1000 && (cblack[4]+1)/2 == 1 && (cblack[5]+1)/2 == 1) { + FORC4 cblack[FC(c/2,c%2)] += + cblack[6 + c/2 % cblack[4] * cblack[5] + c%2 % cblack[5]]; + cblack[4] = cblack[5] = 0; + } size = iheight*iwidth; for (i=0; i < size*4; i++) { - val = image[0][i]; - if (!val) continue; + if (!(val = image[0][i])) continue; + if (cblack[4] && cblack[5]) + val -= cblack[6 + i/4 / iwidth % cblack[4] * cblack[5] + + i/4 % iwidth % cblack[5]]; val -= cblack[i & 3]; val *= scale_mul[i & 3]; image[0][i] = CLIP(val); @@ -4473,10 +4482,12 @@ void CLASS parse_makernote (int base, int uptag) if (get2() != 42) goto quit; offset = get4(); fseek (ifp, offset-8, SEEK_CUR); - } else if (!strcmp (buf,"OLYMPUS")) { + } else if (!strcmp (buf,"OLYMPUS") || + !strcmp (buf,"PENTAX ")) { base = ftell(ifp)-10; fseek (ifp, -2, SEEK_CUR); - order = get2(); get2(); + order = get2(); + if (buf[0] == 'O') get2(); } else if (!strncmp (buf,"SONY",4) || !strcmp (buf,"Panasonic")) { goto nf; @@ -4809,7 +4820,8 @@ void CLASS parse_mos (int offset) { "","DCB2","Volare","Cantare","CMost","Valeo 6","Valeo 11","Valeo 22", "Valeo 11p","Valeo 17","","Aptus 17","Aptus 22","Aptus 75","Aptus 65", "Aptus 54S","Aptus 65S","Aptus 75S","AFi 5","AFi 6","AFi 7", - "AFi-II 7","","","Aptus-II 6","","","Aptus-II 10","Aptus-II 5","","","","","Aptus-II 10R","Aptus-II 8","","Aptus-II 12","","AFi-II 12" }; // RT: added missing model names + "AFi-II 7","","","Aptus-II 6","","","Aptus-II 10","Aptus-II 5", + "","","","","Aptus-II 10R","Aptus-II 8","","Aptus-II 12","","AFi-II 12" }; float romm_cam[3][3]; fseek (ifp, offset, SEEK_SET); @@ -4925,7 +4937,6 @@ 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 cc[4][4], cm[4][3], cam_xyz[4][3], num; @@ -5276,25 +5287,29 @@ guess_cfa_pc: linear_table (len); break; case 50713: /* BlackLevelRepeatDim */ - blrr = get2(); - blrc = get2(); + cblack[4] = get2(); + cblack[5] = get2(); + if (cblack[4] * cblack[5] > sizeof cblack / sizeof *cblack - 6) + cblack[4] = cblack[5] = 1; break; case 61450: - blrr = blrc = 2; - if (filters == UINT_MAX) filters = 0x94949494; /* RT: Fuji X100 fix for dcraw 9.19 to get proper black level parsing, hopefully works for other Fuji cameras too! */ + cblack[4] = cblack[5] = MIN(sqrt(len),64); case 50714: /* BlackLevel */ - black = getreal(type); - if ((unsigned)(filters+1) < 1000) 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; + if(cblack[4] * cblack[5] == 0) { + int dblack[] = { 0,0,0,0 }; + black = getreal(type); + if ((unsigned)(filters+1) < 1000) break; + dblack[0] = dblack[1] = dblack[2] = dblack[3] = black; + if (colors == 3) + filters |= ((filters >> 2 & 0x22222222) | + (filters << 2 & 0x88888888)) & filters << 1; + FORC4 cblack[filters >> (c << 1) & 3] = dblack[c]; + } else { + FORC (cblack[4] * cblack[5]) + cblack[6+c] = getreal(type); + } + black = 0; + break; case 50715: /* BlackLevelDeltaH */ case 50716: /* BlackLevelDeltaV */ for (num=i=0; i < len; i++) @@ -5379,6 +5394,8 @@ guess_cfa_pc: parse_tiff_ifd (-sony_offset); // fclose (ifp); // } + if(ifp) + fclose(ifp); ifp = sfp; free (buf); } @@ -5388,7 +5405,7 @@ guess_cfa_pc: FORCC for (i=0; i < 3; i++) for (cam_xyz[c][i]=j=0; j < colors; j++) cam_xyz[c][i] += cc[c][j] * cm[j][i] * xyz[i]; - cam_xyz_coeff (cam_xyz); + cam_xyz_coeff (cmatrix, cam_xyz); } if (asn[0]) { cam_mul[3] = 0; @@ -6263,6 +6280,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 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 70D", 0, 0x3bc7, + { 7034,-804,-1014,-4420,12564,2058,-851,1994,5758 } }, { "Canon EOS 100D", 0, 0x350f, { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } }, { "Canon EOS 300D", 0, 0xfa0, @@ -6309,6 +6328,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 6847,-614,-1014,-4669,12737,2139,-1197,2488,6846 } }, { "Canon EOS-1D", 0, 0xe20, { 6806,-179,-1020,-8097,16415,1687,-3267,4236,7690 } }, + { "Canon EOS C500", 853, 0, /* DJC */ + { 17851,-10604,922,-7425,16662,763,-3660,3636,22278 } }, { "Canon PowerShot A530", 0, 0, { 0 } }, /* don't want the A5 matrix */ { "Canon PowerShot A50", 0, 0, @@ -6323,6 +6344,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 13244,-5501,-1248,-1508,9858,1935,-270,1083,4366 } }, { "Canon PowerShot G15", 0, 0, { 7474,-2301,-567,-4056,11456,2975,-222,716,4181 } }, + { "Canon PowerShot G16", 0, 0, + { 8020,-2687,-682,-3704,11879,2052,-965,1921,5556 } }, { "Canon PowerShot G1 X", 0, 0, { 7378,-1255,-1043,-4088,12251,2048,-876,1946,5805 } }, { "Canon PowerShot G1", 0, 0, @@ -6363,6 +6386,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 7968,-2565,-636,-2873,10697,2513,180,667,4211 } }, { "Canon PowerShot S110", 0, 0, { 8039,-2643,-654,-3783,11230,2930,-206,690,4194 } }, + { "Canon PowerShot S120", 0, 0, + { 6961,-1685,-695,-4625,12945,1836,-1114,2152,5518 } }, { "Canon PowerShot SX1 IS", 0, 0, { 6578,-259,-502,-5974,13030,3309,-308,1058,4970 } }, { "Canon PowerShot SX50 HS", 0, 0, @@ -6421,10 +6446,10 @@ void CLASS adobe_coeff (const char *make, const char *model) { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, { "Fujifilm S100FS", 514, 0, { 11521,-4355,-1065,-6524,13767,3058,-1466,1984,6045 } }, - { "Fujifilm S200EXR", 512, 0x3fff, - { 11401,-4498,-1312,-5088,12751,2613,-838,1568,5941 } }, { "Fujifilm S20Pro", 0, 0, { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } }, + { "Fujifilm S20", 512, 0x3fff, + { 11401,-4498,-1312,-5088,12751,2613,-838,1568,5941 } }, { "Fujifilm S2Pro", 128, 0, { 12492,-4690,-1402,-7033,15423,1647,-1507,2111,7697 } }, { "Fujifilm S3Pro", 0, 0, @@ -6461,12 +6486,14 @@ void CLASS adobe_coeff (const char *make, const char *model) { 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } }, { "Fujifilm HS10 HS11", 0, 0xf68, { 12440,-3954,-1183,-1123,9674,1708,-83,1614,4086 } }, - { "Fujifilm HS20EXR", 0, 0, + { "Fujifilm HS2", 0, 0, { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, { "Fujifilm HS3", 0, 0, { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, { "Fujifilm HS50EXR", 0, 0, { 12085,-4727,-953,-3257,11489,2002,-511,2046,4592 } }, + { "Fujifilm F900EXR", 0, 0, + { 12085,-4727,-953,-3257,11489,2002,-511,2046,4592 } }, { "Fujifilm X100S", 0, 0, { 10592,-4262,-1008,-3514,11355,2465,-870,2025,6386 } }, { "Fujifilm X100", 0, 0, @@ -6477,12 +6504,20 @@ void CLASS adobe_coeff (const char *make, const char *model) { 11768,-4971,-1133,-4904,12927,2183,-480,1723,4605 } }, { "Fujifilm X-Pro1", 0, 0, { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, + { "Fujifilm X-A1", 0, 0, + { 11086,-4555,-839,-3512,11310,2517,-815,1341,5940 } }, { "Fujifilm X-E1", 0, 0, { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, - { "Fujifilm XF1", 0, 0, - { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } }, + { "Fujifilm X-E2", 0, 0, + { 8458,-2451,-855,-4597,12447,2407,-1475,2482,6526 } }, + { "Fujifilm X-M1", 0, 0, + { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, { "Fujifilm X-S1", 0, 0, { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } }, + { "Fujifilm XF1", 0, 0, + { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } }, + { "Fujifilm XQ1", 0, 0, + { 9252,-2704,-1064,-5893,14265,1717,-1101,2341,4349 } }, { "Imacon Ixpress", 0, 0, /* DJC */ { 7025,-1415,-704,-5188,13765,1424,-1248,2742,6038 } }, { "Kodak NC2000", 0, 0, @@ -6593,6 +6628,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 7911,-2167,-813,-5327,13150,2408,-1288,2483,7968 } }, { "Nikon D3200", 0, 0xfb9, { 7013,-1408,-635,-5268,12902,2640,-1470,2801,7379 } }, + { "Nikon D3300", 147, 0, /* DJC */ + { 6108,-2161,-13,-4091,9871,4220,-1222,2469,7907 } }, { "Nikon D300", 0, 0, { 9030,-1992,-715,-8465,16302,2255,-2689,3217,8069 } }, { "Nikon D3X", 0, 0, @@ -6607,16 +6644,22 @@ void CLASS adobe_coeff (const char *make, const char *model) { 6992,-1668,-806,-8138,15748,2543,-874,850,7897 } }, { "Nikon D4", 0, 0, { 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } }, + { "Nikon Df", 0, 0, + { 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } }, { "Nikon D5000", 0, 0xf00, { 7309,-1403,-519,-8474,16008,2622,-2433,2826,8064 } }, { "Nikon D5100", 0, 0x3de6, { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } }, { "Nikon D5200", 0, 0, { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } }, + { "Nikon D5300", 600, 0, + { 6988,-1384,-714,-5631,13410,2447,-1485,2204,7318 } }, { "Nikon D50", 0, 0, { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } }, { "Nikon D600", 0, 0x3e07, { 8178,-2245,-609,-4857,12394,2776,-1207,2086,7298 } }, + { "Nikon D610", 0, 0, + { 8178,-2245,-609,-4857,12394,2776,-1207,2086,7298 } }, { "Nikon D60", 0, 0, { 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } }, { "Nikon D7000", 0, 0, @@ -6675,10 +6718,14 @@ void CLASS adobe_coeff (const char *make, const char *model) { 11053,-4269,-1024,-1976,10182,2088,-526,1263,4469 } }, { "Nikon COOLPIX P7700", 200, 0, { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } }, + { "Nikon COOLPIX P7800", 200, 0, + { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } }, { "Nikon 1 V2", 0, 0, { 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } }, { "Nikon 1 J3", 0, 0, { 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } }, + { "Nikon 1 AW1", 0, 0, + { 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } }, { "Nikon 1 ", 0, 0, { 8994,-2667,-865,-4594,12324,2552,-699,1786,6260 } }, { "Olympus C5050", 0, 0, @@ -6731,6 +6778,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8343,-2050,-1021,-7715,15705,2103,-1831,2380,8235 } }, { "Olympus E-P3", 0, 0, { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } }, + { "Olympus E-P5", 0, 0, + { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, { "Olympus E-PL1s", 0, 0, { 11409,-3872,-1393,-4572,12757,2003,-709,1810,7415 } }, { "Olympus E-PL1", 0, 0, @@ -6741,10 +6790,14 @@ void CLASS adobe_coeff (const char *make, const char *model) { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } }, { "Olympus E-PL5", 0, 0xfcb, { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, + { "Olympus E-PL6", 0, 0, + { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, { "Olympus E-PM1", 0, 0, { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } }, { "Olympus E-PM2", 0, 0, { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, + { "Olympus E-M1", 0, 0, + { 7687,-1984,-606,-4327,11928,2721,-1381,2339,6452 } }, { "Olympus E-M5", 0, 0xfe1, { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, { "Olympus SP350", 0, 0, @@ -6761,6 +6814,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 10915,-3677,-982,-5587,12986,2911,-1168,1968,6223 } }, { "Olympus SP570UZ", 0, 0, { 11522,-4044,-1146,-4736,12172,2904,-988,1829,6039 } }, + { "Olympus STYLUS1", 0, 0, + { 8360,-2420,-880,-3928,12353,1739,-1381,2416,5173 } }, { "Olympus XZ-10", 0, 0, { 9777,-3483,-925,-2886,11297,1800,-602,1663,5134 } }, { "Olympus XZ-1", 0, 0, @@ -6795,6 +6850,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 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-3", 0, 0, + { 7415,-2052,-721,-5186,12788,2682,-1446,2157,6773 } }, { "Pentax K-5 II", 0, 0, { 8170,-2725,-639,-4440,12017,2744,-771,1465,6599 } }, { "Pentax K-5", 0, 0, @@ -6817,6 +6874,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 13639,-5535,-1371,-1698,9633,2430,316,1152,4108 } }, { "Panasonic DMC-FZ50", 0, 0, { 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } }, + { "Panasonic DMC-FZ7", 144, 0, + { 11532,-4324,-1066,-2375,10847,1749,-564,1699,4351 } }, { "Leica V-LUX1", 0, 0, { 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } }, { "Panasonic DMC-L10", 15, 0xf96, @@ -6829,6 +6888,10 @@ void CLASS adobe_coeff (const char *make, const char *model) { 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } }, { "Leica DIGILUX 2", 0, 0, { 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } }, + { "Panasonic DMC-LF1", 143, 0, + { 9379,-3267,-816,-3227,11560,1881,-926,1928,5340 } }, + { "Leica C (Typ 112)", 143, 0, + { 9379,-3267,-816,-3227,11560,1881,-926,1928,5340 } }, { "Panasonic DMC-LX1", 0, 0xf7f, { 10704,-4187,-1230,-8314,15952,2501,-920,945,8927 } }, { "Leica D-LUX2", 0, 0xf7f, @@ -6873,8 +6936,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } }, { "Panasonic DMC-G5", 143, 0xfff, { 7798,-2562,-740,-3879,11584,2613,-1055,2248,5434 } }, - { "Panasonic DMC-G6", 143, 0xfff, /* DJC */ - { 6395,-2583,-40,-3677,9109,4569,-1502,2806,6431 } }, + { "Panasonic DMC-G6", 142, 0xfff, + { 8294,-2891,-651,-3869,11590,2595,-1183,2267,5352 } }, { "Panasonic DMC-GF1", 15, 0xf92, { 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } }, { "Panasonic DMC-GF2", 143, 0xfff, @@ -6891,8 +6954,14 @@ void CLASS adobe_coeff (const char *make, const char *model) { 7780,-2410,-806,-3913,11724,2484,-1018,2390,5298 } }, { "Panasonic DMC-GH3", 144, 0, { 6559,-1752,-491,-3672,11407,2586,-962,1875,5130 } }, + { "Panasonic DMC-GM1", 143, 0, + { 6770,-1895,-744,-5232,13145,2303,-1664,2691,5703 } }, { "Panasonic DMC-GX1", 143, 0, { 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } }, + { "Panasonic DMC-GX7", 143, 0, + { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } }, + { "Panasonic DMC-TZ61", 143, 0, /* DJC */ + { 6211,-2325,27,-3800,9449,4352,-943,2166,6293 } }, { "Phase One H 20", 0, 0, /* DJC */ { 1313,1855,-109,-6715,15908,808,-327,1840,6020 } }, { "Phase One H 25", 0, 0, @@ -6913,6 +6982,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8898,-2498,-994,-3144,11328,2066,-760,1381,4576 } }, { "Samsung EX2F", 0, 0x7ff, { 10648,-3897,-1055,-2022,10573,1668,-492,1611,4742 } }, + { "Samsung EK-GN120", 0, 0, + { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } }, { "Samsung NX300", 0, 0, { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } }, { "Samsung NX2000", 0, 0, @@ -6929,6 +7000,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 12093,-3557,-1155,-1000,9534,1733,-22,1787,4576 } }, { "Samsung GX-1", 0, 0, { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } }, + { "Samsung GX20", 0, 0, /* copied from Pentax K20D */ + { 9427,-2714,-868,-7493,16092,1373,-2199,3264,7180 } }, { "Samsung S85", 0, 0, /* DJC */ { 11885,-3968,-1473,-4214,12299,1916,-835,1655,5549 } }, { "Sinar", 0, 0, /* DJC */ @@ -6939,8 +7012,12 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8512,-2641,-694,-8042,15670,2526,-1821,2117,7414 } }, { "Sony DSC-V3", 0, 0, { 7511,-2571,-692,-7894,15088,3060,-948,1111,8128 } }, + { "Sony DSC-RX100M2", 200, 0, + { 6596,-2079,-562,-4782,13016,1933,-970,1581,5181 } }, { "Sony DSC-RX100", 200, 0, { 8651,-2754,-1057,-3464,12207,1373,-568,1398,4434 } }, + { "Sony DSC-RX10", 200, 0, + { 6679,-1825,-745,-5047,13256,1953,-1580,2422,5183 } }, { "Sony DSC-RX1", 128, 0, { 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } }, { "Sony DSLR-A100", 0, 0xfeb, @@ -6965,16 +7042,26 @@ void CLASS adobe_coeff (const char *make, const char *model) { 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, + { "Sony DSLR-A700", 128, 0, { 5775,-805,-359,-8574,16295,2391,-1943,2341,7249 } }, { "Sony DSLR-A850", 128, 0, { 5413,-1162,-365,-5665,13098,2866,-608,1179,8440 } }, { "Sony DSLR-A900", 128, 0, { 5209,-1072,-397,-8845,16120,2919,-1618,1803,8654 } }, + { "Sony ILCE-7R", 128, 0, + { 4913,-541,-202,-6130,13513,2906,-1564,2151,7183 } }, + { "Sony ILCE-7", 128, 0, + { 5271,-712,-347,-6153,13653,2763,-1601,2366,7242 } }, + { "Sony ILCE-3000", 128, 0, + { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, + { "Sony ILCE-5000", 128, 0, /* DJC */ + { 4130,-1407,93,-4151,9566,4586,-1035,1976,7000 } }, { "Sony NEX-5N", 128, 0, { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, { "Sony NEX-5R", 128, 0, { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } }, + { "Sony NEX-5T", 128, 0, + { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } }, { "Sony NEX-3N", 128, 0, { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } }, { "Sony NEX-3", 138, 0, /* DJC */ @@ -7020,9 +7107,9 @@ void CLASS adobe_coeff (const char *make, const char *model) if (table[i].black) black = (ushort) table[i].black; if (table[i].maximum) maximum = (ushort) table[i].maximum; if (table[i].trans[0]) { - for (j=0; j < 12; j++) + for (raw_color = j=0; j < 12; j++) cam_xyz[0][j] = table[i].trans[j] / 10000.0; - cam_xyz_coeff (cam_xyz); + cam_xyz_coeff (rgb_cam, cam_xyz); } break; } @@ -7043,7 +7130,7 @@ void CLASS adobe_coeff (const char *make, const char *model) for (j=0; j < 12; j++) { cam_xyz[0][j] = trans[j] / 10000.0; } - cam_xyz_coeff (cam_xyz); + cam_xyz_coeff (rgb_cam,cam_xyz); } } } @@ -7144,13 +7231,13 @@ void CLASS identify() { 4508, 2962, 0, 0, -3, -4 }, { 4508, 3330, 0, 0, -3, -6 }, }; - static const ushort canon[][6] = { + static const ushort canon[][11] = { { 1944, 1416, 0, 0, 48, 0 }, - { 2144, 1560, 4, 8, 52, 2 }, + { 2144, 1560, 4, 8, 52, 2, 0, 0, 0, 25 }, { 2224, 1456, 48, 6, 0, 2 }, { 2376, 1728, 12, 6, 52, 2 }, { 2672, 1968, 12, 6, 44, 2 }, - { 3152, 2068, 64, 12, 0, 0 }, + { 3152, 2068, 64, 12, 0, 0, 16 }, { 3160, 2344, 44, 12, 4, 4 }, { 3344, 2484, 4, 6, 52, 6 }, { 3516, 2328, 42, 14, 0, 0 }, @@ -7158,16 +7245,17 @@ void CLASS identify() { 3744, 2784, 52, 12, 8, 12 }, { 3944, 2622, 30, 18, 6, 2 }, { 3948, 2622, 42, 18, 0, 2 }, - { 3984, 2622, 76, 20, 0, 2 }, + { 3984, 2622, 76, 20, 0, 2, 14 }, { 4104, 3048, 48, 12, 24, 12 }, { 4116, 2178, 4, 2, 0, 0 }, { 4152, 2772, 192, 12, 0, 0 }, { 4160, 3124, 104, 11, 8, 65 }, - { 4176, 3062, 96, 17, 8, 0 }, + { 4176, 3062, 96, 17, 8, 0, 0, 16, 0, 7, 0x49 }, + { 4192, 3062, 96, 17, 24, 0, 0, 16, 0, 0, 0x49 }, { 4312, 2876, 22, 18, 0, 2 }, { 4352, 2874, 62, 18, 0, 0 }, { 4476, 2954, 90, 34, 0, 0 }, - { 4480, 3348, 12, 10, 36, 12 }, + { 4480, 3348, 12, 10, 36, 12, 0, 0, 0, 18, 0x49 }, { 4496, 3366, 80, 50, 12, 0 }, { 4832, 3204, 62, 26, 0, 0 }, { 4832, 3228, 62, 51, 0, 0 }, @@ -7192,6 +7280,7 @@ void CLASS identify() { 0x190, "EOS 40D" }, { 0x169, "EOS-1D Mark III" }, { 0x261, "EOS 50D" }, { 0x281, "EOS-1D Mark IV" }, { 0x287, "EOS 60D" }, { 0x167, "EOS-1DS" }, + { 0x325, "EOS 70D" }, { 0x170, "EOS 300D" }, { 0x188, "EOS-1Ds Mark II" }, { 0x176, "EOS 450D" }, { 0x215, "EOS-1Ds Mark III" }, { 0x189, "EOS 350D" }, { 0x324, "EOS-1D C" }, @@ -7221,6 +7310,7 @@ void CLASS identify() { 10134620,2588,1958, 0, 0, 0, 0, 9,0x94,0,0,"AVT","F-510C",12 }, { 16157136,3272,2469, 0, 0, 0, 0, 9,0x94,0,0,"AVT","F-810C" }, { 15980544,3264,2448, 0, 0, 0, 0, 8,0x61,0,1,"AgfaPhoto","DC-833m" }, + { 9631728,2532,1902, 0, 0, 0, 0,96,0x61,0,0,"Alcatel","5035D" }, { 2868726,1384,1036, 0, 0, 0, 0,64,0x49,0,8,"Baumer","TXG14",1078 }, { 5298000,2400,1766,12,12,44, 2,40,0x94,0,2,"Canon","PowerShot SD300" }, { 6553440,2664,1968, 4, 4,44, 4,40,0x94,0,2,"Canon","PowerShot A460" }, @@ -7236,7 +7326,7 @@ void CLASS identify() { 15467760,3720,2772, 6,12,30, 0,40,0x94,0,2,"Canon","PowerShot SX110 IS" }, { 15534576,3728,2778,12, 9,44, 9,40,0x94,0,2,"Canon","PowerShot SX120 IS" }, { 18653760,4080,3048,24,12,24,12,40,0x94,0,2,"Canon","PowerShot SX20 IS" }, - { 19131120,4168,3060,92,16, 4, 1, 8,0x94,0,2,"Canon","PowerShot SX220 HS" }, + { 19131120,4168,3060,92,16, 4, 1,40,0x94,0,2,"Canon","PowerShot SX220 HS" }, { 21936096,4464,3276,25,10,73,12,40,0x16,0,2,"Canon","PowerShot SX30 IS" }, { 24724224,4704,3504, 8,16,56, 8,40,0x94,0,2,"Canon","PowerShot A3300 IS" }, { 1976352,1632,1211, 0, 2, 0, 1, 0,0x94,0,1,"Casio","QV-2000UX" }, @@ -7261,6 +7351,8 @@ void CLASS identify() { 18702336,4096,3044, 0, 0,24, 0,80,0x94,7,1,"Casio","EX-ZR100" }, { 7684000,2260,1700, 0, 0, 0, 0,13,0x94,0,1,"Casio","QV-4000" }, { 787456,1024, 769, 0, 1, 0, 0, 0,0x49,0,0,"Creative","PC-CAM 600" }, + { 28829184,4384,3288, 0, 0, 0, 0,36,0x61,0,0,"DJI" }, + { 15151104,4608,3288, 0, 0, 0, 0, 0,0x94,0,0,"Matrix" }, { 3840000,1600,1200, 0, 0, 0, 0,65,0x49,0,0,"Foculus","531C" }, { 307200, 640, 480, 0, 0, 0, 0, 0,0x94,0,0,"Generic","640x480" }, { 62464, 256, 244, 1, 1, 6, 1, 0,0x8d,0,0,"Kodak","DC20" }, @@ -7272,6 +7364,9 @@ void CLASS identify() { 6166488,2864,2152, 0, 0, 0, 0, 0,0x94,0,0,"Kodak","C603",3160 }, { 460800, 640, 480, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","C603" }, { 9116448,2848,2134, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","C603" }, + { 12241200,4040,3030, 2, 0, 0,13, 0,0x49,0,0,"Kodak","12MP" }, + { 12272756,4040,3030, 2, 0, 0,13, 0,0x49,0,0,"Kodak","12MP",31556 }, + { 18000000,4000,3000, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","12MP" }, { 614400, 640, 480, 0, 3, 0, 0,64,0x94,0,0,"Kodak","KAI-0340" }, { 3884928,1608,1207, 0, 0, 0, 0,96,0x16,0,0,"Micron","2010",3212 }, { 1138688,1534, 986, 0, 0, 0, 0, 0,0x61,0,0,"Minolta","RD175",513 }, @@ -7423,15 +7518,18 @@ void CLASS identify() 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; + switch (tiff_bps = i*8 / (width * height)) { + case 8: load_raw = &CLASS eight_bit_load_raw; break; + case 10: load_raw = &CLASS nokia_load_raw; + } + raw_height = height + (top_margin = i / (width * tiff_bps/8) - height); + mask[0][3] = 1; filters = 0x61616161; } else if (!memcmp (head,"ARRI",4)) { order = 0x4949; @@ -7455,6 +7553,7 @@ void CLASS identify() fread (model, 1, 30, ifp); data_offset = 0x10000; load_raw = &CLASS canon_rmf_load_raw; + gamma_curve (0, 12.25, 1, 1023); } else if (!memcmp (head+4,"RED1",4)) { strcpy (make, "Red"); strcpy (model,"One"); @@ -7494,7 +7593,7 @@ void CLASS identify() switch (tiff_bps = (fsize-data_offset)*8 / (raw_width*raw_height)) { case 6: load_raw = &CLASS minolta_rd175_load_raw; break; - case 8: + case 8: load_raw = &CLASS eight_bit_load_raw; break; case 10: case 12: load_flags |= 128; @@ -7532,6 +7631,8 @@ void CLASS identify() ((cp = strcasestr(model," DIGITAL CAMERA")) || (cp = strstr(model,"FILE VERSION")))) *cp = 0; + if (!strncasecmp(model,"PENTAX",6)) + strcpy (make, "Pentax"); cp = make + strlen(make); /* Remove trailing spaces */ while (*--cp == ' ') *cp = 0; cp = model + strlen(model); @@ -7558,6 +7659,8 @@ void CLASS identify() { left_margin = 10; width = 4950; filters = 0x16161616; } if (width == 4736 && !strcmp(model,"K-7")) { height = 3122; width = 4684; filters = 0x16161616; top_margin = 2; } + if (width == 6080 && !strcmp(model,"K-3")) + { left_margin = 4; width = 6040; } if (width == 7424 && !strcmp(model,"645D")) { height = 5502; width = 7328; filters = 0x61616161; top_margin = 29; left_margin = 48; } @@ -7584,6 +7687,11 @@ void CLASS identify() height = raw_height - (top_margin = canon[i][3]); width -= canon[i][4]; height -= canon[i][5]; + mask[0][1] = canon[i][6]; + mask[0][3] = -canon[i][7]; + mask[1][1] = canon[i][8]; + mask[1][3] = -canon[i][9]; + if (canon[i][10]) filters = canon[i][10] * 0x01010101; } if ((unique_id | 0x20000) == 0x2720000) { left_margin = 8; @@ -7659,16 +7767,7 @@ canon_a5: } else if (!strcmp(model,"PowerShot A610")) { if (canon_s2is()) strcpy (model+10, "S2 IS"); } else if (!strcmp(model,"PowerShot SX220 HS")) { - mask[0][0] = top_margin = 16; - mask[0][2] = top_margin + height; - mask[0][3] = left_margin = 92; - } else if (!strcmp(model,"PowerShot SX50 HS")) { - mask[0][0] = top_margin = 17; - mask[0][2] = raw_height; - mask[0][3] = 80; - filters = 0x49494949; - } else if (!strcmp(model,"PowerShot G10")) { - filters = 0x49494949; + mask[1][3] = -4; } else if (!strcmp(model,"EOS D2000C")) { filters = 0x61616161; black = curve[200]; @@ -7703,7 +7802,8 @@ canon_a5: !strcmp(model,"D600") || !strcmp(model,"D800") || !strcmp(model,"D800E") ) { width -= 46; - } else if (!strcmp(model,"D4")) { + } else if (!strcmp(model,"D4") || + !strcmp(model,"Df")) { width -= 52; left_margin = 2; } else if (!strncmp(model,"D40",3) || @@ -7807,7 +7907,8 @@ canon_a5: if (width == 4032 || width == 4952) left_margin = 0; if (width == 3328 && (width -= 66)) left_margin = 34; if (width == 4936) left_margin = 4; - if (!strcmp(model,"HS50EXR")) { + if (!strcmp(model,"HS50EXR") || + !strcmp(model,"F900EXR")) { width += 2; left_margin = 0; filters = 0x16161616; @@ -7866,7 +7967,8 @@ konica_400z: } else if (!strcmp(make,"Samsung") && raw_height == 3714) { height -= 18; width = 5536; - filters = 0x49494949; + filters = 0x61616161; + colors = 3; } else if (!strcmp(make,"Samsung") && raw_width == 5632) { order = 0x4949; height = 3694; @@ -8071,10 +8173,11 @@ konica_400z: height -= top_margin = 4; width -= left_margin = 32; gamma_curve (0, 7, 1, 255); - } else if (!strcmp(model,"C603") || !strcmp(model,"C330")) { + } else if (!strcmp(model,"C603") || !strcmp(model,"C330") + || !strcmp(model,"12MP")) { order = 0x4949; if (filters && data_offset) { - fseek (ifp, 168, SEEK_SET); + fseek (ifp, data_offset < 4096 ? 168 : 5252, SEEK_SET); read_shorts (curve, 256); } else gamma_curve (0, 3.875, 1, 255); load_raw = filters ? &CLASS eight_bit_load_raw @@ -8202,9 +8305,6 @@ konica_400z: if (!model[0]) sprintf (model, "%dx%d", width, height); if (filters == UINT_MAX) filters = 0x94949494; - if (raw_color) adobe_coeff (make, model); - if (load_raw == &CLASS kodak_radc_load_raw) - if (raw_color) adobe_coeff ("Apple","Quicktake"); if (thumb_offset && !thumb_height) { fseek (ifp, thumb_offset, SEEK_SET); if (ljpeg_start (&jh, 1)) { @@ -8213,6 +8313,16 @@ konica_400z: } } dng_skip: + if ((use_camera_matrix & (use_camera_wb || dng_version)) + && cmatrix[0][0] > 0.125) { + memcpy (rgb_cam, cmatrix, sizeof cmatrix); + raw_color = 0; + } + if(!strncmp(make, "Samsung", 7) && !strncmp(model, "GX20",4)) + adobe_coeff (make, model); + if (raw_color) adobe_coeff (make, model); + if (load_raw == &CLASS kodak_radc_load_raw) + if (raw_color) adobe_coeff ("Apple","Quicktake"); if (fuji_width) { fuji_width = width >> !fuji_layout; if (~fuji_width & 1) filters = 0x49494949; @@ -8264,7 +8374,6 @@ void CLASS apply_profile (const char *input, const char *output) FILE *fp; unsigned size; - cmsErrorAction (LCMS_ERROR_SHOW); if (strcmp (input, "embed")) hInProfile = cmsOpenProfileFromFile (input, "r"); else if (profile_length) { diff --git a/rtengine/dcraw.h b/rtengine/dcraw.h index 9f6f17086..bf0b46cb1 100644 --- a/rtengine/dcraw.h +++ b/rtengine/dcraw.h @@ -55,7 +55,7 @@ public: ,RT_whitelevel_from_constant(0) ,RT_blacklevel_from_constant(0) ,RT_matrix_from_constant(0) - ,use_auto_wb(0),use_camera_wb(0),use_camera_matrix(-1) + ,use_auto_wb(0),use_camera_wb(0),use_camera_matrix(1) ,output_color(1),output_bps(8),output_tiff(0),med_passes(0),no_auto_bright(0) ,getbithuff(this,ifp,zero_after_ff) ,ph1_bithuff(this,ifp,order) @@ -84,7 +84,7 @@ protected: unsigned thumb_length, meta_length, profile_length; unsigned thumb_misc, *oprof, fuji_layout, shot_select, multi_out; unsigned tiff_nifds, tiff_samples, tiff_bps, tiff_compress; - unsigned black, cblack[4], maximum, mix_green, raw_color, zero_is_bad; + unsigned black, cblack[4102], 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; @@ -333,7 +333,7 @@ void bad_pixels (const char *cfname); void subtract (const char *fname); void gamma_curve (double pwr, double ts, int mode, int imax); void pseudoinverse (double (*in)[3], double (*out)[3], int size); -void cam_xyz_coeff (double cam_xyz[4][3]); +void cam_xyz_coeff (float rgb_cam[3][4], double cam_xyz[4][3]); void hat_transform (float *temp, float *base, int st, int size, int sc); void wavelet_denoise(); void scale_colors(); diff --git a/rtengine/dcraw.patch b/rtengine/dcraw.patch index 46b4edb0e..f11c75ec6 100755 --- a/rtengine/dcraw.patch +++ b/rtengine/dcraw.patch @@ -1,5 +1,5 @@ ---- dcraw.c 2014-01-01 15:42:38 +0000 -+++ dcraw.cc 2014-01-01 18:32:58 +0000 +--- dcraw.c 2014-02-02 13:33:19 +0000 ++++ dcraw.cc 2014-02-02 12:53:32 +0000 @@ -1,3 +1,15 @@ +/*RT*/#include +/*RT*/#include @@ -15,7 +15,7 @@ + /* dcraw.c -- Dave Coffin's raw photo decoder - Copyright 1997-2013 by Dave Coffin, dcoffin a cybercom o net + Copyright 1997-2014 by Dave Coffin, dcoffin a cybercom o net @@ -29,17 +41,17 @@ #define _GNU_SOURCE #endif @@ -44,7 +44,7 @@ #include #if defined(DJGPP) || defined(__MINGW32__) -@@ -98,87 +110,37 @@ +@@ -98,87 +110,38 @@ #define LONG_BIT (8 * sizeof (long)) #endif @@ -54,17 +54,18 @@ -#if !defined(ushort) -#define ushort unsigned short -#endif +- +#define ushort UshORt +typedef unsigned char uchar; +typedef unsigned short ushort; - ++ +#include "dcraw.h" /* - All global variables are defined here, and all functions that + RT All global variables are defined here, and all functions that access them are prefixed with "CLASS". Note that a thread-safe C++ class cannot have non-const static local variables. -- */ + */ -FILE *ifp, *ofp; -short order; -const char *ifname; @@ -78,25 +79,25 @@ -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, cblack[4], maximum, mix_green, raw_color, zero_is_bad; +-unsigned black, 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; -unsigned flip, tiff_flip, filters, colors; -ushort raw_height, raw_width, height, width, top_margin, left_margin; -ushort shrink, iheight, iwidth, fuji_width, thumb_width, thumb_height; --ushort *raw_image, (*image)[4]; +-ushort *raw_image, (*image)[4], cblack[4102]; -ushort white[8][8], curve[0x10000], cr2_slice[3], sraw_mul[4]; -double pixel_aspect, aber[4]={1,1,1,1}, gamm[6]={ 0.45,4.5,0,0,0,0 }; -float bright=1, user_mul[4]={0,0,0,0}, threshold=0; -int mask[8][4]; -int half_size=0, four_color_rgb=0, document_mode=0, highlight=0; --int verbose=0, use_auto_wb=0, use_camera_wb=0, use_camera_matrix=-1; +-int verbose=0, use_auto_wb=0, use_camera_wb=0, use_camera_matrix=1; -int output_color=1, output_bps=8, output_tiff=0, med_passes=0; -int no_auto_bright=0; -unsigned greybox[4] = { 0, 0, UINT_MAX, UINT_MAX }; -float cam_mul[4], pre_mul[4], cmatrix[3][4], rgb_cam[3][4]; -const double xyz_rgb[3][3] = { /* XYZ from RGB */ -+*/ ++ +const double xyz_rgb[3][3] = { // XYZ from RGB { 0.412453, 0.357580, 0.180423 }, { 0.212671, 0.715160, 0.072169 }, @@ -147,7 +148,7 @@ #define SWAP(a,b) { a=a+b; b=a-b; a=a-b; } /* -@@ -254,6 +216,7 @@ +@@ -254,6 +217,7 @@ if (filters == 1) return filter[(row+top_margin)&15][(col+left_margin)&15]; if (filters == 9) return xtrans[(row+top_margin+6)%6][(col+left_margin+6)%6]; @@ -155,7 +156,7 @@ return FC(row,col); } -@@ -296,6 +259,7 @@ +@@ -296,6 +260,7 @@ fprintf (stderr,_("Corrupt data near 0x%llx\n"), (INT64) ftello(ifp)); } data_error++; @@ -163,7 +164,7 @@ } ushort CLASS sget2 (uchar *s) -@@ -369,7 +333,7 @@ +@@ -369,7 +334,7 @@ { if (fread (pixel, 2, count, ifp) < count) derror(); if ((order == 0x4949) == (ntohs(0x1234) == 0x1234)) @@ -172,7 +173,7 @@ } void CLASS canon_600_fixed_wb (int temp) -@@ -541,10 +505,10 @@ +@@ -541,10 +506,10 @@ return 0; } @@ -186,7 +187,7 @@ unsigned c; if (nbits > 25) return 0; -@@ -1209,14 +1173,14 @@ +@@ -1209,14 +1174,14 @@ int i, nz; char tail[424]; @@ -203,7 +204,7 @@ void CLASS ppm_thumb() { -@@ -1494,10 +1458,10 @@ +@@ -1494,10 +1459,10 @@ } } @@ -217,8 +218,8 @@ unsigned c; if (nbits == -1) -@@ -1757,10 +1721,10 @@ - maximum = 0x3ff; +@@ -1757,10 +1722,10 @@ + maximum = curve[0x3ff]; } -unsigned CLASS pana_bits (int nbits) @@ -231,7 +232,7 @@ int byte; if (!nbits) return vbits=0; -@@ -2049,11 +2013,11 @@ +@@ -2049,11 +2014,11 @@ METHODDEF(boolean) fill_input_buffer (j_decompress_ptr cinfo) { @@ -245,7 +246,7 @@ cinfo->src->next_input_byte = jpeg_buffer; cinfo->src->bytes_in_buffer = nbytes; return TRUE; -@@ -2373,10 +2337,9 @@ +@@ -2371,10 +2336,9 @@ maximum = (1 << (thumb_misc & 31)) - 1; } @@ -258,30 +259,7 @@ if (start) { for (p=0; p < 4; p++) pad[p] = key = key * 48828125 + 1; -@@ -2386,8 +2349,10 @@ - for (p=0; p < 127; p++) - pad[p] = htonl(pad[p]); - } -- while (len--) -- *data++ ^= pad[p++ & 127] = pad[(p+1) & 127] ^ pad[(p+65) & 127]; -+ while (len--){ -+ *data++ ^= pad[p & 127] = pad[(p+1) & 127] ^ pad[(p+65) & 127]; -+ p++; -+ } - } - - void CLASS sony_load_raw() -@@ -2445,7 +2410,8 @@ - ushort pix[16]; - int row, col, val, max, min, imax, imin, sh, bit, i; - -- data = (uchar *) malloc (raw_width); -+ //data = (uchar *) malloc (raw_width); -+ data = (uchar *) malloc (raw_width + 1); // RT: added +1 to avoid buffer overrun - merror (data, "sony_arw2_load_raw()"); - for (row=0; row < height; row++) { - fread (data, 1, raw_width, ifp); -@@ -2464,11 +2430,13 @@ +@@ -2462,11 +2426,13 @@ bit += 7; } for (i=0; i < 16; i++, col+=2) @@ -296,7 +274,7 @@ } void CLASS samsung_load_raw() -@@ -2690,7 +2658,7 @@ +@@ -2691,7 +2657,7 @@ void CLASS foveon_decoder (unsigned size, unsigned code) { @@ -305,7 +283,23 @@ struct decode *cur; int i, len; -@@ -4003,239 +3971,8 @@ +@@ -3414,10 +3380,13 @@ + } + } + } else { +- for (row=0; row < height; row++) +- for (col=0; col < width; col++) ++ ++#pragma omp parallel for ++ for (int row=0; row < height; row++) ++ for (int col=0; col < width; col++) + BAYER2(row,col) = RAW(row+top_margin,col+left_margin); + } ++ + if (mask[0][3] > 0) goto mask_set; + if (load_raw == &CLASS canon_load_raw || + load_raw == &CLASS lossless_jpeg_load_raw) { +@@ -4011,239 +3980,8 @@ } } @@ -356,7 +350,8 @@ - This algorithm is officially called: - - "Interpolation using a Threshold-based variable number of gradients" -- ++/* RT: delete interpolation functions */ + - 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. @@ -497,8 +492,7 @@ - int dir[5] = { 1, width, -1, -width, 1 }; - int row, col, diff[2], guess[2], c, d, i; - ushort (*pix)[4]; -+/* RT: delete interpolation functions */ - +- - border_interpolate(3); - if (verbose) fprintf (stderr,_("PPG interpolation...\n")); - @@ -546,7 +540,7 @@ void CLASS cielab (ushort rgb[3], short lab[3]) { -@@ -4496,112 +4233,7 @@ +@@ -4504,112 +4242,7 @@ } #undef fcol @@ -562,7 +556,7 @@ - ushort (*rgb)[TS][TS][3], (*rix)[3], (*pix)[4]; - short (*lab)[TS][TS][3], (*lix)[3]; - char (*homo)[TS][TS], *buffer; - +- - if (verbose) fprintf (stderr,_("AHD interpolation...\n")); - - cielab (0,0); @@ -575,7 +569,7 @@ - - for (top=2; top < height-5; top += TS-6) - for (left=2; left < width-5; left += TS-6) { -- + -/* Interpolate green horizontally and vertically: */ - for (row=top; row < top+TS && row < height-2; row++) { - col = left + (FC(row,left) & 1); @@ -659,7 +653,7 @@ #undef TS void CLASS median_filter() -@@ -4771,7 +4403,7 @@ +@@ -4779,7 +4412,7 @@ } } @@ -668,16 +662,16 @@ void CLASS parse_makernote (int base, int uptag) { -@@ -5177,7 +4809,7 @@ +@@ -5187,7 +4820,7 @@ { "","DCB2","Volare","Cantare","CMost","Valeo 6","Valeo 11","Valeo 22", "Valeo 11p","Valeo 17","","Aptus 17","Aptus 22","Aptus 75","Aptus 65", "Aptus 54S","Aptus 65S","Aptus 75S","AFi 5","AFi 6","AFi 7", -- "","","","","","","","","","","","","","","","","","AFi-II 12" }; -+ "AFi-II 7","","","Aptus-II 6","","","Aptus-II 10","Aptus-II 5","","","","","Aptus-II 10R","Aptus-II 8","","Aptus-II 12","","AFi-II 12" }; // RT: added missing model names +- "Aptus-II 7","","","Aptus-II 6","","","Aptus-II 10","Aptus-II 5", ++ "AFi-II 7","","","Aptus-II 6","","","Aptus-II 10","Aptus-II 5", + "","","","","Aptus-II 10R","Aptus-II 8","","Aptus-II 12","","AFi-II 12" }; float romm_cam[3][3]; - fseek (ifp, offset, SEEK_SET); -@@ -5265,6 +4897,8 @@ +@@ -5276,6 +4909,8 @@ wbi = -2; } if (tag == 2118) wbtemp = getint(type); @@ -686,7 +680,7 @@ if (tag == 2130 + wbi) FORC3 mul[c] = getreal(type); if (tag == 2140 + wbi && wbi >= 0) -@@ -5284,8 +4918,8 @@ +@@ -5295,8 +4930,8 @@ } } @@ -697,7 +691,7 @@ int CLASS parse_tiff_ifd (int base) { -@@ -5299,7 +4933,7 @@ +@@ -5309,7 +4944,7 @@ unsigned sony_curve[] = { 0,0,0,0,0,4095 }; unsigned *buf, sony_offset=0, sony_length=0, sony_key=0; struct jhead jh; @@ -706,15 +700,33 @@ if (tiff_nifds >= sizeof tiff_ifd / sizeof tiff_ifd[0]) return 1; -@@ -5647,6 +5281,7 @@ - break; +@@ -5660,10 +5295,21 @@ case 61450: - blrr = blrc = 2; -+ if (filters == UINT_MAX) filters = 0x94949494; /* RT: Fuji X100 fix for dcraw 9.19 to get proper black level parsing, hopefully works for other Fuji cameras too! */ + cblack[4] = cblack[5] = MIN(sqrt(len),64); case 50714: /* BlackLevel */ - black = getreal(type); - if ((unsigned)(filters+1) < 1000) break; -@@ -5737,12 +5372,13 @@ +- FORC (cblack[4] * cblack[5]) +- cblack[6+c] = getreal(type); +- black = 0; +- break; ++ if(cblack[4] * cblack[5] == 0) { ++ int dblack[] = { 0,0,0,0 }; ++ black = getreal(type); ++ if ((unsigned)(filters+1) < 1000) break; ++ dblack[0] = dblack[1] = dblack[2] = dblack[3] = black; ++ if (colors == 3) ++ filters |= ((filters >> 2 & 0x22222222) | ++ (filters << 2 & 0x88888888)) & filters << 1; ++ FORC4 cblack[filters >> (c << 1) & 3] = dblack[c]; ++ } else { ++ FORC (cblack[4] * cblack[5]) ++ cblack[6+c] = getreal(type); ++ } ++ black = 0; ++ break; + case 50715: /* BlackLevelDeltaH */ + case 50716: /* BlackLevelDeltaV */ + for (num=i=0; i < len; i++) +@@ -5741,12 +5387,15 @@ fread (buf, sony_length, 1, ifp); sony_decrypt (buf, sony_length/4, 1, sony_key); sfp = ifp; @@ -731,10 +743,12 @@ + parse_tiff_ifd (-sony_offset); +// fclose (ifp); +// } ++ if(ifp) ++ fclose(ifp); ifp = sfp; free (buf); } -@@ -5766,6 +5402,7 @@ +@@ -5770,6 +5419,7 @@ int CLASS parse_tiff (int base) { int doff; @@ -742,7 +756,7 @@ fseek (ifp, base, SEEK_SET); order = get2(); -@@ -5843,7 +5480,7 @@ +@@ -5847,7 +5497,7 @@ case 8: load_raw = &CLASS eight_bit_load_raw; break; case 12: if (tiff_ifd[raw].phint == 2) load_flags = 6; @@ -751,7 +765,7 @@ case 14: load_flags = 0; case 16: load_raw = &CLASS unpacked_load_raw; if (!strncmp(make,"OLYMPUS",7) && -@@ -5959,7 +5596,7 @@ +@@ -5963,7 +5613,7 @@ { const char *file, *ext; char *jname, *jfile, *jext; @@ -760,7 +774,7 @@ ext = strrchr (ifname, '.'); file = strrchr (ifname, '/'); -@@ -5981,13 +5618,14 @@ +@@ -5985,13 +5635,14 @@ } else while (isdigit(*--jext)) { if (*jext != '9') { @@ -777,7 +791,7 @@ if (verbose) fprintf (stderr,_("Reading metadata from %s ...\n"), jname); parse_tiff (12); -@@ -6330,7 +5968,11 @@ +@@ -6334,7 +5985,11 @@ order = get2(); hlen = get4(); if (get4() == 0x48454150) /* "HEAP" */ @@ -789,7 +803,7 @@ if (parse_tiff (save+6)) apply_tiff(); fseek (ifp, save+len, SEEK_SET); } -@@ -6582,7 +6224,8 @@ +@@ -6586,7 +6241,8 @@ { static const struct { const char *prefix; @@ -799,7 +813,7 @@ } table[] = { { "AgfaPhoto DC-833m", 0, 0, /* DJC */ { 11438,-3762,-1115,-2409,9914,2497,-1227,2295,5300 } }, -@@ -7383,6 +7026,27 @@ +@@ -7457,6 +7113,27 @@ } break; } @@ -820,14 +834,14 @@ + for (j=0; j < 12; j++) { + cam_xyz[0][j] = trans[j] / 10000.0; + } -+ cam_xyz_coeff (cam_xyz); ++ cam_xyz_coeff (rgb_cam,cam_xyz); + } + } + } } void CLASS simple_coeff (int index) -@@ -7682,13 +7346,20 @@ +@@ -7764,13 +7441,20 @@ fread (head, 1, 32, ifp); fseek (ifp, 0, SEEK_END); flen = fsize = ftell(ifp); @@ -850,7 +864,7 @@ parse_ciff (hlen, flen-hlen, 0); load_raw = &CLASS canon_load_raw; } else if (parse_tiff(0)) apply_tiff(); -@@ -7734,6 +7405,7 @@ +@@ -7816,6 +7500,7 @@ fseek (ifp, 100+28*(shot_select > 0), SEEK_SET); parse_tiff (data_offset = get4()); parse_tiff (thumb_offset+12); @@ -858,7 +872,7 @@ apply_tiff(); } else if (!memcmp (head,"RIFF",4)) { fseek (ifp, 0, SEEK_SET); -@@ -7839,15 +7511,18 @@ +@@ -7925,15 +7610,18 @@ if (make[0] == 0) parse_smal (0, flen); if (make[0] == 0) { parse_jpeg(0); @@ -886,7 +900,7 @@ } for (i=0; i < sizeof corp / sizeof *corp; i++) -@@ -7878,7 +7553,7 @@ +@@ -7966,7 +7654,7 @@ if (height == 3136 && width == 4864) /* Pentax K20D and Samsung GX20 */ { height = 3124; width = 4688; filters = 0x16161616; } if (width == 4352 && (!strcmp(model,"K-r") || !strcmp(model,"K-x"))) @@ -895,16 +909,25 @@ if (width >= 4960 && !strncmp(model,"K-5",3)) { left_margin = 10; width = 4950; filters = 0x16161616; } if (width == 4736 && !strcmp(model,"K-7")) -@@ -8026,7 +7701,7 @@ +@@ -8112,7 +7800,7 @@ width -= 44; } else if (!strcmp(model,"D3200") || !strcmp(model,"D600") || - !strncmp(model,"D800",4)) { + !strcmp(model,"D800") || !strcmp(model,"D800E") ) { width -= 46; - } else if (!strcmp(model,"D4")) { - width -= 52; -@@ -8631,194 +8306,7 @@ + } else if (!strcmp(model,"D4") || + !strcmp(model,"Df")) { +@@ -8630,6 +8318,8 @@ + memcpy (rgb_cam, cmatrix, sizeof cmatrix); + raw_color = 0; + } ++ if(!strncmp(make, "Samsung", 7) && !strncmp(model, "GX20",4)) ++ adobe_coeff (make, model); + if (raw_color) adobe_coeff (make, model); + if (load_raw == &CLASS kodak_radc_load_raw) + if (raw_color) adobe_coeff ("Apple","Quicktake"); +@@ -8725,194 +8415,7 @@ } #endif @@ -1100,7 +1123,7 @@ struct tiff_tag { ushort tag, type; -@@ -8841,584 +8329,12 @@ +@@ -8935,585 +8438,12 @@ unsigned gps[26]; char desc[512], make[64], model[64], soft[32], date[20], artist[64]; }; @@ -1396,7 +1419,7 @@ - case 'A': FORC4 greybox[c] = atoi(argv[arg++]); - case 'a': use_auto_wb = 1; break; - case 'w': use_camera_wb = 1; break; -- case 'M': use_camera_matrix = (opm == '+'); break; +- case 'M': use_camera_matrix = 3 * (opm == '+'); break; - case 'I': read_from_stdin = 1; break; - case 'E': document_mode++; - case 'D': document_mode++; @@ -1412,8 +1435,6 @@ - return 1; - } - } -- if (use_camera_matrix < 0) -- use_camera_matrix = use_camera_wb; - if (arg == argc) { - fprintf (stderr,_("No files to process.\n")); - return 1; @@ -1480,6 +1501,7 @@ - height = thumb_height; - width = thumb_width; - filters = 0; +- colors = 3; - } else { - fseek (ifp, thumb_offset, SEEK_SET); - write_fun = write_thumb; @@ -1564,10 +1586,6 @@ - fclose(ifp); - continue; - } -- if (use_camera_matrix && cmatrix[0][0] > 0.25) { -- memcpy (rgb_cam, cmatrix, sizeof cmatrix); -- raw_color = 0; -- } - if (meta_length) { - meta_data = (char *) malloc (meta_length); - merror (meta_data, "main()"); @@ -1611,6 +1629,12 @@ - FORC3 if (i > cblack[c]) i = cblack[c]; - FORC4 cblack[c] -= i; - black += i; +- i = cblack[6]; +- FORC (cblack[4] * cblack[5]) +- if (i > cblack[6+c]) i = cblack[6+c]; +- FORC (cblack[4] * cblack[5]) +- cblack[6+c] -= i; +- black += i; - if (user_black >= 0) black = user_black; - FORC4 cblack[c] += black; - if (user_sat > 0) maximum = user_sat; diff --git a/rtengine/rawimage.cc b/rtengine/rawimage.cc index 485be7411..0a8d17d0e 100755 --- a/rtengine/rawimage.cc +++ b/rtengine/rawimage.cc @@ -56,9 +56,18 @@ void RawImage::get_colorsCoeff( float *pre_mul_, float *scale_mul_, float *cblac int val; double dsum[8], dmin, dmax; - for (int c = 0; c < 4; c++){ - cblack_[c] = (float) this->get_cblack(c); - pre_mul_[c] = this->get_pre_mul(c); + + + if ((this->get_cblack(4)+1)/2 == 1 && (this->get_cblack(5)+1)/2 == 1) { + for (int c = 0; c < 4; c++){ + cblack_[FC(c/2,c%2)] = this->get_cblack(6 + c/2 % this->get_cblack(4) * this->get_cblack(5) + c%2 % this->get_cblack(5)); + pre_mul_[c] = this->get_pre_mul(c); + } + } else { + for (int c = 0; c < 4; c++){ + cblack_[c] = (float) this->get_cblack(c); + pre_mul_[c] = this->get_pre_mul(c); + } } if ( this->get_cam_mul(0) == -1 || forceAutoWB) { memset(dsum, 0, sizeof dsum); @@ -239,6 +248,8 @@ int RawImage::loadRaw (bool loadData, bool closeFile) if (cc && cc->has_rawCrop()) { int lm, tm, w, h; cc->get_rawCrop(lm, tm, w, h); + if(((int)top_margin - tm) & 1) // we have an odd border difference + filters = (filters << 4) | (filters >> 28); // left rotate filters by 4 bits left_margin = lm; top_margin = tm; if (w < 0) { @@ -508,10 +519,6 @@ DCraw::dcraw_coeff_overrides(const char make[], const char model[], const int is { 7181,-1706,-55,-3557,11409,2450,-621,2072,7533 } }, - { "Sony DSLR-A700", 126 << dcraw_arw2_scaling_bugfix_shift, -1, /* RT */ - { 6509,-1333,-137,-6171,13621,2824,-1490,2226,6952 } }, - { "Sony DSLR-A900", 128 << dcraw_arw2_scaling_bugfix_shift, -1, /* RT */ - { 5715,-1433,-410,-5603,12937,2989,-644,1247,8372 } }, { "SONY NEX-3", 128 << dcraw_arw2_scaling_bugfix_shift, -1, /* RT - Colin Walker */ { 5145,-741,-123,-4915,12310,2945,-794,1489,6906 } }, { "SONY NEX-5", 128 << dcraw_arw2_scaling_bugfix_shift, -1, /* RT - Colin Walker */