1 /** @file 2 Decompressor. Algorithm Ported from OPSD code (Decomp.asm) for Efi and Tiano 3 compress algorithm. 4 5 Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR> 6 This program and the accompanying materials 7 are licensed and made available under the terms and conditions of the BSD License 8 which accompanies this distribution. The full text of the license may be found at 9 http://opensource.org/licenses/bsd-license.php 10 11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 13 14 --*/ 15 16 #include <stdlib.h> 17 #include <string.h> 18 #include "Decompress.h" 19 20 // 21 // Decompression algorithm begins here 22 // 23 #define BITBUFSIZ 32 24 #define MAXMATCH 256 25 #define THRESHOLD 3 26 #define CODE_BIT 16 27 #define BAD_TABLE - 1 28 29 // 30 // C: Char&Len Set; P: Position Set; T: exTra Set 31 // 32 #define NC (0xff + MAXMATCH + 2 - THRESHOLD) 33 #define CBIT 9 34 #define EFIPBIT 4 35 #define MAXPBIT 5 36 #define TBIT 5 37 #define MAXNP ((1U << MAXPBIT) - 1) 38 #define NT (CODE_BIT + 3) 39 #if NT > MAXNP 40 #define NPT NT 41 #else 42 #define NPT MAXNP 43 #endif 44 45 typedef struct { 46 UINT8 *mSrcBase; // Starting address of compressed data 47 UINT8 *mDstBase; // Starting address of decompressed data 48 UINT32 mOutBuf; 49 UINT32 mInBuf; 50 51 UINT16 mBitCount; 52 UINT32 mBitBuf; 53 UINT32 mSubBitBuf; 54 UINT16 mBlockSize; 55 UINT32 mCompSize; 56 UINT32 mOrigSize; 57 58 UINT16 mBadTableFlag; 59 60 UINT16 mLeft[2 * NC - 1]; 61 UINT16 mRight[2 * NC - 1]; 62 UINT8 mCLen[NC]; 63 UINT8 mPTLen[NPT]; 64 UINT16 mCTable[4096]; 65 UINT16 mPTTable[256]; 66 } SCRATCH_DATA; 67 68 STATIC UINT16 mPbit = EFIPBIT; 69 70 STATIC 71 VOID 72 FillBuf ( 73 IN SCRATCH_DATA *Sd, 74 IN UINT16 NumOfBits 75 ) 76 /*++ 77 78 Routine Description: 79 80 Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source. 81 82 Arguments: 83 84 Sd - The global scratch data 85 NumOfBit - The number of bits to shift and read. 86 87 Returns: (VOID) 88 89 --*/ 90 { 91 Sd->mBitBuf = (UINT32) (Sd->mBitBuf << NumOfBits); 92 93 while (NumOfBits > Sd->mBitCount) { 94 95 Sd->mBitBuf |= (UINT32) (Sd->mSubBitBuf << (NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount))); 96 97 if (Sd->mCompSize > 0) { 98 // 99 // Get 1 byte into SubBitBuf 100 // 101 Sd->mCompSize--; 102 Sd->mSubBitBuf = 0; 103 Sd->mSubBitBuf = Sd->mSrcBase[Sd->mInBuf++]; 104 Sd->mBitCount = 8; 105 106 } else { 107 // 108 // No more bits from the source, just pad zero bit. 109 // 110 Sd->mSubBitBuf = 0; 111 Sd->mBitCount = 8; 112 113 } 114 } 115 116 Sd->mBitCount = (UINT16) (Sd->mBitCount - NumOfBits); 117 Sd->mBitBuf |= Sd->mSubBitBuf >> Sd->mBitCount; 118 } 119 120 STATIC 121 UINT32 122 GetBits ( 123 IN SCRATCH_DATA *Sd, 124 IN UINT16 NumOfBits 125 ) 126 /*++ 127 128 Routine Description: 129 130 Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent 131 NumOfBits of bits from source. Returns NumOfBits of bits that are 132 popped out. 133 134 Arguments: 135 136 Sd - The global scratch data. 137 NumOfBits - The number of bits to pop and read. 138 139 Returns: 140 141 The bits that are popped out. 142 143 --*/ 144 { 145 UINT32 OutBits; 146 147 OutBits = (UINT32) (Sd->mBitBuf >> (BITBUFSIZ - NumOfBits)); 148 149 FillBuf (Sd, NumOfBits); 150 151 return OutBits; 152 } 153 154 STATIC 155 UINT16 156 MakeTable ( 157 IN SCRATCH_DATA *Sd, 158 IN UINT16 NumOfChar, 159 IN UINT8 *BitLen, 160 IN UINT16 TableBits, 161 OUT UINT16 *Table 162 ) 163 /*++ 164 165 Routine Description: 166 167 Creates Huffman Code mapping table according to code length array. 168 169 Arguments: 170 171 Sd - The global scratch data 172 NumOfChar - Number of symbols in the symbol set 173 BitLen - Code length array 174 TableBits - The width of the mapping table 175 Table - The table 176 177 Returns: 178 179 0 - OK. 180 BAD_TABLE - The table is corrupted. 181 182 --*/ 183 { 184 UINT16 Count[17]; 185 UINT16 Weight[17]; 186 UINT16 Start[18]; 187 UINT16 *Pointer; 188 UINT16 Index3; 189 UINT16 Index; 190 UINT16 Len; 191 UINT16 Char; 192 UINT16 JuBits; 193 UINT16 Avail; 194 UINT16 NextCode; 195 UINT16 Mask; 196 197 for (Index = 1; Index <= 16; Index++) { 198 Count[Index] = 0; 199 } 200 201 for (Index = 0; Index < NumOfChar; Index++) { 202 Count[BitLen[Index]]++; 203 } 204 205 Start[1] = 0; 206 207 for (Index = 1; Index <= 16; Index++) { 208 Start[Index + 1] = (UINT16) (Start[Index] + (Count[Index] << (16 - Index))); 209 } 210 211 if (Start[17] != 0) { 212 /*(1U << 16)*/ 213 return (UINT16) BAD_TABLE; 214 } 215 216 JuBits = (UINT16) (16 - TableBits); 217 218 for (Index = 1; Index <= TableBits; Index++) { 219 Start[Index] >>= JuBits; 220 Weight[Index] = (UINT16) (1U << (TableBits - Index)); 221 } 222 223 while (Index <= 16) { 224 Weight[Index] = (UINT16) (1U << (16 - Index)); 225 Index++; 226 } 227 228 Index = (UINT16) (Start[TableBits + 1] >> JuBits); 229 230 if (Index != 0) { 231 Index3 = (UINT16) (1U << TableBits); 232 while (Index != Index3) { 233 Table[Index++] = 0; 234 } 235 } 236 237 Avail = NumOfChar; 238 Mask = (UINT16) (1U << (15 - TableBits)); 239 240 for (Char = 0; Char < NumOfChar; Char++) { 241 242 Len = BitLen[Char]; 243 if (Len == 0) { 244 continue; 245 } 246 247 NextCode = (UINT16) (Start[Len] + Weight[Len]); 248 249 if (Len <= TableBits) { 250 251 for (Index = Start[Len]; Index < NextCode; Index++) { 252 Table[Index] = Char; 253 } 254 255 } else { 256 257 Index3 = Start[Len]; 258 Pointer = &Table[Index3 >> JuBits]; 259 Index = (UINT16) (Len - TableBits); 260 261 while (Index != 0) { 262 if (*Pointer == 0) { 263 Sd->mRight[Avail] = Sd->mLeft[Avail] = 0; 264 *Pointer = Avail++; 265 } 266 267 if (Index3 & Mask) { 268 Pointer = &Sd->mRight[*Pointer]; 269 } else { 270 Pointer = &Sd->mLeft[*Pointer]; 271 } 272 273 Index3 <<= 1; 274 Index--; 275 } 276 277 *Pointer = Char; 278 279 } 280 281 Start[Len] = NextCode; 282 } 283 // 284 // Succeeds 285 // 286 return 0; 287 } 288 289 STATIC 290 UINT32 291 DecodeP ( 292 IN SCRATCH_DATA *Sd 293 ) 294 /*++ 295 296 Routine Description: 297 298 Decodes a position value. 299 300 Arguments: 301 302 Sd - the global scratch data 303 304 Returns: 305 306 The position value decoded. 307 308 --*/ 309 { 310 UINT16 Val; 311 UINT32 Mask; 312 UINT32 Pos; 313 314 Val = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)]; 315 316 if (Val >= MAXNP) { 317 Mask = 1U << (BITBUFSIZ - 1 - 8); 318 319 do { 320 321 if (Sd->mBitBuf & Mask) { 322 Val = Sd->mRight[Val]; 323 } else { 324 Val = Sd->mLeft[Val]; 325 } 326 327 Mask >>= 1; 328 } while (Val >= MAXNP); 329 } 330 // 331 // Advance what we have read 332 // 333 FillBuf (Sd, Sd->mPTLen[Val]); 334 335 Pos = Val; 336 if (Val > 1) { 337 Pos = (UINT32) ((1U << (Val - 1)) + GetBits (Sd, (UINT16) (Val - 1))); 338 } 339 340 return Pos; 341 } 342 343 STATIC 344 UINT16 345 ReadPTLen ( 346 IN SCRATCH_DATA *Sd, 347 IN UINT16 nn, 348 IN UINT16 nbit, 349 IN UINT16 Special 350 ) 351 /*++ 352 353 Routine Description: 354 355 Reads code lengths for the Extra Set or the Position Set 356 357 Arguments: 358 359 Sd - The global scratch data 360 nn - Number of symbols 361 nbit - Number of bits needed to represent nn 362 Special - The special symbol that needs to be taken care of 363 364 Returns: 365 366 0 - OK. 367 BAD_TABLE - Table is corrupted. 368 369 --*/ 370 { 371 UINT16 Number; 372 UINT16 CharC; 373 UINT16 Index; 374 UINT32 Mask; 375 376 Number = (UINT16) GetBits (Sd, nbit); 377 378 if (Number == 0) { 379 CharC = (UINT16) GetBits (Sd, nbit); 380 381 for (Index = 0; Index < 256; Index++) { 382 Sd->mPTTable[Index] = CharC; 383 } 384 385 for (Index = 0; Index < nn; Index++) { 386 Sd->mPTLen[Index] = 0; 387 } 388 389 return 0; 390 } 391 392 Index = 0; 393 394 while (Index < Number) { 395 396 CharC = (UINT16) (Sd->mBitBuf >> (BITBUFSIZ - 3)); 397 398 if (CharC == 7) { 399 Mask = 1U << (BITBUFSIZ - 1 - 3); 400 while (Mask & Sd->mBitBuf) { 401 Mask >>= 1; 402 CharC += 1; 403 } 404 } 405 406 FillBuf (Sd, (UINT16) ((CharC < 7) ? 3 : CharC - 3)); 407 408 Sd->mPTLen[Index++] = (UINT8) CharC; 409 410 if (Index == Special) { 411 CharC = (UINT16) GetBits (Sd, 2); 412 CharC--; 413 while ((INT16) (CharC) >= 0) { 414 Sd->mPTLen[Index++] = 0; 415 CharC--; 416 } 417 } 418 } 419 420 while (Index < nn) { 421 Sd->mPTLen[Index++] = 0; 422 } 423 424 return MakeTable (Sd, nn, Sd->mPTLen, 8, Sd->mPTTable); 425 } 426 427 STATIC 428 VOID 429 ReadCLen ( 430 SCRATCH_DATA *Sd 431 ) 432 /*++ 433 434 Routine Description: 435 436 Reads code lengths for Char&Len Set. 437 438 Arguments: 439 440 Sd - the global scratch data 441 442 Returns: (VOID) 443 444 --*/ 445 { 446 UINT16 Number; 447 UINT16 CharC; 448 UINT16 Index; 449 UINT32 Mask; 450 451 Number = (UINT16) GetBits (Sd, CBIT); 452 453 if (Number == 0) { 454 CharC = (UINT16) GetBits (Sd, CBIT); 455 456 for (Index = 0; Index < NC; Index++) { 457 Sd->mCLen[Index] = 0; 458 } 459 460 for (Index = 0; Index < 4096; Index++) { 461 Sd->mCTable[Index] = CharC; 462 } 463 464 return ; 465 } 466 467 Index = 0; 468 while (Index < Number) { 469 470 CharC = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)]; 471 if (CharC >= NT) { 472 Mask = 1U << (BITBUFSIZ - 1 - 8); 473 474 do { 475 476 if (Mask & Sd->mBitBuf) { 477 CharC = Sd->mRight[CharC]; 478 } else { 479 CharC = Sd->mLeft[CharC]; 480 } 481 482 Mask >>= 1; 483 484 } while (CharC >= NT); 485 } 486 // 487 // Advance what we have read 488 // 489 FillBuf (Sd, Sd->mPTLen[CharC]); 490 491 if (CharC <= 2) { 492 493 if (CharC == 0) { 494 CharC = 1; 495 } else if (CharC == 1) { 496 CharC = (UINT16) (GetBits (Sd, 4) + 3); 497 } else if (CharC == 2) { 498 CharC = (UINT16) (GetBits (Sd, CBIT) + 20); 499 } 500 501 CharC--; 502 while ((INT16) (CharC) >= 0) { 503 Sd->mCLen[Index++] = 0; 504 CharC--; 505 } 506 507 } else { 508 509 Sd->mCLen[Index++] = (UINT8) (CharC - 2); 510 511 } 512 } 513 514 while (Index < NC) { 515 Sd->mCLen[Index++] = 0; 516 } 517 518 MakeTable (Sd, NC, Sd->mCLen, 12, Sd->mCTable); 519 520 return ; 521 } 522 523 STATIC 524 UINT16 525 DecodeC ( 526 SCRATCH_DATA *Sd 527 ) 528 /*++ 529 530 Routine Description: 531 532 Decode a character/length value. 533 534 Arguments: 535 536 Sd - The global scratch data. 537 538 Returns: 539 540 The value decoded. 541 542 --*/ 543 { 544 UINT16 Index2; 545 UINT32 Mask; 546 547 if (Sd->mBlockSize == 0) { 548 // 549 // Starting a new block 550 // 551 Sd->mBlockSize = (UINT16) GetBits (Sd, 16); 552 Sd->mBadTableFlag = ReadPTLen (Sd, NT, TBIT, 3); 553 if (Sd->mBadTableFlag != 0) { 554 return 0; 555 } 556 557 ReadCLen (Sd); 558 559 Sd->mBadTableFlag = ReadPTLen (Sd, MAXNP, mPbit, (UINT16) (-1)); 560 if (Sd->mBadTableFlag != 0) { 561 return 0; 562 } 563 } 564 565 Sd->mBlockSize--; 566 Index2 = Sd->mCTable[Sd->mBitBuf >> (BITBUFSIZ - 12)]; 567 568 if (Index2 >= NC) { 569 Mask = 1U << (BITBUFSIZ - 1 - 12); 570 571 do { 572 if (Sd->mBitBuf & Mask) { 573 Index2 = Sd->mRight[Index2]; 574 } else { 575 Index2 = Sd->mLeft[Index2]; 576 } 577 578 Mask >>= 1; 579 } while (Index2 >= NC); 580 } 581 // 582 // Advance what we have read 583 // 584 FillBuf (Sd, Sd->mCLen[Index2]); 585 586 return Index2; 587 } 588 589 STATIC 590 VOID 591 Decode ( 592 SCRATCH_DATA *Sd 593 ) 594 /*++ 595 596 Routine Description: 597 598 Decode the source data and put the resulting data into the destination buffer. 599 600 Arguments: 601 602 Sd - The global scratch data 603 604 Returns: (VOID) 605 606 --*/ 607 { 608 UINT16 BytesRemain; 609 UINT32 DataIdx; 610 UINT16 CharC; 611 612 BytesRemain = (UINT16) (-1); 613 614 DataIdx = 0; 615 616 for (;;) { 617 CharC = DecodeC (Sd); 618 if (Sd->mBadTableFlag != 0) { 619 return ; 620 } 621 622 if (CharC < 256) { 623 // 624 // Process an Original character 625 // 626 Sd->mDstBase[Sd->mOutBuf++] = (UINT8) CharC; 627 if (Sd->mOutBuf >= Sd->mOrigSize) { 628 return ; 629 } 630 631 } else { 632 // 633 // Process a Pointer 634 // 635 CharC = (UINT16) (CharC - (UINT8_MAX + 1 - THRESHOLD)); 636 637 BytesRemain = CharC; 638 639 DataIdx = Sd->mOutBuf - DecodeP (Sd) - 1; 640 641 BytesRemain--; 642 while ((INT16) (BytesRemain) >= 0) { 643 Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++]; 644 if (Sd->mOutBuf >= Sd->mOrigSize) { 645 return ; 646 } 647 648 BytesRemain--; 649 } 650 } 651 } 652 653 return ; 654 } 655 656 EFI_STATUS 657 GetInfo ( 658 IN VOID *Source, 659 IN UINT32 SrcSize, 660 OUT UINT32 *DstSize, 661 OUT UINT32 *ScratchSize 662 ) 663 /*++ 664 665 Routine Description: 666 667 The implementation of EFI_DECOMPRESS_PROTOCOL.GetInfo(). 668 669 Arguments: 670 671 Source - The source buffer containing the compressed data. 672 SrcSize - The size of source buffer 673 DstSize - The size of destination buffer. 674 ScratchSize - The size of scratch buffer. 675 676 Returns: 677 678 EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved. 679 EFI_INVALID_PARAMETER - The source data is corrupted 680 681 --*/ 682 { 683 UINT8 *Src; 684 685 *ScratchSize = sizeof (SCRATCH_DATA); 686 687 Src = Source; 688 if (SrcSize < 8) { 689 return EFI_INVALID_PARAMETER; 690 } 691 692 *DstSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24); 693 return EFI_SUCCESS; 694 } 695 696 EFI_STATUS 697 Decompress ( 698 IN VOID *Source, 699 IN UINT32 SrcSize, 700 IN OUT VOID *Destination, 701 IN UINT32 DstSize, 702 IN OUT VOID *Scratch, 703 IN UINT32 ScratchSize 704 ) 705 /*++ 706 707 Routine Description: 708 709 The implementation Efi and Tiano Decompress(). 710 711 Arguments: 712 713 Source - The source buffer containing the compressed data. 714 SrcSize - The size of source buffer 715 Destination - The destination buffer to store the decompressed data 716 DstSize - The size of destination buffer. 717 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data. 718 ScratchSize - The size of scratch buffer. 719 720 Returns: 721 722 EFI_SUCCESS - Decompression is successfull 723 EFI_INVALID_PARAMETER - The source data is corrupted 724 725 --*/ 726 { 727 UINT32 Index; 728 UINT32 CompSize; 729 UINT32 OrigSize; 730 EFI_STATUS Status; 731 SCRATCH_DATA *Sd; 732 UINT8 *Src; 733 UINT8 *Dst; 734 735 Status = EFI_SUCCESS; 736 Src = Source; 737 Dst = Destination; 738 739 if (ScratchSize < sizeof (SCRATCH_DATA)) { 740 return EFI_INVALID_PARAMETER; 741 } 742 743 Sd = (SCRATCH_DATA *) Scratch; 744 745 if (SrcSize < 8) { 746 return EFI_INVALID_PARAMETER; 747 } 748 749 CompSize = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24); 750 OrigSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24); 751 752 if (SrcSize < CompSize + 8) { 753 return EFI_INVALID_PARAMETER; 754 } 755 756 if (DstSize != OrigSize) { 757 return EFI_INVALID_PARAMETER; 758 } 759 760 Src = Src + 8; 761 762 for (Index = 0; Index < sizeof (SCRATCH_DATA); Index++) { 763 ((UINT8 *) Sd)[Index] = 0; 764 } 765 766 Sd->mSrcBase = Src; 767 Sd->mDstBase = Dst; 768 Sd->mCompSize = CompSize; 769 Sd->mOrigSize = OrigSize; 770 771 // 772 // Fill the first BITBUFSIZ bits 773 // 774 FillBuf (Sd, BITBUFSIZ); 775 776 // 777 // Decompress it 778 // 779 Decode (Sd); 780 781 if (Sd->mBadTableFlag != 0) { 782 // 783 // Something wrong with the source 784 // 785 Status = EFI_INVALID_PARAMETER; 786 } 787 788 return Status; 789 } 790 791 EFI_STATUS 792 EfiGetInfo ( 793 IN VOID *Source, 794 IN UINT32 SrcSize, 795 OUT UINT32 *DstSize, 796 OUT UINT32 *ScratchSize 797 ) 798 /*++ 799 800 Routine Description: 801 802 The implementation Efi Decompress GetInfo(). 803 804 Arguments: 805 806 Source - The source buffer containing the compressed data. 807 SrcSize - The size of source buffer 808 DstSize - The size of destination buffer. 809 ScratchSize - The size of scratch buffer. 810 811 Returns: 812 813 EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved. 814 EFI_INVALID_PARAMETER - The source data is corrupted 815 816 --*/ 817 { 818 return GetInfo (Source, SrcSize, DstSize, ScratchSize); 819 } 820 821 EFI_STATUS 822 TianoGetInfo ( 823 IN VOID *Source, 824 IN UINT32 SrcSize, 825 OUT UINT32 *DstSize, 826 OUT UINT32 *ScratchSize 827 ) 828 /*++ 829 830 Routine Description: 831 832 The implementation Tiano Decompress GetInfo(). 833 834 Arguments: 835 836 Source - The source buffer containing the compressed data. 837 SrcSize - The size of source buffer 838 DstSize - The size of destination buffer. 839 ScratchSize - The size of scratch buffer. 840 841 Returns: 842 843 EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved. 844 EFI_INVALID_PARAMETER - The source data is corrupted 845 846 --*/ 847 { 848 return GetInfo (Source, SrcSize, DstSize, ScratchSize); 849 } 850 851 EFI_STATUS 852 EfiDecompress ( 853 IN VOID *Source, 854 IN UINT32 SrcSize, 855 IN OUT VOID *Destination, 856 IN UINT32 DstSize, 857 IN OUT VOID *Scratch, 858 IN UINT32 ScratchSize 859 ) 860 /*++ 861 862 Routine Description: 863 864 The implementation of Efi Decompress(). 865 866 Arguments: 867 868 Source - The source buffer containing the compressed data. 869 SrcSize - The size of source buffer 870 Destination - The destination buffer to store the decompressed data 871 DstSize - The size of destination buffer. 872 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data. 873 ScratchSize - The size of scratch buffer. 874 875 Returns: 876 877 EFI_SUCCESS - Decompression is successfull 878 EFI_INVALID_PARAMETER - The source data is corrupted 879 880 --*/ 881 { 882 mPbit = EFIPBIT; 883 return Decompress (Source, SrcSize, Destination, DstSize, Scratch, ScratchSize); 884 } 885 886 EFI_STATUS 887 TianoDecompress ( 888 IN VOID *Source, 889 IN UINT32 SrcSize, 890 IN OUT VOID *Destination, 891 IN UINT32 DstSize, 892 IN OUT VOID *Scratch, 893 IN UINT32 ScratchSize 894 ) 895 /*++ 896 897 Routine Description: 898 899 The implementation of Tiano Decompress(). 900 901 Arguments: 902 903 Source - The source buffer containing the compressed data. 904 SrcSize - The size of source buffer 905 Destination - The destination buffer to store the decompressed data 906 DstSize - The size of destination buffer. 907 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data. 908 ScratchSize - The size of scratch buffer. 909 910 Returns: 911 912 EFI_SUCCESS - Decompression is successfull 913 EFI_INVALID_PARAMETER - The source data is corrupted 914 915 --*/ 916 { 917 mPbit = MAXPBIT; 918 return Decompress (Source, SrcSize, Destination, DstSize, Scratch, ScratchSize); 919 } 920 921 EFI_STATUS 922 Extract ( 923 IN VOID *Source, 924 IN UINT32 SrcSize, 925 OUT VOID **Destination, 926 OUT UINT32 *DstSize, 927 IN UINTN Algorithm 928 ) 929 { 930 VOID *Scratch; 931 UINT32 ScratchSize; 932 EFI_STATUS Status; 933 934 Status = EFI_SUCCESS; 935 switch (Algorithm) { 936 case 0: 937 *Destination = (VOID *)malloc(SrcSize); 938 if (*Destination != NULL) { 939 memcpy(*Destination, Source, SrcSize); 940 } else { 941 Status = EFI_OUT_OF_RESOURCES; 942 } 943 break; 944 case 1: 945 Status = EfiGetInfo(Source, SrcSize, DstSize, &ScratchSize); 946 if (Status == EFI_SUCCESS) { 947 Scratch = (VOID *)malloc(ScratchSize); 948 *Destination = (VOID *)malloc(*DstSize); 949 if (Scratch != NULL && *Destination != NULL) { 950 Status = EfiDecompress(Source, SrcSize, *Destination, *DstSize, Scratch, ScratchSize); 951 } else { 952 Status = EFI_OUT_OF_RESOURCES; 953 } 954 } 955 break; 956 case 2: 957 Status = TianoGetInfo(Source, SrcSize, DstSize, &ScratchSize); 958 if (Status == EFI_SUCCESS) { 959 Scratch = (VOID *)malloc(ScratchSize); 960 *Destination = (VOID *)malloc(*DstSize); 961 if (Scratch != NULL && *Destination != NULL) { 962 Status = TianoDecompress(Source, SrcSize, *Destination, *DstSize, Scratch, ScratchSize); 963 } else { 964 Status = EFI_OUT_OF_RESOURCES; 965 } 966 } 967 break; 968 default: 969 Status = EFI_INVALID_PARAMETER; 970 } 971 972 return Status; 973 } 974 975 976