]>
Commit | Line | Data |
---|---|---|
55d85231 KS |
1 | use nihav_core::codecs::*; |
2 | use nihav_core::io::byteio::*; | |
3 | use nihav_core::io::bitreader::*; | |
4 | use nihav_core::io::codebook::*; | |
5 | use nihav_core::io::intcode::*; | |
6 | use std::str::FromStr; | |
7 | ||
8 | use std::ops::*; | |
9 | ||
10 | #[derive(Clone,Copy,Default,Debug,PartialEq)] | |
11 | struct MV { | |
12 | x: i8, | |
13 | y: i8, | |
14 | } | |
15 | ||
16 | impl Add for MV { | |
17 | type Output = MV; | |
18 | fn add(self, other: MV) -> MV { MV { x: self.x + other.x, y: self.y + other.y } } | |
19 | } | |
20 | ||
21 | impl AddAssign for MV { | |
22 | fn add_assign(&mut self, other: MV) { self.x += other.x; self.y += other.y; } | |
23 | } | |
24 | ||
25 | impl Sub for MV { | |
26 | type Output = MV; | |
27 | fn sub(self, other: MV) -> MV { MV { x: self.x - other.x, y: self.y - other.y } } | |
28 | } | |
29 | ||
30 | impl SubAssign for MV { | |
31 | fn sub_assign(&mut self, other: MV) { self.x -= other.x; self.y -= other.y; } | |
32 | } | |
33 | ||
34 | impl MV { | |
35 | fn pred(t: MV, tl: MV, l: MV) -> MV { | |
36 | let x0 = i16::from(t.x); | |
37 | let x1 = i16::from(tl.x); | |
38 | let x2 = i16::from(l.x); | |
39 | let y0 = i16::from(t.y); | |
40 | let y1 = i16::from(tl.y); | |
41 | let y2 = i16::from(l.y); | |
42 | let x = x0 + x1 + x2 - x0.min(x1).min(x2) - x0.max(x1).max(x2); | |
43 | let y = y0 + y1 + y2 - y0.min(y1).min(y2) - y0.max(y1).max(y2); | |
44 | MV{ x: x as i8, y: y as i8 } | |
45 | } | |
46 | } | |
47 | ||
48 | trait ReadCodes { | |
49 | fn read_gammap(&mut self) -> BitReaderResult<u32>; | |
50 | fn read_gammap_s(&mut self) -> BitReaderResult<i32>; | |
51 | fn read_unary(&mut self) -> BitReaderResult<u32>; | |
52 | } | |
53 | ||
54 | impl<'a> ReadCodes for BitReader<'a> { | |
55 | fn read_gammap(&mut self) -> BitReaderResult<u32> { | |
56 | Ok(self.read_code(UintCodeType::GammaP)? - 1) | |
57 | } | |
58 | fn read_gammap_s(&mut self) -> BitReaderResult<i32> { | |
59 | let val = self.read_code(UintCodeType::GammaP)?; | |
60 | if (val & 1) == 0 { | |
61 | Ok((val >> 1) as i32) | |
62 | } else { | |
63 | Ok((1 - (val as i32)) >> 1) | |
64 | } | |
65 | } | |
66 | fn read_unary(&mut self) -> BitReaderResult<u32> { | |
67 | self.read_code(UintCodeType::UnaryZeroes) | |
68 | } | |
69 | } | |
70 | ||
71 | const CUR_BUF: usize = 3; | |
72 | const CHROMA_OFF: usize = 256 * 256; | |
73 | ||
74 | macro_rules! mc { | |
75 | ($bufs: expr, $src_id: expr, $dst_id: expr, $mx: expr, $my: expr, $xpos: expr, $ypos: expr, $w: expr, $h: expr, $ydelta: expr, $udelta: expr, $vdelta: expr, $width: expr, $height: expr) => { | |
76 | if ($mx + ($xpos as isize) < 0) || ($mx + (($xpos + $w) as isize) > ($width as isize)) { | |
77 | return Err(DecoderError::InvalidData); | |
78 | } | |
79 | if ($my + ($ypos as isize) < 0) || ($my + (($ypos + $h) as isize) > ($height as isize)) { | |
80 | return Err(DecoderError::InvalidData); | |
81 | } | |
82 | ||
83 | let sx = (($xpos as isize) + $mx) as usize; | |
84 | let sy = (($ypos as isize) + $my) as usize; | |
85 | ||
86 | let mut soff = sx + sy * 256; | |
87 | let mut doff = $xpos + $ypos * 256; | |
88 | for _y in 0..$h { | |
89 | for x in 0..$w { | |
90 | $bufs[$dst_id][doff + x] = (i32::from($bufs[$src_id][soff + x]) + $ydelta).max(0).min(255) as u8; | |
91 | } | |
92 | soff += 256; | |
93 | doff += 256; | |
94 | } | |
95 | let mut soff = CHROMA_OFF + sx / 2 + (sy / 2) * 256; | |
96 | let mut doff = CHROMA_OFF + $xpos / 2 + $ypos / 2 * 256; | |
97 | for _y in 0..$h / 2 { | |
98 | for x in 0..$w / 2 { | |
99 | $bufs[$dst_id][doff + x] = (i32::from($bufs[$src_id][soff + x]) + $udelta).max(0).min(255) as u8; | |
100 | $bufs[$dst_id][doff + x + 128] = (i32::from($bufs[$src_id][soff + x + 128]) + $vdelta).max(0).min(255) as u8; | |
101 | } | |
102 | soff += 256; | |
103 | doff += 256; | |
104 | } | |
105 | } | |
106 | } | |
107 | ||
108 | fn pred_dc(buf: &mut [u8], mut pos: usize, x: usize, y: usize, w: usize, h: usize) { | |
109 | let dc = if x == 0 && y == 0 { | |
110 | 128 | |
111 | } else if y == 0 { | |
112 | let mut sum = 0; | |
113 | let hh = h as u16; | |
114 | for i in 0..h { | |
115 | sum += u16::from(buf[pos - 1 + i * 256]); | |
116 | } | |
117 | ((sum + hh / 2) / hh) as u8 | |
118 | } else if x == 0 { | |
119 | let mut sum = 0; | |
120 | let ww = w as u16; | |
121 | for i in 0..w { | |
122 | sum += u16::from(buf[pos - 256 + i]); | |
123 | } | |
124 | ((sum + ww / 2) / ww) as u8 | |
125 | } else { | |
126 | let mut sum = 0; | |
127 | let ww = w as u16; | |
128 | for i in 0..w { | |
129 | sum += u16::from(buf[pos - 256 + i]); | |
130 | } | |
131 | let wdc = (sum + ww / 2) / ww; | |
132 | ||
133 | let mut sum = 0; | |
134 | let hh = h as u16; | |
135 | for i in 0..h { | |
136 | sum += u16::from(buf[pos - 1 + i * 256]); | |
137 | } | |
138 | let hdc = (sum + hh / 2) / hh; | |
139 | ||
140 | ((wdc + hdc + 1) >> 1) as u8 | |
141 | }; | |
142 | for _ in 0..h { | |
143 | for x in 0..w { | |
144 | buf[pos + x] = dc; | |
145 | } | |
146 | pos += 256; | |
147 | } | |
148 | } | |
149 | fn pred_dc4x4(buf: &mut [u8], mut pos: usize, x: usize, y: usize) { | |
150 | if x == 0 && y == 0 { | |
151 | for _ in 0..4 { | |
152 | for x in 0..4 { | |
153 | buf[x] = 0x80; | |
154 | } | |
155 | pos += 256; | |
156 | } | |
157 | return; | |
158 | } | |
159 | let mut sum = 0; | |
160 | let mut shift = 1; | |
161 | if y != 0 { | |
162 | for i in 0..4 { | |
163 | sum += u16::from(buf[pos - 256 + i]); | |
164 | } | |
165 | sum += 2; | |
166 | shift += 1; | |
167 | } | |
168 | if x != 0 { | |
169 | for i in 0..4 { | |
170 | sum += u16::from(buf[pos + i * 256 - 1]); | |
171 | } | |
172 | sum += 2; | |
173 | shift += 1; | |
174 | } | |
175 | let dc = (sum >> shift) as u8; | |
176 | for _ in 0..4 { | |
177 | for x in 0..4 { | |
178 | buf[pos + x] = dc; | |
179 | } | |
180 | pos += 256; | |
181 | } | |
182 | } | |
183 | ||
184 | fn pred_hor(buf: &mut [u8], mut pos: usize, w: usize, h: usize) { | |
185 | for _ in 0..h { | |
186 | for x in 0..w { | |
187 | buf[pos + x] = buf[pos - 1]; | |
188 | } | |
189 | pos += 256; | |
190 | } | |
191 | } | |
192 | ||
193 | fn pred_ver(buf: &mut [u8], mut pos: usize, w: usize, h: usize) { | |
194 | for _ in 0..h { | |
195 | for x in 0..w { | |
196 | buf[pos + x] = buf[pos + x - 256]; | |
197 | } | |
198 | pos += 256; | |
199 | } | |
200 | } | |
201 | ||
202 | fn avg(a: u8, b: u8) -> u8 { | |
203 | ((u16::from(a) + u16::from(b) + 1) >> 1) as u8 | |
204 | } | |
205 | fn avg_nr(a: u8, b: u8) -> u8 { | |
206 | ((u16::from(a) + u16::from(b)) >> 1) as u8 | |
207 | } | |
208 | fn interp2(a: u8, b: u8, c: u8) -> u8 { | |
209 | ((u16::from(a) + 2 * u16::from(b) + u16::from(c) + 2) >> 2) as u8 | |
210 | } | |
211 | ||
212 | fn pred_ddown_left(blk: &mut [u8], pos: usize) { | |
213 | let (t0, t1, t2, t3) = (blk[pos - 256], blk[pos - 256 + 1], blk[pos - 256 + 2], blk[pos - 256 + 3]); | |
214 | let (t4, t5, t6, t7) = (blk[pos - 256 + 4], blk[pos - 256 + 5], blk[pos - 256 + 6], blk[pos - 256 + 7]); | |
215 | ||
216 | blk[pos + 0 + 0 * 256] = interp2(t0, t1, t2); | |
217 | let pix = interp2(t1, t2, t3); | |
218 | blk[pos + 1 + 0 * 256] = pix; | |
219 | blk[pos + 0 + 1 * 256] = pix; | |
220 | let pix = interp2(t2, t3, t4); | |
221 | blk[pos + 2 + 0 * 256] = pix; | |
222 | blk[pos + 1 + 1 * 256] = pix; | |
223 | blk[pos + 0 + 2 * 256] = pix; | |
224 | let pix = interp2(t3, t4, t5); | |
225 | blk[pos + 3 + 0 * 256] = pix; | |
226 | blk[pos + 2 + 1 * 256] = pix; | |
227 | blk[pos + 1 + 2 * 256] = pix; | |
228 | blk[pos + 0 + 3 * 256] = pix; | |
229 | let pix = interp2(t4, t5, t6); | |
230 | blk[pos + 3 + 1 * 256] = pix; | |
231 | blk[pos + 2 + 2 * 256] = pix; | |
232 | blk[pos + 1 + 3 * 256] = pix; | |
233 | let pix = interp2(t5, t6, t7); | |
234 | blk[pos + 3 + 2 * 256] = pix; | |
235 | blk[pos + 2 + 3 * 256] = pix; | |
236 | blk[pos + 3 + 3 * 256] = interp2(t6, t7, t7); | |
237 | } | |
238 | fn pred_ddown_right(blk: &mut [u8], pos: usize) { | |
239 | let (l0, l1, l2, l3) = (blk[pos - 1], blk[pos + 256 - 1], blk[pos + 256 * 2 - 1], blk[pos + 256 * 3 - 1]); | |
240 | let (tl, t0, t1, t2) = (blk[pos - 256 - 1], blk[pos - 256], blk[pos - 256 + 1], blk[pos - 256 + 2]); | |
241 | let t3 = blk[pos - 256 + 3]; | |
242 | ||
243 | blk[pos + 0 + 3 * 256] = interp2(l1, l2, l3); | |
244 | let pix = interp2(l0, l1, l2); | |
245 | blk[pos + 0 + 2 * 256] = pix; | |
246 | blk[pos + 1 + 3 * 256] = pix; | |
247 | let pix = interp2(tl, l0, l1); | |
248 | blk[pos + 0 + 1 * 256] = pix; | |
249 | blk[pos + 1 + 2 * 256] = pix; | |
250 | blk[pos + 2 + 3 * 256] = pix; | |
251 | let pix = interp2(l0, tl, t0); | |
252 | blk[pos + 0 + 0 * 256] = pix; | |
253 | blk[pos + 1 + 1 * 256] = pix; | |
254 | blk[pos + 2 + 2 * 256] = pix; | |
255 | blk[pos + 3 + 3 * 256] = pix; | |
256 | let pix = interp2(tl, t0, t1); | |
257 | blk[pos + 1 + 0 * 256] = pix; | |
258 | blk[pos + 2 + 1 * 256] = pix; | |
259 | blk[pos + 3 + 2 * 256] = pix; | |
260 | let pix = interp2(t0, t1, t2); | |
261 | blk[pos + 2 + 0 * 256] = pix; | |
262 | blk[pos + 3 + 1 * 256] = pix; | |
263 | blk[pos + 3 + 0 * 256] = interp2(t1, t2, t3); | |
264 | } | |
265 | fn pred_ver_right(blk: &mut [u8], pos: usize) { | |
266 | let (l0, l1, l2) = (blk[pos - 1], blk[pos + 256 - 1], blk[pos + 256 * 2 - 1]); | |
267 | let (tl, t0, t1, t2, t3) = (blk[pos - 256 - 1], blk[pos - 256], blk[pos - 256 + 1], blk[pos - 256 + 2], blk[pos - 256 + 3]); | |
268 | ||
269 | blk[pos + 0 + 3 * 256] = interp2(l0, l1, l2); | |
270 | blk[pos + 0 + 2 * 256] = interp2(tl, l0, l1); | |
271 | let pix = interp2(l0, tl, t0); | |
272 | blk[pos + 0 + 1 * 256] = pix; | |
273 | blk[pos + 1 + 3 * 256] = pix; | |
274 | let pix = avg(tl, t0); | |
275 | blk[pos + 0 + 0 * 256] = pix; | |
276 | blk[pos + 1 + 2 * 256] = pix; | |
277 | let pix = interp2(tl, t0, t1); | |
278 | blk[pos + 1 + 1 * 256] = pix; | |
279 | blk[pos + 2 + 3 * 256] = pix; | |
280 | let pix = avg(t0, t1); | |
281 | blk[pos + 1 + 0 * 256] = pix; | |
282 | blk[pos + 2 + 2 * 256] = pix; | |
283 | let pix = interp2(t0, t1, t2); | |
284 | blk[pos + 2 + 1 * 256] = pix; | |
285 | blk[pos + 3 + 3 * 256] = pix; | |
286 | let pix = avg(t1, t2); | |
287 | blk[pos + 2 + 0 * 256] = pix; | |
288 | blk[pos + 3 + 2 * 256] = pix; | |
289 | blk[pos + 3 + 1 * 256] = interp2(t1, t2, t3); | |
290 | blk[pos + 3 + 0 * 256] = avg(t2, t3); | |
291 | } | |
292 | fn pred_hor_down(blk: &mut [u8], pos: usize) { | |
293 | let (l0, l1, l2, l3) = (blk[pos - 1], blk[pos + 256 - 1], blk[pos + 256 * 2 - 1], blk[pos + 256 * 3 - 1]); | |
294 | let (tl, t0, t1, t2) = (blk[pos - 256 - 1], blk[pos - 256], blk[pos - 256 + 1], blk[pos - 256 + 2]); | |
295 | ||
296 | blk[pos + 0 + 3 * 256] = avg(l2, l3); | |
297 | blk[pos + 1 + 3 * 256] = interp2(l1, l2, l3); | |
298 | let pix = avg(l1, l2); | |
299 | blk[pos + 0 + 2 * 256] = pix; | |
300 | blk[pos + 2 + 3 * 256] = pix; | |
301 | let pix = interp2(l0, l1, l2); | |
302 | blk[pos + 1 + 2 * 256] = pix; | |
303 | blk[pos + 3 + 3 * 256] = pix; | |
304 | let pix = avg(l0, l1); | |
305 | blk[pos + 0 + 1 * 256] = pix; | |
306 | blk[pos + 2 + 2 * 256] = pix; | |
21e827ed | 307 | let pix = interp2(tl, l0, l1); |
55d85231 KS |
308 | blk[pos + 1 + 1 * 256] = pix; |
309 | blk[pos + 3 + 2 * 256] = pix; | |
310 | let pix = avg(tl, l0); | |
311 | blk[pos + 0 + 0 * 256] = pix; | |
312 | blk[pos + 2 + 1 * 256] = pix; | |
313 | let pix = interp2(l0, tl, t0); | |
314 | blk[pos + 1 + 0 * 256] = pix; | |
315 | blk[pos + 3 + 1 * 256] = pix; | |
316 | blk[pos + 2 + 0 * 256] = interp2(tl, t0, t1); | |
317 | blk[pos + 3 + 0 * 256] = interp2(t0, t1, t2); | |
318 | } | |
319 | fn pred_ver_left(blk: &mut [u8], pos: usize) { | |
320 | let (t0, t1, t2, t3) = (blk[pos - 256], blk[pos - 256 + 1], blk[pos - 256 + 2], blk[pos - 256 + 3]); | |
321 | let (t4, t5, t6) = (blk[pos - 256 + 4], blk[pos - 256 + 5], blk[pos - 256 + 6]); | |
322 | ||
323 | blk[pos + 3 + 3 * 256] = interp2(t4, t5, t6); | |
324 | blk[pos + 3 + 2 * 256] = avg(t4, t5); | |
325 | let pix = interp2(t3, t4, t5); | |
326 | blk[pos + 3 + 1 * 256] = pix; | |
327 | blk[pos + 2 + 3 * 256] = pix; | |
328 | let pix = avg(t3, t4); | |
329 | blk[pos + 3 + 0 * 256] = pix; | |
330 | blk[pos + 2 + 2 * 256] = pix; | |
331 | let pix = interp2(t2, t3, t4); | |
332 | blk[pos + 2 + 1 * 256] = pix; | |
333 | blk[pos + 1 + 3 * 256] = pix; | |
334 | let pix = avg(t2, t3); | |
335 | blk[pos + 2 + 0 * 256] = pix; | |
336 | blk[pos + 1 + 2 * 256] = pix; | |
337 | let pix = interp2(t1, t2, t3); | |
338 | blk[pos + 1 + 1 * 256] = pix; | |
339 | blk[pos + 0 + 3 * 256] = pix; | |
340 | let pix = avg(t1, t2); | |
341 | blk[pos + 1 + 0 * 256] = pix; | |
342 | blk[pos + 0 + 2 * 256] = pix; | |
343 | blk[pos + 0 + 1 * 256] = interp2(t0, t1, t2); | |
344 | blk[pos + 0 + 0 * 256] = avg(t0, t1); | |
345 | } | |
346 | fn pred_hor_up(blk: &mut [u8], pos: usize) { | |
347 | let (l0, l1, l2, l3) = (blk[pos - 1], blk[pos + 256 - 1], blk[pos + 256 * 2 - 1], blk[pos + 256 * 3 - 1]); | |
348 | ||
349 | blk[pos + 0 + 0 * 256] = avg(l0, l1); | |
350 | blk[pos + 1 + 0 * 256] = interp2(l0, l1, l2); | |
351 | let pix = avg(l1, l2); | |
352 | blk[pos + 2 + 0 * 256] = pix; | |
353 | blk[pos + 0 + 1 * 256] = pix; | |
354 | let pix = interp2(l1, l2, l3); | |
355 | blk[pos + 3 + 0 * 256] = pix; | |
356 | blk[pos + 1 + 1 * 256] = pix; | |
357 | let pix = avg(l2, l3); | |
358 | blk[pos + 2 + 1 * 256] = pix; | |
359 | blk[pos + 0 + 2 * 256] = pix; | |
360 | let pix = interp2(l2, l3, l3); | |
361 | blk[pos + 3 + 1 * 256] = pix; | |
362 | blk[pos + 1 + 2 * 256] = pix; | |
363 | blk[pos + 0 + 3 * 256] = l3; | |
364 | blk[pos + 2 + 2 * 256] = l3; | |
365 | blk[pos + 3 + 2 * 256] = l3; | |
366 | blk[pos + 1 + 3 * 256] = l3; | |
367 | blk[pos + 2 + 3 * 256] = l3; | |
368 | blk[pos + 3 + 3 * 256] = l3; | |
369 | } | |
370 | ||
371 | fn pred_plane(blk: &mut [u8], pos: usize, w: usize, h: usize) { | |
372 | if w == 1 && h == 1 { | |
373 | return; | |
374 | } | |
375 | if h == 1 { | |
376 | blk[pos + w / 2 - 1] = avg_nr(blk[pos - 1], blk[pos + w - 1]); | |
377 | if w > 2 { | |
378 | pred_plane(blk, pos, w / 2, 1); | |
379 | pred_plane(blk, pos + w / 2, w / 2, 1); | |
380 | } | |
381 | return; | |
382 | } | |
383 | if w == 1 { | |
384 | blk[pos + (h / 2 - 1) * 256] = avg_nr(blk[pos - 256], blk[pos + (h - 1) * 256]); | |
385 | if h > 2 { | |
386 | pred_plane(blk, pos, 1, h / 2); | |
387 | pred_plane(blk, pos + (h / 2) * 256, 1, h / 2); | |
388 | } | |
389 | return; | |
390 | } | |
391 | ||
392 | let is_even_block = ((w.trailing_zeros() + h.trailing_zeros()) & 1) == 0; // i.e. w*h = 256/64/16/4 | |
393 | ||
394 | let hoff = (h - 1) * 256; | |
395 | let h2off = (h / 2 - 1) * 256; | |
396 | let woff = w - 1; | |
397 | let w2off = w / 2 - 1; | |
398 | let dr = blk[pos + woff + hoff]; | |
399 | let tr = blk[pos + woff - 256]; | |
400 | let dl = blk[pos - 1 + hoff]; | |
401 | ||
402 | let dm = avg_nr(dl, dr); | |
403 | blk[pos + w2off + hoff] = dm; | |
404 | blk[pos + woff + h2off] = avg_nr(tr, dr); | |
16fe22c3 KS |
405 | let (val1, val2) = if is_even_block { |
406 | (dm, blk[pos + w2off - 256]) | |
407 | } else { | |
408 | (blk[pos + woff + h2off], blk[pos - 1 + h2off]) | |
409 | }; | |
410 | blk[pos + w2off + h2off] = avg_nr(val1, val2); | |
55d85231 KS |
411 | |
412 | let hw = w / 2; | |
413 | let hh = h / 2; | |
414 | pred_plane(blk, pos, hw, hh); | |
415 | pred_plane(blk, pos + hw, hw, hh); | |
416 | pred_plane(blk, pos + hh * 256, hw, hh); | |
417 | pred_plane(blk, pos + hw + hh * 256, hw, hh); | |
418 | } | |
419 | fn pred_plane_delta(blk: &mut [u8], pos: usize, w: usize, h: usize, delta: i32) { | |
420 | let tr = blk[pos + w - 1 - 256]; | |
421 | let dl = blk[pos + 256 * (h - 1) - 1]; | |
16fe22c3 | 422 | let pred = avg(tr, dl).wrapping_add(delta as u8); |
55d85231 KS |
423 | blk[pos + 256 * (h - 1) + w - 1] = pred; |
424 | pred_plane(blk, pos, w, h); | |
425 | } | |
426 | ||
427 | struct Codebooks { | |
428 | nc_cb: [Codebook<u8>; 3], | |
429 | num_zero_cb: [Codebook<u8>; 15], | |
430 | zero_run_cb: [Codebook<u8>; 6], | |
431 | } | |
432 | ||
433 | fn map_idx(idx: usize) -> u8 { idx as u8 } | |
434 | macro_rules! create_cb { | |
435 | ($bits_tab: expr, $lens_tab: expr) => {{ | |
436 | let mut cbr = TableCodebookDescReader::new($bits_tab, $lens_tab, map_idx); | |
437 | Codebook::new(&mut cbr, CodebookMode::MSB).unwrap() | |
438 | }} | |
439 | } | |
440 | ||
441 | impl Codebooks { | |
442 | fn new() -> Self { | |
443 | let nc_cb0 = create_cb!(&NC_BITS[0], &NC_LENS[0]); | |
444 | let nc_cb1 = create_cb!(&NC_BITS[1], &NC_LENS[1]); | |
445 | let nc_cb2 = create_cb!(&NC_BITS[2], &NC_LENS[2]); | |
446 | ||
447 | let nz0 = create_cb!(&NUM_ZERO_BITS[ 0], &NUM_ZERO_LENS[ 0]); | |
448 | let nz1 = create_cb!(&NUM_ZERO_BITS[ 1], &NUM_ZERO_LENS[ 1]); | |
449 | let nz2 = create_cb!(&NUM_ZERO_BITS[ 2], &NUM_ZERO_LENS[ 2]); | |
450 | let nz3 = create_cb!(&NUM_ZERO_BITS[ 3], &NUM_ZERO_LENS[ 3]); | |
451 | let nz4 = create_cb!(&NUM_ZERO_BITS[ 4], &NUM_ZERO_LENS[ 4]); | |
452 | let nz5 = create_cb!(&NUM_ZERO_BITS[ 5], &NUM_ZERO_LENS[ 5]); | |
453 | let nz6 = create_cb!(&NUM_ZERO_BITS[ 6], &NUM_ZERO_LENS[ 6]); | |
454 | let nz7 = create_cb!(&NUM_ZERO_BITS[ 7], &NUM_ZERO_LENS[ 7]); | |
455 | let nz8 = create_cb!(&NUM_ZERO_BITS[ 8], &NUM_ZERO_LENS[ 8]); | |
456 | let nz9 = create_cb!(&NUM_ZERO_BITS[ 9], &NUM_ZERO_LENS[ 9]); | |
457 | let nz10 = create_cb!(&NUM_ZERO_BITS[10], &NUM_ZERO_LENS[10]); | |
458 | let nz11 = create_cb!(&NUM_ZERO_BITS[11], &NUM_ZERO_LENS[11]); | |
459 | let nz12 = create_cb!(&NUM_ZERO_BITS[12], &NUM_ZERO_LENS[12]); | |
460 | let nz13 = create_cb!(&NUM_ZERO_BITS[13], &NUM_ZERO_LENS[13]); | |
461 | let nz14 = create_cb!(&NUM_ZERO_BITS[14], &NUM_ZERO_LENS[14]); | |
462 | ||
463 | let zcb0 = create_cb!(&ZERO_RUN_BITS[0], &ZERO_RUN_LENS[0]); | |
464 | let zcb1 = create_cb!(&ZERO_RUN_BITS[1], &ZERO_RUN_LENS[1]); | |
465 | let zcb2 = create_cb!(&ZERO_RUN_BITS[2], &ZERO_RUN_LENS[2]); | |
466 | let zcb3 = create_cb!(&ZERO_RUN_BITS[3], &ZERO_RUN_LENS[3]); | |
467 | let zcb4 = create_cb!(&ZERO_RUN_BITS[4], &ZERO_RUN_LENS[4]); | |
468 | let zcb5 = create_cb!(&ZERO_RUN_BITS[5], &ZERO_RUN_LENS[5]); | |
469 | Self { | |
470 | nc_cb: [nc_cb0, nc_cb1, nc_cb2], | |
471 | num_zero_cb: [nz0, nz1, nz2, nz3, nz4, nz5, nz6, nz7, nz8, nz9, nz10, nz11, nz12, nz13, nz14], | |
472 | zero_run_cb: [zcb0, zcb1, zcb2, zcb3, zcb4, zcb5], | |
473 | } | |
474 | } | |
475 | } | |
476 | ||
477 | macro_rules! transform { | |
478 | ($a: expr, $b: expr, $c: expr, $d: expr, $q0: expr, $q1: expr) => { | |
479 | let t0 = ($a + $c).wrapping_mul($q0); | |
480 | let t1 = ($a - $c).wrapping_mul($q0); | |
481 | let tb = $b.wrapping_mul($q1); | |
482 | let td = $d.wrapping_mul($q1); | |
483 | let t2 = tb + (td >> 1); | |
484 | let t3 = (tb >> 1) - td; | |
485 | $a = t0 + t2; | |
486 | $b = t1 + t3; | |
487 | $c = t1 - t3; | |
488 | $d = t0 - t2; | |
489 | } | |
490 | } | |
491 | ||
492 | fn idct_add(qmat: &[i32; 8], blk: &mut [i32; 16], dst: &mut [u8]) { | |
493 | for i in 0..4 { | |
494 | transform!(blk[i + 0 * 4], blk[i + 1 * 4], blk[i + 2 * 4], blk[i + 3 * 4], qmat[i], qmat[i + 4]); | |
495 | } | |
496 | for (dline, row) in dst.chunks_mut(256).zip(blk.chunks_mut(4)) { | |
497 | transform!(row[0], row[1], row[2], row[3], 1, 1); | |
498 | for (out, coef) in dline.iter_mut().zip(row.iter_mut()) { | |
499 | *out = (i32::from(*out) + ((*coef + 0x20) >> 6)).max(0).min(255) as u8; | |
500 | } | |
501 | } | |
502 | } | |
503 | ||
504 | fn decode_coeffs(br: &mut BitReader, codebooks: &Codebooks, qmat: &[i32; 8], ctx: u8, dst: &mut [u8]) -> DecoderResult<u8> { | |
505 | const ZIGZAG: [usize; 16] = [ | |
506 | 0, 1, 4, 8, | |
507 | 5, 2, 3, 6, | |
508 | 9, 12, 13, 10, | |
509 | 7, 11, 14, 15 | |
510 | ]; | |
511 | const MAX_LEVEL: [i32; 6] = [ 2, 5, 11, 23, 47, 0x8000 ]; | |
512 | ||
513 | let (ncoeffs, nones) = if ctx < 8 { | |
514 | let sym = br.read_cb(&codebooks.nc_cb[NC_MAP[ctx as usize]])?; | |
515 | if sym == 0 { | |
516 | return Ok(0); | |
517 | } | |
518 | (sym >> 2, sym & 3) | |
519 | } else { | |
520 | let ncoeffs = (br.read(4)? + 1) as u8; | |
521 | let nones = br.read(2)? as u8; | |
522 | if ncoeffs < nones { | |
523 | return Ok(0); | |
524 | } | |
525 | (ncoeffs, nones) | |
526 | }; | |
527 | let mut num_zero = if ncoeffs == 16 { 0 } else { | |
528 | br.read_cb(&codebooks.num_zero_cb[ncoeffs as usize - 1])? | |
529 | }; | |
530 | validate!(ncoeffs + num_zero <= 16); | |
531 | let mut blk = [0i32; 16]; | |
532 | let mut level = 0usize; | |
533 | let mut coef_left = ncoeffs; | |
534 | let mut ones_left = nones; | |
535 | let mut idx = ncoeffs + num_zero; | |
536 | while coef_left > 0 { | |
537 | let val = if ones_left > 0 { | |
538 | ones_left -= 1; | |
539 | if !br.read_bool()? { 1 } else { -1 } | |
540 | } else { | |
541 | let prefix = br.read_unary()?; | |
542 | let val = if prefix < 15 { | |
543 | (br.read(level as u8)? | (prefix << level)) as i32 | |
544 | } else { | |
545 | (br.read(11)? + (15 << level)) as i32 | |
546 | }; | |
547 | if val > MAX_LEVEL[level] { | |
548 | level += 1; | |
549 | } | |
550 | if !br.read_bool()? { | |
551 | val + 1 | |
552 | } else { | |
553 | -(val + 1) | |
554 | } | |
555 | }; | |
556 | idx -= 1; | |
557 | blk[ZIGZAG[idx as usize]] = val; | |
558 | coef_left -= 1; | |
559 | if num_zero > 0 && coef_left > 0 { | |
560 | let run = if num_zero < 7 { | |
561 | br.read_cb(&codebooks.zero_run_cb[num_zero as usize - 1])? | |
562 | } else { | |
563 | if br.peek(3) != 0 { | |
564 | 7 - (br.read(3)? as u8) | |
565 | } else { | |
566 | (br.read_unary()? as u8) + 4 | |
567 | } | |
568 | }; | |
569 | validate!(run <= num_zero); | |
570 | idx -= run; | |
571 | num_zero -= run; | |
572 | } | |
573 | } | |
574 | idct_add(qmat, &mut blk, dst); | |
575 | Ok(ncoeffs) | |
576 | } | |
577 | ||
578 | const NCSTRIDE: usize = 64 + 1; | |
579 | ||
580 | struct VXVideoDecoder { | |
581 | info: NACodecInfoRef, | |
582 | width: usize, | |
583 | height: usize, | |
584 | buf: [[u8; 256 * 392]; 4], // layout is luma with stride 256 and at 256*256 chroma lines with two components starting at positions 0 and 128 and stride 256 | |
585 | refs: [usize; 4], | |
586 | ipred4x4: [u8; 25], | |
587 | y_ncoeffs: [u8; NCSTRIDE * (256 / 4 + 1)], | |
588 | c_ncoeffs: [u8; NCSTRIDE * (256 / 8 + 1)], | |
589 | mvs: [MV; 16 * 16], | |
590 | pred_mv: MV, | |
591 | cur_mv: MV, | |
592 | qmat: [i32; 8], | |
593 | codebooks: Codebooks, | |
594 | } | |
595 | ||
596 | impl VXVideoDecoder { | |
597 | fn new() -> Self { | |
598 | Self { | |
599 | info: NACodecInfoRef::default(), | |
600 | buf: [[0x80; 256 * 392]; 4], | |
601 | width: 0, | |
602 | height: 0, | |
603 | refs: [0, 1, 2, 3], | |
604 | ipred4x4: [9; 25], | |
605 | y_ncoeffs: [0; NCSTRIDE * (256 / 4 + 1)], | |
606 | c_ncoeffs: [0; NCSTRIDE * (256 / 8 + 1)], | |
607 | mvs: [MV::default(); 16 * 16], | |
608 | cur_mv: MV::default(), | |
609 | pred_mv: MV::default(), | |
610 | qmat: [0; 8], | |
611 | codebooks: Codebooks::new(), | |
612 | } | |
613 | } | |
614 | fn update_refs(&mut self) { | |
615 | for el in self.refs.iter_mut() { | |
616 | *el = (*el + 3) & 3; | |
617 | } | |
618 | } | |
619 | fn decode_frame(&mut self, br: &mut BitReader) -> DecoderResult<()> { | |
620 | let mut mv_pos = 18; | |
621 | for ypos in (0..self.height).step_by(16) { | |
622 | for xpos in (0..self.width).step_by(16) { | |
623 | let left_mv = self.mvs[mv_pos - 1]; | |
624 | let top_mv = self.mvs[mv_pos - 17]; | |
625 | let tl_mv = self.mvs[mv_pos - 18]; | |
626 | self.pred_mv = MV::pred(top_mv, tl_mv, left_mv); | |
627 | self.cur_mv = MV::default(); | |
628 | self.decode_block(br, xpos, ypos, 16, 16)?; | |
629 | self.mvs[mv_pos] = self.cur_mv; | |
630 | mv_pos += 1; | |
631 | } | |
632 | mv_pos -= self.width / 16; | |
633 | mv_pos += 18; | |
634 | } | |
635 | Ok(()) | |
636 | } | |
637 | fn copy_block(&mut self, xpos: usize, ypos: usize, w: usize, h: usize, ref_buf: usize) -> DecoderResult<()> { | |
638 | let src = self.refs[ref_buf]; | |
639 | let dst = self.refs[CUR_BUF]; | |
640 | self.cur_mv = self.pred_mv; | |
641 | let mx = self.pred_mv.x as isize; | |
642 | let my = self.pred_mv.y as isize; | |
643 | mc!(self.buf, src, dst, mx, my, xpos, ypos, w, h, 0, 0, 0, self.width, self.height); | |
644 | Ok(()) | |
645 | } | |
646 | fn do_mc(&mut self, br: &mut BitReader, xpos: usize, ypos: usize, w: usize, h: usize, ref_buf: usize) -> DecoderResult<()> { | |
647 | let src = self.refs[ref_buf]; | |
648 | let dst = self.refs[CUR_BUF]; | |
649 | let dx = br.read_gammap_s()? as i8; | |
650 | let dy = br.read_gammap_s()? as i8; | |
651 | self.cur_mv = self.pred_mv + MV { x: dx, y: dy }; | |
652 | let mx = self.cur_mv.x as isize; | |
653 | let my = self.cur_mv.y as isize; | |
654 | mc!(self.buf, src, dst, mx, my, xpos, ypos, w, h, 0, 0, 0, self.width, self.height); | |
4d6935ba | 655 | |
55d85231 KS |
656 | Ok(()) |
657 | } | |
658 | fn do_mc_bias(&mut self, br: &mut BitReader, xpos: usize, ypos: usize, w: usize, h: usize) -> DecoderResult<()> { | |
659 | let src = self.refs[0]; | |
660 | let dst = self.refs[CUR_BUF]; | |
661 | let mx = br.read_gammap_s()? as isize; | |
662 | let my = br.read_gammap_s()? as isize; | |
663 | let ydelta = br.read_gammap_s()? * 2; | |
664 | let udelta = br.read_gammap_s()? * 2; | |
665 | let vdelta = br.read_gammap_s()? * 2; | |
666 | mc!(self.buf, src, dst, mx, my, xpos, ypos, w, h, ydelta, udelta, vdelta, self.width, self.height); | |
4d6935ba | 667 | |
55d85231 KS |
668 | Ok(()) |
669 | } | |
670 | fn pred_plane(&mut self, br: &mut BitReader, xpos: usize, ypos: usize, w: usize, h: usize) -> DecoderResult<()> { | |
671 | let ydelta = br.read_gammap_s()? * 2; | |
672 | let udelta = br.read_gammap_s()? * 2; | |
673 | let vdelta = br.read_gammap_s()? * 2; | |
674 | let yoff = xpos + ypos * 256; | |
675 | let coff = CHROMA_OFF + xpos / 2 + ypos / 2 * 256; | |
676 | pred_plane_delta(&mut self.buf[self.refs[CUR_BUF]], yoff, w, h, ydelta); | |
677 | pred_plane_delta(&mut self.buf[self.refs[CUR_BUF]], coff, w / 2, h / 2, udelta); | |
678 | pred_plane_delta(&mut self.buf[self.refs[CUR_BUF]], coff + 128, w / 2, h / 2, vdelta); | |
679 | Ok(()) | |
680 | } | |
681 | fn intra_pred(&mut self, br: &mut BitReader, xpos: usize, ypos: usize, w: usize, h: usize) -> DecoderResult<()> { | |
682 | let ymode = br.read_gammap()? as usize; | |
683 | let cmode = br.read_gammap()? as usize; | |
684 | let yoff = xpos + ypos * 256; | |
685 | let coff = CHROMA_OFF + xpos / 2 + ypos / 2 * 256; | |
686 | let blk = &mut self.buf[self.refs[CUR_BUF]]; | |
687 | match ymode { | |
688 | 0 => pred_ver(blk, yoff, w, h), | |
689 | 1 => pred_hor(blk, yoff, w, h), | |
690 | 2 => pred_dc (blk, yoff, xpos, ypos, w, h), | |
691 | 3 => pred_plane_delta(blk, yoff, w, h, 0), | |
692 | _ => return Err(DecoderError::InvalidData), | |
693 | }; | |
694 | match cmode { | |
695 | 0 => { | |
696 | pred_dc(blk, coff, xpos / 2, ypos / 2, w / 2, h / 2); | |
697 | pred_dc(blk, coff + 128, xpos / 2, ypos / 2, w / 2, h / 2); | |
698 | }, | |
699 | 1 => { | |
700 | pred_hor(blk, coff, w / 2, h / 2); | |
701 | pred_hor(blk, coff + 128, w / 2, h / 2); | |
702 | }, | |
703 | 2 => { | |
704 | pred_ver(blk, coff, w / 2, h / 2); | |
705 | pred_ver(blk, coff + 128, w / 2, h / 2); | |
706 | }, | |
707 | 3 => { | |
708 | pred_plane_delta(blk, coff, w / 2, h / 2, 0); | |
709 | pred_plane_delta(blk, coff + 128, w / 2, h / 2, 0); | |
710 | }, | |
711 | _ => return Err(DecoderError::InvalidData), | |
712 | }; | |
713 | Ok(()) | |
714 | } | |
715 | fn intra_pred4x4(&mut self, br: &mut BitReader, xpos: usize, ypos: usize, w: usize, h: usize) -> DecoderResult<()> { | |
716 | let mut yoff = xpos + ypos * 256; | |
717 | let mut idx = 6; | |
718 | let blk = &mut self.buf[self.refs[CUR_BUF]]; | |
719 | for y in (0..h).step_by(4) { | |
720 | for x in (0..w).step_by(4) { | |
721 | let mut mode = self.ipred4x4[idx - 5].min(self.ipred4x4[idx - 1]); | |
722 | if mode == 9 { | |
723 | mode = 2; | |
724 | } | |
725 | if !br.read_bool()? { | |
726 | let mode1 = br.read(3)? as u8; | |
727 | mode = if mode1 >= mode { mode1 + 1 } else { mode1 }; | |
728 | } | |
729 | match mode { | |
730 | 0 => pred_ver(blk, yoff + x, 4, 4), | |
731 | 1 => pred_hor(blk, yoff + x, 4, 4), | |
732 | 2 => pred_dc4x4(blk, yoff + x, xpos + x, ypos + y), | |
733 | 3 => pred_ddown_left (blk, yoff + x), | |
734 | 4 => pred_ddown_right(blk, yoff + x), | |
735 | 5 => pred_ver_right (blk, yoff + x), | |
736 | 6 => pred_hor_down (blk, yoff + x), | |
737 | 7 => pred_ver_left (blk, yoff + x), | |
738 | 8 => pred_hor_up (blk, yoff + x), | |
739 | _ => unreachable!(), | |
740 | }; | |
741 | self.ipred4x4[idx] = mode; | |
742 | idx += 1; | |
743 | } | |
744 | yoff += 256 * 4; | |
745 | idx -= w / 4; | |
746 | idx += 5; | |
747 | } | |
748 | let cmode = br.read_gammap()? as usize; | |
749 | let coff = CHROMA_OFF + xpos / 2 + ypos / 2 * 256; | |
750 | match cmode { | |
751 | 0 => { | |
752 | pred_dc(blk, coff, xpos / 2, ypos / 2, w / 2, h / 2); | |
753 | pred_dc(blk, coff + 128, xpos / 2, ypos / 2, w / 2, h / 2); | |
754 | }, | |
755 | 1 => { | |
756 | pred_hor(blk, coff, w / 2, h / 2); | |
757 | pred_hor(blk, coff + 128, w / 2, h / 2); | |
758 | }, | |
759 | 2 => { | |
760 | pred_ver(blk, coff, w / 2, h / 2); | |
761 | pred_ver(blk, coff + 128, w / 2, h / 2); | |
762 | }, | |
763 | 3 => { | |
764 | pred_plane_delta(blk, coff, w / 2, h / 2, 0); | |
765 | pred_plane_delta(blk, coff + 128, w / 2, h / 2, 0); | |
766 | }, | |
767 | _ => return Err(DecoderError::InvalidData), | |
768 | }; | |
769 | Ok(()) | |
770 | } | |
771 | fn decode_residue(&mut self, br: &mut BitReader, xpos: usize, ypos: usize, w: usize, h: usize) -> DecoderResult<()> { | |
772 | const CBP: [u8; 32] = [ | |
773 | 0x00, 0x08, 0x04, 0x02, 0x01, 0x1F, 0x0F, 0x0A, | |
774 | 0x05, 0x0C, 0x03, 0x10, 0x0E, 0x0D, 0x0B, 0x07, | |
775 | 0x09, 0x06, 0x1E, 0x1B, 0x1A, 0x1D, 0x17, 0x15, | |
776 | 0x18, 0x12, 0x11, 0x1C, 0x14, 0x13, 0x16, 0x19 | |
777 | ]; | |
778 | ||
779 | let mut yoff = xpos + ypos * 256; | |
780 | let mut coff = CHROMA_OFF + xpos / 2 + ypos / 2 * 256; | |
781 | let blk = &mut self.buf[self.refs[CUR_BUF]]; | |
782 | let mut yidx = (xpos / 4 + 1) + NCSTRIDE * (ypos / 4 + 1); | |
783 | let mut cidx = (xpos / 8 + 1) + NCSTRIDE * (ypos / 8 + 1); | |
784 | for _y in (0..h).step_by(8) { | |
785 | for x in (0..w).step_by(8) { | |
786 | let idx = br.read_gammap()? as usize; | |
787 | validate!(idx < CBP.len()); | |
788 | let cbp = CBP[idx]; | |
789 | for bno in 0..4 { | |
790 | let cur_yidx = yidx + x / 4 + (bno & 1) + (bno / 2) * NCSTRIDE; | |
791 | if (cbp & (1 << bno)) != 0 { | |
792 | let ctx = avg(self.y_ncoeffs[cur_yidx - 1], self.y_ncoeffs[cur_yidx - NCSTRIDE]); | |
793 | self.y_ncoeffs[cur_yidx] = decode_coeffs(br, &self.codebooks, &self.qmat, ctx, &mut blk[yoff + x + (bno & 1) * 4 + (bno / 2) * 4 * 256..])?; | |
794 | } else { | |
795 | self.y_ncoeffs[cur_yidx] = 0; | |
796 | } | |
797 | } | |
798 | if (cbp & 0x10) != 0 { | |
799 | let ctx = avg(self.c_ncoeffs[cidx + x / 8 - 1], self.c_ncoeffs[cidx + x / 8 - NCSTRIDE]); | |
800 | let unc = decode_coeffs(br, &self.codebooks, &self.qmat, ctx, &mut blk[coff + x / 2..])?; | |
801 | let vnc = decode_coeffs(br, &self.codebooks, &self.qmat, ctx, &mut blk[coff + 128 + x / 2..])?; | |
802 | self.c_ncoeffs[cidx + x / 8] = avg(unc, vnc); | |
803 | } else { | |
804 | self.c_ncoeffs[cidx + x / 8] = 0; | |
805 | } | |
806 | } | |
807 | yidx += NCSTRIDE * 2; | |
808 | cidx += NCSTRIDE; | |
809 | yoff += 8 * 256; | |
810 | coff += 4 * 256; | |
811 | } | |
812 | Ok(()) | |
813 | } | |
814 | fn decode_block(&mut self, br: &mut BitReader, xpos: usize, ypos: usize, w: usize, h: usize) -> DecoderResult<()> { | |
815 | let mode = br.read_gammap()?; | |
816 | let min_dim = w.min(h); | |
817 | let large_block = min_dim >= 8; | |
818 | if mode >= 16 && !large_block { | |
819 | return Err(DecoderError::InvalidData); | |
820 | } | |
821 | match mode { | |
822 | 0 if w > 2 => { | |
823 | let hw = w / 2; | |
824 | self.decode_block(br, xpos, ypos, hw, h)?; | |
825 | self.decode_block(br, xpos + hw, ypos, hw, h)?; | |
826 | }, | |
827 | 1 => { self.copy_block(xpos, ypos, w, h, 0)?; }, | |
828 | 2 if h > 2 => { | |
829 | let hh = h / 2; | |
830 | self.decode_block(br, xpos, ypos, w, hh)?; | |
831 | self.decode_block(br, xpos, ypos + hh, w, hh)?; | |
832 | }, | |
833 | 3 => { self.do_mc_bias(br, xpos, ypos, w, h)?; }, | |
834 | 4 | 5 | 6 => { | |
835 | let ref_id = (mode - 4) as usize; | |
836 | self.do_mc(br, xpos, ypos, w, h, ref_id)?; | |
837 | }, | |
838 | 7 => { self.pred_plane(br, xpos, ypos, w, h)?; }, | |
839 | 8 if large_block => { | |
840 | let hw = w / 2; | |
841 | self.decode_block(br, xpos, ypos, hw, h)?; | |
842 | self.decode_block(br, xpos + hw, ypos, hw, h)?; | |
843 | self.decode_residue(br, xpos, ypos, w, h)?; | |
844 | }, | |
845 | 9 => { self.copy_block(xpos, ypos, w, h, 1)?; }, | |
846 | 10 if large_block => { | |
847 | self.do_mc_bias(br, xpos, ypos, w, h)?; | |
848 | self.decode_residue(br, xpos, ypos, w, h)?; | |
849 | }, | |
850 | 11 => { | |
851 | if min_dim >= 4 { | |
852 | self.intra_pred(br, xpos, ypos, w, h)?; | |
853 | } | |
854 | }, | |
855 | 12 if large_block => { | |
856 | self.copy_block(xpos, ypos, w, h, 0)?; | |
857 | self.decode_residue(br, xpos, ypos, w, h)?; | |
858 | }, | |
859 | 13 if large_block => { | |
860 | let hh = h / 2; | |
861 | self.decode_block(br, xpos, ypos, w, hh)?; | |
862 | self.decode_block(br, xpos, ypos + hh, w, hh)?; | |
863 | self.decode_residue(br, xpos, ypos, w, h)?; | |
864 | }, | |
865 | 14 => { self.copy_block(xpos, ypos, w, h, 2)?; }, | |
866 | 15 => { | |
867 | if min_dim >= 4 { | |
868 | self.intra_pred4x4(br, xpos, ypos, w, h)?; | |
869 | } | |
870 | }, | |
871 | 16 | 17 | 18 => { | |
872 | let ref_id = (mode - 16) as usize; | |
873 | self.do_mc(br, xpos, ypos, w, h, ref_id)?; | |
874 | self.decode_residue(br, xpos, ypos, w, h)?; | |
875 | }, | |
876 | 19 => { | |
877 | self.intra_pred4x4(br, xpos, ypos, w, h)?; | |
878 | self.decode_residue(br, xpos, ypos, w, h)?; | |
879 | }, | |
880 | 20 => { | |
881 | self.copy_block(xpos, ypos, w, h, 1)?; | |
882 | self.decode_residue(br, xpos, ypos, w, h)?; | |
883 | }, | |
884 | 21 => { | |
885 | self.copy_block(xpos, ypos, w, h, 2)?; | |
886 | self.decode_residue(br, xpos, ypos, w, h)?; | |
887 | }, | |
888 | 22 => { | |
889 | self.intra_pred(br, xpos, ypos, w, h)?; | |
890 | self.decode_residue(br, xpos, ypos, w, h)?; | |
891 | }, | |
892 | 23 => { | |
893 | self.pred_plane(br, xpos, ypos, w, h)?; | |
894 | self.decode_residue(br, xpos, ypos, w, h)?; | |
895 | }, | |
896 | _ => return Err(DecoderError::InvalidData), | |
897 | }; | |
898 | Ok(()) | |
899 | } | |
900 | } | |
901 | ||
902 | const QUANTISERS: [u8; 52] = [ | |
903 | 10, 13, 10, 13, 13, 16, 13, 16, 11, 14, 11, 14, 14, 18, 14, 18, | |
904 | 13, 16, 13, 16, 16, 20, 16, 20, 14, 18, 14, 18, 18, 23, 18, 23, | |
905 | 16, 20, 16, 20, 20, 25, 20, 25, 18, 23, 18, 23, 23, 29, 23, 29, | |
906 | 20, 14, 12, 10 | |
907 | ]; | |
908 | ||
909 | impl NADecoder for VXVideoDecoder { | |
910 | fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> { | |
911 | if let NACodecTypeInfo::Video(vinfo) = info.get_properties() { | |
912 | self.width = vinfo.get_width(); | |
913 | self.height = vinfo.get_height(); | |
914 | validate!(self.width <= 256 && self.height <= 256); | |
915 | ||
916 | let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(self.width, self.height, false, YUV420_FORMAT)); | |
917 | self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref(); | |
918 | ||
919 | if let Some(edata) = info.get_extradata() { | |
920 | validate!(edata.len() > 0); | |
921 | let fps = edata[0] as usize; | |
922 | validate!(fps <= 60); | |
923 | let base = &QUANTISERS[(fps % 6) * 8..][..8]; | |
924 | let scale = fps / 6; | |
925 | for (dq, iq) in self.qmat.iter_mut().zip(base.iter()) { | |
926 | *dq = i32::from(*iq) << scale; | |
927 | } | |
928 | } else { | |
929 | return Err(DecoderError::InvalidData); | |
930 | } | |
931 | ||
932 | for frm in self.buf.iter_mut() { | |
933 | let (ybuf, cbuf) = frm.split_at_mut(CHROMA_OFF); | |
934 | for el in ybuf.iter_mut() { | |
935 | *el = 0; | |
936 | } | |
937 | for el in cbuf.iter_mut() { | |
938 | *el = 0x80; | |
939 | } | |
940 | } | |
941 | ||
942 | Ok(()) | |
943 | } else { | |
944 | Err(DecoderError::InvalidData) | |
945 | } | |
946 | } | |
947 | fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> { | |
948 | let src = pkt.get_buffer(); | |
7542b753 | 949 | validate!(src.len() > 4); |
55d85231 | 950 | |
7542b753 | 951 | let mut br = BitReader::new(&src[4..], BitReaderMode::LE16MSB); |
55d85231 KS |
952 | |
953 | self.y_ncoeffs = [0; NCSTRIDE * (256 / 4 + 1)]; | |
954 | self.c_ncoeffs = [0; NCSTRIDE * (256 / 8 + 1)]; | |
955 | self.mvs = [MV::default(); 16 * 16]; | |
956 | self.decode_frame(&mut br)?; | |
957 | ||
958 | let bufinfo = alloc_video_buffer(self.info.get_properties().get_video_info().unwrap(), 4)?; | |
959 | let mut buf = bufinfo.get_vbuf().unwrap(); | |
960 | let ystride = buf.get_stride(0); | |
961 | let ustride = buf.get_stride(1); | |
962 | let vstride = buf.get_stride(2); | |
963 | let yoff = buf.get_offset(0); | |
964 | let uoff = buf.get_offset(1); | |
965 | let voff = buf.get_offset(2); | |
966 | let data = buf.get_data_mut().unwrap(); | |
967 | let cur = self.refs[CUR_BUF]; | |
968 | for (sline, dline) in self.buf[cur][0..].chunks(256).take(self.height).zip(data[yoff..].chunks_mut(ystride)) { | |
969 | dline[..self.width].copy_from_slice(&sline[..self.width]); | |
970 | } | |
971 | for (sline, dline) in self.buf[cur][CHROMA_OFF..].chunks(256).take(self.height / 2).zip(data[uoff..].chunks_mut(ustride)) { | |
972 | dline[..self.width / 2].copy_from_slice(&sline[..self.width / 2]); | |
973 | } | |
974 | for (sline, dline) in self.buf[cur][CHROMA_OFF + 128..].chunks(256).take(self.height / 2).zip(data[voff..].chunks_mut(vstride)) { | |
975 | dline[..self.width / 2].copy_from_slice(&sline[..self.width / 2]); | |
976 | } | |
977 | let videobuf = NABufferType::Video(buf); | |
978 | self.update_refs(); | |
979 | ||
980 | let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), videobuf); | |
981 | let is_intra = pkt.get_pts() == Some(0); | |
982 | frm.set_keyframe(is_intra); | |
983 | frm.set_frame_type(if is_intra { FrameType::I } else { FrameType::P }); | |
984 | Ok(frm.into_ref()) | |
985 | } | |
986 | fn flush(&mut self) { | |
987 | } | |
988 | } | |
989 | ||
990 | impl NAOptionHandler for VXVideoDecoder { | |
991 | fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] } | |
992 | fn set_options(&mut self, _options: &[NAOption]) { } | |
993 | fn query_option_value(&self, _name: &str) -> Option<NAValue> { None } | |
994 | } | |
995 | ||
996 | ||
997 | pub fn get_decoder_video() -> Box<dyn NADecoder + Send> { | |
998 | Box::new(VXVideoDecoder::new()) | |
999 | } | |
1000 | ||
e3bb68fa KS |
1001 | fn parse_coeffs(br: &mut BitReader, codebooks: &Codebooks, ctx: u8) -> DecoderResult<u8> { |
1002 | const MAX_LEVEL: [i32; 6] = [ 2, 5, 11, 23, 47, 0x8000 ]; | |
1003 | ||
1004 | let (ncoeffs, nones) = if ctx < 8 { | |
1005 | let sym = br.read_cb(&codebooks.nc_cb[NC_MAP[ctx as usize]])?; | |
1006 | if sym == 0 { | |
1007 | return Ok(0); | |
1008 | } | |
1009 | (sym >> 2, sym & 3) | |
1010 | } else { | |
1011 | let ncoeffs = (br.read(4)? + 1) as u8; | |
1012 | let nones = br.read(2)? as u8; | |
1013 | if ncoeffs < nones { | |
1014 | return Ok(0); | |
1015 | } | |
1016 | (ncoeffs, nones) | |
1017 | }; | |
1018 | let mut num_zero = if ncoeffs == 16 { 0 } else { | |
1019 | br.read_cb(&codebooks.num_zero_cb[ncoeffs as usize - 1])? | |
1020 | }; | |
1021 | validate!(ncoeffs + num_zero <= 16); | |
1022 | let mut level = 0usize; | |
1023 | let mut coef_left = ncoeffs; | |
1024 | let mut ones_left = nones; | |
1025 | while coef_left > 0 { | |
1026 | let _val = if ones_left > 0 { | |
1027 | ones_left -= 1; | |
1028 | if !br.read_bool()? { 1 } else { -1 } | |
1029 | } else { | |
1030 | let prefix = br.read_unary()?; | |
1031 | let val = if prefix < 15 { | |
1032 | (br.read(level as u8)? | (prefix << level)) as i32 | |
1033 | } else { | |
1034 | (br.read(11)? + (15 << level)) as i32 | |
1035 | }; | |
1036 | if val > MAX_LEVEL[level] { | |
1037 | level += 1; | |
1038 | } | |
1039 | if !br.read_bool()? { | |
1040 | val + 1 | |
1041 | } else { | |
1042 | -(val + 1) | |
1043 | } | |
1044 | }; | |
1045 | coef_left -= 1; | |
1046 | if num_zero > 0 && coef_left > 0 { | |
1047 | let run = if num_zero < 7 { | |
1048 | br.read_cb(&codebooks.zero_run_cb[num_zero as usize - 1])? | |
1049 | } else { | |
1050 | if br.peek(3) != 0 { | |
1051 | 7 - (br.read(3)? as u8) | |
1052 | } else { | |
1053 | (br.read_unary()? as u8) + 4 | |
1054 | } | |
1055 | }; | |
1056 | validate!(run <= num_zero); | |
1057 | num_zero -= run; | |
1058 | } | |
1059 | } | |
1060 | Ok(ncoeffs) | |
1061 | } | |
1062 | ||
1063 | #[cfg(feature="demuxer_vx")] | |
1064 | pub struct VXVideoParser { | |
1065 | width: usize, | |
1066 | height: usize, | |
1067 | ipred4x4: [u8; 25], | |
1068 | y_ncoeffs: [u8; NCSTRIDE * (256 / 4 + 1)], | |
1069 | c_ncoeffs: [u8; NCSTRIDE * (256 / 8 + 1)], | |
1070 | codebooks: Codebooks, | |
1071 | } | |
1072 | ||
1073 | #[cfg(feature="demuxer_vx")] | |
1074 | impl VXVideoParser { | |
1075 | pub fn new(width: usize, height: usize) -> Self { | |
1076 | Self { | |
1077 | width, height, | |
1078 | ipred4x4: [9; 25], | |
1079 | y_ncoeffs: [0; NCSTRIDE * (256 / 4 + 1)], | |
1080 | c_ncoeffs: [0; NCSTRIDE * (256 / 8 + 1)], | |
1081 | codebooks: Codebooks::new(), | |
1082 | } | |
1083 | } | |
1084 | pub fn parse_frame(&mut self, src: &[u8]) -> DecoderResult<usize> { | |
1085 | let mut br = BitReader::new(src, BitReaderMode::LE16MSB); | |
1086 | self.y_ncoeffs = [0; NCSTRIDE * (256 / 4 + 1)]; | |
1087 | self.c_ncoeffs = [0; NCSTRIDE * (256 / 8 + 1)]; | |
1088 | ||
1089 | for ypos in (0..self.height).step_by(16) { | |
1090 | for xpos in (0..self.width).step_by(16) { | |
1091 | self.parse_block(&mut br, xpos, ypos, 16, 16)?; | |
1092 | } | |
1093 | } | |
1094 | ||
1095 | Ok(br.tell()) | |
1096 | } | |
1097 | fn parse_mc(&mut self, br: &mut BitReader) -> DecoderResult<()> { | |
1098 | let _dx = br.read_gammap_s()? as i8; | |
1099 | let _dy = br.read_gammap_s()? as i8; | |
1100 | Ok(()) | |
1101 | } | |
1102 | fn parse_mc_bias(&mut self, br: &mut BitReader) -> DecoderResult<()> { | |
1103 | let _mx = br.read_gammap_s()? as isize; | |
1104 | let _my = br.read_gammap_s()? as isize; | |
1105 | let _ydelta = br.read_gammap_s()? * 2; | |
1106 | let _udelta = br.read_gammap_s()? * 2; | |
1107 | let _vdelta = br.read_gammap_s()? * 2; | |
1108 | Ok(()) | |
1109 | } | |
1110 | fn parse_plane_pred(&mut self, br: &mut BitReader) -> DecoderResult<()> { | |
1111 | let _ydelta = br.read_gammap_s()? * 2; | |
1112 | let _udelta = br.read_gammap_s()? * 2; | |
1113 | let _vdelta = br.read_gammap_s()? * 2; | |
1114 | Ok(()) | |
1115 | } | |
1116 | fn parse_intra_pred(&mut self, br: &mut BitReader) -> DecoderResult<()> { | |
1117 | let _ymode = br.read_gammap()? as usize; | |
1118 | let _cmode = br.read_gammap()? as usize; | |
1119 | Ok(()) | |
1120 | } | |
1121 | fn parse_intra_pred4x4(&mut self, br: &mut BitReader, w: usize, h: usize) -> DecoderResult<()> { | |
1122 | let mut idx = 6; | |
1123 | for _y in (0..h).step_by(4) { | |
1124 | for _x in (0..w).step_by(4) { | |
1125 | let mut mode = self.ipred4x4[idx - 5].min(self.ipred4x4[idx - 1]); | |
1126 | if mode == 9 { | |
1127 | mode = 2; | |
1128 | } | |
1129 | if !br.read_bool()? { | |
1130 | let mode1 = br.read(3)? as u8; | |
1131 | mode = if mode1 >= mode { mode1 + 1 } else { mode1 }; | |
1132 | } | |
1133 | self.ipred4x4[idx] = mode; | |
1134 | idx += 1; | |
1135 | } | |
1136 | } | |
1137 | let _cmode = br.read_gammap()? as usize; | |
1138 | Ok(()) | |
1139 | } | |
1140 | fn parse_residue(&mut self, br: &mut BitReader, xpos: usize, ypos: usize, w: usize, h: usize) -> DecoderResult<()> { | |
1141 | const CBP: [u8; 32] = [ | |
1142 | 0x00, 0x08, 0x04, 0x02, 0x01, 0x1F, 0x0F, 0x0A, | |
1143 | 0x05, 0x0C, 0x03, 0x10, 0x0E, 0x0D, 0x0B, 0x07, | |
1144 | 0x09, 0x06, 0x1E, 0x1B, 0x1A, 0x1D, 0x17, 0x15, | |
1145 | 0x18, 0x12, 0x11, 0x1C, 0x14, 0x13, 0x16, 0x19 | |
1146 | ]; | |
1147 | ||
1148 | let mut yidx = (xpos / 4 + 1) + NCSTRIDE * (ypos / 4 + 1); | |
1149 | let mut cidx = (xpos / 8 + 1) + NCSTRIDE * (ypos / 8 + 1); | |
1150 | for _y in (0..h).step_by(8) { | |
1151 | for x in (0..w).step_by(8) { | |
1152 | let idx = br.read_gammap()? as usize; | |
1153 | validate!(idx < CBP.len()); | |
1154 | let cbp = CBP[idx]; | |
1155 | for bno in 0..4 { | |
1156 | let cur_yidx = yidx + x / 4 + (bno & 1) + (bno / 2) * NCSTRIDE; | |
1157 | if (cbp & (1 << bno)) != 0 { | |
1158 | let ctx = avg(self.y_ncoeffs[cur_yidx - 1], self.y_ncoeffs[cur_yidx - NCSTRIDE]); | |
1159 | self.y_ncoeffs[cur_yidx] = parse_coeffs(br, &self.codebooks, ctx)?; | |
1160 | } else { | |
1161 | self.y_ncoeffs[cur_yidx] = 0; | |
1162 | } | |
1163 | } | |
1164 | if (cbp & 0x10) != 0 { | |
1165 | let ctx = avg(self.c_ncoeffs[cidx + x / 8 - 1], self.c_ncoeffs[cidx + x / 8 - NCSTRIDE]); | |
1166 | let unc = parse_coeffs(br, &self.codebooks, ctx)?; | |
1167 | let vnc = parse_coeffs(br, &self.codebooks, ctx)?; | |
1168 | self.c_ncoeffs[cidx + x / 8] = avg(unc, vnc); | |
1169 | } else { | |
1170 | self.c_ncoeffs[cidx + x / 8] = 0; | |
1171 | } | |
1172 | } | |
1173 | yidx += NCSTRIDE * 2; | |
1174 | cidx += NCSTRIDE; | |
1175 | } | |
1176 | Ok(()) | |
1177 | } | |
1178 | fn parse_block(&mut self, br: &mut BitReader, xpos: usize, ypos: usize, w: usize, h: usize) -> DecoderResult<()> { | |
1179 | let mode = br.read_gammap()?; | |
1180 | let min_dim = w.min(h); | |
1181 | let large_block = min_dim >= 8; | |
1182 | if mode >= 16 && !large_block { | |
1183 | return Err(DecoderError::InvalidData); | |
1184 | } | |
1185 | match mode { | |
1186 | 0 if w > 2 => { | |
1187 | let hw = w / 2; | |
1188 | self.parse_block(br, xpos, ypos, hw, h)?; | |
1189 | self.parse_block(br, xpos + hw, ypos, hw, h)?; | |
1190 | }, | |
1191 | 1 => {}, | |
1192 | 2 if h > 2 => { | |
1193 | let hh = h / 2; | |
1194 | self.parse_block(br, xpos, ypos, w, hh)?; | |
1195 | self.parse_block(br, xpos, ypos + hh, w, hh)?; | |
1196 | }, | |
1197 | 3 => { self.parse_mc_bias(br)?; }, | |
1198 | 4 | 5 | 6 => { | |
1199 | self.parse_mc(br)?; | |
1200 | }, | |
1201 | 7 => { self.parse_plane_pred(br)?; }, | |
1202 | 8 if large_block => { | |
1203 | let hw = w / 2; | |
1204 | self.parse_block(br, xpos, ypos, hw, h)?; | |
1205 | self.parse_block(br, xpos + hw, ypos, hw, h)?; | |
1206 | self.parse_residue(br, xpos, ypos, w, h)?; | |
1207 | }, | |
1208 | 9 => {}, | |
1209 | 10 if large_block => { | |
1210 | self.parse_mc_bias(br)?; | |
1211 | self.parse_residue(br, xpos, ypos, w, h)?; | |
1212 | }, | |
1213 | 11 => { | |
1214 | if min_dim >= 4 { | |
1215 | self.parse_intra_pred(br)?; | |
1216 | } | |
1217 | }, | |
1218 | 12 if large_block => { | |
1219 | self.parse_residue(br, xpos, ypos, w, h)?; | |
1220 | }, | |
1221 | 13 if large_block => { | |
1222 | let hh = h / 2; | |
1223 | self.parse_block(br, xpos, ypos, w, hh)?; | |
1224 | self.parse_block(br, xpos, ypos + hh, w, hh)?; | |
1225 | self.parse_residue(br, xpos, ypos, w, h)?; | |
1226 | }, | |
1227 | 14 => {}, | |
1228 | 15 => { | |
1229 | if min_dim >= 4 { | |
1230 | self.parse_intra_pred4x4(br, w, h)?; | |
1231 | } | |
1232 | }, | |
1233 | 16 | 17 | 18 => { | |
1234 | self.parse_mc(br)?; | |
1235 | self.parse_residue(br, xpos, ypos, w, h)?; | |
1236 | }, | |
1237 | 19 => { | |
1238 | self.parse_intra_pred4x4(br, w, h)?; | |
1239 | self.parse_residue(br, xpos, ypos, w, h)?; | |
1240 | }, | |
1241 | 20 => { | |
1242 | self.parse_residue(br, xpos, ypos, w, h)?; | |
1243 | }, | |
1244 | 21 => { | |
1245 | self.parse_residue(br, xpos, ypos, w, h)?; | |
1246 | }, | |
1247 | 22 => { | |
1248 | self.parse_intra_pred(br)?; | |
1249 | self.parse_residue(br, xpos, ypos, w, h)?; | |
1250 | }, | |
1251 | 23 => { | |
1252 | self.parse_plane_pred(br)?; | |
1253 | self.parse_residue(br, xpos, ypos, w, h)?; | |
1254 | }, | |
1255 | _ => return Err(DecoderError::InvalidData), | |
1256 | }; | |
1257 | Ok(()) | |
1258 | } | |
1259 | } | |
1260 | ||
55d85231 KS |
1261 | |
1262 | struct AudioState { | |
1263 | lpc0_idx: usize, | |
1264 | lpc1_idx: usize, | |
1265 | lpc2_idx: usize, | |
1266 | scale: i32, | |
1267 | frame_mode: usize, | |
0e5eee2d | 1268 | lpc_coeffs: [i32; 8], |
55d85231 | 1269 | cur_filt: [i32; 8], |
0e5eee2d KS |
1270 | prev_filt: [i32; 8], |
1271 | ||
1272 | pulse_buf: [i32; 128], | |
1273 | pulse_hist: [i32; 256], | |
1274 | lpc_hist: [i32; 8], | |
55d85231 KS |
1275 | |
1276 | lpc0_cb: [[i16; 8]; 64], | |
1277 | lpc1_cb: [[i16; 8]; 64], | |
1278 | lpc2_cb: [[i16; 8]; 64], | |
1279 | decays: [i32; 8], | |
1280 | base_filt: [i32; 8], | |
1281 | base_scale: i32, | |
1282 | } | |
1283 | ||
1284 | impl AudioState { | |
1285 | fn new() -> Self { | |
1286 | Self { | |
1287 | lpc0_idx: 0, | |
1288 | lpc1_idx: 0, | |
1289 | lpc2_idx: 0, | |
1290 | scale: 0, | |
1291 | frame_mode: 0, | |
0e5eee2d | 1292 | lpc_coeffs: [0; 8], |
55d85231 | 1293 | cur_filt: [0; 8], |
0e5eee2d KS |
1294 | prev_filt: [0; 8], |
1295 | ||
1296 | pulse_buf: [0; 128], | |
1297 | pulse_hist: [0; 256], | |
1298 | lpc_hist: [0; 8], | |
55d85231 KS |
1299 | |
1300 | lpc0_cb: [[0; 8]; 64], | |
1301 | lpc1_cb: [[0; 8]; 64], | |
1302 | lpc2_cb: [[0; 8]; 64], | |
1303 | decays: [0; 8], | |
1304 | base_filt: [0; 8], | |
1305 | base_scale: 0, | |
1306 | } | |
1307 | } | |
1308 | fn read_initial_params(&mut self, br: &mut ByteReader) -> DecoderResult<()> { | |
1309 | for entry in self.lpc0_cb.iter_mut() { | |
1310 | for el in entry.iter_mut() { | |
1311 | *el = br.read_u16le()? as i16; | |
1312 | } | |
1313 | } | |
1314 | for entry in self.lpc1_cb.iter_mut() { | |
1315 | for el in entry.iter_mut() { | |
1316 | *el = br.read_u16le()? as i16; | |
1317 | } | |
1318 | } | |
1319 | for entry in self.lpc2_cb.iter_mut() { | |
1320 | for el in entry.iter_mut() { | |
1321 | *el = br.read_u16le()? as i16; | |
1322 | } | |
1323 | } | |
1324 | for el in self.decays.iter_mut() { | |
1325 | *el = i32::from(br.read_u16le()? as i16); | |
1326 | } | |
1327 | for el in self.base_filt.iter_mut() { | |
1328 | *el = br.read_u32le()? as i32; | |
1329 | } | |
1330 | self.base_scale = br.read_u32le()? as i32; | |
1331 | Ok(()) | |
1332 | } | |
0e5eee2d | 1333 | fn unpack_data(&mut self, br: &mut ByteReader, val: u16) -> DecoderResult<()> { |
55d85231 KS |
1334 | self.lpc0_idx = (val & 0x3F) as usize; |
1335 | self.scale = (self.decays[((val >> 6) & 7) as usize] * self.scale) >> 13; | |
1336 | let val1 = br.read_u16le()?; | |
1337 | self.lpc1_idx = ((val1 >> 6) & 0x3F) as usize; | |
1338 | self.lpc2_idx = (val1 & 0x3F) as usize; | |
1339 | self.frame_mode = ((val1 >> 12) & 3) as usize; | |
1340 | let mut idx = (val1 >> 14) as usize; | |
1341 | if self.frame_mode == 0 { | |
1342 | let mut tail = 0; | |
1343 | for _ in 0..8 { | |
1344 | let val = br.read_u16le()?; | |
1345 | for i in 0..5 { | |
1346 | let add = i32::from((val >> (13 - i * 3)) & 7); | |
0e5eee2d | 1347 | self.pulse_buf[idx] += self.scale * (add * 2 - 7); |
55d85231 KS |
1348 | idx += 3; |
1349 | } | |
1350 | tail = tail * 2 + (val & 1); | |
1351 | } | |
1352 | let add = i32::from((tail >> 5) & 7); | |
0e5eee2d | 1353 | self.pulse_buf[idx] += self.scale * (add * 2 - 7); |
55d85231 KS |
1354 | idx += 3; |
1355 | let add = i32::from((tail >> 2) & 7); | |
0e5eee2d | 1356 | self.pulse_buf[idx] += self.scale * (add * 2 - 7); |
55d85231 KS |
1357 | } else { |
1358 | let (len, step) = match self.frame_mode { | |
1359 | 1 => (5, 3), | |
1360 | 2 => (4, 4), | |
1361 | 3 => (3, 5), | |
1362 | _ => unreachable!(), | |
1363 | }; | |
55d85231 KS |
1364 | for _ in 0..len { |
1365 | let val = br.read_u16le()?; | |
1bab3697 | 1366 | for i in 0..8 { |
55d85231 | 1367 | let add = i32::from((val >> (14 - i * 2)) & 3); |
0e5eee2d | 1368 | self.pulse_buf[idx] += self.scale * (add * 2 - 3); |
55d85231 KS |
1369 | idx += step; |
1370 | } | |
1371 | } | |
1372 | } | |
1373 | Ok(()) | |
1374 | } | |
0e5eee2d | 1375 | fn update_lpc_coeffs(&mut self) { |
55d85231 | 1376 | for i in 0..8 { |
0e5eee2d KS |
1377 | self.lpc_coeffs[i] += i32::from(self.lpc0_cb[self.lpc0_idx][i]); |
1378 | self.lpc_coeffs[i] += i32::from(self.lpc1_cb[self.lpc1_idx][i]); | |
1379 | self.lpc_coeffs[i] += i32::from(self.lpc2_cb[self.lpc2_idx][i]); | |
1380 | } | |
1381 | ||
1382 | let mut tmp = [0; 8]; | |
1383 | ||
1384 | self.cur_filt = self.lpc_coeffs; | |
1385 | for i in 0..4 { | |
1386 | self.cur_filt.swap(i, 7 - i); | |
1387 | } | |
1388 | for len in 1..8 { | |
1389 | let scale = self.cur_filt[len]; | |
1390 | for (prod, &val) in tmp.iter_mut().zip(self.cur_filt.iter()).take(len) { | |
1391 | //*prod = (val * scale) >> 15; | |
1392 | *prod = val.wrapping_mul(scale) >> 15; | |
1393 | } | |
1394 | for (dst, &add) in self.cur_filt.iter_mut().zip(tmp[..len].iter()) { | |
1395 | *dst += add; | |
1396 | } | |
1397 | } | |
1398 | ||
1399 | for el in self.cur_filt.iter_mut() { | |
1400 | *el = -(*el >> 1); | |
55d85231 KS |
1401 | } |
1402 | } | |
0e5eee2d KS |
1403 | fn decode_intra(&mut self, br: &mut ByteReader, val: u16, out: &mut [i32; 128]) -> DecoderResult<()> { |
1404 | self.scale = self.base_scale; | |
1405 | self.lpc_hist = [0; 8]; | |
1406 | ||
1407 | for el in self.pulse_buf.iter_mut() { | |
1408 | *el = 0; | |
1409 | } | |
1410 | self.unpack_data(br, val)?; | |
1411 | ||
1412 | self.lpc_coeffs = self.base_filt; | |
1413 | self.update_lpc_coeffs(); | |
1414 | ||
1415 | apply_lpc(out, &self.pulse_buf, &mut self.lpc_hist, &self.cur_filt); | |
1416 | Ok(()) | |
1417 | } | |
1418 | fn decode_inter(&mut self, br: &mut ByteReader, val: u16, mode: u16, out: &mut [i32; 128]) -> DecoderResult<()> { | |
1419 | let (part0, part1) = self.pulse_hist.split_at_mut(128); | |
1420 | part0.copy_from_slice(part1); | |
1421 | part1.copy_from_slice(&self.pulse_buf); | |
1422 | self.prev_filt = self.cur_filt; | |
1423 | ||
1424 | if mode == 0x7E { | |
1425 | for el in self.pulse_buf.iter_mut() { | |
1426 | *el = 0; | |
1427 | } | |
1428 | } else { | |
1429 | let src = &self.pulse_hist[127 - (mode as usize)..]; | |
1430 | let (src_head, body) = src.split_at(7); | |
1431 | let (src_body, src_tail) = body.split_at(128 - 7 * 2); | |
1432 | ||
1433 | let (dst_head, body) = self.pulse_buf.split_at_mut(7); | |
1434 | let (dst_body, dst_tail) = body.split_at_mut(128 - 7 * 2); | |
1435 | ||
1436 | for (i, (dst, &src)) in dst_head.iter_mut().zip(src_head.iter()).enumerate() { | |
1437 | *dst = (src * ((i + 1) as i32)) >> 4; | |
1438 | } | |
1439 | for (dst, &src) in dst_body.iter_mut().zip(src_body.iter()) { | |
1440 | *dst = src >> 1; | |
1441 | } | |
1442 | for (i, (dst, &src)) in dst_tail.iter_mut().zip(src_tail.iter()).enumerate() { | |
1443 | *dst = (src * ((7 - i) as i32)) >> 4; | |
1444 | } | |
1445 | } | |
1446 | ||
1447 | self.unpack_data(br, val)?; | |
1448 | self.update_lpc_coeffs(); | |
1449 | ||
1450 | let mut filters = [[0; 8]; 4]; | |
1451 | filters[3] = self.cur_filt; | |
1452 | let prev_filter = &self.prev_filt; | |
55d85231 | 1453 | for i in 0..8 { |
0e5eee2d KS |
1454 | filters[1][i] = (prev_filter[i] + filters[3][i]) >> 1; |
1455 | filters[0][i] = (prev_filter[i] + filters[1][i]) >> 1; | |
1456 | filters[2][i] = (filters[1][i] + filters[3][i]) >> 1; | |
55d85231 | 1457 | } |
0e5eee2d KS |
1458 | for ((dst, src), filter) in out.chunks_exact_mut(32) |
1459 | .zip(self.pulse_buf.chunks_exact(32)).zip(filters.iter()) { | |
1460 | apply_lpc(dst, src, &mut self.lpc_hist, filter); | |
1461 | } | |
1462 | Ok(()) | |
55d85231 KS |
1463 | } |
1464 | } | |
1465 | ||
0e5eee2d | 1466 | fn apply_lpc(dst: &mut [i32], src: &[i32], hist: &mut [i32; 8], filt: &[i32; 8]) { |
016340a0 | 1467 | for (hidx, (out, src)) in dst.iter_mut().zip(src.iter()).enumerate() { |
55d85231 KS |
1468 | let mut sum = *src << 14; |
1469 | for i in 0..8 { | |
0e5eee2d KS |
1470 | //sum += hist[(hidx + i) & 7] * filt[i]; |
1471 | sum = sum.wrapping_add(hist[(hidx + i) & 7].wrapping_mul(filt[i])); | |
55d85231 KS |
1472 | } |
1473 | let samp = sum >> 14; | |
1474 | *out = samp; | |
1475 | hist[hidx & 7] = samp; | |
55d85231 KS |
1476 | } |
1477 | } | |
1478 | ||
1479 | struct VXAudioDecoder { | |
1480 | ainfo: NAAudioInfo, | |
1481 | info: Arc<NACodecInfo>, | |
1482 | chmap: NAChannelMap, | |
0e5eee2d KS |
1483 | state: [AudioState; 2], |
1484 | buf: [i32; 128], | |
55d85231 KS |
1485 | } |
1486 | ||
1487 | impl VXAudioDecoder { | |
1488 | fn new() -> Self { | |
1489 | Self { | |
1490 | ainfo: NAAudioInfo::new(0, 1, SND_S16P_FORMAT, 0), | |
1491 | info: NACodecInfo::new_dummy(), | |
1492 | chmap: NAChannelMap::new(), | |
0e5eee2d KS |
1493 | state: [AudioState::new(), AudioState::new()], |
1494 | buf: [0; 128], | |
55d85231 | 1495 | } |
55d85231 KS |
1496 | } |
1497 | fn output(&mut self, dst: &mut [i16]) { | |
0e5eee2d KS |
1498 | for (dst, &src) in dst.iter_mut().zip(self.buf.iter()) { |
1499 | *dst = src.max(-0x8000).min(0x7FFF) as i16; | |
55d85231 | 1500 | } |
55d85231 KS |
1501 | } |
1502 | } | |
1503 | ||
1504 | impl NADecoder for VXAudioDecoder { | |
1505 | fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> { | |
1506 | if let NACodecTypeInfo::Audio(ainfo) = info.get_properties() { | |
0e5eee2d KS |
1507 | if ainfo.channels != 1 && ainfo.channels != 2 { |
1508 | return Err(DecoderError::NotImplemented); | |
1509 | } | |
55d85231 | 1510 | if let Some(edata) = info.get_extradata() { |
0e5eee2d | 1511 | validate!(edata.len() == usize::from(ainfo.channels) * 3124); |
55d85231 KS |
1512 | let mut mr = MemoryReader::new_read(edata.as_slice()); |
1513 | let mut br = ByteReader::new(&mut mr); | |
0e5eee2d KS |
1514 | for state in self.state.iter_mut().take(usize::from(ainfo.channels)) { |
1515 | state.read_initial_params(&mut br)?; | |
1516 | } | |
55d85231 KS |
1517 | } else { |
1518 | return Err(DecoderError::InvalidData); | |
1519 | } | |
0e5eee2d | 1520 | self.ainfo = NAAudioInfo::new(ainfo.get_sample_rate(), ainfo.channels, SND_S16P_FORMAT, 128); |
55d85231 | 1521 | self.info = info.replace_info(NACodecTypeInfo::Audio(self.ainfo)); |
0e5eee2d | 1522 | self.chmap = NAChannelMap::from_str(if ainfo.channels == 1 { "C" } else { "L,R" }).unwrap(); |
55d85231 KS |
1523 | Ok(()) |
1524 | } else { | |
1525 | Err(DecoderError::InvalidData) | |
1526 | } | |
1527 | } | |
1528 | fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> { | |
55d85231 KS |
1529 | let info = pkt.get_stream().get_info(); |
1530 | if let NACodecTypeInfo::Audio(_) = info.get_properties() { | |
1531 | let pktbuf = pkt.get_buffer(); | |
1532 | validate!(pktbuf.len() >= 10); | |
1533 | ||
1534 | let mut mr = MemoryReader::new_read(&pktbuf); | |
1535 | let mut br = ByteReader::new(&mut mr); | |
0e5eee2d KS |
1536 | let nblocks = br.read_u16le()? as usize; |
1537 | validate!(nblocks > 0); | |
55d85231 KS |
1538 | |
1539 | let samples = 128 * nblocks; | |
1540 | let abuf = alloc_audio_buffer(self.ainfo, samples, self.chmap.clone())?; | |
0e5eee2d | 1541 | let stride = abuf.get_audio_stride(); |
55d85231 KS |
1542 | let mut adata = abuf.get_abuf_i16().unwrap(); |
1543 | let dst = adata.get_data_mut().unwrap(); | |
1544 | ||
0e5eee2d KS |
1545 | if self.ainfo.channels == 1 { |
1546 | for blk in dst.chunks_exact_mut(128) { | |
1547 | let val = br.read_u16le()?; | |
1548 | if val == 0x00 { continue; } | |
1549 | let mode = val >> 9; | |
1550 | if mode == 0x7F { | |
1551 | self.state[0].decode_intra(&mut br, val, &mut self.buf)?; | |
1552 | } else { | |
1553 | self.state[0].decode_inter(&mut br, val & 0x1FF, mode, &mut self.buf)?; | |
1554 | } | |
1555 | self.output(blk); | |
1556 | } | |
1557 | } else { | |
1558 | let (l, r) = dst.split_at_mut(stride); | |
1559 | for (lblk, rblk) in l.chunks_exact_mut(128).zip(r.chunks_exact_mut(128)) { | |
1560 | let val = br.read_u16le()?; | |
1561 | if val == 0x00 { continue; } | |
1562 | let mode = val >> 9; | |
1563 | if mode == 0x7F { | |
1564 | self.state[0].decode_intra(&mut br, val, &mut self.buf)?; | |
1565 | } else { | |
1566 | self.state[0].decode_inter(&mut br, val & 0x1FF, mode, &mut self.buf)?; | |
1567 | } | |
1568 | self.output(lblk); | |
1569 | let val = br.read_u16le()?; | |
1570 | if val == 0x00 { continue; } | |
1571 | let mode = val >> 9; | |
1572 | if mode == 0x7F { | |
1573 | self.state[1].decode_intra(&mut br, val, &mut self.buf)?; | |
1574 | } else { | |
1575 | self.state[1].decode_inter(&mut br, val & 0x1FF, mode, &mut self.buf)?; | |
1576 | } | |
1577 | self.output(rblk); | |
55d85231 | 1578 | } |
55d85231 KS |
1579 | } |
1580 | ||
1581 | let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), abuf); | |
1582 | frm.set_duration(Some(samples as u64)); | |
1583 | frm.set_keyframe(true); | |
1584 | Ok(frm.into_ref()) | |
1585 | } else { | |
1586 | Err(DecoderError::InvalidData) | |
1587 | } | |
1588 | } | |
1589 | fn flush(&mut self) { | |
1590 | } | |
1591 | } | |
1592 | ||
1593 | ||
1594 | impl NAOptionHandler for VXAudioDecoder { | |
1595 | fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] } | |
1596 | fn set_options(&mut self, _options: &[NAOption]) { } | |
1597 | fn query_option_value(&self, _name: &str) -> Option<NAValue> { None } | |
1598 | } | |
1599 | ||
1600 | ||
1601 | pub fn get_decoder_audio() -> Box<dyn NADecoder + Send> { | |
1602 | Box::new(VXAudioDecoder::new()) | |
1603 | } | |
1604 | ||
1605 | #[cfg(test)] | |
1606 | mod test { | |
1607 | use nihav_core::codecs::RegisteredDecoders; | |
1608 | use nihav_core::demuxers::RegisteredDemuxers; | |
1609 | use nihav_codec_support::test::dec_video::*; | |
1610 | use crate::game_register_all_decoders; | |
1611 | use crate::game_register_all_demuxers; | |
1612 | #[test] | |
1613 | fn test_vx_video() { | |
1614 | let mut dmx_reg = RegisteredDemuxers::new(); | |
1615 | game_register_all_demuxers(&mut dmx_reg); | |
1616 | let mut dec_reg = RegisteredDecoders::new(); | |
1617 | game_register_all_decoders(&mut dec_reg); | |
1618 | ||
886cde48 | 1619 | // sample from some game |
55d85231 KS |
1620 | test_decoding("vx", "vxvideo", "assets/Game/bioware.vx", Some(31), &dmx_reg, &dec_reg, |
1621 | ExpectedTestResult::MD5Frames(vec![ | |
1622 | [0x33de14fa, 0x00948eb7, 0x028141d7, 0x1d07abd6], | |
2451e953 KS |
1623 | [0x77a96135, 0x0cc2d0b5, 0x45862c7c, 0xe27f5b10], |
1624 | [0x3c3ed089, 0x3c643216, 0xe6aed381, 0x4d43c50f], | |
1625 | [0x09e86330, 0x37d3a766, 0xa8198ac5, 0x21fa089c], | |
1626 | [0xbcab34d7, 0xdffe234a, 0x6534709f, 0xc3050e32], | |
1627 | [0x2bab595d, 0x7a19937e, 0xccc97277, 0x91b32191], | |
1628 | [0xe082f77e, 0x6498fd0d, 0xa3828c0f, 0xb4f7a02a], | |
1629 | [0x8515f6e2, 0xc0cb8ab3, 0xf91a3483, 0xd54470fc], | |
1630 | [0x17b1b54a, 0x1b574323, 0xcdeec1ec, 0x7a00ae4e], | |
1631 | [0x773f1d47, 0x86188681, 0xb111bcb8, 0x80fe34e9], | |
1632 | [0xbc4a8e20, 0xca91d4b6, 0x7275a162, 0x9a73be7c], | |
1633 | [0x0d4992b5, 0xd12a985a, 0x929ebec2, 0x0653fbc7], | |
1634 | [0xc24691b7, 0xabd27a7a, 0xd62cbd73, 0xd72a49ea], | |
1635 | [0x9024f7f4, 0xbe707e73, 0x27b4b4a0, 0x33bb515e], | |
1636 | [0x31aee8fc, 0xd0a3fa6d, 0xea11ef6a, 0x53a5f031], | |
1637 | [0x4a83f326, 0xceff4329, 0x54fbe91e, 0xf98ee74b], | |
1638 | [0xe54b5450, 0x979f4b26, 0x910ee666, 0x05fd1996], | |
1639 | [0xe48d66d0, 0x0a69b963, 0x9917084e, 0xf4b0486d], | |
1640 | [0x624a8b32, 0x0d1ce036, 0x9de8ebf0, 0x472a77b9], | |
1641 | [0x5d307d48, 0x1168f3a9, 0xaa792fb2, 0x34430b20], | |
1642 | [0xf2d80474, 0xac6b0972, 0x500e569e, 0x3c8e7dde], | |
1643 | [0x481310b3, 0x70cdeb91, 0xed007972, 0x70cefff3], | |
1644 | [0x8b5b17ca, 0xca6f9a72, 0x0256908a, 0x4505cf85], | |
1645 | [0xb6222c1d, 0x7a9760cb, 0xb3276304, 0x2ff1595e], | |
1646 | [0xf98e3d89, 0xae957c83, 0xff849c05, 0x8ca54276], | |
1647 | [0xbcebda1c, 0x6f6e4ac6, 0x023e7f0f, 0x9578142f], | |
1648 | [0x399f5155, 0xd95b33e3, 0xf0b55af8, 0xe32db6b2], | |
1649 | [0x0c4d4347, 0x5f5061e4, 0xe2fa4690, 0xa340d294], | |
1650 | [0x6fcdddb5, 0xf101da80, 0x6f55ddd9, 0x0dfeead1], | |
1651 | [0xb9623043, 0x1dab8a93, 0x22fd5f7a, 0x2c2a6633], | |
1652 | [0xb3ac2652, 0xf474e49d, 0x7db51405, 0xcd1c13cc], | |
1653 | [0x6a901339, 0xda88b2be, 0x6d943e18, 0xda9b5926]])); | |
55d85231 | 1654 | } |
0e5eee2d KS |
1655 | #[test] |
1656 | fn test_vx_audio() { | |
1657 | let mut dmx_reg = RegisteredDemuxers::new(); | |
1658 | game_register_all_demuxers(&mut dmx_reg); | |
1659 | let mut dec_reg = RegisteredDecoders::new(); | |
1660 | game_register_all_decoders(&mut dec_reg); | |
1661 | ||
1662 | // sample from some game | |
1663 | test_decoding("vx", "vxaudio", "assets/Game/bioware.vx", Some(100), &dmx_reg, &dec_reg, | |
1664 | ExpectedTestResult::MD5([0xf149848a, 0xd80054d2, 0x278535ff, 0x956ebed7])); | |
1665 | } | |
55d85231 KS |
1666 | } |
1667 | ||
1668 | const NC_MAP: [usize; 8] = [ 0, 0, 1, 1, 2, 2, 2, 2 ]; | |
1669 | const NC_BITS: [[u16; 68]; 3] = [ | |
1670 | [ | |
1671 | 0x0001, 0x0000, 0x0000, 0x0000, 0x0005, 0x0001, 0x0000, 0x0000, | |
1672 | 0x0007, 0x0004, 0x0001, 0x0000, 0x0007, 0x0006, 0x0005, 0x0003, | |
1673 | 0x0007, 0x0006, 0x0005, 0x0003, 0x0007, 0x0006, 0x0005, 0x0004, | |
1674 | 0x000F, 0x0006, 0x0005, 0x0004, 0x000B, 0x000E, 0x0005, 0x0004, | |
1675 | 0x0008, 0x000A, 0x000D, 0x0004, 0x000F, 0x000E, 0x0009, 0x0004, | |
1676 | 0x000B, 0x000A, 0x000D, 0x000C, 0x000F, 0x000E, 0x0009, 0x000C, | |
1677 | 0x000B, 0x000A, 0x000D, 0x0008, 0x000F, 0x0001, 0x0009, 0x000C, | |
1678 | 0x000B, 0x000E, 0x000D, 0x0008, 0x0007, 0x000A, 0x0009, 0x000C, | |
1679 | 0x0004, 0x0006, 0x0005, 0x0008 | |
1680 | ], [ | |
1681 | 0x0003, 0x0000, 0x0000, 0x0000, 0x000B, 0x0002, 0x0000, 0x0000, | |
1682 | 0x0007, 0x0007, 0x0003, 0x0000, 0x0007, 0x000A, 0x0009, 0x0005, | |
1683 | 0x0007, 0x0006, 0x0005, 0x0004, 0x0004, 0x0006, 0x0005, 0x0006, | |
1684 | 0x0007, 0x0006, 0x0005, 0x0008, 0x000F, 0x0006, 0x0005, 0x0004, | |
1685 | 0x000B, 0x000E, 0x000D, 0x0004, 0x000F, 0x000A, 0x0009, 0x0004, | |
1686 | 0x000B, 0x000E, 0x000D, 0x000C, 0x0008, 0x000A, 0x0009, 0x0008, | |
1687 | 0x000F, 0x000E, 0x000D, 0x000C, 0x000B, 0x000A, 0x0009, 0x000C, | |
1688 | 0x0007, 0x000B, 0x0006, 0x0008, 0x0009, 0x0008, 0x000A, 0x0001, | |
1689 | 0x0007, 0x0006, 0x0005, 0x0004 | |
1690 | ], [ | |
1691 | 0x000F, 0x0000, 0x0000, 0x0000, 0x000F, 0x000E, 0x0000, 0x0000, | |
1692 | 0x000B, 0x000F, 0x000D, 0x0000, 0x0008, 0x000C, 0x000E, 0x000C, | |
1693 | 0x000F, 0x000A, 0x000B, 0x000B, 0x000B, 0x0008, 0x0009, 0x000A, | |
1694 | 0x0009, 0x000E, 0x000D, 0x0009, 0x0008, 0x000A, 0x0009, 0x0008, | |
1695 | 0x000F, 0x000E, 0x000D, 0x000D, 0x000B, 0x000E, 0x000A, 0x000C, | |
1696 | 0x000F, 0x000A, 0x000D, 0x000C, 0x000B, 0x000E, 0x0009, 0x000C, | |
1697 | 0x0008, 0x000A, 0x000D, 0x0008, 0x000D, 0x0007, 0x0009, 0x000C, | |
1698 | 0x0009, 0x000C, 0x000B, 0x000A, 0x0005, 0x0008, 0x0007, 0x0006, | |
1699 | 0x0001, 0x0004, 0x0003, 0x0002 | |
1700 | ] | |
1701 | ]; | |
1702 | const NC_LENS: [[u8; 68]; 3] = [ | |
1703 | [ | |
1704 | 1, 0, 0, 0, 6, 2, 0, 0, | |
1705 | 8, 6, 3, 0, 9, 8, 7, 5, | |
1706 | 10, 9, 8, 6, 11, 10, 9, 7, | |
1707 | 13, 11, 10, 8, 13, 13, 11, 9, | |
1708 | 13, 13, 13, 10, 14, 14, 13, 11, | |
1709 | 14, 14, 14, 13, 15, 15, 14, 14, | |
1710 | 15, 15, 15, 14, 16, 15, 15, 15, | |
1711 | 16, 16, 16, 15, 16, 16, 16, 16, | |
1712 | 16, 16, 16, 16 | |
1713 | ], [ | |
1714 | 2, 0, 0, 0, 6, 2, 0, 0, | |
1715 | 6, 5, 3, 0, 7, 6, 6, 4, | |
1716 | 8, 6, 6, 4, 8, 7, 7, 5, | |
1717 | 9, 8, 8, 6, 11, 9, 9, 6, | |
1718 | 11, 11, 11, 7, 12, 11, 11, 9, | |
1719 | 12, 12, 12, 11, 12, 12, 12, 11, | |
1720 | 13, 13, 13, 12, 13, 13, 13, 13, | |
1721 | 13, 14, 13, 13, 14, 14, 14, 13, | |
1722 | 14, 14, 14, 14 | |
1723 | ], [ | |
1724 | 4, 0, 0, 0, 6, 4, 0, 0, | |
1725 | 6, 5, 4, 0, 6, 5, 5, 4, | |
1726 | 7, 5, 5, 4, 7, 5, 5, 4, | |
1727 | 7, 6, 6, 4, 7, 6, 6, 4, | |
1728 | 8, 7, 7, 5, 8, 8, 7, 6, | |
1729 | 9, 8, 8, 7, 9, 9, 8, 8, | |
1730 | 9, 9, 9, 8, 10, 9, 9, 9, | |
1731 | 10, 10, 10, 10, 10, 10, 10, 10, | |
1732 | 10, 10, 10, 10 | |
1733 | ] | |
1734 | ]; | |
1735 | ||
1736 | const NUM_ZERO_BITS: [[u8; 16]; 15] = [ | |
1737 | [ | |
1738 | 0x01, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x01 | |
1739 | ], [ | |
1740 | 0x07, 0x06, 0x05, 0x04, 0x03, 0x05, 0x04, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x01, 0x00, 0x00 | |
1741 | ], [ | |
1742 | 0x05, 0x07, 0x06, 0x05, 0x04, 0x03, 0x04, 0x03, 0x02, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00 | |
1743 | ], [ | |
1744 | 0x03, 0x07, 0x05, 0x04, 0x06, 0x05, 0x04, 0x03, 0x03, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00 | |
1745 | ], [ | |
1746 | 0x05, 0x04, 0x03, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 | |
1747 | ], [ | |
1748 | 0x01, 0x01, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | |
1749 | ], [ | |
1750 | 0x01, 0x01, 0x05, 0x04, 0x03, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | |
1751 | ], [ | |
1752 | 0x01, 0x01, 0x01, 0x03, 0x03, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | |
1753 | ], [ | |
1754 | 0x01, 0x00, 0x01, 0x03, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | |
1755 | ], [ | |
1756 | 0x01, 0x00, 0x01, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | |
1757 | ], [ | |
1758 | 0x00, 0x01, 0x01, 0x02, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | |
1759 | ], [ | |
1760 | 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | |
1761 | ], [ | |
1762 | 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | |
1763 | ], [ | |
1764 | 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | |
1765 | ], [ | |
1766 | 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | |
1767 | ] | |
1768 | ]; | |
1769 | const NUM_ZERO_LENS: [[u8; 16]; 15] = [ | |
1770 | [ 1, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9 ], | |
1771 | [ 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 6, 6, 0 ], | |
1772 | [ 4, 3, 3, 3, 4, 4, 3, 3, 4, 5, 5, 6, 5, 6, 0, 0 ], | |
1773 | [ 5, 3, 4, 4, 3, 3, 3, 4, 3, 4, 5, 5, 5, 0, 0, 0 ], | |
1774 | [ 4, 4, 4, 3, 3, 3, 3, 3, 4, 5, 4, 5, 0, 0, 0, 0 ], | |
1775 | [ 6, 5, 3, 3, 3, 3, 3, 3, 4, 3, 6, 0, 0, 0, 0, 0 ], | |
1776 | [ 6, 5, 3, 3, 3, 2, 3, 4, 3, 6, 0, 0, 0, 0, 0, 0 ], | |
1777 | [ 6, 4, 5, 3, 2, 2, 3, 3, 6, 0, 0, 0, 0, 0, 0, 0 ], | |
1778 | [ 6, 6, 4, 2, 2, 3, 2, 5, 0, 0, 0, 0, 0, 0, 0, 0 ], | |
1779 | [ 5, 5, 3, 2, 2, 2, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], | |
1780 | [ 4, 4, 3, 3, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], | |
1781 | [ 4, 4, 2, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], | |
1782 | [ 3, 3, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], | |
1783 | [ 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], | |
1784 | [ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] | |
1785 | ]; | |
1786 | ||
1787 | const ZERO_RUN_BITS: [[u8; 8]; 6] = [ | |
1788 | [ 1, 0, 0, 0, 0, 0, 0, 0 ], | |
1789 | [ 1, 1, 0, 0, 0, 0, 0, 0 ], | |
1790 | [ 3, 2, 1, 0, 0, 0, 0, 0 ], | |
1791 | [ 3, 2, 1, 1, 0, 0, 0, 0 ], | |
1792 | [ 3, 2, 3, 2, 1, 0, 0, 0 ], | |
1793 | [ 3, 0, 1, 3, 2, 5, 4, 0 ] | |
1794 | ]; | |
1795 | const ZERO_RUN_LENS: [[u8; 8]; 6] = [ | |
1796 | [ 1, 1, 0, 0, 0, 0, 0, 0 ], | |
1797 | [ 1, 2, 2, 0, 0, 0, 0, 0 ], | |
1798 | [ 2, 2, 2, 2, 0, 0, 0, 0 ], | |
1799 | [ 2, 2, 2, 3, 3, 0, 0, 0 ], | |
1800 | [ 2, 2, 3, 3, 3, 3, 0, 0 ], | |
1801 | [ 2, 3, 3, 3, 3, 3, 3, 0 ] | |
1802 | ]; | |
1803 |