Skip to content

Instantly share code, notes, and snippets.

@johncf
Last active October 9, 2024 12:39
Show Gist options
  • Save johncf/7e18feee6acd717d72d87b7b9b5111a1 to your computer and use it in GitHub Desktop.
Save johncf/7e18feee6acd717d72d87b7b9b5111a1 to your computer and use it in GitHub Desktop.
AVIF with HDR and CICP (Coding-Independent Code Points) settings

To convert an HDR PNG that's exported with HLG transfer function in Rec. 2020 color space, do:

avifenc -s 4 -j 4 --min 1 --max 56 -a end-usage=q -a cq-level=18 -a tune=ssim \
    -a color:enable-chroma-deltaq=1 -a color:enable-qm=1 -d 12 --cicp 9/18/9 IMG_0186.png IMG_0186.avif

For HDR with PQ transfer function in Rec. 2020 color space, do:

avifenc -s 4 -j 4 --min 1 --max 56 -a end-usage=q -a cq-level=18 -a tune=ssim \
    -a color:enable-chroma-deltaq=1 -a color:enable-qm=1 -d 12 --cicp 9/16/9 IMG_0186.png IMG_0186.avif

For the default SDR image (sRGB with BT.601 coefficients), simply do:

avifenc -s 4 -j 4 --min 1 --max 56 -a end-usage=q -a cq-level=18 -a color:deltaq-mode=3 -a tune=ssim \
    -a color:enable-chroma-deltaq=1 -a color:enable-qm=1 --cicp 1/13/6 IMG_0186.png IMG_0186.avif

For the same with BT.709 coefficients, do:

avifenc -s 4 -j 4 --min 1 --max 56 -a end-usage=q -a cq-level=18 -a color:deltaq-mode=3 -a tune=ssim \
    -a color:enable-chroma-deltaq=1 -a color:enable-qm=1 --cicp 1/13/1 IMG_0186.png IMG_0186.avif

Notes:

  • Setting deltaq-mode to 5 (HDR) doesn't seem to make a difference at all, 3 produces slightly smaller files for SDR images.
  • If --cicp is ignored and the source image doesn't specify any profile, 2/2/6 is used where 2 means unspecified. This is okay for sRGB.

PQ to HLG conversion

Generate a look-up table (LUT) with hlg-tools using a reference white-point:

hlg-tools/pq2hlg -r 203 -s 128 pq2hlg.cube

Note: popular reference white points in use are: 80 nits, 100 nits, 203 nits, and 300 nits. But 203 nits seems to be becoming the standard in photography.

Map the pixel values with FFMPEG using the above generated LUT (pq2hlg.cube):

ffmpeg -i HDR_sample_pq.png -vf format=rgb48le,lut3d=pq2hlg.cube -color_primaries bt2020 -color_trc arib-std-b67 -colorspace bt2020nc HDR_sample_hlg.png

Note: HDR_sample_hlg.png will have bad metadata even though we specified the correct transfer function arib-std-b67 (ffmpeg issue?), so viewer apps will render it badly.

Convert to avif with the correct transfer function (the 18 in 9/18/9 indicates HLG):

avifenc -s 4 -j 4 --min 1 --max 56 -a end-usage=q -a cq-level=18 -a tune=ssim -a color:enable-chroma-deltaq=1 -a color:enable-qm=1 -d 12 --cicp 9/18/9 HDR_sample_hlg.png HDR_sample_hlg.avif

Copy EXIF tags from the original DNG file:

exiftool -TagsFromFile RAW_sample.DNG "-all:all>all:all" HDR_sample_hlg.avif

PQ optimized

Opening the AVIF file converted from the HDR PNG (PQ or HLG) export from Affinity Photo 2 in iPhone is slower than doing it after these steps. The only explanation I could come up with is the removal of alpha channel perhaps... 🤔

ffmpeg -i IMG_0025_pq.png -vf format=rgb48le -color_primaries bt2020 -color_trc smpte2084 -colorspace bt2020nc IMG_0025_pq2.png
avifenc -s 4 -j 4 --min 1 --max 56 -a end-usage=q -a cq-level=18 -a tune=ssim -a color:enable-chroma-deltaq=1 -a color:enable-qm=1 -d 12 --cicp 9/16/9 IMG_0025_pq2.png IMG_0025_pq2.avif
exiftool -TagsFromFile IMG_0025.DNG "-all:all>all:all" IMG_0025_pq2.avif

Sources:

Misc: HDR-merging and Tone-mapping using OpenCV

Misc: Notes on HDR Gain Map and HEIF-Pillow

HDR Gain map

Pillow-HEIF

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment