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