Converting image colormap data to RGB data

Good evening. I’ve been unable to find any documented functions for
converting image data with colormap to RGB. I’m looking for something
equivalent to this code (but hopefully more efficient):

if ((pData = malloc(j = image->w * image->h * 3)) == NULL)
{
    ...
}

for (pDest = pData,
     i = j / 3,
     pColors = image->format->palette->colors,
     pSrc = image->pixels;
 i > 0;
 i--, pSrc++)
{
*pDest++ = pColors[*pSrc].r;
*pDest++ = pColors[*pSrc].g;
*pDest++ = pColors[*pSrc].b;
}

Am I missing an existing function??

Thanks!

Derrell

Good evening. I’ve been unable to find any documented functions for
converting image data with colormap to RGB.

Stuff your colormapped data into a colormapped surface, or use
SDL_CreateRGBSurfaceFrom() if you already have the data somewhere.
Then create a new RGB surface of the format you are interested in, and
copy the image over.

Or just use SDL_image if your data is in a common file format

“Mattias Engdeg?rd” writes:

Stuff your colormapped data into a colormapped surface, or use
SDL_CreateRGBSurfaceFrom() if you already have the data somewhere.
Then create a new RGB surface of the format you are interested in, and
copy the image over.

Great! I’m much closer now, but the order of bytes pointed to by
’pixels’ is now BGR instead of RGB. I’ve now replaced this working
(but inefficient) code:

if ((pData = malloc(j = image->w * image->h * 3)) == NULL)
{
    ...
}

for (pDest = pData,
     i = j / 3,
     pColors = image->format->palette->colors,
     pSrc = image->pixels;
 i > 0;
 i--, pSrc++)
{
*pDest++ = pColors[*pSrc].r;
*pDest++ = pColors[*pSrc].g;
*pDest++ = pColors[*pSrc].b;
}

with this more efficient code that (erroneously?) creates BGR instead
of RGB:

if ((newImage = SDL_CreateRGBSurface(SDL_SWSURFACE,
				 image->w, image->h,
				 24, 0, 0, 0, 0)) == NULL)
{
fprintf(stderr, "Could not allocate new surface for image\n");
exit(1);
}

SDL_BlitSurface(image, NULL, newImage, NULL);

newImage->pixels now has the bytes in BGR order instead of RGB. What
am I doing wrong?

BTW, the original “image” data comes from IMG_Load(“test.gif”) and I
need to display it in RGB mode rather than in the colormap’ed mode
it’s received in.

Thanks in advance!

Derrell

if ((newImage = SDL_CreateRGBSurface(SDL_SWSURFACE,
image->w, image->h,
24, 0, 0, 0, 0)) == NULL)
[…]

newImage->pixels now has the bytes in BGR order instead of RGB. What
am I doing wrong?

You didn’t tell it how to arrange the components (you passed zeroes as
the {RGBA}masks), so it just made up something for you. If you want
the R, G, B components to come in that order in memory, use

new_image = SDL_CreateRGBSurface(SDL_SWSURFACE, image->w, image->h, 24,
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
0xff0000,
0x00ff00,
0x0000ff,
#else
0x0000ff,
0x00ff00,
0xff0000,
#endif
0);

BTW, the original “image” data comes from IMG_Load(“test.gif”) and I
need to display it in RGB mode rather than in the colormap’ed mode
it’s received in.

To display something in SDL, you just copy it to the display with
SDL_BlitSurface(), which preserves colours (if possible), and does
the conversion for you. But if you want the image in your particular
format (packed 24-bit format in R, G, B memory order), use the above.