]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - 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
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#include <Guid/CustomDecompress.h>\r
20\r
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
27VOID\r
28FillBuf (\r
29 IN SCRATCH_DATA *Sd,\r
30 IN UINT16 NumOfBits\r
31 )\r
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
62/**\r
63 Get NumOfBits of bits out from mBitBuf\r
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
69 @param Sd The global scratch data.\r
70 @param NumOfBits The number of bits to pop and read.\r
71\r
72 @return The bits that are popped out.\r
73\r
74**/\r
75UINT32\r
76GetBits (\r
77 IN SCRATCH_DATA *Sd,\r
78 IN UINT16 NumOfBits\r
79 )\r
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
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
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
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
120 UINT16 Index;\r
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
130 for (Index = 0; Index <= 16; Index++) {\r
131 Count[Index] = 0;\r
132 }\r
133\r
134 for (Index = 0; Index < NumOfChar; Index++) {\r
135 Count[BitLen[Index]]++;\r
136 }\r
137 \r
138 Start[0] = 0;\r
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
153 \r
154 Weight[0] = 0;\r
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
162 Index++; \r
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
169 if (Index < Index3) {\r
170 SetMem16 (Table + Index, (Index3 - Index) * sizeof (*Table), 0);\r
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
180 if (Len == 0 || Len >= 17) {\r
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
199 if (*Pointer == 0 && Avail < (2 * NC - 1)) {\r
200 Sd->mRight[Avail] = Sd->mLeft[Avail] = 0;\r
201 *Pointer = Avail++;\r
202 }\r
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
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
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
235UINT32\r
236DecodeP (\r
237 IN SCRATCH_DATA *Sd\r
238 )\r
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
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
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
295{\r
296 UINT16 Number;\r
297 UINT16 CharC;\r
298 UINT16 Index;\r
299 UINT32 Mask;\r
300\r
301 //\r
302 // Read Extra Set Code Length Array size \r
303 //\r
304 Number = (UINT16) GetBits (Sd, nbit);\r
305\r
306 if (Number == 0) {\r
307 //\r
308 // This represents only Huffman code used\r
309 //\r
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
316 SetMem (Sd->mPTLen, nn, 0);\r
317\r
318 return 0;\r
319 }\r
320\r
321 Index = 0;\r
322\r
323 while (Index < Number && Index < NPT) {\r
324\r
325 CharC = (UINT16) (Sd->mBitBuf >> (BITBUFSIZ - 3));\r
326\r
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
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
339 \r
340 FillBuf (Sd, (UINT16) ((CharC < 7) ? 3 : CharC - 3));\r
341\r
342 Sd->mPTLen[Index++] = (UINT8) CharC;\r
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
350 if (Index == Special) {\r
351 CharC = (UINT16) GetBits (Sd, 2);\r
352 while ((INT16) (--CharC) >= 0 && Index < NPT) {\r
353 Sd->mPTLen[Index++] = 0;\r
354 }\r
355 }\r
356 }\r
357\r
358 while (Index < nn && Index < NPT) {\r
359 Sd->mPTLen[Index++] = 0;\r
360 }\r
361 \r
362 return MakeTable (Sd, nn, Sd->mPTLen, 8, Sd->mPTTable);\r
363}\r
364\r
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
374VOID\r
375ReadCLen (\r
376 SCRATCH_DATA *Sd\r
377 )\r
378{\r
379 UINT16 Number;\r
380 UINT16 CharC;\r
381 UINT16 Index;\r
382 UINT32 Mask;\r
383\r
384 Number = (UINT16) GetBits (Sd, CBIT);\r
385\r
386 if (Number == 0) {\r
387 //\r
388 // This represents only Huffman code used\r
389 //\r
390 CharC = (UINT16) GetBits (Sd, CBIT);\r
391\r
392 SetMem (Sd->mCLen, NC, 0);\r
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
402 while (Index < Number && Index < NC) {\r
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
434 while ((INT16) (--CharC) >= 0 && Index < NC) {\r
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
445 SetMem (Sd->mCLen + Index, NC - Index, 0);\r
446\r
447 MakeTable (Sd, NC, Sd->mCLen, 12, Sd->mCTable);\r
448\r
449 return ;\r
450}\r
451\r
452/**\r
453 Decode a character/length value.\r
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
458\r
459 @param Sd The global scratch data.\r
460\r
461 @return The value decoded.\r
462\r
463**/\r
464UINT16\r
465DecodeC (\r
466 SCRATCH_DATA *Sd\r
467 )\r
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
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
519VOID\r
520Decode (\r
521 SCRATCH_DATA *Sd\r
522 )\r
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
552 CharC = (UINT16) (CharC - (BIT8 - THRESHOLD));\r
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
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
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
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
600 if (SourceSize < 8) {\r
601 return RETURN_INVALID_PARAMETER;\r
602 }\r
603\r
604 CompressedSize = ReadUnaligned32 ((UINT32 *)Source);\r
605 if (SourceSize < (CompressedSize + 8)) {\r
606 return RETURN_INVALID_PARAMETER;\r
607 }\r
608\r
609 *ScratchSize = sizeof (SCRATCH_DATA);\r
610 *DestinationSize = ReadUnaligned32 ((UINT32 *)Source + 1);\r
611\r
612 return RETURN_SUCCESS;\r
613}\r
614\r
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
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
634{\r
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
662 SetMem (Sd, sizeof (SCRATCH_DATA), 0);\r
663\r
664 //\r
665 // The length of the field 'Position Set Code Length Array Size' in Block Header.\r
666 // For UEFI 2.0 de/compression algorithm(Version 1), mPBit = 4\r
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
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
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
721{\r
722 return UefiTianoDecompress (Source, Destination, Scratch, 1);\r
723}\r
724\r
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
737RETURN_STATUS\r
738EFIAPI\r
739TianoDecompressGetInfo (\r
740 IN CONST VOID *InputSection,\r
741 OUT UINT32 *OutputBufferSize,\r
742 OUT UINT32 *ScratchBufferSize,\r
743 OUT UINT16 *SectionAttribute\r
744 )\r
745\r
746{\r
747 ASSERT (SectionAttribute != NULL);\r
748\r
749 if (InputSection == NULL) {\r
750 return RETURN_INVALID_PARAMETER;\r
751 }\r
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
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
768 (*(UINT32 *) (((EFI_COMMON_SECTION_HEADER *) InputSection)->Size) & 0x00ffffff) - ((EFI_GUID_DEFINED_SECTION *) InputSection)->DataOffset,\r
769 OutputBufferSize,\r
770 ScratchBufferSize\r
771 );\r
772}\r
773\r
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
789**/\r
790RETURN_STATUS\r
791EFIAPI\r
792TianoDecompress (\r
793 IN CONST VOID *InputSection,\r
794 OUT VOID **OutputBuffer,\r
795 IN VOID *ScratchBuffer, OPTIONAL\r
796 OUT UINT32 *AuthenticationStatus\r
797 )\r
798{\r
799 ASSERT (OutputBuffer != NULL);\r
800\r
801 if (InputSection == NULL) {\r
802 return RETURN_INVALID_PARAMETER;\r
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
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
825}\r
826\r
827/**\r
828 Register TianoDecompress handler.\r
829\r
830 @retval RETURN_SUCCESS Register successfully.\r
831 @retval RETURN_OUT_OF_RESOURCES No enough memory to store this handler.\r
832**/\r
833RETURN_STATUS\r
834EFIAPI\r
835TianoDecompressLibConstructor (\r
836)\r
837{\r
838 return ExtractGuidedSectionRegisterHandlers (\r
839 &gTianoCustomDecompressGuid,\r
840 TianoDecompressGetInfo,\r
841 TianoDecompress\r
842 ); \r
843}\r