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