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