]> git.nihav.org Git - nihav.git/blobdiff - src/io/codebook.rs
codebook: reject invalid codes
[nihav.git] / src / io / codebook.rs
index d67e790fe77a339b1be3e85af5090fcf73047f87..3d1e8d0e0112e2d2032788e6723bfb17f06014a0 100644 (file)
@@ -195,7 +195,12 @@ impl<S: Copy> Codebook<S> {
         let mut symidx: usize = 0;
         for i in 0..cb.len() {
             let bits = cb.bits(i);
-            if bits > 0 { nnz = nnz + 1; }
+            if bits > 0 {
+                nnz = nnz + 1;
+                if cb.code(i) >= (1 << bits) {
+                    return Err(CodebookError::InvalidCodebook);
+                }
+            }
             maxbits = max(bits, maxbits);
             if bits > MAX_LUT_BITS {
                 let code = cb.code(i);
@@ -309,6 +314,25 @@ impl CodebookDescReader<u32> for ShortCodebookDescReader {
     fn len(&mut self) -> usize { self.data.len() }
 }
 
+pub struct TableCodebookDescReader<CodeType:'static, IndexType:'static> {
+    bits:       &'static [u8],
+    codes:      &'static [CodeType],
+    idx_map:    fn(usize) -> IndexType,
+}
+
+impl<'a, CodeType, IndexType> TableCodebookDescReader<CodeType, IndexType> {
+    pub fn new(codes: &'static [CodeType], bits: &'static [u8], idx_map: fn(usize) -> IndexType) -> Self {
+        Self { bits, codes, idx_map }
+    }
+}
+impl<CodeType: Copy+Into<u32>, IndexType> CodebookDescReader<IndexType> for TableCodebookDescReader<CodeType, IndexType>
+{
+    fn bits(&mut self, idx: usize) -> u8  { self.bits[idx] }
+    fn code(&mut self, idx: usize) -> u32 { self.codes[idx].into() }
+    fn sym (&mut self, idx: usize) -> IndexType { (self.idx_map)(idx) }
+    fn len(&mut self) -> usize { self.bits.len() }
+}
+
 #[cfg(test)]
 mod test {
     use super::*;