Last active
September 26, 2024 00:24
-
-
Save alistair7/3dfbc021db19a9ff237f11a2c3561056 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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