12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019 |
- /** @file
- Decompressor. Algorithm Ported from OPSD code (Decomp.asm) for Efi and Tiano
- compress algorithm.
- Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
- This program and the accompanying materials
- are licensed and made available under the terms and conditions of the BSD License
- which accompanies this distribution. The full text of the license may be found at
- http://opensource.org/licenses/bsd-license.php
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
- --*/
- #include <stdlib.h>
- #include <string.h>
- #include <assert.h>
- #include "Decompress.h"
- //
- // Decompression algorithm begins here
- //
- #define BITBUFSIZ 32
- #define MAXMATCH 256
- #define THRESHOLD 3
- #define CODE_BIT 16
- #define BAD_TABLE - 1
- //
- // C: Char&Len Set; P: Position Set; T: exTra Set
- //
- #define NC (0xff + MAXMATCH + 2 - THRESHOLD)
- #define CBIT 9
- #define EFIPBIT 4
- #define MAXPBIT 5
- #define TBIT 5
- #define MAXNP ((1U << MAXPBIT) - 1)
- #define NT (CODE_BIT + 3)
- #if NT > MAXNP
- #define NPT NT
- #else
- #define NPT MAXNP
- #endif
- typedef struct {
- UINT8 *mSrcBase; // Starting address of compressed data
- UINT8 *mDstBase; // Starting address of decompressed data
- UINT32 mOutBuf;
- UINT32 mInBuf;
- UINT16 mBitCount;
- UINT32 mBitBuf;
- UINT32 mSubBitBuf;
- UINT16 mBlockSize;
- UINT32 mCompSize;
- UINT32 mOrigSize;
- UINT16 mBadTableFlag;
- UINT16 mLeft[2 * NC - 1];
- UINT16 mRight[2 * NC - 1];
- UINT8 mCLen[NC];
- UINT8 mPTLen[NPT];
- UINT16 mCTable[4096];
- UINT16 mPTTable[256];
- } SCRATCH_DATA;
- STATIC UINT16 mPbit = EFIPBIT;
- STATIC
- VOID
- FillBuf (
- IN SCRATCH_DATA *Sd,
- IN UINT16 NumOfBits
- )
- /*++
- Routine Description:
- Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source.
- Arguments:
- Sd - The global scratch data
- NumOfBit - The number of bits to shift and read.
- Returns: (VOID)
- --*/
- {
- Sd->mBitBuf = (UINT32) (((UINT64)Sd->mBitBuf) << NumOfBits);
- while (NumOfBits > Sd->mBitCount) {
- Sd->mBitBuf |= (UINT32) (((UINT64)Sd->mSubBitBuf) << (NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount)));
- if (Sd->mCompSize > 0) {
- //
- // Get 1 byte into SubBitBuf
- //
- Sd->mCompSize--;
- Sd->mSubBitBuf = 0;
- Sd->mSubBitBuf = Sd->mSrcBase[Sd->mInBuf++];
- Sd->mBitCount = 8;
- } else {
- //
- // No more bits from the source, just pad zero bit.
- //
- Sd->mSubBitBuf = 0;
- Sd->mBitCount = 8;
- }
- }
- Sd->mBitCount = (UINT16) (Sd->mBitCount - NumOfBits);
- Sd->mBitBuf |= Sd->mSubBitBuf >> Sd->mBitCount;
- }
- STATIC
- UINT32
- GetBits (
- IN SCRATCH_DATA *Sd,
- IN UINT16 NumOfBits
- )
- /*++
- Routine Description:
- Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent
- NumOfBits of bits from source. Returns NumOfBits of bits that are
- popped out.
- Arguments:
- Sd - The global scratch data.
- NumOfBits - The number of bits to pop and read.
- Returns:
- The bits that are popped out.
- --*/
- {
- UINT32 OutBits;
- OutBits = (UINT32) (Sd->mBitBuf >> (BITBUFSIZ - NumOfBits));
- FillBuf (Sd, NumOfBits);
- return OutBits;
- }
- STATIC
- UINT16
- MakeTable (
- IN SCRATCH_DATA *Sd,
- IN UINT16 NumOfChar,
- IN UINT8 *BitLen,
- IN UINT16 TableBits,
- OUT UINT16 *Table
- )
- /*++
- Routine Description:
- Creates Huffman Code mapping table according to code length array.
- Arguments:
- Sd - The global scratch data
- NumOfChar - Number of symbols in the symbol set
- BitLen - Code length array
- TableBits - The width of the mapping table
- Table - The table
- Returns:
- 0 - OK.
- BAD_TABLE - The table is corrupted.
- --*/
- {
- UINT16 Count[17];
- UINT16 Weight[17];
- UINT16 Start[18];
- UINT16 *Pointer;
- UINT16 Index3;
- UINT16 Index;
- UINT16 Len;
- UINT16 Char;
- UINT16 JuBits;
- UINT16 Avail;
- UINT16 NextCode;
- UINT16 Mask;
- UINT16 MaxTableLength;
- for (Index = 1; Index <= 16; Index++) {
- Count[Index] = 0;
- }
- for (Index = 0; Index < NumOfChar; Index++) {
- if (BitLen[Index] > 16) {
- return (UINT16) BAD_TABLE;
- }
- Count[BitLen[Index]]++;
- }
- Start[1] = 0;
- for (Index = 1; Index <= 16; Index++) {
- Start[Index + 1] = (UINT16) (Start[Index] + (Count[Index] << (16 - Index)));
- }
- if (Start[17] != 0) {
- /*(1U << 16)*/
- return (UINT16) BAD_TABLE;
- }
- JuBits = (UINT16) (16 - TableBits);
- for (Index = 1; Index <= TableBits; Index++) {
- Start[Index] >>= JuBits;
- Weight[Index] = (UINT16) (1U << (TableBits - Index));
- }
- while (Index <= 16) {
- Weight[Index] = (UINT16) (1U << (16 - Index));
- Index++;
- }
- Index = (UINT16) (Start[TableBits + 1] >> JuBits);
- if (Index != 0) {
- Index3 = (UINT16) (1U << TableBits);
- while (Index != Index3) {
- Table[Index++] = 0;
- }
- }
- Avail = NumOfChar;
- Mask = (UINT16) (1U << (15 - TableBits));
- MaxTableLength = (UINT16) (1U << TableBits);
- for (Char = 0; Char < NumOfChar; Char++) {
- Len = BitLen[Char];
- if (Len == 0 || Len >= 17) {
- continue;
- }
- NextCode = (UINT16) (Start[Len] + Weight[Len]);
- if (Len <= TableBits) {
- for (Index = Start[Len]; Index < NextCode; Index++) {
- if (Index >= MaxTableLength) {
- return (UINT16) BAD_TABLE;
- }
- Table[Index] = Char;
- }
- } else {
- Index3 = Start[Len];
- Pointer = &Table[Index3 >> JuBits];
- Index = (UINT16) (Len - TableBits);
- while (Index != 0) {
- if (*Pointer == 0) {
- Sd->mRight[Avail] = Sd->mLeft[Avail] = 0;
- *Pointer = Avail++;
- }
- if (Index3 & Mask) {
- Pointer = &Sd->mRight[*Pointer];
- } else {
- Pointer = &Sd->mLeft[*Pointer];
- }
- Index3 <<= 1;
- Index--;
- }
- *Pointer = Char;
- }
- Start[Len] = NextCode;
- }
- //
- // Succeeds
- //
- return 0;
- }
- STATIC
- UINT32
- DecodeP (
- IN SCRATCH_DATA *Sd
- )
- /*++
- Routine Description:
- Decodes a position value.
- Arguments:
- Sd - the global scratch data
- Returns:
- The position value decoded.
- --*/
- {
- UINT16 Val;
- UINT32 Mask;
- UINT32 Pos;
- Val = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];
- if (Val >= MAXNP) {
- Mask = 1U << (BITBUFSIZ - 1 - 8);
- do {
- if (Sd->mBitBuf & Mask) {
- Val = Sd->mRight[Val];
- } else {
- Val = Sd->mLeft[Val];
- }
- Mask >>= 1;
- } while (Val >= MAXNP);
- }
- //
- // Advance what we have read
- //
- FillBuf (Sd, Sd->mPTLen[Val]);
- Pos = Val;
- if (Val > 1) {
- Pos = (UINT32) ((1U << (Val - 1)) + GetBits (Sd, (UINT16) (Val - 1)));
- }
- return Pos;
- }
- STATIC
- UINT16
- ReadPTLen (
- IN SCRATCH_DATA *Sd,
- IN UINT16 nn,
- IN UINT16 nbit,
- IN UINT16 Special
- )
- /*++
- Routine Description:
- Reads code lengths for the Extra Set or the Position Set
- Arguments:
- Sd - The global scratch data
- nn - Number of symbols
- nbit - Number of bits needed to represent nn
- Special - The special symbol that needs to be taken care of
- Returns:
- 0 - OK.
- BAD_TABLE - Table is corrupted.
- --*/
- {
- UINT16 Number;
- UINT16 CharC;
- UINT16 Index;
- UINT32 Mask;
- assert (nn <= NPT);
- Number = (UINT16) GetBits (Sd, nbit);
- if (Number == 0) {
- CharC = (UINT16) GetBits (Sd, nbit);
- for (Index = 0; Index < 256; Index++) {
- Sd->mPTTable[Index] = CharC;
- }
- for (Index = 0; Index < nn; Index++) {
- Sd->mPTLen[Index] = 0;
- }
- return 0;
- }
- Index = 0;
- while (Index < Number && Index < NPT) {
- CharC = (UINT16) (Sd->mBitBuf >> (BITBUFSIZ - 3));
- if (CharC == 7) {
- Mask = 1U << (BITBUFSIZ - 1 - 3);
- while (Mask & Sd->mBitBuf) {
- Mask >>= 1;
- CharC += 1;
- }
- }
- FillBuf (Sd, (UINT16) ((CharC < 7) ? 3 : CharC - 3));
- Sd->mPTLen[Index++] = (UINT8) CharC;
- if (Index == Special) {
- CharC = (UINT16) GetBits (Sd, 2);
- CharC--;
- while ((INT16) (CharC) >= 0 && Index < NPT) {
- Sd->mPTLen[Index++] = 0;
- CharC--;
- }
- }
- }
- while (Index < nn && Index < NPT) {
- Sd->mPTLen[Index++] = 0;
- }
- return MakeTable (Sd, nn, Sd->mPTLen, 8, Sd->mPTTable);
- }
- STATIC
- VOID
- ReadCLen (
- SCRATCH_DATA *Sd
- )
- /*++
- Routine Description:
- Reads code lengths for Char&Len Set.
- Arguments:
- Sd - the global scratch data
- Returns: (VOID)
- --*/
- {
- UINT16 Number;
- UINT16 CharC;
- UINT16 Index;
- UINT32 Mask;
- Number = (UINT16) GetBits (Sd, CBIT);
- if (Number == 0) {
- CharC = (UINT16) GetBits (Sd, CBIT);
- for (Index = 0; Index < NC; Index++) {
- Sd->mCLen[Index] = 0;
- }
- for (Index = 0; Index < 4096; Index++) {
- Sd->mCTable[Index] = CharC;
- }
- return ;
- }
- Index = 0;
- while (Index < Number) {
- CharC = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];
- if (CharC >= NT) {
- Mask = 1U << (BITBUFSIZ - 1 - 8);
- do {
- if (Mask & Sd->mBitBuf) {
- CharC = Sd->mRight[CharC];
- } else {
- CharC = Sd->mLeft[CharC];
- }
- Mask >>= 1;
- } while (CharC >= NT);
- }
- //
- // Advance what we have read
- //
- FillBuf (Sd, Sd->mPTLen[CharC]);
- if (CharC <= 2) {
- if (CharC == 0) {
- CharC = 1;
- } else if (CharC == 1) {
- CharC = (UINT16) (GetBits (Sd, 4) + 3);
- } else if (CharC == 2) {
- CharC = (UINT16) (GetBits (Sd, CBIT) + 20);
- }
- CharC--;
- while ((INT16) (CharC) >= 0) {
- Sd->mCLen[Index++] = 0;
- CharC--;
- }
- } else {
- Sd->mCLen[Index++] = (UINT8) (CharC - 2);
- }
- }
- while (Index < NC) {
- Sd->mCLen[Index++] = 0;
- }
- MakeTable (Sd, NC, Sd->mCLen, 12, Sd->mCTable);
- return ;
- }
- STATIC
- UINT16
- DecodeC (
- SCRATCH_DATA *Sd
- )
- /*++
- Routine Description:
- Decode a character/length value.
- Arguments:
- Sd - The global scratch data.
- Returns:
- The value decoded.
- --*/
- {
- UINT16 Index2;
- UINT32 Mask;
- if (Sd->mBlockSize == 0) {
- //
- // Starting a new block
- //
- Sd->mBlockSize = (UINT16) GetBits (Sd, 16);
- Sd->mBadTableFlag = ReadPTLen (Sd, NT, TBIT, 3);
- if (Sd->mBadTableFlag != 0) {
- return 0;
- }
- ReadCLen (Sd);
- Sd->mBadTableFlag = ReadPTLen (Sd, MAXNP, mPbit, (UINT16) (-1));
- if (Sd->mBadTableFlag != 0) {
- return 0;
- }
- }
- Sd->mBlockSize--;
- Index2 = Sd->mCTable[Sd->mBitBuf >> (BITBUFSIZ - 12)];
- if (Index2 >= NC) {
- Mask = 1U << (BITBUFSIZ - 1 - 12);
- do {
- if (Sd->mBitBuf & Mask) {
- Index2 = Sd->mRight[Index2];
- } else {
- Index2 = Sd->mLeft[Index2];
- }
- Mask >>= 1;
- } while (Index2 >= NC);
- }
- //
- // Advance what we have read
- //
- FillBuf (Sd, Sd->mCLen[Index2]);
- return Index2;
- }
- STATIC
- VOID
- Decode (
- SCRATCH_DATA *Sd
- )
- /*++
- Routine Description:
- Decode the source data and put the resulting data into the destination buffer.
- Arguments:
- Sd - The global scratch data
- Returns: (VOID)
- --*/
- {
- UINT16 BytesRemain;
- UINT32 DataIdx;
- UINT16 CharC;
- BytesRemain = (UINT16) (-1);
- DataIdx = 0;
- for (;;) {
- CharC = DecodeC (Sd);
- if (Sd->mBadTableFlag != 0) {
- return ;
- }
- if (CharC < 256) {
- //
- // Process an Original character
- //
- Sd->mDstBase[Sd->mOutBuf++] = (UINT8) CharC;
- if (Sd->mOutBuf >= Sd->mOrigSize) {
- return ;
- }
- } else {
- //
- // Process a Pointer
- //
- CharC = (UINT16) (CharC - (UINT8_MAX + 1 - THRESHOLD));
- BytesRemain = CharC;
- DataIdx = Sd->mOutBuf - DecodeP (Sd) - 1;
- BytesRemain--;
- while ((INT16) (BytesRemain) >= 0) {
- if (Sd->mOutBuf >= Sd->mOrigSize) {
- return ;
- }
- if (DataIdx >= Sd->mOrigSize) {
- Sd->mBadTableFlag = (UINT16) BAD_TABLE;
- return ;
- }
- Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];
- BytesRemain--;
- }
- //
- // Once mOutBuf is fully filled, directly return
- //
- if (Sd->mOutBuf >= Sd->mOrigSize) {
- return ;
- }
- }
- }
- return ;
- }
- EFI_STATUS
- GetInfo (
- IN VOID *Source,
- IN UINT32 SrcSize,
- OUT UINT32 *DstSize,
- OUT UINT32 *ScratchSize
- )
- /*++
- Routine Description:
- The implementation of EFI_DECOMPRESS_PROTOCOL.GetInfo().
- Arguments:
- Source - The source buffer containing the compressed data.
- SrcSize - The size of source buffer
- DstSize - The size of destination buffer.
- ScratchSize - The size of scratch buffer.
- Returns:
- EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successfully retrieved.
- EFI_INVALID_PARAMETER - The source data is corrupted
- --*/
- {
- UINT8 *Src;
- UINT32 CompSize;
- *ScratchSize = sizeof (SCRATCH_DATA);
- Src = Source;
- if (SrcSize < 8) {
- return EFI_INVALID_PARAMETER;
- }
- CompSize = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);
- *DstSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);
- if (SrcSize < CompSize + 8 || (CompSize + 8) < 8) {
- return EFI_INVALID_PARAMETER;
- }
- return EFI_SUCCESS;
- }
- EFI_STATUS
- Decompress (
- IN VOID *Source,
- IN UINT32 SrcSize,
- IN OUT VOID *Destination,
- IN UINT32 DstSize,
- IN OUT VOID *Scratch,
- IN UINT32 ScratchSize
- )
- /*++
- Routine Description:
- The implementation Efi and Tiano Decompress().
- Arguments:
- Source - The source buffer containing the compressed data.
- SrcSize - The size of source buffer
- Destination - The destination buffer to store the decompressed data
- DstSize - The size of destination buffer.
- Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
- ScratchSize - The size of scratch buffer.
- Returns:
- EFI_SUCCESS - Decompression is successful
- EFI_INVALID_PARAMETER - The source data is corrupted
- --*/
- {
- UINT32 Index;
- UINT32 CompSize;
- UINT32 OrigSize;
- EFI_STATUS Status;
- SCRATCH_DATA *Sd;
- UINT8 *Src;
- UINT8 *Dst;
- Status = EFI_SUCCESS;
- Src = Source;
- Dst = Destination;
- if (ScratchSize < sizeof (SCRATCH_DATA)) {
- return EFI_INVALID_PARAMETER;
- }
- Sd = (SCRATCH_DATA *) Scratch;
- if (SrcSize < 8) {
- return EFI_INVALID_PARAMETER;
- }
- CompSize = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);
- OrigSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);
- if (SrcSize < CompSize + 8 || (CompSize + 8) < 8) {
- return EFI_INVALID_PARAMETER;
- }
- if (DstSize != OrigSize) {
- return EFI_INVALID_PARAMETER;
- }
- Src = Src + 8;
- for (Index = 0; Index < sizeof (SCRATCH_DATA); Index++) {
- ((UINT8 *) Sd)[Index] = 0;
- }
- Sd->mSrcBase = Src;
- Sd->mDstBase = Dst;
- Sd->mCompSize = CompSize;
- Sd->mOrigSize = OrigSize;
- //
- // Fill the first BITBUFSIZ bits
- //
- FillBuf (Sd, BITBUFSIZ);
- //
- // Decompress it
- //
- Decode (Sd);
- if (Sd->mBadTableFlag != 0) {
- //
- // Something wrong with the source
- //
- Status = EFI_INVALID_PARAMETER;
- }
- return Status;
- }
- EFI_STATUS
- EfiGetInfo (
- IN VOID *Source,
- IN UINT32 SrcSize,
- OUT UINT32 *DstSize,
- OUT UINT32 *ScratchSize
- )
- /*++
- Routine Description:
- The implementation Efi Decompress GetInfo().
- Arguments:
- Source - The source buffer containing the compressed data.
- SrcSize - The size of source buffer
- DstSize - The size of destination buffer.
- ScratchSize - The size of scratch buffer.
- Returns:
- EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successfully retrieved.
- EFI_INVALID_PARAMETER - The source data is corrupted
- --*/
- {
- return GetInfo (Source, SrcSize, DstSize, ScratchSize);
- }
- EFI_STATUS
- TianoGetInfo (
- IN VOID *Source,
- IN UINT32 SrcSize,
- OUT UINT32 *DstSize,
- OUT UINT32 *ScratchSize
- )
- /*++
- Routine Description:
- The implementation Tiano Decompress GetInfo().
- Arguments:
- Source - The source buffer containing the compressed data.
- SrcSize - The size of source buffer
- DstSize - The size of destination buffer.
- ScratchSize - The size of scratch buffer.
- Returns:
- EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successfully retrieved.
- EFI_INVALID_PARAMETER - The source data is corrupted
- --*/
- {
- return GetInfo (Source, SrcSize, DstSize, ScratchSize);
- }
- EFI_STATUS
- EfiDecompress (
- IN VOID *Source,
- IN UINT32 SrcSize,
- IN OUT VOID *Destination,
- IN UINT32 DstSize,
- IN OUT VOID *Scratch,
- IN UINT32 ScratchSize
- )
- /*++
- Routine Description:
- The implementation of Efi Decompress().
- Arguments:
- Source - The source buffer containing the compressed data.
- SrcSize - The size of source buffer
- Destination - The destination buffer to store the decompressed data
- DstSize - The size of destination buffer.
- Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
- ScratchSize - The size of scratch buffer.
- Returns:
- EFI_SUCCESS - Decompression is successful
- EFI_INVALID_PARAMETER - The source data is corrupted
- --*/
- {
- mPbit = EFIPBIT;
- return Decompress (Source, SrcSize, Destination, DstSize, Scratch, ScratchSize);
- }
- EFI_STATUS
- TianoDecompress (
- IN VOID *Source,
- IN UINT32 SrcSize,
- IN OUT VOID *Destination,
- IN UINT32 DstSize,
- IN OUT VOID *Scratch,
- IN UINT32 ScratchSize
- )
- /*++
- Routine Description:
- The implementation of Tiano Decompress().
- Arguments:
- Source - The source buffer containing the compressed data.
- SrcSize - The size of source buffer
- Destination - The destination buffer to store the decompressed data
- DstSize - The size of destination buffer.
- Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
- ScratchSize - The size of scratch buffer.
- Returns:
- EFI_SUCCESS - Decompression is successful
- EFI_INVALID_PARAMETER - The source data is corrupted
- --*/
- {
- mPbit = MAXPBIT;
- return Decompress (Source, SrcSize, Destination, DstSize, Scratch, ScratchSize);
- }
- EFI_STATUS
- Extract (
- IN VOID *Source,
- IN UINT32 SrcSize,
- OUT VOID **Destination,
- OUT UINT32 *DstSize,
- IN UINTN Algorithm
- )
- {
- VOID *Scratch;
- UINT32 ScratchSize;
- EFI_STATUS Status;
- Scratch = NULL;
- Status = EFI_SUCCESS;
- switch (Algorithm) {
- case 0:
- *Destination = (VOID *)malloc(SrcSize);
- if (*Destination != NULL) {
- memcpy(*Destination, Source, SrcSize);
- } else {
- Status = EFI_OUT_OF_RESOURCES;
- }
- break;
- case 1:
- Status = EfiGetInfo(Source, SrcSize, DstSize, &ScratchSize);
- if (Status == EFI_SUCCESS) {
- Scratch = (VOID *)malloc(ScratchSize);
- if (Scratch == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- *Destination = (VOID *)malloc(*DstSize);
- if (*Destination == NULL) {
- free (Scratch);
- return EFI_OUT_OF_RESOURCES;
- }
- Status = EfiDecompress(Source, SrcSize, *Destination, *DstSize, Scratch, ScratchSize);
- }
- break;
- case 2:
- Status = TianoGetInfo(Source, SrcSize, DstSize, &ScratchSize);
- if (Status == EFI_SUCCESS) {
- Scratch = (VOID *)malloc(ScratchSize);
- if (Scratch == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- *Destination = (VOID *)malloc(*DstSize);
- if (*Destination == NULL) {
- free (Scratch);
- return EFI_OUT_OF_RESOURCES;
- }
- Status = TianoDecompress(Source, SrcSize, *Destination, *DstSize, Scratch, ScratchSize);
- }
- break;
- default:
- Status = EFI_INVALID_PARAMETER;
- }
- if (Scratch != NULL) {
- free (Scratch);
- }
- return Status;
- }
|