]>
Commit | Line | Data |
---|---|---|
606c448e | 1 | use nihav_core::codecs::*; |
b83a3961 KS |
2 | use nihav_core::io::byteio::*; |
3 | use nihav_core::io::bitreader::*; | |
4 | use nihav_core::io::codebook::*; | |
b4d5b851 | 5 | use nihav_codec_support::codecs::{IPShuffler, HAMShuffler}; |
b83a3961 | 6 | |
94cebb38 KS |
7 | use super::binkviddata::*; |
8 | ||
b83a3961 KS |
9 | const SKIP_BLOCK: u8 = 0; |
10 | const SCALED_BLOCK: u8 = 1; | |
11 | const MOTION_BLOCK: u8 = 2; | |
12 | const RUN_BLOCK: u8 = 3; | |
13 | const RESIDUE_BLOCK: u8 = 4; | |
14 | const INTRA_BLOCK: u8 = 5; | |
15 | const FILL_BLOCK: u8 = 6; | |
16 | const INTER_BLOCK: u8 = 7; | |
17 | const PATTERN_BLOCK: u8 = 8; | |
18 | const RAW_BLOCK: u8 = 9; | |
19 | ||
20 | #[derive(Default, Clone,Copy)] | |
21 | struct Tree { | |
22 | id: usize, | |
23 | syms: [u8; 16], | |
24 | } | |
25 | ||
26 | impl Tree { | |
27 | fn read_desc(&mut self, br: &mut BitReader) -> DecoderResult<()> { | |
28 | self.id = br.read(4)? as usize; | |
29 | if self.id == 0 { | |
30 | for i in 0..16 { self.syms[i] = i as u8; } | |
31 | } else { | |
32 | if br.read_bool()? { | |
33 | let len = br.read(3)? as usize; | |
34 | let mut present: [bool; 16] = [false; 16]; | |
7e6086e5 | 35 | for i in 0..=len { |
b83a3961 KS |
36 | self.syms[i] = br.read(4)? as u8; |
37 | present[self.syms[i] as usize] = true; | |
38 | } | |
39 | let mut idx = len + 1; | |
40 | for i in 0..16 { | |
41 | if present[i] { continue; } | |
42 | self.syms[idx] = i as u8; | |
43 | idx += 1; | |
44 | } | |
45 | } else { | |
46 | let len = br.read(2)? as usize; | |
47 | let mut syms: [u8; 16] = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]; | |
48 | let mut tmp: [u8; 16] = [0; 16]; | |
7e6086e5 | 49 | for bits in 0..=len { |
b83a3961 KS |
50 | let size = 1 << bits; |
51 | for arr in syms.chunks_mut(size * 2) { | |
52 | let mut ptr0 = 0; | |
53 | let mut ptr1 = size; | |
54 | let mut optr = 0; | |
55 | while (ptr0 < size) && (ptr1 < size * 2) { | |
56 | if !br.read_bool()? { | |
57 | tmp[optr] = arr[ptr0]; | |
58 | ptr0 += 1; | |
59 | } else { | |
60 | tmp[optr] = arr[ptr1]; | |
61 | ptr1 += 1; | |
62 | } | |
63 | optr += 1; | |
64 | } | |
65 | while ptr0 < size { | |
66 | tmp[optr] = arr[ptr0]; | |
67 | ptr0 += 1; | |
68 | optr += 1; | |
69 | } | |
70 | while ptr1 < size * 2 { | |
71 | tmp[optr] = arr[ptr1]; | |
72 | ptr1 += 1; | |
73 | optr += 1; | |
74 | } | |
75 | arr.copy_from_slice(&tmp[0..size * 2]); | |
76 | } | |
77 | } | |
78 | self.syms = syms; | |
79 | } | |
80 | } | |
81 | Ok(()) | |
82 | } | |
83 | fn read_sym(&self, br: &mut BitReader, trees: &BinkTrees) -> DecoderResult<u8> { | |
84 | let idx = br.read_cb(&trees.cb[self.id])?; | |
85 | Ok(self.syms[idx as usize]) | |
86 | } | |
87 | } | |
88 | ||
89 | #[derive(Default)] | |
90 | struct Bundle<T: Copy> { | |
91 | tree: Tree, | |
92 | data: Vec<T>, | |
93 | dec_pos: usize, | |
94 | read_pos: usize, | |
95 | bits: u8, | |
96 | } | |
97 | ||
98 | impl<T:Copy> Bundle<T> { | |
99 | fn binkb_reset(&mut self, bits: u8) { | |
100 | self.bits = bits; | |
101 | self.dec_pos = 0; | |
102 | self.read_pos = 0; | |
103 | } | |
104 | fn reset(&mut self) { | |
105 | self.dec_pos = 0; | |
106 | self.read_pos = 0; | |
107 | } | |
108 | fn read_desc(&mut self, br: &mut BitReader) -> DecoderResult<()> { | |
109 | self.dec_pos = 0; | |
110 | self.read_pos = 0; | |
111 | self.tree.read_desc(br)?; | |
112 | Ok(()) | |
113 | } | |
114 | fn read_len(&mut self, br: &mut BitReader) -> DecoderResult<usize> { | |
115 | if self.read_pos < self.dec_pos { return Ok(0); } | |
116 | let len = br.read(self.bits)? as usize; | |
117 | if len == 0 { | |
118 | self.dec_pos = self.data.len(); | |
119 | self.read_pos = self.data.len() - 1; | |
120 | } | |
121 | Ok(len) | |
122 | } | |
123 | fn read_len_binkb(&mut self, br: &mut BitReader) -> DecoderResult<usize> { | |
124 | if self.read_pos < self.dec_pos { return Ok(0); } | |
125 | let len = br.read(13)? as usize; | |
126 | if len == 0 { | |
127 | self.dec_pos = self.data.len(); | |
128 | self.read_pos = self.data.len() - 1; | |
129 | } | |
b83a3961 KS |
130 | Ok(len) |
131 | } | |
132 | fn get_val(&mut self) -> DecoderResult<T> { | |
133 | validate!(self.read_pos < self.dec_pos); | |
134 | let val = self.data[self.read_pos]; | |
135 | self.read_pos += 1; | |
136 | Ok(val) | |
137 | } | |
138 | } | |
139 | ||
140 | const BLOCK_TYPE_RUNS: [usize; 4] = [ 4, 8, 12, 32 ]; | |
141 | impl Bundle<u8> { | |
142 | fn read_binkb(&mut self, br: &mut BitReader) -> DecoderResult<()> { | |
143 | let len = self.read_len_binkb(br)?; | |
144 | if len == 0 { return Ok(()); } | |
145 | let end = self.dec_pos + len; | |
146 | validate!(end <= self.data.len()); | |
147 | for i in 0..len { | |
148 | self.data[self.dec_pos + i] = br.read(self.bits)? as u8; | |
149 | } | |
150 | self.dec_pos += len; | |
151 | Ok(()) | |
152 | } | |
153 | fn read_runs(&mut self, br: &mut BitReader, trees: &BinkTrees) -> DecoderResult<()> { | |
154 | let len = self.read_len(br)?; | |
155 | if len == 0 { return Ok(()); } | |
156 | let end = self.dec_pos + len; | |
157 | validate!(end <= self.data.len()); | |
158 | if br.read_bool()? { | |
159 | let val = br.read(4)? as u8; | |
160 | for i in 0..len { self.data[self.dec_pos + i] = val; } | |
161 | self.dec_pos += len; | |
162 | } else { | |
163 | while self.dec_pos < end { | |
164 | self.data[self.dec_pos] = self.tree.read_sym(br, trees)?; | |
165 | self.dec_pos += 1; | |
166 | } | |
167 | } | |
168 | Ok(()) | |
169 | } | |
170 | fn read_block_types(&mut self, br: &mut BitReader, trees: &BinkTrees) -> DecoderResult<()> { | |
171 | let len = self.read_len(br)?; | |
172 | if len == 0 { return Ok(()); } | |
173 | let end = self.dec_pos + len; | |
174 | validate!(end <= self.data.len()); | |
175 | if br.read_bool()? { | |
176 | let val = br.read(4)? as u8; | |
177 | for i in 0..len { self.data[self.dec_pos + i] = val; } | |
178 | self.dec_pos += len; | |
179 | } else { | |
180 | let mut last = 0; | |
181 | while self.dec_pos < end { | |
182 | let val = self.tree.read_sym(br, trees)?; | |
183 | if val < 12 { | |
184 | self.data[self.dec_pos] = val; | |
185 | self.dec_pos += 1; | |
186 | last = val; | |
187 | } else { | |
188 | let run = BLOCK_TYPE_RUNS[(val - 12) as usize]; | |
189 | validate!(self.dec_pos + run <= end); | |
190 | for i in 0..run { | |
191 | self.data[self.dec_pos + i] = last; | |
192 | } | |
193 | self.dec_pos += run; | |
194 | } | |
195 | } | |
196 | } | |
197 | Ok(()) | |
198 | } | |
199 | fn read_patterns(&mut self, br: &mut BitReader, trees: &BinkTrees) -> DecoderResult<()> { | |
200 | let len = self.read_len(br)?; | |
201 | if len == 0 { return Ok(()); } | |
202 | let end = self.dec_pos + len; | |
203 | validate!(end <= self.data.len()); | |
204 | for i in 0..len { | |
205 | let pat_lo = self.tree.read_sym(br, trees)?; | |
206 | let pat_hi = self.tree.read_sym(br, trees)?; | |
207 | self.data[self.dec_pos + i] = pat_lo | (pat_hi << 4); | |
208 | } | |
209 | self.dec_pos += len; | |
210 | Ok(()) | |
211 | } | |
212 | fn cvt_color(lo: u8, hi: u8, new_bink: bool) -> u8 { | |
213 | let val = lo | (hi << 4); | |
214 | if !new_bink { | |
215 | let sign = ((val as i8) >> 7) as u8; | |
216 | ((val & 0x7F) ^ sign).wrapping_sub(sign) ^ 0x80 | |
217 | } else { | |
218 | val | |
219 | } | |
220 | } | |
221 | fn read_colors(&mut self, br: &mut BitReader, trees: &BinkTrees, col_hi: &[Tree; 16], col_last: &mut u8, new_bink: bool) -> DecoderResult<()> { | |
222 | let len = self.read_len(br)?; | |
223 | if len == 0 { return Ok(()); } | |
224 | let end = self.dec_pos + len; | |
225 | validate!(end <= self.data.len()); | |
226 | let mut last = *col_last; | |
227 | if br.read_bool()? { | |
228 | last = col_hi[last as usize].read_sym(br, trees)?; | |
229 | let lo = self.tree.read_sym(br, trees)?; | |
230 | let val = Self::cvt_color(lo, last, new_bink); | |
e6aaad5c | 231 | for i in 0..len { self.data[self.dec_pos + i] = val; } |
b83a3961 KS |
232 | self.dec_pos += len; |
233 | } else { | |
234 | while self.dec_pos < end { | |
235 | last = col_hi[last as usize].read_sym(br, trees)?; | |
236 | let lo = self.tree.read_sym(br, trees)?; | |
237 | let val = Self::cvt_color(lo, last, new_bink); | |
238 | self.data[self.dec_pos] = val; | |
239 | self.dec_pos += 1; | |
240 | } | |
241 | } | |
242 | *col_last = last; | |
243 | Ok(()) | |
244 | } | |
245 | } | |
246 | ||
247 | impl Bundle<i8> { | |
248 | fn read_binkb(&mut self, br: &mut BitReader) -> DecoderResult<()> { | |
249 | let len = self.read_len_binkb(br)?; | |
250 | if len == 0 { return Ok(()); } | |
251 | let end = self.dec_pos + len; | |
252 | validate!(end <= self.data.len()); | |
253 | let bias = 1 << (self.bits - 1); | |
254 | for i in 0..len { | |
255 | self.data[self.dec_pos + i] = (br.read(self.bits)? as i8) - bias; | |
256 | } | |
257 | self.dec_pos += len; | |
258 | Ok(()) | |
259 | } | |
260 | fn read_motion_values(&mut self, br: &mut BitReader, trees: &BinkTrees) -> DecoderResult<()> { | |
261 | let len = self.read_len(br)?; | |
262 | if len == 0 { return Ok(()); } | |
263 | let end = self.dec_pos + len; | |
264 | validate!(end <= self.data.len()); | |
265 | if br.read_bool()? { | |
266 | let mut val = br.read(4)? as i8; | |
267 | if val != 0 && br.read_bool()? { val = -val; } | |
268 | for i in 0..len { self.data[self.dec_pos + i] = val; } | |
269 | self.dec_pos += len; | |
270 | } else { | |
271 | while self.dec_pos < end { | |
272 | self.data[self.dec_pos] = self.tree.read_sym(br, trees)? as i8; | |
273 | if self.data[self.dec_pos] != 0 && br.read_bool()? { | |
274 | self.data[self.dec_pos] = -self.data[self.dec_pos]; | |
275 | } | |
276 | self.dec_pos += 1; | |
277 | } | |
278 | } | |
279 | Ok(()) | |
280 | } | |
281 | } | |
282 | ||
283 | const DC_START_BITS: u8 = 11; | |
284 | impl Bundle<u16> { | |
285 | fn read_binkb(&mut self, br: &mut BitReader) -> DecoderResult<()> { | |
286 | let len = self.read_len_binkb(br)?; | |
287 | if len == 0 { return Ok(()); } | |
288 | let end = self.dec_pos + len; | |
289 | validate!(end <= self.data.len()); | |
290 | for i in 0..len { | |
291 | self.data[self.dec_pos + i] = br.read(self.bits)? as u16; | |
292 | } | |
293 | self.dec_pos += len; | |
294 | Ok(()) | |
295 | } | |
296 | fn read_dcs(&mut self, br: &mut BitReader, start_bits: u8) -> DecoderResult<()> { | |
297 | let len = self.read_len(br)?; | |
298 | if len == 0 { return Ok(()); } | |
299 | let end = self.dec_pos + len; | |
300 | validate!(end <= self.data.len()); | |
301 | let mut val = br.read(start_bits)? as u16; | |
302 | self.data[self.dec_pos] = val; | |
303 | self.dec_pos += 1; | |
304 | for i in (1..len).step_by(8) { | |
305 | let seg_len = (len - i).min(8); | |
306 | let bits = br.read(4)? as u8; | |
307 | if bits != 0 { | |
308 | for _ in 0..seg_len { | |
309 | let diff = br.read(bits)? as u16; | |
310 | let res = if diff != 0 && br.read_bool()? { | |
311 | val.checked_sub(diff) | |
312 | } else { | |
313 | val.checked_add(diff) | |
314 | }; | |
315 | validate!(res.is_some()); | |
316 | val = res.unwrap(); | |
317 | self.data[self.dec_pos] = val; | |
318 | self.dec_pos += 1; | |
319 | } | |
320 | } else { | |
321 | for _ in 0..seg_len { | |
322 | self.data[self.dec_pos] = val; | |
323 | self.dec_pos += 1; | |
324 | } | |
325 | } | |
326 | } | |
327 | Ok(()) | |
328 | } | |
329 | } | |
330 | ||
331 | impl Bundle<i16> { | |
332 | fn read_binkb(&mut self, br: &mut BitReader) -> DecoderResult<()> { | |
333 | let len = self.read_len_binkb(br)?; | |
334 | if len == 0 { return Ok(()); } | |
335 | let end = self.dec_pos + len; | |
336 | validate!(end <= self.data.len()); | |
337 | let bias = 1 << (self.bits - 1); | |
338 | for i in 0..len { | |
339 | self.data[self.dec_pos + i] = (br.read(self.bits)? as i16) - bias; | |
340 | } | |
341 | self.dec_pos += len; | |
342 | Ok(()) | |
343 | } | |
344 | fn read_dcs(&mut self, br: &mut BitReader, start_bits: u8) -> DecoderResult<()> { | |
345 | let len = self.read_len(br)?; | |
346 | if len == 0 { return Ok(()); } | |
347 | let end = self.dec_pos + len; | |
348 | validate!(end <= self.data.len()); | |
349 | let mut val = br.read(start_bits - 1)? as i16; | |
350 | if val != 0 && br.read_bool()? { | |
351 | val = -val; | |
352 | } | |
353 | self.data[self.dec_pos] = val; | |
354 | self.dec_pos += 1; | |
355 | for i in (1..len).step_by(8) { | |
356 | let seg_len = (len - i).min(8); | |
357 | let bits = br.read(4)? as u8; | |
358 | if bits != 0 { | |
359 | for _ in 0..seg_len { | |
360 | let mut diff = br.read(bits)? as i16; | |
361 | if diff != 0 && br.read_bool()? { | |
362 | diff = -diff; | |
363 | } | |
364 | let res = val.checked_add(diff); | |
365 | validate!(res.is_some()); | |
366 | val = res.unwrap(); | |
367 | self.data[self.dec_pos] = val; | |
368 | self.dec_pos += 1; | |
369 | } | |
370 | } else { | |
371 | for _ in 0..seg_len { | |
372 | self.data[self.dec_pos] = val; | |
373 | self.dec_pos += 1; | |
374 | } | |
375 | } | |
376 | } | |
377 | Ok(()) | |
378 | } | |
379 | } | |
380 | ||
381 | struct BinkTrees { | |
382 | cb: [Codebook<u8>; 16], | |
383 | } | |
384 | ||
385 | fn map_u8(idx: usize) -> u8 { idx as u8 } | |
386 | ||
387 | impl Default for BinkTrees { | |
388 | fn default() -> Self { | |
fd8666bc KS |
389 | let cb = unsafe { |
390 | let mut ucb: std::mem::MaybeUninit::<[Codebook<u8>; 16]> = std::mem::MaybeUninit::uninit(); | |
391 | for i in 0..16 { | |
392 | let mut cr = TableCodebookDescReader::new(&BINK_TREE_CODES[i], &BINK_TREE_BITS[i], map_u8); | |
393 | std::ptr::write(&mut (*ucb.as_mut_ptr())[i], Codebook::new(&mut cr, CodebookMode::LSB).unwrap()); | |
394 | } | |
395 | ucb.assume_init() | |
396 | }; | |
b83a3961 KS |
397 | Self { cb } |
398 | } | |
399 | } | |
400 | ||
401 | const A1: i32 = 2896; | |
402 | const A2: i32 = 2217; | |
403 | const A3: i32 = 3784; | |
404 | const A4: i32 = -5352; | |
405 | ||
406 | macro_rules! idct { | |
407 | ($src: expr, $sstep: expr, $dst: expr, $dstep: expr, $off: expr, $bias: expr, $shift: expr) => { | |
408 | let a0 = $src[$off + 0 * $sstep] + $src[$off + 4 * $sstep]; | |
409 | let a1 = $src[$off + 0 * $sstep] - $src[$off + 4 * $sstep]; | |
410 | let a2 = $src[$off + 2 * $sstep] + $src[$off + 6 * $sstep]; | |
411 | let a3 = A1.wrapping_mul($src[$off + 2 * $sstep] - $src[$off + 6 * $sstep]) >> 11; | |
412 | let a4 = $src[$off + 5 * $sstep] + $src[$off + 3 * $sstep]; | |
413 | let a5 = $src[$off + 5 * $sstep] - $src[$off + 3 * $sstep]; | |
414 | let a6 = $src[$off + 1 * $sstep] + $src[$off + 7 * $sstep]; | |
415 | let a7 = $src[$off + 1 * $sstep] - $src[$off + 7 * $sstep]; | |
416 | let b0 = a4 + a6; | |
417 | let b1 = A3.wrapping_mul(a5 + a7) >> 11; | |
418 | let b2 = (A4.wrapping_mul(a5) >> 11) - b0 + b1; | |
419 | let b3 = (A1.wrapping_mul(a6 - a4) >> 11) - b2; | |
420 | let b4 = (A2.wrapping_mul(a7) >> 11) + b3 - b1; | |
421 | let c0 = a0 + a2; | |
422 | let c1 = a0 - a2; | |
423 | let c2 = a1 + (a3 - a2); | |
424 | let c3 = a1 - (a3 - a2); | |
425 | ||
426 | $dst[$off + 0 * $dstep] = (c0 + b0 + $bias) >> $shift; | |
427 | $dst[$off + 1 * $dstep] = (c2 + b2 + $bias) >> $shift; | |
428 | $dst[$off + 2 * $dstep] = (c3 + b3 + $bias) >> $shift; | |
429 | $dst[$off + 3 * $dstep] = (c1 - b4 + $bias) >> $shift; | |
430 | $dst[$off + 4 * $dstep] = (c1 + b4 + $bias) >> $shift; | |
431 | $dst[$off + 5 * $dstep] = (c3 - b3 + $bias) >> $shift; | |
432 | $dst[$off + 6 * $dstep] = (c2 - b2 + $bias) >> $shift; | |
433 | $dst[$off + 7 * $dstep] = (c0 - b0 + $bias) >> $shift; | |
434 | }; | |
435 | } | |
436 | ||
b83a3961 KS |
437 | #[derive(Default)] |
438 | struct BinkDecoder { | |
2422d969 | 439 | info: NACodecInfoRef, |
b83a3961 | 440 | ips: IPShuffler, |
8d7a1c5c | 441 | hams: HAMShuffler<u8>, |
b83a3961 KS |
442 | |
443 | is_ver_b: bool, | |
444 | is_ver_i: bool, | |
445 | has_alpha: bool, | |
446 | is_gray: bool, | |
447 | swap_uv: bool, | |
448 | key_frame: bool, | |
449 | ||
450 | cur_w: usize, | |
451 | cur_h: usize, | |
452 | cur_plane: usize, | |
453 | ||
454 | colhi_tree: [Tree; 16], | |
455 | col_last: u8, | |
456 | ||
457 | btype: Bundle<u8>, | |
458 | sbtype: Bundle<u8>, | |
459 | colors: Bundle<u8>, | |
460 | pattern: Bundle<u8>, | |
461 | xoff: Bundle<i8>, | |
462 | yoff: Bundle<i8>, | |
463 | intradc: Bundle<u16>, | |
464 | interdc: Bundle<i16>, | |
465 | intraq: Bundle<u8>, | |
466 | interq: Bundle<u8>, | |
467 | nresidues: Bundle<u8>, | |
468 | run: Bundle<u8>, | |
469 | ||
470 | trees: BinkTrees, | |
471 | ||
472 | qmat_b: QuantMats, | |
473 | } | |
474 | ||
475 | fn calc_len(size: usize) -> u8 { | |
476 | (32 - ((size + 511) as u32).leading_zeros()) as u8 | |
477 | } | |
478 | ||
479 | impl BinkDecoder { | |
480 | fn new() -> Self { | |
481 | Self::default() | |
482 | } | |
483 | fn init_bundle_bufs(&mut self, bw: usize, bh: usize) { | |
484 | let size = bw * bh * 64; | |
485 | self.btype.data.resize(size, 0); | |
486 | self.sbtype.data.resize(size, 0); | |
487 | self.colors.data.resize(size, 0); | |
488 | self.pattern.data.resize(size, 0); | |
489 | self.xoff.data.resize(size, 0); | |
490 | self.yoff.data.resize(size, 0); | |
491 | self.intradc.data.resize(size, 0); | |
492 | self.interdc.data.resize(size, 0); | |
493 | self.intraq.data.resize(size, 0); | |
494 | self.interq.data.resize(size, 0); | |
495 | self.nresidues.data.resize(size, 0); | |
496 | self.run.data.resize(size, 0); | |
497 | } | |
498 | fn init_bundle_lengths(&mut self, w: usize, bw: usize) { | |
4e376911 | 499 | let w = (w + 7) & !7; |
b83a3961 KS |
500 | self.btype.bits = calc_len(w >> 3); |
501 | self.sbtype.bits = calc_len(w >> 4); | |
502 | self.colors.bits = calc_len(bw * 64); | |
503 | self.pattern.bits = calc_len(bw * 8); | |
504 | self.xoff.bits = calc_len(w >> 3); | |
505 | self.yoff.bits = calc_len(w >> 3); | |
506 | self.intradc.bits = calc_len(w >> 3); | |
507 | self.interdc.bits = calc_len(w >> 3); | |
508 | self.run.bits = calc_len(bw * 48); | |
509 | } | |
510 | fn init_bundle_lengths_binkb(&mut self) { | |
511 | self.btype.binkb_reset(4); | |
512 | self.colors.binkb_reset(8); | |
513 | self.pattern.binkb_reset(8); | |
514 | self.xoff.binkb_reset(5); | |
515 | self.yoff.binkb_reset(5); | |
516 | self.intradc.binkb_reset(11); | |
517 | self.interdc.binkb_reset(11); | |
518 | self.intraq.binkb_reset(4); | |
519 | self.interq.binkb_reset(4); | |
520 | self.nresidues.binkb_reset(7); | |
521 | } | |
522 | fn read_bundles_desc(&mut self, br: &mut BitReader) -> DecoderResult<()> { | |
523 | self.btype.read_desc(br)?; | |
524 | self.sbtype.read_desc(br)?; | |
525 | for el in &mut self.colhi_tree { | |
526 | el.read_desc(br)?; | |
527 | } | |
528 | self.col_last = 0; | |
529 | self.colors.read_desc(br)?; | |
530 | self.pattern.read_desc(br)?; | |
531 | self.xoff.read_desc(br)?; | |
532 | self.yoff.read_desc(br)?; | |
533 | self.intradc.reset(); | |
534 | self.interdc.reset(); | |
535 | self.run.read_desc(br)?; | |
536 | Ok(()) | |
537 | } | |
538 | fn read_bundles_binkb(&mut self, br: &mut BitReader) -> DecoderResult<()> { | |
539 | self.btype.read_binkb(br)?; | |
b83a3961 | 540 | self.colors.read_binkb(br)?; |
b83a3961 | 541 | self.pattern.read_binkb(br)?; |
b83a3961 | 542 | self.xoff.read_binkb(br)?; |
b83a3961 | 543 | self.yoff.read_binkb(br)?; |
b83a3961 | 544 | self.intradc.read_binkb(br)?; |
b83a3961 | 545 | self.interdc.read_binkb(br)?; |
b83a3961 | 546 | self.intraq.read_binkb(br)?; |
b83a3961 | 547 | self.interq.read_binkb(br)?; |
b83a3961 | 548 | self.nresidues.read_binkb(br)?; |
b83a3961 KS |
549 | Ok(()) |
550 | } | |
551 | fn read_bundles(&mut self, br: &mut BitReader) -> DecoderResult<()> { | |
552 | self.btype.read_block_types(br, &self.trees)?; | |
553 | self.sbtype.read_block_types(br, &self.trees)?; | |
554 | self.colors.read_colors(br, &self.trees, &self.colhi_tree, &mut self.col_last, self.is_ver_i)?; | |
555 | self.pattern.read_patterns(br, &self.trees)?; | |
556 | self.xoff.read_motion_values(br, &self.trees)?; | |
557 | self.yoff.read_motion_values(br, &self.trees)?; | |
558 | self.intradc.read_dcs(br, DC_START_BITS)?; | |
559 | self.interdc.read_dcs(br, DC_START_BITS)?; | |
560 | self.run.read_runs(br, &self.trees)?; | |
561 | Ok(()) | |
562 | } | |
563 | ||
564 | fn put_block(&self, block: &[u8; 64], dst: &mut [u8], mut off: usize, stride: usize, scaled: bool) { | |
565 | if !scaled { | |
566 | for src in block.chunks_exact(8) { | |
567 | let out = &mut dst[off..][..8]; | |
568 | out.copy_from_slice(src); | |
569 | off += stride; | |
570 | } | |
571 | } else { | |
572 | for src in block.chunks_exact(8) { | |
573 | for i in 0..8 { | |
574 | dst[off + i * 2 + 0] = src[i]; | |
575 | dst[off + i * 2 + 1] = src[i]; | |
576 | } | |
577 | off += stride; | |
578 | for i in 0..8 { | |
579 | dst[off + i * 2 + 0] = src[i]; | |
580 | dst[off + i * 2 + 1] = src[i]; | |
581 | } | |
582 | off += stride; | |
583 | } | |
584 | } | |
585 | } | |
586 | fn copy_block(&mut self, dst: &mut [u8], mut off: usize, stride: usize, bx: usize, by: usize, xoff: i8, yoff: i8) -> DecoderResult<()> { | |
587 | if let Some(prev_buf) = self.ips.get_ref() { | |
588 | let xoff = ((bx * 8) as isize) + (xoff as isize); | |
589 | let yoff = ((by * 8) as isize) + (yoff as isize); | |
590 | validate!((xoff >= 0) && (xoff + 8 <= (self.cur_w as isize))); | |
591 | validate!((yoff >= 0) && (yoff + 8 <= (self.cur_h as isize))); | |
592 | let pstride = prev_buf.get_stride(self.cur_plane); | |
593 | let mut poff = prev_buf.get_offset(self.cur_plane) + (xoff as usize) + (yoff as usize) * pstride; | |
594 | let pdata = prev_buf.get_data(); | |
595 | let ppix = pdata.as_slice(); | |
596 | for _ in 0..8 { | |
597 | let src = &ppix[poff..][..8]; | |
598 | let out = &mut dst[off..][..8]; | |
599 | out.copy_from_slice(src); | |
600 | off += stride; | |
601 | poff += pstride; | |
602 | } | |
603 | Ok(()) | |
604 | } else { | |
605 | Err(DecoderError::MissingReference) | |
606 | } | |
607 | } | |
608 | fn copy_overlapped(&mut self, dst: &mut [u8], mut off: usize, stride: usize, bx: usize, by: usize, xoff: i8, yoff1: i8) -> DecoderResult<()> { | |
609 | let ybias = if self.key_frame { -15 } else { 0 }; | |
610 | let yoff = yoff1 + ybias; | |
611 | ||
b83a3961 KS |
612 | let xpos = ((bx * 8) as isize) + (xoff as isize); |
613 | let ypos = ((by * 8) as isize) + (yoff as isize); | |
614 | validate!((xpos >= 0) && (xpos + 8 <= (self.cur_w as isize))); | |
615 | validate!((ypos >= 0) && (ypos + 8 <= (self.cur_h as isize))); | |
616 | ||
617 | let mut block: [u8; 64] = [0; 64]; | |
618 | let mut ref_off = ((off as isize) + (xoff as isize) + (yoff as isize) * (stride as isize)) as usize; | |
619 | for row in block.chunks_exact_mut(8) { | |
620 | row.copy_from_slice(&dst[ref_off..][..8]); | |
621 | ref_off += stride; | |
622 | } | |
623 | for row in block.chunks_exact(8) { | |
624 | let out = &mut dst[off..][..8]; | |
625 | out.copy_from_slice(row); | |
626 | off += stride; | |
627 | } | |
628 | ||
629 | Ok(()) | |
630 | } | |
631 | fn add_block(&self, coeffs: &[i32; 64], dst: &mut [u8], mut off: usize, stride: usize) { | |
632 | for src in coeffs.chunks_exact(8) { | |
633 | for i in 0..8 { | |
634 | let v = (dst[off + i] as i32) + src[i]; | |
635 | dst[off + i] = v as u8; | |
636 | } | |
637 | off += stride; | |
638 | } | |
639 | } | |
640 | fn idct_put(&self, coeffs: &[i32; 64], dst: &mut [u8], mut off: usize, stride: usize) { | |
641 | let mut tmp: [i32; 64] = [0; 64]; | |
642 | let mut row: [i32; 8] = [0; 8]; | |
643 | for i in 0..8 { | |
644 | idct!(coeffs, 8, tmp, 8, i, 0, 0); | |
645 | } | |
646 | for srow in tmp.chunks_exact(8) { | |
647 | idct!(srow, 1, row, 1, 0, 0x7F, 8); | |
648 | for i in 0..8 { | |
649 | dst[off + i] = row[i] as u8; | |
650 | } | |
651 | off += stride; | |
652 | } | |
653 | } | |
654 | fn idct_add(&self, coeffs: &[i32; 64], dst: &mut [u8], mut off: usize, stride: usize) { | |
655 | let mut tmp: [i32; 64] = [0; 64]; | |
656 | let mut row: [i32; 8] = [0; 8]; | |
657 | for i in 0..8 { | |
658 | idct!(coeffs, 8, tmp, 8, i, 0, 0); | |
659 | } | |
660 | for srow in tmp.chunks_exact(8) { | |
661 | idct!(srow, 1, row, 1, 0, 0x7F, 8); | |
662 | for i in 0..8 { | |
663 | let v = (dst[off + i] as i32) + row[i]; | |
664 | dst[off + i] = v as u8; | |
665 | } | |
666 | off += stride; | |
667 | } | |
668 | } | |
669 | ||
670 | fn decode_plane_binkb(&mut self, br: &mut BitReader, plane_no: usize, buf: &mut NAVideoBuffer<u8>) -> DecoderResult<()> { | |
671 | let stride = buf.get_stride(plane_no); | |
672 | let mut off = buf.get_offset(plane_no); | |
673 | let (width, height) = buf.get_dimensions(plane_no); | |
1a967e6b | 674 | let data = buf.get_data_mut().unwrap(); |
b83a3961 KS |
675 | let dst = data.as_mut_slice(); |
676 | let bw = (width + 7) >> 3; | |
677 | let bh = (height + 7) >> 3; | |
678 | self.cur_w = (width + 7) & !7; | |
679 | self.cur_h = (height + 7) & !7; | |
680 | self.cur_plane = plane_no; | |
681 | self.init_bundle_lengths_binkb(); | |
b83a3961 KS |
682 | for by in 0..bh { |
683 | self.read_bundles_binkb(br)?; | |
b83a3961 KS |
684 | for bx in 0..bw { |
685 | let mut coeffs: [i32; 64] = [0; 64]; | |
686 | let btype = self.btype.get_val()?; | |
b83a3961 KS |
687 | match btype { |
688 | 0 => { // skip | |
689 | }, | |
690 | 1 => { // run | |
691 | let scan = BINK_PATTERNS[br.read(4)? as usize]; | |
692 | let mut idx = 0; | |
693 | while idx < 63 { | |
694 | let run = br.read_bool()?; | |
695 | let len = (br.read(BINKB_RUN_BITS[idx])? as usize) + 1; | |
696 | validate!(idx + len <= 64); | |
697 | if run { | |
698 | let val = self.colors.get_val()?; | |
699 | for j in 0..len { | |
700 | let pos = scan[idx + j] as usize; | |
701 | dst[off + (pos >> 3) * stride + (pos & 7)] = val; | |
702 | } | |
703 | idx += len; | |
704 | } else { | |
705 | for _ in 0..len { | |
706 | let pos = scan[idx] as usize; | |
707 | dst[off + (pos >> 3) * stride + (pos & 7)] = self.colors.get_val()?; | |
708 | idx += 1; | |
709 | } | |
710 | } | |
711 | } | |
712 | if idx == 63 { | |
713 | let pos = scan[idx] as usize; | |
714 | dst[off + (pos >> 3) * stride + (pos & 7)] = self.colors.get_val()?; | |
715 | } | |
716 | }, | |
717 | 2 => { // intra | |
718 | coeffs[0] = self.intradc.get_val()? as i32; | |
719 | let q = self.intraq.get_val()? as usize; | |
720 | read_dct_coefficients(br, &mut coeffs, &BINK_SCAN, &self.qmat_b.intra_qmat, Some(q))?; | |
721 | self.idct_put(&coeffs, dst, off, stride); | |
722 | }, | |
723 | 3 => { // residue | |
724 | let xoff = self.xoff.get_val()?; | |
725 | let yoff = self.yoff.get_val()?; | |
726 | self.copy_overlapped(dst, off, stride, bx, by, xoff, yoff)?; | |
727 | let nmasks = self.nresidues.get_val()? as usize; | |
728 | read_residue(br, &mut coeffs, nmasks)?; | |
729 | self.add_block(&coeffs, dst, off, stride); | |
730 | }, | |
731 | 4 => { // inter | |
732 | let xoff = self.xoff.get_val()?; | |
733 | let yoff = self.yoff.get_val()?; | |
734 | self.copy_overlapped(dst, off, stride, bx, by, xoff, yoff)?; | |
735 | coeffs[0] = self.interdc.get_val()? as i32; | |
736 | let q = self.interq.get_val()? as usize; | |
737 | read_dct_coefficients(br, &mut coeffs, &BINK_SCAN, &self.qmat_b.inter_qmat, Some(q))?; | |
738 | self.idct_add(&coeffs, dst, off, stride); | |
739 | }, | |
740 | 5 => { // fill | |
741 | let fill = self.colors.get_val()?; | |
742 | for i in 0..8 { | |
743 | for j in 0..8 { dst[off + i * stride + j] = fill; } | |
744 | } | |
745 | }, | |
746 | 6 => { // pattern | |
747 | let clr: [u8; 2] = [ self.colors.get_val()?, self.colors.get_val()? ]; | |
748 | for i in 0..8 { | |
749 | let pattern = self.pattern.get_val()? as usize; | |
750 | for j in 0..8 { | |
751 | dst[off + i * stride + j] = clr[(pattern >> j) & 1]; | |
752 | } | |
753 | } | |
754 | }, | |
755 | 7 => { // motion block | |
756 | let xoff = self.xoff.get_val()?; | |
757 | let yoff = self.yoff.get_val()?; | |
758 | self.copy_overlapped(dst, off, stride, bx, by, xoff, yoff)?; | |
759 | }, | |
760 | 8 => { // raw | |
761 | for i in 0..8 { | |
762 | for j in 0..8 { | |
763 | dst[off + i * stride + j] = self.colors.get_val()?; | |
764 | } | |
765 | } | |
766 | }, | |
767 | _ => { return Err(DecoderError::InvalidData); }, | |
768 | }; | |
769 | off += 8; | |
770 | } | |
771 | off += stride * 8 - bw * 8; | |
772 | } | |
773 | if (br.tell() & 0x1F) != 0 { | |
774 | let skip = (32 - (br.tell() & 0x1F)) as u32; | |
775 | br.skip(skip)?; | |
776 | } | |
777 | Ok(()) | |
778 | } | |
779 | fn handle_block(&mut self, br: &mut BitReader, bx: usize, by: usize, | |
780 | dst: &mut [u8], off: usize, stride: usize, btype: u8, scaled: bool) -> DecoderResult<()> { | |
781 | let mut oblock: [u8; 64] = [0; 64]; | |
782 | let mut coeffs: [i32; 64] = [0; 64]; | |
783 | match btype { | |
784 | SKIP_BLOCK => { | |
785 | validate!(!scaled); | |
786 | self.copy_block(dst, off, stride, bx, by, 0, 0)?; | |
787 | }, | |
788 | SCALED_BLOCK => { | |
789 | validate!(!scaled); | |
790 | let sbtype = self.sbtype.get_val()?; | |
791 | self.handle_block(br, bx, by, dst, off, stride, sbtype, true)?; | |
792 | }, | |
793 | MOTION_BLOCK => { | |
794 | validate!(!scaled); | |
795 | let xoff = self.xoff.get_val()?; | |
796 | let yoff = self.yoff.get_val()?; | |
797 | self.copy_block(dst, off, stride, bx, by, xoff, yoff)?; | |
798 | }, | |
799 | RUN_BLOCK => { | |
800 | let scan = BINK_PATTERNS[br.read(4)? as usize]; | |
801 | let mut idx = 0; | |
802 | while idx < 63 { | |
803 | let run = (self.run.get_val()? as usize) + 1; | |
804 | validate!(idx + run <= 64); | |
805 | if br.read_bool()? { | |
806 | let val = self.colors.get_val()?; | |
807 | for j in 0..run { | |
808 | oblock[scan[idx + j] as usize] = val; | |
809 | } | |
810 | idx += run; | |
811 | } else { | |
812 | for _ in 0..run { | |
813 | oblock[scan[idx] as usize] = self.colors.get_val()?; | |
814 | idx += 1; | |
815 | } | |
816 | } | |
817 | } | |
818 | if idx == 63 { oblock[scan[63] as usize] = self.colors.get_val()?; } | |
819 | self.put_block(&oblock, dst, off, stride, scaled); | |
820 | }, | |
821 | RESIDUE_BLOCK => { | |
822 | validate!(!scaled); | |
823 | let xoff = self.xoff.get_val()?; | |
824 | let yoff = self.yoff.get_val()?; | |
825 | self.copy_block(dst, off, stride, bx, by, xoff, yoff)?; | |
826 | let nmasks = br.read(7)? as usize; | |
827 | read_residue(br, &mut coeffs, nmasks)?; | |
828 | self.add_block(&coeffs, dst, off, stride); | |
829 | }, | |
830 | INTRA_BLOCK => { | |
831 | coeffs[0] = self.intradc.get_val()? as i32; | |
832 | read_dct_coefficients(br, &mut coeffs, &BINK_SCAN, BINK_INTRA_QUANT, None)?; | |
833 | if !scaled { | |
834 | self.idct_put(&coeffs, dst, off, stride); | |
835 | } else { | |
836 | self.idct_put(&coeffs, &mut oblock, 0, 8); | |
837 | self.put_block(&oblock, dst, off, stride, scaled); | |
838 | } | |
839 | }, | |
840 | FILL_BLOCK => { | |
841 | let fill = self.colors.get_val()?; | |
842 | oblock = [fill; 64]; | |
843 | self.put_block(&oblock, dst, off, stride, scaled); | |
844 | }, | |
845 | INTER_BLOCK => { | |
846 | validate!(!scaled); | |
847 | let xoff = self.xoff.get_val()?; | |
848 | let yoff = self.yoff.get_val()?; | |
849 | self.copy_block(dst, off, stride, bx, by, xoff, yoff)?; | |
850 | coeffs[0] = self.interdc.get_val()? as i32; | |
851 | read_dct_coefficients(br, &mut coeffs, &BINK_SCAN, BINK_INTER_QUANT, None)?; | |
852 | self.idct_add(&coeffs, dst, off, stride); | |
853 | }, | |
854 | PATTERN_BLOCK => { | |
855 | let clr: [u8; 2] = [ self.colors.get_val()?, self.colors.get_val()? ]; | |
856 | for i in 0..8 { | |
857 | let pattern = self.pattern.get_val()? as usize; | |
858 | for j in 0..8 { | |
859 | oblock[i * 8 + j] = clr[(pattern >> j) & 1]; | |
860 | } | |
861 | } | |
862 | self.put_block(&oblock, dst, off, stride, scaled); | |
863 | }, | |
864 | RAW_BLOCK => { | |
865 | for i in 0..8 { | |
866 | for j in 0..8 { | |
867 | oblock[i * 8 + j] = self.colors.get_val()?; | |
868 | } | |
869 | } | |
870 | self.put_block(&oblock, dst, off, stride, scaled); | |
871 | }, | |
872 | _ => { return Err(DecoderError::InvalidData); }, | |
873 | }; | |
874 | Ok(()) | |
875 | } | |
876 | fn decode_plane(&mut self, br: &mut BitReader, plane_no: usize, buf: &mut NAVideoBuffer<u8>) -> DecoderResult<()> { | |
877 | let stride = buf.get_stride(plane_no); | |
878 | let mut off = buf.get_offset(plane_no); | |
879 | let (width, height) = buf.get_dimensions(plane_no); | |
1a967e6b | 880 | let data = buf.get_data_mut().unwrap(); |
b83a3961 KS |
881 | let dst = data.as_mut_slice(); |
882 | let bw = (width + 7) >> 3; | |
883 | let bh = (height + 7) >> 3; | |
884 | self.cur_w = (width + 7) & !7; | |
885 | self.cur_h = (height + 7) & !7; | |
886 | self.cur_plane = plane_no; | |
887 | self.init_bundle_lengths(width.max(8), bw); | |
888 | self.read_bundles_desc(br)?; | |
889 | for by in 0..bh { | |
890 | self.read_bundles(br)?; | |
891 | let mut bx = 0; | |
892 | while bx < bw { | |
893 | let btype = self.btype.get_val()?; | |
894 | if btype == SCALED_BLOCK && (by & 1) == 1 { // already decoded scaled block, skip | |
895 | bx += 2; | |
896 | continue; | |
897 | } | |
898 | self.handle_block(br, bx, by, dst, off + bx * 8, stride, btype, false)?; | |
899 | if btype == SCALED_BLOCK { | |
900 | bx += 1; | |
901 | } | |
902 | bx += 1; | |
903 | } | |
904 | off += stride * 8; | |
905 | } | |
906 | if (br.tell() & 0x1F) != 0 { | |
907 | let skip = (32 - (br.tell() & 0x1F)) as u32; | |
908 | br.skip(skip)?; | |
909 | } | |
910 | Ok(()) | |
911 | } | |
912 | } | |
913 | ||
914 | fn get_coef(br: &mut BitReader, bits1: u8) -> DecoderResult<i32> { | |
915 | let t; | |
916 | if bits1 == 1 { | |
917 | t = if br.read_bool()? { -1 } else { 1 }; | |
918 | } else { | |
919 | let bits = bits1 - 1; | |
920 | let val = (br.read(bits)? as i32) | (1 << bits); | |
921 | if br.read_bool()? { | |
922 | t = -val; | |
923 | } else { | |
924 | t = val; | |
925 | } | |
926 | } | |
927 | Ok(t) | |
928 | } | |
929 | ||
930 | fn read_dct_coefficients(br: &mut BitReader, block: &mut [i32; 64], scan: &[usize; 64], | |
931 | quant_matrices: &[[i32; 64]; 16], q: Option<usize>) -> DecoderResult<()> { | |
932 | let mut coef_list: [i32; 128] = [0; 128]; | |
933 | let mut mode_list: [u8; 128] = [0; 128]; | |
934 | let mut list_start = 64; | |
935 | let mut list_end = 64; | |
936 | let mut coef_idx: [usize; 64] = [0; 64]; | |
937 | let mut coef_count = 0; | |
938 | ||
939 | coef_list[list_end] = 4; mode_list[list_end] = 0; list_end += 1; | |
940 | coef_list[list_end] = 24; mode_list[list_end] = 0; list_end += 1; | |
941 | coef_list[list_end] = 44; mode_list[list_end] = 0; list_end += 1; | |
942 | coef_list[list_end] = 1; mode_list[list_end] = 3; list_end += 1; | |
943 | coef_list[list_end] = 2; mode_list[list_end] = 3; list_end += 1; | |
944 | coef_list[list_end] = 3; mode_list[list_end] = 3; list_end += 1; | |
945 | ||
946 | let mut bits1 = br.read(4)? as u8; | |
947 | while bits1 >= 1 { | |
948 | let mut list_pos = list_start; | |
949 | while list_pos < list_end { | |
950 | let ccoef = coef_list[list_pos]; | |
951 | let mode = mode_list[list_pos]; | |
952 | if (mode == 0 && ccoef == 0) || !br.read_bool()? { | |
953 | list_pos += 1; | |
954 | continue; | |
955 | } | |
956 | match mode { | |
957 | 0 | 2 => { | |
958 | if mode == 0 { | |
959 | coef_list[list_pos] = ccoef + 4; | |
960 | mode_list[list_pos] = 1; | |
961 | } else { | |
962 | coef_list[list_pos] = 0; | |
963 | mode_list[list_pos] = 0; | |
964 | list_pos += 1; | |
965 | } | |
966 | for i in 0..4 { | |
967 | if br.read_bool()? { | |
968 | list_start -= 1; | |
969 | coef_list[list_start] = ccoef + i; | |
970 | mode_list[list_start] = 3; | |
971 | } else { | |
972 | let idx = (ccoef + i) as usize; | |
973 | block[scan[idx]] = get_coef(br, bits1)?; | |
974 | coef_idx[coef_count] = idx; | |
975 | coef_count += 1; | |
976 | } | |
977 | } | |
978 | }, | |
979 | 1 => { | |
980 | mode_list[list_pos] = 2; | |
981 | for i in 0..3 { | |
982 | coef_list[list_end] = ccoef + i * 4 + 4; | |
983 | mode_list[list_end] = 2; | |
984 | list_end += 1; | |
985 | } | |
986 | }, | |
987 | 3 => { | |
988 | let idx = ccoef as usize; | |
989 | block[scan[idx]] = get_coef(br, bits1)?; | |
990 | coef_idx[coef_count] = idx; | |
991 | coef_count += 1; | |
992 | coef_list[list_pos] = 0; | |
993 | mode_list[list_pos] = 0; | |
994 | list_pos += 1; | |
995 | }, | |
996 | _ => unreachable!(), | |
997 | }; | |
998 | } | |
999 | bits1 -= 1; | |
1000 | } | |
1001 | ||
1002 | let q_index = if let Some(qidx) = q { qidx } else { br.read(4)? as usize }; | |
1003 | let qmat = &quant_matrices[q_index]; | |
1004 | block[0] = block[0].wrapping_mul(qmat[0]) >> 11; | |
7e6086e5 | 1005 | for idx in coef_idx.iter().take(coef_count) { |
b83a3961 KS |
1006 | block[scan[*idx]] = block[scan[*idx]].wrapping_mul(qmat[*idx]) >> 11; |
1007 | } | |
1008 | ||
1009 | Ok(()) | |
1010 | } | |
1011 | ||
1012 | fn read_residue(br: &mut BitReader, block: &mut [i32; 64], mut masks_count: usize) -> DecoderResult<()> { | |
1013 | let mut coef_list: [i32; 128] = [0; 128]; | |
1014 | let mut mode_list: [u8; 128] = [0; 128]; | |
1015 | let mut list_start = 64; | |
1016 | let mut list_end = 64; | |
1017 | let mut nz_coef_idx: [usize; 64] = [0; 64]; | |
1018 | let mut nz_coef_count = 0; | |
1019 | ||
1020 | coef_list[list_end] = 4; mode_list[list_end] = 0; list_end += 1; | |
1021 | coef_list[list_end] = 24; mode_list[list_end] = 0; list_end += 1; | |
1022 | coef_list[list_end] = 44; mode_list[list_end] = 0; list_end += 1; | |
1023 | coef_list[list_end] = 0; mode_list[list_end] = 2; list_end += 1; | |
1024 | ||
1025 | let mut mask = 1 << br.read(3)?; | |
1026 | while mask > 0 { | |
1027 | for i in 0..nz_coef_count { | |
1028 | if !br.read_bool()? { continue; } | |
1029 | let idx = nz_coef_idx[i]; | |
1030 | if block[idx] < 0 { | |
1031 | block[idx] -= mask; | |
1032 | } else { | |
1033 | block[idx] += mask; | |
1034 | } | |
1035 | if masks_count == 0 { | |
1036 | return Ok(()); | |
1037 | } | |
1038 | masks_count -= 1; | |
1039 | } | |
1040 | let mut list_pos = list_start; | |
1041 | while list_pos < list_end { | |
1042 | let ccoef = coef_list[list_pos]; | |
1043 | let mode = mode_list[list_pos]; | |
1044 | if (mode == 0 && ccoef == 0) || !br.read_bool()? { | |
1045 | list_pos += 1; | |
1046 | continue; | |
1047 | } | |
1048 | match mode { | |
1049 | 0 | 2 => { | |
1050 | if mode == 0 { | |
1051 | coef_list[list_pos] = ccoef + 4; | |
1052 | mode_list[list_pos] = 1; | |
1053 | } else { | |
1054 | coef_list[list_pos] = 0; | |
1055 | mode_list[list_pos] = 0; | |
1056 | list_pos += 1; | |
1057 | } | |
1058 | for i in 0..4 { | |
1059 | if br.read_bool()? { | |
1060 | list_start -= 1; | |
1061 | coef_list[list_start] = ccoef + i; | |
1062 | mode_list[list_start] = 3; | |
1063 | } else { | |
1064 | let idx = (ccoef + i) as usize; | |
1065 | nz_coef_idx[nz_coef_count] = BINK_SCAN[idx]; | |
1066 | nz_coef_count += 1; | |
1067 | block[BINK_SCAN[idx]] = if br.read_bool()? { -mask } else { mask }; | |
1068 | if masks_count == 0 { | |
1069 | return Ok(()); | |
1070 | } | |
1071 | masks_count -= 1; | |
1072 | } | |
1073 | } | |
1074 | }, | |
1075 | 1 => { | |
1076 | mode_list[list_pos] = 2; | |
1077 | for i in 0..3 { | |
1078 | coef_list[list_end] = ccoef + i * 4 + 4; | |
1079 | mode_list[list_end] = 2; | |
1080 | list_end += 1; | |
1081 | } | |
1082 | }, | |
1083 | 3 => { | |
1084 | let idx = ccoef as usize; | |
1085 | nz_coef_idx[nz_coef_count] = BINK_SCAN[idx]; | |
1086 | nz_coef_count += 1; | |
1087 | block[BINK_SCAN[idx]] = if br.read_bool()? { -mask } else { mask }; | |
1088 | coef_list[list_pos] = 0; | |
1089 | mode_list[list_pos] = 0; | |
1090 | list_pos += 1; | |
1091 | if masks_count == 0 { | |
1092 | return Ok(()); | |
1093 | } | |
1094 | masks_count -= 1; | |
1095 | }, | |
1096 | _ => unreachable!(), | |
1097 | }; | |
1098 | } | |
1099 | mask >>= 1; | |
1100 | } | |
d24468d9 | 1101 | |
b83a3961 KS |
1102 | Ok(()) |
1103 | } | |
1104 | ||
1105 | const BINK_FLAG_ALPHA: u32 = 0x00100000; | |
1106 | const BINK_FLAG_GRAY: u32 = 0x00020000; | |
1107 | ||
1108 | impl NADecoder for BinkDecoder { | |
01613464 | 1109 | fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> { |
b83a3961 KS |
1110 | if let NACodecTypeInfo::Video(vinfo) = info.get_properties() { |
1111 | let w = vinfo.get_width(); | |
1112 | let h = vinfo.get_height(); | |
1113 | ||
1114 | let edata = info.get_extradata().unwrap(); | |
1115 | validate!(edata.len() >= 8); | |
1116 | ||
1117 | let mut mr = MemoryReader::new_read(&edata); | |
1118 | let mut br = ByteReader::new(&mut mr); | |
1119 | let magic = br.read_u32be()?; | |
1120 | let flags = br.read_u32le()?; | |
1121 | ||
1122 | self.is_ver_b = (magic & 0xFF) == (b'b' as u32); | |
1123 | self.is_ver_i = (magic & 0xFF) >= (b'i' as u32); | |
1124 | self.has_alpha = (flags & BINK_FLAG_ALPHA) != 0; | |
1125 | self.is_gray = (flags & BINK_FLAG_GRAY) != 0; | |
1126 | self.swap_uv = (magic & 0xFF) >= (b'h' as u32); | |
1127 | if self.has_alpha && self.is_gray { return Err(DecoderError::NotImplemented); } | |
1128 | ||
1129 | let aplane = if self.has_alpha { Some(NAPixelChromaton::new(0, 0, false, 8, 0, 3, 1)) } else { None }; | |
1130 | let fmt; | |
1131 | if !self.is_gray { | |
1132 | fmt = NAPixelFormaton::new(ColorModel::YUV(YUVSubmodel::YUVJ), | |
1133 | Some(NAPixelChromaton::new(0, 0, false, 8, 0, 0, 1)), | |
1134 | Some(NAPixelChromaton::new(1, 1, false, 8, 0, 1, 1)), | |
1135 | Some(NAPixelChromaton::new(1, 1, false, 8, 0, 2, 1)), | |
1136 | aplane, None, | |
1137 | 0, if self.has_alpha { 4 } else { 3 } ); | |
1138 | } else { | |
1139 | fmt = NAPixelFormaton::new(ColorModel::YUV(YUVSubmodel::YUVJ), | |
1140 | Some(NAPixelChromaton::new(0, 0, false, 8, 0, 0, 1)), | |
1141 | None, None, None, None, 0, 1); | |
1142 | } | |
1143 | let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(w, h, false, fmt)); | |
2422d969 | 1144 | self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref(); |
b83a3961 KS |
1145 | |
1146 | //self.init_bundle_lengths(w.max(8), (w + 7) >> 3); | |
1147 | self.init_bundle_bufs((w + 7) >> 3, (h + 7) >> 3); | |
1148 | ||
1149 | if self.is_ver_b { | |
1150 | self.qmat_b.calc_binkb_quants(); | |
1151 | } | |
1152 | ||
1153 | Ok(()) | |
1154 | } else { | |
1155 | Err(DecoderError::InvalidData) | |
1156 | } | |
1157 | } | |
01613464 | 1158 | fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> { |
b83a3961 KS |
1159 | let src = pkt.get_buffer(); |
1160 | ||
fa90ccfb | 1161 | let mut br = BitReader::new(&src, BitReaderMode::LE); |
b83a3961 KS |
1162 | |
1163 | let mut buf; | |
1164 | self.key_frame = pkt.is_keyframe(); | |
1165 | if self.is_ver_b { | |
1166 | let bufret = self.hams.clone_ref(); | |
1167 | if let Some(bbuf) = bufret { | |
1168 | buf = bbuf; | |
1169 | } else { | |
7e6086e5 | 1170 | let bufinfo = alloc_video_buffer(self.info.get_properties().get_video_info().unwrap(), 4)?; |
b83a3961 KS |
1171 | buf = bufinfo.get_vbuf().unwrap(); |
1172 | self.key_frame = true; | |
1173 | self.hams.add_frame(buf); | |
1174 | buf = self.hams.get_output_frame().unwrap(); | |
1175 | } | |
1176 | } else { | |
7e6086e5 | 1177 | let bufinfo = alloc_video_buffer(self.info.get_properties().get_video_info().unwrap(), 4)?; |
b83a3961 KS |
1178 | buf = bufinfo.get_vbuf().unwrap(); |
1179 | } | |
1180 | ||
b83a3961 KS |
1181 | let nplanes = if self.is_gray { 1 } else { 3 }; |
1182 | if self.has_alpha { | |
1183 | validate!(!self.is_ver_b); | |
1184 | if self.is_ver_i { | |
1185 | br.skip(32)?; | |
1186 | } | |
1187 | self.decode_plane(&mut br, nplanes, &mut buf)?; | |
1188 | } | |
1189 | if self.is_ver_i { | |
1190 | br.skip(32)?; | |
1191 | } | |
1192 | for plane in 0..nplanes { | |
1193 | if self.is_ver_b { | |
1194 | self.decode_plane_binkb(&mut br, plane, &mut buf)?; | |
1195 | } else { | |
1196 | let plane_idx = if plane > 0 && self.swap_uv { plane ^ 3 } else { plane }; | |
1197 | self.decode_plane(&mut br, plane_idx, &mut buf)?; | |
1198 | } | |
1199 | } | |
b70cc006 | 1200 | let bufinfo = NABufferType::Video(buf); |
b83a3961 KS |
1201 | if !self.is_ver_b { |
1202 | self.ips.add_frame(bufinfo.get_vbuf().unwrap()); | |
1203 | } | |
1204 | ||
1205 | let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo); | |
1206 | frm.set_frame_type(FrameType::P); | |
171860fc | 1207 | Ok(frm.into_ref()) |
b83a3961 | 1208 | } |
f9be4e75 KS |
1209 | fn flush(&mut self) { |
1210 | self.ips.clear(); | |
1211 | } | |
b83a3961 | 1212 | } |
606c448e | 1213 | |
7d57ae2f KS |
1214 | impl NAOptionHandler for BinkDecoder { |
1215 | fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] } | |
1216 | fn set_options(&mut self, _options: &[NAOption]) { } | |
1217 | fn query_option_value(&self, _name: &str) -> Option<NAValue> { None } | |
1218 | } | |
1219 | ||
08a1fab7 | 1220 | pub fn get_decoder() -> Box<dyn NADecoder + Send> { |
b83a3961 KS |
1221 | Box::new(BinkDecoder::new()) |
1222 | } | |
1223 | ||
1224 | #[cfg(test)] | |
1225 | mod test { | |
1226 | use nihav_core::codecs::RegisteredDecoders; | |
1227 | use nihav_core::demuxers::RegisteredDemuxers; | |
ce742854 | 1228 | use nihav_codec_support::test::dec_video::*; |
78fb6560 | 1229 | use crate::rad_register_all_decoders; |
e64739f8 | 1230 | use crate::rad_register_all_demuxers; |
b83a3961 | 1231 | #[test] |
e3dbe0a0 | 1232 | fn test_binkvid_b() { |
b83a3961 KS |
1233 | let mut dmx_reg = RegisteredDemuxers::new(); |
1234 | rad_register_all_demuxers(&mut dmx_reg); | |
1235 | let mut dec_reg = RegisteredDecoders::new(); | |
78fb6560 | 1236 | rad_register_all_decoders(&mut dec_reg); |
b83a3961 | 1237 | |
886cde48 | 1238 | // sample: https://samples.mplayerhq.hu/game-formats/bink/bikb/NEW.BIK |
e3dbe0a0 KS |
1239 | test_decoding("bink", "bink-video", "assets/RAD/NEW.BIK", Some(16), &dmx_reg, &dec_reg, |
1240 | ExpectedTestResult::MD5Frames(vec![ | |
1241 | [0x00edef7e, 0x7efad3b1, 0x7e8bdd74, 0x3f6b00ba], | |
1242 | [0xbc40683f, 0xbeb1c5e4, 0x934777b5, 0x8a8a350d], | |
1243 | [0x68b78627, 0x28ceb63d, 0xfdb1171a, 0x23e69d90], | |
1244 | [0xc8d907a0, 0xb8d44079, 0x0286336b, 0x996479f3], | |
1245 | [0x57bbe4ec, 0xdb8bb9c2, 0x0e6f1fd6, 0xe180125e], | |
1246 | [0xd43c2ae0, 0x4010007f, 0x2a6360a1, 0xb5203a05], | |
1247 | [0xa883acf6, 0x25843f92, 0x4ced9a46, 0x6d513ad9], | |
1248 | [0x959e843f, 0x8d8182b9, 0x3f12d29b, 0x2af8d39f], | |
1249 | [0x93840946, 0x1188c6d1, 0xd5499833, 0x62aac0c6], | |
1250 | [0x4e5a56a6, 0x21517d9a, 0xbe1f270d, 0xe5621945], | |
1251 | [0x1b133742, 0x1eb1bf0a, 0x68cab2e3, 0x92176b5d], | |
1252 | [0x0cf78c43, 0x4bc15549, 0x3dd94323, 0x737eaaae], | |
1253 | [0xdd731c4a, 0x801453b3, 0xa38bef3e, 0x285cfdfe], | |
1254 | [0xe1fec4ee, 0x46737abc, 0x8c452209, 0xc8c6addd], | |
1255 | [0x2978aa50, 0x5f1e6d5a, 0x1f5b0fba, 0xb8e32196], | |
1256 | [0x2e1e95ab, 0x8e31a0b0, 0xfe998512, 0xea9397b6], | |
1257 | [0xf7f6c0d8, 0x893e77a7, 0xdfe0309f, 0xf5e644e2]])); | |
1258 | } | |
1259 | #[test] | |
1260 | fn test_binkvid() { | |
1261 | let mut dmx_reg = RegisteredDemuxers::new(); | |
1262 | rad_register_all_demuxers(&mut dmx_reg); | |
1263 | let mut dec_reg = RegisteredDecoders::new(); | |
78fb6560 | 1264 | rad_register_all_decoders(&mut dec_reg); |
b83a3961 | 1265 | |
886cde48 | 1266 | // sample: https://samples.mplayerhq.hu/game-formats/bink/ActivisionLogo.bik |
e3dbe0a0 KS |
1267 | test_decoding("bink", "bink-video", "assets/RAD/ActivisionLogo.bik", Some(42), |
1268 | &dmx_reg, &dec_reg, | |
1269 | ExpectedTestResult::MD5([0x41128884, 0x73a8c710, 0x5072ea4a, 0x8caca428])); | |
b83a3961 | 1270 | } |
606c448e | 1271 | } |