Ppmd7.c revision f955a79a9fffb09826cf7547f70d08c3798a2f50
1baa3858d3f5d128a5c8466b700098109edcad5f2repo sync/* Ppmd7.c -- PPMdH codec 2f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka2016-05-21 : Igor Pavlov : Public domain 3baa3858d3f5d128a5c8466b700098109edcad5f2repo syncThis code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ 4baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 5cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "Precomp.h" 6cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 7f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka#include <string.h> 8baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 9baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "Ppmd7.h" 10baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 11baa3858d3f5d128a5c8466b700098109edcad5f2repo syncconst Byte PPMD7_kExpEscape[16] = { 25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 }; 12baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const UInt16 kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051}; 13baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 14baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define MAX_FREQ 124 15baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define UNIT_SIZE 12 16baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 17baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define U2B(nu) ((UInt32)(nu) * UNIT_SIZE) 18baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define U2I(nu) (p->Units2Indx[(nu) - 1]) 19baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define I2U(indx) (p->Indx2Units[indx]) 20baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 21baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifdef PPMD_32BIT 22baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #define REF(ptr) (ptr) 23baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#else 24baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #define REF(ptr) ((UInt32)((Byte *)(ptr) - (p)->Base)) 25baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif 26baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 27baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define STATS_REF(ptr) ((CPpmd_State_Ref)REF(ptr)) 28baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 29baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define CTX(ref) ((CPpmd7_Context *)Ppmd7_GetContext(p, ref)) 30baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define STATS(ctx) Ppmd7_GetStats(p, ctx) 31baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define ONE_STATE(ctx) Ppmd7Context_OneState(ctx) 32baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define SUFFIX(ctx) CTX((ctx)->Suffix) 33baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 34baa3858d3f5d128a5c8466b700098109edcad5f2repo synctypedef CPpmd7_Context * CTX_PTR; 35baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 36baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstruct CPpmd7_Node_; 37baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 38baa3858d3f5d128a5c8466b700098109edcad5f2repo synctypedef 39baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifdef PPMD_32BIT 40baa3858d3f5d128a5c8466b700098109edcad5f2repo sync struct CPpmd7_Node_ * 41baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #else 42baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 43baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 44baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CPpmd7_Node_Ref; 45baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 46baa3858d3f5d128a5c8466b700098109edcad5f2repo synctypedef struct CPpmd7_Node_ 47baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 48baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt16 Stamp; /* must be at offset 0 as CPpmd7_Context::NumStats. Stamp=0 means free */ 49baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt16 NU; 50baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CPpmd7_Node_Ref Next; /* must be at offset >= 4 */ 51baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CPpmd7_Node_Ref Prev; 52baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} CPpmd7_Node; 53baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 54baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifdef PPMD_32BIT 55baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #define NODE(ptr) (ptr) 56baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#else 57baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #define NODE(offs) ((CPpmd7_Node *)(p->Base + (offs))) 58baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif 59baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 60baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid Ppmd7_Construct(CPpmd7 *p) 61baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 62baa3858d3f5d128a5c8466b700098109edcad5f2repo sync unsigned i, k, m; 63baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 64baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->Base = 0; 65baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 66baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++) 67baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 68baa3858d3f5d128a5c8466b700098109edcad5f2repo sync unsigned step = (i >= 12 ? 4 : (i >> 2) + 1); 69f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka do { p->Units2Indx[k++] = (Byte)i; } while (--step); 70baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->Indx2Units[i] = (Byte)k; 71baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 72baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 73baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->NS2BSIndx[0] = (0 << 1); 74baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->NS2BSIndx[1] = (1 << 1); 75baa3858d3f5d128a5c8466b700098109edcad5f2repo sync memset(p->NS2BSIndx + 2, (2 << 1), 9); 76baa3858d3f5d128a5c8466b700098109edcad5f2repo sync memset(p->NS2BSIndx + 11, (3 << 1), 256 - 11); 77baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 78baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < 3; i++) 79baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->NS2Indx[i] = (Byte)i; 80baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (m = i, k = 1; i < 256; i++) 81baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 82baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->NS2Indx[i] = (Byte)m; 83baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (--k == 0) 84baa3858d3f5d128a5c8466b700098109edcad5f2repo sync k = (++m) - 2; 85baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 86baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 87baa3858d3f5d128a5c8466b700098109edcad5f2repo sync memset(p->HB2Flag, 0, 0x40); 88baa3858d3f5d128a5c8466b700098109edcad5f2repo sync memset(p->HB2Flag + 0x40, 8, 0x100 - 0x40); 89baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 90baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 91baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid Ppmd7_Free(CPpmd7 *p, ISzAlloc *alloc) 92baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 93baa3858d3f5d128a5c8466b700098109edcad5f2repo sync alloc->Free(alloc, p->Base); 94baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->Size = 0; 95baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->Base = 0; 96baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 97baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 98baa3858d3f5d128a5c8466b700098109edcad5f2repo syncBool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc) 99baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 100baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (p->Base == 0 || p->Size != size) 101baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 102baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Ppmd7_Free(p, alloc); 103baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->AlignOffset = 104baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifdef PPMD_32BIT 105baa3858d3f5d128a5c8466b700098109edcad5f2repo sync (4 - size) & 3; 106baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #else 107baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 4 - (size & 3); 108baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 109baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if ((p->Base = (Byte *)alloc->Alloc(alloc, p->AlignOffset + size 110baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifndef PPMD_32BIT 111baa3858d3f5d128a5c8466b700098109edcad5f2repo sync + UNIT_SIZE 112baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 113baa3858d3f5d128a5c8466b700098109edcad5f2repo sync )) == 0) 114baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return False; 115baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->Size = size; 116baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 117baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return True; 118baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 119baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 120baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic void InsertNode(CPpmd7 *p, void *node, unsigned indx) 121baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 122baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *((CPpmd_Void_Ref *)node) = p->FreeList[indx]; 123baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->FreeList[indx] = REF(node); 124baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 125baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 126baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic void *RemoveNode(CPpmd7 *p, unsigned indx) 127baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 128baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CPpmd_Void_Ref *node = (CPpmd_Void_Ref *)Ppmd7_GetPtr(p, p->FreeList[indx]); 129baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->FreeList[indx] = *node; 130baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return node; 131baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 132baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 133baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic void SplitBlock(CPpmd7 *p, void *ptr, unsigned oldIndx, unsigned newIndx) 134baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 135baa3858d3f5d128a5c8466b700098109edcad5f2repo sync unsigned i, nu = I2U(oldIndx) - I2U(newIndx); 136baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ptr = (Byte *)ptr + U2B(I2U(newIndx)); 137baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (I2U(i = U2I(nu)) != nu) 138baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 139baa3858d3f5d128a5c8466b700098109edcad5f2repo sync unsigned k = I2U(--i); 140baa3858d3f5d128a5c8466b700098109edcad5f2repo sync InsertNode(p, ((Byte *)ptr) + U2B(k), nu - k - 1); 141baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 142baa3858d3f5d128a5c8466b700098109edcad5f2repo sync InsertNode(p, ptr, i); 143baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 144baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 145baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic void GlueFreeBlocks(CPpmd7 *p) 146baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 147baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifdef PPMD_32BIT 148baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CPpmd7_Node headItem; 149baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CPpmd7_Node_Ref head = &headItem; 150baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #else 151baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CPpmd7_Node_Ref head = p->AlignOffset + p->Size; 152baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 153baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 154baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CPpmd7_Node_Ref n = head; 155baa3858d3f5d128a5c8466b700098109edcad5f2repo sync unsigned i; 156baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 157baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->GlueCount = 255; 158baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 159baa3858d3f5d128a5c8466b700098109edcad5f2repo sync /* create doubly-linked list of free blocks */ 160baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < PPMD_NUM_INDEXES; i++) 161baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 162baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt16 nu = I2U(i); 163baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CPpmd7_Node_Ref next = (CPpmd7_Node_Ref)p->FreeList[i]; 164baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->FreeList[i] = 0; 165baa3858d3f5d128a5c8466b700098109edcad5f2repo sync while (next != 0) 166baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 167baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CPpmd7_Node *node = NODE(next); 168baa3858d3f5d128a5c8466b700098109edcad5f2repo sync node->Next = n; 169baa3858d3f5d128a5c8466b700098109edcad5f2repo sync n = NODE(n)->Prev = next; 170baa3858d3f5d128a5c8466b700098109edcad5f2repo sync next = *(const CPpmd7_Node_Ref *)node; 171baa3858d3f5d128a5c8466b700098109edcad5f2repo sync node->Stamp = 0; 172baa3858d3f5d128a5c8466b700098109edcad5f2repo sync node->NU = (UInt16)nu; 173baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 174baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 175baa3858d3f5d128a5c8466b700098109edcad5f2repo sync NODE(head)->Stamp = 1; 176baa3858d3f5d128a5c8466b700098109edcad5f2repo sync NODE(head)->Next = n; 177baa3858d3f5d128a5c8466b700098109edcad5f2repo sync NODE(n)->Prev = head; 178baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (p->LoUnit != p->HiUnit) 179baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ((CPpmd7_Node *)p->LoUnit)->Stamp = 1; 180baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 181baa3858d3f5d128a5c8466b700098109edcad5f2repo sync /* Glue free blocks */ 182baa3858d3f5d128a5c8466b700098109edcad5f2repo sync while (n != head) 183baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 184baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CPpmd7_Node *node = NODE(n); 185baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 nu = (UInt32)node->NU; 186baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (;;) 187baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 188baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CPpmd7_Node *node2 = NODE(n) + nu; 189baa3858d3f5d128a5c8466b700098109edcad5f2repo sync nu += node2->NU; 190baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (node2->Stamp != 0 || nu >= 0x10000) 191baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 192baa3858d3f5d128a5c8466b700098109edcad5f2repo sync NODE(node2->Prev)->Next = node2->Next; 193baa3858d3f5d128a5c8466b700098109edcad5f2repo sync NODE(node2->Next)->Prev = node2->Prev; 194baa3858d3f5d128a5c8466b700098109edcad5f2repo sync node->NU = (UInt16)nu; 195baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 196baa3858d3f5d128a5c8466b700098109edcad5f2repo sync n = node->Next; 197baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 198baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 199baa3858d3f5d128a5c8466b700098109edcad5f2repo sync /* Fill lists of free blocks */ 200baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (n = NODE(head)->Next; n != head;) 201baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 202baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CPpmd7_Node *node = NODE(n); 203baa3858d3f5d128a5c8466b700098109edcad5f2repo sync unsigned nu; 204baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CPpmd7_Node_Ref next = node->Next; 205baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (nu = node->NU; nu > 128; nu -= 128, node += 128) 206baa3858d3f5d128a5c8466b700098109edcad5f2repo sync InsertNode(p, node, PPMD_NUM_INDEXES - 1); 207baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (I2U(i = U2I(nu)) != nu) 208baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 209baa3858d3f5d128a5c8466b700098109edcad5f2repo sync unsigned k = I2U(--i); 210baa3858d3f5d128a5c8466b700098109edcad5f2repo sync InsertNode(p, node + k, nu - k - 1); 211baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 212baa3858d3f5d128a5c8466b700098109edcad5f2repo sync InsertNode(p, node, i); 213baa3858d3f5d128a5c8466b700098109edcad5f2repo sync n = next; 214baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 215baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 216baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 217baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic void *AllocUnitsRare(CPpmd7 *p, unsigned indx) 218baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 219baa3858d3f5d128a5c8466b700098109edcad5f2repo sync unsigned i; 220baa3858d3f5d128a5c8466b700098109edcad5f2repo sync void *retVal; 221baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (p->GlueCount == 0) 222baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 223baa3858d3f5d128a5c8466b700098109edcad5f2repo sync GlueFreeBlocks(p); 224baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (p->FreeList[indx] != 0) 225baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return RemoveNode(p, indx); 226baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 227baa3858d3f5d128a5c8466b700098109edcad5f2repo sync i = indx; 228baa3858d3f5d128a5c8466b700098109edcad5f2repo sync do 229baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 230baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (++i == PPMD_NUM_INDEXES) 231baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 232baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 numBytes = U2B(I2U(indx)); 233baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->GlueCount--; 234baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return ((UInt32)(p->UnitsStart - p->Text) > numBytes) ? (p->UnitsStart -= numBytes) : (NULL); 235baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 236baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 237baa3858d3f5d128a5c8466b700098109edcad5f2repo sync while (p->FreeList[i] == 0); 238baa3858d3f5d128a5c8466b700098109edcad5f2repo sync retVal = RemoveNode(p, i); 239baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SplitBlock(p, retVal, i, indx); 240baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return retVal; 241baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 242baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 243baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic void *AllocUnits(CPpmd7 *p, unsigned indx) 244baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 245baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 numBytes; 246baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (p->FreeList[indx] != 0) 247baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return RemoveNode(p, indx); 248baa3858d3f5d128a5c8466b700098109edcad5f2repo sync numBytes = U2B(I2U(indx)); 249baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (numBytes <= (UInt32)(p->HiUnit - p->LoUnit)) 250baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 251baa3858d3f5d128a5c8466b700098109edcad5f2repo sync void *retVal = p->LoUnit; 252baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->LoUnit += numBytes; 253baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return retVal; 254baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 255baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return AllocUnitsRare(p, indx); 256baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 257baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 258baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define MyMem12Cpy(dest, src, num) \ 259baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { UInt32 *d = (UInt32 *)dest; const UInt32 *s = (const UInt32 *)src; UInt32 n = num; \ 260f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka do { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; } while (--n); } 261baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 262baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic void *ShrinkUnits(CPpmd7 *p, void *oldPtr, unsigned oldNU, unsigned newNU) 263baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 264baa3858d3f5d128a5c8466b700098109edcad5f2repo sync unsigned i0 = U2I(oldNU); 265baa3858d3f5d128a5c8466b700098109edcad5f2repo sync unsigned i1 = U2I(newNU); 266baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (i0 == i1) 267baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return oldPtr; 268baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (p->FreeList[i1] != 0) 269baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 270baa3858d3f5d128a5c8466b700098109edcad5f2repo sync void *ptr = RemoveNode(p, i1); 271baa3858d3f5d128a5c8466b700098109edcad5f2repo sync MyMem12Cpy(ptr, oldPtr, newNU); 272baa3858d3f5d128a5c8466b700098109edcad5f2repo sync InsertNode(p, oldPtr, i0); 273baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return ptr; 274baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 275baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SplitBlock(p, oldPtr, i0, i1); 276baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return oldPtr; 277baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 278baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 279baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define SUCCESSOR(p) ((CPpmd_Void_Ref)((p)->SuccessorLow | ((UInt32)(p)->SuccessorHigh << 16))) 280baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 281baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic void SetSuccessor(CPpmd_State *p, CPpmd_Void_Ref v) 282baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 283baa3858d3f5d128a5c8466b700098109edcad5f2repo sync (p)->SuccessorLow = (UInt16)((UInt32)(v) & 0xFFFF); 284baa3858d3f5d128a5c8466b700098109edcad5f2repo sync (p)->SuccessorHigh = (UInt16)(((UInt32)(v) >> 16) & 0xFFFF); 285baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 286baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 287baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic void RestartModel(CPpmd7 *p) 288baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 289baa3858d3f5d128a5c8466b700098109edcad5f2repo sync unsigned i, k, m; 290baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 291baa3858d3f5d128a5c8466b700098109edcad5f2repo sync memset(p->FreeList, 0, sizeof(p->FreeList)); 292baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->Text = p->Base + p->AlignOffset; 293baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->HiUnit = p->Text + p->Size; 294baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->LoUnit = p->UnitsStart = p->HiUnit - p->Size / 8 / UNIT_SIZE * 7 * UNIT_SIZE; 295baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->GlueCount = 0; 296baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 297baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->OrderFall = p->MaxOrder; 298baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->RunLength = p->InitRL = -(Int32)((p->MaxOrder < 12) ? p->MaxOrder : 12) - 1; 299baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->PrevSuccess = 0; 300baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 301baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->MinContext = p->MaxContext = (CTX_PTR)(p->HiUnit -= UNIT_SIZE); /* AllocContext(p); */ 302baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->MinContext->Suffix = 0; 303baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->MinContext->NumStats = 256; 304baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->MinContext->SummFreq = 256 + 1; 305baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->FoundState = (CPpmd_State *)p->LoUnit; /* AllocUnits(p, PPMD_NUM_INDEXES - 1); */ 306baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->LoUnit += U2B(256 / 2); 307baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->MinContext->Stats = REF(p->FoundState); 308baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < 256; i++) 309baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 310baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CPpmd_State *s = &p->FoundState[i]; 311baa3858d3f5d128a5c8466b700098109edcad5f2repo sync s->Symbol = (Byte)i; 312baa3858d3f5d128a5c8466b700098109edcad5f2repo sync s->Freq = 1; 313baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SetSuccessor(s, 0); 314baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 315baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 316baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < 128; i++) 317baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (k = 0; k < 8; k++) 318baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 319baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt16 *dest = p->BinSumm[i] + k; 320baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt16 val = (UInt16)(PPMD_BIN_SCALE - kInitBinEsc[k] / (i + 2)); 321baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (m = 0; m < 64; m += 8) 322baa3858d3f5d128a5c8466b700098109edcad5f2repo sync dest[m] = val; 323baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 324baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 325baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < 25; i++) 326baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (k = 0; k < 16; k++) 327baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 328baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CPpmd_See *s = &p->See[i][k]; 329baa3858d3f5d128a5c8466b700098109edcad5f2repo sync s->Summ = (UInt16)((5 * i + 10) << (s->Shift = PPMD_PERIOD_BITS - 4)); 330baa3858d3f5d128a5c8466b700098109edcad5f2repo sync s->Count = 4; 331baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 332baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 333baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 334baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid Ppmd7_Init(CPpmd7 *p, unsigned maxOrder) 335baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 336baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->MaxOrder = maxOrder; 337baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RestartModel(p); 338baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->DummySee.Shift = PPMD_PERIOD_BITS; 339baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->DummySee.Summ = 0; /* unused */ 340baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->DummySee.Count = 64; /* unused */ 341baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 342baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 343baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic CTX_PTR CreateSuccessors(CPpmd7 *p, Bool skip) 344baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 345baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CPpmd_State upState; 346baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CTX_PTR c = p->MinContext; 347baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CPpmd_Byte_Ref upBranch = (CPpmd_Byte_Ref)SUCCESSOR(p->FoundState); 348baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CPpmd_State *ps[PPMD7_MAX_ORDER]; 349baa3858d3f5d128a5c8466b700098109edcad5f2repo sync unsigned numPs = 0; 350baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 351baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!skip) 352baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ps[numPs++] = p->FoundState; 353baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 354baa3858d3f5d128a5c8466b700098109edcad5f2repo sync while (c->Suffix) 355baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 356baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CPpmd_Void_Ref successor; 357baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CPpmd_State *s; 358baa3858d3f5d128a5c8466b700098109edcad5f2repo sync c = SUFFIX(c); 359baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (c->NumStats != 1) 360baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 361baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (s = STATS(c); s->Symbol != p->FoundState->Symbol; s++); 362baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 363baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 364baa3858d3f5d128a5c8466b700098109edcad5f2repo sync s = ONE_STATE(c); 365baa3858d3f5d128a5c8466b700098109edcad5f2repo sync successor = SUCCESSOR(s); 366baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (successor != upBranch) 367baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 368baa3858d3f5d128a5c8466b700098109edcad5f2repo sync c = CTX(successor); 369baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (numPs == 0) 370baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return c; 371baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 372baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 373baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ps[numPs++] = s; 374baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 375baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 376baa3858d3f5d128a5c8466b700098109edcad5f2repo sync upState.Symbol = *(const Byte *)Ppmd7_GetPtr(p, upBranch); 377baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SetSuccessor(&upState, upBranch + 1); 378baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 379baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (c->NumStats == 1) 380baa3858d3f5d128a5c8466b700098109edcad5f2repo sync upState.Freq = ONE_STATE(c)->Freq; 381baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 382baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 383baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 cf, s0; 384baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CPpmd_State *s; 385baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (s = STATS(c); s->Symbol != upState.Symbol; s++); 386baa3858d3f5d128a5c8466b700098109edcad5f2repo sync cf = s->Freq - 1; 387baa3858d3f5d128a5c8466b700098109edcad5f2repo sync s0 = c->SummFreq - c->NumStats - cf; 388baa3858d3f5d128a5c8466b700098109edcad5f2repo sync upState.Freq = (Byte)(1 + ((2 * cf <= s0) ? (5 * cf > s0) : ((2 * cf + 3 * s0 - 1) / (2 * s0)))); 389baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 390baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 391baa3858d3f5d128a5c8466b700098109edcad5f2repo sync do 392baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 393baa3858d3f5d128a5c8466b700098109edcad5f2repo sync /* Create Child */ 394baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CTX_PTR c1; /* = AllocContext(p); */ 395baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (p->HiUnit != p->LoUnit) 396baa3858d3f5d128a5c8466b700098109edcad5f2repo sync c1 = (CTX_PTR)(p->HiUnit -= UNIT_SIZE); 397baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else if (p->FreeList[0] != 0) 398baa3858d3f5d128a5c8466b700098109edcad5f2repo sync c1 = (CTX_PTR)RemoveNode(p, 0); 399baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 400baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 401baa3858d3f5d128a5c8466b700098109edcad5f2repo sync c1 = (CTX_PTR)AllocUnitsRare(p, 0); 402baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!c1) 403baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return NULL; 404baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 405baa3858d3f5d128a5c8466b700098109edcad5f2repo sync c1->NumStats = 1; 406baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *ONE_STATE(c1) = upState; 407baa3858d3f5d128a5c8466b700098109edcad5f2repo sync c1->Suffix = REF(c); 408baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SetSuccessor(ps[--numPs], REF(c1)); 409baa3858d3f5d128a5c8466b700098109edcad5f2repo sync c = c1; 410baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 411baa3858d3f5d128a5c8466b700098109edcad5f2repo sync while (numPs != 0); 412baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 413baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return c; 414baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 415baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 416baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic void SwapStates(CPpmd_State *t1, CPpmd_State *t2) 417baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 418baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CPpmd_State tmp = *t1; 419baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *t1 = *t2; 420baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *t2 = tmp; 421baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 422baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 423baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic void UpdateModel(CPpmd7 *p) 424baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 425baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CPpmd_Void_Ref successor, fSuccessor = SUCCESSOR(p->FoundState); 426baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CTX_PTR c; 427baa3858d3f5d128a5c8466b700098109edcad5f2repo sync unsigned s0, ns; 428baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 429baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (p->FoundState->Freq < MAX_FREQ / 4 && p->MinContext->Suffix != 0) 430baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 431baa3858d3f5d128a5c8466b700098109edcad5f2repo sync c = SUFFIX(p->MinContext); 432baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 433baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (c->NumStats == 1) 434baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 435baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CPpmd_State *s = ONE_STATE(c); 436baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (s->Freq < 32) 437baa3858d3f5d128a5c8466b700098109edcad5f2repo sync s->Freq++; 438baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 439baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 440baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 441baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CPpmd_State *s = STATS(c); 442baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (s->Symbol != p->FoundState->Symbol) 443baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 444baa3858d3f5d128a5c8466b700098109edcad5f2repo sync do { s++; } while (s->Symbol != p->FoundState->Symbol); 445baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (s[0].Freq >= s[-1].Freq) 446baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 447baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SwapStates(&s[0], &s[-1]); 448baa3858d3f5d128a5c8466b700098109edcad5f2repo sync s--; 449baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 450baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 451baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (s->Freq < MAX_FREQ - 9) 452baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 453baa3858d3f5d128a5c8466b700098109edcad5f2repo sync s->Freq += 2; 454baa3858d3f5d128a5c8466b700098109edcad5f2repo sync c->SummFreq += 2; 455baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 456baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 457baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 458baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 459baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (p->OrderFall == 0) 460baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 461baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->MinContext = p->MaxContext = CreateSuccessors(p, True); 462baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (p->MinContext == 0) 463baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 464baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RestartModel(p); 465baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return; 466baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 467baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SetSuccessor(p->FoundState, REF(p->MinContext)); 468baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return; 469baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 470baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 471baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *p->Text++ = p->FoundState->Symbol; 472baa3858d3f5d128a5c8466b700098109edcad5f2repo sync successor = REF(p->Text); 473baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (p->Text >= p->UnitsStart) 474baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 475baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RestartModel(p); 476baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return; 477baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 478baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 479baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (fSuccessor) 480baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 481baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (fSuccessor <= successor) 482baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 483baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CTX_PTR cs = CreateSuccessors(p, False); 484baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (cs == NULL) 485baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 486baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RestartModel(p); 487baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return; 488baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 489baa3858d3f5d128a5c8466b700098109edcad5f2repo sync fSuccessor = REF(cs); 490baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 491baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (--p->OrderFall == 0) 492baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 493baa3858d3f5d128a5c8466b700098109edcad5f2repo sync successor = fSuccessor; 494baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->Text -= (p->MaxContext != p->MinContext); 495baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 496baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 497baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 498baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 499baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SetSuccessor(p->FoundState, successor); 500baa3858d3f5d128a5c8466b700098109edcad5f2repo sync fSuccessor = REF(p->MinContext); 501baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 502baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 503baa3858d3f5d128a5c8466b700098109edcad5f2repo sync s0 = p->MinContext->SummFreq - (ns = p->MinContext->NumStats) - (p->FoundState->Freq - 1); 504baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 505baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (c = p->MaxContext; c != p->MinContext; c = SUFFIX(c)) 506baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 507baa3858d3f5d128a5c8466b700098109edcad5f2repo sync unsigned ns1; 508baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 cf, sf; 509baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if ((ns1 = c->NumStats) != 1) 510baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 511baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if ((ns1 & 1) == 0) 512baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 513baa3858d3f5d128a5c8466b700098109edcad5f2repo sync /* Expand for one UNIT */ 514baa3858d3f5d128a5c8466b700098109edcad5f2repo sync unsigned oldNU = ns1 >> 1; 515baa3858d3f5d128a5c8466b700098109edcad5f2repo sync unsigned i = U2I(oldNU); 516baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (i != U2I(oldNU + 1)) 517baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 518baa3858d3f5d128a5c8466b700098109edcad5f2repo sync void *ptr = AllocUnits(p, i + 1); 519baa3858d3f5d128a5c8466b700098109edcad5f2repo sync void *oldPtr; 520baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!ptr) 521baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 522baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RestartModel(p); 523baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return; 524baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 525baa3858d3f5d128a5c8466b700098109edcad5f2repo sync oldPtr = STATS(c); 526baa3858d3f5d128a5c8466b700098109edcad5f2repo sync MyMem12Cpy(ptr, oldPtr, oldNU); 527baa3858d3f5d128a5c8466b700098109edcad5f2repo sync InsertNode(p, oldPtr, i); 528baa3858d3f5d128a5c8466b700098109edcad5f2repo sync c->Stats = STATS_REF(ptr); 529baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 530baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 531baa3858d3f5d128a5c8466b700098109edcad5f2repo sync c->SummFreq = (UInt16)(c->SummFreq + (2 * ns1 < ns) + 2 * ((4 * ns1 <= ns) & (c->SummFreq <= 8 * ns1))); 532baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 533baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 534baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 535baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CPpmd_State *s = (CPpmd_State*)AllocUnits(p, 0); 536baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!s) 537baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 538baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RestartModel(p); 539baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return; 540baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 541baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *s = *ONE_STATE(c); 542baa3858d3f5d128a5c8466b700098109edcad5f2repo sync c->Stats = REF(s); 543baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (s->Freq < MAX_FREQ / 4 - 1) 544baa3858d3f5d128a5c8466b700098109edcad5f2repo sync s->Freq <<= 1; 545baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 546baa3858d3f5d128a5c8466b700098109edcad5f2repo sync s->Freq = MAX_FREQ - 4; 547baa3858d3f5d128a5c8466b700098109edcad5f2repo sync c->SummFreq = (UInt16)(s->Freq + p->InitEsc + (ns > 3)); 548baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 549baa3858d3f5d128a5c8466b700098109edcad5f2repo sync cf = 2 * (UInt32)p->FoundState->Freq * (c->SummFreq + 6); 550baa3858d3f5d128a5c8466b700098109edcad5f2repo sync sf = (UInt32)s0 + c->SummFreq; 551baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (cf < 6 * sf) 552baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 553baa3858d3f5d128a5c8466b700098109edcad5f2repo sync cf = 1 + (cf > sf) + (cf >= 4 * sf); 554baa3858d3f5d128a5c8466b700098109edcad5f2repo sync c->SummFreq += 3; 555baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 556baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 557baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 558baa3858d3f5d128a5c8466b700098109edcad5f2repo sync cf = 4 + (cf >= 9 * sf) + (cf >= 12 * sf) + (cf >= 15 * sf); 559baa3858d3f5d128a5c8466b700098109edcad5f2repo sync c->SummFreq = (UInt16)(c->SummFreq + cf); 560baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 561baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 562baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CPpmd_State *s = STATS(c) + ns1; 563baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SetSuccessor(s, successor); 564baa3858d3f5d128a5c8466b700098109edcad5f2repo sync s->Symbol = p->FoundState->Symbol; 565baa3858d3f5d128a5c8466b700098109edcad5f2repo sync s->Freq = (Byte)cf; 566baa3858d3f5d128a5c8466b700098109edcad5f2repo sync c->NumStats = (UInt16)(ns1 + 1); 567baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 568baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 569baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->MaxContext = p->MinContext = CTX(fSuccessor); 570baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 571baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 572baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic void Rescale(CPpmd7 *p) 573baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 574baa3858d3f5d128a5c8466b700098109edcad5f2repo sync unsigned i, adder, sumFreq, escFreq; 575baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CPpmd_State *stats = STATS(p->MinContext); 576baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CPpmd_State *s = p->FoundState; 577baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 578baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CPpmd_State tmp = *s; 579baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (; s != stats; s--) 580baa3858d3f5d128a5c8466b700098109edcad5f2repo sync s[0] = s[-1]; 581baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *s = tmp; 582baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 583baa3858d3f5d128a5c8466b700098109edcad5f2repo sync escFreq = p->MinContext->SummFreq - s->Freq; 584baa3858d3f5d128a5c8466b700098109edcad5f2repo sync s->Freq += 4; 585baa3858d3f5d128a5c8466b700098109edcad5f2repo sync adder = (p->OrderFall != 0); 586baa3858d3f5d128a5c8466b700098109edcad5f2repo sync s->Freq = (Byte)((s->Freq + adder) >> 1); 587baa3858d3f5d128a5c8466b700098109edcad5f2repo sync sumFreq = s->Freq; 588baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 589baa3858d3f5d128a5c8466b700098109edcad5f2repo sync i = p->MinContext->NumStats - 1; 590baa3858d3f5d128a5c8466b700098109edcad5f2repo sync do 591baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 592baa3858d3f5d128a5c8466b700098109edcad5f2repo sync escFreq -= (++s)->Freq; 593baa3858d3f5d128a5c8466b700098109edcad5f2repo sync s->Freq = (Byte)((s->Freq + adder) >> 1); 594baa3858d3f5d128a5c8466b700098109edcad5f2repo sync sumFreq += s->Freq; 595baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (s[0].Freq > s[-1].Freq) 596baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 597baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CPpmd_State *s1 = s; 598baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CPpmd_State tmp = *s1; 599baa3858d3f5d128a5c8466b700098109edcad5f2repo sync do 600baa3858d3f5d128a5c8466b700098109edcad5f2repo sync s1[0] = s1[-1]; 601baa3858d3f5d128a5c8466b700098109edcad5f2repo sync while (--s1 != stats && tmp.Freq > s1[-1].Freq); 602baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *s1 = tmp; 603baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 604baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 605baa3858d3f5d128a5c8466b700098109edcad5f2repo sync while (--i); 606baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 607baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (s->Freq == 0) 608baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 609baa3858d3f5d128a5c8466b700098109edcad5f2repo sync unsigned numStats = p->MinContext->NumStats; 610baa3858d3f5d128a5c8466b700098109edcad5f2repo sync unsigned n0, n1; 611baa3858d3f5d128a5c8466b700098109edcad5f2repo sync do { i++; } while ((--s)->Freq == 0); 612baa3858d3f5d128a5c8466b700098109edcad5f2repo sync escFreq += i; 613baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->MinContext->NumStats = (UInt16)(p->MinContext->NumStats - i); 614baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (p->MinContext->NumStats == 1) 615baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 616baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CPpmd_State tmp = *stats; 617baa3858d3f5d128a5c8466b700098109edcad5f2repo sync do 618baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 619baa3858d3f5d128a5c8466b700098109edcad5f2repo sync tmp.Freq = (Byte)(tmp.Freq - (tmp.Freq >> 1)); 620baa3858d3f5d128a5c8466b700098109edcad5f2repo sync escFreq >>= 1; 621baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 622baa3858d3f5d128a5c8466b700098109edcad5f2repo sync while (escFreq > 1); 623baa3858d3f5d128a5c8466b700098109edcad5f2repo sync InsertNode(p, stats, U2I(((numStats + 1) >> 1))); 624baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *(p->FoundState = ONE_STATE(p->MinContext)) = tmp; 625baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return; 626baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 627baa3858d3f5d128a5c8466b700098109edcad5f2repo sync n0 = (numStats + 1) >> 1; 628baa3858d3f5d128a5c8466b700098109edcad5f2repo sync n1 = (p->MinContext->NumStats + 1) >> 1; 629baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (n0 != n1) 630baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->MinContext->Stats = STATS_REF(ShrinkUnits(p, stats, n0, n1)); 631baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 632baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->MinContext->SummFreq = (UInt16)(sumFreq + escFreq - (escFreq >> 1)); 633baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->FoundState = STATS(p->MinContext); 634baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 635baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 636baa3858d3f5d128a5c8466b700098109edcad5f2repo syncCPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *escFreq) 637baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 638baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CPpmd_See *see; 639baa3858d3f5d128a5c8466b700098109edcad5f2repo sync unsigned nonMasked = p->MinContext->NumStats - numMasked; 640baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (p->MinContext->NumStats != 256) 641baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 642f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka see = p->See[(unsigned)p->NS2Indx[nonMasked - 1]] + 643baa3858d3f5d128a5c8466b700098109edcad5f2repo sync (nonMasked < (unsigned)SUFFIX(p->MinContext)->NumStats - p->MinContext->NumStats) + 644f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 2 * (unsigned)(p->MinContext->SummFreq < 11 * p->MinContext->NumStats) + 645f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 4 * (unsigned)(numMasked > nonMasked) + 646baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->HiBitsFlag; 647baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 648baa3858d3f5d128a5c8466b700098109edcad5f2repo sync unsigned r = (see->Summ >> see->Shift); 649baa3858d3f5d128a5c8466b700098109edcad5f2repo sync see->Summ = (UInt16)(see->Summ - r); 650baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *escFreq = r + (r == 0); 651baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 652baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 653baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 654baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 655baa3858d3f5d128a5c8466b700098109edcad5f2repo sync see = &p->DummySee; 656baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *escFreq = 1; 657baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 658baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return see; 659baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 660baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 661baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic void NextContext(CPpmd7 *p) 662baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 663baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CTX_PTR c = CTX(SUCCESSOR(p->FoundState)); 664baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (p->OrderFall == 0 && (Byte *)c > p->Text) 665baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->MinContext = p->MaxContext = c; 666baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 667baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UpdateModel(p); 668baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 669baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 670baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid Ppmd7_Update1(CPpmd7 *p) 671baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 672baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CPpmd_State *s = p->FoundState; 673baa3858d3f5d128a5c8466b700098109edcad5f2repo sync s->Freq += 4; 674baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->MinContext->SummFreq += 4; 675baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (s[0].Freq > s[-1].Freq) 676baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 677baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SwapStates(&s[0], &s[-1]); 678baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->FoundState = --s; 679baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (s->Freq > MAX_FREQ) 680baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Rescale(p); 681baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 682baa3858d3f5d128a5c8466b700098109edcad5f2repo sync NextContext(p); 683baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 684baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 685baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid Ppmd7_Update1_0(CPpmd7 *p) 686baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 687baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->PrevSuccess = (2 * p->FoundState->Freq > p->MinContext->SummFreq); 688baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->RunLength += p->PrevSuccess; 689baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->MinContext->SummFreq += 4; 690baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if ((p->FoundState->Freq += 4) > MAX_FREQ) 691baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Rescale(p); 692baa3858d3f5d128a5c8466b700098109edcad5f2repo sync NextContext(p); 693baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 694baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 695baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid Ppmd7_UpdateBin(CPpmd7 *p) 696baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 697baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->FoundState->Freq = (Byte)(p->FoundState->Freq + (p->FoundState->Freq < 128 ? 1: 0)); 698baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->PrevSuccess = 1; 699baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->RunLength++; 700baa3858d3f5d128a5c8466b700098109edcad5f2repo sync NextContext(p); 701baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 702baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 703baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid Ppmd7_Update2(CPpmd7 *p) 704baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 705baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->MinContext->SummFreq += 4; 706baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if ((p->FoundState->Freq += 4) > MAX_FREQ) 707baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Rescale(p); 708baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->RunLength = p->InitRL; 709baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UpdateModel(p); 710baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 711