view 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
line wrap: on
line source
1 // PpmdDecode.h
2 // This code is based on Dmitry Shkarin's PPMdH code
4 #ifndef __COMPRESS_PPMD_DECODE_H
5 #define __COMPRESS_PPMD_DECODE_H
7 #include "PpmdContext.h"
9 namespace NCompress {
10 namespace NPpmd {
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 };
20 typedef NRangeCoder::CDecoder CRangeDecoderMy;
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 };
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 }
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 }
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 );
102 freqSum += hiCnt;
103 count = rangeDecoder->GetThreshold(freqSum);
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);
113 psee2c->update();
114 update2(p);
115 }
116 else
117 {
118 rangeDecoder->Decode(hiCnt, freqSum - hiCnt); // , freqSum);
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 }
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 };
152 }}
154 #endif