bink2: correct KB2f IDCT
[nihav.git] / nihav-rad / src / codecs / bink2.rs
index 4a4f5108587761c1238fb5d2062cba1a5e15bad8..5760286866fde4f224e0ff43c79eafed321d33ca 100644 (file)
@@ -85,6 +85,7 @@ fn bink2_idct(coeffs: &mut [i32; 64]) {
 
 fn bink2_idct_old(coeffs: &mut [f32; 64]) {
     let mut tmp: [f32; 64] = [0.0; 64];
+    coeffs[0] += 512.5;
     for i in 0..8 {
         idct!(float; coeffs, 8, i, tmp, 8, i, 0, 0);
     }
@@ -133,13 +134,30 @@ macro_rules! chroma_interp {
     };
 }
 
+macro_rules! avg_tree {
+    ($a: expr, $b: expr) => (($a + $b + 1) >> 1);
+    ($a: expr, $b: expr, $c: expr, $d: expr) => (avg_tree!(avg_tree!($a, $b), avg_tree!($c, $d)));
+}
+
 impl Bink2DSP {
     fn calc_dc(src: &[u8], stride: usize) -> i32 {
+        let mut sums = [0u16; 8];
+        for i in 0..8 {
+            let s0 = src[i + stride * 0] as u16;
+            let s1 = src[i + stride * 1] as u16;
+            let s2 = src[i + stride * 2] as u16;
+            let s3 = src[i + stride * 3] as u16;
+            let s4 = src[i + stride * 4] as u16;
+            let s5 = src[i + stride * 5] as u16;
+            let s6 = src[i + stride * 6] as u16;
+            let s7 = src[i + stride * 7] as u16;
+            sums[i] = avg_tree!(avg_tree!(s0, s1, s2, s3), avg_tree!(s4, s5, s6, s7));
+        }
         let mut sum = 0;
-        for row in src.chunks(stride).take(8) {
-            for i in 0..8 { sum += row[i] as i32; }
+        for e in sums.iter() {
+            sum += e;
         }
-        sum >> 3
+        sum as i32
     }
     fn put_mb4(dst: &mut [u8], mut off: usize, stride: usize, blk: &mut [[i32; 64]; 4]) {
         bink2_idct(&mut blk[0]);
@@ -191,16 +209,16 @@ impl Bink2DSP {
         {
             let dout = &mut dst[off..];
             for (row, (b0, b1)) in dout.chunks_mut(stride).zip(blk[0].chunks(8).zip(blk[1].chunks(8))) {
-                for i in 0..8 { row[i + 0] = clip8(b0[i] as i32); }
-                for i in 0..8 { row[i + 8] = clip8(b1[i] as i32); }
+                for i in 0..8 { row[i + 0] = clip8((b0[i] as i32) - 512); }
+                for i in 0..8 { row[i + 8] = clip8((b1[i] as i32) - 512); }
             }
         }
         off += stride * 8;
         {
             let dout = &mut dst[off..];
             for (row, (b2, b3)) in dout.chunks_mut(stride).zip(blk[2].chunks(8).zip(blk[3].chunks(8))) {
-                for i in 0..8 { row[i + 0] = clip8(b2[i] as i32); }
-                for i in 0..8 { row[i + 8] = clip8(b3[i] as i32); }
+                for i in 0..8 { row[i + 0] = clip8((b2[i] as i32) - 512); }
+                for i in 0..8 { row[i + 8] = clip8((b3[i] as i32) - 512); }
             }
         }
     }
@@ -212,16 +230,16 @@ impl Bink2DSP {
         {
             let dout = &mut dst[off..];
             for (row, (b0, b1)) in dout.chunks_mut(stride).zip(blk[0].chunks(8).zip(blk[1].chunks(8))) {
-                for i in 0..8 { row[i + 0] = clip8((row[i + 0] as i32) + (b0[i] as i32)); }
-                for i in 0..8 { row[i + 8] = clip8((row[i + 8] as i32) + (b1[i] as i32)); }
+                for i in 0..8 { row[i + 0] = clip8((row[i + 0] as i32) + (b0[i] as i32) - 512); }
+                for i in 0..8 { row[i + 8] = clip8((row[i + 8] as i32) + (b1[i] as i32) - 512); }
             }
         }
         off += stride * 8;
         {
             let dout = &mut dst[off..];
             for (row, (b2, b3)) in dout.chunks_mut(stride).zip(blk[2].chunks(8).zip(blk[3].chunks(8))) {
-                for i in 0..8 { row[i + 0] = clip8((row[i + 0] as i32) + (b2[i] as i32)); }
-                for i in 0..8 { row[i + 8] = clip8((row[i + 8] as i32) + (b3[i] as i32)); }
+                for i in 0..8 { row[i + 0] = clip8((row[i + 0] as i32) + (b2[i] as i32) - 512); }
+                for i in 0..8 { row[i + 8] = clip8((row[i + 8] as i32) + (b3[i] as i32) - 512); }
             }
         }
     }
@@ -1831,7 +1849,7 @@ mod test {
         //let file = "assets/RAD/sc13_01_partial.bk2";
         let file = "assets/RAD/ge_video_86l.bk2";
         //let file = "assets/RAD/eg_club_0.bk2";
-        test_file_decoding("bink", file, Some(42), true, false, Some("bink2"), &dmx_reg, &dec_reg);
+        test_file_decoding("bink", file, Some(8), true, false, None/*Some("bink2")*/, &dmx_reg, &dec_reg);
     }
 }