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