2 // implements canonical Huffman !! Just for decoding when symbols were sorted before creating huffman
4 #ifndef HUFFDECINCLUDED
5 #define HUFFDECINCLUDED
13 uint depth; // max symbol length
14 uint *num; // first pos of each length (dec), number of each length (enc)
15 uint *fst; // first code (numeric) of each length (dec)
20 // { uint max,lim; // maximum symbol (0..max), same excluding zero freqs
21 // uint depth; // max symbol length
23 // { uint *spos; // symbol positions after sorting by decr freq (enc)
24 // uint *symb; // symbols sorted by freq (dec)
26 // uint *num; // first pos of each length (dec), number of each length (enc)
27 // uint *fst; // first code (numeric) of each length (dec)
28 // uint total; // total length to achieve, in bits
32 // Decodes *symb using H, over stream[ptr...lim] (ptr and lim are
33 // bit positions of stream). Returns the new ptr.
34 int decodeHuffDec (THuffDec *H, uint *symb, uint *stream, uint ptr);
37 void saveHuffDec (THuffDec H, FILE *f);
40 void freeHuffDec (THuffDec H);
42 // the number of bytes used by HuffDecman struct.
43 uint sizeHuffDec (THuffDec H);
45 // Loads H from file f, prepared for encoding or decoding depending
48 THuffDec loadHuffDec (FILE *f, int enc);
51 //Decodes a code starting in position ptr from stream. Returns the ranking in the
53 #define decodeHuffDecMacro(H, symb, stream, ptr) \
58 while (pos < H->fst[d]) \
59 { pos = (pos << 1) | bitget(stream,ptr); \
63 symb = H->num[d]+pos-H->fst[d]; \
83 //#define decodeHuffDecMacroVALIDWORDS decodeHuffDecMacro
85 //Decodes a code starting in position ptr from stream. Returns the ranking in the
87 //Saves space, as the last level for num[] and fst[] are not needed.
88 // at expenses of an extra-IF (the last line).
89 #define decodeHuffDecMacroVALIDWORDS(H, symb, stream, ptr, depth) \
94 while ((pos < H->fst[d]) && (d< depth)) \
95 { pos = (pos << 1) | bitget(stream,ptr); \
99 symb = (depth==d) ? pos : H->num[d]+pos-H->fst[d]; \
103 //Decodes a code starting in position ptr from stream. Returns the ranking in the
105 #define decodeHuffDecMacroVariantWordxx(fst,num, symb, stream, ptr, depth) \
110 while ((pos < fst[d]) && (d< depth)) \
111 { pos = (pos << 1) | bitget(stream,ptr); \
115 symb = (depth==d) ? pos : num[d] + pos - fst[d]; \
120 //Decodes a code starting in position ptr from stream. Returns the ranking in the
122 // #define decodeHuffDecMacroVariantWord(fst,symb, stream, ptr, depth) \
127 // while ((d< depth) && (pos < fst[d*2]) ) \
128 // { pos = (pos << 1) | bitget(stream,ptr); \
131 // symb = (depth==d) ? pos : fst[d*2+1] + pos - fst[d*2]; \
135 /** Decodes a variant of a word from a stream of compressed bits, starting in the ptr-th bit
136 The starting bucket in fstnum is "offbucket" [fst|num|fst|num|fst|num]
138 #define decodeHuffDecMacroVariantWordPos(fstnum, offbucket, symb, stream, ptr, depth) \
143 while ((d< depth) && (pos < fstnum[offbucket + d*2]) ) \
144 { pos = (pos << 1) | bitget(stream,ptr); \
147 symb = (depth==d) ? pos : fstnum[offbucket+d*2+1] + pos - fstnum[offbucket+d*2]; \
149 #define decodeHuffDecMacroVariantWordPos2(HV, symb, stream, ptr, idCanonical) \
152 uint *offfstnum = HV.offsetNumAndFst; \
153 uint *fstnum = HV.zoneNumFst; \
154 register uint offbucket = offfstnum[idCanonical]; \
155 register uint depth = (offfstnum[idCanonical+1] - offbucket)/2; \
158 while ((d< depth) && (pos < fstnum[offbucket + d*2]) ) \
159 { pos = (pos << 1) | bitget(stream,ptr); \
162 symb = (depth==d) ? pos : fstnum[offbucket+d*2+1] + pos - fstnum[offbucket+d*2]; \
167 //fst[1] = zone[1*2];
168 //fst[i] = zone[i*2];
170 //num[0] = zone[0 +1];
171 //num[1] = zone[1*2+1];
172 //num[i] = zone[i*2+1];
176 //#define decodeHuffDecMacroVariantWordPos2bits(HV, symb, stream, ptr, idCanonical) \
178 // register uint d; \
179 // uint sizeBuckbits= HV.sizeBuckbits; \
180 // uint dirbElemSize = HV.dirbElemSize; \
181 // uint sizeFstbits = HV.sizeFstbits; \
182 // uint sizeNumbits = HV.sizeNumbits; \
183 // uint *dirb = HV.Dirb; \
184 // uint *zonefstnum = HV.zoneMem; \
185 // register uint offbucket; \
186 // offbucket = bitread (dirb, idCanonical*dirbElemSize, dirbElemSize); \
187 // register uint depth; \
188 // depth = bitread (dirb, (idCanonical+1)*dirbElemSize, dirbElemSize); \
189 // depth = (depth - offbucket)/sizeBuckbits; \
192 // register uint currfst; \
193 // currfst = bitread (zonefstnum, (offbucket + d*sizeBuckbits), sizeFstbits); \
194 // while ((pos < currfst) ) \
195 // { pos = (pos << 1) | bitget(stream,ptr); \
198 // currfst = bitread (zonefstnum, (offbucket + d*sizeBuckbits), sizeFstbits); \
205 // currNum = bitread (zonefstnum, (offbucket + d*sizeBuckbits+ sizeFstbits), sizeNumbits); \
206 // symb = currNum + pos - currfst; \
212 // int decodeHuffDecVariantWord (uint *fst , uint *symb, uint *stream, uint ptr, uint depth);