True, uncompressed RGBA file format

I was looking into the BMP file format a bit and it seems that Windows officially only supports BMP version 1 (Compression = 0, RGB, no Alpha) and BMP versions 4 and 5.
Casey uses version 3, which I do understand how it works and that's the version you would want to use for uncompressed, RGBA pixel formats, but since it's not officially supported I am wondering which applications do officially support it to create images like that?
Adobe Photoshop seems to work for some people, but not everybody. Casey is using GIMP which is fine, but what do artists usually use? Do artists create images in different file formats and I'd have to use GIMP to convert them?

This all sounds a bit nit-picky, but are there other, uncompressed RGBA file formats that are as easy to read as BMP? PNG uses compression so that makes it a bit harder to read/write from scratch.
I don't know why but the gimp on my Linux creates bmp version 5 which the header size is 128 bits long. I don't know how to create a lower version bmp but rather I am working on trying to get different bmp versions to work as well as png. I and some others on the forums has gotten version two and three to work and I know this because they helped me with this process. (thanks!). Currently I reformated over my OSX with linux and I didn't back it up so I have to do everything over again <<.
I am working on trying to get different version of bmp to work and also png format. I can say the png header is quite different and it took me a while to figure out the pattern which is (header size) (header signature)(header info). Super werid. I am also having problems with decompression the (png) image because I don't think the file format tells you the uncompressed size so I think I have to some how find a way and some of these zlib examples are just horrible.

I think they (bmp version) are all the same except with big header size of course.You can go here https://msdn.microsoft.com/en-us/...esktop/dd183386%28v=vs.85%29.aspx to see the different version of the structure.

Edited by popcorn on
Well the simplest uncompressed image formats that you can use are http://en.wikipedia.org/wiki/Netpbm_format specifically the binary version of *.ppm (since you don't have to worry about comments there)

But I only ever used them as intermediate formats simple image manipulation/processing programs where you don't really want to bother with dependencies or a parser yet. So you can just use a batch conversion (imagemagick in the command line under linux or irfanview with a GUI under windows if you're scared) to/from *.ppm
It's not a big deal to write bmp loading code for all the variants it has. You do that once, and then you're done and will never need to touch that code again.

But this code should be used only for loading debug textures/debug code. For real game code you would want some offline asset processing tool where you would convert bmp files (or anything else) to format you want in game - easier to load format, swap rgba channels to correct places, premultiply alpha, etc... So then you don't worry about how to load images during game.

Anyways, if you don't want to write bmp loading code yourself, I can recommend using stb_image.h one header file library. It will load more variants of bmp and also png, jpg and few other popular formats. The good thing about this library it is one header and it has very simple to use API (just look at the comments around line 230).
The TGA format is quite easy: 18 bytes header followed by the data.
It's a bit more complicated if you want to support color map and RLE compression, but not that hard.

http://en.wikipedia.org/wiki/Truevision_TGA
http://www.dca.fee.unicamp.br/~martino/disciplinas/ea978/tgaffs.pdf

Here is a header file I made to handle tga :
http://www.sisyphe.be/donotdelete/tga.h

And how I use it (note that in this example I force the loaded image to be 4 bytes per pixel if the file is 3 bytes per pixel) :
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
struct Bitmap {
	
	u32 width;
	u32 height;
	u32 pitch;
	u32 bytesPerPixel;
	u8* pixels;
};

Bitmap loadTGA( MemoryPool* pool, Services* services, char* fileName ) {
	
	File file = services->readEntireFile( fileName );
	u8* content = file.content;
	Bitmap result = { };
	
	result.width = tga_getWidth( content );
	result.height = tga_getHeight( content );
	result.bytesPerPixel = 4;
	result.pitch = result.width * result.bytesPerPixel;
	
	u32 dataSize = result.width * result.height * result.bytesPerPixel;
	result.pixels = ( u8* ) pushSize( pool, dataSize );

	u32 sourceBytesPerPixel = tga_getPixelDepth( content ) / 8;
	
	if ( tga_getImageType( content ) == TGAImageType::trueColor ) {

		tga_copyData( tga_getImageData( content ), result.pixels, result.width, result.height, sourceBytesPerPixel, true );
	
	} else if ( tga_getImageType( content ) == TGAImageType::trueColorRLE ) {

		tga_RLEDecode( tga_getImageData( content ), result.pixels, result.width, result.height, sourceBytesPerPixel, true );
	}

	services->freeFileMemory( file );
	
	return result;
}


I don't know if it's the right place to ask, but since I'm here to learn and there are more experienced programmer here: if someone has some time to spare and can look at my tga.h file to give some general feedback on the code (like the interface, not the specifics of tga) I would be grateful.
The LoadImage API can, as far as I know, only load one specific BMP format with alpha channel. One that GIMP is unable to save. You need a bitmap with the 40 byte long BITMAPINFOHEADER, biBitCount set to 32 and biCompression set to BI_RGB. Each pixel stored as a 4 byte BGRA value. That's what LoadImage can load and what you can use directly with things like BitBlt, ImageLists, Toolbars, etc.
I can confirm from doing this myself, that the different version are pretty much the same except for the header size.

You can just copy and paste the struct version you need header you want from here
https://msdn.microsoft.com/en-us/...esktop/dd183386%28v=vs.85%29.aspx

and remove the size (DWORD bV4Size;)

then create the bmpfileheader stucture
1
2
3
4
5
6
7
8
struct __attribute__(__packed__)) bmpFileHeader
{
char sign[2];
uint32 size;
unsigned short resv1;
usingned short resv2;
uint32 bitmapOffset;
};


then read the file header
1
2
3
unsigned char fileheader[sizeof...
bmpfile = fopen....
fread(fileheader,sizeof(struct bmpFileheader),1,bmpfile)


then read and get the size

1
2
fread(headerDump,sizeof(uint32),1,bmpFile);
hsize =(uint32) headerDump;


then you check the header size to see what version you need to work with.
1
2
3
if (*hsize == 128-4) //128 bits BMPVersion 5 (minus 4 because we took out the header size)

if (*hsize == 108-4) //108 bits BMPVersion 4 (minus 4 because we took out the header size...I think)


The rest you can follow on handmade hero past episode and is pretty much the same except if you don't have compression then you can skip the episode after he shows you how to do the basic rendering.

I hope this helps.

oops I forgot the mention that I'm doing this on a linux machine.

Edited by popcorn on