mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-08 14:07:00 -06:00
3.13
This commit is contained in:
144
7zip/Compress/PPMD/PPMDEncode.h
Executable file
144
7zip/Compress/PPMD/PPMDEncode.h
Executable file
@@ -0,0 +1,144 @@
|
||||
// PPMDEncode.h
|
||||
// This code is based on Dmitry Shkarin's PPMdH code
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __COMPRESS_PPM_PPMD_ENCODE_H
|
||||
#define __COMPRESS_PPM_PPMD_ENCODE_H
|
||||
|
||||
#include "PPMDContext.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NPPMD {
|
||||
|
||||
struct CEncodeInfo: public CInfo
|
||||
{
|
||||
|
||||
void EncodeBinSymbol(int symbol, NRangeCoder::CEncoder *rangeEncoder)
|
||||
{
|
||||
PPM_CONTEXT::STATE& rs = MinContext->oneState();
|
||||
WORD &bs = GetBinSumm(rs, MinContext->Suffix->NumStats);
|
||||
if (rs.Symbol == symbol)
|
||||
{
|
||||
FoundState = &rs;
|
||||
rs.Freq += (rs.Freq < 128);
|
||||
rangeEncoder->EncodeBit(bs, TOT_BITS, 0);
|
||||
bs += UINT16(INTERVAL-GET_MEAN(bs,PERIOD_BITS, 2));
|
||||
PrevSuccess = 1;
|
||||
RunLength++;
|
||||
}
|
||||
else
|
||||
{
|
||||
rangeEncoder->EncodeBit(bs, TOT_BITS, 1);
|
||||
bs -= UINT16(GET_MEAN(bs,PERIOD_BITS, 2));
|
||||
InitEsc = ExpEscape[bs >> 10];
|
||||
NumMasked = 1;
|
||||
CharMask[rs.Symbol] = EscCount;
|
||||
PrevSuccess = 0;
|
||||
FoundState = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void EncodeSymbol1(int symbol, NRangeCoder::CEncoder *rangeEncoder)
|
||||
{
|
||||
PPM_CONTEXT::STATE* p = MinContext->Stats;
|
||||
if (p->Symbol == symbol)
|
||||
{
|
||||
PrevSuccess = (2 * (p->Freq) > MinContext->SummFreq);
|
||||
RunLength += PrevSuccess;
|
||||
rangeEncoder->Encode(0, MinContext->Stats->Freq, MinContext->SummFreq);
|
||||
(FoundState = p)->Freq += 4;
|
||||
MinContext->SummFreq += 4;
|
||||
if (p->Freq > MAX_FREQ)
|
||||
rescale();
|
||||
return;
|
||||
}
|
||||
PrevSuccess = 0;
|
||||
int LoCnt = p->Freq, i = MinContext->NumStats - 1;
|
||||
while ((++p)->Symbol != symbol)
|
||||
{
|
||||
LoCnt += p->Freq;
|
||||
if (--i == 0)
|
||||
{
|
||||
HiBitsFlag = HB2Flag[FoundState->Symbol];
|
||||
CharMask[p->Symbol] = EscCount;
|
||||
i=(NumMasked = MinContext->NumStats)-1;
|
||||
FoundState = NULL;
|
||||
do { CharMask[(--p)->Symbol] = EscCount; } while ( --i );
|
||||
rangeEncoder->Encode(LoCnt, MinContext->SummFreq - LoCnt, MinContext->SummFreq);
|
||||
return;
|
||||
}
|
||||
}
|
||||
rangeEncoder->Encode(LoCnt, p->Freq, MinContext->SummFreq);
|
||||
update1(p);
|
||||
}
|
||||
|
||||
void EncodeSymbol2(int symbol, NRangeCoder::CEncoder *rangeEncoder)
|
||||
{
|
||||
int hiCnt, i = MinContext->NumStats - NumMasked;
|
||||
UINT32 scale;
|
||||
SEE2_CONTEXT* psee2c = makeEscFreq2(i, scale);
|
||||
PPM_CONTEXT::STATE* p = MinContext->Stats - 1;
|
||||
hiCnt = 0;
|
||||
do
|
||||
{
|
||||
do { p++; } while (CharMask[p->Symbol] == EscCount);
|
||||
hiCnt += p->Freq;
|
||||
if (p->Symbol == symbol)
|
||||
goto SYMBOL_FOUND;
|
||||
CharMask[p->Symbol] = EscCount;
|
||||
}
|
||||
while ( --i );
|
||||
|
||||
rangeEncoder->Encode(hiCnt, scale, hiCnt + scale);
|
||||
scale += hiCnt;
|
||||
|
||||
psee2c->Summ += scale;
|
||||
NumMasked = MinContext->NumStats;
|
||||
return;
|
||||
SYMBOL_FOUND:
|
||||
|
||||
UINT32 highCount = hiCnt;
|
||||
UINT32 lowCount = highCount - p->Freq;
|
||||
if ( --i )
|
||||
{
|
||||
PPM_CONTEXT::STATE* p1 = p;
|
||||
do
|
||||
{
|
||||
do { p1++; } while (CharMask[p1->Symbol] == EscCount);
|
||||
hiCnt += p1->Freq;
|
||||
}
|
||||
while ( --i );
|
||||
}
|
||||
// SubRange.scale += hiCnt;
|
||||
scale += hiCnt;
|
||||
rangeEncoder->Encode(lowCount, highCount - lowCount, scale);
|
||||
psee2c->update();
|
||||
update2(p);
|
||||
}
|
||||
|
||||
void EncodeSymbol(int c, NRangeCoder::CEncoder *rangeEncoder)
|
||||
{
|
||||
if (MinContext->NumStats != 1)
|
||||
EncodeSymbol1(c, rangeEncoder);
|
||||
else
|
||||
EncodeBinSymbol(c, rangeEncoder);
|
||||
while ( !FoundState )
|
||||
{
|
||||
do
|
||||
{
|
||||
OrderFall++;
|
||||
MinContext = MinContext->Suffix;
|
||||
if ( !MinContext )
|
||||
return; // S_OK;
|
||||
}
|
||||
while (MinContext->NumStats == NumMasked);
|
||||
EncodeSymbol2(c, rangeEncoder);
|
||||
}
|
||||
NextContext();
|
||||
}
|
||||
|
||||
};
|
||||
}}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user