/src/libvpx/vp8/decoder/detokenize.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2010 The WebM project authors. All Rights Reserved. |
3 | | * |
4 | | * Use of this source code is governed by a BSD-style license |
5 | | * that can be found in the LICENSE file in the root of the source |
6 | | * tree. An additional intellectual property rights grant can be found |
7 | | * in the file PATENTS. All contributing project authors may |
8 | | * be found in the AUTHORS file in the root of the source tree. |
9 | | */ |
10 | | |
11 | | #include "vp8/common/blockd.h" |
12 | | #include "onyxd_int.h" |
13 | | #include "vpx_mem/vpx_mem.h" |
14 | | #include "vpx_ports/compiler_attributes.h" |
15 | | #include "vpx_ports/mem.h" |
16 | | #include "detokenize.h" |
17 | | |
18 | 9.83M | void vp8_reset_mb_tokens_context(MACROBLOCKD *x) { |
19 | 9.83M | ENTROPY_CONTEXT *a_ctx = ((ENTROPY_CONTEXT *)x->above_context); |
20 | 9.83M | ENTROPY_CONTEXT *l_ctx = ((ENTROPY_CONTEXT *)x->left_context); |
21 | | |
22 | 9.83M | memset(a_ctx, 0, sizeof(ENTROPY_CONTEXT_PLANES) - 1); |
23 | 9.83M | memset(l_ctx, 0, sizeof(ENTROPY_CONTEXT_PLANES) - 1); |
24 | | |
25 | | /* Clear entropy contexts for Y2 blocks */ |
26 | 9.83M | if (!x->mode_info_context->mbmi.is_4x4) { |
27 | 9.30M | a_ctx[8] = l_ctx[8] = 0; |
28 | 9.30M | } |
29 | 9.83M | } |
30 | | |
31 | | /* |
32 | | ------------------------------------------------------------------------------ |
33 | | Residual decoding (Paragraph 13.2 / 13.3) |
34 | | */ |
35 | | static const uint8_t kBands[16 + 1] = { |
36 | | 0, 1, 2, 3, 6, 4, 5, 6, 6, |
37 | | 6, 6, 6, 6, 6, 6, 7, 0 /* extra entry as sentinel */ |
38 | | }; |
39 | | |
40 | | static const uint8_t kCat3[] = { 173, 148, 140, 0 }; |
41 | | static const uint8_t kCat4[] = { 176, 155, 140, 135, 0 }; |
42 | | static const uint8_t kCat5[] = { 180, 157, 141, 134, 130, 0 }; |
43 | | static const uint8_t kCat6[] = { 254, 254, 243, 230, 196, 177, |
44 | | 153, 140, 133, 130, 129, 0 }; |
45 | | static const uint8_t *const kCat3456[] = { kCat3, kCat4, kCat5, kCat6 }; |
46 | | static const uint8_t kZigzag[16] = { 0, 1, 4, 8, 5, 2, 3, 6, |
47 | | 9, 12, 13, 10, 7, 11, 14, 15 }; |
48 | | |
49 | 230M | #define VP8GetBit vp8dx_decode_bool |
50 | | #define NUM_PROBAS 11 |
51 | | #define NUM_CTX 3 |
52 | | |
53 | | /* for const-casting */ |
54 | | typedef const uint8_t (*ProbaArray)[NUM_CTX][NUM_PROBAS]; |
55 | | |
56 | | // With corrupt / fuzzed streams the calculation of br->value may overflow. See |
57 | | // b/148271109. |
58 | | static VPX_NO_UNSIGNED_OVERFLOW_CHECK int GetSigned(BOOL_DECODER *br, |
59 | 30.4M | int value_to_sign) { |
60 | 30.4M | int split = (br->range + 1) >> 1; |
61 | 30.4M | VP8_BD_VALUE bigsplit = (VP8_BD_VALUE)split << (VP8_BD_VALUE_SIZE - 8); |
62 | 30.4M | int v; |
63 | | |
64 | 30.4M | if (br->count < 0) vp8dx_bool_decoder_fill(br); |
65 | | |
66 | 30.4M | if (br->value < bigsplit) { |
67 | 15.2M | br->range = split; |
68 | 15.2M | v = value_to_sign; |
69 | 15.2M | } else { |
70 | 15.1M | br->range = br->range - split; |
71 | 15.1M | br->value = br->value - bigsplit; |
72 | 15.1M | v = -value_to_sign; |
73 | 15.1M | } |
74 | 30.4M | br->range += br->range; |
75 | 30.4M | br->value += br->value; |
76 | 30.4M | br->count--; |
77 | | |
78 | 30.4M | return v; |
79 | 30.4M | } |
80 | | /* |
81 | | Returns the position of the last non-zero coeff plus one |
82 | | (and 0 if there's no coeff at all) |
83 | | */ |
84 | | static int GetCoeffs(BOOL_DECODER *br, ProbaArray prob, int ctx, int n, |
85 | 102M | int16_t *out) { |
86 | 102M | const uint8_t *p = prob[n][ctx]; |
87 | 102M | if (!VP8GetBit(br, p[0])) { /* first EOB is more a 'CBP' bit. */ |
88 | 84.3M | return 0; |
89 | 84.3M | } |
90 | 51.9M | while (1) { |
91 | 51.9M | ++n; |
92 | 51.9M | if (!VP8GetBit(br, p[1])) { |
93 | 21.5M | p = prob[kBands[n]][0]; |
94 | 30.4M | } else { /* non zero coeff */ |
95 | 30.4M | int v, j; |
96 | 30.4M | if (!VP8GetBit(br, p[2])) { |
97 | 25.5M | p = prob[kBands[n]][1]; |
98 | 25.5M | v = 1; |
99 | 25.5M | } else { |
100 | 4.90M | if (!VP8GetBit(br, p[3])) { |
101 | 4.29M | if (!VP8GetBit(br, p[4])) { |
102 | 3.05M | v = 2; |
103 | 3.05M | } else { |
104 | 1.24M | v = 3 + VP8GetBit(br, p[5]); |
105 | 1.24M | } |
106 | 4.29M | } else { |
107 | 610k | if (!VP8GetBit(br, p[6])) { |
108 | 382k | if (!VP8GetBit(br, p[7])) { |
109 | 271k | v = 5 + VP8GetBit(br, 159); |
110 | 271k | } else { |
111 | 110k | v = 7 + 2 * VP8GetBit(br, 165); |
112 | 110k | v += VP8GetBit(br, 145); |
113 | 110k | } |
114 | 382k | } else { |
115 | 227k | const uint8_t *tab; |
116 | 227k | const int bit1 = VP8GetBit(br, p[8]); |
117 | 227k | const int bit0 = VP8GetBit(br, p[9 + bit1]); |
118 | 227k | const int cat = 2 * bit1 + bit0; |
119 | 227k | v = 0; |
120 | 2.46M | for (tab = kCat3456[cat]; *tab; ++tab) { |
121 | 2.23M | v += v + VP8GetBit(br, *tab); |
122 | 2.23M | } |
123 | 227k | v += 3 + (8 << cat); |
124 | 227k | } |
125 | 610k | } |
126 | 4.90M | p = prob[kBands[n]][2]; |
127 | 4.90M | } |
128 | 30.4M | j = kZigzag[n - 1]; |
129 | | |
130 | 30.4M | out[j] = GetSigned(br, v); |
131 | | |
132 | 30.4M | if (n == 16 || !VP8GetBit(br, p[0])) { /* EOB */ |
133 | 18.4M | return n; |
134 | 18.4M | } |
135 | 30.4M | } |
136 | 33.5M | if (n == 16) { |
137 | 98.6k | return 16; |
138 | 98.6k | } |
139 | 33.5M | } |
140 | 18.5M | } |
141 | | |
142 | 4.17M | int vp8_decode_mb_tokens(VP8D_COMP *dx, MACROBLOCKD *x) { |
143 | 4.17M | BOOL_DECODER *bc = x->current_bc; |
144 | 4.17M | const FRAME_CONTEXT *const fc = &dx->common.fc; |
145 | 4.17M | char *eobs = x->eobs; |
146 | | |
147 | 4.17M | int i; |
148 | 4.17M | int nonzeros; |
149 | 4.17M | int eobtotal = 0; |
150 | | |
151 | 4.17M | short *qcoeff_ptr; |
152 | 4.17M | ProbaArray coef_probs; |
153 | 4.17M | ENTROPY_CONTEXT *a_ctx = ((ENTROPY_CONTEXT *)x->above_context); |
154 | 4.17M | ENTROPY_CONTEXT *l_ctx = ((ENTROPY_CONTEXT *)x->left_context); |
155 | 4.17M | ENTROPY_CONTEXT *a; |
156 | 4.17M | ENTROPY_CONTEXT *l; |
157 | 4.17M | int skip_dc = 0; |
158 | | |
159 | 4.17M | qcoeff_ptr = &x->qcoeff[0]; |
160 | | |
161 | 4.17M | if (!x->mode_info_context->mbmi.is_4x4) { |
162 | 2.69M | a = a_ctx + 8; |
163 | 2.69M | l = l_ctx + 8; |
164 | | |
165 | 2.69M | coef_probs = fc->coef_probs[1]; |
166 | | |
167 | 2.69M | nonzeros = GetCoeffs(bc, coef_probs, (*a + *l), 0, qcoeff_ptr + 24 * 16); |
168 | 2.69M | *a = *l = (nonzeros > 0); |
169 | | |
170 | 2.69M | eobs[24] = nonzeros; |
171 | 2.69M | eobtotal += nonzeros - 16; |
172 | | |
173 | 2.69M | coef_probs = fc->coef_probs[0]; |
174 | 2.69M | skip_dc = 1; |
175 | 2.69M | } else { |
176 | 1.47M | coef_probs = fc->coef_probs[3]; |
177 | 1.47M | skip_dc = 0; |
178 | 1.47M | } |
179 | | |
180 | 70.9M | for (i = 0; i < 16; ++i) { |
181 | 66.8M | a = a_ctx + (i & 3); |
182 | 66.8M | l = l_ctx + ((i & 0xc) >> 2); |
183 | | |
184 | 66.8M | nonzeros = GetCoeffs(bc, coef_probs, (*a + *l), skip_dc, qcoeff_ptr); |
185 | 66.8M | *a = *l = (nonzeros > 0); |
186 | | |
187 | 66.8M | nonzeros += skip_dc; |
188 | 66.8M | eobs[i] = nonzeros; |
189 | 66.8M | eobtotal += nonzeros; |
190 | 66.8M | qcoeff_ptr += 16; |
191 | 66.8M | } |
192 | | |
193 | 4.17M | coef_probs = fc->coef_probs[2]; |
194 | | |
195 | 4.17M | a_ctx += 4; |
196 | 4.17M | l_ctx += 4; |
197 | 37.5M | for (i = 16; i < 24; ++i) { |
198 | 33.4M | a = a_ctx + ((i > 19) << 1) + (i & 1); |
199 | 33.4M | l = l_ctx + ((i > 19) << 1) + ((i & 3) > 1); |
200 | | |
201 | 33.4M | nonzeros = GetCoeffs(bc, coef_probs, (*a + *l), 0, qcoeff_ptr); |
202 | 33.4M | *a = *l = (nonzeros > 0); |
203 | | |
204 | 33.4M | eobs[i] = nonzeros; |
205 | 33.4M | eobtotal += nonzeros; |
206 | 33.4M | qcoeff_ptr += 16; |
207 | 33.4M | } |
208 | | |
209 | 4.17M | return eobtotal; |
210 | 4.17M | } |