// // WordBitCompress.h // // BitStream: put and get bits into a buffer // *tagging: add tags to keep track of the position of data // inside the bitstream for debuging purposes. // *freezing: saves current position. further inserts in the BitStream // aren't really done. This way you can try different // compression algorithms and chose the best. // // Compressor: BitStream with extended fuctionalities // // // Part of the ht://Dig package // Copyright (c) 1999-2004 The ht://Dig Group // For copyright details, see the file COPYING in your distribution // or the GNU Library General Public License (LGPL) version 2 or later // // // $Id: WordBitCompress.h,v 1.7 2004/05/28 13:15:26 lha Exp $ // #ifndef _WordBitCompress_h #define _WordBitCompress_h #include #include #include"HtVector_int.h" #include"HtMaxMin.h" typedef unsigned char byte; // ******** HtVector_byte (header) #define GType byte #define HtVectorGType HtVector_byte #include "HtVectorGeneric.h" typedef char * charptr; // ******** HtVector_charptr (header) #define GType charptr #define HtVectorGType HtVector_charptr #include "HtVectorGeneric.h" // ******** Utility inline functions and macros // error checking #define FATAL_ABORT fflush(stdout);fprintf(stderr,"FATAL ERROR at file:%s line:%d !!!\n",__FILE__,__LINE__);fflush(stderr);(*(int *)NULL)=1 #define errr(s) {fprintf(stderr,"FATAL ERROR:%s\n",s);FATAL_ABORT;} #define CHECK_MEM(p) if(!p) errr("mifluz: Out of memory!"); // max/min of 2 values #define TMax(a,b) (((a)>(b)) ? (a) : (b)) #define TMin(a,b) (((a)<(b)) ? (a) : (b)) // compute integer log2 // == minimum number of bits needed to code value inline int num_bits(unsigned int maxval ) { unsigned int mv=maxval; int nbits; for(nbits=0;mv;nbits++){mv>>=1;} return(nbits); } // compute 2^x #define pow2(x) (1<<(x)) // function declarations char *label_str(const char *s,int n); void show_bits(int v,int n=16); // unsigned short max_v(unsigned short *vals,int n); // unsigned int max_v(unsigned int *vals,int n); // unsigned short min_v(unsigned short *vals,int n); // unsigned int min_v(unsigned int *vals,int n); // ************************************************** // *************** BitStream *********************** // ************************************************** // compression is done in Compressor not in BitStream class BitStream { protected: // the buffer were the bitstream is stored HtVector_byte buff; // current bit position within the buffer int bitpos; // tags for debuging HtVector_int tagpos; HtVector_charptr tags; int use_tags; // freezing the bitstream HtVector_int freeze_stack; int freezeon; public: void freeze(); int unfreeze(); // puts a bit into the bitstream inline void put(unsigned int v) { // SPEED CRITICAL SECTION if(freezeon){bitpos++;return;} if(v){buff.back()|=pow2(bitpos & 0x07);} bitpos++; if(!(bitpos & 0x07))// new byte { buff.push_back(0); } } inline void put(unsigned int v,const char *tag) { if(!freezeon){add_tag(tag);} put(v); } // gets a bit from the bitstream inline byte get(const char *tag=(char*)NULL) { // SPEED CRITICAL SECTION if(check_tag(tag)==NOTOK){errr("BitStream::get() check_tag failed");} if(bitpos>=(buff.size()<<3)){errr("BitStream::get reading past end of BitStream!");} byte res=buff[bitpos>>3] & pow2(bitpos & 0x07); // printf("get:res:%d bitpos:%5d/%d buff[%3d]=%x\n",res,bitpos,bitpos%8,bitpos/8,buff[bitpos/8]); bitpos++; return(res); } // get/put an integer using n bits void put_uint(unsigned int v,int n,const char *tag=(char*)"NOTAG"); unsigned int get_uint( int n,const char *tag=(char*)NULL); // get/put n bits of data stored in vals void put_zone(byte *vals,int n,const char *tag); void get_zone(byte *vals,int n,const char *tag); // inline void add_tag(const char *tag) { if(!use_tags || !tag || freezeon){return;} add_tag1(tag); } void add_tag1(const char *tag); inline int check_tag(const char *tag,int pos=-1) { if(!use_tags || !tag){return OK;} return(check_tag1(tag,pos)); } int check_tag1(const char *tag,int pos); void set_use_tags(){use_tags=1;} int find_tag(const char *tag); int find_tag(int pos,int posaftertag=1); void show_bits(int a,int n); void show(int a=0,int n=-1); // position accesors int size(){return(bitpos);} int buffsize(){return(buff.size());} // get a copy of the buffer byte *get_data(); // set the buffer from outside data (current buffer must be empty) void set_data(const byte *nbuff,int nbits); // use this for reading a BitStream after you have written in it // (generally for debuging) void rewind(){bitpos=0;} ~BitStream() { int i; for(i=0;i