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