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