/****************************************************************************** * * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ #include "ixheaacd_type_def.h" #include "ixheaacd_constants.h" #include "ixheaacd_basic_ops32.h" #include "ixheaacd_basic_ops40.h" #include "ixheaacd_basic_ops.h" #include "ixheaacd_bitbuffer.h" #include "ixheaacd_basic_op.h" #include "ixheaacd_mps_aac_struct.h" #include "ixheaacd_mps_res_rom.h" #include "ixheaacd_mps_res_block.h" #include "ixheaacd_mps_res_huffman.h" static PLATFORM_INLINE WORD32 ixheaacd_res_extract_symbol(WORD32 value, WORD32 l_shift, WORD32 r_shift, WORD32 *pow_table_q17) { WORD32 out; out = (WORD16)((value << l_shift) >> r_shift); if (out < 0) { out = -out; out = pow_table_q17[out]; out = -out; } else out = pow_table_q17[out]; return out; } static PLATFORM_INLINE WORD32 ixheaacd_res_extract_signed_symbol(WORD32 value, WORD32 l_shift, WORD32 r_shift, WORD32 *pow_table_q17, WORD32 *temp_word, WORD32 *pr_bit_pos) { WORD32 out; out = ixheaacd_extu(value, l_shift, r_shift); if (out) { WORD32 bit_pos = *pr_bit_pos; out = pow_table_q17[out]; if (*temp_word & 0x80000000) { out = -out; } *temp_word = *temp_word << 1; bit_pos++; *pr_bit_pos = bit_pos; } return out; } VOID ixheaacd_res_inverse_quant_lb(WORD32 *x_invquant, WORD t_bands, WORD32 *pow_table_q17, WORD8 *pulse_data) { WORD32 j; WORD32 temp; WORD32 q_abs; for (j = t_bands - 1; j >= 0; j--) { q_abs = *pulse_data++; temp = (pow_table_q17[q_abs]); *x_invquant++ = -temp; } } static PLATFORM_INLINE WORD ixheaacd_res_c_block_decode_huff_word1( ia_bit_buf_struct *it_bit_buf, WORD32 *qp, WORD16 *offsets, WORD no_bands, WORD group_no, const UWORD16 *h_ori, WORD32 *pow_table_q17, WORD32 maximum_bins_short) { WORD32 sp1, sp2; WORD32 flush_cw; WORD32 i, value, norm_val, off; WORD idx, grp_idx; WORD32 out1, out2; WORD32 err_code = 0; WORD len_idx = 0; UWORD8 *ptr_read_next = it_bit_buf->ptr_read_next; WORD32 bit_pos = it_bit_buf->bit_pos; WORD32 read_word = ixheaacd_res_aac_showbits_32(ptr_read_next); ptr_read_next += 4; do { len_idx = offsets[1] - offsets[0]; grp_idx = group_no; do { qp = qp + offsets[0]; idx = len_idx; do { { UWORD16 first_offset; WORD16 sign_ret_val; UWORD32 read_word1; UWORD16 *h; read_word1 = read_word << bit_pos; h = (UWORD16 *)h_ori; h += (read_word1) >> (27); sign_ret_val = *h; first_offset = 5; while (sign_ret_val > 0) { bit_pos += first_offset; ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word, it_bit_buf->ptr_bit_buf_end); read_word1 = (read_word1) << (first_offset); first_offset = (sign_ret_val >> 11); h += sign_ret_val & (0x07FF); h += (read_word1) >> (32 - first_offset); sign_ret_val = *h; } bit_pos += ((sign_ret_val & 0x7fff) >> 11); value = sign_ret_val & (0x07FF); } out1 = (value & 0x3E0) >> 5; out2 = value & 0x1F; flush_cw = read_word << bit_pos; sp1 = out1; sp2 = out2; if (out1) { if (flush_cw & 0x80000000) { out1 = -out1; } bit_pos++; flush_cw = (WORD32)flush_cw << 1; } if (out2) { bit_pos++; if (flush_cw & 0x80000000) { out2 = -out2; } } ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word, it_bit_buf->ptr_bit_buf_end); if (sp1 == 16) { i = 4; value = ixheaacd_extu(read_word, bit_pos, 23); value = value | 0xfffffe00; norm_val = ixheaacd_norm32(value); i += (norm_val - 22); bit_pos += (norm_val - 21); ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word, it_bit_buf->ptr_bit_buf_end); off = ixheaacd_extu(read_word, bit_pos, 32 - i); bit_pos += i; ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word, it_bit_buf->ptr_bit_buf_end); ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word, it_bit_buf->ptr_bit_buf_end); i = off + ((WORD32)1 << i); if (i <= IQ_TABLE_SIZE_HALF) i = pow_table_q17[i]; else { err_code |= ixheaacd_res_inv_quant(&i, pow_table_q17); } if (out1 < 0) { out1 = -i; } else { out1 = i; } *qp++ = out1; } else { if (out1 <= 0) { out1 = -out1; out1 = pow_table_q17[out1]; *qp++ = -out1; } else { out1 = pow_table_q17[out1]; *qp++ = out1; } } if (sp2 == 16) { i = 4; value = ixheaacd_extu(read_word, bit_pos, 23); value = value | 0xfffffe00; norm_val = ixheaacd_norm32(value); i += (norm_val - 22); bit_pos += (norm_val - 21); ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word, it_bit_buf->ptr_bit_buf_end); off = ixheaacd_extu(read_word, bit_pos, 32 - i); bit_pos += i; ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word, it_bit_buf->ptr_bit_buf_end); ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word, it_bit_buf->ptr_bit_buf_end); i = off + ((WORD32)1 << i); if (i <= IQ_TABLE_SIZE_HALF) i = pow_table_q17[i]; else { err_code |= ixheaacd_res_inv_quant(&i, pow_table_q17); } if (out2 < 0) { out2 = -i; } else { out2 = i; } *qp++ = out2; } else { if (out2 <= 0) { out2 = -out2; out2 = pow_table_q17[out2]; *qp++ = -out2; } else { out2 = pow_table_q17[out2]; *qp++ = out2; } } idx -= 2; } while (idx != 0); qp += (maximum_bins_short - offsets[1]); grp_idx--; } while (grp_idx != 0); offsets++; qp -= (maximum_bins_short * group_no); no_bands--; } while (no_bands >= 0); it_bit_buf->bit_pos = bit_pos; it_bit_buf->ptr_read_next = ptr_read_next - 4; return err_code; } static PLATFORM_INLINE WORD ixheaacd_res_c_block_decode_huff_word1_lb( ia_bit_buf_struct *it_bif_buf, WORD32 len, const UWORD16 *h_ori, WORD32 *x_invquant, WORD32 *pow_table_q17, WORD8 *p_pul_arr) { WORD32 sp1, sp2; WORD32 flush_cw; WORD32 i, value, norm_val, off; WORD idx; WORD32 out1, out2; WORD32 err_code = 0; UWORD8 *ptr_read_next = it_bif_buf->ptr_read_next; WORD32 bit_pos = it_bif_buf->bit_pos; WORD32 read_word = ixheaacd_res_aac_showbits_32(ptr_read_next); ptr_read_next += 4; for (idx = len; idx != 0; idx -= 2) { { UWORD16 first_offset; WORD16 sign_ret_val; UWORD32 read_word1; UWORD16 *h; read_word1 = read_word << bit_pos; h = (UWORD16 *)h_ori; h += (read_word1) >> (27); sign_ret_val = *h; first_offset = 5; while (sign_ret_val > 0) { bit_pos += first_offset; ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word, it_bif_buf->ptr_bit_buf_end); read_word1 = (read_word1) << (first_offset); first_offset = (sign_ret_val >> 11); h += sign_ret_val & (0x07FF); h += (read_word1) >> (32 - first_offset); sign_ret_val = *h; } bit_pos += ((sign_ret_val & 0x7fff) >> 11); value = sign_ret_val & (0x07FF); } flush_cw = read_word << bit_pos; out1 = (value & 0x3E0) >> 5; out2 = value & 0x1F; sp1 = out1; if (out1) { if (flush_cw & 0x80000000) { out1 = -out1; } bit_pos++; flush_cw = (WORD32)flush_cw << 1; } sp2 = out2; if (out2) { bit_pos++; if (flush_cw & 0x80000000) { out2 = -out2; } } ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word, it_bif_buf->ptr_bit_buf_end); if (sp1 == 16) { i = 4; value = ixheaacd_extu(read_word, bit_pos, 23); value = value | 0xfffffe00; norm_val = ixheaacd_norm32(value); i += (norm_val - 22); bit_pos += (norm_val - 21); ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word, it_bif_buf->ptr_bit_buf_end); off = ixheaacd_extu(read_word, bit_pos, 32 - i); bit_pos += i; ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word, it_bif_buf->ptr_bit_buf_end); value = *p_pul_arr++; ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word, it_bif_buf->ptr_bit_buf_end); i = off + ((WORD32)1 << i); i = add_d(i, value); if (i <= IQ_TABLE_SIZE_HALF) i = pow_table_q17[i]; else { err_code |= ixheaacd_res_inv_quant(&i, pow_table_q17); } if (out1 < 0) { i = -i; } *x_invquant++ = i; } else { WORD8 temp = *p_pul_arr++; if (out1 <= 0) { out1 = sub_d(temp, out1); out1 = pow_table_q17[out1]; *x_invquant++ = -out1; } else { out1 = add_d(out1, temp); out1 = pow_table_q17[out1]; *x_invquant++ = out1; } } if (sp2 == 16) { i = 4; value = ixheaacd_extu(read_word, bit_pos, 23); value = value | 0xfffffe00; norm_val = ixheaacd_norm32(value); i += (norm_val - 22); bit_pos += (norm_val - 21); ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word, it_bif_buf->ptr_bit_buf_end); off = ixheaacd_extu(read_word, bit_pos, 32 - i); bit_pos += i; ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word, it_bif_buf->ptr_bit_buf_end); value = *p_pul_arr++; ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word, it_bif_buf->ptr_bit_buf_end); i = off + ((WORD32)1 << i); i = add_d(i, value); if (i <= IQ_TABLE_SIZE_HALF) i = pow_table_q17[i]; else { err_code |= ixheaacd_res_inv_quant(&i, pow_table_q17); } if (out2 < 0) { i = -i; } *x_invquant++ = i; } else { WORD8 temp = *p_pul_arr++; if (out2 <= 0) { out2 = sub_d(temp, out2); out2 = pow_table_q17[out2]; *x_invquant++ = -out2; } else { out2 = add_d(out2, temp); out2 = pow_table_q17[out2]; *x_invquant++ = out2; } } } it_bif_buf->ptr_read_next = ptr_read_next - 4; it_bif_buf->bit_pos = bit_pos; return err_code; } static PLATFORM_INLINE WORD ixheaacd_res_c_block_decode_huff_word2_4( ia_bit_buf_struct *it_bit_buf, WORD32 *qp, WORD16 *offsets, WORD no_bands, WORD group_no, const UWORD16 *h_ori, WORD32 *pow_table_q17, WORD32 sign, WORD32 maximum_bins_short) { WORD32 value; WORD idx, grp_idx; WORD idx_len; WORD32 *qp_org; UWORD8 *ptr_read_next = it_bit_buf->ptr_read_next; WORD32 bit_pos = it_bit_buf->bit_pos; WORD32 read_word = ixheaacd_res_aac_showbits_32(ptr_read_next); ptr_read_next += 4; qp_org = qp; do { idx_len = offsets[1] - offsets[0]; grp_idx = group_no; do { qp = qp + offsets[0]; idx = idx_len; do { UWORD16 first_offset; WORD16 sign_ret_val; UWORD32 read_word1; UWORD16 *h; read_word1 = read_word << bit_pos; h = (UWORD16 *)h_ori; h += (read_word1) >> (27); sign_ret_val = *h; first_offset = 5; while (sign_ret_val > 0) { bit_pos += first_offset; ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word, it_bit_buf->ptr_bit_buf_end); read_word1 = (read_word1) << (first_offset); first_offset = (sign_ret_val >> 11); h += sign_ret_val & (0x07FF); h += (read_word1) >> (32 - first_offset); sign_ret_val = *h; } bit_pos += ((sign_ret_val & 0x7fff) >> 11); value = sign_ret_val & (0x07FF); if (sign) { WORD32 temp_word; temp_word = read_word << bit_pos; *qp++ = ixheaacd_res_extract_signed_symbol(value, 24, 30, pow_table_q17, &temp_word, &bit_pos); *qp++ = ixheaacd_res_extract_signed_symbol(value, 26, 30, pow_table_q17, &temp_word, &bit_pos); *qp++ = ixheaacd_res_extract_signed_symbol(value, 28, 30, pow_table_q17, &temp_word, &bit_pos); *qp++ = ixheaacd_res_extract_signed_symbol(value, 30, 30, pow_table_q17, &temp_word, &bit_pos); } else { *qp++ = ixheaacd_res_extract_symbol(value, 24, 30, pow_table_q17); *qp++ = ixheaacd_res_extract_symbol(value, 26, 30, pow_table_q17); *qp++ = ixheaacd_res_extract_symbol(value, 28, 30, pow_table_q17); *qp++ = ixheaacd_res_extract_symbol(value, 30, 30, pow_table_q17); } ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word, it_bit_buf->ptr_bit_buf_end); idx -= 4; } while (idx != 0); qp += (maximum_bins_short - offsets[1]); grp_idx--; } while (grp_idx != 0); offsets++; qp = qp_org; no_bands--; } while (no_bands >= 0); it_bit_buf->ptr_read_next = ptr_read_next - 4; it_bit_buf->bit_pos = bit_pos; return 0; } static PLATFORM_INLINE WORD ixheaacd_res_c_block_decode_huff_word2_4_lb( ia_bit_buf_struct *it_bit_buf, WORD32 len, const UWORD16 *h_ori, WORD32 *x_invquant, WORD32 *pow_table_q17, WORD8 *p_pul_arr, WORD32 sign) { WORD32 value; WORD idx; UWORD8 *ptr_read_next = it_bit_buf->ptr_read_next; WORD32 bit_pos = it_bit_buf->bit_pos; WORD32 read_word = ixheaacd_res_aac_showbits_32(ptr_read_next); ptr_read_next += 4; for (idx = len; idx != 0; idx -= 4) { WORD32 res; WORD32 ampres, ampres1; WORD32 ampres2, ampres3; UWORD16 first_offset; WORD16 sign_ret_val; UWORD32 read_word1; UWORD16 *h; read_word1 = read_word << bit_pos; h = (UWORD16 *)h_ori; h += (read_word1) >> (27); sign_ret_val = *h; first_offset = 5; while (sign_ret_val > 0) { bit_pos += first_offset; ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word, it_bit_buf->ptr_bit_buf_end); read_word1 = (read_word1) << (first_offset); first_offset = (sign_ret_val >> 11); h += sign_ret_val & (0x07FF); h += (read_word1) >> (32 - first_offset); sign_ret_val = *h; } bit_pos += ((sign_ret_val & 0x7fff) >> 11); value = sign_ret_val & (0x07FF); if (sign) { WORD32 out0, out1, out2, out3; WORD32 ampout0, ampout1, ampout2, ampout3; WORD32 temp_word; temp_word = read_word << bit_pos; out0 = (ixheaacd_extu(value, 24, 30)); ampout0 = add_d(out0, *p_pul_arr++); ampout0 = pow_table_q17[ampout0]; if (out0) { if (temp_word & 0x80000000) { ampout0 = -ampout0; } temp_word = temp_word << 1; bit_pos++; } else { ampout0 = -ampout0; } out1 = (ixheaacd_extu(value, 26, 30)); ampout1 = add_d(out1, *p_pul_arr++); ampout1 = pow_table_q17[ampout1]; if (out1) { if (temp_word & 0x80000000) { ampout1 = -(ampout1); } temp_word = temp_word << 1; bit_pos++; } else { ampout1 = -ampout1; } out2 = (ixheaacd_extu(value, 28, 30)); ampout2 = add_d(out2, *p_pul_arr++); ampout2 = pow_table_q17[ampout2]; if (out2) { if (temp_word & 0x80000000) { ampout2 = -(ampout2); } temp_word = temp_word << 1; bit_pos++; } else { ampout2 = -ampout2; } *x_invquant++ = ampout0; *x_invquant++ = ampout1; *x_invquant++ = ampout2; out3 = (ixheaacd_extu(value, 30, 30)); ampout3 = add_d(out3, *p_pul_arr++); ampout3 = pow_table_q17[ampout3]; if (out3) { if (temp_word & 0x80000000) { ampout3 = -(ampout3); } temp_word = temp_word << 1; bit_pos++; } else { ampout3 = -ampout3; } *x_invquant++ = ampout3; } else { ampres = *p_pul_arr++; res = (ixheaacd_res_exts(value, 24, 30)); if (res > 0) { ampres = add_d(res, ampres); ampres = pow_table_q17[ampres]; } else { ampres = sub_d(ampres, res); ampres = pow_table_q17[ampres]; ampres = -ampres; } res = (ixheaacd_res_exts(value, 26, 30)); ampres1 = *p_pul_arr++; if (res > 0) { ampres1 = add_d(res, ampres1); ampres1 = pow_table_q17[ampres1]; } else { ampres1 = sub_d(ampres1, res); ampres1 = pow_table_q17[ampres1]; ampres1 = -ampres1; } res = (ixheaacd_res_exts(value, 28, 30)); ampres2 = *p_pul_arr++; if (res > 0) { ampres2 = add_d(res, ampres2); ampres2 = pow_table_q17[ampres2]; } else { ampres2 = sub_d(ampres2, res); ampres2 = pow_table_q17[ampres2]; ampres2 = -ampres2; } res = (ixheaacd_res_exts(value, 30, 30)); ampres3 = *p_pul_arr++; if (res > 0) { ampres3 = add_d(res, ampres3); ampres3 = pow_table_q17[ampres3]; } else { ampres3 = sub_d(ampres3, res); ampres3 = pow_table_q17[ampres3]; ampres3 = -ampres3; } *x_invquant++ = ampres; *x_invquant++ = ampres1; *x_invquant++ = ampres2; *x_invquant++ = ampres3; } ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word, it_bit_buf->ptr_bit_buf_end); } it_bit_buf->ptr_read_next = ptr_read_next - 4; it_bit_buf->bit_pos = bit_pos; return 0; } static PLATFORM_INLINE WORD ixheaacd_res_c_block_decode_huff_word2_2( ia_bit_buf_struct *it_bif_buf, WORD32 *qp, WORD16 *offsets, WORD no_bands, WORD group_no, const UWORD16 *h_ori, WORD32 *pow_table_q17, WORD32 sign, WORD32 maximum_bins_short) { WORD32 value; WORD idx, grp_idx; WORD len_idx; WORD32 *qp_org = qp; UWORD8 *ptr_read_next = it_bif_buf->ptr_read_next; WORD32 bit_pos = it_bif_buf->bit_pos; WORD32 read_word = ixheaacd_res_aac_showbits_32(ptr_read_next); ptr_read_next += 4; do { len_idx = offsets[1] - offsets[0]; grp_idx = group_no; do { qp += offsets[0]; idx = len_idx; do { UWORD16 first_offset; WORD16 sign_ret_val; UWORD32 read_word1; UWORD16 *h; read_word1 = read_word << bit_pos; h = (UWORD16 *)h_ori; h += (read_word1) >> (27); sign_ret_val = *h; first_offset = 5; while (sign_ret_val > 0) { bit_pos += first_offset; ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word, it_bif_buf->ptr_bit_buf_end); read_word1 = (read_word1) << (first_offset); first_offset = (sign_ret_val >> 11); h += sign_ret_val & (0x07FF); h += (read_word1) >> (32 - first_offset); sign_ret_val = *h; } bit_pos += ((sign_ret_val & 0x7fff) >> 11); value = sign_ret_val & (0x07FF); if (sign) { WORD32 temp_word; temp_word = read_word << bit_pos; *qp++ = ixheaacd_res_extract_signed_symbol(value, 24, 28, pow_table_q17, &temp_word, &bit_pos); *qp++ = ixheaacd_res_extract_signed_symbol(value, 28, 28, pow_table_q17, &temp_word, &bit_pos); } else { *qp++ = ixheaacd_res_extract_symbol(value, 24, 28, pow_table_q17); *qp++ = ixheaacd_res_extract_symbol(value, 28, 28, pow_table_q17); } ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word, it_bif_buf->ptr_bit_buf_end); idx -= 2; } while (idx != 0); qp += (maximum_bins_short - offsets[1]); grp_idx--; } while (grp_idx != 0); offsets++; qp = qp_org; no_bands--; } while (no_bands >= 0); it_bif_buf->ptr_read_next = ptr_read_next - 4; it_bif_buf->bit_pos = bit_pos; return 0; } static PLATFORM_INLINE WORD ixheaacd_res_c_block_decode_huff_word2_2_lb( ia_bit_buf_struct *it_bit_buf, WORD32 len, const UWORD16 *h_ori, WORD32 *x_invquant, WORD32 *pow_table_q17, WORD8 *p_pul_arr, WORD32 sign) { WORD32 value, res, ampres; WORD idx; UWORD8 *ptr_read_next = it_bit_buf->ptr_read_next; WORD32 bit_pos = it_bit_buf->bit_pos; WORD32 read_word = ixheaacd_res_aac_showbits_32(ptr_read_next); ptr_read_next += 4; for (idx = len; idx != 0; idx -= 2) { { UWORD16 first_offset; WORD16 sign_ret_val; UWORD32 read_word1; UWORD16 *h; read_word1 = read_word << bit_pos; h = (UWORD16 *)h_ori; h += (read_word1) >> (27); sign_ret_val = *h; first_offset = 5; while (sign_ret_val > 0) { bit_pos += first_offset; ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word, it_bit_buf->ptr_bit_buf_end); read_word1 = (read_word1) << (first_offset); first_offset = (sign_ret_val >> 11); h += sign_ret_val & (0x07FF); h += (read_word1) >> (32 - first_offset); sign_ret_val = *h; } bit_pos += ((sign_ret_val & 0x7fff) >> 11); value = sign_ret_val & (0x07FF); } if (sign) { WORD32 out0, out1, temp_word; WORD32 ampout0, ampout1; ampout0 = *p_pul_arr++; ampout1 = *p_pul_arr++; out0 = value & 0xf0; ampout0 = add_d(ampout0, (UWORD32)out0 >> 4); ampout0 = pow_table_q17[ampout0]; out1 = value & 0xf; ampout1 = add_d(out1, ampout1); ampout1 = pow_table_q17[ampout1]; temp_word = read_word << bit_pos; if (out0) { if (temp_word & 0x80000000) { ampout0 = -(ampout0); } bit_pos++; temp_word = temp_word << 1; } else { ampout0 = -(ampout0); } if (out1) { if (temp_word & 0x80000000) { ampout1 = -(ampout1); } bit_pos++; } else { ampout1 = -(ampout1); } ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word, it_bit_buf->ptr_bit_buf_end); *x_invquant++ = ampout0; *x_invquant++ = ampout1; } else { res = ((value << 24) >> 28); ampres = *p_pul_arr++; if (res > 0) { ampres = add_d(res, ampres); *x_invquant++ = pow_table_q17[ampres]; } else { ampres = sub_d(ampres, res); ampres = pow_table_q17[ampres]; *x_invquant++ = -ampres; } res = ((value << 28) >> 28); value = *p_pul_arr++; if (res > 0) { ampres = add_d(res, value); *x_invquant++ = pow_table_q17[ampres]; } else { ampres = sub_d(value, res); ampres = pow_table_q17[ampres]; *x_invquant++ = -ampres; } } ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word, it_bit_buf->ptr_bit_buf_end); } it_bit_buf->ptr_read_next = ptr_read_next - 4; it_bit_buf->bit_pos = bit_pos; return 0; } WORD ixheaacd_res_c_block_decode_huff_word_all( ia_bit_buf_struct *it_bit_buf, WORD32 code_no, WORD32 *quantized_coef, WORD16 *band_offsets, WORD start, WORD band, WORD group_no, ia_mps_dec_residual_aac_tables_struct *aac_tables_ptr, WORD32 maximum_bins_short) { WORD ret_val = 0; WORD start_bit_pos = it_bit_buf->bit_pos; UWORD8 *start_read_pos = it_bit_buf->ptr_read_next; const UWORD16 *h_ori = (UWORD16 *)(aac_tables_ptr->code_book[code_no]); WORD32 *pow_table = (WORD32 *)aac_tables_ptr->res_block_tables_ptr->pow_table_q17; WORD32 no_bands = band - start - 1; WORD16 *p_band_off = band_offsets + start; if (code_no == 11) { const UWORD16 *h_ori = aac_tables_ptr->res_huffmann_tables_ptr->huffman_codebook_11; ret_val = ixheaacd_res_c_block_decode_huff_word1(it_bit_buf, quantized_coef, p_band_off, no_bands, group_no, h_ori, pow_table, maximum_bins_short); } else if (code_no <= 4) { WORD32 sign = 0; if (code_no > 2) sign = 1; ret_val = ixheaacd_res_c_block_decode_huff_word2_4(it_bit_buf, quantized_coef, p_band_off, no_bands, group_no, h_ori, pow_table, sign, maximum_bins_short); } else if (code_no <= 10) { WORD32 sign = 0; if (code_no > 6) sign = 1; ret_val = ixheaacd_res_c_block_decode_huff_word2_2(it_bit_buf, quantized_coef, p_band_off, no_bands, group_no, h_ori, pow_table, sign, maximum_bins_short); } { WORD bits_cons; bits_cons = (WORD)(((it_bit_buf->ptr_read_next - start_read_pos) << 3) + (it_bit_buf->bit_pos - start_bit_pos)); it_bit_buf->cnt_bits -= bits_cons; } return ret_val; } WORD ixheaacd_res_c_block_decode_huff_word_all_lb( ia_bit_buf_struct *it_bit_buf, WORD32 code_no, WORD32 len, ia_mps_dec_residual_aac_tables_struct *aac_tables_ptr, WORD32 *x_invquant, WORD8 *p_pul_arr) { WORD ret_val = 0; WORD start_bit_pos = it_bit_buf->bit_pos; WORD32 *pow_table = (WORD32 *)aac_tables_ptr->res_block_tables_ptr->pow_table_q17; UWORD8 *start_read_pos = it_bit_buf->ptr_read_next; const UWORD16 *h_ori = (UWORD16 *)(aac_tables_ptr->code_book[code_no]); if (code_no == 11) { const UWORD16 *h_ori = aac_tables_ptr->res_huffmann_tables_ptr->huffman_codebook_11; ret_val = ixheaacd_res_c_block_decode_huff_word1_lb(it_bit_buf, len, h_ori, x_invquant, pow_table, p_pul_arr); } else if (code_no <= 4) { WORD32 sign = 0; if (code_no > 2) sign = 1; ret_val = ixheaacd_res_c_block_decode_huff_word2_4_lb(it_bit_buf, len, h_ori, x_invquant, pow_table, p_pul_arr, sign); } else if (code_no <= 10) { WORD32 sign = 0; if (code_no > 6) sign = 1; ret_val = ixheaacd_res_c_block_decode_huff_word2_2_lb(it_bit_buf, len, h_ori, x_invquant, pow_table, p_pul_arr, sign); } { WORD bits_cons; if (it_bit_buf->bit_pos <= 7) { bits_cons = (WORD)(((it_bit_buf->ptr_read_next - start_read_pos) << 3) + (it_bit_buf->bit_pos - start_bit_pos)); it_bit_buf->cnt_bits -= bits_cons; } else { it_bit_buf->ptr_read_next += (it_bit_buf->bit_pos) >> 3; it_bit_buf->bit_pos = it_bit_buf->bit_pos & 0x7; bits_cons = (WORD)(((it_bit_buf->ptr_read_next - start_read_pos) << 3) + ((it_bit_buf->bit_pos - start_bit_pos))); it_bit_buf->cnt_bits -= bits_cons; } } return ret_val; } static VOID ixheaacd_res_apply_one_scf(WORD32 scale_factor, WORD32 *x_invquant, WORD32 end, WORD32 *scale_table_ptr) { WORD32 j; WORD32 temp_1; WORD32 q_factor; WORD32 buffer1; WORD16 scale_short; if (scale_factor < 24) { for (j = end; j > 0; j--) { *x_invquant++ = 0; } } else { WORD32 shift; q_factor = 37 - (scale_factor >> 2); scale_short = scale_table_ptr[(scale_factor & 0x0003)]; shift = q_factor; if (shift > 0) { if (scale_short == (WORD16)0x8000) { for (j = end; j > 0; j--) { temp_1 = *x_invquant; buffer1 = ixheaacd_mult32x16in32_shl_sat(temp_1, scale_short); buffer1 = ixheaacd_shr32(buffer1, shift); *x_invquant++ = buffer1; } } else { for (j = end; j > 0; j--) { temp_1 = *x_invquant; buffer1 = ixheaacd_mult32x16in32_shl(temp_1, scale_short); buffer1 = ixheaacd_shr32(buffer1, shift); *x_invquant++ = buffer1; } } } else { shift = -shift; if (shift > 0) { if (scale_short == (WORD16)0x8000) { for (j = end; j > 0; j--) { temp_1 = *x_invquant; temp_1 = ixheaacd_shl32(temp_1, shift - 1); buffer1 = ixheaacd_mult32x16in32_shl_sat(temp_1, scale_short); buffer1 = ixheaacd_shl32(buffer1, 1); *x_invquant++ = buffer1; } } else { for (j = end; j > 0; j--) { temp_1 = *x_invquant; temp_1 = ixheaacd_shl32(temp_1, shift - 1); buffer1 = ixheaacd_mult32x16in32_shl(temp_1, scale_short); buffer1 = ixheaacd_shl32(buffer1, 1); *x_invquant++ = buffer1; } } } else { if (scale_short == (WORD16)0x8000) { for (j = end; j > 0; j--) { temp_1 = *x_invquant; buffer1 = ixheaacd_mult32x16in32_shl_sat(temp_1, scale_short); *x_invquant++ = buffer1; } } else { for (j = end; j > 0; j--) { temp_1 = *x_invquant; buffer1 = ixheaacd_mult32x16in32_shl(temp_1, scale_short); *x_invquant++ = buffer1; } } } } } } VOID ixheaacd_res_apply_scfs(WORD32 *x_invquant, WORD16 *sc_factor, WORD t_bands, WORD8 *offset, WORD32 *scale_table_ptr) { WORD32 i; WORD16 scale_factor; for (i = t_bands - 1; i >= 0; i--) { scale_factor = *sc_factor++; ixheaacd_res_apply_one_scf(scale_factor, x_invquant, *offset, scale_table_ptr); x_invquant += *offset; offset++; } }