1 /*
2 * Copyright (c) 2016, 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 #ifndef AOM_AV1_COMMON_AV1_TXFM_H_
13 #define AOM_AV1_COMMON_AV1_TXFM_H_
14
15 #include <assert.h>
16 #include <math.h>
17 #include <stdio.h>
18
19 #include "config/aom_config.h"
20
21 #include "av1/common/enums.h"
22 #include "av1/common/blockd.h"
23 #include "aom/aom_integer.h"
24 #include "aom_dsp/aom_dsp_common.h"
25
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29
30 #if !defined(DO_RANGE_CHECK_CLAMP)
31 #define DO_RANGE_CHECK_CLAMP 0
32 #endif
33
34 extern const int32_t av1_cospi_arr_data[7][64];
35 extern const int32_t av1_sinpi_arr_data[7][5];
36
37 #define MAX_TXFM_STAGE_NUM 12
38
39 static const int cos_bit_min = 10;
40 static const int cos_bit_max = 16;
41
42 #define NewSqrt2Bits ((int32_t)12)
43 // 2^12 * sqrt(2)
44 static const int32_t NewSqrt2 = 5793;
45 // 2^12 / sqrt(2)
46 static const int32_t NewInvSqrt2 = 2896;
47
cospi_arr(int n)48 static INLINE const int32_t *cospi_arr(int n) {
49 return av1_cospi_arr_data[n - cos_bit_min];
50 }
51
sinpi_arr(int n)52 static INLINE const int32_t *sinpi_arr(int n) {
53 return av1_sinpi_arr_data[n - cos_bit_min];
54 }
55
range_check_value(int32_t value,int8_t bit)56 static INLINE int32_t range_check_value(int32_t value, int8_t bit) {
57 #if CONFIG_COEFFICIENT_RANGE_CHECKING
58 const int64_t max_value = (1LL << (bit - 1)) - 1;
59 const int64_t min_value = -(1LL << (bit - 1));
60 if (value < min_value || value > max_value) {
61 fprintf(stderr, "coeff out of bit range, value: %d bit %d\n", value, bit);
62 #if !CONFIG_AV1_ENCODER
63 assert(0);
64 #endif
65 }
66 #endif // CONFIG_COEFFICIENT_RANGE_CHECKING
67 #if DO_RANGE_CHECK_CLAMP
68 bit = AOMMIN(bit, 31);
69 return clamp(value, -(1 << (bit - 1)), (1 << (bit - 1)) - 1);
70 #endif // DO_RANGE_CHECK_CLAMP
71 (void)bit;
72 return value;
73 }
74
round_shift(int64_t value,int bit)75 static INLINE int32_t round_shift(int64_t value, int bit) {
76 assert(bit >= 1);
77 return (int32_t)((value + (1ll << (bit - 1))) >> bit);
78 }
79
half_btf(int32_t w0,int32_t in0,int32_t w1,int32_t in1,int bit)80 static INLINE int32_t half_btf(int32_t w0, int32_t in0, int32_t w1, int32_t in1,
81 int bit) {
82 int64_t result_64 = (int64_t)(w0 * in0) + (int64_t)(w1 * in1);
83 int64_t intermediate = result_64 + (1LL << (bit - 1));
84 // NOTE(rachelbarker): The value 'result_64' may not necessarily fit
85 // into 32 bits. However, the result of this function is nominally
86 // ROUND_POWER_OF_TWO_64(result_64, bit)
87 // and that is required to fit into stage_range[stage] many bits
88 // (checked by range_check_buf()).
89 //
90 // Here we've unpacked that rounding operation, and it can be shown
91 // that the value of 'intermediate' here *does* fit into 32 bits
92 // for any conformant bitstream.
93 // The upshot is that, if you do all this calculation using
94 // wrapping 32-bit arithmetic instead of (non-wrapping) 64-bit arithmetic,
95 // then you'll still get the correct result.
96 // To provide a check on this logic, we assert that 'intermediate'
97 // would fit into an int32 if range checking is enabled.
98 #if CONFIG_COEFFICIENT_RANGE_CHECKING
99 assert(intermediate >= INT32_MIN && intermediate <= INT32_MAX);
100 #endif
101 return (int32_t)(intermediate >> bit);
102 }
103
highbd_clip_pixel_add(uint16_t dest,tran_high_t trans,int bd)104 static INLINE uint16_t highbd_clip_pixel_add(uint16_t dest, tran_high_t trans,
105 int bd) {
106 return clip_pixel_highbd(dest + (int)trans, bd);
107 }
108
109 typedef void (*TxfmFunc)(const int32_t *input, int32_t *output, int8_t cos_bit,
110 const int8_t *stage_range);
111
112 typedef void (*FwdTxfm2dFunc)(const int16_t *input, int32_t *output, int stride,
113 TX_TYPE tx_type, int bd);
114
115 enum {
116 TXFM_TYPE_DCT4,
117 TXFM_TYPE_DCT8,
118 TXFM_TYPE_DCT16,
119 TXFM_TYPE_DCT32,
120 TXFM_TYPE_DCT64,
121 TXFM_TYPE_ADST4,
122 TXFM_TYPE_ADST8,
123 TXFM_TYPE_ADST16,
124 TXFM_TYPE_IDENTITY4,
125 TXFM_TYPE_IDENTITY8,
126 TXFM_TYPE_IDENTITY16,
127 TXFM_TYPE_IDENTITY32,
128 TXFM_TYPES,
129 TXFM_TYPE_INVALID,
130 } UENUM1BYTE(TXFM_TYPE);
131
132 typedef struct TXFM_2D_FLIP_CFG {
133 TX_SIZE tx_size;
134 int ud_flip; // flip upside down
135 int lr_flip; // flip left to right
136 const int8_t *shift;
137 int8_t cos_bit_col;
138 int8_t cos_bit_row;
139 int8_t stage_range_col[MAX_TXFM_STAGE_NUM];
140 int8_t stage_range_row[MAX_TXFM_STAGE_NUM];
141 TXFM_TYPE txfm_type_col;
142 TXFM_TYPE txfm_type_row;
143 int stage_num_col;
144 int stage_num_row;
145 } TXFM_2D_FLIP_CFG;
146
get_flip_cfg(TX_TYPE tx_type,int * ud_flip,int * lr_flip)147 static INLINE void get_flip_cfg(TX_TYPE tx_type, int *ud_flip, int *lr_flip) {
148 switch (tx_type) {
149 case DCT_DCT:
150 case ADST_DCT:
151 case DCT_ADST:
152 case ADST_ADST:
153 *ud_flip = 0;
154 *lr_flip = 0;
155 break;
156 case IDTX:
157 case V_DCT:
158 case H_DCT:
159 case V_ADST:
160 case H_ADST:
161 *ud_flip = 0;
162 *lr_flip = 0;
163 break;
164 case FLIPADST_DCT:
165 case FLIPADST_ADST:
166 case V_FLIPADST:
167 *ud_flip = 1;
168 *lr_flip = 0;
169 break;
170 case DCT_FLIPADST:
171 case ADST_FLIPADST:
172 case H_FLIPADST:
173 *ud_flip = 0;
174 *lr_flip = 1;
175 break;
176 case FLIPADST_FLIPADST:
177 *ud_flip = 1;
178 *lr_flip = 1;
179 break;
180 default:
181 *ud_flip = 0;
182 *lr_flip = 0;
183 assert(0);
184 }
185 }
186
set_flip_cfg(TX_TYPE tx_type,TXFM_2D_FLIP_CFG * cfg)187 static INLINE void set_flip_cfg(TX_TYPE tx_type, TXFM_2D_FLIP_CFG *cfg) {
188 get_flip_cfg(tx_type, &cfg->ud_flip, &cfg->lr_flip);
189 }
190
191 // Utility function that returns the log of the ratio of the col and row
192 // sizes.
get_rect_tx_log_ratio(int col,int row)193 static INLINE int get_rect_tx_log_ratio(int col, int row) {
194 if (col == row) return 0;
195 if (col > row) {
196 if (col == row * 2) return 1;
197 if (col == row * 4) return 2;
198 assert(0 && "Unsupported transform size");
199 } else {
200 if (row == col * 2) return -1;
201 if (row == col * 4) return -2;
202 assert(0 && "Unsupported transform size");
203 }
204 return 0; // Invalid
205 }
206
207 void av1_gen_fwd_stage_range(int8_t *stage_range_col, int8_t *stage_range_row,
208 const TXFM_2D_FLIP_CFG *cfg, int bd);
209
210 void av1_gen_inv_stage_range(int8_t *stage_range_col, int8_t *stage_range_row,
211 const TXFM_2D_FLIP_CFG *cfg, TX_SIZE tx_size,
212 int bd);
213
214 void av1_get_fwd_txfm_cfg(TX_TYPE tx_type, TX_SIZE tx_size,
215 TXFM_2D_FLIP_CFG *cfg);
216 void av1_get_inv_txfm_cfg(TX_TYPE tx_type, TX_SIZE tx_size,
217 TXFM_2D_FLIP_CFG *cfg);
218 extern const TXFM_TYPE av1_txfm_type_ls[5][TX_TYPES_1D];
219 extern const int8_t av1_txfm_stage_num_list[TXFM_TYPES];
get_txw_idx(TX_SIZE tx_size)220 static INLINE int get_txw_idx(TX_SIZE tx_size) {
221 return tx_size_wide_log2[tx_size] - tx_size_wide_log2[0];
222 }
get_txh_idx(TX_SIZE tx_size)223 static INLINE int get_txh_idx(TX_SIZE tx_size) {
224 return tx_size_high_log2[tx_size] - tx_size_high_log2[0];
225 }
226
227 void av1_range_check_buf(int32_t stage, const int32_t *input,
228 const int32_t *buf, int32_t size, int8_t bit);
229 #define MAX_TXWH_IDX 5
230 #ifdef __cplusplus
231 }
232 #endif // __cplusplus
233
234 #endif // AOM_AV1_COMMON_AV1_TXFM_H_
235