diff --git a/crates/h264/src/cabac.rs b/crates/h264/src/cabac.rs new file mode 100644 index 00000000..e9369650 --- /dev/null +++ b/crates/h264/src/cabac.rs @@ -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 { + 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, + ctx: Vec, + } + 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 { + // 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); + } +} diff --git a/crates/h264/src/cabac_mb.rs b/crates/h264/src/cabac_mb.rs new file mode 100644 index 00000000..201e5394 --- /dev/null +++ b/crates/h264/src/cabac_mb.rs @@ -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| 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| 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 { + 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| 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 { + 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, 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, 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 { + 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, 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| 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| { + 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 } + } +} diff --git a/crates/h264/src/cabac_tables.rs b/crates/h264/src/cabac_tables.rs new file mode 100644 index 00000000..c5c7205f --- /dev/null +++ b/crates/h264/src/cabac_tables.rs @@ -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), + ], +]; diff --git a/crates/h264/src/decoder.rs b/crates/h264/src/decoder.rs index 3b0f4bff..6e11824c 100644 --- a/crates/h264/src/decoder.rs +++ b/crates/h264/src/decoder.rs @@ -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); diff --git a/crates/h264/src/lib.rs b/crates/h264/src/lib.rs index 9b6f26d3..e66febd4 100644 --- a/crates/h264/src/lib.rs +++ b/crates/h264/src/lib.rs @@ -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; diff --git a/crates/h264/src/picture.rs b/crates/h264/src/picture.rs index 94d3335c..60bd97cb 100644 --- a/crates/h264/src/picture.rs +++ b/crates/h264/src/picture.rs @@ -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 { diff --git a/crates/h264/tests/conformance.rs b/crates/h264/tests/conformance.rs index 07061f73..c5ee81f0 100644 --- a/crates/h264/tests/conformance.rs +++ b/crates/h264/tests/conformance.rs @@ -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, );