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