xref: /btstack/3rd-party/lc3-google/src/bits.c (revision 6897da5c53aac5b1f90f41b5b15d0bd43d61dfff)
19a19cd78SMatthias Ringwald /******************************************************************************
29a19cd78SMatthias Ringwald  *
34930cef6SMatthias Ringwald  *  Copyright 2022 Google LLC
49a19cd78SMatthias Ringwald  *
59a19cd78SMatthias Ringwald  *  Licensed under the Apache License, Version 2.0 (the "License");
69a19cd78SMatthias Ringwald  *  you may not use this file except in compliance with the License.
79a19cd78SMatthias Ringwald  *  You may obtain a copy of the License at:
89a19cd78SMatthias Ringwald  *
99a19cd78SMatthias Ringwald  *  http://www.apache.org/licenses/LICENSE-2.0
109a19cd78SMatthias Ringwald  *
119a19cd78SMatthias Ringwald  *  Unless required by applicable law or agreed to in writing, software
129a19cd78SMatthias Ringwald  *  distributed under the License is distributed on an "AS IS" BASIS,
139a19cd78SMatthias Ringwald  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
149a19cd78SMatthias Ringwald  *  See the License for the specific language governing permissions and
159a19cd78SMatthias Ringwald  *  limitations under the License.
169a19cd78SMatthias Ringwald  *
179a19cd78SMatthias Ringwald  ******************************************************************************/
189a19cd78SMatthias Ringwald 
199a19cd78SMatthias Ringwald #include "bits.h"
209a19cd78SMatthias Ringwald #include "common.h"
219a19cd78SMatthias Ringwald 
229a19cd78SMatthias Ringwald 
239a19cd78SMatthias Ringwald /* ----------------------------------------------------------------------------
249a19cd78SMatthias Ringwald  *  Common
259a19cd78SMatthias Ringwald  * -------------------------------------------------------------------------- */
269a19cd78SMatthias Ringwald 
279a19cd78SMatthias Ringwald static inline int ac_get(struct lc3_bits_buffer *);
289a19cd78SMatthias Ringwald static inline void accu_load(struct lc3_bits_accu *, struct lc3_bits_buffer *);
299a19cd78SMatthias Ringwald 
309a19cd78SMatthias Ringwald /**
319a19cd78SMatthias Ringwald  * Arithmetic coder return range bits
329a19cd78SMatthias Ringwald  * ac              Arithmetic coder
339a19cd78SMatthias Ringwald  * return          1 + log2(ac->range)
349a19cd78SMatthias Ringwald  */
ac_get_range_bits(const struct lc3_bits_ac * ac)359a19cd78SMatthias Ringwald static int ac_get_range_bits(const struct lc3_bits_ac *ac)
369a19cd78SMatthias Ringwald {
379a19cd78SMatthias Ringwald     int nbits = 0;
389a19cd78SMatthias Ringwald 
399a19cd78SMatthias Ringwald     for (unsigned r = ac->range; r; r >>= 1, nbits++);
409a19cd78SMatthias Ringwald 
419a19cd78SMatthias Ringwald     return nbits;
429a19cd78SMatthias Ringwald }
439a19cd78SMatthias Ringwald 
449a19cd78SMatthias Ringwald /**
459a19cd78SMatthias Ringwald  * Arithmetic coder return pending bits
469a19cd78SMatthias Ringwald  * ac              Arithmetic coder
479a19cd78SMatthias Ringwald  * return          Pending bits
489a19cd78SMatthias Ringwald  */
ac_get_pending_bits(const struct lc3_bits_ac * ac)499a19cd78SMatthias Ringwald static int ac_get_pending_bits(const struct lc3_bits_ac *ac)
509a19cd78SMatthias Ringwald {
519a19cd78SMatthias Ringwald     return 26 - ac_get_range_bits(ac) +
529a19cd78SMatthias Ringwald         ((ac->cache >= 0) + ac->carry_count) * 8;
539a19cd78SMatthias Ringwald }
549a19cd78SMatthias Ringwald 
559a19cd78SMatthias Ringwald /**
569a19cd78SMatthias Ringwald  * Return number of bits left in the bitstream
579a19cd78SMatthias Ringwald  * bits            Bitstream context
589a19cd78SMatthias Ringwald  * return          >= 0: Number of bits left  < 0: Overflow
599a19cd78SMatthias Ringwald  */
get_bits_left(const struct lc3_bits * bits)609a19cd78SMatthias Ringwald static int get_bits_left(const struct lc3_bits *bits)
619a19cd78SMatthias Ringwald {
629a19cd78SMatthias Ringwald     const struct lc3_bits_buffer *buffer = &bits->buffer;
639a19cd78SMatthias Ringwald     const struct lc3_bits_accu *accu = &bits->accu;
649a19cd78SMatthias Ringwald     const struct lc3_bits_ac *ac = &bits->ac;
659a19cd78SMatthias Ringwald 
669a19cd78SMatthias Ringwald     uintptr_t end = (uintptr_t)buffer->p_bw +
679a19cd78SMatthias Ringwald         (bits->mode == LC3_BITS_MODE_READ ? LC3_ACCU_BITS/8 : 0);
689a19cd78SMatthias Ringwald 
699a19cd78SMatthias Ringwald     uintptr_t start = (uintptr_t)buffer->p_fw -
709a19cd78SMatthias Ringwald         (bits->mode == LC3_BITS_MODE_READ ? LC3_AC_BITS/8 : 0);
719a19cd78SMatthias Ringwald 
729a19cd78SMatthias Ringwald     int n = end > start ? (int)(end - start) : -(int)(start - end);
739a19cd78SMatthias Ringwald 
749a19cd78SMatthias Ringwald     return 8 * n - (accu->n + accu->nover + ac_get_pending_bits(ac));
759a19cd78SMatthias Ringwald }
769a19cd78SMatthias Ringwald 
779a19cd78SMatthias Ringwald /**
789a19cd78SMatthias Ringwald  * Setup bitstream writing
799a19cd78SMatthias Ringwald  */
lc3_setup_bits(struct lc3_bits * bits,enum lc3_bits_mode mode,void * buffer,int len)809a19cd78SMatthias Ringwald void lc3_setup_bits(struct lc3_bits *bits,
819a19cd78SMatthias Ringwald     enum lc3_bits_mode mode, void *buffer, int len)
829a19cd78SMatthias Ringwald {
839a19cd78SMatthias Ringwald     *bits = (struct lc3_bits){
849a19cd78SMatthias Ringwald         .mode = mode,
859a19cd78SMatthias Ringwald         .accu = {
869a19cd78SMatthias Ringwald             .n = mode == LC3_BITS_MODE_READ ? LC3_ACCU_BITS : 0,
879a19cd78SMatthias Ringwald         },
889a19cd78SMatthias Ringwald         .ac = {
899a19cd78SMatthias Ringwald             .range = 0xffffff,
909a19cd78SMatthias Ringwald             .cache = -1
919a19cd78SMatthias Ringwald         },
929a19cd78SMatthias Ringwald         .buffer = {
939a19cd78SMatthias Ringwald             .start = (uint8_t *)buffer, .end  = (uint8_t *)buffer + len,
949a19cd78SMatthias Ringwald             .p_fw  = (uint8_t *)buffer, .p_bw = (uint8_t *)buffer + len,
959a19cd78SMatthias Ringwald         }
969a19cd78SMatthias Ringwald     };
979a19cd78SMatthias Ringwald 
989a19cd78SMatthias Ringwald     if (mode == LC3_BITS_MODE_READ) {
999a19cd78SMatthias Ringwald         struct lc3_bits_ac *ac = &bits->ac;
1009a19cd78SMatthias Ringwald         struct lc3_bits_accu *accu = &bits->accu;
1019a19cd78SMatthias Ringwald         struct lc3_bits_buffer *buffer = &bits->buffer;
1029a19cd78SMatthias Ringwald 
1039a19cd78SMatthias Ringwald         ac->low  = ac_get(buffer) << 16;
1049a19cd78SMatthias Ringwald         ac->low |= ac_get(buffer) <<  8;
1059a19cd78SMatthias Ringwald         ac->low |= ac_get(buffer);
1069a19cd78SMatthias Ringwald 
1079a19cd78SMatthias Ringwald         accu_load(accu, buffer);
1089a19cd78SMatthias Ringwald     }
1099a19cd78SMatthias Ringwald }
1109a19cd78SMatthias Ringwald 
1119a19cd78SMatthias Ringwald /**
1129a19cd78SMatthias Ringwald  * Return number of bits left in the bitstream
1139a19cd78SMatthias Ringwald  */
lc3_get_bits_left(const struct lc3_bits * bits)1149a19cd78SMatthias Ringwald int lc3_get_bits_left(const struct lc3_bits *bits)
1159a19cd78SMatthias Ringwald {
1169a19cd78SMatthias Ringwald     return LC3_MAX(get_bits_left(bits), 0);
1179a19cd78SMatthias Ringwald }
1189a19cd78SMatthias Ringwald 
1199a19cd78SMatthias Ringwald /**
1209a19cd78SMatthias Ringwald  * Return number of bits left in the bitstream
1219a19cd78SMatthias Ringwald  */
lc3_check_bits(const struct lc3_bits * bits)1229a19cd78SMatthias Ringwald int lc3_check_bits(const struct lc3_bits *bits)
1239a19cd78SMatthias Ringwald {
1249a19cd78SMatthias Ringwald     const struct lc3_bits_ac *ac = &bits->ac;
1259a19cd78SMatthias Ringwald 
1269a19cd78SMatthias Ringwald     return -(get_bits_left(bits) < 0 || ac->error);
1279a19cd78SMatthias Ringwald }
1289a19cd78SMatthias Ringwald 
1299a19cd78SMatthias Ringwald 
1309a19cd78SMatthias Ringwald /* ----------------------------------------------------------------------------
1319a19cd78SMatthias Ringwald  *  Writing
1329a19cd78SMatthias Ringwald  * -------------------------------------------------------------------------- */
1339a19cd78SMatthias Ringwald 
1349a19cd78SMatthias Ringwald /**
1359a19cd78SMatthias Ringwald  * Flush the bits accumulator
1369a19cd78SMatthias Ringwald  * accu            Bitstream accumulator
1379a19cd78SMatthias Ringwald  * buffer          Bitstream buffer
1389a19cd78SMatthias Ringwald  */
accu_flush(struct lc3_bits_accu * accu,struct lc3_bits_buffer * buffer)1399a19cd78SMatthias Ringwald static inline void accu_flush(
1409a19cd78SMatthias Ringwald     struct lc3_bits_accu *accu, struct lc3_bits_buffer *buffer)
1419a19cd78SMatthias Ringwald {
1429a19cd78SMatthias Ringwald     int nbytes = LC3_MIN(accu->n >> 3,
1439a19cd78SMatthias Ringwald         LC3_MAX(buffer->p_bw - buffer->p_fw, 0));
1449a19cd78SMatthias Ringwald 
1459a19cd78SMatthias Ringwald     accu->n -= 8 * nbytes;
1469a19cd78SMatthias Ringwald 
1479a19cd78SMatthias Ringwald     for ( ; nbytes; accu->v >>= 8, nbytes--)
1489a19cd78SMatthias Ringwald         *(--buffer->p_bw) = accu->v & 0xff;
1499a19cd78SMatthias Ringwald 
1509a19cd78SMatthias Ringwald     if (accu->n >= 8)
1519a19cd78SMatthias Ringwald         accu->n = 0;
1529a19cd78SMatthias Ringwald }
1539a19cd78SMatthias Ringwald 
1549a19cd78SMatthias Ringwald /**
1559a19cd78SMatthias Ringwald  * Arithmetic coder put byte
1569a19cd78SMatthias Ringwald  * buffer          Bitstream buffer
1579a19cd78SMatthias Ringwald  * byte            Byte to output
1589a19cd78SMatthias Ringwald  */
ac_put(struct lc3_bits_buffer * buffer,int byte)1599a19cd78SMatthias Ringwald static inline void ac_put(struct lc3_bits_buffer *buffer, int byte)
1609a19cd78SMatthias Ringwald {
1619a19cd78SMatthias Ringwald     if (buffer->p_fw < buffer->end)
1629a19cd78SMatthias Ringwald         *(buffer->p_fw++) = byte;
1639a19cd78SMatthias Ringwald }
1649a19cd78SMatthias Ringwald 
1659a19cd78SMatthias Ringwald /**
1669a19cd78SMatthias Ringwald  * Arithmetic coder range shift
1679a19cd78SMatthias Ringwald  * ac              Arithmetic coder
1689a19cd78SMatthias Ringwald  * buffer          Bitstream buffer
1699a19cd78SMatthias Ringwald  */
ac_shift(struct lc3_bits_ac * ac,struct lc3_bits_buffer * buffer)1704930cef6SMatthias Ringwald LC3_HOT static inline void ac_shift(
1719a19cd78SMatthias Ringwald     struct lc3_bits_ac *ac, struct lc3_bits_buffer *buffer)
1729a19cd78SMatthias Ringwald {
1739a19cd78SMatthias Ringwald     if (ac->low < 0xff0000 || ac->carry)
1749a19cd78SMatthias Ringwald     {
1759a19cd78SMatthias Ringwald         if (ac->cache >= 0)
1769a19cd78SMatthias Ringwald             ac_put(buffer, ac->cache + ac->carry);
1779a19cd78SMatthias Ringwald 
1789a19cd78SMatthias Ringwald         for ( ; ac->carry_count > 0; ac->carry_count--)
1799a19cd78SMatthias Ringwald             ac_put(buffer, ac->carry ? 0x00 : 0xff);
1809a19cd78SMatthias Ringwald 
1819a19cd78SMatthias Ringwald          ac->cache = ac->low >> 16;
1829a19cd78SMatthias Ringwald          ac->carry = 0;
1839a19cd78SMatthias Ringwald     }
1849a19cd78SMatthias Ringwald     else
1859a19cd78SMatthias Ringwald          ac->carry_count++;
1869a19cd78SMatthias Ringwald 
1879a19cd78SMatthias Ringwald     ac->low = (ac->low << 8) & 0xffffff;
1889a19cd78SMatthias Ringwald }
1899a19cd78SMatthias Ringwald 
1909a19cd78SMatthias Ringwald /**
1919a19cd78SMatthias Ringwald  * Arithmetic coder termination
1929a19cd78SMatthias Ringwald  * ac              Arithmetic coder
1939a19cd78SMatthias Ringwald  * buffer          Bitstream buffer
1949a19cd78SMatthias Ringwald  * end_val/nbits   End value and count of bits to terminate (1 to 8)
1959a19cd78SMatthias Ringwald  */
ac_terminate(struct lc3_bits_ac * ac,struct lc3_bits_buffer * buffer)1969a19cd78SMatthias Ringwald static void ac_terminate(struct lc3_bits_ac *ac,
1979a19cd78SMatthias Ringwald     struct lc3_bits_buffer *buffer)
1989a19cd78SMatthias Ringwald {
1999a19cd78SMatthias Ringwald     int nbits = 25 - ac_get_range_bits(ac);
2009a19cd78SMatthias Ringwald     unsigned mask = 0xffffff >> nbits;
2019a19cd78SMatthias Ringwald     unsigned val  = ac->low + mask;
2029a19cd78SMatthias Ringwald     unsigned high = ac->low + ac->range;
2039a19cd78SMatthias Ringwald 
2049a19cd78SMatthias Ringwald     bool over_val  = val  >> 24;
2059a19cd78SMatthias Ringwald     bool over_high = high >> 24;
2069a19cd78SMatthias Ringwald 
2079a19cd78SMatthias Ringwald     val  = (val  & 0xffffff) & ~mask;
2089a19cd78SMatthias Ringwald     high = (high & 0xffffff);
2099a19cd78SMatthias Ringwald 
2109a19cd78SMatthias Ringwald     if (over_val == over_high) {
2119a19cd78SMatthias Ringwald 
2129a19cd78SMatthias Ringwald         if (val + mask >= high) {
2139a19cd78SMatthias Ringwald             nbits++;
2149a19cd78SMatthias Ringwald             mask >>= 1;
2159a19cd78SMatthias Ringwald             val = ((ac->low + mask) & 0xffffff) & ~mask;
2169a19cd78SMatthias Ringwald         }
2179a19cd78SMatthias Ringwald 
2189a19cd78SMatthias Ringwald         ac->carry |= val < ac->low;
2199a19cd78SMatthias Ringwald     }
2209a19cd78SMatthias Ringwald 
2219a19cd78SMatthias Ringwald     ac->low = val;
2229a19cd78SMatthias Ringwald 
2239a19cd78SMatthias Ringwald     for (; nbits > 8; nbits -= 8)
2249a19cd78SMatthias Ringwald         ac_shift(ac, buffer);
2259a19cd78SMatthias Ringwald     ac_shift(ac, buffer);
2269a19cd78SMatthias Ringwald 
2279a19cd78SMatthias Ringwald     int end_val = ac->cache >> (8 - nbits);
2289a19cd78SMatthias Ringwald 
2299a19cd78SMatthias Ringwald     if (ac->carry_count) {
2309a19cd78SMatthias Ringwald         ac_put(buffer, ac->cache);
2319a19cd78SMatthias Ringwald         for ( ; ac->carry_count > 1; ac->carry_count--)
2329a19cd78SMatthias Ringwald             ac_put(buffer, 0xff);
2339a19cd78SMatthias Ringwald 
2349a19cd78SMatthias Ringwald         end_val = nbits < 8 ? 0 : 0xff;
2359a19cd78SMatthias Ringwald     }
2369a19cd78SMatthias Ringwald 
2379a19cd78SMatthias Ringwald     if (buffer->p_fw < buffer->end) {
2389a19cd78SMatthias Ringwald         *buffer->p_fw &= 0xff >> nbits;
2399a19cd78SMatthias Ringwald         *buffer->p_fw |= end_val << (8 - nbits);
2409a19cd78SMatthias Ringwald     }
2419a19cd78SMatthias Ringwald }
2429a19cd78SMatthias Ringwald 
2439a19cd78SMatthias Ringwald /**
2449a19cd78SMatthias Ringwald  * Flush and terminate bitstream
2459a19cd78SMatthias Ringwald  */
lc3_flush_bits(struct lc3_bits * bits)2469a19cd78SMatthias Ringwald void lc3_flush_bits(struct lc3_bits *bits)
2479a19cd78SMatthias Ringwald {
2489a19cd78SMatthias Ringwald     struct lc3_bits_ac *ac = &bits->ac;
2499a19cd78SMatthias Ringwald     struct lc3_bits_accu *accu = &bits->accu;
2509a19cd78SMatthias Ringwald     struct lc3_bits_buffer *buffer = &bits->buffer;
2519a19cd78SMatthias Ringwald 
2529a19cd78SMatthias Ringwald     int nleft = buffer->p_bw - buffer->p_fw;
2539a19cd78SMatthias Ringwald     for (int n = 8 * nleft - accu->n; n > 0; n -= 32)
2549a19cd78SMatthias Ringwald         lc3_put_bits(bits, 0, LC3_MIN(n, 32));
2559a19cd78SMatthias Ringwald 
2569a19cd78SMatthias Ringwald     accu_flush(accu, buffer);
2579a19cd78SMatthias Ringwald 
2589a19cd78SMatthias Ringwald     ac_terminate(ac, buffer);
2599a19cd78SMatthias Ringwald }
2609a19cd78SMatthias Ringwald 
2619a19cd78SMatthias Ringwald /**
2629a19cd78SMatthias Ringwald  * Write from 1 to 32 bits,
2639a19cd78SMatthias Ringwald  * exceeding the capacity of the accumulator
2649a19cd78SMatthias Ringwald  */
lc3_put_bits_generic(struct lc3_bits * bits,unsigned v,int n)2654930cef6SMatthias Ringwald LC3_HOT void lc3_put_bits_generic(struct lc3_bits *bits, unsigned v, int n)
2669a19cd78SMatthias Ringwald {
2679a19cd78SMatthias Ringwald     struct lc3_bits_accu *accu = &bits->accu;
2689a19cd78SMatthias Ringwald 
2699a19cd78SMatthias Ringwald     /* --- Fulfill accumulator and flush -- */
2709a19cd78SMatthias Ringwald 
2719a19cd78SMatthias Ringwald     int n1 = LC3_MIN(LC3_ACCU_BITS - accu->n, n);
2729a19cd78SMatthias Ringwald     if (n1) {
2739a19cd78SMatthias Ringwald         accu->v |= v << accu->n;
2749a19cd78SMatthias Ringwald         accu->n = LC3_ACCU_BITS;
2759a19cd78SMatthias Ringwald     }
2769a19cd78SMatthias Ringwald 
2779a19cd78SMatthias Ringwald     accu_flush(accu, &bits->buffer);
2789a19cd78SMatthias Ringwald 
2799a19cd78SMatthias Ringwald     /* --- Accumulate remaining bits -- */
2809a19cd78SMatthias Ringwald 
2819a19cd78SMatthias Ringwald     accu->v = v >> n1;
2829a19cd78SMatthias Ringwald     accu->n = n - n1;
2839a19cd78SMatthias Ringwald }
2849a19cd78SMatthias Ringwald 
2859a19cd78SMatthias Ringwald /**
2869a19cd78SMatthias Ringwald  * Arithmetic coder renormalization
2879a19cd78SMatthias Ringwald  */
lc3_ac_write_renorm(struct lc3_bits * bits)2884930cef6SMatthias Ringwald LC3_HOT void lc3_ac_write_renorm(struct lc3_bits *bits)
2899a19cd78SMatthias Ringwald {
2909a19cd78SMatthias Ringwald     struct lc3_bits_ac *ac = &bits->ac;
2919a19cd78SMatthias Ringwald 
2929a19cd78SMatthias Ringwald     for ( ; ac->range < 0x10000; ac->range <<= 8)
2939a19cd78SMatthias Ringwald         ac_shift(ac, &bits->buffer);
2949a19cd78SMatthias Ringwald }
2959a19cd78SMatthias Ringwald 
2969a19cd78SMatthias Ringwald 
2979a19cd78SMatthias Ringwald /* ----------------------------------------------------------------------------
2989a19cd78SMatthias Ringwald  *  Reading
2999a19cd78SMatthias Ringwald  * -------------------------------------------------------------------------- */
3009a19cd78SMatthias Ringwald 
3019a19cd78SMatthias Ringwald /**
3029a19cd78SMatthias Ringwald  * Arithmetic coder get byte
3039a19cd78SMatthias Ringwald  * buffer          Bitstream buffer
3049a19cd78SMatthias Ringwald  * return          Byte read, 0 on overflow
3059a19cd78SMatthias Ringwald  */
ac_get(struct lc3_bits_buffer * buffer)3069a19cd78SMatthias Ringwald static inline int ac_get(struct lc3_bits_buffer *buffer)
3079a19cd78SMatthias Ringwald {
3089a19cd78SMatthias Ringwald     return buffer->p_fw < buffer->end ? *(buffer->p_fw++) : 0;
3099a19cd78SMatthias Ringwald }
3109a19cd78SMatthias Ringwald 
3119a19cd78SMatthias Ringwald /**
3129a19cd78SMatthias Ringwald  * Load the accumulator
3139a19cd78SMatthias Ringwald  * accu            Bitstream accumulator
3149a19cd78SMatthias Ringwald  * buffer          Bitstream buffer
3159a19cd78SMatthias Ringwald  */
accu_load(struct lc3_bits_accu * accu,struct lc3_bits_buffer * buffer)3169a19cd78SMatthias Ringwald static inline void accu_load(struct lc3_bits_accu *accu,
3179a19cd78SMatthias Ringwald     struct lc3_bits_buffer *buffer)
3189a19cd78SMatthias Ringwald {
3199a19cd78SMatthias Ringwald     int nbytes = LC3_MIN(accu->n >> 3, buffer->p_bw - buffer->start);
3209a19cd78SMatthias Ringwald 
3219a19cd78SMatthias Ringwald     accu->n -= 8 * nbytes;
3229a19cd78SMatthias Ringwald 
3239a19cd78SMatthias Ringwald     for ( ; nbytes; nbytes--) {
3249a19cd78SMatthias Ringwald         accu->v >>= 8;
325*6897da5cSDirk Helbig         accu->v |= (unsigned)*(--buffer->p_bw) << (LC3_ACCU_BITS - 8);
3269a19cd78SMatthias Ringwald     }
3279a19cd78SMatthias Ringwald 
3289a19cd78SMatthias Ringwald     if (accu->n >= 8) {
3299a19cd78SMatthias Ringwald         accu->nover = LC3_MIN(accu->nover + accu->n, LC3_ACCU_BITS);
3309a19cd78SMatthias Ringwald         accu->v >>= accu->n;
3319a19cd78SMatthias Ringwald         accu->n = 0;
3329a19cd78SMatthias Ringwald     }
3339a19cd78SMatthias Ringwald }
3349a19cd78SMatthias Ringwald 
3359a19cd78SMatthias Ringwald /**
3369a19cd78SMatthias Ringwald  * Read from 1 to 32 bits,
3379a19cd78SMatthias Ringwald  * exceeding the capacity of the accumulator
3389a19cd78SMatthias Ringwald  */
lc3_get_bits_generic(struct lc3_bits * bits,int n)3394930cef6SMatthias Ringwald LC3_HOT unsigned lc3_get_bits_generic(struct lc3_bits *bits, int n)
3409a19cd78SMatthias Ringwald {
3419a19cd78SMatthias Ringwald     struct lc3_bits_accu *accu = &bits->accu;
3429a19cd78SMatthias Ringwald     struct lc3_bits_buffer *buffer = &bits->buffer;
3439a19cd78SMatthias Ringwald 
3449a19cd78SMatthias Ringwald     /* --- Fulfill accumulator and read -- */
3459a19cd78SMatthias Ringwald 
3469a19cd78SMatthias Ringwald     accu_load(accu, buffer);
3479a19cd78SMatthias Ringwald 
3489a19cd78SMatthias Ringwald     int n1 = LC3_MIN(LC3_ACCU_BITS - accu->n, n);
3499a19cd78SMatthias Ringwald     unsigned v = (accu->v >> accu->n) & ((1u << n1) - 1);
3509a19cd78SMatthias Ringwald     accu->n += n1;
3519a19cd78SMatthias Ringwald 
3529a19cd78SMatthias Ringwald     /* --- Second round --- */
3539a19cd78SMatthias Ringwald 
3549a19cd78SMatthias Ringwald     int n2 = n - n1;
3559a19cd78SMatthias Ringwald 
3569a19cd78SMatthias Ringwald     if (n2) {
3579a19cd78SMatthias Ringwald         accu_load(accu, buffer);
3589a19cd78SMatthias Ringwald 
3599a19cd78SMatthias Ringwald         v |= ((accu->v >> accu->n) & ((1u << n2) - 1)) << n1;
3609a19cd78SMatthias Ringwald         accu->n += n2;
3619a19cd78SMatthias Ringwald     }
3629a19cd78SMatthias Ringwald 
3639a19cd78SMatthias Ringwald     return v;
3649a19cd78SMatthias Ringwald }
3659a19cd78SMatthias Ringwald 
3669a19cd78SMatthias Ringwald /**
3679a19cd78SMatthias Ringwald  * Arithmetic coder renormalization
3689a19cd78SMatthias Ringwald  */
lc3_ac_read_renorm(struct lc3_bits * bits)3694930cef6SMatthias Ringwald LC3_HOT void lc3_ac_read_renorm(struct lc3_bits *bits)
3709a19cd78SMatthias Ringwald {
3719a19cd78SMatthias Ringwald     struct lc3_bits_ac *ac = &bits->ac;
3729a19cd78SMatthias Ringwald 
3739a19cd78SMatthias Ringwald     for ( ; ac->range < 0x10000; ac->range <<= 8)
3749a19cd78SMatthias Ringwald         ac->low = ((ac->low << 8) | ac_get(&bits->buffer)) & 0xffffff;
3759a19cd78SMatthias Ringwald }
376