1 /* Ppmd8.h -- PPMdI codec
\r
2 2010-03-24 : Igor Pavlov : Public domain
\r
3 This code is based on:
\r
4 PPMd var.I (2002): Dmitry Shkarin : Public domain
\r
5 Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
\r
14 #define PPMD8_MIN_ORDER 2
\r
15 #define PPMD8_MAX_ORDER 16
\r
17 struct CPpmd8_Context_;
\r
21 struct CPpmd8_Context_ *
\r
27 typedef struct CPpmd8_Context_
\r
32 CPpmd_State_Ref Stats;
\r
33 CPpmd8_Context_Ref Suffix;
\r
36 #define Ppmd8Context_OneState(p) ((CPpmd_State *)&(p)->SummFreq)
\r
38 /* The BUG in Shkarin's code for FREEZE mode was fixed, but that fixed
\r
39 code is not compatible with original code for some files compressed
\r
40 in FREEZE mode. So we disable FREEZE mode support. */
\r
44 PPMD8_RESTORE_METHOD_RESTART,
\r
45 PPMD8_RESTORE_METHOD_CUT_OFF
\r
46 #ifdef PPMD8_FREEZE_SUPPORT
\r
47 , PPMD8_RESTORE_METHOD_FREEZE
\r
53 CPpmd8_Context *MinContext, *MaxContext;
\r
54 CPpmd_State *FoundState;
\r
55 unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder;
\r
56 Int32 RunLength, InitRL; /* must be 32-bit at least */
\r
60 Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart;
\r
62 unsigned RestoreMethod;
\r
74 Byte Indx2Units[PPMD_NUM_INDEXES];
\r
75 Byte Units2Indx[128];
\r
76 CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES];
\r
77 UInt32 Stamps[PPMD_NUM_INDEXES];
\r
79 Byte NS2BSIndx[256], NS2Indx[260];
\r
80 CPpmd_See DummySee, See[24][32];
\r
81 UInt16 BinSumm[25][64];
\r
84 void Ppmd8_Construct(CPpmd8 *p);
\r
85 Bool Ppmd8_Alloc(CPpmd8 *p, UInt32 size, ISzAlloc *alloc);
\r
86 void Ppmd8_Free(CPpmd8 *p, ISzAlloc *alloc);
\r
87 void Ppmd8_Init(CPpmd8 *p, unsigned maxOrder, unsigned restoreMethod);
\r
88 #define Ppmd8_WasAllocated(p) ((p)->Base != NULL)
\r
91 /* ---------- Internal Functions ---------- */
\r
93 extern const Byte PPMD8_kExpEscape[16];
\r
96 #define Ppmd8_GetPtr(p, ptr) (ptr)
\r
97 #define Ppmd8_GetContext(p, ptr) (ptr)
\r
98 #define Ppmd8_GetStats(p, ctx) ((ctx)->Stats)
\r
100 #define Ppmd8_GetPtr(p, offs) ((void *)((p)->Base + (offs)))
\r
101 #define Ppmd8_GetContext(p, offs) ((CPpmd8_Context *)Ppmd8_GetPtr((p), (offs)))
\r
102 #define Ppmd8_GetStats(p, ctx) ((CPpmd_State *)Ppmd8_GetPtr((p), ((ctx)->Stats)))
\r
105 void Ppmd8_Update1(CPpmd8 *p);
\r
106 void Ppmd8_Update1_0(CPpmd8 *p);
\r
107 void Ppmd8_Update2(CPpmd8 *p);
\r
108 void Ppmd8_UpdateBin(CPpmd8 *p);
\r
110 #define Ppmd8_GetBinSumm(p) \
\r
111 &p->BinSumm[p->NS2Indx[Ppmd8Context_OneState(p->MinContext)->Freq - 1]][ \
\r
112 p->NS2BSIndx[Ppmd8_GetContext(p, p->MinContext->Suffix)->NumStats] + \
\r
113 p->PrevSuccess + p->MinContext->Flags + ((p->RunLength >> 26) & 0x20)]
\r
115 CPpmd_See *Ppmd8_MakeEscFreq(CPpmd8 *p, unsigned numMasked, UInt32 *scale);
\r
118 /* ---------- Decode ---------- */
\r
120 Bool Ppmd8_RangeDec_Init(CPpmd8 *p);
\r
121 #define Ppmd8_RangeDec_IsFinishedOK(p) ((p)->Code == 0)
\r
122 int Ppmd8_DecodeSymbol(CPpmd8 *p); /* returns: -1 as EndMarker, -2 as DataError */
\r
125 /* ---------- Encode ---------- */
\r
127 #define Ppmd8_RangeEnc_Init(p) { (p)->Low = 0; (p)->Range = 0xFFFFFFFF; }
\r
128 void Ppmd8_RangeEnc_FlushData(CPpmd8 *p);
\r
129 void Ppmd8_EncodeSymbol(CPpmd8 *p, int symbol); /* symbol = -1 means EndMarker */
\r