pub struct Source<'a> {
pub data: &'a [u8],
pub stride: usize,
pub num_samples: usize,
}
pub fn mix16(input: Source, u: &mut [i32], v: &mut [i32], mixbits: i32, mixres: i32) {
if mixres != 0 {
let modulo: i32 = 1 << mixbits;
let m2: i32 = modulo - mixres;
for j in 0..input.num_samples {
let l = i16::from_le_bytes([input.data[j * input.stride * 2], input.data[j * input.stride * 2 + 1]]) as i32;
let r = i16::from_le_bytes([input.data[j * input.stride * 2 + 2], input.data[j * input.stride * 2 + 3]]) as i32;
u[j] = (mixres * l + m2 * r) >> mixbits;
v[j] = l - r;
}
} else {
for j in 0..input.num_samples {
u[j] = i16::from_le_bytes([input.data[j * input.stride * 2], input.data[j * input.stride * 2 + 1]]) as i32;
v[j] = i16::from_le_bytes([input.data[j * input.stride * 2 + 2], input.data[j * input.stride * 2 + 3]]) as i32;
}
}
}
pub fn mix20(input: Source, u: &mut [i32], v: &mut [i32], mixbits: i32, mixres: i32) {
if mixres != 0 {
let modulo: i32 = 1 << mixbits;
let m2: i32 = modulo - mixres;
for j in 0..input.num_samples {
let l = (i32::from_be_bytes([0, input.data[j * input.stride * 3], input.data[j * input.stride * 3 + 1], input.data[j * input.stride * 3 + 2]]) << 8) >> 12;
let r = (i32::from_be_bytes([0, input.data[j * input.stride * 3 + 3], input.data[j * input.stride * 3 + 4], input.data[j * input.stride * 3 + 5]]) << 8) >> 12;
u[j] = (mixres * l + m2 * r) >> mixbits;
v[j] = l - r;
}
} else {
for j in 0..input.num_samples {
u[j] = (i32::from_be_bytes([0, input.data[j * input.stride * 3], input.data[j * input.stride * 3 + 1], input.data[j * input.stride * 3 + 2]]) << 8) >> 12;
v[j] = (i32::from_be_bytes([0, input.data[j * input.stride * 3 + 3], input.data[j * input.stride * 3 + 4], input.data[j * input.stride * 3 + 5]]) << 8) >> 12;
}
}
}
pub fn mix24(input: Source, u: &mut [i32], v: &mut [i32], mixbits: i32, mixres: i32, shift_uv: &mut [u16], bytes_shifted: usize) {
debug_assert!(bytes_shifted <= 2);
let shift = bytes_shifted * 8;
let mask = (1u32 << shift) - 1;
if mixres != 0 {
let modulo = 1 << mixbits;
let m2 = modulo - mixres;
if bytes_shifted != 0 {
for j in 0..input.num_samples {
let l = (i32::from_be_bytes([0, input.data[j * input.stride * 3], input.data[j * input.stride * 3 + 1], input.data[j * input.stride * 3 + 2]]) << 8) >> 8;
let r = (i32::from_be_bytes([0, input.data[j * input.stride * 3 + 3], input.data[j * input.stride * 3 + 4], input.data[j * input.stride * 3 + 5]]) << 8) >> 8;
shift_uv[j * 2] = ((l as u32) & mask) as u16;
shift_uv[j * 2 + 1] = ((r as u32) & mask) as u16;
let l = l >> shift;
let r = r >> shift;
u[j] = (mixres * l + m2 * r) >> mixbits;
v[j] = l - r;
}
} else {
for j in 0..input.num_samples {
let l = (i32::from_be_bytes([0, input.data[j * input.stride * 3], input.data[j * input.stride * 3 + 1], input.data[j * input.stride * 3 + 2]]) << 8) >> 8;
let r = (i32::from_be_bytes([0, input.data[j * input.stride * 3 + 3], input.data[j * input.stride * 3 + 4], input.data[j * input.stride * 3 + 5]]) << 8) >> 8;
u[j] = (mixres * l + m2 * r) >> mixbits;
v[j] = l - r;
}
}
} else {
if bytes_shifted != 0 {
for j in 0..input.num_samples {
let l = (i32::from_be_bytes([0, input.data[j * input.stride * 3], input.data[j * input.stride * 3 + 1], input.data[j * input.stride * 3 + 2]]) << 8) >> 8;
let r = (i32::from_be_bytes([0, input.data[j * input.stride * 3 + 3], input.data[j * input.stride * 3 + 4], input.data[j * input.stride * 3 + 5]]) << 8) >> 8;
shift_uv[j * 2] = ((l as u32) & mask) as u16;
shift_uv[j * 2 + 1] = ((r as u32) & mask) as u16;
u[j] = l >> shift;
v[j] = r >> shift;
}
} else {
for j in 0..input.num_samples {
u[j] = (i32::from_be_bytes([0, input.data[j * input.stride * 3], input.data[j * input.stride * 3 + 1], input.data[j * input.stride * 3 + 2]]) << 8) >> 8;
v[j] = (i32::from_be_bytes([0, input.data[j * input.stride * 3 + 3], input.data[j * input.stride * 3 + 4], input.data[j * input.stride * 3 + 5]]) << 8) >> 8;
}
}
}
}
pub fn mix32(input: Source, u: &mut [i32], v: &mut [i32], mixbits: i32, mixres: i32, shift_uv: &mut [u16], bytes_shifted: usize) {
debug_assert!(bytes_shifted <= 2);
let shift = bytes_shifted * 8;
let mask = (1u32 << shift) - 1;
if mixres != 0 {
debug_assert!(bytes_shifted != 0);
let modulo = 1 << mixbits;
let m2 = modulo - mixres;
for j in 0..input.num_samples {
let l = i32::from_le_bytes([input.data[j * input.stride * 4], input.data[j * input.stride * 4 + 1], input.data[j * input.stride * 4 + 2], input.data[j * input.stride * 4 + 3]]);
let r = i32::from_le_bytes([input.data[j * input.stride * 4 + 4], input.data[j * input.stride * 4 + 5], input.data[j * input.stride * 4 + 6], input.data[j * input.stride * 4 + 7]]);
shift_uv[j * 2] = ((l as u32) & mask) as u16;
shift_uv[j * 2 + 1] = ((r as u32) & mask) as u16;
let l = l >> shift;
let r = r >> shift;
u[j] = (mixres * l + m2 * r) >> mixbits;
v[j] = l - r;
}
} else if bytes_shifted != 0 {
for j in 0..input.num_samples {
let l = i32::from_le_bytes([input.data[j * input.stride * 4], input.data[j * input.stride * 4 + 1], input.data[j * input.stride * 4 + 2], input.data[j * input.stride * 4 + 3]]);
let r = i32::from_le_bytes([input.data[j * input.stride * 4 + 4], input.data[j * input.stride * 4 + 5], input.data[j * input.stride * 4 + 6], input.data[j * input.stride * 4 + 7]]);
shift_uv[j * 2] = ((l as u32) & mask) as u16;
shift_uv[j * 2 + 1] = ((r as u32) & mask) as u16;
u[j] = l >> shift;
v[j] = r >> shift;
}
} else {
for j in 0..input.num_samples {
u[j] = i32::from_le_bytes([input.data[j * input.stride * 4], input.data[j * input.stride * 4 + 1], input.data[j * input.stride * 4 + 2], input.data[j * input.stride * 4 + 3]]);
v[j] = i32::from_le_bytes([input.data[j * input.stride * 4 + 4], input.data[j * input.stride * 4 + 5], input.data[j * input.stride * 4 + 6], input.data[j * input.stride * 4 + 7]]);
}
}
}
pub fn copy20_to_predictor(input: &[u8], stride: usize, output: &mut [i32], num_samples: usize) {
for j in 0..num_samples {
let val = i32::from_be_bytes([0, input[j * stride * 3], input[j * stride * 3 + 1], input[j * stride * 3 + 2]]);
output[j] = (val << 8) >> 12;
}
}
pub fn copy24_to_predictor(input: &[u8], stride: usize, output: &mut [i32], num_samples: usize) {
for j in 0..num_samples {
let val = i32::from_be_bytes([0, input[j * stride * 3], input[j * stride * 3 + 1], input[j * stride * 3 + 2]]);
output[j] = (val << 8) >> 8;
}
}