3 Copyright (c) 2004 - 2008, Intel Corporation
\r
4 All rights reserved. This program and the accompanying materials
\r
5 are licensed and made available under the terms and conditions of the BSD License
\r
6 which accompanies this distribution. The full text of the license may be found at
\r
7 http://opensource.org/licenses/bsd-license.php
\r
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
\r
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
\r
18 Decompressor. Algorithm Ported from OPSD code (Decomp.asm)
\r
19 for Efi and Tiano compress algorithm.
\r
23 #include "Decompress.h"
\r
26 // Decompression algorithm begins here
\r
28 #define BITBUFSIZ 32
\r
29 #define MAXMATCH 256
\r
32 #define BAD_TABLE - 1
\r
35 // C: Char&Len Set; P: Position Set; T: exTra Set
\r
37 #define NC (0xff + MAXMATCH + 2 - THRESHOLD)
\r
42 #define MAXNP ((1U << MAXPBIT) - 1)
\r
43 #define NT (CODE_BIT + 3)
\r
51 UINT8 *mSrcBase; // Starting address of compressed data
\r
52 UINT8 *mDstBase; // Starting address of decompressed data
\r
63 UINT16 mBadTableFlag;
\r
65 UINT16 mLeft[2 * NC - 1];
\r
66 UINT16 mRight[2 * NC - 1];
\r
69 UINT16 mCTable[4096];
\r
70 UINT16 mPTTable[256];
\r
73 STATIC UINT16 mPbit = EFIPBIT;
\r
78 IN SCRATCH_DATA *Sd,
\r
83 Routine Description:
\r
85 Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source.
\r
89 Sd - The global scratch data
\r
90 NumOfBit - The number of bits to shift and read.
\r
96 Sd->mBitBuf = (UINT32) (Sd->mBitBuf << NumOfBits);
\r
98 while (NumOfBits > Sd->mBitCount) {
\r
100 Sd->mBitBuf |= (UINT32) (Sd->mSubBitBuf << (NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount)));
\r
102 if (Sd->mCompSize > 0) {
\r
104 // Get 1 byte into SubBitBuf
\r
107 Sd->mSubBitBuf = 0;
\r
108 Sd->mSubBitBuf = Sd->mSrcBase[Sd->mInBuf++];
\r
113 // No more bits from the source, just pad zero bit.
\r
115 Sd->mSubBitBuf = 0;
\r
121 Sd->mBitCount = (UINT16) (Sd->mBitCount - NumOfBits);
\r
122 Sd->mBitBuf |= Sd->mSubBitBuf >> Sd->mBitCount;
\r
128 IN SCRATCH_DATA *Sd,
\r
129 IN UINT16 NumOfBits
\r
133 Routine Description:
\r
135 Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent
\r
136 NumOfBits of bits from source. Returns NumOfBits of bits that are
\r
141 Sd - The global scratch data.
\r
142 NumOfBits - The number of bits to pop and read.
\r
146 The bits that are popped out.
\r
152 OutBits = (UINT32) (Sd->mBitBuf >> (BITBUFSIZ - NumOfBits));
\r
154 FillBuf (Sd, NumOfBits);
\r
162 IN SCRATCH_DATA *Sd,
\r
163 IN UINT16 NumOfChar,
\r
165 IN UINT16 TableBits,
\r
170 Routine Description:
\r
172 Creates Huffman Code mapping table according to code length array.
\r
176 Sd - The global scratch data
\r
177 NumOfChar - Number of symbols in the symbol set
\r
178 BitLen - Code length array
\r
179 TableBits - The width of the mapping table
\r
185 BAD_TABLE - The table is corrupted.
\r
202 for (Index = 1; Index <= 16; Index++) {
\r
206 for (Index = 0; Index < NumOfChar; Index++) {
\r
207 Count[BitLen[Index]]++;
\r
212 for (Index = 1; Index <= 16; Index++) {
\r
213 Start[Index + 1] = (UINT16) (Start[Index] + (Count[Index] << (16 - Index)));
\r
216 if (Start[17] != 0) {
\r
218 return (UINT16) BAD_TABLE;
\r
221 JuBits = (UINT16) (16 - TableBits);
\r
223 for (Index = 1; Index <= TableBits; Index++) {
\r
224 Start[Index] >>= JuBits;
\r
225 Weight[Index] = (UINT16) (1U << (TableBits - Index));
\r
228 while (Index <= 16) {
\r
229 Weight[Index++] = (UINT16) (1U << (16 - Index));
\r
232 Index = (UINT16) (Start[TableBits + 1] >> JuBits);
\r
235 Index3 = (UINT16) (1U << TableBits);
\r
236 while (Index != Index3) {
\r
237 Table[Index++] = 0;
\r
242 Mask = (UINT16) (1U << (15 - TableBits));
\r
244 for (Char = 0; Char < NumOfChar; Char++) {
\r
246 Len = BitLen[Char];
\r
251 NextCode = (UINT16) (Start[Len] + Weight[Len]);
\r
253 if (Len <= TableBits) {
\r
255 for (Index = Start[Len]; Index < NextCode; Index++) {
\r
256 Table[Index] = Char;
\r
261 Index3 = Start[Len];
\r
262 Pointer = &Table[Index3 >> JuBits];
\r
263 Index = (UINT16) (Len - TableBits);
\r
265 while (Index != 0) {
\r
266 if (*Pointer == 0) {
\r
267 Sd->mRight[Avail] = Sd->mLeft[Avail] = 0;
\r
268 *Pointer = Avail++;
\r
271 if (Index3 & Mask) {
\r
272 Pointer = &Sd->mRight[*Pointer];
\r
274 Pointer = &Sd->mLeft[*Pointer];
\r
285 Start[Len] = NextCode;
\r
296 IN SCRATCH_DATA *Sd
\r
300 Routine Description:
\r
302 Decodes a position value.
\r
306 Sd - the global scratch data
\r
310 The position value decoded.
\r
318 Val = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];
\r
320 if (Val >= MAXNP) {
\r
321 Mask = 1U << (BITBUFSIZ - 1 - 8);
\r
325 if (Sd->mBitBuf & Mask) {
\r
326 Val = Sd->mRight[Val];
\r
328 Val = Sd->mLeft[Val];
\r
332 } while (Val >= MAXNP);
\r
335 // Advance what we have read
\r
337 FillBuf (Sd, Sd->mPTLen[Val]);
\r
341 Pos = (UINT32) ((1U << (Val - 1)) + GetBits (Sd, (UINT16) (Val - 1)));
\r
350 IN SCRATCH_DATA *Sd,
\r
357 Routine Description:
\r
359 Reads code lengths for the Extra Set or the Position Set
\r
363 Sd - The global scratch data
\r
364 nn - Number of symbols
\r
365 nbit - Number of bits needed to represent nn
\r
366 Special - The special symbol that needs to be taken care of
\r
371 BAD_TABLE - Table is corrupted.
\r
380 Number = (UINT16) GetBits (Sd, nbit);
\r
383 CharC = (UINT16) GetBits (Sd, nbit);
\r
385 for (Index = 0; Index < 256; Index++) {
\r
386 Sd->mPTTable[Index] = CharC;
\r
389 for (Index = 0; Index < nn; Index++) {
\r
390 Sd->mPTLen[Index] = 0;
\r
398 while (Index < Number) {
\r
400 CharC = (UINT16) (Sd->mBitBuf >> (BITBUFSIZ - 3));
\r
403 Mask = 1U << (BITBUFSIZ - 1 - 3);
\r
404 while (Mask & Sd->mBitBuf) {
\r
410 FillBuf (Sd, (UINT16) ((CharC < 7) ? 3 : CharC - 3));
\r
412 Sd->mPTLen[Index++] = (UINT8) CharC;
\r
414 if (Index == Special) {
\r
415 CharC = (UINT16) GetBits (Sd, 2);
\r
417 while ((INT16) (CharC) >= 0) {
\r
418 Sd->mPTLen[Index++] = 0;
\r
424 while (Index < nn) {
\r
425 Sd->mPTLen[Index++] = 0;
\r
428 return MakeTable (Sd, nn, Sd->mPTLen, 8, Sd->mPTTable);
\r
438 Routine Description:
\r
440 Reads code lengths for Char&Len Set.
\r
444 Sd - the global scratch data
\r
455 Number = (UINT16) GetBits (Sd, CBIT);
\r
458 CharC = (UINT16) GetBits (Sd, CBIT);
\r
460 for (Index = 0; Index < NC; Index++) {
\r
461 Sd->mCLen[Index] = 0;
\r
464 for (Index = 0; Index < 4096; Index++) {
\r
465 Sd->mCTable[Index] = CharC;
\r
472 while (Index < Number) {
\r
474 CharC = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];
\r
476 Mask = 1U << (BITBUFSIZ - 1 - 8);
\r
480 if (Mask & Sd->mBitBuf) {
\r
481 CharC = Sd->mRight[CharC];
\r
483 CharC = Sd->mLeft[CharC];
\r
488 } while (CharC >= NT);
\r
491 // Advance what we have read
\r
493 FillBuf (Sd, Sd->mPTLen[CharC]);
\r
499 } else if (CharC == 1) {
\r
500 CharC = (UINT16) (GetBits (Sd, 4) + 3);
\r
501 } else if (CharC == 2) {
\r
502 CharC = (UINT16) (GetBits (Sd, CBIT) + 20);
\r
506 while ((INT16) (CharC) >= 0) {
\r
507 Sd->mCLen[Index++] = 0;
\r
513 Sd->mCLen[Index++] = (UINT8) (CharC - 2);
\r
518 while (Index < NC) {
\r
519 Sd->mCLen[Index++] = 0;
\r
522 MakeTable (Sd, NC, Sd->mCLen, 12, Sd->mCTable);
\r
534 Routine Description:
\r
536 Decode a character/length value.
\r
540 Sd - The global scratch data.
\r
551 if (Sd->mBlockSize == 0) {
\r
553 // Starting a new block
\r
555 Sd->mBlockSize = (UINT16) GetBits (Sd, 16);
\r
556 Sd->mBadTableFlag = ReadPTLen (Sd, NT, TBIT, 3);
\r
557 if (Sd->mBadTableFlag != 0) {
\r
563 Sd->mBadTableFlag = ReadPTLen (Sd, MAXNP, mPbit, (UINT16) (-1));
\r
564 if (Sd->mBadTableFlag != 0) {
\r
570 Index2 = Sd->mCTable[Sd->mBitBuf >> (BITBUFSIZ - 12)];
\r
572 if (Index2 >= NC) {
\r
573 Mask = 1U << (BITBUFSIZ - 1 - 12);
\r
576 if (Sd->mBitBuf & Mask) {
\r
577 Index2 = Sd->mRight[Index2];
\r
579 Index2 = Sd->mLeft[Index2];
\r
583 } while (Index2 >= NC);
\r
586 // Advance what we have read
\r
588 FillBuf (Sd, Sd->mCLen[Index2]);
\r
600 Routine Description:
\r
602 Decode the source data and put the resulting data into the destination buffer.
\r
606 Sd - The global scratch data
\r
612 UINT16 BytesRemain;
\r
616 BytesRemain = (UINT16) (-1);
\r
621 CharC = DecodeC (Sd);
\r
622 if (Sd->mBadTableFlag != 0) {
\r
628 // Process an Original character
\r
630 Sd->mDstBase[Sd->mOutBuf++] = (UINT8) CharC;
\r
631 if (Sd->mOutBuf >= Sd->mOrigSize) {
\r
637 // Process a Pointer
\r
639 CharC = (UINT16) (CharC - (UINT8_MAX + 1 - THRESHOLD));
\r
641 BytesRemain = CharC;
\r
643 DataIdx = Sd->mOutBuf - DecodeP (Sd) - 1;
\r
646 while ((INT16) (BytesRemain) >= 0) {
\r
647 Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];
\r
648 if (Sd->mOutBuf >= Sd->mOrigSize) {
\r
664 OUT UINT32 *DstSize,
\r
665 OUT UINT32 *ScratchSize
\r
669 Routine Description:
\r
671 The implementation of EFI_DECOMPRESS_PROTOCOL.GetInfo().
\r
675 Source - The source buffer containing the compressed data.
\r
676 SrcSize - The size of source buffer
\r
677 DstSize - The size of destination buffer.
\r
678 ScratchSize - The size of scratch buffer.
\r
682 EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved.
\r
683 EFI_INVALID_PARAMETER - The source data is corrupted
\r
689 *ScratchSize = sizeof (SCRATCH_DATA);
\r
693 return EFI_INVALID_PARAMETER;
\r
696 *DstSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);
\r
697 return EFI_SUCCESS;
\r
704 IN OUT VOID *Destination,
\r
706 IN OUT VOID *Scratch,
\r
707 IN UINT32 ScratchSize
\r
711 Routine Description:
\r
713 The implementation Efi and Tiano Decompress().
\r
717 Source - The source buffer containing the compressed data.
\r
718 SrcSize - The size of source buffer
\r
719 Destination - The destination buffer to store the decompressed data
\r
720 DstSize - The size of destination buffer.
\r
721 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
\r
722 ScratchSize - The size of scratch buffer.
\r
726 EFI_SUCCESS - Decompression is successfull
\r
727 EFI_INVALID_PARAMETER - The source data is corrupted
\r
739 Status = EFI_SUCCESS;
\r
743 if (ScratchSize < sizeof (SCRATCH_DATA)) {
\r
744 return EFI_INVALID_PARAMETER;
\r
747 Sd = (SCRATCH_DATA *) Scratch;
\r
750 return EFI_INVALID_PARAMETER;
\r
753 CompSize = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);
\r
754 OrigSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);
\r
756 if (SrcSize < CompSize + 8) {
\r
757 return EFI_INVALID_PARAMETER;
\r
760 if (DstSize != OrigSize) {
\r
761 return EFI_INVALID_PARAMETER;
\r
766 for (Index = 0; Index < sizeof (SCRATCH_DATA); Index++) {
\r
767 ((UINT8 *) Sd)[Index] = 0;
\r
770 Sd->mSrcBase = Src;
\r
771 Sd->mDstBase = Dst;
\r
772 Sd->mCompSize = CompSize;
\r
773 Sd->mOrigSize = OrigSize;
\r
776 // Fill the first BITBUFSIZ bits
\r
778 FillBuf (Sd, BITBUFSIZ);
\r
785 if (Sd->mBadTableFlag != 0) {
\r
787 // Something wrong with the source
\r
789 Status = EFI_INVALID_PARAMETER;
\r
799 OUT UINT32 *DstSize,
\r
800 OUT UINT32 *ScratchSize
\r
804 Routine Description:
\r
806 The implementation Efi Decompress GetInfo().
\r
810 Source - The source buffer containing the compressed data.
\r
811 SrcSize - The size of source buffer
\r
812 DstSize - The size of destination buffer.
\r
813 ScratchSize - The size of scratch buffer.
\r
817 EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved.
\r
818 EFI_INVALID_PARAMETER - The source data is corrupted
\r
822 return GetInfo (Source, SrcSize, DstSize, ScratchSize);
\r
829 OUT UINT32 *DstSize,
\r
830 OUT UINT32 *ScratchSize
\r
834 Routine Description:
\r
836 The implementation Tiano Decompress GetInfo().
\r
840 Source - The source buffer containing the compressed data.
\r
841 SrcSize - The size of source buffer
\r
842 DstSize - The size of destination buffer.
\r
843 ScratchSize - The size of scratch buffer.
\r
847 EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved.
\r
848 EFI_INVALID_PARAMETER - The source data is corrupted
\r
852 return GetInfo (Source, SrcSize, DstSize, ScratchSize);
\r
859 IN OUT VOID *Destination,
\r
861 IN OUT VOID *Scratch,
\r
862 IN UINT32 ScratchSize
\r
866 Routine Description:
\r
868 The implementation of Efi Decompress().
\r
872 Source - The source buffer containing the compressed data.
\r
873 SrcSize - The size of source buffer
\r
874 Destination - The destination buffer to store the decompressed data
\r
875 DstSize - The size of destination buffer.
\r
876 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
\r
877 ScratchSize - The size of scratch buffer.
\r
881 EFI_SUCCESS - Decompression is successfull
\r
882 EFI_INVALID_PARAMETER - The source data is corrupted
\r
887 return Decompress (Source, SrcSize, Destination, DstSize, Scratch, ScratchSize);
\r
894 IN OUT VOID *Destination,
\r
896 IN OUT VOID *Scratch,
\r
897 IN UINT32 ScratchSize
\r
901 Routine Description:
\r
903 The implementation of Tiano Decompress().
\r
907 Source - The source buffer containing the compressed data.
\r
908 SrcSize - The size of source buffer
\r
909 Destination - The destination buffer to store the decompressed data
\r
910 DstSize - The size of destination buffer.
\r
911 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
\r
912 ScratchSize - The size of scratch buffer.
\r
916 EFI_SUCCESS - Decompression is successfull
\r
917 EFI_INVALID_PARAMETER - The source data is corrupted
\r
922 return Decompress (Source, SrcSize, Destination, DstSize, Scratch, ScratchSize);
\r