/* ========================================================================== *Send the block data compressed using the given Huffman trees */ void compress_block( DeflateCT[] ltree, // literal tree DeflateCT[] dtree // distance tree ) { int dist; // distance of matched string int lc; // match length or unmatched char (if dist==0) int lx=0; // running index in l_buf int dx=0; // running index in d_buf int fx=0; // running index in flag_buf int flag=0; // current flags int code; // the code to send int extra; // number of extra bits to send if(last_lit!=0)do{ if((lx&7)==0) flag=flag_buf[fx++]; lc=l_buf[lx++]&0xff; if((flag&1)==0){ SEND_CODE(lc,ltree);/* send a literal byte */ // Tracecv(isgraph(lc),(stderr," '%c' ",lc)); }else{ // Here,lc is the match length-MIN_MATCH code=length_code[lc]; SEND_CODE(code+LITERALS+1,ltree);// send the length code extra=extra_lbits[code]; if(extra!=0){ lc-=base_length[code]; send_bits(lc,extra);// send the extra length bits } dist=d_buf[dx++]; // Here,dist is the match distance-1 code=D_CODE(dist); // Assert (code<D_CODES,"bad d_code"); SEND_CODE(code,dtree); // send the distance code extra=extra_dbits[code]; if(extra!=0){ dist-=base_dist[code]; send_bits(dist,extra); // send the extra distance bits } } // literal or match pair ? flag>>=1; }while(lx<last_lit); SEND_CODE(END_BLOCK,ltree); }
/* ========================================================================== *Send a literal or distance tree in compressed form,using the codes in *bl_tree. */ void send_tree( DeflateCT[] tree,// the tree to be scanned int max_code ) { // and its largest code of non zero frequency int n; // iterates over all tree elements int prevlen=-1; // last emitted length int curlen; // length of current code int nextlen=tree[0].dl; // length of next code int count=0; // repeat count of the current code int max_count=7; // max repeat count int min_count=4; // min repeat count /* tree[max_code+1].dl=-1;*/ /* guard already set */ if(nextlen==0){ max_count=138; min_count=3; } for(n=0;n<=max_code;n++){ curlen=nextlen; nextlen=tree[n+1].dl; if(++count<max_count&&curlen==nextlen){ continue; }else if(count<min_count){ do{ SEND_CODE(curlen,bl_tree);}while(--count!=0); }else if(curlen!=0){ if(curlen!=prevlen){ SEND_CODE(curlen,bl_tree); count--; } // Assert(count>=3&&count<=6," 3_6?"); SEND_CODE(REP_3_6,bl_tree); send_bits(count-3,2); }else if(count<=10){ SEND_CODE(REPZ_3_10,bl_tree); send_bits(count-3,3); }else{ SEND_CODE(REPZ_11_138,bl_tree); send_bits(count-11,7); } count=0; prevlen=curlen; if(nextlen==0){ max_count=138; min_count=3; }else if(curlen==nextlen){ max_count=6; min_count=3; }else{ max_count=7; min_count=4; } } }
/* ========================================================================== *Compares to subtrees,using the tree depth as tie breaker when *the subtrees have equal frequency. This minimizes the worst case length. */ bool SMALLER(DeflateCT[] tree,int n,int m) { return tree[n].fc<tree[m].fc||tree[n].fc==tree[m].fc&&depth[n]<=depth[m]; }
/* Send a code of the given tree. c and tree must not have side effects */ void SEND_CODE(int c,DeflateCT[] tree) { this.send_bits(tree[c].fc,tree[c].dl); }
/* ========================================================================== *Scan a literal or distance tree to determine the frequencies of the codes *in the bit length tree. Updates opt_len to take into account the repeat *counts. (The contribution of the bit length codes will be added later *during the construction of bl_tree.) */ void scan_tree( DeflateCT[] tree,// the tree to be scanned int max_code ) { // and its largest code of non zero frequency int n; // iterates over all tree elements int prevlen=-1; // last emitted length int curlen; // length of current code int nextlen=tree[0].dl; // length of next code int count=0; // repeat count of the current code int max_count=7; // max repeat count int min_count=4; // min repeat count if(nextlen==0){ max_count=138; min_count=3; } tree[max_code+1].dl=0xffff;// guard for(n=0;n<=max_code;n++){ curlen=nextlen; nextlen=tree[n+1].dl; if(++count<max_count&&curlen==nextlen) continue; else if(count<min_count) bl_tree[curlen].fc+=count; else if(curlen!=0){ if(curlen!=prevlen) bl_tree[curlen].fc++; bl_tree[REP_3_6].fc++; }else if(count<=10){ bl_tree[REPZ_3_10].fc++; }else{ bl_tree[REPZ_11_138].fc++; } count=0;prevlen=curlen; if(nextlen==0){ max_count=138; min_count=3; }else if(curlen==nextlen){ max_count=6; min_count=3; }else{ max_count=7; min_count=4; } } }
/* ========================================================================== *Restore the heap property by moving down the tree starting at node k, *exchanging a node with the smallest of its two sons if necessary,stopping *when the heap property is re-established (each father smaller than its *two sons). */ void pqdownheap( DeflateCT[] tree, // the tree to restore int k ) { // node to move down int v=heap[k]; int j=k<<1; // left son of k while(j<=heap_len){ // Set j to the smallest of the two sons: if(j<heap_len&&SMALLER(tree,heap[j+1],heap[j]))j++; // Exit if v is smaller than both sons if(SMALLER(tree,v,heap[j]))break; // Exchange v with the smallest son heap[k]=heap[j]; k=j; // And continue down the tree,setting j to the left son of k j<<=1; } heap[k]=v; }
/* routines (deflate)*/ DeflateCT[] new_ctarray(int n) { DeflateCT[] r=new DeflateCT[n]; for(int i=0;i<n;i++)r[i]=new DeflateCT(); return r; }
/* ========================================================================== *Generate the codes for a given tree and bit counts (which need not be *optimal). *IN assertion: the array bl_count contains the bit length statistics for *the given tree and the field len is set for all tree elements. *OUT assertion: the field code is set for all tree elements of non * zero code length. */ void gen_codes( DeflateCT[] tree, // the tree to decorate int max_code ) { // largest code with non zero frequency int[] next_code=new int[MAX_BITS+1];// next code value for each bit length int code=0; // running code value int bits; // bit index int n; // code index /* The distribution counts are first used to generate the code values *without bit reversal. */ for(bits=1;bits<=MAX_BITS;bits++){ code=((code+bl_count[bits-1])<<1); next_code[bits]=code; } /* Check that the bit counts in bl_count are consistent. The last code *must be all ones. */ // Assert (code+encoder->bl_count[MAX_BITS]-1==(1<<MAX_BITS)-1, // "inconsistent bit counts"); // Tracev((stderr,"\ngen_codes: max_code %d ",max_code)); for(n=0;n<=max_code;n++){ int len=tree[n].dl; if(len==0)continue; // Now reverse the bits tree[n].fc=bi_reverse(next_code[len]++,len); // Tracec(tree!=static_ltree,(stderr,"\nn %3d %c l %2d c %4x (%x)", // n,(isgraph(n)?n:' '),len,tree[n].fc,next_code[len]-1)); } }