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