diff options
author | Igor Pavlov <87184205+ip7z@users.noreply.github.com> | 2023-06-21 00:00:00 +0000 |
---|---|---|
committer | Igor Pavlov <87184205+ip7z@users.noreply.github.com> | 2023-12-17 14:59:19 +0500 |
commit | 5b39dc76f1bc82f941d5c800ab9f34407a06b53a (patch) | |
tree | fe5e17420300b715021a76328444088d32047963 /C/Ppmd7.c | |
parent | 93be7d4abfd4233228f58ee1fbbcd76d91be66a4 (diff) | |
download | 7zip-5b39dc76f1bc82f941d5c800ab9f34407a06b53a.tar.gz 7zip-5b39dc76f1bc82f941d5c800ab9f34407a06b53a.tar.bz2 7zip-5b39dc76f1bc82f941d5c800ab9f34407a06b53a.zip |
23.0123.01
Diffstat (limited to 'C/Ppmd7.c')
-rw-r--r-- | C/Ppmd7.c | 186 |
1 files changed, 102 insertions, 84 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* Ppmd7.c -- PPMdH codec | 1 | /* Ppmd7.c -- PPMdH codec |
2 | 2021-04-13 : Igor Pavlov : Public domain | 2 | 2023-04-02 : Igor Pavlov : Public domain |
3 | This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ | 3 | This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ |
4 | 4 | ||
5 | #include "Precomp.h" | 5 | #include "Precomp.h" |
@@ -14,7 +14,7 @@ This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ | |||
14 | MY_ALIGN(16) | 14 | MY_ALIGN(16) |
15 | static const Byte PPMD7_kExpEscape[16] = { 25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 }; | 15 | static const Byte PPMD7_kExpEscape[16] = { 25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 }; |
16 | MY_ALIGN(16) | 16 | MY_ALIGN(16) |
17 | static const UInt16 kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051}; | 17 | static const UInt16 PPMD7_kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051}; |
18 | 18 | ||
19 | #define MAX_FREQ 124 | 19 | #define MAX_FREQ 124 |
20 | #define UNIT_SIZE 12 | 20 | #define UNIT_SIZE 12 |
@@ -33,7 +33,7 @@ static const UInt16 kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x | |||
33 | #define ONE_STATE(ctx) Ppmd7Context_OneState(ctx) | 33 | #define ONE_STATE(ctx) Ppmd7Context_OneState(ctx) |
34 | #define SUFFIX(ctx) CTX((ctx)->Suffix) | 34 | #define SUFFIX(ctx) CTX((ctx)->Suffix) |
35 | 35 | ||
36 | typedef CPpmd7_Context * CTX_PTR; | 36 | typedef CPpmd7_Context * PPMD7_CTX_PTR; |
37 | 37 | ||
38 | struct CPpmd7_Node_; | 38 | struct CPpmd7_Node_; |
39 | 39 | ||
@@ -107,14 +107,14 @@ BoolInt Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAllocPtr alloc) | |||
107 | // ---------- Internal Memory Allocator ---------- | 107 | // ---------- Internal Memory Allocator ---------- |
108 | 108 | ||
109 | /* We can use CPpmd7_Node in list of free units (as in Ppmd8) | 109 | /* We can use CPpmd7_Node in list of free units (as in Ppmd8) |
110 | But we still need one additional list walk pass in GlueFreeBlocks(). | 110 | But we still need one additional list walk pass in Ppmd7_GlueFreeBlocks(). |
111 | So we use simple CPpmd_Void_Ref instead of CPpmd7_Node in InsertNode() / RemoveNode() | 111 | So we use simple CPpmd_Void_Ref instead of CPpmd7_Node in Ppmd7_InsertNode() / Ppmd7_RemoveNode() |
112 | */ | 112 | */ |
113 | 113 | ||
114 | #define EMPTY_NODE 0 | 114 | #define EMPTY_NODE 0 |
115 | 115 | ||
116 | 116 | ||
117 | static void InsertNode(CPpmd7 *p, void *node, unsigned indx) | 117 | static void Ppmd7_InsertNode(CPpmd7 *p, void *node, unsigned indx) |
118 | { | 118 | { |
119 | *((CPpmd_Void_Ref *)node) = p->FreeList[indx]; | 119 | *((CPpmd_Void_Ref *)node) = p->FreeList[indx]; |
120 | // ((CPpmd7_Node *)node)->Next = (CPpmd7_Node_Ref)p->FreeList[indx]; | 120 | // ((CPpmd7_Node *)node)->Next = (CPpmd7_Node_Ref)p->FreeList[indx]; |
@@ -124,7 +124,7 @@ static void InsertNode(CPpmd7 *p, void *node, unsigned indx) | |||
124 | } | 124 | } |
125 | 125 | ||
126 | 126 | ||
127 | static void *RemoveNode(CPpmd7 *p, unsigned indx) | 127 | static void *Ppmd7_RemoveNode(CPpmd7 *p, unsigned indx) |
128 | { | 128 | { |
129 | CPpmd_Void_Ref *node = (CPpmd_Void_Ref *)Ppmd7_GetPtr(p, p->FreeList[indx]); | 129 | CPpmd_Void_Ref *node = (CPpmd_Void_Ref *)Ppmd7_GetPtr(p, p->FreeList[indx]); |
130 | p->FreeList[indx] = *node; | 130 | p->FreeList[indx] = *node; |
@@ -134,32 +134,32 @@ static void *RemoveNode(CPpmd7 *p, unsigned indx) | |||
134 | } | 134 | } |
135 | 135 | ||
136 | 136 | ||
137 | static void SplitBlock(CPpmd7 *p, void *ptr, unsigned oldIndx, unsigned newIndx) | 137 | static void Ppmd7_SplitBlock(CPpmd7 *p, void *ptr, unsigned oldIndx, unsigned newIndx) |
138 | { | 138 | { |
139 | unsigned i, nu = I2U(oldIndx) - I2U(newIndx); | 139 | unsigned i, nu = I2U(oldIndx) - I2U(newIndx); |
140 | ptr = (Byte *)ptr + U2B(I2U(newIndx)); | 140 | ptr = (Byte *)ptr + U2B(I2U(newIndx)); |
141 | if (I2U(i = U2I(nu)) != nu) | 141 | if (I2U(i = U2I(nu)) != nu) |
142 | { | 142 | { |
143 | unsigned k = I2U(--i); | 143 | unsigned k = I2U(--i); |
144 | InsertNode(p, ((Byte *)ptr) + U2B(k), nu - k - 1); | 144 | Ppmd7_InsertNode(p, ((Byte *)ptr) + U2B(k), nu - k - 1); |
145 | } | 145 | } |
146 | InsertNode(p, ptr, i); | 146 | Ppmd7_InsertNode(p, ptr, i); |
147 | } | 147 | } |
148 | 148 | ||
149 | 149 | ||
150 | /* we use CPpmd7_Node_Union union to solve XLC -O2 strict pointer aliasing problem */ | 150 | /* we use CPpmd7_Node_Union union to solve XLC -O2 strict pointer aliasing problem */ |
151 | 151 | ||
152 | typedef union _CPpmd7_Node_Union | 152 | typedef union |
153 | { | 153 | { |
154 | CPpmd7_Node Node; | 154 | CPpmd7_Node Node; |
155 | CPpmd7_Node_Ref NextRef; | 155 | CPpmd7_Node_Ref NextRef; |
156 | } CPpmd7_Node_Union; | 156 | } CPpmd7_Node_Union; |
157 | 157 | ||
158 | /* Original PPmdH (Ppmd7) code uses doubly linked list in GlueFreeBlocks() | 158 | /* Original PPmdH (Ppmd7) code uses doubly linked list in Ppmd7_GlueFreeBlocks() |
159 | we use single linked list similar to Ppmd8 code */ | 159 | we use single linked list similar to Ppmd8 code */ |
160 | 160 | ||
161 | 161 | ||
162 | static void GlueFreeBlocks(CPpmd7 *p) | 162 | static void Ppmd7_GlueFreeBlocks(CPpmd7 *p) |
163 | { | 163 | { |
164 | /* | 164 | /* |
165 | we use first UInt16 field of 12-bytes UNITs as record type stamp | 165 | we use first UInt16 field of 12-bytes UNITs as record type stamp |
@@ -239,27 +239,27 @@ static void GlueFreeBlocks(CPpmd7 *p) | |||
239 | if (nu == 0) | 239 | if (nu == 0) |
240 | continue; | 240 | continue; |
241 | for (; nu > 128; nu -= 128, node += 128) | 241 | for (; nu > 128; nu -= 128, node += 128) |
242 | InsertNode(p, node, PPMD_NUM_INDEXES - 1); | 242 | Ppmd7_InsertNode(p, node, PPMD_NUM_INDEXES - 1); |
243 | if (I2U(i = U2I(nu)) != nu) | 243 | if (I2U(i = U2I(nu)) != nu) |
244 | { | 244 | { |
245 | unsigned k = I2U(--i); | 245 | unsigned k = I2U(--i); |
246 | InsertNode(p, node + k, (unsigned)nu - k - 1); | 246 | Ppmd7_InsertNode(p, node + k, (unsigned)nu - k - 1); |
247 | } | 247 | } |
248 | InsertNode(p, node, i); | 248 | Ppmd7_InsertNode(p, node, i); |
249 | } | 249 | } |
250 | } | 250 | } |
251 | 251 | ||
252 | 252 | ||
253 | MY_NO_INLINE | 253 | Z7_NO_INLINE |
254 | static void *AllocUnitsRare(CPpmd7 *p, unsigned indx) | 254 | static void *Ppmd7_AllocUnitsRare(CPpmd7 *p, unsigned indx) |
255 | { | 255 | { |
256 | unsigned i; | 256 | unsigned i; |
257 | 257 | ||
258 | if (p->GlueCount == 0) | 258 | if (p->GlueCount == 0) |
259 | { | 259 | { |
260 | GlueFreeBlocks(p); | 260 | Ppmd7_GlueFreeBlocks(p); |
261 | if (p->FreeList[indx] != 0) | 261 | if (p->FreeList[indx] != 0) |
262 | return RemoveNode(p, indx); | 262 | return Ppmd7_RemoveNode(p, indx); |
263 | } | 263 | } |
264 | 264 | ||
265 | i = indx; | 265 | i = indx; |
@@ -277,17 +277,17 @@ static void *AllocUnitsRare(CPpmd7 *p, unsigned indx) | |||
277 | while (p->FreeList[i] == 0); | 277 | while (p->FreeList[i] == 0); |
278 | 278 | ||
279 | { | 279 | { |
280 | void *block = RemoveNode(p, i); | 280 | void *block = Ppmd7_RemoveNode(p, i); |
281 | SplitBlock(p, block, i, indx); | 281 | Ppmd7_SplitBlock(p, block, i, indx); |
282 | return block; | 282 | return block; |
283 | } | 283 | } |
284 | } | 284 | } |
285 | 285 | ||
286 | 286 | ||
287 | static void *AllocUnits(CPpmd7 *p, unsigned indx) | 287 | static void *Ppmd7_AllocUnits(CPpmd7 *p, unsigned indx) |
288 | { | 288 | { |
289 | if (p->FreeList[indx] != 0) | 289 | if (p->FreeList[indx] != 0) |
290 | return RemoveNode(p, indx); | 290 | return Ppmd7_RemoveNode(p, indx); |
291 | { | 291 | { |
292 | UInt32 numBytes = U2B(I2U(indx)); | 292 | UInt32 numBytes = U2B(I2U(indx)); |
293 | Byte *lo = p->LoUnit; | 293 | Byte *lo = p->LoUnit; |
@@ -297,11 +297,11 @@ static void *AllocUnits(CPpmd7 *p, unsigned indx) | |||
297 | return lo; | 297 | return lo; |
298 | } | 298 | } |
299 | } | 299 | } |
300 | return AllocUnitsRare(p, indx); | 300 | return Ppmd7_AllocUnitsRare(p, indx); |
301 | } | 301 | } |
302 | 302 | ||
303 | 303 | ||
304 | #define MyMem12Cpy(dest, src, num) \ | 304 | #define MEM_12_CPY(dest, src, num) \ |
305 | { UInt32 *d = (UInt32 *)dest; const UInt32 *z = (const UInt32 *)src; UInt32 n = num; \ | 305 | { UInt32 *d = (UInt32 *)dest; const UInt32 *z = (const UInt32 *)src; UInt32 n = num; \ |
306 | do { d[0] = z[0]; d[1] = z[1]; d[2] = z[2]; z += 3; d += 3; } while (--n); } | 306 | do { d[0] = z[0]; d[1] = z[1]; d[2] = z[2]; z += 3; d += 3; } while (--n); } |
307 | 307 | ||
@@ -315,12 +315,12 @@ static void *ShrinkUnits(CPpmd7 *p, void *oldPtr, unsigned oldNU, unsigned newNU | |||
315 | return oldPtr; | 315 | return oldPtr; |
316 | if (p->FreeList[i1] != 0) | 316 | if (p->FreeList[i1] != 0) |
317 | { | 317 | { |
318 | void *ptr = RemoveNode(p, i1); | 318 | void *ptr = Ppmd7_RemoveNode(p, i1); |
319 | MyMem12Cpy(ptr, oldPtr, newNU); | 319 | MEM_12_CPY(ptr, oldPtr, newNU) |
320 | InsertNode(p, oldPtr, i0); | 320 | Ppmd7_InsertNode(p, oldPtr, i0); |
321 | return ptr; | 321 | return ptr; |
322 | } | 322 | } |
323 | SplitBlock(p, oldPtr, i0, i1); | 323 | Ppmd7_SplitBlock(p, oldPtr, i0, i1); |
324 | return oldPtr; | 324 | return oldPtr; |
325 | } | 325 | } |
326 | */ | 326 | */ |
@@ -329,14 +329,14 @@ static void *ShrinkUnits(CPpmd7 *p, void *oldPtr, unsigned oldNU, unsigned newNU | |||
329 | #define SUCCESSOR(p) Ppmd_GET_SUCCESSOR(p) | 329 | #define SUCCESSOR(p) Ppmd_GET_SUCCESSOR(p) |
330 | static void SetSuccessor(CPpmd_State *p, CPpmd_Void_Ref v) | 330 | static void SetSuccessor(CPpmd_State *p, CPpmd_Void_Ref v) |
331 | { | 331 | { |
332 | Ppmd_SET_SUCCESSOR(p, v); | 332 | Ppmd_SET_SUCCESSOR(p, v) |
333 | } | 333 | } |
334 | 334 | ||
335 | 335 | ||
336 | 336 | ||
337 | MY_NO_INLINE | 337 | Z7_NO_INLINE |
338 | static | 338 | static |
339 | void RestartModel(CPpmd7 *p) | 339 | void Ppmd7_RestartModel(CPpmd7 *p) |
340 | { | 340 | { |
341 | unsigned i, k; | 341 | unsigned i, k; |
342 | 342 | ||
@@ -352,8 +352,8 @@ void RestartModel(CPpmd7 *p) | |||
352 | p->PrevSuccess = 0; | 352 | p->PrevSuccess = 0; |
353 | 353 | ||
354 | { | 354 | { |
355 | CPpmd7_Context *mc = (CTX_PTR)(void *)(p->HiUnit -= UNIT_SIZE); /* AllocContext(p); */ | 355 | CPpmd7_Context *mc = (PPMD7_CTX_PTR)(void *)(p->HiUnit -= UNIT_SIZE); /* AllocContext(p); */ |
356 | CPpmd_State *s = (CPpmd_State *)p->LoUnit; /* AllocUnits(p, PPMD_NUM_INDEXES - 1); */ | 356 | CPpmd_State *s = (CPpmd_State *)p->LoUnit; /* Ppmd7_AllocUnits(p, PPMD_NUM_INDEXES - 1); */ |
357 | 357 | ||
358 | p->LoUnit += U2B(256 / 2); | 358 | p->LoUnit += U2B(256 / 2); |
359 | p->MaxContext = p->MinContext = mc; | 359 | p->MaxContext = p->MinContext = mc; |
@@ -391,7 +391,7 @@ void RestartModel(CPpmd7 *p) | |||
391 | { | 391 | { |
392 | unsigned m; | 392 | unsigned m; |
393 | UInt16 *dest = p->BinSumm[i] + k; | 393 | UInt16 *dest = p->BinSumm[i] + k; |
394 | UInt16 val = (UInt16)(PPMD_BIN_SCALE - kInitBinEsc[k] / (i + 2)); | 394 | const UInt16 val = (UInt16)(PPMD_BIN_SCALE - PPMD7_kInitBinEsc[k] / (i + 2)); |
395 | for (m = 0; m < 64; m += 8) | 395 | for (m = 0; m < 64; m += 8) |
396 | dest[m] = val; | 396 | dest[m] = val; |
397 | } | 397 | } |
@@ -423,13 +423,13 @@ void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder) | |||
423 | { | 423 | { |
424 | p->MaxOrder = maxOrder; | 424 | p->MaxOrder = maxOrder; |
425 | 425 | ||
426 | RestartModel(p); | 426 | Ppmd7_RestartModel(p); |
427 | } | 427 | } |
428 | 428 | ||
429 | 429 | ||
430 | 430 | ||
431 | /* | 431 | /* |
432 | CreateSuccessors() | 432 | Ppmd7_CreateSuccessors() |
433 | It's called when (FoundState->Successor) is RAW-Successor, | 433 | It's called when (FoundState->Successor) is RAW-Successor, |
434 | that is the link to position in Raw text. | 434 | that is the link to position in Raw text. |
435 | So we create Context records and write the links to | 435 | So we create Context records and write the links to |
@@ -445,10 +445,10 @@ void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder) | |||
445 | also it can return pointer to real context of same order, | 445 | also it can return pointer to real context of same order, |
446 | */ | 446 | */ |
447 | 447 | ||
448 | MY_NO_INLINE | 448 | Z7_NO_INLINE |
449 | static CTX_PTR CreateSuccessors(CPpmd7 *p) | 449 | static PPMD7_CTX_PTR Ppmd7_CreateSuccessors(CPpmd7 *p) |
450 | { | 450 | { |
451 | CTX_PTR c = p->MinContext; | 451 | PPMD7_CTX_PTR c = p->MinContext; |
452 | CPpmd_Byte_Ref upBranch = (CPpmd_Byte_Ref)SUCCESSOR(p->FoundState); | 452 | CPpmd_Byte_Ref upBranch = (CPpmd_Byte_Ref)SUCCESSOR(p->FoundState); |
453 | Byte newSym, newFreq; | 453 | Byte newSym, newFreq; |
454 | unsigned numPs = 0; | 454 | unsigned numPs = 0; |
@@ -522,15 +522,15 @@ static CTX_PTR CreateSuccessors(CPpmd7 *p) | |||
522 | 522 | ||
523 | do | 523 | do |
524 | { | 524 | { |
525 | CTX_PTR c1; | 525 | PPMD7_CTX_PTR c1; |
526 | /* = AllocContext(p); */ | 526 | /* = AllocContext(p); */ |
527 | if (p->HiUnit != p->LoUnit) | 527 | if (p->HiUnit != p->LoUnit) |
528 | c1 = (CTX_PTR)(void *)(p->HiUnit -= UNIT_SIZE); | 528 | c1 = (PPMD7_CTX_PTR)(void *)(p->HiUnit -= UNIT_SIZE); |
529 | else if (p->FreeList[0] != 0) | 529 | else if (p->FreeList[0] != 0) |
530 | c1 = (CTX_PTR)RemoveNode(p, 0); | 530 | c1 = (PPMD7_CTX_PTR)Ppmd7_RemoveNode(p, 0); |
531 | else | 531 | else |
532 | { | 532 | { |
533 | c1 = (CTX_PTR)AllocUnitsRare(p, 0); | 533 | c1 = (PPMD7_CTX_PTR)Ppmd7_AllocUnitsRare(p, 0); |
534 | if (!c1) | 534 | if (!c1) |
535 | return NULL; | 535 | return NULL; |
536 | } | 536 | } |
@@ -550,16 +550,16 @@ static CTX_PTR CreateSuccessors(CPpmd7 *p) | |||
550 | 550 | ||
551 | 551 | ||
552 | 552 | ||
553 | #define SwapStates(s) \ | 553 | #define SWAP_STATES(s) \ |
554 | { CPpmd_State tmp = s[0]; s[0] = s[-1]; s[-1] = tmp; } | 554 | { CPpmd_State tmp = s[0]; s[0] = s[-1]; s[-1] = tmp; } |
555 | 555 | ||
556 | 556 | ||
557 | void Ppmd7_UpdateModel(CPpmd7 *p); | 557 | void Ppmd7_UpdateModel(CPpmd7 *p); |
558 | MY_NO_INLINE | 558 | Z7_NO_INLINE |
559 | void Ppmd7_UpdateModel(CPpmd7 *p) | 559 | void Ppmd7_UpdateModel(CPpmd7 *p) |
560 | { | 560 | { |
561 | CPpmd_Void_Ref maxSuccessor, minSuccessor; | 561 | CPpmd_Void_Ref maxSuccessor, minSuccessor; |
562 | CTX_PTR c, mc; | 562 | PPMD7_CTX_PTR c, mc; |
563 | unsigned s0, ns; | 563 | unsigned s0, ns; |
564 | 564 | ||
565 | 565 | ||
@@ -592,7 +592,7 @@ void Ppmd7_UpdateModel(CPpmd7 *p) | |||
592 | 592 | ||
593 | if (s[0].Freq >= s[-1].Freq) | 593 | if (s[0].Freq >= s[-1].Freq) |
594 | { | 594 | { |
595 | SwapStates(s); | 595 | SWAP_STATES(s) |
596 | s--; | 596 | s--; |
597 | } | 597 | } |
598 | } | 598 | } |
@@ -610,10 +610,10 @@ void Ppmd7_UpdateModel(CPpmd7 *p) | |||
610 | { | 610 | { |
611 | /* MAX ORDER context */ | 611 | /* MAX ORDER context */ |
612 | /* (FoundState->Successor) is RAW-Successor. */ | 612 | /* (FoundState->Successor) is RAW-Successor. */ |
613 | p->MaxContext = p->MinContext = CreateSuccessors(p); | 613 | p->MaxContext = p->MinContext = Ppmd7_CreateSuccessors(p); |
614 | if (!p->MinContext) | 614 | if (!p->MinContext) |
615 | { | 615 | { |
616 | RestartModel(p); | 616 | Ppmd7_RestartModel(p); |
617 | return; | 617 | return; |
618 | } | 618 | } |
619 | SetSuccessor(p->FoundState, REF(p->MinContext)); | 619 | SetSuccessor(p->FoundState, REF(p->MinContext)); |
@@ -629,7 +629,7 @@ void Ppmd7_UpdateModel(CPpmd7 *p) | |||
629 | p->Text = text; | 629 | p->Text = text; |
630 | if (text >= p->UnitsStart) | 630 | if (text >= p->UnitsStart) |
631 | { | 631 | { |
632 | RestartModel(p); | 632 | Ppmd7_RestartModel(p); |
633 | return; | 633 | return; |
634 | } | 634 | } |
635 | maxSuccessor = REF(text); | 635 | maxSuccessor = REF(text); |
@@ -645,10 +645,10 @@ void Ppmd7_UpdateModel(CPpmd7 *p) | |||
645 | if (minSuccessor <= maxSuccessor) | 645 | if (minSuccessor <= maxSuccessor) |
646 | { | 646 | { |
647 | // minSuccessor is RAW-Successor. So we will create real contexts records: | 647 | // minSuccessor is RAW-Successor. So we will create real contexts records: |
648 | CTX_PTR cs = CreateSuccessors(p); | 648 | PPMD7_CTX_PTR cs = Ppmd7_CreateSuccessors(p); |
649 | if (!cs) | 649 | if (!cs) |
650 | { | 650 | { |
651 | RestartModel(p); | 651 | Ppmd7_RestartModel(p); |
652 | return; | 652 | return; |
653 | } | 653 | } |
654 | minSuccessor = REF(cs); | 654 | minSuccessor = REF(cs); |
@@ -715,16 +715,16 @@ void Ppmd7_UpdateModel(CPpmd7 *p) | |||
715 | unsigned i = U2I(oldNU); | 715 | unsigned i = U2I(oldNU); |
716 | if (i != U2I((size_t)oldNU + 1)) | 716 | if (i != U2I((size_t)oldNU + 1)) |
717 | { | 717 | { |
718 | void *ptr = AllocUnits(p, i + 1); | 718 | void *ptr = Ppmd7_AllocUnits(p, i + 1); |
719 | void *oldPtr; | 719 | void *oldPtr; |
720 | if (!ptr) | 720 | if (!ptr) |
721 | { | 721 | { |
722 | RestartModel(p); | 722 | Ppmd7_RestartModel(p); |
723 | return; | 723 | return; |
724 | } | 724 | } |
725 | oldPtr = STATS(c); | 725 | oldPtr = STATS(c); |
726 | MyMem12Cpy(ptr, oldPtr, oldNU); | 726 | MEM_12_CPY(ptr, oldPtr, oldNU) |
727 | InsertNode(p, oldPtr, i); | 727 | Ppmd7_InsertNode(p, oldPtr, i); |
728 | c->Union4.Stats = STATS_REF(ptr); | 728 | c->Union4.Stats = STATS_REF(ptr); |
729 | } | 729 | } |
730 | } | 730 | } |
@@ -739,10 +739,10 @@ void Ppmd7_UpdateModel(CPpmd7 *p) | |||
739 | else | 739 | else |
740 | { | 740 | { |
741 | // instead of One-symbol context we create 2-symbol context | 741 | // instead of One-symbol context we create 2-symbol context |
742 | CPpmd_State *s = (CPpmd_State*)AllocUnits(p, 0); | 742 | CPpmd_State *s = (CPpmd_State*)Ppmd7_AllocUnits(p, 0); |
743 | if (!s) | 743 | if (!s) |
744 | { | 744 | { |
745 | RestartModel(p); | 745 | Ppmd7_RestartModel(p); |
746 | return; | 746 | return; |
747 | } | 747 | } |
748 | { | 748 | { |
@@ -795,8 +795,8 @@ void Ppmd7_UpdateModel(CPpmd7 *p) | |||
795 | 795 | ||
796 | 796 | ||
797 | 797 | ||
798 | MY_NO_INLINE | 798 | Z7_NO_INLINE |
799 | static void Rescale(CPpmd7 *p) | 799 | static void Ppmd7_Rescale(CPpmd7 *p) |
800 | { | 800 | { |
801 | unsigned i, adder, sumFreq, escFreq; | 801 | unsigned i, adder, sumFreq, escFreq; |
802 | CPpmd_State *stats = STATS(p->MinContext); | 802 | CPpmd_State *stats = STATS(p->MinContext); |
@@ -885,7 +885,7 @@ static void Rescale(CPpmd7 *p) | |||
885 | *s = *stats; | 885 | *s = *stats; |
886 | s->Freq = (Byte)freq; // (freq <= 260 / 4) | 886 | s->Freq = (Byte)freq; // (freq <= 260 / 4) |
887 | p->FoundState = s; | 887 | p->FoundState = s; |
888 | InsertNode(p, stats, U2I(n0)); | 888 | Ppmd7_InsertNode(p, stats, U2I(n0)); |
889 | return; | 889 | return; |
890 | } | 890 | } |
891 | 891 | ||
@@ -899,13 +899,13 @@ static void Rescale(CPpmd7 *p) | |||
899 | { | 899 | { |
900 | if (p->FreeList[i1] != 0) | 900 | if (p->FreeList[i1] != 0) |
901 | { | 901 | { |
902 | void *ptr = RemoveNode(p, i1); | 902 | void *ptr = Ppmd7_RemoveNode(p, i1); |
903 | p->MinContext->Union4.Stats = STATS_REF(ptr); | 903 | p->MinContext->Union4.Stats = STATS_REF(ptr); |
904 | MyMem12Cpy(ptr, (const void *)stats, n1); | 904 | MEM_12_CPY(ptr, (const void *)stats, n1) |
905 | InsertNode(p, stats, i0); | 905 | Ppmd7_InsertNode(p, stats, i0); |
906 | } | 906 | } |
907 | else | 907 | else |
908 | SplitBlock(p, stats, i0, i1); | 908 | Ppmd7_SplitBlock(p, stats, i0, i1); |
909 | } | 909 | } |
910 | } | 910 | } |
911 | } | 911 | } |
@@ -948,9 +948,9 @@ CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *escFreq) | |||
948 | } | 948 | } |
949 | 949 | ||
950 | 950 | ||
951 | static void NextContext(CPpmd7 *p) | 951 | static void Ppmd7_NextContext(CPpmd7 *p) |
952 | { | 952 | { |
953 | CTX_PTR c = CTX(SUCCESSOR(p->FoundState)); | 953 | PPMD7_CTX_PTR c = CTX(SUCCESSOR(p->FoundState)); |
954 | if (p->OrderFall == 0 && (const Byte *)c > p->Text) | 954 | if (p->OrderFall == 0 && (const Byte *)c > p->Text) |
955 | p->MaxContext = p->MinContext = c; | 955 | p->MaxContext = p->MinContext = c; |
956 | else | 956 | else |
@@ -967,12 +967,12 @@ void Ppmd7_Update1(CPpmd7 *p) | |||
967 | s->Freq = (Byte)freq; | 967 | s->Freq = (Byte)freq; |
968 | if (freq > s[-1].Freq) | 968 | if (freq > s[-1].Freq) |
969 | { | 969 | { |
970 | SwapStates(s); | 970 | SWAP_STATES(s) |
971 | p->FoundState = --s; | 971 | p->FoundState = --s; |
972 | if (freq > MAX_FREQ) | 972 | if (freq > MAX_FREQ) |
973 | Rescale(p); | 973 | Ppmd7_Rescale(p); |
974 | } | 974 | } |
975 | NextContext(p); | 975 | Ppmd7_NextContext(p); |
976 | } | 976 | } |
977 | 977 | ||
978 | 978 | ||
@@ -988,8 +988,8 @@ void Ppmd7_Update1_0(CPpmd7 *p) | |||
988 | freq += 4; | 988 | freq += 4; |
989 | s->Freq = (Byte)freq; | 989 | s->Freq = (Byte)freq; |
990 | if (freq > MAX_FREQ) | 990 | if (freq > MAX_FREQ) |
991 | Rescale(p); | 991 | Ppmd7_Rescale(p); |
992 | NextContext(p); | 992 | Ppmd7_NextContext(p); |
993 | } | 993 | } |
994 | 994 | ||
995 | 995 | ||
@@ -1000,7 +1000,7 @@ void Ppmd7_UpdateBin(CPpmd7 *p) | |||
1000 | p->FoundState->Freq = (Byte)(freq + (freq < 128)); | 1000 | p->FoundState->Freq = (Byte)(freq + (freq < 128)); |
1001 | p->PrevSuccess = 1; | 1001 | p->PrevSuccess = 1; |
1002 | p->RunLength++; | 1002 | p->RunLength++; |
1003 | NextContext(p); | 1003 | Ppmd7_NextContext(p); |
1004 | } | 1004 | } |
1005 | */ | 1005 | */ |
1006 | 1006 | ||
@@ -1013,7 +1013,7 @@ void Ppmd7_Update2(CPpmd7 *p) | |||
1013 | p->MinContext->Union2.SummFreq = (UInt16)(p->MinContext->Union2.SummFreq + 4); | 1013 | p->MinContext->Union2.SummFreq = (UInt16)(p->MinContext->Union2.SummFreq + 4); |
1014 | s->Freq = (Byte)freq; | 1014 | s->Freq = (Byte)freq; |
1015 | if (freq > MAX_FREQ) | 1015 | if (freq > MAX_FREQ) |
1016 | Rescale(p); | 1016 | Ppmd7_Rescale(p); |
1017 | Ppmd7_UpdateModel(p); | 1017 | Ppmd7_UpdateModel(p); |
1018 | } | 1018 | } |
1019 | 1019 | ||
@@ -1042,8 +1042,8 @@ Last UNIT of array at offset (Size - 12) is root order-0 CPpmd7_Context record. | |||
1042 | The code can free UNITs memory blocks that were allocated to store CPpmd_State vectors. | 1042 | The code can free UNITs memory blocks that were allocated to store CPpmd_State vectors. |
1043 | The code doesn't free UNITs allocated for CPpmd7_Context records. | 1043 | The code doesn't free UNITs allocated for CPpmd7_Context records. |
1044 | 1044 | ||
1045 | The code calls RestartModel(), when there is no free memory for allocation. | 1045 | The code calls Ppmd7_RestartModel(), when there is no free memory for allocation. |
1046 | And RestartModel() changes the state to orignal start state, with full free block. | 1046 | And Ppmd7_RestartModel() changes the state to orignal start state, with full free block. |
1047 | 1047 | ||
1048 | 1048 | ||
1049 | The code allocates UNITs with the following order: | 1049 | The code allocates UNITs with the following order: |
@@ -1051,14 +1051,14 @@ The code allocates UNITs with the following order: | |||
1051 | Allocation of 1 UNIT for Context record | 1051 | Allocation of 1 UNIT for Context record |
1052 | - from free space (HiUnit) down to (LoUnit) | 1052 | - from free space (HiUnit) down to (LoUnit) |
1053 | - from FreeList[0] | 1053 | - from FreeList[0] |
1054 | - AllocUnitsRare() | 1054 | - Ppmd7_AllocUnitsRare() |
1055 | 1055 | ||
1056 | AllocUnits() for CPpmd_State vectors: | 1056 | Ppmd7_AllocUnits() for CPpmd_State vectors: |
1057 | - from FreeList[i] | 1057 | - from FreeList[i] |
1058 | - from free space (LoUnit) up to (HiUnit) | 1058 | - from free space (LoUnit) up to (HiUnit) |
1059 | - AllocUnitsRare() | 1059 | - Ppmd7_AllocUnitsRare() |
1060 | 1060 | ||
1061 | AllocUnitsRare() | 1061 | Ppmd7_AllocUnitsRare() |
1062 | - if (GlueCount == 0) | 1062 | - if (GlueCount == 0) |
1063 | { Glue lists, GlueCount = 255, allocate from FreeList[i]] } | 1063 | { Glue lists, GlueCount = 255, allocate from FreeList[i]] } |
1064 | - loop for all higher sized FreeList[...] lists | 1064 | - loop for all higher sized FreeList[...] lists |
@@ -1093,8 +1093,8 @@ The PPMd code tries to fulfill the condition: | |||
1093 | We have (Sum(Stats[].Freq) <= 256 * 124), because of (MAX_FREQ = 124) | 1093 | We have (Sum(Stats[].Freq) <= 256 * 124), because of (MAX_FREQ = 124) |
1094 | So (4 = 128 - 124) is average reserve for Escape_Freq for each symbol. | 1094 | So (4 = 128 - 124) is average reserve for Escape_Freq for each symbol. |
1095 | If (CPpmd_State::Freq) is not aligned for 4, the reserve can be 5, 6 or 7. | 1095 | If (CPpmd_State::Freq) is not aligned for 4, the reserve can be 5, 6 or 7. |
1096 | SummFreq and Escape_Freq can be changed in Rescale() and *Update*() functions. | 1096 | SummFreq and Escape_Freq can be changed in Ppmd7_Rescale() and *Update*() functions. |
1097 | Rescale() can remove symbols only from max-order contexts. So Escape_Freq can increase after multiple calls of Rescale() for | 1097 | Ppmd7_Rescale() can remove symbols only from max-order contexts. So Escape_Freq can increase after multiple calls of Ppmd7_Rescale() for |
1098 | max-order context. | 1098 | max-order context. |
1099 | 1099 | ||
1100 | When the PPMd code still break (Total <= RC::Range) condition in range coder, | 1100 | When the PPMd code still break (Total <= RC::Range) condition in range coder, |
@@ -1102,3 +1102,21 @@ we have two ways to resolve that problem: | |||
1102 | 1) we can report error, if we want to keep compatibility with original PPMd code that has no fix for such cases. | 1102 | 1) we can report error, if we want to keep compatibility with original PPMd code that has no fix for such cases. |
1103 | 2) we can reduce (Total) value to (RC::Range) by reducing (Escape_Freq) part of (Total) value. | 1103 | 2) we can reduce (Total) value to (RC::Range) by reducing (Escape_Freq) part of (Total) value. |
1104 | */ | 1104 | */ |
1105 | |||
1106 | #undef MAX_FREQ | ||
1107 | #undef UNIT_SIZE | ||
1108 | #undef U2B | ||
1109 | #undef U2I | ||
1110 | #undef I2U | ||
1111 | #undef I2U_UInt16 | ||
1112 | #undef REF | ||
1113 | #undef STATS_REF | ||
1114 | #undef CTX | ||
1115 | #undef STATS | ||
1116 | #undef ONE_STATE | ||
1117 | #undef SUFFIX | ||
1118 | #undef NODE | ||
1119 | #undef EMPTY_NODE | ||
1120 | #undef MEM_12_CPY | ||
1121 | #undef SUCCESSOR | ||
1122 | #undef SWAP_STATES | ||