]> git.nihav.org Git - nihav.git/blame - nihav-duck/src/codecs/vp56.rs
duck: fix or silence clippy warnings
[nihav.git] / nihav-duck / src / codecs / vp56.rs
CommitLineData
3584b223
KS
1use nihav_core::codecs::*;
2use nihav_core::io::bitreader::*;
b4d5b851 3use nihav_codec_support::codecs::{MV, ZERO_MV};
3584b223
KS
4use super::vpcommon::*;
5
6pub const TOKEN_LARGE: u8 = 5;
7pub const TOKEN_EOB: u8 = 42;
8
9#[derive(Clone,Copy,Debug,Default)]
10#[allow(dead_code)]
11pub struct VP56Header {
12 pub is_intra: bool,
13 pub is_golden: bool,
14 pub quant: u8,
15 pub multistream: bool,
16 pub use_huffman: bool,
17 pub version: u8,
18 pub profile: u8,
19 pub interlaced: bool,
20 pub offset: u16,
21 pub mb_w: u8,
22 pub mb_h: u8,
23 pub disp_w: u8,
24 pub disp_h: u8,
25 pub scale: u8,
26}
27
28#[derive(Clone,Copy,Default)]
29pub struct VP56MVModel {
30 pub nz_prob: u8,
31 pub sign_prob: u8,
32 pub raw_probs: [u8; 8],
33 pub tree_probs: [u8; 7],
34}
35
36#[derive(Clone,Copy,Default)]
37pub struct VP56MBTypeModel {
38 pub probs: [u8; 10],
39}
40
41#[derive(Clone,Copy,Default)]
42pub struct VP56CoeffModel {
43 pub dc_token_probs: [[[u8; 5]; 6]; 6],
44 pub dc_value_probs: [u8; 11],
45 pub ac_ctype_probs: [[[[u8; 5]; 5]; 6]; 3],
46 pub ac_type_probs: [[[[u8; 5]; 6]; 3]; 3],
47 pub ac_val_probs: [[[u8; 11]; 6]; 3],
48}
49
50pub struct VP6Models {
51 pub scan_order: [usize; 64],
52 pub scan: [usize; 64],
53 pub zigzag: [usize; 64],
54 pub zero_run_probs: [[u8; 14]; 2],
55}
56
57const MAX_HUFF_ELEMS: usize = 12;
58#[derive(Clone,Copy,Default)]
59pub struct VP6Huff {
60 pub codes: [u16; MAX_HUFF_ELEMS],
61 pub bits: [u8; MAX_HUFF_ELEMS],
62}
63
64#[derive(Clone,Copy,Default)]
65struct Node {
66 weight: u16,
67 sym: i8,
68 ch0: usize,
69 ch1: usize,
70}
71
72fn prob2weight(a: u8, b: u8) -> u8 {
47933c6d 73 let w = ((u16::from(a) * u16::from(b)) >> 8) as u8;
3584b223
KS
74 if w == 0 {
75 1
76 } else {
77 w
78 }
79}
80
81impl VP6Huff {
82 fn build_codes(&mut self, probs: &[u8; 11]) {
83 let mut weights = [0u8; 12];
84
85 weights[11] = prob2weight( probs[0], probs[ 1]);
86 weights[ 0] = prob2weight( probs[0], !probs[ 1]);
87 weights[ 1] = prob2weight(!probs[0], probs[ 2]);
88 let lvroot = prob2weight(!probs[0], !probs[ 2]);
89 let tworoot = prob2weight( lvroot, probs[ 3]);
90 let hlroot = prob2weight( lvroot, !probs[ 3]);
91 weights[ 2] = prob2weight( tworoot, probs[ 4]);
92 let root34 = prob2weight( tworoot, !probs[ 4]);
93 weights[ 3] = prob2weight( root34, probs[ 5]);
94 weights[ 4] = prob2weight( root34, !probs[ 5]);
95 let c1root = prob2weight( hlroot, probs[ 6]);
96 let c34root = prob2weight( hlroot, !probs[ 6]);
97 weights[ 5] = prob2weight( c1root, probs[ 7]);
98 weights[ 6] = prob2weight( c1root, !probs[ 7]);
99 let c3root = prob2weight( c34root, probs[ 8]);
100 let c4root = prob2weight( c34root, !probs[ 8]);
101 weights[ 7] = prob2weight( c3root, probs[ 9]);
102 weights[ 8] = prob2weight( c3root, !probs[ 9]);
103 weights[ 9] = prob2weight( c4root, probs[10]);
104 weights[10] = prob2weight( c4root, !probs[10]);
105
106 self.build(&weights);
107 }
108 fn build_codes_zero_run(&mut self, probs: &[u8; 14]) {
109 let mut weights = [0u8; 9];
110
111 let root = prob2weight( probs[0], probs[1]);
112 weights[0] = prob2weight( root, probs[2]);
113 weights[1] = prob2weight( root, !probs[2]);
114
115 let root = prob2weight( probs[0], !probs[1]);
116 weights[2] = prob2weight( root, probs[3]);
117 weights[3] = prob2weight( root, !probs[3]);
118
119 let root = prob2weight(!probs[0], probs[4]);
120 weights[8] = prob2weight(!probs[0], !probs[4]);
121 let root1 = prob2weight( root, probs[5]);
122 let root2 = prob2weight( root, !probs[5]);
123 weights[4] = prob2weight( root1, probs[6]);
124 weights[5] = prob2weight( root1, !probs[6]);
125 weights[6] = prob2weight( root2, probs[7]);
126 weights[7] = prob2weight( root2, !probs[7]);
127
128 self.build(&weights);
129 }
130 fn build(&mut self, weights: &[u8]) {
131 let mut nodes = [Node::default(); MAX_HUFF_ELEMS * 2];
132 let mut nlen = 0;
133
134 for w in weights.iter().rev() {
47933c6d 135 let weight = u16::from(*w);
3584b223
KS
136 let mut pos = nlen;
137 for i in 0..nlen {
138 if nodes[i].weight > weight {
139 pos = i;
140 break;
141 }
142 }
143 for j in (pos..nlen).rev() {
144 nodes[j + 1] = nodes[j];
145 }
146 nodes[pos].weight = weight;
147 nodes[pos].sym = (weights.len() - nlen - 1) as i8;
148 nlen += 1;
149 }
150
151 let mut low = 0;
152 for _ in 0..nlen-1 {
153 let nnode = Node {
154 weight: nodes[low + 0].weight + nodes[low + 1].weight,
155 sym: -1,
156 ch0: low + 0,
157 ch1: low + 1,
158 };
159 low += 2;
160 let mut pos = low;
161 while (pos < nlen) && (nodes[pos].weight < nnode.weight) {
162 pos += 1;
163 }
164 for j in (pos..nlen).rev() {
165 nodes[j + 1] = nodes[j];
166 }
167 nodes[pos] = nnode;
168 nlen += 1;
169 }
170 self.get_codes(&nodes, nlen - 1, 0, 0);
171 for i in nlen..self.codes.len() {
172 self.codes[i] = self.codes[0];
173 self.bits[i] = self.bits[0];
174 }
175 }
176 fn get_codes(&mut self, nodes: &[Node], pos: usize, code: u16, len: u8) {
177 if nodes[pos].sym >= 0 {
178 self.codes[nodes[pos].sym as usize] = code;
179 self.bits [nodes[pos].sym as usize] = len;
180 } else {
181 self.get_codes(nodes, nodes[pos].ch0, (code << 1) | 0, len + 1);
182 self.get_codes(nodes, nodes[pos].ch1, (code << 1) | 1, len + 1);
183 }
184 }
185}
186
187pub trait ReadHuff {
188 fn read_huff(&mut self, huff: &VP6Huff) -> DecoderResult<u8>;
189}
190
191impl<'a> ReadHuff for BitReader<'a> {
192 fn read_huff(&mut self, huff: &VP6Huff) -> DecoderResult<u8> {
193 let peekval = self.peek(16);
194 for (i, (code, bit)) in huff.codes.iter().zip(huff.bits.iter()).enumerate() {
47933c6d
KS
195 if (peekval >> (16 - *bit)) == u32::from(*code) {
196 self.skip(u32::from(*bit))?;
3584b223
KS
197 return Ok(i as u8);
198 }
199 }
200 Err(DecoderError::InvalidData)
201 }
202}
203
204#[derive(Clone,Copy,Default)]
205pub struct VP6HuffModels {
206 pub dc_token_tree: [VP6Huff; 2],
207 pub ac_token_tree: [[[VP6Huff; 6]; 3]; 2],
208 pub zero_run_tree: [VP6Huff; 2],
209}
210
211impl VP6Models {
212 fn new() -> Self {
213 Self {
214 scan_order: [0; 64],
215 scan: [0; 64],
216 zigzag: [0; 64],
217 zero_run_probs: [[0; 14]; 2],
218 }
219 }
220}
221
222pub struct VP56Models {
223 pub mv_models: [VP56MVModel; 2],
224 pub mbtype_models: [[VP56MBTypeModel; 10]; 3],
225 pub coeff_models: [VP56CoeffModel; 2],
226 pub prob_xmitted: [[u8; 20]; 3],
227 pub vp6models: VP6Models,
228 pub vp6huff: VP6HuffModels,
229}
230
231impl VP56Models {
232 fn new() -> Self {
233 Self {
234 mv_models: [VP56MVModel::default(); 2],
235 mbtype_models: [[VP56MBTypeModel::default(); 10]; 3],
236 coeff_models: [VP56CoeffModel::default(); 2],
237 prob_xmitted: [[0; 20]; 3],
238 vp6models: VP6Models::new(),
239 vp6huff: VP6HuffModels::default(),
240 }
241 }
242}
243
244pub trait VP56Parser {
245 fn parse_header(&mut self, bc: &mut BoolCoder) -> DecoderResult<VP56Header>;
246 fn reset_models(&self, models: &mut VP56Models);
247 fn decode_mv(&self, bc: &mut BoolCoder, model: &VP56MVModel) -> i16;
248 fn decode_mv_models(&self, bc: &mut BoolCoder, models: &mut [VP56MVModel; 2]) -> DecoderResult<()>;
249 fn decode_coeff_models(&self, bc: &mut BoolCoder, models: &mut VP56Models, is_intra: bool) -> DecoderResult<()>;
250 fn decode_block(&self, bc: &mut BoolCoder, coeffs: &mut [i16; 64], model: &VP56CoeffModel, vp6model: &VP6Models, fstate: &mut FrameState) -> DecoderResult<()>;
251 fn decode_block_huff(&self, br: &mut BitReader, coeffs: &mut [i16; 64], vp6model: &VP6Models, model: &VP6HuffModels, fstate: &mut FrameState) -> DecoderResult<()>;
252 fn mc_block(&self, dst: &mut NASimpleVideoFrame<u8>, mc_buf: NAVideoBufferRef<u8>, src: NAVideoBufferRef<u8>, plane: usize, x: usize, y: usize, mv: MV, loop_thr: i16);
253}
254
255enum CoeffReader<'a> {
256 None,
257 Bool(BoolCoder<'a>),
258 Huff(BitReader<'a>),
259}
260
261#[derive(Clone,Copy,Default)]
262struct MBInfo {
263 mb_type: VPMBType,
264 mv: MV,
265}
266
267pub struct FrameState {
268 pub mb_x: usize,
269 pub mb_y: usize,
270 pub plane: usize,
271 pub coeff_cat: [[u8; 64]; 4],
272 pub last_idx: [usize; 4],
273 pub top_ctx: u8,
274 pub ctx_idx: usize,
275 pub dc_quant: i16,
276 pub ac_quant: i16,
277 pub dc_zero_run: [usize; 2],
278 pub ac_zero_run: [usize; 2],
279}
280
281impl FrameState {
282 fn new() -> Self {
283 Self {
284 mb_x: 0,
285 mb_y: 0,
286 plane: 0,
287 coeff_cat: [[0; 64]; 4],
288 last_idx: [0; 4],
289 top_ctx: 0,
290 ctx_idx: 0,
291 dc_quant: 0,
292 ac_quant: 0,
293 dc_zero_run: [0; 2],
294 ac_zero_run: [0; 2],
295 }
296 }
297}
298
13078a1f
KS
299#[derive(Default)]
300pub struct VP56DCPred {
301 dc_y: Vec<i16>,
302 dc_u: Vec<i16>,
303 dc_v: Vec<i16>,
304 ldc_y: [i16; 2],
305 ldc_u: i16,
306 ldc_v: i16,
307 ref_y: Vec<u8>,
308 ref_c: Vec<u8>,
309 ref_left: u8,
310 y_idx: usize,
311 c_idx: usize,
312}
313
314const INVALID_REF: u8 = 42;
315
316impl VP56DCPred {
317 fn new() -> Self { Self::default() }
318 fn resize(&mut self, mb_w: usize) {
319 self.dc_y.resize(mb_w * 2 + 2, 0);
320 self.dc_u.resize(mb_w + 2, 0);
321 self.dc_v.resize(mb_w + 2, 0);
322 self.ref_y.resize(mb_w * 2 + 2, INVALID_REF);
323 self.ref_c.resize(mb_w + 2, INVALID_REF);
324 self.ref_c[0] = 0;
325 }
326 fn reset(&mut self) {
327 self.update_row();
328 for el in self.ref_y.iter_mut().skip(1) { *el = INVALID_REF; }
329 for el in self.ref_c.iter_mut().skip(1) { *el = INVALID_REF; }
330 }
331 fn update_row(&mut self) {
332 self.y_idx = 1;
333 self.c_idx = 1;
334 self.ldc_y = [0; 2];
335 self.ldc_u = 0;
336 self.ldc_v = 0;
337 self.ref_left = INVALID_REF;
338 }
339 fn next_mb(&mut self) {
340 self.y_idx += 2;
341 self.c_idx += 1;
342 }
343}
344
3584b223
KS
345pub struct VP56Decoder {
346 version: u8,
347 has_alpha: bool,
348 flip: bool,
349 shuf: VPShuffler,
350 width: usize,
351 height: usize,
352 mb_w: usize,
353 mb_h: usize,
354 models: VP56Models,
355 coeffs: [[i16; 64]; 6],
356 last_mbt: VPMBType,
357
358 loop_thr: i16,
359 ilace_prob: u8,
360 ilace_mb: bool,
361
362 mb_info: Vec<MBInfo>,
363 fstate: FrameState,
13078a1f 364 dc_pred: VP56DCPred,
3584b223
KS
365 last_dc: [[i16; 4]; 3],
366 top_ctx: [Vec<u8>; 4],
367
368 mc_buf: NAVideoBufferRef<u8>,
369}
370
371fn rescale_mb_mode_prob(prob: u32, total: u32) -> u8 {
372 (255 * prob / (1 + total)) as u8
373}
374
375fn map_mb_type(mbtype: VPMBType) -> usize {
376 match mbtype {
377 VPMBType::InterNoMV => 0,
378 VPMBType::Intra => 1,
379 VPMBType::InterMV => 2,
380 VPMBType::InterNearest => 3,
381 VPMBType::InterNear => 4,
382 VPMBType::GoldenNoMV => 5,
383 VPMBType::GoldenMV => 6,
384 VPMBType::InterFourMV => 7,
385 VPMBType::GoldenNearest => 8,
386 VPMBType::GoldenNear => 9,
387 }
388}
389
3584b223 390pub fn expand_token_bc(bc: &mut BoolCoder, val_probs: &[u8; 11], token: u8, version: u8) -> i16 {
3584b223
KS
391 let mut sign = false;
392 let level;
393 if token < TOKEN_LARGE {
394 if token != 0 {
395 sign = bc.read_bool();
396 }
47933c6d 397 level = i16::from(token);
3584b223
KS
398 } else {
399 let cat: usize = vp_tree!(bc, val_probs[6],
400 vp_tree!(bc, val_probs[7], 0, 1),
401 vp_tree!(bc, val_probs[8],
402 vp_tree!(bc, val_probs[9], 2, 3),
403 vp_tree!(bc, val_probs[10], 4, 5)));
404 if version == 5 {
405 sign = bc.read_bool();
406 }
407 let mut add = 0i16;
3f67638d 408 let add_probs = &VP56_COEF_ADD_PROBS[cat];
3584b223
KS
409 for prob in add_probs.iter() {
410 if *prob == 128 { break; }
411 add = (add << 1) | (bc.read_prob(*prob) as i16);
412 }
413 if version != 5 {
414 sign = bc.read_bool();
415 }
416 level = VP56_COEF_BASE[cat] + add;
417 }
418 if !sign {
419 level
420 } else {
421 -level
422 }
423}
424
425impl VP56Decoder {
426 pub fn new(version: u8, has_alpha: bool, flip: bool) -> Self {
93bbc2b0 427 let vt = alloc_video_buffer(NAVideoInfo::new(24, 24, false, VP_YUVA420_FORMAT), 4).unwrap();
3584b223
KS
428 let mc_buf = vt.get_vbuf().unwrap();
429 Self {
430 version, has_alpha, flip,
431 shuf: VPShuffler::new(),
432 width: 0,
433 height: 0,
434 mb_w: 0,
435 mb_h: 0,
436 models: VP56Models::new(),
437 coeffs: [[0; 64]; 6],
438 last_mbt: VPMBType::InterNoMV,
439
440 loop_thr: 0,
441 ilace_prob: 0,
442 ilace_mb: false,
443
444 mb_info: Vec::new(),
445 fstate: FrameState::new(),
13078a1f 446 dc_pred: VP56DCPred::new(),
3584b223
KS
447 last_dc: [[0; 4]; 3],
448 top_ctx: [Vec::new(), Vec::new(), Vec::new(), Vec::new()],
449
450 mc_buf,
451 }
452 }
453 fn set_dimensions(&mut self, width: usize, height: usize) {
454 self.width = width;
455 self.height = height;
456 self.mb_w = (self.width + 15) >> 4;
457 self.mb_h = (self.height + 15) >> 4;
458 self.mb_info.resize(self.mb_w * self.mb_h, MBInfo::default());
3584b223
KS
459 self.top_ctx = [vec![0; self.mb_w * 2], vec![0; self.mb_w], vec![0; self.mb_w], vec![0; self.mb_w * 2]];
460 }
461 pub fn init(&mut self, supp: &mut NADecoderSupport, vinfo: NAVideoInfo) -> DecoderResult<()> {
462 supp.pool_u8.set_dec_bufs(3);
463 supp.pool_u8.prealloc_video(NAVideoInfo::new(vinfo.get_width(), vinfo.get_height(), false, vinfo.get_format()), 4)?;
464 self.set_dimensions(vinfo.get_width(), vinfo.get_height());
13078a1f 465 self.dc_pred.resize(self.mb_w);
3584b223
KS
466 Ok(())
467 }
f9be4e75
KS
468 pub fn flush(&mut self) {
469 self.shuf.clear();
470 }
3584b223
KS
471 pub fn decode_frame(&mut self, supp: &mut NADecoderSupport, src: &[u8], br: &mut dyn VP56Parser) -> DecoderResult<(NABufferType, FrameType)> {
472 let aoffset;
473 let mut bc;
474 if self.has_alpha {
475 validate!(src.len() >= 7);
476 aoffset = ((src[0] as usize) << 16) | ((src[1] as usize) << 8) | (src[2] as usize);
477 validate!((aoffset > 0) && (aoffset < src.len() - 3));
478 bc = BoolCoder::new(&src[3..])?;
479 } else {
480 validate!(src.len() >= 4);
481 aoffset = src.len();
482 bc = BoolCoder::new(src)?;
483 }
484 let hdr = br.parse_header(&mut bc)?;
485 validate!((hdr.offset as usize) < aoffset); //XXX: take alpha 3 byte offset into account?
486
487 if hdr.mb_w != 0 {
488 self.set_dimensions((hdr.mb_w as usize) * 16, (hdr.mb_h as usize) * 16);
489 }
93bbc2b0
KS
490 let fmt = if !self.has_alpha {
491 YUV420_FORMAT
492 } else {
493 VP_YUVA420_FORMAT
494 };
495 let vinfo = NAVideoInfo::new(self.width, self.height, self.flip, fmt);
3584b223
KS
496 let ret = supp.pool_u8.get_free();
497 if ret.is_none() {
498 return Err(DecoderError::AllocError);
499 }
500 let mut buf = ret.unwrap();
501 if buf.get_info() != vinfo {
502 self.shuf.clear();
503 supp.pool_u8.reset();
504 supp.pool_u8.prealloc_video(vinfo, 4)?;
505 let ret = supp.pool_u8.get_free();
506 if ret.is_none() {
507 return Err(DecoderError::AllocError);
508 }
509 buf = ret.unwrap();
510 }
511 let mut dframe = NASimpleVideoFrame::from_video_buf(&mut buf).unwrap();
512
513 if hdr.is_intra {
514 self.shuf.clear();
6e24ec0b
KS
515 } else {
516 if !self.shuf.has_refs() {
517 return Err(DecoderError::MissingReference);
518 }
3584b223
KS
519 }
520
521 let mut cr;
522 if hdr.multistream {
523 let off = (if self.has_alpha { 3 } else { 0 }) + (hdr.offset as usize);
524 if !hdr.use_huffman {
525 let bc2 = BoolCoder::new(&src[off..])?;
526 cr = CoeffReader::Bool(bc2);
527 } else {
fa90ccfb 528 let br = BitReader::new(&src[off..aoffset], BitReaderMode::BE);
3584b223
KS
529 cr = CoeffReader::Huff(br);
530 }
531 } else {
532 cr = CoeffReader::None;
533 }
534
535 if hdr.is_intra {
536 br.reset_models(&mut self.models);
537 self.reset_mbtype_models();
538 } else {
539 self.decode_mode_prob_models(&mut bc)?;
540 br.decode_mv_models(&mut bc, &mut self.models.mv_models)?;
541 }
542 br.decode_coeff_models(&mut bc, &mut self.models, hdr.is_intra)?;
543 if hdr.use_huffman {
544 for i in 0..2 {
545 self.models.vp6huff.dc_token_tree[i].build_codes(&self.models.coeff_models[i].dc_value_probs);
546 }
547 for i in 0..2 {
548 for mode in 0..3 {
549 for band in 0..6 {
550 self.models.vp6huff.ac_token_tree[i][mode][band].build_codes(&self.models.coeff_models[i].ac_val_probs[mode][band]);
551 }
552 }
553 }
554 for i in 0..2 {
555 self.models.vp6huff.zero_run_tree[i].build_codes_zero_run(&self.models.vp6models.zero_run_probs[i]);
556 }
557 }
558
559 if hdr.interlaced {
560 self.ilace_prob = bc.read_bits(8) as u8;
561 }
562
563 self.fstate = FrameState::new();
564 self.fstate.dc_quant = VP56_DC_QUANTS[hdr.quant as usize] * 4;
565 self.fstate.ac_quant = VP56_AC_QUANTS[hdr.quant as usize] * 4;
47933c6d 566 self.loop_thr = i16::from(VP56_FILTER_LIMITS[hdr.quant as usize]);
3584b223
KS
567
568 self.last_mbt = VPMBType::InterNoMV;
3584b223
KS
569 for vec in self.top_ctx.iter_mut() {
570 for el in vec.iter_mut() {
571 *el = 0;
572 }
573 }
574 self.last_dc = [[0; 4]; 3];
575 self.last_dc[0][1] = 0x80;
576 self.last_dc[0][2] = 0x80;
13078a1f 577 self.dc_pred.reset();
3584b223
KS
578
579 self.ilace_mb = false;
580 for mb_y in 0..self.mb_h {
581 self.fstate.mb_y = mb_y;
582 self.fstate.coeff_cat = [[0; 64]; 4];
583 self.fstate.last_idx = [24; 4];
584 for mb_x in 0..self.mb_w {
585 self.fstate.mb_x = mb_x;
586 self.decode_mb(&mut dframe, &mut bc, &mut cr, br, &hdr, false)?;
13078a1f 587 self.dc_pred.next_mb();
3584b223 588 }
13078a1f 589 self.dc_pred.update_row();
3584b223
KS
590 }
591
592 if self.has_alpha {
593 let asrc = &src[aoffset + 3..];
594 let mut bc = BoolCoder::new(asrc)?;
595 let ahdr = br.parse_header(&mut bc)?;
596 validate!(ahdr.mb_w == hdr.mb_w && ahdr.mb_h == hdr.mb_h);
597 }
598
599 if hdr.is_golden {
600 self.shuf.add_golden_frame(buf.clone());
601 }
602 self.shuf.add_frame(buf.clone());
603
604 Ok((NABufferType::Video(buf), if hdr.is_intra { FrameType::I } else { FrameType::P }))
605 }
606 fn reset_mbtype_models(&mut self) {
607 const DEFAULT_XMITTED_PROBS: [[u8; 20]; 3] = [
608 [ 42, 69, 2, 1, 7, 1, 42, 44, 22, 6, 3, 1, 2, 0, 5, 1, 1, 0, 0, 0 ],
609 [ 8, 229, 1, 1, 8, 0, 0, 0, 0, 0, 2, 1, 1, 0, 0, 0, 1, 1, 0, 0 ],
610 [ 35, 122, 1, 1, 6, 1, 34, 46, 0, 0, 2, 1, 1, 0, 1, 0, 1, 1, 0, 0 ]
611 ];
612 self.models.prob_xmitted.copy_from_slice(&DEFAULT_XMITTED_PROBS);
613 }
614 fn decode_mode_prob_models(&mut self, bc: &mut BoolCoder) -> DecoderResult<()> {
615 for ctx in 0..3 {
616 if bc.read_prob(174) {
617 let idx = bc.read_bits(4) as usize;
618 for i in 0..20 {
619 self.models.prob_xmitted[ctx][i ^ 1] = VP56_MODE_VQ[ctx][idx][i];
620 }
621 }
622 if bc.read_prob(254) {
623 for set in 0..20 {
624 if bc.read_prob(205) {
625 let sign = bc.read_bool();
626 let diff = vp_tree!(bc, 171,
627 vp_tree!(bc, 83, 2, 1),
628 vp_tree!(bc, 199,
629 vp_tree!(bc, 140,
630 vp_tree!(bc, 125,
631 vp_tree!(bc, 104, 6, 5),
632 4
633 ),
634 3
635 ),
636 bc.read_bits(7)
637 )) * 4;
638 validate!(diff < 256);
639 let diff = diff as u8;
640 if !sign {
641 validate!(self.models.prob_xmitted[ctx][set ^ 1] <= 255 - diff);
642 self.models.prob_xmitted[ctx][set ^ 1] += diff;
643 } else {
644 validate!(self.models.prob_xmitted[ctx][set ^ 1] >= diff);
645 self.models.prob_xmitted[ctx][set ^ 1] -= diff;
646 }
647 }
648 }
649 }
650 }
651 for ctx in 0..3 {
652 let prob_xmitted = &self.models.prob_xmitted[ctx];
653 for mode in 0..10 {
654 let mdl = &mut self.models.mbtype_models[ctx][mode];
655 let mut cnt = [0u32; 10];
656 let mut total = 0;
657 for i in 0..10 {
658 if i == mode { continue; }
47933c6d 659 cnt[i] = 100 * u32::from(prob_xmitted[i * 2]);
3584b223
KS
660 total += cnt[i];
661 }
47933c6d
KS
662 let sum = u32::from(prob_xmitted[mode * 2]) + u32::from(prob_xmitted[mode * 2 + 1]);
663 mdl.probs[9] = 255 - rescale_mb_mode_prob(u32::from(prob_xmitted[mode * 2 + 1]), sum);
3584b223
KS
664
665 let inter_mv0_weight = (cnt[0] as u32) + (cnt[2] as u32);
666 let inter_mv1_weight = (cnt[3] as u32) + (cnt[4] as u32);
667 let gold_mv0_weight = (cnt[5] as u32) + (cnt[6] as u32);
668 let gold_mv1_weight = (cnt[8] as u32) + (cnt[9] as u32);
669 let mix_weight = (cnt[1] as u32) + (cnt[7] as u32);
670 mdl.probs[0] = 1 + rescale_mb_mode_prob(inter_mv0_weight + inter_mv1_weight, total);
671 mdl.probs[1] = 1 + rescale_mb_mode_prob(inter_mv0_weight, inter_mv0_weight + inter_mv1_weight);
672 mdl.probs[2] = 1 + rescale_mb_mode_prob(mix_weight, mix_weight + gold_mv0_weight + gold_mv1_weight);
673 mdl.probs[3] = 1 + rescale_mb_mode_prob(cnt[0] as u32, inter_mv0_weight);
674 mdl.probs[4] = 1 + rescale_mb_mode_prob(cnt[3] as u32, inter_mv1_weight);
675 mdl.probs[5] = 1 + rescale_mb_mode_prob(cnt[1], mix_weight);
676 mdl.probs[6] = 1 + rescale_mb_mode_prob(gold_mv0_weight, gold_mv0_weight + gold_mv1_weight);
677 mdl.probs[7] = 1 + rescale_mb_mode_prob(cnt[5], gold_mv0_weight);
678 mdl.probs[8] = 1 + rescale_mb_mode_prob(cnt[8], gold_mv1_weight);
679 }
680 }
681 Ok(())
682 }
683 fn find_mv_pred(&self, ref_id: u8) -> (usize, MV, MV, MV) {
684 const CAND_POS: [(i8, i8); 12] = [
685 (-1, 0), ( 0, -1),
686 (-1, -1), (-1, 1),
687 (-2, 0), ( 0, -2),
688 (-1, -2), (-2, -1),
689 (-2, 1), (-1, 2),
690 (-2, -2), (-2, 2)
691 ];
692
693 let mut nearest_mv = ZERO_MV;
694 let mut near_mv = ZERO_MV;
695 let mut pred_mv = ZERO_MV;
696 let mut num_mv: usize = 0;
697
698 for (i, (yoff, xoff)) in CAND_POS.iter().enumerate() {
699 let cx = (self.fstate.mb_x as isize) + (*xoff as isize);
700 let cy = (self.fstate.mb_y as isize) + (*yoff as isize);
701 if (cx < 0) || (cy < 0) {
702 continue;
703 }
704 let cx = cx as usize;
705 let cy = cy as usize;
706 if (cx >= self.mb_w) || (cy >= self.mb_h) {
707 continue;
708 }
709 let mb_pos = cx + cy * self.mb_w;
710 let mv = self.mb_info[mb_pos].mv;
711 if (self.mb_info[mb_pos].mb_type.get_ref_id() != ref_id) || (mv == ZERO_MV) {
712 continue;
713 }
714 if num_mv == 0 {
715 nearest_mv = mv;
716 num_mv += 1;
717 if (self.version > 5) && (i < 2) {
718 pred_mv = mv;
719 }
720 } else if mv != nearest_mv {
721 near_mv = mv;
722 num_mv += 1;
723 break;
724 }
725 }
726
727 (num_mv, nearest_mv, near_mv, pred_mv)
728 }
729 fn decode_mv(&self, bc: &mut BoolCoder, br: &mut dyn VP56Parser) -> MV {
730 let x = br.decode_mv(bc, &self.models.mv_models[0]);
731 let y = br.decode_mv(bc, &self.models.mv_models[1]);
732 MV{ x, y }
733 }
734 fn decode_mb_type(&mut self, bc: &mut BoolCoder, ctx: usize) -> DecoderResult<VPMBType> {
735 let probs = &self.models.mbtype_models[ctx][map_mb_type(self.last_mbt)].probs;
736 if !bc.read_prob(probs[9]) {
737 self.last_mbt = vp_tree!(
738 bc, probs[0],
739 vp_tree!(bc, probs[1],
740 vp_tree!(bc, probs[3], VPMBType::InterNoMV, VPMBType::InterMV),
741 vp_tree!(bc, probs[4], VPMBType::InterNearest, VPMBType::InterNear)
742 ),
743 vp_tree!(bc, probs[2],
744 vp_tree!(bc, probs[5], VPMBType::Intra, VPMBType::InterFourMV),
745 vp_tree!(bc, probs[6],
746 vp_tree!(bc, probs[7], VPMBType::GoldenNoMV, VPMBType::GoldenMV),
dd72b2d4 747 vp_tree!(bc, probs[8], VPMBType::GoldenNearest, VPMBType::GoldenNear)
3584b223
KS
748 )
749 )
750 );
751 }
752 Ok(self.last_mbt)
753 }
47933c6d 754 #[allow(clippy::cyclomatic_complexity)]
3584b223
KS
755 fn decode_mb(&mut self, frm: &mut NASimpleVideoFrame<u8>, bc: &mut BoolCoder, cr: &mut CoeffReader, br: &mut dyn VP56Parser, hdr: &VP56Header, alpha: bool) -> DecoderResult<()> {
756 const FOURMV_SUB_TYPE: [VPMBType; 4] = [ VPMBType::InterNoMV, VPMBType::InterMV, VPMBType::InterNearest, VPMBType::InterNear ];
757
758 let mb_x = self.fstate.mb_x;
759 let mb_y = self.fstate.mb_y;
760 self.coeffs = [[0; 64]; 6];
761 let mb_pos = mb_x + mb_y * self.mb_w;
762 let mut four_mv = [ZERO_MV; 4];
763 let mut four_mbt = [VPMBType::Intra; 4];
764
765 if hdr.interlaced {
766 let iprob = self.ilace_prob;
767 let prob = if mb_x == 0 {
768 iprob
769 } else if !self.ilace_mb {
47933c6d 770 iprob + (((256 - u16::from(iprob)) >> 1) as u8)
3584b223
KS
771 } else {
772 iprob - (iprob >> 1)
773 };
774 self.ilace_mb = bc.read_prob(prob);
775 }
776
777 let (num_mv, nearest_mv, near_mv, pred_mv) = if hdr.is_intra {
778 (0, ZERO_MV, ZERO_MV, ZERO_MV)
779 } else { self.find_mv_pred(VP_REF_INTER) };
780 let mb_type = if hdr.is_intra {
781 VPMBType::Intra
782 } else {
783 self.decode_mb_type(bc, (num_mv + 1) % 3)?
784 };
785 self.mb_info[mb_pos].mb_type = mb_type;
786 if mb_type.get_ref_id() != VP_REF_GOLDEN {
787 match mb_type {
788 VPMBType::Intra |
789 VPMBType::InterNoMV => {
790 self.mb_info[mb_pos].mv = ZERO_MV;
791 },
792 VPMBType::InterMV => {
793 let diff_mv = self.decode_mv(bc, br);
794 self.mb_info[mb_pos].mv = pred_mv + diff_mv;
795 },
796 VPMBType::InterNearest => {
797 self.mb_info[mb_pos].mv = nearest_mv;
798 },
799 VPMBType::InterNear => {
800 self.mb_info[mb_pos].mv = near_mv;
801 },
802 VPMBType::InterFourMV => {
803 for i in 0..4 {
804 four_mbt[i] = FOURMV_SUB_TYPE[bc.read_bits(2) as usize];
805 }
806 for i in 0..4 {
807 match four_mbt[i] {
808 VPMBType::InterNoMV => {},
809 VPMBType::InterMV => {
810 let diff_mv = self.decode_mv(bc, br);
811 four_mv[i] = pred_mv + diff_mv;
812 },
813 VPMBType::InterNearest => {
814 four_mv[i] = nearest_mv;
815 },
816 VPMBType::InterNear => {
817 four_mv[i] = near_mv;
818 },
819 _ => unreachable!(),
820 };
821 }
822 self.mb_info[mb_pos].mv = four_mv[3];
823 },
824 _ => unreachable!(),
825 };
826 } else {
827 let (_num_mv, nearest_mv, near_mv, pred_mv) = self.find_mv_pred(VP_REF_GOLDEN);
828 match mb_type {
829 VPMBType::GoldenNoMV => {
830 self.mb_info[mb_pos].mv = ZERO_MV;
831 },
832 VPMBType::GoldenMV => {
833 let diff_mv = self.decode_mv(bc, br);
834 self.mb_info[mb_pos].mv = pred_mv + diff_mv;
835 },
836 VPMBType::GoldenNearest => {
837 self.mb_info[mb_pos].mv = nearest_mv;
838 },
839 VPMBType::GoldenNear => {
840 self.mb_info[mb_pos].mv = near_mv;
841 },
842 _ => unreachable!(),
843 };
844 }
845 if !mb_type.is_intra() && (mb_type != VPMBType::InterFourMV) {
846 self.do_mc(br, frm, mb_type, self.mb_info[mb_pos].mv, alpha);
847 } else if mb_type == VPMBType::InterFourMV {
848 self.do_fourmv(br, frm, &four_mv, alpha);
849 }
850
851 for blk_no in 0..4 {
852 self.fstate.plane = if !alpha { 0 } else { 3 };
853 self.fstate.ctx_idx = blk_no >> 1;
854 self.fstate.top_ctx = self.top_ctx[self.fstate.plane][mb_x * 2 + (blk_no & 1)];
855 match cr {
856 CoeffReader::None => {
857 br.decode_block(bc, &mut self.coeffs[blk_no], &self.models.coeff_models[0], &self.models.vp6models, &mut self.fstate)?;
858 },
859 CoeffReader::Bool(ref mut bcc) => {
860 br.decode_block(bcc, &mut self.coeffs[blk_no], &self.models.coeff_models[0], &self.models.vp6models, &mut self.fstate)?;
861 },
862 CoeffReader::Huff(ref mut brc) => {
863 br.decode_block_huff(brc, &mut self.coeffs[blk_no], &self.models.vp6models, &self.models.vp6huff, &mut self.fstate)?;
864 },
865 };
866 self.top_ctx[self.fstate.plane][mb_x * 2 + (blk_no & 1)] = self.fstate.top_ctx;
867 self.predict_dc(mb_type, mb_pos, blk_no, alpha);
868
869 let bx = mb_x * 2 + (blk_no & 1);
870 let by = mb_y * 2 + (blk_no >> 1);
871 let has_ac = self.fstate.last_idx[self.fstate.ctx_idx] > 0;
872 if mb_type.is_intra() {
873 if !self.ilace_mb {
874 if has_ac {
875 vp_put_block(&mut self.coeffs[blk_no], bx, by, self.fstate.plane, frm);
876 } else {
877 vp_put_block_dc(&mut self.coeffs[blk_no], bx, by, self.fstate.plane, frm);
878 }
879 } else {
880 vp_put_block_ilace(&mut self.coeffs[blk_no], bx, by, self.fstate.plane, frm);
881 }
882 } else {
883 if !self.ilace_mb {
884 if has_ac {
885 vp_add_block(&mut self.coeffs[blk_no], bx, by, self.fstate.plane, frm);
886 } else {
887 vp_add_block_dc(&mut self.coeffs[blk_no], bx, by, self.fstate.plane, frm);
888 }
889 } else {
890 vp_add_block_ilace(&mut self.coeffs[blk_no], bx, by, self.fstate.plane, frm);
891 }
892 }
893 }
894 if !alpha {
895 for blk_no in 4..6 {
896 self.fstate.plane = blk_no - 3;
897 self.fstate.ctx_idx = blk_no - 2;
898 self.fstate.top_ctx = self.top_ctx[self.fstate.plane][mb_x];
899 match cr {
900 CoeffReader::None => {
901 br.decode_block(bc, &mut self.coeffs[blk_no], &self.models.coeff_models[1], &self.models.vp6models, &mut self.fstate)?;
902 },
903 CoeffReader::Bool(ref mut bcc) => {
904 br.decode_block(bcc, &mut self.coeffs[blk_no], &self.models.coeff_models[1], &self.models.vp6models, &mut self.fstate)?;
905 },
906 CoeffReader::Huff(ref mut brc) => {
907 br.decode_block_huff(brc, &mut self.coeffs[blk_no], &self.models.vp6models, &self.models.vp6huff, &mut self.fstate)?;
908 },
909 };
910 self.top_ctx[self.fstate.plane][mb_x] = self.fstate.top_ctx;
911 self.predict_dc(mb_type, mb_pos, blk_no, alpha);
912
913 let has_ac = self.fstate.last_idx[self.fstate.ctx_idx] > 0;
914 if mb_type.is_intra() {
915 if has_ac {
916 vp_put_block(&mut self.coeffs[blk_no], mb_x, mb_y, self.fstate.plane, frm);
917 } else {
918 vp_put_block_dc(&mut self.coeffs[blk_no], mb_x, mb_y, self.fstate.plane, frm);
919 }
920 } else {
921 if has_ac {
922 vp_add_block(&mut self.coeffs[blk_no], mb_x, mb_y, self.fstate.plane, frm);
923 } else {
924 vp_add_block_dc(&mut self.coeffs[blk_no], mb_x, mb_y, self.fstate.plane, frm);
925 }
926 }
927 }
928 }
929 Ok(())
930 }
931 fn do_mc(&mut self, br: &dyn VP56Parser, frm: &mut NASimpleVideoFrame<u8>, mb_type: VPMBType, mv: MV, alpha: bool) {
932 let x = self.fstate.mb_x * 16;
933 let y = self.fstate.mb_y * 16;
934 let plane = if !alpha { 0 } else { 3 };
935 let src = if mb_type.get_ref_id() == VP_REF_INTER {
936 self.shuf.get_last().unwrap()
937 } else {
938 self.shuf.get_golden().unwrap()
939 };
940
941 br.mc_block(frm, self.mc_buf.clone(), src.clone(), plane, x + 0, y + 0, mv, self.loop_thr);
942 br.mc_block(frm, self.mc_buf.clone(), src.clone(), plane, x + 8, y + 0, mv, self.loop_thr);
943 br.mc_block(frm, self.mc_buf.clone(), src.clone(), plane, x + 0, y + 8, mv, self.loop_thr);
944 br.mc_block(frm, self.mc_buf.clone(), src.clone(), plane, x + 8, y + 8, mv, self.loop_thr);
945 if !alpha {
946 let x = self.fstate.mb_x * 8;
947 let y = self.fstate.mb_y * 8;
948 br.mc_block(frm, self.mc_buf.clone(), src.clone(), 1, x, y, mv, self.loop_thr);
949 br.mc_block(frm, self.mc_buf.clone(), src.clone(), 2, x, y, mv, self.loop_thr);
950 }
951 }
952 fn do_fourmv(&mut self, br: &dyn VP56Parser, frm: &mut NASimpleVideoFrame<u8>, mvs: &[MV; 4], alpha: bool) {
953 let x = self.fstate.mb_x * 16;
954 let y = self.fstate.mb_y * 16;
955 let plane = if !alpha { 0 } else { 3 };
956 let src = self.shuf.get_last().unwrap();
957 for blk_no in 0..4 {
958 br.mc_block(frm, self.mc_buf.clone(), src.clone(),
959 plane, x + (blk_no & 1) * 8, y + (blk_no & 2) * 4,
960 mvs[blk_no], self.loop_thr);
961 }
962 if !alpha {
963 let x = self.fstate.mb_x * 8;
964 let y = self.fstate.mb_y * 8;
965 let sum = mvs[0] + mvs[1] + mvs[2] + mvs[3];
966 let mv = MV { x: sum.x / 4, y: sum.y / 4 };
967 br.mc_block(frm, self.mc_buf.clone(), src.clone(), 1, x, y, mv, self.loop_thr);
968 br.mc_block(frm, self.mc_buf.clone(), src.clone(), 2, x, y, mv, self.loop_thr);
969 }
970 }
13078a1f 971 fn predict_dc(&mut self, mb_type: VPMBType, _mb_pos: usize, blk_no: usize, _alpha: bool) {
3584b223 972 let is_luma = blk_no < 4;
13078a1f
KS
973 let (plane, dcs) = match blk_no {
974 4 => (1, &mut self.dc_pred.dc_u),
975 5 => (2, &mut self.dc_pred.dc_v),
976 _ => (0, &mut self.dc_pred.dc_y),
3584b223 977 };
13078a1f
KS
978 let (dc_ref, dc_idx) = if is_luma {
979 (&mut self.dc_pred.ref_y, self.dc_pred.y_idx + (blk_no & 1))
3584b223 980 } else {
13078a1f 981 (&mut self.dc_pred.ref_c, self.dc_pred.c_idx)
3584b223
KS
982 };
983 let ref_id = mb_type.get_ref_id();
3584b223
KS
984 let mut dc_pred = 0;
985 let mut count = 0;
13078a1f
KS
986 let has_left_blk = is_luma && ((blk_no & 1) == 1);
987 if has_left_blk || self.dc_pred.ref_left == ref_id {
988 dc_pred += match blk_no {
989 0 | 1 => self.dc_pred.ldc_y[0],
990 2 | 3 => self.dc_pred.ldc_y[1],
991 4 => self.dc_pred.ldc_u,
992 _ => self.dc_pred.ldc_v,
993 };
3584b223
KS
994 count += 1;
995 }
13078a1f
KS
996 if dc_ref[dc_idx] == ref_id {
997 dc_pred += dcs[dc_idx];
3584b223
KS
998 count += 1;
999 }
1000 if self.version == 5 {
13078a1f
KS
1001 if (count < 2) && (dc_ref[dc_idx - 1] == ref_id) {
1002 dc_pred += dcs[dc_idx - 1];
3584b223
KS
1003 count += 1;
1004 }
13078a1f
KS
1005 if (count < 2) && (dc_ref[dc_idx + 1] == ref_id) {
1006 dc_pred += dcs[dc_idx + 1];
3584b223
KS
1007 count += 1;
1008 }
1009 }
1010 if count == 0 {
1011 dc_pred = self.last_dc[ref_id as usize][plane];
1012 } else if count == 2 {
1013 dc_pred /= 2;
1014 }
1015 self.coeffs[blk_no][0] += dc_pred;
13078a1f
KS
1016
1017 let dc = self.coeffs[blk_no][0];
1018 if blk_no != 4 { // update top block reference only for the second chroma component
1019 dc_ref[dc_idx] = ref_id;
1020 }
1021 match blk_no {
1022 0 | 1 => {
1023 self.dc_pred.ldc_y[0] = dc;
1024 },
1025 2 | 3 => {
1026 self.dc_pred.ldc_y[1] = dc;
1027 },
1028 4 => {
1029 self.dc_pred.ldc_u = dc;
1030 },
1031 _ => {
1032 self.dc_pred.ldc_v = dc;
1033 self.dc_pred.ref_left = ref_id;
1034 },
1035 };
1036 dcs[dc_idx] = dc;
1037
1038 self.last_dc[ref_id as usize][plane] = dc;
3584b223
KS
1039 self.coeffs[blk_no][0] = self.coeffs[blk_no][0].wrapping_mul(self.fstate.dc_quant);
1040 }
1041}
1042
1043const VP56_DC_QUANTS: [i16; 64] = [
1044 47, 47, 47, 47, 45, 43, 43, 43,
1045 43, 43, 42, 41, 41, 40, 40, 40,
1046 40, 35, 35, 35, 35, 33, 33, 33,
1047 33, 32, 32, 32, 27, 27, 26, 26,
1048 25, 25, 24, 24, 23, 23, 19, 19,
1049 19, 19, 18, 18, 17, 16, 16, 16,
1050 16, 16, 15, 11, 11, 11, 10, 10,
1051 9, 8, 7, 5, 3, 3, 2, 2
1052];
1053const VP56_AC_QUANTS: [i16; 64] = [
1054 94, 92, 90, 88, 86, 82, 78, 74,
1055 70, 66, 62, 58, 54, 53, 52, 51,
1056 50, 49, 48, 47, 46, 45, 44, 43,
1057 42, 40, 39, 37, 36, 35, 34, 33,
1058 32, 31, 30, 29, 28, 27, 26, 25,
1059 24, 23, 22, 21, 20, 19, 18, 17,
1060 16, 15, 14, 13, 12, 11, 10, 9,
1061 8, 7, 6, 5, 4, 3, 2, 1
1062];
1063
1064const VP56_FILTER_LIMITS: [u8; 64] = [
1065 14, 14, 13, 13, 12, 12, 10, 10,
1066 10, 10, 8, 8, 8, 8, 8, 8,
1067 8, 8, 8, 8, 8, 8, 8, 8,
1068 8, 8, 8, 8, 8, 8, 8, 8,
1069 8, 8, 8, 8, 7, 7, 7, 7,
1070 7, 7, 6, 6, 6, 6, 6, 6,
1071 5, 5, 5, 5, 4, 4, 4, 4,
1072 4, 4, 4, 3, 3, 3, 3, 2
1073];
1074
1075const VP56_MODE_VQ: [[[u8; 20]; 16]; 3] = [
1076 [
1077 [ 9, 15, 32, 25, 7, 19, 9, 21, 1, 12, 14, 12, 3, 18, 14, 23, 3, 10, 0, 4 ],
1078 [ 48, 39, 1, 2, 11, 27, 29, 44, 7, 27, 1, 4, 0, 3, 1, 6, 1, 2, 0, 0 ],
1079 [ 21, 32, 1, 2, 4, 10, 32, 43, 6, 23, 2, 3, 1, 19, 1, 6, 12, 21, 0, 7 ],
1080 [ 69, 83, 0, 0, 0, 2, 10, 29, 3, 12, 0, 1, 0, 3, 0, 3, 2, 2, 0, 0 ],
1081 [ 11, 20, 1, 4, 18, 36, 43, 48, 13, 35, 0, 2, 0, 5, 3, 12, 1, 2, 0, 0 ],
1082 [ 70, 44, 0, 1, 2, 10, 37, 46, 8, 26, 0, 2, 0, 2, 0, 2, 0, 1, 0, 0 ],
1083 [ 8, 15, 0, 1, 8, 21, 74, 53, 22, 42, 0, 1, 0, 2, 0, 3, 1, 2, 0, 0 ],
1084 [ 141, 42, 0, 0, 1, 4, 11, 24, 1, 11, 0, 1, 0, 1, 0, 2, 0, 0, 0, 0 ],
1085 [ 8, 19, 4, 10, 24, 45, 21, 37, 9, 29, 0, 3, 1, 7, 11, 25, 0, 2, 0, 1 ],
1086 [ 46, 42, 0, 1, 2, 10, 54, 51, 10, 30, 0, 2, 0, 2, 0, 1, 0, 1, 0, 0 ],
1087 [ 28, 32, 0, 0, 3, 10, 75, 51, 14, 33, 0, 1, 0, 2, 0, 1, 1, 2, 0, 0 ],
1088 [ 100, 46, 0, 1, 3, 9, 21, 37, 5, 20, 0, 1, 0, 2, 1, 2, 0, 1, 0, 0 ],
1089 [ 27, 29, 0, 1, 9, 25, 53, 51, 12, 34, 0, 1, 0, 3, 1, 5, 0, 2, 0, 0 ],
1090 [ 80, 38, 0, 0, 1, 4, 69, 33, 5, 16, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0 ],
1091 [ 16, 20, 0, 0, 2, 8, 104, 49, 15, 33, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0 ],
1092 [ 194, 16, 0, 0, 1, 1, 1, 9, 1, 3, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0 ],
1093 ], [
1094 [ 41, 22, 1, 0, 1, 31, 0, 0, 0, 0, 0, 1, 1, 7, 0, 1, 98, 25, 4, 10 ],
1095 [ 123, 37, 6, 4, 1, 27, 0, 0, 0, 0, 5, 8, 1, 7, 0, 1, 12, 10, 0, 2 ],
1096 [ 26, 14, 14, 12, 0, 24, 0, 0, 0, 0, 55, 17, 1, 9, 0, 36, 5, 7, 1, 3 ],
1097 [ 209, 5, 0, 0, 0, 27, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0 ],
1098 [ 2, 5, 4, 5, 0, 121, 0, 0, 0, 0, 0, 3, 2, 4, 1, 4, 2, 2, 0, 1 ],
1099 [ 175, 5, 0, 1, 0, 48, 0, 0, 0, 0, 0, 2, 0, 1, 0, 2, 0, 1, 0, 0 ],
1100 [ 83, 5, 2, 3, 0, 102, 0, 0, 0, 0, 1, 3, 0, 2, 0, 1, 0, 0, 0, 0 ],
1101 [ 233, 6, 0, 0, 0, 8, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0 ],
1102 [ 34, 16, 112, 21, 1, 28, 0, 0, 0, 0, 6, 8, 1, 7, 0, 3, 2, 5, 0, 2 ],
1103 [ 159, 35, 2, 2, 0, 25, 0, 0, 0, 0, 3, 6, 0, 5, 0, 1, 4, 4, 0, 1 ],
1104 [ 75, 39, 5, 7, 2, 48, 0, 0, 0, 0, 3, 11, 2, 16, 1, 4, 7, 10, 0, 2 ],
1105 [ 212, 21, 0, 1, 0, 9, 0, 0, 0, 0, 1, 2, 0, 2, 0, 0, 2, 2, 0, 0 ],
1106 [ 4, 2, 0, 0, 0, 172, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 2, 0, 0, 0 ],
1107 [ 187, 22, 1, 1, 0, 17, 0, 0, 0, 0, 3, 6, 0, 4, 0, 1, 4, 4, 0, 1 ],
1108 [ 133, 6, 1, 2, 1, 70, 0, 0, 0, 0, 0, 2, 0, 4, 0, 3, 1, 1, 0, 0 ],
1109 [ 251, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
1110 ], [
1111 [ 2, 3, 2, 3, 0, 2, 0, 2, 0, 0, 11, 4, 1, 4, 0, 2, 3, 2, 0, 4 ],
1112 [ 49, 46, 3, 4, 7, 31, 42, 41, 0, 0, 2, 6, 1, 7, 1, 4, 2, 4, 0, 1 ],
1113 [ 26, 25, 1, 1, 2, 10, 67, 39, 0, 0, 1, 1, 0, 14, 0, 2, 31, 26, 1, 6 ],
1114 [ 103, 46, 1, 2, 2, 10, 33, 42, 0, 0, 1, 4, 0, 3, 0, 1, 1, 3, 0, 0 ],
1115 [ 14, 31, 9, 13, 14, 54, 22, 29, 0, 0, 2, 6, 4, 18, 6, 13, 1, 5, 0, 1 ],
1116 [ 85, 39, 0, 0, 1, 9, 69, 40, 0, 0, 0, 1, 0, 3, 0, 1, 2, 3, 0, 0 ],
1117 [ 31, 28, 0, 0, 3, 14, 130, 34, 0, 0, 0, 1, 0, 3, 0, 1, 3, 3, 0, 1 ],
1118 [ 171, 25, 0, 0, 1, 5, 25, 21, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0 ],
1119 [ 17, 21, 68, 29, 6, 15, 13, 22, 0, 0, 6, 12, 3, 14, 4, 10, 1, 7, 0, 3 ],
1120 [ 51, 39, 0, 1, 2, 12, 91, 44, 0, 0, 0, 2, 0, 3, 0, 1, 2, 3, 0, 1 ],
1121 [ 81, 25, 0, 0, 2, 9, 106, 26, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0 ],
1122 [ 140, 37, 0, 1, 1, 8, 24, 33, 0, 0, 1, 2, 0, 2, 0, 1, 1, 2, 0, 0 ],
1123 [ 14, 23, 1, 3, 11, 53, 90, 31, 0, 0, 0, 3, 1, 5, 2, 6, 1, 2, 0, 0 ],
1124 [ 123, 29, 0, 0, 1, 7, 57, 30, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0 ],
1125 [ 13, 14, 0, 0, 4, 20, 175, 20, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0 ],
1126 [ 202, 23, 0, 0, 1, 3, 2, 9, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0 ],
1127 ]
1128];
1129