PNG has a simple file structure, so I thought it might be good for practicing python.
from binascii import crc32
def read_png_iter(fname):
"""Iterator limited to PNG files. Chunk processing is thrown to other functions."""
with open(fname, 'rb') as a_file:
if a_file.read(8) != b'\x89PNG\r\n\x1a\n':
raise Exception
datl = a_file.read(4)
while datl != b'':
length = int.from_bytes(datl, 'big')
data = a_file.read(4 + length)
if int.from_bytes(a_file.read(4), 'big') != crc32(data):
raise Exception
yield (data[:4], data[4:])
datl = a_file.read(4)
def ihdr_chunk(name, data):
"""Processing for IHDR chunks"""
print(name)
print(f'w:{int.from_bytes(data[:4], "big")}')
print(f'h:{int.from_bytes(data[4:8], "big")}')
def png_chunk(name, data):
"""Other chunks just display the name"""
print(name)
if __name__ == '__main__':
funcs = {b'IHDR': ihdr_chunk}
for chunk in read_png_iter('test.png'):
funcs.get(chunk[0], png_chunk)(chunk[0], chunk[1])
I wrote it as a function because it only displays chunk information, but I think that it should be handled by a class in the end. 2017/08/03 Partially modified.