📄 bitstream.c
字号:
if (info!=NULL) {
/* write info string */
if (fputs(info,stream->file) == EOF) {
CommonWarning("BsOpenFileWrite: "
"error writing bit stream file (header)");
BsClose(stream);
return NULL;
}
if (fputc('\0',stream->file) == EOF) {
CommonWarning("BsOpenFileWrite: "
"error writing bit stream file (header)");
BsClose(stream);
return NULL;
}
}
}
stream->currentBit = 0;
stream->numByte = 0;
return stream;
}
/* BsOpenBufferRead() */
/* Open bit stream buffer for reading. */
BsBitStream *BsOpenBufferRead (
BsBitBuffer *buffer) /* in: bit buffer */
/* returns: */
/* bit stream (handle) */
{
BsBitStream *stream;
if (BSdebugLevel >= 2)
printf("BsOpenBufferRead: id=%ld bufNumBit=%ld bufSize=%ld "
"bufAddr=0x%lx\n",
BSstreamId,buffer->numBit,buffer->size,(unsigned long)buffer);
if ((stream=(BsBitStream*)malloc(sizeof(BsBitStream))) == NULL)
CommonExit(1,"BsOpenBufferRead: memory allocation error");
stream->file = NULL;
stream->write = 0;
stream->streamId = BSstreamId++;
stream->info = NULL;
stream->buffer[0] = buffer;
stream->currentBit = 0;
return stream;
}
/* BsOpenBufferWrite() */
/* Open bit stream buffer for writing. */
/* (Buffer is cleared first - previous data in buffer is lost !!!) */
BsBitStream *BsOpenBufferWrite (
BsBitBuffer *buffer) /* in: bit buffer */
/* returns: */
/* bit stream (handle) */
{
BsBitStream *stream;
if (BSdebugLevel >= 2)
printf("BsOpenBufferWrite: id=%ld bufNumBit=%ld bufSize=%ld "
"bufAddr=0x%lx\n",
BSstreamId,buffer->numBit,buffer->size,(unsigned long)buffer);
if ((stream=(BsBitStream*)malloc(sizeof(BsBitStream))) == NULL)
CommonExit(1,"BsOpenBufferWrite: memory allocation error");
stream->file = NULL;
stream->write = 1;
stream->streamId = BSstreamId++;
stream->info = NULL;
stream->buffer[0] = buffer;
BsClearBuffer(buffer);
stream->currentBit = 0;
return stream;
}
/* BsCurrentBit() */
/* Get number of bits read/written from/to stream. */
long BsCurrentBit (
BsBitStream *stream) /* in: bit stream */
/* returns: */
/* number of bits read/written */
{
return stream->currentBit;
}
/* BsEof() */
/* Test if end of bit stream file occurs within the next numBit bits. */
int BsEof (
BsBitStream *stream, /* in: bit stream */
long numBit) /* in: number of bits ahead scanned for EOF */
/* returns: */
/* 0=not EOF 1=EOF */
{
int eof;
if (BSdebugLevel >= 2)
printf("BsEof: %s id=%ld curBit=%ld numBit=%ld\n",
(stream->file!=NULL)?"file":"buffer",
stream->streamId,stream->currentBit,numBit);
if (stream->file != NULL && numBit > stream->buffer[0]->size)
CommonExit(1,"BsEof: "
"number of bits to look ahead too high (%ld)",numBit);
if (BsReadAhead(stream,numBit+1)) {
CommonWarning("BsEof: error reading bit stream");
eof = 0;
}
else
eof = BsCheckRead(stream,numBit+1);
if (BSdebugLevel >= 2)
printf("BsEof: eof=%d\n",eof);
return eof;
}
static void BsRemoveBufferOffset (BsBitBuffer *buffer, long startPosBit)
{
int bitsToCopy;
BsBitStream* offset_stream;
BsBitBuffer* helpBuffer;
/* open bit stream buffer for reading */
offset_stream = BsOpenBufferRead(buffer);
/* create help buffer */
helpBuffer = BsAllocBuffer(buffer->size);
/* read bits from bit stream to help buffer */
offset_stream->currentBit = startPosBit;
bitsToCopy = buffer->numBit - startPosBit;
if (BsGetBuffer(offset_stream, helpBuffer, bitsToCopy))
CommonExit(1, "BsRemoveBufferOffset: error reading bit stream");
/* close bit stream (no remove) */
BsCloseRemove(offset_stream, 0);
/* memcpy the offset free data from help buffer to buffer */
memcpy(buffer->data, helpBuffer->data, bit2byte(buffer->size));
/*FREE help buffer */
BsFreeBuffer(helpBuffer);
buffer->numBit = bitsToCopy;
}
/* BsCloseRemove() */
/* Close bit stream. */
int BsCloseRemove (
BsBitStream *stream, /* in: bit stream */
int remove) /* in: if opened with BsOpenBufferRead(): */
/* 0 = keep buffer unchanged */
/* 1 = remove bits read from buffer */
/* returns: */
/* 0=OK 1=error */
{
int returnFlag = 0;
int tmp,i;
long startPosBit;
if ((stream->file != NULL) && (BSdebugLevel >= 1) )
printf("BsClose: %s %s id=%ld curBit=%ld\n",
(stream->write)?"write":"read",
(stream->file!=NULL)?"file":"buffer",
stream->streamId,stream->currentBit);
if (stream->file != NULL) {
if (stream->write == 1)
/* flush buffer to file */
if (BsWriteFile(stream)) {
CommonWarning("BsClose: error writing bit stream");
returnFlag = 1;
}
BsFreeBuffer(stream->buffer[0]);
if (stream->write == 0)
BsFreeBuffer(stream->buffer[1]);
if (stream->file!=stdin && stream->file!=stdout)
if (fclose(stream->file)) {
CommonWarning("BsClose: error closing bit stream file");
returnFlag = 1;
}
}
else if (stream->write == 0 && remove){
/* remove all completely read bytes from buffer */
tmp = stream->currentBit/8;
for (i=0; i<((stream->buffer[0]->size+7)>>3)-tmp; i++)
stream->buffer[0]->data[i] = stream->buffer[0]->data[i+tmp];
startPosBit = stream->currentBit - tmp*8;
if ((startPosBit>7) || (startPosBit<0)){
CommonExit(1,"BsClose: Error removing bit in buffer");
}
stream->buffer[0]->numBit -= tmp*8;
/* better located here ??? HP/BT 990520 */
if (stream->buffer[0]->numBit <= startPosBit) {
stream->buffer[0]->numBit=0;
startPosBit=0;
}
/* remove remaining read bits from buffer */
/* usually we do not have remaining bits in buffer
reply: that not really true, eg. HVXC frames are not byte aligned, thereofore you have remaining bits after every second frame,
BT*/
if (startPosBit != 0)
{
/* printf("Remove buffer offset: %li\n", startPosBit); */
BsRemoveBufferOffset(stream->buffer[0], startPosBit);
if ((stream->currentBit - startPosBit) < 0)
CommonExit(1,"BsClose: Error decreasing currentBit");
else
stream->currentBit -= startPosBit;
}
}
if (stream->info != NULL)
FREE(stream->info);
FREE(stream);
return returnFlag;
}
/* BsClose() */
/* Close bit stream. */
int BsClose (
BsBitStream *stream) /* in: bit stream */
/* returns: */
/* 0=OK 1=error */
{
return BsCloseRemove(stream,0);
}
/* BsGetBit() */
/* Read bits from bit stream. */
/* (Current position in bit stream is advanced !!!) */
int BsGetBit (
BsBitStream *stream, /* in: bit stream */
unsigned long *data, /* out: bits read */
/* (may be NULL if numBit==0) */
int numBit) /* in: num bits to read */
/* [0..32] */
/* returns: */
/* 0=OK 1=error */
{
int num;
int maxNum;
int curNum;
unsigned long bits;
if (BSdebugLevel >= 3)
printf("BsGetBit: %s id=%ld numBit=%d curBit=%ld\n",
(stream->file!=NULL)?"file":"buffer",
stream->streamId,numBit,stream->currentBit);
if (stream->write != 0)
CommonExit(1,"BsGetBit: stream not in read mode");
if (numBit<0 || numBit>LONG_NUMBIT)
CommonExit(1,"BsGetBit: number of bits out of range (%d)",numBit);
if (data != NULL)
*data = 0;
if (numBit == 0)
return 0;
/* read bits in packets according to buffer byte boundaries */
num = 0;
maxNum = BYTE_NUMBIT - stream->currentBit % BYTE_NUMBIT;
while (num < numBit) {
curNum = min(numBit-num,maxNum);
if (BsReadByte(stream,&bits,curNum) != curNum) {
if ( ! BSaacEOF || BSdebugLevel > 0 )
CommonWarning("BsGetBit: error reading bit stream");
if ( BSaacEOF ) {
return -1;/* end of stream */
} else {
return 1;
}
}
*data |= bits<<(numBit-num-curNum);
num += curNum;
maxNum = BYTE_NUMBIT;
}
if (BSdebugLevel >= 3)
printf("BsGetBit: data=0x%lx\n",*data);
return 0;
}
/* this function is mainly for debugging purpose, */
/* you can call it from the debugger */
long int BsGetBitBack (
BsBitStream *stream, /* in: bit stream */
int numBit) /* in: num bits to read */
/* [0..32] */
/* returns: */
/* if numBit is positive
return the last numBits bit from stream
else
return the next -numBits from stream
stream->currentBit is always unchanged */
{
int num;
int maxNum;
int curNum;
unsigned long bits;
long int data;
int rewind = 0;
if (BSdebugLevel >= 3)
printf("BsGetBitBack: %s id=%ld numBit=%d curBit=%ld\n",
(stream->file!=NULL)?"file":"buffer",
stream->streamId,numBit,stream->currentBit);
/* if (stream->write != 0) */
/* CommonWarning("BsGetBitBack: stream not in read mode"); */
if (numBit<-32 || numBit>LONG_NUMBIT)
CommonExit(1,"BsGetBitBack: number of bits out of range (%d)",numBit);
data = 0;
if (numBit == 0)
return 0;
if (numBit > 0)
stream->currentBit-=numBit;
else {
rewind = 1;
numBit = -numBit;
}
if (stream->currentBit<0){
stream->currentBit+=numBit;
CommonWarning("BsGetBitBack: stream enough bits in stream ");
return 0;
}
/* read bits in packets according to buffer byte boundaries */
num = 0;
maxNum = BYTE_NUMBIT - stream->currentBit % BYTE_NUMBIT;
while (num < numBit) {
curNum = min(numBit-num,maxNum);
if (BsReadByte(stream,&bits,curNum) != curNum) {
CommonWarning("BsGetBitBack: error reading bit stream");
return 0;
}
data |= bits<<(numBit-num-curNum);
num += curNum;
maxNum = BYTE_NUMBIT;
}
if (rewind) /* rewind */
stream->currentBit-=numBit;
if (BSdebugLevel >= 3)
printf("BsGetBitBack: data=0x%lx\n",data);
return data;
}
/* BsGetBitChar() */
/* Read bits from bit stream (char). */
/* (Current position in bit stream is advanced !!!) */
int BsGetBitChar (
BsBitStream *stream, /* in: bit stream */
unsigned char *data, /* out: bits read */
/* (may be NULL if numBit==0) */
int numBit) /* in: num bits to read */
/* [0..8] */
/* returns: */
/* 0=OK 1=error */
{
unsigned long ultmp;
int result;
if (numBit > 8)
CommonExit(1,"BsGetBitChar: number of bits out of range (%d)",numBit);
if (data != NULL)
*data = 0;
if (numBit == 0)
return 0;
result = BsGetBit(stream,&ultmp,numBit);
*data = ultmp;
return result;
}
/* BsGetBitShort() */
/* Read bits from bit stream (short). */
/* (Current position in bit stream is advanced !!!) */
int BsGetBitShort (
BsBitStream *stream, /* in: bit stream */
unsigned short *data, /* out: bits read */
/* (may be NULL if numBit==0) */
int numBit) /* in: num bits to read */
/* [0..16] */
/* returns: */
/* 0=OK 1=error */
{
unsigned long ultmp;
int result;
if (numBit > 16)
CommonExit(1,"BsGetBitShort: number of bits out of range (%d)",numBit);
if (data != NULL)
*data = 0;
if (numBit == 0)
return 0;
result = BsGetBit(stream,&ultmp,numBit);
*data = ultmp;
return result;
}
/* BsGetBitInt() */
/* Read bits from bit stream (int). */
/* (Current position in bit stream is advanced !!!) */
int BsGetBitInt (
BsBitStream *stream, /* in: bit stream */
unsigned int *data, /* out: bits read */
/* (may be NULL if numBit==0) */
int numBit) /* in: num bits to read */
/* [0..16] */
/* returns: */
/* 0=OK 1=error */
{
unsigned long ultmp;
int result;
if (numBit > 16)
CommonExit(1,"BsGetBitInt: number of bits out of range (%d)",numBit);
if (data != NULL)
*data = 0;
if (numBit == 0)
return 0;
result = BsGetBit(stream,&ultmp,numBit);
*data = ultmp;
return result;
}
/* BsGetBitAhead() */
/* Read bits from bit stream. */
/* (Current position in bit stream is NOT advanced !!!) */
int BsGetBitAhead (
BsBitStream *stream, /* in: bit stream */
unsigned long *data, /* out: bits read */
/* (may be NULL if numBit==0) */
int numBit) /* in: num bits to read */
/* [0..32] */
/* returns: */
/* 0=OK 1=error */
{
long oldCurrentBit;
int result;
if (BSdebugLevel >= 3)
printf("BsGetBitAhead: %s id=%ld numBit=%d\n",
(stream->file!=NULL)?"file":"buffer",stream->streamId,numBit);
oldCurrentBit = stream->currentBit;
result = BsGetBit(stream,data,numBit);
stream->currentBit = oldCurrentBit;
if (result)
CommonWarning("BsGetBitAhead: error reading bit stream");
return result;
}
/* BsGetBitAheadChar() */
/* Read bits from bit stream (char). */
/* (Current position in bit stream is NOT advanced !!!) */
int BsGetBitAheadChar (
BsBitStream *stream, /* in: bit stream */
unsigned char *data, /* out: bits read */
/* (may be NULL if numBit==0) */
int numBit) /* in: num bits to read */
/* [0..8] */
/* returns: */
/* 0=OK 1=error */
{
long oldCurrentBit;
int result;
if (BSdebugLevel >= 3)
printf("BsGetBitAheadChar: %s id=%ld numBit=%d\n",
(stream->file!=NULL)?"file":"buffer",stream->streamId,numBit);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -