1 #ifndef _RAR_PPMMODEL_
2 #define _RAR_PPMMODEL_
3
4 #include "rartypes.hpp"
5 #include "rardefs.hpp"
6 #include "coder.hpp"
7 #include "suballoc.hpp"
8
9 class Unpack;
10
11 const int MAX_O=64; /* maximum allowed model order */
12
13 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 #ifndef STRICT_ALIGNMENT_REQUIRED
17 #pragma pack(1)
18 #endif
19
20 struct SEE2_CONTEXT
21 { // SEE-contexts for PPM-contexts with masked symbols
22 ushort Summ;
23 byte Shift, Count;
initSEE2_CONTEXT24 void init(int InitVal)
25 {
26 Summ=InitVal << (Shift=PERIOD_BITS-4);
27 Count=4;
28 }
getMeanSEE2_CONTEXT29 uint getMean()
30 {
31 uint RetVal=SHORT16(Summ) >> Shift;
32 Summ -= RetVal;
33 return RetVal+(RetVal == 0);
34 }
updateSEE2_CONTEXT35 void update()
36 {
37 if (Shift < PERIOD_BITS && --Count == 0)
38 {
39 Summ += Summ;
40 Count=3 << Shift++;
41 }
42 }
43 };
44
45
46 class ModelPPM;
47 struct PPM_CONTEXT;
48
49 struct STATE
50 {
51 byte Symbol;
52 byte Freq;
53 PPM_CONTEXT* Successor;
54 };
55
56 struct FreqData
57 {
58 ushort SummFreq;
59 STATE _PACK_ATTR * Stats;
60 };
61
62 struct PPM_CONTEXT
63 {
64 ushort NumStats;
65 union
66 {
67 FreqData U;
68 STATE OneState;
69 };
70
71 PPM_CONTEXT* Suffix;
72 inline void encodeBinSymbol(ModelPPM *Model,int symbol); // MaxOrder:
73 inline void encodeSymbol1(ModelPPM *Model,int symbol); // ABCD context
74 inline void encodeSymbol2(ModelPPM *Model,int symbol); // BCD suffix
75 inline void decodeBinSymbol(ModelPPM *Model); // BCDE successor
76 inline bool decodeSymbol1(ModelPPM *Model); // other orders:
77 inline bool decodeSymbol2(ModelPPM *Model); // BCD context
78 inline void update1(ModelPPM *Model,STATE* p); // CD suffix
79 inline void update2(ModelPPM *Model,STATE* p); // BCDE successor
80 void rescale(ModelPPM *Model);
81 inline PPM_CONTEXT* createChild(ModelPPM *Model,STATE* pStats,STATE& FirstState);
82 inline SEE2_CONTEXT* makeEscFreq2(ModelPPM *Model,int Diff);
83 };
84
85 #ifndef STRICT_ALIGNMENT_REQUIRED
86 #ifdef _AIX
87 #pragma pack(pop)
88 #else
89 #pragma pack()
90 #endif
91 #endif
92
93 const uint UNIT_SIZE=Max(sizeof(PPM_CONTEXT),sizeof(RAR_MEM_BLK));
94 const uint FIXED_UNIT_SIZE=12;
95
96 /*
97 inline PPM_CONTEXT::PPM_CONTEXT(STATE* pStats,PPM_CONTEXT* ShorterContext):
98 NumStats(1), Suffix(ShorterContext) { pStats->Successor=this; }
99 inline PPM_CONTEXT::PPM_CONTEXT(): NumStats(0) {}
100 */
101
102 template <class T>
_PPMD_SWAP(T & t1,T & t2)103 inline void _PPMD_SWAP(T& t1,T& t2) { T tmp=t1; t1=t2; t2=tmp; }
104
105
106 class ModelPPM
107 {
108 private:
109 friend struct PPM_CONTEXT;
110
111 SEE2_CONTEXT SEE2Cont[25][16], DummySEE2Cont;
112
113 struct PPM_CONTEXT *MinContext, *MedContext, *MaxContext;
114 STATE* FoundState; // found next state transition
115 int NumMasked, InitEsc, OrderFall, MaxOrder, RunLength, InitRL;
116 byte CharMask[256], NS2Indx[256], NS2BSIndx[256], HB2Flag[256];
117 byte EscCount, PrevSuccess, HiBitsFlag;
118 ushort BinSumm[128][64]; // binary SEE-contexts
119
120 RangeCoder Coder;
121 SubAllocator SubAlloc;
122
123 void RestartModelRare();
124 void StartModelRare(int MaxOrder);
125 inline PPM_CONTEXT* CreateSuccessors(bool Skip,STATE* p1);
126
127 inline void UpdateModel();
128 inline void ClearMask();
129 public:
130 ModelPPM();
131 ModelPPM(const ModelPPM ©);
132 const ModelPPM& operator=(const ModelPPM &src);
133 void CleanUp(); // reset PPM variables after data error
134 bool DecodeInit(Unpack *UnpackRead,int &EscChar);
135 int DecodeChar();
136 };
137
138 #endif
139