archive_ppmd7.c 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168
  1. /* Ppmd7.c -- PPMdH codec
  2. 2010-03-12 : Igor Pavlov : Public domain
  3. This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
  4. #include "archive_platform.h"
  5. #include <memory.h>
  6. #include "archive_ppmd7_private.h"
  7. #ifdef PPMD_32BIT
  8. #define Ppmd7_GetPtr(p, ptr) (ptr)
  9. #define Ppmd7_GetContext(p, ptr) (ptr)
  10. #define Ppmd7_GetStats(p, ctx) ((ctx)->Stats)
  11. #else
  12. #define Ppmd7_GetPtr(p, offs) ((void *)((p)->Base + (offs)))
  13. #define Ppmd7_GetContext(p, offs) ((CPpmd7_Context *)Ppmd7_GetPtr((p), (offs)))
  14. #define Ppmd7_GetStats(p, ctx) ((CPpmd_State *)Ppmd7_GetPtr((p), ((ctx)->Stats)))
  15. #endif
  16. #define Ppmd7_GetBinSumm(p) \
  17. &p->BinSumm[Ppmd7Context_OneState(p->MinContext)->Freq - 1][p->PrevSuccess + \
  18. p->NS2BSIndx[Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] + \
  19. (p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]) + \
  20. 2 * p->HB2Flag[Ppmd7Context_OneState(p->MinContext)->Symbol] + \
  21. ((p->RunLength >> 26) & 0x20)]
  22. #define kTopValue (1 << 24)
  23. #define MAX_FREQ 124
  24. #define UNIT_SIZE 12
  25. #define U2B(nu) ((UInt32)(nu) * UNIT_SIZE)
  26. #define U2I(nu) (p->Units2Indx[(nu) - 1])
  27. #define I2U(indx) (p->Indx2Units[indx])
  28. #ifdef PPMD_32BIT
  29. #define REF(ptr) (ptr)
  30. #else
  31. #define REF(ptr) ((UInt32)((Byte *)(ptr) - (p)->Base))
  32. #endif
  33. #define STATS_REF(ptr) ((CPpmd_State_Ref)REF(ptr))
  34. #define CTX(ref) ((CPpmd7_Context *)Ppmd7_GetContext(p, ref))
  35. #define STATS(ctx) Ppmd7_GetStats(p, ctx)
  36. #define ONE_STATE(ctx) Ppmd7Context_OneState(ctx)
  37. #define SUFFIX(ctx) CTX((ctx)->Suffix)
  38. static const UInt16 kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051};
  39. static const Byte PPMD7_kExpEscape[16] = { 25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 };
  40. typedef CPpmd7_Context * CTX_PTR;
  41. struct CPpmd7_Node_;
  42. typedef
  43. #ifdef PPMD_32BIT
  44. struct CPpmd7_Node_ *
  45. #else
  46. UInt32
  47. #endif
  48. CPpmd7_Node_Ref;
  49. typedef struct CPpmd7_Node_
  50. {
  51. UInt16 Stamp; /* must be at offset 0 as CPpmd7_Context::NumStats. Stamp=0 means free */
  52. UInt16 NU;
  53. CPpmd7_Node_Ref Next; /* must be at offset >= 4 */
  54. CPpmd7_Node_Ref Prev;
  55. } CPpmd7_Node;
  56. #ifdef PPMD_32BIT
  57. #define NODE(ptr) (ptr)
  58. #else
  59. #define NODE(offs) ((CPpmd7_Node *)(p->Base + (offs)))
  60. #endif
  61. static void Ppmd7_Update1(CPpmd7 *p);
  62. static void Ppmd7_Update1_0(CPpmd7 *p);
  63. static void Ppmd7_Update2(CPpmd7 *p);
  64. static void Ppmd7_UpdateBin(CPpmd7 *p);
  65. static CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked,
  66. UInt32 *scale);
  67. /* ----------- Base ----------- */
  68. static void Ppmd7_Construct(CPpmd7 *p)
  69. {
  70. unsigned i, k, m;
  71. p->Base = 0;
  72. for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++)
  73. {
  74. unsigned step = (i >= 12 ? 4 : (i >> 2) + 1);
  75. do { p->Units2Indx[k++] = (Byte)i; } while(--step);
  76. p->Indx2Units[i] = (Byte)k;
  77. }
  78. p->NS2BSIndx[0] = (0 << 1);
  79. p->NS2BSIndx[1] = (1 << 1);
  80. memset(p->NS2BSIndx + 2, (2 << 1), 9);
  81. memset(p->NS2BSIndx + 11, (3 << 1), 256 - 11);
  82. for (i = 0; i < 3; i++)
  83. p->NS2Indx[i] = (Byte)i;
  84. for (m = i, k = 1; i < 256; i++)
  85. {
  86. p->NS2Indx[i] = (Byte)m;
  87. if (--k == 0)
  88. k = (++m) - 2;
  89. }
  90. memset(p->HB2Flag, 0, 0x40);
  91. memset(p->HB2Flag + 0x40, 8, 0x100 - 0x40);
  92. }
  93. static void Ppmd7_Free(CPpmd7 *p, ISzAlloc *alloc)
  94. {
  95. alloc->Free(alloc, p->Base);
  96. p->Size = 0;
  97. p->Base = 0;
  98. }
  99. static Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc)
  100. {
  101. if (p->Base == 0 || p->Size != size)
  102. {
  103. /* RestartModel() below assumes that p->Size >= UNIT_SIZE
  104. (see the calculation of m->MinContext). */
  105. if (size < UNIT_SIZE) {
  106. return False;
  107. }
  108. Ppmd7_Free(p, alloc);
  109. p->AlignOffset =
  110. #ifdef PPMD_32BIT
  111. (4 - size) & 3;
  112. #else
  113. 4 - (size & 3);
  114. #endif
  115. if ((p->Base = (Byte *)alloc->Alloc(alloc, p->AlignOffset + size
  116. #ifndef PPMD_32BIT
  117. + UNIT_SIZE
  118. #endif
  119. )) == 0)
  120. return False;
  121. p->Size = size;
  122. }
  123. return True;
  124. }
  125. static void InsertNode(CPpmd7 *p, void *node, unsigned indx)
  126. {
  127. *((CPpmd_Void_Ref *)node) = p->FreeList[indx];
  128. p->FreeList[indx] = REF(node);
  129. }
  130. static void *RemoveNode(CPpmd7 *p, unsigned indx)
  131. {
  132. CPpmd_Void_Ref *node = (CPpmd_Void_Ref *)Ppmd7_GetPtr(p, p->FreeList[indx]);
  133. p->FreeList[indx] = *node;
  134. return node;
  135. }
  136. static void SplitBlock(CPpmd7 *p, void *ptr, unsigned oldIndx, unsigned newIndx)
  137. {
  138. unsigned i, nu = I2U(oldIndx) - I2U(newIndx);
  139. ptr = (Byte *)ptr + U2B(I2U(newIndx));
  140. if (I2U(i = U2I(nu)) != nu)
  141. {
  142. unsigned k = I2U(--i);
  143. InsertNode(p, ((Byte *)ptr) + U2B(k), nu - k - 1);
  144. }
  145. InsertNode(p, ptr, i);
  146. }
  147. static void GlueFreeBlocks(CPpmd7 *p)
  148. {
  149. #ifdef PPMD_32BIT
  150. CPpmd7_Node headItem;
  151. CPpmd7_Node_Ref head = &headItem;
  152. #else
  153. CPpmd7_Node_Ref head = p->AlignOffset + p->Size;
  154. #endif
  155. CPpmd7_Node_Ref n = head;
  156. unsigned i;
  157. p->GlueCount = 255;
  158. /* create doubly-linked list of free blocks */
  159. for (i = 0; i < PPMD_NUM_INDEXES; i++)
  160. {
  161. UInt16 nu = I2U(i);
  162. CPpmd7_Node_Ref next = (CPpmd7_Node_Ref)p->FreeList[i];
  163. p->FreeList[i] = 0;
  164. while (next != 0)
  165. {
  166. CPpmd7_Node *node = NODE(next);
  167. node->Next = n;
  168. n = NODE(n)->Prev = next;
  169. next = *(const CPpmd7_Node_Ref *)node;
  170. node->Stamp = 0;
  171. node->NU = (UInt16)nu;
  172. }
  173. }
  174. NODE(head)->Stamp = 1;
  175. NODE(head)->Next = n;
  176. NODE(n)->Prev = head;
  177. if (p->LoUnit != p->HiUnit)
  178. ((CPpmd7_Node *)p->LoUnit)->Stamp = 1;
  179. /* Glue free blocks */
  180. while (n != head)
  181. {
  182. CPpmd7_Node *node = NODE(n);
  183. UInt32 nu = (UInt32)node->NU;
  184. for (;;)
  185. {
  186. CPpmd7_Node *node2 = NODE(n) + nu;
  187. nu += node2->NU;
  188. if (node2->Stamp != 0 || nu >= 0x10000)
  189. break;
  190. NODE(node2->Prev)->Next = node2->Next;
  191. NODE(node2->Next)->Prev = node2->Prev;
  192. node->NU = (UInt16)nu;
  193. }
  194. n = node->Next;
  195. }
  196. /* Fill lists of free blocks */
  197. for (n = NODE(head)->Next; n != head;)
  198. {
  199. CPpmd7_Node *node = NODE(n);
  200. unsigned nu;
  201. CPpmd7_Node_Ref next = node->Next;
  202. for (nu = node->NU; nu > 128; nu -= 128, node += 128)
  203. InsertNode(p, node, PPMD_NUM_INDEXES - 1);
  204. if (I2U(i = U2I(nu)) != nu)
  205. {
  206. unsigned k = I2U(--i);
  207. InsertNode(p, node + k, nu - k - 1);
  208. }
  209. InsertNode(p, node, i);
  210. n = next;
  211. }
  212. }
  213. static void *AllocUnitsRare(CPpmd7 *p, unsigned indx)
  214. {
  215. unsigned i;
  216. void *retVal;
  217. if (p->GlueCount == 0)
  218. {
  219. GlueFreeBlocks(p);
  220. if (p->FreeList[indx] != 0)
  221. return RemoveNode(p, indx);
  222. }
  223. i = indx;
  224. do
  225. {
  226. if (++i == PPMD_NUM_INDEXES)
  227. {
  228. UInt32 numBytes = U2B(I2U(indx));
  229. p->GlueCount--;
  230. return ((UInt32)(p->UnitsStart - p->Text) > numBytes) ? (p->UnitsStart -= numBytes) : (NULL);
  231. }
  232. }
  233. while (p->FreeList[i] == 0);
  234. retVal = RemoveNode(p, i);
  235. SplitBlock(p, retVal, i, indx);
  236. return retVal;
  237. }
  238. static void *AllocUnits(CPpmd7 *p, unsigned indx)
  239. {
  240. UInt32 numBytes;
  241. if (p->FreeList[indx] != 0)
  242. return RemoveNode(p, indx);
  243. numBytes = U2B(I2U(indx));
  244. if (numBytes <= (UInt32)(p->HiUnit - p->LoUnit))
  245. {
  246. void *retVal = p->LoUnit;
  247. p->LoUnit += numBytes;
  248. return retVal;
  249. }
  250. return AllocUnitsRare(p, indx);
  251. }
  252. #define MyMem12Cpy(dest, src, num) \
  253. { UInt32 *d = (UInt32 *)dest; const UInt32 *s = (const UInt32 *)src; UInt32 n = num; \
  254. do { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; } while(--n); }
  255. static void *ShrinkUnits(CPpmd7 *p, void *oldPtr, unsigned oldNU, unsigned newNU)
  256. {
  257. unsigned i0 = U2I(oldNU);
  258. unsigned i1 = U2I(newNU);
  259. if (i0 == i1)
  260. return oldPtr;
  261. if (p->FreeList[i1] != 0)
  262. {
  263. void *ptr = RemoveNode(p, i1);
  264. MyMem12Cpy(ptr, oldPtr, newNU);
  265. InsertNode(p, oldPtr, i0);
  266. return ptr;
  267. }
  268. SplitBlock(p, oldPtr, i0, i1);
  269. return oldPtr;
  270. }
  271. #define SUCCESSOR(p) ((CPpmd_Void_Ref)((p)->SuccessorLow | ((UInt32)(p)->SuccessorHigh << 16)))
  272. static void SetSuccessor(CPpmd_State *p, CPpmd_Void_Ref v)
  273. {
  274. (p)->SuccessorLow = (UInt16)((UInt32)(v) & 0xFFFF);
  275. (p)->SuccessorHigh = (UInt16)(((UInt32)(v) >> 16) & 0xFFFF);
  276. }
  277. static void RestartModel(CPpmd7 *p)
  278. {
  279. unsigned i, k, m;
  280. memset(p->FreeList, 0, sizeof(p->FreeList));
  281. p->Text = p->Base + p->AlignOffset;
  282. p->HiUnit = p->Text + p->Size;
  283. p->LoUnit = p->UnitsStart = p->HiUnit - p->Size / 8 / UNIT_SIZE * 7 * UNIT_SIZE;
  284. p->GlueCount = 0;
  285. p->OrderFall = p->MaxOrder;
  286. p->RunLength = p->InitRL = -(Int32)((p->MaxOrder < 12) ? p->MaxOrder : 12) - 1;
  287. p->PrevSuccess = 0;
  288. p->MinContext = p->MaxContext = (CTX_PTR)(p->HiUnit -= UNIT_SIZE); /* AllocContext(p); */
  289. p->MinContext->Suffix = 0;
  290. p->MinContext->NumStats = 256;
  291. p->MinContext->SummFreq = 256 + 1;
  292. p->FoundState = (CPpmd_State *)p->LoUnit; /* AllocUnits(p, PPMD_NUM_INDEXES - 1); */
  293. p->LoUnit += U2B(256 / 2);
  294. p->MinContext->Stats = REF(p->FoundState);
  295. for (i = 0; i < 256; i++)
  296. {
  297. CPpmd_State *s = &p->FoundState[i];
  298. s->Symbol = (Byte)i;
  299. s->Freq = 1;
  300. SetSuccessor(s, 0);
  301. }
  302. for (i = 0; i < 128; i++)
  303. for (k = 0; k < 8; k++)
  304. {
  305. UInt16 *dest = p->BinSumm[i] + k;
  306. UInt16 val = (UInt16)(PPMD_BIN_SCALE - kInitBinEsc[k] / (i + 2));
  307. for (m = 0; m < 64; m += 8)
  308. dest[m] = val;
  309. }
  310. for (i = 0; i < 25; i++)
  311. for (k = 0; k < 16; k++)
  312. {
  313. CPpmd_See *s = &p->See[i][k];
  314. s->Summ = (UInt16)((5 * i + 10) << (s->Shift = PPMD_PERIOD_BITS - 4));
  315. s->Count = 4;
  316. }
  317. }
  318. static void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder)
  319. {
  320. p->MaxOrder = maxOrder;
  321. RestartModel(p);
  322. p->DummySee.Shift = PPMD_PERIOD_BITS;
  323. p->DummySee.Summ = 0; /* unused */
  324. p->DummySee.Count = 64; /* unused */
  325. }
  326. static CTX_PTR CreateSuccessors(CPpmd7 *p, Bool skip)
  327. {
  328. CPpmd_State upState;
  329. CTX_PTR c = p->MinContext;
  330. CPpmd_Byte_Ref upBranch = (CPpmd_Byte_Ref)SUCCESSOR(p->FoundState);
  331. CPpmd_State *ps[PPMD7_MAX_ORDER];
  332. unsigned numPs = 0;
  333. if (!skip)
  334. ps[numPs++] = p->FoundState;
  335. while (c->Suffix)
  336. {
  337. CPpmd_Void_Ref successor;
  338. CPpmd_State *s;
  339. c = SUFFIX(c);
  340. if (c->NumStats != 1)
  341. {
  342. for (s = STATS(c); s->Symbol != p->FoundState->Symbol; s++);
  343. }
  344. else
  345. s = ONE_STATE(c);
  346. successor = SUCCESSOR(s);
  347. if (successor != upBranch)
  348. {
  349. c = CTX(successor);
  350. if (numPs == 0)
  351. return c;
  352. break;
  353. }
  354. ps[numPs++] = s;
  355. }
  356. upState.Symbol = *(const Byte *)Ppmd7_GetPtr(p, upBranch);
  357. SetSuccessor(&upState, upBranch + 1);
  358. if (c->NumStats == 1)
  359. upState.Freq = ONE_STATE(c)->Freq;
  360. else
  361. {
  362. UInt32 cf, s0;
  363. CPpmd_State *s;
  364. for (s = STATS(c); s->Symbol != upState.Symbol; s++);
  365. cf = s->Freq - 1;
  366. s0 = c->SummFreq - c->NumStats - cf;
  367. upState.Freq = (Byte)(1 + ((2 * cf <= s0) ? (5 * cf > s0) : ((2 * cf + 3 * s0 - 1) / (2 * s0))));
  368. }
  369. while (numPs != 0)
  370. {
  371. /* Create Child */
  372. CTX_PTR c1; /* = AllocContext(p); */
  373. if (p->HiUnit != p->LoUnit)
  374. c1 = (CTX_PTR)(p->HiUnit -= UNIT_SIZE);
  375. else if (p->FreeList[0] != 0)
  376. c1 = (CTX_PTR)RemoveNode(p, 0);
  377. else
  378. {
  379. c1 = (CTX_PTR)AllocUnitsRare(p, 0);
  380. if (!c1)
  381. return NULL;
  382. }
  383. c1->NumStats = 1;
  384. *ONE_STATE(c1) = upState;
  385. c1->Suffix = REF(c);
  386. SetSuccessor(ps[--numPs], REF(c1));
  387. c = c1;
  388. }
  389. return c;
  390. }
  391. static void SwapStates(CPpmd_State *t1, CPpmd_State *t2)
  392. {
  393. CPpmd_State tmp = *t1;
  394. *t1 = *t2;
  395. *t2 = tmp;
  396. }
  397. static void UpdateModel(CPpmd7 *p)
  398. {
  399. CPpmd_Void_Ref successor, fSuccessor = SUCCESSOR(p->FoundState);
  400. CTX_PTR c;
  401. unsigned s0, ns;
  402. if (p->FoundState->Freq < MAX_FREQ / 4 && p->MinContext->Suffix != 0)
  403. {
  404. c = SUFFIX(p->MinContext);
  405. if (c->NumStats == 1)
  406. {
  407. CPpmd_State *s = ONE_STATE(c);
  408. if (s->Freq < 32)
  409. s->Freq++;
  410. }
  411. else
  412. {
  413. CPpmd_State *s = STATS(c);
  414. if (s->Symbol != p->FoundState->Symbol)
  415. {
  416. do { s++; } while (s->Symbol != p->FoundState->Symbol);
  417. if (s[0].Freq >= s[-1].Freq)
  418. {
  419. SwapStates(&s[0], &s[-1]);
  420. s--;
  421. }
  422. }
  423. if (s->Freq < MAX_FREQ - 9)
  424. {
  425. s->Freq += 2;
  426. c->SummFreq += 2;
  427. }
  428. }
  429. }
  430. if (p->OrderFall == 0)
  431. {
  432. p->MinContext = p->MaxContext = CreateSuccessors(p, True);
  433. if (p->MinContext == 0)
  434. {
  435. RestartModel(p);
  436. return;
  437. }
  438. SetSuccessor(p->FoundState, REF(p->MinContext));
  439. return;
  440. }
  441. *p->Text++ = p->FoundState->Symbol;
  442. successor = REF(p->Text);
  443. if (p->Text >= p->UnitsStart)
  444. {
  445. RestartModel(p);
  446. return;
  447. }
  448. if (fSuccessor)
  449. {
  450. if (fSuccessor <= successor)
  451. {
  452. CTX_PTR cs = CreateSuccessors(p, False);
  453. if (cs == NULL)
  454. {
  455. RestartModel(p);
  456. return;
  457. }
  458. fSuccessor = REF(cs);
  459. }
  460. if (--p->OrderFall == 0)
  461. {
  462. successor = fSuccessor;
  463. p->Text -= (p->MaxContext != p->MinContext);
  464. }
  465. }
  466. else
  467. {
  468. SetSuccessor(p->FoundState, successor);
  469. fSuccessor = REF(p->MinContext);
  470. }
  471. s0 = p->MinContext->SummFreq - (ns = p->MinContext->NumStats) - (p->FoundState->Freq - 1);
  472. for (c = p->MaxContext; c != p->MinContext; c = SUFFIX(c))
  473. {
  474. unsigned ns1;
  475. UInt32 cf, sf;
  476. if ((ns1 = c->NumStats) != 1)
  477. {
  478. if ((ns1 & 1) == 0)
  479. {
  480. /* Expand for one UNIT */
  481. unsigned oldNU = ns1 >> 1;
  482. unsigned i = U2I(oldNU);
  483. if (i != U2I(oldNU + 1))
  484. {
  485. void *ptr = AllocUnits(p, i + 1);
  486. void *oldPtr;
  487. if (!ptr)
  488. {
  489. RestartModel(p);
  490. return;
  491. }
  492. oldPtr = STATS(c);
  493. MyMem12Cpy(ptr, oldPtr, oldNU);
  494. InsertNode(p, oldPtr, i);
  495. c->Stats = STATS_REF(ptr);
  496. }
  497. }
  498. c->SummFreq = (UInt16)(c->SummFreq + (2 * ns1 < ns) + 2 * ((4 * ns1 <= ns) & (c->SummFreq <= 8 * ns1)));
  499. }
  500. else
  501. {
  502. CPpmd_State *s = (CPpmd_State*)AllocUnits(p, 0);
  503. if (!s)
  504. {
  505. RestartModel(p);
  506. return;
  507. }
  508. *s = *ONE_STATE(c);
  509. c->Stats = REF(s);
  510. if (s->Freq < MAX_FREQ / 4 - 1)
  511. s->Freq <<= 1;
  512. else
  513. s->Freq = MAX_FREQ - 4;
  514. c->SummFreq = (UInt16)(s->Freq + p->InitEsc + (ns > 3));
  515. }
  516. cf = 2 * (UInt32)p->FoundState->Freq * (c->SummFreq + 6);
  517. sf = (UInt32)s0 + c->SummFreq;
  518. if (cf < 6 * sf)
  519. {
  520. cf = 1 + (cf > sf) + (cf >= 4 * sf);
  521. c->SummFreq += 3;
  522. }
  523. else
  524. {
  525. cf = 4 + (cf >= 9 * sf) + (cf >= 12 * sf) + (cf >= 15 * sf);
  526. c->SummFreq = (UInt16)(c->SummFreq + cf);
  527. }
  528. {
  529. CPpmd_State *s = STATS(c) + ns1;
  530. SetSuccessor(s, successor);
  531. s->Symbol = p->FoundState->Symbol;
  532. s->Freq = (Byte)cf;
  533. c->NumStats = (UInt16)(ns1 + 1);
  534. }
  535. }
  536. p->MaxContext = p->MinContext = CTX(fSuccessor);
  537. }
  538. static void Rescale(CPpmd7 *p)
  539. {
  540. unsigned i, adder, sumFreq, escFreq;
  541. CPpmd_State *stats = STATS(p->MinContext);
  542. CPpmd_State *s = p->FoundState;
  543. {
  544. CPpmd_State tmp = *s;
  545. for (; s != stats; s--)
  546. s[0] = s[-1];
  547. *s = tmp;
  548. }
  549. escFreq = p->MinContext->SummFreq - s->Freq;
  550. s->Freq += 4;
  551. adder = (p->OrderFall != 0);
  552. s->Freq = (Byte)((s->Freq + adder) >> 1);
  553. sumFreq = s->Freq;
  554. i = p->MinContext->NumStats - 1;
  555. do
  556. {
  557. escFreq -= (++s)->Freq;
  558. s->Freq = (Byte)((s->Freq + adder) >> 1);
  559. sumFreq += s->Freq;
  560. if (s[0].Freq > s[-1].Freq)
  561. {
  562. CPpmd_State *s1 = s;
  563. CPpmd_State tmp = *s1;
  564. do
  565. s1[0] = s1[-1];
  566. while (--s1 != stats && tmp.Freq > s1[-1].Freq);
  567. *s1 = tmp;
  568. }
  569. }
  570. while (--i);
  571. if (s->Freq == 0)
  572. {
  573. unsigned numStats = p->MinContext->NumStats;
  574. unsigned n0, n1;
  575. do { i++; } while ((--s)->Freq == 0);
  576. escFreq += i;
  577. p->MinContext->NumStats = (UInt16)(p->MinContext->NumStats - i);
  578. if (p->MinContext->NumStats == 1)
  579. {
  580. CPpmd_State tmp = *stats;
  581. do
  582. {
  583. tmp.Freq = (Byte)(tmp.Freq - (tmp.Freq >> 1));
  584. escFreq >>= 1;
  585. }
  586. while (escFreq > 1);
  587. InsertNode(p, stats, U2I(((numStats + 1) >> 1)));
  588. *(p->FoundState = ONE_STATE(p->MinContext)) = tmp;
  589. return;
  590. }
  591. n0 = (numStats + 1) >> 1;
  592. n1 = (p->MinContext->NumStats + 1) >> 1;
  593. if (n0 != n1)
  594. p->MinContext->Stats = STATS_REF(ShrinkUnits(p, stats, n0, n1));
  595. }
  596. p->MinContext->SummFreq = (UInt16)(sumFreq + escFreq - (escFreq >> 1));
  597. p->FoundState = STATS(p->MinContext);
  598. }
  599. static CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *escFreq)
  600. {
  601. CPpmd_See *see;
  602. unsigned nonMasked = p->MinContext->NumStats - numMasked;
  603. if (p->MinContext->NumStats != 256)
  604. {
  605. see = p->See[p->NS2Indx[nonMasked - 1]] +
  606. (nonMasked < (unsigned)SUFFIX(p->MinContext)->NumStats - p->MinContext->NumStats) +
  607. 2 * (p->MinContext->SummFreq < 11 * p->MinContext->NumStats) +
  608. 4 * (numMasked > nonMasked) +
  609. p->HiBitsFlag;
  610. {
  611. unsigned r = (see->Summ >> see->Shift);
  612. see->Summ = (UInt16)(see->Summ - r);
  613. *escFreq = r + (r == 0);
  614. }
  615. }
  616. else
  617. {
  618. see = &p->DummySee;
  619. *escFreq = 1;
  620. }
  621. return see;
  622. }
  623. static void NextContext(CPpmd7 *p)
  624. {
  625. CTX_PTR c = CTX(SUCCESSOR(p->FoundState));
  626. if (p->OrderFall == 0 && (Byte *)c > p->Text)
  627. p->MinContext = p->MaxContext = c;
  628. else
  629. UpdateModel(p);
  630. }
  631. static void Ppmd7_Update1(CPpmd7 *p)
  632. {
  633. CPpmd_State *s = p->FoundState;
  634. s->Freq += 4;
  635. p->MinContext->SummFreq += 4;
  636. if (s[0].Freq > s[-1].Freq)
  637. {
  638. SwapStates(&s[0], &s[-1]);
  639. p->FoundState = --s;
  640. if (s->Freq > MAX_FREQ)
  641. Rescale(p);
  642. }
  643. NextContext(p);
  644. }
  645. static void Ppmd7_Update1_0(CPpmd7 *p)
  646. {
  647. p->PrevSuccess = (2 * p->FoundState->Freq > p->MinContext->SummFreq);
  648. p->RunLength += p->PrevSuccess;
  649. p->MinContext->SummFreq += 4;
  650. if ((p->FoundState->Freq += 4) > MAX_FREQ)
  651. Rescale(p);
  652. NextContext(p);
  653. }
  654. static void Ppmd7_UpdateBin(CPpmd7 *p)
  655. {
  656. p->FoundState->Freq = (Byte)(p->FoundState->Freq + (p->FoundState->Freq < 128 ? 1: 0));
  657. p->PrevSuccess = 1;
  658. p->RunLength++;
  659. NextContext(p);
  660. }
  661. static void Ppmd7_Update2(CPpmd7 *p)
  662. {
  663. p->MinContext->SummFreq += 4;
  664. if ((p->FoundState->Freq += 4) > MAX_FREQ)
  665. Rescale(p);
  666. p->RunLength = p->InitRL;
  667. UpdateModel(p);
  668. }
  669. /* ---------- Decode ---------- */
  670. static Bool Ppmd_RangeDec_Init(CPpmd7z_RangeDec *p)
  671. {
  672. unsigned i;
  673. p->Low = p->Bottom = 0;
  674. p->Range = 0xFFFFFFFF;
  675. for (i = 0; i < 4; i++)
  676. p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
  677. return (p->Code < 0xFFFFFFFF);
  678. }
  679. static Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p)
  680. {
  681. if (p->Stream->Read((void *)p->Stream) != 0)
  682. return False;
  683. return Ppmd_RangeDec_Init(p);
  684. }
  685. static Bool PpmdRAR_RangeDec_Init(CPpmd7z_RangeDec *p)
  686. {
  687. if (!Ppmd_RangeDec_Init(p))
  688. return False;
  689. p->Bottom = 0x8000;
  690. return True;
  691. }
  692. static UInt32 Range_GetThreshold(void *pp, UInt32 total)
  693. {
  694. CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
  695. return (p->Code - p->Low) / (p->Range /= total);
  696. }
  697. static void Range_Normalize(CPpmd7z_RangeDec *p)
  698. {
  699. while (1)
  700. {
  701. if((p->Low ^ (p->Low + p->Range)) >= kTopValue)
  702. {
  703. if(p->Range >= p->Bottom)
  704. break;
  705. else
  706. p->Range = ((uint32_t)(-(int32_t)p->Low)) & (p->Bottom - 1);
  707. }
  708. p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
  709. p->Range <<= 8;
  710. p->Low <<= 8;
  711. }
  712. }
  713. static void Range_Decode_7z(void *pp, UInt32 start, UInt32 size)
  714. {
  715. CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
  716. p->Code -= start * p->Range;
  717. p->Range *= size;
  718. Range_Normalize(p);
  719. }
  720. static void Range_Decode_RAR(void *pp, UInt32 start, UInt32 size)
  721. {
  722. CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
  723. p->Low += start * p->Range;
  724. p->Range *= size;
  725. Range_Normalize(p);
  726. }
  727. static UInt32 Range_DecodeBit_7z(void *pp, UInt32 size0)
  728. {
  729. CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
  730. UInt32 newBound = (p->Range >> 14) * size0;
  731. UInt32 symbol;
  732. if (p->Code < newBound)
  733. {
  734. symbol = 0;
  735. p->Range = newBound;
  736. }
  737. else
  738. {
  739. symbol = 1;
  740. p->Code -= newBound;
  741. p->Range -= newBound;
  742. }
  743. Range_Normalize(p);
  744. return symbol;
  745. }
  746. static UInt32 Range_DecodeBit_RAR(void *pp, UInt32 size0)
  747. {
  748. CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
  749. UInt32 bit, value = p->p.GetThreshold(p, PPMD_BIN_SCALE);
  750. if(value < size0)
  751. {
  752. bit = 0;
  753. p->p.Decode(p, 0, size0);
  754. }
  755. else
  756. {
  757. bit = 1;
  758. p->p.Decode(p, size0, PPMD_BIN_SCALE - size0);
  759. }
  760. return bit;
  761. }
  762. static void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p)
  763. {
  764. p->p.GetThreshold = Range_GetThreshold;
  765. p->p.Decode = Range_Decode_7z;
  766. p->p.DecodeBit = Range_DecodeBit_7z;
  767. }
  768. static void PpmdRAR_RangeDec_CreateVTable(CPpmd7z_RangeDec *p)
  769. {
  770. p->p.GetThreshold = Range_GetThreshold;
  771. p->p.Decode = Range_Decode_RAR;
  772. p->p.DecodeBit = Range_DecodeBit_RAR;
  773. }
  774. #define MASK(sym) ((signed char *)charMask)[sym]
  775. static int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc)
  776. {
  777. size_t charMask[256 / sizeof(size_t)];
  778. if (p->MinContext->NumStats != 1)
  779. {
  780. CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext);
  781. unsigned i;
  782. UInt32 count, hiCnt;
  783. if ((count = rc->GetThreshold(rc, p->MinContext->SummFreq)) < (hiCnt = s->Freq))
  784. {
  785. Byte symbol;
  786. rc->Decode(rc, 0, s->Freq);
  787. p->FoundState = s;
  788. symbol = s->Symbol;
  789. Ppmd7_Update1_0(p);
  790. return symbol;
  791. }
  792. p->PrevSuccess = 0;
  793. i = p->MinContext->NumStats - 1;
  794. do
  795. {
  796. if ((hiCnt += (++s)->Freq) > count)
  797. {
  798. Byte symbol;
  799. rc->Decode(rc, hiCnt - s->Freq, s->Freq);
  800. p->FoundState = s;
  801. symbol = s->Symbol;
  802. Ppmd7_Update1(p);
  803. return symbol;
  804. }
  805. }
  806. while (--i);
  807. if (count >= p->MinContext->SummFreq)
  808. return -2;
  809. p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol];
  810. rc->Decode(rc, hiCnt, p->MinContext->SummFreq - hiCnt);
  811. PPMD_SetAllBitsIn256Bytes(charMask);
  812. MASK(s->Symbol) = 0;
  813. i = p->MinContext->NumStats - 1;
  814. do { MASK((--s)->Symbol) = 0; } while (--i);
  815. }
  816. else
  817. {
  818. UInt16 *prob = Ppmd7_GetBinSumm(p);
  819. if (rc->DecodeBit(rc, *prob) == 0)
  820. {
  821. Byte symbol;
  822. *prob = (UInt16)PPMD_UPDATE_PROB_0(*prob);
  823. symbol = (p->FoundState = Ppmd7Context_OneState(p->MinContext))->Symbol;
  824. Ppmd7_UpdateBin(p);
  825. return symbol;
  826. }
  827. *prob = (UInt16)PPMD_UPDATE_PROB_1(*prob);
  828. p->InitEsc = PPMD7_kExpEscape[*prob >> 10];
  829. PPMD_SetAllBitsIn256Bytes(charMask);
  830. MASK(Ppmd7Context_OneState(p->MinContext)->Symbol) = 0;
  831. p->PrevSuccess = 0;
  832. }
  833. for (;;)
  834. {
  835. CPpmd_State *ps[256], *s;
  836. UInt32 freqSum, count, hiCnt;
  837. CPpmd_See *see;
  838. unsigned i, num, numMasked = p->MinContext->NumStats;
  839. do
  840. {
  841. p->OrderFall++;
  842. if (!p->MinContext->Suffix)
  843. return -1;
  844. p->MinContext = Ppmd7_GetContext(p, p->MinContext->Suffix);
  845. }
  846. while (p->MinContext->NumStats == numMasked);
  847. hiCnt = 0;
  848. s = Ppmd7_GetStats(p, p->MinContext);
  849. i = 0;
  850. num = p->MinContext->NumStats - numMasked;
  851. do
  852. {
  853. int k = (int)(MASK(s->Symbol));
  854. hiCnt += (s->Freq & k);
  855. ps[i] = s++;
  856. i -= k;
  857. }
  858. while (i != num);
  859. see = Ppmd7_MakeEscFreq(p, numMasked, &freqSum);
  860. freqSum += hiCnt;
  861. count = rc->GetThreshold(rc, freqSum);
  862. if (count < hiCnt)
  863. {
  864. Byte symbol;
  865. CPpmd_State **pps = ps;
  866. for (hiCnt = 0; (hiCnt += (*pps)->Freq) <= count; pps++);
  867. s = *pps;
  868. rc->Decode(rc, hiCnt - s->Freq, s->Freq);
  869. Ppmd_See_Update(see);
  870. p->FoundState = s;
  871. symbol = s->Symbol;
  872. Ppmd7_Update2(p);
  873. return symbol;
  874. }
  875. if (count >= freqSum)
  876. return -2;
  877. rc->Decode(rc, hiCnt, freqSum - hiCnt);
  878. see->Summ = (UInt16)(see->Summ + freqSum);
  879. do { MASK(ps[--i]->Symbol) = 0; } while (i != 0);
  880. }
  881. }
  882. /* ---------- Encode ---------- Ppmd7Enc.c */
  883. #define kTopValue (1 << 24)
  884. static void Ppmd7z_RangeEnc_Init(CPpmd7z_RangeEnc *p)
  885. {
  886. p->Low = 0;
  887. p->Range = 0xFFFFFFFF;
  888. p->Cache = 0;
  889. p->CacheSize = 1;
  890. }
  891. static void RangeEnc_ShiftLow(CPpmd7z_RangeEnc *p)
  892. {
  893. if ((UInt32)p->Low < (UInt32)0xFF000000 || (unsigned)(p->Low >> 32) != 0)
  894. {
  895. Byte temp = p->Cache;
  896. do
  897. {
  898. p->Stream->Write(p->Stream, (Byte)(temp + (Byte)(p->Low >> 32)));
  899. temp = 0xFF;
  900. }
  901. while(--p->CacheSize != 0);
  902. p->Cache = (Byte)((UInt32)p->Low >> 24);
  903. }
  904. p->CacheSize++;
  905. p->Low = ((UInt32)p->Low << 8) & 0xFFFFFFFF;
  906. }
  907. static void RangeEnc_Encode(CPpmd7z_RangeEnc *p, UInt32 start, UInt32 size, UInt32 total)
  908. {
  909. p->Low += start * (p->Range /= total);
  910. p->Range *= size;
  911. while (p->Range < kTopValue)
  912. {
  913. p->Range <<= 8;
  914. RangeEnc_ShiftLow(p);
  915. }
  916. }
  917. static void RangeEnc_EncodeBit_0(CPpmd7z_RangeEnc *p, UInt32 size0)
  918. {
  919. p->Range = (p->Range >> 14) * size0;
  920. while (p->Range < kTopValue)
  921. {
  922. p->Range <<= 8;
  923. RangeEnc_ShiftLow(p);
  924. }
  925. }
  926. static void RangeEnc_EncodeBit_1(CPpmd7z_RangeEnc *p, UInt32 size0)
  927. {
  928. UInt32 newBound = (p->Range >> 14) * size0;
  929. p->Low += newBound;
  930. p->Range -= newBound;
  931. while (p->Range < kTopValue)
  932. {
  933. p->Range <<= 8;
  934. RangeEnc_ShiftLow(p);
  935. }
  936. }
  937. static void Ppmd7z_RangeEnc_FlushData(CPpmd7z_RangeEnc *p)
  938. {
  939. unsigned i;
  940. for (i = 0; i < 5; i++)
  941. RangeEnc_ShiftLow(p);
  942. }
  943. #define MASK(sym) ((signed char *)charMask)[sym]
  944. static void Ppmd7_EncodeSymbol(CPpmd7 *p, CPpmd7z_RangeEnc *rc, int symbol)
  945. {
  946. size_t charMask[256 / sizeof(size_t)];
  947. if (p->MinContext->NumStats != 1)
  948. {
  949. CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext);
  950. UInt32 sum;
  951. unsigned i;
  952. if (s->Symbol == symbol)
  953. {
  954. RangeEnc_Encode(rc, 0, s->Freq, p->MinContext->SummFreq);
  955. p->FoundState = s;
  956. Ppmd7_Update1_0(p);
  957. return;
  958. }
  959. p->PrevSuccess = 0;
  960. sum = s->Freq;
  961. i = p->MinContext->NumStats - 1;
  962. do
  963. {
  964. if ((++s)->Symbol == symbol)
  965. {
  966. RangeEnc_Encode(rc, sum, s->Freq, p->MinContext->SummFreq);
  967. p->FoundState = s;
  968. Ppmd7_Update1(p);
  969. return;
  970. }
  971. sum += s->Freq;
  972. }
  973. while (--i);
  974. p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol];
  975. PPMD_SetAllBitsIn256Bytes(charMask);
  976. MASK(s->Symbol) = 0;
  977. i = p->MinContext->NumStats - 1;
  978. do { MASK((--s)->Symbol) = 0; } while (--i);
  979. RangeEnc_Encode(rc, sum, p->MinContext->SummFreq - sum, p->MinContext->SummFreq);
  980. }
  981. else
  982. {
  983. UInt16 *prob = Ppmd7_GetBinSumm(p);
  984. CPpmd_State *s = Ppmd7Context_OneState(p->MinContext);
  985. if (s->Symbol == symbol)
  986. {
  987. RangeEnc_EncodeBit_0(rc, *prob);
  988. *prob = (UInt16)PPMD_UPDATE_PROB_0(*prob);
  989. p->FoundState = s;
  990. Ppmd7_UpdateBin(p);
  991. return;
  992. }
  993. else
  994. {
  995. RangeEnc_EncodeBit_1(rc, *prob);
  996. *prob = (UInt16)PPMD_UPDATE_PROB_1(*prob);
  997. p->InitEsc = PPMD7_kExpEscape[*prob >> 10];
  998. PPMD_SetAllBitsIn256Bytes(charMask);
  999. MASK(s->Symbol) = 0;
  1000. p->PrevSuccess = 0;
  1001. }
  1002. }
  1003. for (;;)
  1004. {
  1005. UInt32 escFreq;
  1006. CPpmd_See *see;
  1007. CPpmd_State *s;
  1008. UInt32 sum;
  1009. unsigned i, numMasked = p->MinContext->NumStats;
  1010. do
  1011. {
  1012. p->OrderFall++;
  1013. if (!p->MinContext->Suffix)
  1014. return; /* EndMarker (symbol = -1) */
  1015. p->MinContext = Ppmd7_GetContext(p, p->MinContext->Suffix);
  1016. }
  1017. while (p->MinContext->NumStats == numMasked);
  1018. see = Ppmd7_MakeEscFreq(p, numMasked, &escFreq);
  1019. s = Ppmd7_GetStats(p, p->MinContext);
  1020. sum = 0;
  1021. i = p->MinContext->NumStats;
  1022. do
  1023. {
  1024. int cur = s->Symbol;
  1025. if (cur == symbol)
  1026. {
  1027. UInt32 low = sum;
  1028. CPpmd_State *s1 = s;
  1029. do
  1030. {
  1031. sum += (s->Freq & (int)(MASK(s->Symbol)));
  1032. s++;
  1033. }
  1034. while (--i);
  1035. RangeEnc_Encode(rc, low, s1->Freq, sum + escFreq);
  1036. Ppmd_See_Update(see);
  1037. p->FoundState = s1;
  1038. Ppmd7_Update2(p);
  1039. return;
  1040. }
  1041. sum += (s->Freq & (int)(MASK(cur)));
  1042. MASK(cur) = 0;
  1043. s++;
  1044. }
  1045. while (--i);
  1046. RangeEnc_Encode(rc, sum, escFreq, sum + escFreq);
  1047. see->Summ = (UInt16)(see->Summ + sum + escFreq);
  1048. }
  1049. }
  1050. const IPpmd7 __archive_ppmd7_functions =
  1051. {
  1052. &Ppmd7_Construct,
  1053. &Ppmd7_Alloc,
  1054. &Ppmd7_Free,
  1055. &Ppmd7_Init,
  1056. &Ppmd7z_RangeDec_CreateVTable,
  1057. &PpmdRAR_RangeDec_CreateVTable,
  1058. &Ppmd7z_RangeDec_Init,
  1059. &PpmdRAR_RangeDec_Init,
  1060. &Ppmd7_DecodeSymbol,
  1061. &Ppmd7z_RangeEnc_Init,
  1062. &Ppmd7z_RangeEnc_FlushData,
  1063. &Ppmd7_EncodeSymbol
  1064. };