summaryrefslogtreecommitdiffstats
path: root/src/libs/7zip/unix/CPP/7zip/Compress/PpmdDecode.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/7zip/unix/CPP/7zip/Compress/PpmdDecode.h')
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Compress/PpmdDecode.h156
1 files changed, 156 insertions, 0 deletions
diff --git a/src/libs/7zip/unix/CPP/7zip/Compress/PpmdDecode.h b/src/libs/7zip/unix/CPP/7zip/Compress/PpmdDecode.h
new file mode 100644
index 000000000..fe6927bf8
--- /dev/null
+++ b/src/libs/7zip/unix/CPP/7zip/Compress/PpmdDecode.h
@@ -0,0 +1,156 @@
+// PpmdDecode.h
+// 2009-05-30 : Igor Pavlov : Public domain
+// This code is based on Dmitry Shkarin's PPMdH code (public domain)
+
+#ifndef __COMPRESS_PPMD_DECODE_H
+#define __COMPRESS_PPMD_DECODE_H
+
+#include "PpmdContext.h"
+
+namespace NCompress {
+namespace NPpmd {
+
+class CRangeDecoderVirt
+{
+public:
+ virtual ~CRangeDecoderVirt() {}
+ virtual UInt32 GetThreshold(UInt32 total) = 0;
+ virtual void Decode(UInt32 start, UInt32 size) = 0;
+ virtual UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits) = 0;
+};
+
+typedef NRangeCoder::CDecoder CRangeDecoderMy;
+
+class CRangeDecoder:public CRangeDecoderVirt, public CRangeDecoderMy
+{
+ UInt32 GetThreshold(UInt32 total) { return CRangeDecoderMy::GetThreshold(total); }
+ void Decode(UInt32 start, UInt32 size) { CRangeDecoderMy::Decode(start, size); }
+ UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits) { return CRangeDecoderMy::DecodeBit(size0, numTotalBits); }
+};
+
+struct CDecodeInfo: public CInfo
+{
+ void DecodeBinSymbol(CRangeDecoderVirt *rangeDecoder)
+ {
+ PPM_CONTEXT::STATE& rs = MinContext->oneState();
+ UInt16& bs = GetBinSumm(rs, GetContextNoCheck(MinContext->Suffix)->NumStats);
+ if (rangeDecoder->DecodeBit(bs, TOT_BITS) == 0)
+ {
+ FoundState = &rs;
+ rs.Freq = (Byte)(rs.Freq + (rs.Freq < 128 ? 1: 0));
+ bs = (UInt16)(bs + INTERVAL - GET_MEAN(bs, PERIOD_BITS, 2));
+ PrevSuccess = 1;
+ RunLength++;
+ }
+ else
+ {
+ bs = (UInt16)(bs - GET_MEAN(bs, PERIOD_BITS, 2));
+ InitEsc = ExpEscape[bs >> 10];
+ NumMasked = 1;
+ CharMask[rs.Symbol] = EscCount;
+ PrevSuccess = 0;
+ FoundState = NULL;
+ }
+ }
+
+ void DecodeSymbol1(CRangeDecoderVirt *rangeDecoder)
+ {
+ PPM_CONTEXT::STATE* p = GetStateNoCheck(MinContext->Stats);
+ int i, count, hiCnt;
+ if ((count = rangeDecoder->GetThreshold(MinContext->SummFreq)) < (hiCnt = p->Freq))
+ {
+ PrevSuccess = (2 * hiCnt > MinContext->SummFreq);
+ RunLength += PrevSuccess;
+ rangeDecoder->Decode(0, p->Freq); // MinContext->SummFreq);
+ (FoundState = p)->Freq = (Byte)(hiCnt += 4);
+ MinContext->SummFreq += 4;
+ if (hiCnt > MAX_FREQ)
+ rescale();
+ return;
+ }
+ PrevSuccess = 0;
+ i = MinContext->NumStats - 1;
+ while ((hiCnt += (++p)->Freq) <= count)
+ if (--i == 0)
+ {
+ HiBitsFlag = HB2Flag[FoundState->Symbol];
+ rangeDecoder->Decode(hiCnt, MinContext->SummFreq - hiCnt); // , MinContext->SummFreq);
+ CharMask[p->Symbol] = EscCount;
+ i = (NumMasked = MinContext->NumStats)-1;
+ FoundState = NULL;
+ do { CharMask[(--p)->Symbol] = EscCount; } while ( --i );
+ return;
+ }
+ rangeDecoder->Decode(hiCnt - p->Freq, p->Freq); // , MinContext->SummFreq);
+ update1(p);
+ }
+
+
+ void DecodeSymbol2(CRangeDecoderVirt *rangeDecoder)
+ {
+ int count, hiCnt, i = MinContext->NumStats - NumMasked;
+ UInt32 freqSum;
+ SEE2_CONTEXT* psee2c = makeEscFreq2(i, freqSum);
+ PPM_CONTEXT::STATE* ps[256], ** pps = ps, * p = GetStateNoCheck(MinContext->Stats)-1;
+ hiCnt = 0;
+ do
+ {
+ do { p++; } while (CharMask[p->Symbol] == EscCount);
+ hiCnt += p->Freq;
+ *pps++ = p;
+ }
+ while ( --i );
+
+ freqSum += hiCnt;
+ count = rangeDecoder->GetThreshold(freqSum);
+
+ p = *(pps = ps);
+ if (count < hiCnt)
+ {
+ hiCnt = 0;
+ while ((hiCnt += p->Freq) <= count)
+ p=*++pps;
+ rangeDecoder->Decode(hiCnt - p->Freq, p->Freq); // , freqSum);
+
+ psee2c->update();
+ update2(p);
+ }
+ else
+ {
+ rangeDecoder->Decode(hiCnt, freqSum - hiCnt); // , freqSum);
+
+ i = MinContext->NumStats - NumMasked;
+ pps--;
+ do { CharMask[(*++pps)->Symbol] = EscCount; } while ( --i );
+ psee2c->Summ = (UInt16)(psee2c->Summ + freqSum);
+ NumMasked = MinContext->NumStats;
+ }
+ }
+
+ int DecodeSymbol(CRangeDecoderVirt *rangeDecoder)
+ {
+ if (MinContext->NumStats != 1)
+ DecodeSymbol1(rangeDecoder);
+ else
+ DecodeBinSymbol(rangeDecoder);
+ while ( !FoundState )
+ {
+ do
+ {
+ OrderFall++;
+ MinContext = GetContext(MinContext->Suffix);
+ if (MinContext == 0)
+ return -1;
+ }
+ while (MinContext->NumStats == NumMasked);
+ DecodeSymbol2(rangeDecoder);
+ }
+ Byte symbol = FoundState->Symbol;
+ NextContext();
+ return symbol;
+ }
+};
+
+}}
+
+#endif