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