更新libclamav库1.0.0版本

This commit is contained in:
2023-01-14 18:28:39 +08:00
parent b879ee0b2e
commit 45fe15f472
8531 changed files with 1222046 additions and 177272 deletions

View File

@@ -0,0 +1,520 @@
pub struct KnownTestValues {
pub input: Vec<f64>,
pub expected_output: Vec<f64>,
}
// [Autogenerated Test Tata]
// known input/output values for DCT Type 1
pub fn known_values_dct1() -> Vec<KnownTestValues> {
vec![
KnownTestValues {
input: vec![0.0, 0.0],
expected_output: vec![0.0, 0.0],
},
KnownTestValues {
input: vec![0.0, 0.0, 0.0],
expected_output: vec![0.0, 0.0, 0.0],
},
KnownTestValues {
input: vec![0.0, 0.0, 0.0, 0.0],
expected_output: vec![0.0, 0.0, 0.0, 0.0],
},
KnownTestValues {
input: vec![0.0, 0.0, 0.0, 0.0, 0.0],
expected_output: vec![0.0, 0.0, 0.0, 0.0, 0.0],
},
KnownTestValues {
input: vec![1.0, 1.0],
expected_output: vec![1.0, 0.0],
},
KnownTestValues {
input: vec![1.0, 1.0, 1.0],
expected_output: vec![2.0, 0.0, 0.0],
},
KnownTestValues {
input: vec![1.0, 1.0, 1.0, 1.0],
expected_output: vec![3.0, 0.0, 0.0, 0.0],
},
KnownTestValues {
input: vec![1.0, 1.0, 1.0, 1.0, 1.0],
expected_output: vec![4.0, 0.0, 0.0, 0.0, 0.0],
},
KnownTestValues {
input: vec![3.3, 5.9],
expected_output: vec![4.6, -1.3],
},
KnownTestValues {
input: vec![3.3, 5.9, -1.9],
expected_output: vec![6.6, 2.6, -5.2],
},
KnownTestValues {
input: vec![3.3, 5.9, -1.9, 6.25],
expected_output: vec![8.775, 2.425, 2.775, -9.275],
},
KnownTestValues {
input: vec![3.3, 5.9, -1.9, 6.25, 0.6],
expected_output: vec![12.2, 1.1025, 3.85, 1.5975, -12.1],
},
]
}
// known input/output values for DCT Type 2
pub fn known_values_dct2() -> Vec<KnownTestValues> {
vec![
KnownTestValues {
input: vec![0.0],
expected_output: vec![0.0],
},
KnownTestValues {
input: vec![0.0, 0.0],
expected_output: vec![0.0, 0.0],
},
KnownTestValues {
input: vec![0.0, 0.0, 0.0],
expected_output: vec![0.0, 0.0, 0.0],
},
KnownTestValues {
input: vec![0.0, 0.0, 0.0, 0.0],
expected_output: vec![0.0, 0.0, 0.0, 0.0],
},
KnownTestValues {
input: vec![0.0, 0.0, 0.0, 0.0, 0.0],
expected_output: vec![0.0, 0.0, 0.0, 0.0, 0.0],
},
KnownTestValues {
input: vec![1.0],
expected_output: vec![1.0],
},
KnownTestValues {
input: vec![1.0, 1.0],
expected_output: vec![2.0, 0.0],
},
KnownTestValues {
input: vec![1.0, 1.0, 1.0],
expected_output: vec![3.0, 0.0, 0.0],
},
KnownTestValues {
input: vec![1.0, 1.0, 1.0, 1.0],
expected_output: vec![4.0, 0.0, 0.0, 0.0],
},
KnownTestValues {
input: vec![1.0, 1.0, 1.0, 1.0, 1.0],
expected_output: vec![5.0, 0.0, 0.0, 0.0, 0.0],
},
KnownTestValues {
input: vec![3.3],
expected_output: vec![3.3],
},
KnownTestValues {
input: vec![3.3, 5.9],
expected_output: vec![9.2, -1.8385],
},
KnownTestValues {
input: vec![3.3, 5.9, -1.9],
expected_output: vec![7.3, 4.5033, -5.2],
},
KnownTestValues {
input: vec![3.3, 5.9, -1.9, 6.25],
expected_output: vec![13.55, 0.25949, 3.9244, -8.3352],
},
KnownTestValues {
input: vec![3.3, 5.9, -1.9, 6.25, 0.6],
expected_output: vec![14.15, 2.3621, 1.3006, 1.9199, -10.524],
},
]
}
// known input/output values for DCT Type 3
pub fn known_values_dct3() -> Vec<KnownTestValues> {
vec![
KnownTestValues {
input: vec![0.0],
expected_output: vec![0.0],
},
KnownTestValues {
input: vec![0.0, 0.0],
expected_output: vec![0.0, 0.0],
},
KnownTestValues {
input: vec![0.0, 0.0, 0.0],
expected_output: vec![0.0, 0.0, 0.0],
},
KnownTestValues {
input: vec![0.0, 0.0, 0.0, 0.0],
expected_output: vec![0.0, 0.0, 0.0, 0.0],
},
KnownTestValues {
input: vec![0.0, 0.0, 0.0, 0.0, 0.0],
expected_output: vec![0.0, 0.0, 0.0, 0.0, 0.0],
},
KnownTestValues {
input: vec![1.0],
expected_output: vec![0.5],
},
KnownTestValues {
input: vec![1.0, 1.0],
expected_output: vec![1.2071, -0.20711],
},
KnownTestValues {
input: vec![1.0, 1.0, 1.0],
expected_output: vec![1.866, -0.5, 0.13397],
},
KnownTestValues {
input: vec![1.0, 1.0, 1.0, 1.0],
expected_output: vec![2.5137, -0.7483, 0.33409, -0.099456],
},
KnownTestValues {
input: vec![1.0, 1.0, 1.0, 1.0, 1.0],
expected_output: vec![3.1569, -0.98131, 0.5, -0.25476, 0.079192],
},
KnownTestValues {
input: vec![3.3],
expected_output: vec![1.65],
},
KnownTestValues {
input: vec![3.3, 5.9],
expected_output: vec![5.8219, -2.5219],
},
KnownTestValues {
input: vec![3.3, 5.9, -1.9],
expected_output: vec![5.8095, 3.55, -4.4095],
},
KnownTestValues {
input: vec![3.3, 5.9, -1.9, 6.25],
expected_output: vec![8.1492, -0.52291, 6.5099, -7.5362],
},
KnownTestValues {
input: vec![3.3, 5.9, -1.9, 6.25, 0.6],
expected_output: vec![9.5832, -0.72445, 4.15, 4.2279, -8.9866],
},
]
}
// known input/output values for DCT Type 4
pub fn known_values_dct4() -> Vec<KnownTestValues> {
vec![
KnownTestValues {
input: vec![0.0],
expected_output: vec![0.0],
},
KnownTestValues {
input: vec![0.0, 0.0],
expected_output: vec![0.0, 0.0],
},
KnownTestValues {
input: vec![0.0, 0.0, 0.0],
expected_output: vec![0.0, 0.0, 0.0],
},
KnownTestValues {
input: vec![0.0, 0.0, 0.0, 0.0],
expected_output: vec![0.0, 0.0, 0.0, 0.0],
},
KnownTestValues {
input: vec![0.0, 0.0, 0.0, 0.0, 0.0],
expected_output: vec![0.0, 0.0, 0.0, 0.0, 0.0],
},
KnownTestValues {
input: vec![1.0],
expected_output: vec![0.70711],
},
KnownTestValues {
input: vec![1.0, 1.0],
expected_output: vec![1.3066, -0.5412],
},
KnownTestValues {
input: vec![1.0, 1.0, 1.0],
expected_output: vec![1.9319, -0.70711, 0.51764],
},
KnownTestValues {
input: vec![1.0, 1.0, 1.0, 1.0],
expected_output: vec![2.5629, -0.89998, 0.60134, -0.5098],
},
KnownTestValues {
input: vec![1.0, 1.0, 1.0, 1.0, 1.0],
expected_output: vec![3.1962, -1.1013, 0.70711, -0.56116, 0.50623],
},
KnownTestValues {
input: vec![3.3],
expected_output: vec![2.3335],
},
KnownTestValues {
input: vec![3.3, 5.9],
expected_output: vec![5.3066, -4.188],
},
KnownTestValues {
input: vec![3.3, 5.9, -1.9],
expected_output: vec![6.8677, -0.49497, -5.1531],
},
KnownTestValues {
input: vec![3.3, 5.9, -1.9, 6.25],
expected_output: vec![8.306, -0.016005, 0.87276, -10.344],
},
KnownTestValues {
input: vec![3.3, 5.9, -1.9, 6.25, 0.6],
expected_output: vec![10.104, -1.2387, 4.3487, -5.2296, -8.482],
},
]
}
// known input/output values for DST Type 1
pub fn known_values_dst1() -> Vec<KnownTestValues> {
vec![
KnownTestValues {
input: vec![0.0],
expected_output: vec![0.0],
},
KnownTestValues {
input: vec![0.0, 0.0],
expected_output: vec![0.0, 0.0],
},
KnownTestValues {
input: vec![0.0, 0.0, 0.0],
expected_output: vec![0.0, 0.0, 0.0],
},
KnownTestValues {
input: vec![0.0, 0.0, 0.0, 0.0],
expected_output: vec![0.0, 0.0, 0.0, 0.0],
},
KnownTestValues {
input: vec![0.0, 0.0, 0.0, 0.0, 0.0],
expected_output: vec![0.0, 0.0, 0.0, 0.0, 0.0],
},
KnownTestValues {
input: vec![1.0],
expected_output: vec![1.0],
},
KnownTestValues {
input: vec![1.0, 1.0],
expected_output: vec![1.7321, 0.0],
},
KnownTestValues {
input: vec![1.0, 1.0, 1.0],
expected_output: vec![2.4142, 0.0, 0.41421],
},
KnownTestValues {
input: vec![1.0, 1.0, 1.0, 1.0],
expected_output: vec![3.0777, 0.0, 0.72654, 0.0],
},
KnownTestValues {
input: vec![1.0, 1.0, 1.0, 1.0, 1.0],
expected_output: vec![3.7321, 0.0, 1.0, 0.0, 0.26795],
},
KnownTestValues {
input: vec![3.3],
expected_output: vec![3.3],
},
KnownTestValues {
input: vec![3.3, 5.9],
expected_output: vec![7.9674, -2.2517],
},
KnownTestValues {
input: vec![3.3, 5.9, -1.9],
expected_output: vec![6.8899, 5.2, -4.9101],
},
KnownTestValues {
input: vec![3.3, 5.9, -1.9, 6.25],
expected_output: vec![9.4176, 1.7791, 6.7314, -9.1522],
},
KnownTestValues {
input: vec![3.3, 5.9, -1.9, 6.25, 0.6],
expected_output: vec![10.572, 2.0352, 5.8, 2.6414, -10.472],
},
]
}
// known input/output values for DST Type 2
pub fn known_values_dst2() -> Vec<KnownTestValues> {
vec![
KnownTestValues {
input: vec![0.0],
expected_output: vec![0.0],
},
KnownTestValues {
input: vec![0.0, 0.0],
expected_output: vec![0.0, 0.0],
},
KnownTestValues {
input: vec![0.0, 0.0, 0.0],
expected_output: vec![0.0, 0.0, 0.0],
},
KnownTestValues {
input: vec![0.0, 0.0, 0.0, 0.0],
expected_output: vec![0.0, 0.0, 0.0, 0.0],
},
KnownTestValues {
input: vec![0.0, 0.0, 0.0, 0.0, 0.0],
expected_output: vec![0.0, 0.0, 0.0, 0.0, 0.0],
},
KnownTestValues {
input: vec![1.0],
expected_output: vec![1.0],
},
KnownTestValues {
input: vec![1.0, 1.0],
expected_output: vec![1.4142, 0.0],
},
KnownTestValues {
input: vec![1.0, 1.0, 1.0],
expected_output: vec![2.0, 0.0, 1.0],
},
KnownTestValues {
input: vec![1.0, 1.0, 1.0, 1.0],
expected_output: vec![2.6131, 0.0, 1.0824, 0.0],
},
KnownTestValues {
input: vec![1.0, 1.0, 1.0, 1.0, 1.0],
expected_output: vec![3.2361, 0.0, 1.2361, 0.0, 1.0],
},
KnownTestValues {
input: vec![3.3],
expected_output: vec![3.3],
},
KnownTestValues {
input: vec![3.3, 5.9],
expected_output: vec![6.5054, -2.6],
},
KnownTestValues {
input: vec![3.3, 5.9, -1.9],
expected_output: vec![6.6, 4.5033, -4.5],
},
KnownTestValues {
input: vec![3.3, 5.9, -1.9, 6.25],
expected_output: vec![7.3501, 3.4295, 7.2923, -10.75],
},
KnownTestValues {
input: vec![3.3, 5.9, -1.9, 6.25, 0.6],
expected_output: vec![9.1347, 1.2542, 8.8097, 2.7736, -10.15],
},
]
}
// known input/output values for DST Type 3
pub fn known_values_dst3() -> Vec<KnownTestValues> {
vec![
KnownTestValues {
input: vec![0.0],
expected_output: vec![0.0],
},
KnownTestValues {
input: vec![0.0, 0.0],
expected_output: vec![0.0, 0.0],
},
KnownTestValues {
input: vec![0.0, 0.0, 0.0],
expected_output: vec![0.0, 0.0, 0.0],
},
KnownTestValues {
input: vec![0.0, 0.0, 0.0, 0.0],
expected_output: vec![0.0, 0.0, 0.0, 0.0],
},
KnownTestValues {
input: vec![0.0, 0.0, 0.0, 0.0, 0.0],
expected_output: vec![0.0, 0.0, 0.0, 0.0, 0.0],
},
KnownTestValues {
input: vec![1.0],
expected_output: vec![0.5],
},
KnownTestValues {
input: vec![1.0, 1.0],
expected_output: vec![1.2071, 0.20711],
},
KnownTestValues {
input: vec![1.0, 1.0, 1.0],
expected_output: vec![1.866, 0.5, 0.13397],
},
KnownTestValues {
input: vec![1.0, 1.0, 1.0, 1.0],
expected_output: vec![2.5137, 0.7483, 0.33409, 0.099456],
},
KnownTestValues {
input: vec![1.0, 1.0, 1.0, 1.0, 1.0],
expected_output: vec![3.1569, 0.98131, 0.5, 0.25476, 0.079192],
},
KnownTestValues {
input: vec![3.3],
expected_output: vec![1.65],
},
KnownTestValues {
input: vec![3.3, 5.9],
expected_output: vec![5.2835, -0.61655],
},
KnownTestValues {
input: vec![3.3, 5.9, -1.9],
expected_output: vec![5.8095, 4.25, -4.4095],
},
KnownTestValues {
input: vec![3.3, 5.9, -1.9, 6.25],
expected_output: vec![6.8044, 4.8228, 2.729, -7.7894],
},
KnownTestValues {
input: vec![3.3, 5.9, -1.9, 6.25, 0.6],
expected_output: vec![9.1947, 3.7202, 5.5, -0.15495, -9.6294],
},
]
}
// known input/output values for DST Type 4
pub fn known_values_dst4() -> Vec<KnownTestValues> {
vec![
KnownTestValues {
input: vec![0.0],
expected_output: vec![0.0],
},
KnownTestValues {
input: vec![0.0, 0.0],
expected_output: vec![0.0, 0.0],
},
KnownTestValues {
input: vec![0.0, 0.0, 0.0],
expected_output: vec![0.0, 0.0, 0.0],
},
KnownTestValues {
input: vec![0.0, 0.0, 0.0, 0.0],
expected_output: vec![0.0, 0.0, 0.0, 0.0],
},
KnownTestValues {
input: vec![0.0, 0.0, 0.0, 0.0, 0.0],
expected_output: vec![0.0, 0.0, 0.0, 0.0, 0.0],
},
KnownTestValues {
input: vec![1.0],
expected_output: vec![0.70711],
},
KnownTestValues {
input: vec![1.0, 1.0],
expected_output: vec![1.3066, 0.5412],
},
KnownTestValues {
input: vec![1.0, 1.0, 1.0],
expected_output: vec![1.9319, 0.70711, 0.51764],
},
KnownTestValues {
input: vec![1.0, 1.0, 1.0, 1.0],
expected_output: vec![2.5629, 0.89998, 0.60134, 0.5098],
},
KnownTestValues {
input: vec![1.0, 1.0, 1.0, 1.0, 1.0],
expected_output: vec![3.1962, 1.1013, 0.70711, 0.56116, 0.50623],
},
KnownTestValues {
input: vec![3.3],
expected_output: vec![2.3335],
},
KnownTestValues {
input: vec![3.3, 5.9],
expected_output: vec![6.7137, 0.79097],
},
KnownTestValues {
input: vec![3.3, 5.9, -1.9],
expected_output: vec![3.1908, 7.8489, -1.4761],
},
KnownTestValues {
input: vec![3.3, 5.9, -1.9, 6.25],
expected_output: vec![8.4718, 2.0527, 9.2307, -3.944],
},
KnownTestValues {
input: vec![3.3, 5.9, -1.9, 6.25, 0.6],
expected_output: vec![8.0127, 4.4697, 3.8537, 9.2615, -6.0846],
},
]
}

View File

@@ -0,0 +1,191 @@
use crate::common::{compare_float_vectors, random_signal};
use rustdct::DctPlanner;
macro_rules! dct_test_with_known_data {
($reference_fn:ident, $naive_struct:ident, $process_fn: ident, $known_data_fn:ident) => (
// Compare our naive struct and our reference_fn implementation against a bunch of known data
let known_data = $known_data_fn();
for entry in known_data {
let len = entry.input.len();
assert_eq!(len, entry.expected_output.len(), "Invalid test data -- input and known output are not the same length");
let mut naive_buffer = entry.input.clone();
let naive_dct = $naive_struct::new(len);
naive_dct.$process_fn(&mut naive_buffer);
let slow_output = $reference_fn(&entry.input);
println!("input: {:?}", entry.input);
println!("expected output:{:?}", entry.expected_output);
println!("naive output: {:?}", naive_buffer);
println!("slow output: {:?}", slow_output);
assert!(compare_float_vectors(&entry.expected_output, &naive_buffer));
assert!(compare_float_vectors(&entry.expected_output, &slow_output));
}
)
}
macro_rules! dct_test_inverse {
($reference_fn:ident, $inverse_fn:ident, $inverse_scale_fn:ident, $first_size:expr) => (
// Test that the slow fn, paired with the correct inverse fn, actually yields the original data
for len in $first_size..20 {
let input = random_signal(len);
let intermediate = $reference_fn(&input);
let inverse = $inverse_fn(&intermediate);
let inverse_scale = $inverse_scale_fn(len);
let scaled_inverse: Vec<f64> = inverse.into_iter().map(|entry| entry * inverse_scale).collect();
println!("input: {:?}", input);
println!("scaled inverse: {:?}", scaled_inverse);
assert!(compare_float_vectors(&input, &scaled_inverse));
}
)
}
macro_rules! dct_test_with_planner {
($reference_fn:ident, $naive_struct:ident, $process_fn: ident, $planner_fn:ident, $first_size:expr) => {
// Compare our naive struct against the output from the planner
for len in $first_size..20 {
let input = random_signal(len);
let mut naive_buffer = input.clone();
let mut actual_buffer = input.clone();
let naive_dct = $naive_struct::new(len);
let mut planner = DctPlanner::new();
let actual_dct = planner.$planner_fn(len);
assert_eq!(
actual_dct.len(),
len,
"Planner created a DCT of incorrect length. Expected {}, got {}",
len,
actual_dct.len()
);
let reference_output = $reference_fn(&input);
naive_dct.$process_fn(&mut naive_buffer);
actual_dct.$process_fn(&mut actual_buffer);
println!("input: {:?}", input);
println!("reference output:{:?}", reference_output);
println!("naive output: {:?}", naive_buffer);
println!("planned output: {:?}", actual_buffer);
assert!(compare_float_vectors(&reference_output, &naive_buffer));
assert!(compare_float_vectors(&reference_output, &actual_buffer));
}
};
}
pub mod test_mdct {
use super::*;
use rustdct::{
mdct::{Mdct, MdctNaive},
RequiredScratch,
};
pub fn planned_matches_naive<F>(len: usize, window_fn: F)
where
F: Fn(usize) -> Vec<f32>,
{
let input = random_signal(len * 2);
println!("input: {:?}", input);
let (input_a, input_b) = input.split_at(len);
let mut naive_output = vec![0f32; len];
let mut actual_output = vec![0f32; len];
let naive_dct = MdctNaive::new(len, &window_fn);
let mut planner = DctPlanner::new();
let actual_dct = planner.plan_mdct(len, window_fn);
assert_eq!(
actual_dct.len(),
len,
"Planner created a DCT of incorrect length"
);
let mut naive_scratch = vec![0f32; naive_dct.get_scratch_len()];
let mut fast_scratch = vec![0f32; actual_dct.get_scratch_len()];
naive_dct.process_mdct_with_scratch(
input_a,
input_b,
&mut naive_output,
&mut naive_scratch,
);
actual_dct.process_mdct_with_scratch(
input_a,
input_b,
&mut actual_output,
&mut fast_scratch,
);
println!("Naive output: {:?}", naive_output);
println!("Planned output: {:?}", actual_output);
assert!(
compare_float_vectors(&naive_output, &actual_output),
"len = {}",
len
);
}
pub fn test_tdac<F>(len: usize, scale_factor: f32, window_fn: F)
where
F: Fn(usize) -> Vec<f32>,
{
let mut planner = DctPlanner::new();
let mdct = planner.plan_mdct(len, &window_fn);
const NUM_SEGMENTS: usize = 5;
let input = random_signal(len * (NUM_SEGMENTS + 1));
let mut output = vec![0f32; len * NUM_SEGMENTS];
let mut inverse = vec![0f32; len * (NUM_SEGMENTS + 1)];
let mut scratch = vec![0f32; mdct.get_scratch_len()];
for i in 0..NUM_SEGMENTS {
let input_chunk = &input[len * i..(len * (i + 2))];
let output_chunk = &mut output[len * i..(len * (i + 1))];
let (input_a, input_b) = input_chunk.split_at(len);
mdct.process_mdct_with_scratch(input_a, input_b, output_chunk, &mut scratch);
}
for i in 0..NUM_SEGMENTS {
let input_chunk = &output[len * i..(len * (i + 1))];
let output_chunk = &mut inverse[len * i..(len * (i + 2))];
let (output_a, output_b) = output_chunk.split_at_mut(len);
mdct.process_imdct_with_scratch(input_chunk, output_a, output_b, &mut scratch);
}
//we have to scale the inverse by 1/len
for element in inverse.iter_mut() {
*element = *element * scale_factor;
}
println!("scale: {:?}", scale_factor);
println!("input: {:?}", &input[len..input.len() - len]);
println!("inverse: {:?}", &inverse[len..input.len() - len]);
assert!(
compare_float_vectors(
&input[len..input.len() - len],
&inverse[len..inverse.len() - len],
),
"len = {}",
len
);
}
}

View File

@@ -0,0 +1,41 @@
use rand::{distributions::Uniform, prelude::Distribution, rngs::StdRng, SeedableRng};
use rustdct::num_traits::{Float, FromPrimitive};
pub mod known_data;
pub mod reference_impls;
#[macro_use]
pub mod macros;
pub fn fuzzy_cmp<T: Float>(a: T, b: T, tolerance: T) -> bool {
a >= b - tolerance && a <= b + tolerance
}
pub fn compare_float_vectors<T: Float + FromPrimitive>(expected: &[T], observed: &[T]) -> bool {
assert_eq!(expected.len(), observed.len());
let tolerance = T::from_f64(0.001).unwrap();
for i in 0..expected.len() {
if !fuzzy_cmp(observed[i], expected[i], tolerance) {
return false;
}
}
true
}
pub fn random_signal<T: Float + FromPrimitive>(length: usize) -> Vec<T> {
let mut sig = Vec::with_capacity(length);
let distribution = Uniform::new(0.0, 10.0);
let seed: [u8; 32] = [
1, 5, 6, 7, 1, 5, 3, 7, 4, 2, 6, 2, 6, 1, 5, 6, 7, 1, 5, 3, 7, 4, 2, 6, 2, 6, 1, 5, 1, 0,
1, 7,
];
let mut rng: StdRng = SeedableRng::from_seed(seed);
for _ in 0..length {
sig.push(T::from_f64(distribution.sample(&mut rng)).unwrap());
}
return sig;
}

View File

@@ -0,0 +1,312 @@
/// This file contains reference implementations of all DCT and DST transforms.
/// The goal of these implementations is not to be fast, but to match the mathematical definitions as closely as possible and to be easy to follow and debug
/// The reference for the mathematical definitions was section 9 of "The Discrete W Transforms" by Wang and Hunt, but with the normalization/orthogonalization factors omitted.
use std::f64;
/// Simplified version of DCT1
pub fn reference_dct1(input: &[f64]) -> Vec<f64> {
let mut result = Vec::new();
for output_index in 0..input.len() {
let mut entry = 0.0;
for input_index in 0..input.len() {
let multiplier = if input_index == 0 || input_index == input.len() - 1 {
0.5
} else {
1.0
};
let cos_inner = (output_index as f64) * (input_index as f64) * f64::consts::PI
/ ((input.len() - 1) as f64);
let twiddle = cos_inner.cos();
entry += input[input_index] * twiddle * multiplier;
}
result.push(entry);
}
result
}
/// Simplified version of DCT2
pub fn reference_dct2(input: &[f64]) -> Vec<f64> {
let mut result = Vec::new();
for output_index in 0..input.len() {
let mut entry = 0.0;
for input_index in 0..input.len() {
let cos_inner = (output_index as f64) * (input_index as f64 + 0.5) * f64::consts::PI
/ (input.len() as f64);
let twiddle = cos_inner.cos();
entry += input[input_index] * twiddle;
}
result.push(entry);
}
result
}
/// Simplified version of DCT3
pub fn reference_dct3(input: &[f64]) -> Vec<f64> {
let mut result = Vec::new();
for output_index in 0..input.len() {
let mut entry = 0.0;
for input_index in 0..input.len() {
let multiplier = if input_index == 0 { 0.5 } else { 1.0 };
let cos_inner = (output_index as f64 + 0.5) * (input_index as f64) * f64::consts::PI
/ (input.len() as f64);
let twiddle = cos_inner.cos();
entry += input[input_index] * twiddle * multiplier;
}
result.push(entry);
}
result
}
/// Simplified version of DCT4
pub fn reference_dct4(input: &[f64]) -> Vec<f64> {
let mut result = Vec::new();
for output_index in 0..input.len() {
let mut entry = 0.0;
for input_index in 0..input.len() {
let cos_inner =
(output_index as f64 + 0.5) * (input_index as f64 + 0.5) * f64::consts::PI
/ (input.len() as f64);
let twiddle = cos_inner.cos();
entry += input[input_index] * twiddle;
}
result.push(entry);
}
result
}
/// Simplified version of DCT5
pub fn reference_dct5(input: &[f64]) -> Vec<f64> {
let mut result = Vec::new();
for output_index in 0..input.len() {
let mut entry = 0.0;
for input_index in 0..input.len() {
let multiplier = if input_index == 0 { 0.5 } else { 1.0 };
let cos_inner = (output_index as f64) * (input_index as f64) * f64::consts::PI
/ (input.len() as f64 - 0.5);
let twiddle = cos_inner.cos();
entry += input[input_index] * twiddle * multiplier;
}
result.push(entry);
}
result
}
/// Simplified version of DCT6
pub fn reference_dct6(input: &[f64]) -> Vec<f64> {
let mut result = Vec::new();
for output_index in 0..input.len() {
let mut entry = 0.0;
for input_index in 0..input.len() {
let multiplier = if input_index == input.len() - 1 {
0.5
} else {
1.0
};
let cos_inner = (output_index as f64) * (input_index as f64 + 0.5) * f64::consts::PI
/ (input.len() as f64 - 0.5);
let twiddle = cos_inner.cos();
entry += input[input_index] * twiddle * multiplier;
}
result.push(entry);
}
result
}
/// Simplified version of DCT7
pub fn reference_dct7(input: &[f64]) -> Vec<f64> {
let mut result = Vec::new();
for output_index in 0..input.len() {
let mut entry = 0.0;
for input_index in 0..input.len() {
let multiplier = if input_index == 0 { 0.5 } else { 1.0 };
let cos_inner = (output_index as f64 + 0.5) * (input_index as f64) * f64::consts::PI
/ (input.len() as f64 - 0.5);
let twiddle = cos_inner.cos();
entry += input[input_index] * twiddle * multiplier;
}
result.push(entry);
}
result
}
/// Simplified version of DCT8
pub fn reference_dct8(input: &[f64]) -> Vec<f64> {
let mut result = Vec::new();
for output_index in 0..input.len() {
let mut entry = 0.0;
for input_index in 0..input.len() {
let cos_inner =
(output_index as f64 + 0.5) * (input_index as f64 + 0.5) * f64::consts::PI
/ (input.len() as f64 + 0.5);
let twiddle = cos_inner.cos();
entry += input[input_index] * twiddle;
}
result.push(entry);
}
result
}
/// Simplified version of DST1
pub fn reference_dst1(input: &[f64]) -> Vec<f64> {
let mut result = Vec::new();
for output_index in 0..input.len() {
let mut entry = 0.0;
for input_index in 0..input.len() {
let sin_inner =
(output_index as f64 + 1.0) * (input_index as f64 + 1.0) * f64::consts::PI
/ ((input.len() + 1) as f64);
let twiddle = sin_inner.sin();
entry += input[input_index] * twiddle;
}
result.push(entry);
}
result
}
/// Simplified version of DST2
pub fn reference_dst2(input: &[f64]) -> Vec<f64> {
let mut result = Vec::new();
for output_index in 0..input.len() {
let mut entry = 0.0;
for input_index in 0..input.len() {
let sin_inner =
(output_index as f64 + 1.0) * (input_index as f64 + 0.5) * f64::consts::PI
/ (input.len() as f64);
let twiddle = sin_inner.sin();
entry += input[input_index] * twiddle;
}
result.push(entry);
}
result
}
/// Simplified version of DST3
pub fn reference_dst3(input: &[f64]) -> Vec<f64> {
let mut result = Vec::new();
for output_index in 0..input.len() {
let mut entry = 0.0;
for input_index in 0..input.len() {
let multiplier = if input_index == input.len() - 1 {
0.5
} else {
1.0
};
let sin_inner =
(output_index as f64 + 0.5) * (input_index as f64 + 1.0) * f64::consts::PI
/ (input.len() as f64);
let twiddle = sin_inner.sin();
entry += input[input_index] * twiddle * multiplier;
}
result.push(entry);
}
result
}
/// Simplified version of DST4
pub fn reference_dst4(input: &[f64]) -> Vec<f64> {
let mut result = Vec::new();
for output_index in 0..input.len() {
let mut entry = 0.0;
for input_index in 0..input.len() {
let sin_inner =
(output_index as f64 + 0.5) * (input_index as f64 + 0.5) * f64::consts::PI
/ (input.len() as f64);
let twiddle = sin_inner.sin();
entry += input[input_index] * twiddle;
}
result.push(entry);
}
result
}
/// Simplified version of DST5
pub fn reference_dst5(input: &[f64]) -> Vec<f64> {
let mut result = Vec::new();
for output_index in 0..input.len() {
let mut entry = 0.0;
for input_index in 0..input.len() {
let sin_inner =
(output_index as f64 + 1.0) * (input_index as f64 + 1.0) * f64::consts::PI
/ ((input.len()) as f64 + 0.5);
let twiddle = sin_inner.sin();
entry += input[input_index] * twiddle;
}
result.push(entry);
}
result
}
/// Simplified version of DST6
pub fn reference_dst6(input: &[f64]) -> Vec<f64> {
let mut result = Vec::new();
for output_index in 0..input.len() {
let mut entry = 0.0;
for input_index in 0..input.len() {
let sin_inner =
(output_index as f64 + 1.0) * (input_index as f64 + 0.5) * f64::consts::PI
/ (input.len() as f64 + 0.5);
let twiddle = sin_inner.sin();
entry += input[input_index] * twiddle;
}
result.push(entry);
}
result
}
/// Simplified version of DST7
pub fn reference_dst7(input: &[f64]) -> Vec<f64> {
let mut result = Vec::new();
for output_index in 0..input.len() {
let mut entry = 0.0;
for input_index in 0..input.len() {
let sin_inner =
(output_index as f64 + 0.5) * (input_index as f64 + 1.0) * f64::consts::PI
/ (input.len() as f64 + 0.5);
let twiddle = sin_inner.sin();
entry += input[input_index] * twiddle;
}
result.push(entry);
}
result
}
/// Simplified version of DST8
pub fn reference_dst8(input: &[f64]) -> Vec<f64> {
let mut result = Vec::new();
for output_index in 0..input.len() {
let mut entry = 0.0;
for input_index in 0..input.len() {
let multiplier = if input_index == input.len() - 1 {
0.5
} else {
1.0
};
let sin_inner =
(output_index as f64 + 0.5) * (input_index as f64 + 0.5) * f64::consts::PI
/ (input.len() as f64 - 0.5);
let twiddle = sin_inner.sin();
entry += input[input_index] * twiddle * multiplier;
}
result.push(entry);
}
result
}