]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.c
added -noclasspath option to the ant cleanall for ForceRebuild, also changed edkii...
[mirror_edk2.git] / MdePkg / Library / BaseUefiDecompressLib / BaseUefiDecompressLib.c
... / ...
Content-type: text/html ]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.c


500 - Internal Server Error

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