3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14 BaseUefiTianoDecompressLib.c
18 UEFI and Tiano Decompress Library
23 // Decompression algorithm begins here
32 // C: Char&Len Set; P: Position Set; T: exTra Set
34 #define NC (0xff + MAXMATCH + 2 - THRESHOLD)
38 #define MAXNP ((1U << MAXPBIT) - 1)
39 #define NT (CODE_BIT + 3)
47 UINT8
*mSrcBase
; // Starting address of compressed data
48 UINT8
*mDstBase
; // Starting address of decompressed data
61 UINT16 mLeft
[2 * NC
- 1];
62 UINT16 mRight
[2 * NC
- 1];
69 // The length of the field 'Position Set Code Length Array Size' in Block Header.
70 // For EFI 1.1 de/compression algorithm, mPBit = 4
71 // For Tiano de/compression algorithm, mPBit = 5
85 Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source.
89 Sd - The global scratch data
90 NumOfBits - The number of bits to shift and read.
96 Sd
->mBitBuf
= (UINT32
) (Sd
->mBitBuf
<< NumOfBits
);
98 while (NumOfBits
> Sd
->mBitCount
) {
100 Sd
->mBitBuf
|= (UINT32
) (Sd
->mSubBitBuf
<< (NumOfBits
= (UINT16
) (NumOfBits
- Sd
->mBitCount
)));
102 if (Sd
->mCompSize
> 0) {
104 // Get 1 byte into SubBitBuf
108 Sd
->mSubBitBuf
= Sd
->mSrcBase
[Sd
->mInBuf
++];
113 // No more bits from the source, just pad zero bit.
121 Sd
->mBitCount
= (UINT16
) (Sd
->mBitCount
- NumOfBits
);
122 Sd
->mBitBuf
|= Sd
->mSubBitBuf
>> Sd
->mBitCount
;
134 Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent
135 NumOfBits of bits from source. Returns NumOfBits of bits that are
140 Sd - The global scratch data.
141 NumOfBits - The number of bits to pop and read.
145 The bits that are popped out.
151 OutBits
= (UINT32
) (Sd
->mBitBuf
>> (BITBUFSIZ
- NumOfBits
));
153 FillBuf (Sd
, NumOfBits
);
170 Creates Huffman Code mapping table according to code length array.
174 Sd - The global scratch data
175 NumOfChar - Number of symbols in the symbol set
176 BitLen - Code length array
177 TableBits - The width of the mapping table
183 BAD_TABLE - The table is corrupted.
192 volatile UINT16 Index
;
200 for (Index
= 1; Index
<= 16; Index
++) {
204 for (Index
= 0; Index
< NumOfChar
; Index
++) {
205 Count
[BitLen
[Index
]]++;
210 for (Index
= 1; Index
<= 16; Index
++) {
211 Start
[Index
+ 1] = (UINT16
) (Start
[Index
] + (Count
[Index
] << (16 - Index
)));
214 if (Start
[17] != 0) {
216 return (UINT16
) BAD_TABLE
;
219 JuBits
= (UINT16
) (16 - TableBits
);
221 for (Index
= 1; Index
<= TableBits
; Index
++) {
222 Start
[Index
] >>= JuBits
;
223 Weight
[Index
] = (UINT16
) (1U << (TableBits
- Index
));
226 while (Index
<= 16) {
227 Weight
[Index
] = (UINT16
) (1U << (16 - Index
));
231 Index
= (UINT16
) (Start
[TableBits
+ 1] >> JuBits
);
234 Index3
= (UINT16
) (1U << TableBits
);
235 while (Index
!= Index3
) {
241 Mask
= (UINT16
) (1U << (15 - TableBits
));
243 for (Char
= 0; Char
< NumOfChar
; Char
++) {
250 NextCode
= (UINT16
) (Start
[Len
] + Weight
[Len
]);
252 if (Len
<= TableBits
) {
254 for (Index
= Start
[Len
]; Index
< NextCode
; Index
++) {
261 Pointer
= &Table
[Index3
>> JuBits
];
262 Index
= (UINT16
) (Len
- TableBits
);
266 Sd
->mRight
[Avail
] = Sd
->mLeft
[Avail
] = 0;
271 Pointer
= &Sd
->mRight
[*Pointer
];
273 Pointer
= &Sd
->mLeft
[*Pointer
];
284 Start
[Len
] = NextCode
;
300 Decodes a position value.
304 Sd - the global scratch data
308 The position value decoded.
316 Val
= Sd
->mPTTable
[Sd
->mBitBuf
>> (BITBUFSIZ
- 8)];
319 Mask
= 1U << (BITBUFSIZ
- 1 - 8);
323 if (Sd
->mBitBuf
& Mask
) {
324 Val
= Sd
->mRight
[Val
];
326 Val
= Sd
->mLeft
[Val
];
330 } while (Val
>= MAXNP
);
333 // Advance what we have read
335 FillBuf (Sd
, Sd
->mPTLen
[Val
]);
339 Pos
= (UINT32
) ((1U << (Val
- 1)) + GetBits (Sd
, (UINT16
) (Val
- 1)));
356 Reads code lengths for the Extra Set or the Position Set
360 Sd - The global scratch data
361 nn - Number of symbols
362 nbit - Number of bits needed to represent nn
363 Special - The special symbol that needs to be taken care of
368 BAD_TABLE - Table is corrupted.
374 volatile UINT16 Index
;
377 Number
= (UINT16
) GetBits (Sd
, nbit
);
380 CharC
= (UINT16
) GetBits (Sd
, nbit
);
382 for (Index
= 0; Index
< 256; Index
++) {
383 Sd
->mPTTable
[Index
] = CharC
;
386 for (Index
= 0; Index
< nn
; Index
++) {
387 Sd
->mPTLen
[Index
] = 0;
395 while (Index
< Number
) {
397 CharC
= (UINT16
) (Sd
->mBitBuf
>> (BITBUFSIZ
- 3));
400 Mask
= 1U << (BITBUFSIZ
- 1 - 3);
401 while (Mask
& Sd
->mBitBuf
) {
407 FillBuf (Sd
, (UINT16
) ((CharC
< 7) ? 3 : CharC
- 3));
409 Sd
->mPTLen
[Index
++] = (UINT8
) CharC
;
411 if (Index
== Special
) {
412 CharC
= (UINT16
) GetBits (Sd
, 2);
413 while ((INT16
) (--CharC
) >= 0) {
414 Sd
->mPTLen
[Index
++] = 0;
420 Sd
->mPTLen
[Index
++] = 0;
423 return MakeTable (Sd
, nn
, Sd
->mPTLen
, 8, Sd
->mPTTable
);
434 Reads code lengths for Char&Len Set.
438 Sd - the global scratch data
446 volatile UINT16 Index
;
449 Number
= (UINT16
) GetBits (Sd
, CBIT
);
452 CharC
= (UINT16
) GetBits (Sd
, CBIT
);
454 for (Index
= 0; Index
< NC
; Index
++) {
455 Sd
->mCLen
[Index
] = 0;
458 for (Index
= 0; Index
< 4096; Index
++) {
459 Sd
->mCTable
[Index
] = CharC
;
466 while (Index
< Number
) {
468 CharC
= Sd
->mPTTable
[Sd
->mBitBuf
>> (BITBUFSIZ
- 8)];
470 Mask
= 1U << (BITBUFSIZ
- 1 - 8);
474 if (Mask
& Sd
->mBitBuf
) {
475 CharC
= Sd
->mRight
[CharC
];
477 CharC
= Sd
->mLeft
[CharC
];
482 } while (CharC
>= NT
);
485 // Advance what we have read
487 FillBuf (Sd
, Sd
->mPTLen
[CharC
]);
493 } else if (CharC
== 1) {
494 CharC
= (UINT16
) (GetBits (Sd
, 4) + 3);
495 } else if (CharC
== 2) {
496 CharC
= (UINT16
) (GetBits (Sd
, CBIT
) + 20);
499 while ((INT16
) (--CharC
) >= 0) {
500 Sd
->mCLen
[Index
++] = 0;
505 Sd
->mCLen
[Index
++] = (UINT8
) (CharC
- 2);
511 Sd
->mCLen
[Index
++] = 0;
514 MakeTable (Sd
, NC
, Sd
->mCLen
, 12, Sd
->mCTable
);
527 Decode a character/length value.
531 Sd - The global scratch data.
542 if (Sd
->mBlockSize
== 0) {
544 // Starting a new block
546 Sd
->mBlockSize
= (UINT16
) GetBits (Sd
, 16);
547 Sd
->mBadTableFlag
= ReadPTLen (Sd
, NT
, TBIT
, 3);
548 if (Sd
->mBadTableFlag
!= 0) {
554 Sd
->mBadTableFlag
= ReadPTLen (Sd
, MAXNP
, Sd
->mPBit
, (UINT16
) (-1));
555 if (Sd
->mBadTableFlag
!= 0) {
561 Index2
= Sd
->mCTable
[Sd
->mBitBuf
>> (BITBUFSIZ
- 12)];
564 Mask
= 1U << (BITBUFSIZ
- 1 - 12);
567 if (Sd
->mBitBuf
& Mask
) {
568 Index2
= Sd
->mRight
[Index2
];
570 Index2
= Sd
->mLeft
[Index2
];
574 } while (Index2
>= NC
);
577 // Advance what we have read
579 FillBuf (Sd
, Sd
->mCLen
[Index2
]);
592 Decode the source data and put the resulting data into the destination buffer.
596 Sd - The global scratch data
606 BytesRemain
= (UINT16
) (-1);
611 CharC
= DecodeC (Sd
);
612 if (Sd
->mBadTableFlag
!= 0) {
618 // Process an Original character
620 if (Sd
->mOutBuf
>= Sd
->mOrigSize
) {
623 Sd
->mDstBase
[Sd
->mOutBuf
++] = (UINT8
) CharC
;
630 CharC
= (UINT16
) (CharC
- (UINT8_MAX
+ 1 - THRESHOLD
));
634 DataIdx
= Sd
->mOutBuf
- DecodeP (Sd
) - 1;
637 while ((INT16
) (BytesRemain
) >= 0) {
638 Sd
->mDstBase
[Sd
->mOutBuf
++] = Sd
->mDstBase
[DataIdx
++];
639 if (Sd
->mOutBuf
>= Sd
->mOrigSize
) {
653 UefiDecompressGetInfo (
654 IN CONST VOID
*Source
,
655 IN UINT32 SourceSize
,
656 OUT UINT32
*DestinationSize
,
657 OUT UINT32
*ScratchSize
663 The internal implementation of *_DECOMPRESS_PROTOCOL.GetInfo().
667 Source - The source buffer containing the compressed data.
668 SourceSize - The size of source buffer
669 DestinationSize - The size of destination buffer.
670 ScratchSize - The size of scratch buffer.
674 RETURN_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved.
675 RETURN_INVALID_PARAMETER - The source data is corrupted
679 UINT32 CompressedSize
;
681 ASSERT (Source
!= NULL
);
682 ASSERT (DestinationSize
!= NULL
);
683 ASSERT (ScratchSize
!= NULL
);
685 *ScratchSize
= sizeof (SCRATCH_DATA
);
687 if (SourceSize
< 8) {
688 return RETURN_INVALID_PARAMETER
;
691 CopyMem (&CompressedSize
, Source
, sizeof (UINT32
));
692 CopyMem (DestinationSize
, (VOID
*)((UINT8
*)Source
+ 4), sizeof (UINT32
));
694 if (SourceSize
< (CompressedSize
+ 8)) {
695 return RETURN_INVALID_PARAMETER
;
698 return RETURN_SUCCESS
;
703 UefiTianoDecompress (
704 IN CONST VOID
*Source
,
705 IN OUT VOID
*Destination
,
706 IN OUT VOID
*Scratch
,
713 The internal implementation of *_DECOMPRESS_PROTOCOL.Decompress().
717 Source - The source buffer containing the compressed data.
718 Destination - The destination buffer to store the decompressed data
719 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
720 Version - 1 for UEFI Decompress algoruthm, 2 for Tiano Decompess algorithm
724 RETURN_SUCCESS - Decompression is successfull
725 RETURN_INVALID_PARAMETER - The source data is corrupted
729 volatile UINT32 Index
;
736 ASSERT (Source
!= NULL
);
737 ASSERT (Destination
!= NULL
);
738 ASSERT (Scratch
!= NULL
);
743 Sd
= (SCRATCH_DATA
*) Scratch
;
745 CompSize
= Src
[0] + (Src
[1] << 8) + (Src
[2] << 16) + (Src
[3] << 24);
746 OrigSize
= Src
[4] + (Src
[5] << 8) + (Src
[6] << 16) + (Src
[7] << 24);
749 // If compressed file size is 0, return
752 return RETURN_SUCCESS
;
757 for (Index
= 0; Index
< sizeof (SCRATCH_DATA
); Index
++) {
758 ((UINT8
*) Sd
)[Index
] = 0;
761 // The length of the field 'Position Set Code Length Array Size' in Block Header.
762 // For EFI 1.1 de/compression algorithm(Version 1), mPBit = 4
763 // For Tiano de/compression algorithm(Version 2), mPBit = 5
775 Sd
->mSrcBase
= (UINT8
*)Src
;
777 Sd
->mCompSize
= CompSize
;
778 Sd
->mOrigSize
= OrigSize
;
781 // Fill the first BITBUFSIZ bits
783 FillBuf (Sd
, BITBUFSIZ
);
790 if (Sd
->mBadTableFlag
!= 0) {
792 // Something wrong with the source
794 return RETURN_INVALID_PARAMETER
;
797 return RETURN_SUCCESS
;
803 IN CONST VOID
*Source
,
804 IN OUT VOID
*Destination
,
811 The internal implementation of *_DECOMPRESS_PROTOCOL.Decompress().
815 Source - The source buffer containing the compressed data.
816 Destination - The destination buffer to store the decompressed data
817 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
821 RETURN_SUCCESS - Decompression is successfull
822 RETURN_INVALID_PARAMETER - The source data is corrupted
826 return UefiTianoDecompress (Source
, Destination
, Scratch
, 1);
831 TianoDecompressGetInfo (
832 IN CONST VOID
*Source
,
833 IN UINT32 SourceSize
,
834 OUT UINT32
*DestinationSize
,
835 OUT UINT32
*ScratchSize
841 The internal implementation of *_DECOMPRESS_PROTOCOL.GetInfo().
845 Source - The source buffer containing the compressed data.
846 SourceSize - The size of source buffer
847 DestinationSize - The size of destination buffer.
848 ScratchSize - The size of scratch buffer.
852 RETURN_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved.
853 RETURN_INVALID_PARAMETER - The source data is corrupted
857 return UefiDecompressGetInfo (Source
, SourceSize
, DestinationSize
, ScratchSize
);
863 IN CONST VOID
*Source
,
864 IN OUT VOID
*Destination
,
871 The internal implementation of *_DECOMPRESS_PROTOCOL.Decompress().
875 Source - The source buffer containing the compressed data.
876 Destination - The destination buffer to store the decompressed data
877 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
881 RETURN_SUCCESS - Decompression is successfull
882 RETURN_INVALID_PARAMETER - The source data is corrupted
886 return UefiTianoDecompress (Source
, Destination
, Scratch
, 2);