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