diff options
Diffstat (limited to 'CPP/7zip/Compress/LzfseDecoder.cpp')
-rw-r--r-- | CPP/7zip/Compress/LzfseDecoder.cpp | 83 |
1 files changed, 44 insertions, 39 deletions
diff --git a/CPP/7zip/Compress/LzfseDecoder.cpp b/CPP/7zip/Compress/LzfseDecoder.cpp index 0eb10af..236d5bd 100644 --- a/CPP/7zip/Compress/LzfseDecoder.cpp +++ b/CPP/7zip/Compress/LzfseDecoder.cpp | |||
@@ -293,7 +293,7 @@ static UInt32 SumFreqs(const UInt16 *freqs, unsigned num) | |||
293 | } | 293 | } |
294 | 294 | ||
295 | 295 | ||
296 | static MY_FORCE_INLINE unsigned CountZeroBits(UInt32 val, UInt32 mask) | 296 | static Z7_FORCE_INLINE unsigned CountZeroBits(UInt32 val, UInt32 mask) |
297 | { | 297 | { |
298 | for (unsigned i = 0;;) | 298 | for (unsigned i = 0;;) |
299 | { | 299 | { |
@@ -305,7 +305,7 @@ static MY_FORCE_INLINE unsigned CountZeroBits(UInt32 val, UInt32 mask) | |||
305 | } | 305 | } |
306 | 306 | ||
307 | 307 | ||
308 | static MY_FORCE_INLINE void InitLitTable(const UInt16 *freqs, UInt32 *table) | 308 | static Z7_FORCE_INLINE void InitLitTable(const UInt16 *freqs, UInt32 *table) |
309 | { | 309 | { |
310 | for (unsigned i = 0; i < NUM_LIT_SYMBOLS; i++) | 310 | for (unsigned i = 0; i < NUM_LIT_SYMBOLS; i++) |
311 | { | 311 | { |
@@ -440,7 +440,7 @@ typedef struct | |||
440 | } CBitStream; | 440 | } CBitStream; |
441 | 441 | ||
442 | 442 | ||
443 | static MY_FORCE_INLINE int FseInStream_Init(CBitStream *s, | 443 | static Z7_FORCE_INLINE int FseInStream_Init(CBitStream *s, |
444 | int n, // [-7, 0], (-n == number_of_unused_bits) in last byte | 444 | int n, // [-7, 0], (-n == number_of_unused_bits) in last byte |
445 | const Byte **pbuf) | 445 | const Byte **pbuf) |
446 | { | 446 | { |
@@ -448,7 +448,7 @@ static MY_FORCE_INLINE int FseInStream_Init(CBitStream *s, | |||
448 | s->accum = GetUi32(*pbuf); | 448 | s->accum = GetUi32(*pbuf); |
449 | if (n) | 449 | if (n) |
450 | { | 450 | { |
451 | s->numBits = n + 32; | 451 | s->numBits = (unsigned)(n + 32); |
452 | if ((s->accum >> s->numBits) != 0) | 452 | if ((s->accum >> s->numBits) != 0) |
453 | return -1; // ERROR, encoder should have zeroed the upper bits | 453 | return -1; // ERROR, encoder should have zeroed the upper bits |
454 | } | 454 | } |
@@ -466,7 +466,7 @@ static MY_FORCE_INLINE int FseInStream_Init(CBitStream *s, | |||
466 | #define mask31(x, numBits) ((x) & (((UInt32)1 << (numBits)) - 1)) | 466 | #define mask31(x, numBits) ((x) & (((UInt32)1 << (numBits)) - 1)) |
467 | 467 | ||
468 | #define FseInStream_FLUSH \ | 468 | #define FseInStream_FLUSH \ |
469 | { unsigned nbits = (31 - in.numBits) & -8; \ | 469 | { const unsigned nbits = (31 - in.numBits) & (unsigned)-8; \ |
470 | if (nbits) { \ | 470 | if (nbits) { \ |
471 | buf -= (nbits >> 3); \ | 471 | buf -= (nbits >> 3); \ |
472 | if (buf < buf_check) return S_FALSE; \ | 472 | if (buf < buf_check) return S_FALSE; \ |
@@ -476,7 +476,7 @@ static MY_FORCE_INLINE int FseInStream_Init(CBitStream *s, | |||
476 | 476 | ||
477 | 477 | ||
478 | 478 | ||
479 | static MY_FORCE_INLINE UInt32 BitStream_Pull(CBitStream *s, unsigned numBits) | 479 | static Z7_FORCE_INLINE UInt32 BitStream_Pull(CBitStream *s, unsigned numBits) |
480 | { | 480 | { |
481 | s->numBits -= numBits; | 481 | s->numBits -= numBits; |
482 | UInt32 v = s->accum >> s->numBits; | 482 | UInt32 v = s->accum >> s->numBits; |
@@ -491,7 +491,7 @@ static MY_FORCE_INLINE UInt32 BitStream_Pull(CBitStream *s, unsigned numBits) | |||
491 | dest = (Byte)(e >> 8); } | 491 | dest = (Byte)(e >> 8); } |
492 | 492 | ||
493 | 493 | ||
494 | static MY_FORCE_INLINE UInt32 FseDecodeExtra(CFseState *pstate, | 494 | static Z7_FORCE_INLINE UInt32 FseDecodeExtra(CFseState *pstate, |
495 | const CExtraEntry *table, | 495 | const CExtraEntry *table, |
496 | CBitStream *s) | 496 | CBitStream *s) |
497 | { | 497 | { |
@@ -509,6 +509,7 @@ static MY_FORCE_INLINE UInt32 FseDecodeExtra(CFseState *pstate, | |||
509 | #define freqs_LIT (freqs_D + NUM_D_SYMBOLS) | 509 | #define freqs_LIT (freqs_D + NUM_D_SYMBOLS) |
510 | 510 | ||
511 | #define GET_BITS_64(v, offset, num, dest) dest = (UInt32) ((v >> (offset)) & ((1 << (num)) - 1)); | 511 | #define GET_BITS_64(v, offset, num, dest) dest = (UInt32) ((v >> (offset)) & ((1 << (num)) - 1)); |
512 | #define GET_BITS_64_Int32(v, offset, num, dest) dest = (Int32)((v >> (offset)) & ((1 << (num)) - 1)); | ||
512 | #define GET_BITS_32(v, offset, num, dest) dest = (CFseState)((v >> (offset)) & ((1 << (num)) - 1)); | 513 | #define GET_BITS_32(v, offset, num, dest) dest = (CFseState)((v >> (offset)) & ((1 << (num)) - 1)); |
513 | 514 | ||
514 | 515 | ||
@@ -592,22 +593,22 @@ HRESULT CDecoder::DecodeLzfse(UInt32 unpackSize, Byte version) | |||
592 | UInt64 v; | 593 | UInt64 v; |
593 | 594 | ||
594 | v = GetUi64(temp); | 595 | v = GetUi64(temp); |
595 | GET_BITS_64(v, 0, 20, numLiterals); | 596 | GET_BITS_64(v, 0, 20, numLiterals) |
596 | GET_BITS_64(v, 20, 20, litPayloadSize); | 597 | GET_BITS_64(v, 20, 20, litPayloadSize) |
597 | GET_BITS_64(v, 40, 20, numMatches); | 598 | GET_BITS_64(v, 40, 20, numMatches) |
598 | GET_BITS_64(v, 60, 3 + 1, literal_bits); // (NumberOfUsedBits - 1) | 599 | GET_BITS_64_Int32(v, 60, 3 + 1, literal_bits) // (NumberOfUsedBits - 1) |
599 | literal_bits -= 7; // (-NumberOfUnusedBits) | 600 | literal_bits -= 7; // (-NumberOfUnusedBits) |
600 | if (literal_bits > 0) | 601 | if (literal_bits > 0) |
601 | return S_FALSE; | 602 | return S_FALSE; |
602 | // GET_BITS_64(v, 63, 1, unused); | 603 | // GET_BITS_64(v, 63, 1, unused); |
603 | 604 | ||
604 | v = GetUi64(temp + 8); | 605 | v = GetUi64(temp + 8); |
605 | GET_BITS_64(v, 0, 10, lit_state_0); | 606 | GET_BITS_64(v, 0, 10, lit_state_0) |
606 | GET_BITS_64(v, 10, 10, lit_state_1); | 607 | GET_BITS_64(v, 10, 10, lit_state_1) |
607 | GET_BITS_64(v, 20, 10, lit_state_2); | 608 | GET_BITS_64(v, 20, 10, lit_state_2) |
608 | GET_BITS_64(v, 30, 10, lit_state_3); | 609 | GET_BITS_64(v, 30, 10, lit_state_3) |
609 | GET_BITS_64(v, 40, 20, lmdPayloadSize); | 610 | GET_BITS_64(v, 40, 20, lmdPayloadSize) |
610 | GET_BITS_64(v, 60, 3 + 1, lmd_bits); | 611 | GET_BITS_64_Int32(v, 60, 3 + 1, lmd_bits) |
611 | lmd_bits -= 7; | 612 | lmd_bits -= 7; |
612 | if (lmd_bits > 0) | 613 | if (lmd_bits > 0) |
613 | return S_FALSE; | 614 | return S_FALSE; |
@@ -618,10 +619,10 @@ HRESULT CDecoder::DecodeLzfse(UInt32 unpackSize, Byte version) | |||
618 | // correspond to a field in the uncompressed header version, | 619 | // correspond to a field in the uncompressed header version, |
619 | // but is required; we wouldn't know the size of the | 620 | // but is required; we wouldn't know the size of the |
620 | // compresssed header otherwise. | 621 | // compresssed header otherwise. |
621 | GET_BITS_32(v32, 0, 10, l_state); | 622 | GET_BITS_32(v32, 0, 10, l_state) |
622 | GET_BITS_32(v32, 10, 10, m_state); | 623 | GET_BITS_32(v32, 10, 10, m_state) |
623 | GET_BITS_32(v32, 20, 10 + 2, d_state); | 624 | GET_BITS_32(v32, 20, 10 + 2, d_state) |
624 | // GET_BITS_64(v, 62, 2, unused); | 625 | // GET_BITS_64(v, 62, 2, unused) |
625 | 626 | ||
626 | headerSize = GetUi32(temp + 16); | 627 | headerSize = GetUi32(temp + 16); |
627 | if (headerSize <= kPreHeaderSize + kHeaderSize) | 628 | if (headerSize <= kPreHeaderSize + kHeaderSize) |
@@ -726,11 +727,11 @@ HRESULT CDecoder::DecodeLzfse(UInt32 unpackSize, Byte version) | |||
726 | for (; lit < lit_limit; lit += 4) | 727 | for (; lit < lit_limit; lit += 4) |
727 | { | 728 | { |
728 | FseInStream_FLUSH | 729 | FseInStream_FLUSH |
729 | DECODE_LIT (lit[0], lit_state_0); | 730 | DECODE_LIT (lit[0], lit_state_0) |
730 | DECODE_LIT (lit[1], lit_state_1); | 731 | DECODE_LIT (lit[1], lit_state_1) |
731 | FseInStream_FLUSH | 732 | FseInStream_FLUSH |
732 | DECODE_LIT (lit[2], lit_state_2); | 733 | DECODE_LIT (lit[2], lit_state_2) |
733 | DECODE_LIT (lit[3], lit_state_3); | 734 | DECODE_LIT (lit[3], lit_state_3) |
734 | } | 735 | } |
735 | 736 | ||
736 | if ((buf_start - buf) * 8 != (int)in.numBits) | 737 | if ((buf_start - buf) * 8 != (int)in.numBits) |
@@ -821,7 +822,7 @@ HRESULT CDecoder::DecodeLzfse(UInt32 unpackSize, Byte version) | |||
821 | 822 | ||
822 | // LZFSE encoder writes 8 additional zero bytes before LMD payload | 823 | // LZFSE encoder writes 8 additional zero bytes before LMD payload |
823 | // We test it: | 824 | // We test it: |
824 | if ((buf - buf_start) * 8 + in.numBits != 64) | 825 | if ((size_t)(buf - buf_start) * 8 + in.numBits != 64) |
825 | return S_FALSE; | 826 | return S_FALSE; |
826 | if (GetUi64(buf_start) != 0) | 827 | if (GetUi64(buf_start) != 0) |
827 | return S_FALSE; | 828 | return S_FALSE; |
@@ -830,7 +831,7 @@ HRESULT CDecoder::DecodeLzfse(UInt32 unpackSize, Byte version) | |||
830 | } | 831 | } |
831 | 832 | ||
832 | 833 | ||
833 | STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, | 834 | HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, |
834 | const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) | 835 | const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) |
835 | { | 836 | { |
836 | PRF(printf("\n\nLzfseDecoder %7u %7u\n", (unsigned)*outSize, (unsigned)*inSize)); | 837 | PRF(printf("\n\nLzfseDecoder %7u %7u\n", (unsigned)*outSize, (unsigned)*inSize)); |
@@ -853,12 +854,14 @@ STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStr | |||
853 | 854 | ||
854 | if (LzvnMode) | 855 | if (LzvnMode) |
855 | { | 856 | { |
857 | if (!outSize || !inSize) | ||
858 | return E_NOTIMPL; | ||
856 | const UInt64 unpackSize = *outSize; | 859 | const UInt64 unpackSize = *outSize; |
857 | const UInt64 packSize = *inSize; | 860 | const UInt64 packSize = *inSize; |
858 | if (unpackSize > (UInt32)(Int32)-1 | 861 | if (unpackSize > (UInt32)(Int32)-1 |
859 | || packSize > (UInt32)(Int32)-1) | 862 | || packSize > (UInt32)(Int32)-1) |
860 | return S_FALSE; | 863 | return S_FALSE; |
861 | RINOK(DecodeLzvn((UInt32)unpackSize, (UInt32)packSize)); | 864 | RINOK(DecodeLzvn((UInt32)unpackSize, (UInt32)packSize)) |
862 | } | 865 | } |
863 | else | 866 | else |
864 | for (;;) | 867 | for (;;) |
@@ -868,12 +871,11 @@ STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStr | |||
868 | 871 | ||
869 | if (progress && ((pos - prevOut) >= (1 << 22) || (packPos - prevIn) >= (1 << 22))) | 872 | if (progress && ((pos - prevOut) >= (1 << 22) || (packPos - prevIn) >= (1 << 22))) |
870 | { | 873 | { |
871 | RINOK(progress->SetRatioInfo(&packPos, &pos)); | 874 | RINOK(progress->SetRatioInfo(&packPos, &pos)) |
872 | prevIn = packPos; | 875 | prevIn = packPos; |
873 | prevOut = pos; | 876 | prevOut = pos; |
874 | } | 877 | } |
875 | 878 | ||
876 | const UInt64 rem = *outSize - pos; | ||
877 | UInt32 v; | 879 | UInt32 v; |
878 | RINOK(GetUInt32(v)) | 880 | RINOK(GetUInt32(v)) |
879 | if ((v & 0xFFFFFF) != 0x787662) // bvx | 881 | if ((v & 0xFFFFFF) != 0x787662) // bvx |
@@ -884,12 +886,15 @@ STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStr | |||
884 | break; | 886 | break; |
885 | 887 | ||
886 | UInt32 unpackSize; | 888 | UInt32 unpackSize; |
887 | RINOK(GetUInt32(unpackSize)); | 889 | RINOK(GetUInt32(unpackSize)) |
888 | 890 | ||
889 | UInt32 cur = unpackSize; | 891 | UInt32 cur = unpackSize; |
890 | if (cur > rem) | 892 | if (outSize) |
891 | cur = (UInt32)rem; | 893 | { |
892 | 894 | const UInt64 rem = *outSize - pos; | |
895 | if (cur > rem) | ||
896 | cur = (UInt32)rem; | ||
897 | } | ||
893 | unpackSize -= cur; | 898 | unpackSize -= cur; |
894 | 899 | ||
895 | HRESULT res; | 900 | HRESULT res; |
@@ -917,15 +922,15 @@ STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStr | |||
917 | coderReleaser.NeedFlush = false; | 922 | coderReleaser.NeedFlush = false; |
918 | HRESULT res = m_OutWindowStream.Flush(); | 923 | HRESULT res = m_OutWindowStream.Flush(); |
919 | if (res == S_OK) | 924 | if (res == S_OK) |
920 | if (*inSize != m_InStream.GetProcessedSize() | 925 | if ((inSize && *inSize != m_InStream.GetProcessedSize()) |
921 | || *outSize != m_OutWindowStream.GetProcessedSize()) | 926 | || (outSize && *outSize != m_OutWindowStream.GetProcessedSize())) |
922 | res = S_FALSE; | 927 | res = S_FALSE; |
923 | return res; | 928 | return res; |
924 | } | 929 | } |
925 | 930 | ||
926 | 931 | ||
927 | STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, | 932 | Z7_COM7F_IMF(CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, |
928 | const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) | 933 | const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)) |
929 | { | 934 | { |
930 | try { return CodeReal(inStream, outStream, inSize, outSize, progress); } | 935 | try { return CodeReal(inStream, outStream, inSize, outSize, progress); } |
931 | catch(const CInBufferException &e) { return e.ErrorCode; } | 936 | catch(const CInBufferException &e) { return e.ErrorCode; } |