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