|
DuxVitae
|
|
Greg Benz
Anyone know of a way to create an HDR JXL from a source image which is 32-bit (ideally) or 16-bit PNG? I just tried CJXL on a 16-bit PNG which shows as HDR in Photoshop, and the resulting JXL does not show as HDR in Chrome. I am able to see valid HDR AVIF in Chrome but do not know yet if Chrome properly supports HDR JXL (ie unclear if I'm seeing clipped data because of the conversion or Chrome), so...
I then did a reverse conversion via DJXL to bring that JXL back to PNG to see how the round tripped image would look in Photoshop, and the twice converted image was no longer HDR in Photoshop. The image is clipped to SDR values.
|
|
2022-08-23 04:35:31
|
|
|
2022-08-23 04:35:31
|
I'm not an expert on this topic (take it with care, some things might be outdated). But I played a bit around with HDR in JXL half a year ago to see whether it would be feasible to encode my HDR panoramic image as JXL (back then I used cjxl version 0.6.8).
It's important to answer the following questions (as you will see in the following):
* What type of content is it (photography, sensor data, computer generated content, ...)?
* Do you need lossy compression to get small files or is lossless compression ok?
* Are the images larger than 130 Megapixels?
* Do you need the full range of values a 16- or 32-bit float offers?
What I learnt following the Discord conversation:
* Lossy compression is only designed to support the dynamic range a human can perceive in a single image
* The bit depth you can specify (e.g. in Gimp) is merely an indicator what pixel depth the decoder should choose. The effective bit depth encoded in the jxl is determined by the error you allow for the encoding process.
|
|
2022-08-23 04:35:45
|
My personal findings (in the following I will use EV to reference the standard term exposure value from photography. It is based on a logarithmic scale):
* Chrome loads 16-bit and 32-bit HDR JXL as 8-bit
* Unless you can manage to compile cjxl with support for EXR, pfm (an uncompressed file format) is the only option to convert 32-bit images to jxl. For 16-bit png might work as well
* Float values above 1 will be clipped (under certain circumstances I managed to perserve values up to 3 for lossy encoding) - so make sure that the brightest spot has a float value of 1
* **Lossless modular encoding** (use `-d 0`): preserves HDR, however file sizes might be larger than those you get from .hdr or .exr files: effort <= 3 - hardly any compression; effort <= 7: 2x larger than .hdr; effort = 9: 30% larger than .exr but several hours of encoding time (performance and compression efficiency have probably improved since I ran the tests).
* **Lossy compression**: 18 EV is the absolute limit if you tweak (i.e. abuse) encoding parameters. I used: `cjxl input.png output.jxl -e 1 -d 0.5 intensity_target=10000` This gives 11 EV dynamic range for linear encoded light and 18 EV for non-linear encoded light.
* If you need to encode large files (older version of cjxl silently crashed when trying to allocate more than 2GB of RAM - I'm not sure whether this is fixed in the latest precompiled binaries) or want a more convenient user interface, you can use the dev version of Gimp (https://www.gimp.org/downloads/devel/). You need to choose a low butteraugli distance (<= 0.5) to encode information beyond SDR. However, at some point you will loose details in the show - meaning you probably won't be able to encode the full dynamic range of the input image.
|
|
|
|
Greg Benz
|
2022-08-23 04:46:06
|
Thank you, <@541589169969823757>, great info!
My issue is a bit more fundamental. I've been trying to convert a test image (but ultimate goal is to convert a photograph). What I'm seeing is complete loss of the HDR data (anything that would be encoded >1.0 in 32-bits, in my PNG I'm using PQ and the SDR white is around 0.48 so everything above that represents HDR values). My test image goes up to 5 stops above SDR white. When I convert that test PNG to JXL and back to PNG using CJXL and DJXL, the result is a PNG where all values which were previously HDR are all clipped to 1.0 and the color space has been changed to a linear sRGB space which clips both my wide gamut and my HDR tones. What previously shows a clear series of brighter than white patches up to +5 stops over SDR white is all just SDR white in the final result. I'm not sure if I need to use some CJXL / DJXL flags to preserve this data, but the result after the round trip is not remotely close to the original.
|
|
|
DuxVitae
|
2022-08-23 04:49:58
|
Try it with `-d 0` for a start to make sure to use lossless encoding.
|
|
2022-08-23 04:52:23
|
Can you lower the exposure of your input image to have all values below 1? Then, it only matters to preserve details in the shadows to encode an HDR (if you say that SDR white is around 0.48 then I assume that a value of 1.0 does not have a specific meaning)
|
|
2022-08-23 04:56:39
|
When it comes to colorspace: jxl stores the image in the XYB color space. The decoder then transformes it to the desired output color space. Since I assume that the encoder correctly interpreted the ICC color profile of png, I think it's more an issue of the decoder.
|
|
2022-08-23 05:10:23
|
Maybe this helps: https://discord.com/channels/794206087879852103/794206170445119489/968531535236067348 (see following messages)
|
|
2022-08-23 05:10:40
|
colorspace can be defined for cjxl and djxl
|
|
|
|
Greg Benz
|
2022-08-23 05:13:18
|
<@541589169969823757> bingo! Just adding -d 0 allowed it to go to JXL and back to PNG in the same color space and tones all the way up to my +5 stops max in the image. Perfectly lossless, 32-bit samples in PNG are identical for the original PNG and round-trip version of the PNG. So the JXL must be good.
Unfortunately, Chrome is struggling with the JXL. It may open my test image as red in the HDR areas then shows as clipped white when I refresh the image. I tried with a photograph and see different results (does not go as far above SDR white and has a full range of values). In the photograph, Chrome has some a brief blip with severe artifacts (mostly black with some bright color details in various areas of the image), but it corrects without reloading. Clearly glitches in Chrome, but I don't quite see the trigger to reproduce the issue on demand. However, even when the artifacts are not there, the image fails to render properly.
Have you seen Chrome render HDR content properly from a JXL? I have seen good results with an AVIF test image, but it was created by Netflix and the issue in Chrome may have to do more with the approach to encoding / colorspace than with the AVIF vs JXL file formats.
|
|
2022-08-23 05:14:03
|
When using the -q 0 flag, the round-trip PNG shows the exact same profile as my source.
|
|
|
DuxVitae
|
2022-08-23 05:17:32
|
Since I ended up that Chrome displayed my HDR as sRGB I didn't put more effort into it. In the end, my use case was to display HDR panoramas and since the whole canvas environment still sticks to sRGB, I didn't investigate further into this direction.
|
|
|
Greg Benz
When using the -q 0 flag, the round-trip PNG shows the exact same profile as my source.
|
|
2022-08-23 05:19:56
|
`-q 0` sounds weird. Are you sure you set the **quality** flag to zero (that would be without effectl when using `-d 0`)?
|
|
|
|
Greg Benz
|
2022-08-23 05:35:29
|
sorry, you're correct. I meant to write -d 0
|
|
2022-08-23 05:36:47
|
Thank you for all your help.
I'll report a bug to Google. The JXL failure here is same failure I see with a valid HDR PNG file. I'm guessing the issue is failure to use this unique PQ color space or some other general HDR failure.
|
|
|
DuxVitae
|
2022-08-23 05:53:29
|
I'd post the link to the bug report on this Discord, too. To make sure the right people see it.
|
|