use peek in GDV demuxer
[nihav.git] / src / io / codebook.rs
CommitLineData
4667915a
KS
1use io::bitreader::BitReader;
2
3#[derive(Debug)]
4pub enum CodebookError {
5 InvalidCodebook,
6 MemoryError,
7 InvalidCode,
8}
9
10type CodebookResult<T> = Result<T, CodebookError>;
11
12pub struct FullCodebookDesc<S> {
13 code: u32,
14 bits: u8,
15 sym: S,
16}
17
18pub struct ShortCodebookDesc {
19 code: u32,
20 bits: u8,
21}
22
23pub trait CodebookDescReader<S> {
24 fn bits(&mut self, idx: usize) -> u8;
25 fn code(&mut self, idx: usize) -> u32;
26 fn sym (&mut self, idx: usize) -> S;
27 fn len (&mut self) -> usize;
28}
29
30#[allow(dead_code)]
31pub struct Codebook<S> {
32 table: Vec<u32>,
33 syms: Vec<S>,
34 lut_bits: u8,
35}
36
37pub trait CodebookReader<S> {
38 fn read_cb(&mut self, cb: &Codebook<S>) -> CodebookResult<S>;
39}
40
41impl<S: Copy> Codebook<S> {
42//todo allow add escapes
43 pub fn new(cb: &mut CodebookDescReader<S>) -> CodebookResult<Self> {
44 let mut maxbits = 0;
45 let mut nnz = 0;
46 for i in 0..cb.len() {
47 let bits = cb.bits(i);
48 if bits > 0 { nnz = nnz + 1; }
49 if bits > maxbits {
50 maxbits = bits;
51 }
52 }
53 if maxbits == 0 { return Err(CodebookError::InvalidCodebook); }
54
55 let mut table: Vec<u32> = Vec::new();
56 let mut syms: Vec<S> = Vec::new();
57 let tab_len = 1 << maxbits;
58 table.reserve(tab_len);
59 if table.capacity() < tab_len { return Err(CodebookError::MemoryError); }
60 table.resize(tab_len, 0xFF);
61 syms.reserve(nnz);
62 if syms.capacity() < nnz { return Err(CodebookError::MemoryError); }
63
64 let mut symidx: u32 = 0;
65 for i in 0..cb.len() {
66 let bits = cb.bits(i);
67 if bits == 0 { continue; }
68 let code = cb.code(i) << (maxbits - bits);
69 let fill_len = 1 << (maxbits - bits);
70 for j in 0..fill_len {
71 let idx = (code + j) as usize;
72 table[idx] = (symidx << 8) | (bits as u32);
73 }
74 symidx = symidx + 1;
75 }
76
77 for i in 0..cb.len() {
78 if cb.bits(i) > 0 {
79 syms.push(cb.sym(i));
80 }
81 }
82
83 Ok(Codebook { table: table, syms: syms, lut_bits: maxbits })
84 }
85}
86
87impl<'a, S: Copy> CodebookReader<S> for BitReader<'a> {
88 #[allow(unused_variables)]
89 fn read_cb(&mut self, cb: &Codebook<S>) -> CodebookResult<S> {
90 let lut_idx = self.peek(cb.lut_bits) as usize;
91 let bits = cb.table[lut_idx] & 0xFF;
92 let idx = (cb.table[lut_idx] >> 8) as usize;
93 if bits == 0xFF || (bits as isize) > self.left() {
94 return Err(CodebookError::InvalidCode);
95 }
96 if let Err(_) = self.skip(bits) {}
97 let sym = cb.syms[idx];
98 return Ok(sym)
99 }
100}
101
102pub struct FullCodebookDescReader<S> {
103 data: Vec<FullCodebookDesc<S>>,
104}
105
106impl<S> FullCodebookDescReader<S> {
107 pub fn new(data: Vec<FullCodebookDesc<S>>) -> Self {
108 FullCodebookDescReader { data: data }
109 }
110}
111
112impl<S: Copy> CodebookDescReader<S> for FullCodebookDescReader<S> {
113 fn bits(&mut self, idx: usize) -> u8 { self.data[idx].bits }
114 fn code(&mut self, idx: usize) -> u32 { self.data[idx].code }
115 fn sym (&mut self, idx: usize) -> S { self.data[idx].sym }
116 fn len(&mut self) -> usize { self.data.len() }
117}
118
119pub struct ShortCodebookDescReader {
120 data: Vec<ShortCodebookDesc>,
121}
122
123impl ShortCodebookDescReader {
124 pub fn new(data: Vec<ShortCodebookDesc<>>) -> Self {
125 ShortCodebookDescReader { data: data }
126 }
127}
128
129impl CodebookDescReader<u32> for ShortCodebookDescReader {
130 fn bits(&mut self, idx: usize) -> u8 { self.data[idx].bits }
131 fn code(&mut self, idx: usize) -> u32 { self.data[idx].code }
132 fn sym (&mut self, idx: usize) -> u32 { idx as u32 }
133 fn len(&mut self) -> usize { self.data.len() }
134}
135
136#[cfg(test)]
137mod test {
138 use super::*;
139 use io::bitreader::*;
140
141 #[test]
142 fn test_cb() {
143 const BITS: [u8; 2] = [0b01011011, 0b10111100];
144 let cb_desc: Vec<FullCodebookDesc<i8>> = vec!(
145 FullCodebookDesc { code: 0b0, bits: 1, sym: 16 },
146 FullCodebookDesc { code: 0b10, bits: 2, sym: -3 },
147 FullCodebookDesc { code: 0b110, bits: 3, sym: 42 },
148 FullCodebookDesc { code: 0b1110, bits: 4, sym: -42 }
149 );
150 let buf = &BITS;
151 let mut br = BitReader::new(buf, buf.len(), BitReaderMode::BE);
152 let mut cfr = FullCodebookDescReader::new(cb_desc);
153 let cb = Codebook::new(&mut cfr).unwrap();
154 assert_eq!(br.read_cb(&cb).unwrap(), 16);
155 assert_eq!(br.read_cb(&cb).unwrap(), -3);
156 assert_eq!(br.read_cb(&cb).unwrap(), 42);
157 assert_eq!(br.read_cb(&cb).unwrap(), -42);
158 let ret = br.read_cb(&cb);
159 if let Err(e) = ret {
160 assert_eq!(e as i32, CodebookError::InvalidCode as i32);
161 } else {
162 assert_eq!(0, 1);
163 }
164
165 let scb_desc: Vec<ShortCodebookDesc> = vec!(
166 ShortCodebookDesc { code: 0b0, bits: 1 },
167 ShortCodebookDesc { code: 0, bits: 0 },
168 ShortCodebookDesc { code: 0b10, bits: 2 },
169 ShortCodebookDesc { code: 0, bits: 0 },
170 ShortCodebookDesc { code: 0, bits: 0 },
171 ShortCodebookDesc { code: 0b110, bits: 3 },
172 ShortCodebookDesc { code: 0, bits: 0 },
173 ShortCodebookDesc { code: 0b1110, bits: 4 }
174 );
175 let mut br2 = BitReader::new(buf, buf.len(), BitReaderMode::BE);
176 let mut cfr = ShortCodebookDescReader::new(scb_desc);
177 let cb = Codebook::new(&mut cfr).unwrap();
178 assert_eq!(br2.read_cb(&cb).unwrap(), 0);
179 assert_eq!(br2.read_cb(&cb).unwrap(), 2);
180 assert_eq!(br2.read_cb(&cb).unwrap(), 5);
181 assert_eq!(br2.read_cb(&cb).unwrap(), 7);
182 }
183}