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)]
15 impl<'a> QdmBitReader<'a> {
16 pub fn new(src: &'a [u8]) -> Self {
17 Self{ cache: 0, pos: 0, bits: 0, src }
19 /*pub fn tell(&self) -> usize {
20 self.pos * 8 - (self.bits as usize)
22 pub fn left(&self) -> isize {
23 ((self.src.len() as isize) - (self.pos as isize)) * 8 + (self.bits as isize)
25 fn refill(&mut self) {
26 while self.bits <= 24 {
27 let byte = if self.pos < self.src.len() {
29 self.src[self.pos - 1]
34 self.cache |= u32::from(byte) << self.bits;
38 fn read_cache(&mut self, nbits: u8) -> u32 {
39 ((1 << nbits) - 1) & self.cache
41 fn skip_cache(&mut self, nbits: u8) {
45 fn reset_cache(&mut self) {
49 pub fn read(&mut self, nbits: u8) -> u32 {
50 if nbits == 0 { return 0; }
51 if nbits > 32 { return 0; }
52 if self.bits < nbits {
55 let res = self.read_cache(nbits);
56 self.skip_cache(nbits);
59 pub fn read_bool(&mut self) -> bool {
63 let res = self.read_cache(1);
67 pub fn peek(&mut self, nbits: u8) -> u32 {
68 if nbits > 32 { return 0 }
69 if self.bits < nbits { self.refill(); }
70 self.read_cache(nbits)
72 pub fn skip(&mut self, nbits: u32) {
73 if u32::from(self.bits) >= nbits {
74 self.skip_cache(nbits as u8);
77 let mut skip_bits = nbits - u32::from(self.bits);
79 self.pos += ((skip_bits / 32) * 4) as usize;
83 self.skip_cache(skip_bits as u8);
88 impl<'a, S: Copy> CodebookReader<S> for QdmBitReader<'a> {
89 fn read_cb(&mut self, cb: &Codebook<S>) -> CodebookResult<S> {
92 let mut lut_bits = cb.lut_bits;
94 let lut_idx = (self.peek(lut_bits) as usize) + idx;
95 if cb.table[lut_idx] == TABLE_FILL_VALUE { return Err(CodebookError::InvalidCode); }
96 let bits = cb.table[lut_idx] & 0x7F;
97 esc = (cb.table[lut_idx] & 0x80) != 0;
98 idx = (cb.table[lut_idx] >> 8) as usize;
99 let skip_bits = if esc { u32::from(lut_bits) } else { bits };
100 self.skip(skip_bits);
101 lut_bits = bits as u8;
108 pub fn to_signed(val: i32) -> i32 {
116 pub trait QdmcCodeReader {
117 fn read_code(&mut self, cb: &Codebook<u8>) -> DecoderResult<u32>;
118 fn read_code_long(&mut self, cb: &Codebook<u8>) -> DecoderResult<u32>;
121 impl<'a> QdmcCodeReader for BitReader<'a> {
122 fn read_code(&mut self, cb: &Codebook<u8>) -> DecoderResult<u32> {
123 let idx = self.read_cb(cb)?;
125 Ok(u32::from(idx - 1))
127 let len = (self.read(3)? as u8) + 1;
128 let val = self.read(len)?;
132 fn read_code_long(&mut self, cb: &Codebook<u8>) -> DecoderResult<u32> {
133 let idx = self.read_code(cb)? as usize;
134 validate!(idx < ESCAPE_PREFIX.len());
135 let add = self.read((idx >> 2) as u8)?;
136 Ok(ESCAPE_PREFIX[idx] + add)
140 impl<'a> QdmcCodeReader for QdmBitReader<'a> {
141 fn read_code(&mut self, cb: &Codebook<u8>) -> DecoderResult<u32> {
142 let idx = self.read_cb(cb)?;
144 Ok(u32::from(idx - 1))
146 let len = (self.read(3) as u8) + 1;
147 let val = self.read(len);
151 fn read_code_long(&mut self, cb: &Codebook<u8>) -> DecoderResult<u32> {
152 let idx = self.read_code(cb)? as usize;
153 validate!(idx < ESCAPE_PREFIX.len());
154 let add = self.read((idx >> 2) as u8);
155 Ok(ESCAPE_PREFIX[idx] + add)
159 const ESCAPE_PREFIX: [u32; 65] = [
160 0x00000, 0x00001, 0x00002, 0x00003, 0x00004, 0x00006, 0x00008, 0x0000A,
161 0x0000C, 0x00010, 0x00014, 0x00018, 0x0001C, 0x00024, 0x0002C, 0x00034,
162 0x0003C, 0x0004C, 0x0005C, 0x0006C, 0x0007C, 0x0009C, 0x000BC, 0x000DC,
163 0x000FC, 0x0013C, 0x0017C, 0x001BC, 0x001FC, 0x0027C, 0x002FC, 0x0037C,
164 0x003FC, 0x004FC, 0x005FC, 0x006FC, 0x007FC, 0x009FC, 0x00BFC, 0x00DFC,
165 0x00FFC, 0x013FC, 0x017FC, 0x01BFC, 0x01FFC, 0x027FC, 0x02FFC, 0x037FC,
166 0x03FFC, 0x04FFC, 0x05FFC, 0x06FFC, 0x07FFC, 0x09FFC, 0x0BFFC, 0x0DFFC,
167 0x0FFFC, 0x13FFC, 0x17FFC, 0x1BFFC, 0x1FFFC, 0x27FFC, 0x2FFFC, 0x37FFC,
176 pub fn new() -> Self { Self { seed: 0 } }
177 pub fn next(&mut self) -> u32 {
178 self.seed = self.seed.wrapping_mul(0x343FD).wrapping_add(0x269EC3);
181 pub fn next_float(&mut self) -> f32 {
183 ((((self.seed >> 16) & 0x7FFF) as f32) - 16384.0) / 16384.0
187 #[derive(Clone,Copy)]
196 pub const MAX_TONES: usize = 8192;