aboutsummaryrefslogtreecommitdiff
path: root/CPP/7zip/Compress/LzfseDecoder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'CPP/7zip/Compress/LzfseDecoder.cpp')
-rw-r--r--CPP/7zip/Compress/LzfseDecoder.cpp83
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
296static MY_FORCE_INLINE unsigned CountZeroBits(UInt32 val, UInt32 mask) 296static 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
308static MY_FORCE_INLINE void InitLitTable(const UInt16 *freqs, UInt32 *table) 308static 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
443static MY_FORCE_INLINE int FseInStream_Init(CBitStream *s, 443static 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
479static MY_FORCE_INLINE UInt32 BitStream_Pull(CBitStream *s, unsigned numBits) 479static 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
494static MY_FORCE_INLINE UInt32 FseDecodeExtra(CFseState *pstate, 494static 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
833STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, 834HRESULT 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
927STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, 932Z7_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; }