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