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