1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2010-2014 L-SMASH project
6 * Authors: Takashi Hirata <silverfilain@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 void lsmash_bits_init( lsmash_bits_t
*bits
, lsmash_bs_t
*bs
)
27 debug_if( !bits
|| !bs
)
34 lsmash_bits_t
*lsmash_bits_create( lsmash_bs_t
*bs
)
38 lsmash_bits_t
*bits
= (lsmash_bits_t
*)lsmash_malloc( sizeof(lsmash_bits_t
) );
41 lsmash_bits_init( bits
, bs
);
45 /* Must be used ONLY for bits struct created with isom_create_bits.
46 * Otherwise, just lsmash_free() the bits struct. */
47 void lsmash_bits_cleanup( lsmash_bits_t
*bits
)
54 void lsmash_bits_empty( lsmash_bits_t
*bits
)
58 lsmash_bs_empty( bits
->bs
);
63 #define BITS_IN_BYTE 8
64 void lsmash_bits_put_align( lsmash_bits_t
*bits
)
70 lsmash_bs_put_byte( bits
->bs
, bits
->cache
<< ( BITS_IN_BYTE
- bits
->store
) );
73 void lsmash_bits_get_align( lsmash_bits_t
*bits
)
81 /* we can change value's type to unsigned int for 64-bit operation if needed. */
82 static inline uint8_t lsmash_bits_mask_lsb8( uint32_t value
, uint32_t width
)
84 return (uint8_t)( value
& ~( ~0U << width
) );
87 void lsmash_bits_put( lsmash_bits_t
*bits
, uint32_t width
, uint64_t value
)
89 debug_if( !bits
|| !width
)
93 if( bits
->store
+ width
< BITS_IN_BYTE
)
95 /* cache can contain all of value's bits. */
96 bits
->cache
<<= width
;
97 bits
->cache
|= lsmash_bits_mask_lsb8( value
, width
);
101 /* flush cache with value's some leading bits. */
102 uint32_t free_bits
= BITS_IN_BYTE
- bits
->store
;
103 bits
->cache
<<= free_bits
;
104 bits
->cache
|= lsmash_bits_mask_lsb8( value
>> (width
-= free_bits
), free_bits
);
105 lsmash_bs_put_byte( bits
->bs
, bits
->cache
);
109 /* cache is empty here. */
110 /* byte unit operation. */
111 while( width
> BITS_IN_BYTE
)
112 lsmash_bs_put_byte( bits
->bs
, (uint8_t)(value
>> (width
-= BITS_IN_BYTE
)) );
113 /* bit unit operation for residual. */
116 bits
->cache
= lsmash_bits_mask_lsb8( value
, width
);
121 uint64_t lsmash_bits_get( lsmash_bits_t
*bits
, uint32_t width
)
123 debug_if( !bits
|| !width
)
128 if( bits
->store
>= width
)
130 /* cache contains all of bits required. */
131 bits
->store
-= width
;
132 return lsmash_bits_mask_lsb8( bits
->cache
>> bits
->store
, width
);
134 /* fill value's leading bits with cache's residual. */
135 value
= lsmash_bits_mask_lsb8( bits
->cache
, bits
->store
);
136 width
-= bits
->store
;
140 /* cache is empty here. */
141 /* byte unit operation. */
142 while( width
> BITS_IN_BYTE
)
144 value
<<= BITS_IN_BYTE
;
145 width
-= BITS_IN_BYTE
;
146 value
|= lsmash_bs_get_byte( bits
->bs
);
148 /* bit unit operation for residual. */
151 bits
->cache
= lsmash_bs_get_byte( bits
->bs
);
152 bits
->store
= BITS_IN_BYTE
- width
;
154 value
|= lsmash_bits_mask_lsb8( bits
->cache
>> bits
->store
, width
);
159 void *lsmash_bits_export_data( lsmash_bits_t
*bits
, uint32_t *length
)
161 lsmash_bits_put_align( bits
);
162 return lsmash_bs_export_data( bits
->bs
, length
);
165 int lsmash_bits_import_data( lsmash_bits_t
*bits
, void *data
, uint32_t length
)
167 return lsmash_bs_import_data( bits
->bs
, data
, length
);
171 bitstream with bytestream for adhoc operation
174 lsmash_bits_t
*lsmash_bits_adhoc_create()
176 lsmash_bs_t
*bs
= lsmash_bs_create();
179 lsmash_bits_t
*bits
= lsmash_bits_create( bs
);
182 lsmash_bs_cleanup( bs
);
188 void lsmash_bits_adhoc_cleanup( lsmash_bits_t
*bits
)
192 lsmash_bs_cleanup( bits
->bs
);
193 lsmash_bits_cleanup( bits
);