Skip to content

Instantly share code, notes, and snippets.

@zachlewis
Last active February 26, 2025 15:28
Show Gist options
  • Save zachlewis/e2024d3d0e15f25d8070d2bddbe4966e to your computer and use it in GitHub Desktop.
Save zachlewis/e2024d3d0e15f25d8070d2bddbe4966e to your computer and use it in GitHub Desktop.
Patch nclx data into AVIF file header for specified Primaries / TRC / YUV Matrix
import binascii
import os
import re
from logging import getLogger
logger = getLogger(__name__)
def patch_avif_header_cicp(input_file, P=9, T=16, M=9, output_file=None, preset=None, dryrun=False):
"""Patch nclx data into AVIF file header for specified Primaries / TRC / YUV Matrix Coeff enums."""
CICP_ENCODINGS = {
# primaries, trc, matrix
'bt2100_pq': (9, 16, 9),
'bt2100_hlg': (9, 18, 9),
'bt709_srgb': (1, 13, 1),
'bt709_g22': (1, 4, 1),
'bt709_bt709': (1, 1, 1),
'p3d65_pq': (12, 16, 1),
'p3d65_srgb': (12, 13, 1),
'p3d65_g22': (12, 4, 1),
}
def cicp_to_bytes(P=1, T=13, M=1):
return binascii.unhexlify("%04x%04x%04x" % (P, T, M))
def bytes_to_cicp(v):
v = binascii.hexlify(v)
return [int(i, 16) for i in [v[0:4], v[5:8], v[9:12]]]
output_file = output_file or input_file
in_place = (input_file == output_file)
P, T, M = CICP_ENCODINGS.get(preset, [P, T, M])
ptrn, offs, cutlen = b"colrnclx", len(b"colrnclx"), 2 * len((P, T, M))
with open(input_file, 'r+b' if in_place else 'rb') as fd_in:
data = fd_in.read()
match = re.search(ptrn, data)
logger.debug('Patch %s: CICP: %s --> %s' % (
os.path.basename(input_file),
tuple(bytes_to_cicp(data[match.start() + offs:match.start() + offs + cutlen])),
(P, T, M)))
if not dryrun:
if in_place:
fd_in.seek(match.start()+offs)
fd_in.write(cicp_to_bytes(P,T,M))
else:
with open(output_file, 'wb') as fd_out:
patched = data[:match.start() + offs] + cicp_to_bytes(P, T, M) + data[match.start() + offs + cutlen:]
fd_out.write(patched)
logger.info(f'Patched CICP({P},{T},{M}): {output_file or input_file}')
return output_file or input_file
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment