Skip to content

Instantly share code, notes, and snippets.

@alistair7
Last active September 26, 2024 00:24
Show Gist options
  • Save alistair7/3dfbc021db19a9ff237f11a2c3561056 to your computer and use it in GitHub Desktop.
Save alistair7/3dfbc021db19a9ff237f11a2c3561056 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Minimal script to check whether a JPEG-XL file contains JPEG
# lossless reconstruction data, in a more robust way than
# grepping the output of jxlinfo.
#
# This parses the ISO BMFF structure directly, so has no dependencies.
#
# Usage:
# jxl_has_jbrd.py «filename»
#
# An exit status of 0 means the file has JPEG reconstruction data.
# Any other exit status means it doesn't (or isn't a JXL).
# If multiple filenames are given, the exit status is 0 only if
# ALL files have JPEG reconstruction data.
#
import io
import struct
JXL_CONTAINER_SIG = b'\0\0\0\x0cJXL \r\n\x87\n'
def jxl_has_jbrd(f):
if f.read(len(JXL_CONTAINER_SIG)) != JXL_CONTAINER_SIG:
return False # Not a JXL container
while True:
boxheader = f.read(16) # size(4) + type(4) [+ bigsize(8)]
if len(boxheader) < 8:
return False # End of file
if boxheader[4:8] == b'jbrd':
return True
(size,) = struct.unpack('>I', boxheader[:4])
if size == 1:
# Real size is uint64 following the box type
if len(boxheader) != 16:
return False # Truncated input
(size,) = struct.unpack('>Q', boxheader[8:])
if size < 8:
return False # Either this is the last box (size==0) or size is invalid
# Skip to the next box
f.seek(size - len(boxheader), io.SEEK_CUR)
if __name__ == '__main__':
from sys import argv, exit
status = 0
for fname in argv[1:]:
with open(fname, 'rb') as f:
if jxl_has_jbrd(f):
#print('+' + fname)
pass
else:
#print('-' + fname)
status = 1
break
exit(status)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment