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