add support for encoding/decoding ultrahdr images#7198
Conversation
Steps to build imagemagick with ultrahdr: git clone https://github.com/google/libultrahdr.git cd libultrahdr && mkdir build && cd build cmake -G "Unix Makefiles" ../ make git clone https://github.com/ImageMagick/ImageMagick.git cd ImageMagick && mkdir build && cd build mkdir uhdr cp ../../libuhdr.a ../../../ultrahdr_api.h ./uhdr cd .. && automake && autoconf && autoheader cd build && ../configure --enable-delegate-build=yes --with-uhdr make Change-Id: Id745d838ffc950d2a8ca158462271b9596d482c6
|
@aayushsoni111 could you provide guidance on an example ImageMagick command which could be used to take an SDR (JPG perhaps) and an HDR source image (10-bit AVIF perhaps) and encode them into a gain map JPG? |
|
@aayushsoni111 In the above build instructions at At the last step Any suggestions on what needs to be done here? |
|
Thank you for your contribution. We had set aside this weekend to work on integrating the Ultra HDR delegate library. However, it seems that won't be necessary anymore. Instead, we'll focus on thoroughly testing your patch to ensure its robustness and security. |
|
Thanks All, there's still bit of work to do , team will note the open items here. |
|
@gregbenz -> this will select only the primary sdr image to be written to heic For Encode, |
|
@gregbenz Basing on the error you are seeing, I think the some relative dir paths got mangled up. |
|
@urban-warrior while testing uhdr.c, during to transcode to heic.c, I noticed a crash that was happening due to a problem in function WriteHEICImageRRGGBBAA, heic.c. If alpha channel is present, I noticed an out of bound access. |
|
@urban-warrior https://docs.google.com/document/d/15dF92ofGfSerekwN-fAcGxYpwBkq9aCzhJZxmXoN4dE/edit?usp=sharing has some notes on the libultrahdr integration in ImageMagick. This document has a list of todo tasks and also details on what is tested so far. |
|
@ram-mohan Any idea what might be missing? I added a couple of line breaks to the build commands at the top of this page. Below is the code I used in MacOS Terminal with comments on results and the working directory at each stage. Every step until the last one produces what seems like a reasonable response (as far as I can tell). Do you see any place where the path seems incorrect?
======
|
|
@gregbenz ../configure --enable-delegate-build=yes --with-uhdr && make |
|
@gregbenz just wanted to check if the build issue has resolved? |
|
@ram-mohan Ah, thanks! That missing line break was my problem. I'm seeing the output and However, when I use the command to encode, the output is 2 standard JPG images, neither with an auxiliary image or gain map metadata. One is the SDR, and the other looks like an improperly encoded HDR, not a gain map. I'm not clear if the failure here is related to the type of source material I'm providing, my conversion commands, or something else. Any suggestions?
|
|
@gregbenz can you please share the input images. I can try from my side once. |
|
We've implemented several patches to enhance support for UHDR in ImageMagick. Currently, we've removed the UHDR calls from JPEG since they wouldn't function properly anyway, and we don't advocate direct calls from one coder to another. Instead, for any UHDR disguised as JPEG, use This version maintains clarity while improving readability and coherence. As expected, there is still work to do. We will evolve UHDR support over time. |
|
@urban-warrior Thank you for further changes for the uhdr integration. We will continue to work on the TODO items listed in the doc above. |
|
We require a dynamic build of libutltrahdr (.so) and support for The header files should be copied to |
|
Sure. We will work towards updating libultrahdr to support dynamic library and to install in standard locations. |
|
hi guys, i follow the ''Steps to build imagemagick with ultrahdr'' however i found some strange problem that when i try and when i try when i try any possible solution? |
|
If you built from source code, you will need to install all the delegates that you need prior to installing Imagemagick. You cannot just use --with--XYZ. That only enables it if you already have it installed. However, that is not usually necessary if you install your delegates and be sure that they are in your $PATH. Please always identify your IM version and platform/OS. It looks like you are on a Mac using arch64 platform. You can install delegates with either Homebrew or MacPorts, then install Imagemagick from source. |
|
@GrousexyHKCN error message, "expects one of {UHDR_CR_FULL_RANGE, UHDR_CR_LIMITED_RANGE}" is due to missing initialization in uhdr.c. This was not a problem a while back but as more changes were pushed to libultrahdr this error is seen. We will issue a pull request that resolves this. thank you |
Thanks for your reply! |
|
You may have to point IM to where Homebrew installed your delegates in your config command. This is what I had used before when installing using MacPorts. Add this to your .configuration command and change the directory to where Homebrew installs. CPPFLAGS='-I/opt/local/include' LDFLAGS='-L/opt/local/lib' \ Also be sure your path the your jpeg and libtiff (and any other delegates) are in your $PATH. |
assuming libjpeg is already installed, below steps should workfirst install libultrahdrgit clone https://github.com/google/libultrahdr.git && cd libultrahdr && mkdir build && cd build clone image magick and configure with uhdr enabledgit clone https://github.com/ImageMagick/ImageMagick.git && cd ImageMagick && mkdir build && cd build |
|
In case others get stuck on Homebrew on macOS building it: It failed for with a conflict between two libjpeg versions in libultrahdr and ImageMagick. Solved with this to point it to libjpeg-turbo instead of libjpeg, all in one line: Example command to create an UltraHDR JPEG: If you see two images as output, like ultrahdr-0.jpg and ultrahdr-1.jpg, then your magick wasn't really built with this new uhdr support. Above example uses bt709 as that's almost sRGB which my input HDR was. Most recent update to this was last week: #7635 |
|
libultra is working extremely well these days. It would be ideal if IM would use the library by default when transcoding (crop/compress/resize) from a support JPG gain map source image and not explicitly requesting a different output (something other than JPG, or deliberate conversion to SDR only or HDR only). Preserving the gain map by default should help support propagate without requiring updates from downstream users of IM. To support this, I'm assuming IM would need to test that an image has a gain map and then use libultra or the standard JPG library as appropriate. Libultra has a function which can test the source image: google/libultrahdr#137 (reply in thread) @urban-warrior, I would love to hear your thoughts on moving in this direction to allow JPG gain maps to be supported by default (preserved) when working with a gain map input. Do you agree that is the right direction, and do you believe we are at a state where testing default support in IM would make sense? |
|
By default '.jpg' or '.jpeg' would produce standard JPEG images. With a define, we can optionally write UHDR images if the gain map is present otherwise standard JPEG. For Linux, its up to the RPM package maintainers to include UHDR support. For Windows, @dlemstra, can we include support for UHDR images in future builds? If so, what would be the approximate ETA? |
|
The -define also as the advantage that stepwise further support can be added for other IM functions. Most will most likely currently just drop the gainmap when writing their output but it can be added individually then later to some functions to consider the gainmap to process. |
|
There is one api we would like to add to uhdr.c. link. This is introduced in android 15. we are currently working on it. will issue a pull request once this done. |
The ETA depends on how easy it would be to add this library as a dependency. Adding this is not high on my priority list so I don't know when I will start on adding this extra dependency. |
|
@ram-mohan Does the IM integration already include flags which would allow control of parameters relevant to cropping, Is there a set of default quality parameters if they are not provided? |
The list of options supported by uhdr plugin is listed here, https://github.com/ImageMagick/Website/pull/107/commits. Further cropping, resizing, ... other IM features/options should work as usual. |
libultrahdr is not yet packaged for a lot of distros (e.g. Debian and Fedora to begin with as largest bases for other derivatives), and for Windows it is only available via MSYS2, not vcpkg... No macOS presence either ATM (Homebrew nor MacPorts). So anyone interested should start requesting it through the appropriate channels. |
|
we have made some progress towards building packages. google/libultrahdr@202e5c3 For homebrew, Homebrew/homebrew-core@master...ram-mohan:homebrew-core:uhdr |
|
I'll try out the homebrew uhdr and reply in github if feedback is needed
there.
…On Mon, Oct 28, 2024 at 6:24 AM ram ***@***.***> wrote:
we have made some progress towards building packages. google/libultrahdr@
202e5c3
<google/libultrahdr@202e5c3>
For homebrew, ***@***.***:homebrew-core:uhdr
<Homebrew/homebrew-core@master...ram-mohan:homebrew-core:uhdr>
—
Reply to this email directly, view it on GitHub
<#7198 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AB6732UNHZ43XELL2B6KHA3Z5Y3KDAVCNFSM6AAAAABFJWNPBCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDINBRGU4DEOJTHE>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
|
The homebrew formula works great!
I just verified it by creating a few gainmap-JPEGs which display fine here.
Added comment in google/libultrahdr#89 .
On Mon, Oct 28, 2024 at 11:33 AM Holger Isenberg ***@***.***>
wrote:
… I'll try out the homebrew uhdr and reply in github if feedback is needed
there.
On Mon, Oct 28, 2024 at 6:24 AM ram ***@***.***> wrote:
> we have made some progress towards building packages. google/libultrahdr@
> 202e5c3
> <google/libultrahdr@202e5c3>
>
> For homebrew, Homebrew/homebrew-core@
> master...ram-mohan:homebrew-core:uhdr
> <Homebrew/homebrew-core@master...ram-mohan:homebrew-core:uhdr>
>
> —
> Reply to this email directly, view it on GitHub
> <#7198 (comment)>,
> or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/AB6732UNHZ43XELL2B6KHA3Z5Y3KDAVCNFSM6AAAAABFJWNPBCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDINBRGU4DEOJTHE>
> .
> You are receiving this because you commented.Message ID:
> ***@***.***>
>
|
|
Hello, I would like to ask if there is currently a recommended set of parameters or process to convert HEIC images shot on an iPhone to AVIF format while preserving HDR, specifically the GainMap data. As far as I know, the HDR GainMap implementation for these two formats should be somewhat similar. When I perform a straightforward conversion using 7.1.1-40 HDRI version with the following command, the output image does not display HDR effects when viewed on an iPhone: magick IMG_xxxx.HEIC IMG_xxxx.AVIFIs there a way to ensure that the HDR information is preserved during the conversion? Any guidance or examples would be greatly appreciated. Thank you! |
|
I'm trying to upload a couple of 10-bit HEIC images shot by Nikon Z6 III to Google Photos. AFAIK, the only HDR format it currently supports is JPG with a gain map. Does this conversion already work in the experimental ImageMagick build? |
|
Yes, works for me with the generated JPGs with IM+uhdr in Google Photos. If yours don't work, check out mine generated on my mars20 website linked from my profile. |
|
I'm currently stuck at building ImageMagick on MacOS. I ran For some reason my build can't decode either JPG or HEIC: $ ./utilities/magick identify --verbose ~/Pictures/DSC_0112.HIF
identify: UnableToOpenConfigureFile `delegates.xml' @ warning/configure.c/GetConfigureOptions/722.
identify: NoDecodeDelegateForThisImageFormat `' @ error/constitute.c/ReadImage/746.
identify: NoDecodeDelegateForThisImageFormat `HIF' @ error/constitute.c/ReadImage/746.
$ ./utilities/magick ~/Pictures/DSC_0112.HIF ~/Pictures/DSC_0112.JPG
magick: UnableToOpenConfigureFile `delegates.xml' @ warning/configure.c/GetConfigureOptions/722.
magick: NoDecodeDelegateForThisImageFormat `HIF' @ error/constitute.c/ReadImage/746. |
|
Update: I managed to build ImageMagick with libultrahdr with the help of the google/libultrahdr#89 thread and did my first conversion: Chrome and the MacOS Preview show the result in HDR, but Google Photos falls back to the SDR image. What do I need to do to make Google Photos display the full dynamic range? |
You can confirm any gain map using the Adobe Gain Map Demo app (https://helpx.adobe.com/camera-raw/using/gain-map.html#resources). It is an outstanding resource and very reliable. It will tell you in the far right side of the image is a gain map. If you click ctrl/cmd-I, it will show an overlay and confirm if the encoding is the ISO spec or another spec (Android using IM as that's libultra's default). If the image has dual encoding (ISO plus some XMP spec), it will simply list ISO and not mention the backup (ISO takes priority in any reader supporting it). Libultra supports Android XMP by default and ISO when enabled in a compile flag. I would assume the current implementation of IM doesn't have ISO enabled. I believe that is safe and would be ideal to enable with the current libuotra code base (I have tested a large number of dual-encoded gain map exports from libultra and it has been working very well with the latest versions - support from various browsers/decoders has been robust). It sounds like you have valid output. Once confirmed, that would indicate the issue was in subsequent transcoding after encoding via IM (such as uploading to a service or what it might deliver based on your device/browser). You'd have to work with that service to request HDR gain map support, as that would be outside the scope of IM and this thread. More resources and info: https://gregbenzphotography.com/hdr/#developers |
|
Thanks a lot for the debugging tips. According to Adobe Gain Map Demo my Pixel 9 photos have Adobe / Ultra HDR gain map type, while the Nikon HEIC photos converted by IM have ISO 21496-1. I believe that libultrahdr should be able to generate gain maps in a format that Google Photos understands. @isenberg had some positive results too. |
|
@pallosp libultrahdr supports both of those formats, but only uses the Android XMP spec by default (which shows as "Adobe / Ultra HDR" in the demo app). IM may need to be updated to enable this flag for ISO encoding with the latest libultrahdr. That said, if you aren't seeing Google Photos support the Android spec, it likely isn't supporting any spec in that scenario (Google widely supports their Android encoding, and libultrahdr is created by Google). The only place I can think of where the ISO adds extra value right now is on Apple's latest operating systems, which supports ISO encoding (and their proprietary Apple XMP encoding), but not the Android/Adobe XMP spec. @ram-mohan What are your thoughts here? Would you agree that enabling dual encoding by default in libultrahdr is ok at this time? And if so, what is the best way to enable that for IM's use of libultrahdr? |
|
Last week I noticed how the Adobe Gainmap Demo app on macOS showed my gainmap JPEGs created with IM+libuhdr as ISO-gainmap JPEG. So it looks like current IM has it already enabled by default. |
|
The current default cmake build configuration of libultrahdr enables iso and disables xmp. So brew install libultrahdr will install the built library which has iso enabled and xmp disabled. So applications that do not support iso and support only xmp can have problems viewing the generated image. whether the jpg image generated has xmp or iso metadata is dependent on the uhdr library and not on IM. If only xmp is desired and not iso, then the library has to built with option UHDR_WRITE_XMP enabled and option UHDR_WRITE_ISO disabled, installed. |
|
Thanks a lot guys! You're awesome! I managed to convert a 10-bit HEIF to a Google Photos compatible Ultra HDR JPG. Here's the complete list of steps:
|
|
@pallosp Thank you for sharing all that great detail! FYI that the Adobe Gain Map Demo app will only list ISO encoding if both that and the Ultra encoding (Android XMP) are in the file. So that tool won't mention the backup (Ultra) encoding. You can examine the file manually with something like EXIFTOOL to confirm the XMP when enabling both encodings, but it isn't necessary (it will just work if you turn on both). It would generally be ideal to either encode both ISO + Ultra (most compatible today) or ISO only (as this saves about 2K in file size). Turning off the ISO encoding (ie DUHDR_WRITE_ISO=OFF) will prevent HDR support on Apple devices and generally means a file which is less forward compatible as everything moves towards ISO as the key way of encoding the gain maps. Dual encoding works great everywhere I've tested with the latest libultrahdr (there was an older bug where the map was truncated when dual encoding, but that was resolved over a month ago). I would avoid disabling the ISO encoding. |
|
SGTM. I tested dual gain maps, and updated the list of steps. BTW, is UHDR support in ImageMagick ready to be enabled by default? Does it need further testing or documentation? |
|
the reason the library defaults to iso over xmp because, current xmp implementation of the library does not support signalling multi channel gainmap metadata. So if xmp is enabled, in multi channel gainmap encoding, gainmap images contains 3 channels but the metadata is same for all of them. For signalling multi channel gainmap metadata, there by preserving better detail library defaults to iso only and xmp disabled. |
|
I understand that multi-channel gain maps are quirky, and ISO is the future. My request was not about changing the default gain map type in libultrahdr, but about linking ImageMagick with libultrahdr. That would halve the amount of tinkering required for creating Google Photos compatible HDR images. Is it reasonable? |
|
@pallosp XMP encoding is necessary for a few applications, but ISO works for most. Going forward, XMP-only images may lack support, so I recommend everything newly encoded includes ISO (either on its own or dual encoded with the Android XMP, as libultrahdr does). While optimizing the red, green, and blue channels in the map metadata improves results theoretically and in testing, I have not seen a visible improvement in image quality across numerous test images. So dual encoding (which will cause single-channel metadata in libultra as the XMP does not support it) seems perfectly fine to me. No perfect answer here, but I believe dual encoding now has much more benefit than downside. And switching to ISO-only encoding at some point in the future (when XMP-only decoding / transcoding is no longer a concern) will be ideal to reduce file size slightly (and allow the multi-channel optimization in this case). |
|
In case it helps anyone else, I used this for my Sony A6700 HIF with HLG to upload to Google Photos with Ultra HDR and the colours matching the bt2100 gamut that is set. Thanks @pallosp for the great guide above! |
Steps to build imagemagick with ultrahdr:
Change-Id: Id745d838ffc950d2a8ca158462271b9596d482c6
Prerequisites
Description