Beispiel #1
0
		// ===========================================================================
		// Send the block data compressed using the given Huffman trees

		// ltree:	literal tree
		// dtree:	distance tree
		static void compress_block(deflate_state s, ct_data[] ltree, ct_data[] dtree)
		{
			uint dist;	// distance of matched string
			int lc;		// match length or unmatched char (if dist == 0)
			uint lx=0;	// running index in l_buf
			uint code;	// the code to send
			int extra;	// number of extra bits to send

			if(s.last_lit!=0)
			{
				do
				{
					dist=s.d_buf[lx];
					lc=s.l_buf[lx++];
					if(dist==0)
					{
						send_code(s, 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(s, (int)(code+LITERALS+1), ltree); // send the length code
						extra=extra_lbits[code];
						if(extra!=0)
						{
							lc-=base_length[code];
							send_bits(s, lc, extra);		// send the extra length bits
						}
						dist--; // dist is now the match distance - 1
						code=(dist<256?_dist_code[dist]:_dist_code[256+(dist>>7)]);
						//Assert (code < D_CODES, "bad d_code");

						send_code(s, (int)code, dtree);		// send the distance code
						extra=extra_dbits[code];
						if(extra!=0)
						{
							dist-=(uint)base_dist[code];
							send_bits(s, (int)dist, extra);	// send the extra distance bits
						}
					} // literal or match pair ?
				} while(lx<s.last_lit);
			}
			send_code(s, END_BLOCK, ltree);
			s.last_eob_len=ltree[END_BLOCK].Len;
		}
Beispiel #2
0
		// ===========================================================================
		// Scan a literal or distance tree to determine the frequencies of the codes
		// in the bit length tree.

		// tree:		the tree to be scanned
		// max_code:	and its largest code of non zero frequency
		static void scan_tree(deflate_state s, ct_data[] tree, int max_code)
		{
			int n;						// iterates over all tree elements
			int prevlen=-1;				// last emitted length
			int curlen;					// length of current code
			int nextlen=tree[0].Len;	// 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].Len=(ushort)0xffff; // guard

			for(n=0; n<=max_code; n++)
			{
				curlen=nextlen; nextlen=tree[n+1].Len;
				if(++count<max_count&&curlen==nextlen) continue;

				if(count<min_count) s.bl_tree[curlen].Freq+=(ushort)count;
				else if(curlen!=0)
				{
					if(curlen!=prevlen) s.bl_tree[curlen].Freq++;
					s.bl_tree[REP_3_6].Freq++;
				}
				else if(count<=10) s.bl_tree[REPZ_3_10].Freq++;
				else s.bl_tree[REPZ_11_138].Freq++;

				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
		// ===========================================================================
		// Send a literal or distance tree in compressed form, using the codes in bl_tree.

		// tree:		the tree to be scanned
		// max_code:	and its largest code of non zero frequency
		static void send_tree(deflate_state s, ct_data[] tree, int max_code)
		{
			int n;						// iterates over all tree elements
			int prevlen=-1;				// last emitted length
			int curlen;					// length of current code
			int nextlen=tree[0].Len;	// 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].Len = -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].Len;
				if(++count<max_count&&curlen==nextlen) continue;

				if(count<min_count)
				{
					do { send_code(s, curlen, s.bl_tree); } while(--count!=0);
				}
				else if(curlen!=0)
				{
					if(curlen!=prevlen) { send_code(s, curlen, s.bl_tree); count--; }

					//Assert(count>=3&&count<=6, " 3_6?");
					send_code(s, REP_3_6, s.bl_tree); send_bits(s, count-3, 2);
				}
				else if(count<=10) { send_code(s, REPZ_3_10, s.bl_tree); send_bits(s, count-3, 3); }
				else { send_code(s, REPZ_11_138, s.bl_tree); send_bits(s, 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 #4
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.

		// tree:		the tree to decorate
		// max_code:	largest code with non zero frequency
		// bl_count:	number of codes at each bit length
		static void gen_codes(ct_data[] tree, int max_code, ushort[] bl_count)
		{
			ushort[] next_code=new ushort[MAX_BITS+1];	// next code value for each bit length
			ushort 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++) next_code[bits]=code=(ushort)((code+bl_count[bits-1])<<1);

			// Check that the bit counts in bl_count are consistent. The last code
			// must be all ones.
			//Assert (code + 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].Len;
				if(len==0) continue;
				// Now reverse the bits
				tree[n].Code=bi_reverse(next_code[len]++, len);

				//Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ", n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
			}
		}
Beispiel #5
0
		// ===========================================================================
		// Remove the smallest element from the heap and recreate the heap with
		// one less element. Updates heap and heap_len.
		//#define pqremove(s, tree, top) \
		//		top = s.heap[SMALLEST]; \
		//		s.heap[SMALLEST] = s.heap[s.heap_len--]; \
		//		pqdownheap(s, tree, SMALLEST);

		// ===========================================================================
		// Compares to subtrees, using the tree depth as tie breaker when
		// the subtrees have equal frequency. This minimizes the worst case length.
		//#define smaller(tree, n, m, depth) \
		//		(tree[n].Freq < tree[m].Freq || \
		//		(tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))

		// ===========================================================================
		// 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).

		// tree:	the tree to restore
		// k:		node to move down
		static void pqdownheap(deflate_state s, ct_data[] tree, int k)
		{
			int v=s.heap[k];
			int j=k<<1;  // left son of k
			while(j<=s.heap_len)
			{
				// Set j to the smallest of the two sons:
				//was if (j < s.heap_len && smaller(tree, s.heap[j+1], s.heap[j], s.depth)) 
				if(j<s.heap_len&&(tree[s.heap[j+1]].Freq<tree[s.heap[j]].Freq||
					(tree[s.heap[j+1]].Freq==tree[s.heap[j]].Freq&&s.depth[s.heap[j+1]]<=s.depth[s.heap[j]]))) j++;

				// Exit if v is smaller than both sons
				//was if (smaller(tree, v, s.heap[j], s.depth)) break;
				if(tree[v].Freq<tree[s.heap[j]].Freq||
					(tree[v].Freq==tree[s.heap[j]].Freq&&s.depth[v]<=s.depth[s.heap[j]])) break;

				// Exchange v with the smallest son
				s.heap[k]=s.heap[j]; k=j;

				// And continue down the tree, setting j to the left son of k
				j<<=1;
			}
			s.heap[k]=v;
		}
Beispiel #6
0
		// ===========================================================================
		// Local (static) routines in this file.
		//

		// Send a code of the given tree. c and tree must not have side effects
		//#define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
		static void send_code(deflate_state s, int c, ct_data[] tree)
		{
			ushort value=tree[c].Code;
			ushort len=tree[c].Len;
			if(s.bi_valid>(int)Buf_size-len)
			{
				int val=value;
				s.bi_buf|=(ushort)(val<<s.bi_valid);
				//was put_short(s, s.bi_buf);
				s.pending_buf[s.pending++]=(byte)(s.bi_buf&0xff);
				s.pending_buf[s.pending++]=(byte)((ushort)s.bi_buf>>8);
				s.bi_buf=(ushort)(val>>(Buf_size-s.bi_valid));
				s.bi_valid+=len-Buf_size;
			}
			else
			{
				s.bi_buf|=(ushort)(value<<s.bi_valid);
				s.bi_valid+=len;
			}
		}
Beispiel #7
0
			public int max_length;					// max bit length for the codes

			public static_tree_desc(ct_data[] static_tree, int[] extra_bits, int extra_base, int elems, int max_length)
			{
				this.static_tree=static_tree;
				this.extra_bits=extra_bits;
				this.extra_base=extra_base;
				this.elems=elems;
				this.max_length=max_length;
			}
Beispiel #8
0
			public ct_data(ct_data data)
			{
				freq=data.freq;
				dad=data.dad;
			}