From 856444fd5447976daef17ab099e9fedee8e5bc35 Mon Sep 17 00:00:00 2001
From: Pumkinpal <[EMAIL REDACTED]>
Date: Sun, 19 Apr 2026 16:57:08 +1000
Subject: [PATCH] Fixed GIF_DISPOSE_RESTORE_BACKGROUND
GIF_DISPOSE_RESTORE_BACKGROUND is handled correctly now by only
restoring the background color to the area covered by the previous frame
- not the entire canvas area.
---
src/IMG_gif.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/src/IMG_gif.c b/src/IMG_gif.c
index 2f0d58282..3b8f6f01a 100644
--- a/src/IMG_gif.c
+++ b/src/IMG_gif.c
@@ -535,7 +535,7 @@ struct IMG_AnimationDecoderContext
/* Frame info */
Uint64 last_duration; /* The duration of the previous frame */
int last_disposal; /* Disposal method from previous frame */
- int restore_frame; /* Frame to restore when using DISPOSE_PREVIOUS */
+ SDL_Rect restore_area; /* Area to restore when using DISPOSE_RESTORE_BACKGROUND */
bool ignore_props;
};
@@ -763,7 +763,8 @@ static bool IMG_AnimationDecoderReset_Internal(IMG_AnimationDecoder *decoder)
ctx->got_header = false;
ctx->got_eof = false;
ctx->last_disposal = GIF_DISPOSE_NONE;
- ctx->restore_frame = 0;
+ SDL_Rect r = {0};
+ ctx->restore_area = r;
// We don't care about metadata when resetting to re-read.
ctx->ignore_props = true;
@@ -850,8 +851,7 @@ static bool IMG_AnimationDecoderGetNextFrame_Internal(IMG_AnimationDecoder *deco
case GIF_DISPOSE_RESTORE_BACKGROUND:
{
- SDL_Rect rect = { 0, 0, ctx->width, ctx->height };
- if (!SDL_FillSurfaceRect(ctx->canvas, &rect, 0)) {
+ if (!SDL_FillSurfaceRect(ctx->canvas, &ctx->restore_area, 0)) {
return SDL_SetError("Failed to fill canvas with background color");
}
} break;
@@ -875,7 +875,12 @@ static bool IMG_AnimationDecoderGetNextFrame_Internal(IMG_AnimationDecoder *deco
if (!SDL_BlitSurface(ctx->canvas, NULL, ctx->prev_canvas, NULL)) {
return SDL_SetError("Failed to save current canvas for restoration");
}
+ } else if (ctx->state.Gif89.disposal == GIF_DISPOSE_RESTORE_BACKGROUND) {
+ SDL_Rect r = { left, top, width, height };
+ ctx->restore_area = r;
}
+
+
Image *image;
if (!useGlobalColormap) {
image = ReadImage(src, width, height, bitPixel, localColorMap, grayScale,
@@ -986,7 +991,8 @@ bool IMG_CreateGIFAnimationDecoder(IMG_AnimationDecoder *decoder, SDL_Properties
ctx->current_delay = 100;
ctx->current_disposal = GIF_DISPOSE_NA;
ctx->last_disposal = GIF_DISPOSE_NONE;
- ctx->restore_frame = 0;
+ SDL_Rect r = {0};
+ ctx->restore_area = r;
decoder->ctx = ctx;
decoder->Reset = IMG_AnimationDecoderReset_Internal;