|
|
@@ -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; |
|
|
|