1*77c1e3ccSAndroid Build Coastguard Worker /*
2*77c1e3ccSAndroid Build Coastguard Worker * Copyright (c) 2016, Alliance for Open Media. All rights reserved.
3*77c1e3ccSAndroid Build Coastguard Worker *
4*77c1e3ccSAndroid Build Coastguard Worker * This source code is subject to the terms of the BSD 2 Clause License and
5*77c1e3ccSAndroid Build Coastguard Worker * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6*77c1e3ccSAndroid Build Coastguard Worker * was not distributed with this source code in the LICENSE file, you can
7*77c1e3ccSAndroid Build Coastguard Worker * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8*77c1e3ccSAndroid Build Coastguard Worker * Media Patent License 1.0 was not distributed with this source code in the
9*77c1e3ccSAndroid Build Coastguard Worker * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10*77c1e3ccSAndroid Build Coastguard Worker */
11*77c1e3ccSAndroid Build Coastguard Worker
12*77c1e3ccSAndroid Build Coastguard Worker #include <assert.h>
13*77c1e3ccSAndroid Build Coastguard Worker #include <math.h>
14*77c1e3ccSAndroid Build Coastguard Worker
15*77c1e3ccSAndroid Build Coastguard Worker #include "config/aom_config.h"
16*77c1e3ccSAndroid Build Coastguard Worker #include "config/aom_dsp_rtcd.h"
17*77c1e3ccSAndroid Build Coastguard Worker
18*77c1e3ccSAndroid Build Coastguard Worker #include "aom_dsp/aom_dsp_common.h"
19*77c1e3ccSAndroid Build Coastguard Worker #include "aom_dsp/intrapred_common.h"
20*77c1e3ccSAndroid Build Coastguard Worker #include "aom_mem/aom_mem.h"
21*77c1e3ccSAndroid Build Coastguard Worker #include "aom_ports/bitops.h"
22*77c1e3ccSAndroid Build Coastguard Worker
v_predictor(uint8_t * dst,ptrdiff_t stride,int bw,int bh,const uint8_t * above,const uint8_t * left)23*77c1e3ccSAndroid Build Coastguard Worker static inline void v_predictor(uint8_t *dst, ptrdiff_t stride, int bw, int bh,
24*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
25*77c1e3ccSAndroid Build Coastguard Worker int r;
26*77c1e3ccSAndroid Build Coastguard Worker (void)left;
27*77c1e3ccSAndroid Build Coastguard Worker
28*77c1e3ccSAndroid Build Coastguard Worker for (r = 0; r < bh; r++) {
29*77c1e3ccSAndroid Build Coastguard Worker memcpy(dst, above, bw);
30*77c1e3ccSAndroid Build Coastguard Worker dst += stride;
31*77c1e3ccSAndroid Build Coastguard Worker }
32*77c1e3ccSAndroid Build Coastguard Worker }
33*77c1e3ccSAndroid Build Coastguard Worker
h_predictor(uint8_t * dst,ptrdiff_t stride,int bw,int bh,const uint8_t * above,const uint8_t * left)34*77c1e3ccSAndroid Build Coastguard Worker static inline void h_predictor(uint8_t *dst, ptrdiff_t stride, int bw, int bh,
35*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
36*77c1e3ccSAndroid Build Coastguard Worker int r;
37*77c1e3ccSAndroid Build Coastguard Worker (void)above;
38*77c1e3ccSAndroid Build Coastguard Worker
39*77c1e3ccSAndroid Build Coastguard Worker for (r = 0; r < bh; r++) {
40*77c1e3ccSAndroid Build Coastguard Worker memset(dst, left[r], bw);
41*77c1e3ccSAndroid Build Coastguard Worker dst += stride;
42*77c1e3ccSAndroid Build Coastguard Worker }
43*77c1e3ccSAndroid Build Coastguard Worker }
44*77c1e3ccSAndroid Build Coastguard Worker
abs_diff(int a,int b)45*77c1e3ccSAndroid Build Coastguard Worker static inline int abs_diff(int a, int b) { return (a > b) ? a - b : b - a; }
46*77c1e3ccSAndroid Build Coastguard Worker
paeth_predictor_single(uint16_t left,uint16_t top,uint16_t top_left)47*77c1e3ccSAndroid Build Coastguard Worker static inline uint16_t paeth_predictor_single(uint16_t left, uint16_t top,
48*77c1e3ccSAndroid Build Coastguard Worker uint16_t top_left) {
49*77c1e3ccSAndroid Build Coastguard Worker const int base = top + left - top_left;
50*77c1e3ccSAndroid Build Coastguard Worker const int p_left = abs_diff(base, left);
51*77c1e3ccSAndroid Build Coastguard Worker const int p_top = abs_diff(base, top);
52*77c1e3ccSAndroid Build Coastguard Worker const int p_top_left = abs_diff(base, top_left);
53*77c1e3ccSAndroid Build Coastguard Worker
54*77c1e3ccSAndroid Build Coastguard Worker // Return nearest to base of left, top and top_left.
55*77c1e3ccSAndroid Build Coastguard Worker return (p_left <= p_top && p_left <= p_top_left) ? left
56*77c1e3ccSAndroid Build Coastguard Worker : (p_top <= p_top_left) ? top
57*77c1e3ccSAndroid Build Coastguard Worker : top_left;
58*77c1e3ccSAndroid Build Coastguard Worker }
59*77c1e3ccSAndroid Build Coastguard Worker
paeth_predictor(uint8_t * dst,ptrdiff_t stride,int bw,int bh,const uint8_t * above,const uint8_t * left)60*77c1e3ccSAndroid Build Coastguard Worker static inline void paeth_predictor(uint8_t *dst, ptrdiff_t stride, int bw,
61*77c1e3ccSAndroid Build Coastguard Worker int bh, const uint8_t *above,
62*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left) {
63*77c1e3ccSAndroid Build Coastguard Worker int r, c;
64*77c1e3ccSAndroid Build Coastguard Worker const uint8_t ytop_left = above[-1];
65*77c1e3ccSAndroid Build Coastguard Worker
66*77c1e3ccSAndroid Build Coastguard Worker for (r = 0; r < bh; r++) {
67*77c1e3ccSAndroid Build Coastguard Worker for (c = 0; c < bw; c++)
68*77c1e3ccSAndroid Build Coastguard Worker dst[c] = (uint8_t)paeth_predictor_single(left[r], above[c], ytop_left);
69*77c1e3ccSAndroid Build Coastguard Worker dst += stride;
70*77c1e3ccSAndroid Build Coastguard Worker }
71*77c1e3ccSAndroid Build Coastguard Worker }
72*77c1e3ccSAndroid Build Coastguard Worker
73*77c1e3ccSAndroid Build Coastguard Worker // Some basic checks on weights for smooth predictor.
74*77c1e3ccSAndroid Build Coastguard Worker #define sm_weights_sanity_checks(weights_w, weights_h, weights_scale, \
75*77c1e3ccSAndroid Build Coastguard Worker pred_scale) \
76*77c1e3ccSAndroid Build Coastguard Worker assert(weights_w[0] < weights_scale); \
77*77c1e3ccSAndroid Build Coastguard Worker assert(weights_h[0] < weights_scale); \
78*77c1e3ccSAndroid Build Coastguard Worker assert(weights_scale - weights_w[bw - 1] < weights_scale); \
79*77c1e3ccSAndroid Build Coastguard Worker assert(weights_scale - weights_h[bh - 1] < weights_scale); \
80*77c1e3ccSAndroid Build Coastguard Worker assert(pred_scale < 31) // ensures no overflow when calculating predictor.
81*77c1e3ccSAndroid Build Coastguard Worker
82*77c1e3ccSAndroid Build Coastguard Worker #define divide_round(value, bits) (((value) + (1 << ((bits)-1))) >> (bits))
83*77c1e3ccSAndroid Build Coastguard Worker
smooth_predictor(uint8_t * dst,ptrdiff_t stride,int bw,int bh,const uint8_t * above,const uint8_t * left)84*77c1e3ccSAndroid Build Coastguard Worker static inline void smooth_predictor(uint8_t *dst, ptrdiff_t stride, int bw,
85*77c1e3ccSAndroid Build Coastguard Worker int bh, const uint8_t *above,
86*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left) {
87*77c1e3ccSAndroid Build Coastguard Worker const uint8_t below_pred = left[bh - 1]; // estimated by bottom-left pixel
88*77c1e3ccSAndroid Build Coastguard Worker const uint8_t right_pred = above[bw - 1]; // estimated by top-right pixel
89*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *const sm_weights_w = smooth_weights + bw - 4;
90*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *const sm_weights_h = smooth_weights + bh - 4;
91*77c1e3ccSAndroid Build Coastguard Worker // scale = 2 * 2^SMOOTH_WEIGHT_LOG2_SCALE
92*77c1e3ccSAndroid Build Coastguard Worker const int log2_scale = 1 + SMOOTH_WEIGHT_LOG2_SCALE;
93*77c1e3ccSAndroid Build Coastguard Worker const uint16_t scale = (1 << SMOOTH_WEIGHT_LOG2_SCALE);
94*77c1e3ccSAndroid Build Coastguard Worker sm_weights_sanity_checks(sm_weights_w, sm_weights_h, scale,
95*77c1e3ccSAndroid Build Coastguard Worker log2_scale + sizeof(*dst));
96*77c1e3ccSAndroid Build Coastguard Worker int r;
97*77c1e3ccSAndroid Build Coastguard Worker for (r = 0; r < bh; ++r) {
98*77c1e3ccSAndroid Build Coastguard Worker int c;
99*77c1e3ccSAndroid Build Coastguard Worker for (c = 0; c < bw; ++c) {
100*77c1e3ccSAndroid Build Coastguard Worker const uint8_t pixels[] = { above[c], below_pred, left[r], right_pred };
101*77c1e3ccSAndroid Build Coastguard Worker const uint8_t weights[] = { sm_weights_h[r], scale - sm_weights_h[r],
102*77c1e3ccSAndroid Build Coastguard Worker sm_weights_w[c], scale - sm_weights_w[c] };
103*77c1e3ccSAndroid Build Coastguard Worker uint32_t this_pred = 0;
104*77c1e3ccSAndroid Build Coastguard Worker int i;
105*77c1e3ccSAndroid Build Coastguard Worker assert(scale >= sm_weights_h[r] && scale >= sm_weights_w[c]);
106*77c1e3ccSAndroid Build Coastguard Worker for (i = 0; i < 4; ++i) {
107*77c1e3ccSAndroid Build Coastguard Worker this_pred += weights[i] * pixels[i];
108*77c1e3ccSAndroid Build Coastguard Worker }
109*77c1e3ccSAndroid Build Coastguard Worker dst[c] = divide_round(this_pred, log2_scale);
110*77c1e3ccSAndroid Build Coastguard Worker }
111*77c1e3ccSAndroid Build Coastguard Worker dst += stride;
112*77c1e3ccSAndroid Build Coastguard Worker }
113*77c1e3ccSAndroid Build Coastguard Worker }
114*77c1e3ccSAndroid Build Coastguard Worker
smooth_v_predictor(uint8_t * dst,ptrdiff_t stride,int bw,int bh,const uint8_t * above,const uint8_t * left)115*77c1e3ccSAndroid Build Coastguard Worker static inline void smooth_v_predictor(uint8_t *dst, ptrdiff_t stride, int bw,
116*77c1e3ccSAndroid Build Coastguard Worker int bh, const uint8_t *above,
117*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left) {
118*77c1e3ccSAndroid Build Coastguard Worker const uint8_t below_pred = left[bh - 1]; // estimated by bottom-left pixel
119*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *const sm_weights = smooth_weights + bh - 4;
120*77c1e3ccSAndroid Build Coastguard Worker // scale = 2^SMOOTH_WEIGHT_LOG2_SCALE
121*77c1e3ccSAndroid Build Coastguard Worker const int log2_scale = SMOOTH_WEIGHT_LOG2_SCALE;
122*77c1e3ccSAndroid Build Coastguard Worker const uint16_t scale = (1 << SMOOTH_WEIGHT_LOG2_SCALE);
123*77c1e3ccSAndroid Build Coastguard Worker sm_weights_sanity_checks(sm_weights, sm_weights, scale,
124*77c1e3ccSAndroid Build Coastguard Worker log2_scale + sizeof(*dst));
125*77c1e3ccSAndroid Build Coastguard Worker
126*77c1e3ccSAndroid Build Coastguard Worker int r;
127*77c1e3ccSAndroid Build Coastguard Worker for (r = 0; r < bh; r++) {
128*77c1e3ccSAndroid Build Coastguard Worker int c;
129*77c1e3ccSAndroid Build Coastguard Worker for (c = 0; c < bw; ++c) {
130*77c1e3ccSAndroid Build Coastguard Worker const uint8_t pixels[] = { above[c], below_pred };
131*77c1e3ccSAndroid Build Coastguard Worker const uint8_t weights[] = { sm_weights[r], scale - sm_weights[r] };
132*77c1e3ccSAndroid Build Coastguard Worker uint32_t this_pred = 0;
133*77c1e3ccSAndroid Build Coastguard Worker assert(scale >= sm_weights[r]);
134*77c1e3ccSAndroid Build Coastguard Worker int i;
135*77c1e3ccSAndroid Build Coastguard Worker for (i = 0; i < 2; ++i) {
136*77c1e3ccSAndroid Build Coastguard Worker this_pred += weights[i] * pixels[i];
137*77c1e3ccSAndroid Build Coastguard Worker }
138*77c1e3ccSAndroid Build Coastguard Worker dst[c] = divide_round(this_pred, log2_scale);
139*77c1e3ccSAndroid Build Coastguard Worker }
140*77c1e3ccSAndroid Build Coastguard Worker dst += stride;
141*77c1e3ccSAndroid Build Coastguard Worker }
142*77c1e3ccSAndroid Build Coastguard Worker }
143*77c1e3ccSAndroid Build Coastguard Worker
smooth_h_predictor(uint8_t * dst,ptrdiff_t stride,int bw,int bh,const uint8_t * above,const uint8_t * left)144*77c1e3ccSAndroid Build Coastguard Worker static inline void smooth_h_predictor(uint8_t *dst, ptrdiff_t stride, int bw,
145*77c1e3ccSAndroid Build Coastguard Worker int bh, const uint8_t *above,
146*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left) {
147*77c1e3ccSAndroid Build Coastguard Worker const uint8_t right_pred = above[bw - 1]; // estimated by top-right pixel
148*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *const sm_weights = smooth_weights + bw - 4;
149*77c1e3ccSAndroid Build Coastguard Worker // scale = 2^SMOOTH_WEIGHT_LOG2_SCALE
150*77c1e3ccSAndroid Build Coastguard Worker const int log2_scale = SMOOTH_WEIGHT_LOG2_SCALE;
151*77c1e3ccSAndroid Build Coastguard Worker const uint16_t scale = (1 << SMOOTH_WEIGHT_LOG2_SCALE);
152*77c1e3ccSAndroid Build Coastguard Worker sm_weights_sanity_checks(sm_weights, sm_weights, scale,
153*77c1e3ccSAndroid Build Coastguard Worker log2_scale + sizeof(*dst));
154*77c1e3ccSAndroid Build Coastguard Worker
155*77c1e3ccSAndroid Build Coastguard Worker int r;
156*77c1e3ccSAndroid Build Coastguard Worker for (r = 0; r < bh; r++) {
157*77c1e3ccSAndroid Build Coastguard Worker int c;
158*77c1e3ccSAndroid Build Coastguard Worker for (c = 0; c < bw; ++c) {
159*77c1e3ccSAndroid Build Coastguard Worker const uint8_t pixels[] = { left[r], right_pred };
160*77c1e3ccSAndroid Build Coastguard Worker const uint8_t weights[] = { sm_weights[c], scale - sm_weights[c] };
161*77c1e3ccSAndroid Build Coastguard Worker uint32_t this_pred = 0;
162*77c1e3ccSAndroid Build Coastguard Worker assert(scale >= sm_weights[c]);
163*77c1e3ccSAndroid Build Coastguard Worker int i;
164*77c1e3ccSAndroid Build Coastguard Worker for (i = 0; i < 2; ++i) {
165*77c1e3ccSAndroid Build Coastguard Worker this_pred += weights[i] * pixels[i];
166*77c1e3ccSAndroid Build Coastguard Worker }
167*77c1e3ccSAndroid Build Coastguard Worker dst[c] = divide_round(this_pred, log2_scale);
168*77c1e3ccSAndroid Build Coastguard Worker }
169*77c1e3ccSAndroid Build Coastguard Worker dst += stride;
170*77c1e3ccSAndroid Build Coastguard Worker }
171*77c1e3ccSAndroid Build Coastguard Worker }
172*77c1e3ccSAndroid Build Coastguard Worker
dc_128_predictor(uint8_t * dst,ptrdiff_t stride,int bw,int bh,const uint8_t * above,const uint8_t * left)173*77c1e3ccSAndroid Build Coastguard Worker static inline void dc_128_predictor(uint8_t *dst, ptrdiff_t stride, int bw,
174*77c1e3ccSAndroid Build Coastguard Worker int bh, const uint8_t *above,
175*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left) {
176*77c1e3ccSAndroid Build Coastguard Worker int r;
177*77c1e3ccSAndroid Build Coastguard Worker (void)above;
178*77c1e3ccSAndroid Build Coastguard Worker (void)left;
179*77c1e3ccSAndroid Build Coastguard Worker
180*77c1e3ccSAndroid Build Coastguard Worker for (r = 0; r < bh; r++) {
181*77c1e3ccSAndroid Build Coastguard Worker memset(dst, 128, bw);
182*77c1e3ccSAndroid Build Coastguard Worker dst += stride;
183*77c1e3ccSAndroid Build Coastguard Worker }
184*77c1e3ccSAndroid Build Coastguard Worker }
185*77c1e3ccSAndroid Build Coastguard Worker
dc_left_predictor(uint8_t * dst,ptrdiff_t stride,int bw,int bh,const uint8_t * above,const uint8_t * left)186*77c1e3ccSAndroid Build Coastguard Worker static inline void dc_left_predictor(uint8_t *dst, ptrdiff_t stride, int bw,
187*77c1e3ccSAndroid Build Coastguard Worker int bh, const uint8_t *above,
188*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left) {
189*77c1e3ccSAndroid Build Coastguard Worker int i, r, expected_dc, sum = 0;
190*77c1e3ccSAndroid Build Coastguard Worker (void)above;
191*77c1e3ccSAndroid Build Coastguard Worker
192*77c1e3ccSAndroid Build Coastguard Worker for (i = 0; i < bh; i++) sum += left[i];
193*77c1e3ccSAndroid Build Coastguard Worker expected_dc = (sum + (bh >> 1)) / bh;
194*77c1e3ccSAndroid Build Coastguard Worker
195*77c1e3ccSAndroid Build Coastguard Worker for (r = 0; r < bh; r++) {
196*77c1e3ccSAndroid Build Coastguard Worker memset(dst, expected_dc, bw);
197*77c1e3ccSAndroid Build Coastguard Worker dst += stride;
198*77c1e3ccSAndroid Build Coastguard Worker }
199*77c1e3ccSAndroid Build Coastguard Worker }
200*77c1e3ccSAndroid Build Coastguard Worker
dc_top_predictor(uint8_t * dst,ptrdiff_t stride,int bw,int bh,const uint8_t * above,const uint8_t * left)201*77c1e3ccSAndroid Build Coastguard Worker static inline void dc_top_predictor(uint8_t *dst, ptrdiff_t stride, int bw,
202*77c1e3ccSAndroid Build Coastguard Worker int bh, const uint8_t *above,
203*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left) {
204*77c1e3ccSAndroid Build Coastguard Worker int i, r, expected_dc, sum = 0;
205*77c1e3ccSAndroid Build Coastguard Worker (void)left;
206*77c1e3ccSAndroid Build Coastguard Worker
207*77c1e3ccSAndroid Build Coastguard Worker for (i = 0; i < bw; i++) sum += above[i];
208*77c1e3ccSAndroid Build Coastguard Worker expected_dc = (sum + (bw >> 1)) / bw;
209*77c1e3ccSAndroid Build Coastguard Worker
210*77c1e3ccSAndroid Build Coastguard Worker for (r = 0; r < bh; r++) {
211*77c1e3ccSAndroid Build Coastguard Worker memset(dst, expected_dc, bw);
212*77c1e3ccSAndroid Build Coastguard Worker dst += stride;
213*77c1e3ccSAndroid Build Coastguard Worker }
214*77c1e3ccSAndroid Build Coastguard Worker }
215*77c1e3ccSAndroid Build Coastguard Worker
dc_predictor(uint8_t * dst,ptrdiff_t stride,int bw,int bh,const uint8_t * above,const uint8_t * left)216*77c1e3ccSAndroid Build Coastguard Worker static inline void dc_predictor(uint8_t *dst, ptrdiff_t stride, int bw, int bh,
217*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
218*77c1e3ccSAndroid Build Coastguard Worker int i, r, expected_dc, sum = 0;
219*77c1e3ccSAndroid Build Coastguard Worker const int count = bw + bh;
220*77c1e3ccSAndroid Build Coastguard Worker
221*77c1e3ccSAndroid Build Coastguard Worker for (i = 0; i < bw; i++) {
222*77c1e3ccSAndroid Build Coastguard Worker sum += above[i];
223*77c1e3ccSAndroid Build Coastguard Worker }
224*77c1e3ccSAndroid Build Coastguard Worker for (i = 0; i < bh; i++) {
225*77c1e3ccSAndroid Build Coastguard Worker sum += left[i];
226*77c1e3ccSAndroid Build Coastguard Worker }
227*77c1e3ccSAndroid Build Coastguard Worker
228*77c1e3ccSAndroid Build Coastguard Worker expected_dc = (sum + (count >> 1)) / count;
229*77c1e3ccSAndroid Build Coastguard Worker
230*77c1e3ccSAndroid Build Coastguard Worker for (r = 0; r < bh; r++) {
231*77c1e3ccSAndroid Build Coastguard Worker memset(dst, expected_dc, bw);
232*77c1e3ccSAndroid Build Coastguard Worker dst += stride;
233*77c1e3ccSAndroid Build Coastguard Worker }
234*77c1e3ccSAndroid Build Coastguard Worker }
235*77c1e3ccSAndroid Build Coastguard Worker
divide_using_multiply_shift(int num,int shift1,int multiplier,int shift2)236*77c1e3ccSAndroid Build Coastguard Worker static inline int divide_using_multiply_shift(int num, int shift1,
237*77c1e3ccSAndroid Build Coastguard Worker int multiplier, int shift2) {
238*77c1e3ccSAndroid Build Coastguard Worker const int interm = num >> shift1;
239*77c1e3ccSAndroid Build Coastguard Worker return interm * multiplier >> shift2;
240*77c1e3ccSAndroid Build Coastguard Worker }
241*77c1e3ccSAndroid Build Coastguard Worker
242*77c1e3ccSAndroid Build Coastguard Worker // The constants (multiplier and shifts) for a given block size are obtained
243*77c1e3ccSAndroid Build Coastguard Worker // as follows:
244*77c1e3ccSAndroid Build Coastguard Worker // - Let sum_w_h = block width + block height.
245*77c1e3ccSAndroid Build Coastguard Worker // - Shift 'sum_w_h' right until we reach an odd number. Let the number of
246*77c1e3ccSAndroid Build Coastguard Worker // shifts for that block size be called 'shift1' (see the parameter in
247*77c1e3ccSAndroid Build Coastguard Worker // dc_predictor_rect() function), and let the odd number be 'd'. [d has only 2
248*77c1e3ccSAndroid Build Coastguard Worker // possible values: d = 3 for a 1:2 rect block and d = 5 for a 1:4 rect
249*77c1e3ccSAndroid Build Coastguard Worker // block].
250*77c1e3ccSAndroid Build Coastguard Worker // - Find multipliers for (i) dividing by 3, and (ii) dividing by 5,
251*77c1e3ccSAndroid Build Coastguard Worker // using the "Algorithm 1" in:
252*77c1e3ccSAndroid Build Coastguard Worker // http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=1467632
253*77c1e3ccSAndroid Build Coastguard Worker // by ensuring that m + n = 16 (in that algorithm). This ensures that our 2nd
254*77c1e3ccSAndroid Build Coastguard Worker // shift will be 16, regardless of the block size.
255*77c1e3ccSAndroid Build Coastguard Worker
256*77c1e3ccSAndroid Build Coastguard Worker // Note: For low bitdepth, assembly code may be optimized by using smaller
257*77c1e3ccSAndroid Build Coastguard Worker // constants for smaller block sizes, where the range of the 'sum' is
258*77c1e3ccSAndroid Build Coastguard Worker // restricted to fewer bits.
259*77c1e3ccSAndroid Build Coastguard Worker
260*77c1e3ccSAndroid Build Coastguard Worker #define DC_MULTIPLIER_1X2 0x5556
261*77c1e3ccSAndroid Build Coastguard Worker #define DC_MULTIPLIER_1X4 0x3334
262*77c1e3ccSAndroid Build Coastguard Worker
263*77c1e3ccSAndroid Build Coastguard Worker #define DC_SHIFT2 16
264*77c1e3ccSAndroid Build Coastguard Worker
dc_predictor_rect(uint8_t * dst,ptrdiff_t stride,int bw,int bh,const uint8_t * above,const uint8_t * left,int shift1,int multiplier)265*77c1e3ccSAndroid Build Coastguard Worker static inline void dc_predictor_rect(uint8_t *dst, ptrdiff_t stride, int bw,
266*77c1e3ccSAndroid Build Coastguard Worker int bh, const uint8_t *above,
267*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left, int shift1,
268*77c1e3ccSAndroid Build Coastguard Worker int multiplier) {
269*77c1e3ccSAndroid Build Coastguard Worker int sum = 0;
270*77c1e3ccSAndroid Build Coastguard Worker
271*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < bw; i++) {
272*77c1e3ccSAndroid Build Coastguard Worker sum += above[i];
273*77c1e3ccSAndroid Build Coastguard Worker }
274*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < bh; i++) {
275*77c1e3ccSAndroid Build Coastguard Worker sum += left[i];
276*77c1e3ccSAndroid Build Coastguard Worker }
277*77c1e3ccSAndroid Build Coastguard Worker
278*77c1e3ccSAndroid Build Coastguard Worker const int expected_dc = divide_using_multiply_shift(
279*77c1e3ccSAndroid Build Coastguard Worker sum + ((bw + bh) >> 1), shift1, multiplier, DC_SHIFT2);
280*77c1e3ccSAndroid Build Coastguard Worker assert(expected_dc < (1 << 8));
281*77c1e3ccSAndroid Build Coastguard Worker
282*77c1e3ccSAndroid Build Coastguard Worker for (int r = 0; r < bh; r++) {
283*77c1e3ccSAndroid Build Coastguard Worker memset(dst, expected_dc, bw);
284*77c1e3ccSAndroid Build Coastguard Worker dst += stride;
285*77c1e3ccSAndroid Build Coastguard Worker }
286*77c1e3ccSAndroid Build Coastguard Worker }
287*77c1e3ccSAndroid Build Coastguard Worker
288*77c1e3ccSAndroid Build Coastguard Worker #undef DC_SHIFT2
289*77c1e3ccSAndroid Build Coastguard Worker
aom_dc_predictor_4x8_c(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)290*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_predictor_4x8_c(uint8_t *dst, ptrdiff_t stride,
291*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
292*77c1e3ccSAndroid Build Coastguard Worker dc_predictor_rect(dst, stride, 4, 8, above, left, 2, DC_MULTIPLIER_1X2);
293*77c1e3ccSAndroid Build Coastguard Worker }
294*77c1e3ccSAndroid Build Coastguard Worker
aom_dc_predictor_8x4_c(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)295*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_predictor_8x4_c(uint8_t *dst, ptrdiff_t stride,
296*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
297*77c1e3ccSAndroid Build Coastguard Worker dc_predictor_rect(dst, stride, 8, 4, above, left, 2, DC_MULTIPLIER_1X2);
298*77c1e3ccSAndroid Build Coastguard Worker }
299*77c1e3ccSAndroid Build Coastguard Worker
300*77c1e3ccSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
aom_dc_predictor_4x16_c(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)301*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_predictor_4x16_c(uint8_t *dst, ptrdiff_t stride,
302*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
303*77c1e3ccSAndroid Build Coastguard Worker dc_predictor_rect(dst, stride, 4, 16, above, left, 2, DC_MULTIPLIER_1X4);
304*77c1e3ccSAndroid Build Coastguard Worker }
305*77c1e3ccSAndroid Build Coastguard Worker
aom_dc_predictor_16x4_c(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)306*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_predictor_16x4_c(uint8_t *dst, ptrdiff_t stride,
307*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
308*77c1e3ccSAndroid Build Coastguard Worker dc_predictor_rect(dst, stride, 16, 4, above, left, 2, DC_MULTIPLIER_1X4);
309*77c1e3ccSAndroid Build Coastguard Worker }
310*77c1e3ccSAndroid Build Coastguard Worker #endif // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
311*77c1e3ccSAndroid Build Coastguard Worker
aom_dc_predictor_8x16_c(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)312*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_predictor_8x16_c(uint8_t *dst, ptrdiff_t stride,
313*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
314*77c1e3ccSAndroid Build Coastguard Worker dc_predictor_rect(dst, stride, 8, 16, above, left, 3, DC_MULTIPLIER_1X2);
315*77c1e3ccSAndroid Build Coastguard Worker }
316*77c1e3ccSAndroid Build Coastguard Worker
aom_dc_predictor_16x8_c(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)317*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_predictor_16x8_c(uint8_t *dst, ptrdiff_t stride,
318*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
319*77c1e3ccSAndroid Build Coastguard Worker dc_predictor_rect(dst, stride, 16, 8, above, left, 3, DC_MULTIPLIER_1X2);
320*77c1e3ccSAndroid Build Coastguard Worker }
321*77c1e3ccSAndroid Build Coastguard Worker
322*77c1e3ccSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
aom_dc_predictor_8x32_c(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)323*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_predictor_8x32_c(uint8_t *dst, ptrdiff_t stride,
324*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
325*77c1e3ccSAndroid Build Coastguard Worker dc_predictor_rect(dst, stride, 8, 32, above, left, 3, DC_MULTIPLIER_1X4);
326*77c1e3ccSAndroid Build Coastguard Worker }
327*77c1e3ccSAndroid Build Coastguard Worker
aom_dc_predictor_32x8_c(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)328*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_predictor_32x8_c(uint8_t *dst, ptrdiff_t stride,
329*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
330*77c1e3ccSAndroid Build Coastguard Worker dc_predictor_rect(dst, stride, 32, 8, above, left, 3, DC_MULTIPLIER_1X4);
331*77c1e3ccSAndroid Build Coastguard Worker }
332*77c1e3ccSAndroid Build Coastguard Worker #endif // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
333*77c1e3ccSAndroid Build Coastguard Worker
aom_dc_predictor_16x32_c(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)334*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_predictor_16x32_c(uint8_t *dst, ptrdiff_t stride,
335*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
336*77c1e3ccSAndroid Build Coastguard Worker dc_predictor_rect(dst, stride, 16, 32, above, left, 4, DC_MULTIPLIER_1X2);
337*77c1e3ccSAndroid Build Coastguard Worker }
338*77c1e3ccSAndroid Build Coastguard Worker
aom_dc_predictor_32x16_c(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)339*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_predictor_32x16_c(uint8_t *dst, ptrdiff_t stride,
340*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
341*77c1e3ccSAndroid Build Coastguard Worker dc_predictor_rect(dst, stride, 32, 16, above, left, 4, DC_MULTIPLIER_1X2);
342*77c1e3ccSAndroid Build Coastguard Worker }
343*77c1e3ccSAndroid Build Coastguard Worker
344*77c1e3ccSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
aom_dc_predictor_16x64_c(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)345*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_predictor_16x64_c(uint8_t *dst, ptrdiff_t stride,
346*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
347*77c1e3ccSAndroid Build Coastguard Worker dc_predictor_rect(dst, stride, 16, 64, above, left, 4, DC_MULTIPLIER_1X4);
348*77c1e3ccSAndroid Build Coastguard Worker }
349*77c1e3ccSAndroid Build Coastguard Worker
aom_dc_predictor_64x16_c(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)350*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_predictor_64x16_c(uint8_t *dst, ptrdiff_t stride,
351*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
352*77c1e3ccSAndroid Build Coastguard Worker dc_predictor_rect(dst, stride, 64, 16, above, left, 4, DC_MULTIPLIER_1X4);
353*77c1e3ccSAndroid Build Coastguard Worker }
354*77c1e3ccSAndroid Build Coastguard Worker #endif // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
355*77c1e3ccSAndroid Build Coastguard Worker
aom_dc_predictor_32x64_c(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)356*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_predictor_32x64_c(uint8_t *dst, ptrdiff_t stride,
357*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
358*77c1e3ccSAndroid Build Coastguard Worker dc_predictor_rect(dst, stride, 32, 64, above, left, 5, DC_MULTIPLIER_1X2);
359*77c1e3ccSAndroid Build Coastguard Worker }
360*77c1e3ccSAndroid Build Coastguard Worker
aom_dc_predictor_64x32_c(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)361*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_predictor_64x32_c(uint8_t *dst, ptrdiff_t stride,
362*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
363*77c1e3ccSAndroid Build Coastguard Worker dc_predictor_rect(dst, stride, 64, 32, above, left, 5, DC_MULTIPLIER_1X2);
364*77c1e3ccSAndroid Build Coastguard Worker }
365*77c1e3ccSAndroid Build Coastguard Worker
366*77c1e3ccSAndroid Build Coastguard Worker #undef DC_MULTIPLIER_1X2
367*77c1e3ccSAndroid Build Coastguard Worker #undef DC_MULTIPLIER_1X4
368*77c1e3ccSAndroid Build Coastguard Worker
369*77c1e3ccSAndroid Build Coastguard Worker #if CONFIG_AV1_HIGHBITDEPTH
370*77c1e3ccSAndroid Build Coastguard Worker
highbd_v_predictor(uint16_t * dst,ptrdiff_t stride,int bw,int bh,const uint16_t * above,const uint16_t * left,int bd)371*77c1e3ccSAndroid Build Coastguard Worker static inline void highbd_v_predictor(uint16_t *dst, ptrdiff_t stride, int bw,
372*77c1e3ccSAndroid Build Coastguard Worker int bh, const uint16_t *above,
373*77c1e3ccSAndroid Build Coastguard Worker const uint16_t *left, int bd) {
374*77c1e3ccSAndroid Build Coastguard Worker int r;
375*77c1e3ccSAndroid Build Coastguard Worker (void)left;
376*77c1e3ccSAndroid Build Coastguard Worker (void)bd;
377*77c1e3ccSAndroid Build Coastguard Worker for (r = 0; r < bh; r++) {
378*77c1e3ccSAndroid Build Coastguard Worker memcpy(dst, above, bw * sizeof(uint16_t));
379*77c1e3ccSAndroid Build Coastguard Worker dst += stride;
380*77c1e3ccSAndroid Build Coastguard Worker }
381*77c1e3ccSAndroid Build Coastguard Worker }
382*77c1e3ccSAndroid Build Coastguard Worker
highbd_h_predictor(uint16_t * dst,ptrdiff_t stride,int bw,int bh,const uint16_t * above,const uint16_t * left,int bd)383*77c1e3ccSAndroid Build Coastguard Worker static inline void highbd_h_predictor(uint16_t *dst, ptrdiff_t stride, int bw,
384*77c1e3ccSAndroid Build Coastguard Worker int bh, const uint16_t *above,
385*77c1e3ccSAndroid Build Coastguard Worker const uint16_t *left, int bd) {
386*77c1e3ccSAndroid Build Coastguard Worker int r;
387*77c1e3ccSAndroid Build Coastguard Worker (void)above;
388*77c1e3ccSAndroid Build Coastguard Worker (void)bd;
389*77c1e3ccSAndroid Build Coastguard Worker for (r = 0; r < bh; r++) {
390*77c1e3ccSAndroid Build Coastguard Worker aom_memset16(dst, left[r], bw);
391*77c1e3ccSAndroid Build Coastguard Worker dst += stride;
392*77c1e3ccSAndroid Build Coastguard Worker }
393*77c1e3ccSAndroid Build Coastguard Worker }
394*77c1e3ccSAndroid Build Coastguard Worker
highbd_paeth_predictor(uint16_t * dst,ptrdiff_t stride,int bw,int bh,const uint16_t * above,const uint16_t * left,int bd)395*77c1e3ccSAndroid Build Coastguard Worker static inline void highbd_paeth_predictor(uint16_t *dst, ptrdiff_t stride,
396*77c1e3ccSAndroid Build Coastguard Worker int bw, int bh, const uint16_t *above,
397*77c1e3ccSAndroid Build Coastguard Worker const uint16_t *left, int bd) {
398*77c1e3ccSAndroid Build Coastguard Worker int r, c;
399*77c1e3ccSAndroid Build Coastguard Worker const uint16_t ytop_left = above[-1];
400*77c1e3ccSAndroid Build Coastguard Worker (void)bd;
401*77c1e3ccSAndroid Build Coastguard Worker
402*77c1e3ccSAndroid Build Coastguard Worker for (r = 0; r < bh; r++) {
403*77c1e3ccSAndroid Build Coastguard Worker for (c = 0; c < bw; c++)
404*77c1e3ccSAndroid Build Coastguard Worker dst[c] = paeth_predictor_single(left[r], above[c], ytop_left);
405*77c1e3ccSAndroid Build Coastguard Worker dst += stride;
406*77c1e3ccSAndroid Build Coastguard Worker }
407*77c1e3ccSAndroid Build Coastguard Worker }
408*77c1e3ccSAndroid Build Coastguard Worker
highbd_smooth_predictor(uint16_t * dst,ptrdiff_t stride,int bw,int bh,const uint16_t * above,const uint16_t * left,int bd)409*77c1e3ccSAndroid Build Coastguard Worker static inline void highbd_smooth_predictor(uint16_t *dst, ptrdiff_t stride,
410*77c1e3ccSAndroid Build Coastguard Worker int bw, int bh,
411*77c1e3ccSAndroid Build Coastguard Worker const uint16_t *above,
412*77c1e3ccSAndroid Build Coastguard Worker const uint16_t *left, int bd) {
413*77c1e3ccSAndroid Build Coastguard Worker (void)bd;
414*77c1e3ccSAndroid Build Coastguard Worker const uint16_t below_pred = left[bh - 1]; // estimated by bottom-left pixel
415*77c1e3ccSAndroid Build Coastguard Worker const uint16_t right_pred = above[bw - 1]; // estimated by top-right pixel
416*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *const sm_weights_w = smooth_weights + bw - 4;
417*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *const sm_weights_h = smooth_weights + bh - 4;
418*77c1e3ccSAndroid Build Coastguard Worker // scale = 2 * 2^SMOOTH_WEIGHT_LOG2_SCALE
419*77c1e3ccSAndroid Build Coastguard Worker const int log2_scale = 1 + SMOOTH_WEIGHT_LOG2_SCALE;
420*77c1e3ccSAndroid Build Coastguard Worker const uint16_t scale = (1 << SMOOTH_WEIGHT_LOG2_SCALE);
421*77c1e3ccSAndroid Build Coastguard Worker sm_weights_sanity_checks(sm_weights_w, sm_weights_h, scale,
422*77c1e3ccSAndroid Build Coastguard Worker log2_scale + sizeof(*dst));
423*77c1e3ccSAndroid Build Coastguard Worker int r;
424*77c1e3ccSAndroid Build Coastguard Worker for (r = 0; r < bh; ++r) {
425*77c1e3ccSAndroid Build Coastguard Worker int c;
426*77c1e3ccSAndroid Build Coastguard Worker for (c = 0; c < bw; ++c) {
427*77c1e3ccSAndroid Build Coastguard Worker const uint16_t pixels[] = { above[c], below_pred, left[r], right_pred };
428*77c1e3ccSAndroid Build Coastguard Worker const uint8_t weights[] = { sm_weights_h[r], scale - sm_weights_h[r],
429*77c1e3ccSAndroid Build Coastguard Worker sm_weights_w[c], scale - sm_weights_w[c] };
430*77c1e3ccSAndroid Build Coastguard Worker uint32_t this_pred = 0;
431*77c1e3ccSAndroid Build Coastguard Worker int i;
432*77c1e3ccSAndroid Build Coastguard Worker assert(scale >= sm_weights_h[r] && scale >= sm_weights_w[c]);
433*77c1e3ccSAndroid Build Coastguard Worker for (i = 0; i < 4; ++i) {
434*77c1e3ccSAndroid Build Coastguard Worker this_pred += weights[i] * pixels[i];
435*77c1e3ccSAndroid Build Coastguard Worker }
436*77c1e3ccSAndroid Build Coastguard Worker dst[c] = divide_round(this_pred, log2_scale);
437*77c1e3ccSAndroid Build Coastguard Worker }
438*77c1e3ccSAndroid Build Coastguard Worker dst += stride;
439*77c1e3ccSAndroid Build Coastguard Worker }
440*77c1e3ccSAndroid Build Coastguard Worker }
441*77c1e3ccSAndroid Build Coastguard Worker
highbd_smooth_v_predictor(uint16_t * dst,ptrdiff_t stride,int bw,int bh,const uint16_t * above,const uint16_t * left,int bd)442*77c1e3ccSAndroid Build Coastguard Worker static inline void highbd_smooth_v_predictor(uint16_t *dst, ptrdiff_t stride,
443*77c1e3ccSAndroid Build Coastguard Worker int bw, int bh,
444*77c1e3ccSAndroid Build Coastguard Worker const uint16_t *above,
445*77c1e3ccSAndroid Build Coastguard Worker const uint16_t *left, int bd) {
446*77c1e3ccSAndroid Build Coastguard Worker (void)bd;
447*77c1e3ccSAndroid Build Coastguard Worker const uint16_t below_pred = left[bh - 1]; // estimated by bottom-left pixel
448*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *const sm_weights = smooth_weights + bh - 4;
449*77c1e3ccSAndroid Build Coastguard Worker // scale = 2^SMOOTH_WEIGHT_LOG2_SCALE
450*77c1e3ccSAndroid Build Coastguard Worker const int log2_scale = SMOOTH_WEIGHT_LOG2_SCALE;
451*77c1e3ccSAndroid Build Coastguard Worker const uint16_t scale = (1 << SMOOTH_WEIGHT_LOG2_SCALE);
452*77c1e3ccSAndroid Build Coastguard Worker sm_weights_sanity_checks(sm_weights, sm_weights, scale,
453*77c1e3ccSAndroid Build Coastguard Worker log2_scale + sizeof(*dst));
454*77c1e3ccSAndroid Build Coastguard Worker
455*77c1e3ccSAndroid Build Coastguard Worker int r;
456*77c1e3ccSAndroid Build Coastguard Worker for (r = 0; r < bh; r++) {
457*77c1e3ccSAndroid Build Coastguard Worker int c;
458*77c1e3ccSAndroid Build Coastguard Worker for (c = 0; c < bw; ++c) {
459*77c1e3ccSAndroid Build Coastguard Worker const uint16_t pixels[] = { above[c], below_pred };
460*77c1e3ccSAndroid Build Coastguard Worker const uint8_t weights[] = { sm_weights[r], scale - sm_weights[r] };
461*77c1e3ccSAndroid Build Coastguard Worker uint32_t this_pred = 0;
462*77c1e3ccSAndroid Build Coastguard Worker assert(scale >= sm_weights[r]);
463*77c1e3ccSAndroid Build Coastguard Worker int i;
464*77c1e3ccSAndroid Build Coastguard Worker for (i = 0; i < 2; ++i) {
465*77c1e3ccSAndroid Build Coastguard Worker this_pred += weights[i] * pixels[i];
466*77c1e3ccSAndroid Build Coastguard Worker }
467*77c1e3ccSAndroid Build Coastguard Worker dst[c] = divide_round(this_pred, log2_scale);
468*77c1e3ccSAndroid Build Coastguard Worker }
469*77c1e3ccSAndroid Build Coastguard Worker dst += stride;
470*77c1e3ccSAndroid Build Coastguard Worker }
471*77c1e3ccSAndroid Build Coastguard Worker }
472*77c1e3ccSAndroid Build Coastguard Worker
highbd_smooth_h_predictor(uint16_t * dst,ptrdiff_t stride,int bw,int bh,const uint16_t * above,const uint16_t * left,int bd)473*77c1e3ccSAndroid Build Coastguard Worker static inline void highbd_smooth_h_predictor(uint16_t *dst, ptrdiff_t stride,
474*77c1e3ccSAndroid Build Coastguard Worker int bw, int bh,
475*77c1e3ccSAndroid Build Coastguard Worker const uint16_t *above,
476*77c1e3ccSAndroid Build Coastguard Worker const uint16_t *left, int bd) {
477*77c1e3ccSAndroid Build Coastguard Worker (void)bd;
478*77c1e3ccSAndroid Build Coastguard Worker const uint16_t right_pred = above[bw - 1]; // estimated by top-right pixel
479*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *const sm_weights = smooth_weights + bw - 4;
480*77c1e3ccSAndroid Build Coastguard Worker // scale = 2^SMOOTH_WEIGHT_LOG2_SCALE
481*77c1e3ccSAndroid Build Coastguard Worker const int log2_scale = SMOOTH_WEIGHT_LOG2_SCALE;
482*77c1e3ccSAndroid Build Coastguard Worker const uint16_t scale = (1 << SMOOTH_WEIGHT_LOG2_SCALE);
483*77c1e3ccSAndroid Build Coastguard Worker sm_weights_sanity_checks(sm_weights, sm_weights, scale,
484*77c1e3ccSAndroid Build Coastguard Worker log2_scale + sizeof(*dst));
485*77c1e3ccSAndroid Build Coastguard Worker
486*77c1e3ccSAndroid Build Coastguard Worker int r;
487*77c1e3ccSAndroid Build Coastguard Worker for (r = 0; r < bh; r++) {
488*77c1e3ccSAndroid Build Coastguard Worker int c;
489*77c1e3ccSAndroid Build Coastguard Worker for (c = 0; c < bw; ++c) {
490*77c1e3ccSAndroid Build Coastguard Worker const uint16_t pixels[] = { left[r], right_pred };
491*77c1e3ccSAndroid Build Coastguard Worker const uint8_t weights[] = { sm_weights[c], scale - sm_weights[c] };
492*77c1e3ccSAndroid Build Coastguard Worker uint32_t this_pred = 0;
493*77c1e3ccSAndroid Build Coastguard Worker assert(scale >= sm_weights[c]);
494*77c1e3ccSAndroid Build Coastguard Worker int i;
495*77c1e3ccSAndroid Build Coastguard Worker for (i = 0; i < 2; ++i) {
496*77c1e3ccSAndroid Build Coastguard Worker this_pred += weights[i] * pixels[i];
497*77c1e3ccSAndroid Build Coastguard Worker }
498*77c1e3ccSAndroid Build Coastguard Worker dst[c] = divide_round(this_pred, log2_scale);
499*77c1e3ccSAndroid Build Coastguard Worker }
500*77c1e3ccSAndroid Build Coastguard Worker dst += stride;
501*77c1e3ccSAndroid Build Coastguard Worker }
502*77c1e3ccSAndroid Build Coastguard Worker }
503*77c1e3ccSAndroid Build Coastguard Worker
highbd_dc_128_predictor(uint16_t * dst,ptrdiff_t stride,int bw,int bh,const uint16_t * above,const uint16_t * left,int bd)504*77c1e3ccSAndroid Build Coastguard Worker static inline void highbd_dc_128_predictor(uint16_t *dst, ptrdiff_t stride,
505*77c1e3ccSAndroid Build Coastguard Worker int bw, int bh,
506*77c1e3ccSAndroid Build Coastguard Worker const uint16_t *above,
507*77c1e3ccSAndroid Build Coastguard Worker const uint16_t *left, int bd) {
508*77c1e3ccSAndroid Build Coastguard Worker int r;
509*77c1e3ccSAndroid Build Coastguard Worker (void)above;
510*77c1e3ccSAndroid Build Coastguard Worker (void)left;
511*77c1e3ccSAndroid Build Coastguard Worker
512*77c1e3ccSAndroid Build Coastguard Worker for (r = 0; r < bh; r++) {
513*77c1e3ccSAndroid Build Coastguard Worker aom_memset16(dst, 128 << (bd - 8), bw);
514*77c1e3ccSAndroid Build Coastguard Worker dst += stride;
515*77c1e3ccSAndroid Build Coastguard Worker }
516*77c1e3ccSAndroid Build Coastguard Worker }
517*77c1e3ccSAndroid Build Coastguard Worker
highbd_dc_left_predictor(uint16_t * dst,ptrdiff_t stride,int bw,int bh,const uint16_t * above,const uint16_t * left,int bd)518*77c1e3ccSAndroid Build Coastguard Worker static inline void highbd_dc_left_predictor(uint16_t *dst, ptrdiff_t stride,
519*77c1e3ccSAndroid Build Coastguard Worker int bw, int bh,
520*77c1e3ccSAndroid Build Coastguard Worker const uint16_t *above,
521*77c1e3ccSAndroid Build Coastguard Worker const uint16_t *left, int bd) {
522*77c1e3ccSAndroid Build Coastguard Worker int i, r, expected_dc, sum = 0;
523*77c1e3ccSAndroid Build Coastguard Worker (void)above;
524*77c1e3ccSAndroid Build Coastguard Worker (void)bd;
525*77c1e3ccSAndroid Build Coastguard Worker
526*77c1e3ccSAndroid Build Coastguard Worker for (i = 0; i < bh; i++) sum += left[i];
527*77c1e3ccSAndroid Build Coastguard Worker expected_dc = (sum + (bh >> 1)) / bh;
528*77c1e3ccSAndroid Build Coastguard Worker
529*77c1e3ccSAndroid Build Coastguard Worker for (r = 0; r < bh; r++) {
530*77c1e3ccSAndroid Build Coastguard Worker aom_memset16(dst, expected_dc, bw);
531*77c1e3ccSAndroid Build Coastguard Worker dst += stride;
532*77c1e3ccSAndroid Build Coastguard Worker }
533*77c1e3ccSAndroid Build Coastguard Worker }
534*77c1e3ccSAndroid Build Coastguard Worker
highbd_dc_top_predictor(uint16_t * dst,ptrdiff_t stride,int bw,int bh,const uint16_t * above,const uint16_t * left,int bd)535*77c1e3ccSAndroid Build Coastguard Worker static inline void highbd_dc_top_predictor(uint16_t *dst, ptrdiff_t stride,
536*77c1e3ccSAndroid Build Coastguard Worker int bw, int bh,
537*77c1e3ccSAndroid Build Coastguard Worker const uint16_t *above,
538*77c1e3ccSAndroid Build Coastguard Worker const uint16_t *left, int bd) {
539*77c1e3ccSAndroid Build Coastguard Worker int i, r, expected_dc, sum = 0;
540*77c1e3ccSAndroid Build Coastguard Worker (void)left;
541*77c1e3ccSAndroid Build Coastguard Worker (void)bd;
542*77c1e3ccSAndroid Build Coastguard Worker
543*77c1e3ccSAndroid Build Coastguard Worker for (i = 0; i < bw; i++) sum += above[i];
544*77c1e3ccSAndroid Build Coastguard Worker expected_dc = (sum + (bw >> 1)) / bw;
545*77c1e3ccSAndroid Build Coastguard Worker
546*77c1e3ccSAndroid Build Coastguard Worker for (r = 0; r < bh; r++) {
547*77c1e3ccSAndroid Build Coastguard Worker aom_memset16(dst, expected_dc, bw);
548*77c1e3ccSAndroid Build Coastguard Worker dst += stride;
549*77c1e3ccSAndroid Build Coastguard Worker }
550*77c1e3ccSAndroid Build Coastguard Worker }
551*77c1e3ccSAndroid Build Coastguard Worker
highbd_dc_predictor(uint16_t * dst,ptrdiff_t stride,int bw,int bh,const uint16_t * above,const uint16_t * left,int bd)552*77c1e3ccSAndroid Build Coastguard Worker static inline void highbd_dc_predictor(uint16_t *dst, ptrdiff_t stride, int bw,
553*77c1e3ccSAndroid Build Coastguard Worker int bh, const uint16_t *above,
554*77c1e3ccSAndroid Build Coastguard Worker const uint16_t *left, int bd) {
555*77c1e3ccSAndroid Build Coastguard Worker int i, r, expected_dc, sum = 0;
556*77c1e3ccSAndroid Build Coastguard Worker const int count = bw + bh;
557*77c1e3ccSAndroid Build Coastguard Worker (void)bd;
558*77c1e3ccSAndroid Build Coastguard Worker
559*77c1e3ccSAndroid Build Coastguard Worker for (i = 0; i < bw; i++) {
560*77c1e3ccSAndroid Build Coastguard Worker sum += above[i];
561*77c1e3ccSAndroid Build Coastguard Worker }
562*77c1e3ccSAndroid Build Coastguard Worker for (i = 0; i < bh; i++) {
563*77c1e3ccSAndroid Build Coastguard Worker sum += left[i];
564*77c1e3ccSAndroid Build Coastguard Worker }
565*77c1e3ccSAndroid Build Coastguard Worker
566*77c1e3ccSAndroid Build Coastguard Worker expected_dc = (sum + (count >> 1)) / count;
567*77c1e3ccSAndroid Build Coastguard Worker
568*77c1e3ccSAndroid Build Coastguard Worker for (r = 0; r < bh; r++) {
569*77c1e3ccSAndroid Build Coastguard Worker aom_memset16(dst, expected_dc, bw);
570*77c1e3ccSAndroid Build Coastguard Worker dst += stride;
571*77c1e3ccSAndroid Build Coastguard Worker }
572*77c1e3ccSAndroid Build Coastguard Worker }
573*77c1e3ccSAndroid Build Coastguard Worker
574*77c1e3ccSAndroid Build Coastguard Worker // Obtained similarly as DC_MULTIPLIER_1X2 and DC_MULTIPLIER_1X4 above, but
575*77c1e3ccSAndroid Build Coastguard Worker // assume 2nd shift of 17 bits instead of 16.
576*77c1e3ccSAndroid Build Coastguard Worker // Note: Strictly speaking, 2nd shift needs to be 17 only when:
577*77c1e3ccSAndroid Build Coastguard Worker // - bit depth == 12, and
578*77c1e3ccSAndroid Build Coastguard Worker // - bw + bh is divisible by 5 (as opposed to divisible by 3).
579*77c1e3ccSAndroid Build Coastguard Worker // All other cases can use half the multipliers with a shift of 16 instead.
580*77c1e3ccSAndroid Build Coastguard Worker // This special optimization can be used when writing assembly code.
581*77c1e3ccSAndroid Build Coastguard Worker #define HIGHBD_DC_MULTIPLIER_1X2 0xAAAB
582*77c1e3ccSAndroid Build Coastguard Worker // Note: This constant is odd, but a smaller even constant (0x199a) with the
583*77c1e3ccSAndroid Build Coastguard Worker // appropriate shift should work for neon in 8/10-bit.
584*77c1e3ccSAndroid Build Coastguard Worker #define HIGHBD_DC_MULTIPLIER_1X4 0x6667
585*77c1e3ccSAndroid Build Coastguard Worker
586*77c1e3ccSAndroid Build Coastguard Worker #define HIGHBD_DC_SHIFT2 17
587*77c1e3ccSAndroid Build Coastguard Worker
highbd_dc_predictor_rect(uint16_t * dst,ptrdiff_t stride,int bw,int bh,const uint16_t * above,const uint16_t * left,int bd,int shift1,uint32_t multiplier)588*77c1e3ccSAndroid Build Coastguard Worker static inline void highbd_dc_predictor_rect(uint16_t *dst, ptrdiff_t stride,
589*77c1e3ccSAndroid Build Coastguard Worker int bw, int bh,
590*77c1e3ccSAndroid Build Coastguard Worker const uint16_t *above,
591*77c1e3ccSAndroid Build Coastguard Worker const uint16_t *left, int bd,
592*77c1e3ccSAndroid Build Coastguard Worker int shift1, uint32_t multiplier) {
593*77c1e3ccSAndroid Build Coastguard Worker int sum = 0;
594*77c1e3ccSAndroid Build Coastguard Worker (void)bd;
595*77c1e3ccSAndroid Build Coastguard Worker
596*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < bw; i++) {
597*77c1e3ccSAndroid Build Coastguard Worker sum += above[i];
598*77c1e3ccSAndroid Build Coastguard Worker }
599*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < bh; i++) {
600*77c1e3ccSAndroid Build Coastguard Worker sum += left[i];
601*77c1e3ccSAndroid Build Coastguard Worker }
602*77c1e3ccSAndroid Build Coastguard Worker
603*77c1e3ccSAndroid Build Coastguard Worker const int expected_dc = divide_using_multiply_shift(
604*77c1e3ccSAndroid Build Coastguard Worker sum + ((bw + bh) >> 1), shift1, multiplier, HIGHBD_DC_SHIFT2);
605*77c1e3ccSAndroid Build Coastguard Worker assert(expected_dc < (1 << bd));
606*77c1e3ccSAndroid Build Coastguard Worker
607*77c1e3ccSAndroid Build Coastguard Worker for (int r = 0; r < bh; r++) {
608*77c1e3ccSAndroid Build Coastguard Worker aom_memset16(dst, expected_dc, bw);
609*77c1e3ccSAndroid Build Coastguard Worker dst += stride;
610*77c1e3ccSAndroid Build Coastguard Worker }
611*77c1e3ccSAndroid Build Coastguard Worker }
612*77c1e3ccSAndroid Build Coastguard Worker
613*77c1e3ccSAndroid Build Coastguard Worker #undef HIGHBD_DC_SHIFT2
614*77c1e3ccSAndroid Build Coastguard Worker
aom_highbd_dc_predictor_4x8_c(uint16_t * dst,ptrdiff_t stride,const uint16_t * above,const uint16_t * left,int bd)615*77c1e3ccSAndroid Build Coastguard Worker void aom_highbd_dc_predictor_4x8_c(uint16_t *dst, ptrdiff_t stride,
616*77c1e3ccSAndroid Build Coastguard Worker const uint16_t *above, const uint16_t *left,
617*77c1e3ccSAndroid Build Coastguard Worker int bd) {
618*77c1e3ccSAndroid Build Coastguard Worker highbd_dc_predictor_rect(dst, stride, 4, 8, above, left, bd, 2,
619*77c1e3ccSAndroid Build Coastguard Worker HIGHBD_DC_MULTIPLIER_1X2);
620*77c1e3ccSAndroid Build Coastguard Worker }
621*77c1e3ccSAndroid Build Coastguard Worker
aom_highbd_dc_predictor_8x4_c(uint16_t * dst,ptrdiff_t stride,const uint16_t * above,const uint16_t * left,int bd)622*77c1e3ccSAndroid Build Coastguard Worker void aom_highbd_dc_predictor_8x4_c(uint16_t *dst, ptrdiff_t stride,
623*77c1e3ccSAndroid Build Coastguard Worker const uint16_t *above, const uint16_t *left,
624*77c1e3ccSAndroid Build Coastguard Worker int bd) {
625*77c1e3ccSAndroid Build Coastguard Worker highbd_dc_predictor_rect(dst, stride, 8, 4, above, left, bd, 2,
626*77c1e3ccSAndroid Build Coastguard Worker HIGHBD_DC_MULTIPLIER_1X2);
627*77c1e3ccSAndroid Build Coastguard Worker }
628*77c1e3ccSAndroid Build Coastguard Worker
629*77c1e3ccSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
aom_highbd_dc_predictor_4x16_c(uint16_t * dst,ptrdiff_t stride,const uint16_t * above,const uint16_t * left,int bd)630*77c1e3ccSAndroid Build Coastguard Worker void aom_highbd_dc_predictor_4x16_c(uint16_t *dst, ptrdiff_t stride,
631*77c1e3ccSAndroid Build Coastguard Worker const uint16_t *above, const uint16_t *left,
632*77c1e3ccSAndroid Build Coastguard Worker int bd) {
633*77c1e3ccSAndroid Build Coastguard Worker highbd_dc_predictor_rect(dst, stride, 4, 16, above, left, bd, 2,
634*77c1e3ccSAndroid Build Coastguard Worker HIGHBD_DC_MULTIPLIER_1X4);
635*77c1e3ccSAndroid Build Coastguard Worker }
636*77c1e3ccSAndroid Build Coastguard Worker
aom_highbd_dc_predictor_16x4_c(uint16_t * dst,ptrdiff_t stride,const uint16_t * above,const uint16_t * left,int bd)637*77c1e3ccSAndroid Build Coastguard Worker void aom_highbd_dc_predictor_16x4_c(uint16_t *dst, ptrdiff_t stride,
638*77c1e3ccSAndroid Build Coastguard Worker const uint16_t *above, const uint16_t *left,
639*77c1e3ccSAndroid Build Coastguard Worker int bd) {
640*77c1e3ccSAndroid Build Coastguard Worker highbd_dc_predictor_rect(dst, stride, 16, 4, above, left, bd, 2,
641*77c1e3ccSAndroid Build Coastguard Worker HIGHBD_DC_MULTIPLIER_1X4);
642*77c1e3ccSAndroid Build Coastguard Worker }
643*77c1e3ccSAndroid Build Coastguard Worker #endif // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
644*77c1e3ccSAndroid Build Coastguard Worker
aom_highbd_dc_predictor_8x16_c(uint16_t * dst,ptrdiff_t stride,const uint16_t * above,const uint16_t * left,int bd)645*77c1e3ccSAndroid Build Coastguard Worker void aom_highbd_dc_predictor_8x16_c(uint16_t *dst, ptrdiff_t stride,
646*77c1e3ccSAndroid Build Coastguard Worker const uint16_t *above, const uint16_t *left,
647*77c1e3ccSAndroid Build Coastguard Worker int bd) {
648*77c1e3ccSAndroid Build Coastguard Worker highbd_dc_predictor_rect(dst, stride, 8, 16, above, left, bd, 3,
649*77c1e3ccSAndroid Build Coastguard Worker HIGHBD_DC_MULTIPLIER_1X2);
650*77c1e3ccSAndroid Build Coastguard Worker }
651*77c1e3ccSAndroid Build Coastguard Worker
aom_highbd_dc_predictor_16x8_c(uint16_t * dst,ptrdiff_t stride,const uint16_t * above,const uint16_t * left,int bd)652*77c1e3ccSAndroid Build Coastguard Worker void aom_highbd_dc_predictor_16x8_c(uint16_t *dst, ptrdiff_t stride,
653*77c1e3ccSAndroid Build Coastguard Worker const uint16_t *above, const uint16_t *left,
654*77c1e3ccSAndroid Build Coastguard Worker int bd) {
655*77c1e3ccSAndroid Build Coastguard Worker highbd_dc_predictor_rect(dst, stride, 16, 8, above, left, bd, 3,
656*77c1e3ccSAndroid Build Coastguard Worker HIGHBD_DC_MULTIPLIER_1X2);
657*77c1e3ccSAndroid Build Coastguard Worker }
658*77c1e3ccSAndroid Build Coastguard Worker
659*77c1e3ccSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
aom_highbd_dc_predictor_8x32_c(uint16_t * dst,ptrdiff_t stride,const uint16_t * above,const uint16_t * left,int bd)660*77c1e3ccSAndroid Build Coastguard Worker void aom_highbd_dc_predictor_8x32_c(uint16_t *dst, ptrdiff_t stride,
661*77c1e3ccSAndroid Build Coastguard Worker const uint16_t *above, const uint16_t *left,
662*77c1e3ccSAndroid Build Coastguard Worker int bd) {
663*77c1e3ccSAndroid Build Coastguard Worker highbd_dc_predictor_rect(dst, stride, 8, 32, above, left, bd, 3,
664*77c1e3ccSAndroid Build Coastguard Worker HIGHBD_DC_MULTIPLIER_1X4);
665*77c1e3ccSAndroid Build Coastguard Worker }
666*77c1e3ccSAndroid Build Coastguard Worker
aom_highbd_dc_predictor_32x8_c(uint16_t * dst,ptrdiff_t stride,const uint16_t * above,const uint16_t * left,int bd)667*77c1e3ccSAndroid Build Coastguard Worker void aom_highbd_dc_predictor_32x8_c(uint16_t *dst, ptrdiff_t stride,
668*77c1e3ccSAndroid Build Coastguard Worker const uint16_t *above, const uint16_t *left,
669*77c1e3ccSAndroid Build Coastguard Worker int bd) {
670*77c1e3ccSAndroid Build Coastguard Worker highbd_dc_predictor_rect(dst, stride, 32, 8, above, left, bd, 3,
671*77c1e3ccSAndroid Build Coastguard Worker HIGHBD_DC_MULTIPLIER_1X4);
672*77c1e3ccSAndroid Build Coastguard Worker }
673*77c1e3ccSAndroid Build Coastguard Worker #endif // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
674*77c1e3ccSAndroid Build Coastguard Worker
aom_highbd_dc_predictor_16x32_c(uint16_t * dst,ptrdiff_t stride,const uint16_t * above,const uint16_t * left,int bd)675*77c1e3ccSAndroid Build Coastguard Worker void aom_highbd_dc_predictor_16x32_c(uint16_t *dst, ptrdiff_t stride,
676*77c1e3ccSAndroid Build Coastguard Worker const uint16_t *above,
677*77c1e3ccSAndroid Build Coastguard Worker const uint16_t *left, int bd) {
678*77c1e3ccSAndroid Build Coastguard Worker highbd_dc_predictor_rect(dst, stride, 16, 32, above, left, bd, 4,
679*77c1e3ccSAndroid Build Coastguard Worker HIGHBD_DC_MULTIPLIER_1X2);
680*77c1e3ccSAndroid Build Coastguard Worker }
681*77c1e3ccSAndroid Build Coastguard Worker
aom_highbd_dc_predictor_32x16_c(uint16_t * dst,ptrdiff_t stride,const uint16_t * above,const uint16_t * left,int bd)682*77c1e3ccSAndroid Build Coastguard Worker void aom_highbd_dc_predictor_32x16_c(uint16_t *dst, ptrdiff_t stride,
683*77c1e3ccSAndroid Build Coastguard Worker const uint16_t *above,
684*77c1e3ccSAndroid Build Coastguard Worker const uint16_t *left, int bd) {
685*77c1e3ccSAndroid Build Coastguard Worker highbd_dc_predictor_rect(dst, stride, 32, 16, above, left, bd, 4,
686*77c1e3ccSAndroid Build Coastguard Worker HIGHBD_DC_MULTIPLIER_1X2);
687*77c1e3ccSAndroid Build Coastguard Worker }
688*77c1e3ccSAndroid Build Coastguard Worker
689*77c1e3ccSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
aom_highbd_dc_predictor_16x64_c(uint16_t * dst,ptrdiff_t stride,const uint16_t * above,const uint16_t * left,int bd)690*77c1e3ccSAndroid Build Coastguard Worker void aom_highbd_dc_predictor_16x64_c(uint16_t *dst, ptrdiff_t stride,
691*77c1e3ccSAndroid Build Coastguard Worker const uint16_t *above,
692*77c1e3ccSAndroid Build Coastguard Worker const uint16_t *left, int bd) {
693*77c1e3ccSAndroid Build Coastguard Worker highbd_dc_predictor_rect(dst, stride, 16, 64, above, left, bd, 4,
694*77c1e3ccSAndroid Build Coastguard Worker HIGHBD_DC_MULTIPLIER_1X4);
695*77c1e3ccSAndroid Build Coastguard Worker }
696*77c1e3ccSAndroid Build Coastguard Worker
aom_highbd_dc_predictor_64x16_c(uint16_t * dst,ptrdiff_t stride,const uint16_t * above,const uint16_t * left,int bd)697*77c1e3ccSAndroid Build Coastguard Worker void aom_highbd_dc_predictor_64x16_c(uint16_t *dst, ptrdiff_t stride,
698*77c1e3ccSAndroid Build Coastguard Worker const uint16_t *above,
699*77c1e3ccSAndroid Build Coastguard Worker const uint16_t *left, int bd) {
700*77c1e3ccSAndroid Build Coastguard Worker highbd_dc_predictor_rect(dst, stride, 64, 16, above, left, bd, 4,
701*77c1e3ccSAndroid Build Coastguard Worker HIGHBD_DC_MULTIPLIER_1X4);
702*77c1e3ccSAndroid Build Coastguard Worker }
703*77c1e3ccSAndroid Build Coastguard Worker #endif // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
704*77c1e3ccSAndroid Build Coastguard Worker
aom_highbd_dc_predictor_32x64_c(uint16_t * dst,ptrdiff_t stride,const uint16_t * above,const uint16_t * left,int bd)705*77c1e3ccSAndroid Build Coastguard Worker void aom_highbd_dc_predictor_32x64_c(uint16_t *dst, ptrdiff_t stride,
706*77c1e3ccSAndroid Build Coastguard Worker const uint16_t *above,
707*77c1e3ccSAndroid Build Coastguard Worker const uint16_t *left, int bd) {
708*77c1e3ccSAndroid Build Coastguard Worker highbd_dc_predictor_rect(dst, stride, 32, 64, above, left, bd, 5,
709*77c1e3ccSAndroid Build Coastguard Worker HIGHBD_DC_MULTIPLIER_1X2);
710*77c1e3ccSAndroid Build Coastguard Worker }
711*77c1e3ccSAndroid Build Coastguard Worker
aom_highbd_dc_predictor_64x32_c(uint16_t * dst,ptrdiff_t stride,const uint16_t * above,const uint16_t * left,int bd)712*77c1e3ccSAndroid Build Coastguard Worker void aom_highbd_dc_predictor_64x32_c(uint16_t *dst, ptrdiff_t stride,
713*77c1e3ccSAndroid Build Coastguard Worker const uint16_t *above,
714*77c1e3ccSAndroid Build Coastguard Worker const uint16_t *left, int bd) {
715*77c1e3ccSAndroid Build Coastguard Worker highbd_dc_predictor_rect(dst, stride, 64, 32, above, left, bd, 5,
716*77c1e3ccSAndroid Build Coastguard Worker HIGHBD_DC_MULTIPLIER_1X2);
717*77c1e3ccSAndroid Build Coastguard Worker }
718*77c1e3ccSAndroid Build Coastguard Worker
719*77c1e3ccSAndroid Build Coastguard Worker #undef HIGHBD_DC_MULTIPLIER_1X2
720*77c1e3ccSAndroid Build Coastguard Worker #undef HIGHBD_DC_MULTIPLIER_1X4
721*77c1e3ccSAndroid Build Coastguard Worker #endif // CONFIG_AV1_HIGHBITDEPTH
722*77c1e3ccSAndroid Build Coastguard Worker
723*77c1e3ccSAndroid Build Coastguard Worker // This serves as a wrapper function, so that all the prediction functions
724*77c1e3ccSAndroid Build Coastguard Worker // can be unified and accessed as a pointer array. Note that the boundary
725*77c1e3ccSAndroid Build Coastguard Worker // above and left are not necessarily used all the time.
726*77c1e3ccSAndroid Build Coastguard Worker #define intra_pred_sized(type, width, height) \
727*77c1e3ccSAndroid Build Coastguard Worker void aom_##type##_predictor_##width##x##height##_c( \
728*77c1e3ccSAndroid Build Coastguard Worker uint8_t *dst, ptrdiff_t stride, const uint8_t *above, \
729*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left) { \
730*77c1e3ccSAndroid Build Coastguard Worker type##_predictor(dst, stride, width, height, above, left); \
731*77c1e3ccSAndroid Build Coastguard Worker }
732*77c1e3ccSAndroid Build Coastguard Worker
733*77c1e3ccSAndroid Build Coastguard Worker #if CONFIG_AV1_HIGHBITDEPTH
734*77c1e3ccSAndroid Build Coastguard Worker #define intra_pred_highbd_sized(type, width, height) \
735*77c1e3ccSAndroid Build Coastguard Worker void aom_highbd_##type##_predictor_##width##x##height##_c( \
736*77c1e3ccSAndroid Build Coastguard Worker uint16_t *dst, ptrdiff_t stride, const uint16_t *above, \
737*77c1e3ccSAndroid Build Coastguard Worker const uint16_t *left, int bd) { \
738*77c1e3ccSAndroid Build Coastguard Worker highbd_##type##_predictor(dst, stride, width, height, above, left, bd); \
739*77c1e3ccSAndroid Build Coastguard Worker }
740*77c1e3ccSAndroid Build Coastguard Worker #else // !CONFIG_AV1_HIGHBITDEPTH
741*77c1e3ccSAndroid Build Coastguard Worker #define intra_pred_highbd_sized(type, width, height)
742*77c1e3ccSAndroid Build Coastguard Worker #endif // CONFIG_AV1_HIGHBITDEPTH
743*77c1e3ccSAndroid Build Coastguard Worker
744*77c1e3ccSAndroid Build Coastguard Worker /* clang-format off */
745*77c1e3ccSAndroid Build Coastguard Worker #if CONFIG_REALTIME_ONLY && !CONFIG_AV1_DECODER
746*77c1e3ccSAndroid Build Coastguard Worker #define intra_pred_rectangular(type) \
747*77c1e3ccSAndroid Build Coastguard Worker intra_pred_sized(type, 4, 8) \
748*77c1e3ccSAndroid Build Coastguard Worker intra_pred_sized(type, 8, 4) \
749*77c1e3ccSAndroid Build Coastguard Worker intra_pred_sized(type, 8, 16) \
750*77c1e3ccSAndroid Build Coastguard Worker intra_pred_sized(type, 16, 8) \
751*77c1e3ccSAndroid Build Coastguard Worker intra_pred_sized(type, 16, 32) \
752*77c1e3ccSAndroid Build Coastguard Worker intra_pred_sized(type, 32, 16) \
753*77c1e3ccSAndroid Build Coastguard Worker intra_pred_sized(type, 32, 64) \
754*77c1e3ccSAndroid Build Coastguard Worker intra_pred_sized(type, 64, 32) \
755*77c1e3ccSAndroid Build Coastguard Worker intra_pred_highbd_sized(type, 4, 8) \
756*77c1e3ccSAndroid Build Coastguard Worker intra_pred_highbd_sized(type, 8, 4) \
757*77c1e3ccSAndroid Build Coastguard Worker intra_pred_highbd_sized(type, 8, 16) \
758*77c1e3ccSAndroid Build Coastguard Worker intra_pred_highbd_sized(type, 16, 8) \
759*77c1e3ccSAndroid Build Coastguard Worker intra_pred_highbd_sized(type, 16, 32) \
760*77c1e3ccSAndroid Build Coastguard Worker intra_pred_highbd_sized(type, 32, 16) \
761*77c1e3ccSAndroid Build Coastguard Worker intra_pred_highbd_sized(type, 32, 64) \
762*77c1e3ccSAndroid Build Coastguard Worker intra_pred_highbd_sized(type, 64, 32)
763*77c1e3ccSAndroid Build Coastguard Worker #else
764*77c1e3ccSAndroid Build Coastguard Worker #define intra_pred_rectangular(type) \
765*77c1e3ccSAndroid Build Coastguard Worker intra_pred_sized(type, 4, 8) \
766*77c1e3ccSAndroid Build Coastguard Worker intra_pred_sized(type, 8, 4) \
767*77c1e3ccSAndroid Build Coastguard Worker intra_pred_sized(type, 8, 16) \
768*77c1e3ccSAndroid Build Coastguard Worker intra_pred_sized(type, 16, 8) \
769*77c1e3ccSAndroid Build Coastguard Worker intra_pred_sized(type, 16, 32) \
770*77c1e3ccSAndroid Build Coastguard Worker intra_pred_sized(type, 32, 16) \
771*77c1e3ccSAndroid Build Coastguard Worker intra_pred_sized(type, 32, 64) \
772*77c1e3ccSAndroid Build Coastguard Worker intra_pred_sized(type, 64, 32) \
773*77c1e3ccSAndroid Build Coastguard Worker intra_pred_sized(type, 4, 16) \
774*77c1e3ccSAndroid Build Coastguard Worker intra_pred_sized(type, 16, 4) \
775*77c1e3ccSAndroid Build Coastguard Worker intra_pred_sized(type, 8, 32) \
776*77c1e3ccSAndroid Build Coastguard Worker intra_pred_sized(type, 32, 8) \
777*77c1e3ccSAndroid Build Coastguard Worker intra_pred_sized(type, 16, 64) \
778*77c1e3ccSAndroid Build Coastguard Worker intra_pred_sized(type, 64, 16) \
779*77c1e3ccSAndroid Build Coastguard Worker intra_pred_highbd_sized(type, 4, 8) \
780*77c1e3ccSAndroid Build Coastguard Worker intra_pred_highbd_sized(type, 8, 4) \
781*77c1e3ccSAndroid Build Coastguard Worker intra_pred_highbd_sized(type, 8, 16) \
782*77c1e3ccSAndroid Build Coastguard Worker intra_pred_highbd_sized(type, 16, 8) \
783*77c1e3ccSAndroid Build Coastguard Worker intra_pred_highbd_sized(type, 16, 32) \
784*77c1e3ccSAndroid Build Coastguard Worker intra_pred_highbd_sized(type, 32, 16) \
785*77c1e3ccSAndroid Build Coastguard Worker intra_pred_highbd_sized(type, 32, 64) \
786*77c1e3ccSAndroid Build Coastguard Worker intra_pred_highbd_sized(type, 64, 32) \
787*77c1e3ccSAndroid Build Coastguard Worker intra_pred_highbd_sized(type, 4, 16) \
788*77c1e3ccSAndroid Build Coastguard Worker intra_pred_highbd_sized(type, 16, 4) \
789*77c1e3ccSAndroid Build Coastguard Worker intra_pred_highbd_sized(type, 8, 32) \
790*77c1e3ccSAndroid Build Coastguard Worker intra_pred_highbd_sized(type, 32, 8) \
791*77c1e3ccSAndroid Build Coastguard Worker intra_pred_highbd_sized(type, 16, 64) \
792*77c1e3ccSAndroid Build Coastguard Worker intra_pred_highbd_sized(type, 64, 16)
793*77c1e3ccSAndroid Build Coastguard Worker #endif // CONFIG_REALTIME_ONLY && !CONFIG_AV1_DECODER
794*77c1e3ccSAndroid Build Coastguard Worker
795*77c1e3ccSAndroid Build Coastguard Worker #define intra_pred_above_4x4(type) \
796*77c1e3ccSAndroid Build Coastguard Worker intra_pred_sized(type, 8, 8) \
797*77c1e3ccSAndroid Build Coastguard Worker intra_pred_sized(type, 16, 16) \
798*77c1e3ccSAndroid Build Coastguard Worker intra_pred_sized(type, 32, 32) \
799*77c1e3ccSAndroid Build Coastguard Worker intra_pred_sized(type, 64, 64) \
800*77c1e3ccSAndroid Build Coastguard Worker intra_pred_highbd_sized(type, 4, 4) \
801*77c1e3ccSAndroid Build Coastguard Worker intra_pred_highbd_sized(type, 8, 8) \
802*77c1e3ccSAndroid Build Coastguard Worker intra_pred_highbd_sized(type, 16, 16) \
803*77c1e3ccSAndroid Build Coastguard Worker intra_pred_highbd_sized(type, 32, 32) \
804*77c1e3ccSAndroid Build Coastguard Worker intra_pred_highbd_sized(type, 64, 64) \
805*77c1e3ccSAndroid Build Coastguard Worker intra_pred_rectangular(type)
806*77c1e3ccSAndroid Build Coastguard Worker #define intra_pred_allsizes(type) \
807*77c1e3ccSAndroid Build Coastguard Worker intra_pred_sized(type, 4, 4) \
808*77c1e3ccSAndroid Build Coastguard Worker intra_pred_above_4x4(type)
809*77c1e3ccSAndroid Build Coastguard Worker #define intra_pred_square(type) \
810*77c1e3ccSAndroid Build Coastguard Worker intra_pred_sized(type, 4, 4) \
811*77c1e3ccSAndroid Build Coastguard Worker intra_pred_sized(type, 8, 8) \
812*77c1e3ccSAndroid Build Coastguard Worker intra_pred_sized(type, 16, 16) \
813*77c1e3ccSAndroid Build Coastguard Worker intra_pred_sized(type, 32, 32) \
814*77c1e3ccSAndroid Build Coastguard Worker intra_pred_sized(type, 64, 64) \
815*77c1e3ccSAndroid Build Coastguard Worker intra_pred_highbd_sized(type, 4, 4) \
816*77c1e3ccSAndroid Build Coastguard Worker intra_pred_highbd_sized(type, 8, 8) \
817*77c1e3ccSAndroid Build Coastguard Worker intra_pred_highbd_sized(type, 16, 16) \
818*77c1e3ccSAndroid Build Coastguard Worker intra_pred_highbd_sized(type, 32, 32) \
819*77c1e3ccSAndroid Build Coastguard Worker intra_pred_highbd_sized(type, 64, 64)
820*77c1e3ccSAndroid Build Coastguard Worker
821*77c1e3ccSAndroid Build Coastguard Worker intra_pred_allsizes(v)
822*77c1e3ccSAndroid Build Coastguard Worker intra_pred_allsizes(h)
823*77c1e3ccSAndroid Build Coastguard Worker intra_pred_allsizes(smooth)
824*77c1e3ccSAndroid Build Coastguard Worker intra_pred_allsizes(smooth_v)
825*77c1e3ccSAndroid Build Coastguard Worker intra_pred_allsizes(smooth_h)
826*77c1e3ccSAndroid Build Coastguard Worker intra_pred_allsizes(paeth)
827*77c1e3ccSAndroid Build Coastguard Worker intra_pred_allsizes(dc_128)
828*77c1e3ccSAndroid Build Coastguard Worker intra_pred_allsizes(dc_left)
829*77c1e3ccSAndroid Build Coastguard Worker intra_pred_allsizes(dc_top)
830*77c1e3ccSAndroid Build Coastguard Worker intra_pred_square(dc)
831*77c1e3ccSAndroid Build Coastguard Worker /* clang-format on */
832*77c1e3ccSAndroid Build Coastguard Worker #undef intra_pred_allsizes
833