Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

EOutOfResources sometimes?

330 views
Skip to first unread message

Antony Hoon

unread,
Jun 27, 2001, 10:24:34 AM6/27/01
to
Hi,

I get all the .BMP .GIF .JPG files in a directory into a TStringList.
And then create thumbnails of them. The problem is *sometime* I get
EOutOfResources with message 'The parameter is incorrect' using
D5/W98B on 2 marked lines below. Using ResMon, everything is still
above 50% sometimes 70%.
What might be the cause of this? If it's out of handle/resources, the
procedure get next files correctly.
And also, it's really only *sometime* (about 20% occansion), if I load
the same directory again, the problem might or might not happen.

Here's what I use:

PImageInfo= ^TImageInfo;
TImageInfo= record
FileName: string;
ThumbCreated: Boolean;
MemStream: TMemoryStream;
Rect: TRect;
end;

procedure LoadThumbs;
var bmp: TImage;
FBuffer: TBitmap;
aII: PImageInfo;
begin
<snip> // All objects are already created
while i <= FFileList.Count-1 do
try
aII := Pointer(FFileList.Objects[i]);
bmp.Picture.LoadFromFile(aII.FileName); // load the file

< snip > // calc rect with aspect ratio (thanks to efg's lab
:-) )

FBuffer.Canvas.StretchDraw(ThumbDst, bmp.picture.Graphic);
// EOutOfResources sometimes above

FBuffer.Dormant;
FBuffer.FreeImage;

aII.MemStream := TMemoryStream.Create;
FBuffer.SaveToStream(aII.MemStream);
// Or EOutOfResources above

aII.MemStream.Seek(0,0);
aII.ThumbCreated := True;
aII.Rect := ThumbDst;
except
on E: Exception do
ShowMessage( E.ClassName + #13#10 + E.Message);
end;

--
Antony Hoon
Delphi Addicted
(Replace 4x7 with 7777 to reply..)

Francesco Savastano

unread,
Jun 27, 2001, 1:20:55 PM6/27/01
to

Antony Hoon <anto...@telkom.net> wrote in message 3b39ed80_2@dnews...
Are you sure you don't have a tmemorystream resource leak ? Do you free the
stream before creating it again ?


Francesco Savastano

unread,
Jun 27, 2001, 1:23:34 PM6/27/01
to
Also i don't see where you create and free fbuffer ...


Joris Van Damme

unread,
Jun 27, 2001, 8:28:03 PM6/27/01
to
Francesco Savastano wrote:
> Are you sure you don't have a tmemorystream resource leak ? Do you free the
> stream before creating it again ?

Is it really necessary to have us all scroll through 2 pages of code to
see these 2 lines you added?

Please, take a look at

http://web.infoave.net/~dcalhoun/nnq/nquote.html

Antony Hoon

unread,
Jun 27, 2001, 10:54:08 PM6/27/01
to
"Francesco Savastano" <france...@tiscalinet.it> wrote in message
news:3b3a1c4e_2@dnews...

> Are you sure you don't have a tmemorystream resource leak ? Do you
free the
> stream before creating it again ?

Yes, I'm sure. Prior entering the while loop, I already created the
bmp and FBuffer.
and outside the while loop, I free them. I just snipped the long
procedure short.

My way to do this:
1. load the file using timage.
2. use stretchdraw to draw the thumbnail to a buffer.
3. save the buffer to a tmemorystream.
4. When needed, I create a TBitmap and then load the image from the
stream.
Is this the correct way ?
Does TMemoryStream need any handle (USER/GDI/etc) ?

FBuffer.Canvas.StretchDraw(ThumbDst, bmp.picture.Graphic);
FBuffer.SaveToStream(aII.MemStream);
Only these two line cause it. Strange thing is, after an
EOutOfResources, the procedure loop back up and can do its job.
It's really driving me crazy. Please help.

Francesco Savastano

unread,
Jun 28, 2001, 6:14:18 AM6/28/01
to

Antony Hoon <anto...@telkom.net> wrote in message 3b3aa89f_2@dnews...

And what about the creating and freeing of tmemorystreams ? You shouldn't
create a tmemorystream in the while loop if you free it only once after the
loop : any time you create the stream you are not creating the same stream
but you are allocating new memory even if the name of the stream variable is
the same .
Solution :

You have to both create the stream and free it or inside the loop or outside
the loop : remember that each create method should have its correspondent
free method !


Francesco Savastano

unread,
Jun 28, 2001, 6:23:21 AM6/28/01
to

Joris Van Damme <as.van.da...@planetinternet.be> wrote in message
3B3A7A13...@planetinternet.be...

Ok , you are right , i have a tendency to not delete the quotes that Outlook
automatically creates , but you should also tell the people that write in
the newsgroup of not posting kilometric messages : if they have a long piece
of code to show they should post the attachment in the proper newsgroup . If
you want that other respect you then respect the others first : if you don't
want to see extremely quoted messages then you shouldn't write extremely
long questions : the question should be synthetic and should have a little
example of code not the whole unit or a procedure that does not fit in one
page ....


Thérèse Hanquet

unread,
Jun 28, 2001, 7:01:27 AM6/28/01
to
Hi Francesco,

> Ok , you are right , i have a tendency to not delete the quotes that
Outlook
> automatically creates , but you should also tell the people that write in
> the newsgroup of not posting kilometric messages

Overquoting long messages is specially annoying when the answer is behind
the quote, because you have to browse the whole message to find the new
part.

Thérèse


Joris Van Damme

unread,
Jun 28, 2001, 10:25:01 AM6/28/01
to
Francesco Savastano wrote:
> > Please, take a look at
> >
> > http://web.infoave.net/~dcalhoun/nnq/nquote.html
>
> Ok , you are right , i have a tendency to not delete the quotes that Outlook
> automatically creates

Thank you for reading the link!!

> but you should also tell the people that write in
> the newsgroup of not posting kilometric messages

I try to be as brief as possible, and not to quote anything that is not
necessary. I also try to continue conversations about stuff that I think
nobody else is interested in out of the ng, though private mail.
However, some stuff is both a big subject that can't be solved in a few
lines, and potentially interesting to others. For example, in the answer
to your red eye problem, I mentioned the color space quality is vital.
If I elaborated on my own solution for this (I couldn't, it's company
property), it would surely have been a 'kilometric message'. But I don't
think you would have mind, and I do think it would potentially have been
interesting to others. That is why I think/thought such a message is not
always a bad thing.

Anyway, I'll keep your comment in mind, and will try even harder to be
as brief as possible.

Joris

Antony Hoon

unread,
Jun 29, 2001, 9:19:22 AM6/29/01
to
"Francesco Savastano" <france...@tiscalinet.it> wrote in message
news:3b3b09c2$1_1@dnews...

> And what about the creating and freeing of tmemorystreams ? You
shouldn't
> create a tmemorystream in the while loop if you free it only once
after the
> loop : any time you create the stream you are not creating the same
stream
> but you are allocating new memory even if the name of the stream
variable is
> the same .

The tmemorystreams are used outside the loop. So it will be freed by
another procedure. I have the list of all TmemoryStreams created.
As soon as the user choose another directory, all the memory streams
are freed, the list is cleared, and the process to load starts again.

Francesco Savastano

unread,
Jun 29, 2001, 6:11:53 PM6/29/01
to

> The tmemorystreams are used outside the loop. So it will be freed by
> another procedure. I have the list of all TmemoryStreams created.
> As soon as the user choose another directory, all the memory streams
> are freed, the list is cleared, and the process to load starts again.
>
> --
> Antony Hoon
> Delphi Addicted
> (Replace 4x7 with 7777 to reply..)
>
>
>
>
Sorry , you are right , i have just given a better look to your code and now
i understand it..
The problem is not the memorystream as you say : One question : why to use a
timage to load gif ,jpg ,bmp ? you could use non-visual objects like
Tjpegimage , Tbitmap , Tgif to load them (i always prefer non visual objects
when i need to do such operations...but this is only my way to do this....)
:
It seems that the problem is related to fbuffer because like you say the
error occurs in both the cases when you are trying to access this object : i
don't see where you set the width and the height of fbuffer : for my
experience an eout of resources error message can be displayed at least in 2
cases : when you have many bitmaps created (many windows handles and gdi
resources occupied) and when you try to create a very large bitmap : perhaps
if you analize better these 2 possible causes you can find out the solution
.
If some other idea will come into my mind i will tell you...you know i had
very bad problems with windows resources when i began graphics programming
and so now that i have more experience i always try to be very careful with
this kind problem...if you find the bug i would like to know it too..
good luck,
Francesco.


Thérèse Hanquet

unread,
Jun 30, 2001, 2:34:44 AM6/30/01
to
Hi Antony,

> FBuffer.Canvas.StretchDraw(ThumbDst, bmp.picture.Graphic);
> FBuffer.SaveToStream(aII.MemStream);
>
> Only these two line cause it. Strange thing is, after an
> EOutOfResources, the procedure loop back up and can do its job.

Can you identify if a particular picture causes this? There is for example a
known problem with JPGs between 1 and 2 Mo when you use the Jpeg unit.

Thérèse


Antony Hoon

unread,
Jun 30, 2001, 5:50:41 AM6/30/01
to
"Francesco Savastano" <france...@tiscalinet.it> wrote in message
news:3b3d038d_2@dnews...

> The problem is not the memorystream as you say : One question : why
to use a
> timage to load gif ,jpg ,bmp ?
Laziness <g>. With TImage I don't have to check the extension and
create appropriate objects. Furthermore, I think it's ok since I only
use one TImage in the loop.

> for my
> experience an eout of resources error message can be displayed at
least in 2
> cases : when you have many bitmaps created (many windows handles and
gdi
> resources occupied) and when you try to create a very large bitmap :
perhaps
> if you analize better these 2 possible causes you can find out the
solution

Yes, that's my understanding of out of resources too.
1. Many bitmaps created. But I only use one TImage and one TBitmap
each loop, no more than that. For displaying I use TPaintBox. I even
call TControlCanvas(paintbox.Canvas).FreeHandle for saving resources.
2. Large bitmap. It happens regardless on the size. That's what makes
it even confusing.

> If some other idea will come into my mind i will tell you...you know
i had
> very bad problems with windows resources when i began graphics
programming
> and so now that i have more experience i always try to be very
careful with
> this kind problem...if you find the bug i would like to know it
too..

Thank you, I really eappreciate it. I will tell you when I find the
bug. Although I think I have narrow it down a bit. Please see my reply
to Thérèse Hanquet on this thread.
Oh, and this is my first time in graphics programming too, what a
frustrating one..

> good luck,
> Francesco.

Antony Hoon

unread,
Jun 30, 2001, 5:50:39 AM6/30/01
to
"Thérèse Hanquet" <therese...@skynet.be> wrote in message
news:3b3d729e_2@dnews...

No, no particular images. Happened to any type, any size.

I made a mistake when with my first post. After some deep anbd tiring
debugging, I found out the EOutOfResources happened on
FBuffer.Dormant.

FBuffer.Canvas.StretchDraw(ThumbDst, bmp.picture.Graphic);
FBuffer.Dormant; // <- actually here..
FBuffer.FreeImage

I took out Dormant and FreeImage. Now it only happens to SaveToStream.
I debugged into VCL: SaveToStream eventually call
TBitmap.SaveToStream.
In it, a line:
Save := GDICheck(SelectObject(FCanvas.FHandle, FDIBHandle));

This is the most probable cause of the EOutOfResources. I put a
breakpoint on GDIError and the call stack pointed to this line.

Any ideas?
Btw, I do use JPEG and RxGif units.

--
Antony Hoon
Delphi Addicted
(Replace 4x7 with 7777 to reply..)

>
> Thérèse
>
>


Thérèse Hanquet

unread,
Jun 30, 2001, 7:55:34 AM6/30/01
to
Hi Antony,

> In it, a line:
> Save := GDICheck(SelectObject(FCanvas.FHandle, FDIBHandle));
>
> This is the most probable cause of the EOutOfResources. I put a
> breakpoint on GDIError and the call stack pointed to this line.
>
> Any ideas?

I only know superficially Graphics.pas, but this seems to indicate there is
a problem with the handle of the bitmap contained in TBitmapImage (which
Save should retrieve) before FDIBHandle is selected. This could explain also
why Dormant fails.

I have very little experience with TImage and with StretchDraw. Besides I
don't see in your code where you set the HandleType and/or PixelFormat of
FBuffer, but I will try a guess in the dark: as you might have different
file formats, you might have different color depths, and in some cases (GIFs
for example) a palette. Maybe the fact that the same bitmap must accomodate
successively those different formats causes trouble? To check this, maybe
you could try to create, customize and free FBuffer inside the While loop to
see if the problem remains...

Good luck anyway.

Thérčse


Francesco Savastano

unread,
Jun 30, 2001, 9:10:22 AM6/30/01
to
Hi , Therese !

> I only know superficially Graphics.pas, but this seems to indicate there
is
> a problem with the handle of the bitmap contained in TBitmapImage (which
> Save should retrieve) before FDIBHandle is selected. This could explain
also
> why Dormant fails.
>
> I have very little experience with TImage and with StretchDraw. Besides I
> don't see in your code where you set the HandleType and/or PixelFormat of
> FBuffer

Yes i agree that it is very important that Antony sets the pixelformat of
fbuffer : i would set pixelformat to pf24bit ( i hate working with other
pixel formats expecially 8 bit , you know for the Palette problems...)

About the dormant and freeimage i make you a confession : i never use them
(even our very kind friend Earl Glynn says that these commands do not make
any useful difference ...if i well remember his words...) . Sometimes when a
command or a function is not very useful it can be better to eliminate it
(or comment it out) from the code to make the job easier..you
know..expecially when you are debugging...

Francesco


Antony Hoon

unread,
Jul 1, 2001, 1:58:32 AM7/1/01
to
"Thérèse Hanquet" <therese...@skynet.be> wrote in message
news:3b3dbdd1_2@dnews...

> I only know superficially Graphics.pas, but this seems to indicate
there is
> a problem with the handle of the bitmap contained in TBitmapImage
(which
> Save should retrieve) before FDIBHandle is selected. This could
explain also
> why Dormant fails.

Umm... <blush> I don't really get that.. but never mind.. <g> I'm not
much a graphics programmer actually. This is just a thumbnailer..
<vbg>

> Maybe the fact that the same bitmap must accomodate
> successively those different formats causes trouble? To check this,
maybe
> you could try to create, customize and free FBuffer inside the While
loop to
> see if the problem remains...

I tried to, I create the TImage and TMemoryStream in the loop and free
it before looping up, no success..

> "Francesco Savastano" <france...@tiscalinet.it> wrote in message

news:3b3dd60e_2@dnews...


> Yes i agree that it is very important that Antony sets the
pixelformat of
> fbuffer : i would set pixelformat to pf24bit ( i hate working with
other
> pixel formats expecially 8 bit , you know for the Palette
problems...)

Yes, I didn't set the pixelformat... I'll try it after reading the
newsgroup, and I'll let you know..

> About the dormant and freeimage i make you a confession : i never
use them
> (even our very kind friend Earl Glynn says that these commands do
not make
> any useful difference ...if i well remember his words...) .

Well, I just know there is a Dormant method when I stumble into this
problem. EOutOfResources and then I saw Dormant's online help mentions
'save resources', then I use it. Actually I don't even know what it is
for.. <blush again>

Thanks you all.. :-)

Thérèse Hanquet

unread,
Jul 1, 2001, 3:23:58 AM7/1/01
to
Hi Antony,


> Umm... <blush> I don't really get that.. but never mind.. <g>

Don't blush! :)

I am not sure to understand the whole thing and this is just a guess.

The return value of SelectObject when the object selected is a bitmap is the
handle of the bitmap that was previously selected (hence the name Save for
the variable, I suppose).
GDIError is raised by GDICheck when the return value is 0. This could have
several causes, such as:
- there is no bitmap with a valid handle selected in the device context of
FImage when SelectObject is called;
- SelectObject fails because the bitmap is already selected in another
device context (but I don't see how this could happen in your case);
- others I don't know of ;)

I am not sure to understand well Dormant either (I should blush too) but the
source mentions that InternalDeletePalette may fail if FreeContext is not
called. Hence it seems possible that Dormant will be troubled if the format
is not the one expected - for example is there should be a palette and there
is not - or reversely. Again it's just a guess...

> I tried to, I create the TImage and TMemoryStream in the loop and free
> it before looping up, no success..

Well in this case I did not mean the TImage neither the TMemoryStream but
the TBitmap (FBuffer) you use to draw the thumbnail.

> Yes, I didn't set the pixelformat... I'll try it after reading the
> newsgroup, and I'll let you know..

Thanks. I am sure other people will be interested too.

Thérèse


Antony Hoon

unread,
Jul 1, 2001, 10:32:30 AM7/1/01
to
Hello,

I solved the problem after 10 hours of continous trial and error, not
to mention dozens of reboot. <g>

I forgot to tell you that the thumbnails are created in another thread
(sorry), although EOutOfResources does not has any apparent problem
with thread at first glance. But here is:

FBuffer.Canvas.StretchDraw(ThumbDst, bmp.Graphic); <- This is not
called from main thread.

After I put that in a procedure and use Synchronize to call it,
everything went smoothly.

At first I thought, since FBuffer, bmp are all created in the TThread,
I don't need Synchronize. I don't actually know the reason why I need
to use Synchronize here.

This is actually part of a freeware TThumbnail component. I'll contact
you as soon as it is finished. :-)

Thanks again for all your help.

0 new messages