bstream: Utilize meaningful error values.
[L-SMASH.git] / common / bstream.c
blob3bf37e767b70419a079102ac645cf43c0d0bbef0
1 /*****************************************************************************
2 * bstream.c
3 *****************************************************************************
4 * Copyright (C) 2010-2014 L-SMASH project
6 * Authors: Yusuke Nakamura <muken.the.vfrmaniac@gmail.com>
8 * Permission to use, copy, modify, and/or distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 *****************************************************************************/
21 /* This file is available under an ISC license. */
23 #include "internal.h" /* must be placed first */
25 #include <string.h>
26 #include <limits.h>
28 lsmash_bs_t *lsmash_bs_create( void )
30 lsmash_bs_t *bs = lsmash_malloc_zero( sizeof(lsmash_bs_t) );
31 if( !bs )
32 return NULL;
33 bs->unseekable = 1;
34 bs->buffer.internal = 1;
35 bs->buffer.max_size = BS_MAX_DEFAULT_READ_SIZE;
36 return bs;
39 static void bs_buffer_free( lsmash_bs_t *bs )
41 if( bs->buffer.internal )
42 lsmash_free( bs->buffer.data );
43 bs->buffer.data = NULL;
44 bs->buffer.alloc = 0;
45 bs->buffer.store = 0;
46 bs->buffer.pos = 0;
49 void lsmash_bs_cleanup( lsmash_bs_t *bs )
51 if( !bs )
52 return;
53 bs_buffer_free( bs );
54 lsmash_free( bs );
57 int lsmash_bs_set_empty_stream( lsmash_bs_t *bs, uint8_t *data, size_t size )
59 if( !bs )
60 return LSMASH_ERR_FUNCTION_PARAM;
61 bs->stream = NULL; /* empty stream */
62 bs->eof = 1; /* unreadable because of empty stream */
63 bs->eob = 0; /* readable on the buffer */
64 bs->error = 0;
65 bs->unseekable = 1; /* only seek on the buffer */
66 bs->written = size; /* behave as if the size of the empty stream is 'size' */
67 bs->offset = size; /* behave as if the poiter of the stream is at the end */
68 bs->buffer.unseekable = 0; /* only seek on the buffer */
69 bs->buffer.internal = 0; /* must not be allocated internally */
70 bs->buffer.data = data;
71 bs->buffer.store = size;
72 bs->buffer.alloc = size;
73 bs->buffer.pos = 0;
74 bs->buffer.max_size = 0; /* make no sense */
75 bs->buffer.count = 0;
76 bs->read = NULL;
77 bs->write = NULL;
78 bs->seek = NULL;
79 return 0;
82 void lsmash_bs_empty( lsmash_bs_t *bs )
84 if( !bs )
85 return;
86 if( bs->buffer.data )
87 memset( bs->buffer.data, 0, bs->buffer.alloc );
88 bs->buffer.store = 0;
89 bs->buffer.pos = 0;
92 static void bs_alloc( lsmash_bs_t *bs, size_t alloc )
94 if( (bs->buffer.alloc >= alloc) || bs->error )
95 return;
96 if( !bs->buffer.internal )
98 /* We cannot re-allocate the memory block. */
99 bs->error = 1;
100 return;
102 alloc += (1 << 16);
103 alloc = LSMASH_MAX( alloc, bs->buffer.max_size );
104 uint8_t *data;
105 if( !bs->buffer.data )
106 data = lsmash_malloc( alloc );
107 else
108 data = lsmash_realloc( bs->buffer.data, alloc );
109 if( !data )
111 bs_buffer_free( bs );
112 bs->error = 1;
113 return;
115 bs->buffer.internal = 1;
116 bs->buffer.data = data;
117 bs->buffer.alloc = alloc;
120 static uint64_t bs_estimate_seek_offset( lsmash_bs_t *bs, int64_t offset, int whence )
122 /* Calculate the offset after the seek. */
123 uint64_t dst_offset;
124 if( whence == SEEK_SET )
126 assert( offset >= 0 );
127 if( bs->written < offset )
128 dst_offset = bs->written;
129 else
130 dst_offset = offset;
132 else if( whence == SEEK_CUR )
134 if( offset < 0 && bs->offset < -offset )
135 dst_offset = 0;
136 else if( offset > 0 && bs->written < bs->offset + offset )
137 dst_offset = bs->written;
138 else
139 dst_offset = bs->offset + offset;
141 else /* if( whence == SEEK_END ) */
143 assert( offset <= 0 );
144 if( bs->written < -offset )
145 dst_offset = 0;
146 else
147 dst_offset = bs->written + offset;
149 return dst_offset;
152 /* TODO: Support offset > INT64_MAX */
153 int64_t lsmash_bs_write_seek( lsmash_bs_t *bs, int64_t offset, int whence )
155 if( bs->unseekable )
156 return LSMASH_ERR_NAMELESS;
157 if( whence != SEEK_SET && whence != SEEK_CUR && whence != SEEK_END )
158 return LSMASH_ERR_FUNCTION_PARAM;
159 /* Try to seek the stream. */
160 int64_t ret = bs->seek( bs->stream, offset, whence );
161 if( ret < 0 )
162 return ret;
163 bs->offset = bs_estimate_seek_offset( bs, offset, whence );
164 bs->eof = 0;
165 bs->eob = 0;
166 return ret;
169 /* TODO: Support offset > INT64_MAX */
170 int64_t lsmash_bs_read_seek( lsmash_bs_t *bs, int64_t offset, int whence )
172 if( whence != SEEK_SET && whence != SEEK_CUR && whence != SEEK_END )
173 return LSMASH_ERR_FUNCTION_PARAM;
174 if( whence == SEEK_CUR )
175 offset -= lsmash_bs_get_remaining_buffer_size( bs );
176 /* Check whether we can seek on the buffer. */
177 if( !bs->buffer.unseekable )
179 assert( bs->offset >= bs->buffer.store );
180 uint64_t dst_offset = bs_estimate_seek_offset( bs, offset, whence );
181 uint64_t offset_s = bs->offset - bs->buffer.store;
182 uint64_t offset_e = bs->offset;
183 if( bs->unseekable || (dst_offset >= offset_s && dst_offset < offset_e) )
185 /* OK, we can. So, seek on the buffer. */
186 bs->buffer.pos = dst_offset - offset_s;
187 bs->eob = 0;
188 return lsmash_bs_get_stream_pos( bs );
191 if( bs->unseekable )
192 return LSMASH_ERR_NAMELESS;
193 /* Try to seek the stream. */
194 int64_t ret = bs->seek( bs->stream, offset, whence );
195 if( ret < 0 )
196 return ret;
197 bs->offset = ret;
198 bs->written = LSMASH_MAX( bs->written, bs->offset );
199 bs->eof = 0;
200 bs->eob = 0;
201 /* The data on the buffer is invalid. */
202 lsmash_bs_empty( bs );
203 return ret;
206 static void bs_dispose_past_data( lsmash_bs_t *bs )
208 /* Move remainder bytes. */
209 assert( bs->buffer.store >= bs->buffer.pos );
210 size_t remainder = lsmash_bs_get_remaining_buffer_size( bs );
211 if( bs->buffer.pos && remainder )
212 memmove( lsmash_bs_get_buffer_data_start( bs ), lsmash_bs_get_buffer_data( bs ), remainder );
213 bs->buffer.store = remainder;
214 bs->buffer.pos = 0;
217 /*---- bitstream writer ----*/
218 void lsmash_bs_put_byte( lsmash_bs_t *bs, uint8_t value )
220 if( bs->buffer.internal
221 || bs->buffer.data )
223 bs_alloc( bs, bs->buffer.store + 1 );
224 if( bs->error )
225 return;
226 bs->buffer.data[ bs->buffer.store ] = value;
228 ++ bs->buffer.store;
231 void lsmash_bs_put_bytes( lsmash_bs_t *bs, uint32_t size, void *value )
233 if( size == 0 || !value )
234 return;
235 if( bs->buffer.internal
236 || bs->buffer.data )
238 bs_alloc( bs, bs->buffer.store + size );
239 if( bs->error )
240 return;
241 memcpy( lsmash_bs_get_buffer_data_end( bs ), value, size );
243 bs->buffer.store += size;
246 void lsmash_bs_put_be16( lsmash_bs_t *bs, uint16_t value )
248 lsmash_bs_put_byte( bs, value >> 8 );
249 lsmash_bs_put_byte( bs, value );
252 void lsmash_bs_put_be24( lsmash_bs_t *bs, uint32_t value )
254 lsmash_bs_put_byte( bs, value >> 16 );
255 lsmash_bs_put_be16( bs, value );
258 void lsmash_bs_put_be32( lsmash_bs_t *bs, uint32_t value )
260 lsmash_bs_put_be16( bs, value >> 16 );
261 lsmash_bs_put_be16( bs, value );
264 void lsmash_bs_put_be64( lsmash_bs_t *bs, uint64_t value )
266 lsmash_bs_put_be32( bs, value >> 32 );
267 lsmash_bs_put_be32( bs, value );
270 void lsmash_bs_put_byte_from_64( lsmash_bs_t *bs, uint64_t value )
272 lsmash_bs_put_byte( bs, value );
275 void lsmash_bs_put_be16_from_64( lsmash_bs_t *bs, uint64_t value )
277 lsmash_bs_put_be16( bs, value );
280 void lsmash_bs_put_be24_from_64( lsmash_bs_t *bs, uint64_t value )
282 lsmash_bs_put_be24( bs, value );
285 void lsmash_bs_put_be32_from_64( lsmash_bs_t *bs, uint64_t value )
287 lsmash_bs_put_be32( bs, value );
290 void lsmash_bs_put_le16( lsmash_bs_t *bs, uint16_t value )
292 lsmash_bs_put_byte( bs, value );
293 lsmash_bs_put_byte( bs, value >> 8 );
296 void lsmash_bs_put_le32( lsmash_bs_t *bs, uint32_t value )
298 lsmash_bs_put_le16( bs, value );
299 lsmash_bs_put_le16( bs, value >> 16 );
302 int lsmash_bs_flush_buffer( lsmash_bs_t *bs )
304 if( !bs )
305 return LSMASH_ERR_FUNCTION_PARAM;
306 if( bs->buffer.store == 0
307 || (bs->stream && bs->write && !bs->buffer.data) )
308 return 0;
309 if( bs->error
310 || (bs->stream && bs->write && bs->write( bs->stream, lsmash_bs_get_buffer_data_start( bs ), bs->buffer.store ) != bs->buffer.store) )
312 bs_buffer_free( bs );
313 bs->error = 1;
314 return LSMASH_ERR_NAMELESS;
316 if( bs->write )
318 bs->written += bs->buffer.store;
319 bs->offset += bs->buffer.store;
321 bs->buffer.store = 0;
322 return 0;
325 int lsmash_bs_write_data( lsmash_bs_t *bs, uint8_t *buf, size_t size )
327 if( !bs || size > INT_MAX )
328 return LSMASH_ERR_FUNCTION_PARAM;
329 if( !buf || size == 0 )
330 return 0;
331 if( bs->error || !bs->stream )
333 bs_buffer_free( bs );
334 bs->error = 1;
335 return LSMASH_ERR_NAMELESS;
337 int write_size = bs->write( bs->stream, buf, size );
338 bs->written += write_size;
339 bs->offset += write_size;
340 return write_size != size ? LSMASH_ERR_NAMELESS : 0;
343 void *lsmash_bs_export_data( lsmash_bs_t *bs, uint32_t *length )
345 if( !bs || !bs->buffer.data || bs->buffer.store == 0 || bs->error )
346 return NULL;
347 void *buf = lsmash_memdup( lsmash_bs_get_buffer_data_start( bs ), bs->buffer.store );
348 if( !buf )
349 return NULL;
350 if( length )
351 *length = bs->buffer.store;
352 return buf;
354 /*---- ----*/
356 /*---- bitstream reader ----*/
357 static void bs_fill_buffer( lsmash_bs_t *bs )
359 if( bs->eof || bs->error )
360 return;
361 if( !bs->read || !bs->stream || bs->buffer.max_size == 0 )
363 bs->eof = 1;
364 return;
366 if( !bs->buffer.data )
368 bs_alloc( bs, bs->buffer.max_size );
369 if( bs->error )
370 return;
372 /* Read bytes from the stream to fill the buffer. */
373 bs_dispose_past_data( bs );
374 while( bs->buffer.alloc > bs->buffer.store )
376 uint64_t invalid_buffer_size = bs->buffer.alloc - bs->buffer.store;
377 int max_read_size = LSMASH_MIN( invalid_buffer_size, bs->buffer.max_size );
378 int read_size = bs->read( bs->stream, lsmash_bs_get_buffer_data_end( bs ), max_read_size );
379 if( read_size == 0 )
381 bs->eof = 1;
382 return;
384 else if( read_size < 0 )
386 bs->error = 1;
387 return;
389 bs->buffer.unseekable = 0;
390 bs->buffer.store += read_size;
391 bs->offset += read_size;
392 bs->written = LSMASH_MAX( bs->written, bs->offset );
396 uint8_t lsmash_bs_show_byte( lsmash_bs_t *bs, uint32_t offset )
398 if( bs->error )
399 return 0;
400 if( offset >= lsmash_bs_get_remaining_buffer_size( bs ) )
402 bs_fill_buffer( bs );
403 if( bs->error )
404 return 0;
405 if( offset >= lsmash_bs_get_remaining_buffer_size( bs ) )
407 if( bs->eof )
408 /* No more read from both the stream and the buffer. */
409 return 0;
410 /* We need increase the buffer size. */
411 bs_alloc( bs, bs->buffer.pos + offset + 1 );
412 bs_fill_buffer( bs );
413 if( bs->error )
414 return 0;
417 return bs->buffer.data[ bs->buffer.pos + offset ];
420 uint16_t lsmash_bs_show_be16( lsmash_bs_t *bs, uint32_t offset )
422 return ((uint16_t)lsmash_bs_show_byte( bs, offset ) << 8)
423 | ((uint16_t)lsmash_bs_show_byte( bs, offset + 1 ));
426 uint32_t lsmash_bs_show_be24( lsmash_bs_t *bs, uint32_t offset )
428 return ((uint32_t)lsmash_bs_show_byte( bs, offset ) << 16)
429 | ((uint32_t)lsmash_bs_show_byte( bs, offset + 1 ) << 8)
430 | ((uint32_t)lsmash_bs_show_byte( bs, offset + 2 ));
433 uint32_t lsmash_bs_show_be32( lsmash_bs_t *bs, uint32_t offset )
435 return ((uint32_t)lsmash_bs_show_byte( bs, offset ) << 24)
436 | ((uint32_t)lsmash_bs_show_byte( bs, offset + 1 ) << 16)
437 | ((uint32_t)lsmash_bs_show_byte( bs, offset + 2 ) << 8)
438 | ((uint32_t)lsmash_bs_show_byte( bs, offset + 3 ));
441 uint64_t lsmash_bs_show_be64( lsmash_bs_t *bs, uint32_t offset )
443 return ((uint64_t)lsmash_bs_show_byte( bs, offset ) << 56)
444 | ((uint64_t)lsmash_bs_show_byte( bs, offset + 1 ) << 48)
445 | ((uint64_t)lsmash_bs_show_byte( bs, offset + 2 ) << 40)
446 | ((uint64_t)lsmash_bs_show_byte( bs, offset + 3 ) << 32)
447 | ((uint64_t)lsmash_bs_show_byte( bs, offset + 4 ) << 24)
448 | ((uint64_t)lsmash_bs_show_byte( bs, offset + 5 ) << 16)
449 | ((uint64_t)lsmash_bs_show_byte( bs, offset + 6 ) << 8)
450 | ((uint64_t)lsmash_bs_show_byte( bs, offset + 7 ));
453 uint8_t lsmash_bs_get_byte( lsmash_bs_t *bs )
455 if( bs->eob || bs->error )
456 return 0;
457 assert( bs->buffer.pos <= bs->buffer.store );
458 if( bs->buffer.pos == bs->buffer.store )
460 bs_fill_buffer( bs );
461 if( bs->error )
462 return 0;
463 if( bs->buffer.pos == bs->buffer.store && bs->eof )
465 /* No more read from both the stream and the buffer. */
466 bs->eob = 1;
467 return 0;
470 ++ bs->buffer.count; /* increment counter */
471 return bs->buffer.data[ bs->buffer.pos ++ ];
474 void lsmash_bs_skip_bytes( lsmash_bs_t *bs, uint32_t size )
476 if( bs->eob || bs->error || size == 0 )
477 return;
478 uint64_t remainder;
479 uint64_t offset = 0;
480 while( size > lsmash_bs_get_remaining_buffer_size( bs ) )
482 remainder = lsmash_bs_get_remaining_buffer_size( bs );
483 offset += remainder;
484 size -= remainder;
485 bs->buffer.pos = bs->buffer.store;
486 if( bs->eof )
488 /* No more read from both the stream and the buffer. */
489 bs->eob = 1;
490 break;
492 else
494 bs_fill_buffer( bs );
495 if( bs->error )
496 break;
499 remainder = LSMASH_MIN( size, lsmash_bs_get_remaining_buffer_size( bs ) );
500 offset += remainder;
501 bs->buffer.pos += remainder;
502 bs->buffer.count += offset;
505 void lsmash_bs_skip_bytes_64( lsmash_bs_t *bs, uint64_t size )
507 while( size )
509 uint64_t skip_bytes = LSMASH_MIN( size, UINT32_MAX );
510 lsmash_bs_skip_bytes( bs, (uint32_t)skip_bytes );
511 size -= skip_bytes;
512 if( bs->eob )
513 return;
517 static int64_t bs_get_bytes( lsmash_bs_t *bs, uint32_t size, uint8_t *buf )
519 size_t remainder;
520 size_t remain_size = size;
521 uintptr_t offset = 0;
522 while( remain_size > lsmash_bs_get_remaining_buffer_size( bs ) )
524 remainder = lsmash_bs_get_remaining_buffer_size( bs );
525 memcpy( buf + offset, lsmash_bs_get_buffer_data( bs ), remainder );
526 offset += remainder;
527 remain_size -= remainder;
528 bs->buffer.pos = bs->buffer.store;
529 if( bs->eof )
531 /* No more read from both the stream and the buffer. */
532 bs->eob = 1;
533 break;
535 else
537 bs_fill_buffer( bs );
538 if( bs->error )
540 bs->buffer.count += offset;
541 return LSMASH_ERR_NAMELESS;
545 remainder = LSMASH_MIN( remain_size, lsmash_bs_get_remaining_buffer_size( bs ) );
546 memcpy( buf + offset, lsmash_bs_get_buffer_data( bs ), remainder );
547 offset += remainder;
548 bs->buffer.pos += remainder;
549 bs->buffer.count += offset;
550 if( offset < size )
551 memset( buf + offset, 0, size - offset );
552 return (int64_t)offset;
555 uint8_t *lsmash_bs_get_bytes( lsmash_bs_t *bs, uint32_t size )
557 if( bs->eob || bs->error || size == 0 )
558 return NULL;
559 uint8_t *value = lsmash_malloc( size );
560 if( !value )
562 bs->error = 1;
563 return NULL;
565 if( bs_get_bytes( bs, size, value ) < 0 )
567 lsmash_free( value );
568 return NULL;
570 return value;
573 int64_t lsmash_bs_get_bytes_ex( lsmash_bs_t *bs, uint32_t size, uint8_t *value )
575 if( size == 0 )
576 return 0;
577 if( bs->eob || bs->error )
578 return LSMASH_ERR_NAMELESS;
579 return bs_get_bytes( bs, size, value );
582 uint16_t lsmash_bs_get_be16( lsmash_bs_t *bs )
584 uint16_t value = lsmash_bs_get_byte( bs );
585 return (value<<8) | lsmash_bs_get_byte( bs );
588 uint32_t lsmash_bs_get_be24( lsmash_bs_t *bs )
590 uint32_t value = lsmash_bs_get_byte( bs );
591 return (value<<16) | lsmash_bs_get_be16( bs );
594 uint32_t lsmash_bs_get_be32( lsmash_bs_t *bs )
596 uint32_t value = lsmash_bs_get_be16( bs );
597 return (value<<16) | lsmash_bs_get_be16( bs );
600 uint64_t lsmash_bs_get_be64( lsmash_bs_t *bs )
602 uint64_t value = lsmash_bs_get_be32( bs );
603 return (value<<32) | lsmash_bs_get_be32( bs );
606 uint64_t lsmash_bs_get_byte_to_64( lsmash_bs_t *bs )
608 return lsmash_bs_get_byte( bs );
611 uint64_t lsmash_bs_get_be16_to_64( lsmash_bs_t *bs )
613 return lsmash_bs_get_be16( bs );
616 uint64_t lsmash_bs_get_be24_to_64( lsmash_bs_t *bs )
618 return lsmash_bs_get_be24( bs );
621 uint64_t lsmash_bs_get_be32_to_64( lsmash_bs_t *bs )
623 return lsmash_bs_get_be32( bs );
626 int lsmash_bs_read( lsmash_bs_t *bs, uint32_t size )
628 if( !bs || size > INT_MAX )
629 return LSMASH_ERR_FUNCTION_PARAM;
630 if( size == 0 )
631 return 0;
632 bs_alloc( bs, bs->buffer.store + size );
633 if( bs->error || !bs->stream )
635 bs->error = 1;
636 return LSMASH_ERR_NAMELESS;
638 int read_size = bs->read( bs->stream, lsmash_bs_get_buffer_data_end( bs ), size );
639 if( read_size == 0 )
641 bs->eof = 1;
642 return 0;
644 else if( read_size < 0 )
646 bs->error = 1;
647 return LSMASH_ERR_NAMELESS;
649 bs->buffer.store += read_size;
650 bs->offset += read_size;
651 bs->written = LSMASH_MAX( bs->written, bs->offset );
652 return read_size;
655 int lsmash_bs_read_data( lsmash_bs_t *bs, uint8_t *buf, size_t *size )
657 if( !bs || !size || *size > INT_MAX )
658 return LSMASH_ERR_FUNCTION_PARAM;
659 if( !buf || *size == 0 )
660 return 0;
661 if( bs->error || !bs->stream )
663 bs->error = 1;
664 return LSMASH_ERR_NAMELESS;
666 int read_size = bs->read( bs->stream, buf, *size );
667 if( read_size == 0 )
668 bs->eof = 1;
669 else if( read_size < 0 )
671 bs->error = 1;
672 return LSMASH_ERR_NAMELESS;
674 bs->buffer.unseekable = 1;
675 bs->offset += read_size;
676 *size = read_size;
677 bs->written = LSMASH_MAX( bs->written, bs->offset );
678 return 0;
681 int lsmash_bs_import_data( lsmash_bs_t *bs, void *data, uint32_t length )
683 if( !bs || !data || length == 0 )
684 return LSMASH_ERR_FUNCTION_PARAM;
685 if( bs->error )
686 return LSMASH_ERR_NAMELESS;
687 bs_alloc( bs, bs->buffer.store + length );
688 if( bs->error || !bs->buffer.data ) /* means, failed to alloc. */
690 bs_buffer_free( bs );
691 return LSMASH_ERR_NAMELESS;
693 memcpy( lsmash_bs_get_buffer_data_end( bs ), data, length );
694 bs->buffer.store += length;
695 return 0;
697 /*---- ----*/
699 /*---- bitstream ----*/
700 void lsmash_bits_init( lsmash_bits_t *bits, lsmash_bs_t *bs )
702 debug_if( !bits || !bs )
703 return;
704 bits->bs = bs;
705 bits->store = 0;
706 bits->cache = 0;
709 lsmash_bits_t *lsmash_bits_create( lsmash_bs_t *bs )
711 debug_if( !bs )
712 return NULL;
713 lsmash_bits_t *bits = (lsmash_bits_t *)lsmash_malloc( sizeof(lsmash_bits_t) );
714 if( !bits )
715 return NULL;
716 lsmash_bits_init( bits, bs );
717 return bits;
720 void lsmash_bits_empty( lsmash_bits_t *bits )
722 debug_if( !bits )
723 return;
724 lsmash_bs_empty( bits->bs );
725 bits->store = 0;
726 bits->cache = 0;
729 #define BITS_IN_BYTE 8
730 void lsmash_bits_put_align( lsmash_bits_t *bits )
732 debug_if( !bits )
733 return;
734 if( !bits->store )
735 return;
736 lsmash_bs_put_byte( bits->bs, bits->cache << ( BITS_IN_BYTE - bits->store ) );
739 void lsmash_bits_get_align( lsmash_bits_t *bits )
741 debug_if( !bits )
742 return;
743 bits->store = 0;
744 bits->cache = 0;
747 /* Must be used ONLY for bits struct created with isom_create_bits.
748 Otherwise, just lsmash_free() the bits struct. */
749 void lsmash_bits_cleanup( lsmash_bits_t *bits )
751 debug_if( !bits )
752 return;
753 lsmash_free( bits );
756 /* we can change value's type to unsigned int for 64-bit operation if needed. */
757 static inline uint8_t lsmash_bits_mask_lsb8( uint32_t value, uint32_t width )
759 return (uint8_t)( value & ~( ~0U << width ) );
762 void lsmash_bits_put( lsmash_bits_t *bits, uint32_t width, uint64_t value )
764 debug_if( !bits || !width )
765 return;
766 if( bits->store )
768 if( bits->store + width < BITS_IN_BYTE )
770 /* cache can contain all of value's bits. */
771 bits->cache <<= width;
772 bits->cache |= lsmash_bits_mask_lsb8( value, width );
773 bits->store += width;
774 return;
776 /* flush cache with value's some leading bits. */
777 uint32_t free_bits = BITS_IN_BYTE - bits->store;
778 bits->cache <<= free_bits;
779 bits->cache |= lsmash_bits_mask_lsb8( value >> (width -= free_bits), free_bits );
780 lsmash_bs_put_byte( bits->bs, bits->cache );
781 bits->store = 0;
782 bits->cache = 0;
784 /* cache is empty here. */
785 /* byte unit operation. */
786 while( width > BITS_IN_BYTE )
787 lsmash_bs_put_byte( bits->bs, (uint8_t)(value >> (width -= BITS_IN_BYTE)) );
788 /* bit unit operation for residual. */
789 if( width )
791 bits->cache = lsmash_bits_mask_lsb8( value, width );
792 bits->store = width;
796 uint64_t lsmash_bits_get( lsmash_bits_t *bits, uint32_t width )
798 debug_if( !bits || !width )
799 return 0;
800 uint64_t value = 0;
801 if( bits->store )
803 if( bits->store >= width )
805 /* cache contains all of bits required. */
806 bits->store -= width;
807 return lsmash_bits_mask_lsb8( bits->cache >> bits->store, width );
809 /* fill value's leading bits with cache's residual. */
810 value = lsmash_bits_mask_lsb8( bits->cache, bits->store );
811 width -= bits->store;
812 bits->store = 0;
813 bits->cache = 0;
815 /* cache is empty here. */
816 /* byte unit operation. */
817 while( width > BITS_IN_BYTE )
819 value <<= BITS_IN_BYTE;
820 width -= BITS_IN_BYTE;
821 value |= lsmash_bs_get_byte( bits->bs );
823 /* bit unit operation for residual. */
824 if( width )
826 bits->cache = lsmash_bs_get_byte( bits->bs );
827 bits->store = BITS_IN_BYTE - width;
828 value <<= width;
829 value |= lsmash_bits_mask_lsb8( bits->cache >> bits->store, width );
831 return value;
834 /****
835 bitstream with bytestream for adhoc operation
836 ****/
838 lsmash_bits_t* lsmash_bits_adhoc_create()
840 lsmash_bs_t* bs = lsmash_bs_create();
841 if( !bs )
842 return NULL;
843 lsmash_bits_t* bits = lsmash_bits_create( bs );
844 if( !bits )
846 lsmash_bs_cleanup( bs );
847 return NULL;
849 return bits;
852 void lsmash_bits_adhoc_cleanup( lsmash_bits_t* bits )
854 if( !bits )
855 return;
856 lsmash_bs_cleanup( bits->bs );
857 lsmash_bits_cleanup( bits );
860 void* lsmash_bits_export_data( lsmash_bits_t* bits, uint32_t* length )
862 lsmash_bits_put_align( bits );
863 return lsmash_bs_export_data( bits->bs, length );
866 int lsmash_bits_import_data( lsmash_bits_t* bits, void* data, uint32_t length )
868 return lsmash_bs_import_data( bits->bs, data, length );
870 /*---- ----*/
872 /*---- basic I/O ----*/
873 int lsmash_fread_wrapper( void *opaque, uint8_t *buf, int size )
875 int read_size = fread( buf, 1, size, (FILE *)opaque );
876 return ferror( (FILE *)opaque ) ? LSMASH_ERR_NAMELESS : read_size;
879 int lsmash_fwrite_wrapper( void *opaque, uint8_t *buf, int size )
881 return fwrite( buf, 1, size, (FILE *)opaque );
884 int64_t lsmash_fseek_wrapper( void *opaque, int64_t offset, int whence )
886 if( lsmash_fseek( (FILE *)opaque, offset, whence ) != 0 )
887 return LSMASH_ERR_NAMELESS;
888 return lsmash_ftell( (FILE *)opaque );
891 lsmash_multiple_buffers_t *lsmash_create_multiple_buffers( uint32_t number_of_buffers, uint32_t buffer_size )
893 if( (uint64_t)number_of_buffers * buffer_size > UINT32_MAX )
894 return NULL;
895 lsmash_multiple_buffers_t *multiple_buffer = lsmash_malloc( sizeof(lsmash_multiple_buffers_t) );
896 if( !multiple_buffer )
897 return NULL;
898 multiple_buffer->buffers = lsmash_malloc( number_of_buffers * buffer_size );
899 if( !multiple_buffer->buffers )
901 lsmash_free( multiple_buffer );
902 return NULL;
904 multiple_buffer->number_of_buffers = number_of_buffers;
905 multiple_buffer->buffer_size = buffer_size;
906 return multiple_buffer;
909 void *lsmash_withdraw_buffer( lsmash_multiple_buffers_t *multiple_buffer, uint32_t buffer_number )
911 if( !multiple_buffer || !buffer_number || buffer_number > multiple_buffer->number_of_buffers )
912 return NULL;
913 return (uint8_t *)multiple_buffer->buffers + (buffer_number - 1) * multiple_buffer->buffer_size;
916 lsmash_multiple_buffers_t *lsmash_resize_multiple_buffers( lsmash_multiple_buffers_t *multiple_buffer, uint32_t buffer_size )
918 if( !multiple_buffer )
919 return NULL;
920 if( buffer_size == multiple_buffer->buffer_size )
921 return multiple_buffer;
922 if( (uint64_t)multiple_buffer->number_of_buffers * buffer_size > UINT32_MAX )
923 return NULL;
924 uint8_t *temp;
925 if( buffer_size > multiple_buffer->buffer_size )
927 temp = lsmash_realloc( multiple_buffer->buffers, multiple_buffer->number_of_buffers * buffer_size );
928 if( !temp )
929 return NULL;
930 for( uint32_t i = multiple_buffer->number_of_buffers - 1; i ; i-- )
931 memmove( temp + buffer_size, temp + i * multiple_buffer->buffer_size, multiple_buffer->buffer_size );
933 else
935 for( uint32_t i = 1; i < multiple_buffer->number_of_buffers; i++ )
936 memmove( (uint8_t *)multiple_buffer->buffers + buffer_size,
937 (uint8_t *)multiple_buffer->buffers + i * multiple_buffer->buffer_size,
938 multiple_buffer->buffer_size );
939 temp = lsmash_realloc( multiple_buffer->buffers, multiple_buffer->number_of_buffers * buffer_size );
940 if( !temp )
941 return NULL;
943 multiple_buffer->buffers = temp;
944 multiple_buffer->buffer_size = buffer_size;
945 return multiple_buffer;
948 void lsmash_destroy_multiple_buffers( lsmash_multiple_buffers_t *multiple_buffer )
950 if( !multiple_buffer )
951 return;
952 lsmash_free( multiple_buffer->buffers );
953 lsmash_free( multiple_buffer );