]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Foundation/Library/Pei/PeiLib/Decompress.c
Remove ambiguous auto-increment usage. (gcc warning)
[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
765\r
766 return ;\r
767}\r
768\r
769EFI_STATUS\r
770GetInfo (\r
771 IN VOID *Source,\r
772 IN UINT32 SrcSize,\r
773 OUT UINT32 *DstSize,\r
774 OUT UINT32 *ScratchSize\r
775 )\r
776/*++\r
777\r
778Routine Description:\r
779\r
780 The internal implementation of *_DECOMPRESS_PROTOCOL.GetInfo().\r
781\r
782Arguments:\r
783\r
784 Source - The source buffer containing the compressed data.\r
785 SrcSize - The size of source buffer\r
786 DstSize - The size of destination buffer.\r
787 ScratchSize - The size of scratch buffer.\r
788\r
789Returns:\r
790\r
791 EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved.\r
792 EFI_INVALID_PARAMETER - The source data is corrupted\r
793\r
794--*/\r
795{\r
796 UINT8 *Src;\r
797\r
798 *ScratchSize = sizeof (SCRATCH_DATA);\r
799\r
800 Src = Source;\r
801 if (SrcSize < 8) {\r
802 return EFI_INVALID_PARAMETER;\r
803 }\r
804\r
805 *DstSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);\r
806 return EFI_SUCCESS;\r
807}\r
808\r
809EFI_STATUS\r
810Decompress (\r
811 IN VOID *Source,\r
812 IN UINT32 SrcSize,\r
813 IN OUT VOID *Destination,\r
814 IN UINT32 DstSize,\r
815 IN OUT VOID *Scratch,\r
816 IN UINT32 ScratchSize,\r
817 IN UINT8 Version\r
818 )\r
819/*++\r
820\r
821Routine Description:\r
822\r
823 The internal implementation of *_DECOMPRESS_PROTOCOL.Decompress().\r
824\r
825Arguments:\r
826\r
827 Source - The source buffer containing the compressed data.\r
828 SrcSize - The size of source buffer\r
829 Destination - The destination buffer to store the decompressed data\r
830 DstSize - The size of destination buffer.\r
831 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.\r
832 ScratchSize - The size of scratch buffer.\r
833 Version - The version of de/compression algorithm.\r
834 Version 1 for EFI 1.1 de/compression algorithm.\r
835 Version 2 for Tiano de/compression algorithm.\r
836\r
837Returns:\r
838\r
839 EFI_SUCCESS - Decompression is successfull\r
840 EFI_INVALID_PARAMETER - The source data is corrupted\r
841\r
842--*/\r
843{\r
844 UINT32 Index;\r
845 UINT32 CompSize;\r
846 UINT32 OrigSize;\r
847 EFI_STATUS Status;\r
848 SCRATCH_DATA *Sd;\r
849 UINT8 *Src;\r
850 UINT8 *Dst;\r
851\r
852 Status = EFI_SUCCESS;\r
853 Src = Source;\r
854 Dst = Destination;\r
855\r
856 if (ScratchSize < sizeof (SCRATCH_DATA)) {\r
857 return EFI_INVALID_PARAMETER;\r
858 }\r
859\r
860 Sd = (SCRATCH_DATA *) Scratch;\r
861\r
862 if (SrcSize < 8) {\r
863 return EFI_INVALID_PARAMETER;\r
864 }\r
865\r
866 CompSize = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);\r
867 OrigSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);\r
868\r
869 //\r
870 // If compressed file size is 0, return\r
871 //\r
872 if (OrigSize == 0) {\r
873 return Status;\r
874 }\r
875\r
876 if (SrcSize < CompSize + 8) {\r
877 return EFI_INVALID_PARAMETER;\r
878 }\r
879\r
880 if (DstSize != OrigSize) {\r
881 return EFI_INVALID_PARAMETER;\r
882 }\r
883\r
884 Src = Src + 8;\r
885\r
886 for (Index = 0; Index < sizeof (SCRATCH_DATA); Index++) {\r
887 ((UINT8 *) Sd)[Index] = 0;\r
888 }\r
889 //\r
890 // The length of the field 'Position Set Code Length Array Size' in Block Header.\r
891 // For EFI 1.1 de/compression algorithm(Version 1), mPBit = 4\r
892 // For Tiano de/compression algorithm(Version 2), mPBit = 5\r
893 //\r
894 switch (Version) {\r
895 case 1:\r
896 Sd->mPBit = 4;\r
897 break;\r
898\r
899 case 2:\r
900 Sd->mPBit = 5;\r
901 break;\r
902\r
903 default:\r
904 //\r
905 // Currently, only have 2 versions\r
906 //\r
907 return EFI_INVALID_PARAMETER;\r
908 }\r
909\r
910 Sd->mSrcBase = Src;\r
911 Sd->mDstBase = Dst;\r
912 Sd->mCompSize = CompSize;\r
913 Sd->mOrigSize = OrigSize;\r
914\r
915 //\r
916 // Fill the first BITBUFSIZ bits\r
917 //\r
918 FillBuf (Sd, BITBUFSIZ);\r
919\r
920 //\r
921 // Decompress it\r
922 //\r
923 Decode (Sd);\r
924\r
925 if (Sd->mBadTableFlag != 0) {\r
926 //\r
927 // Something wrong with the source\r
928 //\r
929 Status = EFI_INVALID_PARAMETER;\r
930 }\r
931\r
932 return Status;\r
933}\r
934\r
935EFI_STATUS\r
936EFIAPI\r
937EfiGetInfo (\r
938 IN EFI_DECOMPRESS_PROTOCOL *This,\r
939 IN VOID *Source,\r
940 IN UINT32 SrcSize,\r
941 OUT UINT32 *DstSize,\r
942 OUT UINT32 *ScratchSize\r
943 )\r
944/*++\r
945\r
946Routine Description:\r
947\r
948 The implementation of EFI_DECOMPRESS_PROTOCOL.GetInfo().\r
949\r
950Arguments:\r
951\r
952 This - The protocol instance pointer\r
953 Source - The source buffer containing the compressed data.\r
954 SrcSize - The size of source buffer\r
955 DstSize - The size of destination buffer.\r
956 ScratchSize - The size of scratch buffer.\r
957\r
958Returns:\r
959\r
960 EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved.\r
961 EFI_INVALID_PARAMETER - The source data is corrupted\r
962\r
963--*/\r
964{\r
965 return GetInfo (\r
966 Source,\r
967 SrcSize,\r
968 DstSize,\r
969 ScratchSize\r
970 );\r
971}\r
972\r
973EFI_STATUS\r
974EFIAPI\r
975EfiDecompress (\r
976 IN EFI_DECOMPRESS_PROTOCOL *This,\r
977 IN VOID *Source,\r
978 IN UINT32 SrcSize,\r
979 IN OUT VOID *Destination,\r
980 IN UINT32 DstSize,\r
981 IN OUT VOID *Scratch,\r
982 IN UINT32 ScratchSize\r
983 )\r
984/*++\r
985\r
986Routine Description:\r
987\r
988 The implementation of EFI_DECOMPRESS_PROTOCOL.Decompress().\r
989\r
990Arguments:\r
991\r
992 This - The protocol instance pointer\r
993 Source - The source buffer containing the compressed data.\r
994 SrcSize - The size of source buffer\r
995 Destination - The destination buffer to store the decompressed data\r
996 DstSize - The size of destination buffer.\r
997 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.\r
998 ScratchSize - The size of scratch buffer.\r
999\r
1000Returns:\r
1001\r
1002 EFI_SUCCESS - Decompression is successfull\r
1003 EFI_INVALID_PARAMETER - The source data is corrupted\r
1004\r
1005--*/\r
1006{\r
1007 //\r
1008 // For EFI 1.1 de/compression algorithm, the version is 1.\r
1009 //\r
1010 return Decompress (\r
1011 Source,\r
1012 SrcSize,\r
1013 Destination,\r
1014 DstSize,\r
1015 Scratch,\r
1016 ScratchSize,\r
1017 1\r
1018 );\r
1019}\r
1020\r
1021EFI_STATUS\r
1022EFIAPI\r
1023TianoGetInfo (\r
1024 IN EFI_TIANO_DECOMPRESS_PROTOCOL *This,\r
1025 IN VOID *Source,\r
1026 IN UINT32 SrcSize,\r
1027 OUT UINT32 *DstSize,\r
1028 OUT UINT32 *ScratchSize\r
1029 )\r
1030/*++\r
1031\r
1032Routine Description:\r
1033\r
1034 The implementation of EFI_TIANO_DECOMPRESS_PROTOCOL.GetInfo().\r
1035\r
1036Arguments:\r
1037\r
1038 This - The protocol instance pointer\r
1039 Source - The source buffer containing the compressed data.\r
1040 SrcSize - The size of source buffer\r
1041 DstSize - The size of destination buffer.\r
1042 ScratchSize - The size of scratch buffer.\r
1043\r
1044Returns:\r
1045\r
1046 EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved.\r
1047 EFI_INVALID_PARAMETER - The source data is corrupted\r
1048\r
1049--*/\r
1050{\r
1051 return GetInfo (\r
1052 Source,\r
1053 SrcSize,\r
1054 DstSize,\r
1055 ScratchSize\r
1056 );\r
1057}\r
1058\r
1059EFI_STATUS\r
1060EFIAPI\r
1061TianoDecompress (\r
1062 IN EFI_TIANO_DECOMPRESS_PROTOCOL *This,\r
1063 IN VOID *Source,\r
1064 IN UINT32 SrcSize,\r
1065 IN OUT VOID *Destination,\r
1066 IN UINT32 DstSize,\r
1067 IN OUT VOID *Scratch,\r
1068 IN UINT32 ScratchSize\r
1069 )\r
1070/*++\r
1071\r
1072Routine Description:\r
1073\r
1074 The implementation of EFI_TIANO_DECOMPRESS_PROTOCOL.Decompress().\r
1075\r
1076Arguments:\r
1077\r
1078 This - The protocol instance pointer\r
1079 Source - The source buffer containing the compressed data.\r
1080 SrcSize - The size of source buffer\r
1081 Destination - The destination buffer to store the decompressed data\r
1082 DstSize - The size of destination buffer.\r
1083 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.\r
1084 ScratchSize - The size of scratch buffer.\r
1085\r
1086Returns:\r
1087\r
1088 EFI_SUCCESS - Decompression is successfull\r
1089 EFI_INVALID_PARAMETER - The source data is corrupted\r
1090\r
1091--*/\r
1092{\r
1093 //\r
1094 // For Tiano de/compression algorithm, the version is 2.\r
1095 //\r
1096 return Decompress (\r
1097 Source,\r
1098 SrcSize,\r
1099 Destination,\r
1100 DstSize,\r
1101 Scratch,\r
1102 ScratchSize,\r
1103 2\r
1104 );\r
1105}\r