• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2 Decompressor. Algorithm Ported from OPSD code (Decomp.asm) for Efi and Tiano
3 compress algorithm.
4 
5 Copyright (c) 2004 - 2016, 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
FillBuf(IN SCRATCH_DATA * Sd,IN UINT16 NumOfBits)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) (Sd->mBitBuf << NumOfBits);
93 
94   while (NumOfBits > Sd->mBitCount) {
95 
96     Sd->mBitBuf |= (UINT32) (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
GetBits(IN SCRATCH_DATA * Sd,IN UINT16 NumOfBits)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
MakeTable(IN SCRATCH_DATA * Sd,IN UINT16 NumOfChar,IN UINT8 * BitLen,IN UINT16 TableBits,OUT UINT16 * Table)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
DecodeP(IN SCRATCH_DATA * Sd)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
ReadPTLen(IN SCRATCH_DATA * Sd,IN UINT16 nn,IN UINT16 nbit,IN UINT16 Special)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) {
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) {
417         Sd->mPTLen[Index++] = 0;
418         CharC--;
419       }
420     }
421   }
422 
423   while (Index < nn) {
424     Sd->mPTLen[Index++] = 0;
425   }
426 
427   return MakeTable (Sd, nn, Sd->mPTLen, 8, Sd->mPTTable);
428 }
429 
430 STATIC
431 VOID
ReadCLen(SCRATCH_DATA * Sd)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
DecodeC(SCRATCH_DATA * Sd)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
Decode(SCRATCH_DATA * Sd)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
GetInfo(IN VOID * Source,IN UINT32 SrcSize,OUT UINT32 * DstSize,OUT UINT32 * ScratchSize)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
Decompress(IN VOID * Source,IN UINT32 SrcSize,IN OUT VOID * Destination,IN UINT32 DstSize,IN OUT VOID * Scratch,IN UINT32 ScratchSize)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
EfiGetInfo(IN VOID * Source,IN UINT32 SrcSize,OUT UINT32 * DstSize,OUT UINT32 * ScratchSize)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
TianoGetInfo(IN VOID * Source,IN UINT32 SrcSize,OUT UINT32 * DstSize,OUT UINT32 * ScratchSize)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
EfiDecompress(IN VOID * Source,IN UINT32 SrcSize,IN OUT VOID * Destination,IN UINT32 DstSize,IN OUT VOID * Scratch,IN UINT32 ScratchSize)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
TianoDecompress(IN VOID * Source,IN UINT32 SrcSize,IN OUT VOID * Destination,IN UINT32 DstSize,IN OUT VOID * Scratch,IN UINT32 ScratchSize)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
Extract(IN VOID * Source,IN UINT32 SrcSize,OUT VOID ** Destination,OUT UINT32 * DstSize,IN UINTN Algorithm)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 
995