Skip to content
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

The number of channels should be encoded in the QOI header #16

Closed
ThomasMertes opened this issue Nov 25, 2021 · 7 comments
Closed

The number of channels should be encoded in the QOI header #16

ThomasMertes opened this issue Nov 25, 2021 · 7 comments

Comments

@ThomasMertes
Copy link

The function
qoi_read(const char *filename, int *out_w, int *out_h, int channels)
needs the number of channels as parameter. This should not be needed.
The QOI file should know with which number of channels it was encoded.

To solve this the header could be improved to contain also the number of channels.
BTW.: The header should also contain some file format version. This allows future improvements.

@ThomasMertes ThomasMertes changed the title The number of channels should be encoded in the QOI header #2 The number of channels should be encoded in the QOI header Nov 25, 2021
@phoboslab
Copy link
Owner

From my point of view (e.g. for use in games where textures get uploaded to the GPU) you'd rather want to specify the number of channels that you want the decoded pixels in - no matter what is actually stored in the file. For simplicity's sake QOI always stores data as RGBA anyway.

Granted, a separate channel count would also allow for tighter compression of RGB data when we can ignore Alpha, but that's a different image format. Not what I was after.

@ThomasMertes
Copy link
Author

I did not recognize that QOI always stores data as RGBA. I expected that it allows files with and without Alpha. I guess that images without Alpha are quite common. It would be interesting to find out how much can be saved by omitting Alpha. Maybe in average the resulting QOI files become smaller than a corresponding PNG.

@richgel999
Copy link

Yes, images without alpha channels are extremely common. If I don't know if the input image has an alpha channel, I'll have to scan all the pixels/texels and look at all the alphas to see if anything is <255, which is going to slow down loading.

@KamilaBorowska
Copy link

KamilaBorowska commented Nov 26, 2021

I imagine you can have 1% savings by removing has_a from QOI_COLOR (I modified qoi implementation to count how often QOI_COLOR occurs). However, this comes at the cost of losing byte alignment property of QOI which means lower performance.

Also, something I noticed during testing - because QOI is byte aligned it's really friendly with compression. You can have 15%-20% savings by compressing your QOI images with GZIP or 30% savings with Brotli.

@phoboslab
Copy link
Owner

The main saving of knowing an image is just RGB would be in QOI_DIFF_24, where we could then use 20 bits on RGB (i.e. 7,7,6) allone. I tried this during development and it does help, but imho not enough to justify the added complexity.

@ThomasMertes
Copy link
Author

When I started to create a Seed7 version of QOI I discovered the "channels" parameter of the function qoi_read(). I got the wrong impression that encoding and decoding of QOI needs to use the same "channels" parameter to work correctly. I expected that my decoding function would also need this "channels" parameter. At that time I stopped my implementation and filed this issue. I planned to continue after the number of "channels" had been added to the header. The discussion here motivated me to take a deeper look (and to continue with the Seed7 version of the QOI decoding function).

The "channels" parameter has actually nothing to do with the QOI format (in a QOI file), Instead it determines the way the image is stored in memory (to be processed afterwards). In other words: My version of the QOI decoding function works without "channels" parameter (it directly creates an image object). So from my point of view a "channels" information in the header is not needed. I would even ignore an informative "channels" information in the header.

My conclusion is: Regarding the "channels" information the header can be left unchanged (without channels). But a versioning of the header would still make sense.

@phoboslab
Copy link
Owner

This is now implemented. See #37 for more info.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants