]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Foundation/Library/Pei/PeiLib/Decompress.c
EdkCompatibilityPkg: Fix typos in comments
[mirror_edk2.git] / EdkCompatibilityPkg / Foundation / Library / Pei / PeiLib / Decompress.c
CommitLineData
3eb9473e 1/*++\r
2\r
4ac4deb7 3Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>\r
4ea9375a 4This program and the accompanying materials \r
3eb9473e 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
4ac4deb7
LG
315 //\r
316 // TableBits should not be greater than 16.\r
317 //\r
318 if (TableBits >= (sizeof (Count)/sizeof (UINT16))) {\r
319 return (UINT16) BAD_TABLE;\r
320 }\r
321 \r
322 //\r
323 // Initialize Count array starting from Index 0, as there is a possibility of Count array being uninitialized.\r
324 //\r
325 for (Index = 0; Index <= 16; Index++) {\r
3eb9473e 326 Count[Index] = 0;\r
327 }\r
328\r
329 for (Index = 0; Index < NumOfChar; Index++) {\r
4ac4deb7
LG
330 //\r
331 // Count array index should not be greater than or equal to its size.\r
332 //\r
333 if (BitLen[Index] < (sizeof (Count)/sizeof (UINT16))) {\r
334 Count[BitLen[Index]]++;\r
335 } else {\r
336 return (UINT16) BAD_TABLE;\r
337 }\r
3eb9473e 338 }\r
339\r
4ac4deb7 340 Start[0] = 0;\r
3eb9473e 341 Start[1] = 0;\r
342\r
343 for (Index = 1; Index <= 16; Index++) {\r
344 Start[Index + 1] = (UINT16) (Start[Index] + (Count[Index] << (16 - Index)));\r
345 }\r
346\r
347 if (Start[17] != 0) {\r
348 /*(1U << 16)*/\r
349 return (UINT16) BAD_TABLE;\r
350 }\r
351\r
352 JuBits = (UINT16) (16 - TableBits);\r
353\r
354 for (Index = 1; Index <= TableBits; Index++) {\r
355 Start[Index] >>= JuBits;\r
356 Weight[Index] = (UINT16) (1U << (TableBits - Index));\r
357 }\r
358\r
359 while (Index <= 16) {\r
e1a09a0e 360 Weight[Index] = (UINT16) (1U << (16 - Index));\r
361 Index++;\r
3eb9473e 362 }\r
363\r
364 Index = (UINT16) (Start[TableBits + 1] >> JuBits);\r
365\r
366 if (Index != 0) {\r
367 Index3 = (UINT16) (1U << TableBits);\r
368 while (Index != Index3) {\r
369 Table[Index++] = 0;\r
370 }\r
371 }\r
372\r
373 Avail = NumOfChar;\r
374 Mask = (UINT16) (1U << (15 - TableBits));\r
375\r
376 for (Char = 0; Char < NumOfChar; Char++) {\r
377\r
378 Len = BitLen[Char];\r
4ac4deb7 379 if (Len == 0 || Len >= 17) {\r
3eb9473e 380 continue;\r
381 }\r
382\r
383 NextCode = (UINT16) (Start[Len] + Weight[Len]);\r
384\r
385 if (Len <= TableBits) {\r
386\r
387 for (Index = Start[Len]; Index < NextCode; Index++) {\r
388 Table[Index] = Char;\r
389 }\r
390\r
391 } else {\r
392\r
393 Index3 = Start[Len];\r
394 Pointer = &Table[Index3 >> JuBits];\r
395 Index = (UINT16) (Len - TableBits);\r
396\r
397 while (Index != 0) {\r
4ac4deb7
LG
398 //\r
399 // Avail should be lesser than size of mRight and mLeft to prevent buffer overflow.\r
400 //\r
401 if ((*Pointer == 0) && (Avail < sizeof (Sd->mRight)/sizeof (UINT16)) && (Avail < sizeof (Sd->mLeft)/sizeof (UINT16))) {\r
3eb9473e 402 Sd->mRight[Avail] = Sd->mLeft[Avail] = 0;\r
403 *Pointer = Avail++;\r
404 }\r
405\r
4ac4deb7
LG
406 //\r
407 // *Pointer should be lesser than size of mRight and mLeft to prevent buffer overflow.\r
408 //\r
409 if ((Index3 & Mask) && (*Pointer < (sizeof (Sd->mRight)/sizeof (UINT16)))) {\r
3eb9473e 410 Pointer = &Sd->mRight[*Pointer];\r
4ac4deb7 411 } else if (*Pointer < (sizeof (Sd->mLeft)/sizeof (UINT16))) {\r
3eb9473e 412 Pointer = &Sd->mLeft[*Pointer];\r
413 }\r
414\r
415 Index3 <<= 1;\r
416 Index--;\r
417 }\r
418\r
419 *Pointer = Char;\r
420\r
421 }\r
422\r
423 Start[Len] = NextCode;\r
424 }\r
425 //\r
426 // Succeeds\r
427 //\r
428 return 0;\r
429}\r
430\r
431STATIC\r
432UINT32\r
433DecodeP (\r
434 IN SCRATCH_DATA *Sd\r
435 )\r
436/*++\r
437\r
438Routine Description:\r
439\r
440 Decodes a position value.\r
441\r
442Arguments:\r
443\r
444 Sd - the global scratch data\r
445\r
446Returns:\r
447\r
448 The position value decoded.\r
449\r
450--*/\r
451{\r
452 UINT16 Val;\r
453 UINT32 Mask;\r
454 UINT32 Pos;\r
455\r
456 Val = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];\r
457\r
458 if (Val >= MAXNP) {\r
459 Mask = 1U << (BITBUFSIZ - 1 - 8);\r
460\r
461 do {\r
462\r
463 if (Sd->mBitBuf & Mask) {\r
464 Val = Sd->mRight[Val];\r
465 } else {\r
466 Val = Sd->mLeft[Val];\r
467 }\r
468\r
469 Mask >>= 1;\r
470 } while (Val >= MAXNP);\r
471 }\r
472 //\r
473 // Advance what we have read\r
474 //\r
475 FillBuf (Sd, Sd->mPTLen[Val]);\r
476\r
477 Pos = Val;\r
478 if (Val > 1) {\r
479 Pos = (UINT32) ((1U << (Val - 1)) + GetBits (Sd, (UINT16) (Val - 1)));\r
480 }\r
481\r
482 return Pos;\r
483}\r
484\r
485STATIC\r
486UINT16\r
487ReadPTLen (\r
488 IN SCRATCH_DATA *Sd,\r
489 IN UINT16 nn,\r
490 IN UINT16 nbit,\r
491 IN UINT16 Special\r
492 )\r
493/*++\r
494\r
495Routine Description:\r
496\r
497 Reads code lengths for the Extra Set or the Position Set\r
498\r
499Arguments:\r
500\r
501 Sd - The global scratch data\r
502 nn - Number of symbols\r
503 nbit - Number of bits needed to represent nn\r
504 Special - The special symbol that needs to be taken care of \r
505\r
506Returns:\r
507\r
508 0 - OK.\r
509 BAD_TABLE - Table is corrupted.\r
510\r
511--*/\r
512{\r
513 UINT16 Number;\r
514 UINT16 CharC;\r
515 UINT16 Index;\r
516 UINT32 Mask;\r
517\r
518 Number = (UINT16) GetBits (Sd, nbit);\r
519\r
4ac4deb7
LG
520 if ((Number > sizeof (Sd->mPTLen)) || (nn > sizeof (Sd->mPTLen))) {\r
521 //\r
522 // Fail if Number or nn is greater than size of mPTLen\r
523 //\r
524 return (UINT16) BAD_TABLE;\r
525 }\r
526\r
3eb9473e 527 if (Number == 0) {\r
528 CharC = (UINT16) GetBits (Sd, nbit);\r
529\r
530 for (Index = 0; Index < 256; Index++) {\r
531 Sd->mPTTable[Index] = CharC;\r
532 }\r
533\r
534 for (Index = 0; Index < nn; Index++) {\r
535 Sd->mPTLen[Index] = 0;\r
536 }\r
537\r
538 return 0;\r
539 }\r
540\r
541 Index = 0;\r
542\r
543 while (Index < Number) {\r
544\r
545 CharC = (UINT16) (Sd->mBitBuf >> (BITBUFSIZ - 3));\r
546\r
547 if (CharC == 7) {\r
548 Mask = 1U << (BITBUFSIZ - 1 - 3);\r
549 while (Mask & Sd->mBitBuf) {\r
550 Mask >>= 1;\r
551 CharC += 1;\r
552 }\r
553 }\r
554\r
555 FillBuf (Sd, (UINT16) ((CharC < 7) ? 3 : CharC - 3));\r
556\r
557 Sd->mPTLen[Index++] = (UINT8) CharC;\r
558\r
559 if (Index == Special) {\r
560 CharC = (UINT16) GetBits (Sd, 2);\r
561 while ((INT16) (--CharC) >= 0) {\r
4ac4deb7
LG
562 if (Index >= sizeof (Sd->mPTLen)) {\r
563 //\r
564 // Fail if Index is greater than or equal to mPTLen\r
565 //\r
566 return (UINT16) BAD_TABLE;\r
567 }\r
3eb9473e 568 Sd->mPTLen[Index++] = 0;\r
569 }\r
570 }\r
571 }\r
572\r
573 while (Index < nn) {\r
574 Sd->mPTLen[Index++] = 0;\r
575 }\r
576\r
577 return MakeTable (Sd, nn, Sd->mPTLen, 8, Sd->mPTTable);\r
578}\r
579\r
580STATIC\r
581VOID\r
582ReadCLen (\r
583 SCRATCH_DATA *Sd\r
584 )\r
585/*++\r
586\r
587Routine Description:\r
588\r
589 Reads code lengths for Char&Len Set.\r
590\r
591Arguments:\r
592\r
593 Sd - the global scratch data\r
594\r
595Returns: (VOID)\r
596\r
597--*/\r
598{\r
599 UINT16 Number;\r
600 UINT16 CharC;\r
601 UINT16 Index;\r
602 UINT32 Mask;\r
603\r
604 Number = (UINT16) GetBits (Sd, CBIT);\r
605\r
606 if (Number == 0) {\r
607 CharC = (UINT16) GetBits (Sd, CBIT);\r
608\r
609 for (Index = 0; Index < NC; Index++) {\r
610 Sd->mCLen[Index] = 0;\r
611 }\r
612\r
613 for (Index = 0; Index < 4096; Index++) {\r
614 Sd->mCTable[Index] = CharC;\r
615 }\r
616\r
617 return ;\r
618 }\r
619\r
620 Index = 0;\r
621 while (Index < Number) {\r
622\r
623 CharC = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];\r
624 if (CharC >= NT) {\r
625 Mask = 1U << (BITBUFSIZ - 1 - 8);\r
626\r
627 do {\r
628\r
629 if (Mask & Sd->mBitBuf) {\r
630 CharC = Sd->mRight[CharC];\r
631 } else {\r
632 CharC = Sd->mLeft[CharC];\r
633 }\r
634\r
635 Mask >>= 1;\r
636\r
637 } while (CharC >= NT);\r
638 }\r
639 //\r
640 // Advance what we have read\r
641 //\r
642 FillBuf (Sd, Sd->mPTLen[CharC]);\r
643\r
644 if (CharC <= 2) {\r
645\r
646 if (CharC == 0) {\r
647 CharC = 1;\r
648 } else if (CharC == 1) {\r
649 CharC = (UINT16) (GetBits (Sd, 4) + 3);\r
650 } else if (CharC == 2) {\r
651 CharC = (UINT16) (GetBits (Sd, CBIT) + 20);\r
652 }\r
653\r
654 while ((INT16) (--CharC) >= 0) {\r
655 Sd->mCLen[Index++] = 0;\r
656 }\r
657\r
658 } else {\r
659\r
660 Sd->mCLen[Index++] = (UINT8) (CharC - 2);\r
661\r
662 }\r
663 }\r
664\r
665 while (Index < NC) {\r
666 Sd->mCLen[Index++] = 0;\r
667 }\r
668\r
669 MakeTable (Sd, NC, Sd->mCLen, 12, Sd->mCTable);\r
670\r
671 return ;\r
672}\r
673\r
674STATIC\r
675UINT16\r
676DecodeC (\r
677 SCRATCH_DATA *Sd\r
678 )\r
679/*++\r
680\r
681Routine Description:\r
682\r
683 Decode a character/length value.\r
684\r
685Arguments:\r
686\r
687 Sd - The global scratch data.\r
688\r
689Returns:\r
690\r
691 The value decoded.\r
692\r
693--*/\r
694{\r
695 UINT16 Index2;\r
696 UINT32 Mask;\r
697\r
698 if (Sd->mBlockSize == 0) {\r
699 //\r
700 // Starting a new block\r
701 //\r
702 Sd->mBlockSize = (UINT16) GetBits (Sd, 16);\r
703 Sd->mBadTableFlag = ReadPTLen (Sd, NT, TBIT, 3);\r
704 if (Sd->mBadTableFlag != 0) {\r
705 return 0;\r
706 }\r
707\r
708 ReadCLen (Sd);\r
709\r
710 Sd->mBadTableFlag = ReadPTLen (Sd, MAXNP, Sd->mPBit, (UINT16) (-1));\r
711 if (Sd->mBadTableFlag != 0) {\r
712 return 0;\r
713 }\r
714 }\r
715\r
716 Sd->mBlockSize--;\r
717 Index2 = Sd->mCTable[Sd->mBitBuf >> (BITBUFSIZ - 12)];\r
718\r
719 if (Index2 >= NC) {\r
720 Mask = 1U << (BITBUFSIZ - 1 - 12);\r
721\r
722 do {\r
723 if (Sd->mBitBuf & Mask) {\r
724 Index2 = Sd->mRight[Index2];\r
725 } else {\r
726 Index2 = Sd->mLeft[Index2];\r
727 }\r
728\r
729 Mask >>= 1;\r
730 } while (Index2 >= NC);\r
731 }\r
732 //\r
733 // Advance what we have read\r
734 //\r
735 FillBuf (Sd, Sd->mCLen[Index2]);\r
736\r
737 return Index2;\r
738}\r
739\r
740STATIC\r
741VOID\r
742Decode (\r
743 SCRATCH_DATA *Sd\r
744 )\r
745/*++\r
746\r
747Routine Description:\r
748\r
749 Decode the source data and put the resulting data into the destination buffer.\r
750\r
751Arguments:\r
752\r
753 Sd - The global scratch data\r
754\r
755Returns: (VOID)\r
756\r
757 --*/\r
758{\r
759 UINT16 BytesRemain;\r
760 UINT32 DataIdx;\r
761 UINT16 CharC;\r
762\r
763 BytesRemain = (UINT16) (-1);\r
764\r
765 DataIdx = 0;\r
766\r
767 for (;;) {\r
768 CharC = DecodeC (Sd);\r
769 if (Sd->mBadTableFlag != 0) {\r
770 return ;\r
771 }\r
772\r
773 if (CharC < 256) {\r
774 //\r
775 // Process an Original character\r
776 //\r
777 if (Sd->mOutBuf >= Sd->mOrigSize) {\r
778 return ;\r
779 } else {\r
780 Sd->mDstBase[Sd->mOutBuf++] = (UINT8) CharC;\r
781 }\r
782\r
783 } else {\r
784 //\r
785 // Process a Pointer\r
786 //\r
787 CharC = (UINT16) (CharC - (UINT8_MAX + 1 - THRESHOLD));\r
788\r
789 BytesRemain = CharC;\r
790\r
791 DataIdx = Sd->mOutBuf - DecodeP (Sd) - 1;\r
792\r
793 BytesRemain--;\r
794 while ((INT16) (BytesRemain) >= 0) {\r
795 Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];\r
796 if (Sd->mOutBuf >= Sd->mOrigSize) {\r
797 return ;\r
798 }\r
799\r
800 BytesRemain--;\r
801 }\r
802 }\r
803 }\r
3eb9473e 804}\r
805\r
806EFI_STATUS\r
807GetInfo (\r
808 IN VOID *Source,\r
809 IN UINT32 SrcSize,\r
810 OUT UINT32 *DstSize,\r
811 OUT UINT32 *ScratchSize\r
812 )\r
813/*++\r
814\r
815Routine Description:\r
816\r
817 The internal implementation of *_DECOMPRESS_PROTOCOL.GetInfo().\r
818\r
819Arguments:\r
820\r
821 Source - The source buffer containing the compressed data.\r
822 SrcSize - The size of source buffer\r
823 DstSize - The size of destination buffer.\r
824 ScratchSize - The size of scratch buffer.\r
825\r
826Returns:\r
827\r
4fc0be87 828 EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successfully retrieved.\r
3eb9473e 829 EFI_INVALID_PARAMETER - The source data is corrupted\r
830\r
831--*/\r
832{\r
833 UINT8 *Src;\r
834\r
835 *ScratchSize = sizeof (SCRATCH_DATA);\r
836\r
837 Src = Source;\r
838 if (SrcSize < 8) {\r
839 return EFI_INVALID_PARAMETER;\r
840 }\r
841\r
842 *DstSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);\r
843 return EFI_SUCCESS;\r
844}\r
845\r
846EFI_STATUS\r
847Decompress (\r
848 IN VOID *Source,\r
849 IN UINT32 SrcSize,\r
850 IN OUT VOID *Destination,\r
851 IN UINT32 DstSize,\r
852 IN OUT VOID *Scratch,\r
853 IN UINT32 ScratchSize,\r
854 IN UINT8 Version\r
855 )\r
856/*++\r
857\r
858Routine Description:\r
859\r
860 The internal implementation of *_DECOMPRESS_PROTOCOL.Decompress().\r
861\r
862Arguments:\r
863\r
864 Source - The source buffer containing the compressed data.\r
865 SrcSize - The size of source buffer\r
866 Destination - The destination buffer to store the decompressed data\r
867 DstSize - The size of destination buffer.\r
868 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.\r
869 ScratchSize - The size of scratch buffer.\r
870 Version - The version of de/compression algorithm.\r
871 Version 1 for EFI 1.1 de/compression algorithm.\r
872 Version 2 for Tiano de/compression algorithm.\r
873\r
874Returns:\r
875\r
876 EFI_SUCCESS - Decompression is successfull\r
877 EFI_INVALID_PARAMETER - The source data is corrupted\r
878\r
879--*/\r
880{\r
881 UINT32 Index;\r
882 UINT32 CompSize;\r
883 UINT32 OrigSize;\r
884 EFI_STATUS Status;\r
885 SCRATCH_DATA *Sd;\r
886 UINT8 *Src;\r
887 UINT8 *Dst;\r
888\r
889 Status = EFI_SUCCESS;\r
890 Src = Source;\r
891 Dst = Destination;\r
892\r
893 if (ScratchSize < sizeof (SCRATCH_DATA)) {\r
894 return EFI_INVALID_PARAMETER;\r
895 }\r
896\r
897 Sd = (SCRATCH_DATA *) Scratch;\r
898\r
899 if (SrcSize < 8) {\r
900 return EFI_INVALID_PARAMETER;\r
901 }\r
902\r
903 CompSize = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);\r
904 OrigSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);\r
905\r
906 //\r
907 // If compressed file size is 0, return\r
908 //\r
909 if (OrigSize == 0) {\r
910 return Status;\r
911 }\r
912\r
913 if (SrcSize < CompSize + 8) {\r
914 return EFI_INVALID_PARAMETER;\r
915 }\r
916\r
917 if (DstSize != OrigSize) {\r
918 return EFI_INVALID_PARAMETER;\r
919 }\r
920\r
921 Src = Src + 8;\r
922\r
923 for (Index = 0; Index < sizeof (SCRATCH_DATA); Index++) {\r
924 ((UINT8 *) Sd)[Index] = 0;\r
925 }\r
926 //\r
927 // The length of the field 'Position Set Code Length Array Size' in Block Header.\r
928 // For EFI 1.1 de/compression algorithm(Version 1), mPBit = 4\r
929 // For Tiano de/compression algorithm(Version 2), mPBit = 5\r
930 //\r
931 switch (Version) {\r
932 case 1:\r
933 Sd->mPBit = 4;\r
934 break;\r
935\r
936 case 2:\r
937 Sd->mPBit = 5;\r
938 break;\r
939\r
940 default:\r
941 //\r
942 // Currently, only have 2 versions\r
943 //\r
944 return EFI_INVALID_PARAMETER;\r
945 }\r
946\r
947 Sd->mSrcBase = Src;\r
948 Sd->mDstBase = Dst;\r
949 Sd->mCompSize = CompSize;\r
950 Sd->mOrigSize = OrigSize;\r
951\r
952 //\r
953 // Fill the first BITBUFSIZ bits\r
954 //\r
955 FillBuf (Sd, BITBUFSIZ);\r
956\r
957 //\r
958 // Decompress it\r
959 //\r
960 Decode (Sd);\r
961\r
962 if (Sd->mBadTableFlag != 0) {\r
963 //\r
964 // Something wrong with the source\r
965 //\r
966 Status = EFI_INVALID_PARAMETER;\r
967 }\r
968\r
969 return Status;\r
970}\r
971\r
972EFI_STATUS\r
973EFIAPI\r
974EfiGetInfo (\r
975 IN EFI_DECOMPRESS_PROTOCOL *This,\r
976 IN VOID *Source,\r
977 IN UINT32 SrcSize,\r
978 OUT UINT32 *DstSize,\r
979 OUT UINT32 *ScratchSize\r
980 )\r
981/*++\r
982\r
983Routine Description:\r
984\r
985 The implementation of EFI_DECOMPRESS_PROTOCOL.GetInfo().\r
986\r
987Arguments:\r
988\r
989 This - The protocol instance pointer\r
990 Source - The source buffer containing the compressed data.\r
991 SrcSize - The size of source buffer\r
992 DstSize - The size of destination buffer.\r
993 ScratchSize - The size of scratch buffer.\r
994\r
995Returns:\r
996\r
4fc0be87 997 EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successfully retrieved.\r
3eb9473e 998 EFI_INVALID_PARAMETER - The source data is corrupted\r
999\r
1000--*/\r
1001{\r
1002 return GetInfo (\r
1003 Source,\r
1004 SrcSize,\r
1005 DstSize,\r
1006 ScratchSize\r
1007 );\r
1008}\r
1009\r
1010EFI_STATUS\r
1011EFIAPI\r
1012EfiDecompress (\r
1013 IN EFI_DECOMPRESS_PROTOCOL *This,\r
1014 IN VOID *Source,\r
1015 IN UINT32 SrcSize,\r
1016 IN OUT VOID *Destination,\r
1017 IN UINT32 DstSize,\r
1018 IN OUT VOID *Scratch,\r
1019 IN UINT32 ScratchSize\r
1020 )\r
1021/*++\r
1022\r
1023Routine Description:\r
1024\r
1025 The implementation of EFI_DECOMPRESS_PROTOCOL.Decompress().\r
1026\r
1027Arguments:\r
1028\r
1029 This - The protocol instance pointer\r
1030 Source - The source buffer containing the compressed data.\r
1031 SrcSize - The size of source buffer\r
1032 Destination - The destination buffer to store the decompressed data\r
1033 DstSize - The size of destination buffer.\r
1034 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.\r
1035 ScratchSize - The size of scratch buffer.\r
1036\r
1037Returns:\r
1038\r
1039 EFI_SUCCESS - Decompression is successfull\r
1040 EFI_INVALID_PARAMETER - The source data is corrupted\r
1041\r
1042--*/\r
1043{\r
1044 //\r
1045 // For EFI 1.1 de/compression algorithm, the version is 1.\r
1046 //\r
1047 return Decompress (\r
1048 Source,\r
1049 SrcSize,\r
1050 Destination,\r
1051 DstSize,\r
1052 Scratch,\r
1053 ScratchSize,\r
1054 1\r
1055 );\r
1056}\r
1057\r
1058EFI_STATUS\r
1059EFIAPI\r
1060TianoGetInfo (\r
1061 IN EFI_TIANO_DECOMPRESS_PROTOCOL *This,\r
1062 IN VOID *Source,\r
1063 IN UINT32 SrcSize,\r
1064 OUT UINT32 *DstSize,\r
1065 OUT UINT32 *ScratchSize\r
1066 )\r
1067/*++\r
1068\r
1069Routine Description:\r
1070\r
1071 The implementation of EFI_TIANO_DECOMPRESS_PROTOCOL.GetInfo().\r
1072\r
1073Arguments:\r
1074\r
1075 This - The protocol instance pointer\r
1076 Source - The source buffer containing the compressed data.\r
1077 SrcSize - The size of source buffer\r
1078 DstSize - The size of destination buffer.\r
1079 ScratchSize - The size of scratch buffer.\r
1080\r
1081Returns:\r
1082\r
4fc0be87 1083 EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successfully retrieved.\r
3eb9473e 1084 EFI_INVALID_PARAMETER - The source data is corrupted\r
1085\r
1086--*/\r
1087{\r
1088 return GetInfo (\r
1089 Source,\r
1090 SrcSize,\r
1091 DstSize,\r
1092 ScratchSize\r
1093 );\r
1094}\r
1095\r
1096EFI_STATUS\r
1097EFIAPI\r
1098TianoDecompress (\r
1099 IN EFI_TIANO_DECOMPRESS_PROTOCOL *This,\r
1100 IN VOID *Source,\r
1101 IN UINT32 SrcSize,\r
1102 IN OUT VOID *Destination,\r
1103 IN UINT32 DstSize,\r
1104 IN OUT VOID *Scratch,\r
1105 IN UINT32 ScratchSize\r
1106 )\r
1107/*++\r
1108\r
1109Routine Description:\r
1110\r
1111 The implementation of EFI_TIANO_DECOMPRESS_PROTOCOL.Decompress().\r
1112\r
1113Arguments:\r
1114\r
1115 This - The protocol instance pointer\r
1116 Source - The source buffer containing the compressed data.\r
1117 SrcSize - The size of source buffer\r
1118 Destination - The destination buffer to store the decompressed data\r
1119 DstSize - The size of destination buffer.\r
1120 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.\r
1121 ScratchSize - The size of scratch buffer.\r
1122\r
1123Returns:\r
1124\r
1125 EFI_SUCCESS - Decompression is successfull\r
1126 EFI_INVALID_PARAMETER - The source data is corrupted\r
1127\r
1128--*/\r
1129{\r
1130 //\r
1131 // For Tiano de/compression algorithm, the version is 2.\r
1132 //\r
1133 return Decompress (\r
1134 Source,\r
1135 SrcSize,\r
1136 Destination,\r
1137 DstSize,\r
1138 Scratch,\r
1139 ScratchSize,\r
1140 2\r
1141 );\r
1142}\r