]>
git.proxmox.com Git - mirror_edk2.git/blob - IntelFrameworkModulePkg/Library/BaseUefiTianoCustomDecompressLib/BaseUefiTianoCustomDecompressLib.c
acde4d503e3eb8f4619975bfcda72364643374cc
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 "BaseUefiTianoCustomDecompressLibInternals.h"
26 Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source.
30 Sd - The global scratch data
31 NumOfBits - The number of bits to shift and read.
37 Sd
->mBitBuf
= (UINT32
) (Sd
->mBitBuf
<< NumOfBits
);
39 while (NumOfBits
> Sd
->mBitCount
) {
41 Sd
->mBitBuf
|= (UINT32
) (Sd
->mSubBitBuf
<< (NumOfBits
= (UINT16
) (NumOfBits
- Sd
->mBitCount
)));
43 if (Sd
->mCompSize
> 0) {
45 // Get 1 byte into SubBitBuf
49 Sd
->mSubBitBuf
= Sd
->mSrcBase
[Sd
->mInBuf
++];
54 // No more bits from the source, just pad zero bit.
62 Sd
->mBitCount
= (UINT16
) (Sd
->mBitCount
- NumOfBits
);
63 Sd
->mBitBuf
|= Sd
->mSubBitBuf
>> Sd
->mBitCount
;
75 Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent
76 NumOfBits of bits from source. Returns NumOfBits of bits that are
81 Sd - The global scratch data.
82 NumOfBits - The number of bits to pop and read.
86 The bits that are popped out.
92 OutBits
= (UINT32
) (Sd
->mBitBuf
>> (BITBUFSIZ
- NumOfBits
));
94 FillBuf (Sd
, NumOfBits
);
111 Creates Huffman Code mapping table according to code length array.
115 Sd - The global scratch data
116 NumOfChar - Number of symbols in the symbol set
117 BitLen - Code length array
118 TableBits - The width of the mapping table
124 BAD_TABLE - The table is corrupted.
133 volatile UINT16 Index
;
143 for (Index
= 1; Index
<= 16; Index
++) {
147 for (Index
= 0; Index
< NumOfChar
; Index
++) {
148 Count
[BitLen
[Index
]]++;
153 for (Index
= 1; Index
<= 16; Index
++) {
154 WordOfStart
= Start
[Index
];
155 WordOfCount
= Count
[Index
];
156 Start
[Index
+ 1] = (UINT16
) (WordOfStart
+ (WordOfCount
<< (16 - Index
)));
159 if (Start
[17] != 0) {
161 return (UINT16
) BAD_TABLE
;
164 JuBits
= (UINT16
) (16 - TableBits
);
166 for (Index
= 1; Index
<= TableBits
; Index
++) {
167 Start
[Index
] >>= JuBits
;
168 Weight
[Index
] = (UINT16
) (1U << (TableBits
- Index
));
171 while (Index
<= 16) {
172 Weight
[Index
] = (UINT16
) (1U << (16 - Index
));
176 Index
= (UINT16
) (Start
[TableBits
+ 1] >> JuBits
);
179 Index3
= (UINT16
) (1U << TableBits
);
180 while (Index
!= Index3
) {
186 Mask
= (UINT16
) (1U << (15 - TableBits
));
188 for (Char
= 0; Char
< NumOfChar
; Char
++) {
195 NextCode
= (UINT16
) (Start
[Len
] + Weight
[Len
]);
197 if (Len
<= TableBits
) {
199 for (Index
= Start
[Len
]; Index
< NextCode
; Index
++) {
206 Pointer
= &Table
[Index3
>> JuBits
];
207 Index
= (UINT16
) (Len
- TableBits
);
211 Sd
->mRight
[Avail
] = Sd
->mLeft
[Avail
] = 0;
216 Pointer
= &Sd
->mRight
[*Pointer
];
218 Pointer
= &Sd
->mLeft
[*Pointer
];
229 Start
[Len
] = NextCode
;
245 Decodes a position value.
249 Sd - the global scratch data
253 The position value decoded.
261 Val
= Sd
->mPTTable
[Sd
->mBitBuf
>> (BITBUFSIZ
- 8)];
264 Mask
= 1U << (BITBUFSIZ
- 1 - 8);
268 if (Sd
->mBitBuf
& Mask
) {
269 Val
= Sd
->mRight
[Val
];
271 Val
= Sd
->mLeft
[Val
];
275 } while (Val
>= MAXNP
);
278 // Advance what we have read
280 FillBuf (Sd
, Sd
->mPTLen
[Val
]);
284 Pos
= (UINT32
) ((1U << (Val
- 1)) + GetBits (Sd
, (UINT16
) (Val
- 1)));
301 Reads code lengths for the Extra Set or the Position Set
305 Sd - The global scratch data
306 nn - Number of symbols
307 nbit - Number of bits needed to represent nn
308 Special - The special symbol that needs to be taken care of
313 BAD_TABLE - Table is corrupted.
319 volatile UINT16 Index
;
322 Number
= (UINT16
) GetBits (Sd
, nbit
);
325 CharC
= (UINT16
) GetBits (Sd
, nbit
);
327 for (Index
= 0; Index
< 256; Index
++) {
328 Sd
->mPTTable
[Index
] = CharC
;
331 for (Index
= 0; Index
< nn
; Index
++) {
332 Sd
->mPTLen
[Index
] = 0;
340 while (Index
< Number
) {
342 CharC
= (UINT16
) (Sd
->mBitBuf
>> (BITBUFSIZ
- 3));
345 Mask
= 1U << (BITBUFSIZ
- 1 - 3);
346 while (Mask
& Sd
->mBitBuf
) {
352 FillBuf (Sd
, (UINT16
) ((CharC
< 7) ? 3 : CharC
- 3));
354 Sd
->mPTLen
[Index
++] = (UINT8
) CharC
;
356 if (Index
== Special
) {
357 CharC
= (UINT16
) GetBits (Sd
, 2);
358 while ((INT16
) (--CharC
) >= 0) {
359 Sd
->mPTLen
[Index
++] = 0;
365 Sd
->mPTLen
[Index
++] = 0;
368 return MakeTable (Sd
, nn
, Sd
->mPTLen
, 8, Sd
->mPTTable
);
379 Reads code lengths for Char&Len Set.
383 Sd - the global scratch data
391 volatile UINT16 Index
;
394 Number
= (UINT16
) GetBits (Sd
, CBIT
);
397 CharC
= (UINT16
) GetBits (Sd
, CBIT
);
399 for (Index
= 0; Index
< NC
; Index
++) {
400 Sd
->mCLen
[Index
] = 0;
403 for (Index
= 0; Index
< 4096; Index
++) {
404 Sd
->mCTable
[Index
] = CharC
;
411 while (Index
< Number
) {
413 CharC
= Sd
->mPTTable
[Sd
->mBitBuf
>> (BITBUFSIZ
- 8)];
415 Mask
= 1U << (BITBUFSIZ
- 1 - 8);
419 if (Mask
& Sd
->mBitBuf
) {
420 CharC
= Sd
->mRight
[CharC
];
422 CharC
= Sd
->mLeft
[CharC
];
427 } while (CharC
>= NT
);
430 // Advance what we have read
432 FillBuf (Sd
, Sd
->mPTLen
[CharC
]);
438 } else if (CharC
== 1) {
439 CharC
= (UINT16
) (GetBits (Sd
, 4) + 3);
440 } else if (CharC
== 2) {
441 CharC
= (UINT16
) (GetBits (Sd
, CBIT
) + 20);
444 while ((INT16
) (--CharC
) >= 0) {
445 Sd
->mCLen
[Index
++] = 0;
450 Sd
->mCLen
[Index
++] = (UINT8
) (CharC
- 2);
456 Sd
->mCLen
[Index
++] = 0;
459 MakeTable (Sd
, NC
, Sd
->mCLen
, 12, Sd
->mCTable
);
472 Decode a character/length value.
476 Sd - The global scratch data.
487 if (Sd
->mBlockSize
== 0) {
489 // Starting a new block
491 Sd
->mBlockSize
= (UINT16
) GetBits (Sd
, 16);
492 Sd
->mBadTableFlag
= ReadPTLen (Sd
, NT
, TBIT
, 3);
493 if (Sd
->mBadTableFlag
!= 0) {
499 Sd
->mBadTableFlag
= ReadPTLen (Sd
, MAXNP
, Sd
->mPBit
, (UINT16
) (-1));
500 if (Sd
->mBadTableFlag
!= 0) {
506 Index2
= Sd
->mCTable
[Sd
->mBitBuf
>> (BITBUFSIZ
- 12)];
509 Mask
= 1U << (BITBUFSIZ
- 1 - 12);
512 if (Sd
->mBitBuf
& Mask
) {
513 Index2
= Sd
->mRight
[Index2
];
515 Index2
= Sd
->mLeft
[Index2
];
519 } while (Index2
>= NC
);
522 // Advance what we have read
524 FillBuf (Sd
, Sd
->mCLen
[Index2
]);
537 Decode the source data and put the resulting data into the destination buffer.
541 Sd - The global scratch data
551 BytesRemain
= (UINT16
) (-1);
556 CharC
= DecodeC (Sd
);
557 if (Sd
->mBadTableFlag
!= 0) {
563 // Process an Original character
565 if (Sd
->mOutBuf
>= Sd
->mOrigSize
) {
568 Sd
->mDstBase
[Sd
->mOutBuf
++] = (UINT8
) CharC
;
575 CharC
= (UINT16
) (CharC
- (UINT8_MAX
+ 1 - THRESHOLD
));
579 DataIdx
= Sd
->mOutBuf
- DecodeP (Sd
) - 1;
582 while ((INT16
) (BytesRemain
) >= 0) {
583 Sd
->mDstBase
[Sd
->mOutBuf
++] = Sd
->mDstBase
[DataIdx
++];
584 if (Sd
->mOutBuf
>= Sd
->mOrigSize
) {
599 UefiDecompressGetInfo (
600 IN CONST VOID
*Source
,
601 IN UINT32 SourceSize
,
602 OUT UINT32
*DestinationSize
,
603 OUT UINT32
*ScratchSize
609 The internal implementation of *_DECOMPRESS_PROTOCOL.GetInfo().
613 Source - The source buffer containing the compressed data.
614 SourceSize - The size of source buffer
615 DestinationSize - The size of destination buffer.
616 ScratchSize - The size of scratch buffer.
620 RETURN_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved.
621 RETURN_INVALID_PARAMETER - The source data is corrupted
625 UINT32 CompressedSize
;
627 ASSERT (Source
!= NULL
);
628 ASSERT (DestinationSize
!= NULL
);
629 ASSERT (ScratchSize
!= NULL
);
631 *ScratchSize
= sizeof (SCRATCH_DATA
);
633 if (SourceSize
< 8) {
634 return RETURN_INVALID_PARAMETER
;
637 CopyMem (&CompressedSize
, Source
, sizeof (UINT32
));
638 CopyMem (DestinationSize
, (VOID
*)((UINT8
*)Source
+ 4), sizeof (UINT32
));
640 if (SourceSize
< (CompressedSize
+ 8)) {
641 return RETURN_INVALID_PARAMETER
;
644 return RETURN_SUCCESS
;
649 UefiTianoDecompress (
650 IN CONST VOID
*Source
,
651 IN OUT VOID
*Destination
,
652 IN OUT VOID
*Scratch
,
659 The internal implementation of *_DECOMPRESS_PROTOCOL.Decompress().
663 Source - The source buffer containing the compressed data.
664 Destination - The destination buffer to store the decompressed data
665 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
666 Version - 1 for UEFI Decompress algoruthm, 2 for Tiano Decompess algorithm
670 RETURN_SUCCESS - Decompression is successfull
671 RETURN_INVALID_PARAMETER - The source data is corrupted
675 volatile UINT32 Index
;
682 ASSERT (Source
!= NULL
);
683 ASSERT (Destination
!= NULL
);
684 ASSERT (Scratch
!= NULL
);
689 Sd
= (SCRATCH_DATA
*) Scratch
;
691 CompSize
= Src
[0] + (Src
[1] << 8) + (Src
[2] << 16) + (Src
[3] << 24);
692 OrigSize
= Src
[4] + (Src
[5] << 8) + (Src
[6] << 16) + (Src
[7] << 24);
695 // If compressed file size is 0, return
698 return RETURN_SUCCESS
;
703 for (Index
= 0; Index
< sizeof (SCRATCH_DATA
); Index
++) {
704 ((UINT8
*) Sd
)[Index
] = 0;
707 // The length of the field 'Position Set Code Length Array Size' in Block Header.
708 // For EFI 1.1 de/compression algorithm(Version 1), mPBit = 4
709 // For Tiano de/compression algorithm(Version 2), mPBit = 5
721 Sd
->mSrcBase
= (UINT8
*)Src
;
723 Sd
->mCompSize
= CompSize
;
724 Sd
->mOrigSize
= OrigSize
;
727 // Fill the first BITBUFSIZ bits
729 FillBuf (Sd
, BITBUFSIZ
);
736 if (Sd
->mBadTableFlag
!= 0) {
738 // Something wrong with the source
740 return RETURN_INVALID_PARAMETER
;
743 return RETURN_SUCCESS
;
749 IN CONST VOID
*Source
,
750 IN OUT VOID
*Destination
,
757 The internal implementation of *_DECOMPRESS_PROTOCOL.Decompress().
761 Source - The source buffer containing the compressed data.
762 Destination - The destination buffer to store the decompressed data
763 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
767 RETURN_SUCCESS - Decompression is successfull
768 RETURN_INVALID_PARAMETER - The source data is corrupted
772 return UefiTianoDecompress (Source
, Destination
, Scratch
, 1);
777 CustomDecompressGetInfo (
778 IN CONST VOID
*Source
,
779 IN UINT32 SourceSize
,
780 OUT UINT32
*DestinationSize
,
781 OUT UINT32
*ScratchSize
787 The internal implementation of *_DECOMPRESS_PROTOCOL.GetInfo().
791 Source - The source buffer containing the compressed data.
792 SourceSize - The size of source buffer
793 DestinationSize - The size of destination buffer.
794 ScratchSize - The size of scratch buffer.
798 RETURN_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved.
799 RETURN_INVALID_PARAMETER - The source data is corrupted
803 return UefiDecompressGetInfo (Source
, SourceSize
, DestinationSize
, ScratchSize
);
809 IN CONST VOID
*Source
,
810 IN OUT VOID
*Destination
,
817 The internal implementation of *_DECOMPRESS_PROTOCOL.Decompress().
821 Source - The source buffer containing the compressed data.
822 Destination - The destination buffer to store the decompressed data
823 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
827 RETURN_SUCCESS - Decompression is successfull
828 RETURN_INVALID_PARAMETER - The source data is corrupted
832 return UefiTianoDecompress (Source
, Destination
, Scratch
, 2);