]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.c
MdePkg: Apply uncrustify changes
[mirror_edk2.git] / MdePkg / Library / BaseUefiDecompressLib / BaseUefiDecompressLib.c
... / ...
CommitLineData
1/** @file\r
2 UEFI Decompress Library implementation refer to UEFI specification.\r
3\r
4 Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
5 Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
6 SPDX-License-Identifier: BSD-2-Clause-Patent\r
7\r
8**/\r
9\r
10#include "BaseUefiDecompressLibInternals.h"\r
11\r
12/**\r
13 Read NumOfBit of bits from source into mBitBuf.\r
14\r
15 Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source.\r
16\r
17 @param Sd The global scratch data.\r
18 @param NumOfBits The number of bits to shift and read.\r
19\r
20**/\r
21VOID\r
22FillBuf (\r
23 IN SCRATCH_DATA *Sd,\r
24 IN UINT16 NumOfBits\r
25 )\r
26{\r
27 //\r
28 // Left shift NumOfBits of bits in advance\r
29 //\r
30 Sd->mBitBuf = (UINT32)LShiftU64 (((UINT64)Sd->mBitBuf), NumOfBits);\r
31\r
32 //\r
33 // Copy data needed in bytes into mSbuBitBuf\r
34 //\r
35 while (NumOfBits > Sd->mBitCount) {\r
36 NumOfBits = (UINT16)(NumOfBits - Sd->mBitCount);\r
37 Sd->mBitBuf |= (UINT32)LShiftU64 (((UINT64)Sd->mSubBitBuf), NumOfBits);\r
38\r
39 if (Sd->mCompSize > 0) {\r
40 //\r
41 // Get 1 byte into SubBitBuf\r
42 //\r
43 Sd->mCompSize--;\r
44 Sd->mSubBitBuf = Sd->mSrcBase[Sd->mInBuf++];\r
45 Sd->mBitCount = 8;\r
46 } else {\r
47 //\r
48 // No more bits from the source, just pad zero bit.\r
49 //\r
50 Sd->mSubBitBuf = 0;\r
51 Sd->mBitCount = 8;\r
52 }\r
53 }\r
54\r
55 //\r
56 // Calculate additional bit count read to update mBitCount\r
57 //\r
58 Sd->mBitCount = (UINT16)(Sd->mBitCount - NumOfBits);\r
59\r
60 //\r
61 // Copy NumOfBits of bits from mSubBitBuf into mBitBuf\r
62 //\r
63 Sd->mBitBuf |= Sd->mSubBitBuf >> Sd->mBitCount;\r
64}\r
65\r
66/**\r
67 Get NumOfBits of bits out from mBitBuf.\r
68\r
69 Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent\r
70 NumOfBits of bits from source. Returns NumOfBits of bits that are\r
71 popped out.\r
72\r
73 @param Sd The global scratch data.\r
74 @param NumOfBits The number of bits to pop and read.\r
75\r
76 @return The bits that are popped out.\r
77\r
78**/\r
79UINT32\r
80GetBits (\r
81 IN SCRATCH_DATA *Sd,\r
82 IN UINT16 NumOfBits\r
83 )\r
84{\r
85 UINT32 OutBits;\r
86\r
87 //\r
88 // Pop NumOfBits of Bits from Left\r
89 //\r
90 OutBits = (UINT32)(Sd->mBitBuf >> (BITBUFSIZ - NumOfBits));\r
91\r
92 //\r
93 // Fill up mBitBuf from source\r
94 //\r
95 FillBuf (Sd, NumOfBits);\r
96\r
97 return OutBits;\r
98}\r
99\r
100/**\r
101 Creates Huffman Code mapping table according to code length array.\r
102\r
103 Creates Huffman Code mapping table for Extra Set, Char&Len Set\r
104 and Position Set according to code length array.\r
105 If TableBits > 16, then ASSERT ().\r
106\r
107 @param Sd The global scratch data.\r
108 @param NumOfChar The number of symbols in the symbol set.\r
109 @param BitLen Code length array.\r
110 @param TableBits The width of the mapping table.\r
111 @param Table The table to be created.\r
112\r
113 @retval 0 OK.\r
114 @retval BAD_TABLE The table is corrupted.\r
115\r
116**/\r
117UINT16\r
118MakeTable (\r
119 IN SCRATCH_DATA *Sd,\r
120 IN UINT16 NumOfChar,\r
121 IN UINT8 *BitLen,\r
122 IN UINT16 TableBits,\r
123 OUT UINT16 *Table\r
124 )\r
125{\r
126 UINT16 Count[17];\r
127 UINT16 Weight[17];\r
128 UINT16 Start[18];\r
129 UINT16 *Pointer;\r
130 UINT16 Index3;\r
131 UINT16 Index;\r
132 UINT16 Len;\r
133 UINT16 Char;\r
134 UINT16 JuBits;\r
135 UINT16 Avail;\r
136 UINT16 NextCode;\r
137 UINT16 Mask;\r
138 UINT16 WordOfStart;\r
139 UINT16 WordOfCount;\r
140 UINT16 MaxTableLength;\r
141\r
142 //\r
143 // The maximum mapping table width supported by this internal\r
144 // working function is 16.\r
145 //\r
146 ASSERT (TableBits <= 16);\r
147\r
148 for (Index = 0; Index <= 16; Index++) {\r
149 Count[Index] = 0;\r
150 }\r
151\r
152 for (Index = 0; Index < NumOfChar; Index++) {\r
153 if (BitLen[Index] > 16) {\r
154 return (UINT16)BAD_TABLE;\r
155 }\r
156\r
157 Count[BitLen[Index]]++;\r
158 }\r
159\r
160 Start[0] = 0;\r
161 Start[1] = 0;\r
162\r
163 for (Index = 1; Index <= 16; Index++) {\r
164 WordOfStart = Start[Index];\r
165 WordOfCount = Count[Index];\r
166 Start[Index + 1] = (UINT16)(WordOfStart + (WordOfCount << (16 - Index)));\r
167 }\r
168\r
169 if (Start[17] != 0) {\r
170 /*(1U << 16)*/\r
171 return (UINT16)BAD_TABLE;\r
172 }\r
173\r
174 JuBits = (UINT16)(16 - TableBits);\r
175\r
176 Weight[0] = 0;\r
177 for (Index = 1; Index <= TableBits; Index++) {\r
178 Start[Index] >>= JuBits;\r
179 Weight[Index] = (UINT16)(1U << (TableBits - Index));\r
180 }\r
181\r
182 while (Index <= 16) {\r
183 Weight[Index] = (UINT16)(1U << (16 - Index));\r
184 Index++;\r
185 }\r
186\r
187 Index = (UINT16)(Start[TableBits + 1] >> JuBits);\r
188\r
189 if (Index != 0) {\r
190 Index3 = (UINT16)(1U << TableBits);\r
191 if (Index < Index3) {\r
192 SetMem16 (Table + Index, (Index3 - Index) * sizeof (*Table), 0);\r
193 }\r
194 }\r
195\r
196 Avail = NumOfChar;\r
197 Mask = (UINT16)(1U << (15 - TableBits));\r
198 MaxTableLength = (UINT16)(1U << TableBits);\r
199\r
200 for (Char = 0; Char < NumOfChar; Char++) {\r
201 Len = BitLen[Char];\r
202 if ((Len == 0) || (Len >= 17)) {\r
203 continue;\r
204 }\r
205\r
206 NextCode = (UINT16)(Start[Len] + Weight[Len]);\r
207\r
208 if (Len <= TableBits) {\r
209 if ((Start[Len] >= NextCode) || (NextCode > MaxTableLength)) {\r
210 return (UINT16)BAD_TABLE;\r
211 }\r
212\r
213 for (Index = Start[Len]; Index < NextCode; Index++) {\r
214 Table[Index] = Char;\r
215 }\r
216 } else {\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
222 if ((*Pointer == 0) && (Avail < (2 * NC - 1))) {\r
223 Sd->mRight[Avail] = Sd->mLeft[Avail] = 0;\r
224 *Pointer = Avail++;\r
225 }\r
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
233 }\r
234\r
235 Index3 <<= 1;\r
236 Index--;\r
237 }\r
238\r
239 *Pointer = Char;\r
240 }\r
241\r
242 Start[Len] = NextCode;\r
243 }\r
244\r
245 //\r
246 // Succeeds\r
247 //\r
248 return 0;\r
249}\r
250\r
251/**\r
252 Decodes a position value.\r
253\r
254 Get a position value according to Position Huffman Table.\r
255\r
256 @param Sd The global scratch data.\r
257\r
258 @return The position value decoded.\r
259\r
260**/\r
261UINT32\r
262DecodeP (\r
263 IN SCRATCH_DATA *Sd\r
264 )\r
265{\r
266 UINT16 Val;\r
267 UINT32 Mask;\r
268 UINT32 Pos;\r
269\r
270 Val = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];\r
271\r
272 if (Val >= MAXNP) {\r
273 Mask = 1U << (BITBUFSIZ - 1 - 8);\r
274\r
275 do {\r
276 if ((Sd->mBitBuf & Mask) != 0) {\r
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 //\r
287 // Advance what we have read\r
288 //\r
289 FillBuf (Sd, Sd->mPTLen[Val]);\r
290\r
291 Pos = Val;\r
292 if (Val > 1) {\r
293 Pos = (UINT32)((1U << (Val - 1)) + GetBits (Sd, (UINT16)(Val - 1)));\r
294 }\r
295\r
296 return Pos;\r
297}\r
298\r
299/**\r
300 Reads code lengths for the Extra Set or the Position Set.\r
301\r
302 Read in the Extra Set or Position Set Length Array, then\r
303 generate the Huffman code mapping for them.\r
304\r
305 @param Sd The global scratch data.\r
306 @param nn The number of symbols.\r
307 @param nbit The number of bits needed to represent nn.\r
308 @param Special The special symbol that needs to be taken care of.\r
309\r
310 @retval 0 OK.\r
311 @retval BAD_TABLE Table is corrupted.\r
312\r
313**/\r
314UINT16\r
315ReadPTLen (\r
316 IN SCRATCH_DATA *Sd,\r
317 IN UINT16 nn,\r
318 IN UINT16 nbit,\r
319 IN UINT16 Special\r
320 )\r
321{\r
322 UINT16 Number;\r
323 UINT16 CharC;\r
324 UINT16 Index;\r
325 UINT32 Mask;\r
326\r
327 ASSERT (nn <= NPT);\r
328 //\r
329 // Read Extra Set Code Length Array size\r
330 //\r
331 Number = (UINT16)GetBits (Sd, nbit);\r
332\r
333 if (Number == 0) {\r
334 //\r
335 // This represents only Huffman code used\r
336 //\r
337 CharC = (UINT16)GetBits (Sd, nbit);\r
338\r
339 SetMem16 (&Sd->mPTTable[0], sizeof (Sd->mPTTable), CharC);\r
340\r
341 SetMem (Sd->mPTLen, nn, 0);\r
342\r
343 return 0;\r
344 }\r
345\r
346 Index = 0;\r
347\r
348 while (Index < Number && Index < NPT) {\r
349 CharC = (UINT16)(Sd->mBitBuf >> (BITBUFSIZ - 3));\r
350\r
351 //\r
352 // If a code length is less than 7, then it is encoded as a 3-bit\r
353 // value. Or it is encoded as a series of "1"s followed by a\r
354 // terminating "0". The number of "1"s = Code length - 4.\r
355 //\r
356 if (CharC == 7) {\r
357 Mask = 1U << (BITBUFSIZ - 1 - 3);\r
358 while (Mask & Sd->mBitBuf) {\r
359 Mask >>= 1;\r
360 CharC += 1;\r
361 }\r
362 }\r
363\r
364 FillBuf (Sd, (UINT16)((CharC < 7) ? 3 : CharC - 3));\r
365\r
366 Sd->mPTLen[Index++] = (UINT8)CharC;\r
367\r
368 //\r
369 // For Code&Len Set,\r
370 // After the third length of the code length concatenation,\r
371 // a 2-bit value is used to indicated the number of consecutive\r
372 // zero lengths after the third length.\r
373 //\r
374 if (Index == Special) {\r
375 CharC = (UINT16)GetBits (Sd, 2);\r
376 while ((INT16)(--CharC) >= 0 && Index < NPT) {\r
377 Sd->mPTLen[Index++] = 0;\r
378 }\r
379 }\r
380 }\r
381\r
382 while (Index < nn && Index < NPT) {\r
383 Sd->mPTLen[Index++] = 0;\r
384 }\r
385\r
386 return MakeTable (Sd, nn, Sd->mPTLen, 8, Sd->mPTTable);\r
387}\r
388\r
389/**\r
390 Reads code lengths for Char&Len Set.\r
391\r
392 Read in and decode the Char&Len Set Code Length Array, then\r
393 generate the Huffman Code mapping table for the Char&Len Set.\r
394\r
395 @param Sd The global scratch data.\r
396\r
397**/\r
398VOID\r
399ReadCLen (\r
400 SCRATCH_DATA *Sd\r
401 )\r
402{\r
403 UINT16 Number;\r
404 UINT16 CharC;\r
405 UINT16 Index;\r
406 UINT32 Mask;\r
407\r
408 Number = (UINT16)GetBits (Sd, CBIT);\r
409\r
410 if (Number == 0) {\r
411 //\r
412 // This represents only Huffman code used\r
413 //\r
414 CharC = (UINT16)GetBits (Sd, CBIT);\r
415\r
416 SetMem (Sd->mCLen, NC, 0);\r
417 SetMem16 (&Sd->mCTable[0], sizeof (Sd->mCTable), CharC);\r
418\r
419 return;\r
420 }\r
421\r
422 Index = 0;\r
423 while (Index < Number && Index < NC) {\r
424 CharC = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];\r
425 if (CharC >= NT) {\r
426 Mask = 1U << (BITBUFSIZ - 1 - 8);\r
427\r
428 do {\r
429 if (Mask & Sd->mBitBuf) {\r
430 CharC = Sd->mRight[CharC];\r
431 } else {\r
432 CharC = Sd->mLeft[CharC];\r
433 }\r
434\r
435 Mask >>= 1;\r
436 } while (CharC >= NT);\r
437 }\r
438\r
439 //\r
440 // Advance what we have read\r
441 //\r
442 FillBuf (Sd, Sd->mPTLen[CharC]);\r
443\r
444 if (CharC <= 2) {\r
445 if (CharC == 0) {\r
446 CharC = 1;\r
447 } else if (CharC == 1) {\r
448 CharC = (UINT16)(GetBits (Sd, 4) + 3);\r
449 } else if (CharC == 2) {\r
450 CharC = (UINT16)(GetBits (Sd, CBIT) + 20);\r
451 }\r
452\r
453 while ((INT16)(--CharC) >= 0 && Index < NC) {\r
454 Sd->mCLen[Index++] = 0;\r
455 }\r
456 } else {\r
457 Sd->mCLen[Index++] = (UINT8)(CharC - 2);\r
458 }\r
459 }\r
460\r
461 SetMem (Sd->mCLen + Index, NC - Index, 0);\r
462\r
463 MakeTable (Sd, NC, Sd->mCLen, 12, Sd->mCTable);\r
464\r
465 return;\r
466}\r
467\r
468/**\r
469 Decode a character/length value.\r
470\r
471 Read one value from mBitBuf, Get one code from mBitBuf. If it is at block boundary, generates\r
472 Huffman code mapping table for Extra Set, Code&Len Set and\r
473 Position Set.\r
474\r
475 @param Sd The global scratch data.\r
476\r
477 @return The value decoded.\r
478\r
479**/\r
480UINT16\r
481DecodeC (\r
482 SCRATCH_DATA *Sd\r
483 )\r
484{\r
485 UINT16 Index2;\r
486 UINT32 Mask;\r
487\r
488 if (Sd->mBlockSize == 0) {\r
489 //\r
490 // Starting a new block\r
491 // Read BlockSize from block header\r
492 //\r
493 Sd->mBlockSize = (UINT16)GetBits (Sd, 16);\r
494\r
495 //\r
496 // Read in the Extra Set Code Length Array,\r
497 // Generate the Huffman code mapping table for Extra Set.\r
498 //\r
499 Sd->mBadTableFlag = ReadPTLen (Sd, NT, TBIT, 3);\r
500 if (Sd->mBadTableFlag != 0) {\r
501 return 0;\r
502 }\r
503\r
504 //\r
505 // Read in and decode the Char&Len Set Code Length Array,\r
506 // Generate the Huffman code mapping table for Char&Len Set.\r
507 //\r
508 ReadCLen (Sd);\r
509\r
510 //\r
511 // Read in the Position Set Code Length Array,\r
512 // Generate the Huffman code mapping table for the Position Set.\r
513 //\r
514 Sd->mBadTableFlag = ReadPTLen (Sd, MAXNP, Sd->mPBit, (UINT16)(-1));\r
515 if (Sd->mBadTableFlag != 0) {\r
516 return 0;\r
517 }\r
518 }\r
519\r
520 //\r
521 // Get one code according to Code&Set Huffman Table\r
522 //\r
523 Sd->mBlockSize--;\r
524 Index2 = Sd->mCTable[Sd->mBitBuf >> (BITBUFSIZ - 12)];\r
525\r
526 if (Index2 >= NC) {\r
527 Mask = 1U << (BITBUFSIZ - 1 - 12);\r
528\r
529 do {\r
530 if ((Sd->mBitBuf & Mask) != 0) {\r
531 Index2 = Sd->mRight[Index2];\r
532 } else {\r
533 Index2 = Sd->mLeft[Index2];\r
534 }\r
535\r
536 Mask >>= 1;\r
537 } while (Index2 >= NC);\r
538 }\r
539\r
540 //\r
541 // Advance what we have read\r
542 //\r
543 FillBuf (Sd, Sd->mCLen[Index2]);\r
544\r
545 return Index2;\r
546}\r
547\r
548/**\r
549 Decode the source data and put the resulting data into the destination buffer.\r
550\r
551 @param Sd The global scratch data.\r
552\r
553**/\r
554VOID\r
555Decode (\r
556 SCRATCH_DATA *Sd\r
557 )\r
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
568 //\r
569 // Get one code from mBitBuf\r
570 //\r
571 CharC = DecodeC (Sd);\r
572 if (Sd->mBadTableFlag != 0) {\r
573 goto Done;\r
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
581 goto Done;\r
582 } else {\r
583 //\r
584 // Write orignal character into mDstBase\r
585 //\r
586 Sd->mDstBase[Sd->mOutBuf++] = (UINT8)CharC;\r
587 }\r
588 } else {\r
589 //\r
590 // Process a Pointer\r
591 //\r
592 CharC = (UINT16)(CharC - (BIT8 - THRESHOLD));\r
593\r
594 //\r
595 // Get string length\r
596 //\r
597 BytesRemain = CharC;\r
598\r
599 //\r
600 // Locate string position\r
601 //\r
602 DataIdx = Sd->mOutBuf - DecodeP (Sd) - 1;\r
603\r
604 //\r
605 // Write BytesRemain of bytes into mDstBase\r
606 //\r
607 BytesRemain--;\r
608\r
609 while ((INT16)(BytesRemain) >= 0) {\r
610 if (Sd->mOutBuf >= Sd->mOrigSize) {\r
611 goto Done;\r
612 }\r
613\r
614 if (DataIdx >= Sd->mOrigSize) {\r
615 Sd->mBadTableFlag = (UINT16)BAD_TABLE;\r
616 goto Done;\r
617 }\r
618\r
619 Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];\r
620\r
621 BytesRemain--;\r
622 }\r
623\r
624 //\r
625 // Once mOutBuf is fully filled, directly return\r
626 //\r
627 if (Sd->mOutBuf >= Sd->mOrigSize) {\r
628 goto Done;\r
629 }\r
630 }\r
631 }\r
632\r
633Done:\r
634 return;\r
635}\r
636\r
637/**\r
638 Given a compressed source buffer, this function retrieves the size of\r
639 the uncompressed buffer and the size of the scratch buffer required\r
640 to decompress the compressed source buffer.\r
641\r
642 Retrieves the size of the uncompressed buffer and the temporary scratch buffer\r
643 required to decompress the buffer specified by Source and SourceSize.\r
644 If the size of the uncompressed buffer or the size of the scratch buffer cannot\r
645 be determined from the compressed data specified by Source and SourceData,\r
646 then RETURN_INVALID_PARAMETER is returned. Otherwise, the size of the uncompressed\r
647 buffer is returned in DestinationSize, the size of the scratch buffer is returned\r
648 in ScratchSize, and RETURN_SUCCESS is returned.\r
649 This function does not have scratch buffer available to perform a thorough\r
650 checking of the validity of the source data. It just retrieves the "Original Size"\r
651 field from the beginning bytes of the source data and output it as DestinationSize.\r
652 And ScratchSize is specific to the decompression implementation.\r
653\r
654 If Source is NULL, then ASSERT().\r
655 If DestinationSize is NULL, then ASSERT().\r
656 If ScratchSize is NULL, then ASSERT().\r
657\r
658 @param Source The source buffer containing the compressed data.\r
659 @param SourceSize The size, in bytes, of the source buffer.\r
660 @param DestinationSize A pointer to the size, in bytes, of the uncompressed buffer\r
661 that will be generated when the compressed buffer specified\r
662 by Source and SourceSize is decompressed.\r
663 @param ScratchSize A pointer to the size, in bytes, of the scratch buffer that\r
664 is required to decompress the compressed buffer specified\r
665 by Source and SourceSize.\r
666\r
667 @retval RETURN_SUCCESS The size of the uncompressed data was returned\r
668 in DestinationSize, and the size of the scratch\r
669 buffer was returned in ScratchSize.\r
670 @retval RETURN_INVALID_PARAMETER\r
671 The size of the uncompressed data or the size of\r
672 the scratch buffer cannot be determined from\r
673 the compressed data specified by Source\r
674 and SourceSize.\r
675**/\r
676RETURN_STATUS\r
677EFIAPI\r
678UefiDecompressGetInfo (\r
679 IN CONST VOID *Source,\r
680 IN UINT32 SourceSize,\r
681 OUT UINT32 *DestinationSize,\r
682 OUT UINT32 *ScratchSize\r
683 )\r
684{\r
685 UINT32 CompressedSize;\r
686\r
687 ASSERT (Source != NULL);\r
688 ASSERT (DestinationSize != NULL);\r
689 ASSERT (ScratchSize != NULL);\r
690\r
691 if (SourceSize < 8) {\r
692 return RETURN_INVALID_PARAMETER;\r
693 }\r
694\r
695 CompressedSize = ReadUnaligned32 ((UINT32 *)Source);\r
696 if ((SourceSize < (CompressedSize + 8)) || ((CompressedSize + 8) < 8)) {\r
697 return RETURN_INVALID_PARAMETER;\r
698 }\r
699\r
700 *ScratchSize = sizeof (SCRATCH_DATA);\r
701 *DestinationSize = ReadUnaligned32 ((UINT32 *)Source + 1);\r
702\r
703 return RETURN_SUCCESS;\r
704}\r
705\r
706/**\r
707 Decompresses a compressed source buffer.\r
708\r
709 Extracts decompressed data to its original form.\r
710 This function is designed so that the decompression algorithm can be implemented\r
711 without using any memory services. As a result, this function is not allowed to\r
712 call any memory allocation services in its implementation. It is the caller's\r
713 responsibility to allocate and free the Destination and Scratch buffers.\r
714 If the compressed source data specified by Source is successfully decompressed\r
715 into Destination, then RETURN_SUCCESS is returned. If the compressed source data\r
716 specified by Source is not in a valid compressed data format,\r
717 then RETURN_INVALID_PARAMETER is returned.\r
718\r
719 If Source is NULL, then ASSERT().\r
720 If Destination is NULL, then ASSERT().\r
721 If the required scratch buffer size > 0 and Scratch is NULL, then ASSERT().\r
722 If the Version is not 1 or 2, then ASSERT().\r
723\r
724 @param Source The source buffer containing the compressed data.\r
725 @param Destination The destination buffer to store the decompressed data.\r
726 @param Scratch A temporary scratch buffer that is used to perform the decompression.\r
727 This is an optional parameter that may be NULL if the\r
728 required scratch buffer size is 0.\r
729 @param Version 1 for UEFI Decompress algoruthm, 2 for Tiano Decompess algorithm.\r
730\r
731 @retval RETURN_SUCCESS Decompression completed successfully, and\r
732 the uncompressed buffer is returned in Destination.\r
733 @retval RETURN_INVALID_PARAMETER\r
734 The source buffer specified by Source is corrupted\r
735 (not in a valid compressed format).\r
736**/\r
737RETURN_STATUS\r
738UefiTianoDecompress (\r
739 IN CONST VOID *Source,\r
740 IN OUT VOID *Destination,\r
741 IN OUT VOID *Scratch,\r
742 IN UINT32 Version\r
743 )\r
744{\r
745 UINT32 CompSize;\r
746 UINT32 OrigSize;\r
747 SCRATCH_DATA *Sd;\r
748 CONST UINT8 *Src;\r
749 UINT8 *Dst;\r
750\r
751 ASSERT (Source != NULL);\r
752 ASSERT (Destination != NULL);\r
753 ASSERT (Scratch != NULL);\r
754 ASSERT (Version == 1 || Version == 2);\r
755\r
756 Src = Source;\r
757 Dst = Destination;\r
758\r
759 Sd = (SCRATCH_DATA *)Scratch;\r
760\r
761 CompSize = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);\r
762 OrigSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);\r
763\r
764 //\r
765 // If compressed file size is 0, return\r
766 //\r
767 if (OrigSize == 0) {\r
768 return RETURN_SUCCESS;\r
769 }\r
770\r
771 Src = Src + 8;\r
772 SetMem (Sd, sizeof (SCRATCH_DATA), 0);\r
773\r
774 //\r
775 // The length of the field 'Position Set Code Length Array Size' in Block Header.\r
776 // For UEFI 2.0 de/compression algorithm(Version 1), mPBit = 4\r
777 // For Tiano de/compression algorithm(Version 2), mPBit = 5\r
778 //\r
779 switch (Version) {\r
780 case 1:\r
781 Sd->mPBit = 4;\r
782 break;\r
783 case 2:\r
784 Sd->mPBit = 5;\r
785 break;\r
786 default:\r
787 ASSERT (FALSE);\r
788 }\r
789\r
790 Sd->mSrcBase = (UINT8 *)Src;\r
791 Sd->mDstBase = Dst;\r
792 //\r
793 // CompSize and OrigSize are calculated in bytes\r
794 //\r
795 Sd->mCompSize = CompSize;\r
796 Sd->mOrigSize = OrigSize;\r
797\r
798 //\r
799 // Fill the first BITBUFSIZ bits\r
800 //\r
801 FillBuf (Sd, BITBUFSIZ);\r
802\r
803 //\r
804 // Decompress it\r
805 //\r
806 Decode (Sd);\r
807\r
808 if (Sd->mBadTableFlag != 0) {\r
809 //\r
810 // Something wrong with the source\r
811 //\r
812 return RETURN_INVALID_PARAMETER;\r
813 }\r
814\r
815 return RETURN_SUCCESS;\r
816}\r
817\r
818/**\r
819 Decompresses a UEFI compressed source buffer.\r
820\r
821 Extracts decompressed data to its original form.\r
822 This function is designed so that the decompression algorithm can be implemented\r
823 without using any memory services. As a result, this function is not allowed to\r
824 call any memory allocation services in its implementation. It is the caller's\r
825 responsibility to allocate and free the Destination and Scratch buffers.\r
826 If the compressed source data specified by Source is successfully decompressed\r
827 into Destination, then RETURN_SUCCESS is returned. If the compressed source data\r
828 specified by Source is not in a valid compressed data format,\r
829 then RETURN_INVALID_PARAMETER is returned.\r
830\r
831 If Source is NULL, then ASSERT().\r
832 If Destination is NULL, then ASSERT().\r
833 If the required scratch buffer size > 0 and Scratch is NULL, then ASSERT().\r
834\r
835 @param Source The source buffer containing the compressed data.\r
836 @param Destination The destination buffer to store the decompressed data\r
837 @param Scratch A temporary scratch buffer that is used to perform the decompression.\r
838 This is an optional parameter that may be NULL if the\r
839 required scratch buffer size is 0.\r
840\r
841 @retval RETURN_SUCCESS Decompression completed successfully, and\r
842 the uncompressed buffer is returned in Destination.\r
843 @retval RETURN_INVALID_PARAMETER\r
844 The source buffer specified by Source is corrupted\r
845 (not in a valid compressed format).\r
846**/\r
847RETURN_STATUS\r
848EFIAPI\r
849UefiDecompress (\r
850 IN CONST VOID *Source,\r
851 IN OUT VOID *Destination,\r
852 IN OUT VOID *Scratch OPTIONAL\r
853 )\r
854{\r
855 return UefiTianoDecompress (Source, Destination, Scratch, 1);\r
856}\r