1344063Smm/* Ppmd8.h -- PPMdI codec
2344063Smm2011-01-27 : Igor Pavlov : Public domain
3344063SmmThis code is based on:
4344063Smm  PPMd var.I (2002): Dmitry Shkarin : Public domain
5344063Smm  Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
6344063Smm
7358090Smm#ifndef ARCHIVE_PPMD8_PRIVATE_H_INCLUDED
8358090Smm#define ARCHIVE_PPMD8_PRIVATE_H_INCLUDED
9344063Smm
10344063Smm#include "archive_ppmd_private.h"
11344063Smm
12344063Smm#define PPMD8_MIN_ORDER 2
13344063Smm#define PPMD8_MAX_ORDER 16
14344063Smm
15344063Smmstruct CPpmd8_Context_;
16344063Smm
17344063Smmtypedef
18344063Smm  #ifdef PPMD_32BIT
19344063Smm    struct CPpmd8_Context_ *
20344063Smm  #else
21344063Smm    UInt32
22344063Smm  #endif
23344063Smm  CPpmd8_Context_Ref;
24344063Smm
25344063Smm#pragma pack(push, 1)
26344063Smm
27344063Smmtypedef struct CPpmd8_Context_
28344063Smm{
29344063Smm  Byte NumStats;
30344063Smm  Byte Flags;
31344063Smm  UInt16 SummFreq;
32344063Smm  CPpmd_State_Ref Stats;
33344063Smm  CPpmd8_Context_Ref Suffix;
34344063Smm} CPpmd8_Context;
35344063Smm
36344063Smm#pragma pack(pop)
37344063Smm
38344063Smm#define Ppmd8Context_OneState(p) ((CPpmd_State *)&(p)->SummFreq)
39344063Smm
40344063Smm/* The BUG in Shkarin's code for FREEZE mode was fixed, but that fixed
41344063Smm   code is not compatible with original code for some files compressed
42344063Smm   in FREEZE mode. So we disable FREEZE mode support. */
43344063Smm
44344063Smmenum
45344063Smm{
46344063Smm  PPMD8_RESTORE_METHOD_RESTART,
47344063Smm  PPMD8_RESTORE_METHOD_CUT_OFF
48344063Smm  #ifdef PPMD8_FREEZE_SUPPORT
49344063Smm  , PPMD8_RESTORE_METHOD_FREEZE
50344063Smm  #endif
51344063Smm};
52344063Smm
53344063Smmtypedef struct
54344063Smm{
55344063Smm  CPpmd8_Context *MinContext, *MaxContext;
56344063Smm  CPpmd_State *FoundState;
57344063Smm  unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder;
58344063Smm  Int32 RunLength, InitRL; /* must be 32-bit at least */
59344063Smm
60344063Smm  UInt32 Size;
61344063Smm  UInt32 GlueCount;
62344063Smm  Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart;
63344063Smm  UInt32 AlignOffset;
64344063Smm  unsigned RestoreMethod;
65344063Smm
66344063Smm  /* Range Coder */
67344063Smm  UInt32 Range;
68344063Smm  UInt32 Code;
69344063Smm  UInt32 Low;
70344063Smm  union
71344063Smm  {
72344063Smm    IByteIn *In;
73344063Smm    IByteOut *Out;
74344063Smm  } Stream;
75344063Smm
76344063Smm  Byte Indx2Units[PPMD_NUM_INDEXES];
77344063Smm  Byte Units2Indx[128];
78344063Smm  CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES];
79344063Smm  UInt32 Stamps[PPMD_NUM_INDEXES];
80344063Smm
81344063Smm  Byte NS2BSIndx[256], NS2Indx[260];
82344063Smm  CPpmd_See DummySee, See[24][32];
83344063Smm  UInt16 BinSumm[25][64];
84344063Smm} CPpmd8;
85344063Smm
86344063Smmvoid Ppmd8_Construct(CPpmd8 *p);
87344063SmmBool Ppmd8_Alloc(CPpmd8 *p, UInt32 size);
88344063Smmvoid Ppmd8_Free(CPpmd8 *p);
89344063Smmvoid Ppmd8_Init(CPpmd8 *p, unsigned maxOrder, unsigned restoreMethod);
90344063Smm#define Ppmd8_WasAllocated(p) ((p)->Base != NULL)
91344063Smm
92344063Smm
93344063Smm/* ---------- Internal Functions ---------- */
94344063Smm
95344063Smmextern const Byte PPMD8_kExpEscape[16];
96344063Smm
97344063Smm#ifdef PPMD_32BIT
98344063Smm  #define Ppmd8_GetPtr(p, ptr) (ptr)
99344063Smm  #define Ppmd8_GetContext(p, ptr) (ptr)
100344063Smm  #define Ppmd8_GetStats(p, ctx) ((ctx)->Stats)
101344063Smm#else
102344063Smm  #define Ppmd8_GetPtr(p, offs) ((void *)((p)->Base + (offs)))
103344063Smm  #define Ppmd8_GetContext(p, offs) ((CPpmd8_Context *)Ppmd8_GetPtr((p), (offs)))
104344063Smm  #define Ppmd8_GetStats(p, ctx) ((CPpmd_State *)Ppmd8_GetPtr((p), ((ctx)->Stats)))
105344063Smm#endif
106344063Smm
107344063Smmvoid Ppmd8_Update1(CPpmd8 *p);
108344063Smmvoid Ppmd8_Update1_0(CPpmd8 *p);
109344063Smmvoid Ppmd8_Update2(CPpmd8 *p);
110344063Smmvoid Ppmd8_UpdateBin(CPpmd8 *p);
111344063Smm
112344063Smm#define Ppmd8_GetBinSumm(p) \
113344063Smm    &p->BinSumm[p->NS2Indx[Ppmd8Context_OneState(p->MinContext)->Freq - 1]][ \
114344063Smm    p->NS2BSIndx[Ppmd8_GetContext(p, p->MinContext->Suffix)->NumStats] + \
115344063Smm    p->PrevSuccess + p->MinContext->Flags + ((p->RunLength >> 26) & 0x20)]
116344063Smm
117344063SmmCPpmd_See *Ppmd8_MakeEscFreq(CPpmd8 *p, unsigned numMasked, UInt32 *scale);
118344063Smm
119344063Smm
120344063Smm/* ---------- Decode ---------- */
121344063Smm
122344063SmmBool Ppmd8_RangeDec_Init(CPpmd8 *p);
123344063Smm#define Ppmd8_RangeDec_IsFinishedOK(p) ((p)->Code == 0)
124344063Smmint Ppmd8_DecodeSymbol(CPpmd8 *p); /* returns: -1 as EndMarker, -2 as DataError */
125344063Smm
126344063Smm/* ---------- Encode ---------- */
127344063Smm
128344063Smm#define Ppmd8_RangeEnc_Init(p) { (p)->Low = 0; (p)->Range = 0xFFFFFFFF; }
129344063Smmvoid Ppmd8_RangeEnc_FlushData(CPpmd8 *p);
130344063Smmvoid Ppmd8_EncodeSymbol(CPpmd8 *p, int symbol); /* symbol = -1 means EndMarker */
131344063Smm
132344063Smmtypedef struct
133344063Smm{
134344063Smm  /* Base Functions */
135344063Smm  void (*Ppmd8_Construct)(CPpmd8 *p);
136344063Smm  Bool (*Ppmd8_Alloc)(CPpmd8 *p, UInt32 size);
137344063Smm  void (*Ppmd8_Free)(CPpmd8 *p);
138344063Smm  void (*Ppmd8_Init)(CPpmd8 *p, unsigned max_order, unsigned restore_method);
139344063Smm  #define Ppmd7_WasAllocated(p) ((p)->Base != NULL)
140344063Smm
141344063Smm  /* Decode Functions */
142344063Smm  int (*Ppmd8_RangeDec_Init)(CPpmd8 *p);
143344063Smm  int (*Ppmd8_DecodeSymbol)(CPpmd8 *p);
144344063Smm} IPpmd8;
145344063Smm
146344063Smmextern const IPpmd8 __archive_ppmd8_functions;
147344063Smm
148344063Smm#endif
149