Lesson 6 of 9

Reading a real file header

Goal

Get a PNG image's width and height from its bytes

01

Explanation

You've read a made-up header, and now it's time for the header of a real file you'll find on your own computer: a PNG image. Every PNG file starts with an eight-byte signature, followed by a series of chunks, and the first one is always a chunk named IHDR that holds the image's dimensions. Every multi-byte number in PNG is big-endian. This is also called network byte order, the usual choice for formats meant to move between different machines.

Each chunk is four consecutive fields: the length of its data in four bytes, then its type as four bytes of text, then its data, then a four-byte checksum. The IHDR data is thirteen bytes long, and its first few fields are what matter here:

Offset  Field
0       PNG signature (eight bytes)
8       chunk data length (four bytes)
12      chunk type IHDR (four bytes)
16      width  (four bytes, big-endian)
20      height (four bytes, big-endian)
24      bit depth (one byte)
25      color type (one byte)

So the width and height sit at offset 16, after the signature, the length and the type. struct.unpack_from(fmt, data, offset) reads from an offset you choose without slicing the data: you pass the offset as its third argument.

02

Your task

Write a function parse_png(data) that reads a PNG header and returns a dictionary with the keys "width", "height", "bit_depth" and "color_type". Read the width and height as big-endian from their offset, and read the bit depth and color type one byte each.

Checks

5 checks
  1. Reads the image's width and height
  2. Reads other dimensions from their offset, not from the start of the file
  3. Reads the width and height as big-endian
  4. Reads the bit depth and color type
  5. The dictionary has exactly the four keys
main.py
OutputPython (Pyodide)

Loading Python. This only happens once. Your browser keeps it after that.

–/5

Checks start once the environment is ready.

5 checks listed under “Your task”.