Home | History | Annotate | Download | only in Common
      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
     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
    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 
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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