]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Foundation/Library/Pei/PeiLib/Decompress.c
Update the copyright notice format
[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
d9ef3b7d 138#ifndef UINT8_MAX\r
3eb9473e 139#define UINT8_MAX 0xff\r
d9ef3b7d 140#endif\r
3eb9473e 141#define BAD_TABLE - 1\r
142\r
143//\r
144// C: Char&Len Set; P: Position Set; T: exTra Set\r
145//\r
146#define NC (0xff + MAXMATCH + 2 - THRESHOLD)\r
147#define CBIT 9\r
148#define MAXPBIT 5\r
149#define TBIT 5\r
150#define MAXNP ((1U << MAXPBIT) - 1)\r
151#define NT (CODE_BIT + 3)\r
152#if NT > MAXNP\r
153#define NPT NT\r
154#else\r
155#define NPT MAXNP\r
156#endif\r
157\r
158typedef struct {\r
159 UINT8 *mSrcBase; // Starting address of compressed data\r
160 UINT8 *mDstBase; // Starting address of decompressed data\r
161 UINT32 mOutBuf;\r
162 UINT32 mInBuf;\r
163\r
164 UINT16 mBitCount;\r
165 UINT32 mBitBuf;\r
166 UINT32 mSubBitBuf;\r
167 UINT16 mBlockSize;\r
168 UINT32 mCompSize;\r
169 UINT32 mOrigSize;\r
170\r
171 UINT16 mBadTableFlag;\r
172\r
173 UINT16 mLeft[2 * NC - 1];\r
174 UINT16 mRight[2 * NC - 1];\r
175 UINT8 mCLen[NC];\r
176 UINT8 mPTLen[NPT];\r
177 UINT16 mCTable[4096];\r
178 UINT16 mPTTable[256];\r
179\r
180 //\r
181 // The length of the field 'Position Set Code Length Array Size' in Block Header.\r
182 // For EFI 1.1 de/compression algorithm, mPBit = 4\r
183 // For Tiano de/compression algorithm, mPBit = 5\r
184 //\r
185 UINT8 mPBit;\r
186} SCRATCH_DATA;\r
187\r
188STATIC\r
189VOID\r
190FillBuf (\r
191 IN SCRATCH_DATA *Sd,\r
192 IN UINT16 NumOfBits\r
193 )\r
194/*++\r
195\r
196Routine Description:\r
197\r
198 Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source.\r
199\r
200Arguments:\r
201\r
202 Sd - The global scratch data\r
203 NumOfBits - The number of bits to shift and read.\r
204\r
205Returns: (VOID)\r
206\r
207--*/\r
208{\r
209 Sd->mBitBuf = (UINT32) (Sd->mBitBuf << NumOfBits);\r
210\r
211 while (NumOfBits > Sd->mBitCount) {\r
212\r
213 Sd->mBitBuf |= (UINT32) (Sd->mSubBitBuf << (NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount)));\r
214\r
215 if (Sd->mCompSize > 0) {\r
216 //\r
217 // Get 1 byte into SubBitBuf\r
218 //\r
219 Sd->mCompSize--;\r
220 Sd->mSubBitBuf = 0;\r
221 Sd->mSubBitBuf = Sd->mSrcBase[Sd->mInBuf++];\r
222 Sd->mBitCount = 8;\r
223\r
224 } else {\r
225 //\r
226 // No more bits from the source, just pad zero bit.\r
227 //\r
228 Sd->mSubBitBuf = 0;\r
229 Sd->mBitCount = 8;\r
230\r
231 }\r
232 }\r
233\r
234 Sd->mBitCount = (UINT16) (Sd->mBitCount - NumOfBits);\r
235 Sd->mBitBuf |= Sd->mSubBitBuf >> Sd->mBitCount;\r
236}\r
237\r
238STATIC\r
239UINT32\r
240GetBits (\r
241 IN SCRATCH_DATA *Sd,\r
242 IN UINT16 NumOfBits\r
243 )\r
244/*++\r
245\r
246Routine Description:\r
247\r
248 Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent \r
249 NumOfBits of bits from source. Returns NumOfBits of bits that are \r
250 popped out.\r
251\r
252Arguments:\r
253\r
254 Sd - The global scratch data.\r
255 NumOfBits - The number of bits to pop and read.\r
256\r
257Returns:\r
258\r
259 The bits that are popped out.\r
260\r
261--*/\r
262{\r
263 UINT32 OutBits;\r
264\r
265 OutBits = (UINT32) (Sd->mBitBuf >> (BITBUFSIZ - NumOfBits));\r
266\r
267 FillBuf (Sd, NumOfBits);\r
268\r
269 return OutBits;\r
270}\r
271\r
272STATIC\r
273UINT16\r
274MakeTable (\r
275 IN SCRATCH_DATA *Sd,\r
276 IN UINT16 NumOfChar,\r
277 IN UINT8 *BitLen,\r
278 IN UINT16 TableBits,\r
279 OUT UINT16 *Table\r
280 )\r
281/*++\r
282\r
283Routine Description:\r
284\r
285 Creates Huffman Code mapping table according to code length array.\r
286\r
287Arguments:\r
288\r
289 Sd - The global scratch data\r
290 NumOfChar - Number of symbols in the symbol set\r
291 BitLen - Code length array\r
292 TableBits - The width of the mapping table\r
293 Table - The table\r
294 \r
295Returns:\r
296 \r
297 0 - OK.\r
298 BAD_TABLE - The table is corrupted.\r
299\r
300--*/\r
301{\r
302 UINT16 Count[17];\r
303 UINT16 Weight[17];\r
304 UINT16 Start[18];\r
305 UINT16 *Pointer;\r
306 UINT16 Index3;\r
307 UINT16 Index;\r
308 UINT16 Len;\r
309 UINT16 Char;\r
310 UINT16 JuBits;\r
311 UINT16 Avail;\r
312 UINT16 NextCode;\r
313 UINT16 Mask;\r
314\r
315 for (Index = 1; Index <= 16; Index++) {\r
316 Count[Index] = 0;\r
317 }\r
318\r
319 for (Index = 0; Index < NumOfChar; Index++) {\r
320 Count[BitLen[Index]]++;\r
321 }\r
322\r
323 Start[1] = 0;\r
324\r
325 for (Index = 1; Index <= 16; Index++) {\r
326 Start[Index + 1] = (UINT16) (Start[Index] + (Count[Index] << (16 - Index)));\r
327 }\r
328\r
329 if (Start[17] != 0) {\r
330 /*(1U << 16)*/\r
331 return (UINT16) BAD_TABLE;\r
332 }\r
333\r
334 JuBits = (UINT16) (16 - TableBits);\r
335\r
336 for (Index = 1; Index <= TableBits; Index++) {\r
337 Start[Index] >>= JuBits;\r
338 Weight[Index] = (UINT16) (1U << (TableBits - Index));\r
339 }\r
340\r
341 while (Index <= 16) {\r
e1a09a0e 342 Weight[Index] = (UINT16) (1U << (16 - Index));\r
343 Index++;\r
3eb9473e 344 }\r
345\r
346 Index = (UINT16) (Start[TableBits + 1] >> JuBits);\r
347\r
348 if (Index != 0) {\r
349 Index3 = (UINT16) (1U << TableBits);\r
350 while (Index != Index3) {\r
351 Table[Index++] = 0;\r
352 }\r
353 }\r
354\r
355 Avail = NumOfChar;\r
356 Mask = (UINT16) (1U << (15 - TableBits));\r
357\r
358 for (Char = 0; Char < NumOfChar; Char++) {\r
359\r
360 Len = BitLen[Char];\r
361 if (Len == 0) {\r
362 continue;\r
363 }\r
364\r
365 NextCode = (UINT16) (Start[Len] + Weight[Len]);\r
366\r
367 if (Len <= TableBits) {\r
368\r
369 for (Index = Start[Len]; Index < NextCode; Index++) {\r
370 Table[Index] = Char;\r
371 }\r
372\r
373 } else {\r
374\r
375 Index3 = Start[Len];\r
376 Pointer = &Table[Index3 >> JuBits];\r
377 Index = (UINT16) (Len - TableBits);\r
378\r
379 while (Index != 0) {\r
380 if (*Pointer == 0) {\r
381 Sd->mRight[Avail] = Sd->mLeft[Avail] = 0;\r
382 *Pointer = Avail++;\r
383 }\r
384\r
385 if (Index3 & Mask) {\r
386 Pointer = &Sd->mRight[*Pointer];\r
387 } else {\r
388 Pointer = &Sd->mLeft[*Pointer];\r
389 }\r
390\r
391 Index3 <<= 1;\r
392 Index--;\r
393 }\r
394\r
395 *Pointer = Char;\r
396\r
397 }\r
398\r
399 Start[Len] = NextCode;\r
400 }\r
401 //\r
402 // Succeeds\r
403 //\r
404 return 0;\r
405}\r
406\r
407STATIC\r
408UINT32\r
409DecodeP (\r
410 IN SCRATCH_DATA *Sd\r
411 )\r
412/*++\r
413\r
414Routine Description:\r
415\r
416 Decodes a position value.\r
417\r
418Arguments:\r
419\r
420 Sd - the global scratch data\r
421\r
422Returns:\r
423\r
424 The position value decoded.\r
425\r
426--*/\r
427{\r
428 UINT16 Val;\r
429 UINT32 Mask;\r
430 UINT32 Pos;\r
431\r
432 Val = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];\r
433\r
434 if (Val >= MAXNP) {\r
435 Mask = 1U << (BITBUFSIZ - 1 - 8);\r
436\r
437 do {\r
438\r
439 if (Sd->mBitBuf & Mask) {\r
440 Val = Sd->mRight[Val];\r
441 } else {\r
442 Val = Sd->mLeft[Val];\r
443 }\r
444\r
445 Mask >>= 1;\r
446 } while (Val >= MAXNP);\r
447 }\r
448 //\r
449 // Advance what we have read\r
450 //\r
451 FillBuf (Sd, Sd->mPTLen[Val]);\r
452\r
453 Pos = Val;\r
454 if (Val > 1) {\r
455 Pos = (UINT32) ((1U << (Val - 1)) + GetBits (Sd, (UINT16) (Val - 1)));\r
456 }\r
457\r
458 return Pos;\r
459}\r
460\r
461STATIC\r
462UINT16\r
463ReadPTLen (\r
464 IN SCRATCH_DATA *Sd,\r
465 IN UINT16 nn,\r
466 IN UINT16 nbit,\r
467 IN UINT16 Special\r
468 )\r
469/*++\r
470\r
471Routine Description:\r
472\r
473 Reads code lengths for the Extra Set or the Position Set\r
474\r
475Arguments:\r
476\r
477 Sd - The global scratch data\r
478 nn - Number of symbols\r
479 nbit - Number of bits needed to represent nn\r
480 Special - The special symbol that needs to be taken care of \r
481\r
482Returns:\r
483\r
484 0 - OK.\r
485 BAD_TABLE - Table is corrupted.\r
486\r
487--*/\r
488{\r
489 UINT16 Number;\r
490 UINT16 CharC;\r
491 UINT16 Index;\r
492 UINT32 Mask;\r
493\r
494 Number = (UINT16) GetBits (Sd, nbit);\r
495\r
496 if (Number == 0) {\r
497 CharC = (UINT16) GetBits (Sd, nbit);\r
498\r
499 for (Index = 0; Index < 256; Index++) {\r
500 Sd->mPTTable[Index] = CharC;\r
501 }\r
502\r
503 for (Index = 0; Index < nn; Index++) {\r
504 Sd->mPTLen[Index] = 0;\r
505 }\r
506\r
507 return 0;\r
508 }\r
509\r
510 Index = 0;\r
511\r
512 while (Index < Number) {\r
513\r
514 CharC = (UINT16) (Sd->mBitBuf >> (BITBUFSIZ - 3));\r
515\r
516 if (CharC == 7) {\r
517 Mask = 1U << (BITBUFSIZ - 1 - 3);\r
518 while (Mask & Sd->mBitBuf) {\r
519 Mask >>= 1;\r
520 CharC += 1;\r
521 }\r
522 }\r
523\r
524 FillBuf (Sd, (UINT16) ((CharC < 7) ? 3 : CharC - 3));\r
525\r
526 Sd->mPTLen[Index++] = (UINT8) CharC;\r
527\r
528 if (Index == Special) {\r
529 CharC = (UINT16) GetBits (Sd, 2);\r
530 while ((INT16) (--CharC) >= 0) {\r
531 Sd->mPTLen[Index++] = 0;\r
532 }\r
533 }\r
534 }\r
535\r
536 while (Index < nn) {\r
537 Sd->mPTLen[Index++] = 0;\r
538 }\r
539\r
540 return MakeTable (Sd, nn, Sd->mPTLen, 8, Sd->mPTTable);\r
541}\r
542\r
543STATIC\r
544VOID\r
545ReadCLen (\r
546 SCRATCH_DATA *Sd\r
547 )\r
548/*++\r
549\r
550Routine Description:\r
551\r
552 Reads code lengths for Char&Len Set.\r
553\r
554Arguments:\r
555\r
556 Sd - the global scratch data\r
557\r
558Returns: (VOID)\r
559\r
560--*/\r
561{\r
562 UINT16 Number;\r
563 UINT16 CharC;\r
564 UINT16 Index;\r
565 UINT32 Mask;\r
566\r
567 Number = (UINT16) GetBits (Sd, CBIT);\r
568\r
569 if (Number == 0) {\r
570 CharC = (UINT16) GetBits (Sd, CBIT);\r
571\r
572 for (Index = 0; Index < NC; Index++) {\r
573 Sd->mCLen[Index] = 0;\r
574 }\r
575\r
576 for (Index = 0; Index < 4096; Index++) {\r
577 Sd->mCTable[Index] = CharC;\r
578 }\r
579\r
580 return ;\r
581 }\r
582\r
583 Index = 0;\r
584 while (Index < Number) {\r
585\r
586 CharC = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];\r
587 if (CharC >= NT) {\r
588 Mask = 1U << (BITBUFSIZ - 1 - 8);\r
589\r
590 do {\r
591\r
592 if (Mask & Sd->mBitBuf) {\r
593 CharC = Sd->mRight[CharC];\r
594 } else {\r
595 CharC = Sd->mLeft[CharC];\r
596 }\r
597\r
598 Mask >>= 1;\r
599\r
600 } while (CharC >= NT);\r
601 }\r
602 //\r
603 // Advance what we have read\r
604 //\r
605 FillBuf (Sd, Sd->mPTLen[CharC]);\r
606\r
607 if (CharC <= 2) {\r
608\r
609 if (CharC == 0) {\r
610 CharC = 1;\r
611 } else if (CharC == 1) {\r
612 CharC = (UINT16) (GetBits (Sd, 4) + 3);\r
613 } else if (CharC == 2) {\r
614 CharC = (UINT16) (GetBits (Sd, CBIT) + 20);\r
615 }\r
616\r
617 while ((INT16) (--CharC) >= 0) {\r
618 Sd->mCLen[Index++] = 0;\r
619 }\r
620\r
621 } else {\r
622\r
623 Sd->mCLen[Index++] = (UINT8) (CharC - 2);\r
624\r
625 }\r
626 }\r
627\r
628 while (Index < NC) {\r
629 Sd->mCLen[Index++] = 0;\r
630 }\r
631\r
632 MakeTable (Sd, NC, Sd->mCLen, 12, Sd->mCTable);\r
633\r
634 return ;\r
635}\r
636\r
637STATIC\r
638UINT16\r
639DecodeC (\r
640 SCRATCH_DATA *Sd\r
641 )\r
642/*++\r
643\r
644Routine Description:\r
645\r
646 Decode a character/length value.\r
647\r
648Arguments:\r
649\r
650 Sd - The global scratch data.\r
651\r
652Returns:\r
653\r
654 The value decoded.\r
655\r
656--*/\r
657{\r
658 UINT16 Index2;\r
659 UINT32 Mask;\r
660\r
661 if (Sd->mBlockSize == 0) {\r
662 //\r
663 // Starting a new block\r
664 //\r
665 Sd->mBlockSize = (UINT16) GetBits (Sd, 16);\r
666 Sd->mBadTableFlag = ReadPTLen (Sd, NT, TBIT, 3);\r
667 if (Sd->mBadTableFlag != 0) {\r
668 return 0;\r
669 }\r
670\r
671 ReadCLen (Sd);\r
672\r
673 Sd->mBadTableFlag = ReadPTLen (Sd, MAXNP, Sd->mPBit, (UINT16) (-1));\r
674 if (Sd->mBadTableFlag != 0) {\r
675 return 0;\r
676 }\r
677 }\r
678\r
679 Sd->mBlockSize--;\r
680 Index2 = Sd->mCTable[Sd->mBitBuf >> (BITBUFSIZ - 12)];\r
681\r
682 if (Index2 >= NC) {\r
683 Mask = 1U << (BITBUFSIZ - 1 - 12);\r
684\r
685 do {\r
686 if (Sd->mBitBuf & Mask) {\r
687 Index2 = Sd->mRight[Index2];\r
688 } else {\r
689 Index2 = Sd->mLeft[Index2];\r
690 }\r
691\r
692 Mask >>= 1;\r
693 } while (Index2 >= NC);\r
694 }\r
695 //\r
696 // Advance what we have read\r
697 //\r
698 FillBuf (Sd, Sd->mCLen[Index2]);\r
699\r
700 return Index2;\r
701}\r
702\r
703STATIC\r
704VOID\r
705Decode (\r
706 SCRATCH_DATA *Sd\r
707 )\r
708/*++\r
709\r
710Routine Description:\r
711\r
712 Decode the source data and put the resulting data into the destination buffer.\r
713\r
714Arguments:\r
715\r
716 Sd - The global scratch data\r
717\r
718Returns: (VOID)\r
719\r
720 --*/\r
721{\r
722 UINT16 BytesRemain;\r
723 UINT32 DataIdx;\r
724 UINT16 CharC;\r
725\r
726 BytesRemain = (UINT16) (-1);\r
727\r
728 DataIdx = 0;\r
729\r
730 for (;;) {\r
731 CharC = DecodeC (Sd);\r
732 if (Sd->mBadTableFlag != 0) {\r
733 return ;\r
734 }\r
735\r
736 if (CharC < 256) {\r
737 //\r
738 // Process an Original character\r
739 //\r
740 if (Sd->mOutBuf >= Sd->mOrigSize) {\r
741 return ;\r
742 } else {\r
743 Sd->mDstBase[Sd->mOutBuf++] = (UINT8) CharC;\r
744 }\r
745\r
746 } else {\r
747 //\r
748 // Process a Pointer\r
749 //\r
750 CharC = (UINT16) (CharC - (UINT8_MAX + 1 - THRESHOLD));\r
751\r
752 BytesRemain = CharC;\r
753\r
754 DataIdx = Sd->mOutBuf - DecodeP (Sd) - 1;\r
755\r
756 BytesRemain--;\r
757 while ((INT16) (BytesRemain) >= 0) {\r
758 Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];\r
759 if (Sd->mOutBuf >= Sd->mOrigSize) {\r
760 return ;\r
761 }\r
762\r
763 BytesRemain--;\r
764 }\r
765 }\r
766 }\r
3eb9473e 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