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