matroskadec: implement matroska_ebmlnum_uint() using ebml_read_num()
authorAurelien Jacobs <aurel@gnuage.org>
Tue, 5 Aug 2008 00:42:52 +0000 (00:42 +0000)
committerAurelien Jacobs <aurel@gnuage.org>
Tue, 5 Aug 2008 00:42:52 +0000 (00:42 +0000)
Originally committed as revision 14608 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavformat/matroskadec.c

index d90162b..338f698 100644 (file)
@@ -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");