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