image_webp/
vp8.rs

1//! An implementation of the VP8 Video Codec
2//!
3//! This module contains a partial implementation of the
4//! VP8 video format as defined in RFC-6386.
5//!
6//! It decodes Keyframes only.
7//! VP8 is the underpinning of the WebP image format
8//!
9//! # Related Links
10//! * [rfc-6386](http://tools.ietf.org/html/rfc6386) - The VP8 Data Format and Decoding Guide
11//! * [VP8.pdf](http://static.googleusercontent.com/media/research.google.com/en//pubs/archive/37073.pdf) - An overview of of the VP8 format
12
13use 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
26// Prediction modes
27const 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// Prediction mode enum
45#[repr(i8)]
46#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
47enum LumaMode {
48    /// Predict DC using row above and column to the left.
49    #[default]
50    DC = DC_PRED,
51
52    /// Predict rows using row above.
53    V = V_PRED,
54
55    /// Predict columns using column to the left.
56    H = H_PRED,
57
58    /// Propagate second differences.
59    TM = TM_PRED,
60
61    /// Each Y subblock is independently predicted.
62    B = B_PRED,
63}
64
65#[repr(i8)]
66#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
67enum ChromaMode {
68    /// Predict DC using row above and column to the left.
69    #[default]
70    DC = DC_PRED,
71
72    /// Predict rows using row above.
73    V = V_PRED,
74
75    /// Predict columns using column to the left.
76    H = H_PRED,
77
78    /// Propagate second differences.
79    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
153// Section 11.2
154// Tree for determining the keyframe luma intra prediction modes:
155const KEYFRAME_YMODE_TREE: [i8; 8] = [-B_PRED, 2, 4, 6, -DC_PRED, -V_PRED, -H_PRED, -TM_PRED];
156
157// Default probabilities for decoding the keyframe luma modes
158const 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
163// Tree for determining the keyframe B_PRED mode:
164const 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
169// Probabilities for the BPRED_MODE_TREE
170const 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
308// Section 11.4 Tree for determining macroblock the chroma mode
309const KEYFRAME_UV_MODE_TREE: [i8; 6] = [-DC_PRED, 2, -V_PRED, 4, -H_PRED, -TM_PRED];
310
311// Probabilities for determining macroblock mode
312const 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
317// Section 13.4
318type TokenProbTables = [[[[Prob; NUM_DCT_TOKENS - 1]; 3]; 8]; 4];
319type TokenProbTreeNodes = [[[[TreeNode; NUM_DCT_TOKENS - 1]; 3]; 8]; 4];
320
321// Probabilities that a token's probability will be updated
322const 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
493// Section 13.5
494// Default Probabilities for tokens
495const 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
684// DCT Tokens
685const 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/// A Representation of the last decoded video frame
769#[derive(Default, Debug, Clone)]
770pub struct Frame {
771    /// The width of the luma plane
772    pub width: u16,
773
774    /// The height of the luma plane
775    pub height: u16,
776
777    /// The luma plane of the frame
778    pub ybuf: Vec<u8>,
779
780    /// The blue plane of the frame
781    pub ubuf: Vec<u8>,
782
783    /// The red plane of the frame
784    pub vbuf: Vec<u8>,
785
786    /// Indicates whether this frame is a keyframe
787    pub keyframe: bool,
788
789    version: u8,
790
791    /// Indicates whether this frame is intended for display
792    pub for_display: bool,
793
794    // Section 9.2
795    /// The pixel type of the frame as defined by Section 9.2
796    /// of the VP8 Specification
797    pub pixel_type: u8,
798
799    // Section 9.4 and 15
800    filter_type: bool, //if true uses simple filter // if false uses normal filter
801    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    /// Fills an rgb buffer from the YUV buffers
820    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    /// Fills an rgba buffer from the YUV buffers
850    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    /// Gets the buffer size
879    #[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
902/// VP8 Decoder
903///
904/// Only decodes keyframes
905pub 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    // Section 9.10
930    prob_intra: Prob,
931
932    // Section 9.11
933    prob_skip_false: Option<Prob>,
934
935    top: Vec<MacroBlock>,
936    left: MacroBlock,
937
938    // The borders from the previous macroblock, used for predictions
939    // See Section 12
940    // Note that the left border contains the top left pixel
941    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    /// Create a new decoder.
953    /// The reader must present a raw vp8 bitstream to the decoder
954    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            // Section 9.10
993            prob_intra: 0u8,
994
995            // Section 9.11
996            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            // The intermediate result (max`284*155`) can be larger than the `i16` range.
1096            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        // Section 9.3
1133        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            // Almost always the first macro block, except when non exists (i.e. `width == 0`)
1195            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            // 8 pixels per macroblock
1211            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        // initialise binary decoder
1224        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            // 9.7 refresh golden frame and altref frame
1260            // FIXME: support this?
1261            return Err(DecodingError::UnsupportedFeature(
1262                "Non-keyframe frames".to_owned(),
1263            ));
1264        }
1265
1266        // Refresh entropy probs ?????
1267        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            // 9.10 remaining frame data
1282            self.prob_intra = 0;
1283
1284            // FIXME: support this?
1285            return Err(DecodingError::UnsupportedFeature(
1286                "Non-keyframe frames".to_owned(),
1287            ));
1288        } else {
1289            // Reset motion vectors
1290        }
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            // intra prediction
1324            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                // `LumaMode::B` - This is predicted individually
1330                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                    // Create a reference to a [i32; 16] array for add_residue (slices of size 16 do not work).
1386                    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        //8x8 with left top border of 1
1424        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        // perform bounds checks once up front,
1490        // so that the compiler doesn't have to insert them in the hot loop below
1491        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    /// Does loop filtering on the macroblock
1653    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            // we skip subblock filtering if the coding mode isn't B_PRED and there's no DCT coefficient coded
1664            let do_subblock_filtering =
1665                mb.luma_mode == LumaMode::B || (!mb.coeffs_skipped && mb.non_zero_dct);
1666
1667            //filter across left of macroblock
1668            if mbx > 0 {
1669                //simple loop filtering
1670                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            //filter across vertical subblocks in macroblock
1714            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            //filter across top of macroblock
1764            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                    //if bottom macroblock, can only filter if there is 3 pixels below
1779                    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            //filter across horizontal subblock edges within the macroblock
1818            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    //return values are the filter level, interior limit and hev threshold
1878    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 frame level filter level is 0, we must skip loop filter
1883        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        //interior limit
1907        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        //high edge variance threshold
1922        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    /// Decodes the current frame
1945    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        //do loop filtering
1987        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        // Section 11.3 #3
2056        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    // A
2069    {
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    // L
2099    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    // P
2110    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);
2122// creates the left and top border for chroma prediction
2123fn 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    // above
2133    {
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    // left
2147    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
2168// set border
2169fn 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    // top left is top right of previous chroma block
2177    left_border[0] = chroma_block[8];
2178
2179    // left border
2180    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// Only 16 elements from rblock are used to add residue, so it is restricted to 16 elements
2203// to enable SIMD and other optimizations.
2204//
2205// Clippy suggests the clamp method, but it seems to optimize worse as of rustc 1.82.0 nightly.
2206#[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    // This pass copies the top row to the rows below it.
2245    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    // This pass copies the first value of a row to the values right of it.
2257    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// Clippy suggests the clamp method, but it seems to optimize worse as of rustc 1.82.0 nightly.
2295#[allow(clippy::manual_clamp)]
2296fn predict_tmpred(a: &mut [u8], size: usize, x0: usize, y0: usize, stride: usize) {
2297    // The formula for tmpred is:
2298    // X_ij = L_i + A_j - P (i, j=0, 1, 2, 3)
2299    //
2300    // |-----|-----|-----|-----|-----|
2301    // | P   | A0  | A1  | A2  | A3  |
2302    // |-----|-----|-----|-----|-----|
2303    // | L0  | X00 | X01 | X02 | X03 |
2304    // |-----|-----|-----|-----|-----|
2305    // | L1  | X10 | X11 | X12 | X13 |
2306    // |-----|-----|-----|-----|-----|
2307    // | L2  | X20 | X21 | X22 | X23 |
2308    // |-----|-----|-----|-----|-----|
2309    // | L3  | X30 | X31 | X32 | X33 |
2310    // |-----|-----|-----|-----|-----|
2311    // Diagram from p. 52 of RFC 6386
2312
2313    // Split at L0
2314    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        // Add 1 to skip over L0 byte
2322        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}