Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 44 additions & 5 deletions src/imageio/imageio_dng.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,38 @@
// these as float/double arrays and handles the conversion; we just pass
// the values as double

// libtiff error/warning handlers — replacing whatever else in the
// process may have installed (e.g. ImageMagick's, which crashes on
// NULL exception context). these just log to stderr and never abort
static void _dt_dng_tiff_warning(const char *module,
const char *fmt, va_list ap)
{
if(darktable.unmuted & DT_DEBUG_IMAGEIO)
{
fprintf(stderr, "%11.4f [imageio_dng] warning: %s: ",
dt_get_wtime() - darktable.start_wtime,
module ? module : "(none)");
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
}
}

static void _dt_dng_tiff_error(const char *module,
const char *fmt, va_list ap)
{
fprintf(stderr, "%11.4f [imageio_dng] error: %s: ",
dt_get_wtime() - darktable.start_wtime,
module ? module : "(none)");
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
}

static void _install_dng_tiff_handlers(void)
{
TIFFSetWarningHandler(_dt_dng_tiff_warning);
TIFFSetErrorHandler(_dt_dng_tiff_error);
}

// map the dcraw 2x2 CFA filters word to 4 single-byte channel indices
// for the DNG CFAPattern tag: 0=R, 1=G, 2=B, following DNG spec §A.3.1
static void _cfa_bytes_from_filters(uint32_t filters, uint8_t out[4])
Expand Down Expand Up @@ -160,6 +192,8 @@ int dt_imageio_dng_write_cfa_bayer(const char *filename,
if(!filename || !cfa || !img || width <= 0 || height <= 0)
return 1;

_install_dng_tiff_handlers();

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

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

_install_dng_tiff_handlers();

#ifdef _WIN32
wchar_t *wfilename = g_utf8_to_utf16(filename, -1, NULL, NULL, NULL);
TIFF *tif = TIFFOpenW(wfilename, "wl");
Expand All @@ -321,7 +358,9 @@ int dt_imageio_dng_write_linear(const char *filename,
g_unlink(filename);
return 1;
}
// libtiff is in INSUBIFD mode after IFD0 was written with TIFFTAG_SUBIFD
// re-initialize directory state so DNG extension tag info is
// available on the SubIFD (see comment in write_cfa_bayer)
TIFFCreateDirectory(tif);
}

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