Advertisement

biSizeImage

Started by November 13, 2000 08:15 PM
6 comments, last by vbisme 24 years, 1 month ago
biSizeImage Specifies the size, in bytes, of the image. This may be set to zero for BI_RGB bitmaps. BI_RGB: An uncompressed format. Whenever I open my .bmp file, the biSizeImage is always "0". How do I find when the size so that I know how much to read. And when reading, can I use (sizeof(BITMAPFILEHEADER) + someheader.bfOffBits) to set the file pointer?
  
#include <fstream.h>
#include <windows.h>
#include <winbase.h>
#include <io.h>

class BitmapFile
{
public:
	BITMAPFILEHEADER	BmpFileHeader;
	BITMAPINFOHEADER	BmpInfoHeader;
	UCHAR				*Buffer;
};

int main()
{
	HANDLE File, File2;	//file handle

	LPDWORD NumBytesWritten, NumBytesRead;	//indications

	BitmapFile	myBmpFile;

	//open file for reading

	File2 = CreateFile("bugs.bmp", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	//read the file

	ReadFile(File2, &myBmpFile.BmpFileHeader, sizeof(BITMAPFILEHEADER), NumBytesRead, NULL);
	ReadFile(File2, &myBmpFile.BmpInfoHeader, sizeof(BITMAPINFOHEADER), NumBytesRead, NULL);
	cout << "Size: " << myBmpFile.BmpFileHeader.bfSize << "\n";
	cout << "Bit-Count: " << myBmpFile.BmpInfoHeader.biBitCount << "\n";
	cout << "Offset: " << myBmpFile.BmpFileHeader.bfOffBits << "\n";
	cout << "Image Size: " << myBmpFile.BmpInfoHeader.biSizeImage << "\n";
	cout << "Image Width: " << myBmpFile.BmpInfoHeader.biWidth << "\n";
	cout << "Image Height: " << myBmpFile.BmpInfoHeader.biHeight << "\n";
	cout << "Byte Number from Offset: " << (sizeof(BITMAPFILEHEADER) + myBmpFile.BmpFileHeader.bfOffBits) << "\n";
	cout << "Byte Number from End: " << SetFilePointer(File2, -(myBmpFile.BmpInfoHeader.biSizeImage), NULL, FILE_END) << "\n";

	
	CloseHandle(File2);

	return(0);
}
  
Please help!
The BMP file format is pain with all the cases it has. I know from my own failed and working tries.

Anyways, You can find out the size in bytes of the bitmap data by multiplying the width by height by (bpp / 8). The only problem is that if the BMP width is not on a DWORD boundary, it will put in as much filler as needed to reach the nearest boundary. Here's my code to compute how much extra filler there is (widthover):


if (((bmp.infoheader.biWidth * (bmp.infoheader.biBitCount / 8)) % 4) != 0)
widthover = 4 - ((bmp.infoheader.biWidth * (bmp.infoheader.biBitCount / 8)) % 4);


Now the width with filler will be biWidth + widthover. You'll want to use that only for computing the data size in the file.

You'll want to get rid of this filler when you draw the BMP, so you might want to make a seperate allocation where you can read in the original without filler. Then delete the original and use the new one.

What you suggested to point to the data might work, but it's easier to just fseek with a negative value (which is the data size with filler) from the end.

---
my website

Edited by - densun on November 13, 2000 10:30:07 PM

Edited by - Densun on November 13, 2000 10:32:23 PM
Advertisement
I don't exactly know what the "filler" is......Why does the size has to be divisible by "4"?

Edited by - vbisme on November 13, 2000 11:31:19 PM
Microsoft likes having things divisible by four so they can use some optimization techniques. Having the bitmap data size be on a 32-bit boundary allows for speedier reading or something. That is why the width of a stored bitmap needs to be divisble by four. In case it isn''t, the bitmap will be save with up to three bytes of filler so it is, and they are just valued at zero and are not wanted when drawing (or you''ll get a black edge on the right side).

---
my website
so the height is not affected?

Thanks by the way...

One other thing, when I got the Bitmapfileheader + bitmapinfoheader + imagesize and compare the sum to the "size"...it is 2 bytes short of the size...is the some other information in the .bmp file?

Edited by - vbisme on November 13, 2000 11:50:59 PM
No, height is not affected. You''ll want to check it''s negative or not. Negative means it''s stored top-down, positive means it''s stored bottom-up.

All a BMP file has is the BITMAPFILEHEADER, BITMAPFILEINFO, and the data. To see how accurate your program is, count by yourself all the bytes in the two structures and then compute in bytes the size of the data with fillers. It could also be something with the program that saved it.

---
my website
Advertisement
I''m having problem reading the "buffer" or bitmap data:

  #include <fstream.h>#include <windows.h>#include <winbase.h>#include <io.h>class BitmapFile{public:	BITMAPFILEHEADER	BmpFileHeader;	BITMAPINFOHEADER	BmpInfoHeader;	UCHAR			*Buffer;};int main(){	HANDLE		File, File2;	//file handle	LPDWORD		NumBytesWritten, NumBytesRead//indications	BitmapFile	myBmpFile;	DWORD		FileDataSize;	//the bitmap size in bytes	DWORD		ActualDataSize;	LONG		AjustedWidth;	LONG		WidthOver = 0;		//open file for reading	File2 = CreateFile("digits.bmp", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);	//read the file	ReadFile(File2, &myBmpFile.BmpFileHeader, sizeof(BITMAPFILEHEADER), NumBytesRead, NULL);	ReadFile(File2, &myBmpFile.BmpInfoHeader, sizeof(BITMAPINFOHEADER), NumBytesRead, NULL);	if (((myBmpFile.BmpInfoHeader.biWidth * (myBmpFile.BmpInfoHeader.biBitCount / 8)) % 4) != 0)	{		WidthOver = 4 - ((myBmpFile.BmpInfoHeader.biWidth * (myBmpFile.BmpInfoHeader.biBitCount / 8)) % 4);	}	AjustedWidth = myBmpFile.BmpInfoHeader.biWidth + WidthOver;	ActualDataSize = myBmpFile.BmpInfoHeader.biWidth * myBmpFile.BmpInfoHeader.biHeight * (myBmpFile.BmpInfoHeader.biBitCount / 8);	FileDataSize = AjustedWidth * myBmpFile.BmpInfoHeader.biHeight * (myBmpFile.BmpInfoHeader.biBitCount / 8);	SetFilePointer(File2, -(FileDataSize), NULL, FILE_END);		//if (myBmpFile.Buffer) { free(myBmpFile.Buffer); }		if (!(myBmpFile.Buffer = (UCHAR *)malloc(FileDataSize)))	{		CloseHandle(File2);		return(0);	}//end if		ReadFile(File2, &myBmpFile.Buffer, FileDataSize, NumBytesRead, NULL);		CloseHandle(File2);	File = CreateFile("test.bmp", GENERIC_WRITE, 0, NULL,		CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);	WriteFile(File, &myBmpFile.BmpFileHeader, sizeof(BITMAPFILEHEADER), NumBytesWritten, NULL);	WriteFile(File, &myBmpFile.BmpInfoHeader, sizeof(BITMAPINFOHEADER), NumBytesWritten, NULL);	WriteFile(File, &myBmpFile.Buffer, FileDataSize, NumBytesWritten, NULL);	CloseHandle(File);	return(0);}  


This code, purposely open on .bmp file, read all it''s data and writing it into a new custom created .bmp. I''m just practice i/o as well as manipulating bitmaps since later I want to be able to put all my bitmap files into a single custom file.

But anyways...I''m able to read the fileheader and the info header, but can''t read the buffer...what''s wrong?
From what I saw of your code, it''s correct. I''m not too familiar with the file functions you use, but they should be similar to the ones I myself use. Sorry, but I don''t have time right now to look through all the code; maybe someone else will.

---
my website

This topic is closed to new replies.

Advertisement