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