|
|
@ -499,62 +499,61 @@ static int xan_decode_frame(AVCodecContext *avctx, |
|
|
|
const uint8_t *buf = avpkt->data; |
|
|
|
const uint8_t *buf = avpkt->data; |
|
|
|
int ret, buf_size = avpkt->size; |
|
|
|
int ret, buf_size = avpkt->size; |
|
|
|
XanContext *s = avctx->priv_data; |
|
|
|
XanContext *s = avctx->priv_data; |
|
|
|
|
|
|
|
const uint8_t *buf_end = buf + buf_size; |
|
|
|
if (avctx->codec->id == AV_CODEC_ID_XAN_WC3) { |
|
|
|
int tag = 0; |
|
|
|
const uint8_t *buf_end = buf + buf_size; |
|
|
|
|
|
|
|
int tag = 0; |
|
|
|
while (buf_end - buf > 8 && tag != VGA__TAG) { |
|
|
|
while (buf_end - buf > 8 && tag != VGA__TAG) { |
|
|
|
unsigned *tmpptr; |
|
|
|
unsigned *tmpptr; |
|
|
|
uint32_t new_pal; |
|
|
|
uint32_t new_pal; |
|
|
|
int size; |
|
|
|
int size; |
|
|
|
int i; |
|
|
|
int i; |
|
|
|
tag = bytestream_get_le32(&buf); |
|
|
|
tag = bytestream_get_le32(&buf); |
|
|
|
size = bytestream_get_be32(&buf); |
|
|
|
size = bytestream_get_be32(&buf); |
|
|
|
size = FFMIN(size, buf_end - buf); |
|
|
|
size = FFMIN(size, buf_end - buf); |
|
|
|
switch (tag) { |
|
|
|
switch (tag) { |
|
|
|
case PALT_TAG: |
|
|
|
case PALT_TAG: |
|
|
|
if (size < PALETTE_SIZE) |
|
|
|
if (size < PALETTE_SIZE) |
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
if (s->palettes_count >= PALETTES_MAX) |
|
|
|
if (s->palettes_count >= PALETTES_MAX) |
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
tmpptr = av_realloc(s->palettes, |
|
|
|
tmpptr = av_realloc(s->palettes, |
|
|
|
(s->palettes_count + 1) * AVPALETTE_SIZE); |
|
|
|
(s->palettes_count + 1) * AVPALETTE_SIZE); |
|
|
|
if (!tmpptr) |
|
|
|
if (!tmpptr) |
|
|
|
return AVERROR(ENOMEM); |
|
|
|
return AVERROR(ENOMEM); |
|
|
|
s->palettes = tmpptr; |
|
|
|
s->palettes = tmpptr; |
|
|
|
tmpptr += s->palettes_count * AVPALETTE_COUNT; |
|
|
|
tmpptr += s->palettes_count * AVPALETTE_COUNT; |
|
|
|
for (i = 0; i < PALETTE_COUNT; i++) { |
|
|
|
for (i = 0; i < PALETTE_COUNT; i++) { |
|
|
|
|
|
|
|
#if RUNTIME_GAMMA |
|
|
|
#if RUNTIME_GAMMA |
|
|
|
int r = gamma_corr(*buf++); |
|
|
|
int r = gamma_corr(*buf++); |
|
|
|
int g = gamma_corr(*buf++); |
|
|
|
int g = gamma_corr(*buf++); |
|
|
|
int b = gamma_corr(*buf++); |
|
|
|
int b = gamma_corr(*buf++); |
|
|
|
#else |
|
|
|
#else |
|
|
|
int r = gamma_lookup[*buf++]; |
|
|
|
int r = gamma_lookup[*buf++]; |
|
|
|
int g = gamma_lookup[*buf++]; |
|
|
|
int g = gamma_lookup[*buf++]; |
|
|
|
int b = gamma_lookup[*buf++]; |
|
|
|
int b = gamma_lookup[*buf++]; |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
*tmpptr++ = (r << 16) | (g << 8) | b; |
|
|
|
*tmpptr++ = (r << 16) | (g << 8) | b; |
|
|
|
} |
|
|
|
|
|
|
|
s->palettes_count++; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case SHOT_TAG: |
|
|
|
|
|
|
|
if (size < 4) |
|
|
|
|
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
|
|
|
|
new_pal = bytestream_get_le32(&buf); |
|
|
|
|
|
|
|
if (new_pal < s->palettes_count) { |
|
|
|
|
|
|
|
s->cur_palette = new_pal; |
|
|
|
|
|
|
|
} else |
|
|
|
|
|
|
|
av_log(avctx, AV_LOG_ERROR, "Invalid palette selected\n"); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case VGA__TAG: |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
default: |
|
|
|
|
|
|
|
buf += size; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
s->palettes_count++; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case SHOT_TAG: |
|
|
|
|
|
|
|
if (size < 4) |
|
|
|
|
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
|
|
|
|
new_pal = bytestream_get_le32(&buf); |
|
|
|
|
|
|
|
if (new_pal < s->palettes_count) { |
|
|
|
|
|
|
|
s->cur_palette = new_pal; |
|
|
|
|
|
|
|
} else |
|
|
|
|
|
|
|
av_log(avctx, AV_LOG_ERROR, "Invalid palette selected\n"); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case VGA__TAG: |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
default: |
|
|
|
|
|
|
|
buf += size; |
|
|
|
|
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
buf_size = buf_end - buf; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
buf_size = buf_end - buf; |
|
|
|
|
|
|
|
|
|
|
|
if (s->palettes_count <= 0) { |
|
|
|
if (s->palettes_count <= 0) { |
|
|
|
av_log(s->avctx, AV_LOG_ERROR, "No palette found\n"); |
|
|
|
av_log(s->avctx, AV_LOG_ERROR, "No palette found\n"); |
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|