#ifndef __BITSTREAM_READER_H__ #define __BITSTREAM_READER_H__ #include #include #include #include typedef struct BitStreamReader BitStreamReader; typedef void BitStreamInputFunction(BitStreamReader *self,void *context); struct BitStreamReader { BitStreamInputFunction *callback; void *context; const uint8_t *pos,*end; uint32_t bits; int numbits; }; static void FillBits(BitStreamReader *self,int required); static void DiscardBits(BitStreamReader *self,int length); static void InitializeBitStreamReader(BitStreamReader *self) { self->callback=NULL; self->context=NULL; self->pos=NULL; self->end=NULL; self->bits=0; self->numbits=0; } static void SetBitStreamInputCallback(BitStreamReader *self,BitStreamInputFunction *callback,void *context) { self->callback=callback; self->context=context; } static void ProvideBitStreamInputBuffer(BitStreamReader *self,const void *bytes,size_t length) { self->pos=bytes; self->end=self->pos+length; } static int ReadBitString(BitStreamReader *self,int length) { if(length==0) return 0; FillBits(self,length); if(self->numbitsbits&((1<numbits&7; if(extrabits==0) return; DiscardBits(self,extrabits); } static void FillBits(BitStreamReader *self,int required) { while(self->numbitspos>=self->end) { if(self->callback) self->callback(self,self->context); else return; if(self->pos>=self->end) return; } uint32_t b=*self->pos++; self->bits|=b<numbits; self->numbits+=8; } } static void DiscardBits(BitStreamReader *self,int length) { self->bits>>=length; self->numbits-=length; } static inline uint16_t MakeHuffmanTableEntry(int value,int length) { return (length<<12)|value; } static inline int ValueOfHuffmanTableEntry(uint16_t entry) { return entry&0xfff; } static inline int LengthOfHuffmanTableEntry(uint16_t entry) { return entry>>12; } static void InitializeHuffmanTable(uint16_t *table,int maxlength) { memset(table,0,sizeof(*table)*(1<>1)&0x5555)|((val&0x5555)<<1); val=((val>>2)&0x3333)|((val&0x3333)<<2); val=((val>>4)&0x0F0F)|((val&0x0F0F)<<4); return (val>>8)|(val<<8); } static bool BuildHuffmanTableFromLengths(uint16_t *table,int maxlength,int *lengths,int numcodes) { InitializeHuffmanTable(table,maxlength); uint32_t code=0; for(int len=1;len<=maxlength;len++) { for(int i=0;ibits&((1<numbits