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