]>
git.proxmox.com Git - mirror_edk2.git/blob - EdkModulePkg/Library/BaseUefiTianoDecompressLib/BaseUefiTianoDecompressLib.c
3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. 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.
14 BaseUefiTianoDecompressLib.c
18 UEFI and Tiano Decompress Library
22 #include "BaseUefiTianoDecompressLibInternals.h"
33 Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source.
37 Sd - The global scratch data
38 NumOfBits - The number of bits to shift and read.
44 Sd
->mBitBuf
= (UINT32
) (Sd
->mBitBuf
<< NumOfBits
);
46 while (NumOfBits
> Sd
->mBitCount
) {
48 Sd
->mBitBuf
|= (UINT32
) (Sd
->mSubBitBuf
<< (NumOfBits
= (UINT16
) (NumOfBits
- Sd
->mBitCount
)));
50 if (Sd
->mCompSize
> 0) {
52 // Get 1 byte into SubBitBuf
56 Sd
->mSubBitBuf
= Sd
->mSrcBase
[Sd
->mInBuf
++];
61 // No more bits from the source, just pad zero bit.
69 Sd
->mBitCount
= (UINT16
) (Sd
->mBitCount
- NumOfBits
);
70 Sd
->mBitBuf
|= Sd
->mSubBitBuf
>> Sd
->mBitCount
;
82 Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent
83 NumOfBits of bits from source. Returns NumOfBits of bits that are
88 Sd - The global scratch data.
89 NumOfBits - The number of bits to pop and read.
93 The bits that are popped out.
99 OutBits
= (UINT32
) (Sd
->mBitBuf
>> (BITBUFSIZ
- NumOfBits
));
101 FillBuf (Sd
, NumOfBits
);
118 Creates Huffman Code mapping table according to code length array.
122 Sd - The global scratch data
123 NumOfChar - Number of symbols in the symbol set
124 BitLen - Code length array
125 TableBits - The width of the mapping table
131 BAD_TABLE - The table is corrupted.
140 volatile UINT16 Index
;
150 for (Index
= 1; Index
<= 16; Index
++) {
154 for (Index
= 0; Index
< NumOfChar
; Index
++) {
155 Count
[BitLen
[Index
]]++;
160 for (Index
= 1; Index
<= 16; Index
++) {
161 WordOfStart
= Start
[Index
];
162 WordOfCount
= Count
[Index
];
163 Start
[Index
+ 1] = (UINT16
) (WordOfStart
+ (WordOfCount
<< (16 - Index
)));
166 if (Start
[17] != 0) {
168 return (UINT16
) BAD_TABLE
;
171 JuBits
= (UINT16
) (16 - TableBits
);
173 for (Index
= 1; Index
<= TableBits
; Index
++) {
174 Start
[Index
] >>= JuBits
;
175 Weight
[Index
] = (UINT16
) (1U << (TableBits
- Index
));
178 while (Index
<= 16) {
179 Weight
[Index
] = (UINT16
) (1U << (16 - Index
));
183 Index
= (UINT16
) (Start
[TableBits
+ 1] >> JuBits
);
186 Index3
= (UINT16
) (1U << TableBits
);
187 while (Index
!= Index3
) {
193 Mask
= (UINT16
) (1U << (15 - TableBits
));
195 for (Char
= 0; Char
< NumOfChar
; Char
++) {
202 NextCode
= (UINT16
) (Start
[Len
] + Weight
[Len
]);
204 if (Len
<= TableBits
) {
206 for (Index
= Start
[Len
]; Index
< NextCode
; Index
++) {
213 Pointer
= &Table
[Index3
>> JuBits
];
214 Index
= (UINT16
) (Len
- TableBits
);
218 Sd
->mRight
[Avail
] = Sd
->mLeft
[Avail
] = 0;
223 Pointer
= &Sd
->mRight
[*Pointer
];
225 Pointer
= &Sd
->mLeft
[*Pointer
];
236 Start
[Len
] = NextCode
;
252 Decodes a position value.
256 Sd - the global scratch data
260 The position value decoded.
268 Val
= Sd
->mPTTable
[Sd
->mBitBuf
>> (BITBUFSIZ
- 8)];
271 Mask
= 1U << (BITBUFSIZ
- 1 - 8);
275 if (Sd
->mBitBuf
& Mask
) {
276 Val
= Sd
->mRight
[Val
];
278 Val
= Sd
->mLeft
[Val
];
282 } while (Val
>= MAXNP
);
285 // Advance what we have read
287 FillBuf (Sd
, Sd
->mPTLen
[Val
]);
291 Pos
= (UINT32
) ((1U << (Val
- 1)) + GetBits (Sd
, (UINT16
) (Val
- 1)));
308 Reads code lengths for the Extra Set or the Position Set
312 Sd - The global scratch data
313 nn - Number of symbols
314 nbit - Number of bits needed to represent nn
315 Special - The special symbol that needs to be taken care of
320 BAD_TABLE - Table is corrupted.
326 volatile UINT16 Index
;
329 Number
= (UINT16
) GetBits (Sd
, nbit
);
332 CharC
= (UINT16
) GetBits (Sd
, nbit
);
334 for (Index
= 0; Index
< 256; Index
++) {
335 Sd
->mPTTable
[Index
] = CharC
;
338 for (Index
= 0; Index
< nn
; Index
++) {
339 Sd
->mPTLen
[Index
] = 0;
347 while (Index
< Number
) {
349 CharC
= (UINT16
) (Sd
->mBitBuf
>> (BITBUFSIZ
- 3));
352 Mask
= 1U << (BITBUFSIZ
- 1 - 3);
353 while (Mask
& Sd
->mBitBuf
) {
359 FillBuf (Sd
, (UINT16
) ((CharC
< 7) ? 3 : CharC
- 3));
361 Sd
->mPTLen
[Index
++] = (UINT8
) CharC
;
363 if (Index
== Special
) {
364 CharC
= (UINT16
) GetBits (Sd
, 2);
365 while ((INT16
) (--CharC
) >= 0) {
366 Sd
->mPTLen
[Index
++] = 0;
372 Sd
->mPTLen
[Index
++] = 0;
375 return MakeTable (Sd
, nn
, Sd
->mPTLen
, 8, Sd
->mPTTable
);
386 Reads code lengths for Char&Len Set.
390 Sd - the global scratch data
398 volatile UINT16 Index
;
401 Number
= (UINT16
) GetBits (Sd
, CBIT
);
404 CharC
= (UINT16
) GetBits (Sd
, CBIT
);
406 for (Index
= 0; Index
< NC
; Index
++) {
407 Sd
->mCLen
[Index
] = 0;
410 for (Index
= 0; Index
< 4096; Index
++) {
411 Sd
->mCTable
[Index
] = CharC
;
418 while (Index
< Number
) {
420 CharC
= Sd
->mPTTable
[Sd
->mBitBuf
>> (BITBUFSIZ
- 8)];
422 Mask
= 1U << (BITBUFSIZ
- 1 - 8);
426 if (Mask
& Sd
->mBitBuf
) {
427 CharC
= Sd
->mRight
[CharC
];
429 CharC
= Sd
->mLeft
[CharC
];
434 } while (CharC
>= NT
);
437 // Advance what we have read
439 FillBuf (Sd
, Sd
->mPTLen
[CharC
]);
445 } else if (CharC
== 1) {
446 CharC
= (UINT16
) (GetBits (Sd
, 4) + 3);
447 } else if (CharC
== 2) {
448 CharC
= (UINT16
) (GetBits (Sd
, CBIT
) + 20);
451 while ((INT16
) (--CharC
) >= 0) {
452 Sd
->mCLen
[Index
++] = 0;
457 Sd
->mCLen
[Index
++] = (UINT8
) (CharC
- 2);
463 Sd
->mCLen
[Index
++] = 0;
466 MakeTable (Sd
, NC
, Sd
->mCLen
, 12, Sd
->mCTable
);
479 Decode a character/length value.
483 Sd - The global scratch data.
494 if (Sd
->mBlockSize
== 0) {
496 // Starting a new block
498 Sd
->mBlockSize
= (UINT16
) GetBits (Sd
, 16);
499 Sd
->mBadTableFlag
= ReadPTLen (Sd
, NT
, TBIT
, 3);
500 if (Sd
->mBadTableFlag
!= 0) {
506 Sd
->mBadTableFlag
= ReadPTLen (Sd
, MAXNP
, Sd
->mPBit
, (UINT16
) (-1));
507 if (Sd
->mBadTableFlag
!= 0) {
513 Index2
= Sd
->mCTable
[Sd
->mBitBuf
>> (BITBUFSIZ
- 12)];
516 Mask
= 1U << (BITBUFSIZ
- 1 - 12);
519 if (Sd
->mBitBuf
& Mask
) {
520 Index2
= Sd
->mRight
[Index2
];
522 Index2
= Sd
->mLeft
[Index2
];
526 } while (Index2
>= NC
);
529 // Advance what we have read
531 FillBuf (Sd
, Sd
->mCLen
[Index2
]);
544 Decode the source data and put the resulting data into the destination buffer.
548 Sd - The global scratch data
558 BytesRemain
= (UINT16
) (-1);
563 CharC
= DecodeC (Sd
);
564 if (Sd
->mBadTableFlag
!= 0) {
570 // Process an Original character
572 if (Sd
->mOutBuf
>= Sd
->mOrigSize
) {
575 Sd
->mDstBase
[Sd
->mOutBuf
++] = (UINT8
) CharC
;
582 CharC
= (UINT16
) (CharC
- (UINT8_MAX
+ 1 - THRESHOLD
));
586 DataIdx
= Sd
->mOutBuf
- DecodeP (Sd
) - 1;
589 while ((INT16
) (BytesRemain
) >= 0) {
590 Sd
->mDstBase
[Sd
->mOutBuf
++] = Sd
->mDstBase
[DataIdx
++];
591 if (Sd
->mOutBuf
>= Sd
->mOrigSize
) {
606 UefiDecompressGetInfo (
607 IN CONST VOID
*Source
,
608 IN UINT32 SourceSize
,
609 OUT UINT32
*DestinationSize
,
610 OUT UINT32
*ScratchSize
616 The internal implementation of *_DECOMPRESS_PROTOCOL.GetInfo().
620 Source - The source buffer containing the compressed data.
621 SourceSize - The size of source buffer
622 DestinationSize - The size of destination buffer.
623 ScratchSize - The size of scratch buffer.
627 RETURN_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved.
628 RETURN_INVALID_PARAMETER - The source data is corrupted
632 UINT32 CompressedSize
;
634 ASSERT (Source
!= NULL
);
635 ASSERT (DestinationSize
!= NULL
);
636 ASSERT (ScratchSize
!= NULL
);
638 *ScratchSize
= sizeof (SCRATCH_DATA
);
640 if (SourceSize
< 8) {
641 return RETURN_INVALID_PARAMETER
;
644 CopyMem (&CompressedSize
, Source
, sizeof (UINT32
));
645 CopyMem (DestinationSize
, (VOID
*)((UINT8
*)Source
+ 4), sizeof (UINT32
));
647 if (SourceSize
< (CompressedSize
+ 8)) {
648 return RETURN_INVALID_PARAMETER
;
651 return RETURN_SUCCESS
;
656 UefiTianoDecompress (
657 IN CONST VOID
*Source
,
658 IN OUT VOID
*Destination
,
659 IN OUT VOID
*Scratch
,
666 The internal implementation of *_DECOMPRESS_PROTOCOL.Decompress().
670 Source - The source buffer containing the compressed data.
671 Destination - The destination buffer to store the decompressed data
672 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
673 Version - 1 for UEFI Decompress algoruthm, 2 for Tiano Decompess algorithm
677 RETURN_SUCCESS - Decompression is successfull
678 RETURN_INVALID_PARAMETER - The source data is corrupted
682 volatile UINT32 Index
;
689 ASSERT (Source
!= NULL
);
690 ASSERT (Destination
!= NULL
);
691 ASSERT (Scratch
!= NULL
);
696 Sd
= (SCRATCH_DATA
*) Scratch
;
698 CompSize
= Src
[0] + (Src
[1] << 8) + (Src
[2] << 16) + (Src
[3] << 24);
699 OrigSize
= Src
[4] + (Src
[5] << 8) + (Src
[6] << 16) + (Src
[7] << 24);
702 // If compressed file size is 0, return
705 return RETURN_SUCCESS
;
710 for (Index
= 0; Index
< sizeof (SCRATCH_DATA
); Index
++) {
711 ((UINT8
*) Sd
)[Index
] = 0;
714 // The length of the field 'Position Set Code Length Array Size' in Block Header.
715 // For EFI 1.1 de/compression algorithm(Version 1), mPBit = 4
716 // For Tiano de/compression algorithm(Version 2), mPBit = 5
728 Sd
->mSrcBase
= (UINT8
*)Src
;
730 Sd
->mCompSize
= CompSize
;
731 Sd
->mOrigSize
= OrigSize
;
734 // Fill the first BITBUFSIZ bits
736 FillBuf (Sd
, BITBUFSIZ
);
743 if (Sd
->mBadTableFlag
!= 0) {
745 // Something wrong with the source
747 return RETURN_INVALID_PARAMETER
;
750 return RETURN_SUCCESS
;
756 IN CONST VOID
*Source
,
757 IN OUT VOID
*Destination
,
764 The internal implementation of *_DECOMPRESS_PROTOCOL.Decompress().
768 Source - The source buffer containing the compressed data.
769 Destination - The destination buffer to store the decompressed data
770 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
774 RETURN_SUCCESS - Decompression is successfull
775 RETURN_INVALID_PARAMETER - The source data is corrupted
779 return UefiTianoDecompress (Source
, Destination
, Scratch
, 1);
784 TianoDecompressGetInfo (
785 IN CONST VOID
*Source
,
786 IN UINT32 SourceSize
,
787 OUT UINT32
*DestinationSize
,
788 OUT UINT32
*ScratchSize
794 The internal implementation of *_DECOMPRESS_PROTOCOL.GetInfo().
798 Source - The source buffer containing the compressed data.
799 SourceSize - The size of source buffer
800 DestinationSize - The size of destination buffer.
801 ScratchSize - The size of scratch buffer.
805 RETURN_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved.
806 RETURN_INVALID_PARAMETER - The source data is corrupted
810 return UefiDecompressGetInfo (Source
, SourceSize
, DestinationSize
, ScratchSize
);
816 IN CONST VOID
*Source
,
817 IN OUT VOID
*Destination
,
824 The internal implementation of *_DECOMPRESS_PROTOCOL.Decompress().
828 Source - The source buffer containing the compressed data.
829 Destination - The destination buffer to store the decompressed data
830 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
834 RETURN_SUCCESS - Decompression is successfull
835 RETURN_INVALID_PARAMETER - The source data is corrupted
839 return UefiTianoDecompress (Source
, Destination
, Scratch
, 2);