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 - 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
     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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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