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