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

📄 ppmcontext.java

📁 java下操作rar文件,创建,压缩/解压缩等等.
💻 JAVA
字号:
/*
 * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
 * Original author: Edmund Wagner
 * Creation date: 31.05.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.ppm;

import de.innosystec.unrar.io.Raw;

/**
 * DOCUMENT ME
 * 
 * @author $LastChangedBy$
 * @version $LastChangedRevision$
 */
public class PPMContext extends Pointer
{

	public static final int size = 12;

	private short numStats; // determines if feqData or onstate is used

	// (1==onestate)

	private FreqData freqData; // -\

	// |-> union
	private State oneState; // -/

	private int Suffix; // pointer ppmcontext

	public static byte[] ExpEscape = { 25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2,
			2, 2, 2 };

	public PPMContext(byte[] mem)
	{
		super(mem);
		oneState = new State(mem);
		freqData = new FreqData(mem);
	}

	public FreqData getFreqData()
	{
		freqData.setAddress(pos+2);
		return freqData;
	}

	public void setFreqData(FreqData freqData)
	{
		this.freqData.setAddress(pos+2);
		this.freqData.setSummFreq(freqData.getSummFreq());
		this.freqData.setStats(freqData.getStats());
		this.freqData.setAddress(pos+2);
		oneState.setAddress(pos + 2);
	}

	public short getNumStats()
	{
		if(mem!=null){
			numStats = Raw.readShortLittleEndian(mem,  pos);
		}
		return numStats;
	}

	public void setNumStats(short numStats)
	{
		this.numStats = numStats;
		if (mem != null) {
			Raw.writeShortLittleEndian(mem, pos, numStats);
		}
	}

	public State getOneState()
	{
		return oneState;
	}

	public void setOneState(State oneState)
	{
		this.oneState.setAddress(pos+2);
		this.oneState.setFreq(oneState.getFreq());
		this.oneState.setSuccessor(oneState.getSuccessor());
		this.oneState.setSymbol(oneState.getSymbol());
		this.oneState.setAddress(pos+2);
		this.freqData.setAddress(pos + 2);
	}

	public int getSuffix()
	{
		if(mem!=null){
			Suffix = Raw.readIntLittleEndian(mem,  pos+8);
		}
		return Suffix;
	}

	public void setSuffix(PPMContext suffix)
	{
		setSuffix(suffix.getAddress());
	}

	public void setSuffix(int suffix)
	{
		Suffix = suffix;
		if (mem != null) {
			Raw.writeIntLittleEndian(mem, pos + 8, suffix);
		}
	}

	@Override
	public boolean setAddress(int pos)
	{
		if (mem == null) {
			return false;
		}
		if (pos < 0 || pos >= mem.length) {
			return false;
		}
		if (pos + size >= mem.length) {
			return false;
		}
		this.pos = pos;
		numStats = Raw.readShortLittleEndian(mem, pos);
		pos += 2;
		if (numStats == 1) {

			oneState.setAddress(pos);
			freqData.setAddress(pos);
			pos += State.size;
		} else {

			freqData.setAddress(pos);
			oneState.setAddress(pos);
			pos += FreqData.size;
		}

		Suffix = Raw.readIntLittleEndian(mem, pos);
		return true;
	}

	public int createChild(ModelPPM model, State pStats/* ptr */,
			State firstState /* ref */)
	{
		PPMContext pc = new PPMContext(model.getSubAlloc().getHeap());
		pc.setAddress(model.getSubAlloc().allocContext()); 
		if (pc != null) { 
			pc.setNumStats((short) 1);
			pc.setOneState(firstState);
			pc.setSuffix(this);
			pStats.setSuccessor(pc);
		}
		return pc.getAddress();
	}

	public void rescale(ModelPPM Model)
	{
		int OldNS = numStats, i = numStats - 1, Adder, EscFreq;
		// STATE* p1, * p;
		State p1 = new State(Model.getHeap());
		State p = new State(Model.getHeap());
		State temp = new State(Model.getHeap());

		for (p.setAddress(Model.getFoundState().getAddress()); p.getAddress() != freqData
				.getStats(); p.setAddress(p.getAddress() - State.size)) {
			temp.setAddress(p.getAddress() - State.size);
			ppmdSwap(Model, p, temp);
		}
		temp.setAddress(freqData.getStats());
		temp.setFreq((byte) (temp.getFreq() + 4));
		freqData.setSummFreq((short) (freqData.getSummFreq() + 4));
		EscFreq = freqData.getSummFreq() - p.getFreq();
		Adder = Model.getOrderFall() != 0 ? 1 : 0;
		p.setFreq((byte) ((p.getFreq() + Adder) >>> 1));
		freqData.setSummFreq(p.getFreq());
		do {
			temp.setAddress(p.getAddress() + State.size);
			EscFreq -= temp.getFreq();
			p.setFreq((byte) ((p.getFreq() + Adder) >>> 1));
			freqData
					.setSummFreq((short) (freqData.getSummFreq() + p.getFreq()));
			temp.setAddress(p.getAddress() - State.size);
			if (p.getFreq() > temp.getFreq()) {
				temp.setAddress(p.getAddress());
				p1.setAddress(p.getAddress());
				State temp2 = new State(Model.getHeap());
				State temp3 = new State(Model.getHeap());
				do {
					// p1[0]=p1[-1];
					temp2.setAddress(p1.getAddress() - State.size);
					p1.setValues(temp2);
					temp3.setAddress(p1.getAddress());
				} while (p1.decAddress().getAddress() != freqData.getStats()&& temp.getFreq() > temp3.getFreq());
				p1.setValues(temp2);

			}
		} while (--i != 0);
		if (p.getFreq() == 0) {
			do {
				i++;
				p.decAddress();
			} while (p.getFreq() == 0);
			EscFreq += i;
			if ((numStats -= i) == 1) {
				State temp2 = new State(null);
				temp.setAddress(freqData.getStats());
				temp2.setValues(temp);
				// STATE tmp=*U.Stats;
				do {
					temp.setFreq((byte) (temp.getFreq() - temp.getFreq() >>> 1));
					EscFreq >>>= 1;
				} while (EscFreq > 1);
				Model.getSubAlloc().freeUnits(freqData.getStats(),(OldNS + 1) >>> 1);
				oneState.setValues(temp);
				Model.getFoundState().setAddress(oneState.getAddress());
				return;
			}
		}
		EscFreq -= EscFreq >>> 1;
		freqData.setSummFreq((short) (freqData.getSummFreq() + EscFreq));
		int n0 = (OldNS + 1) >>> 1, n1 = (numStats + 1) >>> 1;
		if (n0 != n1) {
			freqData.setStats(Model.getSubAlloc().shrinkUnits(freqData.getStats(), n0, n1));
		}
		Model.getFoundState().setAddress(freqData.getStats());
	}

	private int getArrayIndex(ModelPPM Model, State rs)
	{
		PPMContext tempSuffix = new PPMContext(Model.getSubAlloc().getHeap());
		tempSuffix.setAddress(Suffix);
		int ret = 0;
		ret += Model.getPrevSuccess();
		ret += Model.getNS2BSIndx()[tempSuffix.getNumStats() - 1];
		ret += Model.getHiBitsFlag() + 2* Model.getHB2Flag()[(int) rs.getSymbol() & 0xFF];
		ret += ((Model.getRunLength() >>> 26) & 0x20);
		return ret;
	}

	public int getMean(int summ, int shift, int round)
	{
		return ( (summ + (1 << (shift - round) ) ) >>> (shift) );
	}

	public void decodeBinSymbol(ModelPPM Model)
	{
		State rs = new State(Model.getSubAlloc().getHeap());
		rs.setAddress(oneState.getAddress());// State&
		Model.setHiBitsFlag(Model.getHB2Flag()[(short)Model.getFoundState().getSymbol()&0xff]);
		int off1 =(short)(rs.getFreq() & 0xFF) - 1;
		int off2 = getArrayIndex(Model, rs);
		int bs = Model.getBinSumm()[off1][off2];
		if (Model.getCoder().getCurrentShiftCount(ModelPPM.TOT_BITS) < bs) {
			Model.getFoundState().setAddress(rs.getAddress());
			rs.setFreq((byte) (rs.getFreq() + ((rs.getFreq() <= 127) ? 1 : 0)));
			Model.getCoder().getSubRange().setLowCount(0);
			Model.getCoder().getSubRange().setHighCount(bs); 
			bs = ((bs + ModelPPM.INTERVAL - getMean(bs, ModelPPM.PERIOD_BITS, 2)) & 0xffff);
			Model.getBinSumm()[off1][off2] = (short)bs;
			Model.setPrevSuccess((byte) 1); 
			Model.setRunLength(Model.getRunLength() + 1);
		} else {
			Model.getCoder().getSubRange().setLowCount(bs);
			bs = (bs - getMean(bs, ModelPPM.PERIOD_BITS, 2)) & 0xFFFF;
			Model.getBinSumm()[off1][off2] = (short)bs;
			Model.getCoder().getSubRange().setHighCount(ModelPPM.BIN_SCALE);
			Model.setInitEsc(ExpEscape[bs >>> 10]);
			Model.setNumMasked(1);
			Model.getCharMask()[(short)rs.getSymbol()&0xff] = Model.getEscCount();
			Model.setPrevSuccess((byte) 0);
			Model.getFoundState().setAddress(0);
		}
		int a = 0;//TODO just 4 debugging
	}

	public static void ppmdSwap(ModelPPM Model, State state1, State state2)
	{
		byte temp = 0;
		byte[] bytes = Model.getSubAlloc().getHeap();
		int p1 = state1.getAddress();
		int p2 = state2.getAddress();
		
		for (int i = 0; i < State.size; i++) {
			temp = bytes[p1+i];
			bytes[p1+i] = bytes[p2+i];
			bytes[p2+i] = temp;
		}
		state1.setAddress(p1);
		state2.setAddress(p2);
	}

	public void update1(ModelPPM Model, int p/* ptr */)
	{
		Model.getFoundState().setAddress(p);
		Model.getFoundState().setFreq((byte) (Model.getFoundState().getFreq() + 4));
		freqData.setSummFreq((short) (freqData.getSummFreq() + 4));
		State p0 = new State(Model.getSubAlloc().getHeap());
		State p1 = new State(Model.getSubAlloc().getHeap());
		p0.setAddress(p);
		p1.setAddress(p - State.size);
		if (p0.getFreq() > p1.getFreq()) {
			ppmdSwap(Model, p0, p1);
			Model.getFoundState().setAddress(p1.getAddress());
			if (p0.getFreq() > ModelPPM.MAX_FREQ)
				rescale(Model);
		}
	}

	public boolean decodeSymbol2(ModelPPM Model)
	{
		int count, HiCnt, i = numStats - Model.getNumMasked();
		SEE2Context psee2c = makeEscFreq2(Model, i);
		RangeCoder coder = Model.getCoder();
		// STATE* ps[256], ** pps=ps, * p=U.Stats-1;
		int[] ps = new int[256];
		State p = new State(Model.getHeap());
		State temp = new State(Model.getHeap());
		p.setAddress(freqData.getStats()  - State.size); 
		int pps = 0;
		HiCnt = 0;

		do {
			do {
				p.incAddress();// p++;
			} while (Model.getCharMask()[(int)p.getSymbol()&0xff] == Model.getEscCount());
			HiCnt += (short)p.getFreq()&0xff;
			ps[pps++] = p.getAddress();
		} while (--i != 0);
		coder.getSubRange().setScale(coder.getSubRange().getScale() + HiCnt);
		count = (int) coder.getCurrentCount();
		if (count >= coder.getSubRange().getScale()) {
			return false;
		}
		pps = 0;
		p.setAddress(ps[pps]);
		if (count < HiCnt) {
			HiCnt = 0;
			while ((HiCnt += (short)p.getFreq()&0xff) <= count) {
				p.setAddress(ps[++pps]);// p=*++pps;
			}
			coder.getSubRange().setHighCount(HiCnt);
			coder.getSubRange().setLowCount(HiCnt - p.getFreq());
			psee2c.update();
			update2(Model, p.getAddress());
		} else {
			coder.getSubRange().setLowCount(HiCnt);
			coder.getSubRange().setHighCount(coder.getSubRange().getScale());
			i = numStats - Model.getNumMasked();// ->NumMasked;
			pps--;
			do {
				temp.setAddress(++pps);
				Model.getCharMask()[temp.getSymbol()] = Model.getEscCount();
			} while (--i != 0);
			psee2c.setSumm((short) (psee2c.getSumm() + coder.getSubRange()
					.getScale()));
			Model.setNumMasked(numStats);
		}
		return (true);
	}

	public void update2(ModelPPM Model, int p/* state ptr */)
	{
		State temp = new State(Model.getHeap());
		temp.setAddress(p);
		Model.getFoundState().setAddress(p);
		Model.getFoundState().setFreq((byte) (Model.getFoundState().getFreq() + 4)); 
		freqData.setSummFreq((short) (freqData.getSummFreq() + 4));
		if (((short)temp.getFreq()&0xff) > ModelPPM.MAX_FREQ) {
			rescale(Model);
		}
		Model.setEscCount((byte) (Model.getEscCount() + 1));
		Model.setRunLength(Model.getInitRL());
	}

	public SEE2Context makeEscFreq2(ModelPPM Model, int Diff)
	{
		SEE2Context psee2c;
		if (numStats != 256) {
			PPMContext suff = new PPMContext(Model.getHeap());
			suff.setAddress(Suffix);
			int idx1 = 0, idx2 = 0;
			int i = Model.getNS2Indx()[Diff - 1];
			int offset = i * SEE2Context.size;
			offset += (Diff < suff.getNumStats() - numStats) ? 1 : 0;
			offset += 2 * ((freqData.getSummFreq() < 11 * numStats) ? 1 : 0); 
			offset += 4 * ((Model.getNumMasked() > Diff) ? 1 : 0); 
			offset += Model.getHiBitsFlag();
			offset = offset / SEE2Context.size;
			idx1 = offset / 25;
			idx2 = offset % 25;
			psee2c = Model.getSEE2Cont()[idx1][idx2];
			Model.getCoder().getSubRange().setScale(psee2c.getMean());
		} else {
			psee2c = Model.getDummySEE2Cont();
			Model.getCoder().getSubRange().setScale(1);
		}
		return psee2c;
	}

	public boolean decodeSymbol1(ModelPPM Model)
	{

		RangeCoder coder = Model.getCoder();
		coder.getSubRange().setScale(freqData.getSummFreq());
		State p = new State(Model.getHeap());
		p.setAddress(freqData.getStats());
		int i, HiCnt;
		int count = (int) coder.getCurrentCount();
		if (count >= coder.getSubRange().getScale()) {
			return false;
		}
		if (count < (HiCnt = p.getFreq())) {
			coder.getSubRange().setHighCount(HiCnt);
			Model.setPrevSuccess((byte) (2 * ((HiCnt > coder.getSubRange().getScale()) ? 1 : 0)));
			Model.setRunLength(Model.getRunLength() + Model.getPrevSuccess());
			HiCnt += 4;
			Model.getFoundState().setAddress(p.getAddress());
			Model.getFoundState().setFreq((byte) HiCnt);
			freqData.setSummFreq((short) (freqData.getSummFreq() + 4));
			if (HiCnt > ModelPPM.MAX_FREQ) {
				rescale(Model);
			}
			coder.getSubRange().setLowCount(0);
			return true;
		} else {
			if (Model.getFoundState().getAddress() == 0) {
				return (false);
			}
		}
		Model.setPrevSuccess((byte) 0);
		i = numStats - 1;
		while ((HiCnt += ((short)p.incAddress().getFreq())&0xff) <= count)
		{
			if (--i == 0) {
				Model.setHiBitsFlag(Model.getHB2Flag()[Model.getFoundState().getSymbol()]);
				coder.getSubRange().setLowCount(HiCnt);
				Model.getCharMask()[(short)p.getSymbol()&0xff] = Model.getEscCount();
				Model.setNumMasked(numStats);
				i = numStats - 1;
				Model.getFoundState().setAddress(0);
				do {
					Model.getCharMask()[p.decAddress().getSymbol()] = Model.getEscCount();
				} while (--i != 0);
				coder.getSubRange().setHighCount(coder.getSubRange().getScale());
				return (true);
			}
		}
		coder.getSubRange().setLowCount(HiCnt-p.getFreq());
		coder.getSubRange().setHighCount(HiCnt);
		update1(Model, p.getAddress());
		return (true);
	}

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -