]>
Commit | Line | Data |
---|---|---|
1 | use io::bitreader::BitReader; | |
2 | ||
3 | #[derive(Debug)] | |
4 | pub enum CodebookError { | |
5 | InvalidCodebook, | |
6 | MemoryError, | |
7 | InvalidCode, | |
8 | } | |
9 | ||
10 | type CodebookResult<T> = Result<T, CodebookError>; | |
11 | ||
12 | pub struct FullCodebookDesc<S> { | |
13 | code: u32, | |
14 | bits: u8, | |
15 | sym: S, | |
16 | } | |
17 | ||
18 | pub struct ShortCodebookDesc { | |
19 | code: u32, | |
20 | bits: u8, | |
21 | } | |
22 | ||
23 | pub 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)] | |
31 | pub struct Codebook<S> { | |
32 | table: Vec<u32>, | |
33 | syms: Vec<S>, | |
34 | lut_bits: u8, | |
35 | } | |
36 | ||
37 | pub trait CodebookReader<S> { | |
38 | fn read_cb(&mut self, cb: &Codebook<S>) -> CodebookResult<S>; | |
39 | } | |
40 | ||
41 | impl<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 | ||
87 | impl<'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 | ||
102 | pub struct FullCodebookDescReader<S> { | |
103 | data: Vec<FullCodebookDesc<S>>, | |
104 | } | |
105 | ||
106 | impl<S> FullCodebookDescReader<S> { | |
107 | pub fn new(data: Vec<FullCodebookDesc<S>>) -> Self { | |
108 | FullCodebookDescReader { data: data } | |
109 | } | |
110 | } | |
111 | ||
112 | impl<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 | ||
119 | pub struct ShortCodebookDescReader { | |
120 | data: Vec<ShortCodebookDesc>, | |
121 | } | |
122 | ||
123 | impl ShortCodebookDescReader { | |
124 | pub fn new(data: Vec<ShortCodebookDesc<>>) -> Self { | |
125 | ShortCodebookDescReader { data: data } | |
126 | } | |
127 | } | |
128 | ||
129 | impl 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)] | |
137 | mod 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 | } |