libjxl

FORK: libjxl patches used on blog
git clone https://git.neptards.moe/blog/libjxl.git
Log | Files | Refs | Submodules | README | LICENSE

README.md (6539B)


      1 # HDR tools
      2 
      3 This directory contains a small set of command-line tools for HDR conversions,
      4 including to SDR.
      5 
      6 ## Tone mapping
      7 
      8 `tools/tone_map` implements tone mapping as described in annex 5 of
      9 [Report ITU-R BT.2408-4](https://www.itu.int/pub/R-REP-BT.2408-4-2021), more
     10 specifically the YRGB variant. Since the result may contain out-of-gamut colors,
     11 it additionally does very basic gamut mapping. The balance between preserving
     12 saturation and preserving luminance can be controlled by passing a number
     13 between 0 and 1 using `--preserve_saturation`. The default is 0.1. Hue is never
     14 sacrificed.
     15 
     16 ### Examples
     17 
     18 ```shell
     19 # Tone maps a PQ image for a 300 cd/m² display, and writes the result as an SDR
     20 # (but still wide-gamut) image to be shown on such a display.
     21 $ tools/tone_map -t 300 ClassE_507.png ClassE_507_tone_mapped_300.png
     22 
     23 # The result can also be written as a PQ image itself:
     24 $ tools/tone_map -t 300 --pq ClassE_507.png ClassE_507_tone_mapped_300_pq.png
     25 
     26 # It is possible to specify the maximum luminance found in the image using
     27 # `--max_nits`. For OpenEXR input, it will override the `whiteLuminance` tag
     28 # which indicates the luminance of (1, 1, 1). For PQ, it will not affect the
     29 # luminance calculated from the signal, but it will tell the tone mapping how
     30 # much headroom to leave for highlights.
     31 $ tools/tone_map -m 4000 -t 300 ClassE_507.png ClassE_507_tone_mapped_300.png
     32 ```
     33 
     34 ## PQ to HLG conversion
     35 
     36 `tools/pq_to_hlg` performs conversion of a PQ image to HLG as described in
     37 section 6 of the aforementioned BT.2408-4. That is, the PQ image is first
     38 limited to 1000 cd/m² using the tone mapping mentioned above, and the result is
     39 treated as if it were the output of a reference 1000 cd/m² HLG display: such a
     40 display  would have a system gamma of 1.2, and therefore, we can apply the
     41 HLG inverse OOTF with a gamma of 1.2 to get “back” to the linear scene-referred
     42 signal that would have produced that output on that reference display (and then
     43 encode it using the OETF).
     44 
     45 As with the tone mapping tool, the `--max_nits` and `--preserve_saturation`
     46 options can be used to guide the 1000 cd/m² limiting.
     47 
     48 ### Example
     49 
     50 ```shell
     51 $ tools/pq_to_hlg ClassE_507.png ClassE_507_hlg.png
     52 ```
     53 
     54 ## HLG rendering
     55 
     56 HLG is designed to look acceptable without specific processing on displays that
     57 expect a “traditional” SDR signal. Nevertheless, it is possible to optimize the
     58 appearance for specific viewing conditions by applying the HLG inverse OETF and
     59 then the OOTF with an appropriate system gamma. Here, the system gamma is
     60 computed using  the extended model mentioned at the bottom of page 29 of
     61 [Report ITU-R BT.2390-9](https://www.itu.int/pub/R-REP-BT.2390-9-2021). That
     62 formula should work well over a wide range of display peak luminances.
     63 
     64 It is possible to specify not just the peak luminance of the target display
     65 (using `--target_nits`) but also the ambient luminance of the viewing
     66 environment using `--surround_nits`.
     67 
     68 As with the tone mapping tool, the result can be written as a PQ image. In that
     69 case, it would make sense, in further usage of `tools/tone_map` or
     70 `tools/pq_to_hlg`, to set `--max_nits` to the value that was passed as
     71 `--target_nits` to this tool. This also applies to the tone mapping tool.
     72 
     73 ### Examples
     74 
     75 ```shell
     76 # Renders an HLG image for a 300 cd/m² display in a 10 cd/m² room.
     77 $ tools/render_hlg -t 300 -s 10 ClassE_507_hlg.png ClassE_507_hlg_300.png
     78 
     79 # Renders it for a reference 1000 cd/m² display and writes the result as a PQ
     80 # image.
     81 $ tools/render_hlg -t 1000 --pq ClassE_507_hlg.png ClassE_507_hlg_pq.png
     82 
     83 # Informing pq_to_hlg about that maximum luminance then ensures proper
     84 # roundtripping as it will not needlessly tone map the highlights.
     85 $ tools/pq_to_hlg -m 1000 ClassE_507_hlg_pq.png ClassE_507_hlg_pq_hlg.png
     86 ```
     87 
     88 ## Display light to HLG
     89 
     90 By applying the inverse OOTF to a display-referred image, it is possible to
     91 compute the scene light, and from there the HLG signal, that would have
     92 produced that output on that display:
     93 
     94 ```shell
     95 $ tools/display_to_hlg -m 600 -s 5 srgb_input.png hlg_output.png
     96 ```
     97 
     98 This is the mathematical inverse of `tools/render_hlg`. Furthermore,
     99 `tools/pq_to_hlg` is equivalent to `tools/tone_map -t 1000` followed by
    100 `tools/display_to_hlg -m 1000`.
    101 
    102 ## OpenEXR to PQ
    103 
    104 `tools/exr_to_pq` converts an OpenEXR image into a Rec. 2020 + PQ image, which
    105 can be saved as a PNG or PPM file. Luminance information is taken from the
    106 `whiteLuminance` tag if the input has it, and otherwise defaults to treating
    107 (1, 1, 1) as 100 cd/m². It is also possible to override this using the
    108 `--luminance` (`-l`) flag, in two different ways:
    109 
    110 ```shell
    111 # Specifies that the brightest pixel in the image happens to be 1500 cd/m².
    112 $ tools/exr_to_pq --luminance='max=1500' input.exr output.png
    113 
    114 # Specifies that (1, 1, 1) in the input file is 203 cd/m².
    115 $ tools/exr_to_pq --luminance='white=203' input.exr output.png
    116 ```
    117 
    118 # LUT generation
    119 
    120 There are additionally two tools that can be used to generate look-up tables
    121 for use with e.g. FFmpeg, ReShade, or DaVinci Resolve.
    122 
    123 The first of the two tools gives a starting point:
    124 
    125 ```shell
    126 $ tools/generate_lut_template --lut_size=64 identity.ppm
    127 ```
    128 
    129 From there, one can apply a chain of per-pixel transforms (including other
    130 LUTs) that the final LUT is intended to represent:
    131 
    132 ```shell
    133 $ tools/pq_to_hlg identity.ppm pq_to_hlg.ppm
    134 $ tools/render_hlg -t 400 pq_to_hlg.ppm pq_to_400nit_rec2020.png
    135 $ convert pq_to_400nit_rec2020.png -profile /usr/share/color/icc/colord/Rec709.icc pq_to_400nit_rec709.png
    136 ```
    137 
    138 From there, the PNG image can be used as-is with ReShade’s “LUT” shader
    139 (provided that the correct LUT size is set), or it can be converted to a
    140 [Cube](https://web.archive.org/web/20220215173646/https://wwwimages2.adobe.com/content/dam/acom/en/products/speedgrade/cc/pdfs/cube-lut-specification-1.0.pdf)
    141 file for use in other software such as FFmpeg’s [lut3d](https://ffmpeg.org/ffmpeg-filters.html#lut3d-1)
    142 filter:
    143 
    144 ```shell
    145 $ tools/texture_to_cube pq_to_400nit_rec709.png pq_to_400nit_rec709.cube
    146 $ ffmpeg -i pq_video.mkv -vf lut3d=pq_to_400nit_rec709.cube -colorspace bt709 -color_primaries bt709 -color_trc bt709 400nit_rec709_video.mkv
    147 ```
    148 
    149 Note: instead of converting to a standard color space such as Rec. 709, it is
    150 also possible to convert to the color space of the specific display on which
    151 the content is to be shown, in which case the transformed content does not need
    152 any specific tagging and should be displayed directly without color management
    153 (for example using `ffplay`).