1b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao/** @file
2b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  UEFI and Tiano Custom Decompress Library
330f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng  It will do Tiano or UEFI decompress with different verison parameter.
43db510989eb500296c3f4839c427325a02aea2e3klu
5207f04793e69843ec34078b2f082a0e4660a433aShumin QiuCopyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
6180a5a35cb49699bd249dee19e41cee34c856a58hhtianThis program and the accompanying materials
754bd896eb4a66315665e9522371b6b10c284c036qhuangare licensed and made available under the terms and conditions of the BSD License
854bd896eb4a66315665e9522371b6b10c284c036qhuangwhich accompanies this distribution.  The full text of the license may be found at
954bd896eb4a66315665e9522371b6b10c284c036qhuanghttp://opensource.org/licenses/bsd-license.php
1054bd896eb4a66315665e9522371b6b10c284c036qhuang
1154bd896eb4a66315665e9522371b6b10c284c036qhuangTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
1254bd896eb4a66315665e9522371b6b10c284c036qhuangWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
1354bd896eb4a66315665e9522371b6b10c284c036qhuang
143db510989eb500296c3f4839c427325a02aea2e3klu**/
1554bd896eb4a66315665e9522371b6b10c284c036qhuang
1654bd896eb4a66315665e9522371b6b10c284c036qhuang#include "BaseUefiTianoCustomDecompressLibInternals.h"
1754bd896eb4a66315665e9522371b6b10c284c036qhuang
18ed7752ec44001d317f79c8631dccd9650c396617klu/**
19ed7752ec44001d317f79c8631dccd9650c396617klu  Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source.
20ed7752ec44001d317f79c8631dccd9650c396617klu
21ed7752ec44001d317f79c8631dccd9650c396617klu  @param Sd         The global scratch data
22ed7752ec44001d317f79c8631dccd9650c396617klu  @param NumOfBits  The number of bits to shift and read.
23ed7752ec44001d317f79c8631dccd9650c396617klu**/
2454bd896eb4a66315665e9522371b6b10c284c036qhuangVOID
2554bd896eb4a66315665e9522371b6b10c284c036qhuangFillBuf (
2654bd896eb4a66315665e9522371b6b10c284c036qhuang  IN  SCRATCH_DATA  *Sd,
2754bd896eb4a66315665e9522371b6b10c284c036qhuang  IN  UINT16        NumOfBits
2854bd896eb4a66315665e9522371b6b10c284c036qhuang  )
2954bd896eb4a66315665e9522371b6b10c284c036qhuang{
30b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  //
31b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  // Left shift NumOfBits of bits in advance
32b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  //
3354bd896eb4a66315665e9522371b6b10c284c036qhuang  Sd->mBitBuf = (UINT32) (Sd->mBitBuf << NumOfBits);
3454bd896eb4a66315665e9522371b6b10c284c036qhuang
35b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  //
36b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  // Copy data needed in bytes into mSbuBitBuf
37b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  //
3854bd896eb4a66315665e9522371b6b10c284c036qhuang  while (NumOfBits > Sd->mBitCount) {
3954bd896eb4a66315665e9522371b6b10c284c036qhuang
4054bd896eb4a66315665e9522371b6b10c284c036qhuang    Sd->mBitBuf |= (UINT32) (Sd->mSubBitBuf << (NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount)));
4154bd896eb4a66315665e9522371b6b10c284c036qhuang
4254bd896eb4a66315665e9522371b6b10c284c036qhuang    if (Sd->mCompSize > 0) {
4354bd896eb4a66315665e9522371b6b10c284c036qhuang      //
4454bd896eb4a66315665e9522371b6b10c284c036qhuang      // Get 1 byte into SubBitBuf
4554bd896eb4a66315665e9522371b6b10c284c036qhuang      //
4654bd896eb4a66315665e9522371b6b10c284c036qhuang      Sd->mCompSize--;
4754bd896eb4a66315665e9522371b6b10c284c036qhuang      Sd->mSubBitBuf  = 0;
4854bd896eb4a66315665e9522371b6b10c284c036qhuang      Sd->mSubBitBuf  = Sd->mSrcBase[Sd->mInBuf++];
4954bd896eb4a66315665e9522371b6b10c284c036qhuang      Sd->mBitCount   = 8;
5054bd896eb4a66315665e9522371b6b10c284c036qhuang
5154bd896eb4a66315665e9522371b6b10c284c036qhuang    } else {
5254bd896eb4a66315665e9522371b6b10c284c036qhuang      //
5354bd896eb4a66315665e9522371b6b10c284c036qhuang      // No more bits from the source, just pad zero bit.
5454bd896eb4a66315665e9522371b6b10c284c036qhuang      //
5554bd896eb4a66315665e9522371b6b10c284c036qhuang      Sd->mSubBitBuf  = 0;
5654bd896eb4a66315665e9522371b6b10c284c036qhuang      Sd->mBitCount   = 8;
5754bd896eb4a66315665e9522371b6b10c284c036qhuang
5854bd896eb4a66315665e9522371b6b10c284c036qhuang    }
5954bd896eb4a66315665e9522371b6b10c284c036qhuang  }
6054bd896eb4a66315665e9522371b6b10c284c036qhuang
61b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  //
62207f04793e69843ec34078b2f082a0e4660a433aShumin Qiu  // Calculate additional bit count read to update mBitCount
63b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  //
6454bd896eb4a66315665e9522371b6b10c284c036qhuang  Sd->mBitCount = (UINT16) (Sd->mBitCount - NumOfBits);
65b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao
66b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  //
67b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  // Copy NumOfBits of bits from mSubBitBuf into mBitBuf
68b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  //
6954bd896eb4a66315665e9522371b6b10c284c036qhuang  Sd->mBitBuf |= Sd->mSubBitBuf >> Sd->mBitCount;
7054bd896eb4a66315665e9522371b6b10c284c036qhuang}
7154bd896eb4a66315665e9522371b6b10c284c036qhuang
72ed7752ec44001d317f79c8631dccd9650c396617klu/**
73ed7752ec44001d317f79c8631dccd9650c396617klu  Get NumOfBits of bits out from mBitBuf
7454bd896eb4a66315665e9522371b6b10c284c036qhuang
7554bd896eb4a66315665e9522371b6b10c284c036qhuang  Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent
7654bd896eb4a66315665e9522371b6b10c284c036qhuang  NumOfBits of bits from source. Returns NumOfBits of bits that are
7754bd896eb4a66315665e9522371b6b10c284c036qhuang  popped out.
7854bd896eb4a66315665e9522371b6b10c284c036qhuang
79ed7752ec44001d317f79c8631dccd9650c396617klu  @param  Sd        The global scratch data.
80ed7752ec44001d317f79c8631dccd9650c396617klu  @param  NumOfBits The number of bits to pop and read.
8154bd896eb4a66315665e9522371b6b10c284c036qhuang
82ed7752ec44001d317f79c8631dccd9650c396617klu  @return The bits that are popped out.
8354bd896eb4a66315665e9522371b6b10c284c036qhuang
84ed7752ec44001d317f79c8631dccd9650c396617klu**/
85ed7752ec44001d317f79c8631dccd9650c396617kluUINT32
86ed7752ec44001d317f79c8631dccd9650c396617kluGetBits (
87ed7752ec44001d317f79c8631dccd9650c396617klu  IN  SCRATCH_DATA  *Sd,
88ed7752ec44001d317f79c8631dccd9650c396617klu  IN  UINT16        NumOfBits
89ed7752ec44001d317f79c8631dccd9650c396617klu  )
9054bd896eb4a66315665e9522371b6b10c284c036qhuang{
9154bd896eb4a66315665e9522371b6b10c284c036qhuang  UINT32  OutBits;
9254bd896eb4a66315665e9522371b6b10c284c036qhuang
93b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  //
94b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  // Pop NumOfBits of Bits from Left
95b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  //
9654bd896eb4a66315665e9522371b6b10c284c036qhuang  OutBits = (UINT32) (Sd->mBitBuf >> (BITBUFSIZ - NumOfBits));
9754bd896eb4a66315665e9522371b6b10c284c036qhuang
98b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  //
99b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  // Fill up mBitBuf from source
100b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  //
10154bd896eb4a66315665e9522371b6b10c284c036qhuang  FillBuf (Sd, NumOfBits);
10254bd896eb4a66315665e9522371b6b10c284c036qhuang
10354bd896eb4a66315665e9522371b6b10c284c036qhuang  return OutBits;
10454bd896eb4a66315665e9522371b6b10c284c036qhuang}
10554bd896eb4a66315665e9522371b6b10c284c036qhuang
106ed7752ec44001d317f79c8631dccd9650c396617klu/**
107ed7752ec44001d317f79c8631dccd9650c396617klu  Creates Huffman Code mapping table according to code length array.
108ed7752ec44001d317f79c8631dccd9650c396617klu
109ed7752ec44001d317f79c8631dccd9650c396617klu  Creates Huffman Code mapping table for Extra Set, Char&Len Set
110ed7752ec44001d317f79c8631dccd9650c396617klu  and Position Set according to code length array.
11114531b13909c611730888ce9228f715d33f0ea73lgao  If TableBits > 16, then ASSERT ().
112ed7752ec44001d317f79c8631dccd9650c396617klu
113ed7752ec44001d317f79c8631dccd9650c396617klu  @param  Sd        The global scratch data
114ed7752ec44001d317f79c8631dccd9650c396617klu  @param  NumOfChar Number of symbols in the symbol set
115ed7752ec44001d317f79c8631dccd9650c396617klu  @param  BitLen    Code length array
116ed7752ec44001d317f79c8631dccd9650c396617klu  @param  TableBits The width of the mapping table
117b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  @param  Table     The table to be created.
118ed7752ec44001d317f79c8631dccd9650c396617klu
119ed7752ec44001d317f79c8631dccd9650c396617klu  @retval  0 OK.
120ed7752ec44001d317f79c8631dccd9650c396617klu  @retval  BAD_TABLE The table is corrupted.
121ed7752ec44001d317f79c8631dccd9650c396617klu
122ed7752ec44001d317f79c8631dccd9650c396617klu**/
12354bd896eb4a66315665e9522371b6b10c284c036qhuangUINT16
12454bd896eb4a66315665e9522371b6b10c284c036qhuangMakeTable (
12554bd896eb4a66315665e9522371b6b10c284c036qhuang  IN  SCRATCH_DATA  *Sd,
12654bd896eb4a66315665e9522371b6b10c284c036qhuang  IN  UINT16        NumOfChar,
12754bd896eb4a66315665e9522371b6b10c284c036qhuang  IN  UINT8         *BitLen,
12854bd896eb4a66315665e9522371b6b10c284c036qhuang  IN  UINT16        TableBits,
12954bd896eb4a66315665e9522371b6b10c284c036qhuang  OUT UINT16        *Table
13054bd896eb4a66315665e9522371b6b10c284c036qhuang  )
13154bd896eb4a66315665e9522371b6b10c284c036qhuang{
13254bd896eb4a66315665e9522371b6b10c284c036qhuang  UINT16  Count[17];
13354bd896eb4a66315665e9522371b6b10c284c036qhuang  UINT16  Weight[17];
13454bd896eb4a66315665e9522371b6b10c284c036qhuang  UINT16  Start[18];
13554bd896eb4a66315665e9522371b6b10c284c036qhuang  UINT16  *Pointer;
13654bd896eb4a66315665e9522371b6b10c284c036qhuang  UINT16  Index3;
13780267d51f8572313d4f23d9622a41b65ada9f2aclgao  UINT16  Index;
13854bd896eb4a66315665e9522371b6b10c284c036qhuang  UINT16  Len;
13954bd896eb4a66315665e9522371b6b10c284c036qhuang  UINT16  Char;
14054bd896eb4a66315665e9522371b6b10c284c036qhuang  UINT16  JuBits;
14154bd896eb4a66315665e9522371b6b10c284c036qhuang  UINT16  Avail;
14254bd896eb4a66315665e9522371b6b10c284c036qhuang  UINT16  NextCode;
14354bd896eb4a66315665e9522371b6b10c284c036qhuang  UINT16  Mask;
14454bd896eb4a66315665e9522371b6b10c284c036qhuang  UINT16  WordOfStart;
14554bd896eb4a66315665e9522371b6b10c284c036qhuang  UINT16  WordOfCount;
14654bd896eb4a66315665e9522371b6b10c284c036qhuang
14714531b13909c611730888ce9228f715d33f0ea73lgao  //
14814531b13909c611730888ce9228f715d33f0ea73lgao  // The maximum mapping table width supported by this internal
14914531b13909c611730888ce9228f715d33f0ea73lgao  // working function is 16.
15014531b13909c611730888ce9228f715d33f0ea73lgao  //
15114531b13909c611730888ce9228f715d33f0ea73lgao  ASSERT (TableBits <= 16);
15214531b13909c611730888ce9228f715d33f0ea73lgao
153aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang  for (Index = 0; Index <= 16; Index++) {
15454bd896eb4a66315665e9522371b6b10c284c036qhuang    Count[Index] = 0;
15554bd896eb4a66315665e9522371b6b10c284c036qhuang  }
15654bd896eb4a66315665e9522371b6b10c284c036qhuang
15754bd896eb4a66315665e9522371b6b10c284c036qhuang  for (Index = 0; Index < NumOfChar; Index++) {
15854bd896eb4a66315665e9522371b6b10c284c036qhuang    Count[BitLen[Index]]++;
15954bd896eb4a66315665e9522371b6b10c284c036qhuang  }
160aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang
161aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang  Start[0] = 0;
16254bd896eb4a66315665e9522371b6b10c284c036qhuang  Start[1] = 0;
16354bd896eb4a66315665e9522371b6b10c284c036qhuang
16454bd896eb4a66315665e9522371b6b10c284c036qhuang  for (Index = 1; Index <= 16; Index++) {
16554bd896eb4a66315665e9522371b6b10c284c036qhuang    WordOfStart = Start[Index];
16654bd896eb4a66315665e9522371b6b10c284c036qhuang    WordOfCount = Count[Index];
16754bd896eb4a66315665e9522371b6b10c284c036qhuang    Start[Index + 1] = (UINT16) (WordOfStart + (WordOfCount << (16 - Index)));
16854bd896eb4a66315665e9522371b6b10c284c036qhuang  }
16954bd896eb4a66315665e9522371b6b10c284c036qhuang
17054bd896eb4a66315665e9522371b6b10c284c036qhuang  if (Start[17] != 0) {
17154bd896eb4a66315665e9522371b6b10c284c036qhuang    /*(1U << 16)*/
17254bd896eb4a66315665e9522371b6b10c284c036qhuang    return (UINT16) BAD_TABLE;
17354bd896eb4a66315665e9522371b6b10c284c036qhuang  }
17454bd896eb4a66315665e9522371b6b10c284c036qhuang
17554bd896eb4a66315665e9522371b6b10c284c036qhuang  JuBits = (UINT16) (16 - TableBits);
176aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang
177aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang  Weight[0] = 0;
17854bd896eb4a66315665e9522371b6b10c284c036qhuang  for (Index = 1; Index <= TableBits; Index++) {
17954bd896eb4a66315665e9522371b6b10c284c036qhuang    Start[Index] >>= JuBits;
18054bd896eb4a66315665e9522371b6b10c284c036qhuang    Weight[Index] = (UINT16) (1U << (TableBits - Index));
18154bd896eb4a66315665e9522371b6b10c284c036qhuang  }
18254bd896eb4a66315665e9522371b6b10c284c036qhuang
18354bd896eb4a66315665e9522371b6b10c284c036qhuang  while (Index <= 16) {
18454bd896eb4a66315665e9522371b6b10c284c036qhuang    Weight[Index] = (UINT16) (1U << (16 - Index));
185aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang    Index++;
18654bd896eb4a66315665e9522371b6b10c284c036qhuang  }
18754bd896eb4a66315665e9522371b6b10c284c036qhuang
18854bd896eb4a66315665e9522371b6b10c284c036qhuang  Index = (UINT16) (Start[TableBits + 1] >> JuBits);
18954bd896eb4a66315665e9522371b6b10c284c036qhuang
19054bd896eb4a66315665e9522371b6b10c284c036qhuang  if (Index != 0) {
19154bd896eb4a66315665e9522371b6b10c284c036qhuang    Index3 = (UINT16) (1U << TableBits);
192aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang    if (Index < Index3) {
193aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang      SetMem16 (Table + Index, (Index3 - Index) * sizeof (*Table), 0);
19454bd896eb4a66315665e9522371b6b10c284c036qhuang    }
19554bd896eb4a66315665e9522371b6b10c284c036qhuang  }
19654bd896eb4a66315665e9522371b6b10c284c036qhuang
19754bd896eb4a66315665e9522371b6b10c284c036qhuang  Avail = NumOfChar;
19854bd896eb4a66315665e9522371b6b10c284c036qhuang  Mask  = (UINT16) (1U << (15 - TableBits));
19954bd896eb4a66315665e9522371b6b10c284c036qhuang
20054bd896eb4a66315665e9522371b6b10c284c036qhuang  for (Char = 0; Char < NumOfChar; Char++) {
20154bd896eb4a66315665e9522371b6b10c284c036qhuang
20254bd896eb4a66315665e9522371b6b10c284c036qhuang    Len = BitLen[Char];
203aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang    if (Len == 0 || Len >= 17) {
20454bd896eb4a66315665e9522371b6b10c284c036qhuang      continue;
20554bd896eb4a66315665e9522371b6b10c284c036qhuang    }
20654bd896eb4a66315665e9522371b6b10c284c036qhuang
20754bd896eb4a66315665e9522371b6b10c284c036qhuang    NextCode = (UINT16) (Start[Len] + Weight[Len]);
20854bd896eb4a66315665e9522371b6b10c284c036qhuang
20954bd896eb4a66315665e9522371b6b10c284c036qhuang    if (Len <= TableBits) {
21054bd896eb4a66315665e9522371b6b10c284c036qhuang
21154bd896eb4a66315665e9522371b6b10c284c036qhuang      for (Index = Start[Len]; Index < NextCode; Index++) {
21254bd896eb4a66315665e9522371b6b10c284c036qhuang        Table[Index] = Char;
21354bd896eb4a66315665e9522371b6b10c284c036qhuang      }
21454bd896eb4a66315665e9522371b6b10c284c036qhuang
21554bd896eb4a66315665e9522371b6b10c284c036qhuang    } else {
21654bd896eb4a66315665e9522371b6b10c284c036qhuang
21754bd896eb4a66315665e9522371b6b10c284c036qhuang      Index3  = Start[Len];
21854bd896eb4a66315665e9522371b6b10c284c036qhuang      Pointer = &Table[Index3 >> JuBits];
21954bd896eb4a66315665e9522371b6b10c284c036qhuang      Index   = (UINT16) (Len - TableBits);
22054bd896eb4a66315665e9522371b6b10c284c036qhuang
22154bd896eb4a66315665e9522371b6b10c284c036qhuang      while (Index != 0) {
222aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang        if (*Pointer == 0 && Avail < (2 * NC - 1)) {
223aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang          Sd->mRight[Avail] = Sd->mLeft[Avail] = 0;
22454bd896eb4a66315665e9522371b6b10c284c036qhuang          *Pointer = Avail++;
22554bd896eb4a66315665e9522371b6b10c284c036qhuang        }
226aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang
227aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang        if (*Pointer < (2 * NC - 1)) {
228aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang          if ((Index3 & Mask) != 0) {
229aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang            Pointer = &Sd->mRight[*Pointer];
230aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang          } else {
231aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang            Pointer = &Sd->mLeft[*Pointer];
232aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang          }
23354bd896eb4a66315665e9522371b6b10c284c036qhuang        }
23454bd896eb4a66315665e9522371b6b10c284c036qhuang
23554bd896eb4a66315665e9522371b6b10c284c036qhuang        Index3 <<= 1;
23654bd896eb4a66315665e9522371b6b10c284c036qhuang        Index--;
23754bd896eb4a66315665e9522371b6b10c284c036qhuang      }
23854bd896eb4a66315665e9522371b6b10c284c036qhuang
23954bd896eb4a66315665e9522371b6b10c284c036qhuang      *Pointer = Char;
24054bd896eb4a66315665e9522371b6b10c284c036qhuang
24154bd896eb4a66315665e9522371b6b10c284c036qhuang    }
24254bd896eb4a66315665e9522371b6b10c284c036qhuang
24354bd896eb4a66315665e9522371b6b10c284c036qhuang    Start[Len] = NextCode;
24454bd896eb4a66315665e9522371b6b10c284c036qhuang  }
24554bd896eb4a66315665e9522371b6b10c284c036qhuang  //
24654bd896eb4a66315665e9522371b6b10c284c036qhuang  // Succeeds
24754bd896eb4a66315665e9522371b6b10c284c036qhuang  //
24854bd896eb4a66315665e9522371b6b10c284c036qhuang  return 0;
24954bd896eb4a66315665e9522371b6b10c284c036qhuang}
25054bd896eb4a66315665e9522371b6b10c284c036qhuang
251ed7752ec44001d317f79c8631dccd9650c396617klu/**
252ed7752ec44001d317f79c8631dccd9650c396617klu  Decodes a position value.
253ed7752ec44001d317f79c8631dccd9650c396617klu
254b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  Get a position value according to Position Huffman Table.
255b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao
256ed7752ec44001d317f79c8631dccd9650c396617klu  @param Sd      the global scratch data
257ed7752ec44001d317f79c8631dccd9650c396617klu
258ed7752ec44001d317f79c8631dccd9650c396617klu  @return The position value decoded.
259ed7752ec44001d317f79c8631dccd9650c396617klu**/
26054bd896eb4a66315665e9522371b6b10c284c036qhuangUINT32
26154bd896eb4a66315665e9522371b6b10c284c036qhuangDecodeP (
26254bd896eb4a66315665e9522371b6b10c284c036qhuang  IN  SCRATCH_DATA  *Sd
26354bd896eb4a66315665e9522371b6b10c284c036qhuang  )
26454bd896eb4a66315665e9522371b6b10c284c036qhuang{
26554bd896eb4a66315665e9522371b6b10c284c036qhuang  UINT16  Val;
26654bd896eb4a66315665e9522371b6b10c284c036qhuang  UINT32  Mask;
26754bd896eb4a66315665e9522371b6b10c284c036qhuang  UINT32  Pos;
26854bd896eb4a66315665e9522371b6b10c284c036qhuang
26954bd896eb4a66315665e9522371b6b10c284c036qhuang  Val = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];
27054bd896eb4a66315665e9522371b6b10c284c036qhuang
27154bd896eb4a66315665e9522371b6b10c284c036qhuang  if (Val >= MAXNP) {
27254bd896eb4a66315665e9522371b6b10c284c036qhuang    Mask = 1U << (BITBUFSIZ - 1 - 8);
27354bd896eb4a66315665e9522371b6b10c284c036qhuang
27454bd896eb4a66315665e9522371b6b10c284c036qhuang    do {
27554bd896eb4a66315665e9522371b6b10c284c036qhuang
276b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao      if ((Sd->mBitBuf & Mask) != 0) {
27754bd896eb4a66315665e9522371b6b10c284c036qhuang        Val = Sd->mRight[Val];
27854bd896eb4a66315665e9522371b6b10c284c036qhuang      } else {
27954bd896eb4a66315665e9522371b6b10c284c036qhuang        Val = Sd->mLeft[Val];
28054bd896eb4a66315665e9522371b6b10c284c036qhuang      }
28154bd896eb4a66315665e9522371b6b10c284c036qhuang
28254bd896eb4a66315665e9522371b6b10c284c036qhuang      Mask >>= 1;
28354bd896eb4a66315665e9522371b6b10c284c036qhuang    } while (Val >= MAXNP);
28454bd896eb4a66315665e9522371b6b10c284c036qhuang  }
28554bd896eb4a66315665e9522371b6b10c284c036qhuang  //
28654bd896eb4a66315665e9522371b6b10c284c036qhuang  // Advance what we have read
28754bd896eb4a66315665e9522371b6b10c284c036qhuang  //
28854bd896eb4a66315665e9522371b6b10c284c036qhuang  FillBuf (Sd, Sd->mPTLen[Val]);
28954bd896eb4a66315665e9522371b6b10c284c036qhuang
29054bd896eb4a66315665e9522371b6b10c284c036qhuang  Pos = Val;
29154bd896eb4a66315665e9522371b6b10c284c036qhuang  if (Val > 1) {
29254bd896eb4a66315665e9522371b6b10c284c036qhuang    Pos = (UINT32) ((1U << (Val - 1)) + GetBits (Sd, (UINT16) (Val - 1)));
29354bd896eb4a66315665e9522371b6b10c284c036qhuang  }
29454bd896eb4a66315665e9522371b6b10c284c036qhuang
29554bd896eb4a66315665e9522371b6b10c284c036qhuang  return Pos;
29654bd896eb4a66315665e9522371b6b10c284c036qhuang}
29754bd896eb4a66315665e9522371b6b10c284c036qhuang
298ed7752ec44001d317f79c8631dccd9650c396617klu/**
299ed7752ec44001d317f79c8631dccd9650c396617klu  Reads code lengths for the Extra Set or the Position Set.
300ed7752ec44001d317f79c8631dccd9650c396617klu
30170d3fe9dad1d7b2944a2653b3895a11863fb674eGary Lin  Read in the Extra Set or Position Set Length Array, then
302ed7752ec44001d317f79c8631dccd9650c396617klu  generate the Huffman code mapping for them.
303ed7752ec44001d317f79c8631dccd9650c396617klu
304ed7752ec44001d317f79c8631dccd9650c396617klu  @param  Sd      The global scratch data.
305ed7752ec44001d317f79c8631dccd9650c396617klu  @param  nn      Number of symbols.
306ed7752ec44001d317f79c8631dccd9650c396617klu  @param  nbit    Number of bits needed to represent nn.
307ed7752ec44001d317f79c8631dccd9650c396617klu  @param  Special The special symbol that needs to be taken care of.
308ed7752ec44001d317f79c8631dccd9650c396617klu
309ed7752ec44001d317f79c8631dccd9650c396617klu  @retval  0 OK.
310ed7752ec44001d317f79c8631dccd9650c396617klu  @retval  BAD_TABLE Table is corrupted.
311ed7752ec44001d317f79c8631dccd9650c396617klu
312ed7752ec44001d317f79c8631dccd9650c396617klu**/
31354bd896eb4a66315665e9522371b6b10c284c036qhuangUINT16
31454bd896eb4a66315665e9522371b6b10c284c036qhuangReadPTLen (
31554bd896eb4a66315665e9522371b6b10c284c036qhuang  IN  SCRATCH_DATA  *Sd,
31654bd896eb4a66315665e9522371b6b10c284c036qhuang  IN  UINT16        nn,
31754bd896eb4a66315665e9522371b6b10c284c036qhuang  IN  UINT16        nbit,
31854bd896eb4a66315665e9522371b6b10c284c036qhuang  IN  UINT16        Special
31954bd896eb4a66315665e9522371b6b10c284c036qhuang  )
32054bd896eb4a66315665e9522371b6b10c284c036qhuang{
32154bd896eb4a66315665e9522371b6b10c284c036qhuang  UINT16  Number;
32254bd896eb4a66315665e9522371b6b10c284c036qhuang  UINT16  CharC;
32380267d51f8572313d4f23d9622a41b65ada9f2aclgao  UINT16  Index;
32454bd896eb4a66315665e9522371b6b10c284c036qhuang  UINT32  Mask;
32554bd896eb4a66315665e9522371b6b10c284c036qhuang
3265a18908695b8fb1a0ce325bd29b43d51aa65e07fEric Dong  ASSERT (nn <= NPT);
327aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang  //
328aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang  // Read Extra Set Code Length Array size
329aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang  //
33054bd896eb4a66315665e9522371b6b10c284c036qhuang  Number = (UINT16) GetBits (Sd, nbit);
33154bd896eb4a66315665e9522371b6b10c284c036qhuang
33254bd896eb4a66315665e9522371b6b10c284c036qhuang  if (Number == 0) {
333aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang    //
334aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang    // This represents only Huffman code used
335aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang    //
33654bd896eb4a66315665e9522371b6b10c284c036qhuang    CharC = (UINT16) GetBits (Sd, nbit);
33754bd896eb4a66315665e9522371b6b10c284c036qhuang
33854bd896eb4a66315665e9522371b6b10c284c036qhuang    for (Index = 0; Index < 256; Index++) {
33954bd896eb4a66315665e9522371b6b10c284c036qhuang      Sd->mPTTable[Index] = CharC;
34054bd896eb4a66315665e9522371b6b10c284c036qhuang    }
34154bd896eb4a66315665e9522371b6b10c284c036qhuang
342aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang    SetMem (Sd->mPTLen, nn, 0);
34354bd896eb4a66315665e9522371b6b10c284c036qhuang
34454bd896eb4a66315665e9522371b6b10c284c036qhuang    return 0;
34554bd896eb4a66315665e9522371b6b10c284c036qhuang  }
34654bd896eb4a66315665e9522371b6b10c284c036qhuang
34754bd896eb4a66315665e9522371b6b10c284c036qhuang  Index = 0;
34854bd896eb4a66315665e9522371b6b10c284c036qhuang
349aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang  while (Index < Number && Index < NPT) {
35054bd896eb4a66315665e9522371b6b10c284c036qhuang
35154bd896eb4a66315665e9522371b6b10c284c036qhuang    CharC = (UINT16) (Sd->mBitBuf >> (BITBUFSIZ - 3));
35254bd896eb4a66315665e9522371b6b10c284c036qhuang
353aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang    //
354aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang    // If a code length is less than 7, then it is encoded as a 3-bit
355aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang    // value. Or it is encoded as a series of "1"s followed by a
356aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang    // terminating "0". The number of "1"s = Code length - 4.
357aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang    //
35854bd896eb4a66315665e9522371b6b10c284c036qhuang    if (CharC == 7) {
35954bd896eb4a66315665e9522371b6b10c284c036qhuang      Mask = 1U << (BITBUFSIZ - 1 - 3);
36054bd896eb4a66315665e9522371b6b10c284c036qhuang      while (Mask & Sd->mBitBuf) {
36154bd896eb4a66315665e9522371b6b10c284c036qhuang        Mask >>= 1;
36254bd896eb4a66315665e9522371b6b10c284c036qhuang        CharC += 1;
36354bd896eb4a66315665e9522371b6b10c284c036qhuang      }
36454bd896eb4a66315665e9522371b6b10c284c036qhuang    }
365aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang
36654bd896eb4a66315665e9522371b6b10c284c036qhuang    FillBuf (Sd, (UINT16) ((CharC < 7) ? 3 : CharC - 3));
36754bd896eb4a66315665e9522371b6b10c284c036qhuang
36854bd896eb4a66315665e9522371b6b10c284c036qhuang    Sd->mPTLen[Index++] = (UINT8) CharC;
369aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang
370aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang    //
371aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang    // For Code&Len Set,
372aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang    // After the third length of the code length concatenation,
373aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang    // a 2-bit value is used to indicated the number of consecutive
374aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang    // zero lengths after the third length.
375aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang    //
37654bd896eb4a66315665e9522371b6b10c284c036qhuang    if (Index == Special) {
37754bd896eb4a66315665e9522371b6b10c284c036qhuang      CharC = (UINT16) GetBits (Sd, 2);
378aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang      while ((INT16) (--CharC) >= 0 && Index < NPT) {
37954bd896eb4a66315665e9522371b6b10c284c036qhuang        Sd->mPTLen[Index++] = 0;
38054bd896eb4a66315665e9522371b6b10c284c036qhuang      }
38154bd896eb4a66315665e9522371b6b10c284c036qhuang    }
38254bd896eb4a66315665e9522371b6b10c284c036qhuang  }
38354bd896eb4a66315665e9522371b6b10c284c036qhuang
384aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang  while (Index < nn && Index < NPT) {
38554bd896eb4a66315665e9522371b6b10c284c036qhuang    Sd->mPTLen[Index++] = 0;
38654bd896eb4a66315665e9522371b6b10c284c036qhuang  }
387aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang
38854bd896eb4a66315665e9522371b6b10c284c036qhuang  return MakeTable (Sd, nn, Sd->mPTLen, 8, Sd->mPTTable);
38954bd896eb4a66315665e9522371b6b10c284c036qhuang}
39054bd896eb4a66315665e9522371b6b10c284c036qhuang
391ed7752ec44001d317f79c8631dccd9650c396617klu/**
392ed7752ec44001d317f79c8631dccd9650c396617klu  Reads code lengths for Char&Len Set.
393ed7752ec44001d317f79c8631dccd9650c396617klu
394ed7752ec44001d317f79c8631dccd9650c396617klu  Read in and decode the Char&Len Set Code Length Array, then
395ed7752ec44001d317f79c8631dccd9650c396617klu  generate the Huffman Code mapping table for the Char&Len Set.
396ed7752ec44001d317f79c8631dccd9650c396617klu
397ed7752ec44001d317f79c8631dccd9650c396617klu  @param  Sd the global scratch data
398ed7752ec44001d317f79c8631dccd9650c396617klu
399ed7752ec44001d317f79c8631dccd9650c396617klu**/
40054bd896eb4a66315665e9522371b6b10c284c036qhuangVOID
40154bd896eb4a66315665e9522371b6b10c284c036qhuangReadCLen (
40254bd896eb4a66315665e9522371b6b10c284c036qhuang  SCRATCH_DATA  *Sd
40354bd896eb4a66315665e9522371b6b10c284c036qhuang  )
40454bd896eb4a66315665e9522371b6b10c284c036qhuang{
40554bd896eb4a66315665e9522371b6b10c284c036qhuang  UINT16  Number;
40654bd896eb4a66315665e9522371b6b10c284c036qhuang  UINT16  CharC;
40780267d51f8572313d4f23d9622a41b65ada9f2aclgao  UINT16  Index;
40854bd896eb4a66315665e9522371b6b10c284c036qhuang  UINT32  Mask;
40954bd896eb4a66315665e9522371b6b10c284c036qhuang
41054bd896eb4a66315665e9522371b6b10c284c036qhuang  Number = (UINT16) GetBits (Sd, CBIT);
41154bd896eb4a66315665e9522371b6b10c284c036qhuang
41254bd896eb4a66315665e9522371b6b10c284c036qhuang  if (Number == 0) {
413aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang    //
414aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang    // This represents only Huffman code used
415aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang    //
41654bd896eb4a66315665e9522371b6b10c284c036qhuang    CharC = (UINT16) GetBits (Sd, CBIT);
41754bd896eb4a66315665e9522371b6b10c284c036qhuang
418aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang    SetMem (Sd->mCLen, NC, 0);
41954bd896eb4a66315665e9522371b6b10c284c036qhuang
42054bd896eb4a66315665e9522371b6b10c284c036qhuang    for (Index = 0; Index < 4096; Index++) {
42154bd896eb4a66315665e9522371b6b10c284c036qhuang      Sd->mCTable[Index] = CharC;
42254bd896eb4a66315665e9522371b6b10c284c036qhuang    }
42354bd896eb4a66315665e9522371b6b10c284c036qhuang
42454bd896eb4a66315665e9522371b6b10c284c036qhuang    return ;
42554bd896eb4a66315665e9522371b6b10c284c036qhuang  }
42654bd896eb4a66315665e9522371b6b10c284c036qhuang
42754bd896eb4a66315665e9522371b6b10c284c036qhuang  Index = 0;
428aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang  while (Index < Number && Index < NC) {
42954bd896eb4a66315665e9522371b6b10c284c036qhuang    CharC = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];
43054bd896eb4a66315665e9522371b6b10c284c036qhuang    if (CharC >= NT) {
43154bd896eb4a66315665e9522371b6b10c284c036qhuang      Mask = 1U << (BITBUFSIZ - 1 - 8);
43254bd896eb4a66315665e9522371b6b10c284c036qhuang
43354bd896eb4a66315665e9522371b6b10c284c036qhuang      do {
43454bd896eb4a66315665e9522371b6b10c284c036qhuang
43554bd896eb4a66315665e9522371b6b10c284c036qhuang        if (Mask & Sd->mBitBuf) {
43654bd896eb4a66315665e9522371b6b10c284c036qhuang          CharC = Sd->mRight[CharC];
43754bd896eb4a66315665e9522371b6b10c284c036qhuang        } else {
43854bd896eb4a66315665e9522371b6b10c284c036qhuang          CharC = Sd->mLeft[CharC];
43954bd896eb4a66315665e9522371b6b10c284c036qhuang        }
44054bd896eb4a66315665e9522371b6b10c284c036qhuang
44154bd896eb4a66315665e9522371b6b10c284c036qhuang        Mask >>= 1;
44254bd896eb4a66315665e9522371b6b10c284c036qhuang
44354bd896eb4a66315665e9522371b6b10c284c036qhuang      } while (CharC >= NT);
44454bd896eb4a66315665e9522371b6b10c284c036qhuang    }
44554bd896eb4a66315665e9522371b6b10c284c036qhuang    //
44654bd896eb4a66315665e9522371b6b10c284c036qhuang    // Advance what we have read
44754bd896eb4a66315665e9522371b6b10c284c036qhuang    //
44854bd896eb4a66315665e9522371b6b10c284c036qhuang    FillBuf (Sd, Sd->mPTLen[CharC]);
44954bd896eb4a66315665e9522371b6b10c284c036qhuang
45054bd896eb4a66315665e9522371b6b10c284c036qhuang    if (CharC <= 2) {
45154bd896eb4a66315665e9522371b6b10c284c036qhuang
45254bd896eb4a66315665e9522371b6b10c284c036qhuang      if (CharC == 0) {
45354bd896eb4a66315665e9522371b6b10c284c036qhuang        CharC = 1;
45454bd896eb4a66315665e9522371b6b10c284c036qhuang      } else if (CharC == 1) {
45554bd896eb4a66315665e9522371b6b10c284c036qhuang        CharC = (UINT16) (GetBits (Sd, 4) + 3);
45654bd896eb4a66315665e9522371b6b10c284c036qhuang      } else if (CharC == 2) {
45754bd896eb4a66315665e9522371b6b10c284c036qhuang        CharC = (UINT16) (GetBits (Sd, CBIT) + 20);
45854bd896eb4a66315665e9522371b6b10c284c036qhuang      }
45954bd896eb4a66315665e9522371b6b10c284c036qhuang
460aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang      while ((INT16) (--CharC) >= 0 && Index < NC) {
46154bd896eb4a66315665e9522371b6b10c284c036qhuang        Sd->mCLen[Index++] = 0;
46254bd896eb4a66315665e9522371b6b10c284c036qhuang      }
46354bd896eb4a66315665e9522371b6b10c284c036qhuang
46454bd896eb4a66315665e9522371b6b10c284c036qhuang    } else {
46554bd896eb4a66315665e9522371b6b10c284c036qhuang
46654bd896eb4a66315665e9522371b6b10c284c036qhuang      Sd->mCLen[Index++] = (UINT8) (CharC - 2);
46754bd896eb4a66315665e9522371b6b10c284c036qhuang
46854bd896eb4a66315665e9522371b6b10c284c036qhuang    }
46954bd896eb4a66315665e9522371b6b10c284c036qhuang  }
47054bd896eb4a66315665e9522371b6b10c284c036qhuang
471aa950314c706c55c0f4a32c41752bf5a19e8deb4hfang  SetMem (Sd->mCLen + Index, NC - Index, 0);
47254bd896eb4a66315665e9522371b6b10c284c036qhuang
47354bd896eb4a66315665e9522371b6b10c284c036qhuang  MakeTable (Sd, NC, Sd->mCLen, 12, Sd->mCTable);
47454bd896eb4a66315665e9522371b6b10c284c036qhuang
47554bd896eb4a66315665e9522371b6b10c284c036qhuang  return ;
47654bd896eb4a66315665e9522371b6b10c284c036qhuang}
47754bd896eb4a66315665e9522371b6b10c284c036qhuang
478ed7752ec44001d317f79c8631dccd9650c396617klu/**
47954bd896eb4a66315665e9522371b6b10c284c036qhuang  Decode a character/length value.
480ed7752ec44001d317f79c8631dccd9650c396617klu
481ed7752ec44001d317f79c8631dccd9650c396617klu  Read one value from mBitBuf, Get one code from mBitBuf. If it is at block boundary, generates
482ed7752ec44001d317f79c8631dccd9650c396617klu  Huffman code mapping table for Extra Set, Code&Len Set and
483ed7752ec44001d317f79c8631dccd9650c396617klu  Position Set.
48454bd896eb4a66315665e9522371b6b10c284c036qhuang
485ed7752ec44001d317f79c8631dccd9650c396617klu  @param  Sd The global scratch data.
48654bd896eb4a66315665e9522371b6b10c284c036qhuang
487ed7752ec44001d317f79c8631dccd9650c396617klu  @return The value decoded.
48854bd896eb4a66315665e9522371b6b10c284c036qhuang
489ed7752ec44001d317f79c8631dccd9650c396617klu**/
490ed7752ec44001d317f79c8631dccd9650c396617kluUINT16
491ed7752ec44001d317f79c8631dccd9650c396617kluDecodeC (
492ed7752ec44001d317f79c8631dccd9650c396617klu  SCRATCH_DATA  *Sd
493ed7752ec44001d317f79c8631dccd9650c396617klu  )
49454bd896eb4a66315665e9522371b6b10c284c036qhuang{
49554bd896eb4a66315665e9522371b6b10c284c036qhuang  UINT16  Index2;
49654bd896eb4a66315665e9522371b6b10c284c036qhuang  UINT32  Mask;
49754bd896eb4a66315665e9522371b6b10c284c036qhuang
49854bd896eb4a66315665e9522371b6b10c284c036qhuang  if (Sd->mBlockSize == 0) {
49954bd896eb4a66315665e9522371b6b10c284c036qhuang    //
50054bd896eb4a66315665e9522371b6b10c284c036qhuang    // Starting a new block
501b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao    // Read BlockSize from block header
502b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao    //
50354bd896eb4a66315665e9522371b6b10c284c036qhuang    Sd->mBlockSize    = (UINT16) GetBits (Sd, 16);
504b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao
505b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao    //
50670d3fe9dad1d7b2944a2653b3895a11863fb674eGary Lin    // Read in the Extra Set Code Length Array,
507b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao    // Generate the Huffman code mapping table for Extra Set.
508b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao    //
50954bd896eb4a66315665e9522371b6b10c284c036qhuang    Sd->mBadTableFlag = ReadPTLen (Sd, NT, TBIT, 3);
51054bd896eb4a66315665e9522371b6b10c284c036qhuang    if (Sd->mBadTableFlag != 0) {
51154bd896eb4a66315665e9522371b6b10c284c036qhuang      return 0;
51254bd896eb4a66315665e9522371b6b10c284c036qhuang    }
51354bd896eb4a66315665e9522371b6b10c284c036qhuang
514b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao    //
51570d3fe9dad1d7b2944a2653b3895a11863fb674eGary Lin    // Read in and decode the Char&Len Set Code Length Array,
516b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao    // Generate the Huffman code mapping table for Char&Len Set.
517b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao    //
51854bd896eb4a66315665e9522371b6b10c284c036qhuang    ReadCLen (Sd);
51954bd896eb4a66315665e9522371b6b10c284c036qhuang
520b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao    //
52170d3fe9dad1d7b2944a2653b3895a11863fb674eGary Lin    // Read in the Position Set Code Length Array,
522b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao    // Generate the Huffman code mapping table for the Position Set.
523b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao    //
52454bd896eb4a66315665e9522371b6b10c284c036qhuang    Sd->mBadTableFlag = ReadPTLen (Sd, MAXNP, Sd->mPBit, (UINT16) (-1));
52554bd896eb4a66315665e9522371b6b10c284c036qhuang    if (Sd->mBadTableFlag != 0) {
52654bd896eb4a66315665e9522371b6b10c284c036qhuang      return 0;
52754bd896eb4a66315665e9522371b6b10c284c036qhuang    }
52854bd896eb4a66315665e9522371b6b10c284c036qhuang  }
52954bd896eb4a66315665e9522371b6b10c284c036qhuang
530b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  //
531b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  // Get one code according to Code&Set Huffman Table
532b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  //
53354bd896eb4a66315665e9522371b6b10c284c036qhuang  Sd->mBlockSize--;
53454bd896eb4a66315665e9522371b6b10c284c036qhuang  Index2 = Sd->mCTable[Sd->mBitBuf >> (BITBUFSIZ - 12)];
53554bd896eb4a66315665e9522371b6b10c284c036qhuang
53654bd896eb4a66315665e9522371b6b10c284c036qhuang  if (Index2 >= NC) {
53754bd896eb4a66315665e9522371b6b10c284c036qhuang    Mask = 1U << (BITBUFSIZ - 1 - 12);
53854bd896eb4a66315665e9522371b6b10c284c036qhuang
53954bd896eb4a66315665e9522371b6b10c284c036qhuang    do {
540b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao      if ((Sd->mBitBuf & Mask) != 0) {
54154bd896eb4a66315665e9522371b6b10c284c036qhuang        Index2 = Sd->mRight[Index2];
54254bd896eb4a66315665e9522371b6b10c284c036qhuang      } else {
54354bd896eb4a66315665e9522371b6b10c284c036qhuang        Index2 = Sd->mLeft[Index2];
54454bd896eb4a66315665e9522371b6b10c284c036qhuang      }
54554bd896eb4a66315665e9522371b6b10c284c036qhuang
54654bd896eb4a66315665e9522371b6b10c284c036qhuang      Mask >>= 1;
54754bd896eb4a66315665e9522371b6b10c284c036qhuang    } while (Index2 >= NC);
54854bd896eb4a66315665e9522371b6b10c284c036qhuang  }
54954bd896eb4a66315665e9522371b6b10c284c036qhuang  //
55054bd896eb4a66315665e9522371b6b10c284c036qhuang  // Advance what we have read
55154bd896eb4a66315665e9522371b6b10c284c036qhuang  //
55254bd896eb4a66315665e9522371b6b10c284c036qhuang  FillBuf (Sd, Sd->mCLen[Index2]);
55354bd896eb4a66315665e9522371b6b10c284c036qhuang
55454bd896eb4a66315665e9522371b6b10c284c036qhuang  return Index2;
55554bd896eb4a66315665e9522371b6b10c284c036qhuang}
55654bd896eb4a66315665e9522371b6b10c284c036qhuang
557ed7752ec44001d317f79c8631dccd9650c396617klu/**
558b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  Decode the source data and put the resulting data into the destination buffer.
559ed7752ec44001d317f79c8631dccd9650c396617klu
560b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  @param  Sd The global scratch data
561ed7752ec44001d317f79c8631dccd9650c396617klu**/
56254bd896eb4a66315665e9522371b6b10c284c036qhuangVOID
56354bd896eb4a66315665e9522371b6b10c284c036qhuangDecode (
56454bd896eb4a66315665e9522371b6b10c284c036qhuang  SCRATCH_DATA  *Sd
56554bd896eb4a66315665e9522371b6b10c284c036qhuang  )
56654bd896eb4a66315665e9522371b6b10c284c036qhuang{
56754bd896eb4a66315665e9522371b6b10c284c036qhuang  UINT16  BytesRemain;
56854bd896eb4a66315665e9522371b6b10c284c036qhuang  UINT32  DataIdx;
56954bd896eb4a66315665e9522371b6b10c284c036qhuang  UINT16  CharC;
57054bd896eb4a66315665e9522371b6b10c284c036qhuang
57154bd896eb4a66315665e9522371b6b10c284c036qhuang  BytesRemain = (UINT16) (-1);
57254bd896eb4a66315665e9522371b6b10c284c036qhuang
57354bd896eb4a66315665e9522371b6b10c284c036qhuang  DataIdx     = 0;
57454bd896eb4a66315665e9522371b6b10c284c036qhuang
57554bd896eb4a66315665e9522371b6b10c284c036qhuang  for (;;) {
576b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao    //
577b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao    // Get one code from mBitBuf
578b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao    //
57954bd896eb4a66315665e9522371b6b10c284c036qhuang    CharC = DecodeC (Sd);
58054bd896eb4a66315665e9522371b6b10c284c036qhuang    if (Sd->mBadTableFlag != 0) {
581b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao      goto Done;
58254bd896eb4a66315665e9522371b6b10c284c036qhuang    }
58354bd896eb4a66315665e9522371b6b10c284c036qhuang
58454bd896eb4a66315665e9522371b6b10c284c036qhuang    if (CharC < 256) {
58554bd896eb4a66315665e9522371b6b10c284c036qhuang      //
58654bd896eb4a66315665e9522371b6b10c284c036qhuang      // Process an Original character
58754bd896eb4a66315665e9522371b6b10c284c036qhuang      //
58854bd896eb4a66315665e9522371b6b10c284c036qhuang      if (Sd->mOutBuf >= Sd->mOrigSize) {
589b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao        goto Done;
59054bd896eb4a66315665e9522371b6b10c284c036qhuang      } else {
591b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao        //
592b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao        // Write orignal character into mDstBase
593b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao        //
59454bd896eb4a66315665e9522371b6b10c284c036qhuang        Sd->mDstBase[Sd->mOutBuf++] = (UINT8) CharC;
59554bd896eb4a66315665e9522371b6b10c284c036qhuang      }
59654bd896eb4a66315665e9522371b6b10c284c036qhuang
59754bd896eb4a66315665e9522371b6b10c284c036qhuang    } else {
59854bd896eb4a66315665e9522371b6b10c284c036qhuang      //
59954bd896eb4a66315665e9522371b6b10c284c036qhuang      // Process a Pointer
60054bd896eb4a66315665e9522371b6b10c284c036qhuang      //
601157939117269f4f3850ddf19cbccf2159db606c4mdkinney      CharC       = (UINT16) (CharC - (BIT8 - THRESHOLD));
602b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao
603b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao      //
604b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao      // Get string length
605b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao      //
60654bd896eb4a66315665e9522371b6b10c284c036qhuang      BytesRemain = CharC;
60754bd896eb4a66315665e9522371b6b10c284c036qhuang
608b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao      //
609b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao      // Locate string position
610b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao      //
61154bd896eb4a66315665e9522371b6b10c284c036qhuang      DataIdx     = Sd->mOutBuf - DecodeP (Sd) - 1;
61254bd896eb4a66315665e9522371b6b10c284c036qhuang
613b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao      //
614b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao      // Write BytesRemain of bytes into mDstBase
615b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao      //
61654bd896eb4a66315665e9522371b6b10c284c036qhuang      BytesRemain--;
61754bd896eb4a66315665e9522371b6b10c284c036qhuang      while ((INT16) (BytesRemain) >= 0) {
61854bd896eb4a66315665e9522371b6b10c284c036qhuang        Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];
61954bd896eb4a66315665e9522371b6b10c284c036qhuang        if (Sd->mOutBuf >= Sd->mOrigSize) {
62054bd896eb4a66315665e9522371b6b10c284c036qhuang          goto Done ;
62154bd896eb4a66315665e9522371b6b10c284c036qhuang        }
62254bd896eb4a66315665e9522371b6b10c284c036qhuang
62354bd896eb4a66315665e9522371b6b10c284c036qhuang        BytesRemain--;
62454bd896eb4a66315665e9522371b6b10c284c036qhuang      }
62554bd896eb4a66315665e9522371b6b10c284c036qhuang    }
62654bd896eb4a66315665e9522371b6b10c284c036qhuang  }
62754bd896eb4a66315665e9522371b6b10c284c036qhuang
62854bd896eb4a66315665e9522371b6b10c284c036qhuangDone:
62954bd896eb4a66315665e9522371b6b10c284c036qhuang  return ;
63054bd896eb4a66315665e9522371b6b10c284c036qhuang}
63154bd896eb4a66315665e9522371b6b10c284c036qhuang
632ed7752ec44001d317f79c8631dccd9650c396617klu/**
633b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  Given a compressed source buffer, this function retrieves the size of
634b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  the uncompressed buffer and the size of the scratch buffer required
635b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  to decompress the compressed source buffer.
636b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao
637b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  Retrieves the size of the uncompressed buffer and the temporary scratch buffer
638b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  required to decompress the buffer specified by Source and SourceSize.
639b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  If the size of the uncompressed buffer or the size of the scratch buffer cannot
640b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  be determined from the compressed data specified by Source and SourceData,
641b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  then RETURN_INVALID_PARAMETER is returned.  Otherwise, the size of the uncompressed
642b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  buffer is returned in DestinationSize, the size of the scratch buffer is returned
643b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  in ScratchSize, and RETURN_SUCCESS is returned.
644b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  This function does not have scratch buffer available to perform a thorough
645b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  checking of the validity of the source data.  It just retrieves the "Original Size"
646b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  field from the beginning bytes of the source data and output it as DestinationSize.
647b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  And ScratchSize is specific to the decompression implementation.
648b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao
649b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  If Source is NULL, then ASSERT().
650b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  If DestinationSize is NULL, then ASSERT().
651b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  If ScratchSize is NULL, then ASSERT().
652b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao
653b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  @param  Source          The source buffer containing the compressed data.
654b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  @param  SourceSize      The size, in bytes, of the source buffer.
655b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  @param  DestinationSize A pointer to the size, in bytes, of the uncompressed buffer
656b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao                          that will be generated when the compressed buffer specified
657b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao                          by Source and SourceSize is decompressed..
658b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  @param  ScratchSize     A pointer to the size, in bytes, of the scratch buffer that
659b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao                          is required to decompress the compressed buffer specified
660b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao                          by Source and SourceSize.
661b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao
662b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  @retval  RETURN_SUCCESS The size of the uncompressed data was returned
663b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao                          in DestinationSize and the size of the scratch
664b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao                          buffer was returned in ScratchSize.
665b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  @retval  RETURN_INVALID_PARAMETER
666b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao                          The size of the uncompressed data or the size of
667b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao                          the scratch buffer cannot be determined from
668b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao                          the compressed data specified by Source
669b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao                          and SourceSize.
670ed7752ec44001d317f79c8631dccd9650c396617klu**/
67154bd896eb4a66315665e9522371b6b10c284c036qhuangRETURN_STATUS
67254bd896eb4a66315665e9522371b6b10c284c036qhuangEFIAPI
67354bd896eb4a66315665e9522371b6b10c284c036qhuangUefiDecompressGetInfo (
67454bd896eb4a66315665e9522371b6b10c284c036qhuang  IN  CONST VOID  *Source,
67554bd896eb4a66315665e9522371b6b10c284c036qhuang  IN  UINT32      SourceSize,
67654bd896eb4a66315665e9522371b6b10c284c036qhuang  OUT UINT32      *DestinationSize,
67754bd896eb4a66315665e9522371b6b10c284c036qhuang  OUT UINT32      *ScratchSize
67854bd896eb4a66315665e9522371b6b10c284c036qhuang  )
67954bd896eb4a66315665e9522371b6b10c284c036qhuang{
68054bd896eb4a66315665e9522371b6b10c284c036qhuang  UINT32  CompressedSize;
68154bd896eb4a66315665e9522371b6b10c284c036qhuang
68254bd896eb4a66315665e9522371b6b10c284c036qhuang  ASSERT (Source != NULL);
68354bd896eb4a66315665e9522371b6b10c284c036qhuang  ASSERT (DestinationSize != NULL);
68454bd896eb4a66315665e9522371b6b10c284c036qhuang  ASSERT (ScratchSize != NULL);
68554bd896eb4a66315665e9522371b6b10c284c036qhuang
68654bd896eb4a66315665e9522371b6b10c284c036qhuang  if (SourceSize < 8) {
68754bd896eb4a66315665e9522371b6b10c284c036qhuang    return RETURN_INVALID_PARAMETER;
68854bd896eb4a66315665e9522371b6b10c284c036qhuang  }
68954bd896eb4a66315665e9522371b6b10c284c036qhuang
690e69a06299978b99051fc078ac3bc46c77f0d5821mdkinney  CompressedSize   = ReadUnaligned32 ((UINT32 *)Source);
69154bd896eb4a66315665e9522371b6b10c284c036qhuang  if (SourceSize < (CompressedSize + 8)) {
69254bd896eb4a66315665e9522371b6b10c284c036qhuang    return RETURN_INVALID_PARAMETER;
69354bd896eb4a66315665e9522371b6b10c284c036qhuang  }
69454bd896eb4a66315665e9522371b6b10c284c036qhuang
69518fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  *ScratchSize  = sizeof (SCRATCH_DATA);
696e69a06299978b99051fc078ac3bc46c77f0d5821mdkinney  *DestinationSize = ReadUnaligned32 ((UINT32 *)Source + 1);
69718fd8d651d7383c429cbcdf3a4262aa32268cd6clgao
69854bd896eb4a66315665e9522371b6b10c284c036qhuang  return RETURN_SUCCESS;
69954bd896eb4a66315665e9522371b6b10c284c036qhuang}
70054bd896eb4a66315665e9522371b6b10c284c036qhuang
701ed7752ec44001d317f79c8631dccd9650c396617klu/**
702b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  Decompresses a compressed source buffer by EFI or Tiano algorithm.
703b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao
704b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  Extracts decompressed data to its original form.
705b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  This function is designed so that the decompression algorithm can be implemented
706b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  without using any memory services.  As a result, this function is not allowed to
707b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  call any memory allocation services in its implementation.  It is the caller's
708b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  responsibility to allocate and free the Destination and Scratch buffers.
709b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  If the compressed source data specified by Source is successfully decompressed
710b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  into Destination, then RETURN_SUCCESS is returned.  If the compressed source data
711b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  specified by Source is not in a valid compressed data format,
712b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  then RETURN_INVALID_PARAMETER is returned.
713b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao
714b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  If Source is NULL, then ASSERT().
715b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  If Destination is NULL, then ASSERT().
716b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  If the required scratch buffer size > 0 and Scratch is NULL, then ASSERT().
717b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao
718b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  @param  Source      The source buffer containing the compressed data.
719b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  @param  Destination The destination buffer to store the decompressed data
720b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  @param  Scratch     A temporary scratch buffer that is used to perform the decompression.
721b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao                      This is an optional parameter that may be NULL if the
722b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao                      required scratch buffer size is 0.
723b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  @param  Version     1 for UEFI Decompress algoruthm, 2 for Tiano Decompess algorithm.
724b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao
725b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  @retval  RETURN_SUCCESS Decompression completed successfully, and
726b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao                          the uncompressed buffer is returned in Destination.
727b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  @retval  RETURN_INVALID_PARAMETER
728b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao                          The source buffer specified by Source is corrupted
729b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao                          (not in a valid compressed format).
730ed7752ec44001d317f79c8631dccd9650c396617klu**/
73154bd896eb4a66315665e9522371b6b10c284c036qhuangRETURN_STATUS
73254bd896eb4a66315665e9522371b6b10c284c036qhuangEFIAPI
73354bd896eb4a66315665e9522371b6b10c284c036qhuangUefiTianoDecompress (
73454bd896eb4a66315665e9522371b6b10c284c036qhuang  IN CONST VOID  *Source,
73554bd896eb4a66315665e9522371b6b10c284c036qhuang  IN OUT VOID    *Destination,
73654bd896eb4a66315665e9522371b6b10c284c036qhuang  IN OUT VOID    *Scratch,
73754bd896eb4a66315665e9522371b6b10c284c036qhuang  IN UINT32      Version
73854bd896eb4a66315665e9522371b6b10c284c036qhuang  )
73954bd896eb4a66315665e9522371b6b10c284c036qhuang{
74054bd896eb4a66315665e9522371b6b10c284c036qhuang  UINT32           CompSize;
74154bd896eb4a66315665e9522371b6b10c284c036qhuang  UINT32           OrigSize;
74254bd896eb4a66315665e9522371b6b10c284c036qhuang  SCRATCH_DATA     *Sd;
74354bd896eb4a66315665e9522371b6b10c284c036qhuang  CONST UINT8      *Src;
74454bd896eb4a66315665e9522371b6b10c284c036qhuang  UINT8            *Dst;
74554bd896eb4a66315665e9522371b6b10c284c036qhuang
74654bd896eb4a66315665e9522371b6b10c284c036qhuang  ASSERT (Source != NULL);
74754bd896eb4a66315665e9522371b6b10c284c036qhuang  ASSERT (Destination != NULL);
74854bd896eb4a66315665e9522371b6b10c284c036qhuang  ASSERT (Scratch != NULL);
74954bd896eb4a66315665e9522371b6b10c284c036qhuang
75054bd896eb4a66315665e9522371b6b10c284c036qhuang  Src     = Source;
75154bd896eb4a66315665e9522371b6b10c284c036qhuang  Dst     = Destination;
75254bd896eb4a66315665e9522371b6b10c284c036qhuang
75354bd896eb4a66315665e9522371b6b10c284c036qhuang  Sd = (SCRATCH_DATA *) Scratch;
75454bd896eb4a66315665e9522371b6b10c284c036qhuang
75554bd896eb4a66315665e9522371b6b10c284c036qhuang  CompSize  = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);
75654bd896eb4a66315665e9522371b6b10c284c036qhuang  OrigSize  = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);
75754bd896eb4a66315665e9522371b6b10c284c036qhuang
75854bd896eb4a66315665e9522371b6b10c284c036qhuang  //
75954bd896eb4a66315665e9522371b6b10c284c036qhuang  // If compressed file size is 0, return
76054bd896eb4a66315665e9522371b6b10c284c036qhuang  //
76154bd896eb4a66315665e9522371b6b10c284c036qhuang  if (OrigSize == 0) {
76254bd896eb4a66315665e9522371b6b10c284c036qhuang    return RETURN_SUCCESS;
76354bd896eb4a66315665e9522371b6b10c284c036qhuang  }
76454bd896eb4a66315665e9522371b6b10c284c036qhuang
76554bd896eb4a66315665e9522371b6b10c284c036qhuang  Src = Src + 8;
76654bd896eb4a66315665e9522371b6b10c284c036qhuang
767779b8368fa0fb3184f9db8cf810616952ef21ec2rsun  SetMem (Sd, sizeof (SCRATCH_DATA), 0);
768779b8368fa0fb3184f9db8cf810616952ef21ec2rsun
76954bd896eb4a66315665e9522371b6b10c284c036qhuang  //
77054bd896eb4a66315665e9522371b6b10c284c036qhuang  // The length of the field 'Position Set Code Length Array Size' in Block Header.
7718a7d75b0625cffee0c67b85afe56763f93d86481qhuang  // For UEFI 2.0 de/compression algorithm(Version 1), mPBit = 4
77254bd896eb4a66315665e9522371b6b10c284c036qhuang  // For Tiano de/compression algorithm(Version 2), mPBit = 5
77354bd896eb4a66315665e9522371b6b10c284c036qhuang  //
77454bd896eb4a66315665e9522371b6b10c284c036qhuang  switch (Version) {
77554bd896eb4a66315665e9522371b6b10c284c036qhuang    case 1 :
77654bd896eb4a66315665e9522371b6b10c284c036qhuang      Sd->mPBit = 4;
77754bd896eb4a66315665e9522371b6b10c284c036qhuang      break;
77854bd896eb4a66315665e9522371b6b10c284c036qhuang    case 2 :
77954bd896eb4a66315665e9522371b6b10c284c036qhuang      Sd->mPBit = 5;
78054bd896eb4a66315665e9522371b6b10c284c036qhuang      break;
78154bd896eb4a66315665e9522371b6b10c284c036qhuang    default:
78254bd896eb4a66315665e9522371b6b10c284c036qhuang      ASSERT (FALSE);
78354bd896eb4a66315665e9522371b6b10c284c036qhuang  }
78454bd896eb4a66315665e9522371b6b10c284c036qhuang  Sd->mSrcBase  = (UINT8 *)Src;
78554bd896eb4a66315665e9522371b6b10c284c036qhuang  Sd->mDstBase  = Dst;
786b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  //
787207f04793e69843ec34078b2f082a0e4660a433aShumin Qiu  // CompSize and OrigSize are calculated in bytes
788b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  //
78954bd896eb4a66315665e9522371b6b10c284c036qhuang  Sd->mCompSize = CompSize;
79054bd896eb4a66315665e9522371b6b10c284c036qhuang  Sd->mOrigSize = OrigSize;
79154bd896eb4a66315665e9522371b6b10c284c036qhuang
79254bd896eb4a66315665e9522371b6b10c284c036qhuang  //
79354bd896eb4a66315665e9522371b6b10c284c036qhuang  // Fill the first BITBUFSIZ bits
79454bd896eb4a66315665e9522371b6b10c284c036qhuang  //
79554bd896eb4a66315665e9522371b6b10c284c036qhuang  FillBuf (Sd, BITBUFSIZ);
79654bd896eb4a66315665e9522371b6b10c284c036qhuang
79754bd896eb4a66315665e9522371b6b10c284c036qhuang  //
79854bd896eb4a66315665e9522371b6b10c284c036qhuang  // Decompress it
79954bd896eb4a66315665e9522371b6b10c284c036qhuang  //
80054bd896eb4a66315665e9522371b6b10c284c036qhuang  Decode (Sd);
80154bd896eb4a66315665e9522371b6b10c284c036qhuang
80254bd896eb4a66315665e9522371b6b10c284c036qhuang  if (Sd->mBadTableFlag != 0) {
80354bd896eb4a66315665e9522371b6b10c284c036qhuang    //
80454bd896eb4a66315665e9522371b6b10c284c036qhuang    // Something wrong with the source
80554bd896eb4a66315665e9522371b6b10c284c036qhuang    //
80654bd896eb4a66315665e9522371b6b10c284c036qhuang    return RETURN_INVALID_PARAMETER;
80754bd896eb4a66315665e9522371b6b10c284c036qhuang  }
80854bd896eb4a66315665e9522371b6b10c284c036qhuang
80954bd896eb4a66315665e9522371b6b10c284c036qhuang  return RETURN_SUCCESS;
81054bd896eb4a66315665e9522371b6b10c284c036qhuang}
81154bd896eb4a66315665e9522371b6b10c284c036qhuang
812ed7752ec44001d317f79c8631dccd9650c396617klu/**
813b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  Decompresses a UEFI compressed source buffer.
814b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao
815b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  Extracts decompressed data to its original form.
816b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  This function is designed so that the decompression algorithm can be implemented
817b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  without using any memory services.  As a result, this function is not allowed to
818b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  call any memory allocation services in its implementation.  It is the caller's
819b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  responsibility to allocate and free the Destination and Scratch buffers.
820b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  If the compressed source data specified by Source is successfully decompressed
821b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  into Destination, then RETURN_SUCCESS is returned.  If the compressed source data
822b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  specified by Source is not in a valid compressed data format,
823b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  then RETURN_INVALID_PARAMETER is returned.
824b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao
825b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  If Source is NULL, then ASSERT().
826b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  If Destination is NULL, then ASSERT().
827b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  If the required scratch buffer size > 0 and Scratch is NULL, then ASSERT().
828b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao
829b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  @param  Source      The source buffer containing the compressed data.
830b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  @param  Destination The destination buffer to store the decompressed data
831b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  @param  Scratch     A temporary scratch buffer that is used to perform the decompression.
832b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao                      This is an optional parameter that may be NULL if the
833b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao                      required scratch buffer size is 0.
834b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao
835b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  @retval  RETURN_SUCCESS Decompression completed successfully, and
836b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao                          the uncompressed buffer is returned in Destination.
837b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  @retval  RETURN_INVALID_PARAMETER
838b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao                          The source buffer specified by Source is corrupted
839b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao                          (not in a valid compressed format).
840ed7752ec44001d317f79c8631dccd9650c396617klu**/
84154bd896eb4a66315665e9522371b6b10c284c036qhuangRETURN_STATUS
84254bd896eb4a66315665e9522371b6b10c284c036qhuangEFIAPI
84354bd896eb4a66315665e9522371b6b10c284c036qhuangUefiDecompress (
84454bd896eb4a66315665e9522371b6b10c284c036qhuang  IN CONST VOID  *Source,
84554bd896eb4a66315665e9522371b6b10c284c036qhuang  IN OUT VOID    *Destination,
84691c681977b2cb1f1d63b5b9a769e5f5419ecffd2lgao  IN OUT VOID    *Scratch  OPTIONAL
84754bd896eb4a66315665e9522371b6b10c284c036qhuang  )
84854bd896eb4a66315665e9522371b6b10c284c036qhuang{
84954bd896eb4a66315665e9522371b6b10c284c036qhuang  return UefiTianoDecompress (Source, Destination, Scratch, 1);
85054bd896eb4a66315665e9522371b6b10c284c036qhuang}
85154bd896eb4a66315665e9522371b6b10c284c036qhuang
852ed7752ec44001d317f79c8631dccd9650c396617klu/**
853b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  Examines a GUIDed section and returns the size of the decoded buffer and the
854b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  size of an optional scratch buffer required to actually decode the data in a GUIDed section.
855b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao
856b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  Examines a GUIDed section specified by InputSection.
857b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  If GUID for InputSection does not match the GUID that this handler supports,
858b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  then RETURN_UNSUPPORTED is returned.
859b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  If the required information can not be retrieved from InputSection,
860b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  then RETURN_INVALID_PARAMETER is returned.
861b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  If the GUID of InputSection does match the GUID that this handler supports,
862b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  then the size required to hold the decoded buffer is returned in OututBufferSize,
863b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  the size of an optional scratch buffer is returned in ScratchSize, and the Attributes field
864b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  from EFI_GUID_DEFINED_SECTION header of InputSection is returned in SectionAttribute.
865b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao
866b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  If InputSection is NULL, then ASSERT().
867b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  If OutputBufferSize is NULL, then ASSERT().
868b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  If ScratchBufferSize is NULL, then ASSERT().
869b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  If SectionAttribute is NULL, then ASSERT().
870b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao
871ed7752ec44001d317f79c8631dccd9650c396617klu
872b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  @param[in]  InputSection       A pointer to a GUIDed section of an FFS formatted file.
873b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  @param[out] OutputBufferSize   A pointer to the size, in bytes, of an output buffer required
874b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao                                 if the buffer specified by InputSection were decoded.
875b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  @param[out] ScratchBufferSize  A pointer to the size, in bytes, required as scratch space
876b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao                                 if the buffer specified by InputSection were decoded.
877b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  @param[out] SectionAttribute   A pointer to the attributes of the GUIDed section. See the Attributes
878b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao                                 field of EFI_GUID_DEFINED_SECTION in the PI Specification.
879b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao
880b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  @retval  RETURN_SUCCESS            The information about InputSection was returned.
881b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  @retval  RETURN_UNSUPPORTED        The section specified by InputSection does not match the GUID this handler supports.
882b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  @retval  RETURN_INVALID_PARAMETER  The information can not be retrieved from the section specified by InputSection.
883ed7752ec44001d317f79c8631dccd9650c396617klu
884ed7752ec44001d317f79c8631dccd9650c396617klu**/
88554bd896eb4a66315665e9522371b6b10c284c036qhuangRETURN_STATUS
88654bd896eb4a66315665e9522371b6b10c284c036qhuangEFIAPI
88718fd8d651d7383c429cbcdf3a4262aa32268cd6clgaoTianoDecompressGetInfo (
88818fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  IN  CONST VOID  *InputSection,
88918fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  OUT UINT32      *OutputBufferSize,
89018fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  OUT UINT32      *ScratchBufferSize,
89118fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  OUT UINT16      *SectionAttribute
89254bd896eb4a66315665e9522371b6b10c284c036qhuang  )
89354bd896eb4a66315665e9522371b6b10c284c036qhuang
89454bd896eb4a66315665e9522371b6b10c284c036qhuang{
89518fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  ASSERT (SectionAttribute != NULL);
89618fd8d651d7383c429cbcdf3a4262aa32268cd6clgao
89718fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  if (InputSection == NULL) {
89818fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    return RETURN_INVALID_PARAMETER;
899d8c79a815f9e993b741ec38cd39498e674e1739elgao  }
900e6c560aad63b09e6aaee3ccc65be462651772fe5lgao
90130f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng  if (IS_SECTION2 (InputSection)) {
90230f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    if (!CompareGuid (
90330f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng        &gTianoCustomDecompressGuid,
90430f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng        &(((EFI_GUID_DEFINED_SECTION2 *) InputSection)->SectionDefinitionGuid))) {
90530f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng      return RETURN_INVALID_PARAMETER;
90630f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    }
90730f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    //
90830f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    // Get guid attribute of guid section.
90930f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    //
91030f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    *SectionAttribute = ((EFI_GUID_DEFINED_SECTION2 *) InputSection)->Attributes;
91130f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng
91230f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    //
91330f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    // Call Tiano GetInfo to get the required size info.
91430f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    //
91530f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    return UefiDecompressGetInfo (
91630f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng             (UINT8 *) InputSection + ((EFI_GUID_DEFINED_SECTION2 *) InputSection)->DataOffset,
91730f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng             SECTION2_SIZE (InputSection) - ((EFI_GUID_DEFINED_SECTION2 *) InputSection)->DataOffset,
91830f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng             OutputBufferSize,
91930f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng             ScratchBufferSize
92030f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng             );
92130f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng  } else {
92230f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    if (!CompareGuid (
92330f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng        &gTianoCustomDecompressGuid,
924e6c560aad63b09e6aaee3ccc65be462651772fe5lgao        &(((EFI_GUID_DEFINED_SECTION *) InputSection)->SectionDefinitionGuid))) {
92530f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng      return RETURN_INVALID_PARAMETER;
92630f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    }
92730f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    //
92830f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    // Get guid attribute of guid section.
92930f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    //
93030f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    *SectionAttribute = ((EFI_GUID_DEFINED_SECTION *) InputSection)->Attributes;
93118fd8d651d7383c429cbcdf3a4262aa32268cd6clgao
93230f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    //
93330f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    // Call Tiano GetInfo to get the required size info.
93430f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    //
93530f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    return UefiDecompressGetInfo (
93630f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng             (UINT8 *) InputSection + ((EFI_GUID_DEFINED_SECTION *) InputSection)->DataOffset,
93730f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng             SECTION_SIZE (InputSection) - ((EFI_GUID_DEFINED_SECTION *) InputSection)->DataOffset,
93830f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng             OutputBufferSize,
93930f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng             ScratchBufferSize
94030f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng             );
94130f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng  }
94254bd896eb4a66315665e9522371b6b10c284c036qhuang}
94354bd896eb4a66315665e9522371b6b10c284c036qhuang
944ed7752ec44001d317f79c8631dccd9650c396617klu/**
945b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  Decompress a Tiano compressed GUIDed section into a caller allocated output buffer.
946b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao
947b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  Decodes the GUIDed section specified by InputSection.
948b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  If GUID for InputSection does not match the GUID that this handler supports, then RETURN_UNSUPPORTED is returned.
949b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  If the data in InputSection can not be decoded, then RETURN_INVALID_PARAMETER is returned.
950b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  If the GUID of InputSection does match the GUID that this handler supports, then InputSection
951b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  is decoded into the buffer specified by OutputBuffer and the authentication status of this
952b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  decode operation is returned in AuthenticationStatus.  If the decoded buffer is identical to the
953b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  data in InputSection, then OutputBuffer is set to point at the data in InputSection.  Otherwise,
954b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  the decoded data will be placed in caller allocated buffer specified by OutputBuffer.
955b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao
956b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  If InputSection is NULL, then ASSERT().
957b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  If OutputBuffer is NULL, then ASSERT().
958b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  If ScratchBuffer is NULL and this decode operation requires a scratch buffer, then ASSERT().
959b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  If AuthenticationStatus is NULL, then ASSERT().
960b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao
961b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao
962b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  @param[in]  InputSection  A pointer to a GUIDed section of an FFS formatted file.
963b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  @param[out] OutputBuffer  A pointer to a buffer that contains the result of a decode operation.
964b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  @param[in] ScratchBuffer  A caller allocated buffer that may be required by this function
965b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao                            as a scratch buffer to perform the decode operation.
966b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  @param[out] AuthenticationStatus
967b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao                            A pointer to the authentication status of the decoded output buffer.
968b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao                            See the definition of authentication status in the EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI
969b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao                            section of the PI Specification. EFI_AUTH_STATUS_PLATFORM_OVERRIDE must
970b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao                            never be set by this handler.
971b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao
972b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  @retval  RETURN_SUCCESS            The buffer specified by InputSection was decoded.
973b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  @retval  RETURN_UNSUPPORTED        The section specified by InputSection does not match the GUID this handler supports.
974b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  @retval  RETURN_INVALID_PARAMETER  The section specified by InputSection can not be decoded.
975ed7752ec44001d317f79c8631dccd9650c396617klu
976bcd70414877e56f3bffff0bf11b07a30ef51a68fklu**/
97754bd896eb4a66315665e9522371b6b10c284c036qhuangRETURN_STATUS
97854bd896eb4a66315665e9522371b6b10c284c036qhuangEFIAPI
97918fd8d651d7383c429cbcdf3a4262aa32268cd6clgaoTianoDecompress (
98018fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  IN CONST  VOID    *InputSection,
98118fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  OUT       VOID    **OutputBuffer,
98218fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  IN        VOID    *ScratchBuffer,        OPTIONAL
98318fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  OUT       UINT32  *AuthenticationStatus
98454bd896eb4a66315665e9522371b6b10c284c036qhuang  )
98554bd896eb4a66315665e9522371b6b10c284c036qhuang{
98618fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  ASSERT (OutputBuffer != NULL);
987b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  ASSERT (InputSection != NULL);
988e6c560aad63b09e6aaee3ccc65be462651772fe5lgao
98930f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng  if (IS_SECTION2 (InputSection)) {
99030f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    if (!CompareGuid (
99130f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng        &gTianoCustomDecompressGuid,
99230f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng        &(((EFI_GUID_DEFINED_SECTION2 *) InputSection)->SectionDefinitionGuid))) {
99330f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng      return RETURN_INVALID_PARAMETER;
99430f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    }
99530f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng
99630f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    //
99730f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    // Set Authentication to Zero.
99830f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    //
99930f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    *AuthenticationStatus = 0;
100030f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng
100130f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    //
100230f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    // Call Tiano Decompress to get the raw data
100330f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    //
100430f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    return UefiTianoDecompress (
100530f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng             (UINT8 *) InputSection + ((EFI_GUID_DEFINED_SECTION2 *) InputSection)->DataOffset,
100630f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng             *OutputBuffer,
100730f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng             ScratchBuffer,
100830f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng             2
100930f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng           );
101030f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng  } else {
101130f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    if (!CompareGuid (
101230f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng        &gTianoCustomDecompressGuid,
1013e6c560aad63b09e6aaee3ccc65be462651772fe5lgao        &(((EFI_GUID_DEFINED_SECTION *) InputSection)->SectionDefinitionGuid))) {
101430f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng      return RETURN_INVALID_PARAMETER;
101530f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    }
1016e6c560aad63b09e6aaee3ccc65be462651772fe5lgao
101730f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    //
101830f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    // Set Authentication to Zero.
101930f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    //
102030f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    *AuthenticationStatus = 0;
102130f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng
102230f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    //
102330f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    // Call Tiano Decompress to get the raw data
102430f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    //
102530f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    return UefiTianoDecompress (
102630f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng             (UINT8 *) InputSection + ((EFI_GUID_DEFINED_SECTION *) InputSection)->DataOffset,
102730f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng             *OutputBuffer,
102830f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng             ScratchBuffer,
102930f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng             2
103030f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng           );
103130f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng  }
103254bd896eb4a66315665e9522371b6b10c284c036qhuang}
1033d8c79a815f9e993b741ec38cd39498e674e1739elgao
1034ed7752ec44001d317f79c8631dccd9650c396617klu/**
1035b4b6c8de1ea59f61f339798ab1e24eb1e1f64ad5lgao  Registers TianoDecompress and TianoDecompressGetInfo handlers with TianoCustomerDecompressGuid
1036ed7752ec44001d317f79c8631dccd9650c396617klu
103718fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  @retval  RETURN_SUCCESS            Register successfully.
1038ed7752ec44001d317f79c8631dccd9650c396617klu  @retval  RETURN_OUT_OF_RESOURCES   No enough memory to store this handler.
1039d8c79a815f9e993b741ec38cd39498e674e1739elgao**/
10408bd22b8aaa4f5d82e6d9493cb369c8bdc74878felgaoRETURN_STATUS
1041d8c79a815f9e993b741ec38cd39498e674e1739elgaoEFIAPI
104218fd8d651d7383c429cbcdf3a4262aa32268cd6clgaoTianoDecompressLibConstructor (
104318fd8d651d7383c429cbcdf3a4262aa32268cd6clgao)
1044d8c79a815f9e993b741ec38cd39498e674e1739elgao{
104518fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  return ExtractGuidedSectionRegisterHandlers (
104618fd8d651d7383c429cbcdf3a4262aa32268cd6clgao          &gTianoCustomDecompressGuid,
104718fd8d651d7383c429cbcdf3a4262aa32268cd6clgao          TianoDecompressGetInfo,
104818fd8d651d7383c429cbcdf3a4262aa32268cd6clgao          TianoDecompress
104930f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng          );
10506bee1632344ede1224baeb4fc27409b02a0389f8klu}
1051