1 /* Ppmd7.h -- Ppmd7 (PPMdH) compression codec 2 2021-04-13 : Igor Pavlov : Public domain 3 This code is based on: 4 PPMd var.H (2001): Dmitry Shkarin : Public domain */ 5 6 7 #ifndef __PPMD7_H 8 #define __PPMD7_H 9 10 #include "Ppmd.h" 11 12 EXTERN_C_BEGIN 13 14 #define PPMD7_MIN_ORDER 2 15 #define PPMD7_MAX_ORDER 64 16 17 #define PPMD7_MIN_MEM_SIZE (1 << 11) 18 #define PPMD7_MAX_MEM_SIZE (0xFFFFFFFF - 12 * 3) 19 20 struct CPpmd7_Context_; 21 22 typedef Ppmd_Ref_Type(struct CPpmd7_Context_) CPpmd7_Context_Ref; 23 24 // MY_CPU_pragma_pack_push_1 25 26 typedef struct CPpmd7_Context_ 27 { 28 UInt16 NumStats; 29 30 31 union 32 { 33 UInt16 SummFreq; 34 CPpmd_State2 State2; 35 } Union2; 36 37 union 38 { 39 CPpmd_State_Ref Stats; 40 CPpmd_State4 State4; 41 } Union4; 42 43 CPpmd7_Context_Ref Suffix; 44 } CPpmd7_Context; 45 46 // MY_CPU_pragma_pop 47 48 #define Ppmd7Context_OneState(p) ((CPpmd_State *)&(p)->Union2) 49 50 51 52 53 typedef struct 54 { 55 UInt32 Range; 56 UInt32 Code; 57 UInt32 Low; 58 IByteIn *Stream; 59 } CPpmd7_RangeDec; 60 61 62 typedef struct 63 { 64 UInt32 Range; 65 Byte Cache; 66 // Byte _dummy_[3]; 67 UInt64 Low; 68 UInt64 CacheSize; 69 IByteOut *Stream; 70 } CPpmd7z_RangeEnc; 71 72 73 typedef struct 74 { 75 CPpmd7_Context *MinContext, *MaxContext; 76 CPpmd_State *FoundState; 77 unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder, HiBitsFlag; 78 Int32 RunLength, InitRL; /* must be 32-bit at least */ 79 80 UInt32 Size; 81 UInt32 GlueCount; 82 UInt32 AlignOffset; 83 Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart; 84 85 86 87 88 union 89 { 90 CPpmd7_RangeDec dec; 91 CPpmd7z_RangeEnc enc; 92 } rc; 93 94 Byte Indx2Units[PPMD_NUM_INDEXES + 2]; // +2 for alignment 95 Byte Units2Indx[128]; 96 CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES]; 97 98 Byte NS2BSIndx[256], NS2Indx[256]; 99 Byte ExpEscape[16]; 100 CPpmd_See DummySee, See[25][16]; 101 UInt16 BinSumm[128][64]; 102 // int LastSymbol; 103 } CPpmd7; 104 105 106 void Ppmd7_Construct(CPpmd7 *p); 107 BoolInt Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAllocPtr alloc); 108 void Ppmd7_Free(CPpmd7 *p, ISzAllocPtr alloc); 109 void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder); 110 #define Ppmd7_WasAllocated(p) ((p)->Base != NULL) 111 112 113 /* ---------- Internal Functions ---------- */ 114 115 #define Ppmd7_GetPtr(p, ptr) Ppmd_GetPtr(p, ptr) 116 #define Ppmd7_GetContext(p, ptr) Ppmd_GetPtr_Type(p, ptr, CPpmd7_Context) 117 #define Ppmd7_GetStats(p, ctx) Ppmd_GetPtr_Type(p, (ctx)->Union4.Stats, CPpmd_State) 118 119 void Ppmd7_Update1(CPpmd7 *p); 120 void Ppmd7_Update1_0(CPpmd7 *p); 121 void Ppmd7_Update2(CPpmd7 *p); 122 123 #define PPMD7_HiBitsFlag_3(sym) ((((unsigned)sym + 0xC0) >> (8 - 3)) & (1 << 3)) 124 #define PPMD7_HiBitsFlag_4(sym) ((((unsigned)sym + 0xC0) >> (8 - 4)) & (1 << 4)) 125 // #define PPMD7_HiBitsFlag_3(sym) ((sym) < 0x40 ? 0 : (1 << 3)) 126 // #define PPMD7_HiBitsFlag_4(sym) ((sym) < 0x40 ? 0 : (1 << 4)) 127 128 #define Ppmd7_GetBinSumm(p) \ 129 &p->BinSumm[(size_t)(unsigned)Ppmd7Context_OneState(p->MinContext)->Freq - 1] \ 130 [ p->PrevSuccess + ((p->RunLength >> 26) & 0x20) \ 131 + p->NS2BSIndx[(size_t)Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] \ 132 + PPMD7_HiBitsFlag_4(Ppmd7Context_OneState(p->MinContext)->Symbol) \ 133 + (p->HiBitsFlag = PPMD7_HiBitsFlag_3(p->FoundState->Symbol)) ] 134 135 CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *scale); 136 137 138 /* 139 We support two versions of Ppmd7 (PPMdH) methods that use same CPpmd7 structure: 140 1) Ppmd7a_*: original PPMdH 141 2) Ppmd7z_*: modified PPMdH with 7z Range Coder 142 Ppmd7_*: the structures and functions that are common for both versions of PPMd7 (PPMdH) 143 */ 144 145 /* ---------- Decode ---------- */ 146 147 #define PPMD7_SYM_END (-1) 148 #define PPMD7_SYM_ERROR (-2) 149 150 /* 151 You must set (CPpmd7::rc.dec.Stream) before Ppmd7*_RangeDec_Init() 152 153 Ppmd7*_DecodeSymbol() 154 out: 155 >= 0 : decoded byte 156 -1 : PPMD7_SYM_END : End of payload marker 157 -2 : PPMD7_SYM_ERROR : Data error 158 */ 159 160 /* Ppmd7a_* : original PPMdH */ 161 BoolInt Ppmd7a_RangeDec_Init(CPpmd7_RangeDec *p); 162 #define Ppmd7a_RangeDec_IsFinishedOK(p) ((p)->Code == 0) 163 int Ppmd7a_DecodeSymbol(CPpmd7 *p); 164 165 /* Ppmd7z_* : modified PPMdH with 7z Range Coder */ 166 BoolInt Ppmd7z_RangeDec_Init(CPpmd7_RangeDec *p); 167 #define Ppmd7z_RangeDec_IsFinishedOK(p) ((p)->Code == 0) 168 int Ppmd7z_DecodeSymbol(CPpmd7 *p); 169 // Byte *Ppmd7z_DecodeSymbols(CPpmd7 *p, Byte *buf, const Byte *lim); 170 171 172 /* ---------- Encode ---------- */ 173 174 void Ppmd7z_Init_RangeEnc(CPpmd7 *p); 175 void Ppmd7z_Flush_RangeEnc(CPpmd7 *p); 176 // void Ppmd7z_EncodeSymbol(CPpmd7 *p, int symbol); 177 void Ppmd7z_EncodeSymbols(CPpmd7 *p, const Byte *buf, const Byte *lim); 178 179 EXTERN_C_END 180 181 #endif 182