wmv_decoder/
na_simple_idct.rs1#[inline(always)]
2fn clip_u8(x: i32) -> u8 {
3 if x < 0 {
4 0
5 } else if x > 255 {
6 255
7 } else {
8 x as u8
9 }
10}
11
12const W1: i64 = 22725;
14const W2: i64 = 21407;
15const W3: i64 = 19266;
16const W4: i64 = 16383;
17const W5: i64 = 12873;
18const W6: i64 = 8867;
19const W7: i64 = 4520;
20
21const ROW_SHIFT: i32 = 11;
22const COL_SHIFT: i32 = 20;
23const DC_SHIFT: i32 = 3;
24
25const COL_RND_W4_DIV: i16 = ((1i64 << (COL_SHIFT - 1)) / W4) as i16;
27
28#[inline(always)]
29fn idct_row_cond_dc_int16_8bit(row: &mut [i16; 8]) {
30 if row[1] == 0
32 && row[2] == 0
33 && row[3] == 0
34 && row[4] == 0
35 && row[5] == 0
36 && row[6] == 0
37 && row[7] == 0
38 {
39 let t: i16 = (((row[0] as i32) << DC_SHIFT) as i16);
40 *row = [t; 8];
41 return;
42 }
43
44 let r0 = row[0] as i64;
46 let r1 = row[1] as i64;
47 let r2 = row[2] as i64;
48 let r3 = row[3] as i64;
49 let r4 = row[4] as i64;
50 let r5 = row[5] as i64;
51 let r6 = row[6] as i64;
52 let r7 = row[7] as i64;
53
54 let mut a0 = W4 * r0 + (1i64 << (ROW_SHIFT - 1));
55 let mut a1 = a0;
56 let mut a2 = a0;
57 let mut a3 = a0;
58
59 a0 += W2 * r2;
60 a1 += W6 * r2;
61 a2 -= W6 * r2;
62 a3 -= W2 * r2;
63
64 let mut b0 = W1 * r1 + W3 * r3;
65 let mut b1 = W3 * r1 - W7 * r3;
66 let mut b2 = W5 * r1 - W1 * r3;
67 let mut b3 = W7 * r1 - W5 * r3;
68
69 if r4 != 0 || r5 != 0 || r6 != 0 || r7 != 0 {
70 a0 += W4 * r4 + W6 * r6;
71 a1 += -W4 * r4 - W2 * r6;
72 a2 += -W4 * r4 + W2 * r6;
73 a3 += W4 * r4 - W6 * r6;
74
75 b0 += W5 * r5 + W7 * r7;
76 b1 += -W1 * r5 - W5 * r7;
77 b2 += W7 * r5 + W3 * r7;
78 b3 += W3 * r5 - W1 * r7;
79 }
80
81 let rs = ROW_SHIFT as i64;
82 row[0] = ((a0 + b0) >> rs) as i16;
83 row[7] = ((a0 - b0) >> rs) as i16;
84 row[1] = ((a1 + b1) >> rs) as i16;
85 row[6] = ((a1 - b1) >> rs) as i16;
86 row[2] = ((a2 + b2) >> rs) as i16;
87 row[5] = ((a2 - b2) >> rs) as i16;
88 row[3] = ((a3 + b3) >> rs) as i16;
89 row[4] = ((a3 - b3) >> rs) as i16;
90}
91
92#[inline(always)]
93fn idct_sparse_col_int16_8bit(block: &mut [i16; 64], col: usize) {
94 let c0 = block[col + 8 * 0] as i64;
96 let c1 = block[col + 8 * 1] as i64;
97 let c2 = block[col + 8 * 2] as i64;
98 let c3 = block[col + 8 * 3] as i64;
99 let c4 = block[col + 8 * 4] as i64;
100 let c5 = block[col + 8 * 5] as i64;
101 let c6 = block[col + 8 * 6] as i64;
102 let c7 = block[col + 8 * 7] as i64;
103
104 let mut a0 = W4 * (c0 + COL_RND_W4_DIV as i64);
105 let mut a1 = a0;
106 let mut a2 = a0;
107 let mut a3 = a0;
108
109 a0 += W2 * c2;
110 a1 += W6 * c2;
111 a2 -= W6 * c2;
112 a3 -= W2 * c2;
113
114 let mut b0 = W1 * c1 + W3 * c3;
115 let mut b1 = W3 * c1 - W7 * c3;
116 let mut b2 = W5 * c1 - W1 * c3;
117 let mut b3 = W7 * c1 - W5 * c3;
118
119 if c4 != 0 {
120 a0 += W4 * c4;
121 a1 += -W4 * c4;
122 a2 += -W4 * c4;
123 a3 += W4 * c4;
124 }
125 if c5 != 0 {
126 b0 += W5 * c5;
127 b1 += -W1 * c5;
128 b2 += W7 * c5;
129 b3 += W3 * c5;
130 }
131 if c6 != 0 {
132 a0 += W6 * c6;
133 a1 += -W2 * c6;
134 a2 += W2 * c6;
135 a3 += -W6 * c6;
136 }
137 if c7 != 0 {
138 b0 += W7 * c7;
139 b1 += -W5 * c7;
140 b2 += W3 * c7;
141 b3 += -W1 * c7;
142 }
143
144 let cs = COL_SHIFT as i64;
145 block[col + 8 * 0] = ((a0 + b0) >> cs) as i16;
146 block[col + 8 * 1] = ((a1 + b1) >> cs) as i16;
147 block[col + 8 * 2] = ((a2 + b2) >> cs) as i16;
148 block[col + 8 * 3] = ((a3 + b3) >> cs) as i16;
149 block[col + 8 * 4] = ((a3 - b3) >> cs) as i16;
150 block[col + 8 * 5] = ((a2 - b2) >> cs) as i16;
151 block[col + 8 * 6] = ((a1 - b1) >> cs) as i16;
152 block[col + 8 * 7] = ((a0 - b0) >> cs) as i16;
153}
154
155#[inline(always)]
156fn idct_sparse_col_add_int16_8bit(
157 dest: &mut [u8],
158 dest_off: usize,
159 line_size: usize,
160 block: &[i16; 64],
161 col: usize,
162) {
163 let c0 = block[col + 8 * 0] as i64;
164 let c1 = block[col + 8 * 1] as i64;
165 let c2 = block[col + 8 * 2] as i64;
166 let c3 = block[col + 8 * 3] as i64;
167 let c4 = block[col + 8 * 4] as i64;
168 let c5 = block[col + 8 * 5] as i64;
169 let c6 = block[col + 8 * 6] as i64;
170 let c7 = block[col + 8 * 7] as i64;
171
172 let mut a0 = W4 * (c0 + COL_RND_W4_DIV as i64);
173 let mut a1 = a0;
174 let mut a2 = a0;
175 let mut a3 = a0;
176
177 a0 += W2 * c2;
178 a1 += W6 * c2;
179 a2 -= W6 * c2;
180 a3 -= W2 * c2;
181
182 let mut b0 = W1 * c1 + W3 * c3;
183 let mut b1 = W3 * c1 - W7 * c3;
184 let mut b2 = W5 * c1 - W1 * c3;
185 let mut b3 = W7 * c1 - W5 * c3;
186
187 if c4 != 0 {
188 a0 += W4 * c4;
189 a1 += -W4 * c4;
190 a2 += -W4 * c4;
191 a3 += W4 * c4;
192 }
193 if c5 != 0 {
194 b0 += W5 * c5;
195 b1 += -W1 * c5;
196 b2 += W7 * c5;
197 b3 += W3 * c5;
198 }
199 if c6 != 0 {
200 a0 += W6 * c6;
201 a1 += -W2 * c6;
202 a2 += W2 * c6;
203 a3 += -W6 * c6;
204 }
205 if c7 != 0 {
206 b0 += W7 * c7;
207 b1 += -W5 * c7;
208 b2 += W3 * c7;
209 b3 += -W1 * c7;
210 }
211
212 let cs = COL_SHIFT as i64;
213 let vals = [
214 ((a0 + b0) >> cs) as i32,
215 ((a1 + b1) >> cs) as i32,
216 ((a2 + b2) >> cs) as i32,
217 ((a3 + b3) >> cs) as i32,
218 ((a3 - b3) >> cs) as i32,
219 ((a2 - b2) >> cs) as i32,
220 ((a1 - b1) >> cs) as i32,
221 ((a0 - b0) >> cs) as i32,
222 ];
223
224 for r in 0..8usize {
225 let off = dest_off + r * line_size + col;
226 if off < dest.len() {
227 let cur = dest[off] as i32;
228 dest[off] = clip_u8(cur + vals[r]);
229 }
230 }
231}
232
233pub fn ff_simple_idct_int16_8bit(block: &mut [i16; 64]) {
235 for r in 0..8usize {
236 let mut row = [0i16; 8];
237 for c in 0..8usize {
238 row[c] = block[r * 8 + c];
239 }
240 idct_row_cond_dc_int16_8bit(&mut row);
241 for c in 0..8usize {
242 block[r * 8 + c] = row[c];
243 }
244 }
245 for c in 0..8usize {
246 idct_sparse_col_int16_8bit(block, c);
247 }
248}
249
250pub fn ff_simple_idct_add_int16_8bit(
252 dest: &mut [u8],
253 dest_off: usize,
254 line_size: usize,
255 block: &mut [i16; 64],
256) {
257 for r in 0..8usize {
259 let mut row = [0i16; 8];
260 for c in 0..8usize {
261 row[c] = block[r * 8 + c];
262 }
263 idct_row_cond_dc_int16_8bit(&mut row);
264 for c in 0..8usize {
265 block[r * 8 + c] = row[c];
266 }
267 }
268 let tmp = *block;
270 for c in 0..8usize {
271 idct_sparse_col_add_int16_8bit(dest, dest_off, line_size, &tmp, c);
272 }
273}
274
275const CN_SHIFT: i32 = 12;
278const RN_SHIFT: i32 = 15;
279const C_SHIFT: i32 = 17; const R_SHIFT: i32 = 11;
281
282const C1: i64 = 3784;
284const C2: i64 = 1567;
285const C3: i64 = 2896;
286
287const R1: i64 = 30274;
288const R2: i64 = 12540;
289const R3: i64 = 23170;
290
291#[inline(always)]
292fn idct4col_add(
293 dest: &mut [u8],
294 dest_off: usize,
295 line_size: usize,
296 col: &[i16; 64],
297 col_idx: usize,
298) {
299 let a0 = col[col_idx + 8 * 0] as i64;
301 let a1 = col[col_idx + 8 * 1] as i64;
302 let a2 = col[col_idx + 8 * 2] as i64;
303 let a3 = col[col_idx + 8 * 3] as i64;
304
305 let c0 = (a0 + a2) * C3 + (1i64 << (C_SHIFT - 1));
306 let c2 = (a0 - a2) * C3 + (1i64 << (C_SHIFT - 1));
307 let c1 = a1 * C1 + a3 * C2;
308 let c3 = a1 * C2 - a3 * C1;
309
310 let out = [
311 ((c0 + c1) >> C_SHIFT) as i32,
312 ((c2 + c3) >> C_SHIFT) as i32,
313 ((c2 - c3) >> C_SHIFT) as i32,
314 ((c0 - c1) >> C_SHIFT) as i32,
315 ];
316
317 for r in 0..4usize {
318 let off = dest_off + r * line_size;
319 if off < dest.len() {
320 let cur = dest[off] as i32;
321 dest[off] = clip_u8(cur + out[r]);
322 }
323 }
324}
325
326#[inline(always)]
327fn idct4row(row: &mut [i16; 8]) {
328 let a0 = row[0] as i64;
330 let a1 = row[1] as i64;
331 let a2 = row[2] as i64;
332 let a3 = row[3] as i64;
333
334 let c0 = (a0 + a2) * R3 + (1i64 << (R_SHIFT - 1));
335 let c2 = (a0 - a2) * R3 + (1i64 << (R_SHIFT - 1));
336 let c1 = a1 * R1 + a3 * R2;
337 let c3 = a1 * R2 - a3 * R1;
338
339 row[0] = ((c0 + c1) >> R_SHIFT) as i16;
340 row[1] = ((c2 + c3) >> R_SHIFT) as i16;
341 row[2] = ((c2 - c3) >> R_SHIFT) as i16;
342 row[3] = ((c0 - c1) >> R_SHIFT) as i16;
343}
344
345pub fn ff_simple_idct84_add(
347 dest: &mut [u8],
348 dest_off: usize,
349 line_size: usize,
350 block: &mut [i16; 64],
351) {
352 for r in 0..4usize {
354 let mut row = [0i16; 8];
355 for c in 0..8usize {
356 row[c] = block[r * 8 + c];
357 }
358 idct_row_cond_dc_int16_8bit(&mut row);
359 for c in 0..8usize {
360 block[r * 8 + c] = row[c];
361 }
362 }
363 let snap = *block;
364 for c in 0..8usize {
365 idct4col_add(dest, dest_off + c, line_size, &snap, c);
366 }
367}
368
369pub fn ff_simple_idct48_add(
371 dest: &mut [u8],
372 dest_off: usize,
373 line_size: usize,
374 block: &mut [i16; 64],
375) {
376 for r in 0..8usize {
378 let mut row = [0i16; 8];
379 for c in 0..8usize {
380 row[c] = block[r * 8 + c];
381 }
382 idct4row(&mut row);
383 for c in 0..8usize {
384 block[r * 8 + c] = row[c];
385 }
386 }
387 let snap = *block;
389 for c in 0..4usize {
390 idct_sparse_col_add_int16_8bit(dest, dest_off, line_size, &snap, c);
391 }
392}