pub fn do_nothing(src: &[i16; 64], dst: &mut [i16; 64]) {
dst.copy_from_slice(src);
}
pub fn do_flip_h(src: &[i16; 64], dst: &mut [i16; 64]) {
for row in 0..8 {
for col in 0..8 {
let idx = row * 8 + col;
dst[idx] = if col % 2 == 1 { -src[idx] } else { src[idx] };
}
}
}
pub fn do_flip_v(src: &[i16; 64], dst: &mut [i16; 64]) {
for row in 0..8 {
for col in 0..8 {
let idx = row * 8 + col;
dst[idx] = if row % 2 == 1 { -src[idx] } else { src[idx] };
}
}
}
pub fn do_transpose(src: &[i16; 64], dst: &mut [i16; 64]) {
for row in 0..8 {
for col in 0..8 {
dst[col * 8 + row] = src[row * 8 + col];
}
}
}
pub fn do_transverse(src: &[i16; 64], dst: &mut [i16; 64]) {
for row in 0..8 {
for col in 0..8 {
let sign = if (row + col) % 2 == 1 { -1 } else { 1 };
dst[col * 8 + row] = src[row * 8 + col] * sign;
}
}
}
pub fn do_rot_90(src: &[i16; 64], dst: &mut [i16; 64]) {
let mut tmp = [0i16; 64];
do_transpose(src, &mut tmp);
do_flip_h(&tmp, dst);
}
pub fn do_rot_180(src: &[i16; 64], dst: &mut [i16; 64]) {
for row in 0..8 {
for col in 0..8 {
let idx = row * 8 + col;
let sign = if (row + col) % 2 == 1 { -1 } else { 1 };
dst[idx] = src[idx] * sign;
}
}
}
pub fn do_rot_270(src: &[i16; 64], dst: &mut [i16; 64]) {
let mut tmp = [0i16; 64];
do_transpose(src, &mut tmp);
do_flip_v(&tmp, dst);
}
#[cfg(test)]
mod tests {
use super::*;
fn make_test_block() -> [i16; 64] {
let mut block = [0i16; 64];
for i in 0..64 {
block[i] = (i + 1) as i16;
}
block
}
#[test]
fn nothing_is_identity() {
let src = make_test_block();
let mut dst = [0i16; 64];
do_nothing(&src, &mut dst);
assert_eq!(src, dst);
}
#[test]
fn double_hflip_is_identity() {
let src = make_test_block();
let mut tmp = [0i16; 64];
let mut dst = [0i16; 64];
do_flip_h(&src, &mut tmp);
do_flip_h(&tmp, &mut dst);
assert_eq!(src, dst);
}
#[test]
fn double_vflip_is_identity() {
let src = make_test_block();
let mut tmp = [0i16; 64];
let mut dst = [0i16; 64];
do_flip_v(&src, &mut tmp);
do_flip_v(&tmp, &mut dst);
assert_eq!(src, dst);
}
#[test]
fn double_transpose_is_identity() {
let src = make_test_block();
let mut tmp = [0i16; 64];
let mut dst = [0i16; 64];
do_transpose(&src, &mut tmp);
do_transpose(&tmp, &mut dst);
assert_eq!(src, dst);
}
#[test]
fn rot180_is_double_identity() {
let src = make_test_block();
let mut tmp = [0i16; 64];
let mut dst = [0i16; 64];
do_rot_180(&src, &mut tmp);
do_rot_180(&tmp, &mut dst);
assert_eq!(src, dst);
}
#[test]
fn four_rot90_is_identity() {
let src = make_test_block();
let mut a = [0i16; 64];
let mut b = [0i16; 64];
do_rot_90(&src, &mut a);
do_rot_90(&a, &mut b);
do_rot_90(&b, &mut a);
do_rot_90(&a, &mut b);
assert_eq!(src, b);
}
#[test]
fn hflip_negates_odd_columns() {
let src = make_test_block();
let mut dst = [0i16; 64];
do_flip_h(&src, &mut dst);
assert_eq!(dst[0], src[0]);
assert_eq!(dst[1], -src[1]);
assert_eq!(dst[2], src[2]);
}
}