struct getbit_context {
/** Start of the internal buffer. */
const uint8_t *buffer;
- /** End of the internal buffer. */
- const uint8_t *buffer_end;
+ /** Length of buffer in bits (always a multiple of 8). */
+ uint32_t num_bits;
/** Bit counter. */
int index;
};
static inline uint32_t show_bits(struct getbit_context *gbc, int num)
{
int idx = gbc->index;
- const char *p = (const char *)gbc->buffer + (idx >> 3);
- uint32_t x = read_u32_be(p);
+ const char *p;
+ uint32_t x;
+
+ assert(idx + num <= gbc->num_bits);
+ p = (const char *)gbc->buffer + (idx >> 3);
+ x = read_u32_be(p);
return (x << (idx & 7)) >> (32 - num);
}
static inline void skip_bits(struct getbit_context *gbc, int n)
{
+ assert(gbc->index + n <= gbc->num_bits);
gbc->index += n;
}
static inline unsigned int get_bits(struct getbit_context *gbc, int n)
{
- unsigned int ret = show_bits(gbc, n);
+ unsigned int ret = show_bits(gbc, n); /* checks n */
skip_bits(gbc, n);
return ret;
}
/* This is rather hot, we can do better than get_bits(gbc, 1). */
static inline unsigned int get_bit(struct getbit_context *gbc)
{
- int idx = gbc->index++;
- uint8_t tmp = gbc->buffer[idx >> 3], mask = 1 << (7 - (idx & 7));
+ int idx;
+ uint8_t tmp, mask;
+
+ assert(gbc->index < gbc->num_bits);
+ idx = gbc->index++;
+ tmp = gbc->buffer[idx >> 3];
+ mask = 1 << (7 - (idx & 7));
return !!(tmp & mask);
}
const uint8_t *buffer, int size)
{
gbc->buffer = buffer;
- gbc->buffer_end = buffer + size;
+ gbc->num_bits = size * 8;
gbc->index = 0;
}