Preserve user and application XMP metadata across encodes (JPEG/HEIC/AVIF)
- Dominant language
- C++
- Stars
- 344
- Forks
- 67
- Avg merge
- 15d 2h
- Merged PRs (30d)
- 7
Description
### 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
1. **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.
2. **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.
3. **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 `` document, handling Extended XMP segmentation if the combined packet exceeds the 64KB JPEG segment limit.
Contributor guide
Research direction
Start with ultrahdr_api.h and the JPEG, HEIC, and AVIF entry points named in jpegr.cpp, heifultrahdr.cpp, and avifultrahdr.cpp. Trace existing EXIF and ICC passthrough paths, then define completion around raw XMP setter/getter APIs, preservation across JPEG encodes, and attachment and extraction for HEIC and AVIF, including the proposed extended-XMP case.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- api, computer-graphics
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100