A Look Inside The Smallest Possible PNG File

What’s inside a PNG file? Graphics, sure. But how is that graphic encoded? [Evan Hahn] shows you what goes into a single black pixel inside a 67-byte file. Why so many bytes? Well, that is exactly what the post is about.

You had to guess there is some overhead, right? There is an 8-byte header. Next up is a 25-byte metadata block. That single pixel takes 22 bytes, and then there is a 12-byte marker for the end of file. Turns out, you could put a bit more in the file, and would still take 67 bytes. The metadata is in a chunk — a block of data with a type, length, and CRC. That’s why it takes 25 bytes to store the dimensions of the image. A chunk has to be at least 12 bytes long. The metadata includes the image dimensions, the bit depth, and so on.

The next chunk, of course, is the data. The data is compressed, but in the case of one pixel, compression is a misnomer. There will be ten data bytes in the data chunk. That doesn’t include the 12 bytes of the chunk overhead so that one pixel takes a whopping 22 bytes.

The end of file marker is another chunk with no data. The total? 67 bytes. However, you can add more than one bit and still wind up with 67 bytes. For all the details, check out the post.

Luckily, it is easy to pronounce PNG. You can even use the format for circuit simulation.

The 1337 PNG Hashquine

A hashquine is a fun way to show off your crypto-tricks — It’s a file that contains its own hash. In some file types it’s trivial, you just pick the hash to hit, and then put random data in a comment or other invisible field till you get a collision. A Python script that prints its own hash would be easy. But not every file type is so easy. Take PNG for instance. these files are split into chunks of data, and each chunk is both CRC-32 and adler32 checksummed. Make one change, and everything changes, in three places at once. Good luck finding that collision. So how exactly did [David Buchanan] generate that beautiful PNG, which does in fact md5sum to the value in the image? Very cleverly.

md5sum hashquine.pngThankfully [David] shared some of his tricks, and they’re pretty neat. The technique he details is a meet-in-the-middle hack, where 36 pairs of MD5 collision blocks are found, with the understanding that these 36 blocks will get added to the file. For each block, either A or B of the pair will get plugged in at that location, and the md5sum won’t change. It’s a total of 2^36 possible combinations of these blocks, which is more computation than was practical for this particular hack. The solution is to pre-compute the results of every possible combination of the first 18 blocks, and store the results in a lookup table. The second half of the collisions are run backwards from a target CRC value, and the result checked against the lookup table. Find a hit, and you just found a series of blocks that matches both your target md5sum and CRC32 results.

Thanks to [Julian] for the tip! And as he described it, this hack is one that gets more impressive the more you think about it. Enjoy!

Parsing PNGs Differently

There are millions of tiny bugs all around us, in everything from our desktop applications to the appliances in the kitchen. Hidden, arbitrary conditions that cause unintended outputs and behaviors. There are many ways to find these bugs, but one way we don’t hear about very often is finding a bug in your own code, only to realize someone else made the same mistake. For example, [David Buchanan] found a bug in his multi-threaded PNG decoder and realized that the Apple PNG decoder had the same bug.

PNG (Portable Network Graphics) is an image format just like JPEG, WEBP, or TIFF designed to replace GIFs. After a header, the rest of the file is entirely chunks. Each chunk is prepended by a four-letter identifier, with a few chunks being critical chunks. The essential sections are IHDR (the header), IDAT (actual image data), PLTE (the palette information), and IEND (the last chunk in the file). Compression is via the DEFLATE method used in zlib, which is inherently serial. If you’re interested, there’s a convenient poster about the format from a great resource we covered a while back.

Continue reading “Parsing PNGs Differently”

PNG Image Decoding Library Does It With Minimal RAM

Want to display a PNG file on a display attached to an Arduino or other microcontroller board? You’ll want to look at [Larry Bank]’s PNGdec, the Arduino-friendly PNG decoder library which makes it much easier to work with PNG files on your chosen microcontroller.

The PNG image format supports useful features like lossless compression, and was generally developed as an improved (and non-patented) alternative to GIF files. So far so great, but it turns out that decoding PNG files on a microcontroller is a challenge due to the limited amount of memory compared to desktop machines. When the PNG specification was developed in the 90s, computers easily had megabytes of memory to work with, but microcontrollers tend to have memory measured in kilobytes, and lack high-level memory management. [Larry]’s library addresses these issues.

PNGdec is self-contained and free from external dependencies, and also has some features to make converting pixel formats for different display types easy. It will run on any microcontroller that can spare at least 48 K of RAM, so if that sounds useful then check out the GitHub repository for code and examples.

We’ve seen [Larry]’s wonderful work before on optimizing GIF playback as well as rapid JPEG decoding, and these libraries have increasing relevance as hobbyists continue to see small LCD and OLED-based displays become ever more accessible and affordable.

[PNG logo: PNG Home Site]

Images Carrying An Encrypted Data Payload


This is a tidy looking banner image. But according to [Ian] it contains 52KB of source code. You can’t just read out all of that data. Well, you can but it will be gibberish. Before hiding the bits in plain sight he encrypted them with two different keys.

He’s using AES-256 encryption to keep his data away from prying eyes. But if that wasn’t enough, he also wrote a PHP program to hide the bits in a PNG image. Not just any picture will do (otherwise your eye will be able to see something’s awry). The post linked above focuses mainly on how to choose an image that will hide your data most easily. We asked him if he would share his techniques for actually merging the encrypted file with the picture and he delivered. Head on over to his repository if you want to take a look at the generator code.