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