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
|