Beispiel #1
0
        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);
            }
        }