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