DNG: use black/white levels and matrix from the file, unless it comes from the Adobe DNG Converter

See #4472
This commit is contained in:
Alberto Griggio 2018-10-24 12:03:15 +02:00
parent 19cc60a623
commit 4fbb0cd3eb
3 changed files with 54 additions and 28 deletions

View File

@ -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;
}

View File

@ -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];

View File

@ -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];