Skip to content

Commit

Permalink
Support for transparencies in animated gifs requires modifying both
Browse files Browse the repository at this point in the history
libavcodec/gif.c and libavformat/gif.c because both the graphics
control extension (handled by libavformat/gif.c) and the raw frame data
(handled by libavcodec/gif.c) must be changed. This is because
transparencies in GIF can be used both to create a transparent image,
and to provide optimization.

How transparencies are interpreted in a given frame is controlled by
the “disposal method”, which must be set appropriately in the graphics
control extension.

 The “in place” disposal method is used when transparency indicates
optimization, and the “background” disposal method is used when
transparency is intended to be preserved. In order to support both
disposal methods, libavcodec/gif.c must signal to libavformat/gif.c
which disposal method is required for every frame. This is done with a
new side data type: AV_PKT_DATA_GIF_FRAME_DISPOSAL. This requires a
change to avcodec.h

Unfortunately, the addition of a new side data type causes some of the
FATE tests to fail, so the fate tests are updated here as well.

Added additional fix for GIF transparency artifacts
  • Loading branch information
bejayoharen authored and cyburgee committed Jun 30, 2020
1 parent e409262 commit 5f65074
Showing 1 changed file with 3 additions and 2 deletions.
5 changes: 3 additions & 2 deletions libavcodec/gif.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ static void gif_crop_translucent(AVCodecContext *avctx,

*height = y_end + 1 - *y_start;
*width = x_end + 1 - *x_start;

av_log(avctx, AV_LOG_DEBUG,"%dx%d image at pos (%d;%d) [area:%dx%d]\n",
*width, *height, *x_start, *y_start, avctx->width, avctx->height);
}
Expand Down Expand Up @@ -267,7 +268,7 @@ static int gif_image_write_image(AVCodecContext *avctx,
int bcid = -1, honor_transparency = (s->flags & GF_TRANSDIFF) && s->last_frame && !palette;
const uint8_t *ptr;

if (!s->image && avctx->frame_number && is_image_translucent(avctx, buf, linesize)) {
if (!s->image && is_image_translucent(avctx, buf, linesize)) {
gif_crop_translucent(avctx, buf, linesize, &width, &height, &x_start, &y_start);
honor_transparency = 0;
disposal = GCE_DISPOSAL_BACKGROUND;
Expand Down Expand Up @@ -497,4 +498,4 @@ AVCodec ff_gif_encoder = {
AV_PIX_FMT_GRAY8, AV_PIX_FMT_PAL8, AV_PIX_FMT_NONE
},
.priv_class = &gif_class,
};
};

0 comments on commit 5f65074

Please sign in to comment.