Coverage Report

Created: 2025-08-26 06:53

/src/libxaac/decoder/ixheaacd_avq_dec.c
Line
Count
Source (jump to first uncovered line)
1
/******************************************************************************
2
 *                                                                            *
3
 * Copyright (C) 2018 The Android Open Source Project
4
 *
5
 * Licensed under the Apache License, Version 2.0 (the "License");
6
 * you may not use this file except in compliance with the License.
7
 * You may obtain a copy of the License at:
8
 *
9
 * http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 *
17
 *****************************************************************************
18
 * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19
*/
20
#include <stdio.h>
21
#include <stdlib.h>
22
#include <float.h>
23
#include <math.h>
24
#include <assert.h>
25
#include <string.h>
26
#include "ixheaac_type_def.h"
27
#include "ixheaac_constants.h"
28
#include "ixheaac_basic_ops32.h"
29
#include "ixheaac_basic_ops40.h"
30
#include "ixheaacd_acelp_com.h"
31
32
extern const WORD32 ixheaacd_factorial_7[8];
33
extern const WORD32 ixheaacd_iso_code_index_table[LEN_ABS_LEADER];
34
extern const UWORD8 ixheaacd_iso_code_data_table[LEN_SIGN_LEADER];
35
extern const UWORD32 ixheaacd_signed_leader_is[LEN_SIGN_LEADER];
36
extern const WORD32 ixheaacd_iso_code_num_table[],
37
    ixheaacd_pos_abs_leaders_a3[], ixheaacd_pos_abs_leaders_a4[];
38
extern const UWORD8 ixheaacd_absolute_leader_tab_da[][8];
39
extern const UWORD32 ixheaacd_cardinality_offset_table_i3[],
40
    ixheaacd_cardinality_offset_tab_i4[];
41
42
static VOID ixheaacd_nearest_neighbor_2d(WORD32 x[], WORD32 y[], WORD32 count,
43
205k
                                         WORD32 *rem) {
44
205k
  WORD32 i, j, sum;
45
205k
  WORD32 s, e[8], em;
46
205k
  WORD32 rem_temp[8];
47
48
205k
  memcpy(rem_temp, rem, 8 * sizeof(WORD32));
49
50
205k
  sum = 0;
51
1.85M
  for (i = 0; i < 8; i++) {
52
1.64M
    if (x[i] < 0) {
53
177k
      y[i] = ixheaac_negate32_sat(
54
177k
          ixheaac_shl32_sat((ixheaac_sub32_sat(1, x[i]) >> 1), 1));
55
1.46M
    } else {
56
1.46M
      y[i] = ixheaac_shl32_sat((ixheaac_add32_sat(1, x[i]) >> 1), 1);
57
1.46M
    }
58
1.64M
    sum = ixheaac_add32_sat(sum, y[i]);
59
60
1.64M
    if (x[i] % 2 != 0) {
61
563k
      if (x[i] < 0) {
62
172k
        rem_temp[i] = ixheaac_negate32_sat(
63
172k
            ixheaac_sub32_sat(rem_temp[i], (1 << count)));
64
390k
      } else {
65
390k
        rem_temp[i] = ixheaac_sub32_sat(rem_temp[i], (1 << count));
66
390k
      }
67
563k
    }
68
1.64M
  }
69
70
205k
  if (sum % 4) {
71
101k
    em = 0;
72
101k
    j = 0;
73
912k
    for (i = 0; i < 8; i++) {
74
810k
      e[i] = rem_temp[i];
75
810k
    }
76
912k
    for (i = 0; i < 8; i++) {
77
810k
      if (e[i] < 0) {
78
338k
        s = -e[i];
79
472k
      } else {
80
472k
        s = e[i];
81
472k
      }
82
83
810k
      if (em < s) {
84
132k
        em = s;
85
132k
        j = i;
86
132k
      }
87
810k
    }
88
89
101k
    if (e[j] < 0) {
90
57.5k
      y[j] -= 2;
91
57.5k
      rem_temp[j] = ixheaac_add32_sat(rem_temp[j], (2 << count));
92
57.5k
    } else {
93
43.7k
      y[j] = ixheaac_add32_sat(y[j], 2);
94
43.7k
      rem_temp[j] = ixheaac_sub32_sat(rem_temp[j], (2 << count));
95
43.7k
    }
96
101k
  }
97
98
205k
  memcpy(rem, rem_temp, 8 * sizeof(WORD32));
99
205k
  return;
100
205k
}
101
102
VOID ixheaacd_voronoi_search(WORD32 x[], WORD32 y[], WORD32 count, WORD32 *rem1,
103
102k
                             WORD32 *rem2) {
104
102k
  WORD32 i, y0[8], y1[8];
105
102k
  WORD32 x1[8], tmp;
106
102k
  WORD32 e0, e1;
107
108
102k
  ixheaacd_nearest_neighbor_2d(x, y0, count, rem1);
109
926k
  for (i = 0; i < 8; i++) {
110
823k
    if (x[i] == 0) {
111
427k
      if (rem2[i] == 0) {
112
168k
        x1[i] = x[i] - 1;
113
259k
      } else {
114
259k
        x1[i] = 0;
115
259k
        rem2[i] = ixheaac_sub32_sat(rem2[i], (1 << count));
116
259k
      }
117
427k
    } else {
118
395k
      x1[i] = ixheaac_sub32_sat(x[i], 1);
119
395k
    }
120
823k
  }
121
122
102k
  ixheaacd_nearest_neighbor_2d(x1, y1, count, rem2);
123
124
926k
  for (i = 0; i < 8; i++) {
125
823k
    y1[i] = ixheaac_add32_sat(y1[i], 1);
126
823k
  }
127
128
102k
  e0 = e1 = 0;
129
926k
  for (i = 0; i < 8; i++) {
130
823k
    tmp = rem1[i];
131
823k
    e0 = ixheaac_add32_sat(ixheaac_sat64_32((WORD64)tmp * (WORD64)tmp), e0);
132
823k
    tmp = rem2[i];
133
823k
    e1 = ixheaac_add32_sat(ixheaac_sat64_32((WORD64)tmp * (WORD64)tmp), e1);
134
823k
  }
135
136
102k
  if (e0 < e1) {
137
607k
    for (i = 0; i < 8; i++) {
138
539k
      y[i] = y0[i];
139
539k
    }
140
67.4k
  } else {
141
318k
    for (i = 0; i < 8; i++) {
142
283k
      y[i] = y1[i];
143
283k
    }
144
35.4k
  }
145
102k
  return;
146
102k
}
147
148
102k
VOID ixheaacd_voronoi_idx_dec(WORD32 *kv, WORD32 m, WORD32 *y, WORD32 count) {
149
102k
  WORD32 i, v[8], tmp, sum, *ptr1, *ptr2;
150
102k
  WORD32 z[8];
151
102k
  WORD32 rem1[8], rem2[8];
152
153
926k
  for (i = 0; i < 8; i++) y[i] = kv[7];
154
155
102k
  z[7] = y[7] >> count;
156
102k
  rem1[7] = y[7] & (m - 1);
157
102k
  sum = 0;
158
720k
  for (i = 6; i >= 1; i--) {
159
617k
    tmp = ixheaac_shl32_sat(kv[i], 1);
160
617k
    sum = ixheaac_add32_sat(sum, tmp);
161
617k
    y[i] = ixheaac_add32_sat(y[i], tmp);
162
617k
    z[i] = y[i] >> count;
163
617k
    rem1[i] = y[i] & (m - 1);
164
617k
  }
165
102k
  y[0] = ixheaac_add32_sat(
166
102k
      y[0],
167
102k
      ixheaac_add32_sat(ixheaac_sat64_32((WORD64)4 * (WORD64)kv[0]), sum));
168
102k
  z[0] = (ixheaac_sub32_sat(y[0], 2)) >> count;
169
102k
  if (m != 0)
170
102k
    rem1[0] = (ixheaac_sub32_sat(y[0], 2)) % m;
171
0
  else
172
0
    rem1[0] = ixheaac_sub32_sat(y[0], 2);
173
174
102k
  memcpy(rem2, rem1, 8 * sizeof(WORD32));
175
176
102k
  ixheaacd_voronoi_search(z, v, count, rem1, rem2);
177
178
102k
  ptr1 = y;
179
102k
  ptr2 = v;
180
926k
  for (i = 0; i < 8; i++) {
181
823k
    *ptr1 = ixheaac_sub32_sat(*ptr1,
182
823k
                               ixheaac_sat64_32((WORD64)m * (WORD64)*ptr2++));
183
823k
    ptr1++;
184
823k
  }
185
102k
}
186
187
1.43M
static VOID ixheaacd_gosset_rank_of_permutation(WORD32 rank, WORD32 *xs) {
188
1.43M
  WORD32 i, j, a[8], w[8], base, fac, fac_b, target;
189
190
1.43M
  j = 0;
191
1.43M
  w[j] = 1;
192
1.43M
  a[j] = xs[0];
193
1.43M
  base = 1;
194
11.4M
  for (i = 1; i < 8; i++) {
195
10.0M
    if (xs[i] != xs[i - 1]) {
196
2.33M
      j++;
197
2.33M
      w[j] = 1;
198
2.33M
      a[j] = xs[i];
199
7.72M
    } else {
200
7.72M
      w[j]++;
201
7.72M
      base *= w[j];
202
7.72M
    }
203
10.0M
  }
204
205
1.43M
  if (w[0] == 8) {
206
552k
    for (i = 0; i < 8; i++) xs[i] = a[0];
207
1.37M
  } else {
208
1.37M
    target = rank * base;
209
1.37M
    fac_b = 1;
210
211
12.3M
    for (i = 0; i < 8; i++) {
212
11.0M
      fac = fac_b * ixheaacd_factorial_7[i];
213
11.0M
      j = -1;
214
22.6M
      do {
215
22.6M
        target -= w[++j] * fac;
216
22.6M
      } while (target >= 0);
217
11.0M
      xs[i] = a[j];
218
219
11.0M
      target += w[j] * fac;
220
11.0M
      fac_b *= w[j];
221
11.0M
      w[j]--;
222
11.0M
    }
223
1.37M
  }
224
225
1.43M
  return;
226
1.43M
}
227
228
static WORD32 ixheaacd_get_abs_leader_tbl(const UWORD32 *table,
229
2.87M
                                          UWORD32 code_book_ind, WORD32 size) {
230
2.87M
  WORD32 i;
231
232
3.67M
  for (i = 4; i < size; i += 4) {
233
3.30M
    if (code_book_ind < table[i]) break;
234
3.30M
  }
235
2.87M
  if (i > size) i = size;
236
237
2.87M
  if (code_book_ind < table[i - 2]) i -= 2;
238
2.87M
  if (code_book_ind < table[i - 1]) i--;
239
2.87M
  i--;
240
241
2.87M
  return (i);
242
2.87M
}
243
244
static VOID ixheaacd_gosset_decode_base_index(WORD32 n, UWORD32 code_book_ind,
245
3.15M
                                              WORD32 *ya) {
246
3.15M
  WORD32 i, im, t, sign_code, idx = 0, ks, rank;
247
248
3.15M
  if (n < 2) {
249
15.4M
    for (i = 0; i < 8; i++) ya[i] = 0;
250
1.72M
  } else {
251
1.43M
    switch (n) {
252
648k
      case 2:
253
1.23M
      case 3:
254
1.23M
        i = ixheaacd_get_abs_leader_tbl(ixheaacd_cardinality_offset_table_i3,
255
1.23M
                                        code_book_ind, LEN_I3);
256
1.23M
        idx = ixheaacd_pos_abs_leaders_a3[i];
257
1.23M
        break;
258
204k
      case 4:
259
204k
        i = ixheaacd_get_abs_leader_tbl(ixheaacd_cardinality_offset_tab_i4,
260
204k
                                        code_book_ind, LEN_I4);
261
204k
        idx = ixheaacd_pos_abs_leaders_a4[i];
262
204k
        break;
263
1.43M
    }
264
265
12.9M
    for (i = 0; i < 8; i++) ya[i] = ixheaacd_absolute_leader_tab_da[idx][i];
266
267
1.43M
    t = ixheaacd_iso_code_index_table[idx];
268
1.43M
    im = ixheaacd_iso_code_num_table[idx];
269
1.43M
    ks = ixheaacd_get_abs_leader_tbl(ixheaacd_signed_leader_is + t,
270
1.43M
                                     code_book_ind, im);
271
272
1.43M
    sign_code = 2 * ixheaacd_iso_code_data_table[t + ks];
273
12.9M
    for (i = 7; i >= 0; i--) {
274
11.4M
      ya[i] *= (1 - (sign_code & 2));
275
11.4M
      sign_code >>= 1;
276
11.4M
    }
277
278
1.43M
    rank = code_book_ind - ixheaacd_signed_leader_is[t + ks];
279
280
1.43M
    ixheaacd_gosset_rank_of_permutation(rank, ya);
281
1.43M
  }
282
3.15M
  return;
283
3.15M
}
284
285
VOID ixheaacd_rotated_gosset_mtx_dec(WORD32 qn, WORD32 code_book_idx,
286
3.15M
                                     WORD32 *kv, WORD32 *b) {
287
3.15M
  if (qn <= 4) {
288
3.05M
    ixheaacd_gosset_decode_base_index(qn, code_book_idx, b);
289
3.05M
  } else {
290
102k
    WORD32 i, m, c[8];
291
102k
    WORD32 count = 0;
292
316k
    while (qn > 4) {
293
213k
      count++;
294
213k
      qn -= 2;
295
213k
    }
296
297
102k
    if (count >= 31)
298
0
      m = MAX_32;
299
102k
    else
300
102k
      m = 1 << count;
301
302
102k
    ixheaacd_gosset_decode_base_index(qn, code_book_idx, b);
303
304
102k
    ixheaacd_voronoi_idx_dec(kv, m, c, count);
305
306
926k
    for (i = 0; i < 8; i++) {
307
823k
      b[i] =
308
823k
          ixheaac_add32_sat(ixheaac_sat64_32((WORD64)m * (WORD64)b[i]), c[i]);
309
823k
    }
310
102k
  }
311
3.15M
  return;
312
3.15M
}