📄 unpack20.java
字号:
/*
* 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 "&"
* "<": "<" or "<"
* ">": ">" or ">"
* "@": "@"
*/
package de.innosystec.unrar.unpack;
import java.io.IOException;
import java.util.Arrays;
import de.innosystec.unrar.exception.RarException;
import de.innosystec.unrar.unpack.decode.AudioVariables;
import de.innosystec.unrar.unpack.decode.BitDecode;
import de.innosystec.unrar.unpack.decode.Compress;
import de.innosystec.unrar.unpack.decode.Decode;
import de.innosystec.unrar.unpack.decode.DistDecode;
import de.innosystec.unrar.unpack.decode.LitDecode;
import de.innosystec.unrar.unpack.decode.LowDistDecode;
import de.innosystec.unrar.unpack.decode.RepDecode;
import de.innosystec.unrar.unpack.decode.MultDecode;
/**
* DOCUMENT ME
*
* @author $LastChangedBy$
* @version $LastChangedRevision$
*/
public abstract class Unpack20 extends Unpack15
{
protected MultDecode[] MD = new MultDecode[4];
protected byte[] UnpOldTable20 = new byte[Compress.MC20 * 4];
protected int UnpAudioBlock, UnpChannels, UnpCurChannel, UnpChannelDelta;
protected AudioVariables[] AudV = new AudioVariables[4];
protected LitDecode LD = new LitDecode();
protected DistDecode DD = new DistDecode();
protected LowDistDecode LDD = new LowDistDecode();
protected RepDecode RD = new RepDecode();
protected BitDecode BD = new BitDecode();
public static final int[] LDecode = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12,
14, 16, 20, 24, 28, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192,
224 };
public static final byte[] LBits = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2,
2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5 };
public static final int[] DDecode = { 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32,
48, 64, 96, 128, 192, 256, 384, 512, 768, 1024, 1536, 2048, 3072,
4096, 6144, 8192, 12288, 16384, 24576, 32768, 49152, 65536, 98304,
131072, 196608, 262144, 327680, 393216, 458752, 524288, 589824,
655360, 720896, 786432, 851968, 917504, 983040 };
public static final int[] DBits = { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5,
5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14,
15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 };
public static final int[] SDDecode = { 0, 4, 8, 16, 32, 64, 128, 192 };
public static final int[] SDBits = { 2, 2, 3, 4, 5, 6, 6, 6 };
protected void unpack20(boolean solid) throws IOException, RarException
{
int Bits;
if (suspended) {
unpPtr = wrPtr;
} else {
unpInitData(solid);
if (!unpReadBuf()) {
return;
}
if (!solid) {
if (!ReadTables20()) {
return;
}
}
--destUnpSize;
}
while (destUnpSize >= 0) {
unpPtr &= Compress.MAXWINMASK;
if (inAddr > readTop - 30)
if (!unpReadBuf())
break;
if (((wrPtr - unpPtr) & Compress.MAXWINMASK) < 270
&& wrPtr != unpPtr) {
oldUnpWriteBuf();
if (suspended)
return;
}
if (UnpAudioBlock != 0) {
int AudioNumber = decodeNumber(MD[UnpCurChannel]);
if (AudioNumber == 256) {
if (!ReadTables20())
break;
continue;
}
window[unpPtr++] = DecodeAudio(AudioNumber);
if (++UnpCurChannel == UnpChannels)
UnpCurChannel = 0;
--destUnpSize;
continue;
}
int Number = decodeNumber(LD);
if (Number < 256) {
window[unpPtr++] = (byte) Number;
--destUnpSize;
continue;
}
if (Number > 269) {
int Length = LDecode[Number -= 270] + 3;
if ((Bits = LBits[Number]) > 0) {
Length += getbits() >>> (16 - Bits);
addbits(Bits);
}
int DistNumber = decodeNumber(DD);
int Distance = DDecode[DistNumber] + 1;
if ((Bits = DBits[DistNumber]) > 0) {
Distance += getbits() >>> (16 - Bits);
addbits(Bits);
}
if (Distance >= 0x2000) {
Length++;
if (Distance >= 0x40000L)
Length++;
}
CopyString20(Length, Distance);
continue;
}
if (Number == 269) {
if (!ReadTables20())
break;
continue;
}
if (Number == 256) {
CopyString20(lastLength, lastDist);
continue;
}
if (Number < 261) {
int Distance = oldDist[(oldDistPtr - (Number - 256)) & 3];
int LengthNumber = decodeNumber(RD);
int Length = LDecode[LengthNumber] + 2;
if ((Bits = LBits[LengthNumber]) > 0) {
Length += getbits() >>> (16 - Bits);
addbits(Bits);
}
if (Distance >= 0x101) {
Length++;
if (Distance >= 0x2000) {
Length++;
if (Distance >= 0x40000)
Length++;
}
}
CopyString20(Length, Distance);
continue;
}
if (Number < 270) {
int Distance = SDDecode[Number -= 261] + 1;
if ((Bits = SDBits[Number]) > 0) {
Distance += getbits() >>> (16 - Bits);
addbits(Bits);
}
CopyString20(2, Distance);
continue;
}
}
ReadLastTables();
oldUnpWriteBuf();
}
protected void CopyString20(int Length, int Distance)
{
lastDist = oldDist[oldDistPtr++ & 3] = Distance;
lastLength = Length;
destUnpSize -= Length;
int DestPtr = unpPtr - Distance;
if (DestPtr < Compress.MAXWINSIZE - 300
&& unpPtr < Compress.MAXWINSIZE - 300) {
window[unpPtr++] = window[DestPtr++];
window[unpPtr++] = window[DestPtr++];
while (Length > 2) {
Length--;
window[unpPtr++] = window[DestPtr++];
}
} else {
while ((Length--) != 0) {
window[unpPtr] = window[DestPtr++ & Compress.MAXWINMASK];
unpPtr = (unpPtr + 1) & Compress.MAXWINMASK;
}
}
}
protected void makeDecodeTables(byte[] lenTab, int offset, Decode dec,
int size)
{
int[] lenCount = new int[16];
int[] tmpPos = new int[16];
int i;
long M, N;
Arrays.fill(lenCount, 0);// memset(LenCount,0,sizeof(LenCount));
Arrays.fill(dec.getDecodeNum(), 0);// memset(Dec->DecodeNum,0,Size*sizeof(*Dec->DecodeNum));
for (i = 0; i < size; i++) {
lenCount[(int) (lenTab[offset + i] & 0xF)]++;
}
lenCount[0] = 0;
for (tmpPos[0] = 0, dec.getDecodePos()[0] = 0, dec.getDecodeLen()[0] = 0, N = 0, i = 1; i < 16; i++) {
N = 2 * (N + lenCount[i]);
M = N << (15 - i);
if (M > 0xFFFF) {
M = 0xFFFF;
}
dec.getDecodeLen()[i] = (int) M;
tmpPos[i] = dec.getDecodePos()[i] = dec.getDecodePos()[i - 1]
+ lenCount[i - 1];
}
for (i = 0; i < size; i++) {
if (lenTab[offset + i] != 0) {
dec.getDecodeNum()[tmpPos[lenTab[offset + i] & 0xF]++] = i;
}
}
dec.setMaxNum(size);
}
protected int decodeNumber(Decode dec)
{
int bits;
long bitField = getbits() & 0xfffe;
// if (bitField < dec.getDecodeLen()[8]) {
// if (bitField < dec.getDecodeLen()[4]) {
// if (bitField < dec.getDecodeLen()[2]) {
// if (bitField < dec.getDecodeLen()[1]) {
// bits = 1;
// } else {
// bits = 2;
// }
// } else {
// if (bitField < dec.getDecodeLen()[3]) {
// bits = 3;
// } else {
// bits = 4;
// }
// }
// } else {
// if (bitField < dec.getDecodeLen()[6]) {
// if (bitField < dec.getDecodeLen()[5])
// bits = 5;
// else
// bits = 6;
// } else {
// if (bitField < dec.getDecodeLen()[7]) {
// bits = 7;
// } else {
// bits = 8;
// }
// }
// }
// } else {
// if (bitField < dec.getDecodeLen()[12]) {
// if (bitField < dec.getDecodeLen()[10])
// if (bitField < dec.getDecodeLen()[9])
// bits = 9;
// else
// bits = 10;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -