| 1 | static CONST1: i64 = 20091; |
| 2 | static CONST2: i64 = 35468; |
| 3 | |
| 4 | pub(crate) fn idct4x4(block: &mut [i32]) { |
| 5 | // The intermediate results may overflow the types, so we stretch the type. |
| 6 | fn fetch(block: &[i32], idx: usize) -> i64 { |
| 7 | i64::from(block[idx]) |
| 8 | } |
| 9 | |
| 10 | // Perform one lenght check up front to avoid subsequent bounds checks in this function |
| 11 | assert!(block.len() >= 16); |
| 12 | |
| 13 | for i in 0usize..4 { |
| 14 | let a1 = fetch(block, i) + fetch(block, 8 + i); |
| 15 | let b1 = fetch(block, i) - fetch(block, 8 + i); |
| 16 | |
| 17 | let t1 = (fetch(block, 4 + i) * CONST2) >> 16; |
| 18 | let t2 = fetch(block, 12 + i) + ((fetch(block, 12 + i) * CONST1) >> 16); |
| 19 | let c1 = t1 - t2; |
| 20 | |
| 21 | let t1 = fetch(block, 4 + i) + ((fetch(block, 4 + i) * CONST1) >> 16); |
| 22 | let t2 = (fetch(block, 12 + i) * CONST2) >> 16; |
| 23 | let d1 = t1 + t2; |
| 24 | |
| 25 | block[i] = (a1 + d1) as i32; |
| 26 | block[4 + i] = (b1 + c1) as i32; |
| 27 | block[4 * 3 + i] = (a1 - d1) as i32; |
| 28 | block[4 * 2 + i] = (b1 - c1) as i32; |
| 29 | } |
| 30 | |
| 31 | for i in 0usize..4 { |
| 32 | let a1 = fetch(block, 4 * i) + fetch(block, 4 * i + 2); |
| 33 | let b1 = fetch(block, 4 * i) - fetch(block, 4 * i + 2); |
| 34 | |
| 35 | let t1 = (fetch(block, 4 * i + 1) * CONST2) >> 16; |
| 36 | let t2 = fetch(block, 4 * i + 3) + ((fetch(block, 4 * i + 3) * CONST1) >> 16); |
| 37 | let c1 = t1 - t2; |
| 38 | |
| 39 | let t1 = fetch(block, 4 * i + 1) + ((fetch(block, 4 * i + 1) * CONST1) >> 16); |
| 40 | let t2 = (fetch(block, 4 * i + 3) * CONST2) >> 16; |
| 41 | let d1 = t1 + t2; |
| 42 | |
| 43 | block[4 * i] = ((a1 + d1 + 4) >> 3) as i32; |
| 44 | block[4 * i + 3] = ((a1 - d1 + 4) >> 3) as i32; |
| 45 | block[4 * i + 1] = ((b1 + c1 + 4) >> 3) as i32; |
| 46 | block[4 * i + 2] = ((b1 - c1 + 4) >> 3) as i32; |
| 47 | } |
| 48 | } |
| 49 | |
| 50 | // 14.3 |
| 51 | pub(crate) fn iwht4x4(block: &mut [i32]) { |
| 52 | // Perform one length check up front to avoid subsequent bounds checks in this function |
| 53 | assert!(block.len() >= 16); |
| 54 | |
| 55 | for i in 0usize..4 { |
| 56 | let a1 = block[i] + block[12 + i]; |
| 57 | let b1 = block[4 + i] + block[8 + i]; |
| 58 | let c1 = block[4 + i] - block[8 + i]; |
| 59 | let d1 = block[i] - block[12 + i]; |
| 60 | |
| 61 | block[i] = a1 + b1; |
| 62 | block[4 + i] = c1 + d1; |
| 63 | block[8 + i] = a1 - b1; |
| 64 | block[12 + i] = d1 - c1; |
| 65 | } |
| 66 | |
| 67 | for block in block.chunks_exact_mut(4) { |
| 68 | let a1 = block[0] + block[3]; |
| 69 | let b1 = block[1] + block[2]; |
| 70 | let c1 = block[1] - block[2]; |
| 71 | let d1 = block[0] - block[3]; |
| 72 | |
| 73 | let a2 = a1 + b1; |
| 74 | let b2 = c1 + d1; |
| 75 | let c2 = a1 - b1; |
| 76 | let d2 = d1 - c1; |
| 77 | |
| 78 | block[0] = (a2 + 3) >> 3; |
| 79 | block[1] = (b2 + 3) >> 3; |
| 80 | block[2] = (c2 + 3) >> 3; |
| 81 | block[3] = (d2 + 3) >> 3; |
| 82 | } |
| 83 | } |
| 84 | |