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.
This commit is contained in:
Anton Khirnov 2012-11-15 22:03:00 +01:00
parent f6e395e132
commit c6303f8d70
2 changed files with 21 additions and 36 deletions

View File

@ -36,7 +36,6 @@ typedef struct YopDecContext {
int num_pal_colors; int num_pal_colors;
int first_color[2]; int first_color[2];
int frame_data_length; int frame_data_length;
int row_pos;
uint8_t *low_nibble; uint8_t *low_nibble;
uint8_t *srcptr; uint8_t *srcptr;
@ -173,27 +172,12 @@ static uint8_t yop_get_next_nibble(YopDecContext *s)
return ret; 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, static int yop_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
AVPacket *avpkt) AVPacket *avpkt)
{ {
YopDecContext *s = avctx->priv_data; YopDecContext *s = avctx->priv_data;
int tag, firstcolor, is_odd_frame; int tag, firstcolor, is_odd_frame;
int ret, i; int ret, i, x, y;
uint32_t *palette; uint32_t *palette;
if (s->frame.data[0]) if (s->frame.data[0])
@ -205,12 +189,9 @@ static int yop_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
return ret; return ret;
} }
s->frame.linesize[0] = avctx->width;
s->dstbuf = s->frame.data[0]; s->dstbuf = s->frame.data[0];
s->dstptr = s->frame.data[0]; s->dstptr = s->frame.data[0];
s->srcptr = avpkt->data + 4; s->srcptr = avpkt->data + 4;
s->row_pos = 0;
s->low_nibble = NULL; s->low_nibble = NULL;
is_odd_frame = avpkt->data[0]; 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; s->frame.palette_has_changed = 1;
while (s->dstptr - s->dstbuf < for (y = 0; y < avctx->height; y += 2) {
avctx->width * avctx->height && for (x = 0; x < avctx->width; x += 2) {
s->srcptr - avpkt->data < avpkt->size) { if (s->srcptr - avpkt->data >= avpkt->size) {
av_log(avctx, AV_LOG_ERROR, "Packet too small.\n");
tag = yop_get_next_nibble(s); 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;
} }
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; *got_frame = 1;

View File

@ -5,4 +5,3 @@
0, 3, 3, 1, 302760, 0xc34b20bd 0, 3, 3, 1, 302760, 0xc34b20bd
0, 4, 4, 1, 302760, 0x461d29a1 0, 4, 4, 1, 302760, 0x461d29a1
0, 5, 5, 1, 302760, 0x45abca02 0, 5, 5, 1, 302760, 0x45abca02
0, 6, 6, 1, 302760, 0xb05448b9