Sign in to follow this  
programering

Can't save .bmp in RGBA format

Recommended Posts

programering    105
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 bV4RedMask;
	Uint32 bV4GreenMask;
	Uint32 bV4BlueMask;
	Uint32 bV4AlphaMask;
	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;
		bV4RedMask   = /*surf->format->*/Rmask;
		bV4GreenMask = /*surf->format->*/Gmask;
		bV4BlueMask  = /*surf->format->*/Bmask;
		bV4AlphaMask = /*surf->format->*/Amask;
		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,bV4RedMask);
		SDL_WriteLE32(dst,bV4GreenMask);
		SDL_WriteLE32(dst,bV4BlueMask);
		SDL_WriteLE32(dst,bV4AlphaMask);
		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;
	SDL_Surface *rgba = SDL_CreateRGBSurface(SDL_SWSURFACE,width,height,32,Rmask,Gmask,Bmask,Amask);
	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;
}



Thanks for your help.

Share this post


Link to post
Share on other sites
Evil Steve    2017
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 this post


Link to post
Share on other sites
Perost    332
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 this post


Link to post
Share on other sites
programering    105
Quote:
Original post by Evil Steve
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.

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 this post


Link to post
Share on other sites
programering    105
Quote:
Original post by Perost
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.

SDL_image has no save surface functions only for loading them.

Share this post


Link to post
Share on other sites
frob    44975
Quote:
Original post by programering
That'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 this post


Link to post
Share on other sites
swiftcoder    18437
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 this post


Link to post
Share on other sites
samster581    120
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 this post


Link to post
Share on other sites
Evil Steve    2017
Quote:
Original post by samster581
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.
Not with alpha though, as far as I know.

Share this post


Link to post
Share on other sites
samster581    120
Quote:
Original post by Evil Steve
Not 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.


Share this post


Link to post
Share on other sites
Evil Steve    2017
Quote:
Original post by samster581
Quote:
Original post by Evil Steve
Not 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.
I'll take your word for it - I was under the impression that the extra 8-bits were ignored by all image applications.

Quote:
Original post by programering
But why don't I see the new rgba image for if the 4 byte RGBA pixels are written to the file correct.
What are you viewing the image with? Have you compared the file header with a 32-bit BMP file of the same dimensions that works (I.e. saved from Photoshop or something)? They should be identical.
And what do you mean you don't "see the new rgba image"? Does the image fail to load in whatever viewer you're using? Have you tried other editors / viewers? Does the image load, but with no alpha?

Share this post


Link to post
Share on other sites
samster581    120
Quote:
Original post by programering
But why don't I see the new rgba image for if the 4 byte RGBA pixels are written to the file correct.


I don't use SDL to read/write bitmaps. Maybe that's your problem.

I would say you either have to code your own bitmap reading/writing functions, or you would have to examine the bitmap file
in a hex editor to make sure it was written as 32-bit. Don't assume anything until you examined the bits written to file.
If not, then roll your own.

[Edited by - samster581 on November 26, 2008 2:29:42 PM]

Share this post


Link to post
Share on other sites
frob    44975
Quote:
Original post by Evil Steve
I'll take your word for it - I was under the impression that the extra 8-bits were ignored by all image applications.
Not at all.

If it the header says it is a regular image then the high byte is not used. If the format is set to BI_BITFIELDS and the AlphaMask field is set to 0xff000000, then it might (but not guaranteed) be used for an alpha channel.


Even within Windows the use of the field is not consistent. When used for icons or cursors the fourth byte may be used as alpha (as listed above). When used as bitmaps on various blitting and rendering operations they are considered opaque, or as a transparency flag, or are fully alpha blended. It is quite horrible, really.

Share this post


Link to post
Share on other sites
programering    105
Quote:
Original post by Evil Steve
Quote:
Original post by programering
But why don't I see the new rgba image for if the 4 byte RGBA pixels are written to the file correct.

What are you viewing the image with? Have you compared the file header with a 32-bit BMP file of the same dimensions that works (I.e. saved from Photoshop or something)? They should be identical.
And what do you mean you don't "see the new rgba image"? Does the image fail to load in whatever viewer you're using? Have you tried other editors / viewers? Does the image load, but with no alpha?

When I select the new rgba bmp in the folder browser I don't see the image like the original one. But the headers are written correctly cos it displays the dimensions. I tried to open it with ms paint and it displayed the image area just white. With Paint Shop Pro 7 and Adobe PhotoShop CS3 it displays the image blue-ish shrinked in the height but sligtly different from eachother. The most other viewers/editors can't load it.

[Edited by - programering on November 26, 2008 2:23:13 PM]

Share this post


Link to post
Share on other sites
programering    105
I've got it to work now but upside-down, e.i just saving the pixels as they are stored and have the compression set to BI_BITFIELDS. I tried now and change it to BI_RGB and it was shown too but the rgb color order was reversed. It was shown even if the bitfields wasn't written except with the BI_BITFIELDS specified the image was in greyscale. This was the last I was going to try(to get rid of the V4 header and try the bitfields) and guess I was glad when it finally worked. [smile]

Here's the working code:

#include <SDL/SDL.h>


SDL_Surface *ConvRGBA32(SDL_Surface *orig);/*
SDL_Surface *LoadRGBA32BMP(char *filename);
bool SaveRGBA32BMP(SDL_Surface *surf, char *filename);
SDL_Surface *LoadRGBA32BMP_RW(SDL_RWops *src, bool freesrc);*/

bool SaveRGBA32BMP_RW(SDL_Surface *surf, SDL_RWops *dst, bool freedst);





int main(int argc, char *argv[])
{
SDL_Init(SDL_INIT_VIDEO);

SDL_Surface *orig = SDL_LoadBMP("test.bmp");
if (!orig) return 0;

SDL_SetColorKey(orig,SDL_SRCCOLORKEY,SDL_MapRGB(orig->format,0,0,0));

SDL_Surface *rgba = ConvRGBA32(orig);
if (!rgba) { SDL_FreeSurface(orig); return 0; }

SDL_Surface *screen = SDL_SetVideoMode(200,100,32,0);
SDL_FillRect(screen,NULL,SDL_MapRGB(screen->format,255,0,0));
SDL_Rect pos = {0,0,0,0};
if (SDL_BlitSurface(rgba,NULL,screen,&pos) < 0)
fprintf(stderr,"Blit failed: %s\n",SDL_GetError());
SDL_UpdateRect(screen,0,0,0,0);
bool exit = false;
SDL_Event event;
while (!exit)
{
if (SDL_PollEvent(&event))
{
if (event.type == SDL_QUIT)
exit = true;
}
}

SaveRGBA32BMP_RW(rgba,SDL_RWFromFile("rgba.bmp", "wb"),true);

SDL_FreeSurface(orig);
SDL_FreeSurface(rgba);

return 1;
}




#if SDL_BYTEORDER == SDL_LIL_ENDIAN
# define Rmask 0x000000FF
# define Gmask 0x0000FF00
# define Bmask 0x00FF0000
# define Amask 0xFF000000/*
# define Rshift 0
# define Gshift 8
# define Bshift 16
# define Ashift 24*/

#else
# define Rmask 0xFF000000
# define Gmask 0x00FF0000
# define Bmask 0x0000FF00
# define Amask 0x000000FF/*
# define Rshift 24
# define Gshift 16
# define Bshift 8
# define Ashift 0*/

#endif


SDL_Surface *ConvRGBA32(SDL_Surface *orig)
{
int width = orig->w;
int height = orig->h;
SDL_Surface *rgba = SDL_CreateRGBSurface(SDL_SWSURFACE,width,height,32,Rmask,Gmask,Bmask,Amask);
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 = 0xC0;
else
a = 0xff;

*dstpix++ = SDL_MapRGBA(rgba->format,r,g,b,a);
srcpix += bpp;
// *dstpix++ = 0xFF000000; //0x22CCFF99; //0xCC00FFFF; //0xFFFFFFFF;
}

return rgba;
}



#define BI_RGB 0
#define BI_RLE8 1
#define BI_RLE4 2
#define BI_BITFIELDS 3

/*
typedef struct tagBITMAPFILEHEADER {
Uint16 bfType;
Uint32 bfSize;
Uint16 bfReserved1;
Uint16 bfReserved2;
Uint32 bfOffBits;
} BITMAPFILEHEADER;


/*
typedef long FXPT2DOT30;

typedef struct tagCIEXYZ {
FXPT2DOT30 ciexyzX;
FXPT2DOT30 ciexyzY;
FXPT2DOT30 ciexyzZ;
} CIEXYZ;


typedef struct tagCIEXYZTRIPLE {
CIEXYZ ciexyzRed;
CIEXYZ ciexyzGreen;
CIEXYZ ciexyzBlue;
} CIEXYZTRIPLE;


typedef struct tagBITMAPV4HEADER {
Uint32 bV4Size;
Sint32 bV4Width;
Sint32 bV4Height;
Uint16 bV4Planes;
Uint16 bV4BitCount;
Uint32 bV4V4Compression;
Uint32 bV4SizeImage;
Sint32 bV4XPelsPerMeter;
Sint32 bV4YPelsPerMeter;
Uint32 bV4ClrUsed;
Uint32 bV4ClrImportant;
Uint32 bV4RedMask;
Uint32 bV4GreenMask;
Uint32 bV4BlueMask;
Uint32 bV4AlphaMask;
Uint32 bV4CSType;
CIEXYZTRIPLE bV4Endpoints;
Uint32 bV4GammaRed;
Uint32 bV4GammaGreen;
Uint32 bV4GammaBlue;
} BITMAPV4HEADER;
*/
/*

typedef struct tagBITMAPINFOHEADER {
Uint32 biSize;
Sint32 biWidth;
Sint32 biHeight;
Uint16 biPlanes;
Uint16 biBitCount;
Uint32 biCompression;
Uint32 biSizeImage;
Sint32 biXPelsPerMeter;
Sint32 biYPelsPerMeter;
Uint32 biClrUsed;
Uint32 biClrImportant;
} BITMAPINFOHEADER;


BITMAPFILEHEADER bmpFileHeader;
BITMAPINFOHEADER bmpInfoHeader;/*
BITMAPV4HEADER bmpV4Header;*/


/*********************************************************************
bool SaveRGBA32BMP_RW(SDL_Surface *surf, SDL_RWops *dst, bool freedst)
{

if (!surf || !dst || surf->format->BitsPerPixel != 32)
{
if (dst && freedst)
SDL_RWclose(dst);

return false;
}


long fp_start = SDL_RWtell(dst);

// Fill in the BITMAPFILEHEADER:
bmpFileHeader.bfType = 0x4D42;
// bmpFileHeader.bfMagic[0] = 'B';
// bmpFileHeader.bfMagic[1] = 'M';
bmpFileHeader.bfSize = 0;
bmpFileHeader.bfReserved1 = 0;
bmpFileHeader.bfReserved2 = 0;
bmpFileHeader.bfOffBits = 0;
// Write it:
SDL_RWwrite(dst,&bmpFileHeader,sizeof(bmpFileHeader),1);

/*
// Fill in the BITMAPV4HEADER:
bmpV4Header.bV4Size = 108; //sizeof BITMAPV4HEADER;
bmpV4Header.bV4Width = surf->w;
bmpV4Header.bV4Height = surf->h;
bmpV4Header.bV4Planes = 1;
bmpV4Header.bV4BitCount = 32;
bmpV4Header.bV4V4Compression = BI_RGB;
bmpV4Header.bV4SizeImage = surf->pitch * surf->h;
bmpV4Header.bV4XPelsPerMeter = 0;
bmpV4Header.bV4YPelsPerMeter = 0;
bmpV4Header.bV4ClrUsed = 0;
bmpV4Header.bV4ClrImportant = 0;
bmpV4Header.bV4RedMask = surf->format->Rmask;
bmpV4Header.bV4GreenMask = surf->format->Gmask;
bmpV4Header.bV4BlueMask = surf->format->Bmask;
bmpV4Header.bV4AlphaMask = surf->format->Amask;
bmpV4Header.bV4CSType = 0;
bmpV4Header.bV4Endpoints.ciexyzRed.ciexyzX = 0;
bmpV4Header.bV4Endpoints.ciexyzRed.ciexyzY = 0;
bmpV4Header.bV4Endpoints.ciexyzRed.ciexyzZ = 0;
bmpV4Header.bV4Endpoints.ciexyzGreen.ciexyzX = 0;
bmpV4Header.bV4Endpoints.ciexyzGreen.ciexyzY = 0;
bmpV4Header.bV4Endpoints.ciexyzGreen.ciexyzZ = 0;
bmpV4Header.bV4Endpoints.ciexyzBlue.ciexyzX = 0;
bmpV4Header.bV4Endpoints.ciexyzBlue.ciexyzY = 0;
bmpV4Header.bV4Endpoints.ciexyzBlue.ciexyzZ = 0;
bmpV4Header.bV4GammaRed = 0;
bmpV4Header.bV4GammaGreen = 0;
bmpV4Header.bV4GammaBlue = 0;
// Write it:
SDL_RWwrite(dst,&bmpV4Header,sizeof(bmpV4Header),1);
*/
/*

// Fill in the BITMAPINFOHEADER:
bmpInfoHeader.biSize = 108; //sizeof BITMAPV4HEADER;
bmpInfoHeader.biWidth = surf->w;
bmpInfoHeader.biHeight = surf->h;
bmpInfoHeader.biPlanes = 1;
bmpInfoHeader.biBitCount = 32;
bmpInfoHeader.biCompression = BI_RGB;
bmpInfoHeader.biSizeImage = surf->pitch * surf->h;
bmpInfoHeader.biXPelsPerMeter = 0;
bmpInfoHeader.biYPelsPerMeter = 0;
bmpInfoHeader.biClrUsed = 0;
bmpInfoHeader.biClrImportant = 0;

// Write it:
SDL_RWwrite(dst,&bmpInfoHeader,sizeof(bmpInfoHeader),1);

// Get the offset:
bmpFileHeader.bfOffBits = SDL_RWtell(dst);

// Write the pixels:
SDL_RWwrite(dst,surf->pixels,bmpV4Header.bV4SizeImage,1);

// Get the file size:
bmpFileHeader.bfSize = SDL_RWtell(dst);

// Re-Write the BITMAPFILEHEADER with the new info:
SDL_RWseek(dst,fp_start,RW_SEEK_SET); // Set the file pointer back.
SDL_RWwrite(dst,&bmpFileHeader,sizeof(bmpFileHeader),1); // Write it.
SDL_RWseek(dst,fp_start+bmpFileHeader.bfSize,RW_SEEK_SET); // Set the file pointer back.

if (freedst)
SDL_RWclose(dst);

return true;
}
***********************************************************************/

/**********************************************************************
bool SaveRGBA32BMP_RW(SDL_Surface *surf, SDL_RWops *dst, bool freedst)
{
bool success = true;

long fp_start = SDL_RWtell(dst);

if (surf)
{
if (surf->format->BitsPerPixel != 32)
{
success = false;
goto done;
}
}
if (!surf || !dst)
{
success = false;
goto done;
}

// Fill in the BITMAPFILEHEADER:
bmpFileHeader.bfType = 0x4D42;
// bmpFileHeader.bfMagic[0] = 'B';
// bmpFileHeader.bfMagic[1] = 'M';
bmpFileHeader.bfSize = 0;
bmpFileHeader.bfReserved1 = 0;
bmpFileHeader.bfReserved2 = 0;
bmpFileHeader.bfOffBits = 0;
// Write it:
if (SDL_RWwrite(dst,&bmpFileHeader,sizeof(bmpFileHeader),1) < 0)
{
success = false;
goto done;
}

/*
// Fill in the BITMAPV4HEADER:
bmpV4Header.bV4Size = 108; //sizeof BITMAPV4HEADER;
bmpV4Header.bV4Width = surf->w;
bmpV4Header.bV4Height = surf->h;
bmpV4Header.bV4Planes = 1;
bmpV4Header.bV4BitCount = 32;
bmpV4Header.bV4V4Compression = BI_RGB;
bmpV4Header.bV4SizeImage = surf->pitch * surf->h;
bmpV4Header.bV4XPelsPerMeter = 0;
bmpV4Header.bV4YPelsPerMeter = 0;
bmpV4Header.bV4ClrUsed = 0;
bmpV4Header.bV4ClrImportant = 0;
bmpV4Header.bV4RedMask = surf->format->Rmask;
bmpV4Header.bV4GreenMask = surf->format->Gmask;
bmpV4Header.bV4BlueMask = surf->format->Bmask;
bmpV4Header.bV4AlphaMask = surf->format->Amask;
bmpV4Header.bV4CSType = 0;
bmpV4Header.bV4Endpoints.ciexyzRed.ciexyzX = 0;
bmpV4Header.bV4Endpoints.ciexyzRed.ciexyzY = 0;
bmpV4Header.bV4Endpoints.ciexyzRed.ciexyzZ = 0;
bmpV4Header.bV4Endpoints.ciexyzGreen.ciexyzX = 0;
bmpV4Header.bV4Endpoints.ciexyzGreen.ciexyzY = 0;
bmpV4Header.bV4Endpoints.ciexyzGreen.ciexyzZ = 0;
bmpV4Header.bV4Endpoints.ciexyzBlue.ciexyzX = 0;
bmpV4Header.bV4Endpoints.ciexyzBlue.ciexyzY = 0;
bmpV4Header.bV4Endpoints.ciexyzBlue.ciexyzZ = 0;
bmpV4Header.bV4GammaRed = 0;
bmpV4Header.bV4GammaGreen = 0;
bmpV4Header.bV4GammaBlue = 0;
// Write it:
SDL_RWwrite(dst,&bmpV4Header,sizeof(bmpV4Header),1);
*/
/*

// Fill in the BITMAPINFOHEADER:
bmpInfoHeader.biSize = 108; //sizeof BITMAPV4HEADER;
bmpInfoHeader.biWidth = surf->w;
bmpInfoHeader.biHeight = surf->h;
bmpInfoHeader.biPlanes = 1;
bmpInfoHeader.biBitCount = 32;
bmpInfoHeader.biCompression = BI_RGB;
bmpInfoHeader.biSizeImage = surf->pitch * surf->h;
bmpInfoHeader.biXPelsPerMeter = 0;
bmpInfoHeader.biYPelsPerMeter = 0;
bmpInfoHeader.biClrUsed = 0;
bmpInfoHeader.biClrImportant = 0;
// Write it:
if (SDL_RWwrite(dst,&bmpInfoHeader,sizeof(bmpInfoHeader),1) < 0)
{
success = false;
goto done;
}

// Get the offset:
bmpFileHeader.bfOffBits = SDL_RWtell(dst);

// Write the pixels:
if (SDL_RWwrite(dst,surf->pixels,bmpInfoHeader.biSizeImage,1) < 0)
{
success = false;
goto done;
}

// Get the file size:
bmpFileHeader.bfSize = SDL_RWtell(dst);

// Re-Write the BITMAPFILEHEADER with the new info:
SDL_RWseek(dst,fp_start,RW_SEEK_SET); // Set the file pointer back.
SDL_RWwrite(dst,&bmpFileHeader,sizeof(bmpFileHeader),1); // Write it.
SDL_RWseek(dst,fp_start+bmpFileHeader.bfSize,RW_SEEK_SET); // Set the file pointer back.

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

return success;
}
*******************************************************/


/*
SDL_Surface *LoadRGBA32BMP_RW(SDL_RWops *src, int freesrc)
{
}
*/


/*********************************************************
SDL_Surface *LoadRGBA32BMP_RW(SDL_RWops *src, int freesrc)
{
int was_error;
long fp_offset;
int bmpPitch;
int i, pad;
SDL_Surface *surface;
Uint32 Rmask;
Uint32 Gmask;
Uint32 Bmask;
SDL_Palette *palette;
Uint8 *bits;
int ExpandBMP;

/* The Win32 BMP file header (14 bytes) */
/*
char magic[2];
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;

/* Make sure we are passed a valid data source */
/*
surface = NULL;
was_error = 0;
if ( src == NULL ) {
was_error = 1;
goto done;
}

/* Read in the BMP file header */
/*
fp_offset = SDL_RWtell(src);
SDL_ClearError();
if ( SDL_RWread(src, magic, 1, 2) != 2 ) {
SDL_Error(SDL_EFREAD);
was_error = 1;
goto done;
}
if ( SDL_strncmp(magic, "BM", 2) != 0 ) {
SDL_SetError("File is not a Windows BMP file");
was_error = 1;
goto done;
}
bfSize = SDL_ReadLE32(src);
bfReserved1 = SDL_ReadLE16(src);
bfReserved2 = SDL_ReadLE16(src);
bfOffBits = SDL_ReadLE32(src);

/* Read the Win32 BITMAPINFOHEADER */
/*
biSize = SDL_ReadLE32(src);
if ( biSize == 12 ) {
biWidth = (Uint32)SDL_ReadLE16(src);
biHeight = (Uint32)SDL_ReadLE16(src);
biPlanes = SDL_ReadLE16(src);
biBitCount = SDL_ReadLE16(src);
biCompression = BI_RGB;
biSizeImage = 0;
biXPelsPerMeter = 0;
biYPelsPerMeter = 0;
biClrUsed = 0;
biClrImportant = 0;
} else {
biWidth = SDL_ReadLE32(src);
biHeight = SDL_ReadLE32(src);
biPlanes = SDL_ReadLE16(src);
biBitCount = SDL_ReadLE16(src);
biCompression = SDL_ReadLE32(src);
biSizeImage = SDL_ReadLE32(src);
biXPelsPerMeter = SDL_ReadLE32(src);
biYPelsPerMeter = SDL_ReadLE32(src);
biClrUsed = SDL_ReadLE32(src);
biClrImportant = SDL_ReadLE32(src);
}

/* Check for read error */
/*
if ( SDL_strcmp(SDL_GetError(), "") != 0 ) {
was_error = 1;
goto done;
}

/* Expand 1 and 4 bit bitmaps to 8 bits per pixel */
/*
switch (biBitCount) {
case 1:
case 4:
ExpandBMP = biBitCount;
biBitCount = 8;
break;
default:
ExpandBMP = 0;
break;
}

/* We don't support any BMP compression right now */
/*
Rmask = Gmask = Bmask = 0;
switch (biCompression) {
case BI_RGB:
/* If there are no masks, use the defaults */
/*
if ( bfOffBits == (14+biSize) ) {
/* Default values for the BMP format */
/*
switch (biBitCount) {
case 15:
case 16:
Rmask = 0x7C00;
Gmask = 0x03E0;
Bmask = 0x001F;
break;
case 24:
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
Rmask = 0x000000FF;
Gmask = 0x0000FF00;
Bmask = 0x00FF0000;
break;
#endif
case 32:
Rmask = 0x00FF0000;
Gmask = 0x0000FF00;
Bmask = 0x000000FF;
break;
default:
break;
}
break;
}
/* Fall through -- read the RGB masks */
/*

case BI_BITFIELDS:
switch (biBitCount) {
case 15:
case 16:
case 32:
Rmask = SDL_ReadLE32(src);
Gmask = SDL_ReadLE32(src);
Bmask = SDL_ReadLE32(src);
break;
default:
break;
}
break;
default:
SDL_SetError("Compressed BMP files not supported");
was_error = 1;
goto done;
}

/* Create a compatible surface, note that the colors are RGB ordered */
/*
surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
biWidth, biHeight, biBitCount, Rmask, Gmask, Bmask, 0);
if ( surface == NULL ) {
was_error = 1;
goto done;
}

/* Load the palette, if any */
/*
palette = (surface->format)->palette;
if ( palette ) {
if ( biClrUsed == 0 ) {
biClrUsed = 1 << biBitCount;
}
if ( biSize == 12 ) {
for ( i = 0; i < (int)biClrUsed; ++i ) {
SDL_RWread(src, &palette->colors[i].b, 1, 1);
SDL_RWread(src, &palette->colors[i].g, 1, 1);
SDL_RWread(src, &palette->colors[i].r, 1, 1);
palette->colors[i].unused = 0;
}
} else {
for ( i = 0; i < (int)biClrUsed; ++i ) {
SDL_RWread(src, &palette->colors[i].b, 1, 1);
SDL_RWread(src, &palette->colors[i].g, 1, 1);
SDL_RWread(src, &palette->colors[i].r, 1, 1);
SDL_RWread(src, &palette->colors[i].unused, 1, 1);
}
}
palette->ncolors = biClrUsed;
}

/* Read the surface pixels. Note that the bmp image is upside down */
/*
if ( SDL_RWseek(src, fp_offset+bfOffBits, RW_SEEK_SET) < 0 ) {
SDL_Error(SDL_EFSEEK);
was_error = 1;
goto done;
}
bits = (Uint8 *)surface->pixels+(surface->h*surface->pitch);
switch (ExpandBMP) {
case 1:
bmpPitch = (biWidth + 7) >> 3;
pad = (((bmpPitch)%4) ? (4-((bmpPitch)%4)) : 0);
break;
case 4:
bmpPitch = (biWidth + 1) >> 1;
pad = (((bmpPitch)%4) ? (4-((bmpPitch)%4)) : 0);
break;
default:
pad = ((surface->pitch%4) ?
(4-(surface->pitch%4)) : 0);
break;
}
while ( bits > (Uint8 *)surface->pixels ) {
bits -= surface->pitch;
switch (ExpandBMP) {
case 1:
case 4: {
Uint8 pixel = 0;
int shift = (8-ExpandBMP);
for ( i=0; i<surface->w; ++i ) {
if ( i%(8/ExpandBMP) == 0 ) {
if ( !SDL_RWread(src, &pixel, 1, 1) ) {
SDL_SetError(
"Error reading from BMP");
was_error = 1;
goto done;
}
}
*(bits+i) = (pixel>>shift);
pixel <<= ExpandBMP;
} }
break;

default:
if ( SDL_RWread(src, bits, 1, surface->pitch)
!= surface->pitch ) {
SDL_Error(SDL_EFREAD);
was_error = 1;
goto done;
}
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
/* Byte-swap the pixels if needed. Note that the 24bpp
case has already been taken care of above. */
/*
switch(biBitCount) {
case 15:
case 16: {
Uint16 *pix = (Uint16 *)bits;
for(i = 0; i < surface->w; i++)
pix[i] = SDL_Swap16(pix[i]);
break;
}

case 32: {
Uint32 *pix = (Uint32 *)bits;
for(i = 0; i < surface->w; i++)
pix[i] = SDL_Swap32(pix[i]);
break;
}
}
#endif
break;
}
/* Skip padding bytes, ugh */
/*
if ( pad ) {
Uint8 padbyte;
for ( i=0; i<pad; ++i ) {
SDL_RWread(src, &padbyte, 1, 1);
}
}
}
done:
if ( was_error ) {
if ( src ) {
SDL_RWseek(src, fp_offset, RW_SEEK_SET);
}
if ( surface ) {
SDL_FreeSurface(surface);
}
surface = NULL;
}
if ( freesrc && src ) {
SDL_RWclose(src);
}
return(surface);
}

*******************************************/





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 bV4RedMask;
Uint32 bV4GreenMask;
Uint32 bV4BlueMask;
Uint32 bV4AlphaMask;
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_BITFIELDS; // BI_RGB;
biSizeImage = surf->h * surf->pitch;
biXPelsPerMeter = 0;
biYPelsPerMeter = 0;
biClrUsed = 0;
biClrImportant = 0;
/*
bV4RedMask = /*surf->format->*/
/*Rmask;
bV4GreenMask = /*surf->format->*/
/*Gmask;
bV4BlueMask = /*surf->format->*/
/*Bmask;
bV4AlphaMask = /*surf->format->*/
/*Amask;
bV4CSType = 0;
// CIEXYZTRIPLE bV4Endpoints;
bV4Endpoints = 1;
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,/*surf->format->*/
/*Rmask);
SDL_WriteLE32(dst,/*surf->format->*/
/*Gmask);
SDL_WriteLE32(dst,/*surf->format->*/
/*Bmask);
SDL_WriteLE32(dst,/*surf->format->*/
/*Amask);
/*
SDL_WriteLE32(dst,bV4RedMask);
SDL_WriteLE32(dst,bV4GreenMask);
SDL_WriteLE32(dst,bV4BlueMask);
SDL_WriteLE32(dst,bV4AlphaMask);
SDL_WriteLE32(dst,bV4CSType);
for (int i = 0; i < 9; i++)
{
// SDL_RWwrite(dst,&bV4Endpoints,4,1);
SDL_WriteLE32(dst,1);
}
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;
}
}*/

bits = (Uint32 *)surf->pixels;
if (SDL_RWwrite(dst, bits, surf->h * surf->pitch, 1) < 0)
{
SDL_Error(SDL_EFWRITE);
}


// 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 is the faulting reverse scanline writing:

/* 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;
}
}


I can't see any fault in it. But apparently it causes a pretty large chunk of null values in the beginning after the headers with some small strays of bits set in the middle of it and after comes the pixel values in its reverse order. This seem very strange and unlogical. But I'm surprised that the working built bmp image is larger.

[Edited by - programering on November 27, 2008 3:23:51 PM]

Share this post


Link to post
Share on other sites
Evil Steve    2017
Quote:
Original post by programering
I've got it to work now but upside-down, e.i just saving the pixels as they are stored and have the compression set to BI_BITFIELDS. I tried now and change it to BI_RGB and it was shown too but the rgb color order was reversed. It was shown even if the bitfields wasn't written except with the BI_BITFIELDS specified the image was in greyscale. This was the last I was going to try(to get rid of the V4 header and try the bitfields) and guess I was glad when it finally worked. [smile]
Standard BMP files are stored vertically flipped (Quite why I have no idea...), I assume it's the same for V4 BMPs.

Share this post


Link to post
Share on other sites
programering    105
Now I've solved the top-down write code:

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

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


I realized that the pointer is Uint32(4 byte) size and used with pitch which is the number of bytes per pixel row which only applies to Uint8(1-byte) size pointers.

The picture is shown correct now. So it's only the load function that is left to code now.

Share this post


Link to post
Share on other sites
programering    105
And now I have coded(modified SDL_LoadBMP) the loading function and it works. Here it is:

SDL_Surface *LoadRGBA32BMP_RW(SDL_RWops *src, bool freesrc)
{
bool success = true;

long fp_offset;
SDL_Surface *surf = NULL;
Uint32 Rmask;
Uint32 Gmask;
Uint32 Bmask;
Uint32 Amask;
Uint32 *bits;

/* The Win32 BMP file header (14 bytes) */
char magic[2];
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;

/* Make sure we are passed a valid data source */
if (!src)
{
success = false;
goto done;
}

/* Read in the BMP file header */
fp_offset = SDL_RWtell(src);

if (SDL_RWread(src, magic, 1, 2) != 2)
{
SDL_Error(SDL_EFREAD);
success = false;
goto done;
}
if (SDL_strncmp(magic, "BM", 2) != 0)
{
// SDL_SetError("File is not a Windows BMP file");
success = false;
goto done;
}

bfSize = SDL_ReadLE32(src);
bfReserved1 = SDL_ReadLE16(src);
bfReserved2 = SDL_ReadLE16(src);
bfOffBits = SDL_ReadLE32(src);

/* Read the Win32 BITMAPINFOHEADER */
biSize = SDL_ReadLE32(src);
if (biSize == 40)
{
biWidth = SDL_ReadLE32(src);
biHeight = SDL_ReadLE32(src);
biPlanes = SDL_ReadLE16(src);
biBitCount = SDL_ReadLE16(src);
biCompression = SDL_ReadLE32(src);
biSizeImage = SDL_ReadLE32(src);
biXPelsPerMeter = SDL_ReadLE32(src);
biYPelsPerMeter = SDL_ReadLE32(src);
biClrUsed = SDL_ReadLE32(src);
biClrImportant = SDL_ReadLE32(src);

if (biBitCount != 32 && biClrUsed != 0)
{
success = false;
goto done;
}
}
else
{
success = false;
goto done;
}

if (biCompression == BI_BITFIELDS)
{
Rmask = SDL_ReadLE32(src);
Gmask = SDL_ReadLE32(src);
Bmask = SDL_ReadLE32(src);
Amask = SDL_ReadLE32(src);
}
else
{
success = false;
goto done;
}

/* Create a compatible surface, note that the colors are RGB ordered */
surf = SDL_CreateRGBSurface(SDL_SWSURFACE,biWidth,biHeight,biBitCount,Rmask,Gmask,Bmask,Amask);
if (!surf)
{
success = false;
goto done;
}


/* Read the surface pixels. Note that the bmp image is upside down */
if (SDL_RWseek(src, fp_offset+bfOffBits, RW_SEEK_SET) < 0 )
{
SDL_Error(SDL_EFSEEK);
success = false;
goto done;
}

bits = (Uint32 *) surf->pixels + (surf->h * surf->w);
while (bits > (Uint32 *) surf->pixels)
{
bits -= surf->w;
if (SDL_RWread(src,bits,surf->pitch,1) < 0)
{
SDL_Error(SDL_EFREAD);
success = false;
goto done;
}
}

done:
if (!success)
{
if (src) {
SDL_RWseek(src, fp_offset, RW_SEEK_SET);
}
if (surf)
SDL_FreeSurface(surf);

surf = NULL;
}
if (freesrc && src)
{
SDL_RWclose(src);
}

return surf;
}



And here is the new code for testing it:

int main(int argc, char *argv[])
{
SDL_Init(SDL_INIT_VIDEO);
/*
SDL_Surface *orig = SDL_LoadBMP("test.bmp");
if (!orig) return 0;

SDL_SetColorKey(orig,SDL_SRCCOLORKEY,SDL_MapRGB(orig->format,0,0,0));

SDL_Surface *rgba = ConvRGBA32(orig);
if (!rgba) { SDL_FreeSurface(orig); return 0; }
*/

SDL_Surface *rgba = LoadRGBA32BMP_RW(SDL_RWFromFile("rgba.bmp", "rb"),true);

SDL_Surface *screen = SDL_SetVideoMode(200,100,32,0);
SDL_FillRect(screen,NULL,SDL_MapRGB(screen->format,255,255,0));
SDL_Rect pos = {0,0,0,0};
if (SDL_BlitSurface(rgba,NULL,screen,&pos) < 0)
fprintf(stderr,"Blit failed: %s\n",SDL_GetError());
SDL_UpdateRect(screen,0,0,0,0);
bool exit = false;
SDL_Event event;
while (!exit)
{
if (SDL_PollEvent(&event))
{
if (event.type == SDL_QUIT)
exit = true;
}
}

// SaveRGBA32BMP_RW(rgba,SDL_RWFromFile("rgba.bmp", "wb"),true);

// SDL_FreeSurface(orig);
SDL_FreeSurface(rgba);

return 1;
}


Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this