1use byteorder_lite::{LittleEndian, ReadBytesExt};
14use std::default::Default;
15use std::io::Read;
16
17use crate::decoder::{DecodingError, UpsamplingMethod};
18use crate::yuv;
19
20use super::vp8_arithmetic_decoder::ArithmeticDecoder;
21use super::{loop_filter, transform};
22
23const MAX_SEGMENTS: usize = 4;
24const NUM_DCT_TOKENS: usize = 12;
25
26const DC_PRED: i8 = 0;
28const V_PRED: i8 = 1;
29const H_PRED: i8 = 2;
30const TM_PRED: i8 = 3;
31const B_PRED: i8 = 4;
32
33const B_DC_PRED: i8 = 0;
34const B_TM_PRED: i8 = 1;
35const B_VE_PRED: i8 = 2;
36const B_HE_PRED: i8 = 3;
37const B_LD_PRED: i8 = 4;
38const B_RD_PRED: i8 = 5;
39const B_VR_PRED: i8 = 6;
40const B_VL_PRED: i8 = 7;
41const B_HD_PRED: i8 = 8;
42const B_HU_PRED: i8 = 9;
43
44#[repr(i8)]
46#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
47enum LumaMode {
48 #[default]
50 DC = DC_PRED,
51
52 V = V_PRED,
54
55 H = H_PRED,
57
58 TM = TM_PRED,
60
61 B = B_PRED,
63}
64
65#[repr(i8)]
66#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
67enum ChromaMode {
68 #[default]
70 DC = DC_PRED,
71
72 V = V_PRED,
74
75 H = H_PRED,
77
78 TM = TM_PRED,
80}
81
82#[repr(i8)]
83#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
84enum IntraMode {
85 #[default]
86 DC = B_DC_PRED,
87 TM = B_TM_PRED,
88 VE = B_VE_PRED,
89 HE = B_HE_PRED,
90 LD = B_LD_PRED,
91 RD = B_RD_PRED,
92 VR = B_VR_PRED,
93 VL = B_VL_PRED,
94 HD = B_HD_PRED,
95 HU = B_HU_PRED,
96}
97
98type Prob = u8;
99
100#[derive(Clone, Copy)]
101pub(crate) struct TreeNode {
102 pub left: u8,
103 pub right: u8,
104 pub prob: Prob,
105 pub index: u8,
106}
107
108impl TreeNode {
109 const UNINIT: TreeNode = TreeNode {
110 left: 0,
111 right: 0,
112 prob: 0,
113 index: 0,
114 };
115
116 const fn prepare_branch(t: i8) -> u8 {
117 if t > 0 {
118 (t as u8) / 2
119 } else {
120 let value = -t;
121 0x80 | (value as u8)
122 }
123 }
124
125 pub(crate) const fn value_from_branch(t: u8) -> i8 {
126 (t & !0x80) as i8
127 }
128}
129
130const fn tree_nodes_from<const N: usize, const M: usize>(
131 tree: [i8; N],
132 probs: [Prob; M],
133) -> [TreeNode; M] {
134 if N != 2 * M {
135 panic!("invalid tree with probs");
136 }
137 let mut nodes = [TreeNode::UNINIT; M];
138 let mut i = 0;
139 while i < M {
140 nodes[i].left = TreeNode::prepare_branch(tree[2 * i]);
141 nodes[i].right = TreeNode::prepare_branch(tree[2 * i + 1]);
142 nodes[i].prob = probs[i];
143 nodes[i].index = i as u8;
144 i += 1;
145 }
146 nodes
147}
148
149const SEGMENT_ID_TREE: [i8; 6] = [2, 4, -0, -1, -2, -3];
150
151const SEGMENT_TREE_NODE_DEFAULTS: [TreeNode; 3] = tree_nodes_from(SEGMENT_ID_TREE, [255; 3]);
152
153const KEYFRAME_YMODE_TREE: [i8; 8] = [-B_PRED, 2, 4, 6, -DC_PRED, -V_PRED, -H_PRED, -TM_PRED];
156
157const KEYFRAME_YMODE_PROBS: [Prob; 4] = [145, 156, 163, 128];
159
160const KEYFRAME_YMODE_NODES: [TreeNode; 4] =
161 tree_nodes_from(KEYFRAME_YMODE_TREE, KEYFRAME_YMODE_PROBS);
162
163const KEYFRAME_BPRED_MODE_TREE: [i8; 18] = [
165 -B_DC_PRED, 2, -B_TM_PRED, 4, -B_VE_PRED, 6, 8, 12, -B_HE_PRED, 10, -B_RD_PRED, -B_VR_PRED,
166 -B_LD_PRED, 14, -B_VL_PRED, 16, -B_HD_PRED, -B_HU_PRED,
167];
168
169const KEYFRAME_BPRED_MODE_PROBS: [[[Prob; 9]; 10]; 10] = [
171 [
172 [231, 120, 48, 89, 115, 113, 120, 152, 112],
173 [152, 179, 64, 126, 170, 118, 46, 70, 95],
174 [175, 69, 143, 80, 85, 82, 72, 155, 103],
175 [56, 58, 10, 171, 218, 189, 17, 13, 152],
176 [144, 71, 10, 38, 171, 213, 144, 34, 26],
177 [114, 26, 17, 163, 44, 195, 21, 10, 173],
178 [121, 24, 80, 195, 26, 62, 44, 64, 85],
179 [170, 46, 55, 19, 136, 160, 33, 206, 71],
180 [63, 20, 8, 114, 114, 208, 12, 9, 226],
181 [81, 40, 11, 96, 182, 84, 29, 16, 36],
182 ],
183 [
184 [134, 183, 89, 137, 98, 101, 106, 165, 148],
185 [72, 187, 100, 130, 157, 111, 32, 75, 80],
186 [66, 102, 167, 99, 74, 62, 40, 234, 128],
187 [41, 53, 9, 178, 241, 141, 26, 8, 107],
188 [104, 79, 12, 27, 217, 255, 87, 17, 7],
189 [74, 43, 26, 146, 73, 166, 49, 23, 157],
190 [65, 38, 105, 160, 51, 52, 31, 115, 128],
191 [87, 68, 71, 44, 114, 51, 15, 186, 23],
192 [47, 41, 14, 110, 182, 183, 21, 17, 194],
193 [66, 45, 25, 102, 197, 189, 23, 18, 22],
194 ],
195 [
196 [88, 88, 147, 150, 42, 46, 45, 196, 205],
197 [43, 97, 183, 117, 85, 38, 35, 179, 61],
198 [39, 53, 200, 87, 26, 21, 43, 232, 171],
199 [56, 34, 51, 104, 114, 102, 29, 93, 77],
200 [107, 54, 32, 26, 51, 1, 81, 43, 31],
201 [39, 28, 85, 171, 58, 165, 90, 98, 64],
202 [34, 22, 116, 206, 23, 34, 43, 166, 73],
203 [68, 25, 106, 22, 64, 171, 36, 225, 114],
204 [34, 19, 21, 102, 132, 188, 16, 76, 124],
205 [62, 18, 78, 95, 85, 57, 50, 48, 51],
206 ],
207 [
208 [193, 101, 35, 159, 215, 111, 89, 46, 111],
209 [60, 148, 31, 172, 219, 228, 21, 18, 111],
210 [112, 113, 77, 85, 179, 255, 38, 120, 114],
211 [40, 42, 1, 196, 245, 209, 10, 25, 109],
212 [100, 80, 8, 43, 154, 1, 51, 26, 71],
213 [88, 43, 29, 140, 166, 213, 37, 43, 154],
214 [61, 63, 30, 155, 67, 45, 68, 1, 209],
215 [142, 78, 78, 16, 255, 128, 34, 197, 171],
216 [41, 40, 5, 102, 211, 183, 4, 1, 221],
217 [51, 50, 17, 168, 209, 192, 23, 25, 82],
218 ],
219 [
220 [125, 98, 42, 88, 104, 85, 117, 175, 82],
221 [95, 84, 53, 89, 128, 100, 113, 101, 45],
222 [75, 79, 123, 47, 51, 128, 81, 171, 1],
223 [57, 17, 5, 71, 102, 57, 53, 41, 49],
224 [115, 21, 2, 10, 102, 255, 166, 23, 6],
225 [38, 33, 13, 121, 57, 73, 26, 1, 85],
226 [41, 10, 67, 138, 77, 110, 90, 47, 114],
227 [101, 29, 16, 10, 85, 128, 101, 196, 26],
228 [57, 18, 10, 102, 102, 213, 34, 20, 43],
229 [117, 20, 15, 36, 163, 128, 68, 1, 26],
230 ],
231 [
232 [138, 31, 36, 171, 27, 166, 38, 44, 229],
233 [67, 87, 58, 169, 82, 115, 26, 59, 179],
234 [63, 59, 90, 180, 59, 166, 93, 73, 154],
235 [40, 40, 21, 116, 143, 209, 34, 39, 175],
236 [57, 46, 22, 24, 128, 1, 54, 17, 37],
237 [47, 15, 16, 183, 34, 223, 49, 45, 183],
238 [46, 17, 33, 183, 6, 98, 15, 32, 183],
239 [65, 32, 73, 115, 28, 128, 23, 128, 205],
240 [40, 3, 9, 115, 51, 192, 18, 6, 223],
241 [87, 37, 9, 115, 59, 77, 64, 21, 47],
242 ],
243 [
244 [104, 55, 44, 218, 9, 54, 53, 130, 226],
245 [64, 90, 70, 205, 40, 41, 23, 26, 57],
246 [54, 57, 112, 184, 5, 41, 38, 166, 213],
247 [30, 34, 26, 133, 152, 116, 10, 32, 134],
248 [75, 32, 12, 51, 192, 255, 160, 43, 51],
249 [39, 19, 53, 221, 26, 114, 32, 73, 255],
250 [31, 9, 65, 234, 2, 15, 1, 118, 73],
251 [88, 31, 35, 67, 102, 85, 55, 186, 85],
252 [56, 21, 23, 111, 59, 205, 45, 37, 192],
253 [55, 38, 70, 124, 73, 102, 1, 34, 98],
254 ],
255 [
256 [102, 61, 71, 37, 34, 53, 31, 243, 192],
257 [69, 60, 71, 38, 73, 119, 28, 222, 37],
258 [68, 45, 128, 34, 1, 47, 11, 245, 171],
259 [62, 17, 19, 70, 146, 85, 55, 62, 70],
260 [75, 15, 9, 9, 64, 255, 184, 119, 16],
261 [37, 43, 37, 154, 100, 163, 85, 160, 1],
262 [63, 9, 92, 136, 28, 64, 32, 201, 85],
263 [86, 6, 28, 5, 64, 255, 25, 248, 1],
264 [56, 8, 17, 132, 137, 255, 55, 116, 128],
265 [58, 15, 20, 82, 135, 57, 26, 121, 40],
266 ],
267 [
268 [164, 50, 31, 137, 154, 133, 25, 35, 218],
269 [51, 103, 44, 131, 131, 123, 31, 6, 158],
270 [86, 40, 64, 135, 148, 224, 45, 183, 128],
271 [22, 26, 17, 131, 240, 154, 14, 1, 209],
272 [83, 12, 13, 54, 192, 255, 68, 47, 28],
273 [45, 16, 21, 91, 64, 222, 7, 1, 197],
274 [56, 21, 39, 155, 60, 138, 23, 102, 213],
275 [85, 26, 85, 85, 128, 128, 32, 146, 171],
276 [18, 11, 7, 63, 144, 171, 4, 4, 246],
277 [35, 27, 10, 146, 174, 171, 12, 26, 128],
278 ],
279 [
280 [190, 80, 35, 99, 180, 80, 126, 54, 45],
281 [85, 126, 47, 87, 176, 51, 41, 20, 32],
282 [101, 75, 128, 139, 118, 146, 116, 128, 85],
283 [56, 41, 15, 176, 236, 85, 37, 9, 62],
284 [146, 36, 19, 30, 171, 255, 97, 27, 20],
285 [71, 30, 17, 119, 118, 255, 17, 18, 138],
286 [101, 38, 60, 138, 55, 70, 43, 26, 142],
287 [138, 45, 61, 62, 219, 1, 81, 188, 64],
288 [32, 41, 20, 117, 151, 142, 20, 21, 163],
289 [112, 19, 12, 61, 195, 128, 48, 4, 24],
290 ],
291];
292
293const KEYFRAME_BPRED_MODE_NODES: [[[TreeNode; 9]; 10]; 10] = {
294 let mut output = [[[TreeNode::UNINIT; 9]; 10]; 10];
295 let mut i = 0;
296 while i < output.len() {
297 let mut j = 0;
298 while j < output[i].len() {
299 output[i][j] =
300 tree_nodes_from(KEYFRAME_BPRED_MODE_TREE, KEYFRAME_BPRED_MODE_PROBS[i][j]);
301 j += 1;
302 }
303 i += 1;
304 }
305 output
306};
307
308const KEYFRAME_UV_MODE_TREE: [i8; 6] = [-DC_PRED, 2, -V_PRED, 4, -H_PRED, -TM_PRED];
310
311const KEYFRAME_UV_MODE_PROBS: [Prob; 3] = [142, 114, 183];
313
314const KEYFRAME_UV_MODE_NODES: [TreeNode; 3] =
315 tree_nodes_from(KEYFRAME_UV_MODE_TREE, KEYFRAME_UV_MODE_PROBS);
316
317type TokenProbTables = [[[[Prob; NUM_DCT_TOKENS - 1]; 3]; 8]; 4];
319type TokenProbTreeNodes = [[[[TreeNode; NUM_DCT_TOKENS - 1]; 3]; 8]; 4];
320
321const COEFF_UPDATE_PROBS: TokenProbTables = [
323 [
324 [
325 [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
326 [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
327 [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
328 ],
329 [
330 [176, 246, 255, 255, 255, 255, 255, 255, 255, 255, 255],
331 [223, 241, 252, 255, 255, 255, 255, 255, 255, 255, 255],
332 [249, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255],
333 ],
334 [
335 [255, 244, 252, 255, 255, 255, 255, 255, 255, 255, 255],
336 [234, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255],
337 [253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
338 ],
339 [
340 [255, 246, 254, 255, 255, 255, 255, 255, 255, 255, 255],
341 [239, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255],
342 [254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255],
343 ],
344 [
345 [255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255],
346 [251, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255],
347 [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
348 ],
349 [
350 [255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255],
351 [251, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255],
352 [254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255],
353 ],
354 [
355 [255, 254, 253, 255, 254, 255, 255, 255, 255, 255, 255],
356 [250, 255, 254, 255, 254, 255, 255, 255, 255, 255, 255],
357 [254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
358 ],
359 [
360 [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
361 [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
362 [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
363 ],
364 ],
365 [
366 [
367 [217, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
368 [225, 252, 241, 253, 255, 255, 254, 255, 255, 255, 255],
369 [234, 250, 241, 250, 253, 255, 253, 254, 255, 255, 255],
370 ],
371 [
372 [255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255],
373 [223, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255],
374 [238, 253, 254, 254, 255, 255, 255, 255, 255, 255, 255],
375 ],
376 [
377 [255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255],
378 [249, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255],
379 [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
380 ],
381 [
382 [255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255],
383 [247, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255],
384 [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
385 ],
386 [
387 [255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255],
388 [252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
389 [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
390 ],
391 [
392 [255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255],
393 [253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
394 [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
395 ],
396 [
397 [255, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255],
398 [250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
399 [254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
400 ],
401 [
402 [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
403 [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
404 [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
405 ],
406 ],
407 [
408 [
409 [186, 251, 250, 255, 255, 255, 255, 255, 255, 255, 255],
410 [234, 251, 244, 254, 255, 255, 255, 255, 255, 255, 255],
411 [251, 251, 243, 253, 254, 255, 254, 255, 255, 255, 255],
412 ],
413 [
414 [255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255],
415 [236, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255],
416 [251, 253, 253, 254, 254, 255, 255, 255, 255, 255, 255],
417 ],
418 [
419 [255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255],
420 [254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255],
421 [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
422 ],
423 [
424 [255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255],
425 [254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255],
426 [254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
427 ],
428 [
429 [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
430 [254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
431 [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
432 ],
433 [
434 [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
435 [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
436 [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
437 ],
438 [
439 [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
440 [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
441 [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
442 ],
443 [
444 [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
445 [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
446 [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
447 ],
448 ],
449 [
450 [
451 [248, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
452 [250, 254, 252, 254, 255, 255, 255, 255, 255, 255, 255],
453 [248, 254, 249, 253, 255, 255, 255, 255, 255, 255, 255],
454 ],
455 [
456 [255, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255],
457 [246, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255],
458 [252, 254, 251, 254, 254, 255, 255, 255, 255, 255, 255],
459 ],
460 [
461 [255, 254, 252, 255, 255, 255, 255, 255, 255, 255, 255],
462 [248, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255],
463 [253, 255, 254, 254, 255, 255, 255, 255, 255, 255, 255],
464 ],
465 [
466 [255, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255],
467 [245, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255],
468 [253, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255],
469 ],
470 [
471 [255, 251, 253, 255, 255, 255, 255, 255, 255, 255, 255],
472 [252, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255],
473 [255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255],
474 ],
475 [
476 [255, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255],
477 [249, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255],
478 [255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255],
479 ],
480 [
481 [255, 255, 253, 255, 255, 255, 255, 255, 255, 255, 255],
482 [250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
483 [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
484 ],
485 [
486 [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
487 [254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
488 [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
489 ],
490 ],
491];
492
493const COEFF_PROBS: TokenProbTables = [
496 [
497 [
498 [128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128],
499 [128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128],
500 [128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128],
501 ],
502 [
503 [253, 136, 254, 255, 228, 219, 128, 128, 128, 128, 128],
504 [189, 129, 242, 255, 227, 213, 255, 219, 128, 128, 128],
505 [106, 126, 227, 252, 214, 209, 255, 255, 128, 128, 128],
506 ],
507 [
508 [1, 98, 248, 255, 236, 226, 255, 255, 128, 128, 128],
509 [181, 133, 238, 254, 221, 234, 255, 154, 128, 128, 128],
510 [78, 134, 202, 247, 198, 180, 255, 219, 128, 128, 128],
511 ],
512 [
513 [1, 185, 249, 255, 243, 255, 128, 128, 128, 128, 128],
514 [184, 150, 247, 255, 236, 224, 128, 128, 128, 128, 128],
515 [77, 110, 216, 255, 236, 230, 128, 128, 128, 128, 128],
516 ],
517 [
518 [1, 101, 251, 255, 241, 255, 128, 128, 128, 128, 128],
519 [170, 139, 241, 252, 236, 209, 255, 255, 128, 128, 128],
520 [37, 116, 196, 243, 228, 255, 255, 255, 128, 128, 128],
521 ],
522 [
523 [1, 204, 254, 255, 245, 255, 128, 128, 128, 128, 128],
524 [207, 160, 250, 255, 238, 128, 128, 128, 128, 128, 128],
525 [102, 103, 231, 255, 211, 171, 128, 128, 128, 128, 128],
526 ],
527 [
528 [1, 152, 252, 255, 240, 255, 128, 128, 128, 128, 128],
529 [177, 135, 243, 255, 234, 225, 128, 128, 128, 128, 128],
530 [80, 129, 211, 255, 194, 224, 128, 128, 128, 128, 128],
531 ],
532 [
533 [1, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128],
534 [246, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128],
535 [255, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128],
536 ],
537 ],
538 [
539 [
540 [198, 35, 237, 223, 193, 187, 162, 160, 145, 155, 62],
541 [131, 45, 198, 221, 172, 176, 220, 157, 252, 221, 1],
542 [68, 47, 146, 208, 149, 167, 221, 162, 255, 223, 128],
543 ],
544 [
545 [1, 149, 241, 255, 221, 224, 255, 255, 128, 128, 128],
546 [184, 141, 234, 253, 222, 220, 255, 199, 128, 128, 128],
547 [81, 99, 181, 242, 176, 190, 249, 202, 255, 255, 128],
548 ],
549 [
550 [1, 129, 232, 253, 214, 197, 242, 196, 255, 255, 128],
551 [99, 121, 210, 250, 201, 198, 255, 202, 128, 128, 128],
552 [23, 91, 163, 242, 170, 187, 247, 210, 255, 255, 128],
553 ],
554 [
555 [1, 200, 246, 255, 234, 255, 128, 128, 128, 128, 128],
556 [109, 178, 241, 255, 231, 245, 255, 255, 128, 128, 128],
557 [44, 130, 201, 253, 205, 192, 255, 255, 128, 128, 128],
558 ],
559 [
560 [1, 132, 239, 251, 219, 209, 255, 165, 128, 128, 128],
561 [94, 136, 225, 251, 218, 190, 255, 255, 128, 128, 128],
562 [22, 100, 174, 245, 186, 161, 255, 199, 128, 128, 128],
563 ],
564 [
565 [1, 182, 249, 255, 232, 235, 128, 128, 128, 128, 128],
566 [124, 143, 241, 255, 227, 234, 128, 128, 128, 128, 128],
567 [35, 77, 181, 251, 193, 211, 255, 205, 128, 128, 128],
568 ],
569 [
570 [1, 157, 247, 255, 236, 231, 255, 255, 128, 128, 128],
571 [121, 141, 235, 255, 225, 227, 255, 255, 128, 128, 128],
572 [45, 99, 188, 251, 195, 217, 255, 224, 128, 128, 128],
573 ],
574 [
575 [1, 1, 251, 255, 213, 255, 128, 128, 128, 128, 128],
576 [203, 1, 248, 255, 255, 128, 128, 128, 128, 128, 128],
577 [137, 1, 177, 255, 224, 255, 128, 128, 128, 128, 128],
578 ],
579 ],
580 [
581 [
582 [253, 9, 248, 251, 207, 208, 255, 192, 128, 128, 128],
583 [175, 13, 224, 243, 193, 185, 249, 198, 255, 255, 128],
584 [73, 17, 171, 221, 161, 179, 236, 167, 255, 234, 128],
585 ],
586 [
587 [1, 95, 247, 253, 212, 183, 255, 255, 128, 128, 128],
588 [239, 90, 244, 250, 211, 209, 255, 255, 128, 128, 128],
589 [155, 77, 195, 248, 188, 195, 255, 255, 128, 128, 128],
590 ],
591 [
592 [1, 24, 239, 251, 218, 219, 255, 205, 128, 128, 128],
593 [201, 51, 219, 255, 196, 186, 128, 128, 128, 128, 128],
594 [69, 46, 190, 239, 201, 218, 255, 228, 128, 128, 128],
595 ],
596 [
597 [1, 191, 251, 255, 255, 128, 128, 128, 128, 128, 128],
598 [223, 165, 249, 255, 213, 255, 128, 128, 128, 128, 128],
599 [141, 124, 248, 255, 255, 128, 128, 128, 128, 128, 128],
600 ],
601 [
602 [1, 16, 248, 255, 255, 128, 128, 128, 128, 128, 128],
603 [190, 36, 230, 255, 236, 255, 128, 128, 128, 128, 128],
604 [149, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128],
605 ],
606 [
607 [1, 226, 255, 128, 128, 128, 128, 128, 128, 128, 128],
608 [247, 192, 255, 128, 128, 128, 128, 128, 128, 128, 128],
609 [240, 128, 255, 128, 128, 128, 128, 128, 128, 128, 128],
610 ],
611 [
612 [1, 134, 252, 255, 255, 128, 128, 128, 128, 128, 128],
613 [213, 62, 250, 255, 255, 128, 128, 128, 128, 128, 128],
614 [55, 93, 255, 128, 128, 128, 128, 128, 128, 128, 128],
615 ],
616 [
617 [128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128],
618 [128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128],
619 [128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128],
620 ],
621 ],
622 [
623 [
624 [202, 24, 213, 235, 186, 191, 220, 160, 240, 175, 255],
625 [126, 38, 182, 232, 169, 184, 228, 174, 255, 187, 128],
626 [61, 46, 138, 219, 151, 178, 240, 170, 255, 216, 128],
627 ],
628 [
629 [1, 112, 230, 250, 199, 191, 247, 159, 255, 255, 128],
630 [166, 109, 228, 252, 211, 215, 255, 174, 128, 128, 128],
631 [39, 77, 162, 232, 172, 180, 245, 178, 255, 255, 128],
632 ],
633 [
634 [1, 52, 220, 246, 198, 199, 249, 220, 255, 255, 128],
635 [124, 74, 191, 243, 183, 193, 250, 221, 255, 255, 128],
636 [24, 71, 130, 219, 154, 170, 243, 182, 255, 255, 128],
637 ],
638 [
639 [1, 182, 225, 249, 219, 240, 255, 224, 128, 128, 128],
640 [149, 150, 226, 252, 216, 205, 255, 171, 128, 128, 128],
641 [28, 108, 170, 242, 183, 194, 254, 223, 255, 255, 128],
642 ],
643 [
644 [1, 81, 230, 252, 204, 203, 255, 192, 128, 128, 128],
645 [123, 102, 209, 247, 188, 196, 255, 233, 128, 128, 128],
646 [20, 95, 153, 243, 164, 173, 255, 203, 128, 128, 128],
647 ],
648 [
649 [1, 222, 248, 255, 216, 213, 128, 128, 128, 128, 128],
650 [168, 175, 246, 252, 235, 205, 255, 255, 128, 128, 128],
651 [47, 116, 215, 255, 211, 212, 255, 255, 128, 128, 128],
652 ],
653 [
654 [1, 121, 236, 253, 212, 214, 255, 255, 128, 128, 128],
655 [141, 84, 213, 252, 201, 202, 255, 219, 128, 128, 128],
656 [42, 80, 160, 240, 162, 185, 255, 205, 128, 128, 128],
657 ],
658 [
659 [1, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128],
660 [244, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128],
661 [238, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128],
662 ],
663 ],
664];
665
666const COEFF_PROB_NODES: TokenProbTreeNodes = {
667 let mut output = [[[[TreeNode::UNINIT; 11]; 3]; 8]; 4];
668 let mut i = 0;
669 while i < output.len() {
670 let mut j = 0;
671 while j < output[i].len() {
672 let mut k = 0;
673 while k < output[i][j].len() {
674 output[i][j][k] = tree_nodes_from(DCT_TOKEN_TREE, COEFF_PROBS[i][j][k]);
675 k += 1;
676 }
677 j += 1;
678 }
679 i += 1;
680 }
681 output
682};
683
684const DCT_0: i8 = 0;
686const DCT_1: i8 = 1;
687const DCT_2: i8 = 2;
688const DCT_3: i8 = 3;
689const DCT_4: i8 = 4;
690const DCT_CAT1: i8 = 5;
691const DCT_CAT2: i8 = 6;
692const DCT_CAT3: i8 = 7;
693const DCT_CAT4: i8 = 8;
694const DCT_CAT5: i8 = 9;
695const DCT_CAT6: i8 = 10;
696const DCT_EOB: i8 = 11;
697
698const DCT_TOKEN_TREE: [i8; 22] = [
699 -DCT_EOB, 2, -DCT_0, 4, -DCT_1, 6, 8, 12, -DCT_2, 10, -DCT_3, -DCT_4, 14, 16, -DCT_CAT1,
700 -DCT_CAT2, 18, 20, -DCT_CAT3, -DCT_CAT4, -DCT_CAT5, -DCT_CAT6,
701];
702
703const PROB_DCT_CAT: [[Prob; 12]; 6] = [
704 [159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
705 [165, 145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
706 [173, 148, 140, 0, 0, 0, 0, 0, 0, 0, 0, 0],
707 [176, 155, 140, 135, 0, 0, 0, 0, 0, 0, 0, 0],
708 [180, 157, 141, 134, 130, 0, 0, 0, 0, 0, 0, 0],
709 [254, 254, 243, 230, 196, 177, 153, 140, 133, 130, 129, 0],
710];
711
712const DCT_CAT_BASE: [u8; 6] = [5, 7, 11, 19, 35, 67];
713const COEFF_BANDS: [u8; 16] = [0, 1, 2, 3, 6, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7];
714
715#[rustfmt::skip]
716const DC_QUANT: [i16; 128] = [
717 4, 5, 6, 7, 8, 9, 10, 10,
718 11, 12, 13, 14, 15, 16, 17, 17,
719 18, 19, 20, 20, 21, 21, 22, 22,
720 23, 23, 24, 25, 25, 26, 27, 28,
721 29, 30, 31, 32, 33, 34, 35, 36,
722 37, 37, 38, 39, 40, 41, 42, 43,
723 44, 45, 46, 46, 47, 48, 49, 50,
724 51, 52, 53, 54, 55, 56, 57, 58,
725 59, 60, 61, 62, 63, 64, 65, 66,
726 67, 68, 69, 70, 71, 72, 73, 74,
727 75, 76, 76, 77, 78, 79, 80, 81,
728 82, 83, 84, 85, 86, 87, 88, 89,
729 91, 93, 95, 96, 98, 100, 101, 102,
730 104, 106, 108, 110, 112, 114, 116, 118,
731 122, 124, 126, 128, 130, 132, 134, 136,
732 138, 140, 143, 145, 148, 151, 154, 157,
733];
734
735#[rustfmt::skip]
736const AC_QUANT: [i16; 128] = [
737 4, 5, 6, 7, 8, 9, 10, 11,
738 12, 13, 14, 15, 16, 17, 18, 19,
739 20, 21, 22, 23, 24, 25, 26, 27,
740 28, 29, 30, 31, 32, 33, 34, 35,
741 36, 37, 38, 39, 40, 41, 42, 43,
742 44, 45, 46, 47, 48, 49, 50, 51,
743 52, 53, 54, 55, 56, 57, 58, 60,
744 62, 64, 66, 68, 70, 72, 74, 76,
745 78, 80, 82, 84, 86, 88, 90, 92,
746 94, 96, 98, 100, 102, 104, 106, 108,
747 110, 112, 114, 116, 119, 122, 125, 128,
748 131, 134, 137, 140, 143, 146, 149, 152,
749 155, 158, 161, 164, 167, 170, 173, 177,
750 181, 185, 189, 193, 197, 201, 205, 209,
751 213, 217, 221, 225, 229, 234, 239, 245,
752 249, 254, 259, 264, 269, 274, 279, 284,
753];
754
755const ZIGZAG: [u8; 16] = [0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15];
756
757#[derive(Default, Clone, Copy)]
758struct MacroBlock {
759 bpred: [IntraMode; 16],
760 complexity: [u8; 9],
761 luma_mode: LumaMode,
762 chroma_mode: ChromaMode,
763 segmentid: u8,
764 coeffs_skipped: bool,
765 non_zero_dct: bool,
766}
767
768#[derive(Default, Debug, Clone)]
770pub struct Frame {
771 pub width: u16,
773
774 pub height: u16,
776
777 pub ybuf: Vec<u8>,
779
780 pub ubuf: Vec<u8>,
782
783 pub vbuf: Vec<u8>,
785
786 pub keyframe: bool,
788
789 version: u8,
790
791 pub for_display: bool,
793
794 pub pixel_type: u8,
798
799 filter_type: bool, filter_level: u8,
802 sharpness_level: u8,
803}
804
805impl Frame {
806 const fn chroma_width(&self) -> u16 {
807 self.width.div_ceil(2)
808 }
809
810 const fn buffer_width(&self) -> u16 {
811 let difference = self.width % 16;
812 if difference > 0 {
813 self.width + (16 - difference % 16)
814 } else {
815 self.width
816 }
817 }
818
819 pub(crate) fn fill_rgb(&self, buf: &mut [u8], upsampling_method: UpsamplingMethod) {
821 const BPP: usize = 3;
822
823 match upsampling_method {
824 UpsamplingMethod::Bilinear => {
825 yuv::fill_rgb_buffer_fancy::<BPP>(
826 buf,
827 &self.ybuf,
828 &self.ubuf,
829 &self.vbuf,
830 usize::from(self.width),
831 usize::from(self.height),
832 usize::from(self.buffer_width()),
833 );
834 }
835 UpsamplingMethod::Simple => {
836 yuv::fill_rgb_buffer_simple::<BPP>(
837 buf,
838 &self.ybuf,
839 &self.ubuf,
840 &self.vbuf,
841 usize::from(self.width),
842 usize::from(self.chroma_width()),
843 usize::from(self.buffer_width()),
844 );
845 }
846 }
847 }
848
849 pub(crate) fn fill_rgba(&self, buf: &mut [u8], upsampling_method: UpsamplingMethod) {
851 const BPP: usize = 4;
852
853 match upsampling_method {
854 UpsamplingMethod::Bilinear => {
855 yuv::fill_rgb_buffer_fancy::<BPP>(
856 buf,
857 &self.ybuf,
858 &self.ubuf,
859 &self.vbuf,
860 usize::from(self.width),
861 usize::from(self.height),
862 usize::from(self.buffer_width()),
863 );
864 }
865 UpsamplingMethod::Simple => {
866 yuv::fill_rgb_buffer_simple::<BPP>(
867 buf,
868 &self.ybuf,
869 &self.ubuf,
870 &self.vbuf,
871 usize::from(self.width),
872 usize::from(self.chroma_width()),
873 usize::from(self.buffer_width()),
874 );
875 }
876 }
877 }
878 #[must_use]
880 pub fn get_buf_size(&self) -> usize {
881 self.ybuf.len() * 3
882 }
883}
884
885#[derive(Clone, Copy, Default)]
886struct Segment {
887 ydc: i16,
888 yac: i16,
889
890 y2dc: i16,
891 y2ac: i16,
892
893 uvdc: i16,
894 uvac: i16,
895
896 delta_values: bool,
897
898 quantizer_level: i8,
899 loopfilter_level: i8,
900}
901
902pub struct Vp8Decoder<R> {
906 r: R,
907 b: ArithmeticDecoder,
908
909 mbwidth: u16,
910 mbheight: u16,
911 macroblocks: Vec<MacroBlock>,
912
913 frame: Frame,
914
915 segments_enabled: bool,
916 segments_update_map: bool,
917 segment: [Segment; MAX_SEGMENTS],
918
919 loop_filter_adjustments_enabled: bool,
920 ref_delta: [i32; 4],
921 mode_delta: [i32; 4],
922
923 partitions: [ArithmeticDecoder; 8],
924 num_partitions: u8,
925
926 segment_tree_nodes: [TreeNode; 3],
927 token_probs: Box<TokenProbTreeNodes>,
928
929 prob_intra: Prob,
931
932 prob_skip_false: Option<Prob>,
934
935 top: Vec<MacroBlock>,
936 left: MacroBlock,
937
938 top_border_y: Vec<u8>,
942 left_border_y: Vec<u8>,
943
944 top_border_u: Vec<u8>,
945 left_border_u: Vec<u8>,
946
947 top_border_v: Vec<u8>,
948 left_border_v: Vec<u8>,
949}
950
951impl<R: Read> Vp8Decoder<R> {
952 fn new(r: R) -> Self {
955 let f = Frame::default();
956 let s = Segment::default();
957 let m = MacroBlock::default();
958
959 Self {
960 r,
961 b: ArithmeticDecoder::new(),
962
963 mbwidth: 0,
964 mbheight: 0,
965 macroblocks: Vec::new(),
966
967 frame: f,
968 segments_enabled: false,
969 segments_update_map: false,
970 segment: [s; MAX_SEGMENTS],
971
972 loop_filter_adjustments_enabled: false,
973 ref_delta: [0; 4],
974 mode_delta: [0; 4],
975
976 partitions: [
977 ArithmeticDecoder::new(),
978 ArithmeticDecoder::new(),
979 ArithmeticDecoder::new(),
980 ArithmeticDecoder::new(),
981 ArithmeticDecoder::new(),
982 ArithmeticDecoder::new(),
983 ArithmeticDecoder::new(),
984 ArithmeticDecoder::new(),
985 ],
986
987 num_partitions: 1,
988
989 segment_tree_nodes: SEGMENT_TREE_NODE_DEFAULTS,
990 token_probs: Box::new(COEFF_PROB_NODES),
991
992 prob_intra: 0u8,
994
995 prob_skip_false: None,
997
998 top: Vec::new(),
999 left: m,
1000
1001 top_border_y: Vec::new(),
1002 left_border_y: Vec::new(),
1003
1004 top_border_u: Vec::new(),
1005 left_border_u: Vec::new(),
1006
1007 top_border_v: Vec::new(),
1008 left_border_v: Vec::new(),
1009 }
1010 }
1011
1012 fn update_token_probabilities(&mut self) -> Result<(), DecodingError> {
1013 let mut res = self.b.start_accumulated_result();
1014 for (i, is) in COEFF_UPDATE_PROBS.iter().enumerate() {
1015 for (j, js) in is.iter().enumerate() {
1016 for (k, ks) in js.iter().enumerate() {
1017 for (t, prob) in ks.iter().enumerate().take(NUM_DCT_TOKENS - 1) {
1018 if self.b.read_bool(*prob).or_accumulate(&mut res) {
1019 let v = self.b.read_literal(8).or_accumulate(&mut res);
1020 self.token_probs[i][j][k][t].prob = v;
1021 }
1022 }
1023 }
1024 }
1025 }
1026 self.b.check(res, ())
1027 }
1028
1029 fn init_partitions(&mut self, n: usize) -> Result<(), DecodingError> {
1030 if n > 1 {
1031 let mut sizes = vec![0; 3 * n - 3];
1032 self.r.read_exact(sizes.as_mut_slice())?;
1033
1034 for (i, s) in sizes.chunks(3).enumerate() {
1035 let size = { s }
1036 .read_u24::<LittleEndian>()
1037 .expect("Reading from &[u8] can't fail and the chunk is complete");
1038
1039 let size = size as usize;
1040 let mut buf = vec![[0; 4]; size.div_ceil(4)];
1041 let bytes: &mut [u8] = buf.as_mut_slice().as_flattened_mut();
1042 self.r.read_exact(&mut bytes[..size])?;
1043 self.partitions[i].init(buf, size)?;
1044 }
1045 }
1046
1047 let mut buf = Vec::new();
1048 self.r.read_to_end(&mut buf)?;
1049 let size = buf.len();
1050 let mut chunks = vec![[0; 4]; size.div_ceil(4)];
1051 chunks.as_mut_slice().as_flattened_mut()[..size].copy_from_slice(&buf);
1052 self.partitions[n - 1].init(chunks, size)?;
1053
1054 Ok(())
1055 }
1056
1057 fn read_quantization_indices(&mut self) -> Result<(), DecodingError> {
1058 fn dc_quant(index: i32) -> i16 {
1059 DC_QUANT[index.clamp(0, 127) as usize]
1060 }
1061
1062 fn ac_quant(index: i32) -> i16 {
1063 AC_QUANT[index.clamp(0, 127) as usize]
1064 }
1065
1066 let mut res = self.b.start_accumulated_result();
1067
1068 let yac_abs = self.b.read_literal(7).or_accumulate(&mut res);
1069 let ydc_delta = self.b.read_optional_signed_value(4).or_accumulate(&mut res);
1070 let y2dc_delta = self.b.read_optional_signed_value(4).or_accumulate(&mut res);
1071 let y2ac_delta = self.b.read_optional_signed_value(4).or_accumulate(&mut res);
1072 let uvdc_delta = self.b.read_optional_signed_value(4).or_accumulate(&mut res);
1073 let uvac_delta = self.b.read_optional_signed_value(4).or_accumulate(&mut res);
1074
1075 let n = if self.segments_enabled {
1076 MAX_SEGMENTS
1077 } else {
1078 1
1079 };
1080 for i in 0usize..n {
1081 let base = i32::from(if self.segments_enabled {
1082 if self.segment[i].delta_values {
1083 i16::from(self.segment[i].quantizer_level) + i16::from(yac_abs)
1084 } else {
1085 i16::from(self.segment[i].quantizer_level)
1086 }
1087 } else {
1088 i16::from(yac_abs)
1089 });
1090
1091 self.segment[i].ydc = dc_quant(base + ydc_delta);
1092 self.segment[i].yac = ac_quant(base);
1093
1094 self.segment[i].y2dc = dc_quant(base + y2dc_delta) * 2;
1095 self.segment[i].y2ac = (i32::from(ac_quant(base + y2ac_delta)) * 155 / 100) as i16;
1097
1098 self.segment[i].uvdc = dc_quant(base + uvdc_delta);
1099 self.segment[i].uvac = ac_quant(base + uvac_delta);
1100
1101 if self.segment[i].y2ac < 8 {
1102 self.segment[i].y2ac = 8;
1103 }
1104
1105 if self.segment[i].uvdc > 132 {
1106 self.segment[i].uvdc = 132;
1107 }
1108 }
1109
1110 self.b.check(res, ())
1111 }
1112
1113 fn read_loop_filter_adjustments(&mut self) -> Result<(), DecodingError> {
1114 let mut res = self.b.start_accumulated_result();
1115
1116 if self.b.read_flag().or_accumulate(&mut res) {
1117 for i in 0usize..4 {
1118 self.ref_delta[i] = self.b.read_optional_signed_value(6).or_accumulate(&mut res);
1119 }
1120
1121 for i in 0usize..4 {
1122 self.mode_delta[i] = self.b.read_optional_signed_value(6).or_accumulate(&mut res);
1123 }
1124 }
1125
1126 self.b.check(res, ())
1127 }
1128
1129 fn read_segment_updates(&mut self) -> Result<(), DecodingError> {
1130 let mut res = self.b.start_accumulated_result();
1131
1132 self.segments_update_map = self.b.read_flag().or_accumulate(&mut res);
1134 let update_segment_feature_data = self.b.read_flag().or_accumulate(&mut res);
1135
1136 if update_segment_feature_data {
1137 let segment_feature_mode = self.b.read_flag().or_accumulate(&mut res);
1138
1139 for i in 0usize..MAX_SEGMENTS {
1140 self.segment[i].delta_values = !segment_feature_mode;
1141 }
1142
1143 for i in 0usize..MAX_SEGMENTS {
1144 self.segment[i].quantizer_level =
1145 self.b.read_optional_signed_value(7).or_accumulate(&mut res) as i8;
1146 }
1147
1148 for i in 0usize..MAX_SEGMENTS {
1149 self.segment[i].loopfilter_level =
1150 self.b.read_optional_signed_value(6).or_accumulate(&mut res) as i8;
1151 }
1152 }
1153
1154 if self.segments_update_map {
1155 for i in 0usize..3 {
1156 let update = self.b.read_flag().or_accumulate(&mut res);
1157
1158 let prob = if update {
1159 self.b.read_literal(8).or_accumulate(&mut res)
1160 } else {
1161 255
1162 };
1163 self.segment_tree_nodes[i].prob = prob;
1164 }
1165 }
1166
1167 self.b.check(res, ())
1168 }
1169
1170 fn read_frame_header(&mut self) -> Result<(), DecodingError> {
1171 let tag = self.r.read_u24::<LittleEndian>()?;
1172
1173 self.frame.keyframe = tag & 1 == 0;
1174 self.frame.version = ((tag >> 1) & 7) as u8;
1175 self.frame.for_display = (tag >> 4) & 1 != 0;
1176
1177 let first_partition_size = tag >> 5;
1178
1179 if self.frame.keyframe {
1180 let mut tag = [0u8; 3];
1181 self.r.read_exact(&mut tag)?;
1182
1183 if tag != [0x9d, 0x01, 0x2a] {
1184 return Err(DecodingError::Vp8MagicInvalid(tag));
1185 }
1186
1187 let w = self.r.read_u16::<LittleEndian>()?;
1188 let h = self.r.read_u16::<LittleEndian>()?;
1189
1190 self.frame.width = w & 0x3FFF;
1191 self.frame.height = h & 0x3FFF;
1192
1193 self.top = init_top_macroblocks(self.frame.width as usize);
1194 self.left = self.top.first().copied().unwrap_or_default();
1196
1197 self.mbwidth = self.frame.width.div_ceil(16);
1198 self.mbheight = self.frame.height.div_ceil(16);
1199
1200 self.frame.ybuf =
1201 vec![0u8; usize::from(self.mbwidth) * 16 * usize::from(self.mbheight) * 16];
1202 self.frame.ubuf =
1203 vec![0u8; usize::from(self.mbwidth) * 8 * usize::from(self.mbheight) * 8];
1204 self.frame.vbuf =
1205 vec![0u8; usize::from(self.mbwidth) * 8 * usize::from(self.mbheight) * 8];
1206
1207 self.top_border_y = vec![127u8; self.frame.width as usize + 4 + 16];
1208 self.left_border_y = vec![129u8; 1 + 16];
1209
1210 self.top_border_u = vec![127u8; 8 * self.mbwidth as usize];
1212 self.left_border_u = vec![129u8; 1 + 8];
1213
1214 self.top_border_v = vec![127u8; 8 * self.mbwidth as usize];
1215 self.left_border_v = vec![129u8; 1 + 8];
1216 }
1217
1218 let size = first_partition_size as usize;
1219 let mut buf = vec![[0; 4]; size.div_ceil(4)];
1220 let bytes: &mut [u8] = buf.as_mut_slice().as_flattened_mut();
1221 self.r.read_exact(&mut bytes[..size])?;
1222
1223 self.b.init(buf, size)?;
1225
1226 let mut res = self.b.start_accumulated_result();
1227 if self.frame.keyframe {
1228 let color_space = self.b.read_literal(1).or_accumulate(&mut res);
1229 self.frame.pixel_type = self.b.read_literal(1).or_accumulate(&mut res);
1230
1231 if color_space != 0 {
1232 return Err(DecodingError::ColorSpaceInvalid(color_space));
1233 }
1234 }
1235
1236 self.segments_enabled = self.b.read_flag().or_accumulate(&mut res);
1237 if self.segments_enabled {
1238 self.read_segment_updates()?;
1239 }
1240
1241 self.frame.filter_type = self.b.read_flag().or_accumulate(&mut res);
1242 self.frame.filter_level = self.b.read_literal(6).or_accumulate(&mut res);
1243 self.frame.sharpness_level = self.b.read_literal(3).or_accumulate(&mut res);
1244
1245 self.loop_filter_adjustments_enabled = self.b.read_flag().or_accumulate(&mut res);
1246 if self.loop_filter_adjustments_enabled {
1247 self.read_loop_filter_adjustments()?;
1248 }
1249
1250 let num_partitions = 1 << self.b.read_literal(2).or_accumulate(&mut res) as usize;
1251 self.b.check(res, ())?;
1252
1253 self.num_partitions = num_partitions as u8;
1254 self.init_partitions(num_partitions)?;
1255
1256 self.read_quantization_indices()?;
1257
1258 if !self.frame.keyframe {
1259 return Err(DecodingError::UnsupportedFeature(
1262 "Non-keyframe frames".to_owned(),
1263 ));
1264 }
1265
1266 let _ = self.b.read_literal(1);
1268
1269 self.update_token_probabilities()?;
1270
1271 let mut res = self.b.start_accumulated_result();
1272 let mb_no_skip_coeff = self.b.read_literal(1).or_accumulate(&mut res);
1273 self.prob_skip_false = if mb_no_skip_coeff == 1 {
1274 Some(self.b.read_literal(8).or_accumulate(&mut res))
1275 } else {
1276 None
1277 };
1278 self.b.check(res, ())?;
1279
1280 if !self.frame.keyframe {
1281 self.prob_intra = 0;
1283
1284 return Err(DecodingError::UnsupportedFeature(
1286 "Non-keyframe frames".to_owned(),
1287 ));
1288 } else {
1289 }
1291
1292 Ok(())
1293 }
1294
1295 fn read_macroblock_header(&mut self, mbx: usize) -> Result<MacroBlock, DecodingError> {
1296 let mut mb = MacroBlock::default();
1297 let mut res = self.b.start_accumulated_result();
1298
1299 if self.segments_enabled && self.segments_update_map {
1300 mb.segmentid =
1301 (self.b.read_with_tree(&self.segment_tree_nodes)).or_accumulate(&mut res) as u8;
1302 };
1303
1304 mb.coeffs_skipped = if let Some(prob) = self.prob_skip_false {
1305 self.b.read_bool(prob).or_accumulate(&mut res)
1306 } else {
1307 false
1308 };
1309
1310 let inter_predicted = if !self.frame.keyframe {
1311 self.b.read_bool(self.prob_intra).or_accumulate(&mut res)
1312 } else {
1313 false
1314 };
1315
1316 if inter_predicted {
1317 return Err(DecodingError::UnsupportedFeature(
1318 "VP8 inter-prediction".to_owned(),
1319 ));
1320 }
1321
1322 if self.frame.keyframe {
1323 let luma = (self.b.read_with_tree(&KEYFRAME_YMODE_NODES)).or_accumulate(&mut res);
1325 mb.luma_mode =
1326 LumaMode::from_i8(luma).ok_or(DecodingError::LumaPredictionModeInvalid(luma))?;
1327
1328 match mb.luma_mode.into_intra() {
1329 None => {
1331 for y in 0usize..4 {
1332 for x in 0usize..4 {
1333 let top = self.top[mbx].bpred[12 + x];
1334 let left = self.left.bpred[y];
1335 let intra = self.b.read_with_tree(
1336 &KEYFRAME_BPRED_MODE_NODES[top as usize][left as usize],
1337 );
1338 let intra = intra.or_accumulate(&mut res);
1339 let bmode = IntraMode::from_i8(intra)
1340 .ok_or(DecodingError::IntraPredictionModeInvalid(intra))?;
1341 mb.bpred[x + y * 4] = bmode;
1342
1343 self.top[mbx].bpred[12 + x] = bmode;
1344 self.left.bpred[y] = bmode;
1345 }
1346 }
1347 }
1348 Some(mode) => {
1349 for i in 0usize..4 {
1350 mb.bpred[12 + i] = mode;
1351 self.left.bpred[i] = mode;
1352 }
1353 }
1354 }
1355
1356 let chroma = (self.b.read_with_tree(&KEYFRAME_UV_MODE_NODES)).or_accumulate(&mut res);
1357 mb.chroma_mode = ChromaMode::from_i8(chroma)
1358 .ok_or(DecodingError::ChromaPredictionModeInvalid(chroma))?;
1359 }
1360
1361 self.top[mbx].chroma_mode = mb.chroma_mode;
1362 self.top[mbx].luma_mode = mb.luma_mode;
1363 self.top[mbx].bpred = mb.bpred;
1364
1365 self.b.check(res, mb)
1366 }
1367
1368 fn intra_predict_luma(&mut self, mbx: usize, mby: usize, mb: &MacroBlock, resdata: &[i32]) {
1369 let stride = 1usize + 16 + 4;
1370 let mw = self.mbwidth as usize;
1371 let mut ws = create_border_luma(mbx, mby, mw, &self.top_border_y, &self.left_border_y);
1372
1373 match mb.luma_mode {
1374 LumaMode::V => predict_vpred(&mut ws, 16, 1, 1, stride),
1375 LumaMode::H => predict_hpred(&mut ws, 16, 1, 1, stride),
1376 LumaMode::TM => predict_tmpred(&mut ws, 16, 1, 1, stride),
1377 LumaMode::DC => predict_dcpred(&mut ws, 16, stride, mby != 0, mbx != 0),
1378 LumaMode::B => predict_4x4(&mut ws, stride, &mb.bpred, resdata),
1379 }
1380
1381 if mb.luma_mode != LumaMode::B {
1382 for y in 0usize..4 {
1383 for x in 0usize..4 {
1384 let i = x + y * 4;
1385 let rb: &[i32; 16] = resdata[i * 16..][..16].try_into().unwrap();
1387 let y0 = 1 + y * 4;
1388 let x0 = 1 + x * 4;
1389
1390 add_residue(&mut ws, rb, y0, x0, stride);
1391 }
1392 }
1393 }
1394
1395 self.left_border_y[0] = ws[16];
1396
1397 for (i, left) in self.left_border_y[1..][..16].iter_mut().enumerate() {
1398 *left = ws[(i + 1) * stride + 16];
1399 }
1400
1401 for (top, &w) in self.top_border_y[mbx * 16..][..16]
1402 .iter_mut()
1403 .zip(&ws[16 * stride + 1..][..16])
1404 {
1405 *top = w;
1406 }
1407
1408 for y in 0usize..16 {
1409 for (ybuf, &ws) in self.frame.ybuf[(mby * 16 + y) * mw * 16 + mbx * 16..][..16]
1410 .iter_mut()
1411 .zip(ws[(1 + y) * stride + 1..][..16].iter())
1412 {
1413 *ybuf = ws;
1414 }
1415 }
1416 }
1417
1418 fn intra_predict_chroma(&mut self, mbx: usize, mby: usize, mb: &MacroBlock, resdata: &[i32]) {
1419 let stride = 1usize + 8;
1420
1421 let mw = self.mbwidth as usize;
1422
1423 let mut uws = create_border_chroma(mbx, mby, &self.top_border_u, &self.left_border_u);
1425 let mut vws = create_border_chroma(mbx, mby, &self.top_border_v, &self.left_border_v);
1426
1427 match mb.chroma_mode {
1428 ChromaMode::DC => {
1429 predict_dcpred(&mut uws, 8, stride, mby != 0, mbx != 0);
1430 predict_dcpred(&mut vws, 8, stride, mby != 0, mbx != 0);
1431 }
1432 ChromaMode::V => {
1433 predict_vpred(&mut uws, 8, 1, 1, stride);
1434 predict_vpred(&mut vws, 8, 1, 1, stride);
1435 }
1436 ChromaMode::H => {
1437 predict_hpred(&mut uws, 8, 1, 1, stride);
1438 predict_hpred(&mut vws, 8, 1, 1, stride);
1439 }
1440 ChromaMode::TM => {
1441 predict_tmpred(&mut uws, 8, 1, 1, stride);
1442 predict_tmpred(&mut vws, 8, 1, 1, stride);
1443 }
1444 }
1445
1446 for y in 0usize..2 {
1447 for x in 0usize..2 {
1448 let i = x + y * 2;
1449 let urb: &[i32; 16] = resdata[16 * 16 + i * 16..][..16].try_into().unwrap();
1450
1451 let y0 = 1 + y * 4;
1452 let x0 = 1 + x * 4;
1453 add_residue(&mut uws, urb, y0, x0, stride);
1454
1455 let vrb: &[i32; 16] = resdata[20 * 16 + i * 16..][..16].try_into().unwrap();
1456
1457 add_residue(&mut vws, vrb, y0, x0, stride);
1458 }
1459 }
1460
1461 set_chroma_border(&mut self.left_border_u, &mut self.top_border_u, &uws, mbx);
1462 set_chroma_border(&mut self.left_border_v, &mut self.top_border_v, &vws, mbx);
1463
1464 for y in 0usize..8 {
1465 let uv_buf_index = (mby * 8 + y) * mw * 8 + mbx * 8;
1466 let ws_index = (1 + y) * stride + 1;
1467
1468 for (((ub, vb), &uw), &vw) in self.frame.ubuf[uv_buf_index..][..8]
1469 .iter_mut()
1470 .zip(self.frame.vbuf[uv_buf_index..][..8].iter_mut())
1471 .zip(uws[ws_index..][..8].iter())
1472 .zip(vws[ws_index..][..8].iter())
1473 {
1474 *ub = uw;
1475 *vb = vw;
1476 }
1477 }
1478 }
1479
1480 fn read_coefficients(
1481 &mut self,
1482 block: &mut [i32; 16],
1483 p: usize,
1484 plane: usize,
1485 complexity: usize,
1486 dcq: i16,
1487 acq: i16,
1488 ) -> Result<bool, DecodingError> {
1489 assert!(complexity <= 2);
1492
1493 let first = if plane == 0 { 1usize } else { 0usize };
1494 let probs = &self.token_probs[plane];
1495 let decoder = &mut self.partitions[p];
1496
1497 let mut res = decoder.start_accumulated_result();
1498
1499 let mut complexity = complexity;
1500 let mut has_coefficients = false;
1501 let mut skip = false;
1502
1503 for i in first..16usize {
1504 let band = COEFF_BANDS[i] as usize;
1505 let tree = &probs[band][complexity];
1506
1507 let token = decoder
1508 .read_with_tree_with_first_node(tree, tree[skip as usize])
1509 .or_accumulate(&mut res);
1510
1511 let mut abs_value = i32::from(match token {
1512 DCT_EOB => break,
1513
1514 DCT_0 => {
1515 skip = true;
1516 has_coefficients = true;
1517 complexity = 0;
1518 continue;
1519 }
1520
1521 literal @ DCT_1..=DCT_4 => i16::from(literal),
1522
1523 category @ DCT_CAT1..=DCT_CAT6 => {
1524 let probs = PROB_DCT_CAT[(category - DCT_CAT1) as usize];
1525
1526 let mut extra = 0i16;
1527
1528 for t in probs.iter().copied() {
1529 if t == 0 {
1530 break;
1531 }
1532 let b = decoder.read_bool(t).or_accumulate(&mut res);
1533 extra = extra + extra + i16::from(b);
1534 }
1535
1536 i16::from(DCT_CAT_BASE[(category - DCT_CAT1) as usize]) + extra
1537 }
1538
1539 c => panic!("unknown token: {c}"),
1540 });
1541
1542 skip = false;
1543
1544 complexity = if abs_value == 0 {
1545 0
1546 } else if abs_value == 1 {
1547 1
1548 } else {
1549 2
1550 };
1551
1552 if decoder.read_flag().or_accumulate(&mut res) {
1553 abs_value = -abs_value;
1554 }
1555
1556 let zigzag = ZIGZAG[i] as usize;
1557 block[zigzag] = abs_value * i32::from(if zigzag > 0 { acq } else { dcq });
1558
1559 has_coefficients = true;
1560 }
1561
1562 decoder.check(res, has_coefficients)
1563 }
1564
1565 fn read_residual_data(
1566 &mut self,
1567 mb: &mut MacroBlock,
1568 mbx: usize,
1569 p: usize,
1570 ) -> Result<[i32; 384], DecodingError> {
1571 let sindex = mb.segmentid as usize;
1572 let mut blocks = [0i32; 384];
1573 let mut plane = if mb.luma_mode == LumaMode::B { 3 } else { 1 };
1574
1575 if plane == 1 {
1576 let complexity = self.top[mbx].complexity[0] + self.left.complexity[0];
1577 let mut block = [0i32; 16];
1578 let dcq = self.segment[sindex].y2dc;
1579 let acq = self.segment[sindex].y2ac;
1580 let n = self.read_coefficients(&mut block, p, plane, complexity as usize, dcq, acq)?;
1581
1582 self.left.complexity[0] = if n { 1 } else { 0 };
1583 self.top[mbx].complexity[0] = if n { 1 } else { 0 };
1584
1585 transform::iwht4x4(&mut block);
1586
1587 for k in 0usize..16 {
1588 blocks[16 * k] = block[k];
1589 }
1590
1591 plane = 0;
1592 }
1593
1594 for y in 0usize..4 {
1595 let mut left = self.left.complexity[y + 1];
1596 for x in 0usize..4 {
1597 let i = x + y * 4;
1598 let block = &mut blocks[i * 16..][..16];
1599 let block: &mut [i32; 16] = block.try_into().unwrap();
1600
1601 let complexity = self.top[mbx].complexity[x + 1] + left;
1602 let dcq = self.segment[sindex].ydc;
1603 let acq = self.segment[sindex].yac;
1604
1605 let n = self.read_coefficients(block, p, plane, complexity as usize, dcq, acq)?;
1606
1607 if block[0] != 0 || n {
1608 mb.non_zero_dct = true;
1609 transform::idct4x4(block);
1610 }
1611
1612 left = if n { 1 } else { 0 };
1613 self.top[mbx].complexity[x + 1] = if n { 1 } else { 0 };
1614 }
1615
1616 self.left.complexity[y + 1] = left;
1617 }
1618
1619 plane = 2;
1620
1621 for &j in &[5usize, 7usize] {
1622 for y in 0usize..2 {
1623 let mut left = self.left.complexity[y + j];
1624
1625 for x in 0usize..2 {
1626 let i = x + y * 2 + if j == 5 { 16 } else { 20 };
1627 let block = &mut blocks[i * 16..][..16];
1628 let block: &mut [i32; 16] = block.try_into().unwrap();
1629
1630 let complexity = self.top[mbx].complexity[x + j] + left;
1631 let dcq = self.segment[sindex].uvdc;
1632 let acq = self.segment[sindex].uvac;
1633
1634 let n =
1635 self.read_coefficients(block, p, plane, complexity as usize, dcq, acq)?;
1636 if block[0] != 0 || n {
1637 mb.non_zero_dct = true;
1638 transform::idct4x4(block);
1639 }
1640
1641 left = if n { 1 } else { 0 };
1642 self.top[mbx].complexity[x + j] = if n { 1 } else { 0 };
1643 }
1644
1645 self.left.complexity[y + j] = left;
1646 }
1647 }
1648
1649 Ok(blocks)
1650 }
1651
1652 fn loop_filter(&mut self, mbx: usize, mby: usize, mb: &MacroBlock) {
1654 let luma_w = self.mbwidth as usize * 16;
1655 let chroma_w = self.mbwidth as usize * 8;
1656
1657 let (filter_level, interior_limit, hev_threshold) = self.calculate_filter_parameters(mb);
1658
1659 if filter_level > 0 {
1660 let mbedge_limit = (filter_level + 2) * 2 + interior_limit;
1661 let sub_bedge_limit = (filter_level * 2) + interior_limit;
1662
1663 let do_subblock_filtering =
1665 mb.luma_mode == LumaMode::B || (!mb.coeffs_skipped && mb.non_zero_dct);
1666
1667 if mbx > 0 {
1669 if self.frame.filter_type {
1671 for y in 0usize..16 {
1672 let y0 = mby * 16 + y;
1673 let x0 = mbx * 16;
1674
1675 loop_filter::simple_segment_horizontal(
1676 mbedge_limit,
1677 &mut self.frame.ybuf[y0 * luma_w + x0 - 4..][..8],
1678 );
1679 }
1680 } else {
1681 for y in 0usize..16 {
1682 let y0 = mby * 16 + y;
1683 let x0 = mbx * 16;
1684
1685 loop_filter::macroblock_filter_horizontal(
1686 hev_threshold,
1687 interior_limit,
1688 mbedge_limit,
1689 &mut self.frame.ybuf[y0 * luma_w + x0 - 4..][..8],
1690 );
1691 }
1692
1693 for y in 0usize..8 {
1694 let y0 = mby * 8 + y;
1695 let x0 = mbx * 8;
1696
1697 loop_filter::macroblock_filter_horizontal(
1698 hev_threshold,
1699 interior_limit,
1700 mbedge_limit,
1701 &mut self.frame.ubuf[y0 * chroma_w + x0 - 4..][..8],
1702 );
1703 loop_filter::macroblock_filter_horizontal(
1704 hev_threshold,
1705 interior_limit,
1706 mbedge_limit,
1707 &mut self.frame.vbuf[y0 * chroma_w + x0 - 4..][..8],
1708 );
1709 }
1710 }
1711 }
1712
1713 if do_subblock_filtering {
1715 if self.frame.filter_type {
1716 for x in (4usize..16 - 1).step_by(4) {
1717 for y in 0..16 {
1718 let y0 = mby * 16 + y;
1719 let x0 = mbx * 16 + x;
1720
1721 loop_filter::simple_segment_horizontal(
1722 sub_bedge_limit,
1723 &mut self.frame.ybuf[y0 * luma_w + x0 - 4..][..8],
1724 );
1725 }
1726 }
1727 } else {
1728 for x in (4usize..16 - 3).step_by(4) {
1729 for y in 0..16 {
1730 let y0 = mby * 16 + y;
1731 let x0 = mbx * 16 + x;
1732
1733 loop_filter::subblock_filter_horizontal(
1734 hev_threshold,
1735 interior_limit,
1736 sub_bedge_limit,
1737 &mut self.frame.ybuf[y0 * luma_w + x0 - 4..][..8],
1738 );
1739 }
1740 }
1741
1742 for y in 0usize..8 {
1743 let y0 = mby * 8 + y;
1744 let x0 = mbx * 8 + 4;
1745
1746 loop_filter::subblock_filter_horizontal(
1747 hev_threshold,
1748 interior_limit,
1749 sub_bedge_limit,
1750 &mut self.frame.ubuf[y0 * chroma_w + x0 - 4..][..8],
1751 );
1752
1753 loop_filter::subblock_filter_horizontal(
1754 hev_threshold,
1755 interior_limit,
1756 sub_bedge_limit,
1757 &mut self.frame.vbuf[y0 * chroma_w + x0 - 4..][..8],
1758 );
1759 }
1760 }
1761 }
1762
1763 if mby > 0 {
1765 if self.frame.filter_type {
1766 for x in 0usize..16 {
1767 let y0 = mby * 16;
1768 let x0 = mbx * 16 + x;
1769
1770 loop_filter::simple_segment_vertical(
1771 mbedge_limit,
1772 &mut self.frame.ybuf[..],
1773 y0 * luma_w + x0,
1774 luma_w,
1775 );
1776 }
1777 } else {
1778 for x in 0usize..16 {
1780 let y0 = mby * 16;
1781 let x0 = mbx * 16 + x;
1782
1783 loop_filter::macroblock_filter_vertical(
1784 hev_threshold,
1785 interior_limit,
1786 mbedge_limit,
1787 &mut self.frame.ybuf[..],
1788 y0 * luma_w + x0,
1789 luma_w,
1790 );
1791 }
1792
1793 for x in 0usize..8 {
1794 let y0 = mby * 8;
1795 let x0 = mbx * 8 + x;
1796
1797 loop_filter::macroblock_filter_vertical(
1798 hev_threshold,
1799 interior_limit,
1800 mbedge_limit,
1801 &mut self.frame.ubuf[..],
1802 y0 * chroma_w + x0,
1803 chroma_w,
1804 );
1805 loop_filter::macroblock_filter_vertical(
1806 hev_threshold,
1807 interior_limit,
1808 mbedge_limit,
1809 &mut self.frame.vbuf[..],
1810 y0 * chroma_w + x0,
1811 chroma_w,
1812 );
1813 }
1814 }
1815 }
1816
1817 if do_subblock_filtering {
1819 if self.frame.filter_type {
1820 for y in (4usize..16 - 1).step_by(4) {
1821 for x in 0..16 {
1822 let y0 = mby * 16 + y;
1823 let x0 = mbx * 16 + x;
1824
1825 loop_filter::simple_segment_vertical(
1826 sub_bedge_limit,
1827 &mut self.frame.ybuf[..],
1828 y0 * luma_w + x0,
1829 luma_w,
1830 );
1831 }
1832 }
1833 } else {
1834 for y in (4usize..16 - 3).step_by(4) {
1835 for x in 0..16 {
1836 let y0 = mby * 16 + y;
1837 let x0 = mbx * 16 + x;
1838
1839 loop_filter::subblock_filter_vertical(
1840 hev_threshold,
1841 interior_limit,
1842 sub_bedge_limit,
1843 &mut self.frame.ybuf[..],
1844 y0 * luma_w + x0,
1845 luma_w,
1846 );
1847 }
1848 }
1849
1850 for x in 0..8 {
1851 let y0 = mby * 8 + 4;
1852 let x0 = mbx * 8 + x;
1853
1854 loop_filter::subblock_filter_vertical(
1855 hev_threshold,
1856 interior_limit,
1857 sub_bedge_limit,
1858 &mut self.frame.ubuf[..],
1859 y0 * chroma_w + x0,
1860 chroma_w,
1861 );
1862
1863 loop_filter::subblock_filter_vertical(
1864 hev_threshold,
1865 interior_limit,
1866 sub_bedge_limit,
1867 &mut self.frame.vbuf[..],
1868 y0 * chroma_w + x0,
1869 chroma_w,
1870 );
1871 }
1872 }
1873 }
1874 }
1875 }
1876
1877 fn calculate_filter_parameters(&self, macroblock: &MacroBlock) -> (u8, u8, u8) {
1879 let segment = self.segment[macroblock.segmentid as usize];
1880 let mut filter_level = i32::from(self.frame.filter_level);
1881
1882 if filter_level == 0 {
1884 return (0, 0, 0);
1885 }
1886
1887 if self.segments_enabled {
1888 if segment.delta_values {
1889 filter_level += i32::from(segment.loopfilter_level);
1890 } else {
1891 filter_level = i32::from(segment.loopfilter_level);
1892 }
1893 }
1894
1895 filter_level = filter_level.clamp(0, 63);
1896
1897 if self.loop_filter_adjustments_enabled {
1898 filter_level += self.ref_delta[0];
1899 if macroblock.luma_mode == LumaMode::B {
1900 filter_level += self.mode_delta[0];
1901 }
1902 }
1903
1904 let filter_level = filter_level.clamp(0, 63) as u8;
1905
1906 let mut interior_limit = filter_level;
1908
1909 if self.frame.sharpness_level > 0 {
1910 interior_limit >>= if self.frame.sharpness_level > 4 { 2 } else { 1 };
1911
1912 if interior_limit > 9 - self.frame.sharpness_level {
1913 interior_limit = 9 - self.frame.sharpness_level;
1914 }
1915 }
1916
1917 if interior_limit == 0 {
1918 interior_limit = 1;
1919 }
1920
1921 let mut hev_threshold = 0;
1923
1924 #[allow(clippy::collapsible_else_if)]
1925 if self.frame.keyframe {
1926 if filter_level >= 40 {
1927 hev_threshold = 2;
1928 } else if filter_level >= 15 {
1929 hev_threshold = 1;
1930 }
1931 } else {
1932 if filter_level >= 40 {
1933 hev_threshold = 3;
1934 } else if filter_level >= 20 {
1935 hev_threshold = 2;
1936 } else if filter_level >= 15 {
1937 hev_threshold = 1;
1938 }
1939 }
1940
1941 (filter_level, interior_limit, hev_threshold)
1942 }
1943
1944 pub fn decode_frame(r: R) -> Result<Frame, DecodingError> {
1946 let decoder = Self::new(r);
1947 decoder.decode_frame_()
1948 }
1949
1950 fn decode_frame_(mut self) -> Result<Frame, DecodingError> {
1951 self.read_frame_header()?;
1952
1953 for mby in 0..self.mbheight as usize {
1954 let p = mby % self.num_partitions as usize;
1955 self.left = MacroBlock::default();
1956
1957 for mbx in 0..self.mbwidth as usize {
1958 let mut mb = self.read_macroblock_header(mbx)?;
1959 let blocks = if !mb.coeffs_skipped {
1960 self.read_residual_data(&mut mb, mbx, p)?
1961 } else {
1962 if mb.luma_mode != LumaMode::B {
1963 self.left.complexity[0] = 0;
1964 self.top[mbx].complexity[0] = 0;
1965 }
1966
1967 for i in 1usize..9 {
1968 self.left.complexity[i] = 0;
1969 self.top[mbx].complexity[i] = 0;
1970 }
1971
1972 [0i32; 384]
1973 };
1974
1975 self.intra_predict_luma(mbx, mby, &mb, &blocks);
1976 self.intra_predict_chroma(mbx, mby, &mb, &blocks);
1977
1978 self.macroblocks.push(mb);
1979 }
1980
1981 self.left_border_y = vec![129u8; 1 + 16];
1982 self.left_border_u = vec![129u8; 1 + 8];
1983 self.left_border_v = vec![129u8; 1 + 8];
1984 }
1985
1986 for mby in 0..self.mbheight as usize {
1988 for mbx in 0..self.mbwidth as usize {
1989 let mb = self.macroblocks[mby * self.mbwidth as usize + mbx];
1990 self.loop_filter(mbx, mby, &mb);
1991 }
1992 }
1993
1994 Ok(self.frame)
1995 }
1996}
1997
1998impl LumaMode {
1999 const fn from_i8(val: i8) -> Option<Self> {
2000 Some(match val {
2001 DC_PRED => Self::DC,
2002 V_PRED => Self::V,
2003 H_PRED => Self::H,
2004 TM_PRED => Self::TM,
2005 B_PRED => Self::B,
2006 _ => return None,
2007 })
2008 }
2009
2010 const fn into_intra(self) -> Option<IntraMode> {
2011 Some(match self {
2012 Self::DC => IntraMode::DC,
2013 Self::V => IntraMode::VE,
2014 Self::H => IntraMode::HE,
2015 Self::TM => IntraMode::TM,
2016 Self::B => return None,
2017 })
2018 }
2019}
2020
2021impl ChromaMode {
2022 const fn from_i8(val: i8) -> Option<Self> {
2023 Some(match val {
2024 DC_PRED => Self::DC,
2025 V_PRED => Self::V,
2026 H_PRED => Self::H,
2027 TM_PRED => Self::TM,
2028 _ => return None,
2029 })
2030 }
2031}
2032
2033impl IntraMode {
2034 const fn from_i8(val: i8) -> Option<Self> {
2035 Some(match val {
2036 B_DC_PRED => Self::DC,
2037 B_TM_PRED => Self::TM,
2038 B_VE_PRED => Self::VE,
2039 B_HE_PRED => Self::HE,
2040 B_LD_PRED => Self::LD,
2041 B_RD_PRED => Self::RD,
2042 B_VR_PRED => Self::VR,
2043 B_VL_PRED => Self::VL,
2044 B_HD_PRED => Self::HD,
2045 B_HU_PRED => Self::HU,
2046 _ => return None,
2047 })
2048 }
2049}
2050
2051fn init_top_macroblocks(width: usize) -> Vec<MacroBlock> {
2052 let mb_width = width.div_ceil(16);
2053
2054 let mb = MacroBlock {
2055 bpred: [IntraMode::DC; 16],
2057 luma_mode: LumaMode::DC,
2058 ..MacroBlock::default()
2059 };
2060
2061 vec![mb; mb_width]
2062}
2063
2064fn create_border_luma(mbx: usize, mby: usize, mbw: usize, top: &[u8], left: &[u8]) -> [u8; 357] {
2065 let stride = 1usize + 16 + 4;
2066 let mut ws = [0u8; (1 + 16) * (1 + 16 + 4)];
2067
2068 {
2070 let above = &mut ws[1..stride];
2071 if mby == 0 {
2072 for above in above.iter_mut() {
2073 *above = 127;
2074 }
2075 } else {
2076 for (above, &top) in above[..16].iter_mut().zip(&top[mbx * 16..]) {
2077 *above = top;
2078 }
2079
2080 if mbx == mbw - 1 {
2081 for above in &mut above[16..] {
2082 *above = top[mbx * 16 + 15];
2083 }
2084 } else {
2085 for (above, &top) in above[16..].iter_mut().zip(&top[mbx * 16 + 16..]) {
2086 *above = top;
2087 }
2088 }
2089 }
2090 }
2091
2092 for i in 17usize..stride {
2093 ws[4 * stride + i] = ws[i];
2094 ws[8 * stride + i] = ws[i];
2095 ws[12 * stride + i] = ws[i];
2096 }
2097
2098 if mbx == 0 {
2100 for i in 0usize..16 {
2101 ws[(i + 1) * stride] = 129;
2102 }
2103 } else {
2104 for (i, &left) in (0usize..16).zip(&left[1..]) {
2105 ws[(i + 1) * stride] = left;
2106 }
2107 }
2108
2109 ws[0] = if mby == 0 {
2111 127
2112 } else if mbx == 0 {
2113 129
2114 } else {
2115 left[0]
2116 };
2117
2118 ws
2119}
2120
2121const CHROMA_BLOCK_SIZE: usize = (8 + 1) * (8 + 1);
2122fn create_border_chroma(
2124 mbx: usize,
2125 mby: usize,
2126 top: &[u8],
2127 left: &[u8],
2128) -> [u8; CHROMA_BLOCK_SIZE] {
2129 let stride: usize = 1usize + 8;
2130 let mut chroma_block = [0u8; CHROMA_BLOCK_SIZE];
2131
2132 {
2134 let above = &mut chroma_block[1..stride];
2135 if mby == 0 {
2136 for above in above.iter_mut() {
2137 *above = 127;
2138 }
2139 } else {
2140 for (above, &top) in above.iter_mut().zip(&top[mbx * 8..]) {
2141 *above = top;
2142 }
2143 }
2144 }
2145
2146 if mbx == 0 {
2148 for y in 0usize..8 {
2149 chroma_block[(y + 1) * stride] = 129;
2150 }
2151 } else {
2152 for (y, &left) in (0usize..8).zip(&left[1..]) {
2153 chroma_block[(y + 1) * stride] = left;
2154 }
2155 }
2156
2157 chroma_block[0] = if mby == 0 {
2158 127
2159 } else if mbx == 0 {
2160 129
2161 } else {
2162 left[0]
2163 };
2164
2165 chroma_block
2166}
2167
2168fn set_chroma_border(
2170 left_border: &mut [u8],
2171 top_border: &mut [u8],
2172 chroma_block: &[u8],
2173 mbx: usize,
2174) {
2175 let stride = 1usize + 8;
2176 left_border[0] = chroma_block[8];
2178
2179 for (i, left) in left_border[1..][..8].iter_mut().enumerate() {
2181 *left = chroma_block[(i + 1) * stride + 8];
2182 }
2183
2184 for (top, &w) in top_border[mbx * 8..][..8]
2185 .iter_mut()
2186 .zip(&chroma_block[8 * stride + 1..][..8])
2187 {
2188 *top = w;
2189 }
2190}
2191
2192fn avg3(left: u8, this: u8, right: u8) -> u8 {
2193 let avg = (u16::from(left) + 2 * u16::from(this) + u16::from(right) + 2) >> 2;
2194 avg as u8
2195}
2196
2197fn avg2(this: u8, right: u8) -> u8 {
2198 let avg = (u16::from(this) + u16::from(right) + 1) >> 1;
2199 avg as u8
2200}
2201
2202#[allow(clippy::manual_clamp)]
2207fn add_residue(pblock: &mut [u8], rblock: &[i32; 16], y0: usize, x0: usize, stride: usize) {
2208 let mut pos = y0 * stride + x0;
2209 for row in rblock.chunks(4) {
2210 for (p, &a) in pblock[pos..][..4].iter_mut().zip(row.iter()) {
2211 *p = (a + i32::from(*p)).max(0).min(255) as u8;
2212 }
2213 pos += stride;
2214 }
2215}
2216
2217fn predict_4x4(ws: &mut [u8], stride: usize, modes: &[IntraMode], resdata: &[i32]) {
2218 for sby in 0usize..4 {
2219 for sbx in 0usize..4 {
2220 let i = sbx + sby * 4;
2221 let y0 = sby * 4 + 1;
2222 let x0 = sbx * 4 + 1;
2223
2224 match modes[i] {
2225 IntraMode::TM => predict_tmpred(ws, 4, x0, y0, stride),
2226 IntraMode::VE => predict_bvepred(ws, x0, y0, stride),
2227 IntraMode::HE => predict_bhepred(ws, x0, y0, stride),
2228 IntraMode::DC => predict_bdcpred(ws, x0, y0, stride),
2229 IntraMode::LD => predict_bldpred(ws, x0, y0, stride),
2230 IntraMode::RD => predict_brdpred(ws, x0, y0, stride),
2231 IntraMode::VR => predict_bvrpred(ws, x0, y0, stride),
2232 IntraMode::VL => predict_bvlpred(ws, x0, y0, stride),
2233 IntraMode::HD => predict_bhdpred(ws, x0, y0, stride),
2234 IntraMode::HU => predict_bhupred(ws, x0, y0, stride),
2235 }
2236
2237 let rb: &[i32; 16] = resdata[i * 16..][..16].try_into().unwrap();
2238 add_residue(ws, rb, y0, x0, stride);
2239 }
2240 }
2241}
2242
2243fn predict_vpred(a: &mut [u8], size: usize, x0: usize, y0: usize, stride: usize) {
2244 let (above, curr) = a.split_at_mut(stride * y0);
2246 let above_slice = &above[x0..];
2247
2248 for curr_chunk in curr.chunks_exact_mut(stride).take(size) {
2249 for (curr, &above) in curr_chunk[1..].iter_mut().zip(above_slice) {
2250 *curr = above;
2251 }
2252 }
2253}
2254
2255fn predict_hpred(a: &mut [u8], size: usize, x0: usize, y0: usize, stride: usize) {
2256 for chunk in a.chunks_exact_mut(stride).skip(y0).take(size) {
2258 let left = chunk[x0 - 1];
2259 chunk[x0..].iter_mut().for_each(|a| *a = left);
2260 }
2261}
2262
2263fn predict_dcpred(a: &mut [u8], size: usize, stride: usize, above: bool, left: bool) {
2264 let mut sum = 0;
2265 let mut shf = if size == 8 { 2 } else { 3 };
2266
2267 if left {
2268 for y in 0usize..size {
2269 sum += u32::from(a[(y + 1) * stride]);
2270 }
2271
2272 shf += 1;
2273 }
2274
2275 if above {
2276 sum += a[1..=size].iter().fold(0, |acc, &x| acc + u32::from(x));
2277
2278 shf += 1;
2279 }
2280
2281 let dcval = if !left && !above {
2282 128
2283 } else {
2284 (sum + (1 << (shf - 1))) >> shf
2285 };
2286
2287 for y in 0usize..size {
2288 a[1 + stride * (y + 1)..][..size]
2289 .iter_mut()
2290 .for_each(|a| *a = dcval as u8);
2291 }
2292}
2293
2294#[allow(clippy::manual_clamp)]
2296fn predict_tmpred(a: &mut [u8], size: usize, x0: usize, y0: usize, stride: usize) {
2297 let (above, x_block) = a.split_at_mut(y0 * stride + (x0 - 1));
2315 let p = i32::from(above[(y0 - 1) * stride + x0 - 1]);
2316 let above_slice = &above[(y0 - 1) * stride + x0..];
2317
2318 for y in 0usize..size {
2319 let left_minus_p = i32::from(x_block[y * stride]) - p;
2320
2321 x_block[y * stride + 1..][..size]
2323 .iter_mut()
2324 .zip(above_slice)
2325 .for_each(|(cur, &abv)| *cur = (left_minus_p + i32::from(abv)).max(0).min(255) as u8);
2326 }
2327}
2328
2329fn predict_bdcpred(a: &mut [u8], x0: usize, y0: usize, stride: usize) {
2330 let mut v = 4;
2331
2332 a[(y0 - 1) * stride + x0..][..4]
2333 .iter()
2334 .for_each(|&a| v += u32::from(a));
2335
2336 for i in 0usize..4 {
2337 v += u32::from(a[(y0 + i) * stride + x0 - 1]);
2338 }
2339
2340 v >>= 3;
2341 for chunk in a.chunks_exact_mut(stride).skip(y0).take(4) {
2342 for ch in &mut chunk[x0..][..4] {
2343 *ch = v as u8;
2344 }
2345 }
2346}
2347
2348fn topleft_pixel(a: &[u8], x0: usize, y0: usize, stride: usize) -> u8 {
2349 a[(y0 - 1) * stride + x0 - 1]
2350}
2351
2352fn top_pixels(a: &[u8], x0: usize, y0: usize, stride: usize) -> (u8, u8, u8, u8, u8, u8, u8, u8) {
2353 let pos = (y0 - 1) * stride + x0;
2354 let a_slice = &a[pos..pos + 8];
2355 let a0 = a_slice[0];
2356 let a1 = a_slice[1];
2357 let a2 = a_slice[2];
2358 let a3 = a_slice[3];
2359 let a4 = a_slice[4];
2360 let a5 = a_slice[5];
2361 let a6 = a_slice[6];
2362 let a7 = a_slice[7];
2363
2364 (a0, a1, a2, a3, a4, a5, a6, a7)
2365}
2366
2367fn left_pixels(a: &[u8], x0: usize, y0: usize, stride: usize) -> (u8, u8, u8, u8) {
2368 let l0 = a[y0 * stride + x0 - 1];
2369 let l1 = a[(y0 + 1) * stride + x0 - 1];
2370 let l2 = a[(y0 + 2) * stride + x0 - 1];
2371 let l3 = a[(y0 + 3) * stride + x0 - 1];
2372
2373 (l0, l1, l2, l3)
2374}
2375
2376fn edge_pixels(
2377 a: &[u8],
2378 x0: usize,
2379 y0: usize,
2380 stride: usize,
2381) -> (u8, u8, u8, u8, u8, u8, u8, u8, u8) {
2382 let pos = (y0 - 1) * stride + x0 - 1;
2383 let a_slice = &a[pos..=pos + 4];
2384 let e0 = a[pos + 4 * stride];
2385 let e1 = a[pos + 3 * stride];
2386 let e2 = a[pos + 2 * stride];
2387 let e3 = a[pos + stride];
2388 let e4 = a_slice[0];
2389 let e5 = a_slice[1];
2390 let e6 = a_slice[2];
2391 let e7 = a_slice[3];
2392 let e8 = a_slice[4];
2393
2394 (e0, e1, e2, e3, e4, e5, e6, e7, e8)
2395}
2396
2397fn predict_bvepred(a: &mut [u8], x0: usize, y0: usize, stride: usize) {
2398 let p = topleft_pixel(a, x0, y0, stride);
2399 let (a0, a1, a2, a3, a4, ..) = top_pixels(a, x0, y0, stride);
2400 let avg_1 = avg3(p, a0, a1);
2401 let avg_2 = avg3(a0, a1, a2);
2402 let avg_3 = avg3(a1, a2, a3);
2403 let avg_4 = avg3(a2, a3, a4);
2404
2405 let avg = [avg_1, avg_2, avg_3, avg_4];
2406
2407 let mut pos = y0 * stride + x0;
2408 for _ in 0..4 {
2409 a[pos..=pos + 3].copy_from_slice(&avg);
2410 pos += stride;
2411 }
2412}
2413
2414fn predict_bhepred(a: &mut [u8], x0: usize, y0: usize, stride: usize) {
2415 let p = topleft_pixel(a, x0, y0, stride);
2416 let (l0, l1, l2, l3) = left_pixels(a, x0, y0, stride);
2417
2418 let avgs = [
2419 avg3(p, l0, l1),
2420 avg3(l0, l1, l2),
2421 avg3(l1, l2, l3),
2422 avg3(l2, l3, l3),
2423 ];
2424
2425 let mut pos = y0 * stride + x0;
2426 for avg in avgs {
2427 for a_p in &mut a[pos..=pos + 3] {
2428 *a_p = avg;
2429 }
2430 pos += stride;
2431 }
2432}
2433
2434fn predict_bldpred(a: &mut [u8], x0: usize, y0: usize, stride: usize) {
2435 let (a0, a1, a2, a3, a4, a5, a6, a7) = top_pixels(a, x0, y0, stride);
2436
2437 let avgs = [
2438 avg3(a0, a1, a2),
2439 avg3(a1, a2, a3),
2440 avg3(a2, a3, a4),
2441 avg3(a3, a4, a5),
2442 avg3(a4, a5, a6),
2443 avg3(a5, a6, a7),
2444 avg3(a6, a7, a7),
2445 ];
2446
2447 let mut pos = y0 * stride + x0;
2448
2449 for i in 0..4 {
2450 a[pos..=pos + 3].copy_from_slice(&avgs[i..=i + 3]);
2451 pos += stride;
2452 }
2453}
2454
2455fn predict_brdpred(a: &mut [u8], x0: usize, y0: usize, stride: usize) {
2456 let (e0, e1, e2, e3, e4, e5, e6, e7, e8) = edge_pixels(a, x0, y0, stride);
2457
2458 let avgs = [
2459 avg3(e0, e1, e2),
2460 avg3(e1, e2, e3),
2461 avg3(e2, e3, e4),
2462 avg3(e3, e4, e5),
2463 avg3(e4, e5, e6),
2464 avg3(e5, e6, e7),
2465 avg3(e6, e7, e8),
2466 ];
2467 let mut pos = y0 * stride + x0;
2468
2469 for i in 0..4 {
2470 a[pos..=pos + 3].copy_from_slice(&avgs[3 - i..7 - i]);
2471 pos += stride;
2472 }
2473}
2474
2475fn predict_bvrpred(a: &mut [u8], x0: usize, y0: usize, stride: usize) {
2476 let (_, e1, e2, e3, e4, e5, e6, e7, e8) = edge_pixels(a, x0, y0, stride);
2477
2478 a[(y0 + 3) * stride + x0] = avg3(e1, e2, e3);
2479 a[(y0 + 2) * stride + x0] = avg3(e2, e3, e4);
2480 a[(y0 + 3) * stride + x0 + 1] = avg3(e3, e4, e5);
2481 a[(y0 + 1) * stride + x0] = avg3(e3, e4, e5);
2482 a[(y0 + 2) * stride + x0 + 1] = avg2(e4, e5);
2483 a[y0 * stride + x0] = avg2(e4, e5);
2484 a[(y0 + 3) * stride + x0 + 2] = avg3(e4, e5, e6);
2485 a[(y0 + 1) * stride + x0 + 1] = avg3(e4, e5, e6);
2486 a[(y0 + 2) * stride + x0 + 2] = avg2(e5, e6);
2487 a[y0 * stride + x0 + 1] = avg2(e5, e6);
2488 a[(y0 + 3) * stride + x0 + 3] = avg3(e5, e6, e7);
2489 a[(y0 + 1) * stride + x0 + 2] = avg3(e5, e6, e7);
2490 a[(y0 + 2) * stride + x0 + 3] = avg2(e6, e7);
2491 a[y0 * stride + x0 + 2] = avg2(e6, e7);
2492 a[(y0 + 1) * stride + x0 + 3] = avg3(e6, e7, e8);
2493 a[y0 * stride + x0 + 3] = avg2(e7, e8);
2494}
2495
2496fn predict_bvlpred(a: &mut [u8], x0: usize, y0: usize, stride: usize) {
2497 let (a0, a1, a2, a3, a4, a5, a6, a7) = top_pixels(a, x0, y0, stride);
2498
2499 a[y0 * stride + x0] = avg2(a0, a1);
2500 a[(y0 + 1) * stride + x0] = avg3(a0, a1, a2);
2501 a[(y0 + 2) * stride + x0] = avg2(a1, a2);
2502 a[y0 * stride + x0 + 1] = avg2(a1, a2);
2503 a[(y0 + 1) * stride + x0 + 1] = avg3(a1, a2, a3);
2504 a[(y0 + 3) * stride + x0] = avg3(a1, a2, a3);
2505 a[(y0 + 2) * stride + x0 + 1] = avg2(a2, a3);
2506 a[y0 * stride + x0 + 2] = avg2(a2, a3);
2507 a[(y0 + 3) * stride + x0 + 1] = avg3(a2, a3, a4);
2508 a[(y0 + 1) * stride + x0 + 2] = avg3(a2, a3, a4);
2509 a[(y0 + 2) * stride + x0 + 2] = avg2(a3, a4);
2510 a[y0 * stride + x0 + 3] = avg2(a3, a4);
2511 a[(y0 + 3) * stride + x0 + 2] = avg3(a3, a4, a5);
2512 a[(y0 + 1) * stride + x0 + 3] = avg3(a3, a4, a5);
2513 a[(y0 + 2) * stride + x0 + 3] = avg3(a4, a5, a6);
2514 a[(y0 + 3) * stride + x0 + 3] = avg3(a5, a6, a7);
2515}
2516
2517fn predict_bhdpred(a: &mut [u8], x0: usize, y0: usize, stride: usize) {
2518 let (e0, e1, e2, e3, e4, e5, e6, e7, _) = edge_pixels(a, x0, y0, stride);
2519
2520 a[(y0 + 3) * stride + x0] = avg2(e0, e1);
2521 a[(y0 + 3) * stride + x0 + 1] = avg3(e0, e1, e2);
2522 a[(y0 + 2) * stride + x0] = avg2(e1, e2);
2523 a[(y0 + 3) * stride + x0 + 2] = avg2(e1, e2);
2524 a[(y0 + 2) * stride + x0 + 1] = avg3(e1, e2, e3);
2525 a[(y0 + 3) * stride + x0 + 3] = avg3(e1, e2, e3);
2526 a[(y0 + 2) * stride + x0 + 2] = avg2(e2, e3);
2527 a[(y0 + 1) * stride + x0] = avg2(e2, e3);
2528 a[(y0 + 2) * stride + x0 + 3] = avg3(e2, e3, e4);
2529 a[(y0 + 1) * stride + x0 + 1] = avg3(e2, e3, e4);
2530 a[(y0 + 1) * stride + x0 + 2] = avg2(e3, e4);
2531 a[y0 * stride + x0] = avg2(e3, e4);
2532 a[(y0 + 1) * stride + x0 + 3] = avg3(e3, e4, e5);
2533 a[y0 * stride + x0 + 1] = avg3(e3, e4, e5);
2534 a[y0 * stride + x0 + 2] = avg3(e4, e5, e6);
2535 a[y0 * stride + x0 + 3] = avg3(e5, e6, e7);
2536}
2537
2538fn predict_bhupred(a: &mut [u8], x0: usize, y0: usize, stride: usize) {
2539 let (l0, l1, l2, l3) = left_pixels(a, x0, y0, stride);
2540
2541 a[y0 * stride + x0] = avg2(l0, l1);
2542 a[y0 * stride + x0 + 1] = avg3(l0, l1, l2);
2543 a[y0 * stride + x0 + 2] = avg2(l1, l2);
2544 a[(y0 + 1) * stride + x0] = avg2(l1, l2);
2545 a[y0 * stride + x0 + 3] = avg3(l1, l2, l3);
2546 a[(y0 + 1) * stride + x0 + 1] = avg3(l1, l2, l3);
2547 a[(y0 + 1) * stride + x0 + 2] = avg2(l2, l3);
2548 a[(y0 + 2) * stride + x0] = avg2(l2, l3);
2549 a[(y0 + 1) * stride + x0 + 3] = avg3(l2, l3, l3);
2550 a[(y0 + 2) * stride + x0 + 1] = avg3(l2, l3, l3);
2551 a[(y0 + 2) * stride + x0 + 2] = l3;
2552 a[(y0 + 2) * stride + x0 + 3] = l3;
2553 a[(y0 + 3) * stride + x0] = l3;
2554 a[(y0 + 3) * stride + x0 + 1] = l3;
2555 a[(y0 + 3) * stride + x0 + 2] = l3;
2556 a[(y0 + 3) * stride + x0 + 3] = l3;
2557}
2558
2559#[cfg(all(test, feature = "_benchmarks"))]
2560mod benches {
2561 use super::*;
2562 use test::{black_box, Bencher};
2563
2564 const W: usize = 256;
2565 const H: usize = 256;
2566
2567 fn make_sample_image() -> Vec<u8> {
2568 let mut v = Vec::with_capacity((W * H * 4) as usize);
2569 for c in 0u8..=255 {
2570 for k in 0u8..=255 {
2571 v.push(c);
2572 v.push(0);
2573 v.push(0);
2574 v.push(k);
2575 }
2576 }
2577 v
2578 }
2579
2580 #[bench]
2581 fn bench_predict_4x4(b: &mut Bencher) {
2582 let mut v = black_box(make_sample_image());
2583
2584 let res_data = vec![1i32; W * H * 4];
2585 let modes = [
2586 IntraMode::TM,
2587 IntraMode::VE,
2588 IntraMode::HE,
2589 IntraMode::DC,
2590 IntraMode::LD,
2591 IntraMode::RD,
2592 IntraMode::VR,
2593 IntraMode::VL,
2594 IntraMode::HD,
2595 IntraMode::HU,
2596 IntraMode::TM,
2597 IntraMode::VE,
2598 IntraMode::HE,
2599 IntraMode::DC,
2600 IntraMode::LD,
2601 IntraMode::RD,
2602 ];
2603
2604 b.iter(|| {
2605 black_box(predict_4x4(&mut v, W * 2, &modes, &res_data));
2606 });
2607 }
2608
2609 #[bench]
2610 fn bench_predict_bvepred(b: &mut Bencher) {
2611 let mut v = make_sample_image();
2612
2613 b.iter(|| {
2614 predict_bvepred(black_box(&mut v), 5, 5, W * 2);
2615 });
2616 }
2617
2618 #[bench]
2619 fn bench_predict_bldpred(b: &mut Bencher) {
2620 let mut v = black_box(make_sample_image());
2621
2622 b.iter(|| {
2623 black_box(predict_bldpred(black_box(&mut v), 5, 5, W * 2));
2624 });
2625 }
2626
2627 #[bench]
2628 fn bench_predict_brdpred(b: &mut Bencher) {
2629 let mut v = black_box(make_sample_image());
2630
2631 b.iter(|| {
2632 black_box(predict_brdpred(black_box(&mut v), 5, 5, W * 2));
2633 });
2634 }
2635
2636 #[bench]
2637 fn bench_predict_bhepred(b: &mut Bencher) {
2638 let mut v = black_box(make_sample_image());
2639
2640 b.iter(|| {
2641 black_box(predict_bhepred(black_box(&mut v), 5, 5, W * 2));
2642 });
2643 }
2644
2645 #[bench]
2646 fn bench_top_pixels(b: &mut Bencher) {
2647 let v = black_box(make_sample_image());
2648
2649 b.iter(|| {
2650 black_box(top_pixels(black_box(&v), 5, 5, W * 2));
2651 });
2652 }
2653
2654 #[bench]
2655 fn bench_edge_pixels(b: &mut Bencher) {
2656 let v = black_box(make_sample_image());
2657
2658 b.iter(|| {
2659 black_box(edge_pixels(black_box(&v), 5, 5, W * 2));
2660 });
2661 }
2662}
2663
2664#[cfg(test)]
2665mod tests {
2666 use super::*;
2667
2668 #[test]
2669 fn test_avg2() {
2670 for i in 0u8..=255 {
2671 for j in 0u8..=255 {
2672 let ceil_avg = (f32::from(i) + f32::from(j)) / 2.0;
2673 let ceil_avg = ceil_avg.ceil() as u8;
2674 assert_eq!(
2675 ceil_avg,
2676 avg2(i, j),
2677 "avg2({}, {}), expected {}, got {}.",
2678 i,
2679 j,
2680 ceil_avg,
2681 avg2(i, j)
2682 );
2683 }
2684 }
2685 }
2686
2687 #[test]
2688 fn test_avg2_specific() {
2689 assert_eq!(
2690 255,
2691 avg2(255, 255),
2692 "avg2(255, 255), expected 255, got {}.",
2693 avg2(255, 255)
2694 );
2695 assert_eq!(1, avg2(1, 1), "avg2(1, 1), expected 1, got {}.", avg2(1, 1));
2696 assert_eq!(2, avg2(2, 1), "avg2(2, 1), expected 2, got {}.", avg2(2, 1));
2697 }
2698
2699 #[test]
2700 fn test_avg3() {
2701 for i in 0u8..=255 {
2702 for j in 0u8..=255 {
2703 for k in 0u8..=255 {
2704 let floor_avg =
2705 (2.0f32.mul_add(f32::from(j), f32::from(i)) + { f32::from(k) } + 2.0) / 4.0;
2706 let floor_avg = floor_avg.floor() as u8;
2707 assert_eq!(
2708 floor_avg,
2709 avg3(i, j, k),
2710 "avg3({}, {}, {}), expected {}, got {}.",
2711 i,
2712 j,
2713 k,
2714 floor_avg,
2715 avg3(i, j, k)
2716 );
2717 }
2718 }
2719 }
2720 }
2721
2722 #[test]
2723 fn test_edge_pixels() {
2724 #[rustfmt::skip]
2725 let im = vec![5, 6, 7, 8, 9,
2726 4, 0, 0, 0, 0,
2727 3, 0, 0, 0, 0,
2728 2, 0, 0, 0, 0,
2729 1, 0, 0, 0, 0];
2730 let (e0, e1, e2, e3, e4, e5, e6, e7, e8) = edge_pixels(&im, 1, 1, 5);
2731 assert_eq!(e0, 1);
2732 assert_eq!(e1, 2);
2733 assert_eq!(e2, 3);
2734 assert_eq!(e3, 4);
2735 assert_eq!(e4, 5);
2736 assert_eq!(e5, 6);
2737 assert_eq!(e6, 7);
2738 assert_eq!(e7, 8);
2739 assert_eq!(e8, 9);
2740 }
2741
2742 #[test]
2743 fn test_top_pixels() {
2744 #[rustfmt::skip]
2745 let im = vec![1, 2, 3, 4, 5, 6, 7, 8,
2746 0, 0, 0, 0, 0, 0, 0, 0,
2747 0, 0, 0, 0, 0, 0, 0, 0,
2748 0, 0, 0, 0, 0, 0, 0, 0,
2749 0, 0, 0, 0, 0, 0, 0, 0,
2750 0, 0, 0, 0, 0, 0, 0, 0,
2751 0, 0, 0, 0, 0, 0, 0, 0,
2752 0, 0, 0, 0, 0, 0, 0, 0];
2753 let (e0, e1, e2, e3, e4, e5, e6, e7) = top_pixels(&im, 0, 1, 8);
2754 assert_eq!(e0, 1);
2755 assert_eq!(e1, 2);
2756 assert_eq!(e2, 3);
2757 assert_eq!(e3, 4);
2758 assert_eq!(e4, 5);
2759 assert_eq!(e5, 6);
2760 assert_eq!(e6, 7);
2761 assert_eq!(e7, 8);
2762 }
2763
2764 #[test]
2765 fn test_add_residue() {
2766 let mut pblock = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
2767 let rblock = [
2768 -1, -2, -3, -4, 250, 249, 248, 250, -10, -18, -192, -17, -3, 15, 18, 9,
2769 ];
2770 let expected: [u8; 16] = [0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 10, 29, 33, 25];
2771
2772 add_residue(&mut pblock, &rblock, 0, 0, 4);
2773
2774 for (&e, &i) in expected.iter().zip(&pblock) {
2775 assert_eq!(e, i);
2776 }
2777 }
2778
2779 #[test]
2780 fn test_predict_bhepred() {
2781 #[rustfmt::skip]
2782 let expected: Vec<u8> = vec![5, 0, 0, 0, 0,
2783 4, 4, 4, 4, 4,
2784 3, 3, 3, 3, 3,
2785 2, 2, 2, 2, 2,
2786 1, 1, 1, 1, 1];
2787
2788 #[rustfmt::skip]
2789 let mut im = vec![5, 0, 0, 0, 0,
2790 4, 0, 0, 0, 0,
2791 3, 0, 0, 0, 0,
2792 2, 0, 0, 0, 0,
2793 1, 0, 0, 0, 0];
2794 predict_bhepred(&mut im, 1, 1, 5);
2795 for (&e, i) in expected.iter().zip(im) {
2796 assert_eq!(e, i);
2797 }
2798 }
2799
2800 #[test]
2801 fn test_predict_brdpred() {
2802 #[rustfmt::skip]
2803 let expected: Vec<u8> = vec![5, 6, 7, 8, 9,
2804 4, 5, 6, 7, 8,
2805 3, 4, 5, 6, 7,
2806 2, 3, 4, 5, 6,
2807 1, 2, 3, 4, 5];
2808
2809 #[rustfmt::skip]
2810 let mut im = vec![5, 6, 7, 8, 9,
2811 4, 0, 0, 0, 0,
2812 3, 0, 0, 0, 0,
2813 2, 0, 0, 0, 0,
2814 1, 0, 0, 0, 0];
2815 predict_brdpred(&mut im, 1, 1, 5);
2816 for (&e, i) in expected.iter().zip(im) {
2817 assert_eq!(e, i);
2818 }
2819 }
2820
2821 #[test]
2822 fn test_predict_bldpred() {
2823 #[rustfmt::skip]
2824 let mut im: Vec<u8> = vec![1, 2, 3, 4, 5, 6, 7, 8,
2825 0, 0, 0, 0, 0, 0, 0, 0,
2826 0, 0, 0, 0, 0, 0, 0, 0,
2827 0, 0, 0, 0, 0, 0, 0, 0,
2828 0, 0, 0, 0, 0, 0, 0, 0,
2829 0, 0, 0, 0, 0, 0, 0, 0,
2830 0, 0, 0, 0, 0, 0, 0, 0,
2831 0, 0, 0, 0, 0, 0, 0, 0,
2832 0, 0, 0, 0, 0, 0, 0, 0];
2833 let avg_1 = 2u8;
2834 let avg_2 = 3u8;
2835 let avg_3 = 4u8;
2836 let avg_4 = 5u8;
2837 let avg_5 = 6u8;
2838 let avg_6 = 7u8;
2839 let avg_7 = 8u8;
2840
2841 predict_bldpred(&mut im, 0, 1, 8);
2842
2843 assert_eq!(im[8], avg_1);
2844 assert_eq!(im[9], avg_2);
2845 assert_eq!(im[10], avg_3);
2846 assert_eq!(im[11], avg_4);
2847 assert_eq!(im[16], avg_2);
2848 assert_eq!(im[17], avg_3);
2849 assert_eq!(im[18], avg_4);
2850 assert_eq!(im[19], avg_5);
2851 assert_eq!(im[24], avg_3);
2852 assert_eq!(im[25], avg_4);
2853 assert_eq!(im[26], avg_5);
2854 assert_eq!(im[27], avg_6);
2855 assert_eq!(im[32], avg_4);
2856 assert_eq!(im[33], avg_5);
2857 assert_eq!(im[34], avg_6);
2858 assert_eq!(im[35], avg_7);
2859 }
2860
2861 #[test]
2862 fn test_predict_bvepred() {
2863 #[rustfmt::skip]
2864 let mut im: Vec<u8> = vec![1, 2, 3, 4, 5, 6, 7, 8, 9,
2865 0, 0, 0, 0, 0, 0, 0, 0, 0,
2866 0, 0, 0, 0, 0, 0, 0, 0, 0,
2867 0, 0, 0, 0, 0, 0, 0, 0, 0,
2868 0, 0, 0, 0, 0, 0, 0, 0, 0,
2869 0, 0, 0, 0, 0, 0, 0, 0, 0,
2870 0, 0, 0, 0, 0, 0, 0, 0, 0,
2871 0, 0, 0, 0, 0, 0, 0, 0, 0,
2872 0, 0, 0, 0, 0, 0, 0, 0, 0];
2873 let avg_1 = 2u8;
2874 let avg_2 = 3u8;
2875 let avg_3 = 4u8;
2876 let avg_4 = 5u8;
2877
2878 predict_bvepred(&mut im, 1, 1, 9);
2879
2880 assert_eq!(im[10], avg_1);
2881 assert_eq!(im[11], avg_2);
2882 assert_eq!(im[12], avg_3);
2883 assert_eq!(im[13], avg_4);
2884 assert_eq!(im[19], avg_1);
2885 assert_eq!(im[20], avg_2);
2886 assert_eq!(im[21], avg_3);
2887 assert_eq!(im[22], avg_4);
2888 assert_eq!(im[28], avg_1);
2889 assert_eq!(im[29], avg_2);
2890 assert_eq!(im[30], avg_3);
2891 assert_eq!(im[31], avg_4);
2892 assert_eq!(im[37], avg_1);
2893 assert_eq!(im[38], avg_2);
2894 assert_eq!(im[39], avg_3);
2895 assert_eq!(im[40], avg_4);
2896 }
2897}