#ifndef __BITS_H__ #define __BITS_H__ #include #include typedef uint64_t bitcount_t; class BitStreamUndo { //protected: public: uint8_t outbyte; unsigned int byteidx; int bitidx; unsigned int bufcount; fpos_t actpos; bitcount_t totbits; bitcount_t buffer_start; bitcount_t readpos; uint8_t *bfr; unsigned int bfr_size; public: bool eobs; }; typedef class BitStream _BitStream; typedef size_t (*ReadCallback) (_BitStream *bs, uint8_t *dest, size_t size, void *user_data); class BitStream : public BitStreamUndo { public: void *user_data; static const unsigned int BUFFER_SIZE = 4 * 1024; public: BitStream (); ~BitStream (); inline bitcount_t bitcount () { return totbits; } inline bool eos () { return eobs; } }; // // Input bit stream class. Supports the "scanning" of a stream // into a large buffer which is flushed once it has been read. // N.b. if you scan ahead a long way and don't read its your // responsibility to flush manually... // class IBitStream:public BitStream { public: void open (ReadCallback read_callback, void *user_data, unsigned int buf_size = BUFFER_SIZE); void SetBufSize (unsigned int buf_size); void close (); uint32_t get1bit (); uint32_t getbits (int N); void prepareundo (BitStreamUndo & undobuf); void undochanges (BitStreamUndo & undobuf); bool seek_sync (unsigned int sync, int N, int lim); void flush (bitcount_t bitposition); inline unsigned int buffered_bytes () { return (buffer_start + bufcount - readpos); } unsigned int read_buffered_bytes (uint8_t * dst, unsigned int length_bytes); private: bool refill_buffer (); static uint8_t masks[8]; ReadCallback read_callback; }; #endif // __BITS_H__