]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellDebug1CommandsLib/Compress.c
remove unused variable.
[mirror_edk2.git] / ShellPkg / Library / UefiShellDebug1CommandsLib / Compress.c
CommitLineData
5d73d92f 1/** @file\r
2 Main file for compression routine.\r
3\r
4 Compression routine. The compression algorithm is a mixture of\r
5 LZ77 and Huffman coding. LZ77 transforms the source data into a\r
6 sequence of Original Characters and Pointers to repeated strings.\r
7 This sequence is further divided into Blocks and Huffman codings\r
8 are applied to each Block.\r
9\r
3737ac2b 10 Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>\r
5d73d92f 11 This program and the accompanying materials\r
12 are licensed and made available under the terms and conditions of the BSD License\r
13 which accompanies this distribution. The full text of the license may be found at\r
14 http://opensource.org/licenses/bsd-license.php\r
15\r
16 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
17 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
18\r
19**/\r
20\r
21#include <Library/MemoryAllocationLib.h>\r
22#include <Library/BaseMemoryLib.h>\r
23#include <Library/DebugLib.h>\r
24#include <ShellBase.h>\r
25\r
26//\r
27// Macro Definitions\r
28//\r
29typedef INT16 NODE;\r
30#define UINT8_MAX 0xff\r
31#define UINT8_BIT 8\r
32#define THRESHOLD 3\r
33#define INIT_CRC 0\r
34#define WNDBIT 13\r
35#define WNDSIZ (1U << WNDBIT)\r
36#define MAXMATCH 256\r
37#define BLKSIZ (1U << 14) // 16 * 1024U\r
38#define PERC_FLAG 0x8000U\r
39#define CODE_BIT 16\r
40#define NIL 0\r
41#define MAX_HASH_VAL (3 * WNDSIZ + (WNDSIZ / 512 + 1) * UINT8_MAX)\r
3737ac2b 42#define HASH(LoopVar7, LoopVar5) ((LoopVar7) + ((LoopVar5) << (WNDBIT - 9)) + WNDSIZ * 2)\r
5d73d92f 43#define CRCPOLY 0xA001\r
3737ac2b 44#define UPDATE_CRC(LoopVar5) mCrc = mCrcTable[(mCrc ^ (LoopVar5)) & 0xFF] ^ (mCrc >> UINT8_BIT)\r
5d73d92f 45\r
46//\r
47// C: the Char&Len Set; P: the Position Set; T: the exTra Set\r
48//\r
49#define NC (UINT8_MAX + MAXMATCH + 2 - THRESHOLD)\r
50#define CBIT 9\r
51#define NP (WNDBIT + 1)\r
52#define PBIT 4\r
53#define NT (CODE_BIT + 3)\r
54#define TBIT 5\r
55#if NT > NP\r
56 #define NPT NT\r
57#else\r
58 #define NPT NP\r
59#endif\r
60//\r
61// Function Prototypes\r
62//\r
63\r
64/**\r
65 Put a dword to output stream\r
66\r
67 @param[in] Data The dword to put.\r
68**/\r
69VOID\r
70EFIAPI\r
71PutDword(\r
72 IN UINT32 Data\r
73 );\r
74\r
5d73d92f 75//\r
76// Global Variables\r
77//\r
3737ac2b 78STATIC UINT8 *mSrc;\r
79STATIC UINT8 *mDst;\r
80STATIC UINT8 *mSrcUpperLimit;\r
81STATIC UINT8 *mDstUpperLimit;\r
82\r
83STATIC UINT8 *mLevel;\r
84STATIC UINT8 *mText;\r
85STATIC UINT8 *mChildCount;\r
86STATIC UINT8 *mBuf;\r
87STATIC UINT8 mCLen[NC];\r
88STATIC UINT8 mPTLen[NPT];\r
89STATIC UINT8 *mLen;\r
5d73d92f 90STATIC INT16 mHeap[NC + 1];\r
3737ac2b 91STATIC INT32 mRemainder;\r
92STATIC INT32 mMatchLen;\r
93STATIC INT32 mBitCount;\r
94STATIC INT32 mHeapSize;\r
95STATIC INT32 mTempInt32;\r
96STATIC UINT32 mBufSiz = 0;\r
97STATIC UINT32 mOutputPos;\r
98STATIC UINT32 mOutputMask;\r
99STATIC UINT32 mSubBitBuf;\r
100STATIC UINT32 mCrc;\r
101STATIC UINT32 mCompSize;\r
102STATIC UINT32 mOrigSize;\r
103\r
104STATIC UINT16 *mFreq;\r
105STATIC UINT16 *mSortPtr;\r
106STATIC UINT16 mLenCnt[17];\r
107STATIC UINT16 mLeft[2 * NC - 1];\r
108STATIC UINT16 mRight[2 * NC - 1];\r
109STATIC UINT16 mCrcTable[UINT8_MAX + 1];\r
110STATIC UINT16 mCFreq[2 * NC - 1];\r
3737ac2b 111STATIC UINT16 mCCode[NC];\r
112STATIC UINT16 mPFreq[2 * NP - 1];\r
113STATIC UINT16 mPTCode[NPT];\r
114STATIC UINT16 mTFreq[2 * NT - 1];\r
115\r
116STATIC NODE mPos;\r
117STATIC NODE mMatchPos;\r
118STATIC NODE mAvail;\r
119STATIC NODE *mPosition;\r
120STATIC NODE *mParent;\r
121STATIC NODE *mPrev;\r
122STATIC NODE *mNext = NULL;\r
123INT32 mHuffmanDepth = 0;\r
5d73d92f 124\r
5d73d92f 125/**\r
3737ac2b 126 Make a CRC table.\r
5d73d92f 127\r
5d73d92f 128**/\r
3737ac2b 129VOID\r
5d73d92f 130EFIAPI\r
3737ac2b 131MakeCrcTable (\r
132 VOID\r
5d73d92f 133 )\r
134{\r
3737ac2b 135 UINT32 LoopVar1;\r
5d73d92f 136\r
3737ac2b 137 UINT32 LoopVar2;\r
5d73d92f 138\r
3737ac2b 139 UINT32 LoopVar4;\r
5d73d92f 140\r
3737ac2b 141 for (LoopVar1 = 0; LoopVar1 <= UINT8_MAX; LoopVar1++) {\r
142 LoopVar4 = LoopVar1;\r
143 for (LoopVar2 = 0; LoopVar2 < UINT8_BIT; LoopVar2++) {\r
144 if ((LoopVar4 & 1) != 0) {\r
145 LoopVar4 = (LoopVar4 >> 1) ^ CRCPOLY;\r
146 } else {\r
147 LoopVar4 >>= 1;\r
148 }\r
149 }\r
5d73d92f 150\r
3737ac2b 151 mCrcTable[LoopVar1] = (UINT16) LoopVar4;\r
5d73d92f 152 }\r
5d73d92f 153}\r
154\r
155/**\r
156 Put a dword to output stream\r
157\r
158 @param[in] Data The dword to put.\r
159**/\r
160VOID\r
161EFIAPI\r
162PutDword (\r
163 IN UINT32 Data\r
164 )\r
165{\r
166 if (mDst < mDstUpperLimit) {\r
167 *mDst++ = (UINT8) (((UINT8) (Data)) & 0xff);\r
168 }\r
169\r
170 if (mDst < mDstUpperLimit) {\r
171 *mDst++ = (UINT8) (((UINT8) (Data >> 0x08)) & 0xff);\r
172 }\r
173\r
174 if (mDst < mDstUpperLimit) {\r
175 *mDst++ = (UINT8) (((UINT8) (Data >> 0x10)) & 0xff);\r
176 }\r
177\r
178 if (mDst < mDstUpperLimit) {\r
179 *mDst++ = (UINT8) (((UINT8) (Data >> 0x18)) & 0xff);\r
180 }\r
181}\r
182\r
3737ac2b 183/**\r
184 Allocate memory spaces for data structures used in compression process.\r
185 \r
186 @retval EFI_SUCCESS Memory was allocated successfully.\r
187 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
188**/\r
5d73d92f 189EFI_STATUS\r
190EFIAPI\r
191AllocateMemory (\r
192 VOID\r
193 )\r
5d73d92f 194{\r
195 mText = AllocateZeroPool (WNDSIZ * 2 + MAXMATCH);\r
3737ac2b 196 mLevel = AllocateZeroPool ((WNDSIZ + UINT8_MAX + 1) * sizeof (*mLevel));\r
197 mChildCount = AllocateZeroPool ((WNDSIZ + UINT8_MAX + 1) * sizeof (*mChildCount));\r
198 mPosition = AllocateZeroPool ((WNDSIZ + UINT8_MAX + 1) * sizeof (*mPosition));\r
199 mParent = AllocateZeroPool (WNDSIZ * 2 * sizeof (*mParent));\r
200 mPrev = AllocateZeroPool (WNDSIZ * 2 * sizeof (*mPrev));\r
201 mNext = AllocateZeroPool ((MAX_HASH_VAL + 1) * sizeof (*mNext));\r
5d73d92f 202\r
203 mBufSiz = BLKSIZ;\r
3737ac2b 204 mBuf = AllocateZeroPool (mBufSiz);\r
5d73d92f 205 while (mBuf == NULL) {\r
206 mBufSiz = (mBufSiz / 10U) * 9U;\r
207 if (mBufSiz < 4 * 1024U) {\r
208 return EFI_OUT_OF_RESOURCES;\r
209 }\r
210\r
3737ac2b 211 mBuf = AllocateZeroPool (mBufSiz);\r
5d73d92f 212 }\r
213\r
214 mBuf[0] = 0;\r
215\r
216 return EFI_SUCCESS;\r
217}\r
218\r
3737ac2b 219/**\r
220 Called when compression is completed to free memory previously allocated.\r
221\r
222**/\r
223VOID\r
5d73d92f 224EFIAPI\r
225FreeMemory (\r
226 VOID\r
227 )\r
5d73d92f 228{\r
229 SHELL_FREE_NON_NULL (mText);\r
230 SHELL_FREE_NON_NULL (mLevel);\r
231 SHELL_FREE_NON_NULL (mChildCount);\r
232 SHELL_FREE_NON_NULL (mPosition);\r
233 SHELL_FREE_NON_NULL (mParent);\r
234 SHELL_FREE_NON_NULL (mPrev);\r
235 SHELL_FREE_NON_NULL (mNext);\r
236 SHELL_FREE_NON_NULL (mBuf);\r
237}\r
238\r
3737ac2b 239/**\r
240 Initialize String Info Log data structures\r
241\r
242**/\r
5d73d92f 243VOID\r
244EFIAPI\r
245InitSlide (\r
246 VOID\r
247 )\r
5d73d92f 248{\r
3737ac2b 249 NODE LoopVar1;\r
5d73d92f 250\r
251 SetMem (mLevel + WNDSIZ, (UINT8_MAX + 1) * sizeof (UINT8), 1);\r
252 SetMem (mPosition + WNDSIZ, (UINT8_MAX + 1) * sizeof (NODE), 0);\r
253\r
254 SetMem (mParent + WNDSIZ, WNDSIZ * sizeof (NODE), 0);\r
255\r
256 mAvail = 1;\r
3737ac2b 257 for (LoopVar1 = 1; LoopVar1 < WNDSIZ - 1; LoopVar1++) {\r
258 mNext[LoopVar1] = (NODE) (LoopVar1 + 1);\r
5d73d92f 259 }\r
260\r
261 mNext[WNDSIZ - 1] = NIL;\r
262 SetMem (mNext + WNDSIZ * 2, (MAX_HASH_VAL - WNDSIZ * 2 + 1) * sizeof (NODE), 0);\r
263}\r
264\r
3737ac2b 265/**\r
5d73d92f 266 Find child node given the parent node and the edge character\r
267\r
3737ac2b 268 @param[in] LoopVar6 The parent node.\r
269 @param[in] LoopVar5 The edge character.\r
5d73d92f 270\r
3737ac2b 271 @return The child node.\r
272 @retval NIL(Zero) No child could be found.\r
5d73d92f 273\r
274**/\r
3737ac2b 275NODE\r
276EFIAPI\r
277Child (\r
278 IN NODE LoopVar6,\r
279 IN UINT8 LoopVar5\r
280 )\r
5d73d92f 281{\r
3737ac2b 282 NODE LoopVar4;\r
5d73d92f 283\r
3737ac2b 284 LoopVar4 = mNext[HASH (LoopVar6, LoopVar5)];\r
285 mParent[NIL] = LoopVar6; /* sentinel */\r
286 while (mParent[LoopVar4] != LoopVar6) {\r
287 LoopVar4 = mNext[LoopVar4];\r
5d73d92f 288 }\r
289\r
3737ac2b 290 return LoopVar4;\r
5d73d92f 291}\r
292\r
3737ac2b 293/**\r
294 Create a new child for a given parent node.\r
295\r
296 @param[in] LoopVar6 The parent node.\r
297 @param[in] LoopVar5 The edge character.\r
298 @param[in] LoopVar4 The child node.\r
299**/\r
5d73d92f 300VOID\r
301EFIAPI\r
302MakeChild (\r
3737ac2b 303 IN NODE LoopVar6,\r
304 IN UINT8 LoopVar5,\r
305 IN NODE LoopVar4\r
5d73d92f 306 )\r
5d73d92f 307{\r
3737ac2b 308 NODE LoopVar12;\r
309\r
310 NODE LoopVar10;\r
311\r
312 LoopVar12 = (NODE) HASH (LoopVar6, LoopVar5);\r
313 LoopVar10 = mNext[LoopVar12];\r
314 mNext[LoopVar12] = LoopVar4;\r
315 mNext[LoopVar4] = LoopVar10;\r
316 mPrev[LoopVar10] = LoopVar4;\r
317 mPrev[LoopVar4] = LoopVar12;\r
318 mParent[LoopVar4] = LoopVar6;\r
319 mChildCount[LoopVar6]++;\r
5d73d92f 320}\r
321\r
3737ac2b 322/**\r
323 Split a node.\r
324\r
325 @param[in] Old The node to split.\r
326**/\r
5d73d92f 327VOID\r
328EFIAPI\r
329Split (\r
3737ac2b 330 IN NODE Old\r
5d73d92f 331 )\r
5d73d92f 332{\r
333 NODE New;\r
334\r
3737ac2b 335 NODE LoopVar10;\r
5d73d92f 336\r
337 New = mAvail;\r
338 mAvail = mNext[New];\r
339 mChildCount[New] = 0;\r
3737ac2b 340 LoopVar10 = mPrev[Old];\r
341 mPrev[New] = LoopVar10;\r
342 mNext[LoopVar10] = New;\r
343 LoopVar10 = mNext[Old];\r
344 mNext[New] = LoopVar10;\r
345 mPrev[LoopVar10] = New;\r
5d73d92f 346 mParent[New] = mParent[Old];\r
347 mLevel[New] = (UINT8) mMatchLen;\r
348 mPosition[New] = mPos;\r
349 MakeChild (New, mText[mMatchPos + mMatchLen], Old);\r
350 MakeChild (New, mText[mPos + mMatchLen], mPos);\r
351}\r
352\r
3737ac2b 353/**\r
354 Insert string info for current position into the String Info Log.\r
355\r
356**/\r
5d73d92f 357VOID\r
358EFIAPI\r
359InsertNode (\r
360 VOID\r
361 )\r
5d73d92f 362{\r
3737ac2b 363 NODE LoopVar6;\r
5d73d92f 364\r
3737ac2b 365 NODE LoopVar4;\r
5d73d92f 366\r
3737ac2b 367 NODE LoopVar2;\r
5d73d92f 368\r
3737ac2b 369 NODE LoopVar10;\r
370 UINT8 LoopVar5;\r
371 UINT8 *TempString3;\r
372 UINT8 *TempString2;\r
5d73d92f 373\r
374 if (mMatchLen >= 4) {\r
375 //\r
376 // We have just got a long match, the target tree\r
377 // can be located by MatchPos + 1. Travese the tree\r
378 // from bottom up to get to a proper starting point.\r
379 // The usage of PERC_FLAG ensures proper node deletion\r
380 // in DeleteNode() later.\r
381 //\r
382 mMatchLen--;\r
3737ac2b 383 LoopVar4 = (NODE) ((mMatchPos + 1) | WNDSIZ);\r
384 LoopVar6 = mParent[LoopVar4];\r
385 while (LoopVar6 == NIL) {\r
386 LoopVar4 = mNext[LoopVar4];\r
387 LoopVar6 = mParent[LoopVar4];\r
5d73d92f 388 }\r
389\r
3737ac2b 390 while (mLevel[LoopVar6] >= mMatchLen) {\r
391 LoopVar4 = LoopVar6;\r
392 LoopVar6 = mParent[LoopVar6];\r
5d73d92f 393 }\r
394\r
3737ac2b 395 LoopVar10 = LoopVar6;\r
396 while (mPosition[LoopVar10] < 0) {\r
397 mPosition[LoopVar10] = mPos;\r
398 LoopVar10 = mParent[LoopVar10];\r
5d73d92f 399 }\r
400\r
3737ac2b 401 if (LoopVar10 < WNDSIZ) {\r
402 mPosition[LoopVar10] = (NODE) (mPos | PERC_FLAG);\r
5d73d92f 403 }\r
404 } else {\r
405 //\r
406 // Locate the target tree\r
407 //\r
3737ac2b 408 LoopVar6 = (NODE) (mText[mPos] + WNDSIZ);\r
409 LoopVar5 = mText[mPos + 1];\r
410 LoopVar4 = Child (LoopVar6, LoopVar5);\r
411 if (LoopVar4 == NIL) {\r
412 MakeChild (LoopVar6, LoopVar5, mPos);\r
5d73d92f 413 mMatchLen = 1;\r
414 return ;\r
415 }\r
416\r
417 mMatchLen = 2;\r
418 }\r
419 //\r
420 // Traverse down the tree to find a match.\r
421 // Update Position value along the route.\r
422 // Node split or creation is involved.\r
423 //\r
424 for (;;) {\r
3737ac2b 425 if (LoopVar4 >= WNDSIZ) {\r
426 LoopVar2 = MAXMATCH;\r
427 mMatchPos = LoopVar4;\r
5d73d92f 428 } else {\r
3737ac2b 429 LoopVar2 = mLevel[LoopVar4];\r
430 mMatchPos = (NODE) (mPosition[LoopVar4] & ~PERC_FLAG);\r
5d73d92f 431 }\r
432\r
433 if (mMatchPos >= mPos) {\r
434 mMatchPos -= WNDSIZ;\r
435 }\r
436\r
3737ac2b 437 TempString3 = &mText[mPos + mMatchLen];\r
438 TempString2 = &mText[mMatchPos + mMatchLen];\r
439 while (mMatchLen < LoopVar2) {\r
440 if (*TempString3 != *TempString2) {\r
441 Split (LoopVar4);\r
5d73d92f 442 return ;\r
443 }\r
444\r
445 mMatchLen++;\r
3737ac2b 446 TempString3++;\r
447 TempString2++;\r
5d73d92f 448 }\r
449\r
450 if (mMatchLen >= MAXMATCH) {\r
451 break;\r
452 }\r
453\r
3737ac2b 454 mPosition[LoopVar4] = mPos;\r
455 LoopVar6 = LoopVar4;\r
456 LoopVar4 = Child (LoopVar6, *TempString3);\r
457 if (LoopVar4 == NIL) {\r
458 MakeChild (LoopVar6, *TempString3, mPos);\r
5d73d92f 459 return ;\r
460 }\r
461\r
462 mMatchLen++;\r
463 }\r
464\r
3737ac2b 465 LoopVar10 = mPrev[LoopVar4];\r
466 mPrev[mPos] = LoopVar10;\r
467 mNext[LoopVar10] = mPos;\r
468 LoopVar10 = mNext[LoopVar4];\r
469 mNext[mPos] = LoopVar10;\r
470 mPrev[LoopVar10] = mPos;\r
471 mParent[mPos] = LoopVar6;\r
472 mParent[LoopVar4] = NIL;\r
5d73d92f 473\r
474 //\r
475 // Special usage of 'next'\r
476 //\r
3737ac2b 477 mNext[LoopVar4] = mPos;\r
5d73d92f 478\r
479}\r
480\r
3737ac2b 481/**\r
482 Delete outdated string info. (The Usage of PERC_FLAG\r
483 ensures a clean deletion).\r
484\r
485**/\r
5d73d92f 486VOID\r
487EFIAPI\r
488DeleteNode (\r
489 VOID\r
490 )\r
5d73d92f 491{\r
3737ac2b 492 NODE LoopVar6;\r
5d73d92f 493\r
3737ac2b 494 NODE LoopVar4;\r
5d73d92f 495\r
3737ac2b 496 NODE LoopVar11;\r
5d73d92f 497\r
3737ac2b 498 NODE LoopVar10;\r
5d73d92f 499\r
3737ac2b 500 NODE LoopVar9;\r
5d73d92f 501\r
502 if (mParent[mPos] == NIL) {\r
503 return ;\r
504 }\r
505\r
3737ac2b 506 LoopVar4 = mPrev[mPos];\r
507 LoopVar11 = mNext[mPos];\r
508 mNext[LoopVar4] = LoopVar11;\r
509 mPrev[LoopVar11] = LoopVar4;\r
510 LoopVar4 = mParent[mPos];\r
5d73d92f 511 mParent[mPos] = NIL;\r
3737ac2b 512 if (LoopVar4 >= WNDSIZ) {\r
5d73d92f 513 return ;\r
514 }\r
515\r
3737ac2b 516 mChildCount[LoopVar4]--;\r
517 if (mChildCount[LoopVar4] > 1) {\r
5d73d92f 518 return ;\r
519 }\r
520\r
3737ac2b 521 LoopVar10 = (NODE) (mPosition[LoopVar4] & ~PERC_FLAG);\r
522 if (LoopVar10 >= mPos) {\r
523 LoopVar10 -= WNDSIZ;\r
5d73d92f 524 }\r
525\r
3737ac2b 526 LoopVar11 = LoopVar10;\r
527 LoopVar6 = mParent[LoopVar4];\r
528 LoopVar9 = mPosition[LoopVar6];\r
529 while ((LoopVar9 & PERC_FLAG) != 0){\r
530 LoopVar9 &= ~PERC_FLAG;\r
531 if (LoopVar9 >= mPos) {\r
532 LoopVar9 -= WNDSIZ;\r
5d73d92f 533 }\r
534\r
3737ac2b 535 if (LoopVar9 > LoopVar11) {\r
536 LoopVar11 = LoopVar9;\r
5d73d92f 537 }\r
538\r
3737ac2b 539 mPosition[LoopVar6] = (NODE) (LoopVar11 | WNDSIZ);\r
540 LoopVar6 = mParent[LoopVar6];\r
541 LoopVar9 = mPosition[LoopVar6];\r
5d73d92f 542 }\r
543\r
3737ac2b 544 if (LoopVar6 < WNDSIZ) {\r
545 if (LoopVar9 >= mPos) {\r
546 LoopVar9 -= WNDSIZ;\r
5d73d92f 547 }\r
548\r
3737ac2b 549 if (LoopVar9 > LoopVar11) {\r
550 LoopVar11 = LoopVar9;\r
5d73d92f 551 }\r
552\r
3737ac2b 553 mPosition[LoopVar6] = (NODE) (LoopVar11 | WNDSIZ | PERC_FLAG);\r
5d73d92f 554 }\r
555\r
3737ac2b 556 LoopVar11 = Child (LoopVar4, mText[LoopVar10 + mLevel[LoopVar4]]);\r
557 LoopVar10 = mPrev[LoopVar11];\r
558 LoopVar9 = mNext[LoopVar11];\r
559 mNext[LoopVar10] = LoopVar9;\r
560 mPrev[LoopVar9] = LoopVar10;\r
561 LoopVar10 = mPrev[LoopVar4];\r
562 mNext[LoopVar10] = LoopVar11;\r
563 mPrev[LoopVar11] = LoopVar10;\r
564 LoopVar10 = mNext[LoopVar4];\r
565 mPrev[LoopVar10] = LoopVar11;\r
566 mNext[LoopVar11] = LoopVar10;\r
567 mParent[LoopVar11] = mParent[LoopVar4];\r
568 mParent[LoopVar4] = NIL;\r
569 mNext[LoopVar4] = mAvail;\r
570 mAvail = LoopVar4;\r
5d73d92f 571}\r
572\r
3737ac2b 573/**\r
574 Read in source data\r
575\r
576 @param[out] LoopVar7 The buffer to hold the data.\r
577 @param[in] LoopVar8 The number of bytes to read.\r
578\r
579 @return The number of bytes actually read.\r
580**/\r
581INT32\r
5d73d92f 582EFIAPI\r
3737ac2b 583FreadCrc (\r
584 OUT UINT8 *LoopVar7,\r
585 IN INT32 LoopVar8\r
5d73d92f 586 )\r
3737ac2b 587{\r
588 INT32 LoopVar1;\r
5d73d92f 589\r
3737ac2b 590 for (LoopVar1 = 0; mSrc < mSrcUpperLimit && LoopVar1 < LoopVar8; LoopVar1++) {\r
591 *LoopVar7++ = *mSrc++;\r
592 }\r
5d73d92f 593\r
3737ac2b 594 LoopVar8 = LoopVar1;\r
595\r
596 LoopVar7 -= LoopVar8;\r
597 mOrigSize += LoopVar8;\r
598 LoopVar1--;\r
599 while (LoopVar1 >= 0) {\r
600 UPDATE_CRC (*LoopVar7++);\r
601 LoopVar1--;\r
602 }\r
5d73d92f 603\r
3737ac2b 604 return LoopVar8;\r
605}\r
5d73d92f 606\r
3737ac2b 607/**\r
608 Advance the current position (read in new data if needed).\r
609 Delete outdated string info. Find a match string for current position.\r
5d73d92f 610\r
611**/\r
3737ac2b 612VOID\r
613EFIAPI\r
614GetNextMatch (\r
615 VOID\r
616 )\r
5d73d92f 617{\r
3737ac2b 618 INT32 LoopVar8;\r
5d73d92f 619 VOID *Temp;\r
620\r
621 mRemainder--;\r
622 mPos++;\r
623 if (mPos == WNDSIZ * 2) {\r
3737ac2b 624 Temp = AllocateZeroPool (WNDSIZ + MAXMATCH);\r
5d73d92f 625 CopyMem (Temp, &mText[WNDSIZ], WNDSIZ + MAXMATCH);\r
626 CopyMem (&mText[0], Temp, WNDSIZ + MAXMATCH);\r
627 FreePool (Temp);\r
3737ac2b 628 LoopVar8 = FreadCrc (&mText[WNDSIZ + MAXMATCH], WNDSIZ);\r
629 mRemainder += LoopVar8;\r
5d73d92f 630 mPos = WNDSIZ;\r
631 }\r
632\r
633 DeleteNode ();\r
634 InsertNode ();\r
635}\r
636\r
3737ac2b 637/**\r
638 Send entry LoopVar1 down the queue.\r
639\r
640 @param[in] LoopVar1 The index of the item to move.\r
641**/\r
642VOID\r
5d73d92f 643EFIAPI\r
3737ac2b 644DownHeap (\r
645 IN INT32 i\r
5d73d92f 646 )\r
3737ac2b 647{\r
648 INT32 LoopVar1;\r
5d73d92f 649\r
3737ac2b 650 INT32 LoopVar2;\r
5d73d92f 651\r
3737ac2b 652 //\r
653 // priority queue: send i-th entry down heap\r
654 //\r
655 LoopVar2 = mHeap[i];\r
656 LoopVar1 = 2 * i;\r
657 while (LoopVar1 <= mHeapSize) {\r
658 if (LoopVar1 < mHeapSize && mFreq[mHeap[LoopVar1]] > mFreq[mHeap[LoopVar1 + 1]]) {\r
659 LoopVar1++;\r
660 }\r
661\r
662 if (mFreq[LoopVar2] <= mFreq[mHeap[LoopVar1]]) {\r
663 break;\r
664 }\r
5d73d92f 665\r
3737ac2b 666 mHeap[i] = mHeap[LoopVar1];\r
667 i = LoopVar1;\r
668 LoopVar1 = 2 * i;\r
669 }\r
5d73d92f 670\r
3737ac2b 671 mHeap[i] = (INT16) LoopVar2;\r
672}\r
5d73d92f 673\r
3737ac2b 674/**\r
675 Count the number of each code length for a Huffman tree.\r
5d73d92f 676\r
3737ac2b 677 @param[in] LoopVar1 The top node.\r
5d73d92f 678**/\r
3737ac2b 679VOID\r
680EFIAPI\r
681CountLen (\r
682 IN INT32 LoopVar1\r
683 )\r
5d73d92f 684{\r
3737ac2b 685 if (LoopVar1 < mTempInt32) {\r
686 mLenCnt[(mHuffmanDepth < 16) ? mHuffmanDepth : 16]++;\r
687 } else {\r
688 mHuffmanDepth++;\r
689 CountLen (mLeft[LoopVar1]);\r
690 CountLen (mRight[LoopVar1]);\r
691 mHuffmanDepth--;\r
5d73d92f 692 }\r
3737ac2b 693}\r
5d73d92f 694\r
3737ac2b 695/**\r
696 Create code length array for a Huffman tree.\r
5d73d92f 697\r
3737ac2b 698 @param[in] Root The root of the tree.\r
699**/\r
700VOID\r
701EFIAPI\r
702MakeLen (\r
703 IN INT32 Root\r
704 )\r
705{\r
706 INT32 LoopVar1;\r
5d73d92f 707\r
3737ac2b 708 INT32 LoopVar2;\r
709 UINT32 Cum;\r
5d73d92f 710\r
3737ac2b 711 for (LoopVar1 = 0; LoopVar1 <= 16; LoopVar1++) {\r
712 mLenCnt[LoopVar1] = 0;\r
5d73d92f 713 }\r
714\r
3737ac2b 715 CountLen (Root);\r
5d73d92f 716\r
3737ac2b 717 //\r
718 // Adjust the length count array so that\r
719 // no code will be generated longer than its designated length\r
720 //\r
721 Cum = 0;\r
722 for (LoopVar1 = 16; LoopVar1 > 0; LoopVar1--) {\r
723 Cum += mLenCnt[LoopVar1] << (16 - LoopVar1);\r
724 }\r
5d73d92f 725\r
3737ac2b 726 while (Cum != (1U << 16)) {\r
727 mLenCnt[16]--;\r
728 for (LoopVar1 = 15; LoopVar1 > 0; LoopVar1--) {\r
729 if (mLenCnt[LoopVar1] != 0) {\r
730 mLenCnt[LoopVar1]--;\r
731 mLenCnt[LoopVar1 + 1] += 2;\r
732 break;\r
5d73d92f 733 }\r
734 }\r
3737ac2b 735\r
736 Cum--;\r
5d73d92f 737 }\r
738\r
3737ac2b 739 for (LoopVar1 = 16; LoopVar1 > 0; LoopVar1--) {\r
740 LoopVar2 = mLenCnt[LoopVar1];\r
741 LoopVar2--;\r
742 while (LoopVar2 >= 0) {\r
743 mLen[*mSortPtr++] = (UINT8) LoopVar1;\r
744 LoopVar2--;\r
745 }\r
746 }\r
5d73d92f 747}\r
748\r
3737ac2b 749/**\r
750 Assign code to each symbol based on the code length array.\r
751 \r
752 @param[in] LoopVar8 The number of symbols.\r
753 @param[in] Len The code length array.\r
754 @param[out] Code The stores codes for each symbol.\r
755**/\r
5d73d92f 756VOID\r
757EFIAPI\r
3737ac2b 758MakeCode (\r
759 IN INT32 LoopVar8,\r
760 IN UINT8 Len[ ],\r
761 OUT UINT16 Code[ ]\r
5d73d92f 762 )\r
3737ac2b 763{\r
764 INT32 LoopVar1;\r
765 UINT16 Start[18];\r
5d73d92f 766\r
3737ac2b 767 Start[1] = 0;\r
768 for (LoopVar1 = 1; LoopVar1 <= 16; LoopVar1++) {\r
769 Start[LoopVar1 + 1] = (UINT16) ((Start[LoopVar1] + mLenCnt[LoopVar1]) << 1);\r
770 }\r
5d73d92f 771\r
3737ac2b 772 for (LoopVar1 = 0; LoopVar1 < LoopVar8; LoopVar1++) {\r
773 Code[LoopVar1] = Start[Len[LoopVar1]]++;\r
774 }\r
775}\r
776 \r
777/**\r
778 Generates Huffman codes given a frequency distribution of symbols.\r
5d73d92f 779\r
3737ac2b 780 @param[in] NParm The number of symbols.\r
781 @param[in] FreqParm The frequency of each symbol.\r
782 @param[out] LenParm The code length for each symbol.\r
783 @param[out] CodeParm The code for each symbol.\r
5d73d92f 784\r
3737ac2b 785 @return The root of the Huffman tree.\r
5d73d92f 786**/\r
3737ac2b 787INT32\r
788EFIAPI\r
789MakeTree (\r
790 IN INT32 NParm,\r
791 IN UINT16 FreqParm[ ],\r
792 OUT UINT8 LenParm[ ],\r
793 OUT UINT16 CodeParm[ ]\r
794 )\r
5d73d92f 795{\r
3737ac2b 796 INT32 LoopVar1;\r
5d73d92f 797\r
3737ac2b 798 INT32 LoopVar2;\r
5d73d92f 799\r
3737ac2b 800 INT32 LoopVar3;\r
5d73d92f 801\r
3737ac2b 802 INT32 Avail;\r
5d73d92f 803\r
3737ac2b 804 //\r
805 // make tree, calculate len[], return root\r
806 //\r
807 mTempInt32 = NParm;\r
808 mFreq = FreqParm;\r
809 mLen = LenParm;\r
810 Avail = mTempInt32;\r
811 mHeapSize = 0;\r
812 mHeap[1] = 0;\r
813 for (LoopVar1 = 0; LoopVar1 < mTempInt32; LoopVar1++) {\r
814 mLen[LoopVar1] = 0;\r
815 if ((mFreq[LoopVar1]) != 0) {\r
816 mHeapSize++;\r
817 mHeap[mHeapSize] = (INT16) LoopVar1;\r
818 }\r
5d73d92f 819 }\r
820\r
3737ac2b 821 if (mHeapSize < 2) {\r
822 CodeParm[mHeap[1]] = 0;\r
823 return mHeap[1];\r
5d73d92f 824 }\r
825\r
3737ac2b 826 for (LoopVar1 = mHeapSize / 2; LoopVar1 >= 1; LoopVar1--) {\r
827 //\r
828 // make priority queue\r
829 //\r
830 DownHeap (LoopVar1);\r
831 }\r
5d73d92f 832\r
3737ac2b 833 mSortPtr = CodeParm;\r
834 do {\r
835 LoopVar1 = mHeap[1];\r
836 if (LoopVar1 < mTempInt32) {\r
837 *mSortPtr++ = (UINT16) LoopVar1;\r
5d73d92f 838 }\r
5d73d92f 839\r
3737ac2b 840 mHeap[1] = mHeap[mHeapSize--];\r
841 DownHeap (1);\r
842 LoopVar2 = mHeap[1];\r
843 if (LoopVar2 < mTempInt32) {\r
844 *mSortPtr++ = (UINT16) LoopVar2;\r
845 }\r
5d73d92f 846\r
3737ac2b 847 LoopVar3 = Avail++;\r
848 mFreq[LoopVar3] = (UINT16) (mFreq[LoopVar1] + mFreq[LoopVar2]);\r
849 mHeap[1] = (INT16) LoopVar3;\r
850 DownHeap (1);\r
851 mLeft[LoopVar3] = (UINT16) LoopVar1;\r
852 mRight[LoopVar3] = (UINT16) LoopVar2;\r
853 } while (mHeapSize > 1);\r
5d73d92f 854\r
3737ac2b 855 mSortPtr = CodeParm;\r
856 MakeLen (LoopVar3);\r
857 MakeCode (NParm, LenParm, CodeParm);\r
5d73d92f 858\r
3737ac2b 859 //\r
860 // return root\r
861 //\r
862 return LoopVar3;\r
863}\r
5d73d92f 864\r
3737ac2b 865/**\r
866 Outputs rightmost LoopVar8 bits of x\r
5d73d92f 867\r
3737ac2b 868 @param[in] LoopVar8 The rightmost LoopVar8 bits of the data is used.\r
869 @param[in] x The data.\r
5d73d92f 870**/\r
3737ac2b 871VOID\r
872EFIAPI\r
873PutBits (\r
874 IN INT32 LoopVar8,\r
875 IN UINT32 x\r
876 )\r
5d73d92f 877{\r
3737ac2b 878 UINT8 Temp;\r
5d73d92f 879\r
3737ac2b 880 if (LoopVar8 < mBitCount) {\r
881 mSubBitBuf |= x << (mBitCount -= LoopVar8);\r
882 } else {\r
5d73d92f 883\r
3737ac2b 884 Temp = (UINT8)(mSubBitBuf | (x >> (LoopVar8 -= mBitCount)));\r
885 if (mDst < mDstUpperLimit) {\r
886 *mDst++ = Temp;\r
887 }\r
888 mCompSize++;\r
5d73d92f 889\r
3737ac2b 890 if (LoopVar8 < UINT8_BIT) {\r
891 mSubBitBuf = x << (mBitCount = UINT8_BIT - LoopVar8);\r
5d73d92f 892 } else {\r
5d73d92f 893\r
3737ac2b 894 Temp = (UINT8)(x >> (LoopVar8 - UINT8_BIT));\r
895 if (mDst < mDstUpperLimit) {\r
896 *mDst++ = Temp;\r
5d73d92f 897 }\r
3737ac2b 898 mCompSize++;\r
5d73d92f 899\r
3737ac2b 900 mSubBitBuf = x << (mBitCount = 2 * UINT8_BIT - LoopVar8);\r
5d73d92f 901 }\r
902 }\r
903}\r
904\r
3737ac2b 905/**\r
906 Encode a signed 32 bit number.\r
907\r
908 @param[in] LoopVar5 The number to encode.\r
909**/\r
5d73d92f 910VOID\r
911EFIAPI\r
3737ac2b 912EncodeC (\r
913 IN INT32 LoopVar5\r
5d73d92f 914 )\r
3737ac2b 915{\r
916 PutBits (mCLen[LoopVar5], mCCode[LoopVar5]);\r
917}\r
5d73d92f 918\r
3737ac2b 919/**\r
920 Encode a unsigned 32 bit number.\r
5d73d92f 921\r
3737ac2b 922 @param[in] LoopVar7 The number to encode.\r
923**/\r
924VOID\r
925EFIAPI\r
926EncodeP (\r
927 IN UINT32 LoopVar7\r
928 )\r
929{\r
930 UINT32 LoopVar5;\r
5d73d92f 931\r
3737ac2b 932 UINT32 LoopVar6;\r
5d73d92f 933\r
3737ac2b 934 LoopVar5 = 0;\r
935 LoopVar6 = LoopVar7;\r
936 while (LoopVar6 != 0) {\r
937 LoopVar6 >>= 1;\r
938 LoopVar5++;\r
939 }\r
940\r
941 PutBits (mPTLen[LoopVar5], mPTCode[LoopVar5]);\r
942 if (LoopVar5 > 1) {\r
943 PutBits(LoopVar5 - 1, LoopVar7 & (0xFFFFU >> (17 - LoopVar5)));\r
944 }\r
945}\r
946\r
947/**\r
948 Count the frequencies for the Extra Set.\r
5d73d92f 949\r
950**/\r
3737ac2b 951VOID\r
952EFIAPI\r
953CountTFreq (\r
954 VOID\r
955 )\r
5d73d92f 956{\r
3737ac2b 957 INT32 LoopVar1;\r
5d73d92f 958\r
3737ac2b 959 INT32 LoopVar3;\r
5d73d92f 960\r
3737ac2b 961 INT32 LoopVar8;\r
5d73d92f 962\r
963 INT32 Count;\r
964\r
3737ac2b 965 for (LoopVar1 = 0; LoopVar1 < NT; LoopVar1++) {\r
966 mTFreq[LoopVar1] = 0;\r
5d73d92f 967 }\r
968\r
3737ac2b 969 LoopVar8 = NC;\r
970 while (LoopVar8 > 0 && mCLen[LoopVar8 - 1] == 0) {\r
971 LoopVar8--;\r
972 }\r
973\r
974 LoopVar1 = 0;\r
975 while (LoopVar1 < LoopVar8) {\r
976 LoopVar3 = mCLen[LoopVar1++];\r
977 if (LoopVar3 == 0) {\r
5d73d92f 978 Count = 1;\r
3737ac2b 979 while (LoopVar1 < LoopVar8 && mCLen[LoopVar1] == 0) {\r
980 LoopVar1++;\r
5d73d92f 981 Count++;\r
982 }\r
983\r
984 if (Count <= 2) {\r
3737ac2b 985 mTFreq[0] = (UINT16) (mTFreq[0] + Count);\r
5d73d92f 986 } else if (Count <= 18) {\r
3737ac2b 987 mTFreq[1]++;\r
5d73d92f 988 } else if (Count == 19) {\r
3737ac2b 989 mTFreq[0]++;\r
990 mTFreq[1]++;\r
5d73d92f 991 } else {\r
3737ac2b 992 mTFreq[2]++;\r
5d73d92f 993 }\r
994 } else {\r
3737ac2b 995 ASSERT((LoopVar3+2)<(2 * NT - 1));\r
996 mTFreq[LoopVar3 + 2]++;\r
5d73d92f 997 }\r
998 }\r
999}\r
1000\r
3737ac2b 1001/**\r
1002 Outputs the code length array for the Extra Set or the Position Set.\r
5d73d92f 1003\r
3737ac2b 1004 @param[in] LoopVar8 The number of symbols.\r
1005 @param[in] nbit The number of bits needed to represent 'LoopVar8'.\r
1006 @param[in] Special The special symbol that needs to be take care of.\r
1007\r
1008**/\r
5d73d92f 1009VOID\r
1010EFIAPI\r
3737ac2b 1011WritePTLen (\r
1012 IN INT32 LoopVar8,\r
1013 IN INT32 nbit,\r
1014 IN INT32 Special\r
5d73d92f 1015 )\r
1016{\r
3737ac2b 1017 INT32 LoopVar1;\r
5d73d92f 1018\r
3737ac2b 1019 INT32 LoopVar3;\r
5d73d92f 1020\r
3737ac2b 1021 while (LoopVar8 > 0 && mPTLen[LoopVar8 - 1] == 0) {\r
1022 LoopVar8--;\r
5d73d92f 1023 }\r
1024\r
3737ac2b 1025 PutBits (nbit, LoopVar8);\r
1026 LoopVar1 = 0;\r
1027 while (LoopVar1 < LoopVar8) {\r
1028 LoopVar3 = mPTLen[LoopVar1++];\r
1029 if (LoopVar3 <= 6) {\r
1030 PutBits (3, LoopVar3);\r
1031 } else {\r
1032 PutBits (LoopVar3 - 3, (1U << (LoopVar3 - 3)) - 2);\r
1033 }\r
1034\r
1035 if (LoopVar1 == Special) {\r
1036 while (LoopVar1 < 6 && mPTLen[LoopVar1] == 0) {\r
1037 LoopVar1++;\r
1038 }\r
1039\r
1040 PutBits (2, (LoopVar1 - 3) & 3);\r
1041 }\r
5d73d92f 1042 }\r
1043}\r
1044\r
3737ac2b 1045/**\r
1046 Outputs the code length array for Char&Length Set\r
1047\r
1048**/\r
5d73d92f 1049VOID\r
1050EFIAPI\r
3737ac2b 1051WriteCLen (\r
5d73d92f 1052 VOID\r
1053 )\r
3737ac2b 1054{\r
1055 INT32 LoopVar1;\r
5d73d92f 1056\r
3737ac2b 1057 INT32 LoopVar3;\r
5d73d92f 1058\r
3737ac2b 1059 INT32 LoopVar8;\r
5d73d92f 1060\r
3737ac2b 1061 INT32 Count;\r
5d73d92f 1062\r
3737ac2b 1063 LoopVar8 = NC;\r
1064 while (LoopVar8 > 0 && mCLen[LoopVar8 - 1] == 0) {\r
1065 LoopVar8--;\r
1066 }\r
5d73d92f 1067\r
3737ac2b 1068 PutBits (CBIT, LoopVar8);\r
1069 LoopVar1 = 0;\r
1070 while (LoopVar1 < LoopVar8) {\r
1071 LoopVar3 = mCLen[LoopVar1++];\r
1072 if (LoopVar3 == 0) {\r
1073 Count = 1;\r
1074 while (LoopVar1 < LoopVar8 && mCLen[LoopVar1] == 0) {\r
1075 LoopVar1++;\r
1076 Count++;\r
1077 }\r
1078\r
1079 if (Count <= 2) {\r
1080 for (LoopVar3 = 0; LoopVar3 < Count; LoopVar3++) {\r
1081 PutBits (mPTLen[0], mPTCode[0]);\r
1082 }\r
1083 } else if (Count <= 18) {\r
1084 PutBits (mPTLen[1], mPTCode[1]);\r
1085 PutBits (4, Count - 3);\r
1086 } else if (Count == 19) {\r
1087 PutBits (mPTLen[0], mPTCode[0]);\r
1088 PutBits (mPTLen[1], mPTCode[1]);\r
1089 PutBits (4, 15);\r
1090 } else {\r
1091 PutBits (mPTLen[2], mPTCode[2]);\r
1092 PutBits (CBIT, Count - 20);\r
1093 }\r
1094 } else {\r
1095 ASSERT((LoopVar3+2)<NPT);\r
1096 PutBits (mPTLen[LoopVar3 + 2], mPTCode[LoopVar3 + 2]);\r
1097 }\r
1098 }\r
1099}\r
5d73d92f 1100\r
3737ac2b 1101/**\r
1102 Huffman code the block and output it.\r
5d73d92f 1103\r
1104**/\r
3737ac2b 1105VOID\r
1106EFIAPI\r
1107SendBlock (\r
1108 VOID\r
1109 )\r
5d73d92f 1110{\r
3737ac2b 1111 UINT32 LoopVar1;\r
5d73d92f 1112\r
3737ac2b 1113 UINT32 LoopVar3;\r
5d73d92f 1114\r
1115 UINT32 Flags;\r
1116\r
1117 UINT32 Root;\r
1118\r
1119 UINT32 Pos;\r
1120\r
1121 UINT32 Size;\r
1122 Flags = 0;\r
1123\r
1124 Root = MakeTree (NC, mCFreq, mCLen, mCCode);\r
1125 Size = mCFreq[Root];\r
1126 PutBits (16, Size);\r
1127 if (Root >= NC) {\r
1128 CountTFreq ();\r
1129 Root = MakeTree (NT, mTFreq, mPTLen, mPTCode);\r
1130 if (Root >= NT) {\r
1131 WritePTLen (NT, TBIT, 3);\r
1132 } else {\r
1133 PutBits (TBIT, 0);\r
1134 PutBits (TBIT, Root);\r
1135 }\r
1136\r
1137 WriteCLen ();\r
1138 } else {\r
1139 PutBits (TBIT, 0);\r
1140 PutBits (TBIT, 0);\r
1141 PutBits (CBIT, 0);\r
1142 PutBits (CBIT, Root);\r
1143 }\r
1144\r
1145 Root = MakeTree (NP, mPFreq, mPTLen, mPTCode);\r
1146 if (Root >= NP) {\r
1147 WritePTLen (NP, PBIT, -1);\r
1148 } else {\r
1149 PutBits (PBIT, 0);\r
1150 PutBits (PBIT, Root);\r
1151 }\r
1152\r
1153 Pos = 0;\r
3737ac2b 1154 for (LoopVar1 = 0; LoopVar1 < Size; LoopVar1++) {\r
1155 if (LoopVar1 % UINT8_BIT == 0) {\r
5d73d92f 1156 Flags = mBuf[Pos++];\r
1157 } else {\r
1158 Flags <<= 1;\r
1159 }\r
1160 if ((Flags & (1U << (UINT8_BIT - 1))) != 0){\r
1161 EncodeC(mBuf[Pos++] + (1U << UINT8_BIT));\r
3737ac2b 1162 LoopVar3 = mBuf[Pos++] << UINT8_BIT;\r
1163 LoopVar3 += mBuf[Pos++];\r
5d73d92f 1164\r
3737ac2b 1165 EncodeP (LoopVar3);\r
5d73d92f 1166 } else {\r
1167 EncodeC (mBuf[Pos++]);\r
1168 }\r
1169 }\r
1170\r
1171 SetMem (mCFreq, NC * sizeof (UINT16), 0);\r
1172 SetMem (mPFreq, NP * sizeof (UINT16), 0);\r
1173}\r
1174\r
3737ac2b 1175/**\r
1176 Start the huffman encoding.\r
1177\r
1178**/\r
5d73d92f 1179VOID\r
1180EFIAPI\r
3737ac2b 1181HufEncodeStart (\r
1182 VOID\r
5d73d92f 1183 )\r
3737ac2b 1184{\r
1185 SetMem (mCFreq, NC * sizeof (UINT16), 0);\r
1186 SetMem (mPFreq, NP * sizeof (UINT16), 0);\r
5d73d92f 1187\r
3737ac2b 1188 mOutputPos = mOutputMask = 0;\r
5d73d92f 1189\r
3737ac2b 1190 mBitCount = UINT8_BIT;\r
1191 mSubBitBuf = 0;\r
1192}\r
5d73d92f 1193\r
3737ac2b 1194/**\r
1195 Outputs an Original Character or a Pointer.\r
5d73d92f 1196\r
3737ac2b 1197 @param[in] LoopVar5 The original character or the 'String Length' element of \r
1198 a Pointer.\r
1199 @param[in] LoopVar7 The 'Position' field of a Pointer.\r
5d73d92f 1200**/\r
3737ac2b 1201VOID\r
1202EFIAPI\r
1203CompressOutput (\r
1204 IN UINT32 LoopVar5,\r
1205 IN UINT32 LoopVar7\r
1206 )\r
5d73d92f 1207{\r
1208 STATIC UINT32 CPos;\r
1209\r
1210 if ((mOutputMask >>= 1) == 0) {\r
1211 mOutputMask = 1U << (UINT8_BIT - 1);\r
1212 if (mOutputPos >= mBufSiz - 3 * UINT8_BIT) {\r
1213 SendBlock ();\r
1214 mOutputPos = 0;\r
1215 }\r
1216\r
1217 CPos = mOutputPos++;\r
1218 mBuf[CPos] = 0;\r
1219 }\r
3737ac2b 1220 mBuf[mOutputPos++] = (UINT8) LoopVar5;\r
1221 mCFreq[LoopVar5]++;\r
1222 if (LoopVar5 >= (1U << UINT8_BIT)) {\r
5d73d92f 1223 mBuf[CPos] = (UINT8)(mBuf[CPos]|mOutputMask);\r
3737ac2b 1224 mBuf[mOutputPos++] = (UINT8)(LoopVar7 >> UINT8_BIT);\r
1225 mBuf[mOutputPos++] = (UINT8) LoopVar7;\r
1226 LoopVar5 = 0;\r
1227 while (LoopVar7!=0) {\r
1228 LoopVar7 >>= 1;\r
1229 LoopVar5++;\r
5d73d92f 1230 }\r
3737ac2b 1231 mPFreq[LoopVar5]++;\r
5d73d92f 1232 }\r
1233}\r
1234\r
3737ac2b 1235/**\r
1236 End the huffman encoding.\r
5d73d92f 1237\r
3737ac2b 1238**/\r
5d73d92f 1239VOID\r
1240EFIAPI\r
1241HufEncodeEnd (\r
1242 VOID\r
1243 )\r
1244{\r
1245 SendBlock ();\r
1246\r
1247 //\r
1248 // Flush remaining bits\r
1249 //\r
1250 PutBits (UINT8_BIT - 1, 0);\r
5d73d92f 1251}\r
1252\r
3737ac2b 1253/**\r
1254 The main controlling routine for compression process.\r
1255\r
1256 @retval EFI_SUCCESS The compression is successful.\r
1257 @retval EFI_OUT_0F_RESOURCES Not enough memory for compression process.\r
1258**/\r
1259EFI_STATUS\r
5d73d92f 1260EFIAPI\r
3737ac2b 1261Encode (\r
5d73d92f 1262 VOID\r
1263 )\r
1264{\r
3737ac2b 1265 EFI_STATUS Status;\r
1266 INT32 LastMatchLen;\r
1267 NODE LastMatchPos;\r
5d73d92f 1268\r
3737ac2b 1269 Status = AllocateMemory ();\r
1270 if (EFI_ERROR (Status)) {\r
1271 FreeMemory ();\r
1272 return Status;\r
5d73d92f 1273 }\r
5d73d92f 1274\r
3737ac2b 1275 InitSlide ();\r
5d73d92f 1276\r
3737ac2b 1277 HufEncodeStart ();\r
5d73d92f 1278\r
3737ac2b 1279 mRemainder = FreadCrc (&mText[WNDSIZ], WNDSIZ + MAXMATCH);\r
5d73d92f 1280\r
3737ac2b 1281 mMatchLen = 0;\r
1282 mPos = WNDSIZ;\r
1283 InsertNode ();\r
1284 if (mMatchLen > mRemainder) {\r
1285 mMatchLen = mRemainder;\r
1286 }\r
5d73d92f 1287\r
3737ac2b 1288 while (mRemainder > 0) {\r
1289 LastMatchLen = mMatchLen;\r
1290 LastMatchPos = mMatchPos;\r
1291 GetNextMatch ();\r
1292 if (mMatchLen > mRemainder) {\r
1293 mMatchLen = mRemainder;\r
5d73d92f 1294 }\r
5d73d92f 1295\r
3737ac2b 1296 if (mMatchLen > LastMatchLen || LastMatchLen < THRESHOLD) {\r
1297 //\r
1298 // Not enough benefits are gained by outputting a pointer,\r
1299 // so just output the original character\r
1300 //\r
1301 CompressOutput(mText[mPos - 1], 0);\r
5d73d92f 1302 } else {\r
3737ac2b 1303 //\r
1304 // Outputting a pointer is beneficial enough, do it.\r
1305 //\r
5d73d92f 1306\r
3737ac2b 1307 CompressOutput(LastMatchLen + (UINT8_MAX + 1 - THRESHOLD),\r
1308 (mPos - LastMatchPos - 2) & (WNDSIZ - 1));\r
1309 LastMatchLen--;\r
1310 while (LastMatchLen > 0) {\r
1311 GetNextMatch ();\r
1312 LastMatchLen--;\r
5d73d92f 1313 }\r
5d73d92f 1314\r
3737ac2b 1315 if (mMatchLen > mRemainder) {\r
1316 mMatchLen = mRemainder;\r
1317 }\r
5d73d92f 1318 }\r
1319 }\r
5d73d92f 1320\r
3737ac2b 1321 HufEncodeEnd ();\r
1322 FreeMemory ();\r
1323 return EFI_SUCCESS;\r
5d73d92f 1324}\r
1325\r
3737ac2b 1326/**\r
1327 The compression routine.\r
5d73d92f 1328\r
3737ac2b 1329 @param[in] SrcBuffer The buffer containing the source data.\r
1330 @param[in] SrcSize The number of bytes in SrcBuffer.\r
1331 @param[in] DstBuffer The buffer to put the compressed image in.\r
1332 @param[in,out] DstSize On input the size (in bytes) of DstBuffer, on\r
1333 return the number of bytes placed in DstBuffer.\r
5d73d92f 1334\r
3737ac2b 1335 @retval EFI_SUCCESS The compression was sucessful.\r
1336 @retval EFI_BUFFER_TOO_SMALL The buffer was too small. DstSize is required.\r
5d73d92f 1337**/\r
3737ac2b 1338EFI_STATUS\r
5d73d92f 1339EFIAPI\r
3737ac2b 1340Compress (\r
1341 IN VOID *SrcBuffer,\r
1342 IN UINT64 SrcSize,\r
1343 IN VOID *DstBuffer,\r
1344 IN OUT UINT64 *DstSize\r
5d73d92f 1345 )\r
5d73d92f 1346{\r
3737ac2b 1347 EFI_STATUS Status;\r
5d73d92f 1348\r
1349 //\r
3737ac2b 1350 // Initializations\r
5d73d92f 1351 //\r
3737ac2b 1352 mBufSiz = 0;\r
1353 mBuf = NULL;\r
1354 mText = NULL;\r
1355 mLevel = NULL;\r
1356 mChildCount = NULL;\r
1357 mPosition = NULL;\r
1358 mParent = NULL;\r
1359 mPrev = NULL;\r
1360 mNext = NULL;\r
5d73d92f 1361\r
3737ac2b 1362 mSrc = SrcBuffer;\r
1363 mSrcUpperLimit = mSrc + SrcSize;\r
1364 mDst = DstBuffer;\r
1365 mDstUpperLimit = mDst +*DstSize;\r
5d73d92f 1366\r
3737ac2b 1367 PutDword (0L);\r
1368 PutDword (0L);\r
5d73d92f 1369\r
3737ac2b 1370 MakeCrcTable ();\r
5d73d92f 1371\r
3737ac2b 1372 mOrigSize = mCompSize = 0;\r
1373 mCrc = INIT_CRC;\r
5d73d92f 1374\r
1375 //\r
3737ac2b 1376 // Compress it\r
5d73d92f 1377 //\r
3737ac2b 1378 Status = Encode ();\r
1379 if (EFI_ERROR (Status)) {\r
1380 return EFI_OUT_OF_RESOURCES;\r
5d73d92f 1381 }\r
5d73d92f 1382 //\r
3737ac2b 1383 // Null terminate the compressed data\r
5d73d92f 1384 //\r
3737ac2b 1385 if (mDst < mDstUpperLimit) {\r
1386 *mDst++ = 0;\r
5d73d92f 1387 }\r
3737ac2b 1388 //\r
1389 // Fill in compressed size and original size\r
1390 //\r
1391 mDst = DstBuffer;\r
1392 PutDword (mCompSize + 1);\r
1393 PutDword (mOrigSize);\r
5d73d92f 1394\r
1395 //\r
3737ac2b 1396 // Return\r
5d73d92f 1397 //\r
3737ac2b 1398 if (mCompSize + 1 + 8 > *DstSize) {\r
1399 *DstSize = mCompSize + 1 + 8;\r
1400 return EFI_BUFFER_TOO_SMALL;\r
1401 } else {\r
1402 *DstSize = mCompSize + 1 + 8;\r
1403 return EFI_SUCCESS;\r
1404 }\r
1405\r
5d73d92f 1406}\r
3737ac2b 1407\r