1*c0909341SAndroid Build Coastguard Worker /*
2*c0909341SAndroid Build Coastguard Worker * Copyright © 2018, VideoLAN and dav1d authors
3*c0909341SAndroid Build Coastguard Worker * Copyright © 2018, Two Orioles, LLC
4*c0909341SAndroid Build Coastguard Worker * All rights reserved.
5*c0909341SAndroid Build Coastguard Worker *
6*c0909341SAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
7*c0909341SAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions are met:
8*c0909341SAndroid Build Coastguard Worker *
9*c0909341SAndroid Build Coastguard Worker * 1. Redistributions of source code must retain the above copyright notice, this
10*c0909341SAndroid Build Coastguard Worker * list of conditions and the following disclaimer.
11*c0909341SAndroid Build Coastguard Worker *
12*c0909341SAndroid Build Coastguard Worker * 2. Redistributions in binary form must reproduce the above copyright notice,
13*c0909341SAndroid Build Coastguard Worker * this list of conditions and the following disclaimer in the documentation
14*c0909341SAndroid Build Coastguard Worker * and/or other materials provided with the distribution.
15*c0909341SAndroid Build Coastguard Worker *
16*c0909341SAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17*c0909341SAndroid Build Coastguard Worker * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18*c0909341SAndroid Build Coastguard Worker * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19*c0909341SAndroid Build Coastguard Worker * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
20*c0909341SAndroid Build Coastguard Worker * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21*c0909341SAndroid Build Coastguard Worker * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22*c0909341SAndroid Build Coastguard Worker * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23*c0909341SAndroid Build Coastguard Worker * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24*c0909341SAndroid Build Coastguard Worker * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25*c0909341SAndroid Build Coastguard Worker * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*c0909341SAndroid Build Coastguard Worker */
27*c0909341SAndroid Build Coastguard Worker
28*c0909341SAndroid Build Coastguard Worker #include "tests/checkasm/checkasm.h"
29*c0909341SAndroid Build Coastguard Worker
30*c0909341SAndroid Build Coastguard Worker #include <math.h>
31*c0909341SAndroid Build Coastguard Worker
32*c0909341SAndroid Build Coastguard Worker #include "src/itx.h"
33*c0909341SAndroid Build Coastguard Worker #include "src/levels.h"
34*c0909341SAndroid Build Coastguard Worker #include "src/scan.h"
35*c0909341SAndroid Build Coastguard Worker #include "src/tables.h"
36*c0909341SAndroid Build Coastguard Worker
37*c0909341SAndroid Build Coastguard Worker #ifndef M_PI
38*c0909341SAndroid Build Coastguard Worker #define M_PI 3.14159265358979323846
39*c0909341SAndroid Build Coastguard Worker #endif
40*c0909341SAndroid Build Coastguard Worker #ifndef M_SQRT1_2
41*c0909341SAndroid Build Coastguard Worker #define M_SQRT1_2 0.707106781186547524401
42*c0909341SAndroid Build Coastguard Worker #endif
43*c0909341SAndroid Build Coastguard Worker
44*c0909341SAndroid Build Coastguard Worker enum Tx1D { DCT, ADST, FLIPADST, IDENTITY, WHT };
45*c0909341SAndroid Build Coastguard Worker
46*c0909341SAndroid Build Coastguard Worker static const uint8_t itx_1d_types[N_TX_TYPES_PLUS_LL][2] = {
47*c0909341SAndroid Build Coastguard Worker [DCT_DCT] = { DCT, DCT },
48*c0909341SAndroid Build Coastguard Worker [ADST_DCT] = { DCT, ADST },
49*c0909341SAndroid Build Coastguard Worker [DCT_ADST] = { ADST, DCT },
50*c0909341SAndroid Build Coastguard Worker [ADST_ADST] = { ADST, ADST },
51*c0909341SAndroid Build Coastguard Worker [FLIPADST_DCT] = { DCT, FLIPADST },
52*c0909341SAndroid Build Coastguard Worker [DCT_FLIPADST] = { FLIPADST, DCT },
53*c0909341SAndroid Build Coastguard Worker [FLIPADST_FLIPADST] = { FLIPADST, FLIPADST },
54*c0909341SAndroid Build Coastguard Worker [ADST_FLIPADST] = { FLIPADST, ADST },
55*c0909341SAndroid Build Coastguard Worker [FLIPADST_ADST] = { ADST, FLIPADST },
56*c0909341SAndroid Build Coastguard Worker [IDTX] = { IDENTITY, IDENTITY },
57*c0909341SAndroid Build Coastguard Worker [V_DCT] = { IDENTITY, DCT },
58*c0909341SAndroid Build Coastguard Worker [H_DCT] = { DCT, IDENTITY },
59*c0909341SAndroid Build Coastguard Worker [V_ADST] = { IDENTITY, ADST },
60*c0909341SAndroid Build Coastguard Worker [H_ADST] = { ADST, IDENTITY },
61*c0909341SAndroid Build Coastguard Worker [V_FLIPADST] = { IDENTITY, FLIPADST },
62*c0909341SAndroid Build Coastguard Worker [H_FLIPADST] = { FLIPADST, IDENTITY },
63*c0909341SAndroid Build Coastguard Worker [WHT_WHT] = { WHT, WHT },
64*c0909341SAndroid Build Coastguard Worker };
65*c0909341SAndroid Build Coastguard Worker
66*c0909341SAndroid Build Coastguard Worker static const char *const itx_1d_names[5] = {
67*c0909341SAndroid Build Coastguard Worker [DCT] = "dct",
68*c0909341SAndroid Build Coastguard Worker [ADST] = "adst",
69*c0909341SAndroid Build Coastguard Worker [FLIPADST] = "flipadst",
70*c0909341SAndroid Build Coastguard Worker [IDENTITY] = "identity",
71*c0909341SAndroid Build Coastguard Worker [WHT] = "wht"
72*c0909341SAndroid Build Coastguard Worker };
73*c0909341SAndroid Build Coastguard Worker
74*c0909341SAndroid Build Coastguard Worker static const double scaling_factors[9] = {
75*c0909341SAndroid Build Coastguard Worker 4.0000, /* 4x4 */
76*c0909341SAndroid Build Coastguard Worker 4.0000 * M_SQRT1_2, /* 4x8 8x4 */
77*c0909341SAndroid Build Coastguard Worker 2.0000, /* 4x16 8x8 16x4 */
78*c0909341SAndroid Build Coastguard Worker 2.0000 * M_SQRT1_2, /* 8x16 16x8 */
79*c0909341SAndroid Build Coastguard Worker 1.0000, /* 8x32 16x16 32x8 */
80*c0909341SAndroid Build Coastguard Worker 0.5000 * M_SQRT1_2, /* 16x32 32x16 */
81*c0909341SAndroid Build Coastguard Worker 0.2500, /* 16x64 32x32 64x16 */
82*c0909341SAndroid Build Coastguard Worker 0.1250 * M_SQRT1_2, /* 32x64 64x32 */
83*c0909341SAndroid Build Coastguard Worker 0.0625, /* 64x64 */
84*c0909341SAndroid Build Coastguard Worker };
85*c0909341SAndroid Build Coastguard Worker
86*c0909341SAndroid Build Coastguard Worker /* FIXME: Ensure that those forward transforms are similar to the real AV1
87*c0909341SAndroid Build Coastguard Worker * transforms. The FLIPADST currently uses the ADST forward transform for
88*c0909341SAndroid Build Coastguard Worker * example which is obviously "incorrect", but we're just using it for now
89*c0909341SAndroid Build Coastguard Worker * since it does produce coefficients in the correct range at least. */
90*c0909341SAndroid Build Coastguard Worker
91*c0909341SAndroid Build Coastguard Worker /* DCT-II */
fdct_1d(double * const out,const double * const in,const int sz)92*c0909341SAndroid Build Coastguard Worker static void fdct_1d(double *const out, const double *const in, const int sz) {
93*c0909341SAndroid Build Coastguard Worker for (int i = 0; i < sz; i++) {
94*c0909341SAndroid Build Coastguard Worker out[i] = 0.0;
95*c0909341SAndroid Build Coastguard Worker for (int j = 0; j < sz; j++)
96*c0909341SAndroid Build Coastguard Worker out[i] += in[j] * cos(M_PI * (2 * j + 1) * i / (sz * 2.0));
97*c0909341SAndroid Build Coastguard Worker }
98*c0909341SAndroid Build Coastguard Worker out[0] *= M_SQRT1_2;
99*c0909341SAndroid Build Coastguard Worker }
100*c0909341SAndroid Build Coastguard Worker
101*c0909341SAndroid Build Coastguard Worker /* See "Towards jointly optimal spatial prediction and adaptive transform in
102*c0909341SAndroid Build Coastguard Worker * video/image coding", by J. Han, A. Saxena, and K. Rose
103*c0909341SAndroid Build Coastguard Worker * IEEE Proc. ICASSP, pp. 726-729, Mar. 2010.
104*c0909341SAndroid Build Coastguard Worker * and "A Butterfly Structured Design of The Hybrid Transform Coding Scheme",
105*c0909341SAndroid Build Coastguard Worker * by Jingning Han, Yaowu Xu, and Debargha Mukherjee
106*c0909341SAndroid Build Coastguard Worker * http://research.google.com/pubs/archive/41418.pdf
107*c0909341SAndroid Build Coastguard Worker */
fadst_1d(double * const out,const double * const in,const int sz)108*c0909341SAndroid Build Coastguard Worker static void fadst_1d(double *const out, const double *const in, const int sz) {
109*c0909341SAndroid Build Coastguard Worker for (int i = 0; i < sz; i++) {
110*c0909341SAndroid Build Coastguard Worker out[i] = 0.0;
111*c0909341SAndroid Build Coastguard Worker for (int j = 0; j < sz; j++)
112*c0909341SAndroid Build Coastguard Worker out[i] += in[j] * sin(M_PI *
113*c0909341SAndroid Build Coastguard Worker (sz == 4 ? ( j + 1) * (2 * i + 1) / (8.0 + 1.0) :
114*c0909341SAndroid Build Coastguard Worker (2 * j + 1) * (2 * i + 1) / (sz * 4.0)));
115*c0909341SAndroid Build Coastguard Worker }
116*c0909341SAndroid Build Coastguard Worker }
117*c0909341SAndroid Build Coastguard Worker
fwht4_1d(double * const out,const double * const in)118*c0909341SAndroid Build Coastguard Worker static void fwht4_1d(double *const out, const double *const in)
119*c0909341SAndroid Build Coastguard Worker {
120*c0909341SAndroid Build Coastguard Worker const double t0 = in[0] + in[1];
121*c0909341SAndroid Build Coastguard Worker const double t3 = in[3] - in[2];
122*c0909341SAndroid Build Coastguard Worker const double t4 = (t0 - t3) * 0.5;
123*c0909341SAndroid Build Coastguard Worker const double t1 = t4 - in[1];
124*c0909341SAndroid Build Coastguard Worker const double t2 = t4 - in[2];
125*c0909341SAndroid Build Coastguard Worker out[0] = t0 - t2;
126*c0909341SAndroid Build Coastguard Worker out[1] = t2;
127*c0909341SAndroid Build Coastguard Worker out[2] = t3 + t1;
128*c0909341SAndroid Build Coastguard Worker out[3] = t1;
129*c0909341SAndroid Build Coastguard Worker }
130*c0909341SAndroid Build Coastguard Worker
copy_subcoefs(coef * coeff,const enum RectTxfmSize tx,const enum TxfmType txtp,const int sw,const int sh,const int subsh,int * const max_eob)131*c0909341SAndroid Build Coastguard Worker static int copy_subcoefs(coef *coeff,
132*c0909341SAndroid Build Coastguard Worker const enum RectTxfmSize tx, const enum TxfmType txtp,
133*c0909341SAndroid Build Coastguard Worker const int sw, const int sh, const int subsh,
134*c0909341SAndroid Build Coastguard Worker int *const max_eob)
135*c0909341SAndroid Build Coastguard Worker {
136*c0909341SAndroid Build Coastguard Worker /* copy the topleft coefficients such that the return value (being the
137*c0909341SAndroid Build Coastguard Worker * coefficient scantable index for the eob token) guarantees that only
138*c0909341SAndroid Build Coastguard Worker * the topleft $sub out of $sz (where $sz >= $sub) coefficients in both
139*c0909341SAndroid Build Coastguard Worker * dimensions are non-zero. This leads to braching to specific optimized
140*c0909341SAndroid Build Coastguard Worker * simd versions (e.g. dc-only) so that we get full asm coverage in this
141*c0909341SAndroid Build Coastguard Worker * test */
142*c0909341SAndroid Build Coastguard Worker
143*c0909341SAndroid Build Coastguard Worker const enum TxClass tx_class = dav1d_tx_type_class[txtp];
144*c0909341SAndroid Build Coastguard Worker const uint16_t *const scan = dav1d_scans[tx];
145*c0909341SAndroid Build Coastguard Worker const int sub_high = subsh > 0 ? subsh * 8 - 1 : 0;
146*c0909341SAndroid Build Coastguard Worker const int sub_low = subsh > 1 ? sub_high - 8 : 0;
147*c0909341SAndroid Build Coastguard Worker int n, eob;
148*c0909341SAndroid Build Coastguard Worker
149*c0909341SAndroid Build Coastguard Worker for (n = 0, eob = 0; n < sw * sh; n++) {
150*c0909341SAndroid Build Coastguard Worker int rc, rcx, rcy;
151*c0909341SAndroid Build Coastguard Worker if (tx_class == TX_CLASS_2D)
152*c0909341SAndroid Build Coastguard Worker rc = scan[n], rcx = rc % sh, rcy = rc / sh;
153*c0909341SAndroid Build Coastguard Worker else if (tx_class == TX_CLASS_H)
154*c0909341SAndroid Build Coastguard Worker rcx = n % sh, rcy = n / sh, rc = n;
155*c0909341SAndroid Build Coastguard Worker else /* tx_class == TX_CLASS_V */
156*c0909341SAndroid Build Coastguard Worker rcx = n / sw, rcy = n % sw, rc = rcy * sh + rcx;
157*c0909341SAndroid Build Coastguard Worker
158*c0909341SAndroid Build Coastguard Worker /* Pick a random eob within this sub-itx */
159*c0909341SAndroid Build Coastguard Worker if (rcx > sub_high || rcy > sub_high) {
160*c0909341SAndroid Build Coastguard Worker break; /* upper boundary */
161*c0909341SAndroid Build Coastguard Worker } else if (!eob && (rcx > sub_low || rcy > sub_low))
162*c0909341SAndroid Build Coastguard Worker eob = n; /* lower boundary */
163*c0909341SAndroid Build Coastguard Worker }
164*c0909341SAndroid Build Coastguard Worker *max_eob = n - 1;
165*c0909341SAndroid Build Coastguard Worker
166*c0909341SAndroid Build Coastguard Worker if (eob)
167*c0909341SAndroid Build Coastguard Worker eob += rnd() % (n - eob - 1);
168*c0909341SAndroid Build Coastguard Worker if (tx_class == TX_CLASS_2D)
169*c0909341SAndroid Build Coastguard Worker for (n = eob + 1; n < sw * sh; n++)
170*c0909341SAndroid Build Coastguard Worker coeff[scan[n]] = 0;
171*c0909341SAndroid Build Coastguard Worker else if (tx_class == TX_CLASS_H)
172*c0909341SAndroid Build Coastguard Worker for (n = eob + 1; n < sw * sh; n++)
173*c0909341SAndroid Build Coastguard Worker coeff[n] = 0;
174*c0909341SAndroid Build Coastguard Worker else /* tx_class == TX_CLASS_V */ {
175*c0909341SAndroid Build Coastguard Worker for (int rcx = eob / sw, rcy = eob % sw; rcx < sh; rcx++, rcy = -1)
176*c0909341SAndroid Build Coastguard Worker while (++rcy < sw)
177*c0909341SAndroid Build Coastguard Worker coeff[rcy * sh + rcx] = 0;
178*c0909341SAndroid Build Coastguard Worker n = sw * sh;
179*c0909341SAndroid Build Coastguard Worker }
180*c0909341SAndroid Build Coastguard Worker for (; n < 32 * 32; n++)
181*c0909341SAndroid Build Coastguard Worker coeff[n] = rnd();
182*c0909341SAndroid Build Coastguard Worker return eob;
183*c0909341SAndroid Build Coastguard Worker }
184*c0909341SAndroid Build Coastguard Worker
ftx(coef * const buf,const enum RectTxfmSize tx,const enum TxfmType txtp,const int w,const int h,const int subsh,int * const max_eob,const int bitdepth_max)185*c0909341SAndroid Build Coastguard Worker static int ftx(coef *const buf, const enum RectTxfmSize tx,
186*c0909341SAndroid Build Coastguard Worker const enum TxfmType txtp, const int w, const int h,
187*c0909341SAndroid Build Coastguard Worker const int subsh, int *const max_eob, const int bitdepth_max)
188*c0909341SAndroid Build Coastguard Worker {
189*c0909341SAndroid Build Coastguard Worker double out[64 * 64], temp[64 * 64];
190*c0909341SAndroid Build Coastguard Worker const double scale = scaling_factors[ctz(w * h) - 4];
191*c0909341SAndroid Build Coastguard Worker const int sw = imin(w, 32), sh = imin(h, 32);
192*c0909341SAndroid Build Coastguard Worker
193*c0909341SAndroid Build Coastguard Worker for (int i = 0; i < h; i++) {
194*c0909341SAndroid Build Coastguard Worker double in[64], temp_out[64];
195*c0909341SAndroid Build Coastguard Worker
196*c0909341SAndroid Build Coastguard Worker for (int i = 0; i < w; i++)
197*c0909341SAndroid Build Coastguard Worker in[i] = (rnd() & (2 * bitdepth_max + 1)) - bitdepth_max;
198*c0909341SAndroid Build Coastguard Worker
199*c0909341SAndroid Build Coastguard Worker switch (itx_1d_types[txtp][0]) {
200*c0909341SAndroid Build Coastguard Worker case DCT:
201*c0909341SAndroid Build Coastguard Worker fdct_1d(temp_out, in, w);
202*c0909341SAndroid Build Coastguard Worker break;
203*c0909341SAndroid Build Coastguard Worker case ADST:
204*c0909341SAndroid Build Coastguard Worker case FLIPADST:
205*c0909341SAndroid Build Coastguard Worker fadst_1d(temp_out, in, w);
206*c0909341SAndroid Build Coastguard Worker break;
207*c0909341SAndroid Build Coastguard Worker case WHT:
208*c0909341SAndroid Build Coastguard Worker fwht4_1d(temp_out, in);
209*c0909341SAndroid Build Coastguard Worker break;
210*c0909341SAndroid Build Coastguard Worker case IDENTITY:
211*c0909341SAndroid Build Coastguard Worker memcpy(temp_out, in, w * sizeof(*temp_out));
212*c0909341SAndroid Build Coastguard Worker break;
213*c0909341SAndroid Build Coastguard Worker }
214*c0909341SAndroid Build Coastguard Worker
215*c0909341SAndroid Build Coastguard Worker for (int j = 0; j < w; j++)
216*c0909341SAndroid Build Coastguard Worker temp[j * h + i] = temp_out[j] * scale;
217*c0909341SAndroid Build Coastguard Worker }
218*c0909341SAndroid Build Coastguard Worker
219*c0909341SAndroid Build Coastguard Worker for (int i = 0; i < w; i++) {
220*c0909341SAndroid Build Coastguard Worker switch (itx_1d_types[txtp][0]) {
221*c0909341SAndroid Build Coastguard Worker case DCT:
222*c0909341SAndroid Build Coastguard Worker fdct_1d(&out[i * h], &temp[i * h], h);
223*c0909341SAndroid Build Coastguard Worker break;
224*c0909341SAndroid Build Coastguard Worker case ADST:
225*c0909341SAndroid Build Coastguard Worker case FLIPADST:
226*c0909341SAndroid Build Coastguard Worker fadst_1d(&out[i * h], &temp[i * h], h);
227*c0909341SAndroid Build Coastguard Worker break;
228*c0909341SAndroid Build Coastguard Worker case WHT:
229*c0909341SAndroid Build Coastguard Worker fwht4_1d(&out[i * h], &temp[i * h]);
230*c0909341SAndroid Build Coastguard Worker break;
231*c0909341SAndroid Build Coastguard Worker case IDENTITY:
232*c0909341SAndroid Build Coastguard Worker memcpy(&out[i * h], &temp[i * h], h * sizeof(*out));
233*c0909341SAndroid Build Coastguard Worker break;
234*c0909341SAndroid Build Coastguard Worker }
235*c0909341SAndroid Build Coastguard Worker }
236*c0909341SAndroid Build Coastguard Worker
237*c0909341SAndroid Build Coastguard Worker for (int y = 0; y < sh; y++)
238*c0909341SAndroid Build Coastguard Worker for (int x = 0; x < sw; x++)
239*c0909341SAndroid Build Coastguard Worker buf[y * sw + x] = (coef) (out[y * w + x] + 0.5);
240*c0909341SAndroid Build Coastguard Worker
241*c0909341SAndroid Build Coastguard Worker return copy_subcoefs(buf, tx, txtp, sw, sh, subsh, max_eob);
242*c0909341SAndroid Build Coastguard Worker }
243*c0909341SAndroid Build Coastguard Worker
check_itxfm_add(Dav1dInvTxfmDSPContext * const c,const enum RectTxfmSize tx)244*c0909341SAndroid Build Coastguard Worker static void check_itxfm_add(Dav1dInvTxfmDSPContext *const c,
245*c0909341SAndroid Build Coastguard Worker const enum RectTxfmSize tx)
246*c0909341SAndroid Build Coastguard Worker {
247*c0909341SAndroid Build Coastguard Worker ALIGN_STK_64(coef, coeff, 2, [32 * 32]);
248*c0909341SAndroid Build Coastguard Worker PIXEL_RECT(c_dst, 64, 64);
249*c0909341SAndroid Build Coastguard Worker PIXEL_RECT(a_dst, 64, 64);
250*c0909341SAndroid Build Coastguard Worker
251*c0909341SAndroid Build Coastguard Worker static const uint8_t subsh_iters[5] = { 2, 2, 3, 5, 5 };
252*c0909341SAndroid Build Coastguard Worker
253*c0909341SAndroid Build Coastguard Worker const int w = dav1d_txfm_dimensions[tx].w * 4;
254*c0909341SAndroid Build Coastguard Worker const int h = dav1d_txfm_dimensions[tx].h * 4;
255*c0909341SAndroid Build Coastguard Worker const int subsh_max = subsh_iters[imax(dav1d_txfm_dimensions[tx].lw,
256*c0909341SAndroid Build Coastguard Worker dav1d_txfm_dimensions[tx].lh)];
257*c0909341SAndroid Build Coastguard Worker #if BITDEPTH == 16
258*c0909341SAndroid Build Coastguard Worker const int bpc_min = 10, bpc_max = 12;
259*c0909341SAndroid Build Coastguard Worker #else
260*c0909341SAndroid Build Coastguard Worker const int bpc_min = 8, bpc_max = 8;
261*c0909341SAndroid Build Coastguard Worker #endif
262*c0909341SAndroid Build Coastguard Worker
263*c0909341SAndroid Build Coastguard Worker declare_func(void, pixel *dst, ptrdiff_t dst_stride, coef *coeff,
264*c0909341SAndroid Build Coastguard Worker int eob HIGHBD_DECL_SUFFIX);
265*c0909341SAndroid Build Coastguard Worker
266*c0909341SAndroid Build Coastguard Worker for (int bpc = bpc_min; bpc <= bpc_max; bpc += 2) {
267*c0909341SAndroid Build Coastguard Worker bitfn(dav1d_itx_dsp_init)(c, bpc);
268*c0909341SAndroid Build Coastguard Worker for (enum TxfmType txtp = 0; txtp < N_TX_TYPES_PLUS_LL; txtp++)
269*c0909341SAndroid Build Coastguard Worker for (int subsh = 0; subsh < subsh_max; subsh++)
270*c0909341SAndroid Build Coastguard Worker if (check_func(c->itxfm_add[tx][txtp],
271*c0909341SAndroid Build Coastguard Worker "inv_txfm_add_%dx%d_%s_%s_%d_%dbpc",
272*c0909341SAndroid Build Coastguard Worker w, h, itx_1d_names[itx_1d_types[txtp][0]],
273*c0909341SAndroid Build Coastguard Worker itx_1d_names[itx_1d_types[txtp][1]], subsh,
274*c0909341SAndroid Build Coastguard Worker bpc))
275*c0909341SAndroid Build Coastguard Worker {
276*c0909341SAndroid Build Coastguard Worker const int bitdepth_max = (1 << bpc) - 1;
277*c0909341SAndroid Build Coastguard Worker int max_eob;
278*c0909341SAndroid Build Coastguard Worker const int eob = ftx(coeff[0], tx, txtp, w, h, subsh, &max_eob,
279*c0909341SAndroid Build Coastguard Worker bitdepth_max);
280*c0909341SAndroid Build Coastguard Worker memcpy(coeff[1], coeff[0], sizeof(*coeff));
281*c0909341SAndroid Build Coastguard Worker
282*c0909341SAndroid Build Coastguard Worker CLEAR_PIXEL_RECT(c_dst);
283*c0909341SAndroid Build Coastguard Worker CLEAR_PIXEL_RECT(a_dst);
284*c0909341SAndroid Build Coastguard Worker
285*c0909341SAndroid Build Coastguard Worker for (int y = 0; y < h; y++)
286*c0909341SAndroid Build Coastguard Worker for (int x = 0; x < w; x++)
287*c0909341SAndroid Build Coastguard Worker c_dst[y*PXSTRIDE(c_dst_stride) + x] =
288*c0909341SAndroid Build Coastguard Worker a_dst[y*PXSTRIDE(a_dst_stride) + x] = rnd() & bitdepth_max;
289*c0909341SAndroid Build Coastguard Worker
290*c0909341SAndroid Build Coastguard Worker call_ref(c_dst, c_dst_stride, coeff[0], eob
291*c0909341SAndroid Build Coastguard Worker HIGHBD_TAIL_SUFFIX);
292*c0909341SAndroid Build Coastguard Worker call_new(a_dst, a_dst_stride, coeff[1], eob
293*c0909341SAndroid Build Coastguard Worker HIGHBD_TAIL_SUFFIX);
294*c0909341SAndroid Build Coastguard Worker
295*c0909341SAndroid Build Coastguard Worker checkasm_check_pixel_padded(c_dst, c_dst_stride,
296*c0909341SAndroid Build Coastguard Worker a_dst, a_dst_stride,
297*c0909341SAndroid Build Coastguard Worker w, h, "dst");
298*c0909341SAndroid Build Coastguard Worker if (memcmp(coeff[0], coeff[1], sizeof(*coeff)))
299*c0909341SAndroid Build Coastguard Worker fail();
300*c0909341SAndroid Build Coastguard Worker
301*c0909341SAndroid Build Coastguard Worker bench_new(alternate(c_dst, a_dst), a_dst_stride,
302*c0909341SAndroid Build Coastguard Worker alternate(coeff[0], coeff[1]), max_eob HIGHBD_TAIL_SUFFIX);
303*c0909341SAndroid Build Coastguard Worker }
304*c0909341SAndroid Build Coastguard Worker }
305*c0909341SAndroid Build Coastguard Worker report("add_%dx%d", w, h);
306*c0909341SAndroid Build Coastguard Worker }
307*c0909341SAndroid Build Coastguard Worker
bitfn(checkasm_check_itx)308*c0909341SAndroid Build Coastguard Worker void bitfn(checkasm_check_itx)(void) {
309*c0909341SAndroid Build Coastguard Worker static const uint8_t txfm_size_order[N_RECT_TX_SIZES] = {
310*c0909341SAndroid Build Coastguard Worker TX_4X4, RTX_4X8, RTX_4X16,
311*c0909341SAndroid Build Coastguard Worker RTX_8X4, TX_8X8, RTX_8X16, RTX_8X32,
312*c0909341SAndroid Build Coastguard Worker RTX_16X4, RTX_16X8, TX_16X16, RTX_16X32, RTX_16X64,
313*c0909341SAndroid Build Coastguard Worker RTX_32X8, RTX_32X16, TX_32X32, RTX_32X64,
314*c0909341SAndroid Build Coastguard Worker RTX_64X16, RTX_64X32, TX_64X64
315*c0909341SAndroid Build Coastguard Worker };
316*c0909341SAndroid Build Coastguard Worker
317*c0909341SAndroid Build Coastguard Worker /* Zero unused function pointer elements. */
318*c0909341SAndroid Build Coastguard Worker Dav1dInvTxfmDSPContext c = { { { 0 } } };
319*c0909341SAndroid Build Coastguard Worker
320*c0909341SAndroid Build Coastguard Worker for (int i = 0; i < N_RECT_TX_SIZES; i++)
321*c0909341SAndroid Build Coastguard Worker check_itxfm_add(&c, txfm_size_order[i]);
322*c0909341SAndroid Build Coastguard Worker }
323