[cairo] ARGB, BGRA, RGBA mess
Ned Konz
ned at squeakland.org
Fri Jan 14 11:46:36 PST 2005
On Thursday 13 January 2005 2:41 pm, Bill Spitzak wrote:
> In addition having "RGBA" describe anything other than the order of
> bytes in memory is pretty useless if you want to describe data larger
> than bytes, such as 16-bit or float or half (16-bit floats).
I think that the problem comes from the distinction between the *pixel format*
(the layout of *bits* in a pixel *word*) and the *serialization format* (how
you would stream the pixels as a series of bytes).
In the cases where the number of bits in each component happens to be 8, it's
tempting and efficient to use the bytes representing the pixel words as they
stand in memory.
But in general (that is, except for serialization), we don't deal with bytes,
we deal with pixels.
The really interesting operations are the operations on pixels; these have to
know where the components are in the pixel words, but they don't (or
shouldn't, anyway) care about the exact placement of those *bits* in the
pixel *words*.
Just as in other cases (RPC, file formats, external APIs), byte ordering is
only interesting at the edges of our system where we have to communicate with
other systems. And then endianness and byte ordering becomes significant.
If you look at the cairo code, there are masks and shifts that represent
placement of components inside pixel words.
If we want these masks and shifts to remain as constants (which we probably
do, considering that the code is much more efficient in that case) then we
have to do (at least) one of several things to deal with the possible
mismatches:
(1) duplicate every routine that has to deal with individual components of
pixel words for each possible layout of components inside the pixels (i.e.
separate versions for ARGB, RGBA, etc.)
(2) provide translation routines where necessary so that internal buffers can
be serialized or handed to other APIs
If we don't want the duplication of code in (1), then we have to provide
translation as soon as we need more than one format for external systems.
If there is only one internal layout for each word format that we care about,
(for instance, if we always want the bytes to be laid out as A, R, G, B when
we have 32-bit words with 8-bit components) then we can change the Cairo (and
libpixman?) code so that the field mask and shift constants are dependent on
native endianness (using conditional macros in the headers).
But it sounds like we need more than a single layout for various external
systems, anyway; wouldn't it be easier to pick a single in-memory layout for
each format (i.e. only one way to represent ARGB with 8-bit components in
in-memory buffers) and then provide separate utility routines to scramble or
copy bytes and bits into other formats?
I can't see much use in fiddling with byte ordering unless you're dealing with
external systems or libraries. After all, if you're dealing with code that
only deals with libcairo, then you can use the masks and shifts from the
cairo (or libpixman?) headers.
--
Ned Konz
http://bike-nomad.com/squeak/
More information about the cairo
mailing list