-
Notifications
You must be signed in to change notification settings - Fork 0
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
Lossy QOI Variant #21
Comments
In any case, both lossy and lossless QOI might make a nice addition to VNC's compression options. |
This is a really bad lossy format as specified. 4 bit RGBA is going to look awful. I think that any good form of lossless compression will need fairly complicated perceptual modeling and won't be a good fit for QOI. |
It might look awful (or it might not - I'd have to look at some 4-bit outputs), but it still might be good enough for low-bandwidth low-latency VNC. Faster than JPEG or ZLIB compression. Smaller network traffic than lossless.
I assume you meant lossy instead of lossless. |
For screenshots, it's surprisingly OK. The main problem will be things like gradients and faces. |
Does it look awful? Well, there's obvious banding if you know what to look for, but it depends on the context. I'm not saying we can use QOI-Lossy everywhere we'd use JPEG. I'm saying there might be situations (e.g. VNC) where QOI-Lossy might be useful. By the way, quick-and-dirty Go program to downsample to 4444: https://go.dev/play/p/wesTsnYyUah |
Yeah, that's a pretty clear example. The equivalent JPEG will be around the same size with no noticeable quality loss. |
I'll also note that these images were produced by an encoder (treating each pixel independently), but if you want nicer quality (but still smaller than lossless file size), a different encoder could try standard dithering algorithms to lessen the obvious banding. |
Well, yes, but with slower encodes and decodes. Possibly not with hardware-acceleration. Anyway, I'll repeat my previous point (that might have got lost in the rapid replies): I'm not saying we can use QOI-Lossy everywhere we'd use JPEG. I'm saying there might be situations (e.g. VNC) where QOI-Lossy might be useful. And, like QOI-Lossless, it's only 300-ish lines of code. Or 10s of lines if you already have QOI-Lossless. |
One approach that might be a lot better would be to store exact pixels diffs if the pixels are close, and only shift out data if the 8 bit opcodes aren't successful. |
A different really simple approach would be to mul/shift the diffs to increase their range by sacrificing precision, with the range of QOI_DIFF_8 f.e. moving from [-2, -1, 0, 1] to something like [-8, -4, 0, 4]. This should allow for both substantial space savings (QOI_DIFF_16s 5/4-bit ranges would go from [-16..15]/[-8..7] to [-64..60]/[-32..28]) as well as running-delta-dithering by the encoder for still quite respectable quality. Another improvement would be to make all diffs odd (f.e [-7, -3, 1, 5]) to further increase the effective dithering of the lowest bit. You could also change the index to only hash and test the higher 6/5/4-bits when looking for a match. Something like: index: 0xd4 index: 0xd8 => replaced after hit for more dithering EDIT: wait, wouldn't work on decode, oh well, still 0xd4 then. And ignore small diffs (<8?) while encoding runs, so [12,13,12,15] would turn into a run of 4 (with a value of 12 or 13, depending on the intelligence of the encoder). |
Downsampling from 8 to 6 bits per channel (instead of to 4) isn't too bad in terms of visual quality. Again, there's banding if you know where to look, but I think that it's much less obvious... Here's the file sizes in bytes and as a fraction of lossless (8 bits per channel), starting with the demo10 code. Going down to 6 bits per channel still gives you a noticable file size reduction. There might be further file size gains from tweaking the
Perhaps we could use 3 bits of the header for a lossiness knob going from 0 (8 bits per channel) to 7 (1 bit per channel). Again, it's not something you'd want to use all of the time, or even most of the time, but it might be a useful thing to have in the toolbox, especially if it's only 10 or 20 extra lines of code on top of lossless QOI. |
I think for game textures that could be really useful (especially if the encoder was clever enough to add some dithering). |
What about having a lossy encoder, and keeping a "lossless" decoder ? by ignoring small pixel differences to increase the run length? |
Creating a lossy encoder for a lossless format is definitely possible. pngquant exists for png. |
I definitely raise my hand for making encoders support "smart quantization with dithering and high-fidelity transparency" (and possibly other techniques) as pngquant does. It allows for user-settable level of quality and generally solves the most visually distracting artifacts while drastically reducing the size (not as jpg, but much closer than any other attempts I saw above). This could be QOI 1.1 (just adding to the current spec the mandate to support this in encoders). And the best of all - decoders don't need to change a thing! |
FYI it was suggested that phoboslab/qoi#145 might be more appropriate here. Wouldn't mind someone checking the results, as they were pretty compelling, especially as it's "free". |
@kodonnell thanks! I'm really interested in lossy compression, so your findings ignited my further interest in the downscaling idea. I'm though a non-believer in SSIM and thus would want to see maybe 5 complex different images with at least 3 millions of pixels compressed with JPEG@93 (very frequently used ratio for camera-taken pictures of physical world) and with different sampling methods in your package - all three (original, jpeg@93, qoi-lossy) side by side. Or do you already have such images? |
I'm afraid I don't have any such images - can you send some through? I was going to use the python image similarity package which supports other metrics, but didn't want the bloat it requires. What metric would you prefer? |
@kodonnell sorry for the late reply. I would imagine something like ISSIM-S (further details about SSIM huge limitations: https://www.researchgate.net/publication/283153178_Limitations_of_the_SSIM_quality_metric_in_the_context_of_diagnostic_imaging and https://ieeexplore.ieee.org/document/9337182 ). As for pictures anything from your smartphone could do :-) But let us try https://pngquant.org/vsphotoshop.html . |
We could use a bit in the header to indicate a trivial lossy QOI variant (call it QOILY and the original flavor QOILL), reducing from 8 to 4 bits per RGBA channel on encode, reconstitute on decode.
File sizes are now ballpark comparable to (lossy) JPEG, with much of the benefits of lossless QOI (very simple implementation, very fast encode and decode).
The file size ratios vs JPEG looks better for images/screenshots (roughly 1x) than images/kodak (roughly 2x, but these are photos, possibly even JPEGs to start with).
QOI-Lossy vs JPEG File Sizes
The JPEGs were generated by ImageMagick's
convert foo.png foo.jpeg
.QOI-Lossless (the Original QOI) vs PNG File Sizes
QOI-Lossless vs QOI-Lossy File Sizes
The text was updated successfully, but these errors were encountered: