archive_ppmd7.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173
  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 <stdlib.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)
  94. {
  95. free(p->Base);
  96. p->Size = 0;
  97. p->Base = 0;
  98. }
  99. static Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size)
  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);
  109. p->AlignOffset =
  110. #ifdef PPMD_32BIT
  111. (4 - size) & 3;
  112. #else
  113. 4 - (size & 3);
  114. #endif
  115. if ((p->Base = malloc(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) do { \
  253. UInt32 *d = (UInt32 *)dest; \
  254. const UInt32 *s = (const UInt32 *)src; \
  255. UInt32 n = num; \
  256. do { \
  257. d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; \
  258. } while(--n); \
  259. } while (0)
  260. static void *ShrinkUnits(CPpmd7 *p, void *oldPtr, unsigned oldNU, unsigned newNU)
  261. {
  262. unsigned i0 = U2I(oldNU);
  263. unsigned i1 = U2I(newNU);
  264. if (i0 == i1)
  265. return oldPtr;
  266. if (p->FreeList[i1] != 0)
  267. {
  268. void *ptr = RemoveNode(p, i1);
  269. MyMem12Cpy(ptr, oldPtr, newNU);
  270. InsertNode(p, oldPtr, i0);
  271. return ptr;
  272. }
  273. SplitBlock(p, oldPtr, i0, i1);
  274. return oldPtr;
  275. }
  276. #define SUCCESSOR(p) ((CPpmd_Void_Ref)((p)->SuccessorLow | ((UInt32)(p)->SuccessorHigh << 16)))
  277. static void SetSuccessor(CPpmd_State *p, CPpmd_Void_Ref v)
  278. {
  279. (p)->SuccessorLow = (UInt16)((UInt32)(v) & 0xFFFF);
  280. (p)->SuccessorHigh = (UInt16)(((UInt32)(v) >> 16) & 0xFFFF);
  281. }
  282. static void RestartModel(CPpmd7 *p)
  283. {
  284. unsigned i, k, m;
  285. memset(p->FreeList, 0, sizeof(p->FreeList));
  286. p->Text = p->Base + p->AlignOffset;
  287. p->HiUnit = p->Text + p->Size;
  288. p->LoUnit = p->UnitsStart = p->HiUnit - p->Size / 8 / UNIT_SIZE * 7 * UNIT_SIZE;
  289. p->GlueCount = 0;
  290. p->OrderFall = p->MaxOrder;
  291. p->RunLength = p->InitRL = -(Int32)((p->MaxOrder < 12) ? p->MaxOrder : 12) - 1;
  292. p->PrevSuccess = 0;
  293. p->MinContext = p->MaxContext = (CTX_PTR)(p->HiUnit -= UNIT_SIZE); /* AllocContext(p); */
  294. p->MinContext->Suffix = 0;
  295. p->MinContext->NumStats = 256;
  296. p->MinContext->SummFreq = 256 + 1;
  297. p->FoundState = (CPpmd_State *)p->LoUnit; /* AllocUnits(p, PPMD_NUM_INDEXES - 1); */
  298. p->LoUnit += U2B(256 / 2);
  299. p->MinContext->Stats = REF(p->FoundState);
  300. for (i = 0; i < 256; i++)
  301. {
  302. CPpmd_State *s = &p->FoundState[i];
  303. s->Symbol = (Byte)i;
  304. s->Freq = 1;
  305. SetSuccessor(s, 0);
  306. }
  307. for (i = 0; i < 128; i++)
  308. for (k = 0; k < 8; k++)
  309. {
  310. UInt16 *dest = p->BinSumm[i] + k;
  311. UInt16 val = (UInt16)(PPMD_BIN_SCALE - kInitBinEsc[k] / (i + 2));
  312. for (m = 0; m < 64; m += 8)
  313. dest[m] = val;
  314. }
  315. for (i = 0; i < 25; i++)
  316. for (k = 0; k < 16; k++)
  317. {
  318. CPpmd_See *s = &p->See[i][k];
  319. s->Summ = (UInt16)((5 * i + 10) << (s->Shift = PPMD_PERIOD_BITS - 4));
  320. s->Count = 4;
  321. }
  322. }
  323. static void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder)
  324. {
  325. p->MaxOrder = maxOrder;
  326. RestartModel(p);
  327. p->DummySee.Shift = PPMD_PERIOD_BITS;
  328. p->DummySee.Summ = 0; /* unused */
  329. p->DummySee.Count = 64; /* unused */
  330. }
  331. static CTX_PTR CreateSuccessors(CPpmd7 *p, Bool skip)
  332. {
  333. CPpmd_State upState;
  334. CTX_PTR c = p->MinContext;
  335. CPpmd_Byte_Ref upBranch = (CPpmd_Byte_Ref)SUCCESSOR(p->FoundState);
  336. CPpmd_State *ps[PPMD7_MAX_ORDER];
  337. unsigned numPs = 0;
  338. if (!skip)
  339. ps[numPs++] = p->FoundState;
  340. while (c->Suffix)
  341. {
  342. CPpmd_Void_Ref successor;
  343. CPpmd_State *s;
  344. c = SUFFIX(c);
  345. if (c->NumStats != 1)
  346. {
  347. for (s = STATS(c); s->Symbol != p->FoundState->Symbol; s++);
  348. }
  349. else
  350. s = ONE_STATE(c);
  351. successor = SUCCESSOR(s);
  352. if (successor != upBranch)
  353. {
  354. c = CTX(successor);
  355. if (numPs == 0)
  356. return c;
  357. break;
  358. }
  359. ps[numPs++] = s;
  360. }
  361. upState.Symbol = *(const Byte *)Ppmd7_GetPtr(p, upBranch);
  362. SetSuccessor(&upState, upBranch + 1);
  363. if (c->NumStats == 1)
  364. upState.Freq = ONE_STATE(c)->Freq;
  365. else
  366. {
  367. UInt32 cf, s0;
  368. CPpmd_State *s;
  369. for (s = STATS(c); s->Symbol != upState.Symbol; s++);
  370. cf = s->Freq - 1;
  371. s0 = c->SummFreq - c->NumStats - cf;
  372. upState.Freq = (Byte)(1 + ((2 * cf <= s0) ? (5 * cf > s0) : ((2 * cf + 3 * s0 - 1) / (2 * s0))));
  373. }
  374. while (numPs != 0)
  375. {
  376. /* Create Child */
  377. CTX_PTR c1; /* = AllocContext(p); */
  378. if (p->HiUnit != p->LoUnit)
  379. c1 = (CTX_PTR)(p->HiUnit -= UNIT_SIZE);
  380. else if (p->FreeList[0] != 0)
  381. c1 = (CTX_PTR)RemoveNode(p, 0);
  382. else
  383. {
  384. c1 = (CTX_PTR)AllocUnitsRare(p, 0);
  385. if (!c1)
  386. return NULL;
  387. }
  388. c1->NumStats = 1;
  389. *ONE_STATE(c1) = upState;
  390. c1->Suffix = REF(c);
  391. SetSuccessor(ps[--numPs], REF(c1));
  392. c = c1;
  393. }
  394. return c;
  395. }
  396. static void SwapStates(CPpmd_State *t1, CPpmd_State *t2)
  397. {
  398. CPpmd_State tmp = *t1;
  399. *t1 = *t2;
  400. *t2 = tmp;
  401. }
  402. static void UpdateModel(CPpmd7 *p)
  403. {
  404. CPpmd_Void_Ref successor, fSuccessor = SUCCESSOR(p->FoundState);
  405. CTX_PTR c;
  406. unsigned s0, ns;
  407. if (p->FoundState->Freq < MAX_FREQ / 4 && p->MinContext->Suffix != 0)
  408. {
  409. c = SUFFIX(p->MinContext);
  410. if (c->NumStats == 1)
  411. {
  412. CPpmd_State *s = ONE_STATE(c);
  413. if (s->Freq < 32)
  414. s->Freq++;
  415. }
  416. else
  417. {
  418. CPpmd_State *s = STATS(c);
  419. if (s->Symbol != p->FoundState->Symbol)
  420. {
  421. do { s++; } while (s->Symbol != p->FoundState->Symbol);
  422. if (s[0].Freq >= s[-1].Freq)
  423. {
  424. SwapStates(&s[0], &s[-1]);
  425. s--;
  426. }
  427. }
  428. if (s->Freq < MAX_FREQ - 9)
  429. {
  430. s->Freq += 2;
  431. c->SummFreq += 2;
  432. }
  433. }
  434. }
  435. if (p->OrderFall == 0)
  436. {
  437. p->MinContext = p->MaxContext = CreateSuccessors(p, True);
  438. if (p->MinContext == 0)
  439. {
  440. RestartModel(p);
  441. return;
  442. }
  443. SetSuccessor(p->FoundState, REF(p->MinContext));
  444. return;
  445. }
  446. *p->Text++ = p->FoundState->Symbol;
  447. successor = REF(p->Text);
  448. if (p->Text >= p->UnitsStart)
  449. {
  450. RestartModel(p);
  451. return;
  452. }
  453. if (fSuccessor)
  454. {
  455. if (fSuccessor <= successor)
  456. {
  457. CTX_PTR cs = CreateSuccessors(p, False);
  458. if (cs == NULL)
  459. {
  460. RestartModel(p);
  461. return;
  462. }
  463. fSuccessor = REF(cs);
  464. }
  465. if (--p->OrderFall == 0)
  466. {
  467. successor = fSuccessor;
  468. p->Text -= (p->MaxContext != p->MinContext);
  469. }
  470. }
  471. else
  472. {
  473. SetSuccessor(p->FoundState, successor);
  474. fSuccessor = REF(p->MinContext);
  475. }
  476. s0 = p->MinContext->SummFreq - (ns = p->MinContext->NumStats) - (p->FoundState->Freq - 1);
  477. for (c = p->MaxContext; c != p->MinContext; c = SUFFIX(c))
  478. {
  479. unsigned ns1;
  480. UInt32 cf, sf;
  481. if ((ns1 = c->NumStats) != 1)
  482. {
  483. if ((ns1 & 1) == 0)
  484. {
  485. /* Expand for one UNIT */
  486. unsigned oldNU = ns1 >> 1;
  487. unsigned i = U2I(oldNU);
  488. if (i != U2I(oldNU + 1))
  489. {
  490. void *ptr = AllocUnits(p, i + 1);
  491. void *oldPtr;
  492. if (!ptr)
  493. {
  494. RestartModel(p);
  495. return;
  496. }
  497. oldPtr = STATS(c);
  498. MyMem12Cpy(ptr, oldPtr, oldNU);
  499. InsertNode(p, oldPtr, i);
  500. c->Stats = STATS_REF(ptr);
  501. }
  502. }
  503. c->SummFreq = (UInt16)(c->SummFreq + (2 * ns1 < ns) + 2 * ((4 * ns1 <= ns) & (c->SummFreq <= 8 * ns1)));
  504. }
  505. else
  506. {
  507. CPpmd_State *s = (CPpmd_State*)AllocUnits(p, 0);
  508. if (!s)
  509. {
  510. RestartModel(p);
  511. return;
  512. }
  513. *s = *ONE_STATE(c);
  514. c->Stats = REF(s);
  515. if (s->Freq < MAX_FREQ / 4 - 1)
  516. s->Freq <<= 1;
  517. else
  518. s->Freq = MAX_FREQ - 4;
  519. c->SummFreq = (UInt16)(s->Freq + p->InitEsc + (ns > 3));
  520. }
  521. cf = 2 * (UInt32)p->FoundState->Freq * (c->SummFreq + 6);
  522. sf = (UInt32)s0 + c->SummFreq;
  523. if (cf < 6 * sf)
  524. {
  525. cf = 1 + (cf > sf) + (cf >= 4 * sf);
  526. c->SummFreq += 3;
  527. }
  528. else
  529. {
  530. cf = 4 + (cf >= 9 * sf) + (cf >= 12 * sf) + (cf >= 15 * sf);
  531. c->SummFreq = (UInt16)(c->SummFreq + cf);
  532. }
  533. {
  534. CPpmd_State *s = STATS(c) + ns1;
  535. SetSuccessor(s, successor);
  536. s->Symbol = p->FoundState->Symbol;
  537. s->Freq = (Byte)cf;
  538. c->NumStats = (UInt16)(ns1 + 1);
  539. }
  540. }
  541. p->MaxContext = p->MinContext = CTX(fSuccessor);
  542. }
  543. static void Rescale(CPpmd7 *p)
  544. {
  545. unsigned i, adder, sumFreq, escFreq;
  546. CPpmd_State *stats = STATS(p->MinContext);
  547. CPpmd_State *s = p->FoundState;
  548. {
  549. CPpmd_State tmp = *s;
  550. for (; s != stats; s--)
  551. s[0] = s[-1];
  552. *s = tmp;
  553. }
  554. escFreq = p->MinContext->SummFreq - s->Freq;
  555. s->Freq += 4;
  556. adder = (p->OrderFall != 0);
  557. s->Freq = (Byte)((s->Freq + adder) >> 1);
  558. sumFreq = s->Freq;
  559. i = p->MinContext->NumStats - 1;
  560. do
  561. {
  562. escFreq -= (++s)->Freq;
  563. s->Freq = (Byte)((s->Freq + adder) >> 1);
  564. sumFreq += s->Freq;
  565. if (s[0].Freq > s[-1].Freq)
  566. {
  567. CPpmd_State *s1 = s;
  568. CPpmd_State tmp = *s1;
  569. do
  570. s1[0] = s1[-1];
  571. while (--s1 != stats && tmp.Freq > s1[-1].Freq);
  572. *s1 = tmp;
  573. }
  574. }
  575. while (--i);
  576. if (s->Freq == 0)
  577. {
  578. unsigned numStats = p->MinContext->NumStats;
  579. unsigned n0, n1;
  580. do { i++; } while ((--s)->Freq == 0);
  581. escFreq += i;
  582. p->MinContext->NumStats = (UInt16)(p->MinContext->NumStats - i);
  583. if (p->MinContext->NumStats == 1)
  584. {
  585. CPpmd_State tmp = *stats;
  586. do
  587. {
  588. tmp.Freq = (Byte)(tmp.Freq - (tmp.Freq >> 1));
  589. escFreq >>= 1;
  590. }
  591. while (escFreq > 1);
  592. InsertNode(p, stats, U2I(((numStats + 1) >> 1)));
  593. *(p->FoundState = ONE_STATE(p->MinContext)) = tmp;
  594. return;
  595. }
  596. n0 = (numStats + 1) >> 1;
  597. n1 = (p->MinContext->NumStats + 1) >> 1;
  598. if (n0 != n1)
  599. p->MinContext->Stats = STATS_REF(ShrinkUnits(p, stats, n0, n1));
  600. }
  601. p->MinContext->SummFreq = (UInt16)(sumFreq + escFreq - (escFreq >> 1));
  602. p->FoundState = STATS(p->MinContext);
  603. }
  604. static CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *escFreq)
  605. {
  606. CPpmd_See *see;
  607. unsigned nonMasked = p->MinContext->NumStats - numMasked;
  608. if (p->MinContext->NumStats != 256)
  609. {
  610. see = p->See[p->NS2Indx[nonMasked - 1]] +
  611. (nonMasked < (unsigned)SUFFIX(p->MinContext)->NumStats - p->MinContext->NumStats) +
  612. 2 * (p->MinContext->SummFreq < 11 * p->MinContext->NumStats) +
  613. 4 * (numMasked > nonMasked) +
  614. p->HiBitsFlag;
  615. {
  616. unsigned r = (see->Summ >> see->Shift);
  617. see->Summ = (UInt16)(see->Summ - r);
  618. *escFreq = r + (r == 0);
  619. }
  620. }
  621. else
  622. {
  623. see = &p->DummySee;
  624. *escFreq = 1;
  625. }
  626. return see;
  627. }
  628. static void NextContext(CPpmd7 *p)
  629. {
  630. CTX_PTR c = CTX(SUCCESSOR(p->FoundState));
  631. if (p->OrderFall == 0 && (Byte *)c > p->Text)
  632. p->MinContext = p->MaxContext = c;
  633. else
  634. UpdateModel(p);
  635. }
  636. static void Ppmd7_Update1(CPpmd7 *p)
  637. {
  638. CPpmd_State *s = p->FoundState;
  639. s->Freq += 4;
  640. p->MinContext->SummFreq += 4;
  641. if (s[0].Freq > s[-1].Freq)
  642. {
  643. SwapStates(&s[0], &s[-1]);
  644. p->FoundState = --s;
  645. if (s->Freq > MAX_FREQ)
  646. Rescale(p);
  647. }
  648. NextContext(p);
  649. }
  650. static void Ppmd7_Update1_0(CPpmd7 *p)
  651. {
  652. p->PrevSuccess = (2 * p->FoundState->Freq > p->MinContext->SummFreq);
  653. p->RunLength += p->PrevSuccess;
  654. p->MinContext->SummFreq += 4;
  655. if ((p->FoundState->Freq += 4) > MAX_FREQ)
  656. Rescale(p);
  657. NextContext(p);
  658. }
  659. static void Ppmd7_UpdateBin(CPpmd7 *p)
  660. {
  661. p->FoundState->Freq = (Byte)(p->FoundState->Freq + (p->FoundState->Freq < 128 ? 1: 0));
  662. p->PrevSuccess = 1;
  663. p->RunLength++;
  664. NextContext(p);
  665. }
  666. static void Ppmd7_Update2(CPpmd7 *p)
  667. {
  668. p->MinContext->SummFreq += 4;
  669. if ((p->FoundState->Freq += 4) > MAX_FREQ)
  670. Rescale(p);
  671. p->RunLength = p->InitRL;
  672. UpdateModel(p);
  673. }
  674. /* ---------- Decode ---------- */
  675. static Bool Ppmd_RangeDec_Init(CPpmd7z_RangeDec *p)
  676. {
  677. unsigned i;
  678. p->Low = p->Bottom = 0;
  679. p->Range = 0xFFFFFFFF;
  680. for (i = 0; i < 4; i++)
  681. p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
  682. return (p->Code < 0xFFFFFFFF);
  683. }
  684. static Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p)
  685. {
  686. if (p->Stream->Read((void *)p->Stream) != 0)
  687. return False;
  688. return Ppmd_RangeDec_Init(p);
  689. }
  690. static Bool PpmdRAR_RangeDec_Init(CPpmd7z_RangeDec *p)
  691. {
  692. if (!Ppmd_RangeDec_Init(p))
  693. return False;
  694. p->Bottom = 0x8000;
  695. return True;
  696. }
  697. static UInt32 Range_GetThreshold(void *pp, UInt32 total)
  698. {
  699. CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
  700. return (p->Code - p->Low) / (p->Range /= total);
  701. }
  702. static void Range_Normalize(CPpmd7z_RangeDec *p)
  703. {
  704. while (1)
  705. {
  706. if((p->Low ^ (p->Low + p->Range)) >= kTopValue)
  707. {
  708. if(p->Range >= p->Bottom)
  709. break;
  710. else
  711. p->Range = ((uint32_t)(-(int32_t)p->Low)) & (p->Bottom - 1);
  712. }
  713. p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
  714. p->Range <<= 8;
  715. p->Low <<= 8;
  716. }
  717. }
  718. static void Range_Decode_7z(void *pp, UInt32 start, UInt32 size)
  719. {
  720. CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
  721. p->Code -= start * p->Range;
  722. p->Range *= size;
  723. Range_Normalize(p);
  724. }
  725. static void Range_Decode_RAR(void *pp, UInt32 start, UInt32 size)
  726. {
  727. CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
  728. p->Low += start * p->Range;
  729. p->Range *= size;
  730. Range_Normalize(p);
  731. }
  732. static UInt32 Range_DecodeBit_7z(void *pp, UInt32 size0)
  733. {
  734. CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
  735. UInt32 newBound = (p->Range >> 14) * size0;
  736. UInt32 symbol;
  737. if (p->Code < newBound)
  738. {
  739. symbol = 0;
  740. p->Range = newBound;
  741. }
  742. else
  743. {
  744. symbol = 1;
  745. p->Code -= newBound;
  746. p->Range -= newBound;
  747. }
  748. Range_Normalize(p);
  749. return symbol;
  750. }
  751. static UInt32 Range_DecodeBit_RAR(void *pp, UInt32 size0)
  752. {
  753. CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
  754. UInt32 bit, value = p->p.GetThreshold(p, PPMD_BIN_SCALE);
  755. if(value < size0)
  756. {
  757. bit = 0;
  758. p->p.Decode(p, 0, size0);
  759. }
  760. else
  761. {
  762. bit = 1;
  763. p->p.Decode(p, size0, PPMD_BIN_SCALE - size0);
  764. }
  765. return bit;
  766. }
  767. static void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p)
  768. {
  769. p->p.GetThreshold = Range_GetThreshold;
  770. p->p.Decode = Range_Decode_7z;
  771. p->p.DecodeBit = Range_DecodeBit_7z;
  772. }
  773. static void PpmdRAR_RangeDec_CreateVTable(CPpmd7z_RangeDec *p)
  774. {
  775. p->p.GetThreshold = Range_GetThreshold;
  776. p->p.Decode = Range_Decode_RAR;
  777. p->p.DecodeBit = Range_DecodeBit_RAR;
  778. }
  779. #define MASK(sym) ((signed char *)charMask)[sym]
  780. static int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc)
  781. {
  782. size_t charMask[256 / sizeof(size_t)];
  783. if (p->MinContext->NumStats != 1)
  784. {
  785. CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext);
  786. unsigned i;
  787. UInt32 count, hiCnt;
  788. if ((count = rc->GetThreshold(rc, p->MinContext->SummFreq)) < (hiCnt = s->Freq))
  789. {
  790. Byte symbol;
  791. rc->Decode(rc, 0, s->Freq);
  792. p->FoundState = s;
  793. symbol = s->Symbol;
  794. Ppmd7_Update1_0(p);
  795. return symbol;
  796. }
  797. p->PrevSuccess = 0;
  798. i = p->MinContext->NumStats - 1;
  799. do
  800. {
  801. if ((hiCnt += (++s)->Freq) > count)
  802. {
  803. Byte symbol;
  804. rc->Decode(rc, hiCnt - s->Freq, s->Freq);
  805. p->FoundState = s;
  806. symbol = s->Symbol;
  807. Ppmd7_Update1(p);
  808. return symbol;
  809. }
  810. }
  811. while (--i);
  812. if (count >= p->MinContext->SummFreq)
  813. return -2;
  814. p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol];
  815. rc->Decode(rc, hiCnt, p->MinContext->SummFreq - hiCnt);
  816. PPMD_SetAllBitsIn256Bytes(charMask);
  817. MASK(s->Symbol) = 0;
  818. i = p->MinContext->NumStats - 1;
  819. do { MASK((--s)->Symbol) = 0; } while (--i);
  820. }
  821. else
  822. {
  823. UInt16 *prob = Ppmd7_GetBinSumm(p);
  824. if (rc->DecodeBit(rc, *prob) == 0)
  825. {
  826. Byte symbol;
  827. *prob = (UInt16)PPMD_UPDATE_PROB_0(*prob);
  828. symbol = (p->FoundState = Ppmd7Context_OneState(p->MinContext))->Symbol;
  829. Ppmd7_UpdateBin(p);
  830. return symbol;
  831. }
  832. *prob = (UInt16)PPMD_UPDATE_PROB_1(*prob);
  833. p->InitEsc = PPMD7_kExpEscape[*prob >> 10];
  834. PPMD_SetAllBitsIn256Bytes(charMask);
  835. MASK(Ppmd7Context_OneState(p->MinContext)->Symbol) = 0;
  836. p->PrevSuccess = 0;
  837. }
  838. for (;;)
  839. {
  840. CPpmd_State *ps[256], *s;
  841. UInt32 freqSum, count, hiCnt;
  842. CPpmd_See *see;
  843. unsigned i, num, numMasked = p->MinContext->NumStats;
  844. do
  845. {
  846. p->OrderFall++;
  847. if (!p->MinContext->Suffix)
  848. return -1;
  849. p->MinContext = Ppmd7_GetContext(p, p->MinContext->Suffix);
  850. }
  851. while (p->MinContext->NumStats == numMasked);
  852. hiCnt = 0;
  853. s = Ppmd7_GetStats(p, p->MinContext);
  854. i = 0;
  855. num = p->MinContext->NumStats - numMasked;
  856. do
  857. {
  858. int k = (int)(MASK(s->Symbol));
  859. hiCnt += (s->Freq & k);
  860. ps[i] = s++;
  861. i -= k;
  862. }
  863. while (i != num);
  864. see = Ppmd7_MakeEscFreq(p, numMasked, &freqSum);
  865. freqSum += hiCnt;
  866. count = rc->GetThreshold(rc, freqSum);
  867. if (count < hiCnt)
  868. {
  869. Byte symbol;
  870. CPpmd_State **pps = ps;
  871. for (hiCnt = 0; (hiCnt += (*pps)->Freq) <= count; pps++);
  872. s = *pps;
  873. rc->Decode(rc, hiCnt - s->Freq, s->Freq);
  874. Ppmd_See_Update(see);
  875. p->FoundState = s;
  876. symbol = s->Symbol;
  877. Ppmd7_Update2(p);
  878. return symbol;
  879. }
  880. if (count >= freqSum)
  881. return -2;
  882. rc->Decode(rc, hiCnt, freqSum - hiCnt);
  883. see->Summ = (UInt16)(see->Summ + freqSum);
  884. do { MASK(ps[--i]->Symbol) = 0; } while (i != 0);
  885. }
  886. }
  887. /* ---------- Encode ---------- Ppmd7Enc.c */
  888. #define kTopValue (1 << 24)
  889. static void Ppmd7z_RangeEnc_Init(CPpmd7z_RangeEnc *p)
  890. {
  891. p->Low = 0;
  892. p->Range = 0xFFFFFFFF;
  893. p->Cache = 0;
  894. p->CacheSize = 1;
  895. }
  896. static void RangeEnc_ShiftLow(CPpmd7z_RangeEnc *p)
  897. {
  898. if ((UInt32)p->Low < (UInt32)0xFF000000 || (unsigned)(p->Low >> 32) != 0)
  899. {
  900. Byte temp = p->Cache;
  901. do
  902. {
  903. p->Stream->Write(p->Stream, (Byte)(temp + (Byte)(p->Low >> 32)));
  904. temp = 0xFF;
  905. }
  906. while(--p->CacheSize != 0);
  907. p->Cache = (Byte)((UInt32)p->Low >> 24);
  908. }
  909. p->CacheSize++;
  910. p->Low = ((UInt32)p->Low << 8) & 0xFFFFFFFF;
  911. }
  912. static void RangeEnc_Encode(CPpmd7z_RangeEnc *p, UInt32 start, UInt32 size, UInt32 total)
  913. {
  914. p->Low += (UInt64)start * (UInt64)(p->Range /= total);
  915. p->Range *= size;
  916. while (p->Range < kTopValue)
  917. {
  918. p->Range <<= 8;
  919. RangeEnc_ShiftLow(p);
  920. }
  921. }
  922. static void RangeEnc_EncodeBit_0(CPpmd7z_RangeEnc *p, UInt32 size0)
  923. {
  924. p->Range = (p->Range >> 14) * size0;
  925. while (p->Range < kTopValue)
  926. {
  927. p->Range <<= 8;
  928. RangeEnc_ShiftLow(p);
  929. }
  930. }
  931. static void RangeEnc_EncodeBit_1(CPpmd7z_RangeEnc *p, UInt32 size0)
  932. {
  933. UInt32 newBound = (p->Range >> 14) * size0;
  934. p->Low += newBound;
  935. p->Range -= newBound;
  936. while (p->Range < kTopValue)
  937. {
  938. p->Range <<= 8;
  939. RangeEnc_ShiftLow(p);
  940. }
  941. }
  942. static void Ppmd7z_RangeEnc_FlushData(CPpmd7z_RangeEnc *p)
  943. {
  944. unsigned i;
  945. for (i = 0; i < 5; i++)
  946. RangeEnc_ShiftLow(p);
  947. }
  948. #define MASK(sym) ((signed char *)charMask)[sym]
  949. static void Ppmd7_EncodeSymbol(CPpmd7 *p, CPpmd7z_RangeEnc *rc, int symbol)
  950. {
  951. size_t charMask[256 / sizeof(size_t)];
  952. if (p->MinContext->NumStats != 1)
  953. {
  954. CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext);
  955. UInt32 sum;
  956. unsigned i;
  957. if (s->Symbol == symbol)
  958. {
  959. RangeEnc_Encode(rc, 0, s->Freq, p->MinContext->SummFreq);
  960. p->FoundState = s;
  961. Ppmd7_Update1_0(p);
  962. return;
  963. }
  964. p->PrevSuccess = 0;
  965. sum = s->Freq;
  966. i = p->MinContext->NumStats - 1;
  967. do
  968. {
  969. if ((++s)->Symbol == symbol)
  970. {
  971. RangeEnc_Encode(rc, sum, s->Freq, p->MinContext->SummFreq);
  972. p->FoundState = s;
  973. Ppmd7_Update1(p);
  974. return;
  975. }
  976. sum += s->Freq;
  977. }
  978. while (--i);
  979. p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol];
  980. PPMD_SetAllBitsIn256Bytes(charMask);
  981. MASK(s->Symbol) = 0;
  982. i = p->MinContext->NumStats - 1;
  983. do { MASK((--s)->Symbol) = 0; } while (--i);
  984. RangeEnc_Encode(rc, sum, p->MinContext->SummFreq - sum, p->MinContext->SummFreq);
  985. }
  986. else
  987. {
  988. UInt16 *prob = Ppmd7_GetBinSumm(p);
  989. CPpmd_State *s = Ppmd7Context_OneState(p->MinContext);
  990. if (s->Symbol == symbol)
  991. {
  992. RangeEnc_EncodeBit_0(rc, *prob);
  993. *prob = (UInt16)PPMD_UPDATE_PROB_0(*prob);
  994. p->FoundState = s;
  995. Ppmd7_UpdateBin(p);
  996. return;
  997. }
  998. else
  999. {
  1000. RangeEnc_EncodeBit_1(rc, *prob);
  1001. *prob = (UInt16)PPMD_UPDATE_PROB_1(*prob);
  1002. p->InitEsc = PPMD7_kExpEscape[*prob >> 10];
  1003. PPMD_SetAllBitsIn256Bytes(charMask);
  1004. MASK(s->Symbol) = 0;
  1005. p->PrevSuccess = 0;
  1006. }
  1007. }
  1008. for (;;)
  1009. {
  1010. UInt32 escFreq;
  1011. CPpmd_See *see;
  1012. CPpmd_State *s;
  1013. UInt32 sum;
  1014. unsigned i, numMasked = p->MinContext->NumStats;
  1015. do
  1016. {
  1017. p->OrderFall++;
  1018. if (!p->MinContext->Suffix)
  1019. return; /* EndMarker (symbol = -1) */
  1020. p->MinContext = Ppmd7_GetContext(p, p->MinContext->Suffix);
  1021. }
  1022. while (p->MinContext->NumStats == numMasked);
  1023. see = Ppmd7_MakeEscFreq(p, numMasked, &escFreq);
  1024. s = Ppmd7_GetStats(p, p->MinContext);
  1025. sum = 0;
  1026. i = p->MinContext->NumStats;
  1027. do
  1028. {
  1029. int cur = s->Symbol;
  1030. if (cur == symbol)
  1031. {
  1032. UInt32 low = sum;
  1033. CPpmd_State *s1 = s;
  1034. do
  1035. {
  1036. sum += (s->Freq & (int)(MASK(s->Symbol)));
  1037. s++;
  1038. }
  1039. while (--i);
  1040. RangeEnc_Encode(rc, low, s1->Freq, sum + escFreq);
  1041. Ppmd_See_Update(see);
  1042. p->FoundState = s1;
  1043. Ppmd7_Update2(p);
  1044. return;
  1045. }
  1046. sum += (s->Freq & (int)(MASK(cur)));
  1047. MASK(cur) = 0;
  1048. s++;
  1049. }
  1050. while (--i);
  1051. RangeEnc_Encode(rc, sum, escFreq, sum + escFreq);
  1052. see->Summ = (UInt16)(see->Summ + sum + escFreq);
  1053. }
  1054. }
  1055. const IPpmd7 __archive_ppmd7_functions =
  1056. {
  1057. &Ppmd7_Construct,
  1058. &Ppmd7_Alloc,
  1059. &Ppmd7_Free,
  1060. &Ppmd7_Init,
  1061. &Ppmd7z_RangeDec_CreateVTable,
  1062. &PpmdRAR_RangeDec_CreateVTable,
  1063. &Ppmd7z_RangeDec_Init,
  1064. &PpmdRAR_RangeDec_Init,
  1065. &Ppmd7_DecodeSymbol,
  1066. &Ppmd7z_RangeEnc_Init,
  1067. &Ppmd7z_RangeEnc_FlushData,
  1068. &Ppmd7_EncodeSymbol
  1069. };