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