zune_jpeg/
idct.rs
1#![allow(
29 clippy::excessive_precision,
30 clippy::unreadable_literal,
31 clippy::module_name_repetitions,
32 unused_parens,
33 clippy::wildcard_imports
34)]
35
36use zune_core::log::debug;
37use zune_core::options::DecoderOptions;
38
39use crate::decoder::IDCTPtr;
40use crate::idct::scalar::idct_int;
41
42#[cfg(feature = "x86")]
43pub mod avx2;
44#[cfg(feature = "neon")]
45pub mod neon;
46
47pub mod scalar;
48
49#[allow(unused_variables)]
51pub fn choose_idct_func(options: &DecoderOptions) -> IDCTPtr {
52 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
53 #[cfg(feature = "x86")]
54 {
55 if options.use_avx2() {
56 debug!("Using vector integer IDCT");
57 return crate::idct::avx2::idct_avx2;
59 }
60 }
61 #[cfg(target_arch = "aarch64")]
62 #[cfg(feature = "neon")]
63 {
64 if options.use_neon() {
65 debug!("Using vector integer IDCT");
66 return crate::idct::neon::idct_neon;
67 }
68 }
69 debug!("Using scalar integer IDCT");
70 return idct_int;
72}
73
74#[cfg(test)]
75#[allow(unreachable_code)]
76#[allow(dead_code)]
77mod tests {
78 use super::*;
79
80 #[test]
81 fn idct_test0() {
82 let stride = 8;
83 let mut coeff = [10; 64];
84 let mut coeff2 = [10; 64];
85 let mut output_scalar = [0; 64];
86 let mut output_vector = [0; 64];
87 idct_fnc()(&mut coeff, &mut output_vector, stride);
88 idct_int(&mut coeff2, &mut output_scalar, stride);
89 assert_eq!(output_scalar, output_vector, "IDCT and scalar do not match");
90 }
91
92 #[test]
93 fn do_idct_test1() {
94 let stride = 8;
95 let mut coeff = [14; 64];
96 let mut coeff2 = [14; 64];
97 let mut output_scalar = [0; 64];
98 let mut output_vector = [0; 64];
99 idct_fnc()(&mut coeff, &mut output_vector, stride);
100 idct_int(&mut coeff2, &mut output_scalar, stride);
101 assert_eq!(output_scalar, output_vector, "IDCT and scalar do not match");
102 }
103
104 #[test]
105 fn do_idct_test2() {
106 let stride = 8;
107 let mut coeff = [0; 64];
108 coeff[0] = 255;
109 coeff[63] = -256;
110 let mut coeff2 = coeff;
111 let mut output_scalar = [0; 64];
112 let mut output_vector = [0; 64];
113 idct_fnc()(&mut coeff, &mut output_vector, stride);
114 idct_int(&mut coeff2, &mut output_scalar, stride);
115 assert_eq!(output_scalar, output_vector, "IDCT and scalar do not match");
116 }
117
118 #[test]
119 fn do_idct_zeros() {
120 let stride = 8;
121 let mut coeff = [0; 64];
122 let mut coeff2 = [0; 64];
123 let mut output_scalar = [0; 64];
124 let mut output_vector = [0; 64];
125 idct_fnc()(&mut coeff, &mut output_vector, stride);
126 idct_int(&mut coeff2, &mut output_scalar, stride);
127 assert_eq!(output_scalar, output_vector, "IDCT and scalar do not match");
128 }
129
130 fn idct_fnc() -> IDCTPtr {
131 #[cfg(feature = "neon")]
132 #[cfg(target_arch = "aarch64")]
133 {
134 use crate::idct::neon::idct_neon;
135 return idct_neon;
136 }
137
138 #[cfg(feature = "x86")]
139 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
140 {
141 use crate::idct::avx2::idct_avx2;
142 return idct_avx2;
143 }
144
145 idct_int
146 }
147}