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