]> git.nihav.org Git - nihav.git/blame - nihav-qt/src/codecs/qdmcommon.rs
avimux: do not record palette change chunks in OpenDML index
[nihav.git] / nihav-qt / src / codecs / qdmcommon.rs
CommitLineData
4c1582cf
KS
1use nihav_core::codecs::*;
2use nihav_core::io::bitreader::*;
3use nihav_core::io::codebook::*;
4
5/// Bitstream reader.
6#[derive(Debug,Clone)]
7pub struct QdmBitReader<'a> {
8 cache: u32,
9 bits: u8,
10 pos: usize,
11 src: &'a [u8],
12}
13
14#[allow(clippy::identity_op)]
4c1582cf
KS
15impl<'a> QdmBitReader<'a> {
16 pub fn new(src: &'a [u8]) -> Self {
17 Self{ cache: 0, pos: 0, bits: 0, src }
18 }
27116a4c 19 /*pub fn tell(&self) -> usize {
4c1582cf 20 self.pos * 8 - (self.bits as usize)
27116a4c 21 }*/
4c1582cf
KS
22 pub fn left(&self) -> isize {
23 ((self.src.len() as isize) - (self.pos as isize)) * 8 + (self.bits as isize)
24 }
25 fn refill(&mut self) {
26 while self.bits <= 24 {
27 let byte = if self.pos < self.src.len() {
28 self.pos += 1;
29 self.src[self.pos - 1]
30 } else {
31 self.pos += 1;
32 0
33 };
34 self.cache |= u32::from(byte) << self.bits;
35 self.bits += 8;
36 }
37 }
38 fn read_cache(&mut self, nbits: u8) -> u32 {
39 ((1 << nbits) - 1) & self.cache
40 }
41 fn skip_cache(&mut self, nbits: u8) {
42 self.cache >>= nbits;
43 self.bits -= nbits;
44 }
45 fn reset_cache(&mut self) {
46 self.bits = 0;
47 self.cache = 0;
48 }
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 {
53 self.refill();
54 }
55 let res = self.read_cache(nbits);
56 self.skip_cache(nbits);
57 res
58 }
59 pub fn read_bool(&mut self) -> bool {
60 if self.bits < 1 {
61 self.refill();
62 }
63 let res = self.read_cache(1);
64 self.skip_cache(1);
65 res == 1
66 }
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)
71 }
72 pub fn skip(&mut self, nbits: u32) {
73 if u32::from(self.bits) >= nbits {
74 self.skip_cache(nbits as u8);
75 return;
76 }
77 let mut skip_bits = nbits - u32::from(self.bits);
78 self.reset_cache();
79 self.pos += ((skip_bits / 32) * 4) as usize;
80 skip_bits &= 0x1F;
81 self.refill();
82 if skip_bits > 0 {
83 self.skip_cache(skip_bits as u8);
84 }
85 }
86}
87
88impl<'a, S: Copy> CodebookReader<S> for QdmBitReader<'a> {
4c1582cf
KS
89 fn read_cb(&mut self, cb: &Codebook<S>) -> CodebookResult<S> {
90 let mut esc = true;
91 let mut idx = 0;
92 let mut lut_bits = cb.lut_bits;
93 while esc {
e6aaad5c 94 let lut_idx = (self.peek(lut_bits) as usize) + idx;
4c1582cf
KS
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 };
e6aaad5c 100 self.skip(skip_bits);
4c1582cf
KS
101 lut_bits = bits as u8;
102 }
103 Ok(cb.syms[idx])
104 }
105}
106
107
108pub fn to_signed(val: i32) -> i32 {
109 if (val & 1) != 0 {
110 (val + 1) >> 1
111 } else {
112 -(val >> 1)
113 }
114}
115
116pub 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>;
119}
120
121impl<'a> QdmcCodeReader for BitReader<'a> {
122 fn read_code(&mut self, cb: &Codebook<u8>) -> DecoderResult<u32> {
123 let idx = self.read_cb(cb)?;
124 if idx > 0 {
125 Ok(u32::from(idx - 1))
126 } else {
127 let len = (self.read(3)? as u8) + 1;
128 let val = self.read(len)?;
129 Ok(val)
130 }
131 }
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)
137 }
138}
139
140impl<'a> QdmcCodeReader for QdmBitReader<'a> {
141 fn read_code(&mut self, cb: &Codebook<u8>) -> DecoderResult<u32> {
142 let idx = self.read_cb(cb)?;
143 if idx > 0 {
144 Ok(u32::from(idx - 1))
145 } else {
146 let len = (self.read(3) as u8) + 1;
147 let val = self.read(len);
148 Ok(val)
149 }
150 }
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)
156 }
157}
158
159const 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,
168 0x3FFFC
169];
170
171pub struct RNG {
172 pub seed: u32,
173}
174
175impl RNG {
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);
179 self.seed
180 }
181 pub fn next_float(&mut self) -> f32 {
182 self.next();
183 ((((self.seed >> 16) & 0x7FFF) as f32) - 16384.0) / 16384.0
184 }
185}
186
187#[derive(Clone,Copy)]
188pub struct Tone {
189 pub ch: u8,
190 pub phase: u8,
191 pub offset: u8,
192 pub freq: u16,
193 pub amp_idx: u8,
194}
195
196pub const MAX_TONES: usize = 8192;
197