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

Create a water-proof specification #27

Closed
ikskuh opened this issue Nov 26, 2021 · 5 comments
Closed

Create a water-proof specification #27

ikskuh opened this issue Nov 26, 2021 · 5 comments

Comments

@ikskuh
Copy link

ikskuh commented Nov 26, 2021

I implemented the Zig implementation of Qoi and ai made it a clean room implementation, thus testing the specification in qoi.h.

Some problems i noticed in both the implementation and the description: While the qoi format assumes big endian byte order for a lot of things, the implementation is only suitable to run on little endian machines.

Also, the bit order is unclear for cross-byte fields:

qoi/qoi.h

Lines 128 to 134 in dd0b04b

QOI_DIFF_24 {
u8 tag : 4; // b1110
u8 dr : 5; // 5-bit red channel difference: -15..16
u8 dg : 5; // 5-bit green channel difference: -15..16
u8 db : 5; // 5-bit blue channel difference: -15..16
u8 da : 5; // 5-bit alpha channel difference: -15..16
}

dr for example crosses the first byte boundary, and it is unspecified how the bits are ordered here. To me, it was unclear if the 128-bit or the 1-bit of the second byte will provide the additional bit. It's also unclear which bit the bit is in the final u5 value.

A good alternative that makes this unmistakable clear would be something like this:

|                                 QOI_DIFF_24                                 |
|        Byte + 0         |        Byte + 1         |        Byte + 1         |
|  7  6  5  4  3  2  1  0 |  7  6  5  4  3  2  1  0 |  7  6  5  4  3  2  1  0 |
|-------------------------|-------------------------|-------------------------|
|  1  1  1  0 r4 r3 r2 r1 | r0 g4 g3 g2 g1 g0 b4 b3 | b2 b1 b0 a4 a3 a2 a1 a0 |

With:
  r4...r0 forming the red channel difference between -15..16
  g4...g0 forming the green channel difference between -15..16
  b4...b0 forming the blue channel difference between -15..16
  a4...a0 forming the alpha channel difference between -15..16

I'm happy to create a PR for this change

@phoboslab
Copy link
Owner

I like this formatting! However, I'm about to open another issue to discuss some breaking changes. Please wait a bit with the PR until we're certain what exactly we want to specify :)

@oscardssmith
Copy link

also fyi, I'm currently working on a Julia implementation. I'll post it here once I'm done.

@ikskuh
Copy link
Author

ikskuh commented Nov 26, 2021

I like this formatting! However, I'm about to open another issue to discuss some breaking changes. Please wait a bit with the PR until we're certain what exactly we want to specify :)

Oh, how do we get updates on what changed? Is there an announcement?

@phoboslab
Copy link
Owner

No announcement yet. I'll write one once we've come to a conclusion! Discussion here: #28

@ikskuh
Copy link
Author

ikskuh commented Nov 26, 2021

Another thing that should be specified:
Using overflow in the deltas should be a explicit use case and the delta encoding should not clamp but wrap. This allows for single-byte switches between black and white for example

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

3 participants