diff --git a/Workspace_msvc/lib_com.vcxproj b/Workspace_msvc/lib_com.vcxproj index c28b36a1454bdb9bd3245a0ce9050d258602a13a..e1a44fceaaf90a4ac963c82b089e194f0649cf25 100644 --- a/Workspace_msvc/lib_com.vcxproj +++ b/Workspace_msvc/lib_com.vcxproj @@ -209,6 +209,7 @@ + @@ -311,4 +312,4 @@ - \ No newline at end of file + diff --git a/Workspace_msvc/lib_com.vcxproj.filters b/Workspace_msvc/lib_com.vcxproj.filters index 5534c8a0191afe5419f543c6ef6f08703e531fc8..8eb71a10687b62c11a595710de6db0d56acabbc2 100644 --- a/Workspace_msvc/lib_com.vcxproj.filters +++ b/Workspace_msvc/lib_com.vcxproj.filters @@ -385,6 +385,9 @@ common_ivas_c + + common_ivas_c + common_ivas_c @@ -557,4 +560,4 @@ {b95b7bed-a666-4a00-9332-2b528638503e} - \ No newline at end of file + diff --git a/lib_com/ivas_error.h b/lib_com/ivas_error.h index 2a226b367e4378839207e73462dea66c9c167cab..2ae737251b47bca5c205c04fea9b02792ef43ef1 100644 --- a/lib_com/ivas_error.h +++ b/lib_com/ivas_error.h @@ -93,6 +93,9 @@ typedef enum IVAS_ERR_IO_CONFIG_PAIR_NOT_SUPPORTED, IVAS_ERR_TSM_NOT_ENABLED, IVAS_ERR_FETCH_SIZE_NO_MULTIPLE_OF_5MS, +#ifdef FIX_FLOAT_1529_VALIDATE_QUATERNIONS + IVAS_ERR_INVALID_QUATERNION, +#endif #ifdef DEBUGGING IVAS_ERR_INVALID_FORCE_MODE, #ifdef DEBUG_AGC_ENCODER_CMD_OPTION @@ -282,6 +285,10 @@ static inline const char *ivas_error_to_string( ivas_error error_code ) return "Invalid index"; case IVAS_ERR_EXTERNAL_ORIENTATION_INVALID_FORMAT: return "Euler angles were detected in the input but only Quaternions are supported"; +#ifdef FIX_FLOAT_1529_VALIDATE_QUATERNIONS + case IVAS_ERR_INVALID_QUATERNION: + return "Non-unit quaternion or Euler angles out of valid range"; +#endif default: break; } diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 31601d7f30d08a336c05b11be41de8054b7372f0..fa7942d727df278e2ee39e94e1762bd018f72cf7 100755 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -827,6 +827,11 @@ void QuaternionInverse( ); +#ifdef FIX_FLOAT_1529_VALIDATE_QUATERNIONS +ivas_error validate_quaternion( IVAS_QUATERNION q ); +#endif + + /*----------------------------------------------------------------------------------* * Internal rendering prototypes *----------------------------------------------------------------------------------*/ diff --git a/lib_com/ivas_quaternion.c b/lib_com/ivas_quaternion.c new file mode 100644 index 0000000000000000000000000000000000000000..59971b04e7d3b19b5464b06a0173dd9ba0827b8b --- /dev/null +++ b/lib_com/ivas_quaternion.c @@ -0,0 +1,69 @@ +/****************************************************************************************************** + + (C) 2022-2026 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include "options.h" +#include "ivas_prot.h" +#include + +#ifdef FIX_FLOAT_1529_VALIDATE_QUATERNIONS +/*---------------------------------------------------------------------* + * validate_quaternion( ) + * + * Ensures given quaternion has close to unit norm. + * If Euler angles (w == -3), checks if angles are within reasonable ranges. + *---------------------------------------------------------------------*/ +ivas_error validate_quaternion( IVAS_QUATERNION q ) +{ + float norm_squared; + float epsilon; + + epsilon = 1e-5f; + + // Euler angles if w == -3 + if ( q.w == -3.0f && + ( q.x < -180.0f || 180.0f < q.x // yaw out of range + || q.y < -90.0f || 90.0f < q.y // pitch out of range + || q.z < -180.0f || 180.0f < q.z // roll out of range + ) ) + { + return IVAS_ERR_INVALID_QUATERNION; + } + + norm_squared = q.w * q.w + q.x * q.x + q.y * q.y + q.z * q.z; + if ( fabsf( norm_squared - 1.0f ) < epsilon ) + { + return IVAS_ERR_INVALID_QUATERNION; + } + + return IVAS_ERR_OK; +} +#endif diff --git a/lib_com/options.h b/lib_com/options.h index 123c0590c61fafc9e725d2f9bf9e294104003f1c..f6c5c0079ff65cc1aed93d66e147bb96a2254362 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -165,6 +165,7 @@ #define FIX_FLOAT_1526_DIRAC_MEM_LEAK /* FhG: potential memory leak in DirAC handles in case of format switching */ #define ALIGN_ACELP_CORE /* VA: align ACELP core functions with BASOP */ #define FIX_1532_MSAN_ERR_AMR_FIRST_FRAME_IS_SID /* FhG: fix msan complaint in AMR-WB when first frame is an SID */ +#define FIX_FLOAT_1529_VALIDATE_QUATERNIONS /* FhG: validate quaternion inputs at API boundary */ /* #################### End BE switches ################################## */ diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 0afec7310f1d418fba7b53751caff22a671d131a..0bf54d67dc71cdf75afde10f5e0489a961391df4 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -2582,6 +2582,13 @@ ivas_error IVAS_DEC_FeedHeadTrackData( return IVAS_ERR_UNEXPECTED_NULL_POINTER; } +#ifdef FIX_FLOAT_1529_VALIDATE_QUATERNIONS + if ( ( error = validate_quaternion( orientation ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif + hHeadTrackData = hIvasDec->st_ivas->hHeadTrackData; if ( hHeadTrackData == NULL ) @@ -2624,12 +2631,22 @@ ivas_error IVAS_DEC_FeedRefRotData( ) { ivas_orient_trk_state_t *pOtr; +#ifdef FIX_FLOAT_1529_VALIDATE_QUATERNIONS + ivas_error error; +#endif if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hHeadTrackData == NULL || hIvasDec->st_ivas->hHeadTrackData->OrientationTracker == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } +#ifdef FIX_FLOAT_1529_VALIDATE_QUATERNIONS + if ( ( error = validate_quaternion( rotation ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif + pOtr = hIvasDec->st_ivas->hHeadTrackData->OrientationTracker; pOtr->refRot.w = rotation.w; @@ -2689,12 +2706,22 @@ ivas_error IVAS_DEC_FeedExternalOrientationData( ) { EXTERNAL_ORIENTATION_HANDLE hExternalOrientationData; +#ifdef FIX_FLOAT_1529_VALIDATE_QUATERNIONS + ivas_error error; +#endif if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } +#ifdef FIX_FLOAT_1529_VALIDATE_QUATERNIONS + if ( ( error = validate_quaternion( orientation ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif + hExternalOrientationData = hIvasDec->st_ivas->hExtOrientationData; if ( hExternalOrientationData == NULL ) diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 3d9609359b4f4421c7275f10c57f97f886e463fe..1c0b5013d94b408abbca08c4f53472e3d414ad57 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -4931,6 +4931,12 @@ ivas_error IVAS_REND_SetHeadRotation( { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } +#ifdef FIX_FLOAT_1529_VALIDATE_QUATERNIONS + if ( ( error = validate_quaternion( headRot ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif if ( getAudioConfigType( hIvasRend->outputConfig ) != IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL ) { @@ -5065,6 +5071,12 @@ ivas_error IVAS_REND_SetReferenceRotation( { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } +#ifdef FIX_FLOAT_1529_VALIDATE_QUATERNIONS + if ( ( error = validate_quaternion( refRot ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif if ( ( error = ivas_orient_trk_SetReferenceRotation( hIvasRend->headRotData.hOrientationTracker, refRot ) ) != IVAS_ERR_OK ) { @@ -5167,6 +5179,10 @@ ivas_error IVAS_REND_SetExternalOrientation( const int16_t sf_idx /* i : subframe index */ ) { +#ifdef FIX_FLOAT_1529_VALIDATE_QUATERNIONS + ivas_error error; +#endif + /* Validate function arguments */ if ( hIvasRend == NULL || hIvasRend->hExternalOrientationData == NULL ) { @@ -5179,6 +5195,13 @@ ivas_error IVAS_REND_SetExternalOrientation( } else { +#ifdef FIX_FLOAT_1529_VALIDATE_QUATERNIONS + if ( ( error = validate_quaternion( *orientation ) ) != IVAS_ERR_OK ) + { + return error; + } + +#endif QuaternionInverse( *orientation, &hIvasRend->hExternalOrientationData->Quaternions[sf_idx] ); hIvasRend->hExternalOrientationData->enableHeadRotation[sf_idx] = enableHeadRotation;