# HG changeset patch # User nicodvb # Date 1187556823 0 # Node ID b3bc18ea58786f1f4fc956d18e0ea64656ae41ab # Parent 97a8394bec58ad5fc009bb061c220b5b7b6afec3 added from dvdnav's dvdread getbits() code to be used in forthcoming patch to read correctly NAV data diff -r 97a8394bec58 -r b3bc18ea5878 dvdread/nav_read.c --- a/dvdread/nav_read.c Sun Aug 19 09:07:56 2007 +0000 +++ b/dvdread/nav_read.c Sun Aug 19 20:53:43 2007 +0000 @@ -32,6 +32,76 @@ #include "nav_read.h" #include "dvdread_internal.h" +typedef struct { + uint8_t *start; + uint32_t byte_position; + uint32_t bit_position; + uint8_t byte; +} getbits_state_t; + +static int getbits_init(getbits_state_t *state, uint8_t *start) { + if ((state == NULL) || (start == NULL)) return 0; + state->start = start; + state->bit_position = 0; + state->byte_position = 0; + state->byte = start[0]; + return 1; +} + +/* Non-optimized getbits. */ +/* This can easily be optimized for particular platforms. */ +static uint32_t getbits(getbits_state_t *state, uint32_t number_of_bits) { + uint32_t result=0; + uint8_t byte=0; + if (number_of_bits > 32) { + printf("Number of bits > 32 in getbits\n"); + abort(); + } + + if ((state->bit_position) > 0) { /* Last getbits left us in the middle of a byte. */ + if (number_of_bits > (8-state->bit_position)) { /* this getbits will span 2 or more bytes. */ + byte = state->byte; + byte = byte >> (state->bit_position); + result = byte; + number_of_bits -= (8-state->bit_position); + state->bit_position = 0; + state->byte_position++; + state->byte = state->start[state->byte_position]; + } else { + byte=state->byte; + state->byte = state->byte << number_of_bits; + byte = byte >> (8 - number_of_bits); + result = byte; + state->bit_position += number_of_bits; /* Here it is impossible for bit_position > 8 */ + if (state->bit_position == 8) { + state->bit_position = 0; + state->byte_position++; + state->byte = state->start[state->byte_position]; + } + number_of_bits = 0; + } + } + if ((state->bit_position) == 0) { + while (number_of_bits > 7) { + result = (result << 8) + state->byte; + state->byte_position++; + state->byte = state->start[state->byte_position]; + number_of_bits -= 8; + } + if (number_of_bits > 0) { /* number_of_bits < 8 */ + byte = state->byte; + state->byte = state->byte << number_of_bits; + state->bit_position += number_of_bits; /* Here it is impossible for bit_position > 7 */ + byte = byte >> (8 - number_of_bits); + result = (result << number_of_bits) + byte; + number_of_bits = 0; + } + } + + return result; +} + + void navRead_PCI(pci_t *pci, unsigned char *buffer) { int i, j;