EOutOfResources with GIF images
-
- Posts: 27
- Joined: Tue Jun 20, 2006 7:34 pm
- Location: Europe
EOutOfResources with GIF images
Hi.
I have a problem with displaying a large number of GIF images in TRichView.
I have a limit for number of items and I remove them with DeleteParas so the text will not grow too much.
However, there is still a problem that randomly occurs. I checked twice my code to see if there was any memory leak but all the images are correctly being removed from the memory when the program runs.
The problem results in one of possible errors (randomly):
it usually has to do with EOutOfResurces or "Incorrect Parameter" or "Cannot draw on canvas".
It seems that I am not the only one that have this problem. I found the article here: http://blagin.ru/articles/gif.html
For displaying images, I am using TGifimage build in C++Builder XE.
Is there any solution known for this problem? Any better GIF classes to use with TRichView (except vampyre imaging library that is also problematic to use in XE)? Or maybe some other solution?
Cheers,
Jacek
I have a problem with displaying a large number of GIF images in TRichView.
I have a limit for number of items and I remove them with DeleteParas so the text will not grow too much.
However, there is still a problem that randomly occurs. I checked twice my code to see if there was any memory leak but all the images are correctly being removed from the memory when the program runs.
The problem results in one of possible errors (randomly):
it usually has to do with EOutOfResurces or "Incorrect Parameter" or "Cannot draw on canvas".
It seems that I am not the only one that have this problem. I found the article here: http://blagin.ru/articles/gif.html
For displaying images, I am using TGifimage build in C++Builder XE.
Is there any solution known for this problem? Any better GIF classes to use with TRichView (except vampyre imaging library that is also problematic to use in XE)? Or maybe some other solution?
Cheers,
Jacek
-
- Posts: 27
- Joined: Tue Jun 20, 2006 7:34 pm
- Location: Europe
To give more details I present the call stack before application crash:
My experiments show that this error is somehow connected to animated gif. I.e. the exception occurs when I insert lot of not animated gifs. Animated gifs seem to have no limits.
DeleteParas is here but is I remove DeleteParas, the exception will also occur.:7512b727 KERNELBASE.RaiseException + 0x58
:005a24b0 ; Graphics::TCanvas::RequiredState
:006d8a12 ; Gifimg::TGIFFrame::Draw
:006deae1 ; Gifimg::TGIFImage::Draw
:005a1b8c ; Graphics::TCanvas::Draw
:00802f14 Rvgrin::TRVGraphicInterface::DrawGraphic + 0x14
:007f948c ; Rvitem::_16645
:007f965a ; Rvitem::TRVGraphicItemInfo::Paint
:007c2d4b ; Crvfdata::_16549
:007c3b0b ; Crvfdata::TCustomRVFormattedData::PaintTo
:0078fbc0 ; Rvctrldata::TRVControlData::PaintBuffered
:00767959 ; Richview::TCustomRichView::Paint
:005f4211 ; Controls::TCustomControl::PaintWindow
:005ee8e7 ; Controls::TWinControl::PaintHandler
:005ef0c5 ; Controls::TWinControl::WMPaint
:005f41aa Controls::TCustomControl::WMPaint + 0x16
:005ee72d ; Controls::TWinControl::WndProc
:0076bd93 ; Richview::TCustomRichView::WndProc
:006542be Classes::_17544 + 0x16
:76716238 ; C:\Windows\syswow64\USER32.dll
:76717298 USER32.GetDC + 0x52
:76717177 ; C:\Windows\syswow64\USER32.dll
:767172f1 USER32.GetDC + 0xab
:772500e6 ntdll.KiUserCallbackDispatcher + 0x2e
:005f145a Controls::TWinControl::Update(Controls::TWinControl * const ) + 0x1A
:007c59a1 ; Crvfdata::TCustomRVFormattedData::DeleteParas
My experiments show that this error is somehow connected to animated gif. I.e. the exception occurs when I insert lot of not animated gifs. Animated gifs seem to have no limits.
-
- Site Admin
- Posts: 17557
- Joined: Sat Aug 27, 2005 10:28 am
- Contact:
-
- Posts: 27
- Joined: Tue Jun 20, 2006 7:34 pm
- Location: Europe
Hi Sergey,Sergey Tkachenko wrote:Did you include RVGifAnimate2007 in your project?
Without this unit, animated gifs use too many resources.
When this unit is included, resource usage is optimized.
yes I include the file in this way:
Code: Select all
#include <RVGifAnimate2007.hpp>
#pragma link "RVGifAnimate2007"
I prepared a small demo project that, when run on my computer, triggers an error after pressing "Start Non-Animated":
http://www.2shared.com/file/vCOTZAPS/test.html
The demo project includes one non-animated and one animated gif files in debug directory.
Cheers,
Jacek
-
- Site Admin
- Posts: 17557
- Joined: Sat Aug 27, 2005 10:28 am
- Contact:
Well, as you can see, you can add 40,000 animated gifs in TRichView control, and the application still works.
But if you try the same with static gifs, you get an exception about a shortage of resources.
Why does it happen? For animated gifs, TRichView uses its own special code for drawing TGifImage, using as less resources as possible.
For static images, TRichView just uses graphic.Draw method. Unfortunately, TGifImage caches some resources (bitmap, mask, palette) after drawing an image, and you quickly run out of resources.
There are no memory/resource leaks, they just caches too much.
Well, I can implement a special fake animator even for static gifs.
But the latest version of TRichView offers a better solution: shared images. You can use only one copy of TGifImage for inserting as many images as you want.
TRichView 13 will be available in the next couple of days.
PS: FormatTail() should be used only when the next portion of document is added from a new line.
But if you try the same with static gifs, you get an exception about a shortage of resources.
Why does it happen? For animated gifs, TRichView uses its own special code for drawing TGifImage, using as less resources as possible.
For static images, TRichView just uses graphic.Draw method. Unfortunately, TGifImage caches some resources (bitmap, mask, palette) after drawing an image, and you quickly run out of resources.
There are no memory/resource leaks, they just caches too much.
Well, I can implement a special fake animator even for static gifs.
But the latest version of TRichView offers a better solution: shared images. You can use only one copy of TGifImage for inserting as many images as you want.
Code: Select all
TGIFImage *gifImage = new TGIFImage();
gifImage->LoadFromFile(file);
for (int i = 0; i < 50; ++i)
{
for (int j = 0; j < 200; ++j)
{
RichView1->AddPictureEx(L"abc", gifImage, -1, rvvaBaseline);
RichView1->SetItemExtraIntProperty(RichView1->ItemCount-1, rvepShared, 1);
}
RichView1->FormatTail();
Application->ProcessMessages();
}
// do not free gifImage until RichView1 is cleared.
PS: FormatTail() should be used only when the next portion of document is added from a new line.
-
- Posts: 27
- Joined: Tue Jun 20, 2006 7:34 pm
- Location: Europe
Hi Sergey,
thanks for help.
Yes, it is a good idea to give a possibility of suppressing the destruction of that images. I was already testing it and it works until clearing of control which then tries to delete many pointers of the same object instance.
Fake animator from the other side, will be probably easier to use for many people (easy to understand)
Additionally, fake animator will handle the situation when 40 000 distinct, static images are being inserted into the control (when the shared method will probably fail).
Cheers, Jacek
thanks for help.
Yes, it is a good idea to give a possibility of suppressing the destruction of that images. I was already testing it and it works until clearing of control which then tries to delete many pointers of the same object instance.
Fake animator from the other side, will be probably easier to use for many people (easy to understand)
Additionally, fake animator will handle the situation when 40 000 distinct, static images are being inserted into the control (when the shared method will probably fail).
Cheers, Jacek
-
- Posts: 27
- Joined: Tue Jun 20, 2006 7:34 pm
- Location: Europe
Hi Anders,Anders wrote:An easy solution might be to call TGIFImage.Dormant after TGIFImage.Draw.
TGIFImage.Dormant releases all cached resources so it should reduce resource use but will probably also increase the CPU usage on redraws.
yes, it is possible, but it requires the modification in the component source on each update (that is problematic).
Is there any chance that you could add the cache disabling option in TGIFImage?
Also, I think, the error of the memory scarcity of TGIFImage should not be severe to application and caught internally - or maybe there is some way of catching it that I don't know about? My users experiencing now crashes of the application just because of small gif problem - that's not desirable.
Cheers, Jacek
Then ask Sergey to add it to the TRichView source. It's an easy fix (although it's a hack):Jacek Puczynski wrote:yes, it is possible, but it requires the modification in the component source on each update (that is problematic).
Code: Select all
Canvas.StretchDraw(Image, ...);
if (Image is TGIFImage) then
TGIFImage(Image).Dormant;
No.Jacek Puczynski wrote:Is there any chance that you could add the cache disabling option in TGIFImage?
Embarcadero is the current maintainer of TGIFImage. You can ask them (through QC) but IMO it would be a waste of your time. They have fixed some of the bugs I have reported, but they have never implemented any of the improvements I have posted over the years so I've simply stopped reporting feature and improvement requests.
Well, yes it's unfortunate but TGIFImage was never meant to used the way you are using it. The current implementation is optimized for performance rather than resources - as you've discoveredJacek Puczynski wrote:Also, I think, the error of the memory scarcity of TGIFImage should not be severe to application and caught internally
-
- Site Admin
- Posts: 17557
- Joined: Sat Aug 27, 2005 10:28 am
- Contact:
I cannot add the code using TGifImage directly in TRichView files, because using TGifImage is optional (units playing gif animations are exceptions, because they could be included in projects or not).
But of course, some solution is possible. But we need some time to complete the release of trichview 13 before starting making changes.
Anders, thanks for participating
But of course, some solution is possible. But we need some time to complete the release of trichview 13 before starting making changes.
Anders, thanks for participating