AMR importer: Apply refined bytestream reader.
[L-SMASH.git] / common / bstream.h
blob3e14e4db55e9282599e454ee906c214a87f2ac86
1 /*****************************************************************************
2 * bstream.h
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 /*---- bytestream ----*/
24 #define BS_MAX_DEFAULT_READ_SIZE (4 * 1024 * 1024)
26 typedef struct
28 int unseekable; /* If set to 1, the buffer is unseekable. */
29 int internal; /* If set to 1, the buffer is allocated on heap internally.
30 * The pointer to the buffer shall not be changed by any method other than internal allocation. */
31 uint8_t *data; /* the pointer to the buffer for reading/writing */
32 size_t store; /* valid data size on the buffer */
33 size_t alloc; /* total buffer size including invalid area */
34 size_t pos; /* the data position on the buffer to be read next */
35 size_t max_size; /* the maximum number of bytes for reading from the stream at one time */
36 uint64_t count; /* counter for arbitrary usage */
37 } lsmash_buffer_t;
39 typedef struct
41 void *stream; /* I/O stream */
42 uint8_t eof; /* If set to 1, the stream reached EOF. */
43 uint8_t eob; /* if set to 1, we cannot read more bytes from the stream and the buffer until any seek. */
44 uint8_t error; /* If set to 1, any error is detected. */
45 uint8_t unseekable; /* If set to 1, the stream is unseekable. */
46 uint64_t written; /* the number of bytes written into 'stream' already */
47 uint64_t offset; /* the current position in the 'stream'
48 * the number of bytes from the beginning */
49 lsmash_buffer_t buffer;
50 int (*read) ( void *opaque, uint8_t *buf, int size );
51 int (*write)( void *opaque, uint8_t *buf, int size );
52 int64_t (*seek) ( void *opaque, int64_t offset, int whence );
53 } lsmash_bs_t;
55 static inline void lsmash_bs_reset_counter( lsmash_bs_t *bs )
57 bs->buffer.count = 0;
60 static inline uint64_t lsmash_bs_count( lsmash_bs_t *bs )
62 return bs->buffer.count;
65 static inline uint64_t lsmash_bs_get_remaining_buffer_size( lsmash_bs_t *bs )
67 assert( bs->buffer.store >= bs->buffer.pos );
68 return bs->buffer.store - bs->buffer.pos;
71 static inline uint8_t *lsmash_bs_get_buffer_data( lsmash_bs_t *bs )
73 return bs->buffer.data + (uintptr_t)bs->buffer.pos;
76 static inline uint8_t *lsmash_bs_get_buffer_data_start( lsmash_bs_t *bs )
78 return bs->buffer.data;
81 static inline uint8_t *lsmash_bs_get_buffer_data_end( lsmash_bs_t *bs )
83 return bs->buffer.data + (uintptr_t)bs->buffer.store;
86 static inline uint64_t lsmash_bs_get_pos( lsmash_bs_t *bs )
88 return bs->buffer.pos;
91 static inline uint64_t lsmash_bs_get_stream_pos( lsmash_bs_t *bs )
93 assert( bs->buffer.store <= bs->offset );
94 return bs->offset - lsmash_bs_get_remaining_buffer_size( bs );
97 static inline size_t lsmash_bs_get_valid_data_size( lsmash_bs_t *bs )
99 return bs->buffer.store;
102 lsmash_bs_t *lsmash_bs_create( void );
103 void lsmash_bs_cleanup( lsmash_bs_t *bs );
104 int lsmash_bs_set_empty_stream( lsmash_bs_t *bs, uint8_t *data, size_t size );
105 void lsmash_bs_empty( lsmash_bs_t *bs );
106 int64_t lsmash_bs_write_seek( lsmash_bs_t *bs, int64_t offset, int whence );
107 int64_t lsmash_bs_read_seek( lsmash_bs_t *bs, int64_t offset, int whence );
109 /*---- bytestream writer ----*/
110 void lsmash_bs_put_byte( lsmash_bs_t *bs, uint8_t value );
111 void lsmash_bs_put_bytes( lsmash_bs_t *bs, uint32_t size, void *value );
112 void lsmash_bs_put_be16( lsmash_bs_t *bs, uint16_t value );
113 void lsmash_bs_put_be24( lsmash_bs_t *bs, uint32_t value );
114 void lsmash_bs_put_be32( lsmash_bs_t *bs, uint32_t value );
115 void lsmash_bs_put_be64( lsmash_bs_t *bs, uint64_t value );
116 void lsmash_bs_put_byte_from_64( lsmash_bs_t *bs, uint64_t value );
117 void lsmash_bs_put_be16_from_64( lsmash_bs_t *bs, uint64_t value );
118 void lsmash_bs_put_be24_from_64( lsmash_bs_t *bs, uint64_t value );
119 void lsmash_bs_put_be32_from_64( lsmash_bs_t *bs, uint64_t value );
120 void lsmash_bs_put_le16( lsmash_bs_t *bs, uint16_t value );
121 void lsmash_bs_put_le32( lsmash_bs_t *bs, uint32_t value );
122 int lsmash_bs_flush_buffer( lsmash_bs_t *bs );
123 int lsmash_bs_write_data( lsmash_bs_t *bs, uint8_t *buf, size_t size );
124 void *lsmash_bs_export_data( lsmash_bs_t *bs, uint32_t *length );
126 /*---- bytestream reader ----*/
127 uint8_t lsmash_bs_show_byte( lsmash_bs_t *bs, uint32_t offset );
128 uint16_t lsmash_bs_show_be16( lsmash_bs_t *bs, uint32_t offset );
129 uint32_t lsmash_bs_show_be24( lsmash_bs_t *bs, uint32_t offset );
130 uint32_t lsmash_bs_show_be32( lsmash_bs_t *bs, uint32_t offset );
131 uint64_t lsmash_bs_show_be64( lsmash_bs_t *bs, uint32_t offset );
132 uint8_t lsmash_bs_get_byte( lsmash_bs_t *bs );
133 void lsmash_bs_skip_bytes( lsmash_bs_t *bs, uint32_t size );
134 void lsmash_bs_skip_bytes_64( lsmash_bs_t *bs, uint64_t size );
135 uint8_t *lsmash_bs_get_bytes( lsmash_bs_t *bs, uint32_t size );
136 int64_t lsmash_bs_get_bytes_ex( lsmash_bs_t *bs, uint32_t size, uint8_t *value );
137 uint16_t lsmash_bs_get_be16( lsmash_bs_t *bs );
138 uint32_t lsmash_bs_get_be24( lsmash_bs_t *bs );
139 uint32_t lsmash_bs_get_be32( lsmash_bs_t *bs );
140 uint64_t lsmash_bs_get_be64( lsmash_bs_t *bs );
141 uint64_t lsmash_bs_get_byte_to_64( lsmash_bs_t *bs );
142 uint64_t lsmash_bs_get_be16_to_64( lsmash_bs_t *bs );
143 uint64_t lsmash_bs_get_be24_to_64( lsmash_bs_t *bs );
144 uint64_t lsmash_bs_get_be32_to_64( lsmash_bs_t *bs );
145 int lsmash_bs_read( lsmash_bs_t *bs, uint32_t size );
146 int lsmash_bs_read_data( lsmash_bs_t *bs, uint8_t *buf, size_t *size );
147 int lsmash_bs_import_data( lsmash_bs_t *bs, void *data, uint32_t length );
149 /* Check if the given offset reaches both EOF of the stream and the end of the buffer. */
150 static inline int lsmash_bs_is_end( lsmash_bs_t *bs, uint32_t offset )
152 lsmash_bs_show_byte( bs, offset );
153 return bs->eof && (offset >= lsmash_bs_get_remaining_buffer_size( bs ));
156 /*---- bitstream ----*/
157 typedef struct {
158 lsmash_bs_t* bs;
159 uint8_t store;
160 uint8_t cache;
161 } lsmash_bits_t;
163 void lsmash_bits_init( lsmash_bits_t* bits, lsmash_bs_t *bs );
164 lsmash_bits_t *lsmash_bits_create( lsmash_bs_t *bs );
165 void lsmash_bits_empty( lsmash_bits_t *bits );
166 void lsmash_bits_put_align( lsmash_bits_t *bits );
167 void lsmash_bits_get_align( lsmash_bits_t *bits );
168 void lsmash_bits_cleanup( lsmash_bits_t *bits );
170 /*---- bitstream writer ----*/
171 void lsmash_bits_put( lsmash_bits_t *bits, uint32_t width, uint64_t value );
172 uint64_t lsmash_bits_get( lsmash_bits_t *bits, uint32_t width );
173 lsmash_bits_t *lsmash_bits_adhoc_create();
174 void lsmash_bits_adhoc_cleanup( lsmash_bits_t *bits );
175 void* lsmash_bits_export_data( lsmash_bits_t *bits, uint32_t *length );
176 int lsmash_bits_import_data( lsmash_bits_t *bits, void *data, uint32_t length );
178 /*---- basic I/O ----*/
179 int lsmash_fread_wrapper( void *opaque, uint8_t *buf, int size );
180 int lsmash_fwrite_wrapper( void *opaque, uint8_t *buf, int size );
181 int64_t lsmash_fseek_wrapper( void *opaque, int64_t offset, int whence );
183 /*---- multiple buffers ----*/
184 typedef struct
186 uint32_t number_of_buffers;
187 uint32_t buffer_size;
188 void *buffers;
189 } lsmash_multiple_buffers_t;
191 lsmash_multiple_buffers_t *lsmash_create_multiple_buffers( uint32_t number_of_buffers, uint32_t buffer_size );
192 void *lsmash_withdraw_buffer( lsmash_multiple_buffers_t *multiple_buffer, uint32_t buffer_number );
193 lsmash_multiple_buffers_t *lsmash_resize_multiple_buffers( lsmash_multiple_buffers_t *multiple_buffer, uint32_t buffer_size );
194 void lsmash_destroy_multiple_buffers( lsmash_multiple_buffers_t *multiple_buffer );
196 typedef enum
198 LSMASH_STREAM_BUFFERS_TYPE_NONE = 0,
199 LSMASH_STREAM_BUFFERS_TYPE_FILE, /* -> FILE */
200 LSMASH_STREAM_BUFFERS_TYPE_DATA_STRING, /* -> lsmash_data_string_handler_t */
201 } lsmash_stream_buffers_type;
203 typedef struct lsmash_stream_buffers_tag lsmash_stream_buffers_t;
204 struct lsmash_stream_buffers_tag
206 lsmash_stream_buffers_type type;
207 void *stream;
208 lsmash_multiple_buffers_t *bank;
209 uint8_t *start;
210 uint8_t *end;
211 uint8_t *pos;
212 size_t (*update)( lsmash_stream_buffers_t *, uint32_t );
213 int no_more_read;
216 typedef struct
218 uint8_t *data;
219 uint32_t data_length;
220 uint32_t remainder_length;
221 uint32_t consumed_length; /* overall consumed length */
222 } lsmash_data_string_handler_t;
224 void lsmash_stream_buffers_setup( lsmash_stream_buffers_t *sb, lsmash_stream_buffers_type type, void *stream );
225 void lsmash_stream_buffers_cleanup( lsmash_stream_buffers_t *sb ); /* 'type' and 'stream' are not touched. */
226 size_t lsmash_stream_buffers_update( lsmash_stream_buffers_t *sb, uint32_t anticipation_bytes );
227 int lsmash_stream_buffers_is_eos( lsmash_stream_buffers_t *sb );
228 uint32_t lsmash_stream_buffers_get_buffer_size( lsmash_stream_buffers_t *sb );
229 size_t lsmash_stream_buffers_get_valid_size( lsmash_stream_buffers_t *sb );
230 uint8_t lsmash_stream_buffers_get_byte( lsmash_stream_buffers_t *sb );
231 void lsmash_stream_buffers_seek( lsmash_stream_buffers_t *sb, intptr_t offset, int whence );
232 void lsmash_stream_buffers_set_pos( lsmash_stream_buffers_t *sb, uint8_t *pos );
233 uint8_t *lsmash_stream_buffers_get_pos( lsmash_stream_buffers_t *sb );
234 size_t lsmash_stream_buffers_get_offset( lsmash_stream_buffers_t *sb );
235 size_t lsmash_stream_buffers_get_remainder( lsmash_stream_buffers_t *sb );
236 size_t lsmash_stream_buffers_read( lsmash_stream_buffers_t *sb, size_t read_size );
237 void lsmash_stream_buffers_memcpy( uint8_t *data, lsmash_stream_buffers_t *sb, size_t size );
238 void lsmash_data_string_copy( lsmash_stream_buffers_t *sb, lsmash_data_string_handler_t *dsh, size_t size, uint32_t pos );
240 /*---- memory writers ----*/
241 #define LSMASH_SET_BYTE( p, x ) \
242 do \
244 ((uint8_t *)(p))[0] = (x); \
245 } while( 0 )
246 #define LSMASH_SET_BE16( p, x ) \
247 do \
249 ((uint8_t *)(p))[0] = (x) >> 8; \
250 ((uint8_t *)(p))[1] = (x); \
251 } while( 0 )
252 #define LSMASH_SET_BE24( p, x ) \
253 do \
255 ((uint8_t *)(p))[0] = (x) >> 16; \
256 ((uint8_t *)(p))[1] = (x) >> 8; \
257 ((uint8_t *)(p))[2] = (x); \
258 } while( 0 )
259 #define LSMASH_SET_BE32( p, x ) \
260 do \
262 ((uint8_t *)(p))[0] = (x) >> 24; \
263 ((uint8_t *)(p))[1] = (x) >> 16; \
264 ((uint8_t *)(p))[2] = (x) >> 8; \
265 ((uint8_t *)(p))[3] = (x); \
266 } while( 0 )
267 #define LSMASH_SET_BE64( p, x ) \
268 do \
270 ((uint8_t *)(p))[0] = (x) >> 56; \
271 ((uint8_t *)(p))[1] = (x) >> 48; \
272 ((uint8_t *)(p))[2] = (x) >> 40; \
273 ((uint8_t *)(p))[3] = (x) >> 32; \
274 ((uint8_t *)(p))[4] = (x) >> 24; \
275 ((uint8_t *)(p))[5] = (x) >> 16; \
276 ((uint8_t *)(p))[6] = (x) >> 8; \
277 ((uint8_t *)(p))[7] = (x); \
278 } while( 0 )
279 #define LSMASH_SET_LE16( p, x ) \
280 do \
282 ((uint8_t *)(p))[0] = (x); \
283 ((uint8_t *)(p))[1] = (x) >> 8; \
284 } while( 0 )
285 #define LSMASH_SET_LE32( p, x ) \
286 do \
288 ((uint8_t *)(p))[0] = (x); \
289 ((uint8_t *)(p))[1] = (x) >> 8; \
290 ((uint8_t *)(p))[2] = (x) >> 16; \
291 ((uint8_t *)(p))[3] = (x) >> 24; \
292 } while( 0 )
294 /*---- memory readers ----*/
295 #define LSMASH_GET_BYTE( p ) \
296 (((const uint8_t *)(p))[0])
297 #define LSMASH_GET_BE16( p ) \
298 (((uint16_t)((const uint8_t *)(p))[0] << 8) \
299 | ((uint16_t)((const uint8_t *)(p))[1]))
300 #define LSMASH_GET_BE24( p ) \
301 (((uint32_t)((const uint8_t *)(p))[0] << 16) \
302 | ((uint32_t)((const uint8_t *)(p))[1] << 8) \
303 | ((uint32_t)((const uint8_t *)(p))[2]))
304 #define LSMASH_GET_BE32( p ) \
305 (((uint32_t)((const uint8_t *)(p))[0] << 24) \
306 | ((uint32_t)((const uint8_t *)(p))[1] << 16) \
307 | ((uint32_t)((const uint8_t *)(p))[2] << 8) \
308 | ((uint32_t)((const uint8_t *)(p))[3]))
309 #define LSMASH_GET_BE64( p ) \
310 (((uint64_t)((const uint8_t *)(p))[0] << 56) \
311 | ((uint64_t)((const uint8_t *)(p))[1] << 48) \
312 | ((uint64_t)((const uint8_t *)(p))[2] << 40) \
313 | ((uint64_t)((const uint8_t *)(p))[3] << 32) \
314 | ((uint64_t)((const uint8_t *)(p))[4] << 24) \
315 | ((uint64_t)((const uint8_t *)(p))[5] << 16) \
316 | ((uint64_t)((const uint8_t *)(p))[6] << 8) \
317 | ((uint64_t)((const uint8_t *)(p))[7]))
318 #define LSMASH_GET_LE16( p ) \
319 (((uint16_t)((const uint8_t *)(p))[0]) \
320 | ((uint16_t)((const uint8_t *)(p))[1] << 8))
321 #define LSMASH_GET_LE32( p ) \
322 (((uint32_t)((const uint8_t *)(p))[0]) \
323 | ((uint32_t)((const uint8_t *)(p))[1] << 8) \
324 | ((uint32_t)((const uint8_t *)(p))[2] << 16) \
325 | ((uint32_t)((const uint8_t *)(p))[3] << 24))