diff options
Diffstat (limited to 'ffmpeg/libavcodec/gifdec.c')
| -rw-r--r-- | ffmpeg/libavcodec/gifdec.c | 43 |
1 files changed, 24 insertions, 19 deletions
diff --git a/ffmpeg/libavcodec/gifdec.c b/ffmpeg/libavcodec/gifdec.c index 27364c9..78c8900 100644 --- a/ffmpeg/libavcodec/gifdec.c +++ b/ffmpeg/libavcodec/gifdec.c @@ -21,8 +21,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -//#define DEBUG - #include "libavutil/imgutils.h" #include "libavutil/opt.h" #include "avcodec.h" @@ -66,7 +64,6 @@ typedef struct GifState { int stored_bg_color; GetByteContext gb; - /* LZW compatible decoder */ LZWState *lzw; /* aux buffers */ @@ -142,11 +139,11 @@ static int gif_read_image(GifState *s, AVFrame *frame) if (bytestream2_get_bytes_left(&s->gb) < 9) return AVERROR_INVALIDDATA; - left = bytestream2_get_le16u(&s->gb); - top = bytestream2_get_le16u(&s->gb); - width = bytestream2_get_le16u(&s->gb); + left = bytestream2_get_le16u(&s->gb); + top = bytestream2_get_le16u(&s->gb); + width = bytestream2_get_le16u(&s->gb); height = bytestream2_get_le16u(&s->gb); - flags = bytestream2_get_byteu(&s->gb); + flags = bytestream2_get_byteu(&s->gb); is_interleaved = flags & 0x40; has_local_palette = flags & 0x80; bits_per_pixel = (flags & 0x07) + 1; @@ -183,10 +180,14 @@ static int gif_read_image(GifState *s, AVFrame *frame) /* verify that all the image is inside the screen dimensions */ if (left + width > s->screen_width || - top + height > s->screen_height) + top + height > s->screen_height) { + av_log(s->avctx, AV_LOG_ERROR, "image is outside the screen dimensions.\n"); return AVERROR_INVALIDDATA; - if (width <= 0 || height <= 0) + } + if (width <= 0 || height <= 0) { + av_log(s->avctx, AV_LOG_ERROR, "Invalid image dimensions.\n"); return AVERROR_INVALIDDATA; + } /* process disposal method */ if (s->gce_prev_disposal == GCE_DISPOSAL_BACKGROUND) { @@ -236,8 +237,12 @@ static int gif_read_image(GifState *s, AVFrame *frame) pass = 0; y1 = 0; for (y = 0; y < height; y++) { - if (ff_lzw_decode(s->lzw, s->idx_line, width) == 0) + int count = ff_lzw_decode(s->lzw, s->idx_line, width); + if (count != width) { + if (count) + av_log(s->avctx, AV_LOG_ERROR, "LZW decode failed\n"); goto decode_tail; + } pr = ptr + width; @@ -300,7 +305,7 @@ static int gif_read_extension(GifState *s) return AVERROR_INVALIDDATA; ext_code = bytestream2_get_byteu(&s->gb); - ext_len = bytestream2_get_byteu(&s->gb); + ext_len = bytestream2_get_byteu(&s->gb); av_dlog(s->avctx, "ext_code=0x%x len=%d\n", ext_code, ext_len); @@ -314,7 +319,7 @@ static int gif_read_extension(GifState *s) if (bytestream2_get_bytes_left(&s->gb) < 5) return AVERROR_INVALIDDATA; - gce_flags = bytestream2_get_byteu(&s->gb); + gce_flags = bytestream2_get_byteu(&s->gb); bytestream2_skipu(&s->gb, 2); // delay during which the frame is shown gce_transparent_index = bytestream2_get_byteu(&s->gb); if (gce_flags & 0x01) @@ -368,7 +373,7 @@ static int gif_read_header1(GifState *s) /* read screen header */ s->transparent_color_index = -1; - s->screen_width = bytestream2_get_le16u(&s->gb); + s->screen_width = bytestream2_get_le16u(&s->gb); s->screen_height = bytestream2_get_le16u(&s->gb); v = bytestream2_get_byteu(&s->gb); @@ -402,11 +407,11 @@ static int gif_read_header1(GifState *s) static int gif_parse_next_image(GifState *s, AVFrame *frame) { - while (bytestream2_get_bytes_left(&s->gb)) { + while (bytestream2_get_bytes_left(&s->gb) > 0) { int code = bytestream2_get_byte(&s->gb); int ret; - av_dlog(s->avctx, "code=%02x '%c'\n", code, code); + av_log(s->avctx, AV_LOG_DEBUG, "code=%02x '%c'\n", code, code); switch (code) { case GIF_IMAGE_SEPARATOR: @@ -461,12 +466,12 @@ static int gif_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, A if (s->keyframe) { s->keyframe_ok = 0; + s->gce_prev_disposal = GCE_DISPOSAL_NONE; if ((ret = gif_read_header1(s)) < 0) return ret; - if ((ret = av_image_check_size(s->screen_width, s->screen_height, 0, avctx)) < 0) + if ((ret = ff_set_dimensions(avctx, s->screen_width, s->screen_height)) < 0) return ret; - avcodec_set_dimensions(avctx, s->screen_width, s->screen_height); av_frame_unref(s->frame); if ((ret = ff_get_buffer(avctx, s->frame, 0)) < 0) @@ -500,7 +505,7 @@ static int gif_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, A return ret; *got_frame = 1; - return avpkt->size; + return bytestream2_tell(&s->gb); } static av_cold int gif_decode_close(AVCodecContext *avctx) @@ -533,6 +538,7 @@ static const AVClass decoder_class = { AVCodec ff_gif_decoder = { .name = "gif", + .long_name = NULL_IF_CONFIG_SMALL("GIF (Graphics Interchange Format)"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_GIF, .priv_data_size = sizeof(GifState), @@ -540,6 +546,5 @@ AVCodec ff_gif_decoder = { .close = gif_decode_close, .decode = gif_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("GIF (Graphics Interchange Format)"), .priv_class = &decoder_class, }; |
