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 BaseUefiTianoCustomDecompressLib.c
18 UEFI and Custom Decompress Library
23 // Include common header file for this module.
25 #include "CommonHeader.h"
27 #include "BaseUefiTianoCustomDecompressLibInternals.h"
38 Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source.
42 Sd - The global scratch data
43 NumOfBits - The number of bits to shift and read.
49 Sd
->mBitBuf
= (UINT32
) (Sd
->mBitBuf
<< NumOfBits
);
51 while (NumOfBits
> Sd
->mBitCount
) {
53 Sd
->mBitBuf
|= (UINT32
) (Sd
->mSubBitBuf
<< (NumOfBits
= (UINT16
) (NumOfBits
- Sd
->mBitCount
)));
55 if (Sd
->mCompSize
> 0) {
57 // Get 1 byte into SubBitBuf
61 Sd
->mSubBitBuf
= Sd
->mSrcBase
[Sd
->mInBuf
++];
66 // No more bits from the source, just pad zero bit.
74 Sd
->mBitCount
= (UINT16
) (Sd
->mBitCount
- NumOfBits
);
75 Sd
->mBitBuf
|= Sd
->mSubBitBuf
>> Sd
->mBitCount
;
87 Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent
88 NumOfBits of bits from source. Returns NumOfBits of bits that are
93 Sd - The global scratch data.
94 NumOfBits - The number of bits to pop and read.
98 The bits that are popped out.
104 OutBits
= (UINT32
) (Sd
->mBitBuf
>> (BITBUFSIZ
- NumOfBits
));
106 FillBuf (Sd
, NumOfBits
);
123 Creates Huffman Code mapping table according to code length array.
127 Sd - The global scratch data
128 NumOfChar - Number of symbols in the symbol set
129 BitLen - Code length array
130 TableBits - The width of the mapping table
136 BAD_TABLE - The table is corrupted.
145 volatile UINT16 Index
;
155 for (Index
= 1; Index
<= 16; Index
++) {
159 for (Index
= 0; Index
< NumOfChar
; Index
++) {
160 Count
[BitLen
[Index
]]++;
165 for (Index
= 1; Index
<= 16; Index
++) {
166 WordOfStart
= Start
[Index
];
167 WordOfCount
= Count
[Index
];
168 Start
[Index
+ 1] = (UINT16
) (WordOfStart
+ (WordOfCount
<< (16 - Index
)));
171 if (Start
[17] != 0) {
173 return (UINT16
) BAD_TABLE
;
176 JuBits
= (UINT16
) (16 - TableBits
);
178 for (Index
= 1; Index
<= TableBits
; Index
++) {
179 Start
[Index
] >>= JuBits
;
180 Weight
[Index
] = (UINT16
) (1U << (TableBits
- Index
));
183 while (Index
<= 16) {
184 Weight
[Index
] = (UINT16
) (1U << (16 - Index
));
188 Index
= (UINT16
) (Start
[TableBits
+ 1] >> JuBits
);
191 Index3
= (UINT16
) (1U << TableBits
);
192 while (Index
!= Index3
) {
198 Mask
= (UINT16
) (1U << (15 - TableBits
));
200 for (Char
= 0; Char
< NumOfChar
; Char
++) {
207 NextCode
= (UINT16
) (Start
[Len
] + Weight
[Len
]);
209 if (Len
<= TableBits
) {
211 for (Index
= Start
[Len
]; Index
< NextCode
; Index
++) {
218 Pointer
= &Table
[Index3
>> JuBits
];
219 Index
= (UINT16
) (Len
- TableBits
);
223 Sd
->mRight
[Avail
] = Sd
->mLeft
[Avail
] = 0;
228 Pointer
= &Sd
->mRight
[*Pointer
];
230 Pointer
= &Sd
->mLeft
[*Pointer
];
241 Start
[Len
] = NextCode
;
257 Decodes a position value.
261 Sd - the global scratch data
265 The position value decoded.
273 Val
= Sd
->mPTTable
[Sd
->mBitBuf
>> (BITBUFSIZ
- 8)];
276 Mask
= 1U << (BITBUFSIZ
- 1 - 8);
280 if (Sd
->mBitBuf
& Mask
) {
281 Val
= Sd
->mRight
[Val
];
283 Val
= Sd
->mLeft
[Val
];
287 } while (Val
>= MAXNP
);
290 // Advance what we have read
292 FillBuf (Sd
, Sd
->mPTLen
[Val
]);
296 Pos
= (UINT32
) ((1U << (Val
- 1)) + GetBits (Sd
, (UINT16
) (Val
- 1)));
313 Reads code lengths for the Extra Set or the Position Set
317 Sd - The global scratch data
318 nn - Number of symbols
319 nbit - Number of bits needed to represent nn
320 Special - The special symbol that needs to be taken care of
325 BAD_TABLE - Table is corrupted.
331 volatile UINT16 Index
;
334 Number
= (UINT16
) GetBits (Sd
, nbit
);
337 CharC
= (UINT16
) GetBits (Sd
, nbit
);
339 for (Index
= 0; Index
< 256; Index
++) {
340 Sd
->mPTTable
[Index
] = CharC
;
343 for (Index
= 0; Index
< nn
; Index
++) {
344 Sd
->mPTLen
[Index
] = 0;
352 while (Index
< Number
) {
354 CharC
= (UINT16
) (Sd
->mBitBuf
>> (BITBUFSIZ
- 3));
357 Mask
= 1U << (BITBUFSIZ
- 1 - 3);
358 while (Mask
& Sd
->mBitBuf
) {
364 FillBuf (Sd
, (UINT16
) ((CharC
< 7) ? 3 : CharC
- 3));
366 Sd
->mPTLen
[Index
++] = (UINT8
) CharC
;
368 if (Index
== Special
) {
369 CharC
= (UINT16
) GetBits (Sd
, 2);
370 while ((INT16
) (--CharC
) >= 0) {
371 Sd
->mPTLen
[Index
++] = 0;
377 Sd
->mPTLen
[Index
++] = 0;
380 return MakeTable (Sd
, nn
, Sd
->mPTLen
, 8, Sd
->mPTTable
);
391 Reads code lengths for Char&Len Set.
395 Sd - the global scratch data
403 volatile UINT16 Index
;
406 Number
= (UINT16
) GetBits (Sd
, CBIT
);
409 CharC
= (UINT16
) GetBits (Sd
, CBIT
);
411 for (Index
= 0; Index
< NC
; Index
++) {
412 Sd
->mCLen
[Index
] = 0;
415 for (Index
= 0; Index
< 4096; Index
++) {
416 Sd
->mCTable
[Index
] = CharC
;
423 while (Index
< Number
) {
425 CharC
= Sd
->mPTTable
[Sd
->mBitBuf
>> (BITBUFSIZ
- 8)];
427 Mask
= 1U << (BITBUFSIZ
- 1 - 8);
431 if (Mask
& Sd
->mBitBuf
) {
432 CharC
= Sd
->mRight
[CharC
];
434 CharC
= Sd
->mLeft
[CharC
];
439 } while (CharC
>= NT
);
442 // Advance what we have read
444 FillBuf (Sd
, Sd
->mPTLen
[CharC
]);
450 } else if (CharC
== 1) {
451 CharC
= (UINT16
) (GetBits (Sd
, 4) + 3);
452 } else if (CharC
== 2) {
453 CharC
= (UINT16
) (GetBits (Sd
, CBIT
) + 20);
456 while ((INT16
) (--CharC
) >= 0) {
457 Sd
->mCLen
[Index
++] = 0;
462 Sd
->mCLen
[Index
++] = (UINT8
) (CharC
- 2);
468 Sd
->mCLen
[Index
++] = 0;
471 MakeTable (Sd
, NC
, Sd
->mCLen
, 12, Sd
->mCTable
);
484 Decode a character/length value.
488 Sd - The global scratch data.
499 if (Sd
->mBlockSize
== 0) {
501 // Starting a new block
503 Sd
->mBlockSize
= (UINT16
) GetBits (Sd
, 16);
504 Sd
->mBadTableFlag
= ReadPTLen (Sd
, NT
, TBIT
, 3);
505 if (Sd
->mBadTableFlag
!= 0) {
511 Sd
->mBadTableFlag
= ReadPTLen (Sd
, MAXNP
, Sd
->mPBit
, (UINT16
) (-1));
512 if (Sd
->mBadTableFlag
!= 0) {
518 Index2
= Sd
->mCTable
[Sd
->mBitBuf
>> (BITBUFSIZ
- 12)];
521 Mask
= 1U << (BITBUFSIZ
- 1 - 12);
524 if (Sd
->mBitBuf
& Mask
) {
525 Index2
= Sd
->mRight
[Index2
];
527 Index2
= Sd
->mLeft
[Index2
];
531 } while (Index2
>= NC
);
534 // Advance what we have read
536 FillBuf (Sd
, Sd
->mCLen
[Index2
]);
549 Decode the source data and put the resulting data into the destination buffer.
553 Sd - The global scratch data
563 BytesRemain
= (UINT16
) (-1);
568 CharC
= DecodeC (Sd
);
569 if (Sd
->mBadTableFlag
!= 0) {
575 // Process an Original character
577 if (Sd
->mOutBuf
>= Sd
->mOrigSize
) {
580 Sd
->mDstBase
[Sd
->mOutBuf
++] = (UINT8
) CharC
;
587 CharC
= (UINT16
) (CharC
- (UINT8_MAX
+ 1 - THRESHOLD
));
591 DataIdx
= Sd
->mOutBuf
- DecodeP (Sd
) - 1;
594 while ((INT16
) (BytesRemain
) >= 0) {
595 Sd
->mDstBase
[Sd
->mOutBuf
++] = Sd
->mDstBase
[DataIdx
++];
596 if (Sd
->mOutBuf
>= Sd
->mOrigSize
) {
611 UefiDecompressGetInfo (
612 IN CONST VOID
*Source
,
613 IN UINT32 SourceSize
,
614 OUT UINT32
*DestinationSize
,
615 OUT UINT32
*ScratchSize
621 The internal implementation of *_DECOMPRESS_PROTOCOL.GetInfo().
625 Source - The source buffer containing the compressed data.
626 SourceSize - The size of source buffer
627 DestinationSize - The size of destination buffer.
628 ScratchSize - The size of scratch buffer.
632 RETURN_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved.
633 RETURN_INVALID_PARAMETER - The source data is corrupted
637 UINT32 CompressedSize
;
639 ASSERT (Source
!= NULL
);
640 ASSERT (DestinationSize
!= NULL
);
641 ASSERT (ScratchSize
!= NULL
);
643 *ScratchSize
= sizeof (SCRATCH_DATA
);
645 if (SourceSize
< 8) {
646 return RETURN_INVALID_PARAMETER
;
649 CopyMem (&CompressedSize
, Source
, sizeof (UINT32
));
650 CopyMem (DestinationSize
, (VOID
*)((UINT8
*)Source
+ 4), sizeof (UINT32
));
652 if (SourceSize
< (CompressedSize
+ 8)) {
653 return RETURN_INVALID_PARAMETER
;
656 return RETURN_SUCCESS
;
661 UefiTianoDecompress (
662 IN CONST VOID
*Source
,
663 IN OUT VOID
*Destination
,
664 IN OUT VOID
*Scratch
,
671 The internal implementation of *_DECOMPRESS_PROTOCOL.Decompress().
675 Source - The source buffer containing the compressed data.
676 Destination - The destination buffer to store the decompressed data
677 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
678 Version - 1 for UEFI Decompress algoruthm, 2 for Tiano Decompess algorithm
682 RETURN_SUCCESS - Decompression is successfull
683 RETURN_INVALID_PARAMETER - The source data is corrupted
687 volatile UINT32 Index
;
694 ASSERT (Source
!= NULL
);
695 ASSERT (Destination
!= NULL
);
696 ASSERT (Scratch
!= NULL
);
701 Sd
= (SCRATCH_DATA
*) Scratch
;
703 CompSize
= Src
[0] + (Src
[1] << 8) + (Src
[2] << 16) + (Src
[3] << 24);
704 OrigSize
= Src
[4] + (Src
[5] << 8) + (Src
[6] << 16) + (Src
[7] << 24);
707 // If compressed file size is 0, return
710 return RETURN_SUCCESS
;
715 for (Index
= 0; Index
< sizeof (SCRATCH_DATA
); Index
++) {
716 ((UINT8
*) Sd
)[Index
] = 0;
719 // The length of the field 'Position Set Code Length Array Size' in Block Header.
720 // For EFI 1.1 de/compression algorithm(Version 1), mPBit = 4
721 // For Tiano de/compression algorithm(Version 2), mPBit = 5
733 Sd
->mSrcBase
= (UINT8
*)Src
;
735 Sd
->mCompSize
= CompSize
;
736 Sd
->mOrigSize
= OrigSize
;
739 // Fill the first BITBUFSIZ bits
741 FillBuf (Sd
, BITBUFSIZ
);
748 if (Sd
->mBadTableFlag
!= 0) {
750 // Something wrong with the source
752 return RETURN_INVALID_PARAMETER
;
755 return RETURN_SUCCESS
;
761 IN CONST VOID
*Source
,
762 IN OUT VOID
*Destination
,
769 The internal implementation of *_DECOMPRESS_PROTOCOL.Decompress().
773 Source - The source buffer containing the compressed data.
774 Destination - The destination buffer to store the decompressed data
775 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
779 RETURN_SUCCESS - Decompression is successfull
780 RETURN_INVALID_PARAMETER - The source data is corrupted
784 return UefiTianoDecompress (Source
, Destination
, Scratch
, 1);
789 CustomDecompressGetInfo (
790 IN CONST VOID
*Source
,
791 IN UINT32 SourceSize
,
792 OUT UINT32
*DestinationSize
,
793 OUT UINT32
*ScratchSize
799 The internal implementation of *_DECOMPRESS_PROTOCOL.GetInfo().
803 Source - The source buffer containing the compressed data.
804 SourceSize - The size of source buffer
805 DestinationSize - The size of destination buffer.
806 ScratchSize - The size of scratch buffer.
810 RETURN_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved.
811 RETURN_INVALID_PARAMETER - The source data is corrupted
815 return UefiDecompressGetInfo (Source
, SourceSize
, DestinationSize
, ScratchSize
);
821 IN CONST VOID
*Source
,
822 IN OUT VOID
*Destination
,
829 The internal implementation of *_DECOMPRESS_PROTOCOL.Decompress().
833 Source - The source buffer containing the compressed data.
834 Destination - The destination buffer to store the decompressed data
835 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
839 RETURN_SUCCESS - Decompression is successfull
840 RETURN_INVALID_PARAMETER - The source data is corrupted
844 return UefiTianoDecompress (Source
, Destination
, Scratch
, 2);