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