summaryrefslogtreecommitdiff
path: root/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/junrar/unpack/Unpack15.java
diff options
context:
space:
mode:
Diffstat (limited to 'org.fox.ttcomics/src/main/java/org/fox/ttcomics2/junrar/unpack/Unpack15.java')
-rwxr-xr-xorg.fox.ttcomics/src/main/java/org/fox/ttcomics2/junrar/unpack/Unpack15.java554
1 files changed, 554 insertions, 0 deletions
diff --git a/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/junrar/unpack/Unpack15.java b/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/junrar/unpack/Unpack15.java
new file mode 100755
index 0000000..2a7695d
--- /dev/null
+++ b/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/junrar/unpack/Unpack15.java
@@ -0,0 +1,554 @@
+/*
+ * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
+ * Original author: Edmund Wagner
+ * Creation date: 21.06.2007
+ *
+ * Source: $HeadURL$
+ * Last changed: $LastChangedDate$
+ *
+ * the unrar licence applies to all junrar source and binary distributions
+ * you are not allowed to use this source to re-create the RAR compression algorithm
+ *
+ * Here some html entities which can be used for escaping javadoc tags:
+ * "&": "&" or "&"
+ * "<": "&#060;" or "&lt;"
+ * ">": "&#062;" or "&gt;"
+ * "@": "&#064;"
+ */
+package org.fox.ttcomics2.junrar.unpack;
+
+import org.fox.ttcomics2.junrar.exception.RarException;
+import org.fox.ttcomics2.junrar.unpack.decode.Compress;
+import org.fox.ttcomics2.junrar.unpack.vm.BitInput;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+
+public abstract class Unpack15 extends BitInput {
+
+ private static final int STARTL1 = 2;
+ private static final int STARTL2 = 3;
+ private static final int STARTHF0 = 4;
+ private static final int STARTHF1 = 5;
+ private static final int STARTHF2 = 5;
+ private static final int STARTHF3 = 6;
+ private static final int STARTHF4 = 8;
+ static int ShortLen1[] = {1, 3, 4, 4, 5, 6, 7, 8, 8, 4, 4, 5, 6, 6, 4, 0};
+ static int ShortXor1[] = {0, 0xa0, 0xd0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe,
+ 0xff, 0xc0, 0x80, 0x90, 0x98, 0x9c, 0xb0};
+ static int ShortLen2[] = {2, 3, 3, 3, 4, 4, 5, 6, 6, 4, 4, 5, 6, 6, 4, 0};
+ static int ShortXor2[] = {0, 0x40, 0x60, 0xa0, 0xd0, 0xe0, 0xf0, 0xf8,
+ 0xfc, 0xc0, 0x80, 0x90, 0x98, 0x9c, 0xb0};
+ private static int DecL1[] = {0x8000, 0xa000, 0xc000, 0xd000, 0xe000,
+ 0xea00, 0xee00, 0xf000, 0xf200, 0xf200, 0xffff};
+ private static int PosL1[] = {0, 0, 0, 2, 3, 5, 7, 11, 16, 20, 24, 32, 32};
+ private static int DecL2[] = {0xa000, 0xc000, 0xd000, 0xe000, 0xea00,
+ 0xee00, 0xf000, 0xf200, 0xf240, 0xffff};
+ private static int PosL2[] = {0, 0, 0, 0, 5, 7, 9, 13, 18, 22, 26, 34, 36};
+ private static int DecHf0[] = {0x8000, 0xc000, 0xe000, 0xf200, 0xf200,
+ 0xf200, 0xf200, 0xf200, 0xffff};
+ private static int PosHf0[] = {0, 0, 0, 0, 0, 8, 16, 24, 33, 33, 33, 33,
+ 33};
+ private static int DecHf1[] = {0x2000, 0xc000, 0xe000, 0xf000, 0xf200,
+ 0xf200, 0xf7e0, 0xffff};
+ private static int PosHf1[] = {0, 0, 0, 0, 0, 0, 4, 44, 60, 76, 80, 80,
+ 127};
+ private static int DecHf2[] = {0x1000, 0x2400, 0x8000, 0xc000, 0xfa00,
+ 0xffff, 0xffff, 0xffff};
+ private static int PosHf2[] = {0, 0, 0, 0, 0, 0, 2, 7, 53, 117, 233, 0, 0};
+ private static int DecHf3[] = {0x800, 0x2400, 0xee00, 0xfe80, 0xffff,
+ 0xffff, 0xffff};
+ private static int PosHf3[] = {0, 0, 0, 0, 0, 0, 0, 2, 16, 218, 251, 0, 0};
+ private static int DecHf4[] = {0xff00, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff};
+ private static int PosHf4[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0};
+ protected int readBorder;
+ protected boolean suspended;
+ protected boolean unpAllBuf;
+ protected ComprDataIO unpIO;
+ protected boolean unpSomeRead;
+ protected int readTop;
+ protected long destUnpSize;
+ protected byte[] window;
+ protected int[] oldDist = new int[4];
+ protected int unpPtr, wrPtr;
+ protected int oldDistPtr;
+ protected int[] ChSet = new int[256], ChSetA = new int[256],
+ ChSetB = new int[256], ChSetC = new int[256];
+ protected int[] Place = new int[256], PlaceA = new int[256],
+ PlaceB = new int[256], PlaceC = new int[256];
+ protected int[] NToPl = new int[256], NToPlB = new int[256],
+ NToPlC = new int[256];
+ protected int FlagBuf, AvrPlc, AvrPlcB, AvrLn1, AvrLn2, AvrLn3;
+ protected int Buf60, NumHuf, StMode, LCount, FlagsCnt;
+ protected int Nhfb, Nlzb, MaxDist3;
+ protected int lastDist, lastLength;
+
+ protected abstract void unpInitData(boolean solid);
+
+ protected void unpack15(boolean solid) throws IOException, RarException {
+ if (suspended) {
+ unpPtr = wrPtr;
+ } else {
+ unpInitData(solid);
+ oldUnpInitData(solid);
+ unpReadBuf();
+ if (!solid) {
+ initHuff();
+ unpPtr = 0;
+ } else {
+ unpPtr = wrPtr;
+ }
+ --destUnpSize;
+ }
+ if (destUnpSize >= 0) {
+ getFlagsBuf();
+ FlagsCnt = 8;
+ }
+
+ while (destUnpSize >= 0) {
+ unpPtr &= Compress.MAXWINMASK;
+
+ if (inAddr > readTop - 30 && !unpReadBuf()) {
+ break;
+ }
+ if (((wrPtr - unpPtr) & Compress.MAXWINMASK) < 270
+ && wrPtr != unpPtr) {
+ oldUnpWriteBuf();
+ if (suspended) {
+ return;
+ }
+ }
+ if (StMode != 0) {
+ huffDecode();
+ continue;
+ }
+
+ if (--FlagsCnt < 0) {
+ getFlagsBuf();
+ FlagsCnt = 7;
+ }
+
+ if ((FlagBuf & 0x80) != 0) {
+ FlagBuf <<= 1;
+ if (Nlzb > Nhfb) {
+ longLZ();
+ } else {
+ huffDecode();
+ }
+ } else {
+ FlagBuf <<= 1;
+ if (--FlagsCnt < 0) {
+ getFlagsBuf();
+ FlagsCnt = 7;
+ }
+ if ((FlagBuf & 0x80) != 0) {
+ FlagBuf <<= 1;
+ if (Nlzb > Nhfb) {
+ huffDecode();
+ } else {
+ longLZ();
+ }
+ } else {
+ FlagBuf <<= 1;
+ shortLZ();
+ }
+ }
+ }
+ oldUnpWriteBuf();
+ }
+
+
+ protected boolean unpReadBuf() throws IOException, RarException {
+ int dataSize = readTop - inAddr;
+ if (dataSize < 0) {
+ return (false);
+ }
+ if (inAddr > BitInput.MAX_SIZE / 2) {
+ if (dataSize > 0) {
+ //memmove(InBuf,InBuf+InAddr,DataSize);
+// for (int i = 0; i < dataSize; i++) {
+// inBuf[i] = inBuf[inAddr + i];
+// }
+ System.arraycopy(inBuf, inAddr, inBuf, 0, dataSize);
+ }
+ inAddr = 0;
+ readTop = dataSize;
+ } else {
+ dataSize = readTop;
+ }
+ //int readCode=UnpIO->UnpRead(InBuf+DataSize,(BitInput::MAX_SIZE-DataSize)&~0xf);
+ int readCode = unpIO.unpRead(inBuf, dataSize, (BitInput.MAX_SIZE - dataSize) & ~0xf);
+ if (readCode > 0) {
+ readTop += readCode;
+ }
+ readBorder = readTop - 30;
+ return (readCode != -1);
+ }
+
+ private int getShortLen1(int pos) {
+ return pos == 1 ? Buf60 + 3 : ShortLen1[pos];
+ }
+
+ private int getShortLen2(int pos) {
+ return pos == 3 ? Buf60 + 3 : ShortLen2[pos];
+ }
+
+ protected void shortLZ() {
+ int Length, SaveLength;
+ int LastDistance;
+ int Distance;
+ int DistancePlace;
+ NumHuf = 0;
+
+ int BitField = fgetbits();
+ if (LCount == 2) {
+ faddbits(1);
+ if (BitField >= 0x8000) {
+ oldCopyString(lastDist, lastLength);
+ return;
+ }
+ BitField <<= 1;
+ LCount = 0;
+ }
+ BitField >>>= 8;
+ if (AvrLn1 < 37) {
+ for (Length = 0; ; Length++) {
+ if (((BitField ^ ShortXor1[Length]) & (~(0xff >>> getShortLen1(Length)))) == 0) {
+ break;
+ }
+ }
+ faddbits(getShortLen1(Length));
+ } else {
+ for (Length = 0; ; Length++) {
+ if (((BitField ^ ShortXor2[Length]) & (~(0xff >> getShortLen2(Length)))) == 0) {
+ break;
+ }
+ }
+ faddbits(getShortLen2(Length));
+ }
+
+ if (Length >= 9) {
+ if (Length == 9) {
+ LCount++;
+ oldCopyString(lastDist, lastLength);
+ return;
+ }
+ if (Length == 14) {
+ LCount = 0;
+ Length = decodeNum(fgetbits(), STARTL2, DecL2, PosL2) + 5;
+ Distance = (fgetbits() >> 1) | 0x8000;
+ faddbits(15);
+ lastLength = Length;
+ lastDist = Distance;
+ oldCopyString(Distance, Length);
+ return;
+ }
+
+ LCount = 0;
+ SaveLength = Length;
+ Distance = oldDist[(oldDistPtr - (Length - 9)) & 3];
+ Length = decodeNum(fgetbits(), STARTL1, DecL1, PosL1) + 2;
+ if (Length == 0x101 && SaveLength == 10) {
+ Buf60 ^= 1;
+ return;
+ }
+ if (Distance > 256)
+ Length++;
+ if (Distance >= MaxDist3)
+ Length++;
+
+ oldDist[oldDistPtr++] = Distance;
+ oldDistPtr = oldDistPtr & 3;
+ lastLength = Length;
+ lastDist = Distance;
+ oldCopyString(Distance, Length);
+ return;
+ }
+
+ LCount = 0;
+ AvrLn1 += Length;
+ AvrLn1 -= AvrLn1 >> 4;
+
+ DistancePlace = decodeNum(fgetbits(), STARTHF2, DecHf2, PosHf2) & 0xff;
+ Distance = ChSetA[DistancePlace];
+ if (--DistancePlace != -1) {
+ PlaceA[Distance]--;
+ LastDistance = ChSetA[DistancePlace];
+ PlaceA[LastDistance]++;
+ ChSetA[DistancePlace + 1] = LastDistance;
+ ChSetA[DistancePlace] = Distance;
+ }
+ Length += 2;
+ oldDist[oldDistPtr++] = ++Distance;
+ oldDistPtr = oldDistPtr & 3;
+ lastLength = Length;
+ lastDist = Distance;
+ oldCopyString(Distance, Length);
+ }
+
+ protected void longLZ() {
+ int Length;
+ int Distance;
+ int DistancePlace, NewDistancePlace;
+ int OldAvr2, OldAvr3;
+
+ NumHuf = 0;
+ Nlzb += 16;
+ if (Nlzb > 0xff) {
+ Nlzb = 0x90;
+ Nhfb >>>= 1;
+ }
+ OldAvr2 = AvrLn2;
+
+ int BitField = fgetbits();
+ if (AvrLn2 >= 122) {
+ Length = decodeNum(BitField, STARTL2, DecL2, PosL2);
+ } else {
+ if (AvrLn2 >= 64) {
+ Length = decodeNum(BitField, STARTL1, DecL1, PosL1);
+ } else {
+ if (BitField < 0x100) {
+ Length = BitField;
+ faddbits(16);
+ } else {
+ for (Length = 0; ((BitField << Length) & 0x8000) == 0; Length++) {
+ }
+ faddbits(Length + 1);
+ }
+ }
+ }
+ AvrLn2 += Length;
+ AvrLn2 -= AvrLn2 >>> 5;
+
+ BitField = fgetbits();
+ if (AvrPlcB > 0x28ff) {
+ DistancePlace = decodeNum(BitField, STARTHF2, DecHf2, PosHf2);
+ } else {
+ if (AvrPlcB > 0x6ff) {
+ DistancePlace = decodeNum(BitField, STARTHF1, DecHf1, PosHf1);
+ } else {
+ DistancePlace = decodeNum(BitField, STARTHF0, DecHf0, PosHf0);
+ }
+ }
+ AvrPlcB += DistancePlace;
+ AvrPlcB -= AvrPlcB >> 8;
+ while (true) {
+ Distance = ChSetB[DistancePlace & 0xff];
+ NewDistancePlace = NToPlB[Distance++ & 0xff]++;
+ if ((Distance & 0xff) == 0) {
+ corrHuff(ChSetB, NToPlB);
+ } else {
+ break;
+ }
+ }
+
+ ChSetB[DistancePlace] = ChSetB[NewDistancePlace];
+ ChSetB[NewDistancePlace] = Distance;
+
+ Distance = ((Distance & 0xff00) | (fgetbits() >>> 8)) >>> 1;
+ faddbits(7);
+
+ OldAvr3 = AvrLn3;
+ if (Length != 1 && Length != 4) {
+ if (Length == 0 && Distance <= MaxDist3) {
+ AvrLn3++;
+ AvrLn3 -= AvrLn3 >> 8;
+ } else {
+ if (AvrLn3 > 0) {
+ AvrLn3--;
+ }
+ }
+ }
+ Length += 3;
+ if (Distance >= MaxDist3) {
+ Length++;
+ }
+ if (Distance <= 256) {
+ Length += 8;
+ }
+ if (OldAvr3 > 0xb0 || AvrPlc >= 0x2a00 && OldAvr2 < 0x40) {
+ MaxDist3 = 0x7f00;
+ } else {
+ MaxDist3 = 0x2001;
+ }
+ oldDist[oldDistPtr++] = Distance;
+ oldDistPtr = oldDistPtr & 3;
+ lastLength = Length;
+ lastDist = Distance;
+ oldCopyString(Distance, Length);
+ }
+
+ protected void huffDecode() {
+ int CurByte, NewBytePlace;
+ int Length;
+ int Distance;
+ int BytePlace;
+
+ int BitField = fgetbits();
+
+ if (AvrPlc > 0x75ff) {
+ BytePlace = decodeNum(BitField, STARTHF4, DecHf4, PosHf4);
+ } else {
+ if (AvrPlc > 0x5dff) {
+ BytePlace = decodeNum(BitField, STARTHF3, DecHf3, PosHf3);
+ } else {
+ if (AvrPlc > 0x35ff) {
+ BytePlace = decodeNum(BitField, STARTHF2, DecHf2, PosHf2);
+ } else {
+ if (AvrPlc > 0x0dff) {
+ BytePlace = decodeNum(BitField, STARTHF1, DecHf1,
+ PosHf1);
+ } else {
+ BytePlace = decodeNum(BitField, STARTHF0, DecHf0,
+ PosHf0);
+ }
+ }
+ }
+ }
+ BytePlace &= 0xff;
+ if (StMode != 0) {
+ if (BytePlace == 0 && BitField > 0xfff) {
+ BytePlace = 0x100;
+ }
+ if (--BytePlace == -1) {
+ BitField = fgetbits();
+ faddbits(1);
+ if ((BitField & 0x8000) != 0) {
+ NumHuf = StMode = 0;
+ return;
+ } else {
+ Length = (BitField & 0x4000) != 0 ? 4 : 3;
+ faddbits(1);
+ Distance = decodeNum(fgetbits(), STARTHF2, DecHf2, PosHf2);
+ Distance = (Distance << 5) | (fgetbits() >>> 11);
+ faddbits(5);
+ oldCopyString(Distance, Length);
+ return;
+ }
+ }
+ } else {
+ if (NumHuf++ >= 16 && FlagsCnt == 0) {
+ StMode = 1;
+ }
+ }
+ AvrPlc += BytePlace;
+ AvrPlc -= AvrPlc >>> 8;
+ Nhfb += 16;
+ if (Nhfb > 0xff) {
+ Nhfb = 0x90;
+ Nlzb >>>= 1;
+ }
+
+ window[unpPtr++] = (byte) (ChSet[BytePlace] >>> 8);
+ --destUnpSize;
+
+ while (true) {
+ CurByte = ChSet[BytePlace];
+ NewBytePlace = NToPl[CurByte++ & 0xff]++;
+ if ((CurByte & 0xff) > 0xa1) {
+ corrHuff(ChSet, NToPl);
+ } else {
+ break;
+ }
+ }
+
+ ChSet[BytePlace] = ChSet[NewBytePlace];
+ ChSet[NewBytePlace] = CurByte;
+ }
+
+ protected void getFlagsBuf() {
+ int Flags, NewFlagsPlace;
+ int FlagsPlace = decodeNum(fgetbits(), STARTHF2, DecHf2, PosHf2);
+
+ while (true) {
+ Flags = ChSetC[FlagsPlace];
+ FlagBuf = Flags >>> 8;
+ NewFlagsPlace = NToPlC[Flags++ & 0xff]++;
+ if ((Flags & 0xff) != 0) {
+ break;
+ }
+ corrHuff(ChSetC, NToPlC);
+ }
+
+ ChSetC[FlagsPlace] = ChSetC[NewFlagsPlace];
+ ChSetC[NewFlagsPlace] = Flags;
+ }
+
+ protected void oldUnpInitData(boolean Solid) {
+ if (!Solid) {
+ AvrPlcB = AvrLn1 = AvrLn2 = AvrLn3 = NumHuf = Buf60 = 0;
+ AvrPlc = 0x3500;
+ MaxDist3 = 0x2001;
+ Nhfb = Nlzb = 0x80;
+ }
+ FlagsCnt = 0;
+ FlagBuf = 0;
+ StMode = 0;
+ LCount = 0;
+ readTop = 0;
+ }
+
+ protected void initHuff() {
+ for (int I = 0; I < 256; I++) {
+ Place[I] = PlaceA[I] = PlaceB[I] = I;
+ PlaceC[I] = (~I + 1) & 0xff;
+ ChSet[I] = ChSetB[I] = I << 8;
+ ChSetA[I] = I;
+ ChSetC[I] = ((~I + 1) & 0xff) << 8;
+ }
+
+ Arrays.fill(NToPl, 0);// memset(NToPl,0,sizeof(NToPl));
+ Arrays.fill(NToPlB, 0); // memset(NToPlB,0,sizeof(NToPlB));
+ Arrays.fill(NToPlC, 0); // memset(NToPlC,0,sizeof(NToPlC));
+ corrHuff(ChSetB, NToPlB);
+ }
+
+ protected void corrHuff(int[] CharSet, int[] NumToPlace) {
+ int I, J, pos = 0;
+ for (I = 7; I >= 0; I--) {
+ for (J = 0; J < 32; J++, pos++) {
+ CharSet[pos] = ((CharSet[pos] & ~0xff) | I);// *CharSet=(*CharSet
+ // & ~0xff) | I;
+ }
+ }
+ Arrays.fill(NumToPlace, 0);// memset(NumToPlace,0,sizeof(NToPl));
+ for (I = 6; I >= 0; I--) {
+ NumToPlace[I] = (7 - I) * 32;
+ }
+ }
+
+ protected void oldCopyString(int Distance, int Length) {
+ destUnpSize -= Length;
+ while ((Length--) != 0) {
+ window[unpPtr] = window[(unpPtr - Distance) & Compress.MAXWINMASK];
+ unpPtr = (unpPtr + 1) & Compress.MAXWINMASK;
+ }
+ }
+
+ protected int decodeNum(int Num, int StartPos, int[] DecTab, int[] PosTab) {
+ int I;
+ for (Num &= 0xfff0, I = 0; DecTab[I] <= Num; I++) {
+ StartPos++;
+ }
+ faddbits(StartPos);
+ return (((Num - (I != 0 ? DecTab[I - 1] : 0)) >>> (16 - StartPos)) + PosTab[StartPos]);
+ }
+
+ protected void oldUnpWriteBuf() throws IOException {
+ if (unpPtr != wrPtr) {
+ unpSomeRead = true;
+ }
+ if (unpPtr < wrPtr) {
+ unpIO.unpWrite(window, wrPtr, -wrPtr & Compress.MAXWINMASK);
+ unpIO.unpWrite(window, 0, unpPtr);
+ unpAllBuf = true;
+ } else {
+ unpIO.unpWrite(window, wrPtr, unpPtr - wrPtr);
+ }
+ wrPtr = unpPtr;
+ }
+
+
+}