Decompress.c 21 KB

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