Skip to content

PQ output does not reach minimum brightness #19779

@BlankParenthesis

Description

@BlankParenthesis

Is there an existing issue for this?

  • I checked and did not find my issue in the already reported ones

Describe the bug

When saving in a output format using the PQ transfer function, the lowest value (0) is mapped to a value of about 5.5% instead of 0% per channel.

Steps to reproduce

  1. Open a file containing channels with values of 0 (or apply negative exposure to one until it does).
  2. Set output to PQ Rec2020 RGB or PQ P3 RGB.
  3. Export file.
  4. Observe exported values are at least 5.5%.

(I have seen values of less than 5.5% for some outputs, notably JPEG, though they don't reach 0)

Expected behavior

Map values of 0 to 0.

Logfile | Screenshot | Screencast

No response

Commit

No response

Where did you obtain darktable from?

distro packaging

darktable version

5.2.1

What OS are you using?

Linux

What is the version of your OS?

Archlinux

Describe your system

Running lcms2 v2.17-1

Are you using OpenCL GPU in darktable?

No

If yes, what is the GPU card and driver?

No response

Please provide additional context if applicable. You can attach files too, but might need to rename to .txt or .zip

I've had a look at this a fair bit, narrowing down where this is value discrepancy originates. It seems that inverting the tone curves using lcms2 for pq in colorspaces.c:188–190 causes the generated LUT to have the first value in the table be 0.055436 instead of 0 like I would expect.

I was not able to further deduce exactly why this occurs, though user frnxt on a reddit post regarding PQ clipping commented:

Is the X axis linear with respect to luminance in this histogram?

My hypothesis (please correct me if I'm wrong!) is that unless someone went out of their way to implement a custom PQ 1DLUT with more precision or the conversion is done in floating-point in shaders, Darktable uses LittleCMS and ICC profiles, and ICC profiles are limited to 16-bit data for a lot of operations including tone curves.

This is not that much a problem in the nonlinear → linear direction (for input PQ files) where PQ(1/65535) ≈ 1e-8 nits.

This is however much more problematic for the linear → nonlinear direction (for output PQ files) where 1/65535 x 10k nit ≈ 0.15 nit. I know some LittleCMS transform modes clip below a certain value at their lowest precision limits so this might be where your 0.0743 nits comes from.

HLG (in its reference implementation with system gamma 1.2) goes up to 1k nit, so the limit should be ≈ 0.015 nit.

This seems to align with my little knowledge so far and may be of assistance in tracking down a solution.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions