|
|
|
@@ -25,6 +25,7 @@ |
|
|
|
*/ |
|
|
|
|
|
|
|
#include "avcodec.h" |
|
|
|
#include "bytestream.h" |
|
|
|
#include "get_bits.h" |
|
|
|
#include "dsputil.h" |
|
|
|
|
|
|
|
@@ -251,18 +252,19 @@ static int tm2_read_deltas(TM2Context *ctx, int stream_id) { |
|
|
|
static int tm2_read_stream(TM2Context *ctx, const uint8_t *buf, int stream_id, int buf_size) |
|
|
|
{ |
|
|
|
int i; |
|
|
|
int cur = 0; |
|
|
|
int skip = 0; |
|
|
|
int len, toks; |
|
|
|
int len, toks, pos; |
|
|
|
TM2Codes codes; |
|
|
|
GetByteContext gb; |
|
|
|
|
|
|
|
if (buf_size < 4) { |
|
|
|
av_log(ctx->avctx, AV_LOG_ERROR, "not enough space for len left\n"); |
|
|
|
return -1; |
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
} |
|
|
|
|
|
|
|
/* get stream length in dwords */ |
|
|
|
len = AV_RB32(buf); buf += 4; cur += 4; |
|
|
|
bytestream2_init(&gb, buf, buf_size); |
|
|
|
len = bytestream2_get_be32(&gb); |
|
|
|
skip = len * 4 + 4; |
|
|
|
|
|
|
|
if(len == 0) |
|
|
|
@@ -273,36 +275,37 @@ static int tm2_read_stream(TM2Context *ctx, const uint8_t *buf, int stream_id, i |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
toks = AV_RB32(buf); buf += 4; cur += 4; |
|
|
|
toks = bytestream2_get_be32(&gb); |
|
|
|
if(toks & 1) { |
|
|
|
len = AV_RB32(buf); buf += 4; cur += 4; |
|
|
|
len = bytestream2_get_be32(&gb); |
|
|
|
if(len == TM2_ESCAPE) { |
|
|
|
len = AV_RB32(buf); buf += 4; cur += 4; |
|
|
|
len = bytestream2_get_be32(&gb); |
|
|
|
} |
|
|
|
if(len > 0) { |
|
|
|
if (skip <= cur) |
|
|
|
pos = bytestream2_tell(&gb); |
|
|
|
if (skip <= pos) |
|
|
|
return -1; |
|
|
|
init_get_bits(&ctx->gb, buf, (skip - cur) * 8); |
|
|
|
init_get_bits(&ctx->gb, buf + pos, (skip - pos) * 8); |
|
|
|
if(tm2_read_deltas(ctx, stream_id) == -1) |
|
|
|
return -1; |
|
|
|
buf += ((get_bits_count(&ctx->gb) + 31) >> 5) << 2; |
|
|
|
cur += ((get_bits_count(&ctx->gb) + 31) >> 5) << 2; |
|
|
|
bytestream2_skip(&gb, ((get_bits_count(&ctx->gb) + 31) >> 5) << 2); |
|
|
|
} |
|
|
|
} |
|
|
|
/* skip unused fields */ |
|
|
|
if(AV_RB32(buf) == TM2_ESCAPE) { |
|
|
|
buf += 4; cur += 4; /* some unknown length - could be escaped too */ |
|
|
|
len = bytestream2_get_be32(&gb); |
|
|
|
if(len == TM2_ESCAPE) { /* some unknown length - could be escaped too */ |
|
|
|
bytestream2_skip(&gb, 8); /* unused by decoder */ |
|
|
|
} else { |
|
|
|
bytestream2_skip(&gb, 4); /* unused by decoder */ |
|
|
|
} |
|
|
|
buf += 4; cur += 4; |
|
|
|
buf += 4; cur += 4; /* unused by decoder */ |
|
|
|
|
|
|
|
if (skip <= cur) |
|
|
|
pos = bytestream2_tell(&gb); |
|
|
|
if (skip <= pos) |
|
|
|
return -1; |
|
|
|
init_get_bits(&ctx->gb, buf, (skip - cur) * 8); |
|
|
|
init_get_bits(&ctx->gb, buf + pos, (skip - pos) * 8); |
|
|
|
if(tm2_build_huff_table(ctx, &codes) == -1) |
|
|
|
return -1; |
|
|
|
buf += ((get_bits_count(&ctx->gb) + 31) >> 5) << 2; |
|
|
|
cur += ((get_bits_count(&ctx->gb) + 31) >> 5) << 2; |
|
|
|
bytestream2_skip(&gb, ((get_bits_count(&ctx->gb) + 31) >> 5) << 2); |
|
|
|
|
|
|
|
toks >>= 1; |
|
|
|
/* check if we have sane number of tokens */ |
|
|
|
@@ -313,11 +316,12 @@ static int tm2_read_stream(TM2Context *ctx, const uint8_t *buf, int stream_id, i |
|
|
|
} |
|
|
|
ctx->tokens[stream_id] = av_realloc(ctx->tokens[stream_id], toks * sizeof(int)); |
|
|
|
ctx->tok_lens[stream_id] = toks; |
|
|
|
len = AV_RB32(buf); buf += 4; cur += 4; |
|
|
|
len = bytestream2_get_be32(&gb); |
|
|
|
if(len > 0) { |
|
|
|
if (skip <= cur) |
|
|
|
pos = bytestream2_tell(&gb); |
|
|
|
if (skip <= pos) |
|
|
|
return -1; |
|
|
|
init_get_bits(&ctx->gb, buf, (skip - cur) * 8); |
|
|
|
init_get_bits(&ctx->gb, buf + pos, (skip - pos) * 8); |
|
|
|
for(i = 0; i < toks; i++) { |
|
|
|
if (get_bits_left(&ctx->gb) <= 0) { |
|
|
|
av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect number of tokens: %i\n", toks); |
|
|
|
@@ -780,7 +784,7 @@ static int decode_frame(AVCodecContext *avctx, |
|
|
|
AVPacket *avpkt) |
|
|
|
{ |
|
|
|
const uint8_t *buf = avpkt->data; |
|
|
|
int buf_size = avpkt->size; |
|
|
|
int buf_size = avpkt->size & ~3; |
|
|
|
TM2Context * const l = avctx->priv_data; |
|
|
|
AVFrame * const p = &l->pic; |
|
|
|
int i, skip, t; |
|
|
|
@@ -805,6 +809,10 @@ static int decode_frame(AVCodecContext *avctx, |
|
|
|
} |
|
|
|
|
|
|
|
for(i = 0; i < TM2_NUM_STREAMS; i++){ |
|
|
|
if (skip >= buf_size) { |
|
|
|
av_log(avctx, AV_LOG_ERROR, "no space for tm2_read_stream\n"); |
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
} |
|
|
|
t = tm2_read_stream(l, l->buffer + skip, tm2_stream_order[i], buf_size - skip); |
|
|
|
if(t == -1){ |
|
|
|
return -1; |
|
|
|
|