00001 /* 00002 * Copyright (C) 2000, 2001, 2002, 2003 HÃ¥kan Hjort <d95hjort@dtek.chalmers.se> 00003 * 00004 * This file is part of libdvdread. 00005 * 00006 * libdvdread is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * libdvdread is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License along 00017 * with libdvdread; if not, write to the Free Software Foundation, Inc., 00018 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00019 */ 00020 00021 #include <stdio.h> 00022 #include <stdlib.h> 00023 #include <string.h> 00024 #include <inttypes.h> 00025 00026 #include "dvdread/bitreader.h" 00027 00028 int dvdread_getbits_init(getbits_state_t *state, uint8_t *start) { 00029 if ((state == NULL) || (start == NULL)) return 0; 00030 state->start = start; 00031 state->bit_position = 0; 00032 state->byte_position = 0; 00033 state->byte = start[0]; 00034 return 1; 00035 } 00036 00037 /* Non-optimized getbits. */ 00038 /* This can easily be optimized for particular platforms. */ 00039 uint32_t dvdread_getbits(getbits_state_t *state, uint32_t number_of_bits) { 00040 uint32_t result=0; 00041 uint8_t byte=0; 00042 if (number_of_bits > 32) { 00043 printf("Number of bits > 32 in getbits\n"); 00044 abort(); 00045 } 00046 00047 if ((state->bit_position) > 0) { /* Last getbits left us in the middle of a byte. */ 00048 if (number_of_bits > (8-state->bit_position)) { /* this getbits will span 2 or more bytes. */ 00049 byte = state->byte; 00050 byte = byte >> (state->bit_position); 00051 result = byte; 00052 number_of_bits -= (8-state->bit_position); 00053 state->bit_position = 0; 00054 state->byte_position++; 00055 state->byte = state->start[state->byte_position]; 00056 } else { 00057 byte=state->byte; 00058 state->byte = state->byte << number_of_bits; 00059 byte = byte >> (8 - number_of_bits); 00060 result = byte; 00061 state->bit_position += number_of_bits; /* Here it is impossible for bit_position > 8 */ 00062 if (state->bit_position == 8) { 00063 state->bit_position = 0; 00064 state->byte_position++; 00065 state->byte = state->start[state->byte_position]; 00066 } 00067 number_of_bits = 0; 00068 } 00069 } 00070 if ((state->bit_position) == 0) { 00071 while (number_of_bits > 7) { 00072 result = (result << 8) + state->byte; 00073 state->byte_position++; 00074 state->byte = state->start[state->byte_position]; 00075 number_of_bits -= 8; 00076 } 00077 if (number_of_bits > 0) { /* number_of_bits < 8 */ 00078 byte = state->byte; 00079 state->byte = state->byte << number_of_bits; 00080 state->bit_position += number_of_bits; /* Here it is impossible for bit_position > 7 */ 00081 byte = byte >> (8 - number_of_bits); 00082 result = (result << number_of_bits) + byte; 00083 number_of_bits = 0; 00084 } 00085 } 00086 00087 return result; 00088 } 00089 00090 #if 0 /* TODO: optimized versions not yet used */ 00091 00092 /* WARNING: This function can only be used on a byte boundary. 00093 No checks are made that we are in fact on a byte boundary. 00094 */ 00095 uint16_t dvdread_get16bits(getbits_state_t *state) { 00096 uint16_t result; 00097 state->byte_position++; 00098 result = (state->byte << 8) + state->start[state->byte_position++]; 00099 state->byte = state->start[state->byte_position]; 00100 return result; 00101 } 00102 00103 /* WARNING: This function can only be used on a byte boundary. 00104 No checks are made that we are in fact on a byte boundary. 00105 */ 00106 uint32_t dvdread_get32bits(getbits_state_t *state) { 00107 uint32_t result; 00108 state->byte_position++; 00109 result = (state->byte << 8) + state->start[state->byte_position++]; 00110 result = (result << 8) + state->start[state->byte_position++]; 00111 result = (result << 8) + state->start[state->byte_position++]; 00112 state->byte = state->start[state->byte_position]; 00113 return result; 00114 } 00115 00116 #endif
1.6.3