1 /*
2 * Copyright © 2018, VideoLAN and dav1d authors
3 * Copyright © 2018, Two Orioles, LLC
4 * Copyright © 2019, James Almer <[email protected]>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright notice, this
11 * list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright notice,
14 * this list of conditions and the following disclaimer in the documentation
15 * and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #ifndef DAV1D_INPUT_PARSE_H
30 #define DAV1D_INPUT_PARSE_H
31
32 #include <limits.h>
33
34 #include "dav1d/headers.h"
35
leb128(FILE * const f,size_t * const len)36 static int leb128(FILE *const f, size_t *const len) {
37 uint64_t val = 0;
38 unsigned i = 0, more;
39 do {
40 uint8_t v;
41 if (fread(&v, 1, 1, f) < 1)
42 return -1;
43 more = v & 0x80;
44 val |= ((uint64_t) (v & 0x7F)) << (i * 7);
45 i++;
46 } while (more && i < 8);
47 if (val > UINT_MAX || more)
48 return -1;
49 *len = (size_t) val;
50 return i;
51 }
52
53 // these functions are based on an implementation from FFmpeg, and relicensed
54 // with author's permission
55
leb(const uint8_t * ptr,int sz,size_t * const len)56 static int leb(const uint8_t *ptr, int sz, size_t *const len) {
57 uint64_t val = 0;
58 unsigned i = 0, more;
59 do {
60 if (!sz--) return -1;
61 const int v = *ptr++;
62 more = v & 0x80;
63 val |= ((uint64_t) (v & 0x7F)) << (i * 7);
64 i++;
65 } while (more && i < 8);
66 if (val > UINT_MAX || more)
67 return -1;
68 *len = (size_t) val;
69 return i;
70 }
71
parse_obu_header(const uint8_t * buf,int buf_size,size_t * const obu_size,enum Dav1dObuType * const type,const int allow_implicit_size)72 static inline int parse_obu_header(const uint8_t *buf, int buf_size,
73 size_t *const obu_size,
74 enum Dav1dObuType *const type,
75 const int allow_implicit_size)
76 {
77 int ret, extension_flag, has_size_flag;
78
79 if (!buf_size)
80 return -1;
81 if (*buf & 0x80) // obu_forbidden_bit
82 return -1;
83
84 *type = (*buf & 0x78) >> 3;
85 extension_flag = (*buf & 0x4) >> 2;
86 has_size_flag = (*buf & 0x2) >> 1;
87 // ignore obu_reserved_1bit
88 buf++;
89 buf_size--;
90
91 if (extension_flag) {
92 if (!buf_size)
93 return -1;
94 buf++;
95 buf_size--;
96 // ignore fields
97 }
98
99 if (has_size_flag) {
100 ret = leb(buf, buf_size, obu_size);
101 if (ret < 0)
102 return -1;
103 return (int) *obu_size + ret + 1 + extension_flag;
104 } else if (!allow_implicit_size)
105 return -1;
106
107 *obu_size = buf_size;
108 return buf_size + 1 + extension_flag;
109 }
110
111 #endif /* DAV1D_INPUT_PARSE_H */
112