#include #include #include "bitstream.h" static const uint32_t BS_MASKS[33] = { 0, 0x1L, 0x3L, 0x7L, 0xFL, 0x1FL, 0x3FL, 0x7FL, 0xFFL, 0x1FFL, 0x3FFL, 0x7FFL, 0xFFFL, 0x1FFFL, 0x3FFFL, 0x7FFFL, 0xFFFFL, 0x1FFFFL, 0x3FFFFL, 0x7FFFFL, 0xFFFFFL, 0x1FFFFFL, 0x3FFFFFL, 0x7FFFFFL, 0xFFFFFFL, 0x1FFFFFFL, 0x3FFFFFFL, 0x7FFFFFFL, 0xFFFFFFFL, 0x1FFFFFFFL, 0x3FFFFFFFL, 0x7FFFFFFFL, 0xFFFFFFFFL}; void bs_init(struct bitstream* bs, const uint8_t* buffer, size_t input_size) { bs->buffer_ptr = buffer; bs->buffer_end = buffer + input_size; bs->value = 0; bs->pos = 0; bs->shift = 8; bs->size = input_size * 8; } uint32_t bs_get(struct bitstream* bs, int n) { if (n > 32) return 0; bs->pos += n; bs->shift += n; while (bs->shift > 8) { if (bs->buffer_ptr < bs->buffer_end) { bs->value <<= 8; bs->value |= *bs->buffer_ptr++; bs->shift -= 8; } else { bs_seek(bs, bs->pos - n); return 0; // bs->value <<= 8; // bs->shift -= 8; } } return (bs->value >> (8 - bs->shift)) & BS_MASKS[n]; } void bs_seek(struct bitstream* bs, size_t new_pos) { bs->pos = (new_pos / 32) * 32; bs->shift = 8; bs->value = 0; bs_get(bs, new_pos % 32); } uint32_t bs_peek(struct bitstream* bs, int n) { struct bitstream bak = *bs; return bs_get(&bak, n); } size_t bs_remain(struct bitstream* bs) { return bs->size - bs->pos; } int bs_eof(struct bitstream* bs) { return bs_remain(bs) == 0; } uint32_t bs_ue(struct bitstream* bs) { static const uint8_t exp_golomb_bits[256] = { 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; uint32_t bits, read = 0; int bits_left; uint8_t coded; int done = 0; bits = 0; // we want to read 8 bits at a time - if we don't have 8 bits, // read what's left, and shift. The exp_golomb_bits calc remains the // same. while (!done) { bits_left = bs_remain(bs); if (bits_left < 8) { read = bs_peek(bs, bits_left) << (8 - bits_left); done = 1; } else { read = bs_peek(bs, 8); if (read == 0) { bs_get(bs, 8); bits += 8; } else { done = 1; } } } coded = exp_golomb_bits[read]; bs_get(bs, coded); bits += coded; // printf("ue - bits %d\n", bits); return bs_get(bs, bits + 1) - 1; } int32_t bs_se(struct bitstream* bs) { uint32_t ret; ret = bs_ue(bs); if ((ret & 0x1) == 0) { ret >>= 1; int32_t temp = 0 - ret; return temp; } return (ret + 1) >> 1; }