Thread: Bitmap loader

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

    Join Date
    Oct 2004
    Rep Power

    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):

    procedure TForm1.HAttachImageClick(Sender: TObject);
    targetFile : TFileName;
    openDialog : TOpenDialog;
    myFile : File;
    index, grSize : DWORD;
    j, offset, padWidth, byteWidth, diff, size : Integer;
    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
      targetFile := '';
    if targetFile <> '' then
      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
        if (((index + 1) mod padWidth) = 0) then
          seek(myFile, {FilePos(myFile) + }offset);
        BlockRead(myFile, imageData[index], 1);
    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. #2
  3. Banned ;)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Nov 2001
    Woodland Hills, Los Angeles County, California, USA
    Rep Power
    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');
    Up the Irons
    What Would Jimi Do? Smash amps. Burn guitar. Take the groupies home.
    "Death Before Dishonour, my Friends!!" - Bruce D ickinson, Iron Maiden Aug 20, 2005 @ OzzFest
    Down with Sharon Osbourne

    "I wouldn't hire a butcher to fix my car. I also wouldn't hire a marketing firm to build my website." - Nilpo

IMN logo majestic logo threadwatch logo seochat tools logo