1a39fc08dSMartin Matuska /* Ppmd8.h -- PPMdI codec 2a39fc08dSMartin Matuska 2011-01-27 : Igor Pavlov : Public domain 3a39fc08dSMartin Matuska This code is based on: 4a39fc08dSMartin Matuska PPMd var.I (2002): Dmitry Shkarin : Public domain 5a39fc08dSMartin Matuska Carryless rangecoder (1999): Dmitry Subbotin : Public domain */ 6a39fc08dSMartin Matuska 7*f9762417SMartin Matuska #ifndef ARCHIVE_PPMD8_PRIVATE_H_INCLUDED 8*f9762417SMartin Matuska #define ARCHIVE_PPMD8_PRIVATE_H_INCLUDED 9a39fc08dSMartin Matuska 10a39fc08dSMartin Matuska #include "archive_ppmd_private.h" 11a39fc08dSMartin Matuska 12a39fc08dSMartin Matuska #define PPMD8_MIN_ORDER 2 13a39fc08dSMartin Matuska #define PPMD8_MAX_ORDER 16 14a39fc08dSMartin Matuska 15a39fc08dSMartin Matuska struct CPpmd8_Context_; 16a39fc08dSMartin Matuska 17a39fc08dSMartin Matuska typedef 18a39fc08dSMartin Matuska #ifdef PPMD_32BIT 19a39fc08dSMartin Matuska struct CPpmd8_Context_ * 20a39fc08dSMartin Matuska #else 21a39fc08dSMartin Matuska UInt32 22a39fc08dSMartin Matuska #endif 23a39fc08dSMartin Matuska CPpmd8_Context_Ref; 24a39fc08dSMartin Matuska 25a39fc08dSMartin Matuska #pragma pack(push, 1) 26a39fc08dSMartin Matuska 27a39fc08dSMartin Matuska typedef struct CPpmd8_Context_ 28a39fc08dSMartin Matuska { 29a39fc08dSMartin Matuska Byte NumStats; 30a39fc08dSMartin Matuska Byte Flags; 31a39fc08dSMartin Matuska UInt16 SummFreq; 32a39fc08dSMartin Matuska CPpmd_State_Ref Stats; 33a39fc08dSMartin Matuska CPpmd8_Context_Ref Suffix; 34a39fc08dSMartin Matuska } CPpmd8_Context; 35a39fc08dSMartin Matuska 36a39fc08dSMartin Matuska #pragma pack(pop) 37a39fc08dSMartin Matuska 38a39fc08dSMartin Matuska #define Ppmd8Context_OneState(p) ((CPpmd_State *)&(p)->SummFreq) 39a39fc08dSMartin Matuska 40a39fc08dSMartin Matuska /* The BUG in Shkarin's code for FREEZE mode was fixed, but that fixed 41a39fc08dSMartin Matuska code is not compatible with original code for some files compressed 42a39fc08dSMartin Matuska in FREEZE mode. So we disable FREEZE mode support. */ 43a39fc08dSMartin Matuska 44a39fc08dSMartin Matuska enum 45a39fc08dSMartin Matuska { 46a39fc08dSMartin Matuska PPMD8_RESTORE_METHOD_RESTART, 47a39fc08dSMartin Matuska PPMD8_RESTORE_METHOD_CUT_OFF 48a39fc08dSMartin Matuska #ifdef PPMD8_FREEZE_SUPPORT 49a39fc08dSMartin Matuska , PPMD8_RESTORE_METHOD_FREEZE 50a39fc08dSMartin Matuska #endif 51a39fc08dSMartin Matuska }; 52a39fc08dSMartin Matuska 53a39fc08dSMartin Matuska typedef struct 54a39fc08dSMartin Matuska { 55a39fc08dSMartin Matuska CPpmd8_Context *MinContext, *MaxContext; 56a39fc08dSMartin Matuska CPpmd_State *FoundState; 57a39fc08dSMartin Matuska unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder; 58a39fc08dSMartin Matuska Int32 RunLength, InitRL; /* must be 32-bit at least */ 59a39fc08dSMartin Matuska 60a39fc08dSMartin Matuska UInt32 Size; 61a39fc08dSMartin Matuska UInt32 GlueCount; 62a39fc08dSMartin Matuska Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart; 63a39fc08dSMartin Matuska UInt32 AlignOffset; 64a39fc08dSMartin Matuska unsigned RestoreMethod; 65a39fc08dSMartin Matuska 66a39fc08dSMartin Matuska /* Range Coder */ 67a39fc08dSMartin Matuska UInt32 Range; 68a39fc08dSMartin Matuska UInt32 Code; 69a39fc08dSMartin Matuska UInt32 Low; 70a39fc08dSMartin Matuska union 71a39fc08dSMartin Matuska { 72a39fc08dSMartin Matuska IByteIn *In; 73a39fc08dSMartin Matuska IByteOut *Out; 74a39fc08dSMartin Matuska } Stream; 75a39fc08dSMartin Matuska 76a39fc08dSMartin Matuska Byte Indx2Units[PPMD_NUM_INDEXES]; 77a39fc08dSMartin Matuska Byte Units2Indx[128]; 78a39fc08dSMartin Matuska CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES]; 79a39fc08dSMartin Matuska UInt32 Stamps[PPMD_NUM_INDEXES]; 80a39fc08dSMartin Matuska 81a39fc08dSMartin Matuska Byte NS2BSIndx[256], NS2Indx[260]; 82a39fc08dSMartin Matuska CPpmd_See DummySee, See[24][32]; 83a39fc08dSMartin Matuska UInt16 BinSumm[25][64]; 84a39fc08dSMartin Matuska } CPpmd8; 85a39fc08dSMartin Matuska 86a39fc08dSMartin Matuska void Ppmd8_Construct(CPpmd8 *p); 87a39fc08dSMartin Matuska Bool Ppmd8_Alloc(CPpmd8 *p, UInt32 size); 88a39fc08dSMartin Matuska void Ppmd8_Free(CPpmd8 *p); 89a39fc08dSMartin Matuska void Ppmd8_Init(CPpmd8 *p, unsigned maxOrder, unsigned restoreMethod); 90a39fc08dSMartin Matuska #define Ppmd8_WasAllocated(p) ((p)->Base != NULL) 91a39fc08dSMartin Matuska 92a39fc08dSMartin Matuska 93a39fc08dSMartin Matuska /* ---------- Internal Functions ---------- */ 94a39fc08dSMartin Matuska 95a39fc08dSMartin Matuska extern const Byte PPMD8_kExpEscape[16]; 96a39fc08dSMartin Matuska 97a39fc08dSMartin Matuska #ifdef PPMD_32BIT 98a39fc08dSMartin Matuska #define Ppmd8_GetPtr(p, ptr) (ptr) 99a39fc08dSMartin Matuska #define Ppmd8_GetContext(p, ptr) (ptr) 100a39fc08dSMartin Matuska #define Ppmd8_GetStats(p, ctx) ((ctx)->Stats) 101a39fc08dSMartin Matuska #else 102a39fc08dSMartin Matuska #define Ppmd8_GetPtr(p, offs) ((void *)((p)->Base + (offs))) 103a39fc08dSMartin Matuska #define Ppmd8_GetContext(p, offs) ((CPpmd8_Context *)Ppmd8_GetPtr((p), (offs))) 104a39fc08dSMartin Matuska #define Ppmd8_GetStats(p, ctx) ((CPpmd_State *)Ppmd8_GetPtr((p), ((ctx)->Stats))) 105a39fc08dSMartin Matuska #endif 106a39fc08dSMartin Matuska 107a39fc08dSMartin Matuska void Ppmd8_Update1(CPpmd8 *p); 108a39fc08dSMartin Matuska void Ppmd8_Update1_0(CPpmd8 *p); 109a39fc08dSMartin Matuska void Ppmd8_Update2(CPpmd8 *p); 110a39fc08dSMartin Matuska void Ppmd8_UpdateBin(CPpmd8 *p); 111a39fc08dSMartin Matuska 112a39fc08dSMartin Matuska #define Ppmd8_GetBinSumm(p) \ 113a39fc08dSMartin Matuska &p->BinSumm[p->NS2Indx[Ppmd8Context_OneState(p->MinContext)->Freq - 1]][ \ 114a39fc08dSMartin Matuska p->NS2BSIndx[Ppmd8_GetContext(p, p->MinContext->Suffix)->NumStats] + \ 115a39fc08dSMartin Matuska p->PrevSuccess + p->MinContext->Flags + ((p->RunLength >> 26) & 0x20)] 116a39fc08dSMartin Matuska 117a39fc08dSMartin Matuska CPpmd_See *Ppmd8_MakeEscFreq(CPpmd8 *p, unsigned numMasked, UInt32 *scale); 118a39fc08dSMartin Matuska 119a39fc08dSMartin Matuska 120a39fc08dSMartin Matuska /* ---------- Decode ---------- */ 121a39fc08dSMartin Matuska 122a39fc08dSMartin Matuska Bool Ppmd8_RangeDec_Init(CPpmd8 *p); 123a39fc08dSMartin Matuska #define Ppmd8_RangeDec_IsFinishedOK(p) ((p)->Code == 0) 124a39fc08dSMartin Matuska int Ppmd8_DecodeSymbol(CPpmd8 *p); /* returns: -1 as EndMarker, -2 as DataError */ 125a39fc08dSMartin Matuska 126a39fc08dSMartin Matuska /* ---------- Encode ---------- */ 127a39fc08dSMartin Matuska 128a39fc08dSMartin Matuska #define Ppmd8_RangeEnc_Init(p) { (p)->Low = 0; (p)->Range = 0xFFFFFFFF; } 129a39fc08dSMartin Matuska void Ppmd8_RangeEnc_FlushData(CPpmd8 *p); 130a39fc08dSMartin Matuska void Ppmd8_EncodeSymbol(CPpmd8 *p, int symbol); /* symbol = -1 means EndMarker */ 131a39fc08dSMartin Matuska 132a39fc08dSMartin Matuska typedef struct 133a39fc08dSMartin Matuska { 134a39fc08dSMartin Matuska /* Base Functions */ 135a39fc08dSMartin Matuska void (*Ppmd8_Construct)(CPpmd8 *p); 136a39fc08dSMartin Matuska Bool (*Ppmd8_Alloc)(CPpmd8 *p, UInt32 size); 137a39fc08dSMartin Matuska void (*Ppmd8_Free)(CPpmd8 *p); 138a39fc08dSMartin Matuska void (*Ppmd8_Init)(CPpmd8 *p, unsigned max_order, unsigned restore_method); 139a39fc08dSMartin Matuska #define Ppmd7_WasAllocated(p) ((p)->Base != NULL) 140a39fc08dSMartin Matuska 141a39fc08dSMartin Matuska /* Decode Functions */ 142a39fc08dSMartin Matuska int (*Ppmd8_RangeDec_Init)(CPpmd8 *p); 143a39fc08dSMartin Matuska int (*Ppmd8_DecodeSymbol)(CPpmd8 *p); 144a39fc08dSMartin Matuska } IPpmd8; 145a39fc08dSMartin Matuska 146a39fc08dSMartin Matuska extern const IPpmd8 __archive_ppmd8_functions; 147a39fc08dSMartin Matuska 148a39fc08dSMartin Matuska #endif 149