summaryrefslogtreecommitdiff
path: root/ffmpeg/libavcodec/gifdec.c
diff options
context:
space:
mode:
Diffstat (limited to 'ffmpeg/libavcodec/gifdec.c')
-rw-r--r--ffmpeg/libavcodec/gifdec.c43
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,
};