]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.c
Synchronize BaseLib h files to c files.
[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
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
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
118 Creates Huffman Code mapping table for Extra Set, Char&Len Set \r
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
eceb3a4c 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
156 for (Index = 1; Index <= 16; Index++) {\r
157 Count[Index] = 0;\r
158 }\r
159\r
160 for (Index = 0; Index < NumOfChar; Index++) {\r
161 Count[BitLen[Index]]++;\r
162 }\r
163\r
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
178\r
179 for (Index = 1; Index <= TableBits; Index++) {\r
180 Start[Index] >>= JuBits;\r
181 Weight[Index] = (UINT16) (1U << (TableBits - Index));\r
182 }\r
183\r
184 while (Index <= 16) {\r
185 Weight[Index] = (UINT16) (1U << (16 - Index));\r
186 Index++; \r
187 }\r
188\r
189 Index = (UINT16) (Start[TableBits + 1] >> JuBits);\r
190\r
191 if (Index != 0) {\r
192 Index3 = (UINT16) (1U << TableBits);\r
193 while (Index != Index3) {\r
194 Table[Index++] = 0;\r
195 }\r
196 }\r
197\r
198 Avail = NumOfChar;\r
199 Mask = (UINT16) (1U << (15 - TableBits));\r
200\r
201 for (Char = 0; Char < NumOfChar; Char++) {\r
202\r
203 Len = BitLen[Char];\r
204 if (Len == 0) {\r
205 continue;\r
206 }\r
207\r
208 NextCode = (UINT16) (Start[Len] + Weight[Len]);\r
209\r
210 if (Len <= TableBits) {\r
211\r
212 for (Index = Start[Len]; Index < NextCode; Index++) {\r
213 Table[Index] = Char;\r
214 }\r
215\r
216 } else {\r
217\r
218 Index3 = Start[Len];\r
219 Pointer = &Table[Index3 >> JuBits];\r
220 Index = (UINT16) (Len - TableBits);\r
221\r
222 while (Index != 0) {\r
223 if (*Pointer == 0) {\r
224 Sd->mRight[Avail] = Sd->mLeft[Avail] = 0;\r
225 *Pointer = Avail++;\r
226 }\r
227\r
eceb3a4c 228 if ((Index3 & Mask) != 0) {\r
e1f414b6 229 Pointer = &Sd->mRight[*Pointer];\r
230 } else {\r
231 Pointer = &Sd->mLeft[*Pointer];\r
232 }\r
233\r
234 Index3 <<= 1;\r
235 Index--;\r
236 }\r
237\r
238 *Pointer = Char;\r
239\r
240 }\r
241\r
242 Start[Len] = NextCode;\r
243 }\r
244 //\r
245 // Succeeds\r
246 //\r
247 return 0;\r
248}\r
249\r
250/**\r
251 Decodes a position value.\r
252\r
253 Get a position value according to Position Huffman Table.\r
254 \r
255 @param Sd the global scratch data\r
256\r
257 @return The position value decoded.\r
258\r
259**/\r
260UINT32\r
261DecodeP (\r
262 IN SCRATCH_DATA *Sd\r
263 )\r
264{\r
265 UINT16 Val;\r
266 UINT32 Mask;\r
267 UINT32 Pos;\r
268\r
269 Val = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];\r
270\r
271 if (Val >= MAXNP) {\r
272 Mask = 1U << (BITBUFSIZ - 1 - 8);\r
273\r
274 do {\r
275\r
eceb3a4c 276 if ((Sd->mBitBuf & Mask) != 0) {\r
e1f414b6 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 // Advance what we have read\r
287 //\r
288 FillBuf (Sd, Sd->mPTLen[Val]);\r
289\r
290 Pos = Val;\r
291 if (Val > 1) {\r
292 Pos = (UINT32) ((1U << (Val - 1)) + GetBits (Sd, (UINT16) (Val - 1)));\r
293 }\r
294\r
295 return Pos;\r
296}\r
297\r
298/**\r
299 Reads code lengths for the Extra Set or the Position Set.\r
300\r
301 Read in the Extra Set or Pointion Set Length Arrary, then\r
302 generate the Huffman code mapping for them.\r
303\r
304 @param Sd The global scratch data.\r
305 @param nn Number of symbols.\r
306 @param nbit Number of bits needed to represent nn.\r
307 @param Special The special symbol that needs to be taken care of.\r
308\r
309 @retval 0 OK.\r
310 @retval BAD_TABLE Table is corrupted.\r
311\r
312**/\r
313UINT16\r
314ReadPTLen (\r
315 IN SCRATCH_DATA *Sd,\r
316 IN UINT16 nn,\r
317 IN UINT16 nbit,\r
318 IN UINT16 Special\r
319 )\r
320{\r
321 UINT16 Number;\r
322 UINT16 CharC;\r
323 volatile UINT16 Index;\r
324 UINT32 Mask;\r
325\r
326 //\r
327 // Read Extra Set Code Length Array size \r
328 //\r
329 Number = (UINT16) GetBits (Sd, nbit);\r
330\r
331 if (Number == 0) {\r
332 //\r
333 // This represents only Huffman code used\r
334 //\r
335 CharC = (UINT16) GetBits (Sd, nbit);\r
336\r
337 for (Index = 0; Index < 256; Index++) {\r
338 Sd->mPTTable[Index] = CharC;\r
339 }\r
340\r
341 for (Index = 0; Index < nn; Index++) {\r
342 Sd->mPTLen[Index] = 0;\r
343 }\r
344\r
345 return 0;\r
346 }\r
347\r
348 Index = 0;\r
349\r
350 while (Index < Number) {\r
351\r
352 CharC = (UINT16) (Sd->mBitBuf >> (BITBUFSIZ - 3));\r
353\r
354 //\r
355 // If a code length is less than 7, then it is encoded as a 3-bit\r
356 // value. Or it is encoded as a series of "1"s followed by a \r
357 // terminating "0". The number of "1"s = Code length - 4.\r
358 //\r
359 if (CharC == 7) {\r
360 Mask = 1U << (BITBUFSIZ - 1 - 3);\r
361 while (Mask & Sd->mBitBuf) {\r
362 Mask >>= 1;\r
363 CharC += 1;\r
364 }\r
365 }\r
366 \r
367 FillBuf (Sd, (UINT16) ((CharC < 7) ? 3 : CharC - 3));\r
368\r
369 Sd->mPTLen[Index++] = (UINT8) CharC;\r
370 \r
371 //\r
372 // For Code&Len Set, \r
373 // After the third length of the code length concatenation,\r
374 // a 2-bit value is used to indicated the number of consecutive \r
375 // zero lengths after the third length.\r
376 //\r
377 if (Index == Special) {\r
378 CharC = (UINT16) GetBits (Sd, 2);\r
379 while ((INT16) (--CharC) >= 0) {\r
380 Sd->mPTLen[Index++] = 0;\r
381 }\r
382 }\r
383 }\r
384\r
385 while (Index < nn) {\r
386 Sd->mPTLen[Index++] = 0;\r
387 }\r
388 \r
389 return MakeTable (Sd, nn, Sd->mPTLen, 8, Sd->mPTTable);\r
390}\r
391\r
392/**\r
393 Reads code lengths for Char&Len Set.\r
394 \r
395 Read in and decode the Char&Len Set Code Length Array, then\r
396 generate the Huffman Code mapping table for the Char&Len Set.\r
397\r
398 @param Sd the global scratch data\r
399\r
400**/\r
401VOID\r
402ReadCLen (\r
403 SCRATCH_DATA *Sd\r
404 )\r
405{\r
406 UINT16 Number;\r
407 UINT16 CharC;\r
408 volatile UINT16 Index;\r
409 UINT32 Mask;\r
410\r
411 Number = (UINT16) GetBits (Sd, CBIT);\r
412\r
413 if (Number == 0) {\r
414 //\r
415 // This represents only Huffman code used\r
416 //\r
417 CharC = (UINT16) GetBits (Sd, CBIT);\r
418\r
419 for (Index = 0; Index < NC; Index++) {\r
420 Sd->mCLen[Index] = 0;\r
421 }\r
422\r
423 for (Index = 0; Index < 4096; Index++) {\r
424 Sd->mCTable[Index] = CharC;\r
425 }\r
426\r
427 return ;\r
428 }\r
429\r
430 Index = 0;\r
431 while (Index < Number) {\r
432 CharC = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];\r
433 if (CharC >= NT) {\r
434 Mask = 1U << (BITBUFSIZ - 1 - 8);\r
435\r
436 do {\r
437\r
438 if (Mask & Sd->mBitBuf) {\r
439 CharC = Sd->mRight[CharC];\r
440 } else {\r
441 CharC = Sd->mLeft[CharC];\r
442 }\r
443\r
444 Mask >>= 1;\r
445\r
446 } while (CharC >= NT);\r
447 }\r
448 //\r
449 // Advance what we have read\r
450 //\r
451 FillBuf (Sd, Sd->mPTLen[CharC]);\r
452\r
453 if (CharC <= 2) {\r
454\r
455 if (CharC == 0) {\r
456 CharC = 1;\r
457 } else if (CharC == 1) {\r
458 CharC = (UINT16) (GetBits (Sd, 4) + 3);\r
459 } else if (CharC == 2) {\r
460 CharC = (UINT16) (GetBits (Sd, CBIT) + 20);\r
461 }\r
462\r
463 while ((INT16) (--CharC) >= 0) {\r
464 Sd->mCLen[Index++] = 0;\r
465 }\r
466\r
467 } else {\r
468\r
469 Sd->mCLen[Index++] = (UINT8) (CharC - 2);\r
470\r
471 }\r
472 }\r
473\r
474 while (Index < NC) {\r
475 Sd->mCLen[Index++] = 0;\r
476 }\r
477\r
478 MakeTable (Sd, NC, Sd->mCLen, 12, Sd->mCTable);\r
479\r
480 return ;\r
481}\r
482\r
483/**\r
484 Decode a character/length value.\r
485 \r
486 Read one value from mBitBuf, Get one code from mBitBuf. If it is at block boundary, generates\r
487 Huffman code mapping table for Extra Set, Code&Len Set and\r
488 Position Set.\r
489\r
490 @param Sd The global scratch data.\r
491\r
492 @return The value decoded.\r
493\r
494**/\r
495UINT16\r
496DecodeC (\r
497 SCRATCH_DATA *Sd\r
498 )\r
499{\r
500 UINT16 Index2;\r
501 UINT32 Mask;\r
502\r
503 if (Sd->mBlockSize == 0) {\r
504 //\r
505 // Starting a new block\r
506 // Read BlockSize from block header\r
507 // \r
508 Sd->mBlockSize = (UINT16) GetBits (Sd, 16);\r
509\r
510 //\r
511 // Read in the Extra Set Code Length Arrary,\r
512 // Generate the Huffman code mapping table for Extra Set.\r
513 //\r
514 Sd->mBadTableFlag = ReadPTLen (Sd, NT, TBIT, 3);\r
515 if (Sd->mBadTableFlag != 0) {\r
516 return 0;\r
517 }\r
518\r
519 //\r
520 // Read in and decode the Char&Len Set Code Length Arrary,\r
521 // Generate the Huffman code mapping table for Char&Len Set.\r
522 //\r
523 ReadCLen (Sd);\r
524\r
525 //\r
526 // Read in the Position Set Code Length Arrary, \r
527 // Generate the Huffman code mapping table for the Position Set.\r
528 //\r
529 Sd->mBadTableFlag = ReadPTLen (Sd, MAXNP, Sd->mPBit, (UINT16) (-1));\r
530 if (Sd->mBadTableFlag != 0) {\r
531 return 0;\r
532 }\r
533 }\r
534\r
535 //\r
536 // Get one code according to Code&Set Huffman Table\r
537 //\r
538 Sd->mBlockSize--;\r
539 Index2 = Sd->mCTable[Sd->mBitBuf >> (BITBUFSIZ - 12)];\r
540\r
541 if (Index2 >= NC) {\r
542 Mask = 1U << (BITBUFSIZ - 1 - 12);\r
543\r
544 do {\r
eceb3a4c 545 if ((Sd->mBitBuf & Mask) != 0) {\r
e1f414b6 546 Index2 = Sd->mRight[Index2];\r
547 } else {\r
548 Index2 = Sd->mLeft[Index2];\r
549 }\r
550\r
551 Mask >>= 1;\r
552 } while (Index2 >= NC);\r
553 }\r
554 //\r
555 // Advance what we have read\r
556 //\r
557 FillBuf (Sd, Sd->mCLen[Index2]);\r
558\r
559 return Index2;\r
560}\r
561\r
562/**\r
563 Decode the source data and put the resulting data into the destination buffer.\r
eceb3a4c 564 \r
e1f414b6 565 @param Sd The global scratch data\r
566\r
567**/\r
568VOID\r
569Decode (\r
570 SCRATCH_DATA *Sd\r
571 )\r
572{\r
573 UINT16 BytesRemain;\r
574 UINT32 DataIdx;\r
575 UINT16 CharC;\r
576\r
577 BytesRemain = (UINT16) (-1);\r
578\r
579 DataIdx = 0;\r
580\r
581 for (;;) {\r
582 //\r
583 // Get one code from mBitBuf\r
584 // \r
585 CharC = DecodeC (Sd);\r
586 if (Sd->mBadTableFlag != 0) {\r
587 goto Done;\r
588 }\r
589\r
590 if (CharC < 256) {\r
591 //\r
592 // Process an Original character\r
593 //\r
594 if (Sd->mOutBuf >= Sd->mOrigSize) {\r
595 goto Done;\r
596 } else {\r
597 //\r
598 // Write orignal character into mDstBase\r
599 //\r
600 Sd->mDstBase[Sd->mOutBuf++] = (UINT8) CharC;\r
601 }\r
602\r
603 } else {\r
604 //\r
605 // Process a Pointer\r
606 //\r
daa6553a 607 CharC = (UINT16) (CharC - (BIT8 - THRESHOLD));\r
e1f414b6 608 \r
609 //\r
610 // Get string length\r
611 //\r
612 BytesRemain = CharC;\r
613\r
614 //\r
615 // Locate string position\r
616 //\r
617 DataIdx = Sd->mOutBuf - DecodeP (Sd) - 1;\r
618\r
619 //\r
620 // Write BytesRemain of bytes into mDstBase\r
621 //\r
622 BytesRemain--;\r
623 while ((INT16) (BytesRemain) >= 0) {\r
624 Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];\r
625 if (Sd->mOutBuf >= Sd->mOrigSize) {\r
626 goto Done;\r
627 }\r
628\r
629 BytesRemain--;\r
630 }\r
631 }\r
632 }\r
633\r
634Done:\r
635 return ;\r
636}\r
637\r
638/**\r
eceb3a4c
LG
639 Given a compressed source buffer, this function retrieves the size of \r
640 the uncompressed buffer and the size of the scratch buffer required \r
641 to decompress the compressed source buffer.\r
e1f414b6 642\r
643 Retrieves the size of the uncompressed buffer and the temporary scratch buffer \r
644 required to decompress the buffer specified by Source and SourceSize.\r
645 If the size of the uncompressed buffer or the size of the scratch buffer cannot\r
646 be determined from the compressed data specified by Source and SourceData, \r
647 then RETURN_INVALID_PARAMETER is returned. Otherwise, the size of the uncompressed\r
648 buffer is returned in DestinationSize, the size of the scratch buffer is returned\r
649 in ScratchSize, and RETURN_SUCCESS is returned.\r
650 This function does not have scratch buffer available to perform a thorough \r
651 checking of the validity of the source data. It just retrieves the "Original Size"\r
652 field from the beginning bytes of the source data and output it as DestinationSize.\r
653 And ScratchSize is specific to the decompression implementation.\r
654\r
655 If Source is NULL, then ASSERT().\r
656 If DestinationSize is NULL, then ASSERT().\r
657 If ScratchSize is NULL, then ASSERT().\r
658\r
659 @param Source The source buffer containing the compressed data.\r
660 @param SourceSize The size, in bytes, of the source buffer.\r
661 @param DestinationSize A pointer to the size, in bytes, of the uncompressed buffer\r
662 that will be generated when the compressed buffer specified\r
663 by Source and SourceSize is decompressed..\r
664 @param ScratchSize A pointer to the size, in bytes, of the scratch buffer that\r
665 is required to decompress the compressed buffer specified \r
666 by Source and SourceSize.\r
667\r
eceb3a4c
LG
668 @retval RETURN_SUCCESS The size of the uncompressed data was returned \r
669 in DestinationSize and the size of the scratch \r
670 buffer was returned in ScratchSize.\r
671 @retval RETURN_INVALID_PARAMETER \r
672 The size of the uncompressed data or the size of \r
673 the scratch buffer cannot be determined from \r
674 the compressed data specified by Source \r
675 and SourceSize.\r
e1f414b6 676**/\r
677RETURN_STATUS\r
678EFIAPI\r
679UefiDecompressGetInfo (\r
680 IN CONST VOID *Source,\r
681 IN UINT32 SourceSize,\r
682 OUT UINT32 *DestinationSize,\r
683 OUT UINT32 *ScratchSize\r
684 )\r
685{\r
686 UINT32 CompressedSize;\r
687\r
688 ASSERT (Source != NULL);\r
689 ASSERT (DestinationSize != NULL);\r
690 ASSERT (ScratchSize != NULL);\r
691\r
e1f414b6 692 if (SourceSize < 8) {\r
693 return RETURN_INVALID_PARAMETER;\r
694 }\r
695\r
7fd58cbc 696 CompressedSize = ReadUnaligned32 ((UINT32 *)Source);\r
e1f414b6 697 if (SourceSize < (CompressedSize + 8)) {\r
698 return RETURN_INVALID_PARAMETER;\r
699 }\r
700\r
7fd58cbc 701 *ScratchSize = sizeof (SCRATCH_DATA);\r
702 *DestinationSize = ReadUnaligned32 ((UINT32 *)Source + 1);\r
703\r
e1f414b6 704 return RETURN_SUCCESS;\r
705}\r
706\r
707/**\r
708 Decompresses a compressed source buffer.\r
709\r
eceb3a4c 710 Extracts decompressed data to its original form.\r
e1f414b6 711 This function is designed so that the decompression algorithm can be implemented\r
712 without using any memory services. As a result, this function is not allowed to\r
713 call any memory allocation services in its implementation. It is the caller's r\r
714 esponsibility to allocate and free the Destination and Scratch buffers.\r
715 If the compressed source data specified by Source is sucessfully decompressed \r
716 into Destination, then RETURN_SUCCESS is returned. If the compressed source data \r
717 specified by Source is not in a valid compressed data format,\r
718 then RETURN_INVALID_PARAMETER is returned.\r
719\r
720 If Source is NULL, then ASSERT().\r
721 If Destination is NULL, then ASSERT().\r
722 If the required scratch buffer size > 0 and Scratch is NULL, 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 \r
eceb3a4c
LG
730 @retval RETURN_SUCCESS Decompression completed successfully, and \r
731 the uncompressed buffer is returned in Destination.\r
732 @retval RETURN_INVALID_PARAMETER \r
733 The source buffer specified by Source is corrupted \r
734 (not in a valid compressed format).\r
e1f414b6 735**/\r
736RETURN_STATUS\r
737EFIAPI\r
738UefiDecompress (\r
739 IN CONST VOID *Source,\r
740 IN OUT VOID *Destination,\r
6d6a1098 741 IN OUT VOID *Scratch OPTIONAL\r
e1f414b6 742 )\r
743{\r
744 volatile UINT32 Index;\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\r
755 Src = Source;\r
756 Dst = Destination;\r
757\r
758 Sd = (SCRATCH_DATA *) Scratch;\r
759\r
760 CompSize = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);\r
761 OrigSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);\r
762\r
763 //\r
764 // If compressed file size is 0, return\r
765 //\r
766 if (OrigSize == 0) {\r
767 return RETURN_SUCCESS;\r
768 }\r
769\r
770 Src = Src + 8;\r
771\r
772 for (Index = 0; Index < sizeof (SCRATCH_DATA); Index++) {\r
773 ((UINT8 *) Sd)[Index] = 0;\r
774 }\r
775 //\r
776 // The length of the field 'Position Set Code Length Array Size' in Block Header.\r
8a7d75b0 777 // For UEFI 2.0 de/compression algorithm(Version 1), mPBit = 4\r
e1f414b6 778 //\r
779 Sd->mPBit = 4;\r
780 Sd->mSrcBase = (UINT8 *)Src;\r
781 Sd->mDstBase = Dst;\r
782 //\r
783 // CompSize and OrigSize are caculated in bytes\r
784 //\r
785 Sd->mCompSize = CompSize;\r
786 Sd->mOrigSize = OrigSize;\r
787\r
788 //\r
789 // Fill the first BITBUFSIZ bits\r
790 //\r
791 FillBuf (Sd, BITBUFSIZ);\r
792\r
793 //\r
794 // Decompress it\r
795 //\r
796 Decode (Sd);\r
797\r
798 if (Sd->mBadTableFlag != 0) {\r
799 //\r
800 // Something wrong with the source\r
801 //\r
802 return RETURN_INVALID_PARAMETER;\r
803 }\r
804\r
805 return RETURN_SUCCESS;\r
806}\r