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