]> git.nihav.org Git - nihav.git/blob - nihav-qt/src/codecs/qdmcommon.rs
h264: update test hashes after the changes
[nihav.git] / nihav-qt / src / codecs / qdmcommon.rs
1 use nihav_core::codecs::*;
2 use nihav_core::io::bitreader::*;
3 use nihav_core::io::codebook::*;
4
5 /// Bitstream reader.
6 #[derive(Debug,Clone)]
7 pub struct QdmBitReader<'a> {
8 cache: u32,
9 bits: u8,
10 pos: usize,
11 src: &'a [u8],
12 }
13
14 #[allow(clippy::identity_op)]
15 #[allow(dead_code)]
16 impl<'a> QdmBitReader<'a> {
17 pub fn new(src: &'a [u8]) -> Self {
18 Self{ cache: 0, pos: 0, bits: 0, src }
19 }
20 pub fn tell(&self) -> usize {
21 self.pos * 8 - (self.bits as usize)
22 }
23 pub fn left(&self) -> isize {
24 ((self.src.len() as isize) - (self.pos as isize)) * 8 + (self.bits as isize)
25 }
26 fn refill(&mut self) {
27 while self.bits <= 24 {
28 let byte = if self.pos < self.src.len() {
29 self.pos += 1;
30 self.src[self.pos - 1]
31 } else {
32 self.pos += 1;
33 0
34 };
35 self.cache |= u32::from(byte) << self.bits;
36 self.bits += 8;
37 }
38 }
39 fn read_cache(&mut self, nbits: u8) -> u32 {
40 ((1 << nbits) - 1) & self.cache
41 }
42 fn skip_cache(&mut self, nbits: u8) {
43 self.cache >>= nbits;
44 self.bits -= nbits;
45 }
46 fn reset_cache(&mut self) {
47 self.bits = 0;
48 self.cache = 0;
49 }
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 {
54 self.refill();
55 }
56 let res = self.read_cache(nbits);
57 self.skip_cache(nbits);
58 res
59 }
60 pub fn read_bool(&mut self) -> bool {
61 if self.bits < 1 {
62 self.refill();
63 }
64 let res = self.read_cache(1);
65 self.skip_cache(1);
66 res == 1
67 }
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)
72 }
73 pub fn skip(&mut self, nbits: u32) {
74 if u32::from(self.bits) >= nbits {
75 self.skip_cache(nbits as u8);
76 return;
77 }
78 let mut skip_bits = nbits - u32::from(self.bits);
79 self.reset_cache();
80 self.pos += ((skip_bits / 32) * 4) as usize;
81 skip_bits &= 0x1F;
82 self.refill();
83 if skip_bits > 0 {
84 self.skip_cache(skip_bits as u8);
85 }
86 }
87 }
88
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> {
92 let mut esc = true;
93 let mut idx = 0;
94 let mut lut_bits = cb.lut_bits;
95 while esc {
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;
104 }
105 Ok(cb.syms[idx])
106 }
107 }
108
109
110 pub fn to_signed(val: i32) -> i32 {
111 if (val & 1) != 0 {
112 (val + 1) >> 1
113 } else {
114 -(val >> 1)
115 }
116 }
117
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>;
121 }
122
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)?;
126 if idx > 0 {
127 Ok(u32::from(idx - 1))
128 } else {
129 let len = (self.read(3)? as u8) + 1;
130 let val = self.read(len)?;
131 Ok(val)
132 }
133 }
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)
139 }
140 }
141
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)?;
145 if idx > 0 {
146 Ok(u32::from(idx - 1))
147 } else {
148 let len = (self.read(3) as u8) + 1;
149 let val = self.read(len);
150 Ok(val)
151 }
152 }
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)
158 }
159 }
160
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,
170 0x3FFFC
171 ];
172
173 pub struct RNG {
174 pub seed: u32,
175 }
176
177 impl RNG {
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);
181 self.seed
182 }
183 pub fn next_float(&mut self) -> f32 {
184 self.next();
185 ((((self.seed >> 16) & 0x7FFF) as f32) - 16384.0) / 16384.0
186 }
187 }
188
189 #[derive(Clone,Copy)]
190 pub struct Tone {
191 pub ch: u8,
192 pub phase: u8,
193 pub offset: u8,
194 pub freq: u16,
195 pub amp_idx: u8,
196 }
197
198 pub const MAX_TONES: usize = 8192;
199