PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Sunday, July 17, 2022

[FIXED] How to extract frames from this GIF image? (Access violation in TGIFRenderer.Draw)

 July 17, 2022     delphi, delphi-xe7, gif, graphics     No comments   

Issue

I have this functions that extracts frames from animated GIFs. It works with all GIFs except this one: enter image description here

{ Loads a GIF. Returns a list of BMP frames }
function GetGifFrames(GifFile: string): TObjectList;
var
  GIF: TGIFImage;
  TempFrame: TBitmap; 
  Frame: TBitmap;
  Counter: Integer;
  GR: TGIFRenderer;
begin
 { Load GIF }
 GIF := TGIFImage.Create;
 TRY
  TRY
   Gif.Animate := FALSE;
   GIF.LoadFromFile(GifFile);
  EXCEPT
    MesajError('Cannot load '+ GifFile);
    EXIT(NIL);
  END;

  if Gif.Images.Count= 1 then
   begin
     MsgError('This is not an animated GIF'+ CRLF+ GifFile);
     EXIT(NIL);
   end;

  Result:= TObjectList.Create;
  Result.OwnsObjects:= TRUE;                                   { Array of images }

  { GIF render }
  TempFrame:= TBitmap.Create;
  GR:= TGIFRenderer.Create(GIF);                               { GIF render }
  TRY
   TempFrame.SetSize(GIF.Width, GIF.Height);

   for Counter:= 0 to GIF.Images.Count-1 DO
    begin
      { Skip bad frames }
      if GIF.Images[Counter].Empty
      then Continue;

      { Create new frame }
      Frame:= TBitmap.Create;
      Frame.SetSize(GIF.Width, GIF.Height);
      GR.Draw(TempFrame.Canvas, TempFrame.Canvas.ClipRect);   <---------- AV here   { Transfer image from GIF to BMP }     
      Frame.Assign(TempFrame);
      Result.Add(Frame);                                       { Add to list of bitmap frames }
      GR.NextFrame;                                            { Advance }
    end;

  FINALLY
   FreeAndNil(GR);
   FreeAndNil(TempFrame);
  END;

  FINALLY
   FreeAndNil(GIF);
 END;
end;

I have an AV on the line indicated above

Debugger Exception Notification Project Tester.exe raised exception class $C0000005 with message 'access violation at 0x005d3924: read of address 0x0000002c'.

Update: Compilable tester here or here.

The stack trace is:

   GetGifFrames('C:\Test gif\err.gif')
   GIFImg.TGIFRenderer.Draw($7EFA9070,(0, 0, 108, 146, (0, 0), (108, 146)))
   GIFImg.TGIFRenderer.GetBitmap
   GIFImg.TGIFRenderer.RenderFrame

Here in Render frame it crashes on this line:

PreviousBuffer.Canvas.CopyRect(PreviousBuffer.Canvas.ClipRect, Buffer.Canvas, Buffer.Canvas.ClipRect);

This is because PreviousBuffer is NIL!!!!

How to fix this?


Solution

One of the properties of a frame in a GIF file is the DisposalMethod which defines how the image in the frame should be disposed of in preparation of the next frame. In the original file ("Sansanimated.gif" link at the top of the post) this is set to dmNoDisposal for all 13 frames. This works as such in your code without problems. In the file "err.gif" the two frames both have dmPrevious which require an extra internal bitmap. This bitmap is not allocated if the GIFRenderer is not initialized as being animating.

To have the GIFRenderer properly initialized for frames with dmPrevious disposal method setting add one line

GR.Animate := True;  // <---- add this line

right after creating GR.



Answered By - Tom Brunberg
Answer Checked By - Marie Seifert (PHPFixing Admin)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing