130fdf1140b8d1ce93f3821d986fa165552023440lgao/** @file
297fa0ee9b1cffbb4b97ee35365afa7afcf50e174Yingke LiuDecompressor. Algorithm Ported from OPSD code (Decomp.asm) for Efi and Tiano
397fa0ee9b1cffbb4b97ee35365afa7afcf50e174Yingke Liucompress algorithm.
430fdf1140b8d1ce93f3821d986fa165552023440lgao
5b3520abde896e5e3f251054092f084580bfcdc37Hao WuCopyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>
640d841f6a8f84e75409178e19e69b95e01bada0flgaoThis program and the accompanying materials
730fdf1140b8d1ce93f3821d986fa165552023440lgaoare licensed and made available under the terms and conditions of the BSD License
830fdf1140b8d1ce93f3821d986fa165552023440lgaowhich accompanies this distribution.  The full text of the license may be found at
930fdf1140b8d1ce93f3821d986fa165552023440lgaohttp://opensource.org/licenses/bsd-license.php
1030fdf1140b8d1ce93f3821d986fa165552023440lgao
1130fdf1140b8d1ce93f3821d986fa165552023440lgaoTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
1230fdf1140b8d1ce93f3821d986fa165552023440lgaoWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
1330fdf1140b8d1ce93f3821d986fa165552023440lgao
1430fdf1140b8d1ce93f3821d986fa165552023440lgao--*/
1530fdf1140b8d1ce93f3821d986fa165552023440lgao
1630fdf1140b8d1ce93f3821d986fa165552023440lgao#include <stdlib.h>
1730fdf1140b8d1ce93f3821d986fa165552023440lgao#include <string.h>
18b3520abde896e5e3f251054092f084580bfcdc37Hao Wu#include <assert.h>
1930fdf1140b8d1ce93f3821d986fa165552023440lgao#include "Decompress.h"
2030fdf1140b8d1ce93f3821d986fa165552023440lgao
2130fdf1140b8d1ce93f3821d986fa165552023440lgao//
2230fdf1140b8d1ce93f3821d986fa165552023440lgao// Decompression algorithm begins here
2330fdf1140b8d1ce93f3821d986fa165552023440lgao//
2430fdf1140b8d1ce93f3821d986fa165552023440lgao#define BITBUFSIZ 32
2530fdf1140b8d1ce93f3821d986fa165552023440lgao#define MAXMATCH  256
2630fdf1140b8d1ce93f3821d986fa165552023440lgao#define THRESHOLD 3
2730fdf1140b8d1ce93f3821d986fa165552023440lgao#define CODE_BIT  16
2830fdf1140b8d1ce93f3821d986fa165552023440lgao#define BAD_TABLE - 1
2930fdf1140b8d1ce93f3821d986fa165552023440lgao
3030fdf1140b8d1ce93f3821d986fa165552023440lgao//
3130fdf1140b8d1ce93f3821d986fa165552023440lgao// C: Char&Len Set; P: Position Set; T: exTra Set
3230fdf1140b8d1ce93f3821d986fa165552023440lgao//
3330fdf1140b8d1ce93f3821d986fa165552023440lgao#define NC      (0xff + MAXMATCH + 2 - THRESHOLD)
3430fdf1140b8d1ce93f3821d986fa165552023440lgao#define CBIT    9
3530fdf1140b8d1ce93f3821d986fa165552023440lgao#define EFIPBIT 4
3630fdf1140b8d1ce93f3821d986fa165552023440lgao#define MAXPBIT 5
3730fdf1140b8d1ce93f3821d986fa165552023440lgao#define TBIT    5
3830fdf1140b8d1ce93f3821d986fa165552023440lgao#define MAXNP ((1U << MAXPBIT) - 1)
3930fdf1140b8d1ce93f3821d986fa165552023440lgao#define NT    (CODE_BIT + 3)
4030fdf1140b8d1ce93f3821d986fa165552023440lgao#if NT > MAXNP
4130fdf1140b8d1ce93f3821d986fa165552023440lgao#define NPT NT
4230fdf1140b8d1ce93f3821d986fa165552023440lgao#else
4330fdf1140b8d1ce93f3821d986fa165552023440lgao#define NPT MAXNP
4430fdf1140b8d1ce93f3821d986fa165552023440lgao#endif
4530fdf1140b8d1ce93f3821d986fa165552023440lgao
4630fdf1140b8d1ce93f3821d986fa165552023440lgaotypedef struct {
4730fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT8   *mSrcBase;  // Starting address of compressed data
4830fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT8   *mDstBase;  // Starting address of decompressed data
4930fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT32  mOutBuf;
5030fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT32  mInBuf;
5130fdf1140b8d1ce93f3821d986fa165552023440lgao
5230fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT16  mBitCount;
5330fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT32  mBitBuf;
5430fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT32  mSubBitBuf;
5530fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT16  mBlockSize;
5630fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT32  mCompSize;
5730fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT32  mOrigSize;
5830fdf1140b8d1ce93f3821d986fa165552023440lgao
5930fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT16  mBadTableFlag;
6030fdf1140b8d1ce93f3821d986fa165552023440lgao
6130fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT16  mLeft[2 * NC - 1];
6230fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT16  mRight[2 * NC - 1];
6330fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT8   mCLen[NC];
6430fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT8   mPTLen[NPT];
6530fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT16  mCTable[4096];
6630fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT16  mPTTable[256];
6730fdf1140b8d1ce93f3821d986fa165552023440lgao} SCRATCH_DATA;
6830fdf1140b8d1ce93f3821d986fa165552023440lgao
6930fdf1140b8d1ce93f3821d986fa165552023440lgaoSTATIC UINT16 mPbit = EFIPBIT;
7030fdf1140b8d1ce93f3821d986fa165552023440lgao
7130fdf1140b8d1ce93f3821d986fa165552023440lgaoSTATIC
7230fdf1140b8d1ce93f3821d986fa165552023440lgaoVOID
7330fdf1140b8d1ce93f3821d986fa165552023440lgaoFillBuf (
7430fdf1140b8d1ce93f3821d986fa165552023440lgao  IN  SCRATCH_DATA  *Sd,
7530fdf1140b8d1ce93f3821d986fa165552023440lgao  IN  UINT16        NumOfBits
7630fdf1140b8d1ce93f3821d986fa165552023440lgao  )
7730fdf1140b8d1ce93f3821d986fa165552023440lgao/*++
7830fdf1140b8d1ce93f3821d986fa165552023440lgao
7930fdf1140b8d1ce93f3821d986fa165552023440lgaoRoutine Description:
8030fdf1140b8d1ce93f3821d986fa165552023440lgao
8130fdf1140b8d1ce93f3821d986fa165552023440lgao  Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source.
8230fdf1140b8d1ce93f3821d986fa165552023440lgao
8330fdf1140b8d1ce93f3821d986fa165552023440lgaoArguments:
8430fdf1140b8d1ce93f3821d986fa165552023440lgao
8530fdf1140b8d1ce93f3821d986fa165552023440lgao  Sd        - The global scratch data
8630fdf1140b8d1ce93f3821d986fa165552023440lgao  NumOfBit  - The number of bits to shift and read.
8730fdf1140b8d1ce93f3821d986fa165552023440lgao
8830fdf1140b8d1ce93f3821d986fa165552023440lgaoReturns: (VOID)
8930fdf1140b8d1ce93f3821d986fa165552023440lgao
9030fdf1140b8d1ce93f3821d986fa165552023440lgao--*/
9130fdf1140b8d1ce93f3821d986fa165552023440lgao{
9230fdf1140b8d1ce93f3821d986fa165552023440lgao  Sd->mBitBuf = (UINT32) (Sd->mBitBuf << NumOfBits);
9330fdf1140b8d1ce93f3821d986fa165552023440lgao
9430fdf1140b8d1ce93f3821d986fa165552023440lgao  while (NumOfBits > Sd->mBitCount) {
9530fdf1140b8d1ce93f3821d986fa165552023440lgao
9630fdf1140b8d1ce93f3821d986fa165552023440lgao    Sd->mBitBuf |= (UINT32) (Sd->mSubBitBuf << (NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount)));
9730fdf1140b8d1ce93f3821d986fa165552023440lgao
9830fdf1140b8d1ce93f3821d986fa165552023440lgao    if (Sd->mCompSize > 0) {
9930fdf1140b8d1ce93f3821d986fa165552023440lgao      //
10030fdf1140b8d1ce93f3821d986fa165552023440lgao      // Get 1 byte into SubBitBuf
10130fdf1140b8d1ce93f3821d986fa165552023440lgao      //
10230fdf1140b8d1ce93f3821d986fa165552023440lgao      Sd->mCompSize--;
10330fdf1140b8d1ce93f3821d986fa165552023440lgao      Sd->mSubBitBuf  = 0;
10430fdf1140b8d1ce93f3821d986fa165552023440lgao      Sd->mSubBitBuf  = Sd->mSrcBase[Sd->mInBuf++];
10530fdf1140b8d1ce93f3821d986fa165552023440lgao      Sd->mBitCount   = 8;
10630fdf1140b8d1ce93f3821d986fa165552023440lgao
10730fdf1140b8d1ce93f3821d986fa165552023440lgao    } else {
10830fdf1140b8d1ce93f3821d986fa165552023440lgao      //
10930fdf1140b8d1ce93f3821d986fa165552023440lgao      // No more bits from the source, just pad zero bit.
11030fdf1140b8d1ce93f3821d986fa165552023440lgao      //
11130fdf1140b8d1ce93f3821d986fa165552023440lgao      Sd->mSubBitBuf  = 0;
11230fdf1140b8d1ce93f3821d986fa165552023440lgao      Sd->mBitCount   = 8;
11330fdf1140b8d1ce93f3821d986fa165552023440lgao
11430fdf1140b8d1ce93f3821d986fa165552023440lgao    }
11530fdf1140b8d1ce93f3821d986fa165552023440lgao  }
11630fdf1140b8d1ce93f3821d986fa165552023440lgao
11730fdf1140b8d1ce93f3821d986fa165552023440lgao  Sd->mBitCount = (UINT16) (Sd->mBitCount - NumOfBits);
11830fdf1140b8d1ce93f3821d986fa165552023440lgao  Sd->mBitBuf |= Sd->mSubBitBuf >> Sd->mBitCount;
11930fdf1140b8d1ce93f3821d986fa165552023440lgao}
12030fdf1140b8d1ce93f3821d986fa165552023440lgao
12130fdf1140b8d1ce93f3821d986fa165552023440lgaoSTATIC
12230fdf1140b8d1ce93f3821d986fa165552023440lgaoUINT32
12330fdf1140b8d1ce93f3821d986fa165552023440lgaoGetBits (
12430fdf1140b8d1ce93f3821d986fa165552023440lgao  IN  SCRATCH_DATA  *Sd,
12530fdf1140b8d1ce93f3821d986fa165552023440lgao  IN  UINT16        NumOfBits
12630fdf1140b8d1ce93f3821d986fa165552023440lgao  )
12730fdf1140b8d1ce93f3821d986fa165552023440lgao/*++
12830fdf1140b8d1ce93f3821d986fa165552023440lgao
12930fdf1140b8d1ce93f3821d986fa165552023440lgaoRoutine Description:
13030fdf1140b8d1ce93f3821d986fa165552023440lgao
13130fdf1140b8d1ce93f3821d986fa165552023440lgao  Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent
13230fdf1140b8d1ce93f3821d986fa165552023440lgao  NumOfBits of bits from source. Returns NumOfBits of bits that are
13330fdf1140b8d1ce93f3821d986fa165552023440lgao  popped out.
13430fdf1140b8d1ce93f3821d986fa165552023440lgao
13530fdf1140b8d1ce93f3821d986fa165552023440lgaoArguments:
13630fdf1140b8d1ce93f3821d986fa165552023440lgao
13730fdf1140b8d1ce93f3821d986fa165552023440lgao  Sd            - The global scratch data.
13830fdf1140b8d1ce93f3821d986fa165552023440lgao  NumOfBits     - The number of bits to pop and read.
13930fdf1140b8d1ce93f3821d986fa165552023440lgao
14030fdf1140b8d1ce93f3821d986fa165552023440lgaoReturns:
14130fdf1140b8d1ce93f3821d986fa165552023440lgao
14230fdf1140b8d1ce93f3821d986fa165552023440lgao  The bits that are popped out.
14330fdf1140b8d1ce93f3821d986fa165552023440lgao
14430fdf1140b8d1ce93f3821d986fa165552023440lgao--*/
14530fdf1140b8d1ce93f3821d986fa165552023440lgao{
14630fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT32  OutBits;
14730fdf1140b8d1ce93f3821d986fa165552023440lgao
14830fdf1140b8d1ce93f3821d986fa165552023440lgao  OutBits = (UINT32) (Sd->mBitBuf >> (BITBUFSIZ - NumOfBits));
14930fdf1140b8d1ce93f3821d986fa165552023440lgao
15030fdf1140b8d1ce93f3821d986fa165552023440lgao  FillBuf (Sd, NumOfBits);
15130fdf1140b8d1ce93f3821d986fa165552023440lgao
15230fdf1140b8d1ce93f3821d986fa165552023440lgao  return OutBits;
15330fdf1140b8d1ce93f3821d986fa165552023440lgao}
15430fdf1140b8d1ce93f3821d986fa165552023440lgao
15530fdf1140b8d1ce93f3821d986fa165552023440lgaoSTATIC
15630fdf1140b8d1ce93f3821d986fa165552023440lgaoUINT16
15730fdf1140b8d1ce93f3821d986fa165552023440lgaoMakeTable (
15830fdf1140b8d1ce93f3821d986fa165552023440lgao  IN  SCRATCH_DATA  *Sd,
15930fdf1140b8d1ce93f3821d986fa165552023440lgao  IN  UINT16        NumOfChar,
16030fdf1140b8d1ce93f3821d986fa165552023440lgao  IN  UINT8         *BitLen,
16130fdf1140b8d1ce93f3821d986fa165552023440lgao  IN  UINT16        TableBits,
16230fdf1140b8d1ce93f3821d986fa165552023440lgao  OUT UINT16        *Table
16330fdf1140b8d1ce93f3821d986fa165552023440lgao  )
16430fdf1140b8d1ce93f3821d986fa165552023440lgao/*++
16530fdf1140b8d1ce93f3821d986fa165552023440lgao
16630fdf1140b8d1ce93f3821d986fa165552023440lgaoRoutine Description:
16730fdf1140b8d1ce93f3821d986fa165552023440lgao
16830fdf1140b8d1ce93f3821d986fa165552023440lgao  Creates Huffman Code mapping table according to code length array.
16930fdf1140b8d1ce93f3821d986fa165552023440lgao
17030fdf1140b8d1ce93f3821d986fa165552023440lgaoArguments:
17130fdf1140b8d1ce93f3821d986fa165552023440lgao
17230fdf1140b8d1ce93f3821d986fa165552023440lgao  Sd        - The global scratch data
17330fdf1140b8d1ce93f3821d986fa165552023440lgao  NumOfChar - Number of symbols in the symbol set
17430fdf1140b8d1ce93f3821d986fa165552023440lgao  BitLen    - Code length array
17530fdf1140b8d1ce93f3821d986fa165552023440lgao  TableBits - The width of the mapping table
17630fdf1140b8d1ce93f3821d986fa165552023440lgao  Table     - The table
17730fdf1140b8d1ce93f3821d986fa165552023440lgao
17830fdf1140b8d1ce93f3821d986fa165552023440lgaoReturns:
17930fdf1140b8d1ce93f3821d986fa165552023440lgao
18030fdf1140b8d1ce93f3821d986fa165552023440lgao  0         - OK.
18130fdf1140b8d1ce93f3821d986fa165552023440lgao  BAD_TABLE - The table is corrupted.
18230fdf1140b8d1ce93f3821d986fa165552023440lgao
18330fdf1140b8d1ce93f3821d986fa165552023440lgao--*/
18430fdf1140b8d1ce93f3821d986fa165552023440lgao{
18530fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT16  Count[17];
18630fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT16  Weight[17];
18730fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT16  Start[18];
18830fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT16  *Pointer;
18930fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT16  Index3;
19030fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT16  Index;
19130fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT16  Len;
19230fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT16  Char;
19330fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT16  JuBits;
19430fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT16  Avail;
19530fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT16  NextCode;
19630fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT16  Mask;
19730fdf1140b8d1ce93f3821d986fa165552023440lgao
19830fdf1140b8d1ce93f3821d986fa165552023440lgao  for (Index = 1; Index <= 16; Index++) {
19930fdf1140b8d1ce93f3821d986fa165552023440lgao    Count[Index] = 0;
20030fdf1140b8d1ce93f3821d986fa165552023440lgao  }
20130fdf1140b8d1ce93f3821d986fa165552023440lgao
20230fdf1140b8d1ce93f3821d986fa165552023440lgao  for (Index = 0; Index < NumOfChar; Index++) {
20330fdf1140b8d1ce93f3821d986fa165552023440lgao    Count[BitLen[Index]]++;
20430fdf1140b8d1ce93f3821d986fa165552023440lgao  }
20530fdf1140b8d1ce93f3821d986fa165552023440lgao
20630fdf1140b8d1ce93f3821d986fa165552023440lgao  Start[1] = 0;
20730fdf1140b8d1ce93f3821d986fa165552023440lgao
20830fdf1140b8d1ce93f3821d986fa165552023440lgao  for (Index = 1; Index <= 16; Index++) {
20930fdf1140b8d1ce93f3821d986fa165552023440lgao    Start[Index + 1] = (UINT16) (Start[Index] + (Count[Index] << (16 - Index)));
21030fdf1140b8d1ce93f3821d986fa165552023440lgao  }
21130fdf1140b8d1ce93f3821d986fa165552023440lgao
21230fdf1140b8d1ce93f3821d986fa165552023440lgao  if (Start[17] != 0) {
21330fdf1140b8d1ce93f3821d986fa165552023440lgao    /*(1U << 16)*/
21430fdf1140b8d1ce93f3821d986fa165552023440lgao    return (UINT16) BAD_TABLE;
21530fdf1140b8d1ce93f3821d986fa165552023440lgao  }
21630fdf1140b8d1ce93f3821d986fa165552023440lgao
21730fdf1140b8d1ce93f3821d986fa165552023440lgao  JuBits = (UINT16) (16 - TableBits);
21830fdf1140b8d1ce93f3821d986fa165552023440lgao
21930fdf1140b8d1ce93f3821d986fa165552023440lgao  for (Index = 1; Index <= TableBits; Index++) {
22030fdf1140b8d1ce93f3821d986fa165552023440lgao    Start[Index] >>= JuBits;
22130fdf1140b8d1ce93f3821d986fa165552023440lgao    Weight[Index] = (UINT16) (1U << (TableBits - Index));
22230fdf1140b8d1ce93f3821d986fa165552023440lgao  }
22330fdf1140b8d1ce93f3821d986fa165552023440lgao
22430fdf1140b8d1ce93f3821d986fa165552023440lgao  while (Index <= 16) {
22530fdf1140b8d1ce93f3821d986fa165552023440lgao    Weight[Index] = (UINT16) (1U << (16 - Index));
22630fdf1140b8d1ce93f3821d986fa165552023440lgao    Index++;
22730fdf1140b8d1ce93f3821d986fa165552023440lgao  }
22830fdf1140b8d1ce93f3821d986fa165552023440lgao
22930fdf1140b8d1ce93f3821d986fa165552023440lgao  Index = (UINT16) (Start[TableBits + 1] >> JuBits);
23030fdf1140b8d1ce93f3821d986fa165552023440lgao
23130fdf1140b8d1ce93f3821d986fa165552023440lgao  if (Index != 0) {
23230fdf1140b8d1ce93f3821d986fa165552023440lgao    Index3 = (UINT16) (1U << TableBits);
23330fdf1140b8d1ce93f3821d986fa165552023440lgao    while (Index != Index3) {
23430fdf1140b8d1ce93f3821d986fa165552023440lgao      Table[Index++] = 0;
23530fdf1140b8d1ce93f3821d986fa165552023440lgao    }
23630fdf1140b8d1ce93f3821d986fa165552023440lgao  }
23730fdf1140b8d1ce93f3821d986fa165552023440lgao
23830fdf1140b8d1ce93f3821d986fa165552023440lgao  Avail = NumOfChar;
23930fdf1140b8d1ce93f3821d986fa165552023440lgao  Mask  = (UINT16) (1U << (15 - TableBits));
24030fdf1140b8d1ce93f3821d986fa165552023440lgao
24130fdf1140b8d1ce93f3821d986fa165552023440lgao  for (Char = 0; Char < NumOfChar; Char++) {
24230fdf1140b8d1ce93f3821d986fa165552023440lgao
24330fdf1140b8d1ce93f3821d986fa165552023440lgao    Len = BitLen[Char];
244b3520abde896e5e3f251054092f084580bfcdc37Hao Wu    if (Len == 0 || Len >= 17) {
24530fdf1140b8d1ce93f3821d986fa165552023440lgao      continue;
24630fdf1140b8d1ce93f3821d986fa165552023440lgao    }
24730fdf1140b8d1ce93f3821d986fa165552023440lgao
24830fdf1140b8d1ce93f3821d986fa165552023440lgao    NextCode = (UINT16) (Start[Len] + Weight[Len]);
24930fdf1140b8d1ce93f3821d986fa165552023440lgao
25030fdf1140b8d1ce93f3821d986fa165552023440lgao    if (Len <= TableBits) {
25130fdf1140b8d1ce93f3821d986fa165552023440lgao
25230fdf1140b8d1ce93f3821d986fa165552023440lgao      for (Index = Start[Len]; Index < NextCode; Index++) {
25330fdf1140b8d1ce93f3821d986fa165552023440lgao        Table[Index] = Char;
25430fdf1140b8d1ce93f3821d986fa165552023440lgao      }
25530fdf1140b8d1ce93f3821d986fa165552023440lgao
25630fdf1140b8d1ce93f3821d986fa165552023440lgao    } else {
25730fdf1140b8d1ce93f3821d986fa165552023440lgao
25830fdf1140b8d1ce93f3821d986fa165552023440lgao      Index3  = Start[Len];
25930fdf1140b8d1ce93f3821d986fa165552023440lgao      Pointer = &Table[Index3 >> JuBits];
26030fdf1140b8d1ce93f3821d986fa165552023440lgao      Index   = (UINT16) (Len - TableBits);
26130fdf1140b8d1ce93f3821d986fa165552023440lgao
26230fdf1140b8d1ce93f3821d986fa165552023440lgao      while (Index != 0) {
26330fdf1140b8d1ce93f3821d986fa165552023440lgao        if (*Pointer == 0) {
26430fdf1140b8d1ce93f3821d986fa165552023440lgao          Sd->mRight[Avail]                     = Sd->mLeft[Avail] = 0;
26530fdf1140b8d1ce93f3821d986fa165552023440lgao          *Pointer = Avail++;
26630fdf1140b8d1ce93f3821d986fa165552023440lgao        }
26730fdf1140b8d1ce93f3821d986fa165552023440lgao
26830fdf1140b8d1ce93f3821d986fa165552023440lgao        if (Index3 & Mask) {
26930fdf1140b8d1ce93f3821d986fa165552023440lgao          Pointer = &Sd->mRight[*Pointer];
27030fdf1140b8d1ce93f3821d986fa165552023440lgao        } else {
27130fdf1140b8d1ce93f3821d986fa165552023440lgao          Pointer = &Sd->mLeft[*Pointer];
27230fdf1140b8d1ce93f3821d986fa165552023440lgao        }
27330fdf1140b8d1ce93f3821d986fa165552023440lgao
27430fdf1140b8d1ce93f3821d986fa165552023440lgao        Index3 <<= 1;
27530fdf1140b8d1ce93f3821d986fa165552023440lgao        Index--;
27630fdf1140b8d1ce93f3821d986fa165552023440lgao      }
27730fdf1140b8d1ce93f3821d986fa165552023440lgao
27830fdf1140b8d1ce93f3821d986fa165552023440lgao      *Pointer = Char;
27930fdf1140b8d1ce93f3821d986fa165552023440lgao
28030fdf1140b8d1ce93f3821d986fa165552023440lgao    }
28130fdf1140b8d1ce93f3821d986fa165552023440lgao
28230fdf1140b8d1ce93f3821d986fa165552023440lgao    Start[Len] = NextCode;
28330fdf1140b8d1ce93f3821d986fa165552023440lgao  }
28430fdf1140b8d1ce93f3821d986fa165552023440lgao  //
28530fdf1140b8d1ce93f3821d986fa165552023440lgao  // Succeeds
28630fdf1140b8d1ce93f3821d986fa165552023440lgao  //
28730fdf1140b8d1ce93f3821d986fa165552023440lgao  return 0;
28830fdf1140b8d1ce93f3821d986fa165552023440lgao}
28930fdf1140b8d1ce93f3821d986fa165552023440lgao
29030fdf1140b8d1ce93f3821d986fa165552023440lgaoSTATIC
29130fdf1140b8d1ce93f3821d986fa165552023440lgaoUINT32
29230fdf1140b8d1ce93f3821d986fa165552023440lgaoDecodeP (
29330fdf1140b8d1ce93f3821d986fa165552023440lgao  IN  SCRATCH_DATA  *Sd
29430fdf1140b8d1ce93f3821d986fa165552023440lgao  )
29530fdf1140b8d1ce93f3821d986fa165552023440lgao/*++
29630fdf1140b8d1ce93f3821d986fa165552023440lgao
29730fdf1140b8d1ce93f3821d986fa165552023440lgaoRoutine Description:
29830fdf1140b8d1ce93f3821d986fa165552023440lgao
29930fdf1140b8d1ce93f3821d986fa165552023440lgao  Decodes a position value.
30030fdf1140b8d1ce93f3821d986fa165552023440lgao
30130fdf1140b8d1ce93f3821d986fa165552023440lgaoArguments:
30230fdf1140b8d1ce93f3821d986fa165552023440lgao
30330fdf1140b8d1ce93f3821d986fa165552023440lgao  Sd      - the global scratch data
30430fdf1140b8d1ce93f3821d986fa165552023440lgao
30530fdf1140b8d1ce93f3821d986fa165552023440lgaoReturns:
30630fdf1140b8d1ce93f3821d986fa165552023440lgao
30730fdf1140b8d1ce93f3821d986fa165552023440lgao  The position value decoded.
30830fdf1140b8d1ce93f3821d986fa165552023440lgao
30930fdf1140b8d1ce93f3821d986fa165552023440lgao--*/
31030fdf1140b8d1ce93f3821d986fa165552023440lgao{
31130fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT16  Val;
31230fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT32  Mask;
31330fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT32  Pos;
31430fdf1140b8d1ce93f3821d986fa165552023440lgao
31530fdf1140b8d1ce93f3821d986fa165552023440lgao  Val = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];
31630fdf1140b8d1ce93f3821d986fa165552023440lgao
31730fdf1140b8d1ce93f3821d986fa165552023440lgao  if (Val >= MAXNP) {
31830fdf1140b8d1ce93f3821d986fa165552023440lgao    Mask = 1U << (BITBUFSIZ - 1 - 8);
31930fdf1140b8d1ce93f3821d986fa165552023440lgao
32030fdf1140b8d1ce93f3821d986fa165552023440lgao    do {
32130fdf1140b8d1ce93f3821d986fa165552023440lgao
32230fdf1140b8d1ce93f3821d986fa165552023440lgao      if (Sd->mBitBuf & Mask) {
32330fdf1140b8d1ce93f3821d986fa165552023440lgao        Val = Sd->mRight[Val];
32430fdf1140b8d1ce93f3821d986fa165552023440lgao      } else {
32530fdf1140b8d1ce93f3821d986fa165552023440lgao        Val = Sd->mLeft[Val];
32630fdf1140b8d1ce93f3821d986fa165552023440lgao      }
32730fdf1140b8d1ce93f3821d986fa165552023440lgao
32830fdf1140b8d1ce93f3821d986fa165552023440lgao      Mask >>= 1;
32930fdf1140b8d1ce93f3821d986fa165552023440lgao    } while (Val >= MAXNP);
33030fdf1140b8d1ce93f3821d986fa165552023440lgao  }
33130fdf1140b8d1ce93f3821d986fa165552023440lgao  //
33230fdf1140b8d1ce93f3821d986fa165552023440lgao  // Advance what we have read
33330fdf1140b8d1ce93f3821d986fa165552023440lgao  //
33430fdf1140b8d1ce93f3821d986fa165552023440lgao  FillBuf (Sd, Sd->mPTLen[Val]);
33530fdf1140b8d1ce93f3821d986fa165552023440lgao
33630fdf1140b8d1ce93f3821d986fa165552023440lgao  Pos = Val;
33730fdf1140b8d1ce93f3821d986fa165552023440lgao  if (Val > 1) {
33830fdf1140b8d1ce93f3821d986fa165552023440lgao    Pos = (UINT32) ((1U << (Val - 1)) + GetBits (Sd, (UINT16) (Val - 1)));
33930fdf1140b8d1ce93f3821d986fa165552023440lgao  }
34030fdf1140b8d1ce93f3821d986fa165552023440lgao
34130fdf1140b8d1ce93f3821d986fa165552023440lgao  return Pos;
34230fdf1140b8d1ce93f3821d986fa165552023440lgao}
34330fdf1140b8d1ce93f3821d986fa165552023440lgao
34430fdf1140b8d1ce93f3821d986fa165552023440lgaoSTATIC
34530fdf1140b8d1ce93f3821d986fa165552023440lgaoUINT16
34630fdf1140b8d1ce93f3821d986fa165552023440lgaoReadPTLen (
34730fdf1140b8d1ce93f3821d986fa165552023440lgao  IN  SCRATCH_DATA  *Sd,
34830fdf1140b8d1ce93f3821d986fa165552023440lgao  IN  UINT16        nn,
34930fdf1140b8d1ce93f3821d986fa165552023440lgao  IN  UINT16        nbit,
35030fdf1140b8d1ce93f3821d986fa165552023440lgao  IN  UINT16        Special
35130fdf1140b8d1ce93f3821d986fa165552023440lgao  )
35230fdf1140b8d1ce93f3821d986fa165552023440lgao/*++
35330fdf1140b8d1ce93f3821d986fa165552023440lgao
35430fdf1140b8d1ce93f3821d986fa165552023440lgaoRoutine Description:
35530fdf1140b8d1ce93f3821d986fa165552023440lgao
35630fdf1140b8d1ce93f3821d986fa165552023440lgao  Reads code lengths for the Extra Set or the Position Set
35730fdf1140b8d1ce93f3821d986fa165552023440lgao
35830fdf1140b8d1ce93f3821d986fa165552023440lgaoArguments:
35930fdf1140b8d1ce93f3821d986fa165552023440lgao
36030fdf1140b8d1ce93f3821d986fa165552023440lgao  Sd        - The global scratch data
36130fdf1140b8d1ce93f3821d986fa165552023440lgao  nn        - Number of symbols
36230fdf1140b8d1ce93f3821d986fa165552023440lgao  nbit      - Number of bits needed to represent nn
36330fdf1140b8d1ce93f3821d986fa165552023440lgao  Special   - The special symbol that needs to be taken care of
36430fdf1140b8d1ce93f3821d986fa165552023440lgao
36530fdf1140b8d1ce93f3821d986fa165552023440lgaoReturns:
36630fdf1140b8d1ce93f3821d986fa165552023440lgao
36730fdf1140b8d1ce93f3821d986fa165552023440lgao  0         - OK.
36830fdf1140b8d1ce93f3821d986fa165552023440lgao  BAD_TABLE - Table is corrupted.
36930fdf1140b8d1ce93f3821d986fa165552023440lgao
37030fdf1140b8d1ce93f3821d986fa165552023440lgao--*/
37130fdf1140b8d1ce93f3821d986fa165552023440lgao{
37230fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT16  Number;
37330fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT16  CharC;
37430fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT16  Index;
37530fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT32  Mask;
37630fdf1140b8d1ce93f3821d986fa165552023440lgao
377b3520abde896e5e3f251054092f084580bfcdc37Hao Wu  assert (nn <= NPT);
378b3520abde896e5e3f251054092f084580bfcdc37Hao Wu
37930fdf1140b8d1ce93f3821d986fa165552023440lgao  Number = (UINT16) GetBits (Sd, nbit);
38030fdf1140b8d1ce93f3821d986fa165552023440lgao
38130fdf1140b8d1ce93f3821d986fa165552023440lgao  if (Number == 0) {
38230fdf1140b8d1ce93f3821d986fa165552023440lgao    CharC = (UINT16) GetBits (Sd, nbit);
38330fdf1140b8d1ce93f3821d986fa165552023440lgao
38430fdf1140b8d1ce93f3821d986fa165552023440lgao    for (Index = 0; Index < 256; Index++) {
38530fdf1140b8d1ce93f3821d986fa165552023440lgao      Sd->mPTTable[Index] = CharC;
38630fdf1140b8d1ce93f3821d986fa165552023440lgao    }
38730fdf1140b8d1ce93f3821d986fa165552023440lgao
38830fdf1140b8d1ce93f3821d986fa165552023440lgao    for (Index = 0; Index < nn; Index++) {
38930fdf1140b8d1ce93f3821d986fa165552023440lgao      Sd->mPTLen[Index] = 0;
39030fdf1140b8d1ce93f3821d986fa165552023440lgao    }
39130fdf1140b8d1ce93f3821d986fa165552023440lgao
39230fdf1140b8d1ce93f3821d986fa165552023440lgao    return 0;
39330fdf1140b8d1ce93f3821d986fa165552023440lgao  }
39430fdf1140b8d1ce93f3821d986fa165552023440lgao
39530fdf1140b8d1ce93f3821d986fa165552023440lgao  Index = 0;
39630fdf1140b8d1ce93f3821d986fa165552023440lgao
39730fdf1140b8d1ce93f3821d986fa165552023440lgao  while (Index < Number) {
39830fdf1140b8d1ce93f3821d986fa165552023440lgao
39930fdf1140b8d1ce93f3821d986fa165552023440lgao    CharC = (UINT16) (Sd->mBitBuf >> (BITBUFSIZ - 3));
40030fdf1140b8d1ce93f3821d986fa165552023440lgao
40130fdf1140b8d1ce93f3821d986fa165552023440lgao    if (CharC == 7) {
40230fdf1140b8d1ce93f3821d986fa165552023440lgao      Mask = 1U << (BITBUFSIZ - 1 - 3);
40330fdf1140b8d1ce93f3821d986fa165552023440lgao      while (Mask & Sd->mBitBuf) {
40430fdf1140b8d1ce93f3821d986fa165552023440lgao        Mask >>= 1;
40530fdf1140b8d1ce93f3821d986fa165552023440lgao        CharC += 1;
40630fdf1140b8d1ce93f3821d986fa165552023440lgao      }
40730fdf1140b8d1ce93f3821d986fa165552023440lgao    }
40830fdf1140b8d1ce93f3821d986fa165552023440lgao
40930fdf1140b8d1ce93f3821d986fa165552023440lgao    FillBuf (Sd, (UINT16) ((CharC < 7) ? 3 : CharC - 3));
41030fdf1140b8d1ce93f3821d986fa165552023440lgao
41130fdf1140b8d1ce93f3821d986fa165552023440lgao    Sd->mPTLen[Index++] = (UINT8) CharC;
41230fdf1140b8d1ce93f3821d986fa165552023440lgao
41330fdf1140b8d1ce93f3821d986fa165552023440lgao    if (Index == Special) {
41430fdf1140b8d1ce93f3821d986fa165552023440lgao      CharC = (UINT16) GetBits (Sd, 2);
41530fdf1140b8d1ce93f3821d986fa165552023440lgao      CharC--;
41630fdf1140b8d1ce93f3821d986fa165552023440lgao      while ((INT16) (CharC) >= 0) {
41730fdf1140b8d1ce93f3821d986fa165552023440lgao        Sd->mPTLen[Index++] = 0;
41830fdf1140b8d1ce93f3821d986fa165552023440lgao        CharC--;
41930fdf1140b8d1ce93f3821d986fa165552023440lgao      }
42030fdf1140b8d1ce93f3821d986fa165552023440lgao    }
42130fdf1140b8d1ce93f3821d986fa165552023440lgao  }
42230fdf1140b8d1ce93f3821d986fa165552023440lgao
42330fdf1140b8d1ce93f3821d986fa165552023440lgao  while (Index < nn) {
42430fdf1140b8d1ce93f3821d986fa165552023440lgao    Sd->mPTLen[Index++] = 0;
42530fdf1140b8d1ce93f3821d986fa165552023440lgao  }
42630fdf1140b8d1ce93f3821d986fa165552023440lgao
42730fdf1140b8d1ce93f3821d986fa165552023440lgao  return MakeTable (Sd, nn, Sd->mPTLen, 8, Sd->mPTTable);
42830fdf1140b8d1ce93f3821d986fa165552023440lgao}
42930fdf1140b8d1ce93f3821d986fa165552023440lgao
43030fdf1140b8d1ce93f3821d986fa165552023440lgaoSTATIC
43130fdf1140b8d1ce93f3821d986fa165552023440lgaoVOID
43230fdf1140b8d1ce93f3821d986fa165552023440lgaoReadCLen (
43330fdf1140b8d1ce93f3821d986fa165552023440lgao  SCRATCH_DATA  *Sd
43430fdf1140b8d1ce93f3821d986fa165552023440lgao  )
43530fdf1140b8d1ce93f3821d986fa165552023440lgao/*++
43630fdf1140b8d1ce93f3821d986fa165552023440lgao
43730fdf1140b8d1ce93f3821d986fa165552023440lgaoRoutine Description:
43830fdf1140b8d1ce93f3821d986fa165552023440lgao
43930fdf1140b8d1ce93f3821d986fa165552023440lgao  Reads code lengths for Char&Len Set.
44030fdf1140b8d1ce93f3821d986fa165552023440lgao
44130fdf1140b8d1ce93f3821d986fa165552023440lgaoArguments:
44230fdf1140b8d1ce93f3821d986fa165552023440lgao
44330fdf1140b8d1ce93f3821d986fa165552023440lgao  Sd    - the global scratch data
44430fdf1140b8d1ce93f3821d986fa165552023440lgao
44530fdf1140b8d1ce93f3821d986fa165552023440lgaoReturns: (VOID)
44630fdf1140b8d1ce93f3821d986fa165552023440lgao
44730fdf1140b8d1ce93f3821d986fa165552023440lgao--*/
44830fdf1140b8d1ce93f3821d986fa165552023440lgao{
44930fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT16  Number;
45030fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT16  CharC;
45130fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT16  Index;
45230fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT32  Mask;
45330fdf1140b8d1ce93f3821d986fa165552023440lgao
45430fdf1140b8d1ce93f3821d986fa165552023440lgao  Number = (UINT16) GetBits (Sd, CBIT);
45530fdf1140b8d1ce93f3821d986fa165552023440lgao
45630fdf1140b8d1ce93f3821d986fa165552023440lgao  if (Number == 0) {
45730fdf1140b8d1ce93f3821d986fa165552023440lgao    CharC = (UINT16) GetBits (Sd, CBIT);
45830fdf1140b8d1ce93f3821d986fa165552023440lgao
45930fdf1140b8d1ce93f3821d986fa165552023440lgao    for (Index = 0; Index < NC; Index++) {
46030fdf1140b8d1ce93f3821d986fa165552023440lgao      Sd->mCLen[Index] = 0;
46130fdf1140b8d1ce93f3821d986fa165552023440lgao    }
46230fdf1140b8d1ce93f3821d986fa165552023440lgao
46330fdf1140b8d1ce93f3821d986fa165552023440lgao    for (Index = 0; Index < 4096; Index++) {
46430fdf1140b8d1ce93f3821d986fa165552023440lgao      Sd->mCTable[Index] = CharC;
46530fdf1140b8d1ce93f3821d986fa165552023440lgao    }
46630fdf1140b8d1ce93f3821d986fa165552023440lgao
46730fdf1140b8d1ce93f3821d986fa165552023440lgao    return ;
46830fdf1140b8d1ce93f3821d986fa165552023440lgao  }
46930fdf1140b8d1ce93f3821d986fa165552023440lgao
47030fdf1140b8d1ce93f3821d986fa165552023440lgao  Index = 0;
47130fdf1140b8d1ce93f3821d986fa165552023440lgao  while (Index < Number) {
47230fdf1140b8d1ce93f3821d986fa165552023440lgao
47330fdf1140b8d1ce93f3821d986fa165552023440lgao    CharC = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];
47430fdf1140b8d1ce93f3821d986fa165552023440lgao    if (CharC >= NT) {
47530fdf1140b8d1ce93f3821d986fa165552023440lgao      Mask = 1U << (BITBUFSIZ - 1 - 8);
47630fdf1140b8d1ce93f3821d986fa165552023440lgao
47730fdf1140b8d1ce93f3821d986fa165552023440lgao      do {
47830fdf1140b8d1ce93f3821d986fa165552023440lgao
47930fdf1140b8d1ce93f3821d986fa165552023440lgao        if (Mask & Sd->mBitBuf) {
48030fdf1140b8d1ce93f3821d986fa165552023440lgao          CharC = Sd->mRight[CharC];
48130fdf1140b8d1ce93f3821d986fa165552023440lgao        } else {
48230fdf1140b8d1ce93f3821d986fa165552023440lgao          CharC = Sd->mLeft[CharC];
48330fdf1140b8d1ce93f3821d986fa165552023440lgao        }
48430fdf1140b8d1ce93f3821d986fa165552023440lgao
48530fdf1140b8d1ce93f3821d986fa165552023440lgao        Mask >>= 1;
48630fdf1140b8d1ce93f3821d986fa165552023440lgao
48730fdf1140b8d1ce93f3821d986fa165552023440lgao      } while (CharC >= NT);
48830fdf1140b8d1ce93f3821d986fa165552023440lgao    }
48930fdf1140b8d1ce93f3821d986fa165552023440lgao    //
49030fdf1140b8d1ce93f3821d986fa165552023440lgao    // Advance what we have read
49130fdf1140b8d1ce93f3821d986fa165552023440lgao    //
49230fdf1140b8d1ce93f3821d986fa165552023440lgao    FillBuf (Sd, Sd->mPTLen[CharC]);
49330fdf1140b8d1ce93f3821d986fa165552023440lgao
49430fdf1140b8d1ce93f3821d986fa165552023440lgao    if (CharC <= 2) {
49530fdf1140b8d1ce93f3821d986fa165552023440lgao
49630fdf1140b8d1ce93f3821d986fa165552023440lgao      if (CharC == 0) {
49730fdf1140b8d1ce93f3821d986fa165552023440lgao        CharC = 1;
49830fdf1140b8d1ce93f3821d986fa165552023440lgao      } else if (CharC == 1) {
49930fdf1140b8d1ce93f3821d986fa165552023440lgao        CharC = (UINT16) (GetBits (Sd, 4) + 3);
50030fdf1140b8d1ce93f3821d986fa165552023440lgao      } else if (CharC == 2) {
50130fdf1140b8d1ce93f3821d986fa165552023440lgao        CharC = (UINT16) (GetBits (Sd, CBIT) + 20);
50230fdf1140b8d1ce93f3821d986fa165552023440lgao      }
50330fdf1140b8d1ce93f3821d986fa165552023440lgao
50430fdf1140b8d1ce93f3821d986fa165552023440lgao      CharC--;
50530fdf1140b8d1ce93f3821d986fa165552023440lgao      while ((INT16) (CharC) >= 0) {
50630fdf1140b8d1ce93f3821d986fa165552023440lgao        Sd->mCLen[Index++] = 0;
50730fdf1140b8d1ce93f3821d986fa165552023440lgao        CharC--;
50830fdf1140b8d1ce93f3821d986fa165552023440lgao      }
50930fdf1140b8d1ce93f3821d986fa165552023440lgao
51030fdf1140b8d1ce93f3821d986fa165552023440lgao    } else {
51130fdf1140b8d1ce93f3821d986fa165552023440lgao
51230fdf1140b8d1ce93f3821d986fa165552023440lgao      Sd->mCLen[Index++] = (UINT8) (CharC - 2);
51330fdf1140b8d1ce93f3821d986fa165552023440lgao
51430fdf1140b8d1ce93f3821d986fa165552023440lgao    }
51530fdf1140b8d1ce93f3821d986fa165552023440lgao  }
51630fdf1140b8d1ce93f3821d986fa165552023440lgao
51730fdf1140b8d1ce93f3821d986fa165552023440lgao  while (Index < NC) {
51830fdf1140b8d1ce93f3821d986fa165552023440lgao    Sd->mCLen[Index++] = 0;
51930fdf1140b8d1ce93f3821d986fa165552023440lgao  }
52030fdf1140b8d1ce93f3821d986fa165552023440lgao
52130fdf1140b8d1ce93f3821d986fa165552023440lgao  MakeTable (Sd, NC, Sd->mCLen, 12, Sd->mCTable);
52230fdf1140b8d1ce93f3821d986fa165552023440lgao
52330fdf1140b8d1ce93f3821d986fa165552023440lgao  return ;
52430fdf1140b8d1ce93f3821d986fa165552023440lgao}
52530fdf1140b8d1ce93f3821d986fa165552023440lgao
52630fdf1140b8d1ce93f3821d986fa165552023440lgaoSTATIC
52730fdf1140b8d1ce93f3821d986fa165552023440lgaoUINT16
52830fdf1140b8d1ce93f3821d986fa165552023440lgaoDecodeC (
52930fdf1140b8d1ce93f3821d986fa165552023440lgao  SCRATCH_DATA  *Sd
53030fdf1140b8d1ce93f3821d986fa165552023440lgao  )
53130fdf1140b8d1ce93f3821d986fa165552023440lgao/*++
53230fdf1140b8d1ce93f3821d986fa165552023440lgao
53330fdf1140b8d1ce93f3821d986fa165552023440lgaoRoutine Description:
53430fdf1140b8d1ce93f3821d986fa165552023440lgao
53530fdf1140b8d1ce93f3821d986fa165552023440lgao  Decode a character/length value.
53630fdf1140b8d1ce93f3821d986fa165552023440lgao
53730fdf1140b8d1ce93f3821d986fa165552023440lgaoArguments:
53830fdf1140b8d1ce93f3821d986fa165552023440lgao
53930fdf1140b8d1ce93f3821d986fa165552023440lgao  Sd    - The global scratch data.
54030fdf1140b8d1ce93f3821d986fa165552023440lgao
54130fdf1140b8d1ce93f3821d986fa165552023440lgaoReturns:
54230fdf1140b8d1ce93f3821d986fa165552023440lgao
54330fdf1140b8d1ce93f3821d986fa165552023440lgao  The value decoded.
54430fdf1140b8d1ce93f3821d986fa165552023440lgao
54530fdf1140b8d1ce93f3821d986fa165552023440lgao--*/
54630fdf1140b8d1ce93f3821d986fa165552023440lgao{
54730fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT16  Index2;
54830fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT32  Mask;
54930fdf1140b8d1ce93f3821d986fa165552023440lgao
55030fdf1140b8d1ce93f3821d986fa165552023440lgao  if (Sd->mBlockSize == 0) {
55130fdf1140b8d1ce93f3821d986fa165552023440lgao    //
55230fdf1140b8d1ce93f3821d986fa165552023440lgao    // Starting a new block
55330fdf1140b8d1ce93f3821d986fa165552023440lgao    //
55430fdf1140b8d1ce93f3821d986fa165552023440lgao    Sd->mBlockSize    = (UINT16) GetBits (Sd, 16);
55530fdf1140b8d1ce93f3821d986fa165552023440lgao    Sd->mBadTableFlag = ReadPTLen (Sd, NT, TBIT, 3);
55630fdf1140b8d1ce93f3821d986fa165552023440lgao    if (Sd->mBadTableFlag != 0) {
55730fdf1140b8d1ce93f3821d986fa165552023440lgao      return 0;
55830fdf1140b8d1ce93f3821d986fa165552023440lgao    }
55930fdf1140b8d1ce93f3821d986fa165552023440lgao
56030fdf1140b8d1ce93f3821d986fa165552023440lgao    ReadCLen (Sd);
56130fdf1140b8d1ce93f3821d986fa165552023440lgao
56230fdf1140b8d1ce93f3821d986fa165552023440lgao    Sd->mBadTableFlag = ReadPTLen (Sd, MAXNP, mPbit, (UINT16) (-1));
56330fdf1140b8d1ce93f3821d986fa165552023440lgao    if (Sd->mBadTableFlag != 0) {
56430fdf1140b8d1ce93f3821d986fa165552023440lgao      return 0;
56530fdf1140b8d1ce93f3821d986fa165552023440lgao    }
56630fdf1140b8d1ce93f3821d986fa165552023440lgao  }
56730fdf1140b8d1ce93f3821d986fa165552023440lgao
56830fdf1140b8d1ce93f3821d986fa165552023440lgao  Sd->mBlockSize--;
56930fdf1140b8d1ce93f3821d986fa165552023440lgao  Index2 = Sd->mCTable[Sd->mBitBuf >> (BITBUFSIZ - 12)];
57030fdf1140b8d1ce93f3821d986fa165552023440lgao
57130fdf1140b8d1ce93f3821d986fa165552023440lgao  if (Index2 >= NC) {
57230fdf1140b8d1ce93f3821d986fa165552023440lgao    Mask = 1U << (BITBUFSIZ - 1 - 12);
57330fdf1140b8d1ce93f3821d986fa165552023440lgao
57430fdf1140b8d1ce93f3821d986fa165552023440lgao    do {
57530fdf1140b8d1ce93f3821d986fa165552023440lgao      if (Sd->mBitBuf & Mask) {
57630fdf1140b8d1ce93f3821d986fa165552023440lgao        Index2 = Sd->mRight[Index2];
57730fdf1140b8d1ce93f3821d986fa165552023440lgao      } else {
57830fdf1140b8d1ce93f3821d986fa165552023440lgao        Index2 = Sd->mLeft[Index2];
57930fdf1140b8d1ce93f3821d986fa165552023440lgao      }
58030fdf1140b8d1ce93f3821d986fa165552023440lgao
58130fdf1140b8d1ce93f3821d986fa165552023440lgao      Mask >>= 1;
58230fdf1140b8d1ce93f3821d986fa165552023440lgao    } while (Index2 >= NC);
58330fdf1140b8d1ce93f3821d986fa165552023440lgao  }
58430fdf1140b8d1ce93f3821d986fa165552023440lgao  //
58530fdf1140b8d1ce93f3821d986fa165552023440lgao  // Advance what we have read
58630fdf1140b8d1ce93f3821d986fa165552023440lgao  //
58730fdf1140b8d1ce93f3821d986fa165552023440lgao  FillBuf (Sd, Sd->mCLen[Index2]);
58830fdf1140b8d1ce93f3821d986fa165552023440lgao
58930fdf1140b8d1ce93f3821d986fa165552023440lgao  return Index2;
59030fdf1140b8d1ce93f3821d986fa165552023440lgao}
59130fdf1140b8d1ce93f3821d986fa165552023440lgao
59230fdf1140b8d1ce93f3821d986fa165552023440lgaoSTATIC
59330fdf1140b8d1ce93f3821d986fa165552023440lgaoVOID
59430fdf1140b8d1ce93f3821d986fa165552023440lgaoDecode (
59530fdf1140b8d1ce93f3821d986fa165552023440lgao  SCRATCH_DATA  *Sd
59630fdf1140b8d1ce93f3821d986fa165552023440lgao  )
59730fdf1140b8d1ce93f3821d986fa165552023440lgao/*++
59830fdf1140b8d1ce93f3821d986fa165552023440lgao
59930fdf1140b8d1ce93f3821d986fa165552023440lgaoRoutine Description:
60030fdf1140b8d1ce93f3821d986fa165552023440lgao
60130fdf1140b8d1ce93f3821d986fa165552023440lgao  Decode the source data and put the resulting data into the destination buffer.
60230fdf1140b8d1ce93f3821d986fa165552023440lgao
60330fdf1140b8d1ce93f3821d986fa165552023440lgaoArguments:
60430fdf1140b8d1ce93f3821d986fa165552023440lgao
60530fdf1140b8d1ce93f3821d986fa165552023440lgao  Sd            - The global scratch data
60630fdf1140b8d1ce93f3821d986fa165552023440lgao
60730fdf1140b8d1ce93f3821d986fa165552023440lgaoReturns: (VOID)
60830fdf1140b8d1ce93f3821d986fa165552023440lgao
60930fdf1140b8d1ce93f3821d986fa165552023440lgao --*/
61030fdf1140b8d1ce93f3821d986fa165552023440lgao{
61130fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT16  BytesRemain;
61230fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT32  DataIdx;
61330fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT16  CharC;
61430fdf1140b8d1ce93f3821d986fa165552023440lgao
61530fdf1140b8d1ce93f3821d986fa165552023440lgao  BytesRemain = (UINT16) (-1);
61630fdf1140b8d1ce93f3821d986fa165552023440lgao
61730fdf1140b8d1ce93f3821d986fa165552023440lgao  DataIdx     = 0;
61830fdf1140b8d1ce93f3821d986fa165552023440lgao
61930fdf1140b8d1ce93f3821d986fa165552023440lgao  for (;;) {
62030fdf1140b8d1ce93f3821d986fa165552023440lgao    CharC = DecodeC (Sd);
62130fdf1140b8d1ce93f3821d986fa165552023440lgao    if (Sd->mBadTableFlag != 0) {
62230fdf1140b8d1ce93f3821d986fa165552023440lgao      return ;
62330fdf1140b8d1ce93f3821d986fa165552023440lgao    }
62430fdf1140b8d1ce93f3821d986fa165552023440lgao
62530fdf1140b8d1ce93f3821d986fa165552023440lgao    if (CharC < 256) {
62630fdf1140b8d1ce93f3821d986fa165552023440lgao      //
62730fdf1140b8d1ce93f3821d986fa165552023440lgao      // Process an Original character
62830fdf1140b8d1ce93f3821d986fa165552023440lgao      //
62930fdf1140b8d1ce93f3821d986fa165552023440lgao      Sd->mDstBase[Sd->mOutBuf++] = (UINT8) CharC;
63030fdf1140b8d1ce93f3821d986fa165552023440lgao      if (Sd->mOutBuf >= Sd->mOrigSize) {
63130fdf1140b8d1ce93f3821d986fa165552023440lgao        return ;
63230fdf1140b8d1ce93f3821d986fa165552023440lgao      }
63330fdf1140b8d1ce93f3821d986fa165552023440lgao
63430fdf1140b8d1ce93f3821d986fa165552023440lgao    } else {
63530fdf1140b8d1ce93f3821d986fa165552023440lgao      //
63630fdf1140b8d1ce93f3821d986fa165552023440lgao      // Process a Pointer
63730fdf1140b8d1ce93f3821d986fa165552023440lgao      //
63830fdf1140b8d1ce93f3821d986fa165552023440lgao      CharC       = (UINT16) (CharC - (UINT8_MAX + 1 - THRESHOLD));
63930fdf1140b8d1ce93f3821d986fa165552023440lgao
64030fdf1140b8d1ce93f3821d986fa165552023440lgao      BytesRemain = CharC;
64130fdf1140b8d1ce93f3821d986fa165552023440lgao
64230fdf1140b8d1ce93f3821d986fa165552023440lgao      DataIdx     = Sd->mOutBuf - DecodeP (Sd) - 1;
64330fdf1140b8d1ce93f3821d986fa165552023440lgao
64430fdf1140b8d1ce93f3821d986fa165552023440lgao      BytesRemain--;
64530fdf1140b8d1ce93f3821d986fa165552023440lgao      while ((INT16) (BytesRemain) >= 0) {
64630fdf1140b8d1ce93f3821d986fa165552023440lgao        Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];
64730fdf1140b8d1ce93f3821d986fa165552023440lgao        if (Sd->mOutBuf >= Sd->mOrigSize) {
64830fdf1140b8d1ce93f3821d986fa165552023440lgao          return ;
64930fdf1140b8d1ce93f3821d986fa165552023440lgao        }
65030fdf1140b8d1ce93f3821d986fa165552023440lgao
65130fdf1140b8d1ce93f3821d986fa165552023440lgao        BytesRemain--;
65230fdf1140b8d1ce93f3821d986fa165552023440lgao      }
65330fdf1140b8d1ce93f3821d986fa165552023440lgao    }
65430fdf1140b8d1ce93f3821d986fa165552023440lgao  }
65530fdf1140b8d1ce93f3821d986fa165552023440lgao
65630fdf1140b8d1ce93f3821d986fa165552023440lgao  return ;
65730fdf1140b8d1ce93f3821d986fa165552023440lgao}
65830fdf1140b8d1ce93f3821d986fa165552023440lgao
65930fdf1140b8d1ce93f3821d986fa165552023440lgaoEFI_STATUS
66030fdf1140b8d1ce93f3821d986fa165552023440lgaoGetInfo (
66130fdf1140b8d1ce93f3821d986fa165552023440lgao  IN      VOID    *Source,
66230fdf1140b8d1ce93f3821d986fa165552023440lgao  IN      UINT32  SrcSize,
66330fdf1140b8d1ce93f3821d986fa165552023440lgao  OUT     UINT32  *DstSize,
66430fdf1140b8d1ce93f3821d986fa165552023440lgao  OUT     UINT32  *ScratchSize
66530fdf1140b8d1ce93f3821d986fa165552023440lgao  )
66630fdf1140b8d1ce93f3821d986fa165552023440lgao/*++
66730fdf1140b8d1ce93f3821d986fa165552023440lgao
66830fdf1140b8d1ce93f3821d986fa165552023440lgaoRoutine Description:
66930fdf1140b8d1ce93f3821d986fa165552023440lgao
67030fdf1140b8d1ce93f3821d986fa165552023440lgao  The implementation of EFI_DECOMPRESS_PROTOCOL.GetInfo().
67130fdf1140b8d1ce93f3821d986fa165552023440lgao
67230fdf1140b8d1ce93f3821d986fa165552023440lgaoArguments:
67330fdf1140b8d1ce93f3821d986fa165552023440lgao
67430fdf1140b8d1ce93f3821d986fa165552023440lgao  Source      - The source buffer containing the compressed data.
67530fdf1140b8d1ce93f3821d986fa165552023440lgao  SrcSize     - The size of source buffer
67630fdf1140b8d1ce93f3821d986fa165552023440lgao  DstSize     - The size of destination buffer.
67730fdf1140b8d1ce93f3821d986fa165552023440lgao  ScratchSize - The size of scratch buffer.
67830fdf1140b8d1ce93f3821d986fa165552023440lgao
67930fdf1140b8d1ce93f3821d986fa165552023440lgaoReturns:
68030fdf1140b8d1ce93f3821d986fa165552023440lgao
68199e55970ff0778ad46177a9c0fafb0766d4e6837Gary Lin  EFI_SUCCESS           - The size of destination buffer and the size of scratch buffer are successfully retrieved.
68230fdf1140b8d1ce93f3821d986fa165552023440lgao  EFI_INVALID_PARAMETER - The source data is corrupted
68330fdf1140b8d1ce93f3821d986fa165552023440lgao
68430fdf1140b8d1ce93f3821d986fa165552023440lgao--*/
68530fdf1140b8d1ce93f3821d986fa165552023440lgao{
68630fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT8 *Src;
68730fdf1140b8d1ce93f3821d986fa165552023440lgao
68830fdf1140b8d1ce93f3821d986fa165552023440lgao  *ScratchSize  = sizeof (SCRATCH_DATA);
68930fdf1140b8d1ce93f3821d986fa165552023440lgao
69030fdf1140b8d1ce93f3821d986fa165552023440lgao  Src           = Source;
69130fdf1140b8d1ce93f3821d986fa165552023440lgao  if (SrcSize < 8) {
69230fdf1140b8d1ce93f3821d986fa165552023440lgao    return EFI_INVALID_PARAMETER;
69330fdf1140b8d1ce93f3821d986fa165552023440lgao  }
69430fdf1140b8d1ce93f3821d986fa165552023440lgao
69530fdf1140b8d1ce93f3821d986fa165552023440lgao  *DstSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);
69630fdf1140b8d1ce93f3821d986fa165552023440lgao  return EFI_SUCCESS;
69730fdf1140b8d1ce93f3821d986fa165552023440lgao}
69830fdf1140b8d1ce93f3821d986fa165552023440lgao
69930fdf1140b8d1ce93f3821d986fa165552023440lgaoEFI_STATUS
70030fdf1140b8d1ce93f3821d986fa165552023440lgaoDecompress (
70130fdf1140b8d1ce93f3821d986fa165552023440lgao  IN      VOID    *Source,
70230fdf1140b8d1ce93f3821d986fa165552023440lgao  IN      UINT32  SrcSize,
70330fdf1140b8d1ce93f3821d986fa165552023440lgao  IN OUT  VOID    *Destination,
70430fdf1140b8d1ce93f3821d986fa165552023440lgao  IN      UINT32  DstSize,
70530fdf1140b8d1ce93f3821d986fa165552023440lgao  IN OUT  VOID    *Scratch,
70630fdf1140b8d1ce93f3821d986fa165552023440lgao  IN      UINT32  ScratchSize
70730fdf1140b8d1ce93f3821d986fa165552023440lgao  )
70830fdf1140b8d1ce93f3821d986fa165552023440lgao/*++
70930fdf1140b8d1ce93f3821d986fa165552023440lgao
71030fdf1140b8d1ce93f3821d986fa165552023440lgaoRoutine Description:
71130fdf1140b8d1ce93f3821d986fa165552023440lgao
71230fdf1140b8d1ce93f3821d986fa165552023440lgao  The implementation Efi and Tiano Decompress().
71330fdf1140b8d1ce93f3821d986fa165552023440lgao
71430fdf1140b8d1ce93f3821d986fa165552023440lgaoArguments:
71530fdf1140b8d1ce93f3821d986fa165552023440lgao
71630fdf1140b8d1ce93f3821d986fa165552023440lgao  Source      - The source buffer containing the compressed data.
71730fdf1140b8d1ce93f3821d986fa165552023440lgao  SrcSize     - The size of source buffer
71830fdf1140b8d1ce93f3821d986fa165552023440lgao  Destination - The destination buffer to store the decompressed data
71930fdf1140b8d1ce93f3821d986fa165552023440lgao  DstSize     - The size of destination buffer.
72030fdf1140b8d1ce93f3821d986fa165552023440lgao  Scratch     - The buffer used internally by the decompress routine. This  buffer is needed to store intermediate data.
72130fdf1140b8d1ce93f3821d986fa165552023440lgao  ScratchSize - The size of scratch buffer.
72230fdf1140b8d1ce93f3821d986fa165552023440lgao
72330fdf1140b8d1ce93f3821d986fa165552023440lgaoReturns:
72430fdf1140b8d1ce93f3821d986fa165552023440lgao
72530fdf1140b8d1ce93f3821d986fa165552023440lgao  EFI_SUCCESS           - Decompression is successfull
72630fdf1140b8d1ce93f3821d986fa165552023440lgao  EFI_INVALID_PARAMETER - The source data is corrupted
72730fdf1140b8d1ce93f3821d986fa165552023440lgao
72830fdf1140b8d1ce93f3821d986fa165552023440lgao--*/
72930fdf1140b8d1ce93f3821d986fa165552023440lgao{
73030fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT32        Index;
73130fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT32        CompSize;
73230fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT32        OrigSize;
73330fdf1140b8d1ce93f3821d986fa165552023440lgao  EFI_STATUS    Status;
73430fdf1140b8d1ce93f3821d986fa165552023440lgao  SCRATCH_DATA  *Sd;
73530fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT8         *Src;
73630fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT8         *Dst;
73730fdf1140b8d1ce93f3821d986fa165552023440lgao
73830fdf1140b8d1ce93f3821d986fa165552023440lgao  Status  = EFI_SUCCESS;
73930fdf1140b8d1ce93f3821d986fa165552023440lgao  Src     = Source;
74030fdf1140b8d1ce93f3821d986fa165552023440lgao  Dst     = Destination;
74130fdf1140b8d1ce93f3821d986fa165552023440lgao
74230fdf1140b8d1ce93f3821d986fa165552023440lgao  if (ScratchSize < sizeof (SCRATCH_DATA)) {
74330fdf1140b8d1ce93f3821d986fa165552023440lgao    return EFI_INVALID_PARAMETER;
74430fdf1140b8d1ce93f3821d986fa165552023440lgao  }
74530fdf1140b8d1ce93f3821d986fa165552023440lgao
74630fdf1140b8d1ce93f3821d986fa165552023440lgao  Sd = (SCRATCH_DATA *) Scratch;
74730fdf1140b8d1ce93f3821d986fa165552023440lgao
74830fdf1140b8d1ce93f3821d986fa165552023440lgao  if (SrcSize < 8) {
74930fdf1140b8d1ce93f3821d986fa165552023440lgao    return EFI_INVALID_PARAMETER;
75030fdf1140b8d1ce93f3821d986fa165552023440lgao  }
75130fdf1140b8d1ce93f3821d986fa165552023440lgao
75230fdf1140b8d1ce93f3821d986fa165552023440lgao  CompSize  = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);
75330fdf1140b8d1ce93f3821d986fa165552023440lgao  OrigSize  = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);
75430fdf1140b8d1ce93f3821d986fa165552023440lgao
75530fdf1140b8d1ce93f3821d986fa165552023440lgao  if (SrcSize < CompSize + 8) {
75630fdf1140b8d1ce93f3821d986fa165552023440lgao    return EFI_INVALID_PARAMETER;
75730fdf1140b8d1ce93f3821d986fa165552023440lgao  }
75830fdf1140b8d1ce93f3821d986fa165552023440lgao
75930fdf1140b8d1ce93f3821d986fa165552023440lgao  if (DstSize != OrigSize) {
76030fdf1140b8d1ce93f3821d986fa165552023440lgao    return EFI_INVALID_PARAMETER;
76130fdf1140b8d1ce93f3821d986fa165552023440lgao  }
76230fdf1140b8d1ce93f3821d986fa165552023440lgao
76330fdf1140b8d1ce93f3821d986fa165552023440lgao  Src = Src + 8;
76430fdf1140b8d1ce93f3821d986fa165552023440lgao
76530fdf1140b8d1ce93f3821d986fa165552023440lgao  for (Index = 0; Index < sizeof (SCRATCH_DATA); Index++) {
76630fdf1140b8d1ce93f3821d986fa165552023440lgao    ((UINT8 *) Sd)[Index] = 0;
76730fdf1140b8d1ce93f3821d986fa165552023440lgao  }
76830fdf1140b8d1ce93f3821d986fa165552023440lgao
76930fdf1140b8d1ce93f3821d986fa165552023440lgao  Sd->mSrcBase  = Src;
77030fdf1140b8d1ce93f3821d986fa165552023440lgao  Sd->mDstBase  = Dst;
77130fdf1140b8d1ce93f3821d986fa165552023440lgao  Sd->mCompSize = CompSize;
77230fdf1140b8d1ce93f3821d986fa165552023440lgao  Sd->mOrigSize = OrigSize;
77330fdf1140b8d1ce93f3821d986fa165552023440lgao
77430fdf1140b8d1ce93f3821d986fa165552023440lgao  //
77530fdf1140b8d1ce93f3821d986fa165552023440lgao  // Fill the first BITBUFSIZ bits
77630fdf1140b8d1ce93f3821d986fa165552023440lgao  //
77730fdf1140b8d1ce93f3821d986fa165552023440lgao  FillBuf (Sd, BITBUFSIZ);
77830fdf1140b8d1ce93f3821d986fa165552023440lgao
77930fdf1140b8d1ce93f3821d986fa165552023440lgao  //
78030fdf1140b8d1ce93f3821d986fa165552023440lgao  // Decompress it
78130fdf1140b8d1ce93f3821d986fa165552023440lgao  //
78230fdf1140b8d1ce93f3821d986fa165552023440lgao  Decode (Sd);
78330fdf1140b8d1ce93f3821d986fa165552023440lgao
78430fdf1140b8d1ce93f3821d986fa165552023440lgao  if (Sd->mBadTableFlag != 0) {
78530fdf1140b8d1ce93f3821d986fa165552023440lgao    //
78630fdf1140b8d1ce93f3821d986fa165552023440lgao    // Something wrong with the source
78730fdf1140b8d1ce93f3821d986fa165552023440lgao    //
78830fdf1140b8d1ce93f3821d986fa165552023440lgao    Status = EFI_INVALID_PARAMETER;
78930fdf1140b8d1ce93f3821d986fa165552023440lgao  }
79030fdf1140b8d1ce93f3821d986fa165552023440lgao
79130fdf1140b8d1ce93f3821d986fa165552023440lgao  return Status;
79230fdf1140b8d1ce93f3821d986fa165552023440lgao}
79330fdf1140b8d1ce93f3821d986fa165552023440lgao
79430fdf1140b8d1ce93f3821d986fa165552023440lgaoEFI_STATUS
79530fdf1140b8d1ce93f3821d986fa165552023440lgaoEfiGetInfo (
79630fdf1140b8d1ce93f3821d986fa165552023440lgao  IN      VOID    *Source,
79730fdf1140b8d1ce93f3821d986fa165552023440lgao  IN      UINT32  SrcSize,
79830fdf1140b8d1ce93f3821d986fa165552023440lgao  OUT     UINT32  *DstSize,
79930fdf1140b8d1ce93f3821d986fa165552023440lgao  OUT     UINT32  *ScratchSize
80030fdf1140b8d1ce93f3821d986fa165552023440lgao  )
80130fdf1140b8d1ce93f3821d986fa165552023440lgao/*++
80230fdf1140b8d1ce93f3821d986fa165552023440lgao
80330fdf1140b8d1ce93f3821d986fa165552023440lgaoRoutine Description:
80430fdf1140b8d1ce93f3821d986fa165552023440lgao
80530fdf1140b8d1ce93f3821d986fa165552023440lgao  The implementation Efi Decompress GetInfo().
80630fdf1140b8d1ce93f3821d986fa165552023440lgao
80730fdf1140b8d1ce93f3821d986fa165552023440lgaoArguments:
80830fdf1140b8d1ce93f3821d986fa165552023440lgao
80930fdf1140b8d1ce93f3821d986fa165552023440lgao  Source      - The source buffer containing the compressed data.
81030fdf1140b8d1ce93f3821d986fa165552023440lgao  SrcSize     - The size of source buffer
81130fdf1140b8d1ce93f3821d986fa165552023440lgao  DstSize     - The size of destination buffer.
81230fdf1140b8d1ce93f3821d986fa165552023440lgao  ScratchSize - The size of scratch buffer.
81330fdf1140b8d1ce93f3821d986fa165552023440lgao
81430fdf1140b8d1ce93f3821d986fa165552023440lgaoReturns:
81530fdf1140b8d1ce93f3821d986fa165552023440lgao
81699e55970ff0778ad46177a9c0fafb0766d4e6837Gary Lin  EFI_SUCCESS           - The size of destination buffer and the size of scratch buffer are successfully retrieved.
81730fdf1140b8d1ce93f3821d986fa165552023440lgao  EFI_INVALID_PARAMETER - The source data is corrupted
81830fdf1140b8d1ce93f3821d986fa165552023440lgao
81930fdf1140b8d1ce93f3821d986fa165552023440lgao--*/
82030fdf1140b8d1ce93f3821d986fa165552023440lgao{
82130fdf1140b8d1ce93f3821d986fa165552023440lgao  return GetInfo (Source, SrcSize, DstSize, ScratchSize);
82230fdf1140b8d1ce93f3821d986fa165552023440lgao}
82330fdf1140b8d1ce93f3821d986fa165552023440lgao
82430fdf1140b8d1ce93f3821d986fa165552023440lgaoEFI_STATUS
82530fdf1140b8d1ce93f3821d986fa165552023440lgaoTianoGetInfo (
82630fdf1140b8d1ce93f3821d986fa165552023440lgao  IN      VOID    *Source,
82730fdf1140b8d1ce93f3821d986fa165552023440lgao  IN      UINT32  SrcSize,
82830fdf1140b8d1ce93f3821d986fa165552023440lgao  OUT     UINT32  *DstSize,
82930fdf1140b8d1ce93f3821d986fa165552023440lgao  OUT     UINT32  *ScratchSize
83030fdf1140b8d1ce93f3821d986fa165552023440lgao  )
83130fdf1140b8d1ce93f3821d986fa165552023440lgao/*++
83230fdf1140b8d1ce93f3821d986fa165552023440lgao
83330fdf1140b8d1ce93f3821d986fa165552023440lgaoRoutine Description:
83430fdf1140b8d1ce93f3821d986fa165552023440lgao
83530fdf1140b8d1ce93f3821d986fa165552023440lgao  The implementation Tiano Decompress GetInfo().
83630fdf1140b8d1ce93f3821d986fa165552023440lgao
83730fdf1140b8d1ce93f3821d986fa165552023440lgaoArguments:
83830fdf1140b8d1ce93f3821d986fa165552023440lgao
83930fdf1140b8d1ce93f3821d986fa165552023440lgao  Source      - The source buffer containing the compressed data.
84030fdf1140b8d1ce93f3821d986fa165552023440lgao  SrcSize     - The size of source buffer
84130fdf1140b8d1ce93f3821d986fa165552023440lgao  DstSize     - The size of destination buffer.
84230fdf1140b8d1ce93f3821d986fa165552023440lgao  ScratchSize - The size of scratch buffer.
84330fdf1140b8d1ce93f3821d986fa165552023440lgao
84430fdf1140b8d1ce93f3821d986fa165552023440lgaoReturns:
84530fdf1140b8d1ce93f3821d986fa165552023440lgao
84699e55970ff0778ad46177a9c0fafb0766d4e6837Gary Lin  EFI_SUCCESS           - The size of destination buffer and the size of scratch buffer are successfully retrieved.
84730fdf1140b8d1ce93f3821d986fa165552023440lgao  EFI_INVALID_PARAMETER - The source data is corrupted
84830fdf1140b8d1ce93f3821d986fa165552023440lgao
84930fdf1140b8d1ce93f3821d986fa165552023440lgao--*/
85030fdf1140b8d1ce93f3821d986fa165552023440lgao{
85130fdf1140b8d1ce93f3821d986fa165552023440lgao  return GetInfo (Source, SrcSize, DstSize, ScratchSize);
85230fdf1140b8d1ce93f3821d986fa165552023440lgao}
85330fdf1140b8d1ce93f3821d986fa165552023440lgao
85430fdf1140b8d1ce93f3821d986fa165552023440lgaoEFI_STATUS
85530fdf1140b8d1ce93f3821d986fa165552023440lgaoEfiDecompress (
85630fdf1140b8d1ce93f3821d986fa165552023440lgao  IN      VOID    *Source,
85730fdf1140b8d1ce93f3821d986fa165552023440lgao  IN      UINT32  SrcSize,
85830fdf1140b8d1ce93f3821d986fa165552023440lgao  IN OUT  VOID    *Destination,
85930fdf1140b8d1ce93f3821d986fa165552023440lgao  IN      UINT32  DstSize,
86030fdf1140b8d1ce93f3821d986fa165552023440lgao  IN OUT  VOID    *Scratch,
86130fdf1140b8d1ce93f3821d986fa165552023440lgao  IN      UINT32  ScratchSize
86230fdf1140b8d1ce93f3821d986fa165552023440lgao  )
86330fdf1140b8d1ce93f3821d986fa165552023440lgao/*++
86430fdf1140b8d1ce93f3821d986fa165552023440lgao
86530fdf1140b8d1ce93f3821d986fa165552023440lgaoRoutine Description:
86630fdf1140b8d1ce93f3821d986fa165552023440lgao
86730fdf1140b8d1ce93f3821d986fa165552023440lgao  The implementation of Efi Decompress().
86830fdf1140b8d1ce93f3821d986fa165552023440lgao
86930fdf1140b8d1ce93f3821d986fa165552023440lgaoArguments:
87030fdf1140b8d1ce93f3821d986fa165552023440lgao
87130fdf1140b8d1ce93f3821d986fa165552023440lgao  Source      - The source buffer containing the compressed data.
87230fdf1140b8d1ce93f3821d986fa165552023440lgao  SrcSize     - The size of source buffer
87330fdf1140b8d1ce93f3821d986fa165552023440lgao  Destination - The destination buffer to store the decompressed data
87430fdf1140b8d1ce93f3821d986fa165552023440lgao  DstSize     - The size of destination buffer.
87530fdf1140b8d1ce93f3821d986fa165552023440lgao  Scratch     - The buffer used internally by the decompress routine. This  buffer is needed to store intermediate data.
87630fdf1140b8d1ce93f3821d986fa165552023440lgao  ScratchSize - The size of scratch buffer.
87730fdf1140b8d1ce93f3821d986fa165552023440lgao
87830fdf1140b8d1ce93f3821d986fa165552023440lgaoReturns:
87930fdf1140b8d1ce93f3821d986fa165552023440lgao
88030fdf1140b8d1ce93f3821d986fa165552023440lgao  EFI_SUCCESS           - Decompression is successfull
88130fdf1140b8d1ce93f3821d986fa165552023440lgao  EFI_INVALID_PARAMETER - The source data is corrupted
88230fdf1140b8d1ce93f3821d986fa165552023440lgao
88330fdf1140b8d1ce93f3821d986fa165552023440lgao--*/
88430fdf1140b8d1ce93f3821d986fa165552023440lgao{
88530fdf1140b8d1ce93f3821d986fa165552023440lgao  mPbit = EFIPBIT;
88630fdf1140b8d1ce93f3821d986fa165552023440lgao  return Decompress (Source, SrcSize, Destination, DstSize, Scratch, ScratchSize);
88730fdf1140b8d1ce93f3821d986fa165552023440lgao}
88830fdf1140b8d1ce93f3821d986fa165552023440lgao
88930fdf1140b8d1ce93f3821d986fa165552023440lgaoEFI_STATUS
89030fdf1140b8d1ce93f3821d986fa165552023440lgaoTianoDecompress (
89130fdf1140b8d1ce93f3821d986fa165552023440lgao  IN      VOID    *Source,
89230fdf1140b8d1ce93f3821d986fa165552023440lgao  IN      UINT32  SrcSize,
89330fdf1140b8d1ce93f3821d986fa165552023440lgao  IN OUT  VOID    *Destination,
89430fdf1140b8d1ce93f3821d986fa165552023440lgao  IN      UINT32  DstSize,
89530fdf1140b8d1ce93f3821d986fa165552023440lgao  IN OUT  VOID    *Scratch,
89630fdf1140b8d1ce93f3821d986fa165552023440lgao  IN      UINT32  ScratchSize
89730fdf1140b8d1ce93f3821d986fa165552023440lgao  )
89830fdf1140b8d1ce93f3821d986fa165552023440lgao/*++
89930fdf1140b8d1ce93f3821d986fa165552023440lgao
90030fdf1140b8d1ce93f3821d986fa165552023440lgaoRoutine Description:
90130fdf1140b8d1ce93f3821d986fa165552023440lgao
90230fdf1140b8d1ce93f3821d986fa165552023440lgao  The implementation of Tiano Decompress().
90330fdf1140b8d1ce93f3821d986fa165552023440lgao
90430fdf1140b8d1ce93f3821d986fa165552023440lgaoArguments:
90530fdf1140b8d1ce93f3821d986fa165552023440lgao
90630fdf1140b8d1ce93f3821d986fa165552023440lgao  Source      - The source buffer containing the compressed data.
90730fdf1140b8d1ce93f3821d986fa165552023440lgao  SrcSize     - The size of source buffer
90830fdf1140b8d1ce93f3821d986fa165552023440lgao  Destination - The destination buffer to store the decompressed data
90930fdf1140b8d1ce93f3821d986fa165552023440lgao  DstSize     - The size of destination buffer.
91030fdf1140b8d1ce93f3821d986fa165552023440lgao  Scratch     - The buffer used internally by the decompress routine. This  buffer is needed to store intermediate data.
91130fdf1140b8d1ce93f3821d986fa165552023440lgao  ScratchSize - The size of scratch buffer.
91230fdf1140b8d1ce93f3821d986fa165552023440lgao
91330fdf1140b8d1ce93f3821d986fa165552023440lgaoReturns:
91430fdf1140b8d1ce93f3821d986fa165552023440lgao
91530fdf1140b8d1ce93f3821d986fa165552023440lgao  EFI_SUCCESS           - Decompression is successfull
91630fdf1140b8d1ce93f3821d986fa165552023440lgao  EFI_INVALID_PARAMETER - The source data is corrupted
91730fdf1140b8d1ce93f3821d986fa165552023440lgao
91830fdf1140b8d1ce93f3821d986fa165552023440lgao--*/
91930fdf1140b8d1ce93f3821d986fa165552023440lgao{
92030fdf1140b8d1ce93f3821d986fa165552023440lgao  mPbit = MAXPBIT;
92130fdf1140b8d1ce93f3821d986fa165552023440lgao  return Decompress (Source, SrcSize, Destination, DstSize, Scratch, ScratchSize);
92230fdf1140b8d1ce93f3821d986fa165552023440lgao}
92330fdf1140b8d1ce93f3821d986fa165552023440lgao
92430fdf1140b8d1ce93f3821d986fa165552023440lgaoEFI_STATUS
92530fdf1140b8d1ce93f3821d986fa165552023440lgaoExtract (
92630fdf1140b8d1ce93f3821d986fa165552023440lgao  IN      VOID    *Source,
92730fdf1140b8d1ce93f3821d986fa165552023440lgao  IN      UINT32  SrcSize,
92830fdf1140b8d1ce93f3821d986fa165552023440lgao     OUT  VOID    **Destination,
92930fdf1140b8d1ce93f3821d986fa165552023440lgao     OUT  UINT32  *DstSize,
93030fdf1140b8d1ce93f3821d986fa165552023440lgao  IN      UINTN   Algorithm
93130fdf1140b8d1ce93f3821d986fa165552023440lgao  )
93230fdf1140b8d1ce93f3821d986fa165552023440lgao{
93330fdf1140b8d1ce93f3821d986fa165552023440lgao  VOID          *Scratch;
93430fdf1140b8d1ce93f3821d986fa165552023440lgao  UINT32        ScratchSize;
93530fdf1140b8d1ce93f3821d986fa165552023440lgao  EFI_STATUS    Status;
93630fdf1140b8d1ce93f3821d986fa165552023440lgao
937aee346514d224a90622fe4cc553ba8ae79fe2828Hao Wu  Scratch = NULL;
938aee346514d224a90622fe4cc553ba8ae79fe2828Hao Wu  Status  = EFI_SUCCESS;
939aee346514d224a90622fe4cc553ba8ae79fe2828Hao Wu
94030fdf1140b8d1ce93f3821d986fa165552023440lgao  switch (Algorithm) {
94130fdf1140b8d1ce93f3821d986fa165552023440lgao  case 0:
94230fdf1140b8d1ce93f3821d986fa165552023440lgao    *Destination = (VOID *)malloc(SrcSize);
94330fdf1140b8d1ce93f3821d986fa165552023440lgao    if (*Destination != NULL) {
94430fdf1140b8d1ce93f3821d986fa165552023440lgao      memcpy(*Destination, Source, SrcSize);
94530fdf1140b8d1ce93f3821d986fa165552023440lgao    } else {
94630fdf1140b8d1ce93f3821d986fa165552023440lgao      Status = EFI_OUT_OF_RESOURCES;
94730fdf1140b8d1ce93f3821d986fa165552023440lgao    }
94830fdf1140b8d1ce93f3821d986fa165552023440lgao    break;
94930fdf1140b8d1ce93f3821d986fa165552023440lgao  case 1:
95030fdf1140b8d1ce93f3821d986fa165552023440lgao    Status = EfiGetInfo(Source, SrcSize, DstSize, &ScratchSize);
95130fdf1140b8d1ce93f3821d986fa165552023440lgao    if (Status == EFI_SUCCESS) {
95230fdf1140b8d1ce93f3821d986fa165552023440lgao      Scratch = (VOID *)malloc(ScratchSize);
953aee346514d224a90622fe4cc553ba8ae79fe2828Hao Wu      if (Scratch == NULL) {
954aee346514d224a90622fe4cc553ba8ae79fe2828Hao Wu        return EFI_OUT_OF_RESOURCES;
955aee346514d224a90622fe4cc553ba8ae79fe2828Hao Wu      }
956aee346514d224a90622fe4cc553ba8ae79fe2828Hao Wu
95730fdf1140b8d1ce93f3821d986fa165552023440lgao      *Destination = (VOID *)malloc(*DstSize);
958aee346514d224a90622fe4cc553ba8ae79fe2828Hao Wu      if (*Destination == NULL) {
959aee346514d224a90622fe4cc553ba8ae79fe2828Hao Wu        free (Scratch);
960aee346514d224a90622fe4cc553ba8ae79fe2828Hao Wu        return EFI_OUT_OF_RESOURCES;
96130fdf1140b8d1ce93f3821d986fa165552023440lgao      }
962aee346514d224a90622fe4cc553ba8ae79fe2828Hao Wu
963aee346514d224a90622fe4cc553ba8ae79fe2828Hao Wu      Status = EfiDecompress(Source, SrcSize, *Destination, *DstSize, Scratch, ScratchSize);
96430fdf1140b8d1ce93f3821d986fa165552023440lgao    }
96530fdf1140b8d1ce93f3821d986fa165552023440lgao    break;
96630fdf1140b8d1ce93f3821d986fa165552023440lgao  case 2:
96730fdf1140b8d1ce93f3821d986fa165552023440lgao    Status = TianoGetInfo(Source, SrcSize, DstSize, &ScratchSize);
96830fdf1140b8d1ce93f3821d986fa165552023440lgao    if (Status == EFI_SUCCESS) {
96930fdf1140b8d1ce93f3821d986fa165552023440lgao      Scratch = (VOID *)malloc(ScratchSize);
970aee346514d224a90622fe4cc553ba8ae79fe2828Hao Wu      if (Scratch == NULL) {
971aee346514d224a90622fe4cc553ba8ae79fe2828Hao Wu        return EFI_OUT_OF_RESOURCES;
972aee346514d224a90622fe4cc553ba8ae79fe2828Hao Wu      }
973aee346514d224a90622fe4cc553ba8ae79fe2828Hao Wu
97430fdf1140b8d1ce93f3821d986fa165552023440lgao      *Destination = (VOID *)malloc(*DstSize);
975aee346514d224a90622fe4cc553ba8ae79fe2828Hao Wu      if (*Destination == NULL) {
976aee346514d224a90622fe4cc553ba8ae79fe2828Hao Wu        free (Scratch);
977aee346514d224a90622fe4cc553ba8ae79fe2828Hao Wu        return EFI_OUT_OF_RESOURCES;
97830fdf1140b8d1ce93f3821d986fa165552023440lgao      }
979aee346514d224a90622fe4cc553ba8ae79fe2828Hao Wu
980aee346514d224a90622fe4cc553ba8ae79fe2828Hao Wu      Status = TianoDecompress(Source, SrcSize, *Destination, *DstSize, Scratch, ScratchSize);
98130fdf1140b8d1ce93f3821d986fa165552023440lgao    }
98230fdf1140b8d1ce93f3821d986fa165552023440lgao    break;
98330fdf1140b8d1ce93f3821d986fa165552023440lgao  default:
98430fdf1140b8d1ce93f3821d986fa165552023440lgao    Status = EFI_INVALID_PARAMETER;
98530fdf1140b8d1ce93f3821d986fa165552023440lgao  }
98630fdf1140b8d1ce93f3821d986fa165552023440lgao
987aee346514d224a90622fe4cc553ba8ae79fe2828Hao Wu  if (Scratch != NULL) {
988aee346514d224a90622fe4cc553ba8ae79fe2828Hao Wu    free (Scratch);
989aee346514d224a90622fe4cc553ba8ae79fe2828Hao Wu  }
990aee346514d224a90622fe4cc553ba8ae79fe2828Hao Wu
99130fdf1140b8d1ce93f3821d986fa165552023440lgao  return Status;
99230fdf1140b8d1ce93f3821d986fa165552023440lgao}
99330fdf1140b8d1ce93f3821d986fa165552023440lgao
99430fdf1140b8d1ce93f3821d986fa165552023440lgao
995