Closed 0xEAB closed 1 year ago
Well; in that case it seems to me SDL is wrong.
Creates confusion:
For consistency, it would be difficult to explain why rgbaf32 is reversed (or conversely, if rgba8 was reversed but not rgbaf32). There can be an explanation for why rgba8 would be AA BB GG RR in memory byte order, but not for floats.
OpenGL situation, I'd say GL_UNSIGNED_BYTE is very much common rather than something endian-defined.
Cairo is stored in native order, calls the format CAIRO_FORMAT_ARGB32
else I guess people would get confused. So its identifier name is called based upon the layout in memory. I'm not sure what is the benefit of storing in that order to be honest. But still the constant name gives the byte order in typical little endian system.
stb_image.h gives RGBA order in memory when asking "4 channels"
Freeimage uses BGR[A] pixel layout for us
Using a byte by byte memory order to label the pixel layout, then FreeImage uses a BGR[A] pixel layout under a Little Endian processor (Windows, Linux) and uses a RGB[A] pixel layout under a Big Endian processor (Mac OS X or any Big Endian Linux / Unix).
which means it also invert order for 16-bit and 32-bit float components?
What I intended for gamut is that it would be "R then G then B then A" in memory order, anything else will inevitably create confusion in my opinion. Compare length of discussion in Skia vs SDL.
I'm surprised by the extent to which libraries do support ABGR layout though, but that is a separate question. Not sure why it would be more efficient, in what situations. Windows GDI takes BGR order, and .bmp, but that's not a very important use case nowadays?
Thank you for the detailed response. I feel flattered by all the effort put into answering this. I don’t think this gives it its due, but I’m not sure what more I could add of value than “thanks a lot!”
Thanks :) A separate issue would be: should Gamut support bgra8 / argb8 / abgr8 ? What is your use case?
TL;DR to load data for 2D software rendering.
--
While I currently use SDL2 to bring my images to screen, I’d like to eventually replace it with a more modest solution. So I’d prefer not to depend on it for image decoding as well. That brought me to Gamut.
For my use case it’s enough to understand which image formats are expected resp provided by the libraries I use.
Now that I know that I can expect Gamut to produce pixels as [R, G, B, A]
, I have essentially all information that I needed.
My code loads the image using Gamut, copies the data to GC memory for further use and disposes of the Gamut object. I don’t rely on Gamut for any sort of image manipulation. (I might add screenshot functionality that uses Gamut to save the image in the future.)
I currently don’t see much value in Gamut supporting other 8-bit channel R/G/B/A pixel formats. It’s quite easy to convert them in user code if necessary. And while I can speak for my own code only, I think it’s easier when you only have to deal with one pixel format (or a few) throughout the codebase.
The use-case for the ABGR/XBGR formats that I could see is writing colors as integer literals in little-endian code,
e.g. 0xFF__CC_33__44
or 0x__CC_33_44
. What that’s relevant in real-world code is a different question however…
Interverting bytes should be almost free vs memory access. Yes indeed less pixel formats simplify things here.
Also I’ve started to experiment with this change:
- alias Pixel = uint;
+ alias Pixel = ubyte[4];
And I think it makes my code more comprehensible (while it seems to have no effect on codegen).
…until I accidentally sped up my code with this change:
- //alias Pixel = uint;
- //const(ubyte[]) pxSrc = (cast(const(ubyte)*)&src[idx])[0 .. 4];
- //immutable alphaSrc = pxSrc[3] | (pxSrc[3] << 8);
- immutable alphaSrc = src[idx][3] | (src[idx][3] << 8);
+ const(Pixel) pxSrc = src[idx];
+ immutable alphaSrc = pxSrc[3] | (pxSrc[3] << 8);
I’d think, we can close this, right?
SDL2 and Gamut don’t seem to agree on their interpretation of RGBA8 (or “RGBA8888” in SDL). When you consider one to be
0xRR_GG_BB_AA
the other appears like0xAA_BB_GG_RR
.Reproducer
Test image
Resolution: 12×1 Format: PNG-8
Link
Findings
What Gamut calls
PixelType.rgba8
isSDL_PIXELFORMAT_ABGR8888
in SDL2.