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 <assert.h>
34 : #include "ivas_prot_fx.h"
35 : #include "ivas_cnst.h"
36 : #include "ivas_stat_enc.h"
37 : #include "cnst.h"
38 : #include "rom_com.h"
39 : #include <stdint.h>
40 : #include "options.h"
41 : #include "prot_fx.h"
42 : #include "wmc_auto.h"
43 :
44 :
45 : /*
46 : * After finalizing the range encoder, the produced bits are available in the
47 : * rc_st_enc->byte_buffer member array. The bits are packed into bytes, MSB first, as
48 : * byte_buffer[0].bit[7], ..., byte_buffer[0].bit[0], byte_buffer[1].bit[7], ...
49 : * The last byte may contain less than 8 bits. The total bit count is returned
50 : * by the rc_uni_enc_finish function but can also be computed afterwards as
51 : * total_bit_count = (rc_st_enc->byte_count - 1) * 8 + rc_st_enc->last_byte_bit_count
52 : */
53 :
54 : /*-------------------------------------------------------------------*
55 : * Local function prototypes
56 : *-------------------------------------------------------------------*/
57 :
58 : static void rc_uni_enc_shift_fx( RangeUniEncState *rc_st_enc );
59 :
60 :
61 : /*-------------------------------------------------------------------*
62 : * rc_uni_enc_init_fx()
63 : *
64 : * Initalize the range encoder
65 : *-------------------------------------------------------------------*/
66 901194 : void rc_uni_enc_init_fx(
67 : RangeUniEncState *rc_st_enc /* i/o: RC state handle */
68 : )
69 : {
70 901194 : rc_st_enc->rc_low = 0;
71 901194 : rc_st_enc->rc_range = 0xFFFFFFFF;
72 901194 : rc_st_enc->rc_cache = -1;
73 901194 : rc_st_enc->rc_carry = 0;
74 901194 : rc_st_enc->rc_carry_count = 0;
75 :
76 901194 : rc_st_enc->byte_count = 0;
77 901194 : rc_st_enc->last_byte_bit_count = -1;
78 901194 : move32();
79 901194 : move32();
80 901194 : move16();
81 901194 : move16();
82 901194 : move16();
83 901194 : move16();
84 901194 : move16();
85 :
86 901194 : return;
87 : }
88 :
89 : /*-------------------------------------------------------------------*
90 : * rc_uni_enc_encode_fast()
91 : *
92 : * Encode given cumulative frequency and frequency when total frequency is a power of 2
93 : *-------------------------------------------------------------------*/
94 216077650 : void rc_uni_enc_encode_fast_fx(
95 : RangeUniEncState *rc_st_enc, /* i/o: RC state handle */
96 : const UWord16 cum_freq, /* i : Cumulative frequency up to symbol */
97 : const UWord16 sym_freq, /* i : Symbol frequency */
98 : const UWord16 tot_shift /* i : Total frequency as a power of 2 */
99 : )
100 : {
101 : UWord32 r, tmp;
102 :
103 216077650 : r = UL_lshr( rc_st_enc->rc_range, tot_shift );
104 216077650 : tmp = UL_Mpy_32_32( r, (UWord32) cum_freq );
105 :
106 216077650 : rc_st_enc->rc_low = UL_addNsD( rc_st_enc->rc_low, tmp );
107 216077650 : move32();
108 216077650 : if ( LT_64( rc_st_enc->rc_low, tmp ) )
109 : {
110 11353446 : rc_st_enc->rc_carry = 1;
111 11353446 : move16();
112 : }
113 :
114 216077650 : rc_st_enc->rc_range = UL_Mpy_32_32( r, (UWord32) sym_freq );
115 216077650 : move32();
116 :
117 : /* rc_range was shifted right by up to 16, so at most two renormalizations are needed */
118 216077650 : IF( LT_64( rc_st_enc->rc_range, 0x01000000 ) )
119 : {
120 65044470 : rc_st_enc->rc_range = UL_lshl( rc_st_enc->rc_range, 8 );
121 65044470 : move32();
122 65044470 : rc_uni_enc_shift_fx( rc_st_enc );
123 65044470 : IF( LT_64( rc_st_enc->rc_range, 0x01000000 ) )
124 : {
125 72720 : rc_st_enc->rc_range = UL_lshl( rc_st_enc->rc_range, 8 );
126 72720 : move32();
127 72720 : rc_uni_enc_shift_fx( rc_st_enc );
128 : }
129 : }
130 :
131 216077650 : return;
132 : }
133 :
134 :
135 : /*-------------------------------------------------------------------*
136 : * rc_uni_enc_encode_symbol_fastS_fx()
137 : *
138 : * Encode an alphabet symbol when total frequency is a power of 2
139 : *-------------------------------------------------------------------*/
140 215370336 : void rc_uni_enc_encode_symbol_fastS_fx(
141 : RangeUniEncState *rc_st_enc, /* i/o: Encoder state */
142 : const UWord16 symbol, /* i : Symbol to encode */
143 : const UWord16 cum_freq[], /* i : Cumulative frequency up to symbol */
144 : const UWord16 sym_freq[], /* i : Symbol frequency */
145 : const UWord16 tot_shift /* i : Total frequency as a power of 2 */
146 : )
147 : {
148 215370336 : rc_uni_enc_encode_fast_fx( rc_st_enc, cum_freq[symbol], sym_freq[symbol], tot_shift );
149 :
150 215370336 : return;
151 : }
152 :
153 : /*-------------------------------------------------------------------*
154 : * rc_uni_enc_finish_fx()
155 : *
156 : * Finalize the range encoder
157 : *-------------------------------------------------------------------*/
158 : /*! r: Total number of bits produced */
159 890483 : Word16 rc_uni_enc_finish_fx(
160 : RangeUniEncState *rc_st_enc /* i/o: RC state handle */
161 : )
162 : {
163 : Word16 total_bit_count;
164 : UWord32 val, mask;
165 : Word16 bits;
166 :
167 : /* floor(log2(x)) = floor(log2(x >> 24)) + 24, for any x >= 2 ^ 24 */
168 : /* 32 - floor(log2(y)) = norm_ul_float(y) + 1 = norm_l(y >> 24) - 22 */
169 890483 : bits = sub( norm_l( UL_lshr( rc_st_enc->rc_range, 24 ) ), 22 ); /* bits = 32 - floor(log2(rc_range)) */
170 : /* completely equivalent with norm_ul_float(rc_st_enc->rc_range) + 1, but norm_l is faster */
171 :
172 890483 : bits = add( bits, 1 ); /* conservative number of bits, because the decoder only has rc_range available */
173 :
174 :
175 890483 : mask = UL_lshr( 0xFFFFFFFFu, bits );
176 890483 : val = UL_and( UL_addNsD( rc_st_enc->rc_low, mask ), ~mask );
177 :
178 890483 : if ( LT_64( val, rc_st_enc->rc_low ) )
179 : {
180 54742 : rc_st_enc->rc_carry = 1;
181 54742 : move16();
182 : }
183 :
184 890483 : rc_st_enc->rc_low = val;
185 890483 : move32();
186 :
187 1892176 : WHILE( bits > 0 )
188 : {
189 1001693 : rc_uni_enc_shift_fx( rc_st_enc );
190 1001693 : bits = sub( bits, 8 );
191 : }
192 :
193 890483 : bits = add( bits, 8 );
194 :
195 890483 : IF( rc_st_enc->rc_carry_count > 0 )
196 : {
197 : /* rc_carry_count > 0, therefore the last call to rc_uni_enc_shift incremented rc_carry_count */
198 420 : IF( rc_st_enc->rc_cache >= 0 ) /* may actually be always true, but it is difficult to prove formally */
199 : {
200 420 : rc_st_enc->byte_buffer[rc_st_enc->byte_count] = (UWord8) add( rc_st_enc->rc_cache, rc_st_enc->rc_carry );
201 420 : rc_st_enc->byte_count = add( rc_st_enc->byte_count, 1 );
202 420 : move16();
203 420 : move16();
204 : }
205 :
206 421 : WHILE( GT_16( rc_st_enc->rc_carry_count, 1 ) )
207 : {
208 1 : rc_st_enc->byte_buffer[rc_st_enc->byte_count] = (UWord8) add( rc_st_enc->rc_carry, 0xFF );
209 1 : rc_st_enc->byte_count = add( rc_st_enc->byte_count, 1 );
210 1 : rc_st_enc->rc_carry_count = sub( rc_st_enc->rc_carry_count, 1 );
211 1 : move16();
212 1 : move16();
213 1 : move16();
214 : }
215 : /* pack the last 1 to 8 bits into the MSB of the last byte, with zero padding into the LSB */
216 420 : rc_st_enc->byte_buffer[rc_st_enc->byte_count] = (UWord8) L_and( L_deposit_l( add( rc_st_enc->rc_carry, 0xFF ) ), L_shl( 0xFFu, sub( 8, bits ) ) );
217 420 : rc_st_enc->byte_count = add( rc_st_enc->byte_count, 1 );
218 420 : rc_st_enc->last_byte_bit_count = bits;
219 420 : move16();
220 420 : move16();
221 420 : move16();
222 : }
223 : ELSE
224 : {
225 : /* rc_carry_count == 0, therefore the last call to rc_uni_enc_shift wrote into rc_cache */
226 : /* pack the last 1 to 8 bits into the MSB of the last byte, with zero padding into the LSB */
227 890063 : rc_st_enc->byte_buffer[rc_st_enc->byte_count] = (UWord8) L_and( L_deposit_l( add( rc_st_enc->rc_carry, rc_st_enc->rc_cache ) ), L_shl( 0xFFu, sub( 8, bits ) ) );
228 890063 : rc_st_enc->byte_count = add( rc_st_enc->byte_count, 1 );
229 890063 : rc_st_enc->last_byte_bit_count = bits;
230 890063 : move16();
231 890063 : move16();
232 890063 : move16();
233 : }
234 :
235 :
236 890483 : total_bit_count = add( shl( sub( rc_st_enc->byte_count, 1 ), 3 ), rc_st_enc->last_byte_bit_count );
237 :
238 890483 : return total_bit_count;
239 : }
240 :
241 :
242 : /*-------------------------------------------------------------------*
243 : * rc_uni_enc_virtual_finish()
244 : *
245 : * Get the total number of bits that would be produced by finalization
246 : *-------------------------------------------------------------------*/
247 : /*! r: Total number of bits produced */
248 1182531 : Word16 rc_uni_enc_virtual_finish_fx(
249 : RangeUniEncState *rc_st_enc /* i : RC state handle */
250 : )
251 : {
252 :
253 : /*
254 : byte_count bytes have already been written to the byte_buffer array
255 : 1 byte is pending if rc_cache >= 0, consisting of rc_cache or rc_cache + 1
256 : the pending byte bits are computed as 8 - 8 * ((uint16_t) rc_st_enc->rc_cache >> 15)
257 : rc_carry_count bytes are pending, consisting of 0x00 or 0xFF
258 : bits bits will be additionally written during the finalization procedure
259 : bits is computed as norm_l(rc_st_enc->rc_range >> 24) - 21, as in rc_uni_enc_finish
260 : */
261 :
262 : Word16 tmp;
263 1182531 : IF( rc_st_enc->rc_cache > 0 )
264 : {
265 1085767 : tmp = sub( norm_l( UL_lshr( rc_st_enc->rc_range, 24 ) ), 13 );
266 : }
267 : ELSE
268 : {
269 96764 : tmp = sub( norm_l( UL_lshr( rc_st_enc->rc_range, 24 ) ), 13 + 8 );
270 : }
271 1182531 : tmp = add( tmp, shl( add( rc_st_enc->byte_count, rc_st_enc->rc_carry_count ), 3 ) );
272 :
273 : // return ( ( rc_st_enc->byte_count + rc_st_enc->rc_carry_count ) << 3 ) +
274 : // norm_l( rc_st_enc->rc_range >> 24 ) - 13 - 8 * ( (uint16_t) rc_st_enc->rc_cache >> 15 );
275 :
276 1182531 : return tmp;
277 : }
278 :
279 :
280 : /*-------------------------------------------------------------------*
281 : * rc_uni_enc_shift_fx()
282 : *
283 : * Shift a byte out to bitstream (internal function)
284 : *-------------------------------------------------------------------*/
285 66185512 : static void rc_uni_enc_shift_fx(
286 : RangeUniEncState *rc_st_enc /* i/o: RC state handle */
287 : )
288 : {
289 66185512 : test();
290 66185512 : IF( LT_64( rc_st_enc->rc_low, 0xFF000000u ) || rc_st_enc->rc_carry )
291 : {
292 65925286 : IF( rc_st_enc->rc_cache >= 0 )
293 : {
294 65024974 : rc_st_enc->byte_buffer[rc_st_enc->byte_count] = (UWord8) add( rc_st_enc->rc_cache, rc_st_enc->rc_carry );
295 65024974 : rc_st_enc->byte_count = add( rc_st_enc->byte_count, 1 );
296 65024974 : move16();
297 65024974 : move16();
298 : }
299 :
300 66185053 : WHILE( rc_st_enc->rc_carry_count > 0 )
301 : {
302 259767 : rc_st_enc->byte_buffer[rc_st_enc->byte_count] = (UWord8) add( rc_st_enc->rc_carry, 0xFF );
303 259767 : rc_st_enc->byte_count = add( rc_st_enc->byte_count, 1 );
304 259767 : rc_st_enc->rc_carry_count = sub( rc_st_enc->rc_carry_count, 1 );
305 259767 : move16();
306 259767 : move16();
307 259767 : move16();
308 : }
309 :
310 65925286 : rc_st_enc->rc_cache = extract_l( UL_lshr( rc_st_enc->rc_low, 24 ) );
311 65925286 : rc_st_enc->rc_carry = 0;
312 65925286 : move16();
313 65925286 : move16();
314 : }
315 : ELSE
316 : {
317 260226 : rc_st_enc->rc_carry_count = add( rc_st_enc->rc_carry_count, 1 );
318 260226 : move16();
319 : }
320 :
321 66185512 : rc_st_enc->rc_low = UL_lshl( rc_st_enc->rc_low, 8 );
322 66185512 : move32();
323 :
324 66185512 : return;
325 : }
326 :
327 :
328 : /*-------------------------------------------------------------------*
329 : * rc_uni_enc_encode_bits_fx()
330 : *
331 : * Encode up to 16 bits with uniform probability
332 : *-------------------------------------------------------------------*/
333 526743 : void rc_uni_enc_encode_bits_fx(
334 : RangeUniEncState *rc_st_enc, /* i/o: RC state handle */
335 : const UWord16 value, /* i : Value to encode */
336 : const Word16 bits /* i : Number of bits */
337 : )
338 : {
339 : UWord32 tmp;
340 :
341 526743 : rc_st_enc->rc_range = UL_lshr( rc_st_enc->rc_range, bits );
342 526743 : move32();
343 526743 : tmp = UL_Mpy_32_32( rc_st_enc->rc_range, value );
344 :
345 526743 : rc_st_enc->rc_low = UL_addNsD( rc_st_enc->rc_low, tmp );
346 526743 : move32();
347 526743 : if ( LT_64( rc_st_enc->rc_low, tmp ) )
348 : {
349 23652 : rc_st_enc->rc_carry = 1;
350 23652 : move16();
351 : }
352 :
353 : /* rc_range was shifted right by up to 16, so at most two renormalizations are needed */
354 526743 : IF( LT_64( rc_st_enc->rc_range, 0x01000000 ) )
355 : {
356 66629 : rc_st_enc->rc_range = UL_lshl( rc_st_enc->rc_range, 8 );
357 66629 : move32();
358 66629 : rc_uni_enc_shift_fx( rc_st_enc );
359 66629 : IF( LT_64( rc_st_enc->rc_range, 0x01000000 ) )
360 : {
361 0 : rc_st_enc->rc_range = UL_lshl( rc_st_enc->rc_range, 8 );
362 0 : move32();
363 0 : rc_uni_enc_shift_fx( rc_st_enc );
364 : }
365 : }
366 :
367 526743 : return;
368 : }
|