matroskadec: implement matroska_ebmlnum_uint() using ebml_read_num()

Originally committed as revision 14608 to svn://svn.ffmpeg.org/ffmpeg/trunk
pull/126/head
Aurelien Jacobs 17 years ago
parent cc8be50637
commit c1e01133f6
  1. 56
      libavformat/matroskadec.c

@ -478,10 +478,9 @@ static int ebml_level_end(MatroskaDemuxContext *matroska)
* number.
* Returns: num. of bytes read. < 0 on error.
*/
static int ebml_read_num(MatroskaDemuxContext *matroska,
static int ebml_read_num(MatroskaDemuxContext *matroska, ByteIOContext *pb,
int max_size, uint64_t *number)
{
ByteIOContext *pb = matroska->ctx->pb;
int len_mask = 0x80, read = 1, n = 1;
int64_t total = 0;
@ -532,7 +531,7 @@ static int ebml_read_element_id(MatroskaDemuxContext *matroska, uint32_t *id)
uint64_t total;
/* read out the "EBML number", include tag in ID */
if ((read = ebml_read_num(matroska, 4, &total)) < 0)
if ((read = ebml_read_num(matroska, matroska->ctx->pb, 4, &total)) < 0)
return read;
*id = total | (1 << (read * 7));
@ -638,53 +637,26 @@ static int ebml_read_master(MatroskaDemuxContext *matroska, int length)
/*
* Read signed/unsigned "EBML" numbers.
* Return: number of bytes processed, < 0 on error.
* XXX: use ebml_read_num().
*/
static int matroska_ebmlnum_uint(uint8_t *data, uint32_t size, uint64_t *num)
static int matroska_ebmlnum_uint(MatroskaDemuxContext *matroska,
uint8_t *data, uint32_t size, uint64_t *num)
{
int len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
uint64_t total;
if (size <= 0)
return AVERROR_INVALIDDATA;
total = data[0];
while (read <= 8 && !(total & len_mask)) {
read++;
len_mask >>= 1;
}
if (read > 8)
return AVERROR_INVALIDDATA;
if ((total &= (len_mask - 1)) == len_mask - 1)
num_ffs++;
if (size < read)
return AVERROR_INVALIDDATA;
while (n < read) {
if (data[n] == 0xff)
num_ffs++;
total = (total << 8) | data[n];
n++;
}
if (read == num_ffs)
*num = (uint64_t)-1;
else
*num = total;
return read;
ByteIOContext pb;
init_put_byte(&pb, data, size, 0, NULL, NULL, NULL, NULL);
return ebml_read_num(matroska, &pb, 8, num);
}
/*
* Same as above, but signed.
*/
static int matroska_ebmlnum_sint(uint8_t *data, uint32_t size, int64_t *num)
static int matroska_ebmlnum_sint(MatroskaDemuxContext *matroska,
uint8_t *data, uint32_t size, int64_t *num)
{
uint64_t unum;
int res;
/* read as unsigned number first */
if ((res = matroska_ebmlnum_uint(data, size, &unum)) < 0)
if ((res = matroska_ebmlnum_uint(matroska, data, size, &unum)) < 0)
return res;
/* make signed (weird way) */
@ -762,7 +734,7 @@ static int ebml_parse_elem(MatroskaDemuxContext *matroska,
}
if (syntax->type != EBML_PASS && syntax->type != EBML_STOP)
if ((res = ebml_read_num(matroska, 8, &length)) < 0)
if ((res = ebml_read_num(matroska, pb, 8, &length)) < 0)
return res;
switch (syntax->type) {
@ -1387,7 +1359,7 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,
int n, flags, laces = 0;
uint64_t num;
if ((n = matroska_ebmlnum_uint(data, size, &num)) < 0) {
if ((n = matroska_ebmlnum_uint(matroska, data, size, &num)) < 0) {
av_log(matroska->ctx, AV_LOG_ERROR, "EBML block data error\n");
return res;
}
@ -1465,7 +1437,7 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,
case 0x3: /* EBML lacing */ {
uint32_t total;
n = matroska_ebmlnum_uint(data, size, &num);
n = matroska_ebmlnum_uint(matroska, data, size, &num);
if (n < 0) {
av_log(matroska->ctx, AV_LOG_INFO,
"EBML block data error\n");
@ -1477,7 +1449,7 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,
for (n = 1; res == 0 && n < laces - 1; n++) {
int64_t snum;
int r;
r = matroska_ebmlnum_sint (data, size, &snum);
r = matroska_ebmlnum_sint(matroska, data, size, &snum);
if (r < 0) {
av_log(matroska->ctx, AV_LOG_INFO,
"EBML block data error\n");

Loading…
Cancel
Save