Showing images on a TFT or OLED display with a small AVR microcontroller can be a challenge as it requires significant storage space. One solution is to compress the images, but then you need more RAM to decompress it, and that’s a whole other problem. [David Johnson-Davies] of Technoblogy couldn’t find a GIF decoder that fit his needs, so he started writing his own.
We had previously seen a minimal GIF decoder aimed at a Cortex-M0+ that required 24 K of RAM, but this technique is running on an AVR with just 12 K of RAM. Along the way, [David] uses little tricks to shave down the requirements. Since the TFT he targets is a 5-6-5 color space, those 3-byte colors become 2 bytes. The LZW lookup table is encoded as 12-bit pointers to earlier entries plus an additional pixel. However, these savings come at a cost. Animated, local color tables, transparency, interlacing, or GIF87a formatted images aren’t supported. But he ports it over to the PyBadge, which is ATSAMD51 based.
[David] provides some sample code to display a GIF from program memory and an SD card. All the code is on GitHub under a CC By 4.0 license.
[Dominic Szablewski] was tinkering around with compressing RGB images, when he stumbled upon idea of how to make a simple lossless compression algorithm, resulting in the Quite OK Image Format, which seems to offer comparable file sizes to the PNG format but is so simple it runs up to 50 times faster for compression and up to four times faster for decompression. Implementation can be achieved with a miniscule 300 lines of C. Need a bit more detail on the real-world performance? Well [Dominic] has that covered too, with a complete set of benchmarks for your perusal.
Image formats are one of those things these days that are designed by consortium, with so much complexity wedged in making it hard to implement with limited resources, so we find it very refreshing to see someone going back to basics and producing something super lightweight, and plenty good enough in practical terms.
Other uses for the algorithm could be for super simple video compression, for applications where resource is tight and some low-effort bandwidth reduction would be beneficial. Implementation in a small FPGA would also be quite straightforward, since the memory requirement is quite low also.
The project is very new and already there are some tweaks happening to the format, so the GitHub project code may change without warning to reflect any corrections [Dominic] feels necessary.
Thanks [David] for the tip!