]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/C/Common/Decompress.c
33e0f0d1603abc7e40c5295dec40db7d076af9d9
[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 // Once mOutBuf is fully filled, directly return
667 //
668 if (Sd->mOutBuf >= Sd->mOrigSize) {
669 return ;
670 }
671 }
672 }
673
674 return ;
675 }
676
677 EFI_STATUS
678 GetInfo (
679 IN VOID *Source,
680 IN UINT32 SrcSize,
681 OUT UINT32 *DstSize,
682 OUT UINT32 *ScratchSize
683 )
684 /*++
685
686 Routine Description:
687
688 The implementation of EFI_DECOMPRESS_PROTOCOL.GetInfo().
689
690 Arguments:
691
692 Source - The source buffer containing the compressed data.
693 SrcSize - The size of source buffer
694 DstSize - The size of destination buffer.
695 ScratchSize - The size of scratch buffer.
696
697 Returns:
698
699 EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successfully retrieved.
700 EFI_INVALID_PARAMETER - The source data is corrupted
701
702 --*/
703 {
704 UINT8 *Src;
705 UINT32 CompSize;
706
707 *ScratchSize = sizeof (SCRATCH_DATA);
708
709 Src = Source;
710 if (SrcSize < 8) {
711 return EFI_INVALID_PARAMETER;
712 }
713
714 CompSize = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);
715 *DstSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);
716
717 if (SrcSize < CompSize + 8 || (CompSize + 8) < 8) {
718 return EFI_INVALID_PARAMETER;
719 }
720
721 return EFI_SUCCESS;
722 }
723
724 EFI_STATUS
725 Decompress (
726 IN VOID *Source,
727 IN UINT32 SrcSize,
728 IN OUT VOID *Destination,
729 IN UINT32 DstSize,
730 IN OUT VOID *Scratch,
731 IN UINT32 ScratchSize
732 )
733 /*++
734
735 Routine Description:
736
737 The implementation Efi and Tiano Decompress().
738
739 Arguments:
740
741 Source - The source buffer containing the compressed data.
742 SrcSize - The size of source buffer
743 Destination - The destination buffer to store the decompressed data
744 DstSize - The size of destination buffer.
745 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
746 ScratchSize - The size of scratch buffer.
747
748 Returns:
749
750 EFI_SUCCESS - Decompression is successfull
751 EFI_INVALID_PARAMETER - The source data is corrupted
752
753 --*/
754 {
755 UINT32 Index;
756 UINT32 CompSize;
757 UINT32 OrigSize;
758 EFI_STATUS Status;
759 SCRATCH_DATA *Sd;
760 UINT8 *Src;
761 UINT8 *Dst;
762
763 Status = EFI_SUCCESS;
764 Src = Source;
765 Dst = Destination;
766
767 if (ScratchSize < sizeof (SCRATCH_DATA)) {
768 return EFI_INVALID_PARAMETER;
769 }
770
771 Sd = (SCRATCH_DATA *) Scratch;
772
773 if (SrcSize < 8) {
774 return EFI_INVALID_PARAMETER;
775 }
776
777 CompSize = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);
778 OrigSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);
779
780 if (SrcSize < CompSize + 8 || (CompSize + 8) < 8) {
781 return EFI_INVALID_PARAMETER;
782 }
783
784 if (DstSize != OrigSize) {
785 return EFI_INVALID_PARAMETER;
786 }
787
788 Src = Src + 8;
789
790 for (Index = 0; Index < sizeof (SCRATCH_DATA); Index++) {
791 ((UINT8 *) Sd)[Index] = 0;
792 }
793
794 Sd->mSrcBase = Src;
795 Sd->mDstBase = Dst;
796 Sd->mCompSize = CompSize;
797 Sd->mOrigSize = OrigSize;
798
799 //
800 // Fill the first BITBUFSIZ bits
801 //
802 FillBuf (Sd, BITBUFSIZ);
803
804 //
805 // Decompress it
806 //
807 Decode (Sd);
808
809 if (Sd->mBadTableFlag != 0) {
810 //
811 // Something wrong with the source
812 //
813 Status = EFI_INVALID_PARAMETER;
814 }
815
816 return Status;
817 }
818
819 EFI_STATUS
820 EfiGetInfo (
821 IN VOID *Source,
822 IN UINT32 SrcSize,
823 OUT UINT32 *DstSize,
824 OUT UINT32 *ScratchSize
825 )
826 /*++
827
828 Routine Description:
829
830 The implementation Efi Decompress GetInfo().
831
832 Arguments:
833
834 Source - The source buffer containing the compressed data.
835 SrcSize - The size of source buffer
836 DstSize - The size of destination buffer.
837 ScratchSize - The size of scratch buffer.
838
839 Returns:
840
841 EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successfully retrieved.
842 EFI_INVALID_PARAMETER - The source data is corrupted
843
844 --*/
845 {
846 return GetInfo (Source, SrcSize, DstSize, ScratchSize);
847 }
848
849 EFI_STATUS
850 TianoGetInfo (
851 IN VOID *Source,
852 IN UINT32 SrcSize,
853 OUT UINT32 *DstSize,
854 OUT UINT32 *ScratchSize
855 )
856 /*++
857
858 Routine Description:
859
860 The implementation Tiano Decompress GetInfo().
861
862 Arguments:
863
864 Source - The source buffer containing the compressed data.
865 SrcSize - The size of source buffer
866 DstSize - The size of destination buffer.
867 ScratchSize - The size of scratch buffer.
868
869 Returns:
870
871 EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successfully retrieved.
872 EFI_INVALID_PARAMETER - The source data is corrupted
873
874 --*/
875 {
876 return GetInfo (Source, SrcSize, DstSize, ScratchSize);
877 }
878
879 EFI_STATUS
880 EfiDecompress (
881 IN VOID *Source,
882 IN UINT32 SrcSize,
883 IN OUT VOID *Destination,
884 IN UINT32 DstSize,
885 IN OUT VOID *Scratch,
886 IN UINT32 ScratchSize
887 )
888 /*++
889
890 Routine Description:
891
892 The implementation of Efi Decompress().
893
894 Arguments:
895
896 Source - The source buffer containing the compressed data.
897 SrcSize - The size of source buffer
898 Destination - The destination buffer to store the decompressed data
899 DstSize - The size of destination buffer.
900 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
901 ScratchSize - The size of scratch buffer.
902
903 Returns:
904
905 EFI_SUCCESS - Decompression is successfull
906 EFI_INVALID_PARAMETER - The source data is corrupted
907
908 --*/
909 {
910 mPbit = EFIPBIT;
911 return Decompress (Source, SrcSize, Destination, DstSize, Scratch, ScratchSize);
912 }
913
914 EFI_STATUS
915 TianoDecompress (
916 IN VOID *Source,
917 IN UINT32 SrcSize,
918 IN OUT VOID *Destination,
919 IN UINT32 DstSize,
920 IN OUT VOID *Scratch,
921 IN UINT32 ScratchSize
922 )
923 /*++
924
925 Routine Description:
926
927 The implementation of Tiano Decompress().
928
929 Arguments:
930
931 Source - The source buffer containing the compressed data.
932 SrcSize - The size of source buffer
933 Destination - The destination buffer to store the decompressed data
934 DstSize - The size of destination buffer.
935 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
936 ScratchSize - The size of scratch buffer.
937
938 Returns:
939
940 EFI_SUCCESS - Decompression is successfull
941 EFI_INVALID_PARAMETER - The source data is corrupted
942
943 --*/
944 {
945 mPbit = MAXPBIT;
946 return Decompress (Source, SrcSize, Destination, DstSize, Scratch, ScratchSize);
947 }
948
949 EFI_STATUS
950 Extract (
951 IN VOID *Source,
952 IN UINT32 SrcSize,
953 OUT VOID **Destination,
954 OUT UINT32 *DstSize,
955 IN UINTN Algorithm
956 )
957 {
958 VOID *Scratch;
959 UINT32 ScratchSize;
960 EFI_STATUS Status;
961
962 Scratch = NULL;
963 Status = EFI_SUCCESS;
964
965 switch (Algorithm) {
966 case 0:
967 *Destination = (VOID *)malloc(SrcSize);
968 if (*Destination != NULL) {
969 memcpy(*Destination, Source, SrcSize);
970 } else {
971 Status = EFI_OUT_OF_RESOURCES;
972 }
973 break;
974 case 1:
975 Status = EfiGetInfo(Source, SrcSize, DstSize, &ScratchSize);
976 if (Status == EFI_SUCCESS) {
977 Scratch = (VOID *)malloc(ScratchSize);
978 if (Scratch == NULL) {
979 return EFI_OUT_OF_RESOURCES;
980 }
981
982 *Destination = (VOID *)malloc(*DstSize);
983 if (*Destination == NULL) {
984 free (Scratch);
985 return EFI_OUT_OF_RESOURCES;
986 }
987
988 Status = EfiDecompress(Source, SrcSize, *Destination, *DstSize, Scratch, ScratchSize);
989 }
990 break;
991 case 2:
992 Status = TianoGetInfo(Source, SrcSize, DstSize, &ScratchSize);
993 if (Status == EFI_SUCCESS) {
994 Scratch = (VOID *)malloc(ScratchSize);
995 if (Scratch == NULL) {
996 return EFI_OUT_OF_RESOURCES;
997 }
998
999 *Destination = (VOID *)malloc(*DstSize);
1000 if (*Destination == NULL) {
1001 free (Scratch);
1002 return EFI_OUT_OF_RESOURCES;
1003 }
1004
1005 Status = TianoDecompress(Source, SrcSize, *Destination, *DstSize, Scratch, ScratchSize);
1006 }
1007 break;
1008 default:
1009 Status = EFI_INVALID_PARAMETER;
1010 }
1011
1012 if (Scratch != NULL) {
1013 free (Scratch);
1014 }
1015
1016 return Status;
1017 }
1018
1019