/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 | 117k | { |
39 | 117k | assert(sz); |
40 | 117k | c->ptr = c->ptr_start = data; |
41 | 117k | c->ptr_end = &c->ptr_start[sz]; |
42 | 117k | c->state = 0; |
43 | 117k | c->bits_left = 0; |
44 | 117k | c->error = 0; |
45 | 117k | } |
46 | | |
47 | 3.70M | unsigned dav1d_get_bit(GetBits *const c) { |
48 | 3.70M | if (!c->bits_left) { |
49 | 534k | if (c->ptr >= c->ptr_end) { |
50 | 246 | c->error = 1; |
51 | 533k | } else { |
52 | 533k | const unsigned state = *c->ptr++; |
53 | 533k | c->bits_left = 7; |
54 | 533k | c->state = (uint64_t) state << 57; |
55 | 533k | return state >> 7; |
56 | 533k | } |
57 | 534k | } |
58 | | |
59 | 3.17M | const uint64_t state = c->state; |
60 | 3.17M | c->bits_left--; |
61 | 3.17M | c->state = state << 1; |
62 | 3.17M | return (unsigned) (state >> 63); |
63 | 3.70M | } |
64 | | |
65 | 1.22M | static inline void refill(GetBits *const c, const int n) { |
66 | 1.22M | assert(c->bits_left >= 0 && c->bits_left < 32); |
67 | 1.22M | unsigned state = 0; |
68 | 1.33M | do { |
69 | 1.33M | if (c->ptr >= c->ptr_end) { |
70 | 1.08k | c->error = 1; |
71 | 1.08k | if (state) break; |
72 | 1.01k | return; |
73 | 1.08k | } |
74 | 1.33M | state = (state << 8) | *c->ptr++; |
75 | 1.33M | c->bits_left += 8; |
76 | 1.33M | } while (n > c->bits_left); |
77 | 1.22M | c->state |= (uint64_t) state << (64 - c->bits_left); |
78 | 1.22M | } |
79 | | |
80 | | #define GET_BITS(name, type, type64) \ |
81 | 2.09M | type name(GetBits *const c, const int n) { \ |
82 | 2.09M | assert(n > 0 && n <= 32); \ |
83 | 2.09M | /* Unsigned cast avoids refill after eob */ \ |
84 | 2.09M | if ((unsigned) n > (unsigned) c->bits_left) \ |
85 | 2.09M | refill(c, n); \ |
86 | 2.09M | const uint64_t state = c->state; \ |
87 | 2.09M | c->bits_left -= n; \ |
88 | 2.09M | c->state = state << n; \ |
89 | 2.09M | return (type) ((type64) state >> (64 - n)); \ |
90 | 2.09M | } Line | Count | Source | 81 | 1.84M | type name(GetBits *const c, const int n) { \ | 82 | 1.84M | assert(n > 0 && n <= 32); \ | 83 | 1.84M | /* Unsigned cast avoids refill after eob */ \ | 84 | 1.84M | if ((unsigned) n > (unsigned) c->bits_left) \ | 85 | 1.84M | refill(c, n); \ | 86 | 1.84M | const uint64_t state = c->state; \ | 87 | 1.84M | c->bits_left -= n; \ | 88 | 1.84M | c->state = state << n; \ | 89 | 1.84M | return (type) ((type64) state >> (64 - n)); \ | 90 | 1.84M | } |
Line | Count | Source | 81 | 250k | type name(GetBits *const c, const int n) { \ | 82 | 250k | assert(n > 0 && n <= 32); \ | 83 | 250k | /* Unsigned cast avoids refill after eob */ \ | 84 | 250k | if ((unsigned) n > (unsigned) c->bits_left) \ | 85 | 250k | refill(c, n); \ | 86 | 250k | const uint64_t state = c->state; \ | 87 | 250k | c->bits_left -= n; \ | 88 | 250k | c->state = state << n; \ | 89 | 250k | return (type) ((type64) state >> (64 - n)); \ | 90 | 250k | } |
|
91 | | |
92 | | GET_BITS(dav1d_get_bits, unsigned, uint64_t) |
93 | | GET_BITS(dav1d_get_sbits, int, int64_t) |
94 | | |
95 | 79.8k | unsigned dav1d_get_uleb128(GetBits *const c) { |
96 | 79.8k | uint64_t val = 0; |
97 | 79.8k | unsigned i = 0, more; |
98 | | |
99 | 80.9k | do { |
100 | 80.9k | const int v = dav1d_get_bits(c, 8); |
101 | 80.9k | more = v & 0x80; |
102 | 80.9k | val |= ((uint64_t) (v & 0x7F)) << i; |
103 | 80.9k | i += 7; |
104 | 80.9k | } while (more && i < 56); |
105 | | |
106 | 79.8k | if (val > UINT32_MAX || more) { |
107 | 93 | c->error = 1; |
108 | 93 | return 0; |
109 | 93 | } |
110 | | |
111 | 79.7k | return (unsigned) val; |
112 | 79.8k | } |
113 | | |
114 | 34.9k | 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 | 34.9k | assert(max > 1); |
118 | 34.9k | const int l = ulog2(max) + 1; |
119 | 34.9k | assert(l > 1); |
120 | 34.9k | const unsigned m = (1U << l) - max; |
121 | 34.9k | const unsigned v = dav1d_get_bits(c, l - 1); |
122 | 34.9k | return v < m ? v : (v << 1) - m + dav1d_get_bit(c); |
123 | 34.9k | } |
124 | | |
125 | 2.80k | unsigned dav1d_get_vlc(GetBits *const c) { |
126 | 2.80k | if (dav1d_get_bit(c)) |
127 | 33 | return 0; |
128 | | |
129 | 2.77k | int n_bits = 0; |
130 | 8.87k | do { |
131 | 8.87k | if (++n_bits == 32) |
132 | 6 | return UINT32_MAX; |
133 | 8.87k | } while (!dav1d_get_bit(c)); |
134 | | |
135 | 2.76k | return ((1U << n_bits) - 1) + dav1d_get_bits(c, n_bits); |
136 | 2.77k | } |
137 | | |
138 | | static unsigned get_bits_subexp_u(GetBits *const c, const unsigned ref, |
139 | | const unsigned n) |
140 | 142k | { |
141 | 142k | unsigned v = 0; |
142 | | |
143 | 329k | for (int i = 0;; i++) { |
144 | 329k | const int b = i ? 3 + i - 1 : 3; |
145 | | |
146 | 329k | if (n < v + 3 * (1 << b)) { |
147 | 7.63k | v += dav1d_get_uniform(c, n - v + 1); |
148 | 7.63k | break; |
149 | 7.63k | } |
150 | | |
151 | 321k | if (!dav1d_get_bit(c)) { |
152 | 134k | v += dav1d_get_bits(c, b); |
153 | 134k | break; |
154 | 134k | } |
155 | | |
156 | 187k | v += 1 << b; |
157 | 187k | } |
158 | | |
159 | 142k | return ref * 2 <= n ? inv_recenter(ref, v) : n - inv_recenter(n - ref, v); |
160 | 142k | } |
161 | | |
162 | 142k | int dav1d_get_bits_subexp(GetBits *const c, const int ref, const unsigned n) { |
163 | 142k | return (int) get_bits_subexp_u(c, ref + (1 << n), 2 << n) - (1 << n); |
164 | 142k | } |