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