]> git.nihav.org Git - nihav.git/blame - nihav-indeo/src/codecs/ividsp.rs
smacker: fix version 4 support
[nihav.git] / nihav-indeo / src / codecs / ividsp.rs
CommitLineData
01c971c5
KS
1use super::ivi::{IVITransformType,TDir,TrFunc,TrFuncDC};
2
098dcca9 3#[inline(always)]
01c971c5
KS
4fn hbutterfly(a: i32, b: i32) -> (i32, i32) {
5 ((a + b) >> 1, (a - b) >> 1)
6}
098dcca9 7#[inline(always)]
01c971c5
KS
8fn butterfly(a: i32, b: i32) -> (i32, i32) {
9 (a + b, a - b)
10}
098dcca9 11#[inline(always)]
01c971c5
KS
12fn ireflect(a: i32, b: i32) -> (i32, i32) {
13 (((b * 2 - a + 2) >> 2) - a, ((b + 2 * a + 2) >> 2) + b)
14}
15
16macro_rules! haar_transform {
17 ($c0:expr, $c1:expr, $c2:expr, $c3:expr) => {{
18 let (t0, t1) = hbutterfly($c0, $c1);
19 let (t2, t3) = hbutterfly(t0, $c2);
20 $c0 = t2;
21 $c1 = t3;
22 let (t4, t5) = hbutterfly(t1, $c3);
23 $c2 = t4;
24 $c3 = t5;
25 }};
26 ($c0:expr, $c1:expr, $c2:expr, $c3:expr, $c4:expr, $c5:expr, $c6:expr, $c7:expr) => {{
27 let (a0, a1) = hbutterfly($c0 << 1, $c1 << 1);
28
29 let (t0, t1) = hbutterfly(a0, $c2);
30 let (t2, t3) = hbutterfly(a1, $c3);
31 let (u0, u1) = hbutterfly(t0, $c4);
32 let (u2, u3) = hbutterfly(t1, $c5);
33 let (u4, u5) = hbutterfly(t2, $c6);
34 let (u6, u7) = hbutterfly(t3, $c7);
35
36 $c0 = u0;
37 $c1 = u1;
38 $c2 = u2;
39 $c3 = u3;
40 $c4 = u4;
41 $c5 = u5;
42 $c6 = u6;
43 $c7 = u7;
44 }};
45}
46macro_rules! slant_transform {
47 ($c0:expr, $c1:expr, $c2:expr, $c3:expr, $output:ident) => {{
48 let (t0, t1) = butterfly($c0, $c2);
49 let (t2, t3) = ireflect ($c3, $c1);
50 let (t4, t5) = butterfly(t0, t3);
51 let (t6, t7) = butterfly(t1, t2);
52 $c0 = $output(t4);
53 $c1 = $output(t6);
54 $c2 = $output(t7);
55 $c3 = $output(t5);
56 }};
57 ($c0:expr, $c1:expr, $c2:expr, $c3:expr, $c4:expr, $c5:expr, $c6:expr, $c7:expr, $output:ident) => {{
58 let t0 = $c3 + (($c1 * 4 - $c3 + 4) >> 3);
59 let t1 = $c1 + ((-$c1 - $c3 * 4 + 4) >> 3);
60
61 let (t2, t3) = butterfly($c0, t1);
62 let (t4, t5) = butterfly($c4, $c5);
63 let (t6, t7) = butterfly($c7, $c6);
64 let (t8, t9) = butterfly(t0, $c2);
65
66 let (u0, u1) = butterfly(t2, t4);
67 let (u2, u3) = ireflect (t7, t8);
68 let (u4, u5) = butterfly(t3, t5);
69 let (u6, u7) = ireflect (t6, t9);
70
71 let (t0, t1) = butterfly(u0, u3);
72 let (t2, t3) = butterfly(u1, u2);
73 let (t4, t5) = butterfly(u4, u7);
74 let (t6, t7) = butterfly(u5, u6);
75
76 $c0 = $output(t0);
77 $c1 = $output(t2);
78 $c2 = $output(t3);
79 $c3 = $output(t1);
80 $c4 = $output(t4);
81 $c5 = $output(t6);
82 $c6 = $output(t7);
83 $c7 = $output(t5);
84 }};
85}
86
87fn haar8x8_2d(blk: &mut[i32; 64]) {
88 for i in 0..4 {
89 let mut c0 = blk[i + 0*8] << 1;
90 let mut c1 = blk[i + 1*8] << 1;
91 let mut c2 = blk[i + 2*8] << 1;
92 let mut c3 = blk[i + 3*8] << 1;
1a151e53 93 haar_transform!(c0, c1, c2, c3,
01c971c5
KS
94 blk[i + 4*8], blk[i + 5*8], blk[i + 6*8], blk[i + 7*8]);
95 blk[i + 0*8] = c0;
96 blk[i + 1*8] = c1;
97 blk[i + 2*8] = c2;
98 blk[i + 3*8] = c3;
99 }
100 for i in 4..8 {
101 haar_transform!(blk[i + 0*8], blk[i + 1*8], blk[i + 2*8], blk[i + 3*8],
102 blk[i + 4*8], blk[i + 5*8], blk[i + 6*8], blk[i + 7*8]);
103 }
104 for i in 0..8 {
4a9d2671 105 let row = &mut blk[i*8..(i+1)*8];
01c971c5
KS
106 haar_transform!(row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7]);
107 }
108}
109fn haar8x8_row(blk: &mut[i32; 64]) {
110 for i in 0..8 {
4a9d2671 111 let row = &mut blk[i*8..(i+1)*8];
01c971c5
KS
112 haar_transform!(row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7]);
113 }
114}
115fn haar8x8_col(blk: &mut[i32; 64]) {
116 for i in 0..8 {
117 haar_transform!(blk[i + 0*8], blk[i + 1*8], blk[i + 2*8], blk[i + 3*8],
118 blk[i + 4*8], blk[i + 5*8], blk[i + 6*8], blk[i + 7*8]);
119 }
120}
121fn haar8x8_dc(blk: &mut[i32; 64], in0: i32) {
122 let dc = in0 >> 3;
39cd2175 123 for el in blk.iter_mut() { *el = dc; }
01c971c5
KS
124}
125
126fn haar4x4_2d(blk: &mut[i32; 64]) {
127 for i in 0..2 {
128 let mut c0 = blk[i + 0*4] << 1;
129 let mut c1 = blk[i + 1*4] << 1;
130 haar_transform!(c0, c1, blk[i + 2*4], blk[i + 3*4]);
131 blk[i + 0*4] = c0;
132 blk[i + 1*4] = c1;
133 }
134 for i in 2..4 {
135 haar_transform!(blk[i + 0*4], blk[i + 1*4], blk[i + 2*4], blk[i + 3*4]);
136 }
137 for i in 0..4 {
4a9d2671 138 let row = &mut blk[i*4..(i+1)*4];
01c971c5
KS
139 haar_transform!(row[0], row[1], row[2], row[3]);
140 }
141}
142fn haar4x4_row(blk: &mut[i32; 64]) {
143 for i in 0..4 {
4a9d2671 144 let row = &mut blk[i*4..(i+1)*4];
01c971c5
KS
145 haar_transform!(row[0], row[1], row[2], row[3]);
146 }
147}
148fn haar4x4_col(blk: &mut[i32; 64]) {
149 for i in 0..4 {
150 haar_transform!(blk[i + 0*4], blk[i + 1*4], blk[i + 2*4], blk[i + 3*4]);
151 }
152}
153fn haar4x4_dc(blk: &mut[i32; 64], in0: i32) {
154 let dc = in0 >> 3;
39cd2175 155 for el in blk[..16].iter_mut() { *el = dc; }
01c971c5
KS
156}
157
158fn slant8x8_2d(blk: &mut[i32; 64]) {
159 let pass1 = |x: i32| x;
160 let pass2 = |x: i32| (x + 1) >> 1;
161
162 for i in 0..8 {
163 let mut s0 = 0;
164 for j in 0..8 { s0 |= blk[i + j*8]; }
165 if s0 == 0 { continue; }
166
167 slant_transform!(blk[i + 0*8], blk[i + 1*8], blk[i + 2*8], blk[i + 3*8],
168 blk[i + 4*8], blk[i + 5*8], blk[i + 6*8], blk[i + 7*8], pass1);
169 }
170 for i in 0..8 {
4a9d2671 171 let row = &mut blk[i*8..(i+1)*8];
01c971c5
KS
172 slant_transform!(row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7], pass2);
173 }
174}
175fn slant8x8_2d_dc(blk: &mut[i32; 64], in0: i32) {
176 let dc = (in0 + 1) >> 1;
39cd2175 177 for el in blk.iter_mut() { *el = dc; }
01c971c5
KS
178}
179fn slant8x8_row(blk: &mut[i32; 64]) {
180 let pass = |x: i32| (x + 1) >> 1;
181
182 for i in 0..8 {
4a9d2671 183 let row = &mut blk[i*8..(i+1)*8];
01c971c5
KS
184 slant_transform!(row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7], pass);
185 }
186}
187fn slant8x8_row_dc(blk: &mut[i32; 64], in0: i32) {
188 let dc = (in0 + 1) >> 1;
189
39cd2175
KS
190 for el in blk[0..8].iter_mut() { *el = dc; }
191 for el in blk[8..].iter_mut() { *el = 0; }
01c971c5
KS
192}
193fn slant8x8_col(blk: &mut[i32; 64]) {
194 let pass = |x: i32| (x + 1) >> 1;
195
196 for i in 0..8 {
197 slant_transform!(blk[i + 0*8], blk[i + 1*8], blk[i + 2*8], blk[i + 3*8],
198 blk[i + 4*8], blk[i + 5*8], blk[i + 6*8], blk[i + 7*8], pass);
199 }
200}
201fn slant8x8_col_dc(blk: &mut[i32; 64], in0: i32) {
202 let dc = (in0 + 1) >> 1;
203
204 for i in 0..8 {
205 blk[i * 8] = dc;
206 for j in 1..8 { blk[i * 8 + j] = 0; }
207 }
208}
209
210fn slant4x4_2d(blk: &mut[i32; 64]) {
211 let pass1 = |x: i32| x;
212 let pass2 = |x: i32| (x + 1) >> 1;
213
214 for i in 0..4 {
215 slant_transform!(blk[i + 0*4], blk[i + 1*4], blk[i + 2*4], blk[i + 3*4], pass1);
216 }
217 for i in 0..4 {
4a9d2671 218 let row = &mut blk[i*4..(i+1)*4];
01c971c5
KS
219 slant_transform!(row[0], row[1], row[2], row[3], pass2);
220 }
221}
222fn slant4x4_2d_dc(blk: &mut[i32; 64], in0: i32) {
223 let dc = (in0 + 1) >> 1;
39cd2175 224 for el in blk[..16].iter_mut() { *el = dc; }
01c971c5
KS
225}
226fn slant4x4_row(blk: &mut[i32; 64]) {
227 let pass = |x: i32| (x + 1) >> 1;
228
229 for i in 0..4 {
4a9d2671 230 let row = &mut blk[i*4..(i+1)*4];
01c971c5
KS
231 slant_transform!(row[0], row[1], row[2], row[3], pass);
232 }
233}
234fn slant4x4_row_dc(blk: &mut[i32; 64], in0: i32) {
235 let dc = (in0 + 1) >> 1;
236
39cd2175
KS
237 for el in blk[0..4].iter_mut() { *el = dc; }
238 for el in blk[4..16].iter_mut() { *el = 0; }
01c971c5
KS
239}
240fn slant4x4_col(blk: &mut[i32; 64]) {
241 let pass = |x: i32| (x + 1) >> 1;
242
243 for i in 0..4 {
244 slant_transform!(blk[i + 0*4], blk[i + 1*4], blk[i + 2*4], blk[i + 3*4], pass);
245 }
246}
247fn slant4x4_col_dc(blk: &mut[i32; 64], in0: i32) {
248 let dc = (in0 + 1) >> 1;
249
250 for i in 0..4 {
251 blk[i * 4] = dc;
252 for j in 1..4 { blk[i * 4 + j] = 0; }
253 }
254}
255
39cd2175 256fn none8x8(_blk: &mut[i32; 64]) {
01c971c5
KS
257}
258fn none8x8_dc(blk: &mut[i32; 64], dc: i32) {
39cd2175
KS
259 for el in blk[1..8].iter_mut() { *el = dc; }
260 for el in blk[8..].iter_mut() { *el = 0; }
01c971c5 261}
39cd2175 262fn none4x4(_blk: &mut[i32; 64]) {
01c971c5
KS
263}
264fn none4x4_dc(blk: &mut[i32; 64], dc: i32) {
39cd2175
KS
265 for el in blk[1..4].iter_mut() { *el = dc; }
266 for el in blk[4..16].iter_mut() { *el = 0; }
01c971c5
KS
267}
268
269pub fn ivi_get_transform8x8_funcs(ttype: IVITransformType) -> (TrFunc, TrFuncDC) {
270 match ttype {
271 IVITransformType::Haar(_, ref dir) => {
272 match *dir {
273 TDir::TwoD => { (haar8x8_2d, haar8x8_dc) },
274 TDir::Row => { (haar8x8_row, haar8x8_dc) },
275 TDir::Col => { (haar8x8_col, haar8x8_dc) },
276 } },
277 IVITransformType::Slant(_, ref dir) => {
278 match *dir {
279 TDir::TwoD => { (slant8x8_2d, slant8x8_2d_dc) },
280 TDir::Row => { (slant8x8_row, slant8x8_row_dc) },
281 TDir::Col => { (slant8x8_col, slant8x8_col_dc) },
282 } },
283 IVITransformType::DCT(_, _) => { unimplemented!() },
284 IVITransformType::None(_) => { (none8x8, none8x8_dc) }
285 }
286}
287pub fn ivi_get_transform4x4_funcs(ttype: IVITransformType) -> (TrFunc, TrFuncDC) {
288 match ttype {
289 IVITransformType::Haar(_, ref dir) => {
290 match *dir {
291 TDir::TwoD => { (haar4x4_2d, haar4x4_dc) },
292 TDir::Row => { (haar4x4_row, haar4x4_dc) },
293 TDir::Col => { (haar4x4_col, haar4x4_dc) },
294 } },
295 IVITransformType::Slant(_, ref dir) => {
296 match *dir {
297 TDir::TwoD => { (slant4x4_2d, slant4x4_2d_dc) },
298 TDir::Row => { (slant4x4_row, slant4x4_row_dc) },
299 TDir::Col => { (slant4x4_col, slant4x4_col_dc) },
300 } },
301 IVITransformType::DCT(_, _) => { unimplemented!() },
302 IVITransformType::None(_) => { (none4x4, none4x4_dc) }
303 }
304}
305
306pub fn ivi_mc_put(dst: &mut [i16], dstride: usize, src: &[i16], sstride: usize, mode: u8, w: usize, h: usize) {
307 let mut sidx = 0;
308 let mut didx = 0;
309 if src.len() < w + h * sstride { return; }
310 match mode {
311 0 => {
312 for _ in 0..h {
4a9d2671 313 let dest = &mut dst[didx..didx+w];
098dcca9 314 dest.copy_from_slice(&src[sidx..sidx+w]);
01c971c5
KS
315 sidx += sstride;
316 didx += dstride;
317 }
318 },
319 1 => {
098dcca9 320 /*for _ in 0..h {
01c971c5
KS
321 for x in 0..w {
322 let val = (src[sidx + x] + src[sidx + x + 1]) >> 1;
323 dst[didx + x] = val;
324 }
325 sidx += sstride;
326 didx += dstride;
098dcca9
KS
327 }*/
328 unsafe {
329 let mut sptr = src.as_ptr();
330 let mut dptr = dst.as_mut_ptr();
331 for _ in 0..h {
332 let mut last = *sptr;
333 for x in 0..w {
f2af8eca
KS
334 let nv = *sptr.add(x + 1);
335 *dptr.add(x) = nv.wrapping_add(last) >> 1;
098dcca9
KS
336 last = nv;
337 }
f2af8eca
KS
338 sptr = sptr.add(sstride);
339 dptr = dptr.add(dstride);
098dcca9 340 }
01c971c5
KS
341 }
342 },
343 2 => {
098dcca9 344 /*for _ in 0..h {
01c971c5
KS
345 for x in 0..w {
346 let val = (src[sidx + x] + src[sidx + x + sstride]) >> 1;
347 dst[didx + x] = val;
348 }
349 sidx += sstride;
350 didx += dstride;
098dcca9
KS
351 }*/
352 unsafe {
353 let mut sptr0 = src.as_ptr();
f2af8eca 354 let mut sptr1 = sptr0.add(sstride);
098dcca9
KS
355 let mut dptr = dst.as_mut_ptr();
356 for _ in 0..h {
357 for x in 0..w {
f2af8eca
KS
358 let a = *sptr0.add(x);
359 let b = *sptr1.add(x);
360 *dptr.add(x) = a.wrapping_add(b) >> 1;
098dcca9 361 }
f2af8eca
KS
362 sptr0 = sptr0.add(sstride);
363 sptr1 = sptr1.add(sstride);
364 dptr = dptr.add(sstride);
098dcca9 365 }
01c971c5
KS
366 }
367 },
368 3 => {
098dcca9 369 /*for _ in 0..h {
01c971c5
KS
370 for x in 0..w {
371 let val = (src[sidx + x + 0] + src[sidx + x + sstride + 0] +
372 src[sidx + x + 1] + src[sidx + x + sstride + 1]) >> 2;
373 dst[didx + x] = val;
374 }
375 sidx += sstride;
376 didx += dstride;
098dcca9
KS
377 }*/
378 unsafe {
379 let mut sptr0 = src.as_ptr();
f2af8eca 380 let mut sptr1 = sptr0.add(sstride);
098dcca9 381 let mut dptr = dst.as_mut_ptr();
098dcca9 382 for _ in 0..h {
64bb5e77
KS
383 let mut la = *sptr0;
384 let mut lb = *sptr1;
098dcca9 385 for x in 0..w {
f2af8eca
KS
386 let a = *sptr0.add(x + 1);
387 let b = *sptr1.add(x + 1);
098dcca9
KS
388 let aas = a.wrapping_add(la);
389 let bbs = b.wrapping_add(lb);
f2af8eca 390 *dptr.add(x) = aas.wrapping_add(bbs) >> 2;
098dcca9
KS
391 la = a;
392 lb = b;
393 }
f2af8eca
KS
394 sptr0 = sptr0.add(sstride);
395 sptr1 = sptr1.add(sstride);
396 dptr = dptr.add(dstride);
098dcca9 397 }
01c971c5
KS
398 }
399 },
400 _ => {},
401 }
402}
403fn ivi_mc_add(dst: &mut [i16], dstride: usize, src: &[i16], sstride: usize, mode: u8, w: usize, h: usize) {
404 let mut sidx = 0;
405 let mut didx = 0;
406 match mode {
407 0 => {
408 for _ in 0..h {
409 for x in 0..w {
410 dst[didx + x] += src[sidx + x];
411 }
412 sidx += sstride;
413 didx += dstride;
414 }
415 },
416 1 => {
417 for _ in 0..h {
418 for x in 0..w {
419 let val = (src[sidx + x] + src[sidx + x + 1]) >> 1;
420 dst[didx + x] += val;
421 }
422 sidx += sstride;
423 didx += dstride;
424 }
425 },
426 2 => {
427 for _ in 0..h {
428 for x in 0..w {
429 let val = (src[sidx + x] + src[sidx + x + sstride]) >> 1;
430 dst[didx + x] += val;
431 }
432 sidx += sstride;
433 didx += dstride;
434 }
435 },
436 3 => {
437 for _ in 0..h {
438 for x in 0..w {
439 let val = (src[sidx + x + 0] + src[sidx + x + sstride + 0] +
440 src[sidx + x + 1] + src[sidx + x + sstride + 1]) >> 2;
441 dst[didx + x] += val;
442 }
443 sidx += sstride;
444 didx += dstride;
445 }
446 },
447 _ => {},
448 }
449}
450pub fn ivi_mc_avg(dst: &mut [i16], dstride: usize,
451 src1: &[i16], sstride1: usize, mode1: u8,
452 src2: &[i16], sstride2: usize, mode2: u8,
453 w: usize, h: usize) {
454 let mut tidx = 0;
455 let tstride = 8;
456 let mut didx = 0;
457 let mut tmp: [i16; 64] = [0; 64];
458 ivi_mc_add(&mut tmp, tstride, src1, sstride1, mode1, w, h);
459 ivi_mc_add(&mut tmp, tstride, src2, sstride2, mode2, w, h);
460 for _ in 0..h {
461 for x in 0..w { dst[didx + x] = tmp[tidx + x] >> 1; }
462 tidx += tstride;
463 didx += dstride;
464 }
465}