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?