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