]> git.nihav.org Git - nihav.git/blobdiff - src/codecs/indeo/indeo4.rs
GremlinVideo audio decoder
[nihav.git] / src / codecs / indeo / indeo4.rs
index 1c95c60fd5da0c9f8ada795a8aada4ad03fbfdf3..773b17724cc26063712d601095a5fb21a213d344 100644 (file)
@@ -1,10 +1,16 @@
 use std::cell::Ref;
-use io::bitreader::*;
-use formats;
+use crate::io::bitreader::*;
+use crate::formats;
 use super::super::*;
 use super::ivi::*;
 use super::ivibr::*;
 
+#[inline(always)]
+fn mclip8(a: i32) -> u8 {
+    if (a as u16) > 255 { !(a >> 16) as u8 }
+    else { a as u8 }
+}
+
 struct Indeo4Parser {
     mb_cb:          IVICodebook,
     blk_cb:         IVICodebook,
@@ -195,7 +201,6 @@ impl IndeoXParser for Indeo4Parser {
 
         let blk_cb;
         if br.read_bool()? {
-            
             blk_cb = br.read_ivi_codebook_desc(false, true)?;
         } else {
             blk_cb = self.blk_cb;
@@ -331,7 +336,7 @@ impl IndeoXParser for Indeo4Parser {
     }
 
     fn recombine_plane(&mut self, src: &[i16], sstride: usize, dst: &mut [u8], dstride: usize, w: usize, h: usize) {
-        let mut idx0 = 0;
+/*        let mut idx0 = 0;
         let mut idx1 = w / 2;
         let mut idx2 = (h / 2) * sstride;
         let mut idx3 = idx2 + idx1;
@@ -344,10 +349,14 @@ impl IndeoXParser for Indeo4Parser {
                 let p1 = src[idx1 + x];
                 let p2 = src[idx2 + x];
                 let p3 = src[idx3 + x];
-                dst[oidx0 + x * 2 + 0] = clip8(((p0 + p1 + p2 + p3 + 2) >> 2) + 128);
-                dst[oidx0 + x * 2 + 1] = clip8(((p0 + p1 - p2 - p3 + 2) >> 2) + 128);
-                dst[oidx1 + x * 2 + 0] = clip8(((p0 - p1 + p2 - p3 + 2) >> 2) + 128);
-                dst[oidx1 + x * 2 + 1] = clip8(((p0 - p1 - p2 + p3 + 2) >> 2) + 128);
+                let s0 = p0 + p2;
+                let d0 = p0 - p2;
+                let s1 = p1 + p3;
+                let d1 = p1 - p3;
+                dst[oidx0 + x * 2 + 0] = clip8(((s0 + s1 + 2) >> 2) + 128);
+                dst[oidx0 + x * 2 + 1] = clip8(((d0 + d1 + 2) >> 2) + 128);
+                dst[oidx1 + x * 2 + 0] = clip8(((s0 - s1 + 2) >> 2) + 128);
+                dst[oidx1 + x * 2 + 1] = clip8(((d0 - d1 + 2) >> 2) + 128);
             }
             idx0 += sstride;
             idx1 += sstride;
@@ -355,6 +364,54 @@ impl IndeoXParser for Indeo4Parser {
             idx3 += sstride;
             oidx0 += dstride * 2;
             oidx1 += dstride * 2;
+        }*/
+        unsafe {
+            let hw = (w / 2) as isize;
+            let hh = (h / 2) as isize;
+            let mut band0 = src.as_ptr();
+            let mut band1 = band0.offset(hw);
+            let mut band2 = band0.offset(((h / 2) * sstride) as isize);
+            let mut band3 = band2.offset(hw);
+            let mut dst0 = dst.as_mut_ptr();
+            let mut dst1 = dst0.offset(dstride as isize);
+            for _ in 0..hh {
+                let mut b0_ptr = band0;
+                let mut b1_ptr = band1;
+                let mut b2_ptr = band2;
+                let mut b3_ptr = band3;
+                let mut d0_ptr = dst0;
+                let mut d1_ptr = dst1;
+                for _ in 0..hw {
+                    let p0 = *b0_ptr as i32;
+                    let p1 = *b1_ptr as i32;
+                    let p2 = *b2_ptr as i32;
+                    let p3 = *b3_ptr as i32;
+                    let s0 = p0.wrapping_add(p2);
+                    let s1 = p1.wrapping_add(p3);
+                    let d0 = p0.wrapping_sub(p2);
+                    let d1 = p1.wrapping_sub(p3);
+                    let o0 = s0.wrapping_add(s1).wrapping_add(2);
+                    let o1 = d0.wrapping_add(d1).wrapping_add(2);
+                    let o2 = s0.wrapping_sub(s1).wrapping_add(2);
+                    let o3 = d0.wrapping_sub(d1).wrapping_add(2);
+                    *d0_ptr.offset(0) = mclip8((o0 >> 2).wrapping_add(128));
+                    *d0_ptr.offset(1) = mclip8((o1 >> 2).wrapping_add(128));
+                    *d1_ptr.offset(0) = mclip8((o2 >> 2).wrapping_add(128));
+                    *d1_ptr.offset(1) = mclip8((o3 >> 2).wrapping_add(128));
+                    b0_ptr = b0_ptr.offset(1);
+                    b1_ptr = b1_ptr.offset(1);
+                    b2_ptr = b2_ptr.offset(1);
+                    b3_ptr = b3_ptr.offset(1);
+                    d0_ptr = d0_ptr.offset(2);
+                    d1_ptr = d1_ptr.offset(2);
+                }
+                band0 = band0.offset(sstride as isize);
+                band1 = band1.offset(sstride as isize);
+                band2 = band2.offset(sstride as isize);
+                band3 = band3.offset(sstride as isize);
+                dst0 = dst0.offset((dstride * 2) as isize);
+                dst1 = dst1.offset((dstride * 2) as isize);
+            }
         }
     }
 }
@@ -401,7 +458,7 @@ impl NADecoder for Indeo4Decoder {
 }
 
 const INDEO4_PICTURE_SIZE_TAB: [[usize; 2]; 7] = [
-    [640, 480], [320, 240], [160, 120], [704, 480], [352, 240], [252, 288], [176, 144]
+    [640, 480], [320, 240], [160, 120], [704, 480], [352, 240], [352, 288], [176, 144]
 ];
 
 const INDEO4_SLICE_SIZE_TAB: [usize; 15] = [
@@ -707,10 +764,10 @@ pub fn get_decoder() -> Box<NADecoder> {
 
 #[cfg(test)]
 mod test {
-    use test::dec_video::test_file_decoding;
+    use crate::test::dec_video::test_file_decoding;
     #[test]
     fn test_indeo4() {
-         test_file_decoding("avi", "assets/IV4/volcano.avi", /*None*/Some(16), true, false, Some("iv4"));
-panic!("the end");
+         test_file_decoding("avi", "assets/IV4/volcano.avi", /*None*/Some(16), true, false, None/*Some("iv4")*/);
+//panic!("the end");
     }
 }