mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-07 03:15:00 -06:00
4.63
This commit is contained in:
committed by
Kornel Lesiński
parent
c1f1243a70
commit
3a524e5ba2
154
CPP/7zip/Compress/PpmdDecode.h
Executable file
154
CPP/7zip/Compress/PpmdDecode.h
Executable file
@@ -0,0 +1,154 @@
|
||||
// PpmdDecode.h
|
||||
// This code is based on Dmitry Shkarin's PPMdH code
|
||||
|
||||
#ifndef __COMPRESS_PPMD_DECODE_H
|
||||
#define __COMPRESS_PPMD_DECODE_H
|
||||
|
||||
#include "PpmdContext.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NPpmd {
|
||||
|
||||
class CRangeDecoderVirt
|
||||
{
|
||||
public:
|
||||
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
|
||||
Reference in New Issue
Block a user