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