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