/** @file\r
+Compression routine. The compression algorithm is a mixture of LZ77 and Huffman\r
+coding. LZ77 transforms the source data into a sequence of Original Characters\r
+and Pointers to repeated strings.\r
+This sequence is further divided into Blocks and Huffman codings are applied to\r
+each Block.\r
\r
-Copyright (c) 2007 - 2008, Intel Corporation \r
-All rights reserved. This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
\r
-Module Name:\r
-\r
- TianoCompress.c\r
-\r
-Abstract:\r
-\r
- Compression routine. The compression algorithm is a mixture of\r
- LZ77 and Huffman coding. LZ77 transforms the source data into a\r
- sequence of Original Characters and Pointers to repeated strings.\r
- This sequence is further divided into Blocks and Huffman codings\r
- are applied to each Block.\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
\r
**/\r
\r
#include "Compress.h"\r
+#include "Decompress.h"\r
#include "TianoCompress.h"\r
#include "EfiUtilityMsgs.h"\r
#include "ParseInf.h"\r
//\r
STATIC BOOLEAN ENCODE = FALSE;\r
STATIC BOOLEAN DECODE = FALSE;\r
+STATIC BOOLEAN UEFIMODE = FALSE;\r
STATIC UINT8 *mSrc, *mDst, *mSrcUpperLimit, *mDstUpperLimit;\r
STATIC UINT8 *mLevel, *mText, *mChildCount, *mBuf, mCLen[NC], mPTLen[NPT], *mLen;\r
STATIC INT16 mHeap[NC + 1];\r
SrcBuffer - The buffer storing the source data\r
SrcSize - The size of source data\r
DstBuffer - The buffer to store the compressed data\r
- \r
+\r
Version - The version of de/compression algorithm.\r
Version 1 for EFI 1.1 de/compression algorithm.\r
Version 2 for Tiano de/compression algorithm.\r
mSrcUpperLimit = mSrc + SrcSize;\r
mDst = DstBuffer;\r
mDstUpperLimit = mDst +*DstSize;\r
- \r
+\r
PutDword (0L);\r
PutDword (0L);\r
- \r
+\r
MakeCrcTable ();\r
- \r
+\r
mOrigSize = mCompSize = 0;\r
mCrc = INIT_CRC;\r
\r
if (EFI_ERROR (Status)) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
- \r
+\r
//\r
// Null terminate the compressed data\r
//\r
//\r
// Fill in compressed size and original size\r
//\r
- mDst = DstBuffer; \r
- \r
+ mDst = DstBuffer;\r
+\r
PutDword (mCompSize + 1);\r
PutDword (mOrigSize);\r
//\r
//\r
\r
if (mCompSize + 1 + 8 > *DstSize) {\r
- *DstSize = mCompSize + 1 + 8; \r
+ *DstSize = mCompSize + 1 + 8;\r
return EFI_BUFFER_TOO_SMALL;\r
} else {\r
- *DstSize = mCompSize + 1 + 8; \r
+ *DstSize = mCompSize + 1 + 8;\r
return EFI_SUCCESS;\r
}\r
}\r
Routine Description:\r
\r
Put a dword to output stream\r
- \r
+\r
Arguments:\r
\r
Data - the dword to put\r
- \r
+\r
Returns: (VOID)\r
- \r
+\r
--*/\r
{\r
if (mDst < mDstUpperLimit) {\r
Routine Description:\r
\r
Allocate memory spaces for data structures used in compression process\r
- \r
-Argements: \r
+\r
+Arguments:\r
VOID\r
\r
Returns:\r
UINT32 Index;\r
\r
mText = malloc (WNDSIZ * 2 + MAXMATCH);\r
+ if (mText == NULL) {\r
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
for (Index = 0; Index < WNDSIZ * 2 + MAXMATCH; Index++) {\r
mText[Index] = 0;\r
}\r
mParent = malloc (WNDSIZ * 2 * sizeof (*mParent));\r
mPrev = malloc (WNDSIZ * 2 * sizeof (*mPrev));\r
mNext = malloc ((MAX_HASH_VAL + 1) * sizeof (*mNext));\r
+ if (mLevel == NULL || mChildCount == NULL || mPosition == NULL ||\r
+ mParent == NULL || mPrev == NULL || mNext == NULL) {\r
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
\r
mBufSiz = BLKSIZ;\r
mBuf = malloc (mBufSiz);\r
Routine Description:\r
\r
Called when compression is completed to free memory previously allocated.\r
- \r
+\r
Arguments: (VOID)\r
\r
Returns: (VOID)\r
Routine Description:\r
\r
Initialize String Info Log data structures\r
- \r
+\r
Arguments: (VOID)\r
\r
Returns: (VOID)\r
Routine Description:\r
\r
Find child node given the parent node and the edge character\r
- \r
+\r
Arguments:\r
\r
NodeQ - the parent node\r
CharC - the edge character\r
- \r
+\r
Returns:\r
\r
- The child node (NIL if not found) \r
- \r
+ The child node (NIL if not found)\r
+\r
--*/\r
{\r
NODE NodeR;\r
Routine Description:\r
\r
Create a new child for a given parent node.\r
- \r
+\r
Arguments:\r
\r
Parent - the parent node\r
CharC - the edge character\r
Child - the child node\r
- \r
+\r
Returns: (VOID)\r
\r
--*/\r
Routine Description:\r
\r
Split a node.\r
- \r
+\r
Arguments:\r
\r
Old - the node to split\r
- \r
+\r
Returns: (VOID)\r
\r
--*/\r
Routine Description:\r
\r
Insert string info for current position into the String Info Log\r
- \r
+\r
Arguments: (VOID)\r
\r
Returns: (VOID)\r
if (mMatchLen >= 4) {\r
//\r
// We have just got a long match, the target tree\r
- // can be located by MatchPos + 1. Travese the tree\r
+ // can be located by MatchPos + 1. Traverse the tree\r
// from bottom up to get to a proper starting point.\r
// The usage of PERC_FLAG ensures proper node deletion\r
// in DeleteNode() later.\r
\r
Delete outdated string info. (The Usage of PERC_FLAG\r
ensures a clean deletion)\r
- \r
+\r
Arguments: (VOID)\r
\r
Returns: (VOID)\r
Arguments: (VOID)\r
\r
Returns:\r
- \r
+\r
EFI_SUCCESS - The compression is successful\r
EFI_OUT_0F_RESOURCES - Not enough memory for compression process\r
\r
Routine Description:\r
\r
Count the frequencies for the Extra Set\r
- \r
+\r
Arguments: (VOID)\r
\r
Returns: (VOID)\r
Routine Description:\r
\r
Outputs the code length array for the Extra Set or the Position Set.\r
- \r
+\r
Arguments:\r
\r
Number - the number of symbols\r
nbit - the number of bits needed to represent 'n'\r
Special - the special symbol that needs to be take care of\r
- \r
+\r
Returns: (VOID)\r
\r
--*/\r
Routine Description:\r
\r
Outputs the code length array for Char&Length Set\r
- \r
+\r
Arguments: (VOID)\r
\r
Returns: (VOID)\r
Routine Description:\r
\r
Huffman code the block and output it.\r
- \r
-Arguments: \r
+\r
+Arguments:\r
(VOID)\r
\r
-Returns: \r
+Returns:\r
(VOID)\r
\r
--*/\r
Arguments:\r
\r
Number - the rightmost n bits of the data is used\r
- x - the data \r
+ x - the data\r
\r
Returns: (VOID)\r
\r
Routine Description:\r
\r
Read in source data\r
- \r
+\r
Arguments:\r
\r
Pointer - the buffer to hold the data\r
Returns:\r
\r
number of bytes actually read\r
- \r
+\r
--*/\r
{\r
INT32 Index;\r
Routine Description:\r
\r
Count the number of each code length for a Huffman tree.\r
- \r
+\r
Arguments:\r
\r
Index - the top node\r
- \r
+\r
Returns: (VOID)\r
\r
--*/\r
Routine Description:\r
\r
Create code length array for a Huffman tree\r
- \r
+\r
Arguments:\r
\r
Root - the root of the tree\r
- \r
+\r
Returns:\r
\r
VOID\r
Routine Description:\r
\r
Assign code to each symbol based on the code length array\r
- \r
+\r
Arguments:\r
\r
Number - number of symbols\r
Routine Description:\r
\r
Generates Huffman codes given a frequency distribution of symbols\r
- \r
+\r
Arguments:\r
\r
NParm - number of symbols\r
FreqParm - frequency of each symbol\r
LenParm - code length for each symbol\r
CodeParm - code for each symbol\r
- \r
+\r
Returns:\r
\r
Root of the Huffman tree.\r
- \r
+\r
--*/\r
{\r
INT32 Index;\r
OUT UINT32 *BufferLength\r
)\r
/*++\r
- \r
+\r
Routine Description:\r
- \r
+\r
Get the contents of file specified in InputFileName\r
into FileBuffer.\r
- \r
+\r
Arguments:\r
- \r
+\r
InputFileName - Name of the input file.\r
- \r
+\r
FileBuffer - Output buffer to contain data\r
\r
- BufferLength - Actual length of the data \r
+ BufferLength - Actual length of the data\r
\r
Returns:\r
- \r
+\r
EFI_SUCCESS on successful return\r
EFI_ABORTED if unable to open input file.\r
\r
//\r
// Copy the file contents to the output buffer.\r
//\r
- InputFile = fopen (InputFileName, "rb");\r
+ InputFile = fopen (LongFilePath (InputFileName), "rb");\r
if (InputFile == NULL) {\r
Error (NULL, 0, 0001, "Error opening file: %s", InputFileName);\r
return EFI_ABORTED;\r
}\r
- \r
+\r
fseek (InputFile, 0, SEEK_END);\r
FileSize = ftell (InputFile);\r
fseek (InputFile, 0, SEEK_SET);\r
//\r
// Now read the contents of the file into the buffer\r
- // \r
+ //\r
if (FileSize > 0 && FileBuffer != NULL) {\r
if (fread (FileBuffer, FileSize, 1, InputFile) != 1) {\r
Error (NULL, 0, 0004, "Error reading contents of input file: %s", InputFileName);\r
fclose (InputFile);\r
Size += (UINTN) FileSize;\r
*BufferLength = Size;\r
- \r
+\r
if (FileBuffer != NULL) {\r
return EFI_SUCCESS;\r
} else {\r
\r
--*/\r
{\r
- fprintf (stdout, "%s Version %d.%d\n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION);\r
+ fprintf (stdout, "%s Version %d.%d %s \n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION);\r
}\r
\r
VOID\r
// Summary usage\r
//\r
fprintf (stdout, "Usage: %s -e|-d [options] <input_file>\n\n", UTILITY_NAME);\r
- \r
+\r
//\r
// Copyright declaration\r
- // \r
- fprintf (stdout, "Copyright (c) 2007, Intel Corporation. All rights reserved.\n\n");\r
+ //\r
+ fprintf (stdout, "Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.\n\n");\r
\r
//\r
// Details Option\r
//\r
fprintf (stdout, "Options:\n");\r
+ fprintf (stdout, " --uefi\n\\r
+ Enable UefiCompress, use TianoCompress when without this option\n");\r
fprintf (stdout, " -o FileName, --output FileName\n\\r
- File will be created to store the ouput content.\n");\r
+ File will be created to store the output content.\n");\r
fprintf (stdout, " -v, --verbose\n\\r
Turn on verbose output with informational messages.\n");\r
fprintf (stdout, " -q, --quiet\n\\r
EFI_ABORTED Could not generate the section\r
EFI_OUT_OF_RESOURCES No resource to complete the operation.\r
\r
---*/ \r
+--*/\r
{\r
FILE *OutputFile;\r
char *OutputFileName;\r
SCRATCH_DATA *Scratch;\r
UINT8 *Src;\r
UINT32 OrigSize;\r
+ UINT32 CompSize;\r
\r
SetUtilityName(UTILITY_NAME);\r
- \r
+\r
FileBuffer = NULL;\r
Src = NULL;\r
OutBuffer = NULL;\r
Scratch = NULL;\r
OrigSize = 0;\r
+ CompSize = 0;\r
InputLength = 0;\r
InputFileName = NULL;\r
OutputFileName = NULL;\r
+ InputFile = NULL;\r
+ OutputFile = NULL;\r
DstSize=0;\r
DebugLevel = 0;\r
DebugMode = FALSE;\r
Usage();\r
return 0;\r
}\r
- \r
+\r
if ((strcmp(argv[1], "-h") == 0) || (strcmp(argv[1], "--help") == 0)) {\r
Usage();\r
return 0;\r
}\r
- \r
+\r
if ((strcmp(argv[1], "--version") == 0)) {\r
Version();\r
return 0;\r
continue;\r
}\r
\r
+ if (stricmp(argv[0], "--uefi") == 0) {\r
+ UEFIMODE = TRUE;\r
+ argc--;\r
+ argv++;\r
+ continue;\r
+ }\r
+\r
if (stricmp (argv[0], "--debug") == 0) {\r
argc-=2;\r
argv++;\r
OutputFileName = argv[1];\r
argc -=2;\r
argv +=2;\r
- continue; \r
+ continue;\r
}\r
\r
if (argv[0][0]!='-') {\r
}\r
\r
Error (NULL, 0, 1000, "Unknown option", argv[0]);\r
- goto ERROR; \r
+ goto ERROR;\r
}\r
\r
if (InputFileName == NULL) {\r
} else if (DebugMode) {\r
SetPrintLevel(DebugLevel);\r
}\r
- \r
+\r
if (VerboseMode) {\r
VerboseMsg("%s tool start.\n", UTILITY_NAME);\r
}\r
Error (NULL, 0, 4001, "Resource:", "Memory cannot be allocated!");\r
goto ERROR;\r
}\r
- \r
- InputFile = fopen (InputFileName, "rb");\r
+\r
+ InputFile = fopen (LongFilePath (InputFileName), "rb");\r
if (InputFile == NULL) {\r
Error (NULL, 0, 0001, "Error opening input file", InputFileName);\r
goto ERROR;\r
}\r
- \r
+\r
Status = GetFileContents(\r
InputFileName,\r
FileBuffer,\r
FileBuffer = (UINT8 *) malloc (InputLength);\r
if (FileBuffer == NULL) {\r
Error (NULL, 0, 4001, "Resource:", "Memory cannot be allocated!");\r
- return 1;\r
+ goto ERROR;\r
}\r
\r
Status = GetFileContents (\r
}\r
\r
if (EFI_ERROR(Status)) {\r
- free(FileBuffer);\r
- return 1;\r
+ Error (NULL, 0, 0004, "Error getting contents of file: %s", InputFileName);\r
+ goto ERROR;\r
}\r
- \r
- if (OutputFileName != NULL) {\r
- OutputFile = fopen (OutputFileName, "wb");\r
- if (OutputFile == NULL) {\r
- Error (NULL, 0, 0001, "Error opening output file for writing", OutputFileName);\r
- if (InputFile != NULL) {\r
- fclose (InputFile);\r
- }\r
- goto ERROR;\r
- }\r
- } else {\r
- OutputFileName = DEFAULT_OUTPUT_FILE;\r
- OutputFile = fopen (OutputFileName, "wb");\r
- }\r
- \r
+\r
+ if (OutputFileName == NULL) {\r
+ OutputFileName = DEFAULT_OUTPUT_FILE;\r
+ }\r
+ OutputFile = fopen (LongFilePath (OutputFileName), "wb");\r
+ if (OutputFile == NULL) {\r
+ Error (NULL, 0, 0001, "Error opening output file for writing", OutputFileName);\r
+ goto ERROR;\r
+ }\r
+\r
if (ENCODE) {\r
//\r
// First call TianoCompress to get DstSize\r
if (DebugMode) {\r
DebugMsg(UTILITY_NAME, 0, DebugLevel, "Encoding", NULL);\r
}\r
- Status = TianoCompress ((UINT8 *)FileBuffer, InputLength, OutBuffer, &DstSize);\r
- \r
+ if (UEFIMODE) {\r
+ Status = EfiCompress ((UINT8 *)FileBuffer, InputLength, OutBuffer, &DstSize);\r
+ } else {\r
+ Status = TianoCompress ((UINT8 *)FileBuffer, InputLength, OutBuffer, &DstSize);\r
+ }\r
+\r
if (Status == EFI_BUFFER_TOO_SMALL) {\r
OutBuffer = (UINT8 *) malloc (DstSize);\r
if (OutBuffer == NULL) {\r
goto ERROR;\r
}\r
}\r
- Status = TianoCompress ((UINT8 *)FileBuffer, InputLength, OutBuffer, &DstSize);\r
+\r
+ if (UEFIMODE) {\r
+ Status = EfiCompress ((UINT8 *)FileBuffer, InputLength, OutBuffer, &DstSize);\r
+ } else {\r
+ Status = TianoCompress ((UINT8 *)FileBuffer, InputLength, OutBuffer, &DstSize);\r
+ }\r
if (Status != EFI_SUCCESS) {\r
Error (NULL, 0, 0007, "Error compressing file", NULL);\r
goto ERROR;\r
}\r
\r
+ if (OutBuffer == NULL) {\r
+ Error (NULL, 0, 4001, "Resource:", "Memory cannot be allocated!");\r
+ goto ERROR;\r
+ }\r
+\r
fwrite(OutBuffer,(size_t)DstSize, 1, OutputFile);\r
+ fclose(OutputFile);\r
+ fclose(InputFile);\r
free(Scratch);\r
free(FileBuffer);\r
free(OutBuffer);\r
if (VerboseMode) {\r
VerboseMsg("Encoding successful\n");\r
}\r
- return 0; \r
+ return 0;\r
}\r
else if (DECODE) {\r
if (DebugMode) {\r
DebugMsg(UTILITY_NAME, 0, DebugLevel, "Decoding\n", NULL);\r
}\r
- //\r
- // Get Compressed file original size\r
- // \r
- Src = (UINT8 *)FileBuffer; \r
- OrigSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24); \r
- \r
- //\r
- // Allocate OutputBuffer\r
- //\r
- OutBuffer = (UINT8 *)malloc(OrigSize);\r
- if (OutBuffer == NULL) {\r
- Error (NULL, 0, 4001, "Resource:", "Memory cannot be allocated!");\r
- goto ERROR;\r
- } \r
\r
- Status = Decompress((VOID *)FileBuffer, (VOID *)OutBuffer, (VOID *)Scratch, 2);\r
- if (Status != EFI_SUCCESS) {\r
- goto ERROR; \r
- }\r
+ if (UEFIMODE) {\r
+ Status = Extract((VOID *)FileBuffer, InputLength, (VOID *)&OutBuffer, &DstSize, 1);\r
+ if (Status != EFI_SUCCESS) {\r
+ goto ERROR;\r
+ }\r
+ fwrite(OutBuffer, (size_t)(DstSize), 1, OutputFile);\r
+ } else {\r
+ if (InputLength < 8){\r
+ Error (NULL, 0, 3000, "Invalid", "The input file %s is too small.", InputFileName);\r
+ goto ERROR;\r
+ }\r
+ //\r
+ // Get Compressed file original size\r
+ //\r
+ Src = (UINT8 *)FileBuffer;\r
+ OrigSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);\r
+ CompSize = Src[0] + (Src[1] << 8) + (Src[2] <<16) + (Src[3] <<24);\r
\r
- fwrite(OutBuffer, (size_t)(Scratch->mOrigSize), 1, OutputFile);\r
- free(Scratch);\r
- free(FileBuffer);\r
- free(OutBuffer);\r
+ //\r
+ // Allocate OutputBuffer\r
+ //\r
+ if (InputLength < CompSize + 8 || (CompSize + 8) < 8) {\r
+ Error (NULL, 0, 3000, "Invalid", "The input file %s data is invalid.", InputFileName);\r
+ goto ERROR;\r
+ }\r
+ OutBuffer = (UINT8 *)malloc(OrigSize);\r
+ if (OutBuffer == NULL) {\r
+ Error (NULL, 0, 4001, "Resource:", "Memory cannot be allocated!");\r
+ goto ERROR;\r
+ }\r
+\r
+ Status = TDecompress((VOID *)FileBuffer, (VOID *)OutBuffer, (VOID *)Scratch, 2);\r
+ if (Status != EFI_SUCCESS) {\r
+ goto ERROR;\r
+ }\r
+ fwrite(OutBuffer, (size_t)(Scratch->mOrigSize), 1, OutputFile);\r
+ }\r
+ fclose(OutputFile);\r
+ fclose(InputFile);\r
+ if (Scratch != NULL) {\r
+ free(Scratch);\r
+ }\r
+ if (FileBuffer != NULL) {\r
+ free(FileBuffer);\r
+ }\r
+ if (OutBuffer != NULL) {\r
+ free(OutBuffer);\r
+ }\r
\r
if (DebugMode) {\r
DebugMsg(UTILITY_NAME, 0, DebugLevel, "Encoding successful!\n", NULL);\r
}\r
- \r
+\r
if (VerboseMode) {\r
VerboseMsg("Decoding successful\n");\r
}\r
return 0;\r
}\r
- \r
+\r
ERROR:\r
if (DebugMode) {\r
if (ENCODE) {\r
DebugMsg(UTILITY_NAME, 0, DebugLevel, "Decoding Error\n", NULL);\r
}\r
}\r
+ if (OutputFile != NULL) {\r
+ fclose(OutputFile);\r
+ }\r
+ if (InputFile != NULL) {\r
+ fclose (InputFile);\r
+ }\r
if (Scratch != NULL) {\r
free(Scratch);\r
}\r
if (OutBuffer != NULL) {\r
free(OutBuffer);\r
}\r
- \r
+\r
if (VerboseMode) {\r
VerboseMsg("%s tool done with return code is 0x%x.\n", UTILITY_NAME, GetUtilityStatus ());\r
}\r
\r
--*/\r
{\r
- Sd->mBitBuf = (UINT32) (Sd->mBitBuf << NumOfBits);\r
+ Sd->mBitBuf = (UINT32) (((UINT64)Sd->mBitBuf) << NumOfBits);\r
\r
while (NumOfBits > Sd->mBitCount) {\r
\r
- Sd->mBitBuf |= (UINT32) (Sd->mSubBitBuf << (NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount)));\r
+ Sd->mBitBuf |= (UINT32) (((UINT64)Sd->mSubBitBuf) << (NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount)));\r
\r
if (Sd->mCompSize > 0) {\r
//\r
\r
Routine Description:\r
\r
- Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent \r
- NumOfBits of bits from source. Returns NumOfBits of bits that are \r
+ Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent\r
+ NumOfBits of bits from source. Returns NumOfBits of bits that are\r
popped out.\r
\r
Arguments:\r
BitLen - Code length array\r
TableBits - The width of the mapping table\r
Table - The table\r
- \r
+\r
Returns:\r
- \r
+\r
0 - OK.\r
BAD_TABLE - The table is corrupted.\r
\r
UINT16 Start[18];\r
UINT16 *Pointer;\r
UINT16 Index3;\r
- volatile UINT16 Index;\r
+ UINT16 Index;\r
UINT16 Len;\r
UINT16 Char;\r
UINT16 JuBits;\r
UINT16 Mask;\r
UINT16 WordOfStart;\r
UINT16 WordOfCount;\r
+ UINT16 MaxTableLength;\r
\r
- for (Index = 1; Index <= 16; Index++) {\r
+ for (Index = 0; Index <= 16; Index++) {\r
Count[Index] = 0;\r
}\r
\r
for (Index = 0; Index < NumOfChar; Index++) {\r
+ if (BitLen[Index] > 16) {\r
+ return (UINT16) BAD_TABLE;\r
+ }\r
Count[BitLen[Index]]++;\r
}\r
\r
+ Start[0] = 0;\r
Start[1] = 0;\r
\r
for (Index = 1; Index <= 16; Index++) {\r
\r
JuBits = (UINT16) (16 - TableBits);\r
\r
+ Weight[0] = 0;\r
for (Index = 1; Index <= TableBits; Index++) {\r
Start[Index] >>= JuBits;\r
Weight[Index] = (UINT16) (1U << (TableBits - Index));\r
\r
Avail = NumOfChar;\r
Mask = (UINT16) (1U << (15 - TableBits));\r
+ MaxTableLength = (UINT16) (1U << TableBits);\r
\r
for (Char = 0; Char < NumOfChar; Char++) {\r
\r
Len = BitLen[Char];\r
- if (Len == 0) {\r
+ if (Len == 0 || Len >= 17) {\r
continue;\r
}\r
\r
if (Len <= TableBits) {\r
\r
for (Index = Start[Len]; Index < NextCode; Index++) {\r
+ if (Index >= MaxTableLength) {\r
+ return (UINT16) BAD_TABLE;\r
+ }\r
Table[Index] = Char;\r
}\r
\r
Sd - The global scratch data\r
nn - Number of symbols\r
nbit - Number of bits needed to represent nn\r
- Special - The special symbol that needs to be taken care of \r
+ Special - The special symbol that needs to be taken care of\r
\r
Returns:\r
\r
volatile UINT16 Index;\r
UINT32 Mask;\r
\r
+ assert (nn <= NPT);\r
+\r
Number = (UINT16) GetBits (Sd, nbit);\r
\r
if (Number == 0) {\r
DataIdx = Sd->mOutBuf - DecodeP (Sd) - 1;\r
\r
BytesRemain--;\r
+\r
while ((INT16) (BytesRemain) >= 0) {\r
- Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];\r
if (Sd->mOutBuf >= Sd->mOrigSize) {\r
goto Done ;\r
}\r
+ if (DataIdx >= Sd->mOrigSize) {\r
+ Sd->mBadTableFlag = (UINT16) BAD_TABLE;\r
+ goto Done ;\r
+ }\r
+ Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];\r
\r
BytesRemain--;\r
}\r
+ //\r
+ // Once mOutBuf is fully filled, directly return\r
+ //\r
+ if (Sd->mOutBuf >= Sd->mOrigSize) {\r
+ goto Done ;\r
+ }\r
}\r
}\r
\r
\r
RETURN_STATUS\r
EFIAPI\r
-Decompress (\r
+TDecompress (\r
IN VOID *Source,\r
IN OUT VOID *Destination,\r
IN OUT VOID *Scratch,\r
Source - The source buffer containing the compressed data.\r
Destination - The destination buffer to store the decompressed data\r
Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.\r
- Version - 1 for EFI1.1 Decompress algoruthm, 2 for Tiano Decompress algorithm\r
+ Version - 1 for EFI1.1 Decompress algorithm, 2 for Tiano Decompress algorithm\r
\r
Returns:\r
\r
- RETURN_SUCCESS - Decompression is successfull\r
+ RETURN_SUCCESS - Decompression is successful\r
RETURN_INVALID_PARAMETER - The source data is corrupted\r
\r
--*/\r
assert(Source);\r
// assert(Destination);\r
assert(Scratch);\r
- \r
+\r
Src = (UINT8 *)Source;\r
Dst = (UINT8 *)Destination;\r
\r
Sd = (SCRATCH_DATA *) Scratch;\r
CompSize = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);\r
OrigSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);\r
- \r
+\r
//\r
// If compressed file size is 0, return\r
//\r
//\r
// Decompress it\r
//\r
- \r
+\r
Decode (Sd);\r
- \r
+\r
if (Sd->mBadTableFlag != 0) {\r
//\r
// Something wrong with the source\r