From c6303f8d70c25dd6c6e6486c78bf99c9924e2b6b Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 15 Nov 2012 22:03:00 +0100 Subject: yop: simplify/sanitize the decoding loop Do not overwrite linesize set by get_buffer(). The last frame in the FATE test is not decoded anymore, since the file is cut and a part of it is missing. --- libavcodec/yop.c | 52 +++++++++++++++++++--------------------------------- 1 file changed, 19 insertions(+), 33 deletions(-) (limited to 'libavcodec/yop.c') diff --git a/libavcodec/yop.c b/libavcodec/yop.c index c3bb577119..0b9cdfebe2 100644 --- a/libavcodec/yop.c +++ b/libavcodec/yop.c @@ -36,7 +36,6 @@ typedef struct YopDecContext { int num_pal_colors; int first_color[2]; int frame_data_length; - int row_pos; uint8_t *low_nibble; uint8_t *srcptr; @@ -173,27 +172,12 @@ static uint8_t yop_get_next_nibble(YopDecContext *s) return ret; } -/** - * Take s->dstptr to the next macroblock in sequence. - */ -static void yop_next_macroblock(YopDecContext *s) -{ - // If we are advancing to the next row of macroblocks - if (s->row_pos == s->frame.linesize[0] - 2) { - s->dstptr += s->frame.linesize[0]; - s->row_pos = 0; - }else { - s->row_pos += 2; - } - s->dstptr += 2; -} - static int yop_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { YopDecContext *s = avctx->priv_data; int tag, firstcolor, is_odd_frame; - int ret, i; + int ret, i, x, y; uint32_t *palette; if (s->frame.data[0]) @@ -205,12 +189,9 @@ static int yop_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, return ret; } - s->frame.linesize[0] = avctx->width; - s->dstbuf = s->frame.data[0]; s->dstptr = s->frame.data[0]; s->srcptr = avpkt->data + 4; - s->row_pos = 0; s->low_nibble = NULL; is_odd_frame = avpkt->data[0]; @@ -224,23 +205,28 @@ static int yop_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, s->frame.palette_has_changed = 1; - while (s->dstptr - s->dstbuf < - avctx->width * avctx->height && - s->srcptr - avpkt->data < avpkt->size) { - - tag = yop_get_next_nibble(s); + for (y = 0; y < avctx->height; y += 2) { + for (x = 0; x < avctx->width; x += 2) { + if (s->srcptr - avpkt->data >= avpkt->size) { + av_log(avctx, AV_LOG_ERROR, "Packet too small.\n"); + return AVERROR_INVALIDDATA; + } - if (tag != 0xf) { - yop_paint_block(s, tag); - }else { tag = yop_get_next_nibble(s); - ret = yop_copy_previous_block(s, tag); - if (ret < 0) { - avctx->release_buffer(avctx, &s->frame); - return ret; + + if (tag != 0xf) { + yop_paint_block(s, tag); + } else { + tag = yop_get_next_nibble(s); + ret = yop_copy_previous_block(s, tag); + if (ret < 0) { + avctx->release_buffer(avctx, &s->frame); + return ret; + } } + s->dstptr += 2; } - yop_next_macroblock(s); + s->dstptr += 2*s->frame.linesize[0] - x; } *got_frame = 1; -- cgit v1.2.3