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