I have this functions that extracts frames from animated GIFs. It works with all GIFs except this one: 
{ 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?
GR.Draw(TempFrame.Canvas, TempFrame.Canvas.ClipRect);what value stored inGRinTempFrame?TObjectList.TempFrameand itsCanvas, is either nil? Of course in your code they shouldn't, but ...