1f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)/* Ppmd7.h -- PPMdH compression codec
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)2010-03-12 : Igor Pavlov : Public domain
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)/* This code supports virtual RangeDecoder and includes the implementation
603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)of RangeCoder from 7z, instead of RangeCoder from original PPMd var.H.
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)If you need the compatibility with original PPMd var.H, you can use external RangeDecoder */
83551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
93551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#ifndef __PPMD7_H
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __PPMD7_H
11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "Ppmd.h"
133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)EXTERN_C_BEGIN
15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#define PPMD7_MIN_ORDER 2
17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#define PPMD7_MAX_ORDER 64
18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#define PPMD7_MIN_MEM_SIZE (1 << 11)
20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#define PPMD7_MAX_MEM_SIZE (0xFFFFFFFF - 12 * 3)
21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)struct CPpmd7_Context_;
23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)typedef
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  #ifdef PPMD_32BIT
26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    struct CPpmd7_Context_ *
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  #else
28bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    UInt32
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  #endif
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CPpmd7_Context_Ref;
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
32a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)typedef struct CPpmd7_Context_
33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles){
34a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  UInt16 NumStats;
35a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  UInt16 SummFreq;
36a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CPpmd_State_Ref Stats;
37a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CPpmd7_Context_Ref Suffix;
3803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} CPpmd7_Context;
3903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
4003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#define Ppmd7Context_OneState(p) ((CPpmd_State *)&(p)->SummFreq)
4103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
4203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)typedef struct
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){
44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  CPpmd7_Context *MinContext, *MaxContext;
45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  CPpmd_State *FoundState;
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder, HiBitsFlag;
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Int32 RunLength, InitRL; /* must be 32-bit at least */
4803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
4903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  UInt32 Size;
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UInt32 GlueCount;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart;
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UInt32 AlignOffset;
5303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Byte Indx2Units[PPMD_NUM_INDEXES];
5503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  Byte Units2Indx[128];
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES];
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Byte NS2Indx[256], NS2BSIndx[256], HB2Flag[256];
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CPpmd_See DummySee, See[25][16];
59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  UInt16 BinSumm[128][64];
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} CPpmd7;
61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void Ppmd7_Construct(CPpmd7 *p);
63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc);
64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void Ppmd7_Free(CPpmd7 *p, ISzAlloc *alloc);
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder);
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define Ppmd7_WasAllocated(p) ((p)->Base != NULL)
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/* ---------- Internal Functions ---------- */
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)extern const Byte PPMD7_kExpEscape[16];
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifdef PPMD_32BIT
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  #define Ppmd7_GetPtr(p, ptr) (ptr)
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  #define Ppmd7_GetContext(p, ptr) (ptr)
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  #define Ppmd7_GetStats(p, ctx) ((ctx)->Stats)
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#else
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  #define Ppmd7_GetPtr(p, offs) ((void *)((p)->Base + (offs)))
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  #define Ppmd7_GetContext(p, offs) ((CPpmd7_Context *)Ppmd7_GetPtr((p), (offs)))
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  #define Ppmd7_GetStats(p, ctx) ((CPpmd_State *)Ppmd7_GetPtr((p), ((ctx)->Stats)))
81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Ppmd7_Update1(CPpmd7 *p);
8446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void Ppmd7_Update1_0(CPpmd7 *p);
8546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void Ppmd7_Update2(CPpmd7 *p);
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Ppmd7_UpdateBin(CPpmd7 *p);
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define Ppmd7_GetBinSumm(p) \
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    &p->BinSumm[Ppmd7Context_OneState(p->MinContext)->Freq - 1][p->PrevSuccess + \
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    p->NS2BSIndx[Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] + \
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    (p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]) + \
92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    2 * p->HB2Flag[Ppmd7Context_OneState(p->MinContext)->Symbol] + \
93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ((p->RunLength >> 26) & 0x20)]
94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *scale);
965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)/* ---------- Decode ---------- */
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)typedef struct
1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles){
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UInt32 (*GetThreshold)(void *p, UInt32 total);
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void (*Decode)(void *p, UInt32 start, UInt32 size);
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UInt32 (*DecodeBit)(void *p, UInt32 size0);
105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} IPpmd7_RangeDec;
106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)typedef struct
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){
1098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  IPpmd7_RangeDec p;
1108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  UInt32 Range;
1118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  UInt32 Code;
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  IByteIn *Stream;
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} CPpmd7z_RangeDec;
114e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
115e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p);
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p);
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define Ppmd7z_RangeDec_IsFinishedOK(p) ((p)->Code == 0)
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc);
120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/* ---------- Encode ---------- */
123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)typedef struct
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  UInt64 Low;
127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  UInt32 Range;
128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Byte Cache;
129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  UInt64 CacheSize;
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  IByteOut *Stream;
131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} CPpmd7z_RangeEnc;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void Ppmd7z_RangeEnc_Init(CPpmd7z_RangeEnc *p);
13403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void Ppmd7z_RangeEnc_FlushData(CPpmd7z_RangeEnc *p);
13503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
1363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void Ppmd7_EncodeSymbol(CPpmd7 *p, CPpmd7z_RangeEnc *rc, int symbol);
137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)EXTERN_C_END
1393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)