xref: /aosp_15_r20/external/libopenapv/src/oapv_bs.c (revision abb65b4b03b69e1d508d4d9a44dcf199df16e7c3)
1*abb65b4bSAndroid Build Coastguard Worker /*
2*abb65b4bSAndroid Build Coastguard Worker  * Copyright (c) 2022 Samsung Electronics Co., Ltd.
3*abb65b4bSAndroid Build Coastguard Worker  * All Rights Reserved.
4*abb65b4bSAndroid Build Coastguard Worker  *
5*abb65b4bSAndroid Build Coastguard Worker  * Redistribution and use in source and binary forms, with or without
6*abb65b4bSAndroid Build Coastguard Worker  * modification, are permitted provided that the following conditions are met:
7*abb65b4bSAndroid Build Coastguard Worker  *
8*abb65b4bSAndroid Build Coastguard Worker  * - Redistributions of source code must retain the above copyright notice,
9*abb65b4bSAndroid Build Coastguard Worker  *   this list of conditions and the following disclaimer.
10*abb65b4bSAndroid Build Coastguard Worker  *
11*abb65b4bSAndroid Build Coastguard Worker  * - Redistributions in binary form must reproduce the above copyright notice,
12*abb65b4bSAndroid Build Coastguard Worker  *   this list of conditions and the following disclaimer in the documentation
13*abb65b4bSAndroid Build Coastguard Worker  *   and/or other materials provided with the distribution.
14*abb65b4bSAndroid Build Coastguard Worker  *
15*abb65b4bSAndroid Build Coastguard Worker  * - Neither the name of the copyright owner, nor the names of its contributors
16*abb65b4bSAndroid Build Coastguard Worker  *   may be used to endorse or promote products derived from this software
17*abb65b4bSAndroid Build Coastguard Worker  *   without specific prior written permission.
18*abb65b4bSAndroid Build Coastguard Worker  *
19*abb65b4bSAndroid Build Coastguard Worker  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20*abb65b4bSAndroid Build Coastguard Worker  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21*abb65b4bSAndroid Build Coastguard Worker  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22*abb65b4bSAndroid Build Coastguard Worker  * ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23*abb65b4bSAndroid Build Coastguard Worker  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24*abb65b4bSAndroid Build Coastguard Worker  * CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25*abb65b4bSAndroid Build Coastguard Worker  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26*abb65b4bSAndroid Build Coastguard Worker  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27*abb65b4bSAndroid Build Coastguard Worker  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28*abb65b4bSAndroid Build Coastguard Worker  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29*abb65b4bSAndroid Build Coastguard Worker  * POSSIBILITY OF SUCH DAMAGE.
30*abb65b4bSAndroid Build Coastguard Worker  */
31*abb65b4bSAndroid Build Coastguard Worker 
32*abb65b4bSAndroid Build Coastguard Worker #include "oapv_def.h"
33*abb65b4bSAndroid Build Coastguard Worker 
34*abb65b4bSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
35*abb65b4bSAndroid Build Coastguard Worker // start of encoder code
36*abb65b4bSAndroid Build Coastguard Worker #if ENABLE_ENCODER
37*abb65b4bSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
38*abb65b4bSAndroid Build Coastguard Worker /* number of bytes to be sunk */
39*abb65b4bSAndroid Build Coastguard Worker #define BSW_GET_SINK_BYTE(bs) ((32 - (bs)->leftbits + 7) >> 3)
40*abb65b4bSAndroid Build Coastguard Worker 
bsw_flush(oapv_bs_t * bs,int bytes)41*abb65b4bSAndroid Build Coastguard Worker static int bsw_flush(oapv_bs_t *bs, int bytes)
42*abb65b4bSAndroid Build Coastguard Worker {
43*abb65b4bSAndroid Build Coastguard Worker     if(bytes == 0)
44*abb65b4bSAndroid Build Coastguard Worker         bytes = BSW_GET_SINK_BYTE(bs);
45*abb65b4bSAndroid Build Coastguard Worker 
46*abb65b4bSAndroid Build Coastguard Worker     while(bytes--) {
47*abb65b4bSAndroid Build Coastguard Worker         *bs->cur++ = (bs->code >> 24) & 0xFF;
48*abb65b4bSAndroid Build Coastguard Worker         bs->code <<= 8;
49*abb65b4bSAndroid Build Coastguard Worker     }
50*abb65b4bSAndroid Build Coastguard Worker 
51*abb65b4bSAndroid Build Coastguard Worker     bs->leftbits = 32;
52*abb65b4bSAndroid Build Coastguard Worker 
53*abb65b4bSAndroid Build Coastguard Worker     return 0;
54*abb65b4bSAndroid Build Coastguard Worker }
55*abb65b4bSAndroid Build Coastguard Worker 
oapv_bsw_init(oapv_bs_t * bs,u8 * buf,int size,oapv_bs_fn_flush_t fn_flush)56*abb65b4bSAndroid Build Coastguard Worker void oapv_bsw_init(oapv_bs_t *bs, u8 *buf, int size, oapv_bs_fn_flush_t fn_flush)
57*abb65b4bSAndroid Build Coastguard Worker {
58*abb65b4bSAndroid Build Coastguard Worker     bs->size = size;
59*abb65b4bSAndroid Build Coastguard Worker     bs->beg = buf;
60*abb65b4bSAndroid Build Coastguard Worker     bs->cur = buf;
61*abb65b4bSAndroid Build Coastguard Worker     bs->end = buf + size - 1;
62*abb65b4bSAndroid Build Coastguard Worker     bs->code = 0;
63*abb65b4bSAndroid Build Coastguard Worker     bs->leftbits = 32;
64*abb65b4bSAndroid Build Coastguard Worker     bs->fn_flush = (fn_flush == NULL ? bsw_flush : fn_flush);
65*abb65b4bSAndroid Build Coastguard Worker     bs->is_bin_count = 0;
66*abb65b4bSAndroid Build Coastguard Worker     bs->bin_count = 0;
67*abb65b4bSAndroid Build Coastguard Worker }
68*abb65b4bSAndroid Build Coastguard Worker 
oapv_bsw_deinit(oapv_bs_t * bs)69*abb65b4bSAndroid Build Coastguard Worker void oapv_bsw_deinit(oapv_bs_t *bs)
70*abb65b4bSAndroid Build Coastguard Worker {
71*abb65b4bSAndroid Build Coastguard Worker     bs->fn_flush(bs, 0);
72*abb65b4bSAndroid Build Coastguard Worker }
73*abb65b4bSAndroid Build Coastguard Worker 
oapv_bsw_sink(oapv_bs_t * bs)74*abb65b4bSAndroid Build Coastguard Worker void *oapv_bsw_sink(oapv_bs_t *bs)
75*abb65b4bSAndroid Build Coastguard Worker {
76*abb65b4bSAndroid Build Coastguard Worker     oapv_assert_rv(bs->cur + BSW_GET_SINK_BYTE(bs) <= bs->end, NULL);
77*abb65b4bSAndroid Build Coastguard Worker     bs->fn_flush(bs, 0);
78*abb65b4bSAndroid Build Coastguard Worker     bs->code = 0;
79*abb65b4bSAndroid Build Coastguard Worker     bs->leftbits = 32;
80*abb65b4bSAndroid Build Coastguard Worker     return (void *)bs->cur;
81*abb65b4bSAndroid Build Coastguard Worker }
82*abb65b4bSAndroid Build Coastguard Worker 
oapv_bsw_write_direct(void * bits,u32 val,int len)83*abb65b4bSAndroid Build Coastguard Worker int oapv_bsw_write_direct(void *bits, u32 val, int len)
84*abb65b4bSAndroid Build Coastguard Worker {
85*abb65b4bSAndroid Build Coastguard Worker     int            i;
86*abb65b4bSAndroid Build Coastguard Worker     unsigned char *p = (unsigned char *)bits;
87*abb65b4bSAndroid Build Coastguard Worker 
88*abb65b4bSAndroid Build Coastguard Worker     oapv_assert_rv((len & 0x7) == 0, -1); // len should be byte-aligned
89*abb65b4bSAndroid Build Coastguard Worker 
90*abb65b4bSAndroid Build Coastguard Worker     val <<= (32 - len);
91*abb65b4bSAndroid Build Coastguard Worker     for(i = 0; i < (len >> 3); i++) {
92*abb65b4bSAndroid Build Coastguard Worker         p[i] = (val >> 24) & 0xFF;
93*abb65b4bSAndroid Build Coastguard Worker         val <<= 8;
94*abb65b4bSAndroid Build Coastguard Worker     }
95*abb65b4bSAndroid Build Coastguard Worker     return 0;
96*abb65b4bSAndroid Build Coastguard Worker }
97*abb65b4bSAndroid Build Coastguard Worker 
oapv_bsw_write1(oapv_bs_t * bs,int val)98*abb65b4bSAndroid Build Coastguard Worker int oapv_bsw_write1(oapv_bs_t *bs, int val)
99*abb65b4bSAndroid Build Coastguard Worker {
100*abb65b4bSAndroid Build Coastguard Worker     oapv_assert(bs);
101*abb65b4bSAndroid Build Coastguard Worker 
102*abb65b4bSAndroid Build Coastguard Worker     if(bs->is_bin_count) {
103*abb65b4bSAndroid Build Coastguard Worker         bs->bin_count++;
104*abb65b4bSAndroid Build Coastguard Worker         return 0;
105*abb65b4bSAndroid Build Coastguard Worker     }
106*abb65b4bSAndroid Build Coastguard Worker 
107*abb65b4bSAndroid Build Coastguard Worker     bs->leftbits--;
108*abb65b4bSAndroid Build Coastguard Worker     bs->code |= ((val & 0x1) << bs->leftbits);
109*abb65b4bSAndroid Build Coastguard Worker 
110*abb65b4bSAndroid Build Coastguard Worker     if(bs->leftbits == 0) {
111*abb65b4bSAndroid Build Coastguard Worker         oapv_assert_rv(bs->cur <= bs->end, -1);
112*abb65b4bSAndroid Build Coastguard Worker         bs->fn_flush(bs, 0);
113*abb65b4bSAndroid Build Coastguard Worker 
114*abb65b4bSAndroid Build Coastguard Worker         bs->code = 0;
115*abb65b4bSAndroid Build Coastguard Worker         bs->leftbits = 32;
116*abb65b4bSAndroid Build Coastguard Worker     }
117*abb65b4bSAndroid Build Coastguard Worker 
118*abb65b4bSAndroid Build Coastguard Worker     return 0;
119*abb65b4bSAndroid Build Coastguard Worker }
120*abb65b4bSAndroid Build Coastguard Worker 
oapv_bsw_write(oapv_bs_t * bs,u32 val,int len)121*abb65b4bSAndroid Build Coastguard Worker int oapv_bsw_write(oapv_bs_t *bs, u32 val, int len) /* len(1 ~ 32) */
122*abb65b4bSAndroid Build Coastguard Worker {
123*abb65b4bSAndroid Build Coastguard Worker     int leftbits;
124*abb65b4bSAndroid Build Coastguard Worker 
125*abb65b4bSAndroid Build Coastguard Worker     oapv_assert(bs);
126*abb65b4bSAndroid Build Coastguard Worker 
127*abb65b4bSAndroid Build Coastguard Worker     if(bs->is_bin_count) {
128*abb65b4bSAndroid Build Coastguard Worker         bs->bin_count += len;
129*abb65b4bSAndroid Build Coastguard Worker         return 0;
130*abb65b4bSAndroid Build Coastguard Worker     }
131*abb65b4bSAndroid Build Coastguard Worker 
132*abb65b4bSAndroid Build Coastguard Worker     leftbits = bs->leftbits;
133*abb65b4bSAndroid Build Coastguard Worker     val <<= (32 - len);
134*abb65b4bSAndroid Build Coastguard Worker     bs->code |= (val >> (32 - leftbits));
135*abb65b4bSAndroid Build Coastguard Worker 
136*abb65b4bSAndroid Build Coastguard Worker     if(len < leftbits) {
137*abb65b4bSAndroid Build Coastguard Worker         bs->leftbits -= len;
138*abb65b4bSAndroid Build Coastguard Worker     }
139*abb65b4bSAndroid Build Coastguard Worker     else {
140*abb65b4bSAndroid Build Coastguard Worker         oapv_assert_rv(bs->cur + 4 <= bs->end, -1);
141*abb65b4bSAndroid Build Coastguard Worker 
142*abb65b4bSAndroid Build Coastguard Worker         bs->leftbits = 0;
143*abb65b4bSAndroid Build Coastguard Worker         bs->fn_flush(bs, 0);
144*abb65b4bSAndroid Build Coastguard Worker         bs->code = (leftbits < 32 ? val << leftbits : 0);
145*abb65b4bSAndroid Build Coastguard Worker         bs->leftbits = 32 - (len - leftbits);
146*abb65b4bSAndroid Build Coastguard Worker     }
147*abb65b4bSAndroid Build Coastguard Worker 
148*abb65b4bSAndroid Build Coastguard Worker     return 0;
149*abb65b4bSAndroid Build Coastguard Worker }
150*abb65b4bSAndroid Build Coastguard Worker 
151*abb65b4bSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
152*abb65b4bSAndroid Build Coastguard Worker // end of encoder code
153*abb65b4bSAndroid Build Coastguard Worker #endif // ENABLE_ENCODER
154*abb65b4bSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
155*abb65b4bSAndroid Build Coastguard Worker 
156*abb65b4bSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
157*abb65b4bSAndroid Build Coastguard Worker // start of decoder code
158*abb65b4bSAndroid Build Coastguard Worker #if ENABLE_DECODER
159*abb65b4bSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
160*abb65b4bSAndroid Build Coastguard Worker 
161*abb65b4bSAndroid Build Coastguard Worker /* Table of count of leading zero for 4 bit value */
162*abb65b4bSAndroid Build Coastguard Worker static const u8 tbl_zero_count4[16] = {
163*abb65b4bSAndroid Build Coastguard Worker     4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
164*abb65b4bSAndroid Build Coastguard Worker };
165*abb65b4bSAndroid Build Coastguard Worker 
166*abb65b4bSAndroid Build Coastguard Worker // skip code if lefbits are larger than skip bit count;
bsr_skip_code(oapv_bs_t * bs,int size)167*abb65b4bSAndroid Build Coastguard Worker static void inline bsr_skip_code(oapv_bs_t *bs, int size)
168*abb65b4bSAndroid Build Coastguard Worker {
169*abb65b4bSAndroid Build Coastguard Worker     oapv_assert(size <= 32);
170*abb65b4bSAndroid Build Coastguard Worker     oapv_assert(bs->leftbits >= size);
171*abb65b4bSAndroid Build Coastguard Worker     if(size == 32) {
172*abb65b4bSAndroid Build Coastguard Worker         bs->code = 0;
173*abb65b4bSAndroid Build Coastguard Worker         bs->leftbits = 0;
174*abb65b4bSAndroid Build Coastguard Worker     }
175*abb65b4bSAndroid Build Coastguard Worker     else {
176*abb65b4bSAndroid Build Coastguard Worker         bs->code <<= size;
177*abb65b4bSAndroid Build Coastguard Worker         bs->leftbits -= size;
178*abb65b4bSAndroid Build Coastguard Worker     }
179*abb65b4bSAndroid Build Coastguard Worker }
180*abb65b4bSAndroid Build Coastguard Worker 
bsr_flush(oapv_bs_t * bs,int byte)181*abb65b4bSAndroid Build Coastguard Worker static int bsr_flush(oapv_bs_t *bs, int byte)
182*abb65b4bSAndroid Build Coastguard Worker {
183*abb65b4bSAndroid Build Coastguard Worker     int shift = 24, remained;
184*abb65b4bSAndroid Build Coastguard Worker     u32 code = 0;
185*abb65b4bSAndroid Build Coastguard Worker 
186*abb65b4bSAndroid Build Coastguard Worker     oapv_assert(byte);
187*abb65b4bSAndroid Build Coastguard Worker 
188*abb65b4bSAndroid Build Coastguard Worker     remained = (int)(bs->end - bs->cur) + 1;
189*abb65b4bSAndroid Build Coastguard Worker     if(byte > remained)
190*abb65b4bSAndroid Build Coastguard Worker         byte = remained;
191*abb65b4bSAndroid Build Coastguard Worker 
192*abb65b4bSAndroid Build Coastguard Worker     if(byte <= 0) {
193*abb65b4bSAndroid Build Coastguard Worker         bs->code = 0;
194*abb65b4bSAndroid Build Coastguard Worker         bs->leftbits = 0;
195*abb65b4bSAndroid Build Coastguard Worker         return -1;
196*abb65b4bSAndroid Build Coastguard Worker     }
197*abb65b4bSAndroid Build Coastguard Worker 
198*abb65b4bSAndroid Build Coastguard Worker     bs->leftbits = byte << 3;
199*abb65b4bSAndroid Build Coastguard Worker 
200*abb65b4bSAndroid Build Coastguard Worker     bs->cur += byte;
201*abb65b4bSAndroid Build Coastguard Worker     while(byte) {
202*abb65b4bSAndroid Build Coastguard Worker         code |= *(bs->cur - byte) << shift;
203*abb65b4bSAndroid Build Coastguard Worker         byte--;
204*abb65b4bSAndroid Build Coastguard Worker         shift -= 8;
205*abb65b4bSAndroid Build Coastguard Worker     }
206*abb65b4bSAndroid Build Coastguard Worker     bs->code = code;
207*abb65b4bSAndroid Build Coastguard Worker     return 0;
208*abb65b4bSAndroid Build Coastguard Worker }
209*abb65b4bSAndroid Build Coastguard Worker 
oapv_bsr_init(oapv_bs_t * bs,u8 * buf,int size,oapv_bs_fn_flush_t fn_flush)210*abb65b4bSAndroid Build Coastguard Worker void oapv_bsr_init(oapv_bs_t *bs, u8 *buf, int size, oapv_bs_fn_flush_t fn_flush)
211*abb65b4bSAndroid Build Coastguard Worker {
212*abb65b4bSAndroid Build Coastguard Worker     bs->size = size;
213*abb65b4bSAndroid Build Coastguard Worker     bs->cur = buf;
214*abb65b4bSAndroid Build Coastguard Worker     bs->beg = buf;
215*abb65b4bSAndroid Build Coastguard Worker     bs->end = buf + size - 1;
216*abb65b4bSAndroid Build Coastguard Worker     bs->code = 0;
217*abb65b4bSAndroid Build Coastguard Worker     bs->leftbits = 0;
218*abb65b4bSAndroid Build Coastguard Worker     bs->fn_flush = (fn_flush == NULL) ? bsr_flush : fn_flush;
219*abb65b4bSAndroid Build Coastguard Worker }
220*abb65b4bSAndroid Build Coastguard Worker 
oapv_bsr_clz_in_code(u32 code)221*abb65b4bSAndroid Build Coastguard Worker int oapv_bsr_clz_in_code(u32 code)
222*abb65b4bSAndroid Build Coastguard Worker {
223*abb65b4bSAndroid Build Coastguard Worker     int clz, bits4, shift;
224*abb65b4bSAndroid Build Coastguard Worker 
225*abb65b4bSAndroid Build Coastguard Worker     if(code == 0)
226*abb65b4bSAndroid Build Coastguard Worker         return 32; /* to protect infinite loop */
227*abb65b4bSAndroid Build Coastguard Worker 
228*abb65b4bSAndroid Build Coastguard Worker     bits4 = 0;
229*abb65b4bSAndroid Build Coastguard Worker     clz = 0;
230*abb65b4bSAndroid Build Coastguard Worker     shift = 28;
231*abb65b4bSAndroid Build Coastguard Worker 
232*abb65b4bSAndroid Build Coastguard Worker     while(bits4 == 0 && shift >= 0) {
233*abb65b4bSAndroid Build Coastguard Worker         bits4 = (code >> shift) & 0xf;
234*abb65b4bSAndroid Build Coastguard Worker         clz += tbl_zero_count4[bits4];
235*abb65b4bSAndroid Build Coastguard Worker         shift -= 4;
236*abb65b4bSAndroid Build Coastguard Worker     }
237*abb65b4bSAndroid Build Coastguard Worker     return clz;
238*abb65b4bSAndroid Build Coastguard Worker }
239*abb65b4bSAndroid Build Coastguard Worker 
oapv_bsr_align8(oapv_bs_t * bs)240*abb65b4bSAndroid Build Coastguard Worker void oapv_bsr_align8(oapv_bs_t *bs)
241*abb65b4bSAndroid Build Coastguard Worker {
242*abb65b4bSAndroid Build Coastguard Worker     /*
243*abb65b4bSAndroid Build Coastguard Worker     while (!bsr_is_align8(bs)) {
244*abb65b4bSAndroid Build Coastguard Worker         oapv_bsr_read1(bs);
245*abb65b4bSAndroid Build Coastguard Worker     }
246*abb65b4bSAndroid Build Coastguard Worker     */
247*abb65b4bSAndroid Build Coastguard Worker     int size;
248*abb65b4bSAndroid Build Coastguard Worker 
249*abb65b4bSAndroid Build Coastguard Worker     size = bs->leftbits & 0x7;
250*abb65b4bSAndroid Build Coastguard Worker 
251*abb65b4bSAndroid Build Coastguard Worker     bs->code <<= size;
252*abb65b4bSAndroid Build Coastguard Worker     bs->leftbits -= size;
253*abb65b4bSAndroid Build Coastguard Worker }
254*abb65b4bSAndroid Build Coastguard Worker 
oapv_bsr_skip(oapv_bs_t * bs,int size)255*abb65b4bSAndroid Build Coastguard Worker void oapv_bsr_skip(oapv_bs_t *bs, int size)
256*abb65b4bSAndroid Build Coastguard Worker {
257*abb65b4bSAndroid Build Coastguard Worker     oapv_assert(size > 0 && size <= 32);
258*abb65b4bSAndroid Build Coastguard Worker 
259*abb65b4bSAndroid Build Coastguard Worker     if(bs->leftbits < size) {
260*abb65b4bSAndroid Build Coastguard Worker         size -= bs->leftbits;
261*abb65b4bSAndroid Build Coastguard Worker         if(bs->fn_flush(bs, 4)) {
262*abb65b4bSAndroid Build Coastguard Worker             // oapv_trace("already reached the end of bitstream\n");  /* should be updated */
263*abb65b4bSAndroid Build Coastguard Worker             return;
264*abb65b4bSAndroid Build Coastguard Worker         }
265*abb65b4bSAndroid Build Coastguard Worker     }
266*abb65b4bSAndroid Build Coastguard Worker     bsr_skip_code(bs, size);
267*abb65b4bSAndroid Build Coastguard Worker }
268*abb65b4bSAndroid Build Coastguard Worker 
oapv_bsr_peek(oapv_bs_t * bs,u32 * val,int size)269*abb65b4bSAndroid Build Coastguard Worker void oapv_bsr_peek(oapv_bs_t *bs, u32 *val, int size)
270*abb65b4bSAndroid Build Coastguard Worker {
271*abb65b4bSAndroid Build Coastguard Worker     int byte, leftbits;
272*abb65b4bSAndroid Build Coastguard Worker     u32 code = 0;
273*abb65b4bSAndroid Build Coastguard Worker 
274*abb65b4bSAndroid Build Coastguard Worker     if(bs->leftbits < size) {
275*abb65b4bSAndroid Build Coastguard Worker         byte = (32 - bs->leftbits) >> 3;
276*abb65b4bSAndroid Build Coastguard Worker 
277*abb65b4bSAndroid Build Coastguard Worker         /* We should not check the return value
278*abb65b4bSAndroid Build Coastguard Worker         because this function could be failed at the EOB. */
279*abb65b4bSAndroid Build Coastguard Worker         if(byte) {
280*abb65b4bSAndroid Build Coastguard Worker             code = bs->code;
281*abb65b4bSAndroid Build Coastguard Worker             leftbits = bs->leftbits;
282*abb65b4bSAndroid Build Coastguard Worker 
283*abb65b4bSAndroid Build Coastguard Worker             bs->fn_flush(bs, byte);
284*abb65b4bSAndroid Build Coastguard Worker 
285*abb65b4bSAndroid Build Coastguard Worker             bs->code >>= leftbits;
286*abb65b4bSAndroid Build Coastguard Worker             bs->code |= code;
287*abb65b4bSAndroid Build Coastguard Worker             bs->leftbits += leftbits;
288*abb65b4bSAndroid Build Coastguard Worker         }
289*abb65b4bSAndroid Build Coastguard Worker     }
290*abb65b4bSAndroid Build Coastguard Worker 
291*abb65b4bSAndroid Build Coastguard Worker     oapv_assert(bs->leftbits <= 32);
292*abb65b4bSAndroid Build Coastguard Worker 
293*abb65b4bSAndroid Build Coastguard Worker     code = bs->code >> (32 - size);
294*abb65b4bSAndroid Build Coastguard Worker     size -= bs->leftbits;
295*abb65b4bSAndroid Build Coastguard Worker 
296*abb65b4bSAndroid Build Coastguard Worker     if(size > 0) {
297*abb65b4bSAndroid Build Coastguard Worker         /* even though we update several bytes, the requested size would be
298*abb65b4bSAndroid Build Coastguard Worker         larger than current bs->leftbits.
299*abb65b4bSAndroid Build Coastguard Worker         In this case, we should read one more byte, but we could not store
300*abb65b4bSAndroid Build Coastguard Worker         the read byte. */
301*abb65b4bSAndroid Build Coastguard Worker         if(bs->cur <= bs->end) {
302*abb65b4bSAndroid Build Coastguard Worker             code |= *(bs->cur) >> (8 - size);
303*abb65b4bSAndroid Build Coastguard Worker         }
304*abb65b4bSAndroid Build Coastguard Worker     }
305*abb65b4bSAndroid Build Coastguard Worker     *val = code;
306*abb65b4bSAndroid Build Coastguard Worker }
307*abb65b4bSAndroid Build Coastguard Worker 
oapv_bsr_sink(oapv_bs_t * bs)308*abb65b4bSAndroid Build Coastguard Worker void *oapv_bsr_sink(oapv_bs_t *bs)
309*abb65b4bSAndroid Build Coastguard Worker {
310*abb65b4bSAndroid Build Coastguard Worker     oapv_assert_rv(bs->cur + BSW_GET_SINK_BYTE(bs) <= bs->end, NULL);
311*abb65b4bSAndroid Build Coastguard Worker     oapv_assert_rv((bs->leftbits & 7) == 0, NULL);
312*abb65b4bSAndroid Build Coastguard Worker     bs->cur = bs->cur - (bs->leftbits >> 3);
313*abb65b4bSAndroid Build Coastguard Worker     bs->code = 0;
314*abb65b4bSAndroid Build Coastguard Worker     bs->leftbits = 0;
315*abb65b4bSAndroid Build Coastguard Worker     return (void *)bs->cur;
316*abb65b4bSAndroid Build Coastguard Worker }
317*abb65b4bSAndroid Build Coastguard Worker 
oapv_bsr_move(oapv_bs_t * bs,u8 * pos)318*abb65b4bSAndroid Build Coastguard Worker void oapv_bsr_move(oapv_bs_t *bs, u8 *pos)
319*abb65b4bSAndroid Build Coastguard Worker {
320*abb65b4bSAndroid Build Coastguard Worker     bs->code = 0;
321*abb65b4bSAndroid Build Coastguard Worker     bs->leftbits = 0;
322*abb65b4bSAndroid Build Coastguard Worker     bs->cur = pos;
323*abb65b4bSAndroid Build Coastguard Worker }
324*abb65b4bSAndroid Build Coastguard Worker 
oapv_bsr_read(oapv_bs_t * bs,int size)325*abb65b4bSAndroid Build Coastguard Worker u32 oapv_bsr_read(oapv_bs_t *bs, int size)
326*abb65b4bSAndroid Build Coastguard Worker {
327*abb65b4bSAndroid Build Coastguard Worker     u32 code = 0;
328*abb65b4bSAndroid Build Coastguard Worker 
329*abb65b4bSAndroid Build Coastguard Worker     oapv_assert(size > 0);
330*abb65b4bSAndroid Build Coastguard Worker 
331*abb65b4bSAndroid Build Coastguard Worker     if(bs->leftbits < size) {
332*abb65b4bSAndroid Build Coastguard Worker         code = bs->code >> (32 - size);
333*abb65b4bSAndroid Build Coastguard Worker         size -= bs->leftbits;
334*abb65b4bSAndroid Build Coastguard Worker         if(bs->fn_flush(bs, 4)) {
335*abb65b4bSAndroid Build Coastguard Worker             oapv_trace("already reached the end of bitstream\n"); /* should be updated */
336*abb65b4bSAndroid Build Coastguard Worker             return (u32)(-1);
337*abb65b4bSAndroid Build Coastguard Worker         }
338*abb65b4bSAndroid Build Coastguard Worker     }
339*abb65b4bSAndroid Build Coastguard Worker     code |= bs->code >> (32 - size);
340*abb65b4bSAndroid Build Coastguard Worker 
341*abb65b4bSAndroid Build Coastguard Worker     bsr_skip_code(bs, size);
342*abb65b4bSAndroid Build Coastguard Worker 
343*abb65b4bSAndroid Build Coastguard Worker     return code;
344*abb65b4bSAndroid Build Coastguard Worker }
345*abb65b4bSAndroid Build Coastguard Worker 
oapv_bsr_read1(oapv_bs_t * bs)346*abb65b4bSAndroid Build Coastguard Worker int oapv_bsr_read1(oapv_bs_t *bs)
347*abb65b4bSAndroid Build Coastguard Worker {
348*abb65b4bSAndroid Build Coastguard Worker     int code;
349*abb65b4bSAndroid Build Coastguard Worker     if(bs->leftbits == 0) {
350*abb65b4bSAndroid Build Coastguard Worker         if(bs->fn_flush(bs, 4)) {
351*abb65b4bSAndroid Build Coastguard Worker             oapv_trace("already reached the end of bitstream\n"); /* should be updated */
352*abb65b4bSAndroid Build Coastguard Worker             return -1;
353*abb65b4bSAndroid Build Coastguard Worker         }
354*abb65b4bSAndroid Build Coastguard Worker     }
355*abb65b4bSAndroid Build Coastguard Worker     code = (int)(bs->code >> 31);
356*abb65b4bSAndroid Build Coastguard Worker 
357*abb65b4bSAndroid Build Coastguard Worker     bs->code <<= 1;
358*abb65b4bSAndroid Build Coastguard Worker     bs->leftbits -= 1;
359*abb65b4bSAndroid Build Coastguard Worker 
360*abb65b4bSAndroid Build Coastguard Worker     return code;
361*abb65b4bSAndroid Build Coastguard Worker }
362*abb65b4bSAndroid Build Coastguard Worker 
363*abb65b4bSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
364*abb65b4bSAndroid Build Coastguard Worker // end of decoder code
365*abb65b4bSAndroid Build Coastguard Worker #endif // ENABLE_DECODER
366*abb65b4bSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
367