From c6180f306e64ca77c7d5a13fa2ace03b49402da3 Mon Sep 17 00:00:00 2001 From: Collin Burger Date: Fri, 19 Apr 2019 12:05:37 -0400 Subject: [PATCH 1/6] fix transparent crop and add some debugging around gif writing --- libavcodec/gif.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/libavcodec/gif.c b/libavcodec/gif.c index 94c8b1af499f2..008f3c772760d 100644 --- a/libavcodec/gif.c +++ b/libavcodec/gif.c @@ -125,6 +125,7 @@ static void gif_crop_translucent(AVCodecContext *avctx, GIFContext *s = avctx->priv_data; int trans = s->transparent_index; + av_log(avctx, AV_LOG_DEBUG,"avctx frame: %d\n", avctx->frame_number); /* Crop image */ if ((s->flags & GF_OFFSETTING) && trans >= 0) { const int w = avctx->width; @@ -144,11 +145,13 @@ static void gif_crop_translucent(AVCodecContext *avctx, if (!is_trans) break; + // av_log(avctx, AV_LOG_DEBUG,"crop top: %dx%d image at pos (%d;%d) [area:%dx%d]\n", + // *width, *height, *x_start, *y_start, avctx->width, avctx->height); (*y_start)++; } // crop bottom - while (y_end < h) { + while (y_end > *y_start) { int is_trans = 1; for (int i = 0; i < w; i++) { if (buf[w * y_end + i] != trans) { @@ -158,6 +161,8 @@ static void gif_crop_translucent(AVCodecContext *avctx, } if (!is_trans) break; + // av_log(avctx, AV_LOG_DEBUG,"crop bottom: %dx%d image at pos (%d;%d) [area:%dx%d]\n", + // *width, *height, *x_start, *y_start, avctx->width, avctx->height); y_end--; } @@ -172,11 +177,13 @@ static void gif_crop_translucent(AVCodecContext *avctx, } if (!is_trans) break; + // av_log(avctx, AV_LOG_DEBUG,"crop left: %dx%d image at pos (%d;%d) [area:%dx%d]\n", + // *width, *height, *x_start, *y_start, avctx->width, avctx->height); (*x_start)++; } // crop right - while (x_end < w) { + while (x_end > x_start) { int is_trans = 1; for (int i = *y_start; i < y_end; i++) { if (buf[w * i + x_end] != trans) { @@ -186,11 +193,17 @@ static void gif_crop_translucent(AVCodecContext *avctx, } if (!is_trans) break; + // av_log(avctx, AV_LOG_DEBUG,"crop right: %dx%d image at pos (%d;%d) [area:%dx%d]\n", + // *width, *height, *x_start, *y_start, avctx->width, avctx->height); x_end--; } *height = y_end + 1 - *y_start; *width = x_end + 1 - *x_start; + // if (*width == 1 && *height == 1) { + // *x_start = 0; + // *y_start = 0; + // } 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); } @@ -343,11 +356,13 @@ static int gif_image_write_image(AVCodecContext *avctx, bytestream_put_byte(bytestream, 0x08); + // av_log(avctx, AV_LOG_DEBUG, "frame: %d buf_size: %d\n", avctx->frame_number, s->buf_size); ff_lzw_encode_init(s->lzw, s->buf, s->buf_size, 12, FF_LZW_GIF, put_bits); ptr = buf + y_start*linesize + x_start; if (honor_transparency) { + av_log(avctx, AV_LOG_DEBUG, "frame: %d honoring transparency\n", avctx->frame_number); const int ref_linesize = s->last_frame->linesize[0]; const uint8_t *ref = s->last_frame->data[0] + y_start*ref_linesize + x_start; @@ -361,9 +376,13 @@ static int gif_image_write_image(AVCodecContext *avctx, ref += ref_linesize; } } else { + av_log(avctx, AV_LOG_DEBUG, "frame: %d not honoring transparency\n", avctx->frame_number); + av_log(avctx, AV_LOG_DEBUG, "frame: %d lzw encoding image of height: %d\n", avctx->frame_number, height); for (y = 0; y < height; y++) { len += ff_lzw_encode(s->lzw, ptr, width); + av_log(avctx, AV_LOG_DEBUG, "frame: %d lzw encoding image of width: %d\n", avctx->frame_number, width); ptr += linesize; + av_log(avctx, AV_LOG_DEBUG, "frame: %d wrote linesize: %d\n", avctx->frame_number, linesize); } } len += ff_lzw_encode_flush(s->lzw, flush_put_bits); From d69c4cf47f1c234b78accf40909a7c40a1891570 Mon Sep 17 00:00:00 2001 From: Collin Burger Date: Fri, 19 Apr 2019 12:39:30 -0400 Subject: [PATCH 2/6] Update gif.c --- libavcodec/gif.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/gif.c b/libavcodec/gif.c index 008f3c772760d..f557ceaebe3fc 100644 --- a/libavcodec/gif.c +++ b/libavcodec/gif.c @@ -183,7 +183,7 @@ static void gif_crop_translucent(AVCodecContext *avctx, } // crop right - while (x_end > x_start) { + while (x_end > *x_start) { int is_trans = 1; for (int i = *y_start; i < y_end; i++) { if (buf[w * i + x_end] != trans) { From 837634277df05c09f39ce29652782e82d10e016d Mon Sep 17 00:00:00 2001 From: Jacob Graff Date: Mon, 6 May 2019 14:59:23 -0400 Subject: [PATCH 3/6] Fix bug with transparent gif cropping --- libavcodec/gif.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/libavcodec/gif.c b/libavcodec/gif.c index f557ceaebe3fc..383af118bad67 100644 --- a/libavcodec/gif.c +++ b/libavcodec/gif.c @@ -126,6 +126,7 @@ static void gif_crop_translucent(AVCodecContext *avctx, int trans = s->transparent_index; av_log(avctx, AV_LOG_DEBUG,"avctx frame: %d\n", avctx->frame_number); + /* Crop image */ if ((s->flags & GF_OFFSETTING) && trans >= 0) { const int w = avctx->width; @@ -136,8 +137,8 @@ static void gif_crop_translucent(AVCodecContext *avctx, // crop top while (*y_start < y_end) { int is_trans = 1; - for (int i = 0; i < w; i++) { - if (buf[w * *y_start + i] != trans) { + for (int i = 0; i < linesize; i++) { + if (buf[linesize * *y_start + i] != trans) { is_trans = 0; break; } @@ -153,8 +154,8 @@ static void gif_crop_translucent(AVCodecContext *avctx, // crop bottom while (y_end > *y_start) { int is_trans = 1; - for (int i = 0; i < w; i++) { - if (buf[w * y_end + i] != trans) { + for (int i = 0; i < linesize; i++) { + if (buf[linesize * y_end + i] != trans) { is_trans = 0; break; } @@ -170,7 +171,7 @@ static void gif_crop_translucent(AVCodecContext *avctx, while (*x_start < x_end) { int is_trans = 1; for (int i = *y_start; i < y_end; i++) { - if (buf[w * i + *x_start] != trans) { + if (buf[linesize * i + *x_start] != trans) { is_trans = 0; break; } @@ -186,7 +187,7 @@ static void gif_crop_translucent(AVCodecContext *avctx, while (x_end > *x_start) { int is_trans = 1; for (int i = *y_start; i < y_end; i++) { - if (buf[w * i + x_end] != trans) { + if (buf[linesize * i + x_end] != trans) { is_trans = 0; break; } @@ -200,10 +201,7 @@ static void gif_crop_translucent(AVCodecContext *avctx, *height = y_end + 1 - *y_start; *width = x_end + 1 - *x_start; - // if (*width == 1 && *height == 1) { - // *x_start = 0; - // *y_start = 0; - // } + 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); } From 561517b60bdc59e6a7d2306d1a50fc76f3d5f2d5 Mon Sep 17 00:00:00 2001 From: Jacob Graff Date: Mon, 6 May 2019 15:05:06 -0400 Subject: [PATCH 4/6] Optimize --- libavcodec/gif.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/gif.c b/libavcodec/gif.c index 383af118bad67..c43d248ae364e 100644 --- a/libavcodec/gif.c +++ b/libavcodec/gif.c @@ -137,7 +137,7 @@ static void gif_crop_translucent(AVCodecContext *avctx, // crop top while (*y_start < y_end) { int is_trans = 1; - for (int i = 0; i < linesize; i++) { + for (int i = 0; i < w; i++) { if (buf[linesize * *y_start + i] != trans) { is_trans = 0; break; @@ -154,7 +154,7 @@ static void gif_crop_translucent(AVCodecContext *avctx, // crop bottom while (y_end > *y_start) { int is_trans = 1; - for (int i = 0; i < linesize; i++) { + for (int i = 0; i < w; i++) { if (buf[linesize * y_end + i] != trans) { is_trans = 0; break; From d199ea71c03e8bc3a6176da4089b4b34cc565ef3 Mon Sep 17 00:00:00 2001 From: Jacob Graff Date: Mon, 6 May 2019 18:40:59 -0400 Subject: [PATCH 5/6] Remove extra logging --- libavcodec/gif.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/libavcodec/gif.c b/libavcodec/gif.c index c43d248ae364e..d7768b44262e4 100644 --- a/libavcodec/gif.c +++ b/libavcodec/gif.c @@ -125,8 +125,6 @@ static void gif_crop_translucent(AVCodecContext *avctx, GIFContext *s = avctx->priv_data; int trans = s->transparent_index; - av_log(avctx, AV_LOG_DEBUG,"avctx frame: %d\n", avctx->frame_number); - /* Crop image */ if ((s->flags & GF_OFFSETTING) && trans >= 0) { const int w = avctx->width; @@ -146,8 +144,6 @@ static void gif_crop_translucent(AVCodecContext *avctx, if (!is_trans) break; - // av_log(avctx, AV_LOG_DEBUG,"crop top: %dx%d image at pos (%d;%d) [area:%dx%d]\n", - // *width, *height, *x_start, *y_start, avctx->width, avctx->height); (*y_start)++; } @@ -162,8 +158,6 @@ static void gif_crop_translucent(AVCodecContext *avctx, } if (!is_trans) break; - // av_log(avctx, AV_LOG_DEBUG,"crop bottom: %dx%d image at pos (%d;%d) [area:%dx%d]\n", - // *width, *height, *x_start, *y_start, avctx->width, avctx->height); y_end--; } @@ -178,8 +172,6 @@ static void gif_crop_translucent(AVCodecContext *avctx, } if (!is_trans) break; - // av_log(avctx, AV_LOG_DEBUG,"crop left: %dx%d image at pos (%d;%d) [area:%dx%d]\n", - // *width, *height, *x_start, *y_start, avctx->width, avctx->height); (*x_start)++; } @@ -194,14 +186,11 @@ static void gif_crop_translucent(AVCodecContext *avctx, } if (!is_trans) break; - // av_log(avctx, AV_LOG_DEBUG,"crop right: %dx%d image at pos (%d;%d) [area:%dx%d]\n", - // *width, *height, *x_start, *y_start, avctx->width, avctx->height); x_end--; } *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); } @@ -354,13 +343,11 @@ static int gif_image_write_image(AVCodecContext *avctx, bytestream_put_byte(bytestream, 0x08); - // av_log(avctx, AV_LOG_DEBUG, "frame: %d buf_size: %d\n", avctx->frame_number, s->buf_size); ff_lzw_encode_init(s->lzw, s->buf, s->buf_size, 12, FF_LZW_GIF, put_bits); ptr = buf + y_start*linesize + x_start; if (honor_transparency) { - av_log(avctx, AV_LOG_DEBUG, "frame: %d honoring transparency\n", avctx->frame_number); const int ref_linesize = s->last_frame->linesize[0]; const uint8_t *ref = s->last_frame->data[0] + y_start*ref_linesize + x_start; @@ -374,13 +361,9 @@ static int gif_image_write_image(AVCodecContext *avctx, ref += ref_linesize; } } else { - av_log(avctx, AV_LOG_DEBUG, "frame: %d not honoring transparency\n", avctx->frame_number); - av_log(avctx, AV_LOG_DEBUG, "frame: %d lzw encoding image of height: %d\n", avctx->frame_number, height); for (y = 0; y < height; y++) { len += ff_lzw_encode(s->lzw, ptr, width); - av_log(avctx, AV_LOG_DEBUG, "frame: %d lzw encoding image of width: %d\n", avctx->frame_number, width); ptr += linesize; - av_log(avctx, AV_LOG_DEBUG, "frame: %d wrote linesize: %d\n", avctx->frame_number, linesize); } } len += ff_lzw_encode_flush(s->lzw, flush_put_bits); From 9f697edfa5a7e5b68585f051114e6e112305a4dc Mon Sep 17 00:00:00 2001 From: Jacob Graff Date: Fri, 10 May 2019 16:27:02 -0400 Subject: [PATCH 6/6] Fix disposal method issue --- libavcodec/gif.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavcodec/gif.c b/libavcodec/gif.c index d7768b44262e4..6bf656a589a55 100644 --- a/libavcodec/gif.c +++ b/libavcodec/gif.c @@ -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); } @@ -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;