1use std::cmp::{max, min};
6use std::collections::HashMap;
7use std::fmt;
8use std::marker::PhantomData;
9
10use num_traits::AsPrimitive;
11
12use crate::bitread::*;
13
14#[derive(Debug)]
16pub enum CodebookError {
17 InvalidCodebook,
19 InvalidCode,
21}
22
23impl std::error::Error for CodebookError {}
24
25impl fmt::Display for CodebookError {
26 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
27 match self {
28 InvalidCodebook => write!(f, "Invalid Codebook"),
29 InvalidCode => write!(f, "Invalid Code"),
30 }
31 }
32}
33
34use self::CodebookError::*;
35
36#[derive(Debug, Copy, Clone)]
38#[allow(clippy::upper_case_acronyms)]
39pub enum CodebookMode {
40 MSB,
42 LSB,
44}
45
46pub struct FullCodebookDesc<S> {
48 pub code: u32,
50 pub bits: u8,
52 pub sym: S,
54}
55
56pub struct ShortCodebookDesc {
59 pub code: u32,
61 pub bits: u8,
63}
64
65pub trait CodebookDescReader<S> {
68 fn bits(&self, idx: usize) -> u8;
70 fn code(&self, idx: usize) -> u32;
72 fn sym(&self, idx: usize) -> S;
74
75 fn len(&self) -> usize;
77 fn is_empty(&self) -> bool;
79}
80
81#[allow(dead_code)]
83pub struct Codebook<S> {
84 table: Vec<u32>,
85 syms: Vec<S>,
86 lut_bits: u8,
87}
88
89pub trait CodebookReader<S> {
91 fn read_cb(&mut self, cb: &Codebook<S>) -> Result<S, CodebookError>;
93}
94
95pub fn reverse_bits(inval: u32) -> u32 {
97 const REV_TAB: [u8; 16] = [
98 0b0000, 0b1000, 0b0100, 0b1100, 0b0010, 0b1010, 0b0110, 0b1110, 0b0001, 0b1001, 0b0101,
99 0b1101, 0b0011, 0b1011, 0b0111, 0b1111,
100 ];
101
102 let mut ret = 0;
103 let mut val = inval;
104 for _ in 0..8 {
105 ret = (ret << 4) | u32::from(REV_TAB[(val & 0xF) as usize]);
106 val >>= 4;
107 }
108 ret
109}
110
111const TABLE_FILL_VALUE: u32 = 0x7F;
112const MAX_LUT_BITS: u8 = 10;
113
114fn fill_lut_msb(
115 table: &mut [u32],
116 off: usize,
117 code: u32,
118 bits: u8,
119 lut_bits: u8,
120 symidx: u32,
121 esc: bool,
122) {
123 if !esc {
124 let fill_len = lut_bits - bits;
125 let fill_size = 1 << fill_len;
126 let fill_code = code << (lut_bits - bits);
127 let lut_value = (symidx << 8) | u32::from(bits);
128 for j in 0..fill_size {
129 let idx = (fill_code + j) as usize;
130 table[idx + off] = lut_value;
131 }
132 } else {
133 let idx = (code as usize) + off;
134 table[idx] = (symidx << 8) | 0x80 | u32::from(bits);
135 }
136}
137
138fn fill_lut_lsb(
139 table: &mut [u32],
140 off: usize,
141 code: u32,
142 bits: u8,
143 lut_bits: u8,
144 symidx: u32,
145 esc: bool,
146) {
147 if !esc {
148 let fill_len = lut_bits - bits;
149 let fill_size = 1 << fill_len;
150 let fill_code = code;
151 let step = lut_bits - fill_len;
152 for j in 0..fill_size {
153 let idx = (fill_code + (j << step)) as usize;
154 table[idx + off] = (symidx << 8) | u32::from(bits);
155 }
156 } else {
157 let idx = (code as usize) + off;
158 table[idx] = (symidx << 8) | 0x80 | u32::from(bits);
159 }
160}
161
162fn fill_lut(
163 table: &mut [u32],
164 mode: CodebookMode,
165 off: usize,
166 code: u32,
167 bits: u8,
168 lut_bits: u8,
169 symidx: u32,
170 esc: bool,
171) -> bool {
172 match mode {
173 CodebookMode::MSB => fill_lut_msb(table, off, code, bits, lut_bits, symidx, esc),
174 CodebookMode::LSB => fill_lut_lsb(table, off, code, bits, lut_bits, symidx, esc),
175 };
176 bits > lut_bits
177}
178
179fn resize_table(table: &mut Vec<u32>, bits: u8) -> u32 {
180 let add_size = (1 << bits) as usize;
181 table.reserve(add_size);
182 let cur_off = table.len() as u32;
183 let new_size = table.len() + add_size;
184 table.resize(new_size, TABLE_FILL_VALUE);
185 cur_off
186}
187
188fn extract_lut_part(code: u32, bits: u8, lut_bits: u8, mode: CodebookMode) -> u32 {
189 match mode {
190 CodebookMode::MSB => code >> (bits - lut_bits),
191 CodebookMode::LSB => code & ((1 << lut_bits) - 1),
192 }
193}
194
195fn extract_esc_part(code: u32, bits: u8, lut_bits: u8, mode: CodebookMode) -> u32 {
196 match mode {
197 CodebookMode::MSB => code & ((1 << (bits - lut_bits)) - 1),
198 CodebookMode::LSB => code >> lut_bits,
199 }
200}
201
202#[derive(Clone, Copy)]
203struct Code {
204 code: u32,
205 bits: u8,
206 idx: usize,
207}
208
209struct CodeBucket {
210 maxlen: u8,
211 offset: usize,
212 codes: Vec<Code>,
213}
214
215impl CodeBucket {
216 fn new() -> Self {
217 CodeBucket {
218 maxlen: 0,
219 offset: 0,
220 codes: Vec::new(),
221 }
222 }
223 fn add_code(&mut self, c: Code) {
224 if c.bits > self.maxlen {
225 self.maxlen = c.bits;
226 }
227 self.codes.push(c);
228 }
229}
230
231type EscapeCodes = HashMap<u32, CodeBucket>;
232
233fn add_esc_code(cc: &mut EscapeCodes, key: u32, code: u32, bits: u8, idx: usize) {
234 let bucket = cc.entry(key).or_insert_with(CodeBucket::new);
235 bucket.add_code(Code { code, bits, idx });
236}
237
238fn build_esc_lut(
239 table: &mut Vec<u32>,
240 mode: CodebookMode,
241 bucket: &CodeBucket,
242) -> Result<(), CodebookError> {
243 let mut escape_list: EscapeCodes = HashMap::new();
244 let maxlen = min(bucket.maxlen, MAX_LUT_BITS);
245
246 for code in &bucket.codes {
247 let bits = code.bits;
248 if code.bits <= MAX_LUT_BITS {
249 fill_lut(
250 table,
251 mode,
252 bucket.offset,
253 code.code,
254 bits,
255 maxlen,
256 code.idx as u32,
257 false,
258 );
259 } else {
260 let ckey = extract_lut_part(code.code, bits, MAX_LUT_BITS, mode);
261 let cval = extract_esc_part(code.code, bits, MAX_LUT_BITS, mode);
262 add_esc_code(&mut escape_list, ckey, cval, bits - MAX_LUT_BITS, code.idx);
263 }
264 }
265
266 let cur_offset = bucket.offset;
267 for (ckey, sec_bucket) in &mut escape_list {
268 let key = *ckey;
269 let maxlen = min(sec_bucket.maxlen, MAX_LUT_BITS);
270 let new_off = resize_table(table, maxlen);
271 fill_lut(
272 table,
273 mode,
274 cur_offset,
275 key,
276 maxlen,
277 MAX_LUT_BITS,
278 new_off,
279 true,
280 );
281 sec_bucket.offset = new_off as usize;
282 }
283
284 for sec_bucket in escape_list.values() {
285 build_esc_lut(table, mode, sec_bucket)?;
286 }
287
288 Ok(())
289}
290
291impl<S: Copy> Codebook<S> {
292 pub fn new(cb: &dyn CodebookDescReader<S>, mode: CodebookMode) -> Result<Self, CodebookError> {
295 let mut maxbits = 0;
296 let mut nnz = 0;
297 let mut escape_list: EscapeCodes = HashMap::new();
298
299 let mut symidx: usize = 0;
300 for i in 0..cb.len() {
301 let bits = cb.bits(i);
302 if bits > 0 {
303 nnz += 1;
304 }
305 maxbits = max(bits, maxbits);
306 if bits > MAX_LUT_BITS {
307 let code = cb.code(i);
308 let ckey = extract_lut_part(code, bits, MAX_LUT_BITS, mode);
309 let cval = extract_esc_part(code, bits, MAX_LUT_BITS, mode);
310 add_esc_code(&mut escape_list, ckey, cval, bits - MAX_LUT_BITS, symidx);
311 }
312 if bits > 0 {
313 symidx += 1;
314 }
315 }
316 if maxbits == 0 {
317 return Err(InvalidCodebook);
318 }
319
320 if maxbits > MAX_LUT_BITS {
321 maxbits = MAX_LUT_BITS;
322 }
323
324 let tab_len = 1 << maxbits;
325 let mut table: Vec<u32> = Vec::with_capacity(tab_len);
326 let mut syms: Vec<S> = Vec::with_capacity(nnz);
327 table.resize(tab_len, TABLE_FILL_VALUE);
328
329 let mut symidx: u32 = 0;
330 for i in 0..cb.len() {
331 let bits = cb.bits(i);
332 let code = cb.code(i);
333 if bits == 0 {
334 continue;
335 }
336 if bits <= MAX_LUT_BITS {
337 fill_lut(&mut table, mode, 0, code, bits, maxbits, symidx, false);
338 } else {
339 let ckey = extract_lut_part(code, bits, MAX_LUT_BITS, mode) as usize;
340 if table[ckey] == TABLE_FILL_VALUE {
341 let key = ckey as u32;
342 if let Some(bucket) = escape_list.get_mut(&key) {
343 let maxlen = min(bucket.maxlen, MAX_LUT_BITS);
344 let new_off = resize_table(&mut table, maxlen);
345 fill_lut(
346 &mut table,
347 mode,
348 0,
349 key,
350 maxlen,
351 MAX_LUT_BITS,
352 new_off,
353 true,
354 );
355 bucket.offset = new_off as usize;
356 }
357 }
358 }
359 symidx += 1;
360 }
361
362 for bucket in escape_list.values() {
363 build_esc_lut(&mut table, mode, bucket)?;
364 }
365
366 for i in 0..cb.len() {
367 if cb.bits(i) > 0 {
368 syms.push(cb.sym(i));
369 }
370 }
371
372 Ok(Codebook {
373 table,
374 syms,
375 lut_bits: maxbits,
376 })
377 }
378}
379
380impl<'a, S: Copy, B: BitRead<'a>> CodebookReader<S> for B {
381 fn read_cb(&mut self, cb: &Codebook<S>) -> Result<S, CodebookError> {
382 let mut esc = true;
383 let mut idx = 0;
384 let mut lut_bits = cb.lut_bits;
385 while esc {
386 let lut_idx = (self.peek_bits_32(lut_bits as usize) as usize) + idx;
387 if cb.table[lut_idx] == TABLE_FILL_VALUE {
388 return Err(InvalidCode);
389 }
390 let bits = cb.table[lut_idx] & 0x7F;
391 esc = (cb.table[lut_idx] & 0x80) != 0;
392 idx = (cb.table[lut_idx] >> 8) as usize;
393 if bits > self.available() as u32 {
394 return Err(InvalidCode);
395 }
396 let skip_bits = if esc {
397 lut_bits as usize
398 } else {
399 bits as usize
400 };
401 self.skip_bits(skip_bits);
402 lut_bits = bits as u8;
403 }
404 Ok(cb.syms[idx])
405 }
406}
407
408impl<S: Copy> CodebookDescReader<S> for Vec<FullCodebookDesc<S>> {
409 fn bits(&self, idx: usize) -> u8 {
410 self[idx].bits
411 }
412 fn code(&self, idx: usize) -> u32 {
413 self[idx].code
414 }
415 fn sym(&self, idx: usize) -> S {
416 self[idx].sym
417 }
418 fn len(&self) -> usize {
419 Vec::len(self)
420 }
421 fn is_empty(&self) -> bool {
422 Vec::is_empty(self)
423 }
424}
425
426impl CodebookDescReader<u32> for Vec<ShortCodebookDesc> {
427 fn bits(&self, idx: usize) -> u8 {
428 self[idx].bits
429 }
430 fn code(&self, idx: usize) -> u32 {
431 self[idx].code
432 }
433 fn sym(&self, idx: usize) -> u32 {
434 idx as u32
435 }
436 fn len(&self) -> usize {
437 Vec::len(self)
438 }
439 fn is_empty(&self) -> bool {
440 Vec::is_empty(self)
441 }
442}
443
444impl<'a, S: Copy> CodebookDescReader<S> for &'a [FullCodebookDesc<S>] {
445 fn bits(&self, idx: usize) -> u8 {
446 self[idx].bits
447 }
448 fn code(&self, idx: usize) -> u32 {
449 self[idx].code
450 }
451 fn sym(&self, idx: usize) -> S {
452 self[idx].sym
453 }
454 fn len(&self) -> usize {
455 <[FullCodebookDesc<S>]>::len(self)
456 }
457 fn is_empty(&self) -> bool {
458 <[FullCodebookDesc<S>]>::is_empty(self)
459 }
460}
461
462impl<'a> CodebookDescReader<u32> for &'a [ShortCodebookDesc] {
463 fn bits(&self, idx: usize) -> u8 {
464 self[idx].bits
465 }
466 fn code(&self, idx: usize) -> u32 {
467 self[idx].code
468 }
469 fn sym(&self, idx: usize) -> u32 {
470 idx as u32
471 }
472 fn len(&self) -> usize {
473 <[ShortCodebookDesc]>::len(self)
474 }
475 fn is_empty(&self) -> bool {
476 <[ShortCodebookDesc]>::is_empty(self)
477 }
478}
479
480pub struct TableCodebookDescReader<CodeType: 'static, SymType> {
483 bits: &'static [u8],
484 codes: &'static [CodeType],
485 _sym: PhantomData<SymType>,
486}
487
488impl<CodeType, SymType> CodebookDescReader<SymType> for TableCodebookDescReader<CodeType, SymType>
489where
490 CodeType: Copy + Into<u32> + 'static,
491 SymType: Copy + 'static,
492 usize: AsPrimitive<SymType>,
493{
494 fn bits(&self, idx: usize) -> u8 {
495 self.bits[idx]
496 }
497 fn code(&self, idx: usize) -> u32 {
498 self.codes[idx].into()
499 }
500 fn sym(&self, idx: usize) -> SymType {
501 idx.as_()
502 }
503 fn len(&self) -> usize {
504 self.bits.len()
505 }
506 fn is_empty(&self) -> bool {
507 self.bits.is_empty()
508 }
509}
510
511#[cfg(test)]
512mod test {
513 use super::*;
514
515 const BITS: [u8; 8] = [0b01011011, 0b10111100, 0b11111111, 0, 0, 0, 0, 0];
516
517 #[test]
518 fn test_refill_codebook_msb() {
519 let bits = [
521 0b1111_1000,
522 0b0011_1110,
523 0b0000_1111,
524 0b1000_0011,
525 0b1110_0000,
526 0b1111_1000,
527 0b0011_1110,
528 0b0000_1111,
529 0b1000_0000,
530 0,
531 0,
532 0,
533 0,
534 0,
535 0,
536 0,
537 ];
538
539 let cb_desc: Vec<ShortCodebookDesc> = vec![
540 ShortCodebookDesc {
541 code: 0b11111,
542 bits: 5,
543 },
544 ShortCodebookDesc {
545 code: 0b00000,
546 bits: 5,
547 },
548 ];
549 let buf = &bits;
550 let mut br = BitReadBE::new(buf);
551 let cb = Codebook::new(&cb_desc, CodebookMode::MSB).unwrap();
552
553 assert_eq!(br.read_cb(&cb).unwrap(), 0);
554 assert_eq!(br.read_cb(&cb).unwrap(), 1);
555 assert_eq!(br.read_cb(&cb).unwrap(), 0);
556 assert_eq!(br.read_cb(&cb).unwrap(), 1);
557 assert_eq!(br.read_cb(&cb).unwrap(), 0);
558 assert_eq!(br.read_cb(&cb).unwrap(), 1);
559 assert_eq!(br.read_cb(&cb).unwrap(), 0);
560 assert_eq!(br.read_cb(&cb).unwrap(), 1);
561 assert_eq!(br.read_cb(&cb).unwrap(), 0);
562 assert_eq!(br.read_cb(&cb).unwrap(), 1);
563 assert_eq!(br.read_cb(&cb).unwrap(), 0);
564 assert_eq!(br.read_cb(&cb).unwrap(), 1);
565 assert_eq!(br.read_cb(&cb).unwrap(), 0);
566 assert_eq!(br.read_cb(&cb).unwrap(), 1);
567 }
568
569 #[test]
570 fn test_full_codebook_msb() {
571 let cb_desc: Vec<FullCodebookDesc<i8>> = vec![
572 FullCodebookDesc {
573 code: 0b0,
574 bits: 1,
575 sym: 16,
576 },
577 FullCodebookDesc {
578 code: 0b10,
579 bits: 2,
580 sym: -3,
581 },
582 FullCodebookDesc {
583 code: 0b110,
584 bits: 3,
585 sym: 42,
586 },
587 FullCodebookDesc {
588 code: 0b1110,
589 bits: 4,
590 sym: -42,
591 },
592 ];
593 let buf = &BITS;
594 let mut br = BitReadBE::new(buf);
595 let cb = Codebook::new(&cb_desc, CodebookMode::MSB).unwrap();
596
597 assert_eq!(br.read_cb(&cb).unwrap(), 16);
598 assert_eq!(br.read_cb(&cb).unwrap(), -3);
599 assert_eq!(br.read_cb(&cb).unwrap(), 42);
600 assert_eq!(br.read_cb(&cb).unwrap(), -42);
601 let ret = br.read_cb(&cb);
602 if let Err(e) = ret {
603 assert_matches::assert_matches!(e, InvalidCode);
604 } else {
605 assert_eq!(0, 1);
606 }
607 }
608
609 #[test]
610 fn test_short_codebook_msb() {
611 let scb_desc: Vec<ShortCodebookDesc> = vec![
612 ShortCodebookDesc { code: 0b0, bits: 1 },
613 ShortCodebookDesc { code: 0, bits: 0 },
614 ShortCodebookDesc {
615 code: 0b10,
616 bits: 2,
617 },
618 ShortCodebookDesc { code: 0, bits: 0 },
619 ShortCodebookDesc { code: 0, bits: 0 },
620 ShortCodebookDesc {
621 code: 0b110,
622 bits: 3,
623 },
624 ShortCodebookDesc { code: 0, bits: 0 },
625 ShortCodebookDesc {
626 code: 0b11100,
627 bits: 5,
628 },
629 ShortCodebookDesc {
630 code: 0b11101,
631 bits: 5,
632 },
633 ShortCodebookDesc {
634 code: 0b1111010,
635 bits: 7,
636 },
637 ShortCodebookDesc {
638 code: 0b1111011,
639 bits: 7,
640 },
641 ShortCodebookDesc {
642 code: 0b1111110,
643 bits: 7,
644 },
645 ShortCodebookDesc {
646 code: 0b11111111,
647 bits: 8,
648 },
649 ];
650 let buf = &BITS;
651 let mut br2 = BitReadBE::new(buf);
652 let cb = Codebook::new(&scb_desc, CodebookMode::MSB).unwrap();
653 assert_eq!(br2.read_cb(&cb).unwrap(), 0);
654 assert_eq!(br2.read_cb(&cb).unwrap(), 2);
655 assert_eq!(br2.read_cb(&cb).unwrap(), 5);
656 assert_eq!(br2.read_cb(&cb).unwrap(), 8);
657
658 assert_eq!(
659 reverse_bits(0b0000_0101_1011_1011_1101_1111_0111_1111),
660 0b1111_1110_1111_1011_1101_1101_1010_0000
661 );
662 }
663
664 #[test]
665 fn test_short_codebook_lsb() {
666 const BITS_LE: [u8; 8] = [0b11101111, 0b01110010, 0b01, 0, 0, 0, 0, 0];
667 let buf = &BITS_LE;
668 let scble_desc: Vec<ShortCodebookDesc> = vec![
669 ShortCodebookDesc {
670 code: 0b00,
671 bits: 2,
672 },
673 ShortCodebookDesc { code: 0, bits: 0 },
674 ShortCodebookDesc {
675 code: 0b01,
676 bits: 2,
677 },
678 ShortCodebookDesc { code: 0, bits: 0 },
679 ShortCodebookDesc { code: 0, bits: 0 },
680 ShortCodebookDesc {
681 code: 0b011,
682 bits: 3,
683 },
684 ShortCodebookDesc { code: 0, bits: 0 },
685 ShortCodebookDesc {
686 code: 0b10111,
687 bits: 5,
688 },
689 ShortCodebookDesc {
690 code: 0b00111,
691 bits: 5,
692 },
693 ShortCodebookDesc {
694 code: 0b0101111,
695 bits: 7,
696 },
697 ShortCodebookDesc {
698 code: 0b0111111,
699 bits: 7,
700 },
701 ShortCodebookDesc {
702 code: 0b1011101111,
703 bits: 10,
704 },
705 ];
706 let mut brl = BitReadLE::new(buf);
707 let cb = Codebook::new(&scble_desc, CodebookMode::LSB).unwrap();
708 assert_eq!(brl.read_cb(&cb).unwrap(), 11);
709 assert_eq!(brl.read_cb(&cb).unwrap(), 0);
710 assert_eq!(brl.read_cb(&cb).unwrap(), 7);
711 assert_eq!(brl.read_cb(&cb).unwrap(), 0);
712 }
713}