mastodon.gamedev.place is one of the many independent Mastodon servers you can use to participate in the fediverse.
Mastodon server focused on game development and related topics.

Server stats:

5.4K
active users

The default SDR conversion in libheif seems to be not so good? The output images are pretty bland.

Sample AVIF HDR images from mark-heath.com/hdrphotos/

@wolfpld looks like PQ-encoded RGB being displayed (wrongly) on an sRGB display. Is it possible libheif is just giving you a 8-bit version of the PQ signal in the file?

@rfnix In my code it's just a standard decode call, as in their example in the readme:

heif_decode_image(handle, &img, heif_colorspace_RGB, heif_chroma_interleaved_RGB, nullptr);

The images I show are either viewed in gwenview, or converted to jpeg with ImageMagick. Regardless of the method, the output is the same.

@wolfpld if you're not saving the ICC profile or CICP/nclx it's definitely going to get displayed wrong. You're still getting an HDR signal here AFAICT.

(Iirc libheif has RRGGBB or something for 16-bit signals?)

@rfnix I just downloaded a picture from the internet and none of the tools I have can display it properly. This is not a "me" problem.

@wolfpld ah sorry that came off as "this is your fault", that was not my intention, I was interrupted and finished the message too quickly...

What I wanted to add is : the state of HDR support in OSS libraries is very very young, most of them concern themselves with getting the raw RGB pixels and leave you hanging there trying to figure out how to interpret them. And unlike SDR where one will get something close when forgetting the colorimetry metadata of a Display P3 image and may not notice it, for HDR it's absolutely necessary.

@wolfpld technically at this point in time you need libheif+LittleCMS if you want to interpet colors correctly in HDR, or reimplement part of the standards e.g. what mpv does in its rendering shaders.

@wolfpld another solution might be OpenColorIO but I'm way less familiar with it...

@rfnix On my system OpenColorIO is a 8.4 MB package and is used only by Krita. It also depends on LittleCMS.

LittleCMS is a 690 KB package and is used by many different applications.

The choice seems simple.

@wolfpld OCIO is definitely way bigger, maybe the package also brings predefined transformations (e.g. LUTs, which can take some space).

LittleCMS just focuses on reading, writing and executing ICC profiles, but you have to bring your own profiles (or create one on the fly).

- The simple way is one cmsCreateRGBProfile with BT.2020 primaries/whitepoint and PQ tone curve, one cmsCreate_sRGBProfile(), then cmsCreateTransform between the two.

Since you probably need to insert tonemapping in the mix, so you would possibly use a tonemapped version of PQ instead of the real one or something like this.

@wolfpld another option is to implement PQ yourself (it's pretty straightforward actually) to go to linear, then do the tonemapping you want, then go from (tonemapped) BT2020 linear to sRGB using the transform mechanism.

(But that's possibly slower than if you can implement the whole thing using one single cmsCreateTransform.)

Bartosz Taudul

@rfnix I recognize some of the terms you are using :|

I'm looking at OpenEXR now, which is always linear. It may define chromacities, and defaults to BT.709 if unspecified. I assume that I can do some transform with lcms between the color spaces, so that the floating point values I output will be well defined, for example in BT.2020?

With the PQ data I will additionally need to linearize it first, before doing the color space transformation.

Does that sound right?

@rfnix Oops, the PBR Neutral tone mapper is designed for BT.709, so I'd want that instead.

@wolfpld exactly!

lcms lets you choose to use float values, and they can be unbounded for each channel (>1). In general the intent should be "relative colorimetric" if you just want to do simple colorimetric conversions (not perceptual/saturation).

I often prototype in Python with colour-science (colour-science.org), it's slower but the math inside the code is very nice to read and you can use the console!

For example for converting linear BT2020 to linear BT709:

>>> import colour
>>> colour.RGB_to_RGB((0.5, 0.1, 0.5), colour.RGB_COLOURSPACES["ITU-R BT.2020"], colour.RGB_COLOURSPACES["ITU-R BT.709"])
array([ 0.73505646, 0.04684004, 0.54023156])

Colour Science · Colour Science for PythonColour is an open-source Python package providing a comprehensive number of algorithms and datasets for colour science.