### Thread: Bitmap loader

1. No Profile Picture
Registered User
Devshed Newbie (0 - 499 posts)

Join Date
Oct 2004
Posts
1
Rep Power
0

#### Bitmap loader

I am writing a graphics file type, and the last part to do is load a bitmap (only 24 bit ones) and attach the graphics data. Well, it turns out to be more complicated then I thought.

Bitmaps data is aligned on DWORDS, and while I have found tutorials and implmented code to read just the pixel data, not the padding. Here is my code for loading the bitmap data (I have put in red the code that isn't working):

Code:
procedure TForm1.HAttachImageClick(Sender: TObject);
var
targetFile : TFileName;
openDialog : TOpenDialog;
myFile : File;
index, grSize : DWORD;

j, offset, padWidth, byteWidth, diff, size : Integer;

begin

openDialog := TOpenDialog.Create(self);
openDialog.InitialDir := GetCurrentDir;
openDialog.Options := [ofFileMustExist];
openDialog.Filter := 'Bitmap files|*.bmp';
openDialog.FilterIndex := 1;

if openDialog.Execute then
targetFile := openDialog.FileName
else
targetFile := '';

if targetFile <> '' then
begin

bitmapLocation := targetFile;
header.imageAttached := true;

AssignFile(myFile, targetFile);
Reset(myFile, 1);

BlockRead(myFile, bitmap1, 14);
BlockRead(myFile, bitmap2, 40);

Form1.HFileSize.Text := IntToStr(bitmap1.bfSize);
Form1.HHeaderOffset.Text := IntToStr((sizeof(TBITMAPFILEHEADER) + sizeof(TBITMAPINFO)));
Form1.HGraphicHeight.Text := IntToStr(bitmap2.bmiHeader.biHeight);
Form1.HGraphicWidth.Text := IntToStr(bitmap2.bmiHeader.biWidth);
Form1.HGraphicBPP.Text := IntToStr(bitmap2.bmiHeader.biBitCount);
Form1.HGraphicSize.Text := IntToStr(bitmap2.bmiHeader.biSizeImage);

header.fSize := bitmap1.bfSize;
header.fOffset := (sizeof(TBITMAPFILEHEADER) + sizeof(TBITMAPINFO));
header.gWdith := bitmap2.bmiHeader.biWidth;
header.GHeight := bitmap2.bmiHeader.biHeight;
header.gBPP := bitmap2.bmiHeader.biBitCount;
header.gSize := bitmap2.bmiHeader.biSizeImage;

j := header.gSize - 3;
byteWidth := header.gWdith * 3;
padWidth  := byteWidth;

while(padWidth mod 4 <> 0) do
padWidth := padWidth + 1;

diff := header.gHeight * byteWidth;
SetLength(imageData, diff);

offset := padWidth - byteWidth;

for index := 0 to (header.gSize) do
begin

if (((index + 1) mod padWidth) = 0) then
seek(myFile, {FilePos(myFile) + }offset);

BlockRead(myFile, imageData[index], 1);

end;

CloseFile(myFile);
end;
What I'm doing is checking if I am at the end of the line, and if so skipping over the padding. There are two problems:

1. I get a, "Read beyond end of file" crash. I have toyed with all the numbers, set watches, everything. I think the problem is that I am reading one too many lines in the bitmap, but I can't see the problem.

2. When I either skip the error or hack the code enough the avoid the error, the colors are wrong and it is displayed broken and diagonally. This is another problem for another time though.

Thanks for any help!
2. Are you trying to load an image to display it? If so, why not use the prewritten Delphi code for this:
1. Drop a TImage component on the form.
2. Image1.Picture.LoadFromFile('C:\path\to\picture.bmp');