annotate src/win32/7zip/7z/CPP/7zip/Compress/PpmdDecode.h @ 1:f9f4f1b99eed

importing src directory
author Robert McIntyre <rlm@mit.edu>
date Sat, 03 Mar 2012 10:31:27 -0600
parents
children
rev   line source
rlm@1 1 // PpmdDecode.h
rlm@1 2 // This code is based on Dmitry Shkarin's PPMdH code
rlm@1 3
rlm@1 4 #ifndef __COMPRESS_PPMD_DECODE_H
rlm@1 5 #define __COMPRESS_PPMD_DECODE_H
rlm@1 6
rlm@1 7 #include "PpmdContext.h"
rlm@1 8
rlm@1 9 namespace NCompress {
rlm@1 10 namespace NPpmd {
rlm@1 11
rlm@1 12 class CRangeDecoderVirt
rlm@1 13 {
rlm@1 14 public:
rlm@1 15 virtual UInt32 GetThreshold(UInt32 total) = 0;
rlm@1 16 virtual void Decode(UInt32 start, UInt32 size) = 0;
rlm@1 17 virtual UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits) = 0;
rlm@1 18 };
rlm@1 19
rlm@1 20 typedef NRangeCoder::CDecoder CRangeDecoderMy;
rlm@1 21
rlm@1 22 class CRangeDecoder:public CRangeDecoderVirt, public CRangeDecoderMy
rlm@1 23 {
rlm@1 24 UInt32 GetThreshold(UInt32 total) { return CRangeDecoderMy::GetThreshold(total); }
rlm@1 25 void Decode(UInt32 start, UInt32 size) { CRangeDecoderMy::Decode(start, size); }
rlm@1 26 UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits) { return CRangeDecoderMy::DecodeBit(size0, numTotalBits); }
rlm@1 27 };
rlm@1 28
rlm@1 29 struct CDecodeInfo: public CInfo
rlm@1 30 {
rlm@1 31 void DecodeBinSymbol(CRangeDecoderVirt *rangeDecoder)
rlm@1 32 {
rlm@1 33 PPM_CONTEXT::STATE& rs = MinContext->oneState();
rlm@1 34 UInt16& bs = GetBinSumm(rs, GetContextNoCheck(MinContext->Suffix)->NumStats);
rlm@1 35 if (rangeDecoder->DecodeBit(bs, TOT_BITS) == 0)
rlm@1 36 {
rlm@1 37 FoundState = &rs;
rlm@1 38 rs.Freq = (Byte)(rs.Freq + (rs.Freq < 128 ? 1: 0));
rlm@1 39 bs = (UInt16)(bs + INTERVAL - GET_MEAN(bs, PERIOD_BITS, 2));
rlm@1 40 PrevSuccess = 1;
rlm@1 41 RunLength++;
rlm@1 42 }
rlm@1 43 else
rlm@1 44 {
rlm@1 45 bs = (UInt16)(bs - GET_MEAN(bs, PERIOD_BITS, 2));
rlm@1 46 InitEsc = ExpEscape[bs >> 10];
rlm@1 47 NumMasked = 1;
rlm@1 48 CharMask[rs.Symbol] = EscCount;
rlm@1 49 PrevSuccess = 0;
rlm@1 50 FoundState = NULL;
rlm@1 51 }
rlm@1 52 }
rlm@1 53
rlm@1 54 void DecodeSymbol1(CRangeDecoderVirt *rangeDecoder)
rlm@1 55 {
rlm@1 56 PPM_CONTEXT::STATE* p = GetStateNoCheck(MinContext->Stats);
rlm@1 57 int i, count, hiCnt;
rlm@1 58 if ((count = rangeDecoder->GetThreshold(MinContext->SummFreq)) < (hiCnt = p->Freq))
rlm@1 59 {
rlm@1 60 PrevSuccess = (2 * hiCnt > MinContext->SummFreq);
rlm@1 61 RunLength += PrevSuccess;
rlm@1 62 rangeDecoder->Decode(0, p->Freq); // MinContext->SummFreq);
rlm@1 63 (FoundState = p)->Freq = (Byte)(hiCnt += 4);
rlm@1 64 MinContext->SummFreq += 4;
rlm@1 65 if (hiCnt > MAX_FREQ)
rlm@1 66 rescale();
rlm@1 67 return;
rlm@1 68 }
rlm@1 69 PrevSuccess = 0;
rlm@1 70 i = MinContext->NumStats - 1;
rlm@1 71 while ((hiCnt += (++p)->Freq) <= count)
rlm@1 72 if (--i == 0)
rlm@1 73 {
rlm@1 74 HiBitsFlag = HB2Flag[FoundState->Symbol];
rlm@1 75 rangeDecoder->Decode(hiCnt, MinContext->SummFreq - hiCnt); // , MinContext->SummFreq);
rlm@1 76 CharMask[p->Symbol] = EscCount;
rlm@1 77 i = (NumMasked = MinContext->NumStats)-1;
rlm@1 78 FoundState = NULL;
rlm@1 79 do { CharMask[(--p)->Symbol] = EscCount; } while ( --i );
rlm@1 80 return;
rlm@1 81 }
rlm@1 82 rangeDecoder->Decode(hiCnt - p->Freq, p->Freq); // , MinContext->SummFreq);
rlm@1 83 update1(p);
rlm@1 84 }
rlm@1 85
rlm@1 86
rlm@1 87 void DecodeSymbol2(CRangeDecoderVirt *rangeDecoder)
rlm@1 88 {
rlm@1 89 int count, hiCnt, i = MinContext->NumStats - NumMasked;
rlm@1 90 UInt32 freqSum;
rlm@1 91 SEE2_CONTEXT* psee2c = makeEscFreq2(i, freqSum);
rlm@1 92 PPM_CONTEXT::STATE* ps[256], ** pps = ps, * p = GetStateNoCheck(MinContext->Stats)-1;
rlm@1 93 hiCnt = 0;
rlm@1 94 do
rlm@1 95 {
rlm@1 96 do { p++; } while (CharMask[p->Symbol] == EscCount);
rlm@1 97 hiCnt += p->Freq;
rlm@1 98 *pps++ = p;
rlm@1 99 }
rlm@1 100 while ( --i );
rlm@1 101
rlm@1 102 freqSum += hiCnt;
rlm@1 103 count = rangeDecoder->GetThreshold(freqSum);
rlm@1 104
rlm@1 105 p = *(pps = ps);
rlm@1 106 if (count < hiCnt)
rlm@1 107 {
rlm@1 108 hiCnt = 0;
rlm@1 109 while ((hiCnt += p->Freq) <= count)
rlm@1 110 p=*++pps;
rlm@1 111 rangeDecoder->Decode(hiCnt - p->Freq, p->Freq); // , freqSum);
rlm@1 112
rlm@1 113 psee2c->update();
rlm@1 114 update2(p);
rlm@1 115 }
rlm@1 116 else
rlm@1 117 {
rlm@1 118 rangeDecoder->Decode(hiCnt, freqSum - hiCnt); // , freqSum);
rlm@1 119
rlm@1 120 i = MinContext->NumStats - NumMasked;
rlm@1 121 pps--;
rlm@1 122 do { CharMask[(*++pps)->Symbol] = EscCount; } while ( --i );
rlm@1 123 psee2c->Summ = (UInt16)(psee2c->Summ + freqSum);
rlm@1 124 NumMasked = MinContext->NumStats;
rlm@1 125 }
rlm@1 126 }
rlm@1 127
rlm@1 128 int DecodeSymbol(CRangeDecoderVirt *rangeDecoder)
rlm@1 129 {
rlm@1 130 if (MinContext->NumStats != 1)
rlm@1 131 DecodeSymbol1(rangeDecoder);
rlm@1 132 else
rlm@1 133 DecodeBinSymbol(rangeDecoder);
rlm@1 134 while ( !FoundState )
rlm@1 135 {
rlm@1 136 do
rlm@1 137 {
rlm@1 138 OrderFall++;
rlm@1 139 MinContext = GetContext(MinContext->Suffix);
rlm@1 140 if (MinContext == 0)
rlm@1 141 return -1;
rlm@1 142 }
rlm@1 143 while (MinContext->NumStats == NumMasked);
rlm@1 144 DecodeSymbol2(rangeDecoder);
rlm@1 145 }
rlm@1 146 Byte symbol = FoundState->Symbol;
rlm@1 147 NextContext();
rlm@1 148 return symbol;
rlm@1 149 }
rlm@1 150 };
rlm@1 151
rlm@1 152 }}
rlm@1 153
rlm@1 154 #endif