mirror of
https://github.com/WinampDesktop/winamp.git
synced 2024-12-11 17:21:02 -05:00
123 lines
3 KiB
C++
123 lines
3 KiB
C++
|
#ifndef _RAR_PPMMODEL_
|
||
|
#define _RAR_PPMMODEL_
|
||
|
|
||
|
#include "coder.hpp"
|
||
|
#include "suballoc.hpp"
|
||
|
|
||
|
#ifdef ALLOW_MISALIGNED
|
||
|
#pragma pack(1)
|
||
|
#endif
|
||
|
|
||
|
struct RARPPM_DEF
|
||
|
{
|
||
|
static const int INT_BITS=7, PERIOD_BITS=7, TOT_BITS=INT_BITS+PERIOD_BITS,
|
||
|
INTERVAL=1 << INT_BITS, BIN_SCALE=1 << TOT_BITS, MAX_FREQ=124;
|
||
|
};
|
||
|
|
||
|
struct RARPPM_SEE2_CONTEXT : RARPPM_DEF
|
||
|
{ // SEE-contexts for PPM-contexts with masked symbols
|
||
|
ushort Summ;
|
||
|
byte Shift, Count;
|
||
|
void init(int InitVal)
|
||
|
{
|
||
|
Summ=InitVal << (Shift=PERIOD_BITS-4);
|
||
|
Count=4;
|
||
|
}
|
||
|
uint getMean()
|
||
|
{
|
||
|
uint RetVal=GET_SHORT16(Summ) >> Shift;
|
||
|
Summ -= RetVal;
|
||
|
return RetVal+(RetVal == 0);
|
||
|
}
|
||
|
void update()
|
||
|
{
|
||
|
if (Shift < PERIOD_BITS && --Count == 0)
|
||
|
{
|
||
|
Summ += Summ;
|
||
|
Count=3 << Shift++;
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
|
||
|
class ModelPPM;
|
||
|
struct RARPPM_CONTEXT;
|
||
|
|
||
|
struct RARPPM_STATE
|
||
|
{
|
||
|
byte Symbol;
|
||
|
byte Freq;
|
||
|
RARPPM_CONTEXT* Successor;
|
||
|
};
|
||
|
|
||
|
|
||
|
struct RARPPM_CONTEXT : RARPPM_DEF
|
||
|
{
|
||
|
ushort NumStats;
|
||
|
|
||
|
struct FreqData
|
||
|
{
|
||
|
ushort SummFreq;
|
||
|
RARPPM_STATE RARPPM_PACK_ATTR * Stats;
|
||
|
};
|
||
|
|
||
|
union
|
||
|
{
|
||
|
FreqData U;
|
||
|
RARPPM_STATE OneState;
|
||
|
};
|
||
|
|
||
|
RARPPM_CONTEXT* Suffix;
|
||
|
inline void encodeBinSymbol(ModelPPM *Model,int symbol); // MaxOrder:
|
||
|
inline void encodeSymbol1(ModelPPM *Model,int symbol); // ABCD context
|
||
|
inline void encodeSymbol2(ModelPPM *Model,int symbol); // BCD suffix
|
||
|
inline void decodeBinSymbol(ModelPPM *Model); // BCDE successor
|
||
|
inline bool decodeSymbol1(ModelPPM *Model); // other orders:
|
||
|
inline bool decodeSymbol2(ModelPPM *Model); // BCD context
|
||
|
inline void update1(ModelPPM *Model,RARPPM_STATE* p); // CD suffix
|
||
|
inline void update2(ModelPPM *Model,RARPPM_STATE* p); // BCDE successor
|
||
|
void rescale(ModelPPM *Model);
|
||
|
inline RARPPM_CONTEXT* createChild(ModelPPM *Model,RARPPM_STATE* pStats,RARPPM_STATE& FirstState);
|
||
|
inline RARPPM_SEE2_CONTEXT* makeEscFreq2(ModelPPM *Model,int Diff);
|
||
|
};
|
||
|
|
||
|
#ifdef ALLOW_MISALIGNED
|
||
|
#ifdef _AIX
|
||
|
#pragma pack(pop)
|
||
|
#else
|
||
|
#pragma pack()
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
class ModelPPM : RARPPM_DEF
|
||
|
{
|
||
|
private:
|
||
|
friend struct RARPPM_CONTEXT;
|
||
|
|
||
|
RARPPM_SEE2_CONTEXT SEE2Cont[25][16], DummySEE2Cont;
|
||
|
|
||
|
struct RARPPM_CONTEXT *MinContext, *MedContext, *MaxContext;
|
||
|
RARPPM_STATE* FoundState; // found next state transition
|
||
|
int NumMasked, InitEsc, OrderFall, MaxOrder, RunLength, InitRL;
|
||
|
byte CharMask[256], NS2Indx[256], NS2BSIndx[256], HB2Flag[256];
|
||
|
byte EscCount, PrevSuccess, HiBitsFlag;
|
||
|
ushort BinSumm[128][64]; // binary SEE-contexts
|
||
|
|
||
|
RangeCoder Coder;
|
||
|
SubAllocator SubAlloc;
|
||
|
|
||
|
void RestartModelRare();
|
||
|
void StartModelRare(int MaxOrder);
|
||
|
inline RARPPM_CONTEXT* CreateSuccessors(bool Skip,RARPPM_STATE* p1);
|
||
|
|
||
|
inline void UpdateModel();
|
||
|
inline void ClearMask();
|
||
|
public:
|
||
|
ModelPPM();
|
||
|
void CleanUp(); // reset PPM variables after data error
|
||
|
bool DecodeInit(Unpack *UnpackRead,int &EscChar);
|
||
|
int DecodeChar();
|
||
|
};
|
||
|
|
||
|
#endif
|