diff options
author | Anton Khirnov <anton@khirnov.net> | 2012-11-15 22:03:00 +0100 |
---|---|---|
committer | Anton Khirnov <anton@khirnov.net> | 2012-12-24 09:16:51 +0100 |
commit | c6303f8d70c25dd6c6e6486c78bf99c9924e2b6b (patch) | |
tree | 591bc4149dd101a2f2d35ad813a4ab9a29c11f34 | |
parent | f6e395e1320c52cc0720a83787622b15f6762d4f (diff) | |
download | ffmpeg-c6303f8d70c25dd6c6e6486c78bf99c9924e2b6b.tar.gz |
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.
-rw-r--r-- | libavcodec/yop.c | 52 | ||||
-rw-r--r-- | tests/ref/fate/yop | 1 |
2 files changed, 19 insertions, 34 deletions
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; diff --git a/tests/ref/fate/yop b/tests/ref/fate/yop index 5629825688..57f565d5f8 100644 --- a/tests/ref/fate/yop +++ b/tests/ref/fate/yop @@ -5,4 +5,3 @@ 0, 3, 3, 1, 302760, 0xc34b20bd 0, 4, 4, 1, 302760, 0x461d29a1 0, 5, 5, 1, 302760, 0x45abca02 -0, 6, 6, 1, 302760, 0xb05448b9 |