123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- #ifndef _RAR_PPMMODEL_
- #define _RAR_PPMMODEL_
- #include "coder.hpp"
- #include "suballoc.hpp"
- const int MAX_O=64; /* maximum allowed model order */
- 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;
- #ifndef STRICT_ALIGNMENT_REQUIRED
- #pragma pack(1)
- #endif
- struct SEE2_CONTEXT
- { // 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=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 PPM_CONTEXT;
- struct STATE
- {
- byte Symbol;
- byte Freq;
- PPM_CONTEXT* Successor;
- };
- struct FreqData
- {
- ushort SummFreq;
- STATE _PACK_ATTR * Stats;
- };
- struct PPM_CONTEXT
- {
- ushort NumStats;
- union
- {
- FreqData U;
- STATE OneState;
- };
- PPM_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,STATE* p); // CD suffix
- inline void update2(ModelPPM *Model,STATE* p); // BCDE successor
- void rescale(ModelPPM *Model);
- inline PPM_CONTEXT* createChild(ModelPPM *Model,STATE* pStats,STATE& FirstState);
- inline SEE2_CONTEXT* makeEscFreq2(ModelPPM *Model,int Diff);
- };
- #ifndef STRICT_ALIGNMENT_REQUIRED
- #ifdef _AIX
- #pragma pack(pop)
- #else
- #pragma pack()
- #endif
- #endif
- const uint UNIT_SIZE=Max(sizeof(PPM_CONTEXT),sizeof(RAR_MEM_BLK));
- const uint FIXED_UNIT_SIZE=12;
- /*
- inline PPM_CONTEXT::PPM_CONTEXT(STATE* pStats,PPM_CONTEXT* ShorterContext):
- NumStats(1), Suffix(ShorterContext) { pStats->Successor=this; }
- inline PPM_CONTEXT::PPM_CONTEXT(): NumStats(0) {}
- */
- template <class T>
- inline void _PPMD_SWAP(T& t1,T& t2) { T tmp=t1; t1=t2; t2=tmp; }
- class ModelPPM
- {
- private:
- friend struct PPM_CONTEXT;
-
- SEE2_CONTEXT SEE2Cont[25][16], DummySEE2Cont;
-
- struct PPM_CONTEXT *MinContext, *MedContext, *MaxContext;
- 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 PPM_CONTEXT* CreateSuccessors(bool Skip,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
|