1 /*
2 * Copyright (c) 2018, Alliance for Open Media. All rights reserved
3 *
4 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10 */
11
12 #include <assert.h>
13 #include <stdlib.h>
14 #include <math.h>
15
16 #include "config/av1_rtcd.h"
17 #include "av1/encoder/dwt.h"
18
19 // Note: block length must be even for this implementation
analysis_53_row(int length,tran_low_t * x,tran_low_t * lowpass,tran_low_t * highpass)20 static void analysis_53_row(int length, tran_low_t *x, tran_low_t *lowpass,
21 tran_low_t *highpass) {
22 int n;
23 tran_low_t r, *a, *b;
24
25 n = length >> 1;
26 b = highpass;
27 a = lowpass;
28 while (--n) {
29 *a++ = (r = *x++) * 2;
30 *b++ = *x - ((r + x[1] + 1) >> 1);
31 x++;
32 }
33 *a = (r = *x++) * 2;
34 *b = *x - r;
35
36 n = length >> 1;
37 b = highpass;
38 a = lowpass;
39 r = *highpass;
40 while (n--) {
41 *a++ += (r + (*b) + 1) >> 1;
42 r = *b++;
43 }
44 }
45
analysis_53_col(int length,tran_low_t * x,tran_low_t * lowpass,tran_low_t * highpass)46 static void analysis_53_col(int length, tran_low_t *x, tran_low_t *lowpass,
47 tran_low_t *highpass) {
48 int n;
49 tran_low_t r, *a, *b;
50
51 n = length >> 1;
52 b = highpass;
53 a = lowpass;
54 while (--n) {
55 *a++ = (r = *x++);
56 *b++ = (((*x) * 2) - (r + x[1]) + 2) >> 2;
57 x++;
58 }
59 *a = (r = *x++);
60 *b = (*x - r + 1) >> 1;
61
62 n = length >> 1;
63 b = highpass;
64 a = lowpass;
65 r = *highpass;
66 while (n--) {
67 *a++ += (r + (*b) + 1) >> 1;
68 r = *b++;
69 }
70 }
71
dyadic_analyze_53_uint8_input(int levels,int width,int height,uint8_t * x,int pitch_x,tran_low_t * c,int pitch_c,int dwt_scale_bits,int hbd)72 static void dyadic_analyze_53_uint8_input(int levels, int width, int height,
73 uint8_t *x, int pitch_x,
74 tran_low_t *c, int pitch_c,
75 int dwt_scale_bits, int hbd) {
76 int lv, i, j, nh, nw, hh = height, hw = width;
77 tran_low_t buffer[2 * DWT_MAX_LENGTH];
78
79 if (hbd) {
80 uint16_t *x16 = CONVERT_TO_SHORTPTR(x);
81 for (i = 0; i < height; i++) {
82 for (j = 0; j < width; j++) {
83 c[i * pitch_c + j] = x16[i * pitch_x + j] << dwt_scale_bits;
84 }
85 }
86 } else {
87 for (i = 0; i < height; i++) {
88 for (j = 0; j < width; j++) {
89 c[i * pitch_c + j] = x[i * pitch_x + j] << dwt_scale_bits;
90 }
91 }
92 }
93
94 for (lv = 0; lv < levels; lv++) {
95 nh = hh;
96 hh = (hh + 1) >> 1;
97 nw = hw;
98 hw = (hw + 1) >> 1;
99 if ((nh < 2) || (nw < 2)) return;
100 for (i = 0; i < nh; i++) {
101 memcpy(buffer, &c[i * pitch_c], nw * sizeof(tran_low_t));
102 analysis_53_row(nw, buffer, &c[i * pitch_c], &c[i * pitch_c] + hw);
103 }
104 for (j = 0; j < nw; j++) {
105 for (i = 0; i < nh; i++) buffer[i + nh] = c[i * pitch_c + j];
106 analysis_53_col(nh, buffer + nh, buffer, buffer + hh);
107 for (i = 0; i < nh; i++) c[i * pitch_c + j] = buffer[i];
108 }
109 }
110 }
111
av1_fdwt8x8_uint8_input_c(uint8_t * input,tran_low_t * output,int stride,int hbd)112 void av1_fdwt8x8_uint8_input_c(uint8_t *input, tran_low_t *output, int stride,
113 int hbd) {
114 dyadic_analyze_53_uint8_input(4, 8, 8, input, stride, output, 8, 2, hbd);
115 }
116
av1_haar_ac_sad(tran_low_t * output,int bw,int bh,int stride)117 int av1_haar_ac_sad(tran_low_t *output, int bw, int bh, int stride) {
118 int acsad = 0;
119
120 for (int r = 0; r < bh; ++r)
121 for (int c = 0; c < bw; ++c) {
122 if (r >= bh / 2 || c >= bw / 2) acsad += abs(output[r * stride + c]);
123 }
124 return acsad;
125 }
126
av1_dct_ac_sad(tran_low_t * output,int bw,int bh,int stride)127 uint64_t av1_dct_ac_sad(tran_low_t *output, int bw, int bh, int stride) {
128 uint64_t acsad = 0;
129
130 for (int r = 0; r < bh; ++r)
131 for (int c = 0; c < bw; ++c) {
132 if (r > 0 || c > 0) acsad += abs(output[r * stride + c]);
133 }
134
135 return acsad;
136 }
137
av1_variance(uint8_t * input,int bw,int bh,int stride)138 uint32_t av1_variance(uint8_t *input, int bw, int bh, int stride) {
139 int sum = 0;
140 uint32_t sse = 0;
141
142 for (int r = 0; r < bh; ++r)
143 for (int c = 0; c < bw; ++c) {
144 sum += input[r * stride + c];
145 sse += input[r * stride + c] * input[r * stride + c];
146 }
147 return sse - (uint32_t)(((int64_t)sum * sum) / (bw * bh));
148 }
149
av1_haar_ac_sad_8x8_uint8_input(uint8_t * input,int stride,int hbd)150 int av1_haar_ac_sad_8x8_uint8_input(uint8_t *input, int stride, int hbd) {
151 tran_low_t output[64];
152
153 av1_fdwt8x8_uint8_input_c(input, output, stride, hbd);
154 return av1_haar_ac_sad(output, 8, 8, 8);
155 }
156