⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unpack20.java

📁 这是架包java-unrar-0.2.jar的源码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * 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 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 + -