]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/C/Common/Decompress.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / BaseTools / Source / C / Common / Decompress.c
CommitLineData
30fdf114 1/** @file\r
f7496d71 2Decompressor. Algorithm Ported from OPSD code (Decomp.asm) for Efi and Tiano\r
97fa0ee9 3compress algorithm.\r
30fdf114 4\r
f7496d71 5Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
2e351cbe 6SPDX-License-Identifier: BSD-2-Clause-Patent\r
30fdf114 7\r
30fdf114
LG
8--*/\r
9\r
10#include <stdlib.h>\r
11#include <string.h>\r
b3520abd 12#include <assert.h>\r
30fdf114
LG
13#include "Decompress.h"\r
14\r
15//\r
16// Decompression algorithm begins here\r
17//\r
18#define BITBUFSIZ 32\r
19#define MAXMATCH 256\r
20#define THRESHOLD 3\r
21#define CODE_BIT 16\r
22#define BAD_TABLE - 1\r
23\r
24//\r
25// C: Char&Len Set; P: Position Set; T: exTra Set\r
26//\r
27#define NC (0xff + MAXMATCH + 2 - THRESHOLD)\r
28#define CBIT 9\r
29#define EFIPBIT 4\r
30#define MAXPBIT 5\r
31#define TBIT 5\r
32#define MAXNP ((1U << MAXPBIT) - 1)\r
33#define NT (CODE_BIT + 3)\r
34#if NT > MAXNP\r
35#define NPT NT\r
36#else\r
37#define NPT MAXNP\r
38#endif\r
39\r
40typedef struct {\r
41 UINT8 *mSrcBase; // Starting address of compressed data\r
42 UINT8 *mDstBase; // Starting address of decompressed data\r
43 UINT32 mOutBuf;\r
44 UINT32 mInBuf;\r
45\r
46 UINT16 mBitCount;\r
47 UINT32 mBitBuf;\r
48 UINT32 mSubBitBuf;\r
49 UINT16 mBlockSize;\r
50 UINT32 mCompSize;\r
51 UINT32 mOrigSize;\r
52\r
53 UINT16 mBadTableFlag;\r
54\r
55 UINT16 mLeft[2 * NC - 1];\r
56 UINT16 mRight[2 * NC - 1];\r
57 UINT8 mCLen[NC];\r
58 UINT8 mPTLen[NPT];\r
59 UINT16 mCTable[4096];\r
60 UINT16 mPTTable[256];\r
61} SCRATCH_DATA;\r
62\r
63STATIC UINT16 mPbit = EFIPBIT;\r
64\r
65STATIC\r
66VOID\r
67FillBuf (\r
68 IN SCRATCH_DATA *Sd,\r
69 IN UINT16 NumOfBits\r
70 )\r
71/*++\r
72\r
73Routine Description:\r
74\r
75 Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source.\r
76\r
77Arguments:\r
78\r
79 Sd - The global scratch data\r
80 NumOfBit - The number of bits to shift and read.\r
81\r
82Returns: (VOID)\r
83\r
84--*/\r
85{\r
59bc913c 86 Sd->mBitBuf = (UINT32) (((UINT64)Sd->mBitBuf) << NumOfBits);\r
30fdf114
LG
87\r
88 while (NumOfBits > Sd->mBitCount) {\r
89\r
59bc913c 90 Sd->mBitBuf |= (UINT32) (((UINT64)Sd->mSubBitBuf) << (NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount)));\r
30fdf114
LG
91\r
92 if (Sd->mCompSize > 0) {\r
93 //\r
94 // Get 1 byte into SubBitBuf\r
95 //\r
96 Sd->mCompSize--;\r
97 Sd->mSubBitBuf = 0;\r
98 Sd->mSubBitBuf = Sd->mSrcBase[Sd->mInBuf++];\r
99 Sd->mBitCount = 8;\r
100\r
101 } else {\r
102 //\r
103 // No more bits from the source, just pad zero bit.\r
104 //\r
105 Sd->mSubBitBuf = 0;\r
106 Sd->mBitCount = 8;\r
107\r
108 }\r
109 }\r
110\r
111 Sd->mBitCount = (UINT16) (Sd->mBitCount - NumOfBits);\r
112 Sd->mBitBuf |= Sd->mSubBitBuf >> Sd->mBitCount;\r
113}\r
114\r
115STATIC\r
116UINT32\r
117GetBits (\r
118 IN SCRATCH_DATA *Sd,\r
119 IN UINT16 NumOfBits\r
120 )\r
121/*++\r
122\r
123Routine Description:\r
124\r
125 Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent\r
126 NumOfBits of bits from source. Returns NumOfBits of bits that are\r
127 popped out.\r
128\r
129Arguments:\r
130\r
131 Sd - The global scratch data.\r
132 NumOfBits - The number of bits to pop and read.\r
133\r
134Returns:\r
135\r
136 The bits that are popped out.\r
137\r
138--*/\r
139{\r
140 UINT32 OutBits;\r
141\r
142 OutBits = (UINT32) (Sd->mBitBuf >> (BITBUFSIZ - NumOfBits));\r
143\r
144 FillBuf (Sd, NumOfBits);\r
145\r
146 return OutBits;\r
147}\r
148\r
149STATIC\r
150UINT16\r
151MakeTable (\r
152 IN SCRATCH_DATA *Sd,\r
153 IN UINT16 NumOfChar,\r
154 IN UINT8 *BitLen,\r
155 IN UINT16 TableBits,\r
156 OUT UINT16 *Table\r
157 )\r
158/*++\r
159\r
160Routine Description:\r
161\r
162 Creates Huffman Code mapping table according to code length array.\r
163\r
164Arguments:\r
165\r
166 Sd - The global scratch data\r
167 NumOfChar - Number of symbols in the symbol set\r
168 BitLen - Code length array\r
169 TableBits - The width of the mapping table\r
170 Table - The table\r
171\r
172Returns:\r
173\r
174 0 - OK.\r
175 BAD_TABLE - The table is corrupted.\r
176\r
177--*/\r
178{\r
179 UINT16 Count[17];\r
180 UINT16 Weight[17];\r
181 UINT16 Start[18];\r
182 UINT16 *Pointer;\r
183 UINT16 Index3;\r
184 UINT16 Index;\r
185 UINT16 Len;\r
186 UINT16 Char;\r
187 UINT16 JuBits;\r
188 UINT16 Avail;\r
189 UINT16 NextCode;\r
190 UINT16 Mask;\r
041d89bc 191 UINT16 MaxTableLength;\r
30fdf114
LG
192\r
193 for (Index = 1; Index <= 16; Index++) {\r
194 Count[Index] = 0;\r
195 }\r
196\r
197 for (Index = 0; Index < NumOfChar; Index++) {\r
041d89bc
LG
198 if (BitLen[Index] > 16) {\r
199 return (UINT16) BAD_TABLE;\r
200 }\r
30fdf114
LG
201 Count[BitLen[Index]]++;\r
202 }\r
203\r
204 Start[1] = 0;\r
205\r
206 for (Index = 1; Index <= 16; Index++) {\r
207 Start[Index + 1] = (UINT16) (Start[Index] + (Count[Index] << (16 - Index)));\r
208 }\r
209\r
210 if (Start[17] != 0) {\r
211 /*(1U << 16)*/\r
212 return (UINT16) BAD_TABLE;\r
213 }\r
214\r
215 JuBits = (UINT16) (16 - TableBits);\r
216\r
217 for (Index = 1; Index <= TableBits; Index++) {\r
218 Start[Index] >>= JuBits;\r
219 Weight[Index] = (UINT16) (1U << (TableBits - Index));\r
220 }\r
221\r
222 while (Index <= 16) {\r
223 Weight[Index] = (UINT16) (1U << (16 - Index));\r
224 Index++;\r
225 }\r
226\r
227 Index = (UINT16) (Start[TableBits + 1] >> JuBits);\r
228\r
229 if (Index != 0) {\r
230 Index3 = (UINT16) (1U << TableBits);\r
231 while (Index != Index3) {\r
232 Table[Index++] = 0;\r
233 }\r
234 }\r
235\r
236 Avail = NumOfChar;\r
237 Mask = (UINT16) (1U << (15 - TableBits));\r
041d89bc 238 MaxTableLength = (UINT16) (1U << TableBits);\r
30fdf114
LG
239\r
240 for (Char = 0; Char < NumOfChar; Char++) {\r
241\r
242 Len = BitLen[Char];\r
b3520abd 243 if (Len == 0 || Len >= 17) {\r
30fdf114
LG
244 continue;\r
245 }\r
246\r
247 NextCode = (UINT16) (Start[Len] + Weight[Len]);\r
248\r
249 if (Len <= TableBits) {\r
250\r
55756c88
SZ
251 if (Start[Len] >= NextCode || NextCode > MaxTableLength){\r
252 return (UINT16) BAD_TABLE;\r
253 }\r
254\r
30fdf114
LG
255 for (Index = Start[Len]; Index < NextCode; Index++) {\r
256 Table[Index] = Char;\r
257 }\r
258\r
259 } else {\r
260\r
261 Index3 = Start[Len];\r
262 Pointer = &Table[Index3 >> JuBits];\r
263 Index = (UINT16) (Len - TableBits);\r
264\r
265 while (Index != 0) {\r
266 if (*Pointer == 0) {\r
267 Sd->mRight[Avail] = Sd->mLeft[Avail] = 0;\r
268 *Pointer = Avail++;\r
269 }\r
270\r
271 if (Index3 & Mask) {\r
272 Pointer = &Sd->mRight[*Pointer];\r
273 } else {\r
274 Pointer = &Sd->mLeft[*Pointer];\r
275 }\r
276\r
277 Index3 <<= 1;\r
278 Index--;\r
279 }\r
280\r
281 *Pointer = Char;\r
282\r
283 }\r
284\r
285 Start[Len] = NextCode;\r
286 }\r
287 //\r
288 // Succeeds\r
289 //\r
290 return 0;\r
291}\r
292\r
293STATIC\r
294UINT32\r
295DecodeP (\r
296 IN SCRATCH_DATA *Sd\r
297 )\r
298/*++\r
299\r
300Routine Description:\r
301\r
302 Decodes a position value.\r
303\r
304Arguments:\r
305\r
306 Sd - the global scratch data\r
307\r
308Returns:\r
309\r
310 The position value decoded.\r
311\r
312--*/\r
313{\r
314 UINT16 Val;\r
315 UINT32 Mask;\r
316 UINT32 Pos;\r
317\r
318 Val = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];\r
319\r
320 if (Val >= MAXNP) {\r
321 Mask = 1U << (BITBUFSIZ - 1 - 8);\r
322\r
323 do {\r
324\r
325 if (Sd->mBitBuf & Mask) {\r
326 Val = Sd->mRight[Val];\r
327 } else {\r
328 Val = Sd->mLeft[Val];\r
329 }\r
330\r
331 Mask >>= 1;\r
332 } while (Val >= MAXNP);\r
333 }\r
334 //\r
335 // Advance what we have read\r
336 //\r
337 FillBuf (Sd, Sd->mPTLen[Val]);\r
338\r
339 Pos = Val;\r
340 if (Val > 1) {\r
341 Pos = (UINT32) ((1U << (Val - 1)) + GetBits (Sd, (UINT16) (Val - 1)));\r
342 }\r
343\r
344 return Pos;\r
345}\r
346\r
347STATIC\r
348UINT16\r
349ReadPTLen (\r
350 IN SCRATCH_DATA *Sd,\r
351 IN UINT16 nn,\r
352 IN UINT16 nbit,\r
353 IN UINT16 Special\r
354 )\r
355/*++\r
356\r
357Routine Description:\r
358\r
359 Reads code lengths for the Extra Set or the Position Set\r
360\r
361Arguments:\r
362\r
363 Sd - The global scratch data\r
364 nn - Number of symbols\r
365 nbit - Number of bits needed to represent nn\r
366 Special - The special symbol that needs to be taken care of\r
367\r
368Returns:\r
369\r
370 0 - OK.\r
371 BAD_TABLE - Table is corrupted.\r
372\r
373--*/\r
374{\r
375 UINT16 Number;\r
376 UINT16 CharC;\r
377 UINT16 Index;\r
378 UINT32 Mask;\r
379\r
b3520abd
HW
380 assert (nn <= NPT);\r
381\r
30fdf114
LG
382 Number = (UINT16) GetBits (Sd, nbit);\r
383\r
384 if (Number == 0) {\r
385 CharC = (UINT16) GetBits (Sd, nbit);\r
386\r
387 for (Index = 0; Index < 256; Index++) {\r
388 Sd->mPTTable[Index] = CharC;\r
389 }\r
390\r
391 for (Index = 0; Index < nn; Index++) {\r
392 Sd->mPTLen[Index] = 0;\r
393 }\r
394\r
395 return 0;\r
396 }\r
397\r
398 Index = 0;\r
399\r
58356e94 400 while (Index < Number && Index < NPT) {\r
30fdf114
LG
401\r
402 CharC = (UINT16) (Sd->mBitBuf >> (BITBUFSIZ - 3));\r
403\r
404 if (CharC == 7) {\r
405 Mask = 1U << (BITBUFSIZ - 1 - 3);\r
406 while (Mask & Sd->mBitBuf) {\r
407 Mask >>= 1;\r
408 CharC += 1;\r
409 }\r
410 }\r
411\r
412 FillBuf (Sd, (UINT16) ((CharC < 7) ? 3 : CharC - 3));\r
413\r
414 Sd->mPTLen[Index++] = (UINT8) CharC;\r
415\r
416 if (Index == Special) {\r
417 CharC = (UINT16) GetBits (Sd, 2);\r
418 CharC--;\r
58356e94 419 while ((INT16) (CharC) >= 0 && Index < NPT) {\r
30fdf114
LG
420 Sd->mPTLen[Index++] = 0;\r
421 CharC--;\r
422 }\r
423 }\r
424 }\r
425\r
58356e94 426 while (Index < nn && Index < NPT) {\r
30fdf114
LG
427 Sd->mPTLen[Index++] = 0;\r
428 }\r
429\r
430 return MakeTable (Sd, nn, Sd->mPTLen, 8, Sd->mPTTable);\r
431}\r
432\r
433STATIC\r
434VOID\r
435ReadCLen (\r
436 SCRATCH_DATA *Sd\r
437 )\r
438/*++\r
439\r
440Routine Description:\r
441\r
442 Reads code lengths for Char&Len Set.\r
443\r
444Arguments:\r
445\r
446 Sd - the global scratch data\r
447\r
448Returns: (VOID)\r
449\r
450--*/\r
451{\r
452 UINT16 Number;\r
453 UINT16 CharC;\r
454 UINT16 Index;\r
455 UINT32 Mask;\r
456\r
457 Number = (UINT16) GetBits (Sd, CBIT);\r
458\r
459 if (Number == 0) {\r
460 CharC = (UINT16) GetBits (Sd, CBIT);\r
461\r
462 for (Index = 0; Index < NC; Index++) {\r
463 Sd->mCLen[Index] = 0;\r
464 }\r
465\r
466 for (Index = 0; Index < 4096; Index++) {\r
467 Sd->mCTable[Index] = CharC;\r
468 }\r
469\r
470 return ;\r
471 }\r
472\r
473 Index = 0;\r
474 while (Index < Number) {\r
475\r
476 CharC = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];\r
477 if (CharC >= NT) {\r
478 Mask = 1U << (BITBUFSIZ - 1 - 8);\r
479\r
480 do {\r
481\r
482 if (Mask & Sd->mBitBuf) {\r
483 CharC = Sd->mRight[CharC];\r
484 } else {\r
485 CharC = Sd->mLeft[CharC];\r
486 }\r
487\r
488 Mask >>= 1;\r
489\r
490 } while (CharC >= NT);\r
491 }\r
492 //\r
493 // Advance what we have read\r
494 //\r
495 FillBuf (Sd, Sd->mPTLen[CharC]);\r
496\r
497 if (CharC <= 2) {\r
498\r
499 if (CharC == 0) {\r
500 CharC = 1;\r
501 } else if (CharC == 1) {\r
502 CharC = (UINT16) (GetBits (Sd, 4) + 3);\r
503 } else if (CharC == 2) {\r
504 CharC = (UINT16) (GetBits (Sd, CBIT) + 20);\r
505 }\r
506\r
507 CharC--;\r
508 while ((INT16) (CharC) >= 0) {\r
509 Sd->mCLen[Index++] = 0;\r
510 CharC--;\r
511 }\r
512\r
513 } else {\r
514\r
515 Sd->mCLen[Index++] = (UINT8) (CharC - 2);\r
516\r
517 }\r
518 }\r
519\r
520 while (Index < NC) {\r
521 Sd->mCLen[Index++] = 0;\r
522 }\r
523\r
524 MakeTable (Sd, NC, Sd->mCLen, 12, Sd->mCTable);\r
525\r
526 return ;\r
527}\r
528\r
529STATIC\r
530UINT16\r
531DecodeC (\r
532 SCRATCH_DATA *Sd\r
533 )\r
534/*++\r
535\r
536Routine Description:\r
537\r
538 Decode a character/length value.\r
539\r
540Arguments:\r
541\r
542 Sd - The global scratch data.\r
543\r
544Returns:\r
545\r
546 The value decoded.\r
547\r
548--*/\r
549{\r
550 UINT16 Index2;\r
551 UINT32 Mask;\r
552\r
553 if (Sd->mBlockSize == 0) {\r
554 //\r
555 // Starting a new block\r
556 //\r
557 Sd->mBlockSize = (UINT16) GetBits (Sd, 16);\r
558 Sd->mBadTableFlag = ReadPTLen (Sd, NT, TBIT, 3);\r
559 if (Sd->mBadTableFlag != 0) {\r
560 return 0;\r
561 }\r
562\r
563 ReadCLen (Sd);\r
564\r
565 Sd->mBadTableFlag = ReadPTLen (Sd, MAXNP, mPbit, (UINT16) (-1));\r
566 if (Sd->mBadTableFlag != 0) {\r
567 return 0;\r
568 }\r
569 }\r
570\r
571 Sd->mBlockSize--;\r
572 Index2 = Sd->mCTable[Sd->mBitBuf >> (BITBUFSIZ - 12)];\r
573\r
574 if (Index2 >= NC) {\r
575 Mask = 1U << (BITBUFSIZ - 1 - 12);\r
576\r
577 do {\r
578 if (Sd->mBitBuf & Mask) {\r
579 Index2 = Sd->mRight[Index2];\r
580 } else {\r
581 Index2 = Sd->mLeft[Index2];\r
582 }\r
583\r
584 Mask >>= 1;\r
585 } while (Index2 >= NC);\r
586 }\r
587 //\r
588 // Advance what we have read\r
589 //\r
590 FillBuf (Sd, Sd->mCLen[Index2]);\r
591\r
592 return Index2;\r
593}\r
594\r
595STATIC\r
596VOID\r
597Decode (\r
598 SCRATCH_DATA *Sd\r
599 )\r
600/*++\r
601\r
602Routine Description:\r
603\r
604 Decode the source data and put the resulting data into the destination buffer.\r
605\r
606Arguments:\r
607\r
608 Sd - The global scratch data\r
609\r
610Returns: (VOID)\r
611\r
612 --*/\r
613{\r
614 UINT16 BytesRemain;\r
615 UINT32 DataIdx;\r
616 UINT16 CharC;\r
617\r
618 BytesRemain = (UINT16) (-1);\r
619\r
620 DataIdx = 0;\r
621\r
622 for (;;) {\r
623 CharC = DecodeC (Sd);\r
624 if (Sd->mBadTableFlag != 0) {\r
625 return ;\r
626 }\r
627\r
628 if (CharC < 256) {\r
629 //\r
630 // Process an Original character\r
631 //\r
632 Sd->mDstBase[Sd->mOutBuf++] = (UINT8) CharC;\r
633 if (Sd->mOutBuf >= Sd->mOrigSize) {\r
634 return ;\r
635 }\r
636\r
637 } else {\r
638 //\r
639 // Process a Pointer\r
640 //\r
641 CharC = (UINT16) (CharC - (UINT8_MAX + 1 - THRESHOLD));\r
642\r
643 BytesRemain = CharC;\r
644\r
645 DataIdx = Sd->mOutBuf - DecodeP (Sd) - 1;\r
646\r
647 BytesRemain--;\r
648 while ((INT16) (BytesRemain) >= 0) {\r
30fdf114
LG
649 if (Sd->mOutBuf >= Sd->mOrigSize) {\r
650 return ;\r
651 }\r
041d89bc
LG
652 if (DataIdx >= Sd->mOrigSize) {\r
653 Sd->mBadTableFlag = (UINT16) BAD_TABLE;\r
654 return ;\r
655 }\r
656 Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];\r
30fdf114
LG
657\r
658 BytesRemain--;\r
659 }\r
5e45a1fd
LG
660 //\r
661 // Once mOutBuf is fully filled, directly return\r
662 //\r
663 if (Sd->mOutBuf >= Sd->mOrigSize) {\r
664 return ;\r
665 }\r
30fdf114
LG
666 }\r
667 }\r
668\r
669 return ;\r
670}\r
671\r
672EFI_STATUS\r
673GetInfo (\r
674 IN VOID *Source,\r
675 IN UINT32 SrcSize,\r
676 OUT UINT32 *DstSize,\r
677 OUT UINT32 *ScratchSize\r
678 )\r
679/*++\r
680\r
681Routine Description:\r
682\r
683 The implementation of EFI_DECOMPRESS_PROTOCOL.GetInfo().\r
684\r
685Arguments:\r
686\r
687 Source - The source buffer containing the compressed data.\r
688 SrcSize - The size of source buffer\r
689 DstSize - The size of destination buffer.\r
690 ScratchSize - The size of scratch buffer.\r
691\r
692Returns:\r
693\r
99e55970 694 EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successfully retrieved.\r
30fdf114
LG
695 EFI_INVALID_PARAMETER - The source data is corrupted\r
696\r
697--*/\r
698{\r
699 UINT8 *Src;\r
041d89bc 700 UINT32 CompSize;\r
30fdf114
LG
701\r
702 *ScratchSize = sizeof (SCRATCH_DATA);\r
703\r
704 Src = Source;\r
705 if (SrcSize < 8) {\r
706 return EFI_INVALID_PARAMETER;\r
707 }\r
708\r
041d89bc 709 CompSize = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);\r
30fdf114 710 *DstSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);\r
041d89bc
LG
711\r
712 if (SrcSize < CompSize + 8 || (CompSize + 8) < 8) {\r
713 return EFI_INVALID_PARAMETER;\r
714 }\r
715\r
30fdf114
LG
716 return EFI_SUCCESS;\r
717}\r
718\r
719EFI_STATUS\r
720Decompress (\r
721 IN VOID *Source,\r
722 IN UINT32 SrcSize,\r
723 IN OUT VOID *Destination,\r
724 IN UINT32 DstSize,\r
725 IN OUT VOID *Scratch,\r
726 IN UINT32 ScratchSize\r
727 )\r
728/*++\r
729\r
730Routine Description:\r
731\r
732 The implementation Efi and Tiano Decompress().\r
733\r
734Arguments:\r
735\r
736 Source - The source buffer containing the compressed data.\r
737 SrcSize - The size of source buffer\r
738 Destination - The destination buffer to store the decompressed data\r
739 DstSize - The size of destination buffer.\r
740 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.\r
741 ScratchSize - The size of scratch buffer.\r
742\r
743Returns:\r
744\r
fb0b35e0 745 EFI_SUCCESS - Decompression is successful\r
30fdf114
LG
746 EFI_INVALID_PARAMETER - The source data is corrupted\r
747\r
748--*/\r
749{\r
750 UINT32 Index;\r
751 UINT32 CompSize;\r
752 UINT32 OrigSize;\r
753 EFI_STATUS Status;\r
754 SCRATCH_DATA *Sd;\r
755 UINT8 *Src;\r
756 UINT8 *Dst;\r
757\r
758 Status = EFI_SUCCESS;\r
759 Src = Source;\r
760 Dst = Destination;\r
761\r
762 if (ScratchSize < sizeof (SCRATCH_DATA)) {\r
763 return EFI_INVALID_PARAMETER;\r
764 }\r
765\r
766 Sd = (SCRATCH_DATA *) Scratch;\r
767\r
768 if (SrcSize < 8) {\r
769 return EFI_INVALID_PARAMETER;\r
770 }\r
771\r
772 CompSize = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);\r
773 OrigSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);\r
774\r
041d89bc 775 if (SrcSize < CompSize + 8 || (CompSize + 8) < 8) {\r
30fdf114
LG
776 return EFI_INVALID_PARAMETER;\r
777 }\r
778\r
779 if (DstSize != OrigSize) {\r
780 return EFI_INVALID_PARAMETER;\r
781 }\r
782\r
783 Src = Src + 8;\r
784\r
785 for (Index = 0; Index < sizeof (SCRATCH_DATA); Index++) {\r
786 ((UINT8 *) Sd)[Index] = 0;\r
787 }\r
788\r
789 Sd->mSrcBase = Src;\r
790 Sd->mDstBase = Dst;\r
791 Sd->mCompSize = CompSize;\r
792 Sd->mOrigSize = OrigSize;\r
793\r
794 //\r
795 // Fill the first BITBUFSIZ bits\r
796 //\r
797 FillBuf (Sd, BITBUFSIZ);\r
798\r
799 //\r
800 // Decompress it\r
801 //\r
802 Decode (Sd);\r
803\r
804 if (Sd->mBadTableFlag != 0) {\r
805 //\r
806 // Something wrong with the source\r
807 //\r
808 Status = EFI_INVALID_PARAMETER;\r
809 }\r
810\r
811 return Status;\r
812}\r
813\r
814EFI_STATUS\r
815EfiGetInfo (\r
816 IN VOID *Source,\r
817 IN UINT32 SrcSize,\r
818 OUT UINT32 *DstSize,\r
819 OUT UINT32 *ScratchSize\r
820 )\r
821/*++\r
822\r
823Routine Description:\r
824\r
825 The implementation Efi Decompress GetInfo().\r
826\r
827Arguments:\r
828\r
829 Source - The source buffer containing the compressed data.\r
830 SrcSize - The size of source buffer\r
831 DstSize - The size of destination buffer.\r
832 ScratchSize - The size of scratch buffer.\r
833\r
834Returns:\r
835\r
99e55970 836 EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successfully retrieved.\r
30fdf114
LG
837 EFI_INVALID_PARAMETER - The source data is corrupted\r
838\r
839--*/\r
840{\r
841 return GetInfo (Source, SrcSize, DstSize, ScratchSize);\r
842}\r
843\r
844EFI_STATUS\r
845TianoGetInfo (\r
846 IN VOID *Source,\r
847 IN UINT32 SrcSize,\r
848 OUT UINT32 *DstSize,\r
849 OUT UINT32 *ScratchSize\r
850 )\r
851/*++\r
852\r
853Routine Description:\r
854\r
855 The implementation Tiano Decompress GetInfo().\r
856\r
857Arguments:\r
858\r
859 Source - The source buffer containing the compressed data.\r
860 SrcSize - The size of source buffer\r
861 DstSize - The size of destination buffer.\r
862 ScratchSize - The size of scratch buffer.\r
863\r
864Returns:\r
865\r
99e55970 866 EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successfully retrieved.\r
30fdf114
LG
867 EFI_INVALID_PARAMETER - The source data is corrupted\r
868\r
869--*/\r
870{\r
871 return GetInfo (Source, SrcSize, DstSize, ScratchSize);\r
872}\r
873\r
874EFI_STATUS\r
875EfiDecompress (\r
876 IN VOID *Source,\r
877 IN UINT32 SrcSize,\r
878 IN OUT VOID *Destination,\r
879 IN UINT32 DstSize,\r
880 IN OUT VOID *Scratch,\r
881 IN UINT32 ScratchSize\r
882 )\r
883/*++\r
884\r
885Routine Description:\r
886\r
887 The implementation of Efi Decompress().\r
888\r
889Arguments:\r
890\r
891 Source - The source buffer containing the compressed data.\r
892 SrcSize - The size of source buffer\r
893 Destination - The destination buffer to store the decompressed data\r
894 DstSize - The size of destination buffer.\r
895 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.\r
896 ScratchSize - The size of scratch buffer.\r
897\r
898Returns:\r
899\r
fb0b35e0 900 EFI_SUCCESS - Decompression is successful\r
30fdf114
LG
901 EFI_INVALID_PARAMETER - The source data is corrupted\r
902\r
903--*/\r
904{\r
905 mPbit = EFIPBIT;\r
906 return Decompress (Source, SrcSize, Destination, DstSize, Scratch, ScratchSize);\r
907}\r
908\r
909EFI_STATUS\r
910TianoDecompress (\r
911 IN VOID *Source,\r
912 IN UINT32 SrcSize,\r
913 IN OUT VOID *Destination,\r
914 IN UINT32 DstSize,\r
915 IN OUT VOID *Scratch,\r
916 IN UINT32 ScratchSize\r
917 )\r
918/*++\r
919\r
920Routine Description:\r
921\r
922 The implementation of Tiano Decompress().\r
923\r
924Arguments:\r
925\r
926 Source - The source buffer containing the compressed data.\r
927 SrcSize - The size of source buffer\r
928 Destination - The destination buffer to store the decompressed data\r
929 DstSize - The size of destination buffer.\r
930 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.\r
931 ScratchSize - The size of scratch buffer.\r
932\r
933Returns:\r
934\r
fb0b35e0 935 EFI_SUCCESS - Decompression is successful\r
30fdf114
LG
936 EFI_INVALID_PARAMETER - The source data is corrupted\r
937\r
938--*/\r
939{\r
940 mPbit = MAXPBIT;\r
941 return Decompress (Source, SrcSize, Destination, DstSize, Scratch, ScratchSize);\r
942}\r
943\r
944EFI_STATUS\r
945Extract (\r
946 IN VOID *Source,\r
947 IN UINT32 SrcSize,\r
948 OUT VOID **Destination,\r
949 OUT UINT32 *DstSize,\r
950 IN UINTN Algorithm\r
951 )\r
952{\r
953 VOID *Scratch;\r
954 UINT32 ScratchSize;\r
955 EFI_STATUS Status;\r
956\r
aee34651
HW
957 Scratch = NULL;\r
958 Status = EFI_SUCCESS;\r
959\r
30fdf114
LG
960 switch (Algorithm) {\r
961 case 0:\r
962 *Destination = (VOID *)malloc(SrcSize);\r
963 if (*Destination != NULL) {\r
964 memcpy(*Destination, Source, SrcSize);\r
965 } else {\r
966 Status = EFI_OUT_OF_RESOURCES;\r
967 }\r
968 break;\r
969 case 1:\r
970 Status = EfiGetInfo(Source, SrcSize, DstSize, &ScratchSize);\r
971 if (Status == EFI_SUCCESS) {\r
972 Scratch = (VOID *)malloc(ScratchSize);\r
aee34651
HW
973 if (Scratch == NULL) {\r
974 return EFI_OUT_OF_RESOURCES;\r
975 }\r
976\r
30fdf114 977 *Destination = (VOID *)malloc(*DstSize);\r
aee34651
HW
978 if (*Destination == NULL) {\r
979 free (Scratch);\r
980 return EFI_OUT_OF_RESOURCES;\r
30fdf114 981 }\r
aee34651
HW
982\r
983 Status = EfiDecompress(Source, SrcSize, *Destination, *DstSize, Scratch, ScratchSize);\r
30fdf114
LG
984 }\r
985 break;\r
986 case 2:\r
987 Status = TianoGetInfo(Source, SrcSize, DstSize, &ScratchSize);\r
988 if (Status == EFI_SUCCESS) {\r
989 Scratch = (VOID *)malloc(ScratchSize);\r
aee34651
HW
990 if (Scratch == NULL) {\r
991 return EFI_OUT_OF_RESOURCES;\r
992 }\r
993\r
30fdf114 994 *Destination = (VOID *)malloc(*DstSize);\r
aee34651
HW
995 if (*Destination == NULL) {\r
996 free (Scratch);\r
997 return EFI_OUT_OF_RESOURCES;\r
30fdf114 998 }\r
aee34651
HW
999\r
1000 Status = TianoDecompress(Source, SrcSize, *Destination, *DstSize, Scratch, ScratchSize);\r
30fdf114
LG
1001 }\r
1002 break;\r
1003 default:\r
1004 Status = EFI_INVALID_PARAMETER;\r
1005 }\r
1006\r
aee34651
HW
1007 if (Scratch != NULL) {\r
1008 free (Scratch);\r
1009 }\r
1010\r
30fdf114
LG
1011 return Status;\r
1012}\r
1013\r
1014\r