diff options
author | Akshay Ragir <akshay.ragir@ittiam.com> | 2023-10-03 10:41:06 +0530 |
---|---|---|
committer | Divya B M <89966460+divya-bm@users.noreply.github.com> | 2023-10-03 19:14:29 +0530 |
commit | f247fa376e052a1c2a89395f10e23620ab483a24 (patch) | |
tree | 019f9026d917425af46588eb5b481759709c85b5 | |
parent | 56716426e2087e604ee6267129857b409e53ab09 (diff) | |
download | libxaac-f247fa376e052a1c2a89395f10e23620ab483a24.tar.gz |
Fix for the Divide-by-zero in impd_drc_td_drc_gain_calc_init
These changes handle the divide-by-zero runtime error
reported when the successive drc gain coordinates
have same x coordinates.
Bug: ossFuzz:62237
Test: poc in bug
-rw-r--r-- | encoder/drc_src/impd_drc_enc.c | 2 | ||||
-rw-r--r-- | encoder/drc_src/impd_drc_gain_calculator.c | 134 | ||||
-rw-r--r-- | encoder/drc_src/impd_drc_gain_enc.c | 6 | ||||
-rw-r--r-- | encoder/ixheaace_basic_ops.c | 14 | ||||
-rw-r--r-- | encoder/ixheaace_common_utils.h | 3 |
5 files changed, 76 insertions, 83 deletions
diff --git a/encoder/drc_src/impd_drc_enc.c b/encoder/drc_src/impd_drc_enc.c index 1b92856..7e835f7 100644 --- a/encoder/drc_src/impd_drc_enc.c +++ b/encoder/drc_src/impd_drc_enc.c @@ -205,7 +205,7 @@ IA_ERRORCODE impd_drc_gain_enc_init(ia_drc_gain_enc_struct *pstr_gain_enc, pstr_gain_enc->str_drc_compand[0][j].initial_volume = 0.0f; err_code = impd_drc_td_drc_gain_calc_init(pstr_gain_enc, 0, j); - if (err_code & IA_FATAL_ERROR) { + if (err_code) { return err_code; } pstr_gain_enc->str_drc_compand[0][j].ch_idx = ch_idx; diff --git a/encoder/drc_src/impd_drc_gain_calculator.c b/encoder/drc_src/impd_drc_gain_calculator.c index 2a3400e..bbc5b98 100644 --- a/encoder/drc_src/impd_drc_gain_calculator.c +++ b/encoder/drc_src/impd_drc_gain_calculator.c @@ -46,6 +46,7 @@ #include "impd_drc_gain_enc.h" #include "impd_drc_struct_def.h" #include "impd_drc_enc.h" +#include "ixheaace_common_utils.h" static VOID impd_drc_compand_update_volume(ia_drc_compand_chan_param_struct *pstr_channel_param, FLOAT64 in_value) { @@ -68,7 +69,12 @@ static FLOAT64 impd_drc_compand_get_volume(ia_drc_compand_struct *pstr_drc_compa return pstr_drc_compand->out_min_lin; } - in_log = log(in_lin); + if (fabs(in_lin) <= FLT_EPSILON) { + in_log = log(FLT_EPSILON); + } + else { + in_log = log(fabs(in_lin)); + } for (idx = 1; idx < pstr_drc_compand->nb_segments; idx++) { if (in_log <= pstr_drc_compand->str_segment[idx].x) { @@ -122,8 +128,6 @@ IA_ERRORCODE impd_drc_td_drc_gain_calc_init(ia_drc_gain_enc_struct *pstr_drc_gai pstr_drc_compand = &pstr_drc_gain_enc->str_drc_compand[drc_coefficients_uni_drc_idx][gain_set_idx]; - pstr_drc_compand->nb_segments = (pstr_drc_compand->nb_points + 4) * 2; - for (i = 0; i < pstr_drc_compand->nb_points; i++) { if (i && pstr_drc_compand->str_segment[2 * ((i - 1) + 1)].x > pstr_drc_compand->str_segment[2 * ((i) + 1)].x) { @@ -162,6 +166,7 @@ IA_ERRORCODE impd_drc_td_drc_gain_calc_init(ia_drc_gain_enc_struct *pstr_drc_gai } } + pstr_drc_compand->nb_segments = num_points * 2; for (i = 0; i < pstr_drc_compand->nb_segments; i += 2) { pstr_drc_compand->str_segment[i].y += pstr_drc_compand->gain_db; pstr_drc_compand->str_segment[i].x *= M_LN10_DIV_20; @@ -169,35 +174,33 @@ IA_ERRORCODE impd_drc_td_drc_gain_calc_init(ia_drc_gain_enc_struct *pstr_drc_gai } for (i = 4; i < pstr_drc_compand->nb_segments; i += 2) { - pstr_drc_compand->str_segment[i - 4].a = 0; - pstr_drc_compand->str_segment[i - 4].b = - (pstr_drc_compand->str_segment[i - 2].y - pstr_drc_compand->str_segment[i - 4].y) / - (pstr_drc_compand->str_segment[i - 2].x - pstr_drc_compand->str_segment[i - 4].x); - - pstr_drc_compand->str_segment[i - 2].a = 0; - pstr_drc_compand->str_segment[i - 2].b = - (pstr_drc_compand->str_segment[i].y - pstr_drc_compand->str_segment[i - 2].y) / - (pstr_drc_compand->str_segment[i].x - pstr_drc_compand->str_segment[i - 2].x); - - theta = - atan2(pstr_drc_compand->str_segment[i - 2].y - pstr_drc_compand->str_segment[i - 4].y, - pstr_drc_compand->str_segment[i - 2].x - pstr_drc_compand->str_segment[i - 4].x); - length = - hypot(pstr_drc_compand->str_segment[i - 2].x - pstr_drc_compand->str_segment[i - 4].x, - pstr_drc_compand->str_segment[i - 2].y - pstr_drc_compand->str_segment[i - 4].y); + FLOAT64 num = 0.0; + FLOAT64 den = 0.0f; + num = pstr_drc_compand->str_segment[i - 2].y - pstr_drc_compand->str_segment[i - 4].y; + den = pstr_drc_compand->str_segment[i - 2].x - pstr_drc_compand->str_segment[i - 4].x; + length = hypot(num, den); + if (length < FLT_EPSILON) { + return IA_EXHEAACE_EXE_NONFATAL_USAC_INVALID_GAIN_POINTS; + } + pstr_drc_compand->str_segment[i - 4].a = 0; + pstr_drc_compand->str_segment[i - 4].b = ixheaace_div64(num, den); + theta = atan2(num, den); r = MIN(radius, length); pstr_drc_compand->str_segment[i - 3].x = pstr_drc_compand->str_segment[i - 2].x - r * cos(theta); pstr_drc_compand->str_segment[i - 3].y = pstr_drc_compand->str_segment[i - 2].y - r * sin(theta); - theta = - atan2(pstr_drc_compand->str_segment[i].y - pstr_drc_compand->str_segment[i - 2].y, - pstr_drc_compand->str_segment[i - 0].x - pstr_drc_compand->str_segment[i - 2].x); - length = hypot(pstr_drc_compand->str_segment[i].x - pstr_drc_compand->str_segment[i - 2].x, - pstr_drc_compand->str_segment[i].y - pstr_drc_compand->str_segment[i - 2].y); - + num = pstr_drc_compand->str_segment[i].y - pstr_drc_compand->str_segment[i - 2].y; + den = pstr_drc_compand->str_segment[i].x - pstr_drc_compand->str_segment[i - 2].x; + length = hypot(num, den); + if (length < FLT_EPSILON) { + return IA_EXHEAACE_EXE_NONFATAL_USAC_INVALID_GAIN_POINTS; + } + pstr_drc_compand->str_segment[i - 2].a = 0; + pstr_drc_compand->str_segment[i - 2].b = ixheaace_div64(num, den); + theta = atan2(num, den); r = MIN(radius, length / 2); x = pstr_drc_compand->str_segment[i - 2].x + r * cos(theta); y = pstr_drc_compand->str_segment[i - 2].y + r * sin(theta); @@ -214,9 +217,14 @@ IA_ERRORCODE impd_drc_td_drc_gain_calc_init(ia_drc_gain_enc_struct *pstr_drc_gai out_1 = cy - pstr_drc_compand->str_segment[i - 3].y; inp_2 = pstr_drc_compand->str_segment[i - 2].x - pstr_drc_compand->str_segment[i - 3].x; out_2 = pstr_drc_compand->str_segment[i - 2].y - pstr_drc_compand->str_segment[i - 3].y; - pstr_drc_compand->str_segment[i - 3].a = (out_2 / inp_2 - out_1 / inp_1) / (inp_2 - inp_1); - pstr_drc_compand->str_segment[i - 3].b = - out_1 / inp_1 - pstr_drc_compand->str_segment[i - 3].a * inp_1; + + num = (out_2 * inp_1) - (inp_2 * out_1); + den = (inp_2 - inp_1) * inp_1 * inp_2; + pstr_drc_compand->str_segment[i - 3].a = ixheaace_div64(num, den); + + num = out_1 - (pstr_drc_compand->str_segment[i - 3].a * inp_1 * inp_1); + den = inp_1; + pstr_drc_compand->str_segment[i - 3].b = ixheaace_div64(num, den); } pstr_drc_compand->str_segment[i - 3].x = 0; pstr_drc_compand->str_segment[i - 3].y = pstr_drc_compand->str_segment[i - 3].y; @@ -344,8 +352,6 @@ IA_ERRORCODE impd_drc_stft_drc_gain_calc_init(ia_drc_gain_enc_struct *pstr_drc_g width_e = (FLOAT32)(pstr_drc_stft_gain_handle->width_db * M_LN10_DIV_20); - pstr_drc_stft_gain_handle->nb_segments = (pstr_drc_stft_gain_handle->nb_points + 4) * 2; - for (i = 0; i < pstr_drc_stft_gain_handle->nb_points; i++) { if (i && pstr_drc_stft_gain_handle->str_segment[2 * ((i - 1) + 1)].x > pstr_drc_stft_gain_handle->str_segment[2 * (i + 1)].x) { @@ -385,7 +391,7 @@ IA_ERRORCODE impd_drc_stft_drc_gain_calc_init(ia_drc_gain_enc_struct *pstr_drc_g pstr_drc_stft_gain_handle->str_segment[2 * (j + 1)]; } } - + pstr_drc_stft_gain_handle->nb_segments = num_points * 2; for (i = 0; i < pstr_drc_stft_gain_handle->nb_segments; i += 2) { pstr_drc_stft_gain_handle->str_segment[i].y += pstr_drc_stft_gain_handle->gain_db; pstr_drc_stft_gain_handle->str_segment[i].x *= M_LN10_DIV_20; @@ -401,64 +407,31 @@ IA_ERRORCODE impd_drc_stft_drc_gain_calc_init(ia_drc_gain_enc_struct *pstr_drc_g numerator = pstr_drc_stft_gain_handle->str_segment[i - 2].y - pstr_drc_stft_gain_handle->str_segment[i - 4].y; len = hypot(denominator , numerator); - if (len == 0) { + if (len < FLT_EPSILON) { return IA_EXHEAACE_EXE_NONFATAL_USAC_INVALID_GAIN_POINTS; } - if (fabs(denominator) < FLT_EPSILON) { - if (denominator < 0) - denominator = -FLT_EPSILON; - else - denominator = FLT_EPSILON; - } pstr_drc_stft_gain_handle->str_segment[i - 4].a = 0; - pstr_drc_stft_gain_handle->str_segment[i - 4].b = numerator / denominator; + pstr_drc_stft_gain_handle->str_segment[i - 4].b = ixheaace_div64(numerator, denominator); + theta = atan2(numerator, denominator); + r = MIN(width_e / (2.0f * cos(theta)), len / 2); + + pstr_drc_stft_gain_handle->str_segment[i - 3].x = + pstr_drc_stft_gain_handle->str_segment[i - 2].x - r * cos(theta); + pstr_drc_stft_gain_handle->str_segment[i - 3].y = + pstr_drc_stft_gain_handle->str_segment[i - 2].y - r * sin(theta); denominator = pstr_drc_stft_gain_handle->str_segment[i].x - pstr_drc_stft_gain_handle->str_segment[i - 2].x; numerator = pstr_drc_stft_gain_handle->str_segment[i].y - pstr_drc_stft_gain_handle->str_segment[i - 2].y; len = hypot(denominator, numerator); - if (len == 0) { + if (len < FLT_EPSILON) { return IA_EXHEAACE_EXE_NONFATAL_USAC_INVALID_GAIN_POINTS; } - if (fabs(denominator) < FLT_EPSILON) { - if (denominator < 0) - denominator = -FLT_EPSILON; - else - denominator = FLT_EPSILON; - } pstr_drc_stft_gain_handle->str_segment[i - 2].a = 0; - pstr_drc_stft_gain_handle->str_segment[i - 2].b = numerator / denominator; + pstr_drc_stft_gain_handle->str_segment[i - 2].b = ixheaace_div64(numerator, denominator); - - denominator = pstr_drc_stft_gain_handle->str_segment[i - 2].x - - pstr_drc_stft_gain_handle->str_segment[i - 4].x; - numerator = pstr_drc_stft_gain_handle->str_segment[i - 2].y - - pstr_drc_stft_gain_handle->str_segment[i - 4].y; - if (fabs(denominator) < FLT_EPSILON) { - if (denominator < 0) - denominator = -FLT_EPSILON; - else - denominator = FLT_EPSILON; - } theta = atan2(numerator, denominator); - len = hypot(denominator, numerator); - r = MIN(width_e / (2.0f * cos(theta)), len / 2); - - pstr_drc_stft_gain_handle->str_segment[i - 3].x = - pstr_drc_stft_gain_handle->str_segment[i - 2].x - r * cos(theta); - pstr_drc_stft_gain_handle->str_segment[i - 3].y = - pstr_drc_stft_gain_handle->str_segment[i - 2].y - r * sin(theta); - - theta = atan2(pstr_drc_stft_gain_handle->str_segment[i].y - - pstr_drc_stft_gain_handle->str_segment[i - 2].y, - pstr_drc_stft_gain_handle->str_segment[i].x - - pstr_drc_stft_gain_handle->str_segment[i - 2].x); - len = hypot(pstr_drc_stft_gain_handle->str_segment[i].x - - pstr_drc_stft_gain_handle->str_segment[i - 2].x, - pstr_drc_stft_gain_handle->str_segment[i].y - - pstr_drc_stft_gain_handle->str_segment[i - 2].y); - r = MIN(width_e / (2.0f * cos(theta)), len / 2); x = pstr_drc_stft_gain_handle->str_segment[i - 2].x + r * cos(theta); y = pstr_drc_stft_gain_handle->str_segment[i - 2].y + r * sin(theta); @@ -479,10 +452,13 @@ IA_ERRORCODE impd_drc_stft_drc_gain_calc_init(ia_drc_gain_enc_struct *pstr_drc_g pstr_drc_stft_gain_handle->str_segment[i - 3].x; out_2 = pstr_drc_stft_gain_handle->str_segment[i - 2].y - pstr_drc_stft_gain_handle->str_segment[i - 3].y; - pstr_drc_stft_gain_handle->str_segment[i - 3].a = - (out_2 / inp_2 - out_1 / inp_1) / (inp_2 - inp_1); - pstr_drc_stft_gain_handle->str_segment[i - 3].b = - out_1 / inp_1 - pstr_drc_stft_gain_handle->str_segment[i - 3].a * inp_1; + numerator = (out_2 * inp_1) - (inp_2 * out_1); + denominator = (inp_2 - inp_1) * inp_2 * inp_1; + pstr_drc_stft_gain_handle->str_segment[i - 3].a = ixheaace_div64(numerator, denominator); + + numerator = out_1 - (pstr_drc_stft_gain_handle->str_segment[i - 3].a * inp_1 * inp_1); + denominator = inp_1; + pstr_drc_stft_gain_handle->str_segment[i - 3].b = ixheaace_div64(numerator, denominator); } pstr_drc_stft_gain_handle->str_segment[i - 3].x = 0; pstr_drc_stft_gain_handle->str_segment[i - 3].y = diff --git a/encoder/drc_src/impd_drc_gain_enc.c b/encoder/drc_src/impd_drc_gain_enc.c index fd10488..3ea9cf4 100644 --- a/encoder/drc_src/impd_drc_gain_enc.c +++ b/encoder/drc_src/impd_drc_gain_enc.c @@ -21,6 +21,7 @@ #include <stdlib.h> #include <string.h> #include <math.h> +#include <float.h> #include "ixheaac_type_def.h" #include "ixheaac_error_standards.h" #include "ixheaace_error_codes.h" @@ -44,6 +45,7 @@ #include "ixheaace_sbr_header.h" #include "ixheaace_config.h" #include "iusace_config.h" +#include "ixheaace_common_utils.h" static FLOAT32 impd_drc_limit_drc_gain(const WORD32 gain_coding_profile, const FLOAT32 gain) { FLOAT32 limited_drc_gain; @@ -128,7 +130,7 @@ static VOID impd_drc_check_overshoot(const WORD32 t_gain_step, const FLOAT32 gai FLOAT32 k1, k2; FLOAT32 slope_norm = 1.0f / (FLOAT32)time_delta_min; FLOAT32 margin = 0.2f; - FLOAT32 step_inv_2 = 2.0f / t_gain_step; + FLOAT32 step_inv_2 = ixheaace_div32(2.0f, (FLOAT32)t_gain_step); *overshoot_left = FALSE; *overshoot_right = FALSE; @@ -180,7 +182,7 @@ static VOID impd_drc_check_overshoot(const WORD32 t_gain_step, const FLOAT32 gai } if ((!*overshoot_left) && (!*overshoot_right)) { - t_gain_step_inv = 1.0f / (FLOAT32)t_gain_step; + t_gain_step_inv = ixheaace_div32(1.0f, (FLOAT32)t_gain_step); t_gain_step_inv_2 = t_gain_step_inv * t_gain_step_inv; k1 = (gain_right - gain_left) * t_gain_step_inv_2; k2 = norm_slope_1 + norm_slope_0; diff --git a/encoder/ixheaace_basic_ops.c b/encoder/ixheaace_basic_ops.c index 04b727b..a49458e 100644 --- a/encoder/ixheaace_basic_ops.c +++ b/encoder/ixheaace_basic_ops.c @@ -49,3 +49,17 @@ FLOAT32 ixheaace_div32(FLOAT32 num, FLOAT32 den) { return num / den; } } + +FLOAT64 ixheaace_div64(FLOAT64 num, FLOAT64 den) { + if (fabs(den) < FLT_EPSILON) { + if (den < 0.0) { + return -num; + } + else { + return num; + } + } + else { + return num / den; + } +} diff --git a/encoder/ixheaace_common_utils.h b/encoder/ixheaace_common_utils.h index 4c03c9f..9609f18 100644 --- a/encoder/ixheaace_common_utils.h +++ b/encoder/ixheaace_common_utils.h @@ -38,4 +38,5 @@ #define C76 (0.5339693427f) //(sin(u) - 2 * sin(2 * u) - sin(3 * u)) / 3; #define C77 (-0.8748422265f) //(sin(u) + sin(2 * u) + 2 * sin(3 * u)) / 3; -FLOAT32 ixheaace_div32(FLOAT32 num, FLOAT32 den);
\ No newline at end of file +FLOAT32 ixheaace_div32(FLOAT32 num, FLOAT32 den); +FLOAT64 ixheaace_div64(FLOAT64 num, FLOAT64 den); |