]>
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(); | |
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 | ||
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 | ||
1001 | ||
1002 | struct 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 | ||
1018 | impl 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()?; | |
1bab3697 | 1095 | for i in 0..8 { |
55d85231 KS |
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 | ||
1121 | fn apply_lpc(dst: &mut [i32], src: &[i32], hist: &mut [i32], filt: &[i32; 8]) { | |
016340a0 | 1122 | for (hidx, (out, src)) in dst.iter_mut().zip(src.iter()).enumerate() { |
55d85231 KS |
1123 | let mut sum = *src << 14; |
1124 | for i in 0..8 { | |
1125 | sum += hist[(hidx + i) & 7] * filt[i]; | |
1126 | } | |
1127 | let samp = sum >> 14; | |
1128 | *out = samp; | |
1129 | hist[hidx & 7] = samp; | |
55d85231 KS |
1130 | } |
1131 | } | |
1132 | ||
1133 | struct VXAudioDecoder { | |
1134 | ainfo: NAAudioInfo, | |
1135 | info: Arc<NACodecInfo>, | |
1136 | chmap: NAChannelMap, | |
1137 | buf: [i32; 256 * 2], | |
1138 | flip_buf: bool, | |
1139 | state: AudioState, | |
1140 | lpc_hist: [i32; 8], | |
1141 | lpc_filt: [i32; 8], | |
1142 | lpc_filt1: [i32; 8], | |
1143 | } | |
1144 | ||
1145 | impl VXAudioDecoder { | |
1146 | fn new() -> Self { | |
1147 | Self { | |
1148 | ainfo: NAAudioInfo::new(0, 1, SND_S16P_FORMAT, 0), | |
1149 | info: NACodecInfo::new_dummy(), | |
1150 | chmap: NAChannelMap::new(), | |
1151 | buf: [0; 256 * 2], | |
1152 | flip_buf: true, | |
1153 | state: AudioState::new(), | |
1154 | lpc_hist: [0; 8], | |
1155 | lpc_filt: [0; 8], | |
1156 | lpc_filt1: [0; 8], | |
1157 | } | |
1158 | } | |
1159 | fn decode_inter(&mut self, br: &mut ByteReader, mode: u16, val: u16) -> DecoderResult<()> { | |
1160 | let (mut cur_buf, mut prev_buf) = self.buf.split_at_mut(256); | |
1161 | if self.flip_buf { | |
1162 | std::mem::swap(&mut cur_buf, &mut prev_buf); | |
1163 | } | |
1164 | cur_buf[0..128].copy_from_slice(&prev_buf[128..]); | |
1165 | if mode == 0x7E { | |
1166 | for el in cur_buf[128..].iter_mut() { | |
1167 | *el = 0; | |
1168 | } | |
1169 | } else { | |
1170 | let src = &prev_buf[127 - (mode as usize)..]; | |
1171 | let dst = &mut cur_buf[128..]; | |
1172 | for i in 0..7 { | |
1173 | dst[i] = (src[i] * ((i + 1) as i32)) >> 4; | |
1174 | } | |
1175 | for i in 7..121 { | |
1176 | dst[i] = src[i] >> 1; | |
1177 | } | |
1178 | for i in 121..128 { | |
1179 | dst[i] = (src[i] * ((128 - i) as i32)) >> 4; | |
1180 | } | |
1181 | } | |
1182 | ||
1183 | self.state.unpack_data(br, val, prev_buf )?; | |
1184 | self.state.update_inter(); | |
1185 | ||
1186 | let (cfilt, pfilt) = if !self.flip_buf { | |
1187 | (&mut self.lpc_filt, &mut self.lpc_filt1) | |
1188 | } else { | |
1189 | (&mut self.lpc_filt1, &mut self.lpc_filt) | |
1190 | }; | |
1191 | *cfilt = self.state.cur_filt; | |
1192 | let mut f0 = [0; 8]; | |
1193 | let mut f1 = [0; 8]; | |
1194 | let mut f2 = [0; 8]; | |
1195 | for i in 0..8 { | |
1196 | f1[i] = (pfilt[i] + cfilt[i]) >> 1; | |
1197 | f0[i] = (pfilt[i] + f1 [i]) >> 1; | |
1198 | f2[i] = (f1 [i] + cfilt[i]) >> 1; | |
1199 | } | |
1200 | apply_lpc(&mut cur_buf[ 0..][..32], &prev_buf[128..], &mut self.lpc_hist, &f0); | |
1201 | apply_lpc(&mut cur_buf[32..][..32], &prev_buf[128 + 32..], &mut self.lpc_hist, &f1); | |
1202 | apply_lpc(&mut cur_buf[64..][..32], &prev_buf[128 + 64..], &mut self.lpc_hist, &f2); | |
1203 | apply_lpc(&mut cur_buf[96..][..32], &prev_buf[128 + 96..], &mut self.lpc_hist, &cfilt); | |
1204 | Ok(()) | |
1205 | } | |
1206 | fn decode_intra(&mut self, br: &mut ByteReader, val: u16) -> DecoderResult<()> { | |
1207 | self.state.scale = self.state.base_scale; | |
1208 | self.lpc_hist = [0; 8]; | |
1209 | self.flip_buf = true; | |
1210 | ||
1211 | let (mut cur_buf, mut prev_buf) = self.buf.split_at_mut(256); | |
1212 | if self.flip_buf { | |
1213 | std::mem::swap(&mut cur_buf, &mut prev_buf); | |
1214 | } | |
1215 | for el in cur_buf[128..].iter_mut() { | |
1216 | *el = 0; | |
1217 | } | |
1218 | self.state.unpack_data(br, val, prev_buf)?; | |
1219 | self.state.update_intra(); | |
1220 | ||
1221 | self.lpc_filt = self.state.cur_filt; | |
1222 | apply_lpc(&mut cur_buf[..128], &prev_buf[128..], &mut self.lpc_hist, &self.lpc_filt); | |
1223 | Ok(()) | |
1224 | } | |
1225 | fn output(&mut self, dst: &mut [i16]) { | |
1226 | let src = if self.flip_buf { &self.buf[256..][..128] } else { &self.buf[..128] }; | |
1227 | for (src, dst) in src.iter().zip(dst.iter_mut()) { | |
1228 | *dst = (*src).max(-0x8000).min(0x7FFF) as i16; | |
1229 | } | |
1230 | self.flip_buf = !self.flip_buf; | |
1231 | } | |
1232 | } | |
1233 | ||
1234 | impl NADecoder for VXAudioDecoder { | |
1235 | fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> { | |
1236 | if let NACodecTypeInfo::Audio(ainfo) = info.get_properties() { | |
1237 | if let Some(edata) = info.get_extradata() { | |
1238 | validate!(edata.len() >= 3124); | |
1239 | let mut mr = MemoryReader::new_read(edata.as_slice()); | |
1240 | let mut br = ByteReader::new(&mut mr); | |
1241 | self.state.read_initial_params(&mut br)?; | |
1242 | } else { | |
1243 | return Err(DecoderError::InvalidData); | |
1244 | } | |
1245 | self.ainfo = NAAudioInfo::new(ainfo.get_sample_rate(), 1, SND_S16_FORMAT, 1); | |
1246 | self.info = info.replace_info(NACodecTypeInfo::Audio(self.ainfo)); | |
1247 | self.chmap = NAChannelMap::from_str("C").unwrap(); | |
1248 | Ok(()) | |
1249 | } else { | |
1250 | Err(DecoderError::InvalidData) | |
1251 | } | |
1252 | } | |
1253 | fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> { | |
1254 | const SUBFRAME_LEN: [usize; 4] = [20, 14, 12, 10]; | |
1255 | ||
1256 | let info = pkt.get_stream().get_info(); | |
1257 | if let NACodecTypeInfo::Audio(_) = info.get_properties() { | |
1258 | let pktbuf = pkt.get_buffer(); | |
1259 | validate!(pktbuf.len() >= 10); | |
1260 | ||
1261 | let mut mr = MemoryReader::new_read(&pktbuf); | |
1262 | let mut br = ByteReader::new(&mut mr); | |
1263 | let mut nblocks = 0; | |
1264 | while br.left() > 4 { | |
1265 | br.read_skip(2)?; | |
1266 | let val = br.read_u16le()?; | |
1267 | nblocks += 1; | |
1268 | let sf_len = SUBFRAME_LEN[((val >> 12) & 3) as usize]; | |
1269 | if br.left() <= sf_len as i64 { | |
1270 | break; | |
1271 | } | |
1272 | br.read_skip(sf_len - 4)?; | |
1273 | } | |
1274 | ||
1275 | let samples = 128 * nblocks; | |
1276 | let abuf = alloc_audio_buffer(self.ainfo, samples, self.chmap.clone())?; | |
1277 | let mut adata = abuf.get_abuf_i16().unwrap(); | |
1278 | let dst = adata.get_data_mut().unwrap(); | |
1279 | ||
1280 | let mut mr = MemoryReader::new_read(&pktbuf); | |
1281 | let mut br = ByteReader::new(&mut mr); | |
1282 | ||
1283 | let mut blk_no = 0usize; | |
1284 | while br.left() > 0 { | |
1285 | let val = br.read_u16le()?; | |
1286 | let mode = val >> 9; | |
1287 | if mode == 0x7F { | |
1288 | self.decode_intra(&mut br, val)?; | |
1289 | } else { | |
1290 | self.decode_inter(&mut br, val & 0x1FF, mode)?; | |
1291 | } | |
1292 | self.output(&mut dst[blk_no * 128..]); | |
1293 | blk_no += 1; | |
1294 | } | |
1295 | ||
1296 | let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), abuf); | |
1297 | frm.set_duration(Some(samples as u64)); | |
1298 | frm.set_keyframe(true); | |
1299 | Ok(frm.into_ref()) | |
1300 | } else { | |
1301 | Err(DecoderError::InvalidData) | |
1302 | } | |
1303 | } | |
1304 | fn flush(&mut self) { | |
1305 | } | |
1306 | } | |
1307 | ||
1308 | ||
1309 | impl NAOptionHandler for VXAudioDecoder { | |
1310 | fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] } | |
1311 | fn set_options(&mut self, _options: &[NAOption]) { } | |
1312 | fn query_option_value(&self, _name: &str) -> Option<NAValue> { None } | |
1313 | } | |
1314 | ||
1315 | ||
1316 | pub fn get_decoder_audio() -> Box<dyn NADecoder + Send> { | |
1317 | Box::new(VXAudioDecoder::new()) | |
1318 | } | |
1319 | ||
1320 | #[cfg(test)] | |
1321 | mod test { | |
1322 | use nihav_core::codecs::RegisteredDecoders; | |
1323 | use nihav_core::demuxers::RegisteredDemuxers; | |
1324 | use nihav_codec_support::test::dec_video::*; | |
1325 | use crate::game_register_all_decoders; | |
1326 | use crate::game_register_all_demuxers; | |
1327 | #[test] | |
1328 | fn test_vx_video() { | |
1329 | let mut dmx_reg = RegisteredDemuxers::new(); | |
1330 | game_register_all_demuxers(&mut dmx_reg); | |
1331 | let mut dec_reg = RegisteredDecoders::new(); | |
1332 | game_register_all_decoders(&mut dec_reg); | |
1333 | ||
55d85231 KS |
1334 | test_decoding("vx", "vxvideo", "assets/Game/bioware.vx", Some(31), &dmx_reg, &dec_reg, |
1335 | ExpectedTestResult::MD5Frames(vec![ | |
1336 | [0x33de14fa, 0x00948eb7, 0x028141d7, 0x1d07abd6], | |
2451e953 KS |
1337 | [0x77a96135, 0x0cc2d0b5, 0x45862c7c, 0xe27f5b10], |
1338 | [0x3c3ed089, 0x3c643216, 0xe6aed381, 0x4d43c50f], | |
1339 | [0x09e86330, 0x37d3a766, 0xa8198ac5, 0x21fa089c], | |
1340 | [0xbcab34d7, 0xdffe234a, 0x6534709f, 0xc3050e32], | |
1341 | [0x2bab595d, 0x7a19937e, 0xccc97277, 0x91b32191], | |
1342 | [0xe082f77e, 0x6498fd0d, 0xa3828c0f, 0xb4f7a02a], | |
1343 | [0x8515f6e2, 0xc0cb8ab3, 0xf91a3483, 0xd54470fc], | |
1344 | [0x17b1b54a, 0x1b574323, 0xcdeec1ec, 0x7a00ae4e], | |
1345 | [0x773f1d47, 0x86188681, 0xb111bcb8, 0x80fe34e9], | |
1346 | [0xbc4a8e20, 0xca91d4b6, 0x7275a162, 0x9a73be7c], | |
1347 | [0x0d4992b5, 0xd12a985a, 0x929ebec2, 0x0653fbc7], | |
1348 | [0xc24691b7, 0xabd27a7a, 0xd62cbd73, 0xd72a49ea], | |
1349 | [0x9024f7f4, 0xbe707e73, 0x27b4b4a0, 0x33bb515e], | |
1350 | [0x31aee8fc, 0xd0a3fa6d, 0xea11ef6a, 0x53a5f031], | |
1351 | [0x4a83f326, 0xceff4329, 0x54fbe91e, 0xf98ee74b], | |
1352 | [0xe54b5450, 0x979f4b26, 0x910ee666, 0x05fd1996], | |
1353 | [0xe48d66d0, 0x0a69b963, 0x9917084e, 0xf4b0486d], | |
1354 | [0x624a8b32, 0x0d1ce036, 0x9de8ebf0, 0x472a77b9], | |
1355 | [0x5d307d48, 0x1168f3a9, 0xaa792fb2, 0x34430b20], | |
1356 | [0xf2d80474, 0xac6b0972, 0x500e569e, 0x3c8e7dde], | |
1357 | [0x481310b3, 0x70cdeb91, 0xed007972, 0x70cefff3], | |
1358 | [0x8b5b17ca, 0xca6f9a72, 0x0256908a, 0x4505cf85], | |
1359 | [0xb6222c1d, 0x7a9760cb, 0xb3276304, 0x2ff1595e], | |
1360 | [0xf98e3d89, 0xae957c83, 0xff849c05, 0x8ca54276], | |
1361 | [0xbcebda1c, 0x6f6e4ac6, 0x023e7f0f, 0x9578142f], | |
1362 | [0x399f5155, 0xd95b33e3, 0xf0b55af8, 0xe32db6b2], | |
1363 | [0x0c4d4347, 0x5f5061e4, 0xe2fa4690, 0xa340d294], | |
1364 | [0x6fcdddb5, 0xf101da80, 0x6f55ddd9, 0x0dfeead1], | |
1365 | [0xb9623043, 0x1dab8a93, 0x22fd5f7a, 0x2c2a6633], | |
1366 | [0xb3ac2652, 0xf474e49d, 0x7db51405, 0xcd1c13cc], | |
1367 | [0x6a901339, 0xda88b2be, 0x6d943e18, 0xda9b5926]])); | |
55d85231 KS |
1368 | } |
1369 | } | |
1370 | ||
1371 | const NC_MAP: [usize; 8] = [ 0, 0, 1, 1, 2, 2, 2, 2 ]; | |
1372 | const NC_BITS: [[u16; 68]; 3] = [ | |
1373 | [ | |
1374 | 0x0001, 0x0000, 0x0000, 0x0000, 0x0005, 0x0001, 0x0000, 0x0000, | |
1375 | 0x0007, 0x0004, 0x0001, 0x0000, 0x0007, 0x0006, 0x0005, 0x0003, | |
1376 | 0x0007, 0x0006, 0x0005, 0x0003, 0x0007, 0x0006, 0x0005, 0x0004, | |
1377 | 0x000F, 0x0006, 0x0005, 0x0004, 0x000B, 0x000E, 0x0005, 0x0004, | |
1378 | 0x0008, 0x000A, 0x000D, 0x0004, 0x000F, 0x000E, 0x0009, 0x0004, | |
1379 | 0x000B, 0x000A, 0x000D, 0x000C, 0x000F, 0x000E, 0x0009, 0x000C, | |
1380 | 0x000B, 0x000A, 0x000D, 0x0008, 0x000F, 0x0001, 0x0009, 0x000C, | |
1381 | 0x000B, 0x000E, 0x000D, 0x0008, 0x0007, 0x000A, 0x0009, 0x000C, | |
1382 | 0x0004, 0x0006, 0x0005, 0x0008 | |
1383 | ], [ | |
1384 | 0x0003, 0x0000, 0x0000, 0x0000, 0x000B, 0x0002, 0x0000, 0x0000, | |
1385 | 0x0007, 0x0007, 0x0003, 0x0000, 0x0007, 0x000A, 0x0009, 0x0005, | |
1386 | 0x0007, 0x0006, 0x0005, 0x0004, 0x0004, 0x0006, 0x0005, 0x0006, | |
1387 | 0x0007, 0x0006, 0x0005, 0x0008, 0x000F, 0x0006, 0x0005, 0x0004, | |
1388 | 0x000B, 0x000E, 0x000D, 0x0004, 0x000F, 0x000A, 0x0009, 0x0004, | |
1389 | 0x000B, 0x000E, 0x000D, 0x000C, 0x0008, 0x000A, 0x0009, 0x0008, | |
1390 | 0x000F, 0x000E, 0x000D, 0x000C, 0x000B, 0x000A, 0x0009, 0x000C, | |
1391 | 0x0007, 0x000B, 0x0006, 0x0008, 0x0009, 0x0008, 0x000A, 0x0001, | |
1392 | 0x0007, 0x0006, 0x0005, 0x0004 | |
1393 | ], [ | |
1394 | 0x000F, 0x0000, 0x0000, 0x0000, 0x000F, 0x000E, 0x0000, 0x0000, | |
1395 | 0x000B, 0x000F, 0x000D, 0x0000, 0x0008, 0x000C, 0x000E, 0x000C, | |
1396 | 0x000F, 0x000A, 0x000B, 0x000B, 0x000B, 0x0008, 0x0009, 0x000A, | |
1397 | 0x0009, 0x000E, 0x000D, 0x0009, 0x0008, 0x000A, 0x0009, 0x0008, | |
1398 | 0x000F, 0x000E, 0x000D, 0x000D, 0x000B, 0x000E, 0x000A, 0x000C, | |
1399 | 0x000F, 0x000A, 0x000D, 0x000C, 0x000B, 0x000E, 0x0009, 0x000C, | |
1400 | 0x0008, 0x000A, 0x000D, 0x0008, 0x000D, 0x0007, 0x0009, 0x000C, | |
1401 | 0x0009, 0x000C, 0x000B, 0x000A, 0x0005, 0x0008, 0x0007, 0x0006, | |
1402 | 0x0001, 0x0004, 0x0003, 0x0002 | |
1403 | ] | |
1404 | ]; | |
1405 | const NC_LENS: [[u8; 68]; 3] = [ | |
1406 | [ | |
1407 | 1, 0, 0, 0, 6, 2, 0, 0, | |
1408 | 8, 6, 3, 0, 9, 8, 7, 5, | |
1409 | 10, 9, 8, 6, 11, 10, 9, 7, | |
1410 | 13, 11, 10, 8, 13, 13, 11, 9, | |
1411 | 13, 13, 13, 10, 14, 14, 13, 11, | |
1412 | 14, 14, 14, 13, 15, 15, 14, 14, | |
1413 | 15, 15, 15, 14, 16, 15, 15, 15, | |
1414 | 16, 16, 16, 15, 16, 16, 16, 16, | |
1415 | 16, 16, 16, 16 | |
1416 | ], [ | |
1417 | 2, 0, 0, 0, 6, 2, 0, 0, | |
1418 | 6, 5, 3, 0, 7, 6, 6, 4, | |
1419 | 8, 6, 6, 4, 8, 7, 7, 5, | |
1420 | 9, 8, 8, 6, 11, 9, 9, 6, | |
1421 | 11, 11, 11, 7, 12, 11, 11, 9, | |
1422 | 12, 12, 12, 11, 12, 12, 12, 11, | |
1423 | 13, 13, 13, 12, 13, 13, 13, 13, | |
1424 | 13, 14, 13, 13, 14, 14, 14, 13, | |
1425 | 14, 14, 14, 14 | |
1426 | ], [ | |
1427 | 4, 0, 0, 0, 6, 4, 0, 0, | |
1428 | 6, 5, 4, 0, 6, 5, 5, 4, | |
1429 | 7, 5, 5, 4, 7, 5, 5, 4, | |
1430 | 7, 6, 6, 4, 7, 6, 6, 4, | |
1431 | 8, 7, 7, 5, 8, 8, 7, 6, | |
1432 | 9, 8, 8, 7, 9, 9, 8, 8, | |
1433 | 9, 9, 9, 8, 10, 9, 9, 9, | |
1434 | 10, 10, 10, 10, 10, 10, 10, 10, | |
1435 | 10, 10, 10, 10 | |
1436 | ] | |
1437 | ]; | |
1438 | ||
1439 | const NUM_ZERO_BITS: [[u8; 16]; 15] = [ | |
1440 | [ | |
1441 | 0x01, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x01 | |
1442 | ], [ | |
1443 | 0x07, 0x06, 0x05, 0x04, 0x03, 0x05, 0x04, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x01, 0x00, 0x00 | |
1444 | ], [ | |
1445 | 0x05, 0x07, 0x06, 0x05, 0x04, 0x03, 0x04, 0x03, 0x02, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00 | |
1446 | ], [ | |
1447 | 0x03, 0x07, 0x05, 0x04, 0x06, 0x05, 0x04, 0x03, 0x03, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00 | |
1448 | ], [ | |
1449 | 0x05, 0x04, 0x03, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 | |
1450 | ], [ | |
1451 | 0x01, 0x01, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | |
1452 | ], [ | |
1453 | 0x01, 0x01, 0x05, 0x04, 0x03, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | |
1454 | ], [ | |
1455 | 0x01, 0x01, 0x01, 0x03, 0x03, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | |
1456 | ], [ | |
1457 | 0x01, 0x00, 0x01, 0x03, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | |
1458 | ], [ | |
1459 | 0x01, 0x00, 0x01, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | |
1460 | ], [ | |
1461 | 0x00, 0x01, 0x01, 0x02, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | |
1462 | ], [ | |
1463 | 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | |
1464 | ], [ | |
1465 | 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | |
1466 | ], [ | |
1467 | 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | |
1468 | ], [ | |
1469 | 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | |
1470 | ] | |
1471 | ]; | |
1472 | const NUM_ZERO_LENS: [[u8; 16]; 15] = [ | |
1473 | [ 1, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9 ], | |
1474 | [ 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 6, 6, 0 ], | |
1475 | [ 4, 3, 3, 3, 4, 4, 3, 3, 4, 5, 5, 6, 5, 6, 0, 0 ], | |
1476 | [ 5, 3, 4, 4, 3, 3, 3, 4, 3, 4, 5, 5, 5, 0, 0, 0 ], | |
1477 | [ 4, 4, 4, 3, 3, 3, 3, 3, 4, 5, 4, 5, 0, 0, 0, 0 ], | |
1478 | [ 6, 5, 3, 3, 3, 3, 3, 3, 4, 3, 6, 0, 0, 0, 0, 0 ], | |
1479 | [ 6, 5, 3, 3, 3, 2, 3, 4, 3, 6, 0, 0, 0, 0, 0, 0 ], | |
1480 | [ 6, 4, 5, 3, 2, 2, 3, 3, 6, 0, 0, 0, 0, 0, 0, 0 ], | |
1481 | [ 6, 6, 4, 2, 2, 3, 2, 5, 0, 0, 0, 0, 0, 0, 0, 0 ], | |
1482 | [ 5, 5, 3, 2, 2, 2, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], | |
1483 | [ 4, 4, 3, 3, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], | |
1484 | [ 4, 4, 2, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], | |
1485 | [ 3, 3, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], | |
1486 | [ 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], | |
1487 | [ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] | |
1488 | ]; | |
1489 | ||
1490 | const ZERO_RUN_BITS: [[u8; 8]; 6] = [ | |
1491 | [ 1, 0, 0, 0, 0, 0, 0, 0 ], | |
1492 | [ 1, 1, 0, 0, 0, 0, 0, 0 ], | |
1493 | [ 3, 2, 1, 0, 0, 0, 0, 0 ], | |
1494 | [ 3, 2, 1, 1, 0, 0, 0, 0 ], | |
1495 | [ 3, 2, 3, 2, 1, 0, 0, 0 ], | |
1496 | [ 3, 0, 1, 3, 2, 5, 4, 0 ] | |
1497 | ]; | |
1498 | const ZERO_RUN_LENS: [[u8; 8]; 6] = [ | |
1499 | [ 1, 1, 0, 0, 0, 0, 0, 0 ], | |
1500 | [ 1, 2, 2, 0, 0, 0, 0, 0 ], | |
1501 | [ 2, 2, 2, 2, 0, 0, 0, 0 ], | |
1502 | [ 2, 2, 2, 3, 3, 0, 0, 0 ], | |
1503 | [ 2, 2, 3, 3, 3, 3, 0, 0 ], | |
1504 | [ 2, 3, 3, 3, 3, 3, 3, 0 ] | |
1505 | ]; | |
1506 |