The Labs \ Source Viewer \ SSCLI \ System.IO.Compression \ Match

  1. //------------------------------------------------------------------------------
  2. // <copyright file="FastEncoder.cs" company="Microsoft">
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. // </copyright>
  14. //------------------------------------------------------------------------------
  15. namespace System.IO.Compression
  16. {
  17.     using System;
  18.     using System.Diagnostics;
  19.     using System.Globalization;
  20.    
  21.     internal class FastEncoder
  22.     {
  23.         // have we output "bfinal=1"?
  24.         //private bool marked_final_block;
  25.        
  26.         private bool hasBlockHeader;
  27.         // did we output the block header
  28.         private bool hasGzipHeader;
  29.         // did we output the gzip header
  30.         private bool usingGzip;
  31.         // are we generating gzip stream
  32.         private uint gzipCrc32;
  33.         // CRC for gzip stream
  34.         private uint inputStreamSize;
  35.         // stream size for gzip stream
  36.         private FastEncoderWindow inputWindow;
  37.         // input history window
  38.         private DeflateInput inputBuffer;
  39.         private Output output;
  40.         private Match currentMatch;
  41.         // current match in history window
  42.         private bool needsEOB;
  43.         // indicates whether or not we have compressed any data
  44.         public FastEncoder(bool doGZip)
  45.         {
  46.             usingGzip = doGZip;
  47.             inputWindow = new FastEncoderWindow();
  48.             inputBuffer = new DeflateInput();
  49.             output = new Output();
  50.             currentMatch = new Match();
  51.         }
  52.        
  53.         //
  54.         // This function sets the input we need to compress
  55.         // Note we don't make a copy of the buffer for performance reason,
  56.         // so the caller need to be make sure the input is not reused if we didn't finish
  57.         // compressing the input.
  58.         //
  59.         public void SetInput(byte[] input, int startIndex, int count)
  60.         {
  61.             Debug.Assert(inputBuffer.Count == 0, "We have something left in previous input!");
  62.             inputBuffer.Buffer = input;
  63.             inputBuffer.Count = count;
  64.             inputBuffer.StartIndex = startIndex;
  65.         }
  66.        
  67.         // Returns true if we finished compressing the bytes in history window and input buffer
  68.         public bool NeedsInput()
  69.         {
  70.             return inputBuffer.Count == 0 && inputWindow.BytesAvailable == 0;
  71.         }
  72.        
  73.         //
  74.         // Copy the compressed byte to outputBuffer
  75.         // Returns the bytes we have copied. The caller needs to provide the buffer
  76.         // to avoid extra coping.
  77.         //
  78.         public int GetCompressedOutput(byte[] outputBuffer)
  79.         {
  80.             Debug.Assert(!NeedsInput(), "call SetInput before trying to compress!");
  81.            
  82.             output.UpdateBuffer(outputBuffer);
  83.             if (usingGzip && !hasGzipHeader) {
  84.                 // Write the GZIP header only once
  85.                 output.WriteGzipHeader(3);
  86.                 hasGzipHeader = true;
  87.             }
  88.            
  89.             if (!hasBlockHeader) {
  90.                 // Output dynamic block header only once
  91.                 hasBlockHeader = true;
  92.                 output.WritePreamble();
  93.             }
  94.            
  95.             do {
  96.                 // read more input data into the window if there is space available
  97.                 int bytesToCopy = (inputBuffer.Count < inputWindow.FreeWindowSpace) ? inputBuffer.Count : inputWindow.FreeWindowSpace;
  98.                 if (bytesToCopy > 0) {
  99.                     // copy data into history window
  100.                     inputWindow.CopyBytes(inputBuffer.Buffer, inputBuffer.StartIndex, bytesToCopy);
  101.                    
  102.                     if (usingGzip) {
  103.                         // update CRC for gzip stream
  104.                         gzipCrc32 = DecodeHelper.UpdateCrc32(gzipCrc32, inputBuffer.Buffer, inputBuffer.StartIndex, bytesToCopy);
  105.                        
  106.                         uint n = inputStreamSize + (uint)bytesToCopy;
  107.                         if (n < inputStreamSize) {
  108.                             // overflow, gzip doesn't support compressing more than Int32.Maxvalue bytes.
  109.                             throw new InvalidDataException(SR.GetString(SR.StreamSizeOverflow));
  110.                         }
  111.                         inputStreamSize = n;
  112.                     }
  113.                    
  114.                     inputBuffer.ConsumeBytes(bytesToCopy);
  115.                 }
  116.                
  117.                 // compress the bytes in input history window
  118.                 while (inputWindow.BytesAvailable > 0 && output.SafeToWriteTo()) {
  119.                     // Find next match. A match can be a symbol,
  120.                     // a distance/length pair, a symbol followed by a distance/Length pair
  121.                    
  122.                     inputWindow.GetNextSymbolOrMatch(currentMatch);
  123.                    
  124.                     if (currentMatch.State == MatchState.HasSymbol) {
  125.                         output.WriteChar(currentMatch.Symbol);
  126.                     }
  127.                     else if (currentMatch.State == MatchState.HasMatch) {
  128.                         output.WriteMatch(currentMatch.Length, currentMatch.Position);
  129.                     }
  130.                     else {
  131.                         output.WriteChar(currentMatch.Symbol);
  132.                         output.WriteMatch(currentMatch.Length, currentMatch.Position);
  133.                     }
  134.                 }
  135.             }
  136.             while (output.SafeToWriteTo() && !NeedsInput());
  137.            
  138.             // update book keeping needed to write end of block data
  139.             needsEOB = true;
  140.            
  141.             return output.BytesWritten;
  142.             // number of bytes we have written
  143.         }
  144.        
  145.         //
  146.         // Finish the compression. To simply this function, it should only be
  147.         // called when all input are compressed. The left bits and gzip footer will
  148.         // be copied to the outputBuffer.
  149.         //
  150.         public int Finish(byte[] outputBuffer)
  151.         {
  152.             Debug.Assert(NeedsInput(), "only call this when we have no more data to compress!");
  153.            
  154.             output.UpdateBuffer(outputBuffer);
  155.            
  156.             // write EOB data iff we have written anything so far
  157.             if (needsEOB) {
  158.                 // The fast encoder outputs one long block, so it just needs to terminate this block
  159.                 const int EndOfBlockCode = 256;
  160.                 uint code_info = FastEncoderStatics.FastEncoderLiteralCodeInfo[EndOfBlockCode];
  161.                 int code_len = (int)(code_info & 31);
  162.                 output.WriteBits(code_len, code_info >> 5);
  163.                 output.FlushBits();
  164.                
  165.                 if (usingGzip) {
  166.                     output.WriteGzipFooter(gzipCrc32, inputStreamSize);
  167.                 }
  168.             }
  169.            
  170.             return output.BytesWritten;
  171.         }
  172.        
  173.         internal class Output
  174.         {
  175.             private byte[] outputBuf;
  176.             // output buffer
  177.             private int outputPos;
  178.             // output position
  179.             private uint bitBuf;
  180.             // store uncomplete bits
  181.             private int bitCount;
  182.             // number of bits in bitBuffer
  183.             //static private byte[] lengthLookup;
  184.             private static byte[] distLookup;
  185.            
  186.             static Output()
  187.             {
  188.                 //lengthLookup = new byte[512];
  189.                 distLookup = new byte[512];
  190.                
  191.                 GenerateSlotTables();
  192.             }
  193.            
  194.             // Generate the global slot tables which allow us to convert a distance
  195.             // (0..32K) to a distance slot (0..29)
  196.             //
  197.             // Distance table
  198.             // Extra Extra Extra
  199.             // Code Bits Dist Code Bits Dist Code Bits Distance
  200.             // ---- ---- ---- ---- ---- ------ ---- ---- --------
  201.             // 0 0 1 10 4 33-48 20 9 1025-1536
  202.             // 1 0 2 11 4 49-64 21 9 1537-2048
  203.             // 2 0 3 12 5 65-96 22 10 2049-3072
  204.             // 3 0 4 13 5 97-128 23 10 3073-4096
  205.             // 4 1 5,6 14 6 129-192 24 11 4097-6144
  206.             // 5 1 7,8 15 6 193-256 25 11 6145-8192
  207.             // 6 2 9-12 16 7 257-384 26 12 8193-12288
  208.             // 7 2 13-16 17 7 385-512 27 12 12289-16384
  209.             // 8 3 17-24 18 8 513-768 28 13 16385-24576
  210.             // 9 3 25-32 19 8 769-1024 29 13 24577-32768
  211.            
  212.             static internal void GenerateSlotTables()
  213.             {
  214.                 // Initialize the mapping length (0..255) -> length code (0..28)
  215.                 //int length = 0;
  216.                 //for (code = 0; code < FastEncoderStatics.NumLengthBaseCodes-1; code++) {
  217.                 // for (int n = 0; n < (1 << FastEncoderStatics.ExtraLengthBits[code]); n++)
  218.                 // lengthLookup[length++] = (byte) code;
  219.                 //}
  220.                 //lengthLookup[length-1] = (byte) code;
  221.                
  222.                 // Initialize the mapping dist (0..32K) -> dist code (0..29)
  223.                 int dist = 0;
  224.                 int code;
  225.                 for (code = 0; code < 16; code++) {
  226.                     for (int n = 0; n < (1 << FastEncoderStatics.ExtraDistanceBits[code]); n++)
  227.                         distLookup[dist++] = (byte)code;
  228.                 }
  229.                
  230.                 dist >>= 7;
  231.                 // from now on, all distances are divided by 128
  232.                 for (; code < FastEncoderStatics.NumDistBaseCodes; code++) {
  233.                     for (int n = 0; n < (1 << (FastEncoderStatics.ExtraDistanceBits[code] - 7)); n++)
  234.                         distLookup[256 + dist++] = (byte)code;
  235.                 }
  236.             }
  237.            
  238.             // set the output buffer we will be using
  239.             internal void UpdateBuffer(byte[] output)
  240.             {
  241.                 outputBuf = output;
  242.                 outputPos = 0;
  243.             }
  244.            
  245.             internal bool SafeToWriteTo()
  246.             {
  247.                 // can we safely continue writing to output buffer
  248.                 return outputBuf.Length - outputPos > 16;
  249.             }
  250.            
  251.             internal int BytesWritten {
  252.                 get { return outputPos; }
  253.             }
  254.            
  255.             internal int FreeBytes {
  256.                 get { return outputBuf.Length - outputPos; }
  257.             }
  258.            
  259.             // Output the block type and tree structure for our hard-coded trees.
  260.             // Contains following data:
  261.             // "final" block flag 1 bit
  262.             // BLOCKTYPE_DYNAMIC 2 bits
  263.             // FastEncoderLiteralTreeLength
  264.             // FastEncoderDistanceTreeLength
  265.             //
  266.             internal void WritePreamble()
  267.             {
  268.                 Debug.Assert(bitCount == 0, "bitCount must be zero before writing tree bit!");
  269.                 Debug.Assert(FreeBytes >= FastEncoderStatics.FastEncoderTreeStructureData.Length, "Not enough space in output buffer!");
  270.                 Array.Copy(FastEncoderStatics.FastEncoderTreeStructureData, 0, outputBuf, outputPos, FastEncoderStatics.FastEncoderTreeStructureData.Length);
  271.                 outputPos += FastEncoderStatics.FastEncoderTreeStructureData.Length;
  272.                
  273.                 const uint FastEncoderPostTreeBitBuf = 34;
  274.                 const int FastEncoderPostTreeBitCount = 9;
  275.                 bitCount = FastEncoderPostTreeBitCount;
  276.                 bitBuf = FastEncoderPostTreeBitBuf;
  277.             }
  278.            
  279.             internal void WriteMatch(int matchLen, int matchPos)
  280.             {
  281.                 Debug.Assert(matchLen >= FastEncoderWindow.MinMatch && matchLen <= FastEncoderWindow.MaxMatch, "Illegal currentMatch length!");
  282.                 Debug.WriteLineIf(CompressionTracingSwitch.Verbose, String.Format(CultureInfo.InvariantCulture, "Match: {0}:{1}", matchLen, matchPos), "Compression");
  283.                
  284.                 // Get the code information for a match code
  285.                 uint codeInfo = FastEncoderStatics.FastEncoderLiteralCodeInfo[(FastEncoderStatics.NumChars + 1 - FastEncoderWindow.MinMatch) + matchLen];
  286.                 int codeLen = (int)codeInfo & 31;
  287.                 Debug.Assert(codeLen != 0, "Invalid Match Length!");
  288.                 if (codeLen <= 16) {
  289.                     WriteBits(codeLen, codeInfo >> 5);
  290.                 }
  291.                 else {
  292.                     WriteBits(16, (codeInfo >> 5) & 65535);
  293.                     WriteBits(codeLen - 16, codeInfo >> (5 + 16));
  294.                 }
  295.                
  296.                 // Get the code information for a distance code
  297.                 codeInfo = FastEncoderStatics.FastEncoderDistanceCodeInfo[GetSlot(matchPos)];
  298.                 WriteBits((int)(codeInfo & 15), codeInfo >> 8);
  299.                 int extraBits = (int)(codeInfo >> 4) & 15;
  300.                 if (extraBits != 0) {
  301.                     WriteBits(extraBits, (uint)matchPos & FastEncoderStatics.BitMask[extraBits]);
  302.                 }
  303.             }
  304.            
  305.             // write gzip footer
  306.             internal void WriteGzipFooter(uint gzipCrc32, uint inputStreamSize)
  307.             {
  308.                 Debug.Assert(FreeBytes >= 8, "No enough space in output buffer!");
  309.                 outputBuf[outputPos++] = (byte)(gzipCrc32 & 255);
  310.                 outputBuf[outputPos++] = (byte)((gzipCrc32 >> 8) & 255);
  311.                 outputBuf[outputPos++] = (byte)((gzipCrc32 >> 16) & 255);
  312.                 outputBuf[outputPos++] = (byte)((gzipCrc32 >> 24) & 255);
  313.                
  314.                 outputBuf[outputPos++] = (byte)(inputStreamSize & 255);
  315.                 outputBuf[outputPos++] = (byte)((inputStreamSize >> 8) & 255);
  316.                 outputBuf[outputPos++] = (byte)((inputStreamSize >> 16) & 255);
  317.                 outputBuf[outputPos++] = (byte)((inputStreamSize >> 24) & 255);
  318.             }
  319.            
  320.             // write gzip header
  321.             internal void WriteGzipHeader(int compression_level)
  322.             {
  323.                 // only need 11 bytes
  324.                 Debug.Assert(FreeBytes >= 16, "No enough space in output buffer!");
  325.                 Debug.Assert(outputPos == 0, "GZIP header must be at the begining of output!");
  326.                 outputBuf[outputPos++] = 31;
  327.                 // ID1
  328.                 outputBuf[outputPos++] = 139;
  329.                 // ID2
  330.                 outputBuf[outputPos++] = 8;
  331.                 // CM = deflate
  332.                 outputBuf[outputPos++] = 0;
  333.                 // FLG, no text, no crc, no extra, no name, no comment
  334.                 outputBuf[outputPos++] = 0;
  335.                 // MTIME (Modification Time) - no time available
  336.                 outputBuf[outputPos++] = 0;
  337.                 outputBuf[outputPos++] = 0;
  338.                 outputBuf[outputPos++] = 0;
  339.                
  340.                 // XFL
  341.                 // 2 = compressor used max compression, slowest algorithm
  342.                 // 4 = compressor used fastest algorithm
  343.                 if (compression_level == 10)
  344.                     outputBuf[outputPos++] = 2;
  345.                 else
  346.                     outputBuf[outputPos++] = 4;
  347.                
  348.                 outputBuf[outputPos++] = 0;
  349.                 // OS: 0 = FAT filesystem (MS-DOS, OS/2, NT/Win32)
  350.             }
  351.            
  352.             internal void WriteChar(byte b)
  353.             {
  354.                 Debug.WriteLineIf(CompressionTracingSwitch.Verbose, String.Format(CultureInfo.InvariantCulture, "Literal: {0}", b), "Compression");
  355.                 uint code = FastEncoderStatics.FastEncoderLiteralCodeInfo[b];
  356.                 WriteBits((int)code & 31, code >> 5);
  357.             }
  358.            
  359.             internal void WriteBits(int n, uint bits)
  360.             {
  361.                 Debug.Assert(n <= 16, "length must be larger than 16!");
  362.                 bitBuf |= bits << bitCount;
  363.                 bitCount += n;
  364.                 if (bitCount >= 16) {
  365.                     Debug.Assert(outputBuf.Length - outputPos >= 2, "No enough space in output buffer!");
  366.                     outputBuf[outputPos++] = unchecked((byte)bitBuf);
  367.                     outputBuf[outputPos++] = unchecked((byte)(bitBuf >> 8));
  368.                     bitCount -= 16;
  369.                     bitBuf >>= 16;
  370.                 }
  371.             }
  372.            
  373.             // Return the position slot (0...29) of a match offset (0...32767)
  374.             internal int GetSlot(int pos)
  375.             {
  376.                 return distLookup[((pos) < 256) ? (pos) : (256 + ((pos) >> 7))];
  377.             }
  378.            
  379.             // write the bits left in the output as bytes
  380.             internal void FlushBits()
  381.             {
  382.                 // flush bits from bit buffer to output buffer
  383.                 while (bitCount >= 8) {
  384.                     outputBuf[outputPos++] = unchecked((byte)bitBuf);
  385.                     bitCount -= 8;
  386.                     bitBuf >>= 8;
  387.                 }
  388.                
  389.                 if (bitCount > 0) {
  390.                     outputBuf[outputPos++] = unchecked((byte)bitBuf);
  391.                     bitCount = 0;
  392.                 }
  393.             }
  394.         }
  395.     }
  396.    
  397.     internal class DeflateInput
  398.     {
  399.         private byte[] buffer;
  400.         private int count;
  401.         private int startIndex;
  402.        
  403.         internal byte[] Buffer {
  404.             get { return buffer; }
  405.             set { buffer = value; }
  406.         }
  407.        
  408.         internal int Count {
  409.             get { return count; }
  410.             set { count = value; }
  411.         }
  412.        
  413.         internal int StartIndex {
  414.             get { return startIndex; }
  415.             set { startIndex = value; }
  416.         }
  417.        
  418.         internal void ConsumeBytes(int n)
  419.         {
  420.             Debug.Assert(n <= count, "Should use more bytes than what we have in the buffer");
  421.             startIndex += n;
  422.             count -= n;
  423.             Debug.Assert(startIndex + count <= buffer.Length, "Input buffer is in invalid state!");
  424.         }
  425.     }
  426.    
  427.    
  428.     internal enum MatchState
  429.     {
  430.         HasSymbol = 1,
  431.         HasMatch = 2,
  432.         HasSymbolAndMatch = 3
  433.     }
  434.    
  435.     // This class represents a match in the history window
  436.     internal class Match
  437.     {
  438.         MatchState state;
  439.         int pos;
  440.         int len;
  441.         byte symbol;
  442.        
  443.         internal MatchState State {
  444.             get { return state; }
  445.             set { state = value; }
  446.         }
  447.        
  448.         internal int Position {
  449.             get { return pos; }
  450.             set { pos = value; }
  451.         }
  452.        
  453.         internal int Length {
  454.             get { return len; }
  455.             set { len = value; }
  456.         }
  457.        
  458.         internal byte Symbol {
  459.             get { return symbol; }
  460.             set { symbol = value; }
  461.         }
  462.        
  463.     }
  464.    
  465.     static internal class FastEncoderStatics
  466.     {
  467.         // static information for encoding, DO NOT MODIFY
  468.        
  469.         static internal readonly byte[] FastEncoderTreeStructureData = {237, 189, 7, 96, 28, 73, 150, 37, 38, 47,
  470.         109, 202, 123, 127, 74, 245, 74, 215, 224, 116,
  471.         161, 8, 128, 96, 19, 36, 216, 144, 64, 16,
  472.         236, 193, 136, 205, 230, 146, 236, 29, 105, 71,
  473.         35, 41, 171, 42, 129, 202, 101, 86, 101, 93,
  474.         102, 22, 64, 204, 237, 157, 188, 247, 222, 123,
  475.         239, 189, 247, 222, 123, 239, 189, 247, 186, 59,
  476.         157, 78, 39, 247, 223, 255, 63, 92, 102, 100,
  477.         1, 108, 246, 206, 74, 218, 201, 158, 33, 128,
  478.         170, 200, 31, 63, 126, 124, 31, 63};
  479.        
  480.         // Output a currentMatch with length matchLen (>= MIN_MATCH) and displacement matchPos
  481.         //
  482.         // Optimisation: unlike the other encoders, here we have an array of codes for each currentMatch
  483.         // length (not just each currentMatch length slot), complete with all the extra bits filled in, in
  484.         // a single array element.
  485.         //
  486.         // There are many advantages to doing this:
  487.         //
  488.         // 1. A single array lookup on g_FastEncoderLiteralCodeInfo, instead of separate array lookups
  489.         // on g_LengthLookup (to get the length slot), g_FastEncoderLiteralTreeLength,
  490.         // g_FastEncoderLiteralTreeCode, g_ExtraLengthBits, and g_BitMask
  491.         //
  492.         // 2. The array is an array of ULONGs, so no access penalty, unlike for accessing those USHORT
  493.         // code arrays in the other encoders (although they could be made into ULONGs with some
  494.         // modifications to the source).
  495.         //
  496.         // Note, if we could guarantee that codeLen <= 16 always, then we could skip an if statement here.
  497.         //
  498.         // A completely different optimisation is used for the distance codes since, obviously, a table for
  499.         // all 8192 distances combining their extra bits is not feasible. The distance codeinfo table is
  500.         // made up of code[], len[] and # extraBits for this code.
  501.         //
  502.         // The advantages are similar to the above; a ULONG array instead of a USHORT and BYTE array, better
  503.         // cache locality, fewer memory operations.
  504.         //
  505.        
  506.        
  507.         // Encoding information for literal and Length.
  508.         // The least 5 significant bits are the length
  509.         // and the rest is the code bits.
  510.        
  511.         static internal readonly uint[] FastEncoderLiteralCodeInfo = {55278, 317422, 186350, 448494, 120814, 382958, 251886, 514030, 14318, 51180,
  512.         294, 276462, 145390, 407534, 79854, 341998, 210926, 473070, 47086, 309230,
  513.         178158, 440302, 112622, 374766, 243694, 505838, 30702, 292846, 161774, 423918,
  514.         6125, 96238, 1318, 358382, 9194, 116716, 227310, 489454, 137197, 25578,
  515.         2920, 3817, 23531, 5098, 1127, 7016, 3175, 12009, 1896, 5992,
  516.         3944, 7913, 8040, 16105, 21482, 489, 232, 8681, 4585, 4328,
  517.         12777, 13290, 2280, 63470, 325614, 6376, 2537, 1256, 10729, 5352,
  518.         6633, 29674, 56299, 3304, 15339, 194542, 14825, 3050, 1513, 19434,
  519.         9705, 10220, 5609, 13801, 3561, 11242, 75756, 48107, 456686, 129006,
  520.         42988, 31723, 391150, 64491, 260078, 522222, 4078, 806, 615, 2663,
  521.         1639, 1830, 7400, 744, 3687, 166, 108524, 11753, 1190, 359,
  522.         2407, 678, 1383, 71661, 1702, 422, 1446, 3431, 4840, 2792,
  523.         7657, 6888, 2027, 202733, 26604, 38893, 169965, 266222, 135150, 397294,
  524.         69614, 331758, 200686, 462830, 36846, 298990, 167918, 430062, 102382, 364526,
  525.         233454, 495598, 20462, 282606, 151534, 413678, 85998, 348142, 217070, 479214,
  526.         53230, 315374, 184302, 446446, 118766, 380910, 249838, 511982, 12270, 274414,
  527.         143342, 405486, 77806, 339950, 208878, 471022, 45038, 307182, 176110, 438254,
  528.         110574, 372718, 241646, 503790, 28654, 290798, 159726, 421870, 94190, 356334,
  529.         225262, 487406, 61422, 323566, 192494, 454638, 126958, 389102, 258030, 520174,
  530.         8174, 270318, 139246, 401390, 73710, 335854, 204782, 466926, 40942, 303086,
  531.         172014, 434158, 106478, 368622, 237550, 499694, 24558, 286702, 155630, 417774,
  532.         90094, 352238, 221166, 483310, 57326, 319470, 188398, 450542, 122862, 385006,
  533.         253934, 516078, 16366, 278510, 147438, 409582, 81902, 344046, 212974, 475118,
  534.         49134, 311278, 180206, 442350, 114670, 376814, 245742, 507886, 32750, 294894,
  535.         163822, 425966, 98286, 104429, 235501, 22509, 360430, 153581, 229358, 88045,
  536.         491502, 219117, 65518, 327662, 196590, 458734, 131054, 132, 3, 388,
  537.         68, 324, 197, 709, 453, 966, 1990, 38, 1062, 935,
  538.         2983, 1959, 4007, 551, 1575, 2599, 3623, 104, 2152, 4200,
  539.         6248, 873, 4969, 9065, 13161, 1770, 9962, 18154, 26346, 5867,
  540.         14059, 22251, 30443, 38635, 46827, 55019, 63211, 15852, 32236, 48620,
  541.         65004, 81388, 97772, 114156, 130540, 27629, 60397, 93165, 125933, 158701,
  542.         191469, 224237, 257005, 1004, 17388, 33772, 50156, 66540, 82924, 99308,
  543.         115692, 7150, 39918, 72686, 105454, 138222, 170990, 203758, 236526, 269294,
  544.         302062, 334830, 367598, 400366, 433134, 465902, 498670, 92144, 223216, 354288,
  545.         485360, 616432, 747504, 878576, 1009648, 1140720, 1271792, 1402864, 1533936, 1665008,
  546.         1796080, 1927152, 2058224, 34799, 100335, 165871, 231407, 296943, 362479, 428015,
  547.         493551, 559087, 624623, 690159, 755695, 821231, 886767, 952303, 1017839, 59376,
  548.         190448, 321520, 452592, 583664, 714736, 845808, 976880, 1107952, 1239024, 1370096,
  549.         1501168, 1632240, 1763312, 1894384, 2025456, 393203, 917491, 1441779, 1966067, 2490355,
  550.         3014643, 3538931, 4063219, 4587507, 5111795, 5636083, 6160371, 6684659, 7208947, 7733235,
  551.         8257523, 8781811, 9306099, 9830387, 10354675, 10878963, 11403251, 11927539, 12451827, 12976115,
  552.         13500403, 14024691, 14548979, 15073267, 15597555, 16121843, 16646131, 262131, 786419, 1310707,
  553.         1834995, 2359283, 2883571, 3407859, 3932147, 4456435, 4980723, 5505011, 6029299, 6553587,
  554.         7077875, 7602163, 8126451, 8650739, 9175027, 9699315, 10223603, 10747891, 11272179, 11796467,
  555.         12320755, 12845043, 13369331, 13893619, 14417907, 14942195, 15466483, 15990771, 16515059, 524275,
  556.         1048563, 1572851, 2097139, 2621427, 3145715, 3670003, 4194291, 4718579, 5242867, 5767155,
  557.         6291443, 6815731, 7340019, 7864307, 8388595, 8912883, 9437171, 9961459, 10485747, 11010035,
  558.         11534323, 12058611, 12582899, 13107187, 13631475, 14155763, 14680051, 15204339, 15728627, 16252915,
  559.         16777203, 124913, 255985, 387057, 518129, 649201, 780273, 911345, 1042417, 1173489,
  560.         1304561, 1435633, 1566705, 1697777, 1828849, 1959921, 2090993, 2222065, 2353137, 2484209,
  561.         2615281, 2746353, 2877425, 3008497, 3139569, 3270641, 3401713, 3532785, 3663857, 3794929,
  562.         3926001, 4057073, 18411};
  563.        
  564.         static internal readonly uint[] FastEncoderDistanceCodeInfo = {3846, 130826, 261899, 524043, 65305, 16152, 48936, 32552, 7991, 24375,
  565.         3397, 12102, 84, 7509, 2148, 869, 1140, 4981, 3204, 644,
  566.         2708, 1684, 3748, 420, 2484, 2997, 1476, 7109, 2005, 6101,
  567.         0, 256};
  568.        
  569.         static internal readonly uint[] BitMask = {0, 1, 3, 7, 15, 31, 63, 127, 255, 511,
  570.         1023, 2047, 4095, 8191, 16383, 32767};
  571.         static internal readonly byte[] ExtraLengthBits = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
  572.         1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
  573.         4, 4, 4, 4, 5, 5, 5, 5, 0};
  574.         static internal readonly byte[] ExtraDistanceBits = {0, 0, 0, 0, 1, 1, 2, 2, 3, 3,
  575.         4, 4, 5, 5, 6, 6, 7, 7, 8, 8,
  576.         9, 9, 10, 10, 11, 11, 12, 12, 13, 13,
  577.         0, 0};
  578.         internal const int NumChars = 256;
  579.         internal const int NumLengthBaseCodes = 29;
  580.         internal const int NumDistBaseCodes = 30;
  581.        
  582.        
  583.     }
  584. }

Developer Fusion