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