UltraHDR (gain-map JPEG) HDR export via libultrahdr#21458
Draft
MaykThewessen wants to merge 1 commit into
Draft
Conversation
New optional imageio format module exporting ISO 21496-1 gain-map JPEGs (Google UltraHDR) through libultrahdr's API-0 single-input encode path. The module receives darktable's interleaved float32 RGBA buffer (bpp 32). It requires a PQ output color profile (PQ Rec2020 or PQ P3): colorout has then already baked the SMPTE ST 2084 curve into the samples, so the floats are PQ-encoded and normalized to [0, 1]. They are packed to RGBA1010102 and handed to libultrahdr as UHDR_CT_PQ with the matching color gamut (UHDR_CG_BT_2100 for Rec2020, UHDR_CG_DISPLAY_P3 for P3). Any non-PQ profile logs a clear error and fails the export. With only the HDR rendition fed (API-0), libultrahdr internally tone-maps to an SDR base, computes the gain map, and muxes the base JPEG, the ISO 21496-1 gain map, and the MPF container. The GUI exposes base quality, gain map quality, and gain map resolution (full/half/quarter) sliders, round-tripped through plugins/imageio/format/ultrahdr/* conf keys (declared in darktableconfig.xml.in with defaults 95/95/full). Build support is optional and gated on libuhdr being present via pkg-config (USE_ULTRAHDR, default ON): when libuhdr is absent the module is simply not built, so the rest of darktable is unaffected. The cache flag is reset on every configure so toggling USE_ULTRAHDR off (or libuhdr disappearing) cannot leave a stale module target.
Member
|
darktable can write ultrahdr images using the lua-script ultrahdr. I have no idea how much use the script gets, so I don't know how much interest there is. |
Collaborator
Good. So let's stay with the lua addition i would think |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds an optional imageio format module that exports UltraHDR / ISO 21496-1 gain-map JPEGs (Google's UltraHDR) through Google's
libultrahdr. This is the one common HDR still-image format darktable cannot yet write; gain-map JPEGs render as HDR in Chrome and on Android, and (see the macOS note below) on Apple platforms too when libultrahdr is built to dual-encode, while degrading gracefully to the SDR base on viewers that ignore the gain map.How
src/imageio/format/ultrahdr.c(modeled onavif.c), using libultrahdr's API-0 single-input encode path: only the HDR rendition is fed, and the library tone-maps the SDR base, computes the gain map, and muxes the base JPEG + gain map + MPF container itself.bpp32). It requires a PQ output color profile (PQ Rec2020 or PQ P3):colorouthas then already baked the SMPTE ST 2084 curve into the samples, so the floats are PQ-encoded and normalized to [0, 1]. They are packed toUHDR_IMG_FMT_32bppRGBA1010102and taggedUHDR_CT_PQwith the matching gamut (UHDR_CG_BT_2100for Rec2020,UHDR_CG_DISPLAY_P3for P3). Any non-PQ profile logs a clear error and fails the export.darktableconfig.xml.in(defaults 95/95/full).Build / optionality
libuhdrvia pkg-config (USE_ULTRAHDR, default ON). NOTE: the pkg-config and link name islibuhdr, notlibultrahdr.libuhdris absent the module is simply not built, so the rest of darktable is unaffected. The cache flag is reset on every configure so togglingUSE_ULTRAHDRoff (orlibuhdrdisappearing) cannot leave a stale module target.Status
Draft. Compiles and links
libuhdr(1.4.0). Output is standards-conformant (verified withultrahdr_app -m 1and ImageMagick: a 2-image MPF container with an SDR base + ISO 21496-1 gain map) and renders as HDR in Chrome. Open items:UHDR_WRITE_XMP=OFF, ISO-21496-1 only, which is what current Homebrew ships), Apple's ImageIO cannot decode the file at all:CGImageSourceCreateImageAtIndexreturns nil and Preview/Photos/Quick Look/Safari fail to open it. Root cause: in that mode libultrahdr embeds a ~30 KB Lab/CICP ICC profile in the gain-map sub-image that Apple's MPF parser rejects (it aborts the whole file rather than falling back to the primary). Building libultrahdr withUHDR_WRITE_XMP=ON(dual hdrgm-XMP + ISO, the same combination Android 15 and Apple's own camera write) fixes it: the identical darktable export then both decodes and renders as true HDR on macOS (independently verified at ~5.6 stops of headroom for a 0-4000 nit test pattern). The XMP flag both drops the offending gain-map ICC and adds the gain-map XMP Apple keys on (see libultrahdrlib/src/jpegr.cppcompressGainMap). No darktable code change is needed, the PQ RGBA1010102 packing is already correct; this is a libultrahdr packaging matter. When only the default ISO-only libultrahdr is available, darktable's AVIF/HEIF PQ exports remain the Apple-native HDR path.jpgextension, sodarktable-cliselection by extension picks the core JPEG format; the GUI export dropdown selects "UltraHDR JPEG" explicitly. Happy to take guidance on the preferred disambiguation (a distinct extension, or a format selector).UHDR_CT_LINEARfrom a Linear Rec2020 export) could be offered as a higher-fidelity alternative to the 10-bit PQ pack; deferred for now.Related HDR work
Part of a small HDR series: #21357 (AVIF HDR10 CLLI), #21365 (HEIF HDR10 CLLI), #21358 (optional external EDR darkroom viewer).
🤖 Generated with Claude Code