Beispiel #1
0
    /* ==========================================================================
      *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);
    }
Beispiel #2
0
    /* ==========================================================================
      *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;
            }
        }
    }
Beispiel #3
0
 /* ==========================================================================
 *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];
 }
Beispiel #4
0
 /* 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);
 }
Beispiel #5
0
    /* ==========================================================================
    *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;
            }
        }
    }
Beispiel #6
0
    /* ==========================================================================
    *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;
    }
Beispiel #7
0
 /* 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;
 }
Beispiel #8
0
    /* ==========================================================================
      *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));
        }
    }