1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2010 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 */
30 uint64_t lsmash_bs_get_pos( lsmash_bs_t
*bs
)
35 void lsmash_bs_empty( lsmash_bs_t
*bs
)
39 memset( bs
->data
, 0, bs
->alloc
);
44 void lsmash_bs_free( lsmash_bs_t
*bs
)
54 void lsmash_bs_alloc( lsmash_bs_t
*bs
, uint64_t size
)
58 uint64_t alloc
= size
+ (1<<16);
61 data
= malloc( alloc
);
62 else if( bs
->alloc
< size
)
63 data
= realloc( bs
->data
, alloc
);
76 /*---- bitstream writer ----*/
77 void lsmash_bs_put_byte( lsmash_bs_t
*bs
, uint8_t value
)
79 lsmash_bs_alloc( bs
, bs
->store
+ 1 );
82 bs
->data
[bs
->store
++] = value
;
85 void lsmash_bs_put_bytes( lsmash_bs_t
*bs
, void *value
, uint32_t size
)
89 lsmash_bs_alloc( bs
, bs
->store
+ size
);
92 memcpy( bs
->data
+ bs
->store
, value
, size
);
96 void lsmash_bs_put_be16( lsmash_bs_t
*bs
, uint16_t value
)
98 lsmash_bs_put_byte( bs
, (uint8_t)((value
>>8)&0xff) );
99 lsmash_bs_put_byte( bs
, (uint8_t)(value
&0xff) );
102 void lsmash_bs_put_be24( lsmash_bs_t
*bs
, uint32_t value
)
104 lsmash_bs_put_byte( bs
, (uint8_t)((value
>>16)&0xff) );
105 lsmash_bs_put_be16( bs
, (uint16_t)(value
&0xffff) );
108 void lsmash_bs_put_be32( lsmash_bs_t
*bs
, uint32_t value
)
110 lsmash_bs_put_be16( bs
, (uint16_t)((value
>>16)&0xffff) );
111 lsmash_bs_put_be16( bs
, (uint16_t)(value
&0xffff) );
114 void lsmash_bs_put_be64( lsmash_bs_t
*bs
, uint64_t value
)
116 lsmash_bs_put_be32( bs
, (uint32_t)((value
>>32)&0xffffffff) );
117 lsmash_bs_put_be32( bs
, (uint32_t)(value
&0xffffffff) );
120 void lsmash_bs_put_byte_from_64( lsmash_bs_t
*bs
, uint64_t value
)
122 lsmash_bs_put_byte( bs
, (uint8_t)(value
&0xff) );
125 void lsmash_bs_put_be16_from_64( lsmash_bs_t
*bs
, uint64_t value
)
127 lsmash_bs_put_be16( bs
, (uint16_t)(value
&0xffff) );
130 void lsmash_bs_put_be24_from_64( lsmash_bs_t
*bs
, uint64_t value
)
132 lsmash_bs_put_be24( bs
, (uint32_t)(value
&0xffffff) );
135 void lsmash_bs_put_be32_from_64( lsmash_bs_t
*bs
, uint64_t value
)
137 lsmash_bs_put_be32( bs
, (uint32_t)(value
&0xffffffff) );
140 int lsmash_bs_write_data( lsmash_bs_t
*bs
)
144 if( !bs
->store
|| !bs
->data
)
146 if( bs
->error
|| !bs
->stream
|| fwrite( bs
->data
, 1, bs
->store
, bs
->stream
) != bs
->store
)
148 lsmash_bs_free( bs
);
152 bs
->written
+= bs
->store
;
157 lsmash_bs_t
* lsmash_bs_create( char* filename
)
159 lsmash_bs_t
* bs
= malloc( sizeof(lsmash_bs_t
) );
162 memset( bs
, 0, sizeof(lsmash_bs_t
) );
163 if( filename
&& (bs
->stream
= fopen( filename
, "wb" )) == NULL
)
171 void lsmash_bs_cleanup( lsmash_bs_t
*bs
)
176 fclose( bs
->stream
);
177 lsmash_bs_free( bs
);
181 void* lsmash_bs_export_data( lsmash_bs_t
*bs
, uint32_t* length
)
183 if( !bs
|| !bs
->data
|| bs
->store
== 0 || bs
->error
)
185 void* buf
= malloc( bs
->store
);
188 memcpy( buf
, bs
->data
, bs
->store
);
195 /*---- bitstream reader ----*/
196 uint8_t lsmash_bs_get_byte( lsmash_bs_t
*bs
)
198 if( bs
->error
|| !bs
->data
)
200 if( bs
->pos
+ 1 > bs
->store
)
202 lsmash_bs_free( bs
);
206 return bs
->data
[bs
->pos
++];
209 uint8_t *lsmash_bs_get_bytes( lsmash_bs_t
*bs
, uint32_t size
)
211 if( bs
->error
|| !size
)
213 uint8_t *value
= malloc( size
);
214 if( !value
|| bs
->pos
+ size
> bs
->store
)
216 lsmash_bs_free( bs
);
220 memcpy( value
, bs
->data
+ bs
->pos
, size
);
225 uint16_t lsmash_bs_get_be16( lsmash_bs_t
*bs
)
227 uint16_t value
= lsmash_bs_get_byte( bs
);
228 return (value
<<8) | lsmash_bs_get_byte( bs
);
231 uint32_t lsmash_bs_get_be24( lsmash_bs_t
*bs
)
233 uint32_t value
= lsmash_bs_get_byte( bs
);
234 return (value
<<16) | lsmash_bs_get_be16( bs
);
237 uint32_t lsmash_bs_get_be32( lsmash_bs_t
*bs
)
239 uint32_t value
= lsmash_bs_get_be16( bs
);
240 return (value
<<16) | lsmash_bs_get_be16( bs
);
243 uint64_t lsmash_bs_get_be64( lsmash_bs_t
*bs
)
245 uint64_t value
= lsmash_bs_get_be32( bs
);
246 return (value
<<32) | lsmash_bs_get_be32( bs
);
249 uint64_t lsmash_bs_get_byte_to_64( lsmash_bs_t
*bs
)
251 return lsmash_bs_get_byte( bs
);
254 uint64_t lsmash_bs_get_be16_to_64( lsmash_bs_t
*bs
)
256 return lsmash_bs_get_be16( bs
);
259 uint64_t lsmash_bs_get_be24_to_64( lsmash_bs_t
*bs
)
261 return lsmash_bs_get_be24( bs
);
264 uint64_t lsmash_bs_get_be32_to_64( lsmash_bs_t
*bs
)
266 return lsmash_bs_get_be32( bs
);
269 int lsmash_bs_read_data( lsmash_bs_t
*bs
, uint32_t size
)
275 lsmash_bs_alloc( bs
, bs
->store
+ size
);
276 if( bs
->error
|| !bs
->stream
)
278 lsmash_bs_free( bs
);
282 uint64_t read_size
= fread( bs
->data
+ bs
->store
, 1, size
, bs
->stream
);
283 if( read_size
!= size
&& !feof( bs
->stream
) )
288 bs
->store
+= read_size
;
292 int lsmash_bs_import_data( lsmash_bs_t
*bs
, void* data
, uint32_t length
)
294 if( !bs
|| bs
->error
|| !data
|| length
== 0 )
296 lsmash_bs_alloc( bs
, bs
->store
+ length
);
297 if( bs
->error
|| !bs
->data
) /* means, failed to alloc. */
299 lsmash_bs_free( bs
);
302 memcpy( bs
->data
+ bs
->store
, data
, length
);
308 /*---- bitstream ----*/
309 void lsmash_bits_init( lsmash_bits_t
* bits
, lsmash_bs_t
*bs
)
311 debug_if( !bits
|| !bs
)
318 lsmash_bits_t
* lsmash_bits_create( lsmash_bs_t
*bs
)
322 lsmash_bits_t
* bits
= (lsmash_bits_t
*)malloc( sizeof(lsmash_bits_t
) );
325 lsmash_bits_init( bits
, bs
);
329 #define BITS_IN_BYTE 8
330 void lsmash_bits_put_align( lsmash_bits_t
*bits
)
336 lsmash_bs_put_byte( bits
->bs
, bits
->cache
<< ( BITS_IN_BYTE
- bits
->store
) );
339 void lsmash_bits_get_align( lsmash_bits_t
*bits
)
347 /* Must be used ONLY for bits struct created with isom_create_bits.
348 Otherwise, just free() the bits struct. */
349 void lsmash_bits_cleanup( lsmash_bits_t
*bits
)
356 /* we can change value's type to unsigned int for 64-bit operation if needed. */
357 static inline uint8_t lsmash_bits_mask_lsb8( uint32_t value
, uint32_t width
)
359 return (uint8_t)( value
& ~( ~0U << width
) );
362 /* We can change value's type to unsigned int for 64-bit operation if needed. */
363 void lsmash_bits_put( lsmash_bits_t
*bits
, uint32_t value
, uint32_t width
)
365 debug_if( !bits
|| !width
)
369 if( bits
->store
+ width
< BITS_IN_BYTE
)
371 /* cache can contain all of value's bits. */
372 bits
->cache
<<= width
;
373 bits
->cache
|= lsmash_bits_mask_lsb8( value
, width
);
374 bits
->store
+= width
;
377 /* flush cache with value's some leading bits. */
378 uint32_t free_bits
= BITS_IN_BYTE
- bits
->store
;
379 bits
->cache
<<= free_bits
;
380 bits
->cache
|= lsmash_bits_mask_lsb8( value
>> (width
-= free_bits
), free_bits
);
381 lsmash_bs_put_byte( bits
->bs
, bits
->cache
);
385 /* cache is empty here. */
386 /* byte unit operation. */
387 while( width
> BITS_IN_BYTE
)
388 lsmash_bs_put_byte( bits
->bs
, (uint8_t)(value
>> (width
-= BITS_IN_BYTE
)) );
389 /* bit unit operation for residual. */
392 bits
->cache
= lsmash_bits_mask_lsb8( value
, width
);
397 /* We can change value's type to unsigned int for 64-bit operation if needed. */
398 uint32_t lsmash_bits_get( lsmash_bits_t
*bits
, uint32_t width
)
400 debug_if( !bits
|| !width
)
405 if( bits
->store
>= width
)
407 /* cache contains all of bits required. */
408 bits
->store
-= width
;
409 return lsmash_bits_mask_lsb8( bits
->cache
>> bits
->store
, width
);
411 /* fill value's leading bits with cache's residual. */
412 value
= lsmash_bits_mask_lsb8( bits
->cache
, bits
->store
);
413 width
-= bits
->store
;
417 /* cache is empty here. */
418 /* byte unit operation. */
419 while( width
> BITS_IN_BYTE
)
421 value
<<= BITS_IN_BYTE
;
422 width
-= BITS_IN_BYTE
;
423 value
|= lsmash_bs_get_byte( bits
->bs
);
425 /* bit unit operation for residual. */
428 bits
->cache
= lsmash_bs_get_byte( bits
->bs
);
429 bits
->store
= BITS_IN_BYTE
- width
;
431 value
|= lsmash_bits_mask_lsb8( bits
->cache
>> bits
->store
, width
);
437 bitstream with bytestream for adhoc operation
440 lsmash_bits_t
* lsmash_bits_adhoc_create()
442 lsmash_bs_t
* bs
= lsmash_bs_create( NULL
); /* no file writing */
445 lsmash_bits_t
* bits
= lsmash_bits_create( bs
);
448 lsmash_bs_cleanup( bs
);
454 void lsmash_bits_adhoc_cleanup( lsmash_bits_t
* bits
)
458 lsmash_bs_cleanup( bits
->bs
);
459 lsmash_bits_cleanup( bits
);
462 void* lsmash_bits_export_data( lsmash_bits_t
* bits
, uint32_t* length
)
464 lsmash_bits_put_align( bits
);
465 return lsmash_bs_export_data( bits
->bs
, length
);
468 int lsmash_bits_import_data( lsmash_bits_t
* bits
, void* data
, uint32_t length
)
470 return lsmash_bs_import_data( bits
->bs
, data
, length
);
475 void lsmash_init_entry_list( lsmash_entry_list_t
*list
)
479 list
->last_accessed_entry
= NULL
;
480 list
->last_accessed_number
= 0;
481 list
->entry_count
= 0;
484 lsmash_entry_list_t
*lsmash_create_entry_list( void )
486 lsmash_entry_list_t
*list
= malloc( sizeof(lsmash_entry_list_t
) );
489 lsmash_init_entry_list( list
);
493 int lsmash_add_entry( lsmash_entry_list_t
*list
, void *data
)
497 lsmash_entry_t
*entry
= malloc( sizeof(lsmash_entry_t
) );
501 entry
->prev
= list
->tail
;
504 list
->tail
->next
= entry
;
508 list
->entry_count
+= 1;
512 int lsmash_remove_entry_direct( lsmash_entry_list_t
*list
, lsmash_entry_t
*entry
, void* eliminator
)
518 lsmash_entry_t
*next
= entry
->next
;
519 lsmash_entry_t
*prev
= entry
->prev
;
520 if( entry
== list
->head
)
524 if( entry
== list
->tail
)
529 ((lsmash_entry_data_eliminator
)eliminator
)( entry
->data
);
530 if( entry
== list
->last_accessed_entry
)
533 list
->last_accessed_entry
= next
;
536 list
->last_accessed_entry
= prev
;
537 list
->last_accessed_number
-= 1;
541 list
->last_accessed_entry
= NULL
;
542 list
->last_accessed_number
= 0;
547 /* We can't know the current entry number immediately,
548 * so discard the last accessed entry info because time is wasted to know it. */
549 list
->last_accessed_entry
= NULL
;
550 list
->last_accessed_number
= 0;
553 list
->entry_count
-= 1;
557 int lsmash_remove_entry( lsmash_entry_list_t
*list
, uint32_t entry_number
, void* eliminator
)
559 lsmash_entry_t
*entry
= lsmash_get_entry( list
, entry_number
);
560 return lsmash_remove_entry_direct( list
, entry
, eliminator
);
563 void lsmash_remove_entries( lsmash_entry_list_t
*list
, void* eliminator
)
569 for( lsmash_entry_t
*entry
= list
->head
; entry
; )
571 lsmash_entry_t
*next
= entry
->next
;
573 ((lsmash_entry_data_eliminator
)eliminator
)( entry
->data
);
577 lsmash_init_entry_list( list
);
580 void lsmash_remove_list( lsmash_entry_list_t
*list
, void* eliminator
)
584 lsmash_remove_entries( list
, eliminator
);
588 lsmash_entry_t
*lsmash_get_entry( lsmash_entry_list_t
*list
, uint32_t entry_number
)
590 if( !list
|| !entry_number
|| entry_number
> list
->entry_count
)
593 lsmash_entry_t
*entry
= NULL
;
594 if( list
->last_accessed_entry
)
596 if( entry_number
== list
->last_accessed_number
)
597 entry
= list
->last_accessed_entry
;
598 else if( entry_number
== list
->last_accessed_number
+ 1 )
599 entry
= list
->last_accessed_entry
->next
;
600 else if( entry_number
== list
->last_accessed_number
- 1 )
601 entry
= list
->last_accessed_entry
->prev
;
609 if( entry_number
<= (list
->entry_count
>> 1) )
611 /* Look for from the head. */
612 uint32_t distance_plus_one
= entry_number
;
613 for( entry
= list
->head
; entry
&& --distance_plus_one
; entry
= entry
->next
);
617 /* Look for from the tail. */
618 uint32_t distance
= list
->entry_count
- entry_number
;
619 for( entry
= list
->tail
; entry
&& distance
--; entry
= entry
->prev
);
624 list
->last_accessed_entry
= entry
;
625 list
->last_accessed_number
= entry_number
;
630 void *lsmash_get_entry_data( lsmash_entry_list_t
*list
, uint32_t entry_number
)
632 lsmash_entry_t
*entry
= lsmash_get_entry( list
, entry_number
);
633 return entry
? entry
->data
: NULL
;
638 double lsmash_fixed2double( uint64_t value
, int frac_width
)
640 return value
/ (double)(1ULL << frac_width
);
643 float lsmash_int2float32( uint32_t value
)
645 return (union {uint32_t i
; float f
;}){value
}.f
;
648 double lsmash_int2float64( uint64_t value
)
650 return (union {uint64_t i
; double d
;}){value
}.d
;
654 /*---- allocator ----*/
655 void *lsmash_memdup( void *src
, size_t size
)
659 void *dst
= malloc( size
);
662 memcpy( dst
, src
, size
);