/* bits.c * * Fred Smith * Basic BitStream Interface * * see "bitstream.h" for details. */ /* Includes .................................................................. */ #include #include #include #include "bits.h" /* Defines ................................................................... */ #define MAXWORD 0xFFFFFFFF /* 32 bits all set to 1 */ /* #define DEBUG_BITSTREAM */ /* Bitstream Operations ...................................................... */ int bytes_read = 0; int bytes_written = 0; CODE getCode(int bpc,FILE* inStream) /* Read the next bpc bits from inStream */ { static int lastChar=0; /* last char(byte) read in */ static unsigned int remainder=0; /* number of bits in lastChar still in use.*/ CODE returnCode; /* Code that will be returned */ int bits; /*assert(bpc<32);*/ if(remainder>=(unsigned)bpc) { returnCode = (lastChar >> (remainder - bpc)); returnCode &= MAXWORD >> (32 - bpc); remainder-=bpc; return returnCode; } returnCode = (lastChar << (bpc - remainder)); bits = remainder; do { lastChar=getc(inStream); if(lastChar==EOF) return EOF; bits+=8; bytes_read++; if(bits> remainder); return(returnCode & (MAXWORD >> (32 - bpc))); } void putCode(CODE c, int bpc,FILE *outStream) /* Write first bpc bits of c to stream */ { static CODE lastChar=0; /* Last char that was not completely written. */ static int remainder=0; /* Bits of lastChar that still need to be written */ CODE outputChar; int bits; assert(bpc<32); if(c==LAST_CODE) { if(remainder>0) { putc((lastChar << (8-remainder)),outStream); bytes_written++; } return; } assert(c < (unsigned) (0x1 << bpc)); /* Top bits zeroed */ if(bpc<8) { lastChar = (lastChar << bpc); lastChar |= c; remainder+=bpc; if(remainder<8) return; remainder-=8; outputChar = (lastChar >> remainder); putc(outputChar,outStream); bytes_written++; return; } else { outputChar = (lastChar << (8-remainder)) | (c >> (bpc - (8-remainder))); } putc(outputChar,outStream); bytes_written++; bits=bpc-(8-remainder); while(bits>=8) { outputChar=(c & (MAXWORD >> (32-bits))) >> (bits-8); bits-=8; putc(outputChar,outStream); bytes_written++; } remainder=bits; lastChar= (c & (MAXWORD >> (32 - bits))); return; } int bytesWritten(void) { return bytes_written; } int bytesRead(void) { return bytes_read; } void reset(void) { bytes_read=0; bytes_written=0; return; } #ifdef DEBUG_BITSTREAM /* Simple Main to debug bitstream routines */ int main(void) { FILE *inStream,*outStream; unsigned int i; int bpc=3; outStream=fopen("temp.out","wb"); assert(outStream!=NULL); for(i=0;i<8;i++) { putCode(i,bpc,outStream); printf("%7x ",i); } putCode(LAST_CODE,bpc,outStream); printf("\n"); fclose(outStream); inStream=fopen("temp.out","rb"); assert(inStream!=NULL); for(i=0;i<8;i++) { printf("%7x ",getCode(bpc,inStream)); } printf("\n"); fclose(inStream); printf("bytesRead = %5d, bytesWritten = %5d\n",bytesRead(),bytesWritten()); return(1); } #endif