xref: /aosp_15_r20/external/lzma/C/Ppmd8.h (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker /* Ppmd8.h -- Ppmd8 (PPMdI) compression codec
2*f6dc9357SAndroid Build Coastguard Worker 2023-04-02 : Igor Pavlov : Public domain
3*f6dc9357SAndroid Build Coastguard Worker This code is based on:
4*f6dc9357SAndroid Build Coastguard Worker   PPMd var.I (2002): Dmitry Shkarin : Public domain
5*f6dc9357SAndroid Build Coastguard Worker   Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
6*f6dc9357SAndroid Build Coastguard Worker 
7*f6dc9357SAndroid Build Coastguard Worker #ifndef ZIP7_INC_PPMD8_H
8*f6dc9357SAndroid Build Coastguard Worker #define ZIP7_INC_PPMD8_H
9*f6dc9357SAndroid Build Coastguard Worker 
10*f6dc9357SAndroid Build Coastguard Worker #include "Ppmd.h"
11*f6dc9357SAndroid Build Coastguard Worker 
12*f6dc9357SAndroid Build Coastguard Worker EXTERN_C_BEGIN
13*f6dc9357SAndroid Build Coastguard Worker 
14*f6dc9357SAndroid Build Coastguard Worker #define PPMD8_MIN_ORDER 2
15*f6dc9357SAndroid Build Coastguard Worker #define PPMD8_MAX_ORDER 16
16*f6dc9357SAndroid Build Coastguard Worker 
17*f6dc9357SAndroid Build Coastguard Worker 
18*f6dc9357SAndroid Build Coastguard Worker 
19*f6dc9357SAndroid Build Coastguard Worker 
20*f6dc9357SAndroid Build Coastguard Worker struct CPpmd8_Context_;
21*f6dc9357SAndroid Build Coastguard Worker 
22*f6dc9357SAndroid Build Coastguard Worker typedef Ppmd_Ref_Type(struct CPpmd8_Context_) CPpmd8_Context_Ref;
23*f6dc9357SAndroid Build Coastguard Worker 
24*f6dc9357SAndroid Build Coastguard Worker // MY_CPU_pragma_pack_push_1
25*f6dc9357SAndroid Build Coastguard Worker 
26*f6dc9357SAndroid Build Coastguard Worker typedef struct CPpmd8_Context_
27*f6dc9357SAndroid Build Coastguard Worker {
28*f6dc9357SAndroid Build Coastguard Worker   Byte NumStats;
29*f6dc9357SAndroid Build Coastguard Worker   Byte Flags;
30*f6dc9357SAndroid Build Coastguard Worker 
31*f6dc9357SAndroid Build Coastguard Worker   union
32*f6dc9357SAndroid Build Coastguard Worker   {
33*f6dc9357SAndroid Build Coastguard Worker     UInt16 SummFreq;
34*f6dc9357SAndroid Build Coastguard Worker     CPpmd_State2 State2;
35*f6dc9357SAndroid Build Coastguard Worker   } Union2;
36*f6dc9357SAndroid Build Coastguard Worker 
37*f6dc9357SAndroid Build Coastguard Worker   union
38*f6dc9357SAndroid Build Coastguard Worker   {
39*f6dc9357SAndroid Build Coastguard Worker     CPpmd_State_Ref Stats;
40*f6dc9357SAndroid Build Coastguard Worker     CPpmd_State4 State4;
41*f6dc9357SAndroid Build Coastguard Worker   } Union4;
42*f6dc9357SAndroid Build Coastguard Worker 
43*f6dc9357SAndroid Build Coastguard Worker   CPpmd8_Context_Ref Suffix;
44*f6dc9357SAndroid Build Coastguard Worker } CPpmd8_Context;
45*f6dc9357SAndroid Build Coastguard Worker 
46*f6dc9357SAndroid Build Coastguard Worker // MY_CPU_pragma_pop
47*f6dc9357SAndroid Build Coastguard Worker 
48*f6dc9357SAndroid Build Coastguard Worker #define Ppmd8Context_OneState(p) ((CPpmd_State *)&(p)->Union2)
49*f6dc9357SAndroid Build Coastguard Worker 
50*f6dc9357SAndroid Build Coastguard Worker /* PPMdI code rev.2 contains the fix over PPMdI code rev.1.
51*f6dc9357SAndroid Build Coastguard Worker    But the code PPMdI.2 is not compatible with PPMdI.1 for some files compressed
52*f6dc9357SAndroid Build Coastguard Worker    in FREEZE mode. So we disable FREEZE mode support. */
53*f6dc9357SAndroid Build Coastguard Worker 
54*f6dc9357SAndroid Build Coastguard Worker // #define PPMD8_FREEZE_SUPPORT
55*f6dc9357SAndroid Build Coastguard Worker 
56*f6dc9357SAndroid Build Coastguard Worker enum
57*f6dc9357SAndroid Build Coastguard Worker {
58*f6dc9357SAndroid Build Coastguard Worker   PPMD8_RESTORE_METHOD_RESTART,
59*f6dc9357SAndroid Build Coastguard Worker   PPMD8_RESTORE_METHOD_CUT_OFF
60*f6dc9357SAndroid Build Coastguard Worker   #ifdef PPMD8_FREEZE_SUPPORT
61*f6dc9357SAndroid Build Coastguard Worker   , PPMD8_RESTORE_METHOD_FREEZE
62*f6dc9357SAndroid Build Coastguard Worker   #endif
63*f6dc9357SAndroid Build Coastguard Worker   , PPMD8_RESTORE_METHOD_UNSUPPPORTED
64*f6dc9357SAndroid Build Coastguard Worker };
65*f6dc9357SAndroid Build Coastguard Worker 
66*f6dc9357SAndroid Build Coastguard Worker 
67*f6dc9357SAndroid Build Coastguard Worker 
68*f6dc9357SAndroid Build Coastguard Worker 
69*f6dc9357SAndroid Build Coastguard Worker 
70*f6dc9357SAndroid Build Coastguard Worker 
71*f6dc9357SAndroid Build Coastguard Worker 
72*f6dc9357SAndroid Build Coastguard Worker 
73*f6dc9357SAndroid Build Coastguard Worker typedef struct
74*f6dc9357SAndroid Build Coastguard Worker {
75*f6dc9357SAndroid Build Coastguard Worker   CPpmd8_Context *MinContext, *MaxContext;
76*f6dc9357SAndroid Build Coastguard Worker   CPpmd_State *FoundState;
77*f6dc9357SAndroid Build Coastguard Worker   unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder, RestoreMethod;
78*f6dc9357SAndroid Build Coastguard Worker   Int32 RunLength, InitRL; /* must be 32-bit at least */
79*f6dc9357SAndroid Build Coastguard Worker 
80*f6dc9357SAndroid Build Coastguard Worker   UInt32 Size;
81*f6dc9357SAndroid Build Coastguard Worker   UInt32 GlueCount;
82*f6dc9357SAndroid Build Coastguard Worker   UInt32 AlignOffset;
83*f6dc9357SAndroid Build Coastguard Worker   Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart;
84*f6dc9357SAndroid Build Coastguard Worker 
85*f6dc9357SAndroid Build Coastguard Worker   UInt32 Range;
86*f6dc9357SAndroid Build Coastguard Worker   UInt32 Code;
87*f6dc9357SAndroid Build Coastguard Worker   UInt32 Low;
88*f6dc9357SAndroid Build Coastguard Worker   union
89*f6dc9357SAndroid Build Coastguard Worker   {
90*f6dc9357SAndroid Build Coastguard Worker     IByteInPtr In;
91*f6dc9357SAndroid Build Coastguard Worker     IByteOutPtr Out;
92*f6dc9357SAndroid Build Coastguard Worker   } Stream;
93*f6dc9357SAndroid Build Coastguard Worker 
94*f6dc9357SAndroid Build Coastguard Worker   Byte Indx2Units[PPMD_NUM_INDEXES + 2]; // +2 for alignment
95*f6dc9357SAndroid Build Coastguard Worker   Byte Units2Indx[128];
96*f6dc9357SAndroid Build Coastguard Worker   CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES];
97*f6dc9357SAndroid Build Coastguard Worker   UInt32 Stamps[PPMD_NUM_INDEXES];
98*f6dc9357SAndroid Build Coastguard Worker   Byte NS2BSIndx[256], NS2Indx[260];
99*f6dc9357SAndroid Build Coastguard Worker   Byte ExpEscape[16];
100*f6dc9357SAndroid Build Coastguard Worker   CPpmd_See DummySee, See[24][32];
101*f6dc9357SAndroid Build Coastguard Worker   UInt16 BinSumm[25][64];
102*f6dc9357SAndroid Build Coastguard Worker 
103*f6dc9357SAndroid Build Coastguard Worker } CPpmd8;
104*f6dc9357SAndroid Build Coastguard Worker 
105*f6dc9357SAndroid Build Coastguard Worker 
106*f6dc9357SAndroid Build Coastguard Worker void Ppmd8_Construct(CPpmd8 *p);
107*f6dc9357SAndroid Build Coastguard Worker BoolInt Ppmd8_Alloc(CPpmd8 *p, UInt32 size, ISzAllocPtr alloc);
108*f6dc9357SAndroid Build Coastguard Worker void Ppmd8_Free(CPpmd8 *p, ISzAllocPtr alloc);
109*f6dc9357SAndroid Build Coastguard Worker void Ppmd8_Init(CPpmd8 *p, unsigned maxOrder, unsigned restoreMethod);
110*f6dc9357SAndroid Build Coastguard Worker #define Ppmd8_WasAllocated(p) ((p)->Base != NULL)
111*f6dc9357SAndroid Build Coastguard Worker 
112*f6dc9357SAndroid Build Coastguard Worker 
113*f6dc9357SAndroid Build Coastguard Worker /* ---------- Internal Functions ---------- */
114*f6dc9357SAndroid Build Coastguard Worker 
115*f6dc9357SAndroid Build Coastguard Worker #define Ppmd8_GetPtr(p, ptr)     Ppmd_GetPtr(p, ptr)
116*f6dc9357SAndroid Build Coastguard Worker #define Ppmd8_GetContext(p, ptr) Ppmd_GetPtr_Type(p, ptr, CPpmd8_Context)
117*f6dc9357SAndroid Build Coastguard Worker #define Ppmd8_GetStats(p, ctx)   Ppmd_GetPtr_Type(p, (ctx)->Union4.Stats, CPpmd_State)
118*f6dc9357SAndroid Build Coastguard Worker 
119*f6dc9357SAndroid Build Coastguard Worker void Ppmd8_Update1(CPpmd8 *p);
120*f6dc9357SAndroid Build Coastguard Worker void Ppmd8_Update1_0(CPpmd8 *p);
121*f6dc9357SAndroid Build Coastguard Worker void Ppmd8_Update2(CPpmd8 *p);
122*f6dc9357SAndroid Build Coastguard Worker 
123*f6dc9357SAndroid Build Coastguard Worker 
124*f6dc9357SAndroid Build Coastguard Worker 
125*f6dc9357SAndroid Build Coastguard Worker 
126*f6dc9357SAndroid Build Coastguard Worker 
127*f6dc9357SAndroid Build Coastguard Worker 
128*f6dc9357SAndroid Build Coastguard Worker #define Ppmd8_GetBinSumm(p) \
129*f6dc9357SAndroid Build Coastguard Worker     &p->BinSumm[p->NS2Indx[(size_t)Ppmd8Context_OneState(p->MinContext)->Freq - 1]] \
130*f6dc9357SAndroid Build Coastguard Worker     [ p->PrevSuccess + ((p->RunLength >> 26) & 0x20) \
131*f6dc9357SAndroid Build Coastguard Worker     + p->NS2BSIndx[Ppmd8_GetContext(p, p->MinContext->Suffix)->NumStats] + \
132*f6dc9357SAndroid Build Coastguard Worker     + p->MinContext->Flags ]
133*f6dc9357SAndroid Build Coastguard Worker 
134*f6dc9357SAndroid Build Coastguard Worker 
135*f6dc9357SAndroid Build Coastguard Worker CPpmd_See *Ppmd8_MakeEscFreq(CPpmd8 *p, unsigned numMasked, UInt32 *scale);
136*f6dc9357SAndroid Build Coastguard Worker 
137*f6dc9357SAndroid Build Coastguard Worker 
138*f6dc9357SAndroid Build Coastguard Worker /* 20.01: the original PPMdI encoder and decoder probably could work incorrectly in some rare cases,
139*f6dc9357SAndroid Build Coastguard Worker    where the original PPMdI code can give "Divide by Zero" operation.
140*f6dc9357SAndroid Build Coastguard Worker    We use the following fix to allow correct working of encoder and decoder in any cases.
141*f6dc9357SAndroid Build Coastguard Worker    We correct (Escape_Freq) and (_sum_), if (_sum_) is larger than p->Range) */
142*f6dc9357SAndroid Build Coastguard Worker #define PPMD8_CORRECT_SUM_RANGE(p, _sum_) if (_sum_ > p->Range /* /1 */) _sum_ = p->Range;
143*f6dc9357SAndroid Build Coastguard Worker 
144*f6dc9357SAndroid Build Coastguard Worker 
145*f6dc9357SAndroid Build Coastguard Worker /* ---------- Decode ---------- */
146*f6dc9357SAndroid Build Coastguard Worker 
147*f6dc9357SAndroid Build Coastguard Worker #define PPMD8_SYM_END    (-1)
148*f6dc9357SAndroid Build Coastguard Worker #define PPMD8_SYM_ERROR  (-2)
149*f6dc9357SAndroid Build Coastguard Worker 
150*f6dc9357SAndroid Build Coastguard Worker /*
151*f6dc9357SAndroid Build Coastguard Worker You must set (CPpmd8::Stream.In) before Ppmd8_RangeDec_Init()
152*f6dc9357SAndroid Build Coastguard Worker 
153*f6dc9357SAndroid Build Coastguard Worker Ppmd8_DecodeSymbol()
154*f6dc9357SAndroid Build Coastguard Worker out:
155*f6dc9357SAndroid Build Coastguard Worker   >= 0 : decoded byte
156*f6dc9357SAndroid Build Coastguard Worker     -1 : PPMD8_SYM_END   : End of payload marker
157*f6dc9357SAndroid Build Coastguard Worker     -2 : PPMD8_SYM_ERROR : Data error
158*f6dc9357SAndroid Build Coastguard Worker */
159*f6dc9357SAndroid Build Coastguard Worker 
160*f6dc9357SAndroid Build Coastguard Worker 
161*f6dc9357SAndroid Build Coastguard Worker BoolInt Ppmd8_Init_RangeDec(CPpmd8 *p);
162*f6dc9357SAndroid Build Coastguard Worker #define Ppmd8_RangeDec_IsFinishedOK(p) ((p)->Code == 0)
163*f6dc9357SAndroid Build Coastguard Worker int Ppmd8_DecodeSymbol(CPpmd8 *p);
164*f6dc9357SAndroid Build Coastguard Worker 
165*f6dc9357SAndroid Build Coastguard Worker 
166*f6dc9357SAndroid Build Coastguard Worker 
167*f6dc9357SAndroid Build Coastguard Worker 
168*f6dc9357SAndroid Build Coastguard Worker 
169*f6dc9357SAndroid Build Coastguard Worker 
170*f6dc9357SAndroid Build Coastguard Worker 
171*f6dc9357SAndroid Build Coastguard Worker 
172*f6dc9357SAndroid Build Coastguard Worker /* ---------- Encode ---------- */
173*f6dc9357SAndroid Build Coastguard Worker 
174*f6dc9357SAndroid Build Coastguard Worker #define Ppmd8_Init_RangeEnc(p) { (p)->Low = 0; (p)->Range = 0xFFFFFFFF; }
175*f6dc9357SAndroid Build Coastguard Worker void Ppmd8_Flush_RangeEnc(CPpmd8 *p);
176*f6dc9357SAndroid Build Coastguard Worker void Ppmd8_EncodeSymbol(CPpmd8 *p, int symbol);
177*f6dc9357SAndroid Build Coastguard Worker 
178*f6dc9357SAndroid Build Coastguard Worker 
179*f6dc9357SAndroid Build Coastguard Worker EXTERN_C_END
180*f6dc9357SAndroid Build Coastguard Worker 
181*f6dc9357SAndroid Build Coastguard Worker #endif
182