1 #ifndef _RAR_PPMMODEL_
2 #define _RAR_PPMMODEL_
3 
4 #include "coder.hpp"
5 #include "suballoc.hpp"
6 
7 #ifdef ALLOW_MISALIGNED
8 #pragma pack(1)
9 #endif
10 
11 struct RARPPM_DEF
12 {
13   static const int INT_BITS=7, PERIOD_BITS=7, TOT_BITS=INT_BITS+PERIOD_BITS,
14     INTERVAL=1 << INT_BITS, BIN_SCALE=1 << TOT_BITS, MAX_FREQ=124;
15 };
16 
17 struct RARPPM_SEE2_CONTEXT : RARPPM_DEF
18 { // SEE-contexts for PPM-contexts with masked symbols
19   ushort Summ;
20   byte Shift, Count;
initRARPPM_SEE2_CONTEXT21   void init(int InitVal)
22   {
23     Summ=InitVal << (Shift=PERIOD_BITS-4);
24     Count=4;
25   }
getMeanRARPPM_SEE2_CONTEXT26   uint getMean()
27   {
28     uint RetVal=GET_SHORT16(Summ) >> Shift;
29     Summ -= RetVal;
30     return RetVal+(RetVal == 0);
31   }
updateRARPPM_SEE2_CONTEXT32   void update()
33   {
34     if (Shift < PERIOD_BITS && --Count == 0)
35     {
36       Summ += Summ;
37       Count=3 << Shift++;
38     }
39   }
40 };
41 
42 
43 class ModelPPM;
44 struct RARPPM_CONTEXT;
45 
46 struct RARPPM_STATE
47 {
48   byte Symbol;
49   byte Freq;
50   RARPPM_CONTEXT* Successor;
51 };
52 
53 
54 struct RARPPM_CONTEXT : RARPPM_DEF
55 {
56     ushort NumStats;
57 
58     struct FreqData
59     {
60       ushort SummFreq;
61       RARPPM_STATE RARPPM_PACK_ATTR * Stats;
62     };
63 
64     union
65     {
66       FreqData U;
67       RARPPM_STATE OneState;
68     };
69 
70     RARPPM_CONTEXT* Suffix;
71     inline void encodeBinSymbol(ModelPPM *Model,int symbol);  // MaxOrder:
72     inline void encodeSymbol1(ModelPPM *Model,int symbol);    //  ABCD    context
73     inline void encodeSymbol2(ModelPPM *Model,int symbol);    //   BCD    suffix
74     inline void decodeBinSymbol(ModelPPM *Model);  //   BCDE   successor
75     inline bool decodeSymbol1(ModelPPM *Model);    // other orders:
76     inline bool decodeSymbol2(ModelPPM *Model);    //   BCD    context
77     inline void update1(ModelPPM *Model,RARPPM_STATE* p); //    CD    suffix
78     inline void update2(ModelPPM *Model,RARPPM_STATE* p); //   BCDE   successor
79     void rescale(ModelPPM *Model);
80     inline RARPPM_CONTEXT* createChild(ModelPPM *Model,RARPPM_STATE* pStats,RARPPM_STATE& FirstState);
81     inline RARPPM_SEE2_CONTEXT* makeEscFreq2(ModelPPM *Model,int Diff);
82 };
83 
84 #ifdef ALLOW_MISALIGNED
85 #ifdef _AIX
86 #pragma pack(pop)
87 #else
88 #pragma pack()
89 #endif
90 #endif
91 
92 class ModelPPM : RARPPM_DEF
93 {
94   private:
95     friend struct RARPPM_CONTEXT;
96 
97     RARPPM_SEE2_CONTEXT SEE2Cont[25][16], DummySEE2Cont;
98 
99     struct RARPPM_CONTEXT *MinContext, *MedContext, *MaxContext;
100     RARPPM_STATE* FoundState;      // found next state transition
101     int NumMasked, InitEsc, OrderFall, MaxOrder, RunLength, InitRL;
102     byte CharMask[256], NS2Indx[256], NS2BSIndx[256], HB2Flag[256];
103     byte EscCount, PrevSuccess, HiBitsFlag;
104     ushort BinSumm[128][64];               // binary SEE-contexts
105 
106     RangeCoder Coder;
107     SubAllocator SubAlloc;
108 
109     void RestartModelRare();
110     void StartModelRare(int MaxOrder);
111     inline RARPPM_CONTEXT* CreateSuccessors(bool Skip,RARPPM_STATE* p1);
112 
113     inline void UpdateModel();
114     inline void ClearMask();
115   public:
116     ModelPPM();
117     void CleanUp(); // reset PPM variables after data error
118     bool DecodeInit(Unpack *UnpackRead,int &EscChar);
119     int DecodeChar();
120 };
121 
122 #endif
123