LCOV - code coverage report
Current view: top level - lib_enc - ivas_entropy_coder.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 115 116 99.1 %
Date: 2025-05-23 08:37:30 Functions: 7 7 100.0 %

          Line data    Source code
       1             : /******************************************************************************************************
       2             : 
       3             :    (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
       4             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
       5             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
       6             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
       7             :    contributors to this repository. All Rights Reserved.
       8             : 
       9             :    This software is protected by copyright law and by international treaties.
      10             :    The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
      11             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
      12             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
      13             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
      14             :    contributors to this repository retain full ownership rights in their respective contributions in
      15             :    the software. This notice grants no license of any kind, including but not limited to patent
      16             :    license, nor is any license granted by implication, estoppel or otherwise.
      17             : 
      18             :    Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
      19             :    contributions.
      20             : 
      21             :    This software is provided "AS IS", without any express or implied warranties. The software is in the
      22             :    development stage. It is intended exclusively for experts who have experience with such software and
      23             :    solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
      24             :    and fitness for a particular purpose are hereby disclaimed and excluded.
      25             : 
      26             :    Any dispute, controversy or claim arising under or in relation to providing this software shall be
      27             :    submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
      28             :    accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
      29             :    the United Nations Convention on Contracts on the International Sales of Goods.
      30             : 
      31             : *******************************************************************************************************/
      32             : 
      33             : #include <stdint.h>
      34             : #include "options.h"
      35             : #include "ivas_cnst.h"
      36             : #ifdef DEBUGGING
      37             : #include "debug.h"
      38             : #endif
      39             : #include "prot.h"
      40             : #include "ivas_prot.h"
      41             : #include "ivas_rom_com.h"
      42             : #include "math.h"
      43             : #include <assert.h>
      44             : #include "wmc_auto.h"
      45             : 
      46             : 
      47             : /*-----------------------------------------------------------------------------------------*
      48             :  * Function ivas_get_dyn_freq_model()
      49             :  *
      50             :  * Chooses frequency model dynamically
      51             :  *-----------------------------------------------------------------------------------------*/
      52             : 
      53      865982 : static ivas_error ivas_get_dyn_freq_model(
      54             :     int16_t *pInput,
      55             :     const int16_t length,
      56             :     int16_t *model_index,
      57             :     ivas_arith_t *pArith,
      58             :     int16_t **ppCum_freq )
      59             : {
      60             :     float curr_dist[IVAS_MAX_QUANT_LEVELS];
      61             :     int16_t i, n[IVAS_MAX_QUANT_LEVELS + 1], model_idx;
      62             :     float curr_bps, curr_bps_min, curr_bps_new;
      63      865982 :     int16_t range = pArith->range;
      64      865982 :     int16_t m, offset = -pArith->vals[0];
      65             :     ivas_error error;
      66             : 
      67      865982 :     error = IVAS_ERR_OK;
      68             : 
      69    12468308 :     for ( i = 0; i < range + 1; i++ )
      70             :     {
      71    11602326 :         n[i] = 0;
      72             :     }
      73             : 
      74    18152638 :     for ( i = 0; i < length; i++ )
      75             :     {
      76    17286656 :         n[pInput[i] + offset] += 1;
      77             :     }
      78             : 
      79      865982 :     curr_bps = 0;
      80    11602326 :     for ( i = 0; i < range; i++ )
      81             :     {
      82    10736344 :         curr_dist[i] = (float) n[i];
      83    10736344 :         curr_bps -= ( curr_dist[i] * pArith->saved_dist_arr[0][i] );
      84             :     }
      85      865982 :     curr_bps_min = curr_bps;
      86             : 
      87      865982 :     model_idx = 0;
      88             : 
      89     3463928 :     for ( m = 0; m < pArith->num_models - 1; m++ )
      90             :     {
      91     2597946 :         curr_bps_new = 0;
      92    34806978 :         for ( i = 0; i < range; i++ )
      93             :         {
      94    32209032 :             curr_bps_new -= ( curr_dist[i] * pArith->saved_dist_arr[m + 1][i] );
      95             :         }
      96             : 
      97     2597946 :         if ( curr_bps_new < curr_bps_min )
      98             :         {
      99      778327 :             model_idx = m;
     100      778327 :             curr_bps_min = curr_bps_new;
     101             :         }
     102             :     }
     103             : 
     104      865982 :     if ( curr_bps_min < curr_bps )
     105             :     {
     106      499708 :         *ppCum_freq = pArith->cum_freq[model_idx + 1];
     107      499708 :         model_idx = model_idx + 1;
     108             :     }
     109             :     else
     110             :     {
     111      366274 :         model_idx = 0;
     112      366274 :         *ppCum_freq = pArith->cum_freq[0];
     113             :     }
     114             : 
     115      865982 :     *model_index = model_idx;
     116             : 
     117      865982 :     return error;
     118             : }
     119             : 
     120             : 
     121             : /*-----------------------------------------------------------------------------------------*
     122             :  * Function ivas_arith_encode_array()
     123             :  *
     124             :  * Arith encoding of an array of symbols
     125             :  *-----------------------------------------------------------------------------------------*/
     126             : 
     127      865982 : static int16_t ivas_arith_encode_array(
     128             :     int16_t *pInput,
     129             :     ivas_arith_t *pArith,
     130             :     BSTR_ENC_HANDLE hMetaData,
     131             :     const int16_t in_len,
     132             :     const int16_t wc_strat_arith )
     133             : {
     134             :     int16_t model_index, i, ind;
     135      865982 :     int16_t *pCum_freq = NULL;
     136             :     Tastat as;
     137             : 
     138      865982 :     if ( in_len > 0 && pArith->range > 1 )
     139             :     {
     140      865982 :         if ( pArith->dyn_model_bits > 0 )
     141             :         {
     142      865982 :             ivas_get_dyn_freq_model( pInput, in_len, &model_index, pArith, &pCum_freq );
     143      865982 :             if ( ( hMetaData->nb_bits_tot + pArith->dyn_model_bits ) > wc_strat_arith )
     144             :             {
     145           2 :                 return -1;
     146             :             }
     147             : 
     148      865980 :             push_next_indice( hMetaData, model_index, pArith->dyn_model_bits );
     149             :         }
     150             :         else
     151             :         {
     152           0 :             pCum_freq = pArith->cum_freq[0];
     153             :         }
     154             : 
     155      865980 :         ari_start_encoding_14bits( &as );
     156             : 
     157    18070467 :         for ( i = 0; i < in_len; i++ )
     158             :         {
     159    17226623 :             ind = pInput[i] - pArith->vals[0];
     160             : 
     161    17226623 :             ivas_ari_encode_14bits_ext( hMetaData, &as, ind, (const uint16_t *) pCum_freq );
     162    17226623 :             if ( hMetaData->nb_bits_tot > wc_strat_arith )
     163             :             {
     164       22136 :                 return -1;
     165             :             }
     166             :         }
     167             : 
     168      843844 :         ivas_ari_done_encoding_14bits( hMetaData, &as );
     169      843844 :         if ( hMetaData->nb_bits_tot > wc_strat_arith )
     170             :         {
     171        5280 :             return -1;
     172             :         }
     173             :     }
     174             : 
     175      838564 :     return 0;
     176             : }
     177             : 
     178             : 
     179             : /*-----------------------------------------------------------------------------------------*
     180             :  * Function ivas_arithCoder_encode_array_diff()
     181             :  *
     182             :  * Differential arith encoding
     183             :  *-----------------------------------------------------------------------------------------*/
     184             : 
     185      226250 : static int16_t ivas_arithCoder_encode_array_diff(
     186             :     ivas_arith_t *pArith_diff,
     187             :     int16_t *pIn_new,
     188             :     int16_t *pIn_old_scratch,
     189             :     const int16_t length,
     190             :     BSTR_ENC_HANDLE hMetaData,
     191             :     const int16_t wc_strat_arith )
     192             : {
     193             :     int16_t n;
     194             :     int16_t arith_result;
     195             : 
     196      226250 :     if ( length > 0 )
     197             :     {
     198     3487124 :         for ( n = 0; n < length; n++ )
     199             :         {
     200     3260874 :             pIn_old_scratch[n] = pIn_new[n] - pIn_old_scratch[n];
     201             :         }
     202             : 
     203      226250 :         ivas_wrap_arround( pIn_old_scratch, pArith_diff->vals[0], pArith_diff->vals[pArith_diff->range - 1], length );
     204             : 
     205      226250 :         arith_result = ivas_arith_encode_array( pIn_old_scratch, pArith_diff, hMetaData, length, wc_strat_arith );
     206      226250 :         if ( arith_result < 0 )
     207             :         {
     208         903 :             return -1;
     209             :         }
     210             :     }
     211             : 
     212      225347 :     return 0;
     213             : }
     214             : 
     215             : 
     216             : /*-----------------------------------------------------------------------------------------*
     217             :  * Function ivas_huffman_encode()
     218             :  *
     219             :  * ivas_huffman_encode
     220             :  *-----------------------------------------------------------------------------------------*/
     221             : 
     222     4632982 : void ivas_huffman_encode(
     223             :     ivas_huffman_cfg_t *huff_cfg,
     224             :     int16_t in,
     225             :     int16_t *hcode,
     226             :     int16_t *hlen )
     227             : {
     228             :     int16_t min_sym_val;
     229             :     const int16_t *codebook;
     230             : 
     231     4632982 :     min_sym_val = huff_cfg->codebook[0];
     232             : 
     233     4632982 :     codebook = &huff_cfg->codebook[3 * ( in - min_sym_val )];
     234     4632982 :     *hlen = codebook[1];
     235     4632982 :     *hcode = codebook[2];
     236             : 
     237     4632982 :     return;
     238             : }
     239             : 
     240             : 
     241             : /*-----------------------------------------------------------------------------------------*
     242             :  * Function arith_encode_cell_array()
     243             :  *
     244             :  * Arithmetic encode a cell array
     245             :  *-----------------------------------------------------------------------------------------*/
     246             : 
     247      759404 : static int16_t arith_encode_cell_array(
     248             :     ivas_cell_dim_t *pCell_dims,
     249             :     BSTR_ENC_HANDLE hMetaData,
     250             :     const int16_t nB,
     251             :     ivas_arith_t *pArith,
     252             :     int16_t *pSymbol,
     253             :     const int16_t wc_strat_arith )
     254             : {
     255      759404 :     int16_t total_symbol_len = 0;
     256             :     int16_t i;
     257             :     int16_t arith_result;
     258             : 
     259     6795624 :     for ( i = 0; i < nB; i++ )
     260             :     {
     261     6036220 :         total_symbol_len += ( pCell_dims[i].dim1 * pCell_dims[i].dim2 );
     262             :     }
     263             : 
     264      759404 :     assert( total_symbol_len <= ( IVAS_MAX_INPUT_LEN ) );
     265             : 
     266      759404 :     if ( total_symbol_len > 0 )
     267             :     {
     268      639732 :         if ( pArith->range > 1 )
     269             :         {
     270      639732 :             arith_result = ivas_arith_encode_array( pSymbol, pArith, hMetaData, total_symbol_len, wc_strat_arith );
     271      639732 :             if ( arith_result < 0 )
     272             :             {
     273       26515 :                 return -1;
     274             :             }
     275             :         }
     276             :     }
     277             : 
     278      732889 :     return 0;
     279             : }
     280             : 
     281             : 
     282             : /*-----------------------------------------------------------------------------------------*
     283             :  * Function arith_encode_cell_array_diff()
     284             :  *
     285             :  * Arithmetic encode a cell array - differential
     286             :  *-----------------------------------------------------------------------------------------*/
     287             : 
     288      254398 : static int16_t arith_encode_cell_array_diff(
     289             :     const ivas_cell_dim_t *pCell_dims,
     290             :     BSTR_ENC_HANDLE hMetaData,
     291             :     int16_t nB,
     292             :     ivas_arith_t *pArith_diff,
     293             :     int16_t *pSymbol_old,
     294             :     int16_t *pSymbol,
     295             :     const int16_t wc_strat_arith )
     296             : {
     297             :     int16_t i, total_symbol_len;
     298             :     int16_t arith_result;
     299             : 
     300      254398 :     total_symbol_len = 0;
     301     2289582 :     for ( i = 0; i < nB; i++ )
     302             :     {
     303     2035184 :         total_symbol_len += ( pCell_dims[i].dim1 * pCell_dims[i].dim2 );
     304             :     }
     305             : 
     306      254398 :     assert( total_symbol_len <= ( IVAS_MAX_INPUT_LEN ) );
     307             : 
     308      254398 :     if ( total_symbol_len > 0 )
     309             :     {
     310      226250 :         if ( pArith_diff->range > 1 )
     311             :         {
     312      226250 :             arith_result = ivas_arithCoder_encode_array_diff( pArith_diff, pSymbol, pSymbol_old, total_symbol_len, hMetaData, wc_strat_arith );
     313      226250 :             if ( arith_result < 0 )
     314             :             {
     315         903 :                 return -1;
     316             :             }
     317             :         }
     318             :     }
     319             : 
     320      253495 :     return 0;
     321             : }
     322             : 
     323             : 
     324             : /*-----------------------------------------------------------------------------------------*
     325             :  * Function ivas_arith_encode_cmplx_cell_array()
     326             :  *
     327             :  * Arithmetic encode a cell array
     328             :  *-----------------------------------------------------------------------------------------*/
     329             : 
     330      759404 : int16_t ivas_arith_encode_cmplx_cell_array(
     331             :     ivas_arith_t *pArith_re,
     332             :     ivas_arith_t *pArith_re_diff,
     333             :     const int16_t *pDo_diff,
     334             :     const int16_t nB,
     335             :     int16_t *pSymbol_re,
     336             :     int16_t *pSymbol_old_re,
     337             :     ivas_cell_dim_t *pCell_dims,
     338             :     BSTR_ENC_HANDLE hMetaData,
     339             :     const int16_t any_diff,
     340             :     const int16_t wc_strat_arith )
     341             : {
     342             :     int16_t input_old[IVAS_MAX_INPUT_LEN];
     343             :     int16_t input_new[IVAS_MAX_INPUT_LEN];
     344             :     int16_t input[IVAS_MAX_INPUT_LEN];
     345             :     ivas_cell_dim_t cell_dim[IVAS_MAX_NUM_BANDS], cell_dim_diff[IVAS_MAX_NUM_BANDS];
     346             :     int16_t len, idx, i, j, idx1;
     347             :     int16_t total_len;
     348             :     int16_t arith_result;
     349             : 
     350      759404 :     idx1 = 0;
     351      759404 :     if ( any_diff == 1 )
     352             :     {
     353      254435 :         idx = 0;
     354      254435 :         total_len = 0;
     355     2289915 :         for ( i = 0; i < nB; i++ )
     356             :         {
     357     2035480 :             len = ( pCell_dims[i].dim1 * pCell_dims[i].dim2 );
     358     2035480 :             if ( pDo_diff[i] != 0 )
     359             :             {
     360     4787928 :                 for ( j = 0; j < len; j++ )
     361             :                 {
     362     3261318 :                     input_old[idx] = pSymbol_old_re[total_len + j];
     363     3261318 :                     input_new[idx++] = pSymbol_re[total_len + j];
     364             :                 }
     365     1526610 :                 cell_dim_diff[i].dim1 = pCell_dims[i].dim1;
     366     1526610 :                 cell_dim_diff[i].dim2 = pCell_dims[i].dim2;
     367     1526610 :                 cell_dim[i].dim1 = 0;
     368     1526610 :                 cell_dim[i].dim2 = 0;
     369             :             }
     370             :             else
     371             :             {
     372     1595976 :                 for ( j = 0; j < len; j++ )
     373             :                 {
     374     1087106 :                     input[idx1++] = pSymbol_re[total_len + j];
     375             :                 }
     376      508870 :                 cell_dim_diff[i].dim1 = 0;
     377      508870 :                 cell_dim_diff[i].dim2 = 0;
     378      508870 :                 cell_dim[i].dim1 = pCell_dims[i].dim1;
     379      508870 :                 cell_dim[i].dim2 = pCell_dims[i].dim2;
     380             :             }
     381     2035480 :             total_len += len;
     382             :         }
     383             : 
     384      254435 :         arith_result = arith_encode_cell_array( cell_dim, hMetaData, nB, pArith_re, input, wc_strat_arith );
     385      254435 :         if ( arith_result < 0 )
     386             :         {
     387          37 :             return -1;
     388             :         }
     389             : 
     390      254398 :         arith_result = arith_encode_cell_array_diff( cell_dim_diff, hMetaData, nB, pArith_re_diff, input_old, input_new, wc_strat_arith );
     391      254398 :         if ( arith_result < 0 )
     392             :         {
     393         903 :             return -1;
     394             :         }
     395             :     }
     396             :     else
     397             :     {
     398      504969 :         arith_result = arith_encode_cell_array( pCell_dims, hMetaData, nB, pArith_re, pSymbol_re, wc_strat_arith );
     399      504969 :         if ( arith_result < 0 )
     400             :         {
     401       26478 :             return -1;
     402             :         }
     403             :     }
     404             : 
     405      731986 :     return 0;
     406             : }

Generated by: LCOV version 1.14