-
Notifications
You must be signed in to change notification settings - Fork 7.8k
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
stb_image: Fix 16bits PNM images endianness handling #1710
base: master
Are you sure you want to change the base?
Conversation
16bits binary PNM images are supposed to use big-endian, even though it wasn't specified in the first versions of the format.
What do you mean it assumes platform native is little-endian? |
From line Line 4827 in 2e2bef4
instead of something like:
There might be an actual check somewhere that I missed though. |
But the conversion code is not big-endian to little-endian, it's big-endian to platform native. Big-endian to little-endian would just swap the bytes, which is not what this code does. |
I might not understand what "platform-native" means in that context then. And admittedly, I don't really know how the I only found that comment after a search for "endian" to see if I was missing something. |
Do you understand what the code you added is doing, or did you just copy-paste it without understanding it? |
Like, you summarized the existing code as
but I don't know why you think that's an accurate summary, when the accurate summary is
I'm trying to understand why you think this code converts to little-endian when there's 0 little-endianness code in there. |
Big endian is "the most significant byte first", little endian is "the least significant byte first". For a 16 bits unsigned integer, it means that swapping the two bytes convert from one to the other. I'm not sure about your definition of "platform-native", but if it means "the way the CPU stores values in memory", then
(granted, on modern computers big-endian CPUs probably aren't used anymore). If "platform-native" means something else, my comment about Which, given the uint16 values stored in the uint8 array |
Ok, so you don't understand the code you copy-pasted. There is no byte-swapping in the code. It does not convert big-endian to little-endian. It converts big-endian to whatever the natural byte order of the machine is. If the machine is little-endian, it effectively swaps the bytes; if it's big-endian, it has no effect. |
To explain, little endian means that bytes are in order of increasing significance and big endian that bytes are in decreasing order of significance. For uint16 specifically, little-endian means that the uint16 value implied by two bytes is One way to convert between the two is to swap bytes around manually and then read the value using a native CPU load instruction (which interprets the bytes as either big- or little-endian depending on the CPU architecture and possibly operating state). But that's not what that code is doing. The code in question manually assembles a uint16 value by reading the two bytes and putting them together with the desired significance (in this case big-endian). There is no need to know whether the host platform is little or big endian when doing it this way. Big endian means that the uint16 value is given by |
Sorry, but I totally understand the code I wrote. Especially since I write this kind of thing since the 90's. Please stop that. When using pointer arithmetic and type casting in C, you don't need to use a "native CPU load instruction". None is used in your code, none is used in mine. At the end of the day, loading a 16 bits PNM file with I can send you an example image if you need. |
Loading a 16-bit PNM with the big-endian conversion path used for PNGs should be completely fine, this whole discussion is just about there not being any assumption in the conversion path about running on a little-endian platform. |
Ok, so after a good night's sleep... you are right. It's so obvious now that it is embarrassing. Sorry about that. |
No worries, I mostly just wanted to make sure I wasn't missing anything. |
16bits binary PNM images are supposed to use big-endian, even though it wasn't specified in the first versions of the format.
The
// convert the image data from big-endian to platform-native
comment is copied from thestbi__create_png_image_raw()
function. There doesn't seem to be any code there to check what "platform-native" is, it just assumes little-endian, so I did the same.I can add a small check at both places to determine if the conversion is needed if you want.