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