2 UEFI and Custom Decompress Library
4 Copyright (c) 2006, Intel Corporation
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include <Guid/CustomDecompress.h>
16 #include "BaseUefiTianoCustomDecompressLibInternals.h"
27 Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source.
31 Sd - The global scratch data
32 NumOfBits - The number of bits to shift and read.
38 Sd
->mBitBuf
= (UINT32
) (Sd
->mBitBuf
<< NumOfBits
);
40 while (NumOfBits
> Sd
->mBitCount
) {
42 Sd
->mBitBuf
|= (UINT32
) (Sd
->mSubBitBuf
<< (NumOfBits
= (UINT16
) (NumOfBits
- Sd
->mBitCount
)));
44 if (Sd
->mCompSize
> 0) {
46 // Get 1 byte into SubBitBuf
50 Sd
->mSubBitBuf
= Sd
->mSrcBase
[Sd
->mInBuf
++];
55 // No more bits from the source, just pad zero bit.
63 Sd
->mBitCount
= (UINT16
) (Sd
->mBitCount
- NumOfBits
);
64 Sd
->mBitBuf
|= Sd
->mSubBitBuf
>> Sd
->mBitCount
;
76 Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent
77 NumOfBits of bits from source. Returns NumOfBits of bits that are
82 Sd - The global scratch data.
83 NumOfBits - The number of bits to pop and read.
87 The bits that are popped out.
93 OutBits
= (UINT32
) (Sd
->mBitBuf
>> (BITBUFSIZ
- NumOfBits
));
95 FillBuf (Sd
, NumOfBits
);
112 Creates Huffman Code mapping table according to code length array.
116 Sd - The global scratch data
117 NumOfChar - Number of symbols in the symbol set
118 BitLen - Code length array
119 TableBits - The width of the mapping table
125 BAD_TABLE - The table is corrupted.
134 volatile UINT16 Index
;
144 for (Index
= 1; Index
<= 16; Index
++) {
148 for (Index
= 0; Index
< NumOfChar
; Index
++) {
149 Count
[BitLen
[Index
]]++;
154 for (Index
= 1; Index
<= 16; Index
++) {
155 WordOfStart
= Start
[Index
];
156 WordOfCount
= Count
[Index
];
157 Start
[Index
+ 1] = (UINT16
) (WordOfStart
+ (WordOfCount
<< (16 - Index
)));
160 if (Start
[17] != 0) {
162 return (UINT16
) BAD_TABLE
;
165 JuBits
= (UINT16
) (16 - TableBits
);
167 for (Index
= 1; Index
<= TableBits
; Index
++) {
168 Start
[Index
] >>= JuBits
;
169 Weight
[Index
] = (UINT16
) (1U << (TableBits
- Index
));
172 while (Index
<= 16) {
173 Weight
[Index
] = (UINT16
) (1U << (16 - Index
));
177 Index
= (UINT16
) (Start
[TableBits
+ 1] >> JuBits
);
180 Index3
= (UINT16
) (1U << TableBits
);
181 while (Index
!= Index3
) {
187 Mask
= (UINT16
) (1U << (15 - TableBits
));
189 for (Char
= 0; Char
< NumOfChar
; Char
++) {
196 NextCode
= (UINT16
) (Start
[Len
] + Weight
[Len
]);
198 if (Len
<= TableBits
) {
200 for (Index
= Start
[Len
]; Index
< NextCode
; Index
++) {
207 Pointer
= &Table
[Index3
>> JuBits
];
208 Index
= (UINT16
) (Len
- TableBits
);
212 Sd
->mRight
[Avail
] = Sd
->mLeft
[Avail
] = 0;
217 Pointer
= &Sd
->mRight
[*Pointer
];
219 Pointer
= &Sd
->mLeft
[*Pointer
];
230 Start
[Len
] = NextCode
;
246 Decodes a position value.
250 Sd - the global scratch data
254 The position value decoded.
262 Val
= Sd
->mPTTable
[Sd
->mBitBuf
>> (BITBUFSIZ
- 8)];
265 Mask
= 1U << (BITBUFSIZ
- 1 - 8);
269 if (Sd
->mBitBuf
& Mask
) {
270 Val
= Sd
->mRight
[Val
];
272 Val
= Sd
->mLeft
[Val
];
276 } while (Val
>= MAXNP
);
279 // Advance what we have read
281 FillBuf (Sd
, Sd
->mPTLen
[Val
]);
285 Pos
= (UINT32
) ((1U << (Val
- 1)) + GetBits (Sd
, (UINT16
) (Val
- 1)));
302 Reads code lengths for the Extra Set or the Position Set
306 Sd - The global scratch data
307 nn - Number of symbols
308 nbit - Number of bits needed to represent nn
309 Special - The special symbol that needs to be taken care of
314 BAD_TABLE - Table is corrupted.
320 volatile UINT16 Index
;
323 Number
= (UINT16
) GetBits (Sd
, nbit
);
326 CharC
= (UINT16
) GetBits (Sd
, nbit
);
328 for (Index
= 0; Index
< 256; Index
++) {
329 Sd
->mPTTable
[Index
] = CharC
;
332 for (Index
= 0; Index
< nn
; Index
++) {
333 Sd
->mPTLen
[Index
] = 0;
341 while (Index
< Number
) {
343 CharC
= (UINT16
) (Sd
->mBitBuf
>> (BITBUFSIZ
- 3));
346 Mask
= 1U << (BITBUFSIZ
- 1 - 3);
347 while (Mask
& Sd
->mBitBuf
) {
353 FillBuf (Sd
, (UINT16
) ((CharC
< 7) ? 3 : CharC
- 3));
355 Sd
->mPTLen
[Index
++] = (UINT8
) CharC
;
357 if (Index
== Special
) {
358 CharC
= (UINT16
) GetBits (Sd
, 2);
359 while ((INT16
) (--CharC
) >= 0) {
360 Sd
->mPTLen
[Index
++] = 0;
366 Sd
->mPTLen
[Index
++] = 0;
369 return MakeTable (Sd
, nn
, Sd
->mPTLen
, 8, Sd
->mPTTable
);
380 Reads code lengths for Char&Len Set.
384 Sd - the global scratch data
392 volatile UINT16 Index
;
395 Number
= (UINT16
) GetBits (Sd
, CBIT
);
398 CharC
= (UINT16
) GetBits (Sd
, CBIT
);
400 for (Index
= 0; Index
< NC
; Index
++) {
401 Sd
->mCLen
[Index
] = 0;
404 for (Index
= 0; Index
< 4096; Index
++) {
405 Sd
->mCTable
[Index
] = CharC
;
412 while (Index
< Number
) {
414 CharC
= Sd
->mPTTable
[Sd
->mBitBuf
>> (BITBUFSIZ
- 8)];
416 Mask
= 1U << (BITBUFSIZ
- 1 - 8);
420 if (Mask
& Sd
->mBitBuf
) {
421 CharC
= Sd
->mRight
[CharC
];
423 CharC
= Sd
->mLeft
[CharC
];
428 } while (CharC
>= NT
);
431 // Advance what we have read
433 FillBuf (Sd
, Sd
->mPTLen
[CharC
]);
439 } else if (CharC
== 1) {
440 CharC
= (UINT16
) (GetBits (Sd
, 4) + 3);
441 } else if (CharC
== 2) {
442 CharC
= (UINT16
) (GetBits (Sd
, CBIT
) + 20);
445 while ((INT16
) (--CharC
) >= 0) {
446 Sd
->mCLen
[Index
++] = 0;
451 Sd
->mCLen
[Index
++] = (UINT8
) (CharC
- 2);
457 Sd
->mCLen
[Index
++] = 0;
460 MakeTable (Sd
, NC
, Sd
->mCLen
, 12, Sd
->mCTable
);
473 Decode a character/length value.
477 Sd - The global scratch data.
488 if (Sd
->mBlockSize
== 0) {
490 // Starting a new block
492 Sd
->mBlockSize
= (UINT16
) GetBits (Sd
, 16);
493 Sd
->mBadTableFlag
= ReadPTLen (Sd
, NT
, TBIT
, 3);
494 if (Sd
->mBadTableFlag
!= 0) {
500 Sd
->mBadTableFlag
= ReadPTLen (Sd
, MAXNP
, Sd
->mPBit
, (UINT16
) (-1));
501 if (Sd
->mBadTableFlag
!= 0) {
507 Index2
= Sd
->mCTable
[Sd
->mBitBuf
>> (BITBUFSIZ
- 12)];
510 Mask
= 1U << (BITBUFSIZ
- 1 - 12);
513 if (Sd
->mBitBuf
& Mask
) {
514 Index2
= Sd
->mRight
[Index2
];
516 Index2
= Sd
->mLeft
[Index2
];
520 } while (Index2
>= NC
);
523 // Advance what we have read
525 FillBuf (Sd
, Sd
->mCLen
[Index2
]);
538 Decode the source data and put the resulting data into the destination buffer.
542 Sd - The global scratch data
552 BytesRemain
= (UINT16
) (-1);
557 CharC
= DecodeC (Sd
);
558 if (Sd
->mBadTableFlag
!= 0) {
564 // Process an Original character
566 if (Sd
->mOutBuf
>= Sd
->mOrigSize
) {
569 Sd
->mDstBase
[Sd
->mOutBuf
++] = (UINT8
) CharC
;
576 CharC
= (UINT16
) (CharC
- (UINT8_MAX
+ 1 - THRESHOLD
));
580 DataIdx
= Sd
->mOutBuf
- DecodeP (Sd
) - 1;
583 while ((INT16
) (BytesRemain
) >= 0) {
584 Sd
->mDstBase
[Sd
->mOutBuf
++] = Sd
->mDstBase
[DataIdx
++];
585 if (Sd
->mOutBuf
>= Sd
->mOrigSize
) {
600 UefiDecompressGetInfo (
601 IN CONST VOID
*Source
,
602 IN UINT32 SourceSize
,
603 OUT UINT32
*DestinationSize
,
604 OUT UINT32
*ScratchSize
610 The internal implementation of *_DECOMPRESS_PROTOCOL.GetInfo().
614 Source - The source buffer containing the compressed data.
615 SourceSize - The size of source buffer
616 DestinationSize - The size of destination buffer.
617 ScratchSize - The size of scratch buffer.
621 RETURN_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved.
622 RETURN_INVALID_PARAMETER - The source data is corrupted
626 UINT32 CompressedSize
;
628 ASSERT (Source
!= NULL
);
629 ASSERT (DestinationSize
!= NULL
);
630 ASSERT (ScratchSize
!= NULL
);
632 *ScratchSize
= sizeof (SCRATCH_DATA
);
634 if (SourceSize
< 8) {
635 return RETURN_INVALID_PARAMETER
;
638 CopyMem (&CompressedSize
, Source
, sizeof (UINT32
));
639 CopyMem (DestinationSize
, (VOID
*)((UINT8
*)Source
+ 4), sizeof (UINT32
));
641 if (SourceSize
< (CompressedSize
+ 8)) {
642 return RETURN_INVALID_PARAMETER
;
645 return RETURN_SUCCESS
;
650 UefiTianoDecompress (
651 IN CONST VOID
*Source
,
652 IN OUT VOID
*Destination
,
653 IN OUT VOID
*Scratch
,
660 The internal implementation of *_DECOMPRESS_PROTOCOL.Decompress().
664 Source - The source buffer containing the compressed data.
665 Destination - The destination buffer to store the decompressed data
666 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
667 Version - 1 for UEFI Decompress algoruthm, 2 for Tiano Decompess algorithm
671 RETURN_SUCCESS - Decompression is successfull
672 RETURN_INVALID_PARAMETER - The source data is corrupted
676 volatile UINT32 Index
;
683 ASSERT (Source
!= NULL
);
684 ASSERT (Destination
!= NULL
);
685 ASSERT (Scratch
!= NULL
);
690 Sd
= (SCRATCH_DATA
*) Scratch
;
692 CompSize
= Src
[0] + (Src
[1] << 8) + (Src
[2] << 16) + (Src
[3] << 24);
693 OrigSize
= Src
[4] + (Src
[5] << 8) + (Src
[6] << 16) + (Src
[7] << 24);
696 // If compressed file size is 0, return
699 return RETURN_SUCCESS
;
704 for (Index
= 0; Index
< sizeof (SCRATCH_DATA
); Index
++) {
705 ((UINT8
*) Sd
)[Index
] = 0;
708 // The length of the field 'Position Set Code Length Array Size' in Block Header.
709 // For EFI 1.1 de/compression algorithm(Version 1), mPBit = 4
710 // For Tiano de/compression algorithm(Version 2), mPBit = 5
722 Sd
->mSrcBase
= (UINT8
*)Src
;
724 Sd
->mCompSize
= CompSize
;
725 Sd
->mOrigSize
= OrigSize
;
728 // Fill the first BITBUFSIZ bits
730 FillBuf (Sd
, BITBUFSIZ
);
737 if (Sd
->mBadTableFlag
!= 0) {
739 // Something wrong with the source
741 return RETURN_INVALID_PARAMETER
;
744 return RETURN_SUCCESS
;
750 IN CONST VOID
*Source
,
751 IN OUT VOID
*Destination
,
758 The internal implementation of *_DECOMPRESS_PROTOCOL.Decompress().
762 Source - The source buffer containing the compressed data.
763 Destination - The destination buffer to store the decompressed data
764 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
768 RETURN_SUCCESS - Decompression is successfull
769 RETURN_INVALID_PARAMETER - The source data is corrupted
773 return UefiTianoDecompress (Source
, Destination
, Scratch
, 1);
778 CustomDecompressGetInfo (
779 IN CONST GUID
*DecompressGuid
,
780 IN CONST VOID
*Source
,
781 IN UINT32 SourceSize
,
782 OUT UINT32
*DestinationSize
,
783 OUT UINT32
*ScratchSize
789 The internal implementation of *_DECOMPRESS_PROTOCOL.GetInfo().
792 DecompressGuid The guid matches this decompress method.
793 Source - The source buffer containing the compressed data.
794 SourceSize - The size of source buffer
795 DestinationSize - The size of destination buffer.
796 ScratchSize - The size of scratch buffer.
800 RETURN_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved.
801 RETURN_INVALID_PARAMETER - The source data is corrupted
802 RETURN_UNSUPPORTED - Decompress method is not supported.
806 if (CompareGuid (DecompressGuid
, &gTianoCustomDecompressGuid
)) {
807 return UefiDecompressGetInfo (Source
, SourceSize
, DestinationSize
, ScratchSize
);
809 return RETURN_UNSUPPORTED
;
816 IN CONST GUID
*DecompressGuid
,
817 IN CONST VOID
*Source
,
818 IN OUT VOID
*Destination
,
825 The internal implementation of *_DECOMPRESS_PROTOCOL.Decompress().
828 DecompressGuid The guid matches this decompress method.
829 Source - The source buffer containing the compressed data.
830 Destination - The destination buffer to store the decompressed data
831 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
835 RETURN_SUCCESS - Decompression is successfull
836 RETURN_INVALID_PARAMETER - The source data is corrupted
837 RETURN_UNSUPPORTED - Decompress method is not supported.
841 if (CompareGuid (DecompressGuid
, &gTianoCustomDecompressGuid
)) {
842 return UefiTianoDecompress (Source
, Destination
, Scratch
, 2);
844 return RETURN_UNSUPPORTED
;
849 Get decompress method guid list.
851 @param[in, out] AlgorithmGuidTable The decompress method guid list.
852 @param[in, out] NumberOfAlgorithms The number of decompress methods.
854 @retval RETURN_SUCCESS Get all algorithmes list successfully.
855 @retval RETURN_OUT_OF_RESOURCES Source is not enough.
860 CustomDecompressGetAlgorithms (
861 IN OUT GUID
**AlgorithmGuidTable
,
862 IN OUT UINT32
*NumberOfAlgorithms
865 ASSERT (NumberOfAlgorithms
!= NULL
);
867 if (*NumberOfAlgorithms
< 1) {
868 *NumberOfAlgorithms
= 1;
869 return RETURN_OUT_OF_RESOURCES
;
872 ASSERT (AlgorithmGuidTable
!= NULL
);
874 AlgorithmGuidTable
[0] = &gTianoCustomDecompressGuid
;
875 *NumberOfAlgorithms
= 1;
877 return RETURN_SUCCESS
;