efidecompress.c 23 KB

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