Coverage Report

Created: 2026-01-17 06:32

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/aac/libSACenc/src/sacenc_nlc_enc.cpp
Line
Count
Source
1
/* -----------------------------------------------------------------------------
2
Software License for The Fraunhofer FDK AAC Codec Library for Android
3
4
© Copyright  1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
5
Forschung e.V. All rights reserved.
6
7
 1.    INTRODUCTION
8
The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
9
that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
10
scheme for digital audio. This FDK AAC Codec software is intended to be used on
11
a wide variety of Android devices.
12
13
AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
14
general perceptual audio codecs. AAC-ELD is considered the best-performing
15
full-bandwidth communications codec by independent studies and is widely
16
deployed. AAC has been standardized by ISO and IEC as part of the MPEG
17
specifications.
18
19
Patent licenses for necessary patent claims for the FDK AAC Codec (including
20
those of Fraunhofer) may be obtained through Via Licensing
21
(www.vialicensing.com) or through the respective patent owners individually for
22
the purpose of encoding or decoding bit streams in products that are compliant
23
with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
24
Android devices already license these patent claims through Via Licensing or
25
directly from the patent owners, and therefore FDK AAC Codec software may
26
already be covered under those patent licenses when it is used for those
27
licensed purposes only.
28
29
Commercially-licensed AAC software libraries, including floating-point versions
30
with enhanced sound quality, are also available from Fraunhofer. Users are
31
encouraged to check the Fraunhofer website for additional applications
32
information and documentation.
33
34
2.    COPYRIGHT LICENSE
35
36
Redistribution and use in source and binary forms, with or without modification,
37
are permitted without payment of copyright license fees provided that you
38
satisfy the following conditions:
39
40
You must retain the complete text of this software license in redistributions of
41
the FDK AAC Codec or your modifications thereto in source code form.
42
43
You must retain the complete text of this software license in the documentation
44
and/or other materials provided with redistributions of the FDK AAC Codec or
45
your modifications thereto in binary form. You must make available free of
46
charge copies of the complete source code of the FDK AAC Codec and your
47
modifications thereto to recipients of copies in binary form.
48
49
The name of Fraunhofer may not be used to endorse or promote products derived
50
from this library without prior written permission.
51
52
You may not charge copyright license fees for anyone to use, copy or distribute
53
the FDK AAC Codec software or your modifications thereto.
54
55
Your modified versions of the FDK AAC Codec must carry prominent notices stating
56
that you changed the software and the date of any change. For modified versions
57
of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
58
must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
59
AAC Codec Library for Android."
60
61
3.    NO PATENT LICENSE
62
63
NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
64
limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
65
Fraunhofer provides no warranty of patent non-infringement with respect to this
66
software.
67
68
You may use this FDK AAC Codec software or modifications thereto only for
69
purposes that are authorized by appropriate patent licenses.
70
71
4.    DISCLAIMER
72
73
This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
74
holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
75
including but not limited to the implied warranties of merchantability and
76
fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
77
CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
78
or consequential damages, including but not limited to procurement of substitute
79
goods or services; loss of use, data, or profits, or business interruption,
80
however caused and on any theory of liability, whether in contract, strict
81
liability, or tort (including negligence), arising in any way out of the use of
82
this software, even if advised of the possibility of such damage.
83
84
5.    CONTACT INFORMATION
85
86
Fraunhofer Institute for Integrated Circuits IIS
87
Attention: Audio and Multimedia Departments - FDK AAC LL
88
Am Wolfsmantel 33
89
91058 Erlangen, Germany
90
91
www.iis.fraunhofer.de/amm
92
amm-info@iis.fraunhofer.de
93
----------------------------------------------------------------------------- */
94
95
/*********************** MPEG surround encoder library *************************
96
97
   Author(s):   Karsten Linzmeier
98
99
   Description: Noiseless Coding
100
                Huffman encoder
101
102
*******************************************************************************/
103
104
/* Includes ******************************************************************/
105
#include "sacenc_nlc_enc.h"
106
107
#include "genericStds.h"
108
#include "fixpoint_math.h"
109
110
#include "sacenc_const.h"
111
#include "sacenc_huff_tab.h"
112
#include "sacenc_paramextract.h"
113
114
/* Defines *******************************************************************/
115
0
#define PAIR_SHIFT 4
116
0
#define PAIR_MASK 0xf
117
118
#define PBC_MIN_BANDS 5
119
120
typedef enum {
121
  BACKWARDS = 0x0,
122
  FORWARDS = 0x1
123
124
} DIRECTION;
125
126
typedef enum {
127
  DIFF_FREQ = 0x0,
128
  DIFF_TIME = 0x1
129
130
} DIFF_TYPE;
131
132
typedef enum {
133
  HUFF_1D = 0x0,
134
  HUFF_2D = 0x1
135
136
} CODING_SCHEME;
137
138
typedef enum {
139
  FREQ_PAIR = 0x0,
140
  TIME_PAIR = 0x1
141
142
} PAIRING;
143
144
/* Data Types ****************************************************************/
145
146
/* Constants *****************************************************************/
147
static const UCHAR lavHuffVal[4] = {0, 2, 6, 7};
148
static const UCHAR lavHuffLen[4] = {1, 2, 3, 3};
149
150
static const UCHAR lav_step_CLD[] = {0, 0, 0, 0, 1, 1, 2, 2, 3, 3};
151
static const UCHAR lav_step_ICC[] = {0, 0, 1, 1, 2, 2, 3, 3};
152
153
/* Function / Class Declarations *********************************************/
154
155
/* Function / Class Definition ***********************************************/
156
static void split_lsb(const SHORT *const in_data, SHORT offset,
157
                      const INT num_val, SHORT *const out_data_lsb,
158
0
                      SHORT *const out_data_msb) {
159
0
  int i;
160
161
0
  for (i = 0; i < num_val; i++) {
162
0
    SHORT val = in_data[i] + offset;
163
0
    if (out_data_lsb != NULL) out_data_lsb[i] = val & 0x0001;
164
0
    if (out_data_msb != NULL) out_data_msb[i] = val >> 1;
165
0
  }
166
0
}
167
168
static void apply_lsb_coding(HANDLE_FDK_BITSTREAM strm,
169
                             const SHORT *const in_data_lsb, const UINT num_lsb,
170
0
                             const INT num_val) {
171
0
  int i;
172
173
0
  for (i = 0; i < num_val; i++) {
174
0
    FDKwriteBits(strm, in_data_lsb[i], num_lsb);
175
0
  }
176
0
}
177
178
static void calc_diff_freq(const SHORT *const in_data, SHORT *const out_data,
179
0
                           const INT num_val) {
180
0
  int i;
181
0
  out_data[0] = in_data[0];
182
183
0
  for (i = 1; i < num_val; i++) {
184
0
    out_data[i] = in_data[i] - in_data[i - 1];
185
0
  }
186
0
}
187
188
static void calc_diff_time(const SHORT *const in_data,
189
                           const SHORT *const prev_data, SHORT *const out_data,
190
0
                           const INT num_val) {
191
0
  int i;
192
0
  out_data[0] = in_data[0];
193
0
  out_data[1] = prev_data[0];
194
195
0
  for (i = 0; i < num_val; i++) {
196
0
    out_data[i + 2] = in_data[i] - prev_data[i];
197
0
  }
198
0
}
199
200
0
static INT sym_check(SHORT data[2], const INT lav, SHORT *const pSym_bits) {
201
0
  UCHAR symBits = 0;
202
0
  int sum_val = data[0] + data[1];
203
0
  int diff_val = data[0] - data[1];
204
0
  int num_sbits = 0;
205
206
0
  if (sum_val != 0) {
207
0
    int sum_neg = (sum_val < 0) ? 1 : 0;
208
0
    if (sum_neg) {
209
0
      sum_val = -sum_val;
210
0
      diff_val = -diff_val;
211
0
    }
212
0
    symBits = (symBits << 1) | sum_neg;
213
0
    num_sbits++;
214
0
  }
215
216
0
  if (diff_val != 0) {
217
0
    int diff_neg = (diff_val < 0) ? 1 : 0;
218
0
    if (diff_neg) {
219
0
      diff_val = -diff_val;
220
0
    }
221
0
    symBits = (symBits << 1) | diff_neg;
222
0
    num_sbits++;
223
0
  }
224
225
0
  if (pSym_bits != NULL) {
226
0
    *pSym_bits = symBits;
227
0
  }
228
229
0
  if (sum_val % 2) {
230
0
    data[0] = lav - sum_val / 2;
231
0
    data[1] = lav - diff_val / 2;
232
0
  } else {
233
0
    data[0] = sum_val / 2;
234
0
    data[1] = diff_val / 2;
235
0
  }
236
237
0
  return num_sbits;
238
0
}
239
240
0
static INT ilog2(UINT i) {
241
0
  int l = 0;
242
243
0
  if (i) i--;
244
0
  while (i > 0) {
245
0
    i >>= 1;
246
0
    l++;
247
0
  }
248
249
0
  return l;
250
0
}
251
252
0
static SHORT calc_pcm_bits(const SHORT num_val, const SHORT num_levels) {
253
0
  SHORT num_complete_chunks = 0, rest_chunk_size = 0;
254
0
  SHORT max_grp_len = 0, bits_pcm = 0;
255
0
  int chunk_levels, i;
256
257
0
  switch (num_levels) {
258
0
    case 3:
259
0
      max_grp_len = 5;
260
0
      break;
261
0
    case 6:
262
0
      max_grp_len = 5;
263
0
      break;
264
0
    case 7:
265
0
      max_grp_len = 6;
266
0
      break;
267
0
    case 11:
268
0
      max_grp_len = 2;
269
0
      break;
270
0
    case 13:
271
0
      max_grp_len = 4;
272
0
      break;
273
0
    case 19:
274
0
      max_grp_len = 4;
275
0
      break;
276
0
    case 25:
277
0
      max_grp_len = 3;
278
0
      break;
279
0
    case 51:
280
0
      max_grp_len = 4;
281
0
      break;
282
0
    default:
283
0
      max_grp_len = 1;
284
0
  }
285
286
0
  num_complete_chunks = num_val / max_grp_len;
287
0
  rest_chunk_size = num_val % max_grp_len;
288
289
0
  chunk_levels = 1;
290
0
  for (i = 1; i <= max_grp_len; i++) {
291
0
    chunk_levels *= num_levels;
292
0
  }
293
294
0
  bits_pcm = (SHORT)(ilog2(chunk_levels) * num_complete_chunks);
295
0
  bits_pcm += (SHORT)(ilog2(num_levels) * rest_chunk_size);
296
297
0
  return bits_pcm;
298
0
}
299
300
static void apply_pcm_coding(HANDLE_FDK_BITSTREAM strm,
301
                             const SHORT *const in_data_1,
302
                             const SHORT *const in_data_2, const SHORT offset,
303
0
                             const SHORT num_val, const SHORT num_levels) {
304
0
  SHORT i = 0, j = 0, idx = 0;
305
0
  SHORT max_grp_len = 0, grp_len = 0, next_val = 0;
306
0
  int grp_val = 0, chunk_levels = 0;
307
308
0
  SHORT pcm_chunk_size[7] = {0};
309
310
0
  switch (num_levels) {
311
0
    case 3:
312
0
      max_grp_len = 5;
313
0
      break;
314
0
    case 5:
315
0
      max_grp_len = 3;
316
0
      break;
317
0
    case 6:
318
0
      max_grp_len = 5;
319
0
      break;
320
0
    case 7:
321
0
      max_grp_len = 6;
322
0
      break;
323
0
    case 9:
324
0
      max_grp_len = 5;
325
0
      break;
326
0
    case 11:
327
0
      max_grp_len = 2;
328
0
      break;
329
0
    case 13:
330
0
      max_grp_len = 4;
331
0
      break;
332
0
    case 19:
333
0
      max_grp_len = 4;
334
0
      break;
335
0
    case 25:
336
0
      max_grp_len = 3;
337
0
      break;
338
0
    case 51:
339
0
      max_grp_len = 4;
340
0
      break;
341
0
    default:
342
0
      max_grp_len = 1;
343
0
  }
344
345
0
  chunk_levels = 1;
346
0
  for (i = 1; i <= max_grp_len; i++) {
347
0
    chunk_levels *= num_levels;
348
0
    pcm_chunk_size[i] = ilog2(chunk_levels);
349
0
  }
350
351
0
  for (i = 0; i < num_val; i += max_grp_len) {
352
0
    grp_len = FDKmin(max_grp_len, num_val - i);
353
0
    grp_val = 0;
354
0
    for (j = 0; j < grp_len; j++) {
355
0
      idx = i + j;
356
0
      if (in_data_2 == NULL) {
357
0
        next_val = in_data_1[idx];
358
0
      } else if (in_data_1 == NULL) {
359
0
        next_val = in_data_2[idx];
360
0
      } else {
361
0
        next_val = ((idx % 2) ? in_data_2[idx / 2] : in_data_1[idx / 2]);
362
0
      }
363
0
      next_val += offset;
364
0
      grp_val = grp_val * num_levels + next_val;
365
0
    }
366
367
0
    FDKwriteBits(strm, grp_val, pcm_chunk_size[grp_len]);
368
0
  }
369
0
}
370
371
static UINT huff_enc_1D(HANDLE_FDK_BITSTREAM strm, const DATA_TYPE data_type,
372
                        const INT dim1, SHORT *const in_data,
373
0
                        const SHORT num_val, const SHORT p0_flag) {
374
0
  int i, offset = 0;
375
0
  UINT huffBits = 0;
376
377
0
  HUFF_ENTRY part0 = {0};
378
0
  const HUFF_ENTRY *pHuffTab = NULL;
379
380
0
  switch (data_type) {
381
0
    case t_CLD:
382
0
      pHuffTab = fdk_sacenc_huffCLDTab.h1D[dim1];
383
0
      break;
384
0
    case t_ICC:
385
0
      pHuffTab = fdk_sacenc_huffICCTab.h1D[dim1];
386
0
      break;
387
0
  }
388
389
0
  if (p0_flag) {
390
0
    switch (data_type) {
391
0
      case t_CLD:
392
0
        part0 = fdk_sacenc_huffPart0Tab.cld[in_data[0]];
393
0
        break;
394
0
      case t_ICC:
395
0
        part0 = fdk_sacenc_huffPart0Tab.icc[in_data[0]];
396
0
        break;
397
0
    }
398
0
    huffBits += FDKwriteBits(strm, HUFF_VALUE(part0), HUFF_LENGTH(part0));
399
0
    offset = 1;
400
0
  }
401
402
0
  for (i = offset; i < num_val; i++) {
403
0
    int id_sign = 0;
404
0
    int id = in_data[i];
405
406
0
    if (id != 0) {
407
0
      id_sign = 0;
408
0
      if (id < 0) {
409
0
        id = -id;
410
0
        id_sign = 1;
411
0
      }
412
0
    }
413
414
0
    huffBits +=
415
0
        FDKwriteBits(strm, HUFF_VALUE(pHuffTab[id]), HUFF_LENGTH(pHuffTab[id]));
416
417
0
    if (id != 0) {
418
0
      huffBits += FDKwriteBits(strm, id_sign, 1);
419
0
    }
420
0
  } /* for i */
421
422
0
  return huffBits;
423
0
}
424
425
static void getHuffEntry(const INT lav, const DATA_TYPE data_type, const INT i,
426
                         const SHORT tab_idx_2D[2], const SHORT in_data[][2],
427
0
                         HUFF_ENTRY *const pEntry, HUFF_ENTRY *const pEscape) {
428
0
  const HUFF_CLD_TAB_2D *pCLD2dTab =
429
0
      &fdk_sacenc_huffCLDTab.h2D[tab_idx_2D[0]][tab_idx_2D[1]];
430
0
  const HUFF_ICC_TAB_2D *pICC2dTab =
431
0
      &fdk_sacenc_huffICCTab.h2D[tab_idx_2D[0]][tab_idx_2D[1]];
432
433
0
  switch (lav) {
434
0
    case 1: {
435
0
      const LAV1_2D *pLav1 = NULL;
436
0
      switch (data_type) {
437
0
        case t_CLD:
438
0
          pLav1 = NULL;
439
0
          break;
440
0
        case t_ICC:
441
0
          pLav1 = &pICC2dTab->lav1;
442
0
          break;
443
0
      }
444
0
      if (pLav1 != NULL) {
445
0
        *pEntry = pLav1->entry[in_data[i][0]][in_data[i][1]];
446
0
        *pEscape = pLav1->escape;
447
0
      }
448
0
    } break;
449
0
    case 3: {
450
0
      const LAV3_2D *pLav3 = NULL;
451
0
      switch (data_type) {
452
0
        case t_CLD:
453
0
          pLav3 = &pCLD2dTab->lav3;
454
0
          break;
455
0
        case t_ICC:
456
0
          pLav3 = &pICC2dTab->lav3;
457
0
          break;
458
0
      }
459
0
      if (pLav3 != NULL) {
460
0
        *pEntry = pLav3->entry[in_data[i][0]][in_data[i][1]];
461
0
        *pEscape = pLav3->escape;
462
0
      }
463
0
    } break;
464
0
    case 5: {
465
0
      const LAV5_2D *pLav5 = NULL;
466
0
      switch (data_type) {
467
0
        case t_CLD:
468
0
          pLav5 = &pCLD2dTab->lav5;
469
0
          break;
470
0
        case t_ICC:
471
0
          pLav5 = &pICC2dTab->lav5;
472
0
          break;
473
0
      }
474
0
      if (pLav5 != NULL) {
475
0
        *pEntry = pLav5->entry[in_data[i][0]][in_data[i][1]];
476
0
        *pEscape = pLav5->escape;
477
0
      }
478
0
    } break;
479
0
    case 7: {
480
0
      const LAV7_2D *pLav7 = NULL;
481
0
      switch (data_type) {
482
0
        case t_CLD:
483
0
          pLav7 = &pCLD2dTab->lav7;
484
0
          break;
485
0
        case t_ICC:
486
0
          pLav7 = &pICC2dTab->lav7;
487
0
          break;
488
0
      }
489
0
      if (pLav7 != NULL) {
490
0
        *pEntry = pLav7->entry[in_data[i][0]][in_data[i][1]];
491
0
        *pEscape = pLav7->escape;
492
0
      }
493
0
    } break;
494
0
    case 9: {
495
0
      const LAV9_2D *pLav9 = NULL;
496
0
      switch (data_type) {
497
0
        case t_CLD:
498
0
          pLav9 = &pCLD2dTab->lav9;
499
0
          break;
500
0
        case t_ICC:
501
0
          pLav9 = NULL;
502
0
          break;
503
0
      }
504
0
      if (pLav9 != NULL) {
505
0
        *pEntry = pLav9->entry[in_data[i][0]][in_data[i][1]];
506
0
        *pEscape = pLav9->escape;
507
0
      }
508
0
    } break;
509
0
  }
510
0
}
511
512
static UINT huff_enc_2D(HANDLE_FDK_BITSTREAM strm, const DATA_TYPE data_type,
513
                        SHORT tab_idx_2D[2], SHORT lav_idx, SHORT in_data[][2],
514
0
                        SHORT num_val, SHORT stride, SHORT *p0_data[2]) {
515
0
  SHORT i = 0, lav = 0, num_sbits = 0, sym_bits = 0, escIdx = 0;
516
0
  SHORT esc_data[2][MAXBANDS] = {{0}};
517
518
0
  UINT huffBits = 0;
519
520
0
  const HUFF_ENTRY *pHuffEntry = NULL;
521
522
0
  switch (data_type) {
523
0
    case t_CLD:
524
0
      lav = 2 * lav_idx + 3; /* LAV */
525
0
      pHuffEntry = fdk_sacenc_huffPart0Tab.cld;
526
0
      break;
527
0
    case t_ICC:
528
0
      lav = 2 * lav_idx + 1; /* LAV */
529
0
      pHuffEntry = fdk_sacenc_huffPart0Tab.icc;
530
0
      break;
531
0
  }
532
533
  /* Partition 0 */
534
0
  if (p0_data[0] != NULL) {
535
0
    HUFF_ENTRY entry = pHuffEntry[*p0_data[0]];
536
0
    huffBits += FDKwriteBits(strm, HUFF_VALUE(entry), HUFF_LENGTH(entry));
537
0
  }
538
0
  if (p0_data[1] != NULL) {
539
0
    HUFF_ENTRY entry = pHuffEntry[*p0_data[1]];
540
0
    huffBits += FDKwriteBits(strm, HUFF_VALUE(entry), HUFF_LENGTH(entry));
541
0
  }
542
543
0
  for (i = 0; i < num_val; i += stride) {
544
0
    HUFF_ENTRY entry = {0};
545
0
    HUFF_ENTRY escape = {0};
546
547
0
    esc_data[0][escIdx] = in_data[i][0] + lav;
548
0
    esc_data[1][escIdx] = in_data[i][1] + lav;
549
550
0
    num_sbits = sym_check(in_data[i], lav, &sym_bits);
551
552
0
    getHuffEntry(lav, data_type, i, tab_idx_2D, in_data, &entry, &escape);
553
554
0
    huffBits += FDKwriteBits(strm, HUFF_VALUE(entry), HUFF_LENGTH(entry));
555
556
0
    if ((HUFF_VALUE(entry) == HUFF_VALUE(escape)) &&
557
0
        (HUFF_LENGTH(entry) == HUFF_LENGTH(escape))) {
558
0
      escIdx++;
559
0
    } else {
560
0
      huffBits += FDKwriteBits(strm, sym_bits, num_sbits);
561
0
    }
562
0
  } /* for i */
563
564
0
  if (escIdx > 0) {
565
0
    huffBits += calc_pcm_bits(2 * escIdx, (2 * lav + 1));
566
0
    if (strm != NULL) {
567
0
      apply_pcm_coding(strm, esc_data[0], esc_data[1], 0 /*offset*/, 2 * escIdx,
568
0
                       (2 * lav + 1));
569
0
    }
570
0
  }
571
572
0
  return huffBits;
573
0
}
574
575
0
static SCHAR get_next_lav_step(const INT lav, const DATA_TYPE data_type) {
576
0
  SCHAR lav_step = 0;
577
578
0
  switch (data_type) {
579
0
    case t_CLD:
580
0
      lav_step = (lav > 9) ? -1 : lav_step_CLD[lav];
581
0
      break;
582
0
    case t_ICC:
583
0
      lav_step = (lav > 7) ? -1 : lav_step_ICC[lav];
584
0
      break;
585
0
  }
586
587
0
  return lav_step;
588
0
}
589
590
0
static INT diff_type_offset(const DIFF_TYPE diff_type) {
591
0
  int offset = 0;
592
0
  switch (diff_type) {
593
0
    case DIFF_FREQ:
594
0
      offset = 0;
595
0
      break;
596
0
    case DIFF_TIME:
597
0
      offset = 2;
598
0
      break;
599
0
  }
600
0
  return offset;
601
0
}
602
603
static SHORT calc_huff_bits(SHORT *in_data_1, SHORT *in_data_2,
604
                            const DATA_TYPE data_type,
605
                            const DIFF_TYPE diff_type_1,
606
                            const DIFF_TYPE diff_type_2, const SHORT num_val,
607
0
                            SHORT *const lav_idx, SHORT *const cdg_scheme) {
608
0
  SHORT tab_idx_2D[2][2] = {{0}};
609
0
  SHORT tab_idx_1D[2] = {0};
610
0
  SHORT df_rest_flag[2] = {0};
611
0
  SHORT p0_flag[2] = {0};
612
613
0
  SHORT pair_vec[MAXBANDS][2] = {{0}};
614
615
0
  SHORT *p0_data_1[2] = {NULL};
616
0
  SHORT *p0_data_2[2] = {NULL};
617
618
0
  SHORT i = 0;
619
0
  SHORT lav_fp[2] = {0};
620
621
0
  SHORT bit_count_1D = 0;
622
0
  SHORT bit_count_2D_freq = 0;
623
0
  SHORT bit_count_min = 0;
624
625
0
  SHORT num_val_1_short = 0;
626
0
  SHORT num_val_2_short = 0;
627
628
0
  SHORT *in_data_1_short = NULL;
629
0
  SHORT *in_data_2_short = NULL;
630
631
  /* 1D Huffman coding */
632
0
  bit_count_1D = 1; /* HUFF_1D */
633
634
0
  num_val_1_short = num_val;
635
0
  num_val_2_short = num_val;
636
637
0
  if (in_data_1 != NULL) {
638
0
    in_data_1_short = in_data_1 + diff_type_offset(diff_type_1);
639
0
  }
640
0
  if (in_data_2 != NULL) {
641
0
    in_data_2_short = in_data_2 + diff_type_offset(diff_type_2);
642
0
  }
643
644
0
  p0_flag[0] = (diff_type_1 == DIFF_FREQ);
645
0
  p0_flag[1] = (diff_type_2 == DIFF_FREQ);
646
647
0
  tab_idx_1D[0] = (diff_type_1 == DIFF_FREQ) ? 0 : 1;
648
0
  tab_idx_1D[1] = (diff_type_2 == DIFF_FREQ) ? 0 : 1;
649
650
0
  if (in_data_1 != NULL) {
651
0
    bit_count_1D += huff_enc_1D(NULL, data_type, tab_idx_1D[0], in_data_1_short,
652
0
                                num_val_1_short, p0_flag[0]);
653
0
  }
654
0
  if (in_data_2 != NULL) {
655
0
    bit_count_1D += huff_enc_1D(NULL, data_type, tab_idx_1D[1], in_data_2_short,
656
0
                                num_val_2_short, p0_flag[1]);
657
0
  }
658
659
0
  bit_count_min = bit_count_1D;
660
0
  *cdg_scheme = HUFF_1D << PAIR_SHIFT;
661
0
  lav_idx[0] = lav_idx[1] = -1;
662
663
  /* Huffman 2D frequency pairs */
664
0
  bit_count_2D_freq = 1; /* HUFF_2D */
665
666
0
  num_val_1_short = num_val;
667
0
  num_val_2_short = num_val;
668
669
0
  if (in_data_1 != NULL) {
670
0
    in_data_1_short = in_data_1 + diff_type_offset(diff_type_1);
671
0
  }
672
0
  if (in_data_2 != NULL) {
673
0
    in_data_2_short = in_data_2 + diff_type_offset(diff_type_2);
674
0
  }
675
676
0
  lav_fp[0] = lav_fp[1] = 0;
677
678
0
  p0_data_1[0] = NULL;
679
0
  p0_data_1[1] = NULL;
680
0
  p0_data_2[0] = NULL;
681
0
  p0_data_2[1] = NULL;
682
683
0
  if (in_data_1 != NULL) {
684
0
    if (diff_type_1 == DIFF_FREQ) {
685
0
      p0_data_1[0] = &in_data_1[0];
686
0
      p0_data_1[1] = NULL;
687
688
0
      num_val_1_short -= 1;
689
0
      in_data_1_short += 1;
690
0
    }
691
692
0
    df_rest_flag[0] = num_val_1_short % 2;
693
694
0
    if (df_rest_flag[0]) num_val_1_short -= 1;
695
696
0
    for (i = 0; i < num_val_1_short - 1; i += 2) {
697
0
      pair_vec[i][0] = in_data_1_short[i];
698
0
      pair_vec[i][1] = in_data_1_short[i + 1];
699
700
0
      lav_fp[0] = FDKmax(lav_fp[0], fAbs(pair_vec[i][0]));
701
0
      lav_fp[0] = FDKmax(lav_fp[0], fAbs(pair_vec[i][1]));
702
0
    }
703
704
0
    tab_idx_2D[0][0] = (diff_type_1 == DIFF_TIME) ? 1 : 0;
705
0
    tab_idx_2D[0][1] = 0;
706
707
0
    tab_idx_1D[0] = (diff_type_1 == DIFF_FREQ) ? 0 : 1;
708
709
0
    lav_fp[0] = get_next_lav_step(lav_fp[0], data_type);
710
711
0
    if (lav_fp[0] != -1) bit_count_2D_freq += lavHuffLen[lav_fp[0]];
712
0
  }
713
714
0
  if (in_data_2 != NULL) {
715
0
    if (diff_type_2 == DIFF_FREQ) {
716
0
      p0_data_2[0] = NULL;
717
0
      p0_data_2[1] = &in_data_2[0];
718
719
0
      num_val_2_short -= 1;
720
0
      in_data_2_short += 1;
721
0
    }
722
723
0
    df_rest_flag[1] = num_val_2_short % 2;
724
725
0
    if (df_rest_flag[1]) num_val_2_short -= 1;
726
727
0
    for (i = 0; i < num_val_2_short - 1; i += 2) {
728
0
      pair_vec[i + 1][0] = in_data_2_short[i];
729
0
      pair_vec[i + 1][1] = in_data_2_short[i + 1];
730
731
0
      lav_fp[1] = FDKmax(lav_fp[1], fAbs(pair_vec[i + 1][0]));
732
0
      lav_fp[1] = FDKmax(lav_fp[1], fAbs(pair_vec[i + 1][1]));
733
0
    }
734
735
0
    tab_idx_2D[1][0] = (diff_type_2 == DIFF_TIME) ? 1 : 0;
736
0
    tab_idx_2D[1][1] = 0;
737
738
0
    tab_idx_1D[1] = (diff_type_2 == DIFF_FREQ) ? 0 : 1;
739
740
0
    lav_fp[1] = get_next_lav_step(lav_fp[1], data_type);
741
742
0
    if (lav_fp[1] != -1) bit_count_2D_freq += lavHuffLen[lav_fp[1]];
743
0
  }
744
745
0
  if ((lav_fp[0] != -1) && (lav_fp[1] != -1)) {
746
0
    if (in_data_1 != NULL) {
747
0
      bit_count_2D_freq +=
748
0
          huff_enc_2D(NULL, data_type, tab_idx_2D[0], lav_fp[0], pair_vec,
749
0
                      num_val_1_short, 2, p0_data_1);
750
0
    }
751
0
    if (in_data_2 != NULL) {
752
0
      bit_count_2D_freq +=
753
0
          huff_enc_2D(NULL, data_type, tab_idx_2D[1], lav_fp[1], pair_vec + 1,
754
0
                      num_val_2_short, 2, p0_data_2);
755
0
    }
756
0
    if (in_data_1 != NULL) {
757
0
      if (df_rest_flag[0])
758
0
        bit_count_2D_freq +=
759
0
            huff_enc_1D(NULL, data_type, tab_idx_1D[0],
760
0
                        in_data_1_short + num_val_1_short, 1, 0);
761
0
    }
762
0
    if (in_data_2 != NULL) {
763
0
      if (df_rest_flag[1])
764
0
        bit_count_2D_freq +=
765
0
            huff_enc_1D(NULL, data_type, tab_idx_1D[1],
766
0
                        in_data_2_short + num_val_2_short, 1, 0);
767
0
    }
768
769
0
    if (bit_count_2D_freq < bit_count_min) {
770
0
      bit_count_min = bit_count_2D_freq;
771
0
      *cdg_scheme = HUFF_2D << PAIR_SHIFT | FREQ_PAIR;
772
0
      lav_idx[0] = lav_fp[0];
773
0
      lav_idx[1] = lav_fp[1];
774
0
    }
775
0
  }
776
777
0
  return bit_count_min;
778
0
}
779
780
static void apply_huff_coding(HANDLE_FDK_BITSTREAM strm, SHORT *const in_data_1,
781
                              SHORT *const in_data_2, const DATA_TYPE data_type,
782
                              const DIFF_TYPE diff_type_1,
783
                              const DIFF_TYPE diff_type_2, const SHORT num_val,
784
                              const SHORT *const lav_idx,
785
0
                              const SHORT cdg_scheme) {
786
0
  SHORT tab_idx_2D[2][2] = {{0}};
787
0
  SHORT tab_idx_1D[2] = {0};
788
0
  SHORT df_rest_flag[2] = {0};
789
0
  SHORT p0_flag[2] = {0};
790
791
0
  SHORT pair_vec[MAXBANDS][2] = {{0}};
792
793
0
  SHORT *p0_data_1[2] = {NULL};
794
0
  SHORT *p0_data_2[2] = {NULL};
795
796
0
  SHORT i = 0;
797
798
0
  SHORT num_val_1_short = num_val;
799
0
  SHORT num_val_2_short = num_val;
800
801
0
  SHORT *in_data_1_short = NULL;
802
0
  SHORT *in_data_2_short = NULL;
803
804
  /* Offset */
805
0
  if (in_data_1 != NULL) {
806
0
    in_data_1_short = in_data_1 + diff_type_offset(diff_type_1);
807
0
  }
808
0
  if (in_data_2 != NULL) {
809
0
    in_data_2_short = in_data_2 + diff_type_offset(diff_type_2);
810
0
  }
811
812
  /* Signalize coding scheme */
813
0
  FDKwriteBits(strm, cdg_scheme >> PAIR_SHIFT, 1);
814
815
0
  switch (cdg_scheme >> PAIR_SHIFT) {
816
0
    case HUFF_1D:
817
818
0
      p0_flag[0] = (diff_type_1 == DIFF_FREQ);
819
0
      p0_flag[1] = (diff_type_2 == DIFF_FREQ);
820
821
0
      tab_idx_1D[0] = (diff_type_1 == DIFF_FREQ) ? 0 : 1;
822
0
      tab_idx_1D[1] = (diff_type_2 == DIFF_FREQ) ? 0 : 1;
823
824
0
      if (in_data_1 != NULL) {
825
0
        huff_enc_1D(strm, data_type, tab_idx_1D[0], in_data_1_short,
826
0
                    num_val_1_short, p0_flag[0]);
827
0
      }
828
0
      if (in_data_2 != NULL) {
829
0
        huff_enc_1D(strm, data_type, tab_idx_1D[1], in_data_2_short,
830
0
                    num_val_2_short, p0_flag[1]);
831
0
      }
832
0
      break; /* HUFF_1D */
833
834
0
    case HUFF_2D:
835
836
0
      switch (cdg_scheme & PAIR_MASK) {
837
0
        case FREQ_PAIR:
838
839
0
          if (in_data_1 != NULL) {
840
0
            if (diff_type_1 == DIFF_FREQ) {
841
0
              p0_data_1[0] = &in_data_1[0];
842
0
              p0_data_1[1] = NULL;
843
844
0
              num_val_1_short -= 1;
845
0
              in_data_1_short += 1;
846
0
            }
847
848
0
            df_rest_flag[0] = num_val_1_short % 2;
849
850
0
            if (df_rest_flag[0]) num_val_1_short -= 1;
851
852
0
            for (i = 0; i < num_val_1_short - 1; i += 2) {
853
0
              pair_vec[i][0] = in_data_1_short[i];
854
0
              pair_vec[i][1] = in_data_1_short[i + 1];
855
0
            }
856
857
0
            tab_idx_2D[0][0] = (diff_type_1 == DIFF_TIME) ? 1 : 0;
858
0
            tab_idx_2D[0][1] = 0;
859
860
0
            tab_idx_1D[0] = (diff_type_1 == DIFF_FREQ) ? 0 : 1;
861
0
          } /* if( in_data_1 != NULL ) */
862
863
0
          if (in_data_2 != NULL) {
864
0
            if (diff_type_2 == DIFF_FREQ) {
865
0
              p0_data_2[0] = NULL;
866
0
              p0_data_2[1] = &in_data_2[0];
867
868
0
              num_val_2_short -= 1;
869
0
              in_data_2_short += 1;
870
0
            }
871
872
0
            df_rest_flag[1] = num_val_2_short % 2;
873
874
0
            if (df_rest_flag[1]) num_val_2_short -= 1;
875
876
0
            for (i = 0; i < num_val_2_short - 1; i += 2) {
877
0
              pair_vec[i + 1][0] = in_data_2_short[i];
878
0
              pair_vec[i + 1][1] = in_data_2_short[i + 1];
879
0
            }
880
881
0
            tab_idx_2D[1][0] = (diff_type_2 == DIFF_TIME) ? 1 : 0;
882
0
            tab_idx_2D[1][1] = 0;
883
884
0
            tab_idx_1D[1] = (diff_type_2 == DIFF_FREQ) ? 0 : 1;
885
0
          } /* if( in_data_2 != NULL ) */
886
887
0
          if (in_data_1 != NULL) {
888
0
            FDKwriteBits(strm, lavHuffVal[lav_idx[0]], lavHuffLen[lav_idx[0]]);
889
0
            huff_enc_2D(strm, data_type, tab_idx_2D[0], lav_idx[0], pair_vec,
890
0
                        num_val_1_short, 2, p0_data_1);
891
0
            if (df_rest_flag[0]) {
892
0
              huff_enc_1D(strm, data_type, tab_idx_1D[0],
893
0
                          in_data_1_short + num_val_1_short, 1, 0);
894
0
            }
895
0
          }
896
0
          if (in_data_2 != NULL) {
897
0
            FDKwriteBits(strm, lavHuffVal[lav_idx[1]], lavHuffLen[lav_idx[1]]);
898
0
            huff_enc_2D(strm, data_type, tab_idx_2D[1], lav_idx[1],
899
0
                        pair_vec + 1, num_val_2_short, 2, p0_data_2);
900
0
            if (df_rest_flag[1]) {
901
0
              huff_enc_1D(strm, data_type, tab_idx_1D[1],
902
0
                          in_data_2_short + num_val_2_short, 1, 0);
903
0
            }
904
0
          }
905
0
          break; /* FREQ_PAIR */
906
907
0
        case TIME_PAIR:
908
909
0
          if ((diff_type_1 == DIFF_FREQ) || (diff_type_2 == DIFF_FREQ)) {
910
0
            p0_data_1[0] = &in_data_1[0];
911
0
            p0_data_1[1] = &in_data_2[0];
912
913
0
            in_data_1_short += 1;
914
0
            in_data_2_short += 1;
915
916
0
            num_val_1_short -= 1;
917
0
          }
918
919
0
          for (i = 0; i < num_val_1_short; i++) {
920
0
            pair_vec[i][0] = in_data_1_short[i];
921
0
            pair_vec[i][1] = in_data_2_short[i];
922
0
          }
923
924
0
          tab_idx_2D[0][0] =
925
0
              ((diff_type_1 == DIFF_TIME) || (diff_type_2 == DIFF_TIME)) ? 1
926
0
                                                                         : 0;
927
0
          tab_idx_2D[0][1] = 1;
928
929
0
          FDKwriteBits(strm, lavHuffVal[lav_idx[0]], lavHuffLen[lav_idx[0]]);
930
931
0
          huff_enc_2D(strm, data_type, tab_idx_2D[0], lav_idx[0], pair_vec,
932
0
                      num_val_1_short, 1, p0_data_1);
933
934
0
          break; /* TIME_PAIR */
935
0
      }          /* switch( cdg_scheme & PAIR_MASK ) */
936
937
0
      break; /* HUFF_2D */
938
939
0
    default:
940
0
      break;
941
0
  } /* switch( cdg_scheme >> PAIR_SHIFT ) */
942
0
}
943
944
INT fdk_sacenc_ecDataPairEnc(HANDLE_FDK_BITSTREAM strm,
945
                             SHORT aaInData[][MAXBANDS],
946
                             SHORT aHistory[MAXBANDS],
947
                             const DATA_TYPE data_type, const INT setIdx,
948
                             const INT startBand, const INT dataBands,
949
                             const INT coarse_flag,
950
0
                             const INT independency_flag) {
951
0
  SHORT reset = 0, pb = 0;
952
0
  SHORT quant_levels = 0, quant_offset = 0, num_pcm_val = 0;
953
954
0
  SHORT splitLsb_flag = 0;
955
0
  SHORT pcmCoding_flag = 0;
956
957
0
  SHORT allowDiffTimeBack_flag = !independency_flag || (setIdx > 0);
958
959
0
  SHORT num_lsb_bits = -1;
960
0
  SHORT num_pcm_bits = -1;
961
962
0
  SHORT quant_data_lsb[2][MAXBANDS];
963
0
  SHORT quant_data_msb[2][MAXBANDS];
964
965
0
  SHORT quant_data_hist_lsb[MAXBANDS];
966
0
  SHORT quant_data_hist_msb[MAXBANDS];
967
968
0
  SHORT data_diff_freq[2][MAXBANDS];
969
0
  SHORT data_diff_time[2][MAXBANDS + 2];
970
971
0
  SHORT *p_quant_data_msb[2];
972
0
  SHORT *p_quant_data_hist_msb = NULL;
973
974
0
  SHORT min_bits_all = 0;
975
0
  SHORT min_found = 0;
976
977
0
  SHORT min_bits_df_df = -1;
978
0
  SHORT min_bits_df_dt = -1;
979
0
  SHORT min_bits_dtbw_df = -1;
980
0
  SHORT min_bits_dt_dt = -1;
981
982
0
  SHORT lav_df_df[2] = {-1, -1};
983
0
  SHORT lav_df_dt[2] = {-1, -1};
984
0
  SHORT lav_dtbw_df[2] = {-1, -1};
985
0
  SHORT lav_dt_dt[2] = {-1, -1};
986
987
0
  SHORT coding_scheme_df_df = 0;
988
0
  SHORT coding_scheme_df_dt = 0;
989
0
  SHORT coding_scheme_dtbw_df = 0;
990
0
  SHORT coding_scheme_dt_dt = 0;
991
992
0
  switch (data_type) {
993
0
    case t_CLD:
994
0
      if (coarse_flag) {
995
0
        splitLsb_flag = 0;
996
0
        quant_levels = 15;
997
0
        quant_offset = 7;
998
0
      } else {
999
0
        splitLsb_flag = 0;
1000
0
        quant_levels = 31;
1001
0
        quant_offset = 15;
1002
0
      }
1003
0
      break;
1004
0
    case t_ICC:
1005
0
      if (coarse_flag) {
1006
0
        splitLsb_flag = 0;
1007
0
        quant_levels = 4;
1008
0
        quant_offset = 0;
1009
0
      } else {
1010
0
        splitLsb_flag = 0;
1011
0
        quant_levels = 8;
1012
0
        quant_offset = 0;
1013
0
      }
1014
0
      break;
1015
0
  } /* switch( data_type ) */
1016
1017
  /* Split off LSB */
1018
0
  if (splitLsb_flag) {
1019
0
    split_lsb(aaInData[setIdx] + startBand, quant_offset, dataBands,
1020
0
              quant_data_lsb[0], quant_data_msb[0]);
1021
1022
0
    split_lsb(aaInData[setIdx + 1] + startBand, quant_offset, dataBands,
1023
0
              quant_data_lsb[1], quant_data_msb[1]);
1024
1025
0
    p_quant_data_msb[0] = quant_data_msb[0];
1026
0
    p_quant_data_msb[1] = quant_data_msb[1];
1027
1028
0
    num_lsb_bits = 2 * dataBands;
1029
0
  } else if (quant_offset != 0) {
1030
0
    for (pb = 0; pb < dataBands; pb++) {
1031
0
      quant_data_msb[0][pb] = aaInData[setIdx][startBand + pb] + quant_offset;
1032
0
      quant_data_msb[1][pb] =
1033
0
          aaInData[setIdx + 1][startBand + pb] + quant_offset;
1034
0
    }
1035
1036
0
    p_quant_data_msb[0] = quant_data_msb[0];
1037
0
    p_quant_data_msb[1] = quant_data_msb[1];
1038
1039
0
    num_lsb_bits = 0;
1040
0
  } else {
1041
0
    p_quant_data_msb[0] = aaInData[setIdx] + startBand;
1042
0
    p_quant_data_msb[1] = aaInData[setIdx + 1] + startBand;
1043
1044
0
    num_lsb_bits = 0;
1045
0
  }
1046
1047
0
  if (allowDiffTimeBack_flag) {
1048
0
    if (splitLsb_flag) {
1049
0
      split_lsb(aHistory + startBand, quant_offset, dataBands,
1050
0
                quant_data_hist_lsb, quant_data_hist_msb);
1051
1052
0
      p_quant_data_hist_msb = quant_data_hist_msb;
1053
0
    } else if (quant_offset != 0) {
1054
0
      for (pb = 0; pb < dataBands; pb++) {
1055
0
        quant_data_hist_msb[pb] = aHistory[startBand + pb] + quant_offset;
1056
0
      }
1057
0
      p_quant_data_hist_msb = quant_data_hist_msb;
1058
0
    } else {
1059
0
      p_quant_data_hist_msb = aHistory + startBand;
1060
0
    }
1061
0
  }
1062
1063
  /* Calculate frequency differences */
1064
0
  calc_diff_freq(p_quant_data_msb[0], data_diff_freq[0], dataBands);
1065
1066
0
  calc_diff_freq(p_quant_data_msb[1], data_diff_freq[1], dataBands);
1067
1068
  /* Calculate time differences */
1069
0
  if (allowDiffTimeBack_flag) {
1070
0
    calc_diff_time(p_quant_data_msb[0], p_quant_data_hist_msb,
1071
0
                   data_diff_time[0], dataBands);
1072
0
  }
1073
1074
0
  calc_diff_time(p_quant_data_msb[1], p_quant_data_msb[0], data_diff_time[1],
1075
0
                 dataBands);
1076
1077
  /* Calculate coding scheme with minumum bit consumption */
1078
1079
  /**********************************************************/
1080
0
  num_pcm_bits = calc_pcm_bits(2 * dataBands, quant_levels);
1081
0
  num_pcm_val = 2 * dataBands;
1082
1083
  /**********************************************************/
1084
1085
0
  min_bits_all = num_pcm_bits;
1086
1087
  /**********************************************************/
1088
  /**********************************************************/
1089
1090
  /**********************************************************/
1091
0
  min_bits_df_df =
1092
0
      calc_huff_bits(data_diff_freq[0], data_diff_freq[1], data_type, DIFF_FREQ,
1093
0
                     DIFF_FREQ, dataBands, lav_df_df, &coding_scheme_df_df);
1094
1095
0
  min_bits_df_df += 2;
1096
1097
0
  min_bits_df_df += num_lsb_bits;
1098
1099
0
  if (min_bits_df_df < min_bits_all) {
1100
0
    min_bits_all = min_bits_df_df;
1101
0
  }
1102
  /**********************************************************/
1103
1104
  /**********************************************************/
1105
0
  min_bits_df_dt =
1106
0
      calc_huff_bits(data_diff_freq[0], data_diff_time[1], data_type, DIFF_FREQ,
1107
0
                     DIFF_TIME, dataBands, lav_df_dt, &coding_scheme_df_dt);
1108
1109
0
  min_bits_df_dt += 2;
1110
1111
0
  min_bits_df_dt += num_lsb_bits;
1112
1113
0
  if (min_bits_df_dt < min_bits_all) {
1114
0
    min_bits_all = min_bits_df_dt;
1115
0
  }
1116
  /**********************************************************/
1117
1118
  /**********************************************************/
1119
  /**********************************************************/
1120
1121
0
  if (allowDiffTimeBack_flag) {
1122
    /**********************************************************/
1123
0
    min_bits_dtbw_df = calc_huff_bits(
1124
0
        data_diff_time[0], data_diff_freq[1], data_type, DIFF_TIME, DIFF_FREQ,
1125
0
        dataBands, lav_dtbw_df, &coding_scheme_dtbw_df);
1126
1127
0
    min_bits_dtbw_df += 2;
1128
1129
0
    min_bits_dtbw_df += num_lsb_bits;
1130
1131
0
    if (min_bits_dtbw_df < min_bits_all) {
1132
0
      min_bits_all = min_bits_dtbw_df;
1133
0
    }
1134
    /**********************************************************/
1135
1136
    /**********************************************************/
1137
0
    min_bits_dt_dt = calc_huff_bits(data_diff_time[0], data_diff_time[1],
1138
0
                                    data_type, DIFF_TIME, DIFF_TIME, dataBands,
1139
0
                                    lav_dt_dt, &coding_scheme_dt_dt);
1140
1141
0
    min_bits_dt_dt += 2;
1142
1143
0
    min_bits_dt_dt += num_lsb_bits;
1144
1145
0
    if (min_bits_dt_dt < min_bits_all) {
1146
0
      min_bits_all = min_bits_dt_dt;
1147
0
    }
1148
    /**********************************************************/
1149
1150
0
  } /* if( allowDiffTimeBack_flag ) */
1151
1152
  /***************************/
1153
  /* Start actual coding now */
1154
  /***************************/
1155
1156
  /* PCM or Diff/Huff Coding? */
1157
0
  pcmCoding_flag = (min_bits_all == num_pcm_bits);
1158
1159
0
  FDKwriteBits(strm, pcmCoding_flag, 1);
1160
1161
0
  if (pcmCoding_flag) {
1162
    /* Grouped PCM Coding */
1163
0
    apply_pcm_coding(strm, aaInData[setIdx] + startBand,
1164
0
                     aaInData[setIdx + 1] + startBand, quant_offset,
1165
0
                     num_pcm_val, quant_levels);
1166
0
  } else {
1167
    /* Diff/Huff Coding */
1168
1169
0
    min_found = 0;
1170
1171
    /*******************************************/
1172
0
    if (min_bits_all == min_bits_df_df) {
1173
0
      FDKwriteBits(strm, DIFF_FREQ, 1);
1174
0
      FDKwriteBits(strm, DIFF_FREQ, 1);
1175
1176
0
      apply_huff_coding(strm, data_diff_freq[0], data_diff_freq[1], data_type,
1177
0
                        DIFF_FREQ, DIFF_FREQ, dataBands, lav_df_df,
1178
0
                        coding_scheme_df_df);
1179
1180
0
      min_found = 1;
1181
0
    }
1182
    /*******************************************/
1183
1184
    /*******************************************/
1185
0
    if (!min_found && (min_bits_all == min_bits_df_dt)) {
1186
0
      FDKwriteBits(strm, DIFF_FREQ, 1);
1187
0
      FDKwriteBits(strm, DIFF_TIME, 1);
1188
1189
0
      apply_huff_coding(strm, data_diff_freq[0], data_diff_time[1], data_type,
1190
0
                        DIFF_FREQ, DIFF_TIME, dataBands, lav_df_dt,
1191
0
                        coding_scheme_df_dt);
1192
1193
0
      min_found = 1;
1194
0
    }
1195
    /*******************************************/
1196
1197
    /*******************************************/
1198
    /*******************************************/
1199
1200
0
    if (allowDiffTimeBack_flag) {
1201
      /*******************************************/
1202
0
      if (!min_found && (min_bits_all == min_bits_dtbw_df)) {
1203
0
        FDKwriteBits(strm, DIFF_TIME, 1);
1204
0
        FDKwriteBits(strm, DIFF_FREQ, 1);
1205
1206
0
        apply_huff_coding(strm, data_diff_time[0], data_diff_freq[1], data_type,
1207
0
                          DIFF_TIME, DIFF_FREQ, dataBands, lav_dtbw_df,
1208
0
                          coding_scheme_dtbw_df);
1209
1210
0
        min_found = 1;
1211
0
      }
1212
      /*******************************************/
1213
1214
      /*******************************************/
1215
0
      if (!min_found && (min_bits_all == min_bits_dt_dt)) {
1216
0
        FDKwriteBits(strm, DIFF_TIME, 1);
1217
0
        FDKwriteBits(strm, DIFF_TIME, 1);
1218
1219
0
        apply_huff_coding(strm, data_diff_time[0], data_diff_time[1], data_type,
1220
0
                          DIFF_TIME, DIFF_TIME, dataBands, lav_dt_dt,
1221
0
                          coding_scheme_dt_dt);
1222
0
      }
1223
      /*******************************************/
1224
1225
0
    } /* if( allowDiffTimeBack_flag ) */
1226
1227
    /* LSB coding */
1228
0
    if (splitLsb_flag) {
1229
0
      apply_lsb_coding(strm, quant_data_lsb[0], 1, dataBands);
1230
1231
0
      apply_lsb_coding(strm, quant_data_lsb[1], 1, dataBands);
1232
0
    }
1233
1234
0
  } /* Diff/Huff/LSB coding */
1235
1236
0
  return reset;
1237
0
}
1238
1239
INT fdk_sacenc_ecDataSingleEnc(HANDLE_FDK_BITSTREAM strm,
1240
                               SHORT aaInData[][MAXBANDS],
1241
                               SHORT aHistory[MAXBANDS],
1242
                               const DATA_TYPE data_type, const INT setIdx,
1243
                               const INT startBand, const INT dataBands,
1244
                               const INT coarse_flag,
1245
0
                               const INT independency_flag) {
1246
0
  SHORT reset = 0, pb = 0;
1247
0
  SHORT quant_levels = 0, quant_offset = 0, num_pcm_val = 0;
1248
1249
0
  SHORT splitLsb_flag = 0;
1250
0
  SHORT pcmCoding_flag = 0;
1251
1252
0
  SHORT allowDiffTimeBack_flag = !independency_flag || (setIdx > 0);
1253
1254
0
  SHORT num_lsb_bits = -1;
1255
0
  SHORT num_pcm_bits = -1;
1256
1257
0
  SHORT quant_data_lsb[MAXBANDS];
1258
0
  SHORT quant_data_msb[MAXBANDS];
1259
1260
0
  SHORT quant_data_hist_lsb[MAXBANDS];
1261
0
  SHORT quant_data_hist_msb[MAXBANDS];
1262
1263
0
  SHORT data_diff_freq[MAXBANDS];
1264
0
  SHORT data_diff_time[MAXBANDS + 2];
1265
1266
0
  SHORT *p_quant_data_msb;
1267
0
  SHORT *p_quant_data_hist_msb = NULL;
1268
1269
0
  SHORT min_bits_all = 0;
1270
0
  SHORT min_found = 0;
1271
1272
0
  SHORT min_bits_df = -1;
1273
0
  SHORT min_bits_dt = -1;
1274
1275
0
  SHORT lav_df[2] = {-1, -1};
1276
0
  SHORT lav_dt[2] = {-1, -1};
1277
1278
0
  SHORT coding_scheme_df = 0;
1279
0
  SHORT coding_scheme_dt = 0;
1280
1281
0
  switch (data_type) {
1282
0
    case t_CLD:
1283
0
      if (coarse_flag) {
1284
0
        splitLsb_flag = 0;
1285
0
        quant_levels = 15;
1286
0
        quant_offset = 7;
1287
0
      } else {
1288
0
        splitLsb_flag = 0;
1289
0
        quant_levels = 31;
1290
0
        quant_offset = 15;
1291
0
      }
1292
0
      break;
1293
0
    case t_ICC:
1294
0
      if (coarse_flag) {
1295
0
        splitLsb_flag = 0;
1296
0
        quant_levels = 4;
1297
0
        quant_offset = 0;
1298
0
      } else {
1299
0
        splitLsb_flag = 0;
1300
0
        quant_levels = 8;
1301
0
        quant_offset = 0;
1302
0
      }
1303
0
      break;
1304
0
  } /* switch( data_type ) */
1305
1306
  /* Split off LSB */
1307
0
  if (splitLsb_flag) {
1308
0
    split_lsb(aaInData[setIdx] + startBand, quant_offset, dataBands,
1309
0
              quant_data_lsb, quant_data_msb);
1310
1311
0
    p_quant_data_msb = quant_data_msb;
1312
0
    num_lsb_bits = dataBands;
1313
0
  } else if (quant_offset != 0) {
1314
0
    for (pb = 0; pb < dataBands; pb++) {
1315
0
      quant_data_msb[pb] = aaInData[setIdx][startBand + pb] + quant_offset;
1316
0
    }
1317
1318
0
    p_quant_data_msb = quant_data_msb;
1319
0
    num_lsb_bits = 0;
1320
0
  } else {
1321
0
    p_quant_data_msb = aaInData[setIdx] + startBand;
1322
0
    num_lsb_bits = 0;
1323
0
  }
1324
1325
0
  if (allowDiffTimeBack_flag) {
1326
0
    if (splitLsb_flag) {
1327
0
      split_lsb(aHistory + startBand, quant_offset, dataBands,
1328
0
                quant_data_hist_lsb, quant_data_hist_msb);
1329
1330
0
      p_quant_data_hist_msb = quant_data_hist_msb;
1331
0
    } else if (quant_offset != 0) {
1332
0
      for (pb = 0; pb < dataBands; pb++) {
1333
0
        quant_data_hist_msb[pb] = aHistory[startBand + pb] + quant_offset;
1334
0
      }
1335
0
      p_quant_data_hist_msb = quant_data_hist_msb;
1336
0
    } else {
1337
0
      p_quant_data_hist_msb = aHistory + startBand;
1338
0
    }
1339
0
  }
1340
1341
  /* Calculate frequency differences */
1342
0
  calc_diff_freq(p_quant_data_msb, data_diff_freq, dataBands);
1343
1344
  /* Calculate time differences */
1345
0
  if (allowDiffTimeBack_flag) {
1346
0
    calc_diff_time(p_quant_data_msb, p_quant_data_hist_msb, data_diff_time,
1347
0
                   dataBands);
1348
0
  }
1349
1350
  /* Calculate coding scheme with minumum bit consumption */
1351
1352
  /**********************************************************/
1353
0
  num_pcm_bits = calc_pcm_bits(dataBands, quant_levels);
1354
0
  num_pcm_val = dataBands;
1355
1356
  /**********************************************************/
1357
1358
0
  min_bits_all = num_pcm_bits;
1359
1360
  /**********************************************************/
1361
  /**********************************************************/
1362
1363
  /**********************************************************/
1364
0
  min_bits_df = calc_huff_bits(data_diff_freq, NULL, data_type, DIFF_FREQ,
1365
0
                               DIFF_FREQ, dataBands, lav_df, &coding_scheme_df);
1366
1367
0
  if (allowDiffTimeBack_flag) min_bits_df += 1;
1368
1369
0
  min_bits_df += num_lsb_bits;
1370
1371
0
  if (min_bits_df < min_bits_all) {
1372
0
    min_bits_all = min_bits_df;
1373
0
  }
1374
  /**********************************************************/
1375
1376
  /**********************************************************/
1377
0
  if (allowDiffTimeBack_flag) {
1378
0
    min_bits_dt =
1379
0
        calc_huff_bits(data_diff_time, NULL, data_type, DIFF_TIME, DIFF_TIME,
1380
0
                       dataBands, lav_dt, &coding_scheme_dt);
1381
1382
0
    min_bits_dt += 1;
1383
0
    min_bits_dt += num_lsb_bits;
1384
1385
0
    if (min_bits_dt < min_bits_all) {
1386
0
      min_bits_all = min_bits_dt;
1387
0
    }
1388
0
  } /* if( allowDiffTimeBack_flag ) */
1389
1390
  /***************************/
1391
  /* Start actual coding now */
1392
  /***************************/
1393
1394
  /* PCM or Diff/Huff Coding? */
1395
0
  pcmCoding_flag = (min_bits_all == num_pcm_bits);
1396
1397
0
  FDKwriteBits(strm, pcmCoding_flag, 1);
1398
1399
0
  if (pcmCoding_flag) {
1400
    /* Grouped PCM Coding */
1401
0
    apply_pcm_coding(strm, aaInData[setIdx] + startBand, NULL, quant_offset,
1402
0
                     num_pcm_val, quant_levels);
1403
0
  } else {
1404
    /* Diff/Huff Coding */
1405
1406
0
    min_found = 0;
1407
1408
    /*******************************************/
1409
0
    if (min_bits_all == min_bits_df) {
1410
0
      if (allowDiffTimeBack_flag) {
1411
0
        FDKwriteBits(strm, DIFF_FREQ, 1);
1412
0
      }
1413
1414
0
      apply_huff_coding(strm, data_diff_freq, NULL, data_type, DIFF_FREQ,
1415
0
                        DIFF_FREQ, dataBands, lav_df, coding_scheme_df);
1416
1417
0
      min_found = 1;
1418
0
    } /* if( min_bits_all == min_bits_df ) */
1419
    /*******************************************/
1420
1421
    /*******************************************/
1422
0
    if (allowDiffTimeBack_flag) {
1423
      /*******************************************/
1424
0
      if (!min_found && (min_bits_all == min_bits_dt)) {
1425
0
        FDKwriteBits(strm, DIFF_TIME, 1);
1426
1427
0
        apply_huff_coding(strm, data_diff_time, NULL, data_type, DIFF_TIME,
1428
0
                          DIFF_TIME, dataBands, lav_dt, coding_scheme_dt);
1429
0
      }
1430
      /*******************************************/
1431
1432
0
    } /* if( allowDiffTimeBack_flag ) */
1433
1434
    /* LSB coding */
1435
0
    if (splitLsb_flag) {
1436
0
      apply_lsb_coding(strm, quant_data_lsb, 1, dataBands);
1437
0
    }
1438
1439
0
  } /* Diff/Huff/LSB coding */
1440
1441
0
  return reset;
1442
0
}