Einzelnen Beitrag anzeigen

hboy

Registriert seit: 16. Jan 2004
364 Beiträge
 
#1

TBitmap erzeugt stream read error bei bestimmten Bitmaps

  Alt 14. Jan 2011, 15:31
Beim Öffnen der angehängten Bilder in Delphi7 wird in TBitmap die Systemroutine CreateDIBSection aufgerufen. Diese belegt den Speicher für die Pixelinformationen, jedoch nach den Headerinformationen. Daraufhin entsteht ein Stream Read Error, da die verbleibende Dateigröße vom reservierten Speicher abweichen kann. Ob die gesamte Dateigröße im file header nun stimmt oder nicht, ist dabei unerheblich.

Ich habe das mal auf die Schnelle durch Neuberechnung des Pixelspeichers gelöst. hier ein Auszug von TBitmap.ReadDIB(...):

Delphi-Quellcode:
[...]
          BMHandle := CreateDIBSection(DC, BitmapInfo^, DIB_RGB_COLORS, BitsMem, 0, 0);
          if (BMHandle = 0) or (BitsMem = nil) then
            if GetLastError = 0 then InvalidBitmap else RaiseLastOSError;

          try
{$IFDEF LINUX}
[...]
{$ENDIF}

            // (2011-01-14): I noticed that the BitsMem size returned by
            // the system routine CreateDIBSection(...) is the exact
            // amount of memory needed for the image so any accidental padding
            // after the image data block will cause an unhandled stream read
            // error because ImageSize is too large.
            // for uncompressed images, it is easy to recalculate the size
            if (BitmapInfo^.bmiHeader.biCompression = BI_RGB) then
            begin
               ImageSize := (((BitmapInfo^.bmiHeader.biWidth * BitmapInfo^.bmiHeader.biBitCount+7) div 8 +3) div 4) * 4
                             * BitmapInfo^.bmiHeader.biHeight;
            end;
            Stream.ReadBuffer(BitsMem^, ImageSize);
          except
            DeleteObject(BMHandle);
            raise;
          end;
[...]
Dabei habe ich mich auf unkomprimierte bitmaps beschränkt. MSPaint und andere Programme verschlucken sich nicht an den Bildern und eine Klasse von TBitmap abzuleiten, die den Fehler behebt erscheint mir nicht die richtige Vorgehensweise zu sein.

Gibt es eine bessere Lösung, die vielleicht allgemeingültiger ist?
Angehängte Dateien
Dateityp: rar test_bmp.rar (68,2 KB, 1x aufgerufen)
Power is nothing without TControl

Geändert von hboy (14. Jan 2011 um 15:35 Uhr)
  Mit Zitat antworten Zitat