xref: /aosp_15_r20/external/mesa3d/src/util/vl_vlc.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /**************************************************************************
2*61046927SAndroid Build Coastguard Worker  *
3*61046927SAndroid Build Coastguard Worker  * Copyright 2011 Christian König.
4*61046927SAndroid Build Coastguard Worker  * All Rights Reserved.
5*61046927SAndroid Build Coastguard Worker  *
6*61046927SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
7*61046927SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the
8*61046927SAndroid Build Coastguard Worker  * "Software"), to deal in the Software without restriction, including
9*61046927SAndroid Build Coastguard Worker  * without limitation the rights to use, copy, modify, merge, publish,
10*61046927SAndroid Build Coastguard Worker  * distribute, sub license, and/or sell copies of the Software, and to
11*61046927SAndroid Build Coastguard Worker  * permit persons to whom the Software is furnished to do so, subject to
12*61046927SAndroid Build Coastguard Worker  * the following conditions:
13*61046927SAndroid Build Coastguard Worker  *
14*61046927SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the
15*61046927SAndroid Build Coastguard Worker  * next paragraph) shall be included in all copies or substantial portions
16*61046927SAndroid Build Coastguard Worker  * of the Software.
17*61046927SAndroid Build Coastguard Worker  *
18*61046927SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19*61046927SAndroid Build Coastguard Worker  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20*61046927SAndroid Build Coastguard Worker  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21*61046927SAndroid Build Coastguard Worker  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22*61046927SAndroid Build Coastguard Worker  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23*61046927SAndroid Build Coastguard Worker  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24*61046927SAndroid Build Coastguard Worker  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25*61046927SAndroid Build Coastguard Worker  *
26*61046927SAndroid Build Coastguard Worker  **************************************************************************/
27*61046927SAndroid Build Coastguard Worker 
28*61046927SAndroid Build Coastguard Worker /*
29*61046927SAndroid Build Coastguard Worker  * Functions for fast bitwise access to multiple probably unaligned input buffers
30*61046927SAndroid Build Coastguard Worker  */
31*61046927SAndroid Build Coastguard Worker 
32*61046927SAndroid Build Coastguard Worker #ifndef vl_vlc_h
33*61046927SAndroid Build Coastguard Worker #define vl_vlc_h
34*61046927SAndroid Build Coastguard Worker 
35*61046927SAndroid Build Coastguard Worker #include "util/u_math.h"
36*61046927SAndroid Build Coastguard Worker 
37*61046927SAndroid Build Coastguard Worker struct vl_vlc
38*61046927SAndroid Build Coastguard Worker {
39*61046927SAndroid Build Coastguard Worker    uint64_t buffer;
40*61046927SAndroid Build Coastguard Worker    signed invalid_bits;
41*61046927SAndroid Build Coastguard Worker    const uint8_t *data;
42*61046927SAndroid Build Coastguard Worker    const uint8_t *end;
43*61046927SAndroid Build Coastguard Worker 
44*61046927SAndroid Build Coastguard Worker    const void *const *inputs;
45*61046927SAndroid Build Coastguard Worker    const unsigned    *sizes;
46*61046927SAndroid Build Coastguard Worker    unsigned          bytes_left;
47*61046927SAndroid Build Coastguard Worker };
48*61046927SAndroid Build Coastguard Worker 
49*61046927SAndroid Build Coastguard Worker struct vl_vlc_entry
50*61046927SAndroid Build Coastguard Worker {
51*61046927SAndroid Build Coastguard Worker    int8_t length;
52*61046927SAndroid Build Coastguard Worker    int8_t value;
53*61046927SAndroid Build Coastguard Worker };
54*61046927SAndroid Build Coastguard Worker 
55*61046927SAndroid Build Coastguard Worker struct vl_vlc_compressed
56*61046927SAndroid Build Coastguard Worker {
57*61046927SAndroid Build Coastguard Worker    uint16_t bitcode;
58*61046927SAndroid Build Coastguard Worker    struct vl_vlc_entry entry;
59*61046927SAndroid Build Coastguard Worker };
60*61046927SAndroid Build Coastguard Worker 
61*61046927SAndroid Build Coastguard Worker /**
62*61046927SAndroid Build Coastguard Worker  * initalize and decompress a lookup table
63*61046927SAndroid Build Coastguard Worker  */
64*61046927SAndroid Build Coastguard Worker static inline void
vl_vlc_init_table(struct vl_vlc_entry * dst,unsigned dst_size,const struct vl_vlc_compressed * src,unsigned src_size)65*61046927SAndroid Build Coastguard Worker vl_vlc_init_table(struct vl_vlc_entry *dst, unsigned dst_size, const struct vl_vlc_compressed *src, unsigned src_size)
66*61046927SAndroid Build Coastguard Worker {
67*61046927SAndroid Build Coastguard Worker    unsigned i, bits = util_logbase2(dst_size);
68*61046927SAndroid Build Coastguard Worker 
69*61046927SAndroid Build Coastguard Worker    assert(dst && dst_size);
70*61046927SAndroid Build Coastguard Worker    assert(src && src_size);
71*61046927SAndroid Build Coastguard Worker 
72*61046927SAndroid Build Coastguard Worker    for (i=0;i<dst_size;++i) {
73*61046927SAndroid Build Coastguard Worker       dst[i].length = 0;
74*61046927SAndroid Build Coastguard Worker       dst[i].value = 0;
75*61046927SAndroid Build Coastguard Worker    }
76*61046927SAndroid Build Coastguard Worker 
77*61046927SAndroid Build Coastguard Worker    for(; src_size > 0; --src_size, ++src) {
78*61046927SAndroid Build Coastguard Worker       for(i = 0; i < (1u << (bits - src->entry.length)); ++i)
79*61046927SAndroid Build Coastguard Worker          dst[src->bitcode >> (16 - bits) | i] = src->entry;
80*61046927SAndroid Build Coastguard Worker    }
81*61046927SAndroid Build Coastguard Worker }
82*61046927SAndroid Build Coastguard Worker 
83*61046927SAndroid Build Coastguard Worker /**
84*61046927SAndroid Build Coastguard Worker  * switch over to next input buffer
85*61046927SAndroid Build Coastguard Worker  */
86*61046927SAndroid Build Coastguard Worker static inline void
vl_vlc_next_input(struct vl_vlc * vlc)87*61046927SAndroid Build Coastguard Worker vl_vlc_next_input(struct vl_vlc *vlc)
88*61046927SAndroid Build Coastguard Worker {
89*61046927SAndroid Build Coastguard Worker    unsigned len = vlc->sizes[0];
90*61046927SAndroid Build Coastguard Worker 
91*61046927SAndroid Build Coastguard Worker    assert(vlc);
92*61046927SAndroid Build Coastguard Worker    assert(vlc->bytes_left);
93*61046927SAndroid Build Coastguard Worker 
94*61046927SAndroid Build Coastguard Worker    if (len < vlc->bytes_left)
95*61046927SAndroid Build Coastguard Worker       vlc->bytes_left -= len;
96*61046927SAndroid Build Coastguard Worker    else {
97*61046927SAndroid Build Coastguard Worker       len = vlc->bytes_left;
98*61046927SAndroid Build Coastguard Worker       vlc->bytes_left = 0;
99*61046927SAndroid Build Coastguard Worker    }
100*61046927SAndroid Build Coastguard Worker 
101*61046927SAndroid Build Coastguard Worker    vlc->data = (const uint8_t *) vlc->inputs[0];
102*61046927SAndroid Build Coastguard Worker    vlc->end = vlc->data + len;
103*61046927SAndroid Build Coastguard Worker 
104*61046927SAndroid Build Coastguard Worker    ++vlc->inputs;
105*61046927SAndroid Build Coastguard Worker    ++vlc->sizes;
106*61046927SAndroid Build Coastguard Worker }
107*61046927SAndroid Build Coastguard Worker 
108*61046927SAndroid Build Coastguard Worker /**
109*61046927SAndroid Build Coastguard Worker  * align the data pointer to the next dword
110*61046927SAndroid Build Coastguard Worker  */
111*61046927SAndroid Build Coastguard Worker static inline void
vl_vlc_align_data_ptr(struct vl_vlc * vlc)112*61046927SAndroid Build Coastguard Worker vl_vlc_align_data_ptr(struct vl_vlc *vlc)
113*61046927SAndroid Build Coastguard Worker {
114*61046927SAndroid Build Coastguard Worker    /* align the data pointer */
115*61046927SAndroid Build Coastguard Worker    while (vlc->data != vlc->end && ((uintptr_t)vlc->data) & 3) {
116*61046927SAndroid Build Coastguard Worker       vlc->buffer |= (uint64_t)*vlc->data << (24 + vlc->invalid_bits);
117*61046927SAndroid Build Coastguard Worker       ++vlc->data;
118*61046927SAndroid Build Coastguard Worker       vlc->invalid_bits -= 8;
119*61046927SAndroid Build Coastguard Worker    }
120*61046927SAndroid Build Coastguard Worker }
121*61046927SAndroid Build Coastguard Worker 
122*61046927SAndroid Build Coastguard Worker /**
123*61046927SAndroid Build Coastguard Worker  * fill the bit buffer, so that at least 32 bits are valid
124*61046927SAndroid Build Coastguard Worker  */
125*61046927SAndroid Build Coastguard Worker static inline void
vl_vlc_fillbits(struct vl_vlc * vlc)126*61046927SAndroid Build Coastguard Worker vl_vlc_fillbits(struct vl_vlc *vlc)
127*61046927SAndroid Build Coastguard Worker {
128*61046927SAndroid Build Coastguard Worker    assert(vlc);
129*61046927SAndroid Build Coastguard Worker 
130*61046927SAndroid Build Coastguard Worker    /* as long as the buffer needs to be filled */
131*61046927SAndroid Build Coastguard Worker    while (vlc->invalid_bits > 0) {
132*61046927SAndroid Build Coastguard Worker       unsigned bytes_left = vlc->end - vlc->data;
133*61046927SAndroid Build Coastguard Worker 
134*61046927SAndroid Build Coastguard Worker       /* if this input is depleted */
135*61046927SAndroid Build Coastguard Worker       if (bytes_left == 0) {
136*61046927SAndroid Build Coastguard Worker 
137*61046927SAndroid Build Coastguard Worker          if (vlc->bytes_left) {
138*61046927SAndroid Build Coastguard Worker             /* go on to next input */
139*61046927SAndroid Build Coastguard Worker             vl_vlc_next_input(vlc);
140*61046927SAndroid Build Coastguard Worker             vl_vlc_align_data_ptr(vlc);
141*61046927SAndroid Build Coastguard Worker          } else
142*61046927SAndroid Build Coastguard Worker             /* or give up since we don't have anymore inputs */
143*61046927SAndroid Build Coastguard Worker             return;
144*61046927SAndroid Build Coastguard Worker 
145*61046927SAndroid Build Coastguard Worker       } else if (bytes_left >= 4) {
146*61046927SAndroid Build Coastguard Worker 
147*61046927SAndroid Build Coastguard Worker          /* enough bytes in buffer, read in a whole dword */
148*61046927SAndroid Build Coastguard Worker          uint64_t value = *(const uint32_t*)vlc->data;
149*61046927SAndroid Build Coastguard Worker 
150*61046927SAndroid Build Coastguard Worker #if !UTIL_ARCH_BIG_ENDIAN
151*61046927SAndroid Build Coastguard Worker          value = util_bswap32(value);
152*61046927SAndroid Build Coastguard Worker #endif
153*61046927SAndroid Build Coastguard Worker 
154*61046927SAndroid Build Coastguard Worker          vlc->buffer |= value << vlc->invalid_bits;
155*61046927SAndroid Build Coastguard Worker          vlc->data += 4;
156*61046927SAndroid Build Coastguard Worker          vlc->invalid_bits -= 32;
157*61046927SAndroid Build Coastguard Worker 
158*61046927SAndroid Build Coastguard Worker          /* buffer is now definitely filled up avoid the loop test */
159*61046927SAndroid Build Coastguard Worker          break;
160*61046927SAndroid Build Coastguard Worker 
161*61046927SAndroid Build Coastguard Worker       } else while (vlc->data < vlc->end) {
162*61046927SAndroid Build Coastguard Worker 
163*61046927SAndroid Build Coastguard Worker          /* not enough bytes left in buffer, read single bytes */
164*61046927SAndroid Build Coastguard Worker          vlc->buffer |= (uint64_t)*vlc->data << (24 + vlc->invalid_bits);
165*61046927SAndroid Build Coastguard Worker          ++vlc->data;
166*61046927SAndroid Build Coastguard Worker          vlc->invalid_bits -= 8;
167*61046927SAndroid Build Coastguard Worker       }
168*61046927SAndroid Build Coastguard Worker    }
169*61046927SAndroid Build Coastguard Worker }
170*61046927SAndroid Build Coastguard Worker 
171*61046927SAndroid Build Coastguard Worker /**
172*61046927SAndroid Build Coastguard Worker  * initialize vlc structure and start reading from first input buffer
173*61046927SAndroid Build Coastguard Worker  */
174*61046927SAndroid Build Coastguard Worker static inline void
vl_vlc_init(struct vl_vlc * vlc,unsigned num_inputs,const void * const * inputs,const unsigned * sizes)175*61046927SAndroid Build Coastguard Worker vl_vlc_init(struct vl_vlc *vlc, unsigned num_inputs,
176*61046927SAndroid Build Coastguard Worker             const void *const *inputs, const unsigned *sizes)
177*61046927SAndroid Build Coastguard Worker {
178*61046927SAndroid Build Coastguard Worker    unsigned i;
179*61046927SAndroid Build Coastguard Worker 
180*61046927SAndroid Build Coastguard Worker    assert(vlc);
181*61046927SAndroid Build Coastguard Worker    assert(num_inputs);
182*61046927SAndroid Build Coastguard Worker 
183*61046927SAndroid Build Coastguard Worker    vlc->buffer = 0;
184*61046927SAndroid Build Coastguard Worker    vlc->invalid_bits = 32;
185*61046927SAndroid Build Coastguard Worker    vlc->inputs = inputs;
186*61046927SAndroid Build Coastguard Worker    vlc->sizes = sizes;
187*61046927SAndroid Build Coastguard Worker    vlc->bytes_left = 0;
188*61046927SAndroid Build Coastguard Worker    vlc->data = NULL;
189*61046927SAndroid Build Coastguard Worker    vlc->end = NULL;
190*61046927SAndroid Build Coastguard Worker 
191*61046927SAndroid Build Coastguard Worker    for (i = 0; i < num_inputs; ++i)
192*61046927SAndroid Build Coastguard Worker       vlc->bytes_left += sizes[i];
193*61046927SAndroid Build Coastguard Worker 
194*61046927SAndroid Build Coastguard Worker    if (vlc->bytes_left) {
195*61046927SAndroid Build Coastguard Worker       vl_vlc_next_input(vlc);
196*61046927SAndroid Build Coastguard Worker       vl_vlc_align_data_ptr(vlc);
197*61046927SAndroid Build Coastguard Worker       vl_vlc_fillbits(vlc);
198*61046927SAndroid Build Coastguard Worker    }
199*61046927SAndroid Build Coastguard Worker }
200*61046927SAndroid Build Coastguard Worker 
201*61046927SAndroid Build Coastguard Worker /**
202*61046927SAndroid Build Coastguard Worker  * number of bits still valid in bit buffer
203*61046927SAndroid Build Coastguard Worker  */
204*61046927SAndroid Build Coastguard Worker static inline unsigned
vl_vlc_valid_bits(struct vl_vlc * vlc)205*61046927SAndroid Build Coastguard Worker vl_vlc_valid_bits(struct vl_vlc *vlc)
206*61046927SAndroid Build Coastguard Worker {
207*61046927SAndroid Build Coastguard Worker    return 32 - vlc->invalid_bits;
208*61046927SAndroid Build Coastguard Worker }
209*61046927SAndroid Build Coastguard Worker 
210*61046927SAndroid Build Coastguard Worker /**
211*61046927SAndroid Build Coastguard Worker  * number of bits left over all inbut buffers
212*61046927SAndroid Build Coastguard Worker  */
213*61046927SAndroid Build Coastguard Worker static inline unsigned
vl_vlc_bits_left(struct vl_vlc * vlc)214*61046927SAndroid Build Coastguard Worker vl_vlc_bits_left(struct vl_vlc *vlc)
215*61046927SAndroid Build Coastguard Worker {
216*61046927SAndroid Build Coastguard Worker    signed bytes_left = vlc->end - vlc->data;
217*61046927SAndroid Build Coastguard Worker    bytes_left += vlc->bytes_left;
218*61046927SAndroid Build Coastguard Worker    return bytes_left * 8 + vl_vlc_valid_bits(vlc);
219*61046927SAndroid Build Coastguard Worker }
220*61046927SAndroid Build Coastguard Worker 
221*61046927SAndroid Build Coastguard Worker /**
222*61046927SAndroid Build Coastguard Worker  * get num_bits from bit buffer without removing them
223*61046927SAndroid Build Coastguard Worker  */
224*61046927SAndroid Build Coastguard Worker static inline unsigned
vl_vlc_peekbits(struct vl_vlc * vlc,unsigned num_bits)225*61046927SAndroid Build Coastguard Worker vl_vlc_peekbits(struct vl_vlc *vlc, unsigned num_bits)
226*61046927SAndroid Build Coastguard Worker {
227*61046927SAndroid Build Coastguard Worker    assert(vl_vlc_valid_bits(vlc) >= num_bits || vlc->data >= vlc->end);
228*61046927SAndroid Build Coastguard Worker    return vlc->buffer >> (64 - num_bits);
229*61046927SAndroid Build Coastguard Worker }
230*61046927SAndroid Build Coastguard Worker 
231*61046927SAndroid Build Coastguard Worker /**
232*61046927SAndroid Build Coastguard Worker  * remove num_bits from bit buffer
233*61046927SAndroid Build Coastguard Worker  */
234*61046927SAndroid Build Coastguard Worker static inline void
vl_vlc_eatbits(struct vl_vlc * vlc,unsigned num_bits)235*61046927SAndroid Build Coastguard Worker vl_vlc_eatbits(struct vl_vlc *vlc, unsigned num_bits)
236*61046927SAndroid Build Coastguard Worker {
237*61046927SAndroid Build Coastguard Worker    assert(vl_vlc_valid_bits(vlc) >= num_bits);
238*61046927SAndroid Build Coastguard Worker 
239*61046927SAndroid Build Coastguard Worker    vlc->buffer <<= num_bits;
240*61046927SAndroid Build Coastguard Worker    vlc->invalid_bits += num_bits;
241*61046927SAndroid Build Coastguard Worker }
242*61046927SAndroid Build Coastguard Worker 
243*61046927SAndroid Build Coastguard Worker /**
244*61046927SAndroid Build Coastguard Worker  * get num_bits from bit buffer with removing them
245*61046927SAndroid Build Coastguard Worker  */
246*61046927SAndroid Build Coastguard Worker static inline unsigned
vl_vlc_get_uimsbf(struct vl_vlc * vlc,unsigned num_bits)247*61046927SAndroid Build Coastguard Worker vl_vlc_get_uimsbf(struct vl_vlc *vlc, unsigned num_bits)
248*61046927SAndroid Build Coastguard Worker {
249*61046927SAndroid Build Coastguard Worker    unsigned value;
250*61046927SAndroid Build Coastguard Worker 
251*61046927SAndroid Build Coastguard Worker    assert(vl_vlc_valid_bits(vlc) >= num_bits);
252*61046927SAndroid Build Coastguard Worker 
253*61046927SAndroid Build Coastguard Worker    value = vlc->buffer >> (64 - num_bits);
254*61046927SAndroid Build Coastguard Worker    vl_vlc_eatbits(vlc, num_bits);
255*61046927SAndroid Build Coastguard Worker 
256*61046927SAndroid Build Coastguard Worker    return value;
257*61046927SAndroid Build Coastguard Worker }
258*61046927SAndroid Build Coastguard Worker 
259*61046927SAndroid Build Coastguard Worker /**
260*61046927SAndroid Build Coastguard Worker  * treat num_bits as signed value and remove them from bit buffer
261*61046927SAndroid Build Coastguard Worker  */
262*61046927SAndroid Build Coastguard Worker static inline signed
vl_vlc_get_simsbf(struct vl_vlc * vlc,unsigned num_bits)263*61046927SAndroid Build Coastguard Worker vl_vlc_get_simsbf(struct vl_vlc *vlc, unsigned num_bits)
264*61046927SAndroid Build Coastguard Worker {
265*61046927SAndroid Build Coastguard Worker    signed value;
266*61046927SAndroid Build Coastguard Worker 
267*61046927SAndroid Build Coastguard Worker    assert(vl_vlc_valid_bits(vlc) >= num_bits);
268*61046927SAndroid Build Coastguard Worker 
269*61046927SAndroid Build Coastguard Worker    value = ((int64_t)vlc->buffer) >> (64 - num_bits);
270*61046927SAndroid Build Coastguard Worker    vl_vlc_eatbits(vlc, num_bits);
271*61046927SAndroid Build Coastguard Worker 
272*61046927SAndroid Build Coastguard Worker    return value;
273*61046927SAndroid Build Coastguard Worker }
274*61046927SAndroid Build Coastguard Worker 
275*61046927SAndroid Build Coastguard Worker /**
276*61046927SAndroid Build Coastguard Worker  * lookup a value and length in a decompressed table
277*61046927SAndroid Build Coastguard Worker  */
278*61046927SAndroid Build Coastguard Worker static inline int8_t
vl_vlc_get_vlclbf(struct vl_vlc * vlc,const struct vl_vlc_entry * tbl,unsigned num_bits)279*61046927SAndroid Build Coastguard Worker vl_vlc_get_vlclbf(struct vl_vlc *vlc, const struct vl_vlc_entry *tbl, unsigned num_bits)
280*61046927SAndroid Build Coastguard Worker {
281*61046927SAndroid Build Coastguard Worker    tbl += vl_vlc_peekbits(vlc, num_bits);
282*61046927SAndroid Build Coastguard Worker    vl_vlc_eatbits(vlc, tbl->length);
283*61046927SAndroid Build Coastguard Worker    return tbl->value;
284*61046927SAndroid Build Coastguard Worker }
285*61046927SAndroid Build Coastguard Worker 
286*61046927SAndroid Build Coastguard Worker /**
287*61046927SAndroid Build Coastguard Worker  * fast forward search for a specific byte value
288*61046927SAndroid Build Coastguard Worker  */
289*61046927SAndroid Build Coastguard Worker static inline bool
vl_vlc_search_byte(struct vl_vlc * vlc,unsigned num_bits,uint8_t value)290*61046927SAndroid Build Coastguard Worker vl_vlc_search_byte(struct vl_vlc *vlc, unsigned num_bits, uint8_t value)
291*61046927SAndroid Build Coastguard Worker {
292*61046927SAndroid Build Coastguard Worker    /* make sure we are on a byte boundary */
293*61046927SAndroid Build Coastguard Worker    assert((vl_vlc_valid_bits(vlc) % 8) == 0);
294*61046927SAndroid Build Coastguard Worker    assert(num_bits == ~0u || (num_bits % 8) == 0);
295*61046927SAndroid Build Coastguard Worker 
296*61046927SAndroid Build Coastguard Worker    /* deplete the bit buffer */
297*61046927SAndroid Build Coastguard Worker    while (vl_vlc_valid_bits(vlc) > 0) {
298*61046927SAndroid Build Coastguard Worker 
299*61046927SAndroid Build Coastguard Worker       if (vl_vlc_peekbits(vlc, 8) == value) {
300*61046927SAndroid Build Coastguard Worker          vl_vlc_fillbits(vlc);
301*61046927SAndroid Build Coastguard Worker          return true;
302*61046927SAndroid Build Coastguard Worker       }
303*61046927SAndroid Build Coastguard Worker 
304*61046927SAndroid Build Coastguard Worker       vl_vlc_eatbits(vlc, 8);
305*61046927SAndroid Build Coastguard Worker 
306*61046927SAndroid Build Coastguard Worker       if (num_bits != ~0u) {
307*61046927SAndroid Build Coastguard Worker          num_bits -= 8;
308*61046927SAndroid Build Coastguard Worker          if (num_bits == 0)
309*61046927SAndroid Build Coastguard Worker             return false;
310*61046927SAndroid Build Coastguard Worker       }
311*61046927SAndroid Build Coastguard Worker    }
312*61046927SAndroid Build Coastguard Worker 
313*61046927SAndroid Build Coastguard Worker    /* deplete the byte buffers */
314*61046927SAndroid Build Coastguard Worker    while (1) {
315*61046927SAndroid Build Coastguard Worker 
316*61046927SAndroid Build Coastguard Worker       /* if this input is depleted */
317*61046927SAndroid Build Coastguard Worker       if (vlc->data == vlc->end) {
318*61046927SAndroid Build Coastguard Worker          if (vlc->bytes_left)
319*61046927SAndroid Build Coastguard Worker             /* go on to next input */
320*61046927SAndroid Build Coastguard Worker             vl_vlc_next_input(vlc);
321*61046927SAndroid Build Coastguard Worker          else
322*61046927SAndroid Build Coastguard Worker             /* or give up since we don't have anymore inputs */
323*61046927SAndroid Build Coastguard Worker             return false;
324*61046927SAndroid Build Coastguard Worker       }
325*61046927SAndroid Build Coastguard Worker 
326*61046927SAndroid Build Coastguard Worker       if (*vlc->data == value) {
327*61046927SAndroid Build Coastguard Worker          vl_vlc_align_data_ptr(vlc);
328*61046927SAndroid Build Coastguard Worker          vl_vlc_fillbits(vlc);
329*61046927SAndroid Build Coastguard Worker          return true;
330*61046927SAndroid Build Coastguard Worker       }
331*61046927SAndroid Build Coastguard Worker 
332*61046927SAndroid Build Coastguard Worker       ++vlc->data;
333*61046927SAndroid Build Coastguard Worker       if (num_bits != ~0u) {
334*61046927SAndroid Build Coastguard Worker          num_bits -= 8;
335*61046927SAndroid Build Coastguard Worker          if (num_bits == 0) {
336*61046927SAndroid Build Coastguard Worker             vl_vlc_align_data_ptr(vlc);
337*61046927SAndroid Build Coastguard Worker             return false;
338*61046927SAndroid Build Coastguard Worker          }
339*61046927SAndroid Build Coastguard Worker       }
340*61046927SAndroid Build Coastguard Worker    }
341*61046927SAndroid Build Coastguard Worker }
342*61046927SAndroid Build Coastguard Worker 
343*61046927SAndroid Build Coastguard Worker /**
344*61046927SAndroid Build Coastguard Worker  * remove num_bits bits starting at pos from the bitbuffer
345*61046927SAndroid Build Coastguard Worker  */
346*61046927SAndroid Build Coastguard Worker static inline void
vl_vlc_removebits(struct vl_vlc * vlc,unsigned pos,unsigned num_bits)347*61046927SAndroid Build Coastguard Worker vl_vlc_removebits(struct vl_vlc *vlc, unsigned pos, unsigned num_bits)
348*61046927SAndroid Build Coastguard Worker {
349*61046927SAndroid Build Coastguard Worker #if defined(_MSC_VER)
350*61046927SAndroid Build Coastguard Worker    /* MSVC Compiler defines unsigned long as 4 bytes so use explicit 64 bits mask */
351*61046927SAndroid Build Coastguard Worker    uint64_t lo = (vlc->buffer & (UINT64_MAX >> (pos + num_bits))) << num_bits;
352*61046927SAndroid Build Coastguard Worker    uint64_t hi = (vlc->buffer & (UINT64_MAX << (64 - pos)));
353*61046927SAndroid Build Coastguard Worker #else
354*61046927SAndroid Build Coastguard Worker    uint64_t lo = (vlc->buffer & (~0UL >> (pos + num_bits))) << num_bits;
355*61046927SAndroid Build Coastguard Worker    uint64_t hi = (vlc->buffer & (~0UL << (64 - pos)));
356*61046927SAndroid Build Coastguard Worker #endif
357*61046927SAndroid Build Coastguard Worker    vlc->buffer = lo | hi;
358*61046927SAndroid Build Coastguard Worker    vlc->invalid_bits += num_bits;
359*61046927SAndroid Build Coastguard Worker }
360*61046927SAndroid Build Coastguard Worker 
361*61046927SAndroid Build Coastguard Worker /**
362*61046927SAndroid Build Coastguard Worker  * limit the number of bits left for fetching
363*61046927SAndroid Build Coastguard Worker  */
364*61046927SAndroid Build Coastguard Worker static inline void
vl_vlc_limit(struct vl_vlc * vlc,unsigned bits_left)365*61046927SAndroid Build Coastguard Worker vl_vlc_limit(struct vl_vlc *vlc, unsigned bits_left)
366*61046927SAndroid Build Coastguard Worker {
367*61046927SAndroid Build Coastguard Worker    assert(bits_left <= vl_vlc_bits_left(vlc));
368*61046927SAndroid Build Coastguard Worker 
369*61046927SAndroid Build Coastguard Worker    vl_vlc_fillbits(vlc);
370*61046927SAndroid Build Coastguard Worker    if (bits_left < vl_vlc_valid_bits(vlc)) {
371*61046927SAndroid Build Coastguard Worker       vlc->invalid_bits = 32 - bits_left;
372*61046927SAndroid Build Coastguard Worker       vlc->buffer &= ~0L << (vlc->invalid_bits + 32);
373*61046927SAndroid Build Coastguard Worker       vlc->end = vlc->data;
374*61046927SAndroid Build Coastguard Worker       vlc->bytes_left = 0;
375*61046927SAndroid Build Coastguard Worker    } else {
376*61046927SAndroid Build Coastguard Worker       assert((bits_left - vl_vlc_valid_bits(vlc)) % 8 == 0);
377*61046927SAndroid Build Coastguard Worker       vlc->bytes_left = (bits_left - vl_vlc_valid_bits(vlc)) / 8;
378*61046927SAndroid Build Coastguard Worker       if (vlc->bytes_left < (vlc->end - vlc->data)) {
379*61046927SAndroid Build Coastguard Worker          vlc->end = vlc->data + vlc->bytes_left;
380*61046927SAndroid Build Coastguard Worker          vlc->bytes_left = 0;
381*61046927SAndroid Build Coastguard Worker       } else
382*61046927SAndroid Build Coastguard Worker          vlc->bytes_left -= vlc->end - vlc->data;
383*61046927SAndroid Build Coastguard Worker    }
384*61046927SAndroid Build Coastguard Worker }
385*61046927SAndroid Build Coastguard Worker 
386*61046927SAndroid Build Coastguard Worker #endif /* vl_vlc_h */
387