📄 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 + -