decompress.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,105 行 · 第 1/2 页
C
1,105 行
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);
}
while ((INT16) (--CharC) >= 0) {
Sd->mCLen[Index++] = 0;
}
} 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, Sd->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
//
if (Sd->mOutBuf >= Sd->mOrigSize) {
return ;
} else {
Sd->mDstBase[Sd->mOutBuf++] = (UINT8) CharC;
}
} else {
//
// Process a Pointer
//
CharC = (UINT16) (CharC - (UINT8_MAX + 1 - THRESHOLD));
BytesRemain = CharC;
DataIdx = Sd->mOutBuf - DecodeP (Sd) - 1;
BytesRemain--;
while ((INT16) (BytesRemain) >= 0) {
Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];
if (Sd->mOutBuf >= Sd->mOrigSize) {
return ;
}
BytesRemain--;
}
}
}
return ;
}
EFI_STATUS
GetInfo (
IN VOID *Source,
IN UINT32 SrcSize,
OUT UINT32 *DstSize,
OUT UINT32 *ScratchSize
)
/*++
Routine Description:
The internal implementation of *_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 successull retrieved.
EFI_INVALID_PARAMETER - The source data is corrupted
--*/
{
UINT8 *Src;
*ScratchSize = sizeof (SCRATCH_DATA);
Src = Source;
if (SrcSize < 8) {
return EFI_INVALID_PARAMETER;
}
*DstSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);
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,
IN UINT8 Version
)
/*++
Routine Description:
The internal implementation of *_DECOMPRESS_PROTOCOL.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.
Version - The version of de/compression algorithm.
Version 1 for EFI 1.1 de/compression algorithm.
Version 2 for Tiano de/compression algorithm.
Returns:
EFI_SUCCESS - Decompression is successfull
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 compressed file size is 0, return
//
if (OrigSize == 0) {
return Status;
}
if (SrcSize < CompSize + 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;
}
//
// The length of the field 'Position Set Code Length Array Size' in Block Header.
// For EFI 1.1 de/compression algorithm(Version 1), mPBit = 4
// For Tiano de/compression algorithm(Version 2), mPBit = 5
//
switch (Version) {
case 1:
Sd->mPBit = 4;
break;
case 2:
Sd->mPBit = 5;
break;
default:
//
// Currently, only have 2 versions
//
return EFI_INVALID_PARAMETER;
}
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
EFIAPI
EfiGetInfo (
IN EFI_DECOMPRESS_PROTOCOL *This,
IN VOID *Source,
IN UINT32 SrcSize,
OUT UINT32 *DstSize,
OUT UINT32 *ScratchSize
)
/*++
Routine Description:
The implementation of EFI_DECOMPRESS_PROTOCOL.GetInfo().
Arguments:
This - The protocol instance pointer
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 successull retrieved.
EFI_INVALID_PARAMETER - The source data is corrupted
--*/
{
return GetInfo (
Source,
SrcSize,
DstSize,
ScratchSize
);
}
EFI_STATUS
EFIAPI
EfiDecompress (
IN EFI_DECOMPRESS_PROTOCOL *This,
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_PROTOCOL.Decompress().
Arguments:
This - The protocol instance pointer
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 successfull
EFI_INVALID_PARAMETER - The source data is corrupted
--*/
{
//
// For EFI 1.1 de/compression algorithm, the version is 1.
//
return Decompress (
Source,
SrcSize,
Destination,
DstSize,
Scratch,
ScratchSize,
1
);
}
EFI_STATUS
EFIAPI
TianoGetInfo (
IN EFI_TIANO_DECOMPRESS_PROTOCOL *This,
IN VOID *Source,
IN UINT32 SrcSize,
OUT UINT32 *DstSize,
OUT UINT32 *ScratchSize
)
/*++
Routine Description:
The implementation of EFI_TIANO_DECOMPRESS_PROTOCOL.GetInfo().
Arguments:
This - The protocol instance pointer
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 successull retrieved.
EFI_INVALID_PARAMETER - The source data is corrupted
--*/
{
return GetInfo (
Source,
SrcSize,
DstSize,
ScratchSize
);
}
EFI_STATUS
EFIAPI
TianoDecompress (
IN EFI_TIANO_DECOMPRESS_PROTOCOL *This,
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_TIANO_DECOMPRESS_PROTOCOL.Decompress().
Arguments:
This - The protocol instance pointer
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 successfull
EFI_INVALID_PARAMETER - The source data is corrupted
--*/
{
//
// For Tiano de/compression algorithm, the version is 2.
//
return Decompress (
Source,
SrcSize,
Destination,
DstSize,
Scratch,
ScratchSize,
2
);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?