Feature Description
Currently, libultrahdr provides public APIs and passthrough logic for EXIF (uhdr_enc_set_exif_data, uhdr_dec_get_exif) and ICC profiles (uhdr_dec_get_icc), but does not preserve or expose general user/application XMP metadata across encode and transcode pipelines.
In professional photography workflows (e.g., Adobe Lightroom, Camera Raw, Photoshop, Lumenzia), source images frequently carry rich XMP metadata packets containing:
- Copyright and author attribution (Dublin Core)
- Non-destructive develop settings (
crs: adjustments, tone curves, masks, color grading)
- Asset management tags (ratings, color labels, keywords, GPS tags)
Current Behavior
- JPEG (
jpegr.cpp): When reordering base JPEG markers in appendGainMap, all APP markers (0xE0–0xEF) from the base JPEG are skipped, silently stripping existing APP1 XMP packets. If kWriteXmpMetadata is enabled, a brand-new XMP packet is synthesized containing only the UltraHDR container directory (Container:Directory), wiping out original user XMP.
- HEIC & AVIF (
heifultrahdr.cpp, avifultrahdr.cpp): Only EXIF metadata is added to the primary image handle; XMP is neither written during encoding nor extracted during decoding.
- API:
ultrahdr_api.h lacks setter/getter APIs for raw XMP blocks (e.g., uhdr_enc_set_xmp_data / uhdr_dec_get_xmp).
Proposed Solution
- Public API:
- Add
uhdr_enc_set_xmp_data(uhdr_codec_private_t* enc, uhdr_mem_block_t* xmp)
- Add
uhdr_dec_get_xmp(uhdr_codec_private_t* dec)
- Expose corresponding flags in
ultrahdr_app CLI.
- HEIC / AVIF Support:
- In
HeifUltraHdr and AvifUltraHdr, attach user XMP via libheif (heif_context_add_xmp_metadata) and extract via heif_image_handle_get_list_of_metadata_block_IDs. Because gain maps in HEIC/AVIF use ISO 21496-1 tmap items, no XML manipulation is required.
- JPEG Support:
- ISO 21496-1 Mode: Preserve the existing
APP1 XMP marker untouched when writing ISO gain map metadata in APP2.
- XMP / Dual Mode: Merge the UltraHDR container RDF tags into the existing XMP
<x:xmpmeta> document, handling Extended XMP segmentation if the combined packet exceeds the 64KB JPEG segment limit.
Feature Description
Currently,
libultrahdrprovides public APIs and passthrough logic for EXIF (uhdr_enc_set_exif_data,uhdr_dec_get_exif) and ICC profiles (uhdr_dec_get_icc), but does not preserve or expose general user/application XMP metadata across encode and transcode pipelines.In professional photography workflows (e.g., Adobe Lightroom, Camera Raw, Photoshop, Lumenzia), source images frequently carry rich XMP metadata packets containing:
crs:adjustments, tone curves, masks, color grading)Current Behavior
jpegr.cpp): When reordering base JPEG markers inappendGainMap, all APP markers (0xE0–0xEF) from the base JPEG are skipped, silently stripping existingAPP1XMP packets. IfkWriteXmpMetadatais enabled, a brand-new XMP packet is synthesized containing only the UltraHDR container directory (Container:Directory), wiping out original user XMP.heifultrahdr.cpp,avifultrahdr.cpp): Only EXIF metadata is added to the primary image handle; XMP is neither written during encoding nor extracted during decoding.ultrahdr_api.hlacks setter/getter APIs for raw XMP blocks (e.g.,uhdr_enc_set_xmp_data/uhdr_dec_get_xmp).Proposed Solution
uhdr_enc_set_xmp_data(uhdr_codec_private_t* enc, uhdr_mem_block_t* xmp)uhdr_dec_get_xmp(uhdr_codec_private_t* dec)ultrahdr_appCLI.HeifUltraHdrandAvifUltraHdr, attach user XMP vialibheif(heif_context_add_xmp_metadata) and extract viaheif_image_handle_get_list_of_metadata_block_IDs. Because gain maps in HEIC/AVIF use ISO 21496-1tmapitems, no XML manipulation is required.APP1XMP marker untouched when writing ISO gain map metadata inAPP2.<x:xmpmeta>document, handling Extended XMP segmentation if the combined packet exceeds the 64KB JPEG segment limit.