16bpp formats

Simple question, but I couldn’t find it in a quick search of to docs or
code.

How can I determine the pixel format for a 16bpp display at run time?
Also would I need to deal with big vs little endian?

I’m trying to write a function that will convert a set or raw r,g,b
values to a single 16 bit value optimized for the current display.

			-fjr

“Frank J. Ramsay” wrote:

Simple question, but I couldn’t find it in a quick search of to docs or
code.

How can I determine the pixel format for a 16bpp display at run time?
Also would I need to deal with big vs little endian?

I’m trying to write a function that will convert a set or raw r,g,b
values to a single 16 bit value optimized for the current display.

                            -fjr

Look at the format member of the SDL_Surface structure. It has all the
pixel format information available there.–
-Sam Lantinga, Lead Programmer, Loki Entertainment Software

“Frank J. Ramsay” wrote:

Simple question, but I couldn’t find it in a quick search of to docs or
code.

How can I determine the pixel format for a 16bpp display at run time?
Also would I need to deal with big vs little endian?

I’m trying to write a function that will convert a set or raw r,g,b
values to a single 16 bit value optimized for the current display.

Why? There are already functions called ‘SDL_MapRGB’ and ‘SDL_GetRGB’
(the former anyway, the latter doesn’t appear to be officially
documented and doesn’t seem to work on SDL 0.10.0 even though it is in
the source file ‘SDL_pixels.c’). And these are all far more general
than what you’re trying to do.

But if you choose to ignore my advice and go ahead with trying to
reinvent the wheel, you can try fiddling with the entries in the
’format’ member of an SDL_Surface. There are several fields inside the
format structure that are of interest. These are the Xmask, Xshift, and
Xloss (where ‘X’ is either R, G, or B, e.g. ‘Rmask’). You shift
component X by Xloss, and right shift it by Xshift, then get the logical
OR of all of the components. To reverse the process (i.e. get component
X of a pixel), get the logical-AND of the pixel with Xmask, shift right
by Xshift, and then shift left by Xloss. These fields in the format
structure will have values appropriate to your endian. And this process
will work for any high or true color pixel format. But I don’t see any
advantage to doing this yourself rather than letting the two functions
above do it for you…–

| Rafael R. Sevilla @Rafael_R_Sevilla |
| Instrumentation, Robotics, and Control Laboratory |

College of Engineering, University of the Philippines, Diliman

“Rafael R. Sevilla” wrote:

“Frank J. Ramsay” wrote:

Simple question, but I couldn’t find it in a quick search of to docs or
code.

How can I determine the pixel format for a 16bpp display at run time?
Also would I need to deal with big vs little endian?

I’m trying to write a function that will convert a set or raw r,g,b
values to a single 16 bit value optimized for the current display.

Why? There are already functions called ‘SDL_MapRGB’ and ‘SDL_GetRGB’

I saw that function earlier but according to the comment in SDL_video.h
SDL_MAPRGB “Maps a RGB value to a 32-bit pixel in a given format” Which
seems to mean it maps it to 32-bit RGBA, RBGA, etc. and not a 16-bit
one.
If I’m wrong about this great, it will save me a lot of work.

(the former anyway, the latter doesn’t appear to be officially
documented and doesn’t seem to work on SDL 0.10.0 even though it is in
the source file ‘SDL_pixels.c’). And these are all far more general
than what you’re trying to do.
Yes, I am trying to do something very specific.

But if you choose to ignore my advice and go ahead with trying to
reinvent the wheel, you can try fiddling with the entries in the
’format’ member of an SDL_Surface. There are several fields inside the
format structure that are of interest. These are the Xmask, Xshift, and
Xloss (where ‘X’ is either R, G, or B, e.g. ‘Rmask’). You shift
component X by Xloss, and right shift it by Xshift, then get the logical
OR of all of the components. To reverse the process (i.e. get component
X of a pixel), get the logical-AND of the pixel with Xmask, shift right
by Xshift, and then shift left by Xloss. These fields in the format
structure will have values appropriate to your endian. And this process
will work for any high or true color pixel format. But I don’t see any
advantage to doing this yourself rather than letting the two functions
above do it for you…

Thanks for the info, I was just going through the structure of
SDL_PixelFormat
to try and figure out what each of the components represents.

			-fjr

Why? There are already functions called ‘SDL_MapRGB’ and ‘SDL_GetRGB’
(the former anyway, the latter doesn’t appear to be officially
documented and doesn’t seem to work on SDL 0.10.0 even though it is in
the source file ‘SDL_pixels.c’). And these are all far more general
than what you’re trying to do.

I just ran an experiment trying to use SDL_GetRGB and it doesn’t work
right. I’ve got a 16 bpp display and I’m trying to make a 65536 entry
table for darkening the pixel and one for lightening. It works if I
examine the format structure elements to recover the r,g,b components,
but not if I use SDL_GetRGB. Maybe that’s why it is undocumented? In
this code segment below the commented out r,g,b computation works, but the
SDL_GetRGB yields strange color artifacts like the shifts and masks are
off…

    rs=thescreen->format->Rshift-thescreen->format->Rloss+8;
    gs=thescreen->format->Gshift-thescreen->format->Gloss+8;
    bs=thescreen->format->Bshift-thescreen->format->Bloss+8;
    rm=thescreen->format->Rmask;
    gm=thescreen->format->Gmask;
    bm=thescreen->format->Bmask;

    for(i=0;i<65536;++i)
    {
            SDL_GetRGB(i,thescreen->format,&r,&g,&b);

/*
r=((i&rm)<<8)>>rs;
g=((i&gm)<<8)>>gs;
b=((i&bm)<<8)>>bs;
/
darker[i]=SDL_MapRGB(thescreen->format,r
3>>2,g3>>2,b3>>2);
if(r>128 && g>128 && b>128)
lighter[i]=SDL_MapRGB(thescreen->format,r+255>>1,g+255>>1,b+255>>1);
else
lighter[i]=i;
}

This code was taken from my sdlshanghai game.
http://www.xdr.com/dash/linux.html