]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.c
Cleanup MdePkg.dsc, UefiLib.inf and UefiLib.msa
[mirror_edk2.git] / MdePkg / Library / BaseUefiDecompressLib / BaseUefiDecompressLib.c
CommitLineData
e1f414b6 1/** @file\r
2 UEFI Decompress Library.\r
3\r
4 Copyright (c) 2006, Intel Corporation\r
5 All rights reserved. This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13 Module Name: UefiDecompressLib.c\r
14\r
15**/\r
16\r
17//\r
18// Include common header file for this module.\r
19//\r
20#include "CommonHeader.h"\r
21\r
22#include "BaseUefiDecompressLibInternals.h"\r
23\r
24/**\r
25 Read NumOfBit of bits from source into mBitBuf\r
26\r
27 Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source.\r
28\r
29 @param Sd The global scratch data\r
30 @param NumOfBits The number of bits to shift and read.\r
31\r
32**/\r
33VOID\r
34FillBuf (\r
35 IN SCRATCH_DATA *Sd,\r
36 IN UINT16 NumOfBits\r
37 )\r
38{\r
39 //\r
40 // Left shift NumOfBits of bits in advance\r
41 //\r
42 Sd->mBitBuf = (UINT32) (Sd->mBitBuf << NumOfBits);\r
43\r
44 //\r
45 // Copy data needed in bytes into mSbuBitBuf\r
46 //\r
47 while (NumOfBits > Sd->mBitCount) {\r
48\r
49 Sd->mBitBuf |= (UINT32) (Sd->mSubBitBuf << (NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount)));\r
50\r
51 if (Sd->mCompSize > 0) {\r
52 //\r
53 // Get 1 byte into SubBitBuf\r
54 //\r
55 Sd->mCompSize--;\r
56 Sd->mSubBitBuf = Sd->mSrcBase[Sd->mInBuf++];\r
57 Sd->mBitCount = 8;\r
58\r
59 } else {\r
60 //\r
61 // No more bits from the source, just pad zero bit.\r
62 //\r
63 Sd->mSubBitBuf = 0;\r
64 Sd->mBitCount = 8;\r
65\r
66 }\r
67 }\r
68\r
69 //\r
70 // Caculate additional bit count read to update mBitCount\r
71 //\r
72 Sd->mBitCount = (UINT16) (Sd->mBitCount - NumOfBits);\r
73 \r
74 //\r
75 // Copy NumOfBits of bits from mSubBitBuf into mBitBuf\r
76 //\r
77 Sd->mBitBuf |= Sd->mSubBitBuf >> Sd->mBitCount;\r
78}\r
79\r
80/**\r
81 Get NumOfBits of bits out from mBitBuf\r
82\r
83 Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent \r
84 NumOfBits of bits from source. Returns NumOfBits of bits that are \r
85 popped out.\r
86\r
87 @param Sd The global scratch data.\r
88 @param NumOfBits The number of bits to pop and read.\r
89\r
90 @return The bits that are popped out.\r
91\r
92**/\r
93UINT32\r
94GetBits (\r
95 IN SCRATCH_DATA *Sd,\r
96 IN UINT16 NumOfBits\r
97 )\r
98{\r
99 UINT32 OutBits;\r
100\r
101 //\r
102 // Pop NumOfBits of Bits from Left\r
103 // \r
104 OutBits = (UINT32) (Sd->mBitBuf >> (BITBUFSIZ - NumOfBits));\r
105\r
106 //\r
107 // Fill up mBitBuf from source\r
108 //\r
109 FillBuf (Sd, NumOfBits);\r
110\r
111 return OutBits;\r
112}\r
113\r
114/**\r
115 Creates Huffman Code mapping table according to code length array.\r
116\r
117 Creates Huffman Code mapping table for Extra Set, Char&Len Set \r
118 and Position Set according to code length array.\r
119\r
120 @param Sd The global scratch data\r
121 @param NumOfChar Number of symbols in the symbol set\r
122 @param BitLen Code length array\r
123 @param TableBits The width of the mapping table\r
124 @param Table The table\r
125\r
126 @retval 0 OK.\r
127 @retval BAD_TABLE The table is corrupted.\r
128\r
129**/\r
130UINT16\r
131MakeTable (\r
132 IN SCRATCH_DATA *Sd,\r
133 IN UINT16 NumOfChar,\r
134 IN UINT8 *BitLen,\r
135 IN UINT16 TableBits,\r
136 OUT UINT16 *Table\r
137 )\r
138{\r
139 UINT16 Count[17];\r
140 UINT16 Weight[17];\r
141 UINT16 Start[18];\r
142 UINT16 *Pointer;\r
143 UINT16 Index3;\r
144 volatile UINT16 Index;\r
145 UINT16 Len;\r
146 UINT16 Char;\r
147 UINT16 JuBits;\r
148 UINT16 Avail;\r
149 UINT16 NextCode;\r
150 UINT16 Mask;\r
151 UINT16 WordOfStart;\r
152 UINT16 WordOfCount;\r
153\r
154\r
155 for (Index = 1; Index <= 16; Index++) {\r
156 Count[Index] = 0;\r
157 }\r
158\r
159 for (Index = 0; Index < NumOfChar; Index++) {\r
160 Count[BitLen[Index]]++;\r
161 }\r
162\r
163 Start[1] = 0;\r
164\r
165 for (Index = 1; Index <= 16; Index++) {\r
166 WordOfStart = Start[Index];\r
167 WordOfCount = Count[Index];\r
168 Start[Index + 1] = (UINT16) (WordOfStart + (WordOfCount << (16 - Index)));\r
169 }\r
170\r
171 if (Start[17] != 0) {\r
172 /*(1U << 16)*/\r
173 return (UINT16) BAD_TABLE;\r
174 }\r
175\r
176 JuBits = (UINT16) (16 - TableBits);\r
177\r
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
185 Index++; \r
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
192 while (Index != Index3) {\r
193 Table[Index++] = 0;\r
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
203 if (Len == 0) {\r
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
222 if (*Pointer == 0) {\r
223 Sd->mRight[Avail] = Sd->mLeft[Avail] = 0;\r
224 *Pointer = Avail++;\r
225 }\r
226\r
227 if (Index3 & Mask) {\r
228 Pointer = &Sd->mRight[*Pointer];\r
229 } else {\r
230 Pointer = &Sd->mLeft[*Pointer];\r
231 }\r
232\r
233 Index3 <<= 1;\r
234 Index--;\r
235 }\r
236\r
237 *Pointer = Char;\r
238\r
239 }\r
240\r
241 Start[Len] = NextCode;\r
242 }\r
243 //\r
244 // Succeeds\r
245 //\r
246 return 0;\r
247}\r
248\r
249/**\r
250 Decodes a position value.\r
251\r
252 Get a position value according to Position Huffman Table.\r
253 \r
254 @param Sd the global scratch data\r
255\r
256 @return The position value decoded.\r
257\r
258**/\r
259UINT32\r
260DecodeP (\r
261 IN SCRATCH_DATA *Sd\r
262 )\r
263{\r
264 UINT16 Val;\r
265 UINT32 Mask;\r
266 UINT32 Pos;\r
267\r
268 Val = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];\r
269\r
270 if (Val >= MAXNP) {\r
271 Mask = 1U << (BITBUFSIZ - 1 - 8);\r
272\r
273 do {\r
274\r
275 if (Sd->mBitBuf & Mask) {\r
276 Val = Sd->mRight[Val];\r
277 } else {\r
278 Val = Sd->mLeft[Val];\r
279 }\r
280\r
281 Mask >>= 1;\r
282 } while (Val >= MAXNP);\r
283 }\r
284 //\r
285 // Advance what we have read\r
286 //\r
287 FillBuf (Sd, Sd->mPTLen[Val]);\r
288\r
289 Pos = Val;\r
290 if (Val > 1) {\r
291 Pos = (UINT32) ((1U << (Val - 1)) + GetBits (Sd, (UINT16) (Val - 1)));\r
292 }\r
293\r
294 return Pos;\r
295}\r
296\r
297/**\r
298 Reads code lengths for the Extra Set or the Position Set.\r
299\r
300 Read in the Extra Set or Pointion Set Length Arrary, then\r
301 generate the Huffman code mapping for them.\r
302\r
303 @param Sd The global scratch data.\r
304 @param nn Number of symbols.\r
305 @param nbit Number of bits needed to represent nn.\r
306 @param Special The special symbol that needs to be taken care of.\r
307\r
308 @retval 0 OK.\r
309 @retval BAD_TABLE Table is corrupted.\r
310\r
311**/\r
312UINT16\r
313ReadPTLen (\r
314 IN SCRATCH_DATA *Sd,\r
315 IN UINT16 nn,\r
316 IN UINT16 nbit,\r
317 IN UINT16 Special\r
318 )\r
319{\r
320 UINT16 Number;\r
321 UINT16 CharC;\r
322 volatile UINT16 Index;\r
323 UINT32 Mask;\r
324\r
325 //\r
326 // Read Extra Set Code Length Array size \r
327 //\r
328 Number = (UINT16) GetBits (Sd, nbit);\r
329\r
330 if (Number == 0) {\r
331 //\r
332 // This represents only Huffman code used\r
333 //\r
334 CharC = (UINT16) GetBits (Sd, nbit);\r
335\r
336 for (Index = 0; Index < 256; Index++) {\r
337 Sd->mPTTable[Index] = CharC;\r
338 }\r
339\r
340 for (Index = 0; Index < nn; Index++) {\r
341 Sd->mPTLen[Index] = 0;\r
342 }\r
343\r
344 return 0;\r
345 }\r
346\r
347 Index = 0;\r
348\r
349 while (Index < Number) {\r
350\r
351 CharC = (UINT16) (Sd->mBitBuf >> (BITBUFSIZ - 3));\r
352\r
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
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
365 \r
366 FillBuf (Sd, (UINT16) ((CharC < 7) ? 3 : CharC - 3));\r
367\r
368 Sd->mPTLen[Index++] = (UINT8) CharC;\r
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
376 if (Index == Special) {\r
377 CharC = (UINT16) GetBits (Sd, 2);\r
378 while ((INT16) (--CharC) >= 0) {\r
379 Sd->mPTLen[Index++] = 0;\r
380 }\r
381 }\r
382 }\r
383\r
384 while (Index < nn) {\r
385 Sd->mPTLen[Index++] = 0;\r
386 }\r
387 \r
388 return MakeTable (Sd, nn, Sd->mPTLen, 8, Sd->mPTTable);\r
389}\r
390\r
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
400VOID\r
401ReadCLen (\r
402 SCRATCH_DATA *Sd\r
403 )\r
404{\r
405 UINT16 Number;\r
406 UINT16 CharC;\r
407 volatile UINT16 Index;\r
408 UINT32 Mask;\r
409\r
410 Number = (UINT16) GetBits (Sd, CBIT);\r
411\r
412 if (Number == 0) {\r
413 //\r
414 // This represents only Huffman code used\r
415 //\r
416 CharC = (UINT16) GetBits (Sd, CBIT);\r
417\r
418 for (Index = 0; Index < NC; Index++) {\r
419 Sd->mCLen[Index] = 0;\r
420 }\r
421\r
422 for (Index = 0; Index < 4096; Index++) {\r
423 Sd->mCTable[Index] = CharC;\r
424 }\r
425\r
426 return ;\r
427 }\r
428\r
429 Index = 0;\r
430 while (Index < Number) {\r
431 CharC = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];\r
432 if (CharC >= NT) {\r
433 Mask = 1U << (BITBUFSIZ - 1 - 8);\r
434\r
435 do {\r
436\r
437 if (Mask & Sd->mBitBuf) {\r
438 CharC = Sd->mRight[CharC];\r
439 } else {\r
440 CharC = Sd->mLeft[CharC];\r
441 }\r
442\r
443 Mask >>= 1;\r
444\r
445 } while (CharC >= NT);\r
446 }\r
447 //\r
448 // Advance what we have read\r
449 //\r
450 FillBuf (Sd, Sd->mPTLen[CharC]);\r
451\r
452 if (CharC <= 2) {\r
453\r
454 if (CharC == 0) {\r
455 CharC = 1;\r
456 } else if (CharC == 1) {\r
457 CharC = (UINT16) (GetBits (Sd, 4) + 3);\r
458 } else if (CharC == 2) {\r
459 CharC = (UINT16) (GetBits (Sd, CBIT) + 20);\r
460 }\r
461\r
462 while ((INT16) (--CharC) >= 0) {\r
463 Sd->mCLen[Index++] = 0;\r
464 }\r
465\r
466 } else {\r
467\r
468 Sd->mCLen[Index++] = (UINT8) (CharC - 2);\r
469\r
470 }\r
471 }\r
472\r
473 while (Index < NC) {\r
474 Sd->mCLen[Index++] = 0;\r
475 }\r
476\r
477 MakeTable (Sd, NC, Sd->mCLen, 12, Sd->mCTable);\r
478\r
479 return ;\r
480}\r
481\r
482/**\r
483 Decode a character/length value.\r
484 \r
485 Read one value from mBitBuf, Get one code from mBitBuf. If it is at block boundary, generates\r
486 Huffman code mapping table for Extra Set, Code&Len Set and\r
487 Position Set.\r
488\r
489 @param Sd The global scratch data.\r
490\r
491 @return The value decoded.\r
492\r
493**/\r
494UINT16\r
495DecodeC (\r
496 SCRATCH_DATA *Sd\r
497 )\r
498{\r
499 UINT16 Index2;\r
500 UINT32 Mask;\r
501\r
502 if (Sd->mBlockSize == 0) {\r
503 //\r
504 // Starting a new block\r
505 // Read BlockSize from block header\r
506 // \r
507 Sd->mBlockSize = (UINT16) GetBits (Sd, 16);\r
508\r
509 //\r
510 // Read in the Extra Set Code Length Arrary,\r
511 // Generate the Huffman code mapping table for Extra Set.\r
512 //\r
513 Sd->mBadTableFlag = ReadPTLen (Sd, NT, TBIT, 3);\r
514 if (Sd->mBadTableFlag != 0) {\r
515 return 0;\r
516 }\r
517\r
518 //\r
519 // Read in and decode the Char&Len Set Code Length Arrary,\r
520 // Generate the Huffman code mapping table for Char&Len Set.\r
521 //\r
522 ReadCLen (Sd);\r
523\r
524 //\r
525 // Read in the Position Set Code Length Arrary, \r
526 // Generate the Huffman code mapping table for the Position Set.\r
527 //\r
528 Sd->mBadTableFlag = ReadPTLen (Sd, MAXNP, Sd->mPBit, (UINT16) (-1));\r
529 if (Sd->mBadTableFlag != 0) {\r
530 return 0;\r
531 }\r
532 }\r
533\r
534 //\r
535 // Get one code according to Code&Set Huffman Table\r
536 //\r
537 Sd->mBlockSize--;\r
538 Index2 = Sd->mCTable[Sd->mBitBuf >> (BITBUFSIZ - 12)];\r
539\r
540 if (Index2 >= NC) {\r
541 Mask = 1U << (BITBUFSIZ - 1 - 12);\r
542\r
543 do {\r
544 if (Sd->mBitBuf & Mask) {\r
545 Index2 = Sd->mRight[Index2];\r
546 } else {\r
547 Index2 = Sd->mLeft[Index2];\r
548 }\r
549\r
550 Mask >>= 1;\r
551 } while (Index2 >= NC);\r
552 }\r
553 //\r
554 // Advance what we have read\r
555 //\r
556 FillBuf (Sd, Sd->mCLen[Index2]);\r
557\r
558 return Index2;\r
559}\r
560\r
561/**\r
562 Decode the source data and put the resulting data into the destination buffer.\r
563\r
564 Decode the source data and put the resulting data into the destination buffer.\r
565 \r
566 @param Sd The global scratch data\r
567\r
568**/\r
569VOID\r
570Decode (\r
571 SCRATCH_DATA *Sd\r
572 )\r
573{\r
574 UINT16 BytesRemain;\r
575 UINT32 DataIdx;\r
576 UINT16 CharC;\r
577\r
578 BytesRemain = (UINT16) (-1);\r
579\r
580 DataIdx = 0;\r
581\r
582 for (;;) {\r
583 //\r
584 // Get one code from mBitBuf\r
585 // \r
586 CharC = DecodeC (Sd);\r
587 if (Sd->mBadTableFlag != 0) {\r
588 goto Done;\r
589 }\r
590\r
591 if (CharC < 256) {\r
592 //\r
593 // Process an Original character\r
594 //\r
595 if (Sd->mOutBuf >= Sd->mOrigSize) {\r
596 goto Done;\r
597 } else {\r
598 //\r
599 // Write orignal character into mDstBase\r
600 //\r
601 Sd->mDstBase[Sd->mOutBuf++] = (UINT8) CharC;\r
602 }\r
603\r
604 } else {\r
605 //\r
606 // Process a Pointer\r
607 //\r
608 CharC = (UINT16) (CharC - (UINT8_MAX + 1 - THRESHOLD));\r
609 \r
610 //\r
611 // Get string length\r
612 //\r
613 BytesRemain = CharC;\r
614\r
615 //\r
616 // Locate string position\r
617 //\r
618 DataIdx = Sd->mOutBuf - DecodeP (Sd) - 1;\r
619\r
620 //\r
621 // Write BytesRemain of bytes into mDstBase\r
622 //\r
623 BytesRemain--;\r
624 while ((INT16) (BytesRemain) >= 0) {\r
625 Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];\r
626 if (Sd->mOutBuf >= Sd->mOrigSize) {\r
627 goto Done;\r
628 }\r
629\r
630 BytesRemain--;\r
631 }\r
632 }\r
633 }\r
634\r
635Done:\r
636 return ;\r
637}\r
638\r
639/**\r
640 Retrieves the size of the uncompressed buffer and the size of the scratch 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 destination buffer and the size of scratch \r
668 buffer are successull retrieved.\r
669 @retval RETURN_INVALID_PARAMETER The source data is corrupted\r
670\r
671**/\r
672RETURN_STATUS\r
673EFIAPI\r
674UefiDecompressGetInfo (\r
675 IN CONST VOID *Source,\r
676 IN UINT32 SourceSize,\r
677 OUT UINT32 *DestinationSize,\r
678 OUT UINT32 *ScratchSize\r
679 )\r
680{\r
681 UINT32 CompressedSize;\r
682\r
683 ASSERT (Source != NULL);\r
684 ASSERT (DestinationSize != NULL);\r
685 ASSERT (ScratchSize != NULL);\r
686\r
687 *ScratchSize = sizeof (SCRATCH_DATA);\r
688\r
689 if (SourceSize < 8) {\r
690 return RETURN_INVALID_PARAMETER;\r
691 }\r
692\r
693 CopyMem (&CompressedSize, Source, sizeof (UINT32));\r
694 CopyMem (DestinationSize, (VOID *)((UINT8 *)Source + 4), sizeof (UINT32));\r
695\r
696 if (SourceSize < (CompressedSize + 8)) {\r
697 return RETURN_INVALID_PARAMETER;\r
698 }\r
699\r
700 return RETURN_SUCCESS;\r
701}\r
702\r
703/**\r
704 Decompresses a compressed source buffer.\r
705\r
706 This function is designed so that the decompression algorithm can be implemented\r
707 without using any memory services. As a result, this function is not allowed to\r
708 call any memory allocation services in its implementation. It is the caller's r\r
709 esponsibility to allocate and free the Destination and Scratch buffers.\r
710 If the compressed source data specified by Source is sucessfully decompressed \r
711 into Destination, then RETURN_SUCCESS is returned. If the compressed source data \r
712 specified by Source is not in a valid compressed data format,\r
713 then RETURN_INVALID_PARAMETER is returned.\r
714\r
715 If Source is NULL, then ASSERT().\r
716 If Destination is NULL, then ASSERT().\r
717 If the required scratch buffer size > 0 and Scratch is NULL, then ASSERT().\r
718\r
719 @param Source The source buffer containing the compressed data.\r
720 @param Destination The destination buffer to store the decompressed data\r
721 @param Scratch A temporary scratch buffer that is used to perform the decompression.\r
722 This is an optional parameter that may be NULL if the \r
723 required scratch buffer size is 0.\r
724 \r
725 @retval RETURN_SUCCESS Decompression is successfull\r
726 @retval RETURN_INVALID_PARAMETER The source data is corrupted\r
727\r
728**/\r
729RETURN_STATUS\r
730EFIAPI\r
731UefiDecompress (\r
732 IN CONST VOID *Source,\r
733 IN OUT VOID *Destination,\r
734 IN OUT VOID *Scratch\r
735 )\r
736{\r
737 volatile UINT32 Index;\r
738 UINT32 CompSize;\r
739 UINT32 OrigSize;\r
740 SCRATCH_DATA *Sd;\r
741 CONST UINT8 *Src;\r
742 UINT8 *Dst;\r
743\r
744 ASSERT (Source != NULL);\r
745 ASSERT (Destination != NULL);\r
746 ASSERT (Scratch != NULL);\r
747\r
748 Src = Source;\r
749 Dst = Destination;\r
750\r
751 Sd = (SCRATCH_DATA *) Scratch;\r
752\r
753 CompSize = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);\r
754 OrigSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);\r
755\r
756 //\r
757 // If compressed file size is 0, return\r
758 //\r
759 if (OrigSize == 0) {\r
760 return RETURN_SUCCESS;\r
761 }\r
762\r
763 Src = Src + 8;\r
764\r
765 for (Index = 0; Index < sizeof (SCRATCH_DATA); Index++) {\r
766 ((UINT8 *) Sd)[Index] = 0;\r
767 }\r
768 //\r
769 // The length of the field 'Position Set Code Length Array Size' in Block Header.\r
770 // For EFI 1.1 de/compression algorithm(Version 1), mPBit = 4\r
771 // For Tiano de/compression algorithm(Version 2), mPBit = 5\r
772 //\r
773 Sd->mPBit = 4;\r
774 Sd->mSrcBase = (UINT8 *)Src;\r
775 Sd->mDstBase = Dst;\r
776 //\r
777 // CompSize and OrigSize are caculated in bytes\r
778 //\r
779 Sd->mCompSize = CompSize;\r
780 Sd->mOrigSize = OrigSize;\r
781\r
782 //\r
783 // Fill the first BITBUFSIZ bits\r
784 //\r
785 FillBuf (Sd, BITBUFSIZ);\r
786\r
787 //\r
788 // Decompress it\r
789 //\r
790 Decode (Sd);\r
791\r
792 if (Sd->mBadTableFlag != 0) {\r
793 //\r
794 // Something wrong with the source\r
795 //\r
796 return RETURN_INVALID_PARAMETER;\r
797 }\r
798\r
799 return RETURN_SUCCESS;\r
800}\r