Line data Source code
1 : /*
2 : * GPAC - Multimedia Framework C SDK
3 : *
4 : * Authors: Jean Le Feuvre
5 : * Copyright (c) Telecom ParisTech 2000-2020
6 : * All rights reserved
7 : *
8 : * This file is part of GPAC / common tools sub-project
9 : *
10 : * GPAC is free software; you can redistribute it and/or modify
11 : * it under the terms of the GNU Lesser General Public License as published by
12 : * the Free Software Foundation; either version 2, or (at your option)
13 : * any later version.
14 : *
15 : * GPAC is distributed in the hope that it will be useful,
16 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : * GNU Lesser General Public License for more details.
19 : *
20 : * You should have received a copy of the GNU Lesser General Public
21 : * License along with this library; see the file COPYING. If not, write to
22 : * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23 : *
24 : */
25 :
26 : #include <gpac/bitstream.h>
27 :
28 : /*the default size for new streams allocation...*/
29 : #define BS_MEM_BLOCK_ALLOC_SIZE 512
30 :
31 : /*private types*/
32 : enum
33 : {
34 : GF_BITSTREAM_FILE_READ = GF_BITSTREAM_WRITE_DYN + 1,
35 : GF_BITSTREAM_FILE_WRITE,
36 : };
37 :
38 : struct __tag_bitstream
39 : {
40 : /*original stream data*/
41 : FILE *stream;
42 :
43 : /*or original data*/
44 : char *original;
45 : /*the size of our buffer in bytes*/
46 : u64 size;
47 : /*current position in BYTES*/
48 : u64 position;
49 : /*the byte readen/written*/
50 : u32 current;
51 : /*the number of bits in the current byte*/
52 : u32 nbBits;
53 : /*the bitstream mode*/
54 : u32 bsmode;
55 :
56 : void (*EndOfStream)(void *par);
57 : void *par;
58 :
59 :
60 : char *cache_write;
61 : u32 cache_write_size, buffer_written;
62 :
63 : Bool remove_emul_prevention_byte;
64 : u32 nb_zeros;
65 :
66 : GF_Err (*on_block_out)(void *cbk, u8 *data, u32 block_size);
67 : void *usr_data;
68 : u64 bytes_out;
69 : u32 prevent_dispatch;
70 :
71 : u64 cookie;
72 :
73 : u8 *cache_read;
74 : u32 cache_read_size, cache_read_pos, cache_read_alloc;
75 :
76 : void (*on_log)(void *udta, const char *field_name, u32 nb_bits, u64 field_val, s32 idx1, s32 idx2, s32 idx3);
77 : void *log_udta;
78 : };
79 :
80 2797466 : GF_Err gf_bs_reassign_buffer(GF_BitStream *bs, const u8 *buffer, u64 BufferSize)
81 : {
82 2797466 : if (!bs) return GF_BAD_PARAM;
83 2797466 : if (bs->bsmode == GF_BITSTREAM_READ) {
84 1843133 : bs->original = (char*)buffer;
85 1843133 : bs->size = BufferSize;
86 1843133 : bs->position = 0;
87 1843133 : bs->current = 0;
88 1843133 : bs->nbBits = 8;
89 : bs->current = 0;
90 1843133 : bs->nb_zeros = 0;
91 1843133 : return GF_OK;
92 : }
93 954333 : if (bs->bsmode==GF_BITSTREAM_WRITE) {
94 826558 : if (!buffer || !BufferSize) return GF_BAD_PARAM;
95 826558 : bs->original = (char*)buffer;
96 826558 : bs->size = BufferSize;
97 826558 : bs->position = 0;
98 826558 : bs->current = 0;
99 826558 : bs->nbBits = 0;
100 : bs->current = 0;
101 826558 : return GF_OK;
102 : }
103 127775 : if (bs->bsmode!=GF_BITSTREAM_WRITE_DYN) return GF_BAD_PARAM;
104 127775 : if (bs->original) return GF_BAD_PARAM;
105 :
106 110731 : bs->position = 0;
107 110731 : bs->current = 0;
108 110731 : bs->nbBits = 0;
109 : bs->current = 0;
110 110731 : bs->size = BufferSize ? BufferSize : BS_MEM_BLOCK_ALLOC_SIZE;
111 110731 : if (buffer) {
112 110731 : bs->original = (char *) buffer;
113 : } else {
114 0 : bs->original = (char *) gf_malloc(sizeof(char) * ((u32) bs->size));
115 0 : if (! bs->original) {
116 : return GF_OUT_OF_MEM;
117 : }
118 : }
119 : return GF_OK;
120 : }
121 :
122 : GF_EXPORT
123 552356 : GF_BitStream *gf_bs_new(const u8 *buffer, u64 BufferSize, u32 mode)
124 : {
125 552356 : GF_BitStream *tmp = (GF_BitStream *)gf_malloc(sizeof(GF_BitStream));
126 552356 : if (!tmp) return NULL;
127 : memset(tmp, 0, sizeof(GF_BitStream));
128 :
129 552356 : tmp->original = (char*)buffer;
130 552356 : tmp->size = BufferSize;
131 :
132 552356 : tmp->bsmode = mode;
133 :
134 552356 : switch (tmp->bsmode) {
135 311944 : case GF_BITSTREAM_READ:
136 311944 : tmp->nbBits = 8;
137 311944 : tmp->current = 0;
138 311944 : break;
139 240412 : case GF_BITSTREAM_WRITE:
140 : case GF_BITSTREAM_WRITE_DYN:
141 240412 : tmp->nbBits = 0;
142 240412 : if (! buffer) {
143 : /*if BufferSize is specified, use it. This is typically used when AvgSize of
144 : some buffers is known, but some exceed it.*/
145 239045 : if (BufferSize) {
146 : tmp->size = BufferSize;
147 : } else {
148 239000 : tmp->size = BS_MEM_BLOCK_ALLOC_SIZE;
149 : }
150 239045 : tmp->original = (char *) gf_malloc(sizeof(char) * ((u32) tmp->size));
151 239045 : if (! tmp->original) {
152 0 : gf_free(tmp);
153 0 : return NULL;
154 : }
155 239045 : tmp->bsmode = GF_BITSTREAM_WRITE_DYN;
156 : } else {
157 : tmp->original = (char*)buffer;
158 : tmp->size = BufferSize;
159 : }
160 : break;
161 0 : default:
162 : /*the stream constructor is not the same...*/
163 0 : gf_free(tmp);
164 0 : return NULL;
165 : }
166 : return tmp;
167 : }
168 :
169 : GF_EXPORT
170 10011 : GF_BitStream *gf_bs_from_file(FILE *f, u32 mode)
171 : {
172 : GF_BitStream *tmp;
173 10011 : if (!f) return NULL;
174 :
175 10011 : tmp = (GF_BitStream *)gf_malloc(sizeof(GF_BitStream));
176 10011 : if (!tmp) return NULL;
177 : memset(tmp, 0, sizeof(GF_BitStream));
178 : /*switch to internal mode*/
179 10011 : mode = (mode==GF_BITSTREAM_READ) ? GF_BITSTREAM_FILE_READ : GF_BITSTREAM_FILE_WRITE;
180 10011 : tmp->bsmode = mode;
181 10011 : tmp->current = 0;
182 10011 : tmp->nbBits = (mode == GF_BITSTREAM_FILE_READ) ? 8 : 0;
183 10011 : tmp->original = NULL;
184 10011 : tmp->position = 0;
185 10011 : tmp->stream = f;
186 :
187 : /*get the size of this file (for read streams)*/
188 10011 : tmp->position = gf_ftell(f);
189 10011 : tmp->size = gf_fsize(f);
190 10011 : gf_fseek(f, tmp->position, SEEK_SET);
191 :
192 :
193 10011 : if (mode==GF_BITSTREAM_FILE_READ) {
194 8091 : tmp->cache_read_alloc = gf_opts_get_int("core", "bs-cache-size");
195 8091 : if (tmp->cache_read_alloc) {
196 8091 : tmp->cache_read_pos = tmp->cache_read_size = tmp->cache_read_alloc;
197 8091 : tmp->cache_read = gf_malloc(tmp->cache_read_alloc);
198 8091 : if (!tmp->cache_read) {
199 0 : gf_free(tmp);
200 0 : return NULL;
201 : }
202 : }
203 : }
204 10011 : if (mode == GF_BITSTREAM_FILE_WRITE) {
205 1920 : tmp->cache_write_size = gf_opts_get_int("core", "bs-cache-size");
206 1920 : if (tmp->cache_write_size) {
207 1920 : tmp->cache_write = (char*)gf_malloc(tmp->cache_write_size);
208 1920 : if (!tmp->cache_write) {
209 0 : gf_free(tmp);
210 0 : return NULL;
211 : }
212 1920 : tmp->buffer_written = 0;
213 : }
214 : }
215 :
216 : return tmp;
217 : }
218 :
219 :
220 4218 : GF_BitStream *gf_bs_new_cbk_buffer(GF_Err (*on_block_out)(void *cbk, u8 *data, u32 block_size), void *usr_data, u8 *buffer, u32 buffer_size)
221 : {
222 : GF_BitStream *tmp;
223 :
224 4218 : if (!on_block_out) return NULL;
225 :
226 4218 : tmp = (GF_BitStream *)gf_malloc(sizeof(GF_BitStream));
227 4218 : if (!tmp) return NULL;
228 : memset(tmp, 0, sizeof(GF_BitStream));
229 :
230 4218 : if (buffer && buffer_size) {
231 3157 : tmp->size = buffer_size;
232 3157 : tmp->original = buffer;
233 : } else {
234 1061 : tmp->size = buffer_size ? buffer_size : 10*BS_MEM_BLOCK_ALLOC_SIZE;
235 1061 : tmp->original = (char *) gf_malloc(sizeof(char) * ((u32) tmp->size));
236 1061 : if (! tmp->original) {
237 0 : gf_free(tmp);
238 0 : return NULL;
239 : }
240 : }
241 4218 : tmp->bsmode = GF_BITSTREAM_WRITE_DYN;
242 4218 : tmp->on_block_out = on_block_out;
243 4218 : tmp->usr_data = usr_data;
244 :
245 4218 : return tmp;
246 : }
247 :
248 722 : GF_BitStream *gf_bs_new_cbk(GF_Err (*on_block_out)(void *cbk, u8 *data, u32 block_size), void *usr_data, u32 block_size)
249 : {
250 722 : return gf_bs_new_cbk_buffer(on_block_out, usr_data, NULL, block_size);
251 :
252 : }
253 9933 : void gf_bs_prevent_dispatch(GF_BitStream *bs, Bool prevent_dispatch)
254 : {
255 9933 : if (!bs) return;
256 9933 : if (prevent_dispatch) {
257 6150 : bs->prevent_dispatch ++;
258 6150 : return;
259 : }
260 3783 : if (!bs->prevent_dispatch) return;
261 3783 : bs->prevent_dispatch --;
262 :
263 3783 : if (bs->on_block_out && !bs->prevent_dispatch) {
264 : assert(bs->position >= bs->bytes_out);
265 1337 : if (bs->position > bs->bytes_out) {
266 1337 : bs->on_block_out(bs->usr_data, bs->original, (u32) (bs->position - bs->bytes_out));
267 1337 : bs->bytes_out = bs->position;
268 : }
269 : }
270 : }
271 :
272 1527237 : static void bs_flush_write_cache(GF_BitStream *bs)
273 : {
274 1527237 : if (bs->buffer_written) {
275 : u32 nb_write;
276 234328 : nb_write = (u32) gf_fwrite(bs->cache_write, bs->buffer_written, bs->stream);
277 :
278 : //check we didn't rewind the bitstream
279 234328 : if (bs->size == bs->position)
280 233961 : bs->size += nb_write;
281 234328 : bs->position += nb_write;
282 234328 : bs->buffer_written = 0;
283 : }
284 1527237 : }
285 :
286 :
287 :
288 : GF_EXPORT
289 566585 : void gf_bs_del(GF_BitStream *bs)
290 : {
291 566585 : if (!bs) return;
292 566585 : if (bs->on_block_out && bs->position>bs->bytes_out) {
293 610 : bs->on_block_out(bs->usr_data, bs->original, (u32) (bs->position - bs->bytes_out) );
294 : }
295 : /*if we are in dynamic mode (alloc done by the bitstream), free the buffer if still present*/
296 566585 : if ((bs->bsmode == GF_BITSTREAM_WRITE_DYN) && bs->original) gf_free(bs->original);
297 566585 : if (bs->cache_write) {
298 1920 : bs_flush_write_cache(bs);
299 1920 : gf_free(bs->cache_write);
300 : }
301 566585 : if (bs->cache_read)
302 8091 : gf_free(bs->cache_read);
303 566585 : gf_free(bs);
304 : }
305 :
306 : GF_EXPORT
307 1516939 : void gf_bs_enable_emulation_byte_removal(GF_BitStream *bs, Bool do_remove)
308 : {
309 1516939 : if (bs) {
310 1516939 : bs->remove_emul_prevention_byte = do_remove;
311 1516939 : bs->nb_zeros = 0;
312 : }
313 1516939 : }
314 :
315 : /*returns 1 if aligned wrt current mode, 0 otherwise*/
316 1 : Bool gf_bs_is_align(GF_BitStream *bs)
317 : {
318 4697168 : switch (bs->bsmode) {
319 1524650 : case GF_BITSTREAM_READ:
320 : case GF_BITSTREAM_FILE_READ:
321 1524650 : return ( (8 == bs->nbBits) ? GF_TRUE : GF_FALSE);
322 3172518 : default:
323 3172518 : return !bs->nbBits;
324 : }
325 : }
326 :
327 3156274 : static GFINLINE u8 gf_bs_load_byte(GF_BitStream *bs, Bool *is_eos)
328 : {
329 : u8 res;
330 3156274 : if (bs->cache_read) {
331 3156274 : if (bs->cache_read_pos == bs->cache_read_size) {
332 623798 : bs->cache_read_size = (u32) gf_fread(bs->cache_read, bs->cache_read_alloc, bs->stream);
333 623798 : bs->cache_read_pos = 0;
334 623798 : if (!bs->cache_read_size) {
335 0 : *is_eos = GF_TRUE;
336 0 : return 0;
337 : }
338 : }
339 3156274 : res = bs->cache_read[bs->cache_read_pos];
340 3156274 : bs->cache_read_pos++;
341 : } else {
342 0 : res = gf_fgetc(bs->stream);
343 : }
344 : return res;
345 : }
346 :
347 : /*fetch a new byte in the bitstream switch between packets*/
348 51990949 : static u8 BS_ReadByte(GF_BitStream *bs)
349 : {
350 : Bool is_eos;
351 51990949 : if (bs->bsmode == GF_BITSTREAM_READ) {
352 : u8 res;
353 48846487 : if (bs->position >= bs->size) {
354 569 : if (bs->EndOfStream) bs->EndOfStream(bs->par);
355 : return 0;
356 : }
357 48845918 : res = bs->original[bs->position++];
358 :
359 48845918 : if (bs->remove_emul_prevention_byte) {
360 5034698 : if ((bs->nb_zeros==2) && (res==0x03) && (bs->position<bs->size) && (bs->original[bs->position]<0x04)) {
361 20359 : bs->nb_zeros = 0;
362 20359 : res = bs->original[bs->position++];
363 : }
364 5034698 : if (!res) bs->nb_zeros++;
365 4947314 : else bs->nb_zeros = 0;
366 : }
367 : return res;
368 : }
369 3144462 : if (bs->cache_write)
370 0 : bs_flush_write_cache(bs);
371 :
372 3144462 : is_eos = gf_feof(bs->stream);
373 :
374 : /*we are in FILE mode, test for end of file*/
375 3144462 : if (!is_eos || bs->cache_read) {
376 : u8 res;
377 3144462 : Bool loc_eos=GF_FALSE;
378 : assert(bs->position<=bs->size);
379 3144462 : bs->position++;
380 :
381 3144462 : res = gf_bs_load_byte(bs, &loc_eos);
382 3144462 : if (loc_eos) goto bs_eof;
383 :
384 3144462 : if (bs->remove_emul_prevention_byte) {
385 2087765 : if ((bs->nb_zeros==2) && (res==0x03) && (bs->position<bs->size)) {
386 11812 : u8 next = gf_bs_load_byte(bs, &loc_eos);
387 11812 : if (next < 0x04) {
388 11812 : bs->nb_zeros = 0;
389 : res = next;
390 11812 : bs->position++;
391 : } else {
392 0 : gf_bs_seek(bs, bs->position);
393 : }
394 : }
395 2087765 : if (!res) bs->nb_zeros++;
396 1362331 : else bs->nb_zeros = 0;
397 : }
398 3144462 : return res;
399 : }
400 :
401 0 : bs_eof:
402 0 : if (bs->EndOfStream) {
403 0 : bs->EndOfStream(bs->par);
404 : } else {
405 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[BS] Attempt to overread bitstream\n"));
406 : }
407 : assert(bs->position <= 1+bs->size);
408 : return 0;
409 : }
410 :
411 : #define NO_OPTS
412 :
413 : #ifndef NO_OPTS
414 : static u32 bit_mask[] = {0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1};
415 : static u32 bits_mask[] = {0x0, 0x1, 0x3, 0x7, 0xF, 0x1F, 0x3F, 0x7F};
416 : #endif
417 :
418 : GF_EXPORT
419 146430011 : u8 gf_bs_read_bit(GF_BitStream *bs)
420 : {
421 146430011 : if (bs->nbBits == 8) {
422 18744227 : bs->current = BS_ReadByte(bs);
423 18744227 : bs->nbBits = 0;
424 : }
425 : #ifdef NO_OPTS
426 : {
427 : s32 ret;
428 146430011 : bs->current <<= 1;
429 146430011 : bs->nbBits++;
430 146430011 : ret = (bs->current & 0x100) >> 8;
431 146430011 : return (u8) ret;
432 : }
433 : #else
434 : return (u8) (bs->current & bit_mask[bs->nbBits++]) ? 1 : 0;
435 : #endif
436 :
437 : }
438 :
439 : GF_EXPORT
440 37728788 : u32 gf_bs_read_int(GF_BitStream *bs, u32 nBits)
441 : {
442 : u32 ret;
443 :
444 : #ifndef NO_OPTS
445 : if (nBits + bs->nbBits <= 8) {
446 : bs->nbBits += nBits;
447 : ret = (bs->current >> (8 - bs->nbBits) ) & bits_mask[nBits];
448 : return ret;
449 : }
450 : #endif
451 : ret = 0;
452 220323437 : while (nBits-- > 0) {
453 144865861 : ret <<= 1;
454 144865861 : ret |= gf_bs_read_bit(bs);
455 : }
456 37728788 : return ret;
457 : }
458 :
459 : GF_EXPORT
460 30927454 : u32 gf_bs_read_u8(GF_BitStream *bs)
461 : {
462 : assert(bs->nbBits==8);
463 30927454 : if (bs->cache_read && (bs->cache_read_pos+1<bs->cache_read_size) ) {
464 101132 : u32 ret = bs->cache_read[bs->cache_read_pos];
465 101132 : bs->cache_read_pos+=1;
466 101132 : bs->position+=1;
467 101132 : return ret;
468 : }
469 :
470 30826322 : return (u32) BS_ReadByte(bs);
471 : }
472 :
473 : #if 0
474 : GF_EXPORT
475 : u32 gf_bs_read_u8_until_delimiter(GF_BitStream *bs, u8 delimiter, u8* out, u32 max_length) {
476 : u32 i = 0;
477 : char token=0;
478 : u64 cur_pos = gf_bs_get_position(bs);
479 :
480 : if (!max_length) out = NULL;
481 :
482 : while(gf_bs_available(bs) && (!max_length || i < max_length)) {
483 : gf_bs_read_data(bs, &token, 1);
484 : if (token == delimiter) goto found;
485 : if (out) out[i] = token;
486 : i++;
487 : }
488 :
489 : /* Delimiter not found */
490 : gf_bs_seek(bs, cur_pos);
491 : return 0;
492 :
493 : found:
494 : return i;
495 : }
496 : #endif
497 :
498 : GF_EXPORT
499 395770 : u32 gf_bs_read_u16(GF_BitStream *bs)
500 : {
501 : u32 ret;
502 : assert(bs->nbBits==8);
503 395770 : if (bs->cache_read && (bs->cache_read_pos+2<bs->cache_read_size) ) {
504 39140 : ret = bs->cache_read[bs->cache_read_pos];
505 39140 : ret<<=8;
506 39140 : ret |= bs->cache_read[bs->cache_read_pos+1];
507 39140 : bs->cache_read_pos+=2;
508 39140 : bs->position+=2;
509 39140 : return ret;
510 : }
511 :
512 356630 : ret = BS_ReadByte(bs);
513 356630 : ret<<=8;
514 356630 : ret |= BS_ReadByte(bs);
515 356630 : return ret;
516 : }
517 :
518 :
519 : GF_EXPORT
520 62546 : u32 gf_bs_read_u24(GF_BitStream *bs)
521 : {
522 : u32 ret;
523 : assert(bs->nbBits==8);
524 :
525 62546 : if (bs->cache_read && (bs->cache_read_pos+3<bs->cache_read_size) ) {
526 48174 : ret = bs->cache_read[bs->cache_read_pos];
527 48174 : ret<<=8;
528 48174 : ret |= bs->cache_read[bs->cache_read_pos+1];
529 48174 : ret<<=8;
530 48174 : ret |= bs->cache_read[bs->cache_read_pos+2];
531 48174 : bs->cache_read_pos+=3;
532 48174 : bs->position+=3;
533 48174 : return ret;
534 : }
535 :
536 14372 : ret = BS_ReadByte(bs);
537 14372 : ret<<=8;
538 14372 : ret |= BS_ReadByte(bs);
539 14372 : ret<<=8;
540 14372 : ret |= BS_ReadByte(bs);
541 14372 : return ret;
542 : }
543 :
544 : GF_EXPORT
545 2162323 : u32 gf_bs_read_u32(GF_BitStream *bs)
546 : {
547 : u32 ret;
548 : assert(bs->nbBits==8);
549 :
550 2162323 : if (bs->cache_read && (bs->cache_read_pos+4<bs->cache_read_size) ) {
551 1746317 : ret = bs->cache_read[bs->cache_read_pos];
552 1746317 : ret<<=8;
553 1746317 : ret |= bs->cache_read[bs->cache_read_pos+1];
554 1746317 : ret<<=8;
555 1746317 : ret |= bs->cache_read[bs->cache_read_pos+2];
556 1746317 : ret<<=8;
557 1746317 : ret |= bs->cache_read[bs->cache_read_pos+3];
558 1746317 : bs->cache_read_pos+=4;
559 1746317 : bs->position+=4;
560 1746317 : return ret;
561 : }
562 416006 : ret = BS_ReadByte(bs);
563 416006 : ret<<=8;
564 416006 : ret |= BS_ReadByte(bs);
565 416006 : ret<<=8;
566 416006 : ret |= BS_ReadByte(bs);
567 416006 : ret<<=8;
568 416006 : ret |= BS_ReadByte(bs);
569 416006 : return ret;
570 : }
571 :
572 : GF_EXPORT
573 8100 : u64 gf_bs_read_u64(GF_BitStream *bs)
574 : {
575 : u64 ret;
576 :
577 8100 : if (bs->cache_read && (bs->cache_read_pos+8<bs->cache_read_size) ) {
578 1719 : ret = bs->cache_read[bs->cache_read_pos];
579 1719 : ret<<=8;
580 1719 : ret |= bs->cache_read[bs->cache_read_pos+1];
581 1719 : ret<<=8;
582 1719 : ret |= bs->cache_read[bs->cache_read_pos+2];
583 1719 : ret<<=8;
584 1719 : ret |= bs->cache_read[bs->cache_read_pos+3];
585 1719 : ret<<=8;
586 1719 : ret |= bs->cache_read[bs->cache_read_pos+4];
587 1719 : ret<<=8;
588 1719 : ret |= bs->cache_read[bs->cache_read_pos+5];
589 1719 : ret<<=8;
590 1719 : ret |= bs->cache_read[bs->cache_read_pos+6];
591 1719 : ret<<=8;
592 1719 : ret |= bs->cache_read[bs->cache_read_pos+7];
593 1719 : bs->cache_read_pos+=8;
594 1719 : bs->position+=8;
595 1719 : return ret;
596 : }
597 6381 : ret = gf_bs_read_u32(bs);
598 6381 : ret<<=32;
599 6381 : ret |= gf_bs_read_u32(bs);
600 6381 : return ret;
601 : }
602 :
603 : GF_EXPORT
604 11159 : u64 gf_bs_read_long_int(GF_BitStream *bs, u32 nBits)
605 : {
606 : u64 ret = 0;
607 11159 : if (nBits>64) {
608 0 : gf_bs_read_long_int(bs, nBits-64);
609 : ret = gf_bs_read_long_int(bs, 64);
610 : } else {
611 450701 : while (nBits-- > 0) {
612 439542 : ret <<= 1;
613 439542 : ret |= gf_bs_read_bit(bs);
614 : }
615 : }
616 11159 : return ret;
617 : }
618 :
619 :
620 : GF_EXPORT
621 34860 : Float gf_bs_read_float(GF_BitStream *bs)
622 : {
623 34860 : char buf [4] = "\0\0\0";
624 : #ifdef NO_OPTS
625 : s32 i;
626 1150380 : for (i = 0; i < 32; i++)
627 1115520 : buf[3-i/8] |= gf_bs_read_bit(bs) << (7 - i%8);
628 : #else
629 : buf[3] = gf_bs_read_int(bs, 8);
630 : buf[2] = gf_bs_read_int(bs, 8);
631 : buf[1] = gf_bs_read_int(bs, 8);
632 : buf[0] = gf_bs_read_int(bs, 8);
633 : #endif
634 34860 : return (* (Float *) buf);
635 : }
636 :
637 : GF_EXPORT
638 142 : Double gf_bs_read_double(GF_BitStream *bs)
639 : {
640 142 : char buf [8] = "\0\0\0\0\0\0\0";
641 : s32 i;
642 9230 : for (i = 0; i < 64; i++)
643 9088 : buf[7-i/8] |= gf_bs_read_bit(bs) << (7 - i%8);
644 142 : return (* (Double *) buf);
645 : }
646 :
647 : GF_EXPORT
648 2453229 : u32 gf_bs_read_data(GF_BitStream *bs, u8 *data, u32 nbBytes)
649 : {
650 2453229 : u64 orig = bs->position;
651 :
652 2453229 : if (bs->position+nbBytes > bs->size) return 0;
653 :
654 2453227 : if (gf_bs_is_align(bs) ) {
655 : s32 bytes_read, bytes_read_cache;
656 2450244 : switch (bs->bsmode) {
657 464020 : case GF_BITSTREAM_READ:
658 : case GF_BITSTREAM_WRITE:
659 : case GF_BITSTREAM_WRITE_DYN:
660 464020 : memcpy(data, bs->original + bs->position, nbBytes);
661 464020 : bs->position += nbBytes;
662 464020 : return nbBytes;
663 1986224 : case GF_BITSTREAM_FILE_READ:
664 : case GF_BITSTREAM_FILE_WRITE:
665 1986224 : if (bs->cache_write)
666 925007 : bs_flush_write_cache(bs);
667 :
668 : bytes_read = bytes_read_cache = 0;
669 1986224 : if (bs->cache_read) {
670 1061217 : u32 csize = bs->cache_read_size-bs->cache_read_pos;
671 1061217 : if (csize>nbBytes) csize = nbBytes;
672 1061217 : memcpy(data, bs->cache_read + bs->cache_read_pos, csize);
673 1061217 : bs->cache_read_pos += csize;
674 1061217 : nbBytes -= csize;
675 1061217 : bytes_read_cache = csize;
676 : }
677 1986224 : if (nbBytes) {
678 1966928 : bytes_read = (s32) gf_fread(data + bytes_read_cache, nbBytes, bs->stream);
679 1966928 : if (bytes_read<0) return bytes_read_cache;
680 : }
681 1986224 : bs->position += bytes_read + bytes_read_cache;
682 1986224 : return bytes_read + bytes_read_cache;
683 : default:
684 : return 0;
685 : }
686 : }
687 :
688 371207 : while (nbBytes-- > 0) {
689 368224 : *data++ = gf_bs_read_int(bs, 8);
690 : }
691 2983 : return (u32) (bs->position - orig);
692 :
693 : }
694 :
695 :
696 :
697 12757054 : static void BS_WriteByte(GF_BitStream *bs, u8 val)
698 : {
699 : /*we don't allow write on READ buffers*/
700 12757054 : if ( (bs->bsmode == GF_BITSTREAM_READ) || (bs->bsmode == GF_BITSTREAM_FILE_READ) ) {
701 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[BS] Attempt to write on read bitstream\n"));
702 : return;
703 : }
704 12757054 : if (!bs->original && !bs->stream) {
705 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[BS] Attempt to write on unassigned bitstream\n"));
706 : return;
707 : }
708 : /*we are in MEM mode*/
709 12757054 : if ( (bs->bsmode == GF_BITSTREAM_WRITE) || (bs->bsmode == GF_BITSTREAM_WRITE_DYN) ) {
710 : //if callback mode and dispatch is not blocked, dispatch
711 12713305 : if (bs->on_block_out && !bs->prevent_dispatch) {
712 : assert(bs->position >= bs->bytes_out);
713 761021 : if (bs->position - bs->bytes_out == bs->size) {
714 9 : bs->on_block_out(bs->usr_data, bs->original, (u32) (bs->position - bs->bytes_out));
715 9 : bs->bytes_out = bs->position;
716 : }
717 761021 : if (bs->original)
718 761021 : bs->original[bs->position - bs->bytes_out] = val;
719 761021 : bs->position++;
720 : assert(bs->position >= bs->bytes_out);
721 761021 : return;
722 : }
723 : //otherwise store
724 11952284 : if (bs->position - bs->bytes_out == bs->size) {
725 : /*no more space...*/
726 1766 : if (bs->bsmode != GF_BITSTREAM_WRITE_DYN) return;
727 : /*gf_realloc if enough space...*/
728 1766 : if (bs->size > 0xFFFFFFFF) return;
729 1766 : bs->size = bs->size ? (bs->size * 2) : BS_MEM_BLOCK_ALLOC_SIZE;
730 1766 : bs->original = (char*)gf_realloc(bs->original, (u32)bs->size);
731 1766 : if (!bs->original) return;
732 : }
733 11952284 : if (bs->original)
734 11952284 : bs->original[bs->position - bs->bytes_out] = val;
735 11952284 : bs->position++;
736 11952284 : return;
737 : }
738 43749 : if (bs->cache_write) {
739 43749 : if (bs->buffer_written == bs->cache_write_size) {
740 0 : bs_flush_write_cache(bs);
741 : }
742 43749 : bs->cache_write[bs->buffer_written] = val;
743 43749 : bs->buffer_written++;
744 43749 : if (bs->buffer_written == bs->cache_write_size) {
745 7111 : bs_flush_write_cache(bs);
746 : }
747 : return;
748 : }
749 : /*we are in FILE mode, no pb for any gf_realloc...*/
750 0 : gf_fputc(val, bs->stream);
751 :
752 : /*check we didn't rewind the stream*/
753 0 : if (bs->size == bs->position) bs->size++;
754 0 : bs->position += 1;
755 : }
756 :
757 48583488 : static void BS_WriteBit(GF_BitStream *bs, u32 bit)
758 : {
759 48583488 : bs->current <<= 1;
760 48583488 : bs->current |= bit;
761 48583488 : if (++ bs->nbBits == 8) {
762 6072936 : bs->nbBits = 0;
763 6072936 : BS_WriteByte(bs, (u8) bs->current);
764 6072936 : bs->current = 0;
765 : }
766 48583488 : }
767 :
768 5584154 : static s32 bs_handle_nbits_overflow(GF_BitStream* bs, s32 nBits, s32 max_shift)
769 : {
770 5584154 : if (nBits > max_shift) {
771 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[BS] Attempt to write %d bits, when max is %d\n", nBits, max_shift));
772 : }
773 5584154 : while (nBits > max_shift) {
774 0 : gf_bs_write_long_int(bs, 0, max_shift);
775 0 : nBits -= max_shift;
776 : }
777 :
778 5584154 : return nBits;
779 : }
780 :
781 : GF_EXPORT
782 5556423 : void gf_bs_write_int(GF_BitStream *bs, s32 _value, s32 nBits)
783 : {
784 : u32 value, nb_shift;
785 : s32 max_shift = sizeof(s32) * 8;
786 5556423 : if (!nBits) return;
787 5503023 : nBits = bs_handle_nbits_overflow(bs, nBits, max_shift);
788 : //move to unsigned to avoid sanitizer warnings when we pass a value not codable on the given number of bits
789 : //we do this when setting bit fields to all 1's
790 5503023 : value = (u32) _value;
791 5503023 : nb_shift = max_shift - nBits;
792 5503023 : if (nb_shift)
793 4722604 : value <<= nb_shift;
794 :
795 48040133 : while (--nBits >= 0) {
796 : //but check value as signed
797 42537110 : BS_WriteBit (bs, ((s32)value) < 0);
798 42537110 : value <<= 1;
799 : }
800 : }
801 :
802 : GF_EXPORT
803 81408 : void gf_bs_write_long_int(GF_BitStream *bs, s64 _value, s32 nBits)
804 : {
805 : s32 max_shift = sizeof(s64) * 8;
806 81408 : if (!nBits) return;
807 81131 : nBits = bs_handle_nbits_overflow(bs, nBits, max_shift);
808 :
809 : //cf note in gf_bs_write_int
810 81131 : u64 value = (u64) _value;
811 81131 : value <<= max_shift - nBits;
812 1456992 : while (--nBits >= 0) {
813 1294730 : BS_WriteBit (bs, ((s64)value) < 0);
814 1294730 : value <<= 1;
815 : }
816 : }
817 :
818 : GF_EXPORT
819 558598 : void gf_bs_write_u8(GF_BitStream *bs, u32 value)
820 : {
821 : assert(!bs->nbBits);
822 :
823 558598 : if (bs->cache_write && (bs->buffer_written+1 < bs->cache_write_size) ) {
824 24073 : bs->cache_write[bs->buffer_written] = (u8) value;
825 24073 : bs->buffer_written += 1;
826 : } else {
827 534525 : BS_WriteByte(bs, (u8) value);
828 : }
829 558598 : }
830 :
831 : GF_EXPORT
832 696253 : void gf_bs_write_u16(GF_BitStream *bs, u32 value)
833 : {
834 : assert(!bs->nbBits);
835 696253 : if (bs->cache_write && (bs->buffer_written+2 < bs->cache_write_size) ) {
836 17152 : bs->cache_write[bs->buffer_written] = (u8) ((value>>8)&0xff);
837 17152 : bs->cache_write[bs->buffer_written+1] = (u8) ((value)&0xff);
838 17152 : bs->buffer_written += 2;
839 : } else {
840 679101 : BS_WriteByte(bs, (u8) ((value>>8)&0xff));
841 679101 : BS_WriteByte(bs, (u8) ((value)&0xff));
842 : }
843 696253 : }
844 :
845 : GF_EXPORT
846 61382 : void gf_bs_write_u24(GF_BitStream *bs, u32 value)
847 : {
848 : assert(!bs->nbBits);
849 61382 : if (bs->cache_write && (bs->buffer_written+3 < bs->cache_write_size) ) {
850 15913 : bs->cache_write[bs->buffer_written] = (u8) ((value>>16)&0xff);
851 15913 : bs->cache_write[bs->buffer_written+1] = (u8) ((value>>8)&0xff);
852 15913 : bs->cache_write[bs->buffer_written+2] = (u8) ((value)&0xff);
853 15913 : bs->buffer_written += 3;
854 : } else {
855 45469 : BS_WriteByte(bs, (u8) ((value>>16)&0xff));
856 45469 : BS_WriteByte(bs, (u8) ((value>>8)&0xff));
857 45469 : BS_WriteByte(bs, (u8) ((value)&0xff));
858 : }
859 61382 : }
860 :
861 : GF_EXPORT
862 2084565 : void gf_bs_write_u32(GF_BitStream *bs, u32 value)
863 : {
864 : assert(!bs->nbBits);
865 2084565 : if (bs->cache_write && (bs->buffer_written+4 < bs->cache_write_size) ) {
866 920819 : bs->cache_write[bs->buffer_written] = (u8) ((value>>24)&0xff);
867 920819 : bs->cache_write[bs->buffer_written+1] = (u8) ((value>>16)&0xff);
868 920819 : bs->cache_write[bs->buffer_written+2] = (u8) ((value>>8)&0xff);
869 920819 : bs->cache_write[bs->buffer_written+3] = (u8) ((value)&0xff);
870 920819 : bs->buffer_written += 4;
871 : } else {
872 1163746 : BS_WriteByte(bs, (u8) ((value>>24)&0xff));
873 1163746 : BS_WriteByte(bs, (u8) ((value>>16)&0xff));
874 1163746 : BS_WriteByte(bs, (u8) ((value>>8)&0xff));
875 1163746 : BS_WriteByte(bs, (u8) ((value)&0xff));
876 : }
877 2084565 : }
878 :
879 : GF_EXPORT
880 9038 : void gf_bs_write_u64(GF_BitStream *bs, u64 value)
881 : {
882 : assert(!bs->nbBits);
883 9038 : gf_bs_write_u32(bs, (u32) ((value>>32)&0xffffffff));
884 9038 : gf_bs_write_u32(bs, (u32) (value&0xffffffff));
885 9038 : }
886 :
887 : GF_EXPORT
888 21760 : u32 gf_bs_write_byte(GF_BitStream *bs, u8 byte, u32 repeat_count)
889 : {
890 21760 : if (!gf_bs_is_align(bs) || bs->cache_write) {
891 : u32 count = 0;
892 58 : while (count<repeat_count) {
893 29 : gf_bs_write_int(bs, byte, 8);
894 29 : count++;
895 : }
896 : return count;
897 : }
898 :
899 21731 : switch (bs->bsmode) {
900 21720 : case GF_BITSTREAM_WRITE:
901 21720 : if (bs->position + repeat_count > bs->size)
902 : return 0;
903 21720 : memset(bs->original + bs->position, byte, repeat_count);
904 21720 : bs->position += repeat_count;
905 21720 : return repeat_count;
906 11 : case GF_BITSTREAM_WRITE_DYN:
907 : /*need to gf_realloc ...*/
908 11 : if (bs->position+repeat_count> bs->size) {
909 0 : u32 new_size = (u32) (bs->size*2);
910 0 : if (!new_size) new_size = BS_MEM_BLOCK_ALLOC_SIZE;
911 :
912 0 : if (bs->size + repeat_count > 0xFFFFFFFF)
913 : return 0;
914 0 : while (new_size < (u32) ( bs->size + repeat_count))
915 0 : new_size *= 2;
916 0 : bs->original = (char*)gf_realloc(bs->original, sizeof(u32)*new_size);
917 0 : if (!bs->original)
918 : return 0;
919 0 : bs->size = new_size;
920 : }
921 11 : memset(bs->original + bs->position, byte, repeat_count);
922 11 : bs->position += repeat_count;
923 11 : return repeat_count;
924 0 : case GF_BITSTREAM_FILE_READ:
925 : case GF_BITSTREAM_FILE_WRITE:
926 0 : if (gf_fwrite(&byte, repeat_count, bs->stream) != repeat_count)
927 : return 0;
928 0 : if (bs->size == bs->position) bs->size += repeat_count;
929 0 : bs->position += repeat_count;
930 0 : return repeat_count;
931 : default:
932 : return 0;
933 : }
934 : }
935 :
936 :
937 :
938 : GF_EXPORT
939 148203 : void gf_bs_write_float(GF_BitStream *bs, Float value)
940 : {
941 : u32 i;
942 : union
943 : { float f;
944 : char sz [4];
945 : } float_value;
946 148203 : float_value.f = value;
947 :
948 4890699 : for (i = 0; i < 32; i++)
949 4742496 : BS_WriteBit(bs, (float_value.sz [3 - i / 8] & 1 << (7 - i % 8)) != 0);
950 :
951 148203 : }
952 :
953 : GF_EXPORT
954 143 : void gf_bs_write_double (GF_BitStream *bs, Double value)
955 : {
956 : u32 i;
957 : union
958 : { Double d;
959 : char sz [8];
960 : } double_value;
961 143 : double_value.d = value;
962 9295 : for (i = 0; i < 64; i++) {
963 9152 : BS_WriteBit(bs, (double_value.sz [7 - i / 8] & 1 << (7 - i % 8)) != 0);
964 : }
965 143 : }
966 :
967 :
968 : GF_EXPORT
969 2224923 : u32 gf_bs_write_data(GF_BitStream *bs, const u8 *data, u32 nbBytes)
970 : {
971 : /*we need some feedback for this guy...*/
972 2224923 : u64 begin = bs->position;
973 2224923 : if (!nbBytes) return 0;
974 :
975 2222180 : if (gf_bs_is_align(bs)) {
976 2221799 : switch (bs->bsmode) {
977 73082 : case GF_BITSTREAM_WRITE:
978 73082 : if (bs->position+nbBytes > bs->size) {
979 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[BS] Attempt to overwrite bitstream by %d bytes\n", bs->position + nbBytes - bs->size));
980 : return 0;
981 : }
982 73082 : memcpy(bs->original + bs->position, data, nbBytes);
983 73082 : bs->position += nbBytes;
984 73082 : return nbBytes;
985 653062 : case GF_BITSTREAM_WRITE_DYN:
986 : //if callback mode and dispatch not disabled, dispatch bytes
987 653062 : if (bs->on_block_out && !bs->prevent_dispatch) {
988 : assert(bs->position >= bs->bytes_out);
989 :
990 118250 : if (bs->position - bs->bytes_out + nbBytes <= bs->size) {
991 108806 : memcpy(bs->original + bs->position - bs->bytes_out, data, nbBytes);
992 108806 : bs->position += nbBytes;
993 : } else {
994 9444 : if (bs->position > bs->bytes_out)
995 6857 : bs->on_block_out(bs->usr_data, bs->original, (u32) (bs->position - bs->bytes_out) );
996 : if (nbBytes)
997 9444 : bs->on_block_out(bs->usr_data, (char *) data, nbBytes);
998 :
999 9444 : bs->position += nbBytes;
1000 9444 : bs->bytes_out = bs->position;
1001 : }
1002 : assert(bs->position >= bs->bytes_out);
1003 : return nbBytes;
1004 : }
1005 : //otherwise store
1006 : /*need to gf_realloc ...*/
1007 534812 : if (bs->position + nbBytes - bs->bytes_out > bs->size) {
1008 17912 : u32 new_size = (u32) (bs->size*2);
1009 17912 : if (!new_size) new_size = BS_MEM_BLOCK_ALLOC_SIZE;
1010 :
1011 17912 : if (bs->size + nbBytes > 0xFFFFFFFF)
1012 : return 0;
1013 :
1014 36279 : while (new_size < (u32) ( bs->size + nbBytes))
1015 18367 : new_size *= 2;
1016 17912 : bs->original = (char*)gf_realloc(bs->original, sizeof(u32)*new_size);
1017 17912 : if (!bs->original)
1018 : return 0;
1019 17912 : bs->size = new_size;
1020 : }
1021 534812 : memcpy(bs->original + bs->position - bs->bytes_out, data, nbBytes);
1022 534812 : bs->position += nbBytes;
1023 534812 : return nbBytes;
1024 1495654 : case GF_BITSTREAM_FILE_READ:
1025 : case GF_BITSTREAM_FILE_WRITE:
1026 1495654 : if (bs->cache_write) {
1027 : //if block fits in our write cache, write it
1028 1495654 : if (bs->buffer_written + nbBytes < bs->cache_write_size) {
1029 1051884 : memcpy(bs->cache_write+bs->buffer_written, data, nbBytes);
1030 1051884 : bs->buffer_written+=nbBytes;
1031 1051884 : return nbBytes;
1032 : }
1033 : //otherwise flush cache and use file write
1034 443770 : bs_flush_write_cache(bs);
1035 : }
1036 :
1037 443770 : if (gf_fwrite(data, nbBytes, bs->stream) != nbBytes) return 0;
1038 :
1039 443770 : if (bs->size == bs->position) bs->size += nbBytes;
1040 443770 : bs->position += nbBytes;
1041 443770 : return nbBytes;
1042 : default:
1043 : return 0;
1044 : }
1045 : }
1046 :
1047 94590 : while (nbBytes) {
1048 94209 : gf_bs_write_int(bs, (s32) *data, 8);
1049 94209 : data++;
1050 94209 : nbBytes--;
1051 : }
1052 381 : return (u32) (bs->position - begin);
1053 : }
1054 :
1055 : /*align return the num of bits read in READ mode, 0 in WRITE*/
1056 : GF_EXPORT
1057 4062533 : u8 gf_bs_align(GF_BitStream *bs)
1058 : {
1059 4062533 : u8 res = 8 - bs->nbBits;
1060 4062533 : if ( (bs->bsmode == GF_BITSTREAM_READ) || (bs->bsmode == GF_BITSTREAM_FILE_READ)) {
1061 3491591 : if (res > 0) {
1062 539870 : gf_bs_read_int(bs, res);
1063 : }
1064 : return res;
1065 : }
1066 570942 : if (bs->nbBits > 0) {
1067 35370 : gf_bs_write_int (bs, 0, res);
1068 35370 : return res;
1069 : }
1070 : return 0;
1071 : }
1072 :
1073 :
1074 : /*size available in the bitstream*/
1075 : GF_EXPORT
1076 33131833 : u64 gf_bs_available(GF_BitStream *bs)
1077 : {
1078 : s64 cur, end;
1079 :
1080 : /*in WRITE mode only, this should not be called, but return something big in case ...*/
1081 66263666 : if ( (bs->bsmode == GF_BITSTREAM_WRITE)
1082 33131833 : || (bs->bsmode == GF_BITSTREAM_WRITE_DYN)
1083 : )
1084 : return (u64) -1;
1085 :
1086 : /*we are in MEM mode*/
1087 33131833 : if (bs->bsmode == GF_BITSTREAM_READ) {
1088 31710541 : if (bs->size < bs->position)
1089 : return 0;
1090 : else
1091 31710541 : return (bs->size - bs->position);
1092 : }
1093 : /*FILE READ: assume size hasn't changed, otherwise the user shall call gf_bs_get_refreshed_size*/
1094 1421292 : if (bs->bsmode==GF_BITSTREAM_FILE_READ) {
1095 1421292 : if (bs->position>bs->size) return 0;
1096 1421292 : return (bs->size - bs->position);
1097 : }
1098 0 : if (bs->cache_write)
1099 0 : bs_flush_write_cache(bs);
1100 :
1101 0 : cur = gf_ftell(bs->stream);
1102 0 : end = gf_fsize(bs->stream);
1103 0 : gf_fseek(bs->stream, cur, SEEK_SET);
1104 :
1105 0 : return (u64) (end - cur);
1106 : }
1107 :
1108 : /*call this funct to set the buffer size to the nb of bytes written
1109 : Used only in WRITE mode, as we don't know the real size during allocation...
1110 : return -1 for bad param or gf_malloc failed
1111 : return nbBytes cut*/
1112 213092 : static s32 BS_CutBuffer(GF_BitStream *bs)
1113 : {
1114 : s32 nbBytes;
1115 213092 : if ( (bs->bsmode != GF_BITSTREAM_WRITE_DYN) && (bs->bsmode != GF_BITSTREAM_WRITE)) return (u32) -1;
1116 : /*Align our buffer or we're dead!*/
1117 213092 : gf_bs_align(bs);
1118 :
1119 213092 : nbBytes = (u32) (bs->size - bs->position);
1120 213092 : if (!nbBytes || (nbBytes == 0xFFFFFFFF) || (bs->position >= 0xFFFFFFFF)) return 0;
1121 : /*
1122 : bs->original = (char*)gf_realloc(bs->original, (u32) bs->position);
1123 : if (! bs->original) return (u32) -1;
1124 : */
1125 : /*just in case, re-adjust..*/
1126 212870 : bs->size = bs->position;
1127 212870 : return nbBytes;
1128 : }
1129 :
1130 : /*For DYN mode, this gets the content out without cutting the buffer to the number of written bytes*/
1131 : GF_EXPORT
1132 332181 : void gf_bs_get_content_no_truncate(GF_BitStream *bs, u8 **output, u32 *outSize, u32 *alloc_size)
1133 : {
1134 : /*only in WRITE MEM mode*/
1135 332181 : if (bs->bsmode != GF_BITSTREAM_WRITE_DYN) return;
1136 :
1137 332180 : if (bs->on_block_out && bs->position>bs->bytes_out) {
1138 2965 : bs->on_block_out(bs->usr_data, bs->original, (u32) (bs->position - bs->bytes_out) );
1139 : }
1140 :
1141 332180 : if (!bs->position && !bs->nbBits) {
1142 12322 : if (!alloc_size) {
1143 12285 : *output = NULL;
1144 12285 : gf_free(bs->original);
1145 : } else {
1146 37 : *alloc_size = (u32) bs->size;
1147 37 : *output = bs->original;
1148 : }
1149 12322 : *outSize = 0;
1150 : } else {
1151 319858 : if (alloc_size) {
1152 : /*Align our buffer or we're dead!*/
1153 106766 : gf_bs_align(bs);
1154 106766 : *alloc_size = (u32) bs->size;
1155 106766 : *outSize = (u32) bs->position;
1156 106766 : *output = bs->original;
1157 : } else {
1158 213092 : s32 copy = BS_CutBuffer(bs);
1159 213092 : if (copy < 0) {
1160 0 : *output = NULL;
1161 : } else
1162 213092 : *output = bs->original;
1163 213092 : *outSize = (u32) bs->size;
1164 : }
1165 : }
1166 332180 : bs->original = NULL;
1167 332180 : bs->size = 0;
1168 332180 : bs->position = 0;
1169 : }
1170 :
1171 : /*For DYN mode, this gets the content out*/
1172 : GF_EXPORT
1173 217721 : void gf_bs_get_content(GF_BitStream *bs, u8 **output, u32 *outSize)
1174 : {
1175 217721 : gf_bs_get_content_no_truncate(bs, output, outSize, NULL);
1176 217721 : }
1177 :
1178 : /* Skip nbytes.
1179 : Align
1180 : If READ (MEM or FILE) mode, just read n times 8 bit
1181 : If WRITE (MEM or FILE) mode, write n times 0 on 8 bit
1182 : */
1183 : GF_EXPORT
1184 912901 : void gf_bs_skip_bytes(GF_BitStream *bs, u64 nbBytes)
1185 : {
1186 912901 : if (!bs || !nbBytes) return;
1187 :
1188 912700 : gf_bs_align(bs);
1189 :
1190 : /*special case for file skipping...*/
1191 912700 : if ((bs->bsmode == GF_BITSTREAM_FILE_WRITE) || (bs->bsmode == GF_BITSTREAM_FILE_READ)) {
1192 81813 : if (bs->cache_write)
1193 0 : bs_flush_write_cache(bs);
1194 :
1195 81813 : if (bs->cache_read) {
1196 81813 : u32 csize = bs->cache_read_size - bs->cache_read_pos;
1197 81813 : if (csize>=nbBytes) {
1198 33085 : bs->cache_read_pos += (u32) nbBytes;
1199 33085 : bs->position += nbBytes;
1200 33085 : return;
1201 : }
1202 48728 : nbBytes -= csize;
1203 48728 : bs->position += csize;
1204 48728 : bs->cache_read_pos = bs->cache_read_size;
1205 : }
1206 : //weird msys2 bug resulting in broken seek on some files ?!? -the bug is not happening when doing absolute seek
1207 : // gf_fseek(bs->stream, nbBytes, SEEK_CUR);
1208 48728 : bs->position += nbBytes;
1209 48728 : if (bs->bsmode == GF_BITSTREAM_FILE_READ) {
1210 48728 : if (bs->position > bs->size) bs->position = bs->size;
1211 : }
1212 48728 : gf_fseek(bs->stream, bs->position, SEEK_SET);
1213 48728 : return;
1214 : }
1215 :
1216 : /*special case for reading*/
1217 830887 : if (bs->bsmode == GF_BITSTREAM_READ) {
1218 830887 : if (bs->remove_emul_prevention_byte) {
1219 25735 : while (nbBytes) {
1220 23604 : gf_bs_read_u8(bs);
1221 23604 : nbBytes--;
1222 : }
1223 : } else {
1224 828756 : bs->position += nbBytes;
1225 : }
1226 : return;
1227 : }
1228 : /*for writing we must do it this way, otherwise pb in dynamic buffers*/
1229 0 : while (nbBytes) {
1230 0 : gf_bs_write_int(bs, 0, 8);
1231 0 : nbBytes--;
1232 : }
1233 : }
1234 :
1235 : #ifdef GPAC_ENABLE_BIFS_PMF
1236 :
1237 : void gf_bs_rewind_bits(GF_BitStream *bs, u64 nbBits)
1238 : {
1239 : u64 nbBytes;
1240 : if (bs->bsmode != GF_BITSTREAM_READ) return;
1241 :
1242 : nbBits -= (bs->nbBits);
1243 : nbBytes = (nbBits+8)>>3;
1244 : nbBits = nbBytes*8 - nbBits;
1245 : gf_bs_align(bs);
1246 : assert(bs->position >= nbBytes);
1247 : bs->position -= nbBytes + 1;
1248 : gf_bs_read_int(bs, (u32)nbBits);
1249 : return;
1250 : }
1251 :
1252 : #endif
1253 :
1254 : /*seek from beginning of stream: use internally even when non aligned!*/
1255 2433626 : static GF_Err BS_SeekIntern(GF_BitStream *bs, u64 offset)
1256 : {
1257 : u32 i;
1258 : /*if mem, do it */
1259 2433626 : if ((bs->bsmode == GF_BITSTREAM_READ) || (bs->bsmode == GF_BITSTREAM_WRITE) || (bs->bsmode == GF_BITSTREAM_WRITE_DYN)) {
1260 1155057 : if (offset > 0xFFFFFFFF) return GF_IO_ERR;
1261 1155057 : if (!bs->original) return GF_BAD_PARAM;
1262 : /*0 for write, read will be done automatically*/
1263 1117739 : if (offset >= bs->size) {
1264 28449 : if ( (bs->bsmode == GF_BITSTREAM_READ) || (bs->bsmode == GF_BITSTREAM_WRITE) ) {
1265 24970 : if (offset > bs->size) {
1266 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CORE, ("[BS] Attempt to seek to %d after end of bitstream %d, assuming seek to end\n", offset, bs->size));
1267 : }
1268 24970 : bs->position = bs->size;
1269 24970 : bs->nbBits = (bs->bsmode == GF_BITSTREAM_READ) ? 8 : 0;
1270 24970 : return GF_OK;
1271 : }
1272 : /*in DYN, gf_realloc ...*/
1273 3479 : bs->original = (char*)gf_realloc(bs->original, (u32) (offset + 1));
1274 3479 : if (!bs->original)
1275 : return GF_OUT_OF_MEM;
1276 3479 : for (i = 0; i < (u32) (offset + 1 - bs->size); i++) {
1277 3479 : bs->original[bs->size + i] = 0;
1278 : }
1279 3479 : bs->size = offset + 1;
1280 : }
1281 1092769 : bs->current = bs->original[offset];
1282 1092769 : bs->position = offset;
1283 1092769 : bs->nbBits = (bs->bsmode == GF_BITSTREAM_READ) ? 8 : 0;
1284 1092769 : return GF_OK;
1285 : }
1286 :
1287 1278569 : if (bs->cache_write)
1288 74714 : bs_flush_write_cache(bs);
1289 :
1290 1278569 : if (bs->cache_read) {
1291 1203855 : bs->cache_read_pos = bs->cache_read_size;
1292 : }
1293 :
1294 1278569 : gf_fseek(bs->stream, offset, SEEK_SET);
1295 :
1296 1278569 : bs->position = offset;
1297 1278569 : bs->current = 0;
1298 : /*setup NbBits so that next acccess to the buffer will trigger read/write*/
1299 1278569 : bs->nbBits = (bs->bsmode == GF_BITSTREAM_FILE_READ) ? 8 : 0;
1300 1278569 : return GF_OK;
1301 : }
1302 :
1303 : /*seek from beginning of stream: align before anything else*/
1304 : GF_EXPORT
1305 2486493 : GF_Err gf_bs_seek(GF_BitStream *bs, u64 offset)
1306 : {
1307 2486493 : if (bs->on_block_out) {
1308 : GF_Err e;
1309 5009 : if (offset < bs->bytes_out) {
1310 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[BS] Attempt to seek on byte range already forwarded\n"));
1311 : return GF_BAD_PARAM;
1312 : }
1313 : /*warning: we allow offset = bs->size for WRITE buffers*/
1314 5009 : if (offset - bs->bytes_out > bs->size)
1315 : return GF_BAD_PARAM;
1316 5009 : gf_bs_align(bs);
1317 5009 : e = BS_SeekIntern(bs, offset - bs->bytes_out);
1318 5009 : bs->position += bs->bytes_out;
1319 5009 : return e;
1320 : }
1321 2481484 : if (bs->cache_write)
1322 74714 : bs_flush_write_cache(bs);
1323 :
1324 : /*warning: we allow offset = bs->size for WRITE buffers*/
1325 2481484 : if (offset > bs->size) return GF_BAD_PARAM;
1326 :
1327 2428617 : gf_bs_align(bs);
1328 2428617 : return BS_SeekIntern(bs, offset);
1329 : }
1330 :
1331 : /*peek bits (as int!!) from orig position (ON BYTE BOUNDARIES, from 0) - only for read ...*/
1332 : GF_EXPORT
1333 259486 : u32 gf_bs_peek_bits(GF_BitStream *bs, u32 numBits, u64 byte_offset)
1334 : {
1335 : u64 curPos;
1336 : u32 curBits, ret, current, nb_zeros;
1337 :
1338 259486 : if ( (bs->bsmode != GF_BITSTREAM_READ) && (bs->bsmode != GF_BITSTREAM_FILE_READ)) return 0;
1339 259486 : if (!numBits || (bs->size < bs->position + byte_offset)) return 0;
1340 :
1341 : /*store our state*/
1342 : curPos = bs->position;
1343 259442 : curBits = bs->nbBits;
1344 259442 : current = bs->current;
1345 259442 : nb_zeros = bs->nb_zeros;
1346 :
1347 259442 : if (byte_offset) {
1348 6396 : if (bs->remove_emul_prevention_byte) {
1349 0 : while (byte_offset) {
1350 0 : gf_bs_read_int(bs, 8);
1351 0 : byte_offset--;
1352 : }
1353 : } else {
1354 6396 : gf_bs_seek(bs, bs->position + byte_offset);
1355 : }
1356 : }
1357 259442 : ret = gf_bs_read_int(bs, numBits);
1358 :
1359 : /*restore our cache - position*/
1360 259442 : gf_bs_seek(bs, curPos);
1361 : /*to avoid re-reading our bits ...*/
1362 259442 : bs->nbBits = curBits;
1363 259442 : bs->current = current;
1364 259442 : bs->nb_zeros = nb_zeros;
1365 259442 : return ret;
1366 : }
1367 :
1368 : GF_EXPORT
1369 9287 : u64 gf_bs_get_refreshed_size(GF_BitStream *bs)
1370 : {
1371 : s64 offset;
1372 :
1373 9287 : switch (bs->bsmode) {
1374 6950 : case GF_BITSTREAM_READ:
1375 : case GF_BITSTREAM_WRITE:
1376 6950 : return bs->size;
1377 :
1378 2337 : default:
1379 2337 : if (bs->cache_write)
1380 0 : bs_flush_write_cache(bs);
1381 :
1382 2337 : if (bs->stream) {
1383 2337 : offset = gf_ftell(bs->stream);
1384 2337 : bs->size = gf_fsize(bs->stream);
1385 2337 : gf_fseek(bs->stream, offset, SEEK_SET);
1386 : }
1387 2337 : return bs->size;
1388 : }
1389 : }
1390 :
1391 : GF_EXPORT
1392 3210970 : u64 gf_bs_get_size(GF_BitStream *bs)
1393 : {
1394 3210970 : if (bs->cache_write) {
1395 2068057 : if (bs->size == bs->position)
1396 1122768 : return bs->size + bs->buffer_written;
1397 : else
1398 : return bs->size;
1399 : }
1400 1142913 : if (bs->on_block_out)
1401 874 : return bs->position;
1402 1142039 : return bs->size;
1403 : }
1404 :
1405 : GF_EXPORT
1406 8445919 : u64 gf_bs_get_position(GF_BitStream *bs)
1407 : {
1408 8445919 : if (bs->cache_write)
1409 1571711 : return bs->position + bs->buffer_written;
1410 6874208 : return bs->position;
1411 : }
1412 :
1413 : GF_EXPORT
1414 1437 : u8 gf_bs_bits_available(GF_BitStream *bs)
1415 : {
1416 1437 : if (bs->size > bs->position) return 8;
1417 88 : if (bs->nbBits < 8) return (8-bs->nbBits);
1418 : return 0;
1419 : }
1420 :
1421 : GF_EXPORT
1422 127592 : void gf_bs_set_eos_callback(GF_BitStream *bs, void (*EndOfStream)(void *par), void *par)
1423 : {
1424 127592 : bs->EndOfStream = EndOfStream;
1425 127592 : bs->par = par;
1426 127592 : }
1427 :
1428 :
1429 : GF_EXPORT
1430 58634 : u64 gf_bs_read_u64_le(GF_BitStream *bs)
1431 : {
1432 : u64 ret, v;
1433 58634 : ret = gf_bs_read_int(bs, 8);
1434 58634 : v = gf_bs_read_int(bs, 8);
1435 58634 : v<<=8;
1436 58634 : ret |= v;
1437 58634 : v = gf_bs_read_int(bs, 8);
1438 58634 : v<<=16;
1439 58634 : ret |= v;
1440 58634 : v = gf_bs_read_int(bs, 8);
1441 58634 : v<<=24;
1442 58634 : ret |= v;
1443 58634 : v = gf_bs_read_int(bs, 8);
1444 58634 : v<<=32;
1445 58634 : ret |= v;
1446 58634 : v = gf_bs_read_int(bs, 8);
1447 58634 : v<<=40;
1448 58634 : ret |= v;
1449 58634 : v = gf_bs_read_int(bs, 8);
1450 58634 : v<<=48;
1451 58634 : ret |= v;
1452 58634 : v = gf_bs_read_int(bs, 8);
1453 58634 : v<<=56;
1454 58634 : ret |= v;
1455 58634 : return ret;
1456 : }
1457 :
1458 : GF_EXPORT
1459 58777 : u32 gf_bs_read_u32_le(GF_BitStream *bs)
1460 : {
1461 : u32 ret, v;
1462 58777 : ret = gf_bs_read_int(bs, 8);
1463 58777 : v = gf_bs_read_int(bs, 8);
1464 58777 : v<<=8;
1465 58777 : ret |= v;
1466 58777 : v = gf_bs_read_int(bs, 8);
1467 58777 : v<<=16;
1468 58777 : ret |= v;
1469 58777 : v = gf_bs_read_int(bs, 8);
1470 58777 : v<<=24;
1471 58777 : ret |= v;
1472 58777 : return ret;
1473 : }
1474 :
1475 : GF_EXPORT
1476 113 : u16 gf_bs_read_u16_le(GF_BitStream *bs)
1477 : {
1478 : u32 ret, v;
1479 113 : ret = gf_bs_read_int(bs, 8);
1480 113 : v = gf_bs_read_int(bs, 8);
1481 113 : v<<=8;
1482 113 : ret |= v;
1483 113 : return ret;
1484 : }
1485 :
1486 : GF_EXPORT
1487 1 : void gf_bs_write_u64_le(GF_BitStream *bs, u64 val)
1488 : {
1489 1 : gf_bs_write_int(bs, val & 0xFF, 8);
1490 1 : gf_bs_write_int(bs, (val>>8) & 0xFF, 8);
1491 1 : gf_bs_write_int(bs, (val>>16) & 0xFF, 8);
1492 1 : gf_bs_write_int(bs, (val>>24) & 0xFF, 8);
1493 1 : gf_bs_write_int(bs, (val>>32) & 0xFF, 8);
1494 1 : gf_bs_write_int(bs, (val>>40) & 0xFF, 8);
1495 1 : gf_bs_write_int(bs, (val>>48) & 0xFF, 8);
1496 1 : gf_bs_write_int(bs, (val>>56) & 0xFF, 8);
1497 1 : }
1498 :
1499 : GF_EXPORT
1500 211 : void gf_bs_write_u32_le(GF_BitStream *bs, u32 val)
1501 : {
1502 211 : gf_bs_write_int(bs, val & 0xFF, 8);
1503 211 : gf_bs_write_int(bs, val>>8, 8);
1504 211 : gf_bs_write_int(bs, val>>16, 8);
1505 211 : gf_bs_write_int(bs, val>>24, 8);
1506 211 : }
1507 :
1508 : GF_EXPORT
1509 59 : void gf_bs_write_u16_le(GF_BitStream *bs, u32 val)
1510 : {
1511 59 : gf_bs_write_int(bs, val & 0xFF, 8);
1512 59 : gf_bs_write_int(bs, val>>8, 8);
1513 59 : }
1514 :
1515 : GF_EXPORT
1516 21 : u32 gf_bs_get_bit_offset(GF_BitStream *bs)
1517 : {
1518 21 : if (bs->bsmode==GF_BITSTREAM_READ) return (u32) ( (bs->position - 1) * 8 + bs->nbBits);
1519 0 : return (u32) ( (bs->position ) * 8 + bs->nbBits);
1520 : }
1521 :
1522 : GF_EXPORT
1523 1044109 : u32 gf_bs_get_bit_position(GF_BitStream *bs)
1524 : {
1525 1044109 : return bs->nbBits;
1526 : }
1527 :
1528 : GF_EXPORT
1529 1 : u32 gf_bs_read_vluimsbf5(GF_BitStream *bs)
1530 : {
1531 : u32 nb_words = 0;
1532 1 : while (gf_bs_read_int(bs, 1)) nb_words++;
1533 1 : nb_words++;
1534 1 : return gf_bs_read_int(bs, 4*nb_words);
1535 : }
1536 :
1537 : GF_EXPORT
1538 7685 : void gf_bs_truncate(GF_BitStream *bs)
1539 : {
1540 7685 : bs->size = bs->position;
1541 7685 : }
1542 :
1543 :
1544 : GF_EXPORT
1545 3709 : GF_Err gf_bs_transfer(GF_BitStream *dst, GF_BitStream *src, Bool keep_src)
1546 : {
1547 : u8 *data;
1548 : u32 data_len, written;
1549 :
1550 3709 : data = NULL;
1551 3709 : data_len = 0;
1552 3709 : gf_bs_get_content(src, &data, &data_len);
1553 3709 : if (!data || !data_len)
1554 : {
1555 1 : if (data) {
1556 0 : if (keep_src) {
1557 0 : src->original = data;
1558 0 : src->size = data_len;
1559 : } else {
1560 0 : gf_free(data);
1561 : }
1562 : return GF_IO_ERR;
1563 : }
1564 : return GF_OK;
1565 : }
1566 3708 : written = gf_bs_write_data(dst, data, data_len);
1567 3708 : if (keep_src) {
1568 210 : src->original = data;
1569 210 : src->size = data_len;
1570 : } else {
1571 3498 : gf_free(data);
1572 : }
1573 3708 : if (written<data_len) return GF_IO_ERR;
1574 3708 : return GF_OK;
1575 : }
1576 :
1577 : GF_EXPORT
1578 455 : void gf_bs_flush(GF_BitStream *bs)
1579 : {
1580 455 : if (!bs->stream) return;
1581 1 : if (bs->bsmode != GF_BITSTREAM_FILE_WRITE) return;
1582 :
1583 1 : if (bs->cache_write)
1584 1 : bs_flush_write_cache(bs);
1585 :
1586 1 : gf_fflush(bs->stream);
1587 : }
1588 :
1589 : #if 0 //unused
1590 : /*!
1591 : \brief Reassigns FILE object for stream-based bitstreams
1592 : *
1593 : *Reassigns FILE object for stream-based bitstreams. Automatically sets the stream position to the bitstream position
1594 : \param bs the target bitstream
1595 : \param stream the new stream to assign
1596 : */
1597 : void gf_bs_reassign(GF_BitStream *bs, FILE *stream)
1598 : {
1599 : if (!bs) return;
1600 : switch (bs->bsmode) {
1601 : case GF_BITSTREAM_FILE_WRITE:
1602 : case GF_BITSTREAM_FILE_READ:
1603 : bs->stream = stream;
1604 : if (gf_ftell(stream) != bs->position)
1605 : gf_bs_seek(bs, bs->position);
1606 : break;
1607 : }
1608 : }
1609 : #endif
1610 :
1611 11329 : u64 gf_bs_set_cookie(GF_BitStream *bs, u64 cookie)
1612 : {
1613 : u64 res = 0;
1614 11329 : if (bs) {
1615 11329 : res = bs->cookie;
1616 11329 : bs->cookie = cookie;
1617 : }
1618 11329 : return res;
1619 : }
1620 :
1621 171493 : u64 gf_bs_get_cookie(GF_BitStream *bs)
1622 : {
1623 171493 : if (!bs) return 0;
1624 171493 : return bs->cookie;
1625 : }
1626 :
1627 : GF_EXPORT
1628 3 : GF_Err gf_bs_insert_data(GF_BitStream *bs, u8 *data, u32 size, u64 offset)
1629 : {
1630 : u64 cur_r, cur_w, pos;
1631 : u32 nb_io;
1632 :
1633 3 : if (bs->on_block_out) return GF_BAD_PARAM;
1634 :
1635 3 : pos = bs->position;
1636 3 : nb_io = gf_bs_write_data(bs, data, size);
1637 3 : if (nb_io != size) goto exit;
1638 :
1639 3 : cur_w = bs->position;
1640 3 : gf_bs_seek(bs, pos);
1641 : cur_r = pos;
1642 : pos = cur_w;
1643 3 : while (cur_r > offset) {
1644 : u8 block[8196];
1645 : u32 move_bytes = 8196;
1646 32 : if (cur_r - offset < move_bytes)
1647 2 : move_bytes = (u32) (cur_r - offset);
1648 :
1649 32 : gf_bs_seek(bs, cur_r - move_bytes);
1650 32 : nb_io = gf_bs_read_data(bs, block, move_bytes);
1651 32 : if (nb_io != move_bytes) goto exit;
1652 32 : gf_bs_seek(bs, cur_w - move_bytes);
1653 32 : nb_io = gf_bs_write_data(bs, block, move_bytes);
1654 32 : if (nb_io != move_bytes) goto exit;
1655 : cur_r -= move_bytes;
1656 : cur_w -= move_bytes;
1657 : }
1658 :
1659 3 : gf_bs_seek(bs, offset);
1660 3 : nb_io = gf_bs_write_data(bs, data, size);
1661 3 : if (nb_io != size) goto exit;
1662 :
1663 3 : gf_bs_seek(bs, pos);
1664 3 : return GF_OK;
1665 :
1666 0 : exit:
1667 0 : gf_bs_seek(bs, pos);
1668 0 : return GF_IO_ERR;
1669 : }
1670 :
1671 :
1672 9633 : GF_Err gf_bs_set_logger(GF_BitStream *bs, void (*on_bs_log)(void *udta, const char *field_name, u32 nb_bits, u64 field_val, s32 idx1, s32 idx2, s32 idx3), void *udta)
1673 : {
1674 9633 : if (!bs) return GF_BAD_PARAM;
1675 9633 : bs->on_log = on_bs_log;
1676 9633 : bs->log_udta = udta;
1677 9633 : return GF_OK;
1678 : }
1679 :
1680 : #ifndef GPAC_DISABLE_AVPARSE_LOGS
1681 21076936 : void gf_bs_log_idx(GF_BitStream *bs, u32 nBits, const char *fname, s64 val, s32 idx1, s32 idx2, s32 idx3)
1682 : {
1683 : assert(bs);
1684 21076936 : if (bs->on_log) bs->on_log(bs->log_udta, fname, nBits, val, idx1, idx2, idx3);
1685 21076936 : }
1686 : #endif
1687 :
1688 :
|