package com.google.typography.font.tools.conversion.eot;
public class LzcompCompress
{
private static final int MAX_2BYTE_DIST = 512;
private static final int DIST_MIN = 1;
private static final int DIST_WIDTH = 3;
private static final int LEN_MIN = 2;
private static final int LEN_MIN3 = 3;
private static final int LEN_WIDTH = 3;
private static final int BIT_RANGE = 2;
private static final int PRELOAD_SIZE = 7168;
private static final int DEFAULT_MAX_COPY_DIST = Integer.MAX_VALUE;
private BitIOWriter bits = new BitIOWriter();
private boolean usingRunLength = false;
private int length1;
private int maxCopyDist = Integer.MAX_VALUE;
private HuffmanEncoder distEncoder;
private HuffmanEncoder lenEncoder;
private HuffmanEncoder symEncoder;
private int numDistRanges;
private int distMax;
private int dup2;
private int dup4;
private int dup6;
private int numSyms;
private byte[] buf;
private HashNode[] hashTable;
private void write(byte[] paramArrayOfByte)
{
this.bits.writeBit(this.usingRunLength);
this.length1 = paramArrayOfByte.length;
setDistRange(this.length1);
this.distEncoder = new HuffmanEncoder(this.bits, 8);
this.lenEncoder = new HuffmanEncoder(this.bits, 8);
this.symEncoder = new HuffmanEncoder(this.bits, this.numSyms);
this.buf = new byte[7168 + this.length1];
System.arraycopy(paramArrayOfByte, 0, this.buf, 7168, this.length1);
encode();
this.bits.flush();
}
void setDistRange(int paramInt)
{
this.numDistRanges = 1;
for (this.distMax = (1 + (1 << 3 * this.numDistRanges) - 1); this.distMax < this.length1; this.distMax = (1 + (1 << 3 * this.numDistRanges) - 1)) {
this.numDistRanges += 1;
}
this.dup2 = (256 + 8 * this.numDistRanges);
this.dup4 = (this.dup2 + 1);
this.dup6 = (this.dup4 + 1);
this.numSyms = (this.dup6 + 1);
}
private void encode()
{
int i = this.length1 + 7168;
initializeModel();
this.bits.writeValue(this.length1, 24);
int j = this.length1 + 7168;
int[] arrayOfInt = new int[1];
int k = 7168;
while (k < j)
{
int m = k;
int n = makeCopyDecision(k++, arrayOfInt);
int i1;
if (n > 0)
{
i1 = getNumDistRanges(arrayOfInt[0]);
encodeLength(n, arrayOfInt[0], i1);
encodeDistance2(arrayOfInt[0], i1);
for (int i2 = 1; i2 < n; i2++) {
updateModel(k++);
}
}
else
{
i1 = this.buf[m];
if ((m >= 2) && (i1 == this.buf[(m - 2)])) {
this.symEncoder.writeSymbol(this.dup2);
} else if ((m >= 4) && (i1 == this.buf[(m - 4)])) {
this.symEncoder.writeSymbol(this.dup4);
} else if ((m >= 6) && (i1 == this.buf[(m - 6)])) {
this.symEncoder.writeSymbol(this.dup6);
} else {
this.symEncoder.writeSymbol(this.buf[m] & 0xFF);
}
}
}
}
void initializeModel()
{
this.hashTable = new HashNode[65536];
int i = 0;
for (int j = 0; j < 32; j++) {
for (int k = 0; k < 96; k++)
{
this.buf[i] = ((byte)j);
updateModel(i++);
this.buf[i] = ((byte)k);
updateModel(i++);
}
}
for (j = 0; (i < 7168) && (j < 256); j++)
{
this.buf[i] = ((byte)j);
updateModel(i++);
this.buf[i] = ((byte)j);
updateModel(i++);
this.buf[i] = ((byte)j);
updateModel(i++);
this.buf[i] = ((byte)j);
updateModel(i++);
}
}
private int makeCopyDecision(int paramInt, int[] paramArrayOfInt)
{
int[] arrayOfInt1 = new int[1];
int[] arrayOfInt2 = new int[1];
int[] arrayOfInt3 = new int[1];
int i = paramInt;
int j = findMatch(paramInt, arrayOfInt1, arrayOfInt2, arrayOfInt3);
updateModel(paramInt++);
if (arrayOfInt2[0] > 0)
{
int[] arrayOfInt4 = new int[1];
int[] arrayOfInt5 = new int[1];
int[] arrayOfInt6 = new int[1];
int k = findMatch(paramInt, arrayOfInt4, arrayOfInt5, arrayOfInt6);
int m = this.symEncoder.writeSymbolCost(this.buf[i] & 0xFF);
if ((arrayOfInt5[0] >= arrayOfInt2[0]) && (arrayOfInt3[0] > (arrayOfInt6[0] * k + m) / (k + 1)))
{
j = 0;
}
else if (j > 3)
{
k = findMatch(i + j, arrayOfInt4, arrayOfInt5, arrayOfInt6);
if (k >= 2)
{
int[] arrayOfInt7 = new int[1];
int[] arrayOfInt8 = new int[1];
int[] arrayOfInt9 = new int[1];
int i1 = findMatch(i + j - 1, arrayOfInt7, arrayOfInt8, arrayOfInt9);
if ((i1 > k) && (arrayOfInt9[0] < arrayOfInt6[0]))
{
int i2 = getNumDistRanges(arrayOfInt1[0] + 1);
int i3 = encodeLengthCost(j - 1, arrayOfInt1[0] + 1, i2);
int i4 = encodeDistance2Cost(arrayOfInt1[0] + 1, i2);
int i5 = i3 + i4 + arrayOfInt9[0] * i1;
int i6 = arrayOfInt3[0] * j + arrayOfInt6[0] * k;
if (i6 / (j + k) > i5 / (j - 1 + i1))
{
j--;
arrayOfInt1[0] += 1;
}
}
}
}
if (j == 2)
{
int n;
if ((i >= 2) && (this.buf[i] == this.buf[(i - 2)]))
{
n = this.symEncoder.writeSymbolCost(this.dup2);
if (arrayOfInt3[0] * 2 > n + this.symEncoder.writeSymbolCost(this.buf[(i + 1)] & 0xFF)) {
j = 0;
}
}
else if ((i >= 1) && (i + 1 < this.buf.length) && (this.buf[(i + 1)] == this.buf[(i - 1)]))
{
n = this.symEncoder.writeSymbolCost(this.dup2);
if (arrayOfInt3[0] * 2 > m + n) {
j = 0;
}
}
}
}
paramArrayOfInt[0] = arrayOfInt1[0];
return j;
}
int findMatch(int paramInt, int[] paramArrayOfInt1, int[] paramArrayOfInt2, int[] paramArrayOfInt3)
{
int[] arrayOfInt = new int[33];
int i = this.buf.length - paramInt;
int j = 0;
int k = 0;
int m = 0;
int n = 0;
int i1 = 0;
if (i > 1)
{
int i2 = (this.buf[paramInt] & 0xFF) << 8 | this.buf[(paramInt + 1)] & 0xFF;
Object localObject = null;
int i3 = 0;
for (HashNode localHashNode = this.hashTable[i2]; localHashNode != null; localHashNode = localHashNode.next)
{
int i4 = localHashNode.index;
int i5 = paramInt - i4;
i3++;
if ((i3 > 256) || (i5 > this.maxCopyDist))
{
if (this.hashTable[i2] == localHashNode)
{
this.hashTable[i2] = null;
break;
}
((HashNode)localObject).next = null;
break;
}
int i6 = paramInt - i4;
if (i < i6) {
i6 = i;
}
if (i6 >= 2)
{
i4 += 2;
int i7 = 2;
for (i7 = 2; (i7 < i6) && (this.buf[i4] == this.buf[(paramInt + i7)]); i7++) {
i4++;
}
if (i7 >= 2)
{
i5 = i5 - i7 + 1;
if ((i5 <= this.distMax) && ((i7 != 2) || (i5 < 512)) && ((i7 > j) || (i5 <= k) || ((i7 > j - 2) && ((i5 <= k << 3) || ((i7 >= j) && (i5 <= k << 4))))))
{
int i8 = 0;
int i9;
int i10;
if (i7 > i1)
{
i9 = i7;
if (i9 > 32) {
i9 = 32;
}
for (i4 = i1; i4 < i9; i4++)
{
i10 = this.buf[(paramInt + i4)];
arrayOfInt[(i4 + 1)] = (arrayOfInt[i4] + this.symEncoder.writeSymbolCost(i10 & 0xFF));
}
i1 = i9;
if (i7 > 32)
{
i8 = arrayOfInt[32];
i8 += i8 / 32 * (i7 - 32);
}
else
{
i8 = arrayOfInt[i7];
}
}
else
{
i8 = arrayOfInt[i7];
}
if (i8 > m)
{
i9 = getNumDistRanges(i5);
i10 = encodeLengthCost(i7, i5, i9);
if (i8 - i10 - (i9 << 16) > m)
{
i10 += encodeDistance2Cost(i5, i9);
int i11 = i8 - i10;
if (i11 > m)
{
m = i11;
j = i7;
k = i5;
n = i10;
}
}
}
}
}
}
localObject = localHashNode;
}
}
paramArrayOfInt3[0] = (j > 0 ? n / j : 0);
paramArrayOfInt1[0] = k;
paramArrayOfInt2[0] = m;
return j;
}
private int getNumDistRanges(int paramInt)
{
int i = HuffmanEncoder.bitsUsed(paramInt - 1);
int j = (i + 3 - 1) / 3;
return j;
}
private void encodeLength(int paramInt1, int paramInt2, int paramInt3)
{
if (paramInt2 >= 512) {
paramInt1 -= 3;
} else {
paramInt1 -= 2;
}
int i = HuffmanEncoder.bitsUsed(paramInt1);
for (int j = 2; j < i; j += 2) {}
int k = 1 << j - 1;
int m = i > 2 ? 2 : 0;
if ((paramInt1 & k) != 0) {
m |= 0x1;
}
k >>= 1;
m <<= 1;
if ((paramInt1 & k) != 0) {
m |= 0x1;
}
k >>= 1;
this.symEncoder.writeSymbol(256 + m + (paramInt3 - 1) * 8);
for (j = i - 2; j >= 1; j -= 2)
{
m = j > 2 ? 2 : 0;
if ((paramInt1 & k) != 0) {
m |= 0x1;
}
k >>= 1;
m <<= 1;
if ((paramInt1 & k) != 0) {
m |= 0x1;
}
k >>= 1;
this.lenEncoder.writeSymbol(m);
}
}
private int encodeLengthCost(int paramInt1, int paramInt2, int paramInt3)
{
if (paramInt2 >= 512) {
paramInt1 -= 3;
} else {
paramInt1 -= 2;
}
int i = HuffmanEncoder.bitsUsed(paramInt1);
for (int j = 2; j < i; j += 2) {}
int k = 1 << j - 1;
int m = i > 2 ? 2 : 0;
if ((paramInt1 & k) != 0) {
m |= 0x1;
}
k >>= 1;
m <<= 1;
if ((paramInt1 & k) != 0) {
m |= 0x1;
}
k >>= 1;
int n = this.symEncoder.writeSymbolCost(256 + m + (paramInt3 - 1) * 8);
for (j = i - 2; j >= 1; j -= 2)
{
m = j > 2 ? 2 : 0;
if ((paramInt1 & k) != 0) {
m |= 0x1;
}
k >>= 1;
m <<= 1;
if ((paramInt1 & k) != 0) {
m |= 0x1;
}
k >>= 1;
n += this.lenEncoder.writeSymbolCost(m);
}
return n;
}
private void encodeDistance2(int paramInt1, int paramInt2)
{
for (int i = (paramInt2 - 1) * 3; i >= 0; i -= 3) {
this.distEncoder.writeSymbol(paramInt1 >> i & 0x7);
}
}
private int encodeDistance2Cost(int paramInt1, int paramInt2)
{
int i = 0;
paramInt1--;
for (int j = (paramInt2 - 1) * 3; j >= 0; j -= 3) {
i += this.distEncoder.writeSymbolCost(paramInt1 >> j & 0x7);
}
return i;
}
private void updateModel(int paramInt)
{
int i = this.buf[paramInt];
if (paramInt > 0)
{
HashNode localHashNode = new HashNode(null);
int j = this.buf[(paramInt - 1)];
int k = (j & 0xFF) << 8 | i & 0xFF;
localHashNode.index = (paramInt - 1);
localHashNode.next = this.hashTable[k];
this.hashTable[k] = localHashNode;
}
}
private byte[] toByteArray()
{
return this.bits.toByteArray();
}
public static byte[] compress(byte[] paramArrayOfByte)
{
LzcompCompress localLzcompCompress = new LzcompCompress();
localLzcompCompress.write(paramArrayOfByte);
return localLzcompCompress.toByteArray();
}
public static int getPreloadSize()
{
return 7168;
}
private static class HashNode
{
int index;
HashNode next;
}
}
/* Location: C:\Users\Ethan\Desktop\FontZip\FontTool\sfnttool.jar!\com\google\typography\font\tools\conversion\eot\LzcompCompress.class
* Java compiler version: 6 (50.0)
* JD-Core Version: 0.7.1
*/