diff options
author | Igor Pavlov <ipavlov@users.sourceforge.net> | 2010-09-08 04:00:00 +0400 |
---|---|---|
committer | Kornel LesiĆski <kornel@geekhood.net> | 2016-05-28 02:16:03 +0300 |
commit | 044e4bb7413beb329edfa3ad27b492d819cdc811 (patch) | |
tree | 9da146355814669c1c9331c596edce0acd21c490 /CPP/7zip/Compress | |
parent | e279500d76f1944ba26526f085030909a2c7ef49 (diff) |
9.169.16
Diffstat (limited to 'CPP/7zip/Compress')
-rwxr-xr-x | CPP/7zip/Compress/BZip2Decoder.cpp | 184 | ||||
-rwxr-xr-x | CPP/7zip/Compress/BZip2Decoder.h | 36 | ||||
-rwxr-xr-x | CPP/7zip/Compress/DeflateNsisRegister.cpp | 14 | ||||
-rwxr-xr-x | CPP/7zip/Compress/Rar3Decoder.cpp | 6 |
4 files changed, 196 insertions, 44 deletions
diff --git a/CPP/7zip/Compress/BZip2Decoder.cpp b/CPP/7zip/Compress/BZip2Decoder.cpp index 96ecf4b5..bc252d09 100755 --- a/CPP/7zip/Compress/BZip2Decoder.cpp +++ b/CPP/7zip/Compress/BZip2Decoder.cpp @@ -4,9 +4,6 @@ #include "../../../C/Alloc.h" -#include "../../Common/Defs.h" - -#include "BZip2Crc.h" #include "BZip2Decoder.h" #include "Mtf8.h" @@ -15,11 +12,11 @@ namespace NBZip2 { #define NO_INLINE MY_FAST_CALL -const UInt32 kNumThreadsMax = 4; +static const UInt32 kNumThreadsMax = 4; static const UInt32 kBufferSize = (1 << 17); -static Int16 kRandNums[512] = { +static const UInt16 kRandNums[512] = { 619, 720, 127, 481, 931, 816, 813, 233, 566, 247, 985, 724, 205, 454, 863, 491, 741, 242, 949, 214, 733, 859, 335, 708, 621, 574, 73, 654, 730, 472, @@ -76,8 +73,8 @@ static Int16 kRandNums[512] = { bool CState::Alloc() { - if (Counters == 0) - Counters = (UInt32 *)BigAlloc((256 + kBlockSizeMax) * sizeof(UInt32)); + if (!Counters) + Counters = (UInt32 *)::BigAlloc((256 + kBlockSizeMax) * sizeof(UInt32)); return (Counters != 0); } @@ -87,7 +84,7 @@ void CState::Free() Counters = 0; } -UInt32 CDecoder::ReadBits(int numBits) { return m_InStream.ReadBits(numBits); } +UInt32 CDecoder::ReadBits(unsigned numBits) { return m_InStream.ReadBits(numBits); } Byte CDecoder::ReadByte() {return (Byte)ReadBits(8); } bool CDecoder::ReadBit() { return ReadBits(1) != 0; } @@ -102,21 +99,22 @@ UInt32 CDecoder::ReadCrc() return crc; } -UInt32 NO_INLINE ReadBits(NBitm::CDecoder<CInBuffer> *m_InStream, int num) +static UInt32 NO_INLINE ReadBits(NBitm::CDecoder<CInBuffer> *m_InStream, unsigned num) { return m_InStream->ReadBits(num); } -UInt32 NO_INLINE ReadBit(NBitm::CDecoder<CInBuffer> *m_InStream) +static UInt32 NO_INLINE ReadBit(NBitm::CDecoder<CInBuffer> *m_InStream) { return m_InStream->ReadBits(1); } 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) + UInt32 *CharCounters, UInt32 blockSizeMax, Byte *m_Selectors, CHuffmanDecoder *m_HuffmanDecoders, + UInt32 *blockSizeRes, UInt32 *origPtrRes, bool *randRes) { - *randRes = ReadBit(m_InStream) ? true : false; + if (randRes) + *randRes = ReadBit(m_InStream) ? true : false; *origPtrRes = ReadBits(m_InStream, kNumOrigBits); // in original code it compares OrigPtr to (UInt32)(10 + blockSizeMax)) : why ? @@ -258,7 +256,7 @@ static HRESULT NO_INLINE ReadBlock(NBitm::CDecoder<CInBuffer> *m_InStream, return (*origPtrRes < blockSize) ? S_OK : S_FALSE; } -void NO_INLINE DecodeBlock1(UInt32 *charCounters, UInt32 blockSize) +static void NO_INLINE DecodeBlock1(UInt32 *charCounters, UInt32 blockSize) { { UInt32 sum = 0; @@ -283,13 +281,13 @@ static UInt32 NO_INLINE DecodeBlock2(const UInt32 *tt, UInt32 blockSize, UInt32 // it's for speed optimization: prefetch & prevByte_init; UInt32 tPos = tt[tt[OrigPtr] >> 8]; - unsigned int prevByte = (unsigned int)(tPos & 0xFF); + unsigned prevByte = (unsigned)(tPos & 0xFF); - int numReps = 0; + unsigned numReps = 0; do { - unsigned int b = (unsigned int)(tPos & 0xFF); + unsigned b = (unsigned)(tPos & 0xFF); tPos = tt[tPos >> 8]; if (numReps == kRleModeRepSize) @@ -315,7 +313,7 @@ static UInt32 NO_INLINE DecodeBlock2(const UInt32 *tt, UInt32 blockSize, UInt32 m_OutStream.WriteByte((Byte)b); for (; --blockSize != 0;) { - b = (unsigned int)(tPos & 0xFF); + b = (unsigned)(tPos & 0xFF); tPos = tt[tPos >> 8]; crc.UpdateByte(b); m_OutStream.WriteByte((Byte)b); @@ -327,7 +325,7 @@ static UInt32 NO_INLINE DecodeBlock2(const UInt32 *tt, UInt32 blockSize, UInt32 if (--blockSize == 0) break; - b = (unsigned int)(tPos & 0xFF); + b = (unsigned)(tPos & 0xFF); tPos = tt[tPos >> 8]; crc.UpdateByte(b); m_OutStream.WriteByte((Byte)b); @@ -339,7 +337,7 @@ static UInt32 NO_INLINE DecodeBlock2(const UInt32 *tt, UInt32 blockSize, UInt32 if (--blockSize == 0) break; - b = (unsigned int)(tPos & 0xFF); + b = (unsigned)(tPos & 0xFF); tPos = tt[tPos >> 8]; crc.UpdateByte(b); m_OutStream.WriteByte((Byte)b); @@ -354,7 +352,7 @@ static UInt32 NO_INLINE DecodeBlock2(const UInt32 *tt, UInt32 blockSize, UInt32 if (blockSize == 0) break; - b = (unsigned int)(tPos & 0xFF); + b = (unsigned)(tPos & 0xFF); tPos = tt[tPos >> 8]; for (; b > 0; b--) @@ -375,15 +373,15 @@ static UInt32 NO_INLINE DecodeBlock2Rand(const UInt32 *tt, UInt32 blockSize, UIn UInt32 randIndex = 1; UInt32 randToGo = kRandNums[0] - 2; - int numReps = 0; + unsigned numReps = 0; // it's for speed optimization: prefetch & prevByte_init; UInt32 tPos = tt[tt[OrigPtr] >> 8]; - unsigned int prevByte = (unsigned int)(tPos & 0xFF); + unsigned prevByte = (unsigned)(tPos & 0xFF); do { - unsigned int b = (unsigned int)(tPos & 0xFF); + unsigned b = (unsigned)(tPos & 0xFF); tPos = tt[tPos >> 8]; { @@ -449,7 +447,7 @@ HRESULT CDecoder::Create() try { m_States = new CState[NumThreads]; - if (m_States == 0) + if (!m_States) return E_OUTOFMEMORY; } catch(...) { return E_OUTOFMEMORY; } @@ -487,6 +485,7 @@ void CDecoder::Free() delete []m_States; m_States = 0; } + #endif HRESULT CDecoder::ReadSignatures(bool &wasFinished, UInt32 &crc) @@ -794,6 +793,7 @@ STDMETHODIMP CDecoder::SetNumberOfThreads(UInt32 numThreads) NumThreads = kNumThreadsMax; return S_OK; } + #endif HRESULT CDecoder::SetRatioProgress(UInt64 packSize) @@ -805,4 +805,138 @@ HRESULT CDecoder::SetRatioProgress(UInt64 packSize) return Progress->SetRatioInfo(&packSize, &unpackSize); } + +// ---------- NSIS ---------- + +enum +{ + NSIS_STATE_INIT, + NSIS_STATE_NEW_BLOCK, + NSIS_STATE_DATA, + NSIS_STATE_FINISHED, + 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::SetOutStreamSize(const UInt64 * /* outSize */) +{ + _nsisState = NSIS_STATE_INIT; + return S_OK; +} + +STDMETHODIMP CNsisDecoder::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + try { + + *processedSize = 0; + if (_nsisState == NSIS_STATE_FINISHED) + return S_OK; + if (_nsisState == NSIS_STATE_ERROR) + return S_FALSE; + if (size == 0) + return S_OK; + + CState &state = m_State; + + if (_nsisState == NSIS_STATE_INIT) + { + if (!m_InStream.Create(kBufferSize)) + return E_OUTOFMEMORY; + if (!state.Alloc()) + return E_OUTOFMEMORY; + m_InStream.Init(); + _nsisState = NSIS_STATE_NEW_BLOCK; + } + + if (_nsisState == NSIS_STATE_NEW_BLOCK) + { + Byte b = (Byte)m_InStream.ReadBits(8); + if (b == kFinSig0) + { + _nsisState = NSIS_STATE_FINISHED; + return S_OK; + } + if (b != kBlockSig0) + { + _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); + const UInt32 *tt = state.Counters + 256; + _tPos = tt[tt[origPtr] >> 8]; + _prevByte = (unsigned)(_tPos & 0xFF); + _numReps = 0; + _repRem = 0; + _nsisState = NSIS_STATE_DATA; + } + + UInt32 tPos = _tPos; + unsigned prevByte = _prevByte; + unsigned numReps = _numReps; + UInt32 blockSize = _blockSize; + const UInt32 *tt = state.Counters + 256; + + while (_repRem) + { + _repRem--; + *(Byte *)data = (Byte)prevByte; + data = (Byte *)data + 1; + (*processedSize)++; + if (--size == 0) + return S_OK; + } + + if (blockSize == 0) + { + _nsisState = NSIS_STATE_NEW_BLOCK; + return S_OK; + } + + do + { + unsigned b = (unsigned)(tPos & 0xFF); + tPos = tt[tPos >> 8]; + blockSize--; + + if (numReps == kRleModeRepSize) + { + numReps = 0; + while (b) + { + b--; + *(Byte *)data = (Byte)prevByte; + data = (Byte *)data + 1; + (*processedSize)++; + if (--size == 0) + break; + } + _repRem = b; + continue; + } + if (b != prevByte) + numReps = 0; + numReps++; + prevByte = b; + *(Byte *)data = (Byte)b; + data = (Byte *)data + 1; + (*processedSize)++; + size--; + } + while (size && blockSize); + _tPos = tPos; + _prevByte = prevByte; + _numReps = numReps; + _blockSize = blockSize; + return S_OK; + + } + catch(const CInBufferException &e) { return e.ErrorCode; } + catch(...) { return S_FALSE; } +} + }} diff --git a/CPP/7zip/Compress/BZip2Decoder.h b/CPP/7zip/Compress/BZip2Decoder.h index d02b70a8..e6dec1ea 100755 --- a/CPP/7zip/Compress/BZip2Decoder.h +++ b/CPP/7zip/Compress/BZip2Decoder.h @@ -76,11 +76,10 @@ private: bool _needInStreamInit; - UInt32 ReadBits(int numBits); + UInt32 ReadBits(unsigned numBits); Byte ReadByte(); bool ReadBit(); UInt32 ReadCrc(); - HRESULT PrepareBlock(CState &state); HRESULT DecodeFile(bool &isBZ, ICompressProgressInfo *progress); HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, bool &isBZ, ICompressProgressInfo *progress); @@ -168,6 +167,39 @@ public: #endif }; + +class CNsisDecoder : + public ISequentialInStream, + public ICompressSetInStream, + public ICompressSetOutStreamSize, + public CMyUnknownImp +{ + NBitm::CDecoder<CInBuffer> m_InStream; + Byte m_Selectors[kNumSelectorsMax]; + CHuffmanDecoder m_HuffmanDecoders[kNumTablesMax]; + CState m_State; + + int _nsisState; + UInt32 _tPos; + unsigned _prevByte; + unsigned _repRem; + unsigned _numReps; + UInt32 _blockSize; + +public: + + MY_QUERYINTERFACE_BEGIN2(ISequentialInStream) + MY_QUERYINTERFACE_ENTRY(ICompressSetInStream) + MY_QUERYINTERFACE_ENTRY(ICompressSetOutStreamSize) + MY_QUERYINTERFACE_END + MY_ADDREF_RELEASE + + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(SetInStream)(ISequentialInStream *inStream); + STDMETHOD(ReleaseInStream)(); + STDMETHOD(SetOutStreamSize)(const UInt64 *outSize); +}; + }} #endif diff --git a/CPP/7zip/Compress/DeflateNsisRegister.cpp b/CPP/7zip/Compress/DeflateNsisRegister.cpp deleted file mode 100755 index ffad96c2..00000000 --- a/CPP/7zip/Compress/DeflateNsisRegister.cpp +++ /dev/null @@ -1,14 +0,0 @@ -// DeflateNsisRegister.cpp - -#include "StdAfx.h" - -#include "../Common/RegisterCodec.h" - -#include "DeflateDecoder.h" - -static void *CreateCodecDeflateNsis() { return (void *)(ICompressCoder *)(new NCompress::NDeflate::NDecoder::CNsisCOMCoder); } - -static CCodecInfo g_CodecInfo = - { CreateCodecDeflateNsis, 0, 0x040901, L"DeflateNSIS", 1, false }; - -REGISTER_CODEC(DeflateNsis) diff --git a/CPP/7zip/Compress/Rar3Decoder.cpp b/CPP/7zip/Compress/Rar3Decoder.cpp index af5cef1a..dde7c6de 100755 --- a/CPP/7zip/Compress/Rar3Decoder.cpp +++ b/CPP/7zip/Compress/Rar3Decoder.cpp @@ -627,7 +627,6 @@ public: CCoderReleaser(CDecoder *coder): m_Coder(coder) {} ~CCoderReleaser() { - // m_Coder->m_OutWindowStream.Flush(); m_Coder->ReleaseStreams(); } }; @@ -821,7 +820,7 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress) return S_OK; } - for(;;) + for (;;) { bool keepDecompressing; if (_lzMode) @@ -838,9 +837,10 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress) break; } RINOK(WriteBuf()); + UInt64 packSize = m_InBitStream.bitDecoder.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&packSize, &_writtenFileSize)); if (_writtenFileSize < _unpackSize) return S_FALSE; - // return m_OutWindowStream.Flush(); return S_OK; } |