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