]> granicus.if.org Git - libvpx/blob - vpx_dsp/fwd_txfm.c
Merge "Extend the external fb interface to allocate individual planes."
[libvpx] / vpx_dsp / fwd_txfm.c
1 /*
2  *  Copyright (c) 2015 The WebM project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10
11 #include "./vpx_dsp_rtcd.h"
12 #include "vpx_dsp/fwd_txfm.h"
13
14 void vpx_fdct4x4_c(const int16_t *input, tran_low_t *output, int stride) {
15   // The 2D transform is done with two passes which are actually pretty
16   // similar. In the first one, we transform the columns and transpose
17   // the results. In the second one, we transform the rows. To achieve that,
18   // as the first pass results are transposed, we transpose the columns (that
19   // is the transposed rows) and transpose the results (so that it goes back
20   // in normal/row positions).
21   int pass;
22   // We need an intermediate buffer between passes.
23   tran_low_t intermediate[4 * 4];
24   const int16_t *in_pass0 = input;
25   const tran_low_t *in = NULL;
26   tran_low_t *out = intermediate;
27   // Do the two transform/transpose passes
28   for (pass = 0; pass < 2; ++pass) {
29     tran_high_t input[4];      // canbe16
30     tran_high_t step[4];       // canbe16
31     tran_high_t temp1, temp2;  // needs32
32     int i;
33     for (i = 0; i < 4; ++i) {
34       // Load inputs.
35       if (0 == pass) {
36         input[0] = in_pass0[0 * stride] * 16;
37         input[1] = in_pass0[1 * stride] * 16;
38         input[2] = in_pass0[2 * stride] * 16;
39         input[3] = in_pass0[3 * stride] * 16;
40         if (i == 0 && input[0]) {
41           input[0] += 1;
42         }
43       } else {
44         input[0] = in[0 * 4];
45         input[1] = in[1 * 4];
46         input[2] = in[2 * 4];
47         input[3] = in[3 * 4];
48       }
49       // Transform.
50       step[0] = input[0] + input[3];
51       step[1] = input[1] + input[2];
52       step[2] = input[1] - input[2];
53       step[3] = input[0] - input[3];
54       temp1 = (step[0] + step[1]) * cospi_16_64;
55       temp2 = (step[0] - step[1]) * cospi_16_64;
56       out[0] = (tran_low_t)fdct_round_shift(temp1);
57       out[2] = (tran_low_t)fdct_round_shift(temp2);
58       temp1 = step[2] * cospi_24_64 + step[3] * cospi_8_64;
59       temp2 = -step[2] * cospi_8_64 + step[3] * cospi_24_64;
60       out[1] = (tran_low_t)fdct_round_shift(temp1);
61       out[3] = (tran_low_t)fdct_round_shift(temp2);
62       // Do next column (which is a transposed row in second/horizontal pass)
63       in_pass0++;
64       in++;
65       out += 4;
66     }
67     // Setup in/out for next pass.
68     in = intermediate;
69     out = output;
70   }
71
72   {
73     int i, j;
74     for (i = 0; i < 4; ++i) {
75       for (j = 0; j < 4; ++j)
76         output[j + i * 4] = (output[j + i * 4] + 1) >> 2;
77     }
78   }
79 }
80
81 void vpx_fdct4x4_1_c(const int16_t *input, tran_low_t *output, int stride) {
82   int r, c;
83   tran_low_t sum = 0;
84   for (r = 0; r < 4; ++r)
85     for (c = 0; c < 4; ++c)
86       sum += input[r * stride + c];
87
88   output[0] = sum << 1;
89 }
90
91 void vpx_fdct8x8_c(const int16_t *input, tran_low_t *final_output, int stride) {
92   int i, j;
93   tran_low_t intermediate[64];
94   int pass;
95   tran_low_t *output = intermediate;
96   const tran_low_t *in = NULL;
97
98   // Transform columns
99   for (pass = 0; pass < 2; ++pass) {
100     tran_high_t s0, s1, s2, s3, s4, s5, s6, s7;  // canbe16
101     tran_high_t t0, t1, t2, t3;                  // needs32
102     tran_high_t x0, x1, x2, x3;                  // canbe16
103
104     int i;
105     for (i = 0; i < 8; i++) {
106       // stage 1
107       if (pass == 0) {
108         s0 = (input[0 * stride] + input[7 * stride]) * 4;
109         s1 = (input[1 * stride] + input[6 * stride]) * 4;
110         s2 = (input[2 * stride] + input[5 * stride]) * 4;
111         s3 = (input[3 * stride] + input[4 * stride]) * 4;
112         s4 = (input[3 * stride] - input[4 * stride]) * 4;
113         s5 = (input[2 * stride] - input[5 * stride]) * 4;
114         s6 = (input[1 * stride] - input[6 * stride]) * 4;
115         s7 = (input[0 * stride] - input[7 * stride]) * 4;
116         ++input;
117       } else {
118         s0 = in[0 * 8] + in[7 * 8];
119         s1 = in[1 * 8] + in[6 * 8];
120         s2 = in[2 * 8] + in[5 * 8];
121         s3 = in[3 * 8] + in[4 * 8];
122         s4 = in[3 * 8] - in[4 * 8];
123         s5 = in[2 * 8] - in[5 * 8];
124         s6 = in[1 * 8] - in[6 * 8];
125         s7 = in[0 * 8] - in[7 * 8];
126         ++in;
127       }
128
129       // fdct4(step, step);
130       x0 = s0 + s3;
131       x1 = s1 + s2;
132       x2 = s1 - s2;
133       x3 = s0 - s3;
134       t0 = (x0 + x1) * cospi_16_64;
135       t1 = (x0 - x1) * cospi_16_64;
136       t2 =  x2 * cospi_24_64 + x3 *  cospi_8_64;
137       t3 = -x2 * cospi_8_64  + x3 * cospi_24_64;
138       output[0] = (tran_low_t)fdct_round_shift(t0);
139       output[2] = (tran_low_t)fdct_round_shift(t2);
140       output[4] = (tran_low_t)fdct_round_shift(t1);
141       output[6] = (tran_low_t)fdct_round_shift(t3);
142
143       // Stage 2
144       t0 = (s6 - s5) * cospi_16_64;
145       t1 = (s6 + s5) * cospi_16_64;
146       t2 = fdct_round_shift(t0);
147       t3 = fdct_round_shift(t1);
148
149       // Stage 3
150       x0 = s4 + t2;
151       x1 = s4 - t2;
152       x2 = s7 - t3;
153       x3 = s7 + t3;
154
155       // Stage 4
156       t0 = x0 * cospi_28_64 + x3 *   cospi_4_64;
157       t1 = x1 * cospi_12_64 + x2 *  cospi_20_64;
158       t2 = x2 * cospi_12_64 + x1 * -cospi_20_64;
159       t3 = x3 * cospi_28_64 + x0 *  -cospi_4_64;
160       output[1] = (tran_low_t)fdct_round_shift(t0);
161       output[3] = (tran_low_t)fdct_round_shift(t2);
162       output[5] = (tran_low_t)fdct_round_shift(t1);
163       output[7] = (tran_low_t)fdct_round_shift(t3);
164       output += 8;
165     }
166     in  = intermediate;
167     output = final_output;
168   }
169
170   // Rows
171   for (i = 0; i < 8; ++i) {
172     for (j = 0; j < 8; ++j)
173       final_output[j + i * 8] /= 2;
174   }
175 }
176
177 void vpx_fdct8x8_1_c(const int16_t *input, tran_low_t *output, int stride) {
178   int r, c;
179   tran_low_t sum = 0;
180   for (r = 0; r < 8; ++r)
181     for (c = 0; c < 8; ++c)
182       sum += input[r * stride + c];
183
184   output[0] = sum;
185 }
186
187 void vpx_fdct16x16_c(const int16_t *input, tran_low_t *output, int stride) {
188   // The 2D transform is done with two passes which are actually pretty
189   // similar. In the first one, we transform the columns and transpose
190   // the results. In the second one, we transform the rows. To achieve that,
191   // as the first pass results are transposed, we transpose the columns (that
192   // is the transposed rows) and transpose the results (so that it goes back
193   // in normal/row positions).
194   int pass;
195   // We need an intermediate buffer between passes.
196   tran_low_t intermediate[256];
197   const int16_t *in_pass0 = input;
198   const tran_low_t *in = NULL;
199   tran_low_t *out = intermediate;
200   // Do the two transform/transpose passes
201   for (pass = 0; pass < 2; ++pass) {
202     tran_high_t step1[8];      // canbe16
203     tran_high_t step2[8];      // canbe16
204     tran_high_t step3[8];      // canbe16
205     tran_high_t input[8];      // canbe16
206     tran_high_t temp1, temp2;  // needs32
207     int i;
208     for (i = 0; i < 16; i++) {
209       if (0 == pass) {
210         // Calculate input for the first 8 results.
211         input[0] = (in_pass0[0 * stride] + in_pass0[15 * stride]) * 4;
212         input[1] = (in_pass0[1 * stride] + in_pass0[14 * stride]) * 4;
213         input[2] = (in_pass0[2 * stride] + in_pass0[13 * stride]) * 4;
214         input[3] = (in_pass0[3 * stride] + in_pass0[12 * stride]) * 4;
215         input[4] = (in_pass0[4 * stride] + in_pass0[11 * stride]) * 4;
216         input[5] = (in_pass0[5 * stride] + in_pass0[10 * stride]) * 4;
217         input[6] = (in_pass0[6 * stride] + in_pass0[ 9 * stride]) * 4;
218         input[7] = (in_pass0[7 * stride] + in_pass0[ 8 * stride]) * 4;
219         // Calculate input for the next 8 results.
220         step1[0] = (in_pass0[7 * stride] - in_pass0[ 8 * stride]) * 4;
221         step1[1] = (in_pass0[6 * stride] - in_pass0[ 9 * stride]) * 4;
222         step1[2] = (in_pass0[5 * stride] - in_pass0[10 * stride]) * 4;
223         step1[3] = (in_pass0[4 * stride] - in_pass0[11 * stride]) * 4;
224         step1[4] = (in_pass0[3 * stride] - in_pass0[12 * stride]) * 4;
225         step1[5] = (in_pass0[2 * stride] - in_pass0[13 * stride]) * 4;
226         step1[6] = (in_pass0[1 * stride] - in_pass0[14 * stride]) * 4;
227         step1[7] = (in_pass0[0 * stride] - in_pass0[15 * stride]) * 4;
228       } else {
229         // Calculate input for the first 8 results.
230         input[0] = ((in[0 * 16] + 1) >> 2) + ((in[15 * 16] + 1) >> 2);
231         input[1] = ((in[1 * 16] + 1) >> 2) + ((in[14 * 16] + 1) >> 2);
232         input[2] = ((in[2 * 16] + 1) >> 2) + ((in[13 * 16] + 1) >> 2);
233         input[3] = ((in[3 * 16] + 1) >> 2) + ((in[12 * 16] + 1) >> 2);
234         input[4] = ((in[4 * 16] + 1) >> 2) + ((in[11 * 16] + 1) >> 2);
235         input[5] = ((in[5 * 16] + 1) >> 2) + ((in[10 * 16] + 1) >> 2);
236         input[6] = ((in[6 * 16] + 1) >> 2) + ((in[ 9 * 16] + 1) >> 2);
237         input[7] = ((in[7 * 16] + 1) >> 2) + ((in[ 8 * 16] + 1) >> 2);
238         // Calculate input for the next 8 results.
239         step1[0] = ((in[7 * 16] + 1) >> 2) - ((in[ 8 * 16] + 1) >> 2);
240         step1[1] = ((in[6 * 16] + 1) >> 2) - ((in[ 9 * 16] + 1) >> 2);
241         step1[2] = ((in[5 * 16] + 1) >> 2) - ((in[10 * 16] + 1) >> 2);
242         step1[3] = ((in[4 * 16] + 1) >> 2) - ((in[11 * 16] + 1) >> 2);
243         step1[4] = ((in[3 * 16] + 1) >> 2) - ((in[12 * 16] + 1) >> 2);
244         step1[5] = ((in[2 * 16] + 1) >> 2) - ((in[13 * 16] + 1) >> 2);
245         step1[6] = ((in[1 * 16] + 1) >> 2) - ((in[14 * 16] + 1) >> 2);
246         step1[7] = ((in[0 * 16] + 1) >> 2) - ((in[15 * 16] + 1) >> 2);
247       }
248       // Work on the first eight values; fdct8(input, even_results);
249       {
250         tran_high_t s0, s1, s2, s3, s4, s5, s6, s7;  // canbe16
251         tran_high_t t0, t1, t2, t3;                  // needs32
252         tran_high_t x0, x1, x2, x3;                  // canbe16
253
254         // stage 1
255         s0 = input[0] + input[7];
256         s1 = input[1] + input[6];
257         s2 = input[2] + input[5];
258         s3 = input[3] + input[4];
259         s4 = input[3] - input[4];
260         s5 = input[2] - input[5];
261         s6 = input[1] - input[6];
262         s7 = input[0] - input[7];
263
264         // fdct4(step, step);
265         x0 = s0 + s3;
266         x1 = s1 + s2;
267         x2 = s1 - s2;
268         x3 = s0 - s3;
269         t0 = (x0 + x1) * cospi_16_64;
270         t1 = (x0 - x1) * cospi_16_64;
271         t2 = x3 * cospi_8_64  + x2 * cospi_24_64;
272         t3 = x3 * cospi_24_64 - x2 * cospi_8_64;
273         out[0] = (tran_low_t)fdct_round_shift(t0);
274         out[4] = (tran_low_t)fdct_round_shift(t2);
275         out[8] = (tran_low_t)fdct_round_shift(t1);
276         out[12] = (tran_low_t)fdct_round_shift(t3);
277
278         // Stage 2
279         t0 = (s6 - s5) * cospi_16_64;
280         t1 = (s6 + s5) * cospi_16_64;
281         t2 = fdct_round_shift(t0);
282         t3 = fdct_round_shift(t1);
283
284         // Stage 3
285         x0 = s4 + t2;
286         x1 = s4 - t2;
287         x2 = s7 - t3;
288         x3 = s7 + t3;
289
290         // Stage 4
291         t0 = x0 * cospi_28_64 + x3 *   cospi_4_64;
292         t1 = x1 * cospi_12_64 + x2 *  cospi_20_64;
293         t2 = x2 * cospi_12_64 + x1 * -cospi_20_64;
294         t3 = x3 * cospi_28_64 + x0 *  -cospi_4_64;
295         out[2] = (tran_low_t)fdct_round_shift(t0);
296         out[6] = (tran_low_t)fdct_round_shift(t2);
297         out[10] = (tran_low_t)fdct_round_shift(t1);
298         out[14] = (tran_low_t)fdct_round_shift(t3);
299       }
300       // Work on the next eight values; step1 -> odd_results
301       {
302         // step 2
303         temp1 = (step1[5] - step1[2]) * cospi_16_64;
304         temp2 = (step1[4] - step1[3]) * cospi_16_64;
305         step2[2] = fdct_round_shift(temp1);
306         step2[3] = fdct_round_shift(temp2);
307         temp1 = (step1[4] + step1[3]) * cospi_16_64;
308         temp2 = (step1[5] + step1[2]) * cospi_16_64;
309         step2[4] = fdct_round_shift(temp1);
310         step2[5] = fdct_round_shift(temp2);
311         // step 3
312         step3[0] = step1[0] + step2[3];
313         step3[1] = step1[1] + step2[2];
314         step3[2] = step1[1] - step2[2];
315         step3[3] = step1[0] - step2[3];
316         step3[4] = step1[7] - step2[4];
317         step3[5] = step1[6] - step2[5];
318         step3[6] = step1[6] + step2[5];
319         step3[7] = step1[7] + step2[4];
320         // step 4
321         temp1 = step3[1] *  -cospi_8_64 + step3[6] * cospi_24_64;
322         temp2 = step3[2] * cospi_24_64 + step3[5] *  cospi_8_64;
323         step2[1] = fdct_round_shift(temp1);
324         step2[2] = fdct_round_shift(temp2);
325         temp1 = step3[2] * cospi_8_64 - step3[5] * cospi_24_64;
326         temp2 = step3[1] * cospi_24_64 + step3[6] *  cospi_8_64;
327         step2[5] = fdct_round_shift(temp1);
328         step2[6] = fdct_round_shift(temp2);
329         // step 5
330         step1[0] = step3[0] + step2[1];
331         step1[1] = step3[0] - step2[1];
332         step1[2] = step3[3] + step2[2];
333         step1[3] = step3[3] - step2[2];
334         step1[4] = step3[4] - step2[5];
335         step1[5] = step3[4] + step2[5];
336         step1[6] = step3[7] - step2[6];
337         step1[7] = step3[7] + step2[6];
338         // step 6
339         temp1 = step1[0] * cospi_30_64 + step1[7] *  cospi_2_64;
340         temp2 = step1[1] * cospi_14_64 + step1[6] * cospi_18_64;
341         out[1] = (tran_low_t)fdct_round_shift(temp1);
342         out[9] = (tran_low_t)fdct_round_shift(temp2);
343         temp1 = step1[2] * cospi_22_64 + step1[5] * cospi_10_64;
344         temp2 = step1[3] *  cospi_6_64 + step1[4] * cospi_26_64;
345         out[5] = (tran_low_t)fdct_round_shift(temp1);
346         out[13] = (tran_low_t)fdct_round_shift(temp2);
347         temp1 = step1[3] * -cospi_26_64 + step1[4] *  cospi_6_64;
348         temp2 = step1[2] * -cospi_10_64 + step1[5] * cospi_22_64;
349         out[3] = (tran_low_t)fdct_round_shift(temp1);
350         out[11] = (tran_low_t)fdct_round_shift(temp2);
351         temp1 = step1[1] * -cospi_18_64 + step1[6] * cospi_14_64;
352         temp2 = step1[0] *  -cospi_2_64 + step1[7] * cospi_30_64;
353         out[7] = (tran_low_t)fdct_round_shift(temp1);
354         out[15] = (tran_low_t)fdct_round_shift(temp2);
355       }
356       // Do next column (which is a transposed row in second/horizontal pass)
357       in++;
358       in_pass0++;
359       out += 16;
360     }
361     // Setup in/out for next pass.
362     in = intermediate;
363     out = output;
364   }
365 }
366
367 void vpx_fdct16x16_1_c(const int16_t *input, tran_low_t *output, int stride) {
368   int r, c;
369   int sum = 0;
370   for (r = 0; r < 16; ++r)
371     for (c = 0; c < 16; ++c)
372       sum += input[r * stride + c];
373
374   output[0] = (tran_low_t)(sum >> 1);
375 }
376
377 static INLINE tran_high_t dct_32_round(tran_high_t input) {
378   tran_high_t rv = ROUND_POWER_OF_TWO(input, DCT_CONST_BITS);
379   // TODO(debargha, peter.derivaz): Find new bounds for this assert,
380   // and make the bounds consts.
381   // assert(-131072 <= rv && rv <= 131071);
382   return rv;
383 }
384
385 static INLINE tran_high_t half_round_shift(tran_high_t input) {
386   tran_high_t rv = (input + 1 + (input < 0)) >> 2;
387   return rv;
388 }
389
390 void vpx_fdct32(const tran_high_t *input, tran_high_t *output, int round) {
391   tran_high_t step[32];
392   // Stage 1
393   step[0] = input[0] + input[(32 - 1)];
394   step[1] = input[1] + input[(32 - 2)];
395   step[2] = input[2] + input[(32 - 3)];
396   step[3] = input[3] + input[(32 - 4)];
397   step[4] = input[4] + input[(32 - 5)];
398   step[5] = input[5] + input[(32 - 6)];
399   step[6] = input[6] + input[(32 - 7)];
400   step[7] = input[7] + input[(32 - 8)];
401   step[8] = input[8] + input[(32 - 9)];
402   step[9] = input[9] + input[(32 - 10)];
403   step[10] = input[10] + input[(32 - 11)];
404   step[11] = input[11] + input[(32 - 12)];
405   step[12] = input[12] + input[(32 - 13)];
406   step[13] = input[13] + input[(32 - 14)];
407   step[14] = input[14] + input[(32 - 15)];
408   step[15] = input[15] + input[(32 - 16)];
409   step[16] = -input[16] + input[(32 - 17)];
410   step[17] = -input[17] + input[(32 - 18)];
411   step[18] = -input[18] + input[(32 - 19)];
412   step[19] = -input[19] + input[(32 - 20)];
413   step[20] = -input[20] + input[(32 - 21)];
414   step[21] = -input[21] + input[(32 - 22)];
415   step[22] = -input[22] + input[(32 - 23)];
416   step[23] = -input[23] + input[(32 - 24)];
417   step[24] = -input[24] + input[(32 - 25)];
418   step[25] = -input[25] + input[(32 - 26)];
419   step[26] = -input[26] + input[(32 - 27)];
420   step[27] = -input[27] + input[(32 - 28)];
421   step[28] = -input[28] + input[(32 - 29)];
422   step[29] = -input[29] + input[(32 - 30)];
423   step[30] = -input[30] + input[(32 - 31)];
424   step[31] = -input[31] + input[(32 - 32)];
425
426   // Stage 2
427   output[0] = step[0] + step[16 - 1];
428   output[1] = step[1] + step[16 - 2];
429   output[2] = step[2] + step[16 - 3];
430   output[3] = step[3] + step[16 - 4];
431   output[4] = step[4] + step[16 - 5];
432   output[5] = step[5] + step[16 - 6];
433   output[6] = step[6] + step[16 - 7];
434   output[7] = step[7] + step[16 - 8];
435   output[8] = -step[8] + step[16 - 9];
436   output[9] = -step[9] + step[16 - 10];
437   output[10] = -step[10] + step[16 - 11];
438   output[11] = -step[11] + step[16 - 12];
439   output[12] = -step[12] + step[16 - 13];
440   output[13] = -step[13] + step[16 - 14];
441   output[14] = -step[14] + step[16 - 15];
442   output[15] = -step[15] + step[16 - 16];
443
444   output[16] = step[16];
445   output[17] = step[17];
446   output[18] = step[18];
447   output[19] = step[19];
448
449   output[20] = dct_32_round((-step[20] + step[27]) * cospi_16_64);
450   output[21] = dct_32_round((-step[21] + step[26]) * cospi_16_64);
451   output[22] = dct_32_round((-step[22] + step[25]) * cospi_16_64);
452   output[23] = dct_32_round((-step[23] + step[24]) * cospi_16_64);
453
454   output[24] = dct_32_round((step[24] + step[23]) * cospi_16_64);
455   output[25] = dct_32_round((step[25] + step[22]) * cospi_16_64);
456   output[26] = dct_32_round((step[26] + step[21]) * cospi_16_64);
457   output[27] = dct_32_round((step[27] + step[20]) * cospi_16_64);
458
459   output[28] = step[28];
460   output[29] = step[29];
461   output[30] = step[30];
462   output[31] = step[31];
463
464   // dump the magnitude by 4, hence the intermediate values are within
465   // the range of 16 bits.
466   if (round) {
467     output[0] = half_round_shift(output[0]);
468     output[1] = half_round_shift(output[1]);
469     output[2] = half_round_shift(output[2]);
470     output[3] = half_round_shift(output[3]);
471     output[4] = half_round_shift(output[4]);
472     output[5] = half_round_shift(output[5]);
473     output[6] = half_round_shift(output[6]);
474     output[7] = half_round_shift(output[7]);
475     output[8] = half_round_shift(output[8]);
476     output[9] = half_round_shift(output[9]);
477     output[10] = half_round_shift(output[10]);
478     output[11] = half_round_shift(output[11]);
479     output[12] = half_round_shift(output[12]);
480     output[13] = half_round_shift(output[13]);
481     output[14] = half_round_shift(output[14]);
482     output[15] = half_round_shift(output[15]);
483
484     output[16] = half_round_shift(output[16]);
485     output[17] = half_round_shift(output[17]);
486     output[18] = half_round_shift(output[18]);
487     output[19] = half_round_shift(output[19]);
488     output[20] = half_round_shift(output[20]);
489     output[21] = half_round_shift(output[21]);
490     output[22] = half_round_shift(output[22]);
491     output[23] = half_round_shift(output[23]);
492     output[24] = half_round_shift(output[24]);
493     output[25] = half_round_shift(output[25]);
494     output[26] = half_round_shift(output[26]);
495     output[27] = half_round_shift(output[27]);
496     output[28] = half_round_shift(output[28]);
497     output[29] = half_round_shift(output[29]);
498     output[30] = half_round_shift(output[30]);
499     output[31] = half_round_shift(output[31]);
500   }
501
502   // Stage 3
503   step[0] = output[0] + output[(8 - 1)];
504   step[1] = output[1] + output[(8 - 2)];
505   step[2] = output[2] + output[(8 - 3)];
506   step[3] = output[3] + output[(8 - 4)];
507   step[4] = -output[4] + output[(8 - 5)];
508   step[5] = -output[5] + output[(8 - 6)];
509   step[6] = -output[6] + output[(8 - 7)];
510   step[7] = -output[7] + output[(8 - 8)];
511   step[8] = output[8];
512   step[9] = output[9];
513   step[10] = dct_32_round((-output[10] + output[13]) * cospi_16_64);
514   step[11] = dct_32_round((-output[11] + output[12]) * cospi_16_64);
515   step[12] = dct_32_round((output[12] + output[11]) * cospi_16_64);
516   step[13] = dct_32_round((output[13] + output[10]) * cospi_16_64);
517   step[14] = output[14];
518   step[15] = output[15];
519
520   step[16] = output[16] + output[23];
521   step[17] = output[17] + output[22];
522   step[18] = output[18] + output[21];
523   step[19] = output[19] + output[20];
524   step[20] = -output[20] + output[19];
525   step[21] = -output[21] + output[18];
526   step[22] = -output[22] + output[17];
527   step[23] = -output[23] + output[16];
528   step[24] = -output[24] + output[31];
529   step[25] = -output[25] + output[30];
530   step[26] = -output[26] + output[29];
531   step[27] = -output[27] + output[28];
532   step[28] = output[28] + output[27];
533   step[29] = output[29] + output[26];
534   step[30] = output[30] + output[25];
535   step[31] = output[31] + output[24];
536
537   // Stage 4
538   output[0] = step[0] + step[3];
539   output[1] = step[1] + step[2];
540   output[2] = -step[2] + step[1];
541   output[3] = -step[3] + step[0];
542   output[4] = step[4];
543   output[5] = dct_32_round((-step[5] + step[6]) * cospi_16_64);
544   output[6] = dct_32_round((step[6] + step[5]) * cospi_16_64);
545   output[7] = step[7];
546   output[8] = step[8] + step[11];
547   output[9] = step[9] + step[10];
548   output[10] = -step[10] + step[9];
549   output[11] = -step[11] + step[8];
550   output[12] = -step[12] + step[15];
551   output[13] = -step[13] + step[14];
552   output[14] = step[14] + step[13];
553   output[15] = step[15] + step[12];
554
555   output[16] = step[16];
556   output[17] = step[17];
557   output[18] = dct_32_round(step[18] * -cospi_8_64 + step[29] * cospi_24_64);
558   output[19] = dct_32_round(step[19] * -cospi_8_64 + step[28] * cospi_24_64);
559   output[20] = dct_32_round(step[20] * -cospi_24_64 + step[27] * -cospi_8_64);
560   output[21] = dct_32_round(step[21] * -cospi_24_64 + step[26] * -cospi_8_64);
561   output[22] = step[22];
562   output[23] = step[23];
563   output[24] = step[24];
564   output[25] = step[25];
565   output[26] = dct_32_round(step[26] * cospi_24_64 + step[21] * -cospi_8_64);
566   output[27] = dct_32_round(step[27] * cospi_24_64 + step[20] * -cospi_8_64);
567   output[28] = dct_32_round(step[28] * cospi_8_64 + step[19] * cospi_24_64);
568   output[29] = dct_32_round(step[29] * cospi_8_64 + step[18] * cospi_24_64);
569   output[30] = step[30];
570   output[31] = step[31];
571
572   // Stage 5
573   step[0] = dct_32_round((output[0] + output[1]) * cospi_16_64);
574   step[1] = dct_32_round((-output[1] + output[0]) * cospi_16_64);
575   step[2] = dct_32_round(output[2] * cospi_24_64 + output[3] * cospi_8_64);
576   step[3] = dct_32_round(output[3] * cospi_24_64 - output[2] * cospi_8_64);
577   step[4] = output[4] + output[5];
578   step[5] = -output[5] + output[4];
579   step[6] = -output[6] + output[7];
580   step[7] = output[7] + output[6];
581   step[8] = output[8];
582   step[9] = dct_32_round(output[9] * -cospi_8_64 + output[14] * cospi_24_64);
583   step[10] = dct_32_round(output[10] * -cospi_24_64 + output[13] * -cospi_8_64);
584   step[11] = output[11];
585   step[12] = output[12];
586   step[13] = dct_32_round(output[13] * cospi_24_64 + output[10] * -cospi_8_64);
587   step[14] = dct_32_round(output[14] * cospi_8_64 + output[9] * cospi_24_64);
588   step[15] = output[15];
589
590   step[16] = output[16] + output[19];
591   step[17] = output[17] + output[18];
592   step[18] = -output[18] + output[17];
593   step[19] = -output[19] + output[16];
594   step[20] = -output[20] + output[23];
595   step[21] = -output[21] + output[22];
596   step[22] = output[22] + output[21];
597   step[23] = output[23] + output[20];
598   step[24] = output[24] + output[27];
599   step[25] = output[25] + output[26];
600   step[26] = -output[26] + output[25];
601   step[27] = -output[27] + output[24];
602   step[28] = -output[28] + output[31];
603   step[29] = -output[29] + output[30];
604   step[30] = output[30] + output[29];
605   step[31] = output[31] + output[28];
606
607   // Stage 6
608   output[0] = step[0];
609   output[1] = step[1];
610   output[2] = step[2];
611   output[3] = step[3];
612   output[4] = dct_32_round(step[4] * cospi_28_64 + step[7] * cospi_4_64);
613   output[5] = dct_32_round(step[5] * cospi_12_64 + step[6] * cospi_20_64);
614   output[6] = dct_32_round(step[6] * cospi_12_64 + step[5] * -cospi_20_64);
615   output[7] = dct_32_round(step[7] * cospi_28_64 + step[4] * -cospi_4_64);
616   output[8] = step[8] + step[9];
617   output[9] = -step[9] + step[8];
618   output[10] = -step[10] + step[11];
619   output[11] = step[11] + step[10];
620   output[12] = step[12] + step[13];
621   output[13] = -step[13] + step[12];
622   output[14] = -step[14] + step[15];
623   output[15] = step[15] + step[14];
624
625   output[16] = step[16];
626   output[17] = dct_32_round(step[17] * -cospi_4_64 + step[30] * cospi_28_64);
627   output[18] = dct_32_round(step[18] * -cospi_28_64 + step[29] * -cospi_4_64);
628   output[19] = step[19];
629   output[20] = step[20];
630   output[21] = dct_32_round(step[21] * -cospi_20_64 + step[26] * cospi_12_64);
631   output[22] = dct_32_round(step[22] * -cospi_12_64 + step[25] * -cospi_20_64);
632   output[23] = step[23];
633   output[24] = step[24];
634   output[25] = dct_32_round(step[25] * cospi_12_64 + step[22] * -cospi_20_64);
635   output[26] = dct_32_round(step[26] * cospi_20_64 + step[21] * cospi_12_64);
636   output[27] = step[27];
637   output[28] = step[28];
638   output[29] = dct_32_round(step[29] * cospi_28_64 + step[18] * -cospi_4_64);
639   output[30] = dct_32_round(step[30] * cospi_4_64 + step[17] * cospi_28_64);
640   output[31] = step[31];
641
642   // Stage 7
643   step[0] = output[0];
644   step[1] = output[1];
645   step[2] = output[2];
646   step[3] = output[3];
647   step[4] = output[4];
648   step[5] = output[5];
649   step[6] = output[6];
650   step[7] = output[7];
651   step[8] = dct_32_round(output[8] * cospi_30_64 + output[15] * cospi_2_64);
652   step[9] = dct_32_round(output[9] * cospi_14_64 + output[14] * cospi_18_64);
653   step[10] = dct_32_round(output[10] * cospi_22_64 + output[13] * cospi_10_64);
654   step[11] = dct_32_round(output[11] * cospi_6_64 + output[12] * cospi_26_64);
655   step[12] = dct_32_round(output[12] * cospi_6_64 + output[11] * -cospi_26_64);
656   step[13] = dct_32_round(output[13] * cospi_22_64 + output[10] * -cospi_10_64);
657   step[14] = dct_32_round(output[14] * cospi_14_64 + output[9] * -cospi_18_64);
658   step[15] = dct_32_round(output[15] * cospi_30_64 + output[8] * -cospi_2_64);
659
660   step[16] = output[16] + output[17];
661   step[17] = -output[17] + output[16];
662   step[18] = -output[18] + output[19];
663   step[19] = output[19] + output[18];
664   step[20] = output[20] + output[21];
665   step[21] = -output[21] + output[20];
666   step[22] = -output[22] + output[23];
667   step[23] = output[23] + output[22];
668   step[24] = output[24] + output[25];
669   step[25] = -output[25] + output[24];
670   step[26] = -output[26] + output[27];
671   step[27] = output[27] + output[26];
672   step[28] = output[28] + output[29];
673   step[29] = -output[29] + output[28];
674   step[30] = -output[30] + output[31];
675   step[31] = output[31] + output[30];
676
677   // Final stage --- outputs indices are bit-reversed.
678   output[0]  = step[0];
679   output[16] = step[1];
680   output[8]  = step[2];
681   output[24] = step[3];
682   output[4]  = step[4];
683   output[20] = step[5];
684   output[12] = step[6];
685   output[28] = step[7];
686   output[2]  = step[8];
687   output[18] = step[9];
688   output[10] = step[10];
689   output[26] = step[11];
690   output[6]  = step[12];
691   output[22] = step[13];
692   output[14] = step[14];
693   output[30] = step[15];
694
695   output[1]  = dct_32_round(step[16] * cospi_31_64 + step[31] * cospi_1_64);
696   output[17] = dct_32_round(step[17] * cospi_15_64 + step[30] * cospi_17_64);
697   output[9]  = dct_32_round(step[18] * cospi_23_64 + step[29] * cospi_9_64);
698   output[25] = dct_32_round(step[19] * cospi_7_64 + step[28] * cospi_25_64);
699   output[5]  = dct_32_round(step[20] * cospi_27_64 + step[27] * cospi_5_64);
700   output[21] = dct_32_round(step[21] * cospi_11_64 + step[26] * cospi_21_64);
701   output[13] = dct_32_round(step[22] * cospi_19_64 + step[25] * cospi_13_64);
702   output[29] = dct_32_round(step[23] * cospi_3_64 + step[24] * cospi_29_64);
703   output[3]  = dct_32_round(step[24] * cospi_3_64 + step[23] * -cospi_29_64);
704   output[19] = dct_32_round(step[25] * cospi_19_64 + step[22] * -cospi_13_64);
705   output[11] = dct_32_round(step[26] * cospi_11_64 + step[21] * -cospi_21_64);
706   output[27] = dct_32_round(step[27] * cospi_27_64 + step[20] * -cospi_5_64);
707   output[7]  = dct_32_round(step[28] * cospi_7_64 + step[19] * -cospi_25_64);
708   output[23] = dct_32_round(step[29] * cospi_23_64 + step[18] * -cospi_9_64);
709   output[15] = dct_32_round(step[30] * cospi_15_64 + step[17] * -cospi_17_64);
710   output[31] = dct_32_round(step[31] * cospi_31_64 + step[16] * -cospi_1_64);
711 }
712
713 void vpx_fdct32x32_c(const int16_t *input, tran_low_t *out, int stride) {
714   int i, j;
715   tran_high_t output[32 * 32];
716
717   // Columns
718   for (i = 0; i < 32; ++i) {
719     tran_high_t temp_in[32], temp_out[32];
720     for (j = 0; j < 32; ++j)
721       temp_in[j] = input[j * stride + i] * 4;
722     vpx_fdct32(temp_in, temp_out, 0);
723     for (j = 0; j < 32; ++j)
724       output[j * 32 + i] = (temp_out[j] + 1 + (temp_out[j] > 0)) >> 2;
725   }
726
727   // Rows
728   for (i = 0; i < 32; ++i) {
729     tran_high_t temp_in[32], temp_out[32];
730     for (j = 0; j < 32; ++j)
731       temp_in[j] = output[j + i * 32];
732     vpx_fdct32(temp_in, temp_out, 0);
733     for (j = 0; j < 32; ++j)
734       out[j + i * 32] =
735           (tran_low_t)((temp_out[j] + 1 + (temp_out[j] < 0)) >> 2);
736   }
737 }
738
739 // Note that although we use dct_32_round in dct32 computation flow,
740 // this 2d fdct32x32 for rate-distortion optimization loop is operating
741 // within 16 bits precision.
742 void vpx_fdct32x32_rd_c(const int16_t *input, tran_low_t *out, int stride) {
743   int i, j;
744   tran_high_t output[32 * 32];
745
746   // Columns
747   for (i = 0; i < 32; ++i) {
748     tran_high_t temp_in[32], temp_out[32];
749     for (j = 0; j < 32; ++j)
750       temp_in[j] = input[j * stride + i] * 4;
751     vpx_fdct32(temp_in, temp_out, 0);
752     for (j = 0; j < 32; ++j)
753       // TODO(cd): see quality impact of only doing
754       //           output[j * 32 + i] = (temp_out[j] + 1) >> 2;
755       //           PS: also change code in vpx_dsp/x86/vpx_dct_sse2.c
756       output[j * 32 + i] = (temp_out[j] + 1 + (temp_out[j] > 0)) >> 2;
757   }
758
759   // Rows
760   for (i = 0; i < 32; ++i) {
761     tran_high_t temp_in[32], temp_out[32];
762     for (j = 0; j < 32; ++j)
763       temp_in[j] = output[j + i * 32];
764     vpx_fdct32(temp_in, temp_out, 1);
765     for (j = 0; j < 32; ++j)
766       out[j + i * 32] = (tran_low_t)temp_out[j];
767   }
768 }
769
770 void vpx_fdct32x32_1_c(const int16_t *input, tran_low_t *output, int stride) {
771   int r, c;
772   int sum = 0;
773   for (r = 0; r < 32; ++r)
774     for (c = 0; c < 32; ++c)
775       sum += input[r * stride + c];
776
777   output[0] = (tran_low_t)(sum >> 3);
778 }
779
780 #if CONFIG_VP9_HIGHBITDEPTH
781 void vpx_highbd_fdct4x4_c(const int16_t *input, tran_low_t *output,
782                           int stride) {
783   vpx_fdct4x4_c(input, output, stride);
784 }
785
786 void vpx_highbd_fdct8x8_c(const int16_t *input, tran_low_t *final_output,
787                           int stride) {
788   vpx_fdct8x8_c(input, final_output, stride);
789 }
790
791 void vpx_highbd_fdct8x8_1_c(const int16_t *input, tran_low_t *final_output,
792                             int stride) {
793   vpx_fdct8x8_1_c(input, final_output, stride);
794 }
795
796 void vpx_highbd_fdct16x16_c(const int16_t *input, tran_low_t *output,
797                             int stride) {
798   vpx_fdct16x16_c(input, output, stride);
799 }
800
801 void vpx_highbd_fdct16x16_1_c(const int16_t *input, tran_low_t *output,
802                               int stride) {
803   vpx_fdct16x16_1_c(input, output, stride);
804 }
805
806 void vpx_highbd_fdct32x32_c(const int16_t *input, tran_low_t *out, int stride) {
807   vpx_fdct32x32_c(input, out, stride);
808 }
809
810 void vpx_highbd_fdct32x32_rd_c(const int16_t *input, tran_low_t *out,
811                                int stride) {
812   vpx_fdct32x32_rd_c(input, out, stride);
813 }
814
815 void vpx_highbd_fdct32x32_1_c(const int16_t *input, tran_low_t *out,
816                               int stride) {
817   vpx_fdct32x32_1_c(input, out, stride);
818 }
819 #endif  // CONFIG_VP9_HIGHBITDEPTH