]>
Commit | Line | Data |
---|---|---|
b4b6c8de | 1 | /** @file\r |
0a6f4824 | 2 | UEFI and Tiano Custom Decompress Library\r |
30f001ca | 3 | It will do Tiano or UEFI decompress with different verison parameter.\r |
0a6f4824 LG |
4 | \r |
5 | Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r | |
6 | This program and the accompanying materials\r | |
7 | are licensed and made available under the terms and conditions of the BSD License\r | |
8 | which accompanies this distribution. The full text of the license may be found at\r | |
9 | http://opensource.org/licenses/bsd-license.php\r | |
10 | \r | |
11 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r | |
12 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r | |
54bd896e | 13 | \r |
3db51098 | 14 | **/\r |
54bd896e | 15 | \r |
54bd896e | 16 | #include "BaseUefiTianoCustomDecompressLibInternals.h"\r |
17 | \r | |
ed7752ec | 18 | /**\r |
19 | Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source.\r | |
0a6f4824 | 20 | \r |
ed7752ec | 21 | @param Sd The global scratch data\r |
0a6f4824 | 22 | @param NumOfBits The number of bits to shift and read.\r |
ed7752ec | 23 | **/\r |
54bd896e | 24 | VOID\r |
25 | FillBuf (\r | |
26 | IN SCRATCH_DATA *Sd,\r | |
27 | IN UINT16 NumOfBits\r | |
28 | )\r | |
54bd896e | 29 | {\r |
b4b6c8de LG |
30 | //\r |
31 | // Left shift NumOfBits of bits in advance\r | |
32 | //\r | |
9458afa3 | 33 | Sd->mBitBuf = (UINT32) LShiftU64 (((UINT64)Sd->mBitBuf), NumOfBits);\r |
54bd896e | 34 | \r |
b4b6c8de LG |
35 | //\r |
36 | // Copy data needed in bytes into mSbuBitBuf\r | |
37 | //\r | |
54bd896e | 38 | while (NumOfBits > Sd->mBitCount) {\r |
9458afa3 AF |
39 | NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount);\r |
40 | Sd->mBitBuf |= (UINT32) LShiftU64 (((UINT64)Sd->mSubBitBuf), NumOfBits);\r | |
54bd896e | 41 | \r |
42 | if (Sd->mCompSize > 0) {\r | |
43 | //\r | |
44 | // Get 1 byte into SubBitBuf\r | |
45 | //\r | |
46 | Sd->mCompSize--;\r | |
47 | Sd->mSubBitBuf = 0;\r | |
48 | Sd->mSubBitBuf = Sd->mSrcBase[Sd->mInBuf++];\r | |
49 | Sd->mBitCount = 8;\r | |
50 | \r | |
51 | } else {\r | |
52 | //\r | |
53 | // No more bits from the source, just pad zero bit.\r | |
54 | //\r | |
55 | Sd->mSubBitBuf = 0;\r | |
56 | Sd->mBitCount = 8;\r | |
57 | \r | |
58 | }\r | |
59 | }\r | |
60 | \r | |
b4b6c8de | 61 | //\r |
207f0479 | 62 | // Calculate additional bit count read to update mBitCount\r |
b4b6c8de | 63 | //\r |
54bd896e | 64 | Sd->mBitCount = (UINT16) (Sd->mBitCount - NumOfBits);\r |
0a6f4824 | 65 | \r |
b4b6c8de LG |
66 | //\r |
67 | // Copy NumOfBits of bits from mSubBitBuf into mBitBuf\r | |
68 | //\r | |
54bd896e | 69 | Sd->mBitBuf |= Sd->mSubBitBuf >> Sd->mBitCount;\r |
70 | }\r | |
71 | \r | |
ed7752ec | 72 | /**\r |
73 | Get NumOfBits of bits out from mBitBuf\r | |
54bd896e | 74 | \r |
0a6f4824 LG |
75 | Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent\r |
76 | NumOfBits of bits from source. Returns NumOfBits of bits that are\r | |
54bd896e | 77 | popped out.\r |
78 | \r | |
ed7752ec | 79 | @param Sd The global scratch data.\r |
80 | @param NumOfBits The number of bits to pop and read.\r | |
54bd896e | 81 | \r |
ed7752ec | 82 | @return The bits that are popped out.\r |
54bd896e | 83 | \r |
ed7752ec | 84 | **/\r |
85 | UINT32\r | |
86 | GetBits (\r | |
87 | IN SCRATCH_DATA *Sd,\r | |
88 | IN UINT16 NumOfBits\r | |
89 | )\r | |
54bd896e | 90 | {\r |
91 | UINT32 OutBits;\r | |
92 | \r | |
b4b6c8de LG |
93 | //\r |
94 | // Pop NumOfBits of Bits from Left\r | |
0a6f4824 | 95 | //\r |
54bd896e | 96 | OutBits = (UINT32) (Sd->mBitBuf >> (BITBUFSIZ - NumOfBits));\r |
97 | \r | |
b4b6c8de LG |
98 | //\r |
99 | // Fill up mBitBuf from source\r | |
100 | //\r | |
54bd896e | 101 | FillBuf (Sd, NumOfBits);\r |
102 | \r | |
103 | return OutBits;\r | |
104 | }\r | |
105 | \r | |
ed7752ec | 106 | /**\r |
107 | Creates Huffman Code mapping table according to code length array.\r | |
108 | \r | |
0a6f4824 | 109 | Creates Huffman Code mapping table for Extra Set, Char&Len Set\r |
ed7752ec | 110 | and Position Set according to code length array.\r |
14531b13 | 111 | If TableBits > 16, then ASSERT ().\r |
ed7752ec | 112 | \r |
113 | @param Sd The global scratch data\r | |
114 | @param NumOfChar Number of symbols in the symbol set\r | |
115 | @param BitLen Code length array\r | |
116 | @param TableBits The width of the mapping table\r | |
b4b6c8de | 117 | @param Table The table to be created.\r |
ed7752ec | 118 | \r |
119 | @retval 0 OK.\r | |
120 | @retval BAD_TABLE The table is corrupted.\r | |
121 | \r | |
122 | **/\r | |
54bd896e | 123 | UINT16\r |
124 | MakeTable (\r | |
125 | IN SCRATCH_DATA *Sd,\r | |
126 | IN UINT16 NumOfChar,\r | |
127 | IN UINT8 *BitLen,\r | |
128 | IN UINT16 TableBits,\r | |
129 | OUT UINT16 *Table\r | |
130 | )\r | |
54bd896e | 131 | {\r |
132 | UINT16 Count[17];\r | |
133 | UINT16 Weight[17];\r | |
134 | UINT16 Start[18];\r | |
135 | UINT16 *Pointer;\r | |
136 | UINT16 Index3;\r | |
80267d51 | 137 | UINT16 Index;\r |
54bd896e | 138 | UINT16 Len;\r |
139 | UINT16 Char;\r | |
140 | UINT16 JuBits;\r | |
141 | UINT16 Avail;\r | |
142 | UINT16 NextCode;\r | |
143 | UINT16 Mask;\r | |
144 | UINT16 WordOfStart;\r | |
145 | UINT16 WordOfCount;\r | |
684db6da | 146 | UINT16 MaxTableLength;\r |
54bd896e | 147 | \r |
14531b13 LG |
148 | //\r |
149 | // The maximum mapping table width supported by this internal\r | |
150 | // working function is 16.\r | |
151 | //\r | |
152 | ASSERT (TableBits <= 16);\r | |
153 | \r | |
aa950314 | 154 | for (Index = 0; Index <= 16; Index++) {\r |
54bd896e | 155 | Count[Index] = 0;\r |
156 | }\r | |
157 | \r | |
158 | for (Index = 0; Index < NumOfChar; Index++) {\r | |
684db6da LG |
159 | if (BitLen[Index] > 16) {\r |
160 | return (UINT16) BAD_TABLE;\r | |
161 | }\r | |
54bd896e | 162 | Count[BitLen[Index]]++;\r |
163 | }\r | |
0a6f4824 | 164 | \r |
aa950314 | 165 | Start[0] = 0;\r |
54bd896e | 166 | Start[1] = 0;\r |
167 | \r | |
168 | for (Index = 1; Index <= 16; Index++) {\r | |
169 | WordOfStart = Start[Index];\r | |
170 | WordOfCount = Count[Index];\r | |
171 | Start[Index + 1] = (UINT16) (WordOfStart + (WordOfCount << (16 - Index)));\r | |
172 | }\r | |
173 | \r | |
174 | if (Start[17] != 0) {\r | |
175 | /*(1U << 16)*/\r | |
176 | return (UINT16) BAD_TABLE;\r | |
177 | }\r | |
178 | \r | |
179 | JuBits = (UINT16) (16 - TableBits);\r | |
0a6f4824 | 180 | \r |
aa950314 | 181 | Weight[0] = 0;\r |
54bd896e | 182 | for (Index = 1; Index <= TableBits; Index++) {\r |
183 | Start[Index] >>= JuBits;\r | |
184 | Weight[Index] = (UINT16) (1U << (TableBits - Index));\r | |
185 | }\r | |
186 | \r | |
187 | while (Index <= 16) {\r | |
188 | Weight[Index] = (UINT16) (1U << (16 - Index));\r | |
0a6f4824 | 189 | Index++;\r |
54bd896e | 190 | }\r |
191 | \r | |
192 | Index = (UINT16) (Start[TableBits + 1] >> JuBits);\r | |
193 | \r | |
194 | if (Index != 0) {\r | |
195 | Index3 = (UINT16) (1U << TableBits);\r | |
aa950314 | 196 | if (Index < Index3) {\r |
197 | SetMem16 (Table + Index, (Index3 - Index) * sizeof (*Table), 0);\r | |
54bd896e | 198 | }\r |
199 | }\r | |
200 | \r | |
201 | Avail = NumOfChar;\r | |
202 | Mask = (UINT16) (1U << (15 - TableBits));\r | |
684db6da | 203 | MaxTableLength = (UINT16) (1U << TableBits);\r |
54bd896e | 204 | \r |
205 | for (Char = 0; Char < NumOfChar; Char++) {\r | |
206 | \r | |
207 | Len = BitLen[Char];\r | |
aa950314 | 208 | if (Len == 0 || Len >= 17) {\r |
54bd896e | 209 | continue;\r |
210 | }\r | |
211 | \r | |
212 | NextCode = (UINT16) (Start[Len] + Weight[Len]);\r | |
213 | \r | |
214 | if (Len <= TableBits) {\r | |
215 | \r | |
216 | for (Index = Start[Len]; Index < NextCode; Index++) {\r | |
684db6da LG |
217 | if (Index >= MaxTableLength) {\r |
218 | return (UINT16) BAD_TABLE;\r | |
219 | }\r | |
54bd896e | 220 | Table[Index] = Char;\r |
221 | }\r | |
222 | \r | |
223 | } else {\r | |
224 | \r | |
225 | Index3 = Start[Len];\r | |
226 | Pointer = &Table[Index3 >> JuBits];\r | |
227 | Index = (UINT16) (Len - TableBits);\r | |
228 | \r | |
229 | while (Index != 0) {\r | |
aa950314 | 230 | if (*Pointer == 0 && Avail < (2 * NC - 1)) {\r |
231 | Sd->mRight[Avail] = Sd->mLeft[Avail] = 0;\r | |
54bd896e | 232 | *Pointer = Avail++;\r |
233 | }\r | |
0a6f4824 | 234 | \r |
aa950314 | 235 | if (*Pointer < (2 * NC - 1)) {\r |
236 | if ((Index3 & Mask) != 0) {\r | |
237 | Pointer = &Sd->mRight[*Pointer];\r | |
238 | } else {\r | |
239 | Pointer = &Sd->mLeft[*Pointer];\r | |
240 | }\r | |
54bd896e | 241 | }\r |
242 | \r | |
243 | Index3 <<= 1;\r | |
244 | Index--;\r | |
245 | }\r | |
246 | \r | |
247 | *Pointer = Char;\r | |
248 | \r | |
249 | }\r | |
250 | \r | |
251 | Start[Len] = NextCode;\r | |
252 | }\r | |
253 | //\r | |
254 | // Succeeds\r | |
255 | //\r | |
256 | return 0;\r | |
257 | }\r | |
258 | \r | |
ed7752ec | 259 | /**\r |
260 | Decodes a position value.\r | |
0a6f4824 | 261 | \r |
b4b6c8de LG |
262 | Get a position value according to Position Huffman Table.\r |
263 | \r | |
ed7752ec | 264 | @param Sd the global scratch data\r |
0a6f4824 | 265 | \r |
ed7752ec | 266 | @return The position value decoded.\r |
267 | **/\r | |
54bd896e | 268 | UINT32\r |
269 | DecodeP (\r | |
270 | IN SCRATCH_DATA *Sd\r | |
271 | )\r | |
54bd896e | 272 | {\r |
273 | UINT16 Val;\r | |
274 | UINT32 Mask;\r | |
275 | UINT32 Pos;\r | |
276 | \r | |
277 | Val = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];\r | |
278 | \r | |
279 | if (Val >= MAXNP) {\r | |
280 | Mask = 1U << (BITBUFSIZ - 1 - 8);\r | |
281 | \r | |
282 | do {\r | |
283 | \r | |
b4b6c8de | 284 | if ((Sd->mBitBuf & Mask) != 0) {\r |
54bd896e | 285 | Val = Sd->mRight[Val];\r |
286 | } else {\r | |
287 | Val = Sd->mLeft[Val];\r | |
288 | }\r | |
289 | \r | |
290 | Mask >>= 1;\r | |
291 | } while (Val >= MAXNP);\r | |
292 | }\r | |
293 | //\r | |
294 | // Advance what we have read\r | |
295 | //\r | |
296 | FillBuf (Sd, Sd->mPTLen[Val]);\r | |
297 | \r | |
298 | Pos = Val;\r | |
299 | if (Val > 1) {\r | |
300 | Pos = (UINT32) ((1U << (Val - 1)) + GetBits (Sd, (UINT16) (Val - 1)));\r | |
301 | }\r | |
302 | \r | |
303 | return Pos;\r | |
304 | }\r | |
305 | \r | |
ed7752ec | 306 | /**\r |
307 | Reads code lengths for the Extra Set or the Position Set.\r | |
308 | \r | |
70d3fe9d | 309 | Read in the Extra Set or Position Set Length Array, then\r |
ed7752ec | 310 | generate the Huffman code mapping for them.\r |
311 | \r | |
312 | @param Sd The global scratch data.\r | |
313 | @param nn Number of symbols.\r | |
314 | @param nbit Number of bits needed to represent nn.\r | |
315 | @param Special The special symbol that needs to be taken care of.\r | |
316 | \r | |
317 | @retval 0 OK.\r | |
318 | @retval BAD_TABLE Table is corrupted.\r | |
319 | \r | |
320 | **/\r | |
54bd896e | 321 | UINT16\r |
322 | ReadPTLen (\r | |
323 | IN SCRATCH_DATA *Sd,\r | |
324 | IN UINT16 nn,\r | |
325 | IN UINT16 nbit,\r | |
326 | IN UINT16 Special\r | |
327 | )\r | |
54bd896e | 328 | {\r |
329 | UINT16 Number;\r | |
330 | UINT16 CharC;\r | |
80267d51 | 331 | UINT16 Index;\r |
54bd896e | 332 | UINT32 Mask;\r |
333 | \r | |
5a189086 | 334 | ASSERT (nn <= NPT);\r |
aa950314 | 335 | //\r |
0a6f4824 | 336 | // Read Extra Set Code Length Array size\r |
aa950314 | 337 | //\r |
54bd896e | 338 | Number = (UINT16) GetBits (Sd, nbit);\r |
339 | \r | |
340 | if (Number == 0) {\r | |
aa950314 | 341 | //\r |
342 | // This represents only Huffman code used\r | |
343 | //\r | |
54bd896e | 344 | CharC = (UINT16) GetBits (Sd, nbit);\r |
345 | \r | |
346 | for (Index = 0; Index < 256; Index++) {\r | |
347 | Sd->mPTTable[Index] = CharC;\r | |
348 | }\r | |
349 | \r | |
aa950314 | 350 | SetMem (Sd->mPTLen, nn, 0);\r |
54bd896e | 351 | \r |
352 | return 0;\r | |
353 | }\r | |
354 | \r | |
355 | Index = 0;\r | |
356 | \r | |
aa950314 | 357 | while (Index < Number && Index < NPT) {\r |
54bd896e | 358 | \r |
359 | CharC = (UINT16) (Sd->mBitBuf >> (BITBUFSIZ - 3));\r | |
360 | \r | |
aa950314 | 361 | //\r |
362 | // If a code length is less than 7, then it is encoded as a 3-bit\r | |
0a6f4824 | 363 | // value. Or it is encoded as a series of "1"s followed by a\r |
aa950314 | 364 | // terminating "0". The number of "1"s = Code length - 4.\r |
365 | //\r | |
54bd896e | 366 | if (CharC == 7) {\r |
367 | Mask = 1U << (BITBUFSIZ - 1 - 3);\r | |
368 | while (Mask & Sd->mBitBuf) {\r | |
369 | Mask >>= 1;\r | |
370 | CharC += 1;\r | |
371 | }\r | |
372 | }\r | |
0a6f4824 | 373 | \r |
54bd896e | 374 | FillBuf (Sd, (UINT16) ((CharC < 7) ? 3 : CharC - 3));\r |
375 | \r | |
376 | Sd->mPTLen[Index++] = (UINT8) CharC;\r | |
0a6f4824 | 377 | \r |
aa950314 | 378 | //\r |
0a6f4824 | 379 | // For Code&Len Set,\r |
aa950314 | 380 | // After the third length of the code length concatenation,\r |
0a6f4824 | 381 | // a 2-bit value is used to indicated the number of consecutive\r |
aa950314 | 382 | // zero lengths after the third length.\r |
383 | //\r | |
54bd896e | 384 | if (Index == Special) {\r |
385 | CharC = (UINT16) GetBits (Sd, 2);\r | |
aa950314 | 386 | while ((INT16) (--CharC) >= 0 && Index < NPT) {\r |
54bd896e | 387 | Sd->mPTLen[Index++] = 0;\r |
388 | }\r | |
389 | }\r | |
390 | }\r | |
391 | \r | |
aa950314 | 392 | while (Index < nn && Index < NPT) {\r |
54bd896e | 393 | Sd->mPTLen[Index++] = 0;\r |
394 | }\r | |
0a6f4824 | 395 | \r |
54bd896e | 396 | return MakeTable (Sd, nn, Sd->mPTLen, 8, Sd->mPTTable);\r |
397 | }\r | |
398 | \r | |
ed7752ec | 399 | /**\r |
400 | Reads code lengths for Char&Len Set.\r | |
0a6f4824 | 401 | \r |
ed7752ec | 402 | Read in and decode the Char&Len Set Code Length Array, then\r |
403 | generate the Huffman Code mapping table for the Char&Len Set.\r | |
404 | \r | |
405 | @param Sd the global scratch data\r | |
406 | \r | |
407 | **/\r | |
54bd896e | 408 | VOID\r |
409 | ReadCLen (\r | |
410 | SCRATCH_DATA *Sd\r | |
411 | )\r | |
54bd896e | 412 | {\r |
413 | UINT16 Number;\r | |
414 | UINT16 CharC;\r | |
80267d51 | 415 | UINT16 Index;\r |
54bd896e | 416 | UINT32 Mask;\r |
417 | \r | |
418 | Number = (UINT16) GetBits (Sd, CBIT);\r | |
419 | \r | |
420 | if (Number == 0) {\r | |
aa950314 | 421 | //\r |
422 | // This represents only Huffman code used\r | |
423 | //\r | |
54bd896e | 424 | CharC = (UINT16) GetBits (Sd, CBIT);\r |
425 | \r | |
aa950314 | 426 | SetMem (Sd->mCLen, NC, 0);\r |
54bd896e | 427 | \r |
428 | for (Index = 0; Index < 4096; Index++) {\r | |
429 | Sd->mCTable[Index] = CharC;\r | |
430 | }\r | |
431 | \r | |
432 | return ;\r | |
433 | }\r | |
434 | \r | |
435 | Index = 0;\r | |
aa950314 | 436 | while (Index < Number && Index < NC) {\r |
54bd896e | 437 | CharC = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];\r |
438 | if (CharC >= NT) {\r | |
439 | Mask = 1U << (BITBUFSIZ - 1 - 8);\r | |
440 | \r | |
441 | do {\r | |
442 | \r | |
443 | if (Mask & Sd->mBitBuf) {\r | |
444 | CharC = Sd->mRight[CharC];\r | |
445 | } else {\r | |
446 | CharC = Sd->mLeft[CharC];\r | |
447 | }\r | |
448 | \r | |
449 | Mask >>= 1;\r | |
450 | \r | |
451 | } while (CharC >= NT);\r | |
452 | }\r | |
453 | //\r | |
454 | // Advance what we have read\r | |
455 | //\r | |
456 | FillBuf (Sd, Sd->mPTLen[CharC]);\r | |
457 | \r | |
458 | if (CharC <= 2) {\r | |
459 | \r | |
460 | if (CharC == 0) {\r | |
461 | CharC = 1;\r | |
462 | } else if (CharC == 1) {\r | |
463 | CharC = (UINT16) (GetBits (Sd, 4) + 3);\r | |
464 | } else if (CharC == 2) {\r | |
465 | CharC = (UINT16) (GetBits (Sd, CBIT) + 20);\r | |
466 | }\r | |
467 | \r | |
aa950314 | 468 | while ((INT16) (--CharC) >= 0 && Index < NC) {\r |
54bd896e | 469 | Sd->mCLen[Index++] = 0;\r |
470 | }\r | |
471 | \r | |
472 | } else {\r | |
473 | \r | |
474 | Sd->mCLen[Index++] = (UINT8) (CharC - 2);\r | |
475 | \r | |
476 | }\r | |
477 | }\r | |
478 | \r | |
aa950314 | 479 | SetMem (Sd->mCLen + Index, NC - Index, 0);\r |
54bd896e | 480 | \r |
481 | MakeTable (Sd, NC, Sd->mCLen, 12, Sd->mCTable);\r | |
482 | \r | |
483 | return ;\r | |
484 | }\r | |
485 | \r | |
ed7752ec | 486 | /**\r |
54bd896e | 487 | Decode a character/length value.\r |
0a6f4824 | 488 | \r |
ed7752ec | 489 | Read one value from mBitBuf, Get one code from mBitBuf. If it is at block boundary, generates\r |
490 | Huffman code mapping table for Extra Set, Code&Len Set and\r | |
491 | Position Set.\r | |
54bd896e | 492 | \r |
ed7752ec | 493 | @param Sd The global scratch data.\r |
54bd896e | 494 | \r |
ed7752ec | 495 | @return The value decoded.\r |
54bd896e | 496 | \r |
ed7752ec | 497 | **/\r |
498 | UINT16\r | |
499 | DecodeC (\r | |
500 | SCRATCH_DATA *Sd\r | |
501 | )\r | |
54bd896e | 502 | {\r |
503 | UINT16 Index2;\r | |
504 | UINT32 Mask;\r | |
505 | \r | |
506 | if (Sd->mBlockSize == 0) {\r | |
507 | //\r | |
508 | // Starting a new block\r | |
b4b6c8de | 509 | // Read BlockSize from block header\r |
0a6f4824 | 510 | //\r |
54bd896e | 511 | Sd->mBlockSize = (UINT16) GetBits (Sd, 16);\r |
b4b6c8de LG |
512 | \r |
513 | //\r | |
70d3fe9d | 514 | // Read in the Extra Set Code Length Array,\r |
b4b6c8de LG |
515 | // Generate the Huffman code mapping table for Extra Set.\r |
516 | //\r | |
54bd896e | 517 | Sd->mBadTableFlag = ReadPTLen (Sd, NT, TBIT, 3);\r |
518 | if (Sd->mBadTableFlag != 0) {\r | |
519 | return 0;\r | |
520 | }\r | |
521 | \r | |
b4b6c8de | 522 | //\r |
70d3fe9d | 523 | // Read in and decode the Char&Len Set Code Length Array,\r |
b4b6c8de LG |
524 | // Generate the Huffman code mapping table for Char&Len Set.\r |
525 | //\r | |
54bd896e | 526 | ReadCLen (Sd);\r |
527 | \r | |
b4b6c8de | 528 | //\r |
70d3fe9d | 529 | // Read in the Position Set Code Length Array,\r |
b4b6c8de LG |
530 | // Generate the Huffman code mapping table for the Position Set.\r |
531 | //\r | |
54bd896e | 532 | Sd->mBadTableFlag = ReadPTLen (Sd, MAXNP, Sd->mPBit, (UINT16) (-1));\r |
533 | if (Sd->mBadTableFlag != 0) {\r | |
534 | return 0;\r | |
535 | }\r | |
536 | }\r | |
537 | \r | |
b4b6c8de LG |
538 | //\r |
539 | // Get one code according to Code&Set Huffman Table\r | |
540 | //\r | |
54bd896e | 541 | Sd->mBlockSize--;\r |
542 | Index2 = Sd->mCTable[Sd->mBitBuf >> (BITBUFSIZ - 12)];\r | |
543 | \r | |
544 | if (Index2 >= NC) {\r | |
545 | Mask = 1U << (BITBUFSIZ - 1 - 12);\r | |
546 | \r | |
547 | do {\r | |
b4b6c8de | 548 | if ((Sd->mBitBuf & Mask) != 0) {\r |
54bd896e | 549 | Index2 = Sd->mRight[Index2];\r |
550 | } else {\r | |
551 | Index2 = Sd->mLeft[Index2];\r | |
552 | }\r | |
553 | \r | |
554 | Mask >>= 1;\r | |
555 | } while (Index2 >= NC);\r | |
556 | }\r | |
557 | //\r | |
558 | // Advance what we have read\r | |
559 | //\r | |
560 | FillBuf (Sd, Sd->mCLen[Index2]);\r | |
561 | \r | |
562 | return Index2;\r | |
563 | }\r | |
564 | \r | |
ed7752ec | 565 | /**\r |
b4b6c8de | 566 | Decode the source data and put the resulting data into the destination buffer.\r |
0a6f4824 | 567 | \r |
b4b6c8de | 568 | @param Sd The global scratch data\r |
ed7752ec | 569 | **/\r |
54bd896e | 570 | VOID\r |
571 | Decode (\r | |
572 | SCRATCH_DATA *Sd\r | |
573 | )\r | |
54bd896e | 574 | {\r |
575 | UINT16 BytesRemain;\r | |
576 | UINT32 DataIdx;\r | |
577 | UINT16 CharC;\r | |
578 | \r | |
579 | BytesRemain = (UINT16) (-1);\r | |
580 | \r | |
581 | DataIdx = 0;\r | |
582 | \r | |
583 | for (;;) {\r | |
b4b6c8de LG |
584 | //\r |
585 | // Get one code from mBitBuf\r | |
0a6f4824 | 586 | //\r |
54bd896e | 587 | CharC = DecodeC (Sd);\r |
588 | if (Sd->mBadTableFlag != 0) {\r | |
b4b6c8de | 589 | goto Done;\r |
54bd896e | 590 | }\r |
591 | \r | |
592 | if (CharC < 256) {\r | |
593 | //\r | |
594 | // Process an Original character\r | |
595 | //\r | |
596 | if (Sd->mOutBuf >= Sd->mOrigSize) {\r | |
b4b6c8de | 597 | goto Done;\r |
54bd896e | 598 | } else {\r |
b4b6c8de LG |
599 | //\r |
600 | // Write orignal character into mDstBase\r | |
601 | //\r | |
54bd896e | 602 | Sd->mDstBase[Sd->mOutBuf++] = (UINT8) CharC;\r |
603 | }\r | |
604 | \r | |
605 | } else {\r | |
606 | //\r | |
607 | // Process a Pointer\r | |
608 | //\r | |
15793911 | 609 | CharC = (UINT16) (CharC - (BIT8 - THRESHOLD));\r |
0a6f4824 | 610 | \r |
b4b6c8de LG |
611 | //\r |
612 | // Get string length\r | |
613 | //\r | |
54bd896e | 614 | BytesRemain = CharC;\r |
615 | \r | |
b4b6c8de LG |
616 | //\r |
617 | // Locate string position\r | |
618 | //\r | |
54bd896e | 619 | DataIdx = Sd->mOutBuf - DecodeP (Sd) - 1;\r |
620 | \r | |
b4b6c8de LG |
621 | //\r |
622 | // Write BytesRemain of bytes into mDstBase\r | |
623 | //\r | |
54bd896e | 624 | BytesRemain--;\r |
625 | while ((INT16) (BytesRemain) >= 0) {\r | |
54bd896e | 626 | if (Sd->mOutBuf >= Sd->mOrigSize) {\r |
627 | goto Done ;\r | |
628 | }\r | |
684db6da LG |
629 | if (DataIdx >= Sd->mOrigSize) {\r |
630 | Sd->mBadTableFlag = (UINT16) BAD_TABLE;\r | |
631 | goto Done ;\r | |
632 | }\r | |
633 | Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];\r | |
54bd896e | 634 | \r |
635 | BytesRemain--;\r | |
636 | }\r | |
ade71c52 LG |
637 | //\r |
638 | // Once mOutBuf is fully filled, directly return\r | |
639 | //\r | |
640 | if (Sd->mOutBuf >= Sd->mOrigSize) {\r | |
641 | goto Done ;\r | |
642 | }\r | |
54bd896e | 643 | }\r |
644 | }\r | |
645 | \r | |
646 | Done:\r | |
647 | return ;\r | |
648 | }\r | |
649 | \r | |
ed7752ec | 650 | /**\r |
0a6f4824 LG |
651 | Given a compressed source buffer, this function retrieves the size of\r |
652 | the uncompressed buffer and the size of the scratch buffer required\r | |
b4b6c8de LG |
653 | to decompress the compressed source buffer.\r |
654 | \r | |
0a6f4824 | 655 | Retrieves the size of the uncompressed buffer and the temporary scratch buffer\r |
b4b6c8de LG |
656 | required to decompress the buffer specified by Source and SourceSize.\r |
657 | If the size of the uncompressed buffer or the size of the scratch buffer cannot\r | |
0a6f4824 | 658 | be determined from the compressed data specified by Source and SourceData,\r |
b4b6c8de LG |
659 | then RETURN_INVALID_PARAMETER is returned. Otherwise, the size of the uncompressed\r |
660 | buffer is returned in DestinationSize, the size of the scratch buffer is returned\r | |
661 | in ScratchSize, and RETURN_SUCCESS is returned.\r | |
0a6f4824 | 662 | This function does not have scratch buffer available to perform a thorough\r |
b4b6c8de LG |
663 | checking of the validity of the source data. It just retrieves the "Original Size"\r |
664 | field from the beginning bytes of the source data and output it as DestinationSize.\r | |
665 | And ScratchSize is specific to the decompression implementation.\r | |
666 | \r | |
667 | If Source is NULL, then ASSERT().\r | |
668 | If DestinationSize is NULL, then ASSERT().\r | |
669 | If ScratchSize is NULL, then ASSERT().\r | |
670 | \r | |
671 | @param Source The source buffer containing the compressed data.\r | |
672 | @param SourceSize The size, in bytes, of the source buffer.\r | |
673 | @param DestinationSize A pointer to the size, in bytes, of the uncompressed buffer\r | |
674 | that will be generated when the compressed buffer specified\r | |
675 | by Source and SourceSize is decompressed..\r | |
676 | @param ScratchSize A pointer to the size, in bytes, of the scratch buffer that\r | |
0a6f4824 | 677 | is required to decompress the compressed buffer specified\r |
b4b6c8de LG |
678 | by Source and SourceSize.\r |
679 | \r | |
0a6f4824 LG |
680 | @retval RETURN_SUCCESS The size of the uncompressed data was returned\r |
681 | in DestinationSize and the size of the scratch\r | |
b4b6c8de | 682 | buffer was returned in ScratchSize.\r |
0a6f4824 LG |
683 | @retval RETURN_INVALID_PARAMETER\r |
684 | The size of the uncompressed data or the size of\r | |
685 | the scratch buffer cannot be determined from\r | |
686 | the compressed data specified by Source\r | |
b4b6c8de | 687 | and SourceSize.\r |
ed7752ec | 688 | **/\r |
54bd896e | 689 | RETURN_STATUS\r |
690 | EFIAPI\r | |
691 | UefiDecompressGetInfo (\r | |
692 | IN CONST VOID *Source,\r | |
693 | IN UINT32 SourceSize,\r | |
694 | OUT UINT32 *DestinationSize,\r | |
695 | OUT UINT32 *ScratchSize\r | |
696 | )\r | |
54bd896e | 697 | {\r |
698 | UINT32 CompressedSize;\r | |
699 | \r | |
700 | ASSERT (Source != NULL);\r | |
701 | ASSERT (DestinationSize != NULL);\r | |
702 | ASSERT (ScratchSize != NULL);\r | |
703 | \r | |
54bd896e | 704 | if (SourceSize < 8) {\r |
705 | return RETURN_INVALID_PARAMETER;\r | |
706 | }\r | |
707 | \r | |
e69a0629 | 708 | CompressedSize = ReadUnaligned32 ((UINT32 *)Source);\r |
684db6da | 709 | if (SourceSize < (CompressedSize + 8) || (CompressedSize + 8) < 8) {\r |
54bd896e | 710 | return RETURN_INVALID_PARAMETER;\r |
711 | }\r | |
712 | \r | |
18fd8d65 | 713 | *ScratchSize = sizeof (SCRATCH_DATA);\r |
e69a0629 | 714 | *DestinationSize = ReadUnaligned32 ((UINT32 *)Source + 1);\r |
18fd8d65 | 715 | \r |
54bd896e | 716 | return RETURN_SUCCESS;\r |
717 | }\r | |
718 | \r | |
ed7752ec | 719 | /**\r |
b4b6c8de LG |
720 | Decompresses a compressed source buffer by EFI or Tiano algorithm.\r |
721 | \r | |
722 | Extracts decompressed data to its original form.\r | |
723 | This function is designed so that the decompression algorithm can be implemented\r | |
724 | without using any memory services. As a result, this function is not allowed to\r | |
0a6f4824 | 725 | call any memory allocation services in its implementation. It is the caller's\r |
b4b6c8de | 726 | responsibility to allocate and free the Destination and Scratch buffers.\r |
0a6f4824 LG |
727 | If the compressed source data specified by Source is successfully decompressed\r |
728 | into Destination, then RETURN_SUCCESS is returned. If the compressed source data\r | |
b4b6c8de LG |
729 | specified by Source is not in a valid compressed data format,\r |
730 | then RETURN_INVALID_PARAMETER is returned.\r | |
731 | \r | |
732 | If Source is NULL, then ASSERT().\r | |
733 | If Destination is NULL, then ASSERT().\r | |
734 | If the required scratch buffer size > 0 and Scratch is NULL, then ASSERT().\r | |
735 | \r | |
736 | @param Source The source buffer containing the compressed data.\r | |
737 | @param Destination The destination buffer to store the decompressed data\r | |
738 | @param Scratch A temporary scratch buffer that is used to perform the decompression.\r | |
0a6f4824 | 739 | This is an optional parameter that may be NULL if the\r |
b4b6c8de LG |
740 | required scratch buffer size is 0.\r |
741 | @param Version 1 for UEFI Decompress algoruthm, 2 for Tiano Decompess algorithm.\r | |
742 | \r | |
0a6f4824 | 743 | @retval RETURN_SUCCESS Decompression completed successfully, and\r |
b4b6c8de | 744 | the uncompressed buffer is returned in Destination.\r |
0a6f4824 LG |
745 | @retval RETURN_INVALID_PARAMETER\r |
746 | The source buffer specified by Source is corrupted\r | |
b4b6c8de | 747 | (not in a valid compressed format).\r |
ed7752ec | 748 | **/\r |
54bd896e | 749 | RETURN_STATUS\r |
750 | EFIAPI\r | |
751 | UefiTianoDecompress (\r | |
752 | IN CONST VOID *Source,\r | |
753 | IN OUT VOID *Destination,\r | |
754 | IN OUT VOID *Scratch,\r | |
755 | IN UINT32 Version\r | |
756 | )\r | |
54bd896e | 757 | {\r |
54bd896e | 758 | UINT32 CompSize;\r |
759 | UINT32 OrigSize;\r | |
760 | SCRATCH_DATA *Sd;\r | |
761 | CONST UINT8 *Src;\r | |
762 | UINT8 *Dst;\r | |
763 | \r | |
764 | ASSERT (Source != NULL);\r | |
765 | ASSERT (Destination != NULL);\r | |
766 | ASSERT (Scratch != NULL);\r | |
767 | \r | |
768 | Src = Source;\r | |
769 | Dst = Destination;\r | |
770 | \r | |
771 | Sd = (SCRATCH_DATA *) Scratch;\r | |
772 | \r | |
773 | CompSize = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);\r | |
774 | OrigSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);\r | |
775 | \r | |
776 | //\r | |
777 | // If compressed file size is 0, return\r | |
778 | //\r | |
779 | if (OrigSize == 0) {\r | |
780 | return RETURN_SUCCESS;\r | |
781 | }\r | |
782 | \r | |
783 | Src = Src + 8;\r | |
784 | \r | |
779b8368 | 785 | SetMem (Sd, sizeof (SCRATCH_DATA), 0);\r |
786 | \r | |
54bd896e | 787 | //\r |
788 | // The length of the field 'Position Set Code Length Array Size' in Block Header.\r | |
8a7d75b0 | 789 | // For UEFI 2.0 de/compression algorithm(Version 1), mPBit = 4\r |
54bd896e | 790 | // For Tiano de/compression algorithm(Version 2), mPBit = 5\r |
791 | //\r | |
792 | switch (Version) {\r | |
793 | case 1 :\r | |
794 | Sd->mPBit = 4;\r | |
795 | break;\r | |
796 | case 2 :\r | |
797 | Sd->mPBit = 5;\r | |
798 | break;\r | |
799 | default:\r | |
800 | ASSERT (FALSE);\r | |
801 | }\r | |
802 | Sd->mSrcBase = (UINT8 *)Src;\r | |
803 | Sd->mDstBase = Dst;\r | |
b4b6c8de | 804 | //\r |
207f0479 | 805 | // CompSize and OrigSize are calculated in bytes\r |
b4b6c8de | 806 | //\r |
54bd896e | 807 | Sd->mCompSize = CompSize;\r |
808 | Sd->mOrigSize = OrigSize;\r | |
809 | \r | |
810 | //\r | |
811 | // Fill the first BITBUFSIZ bits\r | |
812 | //\r | |
813 | FillBuf (Sd, BITBUFSIZ);\r | |
814 | \r | |
815 | //\r | |
816 | // Decompress it\r | |
817 | //\r | |
818 | Decode (Sd);\r | |
819 | \r | |
820 | if (Sd->mBadTableFlag != 0) {\r | |
821 | //\r | |
822 | // Something wrong with the source\r | |
823 | //\r | |
824 | return RETURN_INVALID_PARAMETER;\r | |
825 | }\r | |
826 | \r | |
827 | return RETURN_SUCCESS;\r | |
828 | }\r | |
829 | \r | |
ed7752ec | 830 | /**\r |
b4b6c8de LG |
831 | Decompresses a UEFI compressed source buffer.\r |
832 | \r | |
833 | Extracts decompressed data to its original form.\r | |
834 | This function is designed so that the decompression algorithm can be implemented\r | |
835 | without using any memory services. As a result, this function is not allowed to\r | |
0a6f4824 | 836 | call any memory allocation services in its implementation. It is the caller's\r |
b4b6c8de | 837 | responsibility to allocate and free the Destination and Scratch buffers.\r |
0a6f4824 LG |
838 | If the compressed source data specified by Source is successfully decompressed\r |
839 | into Destination, then RETURN_SUCCESS is returned. If the compressed source data\r | |
b4b6c8de LG |
840 | specified by Source is not in a valid compressed data format,\r |
841 | then RETURN_INVALID_PARAMETER is returned.\r | |
842 | \r | |
843 | If Source is NULL, then ASSERT().\r | |
844 | If Destination is NULL, then ASSERT().\r | |
845 | If the required scratch buffer size > 0 and Scratch is NULL, then ASSERT().\r | |
846 | \r | |
847 | @param Source The source buffer containing the compressed data.\r | |
848 | @param Destination The destination buffer to store the decompressed data\r | |
849 | @param Scratch A temporary scratch buffer that is used to perform the decompression.\r | |
0a6f4824 | 850 | This is an optional parameter that may be NULL if the\r |
b4b6c8de LG |
851 | required scratch buffer size is 0.\r |
852 | \r | |
0a6f4824 | 853 | @retval RETURN_SUCCESS Decompression completed successfully, and\r |
b4b6c8de | 854 | the uncompressed buffer is returned in Destination.\r |
0a6f4824 LG |
855 | @retval RETURN_INVALID_PARAMETER\r |
856 | The source buffer specified by Source is corrupted\r | |
b4b6c8de | 857 | (not in a valid compressed format).\r |
ed7752ec | 858 | **/\r |
54bd896e | 859 | RETURN_STATUS\r |
860 | EFIAPI\r | |
861 | UefiDecompress (\r | |
862 | IN CONST VOID *Source,\r | |
863 | IN OUT VOID *Destination,\r | |
91c68197 | 864 | IN OUT VOID *Scratch OPTIONAL\r |
54bd896e | 865 | )\r |
54bd896e | 866 | {\r |
867 | return UefiTianoDecompress (Source, Destination, Scratch, 1);\r | |
868 | }\r | |
869 | \r | |
ed7752ec | 870 | /**\r |
b4b6c8de LG |
871 | Examines a GUIDed section and returns the size of the decoded buffer and the\r |
872 | size of an optional scratch buffer required to actually decode the data in a GUIDed section.\r | |
873 | \r | |
0a6f4824 | 874 | Examines a GUIDed section specified by InputSection.\r |
b4b6c8de | 875 | If GUID for InputSection does not match the GUID that this handler supports,\r |
0a6f4824 | 876 | then RETURN_UNSUPPORTED is returned.\r |
b4b6c8de LG |
877 | If the required information can not be retrieved from InputSection,\r |
878 | then RETURN_INVALID_PARAMETER is returned.\r | |
879 | If the GUID of InputSection does match the GUID that this handler supports,\r | |
880 | then the size required to hold the decoded buffer is returned in OututBufferSize,\r | |
881 | the size of an optional scratch buffer is returned in ScratchSize, and the Attributes field\r | |
882 | from EFI_GUID_DEFINED_SECTION header of InputSection is returned in SectionAttribute.\r | |
0a6f4824 | 883 | \r |
b4b6c8de LG |
884 | If InputSection is NULL, then ASSERT().\r |
885 | If OutputBufferSize is NULL, then ASSERT().\r | |
886 | If ScratchBufferSize is NULL, then ASSERT().\r | |
887 | If SectionAttribute is NULL, then ASSERT().\r | |
888 | \r | |
ed7752ec | 889 | \r |
b4b6c8de LG |
890 | @param[in] InputSection A pointer to a GUIDed section of an FFS formatted file.\r |
891 | @param[out] OutputBufferSize A pointer to the size, in bytes, of an output buffer required\r | |
892 | if the buffer specified by InputSection were decoded.\r | |
893 | @param[out] ScratchBufferSize A pointer to the size, in bytes, required as scratch space\r | |
894 | if the buffer specified by InputSection were decoded.\r | |
895 | @param[out] SectionAttribute A pointer to the attributes of the GUIDed section. See the Attributes\r | |
896 | field of EFI_GUID_DEFINED_SECTION in the PI Specification.\r | |
897 | \r | |
898 | @retval RETURN_SUCCESS The information about InputSection was returned.\r | |
899 | @retval RETURN_UNSUPPORTED The section specified by InputSection does not match the GUID this handler supports.\r | |
900 | @retval RETURN_INVALID_PARAMETER The information can not be retrieved from the section specified by InputSection.\r | |
ed7752ec | 901 | \r |
ed7752ec | 902 | **/\r |
54bd896e | 903 | RETURN_STATUS\r |
904 | EFIAPI\r | |
18fd8d65 LG |
905 | TianoDecompressGetInfo (\r |
906 | IN CONST VOID *InputSection,\r | |
907 | OUT UINT32 *OutputBufferSize,\r | |
908 | OUT UINT32 *ScratchBufferSize,\r | |
909 | OUT UINT16 *SectionAttribute\r | |
54bd896e | 910 | )\r |
54bd896e | 911 | \r |
54bd896e | 912 | {\r |
18fd8d65 LG |
913 | ASSERT (SectionAttribute != NULL);\r |
914 | \r | |
915 | if (InputSection == NULL) {\r | |
916 | return RETURN_INVALID_PARAMETER;\r | |
d8c79a81 | 917 | }\r |
e6c560aa | 918 | \r |
30f001ca SZ |
919 | if (IS_SECTION2 (InputSection)) {\r |
920 | if (!CompareGuid (\r | |
921 | &gTianoCustomDecompressGuid,\r | |
922 | &(((EFI_GUID_DEFINED_SECTION2 *) InputSection)->SectionDefinitionGuid))) {\r | |
923 | return RETURN_INVALID_PARAMETER;\r | |
924 | }\r | |
925 | //\r | |
0a6f4824 | 926 | // Get guid attribute of guid section.\r |
30f001ca SZ |
927 | //\r |
928 | *SectionAttribute = ((EFI_GUID_DEFINED_SECTION2 *) InputSection)->Attributes;\r | |
929 | \r | |
930 | //\r | |
931 | // Call Tiano GetInfo to get the required size info.\r | |
932 | //\r | |
933 | return UefiDecompressGetInfo (\r | |
934 | (UINT8 *) InputSection + ((EFI_GUID_DEFINED_SECTION2 *) InputSection)->DataOffset,\r | |
935 | SECTION2_SIZE (InputSection) - ((EFI_GUID_DEFINED_SECTION2 *) InputSection)->DataOffset,\r | |
936 | OutputBufferSize,\r | |
937 | ScratchBufferSize\r | |
938 | );\r | |
939 | } else {\r | |
940 | if (!CompareGuid (\r | |
941 | &gTianoCustomDecompressGuid,\r | |
e6c560aa | 942 | &(((EFI_GUID_DEFINED_SECTION *) InputSection)->SectionDefinitionGuid))) {\r |
30f001ca SZ |
943 | return RETURN_INVALID_PARAMETER;\r |
944 | }\r | |
945 | //\r | |
0a6f4824 | 946 | // Get guid attribute of guid section.\r |
30f001ca SZ |
947 | //\r |
948 | *SectionAttribute = ((EFI_GUID_DEFINED_SECTION *) InputSection)->Attributes;\r | |
18fd8d65 | 949 | \r |
30f001ca SZ |
950 | //\r |
951 | // Call Tiano GetInfo to get the required size info.\r | |
952 | //\r | |
953 | return UefiDecompressGetInfo (\r | |
954 | (UINT8 *) InputSection + ((EFI_GUID_DEFINED_SECTION *) InputSection)->DataOffset,\r | |
955 | SECTION_SIZE (InputSection) - ((EFI_GUID_DEFINED_SECTION *) InputSection)->DataOffset,\r | |
956 | OutputBufferSize,\r | |
957 | ScratchBufferSize\r | |
958 | );\r | |
959 | }\r | |
54bd896e | 960 | }\r |
961 | \r | |
ed7752ec | 962 | /**\r |
b4b6c8de | 963 | Decompress a Tiano compressed GUIDed section into a caller allocated output buffer.\r |
0a6f4824 LG |
964 | \r |
965 | Decodes the GUIDed section specified by InputSection.\r | |
966 | If GUID for InputSection does not match the GUID that this handler supports, then RETURN_UNSUPPORTED is returned.\r | |
b4b6c8de LG |
967 | If the data in InputSection can not be decoded, then RETURN_INVALID_PARAMETER is returned.\r |
968 | If the GUID of InputSection does match the GUID that this handler supports, then InputSection\r | |
969 | is decoded into the buffer specified by OutputBuffer and the authentication status of this\r | |
970 | decode operation is returned in AuthenticationStatus. If the decoded buffer is identical to the\r | |
971 | data in InputSection, then OutputBuffer is set to point at the data in InputSection. Otherwise,\r | |
972 | the decoded data will be placed in caller allocated buffer specified by OutputBuffer.\r | |
0a6f4824 | 973 | \r |
b4b6c8de LG |
974 | If InputSection is NULL, then ASSERT().\r |
975 | If OutputBuffer is NULL, then ASSERT().\r | |
976 | If ScratchBuffer is NULL and this decode operation requires a scratch buffer, then ASSERT().\r | |
977 | If AuthenticationStatus is NULL, then ASSERT().\r | |
978 | \r | |
979 | \r | |
980 | @param[in] InputSection A pointer to a GUIDed section of an FFS formatted file.\r | |
0a6f4824 | 981 | @param[out] OutputBuffer A pointer to a buffer that contains the result of a decode operation.\r |
b4b6c8de | 982 | @param[in] ScratchBuffer A caller allocated buffer that may be required by this function\r |
0a6f4824 LG |
983 | as a scratch buffer to perform the decode operation.\r |
984 | @param[out] AuthenticationStatus\r | |
b4b6c8de LG |
985 | A pointer to the authentication status of the decoded output buffer.\r |
986 | See the definition of authentication status in the EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI\r | |
987 | section of the PI Specification. EFI_AUTH_STATUS_PLATFORM_OVERRIDE must\r | |
988 | never be set by this handler.\r | |
989 | \r | |
990 | @retval RETURN_SUCCESS The buffer specified by InputSection was decoded.\r | |
991 | @retval RETURN_UNSUPPORTED The section specified by InputSection does not match the GUID this handler supports.\r | |
992 | @retval RETURN_INVALID_PARAMETER The section specified by InputSection can not be decoded.\r | |
ed7752ec | 993 | \r |
bcd70414 | 994 | **/\r |
54bd896e | 995 | RETURN_STATUS\r |
996 | EFIAPI\r | |
18fd8d65 LG |
997 | TianoDecompress (\r |
998 | IN CONST VOID *InputSection,\r | |
999 | OUT VOID **OutputBuffer,\r | |
1000 | IN VOID *ScratchBuffer, OPTIONAL\r | |
1001 | OUT UINT32 *AuthenticationStatus\r | |
54bd896e | 1002 | )\r |
54bd896e | 1003 | {\r |
18fd8d65 | 1004 | ASSERT (OutputBuffer != NULL);\r |
b4b6c8de | 1005 | ASSERT (InputSection != NULL);\r |
e6c560aa | 1006 | \r |
30f001ca SZ |
1007 | if (IS_SECTION2 (InputSection)) {\r |
1008 | if (!CompareGuid (\r | |
1009 | &gTianoCustomDecompressGuid,\r | |
1010 | &(((EFI_GUID_DEFINED_SECTION2 *) InputSection)->SectionDefinitionGuid))) {\r | |
1011 | return RETURN_INVALID_PARAMETER;\r | |
1012 | }\r | |
1013 | \r | |
1014 | //\r | |
1015 | // Set Authentication to Zero.\r | |
1016 | //\r | |
1017 | *AuthenticationStatus = 0;\r | |
1018 | \r | |
1019 | //\r | |
1020 | // Call Tiano Decompress to get the raw data\r | |
1021 | //\r | |
1022 | return UefiTianoDecompress (\r | |
1023 | (UINT8 *) InputSection + ((EFI_GUID_DEFINED_SECTION2 *) InputSection)->DataOffset,\r | |
1024 | *OutputBuffer,\r | |
1025 | ScratchBuffer,\r | |
1026 | 2\r | |
1027 | );\r | |
1028 | } else {\r | |
1029 | if (!CompareGuid (\r | |
1030 | &gTianoCustomDecompressGuid,\r | |
e6c560aa | 1031 | &(((EFI_GUID_DEFINED_SECTION *) InputSection)->SectionDefinitionGuid))) {\r |
30f001ca SZ |
1032 | return RETURN_INVALID_PARAMETER;\r |
1033 | }\r | |
e6c560aa | 1034 | \r |
30f001ca SZ |
1035 | //\r |
1036 | // Set Authentication to Zero.\r | |
1037 | //\r | |
1038 | *AuthenticationStatus = 0;\r | |
1039 | \r | |
1040 | //\r | |
1041 | // Call Tiano Decompress to get the raw data\r | |
1042 | //\r | |
1043 | return UefiTianoDecompress (\r | |
1044 | (UINT8 *) InputSection + ((EFI_GUID_DEFINED_SECTION *) InputSection)->DataOffset,\r | |
1045 | *OutputBuffer,\r | |
1046 | ScratchBuffer,\r | |
1047 | 2\r | |
1048 | );\r | |
1049 | }\r | |
54bd896e | 1050 | }\r |
d8c79a81 | 1051 | \r |
ed7752ec | 1052 | /**\r |
b4b6c8de | 1053 | Registers TianoDecompress and TianoDecompressGetInfo handlers with TianoCustomerDecompressGuid\r |
ed7752ec | 1054 | \r |
18fd8d65 | 1055 | @retval RETURN_SUCCESS Register successfully.\r |
ed7752ec | 1056 | @retval RETURN_OUT_OF_RESOURCES No enough memory to store this handler.\r |
d8c79a81 | 1057 | **/\r |
8bd22b8a | 1058 | RETURN_STATUS\r |
d8c79a81 | 1059 | EFIAPI\r |
18fd8d65 | 1060 | TianoDecompressLibConstructor (\r |
2344d341 | 1061 | VOID\r |
18fd8d65 | 1062 | )\r |
d8c79a81 | 1063 | {\r |
18fd8d65 LG |
1064 | return ExtractGuidedSectionRegisterHandlers (\r |
1065 | &gTianoCustomDecompressGuid,\r | |
1066 | TianoDecompressGetInfo,\r | |
1067 | TianoDecompress\r | |
30f001ca | 1068 | );\r |
6bee1632 | 1069 | }\r |