]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.c
MdePkg/BaseUefiDecompressLib: Improve performance of boundary validation
[mirror_edk2.git] / MdePkg / Library / BaseUefiDecompressLib / BaseUefiDecompressLib.c
1 /** @file
2 UEFI Decompress Library implementation refer to UEFI specification.
3
4 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
5 Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php.
10
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14 **/
15
16
17 #include <Base.h>
18 #include <Library/BaseLib.h>
19 #include <Library/DebugLib.h>
20 #include <Library/BaseMemoryLib.h>
21 #include <Library/UefiDecompressLib.h>
22
23 #include "BaseUefiDecompressLibInternals.h"
24
25 /**
26 Read NumOfBit of bits from source into mBitBuf.
27
28 Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source.
29
30 @param Sd The global scratch data.
31 @param NumOfBits The number of bits to shift and read.
32
33 **/
34 VOID
35 FillBuf (
36 IN SCRATCH_DATA *Sd,
37 IN UINT16 NumOfBits
38 )
39 {
40 //
41 // Left shift NumOfBits of bits in advance
42 //
43 Sd->mBitBuf = (UINT32) LShiftU64 (((UINT64)Sd->mBitBuf), NumOfBits);
44
45 //
46 // Copy data needed in bytes into mSbuBitBuf
47 //
48 while (NumOfBits > Sd->mBitCount) {
49 NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount);
50 Sd->mBitBuf |= (UINT32) LShiftU64 (((UINT64)Sd->mSubBitBuf), NumOfBits);
51
52 if (Sd->mCompSize > 0) {
53 //
54 // Get 1 byte into SubBitBuf
55 //
56 Sd->mCompSize--;
57 Sd->mSubBitBuf = Sd->mSrcBase[Sd->mInBuf++];
58 Sd->mBitCount = 8;
59
60 } else {
61 //
62 // No more bits from the source, just pad zero bit.
63 //
64 Sd->mSubBitBuf = 0;
65 Sd->mBitCount = 8;
66
67 }
68 }
69
70 //
71 // Calculate additional bit count read to update mBitCount
72 //
73 Sd->mBitCount = (UINT16) (Sd->mBitCount - NumOfBits);
74
75 //
76 // Copy NumOfBits of bits from mSubBitBuf into mBitBuf
77 //
78 Sd->mBitBuf |= Sd->mSubBitBuf >> Sd->mBitCount;
79 }
80
81 /**
82 Get NumOfBits of bits out from mBitBuf.
83
84 Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent
85 NumOfBits of bits from source. Returns NumOfBits of bits that are
86 popped out.
87
88 @param Sd The global scratch data.
89 @param NumOfBits The number of bits to pop and read.
90
91 @return The bits that are popped out.
92
93 **/
94 UINT32
95 GetBits (
96 IN SCRATCH_DATA *Sd,
97 IN UINT16 NumOfBits
98 )
99 {
100 UINT32 OutBits;
101
102 //
103 // Pop NumOfBits of Bits from Left
104 //
105 OutBits = (UINT32) (Sd->mBitBuf >> (BITBUFSIZ - NumOfBits));
106
107 //
108 // Fill up mBitBuf from source
109 //
110 FillBuf (Sd, NumOfBits);
111
112 return OutBits;
113 }
114
115 /**
116 Creates Huffman Code mapping table according to code length array.
117
118 Creates Huffman Code mapping table for Extra Set, Char&Len Set
119 and Position Set according to code length array.
120 If TableBits > 16, then ASSERT ().
121
122 @param Sd The global scratch data.
123 @param NumOfChar The number of symbols in the symbol set.
124 @param BitLen Code length array.
125 @param TableBits The width of the mapping table.
126 @param Table The table to be created.
127
128 @retval 0 OK.
129 @retval BAD_TABLE The table is corrupted.
130
131 **/
132 UINT16
133 MakeTable (
134 IN SCRATCH_DATA *Sd,
135 IN UINT16 NumOfChar,
136 IN UINT8 *BitLen,
137 IN UINT16 TableBits,
138 OUT UINT16 *Table
139 )
140 {
141 UINT16 Count[17];
142 UINT16 Weight[17];
143 UINT16 Start[18];
144 UINT16 *Pointer;
145 UINT16 Index3;
146 UINT16 Index;
147 UINT16 Len;
148 UINT16 Char;
149 UINT16 JuBits;
150 UINT16 Avail;
151 UINT16 NextCode;
152 UINT16 Mask;
153 UINT16 WordOfStart;
154 UINT16 WordOfCount;
155 UINT16 MaxTableLength;
156
157 //
158 // The maximum mapping table width supported by this internal
159 // working function is 16.
160 //
161 ASSERT (TableBits <= 16);
162
163 for (Index = 0; Index <= 16; Index++) {
164 Count[Index] = 0;
165 }
166
167 for (Index = 0; Index < NumOfChar; Index++) {
168 if (BitLen[Index] > 16) {
169 return (UINT16) BAD_TABLE;
170 }
171 Count[BitLen[Index]]++;
172 }
173
174 Start[0] = 0;
175 Start[1] = 0;
176
177 for (Index = 1; Index <= 16; Index++) {
178 WordOfStart = Start[Index];
179 WordOfCount = Count[Index];
180 Start[Index + 1] = (UINT16) (WordOfStart + (WordOfCount << (16 - Index)));
181 }
182
183 if (Start[17] != 0) {
184 /*(1U << 16)*/
185 return (UINT16) BAD_TABLE;
186 }
187
188 JuBits = (UINT16) (16 - TableBits);
189
190 Weight[0] = 0;
191 for (Index = 1; Index <= TableBits; Index++) {
192 Start[Index] >>= JuBits;
193 Weight[Index] = (UINT16) (1U << (TableBits - Index));
194 }
195
196 while (Index <= 16) {
197 Weight[Index] = (UINT16) (1U << (16 - Index));
198 Index++;
199 }
200
201 Index = (UINT16) (Start[TableBits + 1] >> JuBits);
202
203 if (Index != 0) {
204 Index3 = (UINT16) (1U << TableBits);
205 if (Index < Index3) {
206 SetMem16 (Table + Index, (Index3 - Index) * sizeof (*Table), 0);
207 }
208 }
209
210 Avail = NumOfChar;
211 Mask = (UINT16) (1U << (15 - TableBits));
212 MaxTableLength = (UINT16) (1U << TableBits);
213
214 for (Char = 0; Char < NumOfChar; Char++) {
215
216 Len = BitLen[Char];
217 if (Len == 0 || Len >= 17) {
218 continue;
219 }
220
221 NextCode = (UINT16) (Start[Len] + Weight[Len]);
222
223 if (Len <= TableBits) {
224
225 if (Start[Len] >= NextCode || NextCode > MaxTableLength){
226 return (UINT16) BAD_TABLE;
227 }
228
229 for (Index = Start[Len]; Index < NextCode; Index++) {
230 Table[Index] = Char;
231 }
232
233 } else {
234
235 Index3 = Start[Len];
236 Pointer = &Table[Index3 >> JuBits];
237 Index = (UINT16) (Len - TableBits);
238
239 while (Index != 0) {
240 if (*Pointer == 0 && Avail < (2 * NC - 1)) {
241 Sd->mRight[Avail] = Sd->mLeft[Avail] = 0;
242 *Pointer = Avail++;
243 }
244
245 if (*Pointer < (2 * NC - 1)) {
246 if ((Index3 & Mask) != 0) {
247 Pointer = &Sd->mRight[*Pointer];
248 } else {
249 Pointer = &Sd->mLeft[*Pointer];
250 }
251 }
252
253 Index3 <<= 1;
254 Index--;
255 }
256
257 *Pointer = Char;
258
259 }
260
261 Start[Len] = NextCode;
262 }
263 //
264 // Succeeds
265 //
266 return 0;
267 }
268
269 /**
270 Decodes a position value.
271
272 Get a position value according to Position Huffman Table.
273
274 @param Sd The global scratch data.
275
276 @return The position value decoded.
277
278 **/
279 UINT32
280 DecodeP (
281 IN SCRATCH_DATA *Sd
282 )
283 {
284 UINT16 Val;
285 UINT32 Mask;
286 UINT32 Pos;
287
288 Val = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];
289
290 if (Val >= MAXNP) {
291 Mask = 1U << (BITBUFSIZ - 1 - 8);
292
293 do {
294
295 if ((Sd->mBitBuf & Mask) != 0) {
296 Val = Sd->mRight[Val];
297 } else {
298 Val = Sd->mLeft[Val];
299 }
300
301 Mask >>= 1;
302 } while (Val >= MAXNP);
303 }
304 //
305 // Advance what we have read
306 //
307 FillBuf (Sd, Sd->mPTLen[Val]);
308
309 Pos = Val;
310 if (Val > 1) {
311 Pos = (UINT32) ((1U << (Val - 1)) + GetBits (Sd, (UINT16) (Val - 1)));
312 }
313
314 return Pos;
315 }
316
317 /**
318 Reads code lengths for the Extra Set or the Position Set.
319
320 Read in the Extra Set or Position Set Length Array, then
321 generate the Huffman code mapping for them.
322
323 @param Sd The global scratch data.
324 @param nn The number of symbols.
325 @param nbit The number of bits needed to represent nn.
326 @param Special The special symbol that needs to be taken care of.
327
328 @retval 0 OK.
329 @retval BAD_TABLE Table is corrupted.
330
331 **/
332 UINT16
333 ReadPTLen (
334 IN SCRATCH_DATA *Sd,
335 IN UINT16 nn,
336 IN UINT16 nbit,
337 IN UINT16 Special
338 )
339 {
340 UINT16 Number;
341 UINT16 CharC;
342 UINT16 Index;
343 UINT32 Mask;
344
345 ASSERT (nn <= NPT);
346 //
347 // Read Extra Set Code Length Array size
348 //
349 Number = (UINT16) GetBits (Sd, nbit);
350
351 if (Number == 0) {
352 //
353 // This represents only Huffman code used
354 //
355 CharC = (UINT16) GetBits (Sd, nbit);
356
357 SetMem16 (&Sd->mPTTable[0] , sizeof (Sd->mPTTable), CharC);
358
359 SetMem (Sd->mPTLen, nn, 0);
360
361 return 0;
362 }
363
364 Index = 0;
365
366 while (Index < Number && Index < NPT) {
367
368 CharC = (UINT16) (Sd->mBitBuf >> (BITBUFSIZ - 3));
369
370 //
371 // If a code length is less than 7, then it is encoded as a 3-bit
372 // value. Or it is encoded as a series of "1"s followed by a
373 // terminating "0". The number of "1"s = Code length - 4.
374 //
375 if (CharC == 7) {
376 Mask = 1U << (BITBUFSIZ - 1 - 3);
377 while (Mask & Sd->mBitBuf) {
378 Mask >>= 1;
379 CharC += 1;
380 }
381 }
382
383 FillBuf (Sd, (UINT16) ((CharC < 7) ? 3 : CharC - 3));
384
385 Sd->mPTLen[Index++] = (UINT8) CharC;
386
387 //
388 // For Code&Len Set,
389 // After the third length of the code length concatenation,
390 // a 2-bit value is used to indicated the number of consecutive
391 // zero lengths after the third length.
392 //
393 if (Index == Special) {
394 CharC = (UINT16) GetBits (Sd, 2);
395 while ((INT16) (--CharC) >= 0 && Index < NPT) {
396 Sd->mPTLen[Index++] = 0;
397 }
398 }
399 }
400
401 while (Index < nn && Index < NPT) {
402 Sd->mPTLen[Index++] = 0;
403 }
404
405 return MakeTable (Sd, nn, Sd->mPTLen, 8, Sd->mPTTable);
406 }
407
408 /**
409 Reads code lengths for Char&Len Set.
410
411 Read in and decode the Char&Len Set Code Length Array, then
412 generate the Huffman Code mapping table for the Char&Len Set.
413
414 @param Sd The global scratch data.
415
416 **/
417 VOID
418 ReadCLen (
419 SCRATCH_DATA *Sd
420 )
421 {
422 UINT16 Number;
423 UINT16 CharC;
424 UINT16 Index;
425 UINT32 Mask;
426
427 Number = (UINT16) GetBits (Sd, CBIT);
428
429 if (Number == 0) {
430 //
431 // This represents only Huffman code used
432 //
433 CharC = (UINT16) GetBits (Sd, CBIT);
434
435 SetMem (Sd->mCLen, NC, 0);
436 SetMem16 (&Sd->mCTable[0], sizeof (Sd->mCTable), CharC);
437
438 return ;
439 }
440
441 Index = 0;
442 while (Index < Number && Index < NC) {
443 CharC = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];
444 if (CharC >= NT) {
445 Mask = 1U << (BITBUFSIZ - 1 - 8);
446
447 do {
448
449 if (Mask & Sd->mBitBuf) {
450 CharC = Sd->mRight[CharC];
451 } else {
452 CharC = Sd->mLeft[CharC];
453 }
454
455 Mask >>= 1;
456
457 } while (CharC >= NT);
458 }
459 //
460 // Advance what we have read
461 //
462 FillBuf (Sd, Sd->mPTLen[CharC]);
463
464 if (CharC <= 2) {
465
466 if (CharC == 0) {
467 CharC = 1;
468 } else if (CharC == 1) {
469 CharC = (UINT16) (GetBits (Sd, 4) + 3);
470 } else if (CharC == 2) {
471 CharC = (UINT16) (GetBits (Sd, CBIT) + 20);
472 }
473
474 while ((INT16) (--CharC) >= 0 && Index < NC) {
475 Sd->mCLen[Index++] = 0;
476 }
477
478 } else {
479
480 Sd->mCLen[Index++] = (UINT8) (CharC - 2);
481
482 }
483 }
484
485 SetMem (Sd->mCLen + Index, NC - Index, 0);
486
487 MakeTable (Sd, NC, Sd->mCLen, 12, Sd->mCTable);
488
489 return ;
490 }
491
492 /**
493 Decode a character/length value.
494
495 Read one value from mBitBuf, Get one code from mBitBuf. If it is at block boundary, generates
496 Huffman code mapping table for Extra Set, Code&Len Set and
497 Position Set.
498
499 @param Sd The global scratch data.
500
501 @return The value decoded.
502
503 **/
504 UINT16
505 DecodeC (
506 SCRATCH_DATA *Sd
507 )
508 {
509 UINT16 Index2;
510 UINT32 Mask;
511
512 if (Sd->mBlockSize == 0) {
513 //
514 // Starting a new block
515 // Read BlockSize from block header
516 //
517 Sd->mBlockSize = (UINT16) GetBits (Sd, 16);
518
519 //
520 // Read in the Extra Set Code Length Array,
521 // Generate the Huffman code mapping table for Extra Set.
522 //
523 Sd->mBadTableFlag = ReadPTLen (Sd, NT, TBIT, 3);
524 if (Sd->mBadTableFlag != 0) {
525 return 0;
526 }
527
528 //
529 // Read in and decode the Char&Len Set Code Length Array,
530 // Generate the Huffman code mapping table for Char&Len Set.
531 //
532 ReadCLen (Sd);
533
534 //
535 // Read in the Position Set Code Length Array,
536 // Generate the Huffman code mapping table for the Position Set.
537 //
538 Sd->mBadTableFlag = ReadPTLen (Sd, MAXNP, Sd->mPBit, (UINT16) (-1));
539 if (Sd->mBadTableFlag != 0) {
540 return 0;
541 }
542 }
543
544 //
545 // Get one code according to Code&Set Huffman Table
546 //
547 Sd->mBlockSize--;
548 Index2 = Sd->mCTable[Sd->mBitBuf >> (BITBUFSIZ - 12)];
549
550 if (Index2 >= NC) {
551 Mask = 1U << (BITBUFSIZ - 1 - 12);
552
553 do {
554 if ((Sd->mBitBuf & Mask) != 0) {
555 Index2 = Sd->mRight[Index2];
556 } else {
557 Index2 = Sd->mLeft[Index2];
558 }
559
560 Mask >>= 1;
561 } while (Index2 >= NC);
562 }
563 //
564 // Advance what we have read
565 //
566 FillBuf (Sd, Sd->mCLen[Index2]);
567
568 return Index2;
569 }
570
571 /**
572 Decode the source data and put the resulting data into the destination buffer.
573
574 @param Sd The global scratch data.
575
576 **/
577 VOID
578 Decode (
579 SCRATCH_DATA *Sd
580 )
581 {
582 UINT16 BytesRemain;
583 UINT32 DataIdx;
584 UINT16 CharC;
585
586 BytesRemain = (UINT16) (-1);
587
588 DataIdx = 0;
589
590 for (;;) {
591 //
592 // Get one code from mBitBuf
593 //
594 CharC = DecodeC (Sd);
595 if (Sd->mBadTableFlag != 0) {
596 goto Done;
597 }
598
599 if (CharC < 256) {
600 //
601 // Process an Original character
602 //
603 if (Sd->mOutBuf >= Sd->mOrigSize) {
604 goto Done;
605 } else {
606 //
607 // Write orignal character into mDstBase
608 //
609 Sd->mDstBase[Sd->mOutBuf++] = (UINT8) CharC;
610 }
611
612 } else {
613 //
614 // Process a Pointer
615 //
616 CharC = (UINT16) (CharC - (BIT8 - THRESHOLD));
617
618 //
619 // Get string length
620 //
621 BytesRemain = CharC;
622
623 //
624 // Locate string position
625 //
626 DataIdx = Sd->mOutBuf - DecodeP (Sd) - 1;
627
628 //
629 // Write BytesRemain of bytes into mDstBase
630 //
631 BytesRemain--;
632
633 while ((INT16) (BytesRemain) >= 0) {
634 if (Sd->mOutBuf >= Sd->mOrigSize) {
635 goto Done;
636 }
637 if (DataIdx >= Sd->mOrigSize) {
638 Sd->mBadTableFlag = (UINT16) BAD_TABLE;
639 goto Done;
640 }
641 Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];
642
643 BytesRemain--;
644 }
645 //
646 // Once mOutBuf is fully filled, directly return
647 //
648 if (Sd->mOutBuf >= Sd->mOrigSize) {
649 goto Done;
650 }
651 }
652 }
653
654 Done:
655 return ;
656 }
657
658 /**
659 Given a compressed source buffer, this function retrieves the size of
660 the uncompressed buffer and the size of the scratch buffer required
661 to decompress the compressed source buffer.
662
663 Retrieves the size of the uncompressed buffer and the temporary scratch buffer
664 required to decompress the buffer specified by Source and SourceSize.
665 If the size of the uncompressed buffer or the size of the scratch buffer cannot
666 be determined from the compressed data specified by Source and SourceData,
667 then RETURN_INVALID_PARAMETER is returned. Otherwise, the size of the uncompressed
668 buffer is returned in DestinationSize, the size of the scratch buffer is returned
669 in ScratchSize, and RETURN_SUCCESS is returned.
670 This function does not have scratch buffer available to perform a thorough
671 checking of the validity of the source data. It just retrieves the "Original Size"
672 field from the beginning bytes of the source data and output it as DestinationSize.
673 And ScratchSize is specific to the decompression implementation.
674
675 If Source is NULL, then ASSERT().
676 If DestinationSize is NULL, then ASSERT().
677 If ScratchSize is NULL, then ASSERT().
678
679 @param Source The source buffer containing the compressed data.
680 @param SourceSize The size, in bytes, of the source buffer.
681 @param DestinationSize A pointer to the size, in bytes, of the uncompressed buffer
682 that will be generated when the compressed buffer specified
683 by Source and SourceSize is decompressed.
684 @param ScratchSize A pointer to the size, in bytes, of the scratch buffer that
685 is required to decompress the compressed buffer specified
686 by Source and SourceSize.
687
688 @retval RETURN_SUCCESS The size of the uncompressed data was returned
689 in DestinationSize, and the size of the scratch
690 buffer was returned in ScratchSize.
691 @retval RETURN_INVALID_PARAMETER
692 The size of the uncompressed data or the size of
693 the scratch buffer cannot be determined from
694 the compressed data specified by Source
695 and SourceSize.
696 **/
697 RETURN_STATUS
698 EFIAPI
699 UefiDecompressGetInfo (
700 IN CONST VOID *Source,
701 IN UINT32 SourceSize,
702 OUT UINT32 *DestinationSize,
703 OUT UINT32 *ScratchSize
704 )
705 {
706 UINT32 CompressedSize;
707
708 ASSERT (Source != NULL);
709 ASSERT (DestinationSize != NULL);
710 ASSERT (ScratchSize != NULL);
711
712 if (SourceSize < 8) {
713 return RETURN_INVALID_PARAMETER;
714 }
715
716 CompressedSize = ReadUnaligned32 ((UINT32 *)Source);
717 if (SourceSize < (CompressedSize + 8) || (CompressedSize + 8) < 8) {
718 return RETURN_INVALID_PARAMETER;
719 }
720
721 *ScratchSize = sizeof (SCRATCH_DATA);
722 *DestinationSize = ReadUnaligned32 ((UINT32 *)Source + 1);
723
724 return RETURN_SUCCESS;
725 }
726
727 /**
728 Decompresses a compressed source buffer.
729
730 Extracts decompressed data to its original form.
731 This function is designed so that the decompression algorithm can be implemented
732 without using any memory services. As a result, this function is not allowed to
733 call any memory allocation services in its implementation. It is the caller's
734 responsibility to allocate and free the Destination and Scratch buffers.
735 If the compressed source data specified by Source is successfully decompressed
736 into Destination, then RETURN_SUCCESS is returned. If the compressed source data
737 specified by Source is not in a valid compressed data format,
738 then RETURN_INVALID_PARAMETER is returned.
739
740 If Source is NULL, then ASSERT().
741 If Destination is NULL, then ASSERT().
742 If the required scratch buffer size > 0 and Scratch is NULL, then ASSERT().
743
744 @param Source The source buffer containing the compressed data.
745 @param Destination The destination buffer to store the decompressed data.
746 @param Scratch A temporary scratch buffer that is used to perform the decompression.
747 This is an optional parameter that may be NULL if the
748 required scratch buffer size is 0.
749
750 @retval RETURN_SUCCESS Decompression completed successfully, and
751 the uncompressed buffer is returned in Destination.
752 @retval RETURN_INVALID_PARAMETER
753 The source buffer specified by Source is corrupted
754 (not in a valid compressed format).
755 **/
756 RETURN_STATUS
757 EFIAPI
758 UefiDecompress (
759 IN CONST VOID *Source,
760 IN OUT VOID *Destination,
761 IN OUT VOID *Scratch OPTIONAL
762 )
763 {
764 UINT32 CompSize;
765 UINT32 OrigSize;
766 SCRATCH_DATA *Sd;
767 CONST UINT8 *Src;
768 UINT8 *Dst;
769
770 ASSERT (Source != NULL);
771 ASSERT (Destination != NULL);
772 ASSERT (Scratch != NULL);
773
774 Src = Source;
775 Dst = Destination;
776
777 Sd = (SCRATCH_DATA *) Scratch;
778
779 CompSize = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);
780 OrigSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);
781
782 //
783 // If compressed file size is 0, return
784 //
785 if (OrigSize == 0) {
786 return RETURN_SUCCESS;
787 }
788
789 Src = Src + 8;
790 SetMem (Sd, sizeof (SCRATCH_DATA), 0);
791
792 //
793 // The length of the field 'Position Set Code Length Array Size' in Block Header.
794 // For UEFI 2.0 de/compression algorithm(Version 1), mPBit = 4
795 //
796 Sd->mPBit = 4;
797 Sd->mSrcBase = (UINT8 *)Src;
798 Sd->mDstBase = Dst;
799 //
800 // CompSize and OrigSize are calculated in bytes
801 //
802 Sd->mCompSize = CompSize;
803 Sd->mOrigSize = OrigSize;
804
805 //
806 // Fill the first BITBUFSIZ bits
807 //
808 FillBuf (Sd, BITBUFSIZ);
809
810 //
811 // Decompress it
812 //
813 Decode (Sd);
814
815 if (Sd->mBadTableFlag != 0) {
816 //
817 // Something wrong with the source
818 //
819 return RETURN_INVALID_PARAMETER;
820 }
821
822 return RETURN_SUCCESS;
823 }