I get an "EOutofresources - Not enough storage" when I try to work with BMP files when I try to set BMP.Height or BMP.Width. Imediatelly after these instructions, the stack trace is (in this order): ntdll.dll.RtlLeaveCriticalSection, kernel32.dll.FileTimeToDosDateTime, GDI32.dll.GdiReleaseDC, GDI32.dll.PatBlt, kernel32.dll.ReadFile or like this:
|7E429130|user32.dll GetParent
|7C90FF2D|ntdll.dll RtlGetNtGlobalFlags
|77F15A00|GDI32.dll GdiReleaseDC
|7C83069E|kernel32.dll FileTimeToDosDateTime
|7C9010E0|ntdll.dll RtlLeaveCriticalSection
| |my function (where I set BMP.Height or BMP.Width)
At a moment I was sure that it has to do something with memory fragmentation - the system had enough free ram to process my image BUT the memory was fragmented so there was no block large enough to hold my image. But then I have seen it happening once 11 seconds after Windows start up. My program cycled through the loop where I process the images ONLY once! So, this could not be related to RAM fragmentation.
A different situation (but still related to drawing) when I got this error is below:
|77F16A7E|GDI32.dll IntersectClipRect
|77F16FE5|GDI32.dll BitBlt
|7E429011|user32.dll OffsetRect
|7E42A97D|user32.dll CallWindowProcA
|7E42A993|user32.dll CallWindowProcA
|7C9010E0|ntdll.dll RtlLeaveCriticalSection
|7E4196C2|user32.dll DispatchMessageA
|7E4196B8|user32.dll DispatchMessageA
|0058A2E1|UTest.exe UTest.dpr
|7C90DCB8|ntdll.dll ZwSetInformationThread
I think there is always a 'RtlLeaveCriticalSection' call in the stack trace after BMP.Height.
There is this post pointing to a possible solution by editing a Windows registry key. However, the post says that it applies only to Win XP. While my error appears also on Win 7.
I see many similar posts (some of them are close connected to saving a file to disk) but until nobody came back to report that he fixed the error.
Update:
As you requested, this is the code where the error appears:
procedure TMyBitmap.SetLargeSize(iWidth, iHeight: Integer);
CONST ctBytesPerPixel= 3;
begin
{ Protect agains huge/empty images }
if iWidth< 1 then iWidth:= 1 else
if iWidth> 32768 then iWidth:= 32768;
if iHeight< 1 then iHeight:= 1 else
if iHeight> 32768 then iHeight:= 32768;
{ Set image type }
if iWidth * iHeight * ctBytesPerPixel > 9000000 {~9MB}
then HandleType:= bmDIB { Pros and cons: -no hardware acceleration, +supports larger images }
else HandleType:= bmDDB;
{ Total size is higher than 1GB? }
if (iWidth* iHeight* ctBytesPerPixel) > 1*GB then
begin
Width := 8000; { Set a smaller size }
Height := 8000; { And rise an error }
RAISE Exception.Create('Image is too large.');
end;
{ Set size }
Width := iWidth; <----------------- HERE
Height:= iHeight;
end;