]> git.nihav.org Git - nihav.git/blame_incremental - nihav-game/src/codecs/vx.rs
vx: update test after fixes
[nihav.git] / nihav-game / src / codecs / vx.rs
... / ...
CommitLineData
1use nihav_core::codecs::*;
2use nihav_core::io::byteio::*;
3use nihav_core::io::bitreader::*;
4use nihav_core::io::codebook::*;
5use nihav_core::io::intcode::*;
6use std::str::FromStr;
7
8use std::ops::*;
9
10#[derive(Clone,Copy,Default,Debug,PartialEq)]
11struct MV {
12 x: i8,
13 y: i8,
14}
15
16impl 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
21impl AddAssign for MV {
22 fn add_assign(&mut self, other: MV) { self.x += other.x; self.y += other.y; }
23}
24
25impl 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
30impl SubAssign for MV {
31 fn sub_assign(&mut self, other: MV) { self.x -= other.x; self.y -= other.y; }
32}
33
34impl 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
48trait 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
54impl<'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
71const CUR_BUF: usize = 3;
72const CHROMA_OFF: usize = 256 * 256;
73
74macro_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
108fn 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}
149fn 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
184fn 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
193fn 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
202fn avg(a: u8, b: u8) -> u8 {
203 ((u16::from(a) + u16::from(b) + 1) >> 1) as u8
204}
205fn avg_nr(a: u8, b: u8) -> u8 {
206 ((u16::from(a) + u16::from(b)) >> 1) as u8
207}
208fn 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
212fn 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}
238fn 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}
265fn 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}
292fn 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;
307 let pix = interp2(tl, l0, l1);
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}
319fn 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}
346fn 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
371fn 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);
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);
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}
419fn 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];
422 let pred = avg(tr, dl).wrapping_add(delta as u8);
423 blk[pos + 256 * (h - 1) + w - 1] = pred;
424 pred_plane(blk, pos, w, h);
425}
426
427struct Codebooks {
428 nc_cb: [Codebook<u8>; 3],
429 num_zero_cb: [Codebook<u8>; 15],
430 zero_run_cb: [Codebook<u8>; 6],
431}
432
433fn map_idx(idx: usize) -> u8 { idx as u8 }
434macro_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
441impl 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
477macro_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
492fn 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
504fn 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
578const NCSTRIDE: usize = 64 + 1;
579
580struct 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
596impl 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);
655
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);
667
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
902const 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
909impl 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();
949 validate!(src.len() > 0);
950
951 let mut br = BitReader::new(&src[0..], BitReaderMode::LE16MSB);
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
990impl 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
997pub fn get_decoder_video() -> Box<dyn NADecoder + Send> {
998 Box::new(VXVideoDecoder::new())
999}
1000
1001
1002struct AudioState {
1003 lpc0_idx: usize,
1004 lpc1_idx: usize,
1005 lpc2_idx: usize,
1006 scale: i32,
1007 frame_mode: usize,
1008 cur_filt: [i32; 8],
1009
1010 lpc0_cb: [[i16; 8]; 64],
1011 lpc1_cb: [[i16; 8]; 64],
1012 lpc2_cb: [[i16; 8]; 64],
1013 decays: [i32; 8],
1014 base_filt: [i32; 8],
1015 base_scale: i32,
1016}
1017
1018impl AudioState {
1019 fn new() -> Self {
1020 Self {
1021 lpc0_idx: 0,
1022 lpc1_idx: 0,
1023 lpc2_idx: 0,
1024 scale: 0,
1025 frame_mode: 0,
1026 cur_filt: [0; 8],
1027
1028 lpc0_cb: [[0; 8]; 64],
1029 lpc1_cb: [[0; 8]; 64],
1030 lpc2_cb: [[0; 8]; 64],
1031 decays: [0; 8],
1032 base_filt: [0; 8],
1033 base_scale: 0,
1034 }
1035 }
1036 fn read_initial_params(&mut self, br: &mut ByteReader) -> DecoderResult<()> {
1037 for entry in self.lpc0_cb.iter_mut() {
1038 for el in entry.iter_mut() {
1039 *el = br.read_u16le()? as i16;
1040 }
1041 }
1042 for entry in self.lpc1_cb.iter_mut() {
1043 for el in entry.iter_mut() {
1044 *el = br.read_u16le()? as i16;
1045 }
1046 }
1047 for entry in self.lpc2_cb.iter_mut() {
1048 for el in entry.iter_mut() {
1049 *el = br.read_u16le()? as i16;
1050 }
1051 }
1052 for el in self.decays.iter_mut() {
1053 *el = i32::from(br.read_u16le()? as i16);
1054 }
1055 for el in self.base_filt.iter_mut() {
1056 *el = br.read_u32le()? as i32;
1057 }
1058 self.base_scale = br.read_u32le()? as i32;
1059 Ok(())
1060 }
1061 fn unpack_data(&mut self, br: &mut ByteReader, val: u16, dst: &mut [i32]) -> DecoderResult<()> {
1062 self.lpc0_idx = (val & 0x3F) as usize;
1063 self.scale = (self.decays[((val >> 6) & 7) as usize] * self.scale) >> 13;
1064 let val1 = br.read_u16le()?;
1065 self.lpc1_idx = ((val1 >> 6) & 0x3F) as usize;
1066 self.lpc2_idx = (val1 & 0x3F) as usize;
1067 self.frame_mode = ((val1 >> 12) & 3) as usize;
1068 let mut idx = (val1 >> 14) as usize;
1069 if self.frame_mode == 0 {
1070 let mut tail = 0;
1071 for _ in 0..8 {
1072 let val = br.read_u16le()?;
1073 for i in 0..5 {
1074 let add = i32::from((val >> (13 - i * 3)) & 7);
1075 dst[idx] += self.scale * (add * 2 - 7);
1076 idx += 3;
1077 }
1078 tail = tail * 2 + (val & 1);
1079 }
1080 let add = i32::from((tail >> 5) & 7);
1081 dst[idx] += self.scale * (add * 2 - 7);
1082 idx += 3;
1083 let add = i32::from((tail >> 2) & 7);
1084 dst[idx] += self.scale * (add * 2 - 7);
1085 } else {
1086 let (len, step) = match self.frame_mode {
1087 1 => (5, 3),
1088 2 => (4, 4),
1089 3 => (3, 5),
1090 _ => unreachable!(),
1091 };
1092 idx += 128;
1093 for _ in 0..len {
1094 let val = br.read_u16le()?;
1095 for i in 0..8 {
1096 let add = i32::from((val >> (14 - i * 2)) & 3);
1097 dst[idx] += self.scale * (add * 2 - 3);
1098 idx += step;
1099 }
1100 }
1101 }
1102 Ok(())
1103 }
1104 fn update_intra(&mut self) {
1105 self.cur_filt = self.base_filt;
1106 for i in 0..8 {
1107 self.cur_filt[i] += i32::from(self.lpc0_cb[self.lpc0_idx][i]);
1108 self.cur_filt[i] += i32::from(self.lpc1_cb[self.lpc1_idx][i]);
1109 self.cur_filt[i] += i32::from(self.lpc2_cb[self.lpc2_idx][i]);
1110 }
1111 }
1112 fn update_inter(&mut self) {
1113 for i in 0..8 {
1114 self.cur_filt[i] += i32::from(self.lpc0_cb[self.lpc0_idx][i]);
1115 self.cur_filt[i] += i32::from(self.lpc1_cb[self.lpc1_idx][i]);
1116 self.cur_filt[i] += i32::from(self.lpc2_cb[self.lpc2_idx][i]);
1117 }
1118 }
1119}
1120
1121fn apply_lpc(dst: &mut [i32], src: &[i32], hist: &mut [i32], filt: &[i32; 8]) {
1122 let mut hidx = 0;
1123 for (out, src) in dst.iter_mut().zip(src.iter()) {
1124 let mut sum = *src << 14;
1125 for i in 0..8 {
1126 sum += hist[(hidx + i) & 7] * filt[i];
1127 }
1128 let samp = sum >> 14;
1129 *out = samp;
1130 hist[hidx & 7] = samp;
1131 hidx += 1;
1132 }
1133}
1134
1135struct VXAudioDecoder {
1136 ainfo: NAAudioInfo,
1137 info: Arc<NACodecInfo>,
1138 chmap: NAChannelMap,
1139 buf: [i32; 256 * 2],
1140 flip_buf: bool,
1141 state: AudioState,
1142 lpc_hist: [i32; 8],
1143 lpc_filt: [i32; 8],
1144 lpc_filt1: [i32; 8],
1145}
1146
1147impl VXAudioDecoder {
1148 fn new() -> Self {
1149 Self {
1150 ainfo: NAAudioInfo::new(0, 1, SND_S16P_FORMAT, 0),
1151 info: NACodecInfo::new_dummy(),
1152 chmap: NAChannelMap::new(),
1153 buf: [0; 256 * 2],
1154 flip_buf: true,
1155 state: AudioState::new(),
1156 lpc_hist: [0; 8],
1157 lpc_filt: [0; 8],
1158 lpc_filt1: [0; 8],
1159 }
1160 }
1161 fn decode_inter(&mut self, br: &mut ByteReader, mode: u16, val: u16) -> DecoderResult<()> {
1162 let (mut cur_buf, mut prev_buf) = self.buf.split_at_mut(256);
1163 if self.flip_buf {
1164 std::mem::swap(&mut cur_buf, &mut prev_buf);
1165 }
1166 cur_buf[0..128].copy_from_slice(&prev_buf[128..]);
1167 if mode == 0x7E {
1168 for el in cur_buf[128..].iter_mut() {
1169 *el = 0;
1170 }
1171 } else {
1172 let src = &prev_buf[127 - (mode as usize)..];
1173 let dst = &mut cur_buf[128..];
1174 for i in 0..7 {
1175 dst[i] = (src[i] * ((i + 1) as i32)) >> 4;
1176 }
1177 for i in 7..121 {
1178 dst[i] = src[i] >> 1;
1179 }
1180 for i in 121..128 {
1181 dst[i] = (src[i] * ((128 - i) as i32)) >> 4;
1182 }
1183 }
1184
1185 self.state.unpack_data(br, val, prev_buf )?;
1186 self.state.update_inter();
1187
1188 let (cfilt, pfilt) = if !self.flip_buf {
1189 (&mut self.lpc_filt, &mut self.lpc_filt1)
1190 } else {
1191 (&mut self.lpc_filt1, &mut self.lpc_filt)
1192 };
1193 *cfilt = self.state.cur_filt;
1194 let mut f0 = [0; 8];
1195 let mut f1 = [0; 8];
1196 let mut f2 = [0; 8];
1197 for i in 0..8 {
1198 f1[i] = (pfilt[i] + cfilt[i]) >> 1;
1199 f0[i] = (pfilt[i] + f1 [i]) >> 1;
1200 f2[i] = (f1 [i] + cfilt[i]) >> 1;
1201 }
1202 apply_lpc(&mut cur_buf[ 0..][..32], &prev_buf[128..], &mut self.lpc_hist, &f0);
1203 apply_lpc(&mut cur_buf[32..][..32], &prev_buf[128 + 32..], &mut self.lpc_hist, &f1);
1204 apply_lpc(&mut cur_buf[64..][..32], &prev_buf[128 + 64..], &mut self.lpc_hist, &f2);
1205 apply_lpc(&mut cur_buf[96..][..32], &prev_buf[128 + 96..], &mut self.lpc_hist, &cfilt);
1206 Ok(())
1207 }
1208 fn decode_intra(&mut self, br: &mut ByteReader, val: u16) -> DecoderResult<()> {
1209 self.state.scale = self.state.base_scale;
1210 self.lpc_hist = [0; 8];
1211 self.flip_buf = true;
1212
1213 let (mut cur_buf, mut prev_buf) = self.buf.split_at_mut(256);
1214 if self.flip_buf {
1215 std::mem::swap(&mut cur_buf, &mut prev_buf);
1216 }
1217 for el in cur_buf[128..].iter_mut() {
1218 *el = 0;
1219 }
1220 self.state.unpack_data(br, val, prev_buf)?;
1221 self.state.update_intra();
1222
1223 self.lpc_filt = self.state.cur_filt;
1224 apply_lpc(&mut cur_buf[..128], &prev_buf[128..], &mut self.lpc_hist, &self.lpc_filt);
1225 Ok(())
1226 }
1227 fn output(&mut self, dst: &mut [i16]) {
1228 let src = if self.flip_buf { &self.buf[256..][..128] } else { &self.buf[..128] };
1229 for (src, dst) in src.iter().zip(dst.iter_mut()) {
1230 *dst = (*src).max(-0x8000).min(0x7FFF) as i16;
1231 }
1232 self.flip_buf = !self.flip_buf;
1233 }
1234}
1235
1236impl NADecoder for VXAudioDecoder {
1237 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
1238 if let NACodecTypeInfo::Audio(ainfo) = info.get_properties() {
1239 if let Some(edata) = info.get_extradata() {
1240 validate!(edata.len() >= 3124);
1241 let mut mr = MemoryReader::new_read(edata.as_slice());
1242 let mut br = ByteReader::new(&mut mr);
1243 self.state.read_initial_params(&mut br)?;
1244 } else {
1245 return Err(DecoderError::InvalidData);
1246 }
1247 self.ainfo = NAAudioInfo::new(ainfo.get_sample_rate(), 1, SND_S16_FORMAT, 1);
1248 self.info = info.replace_info(NACodecTypeInfo::Audio(self.ainfo));
1249 self.chmap = NAChannelMap::from_str("C").unwrap();
1250 Ok(())
1251 } else {
1252 Err(DecoderError::InvalidData)
1253 }
1254 }
1255 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
1256 const SUBFRAME_LEN: [usize; 4] = [20, 14, 12, 10];
1257
1258 let info = pkt.get_stream().get_info();
1259 if let NACodecTypeInfo::Audio(_) = info.get_properties() {
1260 let pktbuf = pkt.get_buffer();
1261 validate!(pktbuf.len() >= 10);
1262
1263 let mut mr = MemoryReader::new_read(&pktbuf);
1264 let mut br = ByteReader::new(&mut mr);
1265 let mut nblocks = 0;
1266 while br.left() > 4 {
1267 br.read_skip(2)?;
1268 let val = br.read_u16le()?;
1269 nblocks += 1;
1270 let sf_len = SUBFRAME_LEN[((val >> 12) & 3) as usize];
1271 if br.left() <= sf_len as i64 {
1272 break;
1273 }
1274 br.read_skip(sf_len - 4)?;
1275 }
1276
1277 let samples = 128 * nblocks;
1278 let abuf = alloc_audio_buffer(self.ainfo, samples, self.chmap.clone())?;
1279 let mut adata = abuf.get_abuf_i16().unwrap();
1280 let dst = adata.get_data_mut().unwrap();
1281
1282 let mut mr = MemoryReader::new_read(&pktbuf);
1283 let mut br = ByteReader::new(&mut mr);
1284
1285 let mut blk_no = 0usize;
1286 while br.left() > 0 {
1287 let val = br.read_u16le()?;
1288 let mode = val >> 9;
1289 if mode == 0x7F {
1290 self.decode_intra(&mut br, val)?;
1291 } else {
1292 self.decode_inter(&mut br, val & 0x1FF, mode)?;
1293 }
1294 self.output(&mut dst[blk_no * 128..]);
1295 blk_no += 1;
1296 }
1297
1298 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), abuf);
1299 frm.set_duration(Some(samples as u64));
1300 frm.set_keyframe(true);
1301 Ok(frm.into_ref())
1302 } else {
1303 Err(DecoderError::InvalidData)
1304 }
1305 }
1306 fn flush(&mut self) {
1307 }
1308}
1309
1310
1311impl NAOptionHandler for VXAudioDecoder {
1312 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
1313 fn set_options(&mut self, _options: &[NAOption]) { }
1314 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
1315}
1316
1317
1318pub fn get_decoder_audio() -> Box<dyn NADecoder + Send> {
1319 Box::new(VXAudioDecoder::new())
1320}
1321
1322#[cfg(test)]
1323mod test {
1324 use nihav_core::codecs::RegisteredDecoders;
1325 use nihav_core::demuxers::RegisteredDemuxers;
1326 use nihav_codec_support::test::dec_video::*;
1327 use crate::game_register_all_decoders;
1328 use crate::game_register_all_demuxers;
1329 #[test]
1330 fn test_vx_video() {
1331 let mut dmx_reg = RegisteredDemuxers::new();
1332 game_register_all_demuxers(&mut dmx_reg);
1333 let mut dec_reg = RegisteredDecoders::new();
1334 game_register_all_decoders(&mut dec_reg);
1335
1336 test_decoding("vx", "vxvideo", "assets/Game/bioware.vx", Some(31), &dmx_reg, &dec_reg,
1337 ExpectedTestResult::MD5Frames(vec![
1338 [0x33de14fa, 0x00948eb7, 0x028141d7, 0x1d07abd6],
1339 [0x77a96135, 0x0cc2d0b5, 0x45862c7c, 0xe27f5b10],
1340 [0x3c3ed089, 0x3c643216, 0xe6aed381, 0x4d43c50f],
1341 [0x09e86330, 0x37d3a766, 0xa8198ac5, 0x21fa089c],
1342 [0xbcab34d7, 0xdffe234a, 0x6534709f, 0xc3050e32],
1343 [0x2bab595d, 0x7a19937e, 0xccc97277, 0x91b32191],
1344 [0xe082f77e, 0x6498fd0d, 0xa3828c0f, 0xb4f7a02a],
1345 [0x8515f6e2, 0xc0cb8ab3, 0xf91a3483, 0xd54470fc],
1346 [0x17b1b54a, 0x1b574323, 0xcdeec1ec, 0x7a00ae4e],
1347 [0x773f1d47, 0x86188681, 0xb111bcb8, 0x80fe34e9],
1348 [0xbc4a8e20, 0xca91d4b6, 0x7275a162, 0x9a73be7c],
1349 [0x0d4992b5, 0xd12a985a, 0x929ebec2, 0x0653fbc7],
1350 [0xc24691b7, 0xabd27a7a, 0xd62cbd73, 0xd72a49ea],
1351 [0x9024f7f4, 0xbe707e73, 0x27b4b4a0, 0x33bb515e],
1352 [0x31aee8fc, 0xd0a3fa6d, 0xea11ef6a, 0x53a5f031],
1353 [0x4a83f326, 0xceff4329, 0x54fbe91e, 0xf98ee74b],
1354 [0xe54b5450, 0x979f4b26, 0x910ee666, 0x05fd1996],
1355 [0xe48d66d0, 0x0a69b963, 0x9917084e, 0xf4b0486d],
1356 [0x624a8b32, 0x0d1ce036, 0x9de8ebf0, 0x472a77b9],
1357 [0x5d307d48, 0x1168f3a9, 0xaa792fb2, 0x34430b20],
1358 [0xf2d80474, 0xac6b0972, 0x500e569e, 0x3c8e7dde],
1359 [0x481310b3, 0x70cdeb91, 0xed007972, 0x70cefff3],
1360 [0x8b5b17ca, 0xca6f9a72, 0x0256908a, 0x4505cf85],
1361 [0xb6222c1d, 0x7a9760cb, 0xb3276304, 0x2ff1595e],
1362 [0xf98e3d89, 0xae957c83, 0xff849c05, 0x8ca54276],
1363 [0xbcebda1c, 0x6f6e4ac6, 0x023e7f0f, 0x9578142f],
1364 [0x399f5155, 0xd95b33e3, 0xf0b55af8, 0xe32db6b2],
1365 [0x0c4d4347, 0x5f5061e4, 0xe2fa4690, 0xa340d294],
1366 [0x6fcdddb5, 0xf101da80, 0x6f55ddd9, 0x0dfeead1],
1367 [0xb9623043, 0x1dab8a93, 0x22fd5f7a, 0x2c2a6633],
1368 [0xb3ac2652, 0xf474e49d, 0x7db51405, 0xcd1c13cc],
1369 [0x6a901339, 0xda88b2be, 0x6d943e18, 0xda9b5926]]));
1370 }
1371}
1372
1373const NC_MAP: [usize; 8] = [ 0, 0, 1, 1, 2, 2, 2, 2 ];
1374const NC_BITS: [[u16; 68]; 3] = [
1375 [
1376 0x0001, 0x0000, 0x0000, 0x0000, 0x0005, 0x0001, 0x0000, 0x0000,
1377 0x0007, 0x0004, 0x0001, 0x0000, 0x0007, 0x0006, 0x0005, 0x0003,
1378 0x0007, 0x0006, 0x0005, 0x0003, 0x0007, 0x0006, 0x0005, 0x0004,
1379 0x000F, 0x0006, 0x0005, 0x0004, 0x000B, 0x000E, 0x0005, 0x0004,
1380 0x0008, 0x000A, 0x000D, 0x0004, 0x000F, 0x000E, 0x0009, 0x0004,
1381 0x000B, 0x000A, 0x000D, 0x000C, 0x000F, 0x000E, 0x0009, 0x000C,
1382 0x000B, 0x000A, 0x000D, 0x0008, 0x000F, 0x0001, 0x0009, 0x000C,
1383 0x000B, 0x000E, 0x000D, 0x0008, 0x0007, 0x000A, 0x0009, 0x000C,
1384 0x0004, 0x0006, 0x0005, 0x0008
1385 ], [
1386 0x0003, 0x0000, 0x0000, 0x0000, 0x000B, 0x0002, 0x0000, 0x0000,
1387 0x0007, 0x0007, 0x0003, 0x0000, 0x0007, 0x000A, 0x0009, 0x0005,
1388 0x0007, 0x0006, 0x0005, 0x0004, 0x0004, 0x0006, 0x0005, 0x0006,
1389 0x0007, 0x0006, 0x0005, 0x0008, 0x000F, 0x0006, 0x0005, 0x0004,
1390 0x000B, 0x000E, 0x000D, 0x0004, 0x000F, 0x000A, 0x0009, 0x0004,
1391 0x000B, 0x000E, 0x000D, 0x000C, 0x0008, 0x000A, 0x0009, 0x0008,
1392 0x000F, 0x000E, 0x000D, 0x000C, 0x000B, 0x000A, 0x0009, 0x000C,
1393 0x0007, 0x000B, 0x0006, 0x0008, 0x0009, 0x0008, 0x000A, 0x0001,
1394 0x0007, 0x0006, 0x0005, 0x0004
1395 ], [
1396 0x000F, 0x0000, 0x0000, 0x0000, 0x000F, 0x000E, 0x0000, 0x0000,
1397 0x000B, 0x000F, 0x000D, 0x0000, 0x0008, 0x000C, 0x000E, 0x000C,
1398 0x000F, 0x000A, 0x000B, 0x000B, 0x000B, 0x0008, 0x0009, 0x000A,
1399 0x0009, 0x000E, 0x000D, 0x0009, 0x0008, 0x000A, 0x0009, 0x0008,
1400 0x000F, 0x000E, 0x000D, 0x000D, 0x000B, 0x000E, 0x000A, 0x000C,
1401 0x000F, 0x000A, 0x000D, 0x000C, 0x000B, 0x000E, 0x0009, 0x000C,
1402 0x0008, 0x000A, 0x000D, 0x0008, 0x000D, 0x0007, 0x0009, 0x000C,
1403 0x0009, 0x000C, 0x000B, 0x000A, 0x0005, 0x0008, 0x0007, 0x0006,
1404 0x0001, 0x0004, 0x0003, 0x0002
1405 ]
1406];
1407const NC_LENS: [[u8; 68]; 3] = [
1408 [
1409 1, 0, 0, 0, 6, 2, 0, 0,
1410 8, 6, 3, 0, 9, 8, 7, 5,
1411 10, 9, 8, 6, 11, 10, 9, 7,
1412 13, 11, 10, 8, 13, 13, 11, 9,
1413 13, 13, 13, 10, 14, 14, 13, 11,
1414 14, 14, 14, 13, 15, 15, 14, 14,
1415 15, 15, 15, 14, 16, 15, 15, 15,
1416 16, 16, 16, 15, 16, 16, 16, 16,
1417 16, 16, 16, 16
1418 ], [
1419 2, 0, 0, 0, 6, 2, 0, 0,
1420 6, 5, 3, 0, 7, 6, 6, 4,
1421 8, 6, 6, 4, 8, 7, 7, 5,
1422 9, 8, 8, 6, 11, 9, 9, 6,
1423 11, 11, 11, 7, 12, 11, 11, 9,
1424 12, 12, 12, 11, 12, 12, 12, 11,
1425 13, 13, 13, 12, 13, 13, 13, 13,
1426 13, 14, 13, 13, 14, 14, 14, 13,
1427 14, 14, 14, 14
1428 ], [
1429 4, 0, 0, 0, 6, 4, 0, 0,
1430 6, 5, 4, 0, 6, 5, 5, 4,
1431 7, 5, 5, 4, 7, 5, 5, 4,
1432 7, 6, 6, 4, 7, 6, 6, 4,
1433 8, 7, 7, 5, 8, 8, 7, 6,
1434 9, 8, 8, 7, 9, 9, 8, 8,
1435 9, 9, 9, 8, 10, 9, 9, 9,
1436 10, 10, 10, 10, 10, 10, 10, 10,
1437 10, 10, 10, 10
1438 ]
1439];
1440
1441const NUM_ZERO_BITS: [[u8; 16]; 15] = [
1442 [
1443 0x01, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x01
1444 ], [
1445 0x07, 0x06, 0x05, 0x04, 0x03, 0x05, 0x04, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x01, 0x00, 0x00
1446 ], [
1447 0x05, 0x07, 0x06, 0x05, 0x04, 0x03, 0x04, 0x03, 0x02, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00
1448 ], [
1449 0x03, 0x07, 0x05, 0x04, 0x06, 0x05, 0x04, 0x03, 0x03, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00
1450 ], [
1451 0x05, 0x04, 0x03, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
1452 ], [
1453 0x01, 0x01, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1454 ], [
1455 0x01, 0x01, 0x05, 0x04, 0x03, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1456 ], [
1457 0x01, 0x01, 0x01, 0x03, 0x03, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1458 ], [
1459 0x01, 0x00, 0x01, 0x03, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1460 ], [
1461 0x01, 0x00, 0x01, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1462 ], [
1463 0x00, 0x01, 0x01, 0x02, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1464 ], [
1465 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1466 ], [
1467 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1468 ], [
1469 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1470 ], [
1471 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1472 ]
1473];
1474const NUM_ZERO_LENS: [[u8; 16]; 15] = [
1475 [ 1, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9 ],
1476 [ 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 6, 6, 0 ],
1477 [ 4, 3, 3, 3, 4, 4, 3, 3, 4, 5, 5, 6, 5, 6, 0, 0 ],
1478 [ 5, 3, 4, 4, 3, 3, 3, 4, 3, 4, 5, 5, 5, 0, 0, 0 ],
1479 [ 4, 4, 4, 3, 3, 3, 3, 3, 4, 5, 4, 5, 0, 0, 0, 0 ],
1480 [ 6, 5, 3, 3, 3, 3, 3, 3, 4, 3, 6, 0, 0, 0, 0, 0 ],
1481 [ 6, 5, 3, 3, 3, 2, 3, 4, 3, 6, 0, 0, 0, 0, 0, 0 ],
1482 [ 6, 4, 5, 3, 2, 2, 3, 3, 6, 0, 0, 0, 0, 0, 0, 0 ],
1483 [ 6, 6, 4, 2, 2, 3, 2, 5, 0, 0, 0, 0, 0, 0, 0, 0 ],
1484 [ 5, 5, 3, 2, 2, 2, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
1485 [ 4, 4, 3, 3, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
1486 [ 4, 4, 2, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
1487 [ 3, 3, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
1488 [ 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
1489 [ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
1490];
1491
1492const ZERO_RUN_BITS: [[u8; 8]; 6] = [
1493 [ 1, 0, 0, 0, 0, 0, 0, 0 ],
1494 [ 1, 1, 0, 0, 0, 0, 0, 0 ],
1495 [ 3, 2, 1, 0, 0, 0, 0, 0 ],
1496 [ 3, 2, 1, 1, 0, 0, 0, 0 ],
1497 [ 3, 2, 3, 2, 1, 0, 0, 0 ],
1498 [ 3, 0, 1, 3, 2, 5, 4, 0 ]
1499];
1500const ZERO_RUN_LENS: [[u8; 8]; 6] = [
1501 [ 1, 1, 0, 0, 0, 0, 0, 0 ],
1502 [ 1, 2, 2, 0, 0, 0, 0, 0 ],
1503 [ 2, 2, 2, 2, 0, 0, 0, 0 ],
1504 [ 2, 2, 2, 3, 3, 0, 0, 0 ],
1505 [ 2, 2, 3, 3, 3, 3, 0, 0 ],
1506 [ 2, 3, 3, 3, 3, 3, 3, 0 ]
1507];
1508