Page 1 of 1

rgb format in bmp file

Posted: Fri Apr 11, 2014 12:37 am
by Shaun
Hi, guys!

i am doing gui stuff for my os these days and i got puzzled in bitmap file loading. I have read a lot articles about bmp file format. many people say that the format of rgb stored in bmp file is bgr(24 bpp), and when you load bmp file into memory, you should convert bgr to rgb order if you want to display it on screen.

but in the real world, everything goes weird...

take a look at my converting function:
only take care of 24bpp.
buf conatins the actual bytes of pixel of a bmp file, not include bmp file header and info header.

Code: Select all

void bmp_to_rgb_buffer(char *buf, bmp_t *bmp)
{
	int padding;
	int bpl;
	int psw;
	u32 bufpos;
	u32 newpos;
	int x, y;
	u8 *newbuf = bmp->data;
	padding = 0;
	bpl = bmp->width * 3;
	while ((bpl + padding) % 4 != 0)
		padding++;

	psw = bpl + padding;

	for (y=0; y<bmp->height; y++) {
		for (x=0; x<bpl; x+=3) {
			newpos = (y*bmp->width *3) + x;
			bufpos = (bmp->height-y-1)*psw + x;
                        //convert bgr to rgb order.
			newbuf[newpos] = buf[bufpos+2];
			newbuf[newpos+1] = buf[bufpos+1];
			newbuf[newpos+2] = buf[bufpos];
		}
	}

}
and the result is like this:
Screenshot2.png
Screenshot2.png (17.24 KiB) Viewed 1972 times
after a couple of hour wondering, i change the converting function like this:

Code: Select all

void bmp_to_rgb_buffer(char *buf, bmp_t *bmp)
{
	int padding;
	int bpl;
	int psw;
	u32 bufpos;
	u32 newpos;
	int x, y;
	u8 *newbuf = bmp->data;
	padding = 0;
	bpl = bmp->width * 3;
	while ((bpl + padding) % 4 != 0)
		padding++;

	psw = bpl + padding;

	for (y=0; y<bmp->height; y++) {
		for (x=0; x<bpl; x+=3) {
			newpos = (y*bmp->width *3) + x;
			bufpos = (bmp->height-y-1)*psw + x;
                        //Note, do not convert rgb order in bmp file, just copy the original order
			newbuf[newpos] = buf[bufpos]; 
			newbuf[newpos+1] = buf[bufpos+1];
			newbuf[newpos+2] = buf[bufpos+2];
		}
	}

}

and the result is like this:
Screenshot1.png
it seems like that the second way goes well, :shock: who can tell me where i am wrong?

Re: rgb format in bmp file

Posted: Fri Apr 11, 2014 4:33 am
by zhiayang
I think it should be fairly obvious that you don't need to convert byte order. Most image formats nowadays either work with RGB, or give you a field to tell you the byte order used. I don't remember if BMP has a field (I don't think it does) but in any case, I've never seen a BMP that's not in RGB format.

Re: rgb format in bmp file

Posted: Fri Apr 11, 2014 11:16 am
by jnc100
As far as I recall, if you're using indexed color mode (i.e. with a palette), then the order of bits in the palette is blue, green, red, reserved (for a total of 32-bits), represented as a 'RGBQUAD' structure in the Windows API, whereas if you use 24-bit color mode, then the order of bits in the image is red, green, blue (for a total of 24 bits).

Regards,
John.

Re: rgb format in bmp file

Posted: Fri Apr 11, 2014 11:56 pm
by Octocontrabass
A lot of information on BMP files (and other uncompressed image formats) is confused by endianness. When someone says 32-bit RGBA, they might mean the bytes are in the order red, green, blue, alpha. Or, they might mean the bits are in that order within a little-endian integer, which would put the bytes in the order alpha, blue, green, then red.

You might be tempted to deal with everything on a byte-by-byte basis, but CPUs tend to be more efficient when they're working on larger units of data. (Plus, it doesn't work very well in 15- and 16-bit color modes.)

Re: rgb format in bmp file

Posted: Mon Apr 14, 2014 11:16 pm
by Shaun
@Octocontrabass, got it,thanks!


thanks all!