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