diff --git a/Tiano/EfiTianoCompress.c b/Tiano/EfiTianoCompress.c
index 0e64f5b..d13864c 100644
--- a/Tiano/EfiTianoCompress.c
+++ b/Tiano/EfiTianoCompress.c
@@ -1,4 +1,20 @@
-/* EfiTianoCompress.c
+/* EFI11/Tiano Compress Implementation
+
+Copyright (c) 2014, Nikolaj Schlej
+Copyright (c) 2006 - 2008, Intel Corporation
+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,
+WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+EfiTianoCompress.c
+
+Abstract:
Compression routine. The compression algorithm is a mixture of
LZ77 and Huffman coding. LZ77 transforms the source data into a
@@ -6,1400 +22,295 @@ sequence of Original Characters and Pointers to repeated strings.
This sequence is further divided into Blocks and Huffman codings
are applied to each Block.
-Copyright (c) 2014, Nikolaj Schlej. All rights reserved.
-Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.
-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 "EfiTianoCompress.h"
//
// Macro Definitions
//
-typedef INT16 NODE;
-#ifndef UINT8_MAX
-#define UINT8_MAX 0xff
-#endif
-#define UINT8_BIT 8
-#define THRESHOLD 3
-#define INIT_CRC 0
-#define WNDBIT 13
-#define WNDSIZ (1U << WNDBIT)
-#define MAXMATCH 256
-#define BLKSIZ (1U << 14) // 16 * 1024U
-#define PERC_FLAG 0x8000U
-#define CODE_BIT 16
-#define NIL 0
-#define MAX_HASH_VAL (3 * WNDSIZ + (WNDSIZ / 512 + 1) * UINT8_MAX)
-#define HASH(LoopVar7, LoopVar5) ((LoopVar7) + ((LoopVar5) << (WNDBIT - 9)) + WNDSIZ * 2)
-#define CRCPOLY 0xA001
-#define UPDATE_CRC(LoopVar5) mCrc = mCrcTable[(mCrc ^ (LoopVar5)) & 0xFF] ^ (mCrc >> UINT8_BIT)
+#undef UINT8_MAX
+typedef INT32 NODE;
+#define UINT8_MAX 0xff
+#define UINT8_BIT 8
+#define THRESHOLD 3
+#define INIT_CRC 0
+#define WNDBIT 19
+#define WNDSIZ (1U << WNDBIT)
+#define MAXMATCH 256
+#define BLKSIZ (1U << 14) // 16 * 1024U
+#define PERC_FLAG 0x80000000U
+#define CODE_BIT 16
+#define NIL 0
+#define MAX_HASH_VAL (3 * WNDSIZ + (WNDSIZ / 512 + 1) * UINT8_MAX)
+#define HASH(p, c) ((p) + ((c) << (WNDBIT - 9)) + WNDSIZ * 2)
+#define CRCPOLY 0xA001
+#define UPDATE_CRC(c) mCrc = mCrcTable[(mCrc ^ (c)) & 0xFF] ^ (mCrc >> UINT8_BIT)
//
// C: the Char&Len Set; P: the Position Set; T: the exTra Set
//
-#define NC (UINT8_MAX + MAXMATCH + 2 - THRESHOLD)
-#define CBIT 9
-#define NP (WNDBIT + 1)
-//#define PBIT 4
-#define NT (CODE_BIT + 3)
-#define TBIT 5
+#define NC (UINT8_MAX + MAXMATCH + 2 - THRESHOLD)
+#define CBIT 9
+#define NP (WNDBIT + 1)
+//#define PBIT 5
+#define NT (CODE_BIT + 3)
+#define TBIT 5
#if NT > NP
-#define NPT NT
+#define NPT NT
#else
-#define NPT NP
+#define NPT NP
#endif
//
// Function Prototypes
//
-/**
-Put a dword to output stream
+STATIC
+ VOID
+ PutDword(
+ UINT32 Data
+ );
-@param[in] Data The dword to put.
-**/
-VOID
-EFIAPI
-PutDword(
-IN UINT32 Data
+STATIC
+ INT32
+ AllocateMemory (
+ VOID
+ );
+
+STATIC
+ VOID
+ FreeMemory (
+ VOID
+ );
+
+STATIC
+ VOID
+ InitSlide (
+ VOID
+ );
+
+STATIC
+ NODE
+ Child (
+ NODE NodeQ,
+ UINT8 CharC
+ );
+
+STATIC
+ VOID
+ MakeChild (
+ NODE NodeQ,
+ UINT8 CharC,
+ NODE NodeR
+ );
+
+STATIC
+ VOID
+ Split (
+ NODE Old
+ );
+
+STATIC
+ VOID
+ InsertNode (
+ VOID
+ );
+
+STATIC
+ VOID
+ DeleteNode (
+ VOID
+ );
+
+STATIC
+ VOID
+ GetNextMatch (
+ VOID
+ );
+
+STATIC
+ INT32
+ Encode (
+ VOID
+ );
+
+STATIC
+ VOID
+ CountTFreq (
+ VOID
+ );
+
+STATIC
+ VOID
+ WritePTLen (
+ INT32 Number,
+ INT32 nbit,
+ INT32 Special
+ );
+
+STATIC
+ VOID
+ WriteCLen (
+ VOID
+ );
+
+STATIC
+ VOID
+ EncodeC (
+ INT32 Value
+ );
+
+STATIC
+ VOID
+ EncodeP (
+ UINT32 Value
+ );
+
+STATIC
+ VOID
+ SendBlock (
+ VOID
+ );
+
+STATIC
+ VOID
+ Output (
+ UINT32 c,
+ UINT32 p
+ );
+
+STATIC
+ VOID
+ HufEncodeStart (
+ VOID
+ );
+
+STATIC
+ VOID
+ HufEncodeEnd (
+ VOID
+ );
+
+STATIC
+ VOID
+ MakeCrcTable (
+ VOID
+ );
+
+STATIC
+ VOID
+ PutBits (
+ INT32 Number,
+ UINT32 Value
+ );
+
+STATIC
+ INT32
+ FreadCrc (
+ UINT8 *Pointer,
+ INT32 Number
+ );
+
+STATIC
+ VOID
+ InitPutBits (
+ VOID
+ );
+
+STATIC
+ VOID
+ CountLen (
+ INT32 Index
+ );
+
+STATIC
+ VOID
+ MakeLen (
+ INT32 Root
+ );
+
+STATIC
+ VOID
+ DownHeap (
+ INT32 Index
+ );
+
+STATIC
+ VOID
+ MakeCode (
+ INT32 Number,
+ UINT8 Len[ ],
+ UINT16 Code[]
+);
+
+STATIC
+ INT32
+ MakeTree (
+ INT32 NParm,
+ UINT16 FreqParm[],
+ UINT8 LenParm[ ],
+ UINT16 CodeParm[]
);
//
// Global Variables
//
-STATIC UINT8 *mSrc;
-STATIC UINT8 *mDst;
-STATIC UINT8 *mSrcUpperLimit;
-STATIC UINT8 *mDstUpperLimit;
+STATIC UINT8 *mSrc, *mDst, *mSrcUpperLimit, *mDstUpperLimit;
-STATIC UINT8 *mLevel;
-STATIC UINT8 *mText;
-STATIC UINT8 *mChildCount;
-STATIC UINT8 *mBuf;
-STATIC UINT8 mCLen[NC];
-STATIC UINT8 mPTLen[NPT];
-STATIC UINT8 *mLen;
+STATIC UINT8 *mLevel, *mText, *mChildCount, *mBuf, mCLen[NC], mPTLen[NPT], *mLen;
STATIC INT16 mHeap[NC + 1];
-STATIC INT32 mRemainder;
-STATIC INT32 mMatchLen;
-STATIC INT32 mBitCount;
-STATIC INT32 mHeapSize;
-STATIC INT32 mTempInt32;
-STATIC UINT32 mBufSiz = 0;
-STATIC UINT32 mOutputPos;
-STATIC UINT32 mOutputMask;
-STATIC UINT32 mSubBitBuf;
-STATIC UINT32 mCrc;
-STATIC UINT32 mCompSize;
-STATIC UINT32 mOrigSize;
+STATIC INT32 mRemainder, mMatchLen, mBitCount, mHeapSize, mN;
+STATIC UINT32 mBufSiz = 0, mOutputPos, mOutputMask, mSubBitBuf, mCrc;
+STATIC UINT32 mCompSize, mOrigSize;
-STATIC UINT16 *mFreq;
-STATIC UINT16 *mSortPtr;
-STATIC UINT16 mLenCnt[17];
-STATIC UINT16 mLeft[2 * NC - 1];
-STATIC UINT16 mRight[2 * NC - 1];
-STATIC UINT16 mCrcTable[UINT8_MAX + 1];
-STATIC UINT16 mCFreq[2 * NC - 1];
-STATIC UINT16 mCCode[NC];
-STATIC UINT16 mPFreq[2 * NP - 1];
-STATIC UINT16 mPTCode[NPT];
-STATIC UINT16 mTFreq[2 * NT - 1];
+STATIC UINT16 *mFreq, *mSortPtr, mLenCnt[17], mLeft[2 * NC - 1], mRight[2 * NC - 1], mCrcTable[UINT8_MAX + 1],
+ mCFreq[2 * NC - 1], mCCode[NC], mPFreq[2 * NP - 1], mPTCode[NPT], mTFreq[2 * NT - 1];
-STATIC NODE mPos;
-STATIC NODE mMatchPos;
-STATIC NODE mAvail;
-STATIC NODE *mPosition;
-STATIC NODE *mParent;
-STATIC NODE *mPrev;
-STATIC NODE *mNext = NULL;
-INT32 mHuffmanDepth = 0;
+STATIC UINT8 mPbit;
-STATIC UINT8 mPBit;
+STATIC NODE mPos, mMatchPos, mAvail, *mPosition, *mParent, *mPrev, *mNext = NULL;
-VOID* SetMem(VOID* dst, size_t size, UINT8 value) {
- return memset(dst, value, size);
-}
-
-VOID* CopyMem(VOID* dst, CONST VOID* src, size_t size) {
- return memcpy(dst, src, size);
-}
-
-VOID* AllocateZeroPool(size_t size) {
- VOID* pool;
- if (!size)
- return NULL;
-
- pool = malloc(size);
- memset(pool, 0x00, size);
- return pool;
-}
-
-VOID FreePool(VOID* pool) {
- if (pool != NULL)
- free(pool);
-}
-
-/**
-Make a CRC table.
-
-**/
-VOID
-EFIAPI
-MakeCrcTable(
-VOID
+//
+// functions
+//
+UINT8
+EfiCompress(
+CONST VOID *SrcBuffer,
+CONST UINT64 SrcSize,
+VOID *DstBuffer,
+UINT64 *DstSize
)
+/*++
+
+Routine Description:
+
+The internal implementation of [Efi/Tiano]Compress().
+
+Arguments:
+
+SrcBuffer - The buffer storing the source data
+SrcSize - The size of source data
+DstBuffer - The buffer to store the compressed data
+DstSize - On input, the size of DstBuffer; On output,
+the size of the actual compressed data.
+
+Returns:
+
+EFI_BUFFER_TOO_SMALL - The DstBuffer is too small. this case,
+DstSize contains the size needed.
+EFI_SUCCESS - Compression is successful.
+EFI_OUT_OF_RESOURCES - No resource to complete function.
+EFI_INVALID_PARAMETER - Parameter supplied is wrong.
+
+--*/
{
- UINT32 LoopVar1;
-
- UINT32 LoopVar2;
-
- UINT32 LoopVar4;
-
- for (LoopVar1 = 0; LoopVar1 <= UINT8_MAX; LoopVar1++) {
- LoopVar4 = LoopVar1;
- for (LoopVar2 = 0; LoopVar2 < UINT8_BIT; LoopVar2++) {
- if ((LoopVar4 & 1) != 0) {
- LoopVar4 = (LoopVar4 >> 1) ^ CRCPOLY;
- }
- else {
- LoopVar4 >>= 1;
- }
- }
-
- mCrcTable[LoopVar1] = (UINT16)LoopVar4;
- }
-}
-
-/**
-Put a dword to output stream
-
-@param[in] Data The dword to put.
-**/
-VOID
-EFIAPI
-PutDword(
-IN UINT32 Data
-)
-{
- if (mDst < mDstUpperLimit) {
- *mDst++ = (UINT8)(((UINT8)(Data)) & 0xff);
- }
-
- if (mDst < mDstUpperLimit) {
- *mDst++ = (UINT8)(((UINT8)(Data >> 0x08)) & 0xff);
- }
-
- if (mDst < mDstUpperLimit) {
- *mDst++ = (UINT8)(((UINT8)(Data >> 0x10)) & 0xff);
- }
-
- if (mDst < mDstUpperLimit) {
- *mDst++ = (UINT8)(((UINT8)(Data >> 0x18)) & 0xff);
- }
-}
-
-/**
-Allocate memory spaces for data structures used in compression process.
-
-@retval EFI_SUCCESS Memory was allocated successfully.
-@retval EFI_OUT_OF_RESOURCES A memory allocation failed.
-**/
-EFI_STATUS
-EFIAPI
-AllocateMemory(
-VOID
-)
-{
- mText = AllocateZeroPool(WNDSIZ * 2 + MAXMATCH);
- mLevel = AllocateZeroPool((WNDSIZ + UINT8_MAX + 1) * sizeof(*mLevel));
- mChildCount = AllocateZeroPool((WNDSIZ + UINT8_MAX + 1) * sizeof(*mChildCount));
- mPosition = AllocateZeroPool((WNDSIZ + UINT8_MAX + 1) * sizeof(*mPosition));
- mParent = AllocateZeroPool(WNDSIZ * 2 * sizeof(*mParent));
- mPrev = AllocateZeroPool(WNDSIZ * 2 * sizeof(*mPrev));
- mNext = AllocateZeroPool((MAX_HASH_VAL + 1) * sizeof(*mNext));
-
- mBufSiz = BLKSIZ;
- mBuf = AllocateZeroPool(mBufSiz);
- while (mBuf == NULL) {
- mBufSiz = (mBufSiz / 10U) * 9U;
- if (mBufSiz < 4 * 1024U) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- mBuf = AllocateZeroPool(mBufSiz);
- }
-
- mBuf[0] = 0;
-
- return EFI_SUCCESS;
-}
-
-/**
-Called when compression is completed to free memory previously allocated.
-
-**/
-VOID
-EFIAPI
-FreeMemory(
-VOID
-)
-{
- FreePool(mText);
- FreePool(mLevel);
- FreePool(mChildCount);
- FreePool(mPosition);
- FreePool(mParent);
- FreePool(mPrev);
- FreePool(mNext);
- FreePool(mBuf);
-}
-
-/**
-Initialize String Info Log data structures.
-**/
-VOID
-EFIAPI
-InitSlide(
-VOID
-)
-{
- NODE LoopVar1;
-
- SetMem(mLevel + WNDSIZ, (UINT8_MAX + 1) * sizeof(UINT8), 1);
- SetMem(mPosition + WNDSIZ, (UINT8_MAX + 1) * sizeof(NODE), 0);
-
- SetMem(mParent + WNDSIZ, WNDSIZ * sizeof(NODE), 0);
-
- mAvail = 1;
- for (LoopVar1 = 1; LoopVar1 < WNDSIZ - 1; LoopVar1++) {
- mNext[LoopVar1] = (NODE)(LoopVar1 + 1);
- }
-
- mNext[WNDSIZ - 1] = NIL;
- SetMem(mNext + WNDSIZ * 2, (MAX_HASH_VAL - WNDSIZ * 2 + 1) * sizeof(NODE), 0);
-}
-
-/**
-Find child node given the parent node and the edge character
-
-@param[in] LoopVar6 The parent node.
-@param[in] LoopVar5 The edge character.
-
-@return The child node.
-@retval NIL(Zero) No child could be found.
-
-**/
-NODE
-EFIAPI
-Child(
-IN NODE LoopVar6,
-IN UINT8 LoopVar5
-)
-{
- NODE LoopVar4;
-
- LoopVar4 = mNext[HASH(LoopVar6, LoopVar5)];
- mParent[NIL] = LoopVar6; /* sentinel */
- while (mParent[LoopVar4] != LoopVar6) {
- LoopVar4 = mNext[LoopVar4];
- }
-
- return LoopVar4;
-}
-
-/**
-Create a new child for a given parent node.
-
-@param[in] LoopVar6 The parent node.
-@param[in] LoopVar5 The edge character.
-@param[in] LoopVar4 The child node.
-**/
-VOID
-EFIAPI
-MakeChild(
-IN NODE LoopVar6,
-IN UINT8 LoopVar5,
-IN NODE LoopVar4
-)
-{
- NODE LoopVar12;
-
- NODE LoopVar10;
-
- LoopVar12 = (NODE)HASH(LoopVar6, LoopVar5);
- LoopVar10 = mNext[LoopVar12];
- mNext[LoopVar12] = LoopVar4;
- mNext[LoopVar4] = LoopVar10;
- mPrev[LoopVar10] = LoopVar4;
- mPrev[LoopVar4] = LoopVar12;
- mParent[LoopVar4] = LoopVar6;
- mChildCount[LoopVar6]++;
-}
-
-/**
-Split a node.
-
-@param[in] Old The node to split.
-**/
-VOID
-EFIAPI
-Split(
-IN NODE Old
-)
-{
- NODE New;
-
- NODE LoopVar10;
-
- New = mAvail;
- mAvail = mNext[New];
- mChildCount[New] = 0;
- LoopVar10 = mPrev[Old];
- mPrev[New] = LoopVar10;
- mNext[LoopVar10] = New;
- LoopVar10 = mNext[Old];
- mNext[New] = LoopVar10;
- mPrev[LoopVar10] = New;
- mParent[New] = mParent[Old];
- mLevel[New] = (UINT8)mMatchLen;
- mPosition[New] = mPos;
- MakeChild(New, mText[mMatchPos + mMatchLen], Old);
- MakeChild(New, mText[mPos + mMatchLen], mPos);
-}
-
-/**
-Insert string info for current position into the String Info Log.
-
-**/
-VOID
-EFIAPI
-InsertNode(
-VOID
-)
-{
- NODE LoopVar6;
-
- NODE LoopVar4;
-
- NODE LoopVar2;
-
- NODE LoopVar10;
- UINT8 LoopVar5;
- UINT8 *TempString3;
- UINT8 *TempString2;
-
- if (mMatchLen >= 4) {
- //
- // We have just got a long match, the target tree
- // can be located by MatchPos + 1. Travese the tree
- // from bottom up to get to a proper starting point.
- // The usage of PERC_FLAG ensures proper node deletion
- // in DeleteNode() later.
- //
- mMatchLen--;
- LoopVar4 = (NODE)((mMatchPos + 1) | WNDSIZ);
- LoopVar6 = mParent[LoopVar4];
- while (LoopVar6 == NIL) {
- LoopVar4 = mNext[LoopVar4];
- LoopVar6 = mParent[LoopVar4];
- }
-
- while (mLevel[LoopVar6] >= mMatchLen) {
- LoopVar4 = LoopVar6;
- LoopVar6 = mParent[LoopVar6];
- }
-
- LoopVar10 = LoopVar6;
- while (mPosition[LoopVar10] < 0) {
- mPosition[LoopVar10] = mPos;
- LoopVar10 = mParent[LoopVar10];
- }
-
- if (LoopVar10 < WNDSIZ) {
- mPosition[LoopVar10] = (NODE)(mPos | PERC_FLAG);
- }
- }
- else {
- //
- // Locate the target tree
- //
- LoopVar6 = (NODE)(mText[mPos] + WNDSIZ);
- LoopVar5 = mText[mPos + 1];
- LoopVar4 = Child(LoopVar6, LoopVar5);
- if (LoopVar4 == NIL) {
- MakeChild(LoopVar6, LoopVar5, mPos);
- mMatchLen = 1;
- return;
- }
-
- mMatchLen = 2;
- }
- //
- // Traverse down the tree to find a match.
- // Update Position value along the route.
- // Node split or creation is involved.
- //
- for (;;) {
- if (LoopVar4 >= WNDSIZ) {
- LoopVar2 = MAXMATCH;
- mMatchPos = LoopVar4;
- }
- else {
- LoopVar2 = mLevel[LoopVar4];
- mMatchPos = (NODE)(mPosition[LoopVar4] & ~PERC_FLAG);
- }
-
- if (mMatchPos >= mPos) {
- mMatchPos -= WNDSIZ;
- }
-
- TempString3 = &mText[mPos + mMatchLen];
- TempString2 = &mText[mMatchPos + mMatchLen];
- while (mMatchLen < LoopVar2) {
- if (*TempString3 != *TempString2) {
- Split(LoopVar4);
- return;
- }
-
- mMatchLen++;
- TempString3++;
- TempString2++;
- }
-
- if (mMatchLen >= MAXMATCH) {
- break;
- }
-
- mPosition[LoopVar4] = mPos;
- LoopVar6 = LoopVar4;
- LoopVar4 = Child(LoopVar6, *TempString3);
- if (LoopVar4 == NIL) {
- MakeChild(LoopVar6, *TempString3, mPos);
- return;
- }
-
- mMatchLen++;
- }
-
- LoopVar10 = mPrev[LoopVar4];
- mPrev[mPos] = LoopVar10;
- mNext[LoopVar10] = mPos;
- LoopVar10 = mNext[LoopVar4];
- mNext[mPos] = LoopVar10;
- mPrev[LoopVar10] = mPos;
- mParent[mPos] = LoopVar6;
- mParent[LoopVar4] = NIL;
-
- //
- // Special usage of 'next'
- //
- mNext[LoopVar4] = mPos;
-}
-
-/**
-Delete outdated string info. (The Usage of PERC_FLAG
-ensures a clean deletion).
-
-**/
-VOID
-EFIAPI
-DeleteNode(
-VOID
-)
-{
- NODE LoopVar6;
-
- NODE LoopVar4;
-
- NODE LoopVar11;
-
- NODE LoopVar10;
-
- NODE LoopVar9;
-
- if (mParent[mPos] == NIL) {
- return;
- }
-
- LoopVar4 = mPrev[mPos];
- LoopVar11 = mNext[mPos];
- mNext[LoopVar4] = LoopVar11;
- mPrev[LoopVar11] = LoopVar4;
- LoopVar4 = mParent[mPos];
- mParent[mPos] = NIL;
- if (LoopVar4 >= WNDSIZ) {
- return;
- }
-
- mChildCount[LoopVar4]--;
- if (mChildCount[LoopVar4] > 1) {
- return;
- }
-
- LoopVar10 = (NODE)(mPosition[LoopVar4] & ~PERC_FLAG);
- if (LoopVar10 >= mPos) {
- LoopVar10 -= WNDSIZ;
- }
-
- LoopVar11 = LoopVar10;
- LoopVar6 = mParent[LoopVar4];
- LoopVar9 = mPosition[LoopVar6];
- while ((LoopVar9 & PERC_FLAG) != 0){
- LoopVar9 &= ~PERC_FLAG;
- if (LoopVar9 >= mPos) {
- LoopVar9 -= WNDSIZ;
- }
-
- if (LoopVar9 > LoopVar11) {
- LoopVar11 = LoopVar9;
- }
-
- mPosition[LoopVar6] = (NODE)(LoopVar11 | WNDSIZ);
- LoopVar6 = mParent[LoopVar6];
- LoopVar9 = mPosition[LoopVar6];
- }
-
- if (LoopVar6 < WNDSIZ) {
- if (LoopVar9 >= mPos) {
- LoopVar9 -= WNDSIZ;
- }
-
- if (LoopVar9 > LoopVar11) {
- LoopVar11 = LoopVar9;
- }
-
- mPosition[LoopVar6] = (NODE)(LoopVar11 | WNDSIZ | PERC_FLAG);
- }
-
- LoopVar11 = Child(LoopVar4, mText[LoopVar10 + mLevel[LoopVar4]]);
- LoopVar10 = mPrev[LoopVar11];
- LoopVar9 = mNext[LoopVar11];
- mNext[LoopVar10] = LoopVar9;
- mPrev[LoopVar9] = LoopVar10;
- LoopVar10 = mPrev[LoopVar4];
- mNext[LoopVar10] = LoopVar11;
- mPrev[LoopVar11] = LoopVar10;
- LoopVar10 = mNext[LoopVar4];
- mPrev[LoopVar10] = LoopVar11;
- mNext[LoopVar11] = LoopVar10;
- mParent[LoopVar11] = mParent[LoopVar4];
- mParent[LoopVar4] = NIL;
- mNext[LoopVar4] = mAvail;
- mAvail = LoopVar4;
-}
-
-/**
-Read in source data
-
-@param[out] LoopVar7 The buffer to hold the data.
-@param[in] LoopVar8 The number of bytes to read.
-
-@return The number of bytes actually read.
-**/
-INT32
-EFIAPI
-FreadCrc(
-OUT UINT8 *LoopVar7,
-IN INT32 LoopVar8
-)
-{
- INT32 LoopVar1;
-
- for (LoopVar1 = 0; mSrc < mSrcUpperLimit && LoopVar1 < LoopVar8; LoopVar1++) {
- *LoopVar7++ = *mSrc++;
- }
-
- LoopVar8 = LoopVar1;
-
- LoopVar7 -= LoopVar8;
- mOrigSize += LoopVar8;
- LoopVar1--;
- while (LoopVar1 >= 0) {
- UPDATE_CRC(*LoopVar7++);
- LoopVar1--;
- }
-
- return LoopVar8;
-}
-
-/**
-Advance the current position (read in new data if needed).
-Delete outdated string info. Find a match string for current position.
-
-@retval TRUE The operation was successful.
-@retval FALSE The operation failed due to insufficient memory.
-**/
-BOOLEAN
-EFIAPI
-GetNextMatch(
-VOID
-)
-{
- INT32 LoopVar8;
- VOID *Temp;
-
- mRemainder--;
- mPos++;
- if (mPos == WNDSIZ * 2) {
- Temp = AllocateZeroPool(WNDSIZ + MAXMATCH);
- if (Temp == NULL) {
- return (FALSE);
- }
- CopyMem(Temp, &mText[WNDSIZ], WNDSIZ + MAXMATCH);
- CopyMem(&mText[0], Temp, WNDSIZ + MAXMATCH);
- FreePool(Temp);
- LoopVar8 = FreadCrc(&mText[WNDSIZ + MAXMATCH], WNDSIZ);
- mRemainder += LoopVar8;
- mPos = WNDSIZ;
- }
-
- DeleteNode();
- InsertNode();
-
- return (TRUE);
-}
-
-/**
-Send entry LoopVar1 down the queue.
-
-@param[in] LoopVar1 The index of the item to move.
-**/
-VOID
-EFIAPI
-DownHeap(
-IN INT32 i
-)
-{
- INT32 LoopVar1;
-
- INT32 LoopVar2;
-
- //
- // priority queue: send i-th entry down heap
- //
- LoopVar2 = mHeap[i];
- LoopVar1 = 2 * i;
- while (LoopVar1 <= mHeapSize) {
- if (LoopVar1 < mHeapSize && mFreq[mHeap[LoopVar1]] > mFreq[mHeap[LoopVar1 + 1]]) {
- LoopVar1++;
- }
-
- if (mFreq[LoopVar2] <= mFreq[mHeap[LoopVar1]]) {
- break;
- }
-
- mHeap[i] = mHeap[LoopVar1];
- i = LoopVar1;
- LoopVar1 = 2 * i;
- }
-
- mHeap[i] = (INT16)LoopVar2;
-}
-
-/**
-Count the number of each code length for a Huffman tree.
-
-@param[in] LoopVar1 The top node.
-**/
-VOID
-EFIAPI
-CountLen(
-IN INT32 LoopVar1
-)
-{
- if (LoopVar1 < mTempInt32) {
- mLenCnt[(mHuffmanDepth < 16) ? mHuffmanDepth : 16]++;
- }
- else {
- mHuffmanDepth++;
- CountLen(mLeft[LoopVar1]);
- CountLen(mRight[LoopVar1]);
- mHuffmanDepth--;
- }
-}
-
-/**
-Create code length array for a Huffman tree.
-
-@param[in] Root The root of the tree.
-**/
-VOID
-EFIAPI
-MakeLen(
-IN INT32 Root
-)
-{
- INT32 LoopVar1;
-
- INT32 LoopVar2;
- UINT32 Cum;
-
- for (LoopVar1 = 0; LoopVar1 <= 16; LoopVar1++) {
- mLenCnt[LoopVar1] = 0;
- }
-
- CountLen(Root);
-
- //
- // Adjust the length count array so that
- // no code will be generated longer than its designated length
- //
- Cum = 0;
- for (LoopVar1 = 16; LoopVar1 > 0; LoopVar1--) {
- Cum += mLenCnt[LoopVar1] << (16 - LoopVar1);
- }
-
- while (Cum != (1U << 16)) {
- mLenCnt[16]--;
- for (LoopVar1 = 15; LoopVar1 > 0; LoopVar1--) {
- if (mLenCnt[LoopVar1] != 0) {
- mLenCnt[LoopVar1]--;
- mLenCnt[LoopVar1 + 1] += 2;
- break;
- }
- }
-
- Cum--;
- }
-
- for (LoopVar1 = 16; LoopVar1 > 0; LoopVar1--) {
- LoopVar2 = mLenCnt[LoopVar1];
- LoopVar2--;
- while (LoopVar2 >= 0) {
- mLen[*mSortPtr++] = (UINT8)LoopVar1;
- LoopVar2--;
- }
- }
-}
-
-/**
-Assign code to each symbol based on the code length array.
-
-@param[in] LoopVar8 The number of symbols.
-@param[in] Len The code length array.
-@param[out] Code The stores codes for each symbol.
-**/
-VOID
-EFIAPI
-MakeCode(
-IN INT32 LoopVar8,
-IN UINT8 Len[],
-OUT UINT16 Code[]
-)
-{
- INT32 LoopVar1;
- UINT16 Start[18];
-
- Start[1] = 0;
- for (LoopVar1 = 1; LoopVar1 <= 16; LoopVar1++) {
- Start[LoopVar1 + 1] = (UINT16)((Start[LoopVar1] + mLenCnt[LoopVar1]) << 1);
- }
-
- for (LoopVar1 = 0; LoopVar1 < LoopVar8; LoopVar1++) {
- Code[LoopVar1] = Start[Len[LoopVar1]]++;
- }
-}
-
-/**
-Generates Huffman codes given a frequency distribution of symbols.
-
-@param[in] NParm The number of symbols.
-@param[in] FreqParm The frequency of each symbol.
-@param[out] LenParm The code length for each symbol.
-@param[out] CodeParm The code for each symbol.
-
-@return The root of the Huffman tree.
-**/
-INT32
-EFIAPI
-MakeTree(
-IN INT32 NParm,
-IN UINT16 FreqParm[],
-OUT UINT8 LenParm[],
-OUT UINT16 CodeParm[]
-)
-{
- INT32 LoopVar1;
-
- INT32 LoopVar2;
-
- INT32 LoopVar3;
-
- INT32 Avail;
-
- //
- // make tree, calculate len[], return root
- //
- mTempInt32 = NParm;
- mFreq = FreqParm;
- mLen = LenParm;
- Avail = mTempInt32;
- mHeapSize = 0;
- mHeap[1] = 0;
- for (LoopVar1 = 0; LoopVar1 < mTempInt32; LoopVar1++) {
- mLen[LoopVar1] = 0;
- if ((mFreq[LoopVar1]) != 0) {
- mHeapSize++;
- mHeap[mHeapSize] = (INT16)LoopVar1;
- }
- }
-
- if (mHeapSize < 2) {
- CodeParm[mHeap[1]] = 0;
- return mHeap[1];
- }
-
- for (LoopVar1 = mHeapSize / 2; LoopVar1 >= 1; LoopVar1--) {
- //
- // make priority queue
- //
- DownHeap(LoopVar1);
- }
-
- mSortPtr = CodeParm;
- do {
- LoopVar1 = mHeap[1];
- if (LoopVar1 < mTempInt32) {
- *mSortPtr++ = (UINT16)LoopVar1;
- }
-
- mHeap[1] = mHeap[mHeapSize--];
- DownHeap(1);
- LoopVar2 = mHeap[1];
- if (LoopVar2 < mTempInt32) {
- *mSortPtr++ = (UINT16)LoopVar2;
- }
-
- LoopVar3 = Avail++;
- mFreq[LoopVar3] = (UINT16)(mFreq[LoopVar1] + mFreq[LoopVar2]);
- mHeap[1] = (INT16)LoopVar3;
- DownHeap(1);
- mLeft[LoopVar3] = (UINT16)LoopVar1;
- mRight[LoopVar3] = (UINT16)LoopVar2;
- } while (mHeapSize > 1);
-
- mSortPtr = CodeParm;
- MakeLen(LoopVar3);
- MakeCode(NParm, LenParm, CodeParm);
-
- //
- // return root
- //
- return LoopVar3;
-}
-
-/**
-Outputs rightmost LoopVar8 bits of x
-
-@param[in] LoopVar8 The rightmost LoopVar8 bits of the data is used.
-@param[in] x The data.
-**/
-VOID
-EFIAPI
-PutBits(
-IN INT32 LoopVar8,
-IN UINT32 x
-)
-{
- UINT8 Temp;
-
- if (LoopVar8 < mBitCount) {
- mSubBitBuf |= x << (mBitCount -= LoopVar8);
- }
- else {
- Temp = (UINT8)(mSubBitBuf | (x >> (LoopVar8 -= mBitCount)));
- if (mDst < mDstUpperLimit) {
- *mDst++ = Temp;
- }
- mCompSize++;
-
- if (LoopVar8 < UINT8_BIT) {
- mSubBitBuf = x << (mBitCount = UINT8_BIT - LoopVar8);
- }
- else {
- Temp = (UINT8)(x >> (LoopVar8 - UINT8_BIT));
- if (mDst < mDstUpperLimit) {
- *mDst++ = Temp;
- }
- mCompSize++;
-
- mSubBitBuf = x << (mBitCount = 2 * UINT8_BIT - LoopVar8);
- }
- }
-}
-
-/**
-Encode a signed 32 bit number.
-
-@param[in] LoopVar5 The number to encode.
-**/
-VOID
-EFIAPI
-EncodeC(
-IN INT32 LoopVar5
-)
-{
- PutBits(mCLen[LoopVar5], mCCode[LoopVar5]);
-}
-
-/**
-Encode a unsigned 32 bit number.
-
-@param[in] LoopVar7 The number to encode.
-**/
-VOID
-EFIAPI
-EncodeP(
-IN UINT32 LoopVar7
-)
-{
- UINT32 LoopVar5;
-
- UINT32 LoopVar6;
-
- LoopVar5 = 0;
- LoopVar6 = LoopVar7;
- while (LoopVar6 != 0) {
- LoopVar6 >>= 1;
- LoopVar5++;
- }
-
- PutBits(mPTLen[LoopVar5], mPTCode[LoopVar5]);
- if (LoopVar5 > 1) {
- PutBits(LoopVar5 - 1, LoopVar7 & (0xFFFFU >> (17 - LoopVar5)));
- }
-}
-
-/**
-Count the frequencies for the Extra Set.
-
-**/
-VOID
-EFIAPI
-CountTFreq(
-VOID
-)
-{
- INT32 LoopVar1;
-
- INT32 LoopVar3;
-
- INT32 LoopVar8;
-
- INT32 Count;
-
- for (LoopVar1 = 0; LoopVar1 < NT; LoopVar1++) {
- mTFreq[LoopVar1] = 0;
- }
-
- LoopVar8 = NC;
- while (LoopVar8 > 0 && mCLen[LoopVar8 - 1] == 0) {
- LoopVar8--;
- }
-
- LoopVar1 = 0;
- while (LoopVar1 < LoopVar8) {
- LoopVar3 = mCLen[LoopVar1++];
- if (LoopVar3 == 0) {
- Count = 1;
- while (LoopVar1 < LoopVar8 && mCLen[LoopVar1] == 0) {
- LoopVar1++;
- Count++;
- }
-
- if (Count <= 2) {
- mTFreq[0] = (UINT16)(mTFreq[0] + Count);
- }
- else if (Count <= 18) {
- mTFreq[1]++;
- }
- else if (Count == 19) {
- mTFreq[0]++;
- mTFreq[1]++;
- }
- else {
- mTFreq[2]++;
- }
- }
- else {
- ASSERT((LoopVar3 + 2) < (2 * NT - 1));
- mTFreq[LoopVar3 + 2]++;
- }
- }
-}
-
-/**
-Outputs the code length array for the Extra Set or the Position Set.
-
-@param[in] LoopVar8 The number of symbols.
-@param[in] nbit The number of bits needed to represent 'LoopVar8'.
-@param[in] Special The special symbol that needs to be take care of.
-
-**/
-VOID
-EFIAPI
-WritePTLen(
-IN INT32 LoopVar8,
-IN INT32 nbit,
-IN INT32 Special
-)
-{
- INT32 LoopVar1;
-
- INT32 LoopVar3;
-
- while (LoopVar8 > 0 && mPTLen[LoopVar8 - 1] == 0) {
- LoopVar8--;
- }
-
- PutBits(nbit, LoopVar8);
- LoopVar1 = 0;
- while (LoopVar1 < LoopVar8) {
- LoopVar3 = mPTLen[LoopVar1++];
- if (LoopVar3 <= 6) {
- PutBits(3, LoopVar3);
- }
- else {
- PutBits(LoopVar3 - 3, (1U << (LoopVar3 - 3)) - 2);
- }
-
- if (LoopVar1 == Special) {
- while (LoopVar1 < 6 && mPTLen[LoopVar1] == 0) {
- LoopVar1++;
- }
-
- PutBits(2, (LoopVar1 - 3) & 3);
- }
- }
-}
-
-/**
-Outputs the code length array for Char&Length Set.
-**/
-VOID
-EFIAPI
-WriteCLen(
-VOID
-)
-{
- INT32 LoopVar1;
-
- INT32 LoopVar3;
-
- INT32 LoopVar8;
-
- INT32 Count;
-
- LoopVar8 = NC;
- while (LoopVar8 > 0 && mCLen[LoopVar8 - 1] == 0) {
- LoopVar8--;
- }
-
- PutBits(CBIT, LoopVar8);
- LoopVar1 = 0;
- while (LoopVar1 < LoopVar8) {
- LoopVar3 = mCLen[LoopVar1++];
- if (LoopVar3 == 0) {
- Count = 1;
- while (LoopVar1 < LoopVar8 && mCLen[LoopVar1] == 0) {
- LoopVar1++;
- Count++;
- }
-
- if (Count <= 2) {
- for (LoopVar3 = 0; LoopVar3 < Count; LoopVar3++) {
- PutBits(mPTLen[0], mPTCode[0]);
- }
- }
- else if (Count <= 18) {
- PutBits(mPTLen[1], mPTCode[1]);
- PutBits(4, Count - 3);
- }
- else if (Count == 19) {
- PutBits(mPTLen[0], mPTCode[0]);
- PutBits(mPTLen[1], mPTCode[1]);
- PutBits(4, 15);
- }
- else {
- PutBits(mPTLen[2], mPTCode[2]);
- PutBits(CBIT, Count - 20);
- }
- }
- else {
- ASSERT((LoopVar3 + 2) < NPT);
- PutBits(mPTLen[LoopVar3 + 2], mPTCode[LoopVar3 + 2]);
- }
- }
-}
-
-/**
-Huffman code the block and output it.
-
-**/
-VOID
-EFIAPI
-SendBlock(
-VOID
-)
-{
- UINT32 LoopVar1;
-
- UINT32 LoopVar3;
-
- UINT32 Flags;
-
- UINT32 Root;
-
- UINT32 Pos;
-
- UINT32 Size;
- Flags = 0;
-
- Root = MakeTree(NC, mCFreq, mCLen, mCCode);
- Size = mCFreq[Root];
- PutBits(16, Size);
- if (Root >= NC) {
- CountTFreq();
- Root = MakeTree(NT, mTFreq, mPTLen, mPTCode);
- if (Root >= NT) {
- WritePTLen(NT, TBIT, 3);
- }
- else {
- PutBits(TBIT, 0);
- PutBits(TBIT, Root);
- }
-
- WriteCLen();
- }
- else {
- PutBits(TBIT, 0);
- PutBits(TBIT, 0);
- PutBits(CBIT, 0);
- PutBits(CBIT, Root);
- }
-
- Root = MakeTree(NP, mPFreq, mPTLen, mPTCode);
- if (Root >= NP) {
- WritePTLen(NP, mPBit, -1);
- }
- else {
- PutBits(mPBit, 0);
- PutBits(mPBit, Root);
- }
-
- Pos = 0;
- for (LoopVar1 = 0; LoopVar1 < Size; LoopVar1++) {
- if (LoopVar1 % UINT8_BIT == 0) {
- Flags = mBuf[Pos++];
- }
- else {
- Flags <<= 1;
- }
- if ((Flags & (1U << (UINT8_BIT - 1))) != 0){
- EncodeC(mBuf[Pos++] + (1U << UINT8_BIT));
- LoopVar3 = mBuf[Pos++] << UINT8_BIT;
- LoopVar3 += mBuf[Pos++];
-
- EncodeP(LoopVar3);
- }
- else {
- EncodeC(mBuf[Pos++]);
- }
- }
-
- SetMem(mCFreq, NC * sizeof(UINT16), 0);
- SetMem(mPFreq, NP * sizeof(UINT16), 0);
-}
-
-/**
-Start the huffman encoding.
-
-**/
-VOID
-EFIAPI
-HufEncodeStart(
-VOID
-)
-{
- SetMem(mCFreq, NC * sizeof(UINT16), 0);
- SetMem(mPFreq, NP * sizeof(UINT16), 0);
-
- mOutputPos = mOutputMask = 0;
-
- mBitCount = UINT8_BIT;
- mSubBitBuf = 0;
-}
-
-/**
-Outputs an Original Character or a Pointer.
-
-@param[in] LoopVar5 The original character or the 'String Length' element of
-a Pointer.
-@param[in] LoopVar7 The 'Position' field of a Pointer.
-**/
-VOID
-EFIAPI
-CompressOutput(
-IN UINT32 LoopVar5,
-IN UINT32 LoopVar7
-)
-{
- STATIC UINT32 CPos;
-
- if ((mOutputMask >>= 1) == 0) {
- mOutputMask = 1U << (UINT8_BIT - 1);
- if (mOutputPos >= mBufSiz - 3 * UINT8_BIT) {
- SendBlock();
- mOutputPos = 0;
- }
-
- CPos = mOutputPos++;
- mBuf[CPos] = 0;
- }
- mBuf[mOutputPos++] = (UINT8)LoopVar5;
- mCFreq[LoopVar5]++;
- if (LoopVar5 >= (1U << UINT8_BIT)) {
- mBuf[CPos] = (UINT8)(mBuf[CPos] | mOutputMask);
- mBuf[mOutputPos++] = (UINT8)(LoopVar7 >> UINT8_BIT);
- mBuf[mOutputPos++] = (UINT8)LoopVar7;
- LoopVar5 = 0;
- while (LoopVar7 != 0) {
- LoopVar7 >>= 1;
- LoopVar5++;
- }
- mPFreq[LoopVar5]++;
- }
-}
-
-/**
-End the huffman encoding.
-
-**/
-VOID
-EFIAPI
-HufEncodeEnd(
-VOID
-)
-{
- SendBlock();
-
- //
- // Flush remaining bits
- //
- PutBits(UINT8_BIT - 1, 0);
-}
-
-/**
-The main controlling routine for compression process.
-
-@retval EFI_SUCCESS The compression is successful.
-@retval EFI_OUT_0F_RESOURCES Not enough memory for compression process.
-**/
-EFI_STATUS
-EFIAPI
-Encode(
-VOID
-)
-{
- EFI_STATUS Status;
- INT32 LastMatchLen;
- NODE LastMatchPos;
-
- Status = AllocateMemory();
- if (EFI_ERROR(Status)) {
- FreeMemory();
- return Status;
- }
-
- InitSlide();
-
- HufEncodeStart();
-
- mRemainder = FreadCrc(&mText[WNDSIZ], WNDSIZ + MAXMATCH);
-
- mMatchLen = 0;
- mPos = WNDSIZ;
- InsertNode();
- if (mMatchLen > mRemainder) {
- mMatchLen = mRemainder;
- }
-
- while (mRemainder > 0) {
- LastMatchLen = mMatchLen;
- LastMatchPos = mMatchPos;
- if (!GetNextMatch()) {
- Status = EFI_OUT_OF_RESOURCES;
- }
- if (mMatchLen > mRemainder) {
- mMatchLen = mRemainder;
- }
-
- if (mMatchLen > LastMatchLen || LastMatchLen < THRESHOLD) {
- //
- // Not enough benefits are gained by outputting a pointer,
- // so just output the original character
- //
- CompressOutput(mText[mPos - 1], 0);
- }
- else {
- //
- // Outputting a pointer is beneficial enough, do it.
- //
-
- CompressOutput(LastMatchLen + (UINT8_MAX + 1 - THRESHOLD),
- (mPos - LastMatchPos - 2) & (WNDSIZ - 1));
- LastMatchLen--;
- while (LastMatchLen > 0) {
- if (!GetNextMatch()) {
- Status = EFI_OUT_OF_RESOURCES;
- }
- LastMatchLen--;
- }
-
- if (mMatchLen > mRemainder) {
- mMatchLen = mRemainder;
- }
- }
- }
-
- HufEncodeEnd();
- FreeMemory();
- return (Status);
-}
-
-/**
-The compression routine.
-
-@param[in] SrcBuffer The buffer containing the source data.
-@param[in] SrcSize The number of bytes in SrcBuffer.
-@param[in] DstBuffer The buffer to put the compressed image in.
-@param[in, out] DstSize On input the size (in bytes) of DstBuffer, on
-return the number of bytes placed in DstBuffer.
-
-@retval EFI_SUCCESS The compression was successful.
-@retval EFI_BUFFER_TOO_SMALL The buffer was too small. DstSize is required.
-**/
-EFI_STATUS
-EFIAPI
-Compress(
-IN VOID *SrcBuffer,
-IN UINT64 SrcSize,
-IN VOID *DstBuffer,
-IN OUT UINT64 *DstSize
-)
-{
- EFI_STATUS Status;
+ INT32 Status;
//
// Initializations
//
+ mPbit = 4;
+
mBufSiz = 0;
mBuf = NULL;
mText = NULL;
@@ -1410,7 +321,7 @@ IN OUT UINT64 *DstSize
mPrev = NULL;
mNext = NULL;
- mSrc = SrcBuffer;
+ mSrc = (UINT8*) SrcBuffer;
mSrcUpperLimit = mSrc + SrcSize;
mDst = DstBuffer;
mDstUpperLimit = mDst + *DstSize;
@@ -1427,7 +338,7 @@ IN OUT UINT64 *DstSize
// Compress it
//
Status = Encode();
- if (EFI_ERROR(Status)) {
+ if (Status) {
return EFI_OUT_OF_RESOURCES;
}
//
@@ -1437,7 +348,7 @@ IN OUT UINT64 *DstSize
*mDst++ = 0;
}
//
- // Fill in compressed size and original size
+ // Fill compressed size and original size
//
mDst = DstBuffer;
PutDword(mCompSize + 1);
@@ -1454,20 +365,1489 @@ IN OUT UINT64 *DstSize
*DstSize = mCompSize + 1 + 8;
return EFI_SUCCESS;
}
+
}
-UINT8 EfiCompress(CONST VOID* SrcBuffer, CONST UINT64 SrcSize, VOID* DstBuffer, UINT64* DstSize)
+UINT8
+TianoCompress (
+CONST VOID *SrcBuffer,
+CONST UINT64 SrcSize,
+VOID *DstBuffer,
+UINT64 *DstSize
+)
+ /*++
+
+ Routine Description:
+
+ The internal implementation of [Efi/Tiano]Compress().
+
+ Arguments:
+
+ SrcBuffer - The buffer storing the source data
+ SrcSize - The size of source data
+ DstBuffer - The buffer to store the compressed data
+ DstSize - On input, the size of DstBuffer; On output,
+ the size of the actual compressed data.
+ Version - The version of de/compression algorithm.
+ Version 1 for UEFI 2.0 de/compression algorithm.
+ Version 2 for Tiano de/compression algorithm.
+
+ Returns:
+
+ EFI_BUFFER_TOO_SMALL - The DstBuffer is too small. this case,
+ DstSize contains the size needed.
+ EFI_SUCCESS - Compression is successful.
+ EFI_OUT_OF_RESOURCES - No resource to complete function.
+ EFI_INVALID_PARAMETER - Parameter supplied is wrong.
+
+ --*/
{
- VOID* buffer = (VOID*)SrcBuffer;
- UINT64 size = SrcSize;
- mPBit = 4;
- return Compress(buffer, size, DstBuffer, DstSize);
+ INT32 Status;
+
+ //
+ // Initializations
+ //
+ mPbit = 5;
+
+ mBufSiz = 0;
+ mBuf = NULL;
+ mText = NULL;
+ mLevel = NULL;
+ mChildCount = NULL;
+ mPosition = NULL;
+ mParent = NULL;
+ mPrev = NULL;
+ mNext = NULL;
+
+ mSrc = (UINT8*) SrcBuffer;
+ mSrcUpperLimit = mSrc + SrcSize;
+ mDst = DstBuffer;
+ mDstUpperLimit = mDst +*DstSize;
+
+ PutDword (0L);
+ PutDword (0L);
+
+ MakeCrcTable ();
+
+ mOrigSize = mCompSize = 0;
+ mCrc = INIT_CRC;
+
+ //
+ // Compress it
+ //
+ Status = Encode ();
+ if (Status) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ //
+ // Null terminate the compressed data
+ //
+ if (mDst < mDstUpperLimit) {
+ *mDst++ = 0;
+ }
+ //
+ // Fill compressed size and original size
+ //
+ mDst = DstBuffer;
+ PutDword (mCompSize + 1);
+ PutDword (mOrigSize);
+
+ //
+ // Return
+ //
+ if (mCompSize + 1 + 8 > *DstSize) {
+ *DstSize = mCompSize + 1 + 8;
+ return EFI_BUFFER_TOO_SMALL;
+ } else {
+ *DstSize = mCompSize + 1 + 8;
+ return EFI_SUCCESS;
+ }
+
}
-UINT8 TianoCompress(CONST VOID* SrcBuffer, CONST UINT64 SrcSize, VOID* DstBuffer, UINT64* DstSize)
+STATIC
+ VOID
+ PutDword (
+ UINT32 Data
+ )
+ /*++
+
+ Routine Description:
+
+ Put a DWORD to output stream
+
+ Arguments:
+
+ Data - the DWORD to put
+
+ Returns: (VOID)
+
+ --*/
{
- VOID* buffer = (VOID*)SrcBuffer;
- UINT64 size = SrcSize;
- mPBit = 5;
- return Compress(buffer, size, DstBuffer, DstSize);
-}
\ No newline at end of file
+ if (mDst < mDstUpperLimit) {
+ *mDst++ = (UINT8) (((UINT8) (Data)) & 0xff);
+ }
+
+ if (mDst < mDstUpperLimit) {
+ *mDst++ = (UINT8) (((UINT8) (Data >> 0x08)) & 0xff);
+ }
+
+ if (mDst < mDstUpperLimit) {
+ *mDst++ = (UINT8) (((UINT8) (Data >> 0x10)) & 0xff);
+ }
+
+ if (mDst < mDstUpperLimit) {
+ *mDst++ = (UINT8) (((UINT8) (Data >> 0x18)) & 0xff);
+ }
+}
+
+STATIC
+ INT32
+ AllocateMemory (
+ VOID
+ )
+ /*++
+
+ Routine Description:
+
+ Allocate memory spaces for data structures used compression process
+
+ Arguments:
+ VOID
+
+ Returns:
+
+ EFI_SUCCESS - Memory is allocated successfully
+ EFI_OUT_OF_RESOURCES - Allocation fails
+
+ --*/
+{
+ UINT32 Index;
+
+ mText = malloc (WNDSIZ * 2 + MAXMATCH);
+ for (Index = 0; Index < WNDSIZ * 2 + MAXMATCH; Index++) {
+ mText[Index] = 0;
+ }
+
+ mLevel = malloc ((WNDSIZ + UINT8_MAX + 1) * sizeof (*mLevel));
+ mChildCount = malloc ((WNDSIZ + UINT8_MAX + 1) * sizeof (*mChildCount));
+ mPosition = malloc ((WNDSIZ + UINT8_MAX + 1) * sizeof (*mPosition));
+ mParent = malloc (WNDSIZ * 2 * sizeof (*mParent));
+ mPrev = malloc (WNDSIZ * 2 * sizeof (*mPrev));
+ mNext = malloc ((MAX_HASH_VAL + 1) * sizeof (*mNext));
+
+ mBufSiz = BLKSIZ;
+ mBuf = malloc (mBufSiz);
+ while (mBuf == NULL) {
+ mBufSiz = (mBufSiz / 10U) * 9U;
+ if (mBufSiz < 4 * 1024U) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ mBuf = malloc (mBufSiz);
+ }
+
+ mBuf[0] = 0;
+
+ return EFI_SUCCESS;
+}
+
+VOID
+ FreeMemory (
+ VOID
+ )
+ /*++
+
+ Routine Description:
+
+ Called when compression is completed to free memory previously allocated.
+
+ Arguments: (VOID)
+
+ Returns: (VOID)
+
+ --*/
+{
+ if (mText != NULL) {
+ free (mText);
+ }
+
+ if (mLevel != NULL) {
+ free (mLevel);
+ }
+
+ if (mChildCount != NULL) {
+ free (mChildCount);
+ }
+
+ if (mPosition != NULL) {
+ free (mPosition);
+ }
+
+ if (mParent != NULL) {
+ free (mParent);
+ }
+
+ if (mPrev != NULL) {
+ free (mPrev);
+ }
+
+ if (mNext != NULL) {
+ free (mNext);
+ }
+
+ if (mBuf != NULL) {
+ free (mBuf);
+ }
+
+ return ;
+}
+
+STATIC
+ VOID
+ InitSlide (
+ VOID
+ )
+ /*++
+
+ Routine Description:
+
+ Initialize String Info Log data structures
+
+ Arguments: (VOID)
+
+ Returns: (VOID)
+
+ --*/
+{
+ NODE Index;
+
+ for (Index = (NODE) WNDSIZ; Index <= (NODE) WNDSIZ + UINT8_MAX; Index++) {
+ mLevel[Index] = 1;
+ mPosition[Index] = NIL; // sentinel
+ }
+
+ for (Index = (NODE) WNDSIZ; Index < (NODE) WNDSIZ * 2; Index++) {
+ mParent[Index] = NIL;
+ }
+
+ mAvail = 1;
+ for (Index = 1; Index < (NODE) WNDSIZ - 1; Index++) {
+ mNext[Index] = (NODE) (Index + 1);
+ }
+
+ mNext[WNDSIZ - 1] = NIL;
+ for (Index = (NODE) WNDSIZ * 2; Index <= (NODE) MAX_HASH_VAL; Index++) {
+ mNext[Index] = NIL;
+ }
+}
+
+STATIC
+ NODE
+ Child (
+ NODE NodeQ,
+ UINT8 CharC
+ )
+ /*++
+
+ Routine Description:
+
+ Find child node given the parent node and the edge character
+
+ Arguments:
+
+ NodeQ - the parent node
+ CharC - the edge character
+
+ Returns:
+
+ The child node (NIL if not found)
+
+ --*/
+{
+ NODE NodeR;
+
+ NodeR = mNext[HASH (NodeQ, CharC)];
+ //
+ // sentinel
+ //
+ mParent[NIL] = NodeQ;
+ while (mParent[NodeR] != NodeQ) {
+ NodeR = mNext[NodeR];
+ }
+
+ return NodeR;
+}
+
+STATIC
+ VOID
+ MakeChild (
+ NODE Parent,
+ UINT8 CharC,
+ NODE Child
+ )
+ /*++
+
+ Routine Description:
+
+ Create a new child for a given parent node.
+
+ Arguments:
+
+ Parent - the parent node
+ CharC - the edge character
+ Child - the child node
+
+ Returns: (VOID)
+
+ --*/
+{
+ NODE Node1;
+ NODE Node2;
+
+ Node1 = (NODE) HASH (Parent, CharC);
+ Node2 = mNext[Node1];
+ mNext[Node1] = Child;
+ mNext[Child] = Node2;
+ mPrev[Node2] = Child;
+ mPrev[Child] = Node1;
+ mParent[Child] = Parent;
+ mChildCount[Parent]++;
+}
+
+STATIC
+ VOID
+ Split (
+ NODE Old
+ )
+ /*++
+
+ Routine Description:
+
+ Split a node.
+
+ Arguments:
+
+ Old - the node to split
+
+ Returns: (VOID)
+
+ --*/
+{
+ NODE New;
+ NODE TempNode;
+
+ New = mAvail;
+ mAvail = mNext[New];
+ mChildCount[New] = 0;
+ TempNode = mPrev[Old];
+ mPrev[New] = TempNode;
+ mNext[TempNode] = New;
+ TempNode = mNext[Old];
+ mNext[New] = TempNode;
+ mPrev[TempNode] = New;
+ mParent[New] = mParent[Old];
+ mLevel[New] = (UINT8) mMatchLen;
+ mPosition[New] = mPos;
+ MakeChild (New, mText[mMatchPos + mMatchLen], Old);
+ MakeChild (New, mText[mPos + mMatchLen], mPos);
+}
+
+STATIC
+ VOID
+ InsertNode (
+ VOID
+ )
+ /*++
+
+ Routine Description:
+
+ Insert string info for current position into the String Info Log
+
+ Arguments: (VOID)
+
+ Returns: (VOID)
+
+ --*/
+{
+ NODE NodeQ;
+ NODE NodeR;
+ NODE Index2;
+ NODE NodeT;
+ UINT8 CharC;
+ UINT8 *t1;
+ UINT8 *t2;
+
+ if (mMatchLen >= 4) {
+ //
+ // We have just got a long match, the target tree
+ // can be located by MatchPos + 1. Traverse the tree
+ // from bottom up to get to a proper starting point.
+ // The usage of PERC_FLAG ensures proper node deletion
+ // DeleteNode() later.
+ //
+ mMatchLen--;
+ NodeR = (NODE) ((mMatchPos + 1) | WNDSIZ);
+ NodeQ = mParent[NodeR];
+ while (NodeQ == NIL) {
+ NodeR = mNext[NodeR];
+ NodeQ = mParent[NodeR];
+ }
+
+ while (mLevel[NodeQ] >= mMatchLen) {
+ NodeR = NodeQ;
+ NodeQ = mParent[NodeQ];
+ }
+
+ NodeT = NodeQ;
+ while (mPosition[NodeT] < 0) {
+ mPosition[NodeT] = mPos;
+ NodeT = mParent[NodeT];
+ }
+
+ if (NodeT < (NODE) WNDSIZ) {
+ mPosition[NodeT] = (NODE) (mPos | (UINT32) PERC_FLAG);
+ }
+ } else {
+ //
+ // Locate the target tree
+ //
+ NodeQ = (NODE) (mText[mPos] + WNDSIZ);
+ CharC = mText[mPos + 1];
+ NodeR = Child (NodeQ, CharC);
+ if (NodeR == NIL) {
+ MakeChild (NodeQ, CharC, mPos);
+ mMatchLen = 1;
+ return ;
+ }
+
+ mMatchLen = 2;
+ }
+ //
+ // Traverse down the tree to find a match.
+ // Update Position value along the route.
+ // Node split or creation is involved.
+ //
+ for (;;) {
+ if (NodeR >= (NODE) WNDSIZ) {
+ Index2 = MAXMATCH;
+ mMatchPos = NodeR;
+ } else {
+ Index2 = mLevel[NodeR];
+ mMatchPos = (NODE) (mPosition[NodeR] & (UINT32)~PERC_FLAG);
+ }
+
+ if (mMatchPos >= mPos) {
+ mMatchPos -= WNDSIZ;
+ }
+
+ t1 = &mText[mPos + mMatchLen];
+ t2 = &mText[mMatchPos + mMatchLen];
+ while (mMatchLen < Index2) {
+ if (*t1 != *t2) {
+ Split (NodeR);
+ return ;
+ }
+
+ mMatchLen++;
+ t1++;
+ t2++;
+ }
+
+ if (mMatchLen >= MAXMATCH) {
+ break;
+ }
+
+ mPosition[NodeR] = mPos;
+ NodeQ = NodeR;
+ NodeR = Child (NodeQ, *t1);
+ if (NodeR == NIL) {
+ MakeChild (NodeQ, *t1, mPos);
+ return ;
+ }
+
+ mMatchLen++;
+ }
+
+ NodeT = mPrev[NodeR];
+ mPrev[mPos] = NodeT;
+ mNext[NodeT] = mPos;
+ NodeT = mNext[NodeR];
+ mNext[mPos] = NodeT;
+ mPrev[NodeT] = mPos;
+ mParent[mPos] = NodeQ;
+ mParent[NodeR] = NIL;
+
+ //
+ // Special usage of 'next'
+ //
+ mNext[NodeR] = mPos;
+
+}
+
+STATIC
+ VOID
+ DeleteNode (
+ VOID
+ )
+ /*++
+
+ Routine Description:
+
+ Delete outdated string info. (The Usage of PERC_FLAG
+ ensures a clean deletion)
+
+ Arguments: (VOID)
+
+ Returns: (VOID)
+
+ --*/
+{
+ NODE NodeQ;
+ NODE NodeR;
+ NODE NodeS;
+ NODE NodeT;
+ NODE NodeU;
+
+ if (mParent[mPos] == NIL) {
+ return ;
+ }
+
+ NodeR = mPrev[mPos];
+ NodeS = mNext[mPos];
+ mNext[NodeR] = NodeS;
+ mPrev[NodeS] = NodeR;
+ NodeR = mParent[mPos];
+ mParent[mPos] = NIL;
+ if (NodeR >= (NODE) WNDSIZ) {
+ return ;
+ }
+
+ mChildCount[NodeR]--;
+ if (mChildCount[NodeR] > 1) {
+ return ;
+ }
+
+ NodeT = (NODE) (mPosition[NodeR] & (UINT32)~PERC_FLAG);
+ if (NodeT >= mPos) {
+ NodeT -= WNDSIZ;
+ }
+
+ NodeS = NodeT;
+ NodeQ = mParent[NodeR];
+ NodeU = mPosition[NodeQ];
+ while (NodeU & (UINT32) PERC_FLAG) {
+ NodeU &= (UINT32)~PERC_FLAG;
+ if (NodeU >= mPos) {
+ NodeU -= WNDSIZ;
+ }
+
+ if (NodeU > NodeS) {
+ NodeS = NodeU;
+ }
+
+ mPosition[NodeQ] = (NODE) (NodeS | WNDSIZ);
+ NodeQ = mParent[NodeQ];
+ NodeU = mPosition[NodeQ];
+ }
+
+ if (NodeQ < (NODE) WNDSIZ) {
+ if (NodeU >= mPos) {
+ NodeU -= WNDSIZ;
+ }
+
+ if (NodeU > NodeS) {
+ NodeS = NodeU;
+ }
+
+ mPosition[NodeQ] = (NODE) (NodeS | WNDSIZ | (UINT32) PERC_FLAG);
+ }
+
+ NodeS = Child (NodeR, mText[NodeT + mLevel[NodeR]]);
+ NodeT = mPrev[NodeS];
+ NodeU = mNext[NodeS];
+ mNext[NodeT] = NodeU;
+ mPrev[NodeU] = NodeT;
+ NodeT = mPrev[NodeR];
+ mNext[NodeT] = NodeS;
+ mPrev[NodeS] = NodeT;
+ NodeT = mNext[NodeR];
+ mPrev[NodeT] = NodeS;
+ mNext[NodeS] = NodeT;
+ mParent[NodeS] = mParent[NodeR];
+ mParent[NodeR] = NIL;
+ mNext[NodeR] = mAvail;
+ mAvail = NodeR;
+}
+
+STATIC
+ VOID
+ GetNextMatch (
+ VOID
+ )
+ /*++
+
+ Routine Description:
+
+ Advance the current position (read new data if needed).
+ Delete outdated string info. Find a match string for current position.
+
+ Arguments: (VOID)
+
+ Returns: (VOID)
+
+ --*/
+{
+ INT32 Number;
+
+ mRemainder--;
+ mPos++;
+ if (mPos == WNDSIZ * 2) {
+ memmove (&mText[0], &mText[WNDSIZ], WNDSIZ + MAXMATCH);
+ Number = FreadCrc (&mText[WNDSIZ + MAXMATCH], WNDSIZ);
+ mRemainder += Number;
+ mPos = WNDSIZ;
+ }
+
+ DeleteNode ();
+ InsertNode ();
+}
+
+STATIC
+ INT32
+ Encode (
+ VOID
+ )
+ /*++
+
+ Routine Description:
+
+ The mac controlling routine for compression process.
+
+ Arguments: (VOID)
+
+ Returns:
+
+ EFI_SUCCESS - The compression is successful
+ EFI_OUT_0F_RESOURCES - Not enough memory for compression process
+
+ --*/
+{
+ INT32 Status;
+ INT32 LastMatchLen;
+ NODE LastMatchPos;
+
+ Status = AllocateMemory ();
+ if (Status) {
+ FreeMemory ();
+ return Status;
+ }
+
+ InitSlide ();
+
+ HufEncodeStart ();
+
+ mRemainder = FreadCrc (&mText[WNDSIZ], WNDSIZ + MAXMATCH);
+
+ mMatchLen = 0;
+ mPos = WNDSIZ;
+ InsertNode ();
+ if (mMatchLen > mRemainder) {
+ mMatchLen = mRemainder;
+ }
+
+ while (mRemainder > 0) {
+ LastMatchLen = mMatchLen;
+ LastMatchPos = mMatchPos;
+ GetNextMatch ();
+ if (mMatchLen > mRemainder) {
+ mMatchLen = mRemainder;
+ }
+
+ if (mMatchLen > LastMatchLen || LastMatchLen < THRESHOLD) {
+ //
+ // Not enough benefits are gained by outputting a pointer,
+ // so just output the original character
+ //
+ Output (mText[mPos - 1], 0);
+
+ } else {
+
+ if (LastMatchLen == THRESHOLD) {
+ if (((mPos - LastMatchPos - 2) & (WNDSIZ - 1)) > (1U << 11)) {
+ Output (mText[mPos - 1], 0);
+ continue;
+ }
+ }
+ //
+ // Outputting a pointer is beneficial enough, do it.
+ //
+ Output (
+ LastMatchLen + (UINT8_MAX + 1 - THRESHOLD),
+ (mPos - LastMatchPos - 2) & (WNDSIZ - 1)
+ );
+ LastMatchLen--;
+ while (LastMatchLen > 0) {
+ GetNextMatch ();
+ LastMatchLen--;
+ }
+
+ if (mMatchLen > mRemainder) {
+ mMatchLen = mRemainder;
+ }
+ }
+ }
+
+ HufEncodeEnd ();
+ FreeMemory ();
+ return EFI_SUCCESS;
+}
+
+STATIC
+ VOID
+ CountTFreq (
+ VOID
+ )
+ /*++
+
+ Routine Description:
+
+ Count the frequencies for the Extra Set
+
+ Arguments: (VOID)
+
+ Returns: (VOID)
+
+ --*/
+{
+ INT32 Index;
+ INT32 Index3;
+ INT32 Number;
+ INT32 Count;
+
+ for (Index = 0; Index < NT; Index++) {
+ mTFreq[Index] = 0;
+ }
+
+ Number = NC;
+ while (Number > 0 && mCLen[Number - 1] == 0) {
+ Number--;
+ }
+
+ Index = 0;
+ while (Index < Number) {
+ Index3 = mCLen[Index++];
+ if (Index3 == 0) {
+ Count = 1;
+ while (Index < Number && mCLen[Index] == 0) {
+ Index++;
+ Count++;
+ }
+
+ if (Count <= 2) {
+ mTFreq[0] = (UINT16) (mTFreq[0] + Count);
+ } else if (Count <= 18) {
+ mTFreq[1]++;
+ } else if (Count == 19) {
+ mTFreq[0]++;
+ mTFreq[1]++;
+ } else {
+ mTFreq[2]++;
+ }
+ } else {
+ mTFreq[Index3 + 2]++;
+ }
+ }
+}
+
+STATIC
+ VOID
+ WritePTLen (
+ INT32 Number,
+ INT32 nbit,
+ INT32 Special
+ )
+ /*++
+
+ Routine Description:
+
+ Outputs the code length array for the Extra Set or the Position Set.
+
+ Arguments:
+
+ Number - the number of symbols
+ nbit - the number of bits needed to represent 'n'
+ Special - the special symbol that needs to be take care of
+
+ Returns: (VOID)
+
+ --*/
+{
+ INT32 Index;
+ INT32 Index3;
+
+ while (Number > 0 && mPTLen[Number - 1] == 0) {
+ Number--;
+ }
+
+ PutBits (nbit, Number);
+ Index = 0;
+ while (Index < Number) {
+ Index3 = mPTLen[Index++];
+ if (Index3 <= 6) {
+ PutBits (3, Index3);
+ } else {
+ PutBits (Index3 - 3, (1U << (Index3 - 3)) - 2);
+ }
+
+ if (Index == Special) {
+ while (Index < 6 && mPTLen[Index] == 0) {
+ Index++;
+ }
+
+ PutBits (2, (Index - 3) & 3);
+ }
+ }
+}
+
+STATIC
+ VOID
+ WriteCLen (
+ VOID
+ )
+ /*++
+
+ Routine Description:
+
+ Outputs the code length array for Char&Length Set
+
+ Arguments: (VOID)
+
+ Returns: (VOID)
+
+ --*/
+{
+ INT32 Index;
+ INT32 Index3;
+ INT32 Number;
+ INT32 Count;
+
+ Number = NC;
+ while (Number > 0 && mCLen[Number - 1] == 0) {
+ Number--;
+ }
+
+ PutBits (CBIT, Number);
+ Index = 0;
+ while (Index < Number) {
+ Index3 = mCLen[Index++];
+ if (Index3 == 0) {
+ Count = 1;
+ while (Index < Number && mCLen[Index] == 0) {
+ Index++;
+ Count++;
+ }
+
+ if (Count <= 2) {
+ for (Index3 = 0; Index3 < Count; Index3++) {
+ PutBits (mPTLen[0], mPTCode[0]);
+ }
+ } else if (Count <= 18) {
+ PutBits (mPTLen[1], mPTCode[1]);
+ PutBits (4, Count - 3);
+ } else if (Count == 19) {
+ PutBits (mPTLen[0], mPTCode[0]);
+ PutBits (mPTLen[1], mPTCode[1]);
+ PutBits (4, 15);
+ } else {
+ PutBits (mPTLen[2], mPTCode[2]);
+ PutBits (CBIT, Count - 20);
+ }
+ } else {
+ PutBits (mPTLen[Index3 + 2], mPTCode[Index3 + 2]);
+ }
+ }
+}
+
+STATIC
+ VOID
+ EncodeC (
+ INT32 Value
+ )
+{
+ PutBits (mCLen[Value], mCCode[Value]);
+}
+
+STATIC
+ VOID
+ EncodeP (
+ UINT32 Value
+ )
+{
+ UINT32 Index;
+ UINT32 NodeQ;
+
+ Index = 0;
+ NodeQ = Value;
+ while (NodeQ) {
+ NodeQ >>= 1;
+ Index++;
+ }
+
+ PutBits (mPTLen[Index], mPTCode[Index]);
+ if (Index > 1) {
+ PutBits (Index - 1, Value & (0xFFFFFFFFU >> (32 - Index + 1)));
+ }
+}
+
+STATIC
+ VOID
+ SendBlock (
+ VOID
+ )
+ /*++
+
+ Routine Description:
+
+ Huffman code the block and output it.
+
+ Arguments:
+ (VOID)
+
+ Returns:
+ (VOID)
+
+ --*/
+{
+ UINT32 Index;
+ UINT32 Index2;
+ UINT32 Index3;
+ UINT32 Flags;
+ UINT32 Root;
+ UINT32 Pos;
+ UINT32 Size;
+ Flags = 0;
+
+ Root = MakeTree (NC, mCFreq, mCLen, mCCode);
+ Size = mCFreq[Root];
+ PutBits (16, Size);
+ if (Root >= NC) {
+ CountTFreq ();
+ Root = MakeTree (NT, mTFreq, mPTLen, mPTCode);
+ if (Root >= NT) {
+ WritePTLen (NT, TBIT, 3);
+ } else {
+ PutBits (TBIT, 0);
+ PutBits (TBIT, Root);
+ }
+
+ WriteCLen ();
+ } else {
+ PutBits (TBIT, 0);
+ PutBits (TBIT, 0);
+ PutBits (CBIT, 0);
+ PutBits (CBIT, Root);
+ }
+
+ Root = MakeTree (NP, mPFreq, mPTLen, mPTCode);
+ if (Root >= NP) {
+ WritePTLen (NP, mPbit, -1);
+ } else {
+ PutBits (mPbit, 0);
+ PutBits (mPbit, Root);
+ }
+
+ Pos = 0;
+ for (Index = 0; Index < Size; Index++) {
+ if (Index % UINT8_BIT == 0) {
+ Flags = mBuf[Pos++];
+ } else {
+ Flags <<= 1;
+ }
+
+ if (Flags & (1U << (UINT8_BIT - 1))) {
+ EncodeC (mBuf[Pos++] + (1U << UINT8_BIT));
+ Index3 = mBuf[Pos++];
+ for (Index2 = 0; Index2 < 3; Index2++) {
+ Index3 <<= UINT8_BIT;
+ Index3 += mBuf[Pos++];
+ }
+
+ EncodeP (Index3);
+ } else {
+ EncodeC (mBuf[Pos++]);
+ }
+ }
+
+ for (Index = 0; Index < NC; Index++) {
+ mCFreq[Index] = 0;
+ }
+
+ for (Index = 0; Index < NP; Index++) {
+ mPFreq[Index] = 0;
+ }
+}
+
+STATIC
+ VOID
+ Output (
+ UINT32 CharC,
+ UINT32 Pos
+ )
+ /*++
+
+ Routine Description:
+
+ Outputs an Original Character or a Pointer
+
+ Arguments:
+
+ CharC - The original character or the 'String Length' element of a Pointer
+ Pos - The 'Position' field of a Pointer
+
+ Returns: (VOID)
+
+ --*/
+{
+ STATIC UINT32 CPos;
+
+ if ((mOutputMask >>= 1) == 0) {
+ mOutputMask = 1U << (UINT8_BIT - 1);
+ //
+ // Check the buffer overflow per outputting UINT8_BIT symbols
+ // which is an Original Character or a Pointer. The biggest
+ // symbol is a Pointer which occupies 5 bytes.
+ //
+ if (mOutputPos >= mBufSiz - 5 * UINT8_BIT) {
+ SendBlock ();
+ mOutputPos = 0;
+ }
+
+ CPos = mOutputPos++;
+ mBuf[CPos] = 0;
+ }
+
+ mBuf[mOutputPos++] = (UINT8) CharC;
+ mCFreq[CharC]++;
+ if (CharC >= (1U << UINT8_BIT)) {
+ mBuf[CPos] |= mOutputMask;
+ mBuf[mOutputPos++] = (UINT8) (Pos >> 24);
+ mBuf[mOutputPos++] = (UINT8) (Pos >> 16);
+ mBuf[mOutputPos++] = (UINT8) (Pos >> (UINT8_BIT));
+ mBuf[mOutputPos++] = (UINT8) Pos;
+ CharC = 0;
+ while (Pos) {
+ Pos >>= 1;
+ CharC++;
+ }
+
+ mPFreq[CharC]++;
+ }
+}
+
+STATIC
+ VOID
+ HufEncodeStart (
+ VOID
+ )
+{
+ INT32 Index;
+
+ for (Index = 0; Index < NC; Index++) {
+ mCFreq[Index] = 0;
+ }
+
+ for (Index = 0; Index < NP; Index++) {
+ mPFreq[Index] = 0;
+ }
+
+ mOutputPos = mOutputMask = 0;
+ InitPutBits ();
+ return ;
+}
+
+STATIC
+ VOID
+ HufEncodeEnd (
+ VOID
+ )
+{
+ SendBlock ();
+
+ //
+ // Flush remaining bits
+ //
+ PutBits (UINT8_BIT - 1, 0);
+
+ return ;
+}
+
+STATIC
+ VOID
+ MakeCrcTable (
+ VOID
+ )
+{
+ UINT32 Index;
+ UINT32 Index2;
+ UINT32 Temp;
+
+ for (Index = 0; Index <= UINT8_MAX; Index++) {
+ Temp = Index;
+ for (Index2 = 0; Index2 < UINT8_BIT; Index2++) {
+ if (Temp & 1) {
+ Temp = (Temp >> 1) ^ CRCPOLY;
+ } else {
+ Temp >>= 1;
+ }
+ }
+
+ mCrcTable[Index] = (UINT16) Temp;
+ }
+}
+
+STATIC
+ VOID
+ PutBits (
+ INT32 Number,
+ UINT32 Value
+ )
+ /*++
+
+ Routine Description:
+
+ Outputs rightmost n bits of x
+
+ Arguments:
+
+ Number - the rightmost n bits of the data is used
+ x - the data
+
+ Returns: (VOID)
+
+ --*/
+{
+ UINT8 Temp;
+
+ while (Number >= mBitCount) {
+ //
+ // Number -= mBitCount should never equal to 32
+ //
+ Temp = (UINT8) (mSubBitBuf | (Value >> (Number -= mBitCount)));
+ if (mDst < mDstUpperLimit) {
+ *mDst++ = Temp;
+ }
+
+ mCompSize++;
+ mSubBitBuf = 0;
+ mBitCount = UINT8_BIT;
+ }
+
+ mSubBitBuf |= Value << (mBitCount -= Number);
+}
+
+STATIC
+ INT32
+ FreadCrc (
+ UINT8 *Pointer,
+ INT32 Number
+ )
+ /*++
+
+ Routine Description:
+
+ Read source data
+
+ Arguments:
+
+ Pointer - the buffer to hold the data
+ Number - number of bytes to read
+
+ Returns:
+
+ number of bytes actually read
+
+ --*/
+{
+ INT32 Index;
+
+ for (Index = 0; mSrc < mSrcUpperLimit && Index < Number; Index++) {
+ *Pointer++ = *mSrc++;
+ }
+
+ Number = Index;
+
+ Pointer -= Number;
+ mOrigSize += Number;
+ Index--;
+ while (Index >= 0) {
+ UPDATE_CRC (*Pointer++);
+ Index--;
+ }
+
+ return Number;
+}
+
+STATIC
+ VOID
+ InitPutBits (
+ VOID
+ )
+{
+ mBitCount = UINT8_BIT;
+ mSubBitBuf = 0;
+}
+
+STATIC
+ VOID
+ CountLen (
+ INT32 Index
+ )
+ /*++
+
+ Routine Description:
+
+ Count the number of each code length for a Huffman tree.
+
+ Arguments:
+
+ Index - the top node
+
+ Returns: (VOID)
+
+ --*/
+{
+ STATIC INT32 Depth = 0;
+
+ if (Index < mN) {
+ mLenCnt[(Depth < 16) ? Depth : 16]++;
+ } else {
+ Depth++;
+ CountLen (mLeft[Index]);
+ CountLen (mRight[Index]);
+ Depth--;
+ }
+}
+
+STATIC
+ VOID
+ MakeLen (
+ INT32 Root
+ )
+ /*++
+
+ Routine Description:
+
+ Create code length array for a Huffman tree
+
+ Arguments:
+
+ Root - the root of the tree
+
+ Returns:
+
+ VOID
+
+ --*/
+{
+ INT32 Index;
+ INT32 Index3;
+ UINT32 Cum;
+
+ for (Index = 0; Index <= 16; Index++) {
+ mLenCnt[Index] = 0;
+ }
+
+ CountLen (Root);
+
+ //
+ // Adjust the length count array so that
+ // no code will be generated longer than its designated length
+ //
+ Cum = 0;
+ for (Index = 16; Index > 0; Index--) {
+ Cum += mLenCnt[Index] << (16 - Index);
+ }
+
+ while (Cum != (1U << 16)) {
+ mLenCnt[16]--;
+ for (Index = 15; Index > 0; Index--) {
+ if (mLenCnt[Index] != 0) {
+ mLenCnt[Index]--;
+ mLenCnt[Index + 1] += 2;
+ break;
+ }
+ }
+
+ Cum--;
+ }
+
+ for (Index = 16; Index > 0; Index--) {
+ Index3 = mLenCnt[Index];
+ Index3--;
+ while (Index3 >= 0) {
+ mLen[*mSortPtr++] = (UINT8) Index;
+ Index3--;
+ }
+ }
+}
+
+STATIC
+ VOID
+ DownHeap (
+ INT32 Index
+ )
+{
+ INT32 Index2;
+ INT32 Index3;
+
+ //
+ // priority queue: send Index-th entry down heap
+ //
+ Index3 = mHeap[Index];
+ Index2 = 2 * Index;
+ while (Index2 <= mHeapSize) {
+ if (Index2 < mHeapSize && mFreq[mHeap[Index2]] > mFreq[mHeap[Index2 + 1]]) {
+ Index2++;
+ }
+
+ if (mFreq[Index3] <= mFreq[mHeap[Index2]]) {
+ break;
+ }
+
+ mHeap[Index] = mHeap[Index2];
+ Index = Index2;
+ Index2 = 2 * Index;
+ }
+
+ mHeap[Index] = (INT16) Index3;
+}
+
+STATIC
+ VOID
+ MakeCode (
+ INT32 Number,
+ UINT8 Len[ ],
+ UINT16 Code[]
+)
+ /*++
+
+ Routine Description:
+
+ Assign code to each symbol based on the code length array
+
+ Arguments:
+
+ Number - number of symbols
+ Len - the code length array
+ Code - stores codes for each symbol
+
+ Returns: (VOID)
+
+ --*/
+{
+ INT32 Index;
+ UINT16 Start[18];
+
+ Start[1] = 0;
+ for (Index = 1; Index <= 16; Index++) {
+ Start[Index + 1] = (UINT16) ((Start[Index] + mLenCnt[Index]) << 1);
+ }
+
+ for (Index = 0; Index < Number; Index++) {
+ Code[Index] = Start[Len[Index]]++;
+ }
+}
+
+STATIC
+ INT32
+ MakeTree (
+ INT32 NParm,
+ UINT16 FreqParm[],
+ UINT8 LenParm[ ],
+ UINT16 CodeParm[]
+)
+ /*++
+
+ Routine Description:
+
+ Generates Huffman codes given a frequency distribution of symbols
+
+ Arguments:
+
+ NParm - number of symbols
+ FreqParm - frequency of each symbol
+ LenParm - code length for each symbol
+ CodeParm - code for each symbol
+
+ Returns:
+
+ Root of the Huffman tree.
+
+ --*/
+{
+ INT32 Index;
+ INT32 Index2;
+ INT32 Index3;
+ INT32 Avail;
+
+ //
+ // make tree, calculate len[], return root
+ //
+ mN = NParm;
+ mFreq = FreqParm;
+ mLen = LenParm;
+ Avail = mN;
+ mHeapSize = 0;
+ mHeap[1] = 0;
+ for (Index = 0; Index < mN; Index++) {
+ mLen[Index] = 0;
+ if (mFreq[Index]) {
+ mHeapSize++;
+ mHeap[mHeapSize] = (INT16) Index;
+ }
+ }
+
+ if (mHeapSize < 2) {
+ CodeParm[mHeap[1]] = 0;
+ return mHeap[1];
+ }
+
+ for (Index = mHeapSize / 2; Index >= 1; Index--) {
+ //
+ // make priority queue
+ //
+ DownHeap (Index);
+ }
+
+ mSortPtr = CodeParm;
+ do {
+ Index = mHeap[1];
+ if (Index < mN) {
+ *mSortPtr++ = (UINT16) Index;
+ }
+
+ mHeap[1] = mHeap[mHeapSize--];
+ DownHeap (1);
+ Index2 = mHeap[1];
+ if (Index2 < mN) {
+ *mSortPtr++ = (UINT16) Index2;
+ }
+
+ Index3 = Avail++;
+ mFreq[Index3] = (UINT16) (mFreq[Index] + mFreq[Index2]);
+ mHeap[1] = (INT16) Index3;
+ DownHeap (1);
+ mLeft[Index3] = (UINT16) Index;
+ mRight[Index3] = (UINT16) Index2;
+ } while (mHeapSize > 1);
+
+ mSortPtr = CodeParm;
+ MakeLen (Index3);
+ MakeCode (NParm, LenParm, CodeParm);
+
+ //
+ // return root
+ //
+ return Index3;
+}
diff --git a/guidlineedit.cpp b/guidlineedit.cpp
new file mode 100644
index 0000000..a441e0c
--- /dev/null
+++ b/guidlineedit.cpp
@@ -0,0 +1,61 @@
+/* guidlineedit.cpp
+
+ Copyright (c) 2014, Nikolaj Schlej. All rights reserved.
+ 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 "guidlineedit.h"
+
+GuidLineEdit::GuidLineEdit(QWidget * parent)
+ :QLineEdit(parent)
+{
+}
+
+GuidLineEdit::GuidLineEdit(const QString & contents, QWidget * parent)
+ :QLineEdit(contents, parent)
+{
+}
+
+GuidLineEdit::~GuidLineEdit()
+{
+}
+
+void GuidLineEdit::keyPressEvent(QKeyEvent * event)
+{
+ if (event == QKeySequence::Delete || event->key() == Qt::Key_Backspace)
+ {
+ int pos = cursorPosition();
+ if (event->key() == Qt::Key_Backspace && pos > 0) {
+ cursorBackward(false);
+ pos = cursorPosition();
+ }
+
+ QString txt = text();
+ QString selected = selectedText();
+
+ if (!selected.isEmpty()) {
+ pos = QLineEdit::selectionStart();
+ for (int i = pos; i < pos + selected.count(); i++)
+ if (txt[i] != QChar('-'))
+ txt[i] = QChar('.');
+ }
+ else
+ txt[pos] = QChar('.');
+
+ setCursorPosition(0);
+ insert(txt);
+ setCursorPosition(pos);
+
+ return;
+ }
+
+ // Call original event handler
+ QLineEdit::keyPressEvent(event);
+}
\ No newline at end of file
diff --git a/guidlineedit.h b/guidlineedit.h
new file mode 100644
index 0000000..5324b7b
--- /dev/null
+++ b/guidlineedit.h
@@ -0,0 +1,36 @@
+/* guidlineedit.h
+
+ Copyright (c) 2014, Nikolaj Schlej. All rights reserved.
+ 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.
+
+ */
+
+#ifndef __GUIDLINEEDIT_H__
+#define __GUIDLINEEDIT_H__
+
+#include
+#include
+#include
+#include
+
+#include "basetypes.h"
+
+class GuidLineEdit : public QLineEdit
+{
+public:
+ GuidLineEdit(QWidget * parent = 0);
+ GuidLineEdit(const QString & contents, QWidget * parent = 0);
+ ~GuidLineEdit();
+
+protected:
+ void keyPressEvent(QKeyEvent * event);
+
+};
+
+#endif
diff --git a/searchdialog.ui b/searchdialog.ui
index 4bcc006..c1e2f56 100644
--- a/searchdialog.ui
+++ b/searchdialog.ui
@@ -101,7 +101,7 @@
-
-
+
Consolas
@@ -217,6 +217,13 @@
+
+
+ GuidLineEdit
+ QLineEdit
+
+
+
tabWidget
hexEdit
diff --git a/uefitool.cpp b/uefitool.cpp
index 58e8f69..1332648 100644
--- a/uefitool.cpp
+++ b/uefitool.cpp
@@ -17,7 +17,7 @@
UEFITool::UEFITool(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::UEFITool),
-version(tr("0.18.6"))
+version(tr("0.18.7"))
{
clipboard = QApplication::clipboard();
diff --git a/uefitool.pro b/uefitool.pro
index 7ce3ed9..73e258c 100644
--- a/uefitool.pro
+++ b/uefitool.pro
@@ -14,6 +14,7 @@ SOURCES += uefitool_main.cpp \
treeitem.cpp \
treemodel.cpp \
messagelistitem.cpp \
+ guidlineedit.cpp \
LZMA/LzmaCompress.c \
LZMA/LzmaDecompress.c \
LZMA/SDK/C/LzFind.c \
@@ -35,6 +36,7 @@ HEADERS += uefitool.h \
treeitem.h \
treemodel.h \
messagelistitem.h \
+ guidlineedit.h \
LZMA/LzmaCompress.h \
LZMA/LzmaDecompress.h \
Tiano/EfiTianoDecompress.h \
diff --git a/uefitool.ui b/uefitool.ui
index 3bcb6bc..3e92815 100644
--- a/uefitool.ui
+++ b/uefitool.ui
@@ -497,7 +497,7 @@
- C&opy All
+ C&opy all
Ctrl+Alt+C