Skip to content

Commit 9f3e757

Browse files
authored
Merge pull request #20898 from andriiryzhkov/dng_tag_fix
[AI] Fix raw denoise output corrupted DNG / process crash on some libtiff builds
2 parents 3b42f13 + d5af7b6 commit 9f3e757

1 file changed

Lines changed: 44 additions & 5 deletions

File tree

src/imageio/imageio_dng.c

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,38 @@
3939
// these as float/double arrays and handles the conversion; we just pass
4040
// the values as double
4141

42+
// libtiff error/warning handlers — replacing whatever else in the
43+
// process may have installed (e.g. ImageMagick's, which crashes on
44+
// NULL exception context). these just log to stderr and never abort
45+
static void _dt_dng_tiff_warning(const char *module,
46+
const char *fmt, va_list ap)
47+
{
48+
if(darktable.unmuted & DT_DEBUG_IMAGEIO)
49+
{
50+
fprintf(stderr, "%11.4f [imageio_dng] warning: %s: ",
51+
dt_get_wtime() - darktable.start_wtime,
52+
module ? module : "(none)");
53+
vfprintf(stderr, fmt, ap);
54+
fprintf(stderr, "\n");
55+
}
56+
}
57+
58+
static void _dt_dng_tiff_error(const char *module,
59+
const char *fmt, va_list ap)
60+
{
61+
fprintf(stderr, "%11.4f [imageio_dng] error: %s: ",
62+
dt_get_wtime() - darktable.start_wtime,
63+
module ? module : "(none)");
64+
vfprintf(stderr, fmt, ap);
65+
fprintf(stderr, "\n");
66+
}
67+
68+
static void _install_dng_tiff_handlers(void)
69+
{
70+
TIFFSetWarningHandler(_dt_dng_tiff_warning);
71+
TIFFSetErrorHandler(_dt_dng_tiff_error);
72+
}
73+
4274
// map the dcraw 2x2 CFA filters word to 4 single-byte channel indices
4375
// for the DNG CFAPattern tag: 0=R, 1=G, 2=B, following DNG spec §A.3.1
4476
static void _cfa_bytes_from_filters(uint32_t filters, uint8_t out[4])
@@ -160,6 +192,8 @@ int dt_imageio_dng_write_cfa_bayer(const char *filename,
160192
if(!filename || !cfa || !img || width <= 0 || height <= 0)
161193
return 1;
162194

195+
_install_dng_tiff_handlers();
196+
163197
#ifdef _WIN32
164198
wchar_t *wfilename = g_utf8_to_utf16(filename, -1, NULL, NULL, NULL);
165199
TIFF *tif = TIFFOpenW(wfilename, "wl");
@@ -184,10 +218,11 @@ int dt_imageio_dng_write_cfa_bayer(const char *filename,
184218
g_unlink(filename);
185219
return 1;
186220
}
187-
// libtiff entered INSUBIFD mode when the IFD0 carrying TIFFTAG_SUBIFD
188-
// was written; subsequent TIFFSetField + scanline writes populate
189-
// the SubIFD without an explicit TIFFCreateDirectory call (whose
190-
// return-value convention changed between libtiff versions)
221+
// re-register default tag info on some libtiff builds CFA/DNG
222+
// extension tags would be lost across the IFD write, breaking
223+
// CFAREPEATPATTERNDIM / CFAPATTERN. return value differs across
224+
// libtiff versions; not checked
225+
TIFFCreateDirectory(tif);
191226
}
192227

193228
// raw payload IFD: single IFD when no preview, otherwise SubIFD0
@@ -299,6 +334,8 @@ int dt_imageio_dng_write_linear(const char *filename,
299334
if(!filename || !rgb || !img || width <= 0 || height <= 0)
300335
return 1;
301336

337+
_install_dng_tiff_handlers();
338+
302339
#ifdef _WIN32
303340
wchar_t *wfilename = g_utf8_to_utf16(filename, -1, NULL, NULL, NULL);
304341
TIFF *tif = TIFFOpenW(wfilename, "wl");
@@ -321,7 +358,9 @@ int dt_imageio_dng_write_linear(const char *filename,
321358
g_unlink(filename);
322359
return 1;
323360
}
324-
// libtiff is in INSUBIFD mode after IFD0 was written with TIFFTAG_SUBIFD
361+
// re-initialize directory state so DNG extension tag info is
362+
// available on the SubIFD (see comment in write_cfa_bayer)
363+
TIFFCreateDirectory(tif);
325364
}
326365

327366
// baseline TIFF tags, 3 samples per pixel (demosaicked)

0 commit comments

Comments
 (0)