xref: /aosp_15_r20/external/libvpx/vp9/encoder/vp9_dct.c (revision fb1b10ab9aebc7c7068eedab379b749d7e3900be)
1*fb1b10abSAndroid Build Coastguard Worker /*
2*fb1b10abSAndroid Build Coastguard Worker  *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3*fb1b10abSAndroid Build Coastguard Worker  *
4*fb1b10abSAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*fb1b10abSAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*fb1b10abSAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*fb1b10abSAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*fb1b10abSAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*fb1b10abSAndroid Build Coastguard Worker  */
10*fb1b10abSAndroid Build Coastguard Worker 
11*fb1b10abSAndroid Build Coastguard Worker #include <assert.h>
12*fb1b10abSAndroid Build Coastguard Worker #include <math.h>
13*fb1b10abSAndroid Build Coastguard Worker 
14*fb1b10abSAndroid Build Coastguard Worker #include "./vp9_rtcd.h"
15*fb1b10abSAndroid Build Coastguard Worker #include "./vpx_config.h"
16*fb1b10abSAndroid Build Coastguard Worker #include "./vpx_dsp_rtcd.h"
17*fb1b10abSAndroid Build Coastguard Worker 
18*fb1b10abSAndroid Build Coastguard Worker #include "vp9/common/vp9_blockd.h"
19*fb1b10abSAndroid Build Coastguard Worker #include "vp9/common/vp9_idct.h"
20*fb1b10abSAndroid Build Coastguard Worker #include "vpx_dsp/fwd_txfm.h"
21*fb1b10abSAndroid Build Coastguard Worker #include "vpx_ports/mem.h"
22*fb1b10abSAndroid Build Coastguard Worker 
fdct4(const tran_low_t * input,tran_low_t * output)23*fb1b10abSAndroid Build Coastguard Worker static void fdct4(const tran_low_t *input, tran_low_t *output) {
24*fb1b10abSAndroid Build Coastguard Worker   tran_high_t step[4];
25*fb1b10abSAndroid Build Coastguard Worker   tran_high_t temp1, temp2;
26*fb1b10abSAndroid Build Coastguard Worker 
27*fb1b10abSAndroid Build Coastguard Worker   step[0] = input[0] + input[3];
28*fb1b10abSAndroid Build Coastguard Worker   step[1] = input[1] + input[2];
29*fb1b10abSAndroid Build Coastguard Worker   step[2] = input[1] - input[2];
30*fb1b10abSAndroid Build Coastguard Worker   step[3] = input[0] - input[3];
31*fb1b10abSAndroid Build Coastguard Worker 
32*fb1b10abSAndroid Build Coastguard Worker   temp1 = (step[0] + step[1]) * cospi_16_64;
33*fb1b10abSAndroid Build Coastguard Worker   temp2 = (step[0] - step[1]) * cospi_16_64;
34*fb1b10abSAndroid Build Coastguard Worker   output[0] = (tran_low_t)fdct_round_shift(temp1);
35*fb1b10abSAndroid Build Coastguard Worker   output[2] = (tran_low_t)fdct_round_shift(temp2);
36*fb1b10abSAndroid Build Coastguard Worker   temp1 = step[2] * cospi_24_64 + step[3] * cospi_8_64;
37*fb1b10abSAndroid Build Coastguard Worker   temp2 = -step[2] * cospi_8_64 + step[3] * cospi_24_64;
38*fb1b10abSAndroid Build Coastguard Worker   output[1] = (tran_low_t)fdct_round_shift(temp1);
39*fb1b10abSAndroid Build Coastguard Worker   output[3] = (tran_low_t)fdct_round_shift(temp2);
40*fb1b10abSAndroid Build Coastguard Worker }
41*fb1b10abSAndroid Build Coastguard Worker 
fdct8(const tran_low_t * input,tran_low_t * output)42*fb1b10abSAndroid Build Coastguard Worker static void fdct8(const tran_low_t *input, tran_low_t *output) {
43*fb1b10abSAndroid Build Coastguard Worker   tran_high_t s0, s1, s2, s3, s4, s5, s6, s7;  // canbe16
44*fb1b10abSAndroid Build Coastguard Worker   tran_high_t t0, t1, t2, t3;                  // needs32
45*fb1b10abSAndroid Build Coastguard Worker   tran_high_t x0, x1, x2, x3;                  // canbe16
46*fb1b10abSAndroid Build Coastguard Worker 
47*fb1b10abSAndroid Build Coastguard Worker   // stage 1
48*fb1b10abSAndroid Build Coastguard Worker   s0 = input[0] + input[7];
49*fb1b10abSAndroid Build Coastguard Worker   s1 = input[1] + input[6];
50*fb1b10abSAndroid Build Coastguard Worker   s2 = input[2] + input[5];
51*fb1b10abSAndroid Build Coastguard Worker   s3 = input[3] + input[4];
52*fb1b10abSAndroid Build Coastguard Worker   s4 = input[3] - input[4];
53*fb1b10abSAndroid Build Coastguard Worker   s5 = input[2] - input[5];
54*fb1b10abSAndroid Build Coastguard Worker   s6 = input[1] - input[6];
55*fb1b10abSAndroid Build Coastguard Worker   s7 = input[0] - input[7];
56*fb1b10abSAndroid Build Coastguard Worker 
57*fb1b10abSAndroid Build Coastguard Worker   // fdct4(step, step);
58*fb1b10abSAndroid Build Coastguard Worker   x0 = s0 + s3;
59*fb1b10abSAndroid Build Coastguard Worker   x1 = s1 + s2;
60*fb1b10abSAndroid Build Coastguard Worker   x2 = s1 - s2;
61*fb1b10abSAndroid Build Coastguard Worker   x3 = s0 - s3;
62*fb1b10abSAndroid Build Coastguard Worker   t0 = (x0 + x1) * cospi_16_64;
63*fb1b10abSAndroid Build Coastguard Worker   t1 = (x0 - x1) * cospi_16_64;
64*fb1b10abSAndroid Build Coastguard Worker   t2 = x2 * cospi_24_64 + x3 * cospi_8_64;
65*fb1b10abSAndroid Build Coastguard Worker   t3 = -x2 * cospi_8_64 + x3 * cospi_24_64;
66*fb1b10abSAndroid Build Coastguard Worker   output[0] = (tran_low_t)fdct_round_shift(t0);
67*fb1b10abSAndroid Build Coastguard Worker   output[2] = (tran_low_t)fdct_round_shift(t2);
68*fb1b10abSAndroid Build Coastguard Worker   output[4] = (tran_low_t)fdct_round_shift(t1);
69*fb1b10abSAndroid Build Coastguard Worker   output[6] = (tran_low_t)fdct_round_shift(t3);
70*fb1b10abSAndroid Build Coastguard Worker 
71*fb1b10abSAndroid Build Coastguard Worker   // Stage 2
72*fb1b10abSAndroid Build Coastguard Worker   t0 = (s6 - s5) * cospi_16_64;
73*fb1b10abSAndroid Build Coastguard Worker   t1 = (s6 + s5) * cospi_16_64;
74*fb1b10abSAndroid Build Coastguard Worker   t2 = (tran_low_t)fdct_round_shift(t0);
75*fb1b10abSAndroid Build Coastguard Worker   t3 = (tran_low_t)fdct_round_shift(t1);
76*fb1b10abSAndroid Build Coastguard Worker 
77*fb1b10abSAndroid Build Coastguard Worker   // Stage 3
78*fb1b10abSAndroid Build Coastguard Worker   x0 = s4 + t2;
79*fb1b10abSAndroid Build Coastguard Worker   x1 = s4 - t2;
80*fb1b10abSAndroid Build Coastguard Worker   x2 = s7 - t3;
81*fb1b10abSAndroid Build Coastguard Worker   x3 = s7 + t3;
82*fb1b10abSAndroid Build Coastguard Worker 
83*fb1b10abSAndroid Build Coastguard Worker   // Stage 4
84*fb1b10abSAndroid Build Coastguard Worker   t0 = x0 * cospi_28_64 + x3 * cospi_4_64;
85*fb1b10abSAndroid Build Coastguard Worker   t1 = x1 * cospi_12_64 + x2 * cospi_20_64;
86*fb1b10abSAndroid Build Coastguard Worker   t2 = x2 * cospi_12_64 + x1 * -cospi_20_64;
87*fb1b10abSAndroid Build Coastguard Worker   t3 = x3 * cospi_28_64 + x0 * -cospi_4_64;
88*fb1b10abSAndroid Build Coastguard Worker   output[1] = (tran_low_t)fdct_round_shift(t0);
89*fb1b10abSAndroid Build Coastguard Worker   output[3] = (tran_low_t)fdct_round_shift(t2);
90*fb1b10abSAndroid Build Coastguard Worker   output[5] = (tran_low_t)fdct_round_shift(t1);
91*fb1b10abSAndroid Build Coastguard Worker   output[7] = (tran_low_t)fdct_round_shift(t3);
92*fb1b10abSAndroid Build Coastguard Worker }
93*fb1b10abSAndroid Build Coastguard Worker 
fdct16(const tran_low_t in[16],tran_low_t out[16])94*fb1b10abSAndroid Build Coastguard Worker static void fdct16(const tran_low_t in[16], tran_low_t out[16]) {
95*fb1b10abSAndroid Build Coastguard Worker   tran_high_t step1[8];      // canbe16
96*fb1b10abSAndroid Build Coastguard Worker   tran_high_t step2[8];      // canbe16
97*fb1b10abSAndroid Build Coastguard Worker   tran_high_t step3[8];      // canbe16
98*fb1b10abSAndroid Build Coastguard Worker   tran_high_t input[8];      // canbe16
99*fb1b10abSAndroid Build Coastguard Worker   tran_high_t temp1, temp2;  // needs32
100*fb1b10abSAndroid Build Coastguard Worker 
101*fb1b10abSAndroid Build Coastguard Worker   // step 1
102*fb1b10abSAndroid Build Coastguard Worker   input[0] = in[0] + in[15];
103*fb1b10abSAndroid Build Coastguard Worker   input[1] = in[1] + in[14];
104*fb1b10abSAndroid Build Coastguard Worker   input[2] = in[2] + in[13];
105*fb1b10abSAndroid Build Coastguard Worker   input[3] = in[3] + in[12];
106*fb1b10abSAndroid Build Coastguard Worker   input[4] = in[4] + in[11];
107*fb1b10abSAndroid Build Coastguard Worker   input[5] = in[5] + in[10];
108*fb1b10abSAndroid Build Coastguard Worker   input[6] = in[6] + in[9];
109*fb1b10abSAndroid Build Coastguard Worker   input[7] = in[7] + in[8];
110*fb1b10abSAndroid Build Coastguard Worker 
111*fb1b10abSAndroid Build Coastguard Worker   step1[0] = in[7] - in[8];
112*fb1b10abSAndroid Build Coastguard Worker   step1[1] = in[6] - in[9];
113*fb1b10abSAndroid Build Coastguard Worker   step1[2] = in[5] - in[10];
114*fb1b10abSAndroid Build Coastguard Worker   step1[3] = in[4] - in[11];
115*fb1b10abSAndroid Build Coastguard Worker   step1[4] = in[3] - in[12];
116*fb1b10abSAndroid Build Coastguard Worker   step1[5] = in[2] - in[13];
117*fb1b10abSAndroid Build Coastguard Worker   step1[6] = in[1] - in[14];
118*fb1b10abSAndroid Build Coastguard Worker   step1[7] = in[0] - in[15];
119*fb1b10abSAndroid Build Coastguard Worker 
120*fb1b10abSAndroid Build Coastguard Worker   // fdct8(step, step);
121*fb1b10abSAndroid Build Coastguard Worker   {
122*fb1b10abSAndroid Build Coastguard Worker     tran_high_t s0, s1, s2, s3, s4, s5, s6, s7;  // canbe16
123*fb1b10abSAndroid Build Coastguard Worker     tran_high_t t0, t1, t2, t3;                  // needs32
124*fb1b10abSAndroid Build Coastguard Worker     tran_high_t x0, x1, x2, x3;                  // canbe16
125*fb1b10abSAndroid Build Coastguard Worker 
126*fb1b10abSAndroid Build Coastguard Worker     // stage 1
127*fb1b10abSAndroid Build Coastguard Worker     s0 = input[0] + input[7];
128*fb1b10abSAndroid Build Coastguard Worker     s1 = input[1] + input[6];
129*fb1b10abSAndroid Build Coastguard Worker     s2 = input[2] + input[5];
130*fb1b10abSAndroid Build Coastguard Worker     s3 = input[3] + input[4];
131*fb1b10abSAndroid Build Coastguard Worker     s4 = input[3] - input[4];
132*fb1b10abSAndroid Build Coastguard Worker     s5 = input[2] - input[5];
133*fb1b10abSAndroid Build Coastguard Worker     s6 = input[1] - input[6];
134*fb1b10abSAndroid Build Coastguard Worker     s7 = input[0] - input[7];
135*fb1b10abSAndroid Build Coastguard Worker 
136*fb1b10abSAndroid Build Coastguard Worker     // fdct4(step, step);
137*fb1b10abSAndroid Build Coastguard Worker     x0 = s0 + s3;
138*fb1b10abSAndroid Build Coastguard Worker     x1 = s1 + s2;
139*fb1b10abSAndroid Build Coastguard Worker     x2 = s1 - s2;
140*fb1b10abSAndroid Build Coastguard Worker     x3 = s0 - s3;
141*fb1b10abSAndroid Build Coastguard Worker     t0 = (x0 + x1) * cospi_16_64;
142*fb1b10abSAndroid Build Coastguard Worker     t1 = (x0 - x1) * cospi_16_64;
143*fb1b10abSAndroid Build Coastguard Worker     t2 = x3 * cospi_8_64 + x2 * cospi_24_64;
144*fb1b10abSAndroid Build Coastguard Worker     t3 = x3 * cospi_24_64 - x2 * cospi_8_64;
145*fb1b10abSAndroid Build Coastguard Worker     out[0] = (tran_low_t)fdct_round_shift(t0);
146*fb1b10abSAndroid Build Coastguard Worker     out[4] = (tran_low_t)fdct_round_shift(t2);
147*fb1b10abSAndroid Build Coastguard Worker     out[8] = (tran_low_t)fdct_round_shift(t1);
148*fb1b10abSAndroid Build Coastguard Worker     out[12] = (tran_low_t)fdct_round_shift(t3);
149*fb1b10abSAndroid Build Coastguard Worker 
150*fb1b10abSAndroid Build Coastguard Worker     // Stage 2
151*fb1b10abSAndroid Build Coastguard Worker     t0 = (s6 - s5) * cospi_16_64;
152*fb1b10abSAndroid Build Coastguard Worker     t1 = (s6 + s5) * cospi_16_64;
153*fb1b10abSAndroid Build Coastguard Worker     t2 = fdct_round_shift(t0);
154*fb1b10abSAndroid Build Coastguard Worker     t3 = fdct_round_shift(t1);
155*fb1b10abSAndroid Build Coastguard Worker 
156*fb1b10abSAndroid Build Coastguard Worker     // Stage 3
157*fb1b10abSAndroid Build Coastguard Worker     x0 = s4 + t2;
158*fb1b10abSAndroid Build Coastguard Worker     x1 = s4 - t2;
159*fb1b10abSAndroid Build Coastguard Worker     x2 = s7 - t3;
160*fb1b10abSAndroid Build Coastguard Worker     x3 = s7 + t3;
161*fb1b10abSAndroid Build Coastguard Worker 
162*fb1b10abSAndroid Build Coastguard Worker     // Stage 4
163*fb1b10abSAndroid Build Coastguard Worker     t0 = x0 * cospi_28_64 + x3 * cospi_4_64;
164*fb1b10abSAndroid Build Coastguard Worker     t1 = x1 * cospi_12_64 + x2 * cospi_20_64;
165*fb1b10abSAndroid Build Coastguard Worker     t2 = x2 * cospi_12_64 + x1 * -cospi_20_64;
166*fb1b10abSAndroid Build Coastguard Worker     t3 = x3 * cospi_28_64 + x0 * -cospi_4_64;
167*fb1b10abSAndroid Build Coastguard Worker     out[2] = (tran_low_t)fdct_round_shift(t0);
168*fb1b10abSAndroid Build Coastguard Worker     out[6] = (tran_low_t)fdct_round_shift(t2);
169*fb1b10abSAndroid Build Coastguard Worker     out[10] = (tran_low_t)fdct_round_shift(t1);
170*fb1b10abSAndroid Build Coastguard Worker     out[14] = (tran_low_t)fdct_round_shift(t3);
171*fb1b10abSAndroid Build Coastguard Worker   }
172*fb1b10abSAndroid Build Coastguard Worker 
173*fb1b10abSAndroid Build Coastguard Worker   // step 2
174*fb1b10abSAndroid Build Coastguard Worker   temp1 = (step1[5] - step1[2]) * cospi_16_64;
175*fb1b10abSAndroid Build Coastguard Worker   temp2 = (step1[4] - step1[3]) * cospi_16_64;
176*fb1b10abSAndroid Build Coastguard Worker   step2[2] = fdct_round_shift(temp1);
177*fb1b10abSAndroid Build Coastguard Worker   step2[3] = fdct_round_shift(temp2);
178*fb1b10abSAndroid Build Coastguard Worker   temp1 = (step1[4] + step1[3]) * cospi_16_64;
179*fb1b10abSAndroid Build Coastguard Worker   temp2 = (step1[5] + step1[2]) * cospi_16_64;
180*fb1b10abSAndroid Build Coastguard Worker   step2[4] = fdct_round_shift(temp1);
181*fb1b10abSAndroid Build Coastguard Worker   step2[5] = fdct_round_shift(temp2);
182*fb1b10abSAndroid Build Coastguard Worker 
183*fb1b10abSAndroid Build Coastguard Worker   // step 3
184*fb1b10abSAndroid Build Coastguard Worker   step3[0] = step1[0] + step2[3];
185*fb1b10abSAndroid Build Coastguard Worker   step3[1] = step1[1] + step2[2];
186*fb1b10abSAndroid Build Coastguard Worker   step3[2] = step1[1] - step2[2];
187*fb1b10abSAndroid Build Coastguard Worker   step3[3] = step1[0] - step2[3];
188*fb1b10abSAndroid Build Coastguard Worker   step3[4] = step1[7] - step2[4];
189*fb1b10abSAndroid Build Coastguard Worker   step3[5] = step1[6] - step2[5];
190*fb1b10abSAndroid Build Coastguard Worker   step3[6] = step1[6] + step2[5];
191*fb1b10abSAndroid Build Coastguard Worker   step3[7] = step1[7] + step2[4];
192*fb1b10abSAndroid Build Coastguard Worker 
193*fb1b10abSAndroid Build Coastguard Worker   // step 4
194*fb1b10abSAndroid Build Coastguard Worker   temp1 = step3[1] * -cospi_8_64 + step3[6] * cospi_24_64;
195*fb1b10abSAndroid Build Coastguard Worker   temp2 = step3[2] * cospi_24_64 + step3[5] * cospi_8_64;
196*fb1b10abSAndroid Build Coastguard Worker   step2[1] = fdct_round_shift(temp1);
197*fb1b10abSAndroid Build Coastguard Worker   step2[2] = fdct_round_shift(temp2);
198*fb1b10abSAndroid Build Coastguard Worker   temp1 = step3[2] * cospi_8_64 - step3[5] * cospi_24_64;
199*fb1b10abSAndroid Build Coastguard Worker   temp2 = step3[1] * cospi_24_64 + step3[6] * cospi_8_64;
200*fb1b10abSAndroid Build Coastguard Worker   step2[5] = fdct_round_shift(temp1);
201*fb1b10abSAndroid Build Coastguard Worker   step2[6] = fdct_round_shift(temp2);
202*fb1b10abSAndroid Build Coastguard Worker 
203*fb1b10abSAndroid Build Coastguard Worker   // step 5
204*fb1b10abSAndroid Build Coastguard Worker   step1[0] = step3[0] + step2[1];
205*fb1b10abSAndroid Build Coastguard Worker   step1[1] = step3[0] - step2[1];
206*fb1b10abSAndroid Build Coastguard Worker   step1[2] = step3[3] + step2[2];
207*fb1b10abSAndroid Build Coastguard Worker   step1[3] = step3[3] - step2[2];
208*fb1b10abSAndroid Build Coastguard Worker   step1[4] = step3[4] - step2[5];
209*fb1b10abSAndroid Build Coastguard Worker   step1[5] = step3[4] + step2[5];
210*fb1b10abSAndroid Build Coastguard Worker   step1[6] = step3[7] - step2[6];
211*fb1b10abSAndroid Build Coastguard Worker   step1[7] = step3[7] + step2[6];
212*fb1b10abSAndroid Build Coastguard Worker 
213*fb1b10abSAndroid Build Coastguard Worker   // step 6
214*fb1b10abSAndroid Build Coastguard Worker   temp1 = step1[0] * cospi_30_64 + step1[7] * cospi_2_64;
215*fb1b10abSAndroid Build Coastguard Worker   temp2 = step1[1] * cospi_14_64 + step1[6] * cospi_18_64;
216*fb1b10abSAndroid Build Coastguard Worker   out[1] = (tran_low_t)fdct_round_shift(temp1);
217*fb1b10abSAndroid Build Coastguard Worker   out[9] = (tran_low_t)fdct_round_shift(temp2);
218*fb1b10abSAndroid Build Coastguard Worker 
219*fb1b10abSAndroid Build Coastguard Worker   temp1 = step1[2] * cospi_22_64 + step1[5] * cospi_10_64;
220*fb1b10abSAndroid Build Coastguard Worker   temp2 = step1[3] * cospi_6_64 + step1[4] * cospi_26_64;
221*fb1b10abSAndroid Build Coastguard Worker   out[5] = (tran_low_t)fdct_round_shift(temp1);
222*fb1b10abSAndroid Build Coastguard Worker   out[13] = (tran_low_t)fdct_round_shift(temp2);
223*fb1b10abSAndroid Build Coastguard Worker 
224*fb1b10abSAndroid Build Coastguard Worker   temp1 = step1[3] * -cospi_26_64 + step1[4] * cospi_6_64;
225*fb1b10abSAndroid Build Coastguard Worker   temp2 = step1[2] * -cospi_10_64 + step1[5] * cospi_22_64;
226*fb1b10abSAndroid Build Coastguard Worker   out[3] = (tran_low_t)fdct_round_shift(temp1);
227*fb1b10abSAndroid Build Coastguard Worker   out[11] = (tran_low_t)fdct_round_shift(temp2);
228*fb1b10abSAndroid Build Coastguard Worker 
229*fb1b10abSAndroid Build Coastguard Worker   temp1 = step1[1] * -cospi_18_64 + step1[6] * cospi_14_64;
230*fb1b10abSAndroid Build Coastguard Worker   temp2 = step1[0] * -cospi_2_64 + step1[7] * cospi_30_64;
231*fb1b10abSAndroid Build Coastguard Worker   out[7] = (tran_low_t)fdct_round_shift(temp1);
232*fb1b10abSAndroid Build Coastguard Worker   out[15] = (tran_low_t)fdct_round_shift(temp2);
233*fb1b10abSAndroid Build Coastguard Worker }
234*fb1b10abSAndroid Build Coastguard Worker 
fadst4(const tran_low_t * input,tran_low_t * output)235*fb1b10abSAndroid Build Coastguard Worker static void fadst4(const tran_low_t *input, tran_low_t *output) {
236*fb1b10abSAndroid Build Coastguard Worker   tran_high_t x0, x1, x2, x3;
237*fb1b10abSAndroid Build Coastguard Worker   tran_high_t s0, s1, s2, s3, s4, s5, s6, s7;
238*fb1b10abSAndroid Build Coastguard Worker 
239*fb1b10abSAndroid Build Coastguard Worker   x0 = input[0];
240*fb1b10abSAndroid Build Coastguard Worker   x1 = input[1];
241*fb1b10abSAndroid Build Coastguard Worker   x2 = input[2];
242*fb1b10abSAndroid Build Coastguard Worker   x3 = input[3];
243*fb1b10abSAndroid Build Coastguard Worker 
244*fb1b10abSAndroid Build Coastguard Worker   if (!(x0 | x1 | x2 | x3)) {
245*fb1b10abSAndroid Build Coastguard Worker     output[0] = output[1] = output[2] = output[3] = 0;
246*fb1b10abSAndroid Build Coastguard Worker     return;
247*fb1b10abSAndroid Build Coastguard Worker   }
248*fb1b10abSAndroid Build Coastguard Worker 
249*fb1b10abSAndroid Build Coastguard Worker   s0 = sinpi_1_9 * x0;
250*fb1b10abSAndroid Build Coastguard Worker   s1 = sinpi_4_9 * x0;
251*fb1b10abSAndroid Build Coastguard Worker   s2 = sinpi_2_9 * x1;
252*fb1b10abSAndroid Build Coastguard Worker   s3 = sinpi_1_9 * x1;
253*fb1b10abSAndroid Build Coastguard Worker   s4 = sinpi_3_9 * x2;
254*fb1b10abSAndroid Build Coastguard Worker   s5 = sinpi_4_9 * x3;
255*fb1b10abSAndroid Build Coastguard Worker   s6 = sinpi_2_9 * x3;
256*fb1b10abSAndroid Build Coastguard Worker   s7 = x0 + x1 - x3;
257*fb1b10abSAndroid Build Coastguard Worker 
258*fb1b10abSAndroid Build Coastguard Worker   x0 = s0 + s2 + s5;
259*fb1b10abSAndroid Build Coastguard Worker   x1 = sinpi_3_9 * s7;
260*fb1b10abSAndroid Build Coastguard Worker   x2 = s1 - s3 + s6;
261*fb1b10abSAndroid Build Coastguard Worker   x3 = s4;
262*fb1b10abSAndroid Build Coastguard Worker 
263*fb1b10abSAndroid Build Coastguard Worker   s0 = x0 + x3;
264*fb1b10abSAndroid Build Coastguard Worker   s1 = x1;
265*fb1b10abSAndroid Build Coastguard Worker   s2 = x2 - x3;
266*fb1b10abSAndroid Build Coastguard Worker   s3 = x2 - x0 + x3;
267*fb1b10abSAndroid Build Coastguard Worker 
268*fb1b10abSAndroid Build Coastguard Worker   // 1-D transform scaling factor is sqrt(2).
269*fb1b10abSAndroid Build Coastguard Worker   output[0] = (tran_low_t)fdct_round_shift(s0);
270*fb1b10abSAndroid Build Coastguard Worker   output[1] = (tran_low_t)fdct_round_shift(s1);
271*fb1b10abSAndroid Build Coastguard Worker   output[2] = (tran_low_t)fdct_round_shift(s2);
272*fb1b10abSAndroid Build Coastguard Worker   output[3] = (tran_low_t)fdct_round_shift(s3);
273*fb1b10abSAndroid Build Coastguard Worker }
274*fb1b10abSAndroid Build Coastguard Worker 
fadst8(const tran_low_t * input,tran_low_t * output)275*fb1b10abSAndroid Build Coastguard Worker static void fadst8(const tran_low_t *input, tran_low_t *output) {
276*fb1b10abSAndroid Build Coastguard Worker   tran_high_t s0, s1, s2, s3, s4, s5, s6, s7;
277*fb1b10abSAndroid Build Coastguard Worker 
278*fb1b10abSAndroid Build Coastguard Worker   tran_high_t x0 = input[7];
279*fb1b10abSAndroid Build Coastguard Worker   tran_high_t x1 = input[0];
280*fb1b10abSAndroid Build Coastguard Worker   tran_high_t x2 = input[5];
281*fb1b10abSAndroid Build Coastguard Worker   tran_high_t x3 = input[2];
282*fb1b10abSAndroid Build Coastguard Worker   tran_high_t x4 = input[3];
283*fb1b10abSAndroid Build Coastguard Worker   tran_high_t x5 = input[4];
284*fb1b10abSAndroid Build Coastguard Worker   tran_high_t x6 = input[1];
285*fb1b10abSAndroid Build Coastguard Worker   tran_high_t x7 = input[6];
286*fb1b10abSAndroid Build Coastguard Worker 
287*fb1b10abSAndroid Build Coastguard Worker   // stage 1
288*fb1b10abSAndroid Build Coastguard Worker   s0 = cospi_2_64 * x0 + cospi_30_64 * x1;
289*fb1b10abSAndroid Build Coastguard Worker   s1 = cospi_30_64 * x0 - cospi_2_64 * x1;
290*fb1b10abSAndroid Build Coastguard Worker   s2 = cospi_10_64 * x2 + cospi_22_64 * x3;
291*fb1b10abSAndroid Build Coastguard Worker   s3 = cospi_22_64 * x2 - cospi_10_64 * x3;
292*fb1b10abSAndroid Build Coastguard Worker   s4 = cospi_18_64 * x4 + cospi_14_64 * x5;
293*fb1b10abSAndroid Build Coastguard Worker   s5 = cospi_14_64 * x4 - cospi_18_64 * x5;
294*fb1b10abSAndroid Build Coastguard Worker   s6 = cospi_26_64 * x6 + cospi_6_64 * x7;
295*fb1b10abSAndroid Build Coastguard Worker   s7 = cospi_6_64 * x6 - cospi_26_64 * x7;
296*fb1b10abSAndroid Build Coastguard Worker 
297*fb1b10abSAndroid Build Coastguard Worker   x0 = fdct_round_shift(s0 + s4);
298*fb1b10abSAndroid Build Coastguard Worker   x1 = fdct_round_shift(s1 + s5);
299*fb1b10abSAndroid Build Coastguard Worker   x2 = fdct_round_shift(s2 + s6);
300*fb1b10abSAndroid Build Coastguard Worker   x3 = fdct_round_shift(s3 + s7);
301*fb1b10abSAndroid Build Coastguard Worker   x4 = fdct_round_shift(s0 - s4);
302*fb1b10abSAndroid Build Coastguard Worker   x5 = fdct_round_shift(s1 - s5);
303*fb1b10abSAndroid Build Coastguard Worker   x6 = fdct_round_shift(s2 - s6);
304*fb1b10abSAndroid Build Coastguard Worker   x7 = fdct_round_shift(s3 - s7);
305*fb1b10abSAndroid Build Coastguard Worker 
306*fb1b10abSAndroid Build Coastguard Worker   // stage 2
307*fb1b10abSAndroid Build Coastguard Worker   s0 = x0;
308*fb1b10abSAndroid Build Coastguard Worker   s1 = x1;
309*fb1b10abSAndroid Build Coastguard Worker   s2 = x2;
310*fb1b10abSAndroid Build Coastguard Worker   s3 = x3;
311*fb1b10abSAndroid Build Coastguard Worker   s4 = cospi_8_64 * x4 + cospi_24_64 * x5;
312*fb1b10abSAndroid Build Coastguard Worker   s5 = cospi_24_64 * x4 - cospi_8_64 * x5;
313*fb1b10abSAndroid Build Coastguard Worker   s6 = -cospi_24_64 * x6 + cospi_8_64 * x7;
314*fb1b10abSAndroid Build Coastguard Worker   s7 = cospi_8_64 * x6 + cospi_24_64 * x7;
315*fb1b10abSAndroid Build Coastguard Worker 
316*fb1b10abSAndroid Build Coastguard Worker   x0 = s0 + s2;
317*fb1b10abSAndroid Build Coastguard Worker   x1 = s1 + s3;
318*fb1b10abSAndroid Build Coastguard Worker   x2 = s0 - s2;
319*fb1b10abSAndroid Build Coastguard Worker   x3 = s1 - s3;
320*fb1b10abSAndroid Build Coastguard Worker   x4 = fdct_round_shift(s4 + s6);
321*fb1b10abSAndroid Build Coastguard Worker   x5 = fdct_round_shift(s5 + s7);
322*fb1b10abSAndroid Build Coastguard Worker   x6 = fdct_round_shift(s4 - s6);
323*fb1b10abSAndroid Build Coastguard Worker   x7 = fdct_round_shift(s5 - s7);
324*fb1b10abSAndroid Build Coastguard Worker 
325*fb1b10abSAndroid Build Coastguard Worker   // stage 3
326*fb1b10abSAndroid Build Coastguard Worker   s2 = cospi_16_64 * (x2 + x3);
327*fb1b10abSAndroid Build Coastguard Worker   s3 = cospi_16_64 * (x2 - x3);
328*fb1b10abSAndroid Build Coastguard Worker   s6 = cospi_16_64 * (x6 + x7);
329*fb1b10abSAndroid Build Coastguard Worker   s7 = cospi_16_64 * (x6 - x7);
330*fb1b10abSAndroid Build Coastguard Worker 
331*fb1b10abSAndroid Build Coastguard Worker   x2 = fdct_round_shift(s2);
332*fb1b10abSAndroid Build Coastguard Worker   x3 = fdct_round_shift(s3);
333*fb1b10abSAndroid Build Coastguard Worker   x6 = fdct_round_shift(s6);
334*fb1b10abSAndroid Build Coastguard Worker   x7 = fdct_round_shift(s7);
335*fb1b10abSAndroid Build Coastguard Worker 
336*fb1b10abSAndroid Build Coastguard Worker   output[0] = (tran_low_t)x0;
337*fb1b10abSAndroid Build Coastguard Worker   output[1] = (tran_low_t)-x4;
338*fb1b10abSAndroid Build Coastguard Worker   output[2] = (tran_low_t)x6;
339*fb1b10abSAndroid Build Coastguard Worker   output[3] = (tran_low_t)-x2;
340*fb1b10abSAndroid Build Coastguard Worker   output[4] = (tran_low_t)x3;
341*fb1b10abSAndroid Build Coastguard Worker   output[5] = (tran_low_t)-x7;
342*fb1b10abSAndroid Build Coastguard Worker   output[6] = (tran_low_t)x5;
343*fb1b10abSAndroid Build Coastguard Worker   output[7] = (tran_low_t)-x1;
344*fb1b10abSAndroid Build Coastguard Worker }
345*fb1b10abSAndroid Build Coastguard Worker 
fadst16(const tran_low_t * input,tran_low_t * output)346*fb1b10abSAndroid Build Coastguard Worker static void fadst16(const tran_low_t *input, tran_low_t *output) {
347*fb1b10abSAndroid Build Coastguard Worker   tran_high_t s0, s1, s2, s3, s4, s5, s6, s7, s8;
348*fb1b10abSAndroid Build Coastguard Worker   tran_high_t s9, s10, s11, s12, s13, s14, s15;
349*fb1b10abSAndroid Build Coastguard Worker 
350*fb1b10abSAndroid Build Coastguard Worker   tran_high_t x0 = input[15];
351*fb1b10abSAndroid Build Coastguard Worker   tran_high_t x1 = input[0];
352*fb1b10abSAndroid Build Coastguard Worker   tran_high_t x2 = input[13];
353*fb1b10abSAndroid Build Coastguard Worker   tran_high_t x3 = input[2];
354*fb1b10abSAndroid Build Coastguard Worker   tran_high_t x4 = input[11];
355*fb1b10abSAndroid Build Coastguard Worker   tran_high_t x5 = input[4];
356*fb1b10abSAndroid Build Coastguard Worker   tran_high_t x6 = input[9];
357*fb1b10abSAndroid Build Coastguard Worker   tran_high_t x7 = input[6];
358*fb1b10abSAndroid Build Coastguard Worker   tran_high_t x8 = input[7];
359*fb1b10abSAndroid Build Coastguard Worker   tran_high_t x9 = input[8];
360*fb1b10abSAndroid Build Coastguard Worker   tran_high_t x10 = input[5];
361*fb1b10abSAndroid Build Coastguard Worker   tran_high_t x11 = input[10];
362*fb1b10abSAndroid Build Coastguard Worker   tran_high_t x12 = input[3];
363*fb1b10abSAndroid Build Coastguard Worker   tran_high_t x13 = input[12];
364*fb1b10abSAndroid Build Coastguard Worker   tran_high_t x14 = input[1];
365*fb1b10abSAndroid Build Coastguard Worker   tran_high_t x15 = input[14];
366*fb1b10abSAndroid Build Coastguard Worker 
367*fb1b10abSAndroid Build Coastguard Worker   // stage 1
368*fb1b10abSAndroid Build Coastguard Worker   s0 = x0 * cospi_1_64 + x1 * cospi_31_64;
369*fb1b10abSAndroid Build Coastguard Worker   s1 = x0 * cospi_31_64 - x1 * cospi_1_64;
370*fb1b10abSAndroid Build Coastguard Worker   s2 = x2 * cospi_5_64 + x3 * cospi_27_64;
371*fb1b10abSAndroid Build Coastguard Worker   s3 = x2 * cospi_27_64 - x3 * cospi_5_64;
372*fb1b10abSAndroid Build Coastguard Worker   s4 = x4 * cospi_9_64 + x5 * cospi_23_64;
373*fb1b10abSAndroid Build Coastguard Worker   s5 = x4 * cospi_23_64 - x5 * cospi_9_64;
374*fb1b10abSAndroid Build Coastguard Worker   s6 = x6 * cospi_13_64 + x7 * cospi_19_64;
375*fb1b10abSAndroid Build Coastguard Worker   s7 = x6 * cospi_19_64 - x7 * cospi_13_64;
376*fb1b10abSAndroid Build Coastguard Worker   s8 = x8 * cospi_17_64 + x9 * cospi_15_64;
377*fb1b10abSAndroid Build Coastguard Worker   s9 = x8 * cospi_15_64 - x9 * cospi_17_64;
378*fb1b10abSAndroid Build Coastguard Worker   s10 = x10 * cospi_21_64 + x11 * cospi_11_64;
379*fb1b10abSAndroid Build Coastguard Worker   s11 = x10 * cospi_11_64 - x11 * cospi_21_64;
380*fb1b10abSAndroid Build Coastguard Worker   s12 = x12 * cospi_25_64 + x13 * cospi_7_64;
381*fb1b10abSAndroid Build Coastguard Worker   s13 = x12 * cospi_7_64 - x13 * cospi_25_64;
382*fb1b10abSAndroid Build Coastguard Worker   s14 = x14 * cospi_29_64 + x15 * cospi_3_64;
383*fb1b10abSAndroid Build Coastguard Worker   s15 = x14 * cospi_3_64 - x15 * cospi_29_64;
384*fb1b10abSAndroid Build Coastguard Worker 
385*fb1b10abSAndroid Build Coastguard Worker   x0 = fdct_round_shift(s0 + s8);
386*fb1b10abSAndroid Build Coastguard Worker   x1 = fdct_round_shift(s1 + s9);
387*fb1b10abSAndroid Build Coastguard Worker   x2 = fdct_round_shift(s2 + s10);
388*fb1b10abSAndroid Build Coastguard Worker   x3 = fdct_round_shift(s3 + s11);
389*fb1b10abSAndroid Build Coastguard Worker   x4 = fdct_round_shift(s4 + s12);
390*fb1b10abSAndroid Build Coastguard Worker   x5 = fdct_round_shift(s5 + s13);
391*fb1b10abSAndroid Build Coastguard Worker   x6 = fdct_round_shift(s6 + s14);
392*fb1b10abSAndroid Build Coastguard Worker   x7 = fdct_round_shift(s7 + s15);
393*fb1b10abSAndroid Build Coastguard Worker   x8 = fdct_round_shift(s0 - s8);
394*fb1b10abSAndroid Build Coastguard Worker   x9 = fdct_round_shift(s1 - s9);
395*fb1b10abSAndroid Build Coastguard Worker   x10 = fdct_round_shift(s2 - s10);
396*fb1b10abSAndroid Build Coastguard Worker   x11 = fdct_round_shift(s3 - s11);
397*fb1b10abSAndroid Build Coastguard Worker   x12 = fdct_round_shift(s4 - s12);
398*fb1b10abSAndroid Build Coastguard Worker   x13 = fdct_round_shift(s5 - s13);
399*fb1b10abSAndroid Build Coastguard Worker   x14 = fdct_round_shift(s6 - s14);
400*fb1b10abSAndroid Build Coastguard Worker   x15 = fdct_round_shift(s7 - s15);
401*fb1b10abSAndroid Build Coastguard Worker 
402*fb1b10abSAndroid Build Coastguard Worker   // stage 2
403*fb1b10abSAndroid Build Coastguard Worker   s0 = x0;
404*fb1b10abSAndroid Build Coastguard Worker   s1 = x1;
405*fb1b10abSAndroid Build Coastguard Worker   s2 = x2;
406*fb1b10abSAndroid Build Coastguard Worker   s3 = x3;
407*fb1b10abSAndroid Build Coastguard Worker   s4 = x4;
408*fb1b10abSAndroid Build Coastguard Worker   s5 = x5;
409*fb1b10abSAndroid Build Coastguard Worker   s6 = x6;
410*fb1b10abSAndroid Build Coastguard Worker   s7 = x7;
411*fb1b10abSAndroid Build Coastguard Worker   s8 = x8 * cospi_4_64 + x9 * cospi_28_64;
412*fb1b10abSAndroid Build Coastguard Worker   s9 = x8 * cospi_28_64 - x9 * cospi_4_64;
413*fb1b10abSAndroid Build Coastguard Worker   s10 = x10 * cospi_20_64 + x11 * cospi_12_64;
414*fb1b10abSAndroid Build Coastguard Worker   s11 = x10 * cospi_12_64 - x11 * cospi_20_64;
415*fb1b10abSAndroid Build Coastguard Worker   s12 = -x12 * cospi_28_64 + x13 * cospi_4_64;
416*fb1b10abSAndroid Build Coastguard Worker   s13 = x12 * cospi_4_64 + x13 * cospi_28_64;
417*fb1b10abSAndroid Build Coastguard Worker   s14 = -x14 * cospi_12_64 + x15 * cospi_20_64;
418*fb1b10abSAndroid Build Coastguard Worker   s15 = x14 * cospi_20_64 + x15 * cospi_12_64;
419*fb1b10abSAndroid Build Coastguard Worker 
420*fb1b10abSAndroid Build Coastguard Worker   x0 = s0 + s4;
421*fb1b10abSAndroid Build Coastguard Worker   x1 = s1 + s5;
422*fb1b10abSAndroid Build Coastguard Worker   x2 = s2 + s6;
423*fb1b10abSAndroid Build Coastguard Worker   x3 = s3 + s7;
424*fb1b10abSAndroid Build Coastguard Worker   x4 = s0 - s4;
425*fb1b10abSAndroid Build Coastguard Worker   x5 = s1 - s5;
426*fb1b10abSAndroid Build Coastguard Worker   x6 = s2 - s6;
427*fb1b10abSAndroid Build Coastguard Worker   x7 = s3 - s7;
428*fb1b10abSAndroid Build Coastguard Worker   x8 = fdct_round_shift(s8 + s12);
429*fb1b10abSAndroid Build Coastguard Worker   x9 = fdct_round_shift(s9 + s13);
430*fb1b10abSAndroid Build Coastguard Worker   x10 = fdct_round_shift(s10 + s14);
431*fb1b10abSAndroid Build Coastguard Worker   x11 = fdct_round_shift(s11 + s15);
432*fb1b10abSAndroid Build Coastguard Worker   x12 = fdct_round_shift(s8 - s12);
433*fb1b10abSAndroid Build Coastguard Worker   x13 = fdct_round_shift(s9 - s13);
434*fb1b10abSAndroid Build Coastguard Worker   x14 = fdct_round_shift(s10 - s14);
435*fb1b10abSAndroid Build Coastguard Worker   x15 = fdct_round_shift(s11 - s15);
436*fb1b10abSAndroid Build Coastguard Worker 
437*fb1b10abSAndroid Build Coastguard Worker   // stage 3
438*fb1b10abSAndroid Build Coastguard Worker   s0 = x0;
439*fb1b10abSAndroid Build Coastguard Worker   s1 = x1;
440*fb1b10abSAndroid Build Coastguard Worker   s2 = x2;
441*fb1b10abSAndroid Build Coastguard Worker   s3 = x3;
442*fb1b10abSAndroid Build Coastguard Worker   s4 = x4 * cospi_8_64 + x5 * cospi_24_64;
443*fb1b10abSAndroid Build Coastguard Worker   s5 = x4 * cospi_24_64 - x5 * cospi_8_64;
444*fb1b10abSAndroid Build Coastguard Worker   s6 = -x6 * cospi_24_64 + x7 * cospi_8_64;
445*fb1b10abSAndroid Build Coastguard Worker   s7 = x6 * cospi_8_64 + x7 * cospi_24_64;
446*fb1b10abSAndroid Build Coastguard Worker   s8 = x8;
447*fb1b10abSAndroid Build Coastguard Worker   s9 = x9;
448*fb1b10abSAndroid Build Coastguard Worker   s10 = x10;
449*fb1b10abSAndroid Build Coastguard Worker   s11 = x11;
450*fb1b10abSAndroid Build Coastguard Worker   s12 = x12 * cospi_8_64 + x13 * cospi_24_64;
451*fb1b10abSAndroid Build Coastguard Worker   s13 = x12 * cospi_24_64 - x13 * cospi_8_64;
452*fb1b10abSAndroid Build Coastguard Worker   s14 = -x14 * cospi_24_64 + x15 * cospi_8_64;
453*fb1b10abSAndroid Build Coastguard Worker   s15 = x14 * cospi_8_64 + x15 * cospi_24_64;
454*fb1b10abSAndroid Build Coastguard Worker 
455*fb1b10abSAndroid Build Coastguard Worker   x0 = s0 + s2;
456*fb1b10abSAndroid Build Coastguard Worker   x1 = s1 + s3;
457*fb1b10abSAndroid Build Coastguard Worker   x2 = s0 - s2;
458*fb1b10abSAndroid Build Coastguard Worker   x3 = s1 - s3;
459*fb1b10abSAndroid Build Coastguard Worker   x4 = fdct_round_shift(s4 + s6);
460*fb1b10abSAndroid Build Coastguard Worker   x5 = fdct_round_shift(s5 + s7);
461*fb1b10abSAndroid Build Coastguard Worker   x6 = fdct_round_shift(s4 - s6);
462*fb1b10abSAndroid Build Coastguard Worker   x7 = fdct_round_shift(s5 - s7);
463*fb1b10abSAndroid Build Coastguard Worker   x8 = s8 + s10;
464*fb1b10abSAndroid Build Coastguard Worker   x9 = s9 + s11;
465*fb1b10abSAndroid Build Coastguard Worker   x10 = s8 - s10;
466*fb1b10abSAndroid Build Coastguard Worker   x11 = s9 - s11;
467*fb1b10abSAndroid Build Coastguard Worker   x12 = fdct_round_shift(s12 + s14);
468*fb1b10abSAndroid Build Coastguard Worker   x13 = fdct_round_shift(s13 + s15);
469*fb1b10abSAndroid Build Coastguard Worker   x14 = fdct_round_shift(s12 - s14);
470*fb1b10abSAndroid Build Coastguard Worker   x15 = fdct_round_shift(s13 - s15);
471*fb1b10abSAndroid Build Coastguard Worker 
472*fb1b10abSAndroid Build Coastguard Worker   // stage 4
473*fb1b10abSAndroid Build Coastguard Worker   s2 = (-cospi_16_64) * (x2 + x3);
474*fb1b10abSAndroid Build Coastguard Worker   s3 = cospi_16_64 * (x2 - x3);
475*fb1b10abSAndroid Build Coastguard Worker   s6 = cospi_16_64 * (x6 + x7);
476*fb1b10abSAndroid Build Coastguard Worker   s7 = cospi_16_64 * (-x6 + x7);
477*fb1b10abSAndroid Build Coastguard Worker   s10 = cospi_16_64 * (x10 + x11);
478*fb1b10abSAndroid Build Coastguard Worker   s11 = cospi_16_64 * (-x10 + x11);
479*fb1b10abSAndroid Build Coastguard Worker   s14 = (-cospi_16_64) * (x14 + x15);
480*fb1b10abSAndroid Build Coastguard Worker   s15 = cospi_16_64 * (x14 - x15);
481*fb1b10abSAndroid Build Coastguard Worker 
482*fb1b10abSAndroid Build Coastguard Worker   x2 = fdct_round_shift(s2);
483*fb1b10abSAndroid Build Coastguard Worker   x3 = fdct_round_shift(s3);
484*fb1b10abSAndroid Build Coastguard Worker   x6 = fdct_round_shift(s6);
485*fb1b10abSAndroid Build Coastguard Worker   x7 = fdct_round_shift(s7);
486*fb1b10abSAndroid Build Coastguard Worker   x10 = fdct_round_shift(s10);
487*fb1b10abSAndroid Build Coastguard Worker   x11 = fdct_round_shift(s11);
488*fb1b10abSAndroid Build Coastguard Worker   x14 = fdct_round_shift(s14);
489*fb1b10abSAndroid Build Coastguard Worker   x15 = fdct_round_shift(s15);
490*fb1b10abSAndroid Build Coastguard Worker 
491*fb1b10abSAndroid Build Coastguard Worker   output[0] = (tran_low_t)x0;
492*fb1b10abSAndroid Build Coastguard Worker   output[1] = (tran_low_t)-x8;
493*fb1b10abSAndroid Build Coastguard Worker   output[2] = (tran_low_t)x12;
494*fb1b10abSAndroid Build Coastguard Worker   output[3] = (tran_low_t)-x4;
495*fb1b10abSAndroid Build Coastguard Worker   output[4] = (tran_low_t)x6;
496*fb1b10abSAndroid Build Coastguard Worker   output[5] = (tran_low_t)x14;
497*fb1b10abSAndroid Build Coastguard Worker   output[6] = (tran_low_t)x10;
498*fb1b10abSAndroid Build Coastguard Worker   output[7] = (tran_low_t)x2;
499*fb1b10abSAndroid Build Coastguard Worker   output[8] = (tran_low_t)x3;
500*fb1b10abSAndroid Build Coastguard Worker   output[9] = (tran_low_t)x11;
501*fb1b10abSAndroid Build Coastguard Worker   output[10] = (tran_low_t)x15;
502*fb1b10abSAndroid Build Coastguard Worker   output[11] = (tran_low_t)x7;
503*fb1b10abSAndroid Build Coastguard Worker   output[12] = (tran_low_t)x5;
504*fb1b10abSAndroid Build Coastguard Worker   output[13] = (tran_low_t)-x13;
505*fb1b10abSAndroid Build Coastguard Worker   output[14] = (tran_low_t)x9;
506*fb1b10abSAndroid Build Coastguard Worker   output[15] = (tran_low_t)-x1;
507*fb1b10abSAndroid Build Coastguard Worker }
508*fb1b10abSAndroid Build Coastguard Worker 
509*fb1b10abSAndroid Build Coastguard Worker static const transform_2d FHT_4[] = {
510*fb1b10abSAndroid Build Coastguard Worker   { fdct4, fdct4 },   // DCT_DCT  = 0
511*fb1b10abSAndroid Build Coastguard Worker   { fadst4, fdct4 },  // ADST_DCT = 1
512*fb1b10abSAndroid Build Coastguard Worker   { fdct4, fadst4 },  // DCT_ADST = 2
513*fb1b10abSAndroid Build Coastguard Worker   { fadst4, fadst4 }  // ADST_ADST = 3
514*fb1b10abSAndroid Build Coastguard Worker };
515*fb1b10abSAndroid Build Coastguard Worker 
516*fb1b10abSAndroid Build Coastguard Worker static const transform_2d FHT_8[] = {
517*fb1b10abSAndroid Build Coastguard Worker   { fdct8, fdct8 },   // DCT_DCT  = 0
518*fb1b10abSAndroid Build Coastguard Worker   { fadst8, fdct8 },  // ADST_DCT = 1
519*fb1b10abSAndroid Build Coastguard Worker   { fdct8, fadst8 },  // DCT_ADST = 2
520*fb1b10abSAndroid Build Coastguard Worker   { fadst8, fadst8 }  // ADST_ADST = 3
521*fb1b10abSAndroid Build Coastguard Worker };
522*fb1b10abSAndroid Build Coastguard Worker 
523*fb1b10abSAndroid Build Coastguard Worker static const transform_2d FHT_16[] = {
524*fb1b10abSAndroid Build Coastguard Worker   { fdct16, fdct16 },   // DCT_DCT  = 0
525*fb1b10abSAndroid Build Coastguard Worker   { fadst16, fdct16 },  // ADST_DCT = 1
526*fb1b10abSAndroid Build Coastguard Worker   { fdct16, fadst16 },  // DCT_ADST = 2
527*fb1b10abSAndroid Build Coastguard Worker   { fadst16, fadst16 }  // ADST_ADST = 3
528*fb1b10abSAndroid Build Coastguard Worker };
529*fb1b10abSAndroid Build Coastguard Worker 
vp9_fht4x4_c(const int16_t * input,tran_low_t * output,int stride,int tx_type)530*fb1b10abSAndroid Build Coastguard Worker void vp9_fht4x4_c(const int16_t *input, tran_low_t *output, int stride,
531*fb1b10abSAndroid Build Coastguard Worker                   int tx_type) {
532*fb1b10abSAndroid Build Coastguard Worker   if (tx_type == DCT_DCT) {
533*fb1b10abSAndroid Build Coastguard Worker     vpx_fdct4x4_c(input, output, stride);
534*fb1b10abSAndroid Build Coastguard Worker   } else {
535*fb1b10abSAndroid Build Coastguard Worker     tran_low_t out[4 * 4];
536*fb1b10abSAndroid Build Coastguard Worker     int i, j;
537*fb1b10abSAndroid Build Coastguard Worker     tran_low_t temp_in[4], temp_out[4];
538*fb1b10abSAndroid Build Coastguard Worker     const transform_2d ht = FHT_4[tx_type];
539*fb1b10abSAndroid Build Coastguard Worker 
540*fb1b10abSAndroid Build Coastguard Worker     // Columns
541*fb1b10abSAndroid Build Coastguard Worker     for (i = 0; i < 4; ++i) {
542*fb1b10abSAndroid Build Coastguard Worker       for (j = 0; j < 4; ++j) temp_in[j] = input[j * stride + i] * 16;
543*fb1b10abSAndroid Build Coastguard Worker       if (i == 0 && temp_in[0]) temp_in[0] += 1;
544*fb1b10abSAndroid Build Coastguard Worker       ht.cols(temp_in, temp_out);
545*fb1b10abSAndroid Build Coastguard Worker       for (j = 0; j < 4; ++j) out[j * 4 + i] = temp_out[j];
546*fb1b10abSAndroid Build Coastguard Worker     }
547*fb1b10abSAndroid Build Coastguard Worker 
548*fb1b10abSAndroid Build Coastguard Worker     // Rows
549*fb1b10abSAndroid Build Coastguard Worker     for (i = 0; i < 4; ++i) {
550*fb1b10abSAndroid Build Coastguard Worker       for (j = 0; j < 4; ++j) temp_in[j] = out[j + i * 4];
551*fb1b10abSAndroid Build Coastguard Worker       ht.rows(temp_in, temp_out);
552*fb1b10abSAndroid Build Coastguard Worker       for (j = 0; j < 4; ++j) output[j + i * 4] = (temp_out[j] + 1) >> 2;
553*fb1b10abSAndroid Build Coastguard Worker     }
554*fb1b10abSAndroid Build Coastguard Worker   }
555*fb1b10abSAndroid Build Coastguard Worker }
556*fb1b10abSAndroid Build Coastguard Worker 
vp9_fht8x8_c(const int16_t * input,tran_low_t * output,int stride,int tx_type)557*fb1b10abSAndroid Build Coastguard Worker void vp9_fht8x8_c(const int16_t *input, tran_low_t *output, int stride,
558*fb1b10abSAndroid Build Coastguard Worker                   int tx_type) {
559*fb1b10abSAndroid Build Coastguard Worker   if (tx_type == DCT_DCT) {
560*fb1b10abSAndroid Build Coastguard Worker     vpx_fdct8x8_c(input, output, stride);
561*fb1b10abSAndroid Build Coastguard Worker   } else {
562*fb1b10abSAndroid Build Coastguard Worker     tran_low_t out[64];
563*fb1b10abSAndroid Build Coastguard Worker     int i, j;
564*fb1b10abSAndroid Build Coastguard Worker     tran_low_t temp_in[8], temp_out[8];
565*fb1b10abSAndroid Build Coastguard Worker     const transform_2d ht = FHT_8[tx_type];
566*fb1b10abSAndroid Build Coastguard Worker 
567*fb1b10abSAndroid Build Coastguard Worker     // Columns
568*fb1b10abSAndroid Build Coastguard Worker     for (i = 0; i < 8; ++i) {
569*fb1b10abSAndroid Build Coastguard Worker       for (j = 0; j < 8; ++j) temp_in[j] = input[j * stride + i] * 4;
570*fb1b10abSAndroid Build Coastguard Worker       ht.cols(temp_in, temp_out);
571*fb1b10abSAndroid Build Coastguard Worker       for (j = 0; j < 8; ++j) out[j * 8 + i] = temp_out[j];
572*fb1b10abSAndroid Build Coastguard Worker     }
573*fb1b10abSAndroid Build Coastguard Worker 
574*fb1b10abSAndroid Build Coastguard Worker     // Rows
575*fb1b10abSAndroid Build Coastguard Worker     for (i = 0; i < 8; ++i) {
576*fb1b10abSAndroid Build Coastguard Worker       for (j = 0; j < 8; ++j) temp_in[j] = out[j + i * 8];
577*fb1b10abSAndroid Build Coastguard Worker       ht.rows(temp_in, temp_out);
578*fb1b10abSAndroid Build Coastguard Worker       for (j = 0; j < 8; ++j)
579*fb1b10abSAndroid Build Coastguard Worker         output[j + i * 8] = (temp_out[j] + (temp_out[j] < 0)) >> 1;
580*fb1b10abSAndroid Build Coastguard Worker     }
581*fb1b10abSAndroid Build Coastguard Worker   }
582*fb1b10abSAndroid Build Coastguard Worker }
583*fb1b10abSAndroid Build Coastguard Worker 
584*fb1b10abSAndroid Build Coastguard Worker /* 4-point reversible, orthonormal Walsh-Hadamard in 3.5 adds, 0.5 shifts per
585*fb1b10abSAndroid Build Coastguard Worker    pixel. */
vp9_fwht4x4_c(const int16_t * input,tran_low_t * output,int stride)586*fb1b10abSAndroid Build Coastguard Worker void vp9_fwht4x4_c(const int16_t *input, tran_low_t *output, int stride) {
587*fb1b10abSAndroid Build Coastguard Worker   int i;
588*fb1b10abSAndroid Build Coastguard Worker   tran_high_t a1, b1, c1, d1, e1;
589*fb1b10abSAndroid Build Coastguard Worker   const int16_t *ip_pass0 = input;
590*fb1b10abSAndroid Build Coastguard Worker   const tran_low_t *ip = NULL;
591*fb1b10abSAndroid Build Coastguard Worker   tran_low_t *op = output;
592*fb1b10abSAndroid Build Coastguard Worker 
593*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < 4; i++) {
594*fb1b10abSAndroid Build Coastguard Worker     a1 = ip_pass0[0 * stride];
595*fb1b10abSAndroid Build Coastguard Worker     b1 = ip_pass0[1 * stride];
596*fb1b10abSAndroid Build Coastguard Worker     c1 = ip_pass0[2 * stride];
597*fb1b10abSAndroid Build Coastguard Worker     d1 = ip_pass0[3 * stride];
598*fb1b10abSAndroid Build Coastguard Worker 
599*fb1b10abSAndroid Build Coastguard Worker     a1 += b1;
600*fb1b10abSAndroid Build Coastguard Worker     d1 = d1 - c1;
601*fb1b10abSAndroid Build Coastguard Worker     e1 = (a1 - d1) >> 1;
602*fb1b10abSAndroid Build Coastguard Worker     b1 = e1 - b1;
603*fb1b10abSAndroid Build Coastguard Worker     c1 = e1 - c1;
604*fb1b10abSAndroid Build Coastguard Worker     a1 -= c1;
605*fb1b10abSAndroid Build Coastguard Worker     d1 += b1;
606*fb1b10abSAndroid Build Coastguard Worker     op[0] = (tran_low_t)a1;
607*fb1b10abSAndroid Build Coastguard Worker     op[4] = (tran_low_t)c1;
608*fb1b10abSAndroid Build Coastguard Worker     op[8] = (tran_low_t)d1;
609*fb1b10abSAndroid Build Coastguard Worker     op[12] = (tran_low_t)b1;
610*fb1b10abSAndroid Build Coastguard Worker 
611*fb1b10abSAndroid Build Coastguard Worker     ip_pass0++;
612*fb1b10abSAndroid Build Coastguard Worker     op++;
613*fb1b10abSAndroid Build Coastguard Worker   }
614*fb1b10abSAndroid Build Coastguard Worker   ip = output;
615*fb1b10abSAndroid Build Coastguard Worker   op = output;
616*fb1b10abSAndroid Build Coastguard Worker 
617*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < 4; i++) {
618*fb1b10abSAndroid Build Coastguard Worker     a1 = ip[0];
619*fb1b10abSAndroid Build Coastguard Worker     b1 = ip[1];
620*fb1b10abSAndroid Build Coastguard Worker     c1 = ip[2];
621*fb1b10abSAndroid Build Coastguard Worker     d1 = ip[3];
622*fb1b10abSAndroid Build Coastguard Worker 
623*fb1b10abSAndroid Build Coastguard Worker     a1 += b1;
624*fb1b10abSAndroid Build Coastguard Worker     d1 -= c1;
625*fb1b10abSAndroid Build Coastguard Worker     e1 = (a1 - d1) >> 1;
626*fb1b10abSAndroid Build Coastguard Worker     b1 = e1 - b1;
627*fb1b10abSAndroid Build Coastguard Worker     c1 = e1 - c1;
628*fb1b10abSAndroid Build Coastguard Worker     a1 -= c1;
629*fb1b10abSAndroid Build Coastguard Worker     d1 += b1;
630*fb1b10abSAndroid Build Coastguard Worker     op[0] = (tran_low_t)(a1 * UNIT_QUANT_FACTOR);
631*fb1b10abSAndroid Build Coastguard Worker     op[1] = (tran_low_t)(c1 * UNIT_QUANT_FACTOR);
632*fb1b10abSAndroid Build Coastguard Worker     op[2] = (tran_low_t)(d1 * UNIT_QUANT_FACTOR);
633*fb1b10abSAndroid Build Coastguard Worker     op[3] = (tran_low_t)(b1 * UNIT_QUANT_FACTOR);
634*fb1b10abSAndroid Build Coastguard Worker 
635*fb1b10abSAndroid Build Coastguard Worker     ip += 4;
636*fb1b10abSAndroid Build Coastguard Worker     op += 4;
637*fb1b10abSAndroid Build Coastguard Worker   }
638*fb1b10abSAndroid Build Coastguard Worker }
639*fb1b10abSAndroid Build Coastguard Worker 
vp9_fht16x16_c(const int16_t * input,tran_low_t * output,int stride,int tx_type)640*fb1b10abSAndroid Build Coastguard Worker void vp9_fht16x16_c(const int16_t *input, tran_low_t *output, int stride,
641*fb1b10abSAndroid Build Coastguard Worker                     int tx_type) {
642*fb1b10abSAndroid Build Coastguard Worker   if (tx_type == DCT_DCT) {
643*fb1b10abSAndroid Build Coastguard Worker     vpx_fdct16x16_c(input, output, stride);
644*fb1b10abSAndroid Build Coastguard Worker   } else {
645*fb1b10abSAndroid Build Coastguard Worker     tran_low_t out[256];
646*fb1b10abSAndroid Build Coastguard Worker     int i, j;
647*fb1b10abSAndroid Build Coastguard Worker     tran_low_t temp_in[16], temp_out[16];
648*fb1b10abSAndroid Build Coastguard Worker     const transform_2d ht = FHT_16[tx_type];
649*fb1b10abSAndroid Build Coastguard Worker 
650*fb1b10abSAndroid Build Coastguard Worker     // Columns
651*fb1b10abSAndroid Build Coastguard Worker     for (i = 0; i < 16; ++i) {
652*fb1b10abSAndroid Build Coastguard Worker       for (j = 0; j < 16; ++j) temp_in[j] = input[j * stride + i] * 4;
653*fb1b10abSAndroid Build Coastguard Worker       ht.cols(temp_in, temp_out);
654*fb1b10abSAndroid Build Coastguard Worker       for (j = 0; j < 16; ++j)
655*fb1b10abSAndroid Build Coastguard Worker         out[j * 16 + i] = (temp_out[j] + 1 + (temp_out[j] < 0)) >> 2;
656*fb1b10abSAndroid Build Coastguard Worker     }
657*fb1b10abSAndroid Build Coastguard Worker 
658*fb1b10abSAndroid Build Coastguard Worker     // Rows
659*fb1b10abSAndroid Build Coastguard Worker     for (i = 0; i < 16; ++i) {
660*fb1b10abSAndroid Build Coastguard Worker       for (j = 0; j < 16; ++j) temp_in[j] = out[j + i * 16];
661*fb1b10abSAndroid Build Coastguard Worker       ht.rows(temp_in, temp_out);
662*fb1b10abSAndroid Build Coastguard Worker       for (j = 0; j < 16; ++j) output[j + i * 16] = temp_out[j];
663*fb1b10abSAndroid Build Coastguard Worker     }
664*fb1b10abSAndroid Build Coastguard Worker   }
665*fb1b10abSAndroid Build Coastguard Worker }
666*fb1b10abSAndroid Build Coastguard Worker 
667*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
vp9_highbd_fht4x4_c(const int16_t * input,tran_low_t * output,int stride,int tx_type)668*fb1b10abSAndroid Build Coastguard Worker void vp9_highbd_fht4x4_c(const int16_t *input, tran_low_t *output, int stride,
669*fb1b10abSAndroid Build Coastguard Worker                          int tx_type) {
670*fb1b10abSAndroid Build Coastguard Worker   vp9_fht4x4_c(input, output, stride, tx_type);
671*fb1b10abSAndroid Build Coastguard Worker }
672*fb1b10abSAndroid Build Coastguard Worker 
vp9_highbd_fht8x8_c(const int16_t * input,tran_low_t * output,int stride,int tx_type)673*fb1b10abSAndroid Build Coastguard Worker void vp9_highbd_fht8x8_c(const int16_t *input, tran_low_t *output, int stride,
674*fb1b10abSAndroid Build Coastguard Worker                          int tx_type) {
675*fb1b10abSAndroid Build Coastguard Worker   vp9_fht8x8_c(input, output, stride, tx_type);
676*fb1b10abSAndroid Build Coastguard Worker }
677*fb1b10abSAndroid Build Coastguard Worker 
vp9_highbd_fwht4x4_c(const int16_t * input,tran_low_t * output,int stride)678*fb1b10abSAndroid Build Coastguard Worker void vp9_highbd_fwht4x4_c(const int16_t *input, tran_low_t *output,
679*fb1b10abSAndroid Build Coastguard Worker                           int stride) {
680*fb1b10abSAndroid Build Coastguard Worker   vp9_fwht4x4_c(input, output, stride);
681*fb1b10abSAndroid Build Coastguard Worker }
682*fb1b10abSAndroid Build Coastguard Worker 
vp9_highbd_fht16x16_c(const int16_t * input,tran_low_t * output,int stride,int tx_type)683*fb1b10abSAndroid Build Coastguard Worker void vp9_highbd_fht16x16_c(const int16_t *input, tran_low_t *output, int stride,
684*fb1b10abSAndroid Build Coastguard Worker                            int tx_type) {
685*fb1b10abSAndroid Build Coastguard Worker   vp9_fht16x16_c(input, output, stride, tx_type);
686*fb1b10abSAndroid Build Coastguard Worker }
687*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_VP9_HIGHBITDEPTH
688