]>
git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/C/Common/Decompress.c
2 Decompressor. Algorithm Ported from OPSD code (Decomp.asm) for Efi and Tiano
5 Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
13 #include "Decompress.h"
16 // Decompression algorithm begins here
25 // C: Char&Len Set; P: Position Set; T: exTra Set
27 #define NC (0xff + MAXMATCH + 2 - THRESHOLD)
32 #define MAXNP ((1U << MAXPBIT) - 1)
33 #define NT (CODE_BIT + 3)
41 UINT8
*mSrcBase
; // Starting address of compressed data
42 UINT8
*mDstBase
; // Starting address of decompressed data
55 UINT16 mLeft
[2 * NC
- 1];
56 UINT16 mRight
[2 * NC
- 1];
63 STATIC UINT16 mPbit
= EFIPBIT
;
75 Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source.
79 Sd - The global scratch data
80 NumOfBit - The number of bits to shift and read.
86 Sd
->mBitBuf
= (UINT32
) (((UINT64
)Sd
->mBitBuf
) << NumOfBits
);
88 while (NumOfBits
> Sd
->mBitCount
) {
90 Sd
->mBitBuf
|= (UINT32
) (((UINT64
)Sd
->mSubBitBuf
) << (NumOfBits
= (UINT16
) (NumOfBits
- Sd
->mBitCount
)));
92 if (Sd
->mCompSize
> 0) {
94 // Get 1 byte into SubBitBuf
98 Sd
->mSubBitBuf
= Sd
->mSrcBase
[Sd
->mInBuf
++];
103 // No more bits from the source, just pad zero bit.
111 Sd
->mBitCount
= (UINT16
) (Sd
->mBitCount
- NumOfBits
);
112 Sd
->mBitBuf
|= Sd
->mSubBitBuf
>> Sd
->mBitCount
;
125 Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent
126 NumOfBits of bits from source. Returns NumOfBits of bits that are
131 Sd - The global scratch data.
132 NumOfBits - The number of bits to pop and read.
136 The bits that are popped out.
142 OutBits
= (UINT32
) (Sd
->mBitBuf
>> (BITBUFSIZ
- NumOfBits
));
144 FillBuf (Sd
, NumOfBits
);
162 Creates Huffman Code mapping table according to code length array.
166 Sd - The global scratch data
167 NumOfChar - Number of symbols in the symbol set
168 BitLen - Code length array
169 TableBits - The width of the mapping table
175 BAD_TABLE - The table is corrupted.
191 UINT16 MaxTableLength
;
193 for (Index
= 1; Index
<= 16; Index
++) {
197 for (Index
= 0; Index
< NumOfChar
; Index
++) {
198 if (BitLen
[Index
] > 16) {
199 return (UINT16
) BAD_TABLE
;
201 Count
[BitLen
[Index
]]++;
206 for (Index
= 1; Index
<= 16; Index
++) {
207 Start
[Index
+ 1] = (UINT16
) (Start
[Index
] + (Count
[Index
] << (16 - Index
)));
210 if (Start
[17] != 0) {
212 return (UINT16
) BAD_TABLE
;
215 JuBits
= (UINT16
) (16 - TableBits
);
217 for (Index
= 1; Index
<= TableBits
; Index
++) {
218 Start
[Index
] >>= JuBits
;
219 Weight
[Index
] = (UINT16
) (1U << (TableBits
- Index
));
222 while (Index
<= 16) {
223 Weight
[Index
] = (UINT16
) (1U << (16 - Index
));
227 Index
= (UINT16
) (Start
[TableBits
+ 1] >> JuBits
);
230 Index3
= (UINT16
) (1U << TableBits
);
231 while (Index
!= Index3
) {
237 Mask
= (UINT16
) (1U << (15 - TableBits
));
238 MaxTableLength
= (UINT16
) (1U << TableBits
);
240 for (Char
= 0; Char
< NumOfChar
; Char
++) {
243 if (Len
== 0 || Len
>= 17) {
247 NextCode
= (UINT16
) (Start
[Len
] + Weight
[Len
]);
249 if (Len
<= TableBits
) {
251 if (Start
[Len
] >= NextCode
|| NextCode
> MaxTableLength
){
252 return (UINT16
) BAD_TABLE
;
255 for (Index
= Start
[Len
]; Index
< NextCode
; Index
++) {
262 Pointer
= &Table
[Index3
>> JuBits
];
263 Index
= (UINT16
) (Len
- TableBits
);
267 Sd
->mRight
[Avail
] = Sd
->mLeft
[Avail
] = 0;
272 Pointer
= &Sd
->mRight
[*Pointer
];
274 Pointer
= &Sd
->mLeft
[*Pointer
];
285 Start
[Len
] = NextCode
;
302 Decodes a position value.
306 Sd - the global scratch data
310 The position value decoded.
318 Val
= Sd
->mPTTable
[Sd
->mBitBuf
>> (BITBUFSIZ
- 8)];
321 Mask
= 1U << (BITBUFSIZ
- 1 - 8);
325 if (Sd
->mBitBuf
& Mask
) {
326 Val
= Sd
->mRight
[Val
];
328 Val
= Sd
->mLeft
[Val
];
332 } while (Val
>= MAXNP
);
335 // Advance what we have read
337 FillBuf (Sd
, Sd
->mPTLen
[Val
]);
341 Pos
= (UINT32
) ((1U << (Val
- 1)) + GetBits (Sd
, (UINT16
) (Val
- 1)));
359 Reads code lengths for the Extra Set or the Position Set
363 Sd - The global scratch data
364 nn - Number of symbols
365 nbit - Number of bits needed to represent nn
366 Special - The special symbol that needs to be taken care of
371 BAD_TABLE - Table is corrupted.
382 Number
= (UINT16
) GetBits (Sd
, nbit
);
385 CharC
= (UINT16
) GetBits (Sd
, nbit
);
387 for (Index
= 0; Index
< 256; Index
++) {
388 Sd
->mPTTable
[Index
] = CharC
;
391 for (Index
= 0; Index
< nn
; Index
++) {
392 Sd
->mPTLen
[Index
] = 0;
400 while (Index
< Number
&& Index
< NPT
) {
402 CharC
= (UINT16
) (Sd
->mBitBuf
>> (BITBUFSIZ
- 3));
405 Mask
= 1U << (BITBUFSIZ
- 1 - 3);
406 while (Mask
& Sd
->mBitBuf
) {
412 FillBuf (Sd
, (UINT16
) ((CharC
< 7) ? 3 : CharC
- 3));
414 Sd
->mPTLen
[Index
++] = (UINT8
) CharC
;
416 if (Index
== Special
) {
417 CharC
= (UINT16
) GetBits (Sd
, 2);
419 while ((INT16
) (CharC
) >= 0 && Index
< NPT
) {
420 Sd
->mPTLen
[Index
++] = 0;
426 while (Index
< nn
&& Index
< NPT
) {
427 Sd
->mPTLen
[Index
++] = 0;
430 return MakeTable (Sd
, nn
, Sd
->mPTLen
, 8, Sd
->mPTTable
);
442 Reads code lengths for Char&Len Set.
446 Sd - the global scratch data
457 Number
= (UINT16
) GetBits (Sd
, CBIT
);
460 CharC
= (UINT16
) GetBits (Sd
, CBIT
);
462 for (Index
= 0; Index
< NC
; Index
++) {
463 Sd
->mCLen
[Index
] = 0;
466 for (Index
= 0; Index
< 4096; Index
++) {
467 Sd
->mCTable
[Index
] = CharC
;
474 while (Index
< Number
) {
476 CharC
= Sd
->mPTTable
[Sd
->mBitBuf
>> (BITBUFSIZ
- 8)];
478 Mask
= 1U << (BITBUFSIZ
- 1 - 8);
482 if (Mask
& Sd
->mBitBuf
) {
483 CharC
= Sd
->mRight
[CharC
];
485 CharC
= Sd
->mLeft
[CharC
];
490 } while (CharC
>= NT
);
493 // Advance what we have read
495 FillBuf (Sd
, Sd
->mPTLen
[CharC
]);
501 } else if (CharC
== 1) {
502 CharC
= (UINT16
) (GetBits (Sd
, 4) + 3);
503 } else if (CharC
== 2) {
504 CharC
= (UINT16
) (GetBits (Sd
, CBIT
) + 20);
508 while ((INT16
) (CharC
) >= 0) {
509 Sd
->mCLen
[Index
++] = 0;
515 Sd
->mCLen
[Index
++] = (UINT8
) (CharC
- 2);
521 Sd
->mCLen
[Index
++] = 0;
524 MakeTable (Sd
, NC
, Sd
->mCLen
, 12, Sd
->mCTable
);
538 Decode a character/length value.
542 Sd - The global scratch data.
553 if (Sd
->mBlockSize
== 0) {
555 // Starting a new block
557 Sd
->mBlockSize
= (UINT16
) GetBits (Sd
, 16);
558 Sd
->mBadTableFlag
= ReadPTLen (Sd
, NT
, TBIT
, 3);
559 if (Sd
->mBadTableFlag
!= 0) {
565 Sd
->mBadTableFlag
= ReadPTLen (Sd
, MAXNP
, mPbit
, (UINT16
) (-1));
566 if (Sd
->mBadTableFlag
!= 0) {
572 Index2
= Sd
->mCTable
[Sd
->mBitBuf
>> (BITBUFSIZ
- 12)];
575 Mask
= 1U << (BITBUFSIZ
- 1 - 12);
578 if (Sd
->mBitBuf
& Mask
) {
579 Index2
= Sd
->mRight
[Index2
];
581 Index2
= Sd
->mLeft
[Index2
];
585 } while (Index2
>= NC
);
588 // Advance what we have read
590 FillBuf (Sd
, Sd
->mCLen
[Index2
]);
604 Decode the source data and put the resulting data into the destination buffer.
608 Sd - The global scratch data
618 BytesRemain
= (UINT16
) (-1);
623 CharC
= DecodeC (Sd
);
624 if (Sd
->mBadTableFlag
!= 0) {
630 // Process an Original character
632 Sd
->mDstBase
[Sd
->mOutBuf
++] = (UINT8
) CharC
;
633 if (Sd
->mOutBuf
>= Sd
->mOrigSize
) {
641 CharC
= (UINT16
) (CharC
- (UINT8_MAX
+ 1 - THRESHOLD
));
645 DataIdx
= Sd
->mOutBuf
- DecodeP (Sd
) - 1;
648 while ((INT16
) (BytesRemain
) >= 0) {
649 if (Sd
->mOutBuf
>= Sd
->mOrigSize
) {
652 if (DataIdx
>= Sd
->mOrigSize
) {
653 Sd
->mBadTableFlag
= (UINT16
) BAD_TABLE
;
656 Sd
->mDstBase
[Sd
->mOutBuf
++] = Sd
->mDstBase
[DataIdx
++];
661 // Once mOutBuf is fully filled, directly return
663 if (Sd
->mOutBuf
>= Sd
->mOrigSize
) {
677 OUT UINT32
*ScratchSize
683 The implementation of EFI_DECOMPRESS_PROTOCOL.GetInfo().
687 Source - The source buffer containing the compressed data.
688 SrcSize - The size of source buffer
689 DstSize - The size of destination buffer.
690 ScratchSize - The size of scratch buffer.
694 EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successfully retrieved.
695 EFI_INVALID_PARAMETER - The source data is corrupted
702 *ScratchSize
= sizeof (SCRATCH_DATA
);
706 return EFI_INVALID_PARAMETER
;
709 CompSize
= Src
[0] + (Src
[1] << 8) + (Src
[2] << 16) + (Src
[3] << 24);
710 *DstSize
= Src
[4] + (Src
[5] << 8) + (Src
[6] << 16) + (Src
[7] << 24);
712 if (SrcSize
< CompSize
+ 8 || (CompSize
+ 8) < 8) {
713 return EFI_INVALID_PARAMETER
;
723 IN OUT VOID
*Destination
,
725 IN OUT VOID
*Scratch
,
726 IN UINT32 ScratchSize
732 The implementation Efi and Tiano Decompress().
736 Source - The source buffer containing the compressed data.
737 SrcSize - The size of source buffer
738 Destination - The destination buffer to store the decompressed data
739 DstSize - The size of destination buffer.
740 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
741 ScratchSize - The size of scratch buffer.
745 EFI_SUCCESS - Decompression is successful
746 EFI_INVALID_PARAMETER - The source data is corrupted
758 Status
= EFI_SUCCESS
;
762 if (ScratchSize
< sizeof (SCRATCH_DATA
)) {
763 return EFI_INVALID_PARAMETER
;
766 Sd
= (SCRATCH_DATA
*) Scratch
;
769 return EFI_INVALID_PARAMETER
;
772 CompSize
= Src
[0] + (Src
[1] << 8) + (Src
[2] << 16) + (Src
[3] << 24);
773 OrigSize
= Src
[4] + (Src
[5] << 8) + (Src
[6] << 16) + (Src
[7] << 24);
775 if (SrcSize
< CompSize
+ 8 || (CompSize
+ 8) < 8) {
776 return EFI_INVALID_PARAMETER
;
779 if (DstSize
!= OrigSize
) {
780 return EFI_INVALID_PARAMETER
;
785 for (Index
= 0; Index
< sizeof (SCRATCH_DATA
); Index
++) {
786 ((UINT8
*) Sd
)[Index
] = 0;
791 Sd
->mCompSize
= CompSize
;
792 Sd
->mOrigSize
= OrigSize
;
795 // Fill the first BITBUFSIZ bits
797 FillBuf (Sd
, BITBUFSIZ
);
804 if (Sd
->mBadTableFlag
!= 0) {
806 // Something wrong with the source
808 Status
= EFI_INVALID_PARAMETER
;
819 OUT UINT32
*ScratchSize
825 The implementation Efi Decompress GetInfo().
829 Source - The source buffer containing the compressed data.
830 SrcSize - The size of source buffer
831 DstSize - The size of destination buffer.
832 ScratchSize - The size of scratch buffer.
836 EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successfully retrieved.
837 EFI_INVALID_PARAMETER - The source data is corrupted
841 return GetInfo (Source
, SrcSize
, DstSize
, ScratchSize
);
849 OUT UINT32
*ScratchSize
855 The implementation Tiano Decompress GetInfo().
859 Source - The source buffer containing the compressed data.
860 SrcSize - The size of source buffer
861 DstSize - The size of destination buffer.
862 ScratchSize - The size of scratch buffer.
866 EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successfully retrieved.
867 EFI_INVALID_PARAMETER - The source data is corrupted
871 return GetInfo (Source
, SrcSize
, DstSize
, ScratchSize
);
878 IN OUT VOID
*Destination
,
880 IN OUT VOID
*Scratch
,
881 IN UINT32 ScratchSize
887 The implementation of Efi Decompress().
891 Source - The source buffer containing the compressed data.
892 SrcSize - The size of source buffer
893 Destination - The destination buffer to store the decompressed data
894 DstSize - The size of destination buffer.
895 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
896 ScratchSize - The size of scratch buffer.
900 EFI_SUCCESS - Decompression is successful
901 EFI_INVALID_PARAMETER - The source data is corrupted
906 return Decompress (Source
, SrcSize
, Destination
, DstSize
, Scratch
, ScratchSize
);
913 IN OUT VOID
*Destination
,
915 IN OUT VOID
*Scratch
,
916 IN UINT32 ScratchSize
922 The implementation of Tiano Decompress().
926 Source - The source buffer containing the compressed data.
927 SrcSize - The size of source buffer
928 Destination - The destination buffer to store the decompressed data
929 DstSize - The size of destination buffer.
930 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
931 ScratchSize - The size of scratch buffer.
935 EFI_SUCCESS - Decompression is successful
936 EFI_INVALID_PARAMETER - The source data is corrupted
941 return Decompress (Source
, SrcSize
, Destination
, DstSize
, Scratch
, ScratchSize
);
948 OUT VOID
**Destination
,
958 Status
= EFI_SUCCESS
;
962 *Destination
= (VOID
*)malloc(SrcSize
);
963 if (*Destination
!= NULL
) {
964 memcpy(*Destination
, Source
, SrcSize
);
966 Status
= EFI_OUT_OF_RESOURCES
;
970 Status
= EfiGetInfo(Source
, SrcSize
, DstSize
, &ScratchSize
);
971 if (Status
== EFI_SUCCESS
) {
972 Scratch
= (VOID
*)malloc(ScratchSize
);
973 if (Scratch
== NULL
) {
974 return EFI_OUT_OF_RESOURCES
;
977 *Destination
= (VOID
*)malloc(*DstSize
);
978 if (*Destination
== NULL
) {
980 return EFI_OUT_OF_RESOURCES
;
983 Status
= EfiDecompress(Source
, SrcSize
, *Destination
, *DstSize
, Scratch
, ScratchSize
);
987 Status
= TianoGetInfo(Source
, SrcSize
, DstSize
, &ScratchSize
);
988 if (Status
== EFI_SUCCESS
) {
989 Scratch
= (VOID
*)malloc(ScratchSize
);
990 if (Scratch
== NULL
) {
991 return EFI_OUT_OF_RESOURCES
;
994 *Destination
= (VOID
*)malloc(*DstSize
);
995 if (*Destination
== NULL
) {
997 return EFI_OUT_OF_RESOURCES
;
1000 Status
= TianoDecompress(Source
, SrcSize
, *Destination
, *DstSize
, Scratch
, ScratchSize
);
1004 Status
= EFI_INVALID_PARAMETER
;
1007 if (Scratch
!= NULL
) {