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 bs->cur += byte;
201 while(byte) {
202 code |= *(bs->cur - byte) << shift;
203 byte--;
204 shift -= 8;
205 }
206 bs->code = code;
207 return 0;
208 }
209
oapv_bsr_init(oapv_bs_t * bs,u8 * buf,int size,oapv_bs_fn_flush_t fn_flush)210 void oapv_bsr_init(oapv_bs_t *bs, u8 *buf, int size, oapv_bs_fn_flush_t fn_flush)
211 {
212 bs->size = size;
213 bs->cur = buf;
214 bs->beg = buf;
215 bs->end = buf + size - 1;
216 bs->code = 0;
217 bs->leftbits = 0;
218 bs->fn_flush = (fn_flush == NULL) ? bsr_flush : fn_flush;
219 }
220
oapv_bsr_clz_in_code(u32 code)221 int oapv_bsr_clz_in_code(u32 code)
222 {
223 int clz, bits4, shift;
224
225 if(code == 0)
226 return 32; /* to protect infinite loop */
227
228 bits4 = 0;
229 clz = 0;
230 shift = 28;
231
232 while(bits4 == 0 && shift >= 0) {
233 bits4 = (code >> shift) & 0xf;
234 clz += tbl_zero_count4[bits4];
235 shift -= 4;
236 }
237 return clz;
238 }
239
oapv_bsr_align8(oapv_bs_t * bs)240 void oapv_bsr_align8(oapv_bs_t *bs)
241 {
242 /*
243 while (!bsr_is_align8(bs)) {
244 oapv_bsr_read1(bs);
245 }
246 */
247 int size;
248
249 size = bs->leftbits & 0x7;
250
251 bs->code <<= size;
252 bs->leftbits -= size;
253 }
254
oapv_bsr_skip(oapv_bs_t * bs,int size)255 void oapv_bsr_skip(oapv_bs_t *bs, int size)
256 {
257 oapv_assert(size > 0 && size <= 32);
258
259 if(bs->leftbits < size) {
260 size -= bs->leftbits;
261 if(bs->fn_flush(bs, 4)) {
262 // oapv_trace("already reached the end of bitstream\n"); /* should be updated */
263 return;
264 }
265 }
266 bsr_skip_code(bs, size);
267 }
268
oapv_bsr_peek(oapv_bs_t * bs,u32 * val,int size)269 void oapv_bsr_peek(oapv_bs_t *bs, u32 *val, int size)
270 {
271 int byte, leftbits;
272 u32 code = 0;
273
274 if(bs->leftbits < size) {
275 byte = (32 - bs->leftbits) >> 3;
276
277 /* We should not check the return value
278 because this function could be failed at the EOB. */
279 if(byte) {
280 code = bs->code;
281 leftbits = bs->leftbits;
282
283 bs->fn_flush(bs, byte);
284
285 bs->code >>= leftbits;
286 bs->code |= code;
287 bs->leftbits += leftbits;
288 }
289 }
290
291 oapv_assert(bs->leftbits <= 32);
292
293 code = bs->code >> (32 - size);
294 size -= bs->leftbits;
295
296 if(size > 0) {
297 /* even though we update several bytes, the requested size would be
298 larger than current bs->leftbits.
299 In this case, we should read one more byte, but we could not store
300 the read byte. */
301 if(bs->cur <= bs->end) {
302 code |= *(bs->cur) >> (8 - size);
303 }
304 }
305 *val = code;
306 }
307
oapv_bsr_sink(oapv_bs_t * bs)308 void *oapv_bsr_sink(oapv_bs_t *bs)
309 {
310 oapv_assert_rv(bs->cur + BSW_GET_SINK_BYTE(bs) <= bs->end, NULL);
311 oapv_assert_rv((bs->leftbits & 7) == 0, NULL);
312 bs->cur = bs->cur - (bs->leftbits >> 3);
313 bs->code = 0;
314 bs->leftbits = 0;
315 return (void *)bs->cur;
316 }
317
oapv_bsr_move(oapv_bs_t * bs,u8 * pos)318 void oapv_bsr_move(oapv_bs_t *bs, u8 *pos)
319 {
320 bs->code = 0;
321 bs->leftbits = 0;
322 bs->cur = pos;
323 }
324
oapv_bsr_read(oapv_bs_t * bs,int size)325 u32 oapv_bsr_read(oapv_bs_t *bs, int size)
326 {
327 u32 code = 0;
328
329 oapv_assert(size > 0);
330
331 if(bs->leftbits < size) {
332 code = bs->code >> (32 - size);
333 size -= bs->leftbits;
334 if(bs->fn_flush(bs, 4)) {
335 oapv_trace("already reached the end of bitstream\n"); /* should be updated */
336 return (u32)(-1);
337 }
338 }
339 code |= bs->code >> (32 - size);
340
341 bsr_skip_code(bs, size);
342
343 return code;
344 }
345
oapv_bsr_read1(oapv_bs_t * bs)346 int oapv_bsr_read1(oapv_bs_t *bs)
347 {
348 int code;
349 if(bs->leftbits == 0) {
350 if(bs->fn_flush(bs, 4)) {
351 oapv_trace("already reached the end of bitstream\n"); /* should be updated */
352 return -1;
353 }
354 }
355 code = (int)(bs->code >> 31);
356
357 bs->code <<= 1;
358 bs->leftbits -= 1;
359
360 return code;
361 }
362
363 ///////////////////////////////////////////////////////////////////////////////
364 // end of decoder code
365 #endif // ENABLE_DECODER
366 ///////////////////////////////////////////////////////////////////////////////
367