]>
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 This program and the accompanying materials
10 are licensed and made available under the terms and conditions of the BSD License
11 which accompanies this distribution. The full text of the license may be found at
12 http://opensource.org/licenses/bsd-license.php
14 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
15 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
20 #include "Decompress.h"
21 #include "TianoCompress.h"
22 #include "EfiUtilityMsgs.h"
30 static BOOLEAN VerboseMode
= FALSE
;
31 static BOOLEAN QuietMode
= FALSE
;
33 #define UINT8_MAX 0xff
38 #define WNDSIZ (1U << WNDBIT)
40 #define BLKSIZ (1U << 14) // 16 * 1024U
41 #define PERC_FLAG 0x80000000U
44 #define MAX_HASH_VAL (3 * WNDSIZ + (WNDSIZ / 512 + 1) * UINT8_MAX)
45 #define HASH(p, c) ((p) + ((c) << (WNDBIT - 9)) + WNDSIZ * 2)
46 #define CRCPOLY 0xA001
47 #define UPDATE_CRC(c) mCrc = mCrcTable[(mCrc ^ (c)) & 0xFF] ^ (mCrc >> UINT8_BIT)
50 // C: the Char&Len Set; P: the Position Set; T: the exTra Set
52 //#define NC (UINT8_MAX + MAXMATCH + 2 - THRESHOLD)
54 #define NP (WNDBIT + 1)
56 //#define NT (CODE_BIT + 3)
67 STATIC BOOLEAN ENCODE
= FALSE
;
68 STATIC BOOLEAN DECODE
= FALSE
;
69 STATIC BOOLEAN UEFIMODE
= FALSE
;
70 STATIC UINT8
*mSrc
, *mDst
, *mSrcUpperLimit
, *mDstUpperLimit
;
71 STATIC UINT8
*mLevel
, *mText
, *mChildCount
, *mBuf
, mCLen
[NC
], mPTLen
[NPT
], *mLen
;
72 STATIC INT16 mHeap
[NC
+ 1];
73 STATIC INT32 mRemainder
, mMatchLen
, mBitCount
, mHeapSize
, mN
;
74 STATIC UINT32 mBufSiz
= 0, mOutputPos
, mOutputMask
, mSubBitBuf
, mCrc
;
75 STATIC UINT32 mCompSize
, mOrigSize
;
77 STATIC UINT16
*mFreq
, *mSortPtr
, mLenCnt
[17], mLeft
[2 * NC
- 1], mRight
[2 * NC
- 1], mCrcTable
[UINT8_MAX
+ 1],
78 mCFreq
[2 * NC
- 1], mCCode
[NC
], mPFreq
[2 * NP
- 1], mPTCode
[NPT
], mTFreq
[2 * NT
- 1];
80 STATIC NODE mPos
, mMatchPos
, mAvail
, *mPosition
, *mParent
, *mPrev
, *mNext
= NULL
;
82 static UINT64 DebugLevel
;
83 static BOOLEAN DebugMode
;
92 IN OUT UINT32
*DstSize
98 The internal implementation of [Efi/Tiano]Compress().
102 SrcBuffer - The buffer storing the source data
103 SrcSize - The size of source data
104 DstBuffer - The buffer to store the compressed data
106 Version - The version of de/compression algorithm.
107 Version 1 for EFI 1.1 de/compression algorithm.
108 Version 2 for Tiano de/compression algorithm.
112 EFI_BUFFER_TOO_SMALL - The DstBuffer is too small. In this case,
113 DstSize contains the size needed.
114 EFI_SUCCESS - Compression is successful.
115 EFI_OUT_OF_RESOURCES - No resource to complete function.
116 EFI_INVALID_PARAMETER - Parameter supplied is wrong.
137 mSrcUpperLimit
= mSrc
+ SrcSize
;
139 mDstUpperLimit
= mDst
+*DstSize
;
146 mOrigSize
= mCompSize
= 0;
153 if (EFI_ERROR (Status
)) {
154 return EFI_OUT_OF_RESOURCES
;
158 // Null terminate the compressed data
161 if (mDst
< mDstUpperLimit
) {
166 // Fill in compressed size and original size
170 PutDword (mCompSize
+ 1);
171 PutDword (mOrigSize
);
176 if (mCompSize
+ 1 + 8 > *DstSize
) {
177 *DstSize
= mCompSize
+ 1 + 8;
178 return EFI_BUFFER_TOO_SMALL
;
180 *DstSize
= mCompSize
+ 1 + 8;
194 Put a dword to output stream
198 Data - the dword to put
204 if (mDst
< mDstUpperLimit
) {
205 *mDst
++ = (UINT8
) (((UINT8
) (Data
)) & 0xff);
208 if (mDst
< mDstUpperLimit
) {
209 *mDst
++ = (UINT8
) (((UINT8
) (Data
>> 0x08)) & 0xff);
212 if (mDst
< mDstUpperLimit
) {
213 *mDst
++ = (UINT8
) (((UINT8
) (Data
>> 0x10)) & 0xff);
216 if (mDst
< mDstUpperLimit
) {
217 *mDst
++ = (UINT8
) (((UINT8
) (Data
>> 0x18)) & 0xff);
230 Allocate memory spaces for data structures used in compression process
237 EFI_SUCCESS - Memory is allocated successfully
238 EFI_OUT_OF_RESOURCES - Allocation fails
244 mText
= malloc (WNDSIZ
* 2 + MAXMATCH
);
246 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
247 return EFI_OUT_OF_RESOURCES
;
249 for (Index
= 0; Index
< WNDSIZ
* 2 + MAXMATCH
; Index
++) {
253 mLevel
= malloc ((WNDSIZ
+ UINT8_MAX
+ 1) * sizeof (*mLevel
));
254 mChildCount
= malloc ((WNDSIZ
+ UINT8_MAX
+ 1) * sizeof (*mChildCount
));
255 mPosition
= malloc ((WNDSIZ
+ UINT8_MAX
+ 1) * sizeof (*mPosition
));
256 mParent
= malloc (WNDSIZ
* 2 * sizeof (*mParent
));
257 mPrev
= malloc (WNDSIZ
* 2 * sizeof (*mPrev
));
258 mNext
= malloc ((MAX_HASH_VAL
+ 1) * sizeof (*mNext
));
259 if (mLevel
== NULL
|| mChildCount
== NULL
|| mPosition
== NULL
||
260 mParent
== NULL
|| mPrev
== NULL
|| mNext
== NULL
) {
261 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
262 return EFI_OUT_OF_RESOURCES
;
266 mBuf
= malloc (mBufSiz
);
267 while (mBuf
== NULL
) {
268 mBufSiz
= (mBufSiz
/ 10U) * 9U;
269 if (mBufSiz
< 4 * 1024U) {
270 return EFI_OUT_OF_RESOURCES
;
273 mBuf
= malloc (mBufSiz
);
289 Called when compression is completed to free memory previously allocated.
301 if (mLevel
!= NULL
) {
305 if (mChildCount
!= NULL
) {
309 if (mPosition
!= NULL
) {
313 if (mParent
!= NULL
) {
341 Initialize String Info Log data structures
351 for (Index
= WNDSIZ
; Index
<= WNDSIZ
+ UINT8_MAX
; Index
++) {
353 mPosition
[Index
] = NIL
; // sentinel
356 for (Index
= WNDSIZ
; Index
< WNDSIZ
* 2; Index
++) {
357 mParent
[Index
] = NIL
;
361 for (Index
= 1; Index
< WNDSIZ
- 1; Index
++) {
362 mNext
[Index
] = (NODE
) (Index
+ 1);
365 mNext
[WNDSIZ
- 1] = NIL
;
366 for (Index
= WNDSIZ
* 2; Index
<= MAX_HASH_VAL
; Index
++) {
381 Find child node given the parent node and the edge character
385 NodeQ - the parent node
386 CharC - the edge character
390 The child node (NIL if not found)
396 NodeR
= mNext
[HASH (NodeQ
, CharC
)];
400 mParent
[NIL
] = NodeQ
;
401 while (mParent
[NodeR
] != NodeQ
) {
402 NodeR
= mNext
[NodeR
];
419 Create a new child for a given parent node.
423 Parent - the parent node
424 CharC - the edge character
425 Child - the child node
434 Node1
= (NODE
) HASH (Parent
, CharC
);
435 Node2
= mNext
[Node1
];
436 mNext
[Node1
] = Child
;
437 mNext
[Child
] = Node2
;
438 mPrev
[Node2
] = Child
;
439 mPrev
[Child
] = Node1
;
440 mParent
[Child
] = Parent
;
441 mChildCount
[Parent
]++;
457 Old - the node to split
468 mChildCount
[New
] = 0;
469 TempNode
= mPrev
[Old
];
470 mPrev
[New
] = TempNode
;
471 mNext
[TempNode
] = New
;
472 TempNode
= mNext
[Old
];
473 mNext
[New
] = TempNode
;
474 mPrev
[TempNode
] = New
;
475 mParent
[New
] = mParent
[Old
];
476 mLevel
[New
] = (UINT8
) mMatchLen
;
477 mPosition
[New
] = mPos
;
478 MakeChild (New
, mText
[mMatchPos
+ mMatchLen
], Old
);
479 MakeChild (New
, mText
[mPos
+ mMatchLen
], mPos
);
491 Insert string info for current position into the String Info Log
507 if (mMatchLen
>= 4) {
509 // We have just got a long match, the target tree
510 // can be located by MatchPos + 1. Traverse the tree
511 // from bottom up to get to a proper starting point.
512 // The usage of PERC_FLAG ensures proper node deletion
513 // in DeleteNode() later.
516 NodeR
= (NODE
) ((mMatchPos
+ 1) | WNDSIZ
);
517 NodeQ
= mParent
[NodeR
];
518 while (NodeQ
== NIL
) {
519 NodeR
= mNext
[NodeR
];
520 NodeQ
= mParent
[NodeR
];
523 while (mLevel
[NodeQ
] >= mMatchLen
) {
525 NodeQ
= mParent
[NodeQ
];
529 while (mPosition
[NodeT
] < 0) {
530 mPosition
[NodeT
] = mPos
;
531 NodeT
= mParent
[NodeT
];
534 if (NodeT
< WNDSIZ
) {
535 mPosition
[NodeT
] = (NODE
) (mPos
| (UINT32
) PERC_FLAG
);
539 // Locate the target tree
541 NodeQ
= (NODE
) (mText
[mPos
] + WNDSIZ
);
542 CharC
= mText
[mPos
+ 1];
543 NodeR
= Child (NodeQ
, CharC
);
545 MakeChild (NodeQ
, CharC
, mPos
);
553 // Traverse down the tree to find a match.
554 // Update Position value along the route.
555 // Node split or creation is involved.
558 if (NodeR
>= WNDSIZ
) {
562 Index2
= mLevel
[NodeR
];
563 mMatchPos
= (NODE
) (mPosition
[NodeR
] & (UINT32
)~PERC_FLAG
);
566 if (mMatchPos
>= mPos
) {
570 t1
= &mText
[mPos
+ mMatchLen
];
571 t2
= &mText
[mMatchPos
+ mMatchLen
];
572 while (mMatchLen
< Index2
) {
583 if (mMatchLen
>= MAXMATCH
) {
587 mPosition
[NodeR
] = mPos
;
589 NodeR
= Child (NodeQ
, *t1
);
591 MakeChild (NodeQ
, *t1
, mPos
);
598 NodeT
= mPrev
[NodeR
];
601 NodeT
= mNext
[NodeR
];
604 mParent
[mPos
] = NodeQ
;
605 mParent
[NodeR
] = NIL
;
608 // Special usage of 'next'
623 Delete outdated string info. (The Usage of PERC_FLAG
624 ensures a clean deletion)
638 if (mParent
[mPos
] == NIL
) {
644 mNext
[NodeR
] = NodeS
;
645 mPrev
[NodeS
] = NodeR
;
646 NodeR
= mParent
[mPos
];
648 if (NodeR
>= WNDSIZ
) {
652 mChildCount
[NodeR
]--;
653 if (mChildCount
[NodeR
] > 1) {
657 NodeT
= (NODE
) (mPosition
[NodeR
] & (UINT32
)~PERC_FLAG
);
663 NodeQ
= mParent
[NodeR
];
664 NodeU
= mPosition
[NodeQ
];
665 while (NodeU
& (UINT32
) PERC_FLAG
) {
666 NodeU
&= (UINT32
)~PERC_FLAG
;
675 mPosition
[NodeQ
] = (NODE
) (NodeS
| WNDSIZ
);
676 NodeQ
= mParent
[NodeQ
];
677 NodeU
= mPosition
[NodeQ
];
680 if (NodeQ
< WNDSIZ
) {
689 mPosition
[NodeQ
] = (NODE
) (NodeS
| WNDSIZ
| (UINT32
) PERC_FLAG
);
692 NodeS
= Child (NodeR
, mText
[NodeT
+ mLevel
[NodeR
]]);
693 NodeT
= mPrev
[NodeS
];
694 NodeU
= mNext
[NodeS
];
695 mNext
[NodeT
] = NodeU
;
696 mPrev
[NodeU
] = NodeT
;
697 NodeT
= mPrev
[NodeR
];
698 mNext
[NodeT
] = NodeS
;
699 mPrev
[NodeS
] = NodeT
;
700 NodeT
= mNext
[NodeR
];
701 mPrev
[NodeT
] = NodeS
;
702 mNext
[NodeS
] = NodeT
;
703 mParent
[NodeS
] = mParent
[NodeR
];
704 mParent
[NodeR
] = NIL
;
705 mNext
[NodeR
] = mAvail
;
718 Advance the current position (read in new data if needed).
719 Delete outdated string info. Find a match string for current position.
731 if (mPos
== WNDSIZ
* 2) {
732 memmove (&mText
[0], &mText
[WNDSIZ
], WNDSIZ
+ MAXMATCH
);
733 Number
= FreadCrc (&mText
[WNDSIZ
+ MAXMATCH
], WNDSIZ
);
734 mRemainder
+= Number
;
751 The main controlling routine for compression process.
757 EFI_SUCCESS - The compression is successful
758 EFI_OUT_0F_RESOURCES - Not enough memory for compression process
766 Status
= AllocateMemory ();
767 if (EFI_ERROR (Status
)) {
776 mRemainder
= FreadCrc (&mText
[WNDSIZ
], WNDSIZ
+ MAXMATCH
);
781 if (mMatchLen
> mRemainder
) {
782 mMatchLen
= mRemainder
;
785 while (mRemainder
> 0) {
786 LastMatchLen
= mMatchLen
;
787 LastMatchPos
= mMatchPos
;
789 if (mMatchLen
> mRemainder
) {
790 mMatchLen
= mRemainder
;
793 if (mMatchLen
> LastMatchLen
|| LastMatchLen
< THRESHOLD
) {
795 // Not enough benefits are gained by outputting a pointer,
796 // so just output the original character
798 Output (mText
[mPos
- 1], 0);
802 if (LastMatchLen
== THRESHOLD
) {
803 if (((mPos
- LastMatchPos
- 2) & (WNDSIZ
- 1)) > (1U << 11)) {
804 Output (mText
[mPos
- 1], 0);
809 // Outputting a pointer is beneficial enough, do it.
812 LastMatchLen
+ (UINT8_MAX
+ 1 - THRESHOLD
),
813 (mPos
- LastMatchPos
- 2) & (WNDSIZ
- 1)
816 while (LastMatchLen
> 0) {
821 if (mMatchLen
> mRemainder
) {
822 mMatchLen
= mRemainder
;
841 Count the frequencies for the Extra Set
854 for (Index
= 0; Index
< NT
; Index
++) {
859 while (Number
> 0 && mCLen
[Number
- 1] == 0) {
864 while (Index
< Number
) {
865 Index3
= mCLen
[Index
++];
868 while (Index
< Number
&& mCLen
[Index
] == 0) {
874 mTFreq
[0] = (UINT16
) (mTFreq
[0] + Count
);
875 } else if (Count
<= 18) {
877 } else if (Count
== 19) {
884 mTFreq
[Index3
+ 2]++;
900 Outputs the code length array for the Extra Set or the Position Set.
904 Number - the number of symbols
905 nbit - the number of bits needed to represent 'n'
906 Special - the special symbol that needs to be take care of
915 while (Number
> 0 && mPTLen
[Number
- 1] == 0) {
919 PutBits (nbit
, Number
);
921 while (Index
< Number
) {
922 Index3
= mPTLen
[Index
++];
926 PutBits (Index3
- 3, (1U << (Index3
- 3)) - 2);
929 if (Index
== Special
) {
930 while (Index
< 6 && mPTLen
[Index
] == 0) {
934 PutBits (2, (Index
- 3) & 3);
948 Outputs the code length array for Char&Length Set
962 while (Number
> 0 && mCLen
[Number
- 1] == 0) {
966 PutBits (CBIT
, Number
);
968 while (Index
< Number
) {
969 Index3
= mCLen
[Index
++];
972 while (Index
< Number
&& mCLen
[Index
] == 0) {
978 for (Index3
= 0; Index3
< Count
; Index3
++) {
979 PutBits (mPTLen
[0], mPTCode
[0]);
981 } else if (Count
<= 18) {
982 PutBits (mPTLen
[1], mPTCode
[1]);
983 PutBits (4, Count
- 3);
984 } else if (Count
== 19) {
985 PutBits (mPTLen
[0], mPTCode
[0]);
986 PutBits (mPTLen
[1], mPTCode
[1]);
989 PutBits (mPTLen
[2], mPTCode
[2]);
990 PutBits (CBIT
, Count
- 20);
993 PutBits (mPTLen
[Index3
+ 2], mPTCode
[Index3
+ 2]);
1004 PutBits (mCLen
[Value
], mCCode
[Value
]);
1023 PutBits (mPTLen
[Index
], mPTCode
[Index
]);
1025 PutBits (Index
- 1, Value
& (0xFFFFFFFFU
>> (32 - Index
+ 1)));
1036 Routine Description:
1038 Huffman code the block and output it.
1057 Root
= MakeTree (NC
, mCFreq
, mCLen
, mCCode
);
1058 Size
= mCFreq
[Root
];
1063 Root
= MakeTree (NT
, mTFreq
, mPTLen
, mPTCode
);
1065 WritePTLen (NT
, TBIT
, 3);
1068 PutBits (TBIT
, Root
);
1076 PutBits (CBIT
, Root
);
1079 Root
= MakeTree (NP
, mPFreq
, mPTLen
, mPTCode
);
1081 WritePTLen (NP
, PBIT
, -1);
1084 PutBits (PBIT
, Root
);
1088 for (Index
= 0; Index
< Size
; Index
++) {
1089 if (Index
% UINT8_BIT
== 0) {
1090 Flags
= mBuf
[Pos
++];
1095 if (Flags
& (1U << (UINT8_BIT
- 1))) {
1096 EncodeC (mBuf
[Pos
++] + (1U << UINT8_BIT
));
1097 Index3
= mBuf
[Pos
++];
1098 for (Index2
= 0; Index2
< 3; Index2
++) {
1099 Index3
<<= UINT8_BIT
;
1100 Index3
+= mBuf
[Pos
++];
1105 EncodeC (mBuf
[Pos
++]);
1109 for (Index
= 0; Index
< NC
; Index
++) {
1113 for (Index
= 0; Index
< NP
; Index
++) {
1126 Routine Description:
1128 Outputs an Original Character or a Pointer
1132 CharC - The original character or the 'String Length' element of a Pointer
1133 Pos - The 'Position' field of a Pointer
1141 if ((mOutputMask
>>= 1) == 0) {
1142 mOutputMask
= 1U << (UINT8_BIT
- 1);
1144 // Check the buffer overflow per outputing UINT8_BIT symbols
1145 // which is an Original Character or a Pointer. The biggest
1146 // symbol is a Pointer which occupies 5 bytes.
1148 if (mOutputPos
>= mBufSiz
- 5 * UINT8_BIT
) {
1153 CPos
= mOutputPos
++;
1157 mBuf
[mOutputPos
++] = (UINT8
) CharC
;
1159 if (CharC
>= (1U << UINT8_BIT
)) {
1160 mBuf
[CPos
] |= mOutputMask
;
1161 mBuf
[mOutputPos
++] = (UINT8
) (Pos
>> 24);
1162 mBuf
[mOutputPos
++] = (UINT8
) (Pos
>> 16);
1163 mBuf
[mOutputPos
++] = (UINT8
) (Pos
>> (UINT8_BIT
));
1164 mBuf
[mOutputPos
++] = (UINT8
) Pos
;
1183 for (Index
= 0; Index
< NC
; Index
++) {
1187 for (Index
= 0; Index
< NP
; Index
++) {
1191 mOutputPos
= mOutputMask
= 0;
1205 // Flush remaining bits
1207 PutBits (UINT8_BIT
- 1, 0);
1222 for (Index
= 0; Index
<= UINT8_MAX
; Index
++) {
1224 for (Index2
= 0; Index2
< UINT8_BIT
; Index2
++) {
1226 Temp
= (Temp
>> 1) ^ CRCPOLY
;
1232 mCrcTable
[Index
] = (UINT16
) Temp
;
1244 Routine Description:
1246 Outputs rightmost n bits of x
1250 Number - the rightmost n bits of the data is used
1259 while (Number
>= mBitCount
) {
1261 // Number -= mBitCount should never equal to 32
1263 Temp
= (UINT8
) (mSubBitBuf
| (Value
>> (Number
-= mBitCount
)));
1265 if (mDst
< mDstUpperLimit
) {
1271 mBitCount
= UINT8_BIT
;
1274 mSubBitBuf
|= Value
<< (mBitCount
-= Number
);
1285 Routine Description:
1291 Pointer - the buffer to hold the data
1292 Number - number of bytes to read
1296 number of bytes actually read
1302 for (Index
= 0; mSrc
< mSrcUpperLimit
&& Index
< Number
; Index
++) {
1303 *Pointer
++ = *mSrc
++;
1309 mOrigSize
+= Number
;
1312 while (Index
>= 0) {
1313 UPDATE_CRC (*Pointer
++);
1326 mBitCount
= UINT8_BIT
;
1337 Routine Description:
1339 Count the number of each code length for a Huffman tree.
1343 Index - the top node
1349 STATIC INT32 Depth
= 0;
1352 mLenCnt
[(Depth
< 16) ? Depth
: 16]++;
1355 CountLen (mLeft
[Index
]);
1356 CountLen (mRight
[Index
]);
1368 Routine Description:
1370 Create code length array for a Huffman tree
1374 Root - the root of the tree
1386 for (Index
= 0; Index
<= 16; Index
++) {
1393 // Adjust the length count array so that
1394 // no code will be generated longer than its designated length
1397 for (Index
= 16; Index
> 0; Index
--) {
1398 Cum
+= mLenCnt
[Index
] << (16 - Index
);
1401 while (Cum
!= (1U << 16)) {
1403 for (Index
= 15; Index
> 0; Index
--) {
1404 if (mLenCnt
[Index
] != 0) {
1406 mLenCnt
[Index
+ 1] += 2;
1414 for (Index
= 16; Index
> 0; Index
--) {
1415 Index3
= mLenCnt
[Index
];
1417 while (Index3
>= 0) {
1418 mLen
[*mSortPtr
++] = (UINT8
) Index
;
1434 // priority queue: send Index-th entry down heap
1436 Index3
= mHeap
[Index
];
1438 while (Index2
<= mHeapSize
) {
1439 if (Index2
< mHeapSize
&& mFreq
[mHeap
[Index2
]] > mFreq
[mHeap
[Index2
+ 1]]) {
1443 if (mFreq
[Index3
] <= mFreq
[mHeap
[Index2
]]) {
1447 mHeap
[Index
] = mHeap
[Index2
];
1452 mHeap
[Index
] = (INT16
) Index3
;
1464 Routine Description:
1466 Assign code to each symbol based on the code length array
1470 Number - number of symbols
1471 Len - the code length array
1472 Code - stores codes for each symbol
1482 for (Index
= 1; Index
<= 16; Index
++) {
1483 Start
[Index
+ 1] = (UINT16
) ((Start
[Index
] + mLenCnt
[Index
]) << 1);
1486 for (Index
= 0; Index
< Number
; Index
++) {
1487 Code
[Index
] = Start
[Len
[Index
]]++;
1495 IN UINT16 FreqParm
[],
1496 OUT UINT8 LenParm
[ ],
1497 OUT UINT16 CodeParm
[]
1501 Routine Description:
1503 Generates Huffman codes given a frequency distribution of symbols
1507 NParm - number of symbols
1508 FreqParm - frequency of each symbol
1509 LenParm - code length for each symbol
1510 CodeParm - code for each symbol
1514 Root of the Huffman tree.
1524 // make tree, calculate len[], return root
1532 for (Index
= 0; Index
< mN
; Index
++) {
1536 mHeap
[mHeapSize
] = (INT16
) Index
;
1540 if (mHeapSize
< 2) {
1541 CodeParm
[mHeap
[1]] = 0;
1545 for (Index
= mHeapSize
/ 2; Index
>= 1; Index
--) {
1547 // make priority queue
1552 mSortPtr
= CodeParm
;
1556 *mSortPtr
++ = (UINT16
) Index
;
1559 mHeap
[1] = mHeap
[mHeapSize
--];
1563 *mSortPtr
++ = (UINT16
) Index2
;
1567 mFreq
[Index3
] = (UINT16
) (mFreq
[Index
] + mFreq
[Index2
]);
1568 mHeap
[1] = (INT16
) Index3
;
1570 mLeft
[Index3
] = (UINT16
) Index
;
1571 mRight
[Index3
] = (UINT16
) Index2
;
1572 } while (mHeapSize
> 1);
1574 mSortPtr
= CodeParm
;
1576 MakeCode (NParm
, LenParm
, CodeParm
);
1586 IN
char *InputFileName
,
1587 OUT UINT8
*FileBuffer
,
1588 OUT UINT32
*BufferLength
1592 Routine Description:
1594 Get the contents of file specified in InputFileName
1599 InputFileName - Name of the input file.
1601 FileBuffer - Output buffer to contain data
1603 BufferLength - Actual length of the data
1607 EFI_SUCCESS on successful return
1608 EFI_ABORTED if unable to open input file.
1618 // Copy the file contents to the output buffer.
1620 InputFile
= fopen (LongFilePath (InputFileName
), "rb");
1621 if (InputFile
== NULL
) {
1622 Error (NULL
, 0, 0001, "Error opening file: %s", InputFileName
);
1626 fseek (InputFile
, 0, SEEK_END
);
1627 FileSize
= ftell (InputFile
);
1628 fseek (InputFile
, 0, SEEK_SET
);
1630 // Now read the contents of the file into the buffer
1632 if (FileSize
> 0 && FileBuffer
!= NULL
) {
1633 if (fread (FileBuffer
, FileSize
, 1, InputFile
) != 1) {
1634 Error (NULL
, 0, 0004, "Error reading contents of input file: %s", InputFileName
);
1641 Size
+= (UINTN
) FileSize
;
1642 *BufferLength
= Size
;
1644 if (FileBuffer
!= NULL
) {
1647 return EFI_BUFFER_TOO_SMALL
;
1657 Routine Description:
1659 Displays the standard utility information to SDTOUT
1671 fprintf (stdout
, "%s Version %d.%d %s \n", UTILITY_NAME
, UTILITY_MAJOR_VERSION
, UTILITY_MINOR_VERSION
, __BUILD_VERSION
);
1680 Routine Description:
1682 Displays the utility usage syntax to STDOUT
1697 fprintf (stdout
, "Usage: %s -e|-d [options] <input_file>\n\n", UTILITY_NAME
);
1700 // Copyright declaration
1702 fprintf (stdout
, "Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.\n\n");
1707 fprintf (stdout
, "Options:\n");
1708 fprintf (stdout
, " --uefi\n\
1709 Enable UefiCompress, use TianoCompress when without this option\n");
1710 fprintf (stdout
, " -o FileName, --output FileName\n\
1711 File will be created to store the output content.\n");
1712 fprintf (stdout
, " -v, --verbose\n\
1713 Turn on verbose output with informational messages.\n");
1714 fprintf (stdout
, " -q, --quiet\n\
1715 Disable all messages except key message and fatal error\n");
1716 fprintf (stdout
, " --debug [0-9]\n\
1717 Enable debug messages, at input debug level.\n");
1718 fprintf (stdout
, " --version\n\
1719 Show program's version number and exit.\n");
1720 fprintf (stdout
, " -h, --help\n\
1721 Show this help message and exit.\n");
1732 Routine Description:
1738 command line parameters
1742 EFI_SUCCESS Section header successfully generated and section concatenated.
1743 EFI_ABORTED Could not generate the section
1744 EFI_OUT_OF_RESOURCES No resource to complete the operation.
1749 char *OutputFileName
;
1750 char *InputFileName
;
1757 SCRATCH_DATA
*Scratch
;
1762 SetUtilityName(UTILITY_NAME
);
1771 InputFileName
= NULL
;
1772 OutputFileName
= NULL
;
1780 // Verify the correct number of arguments
1783 Error (NULL
, 0, 1001, "Missing options", "No input options specified.");
1788 if ((strcmp(argv
[1], "-h") == 0) || (strcmp(argv
[1], "--help") == 0)) {
1793 if ((strcmp(argv
[1], "--version") == 0)) {
1800 if (strcmp(argv
[0],"-e") == 0) {
1802 // encode the input file
1807 } else if (strcmp(argv
[0], "-d") == 0) {
1809 // decode the input file
1816 // Error command line
1818 Error (NULL
, 0, 1003, "Invalid option value", "the options specified are not recognized.");
1824 if ((strcmp(argv
[0], "-v") == 0) || (stricmp(argv
[0], "--verbose") == 0)) {
1831 if (stricmp(argv
[0], "--uefi") == 0) {
1838 if (stricmp (argv
[0], "--debug") == 0) {
1841 Status
= AsciiStringToUint64(argv
[0], FALSE
, &DebugLevel
);
1842 if (DebugLevel
> 9) {
1843 Error (NULL
, 0 ,2000, "Invalid parameter", "Unrecognized argument %s", argv
[0]);
1846 if (DebugLevel
>=5 && DebugLevel
<=9){
1855 if ((strcmp(argv
[0], "-q") == 0) || (stricmp (argv
[0], "--quiet") == 0)) {
1862 if ((strcmp(argv
[0], "-o") == 0) || (stricmp (argv
[0], "--output") == 0)) {
1863 if (argv
[1] == NULL
|| argv
[1][0] == '-') {
1864 Error (NULL
, 0, 1003, "Invalid option value", "Output File name is missing for -o option");
1867 OutputFileName
= argv
[1];
1873 if (argv
[0][0]!='-') {
1874 InputFileName
= argv
[0];
1880 Error (NULL
, 0, 1000, "Unknown option", argv
[0]);
1884 if (InputFileName
== NULL
) {
1885 Error (NULL
, 0, 1001, "Missing options", "No input files specified.");
1890 // All Parameters has been parsed, now set the message print level
1894 } else if (VerboseMode
) {
1896 } else if (DebugMode
) {
1897 SetPrintLevel(DebugLevel
);
1901 VerboseMsg("%s tool start.\n", UTILITY_NAME
);
1903 Scratch
= (SCRATCH_DATA
*)malloc(sizeof(SCRATCH_DATA
));
1904 if (Scratch
== NULL
) {
1905 Error (NULL
, 0, 4001, "Resource:", "Memory cannot be allocated!");
1909 InputFile
= fopen (LongFilePath (InputFileName
), "rb");
1910 if (InputFile
== NULL
) {
1911 Error (NULL
, 0, 0001, "Error opening input file", InputFileName
);
1915 Status
= GetFileContents(
1920 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1921 FileBuffer
= (UINT8
*) malloc (InputLength
);
1922 if (FileBuffer
== NULL
) {
1923 Error (NULL
, 0, 4001, "Resource:", "Memory cannot be allocated!");
1927 Status
= GetFileContents (
1934 if (EFI_ERROR(Status
)) {
1935 Error (NULL
, 0, 0004, "Error getting contents of file: %s", InputFileName
);
1939 if (OutputFileName
== NULL
) {
1940 OutputFileName
= DEFAULT_OUTPUT_FILE
;
1942 OutputFile
= fopen (LongFilePath (OutputFileName
), "wb");
1943 if (OutputFile
== NULL
) {
1944 Error (NULL
, 0, 0001, "Error opening output file for writing", OutputFileName
);
1950 // First call TianoCompress to get DstSize
1953 DebugMsg(UTILITY_NAME
, 0, DebugLevel
, "Encoding", NULL
);
1956 Status
= EfiCompress ((UINT8
*)FileBuffer
, InputLength
, OutBuffer
, &DstSize
);
1958 Status
= TianoCompress ((UINT8
*)FileBuffer
, InputLength
, OutBuffer
, &DstSize
);
1961 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1962 OutBuffer
= (UINT8
*) malloc (DstSize
);
1963 if (OutBuffer
== NULL
) {
1964 Error (NULL
, 0, 4001, "Resource:", "Memory cannot be allocated!");
1970 Status
= EfiCompress ((UINT8
*)FileBuffer
, InputLength
, OutBuffer
, &DstSize
);
1972 Status
= TianoCompress ((UINT8
*)FileBuffer
, InputLength
, OutBuffer
, &DstSize
);
1974 if (Status
!= EFI_SUCCESS
) {
1975 Error (NULL
, 0, 0007, "Error compressing file", NULL
);
1979 if (OutBuffer
== NULL
) {
1980 Error (NULL
, 0, 4001, "Resource:", "Memory cannot be allocated!");
1984 fwrite(OutBuffer
,(size_t)DstSize
, 1, OutputFile
);
1992 DebugMsg(UTILITY_NAME
, 0, DebugLevel
, "Encoding Successful!\n", NULL
);
1995 VerboseMsg("Encoding successful\n");
2001 DebugMsg(UTILITY_NAME
, 0, DebugLevel
, "Decoding\n", NULL
);
2005 Status
= Extract((VOID
*)FileBuffer
, InputLength
, (VOID
*)&OutBuffer
, &DstSize
, 1);
2006 if (Status
!= EFI_SUCCESS
) {
2009 fwrite(OutBuffer
, (size_t)(DstSize
), 1, OutputFile
);
2011 if (InputLength
< 8){
2012 Error (NULL
, 0, 3000, "Invalid", "The input file %s is too small.", InputFileName
);
2016 // Get Compressed file original size
2018 Src
= (UINT8
*)FileBuffer
;
2019 OrigSize
= Src
[4] + (Src
[5] << 8) + (Src
[6] << 16) + (Src
[7] << 24);
2020 CompSize
= Src
[0] + (Src
[1] << 8) + (Src
[2] <<16) + (Src
[3] <<24);
2023 // Allocate OutputBuffer
2025 if (InputLength
< CompSize
+ 8 || (CompSize
+ 8) < 8) {
2026 Error (NULL
, 0, 3000, "Invalid", "The input file %s data is invalid.", InputFileName
);
2029 OutBuffer
= (UINT8
*)malloc(OrigSize
);
2030 if (OutBuffer
== NULL
) {
2031 Error (NULL
, 0, 4001, "Resource:", "Memory cannot be allocated!");
2035 Status
= TDecompress((VOID
*)FileBuffer
, (VOID
*)OutBuffer
, (VOID
*)Scratch
, 2);
2036 if (Status
!= EFI_SUCCESS
) {
2039 fwrite(OutBuffer
, (size_t)(Scratch
->mOrigSize
), 1, OutputFile
);
2043 if (Scratch
!= NULL
) {
2046 if (FileBuffer
!= NULL
) {
2049 if (OutBuffer
!= NULL
) {
2054 DebugMsg(UTILITY_NAME
, 0, DebugLevel
, "Encoding successful!\n", NULL
);
2058 VerboseMsg("Decoding successful\n");
2066 DebugMsg(UTILITY_NAME
, 0, DebugLevel
, "Encoding Error\n", NULL
);
2067 } else if (DECODE
) {
2068 DebugMsg(UTILITY_NAME
, 0, DebugLevel
, "Decoding Error\n", NULL
);
2071 if (OutputFile
!= NULL
) {
2074 if (InputFile
!= NULL
) {
2077 if (Scratch
!= NULL
) {
2080 if (FileBuffer
!= NULL
) {
2083 if (OutBuffer
!= NULL
) {
2088 VerboseMsg("%s tool done with return code is 0x%x.\n", UTILITY_NAME
, GetUtilityStatus ());
2090 return GetUtilityStatus ();
2095 IN SCRATCH_DATA
*Sd
,
2100 Routine Description:
2102 Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source.
2106 Sd - The global scratch data
2107 NumOfBits - The number of bits to shift and read.
2113 Sd
->mBitBuf
= (UINT32
) (((UINT64
)Sd
->mBitBuf
) << NumOfBits
);
2115 while (NumOfBits
> Sd
->mBitCount
) {
2117 Sd
->mBitBuf
|= (UINT32
) (((UINT64
)Sd
->mSubBitBuf
) << (NumOfBits
= (UINT16
) (NumOfBits
- Sd
->mBitCount
)));
2119 if (Sd
->mCompSize
> 0) {
2121 // Get 1 byte into SubBitBuf
2125 Sd
->mSubBitBuf
= Sd
->mSrcBase
[Sd
->mInBuf
++];
2130 // No more bits from the source, just pad zero bit.
2138 Sd
->mBitCount
= (UINT16
) (Sd
->mBitCount
- NumOfBits
);
2139 Sd
->mBitBuf
|= Sd
->mSubBitBuf
>> Sd
->mBitCount
;
2144 IN SCRATCH_DATA
*Sd
,
2149 Routine Description:
2151 Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent
2152 NumOfBits of bits from source. Returns NumOfBits of bits that are
2157 Sd - The global scratch data.
2158 NumOfBits - The number of bits to pop and read.
2162 The bits that are popped out.
2168 OutBits
= (UINT32
) (Sd
->mBitBuf
>> (BITBUFSIZ
- NumOfBits
));
2170 FillBuf (Sd
, NumOfBits
);
2177 IN SCRATCH_DATA
*Sd
,
2178 IN UINT16 NumOfChar
,
2180 IN UINT16 TableBits
,
2185 Routine Description:
2187 Creates Huffman Code mapping table according to code length array.
2191 Sd - The global scratch data
2192 NumOfChar - Number of symbols in the symbol set
2193 BitLen - Code length array
2194 TableBits - The width of the mapping table
2200 BAD_TABLE - The table is corrupted.
2218 UINT16 MaxTableLength
;
2220 for (Index
= 0; Index
<= 16; Index
++) {
2224 for (Index
= 0; Index
< NumOfChar
; Index
++) {
2225 if (BitLen
[Index
] > 16) {
2226 return (UINT16
) BAD_TABLE
;
2228 Count
[BitLen
[Index
]]++;
2234 for (Index
= 1; Index
<= 16; Index
++) {
2235 WordOfStart
= Start
[Index
];
2236 WordOfCount
= Count
[Index
];
2237 Start
[Index
+ 1] = (UINT16
) (WordOfStart
+ (WordOfCount
<< (16 - Index
)));
2240 if (Start
[17] != 0) {
2244 return (UINT16
) BAD_TABLE
;
2247 JuBits
= (UINT16
) (16 - TableBits
);
2250 for (Index
= 1; Index
<= TableBits
; Index
++) {
2251 Start
[Index
] >>= JuBits
;
2252 Weight
[Index
] = (UINT16
) (1U << (TableBits
- Index
));
2255 while (Index
<= 16) {
2256 Weight
[Index
] = (UINT16
) (1U << (16 - Index
));
2260 Index
= (UINT16
) (Start
[TableBits
+ 1] >> JuBits
);
2263 Index3
= (UINT16
) (1U << TableBits
);
2264 while (Index
!= Index3
) {
2270 Mask
= (UINT16
) (1U << (15 - TableBits
));
2271 MaxTableLength
= (UINT16
) (1U << TableBits
);
2273 for (Char
= 0; Char
< NumOfChar
; Char
++) {
2276 if (Len
== 0 || Len
>= 17) {
2280 NextCode
= (UINT16
) (Start
[Len
] + Weight
[Len
]);
2282 if (Len
<= TableBits
) {
2284 for (Index
= Start
[Len
]; Index
< NextCode
; Index
++) {
2285 if (Index
>= MaxTableLength
) {
2286 return (UINT16
) BAD_TABLE
;
2288 Table
[Index
] = Char
;
2293 Index3
= Start
[Len
];
2294 Pointer
= &Table
[Index3
>> JuBits
];
2295 Index
= (UINT16
) (Len
- TableBits
);
2297 while (Index
!= 0) {
2298 if (*Pointer
== 0) {
2299 Sd
->mRight
[Avail
] = Sd
->mLeft
[Avail
] = 0;
2303 if (Index3
& Mask
) {
2304 Pointer
= &Sd
->mRight
[*Pointer
];
2306 Pointer
= &Sd
->mLeft
[*Pointer
];
2317 Start
[Len
] = NextCode
;
2331 Routine Description:
2333 Decodes a position value.
2337 Sd - the global scratch data
2341 The position value decoded.
2349 Val
= Sd
->mPTTable
[Sd
->mBitBuf
>> (BITBUFSIZ
- 8)];
2352 Mask
= 1U << (BITBUFSIZ
- 1 - 8);
2356 if (Sd
->mBitBuf
& Mask
) {
2357 Val
= Sd
->mRight
[Val
];
2359 Val
= Sd
->mLeft
[Val
];
2363 } while (Val
>= MAXNP
);
2366 // Advance what we have read
2368 FillBuf (Sd
, Sd
->mPTLen
[Val
]);
2372 Pos
= (UINT32
) ((1U << (Val
- 1)) + GetBits (Sd
, (UINT16
) (Val
- 1)));
2380 IN SCRATCH_DATA
*Sd
,
2387 Routine Description:
2389 Reads code lengths for the Extra Set or the Position Set
2393 Sd - The global scratch data
2394 nn - Number of symbols
2395 nbit - Number of bits needed to represent nn
2396 Special - The special symbol that needs to be taken care of
2401 BAD_TABLE - Table is corrupted.
2407 volatile UINT16 Index
;
2412 Number
= (UINT16
) GetBits (Sd
, nbit
);
2415 CharC
= (UINT16
) GetBits (Sd
, nbit
);
2417 for (Index
= 0; Index
< 256; Index
++) {
2418 Sd
->mPTTable
[Index
] = CharC
;
2421 for (Index
= 0; Index
< nn
; Index
++) {
2422 Sd
->mPTLen
[Index
] = 0;
2430 while (Index
< Number
) {
2432 CharC
= (UINT16
) (Sd
->mBitBuf
>> (BITBUFSIZ
- 3));
2435 Mask
= 1U << (BITBUFSIZ
- 1 - 3);
2436 while (Mask
& Sd
->mBitBuf
) {
2442 FillBuf (Sd
, (UINT16
) ((CharC
< 7) ? 3 : CharC
- 3));
2444 Sd
->mPTLen
[Index
++] = (UINT8
) CharC
;
2446 if (Index
== Special
) {
2447 CharC
= (UINT16
) GetBits (Sd
, 2);
2448 while ((INT16
) (--CharC
) >= 0) {
2449 Sd
->mPTLen
[Index
++] = 0;
2454 while (Index
< nn
) {
2455 Sd
->mPTLen
[Index
++] = 0;
2458 return MakeTable (Sd
, nn
, Sd
->mPTLen
, 8, Sd
->mPTTable
);
2467 Routine Description:
2469 Reads code lengths for Char&Len Set.
2473 Sd - the global scratch data
2481 volatile UINT16 Index
;
2484 Number
= (UINT16
) GetBits (Sd
, CBIT
);
2487 CharC
= (UINT16
) GetBits (Sd
, CBIT
);
2489 for (Index
= 0; Index
< NC
; Index
++) {
2490 Sd
->mCLen
[Index
] = 0;
2493 for (Index
= 0; Index
< 4096; Index
++) {
2494 Sd
->mCTable
[Index
] = CharC
;
2501 while (Index
< Number
) {
2503 CharC
= Sd
->mPTTable
[Sd
->mBitBuf
>> (BITBUFSIZ
- 8)];
2505 Mask
= 1U << (BITBUFSIZ
- 1 - 8);
2509 if (Mask
& Sd
->mBitBuf
) {
2510 CharC
= Sd
->mRight
[CharC
];
2512 CharC
= Sd
->mLeft
[CharC
];
2517 } while (CharC
>= NT
);
2520 // Advance what we have read
2522 FillBuf (Sd
, Sd
->mPTLen
[CharC
]);
2528 } else if (CharC
== 1) {
2529 CharC
= (UINT16
) (GetBits (Sd
, 4) + 3);
2530 } else if (CharC
== 2) {
2531 CharC
= (UINT16
) (GetBits (Sd
, CBIT
) + 20);
2534 while ((INT16
) (--CharC
) >= 0) {
2535 Sd
->mCLen
[Index
++] = 0;
2540 Sd
->mCLen
[Index
++] = (UINT8
) (CharC
- 2);
2545 while (Index
< NC
) {
2546 Sd
->mCLen
[Index
++] = 0;
2549 MakeTable (Sd
, NC
, Sd
->mCLen
, 12, Sd
->mCTable
);
2560 Routine Description:
2562 Decode a character/length value.
2566 Sd - The global scratch data.
2577 if (Sd
->mBlockSize
== 0) {
2579 // Starting a new block
2581 Sd
->mBlockSize
= (UINT16
) GetBits (Sd
, 16);
2582 Sd
->mBadTableFlag
= ReadPTLen (Sd
, NT
, TBIT
, 3);
2583 if (Sd
->mBadTableFlag
!= 0) {
2589 Sd
->mBadTableFlag
= ReadPTLen (Sd
, MAXNP
, Sd
->mPBit
, (UINT16
) (-1));
2590 if (Sd
->mBadTableFlag
!= 0) {
2596 Index2
= Sd
->mCTable
[Sd
->mBitBuf
>> (BITBUFSIZ
- 12)];
2599 Mask
= 1U << (BITBUFSIZ
- 1 - 12);
2602 if (Sd
->mBitBuf
& Mask
) {
2603 Index2
= Sd
->mRight
[Index2
];
2605 Index2
= Sd
->mLeft
[Index2
];
2609 } while (Index2
>= NC
);
2612 // Advance what we have read
2614 FillBuf (Sd
, Sd
->mCLen
[Index2
]);
2625 Routine Description:
2627 Decode the source data and put the resulting data into the destination buffer.
2631 Sd - The global scratch data
2641 BytesRemain
= (UINT16
) (-1);
2646 CharC
= DecodeC (Sd
);
2647 if (Sd
->mBadTableFlag
!= 0) {
2653 // Process an Original character
2655 if (Sd
->mOutBuf
>= Sd
->mOrigSize
) {
2658 Sd
->mDstBase
[Sd
->mOutBuf
++] = (UINT8
) CharC
;
2663 // Process a Pointer
2665 CharC
= (UINT16
) (CharC
- (UINT8_MAX
+ 1 - THRESHOLD
));
2667 BytesRemain
= CharC
;
2669 DataIdx
= Sd
->mOutBuf
- DecodeP (Sd
) - 1;
2673 while ((INT16
) (BytesRemain
) >= 0) {
2674 if (Sd
->mOutBuf
>= Sd
->mOrigSize
) {
2677 if (DataIdx
>= Sd
->mOrigSize
) {
2678 Sd
->mBadTableFlag
= (UINT16
) BAD_TABLE
;
2681 Sd
->mDstBase
[Sd
->mOutBuf
++] = Sd
->mDstBase
[DataIdx
++];
2686 // Once mOutBuf is fully filled, directly return
2688 if (Sd
->mOutBuf
>= Sd
->mOrigSize
) {
2702 IN OUT VOID
*Destination
,
2703 IN OUT VOID
*Scratch
,
2708 Routine Description:
2710 The internal implementation of Decompress().
2714 Source - The source buffer containing the compressed data.
2715 Destination - The destination buffer to store the decompressed data
2716 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
2717 Version - 1 for EFI1.1 Decompress algorithm, 2 for Tiano Decompress algorithm
2721 RETURN_SUCCESS - Decompression is successful
2722 RETURN_INVALID_PARAMETER - The source data is corrupted
2726 volatile UINT32 Index
;
2734 // Verify input is not NULL
2737 // assert(Destination);
2740 Src
= (UINT8
*)Source
;
2741 Dst
= (UINT8
*)Destination
;
2743 Sd
= (SCRATCH_DATA
*) Scratch
;
2744 CompSize
= Src
[0] + (Src
[1] << 8) + (Src
[2] << 16) + (Src
[3] << 24);
2745 OrigSize
= Src
[4] + (Src
[5] << 8) + (Src
[6] << 16) + (Src
[7] << 24);
2748 // If compressed file size is 0, return
2750 if (OrigSize
== 0) {
2751 return RETURN_SUCCESS
;
2756 for (Index
= 0; Index
< sizeof (SCRATCH_DATA
); Index
++) {
2757 ((UINT8
*) Sd
)[Index
] = 0;
2760 // The length of the field 'Position Set Code Length Array Size' in Block Header.
2761 // For EFI 1.1 de/compression algorithm(Version 1), mPBit = 4
2762 // For Tiano de/compression algorithm(Version 2), mPBit = 5
2774 Sd
->mSrcBase
= (UINT8
*)Src
;
2776 Sd
->mCompSize
= CompSize
;
2777 Sd
->mOrigSize
= OrigSize
;
2780 // Fill the first BITBUFSIZ bits
2782 FillBuf (Sd
, BITBUFSIZ
);
2790 if (Sd
->mBadTableFlag
!= 0) {
2792 // Something wrong with the source
2794 return RETURN_INVALID_PARAMETER
;
2797 return RETURN_SUCCESS
;