dcraw: use the right black levels for linear DNGs (#6444)

Linear dng (like the one created by Adobe DNG Converter) contains
multiple tiff subifd with different kind of images (the Primary Image
and multiple previews), these defines different kind of black levels.

Currently dcraw has a global cblack array that is overwritten by the
last parsed tiff ifd. With such kind of linear dng it's the last subifd.
The causes the use of the wrong black levels with the image having
usually a magenta color cast.

The dng spec uses the NewSubFileType tag to define the primary image
with tag value as 0.
This patch reads also the NewSubFileType tag and populates the cblack
array provided by the other tags only if it's the primary image.
This commit is contained in:
Simone Gotti 2022-03-26 11:28:05 +01:00 committed by GitHub
parent 5502f52f90
commit bd118a4a40
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 7 additions and 1 deletions

View File

@ -6404,6 +6404,9 @@ int CLASS parse_tiff_ifd (int base)
case 3: case 257: case 61442: /* ImageHeight */ case 3: case 257: case 61442: /* ImageHeight */
tiff_ifd[ifd].height = getint(type); tiff_ifd[ifd].height = getint(type);
break; break;
case 254:
tiff_ifd[ifd].new_sub_file_type = getint(type);
break;
case 258: /* BitsPerSample */ case 258: /* BitsPerSample */
case 61443: case 61443:
tiff_ifd[ifd].samples = len & 7; tiff_ifd[ifd].samples = len & 7;
@ -6737,14 +6740,17 @@ guess_cfa_pc:
linear_table (len); linear_table (len);
break; break;
case 50713: /* BlackLevelRepeatDim */ case 50713: /* BlackLevelRepeatDim */
if (tiff_ifd[ifd].new_sub_file_type != 0) continue;
cblack[4] = get2(); cblack[4] = get2();
cblack[5] = get2(); cblack[5] = get2();
if (cblack[4] * cblack[5] > sizeof cblack / sizeof *cblack - 6) if (cblack[4] * cblack[5] > sizeof cblack / sizeof *cblack - 6)
cblack[4] = cblack[5] = 1; cblack[4] = cblack[5] = 1;
break; break;
case 61450: case 61450:
if (tiff_ifd[ifd].new_sub_file_type != 0) continue;
cblack[4] = cblack[5] = MIN(sqrt(len),64); cblack[4] = cblack[5] = MIN(sqrt(len),64);
case 50714: /* BlackLevel */ case 50714: /* BlackLevel */
if (tiff_ifd[ifd].new_sub_file_type != 0) continue;
RT_blacklevel_from_constant = ThreeValBool::F; RT_blacklevel_from_constant = ThreeValBool::F;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// taken from LibRaw. // taken from LibRaw.

View File

@ -209,7 +209,7 @@ protected:
} first_decode[2048], *second_decode, *free_decode; } first_decode[2048], *second_decode, *free_decode;
struct tiff_ifd { struct tiff_ifd {
int width, height, bps, comp, phint, offset, flip, samples, bytes; int new_sub_file_type, width, height, bps, comp, phint, offset, flip, samples, bytes;
int tile_width, tile_length, sample_format, predictor; int tile_width, tile_length, sample_format, predictor;
float shutter; float shutter;
} tiff_ifd[10]; } tiff_ifd[10];