LCOV - code coverage report
Current view: top level - lib_enc - range_enc.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 92 95 96.8 %
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             : /*====================================================================================
      34             :     EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0
      35             :   ====================================================================================*/
      36             : 
      37             : #include <stdint.h>
      38             : #include "options.h"
      39             : #ifdef DEBUGGING
      40             : #include "debug.h"
      41             : #endif
      42             : #include "cnst.h"
      43             : #include "rom_com.h"
      44             : #include "prot.h"
      45             : #include "wmc_auto.h"
      46             : 
      47             : /*-------------------------------------------------------------------*
      48             :  * Local function prototypes
      49             :  *-------------------------------------------------------------------*/
      50             : 
      51             : static void rc_enc_shift( BSTR_ENC_HANDLE hBstr, PVQ_ENC_HANDLE hPVQ );
      52             : 
      53             : static void rc_enc_write( BSTR_ENC_HANDLE hBstr, const int16_t byte, const int16_t bits );
      54             : 
      55             : 
      56             : /*-------------------------------------------------------------------*
      57             :  * rc_enc_init()
      58             :  *
      59             :  *  Initalize range coder
      60             :  *-------------------------------------------------------------------*/
      61             : 
      62       31229 : void rc_enc_init(
      63             :     PVQ_ENC_HANDLE hPVQ, /* i/o: PVQ encoder handle     */
      64             :     int16_t tot_bits     /* i  : Total bit budget       */
      65             : )
      66             : {
      67       31229 :     hPVQ->rc_low = 0;
      68       31229 :     hPVQ->rc_range = 0xffffffff;
      69       31229 :     hPVQ->rc_cache = -1;
      70       31229 :     hPVQ->rc_carry = 0;
      71       31229 :     hPVQ->rc_carry_count = 0;
      72       31229 :     hPVQ->rc_num_bits = 0;
      73       31229 :     hPVQ->rc_tot_bits = tot_bits;
      74       31229 :     hPVQ->rc_offset = 0;
      75             : 
      76       31229 :     return;
      77             : }
      78             : 
      79             : /*-------------------------------------------------------------------*
      80             :  * rc_encode()
      81             :  *
      82             :  *  Encode symbol with range coder
      83             :  *-------------------------------------------------------------------*/
      84             : 
      85      331614 : void rc_encode(
      86             :     BSTR_ENC_HANDLE hBstr,   /* i/o: encoder bitstream handle            */
      87             :     PVQ_ENC_HANDLE hPVQ,     /* i/o: PVQ encoder handle                  */
      88             :     const uint32_t cum_freq, /* i  : Cumulative frequency up to symbol   */
      89             :     const uint32_t sym_freq, /* i  : Symbol probability                  */
      90             :     const uint32_t tot       /* i  : Total cumulative frequency          */
      91             : )
      92             : {
      93             :     uint32_t r, tmp;
      94             :     uint32_t inv_tot;
      95             :     int16_t exp;
      96             : 
      97      331614 :     inv_tot = UL_inverse( tot, &exp );
      98      331614 :     tmp = UMult_32_32( hPVQ->rc_range, inv_tot );
      99      331614 :     r = tmp >> ( exp - 32 );
     100      331614 :     tmp = r * cum_freq;
     101             : 
     102      331614 :     hPVQ->rc_low = hPVQ->rc_low + tmp;
     103      331614 :     if ( hPVQ->rc_low < tmp )
     104             :     {
     105       42349 :         hPVQ->rc_carry = 1;
     106             :     }
     107             : 
     108      331614 :     hPVQ->rc_range = r * sym_freq;
     109             : 
     110      599628 :     while ( hPVQ->rc_range < 1 << 24 )
     111             :     {
     112      268014 :         hPVQ->rc_range = hPVQ->rc_range << 8;
     113      268014 :         hPVQ->rc_num_bits += 8;
     114      268014 :         rc_enc_shift( hBstr, hPVQ );
     115             :     }
     116             : 
     117      331614 :     return;
     118             : }
     119             : 
     120             : /*-------------------------------------------------------------------*
     121             :  * rc_enc_finish()
     122             :  *
     123             :  *  Finalize range coder
     124             :  *-------------------------------------------------------------------*/
     125             : 
     126       31229 : void rc_enc_finish(
     127             :     BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle    */
     128             :     PVQ_ENC_HANDLE hPVQ    /* i/o: PVQ encoder handle          */
     129             : )
     130             : {
     131             :     uint32_t val, mask, high;
     132             :     int16_t bits, over1, over2;
     133             : 
     134       31229 :     bits = norm_ul( hPVQ->rc_range ) + 1; /* aligned to BASOP */
     135       31229 :     mask = 0xffffffff >> bits;
     136             : 
     137       31229 :     val = hPVQ->rc_low + mask;
     138       31229 :     high = hPVQ->rc_low + hPVQ->rc_range;
     139             : 
     140       31229 :     over1 = val < hPVQ->rc_low;
     141       31229 :     over2 = high < hPVQ->rc_low;
     142             : 
     143       31229 :     val = val & ~mask;
     144             : 
     145       31229 :     if ( !( over1 ^ over2 ) )
     146             :     {
     147       29592 :         if ( ( val + mask ) >= high )
     148             :         {
     149       11397 :             bits++;
     150       11397 :             mask >>= 1;
     151       11397 :             val = ( hPVQ->rc_low + mask ) & ~mask;
     152             :         }
     153             : 
     154       29592 :         if ( val < hPVQ->rc_low )
     155             :         {
     156        2348 :             hPVQ->rc_carry = 1;
     157             :         }
     158             :     }
     159             : 
     160       31229 :     hPVQ->rc_low = val;
     161             : 
     162       31229 :     if ( bits > hPVQ->rc_tot_bits - hPVQ->rc_num_bits )
     163             :     {
     164           0 :         bits = hPVQ->rc_tot_bits - hPVQ->rc_num_bits;
     165             :     }
     166             : 
     167       31229 :     hPVQ->rc_num_bits += bits;
     168       64160 :     while ( bits > 0 )
     169             :     {
     170       32931 :         rc_enc_shift( hBstr, hPVQ );
     171       32931 :         bits -= 8;
     172             :     }
     173             : 
     174       31229 :     bits += 8;
     175             : 
     176       31229 :     if ( hPVQ->rc_carry_count > 0 )
     177             :     {
     178          16 :         rc_enc_write( hBstr, hPVQ->rc_cache + hPVQ->rc_carry, 8 );
     179             : 
     180          16 :         while ( hPVQ->rc_carry_count > 1 )
     181             :         {
     182           0 :             rc_enc_write( hBstr, ( hPVQ->rc_carry + 0xff ), 8 );
     183           0 :             hPVQ->rc_carry_count--;
     184             :         }
     185          16 :         rc_enc_write( hBstr, ( hPVQ->rc_carry + 0xff ) & ( ( 1 << bits ) - 1 ), bits );
     186             :     }
     187             :     else
     188             :     {
     189       31213 :         rc_enc_write( hBstr, ( hPVQ->rc_cache + hPVQ->rc_carry ) >> ( 8 - bits ), bits );
     190             :     }
     191             : 
     192       31229 :     bits = hPVQ->rc_num_bits;
     193       31699 :     while ( bits < hPVQ->rc_tot_bits - 16 )
     194             :     {
     195         470 :         rc_enc_write( hBstr, 0, 16 );
     196         470 :         bits += 16;
     197             :     }
     198             : 
     199       31229 :     bits = hPVQ->rc_tot_bits - bits;
     200       31229 :     if ( bits > 0 )
     201             :     {
     202       31196 :         rc_enc_write( hBstr, 0, bits );
     203             :     }
     204             : 
     205       31229 :     return;
     206             : }
     207             : 
     208             : /*-------------------------------------------------------------------*
     209             :  * rc_enc_shift()
     210             :  *
     211             :  * Shift a byte out to bitstream
     212             :  *-------------------------------------------------------------------*/
     213             : 
     214      300945 : static void rc_enc_shift(
     215             :     BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle    */
     216             :     PVQ_ENC_HANDLE hPVQ    /* i/o: PVQ encoder handle          */
     217             : )
     218             : {
     219             : 
     220      300945 :     if ( hPVQ->rc_low < ( 0xffUL << 24 ) || hPVQ->rc_carry )
     221             :     {
     222      299730 :         if ( hPVQ->rc_cache >= 0 )
     223             :         {
     224      268501 :             rc_enc_write( hBstr, hPVQ->rc_cache + hPVQ->rc_carry, 8 );
     225             :         }
     226             : 
     227      300929 :         while ( hPVQ->rc_carry_count > 0 )
     228             :         {
     229        1199 :             rc_enc_write( hBstr, ( hPVQ->rc_carry + 0xff ) & 255, 8 );
     230        1199 :             hPVQ->rc_carry_count--;
     231             :         }
     232             : 
     233      299730 :         hPVQ->rc_cache = hPVQ->rc_low >> 24;
     234      299730 :         hPVQ->rc_carry = 0;
     235             :     }
     236             :     else
     237             :     {
     238        1215 :         hPVQ->rc_carry_count++;
     239             :     }
     240             : 
     241      300945 :     hPVQ->rc_low = hPVQ->rc_low << 8;
     242             : 
     243      300945 :     return;
     244             : }
     245             : 
     246             : /*-------------------------------------------------------------------*
     247             :  * rc_enc_bits()
     248             :  *
     249             :  *
     250             :  *-------------------------------------------------------------------*/
     251             : 
     252      525415 : void rc_enc_bits(
     253             :     BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle*/
     254             :     PVQ_ENC_HANDLE hPVQ,   /* i/o: PVQ encoder handle      */
     255             :     const uint32_t value,  /* i  : Value to encode         */
     256             :     const int16_t bits     /* i  : Number of bits used     */
     257             : )
     258             : {
     259             : 
     260      525415 :     if ( rc_get_bits2( hPVQ->rc_num_bits, hPVQ->rc_range ) + bits <= hPVQ->rc_tot_bits )
     261             :     {
     262      525415 :         hPVQ->rc_num_bits += bits;
     263      525415 :         if ( bits > 16 )
     264             :         {
     265       46936 :             push_indice( hBstr, IND_RC_END - hPVQ->rc_offset, (int16_t) ( value >> 16 ), bits - 16 );
     266       46936 :             hPVQ->rc_offset++;
     267             : 
     268       46936 :             push_indice( hBstr, IND_RC_END - hPVQ->rc_offset, (int16_t) ( value & ( ( 1 << 16 ) - 1 ) ), 16 );
     269       46936 :             hPVQ->rc_offset++;
     270             :         }
     271             :         else
     272             :         {
     273      478479 :             push_indice( hBstr, IND_RC_END - hPVQ->rc_offset++, (int16_t) value, bits );
     274             :         }
     275             :     }
     276             :     else
     277             :     {
     278             :     }
     279             : 
     280      525415 :     return;
     281             : }
     282             : 
     283             : /*-------------------------------------------------------------------*
     284             :  * rc_enc_uniform()
     285             :  *
     286             :  * Encode with uniform distribution
     287             :  *-------------------------------------------------------------------*/
     288             : 
     289      299722 : void rc_enc_uniform(
     290             :     BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle    */
     291             :     PVQ_ENC_HANDLE hPVQ,   /* i/o: PVQ encoder handle          */
     292             :     uint32_t value,        /* i  : Value to encode             */
     293             :     uint32_t tot           /* i  : Maximum value               */
     294             : )
     295             : {
     296             :     int16_t n;
     297             : 
     298      299722 :     n = 32 - norm_ul( tot - 1 ); /* aligned to BASOP */
     299             : 
     300      299722 :     if ( n <= 8 )
     301             :     {
     302       74144 :         rc_encode( hBstr, hPVQ, value, 1, tot );
     303             :     }
     304             :     else
     305             :     {
     306      225578 :         n -= 8;
     307      225578 :         rc_encode( hBstr, hPVQ, value >> n, 1, ( tot >> n ) + 1 );
     308      225578 :         rc_enc_bits( hBstr, hPVQ, value & ( ( 1 << n ) - 1 ), n );
     309             :     }
     310             : 
     311      299722 :     return;
     312             : }
     313             : 
     314             : /*-------------------------------------------------------------------*
     315             :  * rc_enc_write()
     316             :  *
     317             :  *  Write a byte to bitstream
     318             :  *-------------------------------------------------------------------*/
     319             : 
     320      332611 : static void rc_enc_write(
     321             :     BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle  */
     322             :     const int16_t byte,    /* i  : Byte to write             */
     323             :     const int16_t bits     /* i  : Number of bits            */
     324             : )
     325             : {
     326      332611 :     push_indice( hBstr, IND_RC_START, byte, bits );
     327             : 
     328      332611 :     return;
     329             : }

Generated by: LCOV version 1.14