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); - - 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; + 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; } + + tag = yop_get_next_nibble(s); + + 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