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