*
* copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
*
- * Licensed under the GNU Lesser General Public License.
- * For licencing details see COPYING.LIB.
+ * Licensed under the GNU Lesser General Public License, see file COPYING.LIB.
*/
/** \file bitstream.h Bitstream structures and inline functions. */
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;
};
-#define VLC_TYPE int16_t
-
/** A variable length code table. */
struct vlc {
/** Number of bits of the table. */
int bits;
/** The code and the bits table. */
- VLC_TYPE(*table)[2];
+ int16_t (*table)[2];
/** The size of the table. */
int table_size;
/** Amount of memory allocated so far. */
static inline uint32_t show_bits(struct getbit_context *gbc, int num)
{
int idx = gbc->index;
- const uint8_t *p = gbc->buffer + (idx >> 3);
- uint32_t x = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
+ 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;
}
void init_vlc(struct vlc *vlc, int nb_bits, int nb_codes, const void *bits,
const void *codes, int codes_size);
void free_vlc(struct vlc *vlc);
-int get_vlc(struct getbit_context *gbc, VLC_TYPE(*table)[2], int bits);
+int get_vlc(struct getbit_context *gbc, const struct vlc *vlc);