|
|
|
@ -39,6 +39,7 @@ typedef struct YopDecContext { |
|
|
|
|
|
|
|
|
|
uint8_t *low_nibble; |
|
|
|
|
uint8_t *srcptr; |
|
|
|
|
uint8_t *src_end; |
|
|
|
|
uint8_t *dstptr; |
|
|
|
|
uint8_t *dstbuf; |
|
|
|
|
} YopDecContext; |
|
|
|
@ -123,8 +124,13 @@ static av_cold int yop_decode_close(AVCodecContext *avctx) |
|
|
|
|
* @param s codec context |
|
|
|
|
* @param tag the tag that was in the nibble |
|
|
|
|
*/ |
|
|
|
|
static void yop_paint_block(YopDecContext *s, int tag) |
|
|
|
|
static int yop_paint_block(YopDecContext *s, int tag) |
|
|
|
|
{ |
|
|
|
|
if (s->src_end - s->srcptr < paint_lut[tag][3]) { |
|
|
|
|
av_log(s->avctx, AV_LOG_ERROR, "Packet too small.\n"); |
|
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
s->dstptr[0] = s->srcptr[0]; |
|
|
|
|
s->dstptr[1] = s->srcptr[paint_lut[tag][0]]; |
|
|
|
|
s->dstptr[s->frame.linesize[0]] = s->srcptr[paint_lut[tag][1]]; |
|
|
|
@ -132,6 +138,7 @@ static void yop_paint_block(YopDecContext *s, int tag) |
|
|
|
|
|
|
|
|
|
// The number of src bytes consumed is in the last part of the lut entry.
|
|
|
|
|
s->srcptr += paint_lut[tag][3]; |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -185,6 +192,11 @@ static int yop_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, |
|
|
|
|
int ret, i, x, y; |
|
|
|
|
uint32_t *palette; |
|
|
|
|
|
|
|
|
|
if (avpkt->size < 4 + 3 * s->num_pal_colors) { |
|
|
|
|
av_log(avctx, AV_LOG_ERROR, "Packet too small.\n"); |
|
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (s->frame.data[0]) |
|
|
|
|
avctx->release_buffer(avctx, &s->frame); |
|
|
|
|
|
|
|
|
@ -197,6 +209,7 @@ static int yop_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, |
|
|
|
|
s->dstbuf = s->frame.data[0]; |
|
|
|
|
s->dstptr = s->frame.data[0]; |
|
|
|
|
s->srcptr = avpkt->data + 4; |
|
|
|
|
s->src_end = avpkt->data + avpkt->size; |
|
|
|
|
s->low_nibble = NULL; |
|
|
|
|
|
|
|
|
|
is_odd_frame = avpkt->data[0]; |
|
|
|
@ -220,7 +233,9 @@ static int yop_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, |
|
|
|
|
tag = yop_get_next_nibble(s); |
|
|
|
|
|
|
|
|
|
if (tag != 0xf) { |
|
|
|
|
yop_paint_block(s, tag); |
|
|
|
|
ret = yop_paint_block(s, tag); |
|
|
|
|
if (ret < 0) |
|
|
|
|
return ret; |
|
|
|
|
} else { |
|
|
|
|
tag = yop_get_next_nibble(s); |
|
|
|
|
ret = yop_copy_previous_block(s, tag); |
|
|
|
|