public int decodeChar(LZMA.RangeCoder.Decoder decoder) { if (minContext.NumStats != 1) { State s = tempState1.Initialize(Heap); s.Address = minContext.FreqData.GetStats(); int i; int count, hiCnt; if ((count = (int) decoder.GetThreshold((uint) minContext.FreqData.SummFreq)) < (hiCnt = s.Freq)) { byte symbol; decoder.Decode(0, (uint) s.Freq); symbol = (byte) s.Symbol; minContext.update1_0(this, s.Address); nextContext(); return symbol; } prevSuccess = 0; i = minContext.NumStats - 1; do { s.IncrementAddress(); if ((hiCnt += s.Freq) > count) { byte symbol; decoder.Decode((uint) (hiCnt - s.Freq), (uint) s.Freq); symbol = (byte) s.Symbol; minContext.update1(this, s.Address); nextContext(); return symbol; } } while (--i > 0); if (count >= minContext.FreqData.SummFreq) return -2; hiBitsFlag = HB2Flag[foundState.Symbol]; decoder.Decode((uint) hiCnt, (uint) (minContext.FreqData.SummFreq - hiCnt)); for (i = 0; i < 256; i++) charMask[i] = -1; charMask[s.Symbol] = 0; i = minContext.NumStats - 1; do { s.DecrementAddress(); charMask[s.Symbol] = 0; } while (--i > 0); } else { State rs = tempState1.Initialize(Heap); rs.Address = minContext.getOneState().Address; hiBitsFlag = getHB2Flag()[foundState.Symbol]; int off1 = rs.Freq - 1; int off2 = minContext.getArrayIndex(this, rs); int bs = binSumm[off1][off2]; if (decoder.DecodeBit((uint) bs, 14) == 0) { byte symbol; binSumm[off1][off2] = (bs + INTERVAL - minContext.getMean(bs, PERIOD_BITS, 2)) & 0xFFFF; foundState.Address = rs.Address; symbol = (byte) rs.Symbol; rs.IncrementFreq((rs.Freq < 128) ? 1 : 0); prevSuccess = 1; incRunLength(1); nextContext(); return symbol; } bs = (bs - minContext.getMean(bs, PERIOD_BITS, 2)) & 0xFFFF; binSumm[off1][off2] = bs; initEsc = PPMContext.ExpEscape[Utility.URShift(bs, 10)]; int i; for (i = 0; i < 256; i++) charMask[i] = -1; charMask[rs.Symbol] = 0; prevSuccess = 0; } for (;;) { State s = tempState1.Initialize(Heap); int i; int freqSum, count, hiCnt; SEE2Context see; int num, numMasked = minContext.NumStats; do { orderFall++; minContext.Address = minContext.getSuffix(); if (minContext.Address <= subAlloc.PText || minContext.Address > subAlloc.HeapEnd) return -1; } while (minContext.NumStats == numMasked); hiCnt = 0; s.Address = minContext.FreqData.GetStats(); i = 0; num = minContext.NumStats - numMasked; do { int k = charMask[s.Symbol]; hiCnt += s.Freq & k; minContext.ps[i] = s.Address; s.IncrementAddress(); i -= k; } while (i != num); see = minContext.makeEscFreq(this, numMasked, out freqSum); freqSum += hiCnt; count = (int) decoder.GetThreshold((uint) freqSum); if (count < hiCnt) { byte symbol; State ps = tempState2.Initialize(Heap); for (hiCnt = 0, i = 0, ps.Address = minContext.ps[i]; (hiCnt += ps.Freq) <= count; i++, ps.Address = minContext.ps[i]) ; s.Address = ps.Address; decoder.Decode((uint) (hiCnt - s.Freq), (uint) s.Freq); see.update(); symbol = (byte) s.Symbol; minContext.update2(this, s.Address); updateModel(); return symbol; } if (count >= freqSum) return -2; decoder.Decode((uint) hiCnt, (uint) (freqSum - hiCnt)); see.Summ = see.Summ + freqSum; do { s.Address = minContext.ps[--i]; charMask[s.Symbol] = 0; } while (i != 0); } }