Sign in to follow this  

Problem with rewriting 32Bitmap from 8bit bitmap

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am trying to write a 32BMP from an 8bit BMP. The reason for it is that i am currently using the alpha channel as flags for a shader and instead of manipulating ALL the posible colors from a 32bit image, I narrow it down to 256; something manageable for my artists. The output file has a weird bit offset and it writes some junk The following code reads the 8bit bmp: ////////////////////////////// // READ THE BITMAP'S FILE HEADE AND INFO HEADER fread(&bmpf, sizeof(BITMAPFILEHEADER), 1, fin8bit); fread(&bmpi, sizeof(BITMAPINFOHEADER), 1, fin8bit); //////////////////////////////////// // compute the size of the palette int paletteSize = 1<<bmpi.biBitCount; ///////////////////////////////////////// // READ the palette... and Pixels palette = new PALETTEENTRY[paletteSize]; fread(palette, sizeof(PALETTEENTRY), paletteSize, fin8bit); int pixNum = bmpi.biHeight * bmpi.biWidth; iPix = new unsigned char [pixNum]; fread(iPix, sizeof(unsigned char), pixNum, fin8bit); fclose(fin8bit); The following code creates the 32bit bmp from that file and just continues the last line: //all colors used bmpi.biClrUsed = 0; //all colors important bmpi.biClrImportant = 0; //bit depth bmpi.biBitCount = 32; //noncompressed bmpi.biCompression = BI_RGB; //must be one bmpi.biPlanes = 1; //each pixel is a struct PALETTENTRY { BYTE, BYTE, BYTE, BYTE } //Dont know if my problem is here bmpi.biSizeImage = (bmpi.biHeight * bmpi.biWidth) * 4; //size of this structure (bmpi) bmpi.biSize = 40; //dont know if this matters bmpi.biXPelsPerMeter = 0; bmpi.biYPelsPerMeter = 0; //Has to be BM bmpf.bfType = 19778; //Must be 0 bmpf.bfReserved1 = 0; bmpf.bfReserved2 = 0; //size of the BMPINFOHEADER + BMPFILEHEADER bmpf.bfOffBits = 12*sizeof(DWORD) + 2*sizeof(BYTE) + 2*sizeof(WORD); //DONT KNOW IF THIS IS HOW TO CALCULATE bmpf.bfSize = (bmpf.bfOffBits) + 4*(bmpi.biHeight * bmpi.biWidth); FILE *fout = fopen("32bitbmp.bmp, "wb"); fwrite(&bmpf, sizeof(BITMAPFILEHEADER), 1, fout); fwrite(&bmpi, sizeof(BITMAPINFOHEADER), 1, fout); //if I change the count it will offset the bitmap, //dont know what'll do it for all int count = 0; for (int i = 0; i < bmpi.biWidth; i++) { for (int j = 0; j < bmpi.biHeight; j++) { //PLaying with the info in the alpha channel palette[iPix[count]].peFlags =rand()%256; fwrite(&palette[iPix[count]], sizeof(int), 1, fout); count++; } } Please help.

Share this post


Link to post
Share on other sites
Hi,

The number of bytes in a windows DIB line is not biWidth*biBitCount/8 but

pitch = ((bm.biWidth+3)&(~3)) * bm.biBitCount/8;

Therefore:

int pitch8bits = ((bmpi.biWidth+3)&(~3));
int pixNum = bmpi.biHeight * pitch8bits;
// ...
bmpi.biSizeImage = (bmpi.biHeight * pitch32bits);

Of course, from the formula above, pitch32bits = 4 * pitch8bits;
This is really important if the (biWidth%4)!=0.

Quote:

//dont know if this matters
bmpi.biXPelsPerMeter = 0;
bmpi.biYPelsPerMeter = 0;

It doesn't, unless you want to specify the picture DPI - which is probably useless in your case.

Quote:

int paletteSize = 1<<bmpi.biBitCount;

Wuck. What is the paletteSize of a 32 bpp bitmap? :)

Quote:

palette[iPix[count]].peFlags =rand()%256;
fwrite(&palette[iPix[count]], sizeof(int), 1, fout);
count++;

Sidenote: you should use sizeof(PALETTEENTRY) instead of sizeof(int).

HTH

Share this post


Link to post
Share on other sites
I changed some of the stuff, the pitch8Bit and the sizeImage. Thanks! It makes it more generic, but i still get the same problem, the bitmap is still rolled over by half of the image. Is there a problem with taking the 8bit indexed palette entries and rewriting them as the PALETTEENTRY RGBA values after the BITMAPINFOHEADER?

my theory is this:
8bit:
BITMAPFILEHEADER, BITMAPINFOHEADER, PALLETEARRAY, INDEXEDARRAY;

32bit:
BITMAPFILEHEADER
//Modify
bmpf.bfOffBits = 12*sizeof(DWORD) + 2*sizeof(BYTE) + 2*sizeof(WORD);
bmpf.bfSize = (bmpf.bfOffBits) + 4*(bmpi.biHeight * pitch8bits);
BITMAPINFOHEADER
bmpi.biSizeImage = pitch8bits * bmpi.biHeight * 4;
bmpi.biSize = 40;
PALETTE[0];
PIXELINFO
for i-> pitch8bits * bmpi.biHeight
write(PALETTEARRAY[ INDEXARRAY [i]])

Share this post


Link to post
Share on other sites

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

If you intended to correct an error in the post then please contact us.

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