File indexing completed on 2025-02-02 04:26:00
0001 /* Ppmd8.h -- PPMdI codec 0002 2011-01-27 : Igor Pavlov : Public domain 0003 This code is based on: 0004 PPMd var.I (2002): Dmitry Shkarin : Public domain 0005 Carryless rangecoder (1999): Dmitry Subbotin : Public domain */ 0006 0007 #ifndef __PPMD8_H 0008 #define __PPMD8_H 0009 0010 #include "Ppmd.h" 0011 0012 EXTERN_C_BEGIN 0013 0014 #define PPMD8_MIN_ORDER 2 0015 #define PPMD8_MAX_ORDER 16 0016 0017 struct CPpmd8_Context_; 0018 0019 typedef 0020 #ifdef PPMD_32BIT 0021 struct CPpmd8_Context_ * 0022 #else 0023 UInt32 0024 #endif 0025 CPpmd8_Context_Ref; 0026 0027 #pragma pack(push, 1) 0028 0029 typedef struct CPpmd8_Context_ 0030 { 0031 Byte NumStats; 0032 Byte Flags; 0033 UInt16 SummFreq; 0034 CPpmd_State_Ref Stats; 0035 CPpmd8_Context_Ref Suffix; 0036 } CPpmd8_Context; 0037 0038 #pragma pack(pop) 0039 0040 #define Ppmd8Context_OneState(p) ((CPpmd_State *)&(p)->SummFreq) 0041 0042 /* The BUG in Shkarin's code for FREEZE mode was fixed, but that fixed 0043 code is not compatible with original code for some files compressed 0044 in FREEZE mode. So we disable FREEZE mode support. */ 0045 0046 enum 0047 { 0048 PPMD8_RESTORE_METHOD_RESTART, 0049 PPMD8_RESTORE_METHOD_CUT_OFF 0050 #ifdef PPMD8_FREEZE_SUPPORT 0051 , PPMD8_RESTORE_METHOD_FREEZE 0052 #endif 0053 }; 0054 0055 typedef struct 0056 { 0057 CPpmd8_Context *MinContext, *MaxContext; 0058 CPpmd_State *FoundState; 0059 unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder; 0060 Int32 RunLength, InitRL; /* must be 32-bit at least */ 0061 0062 UInt32 Size; 0063 UInt32 GlueCount; 0064 Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart; 0065 UInt32 AlignOffset; 0066 unsigned RestoreMethod; 0067 0068 /* Range Coder */ 0069 UInt32 Range; 0070 UInt32 Code; 0071 UInt32 Low; 0072 union 0073 { 0074 IByteIn *In; 0075 IByteOut *Out; 0076 } Stream; 0077 0078 Byte Indx2Units[PPMD_NUM_INDEXES]; 0079 Byte Units2Indx[128]; 0080 CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES]; 0081 UInt32 Stamps[PPMD_NUM_INDEXES]; 0082 0083 Byte NS2BSIndx[256], NS2Indx[260]; 0084 CPpmd_See DummySee, See[24][32]; 0085 UInt16 BinSumm[25][64]; 0086 } CPpmd8; 0087 0088 void Ppmd8_Construct(CPpmd8 *p); 0089 Bool Ppmd8_Alloc(CPpmd8 *p, UInt32 size, ISzAlloc *alloc); 0090 void Ppmd8_Free(CPpmd8 *p, ISzAlloc *alloc); 0091 void Ppmd8_Init(CPpmd8 *p, unsigned maxOrder, unsigned restoreMethod); 0092 #define Ppmd8_WasAllocated(p) ((p)->Base != NULL) 0093 0094 0095 /* ---------- Internal Functions ---------- */ 0096 0097 extern const Byte PPMD8_kExpEscape[16]; 0098 0099 #ifdef PPMD_32BIT 0100 #define Ppmd8_GetPtr(p, ptr) (ptr) 0101 #define Ppmd8_GetContext(p, ptr) (ptr) 0102 #define Ppmd8_GetStats(p, ctx) ((ctx)->Stats) 0103 #else 0104 #define Ppmd8_GetPtr(p, offs) ((void *)((p)->Base + (offs))) 0105 #define Ppmd8_GetContext(p, offs) ((CPpmd8_Context *)Ppmd8_GetPtr((p), (offs))) 0106 #define Ppmd8_GetStats(p, ctx) ((CPpmd_State *)Ppmd8_GetPtr((p), ((ctx)->Stats))) 0107 #endif 0108 0109 void Ppmd8_Update1(CPpmd8 *p); 0110 void Ppmd8_Update1_0(CPpmd8 *p); 0111 void Ppmd8_Update2(CPpmd8 *p); 0112 void Ppmd8_UpdateBin(CPpmd8 *p); 0113 0114 #define Ppmd8_GetBinSumm(p) \ 0115 &p->BinSumm[p->NS2Indx[Ppmd8Context_OneState(p->MinContext)->Freq - 1]][ \ 0116 p->NS2BSIndx[Ppmd8_GetContext(p, p->MinContext->Suffix)->NumStats] + \ 0117 p->PrevSuccess + p->MinContext->Flags + ((p->RunLength >> 26) & 0x20)] 0118 0119 CPpmd_See *Ppmd8_MakeEscFreq(CPpmd8 *p, unsigned numMasked, UInt32 *scale); 0120 0121 0122 /* ---------- Decode ---------- */ 0123 0124 Bool Ppmd8_RangeDec_Init(CPpmd8 *p); 0125 #define Ppmd8_RangeDec_IsFinishedOK(p) ((p)->Code == 0) 0126 int Ppmd8_DecodeSymbol(CPpmd8 *p); /* returns: -1 as EndMarker, -2 as DataError */ 0127 0128 0129 /* ---------- Encode ---------- */ 0130 0131 #define Ppmd8_RangeEnc_Init(p) { (p)->Low = 0; (p)->Range = 0xFFFFFFFF; } 0132 void Ppmd8_RangeEnc_FlushData(CPpmd8 *p); 0133 void Ppmd8_EncodeSymbol(CPpmd8 *p, int symbol); /* symbol = -1 means EndMarker */ 0134 0135 EXTERN_C_END 0136 0137 #endif