Problem with rewriting 32Bitmap from 8bit bitmap

Started by
1 comment, last by Purum 19 years, 2 months ago
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.
Advertisement
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
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 ])

This topic is closed to new replies.

Advertisement