namespace com.hitrust.util.Zip.Compression
|
|
{
|
|
using com.hitrust.util;
|
|
using com.hitrust.util.Zip.Compression.Streams;
|
|
using System;
|
|
|
|
public class InflaterHuffmanTree
|
|
{
|
|
public static InflaterHuffmanTree defDistTree;
|
|
public static InflaterHuffmanTree defLitLenTree;
|
|
private static int MAX_BITLEN = 15;
|
|
private short[] tree;
|
|
|
|
static InflaterHuffmanTree()
|
|
{
|
|
try
|
|
{
|
|
byte[] codeLengths = new byte[0x120];
|
|
int num = 0;
|
|
while (num < 0x90)
|
|
{
|
|
codeLengths[num++] = 8;
|
|
}
|
|
while (num < 0x100)
|
|
{
|
|
codeLengths[num++] = 9;
|
|
}
|
|
while (num < 280)
|
|
{
|
|
codeLengths[num++] = 7;
|
|
}
|
|
while (num < 0x120)
|
|
{
|
|
codeLengths[num++] = 8;
|
|
}
|
|
defLitLenTree = new InflaterHuffmanTree(codeLengths);
|
|
codeLengths = new byte[0x20];
|
|
num = 0;
|
|
while (num < 0x20)
|
|
{
|
|
codeLengths[num++] = 5;
|
|
}
|
|
defDistTree = new InflaterHuffmanTree(codeLengths);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new SharpZipBaseException("InflaterHuffmanTree: static tree length illegal");
|
|
}
|
|
}
|
|
|
|
public InflaterHuffmanTree(byte[] codeLengths)
|
|
{
|
|
this.BuildTree(codeLengths);
|
|
}
|
|
|
|
private void BuildTree(byte[] codeLengths)
|
|
{
|
|
int[] numArray = new int[MAX_BITLEN + 1];
|
|
int[] numArray2 = new int[MAX_BITLEN + 1];
|
|
for (int i = 0; i < codeLengths.Length; i++)
|
|
{
|
|
int index = codeLengths[i];
|
|
if (index > 0)
|
|
{
|
|
numArray[index]++;
|
|
}
|
|
}
|
|
int toReverse = 0;
|
|
int num4 = 0x200;
|
|
for (int j = 1; j <= MAX_BITLEN; j++)
|
|
{
|
|
numArray2[j] = toReverse;
|
|
toReverse += numArray[j] << (0x10 - j);
|
|
if (j >= 10)
|
|
{
|
|
int num6 = numArray2[j] & 0x1ff80;
|
|
int num7 = toReverse & 0x1ff80;
|
|
num4 += (num7 - num6) >> (0x10 - j);
|
|
}
|
|
}
|
|
this.tree = new short[num4];
|
|
int num8 = 0x200;
|
|
for (int k = MAX_BITLEN; k >= 10; k--)
|
|
{
|
|
int num10 = toReverse & 0x1ff80;
|
|
toReverse -= numArray[k] << (0x10 - k);
|
|
int num11 = toReverse & 0x1ff80;
|
|
for (int n = num11; n < num10; n += 0x80)
|
|
{
|
|
this.tree[DeflaterHuffman.BitReverse(n)] = (short) ((-num8 << 4) | k);
|
|
num8 += ((int) 1) << (k - 9);
|
|
}
|
|
}
|
|
for (int m = 0; m < codeLengths.Length; m++)
|
|
{
|
|
int num14 = codeLengths[m];
|
|
if (num14 != 0)
|
|
{
|
|
toReverse = numArray2[num14];
|
|
int num15 = DeflaterHuffman.BitReverse(toReverse);
|
|
if (num14 <= 9)
|
|
{
|
|
do
|
|
{
|
|
this.tree[num15] = (short) ((m << 4) | num14);
|
|
num15 += ((int) 1) << num14;
|
|
}
|
|
while (num15 < 0x200);
|
|
}
|
|
else
|
|
{
|
|
int num16 = this.tree[num15 & 0x1ff];
|
|
int num17 = ((int) 1) << (num16 & 15);
|
|
num16 = -(num16 >> 4);
|
|
do
|
|
{
|
|
this.tree[num16 | (num15 >> 9)] = (short) ((m << 4) | num14);
|
|
num15 += ((int) 1) << num14;
|
|
}
|
|
while (num15 < num17);
|
|
}
|
|
numArray2[num14] = toReverse + (((int) 1) << (0x10 - num14));
|
|
}
|
|
}
|
|
}
|
|
|
|
public int GetSymbol(StreamManipulator input)
|
|
{
|
|
int num2;
|
|
int index = input.PeekBits(9);
|
|
if (index >= 0)
|
|
{
|
|
num2 = this.tree[index];
|
|
if (num2 >= 0)
|
|
{
|
|
input.DropBits(num2 & 15);
|
|
return (num2 >> 4);
|
|
}
|
|
int num3 = -(num2 >> 4);
|
|
int n = num2 & 15;
|
|
index = input.PeekBits(n);
|
|
if (index >= 0)
|
|
{
|
|
num2 = this.tree[num3 | (index >> 9)];
|
|
input.DropBits(num2 & 15);
|
|
return (num2 >> 4);
|
|
}
|
|
int num5 = input.AvailableBits;
|
|
index = input.PeekBits(num5);
|
|
num2 = this.tree[num3 | (index >> 9)];
|
|
if ((num2 & 15) <= num5)
|
|
{
|
|
input.DropBits(num2 & 15);
|
|
return (num2 >> 4);
|
|
}
|
|
return -1;
|
|
}
|
|
int availableBits = input.AvailableBits;
|
|
index = input.PeekBits(availableBits);
|
|
num2 = this.tree[index];
|
|
if ((num2 >= 0) && ((num2 & 15) <= availableBits))
|
|
{
|
|
input.DropBits(num2 & 15);
|
|
return (num2 >> 4);
|
|
}
|
|
return -1;
|
|
}
|
|
}
|
|
}
|
|
|