]>
git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/C/TianoCompress/TianoCompress.c
b88d7da2ed2f8ec459de82569b46e9ba51a5c078
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. Travese 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 ouput 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
;
1761 SetUtilityName(UTILITY_NAME
);
1769 InputFileName
= NULL
;
1770 OutputFileName
= NULL
;
1778 // Verify the correct number of arguments
1781 Error (NULL
, 0, 1001, "Missing options", "No input options specified.");
1786 if ((strcmp(argv
[1], "-h") == 0) || (strcmp(argv
[1], "--help") == 0)) {
1791 if ((strcmp(argv
[1], "--version") == 0)) {
1798 if (strcmp(argv
[0],"-e") == 0) {
1800 // encode the input file
1805 } else if (strcmp(argv
[0], "-d") == 0) {
1807 // decode the input file
1814 // Error command line
1816 Error (NULL
, 0, 1003, "Invalid option value", "the options specified are not recognized.");
1822 if ((strcmp(argv
[0], "-v") == 0) || (stricmp(argv
[0], "--verbose") == 0)) {
1829 if (stricmp(argv
[0], "--uefi") == 0) {
1836 if (stricmp (argv
[0], "--debug") == 0) {
1839 Status
= AsciiStringToUint64(argv
[0], FALSE
, &DebugLevel
);
1840 if (DebugLevel
> 9) {
1841 Error (NULL
, 0 ,2000, "Invalid parameter", "Unrecognized argument %s", argv
[0]);
1844 if (DebugLevel
>=5 && DebugLevel
<=9){
1853 if ((strcmp(argv
[0], "-q") == 0) || (stricmp (argv
[0], "--quiet") == 0)) {
1860 if ((strcmp(argv
[0], "-o") == 0) || (stricmp (argv
[0], "--output") == 0)) {
1861 if (argv
[1] == NULL
|| argv
[1][0] == '-') {
1862 Error (NULL
, 0, 1003, "Invalid option value", "Output File name is missing for -o option");
1865 OutputFileName
= argv
[1];
1871 if (argv
[0][0]!='-') {
1872 InputFileName
= argv
[0];
1878 Error (NULL
, 0, 1000, "Unknown option", argv
[0]);
1882 if (InputFileName
== NULL
) {
1883 Error (NULL
, 0, 1001, "Missing options", "No input files specified.");
1888 // All Parameters has been parsed, now set the message print level
1892 } else if (VerboseMode
) {
1894 } else if (DebugMode
) {
1895 SetPrintLevel(DebugLevel
);
1899 VerboseMsg("%s tool start.\n", UTILITY_NAME
);
1901 Scratch
= (SCRATCH_DATA
*)malloc(sizeof(SCRATCH_DATA
));
1902 if (Scratch
== NULL
) {
1903 Error (NULL
, 0, 4001, "Resource:", "Memory cannot be allocated!");
1907 InputFile
= fopen (LongFilePath (InputFileName
), "rb");
1908 if (InputFile
== NULL
) {
1909 Error (NULL
, 0, 0001, "Error opening input file", InputFileName
);
1913 Status
= GetFileContents(
1918 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1919 FileBuffer
= (UINT8
*) malloc (InputLength
);
1920 if (FileBuffer
== NULL
) {
1921 Error (NULL
, 0, 4001, "Resource:", "Memory cannot be allocated!");
1925 Status
= GetFileContents (
1932 if (EFI_ERROR(Status
)) {
1933 Error (NULL
, 0, 0004, "Error getting contents of file: %s", InputFileName
);
1937 if (OutputFileName
== NULL
) {
1938 OutputFileName
= DEFAULT_OUTPUT_FILE
;
1940 OutputFile
= fopen (LongFilePath (OutputFileName
), "wb");
1941 if (OutputFile
== NULL
) {
1942 Error (NULL
, 0, 0001, "Error opening output file for writing", OutputFileName
);
1948 // First call TianoCompress to get DstSize
1951 DebugMsg(UTILITY_NAME
, 0, DebugLevel
, "Encoding", NULL
);
1954 Status
= EfiCompress ((UINT8
*)FileBuffer
, InputLength
, OutBuffer
, &DstSize
);
1956 Status
= TianoCompress ((UINT8
*)FileBuffer
, InputLength
, OutBuffer
, &DstSize
);
1959 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1960 OutBuffer
= (UINT8
*) malloc (DstSize
);
1961 if (OutBuffer
== NULL
) {
1962 Error (NULL
, 0, 4001, "Resource:", "Memory cannot be allocated!");
1968 Status
= EfiCompress ((UINT8
*)FileBuffer
, InputLength
, OutBuffer
, &DstSize
);
1970 Status
= TianoCompress ((UINT8
*)FileBuffer
, InputLength
, OutBuffer
, &DstSize
);
1972 if (Status
!= EFI_SUCCESS
) {
1973 Error (NULL
, 0, 0007, "Error compressing file", NULL
);
1977 if (OutBuffer
== NULL
) {
1978 Error (NULL
, 0, 4001, "Resource:", "Memory cannot be allocated!");
1982 fwrite(OutBuffer
,(size_t)DstSize
, 1, OutputFile
);
1990 DebugMsg(UTILITY_NAME
, 0, DebugLevel
, "Encoding Successful!\n", NULL
);
1993 VerboseMsg("Encoding successful\n");
1999 DebugMsg(UTILITY_NAME
, 0, DebugLevel
, "Decoding\n", NULL
);
2003 Status
= Extract((VOID
*)FileBuffer
, InputLength
, (VOID
*)&OutBuffer
, &DstSize
, 1);
2004 if (Status
!= EFI_SUCCESS
) {
2007 fwrite(OutBuffer
, (size_t)(DstSize
), 1, OutputFile
);
2010 // Get Compressed file original size
2012 Src
= (UINT8
*)FileBuffer
;
2013 OrigSize
= Src
[4] + (Src
[5] << 8) + (Src
[6] << 16) + (Src
[7] << 24);
2016 // Allocate OutputBuffer
2018 OutBuffer
= (UINT8
*)malloc(OrigSize
);
2019 if (OutBuffer
== NULL
) {
2020 Error (NULL
, 0, 4001, "Resource:", "Memory cannot be allocated!");
2024 Status
= TDecompress((VOID
*)FileBuffer
, (VOID
*)OutBuffer
, (VOID
*)Scratch
, 2);
2025 if (Status
!= EFI_SUCCESS
) {
2028 fwrite(OutBuffer
, (size_t)(Scratch
->mOrigSize
), 1, OutputFile
);
2032 if (Scratch
!= NULL
) {
2035 if (FileBuffer
!= NULL
) {
2038 if (OutBuffer
!= NULL
) {
2043 DebugMsg(UTILITY_NAME
, 0, DebugLevel
, "Encoding successful!\n", NULL
);
2047 VerboseMsg("Decoding successful\n");
2055 DebugMsg(UTILITY_NAME
, 0, DebugLevel
, "Encoding Error\n", NULL
);
2056 } else if (DECODE
) {
2057 DebugMsg(UTILITY_NAME
, 0, DebugLevel
, "Decoding Error\n", NULL
);
2060 if (OutputFile
!= NULL
) {
2063 if (InputFile
!= NULL
) {
2066 if (Scratch
!= NULL
) {
2069 if (FileBuffer
!= NULL
) {
2072 if (OutBuffer
!= NULL
) {
2077 VerboseMsg("%s tool done with return code is 0x%x.\n", UTILITY_NAME
, GetUtilityStatus ());
2079 return GetUtilityStatus ();
2084 IN SCRATCH_DATA
*Sd
,
2089 Routine Description:
2091 Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source.
2095 Sd - The global scratch data
2096 NumOfBits - The number of bits to shift and read.
2102 Sd
->mBitBuf
= (UINT32
) (((UINT64
)Sd
->mBitBuf
) << NumOfBits
);
2104 while (NumOfBits
> Sd
->mBitCount
) {
2106 Sd
->mBitBuf
|= (UINT32
) (((UINT64
)Sd
->mSubBitBuf
) << (NumOfBits
= (UINT16
) (NumOfBits
- Sd
->mBitCount
)));
2108 if (Sd
->mCompSize
> 0) {
2110 // Get 1 byte into SubBitBuf
2114 Sd
->mSubBitBuf
= Sd
->mSrcBase
[Sd
->mInBuf
++];
2119 // No more bits from the source, just pad zero bit.
2127 Sd
->mBitCount
= (UINT16
) (Sd
->mBitCount
- NumOfBits
);
2128 Sd
->mBitBuf
|= Sd
->mSubBitBuf
>> Sd
->mBitCount
;
2133 IN SCRATCH_DATA
*Sd
,
2138 Routine Description:
2140 Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent
2141 NumOfBits of bits from source. Returns NumOfBits of bits that are
2146 Sd - The global scratch data.
2147 NumOfBits - The number of bits to pop and read.
2151 The bits that are popped out.
2157 OutBits
= (UINT32
) (Sd
->mBitBuf
>> (BITBUFSIZ
- NumOfBits
));
2159 FillBuf (Sd
, NumOfBits
);
2166 IN SCRATCH_DATA
*Sd
,
2167 IN UINT16 NumOfChar
,
2169 IN UINT16 TableBits
,
2174 Routine Description:
2176 Creates Huffman Code mapping table according to code length array.
2180 Sd - The global scratch data
2181 NumOfChar - Number of symbols in the symbol set
2182 BitLen - Code length array
2183 TableBits - The width of the mapping table
2189 BAD_TABLE - The table is corrupted.
2208 for (Index
= 0; Index
<= 16; Index
++) {
2212 for (Index
= 0; Index
< NumOfChar
; Index
++) {
2213 Count
[BitLen
[Index
]]++;
2219 for (Index
= 1; Index
<= 16; Index
++) {
2220 WordOfStart
= Start
[Index
];
2221 WordOfCount
= Count
[Index
];
2222 Start
[Index
+ 1] = (UINT16
) (WordOfStart
+ (WordOfCount
<< (16 - Index
)));
2225 if (Start
[17] != 0) {
2229 return (UINT16
) BAD_TABLE
;
2232 JuBits
= (UINT16
) (16 - TableBits
);
2235 for (Index
= 1; Index
<= TableBits
; Index
++) {
2236 Start
[Index
] >>= JuBits
;
2237 Weight
[Index
] = (UINT16
) (1U << (TableBits
- Index
));
2240 while (Index
<= 16) {
2241 Weight
[Index
] = (UINT16
) (1U << (16 - Index
));
2245 Index
= (UINT16
) (Start
[TableBits
+ 1] >> JuBits
);
2248 Index3
= (UINT16
) (1U << TableBits
);
2249 while (Index
!= Index3
) {
2255 Mask
= (UINT16
) (1U << (15 - TableBits
));
2257 for (Char
= 0; Char
< NumOfChar
; Char
++) {
2260 if (Len
== 0 || Len
>= 17) {
2264 NextCode
= (UINT16
) (Start
[Len
] + Weight
[Len
]);
2266 if (Len
<= TableBits
) {
2268 for (Index
= Start
[Len
]; Index
< NextCode
; Index
++) {
2269 Table
[Index
] = Char
;
2274 Index3
= Start
[Len
];
2275 Pointer
= &Table
[Index3
>> JuBits
];
2276 Index
= (UINT16
) (Len
- TableBits
);
2278 while (Index
!= 0) {
2279 if (*Pointer
== 0) {
2280 Sd
->mRight
[Avail
] = Sd
->mLeft
[Avail
] = 0;
2284 if (Index3
& Mask
) {
2285 Pointer
= &Sd
->mRight
[*Pointer
];
2287 Pointer
= &Sd
->mLeft
[*Pointer
];
2298 Start
[Len
] = NextCode
;
2312 Routine Description:
2314 Decodes a position value.
2318 Sd - the global scratch data
2322 The position value decoded.
2330 Val
= Sd
->mPTTable
[Sd
->mBitBuf
>> (BITBUFSIZ
- 8)];
2333 Mask
= 1U << (BITBUFSIZ
- 1 - 8);
2337 if (Sd
->mBitBuf
& Mask
) {
2338 Val
= Sd
->mRight
[Val
];
2340 Val
= Sd
->mLeft
[Val
];
2344 } while (Val
>= MAXNP
);
2347 // Advance what we have read
2349 FillBuf (Sd
, Sd
->mPTLen
[Val
]);
2353 Pos
= (UINT32
) ((1U << (Val
- 1)) + GetBits (Sd
, (UINT16
) (Val
- 1)));
2361 IN SCRATCH_DATA
*Sd
,
2368 Routine Description:
2370 Reads code lengths for the Extra Set or the Position Set
2374 Sd - The global scratch data
2375 nn - Number of symbols
2376 nbit - Number of bits needed to represent nn
2377 Special - The special symbol that needs to be taken care of
2382 BAD_TABLE - Table is corrupted.
2388 volatile UINT16 Index
;
2393 Number
= (UINT16
) GetBits (Sd
, nbit
);
2396 CharC
= (UINT16
) GetBits (Sd
, nbit
);
2398 for (Index
= 0; Index
< 256; Index
++) {
2399 Sd
->mPTTable
[Index
] = CharC
;
2402 for (Index
= 0; Index
< nn
; Index
++) {
2403 Sd
->mPTLen
[Index
] = 0;
2411 while (Index
< Number
) {
2413 CharC
= (UINT16
) (Sd
->mBitBuf
>> (BITBUFSIZ
- 3));
2416 Mask
= 1U << (BITBUFSIZ
- 1 - 3);
2417 while (Mask
& Sd
->mBitBuf
) {
2423 FillBuf (Sd
, (UINT16
) ((CharC
< 7) ? 3 : CharC
- 3));
2425 Sd
->mPTLen
[Index
++] = (UINT8
) CharC
;
2427 if (Index
== Special
) {
2428 CharC
= (UINT16
) GetBits (Sd
, 2);
2429 while ((INT16
) (--CharC
) >= 0) {
2430 Sd
->mPTLen
[Index
++] = 0;
2435 while (Index
< nn
) {
2436 Sd
->mPTLen
[Index
++] = 0;
2439 return MakeTable (Sd
, nn
, Sd
->mPTLen
, 8, Sd
->mPTTable
);
2448 Routine Description:
2450 Reads code lengths for Char&Len Set.
2454 Sd - the global scratch data
2462 volatile UINT16 Index
;
2465 Number
= (UINT16
) GetBits (Sd
, CBIT
);
2468 CharC
= (UINT16
) GetBits (Sd
, CBIT
);
2470 for (Index
= 0; Index
< NC
; Index
++) {
2471 Sd
->mCLen
[Index
] = 0;
2474 for (Index
= 0; Index
< 4096; Index
++) {
2475 Sd
->mCTable
[Index
] = CharC
;
2482 while (Index
< Number
) {
2484 CharC
= Sd
->mPTTable
[Sd
->mBitBuf
>> (BITBUFSIZ
- 8)];
2486 Mask
= 1U << (BITBUFSIZ
- 1 - 8);
2490 if (Mask
& Sd
->mBitBuf
) {
2491 CharC
= Sd
->mRight
[CharC
];
2493 CharC
= Sd
->mLeft
[CharC
];
2498 } while (CharC
>= NT
);
2501 // Advance what we have read
2503 FillBuf (Sd
, Sd
->mPTLen
[CharC
]);
2509 } else if (CharC
== 1) {
2510 CharC
= (UINT16
) (GetBits (Sd
, 4) + 3);
2511 } else if (CharC
== 2) {
2512 CharC
= (UINT16
) (GetBits (Sd
, CBIT
) + 20);
2515 while ((INT16
) (--CharC
) >= 0) {
2516 Sd
->mCLen
[Index
++] = 0;
2521 Sd
->mCLen
[Index
++] = (UINT8
) (CharC
- 2);
2526 while (Index
< NC
) {
2527 Sd
->mCLen
[Index
++] = 0;
2530 MakeTable (Sd
, NC
, Sd
->mCLen
, 12, Sd
->mCTable
);
2541 Routine Description:
2543 Decode a character/length value.
2547 Sd - The global scratch data.
2558 if (Sd
->mBlockSize
== 0) {
2560 // Starting a new block
2562 Sd
->mBlockSize
= (UINT16
) GetBits (Sd
, 16);
2563 Sd
->mBadTableFlag
= ReadPTLen (Sd
, NT
, TBIT
, 3);
2564 if (Sd
->mBadTableFlag
!= 0) {
2570 Sd
->mBadTableFlag
= ReadPTLen (Sd
, MAXNP
, Sd
->mPBit
, (UINT16
) (-1));
2571 if (Sd
->mBadTableFlag
!= 0) {
2577 Index2
= Sd
->mCTable
[Sd
->mBitBuf
>> (BITBUFSIZ
- 12)];
2580 Mask
= 1U << (BITBUFSIZ
- 1 - 12);
2583 if (Sd
->mBitBuf
& Mask
) {
2584 Index2
= Sd
->mRight
[Index2
];
2586 Index2
= Sd
->mLeft
[Index2
];
2590 } while (Index2
>= NC
);
2593 // Advance what we have read
2595 FillBuf (Sd
, Sd
->mCLen
[Index2
]);
2606 Routine Description:
2608 Decode the source data and put the resulting data into the destination buffer.
2612 Sd - The global scratch data
2622 BytesRemain
= (UINT16
) (-1);
2627 CharC
= DecodeC (Sd
);
2628 if (Sd
->mBadTableFlag
!= 0) {
2634 // Process an Original character
2636 if (Sd
->mOutBuf
>= Sd
->mOrigSize
) {
2639 Sd
->mDstBase
[Sd
->mOutBuf
++] = (UINT8
) CharC
;
2644 // Process a Pointer
2646 CharC
= (UINT16
) (CharC
- (UINT8_MAX
+ 1 - THRESHOLD
));
2648 BytesRemain
= CharC
;
2650 DataIdx
= Sd
->mOutBuf
- DecodeP (Sd
) - 1;
2653 while ((INT16
) (BytesRemain
) >= 0) {
2654 Sd
->mDstBase
[Sd
->mOutBuf
++] = Sd
->mDstBase
[DataIdx
++];
2655 if (Sd
->mOutBuf
>= Sd
->mOrigSize
) {
2672 IN OUT VOID
*Destination
,
2673 IN OUT VOID
*Scratch
,
2678 Routine Description:
2680 The internal implementation of Decompress().
2684 Source - The source buffer containing the compressed data.
2685 Destination - The destination buffer to store the decompressed data
2686 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
2687 Version - 1 for EFI1.1 Decompress algoruthm, 2 for Tiano Decompress algorithm
2691 RETURN_SUCCESS - Decompression is successfull
2692 RETURN_INVALID_PARAMETER - The source data is corrupted
2696 volatile UINT32 Index
;
2704 // Verify input is not NULL
2707 // assert(Destination);
2710 Src
= (UINT8
*)Source
;
2711 Dst
= (UINT8
*)Destination
;
2713 Sd
= (SCRATCH_DATA
*) Scratch
;
2714 CompSize
= Src
[0] + (Src
[1] << 8) + (Src
[2] << 16) + (Src
[3] << 24);
2715 OrigSize
= Src
[4] + (Src
[5] << 8) + (Src
[6] << 16) + (Src
[7] << 24);
2718 // If compressed file size is 0, return
2720 if (OrigSize
== 0) {
2721 return RETURN_SUCCESS
;
2726 for (Index
= 0; Index
< sizeof (SCRATCH_DATA
); Index
++) {
2727 ((UINT8
*) Sd
)[Index
] = 0;
2730 // The length of the field 'Position Set Code Length Array Size' in Block Header.
2731 // For EFI 1.1 de/compression algorithm(Version 1), mPBit = 4
2732 // For Tiano de/compression algorithm(Version 2), mPBit = 5
2744 Sd
->mSrcBase
= (UINT8
*)Src
;
2746 Sd
->mCompSize
= CompSize
;
2747 Sd
->mOrigSize
= OrigSize
;
2750 // Fill the first BITBUFSIZ bits
2752 FillBuf (Sd
, BITBUFSIZ
);
2760 if (Sd
->mBadTableFlag
!= 0) {
2762 // Something wrong with the source
2764 return RETURN_INVALID_PARAMETER
;
2767 return RETURN_SUCCESS
;