# Can't save .bmp in RGBA format

This topic is 3612 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I'm writing custom Save/LoadBMP functions to save/load SDL_Surface to/from .bmp in RGBA format, which I need for antialiasing sprite rotation later on. Right now I'm working on the save function but I don't get it to work. First I tried to write the BITMAPHEADER***(Both with BITMAPV4HEADER(Specially for the RGBA format) and BITMAPINFOHEADER) structs as saving method which didn't work, probably because it stored integer members in big-endian which the valid ones are in little-endian. Then I modify the SDL_SaveBMP from it's source(Copying it ofcoarse). First I tried with the BITMAPINFOHEADER info header format as it was orginally but it didn't work all the way, it only got to display its dimension but you didn't see the image. And so I tried with the V4 info header(BITMAPV4HEADER) and same fault. I'm out of ideas what the problem is to make this work so I wonder if you know why it doesn't get displayed. Here's that latest code version:
bool SaveRGBA32BMP_RW(SDL_Surface *surf, SDL_RWops *dst, bool freedst)
{
bool success = true;
long fp_offset;
Uint32 *bits;

/* The Win32 BMP file header (14 bytes) */
char   magic[2] = {'B','M'};
Uint32 bfSize;
Uint16 bfReserved1;
Uint16 bfReserved2;
Uint32 bfOffBits;

/* The Win32 BITMAPINFOHEADER struct (40 bytes) */
Uint32 biSize;
Sint32 biWidth;
Sint32 biHeight;
Uint16 biPlanes;
Uint16 biBitCount;
Uint32 biCompression;
Uint32 biSizeImage;
Sint32 biXPelsPerMeter;
Sint32 biYPelsPerMeter;
Uint32 biClrUsed;
Uint32 biClrImportant;
Uint32 bV4CSType;
//	CIEXYZTRIPLE  bV4Endpoints;
long   bV4Endpoints;
Uint32 bV4GammaRed;
Uint32 bV4GammaGreen;
Uint32 bV4GammaBlue;

/* Make sure we have somewhere to save */
if (surf && dst)
{
if (surf->format->BitsPerPixel != 32)
{
success = false;
goto done;
}

const int bw = surf->w * surf->format->BytesPerPixel;

/* Set the BMP file header values */
bfSize = 0;		 /* We'll write this when we're done */
bfReserved1 = 0;
bfReserved2 = 0;
bfOffBits = 0;		/* We'll write this when we're done */

/* Write the BMP file header values */
fp_offset = SDL_RWtell(dst);
SDL_ClearError();
SDL_RWwrite(dst, magic, 2, 1);
SDL_WriteLE32(dst, bfSize);
SDL_WriteLE16(dst, bfReserved1);
SDL_WriteLE16(dst, bfReserved2);
SDL_WriteLE32(dst, bfOffBits);

/* Set the BMP info values */
biSize = 40;	//180;	// 40;
biWidth = surf->w;
biHeight = surf->h;
biPlanes = 1;
biBitCount = surf->format->BitsPerPixel;
biCompression = BI_RGB;
biSizeImage = surf->h * surf->pitch;
biXPelsPerMeter = 0;
biYPelsPerMeter = 0;
biClrUsed = 0;
biClrImportant = 0;
bV4CSType = 0;
//	CIEXYZTRIPLE  bV4Endpoints;
bV4Endpoints = 0;
bV4GammaRed = 0;
bV4GammaGreen = 0;
bV4GammaBlue = 0;

/* Write the BMP info values */
SDL_WriteLE32(dst, biSize);
SDL_WriteLE32(dst, biWidth);
SDL_WriteLE32(dst, biHeight);
SDL_WriteLE16(dst, biPlanes);
SDL_WriteLE16(dst, biBitCount);
SDL_WriteLE32(dst, biCompression);
SDL_WriteLE32(dst, biSizeImage);
SDL_WriteLE32(dst, biXPelsPerMeter);
SDL_WriteLE32(dst, biYPelsPerMeter);
SDL_WriteLE32(dst, biClrUsed);
SDL_WriteLE32(dst, biClrImportant);

SDL_WriteLE32(dst,bV4CSType);
for (int i = 0; i < 9; i++)
{
//	SDL_RWwrite(dst,&bV4Endpoints,4,1);
SDL_WriteLE32(dst,0);
}
SDL_WriteLE32(dst,bV4GammaRed);
SDL_WriteLE32(dst,bV4GammaGreen);
SDL_WriteLE32(dst,bV4GammaBlue);

/* Write the bitmap offset */
bfOffBits = SDL_RWtell(dst)-fp_offset;
if ( SDL_RWseek(dst, fp_offset+10, RW_SEEK_SET) < 0 ) {
SDL_Error(SDL_EFSEEK);
}
SDL_WriteLE32(dst, bfOffBits);
if ( SDL_RWseek(dst, fp_offset+bfOffBits, RW_SEEK_SET) < 0 ) {
SDL_Error(SDL_EFSEEK);
}

/* Write the bitmap image upside down */
bits = (Uint32 *)surf->pixels + (surf->h * surf->pitch);
while (bits > (Uint32 *)surf->pixels)
{
bits -= surf->pitch;

if (SDL_RWwrite(dst, bits, bw, 1) < 0)
{
SDL_Error(SDL_EFWRITE);
break;
}
}

// Get the file size:
bfSize = SDL_RWtell(dst)-fp_offset;
// Set the file pointer back to:
if (SDL_RWseek(dst, fp_offset+2, RW_SEEK_SET) < 0)
{
SDL_Error(SDL_EFSEEK);
}
// Write the file size:
SDL_WriteLE32(dst, bfSize);
// Set it back to the end once again:
if (SDL_RWseek(dst, fp_offset+bfSize, RW_SEEK_SET) < 0)
{
SDL_Error(SDL_EFSEEK);
}

}

done:
if (freedst && dst)
{
SDL_RWclose(dst);
}

return success;
}


Here's the Palette/RGB to RGBA converting function BTW:
SDL_Surface *ConvRGBA32(SDL_Surface *orig)
{
int width = orig->w;
int height = orig->h;
Uint32 npixels = width * height;
SDL_PixelFormat *format = orig->format;
SDL_Palette *palette = format->palette;
SDL_Color *entry;
Uint8 bpp = format->BytesPerPixel;
Uint32 *dstpix = (Uint32 *)rgba->pixels;
Uint8 *srcpix = (Uint8 *)orig->pixels;
Uint8 r, g, b, a;
Uint32 color;

for (Uint32 i = 0; i < npixels; i++)
{
if (format->BitsPerPixel == 8 && palette)
{
entry = palette->colors + *srcpix;
r = entry->r;
g = entry->g;
b = entry->b;
color = SDL_MapRGB(format,r,g,b);
}
else
{
color = *(Uint32 *)srcpix;
SDL_GetRGB(color,format,&r,&g,&b);
}

if (color == format->colorkey)
a = 0x00;
else
a = 0xff;

*dstpix++ = SDL_MapRGBA(rgba->format,r,g,b,a);
srcpix += bpp;
}

return rgba;
}



##### Share on other sites
BMP files don't contain alpha - they only hold RGB values. In a 32-bit BMP file, the 4th byte of every 4-byte pixel is "reserved" and is just used for padding.

Also, define "doesn't work". Does the image not load up in an image editor? Can you not load the image again using SDL?

##### Share on other sites
Since you're using SDL you could use the SDL_image library instead, and a format like TGA if you need an alpha channel. That would be alot easier compared to writing your own format.

##### Share on other sites
Quote:
 Original post by Evil SteveBMP files don't contain alpha - they only hold RGB values. In a 32-bit BMP file, the 4th byte of every 4-byte pixel is "reserved" and is just used for padding.

That's why I used the BITMAPV4HEADER, I thought it supported RGBA, it has the RGBA masks specification though.

Quote:
 Also, define "doesn't work". Does the image not load up in an image editor? Can you not load the image again using SDL?

I haven't tried to see if it works to load it back on, it surely will cos I use my own special-designed function. But the idea was to have ordinary valid .bmp format images but in RGBA format cos I need it.

##### Share on other sites
Quote:
 Original post by PerostSince you're using SDL you could use the SDL_image library instead, and a format like TGA if you need an alpha channel. That would be alot easier compared to writing your own format.

##### Share on other sites
Quote:
 Original post by programeringThat's why I used the BITMAPV4HEADER, I thought it supported RGBA, it has the RGBA masks specification though.

Yes it has the specification, but no it is not necessarily what you think it is.

The 32-bit formats specify: "Each DWORD in the bitmap array represents the relative intensities of blue, green, and red, respectively, for a pixel. The high byte in each DWORD is not used."

Many programs will write your alpha channel in them, but they can correctly ignore those values.

The alpha masks are still used and useful, however.

When you are creating an icon or cursor (which support transparency) you can assign an alpha mask to it. See MSDN article on alpha blended cursors and icons.

##### Share on other sites
There are many image formats that are designed to store RGBA: TGA, PNG, TIFF and DDS to name a few. There are also many excellent libraries that support reading and writing said formats, so I can't see a need to shoehorn BMP files into storing data they were not designed to contain.

##### Share on other sites
Yes, you can write out 32-bit bitmaps. And you don't have to do anything special or use any special headers.
Just use the old format and set biBitCount to 32 instead of 24. Photoshop loads up 32-bitmaps with no problems.

##### Share on other sites
Quote:
 Original post by samster581Yes, you can write out 32-bit bitmaps. And you don't have to do anything special or use any special headers.Just use the old format and set biBitCount to 32 instead of 24. Photoshop loads up 32-bitmaps with no problems.
Not with alpha though, as far as I know.

##### Share on other sites
Quote:
 Original post by Evil SteveNot with alpha though, as far as I know.

Yes, with alpha. I've done it before.
And Photoshop (CS2) lets you export 32-bit bitmaps too.

Just try it if you don't believe me.

1. 1
Rutin
28
2. 2
3. 3
4. 4
5. 5

• 13
• 11
• 10
• 13
• 20
• ### Forum Statistics

• Total Topics
632948
• Total Posts
3009410
• ### Who's Online (See full list)

There are no registered users currently online

×