Page 1 of 1

A GIF Image Corrupts RVF Documents

Posted: Sun Jul 23, 2006 11:55 pm
by Michel
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

Posted: Mon Jul 24, 2006 7:39 pm
by Sergey Tkachenko
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.

Posted: Mon Jul 24, 2006 7:51 pm
by Sergey Tkachenko
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:

Code: Select all

    Pos: Integer;
    InvalidGraphic: TGraphic;
2) The end of this procedure (starting from the line
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;
The only problem with this new code: no error messages or warnings if such replacement happens.

Posted: Mon Jul 24, 2006 7:55 pm
by Sergey Tkachenko
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

Code: Select all

type
  TGifImage = type TJvGifImage
(of course, unit GifImage.pas must be removed from the project, and RVJvGifAnimate.pas must be used instead of RVGifAnimate.pas).

Posted: Mon Jul 24, 2006 11:12 pm
by Michel
Hi Sergey,
This is a problem with TGifImage.
Yep, looks like it. Your test gave me an idea (see below).
Ok, here are the changes in RVItem.pas.[...]
The only problem with this new code: no error messages or warnings if such replacement happens.
Thanks for a quick fix!
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.
Try using another Gif class, for example TJvGifImage from JVCL.
I suppose I could, but you never know what other hidden surprises it may have...

Thank you once again!

Michel

Posted: Wed Aug 02, 2006 10:07 am
by shmp
Hi Michel,

I have used the other gif units before. Only two are very stable. I am using JVgifImage and it has given me no problem so far. The other gif unit seems to have no support for a very long time, and I can't even remember the URL address.

Just sharing.

Henry

Posted: Wed Aug 02, 2006 5:05 pm
by Michel
Hi Henry,

Thanks for the info! :)

Michel