]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Foundation/Library/Pei/PeiLib/Decompress.c
6d09c6152e4e9f89e268fa54df64a91e2626b99f
[mirror_edk2.git] / EdkCompatibilityPkg / Foundation / Library / Pei / PeiLib / Decompress.c
1 /*++
2
3 Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 Decompress.c
15
16 Abstract:
17
18 Decompressor. Algorithm Ported from OPSD code (Decomp.asm)
19
20 --*/
21
22 #include "TianoCommon.h"
23 #include EFI_PROTOCOL_DEFINITION (Decompress)
24 #include EFI_PROTOCOL_DEFINITION (TianoDecompress)
25
26 EFI_STATUS
27 EFIAPI
28 EfiGetInfo (
29 IN EFI_DECOMPRESS_PROTOCOL *This,
30 IN VOID *Source,
31 IN UINT32 SrcSize,
32 OUT UINT32 *DstSize,
33 OUT UINT32 *ScratchSize
34 );
35
36 EFI_STATUS
37 EFIAPI
38 EfiDecompress (
39 IN EFI_DECOMPRESS_PROTOCOL *This,
40 IN VOID *Source,
41 IN UINT32 SrcSize,
42 IN OUT VOID *Destination,
43 IN UINT32 DstSize,
44 IN OUT VOID *Scratch,
45 IN UINT32 ScratchSize
46 );
47
48 EFI_STATUS
49 EFIAPI
50 TianoGetInfo (
51 IN EFI_TIANO_DECOMPRESS_PROTOCOL *This,
52 IN VOID *Source,
53 IN UINT32 SrcSize,
54 OUT UINT32 *DstSize,
55 OUT UINT32 *ScratchSize
56 );
57
58 EFI_STATUS
59 EFIAPI
60 TianoDecompress (
61 IN EFI_TIANO_DECOMPRESS_PROTOCOL *This,
62 IN VOID *Source,
63 IN UINT32 SrcSize,
64 IN OUT VOID *Destination,
65 IN UINT32 DstSize,
66 IN OUT VOID *Scratch,
67 IN UINT32 ScratchSize
68 );
69
70 //
71 // The protocol instance
72 //
73
74 EFI_DECOMPRESS_PROTOCOL mEfiDecompress = {
75 EfiGetInfo,
76 EfiDecompress
77 };
78
79 EFI_TIANO_DECOMPRESS_PROTOCOL mTianoDecompress = {
80 TianoGetInfo,
81 TianoDecompress
82 };
83
84 EFI_STATUS
85 InstallEfiDecompress (
86 IN OUT EFI_DECOMPRESS_PROTOCOL **This
87 )
88 /*++
89
90 Routine Description:
91
92 Install EFI decompress protocol.
93
94 Arguments:
95
96 This - Pointer to get decompress protocol as output
97
98 Returns:
99
100 EFI_SUCCESS - EFI decompress protocol successfully installed.
101
102 --*/
103 {
104 *This = &mEfiDecompress;
105 return EFI_SUCCESS;
106 }
107
108 EFI_STATUS
109 InstallTianoDecompress (
110 EFI_TIANO_DECOMPRESS_PROTOCOL **This
111 )
112 /*++
113
114 Routine Description:
115
116 Install Tiano decompress protocol.
117
118 Arguments:
119
120 This - Pointer to get decompress protocol as output
121
122 Returns:
123
124 EFI_SUCCESS - Tiano decompress protocol successfully installed.
125
126 --*/
127 {
128 *This = &mTianoDecompress;
129 return EFI_SUCCESS;
130 }
131 //
132 // Decompression algorithm begins here
133 //
134 #define BITBUFSIZ 32
135 #define MAXMATCH 256
136 #define THRESHOLD 3
137 #define CODE_BIT 16
138 #ifndef UINT8_MAX
139 #define UINT8_MAX 0xff
140 #endif
141 #define BAD_TABLE - 1
142
143 //
144 // C: Char&Len Set; P: Position Set; T: exTra Set
145 //
146 #define NC (0xff + MAXMATCH + 2 - THRESHOLD)
147 #define CBIT 9
148 #define MAXPBIT 5
149 #define TBIT 5
150 #define MAXNP ((1U << MAXPBIT) - 1)
151 #define NT (CODE_BIT + 3)
152 #if NT > MAXNP
153 #define NPT NT
154 #else
155 #define NPT MAXNP
156 #endif
157
158 typedef struct {
159 UINT8 *mSrcBase; // Starting address of compressed data
160 UINT8 *mDstBase; // Starting address of decompressed data
161 UINT32 mOutBuf;
162 UINT32 mInBuf;
163
164 UINT16 mBitCount;
165 UINT32 mBitBuf;
166 UINT32 mSubBitBuf;
167 UINT16 mBlockSize;
168 UINT32 mCompSize;
169 UINT32 mOrigSize;
170
171 UINT16 mBadTableFlag;
172
173 UINT16 mLeft[2 * NC - 1];
174 UINT16 mRight[2 * NC - 1];
175 UINT8 mCLen[NC];
176 UINT8 mPTLen[NPT];
177 UINT16 mCTable[4096];
178 UINT16 mPTTable[256];
179
180 //
181 // The length of the field 'Position Set Code Length Array Size' in Block Header.
182 // For EFI 1.1 de/compression algorithm, mPBit = 4
183 // For Tiano de/compression algorithm, mPBit = 5
184 //
185 UINT8 mPBit;
186 } SCRATCH_DATA;
187
188 STATIC
189 VOID
190 FillBuf (
191 IN SCRATCH_DATA *Sd,
192 IN UINT16 NumOfBits
193 )
194 /*++
195
196 Routine Description:
197
198 Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source.
199
200 Arguments:
201
202 Sd - The global scratch data
203 NumOfBits - The number of bits to shift and read.
204
205 Returns: (VOID)
206
207 --*/
208 {
209 Sd->mBitBuf = (UINT32) (Sd->mBitBuf << NumOfBits);
210
211 while (NumOfBits > Sd->mBitCount) {
212
213 Sd->mBitBuf |= (UINT32) (Sd->mSubBitBuf << (NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount)));
214
215 if (Sd->mCompSize > 0) {
216 //
217 // Get 1 byte into SubBitBuf
218 //
219 Sd->mCompSize--;
220 Sd->mSubBitBuf = 0;
221 Sd->mSubBitBuf = Sd->mSrcBase[Sd->mInBuf++];
222 Sd->mBitCount = 8;
223
224 } else {
225 //
226 // No more bits from the source, just pad zero bit.
227 //
228 Sd->mSubBitBuf = 0;
229 Sd->mBitCount = 8;
230
231 }
232 }
233
234 Sd->mBitCount = (UINT16) (Sd->mBitCount - NumOfBits);
235 Sd->mBitBuf |= Sd->mSubBitBuf >> Sd->mBitCount;
236 }
237
238 STATIC
239 UINT32
240 GetBits (
241 IN SCRATCH_DATA *Sd,
242 IN UINT16 NumOfBits
243 )
244 /*++
245
246 Routine Description:
247
248 Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent
249 NumOfBits of bits from source. Returns NumOfBits of bits that are
250 popped out.
251
252 Arguments:
253
254 Sd - The global scratch data.
255 NumOfBits - The number of bits to pop and read.
256
257 Returns:
258
259 The bits that are popped out.
260
261 --*/
262 {
263 UINT32 OutBits;
264
265 OutBits = (UINT32) (Sd->mBitBuf >> (BITBUFSIZ - NumOfBits));
266
267 FillBuf (Sd, NumOfBits);
268
269 return OutBits;
270 }
271
272 STATIC
273 UINT16
274 MakeTable (
275 IN SCRATCH_DATA *Sd,
276 IN UINT16 NumOfChar,
277 IN UINT8 *BitLen,
278 IN UINT16 TableBits,
279 OUT UINT16 *Table
280 )
281 /*++
282
283 Routine Description:
284
285 Creates Huffman Code mapping table according to code length array.
286
287 Arguments:
288
289 Sd - The global scratch data
290 NumOfChar - Number of symbols in the symbol set
291 BitLen - Code length array
292 TableBits - The width of the mapping table
293 Table - The table
294
295 Returns:
296
297 0 - OK.
298 BAD_TABLE - The table is corrupted.
299
300 --*/
301 {
302 UINT16 Count[17];
303 UINT16 Weight[17];
304 UINT16 Start[18];
305 UINT16 *Pointer;
306 UINT16 Index3;
307 UINT16 Index;
308 UINT16 Len;
309 UINT16 Char;
310 UINT16 JuBits;
311 UINT16 Avail;
312 UINT16 NextCode;
313 UINT16 Mask;
314
315 //
316 // TableBits should not be greater than 16.
317 //
318 if (TableBits >= (sizeof (Count)/sizeof (UINT16))) {
319 return (UINT16) BAD_TABLE;
320 }
321
322 //
323 // Initialize Count array starting from Index 0, as there is a possibility of Count array being uninitialized.
324 //
325 for (Index = 0; Index <= 16; Index++) {
326 Count[Index] = 0;
327 }
328
329 for (Index = 0; Index < NumOfChar; Index++) {
330 //
331 // Count array index should not be greater than or equal to its size.
332 //
333 if (BitLen[Index] < (sizeof (Count)/sizeof (UINT16))) {
334 Count[BitLen[Index]]++;
335 } else {
336 return (UINT16) BAD_TABLE;
337 }
338 }
339
340 Start[0] = 0;
341 Start[1] = 0;
342
343 for (Index = 1; Index <= 16; Index++) {
344 Start[Index + 1] = (UINT16) (Start[Index] + (Count[Index] << (16 - Index)));
345 }
346
347 if (Start[17] != 0) {
348 /*(1U << 16)*/
349 return (UINT16) BAD_TABLE;
350 }
351
352 JuBits = (UINT16) (16 - TableBits);
353
354 for (Index = 1; Index <= TableBits; Index++) {
355 Start[Index] >>= JuBits;
356 Weight[Index] = (UINT16) (1U << (TableBits - Index));
357 }
358
359 while (Index <= 16) {
360 Weight[Index] = (UINT16) (1U << (16 - Index));
361 Index++;
362 }
363
364 Index = (UINT16) (Start[TableBits + 1] >> JuBits);
365
366 if (Index != 0) {
367 Index3 = (UINT16) (1U << TableBits);
368 while (Index != Index3) {
369 Table[Index++] = 0;
370 }
371 }
372
373 Avail = NumOfChar;
374 Mask = (UINT16) (1U << (15 - TableBits));
375
376 for (Char = 0; Char < NumOfChar; Char++) {
377
378 Len = BitLen[Char];
379 if (Len == 0 || Len >= 17) {
380 continue;
381 }
382
383 NextCode = (UINT16) (Start[Len] + Weight[Len]);
384
385 if (Len <= TableBits) {
386
387 for (Index = Start[Len]; Index < NextCode; Index++) {
388 Table[Index] = Char;
389 }
390
391 } else {
392
393 Index3 = Start[Len];
394 Pointer = &Table[Index3 >> JuBits];
395 Index = (UINT16) (Len - TableBits);
396
397 while (Index != 0) {
398 //
399 // Avail should be lesser than size of mRight and mLeft to prevent buffer overflow.
400 //
401 if ((*Pointer == 0) && (Avail < sizeof (Sd->mRight)/sizeof (UINT16)) && (Avail < sizeof (Sd->mLeft)/sizeof (UINT16))) {
402 Sd->mRight[Avail] = Sd->mLeft[Avail] = 0;
403 *Pointer = Avail++;
404 }
405
406 //
407 // *Pointer should be lesser than size of mRight and mLeft to prevent buffer overflow.
408 //
409 if ((Index3 & Mask) && (*Pointer < (sizeof (Sd->mRight)/sizeof (UINT16)))) {
410 Pointer = &Sd->mRight[*Pointer];
411 } else if (*Pointer < (sizeof (Sd->mLeft)/sizeof (UINT16))) {
412 Pointer = &Sd->mLeft[*Pointer];
413 }
414
415 Index3 <<= 1;
416 Index--;
417 }
418
419 *Pointer = Char;
420
421 }
422
423 Start[Len] = NextCode;
424 }
425 //
426 // Succeeds
427 //
428 return 0;
429 }
430
431 STATIC
432 UINT32
433 DecodeP (
434 IN SCRATCH_DATA *Sd
435 )
436 /*++
437
438 Routine Description:
439
440 Decodes a position value.
441
442 Arguments:
443
444 Sd - the global scratch data
445
446 Returns:
447
448 The position value decoded.
449
450 --*/
451 {
452 UINT16 Val;
453 UINT32 Mask;
454 UINT32 Pos;
455
456 Val = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];
457
458 if (Val >= MAXNP) {
459 Mask = 1U << (BITBUFSIZ - 1 - 8);
460
461 do {
462
463 if (Sd->mBitBuf & Mask) {
464 Val = Sd->mRight[Val];
465 } else {
466 Val = Sd->mLeft[Val];
467 }
468
469 Mask >>= 1;
470 } while (Val >= MAXNP);
471 }
472 //
473 // Advance what we have read
474 //
475 FillBuf (Sd, Sd->mPTLen[Val]);
476
477 Pos = Val;
478 if (Val > 1) {
479 Pos = (UINT32) ((1U << (Val - 1)) + GetBits (Sd, (UINT16) (Val - 1)));
480 }
481
482 return Pos;
483 }
484
485 STATIC
486 UINT16
487 ReadPTLen (
488 IN SCRATCH_DATA *Sd,
489 IN UINT16 nn,
490 IN UINT16 nbit,
491 IN UINT16 Special
492 )
493 /*++
494
495 Routine Description:
496
497 Reads code lengths for the Extra Set or the Position Set
498
499 Arguments:
500
501 Sd - The global scratch data
502 nn - Number of symbols
503 nbit - Number of bits needed to represent nn
504 Special - The special symbol that needs to be taken care of
505
506 Returns:
507
508 0 - OK.
509 BAD_TABLE - Table is corrupted.
510
511 --*/
512 {
513 UINT16 Number;
514 UINT16 CharC;
515 UINT16 Index;
516 UINT32 Mask;
517
518 Number = (UINT16) GetBits (Sd, nbit);
519
520 if ((Number > sizeof (Sd->mPTLen)) || (nn > sizeof (Sd->mPTLen))) {
521 //
522 // Fail if Number or nn is greater than size of mPTLen
523 //
524 return (UINT16) BAD_TABLE;
525 }
526
527 if (Number == 0) {
528 CharC = (UINT16) GetBits (Sd, nbit);
529
530 for (Index = 0; Index < 256; Index++) {
531 Sd->mPTTable[Index] = CharC;
532 }
533
534 for (Index = 0; Index < nn; Index++) {
535 Sd->mPTLen[Index] = 0;
536 }
537
538 return 0;
539 }
540
541 Index = 0;
542
543 while (Index < Number) {
544
545 CharC = (UINT16) (Sd->mBitBuf >> (BITBUFSIZ - 3));
546
547 if (CharC == 7) {
548 Mask = 1U << (BITBUFSIZ - 1 - 3);
549 while (Mask & Sd->mBitBuf) {
550 Mask >>= 1;
551 CharC += 1;
552 }
553 }
554
555 FillBuf (Sd, (UINT16) ((CharC < 7) ? 3 : CharC - 3));
556
557 Sd->mPTLen[Index++] = (UINT8) CharC;
558
559 if (Index == Special) {
560 CharC = (UINT16) GetBits (Sd, 2);
561 while ((INT16) (--CharC) >= 0) {
562 if (Index >= sizeof (Sd->mPTLen)) {
563 //
564 // Fail if Index is greater than or equal to mPTLen
565 //
566 return (UINT16) BAD_TABLE;
567 }
568 Sd->mPTLen[Index++] = 0;
569 }
570 }
571 }
572
573 while (Index < nn) {
574 Sd->mPTLen[Index++] = 0;
575 }
576
577 return MakeTable (Sd, nn, Sd->mPTLen, 8, Sd->mPTTable);
578 }
579
580 STATIC
581 VOID
582 ReadCLen (
583 SCRATCH_DATA *Sd
584 )
585 /*++
586
587 Routine Description:
588
589 Reads code lengths for Char&Len Set.
590
591 Arguments:
592
593 Sd - the global scratch data
594
595 Returns: (VOID)
596
597 --*/
598 {
599 UINT16 Number;
600 UINT16 CharC;
601 UINT16 Index;
602 UINT32 Mask;
603
604 Number = (UINT16) GetBits (Sd, CBIT);
605
606 if (Number == 0) {
607 CharC = (UINT16) GetBits (Sd, CBIT);
608
609 for (Index = 0; Index < NC; Index++) {
610 Sd->mCLen[Index] = 0;
611 }
612
613 for (Index = 0; Index < 4096; Index++) {
614 Sd->mCTable[Index] = CharC;
615 }
616
617 return ;
618 }
619
620 Index = 0;
621 while (Index < Number) {
622
623 CharC = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];
624 if (CharC >= NT) {
625 Mask = 1U << (BITBUFSIZ - 1 - 8);
626
627 do {
628
629 if (Mask & Sd->mBitBuf) {
630 CharC = Sd->mRight[CharC];
631 } else {
632 CharC = Sd->mLeft[CharC];
633 }
634
635 Mask >>= 1;
636
637 } while (CharC >= NT);
638 }
639 //
640 // Advance what we have read
641 //
642 FillBuf (Sd, Sd->mPTLen[CharC]);
643
644 if (CharC <= 2) {
645
646 if (CharC == 0) {
647 CharC = 1;
648 } else if (CharC == 1) {
649 CharC = (UINT16) (GetBits (Sd, 4) + 3);
650 } else if (CharC == 2) {
651 CharC = (UINT16) (GetBits (Sd, CBIT) + 20);
652 }
653
654 while ((INT16) (--CharC) >= 0) {
655 Sd->mCLen[Index++] = 0;
656 }
657
658 } else {
659
660 Sd->mCLen[Index++] = (UINT8) (CharC - 2);
661
662 }
663 }
664
665 while (Index < NC) {
666 Sd->mCLen[Index++] = 0;
667 }
668
669 MakeTable (Sd, NC, Sd->mCLen, 12, Sd->mCTable);
670
671 return ;
672 }
673
674 STATIC
675 UINT16
676 DecodeC (
677 SCRATCH_DATA *Sd
678 )
679 /*++
680
681 Routine Description:
682
683 Decode a character/length value.
684
685 Arguments:
686
687 Sd - The global scratch data.
688
689 Returns:
690
691 The value decoded.
692
693 --*/
694 {
695 UINT16 Index2;
696 UINT32 Mask;
697
698 if (Sd->mBlockSize == 0) {
699 //
700 // Starting a new block
701 //
702 Sd->mBlockSize = (UINT16) GetBits (Sd, 16);
703 Sd->mBadTableFlag = ReadPTLen (Sd, NT, TBIT, 3);
704 if (Sd->mBadTableFlag != 0) {
705 return 0;
706 }
707
708 ReadCLen (Sd);
709
710 Sd->mBadTableFlag = ReadPTLen (Sd, MAXNP, Sd->mPBit, (UINT16) (-1));
711 if (Sd->mBadTableFlag != 0) {
712 return 0;
713 }
714 }
715
716 Sd->mBlockSize--;
717 Index2 = Sd->mCTable[Sd->mBitBuf >> (BITBUFSIZ - 12)];
718
719 if (Index2 >= NC) {
720 Mask = 1U << (BITBUFSIZ - 1 - 12);
721
722 do {
723 if (Sd->mBitBuf & Mask) {
724 Index2 = Sd->mRight[Index2];
725 } else {
726 Index2 = Sd->mLeft[Index2];
727 }
728
729 Mask >>= 1;
730 } while (Index2 >= NC);
731 }
732 //
733 // Advance what we have read
734 //
735 FillBuf (Sd, Sd->mCLen[Index2]);
736
737 return Index2;
738 }
739
740 STATIC
741 VOID
742 Decode (
743 SCRATCH_DATA *Sd
744 )
745 /*++
746
747 Routine Description:
748
749 Decode the source data and put the resulting data into the destination buffer.
750
751 Arguments:
752
753 Sd - The global scratch data
754
755 Returns: (VOID)
756
757 --*/
758 {
759 UINT16 BytesRemain;
760 UINT32 DataIdx;
761 UINT16 CharC;
762
763 BytesRemain = (UINT16) (-1);
764
765 DataIdx = 0;
766
767 for (;;) {
768 CharC = DecodeC (Sd);
769 if (Sd->mBadTableFlag != 0) {
770 return ;
771 }
772
773 if (CharC < 256) {
774 //
775 // Process an Original character
776 //
777 if (Sd->mOutBuf >= Sd->mOrigSize) {
778 return ;
779 } else {
780 Sd->mDstBase[Sd->mOutBuf++] = (UINT8) CharC;
781 }
782
783 } else {
784 //
785 // Process a Pointer
786 //
787 CharC = (UINT16) (CharC - (UINT8_MAX + 1 - THRESHOLD));
788
789 BytesRemain = CharC;
790
791 DataIdx = Sd->mOutBuf - DecodeP (Sd) - 1;
792
793 BytesRemain--;
794 while ((INT16) (BytesRemain) >= 0) {
795 Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];
796 if (Sd->mOutBuf >= Sd->mOrigSize) {
797 return ;
798 }
799
800 BytesRemain--;
801 }
802 }
803 }
804 }
805
806 EFI_STATUS
807 GetInfo (
808 IN VOID *Source,
809 IN UINT32 SrcSize,
810 OUT UINT32 *DstSize,
811 OUT UINT32 *ScratchSize
812 )
813 /*++
814
815 Routine Description:
816
817 The internal implementation of *_DECOMPRESS_PROTOCOL.GetInfo().
818
819 Arguments:
820
821 Source - The source buffer containing the compressed data.
822 SrcSize - The size of source buffer
823 DstSize - The size of destination buffer.
824 ScratchSize - The size of scratch buffer.
825
826 Returns:
827
828 EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved.
829 EFI_INVALID_PARAMETER - The source data is corrupted
830
831 --*/
832 {
833 UINT8 *Src;
834
835 *ScratchSize = sizeof (SCRATCH_DATA);
836
837 Src = Source;
838 if (SrcSize < 8) {
839 return EFI_INVALID_PARAMETER;
840 }
841
842 *DstSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);
843 return EFI_SUCCESS;
844 }
845
846 EFI_STATUS
847 Decompress (
848 IN VOID *Source,
849 IN UINT32 SrcSize,
850 IN OUT VOID *Destination,
851 IN UINT32 DstSize,
852 IN OUT VOID *Scratch,
853 IN UINT32 ScratchSize,
854 IN UINT8 Version
855 )
856 /*++
857
858 Routine Description:
859
860 The internal implementation of *_DECOMPRESS_PROTOCOL.Decompress().
861
862 Arguments:
863
864 Source - The source buffer containing the compressed data.
865 SrcSize - The size of source buffer
866 Destination - The destination buffer to store the decompressed data
867 DstSize - The size of destination buffer.
868 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
869 ScratchSize - The size of scratch buffer.
870 Version - The version of de/compression algorithm.
871 Version 1 for EFI 1.1 de/compression algorithm.
872 Version 2 for Tiano de/compression algorithm.
873
874 Returns:
875
876 EFI_SUCCESS - Decompression is successfull
877 EFI_INVALID_PARAMETER - The source data is corrupted
878
879 --*/
880 {
881 UINT32 Index;
882 UINT32 CompSize;
883 UINT32 OrigSize;
884 EFI_STATUS Status;
885 SCRATCH_DATA *Sd;
886 UINT8 *Src;
887 UINT8 *Dst;
888
889 Status = EFI_SUCCESS;
890 Src = Source;
891 Dst = Destination;
892
893 if (ScratchSize < sizeof (SCRATCH_DATA)) {
894 return EFI_INVALID_PARAMETER;
895 }
896
897 Sd = (SCRATCH_DATA *) Scratch;
898
899 if (SrcSize < 8) {
900 return EFI_INVALID_PARAMETER;
901 }
902
903 CompSize = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);
904 OrigSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);
905
906 //
907 // If compressed file size is 0, return
908 //
909 if (OrigSize == 0) {
910 return Status;
911 }
912
913 if (SrcSize < CompSize + 8) {
914 return EFI_INVALID_PARAMETER;
915 }
916
917 if (DstSize != OrigSize) {
918 return EFI_INVALID_PARAMETER;
919 }
920
921 Src = Src + 8;
922
923 for (Index = 0; Index < sizeof (SCRATCH_DATA); Index++) {
924 ((UINT8 *) Sd)[Index] = 0;
925 }
926 //
927 // The length of the field 'Position Set Code Length Array Size' in Block Header.
928 // For EFI 1.1 de/compression algorithm(Version 1), mPBit = 4
929 // For Tiano de/compression algorithm(Version 2), mPBit = 5
930 //
931 switch (Version) {
932 case 1:
933 Sd->mPBit = 4;
934 break;
935
936 case 2:
937 Sd->mPBit = 5;
938 break;
939
940 default:
941 //
942 // Currently, only have 2 versions
943 //
944 return EFI_INVALID_PARAMETER;
945 }
946
947 Sd->mSrcBase = Src;
948 Sd->mDstBase = Dst;
949 Sd->mCompSize = CompSize;
950 Sd->mOrigSize = OrigSize;
951
952 //
953 // Fill the first BITBUFSIZ bits
954 //
955 FillBuf (Sd, BITBUFSIZ);
956
957 //
958 // Decompress it
959 //
960 Decode (Sd);
961
962 if (Sd->mBadTableFlag != 0) {
963 //
964 // Something wrong with the source
965 //
966 Status = EFI_INVALID_PARAMETER;
967 }
968
969 return Status;
970 }
971
972 EFI_STATUS
973 EFIAPI
974 EfiGetInfo (
975 IN EFI_DECOMPRESS_PROTOCOL *This,
976 IN VOID *Source,
977 IN UINT32 SrcSize,
978 OUT UINT32 *DstSize,
979 OUT UINT32 *ScratchSize
980 )
981 /*++
982
983 Routine Description:
984
985 The implementation of EFI_DECOMPRESS_PROTOCOL.GetInfo().
986
987 Arguments:
988
989 This - The protocol instance pointer
990 Source - The source buffer containing the compressed data.
991 SrcSize - The size of source buffer
992 DstSize - The size of destination buffer.
993 ScratchSize - The size of scratch buffer.
994
995 Returns:
996
997 EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved.
998 EFI_INVALID_PARAMETER - The source data is corrupted
999
1000 --*/
1001 {
1002 return GetInfo (
1003 Source,
1004 SrcSize,
1005 DstSize,
1006 ScratchSize
1007 );
1008 }
1009
1010 EFI_STATUS
1011 EFIAPI
1012 EfiDecompress (
1013 IN EFI_DECOMPRESS_PROTOCOL *This,
1014 IN VOID *Source,
1015 IN UINT32 SrcSize,
1016 IN OUT VOID *Destination,
1017 IN UINT32 DstSize,
1018 IN OUT VOID *Scratch,
1019 IN UINT32 ScratchSize
1020 )
1021 /*++
1022
1023 Routine Description:
1024
1025 The implementation of EFI_DECOMPRESS_PROTOCOL.Decompress().
1026
1027 Arguments:
1028
1029 This - The protocol instance pointer
1030 Source - The source buffer containing the compressed data.
1031 SrcSize - The size of source buffer
1032 Destination - The destination buffer to store the decompressed data
1033 DstSize - The size of destination buffer.
1034 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
1035 ScratchSize - The size of scratch buffer.
1036
1037 Returns:
1038
1039 EFI_SUCCESS - Decompression is successfull
1040 EFI_INVALID_PARAMETER - The source data is corrupted
1041
1042 --*/
1043 {
1044 //
1045 // For EFI 1.1 de/compression algorithm, the version is 1.
1046 //
1047 return Decompress (
1048 Source,
1049 SrcSize,
1050 Destination,
1051 DstSize,
1052 Scratch,
1053 ScratchSize,
1054 1
1055 );
1056 }
1057
1058 EFI_STATUS
1059 EFIAPI
1060 TianoGetInfo (
1061 IN EFI_TIANO_DECOMPRESS_PROTOCOL *This,
1062 IN VOID *Source,
1063 IN UINT32 SrcSize,
1064 OUT UINT32 *DstSize,
1065 OUT UINT32 *ScratchSize
1066 )
1067 /*++
1068
1069 Routine Description:
1070
1071 The implementation of EFI_TIANO_DECOMPRESS_PROTOCOL.GetInfo().
1072
1073 Arguments:
1074
1075 This - The protocol instance pointer
1076 Source - The source buffer containing the compressed data.
1077 SrcSize - The size of source buffer
1078 DstSize - The size of destination buffer.
1079 ScratchSize - The size of scratch buffer.
1080
1081 Returns:
1082
1083 EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved.
1084 EFI_INVALID_PARAMETER - The source data is corrupted
1085
1086 --*/
1087 {
1088 return GetInfo (
1089 Source,
1090 SrcSize,
1091 DstSize,
1092 ScratchSize
1093 );
1094 }
1095
1096 EFI_STATUS
1097 EFIAPI
1098 TianoDecompress (
1099 IN EFI_TIANO_DECOMPRESS_PROTOCOL *This,
1100 IN VOID *Source,
1101 IN UINT32 SrcSize,
1102 IN OUT VOID *Destination,
1103 IN UINT32 DstSize,
1104 IN OUT VOID *Scratch,
1105 IN UINT32 ScratchSize
1106 )
1107 /*++
1108
1109 Routine Description:
1110
1111 The implementation of EFI_TIANO_DECOMPRESS_PROTOCOL.Decompress().
1112
1113 Arguments:
1114
1115 This - The protocol instance pointer
1116 Source - The source buffer containing the compressed data.
1117 SrcSize - The size of source buffer
1118 Destination - The destination buffer to store the decompressed data
1119 DstSize - The size of destination buffer.
1120 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
1121 ScratchSize - The size of scratch buffer.
1122
1123 Returns:
1124
1125 EFI_SUCCESS - Decompression is successfull
1126 EFI_INVALID_PARAMETER - The source data is corrupted
1127
1128 --*/
1129 {
1130 //
1131 // For Tiano de/compression algorithm, the version is 2.
1132 //
1133 return Decompress (
1134 Source,
1135 SrcSize,
1136 Destination,
1137 DstSize,
1138 Scratch,
1139 ScratchSize,
1140 2
1141 );
1142 }