Lesson 6 of 9
Reading a real file header
- 14 min
- 5 checks
- 3 hints
- Go to task
Goal
Get a PNG image's width and height from its bytes
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.
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- Reads the image's width and height
- Reads other dimensions from their offset, not from the start of the file
- Reads the width and height as big-endian
- Reads the bit depth and color type
- The dictionary has exactly the four keys