1/*
2 *  Copyright (c) 2015 The WebM project authors. All Rights Reserved.
3 *
4 *  Use of this source code is governed by a BSD-style license
5 *  that can be found in the LICENSE file in the root of the source
6 *  tree. An additional intellectual property rights grant can be found
7 *  in the file PATENTS.  All contributing project authors may
8 *  be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "./vpx_dsp_rtcd.h"
12#include "vpx_dsp/quantize.h"
13#include "vpx_mem/vpx_mem.h"
14
15void vpx_quantize_dc(const tran_low_t *coeff_ptr, int n_coeffs, int skip_block,
16                     const int16_t *round_ptr, const int16_t quant,
17                     tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
18                     const int16_t dequant_ptr, uint16_t *eob_ptr) {
19  const int rc = 0;
20  const int coeff = coeff_ptr[rc];
21  const int coeff_sign = (coeff >> 31);
22  const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
23  int tmp, eob = -1;
24
25  memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
26  memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
27
28  if (!skip_block) {
29    tmp = clamp(abs_coeff + round_ptr[rc != 0], INT16_MIN, INT16_MAX);
30    tmp = (tmp * quant) >> 16;
31    qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
32    dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr;
33    if (tmp) eob = 0;
34  }
35  *eob_ptr = eob + 1;
36}
37
38#if CONFIG_VP9_HIGHBITDEPTH
39void vpx_highbd_quantize_dc(const tran_low_t *coeff_ptr, int n_coeffs,
40                            int skip_block, const int16_t *round_ptr,
41                            const int16_t quant, tran_low_t *qcoeff_ptr,
42                            tran_low_t *dqcoeff_ptr, const int16_t dequant_ptr,
43                            uint16_t *eob_ptr) {
44  int eob = -1;
45
46  memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
47  memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
48
49  if (!skip_block) {
50    const int coeff = coeff_ptr[0];
51    const int coeff_sign = (coeff >> 31);
52    const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
53    const int64_t tmp = abs_coeff + round_ptr[0];
54    const int abs_qcoeff = (int)((tmp * quant) >> 16);
55    qcoeff_ptr[0] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
56    dqcoeff_ptr[0] = qcoeff_ptr[0] * dequant_ptr;
57    if (abs_qcoeff) eob = 0;
58  }
59  *eob_ptr = eob + 1;
60}
61#endif
62
63void vpx_quantize_dc_32x32(const tran_low_t *coeff_ptr, int skip_block,
64                           const int16_t *round_ptr, const int16_t quant,
65                           tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
66                           const int16_t dequant_ptr, uint16_t *eob_ptr) {
67  const int n_coeffs = 1024;
68  const int rc = 0;
69  const int coeff = coeff_ptr[rc];
70  const int coeff_sign = (coeff >> 31);
71  const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
72  int tmp, eob = -1;
73
74  memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
75  memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
76
77  if (!skip_block) {
78    tmp = clamp(abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1),
79                INT16_MIN, INT16_MAX);
80    tmp = (tmp * quant) >> 15;
81    qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
82    dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr / 2;
83    if (tmp) eob = 0;
84  }
85  *eob_ptr = eob + 1;
86}
87
88#if CONFIG_VP9_HIGHBITDEPTH
89void vpx_highbd_quantize_dc_32x32(const tran_low_t *coeff_ptr, int skip_block,
90                                  const int16_t *round_ptr, const int16_t quant,
91                                  tran_low_t *qcoeff_ptr,
92                                  tran_low_t *dqcoeff_ptr,
93                                  const int16_t dequant_ptr,
94                                  uint16_t *eob_ptr) {
95  const int n_coeffs = 1024;
96  int eob = -1;
97
98  memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
99  memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
100
101  if (!skip_block) {
102    const int coeff = coeff_ptr[0];
103    const int coeff_sign = (coeff >> 31);
104    const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
105    const int64_t tmp = abs_coeff + ROUND_POWER_OF_TWO(round_ptr[0], 1);
106    const int abs_qcoeff = (int)((tmp * quant) >> 15);
107    qcoeff_ptr[0] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
108    dqcoeff_ptr[0] = qcoeff_ptr[0] * dequant_ptr / 2;
109    if (abs_qcoeff) eob = 0;
110  }
111  *eob_ptr = eob + 1;
112}
113#endif
114
115void vpx_quantize_b_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
116                      int skip_block, const int16_t *zbin_ptr,
117                      const int16_t *round_ptr, const int16_t *quant_ptr,
118                      const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr,
119                      tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr,
120                      uint16_t *eob_ptr, const int16_t *scan,
121                      const int16_t *iscan) {
122  int i, non_zero_count = (int)n_coeffs, eob = -1;
123  const int zbins[2] = { zbin_ptr[0], zbin_ptr[1] };
124  const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 };
125  (void)iscan;
126
127  memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
128  memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
129
130  if (!skip_block) {
131    // Pre-scan pass
132    for (i = (int)n_coeffs - 1; i >= 0; i--) {
133      const int rc = scan[i];
134      const int coeff = coeff_ptr[rc];
135
136      if (coeff < zbins[rc != 0] && coeff > nzbins[rc != 0])
137        non_zero_count--;
138      else
139        break;
140    }
141
142    // Quantization pass: All coefficients with index >= zero_flag are
143    // skippable. Note: zero_flag can be zero.
144    for (i = 0; i < non_zero_count; i++) {
145      const int rc = scan[i];
146      const int coeff = coeff_ptr[rc];
147      const int coeff_sign = (coeff >> 31);
148      const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
149
150      if (abs_coeff >= zbins[rc != 0]) {
151        int tmp = clamp(abs_coeff + round_ptr[rc != 0], INT16_MIN, INT16_MAX);
152        tmp = ((((tmp * quant_ptr[rc != 0]) >> 16) + tmp) *
153               quant_shift_ptr[rc != 0]) >>
154              16;  // quantization
155        qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
156        dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0];
157
158        if (tmp) eob = i;
159      }
160    }
161  }
162  *eob_ptr = eob + 1;
163}
164
165#if CONFIG_VP9_HIGHBITDEPTH
166void vpx_highbd_quantize_b_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
167                             int skip_block, const int16_t *zbin_ptr,
168                             const int16_t *round_ptr, const int16_t *quant_ptr,
169                             const int16_t *quant_shift_ptr,
170                             tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
171                             const int16_t *dequant_ptr, uint16_t *eob_ptr,
172                             const int16_t *scan, const int16_t *iscan) {
173  int i, non_zero_count = (int)n_coeffs, eob = -1;
174  const int zbins[2] = { zbin_ptr[0], zbin_ptr[1] };
175  const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 };
176  (void)iscan;
177
178  memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
179  memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
180
181  if (!skip_block) {
182    // Pre-scan pass
183    for (i = (int)n_coeffs - 1; i >= 0; i--) {
184      const int rc = scan[i];
185      const int coeff = coeff_ptr[rc];
186
187      if (coeff < zbins[rc != 0] && coeff > nzbins[rc != 0])
188        non_zero_count--;
189      else
190        break;
191    }
192
193    // Quantization pass: All coefficients with index >= zero_flag are
194    // skippable. Note: zero_flag can be zero.
195    for (i = 0; i < non_zero_count; i++) {
196      const int rc = scan[i];
197      const int coeff = coeff_ptr[rc];
198      const int coeff_sign = (coeff >> 31);
199      const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
200
201      if (abs_coeff >= zbins[rc != 0]) {
202        const int64_t tmp1 = abs_coeff + round_ptr[rc != 0];
203        const int64_t tmp2 = ((tmp1 * quant_ptr[rc != 0]) >> 16) + tmp1;
204        const uint32_t abs_qcoeff =
205            (uint32_t)((tmp2 * quant_shift_ptr[rc != 0]) >> 16);
206        qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
207        dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0];
208        if (abs_qcoeff) eob = i;
209      }
210    }
211  }
212  *eob_ptr = eob + 1;
213}
214#endif
215
216void vpx_quantize_b_32x32_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
217                            int skip_block, const int16_t *zbin_ptr,
218                            const int16_t *round_ptr, const int16_t *quant_ptr,
219                            const int16_t *quant_shift_ptr,
220                            tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
221                            const int16_t *dequant_ptr, uint16_t *eob_ptr,
222                            const int16_t *scan, const int16_t *iscan) {
223  const int zbins[2] = { ROUND_POWER_OF_TWO(zbin_ptr[0], 1),
224                         ROUND_POWER_OF_TWO(zbin_ptr[1], 1) };
225  const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 };
226
227  int idx = 0;
228  int idx_arr[1024];
229  int i, eob = -1;
230  (void)iscan;
231
232  memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
233  memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
234
235  if (!skip_block) {
236    // Pre-scan pass
237    for (i = 0; i < n_coeffs; i++) {
238      const int rc = scan[i];
239      const int coeff = coeff_ptr[rc];
240
241      // If the coefficient is out of the base ZBIN range, keep it for
242      // quantization.
243      if (coeff >= zbins[rc != 0] || coeff <= nzbins[rc != 0])
244        idx_arr[idx++] = i;
245    }
246
247    // Quantization pass: only process the coefficients selected in
248    // pre-scan pass. Note: idx can be zero.
249    for (i = 0; i < idx; i++) {
250      const int rc = scan[idx_arr[i]];
251      const int coeff = coeff_ptr[rc];
252      const int coeff_sign = (coeff >> 31);
253      int tmp;
254      int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
255      abs_coeff += ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1);
256      abs_coeff = clamp(abs_coeff, INT16_MIN, INT16_MAX);
257      tmp = ((((abs_coeff * quant_ptr[rc != 0]) >> 16) + abs_coeff) *
258             quant_shift_ptr[rc != 0]) >>
259            15;
260
261      qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
262      dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0] / 2;
263
264      if (tmp) eob = idx_arr[i];
265    }
266  }
267  *eob_ptr = eob + 1;
268}
269
270#if CONFIG_VP9_HIGHBITDEPTH
271void vpx_highbd_quantize_b_32x32_c(
272    const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block,
273    const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr,
274    const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr,
275    tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr,
276    const int16_t *scan, const int16_t *iscan) {
277  const int zbins[2] = { ROUND_POWER_OF_TWO(zbin_ptr[0], 1),
278                         ROUND_POWER_OF_TWO(zbin_ptr[1], 1) };
279  const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 };
280
281  int idx = 0;
282  int idx_arr[1024];
283  int i, eob = -1;
284  (void)iscan;
285
286  memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
287  memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
288
289  if (!skip_block) {
290    // Pre-scan pass
291    for (i = 0; i < n_coeffs; i++) {
292      const int rc = scan[i];
293      const int coeff = coeff_ptr[rc];
294
295      // If the coefficient is out of the base ZBIN range, keep it for
296      // quantization.
297      if (coeff >= zbins[rc != 0] || coeff <= nzbins[rc != 0])
298        idx_arr[idx++] = i;
299    }
300
301    // Quantization pass: only process the coefficients selected in
302    // pre-scan pass. Note: idx can be zero.
303    for (i = 0; i < idx; i++) {
304      const int rc = scan[idx_arr[i]];
305      const int coeff = coeff_ptr[rc];
306      const int coeff_sign = (coeff >> 31);
307      const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
308      const int64_t tmp1 =
309          abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1);
310      const int64_t tmp2 = ((tmp1 * quant_ptr[rc != 0]) >> 16) + tmp1;
311      const uint32_t abs_qcoeff =
312          (uint32_t)((tmp2 * quant_shift_ptr[rc != 0]) >> 15);
313      qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
314      dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0] / 2;
315      if (abs_qcoeff) eob = idx_arr[i];
316    }
317  }
318  *eob_ptr = eob + 1;
319}
320#endif
321