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