Time to run the whole decoder on a real file. Today you wire the full pipeline into one Decode and turn an embedded PNG into pixels, proving every stage from signature to color assembly works together.
Decode a real embedded PNG through the complete pipeline and read its dimensions and pixels.
This is the decoder’s finish line. Decode finally strings together every chapter into one call: verify the signature, walk the chunks, read IHDR, concatenate all IDAT data into one zlib stream, inflate it, unfilter the scanlines, and assemble the raw bytes into RGBA pixels. The embedded 91-byte file is a genuine PNG - stored-block compressed, color type 6 - and it comes out as a 2x2 image whose four corners are red, green, blue, and a half-transparent white.
Every hard thing you built is exercised at once: the CRC-checked container, the from-scratch inflater with its bit reader and Huffman machinery, the filter reconstruction, and the color assembly. That the half-alpha white pixel 255,255,255,128 survives unpremultiplied proves the alpha path and the byte-exact plumbing all the way down. From eight magic bytes to a picture in memory, the decoder is complete and real. One capstone remains: proving the encoder closes the loop.
// Decode: verify signature -> walk chunks -> parse IHDR -> concat IDAT data// -> Inflate -> unfilter -> assemble -> Image.// hex of the test PNG (decode this to bytes and hand to Decode):// 89504e470d0a1a0a0000000d49484452000000020000000208060000// 0072b60d2400000022494441547801001200edff00ff0000ff00ff00// ff000000ffffffffff80010000ffff494909786e85b47a0000000049454e44ae426082func Decode(b []byte) (*Image, error) { }