From 4fbb0cd3ebe83d6926febae271c8a5d0e101912c Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Wed, 24 Oct 2018 12:03:15 +0200 Subject: [PATCH 1/7] DNG: use black/white levels and matrix from the file, unless it comes from the Adobe DNG Converter See #4472 --- rtengine/dcraw.cc | 19 ++++++++++-------- rtengine/dcraw.h | 16 +++++++-------- rtengine/rawimage.cc | 47 +++++++++++++++++++++++++++++++++----------- 3 files changed, 54 insertions(+), 28 deletions(-) diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index 035dab2b2..99d006744 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -6113,6 +6113,7 @@ int CLASS parse_tiff_ifd (int base) break; case 305: case 11: /* Software */ fgets (software, 64, ifp); + RT_software = software; if (!strncmp(software,"Adobe",5) || !strncmp(software,"dcraw",5) || !strncmp(software,"UFRaw",5) || @@ -6395,15 +6396,18 @@ guess_cfa_pc: cblack[6+c] = getreal(type); } black = 0; + RT_blacklevel_from_constant = ThreeValBool::F; break; case 50715: /* BlackLevelDeltaH */ case 50716: /* BlackLevelDeltaV */ for (num=i=0; i < (len & 0xffff); i++) num += getreal(type); black += num/len + 0.5; + RT_blacklevel_from_constant = ThreeValBool::F; break; case 50717: /* WhiteLevel */ maximum = getint(type); + RT_whitelevel_from_constant = ThreeValBool::F; break; case 50718: /* DefaultScale */ pixel_aspect = getreal(type); @@ -6541,8 +6545,6 @@ guess_cfa_pc: if (!use_cm) FORCC pre_mul[c] /= cc[cm_D65][c][c]; - RT_from_adobe_dng_converter = !strncmp(software, "Adobe DNG Converter", 19); - return 0; } @@ -10042,12 +10044,13 @@ bw: colors = 1; dng_skip: if ((use_camera_matrix & (use_camera_wb || dng_version)) && cmatrix[0][0] > 0.125 - && !RT_from_adobe_dng_converter /* RT -- do not use the embedded - * matrices for DNGs coming from the - * Adobe DNG Converter, to ensure - * consistency of WB values between - * DNG-converted and original raw - * files. See #4129 */) { + && strncmp(RT_software.c_str(), "Adobe DNG Converter", 19) != 0 + /* RT -- do not use the embedded + * matrices for DNGs coming from the + * Adobe DNG Converter, to ensure + * consistency of WB values between + * DNG-converted and original raw + * files. See #4129 */) { memcpy (rgb_cam, cmatrix, sizeof cmatrix); raw_color = 0; } diff --git a/rtengine/dcraw.h b/rtengine/dcraw.h index 9c6ac4aec..e1b296dbf 100644 --- a/rtengine/dcraw.h +++ b/rtengine/dcraw.h @@ -55,10 +55,9 @@ public: ,verbose(0) ,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) - ,RT_whitelevel_from_constant(0) - ,RT_blacklevel_from_constant(0) - ,RT_matrix_from_constant(0) - ,RT_from_adobe_dng_converter(false) + ,RT_whitelevel_from_constant(ThreeValBool::X) + ,RT_blacklevel_from_constant(ThreeValBool::X) + ,RT_matrix_from_constant(ThreeValBool::X) ,getbithuff(this,ifp,zero_after_ff) ,nikbithuff(ifp) { @@ -150,10 +149,11 @@ protected: int output_color, output_bps, output_tiff, med_passes; int no_auto_bright; unsigned greybox[4] ; - int RT_whitelevel_from_constant; - int RT_blacklevel_from_constant; - int RT_matrix_from_constant; - bool RT_from_adobe_dng_converter; + enum class ThreeValBool { X = -1, F, T }; + ThreeValBool RT_whitelevel_from_constant; + ThreeValBool RT_blacklevel_from_constant; + ThreeValBool RT_matrix_from_constant; + std::string RT_software; float cam_mul[4], pre_mul[4], cmatrix[3][4], rgb_cam[3][4]; diff --git a/rtengine/rawimage.cc b/rtengine/rawimage.cc index 6ef110a03..131b04156 100644 --- a/rtengine/rawimage.cc +++ b/rtengine/rawimage.cc @@ -30,9 +30,9 @@ RawImage::RawImage( const Glib::ustring &name ) , allocation(nullptr) { memset(maximum_c4, 0, sizeof(maximum_c4)); - RT_matrix_from_constant = 0; - RT_blacklevel_from_constant = 0; - RT_whitelevel_from_constant = 0; + RT_matrix_from_constant = ThreeValBool::X; + RT_blacklevel_from_constant = ThreeValBool::X; + RT_whitelevel_from_constant = ThreeValBool::X; } RawImage::~RawImage() @@ -599,14 +599,14 @@ int RawImage::loadRaw (bool loadData, unsigned int imageNum, bool closeFile, Pro if (cc) { for (int i = 0; i < 4; i++) { - if (RT_blacklevel_from_constant) { + if (RT_blacklevel_from_constant == ThreeValBool::T) { int blackFromCc = cc->get_BlackLevel(i, iso_speed); // if black level from camconst > 0xffff it is an absolute value. black_c4[i] = blackFromCc > 0xffff ? (blackFromCc & 0xffff) : blackFromCc + cblack[i]; } // load 4 channel white level here, will be used if available - if (RT_whitelevel_from_constant) { + if (RT_whitelevel_from_constant == ThreeValBool::T) { maximum_c4[i] = cc->get_WhiteLevel(i, iso_speed, aperture); if(tiff_bps > 0 && maximum_c4[i] > 0 && !isFoveon()) { @@ -1049,6 +1049,15 @@ DCraw::dcraw_coeff_overrides(const char make[], const char model[], const int is *black_level = -1; *white_level = -1; + + const bool is_pentax_dng = dng_version && !strncmp(RT_software.c_str(), "PENTAX", 6); + + if (RT_blacklevel_from_constant == ThreeValBool::F && !is_pentax_dng) { + *black_level = black; + } + if (RT_whitelevel_from_constant == ThreeValBool::F && !is_pentax_dng) { + *white_level = maximum; + } memset(trans, 0, sizeof(*trans) * 12); // indicate that DCRAW wants these from constants (rather than having loaded these from RAW file @@ -1056,9 +1065,15 @@ DCraw::dcraw_coeff_overrides(const char make[], const char model[], const int is // from file, but then we will not provide any black level in the tables. This case is mainly just // to avoid loading table values if we have loaded a DNG conversion of a raw file (which already // have constants stored in the file). - RT_whitelevel_from_constant = 1; - RT_blacklevel_from_constant = 1; - RT_matrix_from_constant = 1; + if (RT_whitelevel_from_constant == ThreeValBool::X || is_pentax_dng) { + RT_whitelevel_from_constant = ThreeValBool::T; + } + if (RT_blacklevel_from_constant == ThreeValBool::X || is_pentax_dng) { + RT_blacklevel_from_constant = ThreeValBool::T; + } + if (RT_matrix_from_constant == ThreeValBool::X) { + RT_matrix_from_constant = ThreeValBool::T; + } { // test if we have any information in the camera constants store, if so we take that. @@ -1066,8 +1081,12 @@ DCraw::dcraw_coeff_overrides(const char make[], const char model[], const int is rtengine::CameraConst *cc = ccs->get(make, model); if (cc) { - *black_level = cc->get_BlackLevel(0, iso_speed); - *white_level = cc->get_WhiteLevel(0, iso_speed, aperture); + if (RT_blacklevel_from_constant == ThreeValBool::T) { + *black_level = cc->get_BlackLevel(0, iso_speed); + } + if (RT_whitelevel_from_constant == ThreeValBool::T) { + *white_level = cc->get_WhiteLevel(0, iso_speed, aperture); + } if (cc->has_dcrawMatrix()) { const short *mx = cc->get_dcrawMatrix(); @@ -1086,8 +1105,12 @@ DCraw::dcraw_coeff_overrides(const char make[], const char model[], const int is for (size_t i = 0; i < sizeof table / sizeof(table[0]); i++) { if (strcasecmp(name, table[i].prefix) == 0) { - *black_level = table[i].black_level; - *white_level = table[i].white_level; + if (RT_blacklevel_from_constant == ThreeValBool::T) { + *black_level = table[i].black_level; + } + if (RT_whitelevel_from_constant == ThreeValBool::T) { + *white_level = table[i].white_level; + } for (int j = 0; j < 12; j++) { trans[j] = table[i].trans[j]; From ce4377d7e533046c140c77c967250cedf58df965 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Sun, 28 Oct 2018 09:39:57 +0100 Subject: [PATCH 2/7] Initial support for uncompressed 16-bit float DNGs --- rtengine/dcraw.cc | 44 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index 99d006744..6bb238396 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -30,6 +30,10 @@ //#define BENCHMARK #include "StopWatch.h" +#include +#include + + /* dcraw.c -- Dave Coffin's raw photo decoder Copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net @@ -1170,23 +1174,37 @@ void CLASS lossless_dng_load_raw() } } +static uint32_t DNG_HalfToFloat(uint16_t halfValue); void CLASS packed_dng_load_raw() { ushort *pixel, *rp; int row, col; + int isfloat = (tiff_nifds == 1 && tiff_ifd[0].sample_format == 3 && tiff_bps == 16); + if (isfloat) { + float_raw_image = new float[raw_width * raw_height]; + } pixel = (ushort *) calloc (raw_width, tiff_samples*sizeof *pixel); merror (pixel, "packed_dng_load_raw()"); for (row=0; row < raw_height; row++) { - if (tiff_bps == 16) + if (tiff_bps == 16) { read_shorts (pixel, raw_width * tiff_samples); - else { + if (isfloat) { + uint32_t *dst = reinterpret_cast(&float_raw_image[row*raw_width]); + for (col = 0; col < raw_width; col++) { + uint32_t f = DNG_HalfToFloat(pixel[col]); + dst[col] = f; + } + } + } else { getbits(-1); for (col=0; col < raw_width * tiff_samples; col++) pixel[col] = getbits(tiff_bps); } - for (rp=pixel, col=0; col < raw_width; col++) - adobe_copy_pixel (row, col, &rp); + if (!isfloat) { + for (rp=pixel, col=0; col < raw_width; col++) + adobe_copy_pixel (row, col, &rp); + } } free (pixel); } @@ -10086,7 +10104,14 @@ dng_skip: if (raw_width < width ) raw_width = width; } if (!tiff_bps) tiff_bps = 12; - if (!maximum) maximum = ((uint64_t)1 << tiff_bps) - 1; // use uint64_t to avoid overflow if tiff_bps == 32 + if (!maximum) { + if (tiff_nifds == 1 && tiff_ifd[0].sample_format == 3) { + // float DNG, default white level is 1.0 + maximum = 1; + } else { + maximum = ((uint64_t)1 << tiff_bps) - 1; // use uint64_t to avoid overflow if tiff_bps == 32 + } + } if (!load_raw || height < 22 || width < 22 || tiff_samples > 6 || colors > 4) is_raw = 0; @@ -10169,8 +10194,8 @@ notraw: /* RT: DNG Float */ -#include -#include +// #include +// #include static void decodeFPDeltaRow(Bytef * src, Bytef * dst, size_t tileWidth, size_t realTileWidth, int bytesps, int factor) { // DecodeDeltaBytes @@ -10202,9 +10227,10 @@ static void decodeFPDeltaRow(Bytef * src, Bytef * dst, size_t tileWidth, size_t } -#ifndef __F16C__ +#if 1 //ndef __F16C__ // From DNG SDK dng_utils.h -static inline uint32_t DNG_HalfToFloat(uint16_t halfValue) { +static //inline +uint32_t DNG_HalfToFloat(uint16_t halfValue) { int32_t sign = (halfValue >> 15) & 0x00000001; int32_t exponent = (halfValue >> 10) & 0x0000001f; int32_t mantissa = halfValue & 0x000003ff; From c63633a76db4f556a460c5b3fcbc683a874fa0a2 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Sun, 28 Oct 2018 10:15:59 +0100 Subject: [PATCH 3/7] support for uncompressed 32-bit float DNGs --- rtengine/dcraw.cc | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index 6bb238396..81013bc0b 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -1175,14 +1175,15 @@ void CLASS lossless_dng_load_raw() } static uint32_t DNG_HalfToFloat(uint16_t halfValue); + void CLASS packed_dng_load_raw() { ushort *pixel, *rp; int row, col; - int isfloat = (tiff_nifds == 1 && tiff_ifd[0].sample_format == 3 && tiff_bps == 16); + int isfloat = (tiff_nifds == 1 && tiff_ifd[0].sample_format == 3 && (tiff_bps == 16 || tiff_bps == 32)); if (isfloat) { float_raw_image = new float[raw_width * raw_height]; - } + } pixel = (ushort *) calloc (raw_width, tiff_samples*sizeof *pixel); merror (pixel, "packed_dng_load_raw()"); @@ -1196,6 +1197,14 @@ void CLASS packed_dng_load_raw() dst[col] = f; } } + } else if (isfloat) { + if (fread(&float_raw_image[row*raw_width], sizeof(float), raw_width, ifp) != raw_width) { + derror(); + } + if ((order == 0x4949) == (ntohs(0x1234) == 0x1234)) { + char *d = reinterpret_cast(float_raw_image); + rtengine::swab(d, d, sizeof(float)*raw_width); + } } else { getbits(-1); for (col=0; col < raw_width * tiff_samples; col++) From 632c1362c82045d78767e9a835b75b235893092f Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Sun, 28 Oct 2018 17:32:15 +0100 Subject: [PATCH 4/7] DNG: honour the BaselineExposure tag --- rtengine/dcraw.cc | 3 +++ rtengine/dcraw.h | 2 ++ rtengine/rawimage.h | 2 ++ rtengine/rawimagesource.cc | 5 +++++ rtengine/rtthumbnail.cc | 1 + 5 files changed, 13 insertions(+) diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index 81013bc0b..943d5a96a 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -6463,6 +6463,9 @@ guess_cfa_pc: xyz[2] = 1 - xyz[0] - xyz[1]; FORC3 xyz[c] /= d65_white[c]; break; + case 50730: /* BaselineExposure */ + if (dng_version) RT_baseline_exposure = getreal(type); + break; case 50740: /* DNGPrivateData */ if (dng_version) break; parse_minolta (j = get4()+base); diff --git a/rtengine/dcraw.h b/rtengine/dcraw.h index e1b296dbf..c3794ea5f 100644 --- a/rtengine/dcraw.h +++ b/rtengine/dcraw.h @@ -58,6 +58,7 @@ public: ,RT_whitelevel_from_constant(ThreeValBool::X) ,RT_blacklevel_from_constant(ThreeValBool::X) ,RT_matrix_from_constant(ThreeValBool::X) + ,RT_baseline_exposure(0) ,getbithuff(this,ifp,zero_after_ff) ,nikbithuff(ifp) { @@ -154,6 +155,7 @@ protected: ThreeValBool RT_blacklevel_from_constant; ThreeValBool RT_matrix_from_constant; std::string RT_software; + double RT_baseline_exposure; float cam_mul[4], pre_mul[4], cmatrix[3][4], rgb_cam[3][4]; diff --git a/rtengine/rawimage.h b/rtengine/rawimage.h index 7595ad196..f6b8190e4 100644 --- a/rtengine/rawimage.h +++ b/rtengine/rawimage.h @@ -125,6 +125,8 @@ public: float** data; // holds pixel values, data[i][j] corresponds to the ith row and jth column unsigned prefilters; // original filters saved ( used for 4 color processing ) unsigned int getFrameCount() const { return is_raw; } + + double getBaselineExposure() const { return RT_baseline_exposure; } protected: Glib::ustring filename; // complete filename int rotate_deg; // 0,90,180,270 degree of rotation: info taken by dcraw from exif diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 502da8073..c917ac179 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -716,6 +716,11 @@ void RawImageSource::getImage (const ColorTemp &ctemp, int tran, Imagefloat* ima gm /= area; bm /= area; bool doHr = (hrp.hrenabled && hrp.method != "Color"); + const float expcomp = std::pow(2, ri->getBaselineExposure()); + rm *= expcomp; + gm *= expcomp; + bm *= expcomp; + #ifdef _OPENMP #pragma omp parallel if(!d1x) // omp disabled for D1x to avoid race conditions (see Issue 1088 http://code.google.com/p/rawtherapee/issues/detail?id=1088) { diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index afd8836a1..dd8ca4a99 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -567,6 +567,7 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati tpp->camwbBlue = tpp->blueMultiplier / pre_mul[2]; //ri->get_pre_mul(2); //tpp->defGain = 1.0 / min(ri->get_pre_mul(0), ri->get_pre_mul(1), ri->get_pre_mul(2)); tpp->defGain = max (scale_mul[0], scale_mul[1], scale_mul[2], scale_mul[3]) / min (scale_mul[0], scale_mul[1], scale_mul[2], scale_mul[3]); + tpp->defGain *= std::pow(2, ri->getBaselineExposure()); tpp->gammaCorrected = true; From 6877360913801c2810d1050b1ef841a8f8cdfbb3 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Tue, 30 Oct 2018 14:36:56 +0100 Subject: [PATCH 5/7] DNG: use embedded black and white levels also from files generated by Adobe We only override the colour matrix for Adobe DNG Converter (to ensure a consistent look between dng an native raw) --- rtengine/dcraw.cc | 31 ++++++++++++++++++++++++++----- rtengine/rawimage.cc | 30 +++++++++++++++--------------- 2 files changed, 41 insertions(+), 20 deletions(-) diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index 943d5a96a..d0a267121 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -6409,6 +6409,7 @@ guess_cfa_pc: case 61450: cblack[4] = cblack[5] = MIN(sqrt(len),64); case 50714: /* BlackLevel */ + RT_blacklevel_from_constant = ThreeValBool::F; if(cblack[4] * cblack[5] == 0) { int dblack[] = { 0,0,0,0 }; black = getreal(type); @@ -6423,7 +6424,6 @@ guess_cfa_pc: cblack[6+c] = getreal(type); } black = 0; - RT_blacklevel_from_constant = ThreeValBool::F; break; case 50715: /* BlackLevelDeltaH */ case 50716: /* BlackLevelDeltaV */ @@ -8632,11 +8632,31 @@ void CLASS adobe_coeff (const char *make, const char *model) int i, j; sprintf (name, "%s %s", make, model); + + + // -- RT -------------------------------------------------------------------- + const bool is_pentax_dng = dng_version && !strncmp(RT_software.c_str(), "PENTAX", 6); + // indicate that DCRAW wants these from constants (rather than having loaded these from RAW file + // note: this is simplified so far, in some cases dcraw calls this when it has say the black level + // from file, but then we will not provide any black level in the tables. This case is mainly just + // to avoid loading table values if we have loaded a DNG conversion of a raw file (which already + // have constants stored in the file). + if (RT_whitelevel_from_constant == ThreeValBool::X || is_pentax_dng) { + RT_whitelevel_from_constant = ThreeValBool::T; + } + if (RT_blacklevel_from_constant == ThreeValBool::X || is_pentax_dng) { + RT_blacklevel_from_constant = ThreeValBool::T; + } + if (RT_matrix_from_constant == ThreeValBool::X) { + RT_matrix_from_constant = ThreeValBool::T; + } + // -- RT -------------------------------------------------------------------- + for (i=0; i < sizeof table / sizeof *table; i++) if (!strncmp (name, table[i].prefix, strlen(table[i].prefix))) { - if (table[i].black) black = (ushort) table[i].black; - if (table[i].maximum) maximum = (ushort) table[i].maximum; - if (table[i].trans[0]) { + if (RT_blacklevel_from_constant == ThreeValBool::T && table[i].black) black = (ushort) table[i].black; + if (RT_whitelevel_from_constant == ThreeValBool::T && table[i].maximum) maximum = (ushort) table[i].maximum; + if (RT_matrix_from_constant == ThreeValBool::T && table[i].trans[0]) { for (raw_color = j=0; j < 12; j++) ((double *)cam_xyz)[j] = table[i].trans[j] / 10000.0; cam_xyz_coeff (rgb_cam, cam_xyz); @@ -10082,7 +10102,8 @@ dng_skip: * DNG-converted and original raw * files. See #4129 */) { memcpy (rgb_cam, cmatrix, sizeof cmatrix); - raw_color = 0; +// raw_color = 0; + RT_matrix_from_constant = ThreeValBool::F; } if(!strncmp(make, "Panasonic", 9) && !strncmp(model, "DMC-LX100",9)) adobe_coeff (make, model); diff --git a/rtengine/rawimage.cc b/rtengine/rawimage.cc index 131b04156..2fd4d7dc8 100644 --- a/rtengine/rawimage.cc +++ b/rtengine/rawimage.cc @@ -1060,20 +1060,20 @@ DCraw::dcraw_coeff_overrides(const char make[], const char model[], const int is } memset(trans, 0, sizeof(*trans) * 12); - // indicate that DCRAW wants these from constants (rather than having loaded these from RAW file - // note: this is simplified so far, in some cases dcraw calls this when it has say the black level - // from file, but then we will not provide any black level in the tables. This case is mainly just - // to avoid loading table values if we have loaded a DNG conversion of a raw file (which already - // have constants stored in the file). - if (RT_whitelevel_from_constant == ThreeValBool::X || is_pentax_dng) { - RT_whitelevel_from_constant = ThreeValBool::T; - } - if (RT_blacklevel_from_constant == ThreeValBool::X || is_pentax_dng) { - RT_blacklevel_from_constant = ThreeValBool::T; - } - if (RT_matrix_from_constant == ThreeValBool::X) { - RT_matrix_from_constant = ThreeValBool::T; - } + // // indicate that DCRAW wants these from constants (rather than having loaded these from RAW file + // // note: this is simplified so far, in some cases dcraw calls this when it has say the black level + // // from file, but then we will not provide any black level in the tables. This case is mainly just + // // to avoid loading table values if we have loaded a DNG conversion of a raw file (which already + // // have constants stored in the file). + // if (RT_whitelevel_from_constant == ThreeValBool::X || is_pentax_dng) { + // RT_whitelevel_from_constant = ThreeValBool::T; + // } + // if (RT_blacklevel_from_constant == ThreeValBool::X || is_pentax_dng) { + // RT_blacklevel_from_constant = ThreeValBool::T; + // } + // if (RT_matrix_from_constant == ThreeValBool::X) { + // RT_matrix_from_constant = ThreeValBool::T; + // } { // test if we have any information in the camera constants store, if so we take that. @@ -1088,7 +1088,7 @@ DCraw::dcraw_coeff_overrides(const char make[], const char model[], const int is *white_level = cc->get_WhiteLevel(0, iso_speed, aperture); } - if (cc->has_dcrawMatrix()) { + if (RT_matrix_from_constant == ThreeValBool::T && cc->has_dcrawMatrix()) { const short *mx = cc->get_dcrawMatrix(); for (int j = 0; j < 12; j++) { From e0b4f85e097c2aaa0a9d47edec8ebb264ffc3f00 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Mon, 19 Nov 2018 09:29:21 +0100 Subject: [PATCH 6/7] DNG: protect from ill-formed BaselineExposure values --- rtengine/dcraw.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index 6ee426d63..5e89d7614 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -6523,7 +6523,12 @@ guess_cfa_pc: FORC3 xyz[c] /= d65_white[c]; break; case 50730: /* BaselineExposure */ - if (dng_version) RT_baseline_exposure = getreal(type); + if (dng_version) { + double be = getreal(type); + if (!std::isnan(be)) { + RT_baseline_exposure = be; + } + } break; case 50740: /* DNGPrivateData */ if (dng_version) break; From ac21918094f1534b6bf7de510f2b50acd7feffea Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Tue, 20 Nov 2018 13:37:23 +0100 Subject: [PATCH 7/7] DNG: apply the BaselineExposure tag only for float DNGs --- rtengine/rawimage.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rtengine/rawimage.cc b/rtengine/rawimage.cc index 2fd4d7dc8..ec2f0b78e 100644 --- a/rtengine/rawimage.cc +++ b/rtengine/rawimage.cc @@ -503,6 +503,10 @@ int RawImage::loadRaw (bool loadData, unsigned int imageNum, bool closeFile, Pro fseek (ifp, data_offset, SEEK_SET); (this->*load_raw)(); + if (!float_raw_image) { // apply baseline exposure only for float DNGs + RT_baseline_exposure = 0; + } + if (plistener) { plistener->setProgress(0.9 * progressRange); }