]>
git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/C/Common/Decompress.c
33e0f0d1603abc7e40c5295dec40db7d076af9d9
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 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 #include "Decompress.h"
22 // Decompression algorithm begins here
31 // C: Char&Len Set; P: Position Set; T: exTra Set
33 #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 STATIC UINT16 mPbit
= EFIPBIT
;
81 Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source.
85 Sd - The global scratch data
86 NumOfBit - The number of bits to shift and read.
92 Sd
->mBitBuf
= (UINT32
) (((UINT64
)Sd
->mBitBuf
) << NumOfBits
);
94 while (NumOfBits
> Sd
->mBitCount
) {
96 Sd
->mBitBuf
|= (UINT32
) (((UINT64
)Sd
->mSubBitBuf
) << (NumOfBits
= (UINT16
) (NumOfBits
- Sd
->mBitCount
)));
98 if (Sd
->mCompSize
> 0) {
100 // Get 1 byte into SubBitBuf
104 Sd
->mSubBitBuf
= Sd
->mSrcBase
[Sd
->mInBuf
++];
109 // No more bits from the source, just pad zero bit.
117 Sd
->mBitCount
= (UINT16
) (Sd
->mBitCount
- NumOfBits
);
118 Sd
->mBitBuf
|= Sd
->mSubBitBuf
>> Sd
->mBitCount
;
131 Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent
132 NumOfBits of bits from source. Returns NumOfBits of bits that are
137 Sd - The global scratch data.
138 NumOfBits - The number of bits to pop and read.
142 The bits that are popped out.
148 OutBits
= (UINT32
) (Sd
->mBitBuf
>> (BITBUFSIZ
- NumOfBits
));
150 FillBuf (Sd
, NumOfBits
);
168 Creates Huffman Code mapping table according to code length array.
172 Sd - The global scratch data
173 NumOfChar - Number of symbols in the symbol set
174 BitLen - Code length array
175 TableBits - The width of the mapping table
181 BAD_TABLE - The table is corrupted.
197 UINT16 MaxTableLength
;
199 for (Index
= 1; Index
<= 16; Index
++) {
203 for (Index
= 0; Index
< NumOfChar
; Index
++) {
204 if (BitLen
[Index
] > 16) {
205 return (UINT16
) BAD_TABLE
;
207 Count
[BitLen
[Index
]]++;
212 for (Index
= 1; Index
<= 16; Index
++) {
213 Start
[Index
+ 1] = (UINT16
) (Start
[Index
] + (Count
[Index
] << (16 - Index
)));
216 if (Start
[17] != 0) {
218 return (UINT16
) BAD_TABLE
;
221 JuBits
= (UINT16
) (16 - TableBits
);
223 for (Index
= 1; Index
<= TableBits
; Index
++) {
224 Start
[Index
] >>= JuBits
;
225 Weight
[Index
] = (UINT16
) (1U << (TableBits
- Index
));
228 while (Index
<= 16) {
229 Weight
[Index
] = (UINT16
) (1U << (16 - Index
));
233 Index
= (UINT16
) (Start
[TableBits
+ 1] >> JuBits
);
236 Index3
= (UINT16
) (1U << TableBits
);
237 while (Index
!= Index3
) {
243 Mask
= (UINT16
) (1U << (15 - TableBits
));
244 MaxTableLength
= (UINT16
) (1U << TableBits
);
246 for (Char
= 0; Char
< NumOfChar
; Char
++) {
249 if (Len
== 0 || Len
>= 17) {
253 NextCode
= (UINT16
) (Start
[Len
] + Weight
[Len
]);
255 if (Len
<= TableBits
) {
257 for (Index
= Start
[Len
]; Index
< NextCode
; Index
++) {
258 if (Index
>= MaxTableLength
) {
259 return (UINT16
) BAD_TABLE
;
267 Pointer
= &Table
[Index3
>> JuBits
];
268 Index
= (UINT16
) (Len
- TableBits
);
272 Sd
->mRight
[Avail
] = Sd
->mLeft
[Avail
] = 0;
277 Pointer
= &Sd
->mRight
[*Pointer
];
279 Pointer
= &Sd
->mLeft
[*Pointer
];
290 Start
[Len
] = NextCode
;
307 Decodes a position value.
311 Sd - the global scratch data
315 The position value decoded.
323 Val
= Sd
->mPTTable
[Sd
->mBitBuf
>> (BITBUFSIZ
- 8)];
326 Mask
= 1U << (BITBUFSIZ
- 1 - 8);
330 if (Sd
->mBitBuf
& Mask
) {
331 Val
= Sd
->mRight
[Val
];
333 Val
= Sd
->mLeft
[Val
];
337 } while (Val
>= MAXNP
);
340 // Advance what we have read
342 FillBuf (Sd
, Sd
->mPTLen
[Val
]);
346 Pos
= (UINT32
) ((1U << (Val
- 1)) + GetBits (Sd
, (UINT16
) (Val
- 1)));
364 Reads code lengths for the Extra Set or the Position Set
368 Sd - The global scratch data
369 nn - Number of symbols
370 nbit - Number of bits needed to represent nn
371 Special - The special symbol that needs to be taken care of
376 BAD_TABLE - Table is corrupted.
387 Number
= (UINT16
) GetBits (Sd
, nbit
);
390 CharC
= (UINT16
) GetBits (Sd
, nbit
);
392 for (Index
= 0; Index
< 256; Index
++) {
393 Sd
->mPTTable
[Index
] = CharC
;
396 for (Index
= 0; Index
< nn
; Index
++) {
397 Sd
->mPTLen
[Index
] = 0;
405 while (Index
< Number
&& Index
< NPT
) {
407 CharC
= (UINT16
) (Sd
->mBitBuf
>> (BITBUFSIZ
- 3));
410 Mask
= 1U << (BITBUFSIZ
- 1 - 3);
411 while (Mask
& Sd
->mBitBuf
) {
417 FillBuf (Sd
, (UINT16
) ((CharC
< 7) ? 3 : CharC
- 3));
419 Sd
->mPTLen
[Index
++] = (UINT8
) CharC
;
421 if (Index
== Special
) {
422 CharC
= (UINT16
) GetBits (Sd
, 2);
424 while ((INT16
) (CharC
) >= 0 && Index
< NPT
) {
425 Sd
->mPTLen
[Index
++] = 0;
431 while (Index
< nn
&& Index
< NPT
) {
432 Sd
->mPTLen
[Index
++] = 0;
435 return MakeTable (Sd
, nn
, Sd
->mPTLen
, 8, Sd
->mPTTable
);
447 Reads code lengths for Char&Len Set.
451 Sd - the global scratch data
462 Number
= (UINT16
) GetBits (Sd
, CBIT
);
465 CharC
= (UINT16
) GetBits (Sd
, CBIT
);
467 for (Index
= 0; Index
< NC
; Index
++) {
468 Sd
->mCLen
[Index
] = 0;
471 for (Index
= 0; Index
< 4096; Index
++) {
472 Sd
->mCTable
[Index
] = CharC
;
479 while (Index
< Number
) {
481 CharC
= Sd
->mPTTable
[Sd
->mBitBuf
>> (BITBUFSIZ
- 8)];
483 Mask
= 1U << (BITBUFSIZ
- 1 - 8);
487 if (Mask
& Sd
->mBitBuf
) {
488 CharC
= Sd
->mRight
[CharC
];
490 CharC
= Sd
->mLeft
[CharC
];
495 } while (CharC
>= NT
);
498 // Advance what we have read
500 FillBuf (Sd
, Sd
->mPTLen
[CharC
]);
506 } else if (CharC
== 1) {
507 CharC
= (UINT16
) (GetBits (Sd
, 4) + 3);
508 } else if (CharC
== 2) {
509 CharC
= (UINT16
) (GetBits (Sd
, CBIT
) + 20);
513 while ((INT16
) (CharC
) >= 0) {
514 Sd
->mCLen
[Index
++] = 0;
520 Sd
->mCLen
[Index
++] = (UINT8
) (CharC
- 2);
526 Sd
->mCLen
[Index
++] = 0;
529 MakeTable (Sd
, NC
, Sd
->mCLen
, 12, Sd
->mCTable
);
543 Decode a character/length value.
547 Sd - The global scratch data.
558 if (Sd
->mBlockSize
== 0) {
560 // Starting a new block
562 Sd
->mBlockSize
= (UINT16
) GetBits (Sd
, 16);
563 Sd
->mBadTableFlag
= ReadPTLen (Sd
, NT
, TBIT
, 3);
564 if (Sd
->mBadTableFlag
!= 0) {
570 Sd
->mBadTableFlag
= ReadPTLen (Sd
, MAXNP
, mPbit
, (UINT16
) (-1));
571 if (Sd
->mBadTableFlag
!= 0) {
577 Index2
= Sd
->mCTable
[Sd
->mBitBuf
>> (BITBUFSIZ
- 12)];
580 Mask
= 1U << (BITBUFSIZ
- 1 - 12);
583 if (Sd
->mBitBuf
& Mask
) {
584 Index2
= Sd
->mRight
[Index2
];
586 Index2
= Sd
->mLeft
[Index2
];
590 } while (Index2
>= NC
);
593 // Advance what we have read
595 FillBuf (Sd
, Sd
->mCLen
[Index2
]);
609 Decode the source data and put the resulting data into the destination buffer.
613 Sd - The global scratch data
623 BytesRemain
= (UINT16
) (-1);
628 CharC
= DecodeC (Sd
);
629 if (Sd
->mBadTableFlag
!= 0) {
635 // Process an Original character
637 Sd
->mDstBase
[Sd
->mOutBuf
++] = (UINT8
) CharC
;
638 if (Sd
->mOutBuf
>= Sd
->mOrigSize
) {
646 CharC
= (UINT16
) (CharC
- (UINT8_MAX
+ 1 - THRESHOLD
));
650 DataIdx
= Sd
->mOutBuf
- DecodeP (Sd
) - 1;
653 while ((INT16
) (BytesRemain
) >= 0) {
654 if (Sd
->mOutBuf
>= Sd
->mOrigSize
) {
657 if (DataIdx
>= Sd
->mOrigSize
) {
658 Sd
->mBadTableFlag
= (UINT16
) BAD_TABLE
;
661 Sd
->mDstBase
[Sd
->mOutBuf
++] = Sd
->mDstBase
[DataIdx
++];
666 // Once mOutBuf is fully filled, directly return
668 if (Sd
->mOutBuf
>= Sd
->mOrigSize
) {
682 OUT UINT32
*ScratchSize
688 The implementation of EFI_DECOMPRESS_PROTOCOL.GetInfo().
692 Source - The source buffer containing the compressed data.
693 SrcSize - The size of source buffer
694 DstSize - The size of destination buffer.
695 ScratchSize - The size of scratch buffer.
699 EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successfully retrieved.
700 EFI_INVALID_PARAMETER - The source data is corrupted
707 *ScratchSize
= sizeof (SCRATCH_DATA
);
711 return EFI_INVALID_PARAMETER
;
714 CompSize
= Src
[0] + (Src
[1] << 8) + (Src
[2] << 16) + (Src
[3] << 24);
715 *DstSize
= Src
[4] + (Src
[5] << 8) + (Src
[6] << 16) + (Src
[7] << 24);
717 if (SrcSize
< CompSize
+ 8 || (CompSize
+ 8) < 8) {
718 return EFI_INVALID_PARAMETER
;
728 IN OUT VOID
*Destination
,
730 IN OUT VOID
*Scratch
,
731 IN UINT32 ScratchSize
737 The implementation Efi and Tiano Decompress().
741 Source - The source buffer containing the compressed data.
742 SrcSize - The size of source buffer
743 Destination - The destination buffer to store the decompressed data
744 DstSize - The size of destination buffer.
745 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
746 ScratchSize - The size of scratch buffer.
750 EFI_SUCCESS - Decompression is successfull
751 EFI_INVALID_PARAMETER - The source data is corrupted
763 Status
= EFI_SUCCESS
;
767 if (ScratchSize
< sizeof (SCRATCH_DATA
)) {
768 return EFI_INVALID_PARAMETER
;
771 Sd
= (SCRATCH_DATA
*) Scratch
;
774 return EFI_INVALID_PARAMETER
;
777 CompSize
= Src
[0] + (Src
[1] << 8) + (Src
[2] << 16) + (Src
[3] << 24);
778 OrigSize
= Src
[4] + (Src
[5] << 8) + (Src
[6] << 16) + (Src
[7] << 24);
780 if (SrcSize
< CompSize
+ 8 || (CompSize
+ 8) < 8) {
781 return EFI_INVALID_PARAMETER
;
784 if (DstSize
!= OrigSize
) {
785 return EFI_INVALID_PARAMETER
;
790 for (Index
= 0; Index
< sizeof (SCRATCH_DATA
); Index
++) {
791 ((UINT8
*) Sd
)[Index
] = 0;
796 Sd
->mCompSize
= CompSize
;
797 Sd
->mOrigSize
= OrigSize
;
800 // Fill the first BITBUFSIZ bits
802 FillBuf (Sd
, BITBUFSIZ
);
809 if (Sd
->mBadTableFlag
!= 0) {
811 // Something wrong with the source
813 Status
= EFI_INVALID_PARAMETER
;
824 OUT UINT32
*ScratchSize
830 The implementation Efi Decompress GetInfo().
834 Source - The source buffer containing the compressed data.
835 SrcSize - The size of source buffer
836 DstSize - The size of destination buffer.
837 ScratchSize - The size of scratch buffer.
841 EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successfully retrieved.
842 EFI_INVALID_PARAMETER - The source data is corrupted
846 return GetInfo (Source
, SrcSize
, DstSize
, ScratchSize
);
854 OUT UINT32
*ScratchSize
860 The implementation Tiano Decompress GetInfo().
864 Source - The source buffer containing the compressed data.
865 SrcSize - The size of source buffer
866 DstSize - The size of destination buffer.
867 ScratchSize - The size of scratch buffer.
871 EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successfully retrieved.
872 EFI_INVALID_PARAMETER - The source data is corrupted
876 return GetInfo (Source
, SrcSize
, DstSize
, ScratchSize
);
883 IN OUT VOID
*Destination
,
885 IN OUT VOID
*Scratch
,
886 IN UINT32 ScratchSize
892 The implementation of Efi Decompress().
896 Source - The source buffer containing the compressed data.
897 SrcSize - The size of source buffer
898 Destination - The destination buffer to store the decompressed data
899 DstSize - The size of destination buffer.
900 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
901 ScratchSize - The size of scratch buffer.
905 EFI_SUCCESS - Decompression is successfull
906 EFI_INVALID_PARAMETER - The source data is corrupted
911 return Decompress (Source
, SrcSize
, Destination
, DstSize
, Scratch
, ScratchSize
);
918 IN OUT VOID
*Destination
,
920 IN OUT VOID
*Scratch
,
921 IN UINT32 ScratchSize
927 The implementation of Tiano Decompress().
931 Source - The source buffer containing the compressed data.
932 SrcSize - The size of source buffer
933 Destination - The destination buffer to store the decompressed data
934 DstSize - The size of destination buffer.
935 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
936 ScratchSize - The size of scratch buffer.
940 EFI_SUCCESS - Decompression is successfull
941 EFI_INVALID_PARAMETER - The source data is corrupted
946 return Decompress (Source
, SrcSize
, Destination
, DstSize
, Scratch
, ScratchSize
);
953 OUT VOID
**Destination
,
963 Status
= EFI_SUCCESS
;
967 *Destination
= (VOID
*)malloc(SrcSize
);
968 if (*Destination
!= NULL
) {
969 memcpy(*Destination
, Source
, SrcSize
);
971 Status
= EFI_OUT_OF_RESOURCES
;
975 Status
= EfiGetInfo(Source
, SrcSize
, DstSize
, &ScratchSize
);
976 if (Status
== EFI_SUCCESS
) {
977 Scratch
= (VOID
*)malloc(ScratchSize
);
978 if (Scratch
== NULL
) {
979 return EFI_OUT_OF_RESOURCES
;
982 *Destination
= (VOID
*)malloc(*DstSize
);
983 if (*Destination
== NULL
) {
985 return EFI_OUT_OF_RESOURCES
;
988 Status
= EfiDecompress(Source
, SrcSize
, *Destination
, *DstSize
, Scratch
, ScratchSize
);
992 Status
= TianoGetInfo(Source
, SrcSize
, DstSize
, &ScratchSize
);
993 if (Status
== EFI_SUCCESS
) {
994 Scratch
= (VOID
*)malloc(ScratchSize
);
995 if (Scratch
== NULL
) {
996 return EFI_OUT_OF_RESOURCES
;
999 *Destination
= (VOID
*)malloc(*DstSize
);
1000 if (*Destination
== NULL
) {
1002 return EFI_OUT_OF_RESOURCES
;
1005 Status
= TianoDecompress(Source
, SrcSize
, *Destination
, *DstSize
, Scratch
, ScratchSize
);
1009 Status
= EFI_INVALID_PARAMETER
;
1012 if (Scratch
!= NULL
) {