3 Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>
4 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.
18 Decompressor. Algorithm Ported from OPSD code (Decomp.asm)
22 #include "TianoCommon.h"
23 #include EFI_PROTOCOL_DEFINITION (Decompress)
24 #include EFI_PROTOCOL_DEFINITION (TianoDecompress)
29 IN EFI_DECOMPRESS_PROTOCOL
*This
,
33 OUT UINT32
*ScratchSize
39 IN EFI_DECOMPRESS_PROTOCOL
*This
,
42 IN OUT VOID
*Destination
,
51 IN EFI_TIANO_DECOMPRESS_PROTOCOL
*This
,
55 OUT UINT32
*ScratchSize
61 IN EFI_TIANO_DECOMPRESS_PROTOCOL
*This
,
64 IN OUT VOID
*Destination
,
71 // The protocol instance
74 EFI_DECOMPRESS_PROTOCOL mEfiDecompress
= {
79 EFI_TIANO_DECOMPRESS_PROTOCOL mTianoDecompress
= {
85 InstallEfiDecompress (
86 IN OUT EFI_DECOMPRESS_PROTOCOL
**This
92 Install EFI decompress protocol.
96 This - Pointer to get decompress protocol as output
100 EFI_SUCCESS - EFI decompress protocol successfully installed.
104 *This
= &mEfiDecompress
;
109 InstallTianoDecompress (
110 EFI_TIANO_DECOMPRESS_PROTOCOL
**This
116 Install Tiano decompress protocol.
120 This - Pointer to get decompress protocol as output
124 EFI_SUCCESS - Tiano decompress protocol successfully installed.
128 *This
= &mTianoDecompress
;
132 // Decompression algorithm begins here
139 #define UINT8_MAX 0xff
141 #define BAD_TABLE - 1
144 // C: Char&Len Set; P: Position Set; T: exTra Set
146 #define NC (0xff + MAXMATCH + 2 - THRESHOLD)
150 #define MAXNP ((1U << MAXPBIT) - 1)
151 #define NT (CODE_BIT + 3)
159 UINT8
*mSrcBase
; // Starting address of compressed data
160 UINT8
*mDstBase
; // Starting address of decompressed data
171 UINT16 mBadTableFlag
;
173 UINT16 mLeft
[2 * NC
- 1];
174 UINT16 mRight
[2 * NC
- 1];
177 UINT16 mCTable
[4096];
178 UINT16 mPTTable
[256];
181 // The length of the field 'Position Set Code Length Array Size' in Block Header.
182 // For EFI 1.1 de/compression algorithm, mPBit = 4
183 // For Tiano de/compression algorithm, mPBit = 5
198 Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source.
202 Sd - The global scratch data
203 NumOfBits - The number of bits to shift and read.
209 Sd
->mBitBuf
= (UINT32
) (Sd
->mBitBuf
<< NumOfBits
);
211 while (NumOfBits
> Sd
->mBitCount
) {
213 Sd
->mBitBuf
|= (UINT32
) (Sd
->mSubBitBuf
<< (NumOfBits
= (UINT16
) (NumOfBits
- Sd
->mBitCount
)));
215 if (Sd
->mCompSize
> 0) {
217 // Get 1 byte into SubBitBuf
221 Sd
->mSubBitBuf
= Sd
->mSrcBase
[Sd
->mInBuf
++];
226 // No more bits from the source, just pad zero bit.
234 Sd
->mBitCount
= (UINT16
) (Sd
->mBitCount
- NumOfBits
);
235 Sd
->mBitBuf
|= Sd
->mSubBitBuf
>> Sd
->mBitCount
;
248 Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent
249 NumOfBits of bits from source. Returns NumOfBits of bits that are
254 Sd - The global scratch data.
255 NumOfBits - The number of bits to pop and read.
259 The bits that are popped out.
265 OutBits
= (UINT32
) (Sd
->mBitBuf
>> (BITBUFSIZ
- NumOfBits
));
267 FillBuf (Sd
, NumOfBits
);
285 Creates Huffman Code mapping table according to code length array.
289 Sd - The global scratch data
290 NumOfChar - Number of symbols in the symbol set
291 BitLen - Code length array
292 TableBits - The width of the mapping table
298 BAD_TABLE - The table is corrupted.
316 // TableBits should not be greater than 16.
318 if (TableBits
>= (sizeof (Count
)/sizeof (UINT16
))) {
319 return (UINT16
) BAD_TABLE
;
323 // Initialize Count array starting from Index 0, as there is a possibility of Count array being uninitialized.
325 for (Index
= 0; Index
<= 16; Index
++) {
329 for (Index
= 0; Index
< NumOfChar
; Index
++) {
331 // Count array index should not be greater than or equal to its size.
333 if (BitLen
[Index
] < (sizeof (Count
)/sizeof (UINT16
))) {
334 Count
[BitLen
[Index
]]++;
336 return (UINT16
) BAD_TABLE
;
343 for (Index
= 1; Index
<= 16; Index
++) {
344 Start
[Index
+ 1] = (UINT16
) (Start
[Index
] + (Count
[Index
] << (16 - Index
)));
347 if (Start
[17] != 0) {
349 return (UINT16
) BAD_TABLE
;
352 JuBits
= (UINT16
) (16 - TableBits
);
354 for (Index
= 1; Index
<= TableBits
; Index
++) {
355 Start
[Index
] >>= JuBits
;
356 Weight
[Index
] = (UINT16
) (1U << (TableBits
- Index
));
359 while (Index
<= 16) {
360 Weight
[Index
] = (UINT16
) (1U << (16 - Index
));
364 Index
= (UINT16
) (Start
[TableBits
+ 1] >> JuBits
);
367 Index3
= (UINT16
) (1U << TableBits
);
368 while (Index
!= Index3
) {
374 Mask
= (UINT16
) (1U << (15 - TableBits
));
376 for (Char
= 0; Char
< NumOfChar
; Char
++) {
379 if (Len
== 0 || Len
>= 17) {
383 NextCode
= (UINT16
) (Start
[Len
] + Weight
[Len
]);
385 if (Len
<= TableBits
) {
387 for (Index
= Start
[Len
]; Index
< NextCode
; Index
++) {
394 Pointer
= &Table
[Index3
>> JuBits
];
395 Index
= (UINT16
) (Len
- TableBits
);
399 // Avail should be lesser than size of mRight and mLeft to prevent buffer overflow.
401 if ((*Pointer
== 0) && (Avail
< sizeof (Sd
->mRight
)/sizeof (UINT16
)) && (Avail
< sizeof (Sd
->mLeft
)/sizeof (UINT16
))) {
402 Sd
->mRight
[Avail
] = Sd
->mLeft
[Avail
] = 0;
407 // *Pointer should be lesser than size of mRight and mLeft to prevent buffer overflow.
409 if ((Index3
& Mask
) && (*Pointer
< (sizeof (Sd
->mRight
)/sizeof (UINT16
)))) {
410 Pointer
= &Sd
->mRight
[*Pointer
];
411 } else if (*Pointer
< (sizeof (Sd
->mLeft
)/sizeof (UINT16
))) {
412 Pointer
= &Sd
->mLeft
[*Pointer
];
423 Start
[Len
] = NextCode
;
440 Decodes a position value.
444 Sd - the global scratch data
448 The position value decoded.
456 Val
= Sd
->mPTTable
[Sd
->mBitBuf
>> (BITBUFSIZ
- 8)];
459 Mask
= 1U << (BITBUFSIZ
- 1 - 8);
463 if (Sd
->mBitBuf
& Mask
) {
464 Val
= Sd
->mRight
[Val
];
466 Val
= Sd
->mLeft
[Val
];
470 } while (Val
>= MAXNP
);
473 // Advance what we have read
475 FillBuf (Sd
, Sd
->mPTLen
[Val
]);
479 Pos
= (UINT32
) ((1U << (Val
- 1)) + GetBits (Sd
, (UINT16
) (Val
- 1)));
497 Reads code lengths for the Extra Set or the Position Set
501 Sd - The global scratch data
502 nn - Number of symbols
503 nbit - Number of bits needed to represent nn
504 Special - The special symbol that needs to be taken care of
509 BAD_TABLE - Table is corrupted.
518 Number
= (UINT16
) GetBits (Sd
, nbit
);
520 if ((Number
> sizeof (Sd
->mPTLen
)) || (nn
> sizeof (Sd
->mPTLen
))) {
522 // Fail if Number or nn is greater than size of mPTLen
524 return (UINT16
) BAD_TABLE
;
528 CharC
= (UINT16
) GetBits (Sd
, nbit
);
530 for (Index
= 0; Index
< 256; Index
++) {
531 Sd
->mPTTable
[Index
] = CharC
;
534 for (Index
= 0; Index
< nn
; Index
++) {
535 Sd
->mPTLen
[Index
] = 0;
543 while (Index
< Number
) {
545 CharC
= (UINT16
) (Sd
->mBitBuf
>> (BITBUFSIZ
- 3));
548 Mask
= 1U << (BITBUFSIZ
- 1 - 3);
549 while (Mask
& Sd
->mBitBuf
) {
555 FillBuf (Sd
, (UINT16
) ((CharC
< 7) ? 3 : CharC
- 3));
557 Sd
->mPTLen
[Index
++] = (UINT8
) CharC
;
559 if (Index
== Special
) {
560 CharC
= (UINT16
) GetBits (Sd
, 2);
561 while ((INT16
) (--CharC
) >= 0) {
562 if (Index
>= sizeof (Sd
->mPTLen
)) {
564 // Fail if Index is greater than or equal to mPTLen
566 return (UINT16
) BAD_TABLE
;
568 Sd
->mPTLen
[Index
++] = 0;
574 Sd
->mPTLen
[Index
++] = 0;
577 return MakeTable (Sd
, nn
, Sd
->mPTLen
, 8, Sd
->mPTTable
);
589 Reads code lengths for Char&Len Set.
593 Sd - the global scratch data
604 Number
= (UINT16
) GetBits (Sd
, CBIT
);
607 CharC
= (UINT16
) GetBits (Sd
, CBIT
);
609 for (Index
= 0; Index
< NC
; Index
++) {
610 Sd
->mCLen
[Index
] = 0;
613 for (Index
= 0; Index
< 4096; Index
++) {
614 Sd
->mCTable
[Index
] = CharC
;
621 while (Index
< Number
) {
623 CharC
= Sd
->mPTTable
[Sd
->mBitBuf
>> (BITBUFSIZ
- 8)];
625 Mask
= 1U << (BITBUFSIZ
- 1 - 8);
629 if (Mask
& Sd
->mBitBuf
) {
630 CharC
= Sd
->mRight
[CharC
];
632 CharC
= Sd
->mLeft
[CharC
];
637 } while (CharC
>= NT
);
640 // Advance what we have read
642 FillBuf (Sd
, Sd
->mPTLen
[CharC
]);
648 } else if (CharC
== 1) {
649 CharC
= (UINT16
) (GetBits (Sd
, 4) + 3);
650 } else if (CharC
== 2) {
651 CharC
= (UINT16
) (GetBits (Sd
, CBIT
) + 20);
654 while ((INT16
) (--CharC
) >= 0) {
655 Sd
->mCLen
[Index
++] = 0;
660 Sd
->mCLen
[Index
++] = (UINT8
) (CharC
- 2);
666 Sd
->mCLen
[Index
++] = 0;
669 MakeTable (Sd
, NC
, Sd
->mCLen
, 12, Sd
->mCTable
);
683 Decode a character/length value.
687 Sd - The global scratch data.
698 if (Sd
->mBlockSize
== 0) {
700 // Starting a new block
702 Sd
->mBlockSize
= (UINT16
) GetBits (Sd
, 16);
703 Sd
->mBadTableFlag
= ReadPTLen (Sd
, NT
, TBIT
, 3);
704 if (Sd
->mBadTableFlag
!= 0) {
710 Sd
->mBadTableFlag
= ReadPTLen (Sd
, MAXNP
, Sd
->mPBit
, (UINT16
) (-1));
711 if (Sd
->mBadTableFlag
!= 0) {
717 Index2
= Sd
->mCTable
[Sd
->mBitBuf
>> (BITBUFSIZ
- 12)];
720 Mask
= 1U << (BITBUFSIZ
- 1 - 12);
723 if (Sd
->mBitBuf
& Mask
) {
724 Index2
= Sd
->mRight
[Index2
];
726 Index2
= Sd
->mLeft
[Index2
];
730 } while (Index2
>= NC
);
733 // Advance what we have read
735 FillBuf (Sd
, Sd
->mCLen
[Index2
]);
749 Decode the source data and put the resulting data into the destination buffer.
753 Sd - The global scratch data
763 BytesRemain
= (UINT16
) (-1);
768 CharC
= DecodeC (Sd
);
769 if (Sd
->mBadTableFlag
!= 0) {
775 // Process an Original character
777 if (Sd
->mOutBuf
>= Sd
->mOrigSize
) {
780 Sd
->mDstBase
[Sd
->mOutBuf
++] = (UINT8
) CharC
;
787 CharC
= (UINT16
) (CharC
- (UINT8_MAX
+ 1 - THRESHOLD
));
791 DataIdx
= Sd
->mOutBuf
- DecodeP (Sd
) - 1;
794 while ((INT16
) (BytesRemain
) >= 0) {
795 Sd
->mDstBase
[Sd
->mOutBuf
++] = Sd
->mDstBase
[DataIdx
++];
796 if (Sd
->mOutBuf
>= Sd
->mOrigSize
) {
811 OUT UINT32
*ScratchSize
817 The internal implementation of *_DECOMPRESS_PROTOCOL.GetInfo().
821 Source - The source buffer containing the compressed data.
822 SrcSize - The size of source buffer
823 DstSize - The size of destination buffer.
824 ScratchSize - The size of scratch buffer.
828 EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved.
829 EFI_INVALID_PARAMETER - The source data is corrupted
835 *ScratchSize
= sizeof (SCRATCH_DATA
);
839 return EFI_INVALID_PARAMETER
;
842 *DstSize
= Src
[4] + (Src
[5] << 8) + (Src
[6] << 16) + (Src
[7] << 24);
850 IN OUT VOID
*Destination
,
852 IN OUT VOID
*Scratch
,
853 IN UINT32 ScratchSize
,
860 The internal implementation of *_DECOMPRESS_PROTOCOL.Decompress().
864 Source - The source buffer containing the compressed data.
865 SrcSize - The size of source buffer
866 Destination - The destination buffer to store the decompressed data
867 DstSize - The size of destination buffer.
868 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
869 ScratchSize - The size of scratch buffer.
870 Version - The version of de/compression algorithm.
871 Version 1 for EFI 1.1 de/compression algorithm.
872 Version 2 for Tiano de/compression algorithm.
876 EFI_SUCCESS - Decompression is successfull
877 EFI_INVALID_PARAMETER - The source data is corrupted
889 Status
= EFI_SUCCESS
;
893 if (ScratchSize
< sizeof (SCRATCH_DATA
)) {
894 return EFI_INVALID_PARAMETER
;
897 Sd
= (SCRATCH_DATA
*) Scratch
;
900 return EFI_INVALID_PARAMETER
;
903 CompSize
= Src
[0] + (Src
[1] << 8) + (Src
[2] << 16) + (Src
[3] << 24);
904 OrigSize
= Src
[4] + (Src
[5] << 8) + (Src
[6] << 16) + (Src
[7] << 24);
907 // If compressed file size is 0, return
913 if (SrcSize
< CompSize
+ 8) {
914 return EFI_INVALID_PARAMETER
;
917 if (DstSize
!= OrigSize
) {
918 return EFI_INVALID_PARAMETER
;
923 for (Index
= 0; Index
< sizeof (SCRATCH_DATA
); Index
++) {
924 ((UINT8
*) Sd
)[Index
] = 0;
927 // The length of the field 'Position Set Code Length Array Size' in Block Header.
928 // For EFI 1.1 de/compression algorithm(Version 1), mPBit = 4
929 // For Tiano de/compression algorithm(Version 2), mPBit = 5
942 // Currently, only have 2 versions
944 return EFI_INVALID_PARAMETER
;
949 Sd
->mCompSize
= CompSize
;
950 Sd
->mOrigSize
= OrigSize
;
953 // Fill the first BITBUFSIZ bits
955 FillBuf (Sd
, BITBUFSIZ
);
962 if (Sd
->mBadTableFlag
!= 0) {
964 // Something wrong with the source
966 Status
= EFI_INVALID_PARAMETER
;
975 IN EFI_DECOMPRESS_PROTOCOL
*This
,
979 OUT UINT32
*ScratchSize
985 The implementation of EFI_DECOMPRESS_PROTOCOL.GetInfo().
989 This - The protocol instance pointer
990 Source - The source buffer containing the compressed data.
991 SrcSize - The size of source buffer
992 DstSize - The size of destination buffer.
993 ScratchSize - The size of scratch buffer.
997 EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved.
998 EFI_INVALID_PARAMETER - The source data is corrupted
1013 IN EFI_DECOMPRESS_PROTOCOL
*This
,
1016 IN OUT VOID
*Destination
,
1018 IN OUT VOID
*Scratch
,
1019 IN UINT32 ScratchSize
1023 Routine Description:
1025 The implementation of EFI_DECOMPRESS_PROTOCOL.Decompress().
1029 This - The protocol instance pointer
1030 Source - The source buffer containing the compressed data.
1031 SrcSize - The size of source buffer
1032 Destination - The destination buffer to store the decompressed data
1033 DstSize - The size of destination buffer.
1034 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
1035 ScratchSize - The size of scratch buffer.
1039 EFI_SUCCESS - Decompression is successfull
1040 EFI_INVALID_PARAMETER - The source data is corrupted
1045 // For EFI 1.1 de/compression algorithm, the version is 1.
1061 IN EFI_TIANO_DECOMPRESS_PROTOCOL
*This
,
1064 OUT UINT32
*DstSize
,
1065 OUT UINT32
*ScratchSize
1069 Routine Description:
1071 The implementation of EFI_TIANO_DECOMPRESS_PROTOCOL.GetInfo().
1075 This - The protocol instance pointer
1076 Source - The source buffer containing the compressed data.
1077 SrcSize - The size of source buffer
1078 DstSize - The size of destination buffer.
1079 ScratchSize - The size of scratch buffer.
1083 EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved.
1084 EFI_INVALID_PARAMETER - The source data is corrupted
1099 IN EFI_TIANO_DECOMPRESS_PROTOCOL
*This
,
1102 IN OUT VOID
*Destination
,
1104 IN OUT VOID
*Scratch
,
1105 IN UINT32 ScratchSize
1109 Routine Description:
1111 The implementation of EFI_TIANO_DECOMPRESS_PROTOCOL.Decompress().
1115 This - The protocol instance pointer
1116 Source - The source buffer containing the compressed data.
1117 SrcSize - The size of source buffer
1118 Destination - The destination buffer to store the decompressed data
1119 DstSize - The size of destination buffer.
1120 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
1121 ScratchSize - The size of scratch buffer.
1125 EFI_SUCCESS - Decompression is successfull
1126 EFI_INVALID_PARAMETER - The source data is corrupted
1131 // For Tiano de/compression algorithm, the version is 2.