Decompress.c 20 KB

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