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