Pixel byte manipulation question

I’ve been investigating the SDL data structure and I’m thinking some of
my questions will be more quickly dealt with if I just ask here:

Is the combination of all the used RGBA masks guaranteed to be aligned
to the right of the Uint32 regardless of endianness (eg: 24 bit RGB/BGR
is always 0x00FFFFFF, 16Bit is always 0X0000FFFF/0x00007FFF)?

Is the order of the colorkey applied the same or is there a difference
in the operation?

Any clues would be much appreciated :)___________________________________________________________
The all-new Yahoo! Mail goes wherever you go - free your email address from your Internet provider. http://uk.docs.yahoo.com/nowyoucan.html

the mask tell you what part of the uint32 is RGBA. it is not the
same on all machines, it is determined by the graphics hardwhere. i
test my app on 3 different machines and each have a different RGBA mask.

mattOn Oct 1, 2007, at 4:24 PM, Paul Duffy wrote:

I’ve been investigating the SDL data structure and I’m thinking
some of
my questions will be more quickly dealt with if I just ask here:

Is the combination of all the used RGBA masks guaranteed to be aligned
to the right of the Uint32 regardless of endianness (eg: 24 bit RGB/
BGR
is always 0x00FFFFFF, 16Bit is always 0X0000FFFF/0x00007FFF)?

Is the order of the colorkey applied the same or is there a difference
in the operation?

Any clues would be much appreciated :slight_smile:


The all-new Yahoo! Mail goes wherever you go - free your email
address from your Internet provider. http://uk.docs.yahoo.com/
nowyoucan.html


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

the mask tell you what part of the uint32 is RGBA. it is not the
same on all machines, it is determined by the graphics hardwhere. i
test my app on 3 different machines and each have a different RGBA
mask.

That’s not the part I’m wondering about, I know the mask /order/ is
different for different computers (and actually different file formats
on load) and that at some point the bytes have to be ordered in a way
the hardware expects.

What I need to know is, can I expect the mask and colorkey data be in
the rightmost portion of a Uint32 regardless_of_platform? I know the
order could be RGBA/BGRA/ARGB/ABGR or 565/3553/RGB/BGR. However, some
of the data is stored with bitshifting which doesn’t give a monkeys
about Endianness and just puts the bits in a specific position, eg. the
rightmost bit, whether that’s the highest, lowest or middling bit which
means that regardless of the ordering, some data will end up in the
same bytes of a Uint32 no matter what platform is being used.

So, if a 24 but value is being stored, is it stored in the first or
last 24 bits of the 32 bit integer? If it’s 16 bits, is it stored in
the higher or lower half? Is an 8 bit palette value stored in the first
or last byte of the (still) 32 bit colorkey?

Really, it’s not a question of hardware, it’s a question of how SDL
handles data internally and whether this is consistent.____________________________________________________________________________________
Be a better Globetrotter. Get better travel answers from someone who knows. Yahoo! Answers - Check it out.
http://answers.yahoo.com/dir/?link=list&sid=396545469

the mask tell you what part of the uint32 is RGBA. it is not the
same on all machines, it is determined by the graphics hardwhere. i
test my app on 3 different machines and each have a different RGBA
mask.

That’s not the part I’m wondering about, I know the mask /order/ is
different for different computers (and actually different file formats
on load) and that at some point the bytes have to be ordered in a way
the hardware expects.

What I need to know is, can I expect the mask and colorkey data be in
the rightmost portion of a Uint32 regardless_of_platform? I know the
order could be RGBA/BGRA/ARGB/ABGR or 565/3553/RGB/BGR. However, some
of the data is stored with bitshifting which doesn’t give a monkeys
about Endianness and just puts the bits in a specific position, eg.
the
rightmost bit, whether that’s the highest, lowest or middling bit
which
means that regardless of the ordering, some data will end up in the
same bytes of a Uint32 no matter what platform is being used.

So, if a 24 but value is being stored, is it stored in the first or
last 24 bits of the 32 bit integer? If it’s 16 bits, is it stored in
the higher or lower half? Is an 8 bit palette value stored in the
first
or last byte of the (still) 32 bit colorkey?

Really, it’s not a question of hardware, it’s a question of how SDL
handles data internally and whether this is consistent.

i am not an SDL developer, only a user, so perhaps someone else could
answer better than i. i believe SDL uses a pixel format that is
closest to the hardware or the graphics driver being used. there
should be a list of available graphics drivers for what ever
platform. i suppose this answer doesnt help you any more than the last.

i am not sure how SDL handles internal surfaces.

are you writing an application with SDL or trying to understand it
more ?

you could look at the source.

mattOn Oct 2, 2007, at 10:45 AM, Paul Duffy wrote:

i am not sure how SDL handles internal surfaces.

are you writing an application with SDL or trying to understand it
more ?

Well, mainly I need the ability to blit arbitrary pixels, and clear by
colorkey regardless of colour depth or platform.

you could look at the source.

I’ve been doing a fair bit of prodding at pixels.c, SDL_Surface.c and
the SDL_image files but it’s quite time consuming. I’ve garnered a fair
bit about how it’s all put together but this last detail’s a bit
heavy-going and I may have to go through everything that does anything
with the data to know what I can and can’t expect e.g. is it permissable
to have the masks r = 0xFF000000, g = 0x00FF0000, b = 0x0000FF00 for a
24 bit RGB image or do the first two bytes have to be zero if no Alpha
mask is present?

Maybe it’ll be more enlightening to look at the screen blitting
functions to see what they expect.

Thanks for replying anyway :o)On Tue, 2007-10-02 at 13:33 -0500, matt hull wrote:

On Oct 2, 2007, at 10:45 AM, Paul Duffy wrote:


To help you stay safe and secure online, we’ve developed the all new Yahoo! Security Centre. http://uk.security.yahoo.com

i am not sure how SDL handles internal surfaces.

are you writing an application with SDL or trying to understand it
more ?

Well, mainly I need the ability to blit arbitrary pixels, and clear by
colorkey regardless of colour depth or platform.

you could look at the source.

I’ve been doing a fair bit of prodding at pixels.c, SDL_Surface.c and
the SDL_image files but it’s quite time consuming. I’ve garnered a fair
bit about how it’s all put together but this last detail’s a bit
heavy-going and I may have to go through everything that does anything
with the data to know what I can and can’t expect e.g. is it permissable
to have the masks r = 0xFF000000, g = 0x00FF0000, b = 0x0000FF00 for a
24 bit RGB image or do the first two bytes have to be zero if no Alpha
mask is present?

The only way I can think of that would allow you to have two bytes of
alpha is to have 64 bit pixels. SDL doesn’t do anything with 64 bit
pixels.

Are you perhaps thinking that the "F"s in the mask represent bytes? If
so, they do not, they represent nybbles (4 bits) not bytes (8) bits. Or
was that just a typo?

Anyway, it is possible to have a pixel laid out with the RGB masks you
listed. Not common, but possible.

Bob PendletonOn Wed, 2007-10-03 at 00:35 +0100, Paul Duffy wrote:

On Tue, 2007-10-02 at 13:33 -0500, matt hull wrote:

On Oct 2, 2007, at 10:45 AM, Paul Duffy wrote:

Maybe it’ll be more enlightening to look at the screen blitting
functions to see what they expect.

Thanks for replying anyway :o)


To help you stay safe and secure online, we’ve developed the all new Yahoo! Security Centre. http://uk.security.yahoo.com


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


±-------------------------------------+

i suggest you use the pixel mask and not hard code it. i tried to
base my application on endianness and it fails when tested on a
graphics driver that uses a different format. sure you could specify
that you want a certain format i think, but then SDL will internally
convert it during run time, which my be a speed hit.

mattOn Oct 2, 2007, at 6:35 PM, Paul Duffy wrote:

On Tue, 2007-10-02 at 13:33 -0500, matt hull wrote:

On Oct 2, 2007, at 10:45 AM, Paul Duffy wrote:

i am not sure how SDL handles internal surfaces.

are you writing an application with SDL or trying to understand it
more ?

Well, mainly I need the ability to blit arbitrary pixels, and clear by
colorkey regardless of colour depth or platform.

you could look at the source.

I’ve been doing a fair bit of prodding at pixels.c, SDL_Surface.c and
the SDL_image files but it’s quite time consuming. I’ve garnered a
fair
bit about how it’s all put together but this last detail’s a bit
heavy-going and I may have to go through everything that does anything
with the data to know what I can and can’t expect e.g. is it
permissable
to have the masks r = 0xFF000000, g = 0x00FF0000, b = 0x0000FF00 for a
24 bit RGB image or do the first two bytes have to be zero if no
Alpha
mask is present?

Maybe it’ll be more enlightening to look at the screen blitting
functions to see what they expect.

— Bob Pendleton wrote:

Are you perhaps thinking that the "F"s in the mask represent bytes?
If
so, they do not, they represent nybbles (4 bits) not bytes (8) bits.
Or
was that just a typo?

:oD It was a bit late where I am, fortunately the code I’ve done so far
doesn’t make thie mistake.

Anyway, it is possible to have a pixel laid out with the RGB masks
you
listed. Not common, but possible.

Gack. I’ll have to see if the screen blitting functions would accept
such a format, I’d rather avoid having to check the dest/source masks
every time. If the format is reasonably predictable then the worst I
have to do is use some ifdefs to use the appropriate formatting per
platform rather than having to use runtime detection. I’m mainly trying
to avoid doing anything unnecessary that would slow things down.

— matt hull wrote:

i suggest you use the pixel mask and not hard code it. i tried to
base my application on endianness and it fails when tested on a
graphics driver that uses a different format. sure you could specify

that you want a certain format i think, but then SDL will internally

convert it during run time, which my be a speed hit.

Well, that’s why I’m trying to find this out, I’m trying to move data
around fast while sticking as much as I can to what SDL will expect to
be there, hence I’m bothering to use the masks at all, using the SDL
function analogues (SDL_malloc, SDL_memset, etc) and the SDL functions
for creating and freeing surfaces (which do all the checking for you).

However, when it comes to the masks, I sometimes need to know where the
data as a whole is going to be in a 32 bit integer to be separated and
applied to 1-3 bytes (in order) and I want to do that with the least
number of operations possible so if I can do it without having to check
the exact position of the RGB mask than that’s a few less operations
and one less branch.

As it is, I already know that an Alpha mask will only be accepted in
the first or last byte of the pixel for 32 bit and I’m fairly certain
that the pixel applied as-is to the pixels array (at the correct
position) will work so long as it’s all applied in the order that it’s
read and the masks are the same.

I think I’ll look some more into exactly what it is that SDL itself expects.> On Wed, 2007-10-03 at 00:35 +0100, Paul Duffy wrote:

  ____________________________________________________________________________________

Don’t let your dream ride pass you by. Make it a reality with Yahoo! Autos.

Paul Duffy wrote:

Gack. I’ll have to see if the screen blitting functions would accept
such a format, I’d rather avoid having to check the dest/source masks
every time. If the format is reasonably predictable then the worst I
have to do is use some ifdefs to use the appropriate formatting per
platform rather than having to use runtime detection. I’m mainly trying
to avoid doing anything unnecessary that would slow things down.

The format is not predictable, at least if you don’t enforce it and
force SDL do the conversion (this is an option, but will slow down
things if you don’t have to blit MANY pixels one by one). If you blit on
a DisplayFormatted() surface you should consider Rmask, Gmask… Rshift,
Bshift… to do your pixel blitting.

You can find big endian or little endian pixel modes both in big and
little endian machines, this give already 4 different possibility for
EVERY pixel mode, so you got at least 4 different RGBA cases.

Then you have to consider RGB and 15/16bit modes, and consider also that
most system can promote 15bit to 16bit, 16bit to 32bit, 24bit to
32bit… and so on.

I think that to do things the right way you will need a switch with so
many “case” statements than the shift performance penality will be
acceptable :)–
Bye,
Gabry

So, looking at functions like MapRGB et al and assuming that I’m
blitting to a 24bit surface with unknown RGB order, also assuming that
I’m not caring about overwriting pixels I’m going to be writing to in a
second (because I’m clearing by colorkey) and that I’ve taken into
account that the last few pixels of a line need to be dealt with per
byte in case the number of pixels is even/odd:

Could I use *(Uint32 *)pixeladdress = colorkey << 8 ?

Would *(Uint32 *)pixeladdress = colorkey << 16 | colorkey work for 16
bit surfaces?

I’m mostly assuming that bitshifting will work in the same way on a
datablock larger than a byte regardless of endianness as it seems to be
treated this way in at least parts of SDL (the byte order may change but
it’s all moved to the same place by the same method as far as I can
tell) and I’m hoping it holds true across the board as there wouldn’t be
a single branch required if this is so.

Maybe I’m being obtuse, but I’ve worked so far only on Intel hardware.On Wed, 2007-10-03 at 18:22 +0200, Gabriele Greco wrote:

I think that to do things the right way you will need a switch with so
many “case” statements than the shift performance penality will be
acceptable :slight_smile:


All New Yahoo! Mail ? Tired of Vi at gr@! come-ons? Let our SpamGuard protect you. http://uk.docs.yahoo.com/nowyoucan.html

Yep. and when I use them they will be for compile time and sorting the
code appropriate for the architecture.

Anyway, found the answer in that << will actually push in bits from the
left to the right on a little endian system and right to left on a big
endian system (I make it sound like the hardware abstraction in C is a
bad thing) so:

a Uint32 is given the values 15 << 16 | 235 << 8 | 124

If passed to a 4 byte array as *(Uint32 *)arr = i, the values in the
array will be 124, 235, 15, 0 in a little-endian system whereas in a
big-endian system they will be 0, 15, 235, 124.

So, assuming the RGBmask and colorkey are of the appropriate values (and
they should be) all that’s required to pass the complete value in this
way on a big-endian system is << 8 whereas a little endian system will
require some byte-swapping too.

Of course, I could just use bit-shifting to pass the appropriate values
one at a time but that would require a lot of checking (at least with 16
bit values) of the RGB masks which I’m trying to avoid.On Wed, 2007-10-03 at 13:49 -0500, matt hull wrote:

Anyway, it is possible to have a pixel laid out with the RGB masks
you
listed. Not common, but possible.

Gack. I’ll have to see if the screen blitting functions would accept
such a format, I’d rather avoid having to check the dest/source masks
every time. If the format is reasonably predictable then the worst I
have to do is use some ifdefs to use the appropriate formatting per
platform rather than having to use runtime detection. I’m mainly
trying
to avoid doing anything unnecessary that would slow things down.

ifdef’s should be avoided. those are only for compile time.


Yahoo! Messenger - with free PC-PC calling and photo sharing. http://uk.messenger.yahoo.com

Anyway, it is possible to have a pixel laid out with the RGB masks
you
listed. Not common, but possible.

Gack. I’ll have to see if the screen blitting functions would accept
such a format, I’d rather avoid having to check the dest/source
masks
every time. If the format is reasonably predictable then the worst I
have to do is use some ifdefs to use the appropriate formatting per
platform rather than having to use runtime detection. I’m mainly
trying
to avoid doing anything unnecessary that would slow things down.

ifdef’s should be avoided. those are only for compile time.

Yep. and when I use them they will be for compile time and sorting the
code appropriate for the architecture.

Anyway, found the answer in that << will actually push in bits from
the
left to the right on a little endian system and right to left on a big
endian system (I make it sound like the hardware abstraction in C is a
bad thing) so:

a Uint32 is given the values 15 << 16 | 235 << 8 | 124

If passed to a 4 byte array as *(Uint32 *)arr = i, the values in the
array will be 124, 235, 15, 0 in a little-endian system whereas in a
big-endian system they will be 0, 15, 235, 124.

that is an incorrect assumption. i tried that myself and had to fix
my application. you need to use the mask. the system endianness
doesnt tell all.

So, assuming the RGBmask and colorkey are of the appropriate values
(and
they should be) all that’s required to pass the complete value in this
way on a big-endian system is << 8 whereas a little endian system will
require some byte-swapping too.

Of course, I could just use bit-shifting to pass the appropriate
values
one at a time but that would require a lot of checking (at least
with 16
bit values) of the RGB masks which I’m trying to avoid.

how often are you changing your pixels ? is it possible you could
set up your palette or surface during an initialization?

mattOn Oct 3, 2007, at 4:07 PM, Paul Duffy wrote:

On Wed, 2007-10-03 at 13:49 -0500, matt hull wrote:

that is an incorrect assumption. i tried that myself and had to fix
my application. you need to use the mask. the system endianness
doesnt tell all.

Actually, as I’m entirely using source data which has already had its
ordering defined by the RGB mask at this stage that pretty much is the
be-all and end-all. With the destination RGB mask being defined by the
source mask and the ordering in which the colorkey is stored being
defined by the RGB mask, I can very much rely on not having to worry
about reordering bits or bytes at this stage. My main angle here is
image manipulation which will involve a lot of pixel copying and a lot
of clearing with the colorkey.

Having looked through various functions for SDL, it’s seems clear that
SDL itself expects any mask combination for any pixel value of less than
32 bits to be in the LSB and upwards and that any attempt to have an RGB
mask starting at the MSB will be problematic within SDL itself.

I’m also getting the impression from SDL_FillRect that the ordering of
the bytes per pixel in the pixels array is entirely dependent on the
endianness of the system (in that the LSB of the RGBA mask in a little
endian system will always be first in a 4 bit pixel in a surface and so
on) so what I don’t wan’t to do is do any byte swapping when doing a
colour fill (although all that stuff re. hardware surfaces and 4 or 1
bit pixels can go as I won’t be using any). I can also see some cases
for optimising over SDL_memset4.

how often are you changing your pixels ? is it possible you could
set up your palette or surface during an initialization?

In some cases yes, but there are going to be cases in which I’m going to
be blitting at a given frame-rate which means that functions such as the
default SDL putpixel (as seen in the docs) are going to slow things down
as they check the colour depth and RGB mask per pixel while I would
prefer to do so per frame.

As above with the rectangle filling I already have some prior knowledge
of what I’m going to be dealing with so there’s a lot of things I don’t
need to check, or check as often, and there are places I can optimise
for a slightly less broad support of platforms.On Wed, 2007-10-03 at 18:17 -0500, matt hull wrote:


The all-new Yahoo! Mail goes wherever you go - free your email address from your Internet provider. http://uk.docs.yahoo.com/nowyoucan.html