⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 deflaterengine.cs

📁 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的
💻 CS
📖 第 1 页 / 共 2 页
字号:
// DeflaterEngine.cs// Copyright (C) 2001 Mike Krueger//// This file was translated from java, it was part of the GNU Classpath// Copyright (C) 2001 Free Software Foundation, Inc.//// This program is free software; you can redistribute it and/or// modify it under the terms of the GNU General Public License// as published by the Free Software Foundation; either version 2// of the License, or (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.//// Linking this library statically or dynamically with other modules is// making a combined work based on this library.  Thus, the terms and// conditions of the GNU General Public License cover the whole// combination.// // As a special exception, the copyright holders of this library give you// permission to link this library with independent modules to produce an// executable, regardless of the license terms of these independent// modules, and to copy and distribute the resulting executable under// terms of your choice, provided that you also meet, for each linked// independent module, the terms and conditions of the license of that// module.  An independent module is a module which is not derived from// or based on this library.  If you modify this library, you may extend// this exception to your version of the library, but you are not// obligated to do so.  If you do not wish to do so, delete this// exception statement from your version.using System;using ICSharpCode.SharpZipLib.Checksums;namespace ICSharpCode.SharpZipLib.Zip.Compression {		public enum DeflateStrategy 	{		// The default strategy.		Default  = 0,				// This strategy will only allow longer string repetitions.  It is		// useful for random data with a small character set.		Filtered = 1,				// This strategy will not look for string repetitions at all.  It		// only encodes with Huffman trees (which means, that more common		// characters get a smaller encoding.		HuffmanOnly = 2	}		public class DeflaterEngine : DeflaterConstants 	{		static int TOO_FAR = 4096;				int ins_h;		//		private byte[] buffer;		short[] head;		short[] prev;				int    matchStart, matchLen;		bool   prevAvailable;		int    blockStart;		int    strstart, lookahead;		byte[] window;				DeflateStrategy strategy;		int max_chain, max_lazy, niceLength, goodLength;				/// <summary>		/// The current compression function.		/// </summary>		int comprFunc;				/// <summary>		/// The input data for compression.		/// </summary>		byte[] inputBuf;				/// <summary>		/// The total bytes of input read.		/// </summary>		int totalIn;				/// <summary>		/// The offset into inputBuf, where input data starts.		/// </summary>		int inputOff;				/// <summary>		/// The end offset of the input data.		/// </summary>		int inputEnd;				DeflaterPending pending;		DeflaterHuffman huffman;				/// <summary>		/// The adler checksum		/// </summary>		Adler32 adler;				public DeflaterEngine(DeflaterPending pending) 		{			this.pending = pending;			huffman = new DeflaterHuffman(pending);			adler = new Adler32();						window = new byte[2 * WSIZE];			head   = new short[HASH_SIZE];			prev   = new short[WSIZE];						/* We start at index 1, to avoid a implementation deficiency, that			* we cannot build a repeat pattern at index 0.			*/			blockStart = strstart = 1;		}				public void Reset()		{			huffman.Reset();			adler.Reset();			blockStart = strstart = 1;			lookahead = 0;			totalIn   = 0;			prevAvailable = false;			matchLen = MIN_MATCH - 1;						for (int i = 0; i < HASH_SIZE; i++) 			{				head[i] = 0;			}						for (int i = 0; i < WSIZE; i++) 			{				prev[i] = 0;			}		}				public void ResetAdler()		{			adler.Reset();		}				public int Adler 		{			get 			{				return (int)adler.Value;			}		}				public int TotalIn 		{			get 			{				return totalIn;			}		}				public DeflateStrategy Strategy 		{			get 			{				return strategy;			}			set 			{				strategy = value;			}		}				public void SetLevel(int lvl)		{			goodLength = DeflaterConstants.GOOD_LENGTH[lvl];			max_lazy   = DeflaterConstants.MAX_LAZY[lvl];			niceLength = DeflaterConstants.NICE_LENGTH[lvl];			max_chain  = DeflaterConstants.MAX_CHAIN[lvl];						if (DeflaterConstants.COMPR_FUNC[lvl] != comprFunc) 			{				//				if (DeflaterConstants.DEBUGGING) {				//					//Console.WriteLine("Change from "+comprFunc +" to "				//					                  + DeflaterConstants.COMPR_FUNC[lvl]);				//				}				switch (comprFunc) 				{					case DEFLATE_STORED:						if (strstart > blockStart) 						{							huffman.FlushStoredBlock(window, blockStart,								strstart - blockStart, false);							blockStart = strstart;						}						UpdateHash();						break;					case DEFLATE_FAST:						if (strstart > blockStart) 						{							huffman.FlushBlock(window, blockStart, strstart - blockStart,								false);							blockStart = strstart;						}						break;					case DEFLATE_SLOW:						if (prevAvailable) 						{							huffman.TallyLit(window[strstart-1] & 0xff);						}						if (strstart > blockStart) 						{							huffman.FlushBlock(window, blockStart, strstart - blockStart,								false);							blockStart = strstart;						}						prevAvailable = false;						matchLen = MIN_MATCH - 1;						break;				}				comprFunc = COMPR_FUNC[lvl];			}		}				private void UpdateHash() 		{			//			if (DEBUGGING) {			//				//Console.WriteLine("updateHash: "+strstart);			//			}			ins_h = (window[strstart] << HASH_SHIFT) ^ window[strstart + 1];		}				private int InsertString() 		{			short match;			int hash = ((ins_h << HASH_SHIFT) ^ window[strstart + (MIN_MATCH -1)]) & HASH_MASK;						//			if (DEBUGGING) {			//				if (hash != (((window[strstart] << (2*HASH_SHIFT)) ^ 			//				              (window[strstart + 1] << HASH_SHIFT) ^ 			//				              (window[strstart + 2])) & HASH_MASK)) {			//						throw new Exception("hash inconsistent: "+hash+"/"			//						                    +window[strstart]+","			//						                    +window[strstart+1]+","			//						                    +window[strstart+2]+","+HASH_SHIFT);			//					}			//			}						prev[strstart & WMASK] = match = head[hash];			head[hash] = (short)strstart;			ins_h = hash;			return match & 0xffff;		}				void SlideWindow()		{			Array.Copy(window, WSIZE, window, 0, WSIZE);			matchStart -= WSIZE;			strstart   -= WSIZE;			blockStart -= WSIZE;						/* Slide the hash table (could be avoided with 32 bit values			 * at the expense of memory usage).			 */			for (int i = 0; i < HASH_SIZE; ++i) 			{				int m = head[i] & 0xffff;				head[i] = (short)(m >= WSIZE ? (m - WSIZE) : 0);			}						/* Slide the prev table. */			for (int i = 0; i < WSIZE; i++) 			{				int m = prev[i] & 0xffff;				prev[i] = (short)(m >= WSIZE ? (m - WSIZE) : 0);			}		}				public void FillWindow()		{			/* If the window is almost full and there is insufficient lookahead,			 * move the upper half to the lower one to make room in the upper half.			 */			if (strstart >= WSIZE + MAX_DIST) 			{				SlideWindow();			}						/* If there is not enough lookahead, but still some input left,			 * read in the input			 */			while (lookahead < DeflaterConstants.MIN_LOOKAHEAD && inputOff < inputEnd) 			{				int more = 2 * WSIZE - lookahead - strstart;								if (more > inputEnd - inputOff) 				{					more = inputEnd - inputOff;				}								System.Array.Copy(inputBuf, inputOff, window, strstart + lookahead, more);				adler.Update(inputBuf, inputOff, more);								inputOff += more;				totalIn  += more;				lookahead += more;			}						if (lookahead >= MIN_MATCH) 			{				UpdateHash();			}		}				private bool FindLongestMatch(int curMatch) 		{			int chainLength = this.max_chain;			int niceLength  = this.niceLength;			short[] prev    = this.prev;			int scan        = this.strstart;			int match;			int best_end = this.strstart + matchLen;			int best_len = Math.Max(matchLen, MIN_MATCH - 1);						int limit = Math.Max(strstart - MAX_DIST, 0);						int strend = strstart + MAX_MATCH - 1;			byte scan_end1 = window[best_end - 1];			byte scan_end  = window[best_end];						/* Do not waste too much time if we already have a good match: */			if (best_len >= this.goodLength) 			{				chainLength >>= 2;			}						/* Do not look for matches beyond the end of the input. This is necessary			* to make deflate deterministic.			*/			if (niceLength > lookahead) 			{				niceLength = lookahead;			}						if (DeflaterConstants.DEBUGGING && strstart > 2 * WSIZE - MIN_LOOKAHEAD) 			{				throw new InvalidOperationException("need lookahead");			}						do 			{				if (DeflaterConstants.DEBUGGING && curMatch >= strstart) 				{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -