/work/dav1d/src/getbits.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright © 2018, VideoLAN and dav1d authors |
3 | | * Copyright © 2018, Two Orioles, LLC |
4 | | * All rights reserved. |
5 | | * |
6 | | * Redistribution and use in source and binary forms, with or without |
7 | | * modification, are permitted provided that the following conditions are met: |
8 | | * |
9 | | * 1. Redistributions of source code must retain the above copyright notice, this |
10 | | * list of conditions and the following disclaimer. |
11 | | * |
12 | | * 2. Redistributions in binary form must reproduce the above copyright notice, |
13 | | * this list of conditions and the following disclaimer in the documentation |
14 | | * and/or other materials provided with the distribution. |
15 | | * |
16 | | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
17 | | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR |
20 | | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
22 | | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
23 | | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
24 | | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
25 | | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | | */ |
27 | | |
28 | | #include "config.h" |
29 | | |
30 | | #include <limits.h> |
31 | | |
32 | | #include "common/intops.h" |
33 | | |
34 | | #include "src/getbits.h" |
35 | | |
36 | | void dav1d_init_get_bits(GetBits *const c, const uint8_t *const data, |
37 | | const size_t sz) |
38 | 0 | { |
39 | 0 | assert(sz); |
40 | 0 | c->ptr = c->ptr_start = data; |
41 | 0 | c->ptr_end = &c->ptr_start[sz]; |
42 | 0 | c->state = 0; |
43 | 0 | c->bits_left = 0; |
44 | 0 | c->error = 0; |
45 | 0 | } |
46 | | |
47 | 0 | unsigned dav1d_get_bit(GetBits *const c) { |
48 | 0 | if (!c->bits_left) { |
49 | 0 | if (c->ptr >= c->ptr_end) { |
50 | 0 | c->error = 1; |
51 | 0 | } else { |
52 | 0 | const unsigned state = *c->ptr++; |
53 | 0 | c->bits_left = 7; |
54 | 0 | c->state = (uint64_t) state << 57; |
55 | 0 | return state >> 7; |
56 | 0 | } |
57 | 0 | } |
58 | | |
59 | 0 | const uint64_t state = c->state; |
60 | 0 | c->bits_left--; |
61 | 0 | c->state = state << 1; |
62 | 0 | return (unsigned) (state >> 63); |
63 | 0 | } |
64 | | |
65 | 0 | static inline void refill(GetBits *const c, const int n) { |
66 | 0 | assert(c->bits_left >= 0 && c->bits_left < 32); |
67 | 0 | unsigned state = 0; |
68 | 0 | do { |
69 | 0 | if (c->ptr >= c->ptr_end) { |
70 | 0 | c->error = 1; |
71 | 0 | if (state) break; |
72 | 0 | return; |
73 | 0 | } |
74 | 0 | state = (state << 8) | *c->ptr++; |
75 | 0 | c->bits_left += 8; |
76 | 0 | } while (n > c->bits_left); |
77 | 0 | c->state |= (uint64_t) state << (64 - c->bits_left); |
78 | 0 | } |
79 | | |
80 | | #define GET_BITS(name, type, type64) \ |
81 | 0 | type name(GetBits *const c, const int n) { \ |
82 | 0 | assert(n > 0 && n <= 32); \ |
83 | 0 | /* Unsigned cast avoids refill after eob */ \ |
84 | 0 | if ((unsigned) n > (unsigned) c->bits_left) \ |
85 | 0 | refill(c, n); \ |
86 | 0 | const uint64_t state = c->state; \ |
87 | 0 | c->bits_left -= n; \ |
88 | 0 | c->state = state << n; \ |
89 | 0 | return (type) ((type64) state >> (64 - n)); \ |
90 | 0 | } Unexecuted instantiation: dav1d_get_bits Unexecuted instantiation: dav1d_get_sbits |
91 | | |
92 | | GET_BITS(dav1d_get_bits, unsigned, uint64_t) |
93 | | GET_BITS(dav1d_get_sbits, int, int64_t) |
94 | | |
95 | 0 | unsigned dav1d_get_uleb128(GetBits *const c) { |
96 | 0 | uint64_t val = 0; |
97 | 0 | unsigned i = 0, more; |
98 | |
|
99 | 0 | do { |
100 | 0 | const int v = dav1d_get_bits(c, 8); |
101 | 0 | more = v & 0x80; |
102 | 0 | val |= ((uint64_t) (v & 0x7F)) << i; |
103 | 0 | i += 7; |
104 | 0 | } while (more && i < 56); |
105 | |
|
106 | 0 | if (val > UINT32_MAX || more) { |
107 | 0 | c->error = 1; |
108 | 0 | return 0; |
109 | 0 | } |
110 | | |
111 | 0 | return (unsigned) val; |
112 | 0 | } |
113 | | |
114 | 0 | unsigned dav1d_get_uniform(GetBits *const c, const unsigned max) { |
115 | | // Output in range [0..max-1] |
116 | | // max must be > 1, or else nothing is read from the bitstream |
117 | 0 | assert(max > 1); |
118 | 0 | const int l = ulog2(max) + 1; |
119 | 0 | assert(l > 1); |
120 | 0 | const unsigned m = (1U << l) - max; |
121 | 0 | const unsigned v = dav1d_get_bits(c, l - 1); |
122 | 0 | return v < m ? v : (v << 1) - m + dav1d_get_bit(c); |
123 | 0 | } |
124 | | |
125 | 0 | unsigned dav1d_get_vlc(GetBits *const c) { |
126 | 0 | if (dav1d_get_bit(c)) |
127 | 0 | return 0; |
128 | | |
129 | 0 | int n_bits = 0; |
130 | 0 | do { |
131 | 0 | if (++n_bits == 32) |
132 | 0 | return UINT32_MAX; |
133 | 0 | } while (!dav1d_get_bit(c)); |
134 | | |
135 | 0 | return ((1U << n_bits) - 1) + dav1d_get_bits(c, n_bits); |
136 | 0 | } |
137 | | |
138 | | static unsigned get_bits_subexp_u(GetBits *const c, const unsigned ref, |
139 | | const unsigned n) |
140 | 0 | { |
141 | 0 | unsigned v = 0; |
142 | |
|
143 | 0 | for (int i = 0;; i++) { |
144 | 0 | const int b = i ? 3 + i - 1 : 3; |
145 | |
|
146 | 0 | if (n < v + 3 * (1 << b)) { |
147 | 0 | v += dav1d_get_uniform(c, n - v + 1); |
148 | 0 | break; |
149 | 0 | } |
150 | | |
151 | 0 | if (!dav1d_get_bit(c)) { |
152 | 0 | v += dav1d_get_bits(c, b); |
153 | 0 | break; |
154 | 0 | } |
155 | | |
156 | 0 | v += 1 << b; |
157 | 0 | } |
158 | |
|
159 | 0 | return ref * 2 <= n ? inv_recenter(ref, v) : n - inv_recenter(n - ref, v); |
160 | 0 | } |
161 | | |
162 | 0 | int dav1d_get_bits_subexp(GetBits *const c, const int ref, const unsigned n) { |
163 | 0 | return (int) get_bits_subexp_u(c, ref + (1 << n), 2 << n) - (1 << n); |
164 | 0 | } |