Quite Ok Image format, first official
QOI, the standard
Earlier this month I wrote about an exciting new image format that was an option for simple and fast encoding while also being on par with state of the art formats. QOI was lossless, compressed about as well as PNG and was about as fast as an image can get to encode and decode.
Dominic Szablewski promised to release the standard once he had some time to test things and respond to feedback. He did exactly that on the day he promised, 12/20/2021. The format changed a bit and all based on tests that he and the community ran to see what was the best option for each change. All while honoring the original concepts of being simple and fast.
The official website
for the standard is up and is about as simple as the image format
itself.
There is a PDF
that fully describes the file format on a single sheet of paper.
That isn’t cutting corners either there is a good description
for each part and even some discussion in the same page. Anyone
thinking of creating a new file format should take a hint
from this effort.
Changes
I described the original format in depth in my previous post. The original purposed format was decent, but some of the features just didn’t pan out in testing. It turned out that runs of the same pixel above 60 times were incredibly rare and could just be repeated smaller runs with little overhead. Differences were shifted to be relative to green which fits more images.
With those changes the flags that denoted the different encodings were simplified. This gave a bit back to the encoding of runs, but took away the last 2 sizes to represent full RGB or RGBA encodings. So now you look for the first 7 bits being 1s and the least bit is RGB for 0 and RGBA for 1. Otherwise the first 2 bits being 1s means it is a run with legal lengths from 1 to 62.
The number of differences were reduced to 2. 0 1 stands for a 2 bit difference in R, G and B, while 1 0 stands for a 2 byte encoding with Green getting 6 bits of difference compared to 4 bits for Blue and Red.
The other major change was the hash for indexing was made a bit more robust. It is now
( (r * 3) + (g * 5) + (b * 7) + (a * 11) ) % 64
That’s it. I decided not to spell out the new format myself as the PDF linked above does a wonderful job. No need to recreate it, but it might be nice to have the format in a few other formats over time (PDF is the opposite of QOI as it is overly complex for encoding something this simple).
What can this be used for?
Well, in theory anything that PNG is used for and then some. It is roughly the same compression. It is lossless and it can encode a huge images at a fast clip. Implementing this on a microcontroller would be a cake walk so long as there is enough storage for the image file.
For scientific results it is a great option given that data often needs to be collected quickly and stored without degradation. There is a valid argument for supporting YUV in place of RGB in some cases but that could be added to QOI very quickly with minor changes (Y mapped to G and just have a header setting to let the reader know).
Right now the biggest hurdle for QOI is the support in programs like browsers. Given the level of effort in implementing QOI let’s hope that all major browsers support it in early 2022.
Where can this go?
Like I pointed out, this format is a great option for a microcontroller where power and running time are a big concern. Imagine a small sensor that is triggered, wakes up, and takes a picture before going back to sleep. The time to save the image is about as short as it will get and the amount of code will fit on anything big enough to talk to a sensor and storage.
Science experiments can use this format for results. Unlike JPEG that adds noise while compressing, QOI is lossless. It is also helpful where the experiment is running on resource constrained processors (solar powered, radiation hardened, etc). The QOI format also supports huge images (4 billion pixels in either width or height) which may be a requirement for some sensors.
I think there is also a lot of potential for video. There is very little support for lossless video encoding right now and the options are more complex than what QOI can do and often don’t compress as well.
Video options
QOI could come in 2 video formats (set in the header). Each would encode the timing of the frames as a set number per second or number of nanoseconds between frames (avoid non linear as that gets complicated and doesn’t buy much). The first would just be the stack of frames, each encoded as they are. Literally a stream of QOI images. This format would be best suited for low resource encoding and decoding where CPU, memory and/or latency is more important than the storage size.
The second option would be a difference image encoded for runs of X frames. This means encoding the image by subtracting it from the one before. This should result in much smaller images most of the time, and not much larger image most of the time. A full image could be used every X frames to prevent huge lag in playback from given points.
This second option is very similar to MPEG and the Group of Pictures (GOP) concept. In many videos much of the image doesn’t change much from frame to frame. Think of a fixed camera. The background doesn’t change much and those areas would be easy to encode as they would approach 0 in the differences. Many pixels would be runs, index hits or 3 bit differences.
Granted adding things like audio and subtitles would would be a big move away from the QOI concept of simple. Partially because it is a complexity that grows the overall format, and there is no equivalent simple format for audio. There are still lots of applications that can benefit from this. A replacement for animated GIFs comes to mind.
I’m looking forward to see where this image format goes next and I hope others are also. Seeing it become as well supported as PNG would be a big step forward for simple formats everywhere.