diff --git a/rtengine/camconst.json b/rtengine/camconst.json index fb4d3a501..892d1a0e7 100755 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -884,17 +884,33 @@ Quality X: unknown, ie we knowing to little about the camera properties to know "ranges": { "black": 0, "white": 63300 } }, - { // Quality A + { // Quality A for tested CFV, the other models have the same sensor (16 megapixel square sensor) + "make_model": [ "Hasselblad V96C", "Hasselblad CFV", "Hasselblad CFV-II" ], + "dcraw_matrix": [ 8519, -3260, -280, -5081, 13459, 1738, -1449, 2960, 7809 ] // borrowed from Adobe's DNG converter + }, + { // Quality A for tested CF-22, the other models have the same sensor + "make_model": [ "Hasselblad CF-22", "Hasselblad CF-22MS", "Hasselblad CFH-22", "Hasselblad H3D-22", "Hasselblad H3DII-22" ], + "dcraw_matrix": [ 8519, -3260, -280, -5081, 13459, 1738, -1449, 2960, 7809 ] // borrowed from Adobe's DNG converter + }, + { // Quality A for tested H3D-31, the other models have the same sensor "make_model": [ "Hasselblad H3D-31", "Hasselblad H3DII-31", "Hasselblad H4D-31" ], - "dcraw_matrix": [ 5458, -1448, 145, -4479, 12338, 2401, -1659, 3086, 6710 ] + "dcraw_matrix": [ 5458, -1448, 145, -4479, 12338, 2401, -1659, 3086, 6710 ] // borrowed from Adobe's DNG converter + }, + { // Quality A for tested CFV-39, the other models have the same sensor. Small filter differences may exist so some might do better with a slightly different profile + "make_model": [ "Hasselblad CF-39", "Hasselblad CF-39MS", "Hasselblad CFH-39", "Hasselblad CFV-39", "Hasselblad H3D-39", "Hasselblad H3DII-39", "Hasselblad H3DII-39MS" ], + "dcraw_matrix": [ 3857, 452, -46, -6008, 14477, 1596, -2627, 4481, 5718 ] // borrowed from Adobe's DNG converter + }, + { // Quality A for tested CFV-50, the other models have the same sensor + "make_model": [ "Hasselblad CFV-50", "Hasselblad H3DII-50", "Hasselblad H3DII-50MS", "Hasselblad H4D-50", "Hasselblad H4D-50MS", "Hasselblad H4D-200MS", "Hasselblad H5D-50", "Hasselblad H5D-50MS", "Hasselblad H5D-200MS" ], + "dcraw_matrix": [ 5656, -659, -346, -3923, 12306, 1791, -1602, 3509, 5442 ] // borrowed from Adobe's DNG converter }, { // Quality A - "make_model": [ "Hasselblad CFV-50", "Hasselblad H3DII-50", "Hasselblad H3DII-50MS", "Hasselblad H4D-50", "Hasselblad H4D-50MS", "Hasselblad H4D-200MS", "Hasselblad H5D-50", "Hasselblad H5D-50 Multi-Shot" ], - "dcraw_matrix": [ 5656, -659, -346, -3923, 12306, 1791, -1602, 3509, 5442 ] + "make_model": [ "Hasselblad H4D-40", "Hasselblad H5D-40" ], + "dcraw_matrix": [ 9662, -684, -279, -4903, 12293, 2950, -344, 1669, 6024 ] // borrowed from Adobe's DNG converter }, - { // Quality A + { // Quality A for tested H4D-60, the other models have the same sensor "make_model": [ "Hasselblad H4D-60", "Hasselblad H5D-60" ], - "dcraw_matrix": [ 9662, -684, -279, -4903, 12293, 2950, -344, 1669, 6024 ] + "dcraw_matrix": [ 9662, -684, -279, -4903, 12293, 2950, -344, 1669, 6024 ] // borrowed from Adobe's DNG converter }, // dummy test entry to test the parser and show the format with all entries active diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index 792aa14c4..e97b71106 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -5489,6 +5489,9 @@ int CLASS parse_tiff_ifd (int base) if (!make[0]) strcpy (make, "DNG"); is_raw = 1; break; + case 50708: /* UniqueCameraModel */ + fgets (model3, 64, ifp); + break; case 50710: /* CFAPlaneColor */ if (len > 4) len = 4; colors = len; @@ -7636,7 +7639,7 @@ void CLASS identify() tiff_flip = flip = filters = UINT_MAX; /* unknown */ raw_height = raw_width = fuji_width = fuji_layout = cr2_slice[0] = 0; maximum = height = width = top_margin = left_margin = 0; - cdesc[0] = desc[0] = artist[0] = make[0] = model[0] = model2[0] = 0; + cdesc[0] = desc[0] = artist[0] = make[0] = model[0] = model2[0] = model3[0] = 0; iso_speed = shutter = aperture = focal_len = unique_id = 0; tiff_nifds = 0; memset (tiff_ifd, 0, sizeof tiff_ifd); @@ -8240,6 +8243,7 @@ konica_400z: if (load_raw == &CLASS lossless_jpeg_load_raw) load_raw = &CLASS hasselblad_load_raw; if (raw_width == 7262) { + if (!strcmp(model, "H3D")) strcpy(model, "H3D-39"); // RT height = 5444; width = 7248; top_margin = 4; @@ -8252,13 +8256,13 @@ konica_400z: left_margin = 41; filters = 0x61616161; } else if (raw_width == 6542) { // RT, H3D-31, H3DII-31 - if (!strcmp(model, "H3D")) strcpy(model, "H3D-31"); // note: can't differ between H3D-31 and H3DII-31. + if (!strcmp(model, "H3D")) strcpy(model, "H3D-31"); height = 4904; width = 6524; top_margin = 4; left_margin = 8; } else if (raw_width == 8282) { // RT, H3DII-50, H3DII-50MS, CFV-50 - if (!strcmp(model, "H3D")) strcpy(model, "H3DII-50"); // note: can't differ between H3DII-50 and H3DII-50MS + if (!strcmp(model, "H3D")) strcpy(model, "H3DII-50"); height = 6152; width = 8196; top_margin = 4; @@ -8271,6 +8275,11 @@ konica_400z: // RT: removed black level / maximum adjustment, as it does not seem to be correct when there are clipped highlights. Tested with Hasselblad H4D-60. //black += load_flags = 256; //maximum = 0x8101; + } else if (raw_width == 4096) { // RT: CF-22 etc + if (!strcmp(model, "H3D")) strcpy(model, "H3D-22"); + else if (strstr(model3, "Hasselblad ") == model3) strcpy(model, &model3[11]); + if (strstr(model3, "ixpressCF132")) strcpy(model, "CF-22"); // ixpressCF132 / CF132 is same as CF-22, we use the simpler name + else if (strstr(model3, "Hasselblad96")) strcpy(model, "CFV"); // popularly called CFV-16 } else if (raw_width == 4090) { strcpy (model, "V96C"); height -= (top_margin = 6); diff --git a/rtengine/dcraw.h b/rtengine/dcraw.h index b19362f2d..f9a7b4463 100644 --- a/rtengine/dcraw.h +++ b/rtengine/dcraw.h @@ -76,7 +76,7 @@ protected: short order; const char *ifname; char *meta_data, xtrans[6][6]; - char cdesc[5], desc[512], make[64], model[64], model2[64], artist[64]; + char cdesc[5], desc[512], make[64], model[64], model2[64], model3[64], artist[64]; float flash_used, canon_ev, iso_speed, shutter, aperture, focal_len; time_t timestamp; unsigned shot_order, kodak_cbpp, filters, exif_cfa, unique_id; diff --git a/rtengine/dcraw.patch b/rtengine/dcraw.patch index 49b3a2fe5..03feaca93 100755 --- a/rtengine/dcraw.patch +++ b/rtengine/dcraw.patch @@ -1,5 +1,5 @@ --- dcraw.c 2014-02-19 17:25:45.051457734 +0100 -+++ dcraw.cc 2014-05-24 13:32:56.039537212 +0200 ++++ dcraw.cc 2014-05-26 14:28:48.785835594 +0200 @@ -1,3 +1,15 @@ +/*RT*/#include +/*RT*/#include @@ -1051,7 +1051,17 @@ case 400: strcpy (make, "Sarnoff"); maximum = 0xfff; -@@ -5660,10 +5519,21 @@ +@@ -5630,6 +5489,9 @@ + if (!make[0]) strcpy (make, "DNG"); + is_raw = 1; + break; ++ case 50708: /* UniqueCameraModel */ ++ fgets (model3, 64, ifp); ++ break; + case 50710: /* CFAPlaneColor */ + if (len > 4) len = 4; + colors = len; +@@ -5660,10 +5522,21 @@ case 61450: cblack[4] = cblack[5] = MIN(sqrt(len),64); case 50714: /* BlackLevel */ @@ -1077,7 +1087,7 @@ case 50715: /* BlackLevelDeltaH */ case 50716: /* BlackLevelDeltaV */ for (num=i=0; i < len; i++) -@@ -5741,12 +5611,15 @@ +@@ -5741,12 +5614,15 @@ fread (buf, sony_length, 1, ifp); sony_decrypt (buf, sony_length/4, 1, sony_key); sfp = ifp; @@ -1099,7 +1109,7 @@ ifp = sfp; free (buf); } -@@ -5770,6 +5643,7 @@ +@@ -5770,6 +5646,7 @@ int CLASS parse_tiff (int base) { int doff; @@ -1107,7 +1117,7 @@ fseek (ifp, base, SEEK_SET); order = get2(); -@@ -5847,7 +5721,7 @@ +@@ -5847,7 +5724,7 @@ case 8: load_raw = &CLASS eight_bit_load_raw; break; case 12: if (tiff_ifd[raw].phint == 2) load_flags = 6; @@ -1116,7 +1126,7 @@ case 14: load_flags = 0; case 16: load_raw = &CLASS unpacked_load_raw; if (!strncmp(make,"OLYMPUS",7) && -@@ -5878,6 +5752,7 @@ +@@ -5878,6 +5755,7 @@ case 32803: load_raw = &CLASS kodak_65000_load_raw; } case 32867: case 34892: break; @@ -1124,7 +1134,7 @@ default: is_raw = 0; } if (!dng_version) -@@ -5963,7 +5838,7 @@ +@@ -5963,7 +5841,7 @@ { const char *file, *ext; char *jname, *jfile, *jext; @@ -1133,7 +1143,7 @@ ext = strrchr (ifname, '.'); file = strrchr (ifname, '/'); -@@ -5985,13 +5860,14 @@ +@@ -5985,13 +5863,14 @@ } else while (isdigit(*--jext)) { if (*jext != '9') { @@ -1150,7 +1160,7 @@ if (verbose) fprintf (stderr,_("Reading metadata from %s ...\n"), jname); parse_tiff (12); -@@ -6256,6 +6132,8 @@ +@@ -6256,6 +6135,8 @@ case 0x21d: ph1.black = data; break; case 0x222: ph1.split_col = data; break; case 0x223: ph1.black_off = data+base; break; @@ -1159,7 +1169,7 @@ case 0x301: model[63] = 0; fread (model, 1, 63, ifp); -@@ -6334,7 +6212,11 @@ +@@ -6334,7 +6215,11 @@ order = get2(); hlen = get4(); if (get4() == 0x48454150) /* "HEAP" */ @@ -1171,7 +1181,7 @@ if (parse_tiff (save+6)) apply_tiff(); fseek (ifp, save+len, SEEK_SET); } -@@ -6586,7 +6468,8 @@ +@@ -6586,7 +6471,8 @@ { static const struct { const char *prefix; @@ -1181,7 +1191,7 @@ } table[] = { { "AgfaPhoto DC-833m", 0, 0, /* DJC */ { 11438,-3762,-1115,-2409,9914,2497,-1227,2295,5300 } }, -@@ -7457,6 +7340,27 @@ +@@ -7457,6 +7343,27 @@ } break; } @@ -1209,7 +1219,16 @@ } void CLASS simple_coeff (int index) -@@ -7764,13 +7668,20 @@ +@@ -7732,7 +7639,7 @@ + tiff_flip = flip = filters = UINT_MAX; /* unknown */ + raw_height = raw_width = fuji_width = fuji_layout = cr2_slice[0] = 0; + maximum = height = width = top_margin = left_margin = 0; +- cdesc[0] = desc[0] = artist[0] = make[0] = model[0] = model2[0] = 0; ++ cdesc[0] = desc[0] = artist[0] = make[0] = model[0] = model2[0] = model3[0] = 0; + iso_speed = shutter = aperture = focal_len = unique_id = 0; + tiff_nifds = 0; + memset (tiff_ifd, 0, sizeof tiff_ifd); +@@ -7764,13 +7671,20 @@ fread (head, 1, 32, ifp); fseek (ifp, 0, SEEK_END); flen = fsize = ftell(ifp); @@ -1232,7 +1251,7 @@ parse_ciff (hlen, flen-hlen, 0); load_raw = &CLASS canon_load_raw; } else if (parse_tiff(0)) apply_tiff(); -@@ -7816,6 +7727,7 @@ +@@ -7816,6 +7730,7 @@ fseek (ifp, 100+28*(shot_select > 0), SEEK_SET); parse_tiff (data_offset = get4()); parse_tiff (thumb_offset+12); @@ -1240,7 +1259,7 @@ apply_tiff(); } else if (!memcmp (head,"RIFF",4)) { fseek (ifp, 0, SEEK_SET); -@@ -7925,15 +7837,18 @@ +@@ -7925,15 +7840,18 @@ if (make[0] == 0) parse_smal (0, flen); if (make[0] == 0) { parse_jpeg(0); @@ -1268,7 +1287,7 @@ } for (i=0; i < sizeof corp / sizeof *corp; i++) -@@ -7966,7 +7881,7 @@ +@@ -7966,7 +7884,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"))) @@ -1277,7 +1296,7 @@ if (width >= 4960 && !strncmp(model,"K-5",3)) { left_margin = 10; width = 4950; filters = 0x16161616; } if (width == 4736 && !strcmp(model,"K-7")) -@@ -7985,6 +7900,7 @@ +@@ -7985,6 +7903,7 @@ switch (tiff_compress) { case 1: load_raw = &CLASS packed_dng_load_raw; break; case 7: load_raw = &CLASS lossless_dng_load_raw; break; @@ -1285,7 +1304,7 @@ case 34892: load_raw = &CLASS lossy_dng_load_raw; break; default: load_raw = 0; } -@@ -8112,7 +8028,7 @@ +@@ -8112,7 +8031,7 @@ width -= 44; } else if (!strcmp(model,"D3200") || !strcmp(model,"D600") || @@ -1294,18 +1313,26 @@ width -= 46; } else if (!strcmp(model,"D4") || !strcmp(model,"Df")) { -@@ -8335,13 +8251,26 @@ +@@ -8324,6 +8243,7 @@ + if (load_raw == &CLASS lossless_jpeg_load_raw) + load_raw = &CLASS hasselblad_load_raw; + if (raw_width == 7262) { ++ if (!strcmp(model, "H3D")) strcpy(model, "H3D-39"); // RT + height = 5444; + width = 7248; + top_margin = 4; +@@ -8335,13 +8255,31 @@ top_margin = 4; left_margin = 41; filters = 0x61616161; + } else if (raw_width == 6542) { // RT, H3D-31, H3DII-31 -+ if (!strcmp(model, "H3D")) strcpy(model, "H3D-31"); // note: can't differ between H3D-31 and H3DII-31. ++ if (!strcmp(model, "H3D")) strcpy(model, "H3D-31"); + height = 4904; + width = 6524; + top_margin = 4; + left_margin = 8; + } else if (raw_width == 8282) { // RT, H3DII-50, H3DII-50MS, CFV-50 -+ if (!strcmp(model, "H3D")) strcpy(model, "H3DII-50"); // note: can't differ between H3DII-50 and H3DII-50MS ++ if (!strcmp(model, "H3D")) strcpy(model, "H3DII-50"); + height = 6152; + width = 8196; + top_margin = 4; @@ -1320,10 +1347,15 @@ + // RT: removed black level / maximum adjustment, as it does not seem to be correct when there are clipped highlights. Tested with Hasselblad H4D-60. + //black += load_flags = 256; + //maximum = 0x8101; ++ } else if (raw_width == 4096) { // RT: CF-22 etc ++ if (!strcmp(model, "H3D")) strcpy(model, "H3D-22"); ++ else if (strstr(model3, "Hasselblad ") == model3) strcpy(model, &model3[11]); ++ if (strstr(model3, "ixpressCF132")) strcpy(model, "CF-22"); // ixpressCF132 / CF132 is same as CF-22, we use the simpler name ++ else if (strstr(model3, "Hasselblad96")) strcpy(model, "CFV"); // popularly called CFV-16 } else if (raw_width == 4090) { strcpy (model, "V96C"); height -= (top_margin = 6); -@@ -8394,6 +8323,7 @@ +@@ -8394,6 +8332,7 @@ filters = 0x16161616; } } else if (!strcmp(make,"Leica") || !strcmp(make,"Panasonic")) { @@ -1331,7 +1363,7 @@ if ((flen - data_offset) / (raw_width*8/7) == raw_height) load_raw = &CLASS panasonic_load_raw; if (!load_raw) { -@@ -8411,6 +8341,7 @@ +@@ -8411,6 +8350,7 @@ } filters = 0x01010101 * (uchar) "\x94\x61\x49\x16" [((filters-1) ^ (left_margin & 1) ^ (top_margin << 1)) & 3]; @@ -1339,7 +1371,7 @@ } else if (!strcmp(model,"C770UZ")) { height = 1718; width = 2304; -@@ -8630,6 +8561,10 @@ +@@ -8630,6 +8570,10 @@ memcpy (rgb_cam, cmatrix, sizeof cmatrix); raw_color = 0; } @@ -1350,7 +1382,7 @@ if (raw_color) adobe_coeff (make, model); if (load_raw == &CLASS kodak_radc_load_raw) if (raw_color) adobe_coeff ("Apple","Quicktake"); -@@ -8646,7 +8581,7 @@ +@@ -8646,7 +8590,7 @@ if (!tiff_bps) tiff_bps = 12; if (!maximum) maximum = (1 << tiff_bps) - 1; if (!load_raw || height < 22 || width < 22 || @@ -1359,7 +1391,7 @@ is_raw = 0; #ifdef NO_JASPER if (load_raw == &CLASS redcine_load_raw) { -@@ -8725,195 +8660,269 @@ +@@ -8725,194 +8669,268 @@ } #endif @@ -1745,7 +1777,11 @@ +#ifdef _OPENMP +#pragma omp parallel +#endif -+{ + { +- if (flip & 4) SWAP(row,col); +- if (flip & 2) row = iheight - 1 - row; +- if (flip & 1) col = iwidth - 1 - col; +- return row * iwidth + col; + Bytef cBuffer[maxCompressed]; + Bytef uBuffer[dstLen]; + float maxValuethr = 0.0f; @@ -1783,28 +1819,23 @@ +#ifdef _OPENMP +#pragma omp critical +#endif - { -- if (flip & 4) SWAP(row,col); -- if (flip & 2) row = iheight - 1 - row; -- if (flip & 1) col = iwidth - 1 - col; -- return row * iwidth + col; ++{ + if(maxValuethr > maxValue) + maxValue = maxValuethr; +} -+} + } + } + + if (ifd->sample_format == 3) { // Floating point data + copyFloatDataToInt(float_raw_image, raw_image, raw_width*raw_height, maxValue); + } - } - -+/* RT: removed unused functions */ ++} + ++/* RT: removed unused functions */ + struct tiff_tag { ushort tag, type; - int count; -@@ -8935,585 +8944,12 @@ +@@ -8935,585 +8953,12 @@ unsigned gps[26]; char desc[512], make[64], model[64], soft[32], date[20], artist[64]; };