1 use nihav_core::codecs::*;
2 use nihav_core::io::bitreader::*;
3 use nihav_core::io::codebook::*;
7 pub struct QdmBitReader<'a> {
14 #[allow(clippy::identity_op)]
16 impl<'a> QdmBitReader<'a> {
17 pub fn new(src: &'a [u8]) -> Self {
18 Self{ cache: 0, pos: 0, bits: 0, src }
20 pub fn tell(&self) -> usize {
21 self.pos * 8 - (self.bits as usize)
23 pub fn left(&self) -> isize {
24 ((self.src.len() as isize) - (self.pos as isize)) * 8 + (self.bits as isize)
26 fn refill(&mut self) {
27 while self.bits <= 24 {
28 let byte = if self.pos < self.src.len() {
30 self.src[self.pos - 1]
35 self.cache |= u32::from(byte) << self.bits;
39 fn read_cache(&mut self, nbits: u8) -> u32 {
40 ((1 << nbits) - 1) & self.cache
42 fn skip_cache(&mut self, nbits: u8) {
46 fn reset_cache(&mut self) {
50 pub fn read(&mut self, nbits: u8) -> u32 {
51 if nbits == 0 { return 0; }
52 if nbits > 32 { return 0; }
53 if self.bits < nbits {
56 let res = self.read_cache(nbits);
57 self.skip_cache(nbits);
60 pub fn read_bool(&mut self) -> bool {
64 let res = self.read_cache(1);
68 pub fn peek(&mut self, nbits: u8) -> u32 {
69 if nbits > 32 { return 0 }
70 if self.bits < nbits { self.refill(); }
71 self.read_cache(nbits)
73 pub fn skip(&mut self, nbits: u32) {
74 if u32::from(self.bits) >= nbits {
75 self.skip_cache(nbits as u8);
78 let mut skip_bits = nbits - u32::from(self.bits);
80 self.pos += ((skip_bits / 32) * 4) as usize;
84 self.skip_cache(skip_bits as u8);
89 impl<'a, S: Copy> CodebookReader<S> for QdmBitReader<'a> {
90 #[allow(unused_variables)]
91 fn read_cb(&mut self, cb: &Codebook<S>) -> CodebookResult<S> {
94 let mut lut_bits = cb.lut_bits;
96 let lut_idx = (self.peek(lut_bits) as usize) + (idx as usize);
97 if cb.table[lut_idx] == TABLE_FILL_VALUE { return Err(CodebookError::InvalidCode); }
98 let bits = cb.table[lut_idx] & 0x7F;
99 esc = (cb.table[lut_idx] & 0x80) != 0;
100 idx = (cb.table[lut_idx] >> 8) as usize;
101 let skip_bits = if esc { u32::from(lut_bits) } else { bits };
102 self.skip(skip_bits as u32);
103 lut_bits = bits as u8;
110 pub fn to_signed(val: i32) -> i32 {
118 pub trait QdmcCodeReader {
119 fn read_code(&mut self, cb: &Codebook<u8>) -> DecoderResult<u32>;
120 fn read_code_long(&mut self, cb: &Codebook<u8>) -> DecoderResult<u32>;
123 impl<'a> QdmcCodeReader for BitReader<'a> {
124 fn read_code(&mut self, cb: &Codebook<u8>) -> DecoderResult<u32> {
125 let idx = self.read_cb(cb)?;
127 Ok(u32::from(idx - 1))
129 let len = (self.read(3)? as u8) + 1;
130 let val = self.read(len)?;
134 fn read_code_long(&mut self, cb: &Codebook<u8>) -> DecoderResult<u32> {
135 let idx = self.read_code(cb)? as usize;
136 validate!(idx < ESCAPE_PREFIX.len());
137 let add = self.read((idx >> 2) as u8)?;
138 Ok(ESCAPE_PREFIX[idx] + add)
142 impl<'a> QdmcCodeReader for QdmBitReader<'a> {
143 fn read_code(&mut self, cb: &Codebook<u8>) -> DecoderResult<u32> {
144 let idx = self.read_cb(cb)?;
146 Ok(u32::from(idx - 1))
148 let len = (self.read(3) as u8) + 1;
149 let val = self.read(len);
153 fn read_code_long(&mut self, cb: &Codebook<u8>) -> DecoderResult<u32> {
154 let idx = self.read_code(cb)? as usize;
155 validate!(idx < ESCAPE_PREFIX.len());
156 let add = self.read((idx >> 2) as u8);
157 Ok(ESCAPE_PREFIX[idx] + add)
161 const ESCAPE_PREFIX: [u32; 65] = [
162 0x00000, 0x00001, 0x00002, 0x00003, 0x00004, 0x00006, 0x00008, 0x0000A,
163 0x0000C, 0x00010, 0x00014, 0x00018, 0x0001C, 0x00024, 0x0002C, 0x00034,
164 0x0003C, 0x0004C, 0x0005C, 0x0006C, 0x0007C, 0x0009C, 0x000BC, 0x000DC,
165 0x000FC, 0x0013C, 0x0017C, 0x001BC, 0x001FC, 0x0027C, 0x002FC, 0x0037C,
166 0x003FC, 0x004FC, 0x005FC, 0x006FC, 0x007FC, 0x009FC, 0x00BFC, 0x00DFC,
167 0x00FFC, 0x013FC, 0x017FC, 0x01BFC, 0x01FFC, 0x027FC, 0x02FFC, 0x037FC,
168 0x03FFC, 0x04FFC, 0x05FFC, 0x06FFC, 0x07FFC, 0x09FFC, 0x0BFFC, 0x0DFFC,
169 0x0FFFC, 0x13FFC, 0x17FFC, 0x1BFFC, 0x1FFFC, 0x27FFC, 0x2FFFC, 0x37FFC,
178 pub fn new() -> Self { Self { seed: 0 } }
179 pub fn next(&mut self) -> u32 {
180 self.seed = self.seed.wrapping_mul(0x343FD).wrapping_add(0x269EC3);
183 pub fn next_float(&mut self) -> f32 {
185 ((((self.seed >> 16) & 0x7FFF) as f32) - 16384.0) / 16384.0
189 #[derive(Clone,Copy)]
198 pub const MAX_TONES: usize = 8192;