4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/** @file
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UEFI Decompress Library implementation refer to UEFI specification.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This program and the accompanying materials
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync are licensed and made available under the terms and conditions of the BSD License
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync which accompanies this distribution. The full text of the license may be found at
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync http://opensource.org/licenses/bsd-license.php.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <Base.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <Library/BaseLib.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <Library/DebugLib.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <Library/BaseMemoryLib.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <Library/UefiDecompressLib.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include "BaseUefiDecompressLibInternals.h"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Read NumOfBit of bits from source into mBitBuf.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Sd The global scratch data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param NumOfBits The number of bits to shift and read.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncFillBuf (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN SCRATCH_DATA *Sd,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT16 NumOfBits
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Left shift NumOfBits of bits in advance
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sd->mBitBuf = (UINT32) (Sd->mBitBuf << NumOfBits);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Copy data needed in bytes into mSbuBitBuf
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (NumOfBits > Sd->mBitCount) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sd->mBitBuf |= (UINT32) (Sd->mSubBitBuf << (NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount)));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Sd->mCompSize > 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get 1 byte into SubBitBuf
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sd->mCompSize--;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sd->mSubBitBuf = Sd->mSrcBase[Sd->mInBuf++];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sd->mBitCount = 8;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // No more bits from the source, just pad zero bit.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sd->mSubBitBuf = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sd->mBitCount = 8;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Caculate additional bit count read to update mBitCount
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sd->mBitCount = (UINT16) (Sd->mBitCount - NumOfBits);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Copy NumOfBits of bits from mSubBitBuf into mBitBuf
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sd->mBitBuf |= Sd->mSubBitBuf >> Sd->mBitCount;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Get NumOfBits of bits out from mBitBuf.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NumOfBits of bits from source. Returns NumOfBits of bits that are
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync popped out.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Sd The global scratch data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param NumOfBits The number of bits to pop and read.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return The bits that are popped out.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncUINT32
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncGetBits (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN SCRATCH_DATA *Sd,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT16 NumOfBits
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 OutBits;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Pop NumOfBits of Bits from Left
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OutBits = (UINT32) (Sd->mBitBuf >> (BITBUFSIZ - NumOfBits));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Fill up mBitBuf from source
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FillBuf (Sd, NumOfBits);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return OutBits;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Creates Huffman Code mapping table according to code length array.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Creates Huffman Code mapping table for Extra Set, Char&Len Set
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync and Position Set according to code length array.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync If TableBits > 16, then ASSERT ().
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Sd The global scratch data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param NumOfChar The number of symbols in the symbol set.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BitLen Code length array.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param TableBits The width of the mapping table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Table The table to be created.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval 0 OK.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval BAD_TABLE The table is corrupted.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncUINT16
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncMakeTable (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN SCRATCH_DATA *Sd,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT16 NumOfChar,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT8 *BitLen,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT16 TableBits,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT UINT16 *Table
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 Count[17];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 Weight[17];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 Start[18];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 *Pointer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 Index3;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 Index;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 Len;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 Char;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 JuBits;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 Avail;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 NextCode;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 Mask;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 WordOfStart;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 WordOfCount;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The maximum mapping table width supported by this internal
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // working function is 16.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (TableBits <= 16);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index <= 16; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Count[Index] = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < NumOfChar; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Count[BitLen[Index]]++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Start[0] = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Start[1] = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 1; Index <= 16; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync WordOfStart = Start[Index];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync WordOfCount = Count[Index];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Start[Index + 1] = (UINT16) (WordOfStart + (WordOfCount << (16 - Index)));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Start[17] != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /*(1U << 16)*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return (UINT16) BAD_TABLE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync JuBits = (UINT16) (16 - TableBits);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Weight[0] = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 1; Index <= TableBits; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Start[Index] >>= JuBits;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Weight[Index] = (UINT16) (1U << (TableBits - Index));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (Index <= 16) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Weight[Index] = (UINT16) (1U << (16 - Index));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Index++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Index = (UINT16) (Start[TableBits + 1] >> JuBits);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Index != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Index3 = (UINT16) (1U << TableBits);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Index < Index3) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SetMem16 (Table + Index, (Index3 - Index) * sizeof (*Table), 0);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Avail = NumOfChar;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Mask = (UINT16) (1U << (15 - TableBits));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Char = 0; Char < NumOfChar; Char++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Len = BitLen[Char];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Len == 0 || Len >= 17) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NextCode = (UINT16) (Start[Len] + Weight[Len]);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Len <= TableBits) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = Start[Len]; Index < NextCode; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Table[Index] = Char;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Index3 = Start[Len];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Pointer = &Table[Index3 >> JuBits];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Index = (UINT16) (Len - TableBits);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (Index != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (*Pointer == 0 && Avail < (2 * NC - 1)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sd->mRight[Avail] = Sd->mLeft[Avail] = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *Pointer = Avail++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (*Pointer < (2 * NC - 1)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((Index3 & Mask) != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Pointer = &Sd->mRight[*Pointer];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Pointer = &Sd->mLeft[*Pointer];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Index3 <<= 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Index--;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *Pointer = Char;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Start[Len] = NextCode;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Succeeds
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Decodes a position value.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Get a position value according to Position Huffman Table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Sd The global scratch data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return The position value decoded.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncUINT32
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncDecodeP (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN SCRATCH_DATA *Sd
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 Val;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 Mask;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 Pos;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Val = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Val >= MAXNP) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Mask = 1U << (BITBUFSIZ - 1 - 8);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync do {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((Sd->mBitBuf & Mask) != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Val = Sd->mRight[Val];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Val = Sd->mLeft[Val];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Mask >>= 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } while (Val >= MAXNP);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Advance what we have read
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FillBuf (Sd, Sd->mPTLen[Val]);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Pos = Val;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Val > 1) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Pos = (UINT32) ((1U << (Val - 1)) + GetBits (Sd, (UINT16) (Val - 1)));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Pos;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Reads code lengths for the Extra Set or the Position Set.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Read in the Extra Set or Pointion Set Length Arrary, then
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync generate the Huffman code mapping for them.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Sd The global scratch data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param nn The number of symbols.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param nbit The number of bits needed to represent nn.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Special The special symbol that needs to be taken care of.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval 0 OK.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval BAD_TABLE Table is corrupted.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncUINT16
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncReadPTLen (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN SCRATCH_DATA *Sd,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT16 nn,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT16 nbit,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT16 Special
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 Number;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 CharC;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 Index;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 Mask;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Read Extra Set Code Length Array size
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Number = (UINT16) GetBits (Sd, nbit);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Number == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // This represents only Huffman code used
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CharC = (UINT16) GetBits (Sd, nbit);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SetMem16 (&Sd->mPTTable[0] , sizeof (Sd->mPTTable), CharC);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SetMem (Sd->mPTLen, nn, 0);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Index = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (Index < Number && Index < NPT) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CharC = (UINT16) (Sd->mBitBuf >> (BITBUFSIZ - 3));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If a code length is less than 7, then it is encoded as a 3-bit
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // value. Or it is encoded as a series of "1"s followed by a
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // terminating "0". The number of "1"s = Code length - 4.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (CharC == 7) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Mask = 1U << (BITBUFSIZ - 1 - 3);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (Mask & Sd->mBitBuf) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Mask >>= 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CharC += 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FillBuf (Sd, (UINT16) ((CharC < 7) ? 3 : CharC - 3));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sd->mPTLen[Index++] = (UINT8) CharC;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // For Code&Len Set,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // After the third length of the code length concatenation,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // a 2-bit value is used to indicated the number of consecutive
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // zero lengths after the third length.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Index == Special) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CharC = (UINT16) GetBits (Sd, 2);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while ((INT16) (--CharC) >= 0 && Index < NPT) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sd->mPTLen[Index++] = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (Index < nn && Index < NPT) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sd->mPTLen[Index++] = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return MakeTable (Sd, nn, Sd->mPTLen, 8, Sd->mPTTable);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Reads code lengths for Char&Len Set.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Read in and decode the Char&Len Set Code Length Array, then
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync generate the Huffman Code mapping table for the Char&Len Set.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Sd The global scratch data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncReadCLen (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SCRATCH_DATA *Sd
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 Number;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 CharC;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 Index;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 Mask;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Number = (UINT16) GetBits (Sd, CBIT);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Number == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // This represents only Huffman code used
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CharC = (UINT16) GetBits (Sd, CBIT);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SetMem (Sd->mCLen, NC, 0);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SetMem16 (&Sd->mCTable[0], sizeof (Sd->mCTable), CharC);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return ;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Index = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (Index < Number && Index < NC) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CharC = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (CharC >= NT) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Mask = 1U << (BITBUFSIZ - 1 - 8);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync do {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Mask & Sd->mBitBuf) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CharC = Sd->mRight[CharC];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CharC = Sd->mLeft[CharC];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Mask >>= 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } while (CharC >= NT);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Advance what we have read
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FillBuf (Sd, Sd->mPTLen[CharC]);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (CharC <= 2) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (CharC == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CharC = 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (CharC == 1) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CharC = (UINT16) (GetBits (Sd, 4) + 3);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (CharC == 2) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CharC = (UINT16) (GetBits (Sd, CBIT) + 20);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while ((INT16) (--CharC) >= 0 && Index < NC) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sd->mCLen[Index++] = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sd->mCLen[Index++] = (UINT8) (CharC - 2);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SetMem (Sd->mCLen + Index, NC - Index, 0);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MakeTable (Sd, NC, Sd->mCLen, 12, Sd->mCTable);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return ;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Decode a character/length value.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Read one value from mBitBuf, Get one code from mBitBuf. If it is at block boundary, generates
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Huffman code mapping table for Extra Set, Code&Len Set and
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Position Set.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Sd The global scratch data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return The value decoded.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncUINT16
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncDecodeC (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SCRATCH_DATA *Sd
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 Index2;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 Mask;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Sd->mBlockSize == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Starting a new block
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Read BlockSize from block header
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sd->mBlockSize = (UINT16) GetBits (Sd, 16);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Read in the Extra Set Code Length Arrary,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Generate the Huffman code mapping table for Extra Set.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sd->mBadTableFlag = ReadPTLen (Sd, NT, TBIT, 3);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Sd->mBadTableFlag != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Read in and decode the Char&Len Set Code Length Arrary,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Generate the Huffman code mapping table for Char&Len Set.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ReadCLen (Sd);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Read in the Position Set Code Length Arrary,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Generate the Huffman code mapping table for the Position Set.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sd->mBadTableFlag = ReadPTLen (Sd, MAXNP, Sd->mPBit, (UINT16) (-1));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Sd->mBadTableFlag != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get one code according to Code&Set Huffman Table
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sd->mBlockSize--;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Index2 = Sd->mCTable[Sd->mBitBuf >> (BITBUFSIZ - 12)];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Index2 >= NC) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Mask = 1U << (BITBUFSIZ - 1 - 12);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync do {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((Sd->mBitBuf & Mask) != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Index2 = Sd->mRight[Index2];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Index2 = Sd->mLeft[Index2];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Mask >>= 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } while (Index2 >= NC);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Advance what we have read
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FillBuf (Sd, Sd->mCLen[Index2]);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Index2;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Decode the source data and put the resulting data into the destination buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Sd The global scratch data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncDecode (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SCRATCH_DATA *Sd
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 BytesRemain;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 DataIdx;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 CharC;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BytesRemain = (UINT16) (-1);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DataIdx = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (;;) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get one code from mBitBuf
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CharC = DecodeC (Sd);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Sd->mBadTableFlag != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Done;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (CharC < 256) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Process an Original character
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Sd->mOutBuf >= Sd->mOrigSize) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Done;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Write orignal character into mDstBase
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sd->mDstBase[Sd->mOutBuf++] = (UINT8) CharC;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Process a Pointer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CharC = (UINT16) (CharC - (BIT8 - THRESHOLD));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get string length
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BytesRemain = CharC;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Locate string position
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DataIdx = Sd->mOutBuf - DecodeP (Sd) - 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Write BytesRemain of bytes into mDstBase
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BytesRemain--;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while ((INT16) (BytesRemain) >= 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Sd->mOutBuf >= Sd->mOrigSize) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Done;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BytesRemain--;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncDone:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return ;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Given a compressed source buffer, this function retrieves the size of
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the uncompressed buffer and the size of the scratch buffer required
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync to decompress the compressed source buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Retrieves the size of the uncompressed buffer and the temporary scratch buffer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync required to decompress the buffer specified by Source and SourceSize.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync If the size of the uncompressed buffer or the size of the scratch buffer cannot
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync be determined from the compressed data specified by Source and SourceData,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync then RETURN_INVALID_PARAMETER is returned. Otherwise, the size of the uncompressed
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync buffer is returned in DestinationSize, the size of the scratch buffer is returned
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync in ScratchSize, and RETURN_SUCCESS is returned.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function does not have scratch buffer available to perform a thorough
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync checking of the validity of the source data. It just retrieves the "Original Size"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync field from the beginning bytes of the source data and output it as DestinationSize.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync And ScratchSize is specific to the decompression implementation.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync If Source is NULL, then ASSERT().
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync If DestinationSize is NULL, then ASSERT().
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync If ScratchSize is NULL, then ASSERT().
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Source The source buffer containing the compressed data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param SourceSize The size, in bytes, of the source buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param DestinationSize A pointer to the size, in bytes, of the uncompressed buffer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync that will be generated when the compressed buffer specified
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync by Source and SourceSize is decompressed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param ScratchSize A pointer to the size, in bytes, of the scratch buffer that
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync is required to decompress the compressed buffer specified
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync by Source and SourceSize.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval RETURN_SUCCESS The size of the uncompressed data was returned
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync in DestinationSize, and the size of the scratch
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync buffer was returned in ScratchSize.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval RETURN_INVALID_PARAMETER
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The size of the uncompressed data or the size of
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the scratch buffer cannot be determined from
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the compressed data specified by Source
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync and SourceSize.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRETURN_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncUefiDecompressGetInfo (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN CONST VOID *Source,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT32 SourceSize,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT UINT32 *DestinationSize,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT UINT32 *ScratchSize
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 CompressedSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (Source != NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (DestinationSize != NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (ScratchSize != NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (SourceSize < 8) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return RETURN_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CompressedSize = ReadUnaligned32 ((UINT32 *)Source);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (SourceSize < (CompressedSize + 8)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return RETURN_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *ScratchSize = sizeof (SCRATCH_DATA);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *DestinationSize = ReadUnaligned32 ((UINT32 *)Source + 1);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return RETURN_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Decompresses a compressed source buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Extracts decompressed data to its original form.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function is designed so that the decompression algorithm can be implemented
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync without using any memory services. As a result, this function is not allowed to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync call any memory allocation services in its implementation. It is the caller's
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync responsibility to allocate and free the Destination and Scratch buffers.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync If the compressed source data specified by Source is successfully decompressed
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync into Destination, then RETURN_SUCCESS is returned. If the compressed source data
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync specified by Source is not in a valid compressed data format,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync then RETURN_INVALID_PARAMETER is returned.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync If Source is NULL, then ASSERT().
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync If Destination is NULL, then ASSERT().
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync If the required scratch buffer size > 0 and Scratch is NULL, then ASSERT().
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Source The source buffer containing the compressed data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Destination The destination buffer to store the decompressed data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Scratch A temporary scratch buffer that is used to perform the decompression.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This is an optional parameter that may be NULL if the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync required scratch buffer size is 0.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval RETURN_SUCCESS Decompression completed successfully, and
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the uncompressed buffer is returned in Destination.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval RETURN_INVALID_PARAMETER
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The source buffer specified by Source is corrupted
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (not in a valid compressed format).
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRETURN_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncUefiDecompress (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN CONST VOID *Source,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT VOID *Destination,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT VOID *Scratch OPTIONAL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 CompSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 OrigSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SCRATCH_DATA *Sd;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CONST UINT8 *Src;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 *Dst;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (Source != NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (Destination != NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (Scratch != NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Src = Source;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Dst = Destination;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sd = (SCRATCH_DATA *) Scratch;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CompSize = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OrigSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If compressed file size is 0, return
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (OrigSize == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return RETURN_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Src = Src + 8;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SetMem (Sd, sizeof (SCRATCH_DATA), 0);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The length of the field 'Position Set Code Length Array Size' in Block Header.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // For UEFI 2.0 de/compression algorithm(Version 1), mPBit = 4
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sd->mPBit = 4;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sd->mSrcBase = (UINT8 *)Src;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sd->mDstBase = Dst;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // CompSize and OrigSize are caculated in bytes
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sd->mCompSize = CompSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sd->mOrigSize = OrigSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Fill the first BITBUFSIZ bits
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FillBuf (Sd, BITBUFSIZ);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Decompress it
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Decode (Sd);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Sd->mBadTableFlag != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Something wrong with the source
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return RETURN_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return RETURN_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}