diff options
author | Igor Pavlov <ipavlov@users.sourceforge.net> | 2014-11-23 03:00:00 +0300 |
---|---|---|
committer | Kornel LesiĆski <kornel@geekhood.net> | 2016-05-28 02:16:51 +0300 |
commit | f08f4dcc3c02464c17753b3feafcfe5243b9e236 (patch) | |
tree | b0e1b15bc5368d92dff422e8ec0818564a2b00b8 /CPP/7zip/Compress | |
parent | 83f8ddcc5b2161e1e3c49666265257fca8aeb12c (diff) |
9.349.34
Diffstat (limited to 'CPP/7zip/Compress')
99 files changed, 1416 insertions, 1091 deletions
diff --git a/CPP/7zip/Compress/ArjDecoder1.cpp b/CPP/7zip/Compress/ArjDecoder1.cpp index 2c354e1e..2eaa591c 100755..100644 --- a/CPP/7zip/Compress/ArjDecoder1.cpp +++ b/CPP/7zip/Compress/ArjDecoder1.cpp @@ -260,7 +260,7 @@ HRESULT CCoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *ou UInt32 blockSize = 0; - while(pos < *outSize) + while (pos < *outSize) { if (blockSize == 0) { diff --git a/CPP/7zip/Compress/ArjDecoder1.h b/CPP/7zip/Compress/ArjDecoder1.h index 17939daf..dd12e445 100755..100644 --- a/CPP/7zip/Compress/ArjDecoder1.h +++ b/CPP/7zip/Compress/ArjDecoder1.h @@ -55,12 +55,6 @@ class CCoder : UInt32 c_table[CTABLESIZE]; UInt32 pt_table[PTABLESIZE]; - void ReleaseStreams() - { - m_OutWindowStream.ReleaseStream(); - m_InBitStream.ReleaseStream(); - } - class CCoderReleaser { CCoder *m_Coder; @@ -71,7 +65,6 @@ class CCoder : { if (NeedFlush) m_Coder->m_OutWindowStream.Flush(); - m_Coder->ReleaseStreams(); } }; friend class CCoderReleaser; diff --git a/CPP/7zip/Compress/ArjDecoder2.cpp b/CPP/7zip/Compress/ArjDecoder2.cpp index 365993bc..4903605c 100755..100644 --- a/CPP/7zip/Compress/ArjDecoder2.cpp +++ b/CPP/7zip/Compress/ArjDecoder2.cpp @@ -27,9 +27,10 @@ HRESULT CCoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *ou m_OutWindowStream.Init(false); m_InBitStream.SetStream(inStream); m_InBitStream.Init(); + CCoderReleaser coderReleaser(this); - while(pos < *outSize) + while (pos < *outSize) { const UInt32 kStartWidth = 0; const UInt32 kStopWidth = 7; diff --git a/CPP/7zip/Compress/ArjDecoder2.h b/CPP/7zip/Compress/ArjDecoder2.h index cf00975d..cf544d9e 100755..100644 --- a/CPP/7zip/Compress/ArjDecoder2.h +++ b/CPP/7zip/Compress/ArjDecoder2.h @@ -23,12 +23,6 @@ class CCoder : CLzOutWindow m_OutWindowStream; NBitm::CDecoder<CInBuffer> m_InBitStream; - void ReleaseStreams() - { - m_OutWindowStream.ReleaseStream(); - m_InBitStream.ReleaseStream(); - } - class CCoderReleaser { CCoder *m_Coder; @@ -39,7 +33,6 @@ class CCoder : { if (NeedFlush) m_Coder->m_OutWindowStream.Flush(); - m_Coder->ReleaseStreams(); } }; friend class CCoderReleaser; diff --git a/CPP/7zip/Compress/BZip2Const.h b/CPP/7zip/Compress/BZip2Const.h index 62427aa6..62427aa6 100755..100644 --- a/CPP/7zip/Compress/BZip2Const.h +++ b/CPP/7zip/Compress/BZip2Const.h diff --git a/CPP/7zip/Compress/BZip2Crc.cpp b/CPP/7zip/Compress/BZip2Crc.cpp index 4e4741f4..4e4741f4 100755..100644 --- a/CPP/7zip/Compress/BZip2Crc.cpp +++ b/CPP/7zip/Compress/BZip2Crc.cpp diff --git a/CPP/7zip/Compress/BZip2Crc.h b/CPP/7zip/Compress/BZip2Crc.h index 876945b5..1b5755b5 100755..100644 --- a/CPP/7zip/Compress/BZip2Crc.h +++ b/CPP/7zip/Compress/BZip2Crc.h @@ -3,7 +3,7 @@ #ifndef __BZIP2_CRC_H #define __BZIP2_CRC_H -#include "Common/Types.h" +#include "../../Common/MyTypes.h" class CBZip2Crc { diff --git a/CPP/7zip/Compress/BZip2Decoder.cpp b/CPP/7zip/Compress/BZip2Decoder.cpp index cb1f981a..3798421e 100755..100644 --- a/CPP/7zip/Compress/BZip2Decoder.cpp +++ b/CPP/7zip/Compress/BZip2Decoder.cpp @@ -85,41 +85,21 @@ void CState::Free() Counters = 0; } -UInt32 CDecoder::ReadBits(unsigned numBits) { return m_InStream.ReadBits(numBits); } -Byte CDecoder::ReadByte() {return (Byte)ReadBits(8); } -bool CDecoder::ReadBit() { return ReadBits(1) != 0; } +Byte CDecoder::ReadByte() { return (Byte)Base.ReadBits(8); } -UInt32 CDecoder::ReadCrc() -{ - UInt32 crc = 0; - for (int i = 0; i < 4; i++) - { - crc <<= 8; - crc |= ReadByte(); - } - return crc; -} +UInt32 CBase::ReadBits(unsigned numBits) { return BitDecoder.ReadBits(numBits); } +unsigned CBase::ReadBit() { return (unsigned)BitDecoder.ReadBits(1); } -static UInt32 NO_INLINE ReadBits(NBitm::CDecoder<CInBuffer> *m_InStream, unsigned num) +HRESULT CBase::ReadBlock(UInt32 *charCounters, UInt32 blockSizeMax, CBlockProps *props) { - return m_InStream->ReadBits(num); -} - -static UInt32 NO_INLINE ReadBit(NBitm::CDecoder<CInBuffer> *m_InStream) -{ - return m_InStream->ReadBits(1); -} + NumBlocks++; -static HRESULT NO_INLINE ReadBlock(NBitm::CDecoder<CInBuffer> *m_InStream, - UInt32 *CharCounters, UInt32 blockSizeMax, Byte *m_Selectors, CHuffmanDecoder *m_HuffmanDecoders, - UInt32 *blockSizeRes, UInt32 *origPtrRes, bool *randRes) -{ - if (randRes) - *randRes = ReadBit(m_InStream) ? true : false; - *origPtrRes = ReadBits(m_InStream, kNumOrigBits); + if (props->randMode) + props->randMode = ReadBit() ? true : false; + props->origPtr = ReadBits(kNumOrigBits); // in original code it compares OrigPtr to (UInt32)(10 + blockSizeMax)) : why ? - if (*origPtrRes >= blockSizeMax) + if (props->origPtr >= blockSizeMax) return S_FALSE; CMtf8Decoder mtf; @@ -130,11 +110,11 @@ static HRESULT NO_INLINE ReadBlock(NBitm::CDecoder<CInBuffer> *m_InStream, Byte inUse16[16]; int i; for (i = 0; i < 16; i++) - inUse16[i] = (Byte)ReadBit(m_InStream); + inUse16[i] = (Byte)ReadBit(); for (i = 0; i < 256; i++) if (inUse16[i >> 4]) { - if (ReadBit(m_InStream)) + if (ReadBit()) mtf.Add(numInUse++, (Byte)i); } if (numInUse == 0) @@ -143,11 +123,11 @@ static HRESULT NO_INLINE ReadBlock(NBitm::CDecoder<CInBuffer> *m_InStream, } int alphaSize = numInUse + 2; - int numTables = ReadBits(m_InStream, kNumTablesBits); + int numTables = ReadBits(kNumTablesBits); if (numTables < kNumTablesMin || numTables > kNumTablesMax) return S_FALSE; - UInt32 numSelectors = ReadBits(m_InStream, kNumSelectorsBits); + UInt32 numSelectors = ReadBits(kNumSelectorsBits); if (numSelectors < 1 || numSelectors > kNumSelectorsMax) return S_FALSE; @@ -156,12 +136,12 @@ static HRESULT NO_INLINE ReadBlock(NBitm::CDecoder<CInBuffer> *m_InStream, int t = 0; do mtfPos[t] = (Byte)t; - while(++t < numTables); + while (++t < numTables); UInt32 i = 0; do { int j = 0; - while (ReadBit(m_InStream)) + while (ReadBit()) if (++j >= numTables) return S_FALSE; Byte tmp = mtfPos[j]; @@ -169,14 +149,14 @@ static HRESULT NO_INLINE ReadBlock(NBitm::CDecoder<CInBuffer> *m_InStream, mtfPos[j] = mtfPos[j - 1]; m_Selectors[i] = mtfPos[0] = tmp; } - while(++i < numSelectors); + while (++i < numSelectors); } int t = 0; do { Byte lens[kMaxAlphaSize]; - int len = (int)ReadBits(m_InStream, kNumLevelsBits); + int len = (int)ReadBits(kNumLevelsBits); int i; for (i = 0; i < alphaSize; i++) { @@ -184,22 +164,22 @@ static HRESULT NO_INLINE ReadBlock(NBitm::CDecoder<CInBuffer> *m_InStream, { if (len < 1 || len > kMaxHuffmanLen) return S_FALSE; - if (!ReadBit(m_InStream)) + if (!ReadBit()) break; - len += 1 - (int)(ReadBit(m_InStream) << 1); + len += 1 - (int)(ReadBit() << 1); } lens[i] = (Byte)len; } for (; i < kMaxAlphaSize; i++) lens[i] = 0; - if(!m_HuffmanDecoders[t].SetCodeLengths(lens)) + if (!m_HuffmanDecoders[t].SetCodeLengths(lens)) return S_FALSE; } - while(++t < numTables); + while (++t < numTables); { for (int i = 0; i < 256; i++) - CharCounters[i] = 0; + charCounters[i] = 0; } UInt32 blockSize = 0; @@ -221,7 +201,10 @@ static HRESULT NO_INLINE ReadBlock(NBitm::CDecoder<CInBuffer> *m_InStream, } groupSize--; - UInt32 nextSym = huffmanDecoder->DecodeSymbol(m_InStream); + if (BitDecoder.ExtraBitsWereRead_Fast()) + break; + + UInt32 nextSym = huffmanDecoder->DecodeSymbol(&BitDecoder); if (nextSym < 2) { @@ -233,10 +216,10 @@ static HRESULT NO_INLINE ReadBlock(NBitm::CDecoder<CInBuffer> *m_InStream, if (runCounter != 0) { UInt32 b = (UInt32)mtf.GetHead(); - CharCounters[b] += runCounter; + charCounters[b] += runCounter; do - CharCounters[256 + blockSize++] = b; - while(--runCounter != 0); + charCounters[256 + blockSize++] = b; + while (--runCounter != 0); runPower = 0; } if (nextSym <= (UInt32)numInUse) @@ -244,17 +227,20 @@ static HRESULT NO_INLINE ReadBlock(NBitm::CDecoder<CInBuffer> *m_InStream, UInt32 b = (UInt32)mtf.GetAndMove((int)nextSym - 1); if (blockSize >= blockSizeMax) return S_FALSE; - CharCounters[b]++; - CharCounters[256 + blockSize++] = b; + charCounters[b]++; + charCounters[256 + blockSize++] = b; } else if (nextSym == (UInt32)numInUse + 1) break; else return S_FALSE; } + + if (BitDecoder.ExtraBitsWereRead()) + return S_FALSE; } - *blockSizeRes = blockSize; - return (*origPtrRes < blockSize) ? S_OK : S_FALSE; + props->blockSize = blockSize; + return (props->origPtr < props->blockSize) ? S_OK : S_FALSE; } static void NO_INLINE DecodeBlock1(UInt32 *charCounters, UInt32 blockSize) @@ -273,7 +259,7 @@ static void NO_INLINE DecodeBlock1(UInt32 *charCounters, UInt32 blockSize) UInt32 i = 0; do tt[charCounters[tt[i] & 0xFF]++] |= (i << 8); - while(++i < blockSize); + while (++i < blockSize); } static UInt32 NO_INLINE DecodeBlock2(const UInt32 *tt, UInt32 blockSize, UInt32 OrigPtr, COutBuffer &m_OutStream) @@ -363,7 +349,7 @@ static UInt32 NO_INLINE DecodeBlock2(const UInt32 *tt, UInt32 blockSize, UInt32 } */ } - while(--blockSize != 0); + while (--blockSize != 0); return crc.GetDigest(); } @@ -412,10 +398,17 @@ static UInt32 NO_INLINE DecodeBlock2Rand(const UInt32 *tt, UInt32 blockSize, UIn crc.UpdateByte(b); m_OutStream.WriteByte((Byte)b); } - while(--blockSize != 0); + while (--blockSize != 0); return crc.GetDigest(); } +static UInt32 NO_INLINE DecodeBlock(const CBlockProps &props, UInt32 *tt, COutBuffer &m_OutStream) +{ + if (props.randMode) + return DecodeBlock2Rand(tt, props.blockSize, props.origPtr, m_OutStream); + else + return DecodeBlock2 (tt, props.blockSize, props.origPtr, m_OutStream); +} CDecoder::CDecoder() { @@ -434,7 +427,7 @@ CDecoder::~CDecoder() Free(); } -#define RINOK_THREAD(x) { WRes __result_ = (x); if(__result_ != 0) return __result_; } +#define RINOK_THREAD(x) { WRes __result_ = (x); if (__result_ != 0) return __result_; } HRESULT CDecoder::Create() { @@ -489,37 +482,71 @@ void CDecoder::Free() #endif -HRESULT CDecoder::ReadSignatures(bool &wasFinished, UInt32 &crc) +bool IsEndSig(const Byte *p) throw() { - wasFinished = false; - Byte s[6]; - for (int i = 0; i < 6; i++) + return + p[0] == kFinSig0 && + p[1] == kFinSig1 && + p[2] == kFinSig2 && + p[3] == kFinSig3 && + p[4] == kFinSig4 && + p[5] == kFinSig5; +} + +bool IsBlockSig(const Byte *p) throw() +{ + return + p[0] == kBlockSig0 && + p[1] == kBlockSig1 && + p[2] == kBlockSig2 && + p[3] == kBlockSig3 && + p[4] == kBlockSig4 && + p[5] == kBlockSig5; +} + +HRESULT CDecoder::ReadSignature(UInt32 &crc) +{ + BzWasFinished = false; + crc = 0; + + Byte s[10]; + int i; + for (i = 0; i < 10; i++) s[i] = ReadByte(); - crc = ReadCrc(); - if (s[0] == kFinSig0) + + if (Base.BitDecoder.ExtraBitsWereRead()) + return S_FALSE; + + UInt32 v = 0; + for (i = 0; i < 4; i++) { - if (s[1] != kFinSig1 || - s[2] != kFinSig2 || - s[3] != kFinSig3 || - s[4] != kFinSig4 || - s[5] != kFinSig5) - return S_FALSE; - - wasFinished = true; - return (crc == CombinedCrc.GetDigest()) ? S_OK : S_FALSE; + v <<= 8; + v |= s[6 + i]; } - if (s[0] != kBlockSig0 || - s[1] != kBlockSig1 || - s[2] != kBlockSig2 || - s[3] != kBlockSig3 || - s[4] != kBlockSig4 || - s[5] != kBlockSig5) + + crc = v; + + if (IsBlockSig(s)) + { + IsBz = true; + CombinedCrc.Update(crc); + return S_OK; + } + + if (!IsEndSig(s)) return S_FALSE; - CombinedCrc.Update(crc); + + IsBz = true; + BzWasFinished = true; + if (crc != CombinedCrc.GetDigest()) + { + CrcError = true; + return S_FALSE; + } return S_OK; } -HRESULT CDecoder::DecodeFile(bool &isBZ, ICompressProgressInfo *progress) +HRESULT CDecoder::DecodeFile(ICompressProgressInfo *progress) { Progress = progress; #ifndef _7ZIP_ST @@ -541,18 +568,27 @@ HRESULT CDecoder::DecodeFile(bool &isBZ, ICompressProgressInfo *progress) return E_OUTOFMEMORY; #endif - isBZ = false; - Byte s[6]; + IsBz = false; + + /* + if (Base.BitDecoder.ExtraBitsWereRead()) + return E_FAIL; + */ + + Byte s[4]; int i; for (i = 0; i < 4; i++) s[i] = ReadByte(); + if (Base.BitDecoder.ExtraBitsWereRead()) + return S_FALSE; + if (s[0] != kArSig0 || s[1] != kArSig1 || s[2] != kArSig2 || s[3] <= kArSig3 || s[3] > kArSig3 + kBlockSizeMultMax) - return S_OK; - isBZ = true; + return S_FALSE; + UInt32 dicSize = (UInt32)(s[3] - kArSig3) * kBlockSizeStep; CombinedCrc.Init(); @@ -584,58 +620,59 @@ HRESULT CDecoder::DecodeFile(bool &isBZ, ICompressProgressInfo *progress) CState &state = m_States[0]; for (;;) { - RINOK(SetRatioProgress(m_InStream.GetProcessedSize())); - bool wasFinished; + RINOK(SetRatioProgress(Base.BitDecoder.GetProcessedSize())); UInt32 crc; - RINOK(ReadSignatures(wasFinished, crc)); - if (wasFinished) + RINOK(ReadSignature(crc)); + if (BzWasFinished) return S_OK; - UInt32 blockSize, origPtr; - bool randMode; - RINOK(ReadBlock(&m_InStream, state.Counters, dicSize, - m_Selectors, m_HuffmanDecoders, - &blockSize, &origPtr, &randMode)); - DecodeBlock1(state.Counters, blockSize); - if ((randMode ? - DecodeBlock2Rand(state.Counters + 256, blockSize, origPtr, m_OutStream) : - DecodeBlock2(state.Counters + 256, blockSize, origPtr, m_OutStream)) != crc) + CBlockProps props; + props.randMode = true; + RINOK(Base.ReadBlock(state.Counters, dicSize, &props)); + DecodeBlock1(state.Counters, props.blockSize); + if (DecodeBlock(props, state.Counters + 256, m_OutStream) != crc) + { + CrcError = true; return S_FALSE; + } } } - return SetRatioProgress(m_InStream.GetProcessedSize()); + return SetRatioProgress(Base.BitDecoder.GetProcessedSize()); } HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, - bool &isBZ, ICompressProgressInfo *progress) + ICompressProgressInfo *progress) { - isBZ = false; + IsBz = false; + BzWasFinished = false; + CrcError = false; + try { - if (!m_InStream.Create(kBufferSize)) + if (!Base.BitDecoder.Create(kBufferSize)) return E_OUTOFMEMORY; if (!m_OutStream.Create(kBufferSize)) return E_OUTOFMEMORY; if (inStream) - m_InStream.SetStream(inStream); + Base.BitDecoder.SetStream(inStream); - CDecoderFlusher flusher(this, inStream != NULL); + CDecoderFlusher flusher(this); if (_needInStreamInit) { - m_InStream.Init(); + Base.BitDecoder.Init(); _needInStreamInit = false; } - _inStart = m_InStream.GetProcessedSize(); + _inStart = Base.BitDecoder.GetProcessedSize(); - m_InStream.AlignToByte(); + Base.BitDecoder.AlignToByte(); m_OutStream.SetStream(outStream); m_OutStream.Init(); - RINOK(DecodeFile(isBZ, progress)); + RINOK(DecodeFile(progress)); flusher.NeedFlush = false; return Flush(); @@ -649,18 +686,26 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress) { _needInStreamInit = true; - bool isBZ; - RINOK(CodeReal(inStream, outStream, isBZ, progress)); - return isBZ ? S_OK : S_FALSE; + return CodeReal(inStream, outStream, progress); } -HRESULT CDecoder::CodeResume(ISequentialOutStream *outStream, bool &isBZ, ICompressProgressInfo *progress) +HRESULT CDecoder::CodeResume(ISequentialOutStream *outStream, ICompressProgressInfo *progress) { - return CodeReal(NULL, outStream, isBZ, progress); + return CodeReal(NULL, outStream, progress); } -STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) { m_InStream.SetStream(inStream); return S_OK; } -STDMETHODIMP CDecoder::ReleaseInStream() { m_InStream.ReleaseStream(); return S_OK; } +STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) +{ + Base.InStreamRef = inStream; + Base.BitDecoder.SetStream(inStream); + return S_OK; +} + +STDMETHODIMP CDecoder::ReleaseInStream() +{ + Base.InStreamRef.Release(); + return S_OK; +} #ifndef _7ZIP_ST @@ -709,36 +754,33 @@ void CState::ThreadFunc() Decoder->NextBlockIndex = nextBlockIndex; UInt32 crc; UInt64 packSize = 0; - UInt32 blockSize = 0, origPtr = 0; - bool randMode = false; + CBlockProps props; try { - bool wasFinished; - res = Decoder->ReadSignatures(wasFinished, crc); + res = Decoder->ReadSignature(crc); if (res != S_OK) { Decoder->Result1 = res; FinishStream(); continue; } - if (wasFinished) + if (Decoder->BzWasFinished) { Decoder->Result1 = res; FinishStream(); continue; } - res = ReadBlock(&Decoder->m_InStream, Counters, Decoder->BlockSizeMax, - Decoder->m_Selectors, Decoder->m_HuffmanDecoders, - &blockSize, &origPtr, &randMode); + props.randMode = true; + res = Decoder->Base.ReadBlock(Counters, Decoder->BlockSizeMax, &props); if (res != S_OK) { Decoder->Result1 = res; FinishStream(); continue; } - packSize = Decoder->m_InStream.GetProcessedSize(); + packSize = Decoder->Base.BitDecoder.GetProcessedSize(); } catch(const CInBufferException &e) { res = e.ErrorCode; if (res != S_OK) res = E_FAIL; } catch(...) { res = E_FAIL; } @@ -751,7 +793,7 @@ void CState::ThreadFunc() Decoder->CS.Leave(); - DecodeBlock1(Counters, blockSize); + DecodeBlock1(Counters, props.blockSize); bool needFinish = true; try @@ -760,9 +802,7 @@ void CState::ThreadFunc() needFinish = Decoder->StreamWasFinished2; if (!needFinish) { - if ((randMode ? - DecodeBlock2Rand(Counters + 256, blockSize, origPtr, Decoder->m_OutStream) : - DecodeBlock2(Counters + 256, blockSize, origPtr, Decoder->m_OutStream)) == crc) + if (DecodeBlock(props, Counters + 256, Decoder->m_OutStream) == crc) res = Decoder->SetRatioProgress(packSize); else res = S_FALSE; @@ -818,8 +858,17 @@ enum NSIS_STATE_ERROR }; -STDMETHODIMP CNsisDecoder::SetInStream(ISequentialInStream *inStream) { m_InStream.SetStream(inStream); return S_OK; } -STDMETHODIMP CNsisDecoder::ReleaseInStream() { m_InStream.ReleaseStream(); return S_OK; } +STDMETHODIMP CNsisDecoder::SetInStream(ISequentialInStream *inStream) +{ + Base.InStreamRef = inStream; + Base.BitDecoder.SetStream(inStream); + return S_OK; +} +STDMETHODIMP CNsisDecoder::ReleaseInStream() +{ + Base.InStreamRef.Release(); + return S_OK; +} STDMETHODIMP CNsisDecoder::SetOutStreamSize(const UInt64 * /* outSize */) { @@ -843,17 +892,17 @@ STDMETHODIMP CNsisDecoder::Read(void *data, UInt32 size, UInt32 *processedSize) if (_nsisState == NSIS_STATE_INIT) { - if (!m_InStream.Create(kBufferSize)) + if (!Base.BitDecoder.Create(kBufferSize)) return E_OUTOFMEMORY; if (!state.Alloc()) return E_OUTOFMEMORY; - m_InStream.Init(); + Base.BitDecoder.Init(); _nsisState = NSIS_STATE_NEW_BLOCK; } if (_nsisState == NSIS_STATE_NEW_BLOCK) { - Byte b = (Byte)m_InStream.ReadBits(8); + Byte b = (Byte)Base.ReadBits(8); if (b == kFinSig0) { _nsisState = NSIS_STATE_FINISHED; @@ -864,12 +913,13 @@ STDMETHODIMP CNsisDecoder::Read(void *data, UInt32 size, UInt32 *processedSize) _nsisState = NSIS_STATE_ERROR; return S_FALSE; } - UInt32 origPtr; - RINOK(ReadBlock(&m_InStream, state.Counters, 9 * kBlockSizeStep, - m_Selectors, m_HuffmanDecoders, &_blockSize, &origPtr, NULL)); - DecodeBlock1(state.Counters, _blockSize); + CBlockProps props; + props.randMode = false; + RINOK(Base.ReadBlock(state.Counters, 9 * kBlockSizeStep, &props)); + _blockSize = props.blockSize; + DecodeBlock1(state.Counters, props.blockSize); const UInt32 *tt = state.Counters + 256; - _tPos = tt[tt[origPtr] >> 8]; + _tPos = tt[tt[props.origPtr] >> 8]; _prevByte = (unsigned)(_tPos & 0xFF); _numReps = 0; _repRem = 0; diff --git a/CPP/7zip/Compress/BZip2Decoder.h b/CPP/7zip/Compress/BZip2Decoder.h index e6dec1ea..2c28c5a1 100755..100644 --- a/CPP/7zip/Compress/BZip2Decoder.h +++ b/CPP/7zip/Compress/BZip2Decoder.h @@ -23,6 +23,9 @@ namespace NCompress { namespace NBZip2 { +bool IsEndSig(const Byte *p) throw(); +bool IsBlockSig(const Byte *p) throw(); + typedef NCompress::NHuffman::CDecoder<kMaxHuffmanLen, kMaxAlphaSize> CHuffmanDecoder; class CDecoder; @@ -57,6 +60,40 @@ struct CState void Free(); }; +struct CBlockProps +{ + UInt32 blockSize; + UInt32 origPtr; + bool randMode; + + CBlockProps(): blockSize(0), origPtr(0), randMode(false) {} +}; + +struct CBase +{ + CMyComPtr<ISequentialInStream> InStreamRef; + NBitm::CDecoder<CInBuffer> BitDecoder; + +private: + Byte m_Selectors[kNumSelectorsMax]; + CHuffmanDecoder m_HuffmanDecoders[kNumTablesMax]; + +public: + UInt64 NumBlocks; + + CBase(): NumBlocks(0) {} + UInt32 ReadBits(unsigned numBits); + unsigned ReadBit(); + void InitNumBlocks() { NumBlocks = 0; } + + /* + ReadBlock() props->randMode: + in: need read randMode bit, + out: randMode status + */ + HRESULT ReadBlock(UInt32 *charCounters, UInt32 blockSizeMax, CBlockProps *props); +}; + class CDecoder : public ICompressCoder, #ifndef _7ZIP_ST @@ -67,37 +104,30 @@ class CDecoder : public: COutBuffer m_OutStream; Byte MtPad[1 << 8]; // It's pad for Multi-Threading. Must be >= Cache_Line_Size. - NBitm::CDecoder<CInBuffer> m_InStream; - Byte m_Selectors[kNumSelectorsMax]; - CHuffmanDecoder m_HuffmanDecoders[kNumTablesMax]; + + CBase Base; + UInt64 _inStart; private: bool _needInStreamInit; - UInt32 ReadBits(unsigned numBits); Byte ReadByte(); - bool ReadBit(); - UInt32 ReadCrc(); - HRESULT DecodeFile(bool &isBZ, ICompressProgressInfo *progress); - HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, - bool &isBZ, ICompressProgressInfo *progress); + + HRESULT DecodeFile(ICompressProgressInfo *progress); + HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress); + class CDecoderFlusher { CDecoder *_decoder; public: bool NeedFlush; - bool ReleaseInStream; - CDecoderFlusher(CDecoder *decoder, bool releaseInStream): - _decoder(decoder), - ReleaseInStream(releaseInStream), - NeedFlush(true) {} + CDecoderFlusher(CDecoder *decoder): _decoder(decoder), NeedFlush(true) {} ~CDecoderFlusher() { if (NeedFlush) _decoder->Flush(); - _decoder->ReleaseStreams(ReleaseInStream); } }; @@ -123,6 +153,11 @@ public: HRESULT Result2; UInt32 BlockSizeMax; + + bool IsBz; + bool BzWasFinished; // bzip stream was finished with end signature + bool CrcError; // it can CRC error of block or CRC error of whole stream. + ~CDecoder(); HRESULT Create(); void Free(); @@ -134,15 +169,9 @@ public: CDecoder(); HRESULT SetRatioProgress(UInt64 packSize); - HRESULT ReadSignatures(bool &wasFinished, UInt32 &crc); + HRESULT ReadSignature(UInt32 &crc); HRESULT Flush() { return m_OutStream.Flush(); } - void ReleaseStreams(bool releaseInStream) - { - if (releaseInStream) - m_InStream.ReleaseStream(); - m_OutStream.ReleaseStream(); - } MY_QUERYINTERFACE_BEGIN2(ICompressCoder) #ifndef _7ZIP_ST @@ -159,8 +188,13 @@ public: STDMETHOD(SetInStream)(ISequentialInStream *inStream); STDMETHOD(ReleaseInStream)(); - HRESULT CodeResume(ISequentialOutStream *outStream, bool &isBZ, ICompressProgressInfo *progress); - UInt64 GetInputProcessedSize() const { return m_InStream.GetProcessedSize(); } + HRESULT CodeResume(ISequentialOutStream *outStream, ICompressProgressInfo *progress); + + UInt64 GetStreamSize() const { return Base.BitDecoder.GetStreamSize(); } + UInt64 GetInputProcessedSize() const { return Base.BitDecoder.GetProcessedSize(); } + + void InitNumBlocks() { Base.InitNumBlocks(); } + UInt64 GetNumBlocks() const { return Base.NumBlocks; } #ifndef _7ZIP_ST STDMETHOD(SetNumberOfThreads)(UInt32 numThreads); @@ -174,9 +208,8 @@ class CNsisDecoder : public ICompressSetOutStreamSize, public CMyUnknownImp { - NBitm::CDecoder<CInBuffer> m_InStream; - Byte m_Selectors[kNumSelectorsMax]; - CHuffmanDecoder m_HuffmanDecoders[kNumTablesMax]; + CBase Base; + CState m_State; int _nsisState; diff --git a/CPP/7zip/Compress/BZip2Encoder.cpp b/CPP/7zip/Compress/BZip2Encoder.cpp index 6dafc45f..2bdbe989 100755..100644 --- a/CPP/7zip/Compress/BZip2Encoder.cpp +++ b/CPP/7zip/Compress/BZip2Encoder.cpp @@ -53,7 +53,7 @@ static THREAD_FUNC_DECL MFThread(void *threadCoderInfo) return ((CThreadInfo *)threadCoderInfo)->ThreadFunc(); } -#define RINOK_THREAD(x) { WRes __result_ = (x); if(__result_ != 0) return __result_; } +#define RINOK_THREAD(x) { WRes __result_ = (x); if (__result_ != 0) return __result_; } HRESULT CThreadInfo::Create() { @@ -244,9 +244,8 @@ UInt32 CEncoder::ReadRleBlock(Byte *buffer) return i; } -void CThreadInfo::WriteBits2(UInt32 value, UInt32 numBits) - { m_OutStreamCurrent->WriteBits(value, numBits); } -void CThreadInfo::WriteByte2(Byte b) { WriteBits2(b , 8); } +void CThreadInfo::WriteBits2(UInt32 value, unsigned numBits) { m_OutStreamCurrent->WriteBits(value, numBits); } +void CThreadInfo::WriteByte2(Byte b) { WriteBits2(b, 8); } void CThreadInfo::WriteBit2(bool v) { WriteBits2((v ? 1 : 0), 1); } void CThreadInfo::WriteCrc2(UInt32 v) { @@ -254,9 +253,8 @@ void CThreadInfo::WriteCrc2(UInt32 v) WriteByte2(((Byte)(v >> (24 - i * 8)))); } -void CEncoder::WriteBits(UInt32 value, UInt32 numBits) - { m_OutStream.WriteBits(value, numBits); } -void CEncoder::WriteByte(Byte b) { WriteBits(b , 8); } +void CEncoder::WriteBits(UInt32 value, unsigned numBits) { m_OutStream.WriteBits(value, numBits); } +void CEncoder::WriteByte(Byte b) { WriteBits(b, 8); } void CEncoder::WriteBit(bool v) { WriteBits((v ? 1 : 0), 1); } void CEncoder::WriteCrc(UInt32 v) { @@ -318,7 +316,7 @@ void CThreadInfo::EncodeBlock(const Byte *block, UInt32 blockSize) block--; do { - int pos = mtf.FindAndMove(block[bsIndex[i]]); + unsigned pos = mtf.FindAndMove(block[bsIndex[i]]); if (pos == 0) rleSize++; else @@ -374,7 +372,7 @@ void CThreadInfo::EncodeBlock(const Byte *block, UInt32 blockSize) { int numTables; - if(m_OptimizeNumTables) + if (m_OptimizeNumTables) { m_OutStreamCurrent->SetPos(startPos); m_OutStreamCurrent->SetCurState((startPos & 7), startCurByte); @@ -415,12 +413,12 @@ void CThreadInfo::EncodeBlock(const Byte *block, UInt32 blockSize) Byte *lens = Lens[t - 1]; int i = 0; do - lens[i] = (i >= gs && i < ge) ? 0 : 1; + lens[i] = (Byte)((i >= gs && i < ge) ? 0 : 1); while (++i < alphaSize); gs = ge; remFreq -= aFreq; } - while(--t != 0); + while (--t != 0); } @@ -430,7 +428,7 @@ void CThreadInfo::EncodeBlock(const Byte *block, UInt32 blockSize) int t = 0; do memset(Freqs[t], 0, sizeof(Freqs[t])); - while(++t < numTables); + while (++t < numTables); } { @@ -465,7 +463,7 @@ void CThreadInfo::EncodeBlock(const Byte *block, UInt32 blockSize) bestPrice = price; } } - while(++t < numTables); + while (++t < numTables); UInt32 *freqs = Freqs[m_Selectors[g++]]; int j = 0; do @@ -483,10 +481,10 @@ void CThreadInfo::EncodeBlock(const Byte *block, UInt32 blockSize) do if (freqs[i] == 0) freqs[i] = 1; - while(++i < alphaSize); + while (++i < alphaSize); Huffman_Generate(freqs, Codes[t], Lens[t], kMaxAlphaSize, kMaxHuffmanLenForEncoding); } - while(++t < numTables); + while (++t < numTables); } { @@ -495,7 +493,7 @@ void CThreadInfo::EncodeBlock(const Byte *block, UInt32 blockSize) int t = 0; do mtfSel[t] = (Byte)t; - while(++t < numTables); + while (++t < numTables); } UInt32 i = 0; @@ -510,7 +508,7 @@ void CThreadInfo::EncodeBlock(const Byte *block, UInt32 blockSize) mtfSel[pos] = mtfSel[pos - 1]; mtfSel[0] = sel; } - while(++i < numSelectors); + while (++i < numSelectors); } { @@ -542,7 +540,7 @@ void CThreadInfo::EncodeBlock(const Byte *block, UInt32 blockSize) } while (++i < alphaSize); } - while(++t < numTables); + while (++t < numTables); } { @@ -722,7 +720,7 @@ HRESULT CThreadInfo::EncodeBlock3(UInt32 blockSize) void CEncoder::WriteBytes(const Byte *data, UInt32 sizeInBits, Byte lastByte) { - UInt32 bytesSize = (sizeInBits / 8); + UInt32 bytesSize = (sizeInBits >> 3); for (UInt32 i = 0; i < bytesSize; i++) m_OutStream.WriteBits(data[i], 8); WriteBits(lastByte, (sizeInBits & 7)); @@ -770,8 +768,6 @@ HRESULT CEncoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * m_OutStream.SetStream(outStream); m_OutStream.Init(); - CFlusher flusher(this); - CombinedCrc.Init(); #ifndef _7ZIP_ST NextBlockIndex = 0; diff --git a/CPP/7zip/Compress/BZip2Encoder.h b/CPP/7zip/Compress/BZip2Encoder.h index 5aa8a786..6b04eca1 100755..100644 --- a/CPP/7zip/Compress/BZip2Encoder.h +++ b/CPP/7zip/Compress/BZip2Encoder.h @@ -25,61 +25,61 @@ namespace NBZip2 { class CMsbfEncoderTemp { - UInt32 m_Pos; - int m_BitPos; - Byte m_CurByte; - Byte *Buffer; + UInt32 _pos; + unsigned _bitPos; + Byte _curByte; + Byte *_buf; public: - void SetStream(Byte *buffer) { Buffer = buffer; } - Byte *GetStream() const { return Buffer; } + void SetStream(Byte *buf) { _buf = buf; } + Byte *GetStream() const { return _buf; } void Init() { - m_Pos = 0; - m_BitPos = 8; - m_CurByte = 0; + _pos = 0; + _bitPos = 8; + _curByte = 0; } void Flush() { - if (m_BitPos < 8) - WriteBits(0, m_BitPos); + if (_bitPos < 8) + WriteBits(0, _bitPos); } - void WriteBits(UInt32 value, int numBits) + void WriteBits(UInt32 value, unsigned numBits) { while (numBits > 0) { - int numNewBits = MyMin(numBits, m_BitPos); + unsigned numNewBits = MyMin(numBits, _bitPos); numBits -= numNewBits; - m_CurByte <<= numNewBits; + _curByte <<= numNewBits; UInt32 newBits = value >> numBits; - m_CurByte |= Byte(newBits); + _curByte |= Byte(newBits); value -= (newBits << numBits); - m_BitPos -= numNewBits; + _bitPos -= numNewBits; - if (m_BitPos == 0) + if (_bitPos == 0) { - Buffer[m_Pos++] = m_CurByte; - m_BitPos = 8; + _buf[_pos++] = _curByte; + _bitPos = 8; } } } - UInt32 GetBytePos() const { return m_Pos ; } - UInt32 GetPos() const { return m_Pos * 8 + (8 - m_BitPos); } - Byte GetCurByte() const { return m_CurByte; } + UInt32 GetBytePos() const { return _pos ; } + UInt32 GetPos() const { return _pos * 8 + (8 - _bitPos); } + Byte GetCurByte() const { return _curByte; } void SetPos(UInt32 bitPos) { - m_Pos = bitPos / 8; - m_BitPos = 8 - ((int)bitPos & 7); + _pos = bitPos >> 3; + _bitPos = 8 - ((unsigned)bitPos & 7); } - void SetCurState(int bitPos, Byte curByte) + void SetCurState(unsigned bitPos, Byte curByte) { - m_BitPos = 8 - bitPos; - m_CurByte = curByte; + _bitPos = 8 - bitPos; + _curByte = curByte; } }; @@ -109,7 +109,7 @@ private: UInt32 m_BlockIndex; - void WriteBits2(UInt32 value, UInt32 numBits); + void WriteBits2(UInt32 value, unsigned numBits); void WriteByte2(Byte b); void WriteBit2(bool v); void WriteCrc2(UInt32 v); @@ -193,10 +193,10 @@ public: CThreadInfo ThreadsInfo; #endif - UInt32 ReadRleBlock(Byte *buffer); + UInt32 ReadRleBlock(Byte *buf); void WriteBytes(const Byte *data, UInt32 sizeInBits, Byte lastByte); - void WriteBits(UInt32 value, UInt32 numBits); + void WriteBits(UInt32 value, unsigned numBits); void WriteByte(Byte b); void WriteBit(bool v); void WriteCrc(UInt32 v); @@ -214,23 +214,6 @@ public: HRESULT Flush() { return m_OutStream.Flush(); } - void ReleaseStreams() - { - m_InStream.ReleaseStream(); - m_OutStream.ReleaseStream(); - } - - class CFlusher - { - CEncoder *_coder; - public: - CFlusher(CEncoder *coder): _coder(coder) {} - ~CFlusher() - { - _coder->ReleaseStreams(); - } - }; - #ifndef _7ZIP_ST MY_UNKNOWN_IMP2(ICompressSetCoderMt, ICompressSetCoderProperties) #else diff --git a/CPP/7zip/Compress/BZip2Register.cpp b/CPP/7zip/Compress/BZip2Register.cpp index ef14204b..ef14204b 100755..100644 --- a/CPP/7zip/Compress/BZip2Register.cpp +++ b/CPP/7zip/Compress/BZip2Register.cpp diff --git a/CPP/7zip/Compress/Bcj2Coder.cpp b/CPP/7zip/Compress/Bcj2Coder.cpp index 684da5ab..2d737e8a 100755..100644 --- a/CPP/7zip/Compress/Bcj2Coder.cpp +++ b/CPP/7zip/Compress/Bcj2Coder.cpp @@ -15,35 +15,22 @@ inline unsigned GetIndex(Byte b0, Byte b1) { return ((b1 == 0xE8) ? b0 : ((b1 == #ifndef EXTRACT_ONLY -static const int kBufferSize = 1 << 17; +static const unsigned kBufSize = 1 << 17; + +#define NUM_BITS 2 +#define SIGN_BIT (1 << NUM_BITS) +#define MASK_HIGH (0x100 - (1 << (NUM_BITS + 1))) + +static const UInt32 kDefaultLimit = (1 << (24 + NUM_BITS)); static bool inline Test86MSByte(Byte b) { - return (b == 0 || b == 0xFF); -} - -bool CEncoder::Create() -{ - if (!_mainStream.Create(1 << 18)) - return false; - if (!_callStream.Create(1 << 18)) - return false; - if (!_jumpStream.Create(1 << 18)) - return false; - if (!_rangeEncoder.Create(1 << 20)) - return false; - if (_buffer == 0) - { - _buffer = (Byte *)MidAlloc(kBufferSize); - if (_buffer == 0) - return false; - } - return true; + return (((b) + SIGN_BIT) & MASK_HIGH) == 0; } CEncoder::~CEncoder() { - ::MidFree(_buffer); + ::MidFree(_buf); } HRESULT CEncoder::Flush() @@ -51,12 +38,10 @@ HRESULT CEncoder::Flush() RINOK(_mainStream.Flush()); RINOK(_callStream.Flush()); RINOK(_jumpStream.Flush()); - _rangeEncoder.FlushData(); - return _rangeEncoder.FlushStream(); + _rc.FlushData(); + return _rc.FlushStream(); } -const UInt32 kDefaultLimit = (1 << 24); - HRESULT CEncoder::CodeReal(ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 numInStreams, ISequentialOutStream **outStreams, const UInt64 ** /* outSizes */, UInt32 numOutStreams, ICompressProgressInfo *progress) @@ -64,32 +49,34 @@ HRESULT CEncoder::CodeReal(ISequentialInStream **inStreams, const UInt64 **inSiz if (numInStreams != 1 || numOutStreams != 4) return E_INVALIDARG; - if (!Create()) - return E_OUTOFMEMORY; + if (!_mainStream.Create(1 << 18)) return E_OUTOFMEMORY; + if (!_callStream.Create(1 << 18)) return E_OUTOFMEMORY; + if (!_jumpStream.Create(1 << 18)) return E_OUTOFMEMORY; + if (!_rc.Create(1 << 20)) return E_OUTOFMEMORY; + if (_buf == 0) + { + _buf = (Byte *)MidAlloc(kBufSize); + if (_buf == 0) + return E_OUTOFMEMORY; + } bool sizeIsDefined = false; UInt64 inSize = 0; - if (inSizes != NULL) - if (inSizes[0] != NULL) + if (inSizes) + if (inSizes[0]) { inSize = *inSizes[0]; if (inSize <= kDefaultLimit) sizeIsDefined = true; } - CCoderReleaser releaser(this); - ISequentialInStream *inStream = inStreams[0]; - _mainStream.SetStream(outStreams[0]); - _mainStream.Init(); - _callStream.SetStream(outStreams[1]); - _callStream.Init(); - _jumpStream.SetStream(outStreams[2]); - _jumpStream.Init(); - _rangeEncoder.SetStream(outStreams[3]); - _rangeEncoder.Init(); - for (int i = 0; i < 256 + 2; i++) + _mainStream.SetStream(outStreams[0]); _mainStream.Init(); + _callStream.SetStream(outStreams[1]); _callStream.Init(); + _jumpStream.SetStream(outStreams[2]); _jumpStream.Init(); + _rc.SetStream(outStreams[3]); _rc.Init(); + for (unsigned i = 0; i < 256 + 2; i++) _statusEncoder[i].Init(); CMyComPtr<ICompressGetSubStreamSize> getSubStreamSize; @@ -99,12 +86,12 @@ HRESULT CEncoder::CodeReal(ISequentialInStream **inStreams, const UInt64 **inSiz UInt32 nowPos = 0; UInt64 nowPos64 = 0; - UInt32 bufferPos = 0; + UInt32 bufPos = 0; Byte prevByte = 0; UInt64 subStreamIndex = 0; - UInt64 subStreamStartPos = 0; + UInt64 subStreamStartPos = 0; UInt64 subStreamEndPos = 0; for (;;) @@ -112,23 +99,23 @@ HRESULT CEncoder::CodeReal(ISequentialInStream **inStreams, const UInt64 **inSiz UInt32 processedSize = 0; for (;;) { - UInt32 size = kBufferSize - (bufferPos + processedSize); + UInt32 size = kBufSize - (bufPos + processedSize); UInt32 processedSizeLoc; if (size == 0) break; - RINOK(inStream->Read(_buffer + bufferPos + processedSize, size, &processedSizeLoc)); + RINOK(inStream->Read(_buf + bufPos + processedSize, size, &processedSizeLoc)); if (processedSizeLoc == 0) break; processedSize += processedSizeLoc; } - UInt32 endPos = bufferPos + processedSize; + UInt32 endPos = bufPos + processedSize; if (endPos < 5) { // change it - for (bufferPos = 0; bufferPos < endPos; bufferPos++) + for (bufPos = 0; bufPos < endPos; bufPos++) { - Byte b = _buffer[bufferPos]; + Byte b = _buf[bufPos]; _mainStream.WriteByte(b); UInt32 index; if (b == 0xE8) @@ -142,37 +129,37 @@ HRESULT CEncoder::CodeReal(ISequentialInStream **inStreams, const UInt64 **inSiz prevByte = b; continue; } - _statusEncoder[index].Encode(&_rangeEncoder, 0); + _statusEncoder[index].Encode(&_rc, 0); prevByte = b; } return Flush(); } - bufferPos = 0; + bufPos = 0; UInt32 limit = endPos - 5; - while(bufferPos <= limit) + while (bufPos <= limit) { - Byte b = _buffer[bufferPos]; + Byte b = _buf[bufPos]; _mainStream.WriteByte(b); if (!IsJ(prevByte, b)) { - bufferPos++; + bufPos++; prevByte = b; continue; } - Byte nextByte = _buffer[bufferPos + 4]; + Byte nextByte = _buf[bufPos + 4]; UInt32 src = (UInt32(nextByte) << 24) | - (UInt32(_buffer[bufferPos + 3]) << 16) | - (UInt32(_buffer[bufferPos + 2]) << 8) | - (_buffer[bufferPos + 1]); - UInt32 dest = (nowPos + bufferPos + 5) + src; + (UInt32(_buf[bufPos + 3]) << 16) | + (UInt32(_buf[bufPos + 2]) << 8) | + (_buf[bufPos + 1]); + UInt32 dest = (nowPos + bufPos + 5) + src; // if (Test86MSByte(nextByte)) bool convert; - if (getSubStreamSize != NULL) + if (getSubStreamSize) { - UInt64 currentPos = (nowPos64 + bufferPos); + UInt64 currentPos = (nowPos64 + bufPos); while (subStreamEndPos < currentPos) { UInt64 subStreamSize; @@ -214,8 +201,8 @@ HRESULT CEncoder::CodeReal(ISequentialInStream **inStreams, const UInt64 **inSiz unsigned index = GetIndex(prevByte, b); if (convert) { - _statusEncoder[index].Encode(&_rangeEncoder, 1); - bufferPos += 5; + _statusEncoder[index].Encode(&_rc, 1); + bufPos += 5; COutBuffer &s = (b == 0xE8) ? _callStream : _jumpStream; for (int i = 24; i >= 0; i -= 8) s.WriteByte((Byte)(dest >> i)); @@ -223,30 +210,30 @@ HRESULT CEncoder::CodeReal(ISequentialInStream **inStreams, const UInt64 **inSiz } else { - _statusEncoder[index].Encode(&_rangeEncoder, 0); - bufferPos++; + _statusEncoder[index].Encode(&_rc, 0); + bufPos++; prevByte = b; } } - nowPos += bufferPos; - nowPos64 += bufferPos; + nowPos += bufPos; + nowPos64 += bufPos; - if (progress != NULL) + if (progress) { /* const UInt64 compressedSize = _mainStream.GetProcessedSize() + _callStream.GetProcessedSize() + _jumpStream.GetProcessedSize() + - _rangeEncoder.GetProcessedSize(); + _rc.GetProcessedSize(); */ RINOK(progress->SetRatioInfo(&nowPos64, NULL)); } UInt32 i = 0; - while(bufferPos < endPos) - _buffer[i++] = _buffer[bufferPos++]; - bufferPos = i; + while (bufPos < endPos) + _buf[i++] = _buf[bufPos++]; + bufPos = i; } } @@ -284,46 +271,39 @@ HRESULT CDecoder::CodeReal(ISequentialInStream **inStreams, const UInt64 ** /* i if (numInStreams != 4 || numOutStreams != 1) return E_INVALIDARG; - if (!_mainInStream.Create(_inBufSizes[0])) - return E_OUTOFMEMORY; - if (!_callStream.Create(_inBufSizes[1])) - return E_OUTOFMEMORY; - if (!_jumpStream.Create(_inBufSizes[2])) - return E_OUTOFMEMORY; - if (!_rangeDecoder.Create(_inBufSizes[3])) - return E_OUTOFMEMORY; - if (!_outStream.Create(_outBufSize)) - return E_OUTOFMEMORY; - - CCoderReleaser releaser(this); + if (!_mainStream.Create(_inBufSizes[0])) return E_OUTOFMEMORY; + if (!_callStream.Create(_inBufSizes[1])) return E_OUTOFMEMORY; + if (!_jumpStream.Create(_inBufSizes[2])) return E_OUTOFMEMORY; + if (!_rc.Create(_inBufSizes[3])) return E_OUTOFMEMORY; + if (!_outStream.Create(_outBufSize)) return E_OUTOFMEMORY; - _mainInStream.SetStream(inStreams[0]); + _mainStream.SetStream(inStreams[0]); _callStream.SetStream(inStreams[1]); _jumpStream.SetStream(inStreams[2]); - _rangeDecoder.SetStream(inStreams[3]); + _rc.SetStream(inStreams[3]); _outStream.SetStream(outStreams[0]); - _mainInStream.Init(); + _mainStream.Init(); _callStream.Init(); _jumpStream.Init(); - _rangeDecoder.Init(); + _rc.Init(); _outStream.Init(); - for (int i = 0; i < 256 + 2; i++) + for (unsigned i = 0; i < 256 + 2; i++) _statusDecoder[i].Init(); Byte prevByte = 0; UInt32 processedBytes = 0; for (;;) { - if (processedBytes >= (1 << 20) && progress != NULL) + if (processedBytes >= (1 << 20) && progress) { /* const UInt64 compressedSize = - _mainInStream.GetProcessedSize() + + _mainStream.GetProcessedSize() + _callStream.GetProcessedSize() + _jumpStream.GetProcessedSize() + - _rangeDecoder.GetProcessedSize(); + _rc.GetProcessedSize(); */ const UInt64 nowPos64 = _outStream.GetProcessedSize(); RINOK(progress->SetRatioInfo(NULL, &nowPos64)); @@ -334,8 +314,8 @@ HRESULT CDecoder::CodeReal(ISequentialInStream **inStreams, const UInt64 ** /* i const UInt32 kBurstSize = (1 << 18); for (i = 0; i < kBurstSize; i++) { - if (!_mainInStream.ReadByte(b)) - return Flush(); + if (!_mainStream.ReadByte(b)) + return _outStream.Flush(); _outStream.WriteByte(b); if (IsJ(prevByte, b)) break; @@ -345,14 +325,14 @@ HRESULT CDecoder::CodeReal(ISequentialInStream **inStreams, const UInt64 ** /* i if (i == kBurstSize) continue; unsigned index = GetIndex(prevByte, b); - if (_statusDecoder[index].Decode(&_rangeDecoder) == 1) + if (_statusDecoder[index].Decode(&_rc) == 1) { UInt32 src = 0; CInBuffer &s = (b == 0xE8) ? _callStream : _jumpStream; - for (int i = 0; i < 4; i++) + for (unsigned i = 0; i < 4; i++) { Byte b0; - if(!s.ReadByte(b0)) + if (!s.ReadByte(b0)) return S_FALSE; src <<= 8; src |= ((UInt32)b0); diff --git a/CPP/7zip/Compress/Bcj2Coder.h b/CPP/7zip/Compress/Bcj2Coder.h index 79a713f1..d2b3bda3 100755..100644 --- a/CPP/7zip/Compress/Bcj2Coder.h +++ b/CPP/7zip/Compress/Bcj2Coder.h @@ -12,7 +12,7 @@ namespace NCompress { namespace NBcj2 { -const int kNumMoveBits = 5; +const unsigned kNumMoveBits = 5; #ifndef EXTRACT_ONLY @@ -20,32 +20,15 @@ class CEncoder: public ICompressCoder2, public CMyUnknownImp { - Byte *_buffer; - bool Create(); + Byte *_buf; COutBuffer _mainStream; COutBuffer _callStream; COutBuffer _jumpStream; - NCompress::NRangeCoder::CEncoder _rangeEncoder; - NCompress::NRangeCoder::CBitEncoder<kNumMoveBits> _statusEncoder[256 + 2]; + NRangeCoder::CEncoder _rc; + NRangeCoder::CBitEncoder<kNumMoveBits> _statusEncoder[256 + 2]; HRESULT Flush(); -public: - void ReleaseStreams() - { - _mainStream.ReleaseStream(); - _callStream.ReleaseStream(); - _jumpStream.ReleaseStream(); - _rangeEncoder.ReleaseStream(); - } - - class CCoderReleaser - { - CEncoder *_coder; - public: - CCoderReleaser(CEncoder *coder): _coder(coder) {} - ~CCoderReleaser() { _coder->ReleaseStreams(); } - }; public: MY_UNKNOWN_IMP @@ -56,7 +39,8 @@ public: STDMETHOD(Code)(ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 numInStreams, ISequentialOutStream **outStreams, const UInt64 **outSizes, UInt32 numOutStreams, ICompressProgressInfo *progress); - CEncoder(): _buffer(0) {}; + + CEncoder(): _buf(0) {}; ~CEncoder(); }; @@ -67,37 +51,19 @@ class CDecoder: public ICompressSetBufSize, public CMyUnknownImp { - CInBuffer _mainInStream; + CInBuffer _mainStream; CInBuffer _callStream; CInBuffer _jumpStream; - NCompress::NRangeCoder::CDecoder _rangeDecoder; - NCompress::NRangeCoder::CBitDecoder<kNumMoveBits> _statusDecoder[256 + 2]; + NRangeCoder::CDecoder _rc; + NRangeCoder::CBitDecoder<kNumMoveBits> _statusDecoder[256 + 2]; COutBuffer _outStream; UInt32 _inBufSizes[4]; UInt32 _outBufSize; public: - void ReleaseStreams() - { - _mainInStream.ReleaseStream(); - _callStream.ReleaseStream(); - _jumpStream.ReleaseStream(); - _rangeDecoder.ReleaseStream(); - _outStream.ReleaseStream(); - } - - HRESULT Flush() { return _outStream.Flush(); } - class CCoderReleaser - { - CDecoder *_coder; - public: - CCoderReleaser(CDecoder *coder): _coder(coder) {} - ~CCoderReleaser() { _coder->ReleaseStreams(); } - }; - -public: MY_UNKNOWN_IMP1(ICompressSetBufSize); + HRESULT CodeReal(ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 numInStreams, ISequentialOutStream **outStreams, const UInt64 **outSizes, UInt32 numOutStreams, ICompressProgressInfo *progress); @@ -107,6 +73,7 @@ public: STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size); STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size); + CDecoder(); }; diff --git a/CPP/7zip/Compress/Bcj2Register.cpp b/CPP/7zip/Compress/Bcj2Register.cpp index 8eb1e736..8eb1e736 100755..100644 --- a/CPP/7zip/Compress/Bcj2Register.cpp +++ b/CPP/7zip/Compress/Bcj2Register.cpp diff --git a/CPP/7zip/Compress/BcjCoder.cpp b/CPP/7zip/Compress/BcjCoder.cpp index 0e34ef48..0e34ef48 100755..100644 --- a/CPP/7zip/Compress/BcjCoder.cpp +++ b/CPP/7zip/Compress/BcjCoder.cpp diff --git a/CPP/7zip/Compress/BcjCoder.h b/CPP/7zip/Compress/BcjCoder.h index 0754bcd2..0754bcd2 100755..100644 --- a/CPP/7zip/Compress/BcjCoder.h +++ b/CPP/7zip/Compress/BcjCoder.h diff --git a/CPP/7zip/Compress/BcjRegister.cpp b/CPP/7zip/Compress/BcjRegister.cpp index 648ad8e0..648ad8e0 100755..100644 --- a/CPP/7zip/Compress/BcjRegister.cpp +++ b/CPP/7zip/Compress/BcjRegister.cpp diff --git a/CPP/7zip/Compress/BitlDecoder.cpp b/CPP/7zip/Compress/BitlDecoder.cpp index 78665be8..516b0932 100755..100644 --- a/CPP/7zip/Compress/BitlDecoder.cpp +++ b/CPP/7zip/Compress/BitlDecoder.cpp @@ -12,9 +12,9 @@ struct CInverterTableInitializer { CInverterTableInitializer() { - for (int i = 0; i < 256; i++) + for (unsigned i = 0; i < 256; i++) { - int x = ((i & 0x55) << 1) | ((i & 0xAA) >> 1); + unsigned x = ((i & 0x55) << 1) | ((i & 0xAA) >> 1); x = ((x & 0x33) << 2) | ((x & 0xCC) >> 2); kInvertTable[i] = (Byte)(((x & 0x0F) << 4) | ((x & 0xF0) >> 4)); } diff --git a/CPP/7zip/Compress/BitlDecoder.h b/CPP/7zip/Compress/BitlDecoder.h index ff373bac..27be1716 100755..100644 --- a/CPP/7zip/Compress/BitlDecoder.h +++ b/CPP/7zip/Compress/BitlDecoder.h @@ -9,130 +9,127 @@ namespace NBitl { const unsigned kNumBigValueBits = 8 * 4; const unsigned kNumValueBytes = 3; -const unsigned kNumValueBits = 8 * kNumValueBytes; +const unsigned kNumValueBits = 8 * kNumValueBytes; const UInt32 kMask = (1 << kNumValueBits) - 1; extern Byte kInvertTable[256]; +/* TInByte must support "Extra Bytes" (bytes that can be read after the end of stream + TInByte::ReadByte() returns 0xFF after the end of stream + TInByte::NumExtraBytes contains the number "Extra Bytes" + + Bitl decoder can read up to 4 bytes ahead to internal buffer. */ + template<class TInByte> class CBaseDecoder { protected: - unsigned m_BitPos; - UInt32 m_Value; - TInByte m_Stream; + unsigned _bitPos; + UInt32 _value; + TInByte _stream; public: - UInt32 NumExtraBytes; - bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); } - void SetStream(ISequentialInStream *inStream) { m_Stream.SetStream(inStream); } - void ReleaseStream() { m_Stream.ReleaseStream(); } + bool Create(UInt32 bufSize) { return _stream.Create(bufSize); } + void SetStream(ISequentialInStream *inStream) { _stream.SetStream(inStream); } void Init() { - m_Stream.Init(); - m_BitPos = kNumBigValueBits; - m_Value = 0; - NumExtraBytes = 0; + _stream.Init(); + _bitPos = kNumBigValueBits; + _value = 0; } - UInt64 GetProcessedSize() const { return m_Stream.GetProcessedSize() + NumExtraBytes - (kNumBigValueBits - m_BitPos) / 8; } + + UInt64 GetStreamSize() const { return _stream.GetStreamSize(); } + UInt64 GetProcessedSize() const { return _stream.GetProcessedSize() - ((kNumBigValueBits - _bitPos) >> 3); } + + bool ThereAreDataInBitsBuffer() const { return this->_bitPos != kNumBigValueBits; } void Normalize() { - for (; m_BitPos >= 8; m_BitPos -= 8) - { - Byte b = 0; - if (!m_Stream.ReadByte(b)) - { - b = 0xFF; // check it - NumExtraBytes++; - } - m_Value = (b << (kNumBigValueBits - m_BitPos)) | m_Value; - } + for (; _bitPos >= 8; _bitPos -= 8) + _value = ((UInt32)_stream.ReadByte() << (kNumBigValueBits - _bitPos)) | _value; } UInt32 ReadBits(unsigned numBits) { Normalize(); - UInt32 res = m_Value & ((1 << numBits) - 1); - m_BitPos += numBits; - m_Value >>= numBits; + UInt32 res = _value & ((1 << numBits) - 1); + _bitPos += numBits; + _value >>= numBits; return res; } bool ExtraBitsWereRead() const { - if (NumExtraBytes == 0) - return false; - return ((UInt32)(kNumBigValueBits - m_BitPos) < (NumExtraBytes << 3)); + return (_stream.NumExtraBytes > 4 || kNumBigValueBits - _bitPos < (_stream.NumExtraBytes << 3)); + } + + bool ExtraBitsWereRead_Fast() const + { + // full version is not inlined in vc6. + // return _stream.NumExtraBytes != 0 && (_stream.NumExtraBytes > 4 || kNumBigValueBits - _bitPos < (_stream.NumExtraBytes << 3)); + + // (_stream.NumExtraBytes > 4) is fast overread detection. It's possible that + // it doesn't return true, if small number of extra bits were read. + return (_stream.NumExtraBytes > 4); } + + // it must be fixed !!! with extra bits + // UInt32 GetNumExtraBytes() const { return _stream.NumExtraBytes; } }; template<class TInByte> class CDecoder: public CBaseDecoder<TInByte> { - UInt32 m_NormalValue; + UInt32 _normalValue; public: void Init() { CBaseDecoder<TInByte>::Init(); - m_NormalValue = 0; + _normalValue = 0; } void Normalize() { - for (; this->m_BitPos >= 8; this->m_BitPos -= 8) + for (; this->_bitPos >= 8; this->_bitPos -= 8) { - Byte b = 0; - if (!this->m_Stream.ReadByte(b)) - { - b = 0xFF; // check it - this->NumExtraBytes++; - } - m_NormalValue = (b << (kNumBigValueBits - this->m_BitPos)) | m_NormalValue; - this->m_Value = (this->m_Value << 8) | kInvertTable[b]; + Byte b = this->_stream.ReadByte(); + _normalValue = ((UInt32)b << (kNumBigValueBits - this->_bitPos)) | _normalValue; + this->_value = (this->_value << 8) | kInvertTable[b]; } } UInt32 GetValue(unsigned numBits) { Normalize(); - return ((this->m_Value >> (8 - this->m_BitPos)) & kMask) >> (kNumValueBits - numBits); + return ((this->_value >> (8 - this->_bitPos)) & kMask) >> (kNumValueBits - numBits); } void MovePos(unsigned numBits) { - this->m_BitPos += numBits; - m_NormalValue >>= numBits; + this->_bitPos += numBits; + _normalValue >>= numBits; } UInt32 ReadBits(unsigned numBits) { Normalize(); - UInt32 res = m_NormalValue & ((1 << numBits) - 1); + UInt32 res = _normalValue & ((1 << numBits) - 1); MovePos(numBits); return res; } - void AlignToByte() { MovePos((32 - this->m_BitPos) & 7); } + void AlignToByte() { MovePos((32 - this->_bitPos) & 7); } - Byte ReadByte() + Byte ReadDirectByte() { return _stream.ReadByte(); } + + Byte ReadAlignedByte() { - if (this->m_BitPos == kNumBigValueBits) - { - Byte b = 0; - if (!this->m_Stream.ReadByte(b)) - { - b = 0xFF; - this->NumExtraBytes++; - } - return b; - } - { - Byte b = (Byte)(m_NormalValue & 0xFF); - MovePos(8); - return b; - } + if (this->_bitPos == kNumBigValueBits) + return _stream.ReadByte(); + Byte b = (Byte)(_normalValue & 0xFF); + MovePos(8); + return b; } }; diff --git a/CPP/7zip/Compress/BitlEncoder.h b/CPP/7zip/Compress/BitlEncoder.h index 7de57545..22b83545 100755..100644 --- a/CPP/7zip/Compress/BitlEncoder.h +++ b/CPP/7zip/Compress/BitlEncoder.h @@ -7,51 +7,50 @@ class CBitlEncoder { - COutBuffer m_Stream; - unsigned m_BitPos; - Byte m_CurByte; + COutBuffer _stream; + unsigned _bitPos; + Byte _curByte; public: - bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); } - void SetStream(ISequentialOutStream *outStream) { m_Stream.SetStream(outStream); } - void ReleaseStream() { m_Stream.ReleaseStream(); } - UInt32 GetBitPosition() const { return (8 - m_BitPos); } - UInt64 GetProcessedSize() const { return m_Stream.GetProcessedSize() + (8 - m_BitPos + 7) /8; } + bool Create(UInt32 bufSize) { return _stream.Create(bufSize); } + void SetStream(ISequentialOutStream *outStream) { _stream.SetStream(outStream); } + // unsigned GetBitPosition() const { return (8 - _bitPos); } + UInt64 GetProcessedSize() const { return _stream.GetProcessedSize() + ((8 - _bitPos + 7) >> 3); } void Init() { - m_Stream.Init(); - m_BitPos = 8; - m_CurByte = 0; + _stream.Init(); + _bitPos = 8; + _curByte = 0; } HRESULT Flush() { FlushByte(); - return m_Stream.Flush(); + return _stream.Flush(); } void FlushByte() { - if (m_BitPos < 8) - m_Stream.WriteByte(m_CurByte); - m_BitPos = 8; - m_CurByte = 0; + if (_bitPos < 8) + _stream.WriteByte(_curByte); + _bitPos = 8; + _curByte = 0; } void WriteBits(UInt32 value, unsigned numBits) { while (numBits > 0) { - if (numBits < m_BitPos) + if (numBits < _bitPos) { - m_CurByte |= (value & ((1 << numBits) - 1)) << (8 - m_BitPos); - m_BitPos -= numBits; + _curByte |= (value & ((1 << numBits) - 1)) << (8 - _bitPos); + _bitPos -= numBits; return; } - numBits -= m_BitPos; - m_Stream.WriteByte((Byte)(m_CurByte | (value << (8 - m_BitPos)))); - value >>= m_BitPos; - m_BitPos = 8; - m_CurByte = 0; + numBits -= _bitPos; + _stream.WriteByte((Byte)(_curByte | (value << (8 - _bitPos)))); + value >>= _bitPos; + _bitPos = 8; + _curByte = 0; } } - void WriteByte(Byte b) { m_Stream.WriteByte(b);} + void WriteByte(Byte b) { _stream.WriteByte(b);} }; #endif diff --git a/CPP/7zip/Compress/BitmDecoder.h b/CPP/7zip/Compress/BitmDecoder.h index 4369b452..fef20e06 100755..100644 --- a/CPP/7zip/Compress/BitmDecoder.h +++ b/CPP/7zip/Compress/BitmDecoder.h @@ -9,45 +9,59 @@ namespace NBitm { const unsigned kNumBigValueBits = 8 * 4; const unsigned kNumValueBytes = 3; -const unsigned kNumValueBits = 8 * kNumValueBytes; +const unsigned kNumValueBits = 8 * kNumValueBytes; const UInt32 kMask = (1 << kNumValueBits) - 1; +// _bitPos - the number of free bits (high bits in _value) +// (kNumBigValueBits - _bitPos) = (32 - _bitPos) == the number of ready to read bits (low bits of _value) + template<class TInByte> class CDecoder { - unsigned m_BitPos; - UInt32 m_Value; + unsigned _bitPos; + UInt32 _value; + TInByte _stream; public: - TInByte m_Stream; - bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); } - void SetStream(ISequentialInStream *inStream) { m_Stream.SetStream(inStream);} - void ReleaseStream() { m_Stream.ReleaseStream();} + bool Create(UInt32 bufSize) { return _stream.Create(bufSize); } + void SetStream(ISequentialInStream *inStream) { _stream.SetStream(inStream);} void Init() { - m_Stream.Init(); - m_BitPos = kNumBigValueBits; + _stream.Init(); + _bitPos = kNumBigValueBits; + _value = 0; Normalize(); } - UInt64 GetProcessedSize() const { return m_Stream.GetProcessedSize() - (kNumBigValueBits - m_BitPos) / 8; } - + UInt64 GetStreamSize() const { return _stream.GetStreamSize(); } + UInt64 GetProcessedSize() const { return _stream.GetProcessedSize() - ((kNumBigValueBits - _bitPos) >> 3); } + + bool ExtraBitsWereRead() const + { + return (_stream.NumExtraBytes > 4 || kNumBigValueBits - _bitPos < (_stream.NumExtraBytes << 3)); + } + + bool ExtraBitsWereRead_Fast() const + { + return (_stream.NumExtraBytes > 4); + } + void Normalize() { - for (;m_BitPos >= 8; m_BitPos -= 8) - m_Value = (m_Value << 8) | m_Stream.ReadByte(); + for (; _bitPos >= 8; _bitPos -= 8) + _value = (_value << 8) | _stream.ReadByte(); } UInt32 GetValue(unsigned numBits) const { - // return (m_Value << m_BitPos) >> (kNumBigValueBits - numBits); - return ((m_Value >> (8 - m_BitPos)) & kMask) >> (kNumValueBits - numBits); + // return (_value << _bitPos) >> (kNumBigValueBits - numBits); + return ((_value >> (8 - _bitPos)) & kMask) >> (kNumValueBits - numBits); } void MovePos(unsigned numBits) { - m_BitPos += numBits; + _bitPos += numBits; Normalize(); } @@ -58,7 +72,7 @@ public: return res; } - void AlignToByte() { MovePos((32 - m_BitPos) & 7); } + void AlignToByte() { MovePos((kNumBigValueBits - _bitPos) & 7); } }; } diff --git a/CPP/7zip/Compress/BitmEncoder.h b/CPP/7zip/Compress/BitmEncoder.h index a85dbff8..05079ace 100755..100644 --- a/CPP/7zip/Compress/BitmEncoder.h +++ b/CPP/7zip/Compress/BitmEncoder.h @@ -8,41 +8,40 @@ template<class TOutByte> class CBitmEncoder { - TOutByte m_Stream; - unsigned m_BitPos; - Byte m_CurByte; + unsigned _bitPos; + Byte _curByte; + TOutByte _stream; public: - bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); } - void SetStream(ISequentialOutStream *outStream) { m_Stream.SetStream(outStream);} - void ReleaseStream() { m_Stream.ReleaseStream(); } - UInt64 GetProcessedSize() const { return m_Stream.GetProcessedSize() + (8 - m_BitPos + 7) / 8; } + bool Create(UInt32 bufferSize) { return _stream.Create(bufferSize); } + void SetStream(ISequentialOutStream *outStream) { _stream.SetStream(outStream);} + UInt64 GetProcessedSize() const { return _stream.GetProcessedSize() + ((8 - _bitPos + 7) >> 3); } void Init() { - m_Stream.Init(); - m_BitPos = 8; - m_CurByte = 0; + _stream.Init(); + _bitPos = 8; + _curByte = 0; } HRESULT Flush() { - if (m_BitPos < 8) - WriteBits(0, m_BitPos); - return m_Stream.Flush(); + if (_bitPos < 8) + WriteBits(0, _bitPos); + return _stream.Flush(); } void WriteBits(UInt32 value, unsigned numBits) { while (numBits > 0) { - if (numBits < m_BitPos) + if (numBits < _bitPos) { - m_CurByte |= ((Byte)value << (m_BitPos -= numBits)); + _curByte |= ((Byte)value << (_bitPos -= numBits)); return; } - numBits -= m_BitPos; + numBits -= _bitPos; UInt32 newBits = (value >> numBits); value -= (newBits << numBits); - m_Stream.WriteByte((Byte)(m_CurByte | newBits)); - m_BitPos = 8; - m_CurByte = 0; + _stream.WriteByte((Byte)(_curByte | newBits)); + _bitPos = 8; + _curByte = 0; } } }; diff --git a/CPP/7zip/Compress/BranchCoder.cpp b/CPP/7zip/Compress/BranchCoder.cpp index 43170952..43170952 100755..100644 --- a/CPP/7zip/Compress/BranchCoder.cpp +++ b/CPP/7zip/Compress/BranchCoder.cpp diff --git a/CPP/7zip/Compress/BranchCoder.h b/CPP/7zip/Compress/BranchCoder.h index 0e3a5c4e..0e3a5c4e 100755..100644 --- a/CPP/7zip/Compress/BranchCoder.h +++ b/CPP/7zip/Compress/BranchCoder.h diff --git a/CPP/7zip/Compress/BranchMisc.cpp b/CPP/7zip/Compress/BranchMisc.cpp index 423b723a..239f2513 100755..100644 --- a/CPP/7zip/Compress/BranchMisc.cpp +++ b/CPP/7zip/Compress/BranchMisc.cpp @@ -6,32 +6,16 @@ #include "BranchMisc.h" -UInt32 CBC_ARM_Encoder::SubFilter(Byte *data, UInt32 size) - { return (UInt32)::ARM_Convert(data, size, _bufferPos, 1); } - -UInt32 CBC_ARM_Decoder::SubFilter(Byte *data, UInt32 size) - { return (UInt32)::ARM_Convert(data, size, _bufferPos, 0); } - -UInt32 CBC_ARMT_Encoder::SubFilter(Byte *data, UInt32 size) - { return (UInt32)::ARMT_Convert(data, size, _bufferPos, 1); } - -UInt32 CBC_ARMT_Decoder::SubFilter(Byte *data, UInt32 size) - { return (UInt32)::ARMT_Convert(data, size, _bufferPos, 0); } - -UInt32 CBC_PPC_Encoder::SubFilter(Byte *data, UInt32 size) - { return (UInt32)::PPC_Convert(data, size, _bufferPos, 1); } - -UInt32 CBC_PPC_Decoder::SubFilter(Byte *data, UInt32 size) - { return (UInt32)::PPC_Convert(data, size, _bufferPos, 0); } - -UInt32 CBC_SPARC_Encoder::SubFilter(Byte *data, UInt32 size) - { return (UInt32)::SPARC_Convert(data, size, _bufferPos, 1); } - -UInt32 CBC_SPARC_Decoder::SubFilter(Byte *data, UInt32 size) - { return (UInt32)::SPARC_Convert(data, size, _bufferPos, 0); } - -UInt32 CBC_IA64_Encoder::SubFilter(Byte *data, UInt32 size) - { return (UInt32)::IA64_Convert(data, size, _bufferPos, 1); } - -UInt32 CBC_IA64_Decoder::SubFilter(Byte *data, UInt32 size) - { return (UInt32)::IA64_Convert(data, size, _bufferPos, 0); } +#define SUB_FILTER_IMP2(name, coderStr, coderNum) \ + UInt32 CBC_ ## name ## coderStr::SubFilter(Byte *data, UInt32 size) \ + { return (UInt32)::name ## Convert(data, size, _bufferPos, coderNum); } + +#define SUB_FILTER_IMP(name) \ + SUB_FILTER_IMP2(name, Encoder, 1) \ + SUB_FILTER_IMP2(name, Decoder, 0) \ + +SUB_FILTER_IMP(ARM_) +SUB_FILTER_IMP(ARMT_) +SUB_FILTER_IMP(PPC_) +SUB_FILTER_IMP(SPARC_) +SUB_FILTER_IMP(IA64_) diff --git a/CPP/7zip/Compress/BranchMisc.h b/CPP/7zip/Compress/BranchMisc.h index 81198b21..81198b21 100755..100644 --- a/CPP/7zip/Compress/BranchMisc.h +++ b/CPP/7zip/Compress/BranchMisc.h diff --git a/CPP/7zip/Compress/BranchRegister.cpp b/CPP/7zip/Compress/BranchRegister.cpp index 380828c6..380828c6 100755..100644 --- a/CPP/7zip/Compress/BranchRegister.cpp +++ b/CPP/7zip/Compress/BranchRegister.cpp diff --git a/CPP/7zip/Compress/ByteSwap.cpp b/CPP/7zip/Compress/ByteSwap.cpp index 645b6ffc..645b6ffc 100755..100644 --- a/CPP/7zip/Compress/ByteSwap.cpp +++ b/CPP/7zip/Compress/ByteSwap.cpp diff --git a/CPP/7zip/Compress/Codec.def b/CPP/7zip/Compress/Codec.def index ebf73a3b..ebf73a3b 100755..100644 --- a/CPP/7zip/Compress/Codec.def +++ b/CPP/7zip/Compress/Codec.def diff --git a/CPP/7zip/Compress/CodecExports.cpp b/CPP/7zip/Compress/CodecExports.cpp index 4ff1c0fc..726d35fc 100755..100644 --- a/CPP/7zip/Compress/CodecExports.cpp +++ b/CPP/7zip/Compress/CodecExports.cpp @@ -2,7 +2,10 @@ #include "StdAfx.h" +#include "../../../C/CpuArch.h" + #include "../../Common/ComTry.h" +#include "../../Common/MyCom.h" #include "../../Windows/PropVariant.h" @@ -13,10 +16,15 @@ extern unsigned int g_NumCodecs; extern const CCodecInfo *g_Codecs[]; +extern unsigned int g_NumHashers; +extern const CHasherInfo *g_Hashers[]; + static const UInt16 kDecodeId = 0x2790; +static const UInt16 kEncodeId = 0x2791; +static const UInt16 kHasherId = 0x2792; DEFINE_GUID(CLSID_CCodec, -0x23170F69, 0x40C1, kDecodeId, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); +0x23170F69, 0x40C1, kDecodeId, 0, 0, 0, 0, 0, 0, 0, 0); static inline HRESULT SetPropString(const char *s, unsigned int size, PROPVARIANT *value) { @@ -30,13 +38,13 @@ static inline HRESULT SetPropGUID(const GUID &guid, PROPVARIANT *value) return SetPropString((const char *)&guid, sizeof(GUID), value); } -static HRESULT SetClassID(CMethodId id, bool encode, PROPVARIANT *value) +static HRESULT SetClassID(CMethodId id, UInt16 typeId, PROPVARIANT *value) { - GUID clsId = CLSID_CCodec; - for (int i = 0; i < sizeof(id); i++, id >>= 8) - clsId.Data4[i] = (Byte)(id & 0xFF); - if (encode) - clsId.Data3++; + GUID clsId; + clsId.Data1 = CLSID_CCodec.Data1; + clsId.Data2 = CLSID_CCodec.Data2; + clsId.Data3 = typeId; + SetUi64(clsId.Data4, id); return SetPropGUID(clsId, value); } @@ -44,13 +52,14 @@ static HRESULT FindCodecClassId(const GUID *clsID, UInt32 isCoder2, bool isFilte { index = -1; if (clsID->Data1 != CLSID_CCodec.Data1 || - clsID->Data2 != CLSID_CCodec.Data2 || - (clsID->Data3 & ~1) != kDecodeId) + clsID->Data2 != CLSID_CCodec.Data2) + return S_OK; + encode = true; + if (clsID->Data3 == kDecodeId) + encode = false; + else if (clsID->Data3 != kEncodeId) return S_OK; - encode = (clsID->Data3 != kDecodeId); - UInt64 id = 0; - for (int j = 0; j < 8; j++) - id |= ((UInt64)clsID->Data4[j]) << (8 * j); + UInt64 id = GetUi64(clsID->Data4); for (unsigned i = 0; i < g_NumCodecs; i++) { const CCodecInfo &codec = *g_Codecs[i]; @@ -65,7 +74,7 @@ static HRESULT FindCodecClassId(const GUID *clsID, UInt32 isCoder2, bool isFilte return S_OK; } -STDAPI CreateCoder2(bool encode, UInt32 index, const GUID *iid, void **outObject) +STDAPI CreateCoder2(bool encode, int index, const GUID *iid, void **outObject) { COM_TRY_BEGIN *outObject = 0; @@ -88,18 +97,22 @@ STDAPI CreateCoder2(bool encode, UInt32 index, const GUID *iid, void **outObject return CLASS_E_CLASSNOTAVAILABLE; *outObject = codec.CreateDecoder(); } - if (isCoder) - ((ICompressCoder *)*outObject)->AddRef(); - else if (isCoder2) - ((ICompressCoder2 *)*outObject)->AddRef(); - else - ((ICompressFilter *)*outObject)->AddRef(); + if (*outObject) + { + if (isCoder) + ((ICompressCoder *)*outObject)->AddRef(); + else if (isCoder2) + ((ICompressCoder2 *)*outObject)->AddRef(); + else + ((ICompressFilter *)*outObject)->AddRef(); + } return S_OK; COM_TRY_END } STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject) { + COM_TRY_BEGIN *outObject = 0; bool isCoder = (*iid == IID_ICompressCoder) != 0; bool isCoder2 = (*iid == IID_ICompressCoder2) != 0; @@ -113,42 +126,54 @@ STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject) return res; if (codecIndex < 0) return CLASS_E_CLASSNOTAVAILABLE; - return CreateCoder2(encode, codecIndex, iid, outObject); + + const CCodecInfo &codec = *g_Codecs[codecIndex]; + if (encode) + *outObject = codec.CreateEncoder(); + else + *outObject = codec.CreateDecoder(); + if (*outObject) + { + if (isCoder) + ((ICompressCoder *)*outObject)->AddRef(); + else if (isCoder2) + ((ICompressCoder2 *)*outObject)->AddRef(); + else + ((ICompressFilter *)*outObject)->AddRef(); + } + return S_OK; + COM_TRY_END } STDAPI GetMethodProperty(UInt32 codecIndex, PROPID propID, PROPVARIANT *value) { ::VariantClear((VARIANTARG *)value); const CCodecInfo &codec = *g_Codecs[codecIndex]; - switch(propID) + switch (propID) { case NMethodPropID::kID: - { value->uhVal.QuadPart = (UInt64)codec.Id; value->vt = VT_UI8; break; - } case NMethodPropID::kName: if ((value->bstrVal = ::SysAllocString(codec.Name)) != 0) value->vt = VT_BSTR; break; case NMethodPropID::kDecoder: if (codec.CreateDecoder) - return SetClassID(codec.Id, false, value); + return SetClassID(codec.Id, kDecodeId, value); break; case NMethodPropID::kEncoder: if (codec.CreateEncoder) - return SetClassID(codec.Id, true, value); + return SetClassID(codec.Id, kEncodeId, value); break; case NMethodPropID::kInStreams: - { if (codec.NumInStreams != 1) { value->vt = VT_UI4; value->ulVal = (ULONG)codec.NumInStreams; } break; - } } return S_OK; } @@ -158,3 +183,101 @@ STDAPI GetNumberOfMethods(UINT32 *numCodecs) *numCodecs = g_NumCodecs; return S_OK; } + + +static int FindHasherClassId(const GUID *clsID) +{ + if (clsID->Data1 != CLSID_CCodec.Data1 || + clsID->Data2 != CLSID_CCodec.Data2 || + clsID->Data3 != kHasherId) + return -1; + UInt64 id = GetUi64(clsID->Data4); + for (unsigned i = 0; i < g_NumCodecs; i++) + if (id == g_Hashers[i]->Id) + return i; + return -1; +} + +static HRESULT CreateHasher2(UInt32 index, IHasher **hasher) +{ + COM_TRY_BEGIN + *hasher = g_Hashers[index]->CreateHasher(); + if (*hasher) + (*hasher)->AddRef(); + return S_OK; + COM_TRY_END +} + +STDAPI CreateHasher(const GUID *clsid, IHasher **outObject) +{ + COM_TRY_BEGIN + *outObject = 0; + int index = FindHasherClassId(clsid); + if (index < 0) + return CLASS_E_CLASSNOTAVAILABLE; + return CreateHasher2(index, outObject); + COM_TRY_END +} + +STDAPI GetHasherProp(UInt32 codecIndex, PROPID propID, PROPVARIANT *value) +{ + ::VariantClear((VARIANTARG *)value); + const CHasherInfo &codec = *g_Hashers[codecIndex]; + switch (propID) + { + case NMethodPropID::kID: + value->uhVal.QuadPart = (UInt64)codec.Id; + value->vt = VT_UI8; + break; + case NMethodPropID::kName: + if ((value->bstrVal = ::SysAllocString(codec.Name)) != 0) + value->vt = VT_BSTR; + break; + case NMethodPropID::kEncoder: + if (codec.CreateHasher) + return SetClassID(codec.Id, kHasherId, value); + break; + case NMethodPropID::kDigestSize: + value->ulVal = (ULONG)codec.DigestSize; + value->vt = VT_UI4; + break; + } + return S_OK; +} + +class CHashers: + public IHashers, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP1(IHashers) + + STDMETHOD_(UInt32, GetNumHashers)(); + STDMETHOD(GetHasherProp)(UInt32 index, PROPID propID, PROPVARIANT *value); + STDMETHOD(CreateHasher)(UInt32 index, IHasher **hasher); +}; + +STDAPI GetHashers(IHashers **hashers) +{ + COM_TRY_BEGIN + *hashers = new CHashers; + if (*hashers) + (*hashers)->AddRef(); + return S_OK; + COM_TRY_END +} + +STDMETHODIMP_(UInt32) CHashers::GetNumHashers() +{ + return g_NumHashers; +} + +STDMETHODIMP CHashers::GetHasherProp(UInt32 index, PROPID propID, PROPVARIANT *value) +{ + return ::GetHasherProp(index, propID, value); +} + +STDMETHODIMP CHashers::CreateHasher(UInt32 index, IHasher **hasher) +{ + return ::CreateHasher2(index, hasher); +} diff --git a/CPP/7zip/Compress/CopyCoder.cpp b/CPP/7zip/Compress/CopyCoder.cpp index f71692a7..f0863202 100755..100644 --- a/CPP/7zip/Compress/CopyCoder.cpp +++ b/CPP/7zip/Compress/CopyCoder.cpp @@ -22,10 +22,10 @@ STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream, const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress) { - if (_buffer == 0) + if (!_buffer) { _buffer = (Byte *)::MidAlloc(kBufferSize); - if (_buffer == 0) + if (!_buffer) return E_OUTOFMEMORY; } @@ -33,9 +33,8 @@ STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream, for (;;) { UInt32 size = kBufferSize; - if (outSize != 0) - if (size > *outSize - TotalSize) - size = (UInt32)(*outSize - TotalSize); + if (outSize && size > *outSize - TotalSize) + size = (UInt32)(*outSize - TotalSize); RINOK(inStream->Read(_buffer, size, &size)); if (size == 0) break; @@ -44,7 +43,7 @@ STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream, RINOK(WriteStream(outStream, _buffer, size)); } TotalSize += size; - if (progress != NULL) + if (progress) { RINOK(progress->SetRatioInfo(&TotalSize, &TotalSize)); } @@ -60,8 +59,16 @@ STDMETHODIMP CCopyCoder::GetInStreamProcessedSize(UInt64 *value) HRESULT CopyStream(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress) { - CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder; + CMyComPtr<ICompressCoder> copyCoder = new CCopyCoder; return copyCoder->Code(inStream, outStream, NULL, NULL, progress); } +HRESULT CopyStream_ExactSize(ISequentialInStream *inStream, ISequentialOutStream *outStream, UInt64 size, ICompressProgressInfo *progress) +{ + NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder; + CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec; + RINOK(copyCoder->Code(inStream, outStream, NULL, &size, progress)); + return copyCoderSpec->TotalSize == size ? S_OK : E_FAIL; +} + } diff --git a/CPP/7zip/Compress/CopyCoder.h b/CPP/7zip/Compress/CopyCoder.h index c5445ccf..5e0bb643 100755..100644 --- a/CPP/7zip/Compress/CopyCoder.h +++ b/CPP/7zip/Compress/CopyCoder.h @@ -28,6 +28,7 @@ public: }; HRESULT CopyStream(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress); +HRESULT CopyStream_ExactSize(ISequentialInStream *inStream, ISequentialOutStream *outStream, UInt64 size, ICompressProgressInfo *progress); } diff --git a/CPP/7zip/Compress/CopyRegister.cpp b/CPP/7zip/Compress/CopyRegister.cpp index efb9b9e9..efb9b9e9 100755..100644 --- a/CPP/7zip/Compress/CopyRegister.cpp +++ b/CPP/7zip/Compress/CopyRegister.cpp diff --git a/CPP/7zip/Compress/Deflate64Register.cpp b/CPP/7zip/Compress/Deflate64Register.cpp index 509e675a..509e675a 100755..100644 --- a/CPP/7zip/Compress/Deflate64Register.cpp +++ b/CPP/7zip/Compress/Deflate64Register.cpp diff --git a/CPP/7zip/Compress/DeflateConst.h b/CPP/7zip/Compress/DeflateConst.h index 00e5ab8b..c3ae5719 100755..100644 --- a/CPP/7zip/Compress/DeflateConst.h +++ b/CPP/7zip/Compress/DeflateConst.h @@ -48,7 +48,7 @@ const Byte kLenDirectBits32[kFixedLenTableSize] = const Byte kLenDirectBits64[kFixedLenTableSize] = {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 16, 0, 0}; -const UInt32 kDistStart[kDistTableSize64] = +const UInt32 kDistStart[kDistTableSize64] = {0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768, 1024,1536,2048,3072,4096,6144,8192,12288,16384,24576,32768,49152}; const Byte kDistDirectBits[kDistTableSize64] = @@ -106,24 +106,21 @@ struct CLevels void SubClear() { UInt32 i; - for(i = kNumLitLenCodesMin; i < kFixedMainTableSize; i++) + for (i = kNumLitLenCodesMin; i < kFixedMainTableSize; i++) litLenLevels[i] = 0; - for(i = 0; i < kFixedDistTableSize; i++) + for (i = 0; i < kFixedDistTableSize; i++) distLevels[i] = 0; } void SetFixedLevels() { - int i; + int i = 0; + + for (; i < 144; i++) litLenLevels[i] = 8; + for (; i < 256; i++) litLenLevels[i] = 9; + for (; i < 280; i++) litLenLevels[i] = 7; + for (; i < 288; i++) litLenLevels[i] = 8; - for (i = 0; i < 144; i++) - litLenLevels[i] = 8; - for (; i < 256; i++) - litLenLevels[i] = 9; - for (; i < 280; i++) - litLenLevels[i] = 7; - for (; i < 288; i++) - litLenLevels[i] = 8; for (i = 0; i < kFixedDistTableSize; i++) // test it: InfoZip only uses kDistTableSize distLevels[i] = 5; } diff --git a/CPP/7zip/Compress/DeflateDecoder.cpp b/CPP/7zip/Compress/DeflateDecoder.cpp index 2848cd81..5285e143 100755..100644 --- a/CPP/7zip/Compress/DeflateDecoder.cpp +++ b/CPP/7zip/Compress/DeflateDecoder.cpp @@ -8,24 +8,27 @@ namespace NCompress { namespace NDeflate { namespace NDecoder { -static const int kLenIdFinished = -1; -static const int kLenIdNeedInit = -2; - CCoder::CCoder(bool deflate64Mode, bool deflateNSIS): _deflate64Mode(deflate64Mode), _deflateNSIS(deflateNSIS), _keepHistory(false), + _needFinishInput(false), _needInitInStream(true), ZlibMode(false) {} -UInt32 CCoder::ReadBits(int numBits) +UInt32 CCoder::ReadBits(unsigned numBits) { return m_InBitStream.ReadBits(numBits); } -bool CCoder::DeCodeLevelTable(Byte *values, int numSymbols) +Byte CCoder::ReadAlignedByte() +{ + return m_InBitStream.ReadAlignedByte(); +} + +bool CCoder::DeCodeLevelTable(Byte *values, unsigned numSymbols) { - int i = 0; + unsigned i = 0; do { UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream); @@ -37,25 +40,25 @@ bool CCoder::DeCodeLevelTable(Byte *values, int numSymbols) { if (i == 0) return false; - int num = ReadBits(2) + 3; + unsigned num = ReadBits(2) + 3; for (; num > 0 && i < numSymbols; num--, i++) values[i] = values[i - 1]; } else { - int num; + unsigned num; if (number == kTableLevel0Number) num = ReadBits(3) + 3; else num = ReadBits(7) + 11; - for (;num > 0 && i < numSymbols; num--) + for (; num > 0 && i < numSymbols; num--) values[i++] = 0; } } else return false; } - while(i < numSymbols); + while (i < numSymbols); return true; } @@ -64,18 +67,22 @@ bool CCoder::DeCodeLevelTable(Byte *values, int numSymbols) bool CCoder::ReadTables(void) { m_FinalBlock = (ReadBits(kFinalBlockFieldSize) == NFinalBlockField::kFinalBlock); + if (m_InBitStream.ExtraBitsWereRead()) + return false; UInt32 blockType = ReadBits(kBlockTypeFieldSize); if (blockType > NBlockType::kDynamicHuffman) return false; + if (m_InBitStream.ExtraBitsWereRead()) + return false; if (blockType == NBlockType::kStored) { m_StoredMode = true; m_InBitStream.AlignToByte(); - m_StoredBlockSize = ReadBits(kStoredBlockLengthFieldSize); + m_StoredBlockSize = ReadAligned_UInt16(); // ReadBits(kStoredBlockLengthFieldSize) if (_deflateNSIS) return true; - return (m_StoredBlockSize == (UInt16)~ReadBits(kStoredBlockLengthFieldSize)); + return (m_StoredBlockSize == (UInt16)~ReadAligned_UInt16()); } m_StoredMode = false; @@ -88,29 +95,35 @@ bool CCoder::ReadTables(void) } else { - int numLitLenLevels = ReadBits(kNumLenCodesFieldSize) + kNumLitLenCodesMin; + unsigned numLitLenLevels = ReadBits(kNumLenCodesFieldSize) + kNumLitLenCodesMin; _numDistLevels = ReadBits(kNumDistCodesFieldSize) + kNumDistCodesMin; - int numLevelCodes = ReadBits(kNumLevelCodesFieldSize) + kNumLevelCodesMin; + unsigned numLevelCodes = ReadBits(kNumLevelCodesFieldSize) + kNumLevelCodesMin; if (!_deflate64Mode) if (_numDistLevels > kDistTableSize32) return false; Byte levelLevels[kLevelTableSize]; - for (int i = 0; i < kLevelTableSize; i++) + for (unsigned i = 0; i < kLevelTableSize; i++) { int position = kCodeLengthAlphabetOrder[i]; - if(i < numLevelCodes) + if (i < numLevelCodes) levelLevels[position] = (Byte)ReadBits(kLevelFieldSize); else levelLevels[position] = 0; } + if (m_InBitStream.ExtraBitsWereRead()) + return false; + RIF(m_LevelDecoder.SetCodeLengths(levelLevels)); Byte tmpLevels[kFixedMainTableSize + kFixedDistTableSize]; if (!DeCodeLevelTable(tmpLevels, numLitLenLevels + _numDistLevels)) return false; + + if (m_InBitStream.ExtraBitsWereRead()) + return false; levels.SubClear(); memcpy(levels.litLenLevels, tmpLevels, numLitLenLevels); @@ -120,7 +133,7 @@ bool CCoder::ReadTables(void) return m_DistDecoder.SetCodeLengths(levels.distLevels); } -HRESULT CCoder::CodeSpec(UInt32 curSize) +HRESULT CCoder::CodeSpec(UInt32 curSize, bool finishInputStream) { if (_remainLen == kLenIdFinished) return S_OK; @@ -136,10 +149,7 @@ HRESULT CCoder::CodeSpec(UInt32 curSize) _needReadTable = true; } - if (curSize == 0) - return S_OK; - - while(_remainLen > 0 && curSize > 0) + while (_remainLen > 0 && curSize > 0) { _remainLen--; Byte b = m_OutWindowStream.GetByte(_rep0); @@ -147,8 +157,10 @@ HRESULT CCoder::CodeSpec(UInt32 curSize) curSize--; } - while(curSize > 0) + while (curSize > 0 || finishInputStream) { + if (m_InBitStream.ExtraBitsWereRead()) + return S_FALSE; if (_needReadTable) { if (m_FinalBlock) @@ -158,19 +170,28 @@ HRESULT CCoder::CodeSpec(UInt32 curSize) } if (!ReadTables()) return S_FALSE; + if (m_InBitStream.ExtraBitsWereRead()) + return S_FALSE; _needReadTable = false; } - if(m_StoredMode) + if (m_StoredMode) { + if (finishInputStream && curSize == 0 && m_StoredBlockSize != 0) + return S_FALSE; + /* NSIS version contains some bits in bitl bits buffer. + So we must read some first bytes via ReadAlignedByte */ + for (; m_StoredBlockSize > 0 && curSize > 0 && m_InBitStream.ThereAreDataInBitsBuffer(); m_StoredBlockSize--, curSize--) + m_OutWindowStream.PutByte(ReadAlignedByte()); for (; m_StoredBlockSize > 0 && curSize > 0; m_StoredBlockSize--, curSize--) - m_OutWindowStream.PutByte(m_InBitStream.ReadByte()); + m_OutWindowStream.PutByte(m_InBitStream.ReadDirectByte()); _needReadTable = (m_StoredBlockSize == 0); continue; } - while(curSize > 0) + + while (curSize > 0) { - if (m_InBitStream.NumExtraBytes > 4) + if (m_InBitStream.ExtraBitsWereRead_Fast()) return S_FALSE; UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream); @@ -190,7 +211,7 @@ HRESULT CCoder::CodeSpec(UInt32 curSize) number -= kSymbolMatch; UInt32 len; { - int numBits; + unsigned numBits; if (_deflate64Mode) { len = kLenStart64[number]; @@ -224,28 +245,40 @@ HRESULT CCoder::CodeSpec(UInt32 curSize) else return S_FALSE; } + + if (finishInputStream && curSize == 0) + { + if (m_MainDecoder.DecodeSymbol(&m_InBitStream) != kSymbolEndOfBlock) + return S_FALSE; + _needReadTable = true; + } } + + if (m_InBitStream.ExtraBitsWereRead()) + return S_FALSE; + return S_OK; } #ifdef _NO_EXCEPTIONS #define DEFLATE_TRY_BEGIN -#define DEFLATE_TRY_END +#define DEFLATE_TRY_END(res) #else #define DEFLATE_TRY_BEGIN try { -#define DEFLATE_TRY_END } \ - catch(const CInBufferException &e) { return e.ErrorCode; } \ - catch(const CLzOutWindowException &e) { return e.ErrorCode; } \ - catch(...) { return S_FALSE; } +#define DEFLATE_TRY_END(res) } \ + catch(const CInBufferException &e) { res = e.ErrorCode; } \ + catch(const CLzOutWindowException &e) { res = e.ErrorCode; } \ + catch(...) { res = S_FALSE; } #endif HRESULT CCoder::CodeReal(ISequentialOutStream *outStream, const UInt64 *outSize, ICompressProgressInfo *progress) { + HRESULT res; DEFLATE_TRY_BEGIN m_OutWindowStream.SetStream(outStream); CCoderReleaser flusher(this); @@ -255,18 +288,23 @@ HRESULT CCoder::CodeReal(ISequentialOutStream *outStream, for (;;) { UInt32 curSize = 1 << 18; - if (outSize != 0) + bool finishInputStream = false; + if (outSize) { const UInt64 rem = *outSize - (m_OutWindowStream.GetProcessedSize() - start); - if (curSize > rem) + if (curSize >= rem) + { curSize = (UInt32)rem; + if (ZlibMode || _needFinishInput) + finishInputStream = true; + } } if (curSize == 0) break; - RINOK(CodeSpec(curSize)); + RINOK(CodeSpec(curSize, finishInputStream)); if (_remainLen == kLenIdFinished) break; - if (progress != NULL) + if (progress) { const UInt64 inSize = m_InBitStream.GetProcessedSize() - inStart; const UInt64 nowPos64 = m_OutWindowStream.GetProcessedSize() - start; @@ -277,14 +315,14 @@ HRESULT CCoder::CodeReal(ISequentialOutStream *outStream, { m_InBitStream.AlignToByte(); for (int i = 0; i < 4; i++) - ZlibFooter[i] = m_InBitStream.ReadByte(); + ZlibFooter[i] = ReadAlignedByte(); } flusher.NeedFlush = false; - HRESULT res = Flush(); + res = Flush(); if (res == S_OK && InputEofError()) return S_FALSE; + DEFLATE_TRY_END(res) return res; - DEFLATE_TRY_END } HRESULT CCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, @@ -307,13 +345,14 @@ STDMETHODIMP CCoder::GetInStreamProcessedSize(UInt64 *value) STDMETHODIMP CCoder::SetInStream(ISequentialInStream *inStream) { + m_InStreamRef = inStream; m_InBitStream.SetStream(inStream); return S_OK; } STDMETHODIMP CCoder::ReleaseInStream() { - m_InBitStream.ReleaseStream(); + m_InStreamRef.Release(); return S_OK; } @@ -329,16 +368,22 @@ STDMETHODIMP CCoder::SetOutStreamSize(const UInt64 * /* outSize */) STDMETHODIMP CCoder::Read(void *data, UInt32 size, UInt32 *processedSize) { + HRESULT res; DEFLATE_TRY_BEGIN if (processedSize) *processedSize = 0; const UInt64 startPos = m_OutWindowStream.GetProcessedSize(); m_OutWindowStream.SetMemStream((Byte *)data); - RINOK(CodeSpec(size)); - if (processedSize) - *processedSize = (UInt32)(m_OutWindowStream.GetProcessedSize() - startPos); - return Flush(); - DEFLATE_TRY_END + res = CodeSpec(size, false); + if (res == S_OK) + { + res = Flush(); + if (processedSize) + *processedSize = (UInt32)(m_OutWindowStream.GetProcessedSize() - startPos); + } + DEFLATE_TRY_END(res) + m_OutWindowStream.SetMemStream(NULL); + return res; } #endif diff --git a/CPP/7zip/Compress/DeflateDecoder.h b/CPP/7zip/Compress/DeflateDecoder.h index 56ab2bea..856a5771 100755..100644 --- a/CPP/7zip/Compress/DeflateDecoder.h +++ b/CPP/7zip/Compress/DeflateDecoder.h @@ -18,6 +18,9 @@ namespace NCompress { namespace NDeflate { namespace NDecoder { +const int kLenIdFinished = -1; +const int kLenIdNeedInit = -2; + class CCoder: public ICompressCoder, public ICompressGetInStreamProcessedSize, @@ -29,6 +32,7 @@ class CCoder: public CMyUnknownImp { CLzOutWindow m_OutWindowStream; + CMyComPtr<ISequentialInStream> m_InStreamRef; NBitl::CDecoder<CInBuffer> m_InBitStream; NCompress::NHuffman::CDecoder<kNumHuffmanBits, kFixedMainTableSize> m_MainDecoder; NCompress::NHuffman::CDecoder<kNumHuffmanBits, kFixedDistTableSize> m_DistDecoder; @@ -36,22 +40,23 @@ class CCoder: UInt32 m_StoredBlockSize; + UInt32 _numDistLevels; bool m_FinalBlock; bool m_StoredMode; - UInt32 _numDistLevels; - bool _deflateNSIS; bool _deflate64Mode; bool _keepHistory; + bool _needFinishInput; + bool _needInitInStream; + bool _needReadTable; Int32 _remainLen; UInt32 _rep0; - bool _needReadTable; - UInt32 ReadBits(int numBits); + UInt32 ReadBits(unsigned numBits); - bool DeCodeLevelTable(Byte *values, int numSymbols); + bool DeCodeLevelTable(Byte *values, unsigned numSymbols); bool ReadTables(); HRESULT Flush() { return m_OutWindowStream.Flush(); } @@ -65,12 +70,11 @@ class CCoder: { if (NeedFlush) _coder->Flush(); - _coder->ReleaseOutStream(); } }; friend class CCoderReleaser; - HRESULT CodeSpec(UInt32 curSize); + HRESULT CodeSpec(UInt32 curSize, bool finishInputStream); public: bool ZlibMode; Byte ZlibFooter[4]; @@ -78,12 +82,11 @@ public: CCoder(bool deflate64Mode, bool deflateNSIS = false); virtual ~CCoder() {}; - void SetKeepHistory(bool keepHistory) { _keepHistory = keepHistory; } + void Set_KeepHistory(bool keepHistory) { _keepHistory = keepHistory; } + void Set_NeedFinishInput(bool needFinishInput) { _needFinishInput = needFinishInput; } - void ReleaseOutStream() - { - m_OutWindowStream.ReleaseStream(); - } + bool IsFinished() const { return _remainLen == kLenIdFinished;; } + bool IsFinalBlock() const { return m_FinalBlock; } HRESULT CodeReal(ISequentialOutStream *outStream, const UInt64 *outSize, ICompressProgressInfo *progress); @@ -126,31 +129,24 @@ public: } void AlignToByte() { m_InBitStream.AlignToByte(); } - Byte ReadByte() { return (Byte)m_InBitStream.ReadBits(8); } + Byte ReadAlignedByte(); + UInt32 ReadAligned_UInt16() // aligned for Byte range + { + UInt32 v = m_InBitStream.ReadAlignedByte(); + return v | ((UInt32)m_InBitStream.ReadAlignedByte() << 8); + } bool InputEofError() const { return m_InBitStream.ExtraBitsWereRead(); } + + UInt64 GetStreamSize() const { return m_InBitStream.GetStreamSize(); } UInt64 GetInputProcessedSize() const { return m_InBitStream.GetProcessedSize(); } // IGetInStreamProcessedSize STDMETHOD(GetInStreamProcessedSize)(UInt64 *value); }; -class CCOMCoder : public CCoder -{ -public: - CCOMCoder(): CCoder(false) {} -}; - -class CNsisCOMCoder : public CCoder -{ -public: - CNsisCOMCoder(): CCoder(false, true) {} -}; - -class CCOMCoder64 : public CCoder -{ -public: - CCOMCoder64(): CCoder(true) {} -}; +class CCOMCoder : public CCoder { public: CCOMCoder(): CCoder(false) {} }; +class CNsisCOMCoder : public CCoder { public: CNsisCOMCoder(): CCoder(false, true) {} }; +class CCOMCoder64 : public CCoder { public: CCOMCoder64(): CCoder(true) {} }; }}} diff --git a/CPP/7zip/Compress/DeflateEncoder.cpp b/CPP/7zip/Compress/DeflateEncoder.cpp index 813b6de4..392ee93d 100755..100644 --- a/CPP/7zip/Compress/DeflateEncoder.cpp +++ b/CPP/7zip/Compress/DeflateEncoder.cpp @@ -5,7 +5,7 @@ #include "../../../C/Alloc.h" #include "../../../C/HuffEnc.h" -#include "Common/ComTry.h" +#include "../../Common/ComTry.h" #include "DeflateEncoder.h" @@ -50,11 +50,11 @@ public: CFastPosInit() { int i; - for(i = 0; i < kNumLenSlots; i++) + for (i = 0; i < kNumLenSlots; i++) { int c = kLenStart32[i]; int j = 1 << kLenDirectBits32[i]; - for(int k = 0; k < j; k++, c++) + for (int k = 0; k < j; k++, c++) g_LenSlots[c] = (Byte)i; } @@ -147,7 +147,7 @@ CCoder::CCoder(bool deflate64Mode): HRESULT CCoder::Create() { - COM_TRY_BEGIN + // COM_TRY_BEGIN if (m_Values == 0) { m_Values = (CCodeValue *)MyAlloc((kMaxUncompressedBlockSize) * sizeof(CCodeValue)); @@ -197,7 +197,7 @@ HRESULT CCoder::Create() _lzInWindow.cutValue = m_MatchFinderCycles; m_Created = true; return S_OK; - COM_TRY_END + // COM_TRY_END } HRESULT CCoder::BaseSetEncoderProperties2(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps) @@ -264,7 +264,7 @@ NO_INLINE void CCoder::GetMatches() if (numPairs > 0) { UInt32 i; - for(i = 0; i < numPairs; i += 2) + for (i = 0; i < numPairs; i += 2) { m_MatchDistances[i + 1] = (UInt16)distanceTmp[i]; m_MatchDistances[i + 2] = (UInt16)distanceTmp[i + 1]; @@ -316,7 +316,7 @@ NO_INLINE UInt32 CCoder::Backward(UInt32 &backRes, UInt32 cur) m_Optimum[posPrev].PosPrev = (UInt16)cur; cur = posPrev; } - while(cur > 0); + while (cur > 0); backRes = m_Optimum[0].BackPrev; m_OptimumCurrentIndex = m_Optimum[0].PosPrev; return m_OptimumCurrentIndex; @@ -324,7 +324,7 @@ NO_INLINE UInt32 CCoder::Backward(UInt32 &backRes, UInt32 cur) NO_INLINE UInt32 CCoder::GetOptimal(UInt32 &backRes) { - if(m_OptimumEndIndex != m_OptimumCurrentIndex) + if (m_OptimumEndIndex != m_OptimumCurrentIndex) { UInt32 len = m_Optimum[m_OptimumCurrentIndex].PosPrev - m_OptimumCurrentIndex; backRes = m_Optimum[m_OptimumCurrentIndex].BackPrev; @@ -336,13 +336,13 @@ NO_INLINE UInt32 CCoder::GetOptimal(UInt32 &backRes) GetMatches(); UInt32 numDistancePairs = m_MatchDistances[0]; - if(numDistancePairs == 0) + if (numDistancePairs == 0) return 1; const UInt16 *matchDistances = m_MatchDistances + 1; UInt32 lenMain = matchDistances[numDistancePairs - 2]; - if(lenMain > m_NumFastBytes) + if (lenMain > m_NumFastBytes) { backRes = matchDistances[numDistancePairs - 1]; MovePos(lenMain - 1); @@ -356,7 +356,7 @@ NO_INLINE UInt32 CCoder::GetOptimal(UInt32 &backRes) UInt32 offs = 0; - for(UInt32 i = kMatchMinLen; i <= lenMain; i++) + for (UInt32 i = kMatchMinLen; i <= lenMain; i++) { UInt32 distance = matchDistances[offs + 1]; m_Optimum[i].PosPrev = 0; @@ -371,17 +371,17 @@ NO_INLINE UInt32 CCoder::GetOptimal(UInt32 &backRes) for (;;) { ++cur; - if(cur == lenEnd || cur == kNumOptsBase || m_Pos >= kMatchArrayLimit) + if (cur == lenEnd || cur == kNumOptsBase || m_Pos >= kMatchArrayLimit) return Backward(backRes, cur); GetMatches(); matchDistances = m_MatchDistances + 1; UInt32 numDistancePairs = m_MatchDistances[0]; UInt32 newLen = 0; - if(numDistancePairs != 0) + if (numDistancePairs != 0) { newLen = matchDistances[numDistancePairs - 2]; - if(newLen > m_NumFastBytes) + if (newLen > m_NumFastBytes) { UInt32 len = Backward(backRes, cur); m_Optimum[cur].BackPrev = matchDistances[numDistancePairs - 1]; @@ -399,14 +399,14 @@ NO_INLINE UInt32 CCoder::GetOptimal(UInt32 &backRes) optimum.Price = curAnd1Price; optimum.PosPrev = (UInt16)cur; } - if(numDistancePairs == 0) + if (numDistancePairs == 0) continue; - while(lenEnd < cur + newLen) + while (lenEnd < cur + newLen) m_Optimum[++lenEnd].Price = kIfinityPrice; offs = 0; UInt32 distance = matchDistances[offs + 1]; curPrice += m_PosPrices[GetPosSlot(distance)]; - for(UInt32 lenTest = kMatchMinLen; ; lenTest++) + for (UInt32 lenTest = kMatchMinLen; ; lenTest++) { UInt32 curAndLenPrice = curPrice + m_LenPrices[lenTest - kMatchMinLen]; COptimal &optimum = m_Optimum[cur + lenTest]; @@ -444,12 +444,12 @@ UInt32 CCoder::GetOptimalFast(UInt32 &backRes) void CTables::InitStructures() { UInt32 i; - for(i = 0; i < 256; i++) + for (i = 0; i < 256; i++) litLenLevels[i] = 8; litLenLevels[i++] = 13; - for(;i < kFixedMainTableSize; i++) + for (;i < kFixedMainTableSize; i++) litLenLevels[i] = 5; - for(i = 0; i < kFixedDistTableSize; i++) + for (i = 0; i < kFixedDistTableSize; i++) distLevels[i] = 5; } @@ -539,7 +539,7 @@ NO_INLINE void CCoder::LevelTableCode(const Byte *levels, int numLevels, const B continue; if (count < minCount) - for(int i = 0; i < count; i++) + for (int i = 0; i < count; i++) WRITE_HF(curLen); else if (curLen != 0) { @@ -662,20 +662,20 @@ NO_INLINE void CCoder::SetPrices(const CLevels &levels) if (_fastMode) return; UInt32 i; - for(i = 0; i < 256; i++) + for (i = 0; i < 256; i++) { Byte price = levels.litLenLevels[i]; m_LiteralPrices[i] = ((price != 0) ? price : kNoLiteralStatPrice); } - for(i = 0; i < m_NumLenCombinations; i++) + for (i = 0; i < m_NumLenCombinations; i++) { UInt32 slot = g_LenSlots[i]; Byte price = levels.litLenLevels[kSymbolMatch + slot]; m_LenPrices[i] = (Byte)(((price != 0) ? price : kNoLenStatPrice) + m_LenDirectBits[slot]); } - for(i = 0; i < kDistTableSize64; i++) + for (i = 0; i < kDistTableSize64; i++) { Byte price = levels.distLevels[i]; m_PosPrices[i] = (Byte)(((price != 0) ? price: kNoPosStatPrice) + kDistDirectBits[i]); @@ -731,7 +731,7 @@ static UInt32 GetStorePrice(UInt32 blockSize, int bitPosition) bitPosition = 0; blockSize -= curBlockSize; } - while(blockSize != 0); + while (blockSize != 0); return price; } @@ -747,11 +747,11 @@ void CCoder::WriteStoreBlock(UInt32 blockSize, UInt32 additionalOffset, bool fin WriteBits((UInt16)curBlockSize, kStoredBlockLengthFieldSize); WriteBits((UInt16)~curBlockSize, kStoredBlockLengthFieldSize); const Byte *data = Inline_MatchFinder_GetPointerToCurrentPos(&_lzInWindow)- additionalOffset; - for(UInt32 i = 0; i < curBlockSize; i++) + for (UInt32 i = 0; i < curBlockSize; i++) m_OutStream.WriteByte(data[i]); additionalOffset -= curBlockSize; } - while(blockSize != 0); + while (blockSize != 0); } NO_INLINE UInt32 CCoder::TryDynBlock(int tableIndex, UInt32 numPasses) @@ -776,11 +776,11 @@ NO_INLINE UInt32 CCoder::TryDynBlock(int tableIndex, UInt32 numPasses) (CLevels &)t = m_NewLevels; m_NumLitLenLevels = kMainTableSize; - while(m_NumLitLenLevels > kNumLitLenCodesMin && m_NewLevels.litLenLevels[m_NumLitLenLevels - 1] == 0) + while (m_NumLitLenLevels > kNumLitLenCodesMin && m_NewLevels.litLenLevels[m_NumLitLenLevels - 1] == 0) m_NumLitLenLevels--; m_NumDistLevels = kDistTableSize64; - while(m_NumDistLevels > kNumDistCodesMin && m_NewLevels.distLevels[m_NumDistLevels - 1] == 0) + while (m_NumDistLevels > kNumDistCodesMin && m_NewLevels.distLevels[m_NumDistLevels - 1] == 0) m_NumDistLevels--; UInt32 levelFreqs[kLevelTableSize]; @@ -947,8 +947,6 @@ HRESULT CCoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *ou m_OutStream.SetStream(outStream); m_OutStream.Init(); - CCoderReleaser coderReleaser(this); - m_OptimumEndIndex = m_OptimumCurrentIndex = 0; CTables &t = m_Tables[1]; diff --git a/CPP/7zip/Compress/DeflateEncoder.h b/CPP/7zip/Compress/DeflateEncoder.h index f25d802e..d8e88f89 100755..100644 --- a/CPP/7zip/Compress/DeflateEncoder.h +++ b/CPP/7zip/Compress/DeflateEncoder.h @@ -5,7 +5,7 @@ #include "../../../C/LzFind.h" -#include "Common/MyCom.h" +#include "../../Common/MyCom.h" #include "../ICoder.h" @@ -49,7 +49,7 @@ struct CTables: public CLevels typedef struct _CSeqInStream { ISeqInStream SeqInStream; - CMyComPtr<ISequentialInStream> RealStream; + ISequentialInStream *RealStream; } CSeqInStream; struct CEncProps @@ -165,20 +165,6 @@ public: void WriteBlockData(bool writeMode, bool finalBlock); - void ReleaseStreams() - { - _seqInStream.RealStream.Release(); - m_OutStream.ReleaseStream(); - } - class CCoderReleaser - { - CCoder *m_Coder; - public: - CCoderReleaser(CCoder *coder): m_Coder(coder) {} - ~CCoderReleaser() { m_Coder->ReleaseStreams(); } - }; - friend class CCoderReleaser; - UInt32 GetBlockPrice(int tableIndex, int numDivPasses); void CodeBlock(int tableIndex, bool finalBlock); diff --git a/CPP/7zip/Compress/DeflateRegister.cpp b/CPP/7zip/Compress/DeflateRegister.cpp index 45f55219..45f55219 100755..100644 --- a/CPP/7zip/Compress/DeflateRegister.cpp +++ b/CPP/7zip/Compress/DeflateRegister.cpp diff --git a/CPP/7zip/Compress/DeltaFilter.cpp b/CPP/7zip/Compress/DeltaFilter.cpp index d8378a60..d8378a60 100755..100644 --- a/CPP/7zip/Compress/DeltaFilter.cpp +++ b/CPP/7zip/Compress/DeltaFilter.cpp diff --git a/CPP/7zip/Compress/DllExports2.cpp b/CPP/7zip/Compress/DllExports2Compress.cpp index 286ef08b..286ef08b 100755..100644 --- a/CPP/7zip/Compress/DllExports2.cpp +++ b/CPP/7zip/Compress/DllExports2Compress.cpp diff --git a/CPP/7zip/Compress/DllExports.cpp b/CPP/7zip/Compress/DllExportsCompress.cpp index 6af7e5ec..8b37c899 100755..100644 --- a/CPP/7zip/Compress/DllExports.cpp +++ b/CPP/7zip/Compress/DllExportsCompress.cpp @@ -1,4 +1,4 @@ -// DllExports.cpp +// DllExportsCompress.cpp #include "StdAfx.h" @@ -8,8 +8,8 @@ #include "../Common/RegisterCodec.h" -static const unsigned int kNumCodecsMax = 32; -unsigned int g_NumCodecs = 0; +static const unsigned kNumCodecsMax = 48; +unsigned g_NumCodecs = 0; const CCodecInfo *g_Codecs[kNumCodecsMax]; void RegisterCodec(const CCodecInfo *codecInfo) { @@ -17,6 +17,15 @@ void RegisterCodec(const CCodecInfo *codecInfo) g_Codecs[g_NumCodecs++] = codecInfo; } +static const unsigned kNumHashersMax = 16; +unsigned g_NumHashers = 0; +const CHasherInfo *g_Hashers[kNumHashersMax]; +void RegisterHasher(const CHasherInfo *hashInfo) throw() +{ + if (g_NumHashers < kNumHashersMax) + g_Hashers[g_NumHashers++] = hashInfo; +} + #ifdef _WIN32 extern "C" BOOL WINAPI DllMain( @@ -42,4 +51,3 @@ STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject) { return CreateCoder(clsid, iid, outObject); } - diff --git a/CPP/7zip/Compress/HuffmanDecoder.h b/CPP/7zip/Compress/HuffmanDecoder.h index 82a1e6f2..21f96f0d 100755..100644 --- a/CPP/7zip/Compress/HuffmanDecoder.h +++ b/CPP/7zip/Compress/HuffmanDecoder.h @@ -3,7 +3,7 @@ #ifndef __COMPRESS_HUFFMAN_DECODER_H #define __COMPRESS_HUFFMAN_DECODER_H -#include "../../Common/Types.h" +#include "../../Common/MyTypes.h" namespace NCompress { namespace NHuffman { @@ -25,7 +25,7 @@ public: int lenCounts[kNumBitsMax + 1]; UInt32 tmpPositions[kNumBitsMax + 1]; int i; - for(i = 1; i <= kNumBitsMax; i++) + for (i = 1; i <= kNumBitsMax; i++) lenCounts[i] = 0; UInt32 symbol; for (symbol = 0; symbol < m_NumSymbols; symbol++) @@ -49,7 +49,7 @@ public: m_Limits[i] = (i == kNumBitsMax) ? kMaxValue : startPos; m_Positions[i] = m_Positions[i - 1] + lenCounts[i - 1]; tmpPositions[i] = m_Positions[i]; - if(i <= kNumTableBits) + if (i <= kNumTableBits) { UInt32 limit = (m_Limits[i] >> (kNumBitsMax - kNumTableBits)); for (; index < limit; index++) diff --git a/CPP/7zip/Compress/ImplodeDecoder.cpp b/CPP/7zip/Compress/ImplodeDecoder.cpp index f84a013c..e1d68a43 100755..100644 --- a/CPP/7zip/Compress/ImplodeDecoder.cpp +++ b/CPP/7zip/Compress/ImplodeDecoder.cpp @@ -1,9 +1,10 @@ -// Implode/Decoder.cpp +// ImplodeDecoder.cpp #include "StdAfx.h" +#include "../../Common/Defs.h" + #include "ImplodeDecoder.h" -#include "Common/Defs.h" namespace NCompress { namespace NImplode { @@ -67,11 +68,13 @@ CCoder::CCoder(): { } +/* void CCoder::ReleaseStreams() { m_OutWindowStream.ReleaseStream(); m_InBitStream.ReleaseStream(); } +*/ bool CCoder::ReadLevelItems(NImplode::NHuffman::CDecoder &decoder, Byte *levels, int numLevelItems) @@ -79,7 +82,7 @@ bool CCoder::ReadLevelItems(NImplode::NHuffman::CDecoder &decoder, int numCodedStructures = m_InBitStream.ReadBits(kNumBitsInByte) + kLevelStructuresNumberAdditionalValue; int currentIndex = 0; - for(int i = 0; i < numCodedStructures; i++) + for (int i = 0; i < numCodedStructures; i++) { int level = m_InBitStream.ReadBits(kNumLevelStructureLevelBits) + kLevelStructureLevelAdditionalValue; @@ -87,7 +90,7 @@ bool CCoder::ReadLevelItems(NImplode::NHuffman::CDecoder &decoder, kLevelStructureRepNumberAdditionalValue; if (currentIndex + rep > numLevelItems) throw CException(CException::kData); - for(int j = 0; j < rep; j++) + for (int j = 0; j < rep; j++) levels[currentIndex++] = (Byte)level; } if (currentIndex != numLevelItems) @@ -113,6 +116,7 @@ bool CCoder::ReadTables(void) return ReadLevelItems(m_DistanceDecoder, distanceLevels, kDistanceTableSize); } +/* class CCoderReleaser { CCoder *m_Coder; @@ -120,6 +124,7 @@ public: CCoderReleaser(CCoder *coder): m_Coder(coder) {} ~CCoderReleaser() { m_Coder->ReleaseStreams(); } }; +*/ HRESULT CCoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress) @@ -136,19 +141,19 @@ HRESULT CCoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *ou m_OutWindowStream.Init(false); m_InBitStream.SetStream(inStream); m_InBitStream.Init(); - CCoderReleaser coderReleaser(this); + // CCoderReleaser coderReleaser(this); if (!ReadTables()) return S_FALSE; - while(pos < unPackSize) + while (pos < unPackSize) { if (progress != NULL && pos % (1 << 16) == 0) { UInt64 packSize = m_InBitStream.GetProcessedSize(); RINOK(progress->SetRatioInfo(&packSize, &pos)); } - if(m_InBitStream.ReadBits(1) == kMatchId) // match + if (m_InBitStream.ReadBits(1) == kMatchId) // match { UInt32 lowDistBits = m_InBitStream.ReadBits(m_NumDistanceLowDirectBits); UInt32 distance = m_DistanceDecoder.DecodeSymbol(&m_InBitStream); @@ -159,9 +164,9 @@ HRESULT CCoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *ou if (lengthSymbol >= kLengthTableSize) return S_FALSE; UInt32 length = lengthSymbol + m_MinMatchLength; - if (lengthSymbol == kLengthTableSize - 1) // special symbol = 63 + if (lengthSymbol == kLengthTableSize - 1) // special symbol = 63 length += m_InBitStream.ReadBits(kNumAdditionalLengthBits); - while(distance >= pos && length > 0) + while (distance >= pos && length > 0) { m_OutWindowStream.PutByte(0); pos++; diff --git a/CPP/7zip/Compress/ImplodeDecoder.h b/CPP/7zip/Compress/ImplodeDecoder.h index 7ea1553e..5876ecac 100755..100644 --- a/CPP/7zip/Compress/ImplodeDecoder.h +++ b/CPP/7zip/Compress/ImplodeDecoder.h @@ -40,9 +40,8 @@ public: MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2) - void ReleaseStreams(); - HRESULT Flush() { return m_OutWindowStream.Flush(); } - + // void ReleaseStreams(); + HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); diff --git a/CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp b/CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp index 64345e08..2170326e 100755..100644 --- a/CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp +++ b/CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp @@ -24,7 +24,7 @@ bool CDecoder::SetCodeLengths(const Byte *codeLengths) // int lenCounts[kNumBitsInLongestCode + 1], tmpPositions[kNumBitsInLongestCode + 1]; int lenCounts[kNumBitsInLongestCode + 2], tmpPositions[kNumBitsInLongestCode + 1]; int i; - for(i = 0; i <= kNumBitsInLongestCode; i++) + for (i = 0; i <= kNumBitsInLongestCode; i++) lenCounts[i] = 0; UInt32 symbolIndex; for (symbolIndex = 0; symbolIndex < m_NumSymbols; symbolIndex++) @@ -34,7 +34,7 @@ bool CDecoder::SetCodeLengths(const Byte *codeLengths) // tmpPositions[0] = m_Positions[0] = m_Limitits[0] = 0; m_Limitits[kNumBitsInLongestCode + 1] = 0; m_Positions[kNumBitsInLongestCode + 1] = 0; - lenCounts[kNumBitsInLongestCode + 1] = 0; + lenCounts[kNumBitsInLongestCode + 1] = 0; UInt32 startPos = 0; @@ -68,7 +68,7 @@ UInt32 CDecoder::DecodeSymbol(CInBit *inStream) UInt32 numBits = 0; UInt32 value = inStream->GetValue(kNumBitsInLongestCode); int i; - for(i = kNumBitsInLongestCode; i > 0; i--) + for (i = kNumBitsInLongestCode; i > 0; i--) { if (value < m_Limitits[i]) { diff --git a/CPP/7zip/Compress/ImplodeHuffmanDecoder.h b/CPP/7zip/Compress/ImplodeHuffmanDecoder.h index 6120a35a..6120a35a 100755..100644 --- a/CPP/7zip/Compress/ImplodeHuffmanDecoder.h +++ b/CPP/7zip/Compress/ImplodeHuffmanDecoder.h diff --git a/CPP/7zip/Compress/LzOutWindow.cpp b/CPP/7zip/Compress/LzOutWindow.cpp index df46295b..df46295b 100755..100644 --- a/CPP/7zip/Compress/LzOutWindow.cpp +++ b/CPP/7zip/Compress/LzOutWindow.cpp diff --git a/CPP/7zip/Compress/LzOutWindow.h b/CPP/7zip/Compress/LzOutWindow.h index d8d13c22..507aa7f4 100755..100644 --- a/CPP/7zip/Compress/LzOutWindow.h +++ b/CPP/7zip/Compress/LzOutWindow.h @@ -3,8 +3,6 @@ #ifndef __LZ_OUT_WINDOW_H #define __LZ_OUT_WINDOW_H -#include "../IStream.h" - #include "../Common/OutBuffer.h" #ifndef _NO_EXCEPTIONS @@ -14,7 +12,7 @@ typedef COutBufferException CLzOutWindowException; class CLzOutWindow: public COutBuffer { public: - void Init(bool solid = false); + void Init(bool solid = false) throw(); // distance >= 0, len > 0, bool CopyBlock(UInt32 distance, UInt32 len) @@ -22,34 +20,34 @@ public: UInt32 pos = _pos - distance - 1; if (distance >= _pos) { - if (!_overDict || distance >= _bufferSize) + if (!_overDict || distance >= _bufSize) return false; - pos += _bufferSize; + pos += _bufSize; } - if (_limitPos - _pos > len && _bufferSize - pos > len) + if (_limitPos - _pos > len && _bufSize - pos > len) { - const Byte *src = _buffer + pos; - Byte *dest = _buffer + _pos; + const Byte *src = _buf + pos; + Byte *dest = _buf + _pos; _pos += len; do *dest++ = *src++; - while(--len != 0); + while (--len != 0); } else do { - if (pos == _bufferSize) + if (pos == _bufSize) pos = 0; - _buffer[_pos++] = _buffer[pos++]; + _buf[_pos++] = _buf[pos++]; if (_pos == _limitPos) FlushWithCheck(); } - while(--len != 0); + while (--len != 0); return true; } void PutByte(Byte b) { - _buffer[_pos++] = b; + _buf[_pos++] = b; if (_pos == _limitPos) FlushWithCheck(); } @@ -57,9 +55,9 @@ public: Byte GetByte(UInt32 distance) const { UInt32 pos = _pos - distance - 1; - if (pos >= _bufferSize) - pos += _bufferSize; - return _buffer[pos]; + if (pos >= _bufSize) + pos += _bufSize; + return _buf[pos]; } }; diff --git a/CPP/7zip/Compress/LzhDecoder.cpp b/CPP/7zip/Compress/LzhDecoder.cpp index 6f9b5065..ad6e873a 100755..100644 --- a/CPP/7zip/Compress/LzhDecoder.cpp +++ b/CPP/7zip/Compress/LzhDecoder.cpp @@ -4,8 +4,6 @@ #include "LzhDecoder.h" -#include "Windows/Defs.h" - namespace NCompress{ namespace NLzh { namespace NDecoder { @@ -16,7 +14,7 @@ static const int kBlockSizeBits = 16; static const int kNumCBits = 9; static const int kNumLevelBits = 5; // smallest integer such that (1 << kNumLevelBits) > kNumLevelSymbols/ -UInt32 CCoder::ReadBits(int numBits) { return m_InBitStream.ReadBits(numBits); } +UInt32 CCoder::ReadBits(int numBits) { return m_InBitStream.ReadBits(numBits); } HRESULT CCoder::ReadLevelTable() { @@ -163,7 +161,7 @@ STDMETHODIMP CCoder::CodeReal(ISequentialInStream *inStream, UInt32 blockSize = 0; - while(pos < *outSize) + while (pos < *outSize) { // for (i = 0; i < dictSize; i++) dtext[i] = 0x20; @@ -191,7 +189,7 @@ STDMETHODIMP CCoder::CodeReal(ISequentialInStream *inStream, else { // offset = (interface->method == LARC_METHOD_NUM) ? 0x100 - 2 : 0x100 - 3; - UInt32 len = c - 256 + kMinMatch; + UInt32 len = c - 256 + kMinMatch; UInt32 distance = m_PHuffmanDecoder.Decode(&m_InBitStream); if (distance != 0) distance = (1 << (distance - 1)) + ReadBits(distance - 1); diff --git a/CPP/7zip/Compress/LzhDecoder.h b/CPP/7zip/Compress/LzhDecoder.h index ed631e20..a805f9f9 100755..100644 --- a/CPP/7zip/Compress/LzhDecoder.h +++ b/CPP/7zip/Compress/LzhDecoder.h @@ -56,11 +56,12 @@ class CCoder : CHuffmanDecoder<kNumDistanceSymbols> m_PHuffmanDecoder; CHuffmanDecoder<kNumCSymbols> m_CHuffmanDecoder; + /* void ReleaseStreams() { m_OutWindowStream.ReleaseStream(); - m_InBitStream.ReleaseStream(); } + */ class CCoderReleaser { @@ -72,7 +73,7 @@ class CCoder : { if (NeedFlush) m_Coder->m_OutWindowStream.Flush(); - m_Coder->ReleaseStreams(); + // m_Coder->ReleaseStreams(); } }; friend class CCoderReleaser; diff --git a/CPP/7zip/Compress/Lzma2Decoder.cpp b/CPP/7zip/Compress/Lzma2Decoder.cpp index 322015e2..322015e2 100755..100644 --- a/CPP/7zip/Compress/Lzma2Decoder.cpp +++ b/CPP/7zip/Compress/Lzma2Decoder.cpp diff --git a/CPP/7zip/Compress/Lzma2Decoder.h b/CPP/7zip/Compress/Lzma2Decoder.h index fd7ca2f3..fd7ca2f3 100755..100644 --- a/CPP/7zip/Compress/Lzma2Decoder.h +++ b/CPP/7zip/Compress/Lzma2Decoder.h diff --git a/CPP/7zip/Compress/Lzma2Encoder.cpp b/CPP/7zip/Compress/Lzma2Encoder.cpp index 5e4c71be..5e4c71be 100755..100644 --- a/CPP/7zip/Compress/Lzma2Encoder.cpp +++ b/CPP/7zip/Compress/Lzma2Encoder.cpp diff --git a/CPP/7zip/Compress/Lzma2Encoder.h b/CPP/7zip/Compress/Lzma2Encoder.h index f0fb74d3..f0fb74d3 100755..100644 --- a/CPP/7zip/Compress/Lzma2Encoder.h +++ b/CPP/7zip/Compress/Lzma2Encoder.h diff --git a/CPP/7zip/Compress/Lzma2Register.cpp b/CPP/7zip/Compress/Lzma2Register.cpp index cace871e..cace871e 100755..100644 --- a/CPP/7zip/Compress/Lzma2Register.cpp +++ b/CPP/7zip/Compress/Lzma2Register.cpp diff --git a/CPP/7zip/Compress/LzmaDecoder.cpp b/CPP/7zip/Compress/LzmaDecoder.cpp index b7c260bd..a7ee31ba 100755..100644 --- a/CPP/7zip/Compress/LzmaDecoder.cpp +++ b/CPP/7zip/Compress/LzmaDecoder.cpp @@ -27,7 +27,8 @@ namespace NLzma { CDecoder::CDecoder(): _inBuf(0), _propsWereSet(false), _outSizeDefined(false), _inBufSize(1 << 20), _outBufSize(1 << 22), - FinishStream(false) + FinishStream(false), + NeedMoreInput(false) { _inSizeProcessed = 0; _inPos = _inSize = 0; @@ -81,6 +82,7 @@ STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize) { _inSizeProcessed = 0; _inPos = _inSize = 0; + NeedMoreInput = false; SetOutStreamSizeResume(outSize); return S_OK; } @@ -144,9 +146,21 @@ HRESULT CDecoder::CodeSpec(ISequentialInStream *inStream, ISequentialOutStream * return S_FALSE; RINOK(res2); if (stopDecoding) + { + if (status == LZMA_STATUS_NEEDS_MORE_INPUT) + NeedMoreInput = true; + if (FinishStream && + status != LZMA_STATUS_FINISHED_WITH_MARK && + status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK) + return S_FALSE; return S_OK; + } if (finished) + { + if (status == LZMA_STATUS_NEEDS_MORE_INPUT) + NeedMoreInput = true; return (status == LZMA_STATUS_FINISHED_WITH_MARK ? S_OK : S_FALSE); + } } if (progress) { diff --git a/CPP/7zip/Compress/LzmaDecoder.h b/CPP/7zip/Compress/LzmaDecoder.h index d28a4634..754eaa3f 100755..100644 --- a/CPP/7zip/Compress/LzmaDecoder.h +++ b/CPP/7zip/Compress/LzmaDecoder.h @@ -73,10 +73,14 @@ public: #endif - bool FinishStream; + bool FinishStream; // set it before decoding, if you need to decode full LZMA stream + + bool NeedMoreInput; // it's set by decoder, if it needs more input data to decode stream CDecoder(); virtual ~CDecoder(); + + UInt64 GetOutputProcessedSize() const { return _outSizeProcessed; } }; }} diff --git a/CPP/7zip/Compress/LzmaEncoder.cpp b/CPP/7zip/Compress/LzmaEncoder.cpp index 80e12f18..484d0452 100755..100644 --- a/CPP/7zip/Compress/LzmaEncoder.cpp +++ b/CPP/7zip/Compress/LzmaEncoder.cpp @@ -87,8 +87,8 @@ HRESULT SetLzmaProp(PROPID propID, const PROPVARIANT &prop, CLzmaEncProps &ep) return S_OK; if (propID == NCoderPropID::kReduceSize) { - if (prop.vt == VT_UI8 && prop.uhVal.QuadPart < (UInt32)(Int32)-1) - ep.reduceSize = (UInt32)prop.uhVal.QuadPart; + if (prop.vt == VT_UI8) + ep.reduceSize = prop.uhVal.QuadPart; return S_OK; } if (prop.vt != VT_UI4) @@ -124,7 +124,7 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, switch (propID) { case NCoderPropID::kEndMarker: - if (prop.vt != VT_BOOL) return E_INVALIDARG; props.writeEndMark = (prop.boolVal == VARIANT_TRUE); break; + if (prop.vt != VT_BOOL) return E_INVALIDARG; props.writeEndMark = (prop.boolVal != VARIANT_FALSE); break; default: RINOK(SetLzmaProp(propID, prop, props)); } @@ -148,6 +148,7 @@ STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream CCompressProgressWrap progressWrap(progress); SRes res = LzmaEnc_Encode(_encoder, &outWrap.p, &inWrap.p, progress ? &progressWrap.p : NULL, &g_Alloc, &g_BigAlloc); + _inputProcessed = inWrap.Processed; if (res == SZ_ERROR_READ && inWrap.Res != S_OK) return inWrap.Res; if (res == SZ_ERROR_WRITE && outWrap.Res != S_OK) @@ -156,5 +157,5 @@ STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream return progressWrap.Res; return SResToHRESULT(res); } - + }} diff --git a/CPP/7zip/Compress/LzmaEncoder.h b/CPP/7zip/Compress/LzmaEncoder.h index 904c0002..3ed067f1 100755..100644 --- a/CPP/7zip/Compress/LzmaEncoder.h +++ b/CPP/7zip/Compress/LzmaEncoder.h @@ -19,6 +19,7 @@ class CEncoder: public CMyUnknownImp { CLzmaEncHandle _encoder; + UInt64 _inputProcessed; public: MY_UNKNOWN_IMP2(ICompressSetCoderProperties, ICompressWriteCoderProperties) @@ -29,6 +30,7 @@ public: CEncoder(); virtual ~CEncoder(); + UInt64 GetInputProcessedSize() const { return _inputProcessed; } }; }} diff --git a/CPP/7zip/Compress/LzmaRegister.cpp b/CPP/7zip/Compress/LzmaRegister.cpp index 96ed0bae..96ed0bae 100755..100644 --- a/CPP/7zip/Compress/LzmaRegister.cpp +++ b/CPP/7zip/Compress/LzmaRegister.cpp diff --git a/CPP/7zip/Compress/Lzx.h b/CPP/7zip/Compress/Lzx.h index 09ab7f07..09ab7f07 100755..100644 --- a/CPP/7zip/Compress/Lzx.h +++ b/CPP/7zip/Compress/Lzx.h diff --git a/CPP/7zip/Compress/Lzx86Converter.cpp b/CPP/7zip/Compress/Lzx86Converter.cpp index 9e53f18a..3a63057a 100755..100644 --- a/CPP/7zip/Compress/Lzx86Converter.cpp +++ b/CPP/7zip/Compress/Lzx86Converter.cpp @@ -9,31 +9,31 @@ namespace NCompress { namespace NLzx { -static const int kResidue = 6 + 4; +static const UInt32 kResidue = 6 + 4; void Cx86ConvertOutStream::MakeTranslation() { - if (m_Pos <= kResidue) + if (_pos <= kResidue) return; - UInt32 numBytes = m_Pos - kResidue; - Byte *buffer = m_Buffer; + UInt32 numBytes = _pos - kResidue; + Byte *buf = _buf; for (UInt32 i = 0; i < numBytes;) { - if (buffer[i++] == 0xE8) + if (buf[i++] == 0xE8) { Int32 absValue = 0; - int j; - for(j = 0; j < 4; j++) - absValue += (UInt32)buffer[i + j] << (j * 8); - Int32 pos = (Int32)(m_ProcessedSize + i - 1); - if (absValue >= -pos && absValue < (Int32)m_TranslationSize) + unsigned j; + for (j = 0; j < 4; j++) + absValue += (UInt32)buf[i + j] << (j * 8); + Int32 pos = (Int32)(_processedSize + i - 1); + if (absValue >= -pos && absValue < (Int32)_translationSize) { UInt32 offset = (absValue >= 0) ? absValue - pos : - absValue + m_TranslationSize; - for(j = 0; j < 4; j++) + absValue + _translationSize; + for (j = 0; j < 4; j++) { - buffer[i + j] = (Byte)(offset & 0xFF); + buf[i + j] = (Byte)(offset & 0xFF); offset >>= 8; } } @@ -44,46 +44,46 @@ void Cx86ConvertOutStream::MakeTranslation() STDMETHODIMP Cx86ConvertOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) { - if (processedSize != NULL) + if (processedSize) *processedSize = 0; - if (!m_TranslationMode) - return m_Stream->Write(data, size, processedSize); + if (!_translationMode) + return _stream->Write(data, size, processedSize); UInt32 realProcessedSize = 0; while (realProcessedSize < size) { - UInt32 writeSize = MyMin(size - realProcessedSize, kUncompressedBlockSize - m_Pos); - memmove(m_Buffer + m_Pos, (const Byte *)data + realProcessedSize, writeSize); - m_Pos += writeSize; + UInt32 writeSize = MyMin(size - realProcessedSize, kUncompressedBlockSize - _pos); + memcpy(_buf + _pos, (const Byte *)data + realProcessedSize, writeSize); + _pos += writeSize; realProcessedSize += writeSize; - if (m_Pos == kUncompressedBlockSize) + if (_pos == kUncompressedBlockSize) { RINOK(Flush()); } } - if (processedSize != NULL) + if (processedSize) *processedSize = realProcessedSize; return S_OK; } HRESULT Cx86ConvertOutStream::Flush() { - if (m_Pos == 0) + if (_pos == 0) return S_OK; - if (m_TranslationMode) + if (_translationMode) MakeTranslation(); UInt32 pos = 0; do { UInt32 processed; - RINOK(m_Stream->Write(m_Buffer + pos, m_Pos - pos, &processed)); + RINOK(_stream->Write(_buf + pos, _pos - pos, &processed)); if (processed == 0) return E_FAIL; pos += processed; } - while(pos < m_Pos); - m_ProcessedSize += m_Pos; - m_Pos = 0; - m_TranslationMode = (m_TranslationMode && (m_ProcessedSize < (1 << 30))); + while (pos < _pos); + _processedSize += _pos; + _pos = 0; + _translationMode = (_translationMode && (_processedSize < ((UInt32)1 << 30))); return S_OK; } diff --git a/CPP/7zip/Compress/Lzx86Converter.h b/CPP/7zip/Compress/Lzx86Converter.h index 9f110c29..1e531d1a 100755..100644 --- a/CPP/7zip/Compress/Lzx86Converter.h +++ b/CPP/7zip/Compress/Lzx86Converter.h @@ -10,29 +10,28 @@ namespace NCompress { namespace NLzx { -const int kUncompressedBlockSize = 1 << 15; +const unsigned kUncompressedBlockSize = (unsigned)1 << 15; class Cx86ConvertOutStream: public ISequentialOutStream, public CMyUnknownImp { - CMyComPtr<ISequentialOutStream> m_Stream; - UInt32 m_ProcessedSize; - UInt32 m_Pos; - UInt32 m_TranslationSize; - bool m_TranslationMode; - Byte m_Buffer[kUncompressedBlockSize]; + ISequentialOutStream *_stream; + UInt32 _processedSize; + UInt32 _pos; + UInt32 _translationSize; + bool _translationMode; + Byte _buf[kUncompressedBlockSize]; void MakeTranslation(); public: - void SetStream(ISequentialOutStream *outStream) { m_Stream = outStream; } - void ReleaseStream() { m_Stream.Release(); } + void SetStream(ISequentialOutStream *outStream) { _stream = outStream; } void Init(bool translationMode, UInt32 translationSize) { - m_TranslationMode = translationMode; - m_TranslationSize = translationSize; - m_ProcessedSize = 0; - m_Pos = 0; + _translationMode = translationMode; + _translationSize = translationSize; + _processedSize = 0; + _pos = 0; } HRESULT Flush(); diff --git a/CPP/7zip/Compress/LzxDecoder.cpp b/CPP/7zip/Compress/LzxDecoder.cpp index 924229e9..acf3b037 100755..100644 --- a/CPP/7zip/Compress/LzxDecoder.cpp +++ b/CPP/7zip/Compress/LzxDecoder.cpp @@ -20,12 +20,14 @@ CDecoder::CDecoder(bool wimMode): m_x86ConvertOutStream = m_x86ConvertOutStreamSpec; } +/* void CDecoder::ReleaseStreams() { m_OutWindowStream.ReleaseStream(); m_InBitStream.ReleaseStream(); m_x86ConvertOutStreamSpec->ReleaseStream(); } +*/ STDMETHODIMP CDecoder::Flush() { @@ -152,7 +154,7 @@ public: { if (NeedFlush) m_Decoder->Flush(); - m_Decoder->ReleaseStreams(); + // m_Decoder->ReleaseStreams(); } }; @@ -308,7 +310,8 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * return E_INVALIDARG; UInt64 size = *outSize; - RINOK(SetInStream(inStream)); + // RINOK(SetInStream(inStream)); + m_InBitStream.SetStream(inStream); m_x86ConvertOutStreamSpec->SetStream(outStream); m_OutWindowStream.SetStream(m_x86ConvertOutStream); RINOK(SetOutStreamSize(outSize)); @@ -344,17 +347,20 @@ HRESULT CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outS catch(...) { return S_FALSE; } } +/* STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) { + m_InStreamRef = inStream; m_InBitStream.SetStream(inStream); return S_OK; } STDMETHODIMP CDecoder::ReleaseInStream() { - m_InBitStream.ReleaseStream(); + m_InStreamRef.Release(); return S_OK; } +*/ STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize) { diff --git a/CPP/7zip/Compress/LzxDecoder.h b/CPP/7zip/Compress/LzxDecoder.h index 73a05061..62d5b488 100755..100644 --- a/CPP/7zip/Compress/LzxDecoder.h +++ b/CPP/7zip/Compress/LzxDecoder.h @@ -23,45 +23,44 @@ const UInt32 kBitDecoderValueMask = (1 << kNumValueBits) - 1; class CDecoder { - CInBuffer m_Stream; - UInt32 m_Value; - unsigned m_BitPos; + CInBuffer _stream; + UInt32 _value; + unsigned _bitPos; public: CDecoder() {} - bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); } + bool Create(UInt32 bufSize) { return _stream.Create(bufSize); } - void SetStream(ISequentialInStream *s) { m_Stream.SetStream(s); } - void ReleaseStream() { m_Stream.ReleaseStream(); } + void SetStream(ISequentialInStream *s) { _stream.SetStream(s); } void Init() { - m_Stream.Init(); - m_BitPos = kNumBigValueBits; + _stream.Init(); + _bitPos = kNumBigValueBits; } - UInt64 GetProcessedSize() const { return m_Stream.GetProcessedSize() - (kNumBigValueBits - m_BitPos) / 8; } + UInt64 GetProcessedSize() const { return _stream.GetProcessedSize() - ((kNumBigValueBits - _bitPos) >> 3); } - unsigned GetBitPosition() const { return m_BitPos & 0xF; } + unsigned GetBitPosition() const { return _bitPos & 0xF; } void Normalize() { - for (; m_BitPos >= 16; m_BitPos -= 16) + for (; _bitPos >= 16; _bitPos -= 16) { - Byte b0 = m_Stream.ReadByte(); - Byte b1 = m_Stream.ReadByte(); - m_Value = (m_Value << 8) | b1; - m_Value = (m_Value << 8) | b0; + Byte b0 = _stream.ReadByte(); + Byte b1 = _stream.ReadByte(); + _value = (_value << 8) | b1; + _value = (_value << 8) | b0; } } UInt32 GetValue(unsigned numBits) const { - return ((m_Value >> ((32 - kNumValueBits) - m_BitPos)) & kBitDecoderValueMask) >> (kNumValueBits - numBits); + return ((_value >> ((32 - kNumValueBits) - _bitPos)) & kBitDecoderValueMask) >> (kNumValueBits - numBits); } void MovePos(unsigned numBits) { - m_BitPos += numBits; + _bitPos += numBits; Normalize(); } @@ -82,14 +81,14 @@ public: bool ReadUInt32(UInt32 &v) { - if (m_BitPos != 0) + if (_bitPos != 0) return false; - v = ((m_Value >> 16) & 0xFFFF) | ((m_Value << 16) & 0xFFFF0000); - m_BitPos = kNumBigValueBits; + v = ((_value >> 16) & 0xFFFF) | ((_value << 16) & 0xFFFF0000); + _bitPos = kNumBigValueBits; return true; } - Byte DirectReadByte() { return m_Stream.ReadByte(); } + Byte DirectReadByte() { return _stream.ReadByte(); } }; } @@ -98,6 +97,7 @@ class CDecoder : public ICompressCoder, public CMyUnknownImp { + // CMyComPtr<ISequentialInStream> m_InStreamRef; NBitStream::CDecoder m_InBitStream; CLzOutWindow m_OutWindowStream; @@ -140,14 +140,14 @@ public: MY_UNKNOWN_IMP - void ReleaseStreams(); + // void ReleaseStreams(); STDMETHOD(Flush)(); STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - STDMETHOD(SetInStream)(ISequentialInStream *inStream); - STDMETHOD(ReleaseInStream)(); + // STDMETHOD(SetInStream)(ISequentialInStream *inStream); + // STDMETHOD(ReleaseInStream)(); STDMETHOD(SetOutStreamSize)(const UInt64 *outSize); HRESULT SetParams(unsigned numDictBits); diff --git a/CPP/7zip/Compress/Mtf8.h b/CPP/7zip/Compress/Mtf8.h index d15dd4a5..5d49fe44 100755..100644 --- a/CPP/7zip/Compress/Mtf8.h +++ b/CPP/7zip/Compress/Mtf8.h @@ -5,19 +5,17 @@ #include "../../../C/CpuArch.h" -#include "../../Common/Types.h" - namespace NCompress { struct CMtf8Encoder { Byte Buf[256]; - int FindAndMove(Byte v) + unsigned FindAndMove(Byte v) { - int pos; + unsigned pos; for (pos = 0; Buf[pos] != v; pos++); - int resPos = pos; + unsigned resPos = pos; for (; pos >= 8; pos -= 8) { Buf[pos] = Buf[pos - 1]; @@ -29,7 +27,7 @@ struct CMtf8Encoder Buf[pos - 6] = Buf[pos - 7]; Buf[pos - 7] = Buf[pos - 8]; } - for (; pos > 0; pos--) + for (; pos != 0; pos--) Buf[pos] = Buf[pos - 1]; Buf[0] = v; return resPos; @@ -81,9 +79,9 @@ struct CMtf8Decoder CMtfVar Buf[256 >> MTF_MOVS]; void StartInit() { memset(Buf, 0, sizeof(Buf)); } - void Add(unsigned int pos, Byte val) { Buf[pos >> MTF_MOVS] |= ((CMtfVar)val << ((pos & MTF_MASK) << 3)); } + void Add(unsigned pos, Byte val) { Buf[pos >> MTF_MOVS] |= ((CMtfVar)val << ((pos & MTF_MASK) << 3)); } Byte GetHead() const { return (Byte)Buf[0]; } - Byte GetAndMove(unsigned int pos) + Byte GetAndMove(unsigned pos) { UInt32 lim = ((UInt32)pos >> MTF_MOVS); pos = (pos & MTF_MASK) << 3; @@ -164,7 +162,7 @@ public: for (int t = Counts[g] - 1; t >= 0; t--, i--) Buf[i] = Buf[offset + t]; } - while(g != 0); + while (g != 0); for (i = kSmallSize - 1; i >= 0; i--) Buf[i] = SmallBuffer[i]; diff --git a/CPP/7zip/Compress/PpmdDecoder.cpp b/CPP/7zip/Compress/PpmdDecoder.cpp index c02f44f1..c02f44f1 100755..100644 --- a/CPP/7zip/Compress/PpmdDecoder.cpp +++ b/CPP/7zip/Compress/PpmdDecoder.cpp diff --git a/CPP/7zip/Compress/PpmdDecoder.h b/CPP/7zip/Compress/PpmdDecoder.h index 8ebcd700..8ebcd700 100755..100644 --- a/CPP/7zip/Compress/PpmdDecoder.h +++ b/CPP/7zip/Compress/PpmdDecoder.h diff --git a/CPP/7zip/Compress/PpmdEncoder.cpp b/CPP/7zip/Compress/PpmdEncoder.cpp index 5bf83529..5bf83529 100755..100644 --- a/CPP/7zip/Compress/PpmdEncoder.cpp +++ b/CPP/7zip/Compress/PpmdEncoder.cpp diff --git a/CPP/7zip/Compress/PpmdEncoder.h b/CPP/7zip/Compress/PpmdEncoder.h index fb74cf57..fb74cf57 100755..100644 --- a/CPP/7zip/Compress/PpmdEncoder.h +++ b/CPP/7zip/Compress/PpmdEncoder.h diff --git a/CPP/7zip/Compress/PpmdRegister.cpp b/CPP/7zip/Compress/PpmdRegister.cpp index 9f59fcdd..9f59fcdd 100755..100644 --- a/CPP/7zip/Compress/PpmdRegister.cpp +++ b/CPP/7zip/Compress/PpmdRegister.cpp diff --git a/CPP/7zip/Compress/PpmdZip.cpp b/CPP/7zip/Compress/PpmdZip.cpp index 036f3c72..036f3c72 100755..100644 --- a/CPP/7zip/Compress/PpmdZip.cpp +++ b/CPP/7zip/Compress/PpmdZip.cpp diff --git a/CPP/7zip/Compress/PpmdZip.h b/CPP/7zip/Compress/PpmdZip.h index e15a060d..e15a060d 100755..100644 --- a/CPP/7zip/Compress/PpmdZip.h +++ b/CPP/7zip/Compress/PpmdZip.h diff --git a/CPP/7zip/Compress/QuantumDecoder.cpp b/CPP/7zip/Compress/QuantumDecoder.cpp index 63da32cc..b184dfb6 100755..100644 --- a/CPP/7zip/Compress/QuantumDecoder.cpp +++ b/CPP/7zip/Compress/QuantumDecoder.cpp @@ -70,7 +70,7 @@ HRESULT CDecoder::CodeSpec(UInt32 curSize) { lenSlot -= 2; int numDirectBits = (int)(lenSlot >> 2); - len += ((4 | (lenSlot & 3)) << numDirectBits) - 2; + len += ((4 | (lenSlot & 3)) << numDirectBits) - 2; if (numDirectBits < 6) len += _rangeDecoder.Stream.ReadBits(numDirectBits); } @@ -108,7 +108,9 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * return E_INVALIDARG; UInt64 size = *outSize; - SetInStream(inStream); + // SetInStream(inStream); + _rangeDecoder.SetStream(inStream); + _outWindowStream.SetStream(outStream); SetOutStreamSize(outSize); CDecoderFlusher flusher(this); @@ -143,17 +145,20 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream catch(...) { return S_FALSE; } } +/* STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) { + m_InStreamRef = inStream; _rangeDecoder.SetStream(inStream); return S_OK; } STDMETHODIMP CDecoder::ReleaseInStream() { - _rangeDecoder.ReleaseStream(); + m_InStreamRef.Release(); return S_OK; } +*/ STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize) { diff --git a/CPP/7zip/Compress/QuantumDecoder.h b/CPP/7zip/Compress/QuantumDecoder.h index a5f78358..c18ea2aa 100755..100644 --- a/CPP/7zip/Compress/QuantumDecoder.h +++ b/CPP/7zip/Compress/QuantumDecoder.h @@ -21,7 +21,7 @@ class CStreamBitDecoder public: bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); } void SetStream(ISequentialInStream *stream) { Stream.SetStream(stream); } - void ReleaseStream() { Stream.ReleaseStream(); } + // void ReleaseStream() { Stream.ReleaseStream(); } void Finish() { Value = 0x10000; } @@ -71,7 +71,7 @@ public: CStreamBitDecoder Stream; bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); } void SetStream(ISequentialInStream *stream) { Stream.SetStream(stream); } - void ReleaseStream() { Stream.ReleaseStream(); } + // void ReleaseStream() { Stream.ReleaseStream(); } void Init() { @@ -196,11 +196,12 @@ public: class CDecoder: public ICompressCoder, - public ICompressSetInStream, - public ICompressSetOutStreamSize, + // public ICompressSetInStream, + // public ICompressSetOutStreamSize, public CMyUnknownImp { CLzOutWindow _outWindowStream; + // CMyComPtr<ISequentialInStream> m_InStreamRef; NRangeCoder::CDecoder _rangeDecoder; UInt64 _outSize; @@ -217,15 +218,19 @@ class CDecoder: void Init(); HRESULT CodeSpec(UInt32 size); public: + + MY_UNKNOWN_IMP + + /* MY_UNKNOWN_IMP2( ICompressSetInStream, ICompressSetOutStreamSize) - void ReleaseStreams() { _outWindowStream.ReleaseStream(); ReleaseInStream(); } + */ class CDecoderFlusher { @@ -237,11 +242,11 @@ public: { if (NeedFlush) _decoder->Flush(); - _decoder->ReleaseStreams(); + // _decoder->ReleaseStreams(); } }; - HRESULT Flush() { return _outWindowStream.Flush(); } + HRESULT Flush() { return _outWindowStream.Flush(); } HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); @@ -249,8 +254,8 @@ public: STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - STDMETHOD(SetInStream)(ISequentialInStream *inStream); - STDMETHOD(ReleaseInStream)(); + // STDMETHOD(SetInStream)(ISequentialInStream *inStream); + // STDMETHOD(ReleaseInStream)(); STDMETHOD(SetOutStreamSize)(const UInt64 *outSize); HRESULT SetParams(int numDictBits); diff --git a/CPP/7zip/Compress/RangeCoder.h b/CPP/7zip/Compress/RangeCoder.h index 1eb2a6d4..0b0d44ae 100755..100644 --- a/CPP/7zip/Compress/RangeCoder.h +++ b/CPP/7zip/Compress/RangeCoder.h @@ -1,5 +1,5 @@ // Compress/RangeCoder.h -// 2009-05-30 : Igor Pavlov : Public domain +// 2013-01-10 : Igor Pavlov : Public domain #ifndef __COMPRESS_RANGE_CODER_H #define __COMPRESS_RANGE_CODER_H @@ -10,7 +10,7 @@ namespace NCompress { namespace NRangeCoder { -const int kNumTopBits = 24; +const unsigned kNumTopBits = 24; const UInt32 kTopValue = (1 << kNumTopBits); class CEncoder @@ -21,7 +21,7 @@ public: UInt64 Low; UInt32 Range; COutBuffer Stream; - bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); } + bool Create(UInt32 bufSize) { return Stream.Create(bufSize); } void SetStream(ISequentialOutStream *stream) { Stream.SetStream(stream); } void Init() @@ -36,14 +36,12 @@ public: void FlushData() { // Low += 1; - for(int i = 0; i < 5; i++) + for (int i = 0; i < 5; i++) ShiftLow(); } HRESULT FlushStream() { return Stream.Flush(); } - void ReleaseStream() { Stream.ReleaseStream(); } - void Encode(UInt32 start, UInt32 size, UInt32 total) { Low += start * (Range /= total); @@ -57,7 +55,7 @@ public: void ShiftLow() { - if ((UInt32)Low < (UInt32)0xFF000000 || (int)(Low >> 32) != 0) + if ((UInt32)Low < (UInt32)0xFF000000 || (unsigned)(Low >> 32) != 0) { Byte temp = _cache; do @@ -65,7 +63,7 @@ public: Stream.WriteByte((Byte)(temp + (Byte)(Low >> 32))); temp = 0xFF; } - while(--_cacheSize != 0); + while (--_cacheSize != 0); _cache = (Byte)((UInt32)Low >> 24); } _cacheSize++; @@ -103,7 +101,7 @@ public: } } - UInt64 GetProcessedSize() { return Stream.GetProcessedSize() + _cacheSize + 4; } + UInt64 GetProcessedSize() { return Stream.GetProcessedSize() + _cacheSize + 4; } }; class CDecoder @@ -112,7 +110,7 @@ public: CInBuffer Stream; UInt32 Range; UInt32 Code; - bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); } + bool Create(UInt32 bufSize) { return Stream.Create(bufSize); } void Normalize() { @@ -129,15 +127,13 @@ public: Stream.Init(); Code = 0; Range = 0xFFFFFFFF; - for(int i = 0; i < 5; i++) + for (int i = 0; i < 5; i++) Code = (Code << 8) | Stream.ReadByte(); } - void ReleaseStream() { Stream.ReleaseStream(); } - UInt32 GetThreshold(UInt32 total) { - return (Code) / ( Range /= total); + return (Code) / (Range /= total); } void Decode(UInt32 start, UInt32 size) @@ -197,7 +193,7 @@ public: return symbol; } - UInt64 GetProcessedSize() {return Stream.GetProcessedSize(); } + UInt64 GetProcessedSize() { return Stream.GetProcessedSize(); } }; }} diff --git a/CPP/7zip/Compress/RangeCoderBit.h b/CPP/7zip/Compress/RangeCoderBit.h index b5a1830d..0eddd558 100755..100644 --- a/CPP/7zip/Compress/RangeCoderBit.h +++ b/CPP/7zip/Compress/RangeCoderBit.h @@ -1,5 +1,5 @@ // Compress/RangeCoderBit.h -// 2009-05-30 : Igor Pavlov : Public domain +// 2013-01-10 : Igor Pavlov : Public domain #ifndef __COMPRESS_RANGE_CODER_BIT_H #define __COMPRESS_RANGE_CODER_BIT_H @@ -9,17 +9,17 @@ namespace NCompress { namespace NRangeCoder { -const int kNumBitModelTotalBits = 11; +const unsigned kNumBitModelTotalBits = 11; const UInt32 kBitModelTotal = (1 << kNumBitModelTotalBits); -const int kNumMoveReducingBits = 4; +const unsigned kNumMoveReducingBits = 4; -const int kNumBitPriceShiftBits = 4; +const unsigned kNumBitPriceShiftBits = 4; const UInt32 kBitPrice = 1 << kNumBitPriceShiftBits; extern UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits]; -template <int numMoveBits> +template <unsigned numMoveBits> class CBitModel { public: @@ -39,7 +39,7 @@ public: void Init() { Prob = kBitModelTotal / 2; } }; -template <int numMoveBits> +template <unsigned numMoveBits> class CBitEncoder: public CBitModel<numMoveBits> { public: @@ -69,14 +69,14 @@ public: } UInt32 GetPrice(UInt32 symbol) const { - return ProbPrices[(this->Prob ^ ((-(int)symbol)) & (kBitModelTotal - 1)) >> kNumMoveReducingBits]; + return ProbPrices[(this->Prob ^ ((-(int)(Int32)symbol)) & (kBitModelTotal - 1)) >> kNumMoveReducingBits]; } UInt32 GetPrice0() const { return ProbPrices[this->Prob >> kNumMoveReducingBits]; } UInt32 GetPrice1() const { return ProbPrices[(this->Prob ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]; } }; -template <int numMoveBits> +template <unsigned numMoveBits> class CBitDecoder: public CBitModel<numMoveBits> { public: diff --git a/CPP/7zip/Compress/Rar1Decoder.cpp b/CPP/7zip/Compress/Rar1Decoder.cpp index eadca7b3..8eb904df 100755..100644 --- a/CPP/7zip/Compress/Rar1Decoder.cpp +++ b/CPP/7zip/Compress/Rar1Decoder.cpp @@ -19,6 +19,7 @@ static UInt32 PosHf4[]={0,0,0,0,0,0,0,0,0,255, 257,0,0}; static const UInt32 kHistorySize = (1 << 16); +/* class CCoderReleaser { CDecoder *m_Coder; @@ -26,12 +27,13 @@ public: CCoderReleaser(CDecoder *coder): m_Coder(coder) {} ~CCoderReleaser() { m_Coder->ReleaseStreams(); } }; +*/ CDecoder::CDecoder(): m_IsSolid(false) { } void CDecoder::InitStructures() { - for(int i = 0; i < kNumRepDists; i++) + for (int i = 0; i < kNumRepDists; i++) m_RepDists[i] = 0; m_RepDistPtr = 0; LastLength = 0; @@ -65,9 +67,9 @@ UInt32 CDecoder::DecodeNum(const UInt32 *posTab) return((num >> (12 - startPos)) + posTab[startPos]); } -static Byte kShortLen1[] = {1,3,4,4,5,6,7,8,8,4,4,5,6,6 }; +static Byte kShortLen1 [] = {1,3,4,4,5,6,7,8,8,4,4,5,6,6 }; static Byte kShortLen1a[] = {1,4,4,4,5,6,7,8,8,4,4,5,6,6,4 }; -static Byte kShortLen2[] = {2,3,3,3,4,4,5,6,6,4,4,5,6,6 }; +static Byte kShortLen2 [] = {2,3,3,3,4,4,5,6,6,4,4,5,6,6 }; static Byte kShortLen2a[] = {2,3,3,4,4,4,5,6,6,4,4,5,6,6,4 }; static UInt32 kShortXor1[] = {0,0xa0,0xd0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff,0xc0,0x80,0x90,0x98,0x9c,0xb0}; static UInt32 kShortXor2[] = {0,0x40,0x60,0xa0,0xd0,0xe0,0xf0,0xf8,0xfc,0xc0,0x80,0x90,0x98,0x9c,0xb0}; @@ -389,7 +391,7 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * m_InBitStream.SetStream(inStream); m_InBitStream.Init(); - CCoderReleaser coderReleaser(this); + // CCoderReleaser coderReleaser(this); InitData(); if (!m_IsSolid) { diff --git a/CPP/7zip/Compress/Rar1Decoder.h b/CPP/7zip/Compress/Rar1Decoder.h index f7c08b38..630f0893 100755..100644 --- a/CPP/7zip/Compress/Rar1Decoder.h +++ b/CPP/7zip/Compress/Rar1Decoder.h @@ -70,11 +70,13 @@ public: MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2) + /* void ReleaseStreams() { m_OutWindowStream.ReleaseStream(); m_InBitStream.ReleaseStream(); } + */ STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); diff --git a/CPP/7zip/Compress/Rar2Decoder.cpp b/CPP/7zip/Compress/Rar2Decoder.cpp index 4e669bd6..1773939c 100755..100644 --- a/CPP/7zip/Compress/Rar2Decoder.cpp +++ b/CPP/7zip/Compress/Rar2Decoder.cpp @@ -85,7 +85,7 @@ CDecoder::CDecoder(): void CDecoder::InitStructures() { m_MmFilter.Init(); - for(int i = 0; i < kNumRepDists; i++) + for (int i = 0; i < kNumRepDists; i++) m_RepDists[i] = 0; m_RepDistPtr = 0; m_LastLength = 0; @@ -191,6 +191,7 @@ bool CDecoder::ReadLastTables() return true; } +/* class CCoderReleaser { CDecoder *m_Coder; @@ -201,6 +202,7 @@ public: m_Coder->ReleaseStreams(); } }; +*/ bool CDecoder::DecodeMm(UInt32 pos) { @@ -319,7 +321,7 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * m_InBitStream.SetStream(inStream); m_InBitStream.Init(); - CCoderReleaser coderReleaser(this); + // CCoderReleaser coderReleaser(this); if (!m_IsSolid) { InitStructures(); @@ -335,7 +337,7 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * } UInt64 startPos = m_OutWindowStream.GetProcessedSize(); - while(pos < unPackSize) + while (pos < unPackSize) { UInt32 blockSize = 1 << 20; if (blockSize > unPackSize - pos) diff --git a/CPP/7zip/Compress/Rar2Decoder.h b/CPP/7zip/Compress/Rar2Decoder.h index 61a8b4da..44b262c1 100755..100644 --- a/CPP/7zip/Compress/Rar2Decoder.h +++ b/CPP/7zip/Compress/Rar2Decoder.h @@ -53,10 +53,10 @@ const UInt32 kLen2NumNumbers = 8; const UInt32 kReadTableNumber = kLen2Number + kLen2NumNumbers; const UInt32 kMatchNumber = kReadTableNumber + 1; -const Byte kLenStart[kLenTableSize] = {0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224}; +const Byte kLenStart [kLenTableSize] = {0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224}; const Byte kLenDirectBits[kLenTableSize] = {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5}; -const UInt32 kDistStart[kDistTableSize] = {0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,1024,1536,2048,3072,4096,6144,8192,12288,16384,24576,32768U,49152U,65536,98304,131072,196608,262144,327680,393216,458752,524288,589824,655360,720896,786432,851968,917504,983040}; +const UInt32 kDistStart [kDistTableSize] = {0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,1024,1536,2048,3072,4096,6144,8192,12288,16384,24576,32768U,49152U,65536,98304,131072,196608,262144,327680,393216,458752,524288,589824,655360,720896,786432,851968,917504,983040}; const Byte kDistDirectBits[kDistTableSize] = {0,0,0,0,1,1,2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16}; const Byte kLevelDirectBits[kLevelTableSize] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7}; @@ -156,11 +156,13 @@ public: MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2) + /* void ReleaseStreams() { m_OutWindowStream.ReleaseStream(); m_InBitStream.ReleaseStream(); } + */ STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); diff --git a/CPP/7zip/Compress/Rar3Decoder.cpp b/CPP/7zip/Compress/Rar3Decoder.cpp index dde7c6de..3c70e1c0 100755..100644 --- a/CPP/7zip/Compress/Rar3Decoder.cpp +++ b/CPP/7zip/Compress/Rar3Decoder.cpp @@ -25,7 +25,7 @@ static const UInt32 kSymbolReadTable = 256; static const UInt32 kSymbolRep = 259; static const UInt32 kSymbolLen2 = kSymbolRep + kNumReps; -static const Byte kLenStart[kLenTableSize] = {0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224}; +static const Byte kLenStart [kLenTableSize] = {0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224}; static const Byte kLenDirectBits[kLenTableSize] = {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5}; static const Byte kDistDirectBits[kDistTableSize] = @@ -153,7 +153,7 @@ HRESULT CDecoder::WriteBuf() { UInt32 writtenBorder = _wrPtr; UInt32 writeSize = (_winPos - writtenBorder) & kWindowMask; - for (int i = 0; i < _tempFilters.Size(); i++) + FOR_VECTOR (i, _tempFilters) { CTempFilter *filter = _tempFilters[i]; if (filter == NULL) @@ -202,7 +202,7 @@ HRESULT CDecoder::WriteBuf() } else { - for (int j = i; j < _tempFilters.Size(); j++) + for (unsigned j = i; j < _tempFilters.Size(); j++) { CTempFilter *filter = _tempFilters[j]; if (filter != NULL && filter->NextWindow) @@ -221,7 +221,7 @@ HRESULT CDecoder::WriteBuf() void CDecoder::InitFilters() { _lastFilter = 0; - int i; + unsigned i; for (i = 0; i < _tempFilters.Size(); i++) delete _tempFilters[i]; _tempFilters.Clear(); @@ -238,7 +238,7 @@ bool CDecoder::AddVmCode(UInt32 firstByte, UInt32 codeSize) UInt32 filterIndex; if (firstByte & 0x80) { - filterIndex = NVm::ReadEncodedUInt32(inp); + filterIndex = inp.ReadEncodedUInt32(); if (filterIndex == 0) InitFilters(); else @@ -267,7 +267,7 @@ bool CDecoder::AddVmCode(UInt32 firstByte, UInt32 codeSize) } int numEmptyItems = 0; - int i; + unsigned i; for (i = 0; i < _tempFilters.Size(); i++) { _tempFilters[i - numEmptyItems] = _tempFilters[i]; @@ -284,62 +284,56 @@ bool CDecoder::AddVmCode(UInt32 firstByte, UInt32 codeSize) CTempFilter *tempFilter = new CTempFilter; _tempFilters[_tempFilters.Size() - numEmptyItems] = tempFilter; tempFilter->FilterIndex = filterIndex; - tempFilter->ExecCount = filter->ExecCount; - UInt32 blockStart = NVm::ReadEncodedUInt32(inp); + UInt32 blockStart = inp.ReadEncodedUInt32(); if (firstByte & 0x40) blockStart += 258; tempFilter->BlockStart = (blockStart + _winPos) & kWindowMask; if (firstByte & 0x20) - filter->BlockSize = NVm::ReadEncodedUInt32(inp); + filter->BlockSize = inp.ReadEncodedUInt32(); tempFilter->BlockSize = filter->BlockSize; tempFilter->NextWindow = _wrPtr != _winPos && ((_wrPtr - _winPos) & kWindowMask) <= blockStart; memset(tempFilter->InitR, 0, sizeof(tempFilter->InitR)); tempFilter->InitR[3] = NVm::kGlobalOffset; tempFilter->InitR[4] = tempFilter->BlockSize; - tempFilter->InitR[5] = tempFilter->ExecCount; + tempFilter->InitR[5] = filter->ExecCount; if (firstByte & 0x10) { UInt32 initMask = inp.ReadBits(NVm::kNumGpRegs); for (int i = 0; i < NVm::kNumGpRegs; i++) if (initMask & (1 << i)) - tempFilter->InitR[i] = NVm::ReadEncodedUInt32(inp); + tempFilter->InitR[i] = inp.ReadEncodedUInt32(); } if (newFilter) { - UInt32 vmCodeSize = NVm::ReadEncodedUInt32(inp); + UInt32 vmCodeSize = inp.ReadEncodedUInt32(); if (vmCodeSize >= kVmCodeSizeMax || vmCodeSize == 0) return false; for (UInt32 i = 0; i < vmCodeSize; i++) _vmCode[i] = (Byte)inp.ReadBits(8); - _vm.PrepareProgram(_vmCode, vmCodeSize, filter); + filter->PrepareProgram(_vmCode, vmCodeSize); } - tempFilter->AllocateEmptyFixedGlobal(); - Byte *globalData = &tempFilter->GlobalData[0]; for (i = 0; i < NVm::kNumGpRegs; i++) NVm::SetValue32(&globalData[i * 4], tempFilter->InitR[i]); NVm::SetValue32(&globalData[NVm::NGlobalOffset::kBlockSize], tempFilter->BlockSize); NVm::SetValue32(&globalData[NVm::NGlobalOffset::kBlockPos], 0); // It was commented. why? - NVm::SetValue32(&globalData[NVm::NGlobalOffset::kExecCount], tempFilter->ExecCount); + NVm::SetValue32(&globalData[NVm::NGlobalOffset::kExecCount], filter->ExecCount); if (firstByte & 8) { - UInt32 dataSize = NVm::ReadEncodedUInt32(inp); + UInt32 dataSize = inp.ReadEncodedUInt32(); if (dataSize > NVm::kGlobalSize - NVm::kFixedGlobalSize) return false; CRecordVector<Byte> &globalData = tempFilter->GlobalData; - int requredSize = (int)(dataSize + NVm::kFixedGlobalSize); - if (globalData.Size() < requredSize) - { - globalData.Reserve(requredSize); - for (; globalData.Size() < requredSize; i++) - globalData.Add(0); - } + unsigned requiredSize = (unsigned)(dataSize + NVm::kFixedGlobalSize); + if (globalData.Size() < requiredSize) + globalData.ChangeSize_KeepData(requiredSize); + Byte *dest = &globalData[NVm::kFixedGlobalSize]; for (UInt32 i = 0; i < dataSize; i++) - globalData[NVm::kFixedGlobalSize + i] = (Byte)inp.ReadBits(8); + dest[i] = (Byte)inp.ReadBits(8); } return true; } @@ -384,6 +378,8 @@ bool CDecoder::ReadVmCodePPM() } if (length > kVmDataSizeMax) return false; + if (InputEofError_Fast()) + return false; for (UInt32 i = 0; i < length; i++) { int b = DecodePpmSymbol(); @@ -396,14 +392,13 @@ bool CDecoder::ReadVmCodePPM() #define RIF(x) { if (!(x)) return S_FALSE; } -UInt32 CDecoder::ReadBits(int numBits) { return m_InBitStream.bitDecoder.ReadBits(numBits); } +UInt32 CDecoder::ReadBits(int numBits) { return m_InBitStream.BitDecoder.ReadBits(numBits); } -///////////////////////////////////////////////// -// PPM +// ---------- PPM ---------- HRESULT CDecoder::InitPPM() { - Byte maxOrder = (Byte)ReadBits(7); + unsigned maxOrder = (unsigned)ReadBits(7); bool reset = ((maxOrder & 0x20) != 0); int maxMB = 0; @@ -458,6 +453,8 @@ HRESULT CDecoder::DecodePPM(Int32 num, bool &keepDecompressing) return S_OK; } } + if (InputEofError_Fast()) + return false; int c = DecodePpmSymbol(); if (c < 0) { @@ -526,13 +523,12 @@ HRESULT CDecoder::DecodePPM(Int32 num, bool &keepDecompressing) return S_OK; } -///////////////////////////////////////////////// -// LZ +// ---------- LZ ---------- HRESULT CDecoder::ReadTables(bool &keepDecompressing) { keepDecompressing = true; - ReadBits((8 - m_InBitStream.bitDecoder.GetBitPosition()) & 7); + m_InBitStream.BitDecoder.AlignToByte(); if (ReadBits(1) != 0) { _lzMode = false; @@ -571,7 +567,7 @@ HRESULT CDecoder::ReadTables(bool &keepDecompressing) i = 0; while (i < kTablesSizesSum) { - UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream.bitDecoder); + UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream.BitDecoder); if (number < 16) { newLevels[i] = Byte((number + m_LastLevels[i]) & 15); @@ -620,6 +616,7 @@ HRESULT CDecoder::ReadTables(bool &keepDecompressing) return S_OK; } +/* class CCoderReleaser { CDecoder *m_Coder; @@ -630,6 +627,7 @@ public: m_Coder->ReleaseStreams(); } }; +*/ HRESULT CDecoder::ReadEndOfBlock(bool &keepDecompressing) { @@ -680,7 +678,11 @@ HRESULT CDecoder::DecodeLZ(bool &keepDecompressing) return S_OK; } } - UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream.bitDecoder); + + if (InputEofError_Fast()) + return S_FALSE; + + UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream.BitDecoder); if (number < 256) { PutByte((Byte)number); @@ -724,10 +726,10 @@ HRESULT CDecoder::DecodeLZ(bool &keepDecompressing) rep0 = distance; } - UInt32 number = m_LenDecoder.DecodeSymbol(&m_InBitStream.bitDecoder); + UInt32 number = m_LenDecoder.DecodeSymbol(&m_InBitStream.BitDecoder); if (number >= kLenTableSize) return S_FALSE; - length = 2 + kLenStart[number] + m_InBitStream.bitDecoder.ReadBits(kLenDirectBits[number]); + length = 2 + kLenStart[number] + m_InBitStream.BitDecoder.ReadBits(kLenDirectBits[number]); } else { @@ -737,14 +739,14 @@ HRESULT CDecoder::DecodeLZ(bool &keepDecompressing) if (number < 271) { number -= 263; - rep0 = kLen2DistStarts[number] + m_InBitStream.bitDecoder.ReadBits(kLen2DistDirectBits[number]); + rep0 = kLen2DistStarts[number] + m_InBitStream.BitDecoder.ReadBits(kLen2DistDirectBits[number]); length = 2; } else if (number < 299) { number -= 271; - length = kNormalMatchMinLen + (UInt32)kLenStart[number] + m_InBitStream.bitDecoder.ReadBits(kLenDirectBits[number]); - UInt32 number = m_DistDecoder.DecodeSymbol(&m_InBitStream.bitDecoder); + length = kNormalMatchMinLen + (UInt32)kLenStart[number] + m_InBitStream.BitDecoder.ReadBits(kLenDirectBits[number]); + UInt32 number = m_DistDecoder.DecodeSymbol(&m_InBitStream.BitDecoder); if (number >= kDistTableSize) return S_FALSE; rep0 = kDistStart[number]; @@ -752,7 +754,7 @@ HRESULT CDecoder::DecodeLZ(bool &keepDecompressing) if (number >= (kNumAlignBits * 2) + 2) { if (numBits > kNumAlignBits) - rep0 += (m_InBitStream.bitDecoder.ReadBits(numBits - kNumAlignBits) << kNumAlignBits); + rep0 += (m_InBitStream.BitDecoder.ReadBits(numBits - kNumAlignBits) << kNumAlignBits); if (PrevAlignCount > 0) { PrevAlignCount--; @@ -760,13 +762,13 @@ HRESULT CDecoder::DecodeLZ(bool &keepDecompressing) } else { - UInt32 number = m_AlignDecoder.DecodeSymbol(&m_InBitStream.bitDecoder); + UInt32 number = m_AlignDecoder.DecodeSymbol(&m_InBitStream.BitDecoder); if (number < (1 << kNumAlignBits)) { rep0 += number; PrevAlignBits = number; } - else if (number == (1 << kNumAlignBits)) + else if (number == (1 << kNumAlignBits)) { PrevAlignCount = kNumAlignReps; rep0 += PrevAlignBits; @@ -776,7 +778,7 @@ HRESULT CDecoder::DecodeLZ(bool &keepDecompressing) } } else - rep0 += m_InBitStream.bitDecoder.ReadBits(numBits); + rep0 += m_InBitStream.BitDecoder.ReadBits(numBits); length += ((kDistLimit4 - rep0) >> 31) + ((kDistLimit3 - rep0) >> 31); } else @@ -831,13 +833,17 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress) { RINOK(DecodePPM(1 << 18, keepDecompressing)) } - UInt64 packSize = m_InBitStream.bitDecoder.GetProcessedSize(); + + if (InputEofError()) + return S_FALSE; + + UInt64 packSize = m_InBitStream.BitDecoder.GetProcessedSize(); RINOK(progress->SetRatioInfo(&packSize, &_writtenFileSize)); if (!keepDecompressing) break; } RINOK(WriteBuf()); - UInt64 packSize = m_InBitStream.bitDecoder.GetProcessedSize(); + UInt64 packSize = m_InBitStream.BitDecoder.GetProcessedSize(); RINOK(progress->SetRatioInfo(&packSize, &_writtenFileSize)); if (_writtenFileSize < _unpackSize) return S_FALSE; @@ -866,17 +872,17 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream if (_window == 0) return E_OUTOFMEMORY; } - if (!m_InBitStream.bitDecoder.Create(1 << 20)) + if (!m_InBitStream.BitDecoder.Create(1 << 20)) return E_OUTOFMEMORY; if (!_vm.Create()) return E_OUTOFMEMORY; - m_InBitStream.bitDecoder.SetStream(inStream); - m_InBitStream.bitDecoder.Init(); + m_InBitStream.BitDecoder.SetStream(inStream); + m_InBitStream.BitDecoder.Init(); _outStream = outStream; - CCoderReleaser coderReleaser(this); + // CCoderReleaser coderReleaser(this); _unpackSize = *outSize; return CodeReal(progress); } diff --git a/CPP/7zip/Compress/Rar3Decoder.h b/CPP/7zip/Compress/Rar3Decoder.h index 99b647dc..77379858 100755..100644 --- a/CPP/7zip/Compress/Rar3Decoder.h +++ b/CPP/7zip/Compress/Rar3Decoder.h @@ -40,43 +40,53 @@ const UInt32 kTablesSizesSum = kMainTableSize + kDistTableSize + kAlignTableSize class CBitDecoder { - UInt32 m_Value; - unsigned m_BitPos; + UInt32 _value; + unsigned _bitPos; public: - CInBuffer m_Stream; - bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); } - void SetStream(ISequentialInStream *inStream) { m_Stream.SetStream(inStream);} - void ReleaseStream() { m_Stream.ReleaseStream();} + CInBuffer Stream; + + bool Create(UInt32 bufSize) { return Stream.Create(bufSize); } + void SetStream(ISequentialInStream *inStream) { Stream.SetStream(inStream);} void Init() { - m_Stream.Init(); - m_BitPos = 0; - m_Value = 0; + Stream.Init(); + _bitPos = 0; + _value = 0; } - UInt64 GetProcessedSize() const { return m_Stream.GetProcessedSize() - (m_BitPos) / 8; } - UInt32 GetBitPosition() const { return ((8 - m_BitPos) & 7); } + bool ExtraBitsWereRead() const + { + return (Stream.NumExtraBytes > 4 || _bitPos < (Stream.NumExtraBytes << 3)); + } + + UInt64 GetProcessedSize() const { return Stream.GetProcessedSize() - (_bitPos >> 3); } + + void AlignToByte() + { + _bitPos &= ~(unsigned)7; + _value = _value & ((1 << _bitPos) - 1); + } UInt32 GetValue(unsigned numBits) { - if (m_BitPos < numBits) + if (_bitPos < numBits) { - m_BitPos += 8; - m_Value = (m_Value << 8) | m_Stream.ReadByte(); - if (m_BitPos < numBits) + _bitPos += 8; + _value = (_value << 8) | Stream.ReadByte(); + if (_bitPos < numBits) { - m_BitPos += 8; - m_Value = (m_Value << 8) | m_Stream.ReadByte(); + _bitPos += 8; + _value = (_value << 8) | Stream.ReadByte(); } } - return m_Value >> (m_BitPos - numBits); + return _value >> (_bitPos - numBits); } void MovePos(unsigned numBits) { - m_BitPos -= numBits; - m_Value = m_Value & ((1 << m_BitPos) - 1); + _bitPos -= numBits; + _value = _value & ((1 << _bitPos) - 1); } UInt32 ReadBits(unsigned numBits) @@ -96,7 +106,7 @@ struct CRangeDecoder UInt32 Range; UInt32 Code; UInt32 Low; - CBitDecoder bitDecoder; + CBitDecoder BitDecoder; SRes Res; public: @@ -106,7 +116,7 @@ public: Low = 0; Range = 0xFFFFFFFF; for (int i = 0; i < 4; i++) - Code = (Code << 8) | bitDecoder.ReadBits(8); + Code = (Code << 8) | BitDecoder.ReadBits(8); } void Normalize() @@ -114,7 +124,7 @@ public: while ((Low ^ (Low + Range)) < kTopValue || Range < kBot && ((Range = (0 - Low) & (kBot - 1)), 1)) { - Code = (Code << 8) | bitDecoder.m_Stream.ReadByte(); + Code = (Code << 8) | BitDecoder.Stream.ReadByte(); Range <<= 8; Low <<= 8; } @@ -129,6 +139,7 @@ struct CFilter: public NVm::CProgram UInt32 BlockStart; UInt32 BlockSize; UInt32 ExecCount; + CFilter(): BlockStart(0), BlockSize(0), ExecCount(0) {} }; @@ -136,10 +147,15 @@ struct CTempFilter: public NVm::CProgramInitState { UInt32 BlockStart; UInt32 BlockSize; - UInt32 ExecCount; bool NextWindow; UInt32 FilterIndex; + + CTempFilter() + { + // all filters must contain at least FixedGlobal block + AllocateEmptyFixedGlobal(); + } }; const int kNumHuffmanBits = 15; @@ -156,7 +172,7 @@ class CDecoder: UInt64 _lzSize; UInt64 _unpackSize; UInt64 _writtenFileSize; // if it's > _unpackSize, then _unpackSize only written - CMyComPtr<ISequentialOutStream> _outStream; + ISequentialOutStream *_outStream; NHuffman::CDecoder<kNumHuffmanBits, kMainTableSize> m_MainDecoder; NHuffman::CDecoder<kNumHuffmanBits, kDistTableSize> m_DistDecoder; NHuffman::CDecoder<kNumHuffmanBits, kAlignTableSize> m_AlignDecoder; @@ -209,18 +225,16 @@ class CDecoder: HRESULT ReadEndOfBlock(bool &keepDecompressing); HRESULT DecodeLZ(bool &keepDecompressing); HRESULT CodeReal(ICompressProgressInfo *progress); + + bool InputEofError() const { return m_InBitStream.BitDecoder.ExtraBitsWereRead(); } + bool InputEofError_Fast() const { return (m_InBitStream.BitDecoder.Stream.NumExtraBytes > 2); } + public: CDecoder(); ~CDecoder(); MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2) - void ReleaseStreams() - { - _outStream.Release(); - m_InBitStream.bitDecoder.ReleaseStream(); - } - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); diff --git a/CPP/7zip/Compress/Rar3Vm.cpp b/CPP/7zip/Compress/Rar3Vm.cpp index 74051dd7..5b113bfa 100755..100644 --- a/CPP/7zip/Compress/Rar3Vm.cpp +++ b/CPP/7zip/Compress/Rar3Vm.cpp @@ -15,18 +15,20 @@ Note: #include "../../../C/7zCrc.h" #include "../../../C/Alloc.h" +#include "../../Common/Defs.h" + #include "Rar3Vm.h" namespace NCompress { namespace NRar3 { -UInt32 CMemBitDecoder::ReadBits(int numBits) +UInt32 CMemBitDecoder::ReadBits(unsigned numBits) { UInt32 res = 0; for (;;) { - Byte b = _bitPos < _bitSize ? _data[_bitPos >> 3] : 0; - int avail = (int)(8 - (_bitPos & 7)); + unsigned b = _bitPos < _bitSize ? (unsigned)_data[_bitPos >> 3] : 0; + unsigned avail = (unsigned)(8 - (_bitPos & 7)); if (numBits <= avail) { _bitPos += numBits; @@ -40,6 +42,15 @@ UInt32 CMemBitDecoder::ReadBits(int numBits) UInt32 CMemBitDecoder::ReadBit() { return ReadBits(1); } +UInt32 CMemBitDecoder::ReadEncodedUInt32() +{ + unsigned v = (unsigned)ReadBits(2); + UInt32 res = ReadBits(4 << v); + if (v == 1 && res < 16) + res = 0xFFFFFF00 | (res << 4) | ReadBits(4); + return res; +} + namespace NVm { static const UInt32 kStackRegIndex = kNumRegs - 1; @@ -58,7 +69,7 @@ static const Byte CF_PROC = 16; static const Byte CF_USEFLAGS = 32; static const Byte CF_CHFLAGS = 64; -static Byte kCmdFlags[]= +static const Byte kCmdFlags[]= { /* CMD_MOV */ CF_OP2 | CF_BYTEMODE, /* CMD_CMP */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS, @@ -142,7 +153,11 @@ bool CVm::Execute(CProgram *prg, const CProgramInitState *initState, { res = ExecuteCode(prg); if (!res) - prg->Commands[0].OpCode = CMD_RET; + { + prg->Commands.Clear(); + prg->Commands.Add(CCommand()); + prg->Commands.Back().OpCode = CMD_RET; + } } UInt32 newBlockPos = GetFixedGlobalValue32(NGlobalOffset::kBlockPos) & kSpaceMask; UInt32 newBlockSize = GetFixedGlobalValue32(NGlobalOffset::kBlockSize) & kSpaceMask; @@ -157,9 +172,8 @@ bool CVm::Execute(CProgram *prg, const CProgramInitState *initState, if (dataSize != 0) { dataSize += kFixedGlobalSize; - outGlobalData.Reserve(dataSize); - for (UInt32 i = 0; i < dataSize; i++) - outGlobalData.Add(Mem[kGlobalOffset + i]); + outGlobalData.ClearAndSetSize(dataSize); + memcpy(&outGlobalData[0], Mem + kGlobalOffset, dataSize); } return res; } @@ -234,6 +248,9 @@ bool CVm::ExecuteCode(const CProgram *prg) const CCommand *commands = &prg->Commands[0]; const CCommand *cmd = commands; UInt32 numCommands = prg->Commands.Size(); + if (numCommands == 0) + return false; + for (;;) { switch(cmd->OpCode) @@ -256,8 +273,7 @@ bool CVm::ExecuteCode(const CProgram *prg) case CMD_CMPB: { Byte v1 = GetOperand8(&cmd->Op1); - Byte res = v1 - GetOperand8(&cmd->Op2); - res &= 0xFF; + Byte res = (Byte)((v1 - GetOperand8(&cmd->Op2)) & 0xFF); Flags = res == 0 ? FLAG_Z : (res > v1) | GET_FLAG_S_B(res); } break; @@ -272,8 +288,7 @@ bool CVm::ExecuteCode(const CProgram *prg) case CMD_ADDB: { Byte v1 = GetOperand8(&cmd->Op1); - Byte res = v1 + GetOperand8(&cmd->Op2); - res &= 0xFF; + Byte res = (Byte)((v1 + GetOperand8(&cmd->Op2)) & 0xFF); SetOperand8(&cmd->Op1, (Byte)res); Flags = (res < v1) | (res == 0 ? FLAG_Z : GET_FLAG_S_B(res)); } @@ -326,7 +341,7 @@ bool CVm::ExecuteCode(const CProgram *prg) break; case CMD_INCB: { - Byte res = GetOperand8(&cmd->Op1) + 1; + Byte res = (Byte)(GetOperand8(&cmd->Op1) + 1); SetOperand8(&cmd->Op1, res);; FLAGS_UPDATE_SZ_B; } @@ -340,7 +355,7 @@ bool CVm::ExecuteCode(const CProgram *prg) break; case CMD_DECB: { - Byte res = GetOperand8(&cmd->Op1) - 1; + Byte res = (Byte)(GetOperand8(&cmd->Op1) - 1); SetOperand8(&cmd->Op1, res);; FLAGS_UPDATE_SZ_B; } @@ -354,7 +369,7 @@ bool CVm::ExecuteCode(const CProgram *prg) break; case CMD_XORB: { - Byte res = GetOperand8(&cmd->Op1) ^ GetOperand8(&cmd->Op2); + Byte res = (Byte)(GetOperand8(&cmd->Op1) ^ GetOperand8(&cmd->Op2)); SetOperand8(&cmd->Op1, res); FLAGS_UPDATE_SZ_B; } @@ -368,7 +383,7 @@ bool CVm::ExecuteCode(const CProgram *prg) break; case CMD_ANDB: { - Byte res = GetOperand8(&cmd->Op1) & GetOperand8(&cmd->Op2); + Byte res = (Byte)(GetOperand8(&cmd->Op1) & GetOperand8(&cmd->Op2)); SetOperand8(&cmd->Op1, res); FLAGS_UPDATE_SZ_B; } @@ -382,7 +397,7 @@ bool CVm::ExecuteCode(const CProgram *prg) break; case CMD_ORB: { - Byte res = GetOperand8(&cmd->Op1) | GetOperand8(&cmd->Op2); + Byte res = (Byte)(GetOperand8(&cmd->Op1) | GetOperand8(&cmd->Op2)); SetOperand8(&cmd->Op1, res); FLAGS_UPDATE_SZ_B; } @@ -395,7 +410,7 @@ bool CVm::ExecuteCode(const CProgram *prg) break; case CMD_TESTB: { - Byte res = GetOperand8(&cmd->Op1) & GetOperand8(&cmd->Op2); + Byte res = (Byte)(GetOperand8(&cmd->Op1) & GetOperand8(&cmd->Op2)); FLAGS_UPDATE_SZ_B; } break; @@ -589,7 +604,7 @@ bool CVm::ExecuteCode(const CProgram *prg) break; case CMD_MULB: { - Byte res = GetOperand8(&cmd->Op1) * GetOperand8(&cmd->Op2); + Byte res = (Byte)(GetOperand8(&cmd->Op1) * GetOperand8(&cmd->Op2)); SetOperand8(&cmd->Op1, res); } break; @@ -627,28 +642,7 @@ bool CVm::ExecuteCode(const CProgram *prg) ////////////////////////////////////////////////////// // Read program -UInt32 ReadEncodedUInt32(CMemBitDecoder &inp) -{ - switch(inp.ReadBits(2)) - { - case 0: - return inp.ReadBits(4); - case 1: - { - UInt32 v = inp.ReadBits(4); - if (v == 0) - return 0xFFFFFF00 | inp.ReadBits(8); - else - return (v << 4) | inp.ReadBits(4); - } - case 2: - return inp.ReadBits(16); - default: - return inp.ReadBits(32); - } -} - -void CVm::DecodeArg(CMemBitDecoder &inp, COperand &op, bool byteMode) +static void DecodeArg(CMemBitDecoder &inp, COperand &op, bool byteMode) { if (inp.ReadBit()) { @@ -661,7 +655,7 @@ void CVm::DecodeArg(CMemBitDecoder &inp, COperand &op, bool byteMode) if (byteMode) op.Data = inp.ReadBits(8); else - op.Data = ReadEncodedUInt32(inp); + op.Data = inp.ReadEncodedUInt32(); } else { @@ -677,27 +671,27 @@ void CVm::DecodeArg(CMemBitDecoder &inp, COperand &op, bool byteMode) op.Data = inp.ReadBits(kNumRegBits); else op.Data = kNumRegs; - op.Base = ReadEncodedUInt32(inp); + op.Base = inp.ReadEncodedUInt32(); } } } -void CVm::ReadVmProgram(const Byte *code, UInt32 codeSize, CProgram *prg) +void CProgram::ReadProgram(const Byte *code, UInt32 codeSize) { CMemBitDecoder inp; inp.Init(code, codeSize); - prg->StaticData.Clear(); + StaticData.Clear(); if (inp.ReadBit()) { - UInt32 dataSize = ReadEncodedUInt32(inp) + 1; + UInt32 dataSize = inp.ReadEncodedUInt32() + 1; for (UInt32 i = 0; inp.Avail() && i < dataSize; i++) - prg->StaticData.Add((Byte)inp.ReadBits(8)); + StaticData.Add((Byte)inp.ReadBits(8)); } while (inp.Avail()) { - prg->Commands.Add(CCommand()); - CCommand *cmd = &prg->Commands.Back(); + Commands.Add(CCommand()); + CCommand *cmd = &Commands.Back(); if (inp.ReadBit() == 0) cmd->OpCode = (ECommand)inp.ReadBits(3); else @@ -716,20 +710,20 @@ void CVm::ReadVmProgram(const Byte *code, UInt32 codeSize, CProgram *prg) { if (cmd->Op1.Type == OP_TYPE_INT && (kCmdFlags[cmd->OpCode] & (CF_JUMP | CF_PROC))) { - int Distance = cmd->Op1.Data; - if (Distance >= 256) - Distance -= 256; + int dist = cmd->Op1.Data; + if (dist >= 256) + dist -= 256; else { - if (Distance >= 136) - Distance -= 264; - else if (Distance >= 16) - Distance -= 8; - else if (Distance >= 8) - Distance -= 16; - Distance += prg->Commands.Size() - 1; + if (dist >= 136) + dist -= 264; + else if (dist >= 16) + dist -= 8; + else if (dist >= 8) + dist -= 16; + dist += Commands.Size() - 1; } - cmd->Op1.Data = Distance; + cmd->Op1.Data = dist; } } } @@ -770,7 +764,7 @@ enum EStandardFilter SF_UPCASE }; -struct StandardFilterSignature +static const struct CStandardFilterSignature { UInt32 Length; UInt32 CRC; @@ -792,7 +786,7 @@ static int FindStandardFilter(const Byte *code, UInt32 codeSize) UInt32 crc = CrcCalc(code, codeSize); for (int i = 0; i < sizeof(kStdFilters) / sizeof(kStdFilters[0]); i++) { - StandardFilterSignature &sfs = kStdFilters[i]; + const CStandardFilterSignature &sfs = kStdFilters[i]; if (sfs.CRC == crc && sfs.Length == codeSize) return i; } @@ -801,30 +795,28 @@ static int FindStandardFilter(const Byte *code, UInt32 codeSize) #endif -void CVm::PrepareProgram(const Byte *code, UInt32 codeSize, CProgram *prg) +void CProgram::PrepareProgram(const Byte *code, UInt32 codeSize) { Byte xorSum = 0; for (UInt32 i = 1; i < codeSize; i++) xorSum ^= code[i]; - prg->Commands.Clear(); + Commands.Clear(); #ifdef RARVM_STANDARD_FILTERS - prg->StandardFilterIndex = -1; + StandardFilterIndex = -1; #endif if (xorSum == code[0] && codeSize > 0) { #ifdef RARVM_STANDARD_FILTERS - prg->StandardFilterIndex = FindStandardFilter(code, codeSize); - if (prg->StandardFilterIndex >= 0) + StandardFilterIndex = FindStandardFilter(code, codeSize); + if (StandardFilterIndex >= 0) return; #endif - // 1 byte for checksum - ReadVmProgram(code + 1, codeSize - 1, prg); + ReadProgram(code + 1, codeSize - 1); } - prg->Commands.Add(CCommand()); - CCommand *cmd = &prg->Commands.Back(); - cmd->OpCode = CMD_RET; + Commands.Add(CCommand()); + Commands.Back().OpCode = CMD_RET; } void CVm::SetMemory(UInt32 pos, const Byte *data, UInt32 dataSize) @@ -841,7 +833,7 @@ static void E8E9Decode(Byte *data, UInt32 dataSize, UInt32 fileOffset, bool e9) return; dataSize -= 4; const UInt32 kFileSize = 0x1000000; - Byte cmpByte2 = (e9 ? 0xE9 : 0xE8); + Byte cmpByte2 = (Byte)(e9 ? 0xE9 : 0xE8); for (UInt32 curPos = 0; curPos < dataSize;) { Byte curByte = *(data++); @@ -886,7 +878,7 @@ static void ItaniumDecode(Byte *data, UInt32 dataSize, UInt32 fileOffset) { const UInt32 kMask = 0xFFFFF; Byte *p = data + ((unsigned int)startPos >> 3); - UInt32 bitField = ((UInt32)p[0]) | ((UInt32)p[1] << 8) | ((UInt32)p[2] << 16); + UInt32 bitField = ((UInt32)p[0]) | ((UInt32)p[1] << 8) | ((UInt32)p[2] << 16); int inBit = (startPos & 7); UInt32 offset = (bitField >> inBit) & kMask; UInt32 andMask = ~(kMask << inBit); @@ -915,7 +907,7 @@ static void DeltaDecode(Byte *data, UInt32 dataSize, UInt32 numChannels) { Byte prevByte = 0; for (UInt32 destPos = dataSize + curChannel; destPos < border; destPos += numChannels) - data[destPos] = (prevByte = prevByte - data[srcPos++]); + data[destPos] = (prevByte = (Byte)(prevByte - data[srcPos++])); } } @@ -956,8 +948,8 @@ static void RgbDecode(Byte *srcData, UInt32 dataSize, UInt32 width, UInt32 posR) for (UInt32 i = posR, border = dataSize - 2; i < border; i += 3) { Byte g = destData[i + 1]; - destData[i] = destData[i] + g; - destData[i + 2] = destData[i + 2] + g; + destData[i ] = (Byte)(destData[i ] + g); + destData[i + 2] = (Byte)(destData[i + 2] + g); } } diff --git a/CPP/7zip/Compress/Rar3Vm.h b/CPP/7zip/Compress/Rar3Vm.h index c02534c6..55842b90 100755..100644 --- a/CPP/7zip/Compress/Rar3Vm.h +++ b/CPP/7zip/Compress/Rar3Vm.h @@ -7,8 +7,8 @@ #include "../../../C/CpuArch.h" -#include "Common/MyVector.h" -#include "Common/Types.h" +#include "../../Common/MyTypes.h" +#include "../../Common/MyVector.h" #define RARVM_STANDARD_FILTERS @@ -27,9 +27,11 @@ public: _bitSize = (byteSize << 3); _bitPos = 0; } - UInt32 ReadBits(int numBits); + UInt32 ReadBits(unsigned numBits); UInt32 ReadBit(); bool Avail() const { return (_bitPos < _bitSize); } + + UInt32 ReadEncodedUInt32(); }; namespace NVm { @@ -37,8 +39,6 @@ namespace NVm { inline UInt32 GetValue32(const void *addr) { return GetUi32(addr); } inline void SetValue32(void *addr, UInt32 value) { SetUi32(addr, value); } -UInt32 ReadEncodedUInt32(CMemBitDecoder &inp); - const int kNumRegBits = 3; const UInt32 kNumRegs = 1 << kNumRegBits; const UInt32 kNumGpRegs = kNumRegs - 1; @@ -95,13 +95,19 @@ struct CBlockRef UInt32 Size; }; -struct CProgram +class CProgram { +public: CRecordVector<CCommand> Commands; #ifdef RARVM_STANDARD_FILTERS int StandardFilterIndex; #endif CRecordVector<Byte> StaticData; + +private: + void ReadProgram(const Byte *code, UInt32 codeSize); +public: + void PrepareProgram(const Byte *code, UInt32 codeSize); }; struct CProgramInitState @@ -111,10 +117,8 @@ struct CProgramInitState void AllocateEmptyFixedGlobal() { - GlobalData.Clear(); - GlobalData.Reserve(NVm::kFixedGlobalSize); - for (UInt32 i = 0; i < NVm::kFixedGlobalSize; i++) - GlobalData.Add(0); + GlobalData.ClearAndSetSize(NVm::kFixedGlobalSize); + memset(&GlobalData[0], 0, NVm::kFixedGlobalSize); } }; @@ -150,8 +154,6 @@ private: UInt32 GetOperand(bool byteMode, const COperand *op) const; void SetOperand(bool byteMode, const COperand *op, UInt32 val); - void DecodeArg(CMemBitDecoder &inp, COperand &op, bool byteMode); - bool ExecuteCode(const CProgram *prg); #ifdef RARVM_STANDARD_FILTERS @@ -161,12 +163,10 @@ private: Byte *Mem; UInt32 R[kNumRegs + 1]; // R[kNumRegs] = 0 always (speed optimization) UInt32 Flags; - void ReadVmProgram(const Byte *code, UInt32 codeSize, CProgram *prg); public: CVm(); ~CVm(); bool Create(); - void PrepareProgram(const Byte *code, UInt32 codeSize, CProgram *prg); void SetMemory(UInt32 pos, const Byte *data, UInt32 dataSize); bool Execute(CProgram *prg, const CProgramInitState *initState, CBlockRef &outBlockRef, CRecordVector<Byte> &outGlobalData); diff --git a/CPP/7zip/Compress/RarCodecsRegister.cpp b/CPP/7zip/Compress/RarCodecsRegister.cpp index e3f6a05c..e3f6a05c 100755..100644 --- a/CPP/7zip/Compress/RarCodecsRegister.cpp +++ b/CPP/7zip/Compress/RarCodecsRegister.cpp diff --git a/CPP/7zip/Compress/ShrinkDecoder.cpp b/CPP/7zip/Compress/ShrinkDecoder.cpp index a89d323c..a89d323c 100755..100644 --- a/CPP/7zip/Compress/ShrinkDecoder.cpp +++ b/CPP/7zip/Compress/ShrinkDecoder.cpp diff --git a/CPP/7zip/Compress/ShrinkDecoder.h b/CPP/7zip/Compress/ShrinkDecoder.h index 9bbecd41..9bbecd41 100755..100644 --- a/CPP/7zip/Compress/ShrinkDecoder.h +++ b/CPP/7zip/Compress/ShrinkDecoder.h diff --git a/CPP/7zip/Compress/StdAfx.h b/CPP/7zip/Compress/StdAfx.h index 99a8aa46..1cbd7fea 100755..100644 --- a/CPP/7zip/Compress/StdAfx.h +++ b/CPP/7zip/Compress/StdAfx.h @@ -3,6 +3,6 @@ #ifndef __STDAFX_H #define __STDAFX_H -#include "../../Common/MyWindows.h" +#include "../../Common/Common.h" #endif diff --git a/CPP/7zip/Compress/ZDecoder.cpp b/CPP/7zip/Compress/ZDecoder.cpp index e28c6451..7308bc0b 100755..100644 --- a/CPP/7zip/Compress/ZDecoder.cpp +++ b/CPP/7zip/Compress/ZDecoder.cpp @@ -2,6 +2,8 @@ #include "StdAfx.h" +// #include <stdio.h> + #include "../../../C/Alloc.h" #include "../Common/InBuffer.h" @@ -15,8 +17,8 @@ namespace NZ { static const UInt32 kBufferSize = (1 << 20); static const Byte kNumBitsMask = 0x1F; static const Byte kBlockModeMask = 0x80; -static const int kNumMinBits = 9; -static const int kNumMaxBits = 16; +static const unsigned kNumMinBits = 9; +static const unsigned kNumMaxBits = 16; void CDecoder::Free() { @@ -33,6 +35,8 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * CInBuffer inBuffer; COutBuffer outBuffer; + PackSize = 0; + if (!inBuffer.Create(kBufferSize)) return E_OUTOFMEMORY; inBuffer.SetStream(inStream); @@ -43,11 +47,22 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * outBuffer.SetStream(outStream); outBuffer.Init(); - int maxbits = _properties & kNumBitsMask; + Byte buf[kNumMaxBits + 4]; + { + if (inBuffer.ReadBytes(buf, 3) < 3) + return S_FALSE; + if (buf[0] != 0x1F || buf[1] != 0x9D) + return S_FALSE;; + } + Byte prop = buf[2]; + + if ((prop & 0x60) != 0) + return S_FALSE; + unsigned maxbits = prop & kNumBitsMask; if (maxbits < kNumMinBits || maxbits > kNumMaxBits) return S_FALSE; UInt32 numItems = 1 << maxbits; - bool blockMode = ((_properties & kBlockModeMask) != 0); + // Speed optimization: blockSymbol can contain unused velue. if (maxbits != _numMaxBits || _parents == 0 || _suffixes == 0 || _stack == 0) { @@ -59,18 +74,16 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * } UInt64 prevPos = 0; - int numBits = kNumMinBits; - UInt32 head = blockMode ? 257 : 256; - + UInt32 blockSymbol = ((prop & kBlockModeMask) != 0) ? 256 : ((UInt32)1 << kNumMaxBits); + unsigned numBits = kNumMinBits; + UInt32 head = (blockSymbol == 256) ? 257 : 256; bool needPrev = false; - unsigned bitPos = 0; unsigned numBufBits = 0; - Byte buf[kNumMaxBits + 4]; - _parents[256] = 0; // virus protection _suffixes[256] = 0; + HRESULT res = S_OK; for (;;) { @@ -79,7 +92,7 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * numBufBits = (unsigned)inBuffer.ReadBytes(buf, numBits) * 8; bitPos = 0; UInt64 nowPos = outBuffer.GetProcessedSize(); - if (progress != NULL && nowPos - prevPos >= (1 << 18)) + if (progress && nowPos - prevPos >= (1 << 13)) { prevPos = nowPos; UInt64 packSize = inBuffer.GetProcessedSize(); @@ -94,8 +107,11 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * if (bitPos > numBufBits) break; if (symbol >= head) - return S_FALSE; - if (blockMode && symbol == 256) + { + res = S_FALSE; + break; + } + if (symbol == blockSymbol) { numBufBits = bitPos = 0; numBits = kNumMinBits; @@ -104,7 +120,7 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * continue; } UInt32 cur = symbol; - int i = 0; + unsigned i = 0; while (cur >= 256) { _stack[i++] = _suffixes[cur]; @@ -136,7 +152,9 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * else needPrev = false; } - return outBuffer.Flush(); + PackSize = inBuffer.GetProcessedSize(); + HRESULT res2 = outBuffer.Flush(); + return (res == S_OK) ? res2 : res; } STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, @@ -148,12 +166,72 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream catch(...) { return S_FALSE; } } -STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) +bool CheckStream(const Byte *data, size_t size) { - if (size < 1) - return E_INVALIDARG; - _properties = data[0]; - return S_OK; + if (size < 3) + return false; + if (data[0] != 0x1F || data[1] != 0x9D) + return false; + Byte prop = data[2]; + if ((prop & 0x60) != 0) + return false; + unsigned maxbits = prop & kNumBitsMask; + if (maxbits < kNumMinBits || maxbits > kNumMaxBits) + return false; + UInt32 numItems = 1 << maxbits; + UInt32 blockSymbol = ((prop & kBlockModeMask) != 0) ? 256 : ((UInt32)1 << kNumMaxBits); + unsigned numBits = kNumMinBits; + UInt32 head = (blockSymbol == 256) ? 257 : 256; + unsigned bitPos = 0; + unsigned numBufBits = 0; + Byte buf[kNumMaxBits + 4]; + data += 3; + size -= 3; + // printf("\n\n"); + for (;;) + { + if (numBufBits == bitPos) + { + unsigned num = (numBits < size) ? numBits : (unsigned)size; + memcpy(buf, data, num); + data += num; + size -= num; + numBufBits = num * 8; + bitPos = 0; + } + unsigned bytePos = bitPos >> 3; + UInt32 symbol = buf[bytePos] | ((UInt32)buf[bytePos + 1] << 8) | ((UInt32)buf[bytePos + 2] << 16); + symbol >>= (bitPos & 7); + symbol &= (1 << numBits) - 1; + bitPos += numBits; + if (bitPos > numBufBits) + { + // printf(" OK", symbol); + return true; + } + // printf("%3X ", symbol); + if (symbol >= head) + return false; + if (symbol == blockSymbol) + { + numBufBits = bitPos = 0; + numBits = kNumMinBits; + head = 257; + continue; + } + if (head < numItems) + { + head++; + if (head > ((UInt32)1 << numBits)) + { + if (numBits < maxbits) + { + numBufBits = bitPos = 0; + numBits++; + } + } + } + } } }} diff --git a/CPP/7zip/Compress/ZDecoder.h b/CPP/7zip/Compress/ZDecoder.h index 2bd83a17..19acd498 100755..100644 --- a/CPP/7zip/Compress/ZDecoder.h +++ b/CPP/7zip/Compress/ZDecoder.h @@ -10,33 +10,45 @@ namespace NCompress { namespace NZ { +// Z decoder decodes Z data stream, including 3 bytes of header. + class CDecoder: public ICompressCoder, - public ICompressSetDecoderProperties2, public CMyUnknownImp { UInt16 *_parents; Byte *_suffixes; Byte *_stack; - Byte _properties; - int _numMaxBits; + unsigned _numMaxBits; public: - CDecoder(): _parents(0), _suffixes(0), _stack(0), _properties(0), _numMaxBits(0) {}; + CDecoder(): _parents(0), _suffixes(0), _stack(0), /* _prop(0), */ _numMaxBits(0) {}; ~CDecoder(); void Free(); + UInt64 PackSize; - MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2) + MY_UNKNOWN_IMP1(ICompressCoder) HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - - STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); }; +/* + There is no end_of_payload_marker in Z stream. + Z decoder stops decoding, if it reaches end of input stream. + + CheckStream function: + (size) must be at least 3 bytes (size of Z header). + if (size) is larger than size of real Z stream in (data), CheckStream can return false. +*/ + +const unsigned kRecommendedCheckSize = 64; + +bool CheckStream(const Byte *data, size_t size); + }} #endif diff --git a/CPP/7zip/Compress/ZlibDecoder.cpp b/CPP/7zip/Compress/ZlibDecoder.cpp index 90d6715d..8f3a63cb 100755..100644 --- a/CPP/7zip/Compress/ZlibDecoder.cpp +++ b/CPP/7zip/Compress/ZlibDecoder.cpp @@ -38,9 +38,12 @@ UInt32 Adler32_Update(UInt32 adler, const Byte *buf, size_t size) STDMETHODIMP COutStreamWithAdler::Write(const void *data, UInt32 size, UInt32 *processedSize) { - HRESULT result = _stream->Write(data, size, &size); + HRESULT result = S_OK; + if (_stream) + result = _stream->Write(data, size, &size); _adler = Adler32_Update(_adler, (const Byte *)data, size); - if (processedSize != NULL) + _size += size; + if (processedSize) *processedSize = size; return result; } @@ -58,21 +61,21 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream DeflateDecoder = DeflateDecoderSpec; } + if (inSize && *inSize < 2) + return S_FALSE; Byte buf[2]; RINOK(ReadStream_FALSE(inStream, buf, 2)); - int method = buf[0] & 0xF; - if (method != 8) - return S_FALSE; - // int dicSize = buf[0] >> 4; - if ((((UInt32)buf[0] << 8) + buf[1]) % 31 != 0) + if (!IsZlib(buf)) return S_FALSE; - if ((buf[1] & 0x20) != 0) // dictPresent - return S_FALSE; - // int level = (buf[1] >> 6); AdlerSpec->SetStream(outStream); AdlerSpec->Init(); - HRESULT res = DeflateDecoder->Code(inStream, AdlerStream, inSize, outSize, progress); + + UInt64 inSize2 = 0; + if (inSize) + inSize2 = *inSize - 2; + + HRESULT res = DeflateDecoder->Code(inStream, AdlerStream, inSize ? &inSize2 : NULL, outSize, progress); AdlerSpec->ReleaseStream(); if (res == S_OK) diff --git a/CPP/7zip/Compress/ZlibDecoder.h b/CPP/7zip/Compress/ZlibDecoder.h index 95c11002..8c5e73b0 100755..100644 --- a/CPP/7zip/Compress/ZlibDecoder.h +++ b/CPP/7zip/Compress/ZlibDecoder.h @@ -16,13 +16,15 @@ class COutStreamWithAdler: { CMyComPtr<ISequentialOutStream> _stream; UInt32 _adler; + UInt64 _size; public: MY_UNKNOWN_IMP STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); void SetStream(ISequentialOutStream *stream) { _stream = stream; } void ReleaseStream() { _stream.Release(); } - void Init() { _adler = ADLER_INIT_VAL; } + void Init() { _adler = ADLER_INIT_VAL; _size = 0; } UInt32 GetAdler() const { return _adler; } + UInt64 GetSize() const { return _size; } }; class CDecoder: @@ -39,10 +41,39 @@ public: const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); UInt64 GetInputProcessedSize() const { return DeflateDecoderSpec->GetInputProcessedSize() + 2; } + UInt64 GetOutputProcessedSize() const { return AdlerSpec->GetSize(); } MY_UNKNOWN_IMP }; +static bool inline IsZlib(const Byte *p) +{ + if ((p[0] & 0xF) != 8) // method + return false; + if (((unsigned)p[0] >> 4) > 7) // logar_window_size minus 8. + return false; + if ((p[1] & 0x20) != 0) // dictPresent + return false; + if ((((UInt32)p[0] << 8) + p[1]) % 31 != 0) + return false; + return true; +} + +// IsZlib_3bytes checks 2 bytes of zlib header and starting byte of Deflate stream + +static bool inline IsZlib_3bytes(const Byte *p) +{ + if (!IsZlib(p)) + return false; + unsigned val = p[2]; + unsigned blockType = (val >> 1) & 0x3; + if (blockType == 3) // unsupported block type for deflate + return false; + if (blockType == NCompress::NDeflate::NBlockType::kStored && (val >> 3) != 0) + return false; + return true; +} + }} #endif diff --git a/CPP/7zip/Compress/ZlibEncoder.cpp b/CPP/7zip/Compress/ZlibEncoder.cpp index 09235c33..09235c33 100755..100644 --- a/CPP/7zip/Compress/ZlibEncoder.cpp +++ b/CPP/7zip/Compress/ZlibEncoder.cpp diff --git a/CPP/7zip/Compress/ZlibEncoder.h b/CPP/7zip/Compress/ZlibEncoder.h index 621cc1d0..621cc1d0 100755..100644 --- a/CPP/7zip/Compress/ZlibEncoder.h +++ b/CPP/7zip/Compress/ZlibEncoder.h diff --git a/CPP/7zip/Compress/makefile b/CPP/7zip/Compress/makefile index e981319d..e981319d 100755..100644 --- a/CPP/7zip/Compress/makefile +++ b/CPP/7zip/Compress/makefile |