From c1e01133f6c2c0533513b1dc07b00ad63125a3bb Mon Sep 17 00:00:00 2001 From: Aurelien Jacobs Date: Tue, 5 Aug 2008 00:42:52 +0000 Subject: [PATCH] matroskadec: implement matroska_ebmlnum_uint() using ebml_read_num() Originally committed as revision 14608 to svn://svn.ffmpeg.org/ffmpeg/trunk --- libavformat/matroskadec.c | 56 ++++++++++----------------------------- 1 file changed, 14 insertions(+), 42 deletions(-) diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index d90162b404..338f69868e 100644 --- a/libavformat/matroskadec.c +++ b/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");