TianoCore EDK2 master
Loading...
Searching...
No Matches
BaseUefiDecompressLib.c
Go to the documentation of this file.
1
11
21VOID
23 IN SCRATCH_DATA *Sd,
24 IN UINT16 NumOfBits
25 )
26{
27 //
28 // Left shift NumOfBits of bits in advance
29 //
30 Sd->mBitBuf = (UINT32)LShiftU64 (((UINT64)Sd->mBitBuf), NumOfBits);
31
32 //
33 // Copy data needed in bytes into mSbuBitBuf
34 //
35 while (NumOfBits > Sd->mBitCount) {
36 NumOfBits = (UINT16)(NumOfBits - Sd->mBitCount);
37 Sd->mBitBuf |= (UINT32)LShiftU64 (((UINT64)Sd->mSubBitBuf), NumOfBits);
38
39 if (Sd->mCompSize > 0) {
40 //
41 // Get 1 byte into SubBitBuf
42 //
43 Sd->mCompSize--;
44 Sd->mSubBitBuf = Sd->mSrcBase[Sd->mInBuf++];
45 Sd->mBitCount = 8;
46 } else {
47 //
48 // No more bits from the source, just pad zero bit.
49 //
50 Sd->mSubBitBuf = 0;
51 Sd->mBitCount = 8;
52 }
53 }
54
55 //
56 // Calculate additional bit count read to update mBitCount
57 //
58 Sd->mBitCount = (UINT16)(Sd->mBitCount - NumOfBits);
59
60 //
61 // Copy NumOfBits of bits from mSubBitBuf into mBitBuf
62 //
63 Sd->mBitBuf |= Sd->mSubBitBuf >> Sd->mBitCount;
64}
65
79UINT32
81 IN SCRATCH_DATA *Sd,
82 IN UINT16 NumOfBits
83 )
84{
85 UINT32 OutBits;
86
87 //
88 // Pop NumOfBits of Bits from Left
89 //
90 OutBits = (UINT32)(Sd->mBitBuf >> (BITBUFSIZ - NumOfBits));
91
92 //
93 // Fill up mBitBuf from source
94 //
95 FillBuf (Sd, NumOfBits);
96
97 return OutBits;
98}
99
117UINT16
119 IN SCRATCH_DATA *Sd,
120 IN UINT16 NumOfChar,
121 IN UINT8 *BitLen,
122 IN UINT16 TableBits,
123 OUT UINT16 *Table
124 )
125{
126 UINT16 Count[17];
127 UINT16 Weight[17];
128 UINT16 Start[18];
129 UINT16 *Pointer;
130 UINT16 Index3;
131 UINT16 Index;
132 UINT16 Len;
133 UINT16 Char;
134 UINT16 JuBits;
135 UINT16 Avail;
136 UINT16 NextCode;
137 UINT16 Mask;
138 UINT16 WordOfStart;
139 UINT16 WordOfCount;
140 UINT16 MaxTableLength;
141
142 //
143 // The maximum mapping table width supported by this internal
144 // working function is 16.
145 //
146 ASSERT (TableBits <= 16);
147
148 for (Index = 0; Index <= 16; Index++) {
149 Count[Index] = 0;
150 }
151
152 for (Index = 0; Index < NumOfChar; Index++) {
153 if (BitLen[Index] > 16) {
154 return (UINT16)BAD_TABLE;
155 }
156
157 Count[BitLen[Index]]++;
158 }
159
160 Start[0] = 0;
161 Start[1] = 0;
162
163 for (Index = 1; Index <= 16; Index++) {
164 WordOfStart = Start[Index];
165 WordOfCount = Count[Index];
166 Start[Index + 1] = (UINT16)(WordOfStart + (WordOfCount << (16 - Index)));
167 }
168
169 if (Start[17] != 0) {
170 /*(1U << 16)*/
171 return (UINT16)BAD_TABLE;
172 }
173
174 JuBits = (UINT16)(16 - TableBits);
175
176 Weight[0] = 0;
177 for (Index = 1; Index <= TableBits; Index++) {
178 Start[Index] >>= JuBits;
179 Weight[Index] = (UINT16)(1U << (TableBits - Index));
180 }
181
182 while (Index <= 16) {
183 Weight[Index] = (UINT16)(1U << (16 - Index));
184 Index++;
185 }
186
187 Index = (UINT16)(Start[TableBits + 1] >> JuBits);
188
189 if (Index != 0) {
190 Index3 = (UINT16)(1U << TableBits);
191 if (Index < Index3) {
192 SetMem16 (Table + Index, (Index3 - Index) * sizeof (*Table), 0);
193 }
194 }
195
196 Avail = NumOfChar;
197 Mask = (UINT16)(1U << (15 - TableBits));
198 MaxTableLength = (UINT16)(1U << TableBits);
199
200 for (Char = 0; Char < NumOfChar; Char++) {
201 Len = BitLen[Char];
202 if ((Len == 0) || (Len >= 17)) {
203 continue;
204 }
205
206 NextCode = (UINT16)(Start[Len] + Weight[Len]);
207
208 if (Len <= TableBits) {
209 if ((Start[Len] >= NextCode) || (NextCode > MaxTableLength)) {
210 return (UINT16)BAD_TABLE;
211 }
212
213 for (Index = Start[Len]; Index < NextCode; Index++) {
214 Table[Index] = Char;
215 }
216 } else {
217 Index3 = Start[Len];
218 Pointer = &Table[Index3 >> JuBits];
219 Index = (UINT16)(Len - TableBits);
220
221 while (Index != 0) {
222 if ((*Pointer == 0) && (Avail < (2 * NC - 1))) {
223 Sd->mRight[Avail] = Sd->mLeft[Avail] = 0;
224 *Pointer = Avail++;
225 }
226
227 if (*Pointer < (2 * NC - 1)) {
228 if ((Index3 & Mask) != 0) {
229 Pointer = &Sd->mRight[*Pointer];
230 } else {
231 Pointer = &Sd->mLeft[*Pointer];
232 }
233 }
234
235 Index3 <<= 1;
236 Index--;
237 }
238
239 *Pointer = Char;
240 }
241
242 Start[Len] = NextCode;
243 }
244
245 //
246 // Succeeds
247 //
248 return 0;
249}
250
261UINT32
263 IN SCRATCH_DATA *Sd
264 )
265{
266 UINT16 Val;
267 UINT32 Mask;
268 UINT32 Pos;
269
270 Val = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];
271
272 if (Val >= MAXNP) {
273 Mask = 1U << (BITBUFSIZ - 1 - 8);
274
275 do {
276 if ((Sd->mBitBuf & Mask) != 0) {
277 Val = Sd->mRight[Val];
278 } else {
279 Val = Sd->mLeft[Val];
280 }
281
282 Mask >>= 1;
283 } while (Val >= MAXNP);
284 }
285
286 //
287 // Advance what we have read
288 //
289 FillBuf (Sd, Sd->mPTLen[Val]);
290
291 Pos = Val;
292 if (Val > 1) {
293 Pos = (UINT32)((1U << (Val - 1)) + GetBits (Sd, (UINT16)(Val - 1)));
294 }
295
296 return Pos;
297}
298
314UINT16
316 IN SCRATCH_DATA *Sd,
317 IN UINT16 nn,
318 IN UINT16 nbit,
319 IN UINT16 Special
320 )
321{
322 UINT16 Number;
323 UINT16 CharC;
324 UINT16 Index;
325 UINT32 Mask;
326
327 ASSERT (nn <= NPT);
328 //
329 // Read Extra Set Code Length Array size
330 //
331 Number = (UINT16)GetBits (Sd, nbit);
332
333 if (Number == 0) {
334 //
335 // This represents only Huffman code used
336 //
337 CharC = (UINT16)GetBits (Sd, nbit);
338
339 SetMem16 (&Sd->mPTTable[0], sizeof (Sd->mPTTable), CharC);
340
341 SetMem (Sd->mPTLen, nn, 0);
342
343 return 0;
344 }
345
346 Index = 0;
347
348 while (Index < Number && Index < NPT) {
349 CharC = (UINT16)(Sd->mBitBuf >> (BITBUFSIZ - 3));
350
351 //
352 // If a code length is less than 7, then it is encoded as a 3-bit
353 // value. Or it is encoded as a series of "1"s followed by a
354 // terminating "0". The number of "1"s = Code length - 4.
355 //
356 if (CharC == 7) {
357 Mask = 1U << (BITBUFSIZ - 1 - 3);
358 while (Mask & Sd->mBitBuf) {
359 Mask >>= 1;
360 CharC += 1;
361 }
362 }
363
364 FillBuf (Sd, (UINT16)((CharC < 7) ? 3 : CharC - 3));
365
366 Sd->mPTLen[Index++] = (UINT8)CharC;
367
368 //
369 // For Code&Len Set,
370 // After the third length of the code length concatenation,
371 // a 2-bit value is used to indicated the number of consecutive
372 // zero lengths after the third length.
373 //
374 if (Index == Special) {
375 CharC = (UINT16)GetBits (Sd, 2);
376 while ((INT16)(--CharC) >= 0 && Index < NPT) {
377 Sd->mPTLen[Index++] = 0;
378 }
379 }
380 }
381
382 while (Index < nn && Index < NPT) {
383 Sd->mPTLen[Index++] = 0;
384 }
385
386 return MakeTable (Sd, nn, Sd->mPTLen, 8, Sd->mPTTable);
387}
388
398VOID
400 SCRATCH_DATA *Sd
401 )
402{
403 UINT16 Number;
404 UINT16 CharC;
405 UINT16 Index;
406 UINT32 Mask;
407
408 Number = (UINT16)GetBits (Sd, CBIT);
409
410 if (Number == 0) {
411 //
412 // This represents only Huffman code used
413 //
414 CharC = (UINT16)GetBits (Sd, CBIT);
415
416 SetMem (Sd->mCLen, NC, 0);
417 SetMem16 (&Sd->mCTable[0], sizeof (Sd->mCTable), CharC);
418
419 return;
420 }
421
422 Index = 0;
423 while (Index < Number && Index < NC) {
424 CharC = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];
425 if (CharC >= NT) {
426 Mask = 1U << (BITBUFSIZ - 1 - 8);
427
428 do {
429 if (Mask & Sd->mBitBuf) {
430 CharC = Sd->mRight[CharC];
431 } else {
432 CharC = Sd->mLeft[CharC];
433 }
434
435 Mask >>= 1;
436 } while (CharC >= NT);
437 }
438
439 //
440 // Advance what we have read
441 //
442 FillBuf (Sd, Sd->mPTLen[CharC]);
443
444 if (CharC <= 2) {
445 if (CharC == 0) {
446 CharC = 1;
447 } else if (CharC == 1) {
448 CharC = (UINT16)(GetBits (Sd, 4) + 3);
449 } else if (CharC == 2) {
450 CharC = (UINT16)(GetBits (Sd, CBIT) + 20);
451 }
452
453 while ((INT16)(--CharC) >= 0 && Index < NC) {
454 Sd->mCLen[Index++] = 0;
455 }
456 } else {
457 Sd->mCLen[Index++] = (UINT8)(CharC - 2);
458 }
459 }
460
461 SetMem (Sd->mCLen + Index, NC - Index, 0);
462
463 MakeTable (Sd, NC, Sd->mCLen, 12, Sd->mCTable);
464
465 return;
466}
467
480UINT16
482 SCRATCH_DATA *Sd
483 )
484{
485 UINT16 Index2;
486 UINT32 Mask;
487
488 if (Sd->mBlockSize == 0) {
489 //
490 // Starting a new block
491 // Read BlockSize from block header
492 //
493 Sd->mBlockSize = (UINT16)GetBits (Sd, 16);
494
495 //
496 // Read in the Extra Set Code Length Array,
497 // Generate the Huffman code mapping table for Extra Set.
498 //
499 Sd->mBadTableFlag = ReadPTLen (Sd, NT, TBIT, 3);
500 if (Sd->mBadTableFlag != 0) {
501 return 0;
502 }
503
504 //
505 // Read in and decode the Char&Len Set Code Length Array,
506 // Generate the Huffman code mapping table for Char&Len Set.
507 //
508 ReadCLen (Sd);
509
510 //
511 // Read in the Position Set Code Length Array,
512 // Generate the Huffman code mapping table for the Position Set.
513 //
514 Sd->mBadTableFlag = ReadPTLen (Sd, MAXNP, Sd->mPBit, (UINT16)(-1));
515 if (Sd->mBadTableFlag != 0) {
516 return 0;
517 }
518 }
519
520 //
521 // Get one code according to Code&Set Huffman Table
522 //
523 Sd->mBlockSize--;
524 Index2 = Sd->mCTable[Sd->mBitBuf >> (BITBUFSIZ - 12)];
525
526 if (Index2 >= NC) {
527 Mask = 1U << (BITBUFSIZ - 1 - 12);
528
529 do {
530 if ((Sd->mBitBuf & Mask) != 0) {
531 Index2 = Sd->mRight[Index2];
532 } else {
533 Index2 = Sd->mLeft[Index2];
534 }
535
536 Mask >>= 1;
537 } while (Index2 >= NC);
538 }
539
540 //
541 // Advance what we have read
542 //
543 FillBuf (Sd, Sd->mCLen[Index2]);
544
545 return Index2;
546}
547
554VOID
556 SCRATCH_DATA *Sd
557 )
558{
559 UINT16 BytesRemain;
560 UINT32 DataIdx;
561 UINT16 CharC;
562
563 BytesRemain = (UINT16)(-1);
564
565 DataIdx = 0;
566
567 for ( ; ;) {
568 //
569 // Get one code from mBitBuf
570 //
571 CharC = DecodeC (Sd);
572 if (Sd->mBadTableFlag != 0) {
573 goto Done;
574 }
575
576 if (CharC < 256) {
577 //
578 // Process an Original character
579 //
580 if (Sd->mOutBuf >= Sd->mOrigSize) {
581 goto Done;
582 } else {
583 //
584 // Write orignal character into mDstBase
585 //
586 Sd->mDstBase[Sd->mOutBuf++] = (UINT8)CharC;
587 }
588 } else {
589 //
590 // Process a Pointer
591 //
592 CharC = (UINT16)(CharC - (BIT8 - THRESHOLD));
593
594 //
595 // Get string length
596 //
597 BytesRemain = CharC;
598
599 //
600 // Locate string position
601 //
602 DataIdx = Sd->mOutBuf - DecodeP (Sd) - 1;
603
604 //
605 // Write BytesRemain of bytes into mDstBase
606 //
607 BytesRemain--;
608
609 while ((INT16)(BytesRemain) >= 0) {
610 if (Sd->mOutBuf >= Sd->mOrigSize) {
611 goto Done;
612 }
613
614 if (DataIdx >= Sd->mOrigSize) {
615 Sd->mBadTableFlag = (UINT16)BAD_TABLE;
616 goto Done;
617 }
618
619 Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];
620
621 BytesRemain--;
622 }
623
624 //
625 // Once mOutBuf is fully filled, directly return
626 //
627 if (Sd->mOutBuf >= Sd->mOrigSize) {
628 goto Done;
629 }
630 }
631 }
632
633Done:
634 return;
635}
636
676RETURN_STATUS
677EFIAPI
679 IN CONST VOID *Source,
680 IN UINT32 SourceSize,
681 OUT UINT32 *DestinationSize,
682 OUT UINT32 *ScratchSize
683 )
684{
685 UINT32 CompressedSize;
686
687 ASSERT (Source != NULL);
688 ASSERT (DestinationSize != NULL);
689 ASSERT (ScratchSize != NULL);
690
691 if (SourceSize < 8) {
693 }
694
695 CompressedSize = ReadUnaligned32 ((UINT32 *)Source);
696 if ((SourceSize < (CompressedSize + 8)) || ((CompressedSize + 8) < 8)) {
698 }
699
700 *ScratchSize = sizeof (SCRATCH_DATA);
701 *DestinationSize = ReadUnaligned32 ((UINT32 *)Source + 1);
702
703 return RETURN_SUCCESS;
704}
705
737RETURN_STATUS
739 IN CONST VOID *Source,
740 IN OUT VOID *Destination,
741 IN OUT VOID *Scratch,
742 IN UINT32 Version
743 )
744{
745 UINT32 CompSize;
746 UINT32 OrigSize;
747 SCRATCH_DATA *Sd;
748 CONST UINT8 *Src;
749 UINT8 *Dst;
750
751 ASSERT (Source != NULL);
752 ASSERT (Destination != NULL);
753 ASSERT (Scratch != NULL);
754 ASSERT (Version == 1 || Version == 2);
755
756 Src = Source;
757 Dst = Destination;
758
759 Sd = (SCRATCH_DATA *)Scratch;
760
761 CompSize = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);
762 OrigSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);
763
764 //
765 // If compressed file size is 0, return
766 //
767 if (OrigSize == 0) {
768 return RETURN_SUCCESS;
769 }
770
771 Src = Src + 8;
772 SetMem (Sd, sizeof (SCRATCH_DATA), 0);
773
774 //
775 // The length of the field 'Position Set Code Length Array Size' in Block Header.
776 // For UEFI 2.0 de/compression algorithm(Version 1), mPBit = 4
777 // For Tiano de/compression algorithm(Version 2), mPBit = 5
778 //
779 switch (Version) {
780 case 1:
781 Sd->mPBit = 4;
782 break;
783 case 2:
784 Sd->mPBit = 5;
785 break;
786 default:
787 ASSERT (FALSE);
788 }
789
790 Sd->mSrcBase = (UINT8 *)Src;
791 Sd->mDstBase = Dst;
792 //
793 // CompSize and OrigSize are calculated in bytes
794 //
795 Sd->mCompSize = CompSize;
796 Sd->mOrigSize = OrigSize;
797
798 //
799 // Fill the first BITBUFSIZ bits
800 //
801 FillBuf (Sd, BITBUFSIZ);
802
803 //
804 // Decompress it
805 //
806 Decode (Sd);
807
808 if (Sd->mBadTableFlag != 0) {
809 //
810 // Something wrong with the source
811 //
813 }
814
815 return RETURN_SUCCESS;
816}
817
847RETURN_STATUS
848EFIAPI
850 IN CONST VOID *Source,
851 IN OUT VOID *Destination,
852 IN OUT VOID *Scratch OPTIONAL
853 )
854{
855 return UefiTianoDecompress (Source, Destination, Scratch, 1);
856}
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: LShiftU64.c:28
UINT32 EFIAPI ReadUnaligned32(IN CONST UINT32 *Buffer)
Definition: Unaligned.c:145
VOID *EFIAPI SetMem16(OUT VOID *Buffer, IN UINTN Length, IN UINT16 Value)
VOID *EFIAPI SetMem(OUT VOID *Buffer, IN UINTN Length, IN UINT8 Value)
Definition: SetMemWrapper.c:38
VOID FillBuf(IN SCRATCH_DATA *Sd, IN UINT16 NumOfBits)
RETURN_STATUS UefiTianoDecompress(IN CONST VOID *Source, IN OUT VOID *Destination, IN OUT VOID *Scratch, IN UINT32 Version)
UINT32 GetBits(IN SCRATCH_DATA *Sd, IN UINT16 NumOfBits)
VOID ReadCLen(SCRATCH_DATA *Sd)
UINT32 DecodeP(IN SCRATCH_DATA *Sd)
UINT16 ReadPTLen(IN SCRATCH_DATA *Sd, IN UINT16 nn, IN UINT16 nbit, IN UINT16 Special)
RETURN_STATUS EFIAPI UefiDecompress(IN CONST VOID *Source, IN OUT VOID *Destination, IN OUT VOID *Scratch OPTIONAL)
UINT16 MakeTable(IN SCRATCH_DATA *Sd, IN UINT16 NumOfChar, IN UINT8 *BitLen, IN UINT16 TableBits, OUT UINT16 *Table)
VOID Decode(SCRATCH_DATA *Sd)
RETURN_STATUS EFIAPI UefiDecompressGetInfo(IN CONST VOID *Source, IN UINT32 SourceSize, OUT UINT32 *DestinationSize, OUT UINT32 *ScratchSize)
UINT16 DecodeC(SCRATCH_DATA *Sd)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define RETURN_SUCCESS
Definition: Base.h:1066
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define RETURN_INVALID_PARAMETER
Definition: Base.h:1076