]>
git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/C/TianoCompress/TianoCompress.c
2 Compression routine. The compression algorithm is a mixture of LZ77 and Huffman
3 coding. LZ77 transforms the source data into a sequence of Original Characters
4 and Pointers to repeated strings.
5 This sequence is further divided into Blocks and Huffman codings are applied to
8 Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
9 SPDX-License-Identifier: BSD-2-Clause-Patent
14 #include "Decompress.h"
15 #include "TianoCompress.h"
16 #include "EfiUtilityMsgs.h"
24 static BOOLEAN VerboseMode
= FALSE
;
25 static BOOLEAN QuietMode
= FALSE
;
27 #define UINT8_MAX 0xff
32 #define WNDSIZ (1U << WNDBIT)
34 #define BLKSIZ (1U << 14) // 16 * 1024U
35 #define PERC_FLAG 0x80000000U
38 #define MAX_HASH_VAL (3 * WNDSIZ + (WNDSIZ / 512 + 1) * UINT8_MAX)
39 #define HASH(p, c) ((p) + ((c) << (WNDBIT - 9)) + WNDSIZ * 2)
40 #define CRCPOLY 0xA001
41 #define UPDATE_CRC(c) mCrc = mCrcTable[(mCrc ^ (c)) & 0xFF] ^ (mCrc >> UINT8_BIT)
44 // C: the Char&Len Set; P: the Position Set; T: the exTra Set
46 //#define NC (UINT8_MAX + MAXMATCH + 2 - THRESHOLD)
48 #define NP (WNDBIT + 1)
50 //#define NT (CODE_BIT + 3)
61 STATIC BOOLEAN ENCODE
= FALSE
;
62 STATIC BOOLEAN DECODE
= FALSE
;
63 STATIC BOOLEAN UEFIMODE
= FALSE
;
64 STATIC UINT8
*mSrc
, *mDst
, *mSrcUpperLimit
, *mDstUpperLimit
;
65 STATIC UINT8
*mLevel
, *mText
, *mChildCount
, *mBuf
, mCLen
[NC
], mPTLen
[NPT
], *mLen
;
66 STATIC INT16 mHeap
[NC
+ 1];
67 STATIC INT32 mRemainder
, mMatchLen
, mBitCount
, mHeapSize
, mN
;
68 STATIC UINT32 mBufSiz
= 0, mOutputPos
, mOutputMask
, mSubBitBuf
, mCrc
;
69 STATIC UINT32 mCompSize
, mOrigSize
;
71 STATIC UINT16
*mFreq
, *mSortPtr
, mLenCnt
[17], mLeft
[2 * NC
- 1], mRight
[2 * NC
- 1], mCrcTable
[UINT8_MAX
+ 1],
72 mCFreq
[2 * NC
- 1], mCCode
[NC
], mPFreq
[2 * NP
- 1], mPTCode
[NPT
], mTFreq
[2 * NT
- 1];
74 STATIC NODE mPos
, mMatchPos
, mAvail
, *mPosition
, *mParent
, *mPrev
, *mNext
= NULL
;
76 static UINT64 DebugLevel
;
77 static BOOLEAN DebugMode
;
86 IN OUT UINT32
*DstSize
92 The internal implementation of [Efi/Tiano]Compress().
96 SrcBuffer - The buffer storing the source data
97 SrcSize - The size of source data
98 DstBuffer - The buffer to store the compressed data
100 Version - The version of de/compression algorithm.
101 Version 1 for EFI 1.1 de/compression algorithm.
102 Version 2 for Tiano de/compression algorithm.
106 EFI_BUFFER_TOO_SMALL - The DstBuffer is too small. In this case,
107 DstSize contains the size needed.
108 EFI_SUCCESS - Compression is successful.
109 EFI_OUT_OF_RESOURCES - No resource to complete function.
110 EFI_INVALID_PARAMETER - Parameter supplied is wrong.
131 mSrcUpperLimit
= mSrc
+ SrcSize
;
133 mDstUpperLimit
= mDst
+*DstSize
;
140 mOrigSize
= mCompSize
= 0;
147 if (EFI_ERROR (Status
)) {
148 return EFI_OUT_OF_RESOURCES
;
152 // Null terminate the compressed data
155 if (mDst
< mDstUpperLimit
) {
160 // Fill in compressed size and original size
164 PutDword (mCompSize
+ 1);
165 PutDword (mOrigSize
);
170 if (mCompSize
+ 1 + 8 > *DstSize
) {
171 *DstSize
= mCompSize
+ 1 + 8;
172 return EFI_BUFFER_TOO_SMALL
;
174 *DstSize
= mCompSize
+ 1 + 8;
188 Put a dword to output stream
192 Data - the dword to put
198 if (mDst
< mDstUpperLimit
) {
199 *mDst
++ = (UINT8
) (((UINT8
) (Data
)) & 0xff);
202 if (mDst
< mDstUpperLimit
) {
203 *mDst
++ = (UINT8
) (((UINT8
) (Data
>> 0x08)) & 0xff);
206 if (mDst
< mDstUpperLimit
) {
207 *mDst
++ = (UINT8
) (((UINT8
) (Data
>> 0x10)) & 0xff);
210 if (mDst
< mDstUpperLimit
) {
211 *mDst
++ = (UINT8
) (((UINT8
) (Data
>> 0x18)) & 0xff);
224 Allocate memory spaces for data structures used in compression process
231 EFI_SUCCESS - Memory is allocated successfully
232 EFI_OUT_OF_RESOURCES - Allocation fails
238 mText
= malloc (WNDSIZ
* 2 + MAXMATCH
);
240 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
241 return EFI_OUT_OF_RESOURCES
;
243 for (Index
= 0; Index
< WNDSIZ
* 2 + MAXMATCH
; Index
++) {
247 mLevel
= malloc ((WNDSIZ
+ UINT8_MAX
+ 1) * sizeof (*mLevel
));
248 mChildCount
= malloc ((WNDSIZ
+ UINT8_MAX
+ 1) * sizeof (*mChildCount
));
249 mPosition
= malloc ((WNDSIZ
+ UINT8_MAX
+ 1) * sizeof (*mPosition
));
250 mParent
= malloc (WNDSIZ
* 2 * sizeof (*mParent
));
251 mPrev
= malloc (WNDSIZ
* 2 * sizeof (*mPrev
));
252 mNext
= malloc ((MAX_HASH_VAL
+ 1) * sizeof (*mNext
));
253 if (mLevel
== NULL
|| mChildCount
== NULL
|| mPosition
== NULL
||
254 mParent
== NULL
|| mPrev
== NULL
|| mNext
== NULL
) {
255 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
256 return EFI_OUT_OF_RESOURCES
;
260 mBuf
= malloc (mBufSiz
);
261 while (mBuf
== NULL
) {
262 mBufSiz
= (mBufSiz
/ 10U) * 9U;
263 if (mBufSiz
< 4 * 1024U) {
264 return EFI_OUT_OF_RESOURCES
;
267 mBuf
= malloc (mBufSiz
);
283 Called when compression is completed to free memory previously allocated.
295 if (mLevel
!= NULL
) {
299 if (mChildCount
!= NULL
) {
303 if (mPosition
!= NULL
) {
307 if (mParent
!= NULL
) {
335 Initialize String Info Log data structures
345 for (Index
= WNDSIZ
; Index
<= WNDSIZ
+ UINT8_MAX
; Index
++) {
347 mPosition
[Index
] = NIL
; // sentinel
350 for (Index
= WNDSIZ
; Index
< WNDSIZ
* 2; Index
++) {
351 mParent
[Index
] = NIL
;
355 for (Index
= 1; Index
< WNDSIZ
- 1; Index
++) {
356 mNext
[Index
] = (NODE
) (Index
+ 1);
359 mNext
[WNDSIZ
- 1] = NIL
;
360 for (Index
= WNDSIZ
* 2; Index
<= MAX_HASH_VAL
; Index
++) {
375 Find child node given the parent node and the edge character
379 NodeQ - the parent node
380 CharC - the edge character
384 The child node (NIL if not found)
390 NodeR
= mNext
[HASH (NodeQ
, CharC
)];
394 mParent
[NIL
] = NodeQ
;
395 while (mParent
[NodeR
] != NodeQ
) {
396 NodeR
= mNext
[NodeR
];
413 Create a new child for a given parent node.
417 Parent - the parent node
418 CharC - the edge character
419 Child - the child node
428 Node1
= (NODE
) HASH (Parent
, CharC
);
429 Node2
= mNext
[Node1
];
430 mNext
[Node1
] = Child
;
431 mNext
[Child
] = Node2
;
432 mPrev
[Node2
] = Child
;
433 mPrev
[Child
] = Node1
;
434 mParent
[Child
] = Parent
;
435 mChildCount
[Parent
]++;
451 Old - the node to split
462 mChildCount
[New
] = 0;
463 TempNode
= mPrev
[Old
];
464 mPrev
[New
] = TempNode
;
465 mNext
[TempNode
] = New
;
466 TempNode
= mNext
[Old
];
467 mNext
[New
] = TempNode
;
468 mPrev
[TempNode
] = New
;
469 mParent
[New
] = mParent
[Old
];
470 mLevel
[New
] = (UINT8
) mMatchLen
;
471 mPosition
[New
] = mPos
;
472 MakeChild (New
, mText
[mMatchPos
+ mMatchLen
], Old
);
473 MakeChild (New
, mText
[mPos
+ mMatchLen
], mPos
);
485 Insert string info for current position into the String Info Log
501 if (mMatchLen
>= 4) {
503 // We have just got a long match, the target tree
504 // can be located by MatchPos + 1. Traverse the tree
505 // from bottom up to get to a proper starting point.
506 // The usage of PERC_FLAG ensures proper node deletion
507 // in DeleteNode() later.
510 NodeR
= (NODE
) ((mMatchPos
+ 1) | WNDSIZ
);
511 NodeQ
= mParent
[NodeR
];
512 while (NodeQ
== NIL
) {
513 NodeR
= mNext
[NodeR
];
514 NodeQ
= mParent
[NodeR
];
517 while (mLevel
[NodeQ
] >= mMatchLen
) {
519 NodeQ
= mParent
[NodeQ
];
523 while (mPosition
[NodeT
] < 0) {
524 mPosition
[NodeT
] = mPos
;
525 NodeT
= mParent
[NodeT
];
528 if (NodeT
< WNDSIZ
) {
529 mPosition
[NodeT
] = (NODE
) (mPos
| (UINT32
) PERC_FLAG
);
533 // Locate the target tree
535 NodeQ
= (NODE
) (mText
[mPos
] + WNDSIZ
);
536 CharC
= mText
[mPos
+ 1];
537 NodeR
= Child (NodeQ
, CharC
);
539 MakeChild (NodeQ
, CharC
, mPos
);
547 // Traverse down the tree to find a match.
548 // Update Position value along the route.
549 // Node split or creation is involved.
552 if (NodeR
>= WNDSIZ
) {
556 Index2
= mLevel
[NodeR
];
557 mMatchPos
= (NODE
) (mPosition
[NodeR
] & (UINT32
)~PERC_FLAG
);
560 if (mMatchPos
>= mPos
) {
564 t1
= &mText
[mPos
+ mMatchLen
];
565 t2
= &mText
[mMatchPos
+ mMatchLen
];
566 while (mMatchLen
< Index2
) {
577 if (mMatchLen
>= MAXMATCH
) {
581 mPosition
[NodeR
] = mPos
;
583 NodeR
= Child (NodeQ
, *t1
);
585 MakeChild (NodeQ
, *t1
, mPos
);
592 NodeT
= mPrev
[NodeR
];
595 NodeT
= mNext
[NodeR
];
598 mParent
[mPos
] = NodeQ
;
599 mParent
[NodeR
] = NIL
;
602 // Special usage of 'next'
617 Delete outdated string info. (The Usage of PERC_FLAG
618 ensures a clean deletion)
632 if (mParent
[mPos
] == NIL
) {
638 mNext
[NodeR
] = NodeS
;
639 mPrev
[NodeS
] = NodeR
;
640 NodeR
= mParent
[mPos
];
642 if (NodeR
>= WNDSIZ
) {
646 mChildCount
[NodeR
]--;
647 if (mChildCount
[NodeR
] > 1) {
651 NodeT
= (NODE
) (mPosition
[NodeR
] & (UINT32
)~PERC_FLAG
);
657 NodeQ
= mParent
[NodeR
];
658 NodeU
= mPosition
[NodeQ
];
659 while (NodeU
& (UINT32
) PERC_FLAG
) {
660 NodeU
&= (UINT32
)~PERC_FLAG
;
669 mPosition
[NodeQ
] = (NODE
) (NodeS
| WNDSIZ
);
670 NodeQ
= mParent
[NodeQ
];
671 NodeU
= mPosition
[NodeQ
];
674 if (NodeQ
< WNDSIZ
) {
683 mPosition
[NodeQ
] = (NODE
) (NodeS
| WNDSIZ
| (UINT32
) PERC_FLAG
);
686 NodeS
= Child (NodeR
, mText
[NodeT
+ mLevel
[NodeR
]]);
687 NodeT
= mPrev
[NodeS
];
688 NodeU
= mNext
[NodeS
];
689 mNext
[NodeT
] = NodeU
;
690 mPrev
[NodeU
] = NodeT
;
691 NodeT
= mPrev
[NodeR
];
692 mNext
[NodeT
] = NodeS
;
693 mPrev
[NodeS
] = NodeT
;
694 NodeT
= mNext
[NodeR
];
695 mPrev
[NodeT
] = NodeS
;
696 mNext
[NodeS
] = NodeT
;
697 mParent
[NodeS
] = mParent
[NodeR
];
698 mParent
[NodeR
] = NIL
;
699 mNext
[NodeR
] = mAvail
;
712 Advance the current position (read in new data if needed).
713 Delete outdated string info. Find a match string for current position.
725 if (mPos
== WNDSIZ
* 2) {
726 memmove (&mText
[0], &mText
[WNDSIZ
], WNDSIZ
+ MAXMATCH
);
727 Number
= FreadCrc (&mText
[WNDSIZ
+ MAXMATCH
], WNDSIZ
);
728 mRemainder
+= Number
;
745 The main controlling routine for compression process.
751 EFI_SUCCESS - The compression is successful
752 EFI_OUT_0F_RESOURCES - Not enough memory for compression process
760 Status
= AllocateMemory ();
761 if (EFI_ERROR (Status
)) {
770 mRemainder
= FreadCrc (&mText
[WNDSIZ
], WNDSIZ
+ MAXMATCH
);
775 if (mMatchLen
> mRemainder
) {
776 mMatchLen
= mRemainder
;
779 while (mRemainder
> 0) {
780 LastMatchLen
= mMatchLen
;
781 LastMatchPos
= mMatchPos
;
783 if (mMatchLen
> mRemainder
) {
784 mMatchLen
= mRemainder
;
787 if (mMatchLen
> LastMatchLen
|| LastMatchLen
< THRESHOLD
) {
789 // Not enough benefits are gained by outputting a pointer,
790 // so just output the original character
792 Output (mText
[mPos
- 1], 0);
796 if (LastMatchLen
== THRESHOLD
) {
797 if (((mPos
- LastMatchPos
- 2) & (WNDSIZ
- 1)) > (1U << 11)) {
798 Output (mText
[mPos
- 1], 0);
803 // Outputting a pointer is beneficial enough, do it.
806 LastMatchLen
+ (UINT8_MAX
+ 1 - THRESHOLD
),
807 (mPos
- LastMatchPos
- 2) & (WNDSIZ
- 1)
810 while (LastMatchLen
> 0) {
815 if (mMatchLen
> mRemainder
) {
816 mMatchLen
= mRemainder
;
835 Count the frequencies for the Extra Set
848 for (Index
= 0; Index
< NT
; Index
++) {
853 while (Number
> 0 && mCLen
[Number
- 1] == 0) {
858 while (Index
< Number
) {
859 Index3
= mCLen
[Index
++];
862 while (Index
< Number
&& mCLen
[Index
] == 0) {
868 mTFreq
[0] = (UINT16
) (mTFreq
[0] + Count
);
869 } else if (Count
<= 18) {
871 } else if (Count
== 19) {
878 mTFreq
[Index3
+ 2]++;
894 Outputs the code length array for the Extra Set or the Position Set.
898 Number - the number of symbols
899 nbit - the number of bits needed to represent 'n'
900 Special - the special symbol that needs to be take care of
909 while (Number
> 0 && mPTLen
[Number
- 1] == 0) {
913 PutBits (nbit
, Number
);
915 while (Index
< Number
) {
916 Index3
= mPTLen
[Index
++];
920 PutBits (Index3
- 3, (1U << (Index3
- 3)) - 2);
923 if (Index
== Special
) {
924 while (Index
< 6 && mPTLen
[Index
] == 0) {
928 PutBits (2, (Index
- 3) & 3);
942 Outputs the code length array for Char&Length Set
956 while (Number
> 0 && mCLen
[Number
- 1] == 0) {
960 PutBits (CBIT
, Number
);
962 while (Index
< Number
) {
963 Index3
= mCLen
[Index
++];
966 while (Index
< Number
&& mCLen
[Index
] == 0) {
972 for (Index3
= 0; Index3
< Count
; Index3
++) {
973 PutBits (mPTLen
[0], mPTCode
[0]);
975 } else if (Count
<= 18) {
976 PutBits (mPTLen
[1], mPTCode
[1]);
977 PutBits (4, Count
- 3);
978 } else if (Count
== 19) {
979 PutBits (mPTLen
[0], mPTCode
[0]);
980 PutBits (mPTLen
[1], mPTCode
[1]);
983 PutBits (mPTLen
[2], mPTCode
[2]);
984 PutBits (CBIT
, Count
- 20);
987 PutBits (mPTLen
[Index3
+ 2], mPTCode
[Index3
+ 2]);
998 PutBits (mCLen
[Value
], mCCode
[Value
]);
1017 PutBits (mPTLen
[Index
], mPTCode
[Index
]);
1019 PutBits (Index
- 1, Value
& (0xFFFFFFFFU
>> (32 - Index
+ 1)));
1030 Routine Description:
1032 Huffman code the block and output it.
1051 Root
= MakeTree (NC
, mCFreq
, mCLen
, mCCode
);
1052 Size
= mCFreq
[Root
];
1057 Root
= MakeTree (NT
, mTFreq
, mPTLen
, mPTCode
);
1059 WritePTLen (NT
, TBIT
, 3);
1062 PutBits (TBIT
, Root
);
1070 PutBits (CBIT
, Root
);
1073 Root
= MakeTree (NP
, mPFreq
, mPTLen
, mPTCode
);
1075 WritePTLen (NP
, PBIT
, -1);
1078 PutBits (PBIT
, Root
);
1082 for (Index
= 0; Index
< Size
; Index
++) {
1083 if (Index
% UINT8_BIT
== 0) {
1084 Flags
= mBuf
[Pos
++];
1089 if (Flags
& (1U << (UINT8_BIT
- 1))) {
1090 EncodeC (mBuf
[Pos
++] + (1U << UINT8_BIT
));
1091 Index3
= mBuf
[Pos
++];
1092 for (Index2
= 0; Index2
< 3; Index2
++) {
1093 Index3
<<= UINT8_BIT
;
1094 Index3
+= mBuf
[Pos
++];
1099 EncodeC (mBuf
[Pos
++]);
1103 for (Index
= 0; Index
< NC
; Index
++) {
1107 for (Index
= 0; Index
< NP
; Index
++) {
1120 Routine Description:
1122 Outputs an Original Character or a Pointer
1126 CharC - The original character or the 'String Length' element of a Pointer
1127 Pos - The 'Position' field of a Pointer
1135 if ((mOutputMask
>>= 1) == 0) {
1136 mOutputMask
= 1U << (UINT8_BIT
- 1);
1138 // Check the buffer overflow per outputing UINT8_BIT symbols
1139 // which is an Original Character or a Pointer. The biggest
1140 // symbol is a Pointer which occupies 5 bytes.
1142 if (mOutputPos
>= mBufSiz
- 5 * UINT8_BIT
) {
1147 CPos
= mOutputPos
++;
1151 mBuf
[mOutputPos
++] = (UINT8
) CharC
;
1153 if (CharC
>= (1U << UINT8_BIT
)) {
1154 mBuf
[CPos
] |= mOutputMask
;
1155 mBuf
[mOutputPos
++] = (UINT8
) (Pos
>> 24);
1156 mBuf
[mOutputPos
++] = (UINT8
) (Pos
>> 16);
1157 mBuf
[mOutputPos
++] = (UINT8
) (Pos
>> (UINT8_BIT
));
1158 mBuf
[mOutputPos
++] = (UINT8
) Pos
;
1177 for (Index
= 0; Index
< NC
; Index
++) {
1181 for (Index
= 0; Index
< NP
; Index
++) {
1185 mOutputPos
= mOutputMask
= 0;
1199 // Flush remaining bits
1201 PutBits (UINT8_BIT
- 1, 0);
1216 for (Index
= 0; Index
<= UINT8_MAX
; Index
++) {
1218 for (Index2
= 0; Index2
< UINT8_BIT
; Index2
++) {
1220 Temp
= (Temp
>> 1) ^ CRCPOLY
;
1226 mCrcTable
[Index
] = (UINT16
) Temp
;
1238 Routine Description:
1240 Outputs rightmost n bits of x
1244 Number - the rightmost n bits of the data is used
1253 while (Number
>= mBitCount
) {
1255 // Number -= mBitCount should never equal to 32
1257 Temp
= (UINT8
) (mSubBitBuf
| (Value
>> (Number
-= mBitCount
)));
1259 if (mDst
< mDstUpperLimit
) {
1265 mBitCount
= UINT8_BIT
;
1268 mSubBitBuf
|= Value
<< (mBitCount
-= Number
);
1279 Routine Description:
1285 Pointer - the buffer to hold the data
1286 Number - number of bytes to read
1290 number of bytes actually read
1296 for (Index
= 0; mSrc
< mSrcUpperLimit
&& Index
< Number
; Index
++) {
1297 *Pointer
++ = *mSrc
++;
1303 mOrigSize
+= Number
;
1306 while (Index
>= 0) {
1307 UPDATE_CRC (*Pointer
++);
1320 mBitCount
= UINT8_BIT
;
1331 Routine Description:
1333 Count the number of each code length for a Huffman tree.
1337 Index - the top node
1343 STATIC INT32 Depth
= 0;
1346 mLenCnt
[(Depth
< 16) ? Depth
: 16]++;
1349 CountLen (mLeft
[Index
]);
1350 CountLen (mRight
[Index
]);
1362 Routine Description:
1364 Create code length array for a Huffman tree
1368 Root - the root of the tree
1380 for (Index
= 0; Index
<= 16; Index
++) {
1387 // Adjust the length count array so that
1388 // no code will be generated longer than its designated length
1391 for (Index
= 16; Index
> 0; Index
--) {
1392 Cum
+= mLenCnt
[Index
] << (16 - Index
);
1395 while (Cum
!= (1U << 16)) {
1397 for (Index
= 15; Index
> 0; Index
--) {
1398 if (mLenCnt
[Index
] != 0) {
1400 mLenCnt
[Index
+ 1] += 2;
1408 for (Index
= 16; Index
> 0; Index
--) {
1409 Index3
= mLenCnt
[Index
];
1411 while (Index3
>= 0) {
1412 mLen
[*mSortPtr
++] = (UINT8
) Index
;
1428 // priority queue: send Index-th entry down heap
1430 Index3
= mHeap
[Index
];
1432 while (Index2
<= mHeapSize
) {
1433 if (Index2
< mHeapSize
&& mFreq
[mHeap
[Index2
]] > mFreq
[mHeap
[Index2
+ 1]]) {
1437 if (mFreq
[Index3
] <= mFreq
[mHeap
[Index2
]]) {
1441 mHeap
[Index
] = mHeap
[Index2
];
1446 mHeap
[Index
] = (INT16
) Index3
;
1458 Routine Description:
1460 Assign code to each symbol based on the code length array
1464 Number - number of symbols
1465 Len - the code length array
1466 Code - stores codes for each symbol
1476 for (Index
= 1; Index
<= 16; Index
++) {
1477 Start
[Index
+ 1] = (UINT16
) ((Start
[Index
] + mLenCnt
[Index
]) << 1);
1480 for (Index
= 0; Index
< Number
; Index
++) {
1481 Code
[Index
] = Start
[Len
[Index
]]++;
1489 IN UINT16 FreqParm
[],
1490 OUT UINT8 LenParm
[ ],
1491 OUT UINT16 CodeParm
[]
1495 Routine Description:
1497 Generates Huffman codes given a frequency distribution of symbols
1501 NParm - number of symbols
1502 FreqParm - frequency of each symbol
1503 LenParm - code length for each symbol
1504 CodeParm - code for each symbol
1508 Root of the Huffman tree.
1518 // make tree, calculate len[], return root
1526 for (Index
= 0; Index
< mN
; Index
++) {
1530 mHeap
[mHeapSize
] = (INT16
) Index
;
1534 if (mHeapSize
< 2) {
1535 CodeParm
[mHeap
[1]] = 0;
1539 for (Index
= mHeapSize
/ 2; Index
>= 1; Index
--) {
1541 // make priority queue
1546 mSortPtr
= CodeParm
;
1550 *mSortPtr
++ = (UINT16
) Index
;
1553 mHeap
[1] = mHeap
[mHeapSize
--];
1557 *mSortPtr
++ = (UINT16
) Index2
;
1561 mFreq
[Index3
] = (UINT16
) (mFreq
[Index
] + mFreq
[Index2
]);
1562 mHeap
[1] = (INT16
) Index3
;
1564 mLeft
[Index3
] = (UINT16
) Index
;
1565 mRight
[Index3
] = (UINT16
) Index2
;
1566 } while (mHeapSize
> 1);
1568 mSortPtr
= CodeParm
;
1570 MakeCode (NParm
, LenParm
, CodeParm
);
1580 IN
char *InputFileName
,
1581 OUT UINT8
*FileBuffer
,
1582 OUT UINT32
*BufferLength
1586 Routine Description:
1588 Get the contents of file specified in InputFileName
1593 InputFileName - Name of the input file.
1595 FileBuffer - Output buffer to contain data
1597 BufferLength - Actual length of the data
1601 EFI_SUCCESS on successful return
1602 EFI_ABORTED if unable to open input file.
1612 // Copy the file contents to the output buffer.
1614 InputFile
= fopen (LongFilePath (InputFileName
), "rb");
1615 if (InputFile
== NULL
) {
1616 Error (NULL
, 0, 0001, "Error opening file: %s", InputFileName
);
1620 fseek (InputFile
, 0, SEEK_END
);
1621 FileSize
= ftell (InputFile
);
1622 fseek (InputFile
, 0, SEEK_SET
);
1624 // Now read the contents of the file into the buffer
1626 if (FileSize
> 0 && FileBuffer
!= NULL
) {
1627 if (fread (FileBuffer
, FileSize
, 1, InputFile
) != 1) {
1628 Error (NULL
, 0, 0004, "Error reading contents of input file: %s", InputFileName
);
1635 Size
+= (UINTN
) FileSize
;
1636 *BufferLength
= Size
;
1638 if (FileBuffer
!= NULL
) {
1641 return EFI_BUFFER_TOO_SMALL
;
1651 Routine Description:
1653 Displays the standard utility information to SDTOUT
1665 fprintf (stdout
, "%s Version %d.%d %s \n", UTILITY_NAME
, UTILITY_MAJOR_VERSION
, UTILITY_MINOR_VERSION
, __BUILD_VERSION
);
1674 Routine Description:
1676 Displays the utility usage syntax to STDOUT
1691 fprintf (stdout
, "Usage: %s -e|-d [options] <input_file>\n\n", UTILITY_NAME
);
1694 // Copyright declaration
1696 fprintf (stdout
, "Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.\n\n");
1701 fprintf (stdout
, "Options:\n");
1702 fprintf (stdout
, " --uefi\n\
1703 Enable UefiCompress, use TianoCompress when without this option\n");
1704 fprintf (stdout
, " -o FileName, --output FileName\n\
1705 File will be created to store the output content.\n");
1706 fprintf (stdout
, " -v, --verbose\n\
1707 Turn on verbose output with informational messages.\n");
1708 fprintf (stdout
, " -q, --quiet\n\
1709 Disable all messages except key message and fatal error\n");
1710 fprintf (stdout
, " --debug [0-9]\n\
1711 Enable debug messages, at input debug level.\n");
1712 fprintf (stdout
, " --version\n\
1713 Show program's version number and exit.\n");
1714 fprintf (stdout
, " -h, --help\n\
1715 Show this help message and exit.\n");
1726 Routine Description:
1732 command line parameters
1736 EFI_SUCCESS Section header successfully generated and section concatenated.
1737 EFI_ABORTED Could not generate the section
1738 EFI_OUT_OF_RESOURCES No resource to complete the operation.
1743 char *OutputFileName
;
1744 char *InputFileName
;
1751 SCRATCH_DATA
*Scratch
;
1756 SetUtilityName(UTILITY_NAME
);
1765 InputFileName
= NULL
;
1766 OutputFileName
= NULL
;
1774 // Verify the correct number of arguments
1777 Error (NULL
, 0, 1001, "Missing options", "No input options specified.");
1782 if ((strcmp(argv
[1], "-h") == 0) || (strcmp(argv
[1], "--help") == 0)) {
1787 if ((strcmp(argv
[1], "--version") == 0)) {
1794 if (strcmp(argv
[0],"-e") == 0) {
1796 // encode the input file
1801 } else if (strcmp(argv
[0], "-d") == 0) {
1803 // decode the input file
1810 // Error command line
1812 Error (NULL
, 0, 1003, "Invalid option value", "the options specified are not recognized.");
1818 if ((strcmp(argv
[0], "-v") == 0) || (stricmp(argv
[0], "--verbose") == 0)) {
1825 if (stricmp(argv
[0], "--uefi") == 0) {
1832 if (stricmp (argv
[0], "--debug") == 0) {
1835 Status
= AsciiStringToUint64(argv
[0], FALSE
, &DebugLevel
);
1836 if (DebugLevel
> 9) {
1837 Error (NULL
, 0 ,2000, "Invalid parameter", "Unrecognized argument %s", argv
[0]);
1840 if (DebugLevel
>=5 && DebugLevel
<=9){
1849 if ((strcmp(argv
[0], "-q") == 0) || (stricmp (argv
[0], "--quiet") == 0)) {
1856 if ((strcmp(argv
[0], "-o") == 0) || (stricmp (argv
[0], "--output") == 0)) {
1857 if (argv
[1] == NULL
|| argv
[1][0] == '-') {
1858 Error (NULL
, 0, 1003, "Invalid option value", "Output File name is missing for -o option");
1861 OutputFileName
= argv
[1];
1867 if (argv
[0][0]!='-') {
1868 InputFileName
= argv
[0];
1874 Error (NULL
, 0, 1000, "Unknown option", argv
[0]);
1878 if (InputFileName
== NULL
) {
1879 Error (NULL
, 0, 1001, "Missing options", "No input files specified.");
1884 // All Parameters has been parsed, now set the message print level
1888 } else if (VerboseMode
) {
1890 } else if (DebugMode
) {
1891 SetPrintLevel(DebugLevel
);
1895 VerboseMsg("%s tool start.\n", UTILITY_NAME
);
1897 Scratch
= (SCRATCH_DATA
*)malloc(sizeof(SCRATCH_DATA
));
1898 if (Scratch
== NULL
) {
1899 Error (NULL
, 0, 4001, "Resource:", "Memory cannot be allocated!");
1903 InputFile
= fopen (LongFilePath (InputFileName
), "rb");
1904 if (InputFile
== NULL
) {
1905 Error (NULL
, 0, 0001, "Error opening input file", InputFileName
);
1909 Status
= GetFileContents(
1914 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1915 FileBuffer
= (UINT8
*) malloc (InputLength
);
1916 if (FileBuffer
== NULL
) {
1917 Error (NULL
, 0, 4001, "Resource:", "Memory cannot be allocated!");
1921 Status
= GetFileContents (
1928 if (EFI_ERROR(Status
)) {
1929 Error (NULL
, 0, 0004, "Error getting contents of file: %s", InputFileName
);
1933 if (OutputFileName
== NULL
) {
1934 OutputFileName
= DEFAULT_OUTPUT_FILE
;
1936 OutputFile
= fopen (LongFilePath (OutputFileName
), "wb");
1937 if (OutputFile
== NULL
) {
1938 Error (NULL
, 0, 0001, "Error opening output file for writing", OutputFileName
);
1944 // First call TianoCompress to get DstSize
1947 DebugMsg(UTILITY_NAME
, 0, DebugLevel
, "Encoding", NULL
);
1950 Status
= EfiCompress ((UINT8
*)FileBuffer
, InputLength
, OutBuffer
, &DstSize
);
1952 Status
= TianoCompress ((UINT8
*)FileBuffer
, InputLength
, OutBuffer
, &DstSize
);
1955 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1956 OutBuffer
= (UINT8
*) malloc (DstSize
);
1957 if (OutBuffer
== NULL
) {
1958 Error (NULL
, 0, 4001, "Resource:", "Memory cannot be allocated!");
1964 Status
= EfiCompress ((UINT8
*)FileBuffer
, InputLength
, OutBuffer
, &DstSize
);
1966 Status
= TianoCompress ((UINT8
*)FileBuffer
, InputLength
, OutBuffer
, &DstSize
);
1968 if (Status
!= EFI_SUCCESS
) {
1969 Error (NULL
, 0, 0007, "Error compressing file", NULL
);
1973 if (OutBuffer
== NULL
) {
1974 Error (NULL
, 0, 4001, "Resource:", "Memory cannot be allocated!");
1978 fwrite(OutBuffer
,(size_t)DstSize
, 1, OutputFile
);
1986 DebugMsg(UTILITY_NAME
, 0, DebugLevel
, "Encoding Successful!\n", NULL
);
1989 VerboseMsg("Encoding successful\n");
1995 DebugMsg(UTILITY_NAME
, 0, DebugLevel
, "Decoding\n", NULL
);
1999 Status
= Extract((VOID
*)FileBuffer
, InputLength
, (VOID
*)&OutBuffer
, &DstSize
, 1);
2000 if (Status
!= EFI_SUCCESS
) {
2003 fwrite(OutBuffer
, (size_t)(DstSize
), 1, OutputFile
);
2005 if (InputLength
< 8){
2006 Error (NULL
, 0, 3000, "Invalid", "The input file %s is too small.", InputFileName
);
2010 // Get Compressed file original size
2012 Src
= (UINT8
*)FileBuffer
;
2013 OrigSize
= Src
[4] + (Src
[5] << 8) + (Src
[6] << 16) + (Src
[7] << 24);
2014 CompSize
= Src
[0] + (Src
[1] << 8) + (Src
[2] <<16) + (Src
[3] <<24);
2017 // Allocate OutputBuffer
2019 if (InputLength
< CompSize
+ 8 || (CompSize
+ 8) < 8) {
2020 Error (NULL
, 0, 3000, "Invalid", "The input file %s data is invalid.", InputFileName
);
2023 OutBuffer
= (UINT8
*)malloc(OrigSize
);
2024 if (OutBuffer
== NULL
) {
2025 Error (NULL
, 0, 4001, "Resource:", "Memory cannot be allocated!");
2029 Status
= TDecompress((VOID
*)FileBuffer
, (VOID
*)OutBuffer
, (VOID
*)Scratch
, 2);
2030 if (Status
!= EFI_SUCCESS
) {
2033 fwrite(OutBuffer
, (size_t)(Scratch
->mOrigSize
), 1, OutputFile
);
2037 if (Scratch
!= NULL
) {
2040 if (FileBuffer
!= NULL
) {
2043 if (OutBuffer
!= NULL
) {
2048 DebugMsg(UTILITY_NAME
, 0, DebugLevel
, "Encoding successful!\n", NULL
);
2052 VerboseMsg("Decoding successful\n");
2060 DebugMsg(UTILITY_NAME
, 0, DebugLevel
, "Encoding Error\n", NULL
);
2061 } else if (DECODE
) {
2062 DebugMsg(UTILITY_NAME
, 0, DebugLevel
, "Decoding Error\n", NULL
);
2065 if (OutputFile
!= NULL
) {
2068 if (InputFile
!= NULL
) {
2071 if (Scratch
!= NULL
) {
2074 if (FileBuffer
!= NULL
) {
2077 if (OutBuffer
!= NULL
) {
2082 VerboseMsg("%s tool done with return code is 0x%x.\n", UTILITY_NAME
, GetUtilityStatus ());
2084 return GetUtilityStatus ();
2089 IN SCRATCH_DATA
*Sd
,
2094 Routine Description:
2096 Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source.
2100 Sd - The global scratch data
2101 NumOfBits - The number of bits to shift and read.
2107 Sd
->mBitBuf
= (UINT32
) (((UINT64
)Sd
->mBitBuf
) << NumOfBits
);
2109 while (NumOfBits
> Sd
->mBitCount
) {
2111 Sd
->mBitBuf
|= (UINT32
) (((UINT64
)Sd
->mSubBitBuf
) << (NumOfBits
= (UINT16
) (NumOfBits
- Sd
->mBitCount
)));
2113 if (Sd
->mCompSize
> 0) {
2115 // Get 1 byte into SubBitBuf
2119 Sd
->mSubBitBuf
= Sd
->mSrcBase
[Sd
->mInBuf
++];
2124 // No more bits from the source, just pad zero bit.
2132 Sd
->mBitCount
= (UINT16
) (Sd
->mBitCount
- NumOfBits
);
2133 Sd
->mBitBuf
|= Sd
->mSubBitBuf
>> Sd
->mBitCount
;
2138 IN SCRATCH_DATA
*Sd
,
2143 Routine Description:
2145 Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent
2146 NumOfBits of bits from source. Returns NumOfBits of bits that are
2151 Sd - The global scratch data.
2152 NumOfBits - The number of bits to pop and read.
2156 The bits that are popped out.
2162 OutBits
= (UINT32
) (Sd
->mBitBuf
>> (BITBUFSIZ
- NumOfBits
));
2164 FillBuf (Sd
, NumOfBits
);
2171 IN SCRATCH_DATA
*Sd
,
2172 IN UINT16 NumOfChar
,
2174 IN UINT16 TableBits
,
2179 Routine Description:
2181 Creates Huffman Code mapping table according to code length array.
2185 Sd - The global scratch data
2186 NumOfChar - Number of symbols in the symbol set
2187 BitLen - Code length array
2188 TableBits - The width of the mapping table
2194 BAD_TABLE - The table is corrupted.
2212 UINT16 MaxTableLength
;
2214 for (Index
= 0; Index
<= 16; Index
++) {
2218 for (Index
= 0; Index
< NumOfChar
; Index
++) {
2219 if (BitLen
[Index
] > 16) {
2220 return (UINT16
) BAD_TABLE
;
2222 Count
[BitLen
[Index
]]++;
2228 for (Index
= 1; Index
<= 16; Index
++) {
2229 WordOfStart
= Start
[Index
];
2230 WordOfCount
= Count
[Index
];
2231 Start
[Index
+ 1] = (UINT16
) (WordOfStart
+ (WordOfCount
<< (16 - Index
)));
2234 if (Start
[17] != 0) {
2238 return (UINT16
) BAD_TABLE
;
2241 JuBits
= (UINT16
) (16 - TableBits
);
2244 for (Index
= 1; Index
<= TableBits
; Index
++) {
2245 Start
[Index
] >>= JuBits
;
2246 Weight
[Index
] = (UINT16
) (1U << (TableBits
- Index
));
2249 while (Index
<= 16) {
2250 Weight
[Index
] = (UINT16
) (1U << (16 - Index
));
2254 Index
= (UINT16
) (Start
[TableBits
+ 1] >> JuBits
);
2257 Index3
= (UINT16
) (1U << TableBits
);
2258 while (Index
!= Index3
) {
2264 Mask
= (UINT16
) (1U << (15 - TableBits
));
2265 MaxTableLength
= (UINT16
) (1U << TableBits
);
2267 for (Char
= 0; Char
< NumOfChar
; Char
++) {
2270 if (Len
== 0 || Len
>= 17) {
2274 NextCode
= (UINT16
) (Start
[Len
] + Weight
[Len
]);
2276 if (Len
<= TableBits
) {
2278 if (Start
[Len
] >= NextCode
|| NextCode
> MaxTableLength
){
2279 return (UINT16
) BAD_TABLE
;
2282 for (Index
= Start
[Len
]; Index
< NextCode
; Index
++) {
2283 Table
[Index
] = Char
;
2288 Index3
= Start
[Len
];
2289 Pointer
= &Table
[Index3
>> JuBits
];
2290 Index
= (UINT16
) (Len
- TableBits
);
2292 while (Index
!= 0) {
2293 if (*Pointer
== 0) {
2294 Sd
->mRight
[Avail
] = Sd
->mLeft
[Avail
] = 0;
2298 if (Index3
& Mask
) {
2299 Pointer
= &Sd
->mRight
[*Pointer
];
2301 Pointer
= &Sd
->mLeft
[*Pointer
];
2312 Start
[Len
] = NextCode
;
2326 Routine Description:
2328 Decodes a position value.
2332 Sd - the global scratch data
2336 The position value decoded.
2344 Val
= Sd
->mPTTable
[Sd
->mBitBuf
>> (BITBUFSIZ
- 8)];
2347 Mask
= 1U << (BITBUFSIZ
- 1 - 8);
2351 if (Sd
->mBitBuf
& Mask
) {
2352 Val
= Sd
->mRight
[Val
];
2354 Val
= Sd
->mLeft
[Val
];
2358 } while (Val
>= MAXNP
);
2361 // Advance what we have read
2363 FillBuf (Sd
, Sd
->mPTLen
[Val
]);
2367 Pos
= (UINT32
) ((1U << (Val
- 1)) + GetBits (Sd
, (UINT16
) (Val
- 1)));
2375 IN SCRATCH_DATA
*Sd
,
2382 Routine Description:
2384 Reads code lengths for the Extra Set or the Position Set
2388 Sd - The global scratch data
2389 nn - Number of symbols
2390 nbit - Number of bits needed to represent nn
2391 Special - The special symbol that needs to be taken care of
2396 BAD_TABLE - Table is corrupted.
2402 volatile UINT16 Index
;
2407 Number
= (UINT16
) GetBits (Sd
, nbit
);
2410 CharC
= (UINT16
) GetBits (Sd
, nbit
);
2412 for (Index
= 0; Index
< 256; Index
++) {
2413 Sd
->mPTTable
[Index
] = CharC
;
2416 for (Index
= 0; Index
< nn
; Index
++) {
2417 Sd
->mPTLen
[Index
] = 0;
2425 while (Index
< Number
) {
2427 CharC
= (UINT16
) (Sd
->mBitBuf
>> (BITBUFSIZ
- 3));
2430 Mask
= 1U << (BITBUFSIZ
- 1 - 3);
2431 while (Mask
& Sd
->mBitBuf
) {
2437 FillBuf (Sd
, (UINT16
) ((CharC
< 7) ? 3 : CharC
- 3));
2439 Sd
->mPTLen
[Index
++] = (UINT8
) CharC
;
2441 if (Index
== Special
) {
2442 CharC
= (UINT16
) GetBits (Sd
, 2);
2443 while ((INT16
) (--CharC
) >= 0) {
2444 Sd
->mPTLen
[Index
++] = 0;
2449 while (Index
< nn
) {
2450 Sd
->mPTLen
[Index
++] = 0;
2453 return MakeTable (Sd
, nn
, Sd
->mPTLen
, 8, Sd
->mPTTable
);
2462 Routine Description:
2464 Reads code lengths for Char&Len Set.
2468 Sd - the global scratch data
2476 volatile UINT16 Index
;
2479 Number
= (UINT16
) GetBits (Sd
, CBIT
);
2482 CharC
= (UINT16
) GetBits (Sd
, CBIT
);
2484 for (Index
= 0; Index
< NC
; Index
++) {
2485 Sd
->mCLen
[Index
] = 0;
2488 for (Index
= 0; Index
< 4096; Index
++) {
2489 Sd
->mCTable
[Index
] = CharC
;
2496 while (Index
< Number
) {
2498 CharC
= Sd
->mPTTable
[Sd
->mBitBuf
>> (BITBUFSIZ
- 8)];
2500 Mask
= 1U << (BITBUFSIZ
- 1 - 8);
2504 if (Mask
& Sd
->mBitBuf
) {
2505 CharC
= Sd
->mRight
[CharC
];
2507 CharC
= Sd
->mLeft
[CharC
];
2512 } while (CharC
>= NT
);
2515 // Advance what we have read
2517 FillBuf (Sd
, Sd
->mPTLen
[CharC
]);
2523 } else if (CharC
== 1) {
2524 CharC
= (UINT16
) (GetBits (Sd
, 4) + 3);
2525 } else if (CharC
== 2) {
2526 CharC
= (UINT16
) (GetBits (Sd
, CBIT
) + 20);
2529 while ((INT16
) (--CharC
) >= 0) {
2530 Sd
->mCLen
[Index
++] = 0;
2535 Sd
->mCLen
[Index
++] = (UINT8
) (CharC
- 2);
2540 while (Index
< NC
) {
2541 Sd
->mCLen
[Index
++] = 0;
2544 MakeTable (Sd
, NC
, Sd
->mCLen
, 12, Sd
->mCTable
);
2555 Routine Description:
2557 Decode a character/length value.
2561 Sd - The global scratch data.
2572 if (Sd
->mBlockSize
== 0) {
2574 // Starting a new block
2576 Sd
->mBlockSize
= (UINT16
) GetBits (Sd
, 16);
2577 Sd
->mBadTableFlag
= ReadPTLen (Sd
, NT
, TBIT
, 3);
2578 if (Sd
->mBadTableFlag
!= 0) {
2584 Sd
->mBadTableFlag
= ReadPTLen (Sd
, MAXNP
, Sd
->mPBit
, (UINT16
) (-1));
2585 if (Sd
->mBadTableFlag
!= 0) {
2591 Index2
= Sd
->mCTable
[Sd
->mBitBuf
>> (BITBUFSIZ
- 12)];
2594 Mask
= 1U << (BITBUFSIZ
- 1 - 12);
2597 if (Sd
->mBitBuf
& Mask
) {
2598 Index2
= Sd
->mRight
[Index2
];
2600 Index2
= Sd
->mLeft
[Index2
];
2604 } while (Index2
>= NC
);
2607 // Advance what we have read
2609 FillBuf (Sd
, Sd
->mCLen
[Index2
]);
2620 Routine Description:
2622 Decode the source data and put the resulting data into the destination buffer.
2626 Sd - The global scratch data
2636 BytesRemain
= (UINT16
) (-1);
2641 CharC
= DecodeC (Sd
);
2642 if (Sd
->mBadTableFlag
!= 0) {
2648 // Process an Original character
2650 if (Sd
->mOutBuf
>= Sd
->mOrigSize
) {
2653 Sd
->mDstBase
[Sd
->mOutBuf
++] = (UINT8
) CharC
;
2658 // Process a Pointer
2660 CharC
= (UINT16
) (CharC
- (UINT8_MAX
+ 1 - THRESHOLD
));
2662 BytesRemain
= CharC
;
2664 DataIdx
= Sd
->mOutBuf
- DecodeP (Sd
) - 1;
2668 while ((INT16
) (BytesRemain
) >= 0) {
2669 if (Sd
->mOutBuf
>= Sd
->mOrigSize
) {
2672 if (DataIdx
>= Sd
->mOrigSize
) {
2673 Sd
->mBadTableFlag
= (UINT16
) BAD_TABLE
;
2676 Sd
->mDstBase
[Sd
->mOutBuf
++] = Sd
->mDstBase
[DataIdx
++];
2681 // Once mOutBuf is fully filled, directly return
2683 if (Sd
->mOutBuf
>= Sd
->mOrigSize
) {
2697 IN OUT VOID
*Destination
,
2698 IN OUT VOID
*Scratch
,
2703 Routine Description:
2705 The internal implementation of Decompress().
2709 Source - The source buffer containing the compressed data.
2710 Destination - The destination buffer to store the decompressed data
2711 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
2712 Version - 1 for EFI1.1 Decompress algorithm, 2 for Tiano Decompress algorithm
2716 RETURN_SUCCESS - Decompression is successful
2717 RETURN_INVALID_PARAMETER - The source data is corrupted
2721 volatile UINT32 Index
;
2729 // Verify input is not NULL
2732 // assert(Destination);
2735 Src
= (UINT8
*)Source
;
2736 Dst
= (UINT8
*)Destination
;
2738 Sd
= (SCRATCH_DATA
*) Scratch
;
2739 CompSize
= Src
[0] + (Src
[1] << 8) + (Src
[2] << 16) + (Src
[3] << 24);
2740 OrigSize
= Src
[4] + (Src
[5] << 8) + (Src
[6] << 16) + (Src
[7] << 24);
2743 // If compressed file size is 0, return
2745 if (OrigSize
== 0) {
2746 return RETURN_SUCCESS
;
2751 for (Index
= 0; Index
< sizeof (SCRATCH_DATA
); Index
++) {
2752 ((UINT8
*) Sd
)[Index
] = 0;
2755 // The length of the field 'Position Set Code Length Array Size' in Block Header.
2756 // For EFI 1.1 de/compression algorithm(Version 1), mPBit = 4
2757 // For Tiano de/compression algorithm(Version 2), mPBit = 5
2769 Sd
->mSrcBase
= (UINT8
*)Src
;
2771 Sd
->mCompSize
= CompSize
;
2772 Sd
->mOrigSize
= OrigSize
;
2775 // Fill the first BITBUFSIZ bits
2777 FillBuf (Sd
, BITBUFSIZ
);
2785 if (Sd
->mBadTableFlag
!= 0) {
2787 // Something wrong with the source
2789 return RETURN_INVALID_PARAMETER
;
2792 return RETURN_SUCCESS
;