]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.c
re order the function definition to avoid unnecessary declaration.
[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
7fd58cbc 17#include <Library/BaseLib.h>\r
c7d265a9 18#include <Library/DebugLib.h>\r
02313d1e
LG
19#include <Library/BaseMemoryLib.h>\r
20#include <Library/UefiDecompressLib.h>\r
e1f414b6 21\r
22#include "BaseUefiDecompressLibInternals.h"\r
23\r
24/**\r
eceb3a4c 25 Read NumOfBit of bits from source into mBitBuf.\r
e1f414b6 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
eceb3a4c 81 Get NumOfBits of bits out from mBitBuf.\r
e1f414b6 82\r
efb23117 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
e1f414b6 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
efb23117 117 Creates Huffman Code mapping table for Extra Set, Char&Len Set\r
e1f414b6 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
efb23117 124 @param Table The table to be created.\r
e1f414b6 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
02313d1e 144 UINT16 Index;\r
e1f414b6 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
9872985b 155 for (Index = 0; Index <= 16; Index++) {\r
e1f414b6 156 Count[Index] = 0;\r
157 }\r
158\r
159 for (Index = 0; Index < NumOfChar; Index++) {\r
160 Count[BitLen[Index]]++;\r
161 }\r
9872985b
LG
162 \r
163 Start[0] = 0;\r
e1f414b6 164 Start[1] = 0;\r
165\r
166 for (Index = 1; Index <= 16; Index++) {\r
167 WordOfStart = Start[Index];\r
168 WordOfCount = Count[Index];\r
169 Start[Index + 1] = (UINT16) (WordOfStart + (WordOfCount << (16 - Index)));\r
170 }\r
171\r
172 if (Start[17] != 0) {\r
173 /*(1U << 16)*/\r
174 return (UINT16) BAD_TABLE;\r
175 }\r
176\r
177 JuBits = (UINT16) (16 - TableBits);\r
9872985b
LG
178 \r
179 Weight[0] = 0;\r
e1f414b6 180 for (Index = 1; Index <= TableBits; Index++) {\r
181 Start[Index] >>= JuBits;\r
182 Weight[Index] = (UINT16) (1U << (TableBits - Index));\r
183 }\r
184\r
185 while (Index <= 16) {\r
186 Weight[Index] = (UINT16) (1U << (16 - Index));\r
187 Index++; \r
188 }\r
189\r
190 Index = (UINT16) (Start[TableBits + 1] >> JuBits);\r
191\r
192 if (Index != 0) {\r
193 Index3 = (UINT16) (1U << TableBits);\r
02313d1e
LG
194 if (Index < Index3) {\r
195 SetMem16 (Table + Index, (Index3 - Index) * sizeof (*Table), 0);\r
e1f414b6 196 }\r
197 }\r
198\r
199 Avail = NumOfChar;\r
200 Mask = (UINT16) (1U << (15 - TableBits));\r
201\r
202 for (Char = 0; Char < NumOfChar; Char++) {\r
203\r
204 Len = BitLen[Char];\r
9872985b 205 if (Len == 0 || Len >= 17) {\r
e1f414b6 206 continue;\r
207 }\r
208\r
209 NextCode = (UINT16) (Start[Len] + Weight[Len]);\r
210\r
211 if (Len <= TableBits) {\r
212\r
213 for (Index = Start[Len]; Index < NextCode; Index++) {\r
214 Table[Index] = Char;\r
215 }\r
216\r
217 } else {\r
218\r
219 Index3 = Start[Len];\r
220 Pointer = &Table[Index3 >> JuBits];\r
221 Index = (UINT16) (Len - TableBits);\r
222\r
223 while (Index != 0) {\r
0ba7fffd 224 if (*Pointer == 0 && Avail < (2 * NC - 1)) {\r
9872985b 225 Sd->mRight[Avail] = Sd->mLeft[Avail] = 0;\r
e1f414b6 226 *Pointer = Avail++;\r
227 }\r
228\r
eceb3a4c 229 if ((Index3 & Mask) != 0) {\r
e1f414b6 230 Pointer = &Sd->mRight[*Pointer];\r
231 } else {\r
232 Pointer = &Sd->mLeft[*Pointer];\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\r
243 Start[Len] = NextCode;\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
efb23117 255\r
e1f414b6 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\r
eceb3a4c 277 if ((Sd->mBitBuf & Mask) != 0) {\r
e1f414b6 278 Val = Sd->mRight[Val];\r
279 } else {\r
280 Val = Sd->mLeft[Val];\r
281 }\r
282\r
283 Mask >>= 1;\r
284 } while (Val >= MAXNP);\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 Pointion Set Length Arrary, then\r
303 generate the Huffman code mapping for them.\r
304\r
305 @param Sd The global scratch data.\r
306 @param nn Number of symbols.\r
307 @param nbit 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
02313d1e 324 UINT16 Index;\r
e1f414b6 325 UINT32 Mask;\r
326\r
327 //\r
328 // Read Extra Set Code Length Array size \r
329 //\r
330 Number = (UINT16) GetBits (Sd, nbit);\r
331\r
332 if (Number == 0) {\r
333 //\r
334 // This represents only Huffman code used\r
335 //\r
336 CharC = (UINT16) GetBits (Sd, nbit);\r
337\r
338 for (Index = 0; Index < 256; Index++) {\r
339 Sd->mPTTable[Index] = CharC;\r
340 }\r
341\r
02313d1e 342 SetMem (Sd->mPTLen, nn, 0);\r
e1f414b6 343\r
344 return 0;\r
345 }\r
346\r
347 Index = 0;\r
348\r
9872985b 349 while (Index < Number && Index < NPT) {\r
e1f414b6 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
0ba7fffd 378 while ((INT16) (--CharC) >= 0 && Index < NPT) {\r
e1f414b6 379 Sd->mPTLen[Index++] = 0;\r
380 }\r
381 }\r
382 }\r
383\r
9872985b 384 while (Index < nn && Index < NPT) {\r
e1f414b6 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
efb23117 393\r
e1f414b6 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
02313d1e 407 UINT16 Index;\r
e1f414b6 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
02313d1e 418 SetMem (Sd->mCLen, NC, 0);\r
e1f414b6 419\r
420 for (Index = 0; Index < 4096; Index++) {\r
421 Sd->mCTable[Index] = CharC;\r
422 }\r
423\r
424 return ;\r
425 }\r
426\r
427 Index = 0;\r
9872985b 428 while (Index < Number && Index < NC) {\r
e1f414b6 429 CharC = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];\r
430 if (CharC >= NT) {\r
431 Mask = 1U << (BITBUFSIZ - 1 - 8);\r
432\r
433 do {\r
434\r
435 if (Mask & Sd->mBitBuf) {\r
436 CharC = Sd->mRight[CharC];\r
437 } else {\r
438 CharC = Sd->mLeft[CharC];\r
439 }\r
440\r
441 Mask >>= 1;\r
442\r
443 } while (CharC >= NT);\r
444 }\r
445 //\r
446 // Advance what we have read\r
447 //\r
448 FillBuf (Sd, Sd->mPTLen[CharC]);\r
449\r
450 if (CharC <= 2) {\r
451\r
452 if (CharC == 0) {\r
453 CharC = 1;\r
454 } else if (CharC == 1) {\r
455 CharC = (UINT16) (GetBits (Sd, 4) + 3);\r
456 } else if (CharC == 2) {\r
457 CharC = (UINT16) (GetBits (Sd, CBIT) + 20);\r
458 }\r
459\r
0ba7fffd 460 while ((INT16) (--CharC) >= 0 && Index < NC) {\r
e1f414b6 461 Sd->mCLen[Index++] = 0;\r
462 }\r
463\r
464 } else {\r
465\r
466 Sd->mCLen[Index++] = (UINT8) (CharC - 2);\r
467\r
468 }\r
469 }\r
470\r
02313d1e 471 SetMem (Sd->mCLen + Index, NC - Index, 0);\r
e1f414b6 472\r
473 MakeTable (Sd, NC, Sd->mCLen, 12, Sd->mCTable);\r
474\r
475 return ;\r
476}\r
477\r
478/**\r
479 Decode a character/length value.\r
efb23117 480\r
e1f414b6 481 Read one value from mBitBuf, Get one code from mBitBuf. If it is at block boundary, generates\r
482 Huffman code mapping table for Extra Set, Code&Len Set and\r
483 Position Set.\r
484\r
485 @param Sd The global scratch data.\r
486\r
487 @return The value decoded.\r
488\r
489**/\r
490UINT16\r
491DecodeC (\r
492 SCRATCH_DATA *Sd\r
493 )\r
494{\r
495 UINT16 Index2;\r
496 UINT32 Mask;\r
497\r
498 if (Sd->mBlockSize == 0) {\r
499 //\r
500 // Starting a new block\r
501 // Read BlockSize from block header\r
502 // \r
503 Sd->mBlockSize = (UINT16) GetBits (Sd, 16);\r
504\r
505 //\r
506 // Read in the Extra Set Code Length Arrary,\r
507 // Generate the Huffman code mapping table for Extra Set.\r
508 //\r
509 Sd->mBadTableFlag = ReadPTLen (Sd, NT, TBIT, 3);\r
510 if (Sd->mBadTableFlag != 0) {\r
511 return 0;\r
512 }\r
513\r
514 //\r
515 // Read in and decode the Char&Len Set Code Length Arrary,\r
516 // Generate the Huffman code mapping table for Char&Len Set.\r
517 //\r
518 ReadCLen (Sd);\r
519\r
520 //\r
521 // Read in the Position Set Code Length Arrary, \r
522 // Generate the Huffman code mapping table for the Position Set.\r
523 //\r
524 Sd->mBadTableFlag = ReadPTLen (Sd, MAXNP, Sd->mPBit, (UINT16) (-1));\r
525 if (Sd->mBadTableFlag != 0) {\r
526 return 0;\r
527 }\r
528 }\r
529\r
530 //\r
531 // Get one code according to Code&Set Huffman Table\r
532 //\r
533 Sd->mBlockSize--;\r
534 Index2 = Sd->mCTable[Sd->mBitBuf >> (BITBUFSIZ - 12)];\r
535\r
536 if (Index2 >= NC) {\r
537 Mask = 1U << (BITBUFSIZ - 1 - 12);\r
538\r
539 do {\r
eceb3a4c 540 if ((Sd->mBitBuf & Mask) != 0) {\r
e1f414b6 541 Index2 = Sd->mRight[Index2];\r
542 } else {\r
543 Index2 = Sd->mLeft[Index2];\r
544 }\r
545\r
546 Mask >>= 1;\r
547 } while (Index2 >= NC);\r
548 }\r
549 //\r
550 // Advance what we have read\r
551 //\r
552 FillBuf (Sd, Sd->mCLen[Index2]);\r
553\r
554 return Index2;\r
555}\r
556\r
557/**\r
558 Decode the source data and put the resulting data into the destination buffer.\r
efb23117 559\r
e1f414b6 560 @param Sd The global scratch data\r
561\r
562**/\r
563VOID\r
564Decode (\r
565 SCRATCH_DATA *Sd\r
566 )\r
567{\r
568 UINT16 BytesRemain;\r
569 UINT32 DataIdx;\r
570 UINT16 CharC;\r
571\r
572 BytesRemain = (UINT16) (-1);\r
573\r
574 DataIdx = 0;\r
575\r
576 for (;;) {\r
577 //\r
578 // Get one code from mBitBuf\r
579 // \r
580 CharC = DecodeC (Sd);\r
581 if (Sd->mBadTableFlag != 0) {\r
582 goto Done;\r
583 }\r
584\r
585 if (CharC < 256) {\r
586 //\r
587 // Process an Original character\r
588 //\r
589 if (Sd->mOutBuf >= Sd->mOrigSize) {\r
590 goto Done;\r
591 } else {\r
592 //\r
593 // Write orignal character into mDstBase\r
594 //\r
595 Sd->mDstBase[Sd->mOutBuf++] = (UINT8) CharC;\r
596 }\r
597\r
598 } else {\r
599 //\r
600 // Process a Pointer\r
601 //\r
daa6553a 602 CharC = (UINT16) (CharC - (BIT8 - THRESHOLD));\r
e1f414b6 603 \r
604 //\r
605 // Get string length\r
606 //\r
607 BytesRemain = CharC;\r
608\r
609 //\r
610 // Locate string position\r
611 //\r
612 DataIdx = Sd->mOutBuf - DecodeP (Sd) - 1;\r
613\r
614 //\r
615 // Write BytesRemain of bytes into mDstBase\r
616 //\r
617 BytesRemain--;\r
618 while ((INT16) (BytesRemain) >= 0) {\r
619 Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];\r
620 if (Sd->mOutBuf >= Sd->mOrigSize) {\r
621 goto Done;\r
622 }\r
623\r
624 BytesRemain--;\r
625 }\r
626 }\r
627 }\r
628\r
629Done:\r
630 return ;\r
631}\r
632\r
633/**\r
eceb3a4c
LG
634 Given a compressed source buffer, this function retrieves the size of \r
635 the uncompressed buffer and the size of the scratch buffer required \r
636 to decompress the compressed source buffer.\r
e1f414b6 637\r
638 Retrieves the size of the uncompressed buffer and the temporary scratch buffer \r
639 required to decompress the buffer specified by Source and SourceSize.\r
640 If the size of the uncompressed buffer or the size of the scratch buffer cannot\r
641 be determined from the compressed data specified by Source and SourceData, \r
642 then RETURN_INVALID_PARAMETER is returned. Otherwise, the size of the uncompressed\r
643 buffer is returned in DestinationSize, the size of the scratch buffer is returned\r
644 in ScratchSize, and RETURN_SUCCESS is returned.\r
645 This function does not have scratch buffer available to perform a thorough \r
646 checking of the validity of the source data. It just retrieves the "Original Size"\r
647 field from the beginning bytes of the source data and output it as DestinationSize.\r
648 And ScratchSize is specific to the decompression implementation.\r
649\r
650 If Source is NULL, then ASSERT().\r
651 If DestinationSize is NULL, then ASSERT().\r
652 If ScratchSize is NULL, then ASSERT().\r
653\r
654 @param Source The source buffer containing the compressed data.\r
655 @param SourceSize The size, in bytes, of the source buffer.\r
656 @param DestinationSize A pointer to the size, in bytes, of the uncompressed buffer\r
657 that will be generated when the compressed buffer specified\r
658 by Source and SourceSize is decompressed..\r
659 @param ScratchSize A pointer to the size, in bytes, of the scratch buffer that\r
660 is required to decompress the compressed buffer specified \r
661 by Source and SourceSize.\r
662\r
eceb3a4c
LG
663 @retval RETURN_SUCCESS The size of the uncompressed data was returned \r
664 in DestinationSize and the size of the scratch \r
665 buffer was returned in ScratchSize.\r
666 @retval RETURN_INVALID_PARAMETER \r
667 The size of the uncompressed data or the size of \r
668 the scratch buffer cannot be determined from \r
669 the compressed data specified by Source \r
670 and SourceSize.\r
e1f414b6 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
e1f414b6 687 if (SourceSize < 8) {\r
688 return RETURN_INVALID_PARAMETER;\r
689 }\r
690\r
7fd58cbc 691 CompressedSize = ReadUnaligned32 ((UINT32 *)Source);\r
e1f414b6 692 if (SourceSize < (CompressedSize + 8)) {\r
693 return RETURN_INVALID_PARAMETER;\r
694 }\r
695\r
7fd58cbc 696 *ScratchSize = sizeof (SCRATCH_DATA);\r
697 *DestinationSize = ReadUnaligned32 ((UINT32 *)Source + 1);\r
698\r
e1f414b6 699 return RETURN_SUCCESS;\r
700}\r
701\r
702/**\r
703 Decompresses a compressed source buffer.\r
704\r
eceb3a4c 705 Extracts decompressed data to its original form.\r
e1f414b6 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
eceb3a4c
LG
725 @retval RETURN_SUCCESS Decompression completed successfully, and \r
726 the uncompressed buffer is returned in Destination.\r
727 @retval RETURN_INVALID_PARAMETER \r
728 The source buffer specified by Source is corrupted \r
729 (not in a valid compressed format).\r
e1f414b6 730**/\r
731RETURN_STATUS\r
732EFIAPI\r
733UefiDecompress (\r
734 IN CONST VOID *Source,\r
735 IN OUT VOID *Destination,\r
6d6a1098 736 IN OUT VOID *Scratch OPTIONAL\r
e1f414b6 737 )\r
738{\r
e1f414b6 739 UINT32 CompSize;\r
740 UINT32 OrigSize;\r
741 SCRATCH_DATA *Sd;\r
742 CONST UINT8 *Src;\r
743 UINT8 *Dst;\r
744\r
745 ASSERT (Source != NULL);\r
746 ASSERT (Destination != NULL);\r
747 ASSERT (Scratch != NULL);\r
748\r
749 Src = Source;\r
750 Dst = Destination;\r
751\r
752 Sd = (SCRATCH_DATA *) Scratch;\r
753\r
754 CompSize = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);\r
755 OrigSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);\r
756\r
757 //\r
758 // If compressed file size is 0, return\r
759 //\r
760 if (OrigSize == 0) {\r
761 return RETURN_SUCCESS;\r
762 }\r
763\r
764 Src = Src + 8;\r
02313d1e 765 SetMem (Sd, sizeof (SCRATCH_DATA), 0);\r
e1f414b6 766\r
e1f414b6 767 //\r
768 // The length of the field 'Position Set Code Length Array Size' in Block Header.\r
8a7d75b0 769 // For UEFI 2.0 de/compression algorithm(Version 1), mPBit = 4\r
e1f414b6 770 //\r
771 Sd->mPBit = 4;\r
772 Sd->mSrcBase = (UINT8 *)Src;\r
773 Sd->mDstBase = Dst;\r
774 //\r
775 // CompSize and OrigSize are caculated in bytes\r
776 //\r
777 Sd->mCompSize = CompSize;\r
778 Sd->mOrigSize = OrigSize;\r
779\r
780 //\r
781 // Fill the first BITBUFSIZ bits\r
782 //\r
783 FillBuf (Sd, BITBUFSIZ);\r
784\r
785 //\r
786 // Decompress it\r
787 //\r
788 Decode (Sd);\r
789\r
790 if (Sd->mBadTableFlag != 0) {\r
791 //\r
792 // Something wrong with the source\r
793 //\r
794 return RETURN_INVALID_PARAMETER;\r
795 }\r
796\r
797 return RETURN_SUCCESS;\r
798}\r