]> git.sesse.net Git - fjl/blobdiff - bitsource.c
Fix a Makefile typo.
[fjl] / bitsource.c
index 72b143bf7092b666669b3eafb19baf1b7d3bd670..b1593aa6ec554959b4bba6bbe3aceb75d4e04863 100644 (file)
@@ -8,19 +8,26 @@
 #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;
@@ -39,19 +46,30 @@ void possibly_refill_slow_path(struct bit_source* source, unsigned num_bits)
                        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;