-
Notifications
You must be signed in to change notification settings - Fork 335
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comprehensive Test Suite of Images #69
Comments
This is very cool! I'll check it out and run my impl against it 😊 |
qoiconv.c currently has trouble encoding The reason is that they all are grayscale or grayscale with alpha, and stb_image.h decodes those as buffers of 1 and 2 channels respectively. |
It was commented in #48 (comment) that the filename |
Ha, amazing! I fixed the name in the .tar archive. Thanks! Decoding of the greyscale images mentioned above should be fixed with 525f32c |
I put together a collection of transparent sprites from our game to test the effectiveness of qoi at encoding transparent images. In general they don't have many hard alpha edges, they have mostly soft and messy alpha edges like you would expect from digitally painted assets. Here's the gist with the zip and a full benchmark result. I've also put a summary of the results below. It performs worse than on opaque images, as expected, but still surprisingly well compared to PNG, except on a few pathological images with deliberately gradual and uniform alpha gradients, which are 40x larger than their PNG counterparts. These aren't artificial images, we actually use all of them in the game. That said, the worst compression ratio on one of these is 35.3%, which isn't terrible, but it still leaves me wanting for at least one DIFF opcode that includes alpha.
|
@notnullnotvoid Tested @wbd73's idea of replacing QOI_OP_RGBA with QOI_OP_A on your images. It certainly is helping images with more complex alpha! Also, @phoboslab, wouldn't consecutive QOI_OP_As, which shouldn't normally happen and also don't decode into additional pixels, make for a good QOI_END_IMAGE? EDIT: Another small tweak that allows for QOI_OP_RUN -> QOI_OP_A -> QOI_OP_RUN instead of QOI_OP_RUN -> QOI_OP_A -> QOI_OP_DIFF(0) -> QOI_OP_RUN. EDIT: Re-run produced smaller performance loss (PC must have done something in the background the first time), updated qoi_op_a_tweak throughput.
|
Thanks for the info! On my end I tried stealing a couple 8-bit opcodes from QOI_OP_RUN and using them for 2-bit-per-channel and 4-bit-per-channel RGBA diffs. I got improvements on the lance image set, at the cost of some speed:
I also ran the main test suite to make sure there weren't any major regressions. It looks like it helps a bit on the icons, but not on other transparent images which mostly have hard alpha. As expected, none of the images got significantly larger.
Here's the exact code (diff) for these benchmarks. I would strongly advocate for including something like this in the spec, although I understand it's not free gains, as there's a performance and complexity cost. I will point out however, the impact on opaque images is significantly smaller than on transparent images - there's no noticeable cost for encoding opaque images (makes sense), and only a small cost for decoding opaque images, which could probably be mitigated by reordering branches in the decoder. Edit: included results for |
Any chance you could do the images-lance numbers for demo10 (nigeltao/qoi2-bikeshed#22)? |
I've added the numbers for |
That's essentially what |
Replacing QOI_OP_RGBA surprises me, especially if, in some sense, your QOI_OP_A combines with the next op - it's no longer the case that each op emits at least one pixel. Here's my numbers for tweaking phoboslab/master (commit aefa0f7, 2021-12-17) to add my stand-alone QOI_OP_A alongside QOI_OP_RGBA (QOI_OP_A replaces "QOI_OP_RUN with run length 62", like as in #71 (comment)):
337a338
> #define QOI_OP_A 0xfd /* 11111101 */
439c440
< if (run == 62 || px_pos == px_end) {
---
> if (run == 61 || px_pos == px_end) {
489a491,498
> else if (
> (px.rgba.r == px_prev.rgba.r) &&
> (px.rgba.g == px_prev.rgba.g) &&
> (px.rgba.b == px_prev.rgba.b)
> ) {
> bytes[p++] = QOI_OP_A;
> bytes[p++] = px.rgba.a;
> }
593a603,605
> }
> else if (b1 == QOI_OP_A) {
> px.rgba.a = bytes[p++]; |
Note that |
I have now assembled a pretty comprehensive suite of test images. These all come with the proper license information (CC or public domain). It includes:
Here's the full set:
https://phoboslab.org/files/qoibench/qoi_benchmark_suite.tar (1.1 GB) — very proudly excluding lenna.jpg
All images in this test suite are PNGs. I will add QOI images once the specification has been finalized (related #20).
To make it a bit easier to test tweaks for qoi, qoibench.c (in the experimental branch) can now descend into subdirectories, prints a grand total and has gained various options:
E.g. if you just want to check the overall compression ratio for qoi as fast as possible:
./qoibench 1 images/ --nowarmup --nopng --noverify --nodecode
The text was updated successfully, but these errors were encountered: