This page details my porting of the Quite Okay Image (QOI) format encoder to the D Programming Language. The QOI format was created by Dominic Szablewski as a fast, easy to understand lossless image format. I was able to include the decoder in my Viewer program and thought it would be good to make an encoder as well!
To keep the download size small, this is provided as a 7zip archive. Archive includes the compiled exe and source.
Download now! (174KB 7Zip)
Updated (07/07/2024)
Given that the compression method and encoder are relatively simple, there were no radical changes in the conversion, more a case of tiny tweaks to get some benefits that the D Language provides:
Instead of this:
px_len = desc->width * desc->height * desc->channels;
As I knew the passed array of bitmap pixels was set to the correct length, I could use that instead:
int px_len = pixels.length;
From this:
max_size = desc->width * desc->height * (desc->channels + 1) + QOI_HEADER_SIZE + sizeof(qoi_padding); bytes = (unsigned char *) malloc(max_size);
to this:
ubyte[] qoi_data; qoi_data.length=desc.width*desc.height*(desc.channels + 1)+QOI_HEADER_SIZE+qoi_padding.length;
Using a dynamic array means easy resizing and I bounds checking. If I overshoot the array size, I get a crash instead of random unsafe behaviour!
This was the original loop for writing the QOI end file marker:
static const unsigned char qoi_padding[8] = {0,0,0,0,0,0,0,1}; ... for (i = 0; i < (int)sizeof(qoi_padding); i++) { bytes[p++] = qoi_padding[i]; }
With D we can be lazy and use a foreach loop, we let the compiler figure out the type for 'b' as well:
private byte[8] qoi_padding = [0,0,0,0,0,0,0,1]; ... foreach(b;qoi_padding) { bytes[p++] = b; }
As final check, a CRC checksum tells me that the files this creates are identical to IrfanView which is a good sign. This version was not made for speed but as an easy to understand reference version. As it works well, it will probably be the basis of encoders for my Java and C# applications too!
These numbers should be taken with a pinch of salt but just to give some idea of comparison:
Test Bitmap
Resolution: 1296 x 1336 x 3 (24bit)
File Size: 5833KB
BMP | QOI | PNG | |
---|---|---|---|
Compression Time (ms) | n/a | 123 | n/a |
File Size (KB): | 5833 | 2729 | 1976 |
Time to open (IrfanView): | 16ms | 94ms | 234ms |
This encoder works and is reasonably quick. The QOI format looks like a good one to use if an application needs a simple way to add a lossless image save option!
Created 07/07/2024