1 use super::ivi::{IVITransformType,TDir,TrFunc,TrFuncDC};
3 fn hbutterfly(a: i32, b: i32) -> (i32, i32) {
4 ((a + b) >> 1, (a - b) >> 1)
6 fn butterfly(a: i32, b: i32) -> (i32, i32) {
9 fn ireflect(a: i32, b: i32) -> (i32, i32) {
10 (((b * 2 - a + 2) >> 2) - a, ((b + 2 * a + 2) >> 2) + b)
13 macro_rules! haar_transform {
14 ($c0:expr, $c1:expr, $c2:expr, $c3:expr) => {{
15 let (t0, t1) = hbutterfly($c0, $c1);
16 let (t2, t3) = hbutterfly(t0, $c2);
19 let (t4, t5) = hbutterfly(t1, $c3);
23 ($c0:expr, $c1:expr, $c2:expr, $c3:expr, $c4:expr, $c5:expr, $c6:expr, $c7:expr) => {{
24 let (a0, a1) = hbutterfly($c0 << 1, $c1 << 1);
26 let (t0, t1) = hbutterfly(a0, $c2);
27 let (t2, t3) = hbutterfly(a1, $c3);
28 let (u0, u1) = hbutterfly(t0, $c4);
29 let (u2, u3) = hbutterfly(t1, $c5);
30 let (u4, u5) = hbutterfly(t2, $c6);
31 let (u6, u7) = hbutterfly(t3, $c7);
43 macro_rules! slant_transform {
44 ($c0:expr, $c1:expr, $c2:expr, $c3:expr, $output:ident) => {{
45 let (t0, t1) = butterfly($c0, $c2);
46 let (t2, t3) = ireflect ($c3, $c1);
47 let (t4, t5) = butterfly(t0, t3);
48 let (t6, t7) = butterfly(t1, t2);
54 ($c0:expr, $c1:expr, $c2:expr, $c3:expr, $c4:expr, $c5:expr, $c6:expr, $c7:expr, $output:ident) => {{
55 let t0 = $c3 + (($c1 * 4 - $c3 + 4) >> 3);
56 let t1 = $c1 + ((-$c1 - $c3 * 4 + 4) >> 3);
58 let (t2, t3) = butterfly($c0, t1);
59 let (t4, t5) = butterfly($c4, $c5);
60 let (t6, t7) = butterfly($c7, $c6);
61 let (t8, t9) = butterfly(t0, $c2);
63 let (u0, u1) = butterfly(t2, t4);
64 let (u2, u3) = ireflect (t7, t8);
65 let (u4, u5) = butterfly(t3, t5);
66 let (u6, u7) = ireflect (t6, t9);
68 let (t0, t1) = butterfly(u0, u3);
69 let (t2, t3) = butterfly(u1, u2);
70 let (t4, t5) = butterfly(u4, u7);
71 let (t6, t7) = butterfly(u5, u6);
84 fn haar8x8_2d(blk: &mut[i32; 64]) {
86 let mut c0 = blk[i + 0*8] << 1;
87 let mut c1 = blk[i + 1*8] << 1;
88 let mut c2 = blk[i + 2*8] << 1;
89 let mut c3 = blk[i + 3*8] << 1;
90 haar_transform!(c0, c1, c2, c3,
91 blk[i + 4*8], blk[i + 5*8], blk[i + 6*8], blk[i + 7*8]);
98 haar_transform!(blk[i + 0*8], blk[i + 1*8], blk[i + 2*8], blk[i + 3*8],
99 blk[i + 4*8], blk[i + 5*8], blk[i + 6*8], blk[i + 7*8]);
102 let mut row = &mut blk[i*8..(i+1)*8];
103 haar_transform!(row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7]);
106 fn haar8x8_row(blk: &mut[i32; 64]) {
108 let mut row = &mut blk[i*8..(i+1)*8];
109 haar_transform!(row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7]);
112 fn haar8x8_col(blk: &mut[i32; 64]) {
114 haar_transform!(blk[i + 0*8], blk[i + 1*8], blk[i + 2*8], blk[i + 3*8],
115 blk[i + 4*8], blk[i + 5*8], blk[i + 6*8], blk[i + 7*8]);
118 fn haar8x8_dc(blk: &mut[i32; 64], in0: i32) {
120 for i in 0..64 { blk[i] = dc; }
123 fn haar4x4_2d(blk: &mut[i32; 64]) {
125 let mut c0 = blk[i + 0*4] << 1;
126 let mut c1 = blk[i + 1*4] << 1;
127 haar_transform!(c0, c1, blk[i + 2*4], blk[i + 3*4]);
132 haar_transform!(blk[i + 0*4], blk[i + 1*4], blk[i + 2*4], blk[i + 3*4]);
135 let mut row = &mut blk[i*4..(i+1)*4];
136 haar_transform!(row[0], row[1], row[2], row[3]);
139 fn haar4x4_row(blk: &mut[i32; 64]) {
141 let mut row = &mut blk[i*4..(i+1)*4];
142 haar_transform!(row[0], row[1], row[2], row[3]);
145 fn haar4x4_col(blk: &mut[i32; 64]) {
147 haar_transform!(blk[i + 0*4], blk[i + 1*4], blk[i + 2*4], blk[i + 3*4]);
150 fn haar4x4_dc(blk: &mut[i32; 64], in0: i32) {
152 for i in 0..16 { blk[i] = dc; }
155 fn slant8x8_2d(blk: &mut[i32; 64]) {
156 let pass1 = |x: i32| x;
157 let pass2 = |x: i32| (x + 1) >> 1;
161 for j in 0..8 { s0 |= blk[i + j*8]; }
162 if s0 == 0 { continue; }
164 slant_transform!(blk[i + 0*8], blk[i + 1*8], blk[i + 2*8], blk[i + 3*8],
165 blk[i + 4*8], blk[i + 5*8], blk[i + 6*8], blk[i + 7*8], pass1);
168 let mut row = &mut blk[i*8..(i+1)*8];
169 slant_transform!(row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7], pass2);
172 fn slant8x8_2d_dc(blk: &mut[i32; 64], in0: i32) {
173 let dc = (in0 + 1) >> 1;
174 for i in 0..64 { blk[i] = dc; }
176 fn slant8x8_row(blk: &mut[i32; 64]) {
177 let pass = |x: i32| (x + 1) >> 1;
180 let mut row = &mut blk[i*8..(i+1)*8];
181 slant_transform!(row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7], pass);
184 fn slant8x8_row_dc(blk: &mut[i32; 64], in0: i32) {
185 let dc = (in0 + 1) >> 1;
187 for i in 0..8 { blk[i] = dc; }
188 for i in 8..64 { blk[i] = 0; }
190 fn slant8x8_col(blk: &mut[i32; 64]) {
191 let pass = |x: i32| (x + 1) >> 1;
194 slant_transform!(blk[i + 0*8], blk[i + 1*8], blk[i + 2*8], blk[i + 3*8],
195 blk[i + 4*8], blk[i + 5*8], blk[i + 6*8], blk[i + 7*8], pass);
198 fn slant8x8_col_dc(blk: &mut[i32; 64], in0: i32) {
199 let dc = (in0 + 1) >> 1;
203 for j in 1..8 { blk[i * 8 + j] = 0; }
207 fn slant4x4_2d(blk: &mut[i32; 64]) {
208 let pass1 = |x: i32| x;
209 let pass2 = |x: i32| (x + 1) >> 1;
212 slant_transform!(blk[i + 0*4], blk[i + 1*4], blk[i + 2*4], blk[i + 3*4], pass1);
215 let mut row = &mut blk[i*4..(i+1)*4];
216 slant_transform!(row[0], row[1], row[2], row[3], pass2);
219 fn slant4x4_2d_dc(blk: &mut[i32; 64], in0: i32) {
220 let dc = (in0 + 1) >> 1;
221 for i in 0..16 { blk[i] = dc; }
223 fn slant4x4_row(blk: &mut[i32; 64]) {
224 let pass = |x: i32| (x + 1) >> 1;
227 let mut row = &mut blk[i*4..(i+1)*4];
228 slant_transform!(row[0], row[1], row[2], row[3], pass);
231 fn slant4x4_row_dc(blk: &mut[i32; 64], in0: i32) {
232 let dc = (in0 + 1) >> 1;
234 for i in 0..4 { blk[i] = dc; }
235 for i in 4..16 { blk[i] = 0; }
237 fn slant4x4_col(blk: &mut[i32; 64]) {
238 let pass = |x: i32| (x + 1) >> 1;
241 slant_transform!(blk[i + 0*4], blk[i + 1*4], blk[i + 2*4], blk[i + 3*4], pass);
244 fn slant4x4_col_dc(blk: &mut[i32; 64], in0: i32) {
245 let dc = (in0 + 1) >> 1;
249 for j in 1..4 { blk[i * 4 + j] = 0; }
253 #[allow(unused_variables)]
254 fn none8x8(blk: &mut[i32; 64]) {
256 fn none8x8_dc(blk: &mut[i32; 64], dc: i32) {
257 for i in 1..8 { blk[i] = dc; }
258 for i in 8..64 { blk[i] = 0; }
260 #[allow(unused_variables)]
261 fn none4x4(blk: &mut[i32; 64]) {
263 fn none4x4_dc(blk: &mut[i32; 64], dc: i32) {
264 for i in 1..4 { blk[i] = dc; }
265 for i in 4..16 { blk[i] = 0; }
268 pub fn ivi_get_transform8x8_funcs(ttype: IVITransformType) -> (TrFunc, TrFuncDC) {
270 IVITransformType::Haar(_, ref dir) => {
272 TDir::TwoD => { (haar8x8_2d, haar8x8_dc) },
273 TDir::Row => { (haar8x8_row, haar8x8_dc) },
274 TDir::Col => { (haar8x8_col, haar8x8_dc) },
276 IVITransformType::Slant(_, ref dir) => {
278 TDir::TwoD => { (slant8x8_2d, slant8x8_2d_dc) },
279 TDir::Row => { (slant8x8_row, slant8x8_row_dc) },
280 TDir::Col => { (slant8x8_col, slant8x8_col_dc) },
282 IVITransformType::DCT(_, _) => { unimplemented!() },
283 IVITransformType::None(_) => { (none8x8, none8x8_dc) }
286 pub fn ivi_get_transform4x4_funcs(ttype: IVITransformType) -> (TrFunc, TrFuncDC) {
288 IVITransformType::Haar(_, ref dir) => {
290 TDir::TwoD => { (haar4x4_2d, haar4x4_dc) },
291 TDir::Row => { (haar4x4_row, haar4x4_dc) },
292 TDir::Col => { (haar4x4_col, haar4x4_dc) },
294 IVITransformType::Slant(_, ref dir) => {
296 TDir::TwoD => { (slant4x4_2d, slant4x4_2d_dc) },
297 TDir::Row => { (slant4x4_row, slant4x4_row_dc) },
298 TDir::Col => { (slant4x4_col, slant4x4_col_dc) },
300 IVITransformType::DCT(_, _) => { unimplemented!() },
301 IVITransformType::None(_) => { (none4x4, none4x4_dc) }
305 pub fn ivi_mc_put(dst: &mut [i16], dstride: usize, src: &[i16], sstride: usize, mode: u8, w: usize, h: usize) {
308 if src.len() < w + h * sstride { return; }
313 dst[didx + x] = src[sidx + x];
322 let val = (src[sidx + x] + src[sidx + x + 1]) >> 1;
332 let val = (src[sidx + x] + src[sidx + x + sstride]) >> 1;
342 let val = (src[sidx + x + 0] + src[sidx + x + sstride + 0] +
343 src[sidx + x + 1] + src[sidx + x + sstride + 1]) >> 2;
353 fn ivi_mc_add(dst: &mut [i16], dstride: usize, src: &[i16], sstride: usize, mode: u8, w: usize, h: usize) {
360 dst[didx + x] += src[sidx + x];
369 let val = (src[sidx + x] + src[sidx + x + 1]) >> 1;
370 dst[didx + x] += val;
379 let val = (src[sidx + x] + src[sidx + x + sstride]) >> 1;
380 dst[didx + x] += val;
389 let val = (src[sidx + x + 0] + src[sidx + x + sstride + 0] +
390 src[sidx + x + 1] + src[sidx + x + sstride + 1]) >> 2;
391 dst[didx + x] += val;
400 pub fn ivi_mc_avg(dst: &mut [i16], dstride: usize,
401 src1: &[i16], sstride1: usize, mode1: u8,
402 src2: &[i16], sstride2: usize, mode2: u8,
403 w: usize, h: usize) {
407 let mut tmp: [i16; 64] = [0; 64];
408 ivi_mc_add(&mut tmp, tstride, src1, sstride1, mode1, w, h);
409 ivi_mc_add(&mut tmp, tstride, src2, sstride2, mode2, w, h);
411 for x in 0..w { dst[didx + x] = tmp[tidx + x] >> 1; }