xref: /aosp_15_r20/external/libgav1/src/dsp/inverse_transform.inc (revision 095378508e87ed692bf8dfeb34008b65b3735891)
1*09537850SAkhilesh Sanikop// Copyright 2019 The libgav1 Authors
2*09537850SAkhilesh Sanikop//
3*09537850SAkhilesh Sanikop// Licensed under the Apache License, Version 2.0 (the "License");
4*09537850SAkhilesh Sanikop// you may not use this file except in compliance with the License.
5*09537850SAkhilesh Sanikop// You may obtain a copy of the License at
6*09537850SAkhilesh Sanikop//
7*09537850SAkhilesh Sanikop//      http://www.apache.org/licenses/LICENSE-2.0
8*09537850SAkhilesh Sanikop//
9*09537850SAkhilesh Sanikop// Unless required by applicable law or agreed to in writing, software
10*09537850SAkhilesh Sanikop// distributed under the License is distributed on an "AS IS" BASIS,
11*09537850SAkhilesh Sanikop// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*09537850SAkhilesh Sanikop// See the License for the specific language governing permissions and
13*09537850SAkhilesh Sanikop// limitations under the License.
14*09537850SAkhilesh Sanikop
15*09537850SAkhilesh Sanikop// Constants and utility functions used for inverse transform implementations.
16*09537850SAkhilesh Sanikop// This will be included inside an anonymous namespace on files where these are
17*09537850SAkhilesh Sanikop// necessary.
18*09537850SAkhilesh Sanikop
19*09537850SAkhilesh Sanikop// The value at index i is derived as: round(cos(pi * i / 128) * (1 << 12)).
20*09537850SAkhilesh Sanikopconstexpr int16_t kCos128[65] = {
21*09537850SAkhilesh Sanikop    4096, 4095, 4091, 4085, 4076, 4065, 4052, 4036, 4017, 3996, 3973,
22*09537850SAkhilesh Sanikop    3948, 3920, 3889, 3857, 3822, 3784, 3745, 3703, 3659, 3612, 3564,
23*09537850SAkhilesh Sanikop    3513, 3461, 3406, 3349, 3290, 3229, 3166, 3102, 3035, 2967, 2896,
24*09537850SAkhilesh Sanikop    2824, 2751, 2675, 2598, 2520, 2440, 2359, 2276, 2191, 2106, 2019,
25*09537850SAkhilesh Sanikop    1931, 1842, 1751, 1660, 1567, 1474, 1380, 1285, 1189, 1092, 995,
26*09537850SAkhilesh Sanikop    897,  799,  700,  601,  501,  401,  301,  201,  101,  0};
27*09537850SAkhilesh Sanikop
28*09537850SAkhilesh Sanikopinline int16_t Cos128(int angle) {
29*09537850SAkhilesh Sanikop  angle &= 0xff;
30*09537850SAkhilesh Sanikop
31*09537850SAkhilesh Sanikop  // If |angle| is 128, this function returns -4096 (= -2^12), which will
32*09537850SAkhilesh Sanikop  // cause the 32-bit multiplications in ButterflyRotation() to overflow if
33*09537850SAkhilesh Sanikop  // dst[a] or dst[b] is -2^19 (a possible corner case when |range| is 20):
34*09537850SAkhilesh Sanikop  //
35*09537850SAkhilesh Sanikop  //   (-2^12) * (-2^19) = 2^31, which cannot be represented as an int32_t.
36*09537850SAkhilesh Sanikop  //
37*09537850SAkhilesh Sanikop  // Note: |range| is 20 when bitdepth is 12 and a row transform is performed.
38*09537850SAkhilesh Sanikop  //
39*09537850SAkhilesh Sanikop  // Assert that this angle is never used by DCT or ADST.
40*09537850SAkhilesh Sanikop  assert(angle != 128);
41*09537850SAkhilesh Sanikop  if (angle <= 64) return kCos128[angle];
42*09537850SAkhilesh Sanikop  if (angle <= 128) return -kCos128[128 - angle];
43*09537850SAkhilesh Sanikop  if (angle <= 192) return -kCos128[angle - 128];
44*09537850SAkhilesh Sanikop  return kCos128[256 - angle];
45*09537850SAkhilesh Sanikop}
46*09537850SAkhilesh Sanikop
47*09537850SAkhilesh Sanikopinline int16_t Sin128(int angle) { return Cos128(angle - 64); }
48*09537850SAkhilesh Sanikop
49*09537850SAkhilesh Sanikop// The value for index i is derived as:
50*09537850SAkhilesh Sanikop// round(sqrt(2) * sin(i * pi / 9) * 2 / 3 * (1 << 12)).
51*09537850SAkhilesh Sanikopconstexpr int16_t kAdst4Multiplier[4] = {1321, 2482, 3344, 3803};
52*09537850SAkhilesh Sanikop
53*09537850SAkhilesh Sanikopconstexpr uint8_t kTransformRowShift[kNumTransformSizes] = {
54*09537850SAkhilesh Sanikop    0, 0, 1, 0, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 2, 1, 2, 1, 2};
55*09537850SAkhilesh Sanikop
56*09537850SAkhilesh Sanikopconstexpr bool kShouldRound[kNumTransformSizes] = {
57*09537850SAkhilesh Sanikop    false, true,  false, true, false, true, false, false, true, false,
58*09537850SAkhilesh Sanikop    true,  false, false, true, false, true, false, true,  false};
59*09537850SAkhilesh Sanikop
60*09537850SAkhilesh Sanikopconstexpr int16_t kIdentity4Multiplier /* round(2^12 * sqrt(2)) */ = 0x16A1;
61*09537850SAkhilesh Sanikopconstexpr int16_t kIdentity4MultiplierFraction /* round(2^12 * (sqrt(2) - 1))*/
62*09537850SAkhilesh Sanikop    = 0x6A1;
63*09537850SAkhilesh Sanikopconstexpr int16_t kIdentity16Multiplier /* 2 * round(2^12 * sqrt(2)) */ = 11586;
64*09537850SAkhilesh Sanikopconstexpr int16_t kTransformRowMultiplier /* round(2^12 / sqrt(2)) */ = 2896;
65