tianocompress.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,766 行 · 第 1/3 页
C
1,766 行
return NodeR;
}
STATIC
VOID
MakeChild (
IN NODE Parent,
IN UINT8 CharC,
IN 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. 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--;
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 < 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 >= 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 >= 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 < 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 in 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
EFI_STATUS
Encode (
VOID
)
/*++
Routine Description:
The main controlling routine for compression process.
Arguments: (VOID)
Returns:
EFI_SUCCESS - The compression is successful
EFI_OUT_0F_RESOURCES - Not enough memory for compression process
--*/
{
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;
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 (
IN INT32 Number,
IN INT32 nbit,
IN 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 {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?