Hi Sergey,
I ran into a rather serious problem. Here are the steps to reproduce.
1. Download the following animated GIF image from the Web: http://www.cyberisle.com/animate/animals/run-cat.gif
2. In your pre-compiled RVActionTest 1.9.8, create a new blank document and insert the above image into it (everything seems to be fine at this point: the image is nicely animated)
3. Save the document as Abc1.rvf or whatever (seemingly, no problems)
4. Open the just-saved Abc1.rvf - at this point, the image is all white, but you can still select it in the document
5. Save the already apparently half-corrupted document as Abc2.rvf (the document is saved but we also get the "Error saving file" message)
6. The Abc2.rvf file is completely corrupted.
I first caught this problem in the DB-aware version where I don't seem to be getting any notification of the above problem (nothing similar to the return value of SaveRVF()), so I can't even warn the user or attempt to prevent data loss. This is rather catastrophic since a user can completely lose his document just because he inserted a picture like the one above.
I tried the above GIF in a regular project with TGIFImage and TImage components and didn't see any problems. If the GIF is in some way corrupted or unusual, I don't know what may be wrong with it. TRichView should not corrupt documents even with completely corrupt images though.
I hope this can be fixed easily enough!
Thanks,
Michel
A GIF Image Corrupts RVF Documents
-
- Site Admin
- Posts: 17555
- Joined: Sat Aug 27, 2005 10:28 am
- Contact:
This is a problem with TGifImage.
I created a very simple test project:
Image1.Picture.LoadFromFile('d:\run-cat.gif');
Image1.Picture.SaveToFile('d:\run-cat2.gif');
Image2.Picture.LoadFromFile('d:\run-cat2.gif');
When I run it, I can see an empty picture in Image2.
If I add the line:
Image2.Picture.SaveToFile('d:\run-cat3.gif');
an exception occurs.
I created a very simple test project:
Image1.Picture.LoadFromFile('d:\run-cat.gif');
Image1.Picture.SaveToFile('d:\run-cat2.gif');
Image2.Picture.LoadFromFile('d:\run-cat2.gif');
When I run it, I can see an empty picture in Image2.
If I add the line:
Image2.Picture.SaveToFile('d:\run-cat3.gif');
an exception occurs.
-
- Site Admin
- Posts: 17555
- Joined: Sat Aug 27, 2005 10:28 am
- Contact:
Ok, here are the changes in RVItem.pas.
After these changes, if an exception occurs on image saving, RVStyle.InvalidPicture is saved instead.
1) In the procedure TRVGraphicItemInfo.SaveRVF, add to var:
2) The end of this procedure (starting from the line
if SaveType<>1 then begin) must be the following:
The only problem with this new code: no error messages or warnings if such replacement happens.
After these changes, if an exception occurs on image saving, RVStyle.InvalidPicture is saved instead.
1) In the procedure TRVGraphicItemInfo.SaveRVF, add to var:
Code: Select all
Pos: Integer;
InvalidGraphic: TGraphic;
if SaveType<>1 then begin) must be the following:
Code: Select all
if SaveType<>1 then begin
Pos := Stream.Position;
try
RVFWriteLine(Stream, Image.ClassName);
SaveRVFExtraProperties(Stream);
if rvfoSaveBinary in TCustomRVData(RVData).RVFOptions then
RVFSavePictureBinary(Stream, Image)
else
RVFWriteLine(Stream, RVFSavePicture(Image));
except
if Stream.Size=Stream.Position then
Stream.Size := Pos;
Stream.Position := Pos;
InvalidGraphic := TCustomRVData(RVData).GetRVStyle.InvalidPicture.Graphic;
RVFWriteLine(Stream, InvalidGraphic.ClassName);
SaveRVFExtraProperties(Stream);
if rvfoSaveBinary in TCustomRVData(RVData).RVFOptions then
RVFSavePictureBinary(Stream, InvalidGraphic)
else
RVFWriteLine(Stream, RVFSavePicture(InvalidGraphic));
end;
end
else
SaveRVFExtraProperties(Stream);
end;
Last edited by Sergey Tkachenko on Mon Jul 24, 2006 7:56 pm, edited 1 time in total.
-
- Site Admin
- Posts: 17555
- Joined: Sat Aug 27, 2005 10:28 am
- Contact:
Try using another Gif class, for example TJvGifImage from JVCL.
May be it does not have this problem.
For quick moving from one implementation to another without changing all RVF documents, add the line
(of course, unit GifImage.pas must be removed from the project, and RVJvGifAnimate.pas must be used instead of RVGifAnimate.pas).
May be it does not have this problem.
For quick moving from one implementation to another without changing all RVF documents, add the line
Code: Select all
type
TGifImage = type TJvGifImage
Hi Sergey,
I figured that as an added protection I can test all GIF images when the user decides to insert them into the document. To do this, I use pretty much what your pseudo-code did - except I'm saving/reloading to/from a stream. Works like a charm. Pasted images are not tested, but that shouldn't cause too many problems.
Thank you once again!
Michel
Yep, looks like it. Your test gave me an idea (see below).This is a problem with TGifImage.
Thanks for a quick fix!Ok, here are the changes in RVItem.pas.[...]
The only problem with this new code: no error messages or warnings if such replacement happens.
I figured that as an added protection I can test all GIF images when the user decides to insert them into the document. To do this, I use pretty much what your pseudo-code did - except I'm saving/reloading to/from a stream. Works like a charm. Pasted images are not tested, but that shouldn't cause too many problems.
I suppose I could, but you never know what other hidden surprises it may have...Try using another Gif class, for example TJvGifImage from JVCL.
Thank you once again!
Michel