M2.4: H.264 CABAC entropy decoding

- arithmetic decoding engine (DecodeDecision / Bypass / Terminate, 9-bit
  register semantics incl. I_PCM re-initialisation), combined state
  transition table, round-trip tested against a reference encoder model
- context initialisation for cabac_init_idc 0..2 and I slices, all 1024
  (m, n) pairs extracted from Tables 9-12..9-33 of the spec
- binarisations + ctxIdxInc derivations: mb_skip_flag, mb_type (I/P/B incl.
  intra suffixes and I_PCM), sub_mb_type, ref_idx, mvd (UEG3), prev/rem intra
  modes, intra_chroma_pred_mode, coded_block_pattern, mb_qp_delta,
  transform_size_8x8_flag, coded_block_flag (all block categories incl.
  inferred 8x8 flags), significant/last (frame, 4x4 and 8x8 tables),
  coeff_abs_level_minus1 (UEG0), end_of_slice_flag

The full fixture matrix (32 libx264 configurations: Baseline/Main/High,
CABAC+B-pyramid, weightp/weightb, direct temporal/spatial, ref=4, deblock
variants, cqm=jvt, 4 slices, open GOP, constrained intra, 8x8dct=0, QP 1/50,
720p/1080p/1918x1078 crop) decodes bit-exact against ffmpeg.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Brandon Thomas 2026-09-30 06:19:54 -04:00
parent c6a7075de7
commit aefe1ae08f
7 changed files with 1552 additions and 2 deletions

320
crates/h264/src/cabac.rs Normal file
View File

@ -0,0 +1,320 @@
//! CABAC arithmetic decoding engine (9.3.1.2, 9.3.3.2) and context initialisation (9.3.1.1).
use crate::cabac_tables::CABAC_INIT_MN;
use crate::error::{Result, ensure};
/// Table 9-44 rangeTabLPS[pStateIdx][qCodIRangeIdx].
#[rustfmt::skip]
static RANGE_TAB_LPS: [[u8; 4]; 64] = [
[128, 176, 208, 240], [128, 167, 197, 227], [128, 158, 187, 216], [123, 150, 178, 205],
[116, 142, 169, 195], [111, 135, 160, 185], [105, 128, 152, 175], [100, 122, 144, 166],
[95, 116, 137, 158], [90, 110, 130, 150], [85, 104, 123, 142], [81, 99, 117, 135],
[77, 94, 111, 128], [73, 89, 105, 122], [69, 85, 100, 116], [66, 80, 95, 110],
[62, 76, 90, 104], [59, 72, 86, 99], [56, 69, 81, 94], [53, 65, 77, 89],
[51, 62, 73, 85], [48, 59, 69, 80], [46, 56, 66, 76], [43, 53, 63, 72],
[41, 50, 59, 69], [39, 48, 56, 65], [37, 45, 54, 62], [35, 43, 51, 59],
[33, 41, 48, 56], [32, 39, 46, 53], [30, 37, 43, 50], [29, 35, 41, 48],
[27, 33, 39, 45], [26, 31, 37, 43], [24, 30, 35, 41], [23, 28, 33, 39],
[22, 27, 32, 37], [21, 26, 30, 35], [20, 24, 29, 33], [19, 23, 27, 31],
[18, 22, 26, 30], [17, 21, 25, 28], [16, 20, 23, 27], [15, 19, 22, 25],
[14, 18, 21, 24], [14, 17, 20, 23], [13, 16, 19, 22], [12, 15, 18, 21],
[12, 14, 17, 20], [11, 14, 16, 19], [11, 13, 15, 18], [10, 12, 15, 17],
[10, 12, 14, 16], [9, 11, 13, 15], [9, 11, 12, 14], [8, 10, 12, 14],
[8, 9, 11, 13], [7, 9, 11, 12], [7, 9, 10, 12], [7, 8, 10, 11],
[6, 8, 9, 11], [6, 7, 9, 10], [6, 7, 8, 9], [2, 2, 2, 2],
];
/// Table 9-45 transIdxLPS.
#[rustfmt::skip]
static TRANS_IDX_LPS: [u8; 64] = [
0, 0, 1, 2, 2, 4, 4, 5, 6, 7, 8, 9, 9, 11, 11, 12,
13, 13, 15, 15, 16, 16, 18, 18, 19, 19, 21, 21, 22, 22, 23, 24,
24, 25, 26, 26, 27, 27, 28, 29, 29, 30, 30, 30, 31, 32, 32, 33,
33, 33, 34, 34, 35, 35, 35, 36, 36, 36, 37, 37, 37, 38, 38, 63,
];
/// Table 9-45 transIdxMPS.
#[rustfmt::skip]
static TRANS_IDX_MPS: [u8; 64] = [
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 62, 63,
];
/// Combined state transition: index = (pStateIdx << 1 | valMPS) * 2 + bin_is_lps.
/// Each context is stored as `pStateIdx << 1 | valMPS`.
static NEXT_STATE: [[u8; 2]; 128] = {
let mut t = [[0u8; 2]; 128];
let mut s = 0;
while s < 128 {
let p = s >> 1;
let mps = s & 1;
// MPS path
t[s][0] = (TRANS_IDX_MPS[p] << 1) | mps as u8;
// LPS path
let new_mps = if p == 0 { 1 - mps } else { mps };
t[s][1] = (TRANS_IDX_LPS[p] << 1) | new_mps as u8;
s += 1;
}
t
};
/// Number of context variables used (0..=1023).
pub const NUM_CTX: usize = 1024;
pub struct Cabac<'a> {
data: &'a [u8],
/// Bit position of the next unread bit.
pos: usize,
range: u32,
offset: u32,
pub ctx: [u8; NUM_CTX],
}
impl<'a> Cabac<'a> {
/// Create an engine over `data` (slice RBSP) starting at bit `pos` (must be byte aligned),
/// with contexts initialised for `slice_qp` and `init` (0..=2 cabac_init_idc, 3 = I slice).
pub fn new(data: &'a [u8], pos: usize, slice_qp: i32, init: usize) -> Result<Self> {
let mut c = Cabac { data, pos, range: 0, offset: 0, ctx: [0; NUM_CTX] };
c.init_contexts(slice_qp, init);
c.init_engine()?;
Ok(c)
}
pub fn init_contexts(&mut self, slice_qp: i32, init: usize) {
let qp = slice_qp.clamp(0, 51);
let tab = &CABAC_INIT_MN[init];
for (c, &(m, n)) in self.ctx.iter_mut().zip(tab.iter()) {
let pre = (((m as i32) * qp) >> 4) + n as i32;
let pre = pre.clamp(1, 126);
*c = if pre <= 63 { ((63 - pre) << 1) as u8 } else { (((pre - 64) << 1) | 1) as u8 };
}
// ctxIdx 276 (end_of_slice / I_PCM) is handled by decode_terminate.
}
/// 9.3.1.2: codIRange = 510, codIOffset = read_bits(9).
pub fn init_engine(&mut self) -> Result<()> {
self.range = 510;
self.offset = self.read_bits(9);
ensure!(self.offset < 510, "invalid CABAC offset at init");
Ok(())
}
#[inline(always)]
fn read_bits(&mut self, n: u32) -> u32 {
// big-endian 64-bit window starting at the byte containing `pos`
let byte = self.pos >> 3;
let mut w = [0u8; 8];
if let Some(src) = self.data.get(byte..byte + 8) {
w.copy_from_slice(src);
} else if byte < self.data.len() {
let n = self.data.len() - byte;
w[..n].copy_from_slice(&self.data[byte..]);
}
let v = u64::from_be_bytes(w) << (self.pos & 7);
self.pos += n as usize;
(v >> (64 - n)) as u32
}
/// Bit position (for I_PCM alignment after decode_terminate returned 1).
pub fn bit_pos(&self) -> usize {
self.pos
}
pub fn set_bit_pos(&mut self, pos: usize) {
self.pos = pos;
}
pub fn data(&self) -> &'a [u8] {
self.data
}
/// True when the reader has run past the end of the data (corrupt stream).
pub fn overrun(&self) -> bool {
self.pos > self.data.len() * 8 + 64
}
#[inline(always)]
pub fn decode_decision(&mut self, ctx_idx: usize) -> u32 {
let s = self.ctx[ctx_idx] as usize;
let p = s >> 1;
let mps = (s & 1) as u32;
let q = ((self.range >> 6) & 3) as usize;
let lps = RANGE_TAB_LPS[p][q] as u32;
self.range -= lps;
let bin;
if self.offset >= self.range {
bin = 1 - mps;
self.offset -= self.range;
self.range = lps;
self.ctx[ctx_idx] = NEXT_STATE[s][1];
} else {
bin = mps;
self.ctx[ctx_idx] = NEXT_STATE[s][0];
}
if self.range < 256 {
let shift = self.range.leading_zeros() - 23;
self.range <<= shift;
self.offset = (self.offset << shift) | self.read_bits(shift);
}
bin
}
#[inline(always)]
pub fn decode_bypass(&mut self) -> u32 {
self.offset = (self.offset << 1) | self.read_bits(1);
if self.offset >= self.range {
self.offset -= self.range;
1
} else {
0
}
}
pub fn decode_terminate(&mut self) -> u32 {
self.range -= 2;
if self.offset >= self.range {
1
} else {
if self.range < 256 {
let shift = self.range.leading_zeros() - 23;
self.range <<= shift;
self.offset = (self.offset << shift) | self.read_bits(shift);
}
0
}
}
}
#[cfg(test)]
mod tests {
use super::*;
/// Minimal CABAC encoder (9.3.4, informative) used to round-trip test the decoder.
struct Enc {
low: u32,
range: u32,
outstanding: u32,
first: bool,
bits: Vec<bool>,
ctx: Vec<u8>,
}
impl Enc {
fn new(ctx: &[u8]) -> Self {
Enc { low: 0, range: 510, outstanding: 0, first: true, bits: vec![], ctx: ctx.to_vec() }
}
fn put(&mut self, b: bool) {
if self.first {
self.first = false;
} else {
self.bits.push(b);
}
while self.outstanding > 0 {
self.bits.push(!b);
self.outstanding -= 1;
}
}
fn renorm(&mut self) {
while self.range < 256 {
if self.low < 256 {
self.put(false);
} else if self.low >= 512 {
self.low -= 512;
self.put(true);
} else {
self.low -= 256;
self.outstanding += 1;
}
self.range <<= 1;
self.low <<= 1;
}
}
fn encode(&mut self, ctx_idx: usize, bin: u32) {
let s = self.ctx[ctx_idx] as usize;
let p = s >> 1;
let mps = (s & 1) as u32;
let q = ((self.range >> 6) & 3) as usize;
let lps = RANGE_TAB_LPS[p][q] as u32;
self.range -= lps;
if bin != mps {
self.low += self.range;
self.range = lps;
self.ctx[ctx_idx] = NEXT_STATE[s][1];
} else {
self.ctx[ctx_idx] = NEXT_STATE[s][0];
}
self.renorm();
}
fn bypass(&mut self, bin: u32) {
self.low <<= 1;
if bin != 0 {
self.low += self.range;
}
if self.low >= 1024 {
self.put(true);
self.low -= 1024;
} else if self.low < 512 {
self.put(false);
} else {
self.low -= 512;
self.outstanding += 1;
}
}
fn terminate_flush(&mut self) -> Vec<u8> {
// encode terminate bin = 1 then flush (9.3.4.5)
self.range -= 2;
self.low += self.range;
self.range = 2;
self.renorm();
self.put((self.low >> 9) & 1 != 0);
self.bits.push((self.low >> 8) & 1 != 0);
self.bits.push(true); // rbsp_stop_one_bit
while !self.bits.len().is_multiple_of(8) {
self.bits.push(false);
}
self.bits.chunks(8).map(|c| c.iter().fold(0u8, |a, &b| (a << 1) | b as u8)).collect()
}
}
#[test]
fn context_init_formula() {
let c = Cabac::new(&[0, 0, 0, 0], 0, 26, 3).unwrap();
// ctxIdx 0: m=20, n=-15 at QP 26: ((20*26)>>4) - 15 = 32 - 15 = 17 -> pState 46, MPS 0
assert_eq!(c.ctx[0], 46 << 1);
// ctxIdx 60: m=0,n=41 -> pre 41 -> pState 22 MPS 0
assert_eq!(c.ctx[60], 22 << 1);
// ctxIdx 70 (I): m=0 n=11 -> pState 52 MPS 0
assert_eq!(c.ctx[70], 52 << 1);
}
#[test]
fn round_trip_random_bins() {
let mut seed = 12345u32;
let mut rnd = || {
seed ^= seed << 13;
seed ^= seed >> 17;
seed ^= seed << 5;
seed
};
let dummy = Cabac::new(&[0, 0, 0, 0], 0, 30, 0).unwrap();
let mut enc = Enc::new(&dummy.ctx);
let mut ops = Vec::new();
for _ in 0..5000 {
let kind = rnd() % 4;
let ctx = (rnd() % 16) as usize;
// skewed bins so contexts adapt
let bin = if rnd() % 10 < 8 { (ctx & 1) as u32 } else { 1 - (ctx & 1) as u32 };
if kind == 0 {
enc.bypass(bin);
} else {
enc.encode(ctx, bin);
}
ops.push((kind, ctx, bin));
}
let bytes = enc.terminate_flush();
let mut dec = Cabac::new(&bytes, 0, 30, 0).unwrap();
for (i, &(kind, ctx, bin)) in ops.iter().enumerate() {
let got = if kind == 0 { dec.decode_bypass() } else { dec.decode_decision(ctx) };
assert_eq!(got, bin, "bin {i}");
}
assert_eq!(dec.decode_terminate(), 1);
}
}

675
crates/h264/src/cabac_mb.rs Normal file
View File

@ -0,0 +1,675 @@
//! CABAC slice data and macroblock layer parsing (7.3.4, 7.3.5 with 9.3 binarisations and context
//! index derivations).
use crate::cabac::Cabac;
use crate::error::{Result, ensure, invalid};
use crate::mbtypes::*;
use crate::picture::MbKind;
use crate::slice::SliceType;
use crate::slicedec::{MbCur, SliceDecoder};
/// Table 9-43: significant_coeff_flag ctxIdxInc for 8x8 frame blocks.
#[rustfmt::skip]
const SIG8_FRAME: [u8; 63] = [
0, 1, 2, 3, 4, 5, 5, 4, 4, 3, 3, 4, 4, 4, 5, 5, 4, 4, 4, 4, 3, 3, 6, 7, 7, 7, 8, 9, 10, 9, 8, 7,
7, 6, 11, 12, 13, 11, 6, 7, 8, 9, 14, 10, 9, 8, 6, 11, 12, 13, 11, 6, 9, 14, 10, 9, 11, 12, 13, 11, 14, 10, 12,
];
/// Table 9-43: last_significant_coeff_flag ctxIdxInc for 8x8 blocks.
#[rustfmt::skip]
const LAST8: [u8; 63] = [
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8,
];
/// Table 9-40 ctxIdxBlockCatOffset for ctxBlockCat 0..=5: (coded_block_flag, significant/last, abs level).
const CAT_OFFSET: [(usize, usize, usize); 6] = [(0, 0, 0), (4, 15, 10), (8, 29, 20), (12, 44, 30), (16, 47, 39), (0, 0, 0)];
impl SliceDecoder<'_> {
/// Decode slice_data() with CABAC. `rbsp` is the whole slice RBSP.
pub fn decode_cabac(&mut self, rbsp: &[u8]) -> Result<()> {
let start = self.sh.header_bits.div_ceil(8) * 8;
let init = if self.sh.slice_type.is_intra() { 3 } else { self.sh.cabac_init_idc as usize };
let mut c = Cabac::new(rbsp, start, self.sh.qp(self.pps), init)?;
let total = self.mb_w * self.mb_h;
let mut addr = self.sh.first_mb_in_slice as usize;
let intra_slice = self.sh.slice_type.is_intra();
loop {
ensure!(addr < total, "macroblock address {addr} out of range");
self.start_mb(addr);
let skip = !intra_slice && self.decode_skip_flag(&mut c);
if skip {
self.decode_skip()?;
} else {
self.decode_mb_cabac(&mut c)?;
}
self.pic.decoded_mbs += 1;
ensure!(!c.overrun(), "CABAC read past end of slice data");
if c.decode_terminate() == 1 {
break;
}
addr += 1;
}
Ok(())
}
fn decode_skip_flag(&mut self, c: &mut Cabac) -> bool {
let cond = |n: Option<usize>| n.map(|m| !self.pic.mbs[m].kind_is_skip()).unwrap_or(false) as usize;
let inc = cond(self.nb[0]) + cond(self.nb[1]);
let base = if self.sh.slice_type.is_b() { 24 } else { 11 };
c.decode_decision(base + inc) == 1
}
/// Intra mb_type suffix / I-slice mb_type (Table 9-36). `base` is 3 (I slice) or 17/32 (prefix
/// offsets in P/B slices). Returns the I-slice mb_type value 0..=25.
fn decode_mb_type_i(&mut self, c: &mut Cabac, base: usize) -> u32 {
let islice = base == 3;
let b0 = if islice {
let cond = |n: Option<usize>| n.map(|m| !matches!(self.pic.mbs[m].kind, MbKind::I4x4 | MbKind::I8x8)).unwrap_or(false) as usize;
let inc = cond(self.nb[0]) + cond(self.nb[1]);
c.decode_decision(base + inc)
} else {
c.decode_decision(base)
};
if b0 == 0 {
return 0;
}
if c.decode_terminate() == 1 {
return 25;
}
let (c_luma, c_chroma, c_chroma2, c_pred0, c_pred1) =
if islice { (base + 3, base + 4, base + 5, base + 6, base + 7) } else { (base + 1, base + 2, base + 2, base + 3, base + 3) };
let luma = c.decode_decision(c_luma);
let mut chroma = c.decode_decision(c_chroma);
if chroma != 0 {
chroma += c.decode_decision(c_chroma2);
}
let p0 = c.decode_decision(c_pred0);
let p1 = c.decode_decision(c_pred1);
1 + (p0 * 2 + p1) + 4 * chroma + 12 * luma
}
fn decode_mb_type(&mut self, c: &mut Cabac) -> Result<MbTypeInfo> {
let info = match self.sh.slice_type {
SliceType::I | SliceType::Si => intra_mb_type(self.decode_mb_type_i(c, 3)),
SliceType::P | SliceType::Sp => {
if c.decode_decision(14) == 1 {
intra_mb_type(self.decode_mb_type_i(c, 17))
} else if c.decode_decision(15) == 0 {
p_mb_type(if c.decode_decision(16) == 0 { 0 } else { 3 })
} else {
p_mb_type(if c.decode_decision(17) == 1 { 1 } else { 2 })
}
}
SliceType::B => {
let cond = |n: Option<usize>| n.map(|m| !matches!(self.pic.mbs[m].kind, MbKind::BSkip | MbKind::BDirect16x16)).unwrap_or(false) as usize;
let inc = cond(self.nb[0]) + cond(self.nb[1]);
if c.decode_decision(27 + inc) == 0 {
b_mb_type(0)
} else if c.decode_decision(27 + 3) == 0 {
b_mb_type(1 + c.decode_decision(27 + 5))
} else {
let b2 = c.decode_decision(27 + 4);
let b3 = c.decode_decision(27 + 5);
let b4 = c.decode_decision(27 + 5);
let b5 = c.decode_decision(27 + 5);
let v = (b2 << 3) | (b3 << 2) | (b4 << 1) | b5;
match v {
0b1101 => intra_mb_type(self.decode_mb_type_i(c, 32)),
0b1111 => b_mb_type(22),
0b1110 => b_mb_type(11),
_ if b2 == 0 => b_mb_type(3 + v),
_ => {
let b6 = c.decode_decision(27 + 5);
b_mb_type(12 + (((v & 7) << 1) | b6))
}
}
}
}
};
match info {
Some(i) => Ok(i),
None => invalid("invalid CABAC mb_type"),
}
}
fn decode_sub_mb_type(&mut self, c: &mut Cabac) -> Result<SubMbInfo> {
let r = if self.sh.slice_type.is_b() {
if c.decode_decision(36) == 0 {
b_sub_mb_type(0)
} else if c.decode_decision(37) == 0 {
b_sub_mb_type(1 + c.decode_decision(39))
} else if c.decode_decision(38) == 1 {
if c.decode_decision(39) == 1 {
b_sub_mb_type(11 + c.decode_decision(39))
} else {
let b4 = c.decode_decision(39);
let b5 = c.decode_decision(39);
b_sub_mb_type(7 + (b4 << 1) + b5)
}
} else {
let b3 = c.decode_decision(39);
let b4 = c.decode_decision(39);
b_sub_mb_type(3 + (b3 << 1) + b4)
}
} else if c.decode_decision(21) == 1 {
p_sub_mb_type(0)
} else if c.decode_decision(22) == 0 {
p_sub_mb_type(1)
} else {
p_sub_mb_type(if c.decode_decision(23) == 1 { 2 } else { 3 })
};
match r {
Some(s) => Ok(s),
None => invalid("invalid CABAC sub_mb_type"),
}
}
/// ref_idx_lX for the partition whose top-left 4x4 block is (x, y) (9.3.3.1.1.6).
fn decode_ref_idx(&mut self, c: &mut Cabac, list: usize, x: usize, y: usize) -> u32 {
let cond = |xx: i32, yy: i32| -> usize {
let (mb, bx, by) = if xx < 0 {
(self.nb[0], 3usize, yy as usize)
} else if yy < 0 {
(self.nb[1], xx as usize, 3usize)
} else {
(Some(self.mb_addr), xx as usize, yy as usize)
};
let Some(m) = mb else { return 0 };
let st = &self.pic.mbs[m];
let b8 = (by >> 1) * 2 + (bx >> 1);
if st.kind.is_intra() || st.kind_is_skip() || st.direct8x8 & (1 << b8) != 0 {
return 0;
}
(st.ref_idx[list][b8] > 0) as usize
};
let inc = cond(x as i32 - 1, y as i32) + 2 * cond(x as i32, y as i32 - 1);
let mut v = 0u32;
if c.decode_decision(54 + inc) == 1 {
v = 1;
if c.decode_decision(54 + 4) == 1 {
v = 2;
while c.decode_decision(54 + 5) == 1 {
v += 1;
if v > 32 {
break;
}
}
}
}
v
}
/// One mvd component for the (sub-)partition with top-left 4x4 block (x, y) (9.3.3.1.1.7, UEG3).
fn decode_mvd(&mut self, c: &mut Cabac, list: usize, comp: usize, x: usize, y: usize) -> i32 {
let absn = |xx: i32, yy: i32| -> u32 {
let (mb, bx, by) = if xx < 0 {
(self.nb[0], 3usize, yy as usize)
} else if yy < 0 {
(self.nb[1], xx as usize, 3usize)
} else {
(Some(self.mb_addr), xx as usize, yy as usize)
};
match mb {
Some(m) => self.pic.mbs[m].mvd[list][by * 4 + bx][comp] as u32,
None => 0,
}
};
let sum = absn(x as i32 - 1, y as i32) + absn(x as i32, y as i32 - 1);
let inc = if sum > 32 {
2
} else if sum > 2 {
1
} else {
0
};
let base = if comp == 0 { 40 } else { 47 };
if c.decode_decision(base + inc) == 0 {
return 0;
}
let mut prefix = 1;
while prefix < 9 && c.decode_decision(base + (prefix + 2).min(6)) == 1 {
prefix += 1;
}
let mut val = prefix as i32;
if prefix >= 9 {
// EG3 suffix
let mut k = 3;
while c.decode_bypass() == 1 {
val += 1 << k;
k += 1;
if k > 24 {
break;
}
}
while k > 0 {
k -= 1;
val += (c.decode_bypass() as i32) << k;
}
}
if c.decode_bypass() == 1 { -val } else { val }
}
fn set_cur_ref(&mut self, list: usize, x: usize, y: usize, w: usize, h: usize, r: i8) {
let st = self.mb_mut();
for yy in (y..y + h).step_by(2) {
for xx in (x..x + w).step_by(2) {
st.ref_idx[list][(yy >> 1) * 2 + (xx >> 1)] = r;
}
}
}
fn set_cur_mvd(&mut self, list: usize, x: usize, y: usize, w: usize, h: usize, d: [i32; 2]) {
let a = [d[0].unsigned_abs().min(127) as u8, d[1].unsigned_abs().min(127) as u8];
let st = self.mb_mut();
for yy in y..y + h {
for xx in x..x + w {
st.mvd[list][yy * 4 + xx] = a;
}
}
}
fn decode_cbp(&mut self, c: &mut Cabac) -> u8 {
let mut luma = 0u8;
for b8 in 0..4usize {
let (bx, by) = ((b8 & 1) * 2, (b8 >> 1) * 2);
// A
let ca = if bx > 0 { ((luma >> (b8 - 1)) & 1 == 0) as usize } else { self.cbp_luma_cond(self.nb[0], b8 + 1) };
let cb = if by > 0 { ((luma >> (b8 - 2)) & 1 == 0) as usize } else { self.cbp_luma_cond(self.nb[1], b8 + 2) };
let _ = (bx, by);
let bin = c.decode_decision(73 + ca + 2 * cb);
luma |= (bin as u8) << b8;
}
let cond = |n: Option<usize>, bin: usize| -> usize {
let Some(m) = n else { return 0 };
let st = &self.pic.mbs[m];
if st.kind == MbKind::IPcm {
return 1;
}
if st.kind_is_skip() {
return 0;
}
let ch = st.cbp >> 4;
if bin == 0 { (ch != 0) as usize } else { (ch == 2) as usize }
};
let inc0 = cond(self.nb[0], 0) + 2 * cond(self.nb[1], 0);
let mut chroma = 0u8;
if c.decode_decision(77 + inc0) == 1 {
let inc1 = cond(self.nb[0], 1) + 2 * cond(self.nb[1], 1) + 4;
chroma = 1 + c.decode_decision(77 + inc1) as u8;
}
luma | (chroma << 4)
}
/// condTermFlagN for coded_block_pattern luma bin from a neighbouring MB; `b8n` is the neighbouring
/// 8x8 block index within that MB.
fn cbp_luma_cond(&self, n: Option<usize>, b8n: usize) -> usize {
let Some(m) = n else { return 0 };
let st = &self.pic.mbs[m];
if st.kind == MbKind::IPcm {
return 0;
}
if st.kind_is_skip() {
return 1;
}
((st.cbp >> (b8n & 3)) & 1 == 0) as usize
}
fn decode_qp_delta(&mut self, c: &mut Cabac) -> Result<i32> {
let inc = self.prev_qp_delta_nz as usize;
if c.decode_decision(60 + inc) == 0 {
return Ok(0);
}
let mut k = 1u32;
let mut ctx = 62;
while c.decode_decision(ctx) == 1 {
k += 1;
ctx = 63;
ensure!(k <= 128, "mb_qp_delta too large");
}
let v = k.div_ceil(2) as i32;
Ok(if k % 2 == 1 { v } else { -v })
}
/// coded_block_flag ctxIdxInc condition for a neighbouring luma 4x4 block (cat 0..2) or chroma.
fn cbf_luma_cond(&self, bx: i32, by: i32, intra_cur: bool) -> usize {
if bx >= 0 && by >= 0 {
return (self.mb().nnz[(by * 4 + bx) as usize] != 0) as usize;
}
let n = if bx < 0 { self.nb[0] } else { self.nb[1] };
let Some(m) = n else { return intra_cur as usize };
let st = &self.pic.mbs[m];
let (x, y) = if bx < 0 { (3, by as usize) } else { (bx as usize, 3) };
(st.nnz[y * 4 + x] != 0) as usize
}
fn cbf_dc_cond(&self, n: Option<usize>, bit: u8, intra_cur: bool) -> usize {
let Some(m) = n else { return intra_cur as usize };
let st = &self.pic.mbs[m];
if st.kind == MbKind::IPcm {
return 1;
}
(st.cbf_dc & (1 << bit) != 0) as usize
}
fn cbf_chroma_ac_cond(&self, comp: usize, bx: i32, by: i32, intra_cur: bool) -> usize {
if bx >= 0 && by >= 0 {
return (self.mb().nnz_c[comp][(by * 2 + bx) as usize] != 0) as usize;
}
let n = if bx < 0 { self.nb[0] } else { self.nb[1] };
let Some(m) = n else { return intra_cur as usize };
let st = &self.pic.mbs[m];
let (x, y) = if bx < 0 { (1, by as usize) } else { (bx as usize, 1) };
(st.nnz_c[comp][y * 2 + x] != 0) as usize
}
/// residual_block_cabac for ctxBlockCat `cat` (0..=5). Coefficients are written to `coeff`
/// in list order (indices 0..max_num). `cbf_inc` is the coded_block_flag ctxIdxInc (ignored for cat 5).
/// Returns the number of non-zero coefficients.
fn residual_block_cabac(&mut self, c: &mut Cabac, coeff: &mut [i32], cat: usize, max_num: usize, cbf_inc: usize) -> u8 {
if cat != 5 && c.decode_decision(85 + CAT_OFFSET[cat].0 + cbf_inc) == 0 {
return 0;
}
let (sig_base, last_base, abs_base) =
if cat == 5 { (402, 417, 426) } else { (105 + CAT_OFFSET[cat].1, 166 + CAT_OFFSET[cat].1, 227 + CAT_OFFSET[cat].2) };
let mut sig = [false; 64];
let mut num = max_num;
let mut i = 0;
while i + 1 < num {
let (si, li) = match cat {
3 => (i.min(2), i.min(2)),
5 => (SIG8_FRAME[i] as usize, LAST8[i] as usize),
_ => (i, i),
};
if c.decode_decision(sig_base + si) == 1 {
sig[i] = true;
if c.decode_decision(last_base + li) == 1 {
num = i + 1;
break;
}
}
i += 1;
}
sig[num - 1] = true;
let mut eq1 = 0usize;
let mut gt1 = 0usize;
let mut count = 0u8;
let gt1_cap = if cat == 3 { 3 } else { 4 };
for i in (0..num).rev() {
if !sig[i] {
continue;
}
let inc0 = if gt1 != 0 { 0 } else { (1 + eq1).min(4) };
let mut abs = 1i32;
if c.decode_decision(abs_base + inc0) == 1 {
let ctx = abs_base + 5 + gt1.min(gt1_cap);
let mut prefix = 1;
while prefix < 14 && c.decode_decision(ctx) == 1 {
prefix += 1;
}
abs = prefix + 1;
if prefix == 14 {
let mut k = 0;
let mut suf = 0i32;
while c.decode_bypass() == 1 {
suf += 1 << k;
k += 1;
if k > 24 {
break;
}
}
while k > 0 {
k -= 1;
suf += (c.decode_bypass() as i32) << k;
}
abs += suf;
}
}
if abs == 1 {
eq1 += 1;
} else {
gt1 += 1;
}
coeff[i] = if c.decode_bypass() == 1 { -abs } else { abs };
count += 1;
}
count
}
fn residual_cabac(&mut self, c: &mut Cabac, cbp: u8) -> Result<()> {
let kind = self.mb().kind;
let intra = kind.is_intra();
let t8 = self.mb().transform_8x8;
if kind == MbKind::I16x16 {
let inc = self.cbf_dc_cond(self.nb[0], 0, intra) + 2 * self.cbf_dc_cond(self.nb[1], 0, intra);
let mut lv = [0i32; 16];
if self.residual_block_cabac(c, &mut lv, 0, 16, inc) > 0 {
self.mb_mut().cbf_dc |= 1;
self.put_luma_dc(&lv);
}
}
for b8 in 0..4 {
let (bx8, by8) = ((b8 & 1) * 2, (b8 >> 1) * 2);
if cbp & (1 << b8) == 0 {
continue;
}
if t8 {
let mut lv = [0i32; 64];
self.residual_block_cabac(c, &mut lv, 5, 64, 0);
let st = self.mb_mut();
for r in [by8 * 4 + bx8, by8 * 4 + bx8 + 1, (by8 + 1) * 4 + bx8, (by8 + 1) * 4 + bx8 + 1] {
st.nnz[r] = 1;
}
self.put_luma8(b8, &lv);
} else {
for i4 in 0..4 {
let (bx, by) = (bx8 + (i4 & 1), by8 + (i4 >> 1));
let raster = by * 4 + bx;
let inc = self.cbf_luma_cond(bx as i32 - 1, by as i32, intra) + 2 * self.cbf_luma_cond(bx as i32, by as i32 - 1, intra);
let mut lv = [0i32; 16];
let n = if kind == MbKind::I16x16 {
self.residual_block_cabac(c, &mut lv[1..], 1, 15, inc)
} else {
self.residual_block_cabac(c, &mut lv, 2, 16, inc)
};
self.mb_mut().nnz[raster] = n;
if n > 0 {
self.put_luma4(raster, &lv, kind == MbKind::I16x16);
}
}
}
}
let cbp_c = cbp >> 4;
if cbp_c != 0 {
for comp in 0..2 {
let bit = 1 + comp as u8;
let inc = self.cbf_dc_cond(self.nb[0], bit, intra) + 2 * self.cbf_dc_cond(self.nb[1], bit, intra);
let mut lv = [0i32; 4];
if self.residual_block_cabac(c, &mut lv, 3, 4, inc) > 0 {
self.mb_mut().cbf_dc |= 1 << bit;
self.put_chroma_dc(comp, &lv);
}
}
}
if cbp_c == 2 {
for comp in 0..2 {
for b in 0..4 {
let (bx, by) = ((b & 1) as i32, (b >> 1) as i32);
let inc = self.cbf_chroma_ac_cond(comp, bx - 1, by, intra) + 2 * self.cbf_chroma_ac_cond(comp, bx, by - 1, intra);
let mut lv = [0i32; 16];
let n = self.residual_block_cabac(c, &mut lv[1..], 4, 15, inc);
self.mb_mut().nnz_c[comp][b] = n;
if n > 0 {
self.put_chroma_ac(comp, b, &lv);
}
}
}
}
Ok(())
}
/// Parse and reconstruct one macroblock_layer() with CABAC.
fn decode_mb_cabac(&mut self, c: &mut Cabac) -> Result<()> {
let mut info = self.decode_mb_type(c)?;
self.cur = MbCur { info, ..Default::default() };
if info.kind == MbKind::IPcm {
// pcm alignment + samples, then re-initialise the arithmetic decoder
let pos = c.bit_pos().div_ceil(8);
let data = c.data();
ensure!(data.len() >= pos + 384, "truncated I_PCM macroblock");
let samples: [u8; 384] = data[pos..pos + 384].try_into().unwrap();
c.set_bit_pos((pos + 384) * 8);
c.init_engine()?;
self.finish_pcm();
self.write_pcm(&samples);
self.prev_qp_delta_nz = false;
return Ok(());
}
let intra = info.kind.is_intra();
if info.kind == MbKind::I4x4 && self.pps.transform_8x8_mode && self.decode_t8x8_flag(c) {
info.kind = MbKind::I8x8;
self.cur.info.kind = MbKind::I8x8;
self.mb_mut().transform_8x8 = true;
}
self.mb_mut().kind = info.kind;
let n_ref = self.sh.num_ref_idx_active;
match info.kind {
MbKind::I4x4 | MbKind::I8x8 => {
let n = if info.kind == MbKind::I8x8 { 4 } else { 16 };
for i in 0..n {
self.cur.rem_mode[i] = if c.decode_decision(68) == 1 {
-1
} else {
let b0 = c.decode_decision(69);
let b1 = c.decode_decision(69);
let b2 = c.decode_decision(69);
(b0 | (b1 << 1) | (b2 << 2)) as i8
};
}
self.derive_intra_modes(info.kind == MbKind::I8x8);
let m = self.decode_chroma_mode(c);
self.mb_mut().intra_chroma_mode = m;
}
MbKind::I16x16 => {
let m = self.decode_chroma_mode(c);
self.mb_mut().intra_chroma_mode = m;
}
MbKind::BDirect16x16 => {
self.mb_mut().direct8x8 = 0xf;
}
_ => {
if info.part == Part::P8x8 {
for p in 0..4 {
self.cur.sub[p] = self.decode_sub_mb_type(c)?;
}
let direct_mask: u8 = (0..4).filter(|&p| self.cur.sub[p].direct).map(|p| 1u8 << p).sum();
self.mb_mut().direct8x8 = direct_mask;
for l in 0..2 {
for p in 0..4 {
let sub = self.cur.sub[p];
if sub.direct || sub.pred & (1 << l) == 0 {
continue;
}
let (x, y) = ((p & 1) * 2, (p >> 1) * 2);
let r = if n_ref[l] > 1 && !info.ref0 { self.decode_ref_idx(c, l, x, y) as i8 } else { 0 };
self.cur.ref_idx[l][p] = r;
self.set_cur_ref(l, x, y, 2, 2, r);
}
}
for l in 0..2 {
for p in 0..4 {
let sub = self.cur.sub[p];
if sub.direct || sub.pred & (1 << l) == 0 {
continue;
}
let (x8, y8) = ((p & 1) * 2, (p >> 1) * 2);
for j in 0..sub.shape.num_parts() {
let (sx, sy, w, h) = sub.shape.rect(j);
let (x, y) = (x8 + sx, y8 + sy);
let dx = self.decode_mvd(c, l, 0, x, y);
let dy = self.decode_mvd(c, l, 1, x, y);
self.set_cur_mvd(l, x, y, w, h, [dx, dy]);
self.cur.mvd[l][p * 4 + j] = [dx as i16, dy as i16];
}
}
}
} else {
let np = info.part.num_parts();
for l in 0..2 {
for p in 0..np {
if info.pred[p] & (1 << l) == 0 {
continue;
}
let (x, y, w, h) = info.part.rect(p);
let r = if n_ref[l] > 1 { self.decode_ref_idx(c, l, x, y) as i8 } else { 0 };
self.cur.ref_idx[l][p] = r;
self.set_cur_ref(l, x, y, w, h, r);
}
}
for l in 0..2 {
for p in 0..np {
if info.pred[p] & (1 << l) == 0 {
continue;
}
let (x, y, w, h) = info.part.rect(p);
let dx = self.decode_mvd(c, l, 0, x, y);
let dy = self.decode_mvd(c, l, 1, x, y);
self.set_cur_mvd(l, x, y, w, h, [dx, dy]);
self.cur.mvd[l][p * 4] = [dx as i16, dy as i16];
}
}
}
}
}
let cbp = if info.kind == MbKind::I16x16 { info.i16_cbp } else { self.decode_cbp(c) };
self.cur.cbp = cbp;
self.mb_mut().cbp = cbp;
if !intra && cbp & 15 != 0 && self.pps.transform_8x8_mode && self.no_sub_8x8_lt() {
let t = self.decode_t8x8_flag(c);
self.mb_mut().transform_8x8 = t;
}
if !intra {
// ref_idx written during parsing is replaced by the derived motion
self.derive_inter_motion()?;
}
if cbp != 0 || info.kind == MbKind::I16x16 {
let d = self.decode_qp_delta(c)?;
self.apply_qp_delta(d)?;
self.prev_qp_delta_nz = d != 0;
} else {
self.prev_qp_delta_nz = false;
}
self.store_qp();
self.residual_cabac(c, cbp)?;
if intra {
self.reconstruct_intra();
} else {
self.predict_inter();
self.reconstruct_inter_residual();
}
Ok(())
}
fn decode_t8x8_flag(&mut self, c: &mut Cabac) -> bool {
let cond = |n: Option<usize>| n.map(|m| self.pic.mbs[m].transform_8x8).unwrap_or(false) as usize;
let inc = cond(self.nb[0]) + cond(self.nb[1]);
c.decode_decision(399 + inc) == 1
}
fn decode_chroma_mode(&mut self, c: &mut Cabac) -> u8 {
let cond = |n: Option<usize>| {
n.map(|m| {
let st = &self.pic.mbs[m];
st.kind.is_intra() && st.kind != MbKind::IPcm && st.intra_chroma_mode != 0
})
.unwrap_or(false) as usize
};
let inc = cond(self.nb[0]) + cond(self.nb[1]);
if c.decode_decision(64 + inc) == 0 {
return 0;
}
if c.decode_decision(67) == 0 {
return 1;
}
if c.decode_decision(67) == 0 { 2 } else { 3 }
}
}

View File

@ -0,0 +1,525 @@
// Generated from ITU-T H.264 (06/2026) Tables 9-12..9-33 (m, n) by a table-extraction script.
// Index: [0..=2] = cabac_init_idc for P/SP/B slices, [3] = I/SI slices. (0, 0) marks "na".
#[rustfmt::skip]
pub(crate) static CABAC_INIT_MN: [[(i8, i8); 1024]; 4] = [
[
(20, -15), (2, 54), (3, 74), (20, -15), (2, 54), (3, 74), (-28, 127), (-23, 104),
(-6, 53), (-1, 54), (7, 51), (23, 33), (23, 2), (21, 0), (1, 9), (0, 49),
(-37, 118), (5, 57), (-13, 78), (-11, 65), (1, 62), (12, 49), (-4, 73), (17, 50),
(18, 64), (9, 43), (29, 0), (26, 67), (16, 90), (9, 104), (-46, 127), (-20, 104),
(1, 67), (-13, 78), (-11, 65), (1, 62), (-6, 86), (-17, 95), (-6, 61), (9, 45),
(-3, 69), (-6, 81), (-11, 96), (6, 55), (7, 67), (-5, 86), (2, 88), (0, 58),
(-3, 76), (-10, 94), (5, 54), (4, 69), (-3, 81), (0, 88), (-7, 67), (-5, 74),
(-4, 74), (-5, 80), (-7, 72), (1, 58), (0, 41), (0, 63), (0, 63), (0, 63),
(-9, 83), (4, 86), (0, 97), (-7, 72), (13, 41), (3, 62), (0, 45), (-4, 78),
(-3, 96), (-27, 126), (-28, 98), (-25, 101), (-23, 67), (-28, 82), (-20, 94), (-16, 83),
(-22, 110), (-21, 91), (-18, 102), (-13, 93), (-29, 127), (-7, 92), (-5, 89), (-7, 96),
(-13, 108), (-3, 46), (-1, 65), (-1, 57), (-9, 93), (-3, 74), (-9, 92), (-8, 87),
(-23, 126), (5, 54), (6, 60), (6, 59), (6, 69), (-1, 48), (0, 68), (-4, 69),
(-8, 88), (-2, 85), (-6, 78), (-1, 75), (-7, 77), (2, 54), (5, 50), (-3, 68),
(1, 50), (6, 42), (-4, 81), (1, 63), (-4, 70), (0, 67), (2, 57), (-2, 76),
(11, 35), (4, 64), (1, 61), (11, 35), (18, 25), (12, 24), (13, 29), (13, 36),
(-10, 93), (-7, 73), (-2, 73), (13, 46), (9, 49), (-7, 100), (9, 53), (2, 53),
(5, 53), (-2, 61), (0, 56), (0, 56), (-13, 63), (-5, 60), (-1, 62), (4, 57),
(-6, 69), (4, 57), (14, 39), (4, 51), (13, 68), (3, 64), (1, 61), (9, 63),
(7, 50), (16, 39), (5, 44), (4, 52), (11, 48), (-5, 60), (-1, 59), (0, 59),
(22, 33), (5, 44), (14, 43), (-1, 78), (0, 60), (9, 69), (11, 28), (2, 40),
(3, 44), (0, 49), (0, 46), (2, 44), (2, 51), (0, 47), (4, 39), (2, 62),
(6, 46), (0, 54), (3, 54), (2, 58), (4, 63), (6, 51), (6, 57), (7, 53),
(6, 52), (6, 55), (11, 45), (14, 36), (8, 53), (-1, 82), (7, 55), (-3, 78),
(15, 46), (22, 31), (-1, 84), (25, 7), (30, -7), (28, 3), (28, 4), (32, 0),
(34, -1), (30, 6), (30, 6), (32, 9), (31, 19), (26, 27), (26, 30), (37, 20),
(28, 34), (17, 70), (1, 67), (5, 59), (9, 67), (16, 30), (18, 32), (18, 35),
(22, 29), (24, 31), (23, 38), (18, 43), (20, 41), (11, 63), (9, 59), (9, 64),
(-1, 94), (-2, 89), (-9, 108), (-6, 76), (-2, 44), (0, 45), (0, 52), (-3, 64),
(-2, 59), (-4, 70), (-4, 75), (-8, 82), (-17, 102), (-9, 77), (3, 24), (0, 42),
(0, 48), (0, 55), (-6, 59), (-7, 71), (-12, 83), (-11, 87), (-30, 119), (1, 58),
(-3, 29), (-1, 36), (1, 38), (2, 43), (-6, 55), (0, 58), (0, 64), (-3, 74),
(-10, 90), (0, 70), (-4, 29), (5, 31), (7, 42), (1, 59), (-2, 58), (-3, 72),
(-3, 81), (-11, 97), (0, 58), (8, 5), (10, 14), (14, 18), (13, 27), (2, 40),
(0, 58), (-3, 70), (-6, 79), (-8, 85), (0, 0), (-13, 106), (-16, 106), (-10, 87),
(-21, 114), (-18, 110), (-14, 98), (-22, 110), (-21, 106), (-18, 103), (-21, 107), (-23, 108),
(-26, 112), (-10, 96), (-12, 95), (-5, 91), (-9, 93), (-22, 94), (-5, 86), (9, 67),
(-4, 80), (-10, 85), (-1, 70), (7, 60), (9, 58), (5, 61), (12, 50), (15, 50),
(18, 49), (17, 54), (10, 41), (7, 46), (-1, 51), (7, 49), (8, 52), (9, 41),
(6, 47), (2, 55), (13, 41), (10, 44), (6, 50), (5, 53), (13, 49), (4, 63),
(6, 64), (-2, 69), (-2, 59), (6, 70), (10, 44), (9, 31), (12, 43), (3, 53),
(14, 34), (10, 38), (-3, 52), (13, 40), (17, 32), (7, 44), (7, 38), (13, 50),
(10, 57), (26, 43), (14, 11), (11, 14), (9, 11), (18, 11), (21, 9), (23, -2),
(32, -15), (32, -15), (34, -21), (39, -23), (42, -33), (41, -31), (46, -28), (38, -12),
(21, 29), (45, -24), (53, -45), (48, -26), (65, -43), (43, -19), (39, -10), (30, 9),
(18, 26), (20, 27), (0, 57), (-14, 82), (-5, 75), (-19, 97), (-35, 125), (27, 0),
(28, 0), (31, -4), (27, 6), (34, 8), (30, 10), (24, 22), (33, 19), (22, 32),
(26, 31), (21, 41), (26, 44), (23, 47), (16, 65), (14, 71), (8, 60), (6, 63),
(17, 65), (21, 24), (23, 20), (26, 23), (27, 32), (28, 23), (28, 24), (23, 40),
(24, 32), (28, 29), (23, 42), (19, 57), (22, 53), (22, 61), (11, 86), (12, 40),
(11, 51), (14, 59), (-4, 79), (-7, 71), (-5, 69), (-9, 70), (-8, 66), (-10, 68),
(-19, 73), (-12, 69), (-16, 70), (-15, 67), (-20, 62), (-19, 70), (-16, 66), (-22, 65),
(-20, 63), (9, -2), (26, -9), (33, -9), (39, -7), (41, -2), (45, 3), (49, 9),
(45, 27), (36, 59), (-6, 66), (-7, 35), (-7, 42), (-8, 45), (-5, 48), (-12, 56),
(-6, 60), (-5, 62), (-8, 66), (-8, 76), (-5, 85), (-6, 81), (-10, 77), (-7, 81),
(-17, 80), (-18, 73), (-4, 74), (-10, 83), (-9, 71), (-9, 67), (-1, 61), (-8, 66),
(-14, 66), (0, 59), (2, 59), (21, -13), (33, -14), (39, -7), (46, -2), (51, 2),
(60, 6), (61, 17), (55, 34), (42, 62), (-7, 92), (-5, 89), (-7, 96), (-13, 108),
(-3, 46), (-1, 65), (-1, 57), (-9, 93), (-3, 74), (-9, 92), (-8, 87), (-23, 126),
(-7, 92), (-5, 89), (-7, 96), (-13, 108), (-3, 46), (-1, 65), (-1, 57), (-9, 93),
(-3, 74), (-9, 92), (-8, 87), (-23, 126), (-2, 85), (-6, 78), (-1, 75), (-7, 77),
(2, 54), (5, 50), (-3, 68), (1, 50), (6, 42), (-4, 81), (1, 63), (-4, 70),
(0, 67), (2, 57), (-2, 76), (11, 35), (4, 64), (1, 61), (11, 35), (18, 25),
(12, 24), (13, 29), (13, 36), (-10, 93), (-7, 73), (-2, 73), (13, 46), (9, 49),
(-7, 100), (9, 53), (2, 53), (5, 53), (-2, 61), (0, 56), (0, 56), (-13, 63),
(-5, 60), (-1, 62), (4, 57), (-6, 69), (4, 57), (14, 39), (4, 51), (13, 68),
(-2, 85), (-6, 78), (-1, 75), (-7, 77), (2, 54), (5, 50), (-3, 68), (1, 50),
(6, 42), (-4, 81), (1, 63), (-4, 70), (0, 67), (2, 57), (-2, 76), (11, 35),
(4, 64), (1, 61), (11, 35), (18, 25), (12, 24), (13, 29), (13, 36), (-10, 93),
(-7, 73), (-2, 73), (13, 46), (9, 49), (-7, 100), (9, 53), (2, 53), (5, 53),
(-2, 61), (0, 56), (0, 56), (-13, 63), (-5, 60), (-1, 62), (4, 57), (-6, 69),
(4, 57), (14, 39), (4, 51), (13, 68), (11, 28), (2, 40), (3, 44), (0, 49),
(0, 46), (2, 44), (2, 51), (0, 47), (4, 39), (2, 62), (6, 46), (0, 54),
(3, 54), (2, 58), (4, 63), (6, 51), (6, 57), (7, 53), (6, 52), (6, 55),
(11, 45), (14, 36), (8, 53), (-1, 82), (7, 55), (-3, 78), (15, 46), (22, 31),
(-1, 84), (25, 7), (30, -7), (28, 3), (28, 4), (32, 0), (34, -1), (30, 6),
(30, 6), (32, 9), (31, 19), (26, 27), (26, 30), (37, 20), (28, 34), (17, 70),
(11, 28), (2, 40), (3, 44), (0, 49), (0, 46), (2, 44), (2, 51), (0, 47),
(4, 39), (2, 62), (6, 46), (0, 54), (3, 54), (2, 58), (4, 63), (6, 51),
(6, 57), (7, 53), (6, 52), (6, 55), (11, 45), (14, 36), (8, 53), (-1, 82),
(7, 55), (-3, 78), (15, 46), (22, 31), (-1, 84), (25, 7), (30, -7), (28, 3),
(28, 4), (32, 0), (34, -1), (30, 6), (30, 6), (32, 9), (31, 19), (26, 27),
(26, 30), (37, 20), (28, 34), (17, 70), (-4, 79), (-7, 71), (-5, 69), (-9, 70),
(-8, 66), (-10, 68), (-19, 73), (-12, 69), (-16, 70), (-15, 67), (-20, 62), (-19, 70),
(-16, 66), (-22, 65), (-20, 63), (-5, 85), (-6, 81), (-10, 77), (-7, 81), (-17, 80),
(-18, 73), (-4, 74), (-10, 83), (-9, 71), (-9, 67), (-1, 61), (-8, 66), (-14, 66),
(0, 59), (2, 59), (9, -2), (26, -9), (33, -9), (39, -7), (41, -2), (45, 3),
(49, 9), (45, 27), (36, 59), (21, -13), (33, -14), (39, -7), (46, -2), (51, 2),
(60, 6), (61, 17), (55, 34), (42, 62), (-6, 66), (-7, 35), (-7, 42), (-8, 45),
(-5, 48), (-12, 56), (-6, 60), (-5, 62), (-8, 66), (-8, 76), (-4, 79), (-7, 71),
(-5, 69), (-9, 70), (-8, 66), (-10, 68), (-19, 73), (-12, 69), (-16, 70), (-15, 67),
(-20, 62), (-19, 70), (-16, 66), (-22, 65), (-20, 63), (-5, 85), (-6, 81), (-10, 77),
(-7, 81), (-17, 80), (-18, 73), (-4, 74), (-10, 83), (-9, 71), (-9, 67), (-1, 61),
(-8, 66), (-14, 66), (0, 59), (2, 59), (9, -2), (26, -9), (33, -9), (39, -7),
(41, -2), (45, 3), (49, 9), (45, 27), (36, 59), (21, -13), (33, -14), (39, -7),
(46, -2), (51, 2), (60, 6), (61, 17), (55, 34), (42, 62), (-6, 66), (-7, 35),
(-7, 42), (-8, 45), (-5, 48), (-12, 56), (-6, 60), (-5, 62), (-8, 66), (-8, 76),
(-13, 106), (-16, 106), (-10, 87), (-21, 114), (-18, 110), (-14, 98), (-22, 110), (-21, 106),
(-18, 103), (-21, 107), (-23, 108), (-26, 112), (-10, 96), (-12, 95), (-5, 91), (-9, 93),
(-22, 94), (-5, 86), (9, 67), (-4, 80), (-10, 85), (-1, 70), (7, 60), (9, 58),
(5, 61), (12, 50), (15, 50), (18, 49), (17, 54), (10, 41), (7, 46), (-1, 51),
(7, 49), (8, 52), (9, 41), (6, 47), (2, 55), (13, 41), (10, 44), (6, 50),
(5, 53), (13, 49), (4, 63), (6, 64), (-13, 106), (-16, 106), (-10, 87), (-21, 114),
(-18, 110), (-14, 98), (-22, 110), (-21, 106), (-18, 103), (-21, 107), (-23, 108), (-26, 112),
(-10, 96), (-12, 95), (-5, 91), (-9, 93), (-22, 94), (-5, 86), (9, 67), (-4, 80),
(-10, 85), (-1, 70), (7, 60), (9, 58), (5, 61), (12, 50), (15, 50), (18, 49),
(17, 54), (10, 41), (7, 46), (-1, 51), (7, 49), (8, 52), (9, 41), (6, 47),
(2, 55), (13, 41), (10, 44), (6, 50), (5, 53), (13, 49), (4, 63), (6, 64),
(14, 11), (11, 14), (9, 11), (18, 11), (21, 9), (23, -2), (32, -15), (32, -15),
(34, -21), (39, -23), (42, -33), (41, -31), (46, -28), (38, -12), (21, 29), (45, -24),
(53, -45), (48, -26), (65, -43), (43, -19), (39, -10), (30, 9), (18, 26), (20, 27),
(0, 57), (-14, 82), (-5, 75), (-19, 97), (-35, 125), (27, 0), (28, 0), (31, -4),
(27, 6), (34, 8), (30, 10), (24, 22), (33, 19), (22, 32), (26, 31), (21, 41),
(26, 44), (23, 47), (16, 65), (14, 71), (14, 11), (11, 14), (9, 11), (18, 11),
(21, 9), (23, -2), (32, -15), (32, -15), (34, -21), (39, -23), (42, -33), (41, -31),
(46, -28), (38, -12), (21, 29), (45, -24), (53, -45), (48, -26), (65, -43), (43, -19),
(39, -10), (30, 9), (18, 26), (20, 27), (0, 57), (-14, 82), (-5, 75), (-19, 97),
(-35, 125), (27, 0), (28, 0), (31, -4), (27, 6), (34, 8), (30, 10), (24, 22),
(33, 19), (22, 32), (26, 31), (21, 41), (26, 44), (23, 47), (16, 65), (14, 71),
(-6, 76), (-2, 44), (0, 45), (0, 52), (-3, 64), (-2, 59), (-4, 70), (-4, 75),
(-8, 82), (-17, 102), (-9, 77), (3, 24), (0, 42), (0, 48), (0, 55), (-6, 59),
(-7, 71), (-12, 83), (-11, 87), (-30, 119), (1, 58), (-3, 29), (-1, 36), (1, 38),
(2, 43), (-6, 55), (0, 58), (0, 64), (-3, 74), (-10, 90), (-6, 76), (-2, 44),
(0, 45), (0, 52), (-3, 64), (-2, 59), (-4, 70), (-4, 75), (-8, 82), (-17, 102),
(-9, 77), (3, 24), (0, 42), (0, 48), (0, 55), (-6, 59), (-7, 71), (-12, 83),
(-11, 87), (-30, 119), (1, 58), (-3, 29), (-1, 36), (1, 38), (2, 43), (-6, 55),
(0, 58), (0, 64), (-3, 74), (-10, 90), (-3, 74), (-9, 92), (-8, 87), (-23, 126),
(-3, 74), (-9, 92), (-8, 87), (-23, 126), (-3, 74), (-9, 92), (-8, 87), (-23, 126),
],
[
(20, -15), (2, 54), (3, 74), (20, -15), (2, 54), (3, 74), (-28, 127), (-23, 104),
(-6, 53), (-1, 54), (7, 51), (22, 25), (34, 0), (16, 0), (-2, 9), (4, 41),
(-29, 118), (2, 65), (-6, 71), (-13, 79), (5, 52), (9, 50), (-3, 70), (10, 54),
(26, 34), (19, 22), (40, 0), (57, 2), (41, 36), (26, 69), (-45, 127), (-15, 101),
(-4, 76), (-6, 71), (-13, 79), (5, 52), (6, 69), (-13, 90), (0, 52), (8, 43),
(-2, 69), (-5, 82), (-10, 96), (2, 59), (2, 75), (-3, 87), (-3, 100), (1, 56),
(-3, 74), (-6, 85), (0, 59), (-3, 81), (-7, 86), (-5, 95), (-1, 66), (-1, 77),
(1, 70), (-2, 86), (-5, 72), (0, 61), (0, 41), (0, 63), (0, 63), (0, 63),
(-9, 83), (4, 86), (0, 97), (-7, 72), (13, 41), (3, 62), (13, 15), (7, 51),
(2, 80), (-39, 127), (-18, 91), (-17, 96), (-26, 81), (-35, 98), (-24, 102), (-23, 97),
(-27, 119), (-24, 99), (-21, 110), (-18, 102), (-36, 127), (0, 80), (-5, 89), (-7, 94),
(-4, 92), (0, 39), (0, 65), (-15, 84), (-35, 127), (-2, 73), (-12, 104), (-9, 91),
(-31, 127), (3, 55), (7, 56), (7, 55), (8, 61), (-3, 53), (0, 68), (-7, 74),
(-9, 88), (-13, 103), (-13, 91), (-9, 89), (-14, 92), (-8, 76), (-12, 87), (-23, 110),
(-24, 105), (-10, 78), (-20, 112), (-17, 99), (-78, 127), (-70, 127), (-50, 127), (-46, 127),
(-4, 66), (-5, 78), (-4, 71), (-8, 72), (2, 59), (-1, 55), (-7, 70), (-6, 75),
(-8, 89), (-34, 119), (-3, 75), (32, 20), (30, 22), (-44, 127), (0, 54), (-5, 61),
(0, 58), (-1, 60), (-3, 61), (-8, 67), (-25, 84), (-14, 74), (-5, 65), (5, 52),
(2, 57), (0, 61), (-9, 69), (-11, 70), (18, 55), (-4, 71), (0, 58), (7, 61),
(9, 41), (18, 25), (9, 32), (5, 43), (9, 47), (0, 44), (0, 51), (2, 46),
(19, 38), (-4, 66), (15, 38), (12, 42), (9, 34), (0, 89), (4, 45), (10, 28),
(10, 31), (33, -11), (52, -43), (18, 15), (28, 0), (35, -22), (38, -25), (34, 0),
(39, -18), (32, -12), (102, -94), (0, 0), (56, -15), (33, -4), (29, 10), (37, -5),
(51, -29), (39, -9), (52, -34), (69, -58), (67, -63), (44, -5), (32, 7), (55, -29),
(32, 1), (0, 0), (27, 36), (33, -25), (34, -30), (36, -28), (38, -28), (38, -27),
(34, -18), (35, -16), (34, -14), (32, -8), (37, -6), (35, 0), (30, 10), (28, 18),
(26, 25), (29, 41), (0, 75), (2, 72), (8, 77), (14, 35), (18, 31), (17, 35),
(21, 30), (17, 45), (20, 42), (18, 45), (27, 26), (16, 54), (7, 66), (16, 56),
(11, 73), (10, 67), (-10, 116), (-23, 112), (-15, 71), (-7, 61), (0, 53), (-5, 66),
(-11, 77), (-9, 80), (-9, 84), (-10, 87), (-34, 127), (-21, 101), (-3, 39), (-5, 53),
(-7, 61), (-11, 75), (-15, 77), (-17, 91), (-25, 107), (-25, 111), (-28, 122), (-11, 76),
(-10, 44), (-10, 52), (-10, 57), (-9, 58), (-16, 72), (-7, 69), (-4, 69), (-5, 74),
(-9, 86), (2, 66), (-9, 34), (1, 32), (11, 31), (5, 52), (-2, 55), (-2, 67),
(0, 73), (-8, 89), (3, 52), (7, 4), (10, 8), (17, 8), (16, 19), (3, 37),
(-1, 61), (-5, 73), (-1, 70), (-4, 78), (0, 0), (-21, 126), (-23, 124), (-20, 110),
(-26, 126), (-25, 124), (-17, 105), (-27, 121), (-27, 117), (-17, 102), (-26, 117), (-27, 116),
(-33, 122), (-10, 95), (-14, 100), (-8, 95), (-17, 111), (-28, 114), (-6, 89), (-2, 80),
(-4, 82), (-9, 85), (-8, 81), (-1, 72), (5, 64), (1, 67), (9, 56), (0, 69),
(1, 69), (7, 69), (-7, 69), (-6, 67), (-16, 77), (-2, 64), (2, 61), (-6, 67),
(-3, 64), (2, 57), (-3, 65), (-3, 66), (0, 62), (9, 51), (-1, 66), (-2, 71),
(-2, 75), (-1, 70), (-9, 72), (14, 60), (16, 37), (0, 47), (18, 35), (11, 37),
(12, 41), (10, 41), (2, 48), (12, 41), (13, 41), (0, 59), (3, 50), (19, 40),
(3, 66), (18, 50), (19, -6), (18, -6), (14, 0), (26, -12), (31, -16), (33, -25),
(33, -22), (37, -28), (39, -30), (42, -30), (47, -42), (45, -36), (49, -34), (41, -17),
(32, 9), (69, -71), (63, -63), (66, -64), (77, -74), (54, -39), (52, -35), (41, -10),
(36, 0), (40, -1), (30, 14), (28, 26), (23, 37), (12, 55), (11, 65), (37, -33),
(39, -36), (40, -37), (38, -30), (46, -33), (42, -30), (40, -24), (49, -29), (38, -12),
(40, -10), (38, -3), (46, -5), (31, 20), (29, 30), (25, 44), (12, 48), (11, 49),
(26, 45), (22, 22), (23, 22), (27, 21), (33, 20), (26, 28), (30, 24), (27, 34),
(18, 42), (25, 39), (18, 50), (12, 70), (21, 54), (14, 71), (11, 83), (25, 32),
(21, 49), (21, 54), (-5, 85), (-6, 81), (-10, 77), (-7, 81), (-17, 80), (-18, 73),
(-4, 74), (-10, 83), (-9, 71), (-9, 67), (-1, 61), (-8, 66), (-14, 66), (0, 59),
(2, 59), (17, -10), (32, -13), (42, -9), (49, -5), (53, 0), (64, 3), (68, 10),
(66, 27), (47, 57), (-5, 71), (0, 24), (-1, 36), (-2, 42), (-2, 52), (-9, 57),
(-6, 63), (-4, 65), (-4, 67), (-7, 82), (-3, 81), (-3, 76), (-7, 72), (-6, 78),
(-12, 72), (-14, 68), (-3, 70), (-6, 76), (-5, 66), (-5, 62), (0, 57), (-4, 61),
(-9, 60), (1, 54), (2, 58), (17, -10), (32, -13), (42, -9), (49, -5), (53, 0),
(64, 3), (68, 10), (66, 27), (47, 57), (0, 80), (-5, 89), (-7, 94), (-4, 92),
(0, 39), (0, 65), (-15, 84), (-35, 127), (-2, 73), (-12, 104), (-9, 91), (-31, 127),
(0, 80), (-5, 89), (-7, 94), (-4, 92), (0, 39), (0, 65), (-15, 84), (-35, 127),
(-2, 73), (-12, 104), (-9, 91), (-31, 127), (-13, 103), (-13, 91), (-9, 89), (-14, 92),
(-8, 76), (-12, 87), (-23, 110), (-24, 105), (-10, 78), (-20, 112), (-17, 99), (-78, 127),
(-70, 127), (-50, 127), (-46, 127), (-4, 66), (-5, 78), (-4, 71), (-8, 72), (2, 59),
(-1, 55), (-7, 70), (-6, 75), (-8, 89), (-34, 119), (-3, 75), (32, 20), (30, 22),
(-44, 127), (0, 54), (-5, 61), (0, 58), (-1, 60), (-3, 61), (-8, 67), (-25, 84),
(-14, 74), (-5, 65), (5, 52), (2, 57), (0, 61), (-9, 69), (-11, 70), (18, 55),
(-13, 103), (-13, 91), (-9, 89), (-14, 92), (-8, 76), (-12, 87), (-23, 110), (-24, 105),
(-10, 78), (-20, 112), (-17, 99), (-78, 127), (-70, 127), (-50, 127), (-46, 127), (-4, 66),
(-5, 78), (-4, 71), (-8, 72), (2, 59), (-1, 55), (-7, 70), (-6, 75), (-8, 89),
(-34, 119), (-3, 75), (32, 20), (30, 22), (-44, 127), (0, 54), (-5, 61), (0, 58),
(-1, 60), (-3, 61), (-8, 67), (-25, 84), (-14, 74), (-5, 65), (5, 52), (2, 57),
(0, 61), (-9, 69), (-11, 70), (18, 55), (4, 45), (10, 28), (10, 31), (33, -11),
(52, -43), (18, 15), (28, 0), (35, -22), (38, -25), (34, 0), (39, -18), (32, -12),
(102, -94), (0, 0), (56, -15), (33, -4), (29, 10), (37, -5), (51, -29), (39, -9),
(52, -34), (69, -58), (67, -63), (44, -5), (32, 7), (55, -29), (32, 1), (0, 0),
(27, 36), (33, -25), (34, -30), (36, -28), (38, -28), (38, -27), (34, -18), (35, -16),
(34, -14), (32, -8), (37, -6), (35, 0), (30, 10), (28, 18), (26, 25), (29, 41),
(4, 45), (10, 28), (10, 31), (33, -11), (52, -43), (18, 15), (28, 0), (35, -22),
(38, -25), (34, 0), (39, -18), (32, -12), (102, -94), (0, 0), (56, -15), (33, -4),
(29, 10), (37, -5), (51, -29), (39, -9), (52, -34), (69, -58), (67, -63), (44, -5),
(32, 7), (55, -29), (32, 1), (0, 0), (27, 36), (33, -25), (34, -30), (36, -28),
(38, -28), (38, -27), (34, -18), (35, -16), (34, -14), (32, -8), (37, -6), (35, 0),
(30, 10), (28, 18), (26, 25), (29, 41), (-5, 85), (-6, 81), (-10, 77), (-7, 81),
(-17, 80), (-18, 73), (-4, 74), (-10, 83), (-9, 71), (-9, 67), (-1, 61), (-8, 66),
(-14, 66), (0, 59), (2, 59), (-3, 81), (-3, 76), (-7, 72), (-6, 78), (-12, 72),
(-14, 68), (-3, 70), (-6, 76), (-5, 66), (-5, 62), (0, 57), (-4, 61), (-9, 60),
(1, 54), (2, 58), (17, -10), (32, -13), (42, -9), (49, -5), (53, 0), (64, 3),
(68, 10), (66, 27), (47, 57), (17, -10), (32, -13), (42, -9), (49, -5), (53, 0),
(64, 3), (68, 10), (66, 27), (47, 57), (-5, 71), (0, 24), (-1, 36), (-2, 42),
(-2, 52), (-9, 57), (-6, 63), (-4, 65), (-4, 67), (-7, 82), (-5, 85), (-6, 81),
(-10, 77), (-7, 81), (-17, 80), (-18, 73), (-4, 74), (-10, 83), (-9, 71), (-9, 67),
(-1, 61), (-8, 66), (-14, 66), (0, 59), (2, 59), (-3, 81), (-3, 76), (-7, 72),
(-6, 78), (-12, 72), (-14, 68), (-3, 70), (-6, 76), (-5, 66), (-5, 62), (0, 57),
(-4, 61), (-9, 60), (1, 54), (2, 58), (17, -10), (32, -13), (42, -9), (49, -5),
(53, 0), (64, 3), (68, 10), (66, 27), (47, 57), (17, -10), (32, -13), (42, -9),
(49, -5), (53, 0), (64, 3), (68, 10), (66, 27), (47, 57), (-5, 71), (0, 24),
(-1, 36), (-2, 42), (-2, 52), (-9, 57), (-6, 63), (-4, 65), (-4, 67), (-7, 82),
(-21, 126), (-23, 124), (-20, 110), (-26, 126), (-25, 124), (-17, 105), (-27, 121), (-27, 117),
(-17, 102), (-26, 117), (-27, 116), (-33, 122), (-10, 95), (-14, 100), (-8, 95), (-17, 111),
(-28, 114), (-6, 89), (-2, 80), (-4, 82), (-9, 85), (-8, 81), (-1, 72), (5, 64),
(1, 67), (9, 56), (0, 69), (1, 69), (7, 69), (-7, 69), (-6, 67), (-16, 77),
(-2, 64), (2, 61), (-6, 67), (-3, 64), (2, 57), (-3, 65), (-3, 66), (0, 62),
(9, 51), (-1, 66), (-2, 71), (-2, 75), (-21, 126), (-23, 124), (-20, 110), (-26, 126),
(-25, 124), (-17, 105), (-27, 121), (-27, 117), (-17, 102), (-26, 117), (-27, 116), (-33, 122),
(-10, 95), (-14, 100), (-8, 95), (-17, 111), (-28, 114), (-6, 89), (-2, 80), (-4, 82),
(-9, 85), (-8, 81), (-1, 72), (5, 64), (1, 67), (9, 56), (0, 69), (1, 69),
(7, 69), (-7, 69), (-6, 67), (-16, 77), (-2, 64), (2, 61), (-6, 67), (-3, 64),
(2, 57), (-3, 65), (-3, 66), (0, 62), (9, 51), (-1, 66), (-2, 71), (-2, 75),
(19, -6), (18, -6), (14, 0), (26, -12), (31, -16), (33, -25), (33, -22), (37, -28),
(39, -30), (42, -30), (47, -42), (45, -36), (49, -34), (41, -17), (32, 9), (69, -71),
(63, -63), (66, -64), (77, -74), (54, -39), (52, -35), (41, -10), (36, 0), (40, -1),
(30, 14), (28, 26), (23, 37), (12, 55), (11, 65), (37, -33), (39, -36), (40, -37),
(38, -30), (46, -33), (42, -30), (40, -24), (49, -29), (38, -12), (40, -10), (38, -3),
(46, -5), (31, 20), (29, 30), (25, 44), (19, -6), (18, -6), (14, 0), (26, -12),
(31, -16), (33, -25), (33, -22), (37, -28), (39, -30), (42, -30), (47, -42), (45, -36),
(49, -34), (41, -17), (32, 9), (69, -71), (63, -63), (66, -64), (77, -74), (54, -39),
(52, -35), (41, -10), (36, 0), (40, -1), (30, 14), (28, 26), (23, 37), (12, 55),
(11, 65), (37, -33), (39, -36), (40, -37), (38, -30), (46, -33), (42, -30), (40, -24),
(49, -29), (38, -12), (40, -10), (38, -3), (46, -5), (31, 20), (29, 30), (25, 44),
(-23, 112), (-15, 71), (-7, 61), (0, 53), (-5, 66), (-11, 77), (-9, 80), (-9, 84),
(-10, 87), (-34, 127), (-21, 101), (-3, 39), (-5, 53), (-7, 61), (-11, 75), (-15, 77),
(-17, 91), (-25, 107), (-25, 111), (-28, 122), (-11, 76), (-10, 44), (-10, 52), (-10, 57),
(-9, 58), (-16, 72), (-7, 69), (-4, 69), (-5, 74), (-9, 86), (-23, 112), (-15, 71),
(-7, 61), (0, 53), (-5, 66), (-11, 77), (-9, 80), (-9, 84), (-10, 87), (-34, 127),
(-21, 101), (-3, 39), (-5, 53), (-7, 61), (-11, 75), (-15, 77), (-17, 91), (-25, 107),
(-25, 111), (-28, 122), (-11, 76), (-10, 44), (-10, 52), (-10, 57), (-9, 58), (-16, 72),
(-7, 69), (-4, 69), (-5, 74), (-9, 86), (-2, 73), (-12, 104), (-9, 91), (-31, 127),
(-2, 73), (-12, 104), (-9, 91), (-31, 127), (-2, 73), (-12, 104), (-9, 91), (-31, 127),
],
[
(20, -15), (2, 54), (3, 74), (20, -15), (2, 54), (3, 74), (-28, 127), (-23, 104),
(-6, 53), (-1, 54), (7, 51), (29, 16), (25, 0), (14, 0), (-10, 51), (-3, 62),
(-27, 99), (26, 16), (-4, 85), (-24, 102), (5, 57), (6, 57), (-17, 73), (14, 57),
(20, 40), (20, 10), (29, 0), (54, 0), (37, 42), (12, 97), (-32, 127), (-22, 117),
(-2, 74), (-4, 85), (-24, 102), (5, 57), (-6, 93), (-14, 88), (-6, 44), (4, 55),
(-11, 89), (-15, 103), (-21, 116), (19, 57), (20, 58), (4, 84), (6, 96), (1, 63),
(-5, 85), (-13, 106), (5, 63), (6, 75), (-3, 90), (-1, 101), (3, 55), (-4, 79),
(-2, 75), (-12, 97), (-7, 50), (1, 60), (0, 41), (0, 63), (0, 63), (0, 63),
(-9, 83), (4, 86), (0, 97), (-7, 72), (13, 41), (3, 62), (7, 34), (-9, 88),
(-20, 127), (-36, 127), (-17, 91), (-14, 95), (-25, 84), (-25, 86), (-12, 89), (-17, 91),
(-31, 127), (-14, 76), (-18, 103), (-13, 90), (-37, 127), (11, 80), (5, 76), (2, 84),
(5, 78), (-6, 55), (4, 61), (-14, 83), (-37, 127), (-5, 79), (-11, 104), (-11, 91),
(-30, 127), (0, 65), (-2, 79), (0, 72), (-4, 92), (-6, 56), (3, 68), (-8, 71),
(-13, 98), (-4, 86), (-12, 88), (-5, 82), (-3, 72), (-4, 67), (-8, 72), (-16, 89),
(-9, 69), (-1, 59), (5, 66), (4, 57), (-4, 71), (-2, 71), (2, 58), (-1, 74),
(-4, 44), (-1, 69), (0, 62), (-7, 51), (-4, 47), (-6, 42), (-3, 41), (-6, 53),
(8, 76), (-9, 78), (-11, 83), (9, 52), (0, 67), (-5, 90), (1, 67), (-15, 72),
(-5, 75), (-8, 80), (-21, 83), (-21, 64), (-13, 31), (-25, 64), (-29, 94), (9, 75),
(17, 63), (-8, 74), (-5, 35), (-2, 27), (13, 91), (3, 65), (-7, 69), (8, 77),
(-10, 66), (3, 62), (-3, 68), (-20, 81), (0, 30), (1, 7), (-3, 23), (-21, 74),
(16, 66), (-23, 124), (17, 37), (44, -18), (50, -34), (-22, 127), (4, 39), (0, 42),
(7, 34), (11, 29), (8, 31), (6, 37), (7, 42), (3, 40), (8, 33), (13, 43),
(13, 36), (4, 47), (3, 55), (2, 58), (6, 60), (8, 44), (11, 44), (14, 42),
(7, 48), (4, 56), (4, 52), (13, 37), (9, 49), (19, 58), (10, 48), (12, 45),
(0, 69), (20, 33), (8, 63), (35, -18), (33, -25), (28, -3), (24, 10), (27, 0),
(34, -14), (52, -44), (39, -24), (19, 17), (31, 25), (36, 29), (24, 33), (34, 15),
(30, 20), (22, 73), (20, 34), (19, 31), (27, 44), (19, 16), (15, 36), (15, 36),
(21, 28), (25, 21), (30, 20), (31, 12), (27, 16), (24, 42), (0, 93), (14, 56),
(15, 57), (26, 38), (-24, 127), (-24, 115), (-22, 82), (-9, 62), (0, 53), (0, 59),
(-14, 85), (-13, 89), (-13, 94), (-11, 92), (-29, 127), (-21, 100), (-14, 57), (-12, 67),
(-11, 71), (-10, 77), (-21, 85), (-16, 88), (-23, 104), (-15, 98), (-37, 127), (-10, 82),
(-8, 48), (-8, 61), (-8, 66), (-7, 70), (-14, 75), (-10, 79), (-9, 83), (-12, 92),
(-18, 108), (-4, 79), (-22, 69), (-16, 75), (-2, 58), (1, 58), (-13, 78), (-9, 83),
(-4, 81), (-13, 99), (-13, 81), (-6, 38), (-13, 62), (-6, 58), (-2, 59), (-16, 73),
(-10, 76), (-13, 86), (-9, 83), (-10, 87), (0, 0), (-22, 127), (-25, 127), (-25, 120),
(-27, 127), (-19, 114), (-23, 117), (-25, 118), (-26, 117), (-24, 113), (-28, 118), (-31, 120),
(-37, 124), (-10, 94), (-15, 102), (-10, 99), (-13, 106), (-50, 127), (-5, 92), (17, 57),
(-5, 86), (-13, 94), (-12, 91), (-2, 77), (0, 71), (-1, 73), (4, 64), (-7, 81),
(5, 64), (15, 57), (1, 67), (0, 68), (-10, 67), (1, 68), (0, 77), (2, 64),
(0, 68), (-5, 78), (7, 55), (5, 59), (2, 65), (14, 54), (15, 44), (5, 60),
(2, 70), (-2, 76), (-18, 86), (12, 70), (5, 64), (-12, 70), (11, 55), (5, 56),
(0, 69), (2, 65), (-6, 74), (5, 54), (7, 54), (-6, 76), (-11, 82), (-2, 77),
(-2, 77), (25, 42), (17, -13), (16, -9), (17, -12), (27, -21), (37, -30), (41, -40),
(42, -41), (48, -47), (39, -32), (46, -40), (52, -51), (46, -41), (52, -39), (43, -19),
(32, 11), (61, -55), (56, -46), (62, -50), (81, -67), (45, -20), (35, -2), (28, 15),
(34, 1), (39, 1), (30, 17), (20, 38), (18, 45), (15, 54), (0, 79), (36, -16),
(37, -14), (37, -17), (32, 1), (34, 15), (29, 15), (24, 25), (34, 22), (31, 16),
(35, 18), (31, 28), (33, 41), (36, 28), (27, 47), (21, 62), (18, 31), (19, 26),
(36, 24), (24, 23), (27, 16), (24, 30), (31, 29), (22, 41), (22, 42), (16, 60),
(15, 52), (14, 60), (3, 78), (-16, 123), (21, 53), (22, 56), (25, 61), (21, 33),
(19, 50), (17, 61), (-3, 78), (-8, 74), (-9, 72), (-10, 72), (-18, 75), (-12, 71),
(-11, 63), (-5, 70), (-17, 75), (-14, 72), (-16, 67), (-8, 53), (-14, 59), (-9, 52),
(-11, 68), (9, -2), (30, -10), (31, -4), (33, -1), (33, 7), (31, 12), (37, 23),
(31, 38), (20, 64), (-9, 71), (-7, 37), (-8, 44), (-11, 49), (-10, 56), (-12, 59),
(-8, 63), (-9, 67), (-6, 68), (-10, 79), (-3, 78), (-8, 74), (-9, 72), (-10, 72),
(-18, 75), (-12, 71), (-11, 63), (-5, 70), (-17, 75), (-14, 72), (-16, 67), (-8, 53),
(-14, 59), (-9, 52), (-11, 68), (9, -2), (30, -10), (31, -4), (33, -1), (33, 7),
(31, 12), (37, 23), (31, 38), (20, 64), (11, 80), (5, 76), (2, 84), (5, 78),
(-6, 55), (4, 61), (-14, 83), (-37, 127), (-5, 79), (-11, 104), (-11, 91), (-30, 127),
(11, 80), (5, 76), (2, 84), (5, 78), (-6, 55), (4, 61), (-14, 83), (-37, 127),
(-5, 79), (-11, 104), (-11, 91), (-30, 127), (-4, 86), (-12, 88), (-5, 82), (-3, 72),
(-4, 67), (-8, 72), (-16, 89), (-9, 69), (-1, 59), (5, 66), (4, 57), (-4, 71),
(-2, 71), (2, 58), (-1, 74), (-4, 44), (-1, 69), (0, 62), (-7, 51), (-4, 47),
(-6, 42), (-3, 41), (-6, 53), (8, 76), (-9, 78), (-11, 83), (9, 52), (0, 67),
(-5, 90), (1, 67), (-15, 72), (-5, 75), (-8, 80), (-21, 83), (-21, 64), (-13, 31),
(-25, 64), (-29, 94), (9, 75), (17, 63), (-8, 74), (-5, 35), (-2, 27), (13, 91),
(-4, 86), (-12, 88), (-5, 82), (-3, 72), (-4, 67), (-8, 72), (-16, 89), (-9, 69),
(-1, 59), (5, 66), (4, 57), (-4, 71), (-2, 71), (2, 58), (-1, 74), (-4, 44),
(-1, 69), (0, 62), (-7, 51), (-4, 47), (-6, 42), (-3, 41), (-6, 53), (8, 76),
(-9, 78), (-11, 83), (9, 52), (0, 67), (-5, 90), (1, 67), (-15, 72), (-5, 75),
(-8, 80), (-21, 83), (-21, 64), (-13, 31), (-25, 64), (-29, 94), (9, 75), (17, 63),
(-8, 74), (-5, 35), (-2, 27), (13, 91), (4, 39), (0, 42), (7, 34), (11, 29),
(8, 31), (6, 37), (7, 42), (3, 40), (8, 33), (13, 43), (13, 36), (4, 47),
(3, 55), (2, 58), (6, 60), (8, 44), (11, 44), (14, 42), (7, 48), (4, 56),
(4, 52), (13, 37), (9, 49), (19, 58), (10, 48), (12, 45), (0, 69), (20, 33),
(8, 63), (35, -18), (33, -25), (28, -3), (24, 10), (27, 0), (34, -14), (52, -44),
(39, -24), (19, 17), (31, 25), (36, 29), (24, 33), (34, 15), (30, 20), (22, 73),
(4, 39), (0, 42), (7, 34), (11, 29), (8, 31), (6, 37), (7, 42), (3, 40),
(8, 33), (13, 43), (13, 36), (4, 47), (3, 55), (2, 58), (6, 60), (8, 44),
(11, 44), (14, 42), (7, 48), (4, 56), (4, 52), (13, 37), (9, 49), (19, 58),
(10, 48), (12, 45), (0, 69), (20, 33), (8, 63), (35, -18), (33, -25), (28, -3),
(24, 10), (27, 0), (34, -14), (52, -44), (39, -24), (19, 17), (31, 25), (36, 29),
(24, 33), (34, 15), (30, 20), (22, 73), (-3, 78), (-8, 74), (-9, 72), (-10, 72),
(-18, 75), (-12, 71), (-11, 63), (-5, 70), (-17, 75), (-14, 72), (-16, 67), (-8, 53),
(-14, 59), (-9, 52), (-11, 68), (-3, 78), (-8, 74), (-9, 72), (-10, 72), (-18, 75),
(-12, 71), (-11, 63), (-5, 70), (-17, 75), (-14, 72), (-16, 67), (-8, 53), (-14, 59),
(-9, 52), (-11, 68), (9, -2), (30, -10), (31, -4), (33, -1), (33, 7), (31, 12),
(37, 23), (31, 38), (20, 64), (9, -2), (30, -10), (31, -4), (33, -1), (33, 7),
(31, 12), (37, 23), (31, 38), (20, 64), (-9, 71), (-7, 37), (-8, 44), (-11, 49),
(-10, 56), (-12, 59), (-8, 63), (-9, 67), (-6, 68), (-10, 79), (-3, 78), (-8, 74),
(-9, 72), (-10, 72), (-18, 75), (-12, 71), (-11, 63), (-5, 70), (-17, 75), (-14, 72),
(-16, 67), (-8, 53), (-14, 59), (-9, 52), (-11, 68), (-3, 78), (-8, 74), (-9, 72),
(-10, 72), (-18, 75), (-12, 71), (-11, 63), (-5, 70), (-17, 75), (-14, 72), (-16, 67),
(-8, 53), (-14, 59), (-9, 52), (-11, 68), (9, -2), (30, -10), (31, -4), (33, -1),
(33, 7), (31, 12), (37, 23), (31, 38), (20, 64), (9, -2), (30, -10), (31, -4),
(33, -1), (33, 7), (31, 12), (37, 23), (31, 38), (20, 64), (-9, 71), (-7, 37),
(-8, 44), (-11, 49), (-10, 56), (-12, 59), (-8, 63), (-9, 67), (-6, 68), (-10, 79),
(-22, 127), (-25, 127), (-25, 120), (-27, 127), (-19, 114), (-23, 117), (-25, 118), (-26, 117),
(-24, 113), (-28, 118), (-31, 120), (-37, 124), (-10, 94), (-15, 102), (-10, 99), (-13, 106),
(-50, 127), (-5, 92), (17, 57), (-5, 86), (-13, 94), (-12, 91), (-2, 77), (0, 71),
(-1, 73), (4, 64), (-7, 81), (5, 64), (15, 57), (1, 67), (0, 68), (-10, 67),
(1, 68), (0, 77), (2, 64), (0, 68), (-5, 78), (7, 55), (5, 59), (2, 65),
(14, 54), (15, 44), (5, 60), (2, 70), (-22, 127), (-25, 127), (-25, 120), (-27, 127),
(-19, 114), (-23, 117), (-25, 118), (-26, 117), (-24, 113), (-28, 118), (-31, 120), (-37, 124),
(-10, 94), (-15, 102), (-10, 99), (-13, 106), (-50, 127), (-5, 92), (17, 57), (-5, 86),
(-13, 94), (-12, 91), (-2, 77), (0, 71), (-1, 73), (4, 64), (-7, 81), (5, 64),
(15, 57), (1, 67), (0, 68), (-10, 67), (1, 68), (0, 77), (2, 64), (0, 68),
(-5, 78), (7, 55), (5, 59), (2, 65), (14, 54), (15, 44), (5, 60), (2, 70),
(17, -13), (16, -9), (17, -12), (27, -21), (37, -30), (41, -40), (42, -41), (48, -47),
(39, -32), (46, -40), (52, -51), (46, -41), (52, -39), (43, -19), (32, 11), (61, -55),
(56, -46), (62, -50), (81, -67), (45, -20), (35, -2), (28, 15), (34, 1), (39, 1),
(30, 17), (20, 38), (18, 45), (15, 54), (0, 79), (36, -16), (37, -14), (37, -17),
(32, 1), (34, 15), (29, 15), (24, 25), (34, 22), (31, 16), (35, 18), (31, 28),
(33, 41), (36, 28), (27, 47), (21, 62), (17, -13), (16, -9), (17, -12), (27, -21),
(37, -30), (41, -40), (42, -41), (48, -47), (39, -32), (46, -40), (52, -51), (46, -41),
(52, -39), (43, -19), (32, 11), (61, -55), (56, -46), (62, -50), (81, -67), (45, -20),
(35, -2), (28, 15), (34, 1), (39, 1), (30, 17), (20, 38), (18, 45), (15, 54),
(0, 79), (36, -16), (37, -14), (37, -17), (32, 1), (34, 15), (29, 15), (24, 25),
(34, 22), (31, 16), (35, 18), (31, 28), (33, 41), (36, 28), (27, 47), (21, 62),
(-24, 115), (-22, 82), (-9, 62), (0, 53), (0, 59), (-14, 85), (-13, 89), (-13, 94),
(-11, 92), (-29, 127), (-21, 100), (-14, 57), (-12, 67), (-11, 71), (-10, 77), (-21, 85),
(-16, 88), (-23, 104), (-15, 98), (-37, 127), (-10, 82), (-8, 48), (-8, 61), (-8, 66),
(-7, 70), (-14, 75), (-10, 79), (-9, 83), (-12, 92), (-18, 108), (-24, 115), (-22, 82),
(-9, 62), (0, 53), (0, 59), (-14, 85), (-13, 89), (-13, 94), (-11, 92), (-29, 127),
(-21, 100), (-14, 57), (-12, 67), (-11, 71), (-10, 77), (-21, 85), (-16, 88), (-23, 104),
(-15, 98), (-37, 127), (-10, 82), (-8, 48), (-8, 61), (-8, 66), (-7, 70), (-14, 75),
(-10, 79), (-9, 83), (-12, 92), (-18, 108), (-5, 79), (-11, 104), (-11, 91), (-30, 127),
(-5, 79), (-11, 104), (-11, 91), (-30, 127), (-5, 79), (-11, 104), (-11, 91), (-30, 127),
],
[
(20, -15), (2, 54), (3, 74), (20, -15), (2, 54), (3, 74), (-28, 127), (-23, 104),
(-6, 53), (-1, 54), (7, 51), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0),
(0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0),
(0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0),
(0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0),
(0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0),
(0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0),
(0, 0), (0, 0), (0, 0), (0, 0), (0, 41), (0, 63), (0, 63), (0, 63),
(-9, 83), (4, 86), (0, 97), (-7, 72), (13, 41), (3, 62), (0, 11), (1, 55),
(0, 69), (-17, 127), (-13, 102), (0, 82), (-7, 74), (-21, 107), (-27, 127), (-31, 127),
(-24, 127), (-18, 95), (-27, 127), (-21, 114), (-30, 127), (-17, 123), (-12, 115), (-16, 122),
(-11, 115), (-12, 63), (-2, 68), (-15, 84), (-13, 104), (-3, 70), (-8, 93), (-10, 90),
(-30, 127), (-1, 74), (-6, 97), (-7, 91), (-20, 127), (-4, 56), (-5, 82), (-7, 76),
(-22, 125), (-7, 93), (-11, 87), (-3, 77), (-5, 71), (-4, 63), (-4, 68), (-12, 84),
(-7, 62), (-7, 65), (8, 61), (5, 56), (-2, 66), (1, 64), (0, 61), (-2, 78),
(1, 50), (7, 52), (10, 35), (0, 44), (11, 38), (1, 45), (0, 46), (5, 44),
(31, 17), (1, 51), (7, 50), (28, 19), (16, 33), (14, 62), (-13, 108), (-15, 100),
(-13, 101), (-13, 91), (-12, 94), (-10, 88), (-16, 84), (-10, 86), (-7, 83), (-13, 87),
(-19, 94), (1, 70), (0, 72), (-5, 74), (18, 59), (-8, 102), (-15, 100), (0, 95),
(-4, 75), (2, 72), (-11, 75), (-3, 71), (15, 46), (-13, 69), (0, 62), (0, 65),
(21, 37), (-15, 72), (9, 57), (16, 54), (0, 62), (12, 72), (24, 0), (15, 9),
(8, 25), (13, 18), (15, 9), (13, 19), (10, 37), (12, 18), (6, 29), (20, 33),
(15, 30), (4, 45), (1, 58), (0, 62), (7, 61), (12, 38), (11, 45), (15, 39),
(11, 42), (13, 44), (16, 45), (12, 41), (10, 49), (30, 34), (18, 42), (10, 55),
(17, 51), (17, 46), (0, 89), (26, -19), (22, -17), (26, -17), (30, -25), (28, -20),
(33, -23), (37, -27), (33, -23), (40, -28), (38, -17), (33, -11), (40, -15), (41, -6),
(38, 1), (41, 17), (30, -6), (27, 3), (26, 22), (37, -16), (35, -4), (38, -8),
(38, -3), (37, 3), (38, 5), (42, 0), (35, 16), (39, 22), (14, 48), (27, 37),
(21, 60), (12, 68), (2, 97), (-3, 71), (-6, 42), (-5, 50), (-3, 54), (-2, 62),
(0, 58), (1, 63), (-2, 72), (-1, 74), (-9, 91), (-5, 67), (-5, 27), (-3, 39),
(-2, 44), (0, 46), (-16, 64), (-8, 68), (-10, 78), (-6, 77), (-10, 86), (-12, 92),
(-15, 55), (-10, 60), (-6, 62), (-4, 65), (-12, 73), (-8, 76), (-7, 80), (-9, 88),
(-17, 110), (-11, 97), (-20, 84), (-11, 79), (-6, 73), (-4, 74), (-13, 86), (-13, 96),
(-11, 97), (-19, 117), (-8, 78), (-5, 33), (-4, 48), (-2, 53), (-3, 62), (-13, 71),
(-10, 79), (-12, 86), (-13, 90), (-14, 97), (0, 0), (-6, 93), (-6, 84), (-8, 79),
(0, 66), (-1, 71), (0, 62), (-2, 60), (-2, 59), (-5, 75), (-3, 62), (-4, 58),
(-9, 66), (-1, 79), (0, 71), (3, 68), (10, 44), (-7, 62), (15, 36), (14, 40),
(16, 27), (12, 29), (1, 44), (20, 36), (18, 32), (5, 42), (1, 48), (10, 62),
(17, 46), (9, 64), (-12, 104), (-11, 97), (-16, 96), (-7, 88), (-8, 85), (-7, 85),
(-9, 85), (-13, 88), (4, 66), (-3, 77), (-3, 76), (-6, 76), (10, 58), (-1, 76),
(-1, 83), (-7, 99), (-14, 95), (2, 95), (0, 76), (-5, 74), (0, 70), (-11, 75),
(1, 68), (0, 65), (-14, 73), (3, 62), (4, 62), (-1, 68), (-13, 75), (11, 55),
(5, 64), (12, 70), (15, 6), (6, 19), (7, 16), (12, 14), (18, 13), (13, 11),
(13, 15), (15, 16), (12, 23), (13, 23), (15, 20), (14, 26), (14, 44), (17, 40),
(17, 47), (24, 17), (21, 21), (25, 22), (31, 27), (22, 29), (19, 35), (14, 50),
(10, 57), (7, 63), (-2, 77), (-4, 82), (-3, 94), (9, 69), (-12, 109), (36, -35),
(36, -34), (32, -26), (37, -30), (44, -32), (34, -18), (34, -15), (40, -15), (33, -7),
(35, -5), (33, 0), (38, 2), (33, 13), (23, 35), (13, 58), (29, -3), (26, 0),
(22, 30), (31, -7), (35, -15), (34, -3), (34, 3), (36, -1), (34, 5), (32, 11),
(35, 5), (34, 12), (39, 11), (30, 29), (34, 26), (29, 39), (19, 66), (31, 21),
(31, 31), (25, 50), (-17, 120), (-20, 112), (-18, 114), (-11, 85), (-15, 92), (-14, 89),
(-26, 71), (-15, 81), (-14, 80), (0, 68), (-14, 70), (-24, 56), (-23, 68), (-24, 50),
(-11, 74), (23, -13), (26, -13), (40, -15), (49, -14), (44, 3), (45, 6), (44, 34),
(33, 54), (19, 82), (-3, 75), (-1, 23), (1, 34), (1, 43), (0, 54), (-2, 55),
(0, 61), (1, 64), (0, 68), (-9, 92), (-14, 106), (-13, 97), (-15, 90), (-12, 90),
(-18, 88), (-10, 73), (-9, 79), (-14, 86), (-10, 73), (-10, 70), (-10, 69), (-5, 66),
(-9, 64), (-5, 58), (2, 59), (21, -10), (24, -11), (28, -8), (28, -1), (29, 3),
(29, 9), (35, 20), (29, 36), (14, 67), (-17, 123), (-12, 115), (-16, 122), (-11, 115),
(-12, 63), (-2, 68), (-15, 84), (-13, 104), (-3, 70), (-8, 93), (-10, 90), (-30, 127),
(-17, 123), (-12, 115), (-16, 122), (-11, 115), (-12, 63), (-2, 68), (-15, 84), (-13, 104),
(-3, 70), (-8, 93), (-10, 90), (-30, 127), (-7, 93), (-11, 87), (-3, 77), (-5, 71),
(-4, 63), (-4, 68), (-12, 84), (-7, 62), (-7, 65), (8, 61), (5, 56), (-2, 66),
(1, 64), (0, 61), (-2, 78), (1, 50), (7, 52), (10, 35), (0, 44), (11, 38),
(1, 45), (0, 46), (5, 44), (31, 17), (1, 51), (7, 50), (28, 19), (16, 33),
(14, 62), (-13, 108), (-15, 100), (-13, 101), (-13, 91), (-12, 94), (-10, 88), (-16, 84),
(-10, 86), (-7, 83), (-13, 87), (-19, 94), (1, 70), (0, 72), (-5, 74), (18, 59),
(-7, 93), (-11, 87), (-3, 77), (-5, 71), (-4, 63), (-4, 68), (-12, 84), (-7, 62),
(-7, 65), (8, 61), (5, 56), (-2, 66), (1, 64), (0, 61), (-2, 78), (1, 50),
(7, 52), (10, 35), (0, 44), (11, 38), (1, 45), (0, 46), (5, 44), (31, 17),
(1, 51), (7, 50), (28, 19), (16, 33), (14, 62), (-13, 108), (-15, 100), (-13, 101),
(-13, 91), (-12, 94), (-10, 88), (-16, 84), (-10, 86), (-7, 83), (-13, 87), (-19, 94),
(1, 70), (0, 72), (-5, 74), (18, 59), (24, 0), (15, 9), (8, 25), (13, 18),
(15, 9), (13, 19), (10, 37), (12, 18), (6, 29), (20, 33), (15, 30), (4, 45),
(1, 58), (0, 62), (7, 61), (12, 38), (11, 45), (15, 39), (11, 42), (13, 44),
(16, 45), (12, 41), (10, 49), (30, 34), (18, 42), (10, 55), (17, 51), (17, 46),
(0, 89), (26, -19), (22, -17), (26, -17), (30, -25), (28, -20), (33, -23), (37, -27),
(33, -23), (40, -28), (38, -17), (33, -11), (40, -15), (41, -6), (38, 1), (41, 17),
(24, 0), (15, 9), (8, 25), (13, 18), (15, 9), (13, 19), (10, 37), (12, 18),
(6, 29), (20, 33), (15, 30), (4, 45), (1, 58), (0, 62), (7, 61), (12, 38),
(11, 45), (15, 39), (11, 42), (13, 44), (16, 45), (12, 41), (10, 49), (30, 34),
(18, 42), (10, 55), (17, 51), (17, 46), (0, 89), (26, -19), (22, -17), (26, -17),
(30, -25), (28, -20), (33, -23), (37, -27), (33, -23), (40, -28), (38, -17), (33, -11),
(40, -15), (41, -6), (38, 1), (41, 17), (-17, 120), (-20, 112), (-18, 114), (-11, 85),
(-15, 92), (-14, 89), (-26, 71), (-15, 81), (-14, 80), (0, 68), (-14, 70), (-24, 56),
(-23, 68), (-24, 50), (-11, 74), (-14, 106), (-13, 97), (-15, 90), (-12, 90), (-18, 88),
(-10, 73), (-9, 79), (-14, 86), (-10, 73), (-10, 70), (-10, 69), (-5, 66), (-9, 64),
(-5, 58), (2, 59), (23, -13), (26, -13), (40, -15), (49, -14), (44, 3), (45, 6),
(44, 34), (33, 54), (19, 82), (21, -10), (24, -11), (28, -8), (28, -1), (29, 3),
(29, 9), (35, 20), (29, 36), (14, 67), (-3, 75), (-1, 23), (1, 34), (1, 43),
(0, 54), (-2, 55), (0, 61), (1, 64), (0, 68), (-9, 92), (-17, 120), (-20, 112),
(-18, 114), (-11, 85), (-15, 92), (-14, 89), (-26, 71), (-15, 81), (-14, 80), (0, 68),
(-14, 70), (-24, 56), (-23, 68), (-24, 50), (-11, 74), (-14, 106), (-13, 97), (-15, 90),
(-12, 90), (-18, 88), (-10, 73), (-9, 79), (-14, 86), (-10, 73), (-10, 70), (-10, 69),
(-5, 66), (-9, 64), (-5, 58), (2, 59), (23, -13), (26, -13), (40, -15), (49, -14),
(44, 3), (45, 6), (44, 34), (33, 54), (19, 82), (21, -10), (24, -11), (28, -8),
(28, -1), (29, 3), (29, 9), (35, 20), (29, 36), (14, 67), (-3, 75), (-1, 23),
(1, 34), (1, 43), (0, 54), (-2, 55), (0, 61), (1, 64), (0, 68), (-9, 92),
(-6, 93), (-6, 84), (-8, 79), (0, 66), (-1, 71), (0, 62), (-2, 60), (-2, 59),
(-5, 75), (-3, 62), (-4, 58), (-9, 66), (-1, 79), (0, 71), (3, 68), (10, 44),
(-7, 62), (15, 36), (14, 40), (16, 27), (12, 29), (1, 44), (20, 36), (18, 32),
(5, 42), (1, 48), (10, 62), (17, 46), (9, 64), (-12, 104), (-11, 97), (-16, 96),
(-7, 88), (-8, 85), (-7, 85), (-9, 85), (-13, 88), (4, 66), (-3, 77), (-3, 76),
(-6, 76), (10, 58), (-1, 76), (-1, 83), (-6, 93), (-6, 84), (-8, 79), (0, 66),
(-1, 71), (0, 62), (-2, 60), (-2, 59), (-5, 75), (-3, 62), (-4, 58), (-9, 66),
(-1, 79), (0, 71), (3, 68), (10, 44), (-7, 62), (15, 36), (14, 40), (16, 27),
(12, 29), (1, 44), (20, 36), (18, 32), (5, 42), (1, 48), (10, 62), (17, 46),
(9, 64), (-12, 104), (-11, 97), (-16, 96), (-7, 88), (-8, 85), (-7, 85), (-9, 85),
(-13, 88), (4, 66), (-3, 77), (-3, 76), (-6, 76), (10, 58), (-1, 76), (-1, 83),
(15, 6), (6, 19), (7, 16), (12, 14), (18, 13), (13, 11), (13, 15), (15, 16),
(12, 23), (13, 23), (15, 20), (14, 26), (14, 44), (17, 40), (17, 47), (24, 17),
(21, 21), (25, 22), (31, 27), (22, 29), (19, 35), (14, 50), (10, 57), (7, 63),
(-2, 77), (-4, 82), (-3, 94), (9, 69), (-12, 109), (36, -35), (36, -34), (32, -26),
(37, -30), (44, -32), (34, -18), (34, -15), (40, -15), (33, -7), (35, -5), (33, 0),
(38, 2), (33, 13), (23, 35), (13, 58), (15, 6), (6, 19), (7, 16), (12, 14),
(18, 13), (13, 11), (13, 15), (15, 16), (12, 23), (13, 23), (15, 20), (14, 26),
(14, 44), (17, 40), (17, 47), (24, 17), (21, 21), (25, 22), (31, 27), (22, 29),
(19, 35), (14, 50), (10, 57), (7, 63), (-2, 77), (-4, 82), (-3, 94), (9, 69),
(-12, 109), (36, -35), (36, -34), (32, -26), (37, -30), (44, -32), (34, -18), (34, -15),
(40, -15), (33, -7), (35, -5), (33, 0), (38, 2), (33, 13), (23, 35), (13, 58),
(-3, 71), (-6, 42), (-5, 50), (-3, 54), (-2, 62), (0, 58), (1, 63), (-2, 72),
(-1, 74), (-9, 91), (-5, 67), (-5, 27), (-3, 39), (-2, 44), (0, 46), (-16, 64),
(-8, 68), (-10, 78), (-6, 77), (-10, 86), (-12, 92), (-15, 55), (-10, 60), (-6, 62),
(-4, 65), (-12, 73), (-8, 76), (-7, 80), (-9, 88), (-17, 110), (-3, 71), (-6, 42),
(-5, 50), (-3, 54), (-2, 62), (0, 58), (1, 63), (-2, 72), (-1, 74), (-9, 91),
(-5, 67), (-5, 27), (-3, 39), (-2, 44), (0, 46), (-16, 64), (-8, 68), (-10, 78),
(-6, 77), (-10, 86), (-12, 92), (-15, 55), (-10, 60), (-6, 62), (-4, 65), (-12, 73),
(-8, 76), (-7, 80), (-9, 88), (-17, 110), (-3, 70), (-8, 93), (-10, 90), (-30, 127),
(-3, 70), (-8, 93), (-10, 90), (-30, 127), (-3, 70), (-8, 93), (-10, 90), (-30, 127),
],
];

View File

@ -238,7 +238,7 @@ impl Decoder {
}
let mut sd = SliceDecoder::new(&sh, &pps, &sps, &mut cur.pic, &refs, &ls)?;
if pps.entropy_coding_mode {
return unsupported("CABAC entropy coding");
sd.decode_cabac(&rbsp)?;
} else {
let mut r = BitReader::new(&rbsp);
r.seek_bits(sh.header_bits);

View File

@ -18,6 +18,10 @@
// Index loops over fixed-size blocks read more clearly than iterator chains in codec code.
#![allow(clippy::needless_range_loop, clippy::too_many_arguments)]
mod cabac;
mod cabac_mb;
#[rustfmt::skip]
mod cabac_tables;
mod cavlc;
#[rustfmt::skip]
mod cavlc_tables;

View File

@ -76,12 +76,18 @@ pub struct MbState {
/// Motion vectors per 4x4 block (raster order).
pub mv: [[[i16; 2]; 16]; 2],
/// |mvd| per 4x4 block (raster), saturated, for CABAC context selection.
#[allow(dead_code)] // used by CABAC context selection
pub mvd: [[[u8; 2]; 16]; 2],
/// Bit per 8x8 block predicted in direct mode.
pub direct8x8: u8,
}
impl MbState {
#[inline]
pub fn kind_is_skip(&self) -> bool {
matches!(self.kind, MbKind::PSkip | MbKind::BSkip)
}
}
impl Default for MbState {
fn default() -> Self {
MbState {

View File

@ -30,4 +30,24 @@ fixture_tests!(
cavlc_weightp,
slices4_cavlc,
qp1_cavlc,
main_cabac_b,
high_720p,
high_1080p,
crop_1918x1078,
bpyramid,
weightp2,
weightb,
direct_temporal,
direct_spatial,
ref4,
no_deblock,
deblock_m2_2,
cqm_jvt,
slices4,
keyint10,
open_gop,
constrained_intra,
no8x8dct,
qp50,
qp1,
);