-
Notifications
You must be signed in to change notification settings - Fork 328
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
Possible Signed Overflow for Luma Chunks #254
Comments
According to this SO answer the behavior is not "undefined" but "implementation defined". I guess the Also, it is my understanding that the reason that signed integer overflow is undefined is that 50 years ago there existed some CPUs that didn't use twos-complement representation. Interestingly there is a proposal to abandon anything but twos-complement representation in C. So I believe this is a non-issue. If you can find any platform where qoi.h does compile but signed integer overflow does not wrap (or more specifically: the demotion of int to char does not do the right thing), I may reconsider :) Edit: wait, sorry, I think I totally misunderstood the actual issue. For the encoder to produce a QOI_DIFF with an invalid I agree that this probably requires some documentation, though. |
I could be wrong but that SO answer relies on a different behaviour: The literal I did actually double check the standard (C99 draft in this case), but my reading was mostly inconclusive: According to Chapter Chapter
With the quote:
However, it is worth noting that the signedness of Finally, it seems that some clever standards lawyering is actually happening according to this SO answer. So, if I'm reading this correctly, "small integers" are essentially promoted to Sorry, I guess this became a bit long winded. Frankly, I actually agree with you that we would all be better of if that proposal would be accepted and all of this type promotion nonsense went away. That said however, would you mind if I added a pull request adding a comment above these expressions with something along the lines |
Very interesting. Thanks for looking into the C standard! Pardon my ignorance and bikeshedding but:
does it, though? What's the alternative in |
Hmm, your right, upon re-reading the SO answer above, I guess it's more of "may rely on type promotion to
This doesn't change the output (for most platforms), but does make the type promotions intent explicit. I wasn't actually considering alternatives though, to be absolutely honest, but that's obviously something to think of. My first implementation was actually using ints (or
Original:
Using
(This output is all from Looking at these samples, it seems like using Saturation arithmetic could be interesting, but it's slightly beyond me to test that quickly right now at least. That said, I personally like this alternative better (for both Luma and Diff chunks actually), since I personally thinks it's a bit more "realistic" to look at values close together than wrapping all the way from white to black or vice-versa, even if that is pretty common for synthetic files. |
Starting with https://en.cppreference.com/w/c/23 integers are represented as twos complement.
I suspect (without testing) these should be catched by |
Hello,
I've spent a bit of time implementing my own version of the QOI encode/decoder
using Rust. The intent was that the output would binary compatible with that of
the reference decoder. During testing however, I did notice a small discrepancy
between in (at least) one of the testfiles (
qoi_test_images/testcard.qoi
).After some debugging, I noticed that I handled the Diff/Luma chunks incorrectly.
After fixing that though, Rust noticed that the expression to compute the Luma
differences can actually overflow:
For the testfile above, this yields the output:
Which really should overflow the
vr - vg
expression. Then again, maybe I'mmissing some obscure integer promotion rule? I even tried adding sanitizers to
the QOI build files when generating this:
But they didn't trigger on this, which makes me unsure whether it is "really" a
bug. Either way, given that signed overflow is typically regarded as undefined
behavior according to the C/C++ standards, I think that this should be changed,
or at least documented with a mild warning above the statements.
The text was updated successfully, but these errors were encountered: