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(format:ImageFormat::WebP.into(), err: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: usize = (width + 15) / 16;
2163
2164 let mb: MacroBlock = 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 = (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 = (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: usize = y0 * stride + x0;
2245 for row: &[i32] in rblock.chunks(chunk_size:4) {
2246 for (p: &mut u8, &a: i32) in pblock[pos..pos + 4].iter_mut().zip(row.iter()) {
2247 *p = clamp(a:a + i32::from(*p), min:0, max: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: usize in 0usize..size {
2281 for x: usize 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: usize in 0usize..size {
2289 for x: usize 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: usize in 0usize..size {
2330 for x: usize in 0usize..size {
2331 let pred: i32 = 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(a:pred, min:0, max:255) as u8;
2336 }
2337 }
2338}
2339
2340fn predict_bdcpred(a: &mut [u8], x0: usize, y0: usize, stride: usize) {
2341 let mut v: u32 = 4;
2342 for i: usize 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: usize in 0usize..4 {
2348 for x: usize 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: usize = (y0 - 1) * stride + x0;
2360 let a_slice: &[u8] = &a[pos..pos + 8];
2361 let a0: u8 = a_slice[0];
2362 let a1: u8 = a_slice[1];
2363 let a2: u8 = a_slice[2];
2364 let a3: u8 = a_slice[3];
2365 let a4: u8 = a_slice[4];
2366 let a5: u8 = a_slice[5];
2367 let a6: u8 = a_slice[6];
2368 let a7: u8 = 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: u8 = a[y0 * stride + x0 - 1];
2375 let l1: u8 = a[(y0 + 1) * stride + x0 - 1];
2376 let l2: u8 = a[(y0 + 2) * stride + x0 - 1];
2377 let l3: u8 = 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: usize = (y0 - 1) * stride + x0 - 1;
2389 let a_slice: &[u8] = &a[pos..=pos + 4];
2390 let e0: u8 = a[pos + 4 * stride];
2391 let e1: u8 = a[pos + 3 * stride];
2392 let e2: u8 = a[pos + 2 * stride];
2393 let e3: u8 = a[pos + stride];
2394 let e4: u8 = a_slice[0];
2395 let e5: u8 = a_slice[1];
2396 let e6: u8 = a_slice[2];
2397 let e7: u8 = a_slice[3];
2398 let e8: u8 = 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: u8 = topleft_pixel(a, x0, y0, stride);
2405 let (a0: u8, a1: u8, a2: u8, a3: u8, a4: u8, _, _, _) = top_pixels(a, x0, y0, stride);
2406 let avg_1: u8 = avg3(left:p, this:a0, right:a1);
2407 let avg_2: u8 = avg3(left:a0, this:a1, right:a2);
2408 let avg_3: u8 = avg3(left:a1, this:a2, right:a3);
2409 let avg_4: u8 = avg3(left:a2, this:a3, right:a4);
2410
2411 let avg: [u8; 4] = [avg_1, avg_2, avg_3, avg_4];
2412
2413 let mut pos: usize = 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: u8 = topleft_pixel(a, x0, y0, stride);
2422 let (l0: u8, l1: u8, l2: u8, l3: u8) = left_pixels(a, x0, y0, stride);
2423
2424 let avgs: [u8; 4] = [
2425 avg3(left:p, this:l0, right:l1),
2426 avg3(left:l0, this:l1, right:l2),
2427 avg3(left:l1, this:l2, right:l3),
2428 avg3(left:l2, this:l3, right:l3),
2429 ];
2430
2431 let mut pos: usize = y0 * stride + x0;
2432 for &avg: u8 in avgs.iter() {
2433 for a_p: &mut u8 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: u8, a1: u8, a2: u8, a3: u8, a4: u8, a5: u8, a6: u8, a7: u8) = top_pixels(a, x0, y0, stride);
2442
2443 let avgs: [u8; 7] = [
2444 avg3(left:a0, this:a1, right:a2),
2445 avg3(left:a1, this:a2, right:a3),
2446 avg3(left:a2, this:a3, right:a4),
2447 avg3(left:a3, this:a4, right:a5),
2448 avg3(left:a4, this:a5, right:a6),
2449 avg3(left:a5, this:a6, right:a7),
2450 avg3(left:a6, this:a7, right:a7),
2451 ];
2452
2453 let mut pos: usize = y0 * stride + x0;
2454
2455 for i: usize 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: u8, e1: u8, e2: u8, e3: u8, e4: u8, e5: u8, e6: u8, e7: u8, e8: u8) = edge_pixels(a, x0, y0, stride);
2463
2464 let avgs: [u8; 7] = [
2465 avg3(left:e0, this:e1, right:e2),
2466 avg3(left:e1, this:e2, right:e3),
2467 avg3(left:e2, this:e3, right:e4),
2468 avg3(left:e3, this:e4, right:e5),
2469 avg3(left:e4, this:e5, right:e6),
2470 avg3(left:e5, this:e6, right:e7),
2471 avg3(left:e6, this:e7, right:e8),
2472 ];
2473 let mut pos: usize = y0 * stride + x0;
2474
2475 for i: usize 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: u8, e2: u8, e3: u8, e4: u8, e5: u8, e6: u8, e7: u8, e8: u8) = edge_pixels(a, x0, y0, stride);
2483
2484 a[(y0 + 3) * stride + x0] = avg3(left:e1, this:e2, right:e3);
2485 a[(y0 + 2) * stride + x0] = avg3(left:e2, this:e3, right:e4);
2486 a[(y0 + 3) * stride + x0 + 1] = avg3(left:e3, this:e4, right:e5);
2487 a[(y0 + 1) * stride + x0] = avg3(left:e3, this:e4, right:e5);
2488 a[(y0 + 2) * stride + x0 + 1] = avg2(this:e4, right:e5);
2489 a[y0 * stride + x0] = avg2(this:e4, right:e5);
2490 a[(y0 + 3) * stride + x0 + 2] = avg3(left:e4, this:e5, right:e6);
2491 a[(y0 + 1) * stride + x0 + 1] = avg3(left:e4, this:e5, right:e6);
2492 a[(y0 + 2) * stride + x0 + 2] = avg2(this:e5, right:e6);
2493 a[y0 * stride + x0 + 1] = avg2(this:e5, right:e6);
2494 a[(y0 + 3) * stride + x0 + 3] = avg3(left:e5, this:e6, right:e7);
2495 a[(y0 + 1) * stride + x0 + 2] = avg3(left:e5, this:e6, right:e7);
2496 a[(y0 + 2) * stride + x0 + 3] = avg2(this:e6, right:e7);
2497 a[y0 * stride + x0 + 2] = avg2(this:e6, right:e7);
2498 a[(y0 + 1) * stride + x0 + 3] = avg3(left:e6, this:e7, right:e8);
2499 a[y0 * stride + x0 + 3] = avg2(this:e7, right:e8);
2500}
2501
2502fn predict_bvlpred(a: &mut [u8], x0: usize, y0: usize, stride: usize) {
2503 let (a0: u8, a1: u8, a2: u8, a3: u8, a4: u8, a5: u8, a6: u8, a7: u8) = top_pixels(a, x0, y0, stride);
2504
2505 a[y0 * stride + x0] = avg2(this:a0, right:a1);
2506 a[(y0 + 1) * stride + x0] = avg3(left:a0, this:a1, right:a2);
2507 a[(y0 + 2) * stride + x0] = avg2(this:a1, right:a2);
2508 a[y0 * stride + x0 + 1] = avg2(this:a1, right:a2);
2509 a[(y0 + 1) * stride + x0 + 1] = avg3(left:a1, this:a2, right:a3);
2510 a[(y0 + 3) * stride + x0] = avg3(left:a1, this:a2, right:a3);
2511 a[(y0 + 2) * stride + x0 + 1] = avg2(this:a2, right:a3);
2512 a[y0 * stride + x0 + 2] = avg2(this:a2, right:a3);
2513 a[(y0 + 3) * stride + x0 + 1] = avg3(left:a2, this:a3, right:a4);
2514 a[(y0 + 1) * stride + x0 + 2] = avg3(left:a2, this:a3, right:a4);
2515 a[(y0 + 2) * stride + x0 + 2] = avg2(this:a3, right:a4);
2516 a[y0 * stride + x0 + 3] = avg2(this:a3, right:a4);
2517 a[(y0 + 3) * stride + x0 + 2] = avg3(left:a3, this:a4, right:a5);
2518 a[(y0 + 1) * stride + x0 + 3] = avg3(left:a3, this:a4, right:a5);
2519 a[(y0 + 2) * stride + x0 + 3] = avg3(left:a4, this:a5, right:a6);
2520 a[(y0 + 3) * stride + x0 + 3] = avg3(left:a5, this:a6, right:a7);
2521}
2522
2523fn predict_bhdpred(a: &mut [u8], x0: usize, y0: usize, stride: usize) {
2524 let (e0: u8, e1: u8, e2: u8, e3: u8, e4: u8, e5: u8, e6: u8, e7: u8, _) = edge_pixels(a, x0, y0, stride);
2525
2526 a[(y0 + 3) * stride + x0] = avg2(this:e0, right:e1);
2527 a[(y0 + 3) * stride + x0 + 1] = avg3(left:e0, this:e1, right:e2);
2528 a[(y0 + 2) * stride + x0] = avg2(this:e1, right:e2);
2529 a[(y0 + 3) * stride + x0 + 2] = avg2(this:e1, right:e2);
2530 a[(y0 + 2) * stride + x0 + 1] = avg3(left:e1, this:e2, right:e3);
2531 a[(y0 + 3) * stride + x0 + 3] = avg3(left:e1, this:e2, right:e3);
2532 a[(y0 + 2) * stride + x0 + 2] = avg2(this:e2, right:e3);
2533 a[(y0 + 1) * stride + x0] = avg2(this:e2, right:e3);
2534 a[(y0 + 2) * stride + x0 + 3] = avg3(left:e2, this:e3, right:e4);
2535 a[(y0 + 1) * stride + x0 + 1] = avg3(left:e2, this:e3, right:e4);
2536 a[(y0 + 1) * stride + x0 + 2] = avg2(this:e3, right:e4);
2537 a[y0 * stride + x0] = avg2(this:e3, right:e4);
2538 a[(y0 + 1) * stride + x0 + 3] = avg3(left:e3, this:e4, right:e5);
2539 a[y0 * stride + x0 + 1] = avg3(left:e3, this:e4, right:e5);
2540 a[y0 * stride + x0 + 2] = avg3(left:e4, this:e5, right:e6);
2541 a[y0 * stride + x0 + 3] = avg3(left:e5, this:e6, right:e7);
2542}
2543
2544fn predict_bhupred(a: &mut [u8], x0: usize, y0: usize, stride: usize) {
2545 let (l0: u8, l1: u8, l2: u8, l3: u8) = left_pixels(a, x0, y0, stride);
2546
2547 a[y0 * stride + x0] = avg2(this:l0, right:l1);
2548 a[y0 * stride + x0 + 1] = avg3(left:l0, this:l1, right:l2);
2549 a[y0 * stride + x0 + 2] = avg2(this:l1, right:l2);
2550 a[(y0 + 1) * stride + x0] = avg2(this:l1, right:l2);
2551 a[y0 * stride + x0 + 3] = avg3(left:l1, this:l2, right:l3);
2552 a[(y0 + 1) * stride + x0 + 1] = avg3(left:l1, this:l2, right:l3);
2553 a[(y0 + 1) * stride + x0 + 2] = avg2(this:l2, right:l3);
2554 a[(y0 + 2) * stride + x0] = avg2(this:l2, right:l3);
2555 a[(y0 + 1) * stride + x0 + 3] = avg3(left:l2, this:l3, right:l3);
2556 a[(y0 + 2) * stride + x0 + 1] = avg3(left:l2, this:l3, right: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}
2917