Home | History | Annotate | Download | only in decoder
      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 <string.h>
     21 #include "ixheaacd_sbr_common.h"
     22 #include <ixheaacd_type_def.h>
     23 
     24 #include "ixheaacd_constants.h"
     25 #include "ixheaacd_basic_ops32.h"
     26 #include "ixheaacd_basic_ops40.h"
     27 #include "ixheaacd_basic_ops.h"
     28 
     29 #include "ixheaacd_bitbuffer.h"
     30 #include "ixheaacd_defines.h"
     31 #include "ixheaacd_aac_rom.h"
     32 #include "ixheaacd_pulsedata.h"
     33 
     34 #include "ixheaacd_pns.h"
     35 
     36 #include "ixheaacd_lt_predict.h"
     37 
     38 #include "ixheaacd_channelinfo.h"
     39 
     40 #include "ixheaacd_drc_data_struct.h"
     41 #include "ixheaacd_drc_dec.h"
     42 
     43 #include "ixheaacd_sbrdecoder.h"
     44 
     45 #include "ixheaacd_block.h"
     46 #include "ixheaacd_channel.h"
     47 #include "ixheaacd_common_rom.h"
     48 
     49 #include "ixheaacd_aacdec.h"
     50 
     51 #include "ixheaacd_sbrdecsettings.h"
     52 
     53 #include "ixheaacd_env_extr_part.h"
     54 #include "ixheaacd_sbr_rom.h"
     55 #include "ixheaacd_audioobjtypes.h"
     56 #include "ixheaacd_memory_standards.h"
     57 #include "ixheaacd_latmdemux.h"
     58 #include "ixheaacd_mps_polyphase.h"
     59 #include "ixheaacd_config.h"
     60 #include "ixheaacd_mps_dec.h"
     61 #include "ixheaacd_struct_def.h"
     62 
     63 #include "ixheaacd_cnst.h"
     64 #include "ixheaacd_rvlc.h"
     65 
     66 const UWORD8 ixheaacd_min_huff_cb_pair_tbl[MAX_CB_PAIRS] = {
     67     0,  1,  3,  5,  7,  9,  16, 17, 18, 19, 20, 21,
     68     22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 11};
     69 const UWORD8 ixheaacd_max_huff_cb_pair_table[MAX_CB_PAIRS] = {
     70     0,  2,  4,  6,  8,  10, 16, 17, 18, 19, 20, 21,
     71     22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 11};
     72 const UWORD8 ixheaacd_max_huff_cw_len_table[MAX_CB] = {
     73     0,  11, 9,  20, 16, 13, 11, 14, 12, 17, 14, 49, 0,  0,  0,  0,
     74     14, 17, 21, 21, 25, 25, 29, 29, 29, 29, 33, 33, 33, 37, 37, 41};
     75 const UWORD8 ixheaacd_huff_cb_dim_table[MAX_CB] = {
     76     2, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2,
     77     2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
     78 const UWORD8 ixheaacd_huff_cb_dim_shift_table[MAX_CB] = {
     79     1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,
     80     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
     81 const UWORD8 ixheaacd_huff_cb_sign_table[MAX_CB] = {
     82     0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0,
     83     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
     84 const UWORD8 ixheaacd_huff_cb_priority_table[MAX_CB] = {
     85     0, 1, 1, 2, 2,  3,  3,  4,  4,  5,  5,  22, 0,  0,  0,  0,
     86     6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21};
     87 const UWORD16 ixheaacd_huff_reord_lav_table[MAX_CB] = {
     88     0,    1,   1,   2,   2,   4,   4,   7,   7,    12,  12,
     89     8191, 0,   0,   0,   0,   15,  31,  47,  63,   95,  127,
     90     159,  191, 223, 255, 319, 383, 511, 767, 1023, 2047};
     91 
     92 VOID ixheaacd_huff_code_reorder_tbl_init(ia_hcr_info_struct *ptr_hcr_info) {
     93   ptr_hcr_info->codebook_pairs.ptr_min_cb_pair_tbl =
     94       ixheaacd_min_huff_cb_pair_tbl;
     95   ptr_hcr_info->codebook_pairs.ptr_max_cb_pair_tbl =
     96       ixheaacd_max_huff_cb_pair_table;
     97   ptr_hcr_info->table_info.ptr_max_cw_len_tbl = ixheaacd_max_huff_cw_len_table;
     98   ptr_hcr_info->table_info.ptr_cb_dimension_tbl = ixheaacd_huff_cb_dim_table;
     99   ptr_hcr_info->table_info.ptr_cb_dim_shift_tbl =
    100       ixheaacd_huff_cb_dim_shift_table;
    101   ptr_hcr_info->table_info.ptr_cb_sign_tbl = ixheaacd_huff_cb_sign_table;
    102   ptr_hcr_info->table_info.ptr_cb_priority = ixheaacd_huff_cb_priority_table;
    103   ptr_hcr_info->table_info.ptr_lav_tbl = ixheaacd_huff_reord_lav_table;
    104 }
    105 
    106 VOID ixheaacd_huff_mute_erroneous_lines(ia_hcr_info_struct *ptr_hcr_info) {
    107   WORD32 c;
    108   WORD32 *ptr_long = ptr_hcr_info->str_dec_io.ptr_quant_spec_coeff_base;
    109 
    110   for (c = 0; c < 1024; c++) {
    111     if (ptr_long[c] == (WORD32)8192) {
    112       ptr_long[c] = 0;
    113     }
    114   }
    115 }
    116 
    117 static UWORD8 ixheaacd_err_detect_pcw_segment(WORD8 remaining_bits_in_segment,
    118                                               ia_hcr_info_struct *ptr_hcr_info,
    119                                               ia_pcw_type_struct kind,
    120                                               WORD32 *qsc_base_of_cw,
    121                                               UWORD8 dimension) {
    122   WORD8 i;
    123   if (remaining_bits_in_segment < 0) {
    124     switch (kind) {
    125       case PCW:
    126         ptr_hcr_info->str_dec_io.err_log |= (ERROR_POS << 31);
    127         break;
    128       case PCW_SIGN:
    129         ptr_hcr_info->str_dec_io.err_log |= (ERROR_POS << 30);
    130         break;
    131       case PCW_ESC_SIGN:
    132         ptr_hcr_info->str_dec_io.err_log |= (ERROR_POS << 29);
    133         break;
    134     }
    135     for (i = dimension; i != 0; i--) {
    136       *qsc_base_of_cw++ = (WORD32)8192;
    137     }
    138     return 1;
    139   }
    140   return 0;
    141 }
    142 
    143 static VOID ixheaacd_nonpcw_sideinfo_init(ia_hcr_info_struct *ptr_hcr_info) {
    144   UWORD16 i, k;
    145   UWORD8 cb_dim;
    146   UWORD8 *ptr_cb = ptr_hcr_info->str_non_pcw_side_info.ptr_cb;
    147   UWORD16 *res_ptr_idx = ptr_hcr_info->str_non_pcw_side_info.res_ptr_idx;
    148   UWORD16 *ptr_num_ext_sorted_cw_in_sect =
    149       ptr_hcr_info->sect_info.ptr_num_ext_sorted_cw_in_sect;
    150   WORD32 num_ext_sorted_cw_in_sect_idx =
    151       ptr_hcr_info->sect_info.num_ext_sorted_cw_in_sect_idx;
    152   UWORD8 *ptr_ext_sorted_cw = ptr_hcr_info->sect_info.ptr_ext_sorted_cw;
    153   WORD32 ext_sorted_cw_idx = ptr_hcr_info->sect_info.ext_sorted_cw_idx;
    154   UWORD16 *ptr_num_ext_sorted_sect_in_sets =
    155       ptr_hcr_info->sect_info.ptr_num_ext_sorted_sect_in_sets;
    156   WORD32 num_ext_sorted_sect_in_sets_idx =
    157       ptr_hcr_info->sect_info.num_ext_sorted_sect_in_sets_idx;
    158   WORD32 quant_spec_coeff_idx = ptr_hcr_info->str_dec_io.quant_spec_coeff_idx;
    159   const UWORD8 *ptr_cb_dimension_tbl =
    160       ptr_hcr_info->table_info.ptr_cb_dimension_tbl;
    161   WORD32 loop_idx = 0;
    162 
    163   for (i = ptr_num_ext_sorted_sect_in_sets[num_ext_sorted_sect_in_sets_idx];
    164        i != 0; i--) {
    165     cb_dim = ptr_cb_dimension_tbl[ptr_ext_sorted_cw[ext_sorted_cw_idx]];
    166 
    167     for (k = ptr_num_ext_sorted_cw_in_sect[num_ext_sorted_cw_in_sect_idx];
    168          k != 0; k--) {
    169       loop_idx++;
    170       if (loop_idx > 256) {
    171         return;
    172       }
    173       *ptr_cb++ = ptr_ext_sorted_cw[ext_sorted_cw_idx];
    174       *res_ptr_idx++ = quant_spec_coeff_idx;
    175       quant_spec_coeff_idx += cb_dim;
    176       if (quant_spec_coeff_idx >= 1024) {
    177         return;
    178       }
    179     }
    180     num_ext_sorted_cw_in_sect_idx++;
    181     ext_sorted_cw_idx++;
    182     if (num_ext_sorted_cw_in_sect_idx >= (MAX_SFB_HCR + MAX_HCR_SETS) ||
    183         ext_sorted_cw_idx >= (MAX_SFB_HCR + MAX_HCR_SETS)) {
    184       return;
    185     }
    186   }
    187   num_ext_sorted_sect_in_sets_idx++;
    188   if (num_ext_sorted_cw_in_sect_idx >= (MAX_SFB_HCR + MAX_HCR_SETS)) {
    189     return;
    190   }
    191 
    192   ptr_hcr_info->sect_info.num_ext_sorted_cw_in_sect_idx =
    193       num_ext_sorted_cw_in_sect_idx;
    194   ptr_hcr_info->sect_info.ext_sorted_cw_idx = ext_sorted_cw_idx;
    195   ptr_hcr_info->sect_info.num_ext_sorted_sect_in_sets_idx =
    196       num_ext_sorted_sect_in_sets_idx;
    197   ptr_hcr_info->sect_info.num_ext_sorted_cw_in_sect_idx =
    198       num_ext_sorted_cw_in_sect_idx;
    199   ptr_hcr_info->str_dec_io.quant_spec_coeff_idx = quant_spec_coeff_idx;
    200 }
    201 
    202 static VOID ixheaacd_calc_num_ext_sorted_sect_sets(
    203     UWORD32 num_segment, UWORD16 *ptr_num_ext_sorted_cw_in_sect,
    204     WORD32 num_ext_sorted_cw_in_sect_idx,
    205     UWORD16 *ptr_num_ext_sorted_sect_in_sets,
    206     WORD32 num_ext_sorted_sect_in_sets_idx) {
    207   UWORD16 counter = 0;
    208   UWORD32 cw_sum = 0;
    209   UWORD16 *ptr_num_ext_sort_cw_in_sect = ptr_num_ext_sorted_cw_in_sect;
    210   UWORD16 *ptr_num_ext_sort_sect_in_sets = ptr_num_ext_sorted_sect_in_sets;
    211 
    212   while (ptr_num_ext_sort_cw_in_sect[num_ext_sorted_cw_in_sect_idx] != 0) {
    213     cw_sum += ptr_num_ext_sort_cw_in_sect[num_ext_sorted_cw_in_sect_idx];
    214     num_ext_sorted_cw_in_sect_idx++;
    215     if (num_ext_sorted_cw_in_sect_idx >= (MAX_SFB_HCR + MAX_HCR_SETS)) {
    216       return;
    217     }
    218     if (cw_sum > num_segment) {
    219       return;
    220     }
    221     counter++;
    222     if (counter > 256) {
    223       return;
    224     }
    225     if (cw_sum == num_segment) {
    226       ptr_num_ext_sort_sect_in_sets[num_ext_sorted_sect_in_sets_idx] = counter;
    227       num_ext_sorted_sect_in_sets_idx++;
    228       if (num_ext_sorted_sect_in_sets_idx >= MAX_HCR_SETS) {
    229         return;
    230       }
    231       counter = 0;
    232       cw_sum = 0;
    233     }
    234   }
    235   ptr_num_ext_sort_sect_in_sets[num_ext_sorted_sect_in_sets_idx] = counter;
    236 }
    237 
    238 static VOID ixheaacd_validate_hcr_sideinfo(WORD8 cb, WORD32 num_line,
    239                                            UWORD32 *error_word) {
    240   if (cb < ZERO_HCB || cb >= MAX_CB_CHECK || cb == (ESC_HCB + 1)) {
    241     *error_word |= (ERROR_POS << 4);
    242   }
    243   if (num_line < 0 || num_line > 1024) {
    244     *error_word |= (ERROR_POS << 5);
    245   }
    246 }
    247 
    248 static VOID ixheaacd_validate_hcr_lengths(WORD8 longest_cw_len,
    249                                           WORD16 reordered_spec_data_len,
    250                                           UWORD32 *error_word) {
    251   if (reordered_spec_data_len < longest_cw_len) {
    252     *error_word |= (ERROR_POS << 8);
    253   }
    254 }
    255 
    256 UWORD32 ixheaacd_huff_code_reorder_init(
    257     ia_hcr_info_struct *ptr_hcr_info,
    258     ia_aac_dec_channel_info_struct *ptr_aac_dec_channel_info,
    259     ia_aac_dec_tables_struct *ptr_aac_tables, ia_bit_buf_struct *itt_bit_buff) {
    260   ia_ics_info_struct *ptr_ics_info = &ptr_aac_dec_channel_info->str_ics_info;
    261   WORD16 *ptr_num_sect_lines;
    262   UWORD8 *ptr_cb;
    263   WORD16 num_sect;
    264   WORD8 cb;
    265   WORD32 num_line;
    266   WORD32 i;
    267 
    268   ptr_hcr_info->str_dec_io.reordered_spec_data_len =
    269       ptr_aac_dec_channel_info->reorder_spect_data_len;
    270   ptr_hcr_info->str_dec_io.longest_cw_len =
    271       ptr_aac_dec_channel_info->longest_cw_len;
    272   ptr_hcr_info->str_dec_io.ptr_quant_spec_coeff_base =
    273       ptr_aac_dec_channel_info->ptr_spec_coeff;
    274   ptr_hcr_info->str_dec_io.quant_spec_coeff_idx = 0;
    275   ptr_hcr_info->str_dec_io.ptr_cb = ptr_aac_dec_channel_info->cb4_hcr_arr;
    276   ptr_hcr_info->str_dec_io.ptr_num_line_in_sect =
    277       ptr_aac_dec_channel_info->num_line_in_sec4_hcr_arr;
    278   ptr_hcr_info->str_dec_io.num_sect = ptr_aac_dec_channel_info->number_sect;
    279   ptr_hcr_info->str_dec_io.err_log = 0;
    280   ptr_hcr_info->str_non_pcw_side_info.ptr_result_base =
    281       ptr_aac_dec_channel_info->ptr_spec_coeff;
    282 
    283   ptr_hcr_info->str_dec_io.bit_str_idx =
    284       itt_bit_buff->size - itt_bit_buff->cnt_bits;
    285   itt_bit_buff->byte_ptr = (UWORD8 *)ptr_aac_dec_channel_info->scratch_buf_ptr;
    286   itt_bit_buff->ptr_start = (UWORD8 *)ptr_aac_dec_channel_info->scratch_buf_ptr;
    287 
    288   if (ptr_aac_dec_channel_info->str_ics_info.window_sequence ==
    289       EIGHT_SHORT_SEQUENCE) {
    290     WORD16 band;
    291     WORD16 max_band;
    292     WORD8 group;
    293     WORD8 win_group_len;
    294     WORD8 window;
    295     WORD8 num_unit_in_band;
    296     WORD8 cnt_unit_in_band;
    297     WORD8 grp_win;
    298     WORD8 cb_prev;
    299 
    300     WORD8 *ptr_code_book;
    301     const WORD16 *band_offsets;
    302     WORD16 num_groups;
    303 
    304     ptr_code_book = ptr_aac_dec_channel_info->ptr_code_book;
    305     ptr_num_sect_lines = ptr_hcr_info->str_dec_io.ptr_num_line_in_sect;
    306     ptr_cb = ptr_hcr_info->str_dec_io.ptr_cb;
    307     band_offsets = (WORD16 *)ixheaacd_getscalefactorbandoffsets(ptr_ics_info,
    308                                                                 ptr_aac_tables);
    309     num_groups = ptr_ics_info->num_window_groups;
    310 
    311     num_line = 0;
    312     num_sect = 0;
    313     cb = ptr_code_book[0];
    314     cb_prev = ptr_code_book[0];
    315 
    316     *ptr_cb++ = cb_prev;
    317 
    318     max_band = ptr_ics_info->max_sfb;
    319     for (band = 0; band < max_band; band++) {
    320       num_unit_in_band = ((band_offsets[band + 1] - band_offsets[band]) >> 2);
    321       for (cnt_unit_in_band = num_unit_in_band; cnt_unit_in_band != 0;
    322            cnt_unit_in_band--) {
    323         for (window = 0, group = 0; group < num_groups; group++) {
    324           win_group_len = ptr_ics_info->window_group_length[group];
    325           for (grp_win = win_group_len; grp_win != 0; grp_win--, window++) {
    326             cb = ptr_code_book[group * 16 + band];
    327             if (cb != cb_prev) {
    328               ixheaacd_validate_hcr_sideinfo(cb, num_line,
    329                                              &ptr_hcr_info->str_dec_io.err_log);
    330               if (ptr_hcr_info->str_dec_io.err_log != 0) {
    331                 return (ptr_hcr_info->str_dec_io.err_log);
    332               }
    333               *ptr_cb++ = cb;
    334               *ptr_num_sect_lines++ = num_line;
    335               num_sect++;
    336 
    337               cb_prev = cb;
    338               num_line = LINES_PER_UNIT;
    339             } else {
    340               num_line += LINES_PER_UNIT;
    341             }
    342           }
    343         }
    344       }
    345     }
    346 
    347     num_sect++;
    348 
    349     ixheaacd_validate_hcr_sideinfo(cb, num_line,
    350                                    &ptr_hcr_info->str_dec_io.err_log);
    351     if (num_sect <= 0 || num_sect > 1024 / 2) {
    352       ptr_hcr_info->str_dec_io.err_log |= (ERROR_POS << 7);
    353     }
    354     ixheaacd_validate_hcr_lengths(
    355         ptr_hcr_info->str_dec_io.longest_cw_len,
    356         ptr_hcr_info->str_dec_io.reordered_spec_data_len,
    357         &ptr_hcr_info->str_dec_io.err_log);
    358     if (ptr_hcr_info->str_dec_io.err_log != 0) {
    359       return (ptr_hcr_info->str_dec_io.err_log);
    360     }
    361 
    362     *ptr_cb = cb;
    363     *ptr_num_sect_lines = num_line;
    364     ptr_hcr_info->str_dec_io.num_sect = num_sect;
    365 
    366   } else {
    367     ixheaacd_validate_hcr_lengths(
    368         ptr_hcr_info->str_dec_io.longest_cw_len,
    369         ptr_hcr_info->str_dec_io.reordered_spec_data_len,
    370         &ptr_hcr_info->str_dec_io.err_log);
    371     num_sect = ptr_hcr_info->str_dec_io.num_sect;
    372     ptr_num_sect_lines = ptr_hcr_info->str_dec_io.ptr_num_line_in_sect;
    373     ptr_cb = ptr_hcr_info->str_dec_io.ptr_cb;
    374     if (num_sect <= 0 || num_sect > 64) {
    375       ptr_hcr_info->str_dec_io.err_log |= (ERROR_POS << 6);
    376       num_sect = 0;
    377     }
    378 
    379     for (i = num_sect; i != 0; i--) {
    380       cb = *ptr_cb++;
    381 
    382       if (cb < ZERO_HCB || cb >= MAX_CB_CHECK || cb == (ESC_HCB + 1)) {
    383         ptr_hcr_info->str_dec_io.err_log |= (ERROR_POS << 2);
    384       }
    385 
    386       num_line = *ptr_num_sect_lines++;
    387 
    388       if ((num_line <= 0) || (num_line > 1024)) {
    389         ptr_hcr_info->str_dec_io.err_log |= (ERROR_POS << 3);
    390       }
    391     }
    392     if (ptr_hcr_info->str_dec_io.err_log != 0) {
    393       return (ptr_hcr_info->str_dec_io.err_log);
    394     }
    395   }
    396 
    397   ptr_cb = ptr_hcr_info->str_dec_io.ptr_cb;
    398   for (i = 0; i < num_sect; i++) {
    399     if ((*ptr_cb == NOISE_HCB) || (*ptr_cb == INTENSITY_HCB2) ||
    400         (*ptr_cb == INTENSITY_HCB)) {
    401       *ptr_cb = 0;
    402     }
    403     ptr_cb++;
    404   }
    405 
    406   return (ptr_hcr_info->str_dec_io.err_log);
    407 }
    408 
    409 static VOID ixheaacd_huff_calc_num_cwd(ia_hcr_info_struct *ptr_hcr_info) {
    410   WORD32 sect_idx;
    411   UWORD32 num_code_word;
    412 
    413   UWORD32 num_sect = ptr_hcr_info->str_dec_io.num_sect;
    414   UWORD8 *ptr_cb = ptr_hcr_info->str_dec_io.ptr_cb;
    415   WORD16 *ptr_num_line_in_sect = ptr_hcr_info->str_dec_io.ptr_num_line_in_sect;
    416   const UWORD8 *ptr_cb_dim_shift_tbl =
    417       ptr_hcr_info->table_info.ptr_cb_dim_shift_tbl;
    418   UWORD16 *ptr_num_cw_in_sect = ptr_hcr_info->sect_info.ptr_num_cw_in_sect;
    419 
    420   num_code_word = 0;
    421   for (sect_idx = num_sect; sect_idx != 0; sect_idx--) {
    422     *ptr_num_cw_in_sect =
    423         *ptr_num_line_in_sect++ >> ptr_cb_dim_shift_tbl[*ptr_cb];
    424     if (*ptr_cb != 0) {
    425       num_code_word += *ptr_num_cw_in_sect;
    426     }
    427     ptr_num_cw_in_sect++;
    428     ptr_cb++;
    429   }
    430   ptr_hcr_info->sect_info.num_code_word = num_code_word;
    431 }
    432 
    433 static VOID ixheaacd_huff_sort_sect_cb_cwd(ia_hcr_info_struct *ptr_hcr_info) {
    434   UWORD32 i, j, k;
    435   UWORD8 temp;
    436   UWORD32 counter;
    437   UWORD32 start_offset;
    438   UWORD32 num_zero_sect;
    439   UWORD8 *ptr_dest;
    440   UWORD32 num_sect_dec;
    441 
    442   UWORD32 num_sect = ptr_hcr_info->str_dec_io.num_sect;
    443   UWORD8 *ptr_cb = ptr_hcr_info->str_dec_io.ptr_cb;
    444   UWORD8 *ptr_sorted_cb = ptr_hcr_info->sect_info.ptr_sorted_cb;
    445   UWORD16 *ptr_num_cw_in_sect = ptr_hcr_info->sect_info.ptr_num_cw_in_sect;
    446   UWORD16 *ptr_num_sorted_cw_in_sect =
    447       ptr_hcr_info->sect_info.ptr_num_sorted_cw_in_sect;
    448   UWORD8 *ptr_cb_switch = ptr_hcr_info->sect_info.ptr_cb_switch;
    449   UWORD16 *ptr_reorder_offset = ptr_hcr_info->sect_info.ptr_reorder_offset;
    450   const UWORD8 *ptr_cb_priority = ptr_hcr_info->table_info.ptr_cb_priority;
    451   const UWORD8 *ptr_min_cb_pair_tbl =
    452       ptr_hcr_info->codebook_pairs.ptr_min_cb_pair_tbl;
    453   const UWORD8 *ptr_max_cb_pair_tbl =
    454       ptr_hcr_info->codebook_pairs.ptr_max_cb_pair_tbl;
    455   const UWORD8 *ptr_cb_dim_shift_tbl =
    456       ptr_hcr_info->table_info.ptr_cb_dim_shift_tbl;
    457 
    458   UWORD32 search_start_idx = 0;
    459 
    460   ptr_dest = ptr_sorted_cb;
    461   num_zero_sect = 0;
    462   for (i = num_sect; i != 0; i--) {
    463     if (ptr_cb_priority[*ptr_cb] == 0) {
    464       num_zero_sect += 1;
    465     }
    466     *ptr_dest++ = ptr_cb_priority[*ptr_cb++];
    467   }
    468   ptr_hcr_info->sect_info.num_sorted_section = num_sect - num_zero_sect;
    469   ptr_cb = ptr_hcr_info->str_dec_io.ptr_cb;
    470 
    471   num_sect_dec = num_sect - 1;
    472   if (num_sect_dec > 0) {
    473     counter = num_sect_dec;
    474     for (j = num_sect_dec; j != 0; j--) {
    475       for (i = 0; i < counter; i++) {
    476         if (ptr_sorted_cb[i + 1] > ptr_sorted_cb[i]) {
    477           temp = ptr_sorted_cb[i];
    478           ptr_sorted_cb[i] = ptr_sorted_cb[i + 1];
    479           ptr_sorted_cb[i + 1] = temp;
    480         }
    481       }
    482       counter -= 1;
    483     }
    484   }
    485 
    486   for (i = num_sect; i != 0; i--) {
    487     *ptr_cb_switch++ = 0;
    488   }
    489   ptr_cb_switch = ptr_hcr_info->sect_info.ptr_cb_switch;
    490 
    491   for (j = 0; j < num_sect; j++) {
    492     for (i = search_start_idx; i < num_sect; i++) {
    493       if (ptr_cb_switch[i] == 0 &&
    494           (ptr_min_cb_pair_tbl[ptr_sorted_cb[j]] == ptr_cb[i] ||
    495            ptr_max_cb_pair_tbl[ptr_sorted_cb[j]] == ptr_cb[i])) {
    496         ptr_cb_switch[i] = 1;
    497         ptr_sorted_cb[j] = ptr_cb[i];
    498         ptr_num_sorted_cw_in_sect[j] = ptr_num_cw_in_sect[i];
    499 
    500         start_offset = 0;
    501         for (k = 0; k < i; k++) {
    502           start_offset += ptr_num_cw_in_sect[k]
    503                           << ptr_cb_dim_shift_tbl[ptr_cb[k]];
    504         }
    505         ptr_reorder_offset[j] = start_offset;
    506 
    507         if (i == search_start_idx) {
    508           UWORD32 k = i;
    509           while (ptr_cb_switch[k++] == 1) search_start_idx++;
    510         }
    511         break;
    512       }
    513     }
    514   }
    515 }
    516 
    517 static VOID ixheaacd_huff_ext_sect_info(ia_hcr_info_struct *ptr_hcr_info) {
    518   UWORD32 srt_sec_cnt = 0;
    519   UWORD32 x_srt_sc_cnt = 0;
    520   UWORD32 remain_num_cw_sort_sec;
    521   UWORD32 in_segment_remain_num_cw;
    522 
    523   UWORD32 num_sorted_section = ptr_hcr_info->sect_info.num_sorted_section;
    524   UWORD8 *ptr_sorted_cb = ptr_hcr_info->sect_info.ptr_sorted_cb;
    525   UWORD16 *ptr_num_sorted_cw_in_sect =
    526       ptr_hcr_info->sect_info.ptr_num_sorted_cw_in_sect;
    527   UWORD8 *ptr_extended_sorted_code_book =
    528       ptr_hcr_info->sect_info.ptr_ext_sorted_cw;
    529   UWORD16 *ptr_num_ext_sort_cw_sect =
    530       ptr_hcr_info->sect_info.ptr_num_ext_sorted_cw_in_sect;
    531   UWORD32 num_segment = ptr_hcr_info->str_segment_info.num_segment;
    532   UWORD8 *ptr_ext_sorted_sect_max_cb_len =
    533       ptr_hcr_info->sect_info.ptr_ext_sorted_sect_max_cb_len;
    534   WORD8 longest_cw_len = ptr_hcr_info->str_dec_io.longest_cw_len;
    535   const UWORD8 *ptr_max_cw_len_tbl =
    536       ptr_hcr_info->table_info.ptr_max_cw_len_tbl;
    537 
    538   remain_num_cw_sort_sec = ptr_num_sorted_cw_in_sect[srt_sec_cnt];
    539   in_segment_remain_num_cw = num_segment;
    540 
    541   while (srt_sec_cnt < num_sorted_section) {
    542     if (in_segment_remain_num_cw < remain_num_cw_sort_sec) {
    543       ptr_num_ext_sort_cw_sect[x_srt_sc_cnt] = in_segment_remain_num_cw;
    544       ptr_extended_sorted_code_book[x_srt_sc_cnt] = ptr_sorted_cb[srt_sec_cnt];
    545 
    546       remain_num_cw_sort_sec -= in_segment_remain_num_cw;
    547       in_segment_remain_num_cw = num_segment;
    548     } else if (in_segment_remain_num_cw == remain_num_cw_sort_sec) {
    549       ptr_num_ext_sort_cw_sect[x_srt_sc_cnt] = in_segment_remain_num_cw;
    550       ptr_extended_sorted_code_book[x_srt_sc_cnt] = ptr_sorted_cb[srt_sec_cnt];
    551 
    552       srt_sec_cnt++;
    553       remain_num_cw_sort_sec = ptr_num_sorted_cw_in_sect[srt_sec_cnt];
    554       in_segment_remain_num_cw = num_segment;
    555     } else {
    556       ptr_num_ext_sort_cw_sect[x_srt_sc_cnt] = remain_num_cw_sort_sec;
    557       ptr_extended_sorted_code_book[x_srt_sc_cnt] = ptr_sorted_cb[srt_sec_cnt];
    558 
    559       in_segment_remain_num_cw -= remain_num_cw_sort_sec;
    560       srt_sec_cnt++;
    561       remain_num_cw_sort_sec = ptr_num_sorted_cw_in_sect[srt_sec_cnt];
    562     }
    563     ptr_ext_sorted_sect_max_cb_len[x_srt_sc_cnt] =
    564         min(ptr_max_cw_len_tbl[ptr_extended_sorted_code_book[x_srt_sc_cnt]],
    565             longest_cw_len);
    566 
    567     x_srt_sc_cnt += 1;
    568 
    569     if (x_srt_sc_cnt >= (MAX_SFB_HCR + MAX_HCR_SETS)) {
    570       ptr_hcr_info->str_dec_io.err_log |= (ERROR_POS << 28);
    571       return;
    572     }
    573   }
    574   ptr_num_ext_sort_cw_sect[x_srt_sc_cnt] = 0;
    575 }
    576 
    577 static UWORD32 ixheaacd_hcr_prepare_segmentation_grid(
    578     ia_hcr_info_struct *ptr_hcr_info) {
    579   UWORD16 i, j;
    580   UWORD16 num_segment = 0;
    581   UWORD16 segment_start = 0;
    582   UWORD8 segment_width;
    583   UWORD8 last_segment_width;
    584   UWORD8 sorted_code_book;
    585   UWORD8 end_flag = 0;
    586   UWORD16 intermediate_result;
    587 
    588   WORD8 longest_cw_len = ptr_hcr_info->str_dec_io.longest_cw_len;
    589   WORD16 reordered_spec_data_len =
    590       ptr_hcr_info->str_dec_io.reordered_spec_data_len;
    591   UWORD32 num_sorted_section = ptr_hcr_info->sect_info.num_sorted_section;
    592   UWORD8 *ptr_sorted_cb = ptr_hcr_info->sect_info.ptr_sorted_cb;
    593   UWORD16 *ptr_num_sorted_cw_in_sect =
    594       ptr_hcr_info->sect_info.ptr_num_sorted_cw_in_sect;
    595   UWORD16 *arr_seg_start_l = ptr_hcr_info->str_segment_info.arr_seg_start_l;
    596   UWORD16 *arr_seg_start_r = ptr_hcr_info->str_segment_info.arr_seg_start_r;
    597   WORD8 *p_remaining_bits_in_seg =
    598       ptr_hcr_info->str_segment_info.p_remaining_bits_in_seg;
    599   UWORD16 bit_str_idx = ptr_hcr_info->str_dec_io.bit_str_idx;
    600   const UWORD8 *ptr_max_cw_len_tbl =
    601       ptr_hcr_info->table_info.ptr_max_cw_len_tbl;
    602 
    603   for (i = num_sorted_section; i != 0; i--) {
    604     sorted_code_book = *ptr_sorted_cb++;
    605     segment_width = min(ptr_max_cw_len_tbl[sorted_code_book], longest_cw_len);
    606 
    607     for (j = *ptr_num_sorted_cw_in_sect; j != 0; j--) {
    608       intermediate_result = bit_str_idx + segment_start;
    609       if ((segment_start + segment_width) <= reordered_spec_data_len) {
    610         *arr_seg_start_l++ = intermediate_result;
    611         *arr_seg_start_r++ = intermediate_result + segment_width - 1;
    612         *p_remaining_bits_in_seg++ = segment_width;
    613         segment_start += segment_width;
    614         num_segment += 1;
    615       } else {
    616         arr_seg_start_l--;
    617         arr_seg_start_r--;
    618         p_remaining_bits_in_seg--;
    619         segment_start = *arr_seg_start_l - bit_str_idx;
    620 
    621         last_segment_width = reordered_spec_data_len - segment_start;
    622         *p_remaining_bits_in_seg = last_segment_width;
    623         *arr_seg_start_r = bit_str_idx + segment_start + last_segment_width - 1;
    624         end_flag = 1;
    625         break;
    626       }
    627     }
    628     ptr_num_sorted_cw_in_sect++;
    629     if (end_flag != 0) {
    630       break;
    631     }
    632   }
    633 
    634   if (num_segment == 0) ptr_hcr_info->str_dec_io.err_log |= (ERROR_POS << 9);
    635 
    636   ptr_hcr_info->str_segment_info.num_segment = num_segment;
    637 
    638   return (ptr_hcr_info->str_dec_io.err_log);
    639 }
    640 
    641 static PLATFORM_INLINE UWORD16 *ixheaacd_huff_dec_pair_hcr_pcw(
    642     ia_hcr_info_struct *ptr_hcr_info, ia_bit_buf_struct *it_bit_buff,
    643     WORD no_bands, const UWORD16 *code_book_tbl, WORD32 *read_word,
    644     WORD32 tbl_sign, const UWORD32 *idx_table, UWORD16 *arr_seg_start_l,
    645     WORD32 *read_bits, WORD32 huff_mode, WORD8 *p_remaining_bits_in_seg,
    646     WORD32 *ptr_num_decoded_bits)
    647 
    648 {
    649   WORD32 spec_index = ptr_hcr_info->str_dec_io.quant_spec_coeff_idx;
    650   WORD32 *spec_coef =
    651       ptr_hcr_info->str_dec_io.ptr_quant_spec_coeff_base + spec_index;
    652   WORD16 index, length;
    653   WORD32 y, z;
    654   UWORD8 *ptr_read_next = it_bit_buff->ptr_read_next;
    655   WORD32 *bit_pos = &it_bit_buff->bit_pos;
    656 
    657   do {
    658     UWORD32 read_word1;
    659 
    660     WORD32 read_bit_offset =
    661         *arr_seg_start_l - (it_bit_buff->size - *read_bits);
    662 
    663     if (read_bit_offset) {
    664       *read_bits -= read_bit_offset;
    665       *bit_pos += read_bit_offset;
    666       ixheaacd_aac_read_byte_corr(&ptr_read_next, bit_pos, read_word,
    667                                   it_bit_buff->ptr_bit_buf_end);
    668     }
    669 
    670     read_word1 = *read_word << *bit_pos;
    671     ixheaacd_huffman_decode(read_word1, &index, &length, code_book_tbl,
    672                             idx_table);
    673     *bit_pos += length;
    674     *ptr_num_decoded_bits += length;
    675     *p_remaining_bits_in_seg -= length;
    676     *arr_seg_start_l += length;
    677     *read_bits -= length;
    678     ixheaacd_aac_read_byte_corr(&ptr_read_next, bit_pos, read_word,
    679                                 it_bit_buff->ptr_bit_buf_end);
    680     if (tbl_sign) {
    681       WORD32 temp_word;
    682       temp_word = *read_word << *bit_pos;
    683       y = index / huff_mode;
    684       z = index - huff_mode * y;
    685 
    686       if (y) {
    687         if (temp_word & 0x80000000) y = -y;
    688 
    689         temp_word = temp_word << 1;
    690         *bit_pos += 1;
    691         *p_remaining_bits_in_seg -= 1;
    692         *ptr_num_decoded_bits += 1;
    693         *arr_seg_start_l += 1;
    694         *read_bits -= 1;
    695       }
    696       *spec_coef++ = y;
    697       spec_index++;
    698 
    699       if (z) {
    700         if (temp_word & 0x80000000) {
    701           z = -z;
    702         }
    703         temp_word <<= 1;
    704         *bit_pos += 1;
    705         *p_remaining_bits_in_seg -= 1;
    706         *ptr_num_decoded_bits += 1;
    707         *arr_seg_start_l += 1;
    708         *read_bits -= 1;
    709       }
    710       *spec_coef++ = z;
    711       spec_index++;
    712     } else {
    713       y = (index / huff_mode) - 4;
    714       z = index - ((y + 4) * huff_mode) - 4;
    715 
    716       *spec_coef++ = y;
    717       *spec_coef++ = z;
    718       spec_index += 2;
    719     }
    720     ixheaacd_aac_read_byte_corr(&ptr_read_next, bit_pos, read_word,
    721                                 it_bit_buff->ptr_bit_buf_end);
    722     no_bands--;
    723     arr_seg_start_l++;
    724     p_remaining_bits_in_seg++;
    725   } while (no_bands != 0);
    726 
    727   it_bit_buff->ptr_read_next = ptr_read_next;
    728   ptr_hcr_info->str_dec_io.quant_spec_coeff_idx = spec_index;
    729 
    730   return arr_seg_start_l;
    731 }
    732 
    733 static PLATFORM_INLINE WORD16 ixheaacd_huff_dec_pair_hcr_non_pcw(
    734     ia_bit_buf_struct *itt_bit_buff, WORD32 *spec_coef,
    735     const UWORD16 *code_book_tbl, WORD32 tbl_sign, const UWORD32 *idx_table,
    736     WORD32 huff_mode)
    737 
    738 {
    739   WORD16 index, length;
    740   WORD32 y, z;
    741   WORD32 read_word1;
    742   WORD32 read_word;
    743 
    744   read_word = ixheaacd_aac_showbits_32(itt_bit_buff->byte_ptr,
    745                                        itt_bit_buff->bit_count, NULL);
    746 
    747   ixheaacd_huffman_decode(read_word, &index, &length, code_book_tbl, idx_table);
    748   read_word1 = read_word << length;
    749   if (tbl_sign) {
    750     WORD32 temp_word;
    751     temp_word = read_word1;
    752     y = index / huff_mode;
    753     z = index - huff_mode * y;
    754 
    755     if (y) {
    756       if (temp_word & 0x80000000) y = -y;
    757 
    758       temp_word = temp_word << 1;
    759       length++;
    760     }
    761     *spec_coef++ = y;
    762 
    763     if (z) {
    764       if (temp_word & 0x80000000) {
    765         z = -z;
    766       }
    767       temp_word <<= 1;
    768       length++;
    769     }
    770     *spec_coef++ = z;
    771   } else {
    772     y = (index / huff_mode) - 4;
    773     z = index - ((y + 4) * huff_mode) - 4;
    774 
    775     *spec_coef++ = y;
    776     *spec_coef++ = z;
    777   }
    778 
    779   return length;
    780 }
    781 
    782 static PLATFORM_INLINE UWORD16 *ixheaacd_huff_dec_quad_hcr_pcw(
    783     ia_hcr_info_struct *ptr_hcr_info, ia_bit_buf_struct *it_bit_buff,
    784     WORD no_bands, const UWORD16 *code_book_tbl, WORD32 tbl_sign,
    785     const UWORD32 *idx_table, WORD32 *read_word, WORD32 *read_bits,
    786     UWORD16 *arr_seg_start_l, WORD8 *p_remaining_bits_in_seg,
    787     WORD32 *ptr_num_decoded_bits) {
    788   WORD16 index, length;
    789 
    790   UWORD8 *ptr_read_next = it_bit_buff->ptr_read_next;
    791   WORD32 spec_index = ptr_hcr_info->str_dec_io.quant_spec_coeff_idx;
    792   WORD32 *spec_coef =
    793       ptr_hcr_info->str_dec_io.ptr_quant_spec_coeff_base + spec_index;
    794   WORD32 *bit_pos = &it_bit_buff->bit_pos;
    795 
    796   do {
    797     UWORD32 read_word1;
    798 
    799     WORD32 read_bit_offset =
    800         *arr_seg_start_l - (it_bit_buff->size - *read_bits);
    801 
    802     if (read_bit_offset) {
    803       *read_bits -= read_bit_offset;
    804       *bit_pos += read_bit_offset;
    805       ixheaacd_aac_read_byte_corr(&ptr_read_next, bit_pos, read_word,
    806                                   it_bit_buff->ptr_bit_buf_end);
    807     }
    808 
    809     read_word1 = *read_word << *bit_pos;
    810     ixheaacd_huffman_decode(read_word1, &index, &length, code_book_tbl,
    811                             idx_table);
    812     *bit_pos += length;
    813     *p_remaining_bits_in_seg -= length;
    814     *read_bits -= length;
    815     *ptr_num_decoded_bits += length;
    816     *arr_seg_start_l += length;
    817     ixheaacd_aac_read_byte_corr(&ptr_read_next, bit_pos, read_word,
    818                                 it_bit_buff->ptr_bit_buf_end);
    819     if (tbl_sign) {
    820       WORD32 temp_word;
    821       WORD32 w, x, y, z;
    822       temp_word = *read_word << *bit_pos;
    823       w = index / 27;
    824       index = index - w * 27;
    825       x = index / 9;
    826       index = index - x * 9;
    827       y = index / 3;
    828       z = index - y * 3;
    829       if (w) {
    830         if (temp_word & 0x80000000) w = -w;
    831         temp_word <<= 1;
    832         *bit_pos += 1;
    833         *p_remaining_bits_in_seg -= 1;
    834         *read_bits -= 1;
    835         *ptr_num_decoded_bits += 1;
    836         *arr_seg_start_l += 1;
    837       }
    838       *spec_coef++ = w;
    839       spec_index++;
    840 
    841       if (x) {
    842         if (temp_word & 0x80000000) x = -x;
    843         temp_word <<= 1;
    844         *bit_pos += 1;
    845         *p_remaining_bits_in_seg -= 1;
    846         *read_bits -= 1;
    847         *ptr_num_decoded_bits += 1;
    848         *arr_seg_start_l += 1;
    849       }
    850       *spec_coef++ = x;
    851       spec_index++;
    852       if (y) {
    853         if (temp_word & 0x80000000) y = -y;
    854         temp_word <<= 1;
    855         *bit_pos += 1;
    856         *p_remaining_bits_in_seg -= 1;
    857         *read_bits -= 1;
    858         *ptr_num_decoded_bits += 1;
    859         *arr_seg_start_l += 1;
    860       }
    861       *spec_coef++ = y;
    862       spec_index++;
    863       if (z) {
    864         if (temp_word & 0x80000000) z = -z;
    865         temp_word <<= 1;
    866         *bit_pos += 1;
    867         *p_remaining_bits_in_seg -= 1;
    868         *read_bits -= 1;
    869         *ptr_num_decoded_bits += 1;
    870         *arr_seg_start_l += 1;
    871       }
    872       *spec_coef++ = z;
    873       spec_index++;
    874 
    875     }
    876 
    877     else {
    878       WORD32 w, x, y, z;
    879 
    880       w = index / 27 - 1;
    881       index = index - (w + 1) * 27;
    882       x = index / 9 - 1;
    883       index = index - (x + 1) * 9;
    884       y = index / 3 - 1;
    885       z = index - ((y + 1) * 3) - 1;
    886       *spec_coef++ = w;
    887 
    888       *spec_coef++ = x;
    889 
    890       *spec_coef++ = y;
    891 
    892       *spec_coef++ = z;
    893       spec_index += 4;
    894     }
    895 
    896     ixheaacd_aac_read_byte_corr(&ptr_read_next, bit_pos, read_word,
    897                                 it_bit_buff->ptr_bit_buf_end);
    898     arr_seg_start_l++;
    899     p_remaining_bits_in_seg++;
    900     no_bands--;
    901   } while (no_bands != 0);
    902 
    903   it_bit_buff->ptr_read_next = ptr_read_next;
    904   ptr_hcr_info->str_dec_io.quant_spec_coeff_idx = spec_index;
    905 
    906   return arr_seg_start_l;
    907 }
    908 
    909 static UWORD16 *ixheaacd_huff_dec_word_hcr_pcw(
    910     ia_hcr_info_struct *ptr_hcr_info, ia_bit_buf_struct *it_bit_buff,
    911     WORD no_bands, const UWORD16 *code_book_tbl, WORD32 *read_word,
    912     const UWORD32 *idx_table, UWORD16 *arr_seg_start_l, WORD32 *read_bits,
    913     WORD8 *p_remaining_bits_in_seg, WORD32 *ptr_num_decoded_bits) {
    914   WORD32 sp1, sp2;
    915   WORD32 flush_cw;
    916   WORD32 i, value, norm_val, off;
    917   WORD32 out1, out2;
    918   WORD16 index;
    919   WORD32 length;
    920   UWORD8 *ptr_read_next = it_bit_buff->ptr_read_next;
    921   WORD32 spec_index = ptr_hcr_info->str_dec_io.quant_spec_coeff_idx;
    922   WORD32 *spec_coef =
    923       ptr_hcr_info->str_dec_io.ptr_quant_spec_coeff_base + spec_index;
    924   WORD32 *bit_pos = &it_bit_buff->bit_pos;
    925 
    926   do {
    927     UWORD32 read_word1;
    928 
    929     WORD32 read_bit_offset =
    930         *arr_seg_start_l - (it_bit_buff->size - *read_bits);
    931 
    932     if (read_bit_offset) {
    933       *read_bits -= read_bit_offset;
    934       *bit_pos += read_bit_offset;
    935       ixheaacd_aac_read_byte_corr1(&ptr_read_next, bit_pos, read_word,
    936                                    it_bit_buff->ptr_bit_buf_end);
    937     }
    938 
    939     read_word1 = *read_word << *bit_pos;
    940     ixheaacd_huff_sfb_table(read_word1, &index, &length, code_book_tbl,
    941                             idx_table);
    942     *bit_pos += length;
    943     *read_bits -= length;
    944     *arr_seg_start_l += length;
    945     *p_remaining_bits_in_seg -= length;
    946     *ptr_num_decoded_bits += length;
    947     ixheaacd_aac_read_byte_corr(&ptr_read_next, bit_pos, read_word,
    948                                 it_bit_buff->ptr_bit_buf_end);
    949 
    950     out1 = index / 17;
    951     out2 = index - out1 * 17;
    952     flush_cw = *read_word << *bit_pos;
    953 
    954     sp1 = out1;
    955     sp2 = out2;
    956 
    957     if (out1) {
    958       if (flush_cw & 0x80000000) {
    959         out1 = -out1;
    960       }
    961       *bit_pos += 1;
    962       *read_bits -= 1;
    963       *p_remaining_bits_in_seg -= 1;
    964       *ptr_num_decoded_bits += 1;
    965       *arr_seg_start_l += 1;
    966       flush_cw = (WORD32)flush_cw << 1;
    967     }
    968 
    969     if (out2) {
    970       *bit_pos += 1;
    971       *read_bits -= 1;
    972       *p_remaining_bits_in_seg -= 1;
    973       *ptr_num_decoded_bits += 1;
    974       *arr_seg_start_l += 1;
    975       if (flush_cw & 0x80000000) {
    976         out2 = -out2;
    977       }
    978     }
    979 
    980     ixheaacd_aac_read_byte_corr(&ptr_read_next, bit_pos, read_word,
    981                                 it_bit_buff->ptr_bit_buf_end);
    982 
    983     if (sp1 == 16) {
    984       i = 4;
    985       value = ixheaacd_extu(*read_word, *bit_pos, 23);
    986       value = value | 0xfffffe00;
    987       norm_val = ixheaacd_norm32(value);
    988 
    989       i += (norm_val - 22);
    990       *bit_pos += (norm_val - 21);
    991       *p_remaining_bits_in_seg -= (norm_val - 21);
    992       *ptr_num_decoded_bits += (norm_val - 21);
    993       *read_bits -= (norm_val - 21);
    994       *arr_seg_start_l += (norm_val - 21);
    995 
    996       ixheaacd_aac_read_byte_corr(&ptr_read_next, bit_pos, read_word,
    997                                   it_bit_buff->ptr_bit_buf_end);
    998 
    999       off = ixheaacd_extu(*read_word, *bit_pos, 32 - i);
   1000 
   1001       *bit_pos += i;
   1002       *p_remaining_bits_in_seg -= i;
   1003       *ptr_num_decoded_bits += i;
   1004       *read_bits -= i;
   1005       *arr_seg_start_l += i;
   1006 
   1007       ixheaacd_aac_read_byte_corr(&ptr_read_next, bit_pos, read_word,
   1008                                   it_bit_buff->ptr_bit_buf_end);
   1009       ixheaacd_aac_read_byte_corr(&ptr_read_next, bit_pos, read_word,
   1010                                   it_bit_buff->ptr_bit_buf_end);
   1011 
   1012       i = off + ((WORD32)1 << i);
   1013 
   1014       if (out1 < 0)
   1015         *spec_coef++ = -i;
   1016       else
   1017         *spec_coef++ = i;
   1018       spec_index++;
   1019     } else {
   1020       *spec_coef++ = out1;
   1021       spec_index++;
   1022     }
   1023 
   1024     if (sp2 == 16) {
   1025       i = 4;
   1026       value = ixheaacd_extu(*read_word, *bit_pos, 23);
   1027       value = value | 0xfffffe00;
   1028       norm_val = ixheaacd_norm32(value);
   1029 
   1030       i += (norm_val - 22);
   1031 
   1032       *bit_pos += (norm_val - 21);
   1033       *read_bits -= (norm_val - 21);
   1034       *p_remaining_bits_in_seg -= (norm_val - 21);
   1035       *ptr_num_decoded_bits += (norm_val - 21);
   1036       *arr_seg_start_l += (norm_val - 21);
   1037       ixheaacd_aac_read_byte_corr(&ptr_read_next, bit_pos, read_word,
   1038                                   it_bit_buff->ptr_bit_buf_end);
   1039 
   1040       off = ixheaacd_extu(*read_word, *bit_pos, 32 - i);
   1041 
   1042       *bit_pos += i;
   1043       *p_remaining_bits_in_seg -= i;
   1044       *ptr_num_decoded_bits += i;
   1045       *read_bits -= i;
   1046       *arr_seg_start_l += i;
   1047 
   1048       ixheaacd_aac_read_byte_corr(&ptr_read_next, bit_pos, read_word,
   1049                                   it_bit_buff->ptr_bit_buf_end);
   1050       ixheaacd_aac_read_byte_corr(&ptr_read_next, bit_pos, read_word,
   1051                                   it_bit_buff->ptr_bit_buf_end);
   1052 
   1053       i = off + ((WORD32)1 << i);
   1054 
   1055       if (out2 < 0)
   1056         *spec_coef++ = -i;
   1057       else
   1058         *spec_coef++ = i;
   1059       spec_index++;
   1060     } else {
   1061       *spec_coef++ = out2;
   1062       spec_index++;
   1063     }
   1064 
   1065     arr_seg_start_l++;
   1066     p_remaining_bits_in_seg++;
   1067 
   1068     no_bands--;
   1069   } while (no_bands != 0);
   1070 
   1071   it_bit_buff->ptr_read_next = ptr_read_next;
   1072   ptr_hcr_info->str_dec_io.quant_spec_coeff_idx = spec_index;
   1073 
   1074   return arr_seg_start_l;
   1075 }
   1076 
   1077 static VOID ixheaacd_decode_pcw(ia_bit_buf_struct *itt_bit_buff,
   1078                                 ia_hcr_info_struct *ptr_hcr_info,
   1079                                 ia_aac_dec_tables_struct *ptr_aac_tables) {
   1080   UWORD16 ext_sort_sec;
   1081   UWORD16 cur_ext_sort_cw_sec;
   1082   UWORD8 codebook;
   1083   UWORD8 dimension;
   1084   WORD32 increment;
   1085 
   1086   WORD32 num_ext_sorted_cw_in_sect_idx =
   1087       ptr_hcr_info->sect_info.num_ext_sorted_cw_in_sect_idx;
   1088   UWORD8 *ptr_ext_sorted_cw = ptr_hcr_info->sect_info.ptr_ext_sorted_cw;
   1089   WORD32 ext_sorted_cw_idx = ptr_hcr_info->sect_info.ext_sorted_cw_idx;
   1090   UWORD16 *ptr_num_ext_sorted_sect_in_sets =
   1091       ptr_hcr_info->sect_info.ptr_num_ext_sorted_sect_in_sets;
   1092   WORD32 num_ext_sorted_sect_in_sets_idx =
   1093       ptr_hcr_info->sect_info.num_ext_sorted_sect_in_sets_idx;
   1094   WORD32 *ptr_quant_spec_coeff =
   1095       ptr_hcr_info->str_dec_io.ptr_quant_spec_coeff_base;
   1096   UWORD16 *arr_seg_start_l = ptr_hcr_info->str_segment_info.arr_seg_start_l;
   1097   WORD8 *p_remaining_bits_in_seg =
   1098       ptr_hcr_info->str_segment_info.p_remaining_bits_in_seg;
   1099   UWORD8 *ptr_ext_sorted_sect_max_cb_len =
   1100       ptr_hcr_info->sect_info.ptr_ext_sorted_sect_max_cb_len;
   1101   WORD32 ext_sorted_sect_max_cb_len_idx =
   1102       ptr_hcr_info->sect_info.ext_sorted_sect_max_cb_len_idx;
   1103   UWORD8 max_allowed_cw_len;
   1104   WORD32 num_decoded_bits;
   1105   const UWORD8 *ptr_cb_dimension_tbl =
   1106       ptr_hcr_info->table_info.ptr_cb_dimension_tbl;
   1107 
   1108   WORD32 read_word = ixheaacd_aac_showbits_32(
   1109       itt_bit_buff->ptr_read_next, itt_bit_buff->cnt_bits, &increment);
   1110   WORD32 read_bits = itt_bit_buff->cnt_bits;
   1111 
   1112   itt_bit_buff->ptr_read_next += increment;
   1113 
   1114   for (ext_sort_sec =
   1115            ptr_num_ext_sorted_sect_in_sets[num_ext_sorted_sect_in_sets_idx];
   1116        ext_sort_sec != 0; ext_sort_sec--) {
   1117     codebook = ptr_ext_sorted_cw[ext_sorted_cw_idx];
   1118     if (codebook <= 0) return;
   1119 
   1120     ext_sorted_cw_idx++;
   1121     if (ext_sorted_cw_idx >= (MAX_SFB_HCR + MAX_HCR_SETS)) {
   1122       return;
   1123     }
   1124     dimension = ptr_cb_dimension_tbl[codebook];
   1125     max_allowed_cw_len =
   1126         ptr_ext_sorted_sect_max_cb_len[ext_sorted_sect_max_cb_len_idx];
   1127     ext_sorted_sect_max_cb_len_idx++;
   1128     if (ext_sorted_sect_max_cb_len_idx >= (MAX_SFB_HCR + MAX_HCR_SETS)) {
   1129       return;
   1130     }
   1131 
   1132     if (codebook <= 4) {
   1133       WORD32 tbl_sign = 0;
   1134       const UWORD16 *cb_table = (UWORD16 *)(ptr_aac_tables->code_book[codebook]);
   1135       const UWORD32 *idx_table = (UWORD32 *)(ptr_aac_tables->index_table[codebook]);
   1136 
   1137       if (codebook > 2) {
   1138         tbl_sign = 1;
   1139       }
   1140 
   1141       {
   1142         num_decoded_bits = 0;
   1143         cur_ext_sort_cw_sec =
   1144             ptr_hcr_info->sect_info
   1145                 .ptr_num_ext_sorted_cw_in_sect[num_ext_sorted_cw_in_sect_idx];
   1146 
   1147         arr_seg_start_l = ixheaacd_huff_dec_quad_hcr_pcw(
   1148             ptr_hcr_info, itt_bit_buff, cur_ext_sort_cw_sec, cb_table, tbl_sign,
   1149             idx_table, &read_word, &read_bits, arr_seg_start_l,
   1150             p_remaining_bits_in_seg, &num_decoded_bits);
   1151 
   1152         p_remaining_bits_in_seg += cur_ext_sort_cw_sec;
   1153 
   1154         if (cur_ext_sort_cw_sec * max_allowed_cw_len < num_decoded_bits) {
   1155           ptr_hcr_info->str_dec_io.err_log |= (ERROR_POS << 19);
   1156         }
   1157 
   1158         if (1 ==
   1159             ixheaacd_err_detect_pcw_segment(
   1160                 *p_remaining_bits_in_seg, ptr_hcr_info, PCW,
   1161                 ptr_quant_spec_coeff +
   1162                     ptr_hcr_info->str_dec_io.quant_spec_coeff_idx - dimension,
   1163                 dimension)) {
   1164           return;
   1165         }
   1166       }
   1167     } else if (codebook < 11) {
   1168       {
   1169         WORD32 tbl_sign = 0;
   1170         WORD32 huff_mode = 9;
   1171         const UWORD16 *cb_table = (UWORD16 *)(ptr_aac_tables->code_book[codebook]);
   1172         const UWORD32 *idx_table = (UWORD32 *)(ptr_aac_tables->index_table[codebook]);
   1173         num_decoded_bits = 0;
   1174 
   1175         if (codebook > 6) {
   1176           if (codebook > 8)
   1177             huff_mode = 13;
   1178           else
   1179             huff_mode = 8;
   1180           tbl_sign = 1;
   1181         }
   1182 
   1183         cur_ext_sort_cw_sec =
   1184             ptr_hcr_info->sect_info
   1185                 .ptr_num_ext_sorted_cw_in_sect[num_ext_sorted_cw_in_sect_idx];
   1186 
   1187         arr_seg_start_l = ixheaacd_huff_dec_pair_hcr_pcw(
   1188             ptr_hcr_info, itt_bit_buff, cur_ext_sort_cw_sec, cb_table,
   1189             &read_word, tbl_sign, idx_table, arr_seg_start_l, &read_bits,
   1190             huff_mode, p_remaining_bits_in_seg, &num_decoded_bits);
   1191 
   1192         p_remaining_bits_in_seg += cur_ext_sort_cw_sec;
   1193 
   1194         if (cur_ext_sort_cw_sec * max_allowed_cw_len < num_decoded_bits) {
   1195           ptr_hcr_info->str_dec_io.err_log |= (ERROR_POS << 18);
   1196         }
   1197 
   1198         if (1 ==
   1199             ixheaacd_err_detect_pcw_segment(
   1200                 *p_remaining_bits_in_seg, ptr_hcr_info, PCW_SIGN,
   1201                 ptr_quant_spec_coeff +
   1202                     ptr_hcr_info->str_dec_io.quant_spec_coeff_idx - dimension,
   1203                 dimension)) {
   1204           return;
   1205         }
   1206       }
   1207     } else if ((codebook >= 11)) {
   1208       const UWORD32 *idx_table =
   1209           ptr_aac_tables->pstr_huffmann_tables->idx_table_hf11;
   1210       const UWORD16 *cb_table =
   1211           ptr_aac_tables->pstr_huffmann_tables->input_table_cb11;
   1212       num_decoded_bits = 0;
   1213 
   1214       cur_ext_sort_cw_sec =
   1215           ptr_hcr_info->sect_info
   1216               .ptr_num_ext_sorted_cw_in_sect[num_ext_sorted_cw_in_sect_idx];
   1217 
   1218       arr_seg_start_l = ixheaacd_huff_dec_word_hcr_pcw(
   1219           ptr_hcr_info, itt_bit_buff, cur_ext_sort_cw_sec, cb_table, &read_word,
   1220           idx_table, arr_seg_start_l, &read_bits, p_remaining_bits_in_seg,
   1221           &num_decoded_bits);
   1222 
   1223       p_remaining_bits_in_seg += cur_ext_sort_cw_sec;
   1224 
   1225       if (cur_ext_sort_cw_sec * max_allowed_cw_len < num_decoded_bits) {
   1226         ptr_hcr_info->str_dec_io.err_log |= (ERROR_POS << 17);
   1227       }
   1228 
   1229       if (1 == ixheaacd_err_detect_pcw_segment(
   1230                    *p_remaining_bits_in_seg, ptr_hcr_info, PCW_ESC_SIGN,
   1231                    ptr_quant_spec_coeff +
   1232                        ptr_hcr_info->str_dec_io.quant_spec_coeff_idx - 2,
   1233                    2)) {
   1234         return;
   1235       }
   1236     }
   1237 
   1238     num_ext_sorted_cw_in_sect_idx++;
   1239     if (num_ext_sorted_cw_in_sect_idx >= MAX_SFB_HCR + MAX_HCR_SETS) {
   1240       return;
   1241     }
   1242   }
   1243 
   1244   num_ext_sorted_sect_in_sets_idx++;
   1245   if (num_ext_sorted_sect_in_sets_idx >= MAX_HCR_SETS) {
   1246     return;
   1247   }
   1248 
   1249   itt_bit_buff->cnt_bits = read_bits;
   1250 
   1251   ptr_hcr_info->sect_info.num_ext_sorted_cw_in_sect_idx =
   1252       num_ext_sorted_cw_in_sect_idx;
   1253   ptr_hcr_info->sect_info.ext_sorted_cw_idx = ext_sorted_cw_idx;
   1254   ptr_hcr_info->sect_info.num_ext_sorted_sect_in_sets_idx =
   1255       num_ext_sorted_sect_in_sets_idx;
   1256   ptr_hcr_info->sect_info.ext_sorted_sect_max_cb_len_idx =
   1257       ext_sorted_sect_max_cb_len_idx;
   1258 }
   1259 
   1260 static UWORD32 ixheaacd_init_segment_bit_field(WORD32 num_segment,
   1261                                                WORD8 *p_remaining_bits_in_seg) {
   1262   WORD16 i;
   1263   WORD16 num_valid_segment = 0;
   1264 
   1265   for (i = 0; i < num_segment; i++) {
   1266     if (p_remaining_bits_in_seg[i] != 0) {
   1267       num_valid_segment += 1;
   1268     }
   1269   }
   1270 
   1271   return num_valid_segment;
   1272 }
   1273 
   1274 UWORD8 ixheaacd_toggle_read_dir(UWORD8 read_direction) {
   1275   if (read_direction == FROM_LEFT_TO_RIGHT) {
   1276     return FROM_RIGHT_TO_LEFT;
   1277   } else {
   1278     return FROM_LEFT_TO_RIGHT;
   1279   }
   1280 }
   1281 
   1282 static PLATFORM_INLINE UWORD16 ixheaacd_huff_dec_quad_hcr_non_pcw(
   1283     ia_bit_buf_struct *itt_bit_buff, WORD32 *spec_coef,
   1284     const UWORD16 *code_book_tbl, WORD32 tbl_sign, const UWORD32 *idx_table) {
   1285   WORD16 index, length;
   1286   WORD16 cw_len;
   1287   WORD32 read_word;
   1288 
   1289   read_word = ixheaacd_aac_showbits_32(itt_bit_buff->byte_ptr,
   1290                                        itt_bit_buff->bit_count, NULL);
   1291   ixheaacd_huffman_decode(read_word, &index, &length, code_book_tbl, idx_table);
   1292   cw_len = length;
   1293   if (tbl_sign) {
   1294     WORD32 temp_word;
   1295     WORD32 w, x, y, z;
   1296     temp_word = read_word << length;
   1297     w = index / 27;
   1298     index = index - w * 27;
   1299     x = index / 9;
   1300     index = index - x * 9;
   1301     y = index / 3;
   1302     z = index - y * 3;
   1303     if (w) {
   1304       if (temp_word & 0x80000000) w = -w;
   1305       temp_word <<= 1;
   1306       cw_len++;
   1307     }
   1308     *spec_coef++ = w;
   1309 
   1310     if (x) {
   1311       if (temp_word & 0x80000000) x = -x;
   1312       temp_word <<= 1;
   1313       cw_len++;
   1314     }
   1315     *spec_coef++ = x;
   1316     if (y) {
   1317       if (temp_word & 0x80000000) y = -y;
   1318       temp_word <<= 1;
   1319       cw_len++;
   1320     }
   1321     *spec_coef++ = y;
   1322     if (z) {
   1323       if (temp_word & 0x80000000) z = -z;
   1324       temp_word <<= 1;
   1325       cw_len++;
   1326     }
   1327     *spec_coef++ = z;
   1328 
   1329   }
   1330 
   1331   else {
   1332     WORD32 w, x, y, z;
   1333 
   1334     w = index / 27 - 1;
   1335     index = index - (w + 1) * 27;
   1336     x = index / 9 - 1;
   1337     index = index - (x + 1) * 9;
   1338     y = index / 3 - 1;
   1339     z = index - ((y + 1) * 3) - 1;
   1340     *spec_coef++ = w;
   1341     *spec_coef++ = x;
   1342     *spec_coef++ = y;
   1343     *spec_coef++ = z;
   1344   }
   1345 
   1346   return cw_len;
   1347 }
   1348 
   1349 static PLATFORM_INLINE UWORD16 ixheaacd_huff_dec_word_hcr_non_pcw(
   1350     ia_bit_buf_struct *itt_bit_buff, WORD32 *spec_coef,
   1351     const UWORD16 *code_book_tbl, const UWORD32 *idx_table) {
   1352   WORD32 sp1, sp2;
   1353   WORD32 flush_cw;
   1354   WORD32 i, value, norm_val, off;
   1355   WORD32 out1, out2;
   1356   UWORD16 cw_len;
   1357 
   1358   WORD16 index;
   1359   WORD32 length;
   1360 
   1361   WORD32 read_word;
   1362   WORD32 increment;
   1363 
   1364   read_word = ixheaacd_aac_showbits_32(itt_bit_buff->byte_ptr,
   1365                                        itt_bit_buff->bit_count, &increment);
   1366 
   1367   UWORD8 *ptr_read_next = itt_bit_buff->byte_ptr;
   1368   ptr_read_next += increment;
   1369 
   1370   ixheaacd_huff_sfb_table(read_word, &index, &length, code_book_tbl, idx_table);
   1371   cw_len = length;
   1372 
   1373   ixheaacd_aac_read_byte_corr1(&ptr_read_next, &length, &read_word, NULL);
   1374 
   1375   out1 = index / 17;
   1376   out2 = index - out1 * 17;
   1377   flush_cw = read_word << length;
   1378 
   1379   sp1 = out1;
   1380   sp2 = out2;
   1381 
   1382   if (out1) {
   1383     if (flush_cw & 0x80000000) {
   1384       out1 = -out1;
   1385     }
   1386     flush_cw = (WORD32)flush_cw << 1;
   1387     length++;
   1388     cw_len++;
   1389   }
   1390 
   1391   if (out2) {
   1392     if (flush_cw & 0x80000000) {
   1393       out2 = -out2;
   1394     }
   1395     length++;
   1396     cw_len++;
   1397   }
   1398 
   1399   ixheaacd_aac_read_byte_corr1(&ptr_read_next, &length, &read_word, NULL);
   1400 
   1401   if (sp1 == 16) {
   1402     i = 4;
   1403     value = ixheaacd_extu(read_word, length, 23);
   1404     value = value | 0xfffffe00;
   1405     norm_val = ixheaacd_norm32(value);
   1406 
   1407     i += (norm_val - 22);
   1408     length += (norm_val - 21);
   1409     cw_len += (norm_val - 21);
   1410 
   1411     ixheaacd_aac_read_byte_corr1(&ptr_read_next, &length, &read_word, NULL);
   1412 
   1413     off = ixheaacd_extu(read_word, length, 32 - i);
   1414     length += i;
   1415     cw_len += i;
   1416 
   1417     ixheaacd_aac_read_byte_corr1(&ptr_read_next, &length, &read_word, NULL);
   1418 
   1419     i = off + ((WORD32)1 << i);
   1420 
   1421     if (out1 < 0)
   1422       *spec_coef++ = -i;
   1423     else
   1424       *spec_coef++ = i;
   1425   } else {
   1426     *spec_coef++ = out1;
   1427   }
   1428 
   1429   if (sp2 == 16) {
   1430     i = 4;
   1431     value = ixheaacd_extu(read_word, length, 23);
   1432     value = value | 0xfffffe00;
   1433     norm_val = ixheaacd_norm32(value);
   1434 
   1435     i += (norm_val - 22);
   1436     length += (norm_val - 21);
   1437     cw_len += (norm_val - 21);
   1438 
   1439     ixheaacd_aac_read_byte_corr1(&ptr_read_next, &length, &read_word, NULL);
   1440 
   1441     off = ixheaacd_extu(read_word, length, 32 - i);
   1442     length += i;
   1443     cw_len += i;
   1444 
   1445     ixheaacd_aac_read_byte_corr1(&ptr_read_next, &length, &read_word, NULL);
   1446     i = off + ((WORD32)1 << i);
   1447 
   1448     if (out2 < 0)
   1449       *spec_coef++ = -i;
   1450     else
   1451       *spec_coef++ = i;
   1452   } else {
   1453     *spec_coef++ = out2;
   1454   }
   1455 
   1456   return cw_len;
   1457 }
   1458 
   1459 static VOID ixheaacd_decode_hcr_non_pcw(
   1460     ia_bit_buf_struct *itt_bit_buff, ia_hcr_info_struct *ptr_hcr_info,
   1461     ia_aac_dec_tables_struct *ptr_aac_tables, WORD32 *cw_offset, WORD32 trial,
   1462     WORD32 start) {
   1463   WORD16 codeword_len = 0;
   1464   WORD8 seg_bits_left;
   1465   UWORD8 tot_bits_to_save, code_bits_to_save, extra_code_bits;
   1466   WORD32 segment_offset = 0;
   1467   WORD8 *p_remaining_bits_in_seg =
   1468       ptr_hcr_info->str_segment_info.p_remaining_bits_in_seg;
   1469   WORD32 num_segment = ptr_hcr_info->str_segment_info.num_segment;
   1470 
   1471   for (segment_offset = start; segment_offset < trial;
   1472        segment_offset++, *cw_offset += 1) {
   1473     if (p_remaining_bits_in_seg[segment_offset] &&
   1474         !ptr_hcr_info->str_segment_info.is_decoded[*cw_offset]) {
   1475       {
   1476         UWORD32 i_qsc;
   1477         WORD8 current_seg_bits = p_remaining_bits_in_seg[segment_offset];
   1478 
   1479         itt_bit_buff->byte_ptr = itt_bit_buff->ptr_start;
   1480         itt_bit_buff->valid_bits = 0;
   1481         itt_bit_buff->byte = 0;
   1482         itt_bit_buff->bit_count = 0;
   1483         itt_bit_buff->write_bit_count = 0;
   1484 
   1485         if (ptr_hcr_info->str_segment_info.p_num_bits[*cw_offset]) {
   1486           extra_code_bits = max(
   1487               ptr_hcr_info->str_segment_info.p_num_bits[*cw_offset] - 32, 0);
   1488           code_bits_to_save =
   1489               min(ptr_hcr_info->str_segment_info.p_num_bits[*cw_offset], 32);
   1490 
   1491           ixheaacd_write_bit(
   1492               itt_bit_buff,
   1493               ptr_hcr_info->str_segment_info.code_extra[*cw_offset],
   1494               extra_code_bits);
   1495           ixheaacd_write_bit(itt_bit_buff,
   1496                              ptr_hcr_info->str_segment_info.code[*cw_offset],
   1497                              code_bits_to_save);
   1498         }
   1499         {
   1500           UWORD32 bit;
   1501           WORD32 read_bit_offset;
   1502 
   1503           if (ptr_hcr_info->str_segment_info.read_direction ==
   1504               FROM_LEFT_TO_RIGHT) {
   1505             read_bit_offset =
   1506                 ptr_hcr_info->str_segment_info.arr_seg_start_l[segment_offset] -
   1507                 (itt_bit_buff->size - itt_bit_buff->cnt_bits);
   1508             if (read_bit_offset) {
   1509               itt_bit_buff->cnt_bits += -read_bit_offset;
   1510             }
   1511             itt_bit_buff->ptr_read_next =
   1512                 itt_bit_buff->ptr_bit_buf_base +
   1513                 ((itt_bit_buff->size - itt_bit_buff->cnt_bits) >> 3);
   1514             itt_bit_buff->bit_pos =
   1515                 ((itt_bit_buff->size - itt_bit_buff->cnt_bits) & 7);
   1516 
   1517             for (; p_remaining_bits_in_seg[segment_offset] > 0;
   1518                  p_remaining_bits_in_seg[segment_offset] -= 1) {
   1519               bit = ixheaacd_aac_read_bit_rev(itt_bit_buff);
   1520               ptr_hcr_info->str_segment_info.arr_seg_start_l[segment_offset] +=
   1521                   1;
   1522 
   1523               ixheaacd_write_bit(itt_bit_buff, bit, 1);
   1524             }
   1525 
   1526           } else {
   1527             read_bit_offset =
   1528                 ptr_hcr_info->str_segment_info.arr_seg_start_r[segment_offset] -
   1529                 (itt_bit_buff->size - itt_bit_buff->cnt_bits);
   1530             if (read_bit_offset) {
   1531               itt_bit_buff->cnt_bits += -read_bit_offset;
   1532             }
   1533             itt_bit_buff->ptr_read_next =
   1534                 itt_bit_buff->ptr_bit_buf_base +
   1535                 ((itt_bit_buff->size - itt_bit_buff->cnt_bits) >> 3);
   1536             itt_bit_buff->bit_pos =
   1537                 ((itt_bit_buff->size - itt_bit_buff->cnt_bits) & 7);
   1538 
   1539             for (; p_remaining_bits_in_seg[segment_offset] > 0;
   1540                  p_remaining_bits_in_seg[segment_offset] -= 1) {
   1541               bit = ixheaacd_aac_read_bit(itt_bit_buff);
   1542               ptr_hcr_info->str_segment_info.arr_seg_start_r[segment_offset] -=
   1543                   1;
   1544               ixheaacd_write_bit(itt_bit_buff, bit, 1);
   1545             }
   1546           }
   1547         }
   1548 
   1549         ixheaacd_write_bit(itt_bit_buff, 0, 32 - itt_bit_buff->bit_count % 32);
   1550         itt_bit_buff->valid_bits = 8;
   1551         itt_bit_buff->byte_ptr = itt_bit_buff->ptr_start;
   1552         itt_bit_buff->byte = *itt_bit_buff->ptr_start;
   1553 
   1554         if (current_seg_bits) {
   1555           i_qsc = ptr_hcr_info->str_non_pcw_side_info
   1556                       .res_ptr_idx[*cw_offset % num_segment];
   1557 
   1558           if (ptr_hcr_info->str_non_pcw_side_info
   1559                   .ptr_cb[*cw_offset % num_segment] <= 4) {
   1560             WORD32 tbl_sign = 0;
   1561             const UWORD16 *cb_table =
   1562                 (UWORD16
   1563                      *)(ptr_aac_tables
   1564                             ->code_book[ptr_hcr_info->str_non_pcw_side_info
   1565                                             .ptr_cb[*cw_offset % num_segment]]);
   1566             const UWORD32 *idx_table =
   1567                 (UWORD32 *)(ptr_aac_tables->index_table
   1568                                 [ptr_hcr_info->str_non_pcw_side_info
   1569                                      .ptr_cb[*cw_offset % num_segment]]);
   1570 
   1571             if (ptr_hcr_info->str_non_pcw_side_info
   1572                     .ptr_cb[*cw_offset % num_segment] > 2) {
   1573               tbl_sign = 1;
   1574             }
   1575 
   1576             codeword_len = ixheaacd_huff_dec_quad_hcr_non_pcw(
   1577                 itt_bit_buff,
   1578                 &ptr_hcr_info->str_non_pcw_side_info.ptr_result_base[i_qsc],
   1579                 cb_table, tbl_sign, idx_table);
   1580 
   1581             seg_bits_left =
   1582                 current_seg_bits - codeword_len +
   1583                 ptr_hcr_info->str_segment_info.p_num_bits[*cw_offset];
   1584 
   1585           }
   1586 
   1587           else if (ptr_hcr_info->str_non_pcw_side_info
   1588                        .ptr_cb[*cw_offset % num_segment] < 11) {
   1589             WORD32 tbl_sign = 0;
   1590             WORD32 huff_mode = 9;
   1591 
   1592             const UWORD16 *cb_table =
   1593                 (UWORD16
   1594                      *)(ptr_aac_tables
   1595                             ->code_book[ptr_hcr_info->str_non_pcw_side_info
   1596                                             .ptr_cb[*cw_offset % num_segment]]);
   1597             const UWORD32 *idx_table =
   1598                 (UWORD32 *)(ptr_aac_tables->index_table
   1599                                 [ptr_hcr_info->str_non_pcw_side_info
   1600                                      .ptr_cb[*cw_offset % num_segment]]);
   1601 
   1602             if (ptr_hcr_info->str_non_pcw_side_info
   1603                     .ptr_cb[*cw_offset % num_segment] > 6) {
   1604               if (ptr_hcr_info->str_non_pcw_side_info
   1605                       .ptr_cb[*cw_offset % num_segment] > 8)
   1606                 huff_mode = 13;
   1607               else
   1608                 huff_mode = 8;
   1609               tbl_sign = 1;
   1610             }
   1611             codeword_len = ixheaacd_huff_dec_pair_hcr_non_pcw(
   1612                 itt_bit_buff,
   1613                 &ptr_hcr_info->str_non_pcw_side_info.ptr_result_base[i_qsc],
   1614                 cb_table, tbl_sign, idx_table, huff_mode);
   1615 
   1616             seg_bits_left =
   1617                 current_seg_bits - codeword_len +
   1618                 ptr_hcr_info->str_segment_info.p_num_bits[*cw_offset];
   1619           }
   1620           if (ptr_hcr_info->str_non_pcw_side_info
   1621                   .ptr_cb[*cw_offset % num_segment] >= 11) {
   1622             const UWORD32 *idx_table =
   1623                 ptr_aac_tables->pstr_huffmann_tables->idx_table_hf11;
   1624             const UWORD16 *cb_table =
   1625                 ptr_aac_tables->pstr_huffmann_tables->input_table_cb11;
   1626 
   1627             codeword_len = ixheaacd_huff_dec_word_hcr_non_pcw(
   1628                 itt_bit_buff,
   1629                 &ptr_hcr_info->str_non_pcw_side_info.ptr_result_base[i_qsc],
   1630                 cb_table, idx_table);
   1631 
   1632             seg_bits_left =
   1633                 current_seg_bits - codeword_len +
   1634                 ptr_hcr_info->str_segment_info.p_num_bits[*cw_offset];
   1635           }
   1636           if (seg_bits_left < 0) {
   1637             tot_bits_to_save =
   1638                 current_seg_bits +
   1639                 ptr_hcr_info->str_segment_info.p_num_bits[*cw_offset];
   1640             extra_code_bits = max(tot_bits_to_save - 32, 0);
   1641             code_bits_to_save = min(tot_bits_to_save, 32);
   1642 
   1643             ptr_hcr_info->str_segment_info.code_extra[*cw_offset] =
   1644                 ixheaacd_read_bit(itt_bit_buff, extra_code_bits);
   1645             ptr_hcr_info->str_segment_info.code[*cw_offset] =
   1646                 ixheaacd_read_bit(itt_bit_buff, code_bits_to_save);
   1647             ptr_hcr_info->str_segment_info.p_num_bits[*cw_offset] =
   1648                 tot_bits_to_save;
   1649 
   1650             p_remaining_bits_in_seg[segment_offset] = 0;
   1651             if (p_remaining_bits_in_seg[segment_offset] < 0)
   1652               p_remaining_bits_in_seg[segment_offset] = 0;
   1653           } else {
   1654             p_remaining_bits_in_seg[segment_offset] =
   1655                 current_seg_bits -
   1656                 (codeword_len -
   1657                  ptr_hcr_info->str_segment_info.p_num_bits[*cw_offset]);
   1658             ptr_hcr_info->str_segment_info.p_num_bits[*cw_offset] = 0;
   1659             ptr_hcr_info->str_segment_info.is_decoded[*cw_offset] = 1;
   1660             if (p_remaining_bits_in_seg[segment_offset] < 0)
   1661               p_remaining_bits_in_seg[segment_offset] = 0;
   1662           }
   1663 
   1664           if (p_remaining_bits_in_seg[segment_offset] > 0) {
   1665             if (ptr_hcr_info->str_segment_info.read_direction ==
   1666                 FROM_LEFT_TO_RIGHT)
   1667               ptr_hcr_info->str_segment_info.arr_seg_start_l[segment_offset] -=
   1668                   (p_remaining_bits_in_seg[segment_offset]);
   1669             else
   1670               ptr_hcr_info->str_segment_info.arr_seg_start_r[segment_offset] +=
   1671                   (p_remaining_bits_in_seg[segment_offset]);
   1672           }
   1673         }
   1674       }
   1675     }
   1676   }
   1677 }
   1678 
   1679 VOID ixheaacd_decode_non_pcw(ia_bit_buf_struct *itt_bit_buff,
   1680                              ia_hcr_info_struct *ptr_hcr_info,
   1681                              ia_aac_dec_tables_struct *ptr_aac_tables) {
   1682   UWORD32 num_valid_segment;
   1683   WORD32 cw_offset;
   1684   WORD32 trial;
   1685   WORD32 num_segment;
   1686   WORD32 num_code_word;
   1687   UWORD8 num_set;
   1688   UWORD8 current_set;
   1689   WORD32 code_word_set;
   1690   WORD32 loop1, loop2;
   1691 
   1692   num_segment = ptr_hcr_info->str_segment_info.num_segment;
   1693 
   1694   num_valid_segment = ixheaacd_init_segment_bit_field(
   1695       num_segment, ptr_hcr_info->str_segment_info.p_remaining_bits_in_seg);
   1696 
   1697   if (num_valid_segment != 0) {
   1698     num_code_word = ptr_hcr_info->sect_info.num_code_word;
   1699     num_set = ((num_code_word - 1) / num_segment) + 1;
   1700 
   1701     ptr_hcr_info->str_segment_info.read_direction = FROM_RIGHT_TO_LEFT;
   1702 
   1703     for (current_set = 1; current_set < num_set; current_set++) {
   1704       num_code_word -= num_segment;
   1705       if (num_code_word < num_segment) {
   1706         code_word_set = num_code_word;
   1707       } else {
   1708         code_word_set = num_segment;
   1709       }
   1710 
   1711       ixheaacd_nonpcw_sideinfo_init(ptr_hcr_info);
   1712 
   1713       cw_offset = num_segment * current_set;
   1714 
   1715       ixheaacd_decode_hcr_non_pcw(itt_bit_buff, ptr_hcr_info, ptr_aac_tables,
   1716                                   &cw_offset, code_word_set, 0);
   1717 
   1718       for (trial = 1; trial < num_segment; trial++) {
   1719         cw_offset = num_segment * current_set;
   1720 
   1721         loop1 = min(num_segment, trial + code_word_set);
   1722         loop2 = max(0, trial + code_word_set - num_segment);
   1723 
   1724         ixheaacd_decode_hcr_non_pcw(itt_bit_buff, ptr_hcr_info, ptr_aac_tables,
   1725                                     &cw_offset, loop1, trial);
   1726 
   1727         ixheaacd_decode_hcr_non_pcw(itt_bit_buff, ptr_hcr_info, ptr_aac_tables,
   1728                                     &cw_offset, loop2, 0);
   1729       }
   1730 
   1731       ptr_hcr_info->str_segment_info.read_direction = ixheaacd_toggle_read_dir(
   1732           ptr_hcr_info->str_segment_info.read_direction);
   1733     }
   1734   }
   1735 }
   1736 
   1737 static VOID ixheaacd_hcr_reorder_quantized_spec_coeff(
   1738     ia_hcr_info_struct *ptr_hcr_info,
   1739     ia_aac_dec_channel_info_struct *ptr_aac_dec_channel_info) {
   1740   WORD32 qsc;
   1741   UWORD32 abs_qsc;
   1742   UWORD32 i, j;
   1743   UWORD16 num_spec_val_sect;
   1744   WORD32 *ptr_teva;
   1745   UWORD16 lav_err_cnt = 0;
   1746 
   1747   UWORD32 num_sect = ptr_hcr_info->str_dec_io.num_sect;
   1748   WORD32 *ptr_quant_spec_coeff_base =
   1749       ptr_hcr_info->str_dec_io.ptr_quant_spec_coeff_base;
   1750   WORD32 *ptr_quant_spec_coeff =
   1751       ptr_hcr_info->str_dec_io.ptr_quant_spec_coeff_base;
   1752   const UWORD8 *ptr_cb_dim_shift_tbl =
   1753       ptr_hcr_info->table_info.ptr_cb_dim_shift_tbl;
   1754   const UWORD16 *ptr_lav_tbl = ptr_hcr_info->table_info.ptr_lav_tbl;
   1755   UWORD8 *ptr_sorted_cb = ptr_hcr_info->sect_info.ptr_sorted_cb;
   1756   UWORD16 *ptr_num_sorted_cw_in_sect =
   1757       ptr_hcr_info->sect_info.ptr_num_sorted_cw_in_sect;
   1758   UWORD16 *ptr_reorder_offset = ptr_hcr_info->sect_info.ptr_reorder_offset;
   1759   WORD32 *arr_temp_values = ptr_hcr_info->str_segment_info.arr_temp_values;
   1760   WORD32 *ptr_bak = ptr_hcr_info->str_segment_info.arr_temp_values;
   1761 
   1762   for (i = num_sect; i != 0; i--) {
   1763     num_spec_val_sect = *ptr_num_sorted_cw_in_sect++
   1764                         << ptr_cb_dim_shift_tbl[*ptr_sorted_cb];
   1765     ptr_teva = &arr_temp_values[*ptr_reorder_offset++];
   1766     for (j = num_spec_val_sect; j != 0; j--) {
   1767       qsc = *ptr_quant_spec_coeff++;
   1768       abs_qsc = ixheaacd_abs32(qsc);
   1769       if (abs_qsc <= ptr_lav_tbl[*ptr_sorted_cb]) {
   1770         *ptr_teva++ = (WORD32)qsc;
   1771       } else {
   1772         if (abs_qsc == 8192) {
   1773           *ptr_teva++ = (WORD32)qsc;
   1774         } else {
   1775           *ptr_teva++ = (WORD32)8192;
   1776           lav_err_cnt += 1;
   1777         }
   1778       }
   1779     }
   1780     ptr_sorted_cb++;
   1781   }
   1782 
   1783   if (ptr_aac_dec_channel_info->str_ics_info.window_sequence ==
   1784       EIGHT_SHORT_SEQUENCE) {
   1785     WORD32 *ptr_out;
   1786     WORD8 window;
   1787 
   1788     ptr_bak = ptr_hcr_info->str_segment_info.arr_temp_values;
   1789     for (window = 0; window < 8; window++) {
   1790       ptr_out = ptr_quant_spec_coeff_base +
   1791                 (window * ptr_aac_dec_channel_info->granule_len);
   1792       for (i = 0; i < (LINES_PER_UNIT_GROUP); i++) {
   1793         ptr_teva = ptr_bak + (window << 2) + i * 32;
   1794         for (j = (LINES_PER_UNIT); j != 0; j--) {
   1795           *ptr_out++ = *ptr_teva++;
   1796         }
   1797       }
   1798     }
   1799   } else {
   1800     ptr_quant_spec_coeff = ptr_quant_spec_coeff_base;
   1801     for (i = 1024; i != 0; i--) {
   1802       *ptr_quant_spec_coeff++ = *ptr_bak++;
   1803     }
   1804   }
   1805 
   1806   if (lav_err_cnt != 0) {
   1807     ptr_hcr_info->str_dec_io.err_log |= (ERROR_POS << 1);
   1808   }
   1809 }
   1810 
   1811 static VOID ixheaacd_err_detect_segmentation_final(
   1812     ia_hcr_info_struct *ptr_hcr_info) {
   1813   UWORD8 segmentation_err_flag = 0;
   1814   UWORD16 i;
   1815   WORD8 *p_remaining_bits_in_seg =
   1816       ptr_hcr_info->str_segment_info.p_remaining_bits_in_seg;
   1817   UWORD32 num_segment = ptr_hcr_info->str_segment_info.num_segment;
   1818 
   1819   for (i = num_segment; i != 0; i--) {
   1820     if (*p_remaining_bits_in_seg++ != 0) {
   1821       segmentation_err_flag = 1;
   1822     }
   1823   }
   1824   if (segmentation_err_flag == 1) {
   1825     ptr_hcr_info->str_dec_io.err_log |= ERROR_POS;
   1826   }
   1827 }
   1828 
   1829 UWORD32 ixheaacd_hcr_decoder(
   1830     ia_hcr_info_struct *ptr_hcr_info,
   1831     ia_aac_dec_channel_info_struct *ptr_aac_dec_channel_info,
   1832     ia_aac_dec_tables_struct *ptr_aac_tables, ia_bit_buf_struct *itt_bit_buff) {
   1833   WORD32 ptr_tmp1, ptr_tmp2, ptr_tmp3, ptr_tmp4;
   1834   WORD32 ptr_tmp5;
   1835 
   1836   WORD32 bit_cnt_offset;
   1837   UWORD32 save_bit_cnt = itt_bit_buff->cnt_bits;
   1838 
   1839   ixheaacd_huff_calc_num_cwd(ptr_hcr_info);
   1840 
   1841   ixheaacd_huff_sort_sect_cb_cwd(ptr_hcr_info);
   1842 
   1843   if (ixheaacd_hcr_prepare_segmentation_grid(ptr_hcr_info) != 0)
   1844     return (ptr_hcr_info->str_dec_io.err_log);
   1845 
   1846   ixheaacd_huff_ext_sect_info(ptr_hcr_info);
   1847 
   1848   if ((ptr_hcr_info->str_dec_io.err_log & HCR_FATAL_PCW_ERROR_MASK) != 0) {
   1849     return (ptr_hcr_info->str_dec_io.err_log);
   1850   }
   1851 
   1852   ixheaacd_calc_num_ext_sorted_sect_sets(
   1853       ptr_hcr_info->str_segment_info.num_segment,
   1854       ptr_hcr_info->sect_info.ptr_num_ext_sorted_cw_in_sect,
   1855       ptr_hcr_info->sect_info.num_ext_sorted_cw_in_sect_idx,
   1856       ptr_hcr_info->sect_info.ptr_num_ext_sorted_sect_in_sets,
   1857       ptr_hcr_info->sect_info.num_ext_sorted_sect_in_sets_idx);
   1858 
   1859   ptr_tmp1 = ptr_hcr_info->sect_info.num_ext_sorted_cw_in_sect_idx;
   1860   ptr_tmp2 = ptr_hcr_info->sect_info.ext_sorted_cw_idx;
   1861   ptr_tmp3 = ptr_hcr_info->sect_info.num_ext_sorted_sect_in_sets_idx;
   1862   ptr_tmp4 = ptr_hcr_info->str_dec_io.quant_spec_coeff_idx;
   1863   ptr_tmp5 = ptr_hcr_info->sect_info.ext_sorted_sect_max_cb_len_idx;
   1864 
   1865   ixheaacd_decode_pcw(itt_bit_buff, ptr_hcr_info, ptr_aac_tables);
   1866 
   1867   if ((ptr_hcr_info->str_dec_io.err_log & HCR_FATAL_PCW_ERROR_MASK) == 0) {
   1868     ixheaacd_decode_non_pcw(itt_bit_buff, ptr_hcr_info, ptr_aac_tables);
   1869   }
   1870 
   1871   ixheaacd_err_detect_segmentation_final(ptr_hcr_info);
   1872 
   1873   ptr_hcr_info->sect_info.num_ext_sorted_cw_in_sect_idx = ptr_tmp1;
   1874   ptr_hcr_info->sect_info.ext_sorted_cw_idx = ptr_tmp2;
   1875   ptr_hcr_info->sect_info.num_ext_sorted_sect_in_sets_idx = ptr_tmp3;
   1876   ptr_hcr_info->str_dec_io.quant_spec_coeff_idx = ptr_tmp4;
   1877   ptr_hcr_info->sect_info.ext_sorted_sect_max_cb_len_idx = ptr_tmp5;
   1878 
   1879   ixheaacd_hcr_reorder_quantized_spec_coeff(ptr_hcr_info,
   1880                                             ptr_aac_dec_channel_info);
   1881 
   1882   bit_cnt_offset = (WORD32)itt_bit_buff->cnt_bits - (WORD32)save_bit_cnt;
   1883   if (bit_cnt_offset) {
   1884     itt_bit_buff->cnt_bits += -bit_cnt_offset;
   1885     itt_bit_buff->ptr_read_next =
   1886         itt_bit_buff->ptr_bit_buf_base +
   1887         ((itt_bit_buff->size - itt_bit_buff->cnt_bits) >> 3);
   1888     itt_bit_buff->bit_pos = (itt_bit_buff->size - itt_bit_buff->cnt_bits) & 7;
   1889   }
   1890 
   1891   return (ptr_hcr_info->str_dec_io.err_log);
   1892 }
   1893