Refactor: bitstream.c full cleanup

This commit is contained in:
Marko Viitanen 2013-09-18 15:45:46 +03:00
parent df8c5a6acd
commit db3d8d8a6e

View file

@ -18,7 +18,7 @@
#include <math.h> #include <math.h>
#include <string.h> #include <string.h>
#include <stdarg.h> #include <stdarg.h>
/* for hton */ //for hton
#ifdef WIN32 #ifdef WIN32
#include <Winsock2.h> #include <Winsock2.h>
#else #else
@ -36,7 +36,7 @@ void printf_bitstream(char *msg, ...)
va_start(fmtargs,msg); va_start(fmtargs,msg);
vsnprintf(buffer,sizeof(buffer)-1,msg,fmtargs); vsnprintf(buffer,sizeof(buffer)-1,msg,fmtargs);
va_end(fmtargs); va_end(fmtargs);
printf("%s",buffer); printf("%s",buffer);
} }
#endif #endif
@ -54,38 +54,43 @@ int floor_log2(unsigned int n) {
return ((n == 0) ? (-1) : pos); return ((n == 0) ? (-1) : pos);
} }
//Initialize the Exp Golomb code table with desired number of values /**
* \brief Initialize the Exp Golomb code table with desired number of values
* \param len table length to init
*
* Allocates g_exp_table with len*sizeof(bit_table) and fills it with exponential golomb codes
*/
void init_exp_golomb(uint32_t len) void init_exp_golomb(uint32_t len)
{ {
uint32_t code_num; uint32_t code_num;
uint32_t M; uint32_t M;
uint32_t info; uint32_t info;
g_exp_table=(bit_table*)malloc(len*sizeof(bit_table)); g_exp_table = (bit_table*)malloc(len*sizeof(bit_table));
for(code_num=0;code_num<len;code_num++) for (code_num = 0; code_num < len; code_num++) {
{ M = (uint32_t)floor_log2(code_num + 1);
M=(uint32_t)floor_log2(code_num+1); info = code_num + 1 - (uint32_t)pow(2, M);
info=code_num+1-(uint32_t)pow(2,M); g_exp_table[code_num].len = M * 2 + 1;
g_exp_table[code_num].len=M*2+1; g_exp_table[code_num].value = (1<<M) | info;
g_exp_table[code_num].value=(1<<M)|info; }
//printf_cavlc("Len: %i %x\n", M*2+1, (1<<M)|info);
}
} }
/* /**
* Clear bitstream * \brief Clear bitstream
*/ */
void bitstream_init(bitstream* stream) void bitstream_init(bitstream *stream)
{ {
stream->cur_byte=0; stream->cur_byte = 0;
stream->cur_bit=0; stream->cur_bit = 0;
memset(stream->data, 0, sizeof(uint32_t)*32); memset(stream->data, 0, sizeof(uint32_t)*32);
} }
/* /**
* Allocate buffer * \brief Allocate buffer
* \param stream pointer bitstream to put the data
* \param alloc size to allocate
*/ */
void bitstream_alloc(bitstream* stream, uint32_t alloc) void bitstream_alloc(bitstream *stream, uint32_t alloc)
{ {
stream->buffer = (uint8_t*)malloc(alloc); stream->buffer = (uint8_t*)malloc(alloc);
stream->bufferlen = alloc; stream->bufferlen = alloc;
@ -93,127 +98,110 @@ void bitstream_alloc(bitstream* stream, uint32_t alloc)
bitstream_clear_buffer(stream); bitstream_clear_buffer(stream);
} }
void bitstream_clear_buffer(bitstream* stream) /**
* \brief clear output buffer
*/
void bitstream_clear_buffer(bitstream *stream)
{ {
memset(stream->buffer,0,stream->bufferlen); memset(stream->buffer, 0, stream->bufferlen);
stream->buffer_pos = 0; stream->buffer_pos = 0;
} }
/**
/*! * \brief Put bits to bitstream
\brief Put bits to bitstream * \param stream pointer bitstream to put the data
\param stream pointer bitstream to put the data * \param data input data
\param data input data * \param bits number of bits to write from data to stream
\param bits number of bits to write from data to stream */
*/ void bitstream_put(bitstream *stream, uint32_t data, uint8_t bits)
void bitstream_put(bitstream* stream, uint32_t data, uint8_t bits)
{ {
uint32_t bitsleft=32-stream->cur_bit; uint32_t bitsleft = 32 - stream->cur_bit;
#ifdef VERBOSE #ifdef VERBOSE
uint8_t i=0; uint8_t i=0;
printf_bitstream("put: "); printf_bitstream("put: ");
for(i=0;i<bits;i++) for (i = 0; i < bits; i++) {
{
printf("%i",(data&(1<<(bits-i-1)))?1:0); printf("%i",(data&(1<<(bits-i-1)))?1:0);
} }
printf_bitstream("\n"); printf_bitstream("\n");
//printf_bitstream(" count: %i\n",bits); //printf_bitstream(" count: %i\n",bits);
#endif #endif
//Theres space for all the bits //There's space for all the bits
if(bits<=bitsleft) if (bits <= bitsleft) {
{
stream->data[stream->cur_byte] |= (data<<((bitsleft-bits))); stream->data[stream->cur_byte] |= (data<<((bitsleft-bits)));
stream->cur_bit+=bits; stream->cur_bit += bits;
bits=0; bits = 0;
} } else { //No space for everything, store the bits we can and continue later
//No space for everything, store the bits we can and continue later
else
{
stream->data[stream->cur_byte] |= (data>>(bits-bitsleft)); stream->data[stream->cur_byte] |= (data>>(bits-bitsleft));
stream->cur_bit=32; stream->cur_bit = 32;
bits-=bitsleft; bits -= bitsleft;
} }
//Check if the buffer is full //Check if the buffer is full, and flush to output if it is
if(stream->cur_bit==32) if (stream->cur_bit == 32) {
{ bitsleft = 32;
bitsleft=32;
stream->cur_byte++; stream->cur_byte++;
stream->cur_bit = 0; stream->cur_bit = 0;
if(stream->cur_byte==32) if (stream->cur_byte == 32) {
{ //Flush data out
//Flush data out bitstream_flush(stream);
bitstream_flush(stream);
} }
} }
//..still some writing to do //Write the last of the bits (if buffer was full and flushed before)
if(bits!=0) if (bits != 0) {
{
stream->data[stream->cur_byte] |= (data<<(bitsleft-bits)); stream->data[stream->cur_byte] |= (data<<(bitsleft-bits));
stream->cur_bit+=bits; stream->cur_bit += bits;
} }
} }
/*! /**
\brief Align the bitstream * \brief Align the bitstream with one-bit padding
*/ */
void bitstream_align(bitstream* stream) void bitstream_align(bitstream *stream)
{ {
bitstream_put(stream,1, 1); bitstream_put(stream, 1, 1);
if((stream->cur_bit&7) != 0) if ((stream->cur_bit & 7) != 0) {
{ bitstream_put(stream, 0, 8 - (stream->cur_bit & 7));
bitstream_put(stream,0, 8-(stream->cur_bit&7));
} }
} }
void bitstream_align_zero(bitstream* stream) /**
* \brief Align the bitstream with zero
*/
void bitstream_align_zero(bitstream *stream)
{ {
if((stream->cur_bit&7) != 0) if ((stream->cur_bit & 7) != 0) {
{ bitstream_put(stream, 0, 8 - (stream->cur_bit & 7));
bitstream_put(stream,0, 8-(stream->cur_bit&7));
} }
} }
void bitstream_flush(bitstream* stream) /**
* \brief Flush bitstream to output
*/
void bitstream_flush(bitstream *stream)
{ {
/*
* SAVE DATA TO OUTPUT
*/
int i; int i;
uint32_t correct_endian; uint32_t correct_endian;
if(stream->output) //If output open, write to output
{ if (stream->output) {
if(stream->cur_byte) if (stream->cur_byte) fwrite(&stream->data[0], stream->cur_byte * 4, 1, stream->output);
{ if (stream->cur_bit>>3) fwrite(&stream->data[stream->cur_byte], stream->cur_bit>>3, 1, stream->output);
fwrite(&stream->data[0], stream->cur_byte*4, 1, stream->output);
} } else { //No file open, write to buffer
if (stream->cur_byte) {
if(stream->cur_bit>>3) //Handle endianness issue
{ for (i = 0; i < stream->cur_byte; i++) {
fwrite(&stream->data[stream->cur_byte], stream->cur_bit>>3, 1, stream->output); //"network" is big-endian
}
}
/* No file open, write to buffer */
else
{
if(stream->cur_byte)
{
/* Handle endianness issue */
for(i = 0; i < stream->cur_byte; i++)
{
/* "network" is big-endian */
correct_endian = htonl(stream->data[i]); correct_endian = htonl(stream->data[i]);
memcpy((uint8_t*)&stream->buffer[stream->buffer_pos],&correct_endian,4); memcpy((uint8_t*)&stream->buffer[stream->buffer_pos], &correct_endian, 4);
stream->buffer_pos += 4; stream->buffer_pos += 4;
} }
} }
if(stream->cur_bit>>3) if (stream->cur_bit>>3) {
{
correct_endian = htonl(stream->data[stream->cur_byte]); correct_endian = htonl(stream->data[stream->cur_byte]);
memcpy((uint8_t*)&stream->buffer[stream->buffer_pos],&correct_endian,stream->cur_bit>>3); memcpy((uint8_t*)&stream->buffer[stream->buffer_pos], &correct_endian, stream->cur_bit>>3);
stream->buffer_pos += stream->cur_bit>>3; stream->buffer_pos += stream->cur_bit>>3;
} }
} }