#define MARKER_CHAR 0xff
#define STUFF_MARKER 0x00
-void init_bit_source(struct bit_source* source, input_func_t* input_func, void* userdata)
+void init_bit_source(struct bit_source* source, input_func_t* input_func,
+ unsigned padding_bytes, void* userdata)
{
memset(source, 0, sizeof(*source));
source->bytes = (uint8_t*)malloc(BYTERESERVOIR_SIZE);
+ source->byte_read_ptr = source->bytes;
source->input_func = input_func;
+ source->padding_bytes_available = padding_bytes;
source->userdata = userdata;
}
void possibly_refill_slow_path(struct bit_source* source, unsigned num_bits)
{
- // First, make sure there's stuff in the byte reservoir if we can.
+ // First, move out the data we already read.
assert(source->bytes_available <= BYTERESERVOIR_SIZE);
+ assert(source->byte_read_ptr >= source->bytes);
+ memmove(source->bytes, source->byte_read_ptr, source->bytes_available);
+ source->byte_read_ptr = source->bytes;
+ // Then, make sure there's stuff in the byte reservoir if we can.
// Read data from the source until we have enough to satisfy the request.
while (source->bits_available + 8 * source->bytes_available < num_bits) {
const size_t bytes_to_read = BYTERESERVOIR_SIZE - source->bytes_available;
exit(1);
}
if (bytes_read == 0) {
- fprintf(stderr, "Premature EOF\n");
- exit(1);
+ source->source_eof = true;
+ if (source->padding_bytes_available > 0) {
+ unsigned padding_to_add = source->padding_bytes_available;
+ if (padding_to_add > bytes_to_read) {
+ padding_to_add = bytes_to_read;
+ }
+ memset(source->bytes + source->bytes_available, 0, padding_to_add);
+ source->padding_bytes_available -= padding_to_add;
+ source->bytes_available += padding_to_add;
+ } else {
+ fprintf(stderr, "Premature EOF\n");
+ exit(1);
+ }
+ } else {
+ source->bytes_available += bytes_read;
}
-
- source->bytes_available += bytes_read;
}
// Fill the bit reservoir one by one byte until we have enough.
while (source->bits_available < num_bits) {
assert(source->bytes_available > 0);
assert(source->bits_available + 8 <= BITRESERVOIR_SIZE);
- uint8_t byte = *(source->bytes);
- ++source->bytes;
+ uint8_t byte = *(source->byte_read_ptr);
+ ++source->byte_read_ptr;
--source->bytes_available;
source->bits |= ((bitreservoir_t)byte << (BITRESERVOIR_SIZE - source->bits_available - 8));
source->bits_available += 8;