]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Library/BaseUefiTianoCustomDecompressLib/BaseUefiTianoCustomDecompressLib.c
Reviewed the code comments in the Include/Protocol directory for typos, grammar issue...
[mirror_edk2.git] / IntelFrameworkModulePkg / Library / BaseUefiTianoCustomDecompressLib / BaseUefiTianoCustomDecompressLib.c
CommitLineData
3db51098 1/**@file\r
2 UEFI and Custom Decompress Library \r
ed7752ec 3 The function of UefiTianoDecompress() is interface for this module,\r
4 it will do tiano or uefi decompress with different verison parameter.\r
5 See EFI specification 1.1 Chapter 17 to get LZ77 compress/decompress.\r
3db51098 6 \r
54bd896e 7Copyright (c) 2006, Intel Corporation \r
8All rights reserved. This program and the accompanying materials \r
9are licensed and made available under the terms and conditions of the BSD License \r
10which accompanies this distribution. The full text of the license may be found at \r
11http://opensource.org/licenses/bsd-license.php \r
12 \r
13THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
14WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
15\r
3db51098 16**/\r
54bd896e 17\r
54bd896e 18#include "BaseUefiTianoCustomDecompressLibInternals.h"\r
8bd22b8a 19#include <Guid/CustomDecompress.h>\r
54bd896e 20\r
ed7752ec 21/**\r
22 Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source.\r
23 \r
24 @param Sd The global scratch data\r
25 @param NumOfBits The number of bits to shift and read. \r
26**/\r
54bd896e 27VOID\r
28FillBuf (\r
29 IN SCRATCH_DATA *Sd,\r
30 IN UINT16 NumOfBits\r
31 )\r
54bd896e 32{\r
33 Sd->mBitBuf = (UINT32) (Sd->mBitBuf << NumOfBits);\r
34\r
35 while (NumOfBits > Sd->mBitCount) {\r
36\r
37 Sd->mBitBuf |= (UINT32) (Sd->mSubBitBuf << (NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount)));\r
38\r
39 if (Sd->mCompSize > 0) {\r
40 //\r
41 // Get 1 byte into SubBitBuf\r
42 //\r
43 Sd->mCompSize--;\r
44 Sd->mSubBitBuf = 0;\r
45 Sd->mSubBitBuf = Sd->mSrcBase[Sd->mInBuf++];\r
46 Sd->mBitCount = 8;\r
47\r
48 } else {\r
49 //\r
50 // No more bits from the source, just pad zero bit.\r
51 //\r
52 Sd->mSubBitBuf = 0;\r
53 Sd->mBitCount = 8;\r
54\r
55 }\r
56 }\r
57\r
58 Sd->mBitCount = (UINT16) (Sd->mBitCount - NumOfBits);\r
59 Sd->mBitBuf |= Sd->mSubBitBuf >> Sd->mBitCount;\r
60}\r
61\r
ed7752ec 62/**\r
63 Get NumOfBits of bits out from mBitBuf\r
54bd896e 64\r
65 Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent \r
66 NumOfBits of bits from source. Returns NumOfBits of bits that are \r
67 popped out.\r
68\r
ed7752ec 69 @param Sd The global scratch data.\r
70 @param NumOfBits The number of bits to pop and read.\r
54bd896e 71\r
ed7752ec 72 @return The bits that are popped out.\r
54bd896e 73\r
ed7752ec 74**/\r
75UINT32\r
76GetBits (\r
77 IN SCRATCH_DATA *Sd,\r
78 IN UINT16 NumOfBits\r
79 )\r
54bd896e 80{\r
81 UINT32 OutBits;\r
82\r
83 OutBits = (UINT32) (Sd->mBitBuf >> (BITBUFSIZ - NumOfBits));\r
84\r
85 FillBuf (Sd, NumOfBits);\r
86\r
87 return OutBits;\r
88}\r
89\r
ed7752ec 90/**\r
91 Creates Huffman Code mapping table according to code length array.\r
92\r
93 Creates Huffman Code mapping table for Extra Set, Char&Len Set \r
94 and Position Set according to code length array.\r
95\r
96 @param Sd The global scratch data\r
97 @param NumOfChar Number of symbols in the symbol set\r
98 @param BitLen Code length array\r
99 @param TableBits The width of the mapping table\r
100 @param Table The table\r
101\r
102 @retval 0 OK.\r
103 @retval BAD_TABLE The table is corrupted.\r
104\r
105**/\r
54bd896e 106UINT16\r
107MakeTable (\r
108 IN SCRATCH_DATA *Sd,\r
109 IN UINT16 NumOfChar,\r
110 IN UINT8 *BitLen,\r
111 IN UINT16 TableBits,\r
112 OUT UINT16 *Table\r
113 )\r
54bd896e 114{\r
115 UINT16 Count[17];\r
116 UINT16 Weight[17];\r
117 UINT16 Start[18];\r
118 UINT16 *Pointer;\r
119 UINT16 Index3;\r
80267d51 120 UINT16 Index;\r
54bd896e 121 UINT16 Len;\r
122 UINT16 Char;\r
123 UINT16 JuBits;\r
124 UINT16 Avail;\r
125 UINT16 NextCode;\r
126 UINT16 Mask;\r
127 UINT16 WordOfStart;\r
128 UINT16 WordOfCount;\r
129\r
aa950314 130 for (Index = 0; Index <= 16; Index++) {\r
54bd896e 131 Count[Index] = 0;\r
132 }\r
133\r
134 for (Index = 0; Index < NumOfChar; Index++) {\r
135 Count[BitLen[Index]]++;\r
136 }\r
aa950314 137 \r
138 Start[0] = 0;\r
54bd896e 139 Start[1] = 0;\r
140\r
141 for (Index = 1; Index <= 16; Index++) {\r
142 WordOfStart = Start[Index];\r
143 WordOfCount = Count[Index];\r
144 Start[Index + 1] = (UINT16) (WordOfStart + (WordOfCount << (16 - Index)));\r
145 }\r
146\r
147 if (Start[17] != 0) {\r
148 /*(1U << 16)*/\r
149 return (UINT16) BAD_TABLE;\r
150 }\r
151\r
152 JuBits = (UINT16) (16 - TableBits);\r
aa950314 153 \r
154 Weight[0] = 0;\r
54bd896e 155 for (Index = 1; Index <= TableBits; Index++) {\r
156 Start[Index] >>= JuBits;\r
157 Weight[Index] = (UINT16) (1U << (TableBits - Index));\r
158 }\r
159\r
160 while (Index <= 16) {\r
161 Weight[Index] = (UINT16) (1U << (16 - Index));\r
aa950314 162 Index++; \r
54bd896e 163 }\r
164\r
165 Index = (UINT16) (Start[TableBits + 1] >> JuBits);\r
166\r
167 if (Index != 0) {\r
168 Index3 = (UINT16) (1U << TableBits);\r
aa950314 169 if (Index < Index3) {\r
170 SetMem16 (Table + Index, (Index3 - Index) * sizeof (*Table), 0);\r
54bd896e 171 }\r
172 }\r
173\r
174 Avail = NumOfChar;\r
175 Mask = (UINT16) (1U << (15 - TableBits));\r
176\r
177 for (Char = 0; Char < NumOfChar; Char++) {\r
178\r
179 Len = BitLen[Char];\r
aa950314 180 if (Len == 0 || Len >= 17) {\r
54bd896e 181 continue;\r
182 }\r
183\r
184 NextCode = (UINT16) (Start[Len] + Weight[Len]);\r
185\r
186 if (Len <= TableBits) {\r
187\r
188 for (Index = Start[Len]; Index < NextCode; Index++) {\r
189 Table[Index] = Char;\r
190 }\r
191\r
192 } else {\r
193\r
194 Index3 = Start[Len];\r
195 Pointer = &Table[Index3 >> JuBits];\r
196 Index = (UINT16) (Len - TableBits);\r
197\r
198 while (Index != 0) {\r
aa950314 199 if (*Pointer == 0 && Avail < (2 * NC - 1)) {\r
200 Sd->mRight[Avail] = Sd->mLeft[Avail] = 0;\r
54bd896e 201 *Pointer = Avail++;\r
202 }\r
aa950314 203 \r
204 if (*Pointer < (2 * NC - 1)) {\r
205 if ((Index3 & Mask) != 0) {\r
206 Pointer = &Sd->mRight[*Pointer];\r
207 } else {\r
208 Pointer = &Sd->mLeft[*Pointer];\r
209 }\r
54bd896e 210 }\r
211\r
212 Index3 <<= 1;\r
213 Index--;\r
214 }\r
215\r
216 *Pointer = Char;\r
217\r
218 }\r
219\r
220 Start[Len] = NextCode;\r
221 }\r
222 //\r
223 // Succeeds\r
224 //\r
225 return 0;\r
226}\r
227\r
ed7752ec 228/**\r
229 Decodes a position value.\r
230 \r
231 @param Sd the global scratch data\r
232 \r
233 @return The position value decoded.\r
234**/\r
54bd896e 235UINT32\r
236DecodeP (\r
237 IN SCRATCH_DATA *Sd\r
238 )\r
54bd896e 239{\r
240 UINT16 Val;\r
241 UINT32 Mask;\r
242 UINT32 Pos;\r
243\r
244 Val = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];\r
245\r
246 if (Val >= MAXNP) {\r
247 Mask = 1U << (BITBUFSIZ - 1 - 8);\r
248\r
249 do {\r
250\r
251 if (Sd->mBitBuf & Mask) {\r
252 Val = Sd->mRight[Val];\r
253 } else {\r
254 Val = Sd->mLeft[Val];\r
255 }\r
256\r
257 Mask >>= 1;\r
258 } while (Val >= MAXNP);\r
259 }\r
260 //\r
261 // Advance what we have read\r
262 //\r
263 FillBuf (Sd, Sd->mPTLen[Val]);\r
264\r
265 Pos = Val;\r
266 if (Val > 1) {\r
267 Pos = (UINT32) ((1U << (Val - 1)) + GetBits (Sd, (UINT16) (Val - 1)));\r
268 }\r
269\r
270 return Pos;\r
271}\r
272\r
ed7752ec 273/**\r
274 Reads code lengths for the Extra Set or the Position Set.\r
275\r
276 Read in the Extra Set or Pointion Set Length Arrary, then\r
277 generate the Huffman code mapping for them.\r
278\r
279 @param Sd The global scratch data.\r
280 @param nn Number of symbols.\r
281 @param nbit Number of bits needed to represent nn.\r
282 @param Special The special symbol that needs to be taken care of.\r
283\r
284 @retval 0 OK.\r
285 @retval BAD_TABLE Table is corrupted.\r
286\r
287**/\r
54bd896e 288UINT16\r
289ReadPTLen (\r
290 IN SCRATCH_DATA *Sd,\r
291 IN UINT16 nn,\r
292 IN UINT16 nbit,\r
293 IN UINT16 Special\r
294 )\r
54bd896e 295{\r
296 UINT16 Number;\r
297 UINT16 CharC;\r
80267d51 298 UINT16 Index;\r
54bd896e 299 UINT32 Mask;\r
300\r
aa950314 301 //\r
302 // Read Extra Set Code Length Array size \r
303 //\r
54bd896e 304 Number = (UINT16) GetBits (Sd, nbit);\r
305\r
306 if (Number == 0) {\r
aa950314 307 //\r
308 // This represents only Huffman code used\r
309 //\r
54bd896e 310 CharC = (UINT16) GetBits (Sd, nbit);\r
311\r
312 for (Index = 0; Index < 256; Index++) {\r
313 Sd->mPTTable[Index] = CharC;\r
314 }\r
315\r
aa950314 316 SetMem (Sd->mPTLen, nn, 0);\r
54bd896e 317\r
318 return 0;\r
319 }\r
320\r
321 Index = 0;\r
322\r
aa950314 323 while (Index < Number && Index < NPT) {\r
54bd896e 324\r
325 CharC = (UINT16) (Sd->mBitBuf >> (BITBUFSIZ - 3));\r
326\r
aa950314 327 //\r
328 // If a code length is less than 7, then it is encoded as a 3-bit\r
329 // value. Or it is encoded as a series of "1"s followed by a \r
330 // terminating "0". The number of "1"s = Code length - 4.\r
331 //\r
54bd896e 332 if (CharC == 7) {\r
333 Mask = 1U << (BITBUFSIZ - 1 - 3);\r
334 while (Mask & Sd->mBitBuf) {\r
335 Mask >>= 1;\r
336 CharC += 1;\r
337 }\r
338 }\r
aa950314 339 \r
54bd896e 340 FillBuf (Sd, (UINT16) ((CharC < 7) ? 3 : CharC - 3));\r
341\r
342 Sd->mPTLen[Index++] = (UINT8) CharC;\r
aa950314 343 \r
344 //\r
345 // For Code&Len Set, \r
346 // After the third length of the code length concatenation,\r
347 // a 2-bit value is used to indicated the number of consecutive \r
348 // zero lengths after the third length.\r
349 //\r
54bd896e 350 if (Index == Special) {\r
351 CharC = (UINT16) GetBits (Sd, 2);\r
aa950314 352 while ((INT16) (--CharC) >= 0 && Index < NPT) {\r
54bd896e 353 Sd->mPTLen[Index++] = 0;\r
354 }\r
355 }\r
356 }\r
357\r
aa950314 358 while (Index < nn && Index < NPT) {\r
54bd896e 359 Sd->mPTLen[Index++] = 0;\r
360 }\r
aa950314 361 \r
54bd896e 362 return MakeTable (Sd, nn, Sd->mPTLen, 8, Sd->mPTTable);\r
363}\r
364\r
ed7752ec 365/**\r
366 Reads code lengths for Char&Len Set.\r
367 \r
368 Read in and decode the Char&Len Set Code Length Array, then\r
369 generate the Huffman Code mapping table for the Char&Len Set.\r
370\r
371 @param Sd the global scratch data\r
372\r
373**/\r
54bd896e 374VOID\r
375ReadCLen (\r
376 SCRATCH_DATA *Sd\r
377 )\r
54bd896e 378{\r
379 UINT16 Number;\r
380 UINT16 CharC;\r
80267d51 381 UINT16 Index;\r
54bd896e 382 UINT32 Mask;\r
383\r
384 Number = (UINT16) GetBits (Sd, CBIT);\r
385\r
386 if (Number == 0) {\r
aa950314 387 //\r
388 // This represents only Huffman code used\r
389 //\r
54bd896e 390 CharC = (UINT16) GetBits (Sd, CBIT);\r
391\r
aa950314 392 SetMem (Sd->mCLen, NC, 0);\r
54bd896e 393\r
394 for (Index = 0; Index < 4096; Index++) {\r
395 Sd->mCTable[Index] = CharC;\r
396 }\r
397\r
398 return ;\r
399 }\r
400\r
401 Index = 0;\r
aa950314 402 while (Index < Number && Index < NC) {\r
54bd896e 403 CharC = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];\r
404 if (CharC >= NT) {\r
405 Mask = 1U << (BITBUFSIZ - 1 - 8);\r
406\r
407 do {\r
408\r
409 if (Mask & Sd->mBitBuf) {\r
410 CharC = Sd->mRight[CharC];\r
411 } else {\r
412 CharC = Sd->mLeft[CharC];\r
413 }\r
414\r
415 Mask >>= 1;\r
416\r
417 } while (CharC >= NT);\r
418 }\r
419 //\r
420 // Advance what we have read\r
421 //\r
422 FillBuf (Sd, Sd->mPTLen[CharC]);\r
423\r
424 if (CharC <= 2) {\r
425\r
426 if (CharC == 0) {\r
427 CharC = 1;\r
428 } else if (CharC == 1) {\r
429 CharC = (UINT16) (GetBits (Sd, 4) + 3);\r
430 } else if (CharC == 2) {\r
431 CharC = (UINT16) (GetBits (Sd, CBIT) + 20);\r
432 }\r
433\r
aa950314 434 while ((INT16) (--CharC) >= 0 && Index < NC) {\r
54bd896e 435 Sd->mCLen[Index++] = 0;\r
436 }\r
437\r
438 } else {\r
439\r
440 Sd->mCLen[Index++] = (UINT8) (CharC - 2);\r
441\r
442 }\r
443 }\r
444\r
aa950314 445 SetMem (Sd->mCLen + Index, NC - Index, 0);\r
54bd896e 446\r
447 MakeTable (Sd, NC, Sd->mCLen, 12, Sd->mCTable);\r
448\r
449 return ;\r
450}\r
451\r
ed7752ec 452/**\r
54bd896e 453 Decode a character/length value.\r
ed7752ec 454 \r
455 Read one value from mBitBuf, Get one code from mBitBuf. If it is at block boundary, generates\r
456 Huffman code mapping table for Extra Set, Code&Len Set and\r
457 Position Set.\r
54bd896e 458\r
ed7752ec 459 @param Sd The global scratch data.\r
54bd896e 460\r
ed7752ec 461 @return The value decoded.\r
54bd896e 462\r
ed7752ec 463**/\r
464UINT16\r
465DecodeC (\r
466 SCRATCH_DATA *Sd\r
467 )\r
54bd896e 468{\r
469 UINT16 Index2;\r
470 UINT32 Mask;\r
471\r
472 if (Sd->mBlockSize == 0) {\r
473 //\r
474 // Starting a new block\r
475 //\r
476 Sd->mBlockSize = (UINT16) GetBits (Sd, 16);\r
477 Sd->mBadTableFlag = ReadPTLen (Sd, NT, TBIT, 3);\r
478 if (Sd->mBadTableFlag != 0) {\r
479 return 0;\r
480 }\r
481\r
482 ReadCLen (Sd);\r
483\r
484 Sd->mBadTableFlag = ReadPTLen (Sd, MAXNP, Sd->mPBit, (UINT16) (-1));\r
485 if (Sd->mBadTableFlag != 0) {\r
486 return 0;\r
487 }\r
488 }\r
489\r
490 Sd->mBlockSize--;\r
491 Index2 = Sd->mCTable[Sd->mBitBuf >> (BITBUFSIZ - 12)];\r
492\r
493 if (Index2 >= NC) {\r
494 Mask = 1U << (BITBUFSIZ - 1 - 12);\r
495\r
496 do {\r
497 if (Sd->mBitBuf & Mask) {\r
498 Index2 = Sd->mRight[Index2];\r
499 } else {\r
500 Index2 = Sd->mLeft[Index2];\r
501 }\r
502\r
503 Mask >>= 1;\r
504 } while (Index2 >= NC);\r
505 }\r
506 //\r
507 // Advance what we have read\r
508 //\r
509 FillBuf (Sd, Sd->mCLen[Index2]);\r
510\r
511 return Index2;\r
512}\r
513\r
ed7752ec 514/**\r
515 Decode the source data ad put the resulting data into the destination buffer.\r
516 \r
517 @param Sd - The global scratch data\r
518**/\r
54bd896e 519VOID\r
520Decode (\r
521 SCRATCH_DATA *Sd\r
522 )\r
54bd896e 523{\r
524 UINT16 BytesRemain;\r
525 UINT32 DataIdx;\r
526 UINT16 CharC;\r
527\r
528 BytesRemain = (UINT16) (-1);\r
529\r
530 DataIdx = 0;\r
531\r
532 for (;;) {\r
533 CharC = DecodeC (Sd);\r
534 if (Sd->mBadTableFlag != 0) {\r
535 goto Done ;\r
536 }\r
537\r
538 if (CharC < 256) {\r
539 //\r
540 // Process an Original character\r
541 //\r
542 if (Sd->mOutBuf >= Sd->mOrigSize) {\r
543 goto Done ;\r
544 } else {\r
545 Sd->mDstBase[Sd->mOutBuf++] = (UINT8) CharC;\r
546 }\r
547\r
548 } else {\r
549 //\r
550 // Process a Pointer\r
551 //\r
15793911 552 CharC = (UINT16) (CharC - (BIT8 - THRESHOLD));\r
54bd896e 553\r
554 BytesRemain = CharC;\r
555\r
556 DataIdx = Sd->mOutBuf - DecodeP (Sd) - 1;\r
557\r
558 BytesRemain--;\r
559 while ((INT16) (BytesRemain) >= 0) {\r
560 Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];\r
561 if (Sd->mOutBuf >= Sd->mOrigSize) {\r
562 goto Done ;\r
563 }\r
564\r
565 BytesRemain--;\r
566 }\r
567 }\r
568 }\r
569\r
570Done:\r
571 return ;\r
572}\r
573\r
ed7752ec 574/**\r
575 The internal implementation of *_DECOMPRESS_PROTOCOL.GetInfo().\r
576 \r
577 @param Source The source buffer containing the compressed data.\r
578 @param SourceSize The size of source buffer\r
579 @param DestinationSize The size of destination buffer.\r
580 @param ScratchSize The size of scratch buffer.\r
581\r
582 @retval RETURN_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved.\r
583 @retval RETURN_INVALID_PARAMETER - The source data is corrupted\r
584**/\r
54bd896e 585RETURN_STATUS\r
586EFIAPI\r
587UefiDecompressGetInfo (\r
588 IN CONST VOID *Source,\r
589 IN UINT32 SourceSize,\r
590 OUT UINT32 *DestinationSize,\r
591 OUT UINT32 *ScratchSize\r
592 )\r
54bd896e 593{\r
594 UINT32 CompressedSize;\r
595\r
596 ASSERT (Source != NULL);\r
597 ASSERT (DestinationSize != NULL);\r
598 ASSERT (ScratchSize != NULL);\r
599\r
54bd896e 600 if (SourceSize < 8) {\r
601 return RETURN_INVALID_PARAMETER;\r
602 }\r
603\r
e69a0629 604 CompressedSize = ReadUnaligned32 ((UINT32 *)Source);\r
54bd896e 605 if (SourceSize < (CompressedSize + 8)) {\r
606 return RETURN_INVALID_PARAMETER;\r
607 }\r
608\r
18fd8d65 609 *ScratchSize = sizeof (SCRATCH_DATA);\r
e69a0629 610 *DestinationSize = ReadUnaligned32 ((UINT32 *)Source + 1);\r
18fd8d65 611\r
54bd896e 612 return RETURN_SUCCESS;\r
613}\r
614\r
ed7752ec 615/**\r
616 The internal implementation of *_DECOMPRESS_PROTOCOL.Decompress().\r
617\r
618 @param Source The source buffer containing the compressed data.\r
619 @param Destination The destination buffer to store the decompressed data\r
620 @param Scratch The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.\r
621 @param Version 1 for UEFI Decompress algoruthm, 2 for Tiano Decompess algorithm\r
622\r
623 @retval RETURN_SUCCESS Decompression is successfull\r
624 @retval RETURN_INVALID_PARAMETER The source data is corrupted\r
625**/\r
54bd896e 626RETURN_STATUS\r
627EFIAPI\r
628UefiTianoDecompress (\r
629 IN CONST VOID *Source,\r
630 IN OUT VOID *Destination,\r
631 IN OUT VOID *Scratch,\r
632 IN UINT32 Version\r
633 )\r
54bd896e 634{\r
54bd896e 635 UINT32 CompSize;\r
636 UINT32 OrigSize;\r
637 SCRATCH_DATA *Sd;\r
638 CONST UINT8 *Src;\r
639 UINT8 *Dst;\r
640\r
641 ASSERT (Source != NULL);\r
642 ASSERT (Destination != NULL);\r
643 ASSERT (Scratch != NULL);\r
644\r
645 Src = Source;\r
646 Dst = Destination;\r
647\r
648 Sd = (SCRATCH_DATA *) Scratch;\r
649\r
650 CompSize = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);\r
651 OrigSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);\r
652\r
653 //\r
654 // If compressed file size is 0, return\r
655 //\r
656 if (OrigSize == 0) {\r
657 return RETURN_SUCCESS;\r
658 }\r
659\r
660 Src = Src + 8;\r
661\r
779b8368 662 SetMem (Sd, sizeof (SCRATCH_DATA), 0);\r
663\r
54bd896e 664 //\r
665 // The length of the field 'Position Set Code Length Array Size' in Block Header.\r
8a7d75b0 666 // For UEFI 2.0 de/compression algorithm(Version 1), mPBit = 4\r
54bd896e 667 // For Tiano de/compression algorithm(Version 2), mPBit = 5\r
668 //\r
669 switch (Version) {\r
670 case 1 :\r
671 Sd->mPBit = 4;\r
672 break;\r
673 case 2 :\r
674 Sd->mPBit = 5;\r
675 break;\r
676 default:\r
677 ASSERT (FALSE);\r
678 }\r
679 Sd->mSrcBase = (UINT8 *)Src;\r
680 Sd->mDstBase = Dst;\r
681 Sd->mCompSize = CompSize;\r
682 Sd->mOrigSize = OrigSize;\r
683\r
684 //\r
685 // Fill the first BITBUFSIZ bits\r
686 //\r
687 FillBuf (Sd, BITBUFSIZ);\r
688\r
689 //\r
690 // Decompress it\r
691 //\r
692 Decode (Sd);\r
693\r
694 if (Sd->mBadTableFlag != 0) {\r
695 //\r
696 // Something wrong with the source\r
697 //\r
698 return RETURN_INVALID_PARAMETER;\r
699 }\r
700\r
701 return RETURN_SUCCESS;\r
702}\r
703\r
ed7752ec 704/**\r
705 The internal implementation of *_DECOMPRESS_PROTOCOL.Decompress().\r
706 \r
707 @param Source - The source buffer containing the compressed data.\r
708 @param Destination - The destination buffer to store the decompressed data\r
709 @param Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.\r
710\r
711 @retval RETURN_SUCCESS - Decompression is successfull\r
712 @retval RETURN_INVALID_PARAMETER - The source data is corrupted \r
713**/\r
54bd896e 714RETURN_STATUS\r
715EFIAPI\r
716UefiDecompress (\r
717 IN CONST VOID *Source,\r
718 IN OUT VOID *Destination,\r
719 IN OUT VOID *Scratch\r
720 )\r
54bd896e 721{\r
722 return UefiTianoDecompress (Source, Destination, Scratch, 1);\r
723}\r
724\r
ed7752ec 725/**\r
726 The internal implementation of Tiano decompress GetInfo.\r
727\r
728 @param InputSection Buffer containing the input GUIDed section to be processed. \r
729 @param OutputBufferSize The size of OutputBuffer.\r
730 @param ScratchBufferSize The size of ScratchBuffer.\r
731 @param SectionAttribute The attribute of the input guided section.\r
732\r
733 @retval RETURN_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved.\r
734 @retval RETURN_INVALID_PARAMETER - The source data is corrupted\r
735 The GUID in InputSection does not match this instance guid.\r
736**/\r
54bd896e 737RETURN_STATUS\r
738EFIAPI\r
18fd8d65
LG
739TianoDecompressGetInfo (\r
740 IN CONST VOID *InputSection,\r
741 OUT UINT32 *OutputBufferSize,\r
742 OUT UINT32 *ScratchBufferSize,\r
743 OUT UINT16 *SectionAttribute\r
54bd896e 744 )\r
54bd896e 745\r
54bd896e 746{\r
18fd8d65
LG
747 ASSERT (SectionAttribute != NULL);\r
748\r
749 if (InputSection == NULL) {\r
750 return RETURN_INVALID_PARAMETER;\r
d8c79a81 751 }\r
e6c560aa
LG
752\r
753 if (!CompareGuid (\r
754 &gTianoCustomDecompressGuid, \r
755 &(((EFI_GUID_DEFINED_SECTION *) InputSection)->SectionDefinitionGuid))) {\r
756 return RETURN_INVALID_PARAMETER;\r
757 }\r
18fd8d65
LG
758 //\r
759 // Get guid attribute of guid section. \r
760 //\r
761 *SectionAttribute = ((EFI_GUID_DEFINED_SECTION *) InputSection)->Attributes;\r
762\r
763 //\r
764 // Call Tiano GetInfo to get the required size info.\r
765 //\r
766 return UefiDecompressGetInfo (\r
767 (UINT8 *) InputSection + ((EFI_GUID_DEFINED_SECTION *) InputSection)->DataOffset,\r
9c294371 768 (*(UINT32 *) (((EFI_COMMON_SECTION_HEADER *) InputSection)->Size) & 0x00ffffff) - ((EFI_GUID_DEFINED_SECTION *) InputSection)->DataOffset,\r
18fd8d65
LG
769 OutputBufferSize,\r
770 ScratchBufferSize\r
771 );\r
54bd896e 772}\r
773\r
ed7752ec 774/**\r
775 The implementation of Tiano Decompress().\r
776\r
777 @param InputSection Buffer containing the input GUIDed section to be processed. \r
778 @param OutputBuffer OutputBuffer to point to the start of the section's contents.\r
779 if guided data is not prcessed. Otherwise,\r
780 OutputBuffer to contain the output data, which is allocated by the caller.\r
781 @param ScratchBuffer A pointer to a caller-allocated buffer for function internal use. \r
782 @param AuthenticationStatus A pointer to a caller-allocated UINT32 that indicates the\r
783 authentication status of the output buffer. \r
784\r
785 @retval RETURN_SUCCESS Decompression is successfull\r
786 @retval RETURN_INVALID_PARAMETER The source data is corrupted, or\r
787 The GUID in InputSection does not match this instance guid.\r
788\r
bcd70414 789**/\r
54bd896e 790RETURN_STATUS\r
791EFIAPI\r
18fd8d65
LG
792TianoDecompress (\r
793 IN CONST VOID *InputSection,\r
794 OUT VOID **OutputBuffer,\r
795 IN VOID *ScratchBuffer, OPTIONAL\r
796 OUT UINT32 *AuthenticationStatus\r
54bd896e 797 )\r
54bd896e 798{\r
18fd8d65
LG
799 ASSERT (OutputBuffer != NULL);\r
800\r
801 if (InputSection == NULL) {\r
802 return RETURN_INVALID_PARAMETER;\r
e6c560aa
LG
803 }\r
804\r
805 if (!CompareGuid (\r
806 &gTianoCustomDecompressGuid, \r
807 &(((EFI_GUID_DEFINED_SECTION *) InputSection)->SectionDefinitionGuid))) {\r
808 return RETURN_INVALID_PARAMETER;\r
809 }\r
810\r
18fd8d65
LG
811 //\r
812 // Set Authentication to Zero.\r
813 //\r
814 *AuthenticationStatus = 0;\r
815 \r
816 //\r
817 // Call Tiano Decompress to get the raw data\r
818 //\r
819 return UefiTianoDecompress (\r
820 (UINT8 *) InputSection + ((EFI_GUID_DEFINED_SECTION *) InputSection)->DataOffset,\r
821 *OutputBuffer,\r
822 ScratchBuffer,\r
823 2\r
824 );\r
54bd896e 825}\r
d8c79a81 826\r
ed7752ec 827/**\r
18fd8d65 828 Register TianoDecompress handler.\r
ed7752ec 829\r
18fd8d65 830 @retval RETURN_SUCCESS Register successfully.\r
ed7752ec 831 @retval RETURN_OUT_OF_RESOURCES No enough memory to store this handler.\r
d8c79a81 832**/\r
8bd22b8a 833RETURN_STATUS\r
d8c79a81 834EFIAPI\r
18fd8d65
LG
835TianoDecompressLibConstructor (\r
836)\r
d8c79a81 837{\r
18fd8d65
LG
838 return ExtractGuidedSectionRegisterHandlers (\r
839 &gTianoCustomDecompressGuid,\r
840 TianoDecompressGetInfo,\r
841 TianoDecompress\r
842 ); \r
6bee1632 843}\r