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 VOID 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   ptr_hcr_info->str_segment_info.num_segment = num_segment;
    634 }
    635 
    636 static PLATFORM_INLINE UWORD16 *ixheaacd_huff_dec_pair_hcr_pcw(
    637     ia_hcr_info_struct *ptr_hcr_info, ia_bit_buf_struct *it_bit_buff,
    638     WORD no_bands, const UWORD16 *code_book_tbl, WORD32 *read_word,
    639     WORD32 tbl_sign, const UWORD32 *idx_table, UWORD16 *arr_seg_start_l,
    640     WORD32 *read_bits, WORD32 huff_mode, WORD8 *p_remaining_bits_in_seg,
    641     WORD32 *ptr_num_decoded_bits)
    642 
    643 {
    644   WORD32 spec_index = ptr_hcr_info->str_dec_io.quant_spec_coeff_idx;
    645   WORD32 *spec_coef =
    646       ptr_hcr_info->str_dec_io.ptr_quant_spec_coeff_base + spec_index;
    647   WORD16 index, length;
    648   WORD32 y, z;
    649   UWORD8 *ptr_read_next = it_bit_buff->ptr_read_next;
    650   WORD32 *bit_pos = &it_bit_buff->bit_pos;
    651 
    652   do {
    653     UWORD32 read_word1;
    654 
    655     WORD32 read_bit_offset =
    656         *arr_seg_start_l - (it_bit_buff->size - *read_bits);
    657 
    658     if (read_bit_offset) {
    659       *read_bits -= read_bit_offset;
    660       *bit_pos += read_bit_offset;
    661       ixheaacd_aac_read_byte_corr(&ptr_read_next, bit_pos, read_word,
    662                                   it_bit_buff->ptr_bit_buf_end);
    663     }
    664 
    665     read_word1 = *read_word << *bit_pos;
    666     ixheaacd_huffman_decode(read_word1, &index, &length, code_book_tbl,
    667                             idx_table);
    668     *bit_pos += length;
    669     *ptr_num_decoded_bits += length;
    670     *p_remaining_bits_in_seg -= length;
    671     *arr_seg_start_l += length;
    672     *read_bits -= length;
    673     ixheaacd_aac_read_byte_corr(&ptr_read_next, bit_pos, read_word,
    674                                 it_bit_buff->ptr_bit_buf_end);
    675     if (tbl_sign) {
    676       WORD32 temp_word;
    677       temp_word = *read_word << *bit_pos;
    678       y = index / huff_mode;
    679       z = index - huff_mode * y;
    680 
    681       if (y) {
    682         if (temp_word & 0x80000000) y = -y;
    683 
    684         temp_word = temp_word << 1;
    685         *bit_pos += 1;
    686         *p_remaining_bits_in_seg -= 1;
    687         *ptr_num_decoded_bits += 1;
    688         *arr_seg_start_l += 1;
    689         *read_bits -= 1;
    690       }
    691       *spec_coef++ = y;
    692       spec_index++;
    693 
    694       if (z) {
    695         if (temp_word & 0x80000000) {
    696           z = -z;
    697         }
    698         temp_word <<= 1;
    699         *bit_pos += 1;
    700         *p_remaining_bits_in_seg -= 1;
    701         *ptr_num_decoded_bits += 1;
    702         *arr_seg_start_l += 1;
    703         *read_bits -= 1;
    704       }
    705       *spec_coef++ = z;
    706       spec_index++;
    707     } else {
    708       y = (index / huff_mode) - 4;
    709       z = index - ((y + 4) * huff_mode) - 4;
    710 
    711       *spec_coef++ = y;
    712       *spec_coef++ = z;
    713       spec_index += 2;
    714     }
    715     ixheaacd_aac_read_byte_corr(&ptr_read_next, bit_pos, read_word,
    716                                 it_bit_buff->ptr_bit_buf_end);
    717     no_bands--;
    718     arr_seg_start_l++;
    719     p_remaining_bits_in_seg++;
    720   } while (no_bands != 0);
    721 
    722   it_bit_buff->ptr_read_next = ptr_read_next;
    723   ptr_hcr_info->str_dec_io.quant_spec_coeff_idx = spec_index;
    724 
    725   return arr_seg_start_l;
    726 }
    727 
    728 static PLATFORM_INLINE WORD16 ixheaacd_huff_dec_pair_hcr_non_pcw(
    729     ia_bit_buf_struct *itt_bit_buff, WORD32 *spec_coef,
    730     const UWORD16 *code_book_tbl, WORD32 tbl_sign, const UWORD32 *idx_table,
    731     WORD32 huff_mode)
    732 
    733 {
    734   WORD16 index, length;
    735   WORD32 y, z;
    736   WORD32 read_word1;
    737   WORD32 read_word = ixheaacd_aac_showbits_32(itt_bit_buff->byte_ptr);
    738 
    739   ixheaacd_huffman_decode(read_word, &index, &length, code_book_tbl, idx_table);
    740   read_word1 = read_word << length;
    741   if (tbl_sign) {
    742     WORD32 temp_word;
    743     temp_word = read_word1;
    744     y = index / huff_mode;
    745     z = index - huff_mode * y;
    746 
    747     if (y) {
    748       if (temp_word & 0x80000000) y = -y;
    749 
    750       temp_word = temp_word << 1;
    751       length++;
    752     }
    753     *spec_coef++ = y;
    754 
    755     if (z) {
    756       if (temp_word & 0x80000000) {
    757         z = -z;
    758       }
    759       temp_word <<= 1;
    760       length++;
    761     }
    762     *spec_coef++ = z;
    763   } else {
    764     y = (index / huff_mode) - 4;
    765     z = index - ((y + 4) * huff_mode) - 4;
    766 
    767     *spec_coef++ = y;
    768     *spec_coef++ = z;
    769   }
    770 
    771   return length;
    772 }
    773 
    774 static PLATFORM_INLINE UWORD16 *ixheaacd_huff_dec_quad_hcr_pcw(
    775     ia_hcr_info_struct *ptr_hcr_info, ia_bit_buf_struct *it_bit_buff,
    776     WORD no_bands, const UWORD16 *code_book_tbl, WORD32 tbl_sign,
    777     const UWORD32 *idx_table, WORD32 *read_word, WORD32 *read_bits,
    778     UWORD16 *arr_seg_start_l, WORD8 *p_remaining_bits_in_seg,
    779     WORD32 *ptr_num_decoded_bits) {
    780   WORD16 index, length;
    781 
    782   UWORD8 *ptr_read_next = it_bit_buff->ptr_read_next;
    783   WORD32 spec_index = ptr_hcr_info->str_dec_io.quant_spec_coeff_idx;
    784   WORD32 *spec_coef =
    785       ptr_hcr_info->str_dec_io.ptr_quant_spec_coeff_base + spec_index;
    786   WORD32 *bit_pos = &it_bit_buff->bit_pos;
    787 
    788   do {
    789     UWORD32 read_word1;
    790 
    791     WORD32 read_bit_offset =
    792         *arr_seg_start_l - (it_bit_buff->size - *read_bits);
    793 
    794     if (read_bit_offset) {
    795       *read_bits -= read_bit_offset;
    796       *bit_pos += read_bit_offset;
    797       ixheaacd_aac_read_byte_corr(&ptr_read_next, bit_pos, read_word,
    798                                   it_bit_buff->ptr_bit_buf_end);
    799     }
    800 
    801     read_word1 = *read_word << *bit_pos;
    802     ixheaacd_huffman_decode(read_word1, &index, &length, code_book_tbl,
    803                             idx_table);
    804     *bit_pos += length;
    805     *p_remaining_bits_in_seg -= length;
    806     *read_bits -= length;
    807     *ptr_num_decoded_bits += length;
    808     *arr_seg_start_l += length;
    809     ixheaacd_aac_read_byte_corr(&ptr_read_next, bit_pos, read_word,
    810                                 it_bit_buff->ptr_bit_buf_end);
    811     if (tbl_sign) {
    812       WORD32 temp_word;
    813       WORD32 w, x, y, z;
    814       temp_word = *read_word << *bit_pos;
    815       w = index / 27;
    816       index = index - w * 27;
    817       x = index / 9;
    818       index = index - x * 9;
    819       y = index / 3;
    820       z = index - y * 3;
    821       if (w) {
    822         if (temp_word & 0x80000000) w = -w;
    823         temp_word <<= 1;
    824         *bit_pos += 1;
    825         *p_remaining_bits_in_seg -= 1;
    826         *read_bits -= 1;
    827         *ptr_num_decoded_bits += 1;
    828         *arr_seg_start_l += 1;
    829       }
    830       *spec_coef++ = w;
    831       spec_index++;
    832 
    833       if (x) {
    834         if (temp_word & 0x80000000) x = -x;
    835         temp_word <<= 1;
    836         *bit_pos += 1;
    837         *p_remaining_bits_in_seg -= 1;
    838         *read_bits -= 1;
    839         *ptr_num_decoded_bits += 1;
    840         *arr_seg_start_l += 1;
    841       }
    842       *spec_coef++ = x;
    843       spec_index++;
    844       if (y) {
    845         if (temp_word & 0x80000000) y = -y;
    846         temp_word <<= 1;
    847         *bit_pos += 1;
    848         *p_remaining_bits_in_seg -= 1;
    849         *read_bits -= 1;
    850         *ptr_num_decoded_bits += 1;
    851         *arr_seg_start_l += 1;
    852       }
    853       *spec_coef++ = y;
    854       spec_index++;
    855       if (z) {
    856         if (temp_word & 0x80000000) z = -z;
    857         temp_word <<= 1;
    858         *bit_pos += 1;
    859         *p_remaining_bits_in_seg -= 1;
    860         *read_bits -= 1;
    861         *ptr_num_decoded_bits += 1;
    862         *arr_seg_start_l += 1;
    863       }
    864       *spec_coef++ = z;
    865       spec_index++;
    866 
    867     }
    868 
    869     else {
    870       WORD32 w, x, y, z;
    871 
    872       w = index / 27 - 1;
    873       index = index - (w + 1) * 27;
    874       x = index / 9 - 1;
    875       index = index - (x + 1) * 9;
    876       y = index / 3 - 1;
    877       z = index - ((y + 1) * 3) - 1;
    878       *spec_coef++ = w;
    879 
    880       *spec_coef++ = x;
    881 
    882       *spec_coef++ = y;
    883 
    884       *spec_coef++ = z;
    885       spec_index += 4;
    886     }
    887 
    888     ixheaacd_aac_read_byte_corr(&ptr_read_next, bit_pos, read_word,
    889                                 it_bit_buff->ptr_bit_buf_end);
    890     arr_seg_start_l++;
    891     p_remaining_bits_in_seg++;
    892     no_bands--;
    893   } while (no_bands != 0);
    894 
    895   it_bit_buff->ptr_read_next = ptr_read_next;
    896   ptr_hcr_info->str_dec_io.quant_spec_coeff_idx = spec_index;
    897 
    898   return arr_seg_start_l;
    899 }
    900 
    901 static UWORD16 *ixheaacd_huff_dec_word_hcr_pcw(
    902     ia_hcr_info_struct *ptr_hcr_info, ia_bit_buf_struct *it_bit_buff,
    903     WORD no_bands, const UWORD16 *code_book_tbl, WORD32 *read_word,
    904     const UWORD32 *idx_table, UWORD16 *arr_seg_start_l, WORD32 *read_bits,
    905     WORD8 *p_remaining_bits_in_seg, WORD32 *ptr_num_decoded_bits) {
    906   WORD32 sp1, sp2;
    907   WORD32 flush_cw;
    908   WORD32 i, value, norm_val, off;
    909   WORD32 out1, out2;
    910   WORD16 index, length;
    911   UWORD8 *ptr_read_next = it_bit_buff->ptr_read_next;
    912   WORD32 spec_index = ptr_hcr_info->str_dec_io.quant_spec_coeff_idx;
    913   WORD32 *spec_coef =
    914       ptr_hcr_info->str_dec_io.ptr_quant_spec_coeff_base + spec_index;
    915   WORD32 *bit_pos = &it_bit_buff->bit_pos;
    916 
    917   do {
    918     UWORD32 read_word1;
    919 
    920     WORD32 read_bit_offset =
    921         *arr_seg_start_l - (it_bit_buff->size - *read_bits);
    922 
    923     if (read_bit_offset) {
    924       *read_bits -= read_bit_offset;
    925       *bit_pos += read_bit_offset;
    926       ixheaacd_aac_read_byte_corr1(&ptr_read_next, (WORD16 *)bit_pos,
    927                                    read_word);
    928     }
    929 
    930     read_word1 = *read_word << *bit_pos;
    931     ixheaacd_huff_sfb_table(read_word1, &index, &length, code_book_tbl,
    932                             idx_table);
    933     *bit_pos += length;
    934     *read_bits -= length;
    935     *arr_seg_start_l += length;
    936     *p_remaining_bits_in_seg -= length;
    937     *ptr_num_decoded_bits += length;
    938     ixheaacd_aac_read_byte_corr(&ptr_read_next, bit_pos, read_word,
    939                                 it_bit_buff->ptr_bit_buf_end);
    940 
    941     out1 = index / 17;
    942     out2 = index - out1 * 17;
    943     flush_cw = *read_word << *bit_pos;
    944 
    945     sp1 = out1;
    946     sp2 = out2;
    947 
    948     if (out1) {
    949       if (flush_cw & 0x80000000) {
    950         out1 = -out1;
    951       }
    952       *bit_pos += 1;
    953       *read_bits -= 1;
    954       *p_remaining_bits_in_seg -= 1;
    955       *ptr_num_decoded_bits += 1;
    956       *arr_seg_start_l += 1;
    957       flush_cw = (WORD32)flush_cw << 1;
    958     }
    959 
    960     if (out2) {
    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       if (flush_cw & 0x80000000) {
    967         out2 = -out2;
    968       }
    969     }
    970 
    971     ixheaacd_aac_read_byte_corr(&ptr_read_next, bit_pos, read_word,
    972                                 it_bit_buff->ptr_bit_buf_end);
    973 
    974     if (sp1 == 16) {
    975       i = 4;
    976       value = ixheaacd_extu(*read_word, *bit_pos, 23);
    977       value = value | 0xfffffe00;
    978       norm_val = ixheaacd_norm32(value);
    979 
    980       i += (norm_val - 22);
    981       *bit_pos += (norm_val - 21);
    982       *p_remaining_bits_in_seg -= (norm_val - 21);
    983       *ptr_num_decoded_bits += (norm_val - 21);
    984       *read_bits -= (norm_val - 21);
    985       *arr_seg_start_l += (norm_val - 21);
    986 
    987       ixheaacd_aac_read_byte_corr(&ptr_read_next, bit_pos, read_word,
    988                                   it_bit_buff->ptr_bit_buf_end);
    989 
    990       off = ixheaacd_extu(*read_word, *bit_pos, 32 - i);
    991 
    992       *bit_pos += i;
    993       *p_remaining_bits_in_seg -= i;
    994       *ptr_num_decoded_bits += i;
    995       *read_bits -= i;
    996       *arr_seg_start_l += i;
    997 
    998       ixheaacd_aac_read_byte_corr(&ptr_read_next, bit_pos, read_word,
    999                                   it_bit_buff->ptr_bit_buf_end);
   1000       ixheaacd_aac_read_byte_corr(&ptr_read_next, bit_pos, read_word,
   1001                                   it_bit_buff->ptr_bit_buf_end);
   1002 
   1003       i = off + ((WORD32)1 << i);
   1004 
   1005       if (out1 < 0)
   1006         *spec_coef++ = -i;
   1007       else
   1008         *spec_coef++ = i;
   1009       spec_index++;
   1010     } else {
   1011       *spec_coef++ = out1;
   1012       spec_index++;
   1013     }
   1014 
   1015     if (sp2 == 16) {
   1016       i = 4;
   1017       value = ixheaacd_extu(*read_word, *bit_pos, 23);
   1018       value = value | 0xfffffe00;
   1019       norm_val = ixheaacd_norm32(value);
   1020 
   1021       i += (norm_val - 22);
   1022 
   1023       *bit_pos += (norm_val - 21);
   1024       *read_bits -= (norm_val - 21);
   1025       *p_remaining_bits_in_seg -= (norm_val - 21);
   1026       *ptr_num_decoded_bits += (norm_val - 21);
   1027       *arr_seg_start_l += (norm_val - 21);
   1028       ixheaacd_aac_read_byte_corr(&ptr_read_next, bit_pos, read_word,
   1029                                   it_bit_buff->ptr_bit_buf_end);
   1030 
   1031       off = ixheaacd_extu(*read_word, *bit_pos, 32 - i);
   1032 
   1033       *bit_pos += i;
   1034       *p_remaining_bits_in_seg -= i;
   1035       *ptr_num_decoded_bits += i;
   1036       *read_bits -= i;
   1037       *arr_seg_start_l += i;
   1038 
   1039       ixheaacd_aac_read_byte_corr(&ptr_read_next, bit_pos, read_word,
   1040                                   it_bit_buff->ptr_bit_buf_end);
   1041       ixheaacd_aac_read_byte_corr(&ptr_read_next, bit_pos, read_word,
   1042                                   it_bit_buff->ptr_bit_buf_end);
   1043 
   1044       i = off + ((WORD32)1 << i);
   1045 
   1046       if (out2 < 0)
   1047         *spec_coef++ = -i;
   1048       else
   1049         *spec_coef++ = i;
   1050       spec_index++;
   1051     } else {
   1052       *spec_coef++ = out2;
   1053       spec_index++;
   1054     }
   1055 
   1056     arr_seg_start_l++;
   1057     p_remaining_bits_in_seg++;
   1058 
   1059     no_bands--;
   1060   } while (no_bands != 0);
   1061 
   1062   it_bit_buff->ptr_read_next = ptr_read_next;
   1063   ptr_hcr_info->str_dec_io.quant_spec_coeff_idx = spec_index;
   1064 
   1065   return arr_seg_start_l;
   1066 }
   1067 
   1068 static VOID ixheaacd_decode_pcw(ia_bit_buf_struct *itt_bit_buff,
   1069                                 ia_hcr_info_struct *ptr_hcr_info,
   1070                                 ia_aac_dec_tables_struct *ptr_aac_tables) {
   1071   UWORD16 ext_sort_sec;
   1072   UWORD16 cur_ext_sort_cw_sec;
   1073   UWORD8 codebook;
   1074   UWORD8 dimension;
   1075 
   1076   WORD32 num_ext_sorted_cw_in_sect_idx =
   1077       ptr_hcr_info->sect_info.num_ext_sorted_cw_in_sect_idx;
   1078   UWORD8 *ptr_ext_sorted_cw = ptr_hcr_info->sect_info.ptr_ext_sorted_cw;
   1079   WORD32 ext_sorted_cw_idx = ptr_hcr_info->sect_info.ext_sorted_cw_idx;
   1080   UWORD16 *ptr_num_ext_sorted_sect_in_sets =
   1081       ptr_hcr_info->sect_info.ptr_num_ext_sorted_sect_in_sets;
   1082   WORD32 num_ext_sorted_sect_in_sets_idx =
   1083       ptr_hcr_info->sect_info.num_ext_sorted_sect_in_sets_idx;
   1084   WORD32 *ptr_quant_spec_coeff =
   1085       ptr_hcr_info->str_dec_io.ptr_quant_spec_coeff_base;
   1086   UWORD16 *arr_seg_start_l = ptr_hcr_info->str_segment_info.arr_seg_start_l;
   1087   WORD8 *p_remaining_bits_in_seg =
   1088       ptr_hcr_info->str_segment_info.p_remaining_bits_in_seg;
   1089   UWORD8 *ptr_ext_sorted_sect_max_cb_len =
   1090       ptr_hcr_info->sect_info.ptr_ext_sorted_sect_max_cb_len;
   1091   WORD32 ext_sorted_sect_max_cb_len_idx =
   1092       ptr_hcr_info->sect_info.ext_sorted_sect_max_cb_len_idx;
   1093   UWORD8 max_allowed_cw_len;
   1094   WORD32 num_decoded_bits;
   1095   const UWORD8 *ptr_cb_dimension_tbl =
   1096       ptr_hcr_info->table_info.ptr_cb_dimension_tbl;
   1097   const UWORD16 *cb_table;
   1098   const UWORD32 *idx_table;
   1099 
   1100   WORD32 read_word = ixheaacd_aac_showbits_32(itt_bit_buff->ptr_read_next);
   1101   WORD32 read_bits = itt_bit_buff->cnt_bits;
   1102 
   1103   itt_bit_buff->ptr_read_next += 4;
   1104 
   1105   for (ext_sort_sec =
   1106            ptr_num_ext_sorted_sect_in_sets[num_ext_sorted_sect_in_sets_idx];
   1107        ext_sort_sec != 0; ext_sort_sec--) {
   1108     codebook = ptr_ext_sorted_cw[ext_sorted_cw_idx];
   1109     cb_table = (UWORD16 *)(ptr_aac_tables->code_book[codebook]);
   1110     idx_table = (UWORD32 *)(ptr_aac_tables->index_table[codebook]);
   1111     ext_sorted_cw_idx++;
   1112     if (ext_sorted_cw_idx >= (MAX_SFB_HCR + MAX_HCR_SETS)) {
   1113       return;
   1114     }
   1115     dimension = ptr_cb_dimension_tbl[codebook];
   1116     max_allowed_cw_len =
   1117         ptr_ext_sorted_sect_max_cb_len[ext_sorted_sect_max_cb_len_idx];
   1118     ext_sorted_sect_max_cb_len_idx++;
   1119     if (ext_sorted_sect_max_cb_len_idx >= (MAX_SFB_HCR + MAX_HCR_SETS)) {
   1120       return;
   1121     }
   1122 
   1123     if (codebook <= 4) {
   1124       WORD32 tbl_sign = 0;
   1125 
   1126       if (codebook > 2) {
   1127         tbl_sign = 1;
   1128       }
   1129 
   1130       {
   1131         num_decoded_bits = 0;
   1132         cur_ext_sort_cw_sec =
   1133             ptr_hcr_info->sect_info
   1134                 .ptr_num_ext_sorted_cw_in_sect[num_ext_sorted_cw_in_sect_idx];
   1135 
   1136         arr_seg_start_l = ixheaacd_huff_dec_quad_hcr_pcw(
   1137             ptr_hcr_info, itt_bit_buff, cur_ext_sort_cw_sec, cb_table, tbl_sign,
   1138             idx_table, &read_word, &read_bits, arr_seg_start_l,
   1139             p_remaining_bits_in_seg, &num_decoded_bits);
   1140 
   1141         p_remaining_bits_in_seg += cur_ext_sort_cw_sec;
   1142 
   1143         if (cur_ext_sort_cw_sec * max_allowed_cw_len < num_decoded_bits) {
   1144           ptr_hcr_info->str_dec_io.err_log |= (ERROR_POS << 19);
   1145         }
   1146 
   1147         if (1 ==
   1148             ixheaacd_err_detect_pcw_segment(
   1149                 *p_remaining_bits_in_seg, ptr_hcr_info, PCW,
   1150                 ptr_quant_spec_coeff +
   1151                     ptr_hcr_info->str_dec_io.quant_spec_coeff_idx - dimension,
   1152                 dimension)) {
   1153           return;
   1154         }
   1155       }
   1156     } else if (codebook < 11) {
   1157       {
   1158         WORD32 tbl_sign = 0;
   1159         WORD32 huff_mode = 9;
   1160         num_decoded_bits = 0;
   1161 
   1162         if (codebook > 6) {
   1163           if (codebook > 8)
   1164             huff_mode = 13;
   1165           else
   1166             huff_mode = 8;
   1167           tbl_sign = 1;
   1168         }
   1169 
   1170         cur_ext_sort_cw_sec =
   1171             ptr_hcr_info->sect_info
   1172                 .ptr_num_ext_sorted_cw_in_sect[num_ext_sorted_cw_in_sect_idx];
   1173 
   1174         arr_seg_start_l = ixheaacd_huff_dec_pair_hcr_pcw(
   1175             ptr_hcr_info, itt_bit_buff, cur_ext_sort_cw_sec, cb_table,
   1176             &read_word, tbl_sign, idx_table, arr_seg_start_l, &read_bits,
   1177             huff_mode, p_remaining_bits_in_seg, &num_decoded_bits);
   1178 
   1179         p_remaining_bits_in_seg += cur_ext_sort_cw_sec;
   1180 
   1181         if (cur_ext_sort_cw_sec * max_allowed_cw_len < num_decoded_bits) {
   1182           ptr_hcr_info->str_dec_io.err_log |= (ERROR_POS << 18);
   1183         }
   1184 
   1185         if (1 ==
   1186             ixheaacd_err_detect_pcw_segment(
   1187                 *p_remaining_bits_in_seg, ptr_hcr_info, PCW_SIGN,
   1188                 ptr_quant_spec_coeff +
   1189                     ptr_hcr_info->str_dec_io.quant_spec_coeff_idx - dimension,
   1190                 dimension)) {
   1191           return;
   1192         }
   1193       }
   1194     } else if ((codebook >= 11)) {
   1195       const UWORD32 *idx_table =
   1196           ptr_aac_tables->pstr_huffmann_tables->idx_table_hf11;
   1197       const UWORD16 *cb_table =
   1198           ptr_aac_tables->pstr_huffmann_tables->input_table_cb11;
   1199       num_decoded_bits = 0;
   1200 
   1201       cur_ext_sort_cw_sec =
   1202           ptr_hcr_info->sect_info
   1203               .ptr_num_ext_sorted_cw_in_sect[num_ext_sorted_cw_in_sect_idx];
   1204 
   1205       arr_seg_start_l = ixheaacd_huff_dec_word_hcr_pcw(
   1206           ptr_hcr_info, itt_bit_buff, cur_ext_sort_cw_sec, cb_table, &read_word,
   1207           idx_table, arr_seg_start_l, &read_bits, p_remaining_bits_in_seg,
   1208           &num_decoded_bits);
   1209 
   1210       p_remaining_bits_in_seg += cur_ext_sort_cw_sec;
   1211 
   1212       if (cur_ext_sort_cw_sec * max_allowed_cw_len < num_decoded_bits) {
   1213         ptr_hcr_info->str_dec_io.err_log |= (ERROR_POS << 17);
   1214       }
   1215 
   1216       if (1 == ixheaacd_err_detect_pcw_segment(
   1217                    *p_remaining_bits_in_seg, ptr_hcr_info, PCW_ESC_SIGN,
   1218                    ptr_quant_spec_coeff +
   1219                        ptr_hcr_info->str_dec_io.quant_spec_coeff_idx - 2,
   1220                    2)) {
   1221         return;
   1222       }
   1223     }
   1224 
   1225     num_ext_sorted_cw_in_sect_idx++;
   1226     if (num_ext_sorted_cw_in_sect_idx >= MAX_SFB_HCR + MAX_HCR_SETS) {
   1227       return;
   1228     }
   1229   }
   1230 
   1231   num_ext_sorted_sect_in_sets_idx++;
   1232   if (num_ext_sorted_sect_in_sets_idx >= MAX_HCR_SETS) {
   1233     return;
   1234   }
   1235 
   1236   itt_bit_buff->cnt_bits = read_bits;
   1237 
   1238   ptr_hcr_info->sect_info.num_ext_sorted_cw_in_sect_idx =
   1239       num_ext_sorted_cw_in_sect_idx;
   1240   ptr_hcr_info->sect_info.ext_sorted_cw_idx = ext_sorted_cw_idx;
   1241   ptr_hcr_info->sect_info.num_ext_sorted_sect_in_sets_idx =
   1242       num_ext_sorted_sect_in_sets_idx;
   1243   ptr_hcr_info->sect_info.ext_sorted_sect_max_cb_len_idx =
   1244       ext_sorted_sect_max_cb_len_idx;
   1245 }
   1246 
   1247 static UWORD32 ixheaacd_init_segment_bit_field(WORD32 num_segment,
   1248                                                WORD8 *p_remaining_bits_in_seg) {
   1249   WORD16 i;
   1250   WORD16 num_valid_segment = 0;
   1251 
   1252   for (i = 0; i < num_segment; i++) {
   1253     if (p_remaining_bits_in_seg[i] != 0) {
   1254       num_valid_segment += 1;
   1255     }
   1256   }
   1257 
   1258   return num_valid_segment;
   1259 }
   1260 
   1261 UWORD8 ixheaacd_toggle_read_dir(UWORD8 read_direction) {
   1262   if (read_direction == FROM_LEFT_TO_RIGHT) {
   1263     return FROM_RIGHT_TO_LEFT;
   1264   } else {
   1265     return FROM_LEFT_TO_RIGHT;
   1266   }
   1267 }
   1268 
   1269 static PLATFORM_INLINE UWORD16 ixheaacd_huff_dec_quad_hcr_non_pcw(
   1270     ia_bit_buf_struct *itt_bit_buff, WORD32 *spec_coef,
   1271     const UWORD16 *code_book_tbl, WORD32 tbl_sign, const UWORD32 *idx_table) {
   1272   WORD16 index, length;
   1273   WORD16 cw_len;
   1274   WORD32 read_word = ixheaacd_aac_showbits_32(itt_bit_buff->byte_ptr);
   1275   ixheaacd_huffman_decode(read_word, &index, &length, code_book_tbl, idx_table);
   1276   cw_len = length;
   1277   if (tbl_sign) {
   1278     WORD32 temp_word;
   1279     WORD32 w, x, y, z;
   1280     temp_word = read_word << length;
   1281     w = index / 27;
   1282     index = index - w * 27;
   1283     x = index / 9;
   1284     index = index - x * 9;
   1285     y = index / 3;
   1286     z = index - y * 3;
   1287     if (w) {
   1288       if (temp_word & 0x80000000) w = -w;
   1289       temp_word <<= 1;
   1290       cw_len++;
   1291     }
   1292     *spec_coef++ = w;
   1293 
   1294     if (x) {
   1295       if (temp_word & 0x80000000) x = -x;
   1296       temp_word <<= 1;
   1297       cw_len++;
   1298     }
   1299     *spec_coef++ = x;
   1300     if (y) {
   1301       if (temp_word & 0x80000000) y = -y;
   1302       temp_word <<= 1;
   1303       cw_len++;
   1304     }
   1305     *spec_coef++ = y;
   1306     if (z) {
   1307       if (temp_word & 0x80000000) z = -z;
   1308       temp_word <<= 1;
   1309       cw_len++;
   1310     }
   1311     *spec_coef++ = z;
   1312 
   1313   }
   1314 
   1315   else {
   1316     WORD32 w, x, y, z;
   1317 
   1318     w = index / 27 - 1;
   1319     index = index - (w + 1) * 27;
   1320     x = index / 9 - 1;
   1321     index = index - (x + 1) * 9;
   1322     y = index / 3 - 1;
   1323     z = index - ((y + 1) * 3) - 1;
   1324     *spec_coef++ = w;
   1325     *spec_coef++ = x;
   1326     *spec_coef++ = y;
   1327     *spec_coef++ = z;
   1328   }
   1329 
   1330   return cw_len;
   1331 }
   1332 
   1333 static PLATFORM_INLINE UWORD16 ixheaacd_huff_dec_word_hcr_non_pcw(
   1334     ia_bit_buf_struct *itt_bit_buff, WORD32 *spec_coef,
   1335     const UWORD16 *code_book_tbl, const UWORD32 *idx_table) {
   1336   WORD32 sp1, sp2;
   1337   WORD32 flush_cw;
   1338   WORD32 i, value, norm_val, off;
   1339   WORD32 out1, out2;
   1340   UWORD16 cw_len;
   1341 
   1342   WORD16 index, length;
   1343 
   1344   WORD32 read_word = ixheaacd_aac_showbits_32(itt_bit_buff->byte_ptr);
   1345   UWORD8 *ptr_read_next = itt_bit_buff->byte_ptr;
   1346   ptr_read_next += 4;
   1347 
   1348   ixheaacd_huff_sfb_table(read_word, &index, &length, code_book_tbl, idx_table);
   1349   cw_len = length;
   1350 
   1351   ixheaacd_aac_read_byte_corr1(&ptr_read_next, &length, &read_word);
   1352 
   1353   out1 = index / 17;
   1354   out2 = index - out1 * 17;
   1355   flush_cw = read_word << length;
   1356 
   1357   sp1 = out1;
   1358   sp2 = out2;
   1359 
   1360   if (out1) {
   1361     if (flush_cw & 0x80000000) {
   1362       out1 = -out1;
   1363     }
   1364     flush_cw = (WORD32)flush_cw << 1;
   1365     length++;
   1366     cw_len++;
   1367   }
   1368 
   1369   if (out2) {
   1370     if (flush_cw & 0x80000000) {
   1371       out2 = -out2;
   1372     }
   1373     length++;
   1374     cw_len++;
   1375   }
   1376 
   1377   ixheaacd_aac_read_byte_corr1(&ptr_read_next, &length, &read_word);
   1378 
   1379   if (sp1 == 16) {
   1380     i = 4;
   1381     value = ixheaacd_extu(read_word, length, 23);
   1382     value = value | 0xfffffe00;
   1383     norm_val = ixheaacd_norm32(value);
   1384 
   1385     i += (norm_val - 22);
   1386     length += (norm_val - 21);
   1387     cw_len += (norm_val - 21);
   1388 
   1389     ixheaacd_aac_read_byte_corr1(&ptr_read_next, &length, &read_word);
   1390 
   1391     off = ixheaacd_extu(read_word, length, 32 - i);
   1392     length += i;
   1393     cw_len += i;
   1394 
   1395     ixheaacd_aac_read_byte_corr1(&ptr_read_next, &length, &read_word);
   1396 
   1397     i = off + ((WORD32)1 << i);
   1398 
   1399     if (out1 < 0)
   1400       *spec_coef++ = -i;
   1401     else
   1402       *spec_coef++ = i;
   1403   } else {
   1404     *spec_coef++ = out1;
   1405   }
   1406 
   1407   if (sp2 == 16) {
   1408     i = 4;
   1409     value = ixheaacd_extu(read_word, length, 23);
   1410     value = value | 0xfffffe00;
   1411     norm_val = ixheaacd_norm32(value);
   1412 
   1413     i += (norm_val - 22);
   1414     length += (norm_val - 21);
   1415     cw_len += (norm_val - 21);
   1416 
   1417     ixheaacd_aac_read_byte_corr1(&ptr_read_next, &length, &read_word);
   1418 
   1419     off = ixheaacd_extu(read_word, length, 32 - i);
   1420     length += i;
   1421     cw_len += i;
   1422 
   1423     ixheaacd_aac_read_byte_corr1(&ptr_read_next, &length, &read_word);
   1424     i = off + ((WORD32)1 << i);
   1425 
   1426     if (out2 < 0)
   1427       *spec_coef++ = -i;
   1428     else
   1429       *spec_coef++ = i;
   1430   } else {
   1431     *spec_coef++ = out2;
   1432   }
   1433 
   1434   return cw_len;
   1435 }
   1436 
   1437 static VOID ixheaacd_decode_hcr_non_pcw(
   1438     ia_bit_buf_struct *itt_bit_buff, ia_hcr_info_struct *ptr_hcr_info,
   1439     ia_aac_dec_tables_struct *ptr_aac_tables, WORD32 *cw_offset, WORD32 trial,
   1440     WORD32 start) {
   1441   UWORD16 *cb_table;
   1442   UWORD32 *idx_table;
   1443   WORD16 codeword_len = 0;
   1444   WORD8 seg_bits_left;
   1445   UWORD8 tot_bits_to_save, code_bits_to_save, extra_code_bits;
   1446   WORD32 segment_offset = 0;
   1447   WORD8 *p_remaining_bits_in_seg =
   1448       ptr_hcr_info->str_segment_info.p_remaining_bits_in_seg;
   1449   WORD32 num_segment = ptr_hcr_info->str_segment_info.num_segment;
   1450 
   1451   for (segment_offset = start; segment_offset < trial;
   1452        segment_offset++, *cw_offset += 1) {
   1453     if (p_remaining_bits_in_seg[segment_offset] &&
   1454         !ptr_hcr_info->str_segment_info.is_decoded[*cw_offset]) {
   1455       cb_table =
   1456           (UWORD16 *)(ptr_aac_tables
   1457                           ->code_book[ptr_hcr_info->str_non_pcw_side_info
   1458                                           .ptr_cb[*cw_offset % num_segment]]);
   1459       idx_table =
   1460           (UWORD32 *)(ptr_aac_tables
   1461                           ->index_table[ptr_hcr_info->str_non_pcw_side_info
   1462                                             .ptr_cb[*cw_offset % num_segment]]);
   1463       {
   1464         UWORD32 i_qsc;
   1465         WORD8 current_seg_bits = p_remaining_bits_in_seg[segment_offset];
   1466 
   1467         itt_bit_buff->byte_ptr = itt_bit_buff->ptr_start;
   1468         itt_bit_buff->valid_bits = 0;
   1469         itt_bit_buff->byte = 0;
   1470         itt_bit_buff->bit_count = 0;
   1471         itt_bit_buff->write_bit_count = 0;
   1472 
   1473         if (ptr_hcr_info->str_segment_info.p_num_bits[*cw_offset]) {
   1474           extra_code_bits = max(
   1475               ptr_hcr_info->str_segment_info.p_num_bits[*cw_offset] - 32, 0);
   1476           code_bits_to_save =
   1477               min(ptr_hcr_info->str_segment_info.p_num_bits[*cw_offset], 32);
   1478 
   1479           ixheaacd_write_bit(
   1480               itt_bit_buff,
   1481               ptr_hcr_info->str_segment_info.code_extra[*cw_offset],
   1482               extra_code_bits);
   1483           ixheaacd_write_bit(itt_bit_buff,
   1484                              ptr_hcr_info->str_segment_info.code[*cw_offset],
   1485                              code_bits_to_save);
   1486         }
   1487         {
   1488           UWORD32 bit;
   1489           WORD32 read_bit_offset;
   1490 
   1491           if (ptr_hcr_info->str_segment_info.read_direction ==
   1492               FROM_LEFT_TO_RIGHT) {
   1493             read_bit_offset =
   1494                 ptr_hcr_info->str_segment_info.arr_seg_start_l[segment_offset] -
   1495                 (itt_bit_buff->size - itt_bit_buff->cnt_bits);
   1496             if (read_bit_offset) {
   1497               itt_bit_buff->cnt_bits += -read_bit_offset;
   1498             }
   1499             itt_bit_buff->ptr_read_next =
   1500                 itt_bit_buff->ptr_bit_buf_base +
   1501                 ((itt_bit_buff->size - itt_bit_buff->cnt_bits) >> 3);
   1502             itt_bit_buff->bit_pos =
   1503                 ((itt_bit_buff->size - itt_bit_buff->cnt_bits) & 7);
   1504 
   1505             for (; p_remaining_bits_in_seg[segment_offset] > 0;
   1506                  p_remaining_bits_in_seg[segment_offset] -= 1) {
   1507               bit = ixheaacd_aac_read_bit_rev(itt_bit_buff);
   1508               ptr_hcr_info->str_segment_info.arr_seg_start_l[segment_offset] +=
   1509                   1;
   1510 
   1511               ixheaacd_write_bit(itt_bit_buff, bit, 1);
   1512             }
   1513 
   1514           } else {
   1515             read_bit_offset =
   1516                 ptr_hcr_info->str_segment_info.arr_seg_start_r[segment_offset] -
   1517                 (itt_bit_buff->size - itt_bit_buff->cnt_bits);
   1518             if (read_bit_offset) {
   1519               itt_bit_buff->cnt_bits += -read_bit_offset;
   1520             }
   1521             itt_bit_buff->ptr_read_next =
   1522                 itt_bit_buff->ptr_bit_buf_base +
   1523                 ((itt_bit_buff->size - itt_bit_buff->cnt_bits) >> 3);
   1524             itt_bit_buff->bit_pos =
   1525                 ((itt_bit_buff->size - itt_bit_buff->cnt_bits) & 7);
   1526 
   1527             for (; p_remaining_bits_in_seg[segment_offset] > 0;
   1528                  p_remaining_bits_in_seg[segment_offset] -= 1) {
   1529               bit = ixheaacd_aac_read_bit(itt_bit_buff);
   1530               ptr_hcr_info->str_segment_info.arr_seg_start_r[segment_offset] -=
   1531                   1;
   1532               ixheaacd_write_bit(itt_bit_buff, bit, 1);
   1533             }
   1534           }
   1535         }
   1536 
   1537         ixheaacd_write_bit(itt_bit_buff, 0, 32 - itt_bit_buff->bit_count % 32);
   1538         itt_bit_buff->valid_bits = 8;
   1539         itt_bit_buff->byte_ptr = itt_bit_buff->ptr_start;
   1540         itt_bit_buff->byte = *itt_bit_buff->ptr_start;
   1541 
   1542         if (current_seg_bits) {
   1543           i_qsc = ptr_hcr_info->str_non_pcw_side_info
   1544                       .res_ptr_idx[*cw_offset % num_segment];
   1545 
   1546           if (ptr_hcr_info->str_non_pcw_side_info
   1547                   .ptr_cb[*cw_offset % num_segment] <= 4) {
   1548             WORD32 tbl_sign = 0;
   1549 
   1550             if (ptr_hcr_info->str_non_pcw_side_info
   1551                     .ptr_cb[*cw_offset % num_segment] > 2) {
   1552               tbl_sign = 1;
   1553             }
   1554 
   1555             codeword_len = ixheaacd_huff_dec_quad_hcr_non_pcw(
   1556                 itt_bit_buff,
   1557                 &ptr_hcr_info->str_non_pcw_side_info.ptr_result_base[i_qsc],
   1558                 cb_table, tbl_sign, idx_table);
   1559 
   1560             seg_bits_left =
   1561                 current_seg_bits - codeword_len +
   1562                 ptr_hcr_info->str_segment_info.p_num_bits[*cw_offset];
   1563 
   1564           }
   1565 
   1566           else if (ptr_hcr_info->str_non_pcw_side_info
   1567                        .ptr_cb[*cw_offset % num_segment] < 11) {
   1568             WORD32 tbl_sign = 0;
   1569             WORD32 huff_mode = 9;
   1570             if (ptr_hcr_info->str_non_pcw_side_info
   1571                     .ptr_cb[*cw_offset % num_segment] > 6) {
   1572               if (ptr_hcr_info->str_non_pcw_side_info
   1573                       .ptr_cb[*cw_offset % num_segment] > 8)
   1574                 huff_mode = 13;
   1575               else
   1576                 huff_mode = 8;
   1577               tbl_sign = 1;
   1578             }
   1579             codeword_len = ixheaacd_huff_dec_pair_hcr_non_pcw(
   1580                 itt_bit_buff,
   1581                 &ptr_hcr_info->str_non_pcw_side_info.ptr_result_base[i_qsc],
   1582                 cb_table, tbl_sign, idx_table, huff_mode);
   1583 
   1584             seg_bits_left =
   1585                 current_seg_bits - codeword_len +
   1586                 ptr_hcr_info->str_segment_info.p_num_bits[*cw_offset];
   1587           }
   1588           if (ptr_hcr_info->str_non_pcw_side_info
   1589                   .ptr_cb[*cw_offset % num_segment] >= 11) {
   1590             const UWORD32 *idx_table =
   1591                 ptr_aac_tables->pstr_huffmann_tables->idx_table_hf11;
   1592             const UWORD16 *cb_table =
   1593                 ptr_aac_tables->pstr_huffmann_tables->input_table_cb11;
   1594 
   1595             codeword_len = ixheaacd_huff_dec_word_hcr_non_pcw(
   1596                 itt_bit_buff,
   1597                 &ptr_hcr_info->str_non_pcw_side_info.ptr_result_base[i_qsc],
   1598                 cb_table, idx_table);
   1599 
   1600             seg_bits_left =
   1601                 current_seg_bits - codeword_len +
   1602                 ptr_hcr_info->str_segment_info.p_num_bits[*cw_offset];
   1603           }
   1604           if (seg_bits_left < 0) {
   1605             tot_bits_to_save =
   1606                 current_seg_bits +
   1607                 ptr_hcr_info->str_segment_info.p_num_bits[*cw_offset];
   1608             extra_code_bits = max(tot_bits_to_save - 32, 0);
   1609             code_bits_to_save = min(tot_bits_to_save, 32);
   1610 
   1611             ptr_hcr_info->str_segment_info.code_extra[*cw_offset] =
   1612                 ixheaacd_read_bit(itt_bit_buff, extra_code_bits);
   1613             ptr_hcr_info->str_segment_info.code[*cw_offset] =
   1614                 ixheaacd_read_bit(itt_bit_buff, code_bits_to_save);
   1615             ptr_hcr_info->str_segment_info.p_num_bits[*cw_offset] =
   1616                 tot_bits_to_save;
   1617 
   1618             p_remaining_bits_in_seg[segment_offset] = 0;
   1619             if (p_remaining_bits_in_seg[segment_offset] < 0)
   1620               p_remaining_bits_in_seg[segment_offset] = 0;
   1621           } else {
   1622             p_remaining_bits_in_seg[segment_offset] =
   1623                 current_seg_bits -
   1624                 (codeword_len -
   1625                  ptr_hcr_info->str_segment_info.p_num_bits[*cw_offset]);
   1626             ptr_hcr_info->str_segment_info.p_num_bits[*cw_offset] = 0;
   1627             ptr_hcr_info->str_segment_info.is_decoded[*cw_offset] = 1;
   1628             if (p_remaining_bits_in_seg[segment_offset] < 0)
   1629               p_remaining_bits_in_seg[segment_offset] = 0;
   1630           }
   1631 
   1632           if (p_remaining_bits_in_seg[segment_offset] > 0) {
   1633             if (ptr_hcr_info->str_segment_info.read_direction ==
   1634                 FROM_LEFT_TO_RIGHT)
   1635               ptr_hcr_info->str_segment_info.arr_seg_start_l[segment_offset] -=
   1636                   (p_remaining_bits_in_seg[segment_offset]);
   1637             else
   1638               ptr_hcr_info->str_segment_info.arr_seg_start_r[segment_offset] +=
   1639                   (p_remaining_bits_in_seg[segment_offset]);
   1640           }
   1641         }
   1642       }
   1643     }
   1644   }
   1645 }
   1646 
   1647 VOID ixheaacd_decode_non_pcw(ia_bit_buf_struct *itt_bit_buff,
   1648                              ia_hcr_info_struct *ptr_hcr_info,
   1649                              ia_aac_dec_tables_struct *ptr_aac_tables) {
   1650   UWORD32 num_valid_segment;
   1651   WORD32 cw_offset;
   1652   WORD32 trial;
   1653   WORD32 num_segment;
   1654   WORD32 num_code_word;
   1655   UWORD8 num_set;
   1656   UWORD8 current_set;
   1657   WORD32 code_word_set;
   1658   WORD32 loop1, loop2;
   1659 
   1660   num_segment = ptr_hcr_info->str_segment_info.num_segment;
   1661 
   1662   num_valid_segment = ixheaacd_init_segment_bit_field(
   1663       num_segment, ptr_hcr_info->str_segment_info.p_remaining_bits_in_seg);
   1664 
   1665   if (num_valid_segment != 0) {
   1666     num_code_word = ptr_hcr_info->sect_info.num_code_word;
   1667     num_set = ((num_code_word - 1) / num_segment) + 1;
   1668 
   1669     ptr_hcr_info->str_segment_info.read_direction = FROM_RIGHT_TO_LEFT;
   1670 
   1671     for (current_set = 1; current_set < num_set; current_set++) {
   1672       num_code_word -= num_segment;
   1673       if (num_code_word < num_segment) {
   1674         code_word_set = num_code_word;
   1675       } else {
   1676         code_word_set = num_segment;
   1677       }
   1678 
   1679       ixheaacd_nonpcw_sideinfo_init(ptr_hcr_info);
   1680 
   1681       cw_offset = num_segment * current_set;
   1682 
   1683       ixheaacd_decode_hcr_non_pcw(itt_bit_buff, ptr_hcr_info, ptr_aac_tables,
   1684                                   &cw_offset, code_word_set, 0);
   1685 
   1686       for (trial = 1; trial < num_segment; trial++) {
   1687         cw_offset = num_segment * current_set;
   1688 
   1689         loop1 = min(num_segment, trial + code_word_set);
   1690         loop2 = max(0, trial + code_word_set - num_segment);
   1691 
   1692         ixheaacd_decode_hcr_non_pcw(itt_bit_buff, ptr_hcr_info, ptr_aac_tables,
   1693                                     &cw_offset, loop1, trial);
   1694 
   1695         ixheaacd_decode_hcr_non_pcw(itt_bit_buff, ptr_hcr_info, ptr_aac_tables,
   1696                                     &cw_offset, loop2, 0);
   1697       }
   1698 
   1699       ptr_hcr_info->str_segment_info.read_direction = ixheaacd_toggle_read_dir(
   1700           ptr_hcr_info->str_segment_info.read_direction);
   1701     }
   1702   }
   1703 }
   1704 
   1705 static VOID ixheaacd_hcr_reorder_quantized_spec_coeff(
   1706     ia_hcr_info_struct *ptr_hcr_info,
   1707     ia_aac_dec_channel_info_struct *ptr_aac_dec_channel_info) {
   1708   WORD32 qsc;
   1709   UWORD32 abs_qsc;
   1710   UWORD32 i, j;
   1711   UWORD16 num_spec_val_sect;
   1712   WORD32 *ptr_teva;
   1713   UWORD16 lav_err_cnt = 0;
   1714 
   1715   UWORD32 num_sect = ptr_hcr_info->str_dec_io.num_sect;
   1716   WORD32 *ptr_quant_spec_coeff_base =
   1717       ptr_hcr_info->str_dec_io.ptr_quant_spec_coeff_base;
   1718   WORD32 *ptr_quant_spec_coeff =
   1719       ptr_hcr_info->str_dec_io.ptr_quant_spec_coeff_base;
   1720   const UWORD8 *ptr_cb_dim_shift_tbl =
   1721       ptr_hcr_info->table_info.ptr_cb_dim_shift_tbl;
   1722   const UWORD16 *ptr_lav_tbl = ptr_hcr_info->table_info.ptr_lav_tbl;
   1723   UWORD8 *ptr_sorted_cb = ptr_hcr_info->sect_info.ptr_sorted_cb;
   1724   UWORD16 *ptr_num_sorted_cw_in_sect =
   1725       ptr_hcr_info->sect_info.ptr_num_sorted_cw_in_sect;
   1726   UWORD16 *ptr_reorder_offset = ptr_hcr_info->sect_info.ptr_reorder_offset;
   1727   WORD32 *arr_temp_values = ptr_hcr_info->str_segment_info.arr_temp_values;
   1728   WORD32 *ptr_bak = ptr_hcr_info->str_segment_info.arr_temp_values;
   1729 
   1730   WORD32 cnt = 0;
   1731 
   1732   for (i = num_sect; i != 0; i--) {
   1733     num_spec_val_sect = *ptr_num_sorted_cw_in_sect++
   1734                         << ptr_cb_dim_shift_tbl[*ptr_sorted_cb];
   1735     ptr_teva = &arr_temp_values[*ptr_reorder_offset++];
   1736     for (j = num_spec_val_sect; j != 0; j--) {
   1737       cnt++;
   1738       qsc = *ptr_quant_spec_coeff++;
   1739       abs_qsc = ixheaacd_abs32(qsc);
   1740       if (abs_qsc <= ptr_lav_tbl[*ptr_sorted_cb]) {
   1741         *ptr_teva++ = (WORD32)qsc;
   1742       } else {
   1743         if (abs_qsc == 8192) {
   1744           *ptr_teva++ = (WORD32)qsc;
   1745         } else {
   1746           *ptr_teva++ = (WORD32)8192;
   1747           lav_err_cnt += 1;
   1748         }
   1749       }
   1750     }
   1751     ptr_sorted_cb++;
   1752   }
   1753 
   1754   if (ptr_aac_dec_channel_info->str_ics_info.window_sequence ==
   1755       EIGHT_SHORT_SEQUENCE) {
   1756     WORD32 *ptr_out;
   1757     WORD8 window;
   1758 
   1759     ptr_bak = ptr_hcr_info->str_segment_info.arr_temp_values;
   1760     for (window = 0; window < 8; window++) {
   1761       ptr_out = ptr_quant_spec_coeff_base +
   1762                 (window * ptr_aac_dec_channel_info->granule_len);
   1763       for (i = 0; i < (LINES_PER_UNIT_GROUP); i++) {
   1764         ptr_teva = ptr_bak + (window << 2) + i * 32;
   1765         for (j = (LINES_PER_UNIT); j != 0; j--) {
   1766           *ptr_out++ = *ptr_teva++;
   1767         }
   1768       }
   1769     }
   1770   } else {
   1771     ptr_quant_spec_coeff = ptr_quant_spec_coeff_base;
   1772     for (i = 1024; i != 0; i--) {
   1773       *ptr_quant_spec_coeff++ = *ptr_bak++;
   1774     }
   1775   }
   1776 
   1777   if (lav_err_cnt != 0) {
   1778     ptr_hcr_info->str_dec_io.err_log |= (ERROR_POS << 1);
   1779   }
   1780 }
   1781 
   1782 static VOID ixheaacd_err_detect_segmentation_final(
   1783     ia_hcr_info_struct *ptr_hcr_info) {
   1784   UWORD8 segmentation_err_flag = 0;
   1785   UWORD16 i;
   1786   WORD8 *p_remaining_bits_in_seg =
   1787       ptr_hcr_info->str_segment_info.p_remaining_bits_in_seg;
   1788   UWORD32 num_segment = ptr_hcr_info->str_segment_info.num_segment;
   1789 
   1790   for (i = num_segment; i != 0; i--) {
   1791     if (*p_remaining_bits_in_seg++ != 0) {
   1792       segmentation_err_flag = 1;
   1793     }
   1794   }
   1795   if (segmentation_err_flag == 1) {
   1796     ptr_hcr_info->str_dec_io.err_log |= ERROR_POS;
   1797   }
   1798 }
   1799 
   1800 UWORD32 ixheaacd_hcr_decoder(
   1801     ia_hcr_info_struct *ptr_hcr_info,
   1802     ia_aac_dec_channel_info_struct *ptr_aac_dec_channel_info,
   1803     ia_aac_dec_tables_struct *ptr_aac_tables, ia_bit_buf_struct *itt_bit_buff) {
   1804   WORD32 ptr_tmp1, ptr_tmp2, ptr_tmp3, ptr_tmp4;
   1805   WORD32 ptr_tmp5;
   1806 
   1807   WORD32 bit_cnt_offset;
   1808   UWORD32 save_bit_cnt = itt_bit_buff->cnt_bits;
   1809 
   1810   ixheaacd_huff_calc_num_cwd(ptr_hcr_info);
   1811 
   1812   ixheaacd_huff_sort_sect_cb_cwd(ptr_hcr_info);
   1813 
   1814   ixheaacd_hcr_prepare_segmentation_grid(ptr_hcr_info);
   1815 
   1816   ixheaacd_huff_ext_sect_info(ptr_hcr_info);
   1817 
   1818   if ((ptr_hcr_info->str_dec_io.err_log & HCR_FATAL_PCW_ERROR_MASK) != 0) {
   1819     return (ptr_hcr_info->str_dec_io.err_log);
   1820   }
   1821 
   1822   ixheaacd_calc_num_ext_sorted_sect_sets(
   1823       ptr_hcr_info->str_segment_info.num_segment,
   1824       ptr_hcr_info->sect_info.ptr_num_ext_sorted_cw_in_sect,
   1825       ptr_hcr_info->sect_info.num_ext_sorted_cw_in_sect_idx,
   1826       ptr_hcr_info->sect_info.ptr_num_ext_sorted_sect_in_sets,
   1827       ptr_hcr_info->sect_info.num_ext_sorted_sect_in_sets_idx);
   1828 
   1829   ptr_tmp1 = ptr_hcr_info->sect_info.num_ext_sorted_cw_in_sect_idx;
   1830   ptr_tmp2 = ptr_hcr_info->sect_info.ext_sorted_cw_idx;
   1831   ptr_tmp3 = ptr_hcr_info->sect_info.num_ext_sorted_sect_in_sets_idx;
   1832   ptr_tmp4 = ptr_hcr_info->str_dec_io.quant_spec_coeff_idx;
   1833   ptr_tmp5 = ptr_hcr_info->sect_info.ext_sorted_sect_max_cb_len_idx;
   1834 
   1835   ixheaacd_decode_pcw(itt_bit_buff, ptr_hcr_info, ptr_aac_tables);
   1836 
   1837   if ((ptr_hcr_info->str_dec_io.err_log & HCR_FATAL_PCW_ERROR_MASK) == 0) {
   1838     ixheaacd_decode_non_pcw(itt_bit_buff, ptr_hcr_info, ptr_aac_tables);
   1839   }
   1840 
   1841   ixheaacd_err_detect_segmentation_final(ptr_hcr_info);
   1842 
   1843   ptr_hcr_info->sect_info.num_ext_sorted_cw_in_sect_idx = ptr_tmp1;
   1844   ptr_hcr_info->sect_info.ext_sorted_cw_idx = ptr_tmp2;
   1845   ptr_hcr_info->sect_info.num_ext_sorted_sect_in_sets_idx = ptr_tmp3;
   1846   ptr_hcr_info->str_dec_io.quant_spec_coeff_idx = ptr_tmp4;
   1847   ptr_hcr_info->sect_info.ext_sorted_sect_max_cb_len_idx = ptr_tmp5;
   1848 
   1849   ixheaacd_hcr_reorder_quantized_spec_coeff(ptr_hcr_info,
   1850                                             ptr_aac_dec_channel_info);
   1851 
   1852   bit_cnt_offset = (WORD32)itt_bit_buff->cnt_bits - (WORD32)save_bit_cnt;
   1853   if (bit_cnt_offset) {
   1854     itt_bit_buff->cnt_bits += -bit_cnt_offset;
   1855     itt_bit_buff->ptr_read_next =
   1856         itt_bit_buff->ptr_bit_buf_base +
   1857         ((itt_bit_buff->size - itt_bit_buff->cnt_bits) >> 3);
   1858     itt_bit_buff->bit_pos = (itt_bit_buff->size - itt_bit_buff->cnt_bits) & 7;
   1859   }
   1860 
   1861   return (ptr_hcr_info->str_dec_io.err_log);
   1862 }
   1863