| #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 |