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